summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk35
-rw-r--r--CaCerts.mk3
-rw-r--r--Docs.mk29
-rw-r--r--JavaLibrary.mk166
-rw-r--r--NOTICE278
-rw-r--r--NativeCode.mk91
-rw-r--r--benchmarks/Android.mk47
-rw-r--r--benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java148
-rw-r--r--benchmarks/src/benchmarks/ReferenceGetBenchmark.java60
-rw-r--r--benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java100
-rw-r--r--benchmarks/src/benchmarks/regression/CipherInputStreamBenchmark.java85
-rw-r--r--benchmarks/src/benchmarks/regression/EqualsHashCodeBenchmark.java15
-rw-r--r--benchmarks/src/benchmarks/regression/IcuBenchmark.java2
-rw-r--r--benchmarks/src/benchmarks/regression/MathBenchmark.java341
-rw-r--r--benchmarks/src/benchmarks/regression/SSLLoopbackBenchmark.java47
-rw-r--r--benchmarks/src/benchmarks/regression/SSLSocketBenchmark.java16
-rw-r--r--benchmarks/src/benchmarks/regression/SSLSocketFactoryBenchmark.java29
-rw-r--r--benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java12
-rw-r--r--crypto/jarjar-rules.txt1
-rw-r--r--crypto/src/main/java/org/conscrypt/AbstractSessionContext.java298
-rw-r--r--crypto/src/main/java/org/conscrypt/AlertException.java66
-rw-r--r--crypto/src/main/java/org/conscrypt/AlertProtocol.java281
-rw-r--r--crypto/src/main/java/org/conscrypt/Appendable.java33
-rw-r--r--crypto/src/main/java/org/conscrypt/ByteArray.java44
-rw-r--r--crypto/src/main/java/org/conscrypt/CertPinManager.java229
-rw-r--r--crypto/src/main/java/org/conscrypt/CertificateMessage.java166
-rw-r--r--crypto/src/main/java/org/conscrypt/CertificateRequest.java159
-rw-r--r--crypto/src/main/java/org/conscrypt/CertificateVerify.java90
-rw-r--r--crypto/src/main/java/org/conscrypt/ChainStrengthAnalyzer.java58
-rw-r--r--crypto/src/main/java/org/conscrypt/CipherSuite.java1184
-rw-r--r--crypto/src/main/java/org/conscrypt/ClientHandshakeImpl.java604
-rw-r--r--crypto/src/main/java/org/conscrypt/ClientHello.java207
-rw-r--r--crypto/src/main/java/org/conscrypt/ClientKeyExchange.java148
-rw-r--r--crypto/src/main/java/org/conscrypt/ClientSessionContext.java145
-rw-r--r--crypto/src/main/java/org/conscrypt/ConnectionState.java177
-rw-r--r--crypto/src/main/java/org/conscrypt/ConnectionStateSSLv3.java361
-rw-r--r--crypto/src/main/java/org/conscrypt/ConnectionStateTLS.java351
-rw-r--r--crypto/src/main/java/org/conscrypt/ContentType.java49
-rw-r--r--crypto/src/main/java/org/conscrypt/DHParameters.java108
-rw-r--r--crypto/src/main/java/org/conscrypt/DataStream.java42
-rw-r--r--crypto/src/main/java/org/conscrypt/DefaultSSLContextImpl.java130
-rw-r--r--crypto/src/main/java/org/conscrypt/DelegatedTask.java43
-rw-r--r--crypto/src/main/java/org/conscrypt/DigitalSignature.java259
-rw-r--r--crypto/src/main/java/org/conscrypt/EndOfBufferException.java33
-rw-r--r--crypto/src/main/java/org/conscrypt/EndOfSourceException.java33
-rw-r--r--crypto/src/main/java/org/conscrypt/FileClientSessionCache.java365
-rw-r--r--crypto/src/main/java/org/conscrypt/Finished.java78
-rw-r--r--crypto/src/main/java/org/conscrypt/Handshake.java89
-rw-r--r--crypto/src/main/java/org/conscrypt/HandshakeIODataStream.java435
-rw-r--r--crypto/src/main/java/org/conscrypt/HandshakeProtocol.java527
-rw-r--r--crypto/src/main/java/org/conscrypt/HelloRequest.java73
-rw-r--r--crypto/src/main/java/org/conscrypt/JSSEProvider.java123
-rw-r--r--crypto/src/main/java/org/conscrypt/KeyManagerFactoryImpl.java116
-rw-r--r--crypto/src/main/java/org/conscrypt/KeyManagerImpl.java220
-rw-r--r--crypto/src/main/java/org/conscrypt/Logger.java108
-rw-r--r--crypto/src/main/java/org/conscrypt/Message.java70
-rw-r--r--crypto/src/main/java/org/conscrypt/NativeCrypto.java1097
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLBIOInputStream.java72
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLCipher.java850
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLCipherContext.java42
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLCipherRSA.java357
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLContextImpl.java52
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyFactory.java201
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyPairGenerator.java90
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAParams.java155
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAPrivateKey.java234
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAPublicKey.java193
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDigestContext.java42
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECDHKeyAgreement.java158
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECGroupContext.java171
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECKeyFactory.java188
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECKeyPairGenerator.java110
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECPointContext.java83
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECPrivateKey.java188
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECPublicKey.java173
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLEngine.java139
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLKey.java213
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLKeyHolder.java21
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLMac.java167
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLMessageDigestJDK.java154
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLProvider.java241
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyFactory.java232
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyPairGenerator.java74
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java329
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java271
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAPublicKey.java189
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRandom.java41
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSecretKey.java137
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java76
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java245
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSessionImpl.java449
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSignature.java343
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSignatureRawRSA.java195
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java100
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java1137
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java203
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509CRL.java391
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java135
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509CertPath.java246
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509Certificate.java497
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java340
-rw-r--r--crypto/src/main/java/org/conscrypt/PRF.java198
-rw-r--r--crypto/src/main/java/org/conscrypt/PinEntryException.java29
-rw-r--r--crypto/src/main/java/org/conscrypt/PinFailureLogger.java70
-rw-r--r--crypto/src/main/java/org/conscrypt/PinListEntry.java155
-rw-r--r--crypto/src/main/java/org/conscrypt/PinManagerException.java32
-rw-r--r--crypto/src/main/java/org/conscrypt/Platform.java55
-rw-r--r--crypto/src/main/java/org/conscrypt/ProtocolVersion.java145
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLBufferedInput.java75
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLClientSessionCache.java53
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLContextImpl.java141
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLEngineAppData.java93
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLEngineDataStream.java91
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLEngineImpl.java753
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLInputStream.java113
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLParametersImpl.java418
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLRecordProtocol.java477
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLServerSessionCache.java52
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLServerSocketFactoryImpl.java128
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLServerSocketImpl.java266
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSessionImpl.java236
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketFactoryImpl.java162
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketImpl.java847
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketInputStream.java164
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketOutputStream.java45
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketWrapper.java232
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLStreamedInput.java57
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLv3Constants.java84
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerHandshakeImpl.java653
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerHello.java136
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerHelloDone.java76
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerKeyExchange.java245
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerSessionContext.java88
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustManagerFactoryImpl.java82
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustManagerImpl.java536
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustedCertificateIndex.java148
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java113
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java587
-rw-r--r--crypto/src/main/java/org/conscrypt/X509PublicKey.java86
-rw-r--r--crypto/src/main/java/org/conscrypt/util/EmptyArray.java35
-rw-r--r--crypto/src/main/native/org_conscrypt_NativeCrypto.cpp8244
-rw-r--r--crypto/src/main/native/sub.mk18
-rw-r--r--crypto/src/test/java/org/conscrypt/CertPinManagerTest.java175
-rw-r--r--crypto/src/test/java/org/conscrypt/ChainStrengthAnalyzerTest.java128
-rw-r--r--crypto/src/test/java/org/conscrypt/CipherSuiteTest.java167
-rw-r--r--crypto/src/test/java/org/conscrypt/ClientSessionContextTest.java120
-rw-r--r--crypto/src/test/java/org/conscrypt/FileClientSessionCacheTest.java56
-rw-r--r--crypto/src/test/java/org/conscrypt/MacTest.java69
-rw-r--r--crypto/src/test/java/org/conscrypt/NativeCryptoTest.java2629
-rw-r--r--crypto/src/test/java/org/conscrypt/OpenSSLSignatureTest.java36
-rw-r--r--crypto/src/test/java/org/conscrypt/SignatureTest.java125
-rw-r--r--crypto/src/test/java/org/conscrypt/TrustManagerImplTest.java235
-rw-r--r--crypto/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java662
-rw-r--r--dalvik/src/main/java/dalvik/annotation/BrokenTest.java2
-rw-r--r--dalvik/src/main/java/dalvik/annotation/SideEffect.java2
-rw-r--r--dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java23
-rw-r--r--dalvik/src/main/java/dalvik/system/DexClassLoader.java4
-rw-r--r--dalvik/src/main/java/dalvik/system/DexFile.java91
-rw-r--r--dalvik/src/main/java/dalvik/system/DexPathList.java59
-rw-r--r--dalvik/src/main/java/dalvik/system/VMDebug.java16
-rw-r--r--dalvik/src/main/java/dalvik/system/Zygote.java206
-rw-r--r--dalvik/src/main/java/dalvik/system/ZygoteHooks.java80
-rw-r--r--dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java119
-rw-r--r--dex/src/main/java/com/android/dex/Dex.java20
-rw-r--r--dex/src/main/java/com/android/dex/DexException.java2
-rw-r--r--dex/src/main/java/com/android/dex/DexIndexOverflowException.java30
-rw-r--r--expectations/brokentests.txt863
-rw-r--r--expectations/icebox.txt67
-rw-r--r--expectations/knownfailures.txt633
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/io/BufferedReaderTest.java592
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/ScannerParseLargeFileBenchmarkTest.java76
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/ScannerTest.java5634
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/UUIDTest.java457
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/AbstractBufferTest.java306
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.java52
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteBufferTest.java2177
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteOrderTest.java40
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java1081
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectByteBufferTest.java60
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectCharBufferTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectDoubleBufferTest.java60
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectFloatBufferTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectIntBufferTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectLongBufferTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectShortBufferTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java664
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateDirectByteBufferTest.java31
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateHeapByteBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateWrappedByteBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java674
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapByteBufferTest.java60
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapCharBufferTest.java44
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapDoubleBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapFloatBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapIntBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapLongBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapShortBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/IntBufferTest.java650
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.java51
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/LongBufferTest.java657
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/MappedByteBufferTest.java231
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.java51
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyCharBufferTest.java209
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyDirectByteBufferTest.java44
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyDoubleBufferTest.java160
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyFloatBufferTest.java161
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapByteBufferTest.java43
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapCharBufferTest.java35
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapDoubleBufferTest.java34
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapFloatBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapIntBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapLongBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapShortBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyIntBufferTest.java161
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyLongBufferTest.java161
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyShortBufferTest.java161
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedByteBufferTest.java45
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java34
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedIntBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedLongBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedShortBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ShortBufferTest.java637
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceDirectByteBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceHeapByteBufferTest.java33
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceWrappedByteBufferTest.java33
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedByteBufferTest.java97
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest1.java84
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest2.java128
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedDoubleBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedFloatBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedIntBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedLongBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedShortBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ChannelsTest.java622
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/DatagramChannelTest.java2557
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelLockingTest.java208
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java3121
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java199
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MapModeTest.java52
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockDatagramChannel.java81
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockServerSocketChannel.java46
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockSocketChannel.java75
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/PipeTest.java59
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectableChannelTest.java89
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectionKeyTest.java321
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java685
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ServerSocketChannelTest.java682
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SinkChannelTest.java505
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java3628
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SourceChannelTest.java554
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnixSelectorTest.java116
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractInterruptibleChannelTest.java135
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java313
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectionKeyTest.java76
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectorTest.java160
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/MockAbstractSelector.java89
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/ASCIICharsetEncoderTest.java449
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharacterCodingExceptionTest.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java279
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetEncoderTest.java212
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CoderMalfunctionErrorTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/IllegalCharsetNameExceptionTest.java94
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/MalformedInputExceptionTest.java85
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/UnmappableCharacterExceptionTest.java86
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/UnsupportedCharsetExceptionTest.java93
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/file/FileURLConnectionTest.java132
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedInputStreamTest.java562
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedOutputStreamTest.java849
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedReaderTest.java592
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedWriterTest.java302
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ByteArrayInputStreamTest.java180
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ByteArrayOutputStreamTest.java213
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharArrayReaderTest.java178
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharArrayWriterTest.java233
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharConversionExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ComputeSerialVersionUIDTest.java86
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ConsoleTest.java106
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataInputStreamTest.java594
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataOutputStreamTest.java262
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/EOFExceptionTest.java52
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileDescriptorTest.java89
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileInputStreamTest.java482
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileNotFoundExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileOutputStreamTest.java394
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileReaderTest.java118
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java2191
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileWriterTest.java185
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterInputStreamTest.java209
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java138
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOErrorTest.java73
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOExceptionTest.java113
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InputStreamReaderTest.java529
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InputStreamTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InterruptedIOExceptionTest.java47
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InvalidClassExceptionTest.java71
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/LineNumberInputStreamTest.java167
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/LineNumberReaderTest.java221
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/NotActiveExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/NotSerializableExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java213
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectOutputStream2Test.java59
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectOutputStreamTest.java1323
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java223
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamConstantsTest.java45
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamFieldTest.java395
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OpenRandomFileTest.java58
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OutputStreamTesterTest.java206
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OutputStreamWriterTest.java701
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedInputStreamTest.java448
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedOutputStreamTest.java231
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedReaderTest.java399
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedWriterTest.java477
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PrintStreamTest.java673
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PrintWriterTest.java779
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PushbackInputStreamTest.java256
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PushbackReaderTest.java381
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/RandomAccessFileTest.java1059
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ReaderTest.java205
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SequenceInputStreamTest.java193
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest.java1022
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest1.java1657
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest2.java2101
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest3.java1670
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest4.java1969
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationTestClass.java337
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StreamCorruptedExceptionTest.java78
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StreamTokenizerTest.java448
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringBufferInputStreamTest.java99
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringReaderTest.java172
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringWriterTest.java211
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SyncFailedExceptionTest.java46
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/UTFDataFormatExceptionTest.java83
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/UnsupportedEncodingExceptionTest.java68
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriteAbortedExceptionTest.java73
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriterTest.java147
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriterTesterTest.java213
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/AbstractMethodErrorTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArithmeticExceptionTest.java41
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArrayIndexOutOfBoundsExceptionTest.java52
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArrayStoreExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/AssertionErrorTest.java78
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/BooleanTest.java157
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ByteTest.java672
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CharacterImplTest.java38
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CharacterTest.java1637
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Character_SubsetTest.java49
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Character_UnicodeBlockTest.java822
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassCastExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassCircularityErrorTest.java40
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassFormatErrorTest.java43
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassLoaderTest.java158
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassNotFoundExceptionTest.java60
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassTest.java642
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CloneNotSupportedExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CompilerTest.java65
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/DoubleTest.java1444
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/EnumConstantNotPresentExceptionTest.java45
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/EnumTest.java261
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ExceptionInInitializerErrorTest.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/FloatTest.java1077
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalAccessErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalAccessExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalArgumentExceptionTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalMonitorStateExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalStateExceptionTest.java95
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalThreadStateExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IncompatibleClassChangeErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IndexOutOfBoundsExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InheritableThreadLocalTest.java41
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InstantiationErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InstantiationExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IntegerTest.java1231
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InternalErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InterruptedExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/LinkageErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/LongTest.java1067
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MathTest.java1960
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MockEnum.java57
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MockEnum2.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NegativeArraySizeExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoClassDefFoundErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchFieldErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchFieldExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchMethodErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchMethodExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NullPointerExceptionTest.java41
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NumberFormatExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NumberTest.java66
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ObjectTest.java388
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/OutOfMemoryErrorTest.java46
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Process2Test.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessBuilderTest.java171
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java221
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java135
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeExceptionTest.java59
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeTest.java128
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/SecurityExceptionTest.java81
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ShortTest.java684
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StackOverflowErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StrictMathTest.java1490
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/String2Test.java978
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBuffer2Test.java610
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBufferTest.java623
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBuilderTest.java1986
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringIndexOutOfBoundsExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java697
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/SystemTest.java413
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadDeathTest.java30
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadGroupTest.java795
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadLocalTest.java150
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadTest.java1011
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThrowableTest.java183
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/TypeNotPresentExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnknownErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsatisfiedLinkErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsupportedClassVersionErrorTest.java46
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsupportedOperationExceptionTest.java100
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/VerifyErrorTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/VirtualMachineErrorTest.java45
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/PhantomReferenceTest.java141
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceQueueTest.java254
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceTest.java340
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/SoftReferenceTest.java141
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/WeakReferenceTest.java80
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/AccessibleObjectTest.java215
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ArrayTest.java1001
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/BoundedGenericMethodsTests.java128
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ConstructorTest.java442
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/FieldTest.java1639
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericArrayTypeTest.java64
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericMethodsTests.java121
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericReflectionTestsBase.java74
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericSignatureFormatErrorTest.java100
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/InvocationTargetExceptionTest.java305
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MalformedParameterizedTypeExceptionTest.java34
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MalformedParameterizedTypeExceptionTests.java21
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MethodTest.java881
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ModifierTest.java435
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ParameterizedTypeTest.java77
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ProxyTest.java334
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/TypeVariableTest.java150
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/UndeclaredThrowableExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/UndeclaredThrowableExceptionTests.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/WildcardTypeTest.java151
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java952
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java988
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/math/MathContextTest.java79
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/math/OldBigIntegerTest.java372
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/math/RoundingModeTest.java49
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/BindExceptionTest.java67
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ConnectExceptionTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieHandlerTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieManagerTest.java303
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookiePolicyTest.java112
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieStoreTest.java401
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramPacketTest.java338
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketImplTest.java152
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java940
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/HttpCookieTest.java978
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/IDNTest.java156
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/Inet4AddressTest.java346
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/Inet6AddressTest.java916
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetAddressTest.java443
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetAddressThreadTest.java175
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetSocketAddressTest.java131
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InterfaceAddressTest.java164
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/JarURLConnectionTest.java312
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MalformedURLExceptionTest.java72
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java929
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/NetworkInterfaceTest.java496
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/NoRouteToHostExceptionTest.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/PasswordAuthenticationTest.java74
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProtocolExceptionTest.java67
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProxySelectorTest.java562
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProxyTest.java238
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ResponseCacheTest.java70
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SecureCacheResponseTest.java85
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java950
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketExceptionTest.java51
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketImplTest.java155
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTest.java1634
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTimeoutExceptionTest.java67
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/TestServerSocketInit.java30
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URISyntaxExceptionTest.java115
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URITest.java1841
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URLDecoderTest.java64
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URLTest.java1155
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/UnknownHostExceptionTest.java68
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/net/UnknownServiceExceptionTest.java67
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/AbstractBufferTest.java306
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/BufferOverflowExceptionTest.java52
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/BufferUnderflowExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java2177
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteOrderTest.java40
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/CharBufferTest.java1081
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java60
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectCharBufferTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectDoubleBufferTest.java60
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectFloatBufferTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectIntBufferTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectLongBufferTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectShortBufferTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java664
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateDirectByteBufferTest.java31
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateHeapByteBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateWrappedByteBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/FloatBufferTest.java674
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapByteBufferTest.java60
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapCharBufferTest.java44
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapDoubleBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapFloatBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapIntBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapLongBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapShortBufferTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/IntBufferTest.java650
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/InvalidMarkExceptionTest.java51
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/LongBufferTest.java657
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/MappedByteBufferTest.java231
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyBufferExceptionTest.java51
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyCharBufferTest.java209
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyDirectByteBufferTest.java44
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyDoubleBufferTest.java160
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyFloatBufferTest.java161
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapByteBufferTest.java43
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapCharBufferTest.java35
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapDoubleBufferTest.java34
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapFloatBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapIntBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapLongBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapShortBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyIntBufferTest.java161
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyLongBufferTest.java161
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyShortBufferTest.java161
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedByteBufferTest.java45
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java34
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedIntBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedLongBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedShortBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ShortBufferTest.java637
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceDirectByteBufferTest.java32
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceHeapByteBufferTest.java33
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceWrappedByteBufferTest.java33
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedByteBufferTest.java97
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedCharBufferTest1.java84
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedCharBufferTest2.java128
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedDoubleBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedFloatBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedIntBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedLongBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedShortBufferTest.java87
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/AlreadyConnectedExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/AsynchronousCloseExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/CancelledKeyExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ChannelsTest.java616
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedByInterruptExceptionTest.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedChannelExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedSelectorExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ConnectionPendingExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java2523
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelLockingTest.java208
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java3121
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockInterruptionExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockTest.java199
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/IllegalSelectorExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MapModeTest.java52
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockDatagramChannel.java93
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockServerSocketChannel.java50
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockSocketChannel.java86
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NoConnectionPendingExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NonReadableChannelExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NonWritableChannelExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NotYetBoundExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NotYetConnectedExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/OverlappingFileLockExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/PipeTest.java59
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectableChannelTest.java89
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectionKeyTest.java318
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectorTest.java676
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java811
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SinkChannelTest.java505
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java3812
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SourceChannelTest.java554
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnixSelectorTest.java116
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnresolvedAddressExceptionTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java55
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractInterruptibleChannelTest.java135
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java313
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectionKeyTest.java76
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectorTest.java160
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/MockAbstractSelector.java89
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCCharsetDecoderTest.java72
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCCharsetTest.java59
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCIICharsetEncoderTest.java455
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/AbstractCharsetTestCase.java175
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharacterCodingExceptionTest.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetDecoder2Test.java279
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetDecoderTest.java875
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetEncoder2Test.java212
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetEncoderTest.java1129
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java906
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CoderMalfunctionErrorTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CoderResultTest.java265
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CodingErrorActionTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/GBCharsetDecoderTest.java64
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/GBCharsetEncoderTest.java89
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetDecoderTest.java61
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetEncoderTest.java93
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetTest.java58
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/IllegalCharsetNameExceptionTest.java94
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/MalformedInputExceptionTest.java85
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetDecoderTest.java72
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetEncoderTest.java108
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetTest.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetDecoderTest.java118
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetEncoderTest.java128
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetTest.java51
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetDecoderTest.java72
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetEncoderTest.java109
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetTest.java54
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF8CharsetTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTFCharsetDecoderTest.java76
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTFCharsetEncoderTest.java96
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UnmappableCharacterExceptionTest.java86
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UnsupportedCharsetExceptionTest.java93
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AnnotationTest.java45
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedCharacterIteratorAttributeTest.java147
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedCharacterIteratorTest.java178
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedStringTest.java179
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/BidiTest.java964
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/BreakIteratorTest.java317
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ChoiceFormatTest.java469
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollationElementIteratorTest.java224
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollationKeyTest.java117
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollatorTest.java234
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DataFormatFieldTest.java223
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java423
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatTest.java475
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatSymbolsTest.java552
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java2594
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/FieldPositionTest.java249
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/LoadLocaleProviderTestHelper.java48
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/MessageFormatFieldTest.java46
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/MessageFormatTest.java953
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NormalizerTest.java183
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NumberFormatFieldTest.java46
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NumberFormatTest.java295
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ParseExceptionTest.java49
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ParsePositionTest.java117
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/RuleBasedCollatorTest.java258
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java835
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/StringCharacterIteratorTest.java521
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_DecimalFormat.java248
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_Format.java139
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_MessageFormat.java118
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_SimpleDateFormat.java258
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractCollectionTest.java345
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractListTest.java576
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractMapTest.java415
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractQueueTest.java323
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractSequentialListTest.java603
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayDequeTest.java932
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayListTest.java1071
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/Arrays2Test.java472
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArraysTest.java4209
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/BitSetTest.java1361
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CalendarTest.java1099
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/Collections2Test.java495
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CollectionsTest.java2385
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModTest.java667
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModificationExceptionTest.java107
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ControlTest.java682
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java405
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/DateTest.java520
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/DuplicateFormatFlagsExceptionTest.java94
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EmptyStackExceptionTest.java65
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumMapTest.java1175
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumSetTest.java2003
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EventObjectTest.java70
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatFlagsConversionMismatchExceptionTest.java115
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormattableFlagsTest.java27
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterClosedExceptionTest.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java4244
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/GregorianCalendarTest.java753
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashMapTest.java755
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashSetTest.java253
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashtableTest.java935
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IdentityHashMap2Test.java467
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IdentityHashMapTest.java871
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatCodePointExceptionTest.java91
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatConversionExceptionTest.java115
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatFlagsExceptionTest.java94
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatPrecisionExceptionTest.java92
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatWidthExceptionTest.java93
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/InputMismatchExceptionTest.java67
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/InvalidPropertiesFormatExceptionTest.java50
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedHashMapTest.java736
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedHashSetTest.java351
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedListTest.java983
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ListResourceBundleTest.java76
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java449
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingFormatArgumentExceptionTest.java97
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingFormatWidthExceptionTest.java95
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingResourceExceptionTest.java85
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/NoSuchElementExceptionTest.java73
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ObservableTest.java246
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PriorityQueueTest.java823
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PropertiesTest.java1157
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PropertyResourceBundleTest.java201
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RandomTest.java320
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RefSortedMap.java402
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ResourceBundleTest.java398
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SampleBundleClass.java43
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerParseLargeFileBenchmarkTest.java73
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java5606
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ServiceConfigurationErrorTest.java78
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleEntryTest.java133
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleImmutableEntryTest.java146
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleTimeZoneTest.java838
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SortedMapTestBase.java369
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/StackTest.java214
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/StringTokenizerTest.java311
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimeZoneTest.java301
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTaskTest.java248
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTest.java986
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TooManyListenersExceptionTest.java64
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapExtendTest.java13581
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapRndTest.java28
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapTest.java1968
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeSetTest.java342
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UUIDTest.java457
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UnknownFormatConversionExceptionTest.java96
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UnknownFormatFlagsExceptionTest.java94
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java1406
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/WeakHashMapTest.java423
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/AttributesNameTest.java39
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/AttributesTest.java286
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarEntryTest.java182
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarExceptionTest.java53
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java1017
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarInputStreamTest.java406
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarOutputStreamTest.java91
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/ManifestTest.java456
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/AbstractPreferencesTest.java1699
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/BackingStoreExceptionTest.java62
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/FilePreferencesImplTest.java120
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/InvalidPreferencesFormatExceptionTest.java81
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/MockAbstractPreferences.java263
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/MockPreferencesFactory.java42
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/NodeChangeEventTest.java63
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/NodeChangeListenerTest.java68
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferenceChangeEventTest.java84
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferenceChangeListenerTest.java52
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesFactoryTest.java59
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesTest.java420
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java85
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/A.java13
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/B.java4
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/I.java5
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/P.java28
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/Adler32Test.java169
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CRC32Test.java186
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CheckedInputStreamTest.java130
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CheckedOutputStreamTest.java140
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterInputStreamTest.java426
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterOutputStreamTest.java402
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterTest.java1129
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/GZIPInputStreamTest.java301
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/GZIPOutputStreamTest.java187
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java480
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterOutputStreamTest.java392
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java1135
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipEntryTest.java453
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipErrorTest.java50
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipFileTest.java421
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java245
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipOutputStreamTest.java292
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ServerSocketFactoryTest.java (renamed from luni/src/test/java/tests/api/javax/net/ServerSocketFactoryTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/SocketFactoryTest.java267
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/CertPathTrustManagerParametersTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/CertPathTrustManagerParametersTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/CertificatesToPlayWith.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/CertificatesToPlayWith.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HostnameVerifierTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/HostnameVerifierTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HttpsURLConnectionTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/HttpsURLConnectionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactory1Test.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactory1Test.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactory2Test.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactory2Test.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactorySpiTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactorySpiTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyStoreBuilderParametersTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContext1Test.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLContext1Test.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContext2Test.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLContext2Test.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContextSpiTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLContextSpiTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultHandshakeStatusTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultHandshakeStatusTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultStatusTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultStatusTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java1210
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLHandshakeExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLHandshakeExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLKeyExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLKeyExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLProtocolExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLProtocolExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketFactoryTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketFactoryTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionBindingEventTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLSessionBindingEventTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionBindingListenerTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLSessionBindingListenerTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionContextTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/SSLSessionContextTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java655
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketFactoryTest.java129
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java631
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactory1Test.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactory1Test.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactory2Test.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactory2Test.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactorySpiTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactorySpiTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509ExtendedKeyManagerTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/X509ExtendedKeyManagerTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509KeyManagerTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/X509KeyManagerTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509TrustManagerTest.java (renamed from luni/src/test/java/tests/api/javax/net/ssl/X509TrustManagerTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/DestroyFailedExceptionTest.java81
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/DestroyableTest.java64
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/LoginExceptionTest.java69
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/SubjectTest.java257
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/CallbackHandlerTest.java47
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.java137
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/UnsupportedCallbackExceptionTest.java117
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/login/LoginExceptionTest.java83
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.java3094
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateEncodingExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/security/cert/CertificateEncodingExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/security/cert/CertificateExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateExpiredExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/security/cert/CertificateExpiredExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateNotYetValidExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/security/cert/CertificateNotYetValidExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateParsingExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/security/cert/CertificateParsingExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateTest.java (renamed from luni/src/test/java/tests/api/javax/security/cert/CertificateTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java785
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/DocumentBuilderFactoryTest.java (renamed from luni/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/DocumentBuilderTest.java (renamed from luni/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/FactoryConfigurationErrorTest.java (renamed from luni/src/test/java/tests/api/javax/xml/parsers/FactoryConfigurationErrorTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/ParserConfigurationExceptionTest.java (renamed from luni/src/test/java/tests/api/javax/xml/parsers/ParserConfigurationExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserFactoryTest.java (renamed from luni/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserTest.java899
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserTestSupport.java (renamed from luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/apache/harmony/kernel/dalvik/ThreadsTest.java (renamed from luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/HandlerBaseTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/HandlerBaseTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/InputSourceTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/InputSourceTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXExceptionTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/SAXExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXNotRecognizedExceptionTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/SAXNotRecognizedExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXNotSupportedExceptionTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/SAXNotSupportedExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXParseExceptionTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/SAXParseExceptionTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/Attributes2ImplTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/ext/Attributes2ImplTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/DefaultHandler2Test.java (renamed from luni/src/test/java/tests/api/org/xml/sax/ext/DefaultHandler2Test.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/Locator2ImplTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/ext/Locator2ImplTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/AttributeListImplTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/AttributeListImplTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/AttributesImplTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/AttributesImplTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/DefaultHandlerTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/DefaultHandlerTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/LocatorImplTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/LocatorImplTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/NamespaceSupportTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/NamespaceSupportTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/ParserAdapterTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/ParserFactoryTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLFilterImplTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/XMLFilterImplTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLReaderAdapterTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLReaderFactoryTest.java (renamed from luni/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/BrokenInputStream.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/DoNothingParser.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/DoNothingParser.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/DoNothingXMLReader.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/DoNothingXMLReader.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MethodLogger.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/MethodLogger.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockFilter.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/MockFilter.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockHandler.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/MockHandler.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockParser.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/MockParser.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockReader.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/MockReader.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockResolver.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/MockResolver.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoAccessParser.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/NoAccessParser.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoAccessXMLReader.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/NoAccessXMLReader.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoInstanceParser.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/NoInstanceParser.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoInstanceXMLReader.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/NoInstanceXMLReader.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoSubclassParser.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/NoSubclassParser.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoSubclassXMLReader.java (renamed from luni/src/test/java/tests/api/org/xml/sax/support/NoSubclassXMLReader.java)0
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/pkg1/TestClass.java30
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/pkg2/TestClass.java29
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/support/A.java30
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/support/B.java21
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/support/I.java22
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/support/P.java45
-rw-r--r--harmony-tests/src/test/java/tests/api/java/math/BigDecimalTest.java952
-rw-r--r--harmony-tests/src/test/java/tests/api/java/math/BigIntegerTest.java988
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/ASCCharsetDecoderTest.java72
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/ASCCharsetTest.java59
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java175
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetDecoderTest.java875
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetEncoderTest.java1139
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetTest.java906
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/CoderResultTest.java265
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/CodingErrorActionTest.java62
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetDecoderTest.java64
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetEncoderTest.java89
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetDecoderTest.java61
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetEncoderTest.java93
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetTest.java58
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetDecoderTest.java72
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetEncoderTest.java108
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetTest.java53
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetDecoderTest.java118
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetEncoderTest.java128
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetTest.java51
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetDecoderTest.java72
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetEncoderTest.java109
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetTest.java54
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTF8CharsetTest.java62
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetDecoderTest.java76
-rw-r--r--harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetEncoderTest.java96
-rw-r--r--harmony-tests/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider2
-rw-r--r--harmony-tests/src/test/resources/resources/dex1.bytes (renamed from luni/src/test/resources/tests/api/java/lang/reflect/dex1.bytes)bin888 -> 888 bytes
-rw-r--r--harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs-badencoding.xml65
-rw-r--r--harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs-badform.xml51
-rw-r--r--harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs.xml89
-rw-r--r--harmony-tests/src/test/resources/resources/test.doc20
-rw-r--r--harmony-tests/src/test/resources/resources/test.htx22
-rw-r--r--harmony-tests/src/test/resources/resources/test.java20
-rw-r--r--harmony-tests/src/test/resources/resources/test.rtf20
-rw-r--r--harmony-tests/src/test/resources/resources/test.xml22
-rw-r--r--harmony-tests/src/test/resources/resources/test_resource.txt1
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/FileTest.golden.serbin0 -> 88 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/IOErrorTest.golden.serbin0 -> 2047 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/test_array_integers.serbin0 -> 226 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/test_array_strings.serbin0 -> 150 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/testfile1
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/AbstractMethodErrorTest.golden.serbin0 -> 1605 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.0.serbin0 -> 108 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.1.serbin0 -> 418 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.2.serbin0 -> 314 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.3.serbin0 -> 283 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.harmony.serbin0 -> 314 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/IllegalArgumentExceptionTest.golden.serbin0 -> 1356 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/IllegalStateExceptionTest.golden.serbin0 -> 1347 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/SecurityExceptionTest.golden.serbin0 -> 1335 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/StringBufferTest.golden.serbin0 -> 154 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/StringBuilderTest.golden.serbin0 -> 126 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/UnsupportedOperationExceptionTest.golden.serbin0 -> 1371 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/HttpRetryExceptionTest.golden.serbin0 -> 1279 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet4AddressTest.golden.serbin0 -> 112 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet6AddressTest.golden.0.serbin0 -> 260 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet6AddressTest.golden.1.serbin0 -> 261 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetAddressTest.golden.serbin0 -> 112 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetSocketAddressTest.golden.0.serbin0 -> 170 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetSocketAddressTest.golden.1.serbin0 -> 252 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/SocketTimeoutExceptionTest.golden.serbin0 -> 1628 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/BufferOverflowExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.golden.ser)bin1283 -> 1283 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/BufferUnderflowExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.golden.ser)bin1369 -> 1369 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/InvalidMarkExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.golden.ser)bin1403 -> 1403 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/ReadOnlyBufferExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.golden.ser)bin1420 -> 1420 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/AlreadyConnectedExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.golden.ser)bin1427 -> 1427 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/AsynchronousCloseExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.golden.ser)bin1441 -> 1441 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/CancelledKeyExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.golden.ser)bin1424 -> 1424 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedByInterruptExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.golden.ser)bin1500 -> 1500 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedChannelExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.golden.ser)bin1374 -> 1374 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedSelectorExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.golden.ser)bin1430 -> 1430 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ConnectionPendingExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.golden.ser)bin1439 -> 1439 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/FileLockInterruptionExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.golden.ser)bin1395 -> 1395 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/IllegalBlockingModeExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.golden.ser)bin1743 -> 1743 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/IllegalSelectorExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.golden.ser)bin1734 -> 1734 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NoConnectionPendingExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.golden.ser)bin1445 -> 1445 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NonReadableChannelExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.golden.ser)bin1442 -> 1442 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NonWritableChannelExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.golden.ser)bin1442 -> 1442 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NotYetBoundExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.golden.ser)bin1719 -> 1719 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NotYetConnectedExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.golden.ser)bin1731 -> 1731 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/OverlappingFileLockExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.golden.ser)bin1743 -> 1743 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/UnresolvedAddressExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.golden.ser)bin1740 -> 1740 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.golden.ser)bin1755 -> 1755 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/CharacterCodingExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/CharacterCodingExceptionTest.golden.ser)bin1822 -> 1822 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/CoderMalfunctionErrorTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/CoderMalfunctionErrorTest.golden.ser)bin1771 -> 1771 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/IllegalCharsetNameExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/IllegalCharsetNameExceptionTest.golden.ser)bin1924 -> 1924 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/MalformedInputExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/MalformedInputExceptionTest.golden.ser)bin1893 -> 1893 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/UnmappableCharacterExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/UnmappableCharacterExceptionTest.golden.ser)bin1908 -> 1908 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/UnsupportedCharsetExceptionTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/UnsupportedCharsetExceptionTest.golden.ser)bin1924 -> 1924 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormat.ser (renamed from luni/src/test/resources/serialization/java/text/DecimalFormat.ser)bin1384 -> 1384 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbols.ser (renamed from luni/src/test/resources/serialization/java/text/DecimalFormatSymbols.ser)bin495 -> 495 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbolsTest.golden.serbin0 -> 526 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleEntry.golden.serbin0 -> 178 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleImmutableEntry.golden.serbin0 -> 187 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/ArrayDequeTest.golden.serbin0 -> 165 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/BitSetTest.golden.serbin0 -> 137 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedCollection.golden.serbin0 -> 246 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedList.golden.serbin0 -> 320 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedListRandomAccess.golden.serbin0 -> 390 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedMap.golden.serbin0 -> 311 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSet.golden.serbin0 -> 293 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedMap.golden.serbin0 -> 400 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedSet.golden.serbin0 -> 373 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_asLifoQueue.golden.serbin0 -> 1189 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_newSetFromMap.golden.serbin0 -> 1758 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/DuplicateFormatFlagsExceptionTest.golden.serbin0 -> 1490 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/EnumMapTest.golden.serbin0 -> 285 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/EnumSetTest.golden.serbin0 -> 912 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/FormatFlagsConversionMismatchExceptionTest.golden.serbin0 -> 1522 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/FormatterClosedExceptionTest.golden.serbin0 -> 1401 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/HashMapTest.golden.serbin0 -> 96 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/HashSetTest.golden.ser (renamed from luni/src/test/resources/serialization/tests/api/java/util/HashSetTest.golden.ser)bin69 -> 69 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IdentityHashMapTest.golden.ser (renamed from luni/src/test/resources/serialization/tests/api/java/util/IdentityHashMapTest.golden.ser)bin88 -> 88 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatCodePointExceptionTest.golden.serbin0 -> 1481 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatConversionExceptionTest.golden.serbin0 -> 1541 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatFlagsExceptionTest.golden.serbin0 -> 1486 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatPrecisionExceptionTest.golden.serbin0 -> 1481 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatWidthExceptionTest.golden.serbin0 -> 1469 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/InputMismatchExceptionTest.golden.serbin0 -> 1644 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/LinkedListTest.golden.serbin0 -> 1165 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/MissingFormatArgumentExceptionTest.golden.serbin0 -> 1494 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/MissingFormatWidthExceptionTest.golden.serbin0 -> 1485 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/PriorityQueue.golden.serbin0 -> 278 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/RandomTest.golden.serbin0 -> 104 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/ServiceConfigurationErrorTest.golden.serbin0 -> 2180 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UUIDTest.golden.ser (renamed from luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/util/UUIDTest.golden.ser)bin80 -> 80 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UnknownFormatConversionExceptionTest.golden.serbin0 -> 1500 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UnknownFormatFlagsExceptionTest.golden.serbin0 -> 1489 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/prefs/BackingStoreExceptionTest.golden.serbin0 -> 1547 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/prefs/InvalidPreferencesFormatExceptionTest.golden.serbin0 -> 1583 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/zip/ZipErrorTest.golden.serbin0 -> 1718 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/DestroyFailedExceptionTest.golden.0.serbin0 -> 1351 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.0.serbin0 -> 285 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.1.serbin0 -> 285 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.2.serbin0 -> 309 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.3.serbin0 -> 309 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.golden.0.serbin0 -> 137 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.golden.1.serbin0 -> 164 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/login/LoginExceptionTest.golden.0.serbin0 -> 1392 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.0.serbin0 -> 97 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.1.serbin0 -> 109 bytes
-rw-r--r--harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.2.serbin0 -> 119 bytes
-rw-r--r--harmony-tests/src/test/resources/tests/resources/X500PrincipalTest.0.dat5
-rw-r--r--harmony-tests/src/test/resources/tests/resources/X500PrincipalTest.1.dat5
-rw-r--r--harmony-tests/src/test/resources/tests/resources/hyts_compDiction.binbin0 -> 501 bytes
-rw-r--r--harmony-tests/src/test/resources/tests/resources/hyts_compressD.binbin0 -> 500 bytes
-rw-r--r--harmony-tests/src/test/resources/tests/resources/hyts_construOD.binbin0 -> 13 bytes
-rw-r--r--harmony-tests/src/test/resources/tests/resources/hyts_construODI.binbin0 -> 18 bytes
-rw-r--r--harmony-tests/src/test/resources/tests/resources/hyts_gInput.txt.gzbin0 -> 42 bytes
-rw-r--r--harmony-tests/src/test/resources/tests/resources/hyts_resource_fr_FR.properties3
-rw-r--r--harmony-tests/src/test/resources/tests/resources/net/lf.jar (renamed from support/src/test/java/tests/resources/net/lf.jar)bin33095 -> 33095 bytes
-rw-r--r--harmony-tests/src/test/resources/tests/resources/net/url-test.jarbin0 -> 528 bytes
-rw-r--r--include/ScopedIcuLocale.h62
-rw-r--r--include/StaticAssert.h28
-rw-r--r--json/src/main/java/org/json/JSONArray.java11
-rw-r--r--json/src/main/java/org/json/JSONObject.java114
-rw-r--r--json/src/test/java/org/json/JSONArrayTest.java13
-rw-r--r--json/src/test/java/org/json/JSONObjectTest.java40
-rw-r--r--jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java604
-rw-r--r--jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java172
-rw-r--r--jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java1209
-rw-r--r--jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java1212
-rw-r--r--jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueFairTest.java25
-rw-r--r--jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNotFairTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java879
-rw-r--r--jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java888
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java136
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java337
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java232
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java261
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java337
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java232
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicLongTest.java264
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java147
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java213
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java160
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java137
-rw-r--r--jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java147
-rw-r--r--jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java366
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java686
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java858
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java511
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java1263
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java982
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java1410
-rw-r--r--jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java1123
-rw-r--r--jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java705
-rw-r--r--jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java359
-rw-r--r--jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java190
-rw-r--r--jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java1821
-rw-r--r--jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java458
-rw-r--r--jsr166-tests/src/test/java/jsr166/DelayQueueTest.java766
-rw-r--r--jsr166-tests/src/test/java/jsr166/EntryTest.java123
-rw-r--r--jsr166-tests/src/test/java/jsr166/ExchangerTest.java146
-rw-r--r--jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java221
-rw-r--r--jsr166-tests/src/test/java/jsr166/ExecutorsTest.java585
-rw-r--r--jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java996
-rw-r--r--jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java1605
-rw-r--r--jsr166-tests/src/test/java/jsr166/FutureTaskTest.java799
-rw-r--r--jsr166-tests/src/test/java/jsr166/JSR166TestCase.java1140
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeBoundedTest.java18
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java1757
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeUnboundedTest.java18
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueBoundedTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java812
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueUnboundedTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedListTest.java627
-rw-r--r--jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java1007
-rw-r--r--jsr166-tests/src/test/java/jsr166/LockSupportTest.java362
-rw-r--r--jsr166-tests/src/test/java/jsr166/PhaserTest.java786
-rw-r--r--jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueGenericTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueInitialCapacityTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java699
-rw-r--r--jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java492
-rw-r--r--jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java1237
-rw-r--r--jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java1020
-rw-r--r--jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java1133
-rw-r--r--jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java1670
-rw-r--r--jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java1213
-rw-r--r--jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java1164
-rw-r--r--jsr166-tests/src/test/java/jsr166/SemaphoreTest.java629
-rw-r--r--jsr166-tests/src/test/java/jsr166/SynchronousQueueFairTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/SynchronousQueueNotFairTest.java20
-rw-r--r--jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java589
-rw-r--r--jsr166-tests/src/test/java/jsr166/SystemTest.java63
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java290
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java96
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java1769
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java2010
-rw-r--r--jsr166-tests/src/test/java/jsr166/ThreadTest.java65
-rw-r--r--jsr166-tests/src/test/java/jsr166/TimeUnitTest.java457
-rw-r--r--jsr166-tests/src/test/java/jsr166/TreeMapTest.java1068
-rw-r--r--jsr166-tests/src/test/java/jsr166/TreeSetTest.java985
-rw-r--r--jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java1097
-rw-r--r--jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java1116
-rw-r--r--libart/src/main/java/dalvik/system/VMRuntime.java113
-rw-r--r--libart/src/main/java/java/lang/Class.java34
-rw-r--r--libart/src/main/java/java/lang/ClassLoader.java6
-rw-r--r--libart/src/main/java/java/lang/Daemons.java42
-rw-r--r--libart/src/main/java/java/lang/DexCache.java5
-rw-r--r--libart/src/main/java/java/lang/Enum.java3
-rw-r--r--libart/src/main/java/java/lang/Object.java91
-rw-r--r--libart/src/main/java/java/lang/String.java459
-rw-r--r--libart/src/main/java/java/lang/Thread.java49
-rw-r--r--libart/src/main/java/java/lang/ref/Reference.java226
-rw-r--r--libart/src/main/java/java/lang/reflect/AbstractMethod.java10
-rw-r--r--libart/src/main/java/java/lang/reflect/AccessibleObject.java7
-rw-r--r--libart/src/main/java/java/lang/reflect/ArtMethod.java96
-rw-r--r--libart/src/main/java/java/lang/reflect/Constructor.java12
-rw-r--r--libart/src/main/java/java/lang/reflect/Field.java153
-rw-r--r--libart/src/main/java/java/lang/reflect/Method.java9
-rw-r--r--libart/src/main/java/java/lang/reflect/Proxy.java56
-rw-r--r--libart/src/main/java/sun/misc/Unsafe.java24
-rw-r--r--libdvm/src/main/java/dalvik/system/VMRuntime.java245
-rw-r--r--libdvm/src/main/java/dalvik/system/VMStack.java100
-rw-r--r--libdvm/src/main/java/java/lang/Class.java1348
-rw-r--r--libdvm/src/main/java/java/lang/ClassLoader.java836
-rw-r--r--libdvm/src/main/java/java/lang/Daemons.java281
-rw-r--r--libdvm/src/main/java/java/lang/Enum.java221
-rw-r--r--libdvm/src/main/java/java/lang/Object.java442
-rw-r--r--libdvm/src/main/java/java/lang/String.java2046
-rw-r--r--libdvm/src/main/java/java/lang/Thread.java1281
-rw-r--r--libdvm/src/main/java/java/lang/ThreadGroup.java726
-rw-r--r--libdvm/src/main/java/java/lang/VMClassLoader.java85
-rw-r--r--libdvm/src/main/java/java/lang/VMThread.java77
-rw-r--r--libdvm/src/main/java/java/lang/reflect/AccessibleObject.java320
-rw-r--r--libdvm/src/main/java/java/lang/reflect/Constructor.java466
-rw-r--r--libdvm/src/main/java/java/lang/reflect/Field.java931
-rw-r--r--libdvm/src/main/java/java/lang/reflect/Method.java587
-rw-r--r--libdvm/src/main/java/java/lang/reflect/Proxy.java278
-rw-r--r--libdvm/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java63
-rw-r--r--libdvm/src/main/java/sun/misc/Unsafe.java350
-rw-r--r--luni/src/main/files/cacerts/03f2b8cf.0120
-rw-r--r--luni/src/main/files/cacerts/1dbdda5b.074
-rw-r--r--luni/src/main/files/cacerts/1f58a078.0120
-rw-r--r--luni/src/main/files/cacerts/2e8714cb.0103
-rw-r--r--luni/src/main/files/cacerts/48478734.076
-rw-r--r--luni/src/main/files/cacerts/52b525c7.0120
-rw-r--r--luni/src/main/files/cacerts/5a5372fc.074
-rw-r--r--luni/src/main/files/cacerts/635ccfd5.074
-rw-r--r--luni/src/main/files/cacerts/6adf0799.080
-rw-r--r--luni/src/main/files/cacerts/8d6437c3.080
-rw-r--r--luni/src/main/files/cacerts/961f5451.0121
-rw-r--r--luni/src/main/files/cacerts/a2c66da8.0121
-rw-r--r--luni/src/main/files/cacerts/bcdd5959.052
-rw-r--r--luni/src/main/files/cacerts/c491639e.053
-rw-r--r--luni/src/main/files/cacerts/c8763593.0132
-rw-r--r--luni/src/main/files/cacerts/c90bc37d.080
-rw-r--r--luni/src/main/files/cacerts/d06393bb.080
-rw-r--r--luni/src/main/files/cacerts/d537fba6.096
-rw-r--r--luni/src/main/files/cacerts/e442e424.0120
-rw-r--r--luni/src/main/files/cacerts/ed39abd0.053
-rw-r--r--luni/src/main/files/cacerts/f4996e82.052
-rw-r--r--luni/src/main/java/android/system/ErrnoException.java82
-rw-r--r--luni/src/main/java/android/system/GaiException.java83
-rw-r--r--luni/src/main/java/android/system/Os.java539
-rw-r--r--luni/src/main/java/android/system/OsConstants.java850
-rw-r--r--luni/src/main/java/android/system/StructAddrinfo.java58
-rw-r--r--luni/src/main/java/android/system/StructFlock.java47
-rw-r--r--luni/src/main/java/android/system/StructGroupReq.java39
-rw-r--r--luni/src/main/java/android/system/StructGroupSourceReq.java41
-rw-r--r--luni/src/main/java/android/system/StructLinger.java46
-rw-r--r--luni/src/main/java/android/system/StructPasswd.java48
-rw-r--r--luni/src/main/java/android/system/StructPollfd.java49
-rw-r--r--luni/src/main/java/android/system/StructStat.java98
-rw-r--r--luni/src/main/java/android/system/StructStatVfs.java80
-rw-r--r--luni/src/main/java/android/system/StructTimeval.java52
-rw-r--r--luni/src/main/java/android/system/StructUcred.java45
-rw-r--r--luni/src/main/java/android/system/StructUtsname.java55
-rw-r--r--luni/src/main/java/android/util/MutableBoolean.java27
-rw-r--r--luni/src/main/java/android/util/MutableByte.java27
-rw-r--r--luni/src/main/java/android/util/MutableChar.java27
-rw-r--r--luni/src/main/java/android/util/MutableDouble.java27
-rw-r--r--luni/src/main/java/android/util/MutableFloat.java27
-rw-r--r--luni/src/main/java/android/util/MutableInt.java27
-rw-r--r--luni/src/main/java/android/util/MutableLong.java27
-rw-r--r--luni/src/main/java/android/util/MutableShort.java27
-rw-r--r--luni/src/main/java/java/io/BufferedInputStream.java11
-rw-r--r--luni/src/main/java/java/io/Console.java47
-rw-r--r--luni/src/main/java/java/io/File.java19
-rw-r--r--luni/src/main/java/java/io/FileDescriptor.java13
-rw-r--r--luni/src/main/java/java/io/FileInputStream.java12
-rw-r--r--luni/src/main/java/java/io/FileOutputStream.java9
-rw-r--r--luni/src/main/java/java/io/InputStream.java20
-rw-r--r--luni/src/main/java/java/io/InputStreamReader.java6
-rw-r--r--luni/src/main/java/java/io/ObjectInputStream.java4
-rw-r--r--luni/src/main/java/java/io/ObjectOutput.java2
-rw-r--r--luni/src/main/java/java/io/ObjectOutputStream.java48
-rw-r--r--luni/src/main/java/java/io/OutputStreamWriter.java4
-rw-r--r--luni/src/main/java/java/io/PipedInputStream.java5
-rw-r--r--luni/src/main/java/java/io/PipedOutputStream.java2
-rw-r--r--luni/src/main/java/java/io/PipedReader.java2
-rw-r--r--luni/src/main/java/java/io/PipedWriter.java5
-rw-r--r--luni/src/main/java/java/io/RandomAccessFile.java11
-rw-r--r--luni/src/main/java/java/lang/AbstractStringBuilder.java79
-rw-r--r--luni/src/main/java/java/lang/CaseMapper.java19
-rw-r--r--luni/src/main/java/java/lang/CharSequence.java11
-rw-r--r--luni/src/main/java/java/lang/Character.java38
-rw-r--r--luni/src/main/java/java/lang/Double.java8
-rw-r--r--luni/src/main/java/java/lang/Float.java8
-rw-r--r--luni/src/main/java/java/lang/Integer.java70
-rw-r--r--luni/src/main/java/java/lang/Long.java65
-rw-r--r--luni/src/main/java/java/lang/ProcessManager.java8
-rw-r--r--luni/src/main/java/java/lang/Runtime.java65
-rw-r--r--luni/src/main/java/java/lang/StringToReal.java37
-rw-r--r--luni/src/main/java/java/lang/System.java627
-rw-r--r--luni/src/main/java/java/lang/ref/FinalizerReference.java30
-rw-r--r--luni/src/main/java/java/lang/ref/Reference.java200
-rw-r--r--luni/src/main/java/java/lang/ref/ReferenceQueue.java36
-rw-r--r--luni/src/main/java/java/lang/reflect/Array.java12
-rw-r--r--luni/src/main/java/java/lang/reflect/Modifier.java2
-rw-r--r--luni/src/main/java/java/math/BigDecimal.java8
-rw-r--r--luni/src/main/java/java/math/Multiplication.java78
-rw-r--r--luni/src/main/java/java/net/AddressCache.java50
-rw-r--r--luni/src/main/java/java/net/DatagramSocket.java70
-rw-r--r--luni/src/main/java/java/net/DatagramSocketImpl.java36
-rw-r--r--luni/src/main/java/java/net/HttpCookie.java62
-rw-r--r--luni/src/main/java/java/net/HttpURLConnection.java12
-rw-r--r--luni/src/main/java/java/net/Inet4Address.java2
-rw-r--r--luni/src/main/java/java/net/Inet6Address.java2
-rw-r--r--luni/src/main/java/java/net/InetAddress.java77
-rw-r--r--luni/src/main/java/java/net/InetUnixAddress.java2
-rw-r--r--luni/src/main/java/java/net/JarURLConnection.java20
-rw-r--r--luni/src/main/java/java/net/MulticastSocket.java6
-rw-r--r--luni/src/main/java/java/net/NetworkInterface.java4
-rw-r--r--luni/src/main/java/java/net/PlainDatagramSocketImpl.java43
-rw-r--r--luni/src/main/java/java/net/PlainSocketImpl.java47
-rw-r--r--luni/src/main/java/java/net/ServerSocket.java43
-rw-r--r--luni/src/main/java/java/net/Socket.java74
-rw-r--r--luni/src/main/java/java/net/SocketImpl.java27
-rw-r--r--luni/src/main/java/java/net/SocketOptions.java81
-rw-r--r--luni/src/main/java/java/net/URI.java55
-rw-r--r--luni/src/main/java/java/net/URLConnection.java7
-rw-r--r--luni/src/main/java/java/net/URLStreamHandler.java8
-rw-r--r--luni/src/main/java/java/nio/Buffer.java23
-rw-r--r--luni/src/main/java/java/nio/ByteArrayBuffer.java2
-rw-r--r--luni/src/main/java/java/nio/ByteBuffer.java160
-rw-r--r--luni/src/main/java/java/nio/ByteBufferAsCharBuffer.java3
-rw-r--r--luni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java3
-rw-r--r--luni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java3
-rw-r--r--luni/src/main/java/java/nio/ByteBufferAsIntBuffer.java3
-rw-r--r--luni/src/main/java/java/nio/ByteBufferAsLongBuffer.java3
-rw-r--r--luni/src/main/java/java/nio/ByteBufferAsShortBuffer.java3
-rw-r--r--luni/src/main/java/java/nio/CharArrayBuffer.java2
-rw-r--r--luni/src/main/java/java/nio/CharBuffer.java85
-rw-r--r--luni/src/main/java/java/nio/CharSequenceAdapter.java2
-rw-r--r--luni/src/main/java/java/nio/DatagramChannelImpl.java248
-rw-r--r--luni/src/main/java/java/nio/DirectByteBuffer.java87
-rw-r--r--luni/src/main/java/java/nio/DoubleArrayBuffer.java2
-rw-r--r--luni/src/main/java/java/nio/DoubleBuffer.java44
-rw-r--r--luni/src/main/java/java/nio/FileChannelImpl.java29
-rw-r--r--luni/src/main/java/java/nio/FloatArrayBuffer.java2
-rw-r--r--luni/src/main/java/java/nio/FloatBuffer.java46
-rw-r--r--luni/src/main/java/java/nio/IntArrayBuffer.java2
-rw-r--r--luni/src/main/java/java/nio/IntBuffer.java44
-rw-r--r--luni/src/main/java/java/nio/IoVec.java2
-rw-r--r--luni/src/main/java/java/nio/LongArrayBuffer.java2
-rw-r--r--luni/src/main/java/java/nio/LongBuffer.java44
-rw-r--r--luni/src/main/java/java/nio/MappedByteBuffer.java12
-rw-r--r--luni/src/main/java/java/nio/MemoryBlock.java30
-rw-r--r--luni/src/main/java/java/nio/NIOAccess.java17
-rw-r--r--luni/src/main/java/java/nio/NioUtils.java8
-rw-r--r--luni/src/main/java/java/nio/PipeImpl.java4
-rw-r--r--luni/src/main/java/java/nio/SelectorImpl.java24
-rw-r--r--luni/src/main/java/java/nio/ServerSocketChannelImpl.java63
-rw-r--r--luni/src/main/java/java/nio/ShortArrayBuffer.java2
-rw-r--r--luni/src/main/java/java/nio/ShortBuffer.java44
-rw-r--r--luni/src/main/java/java/nio/SocketChannelImpl.java304
-rw-r--r--luni/src/main/java/java/nio/channels/DatagramChannel.java3
-rw-r--r--luni/src/main/java/java/nio/channels/FileChannel.java23
-rw-r--r--luni/src/main/java/java/nio/channels/FileLock.java2
-rw-r--r--luni/src/main/java/java/nio/channels/ServerSocketChannel.java3
-rw-r--r--luni/src/main/java/java/nio/channels/SocketChannel.java48
-rw-r--r--luni/src/main/java/java/nio/charset/CharsetDecoderICU.java18
-rw-r--r--luni/src/main/java/java/nio/charset/CharsetEncoderICU.java30
-rw-r--r--luni/src/main/java/java/security/AlgorithmParameterGenerator.java3
-rw-r--r--luni/src/main/java/java/security/AlgorithmParameters.java3
-rw-r--r--luni/src/main/java/java/security/GuardedObject.java2
-rw-r--r--luni/src/main/java/java/security/KeyFactory.java3
-rw-r--r--luni/src/main/java/java/security/KeyPairGenerator.java3
-rw-r--r--luni/src/main/java/java/security/KeyStore.java3
-rw-r--r--luni/src/main/java/java/security/MessageDigest.java27
-rw-r--r--luni/src/main/java/java/security/Provider.java246
-rw-r--r--luni/src/main/java/java/security/SecureRandom.java7
-rw-r--r--luni/src/main/java/java/security/Security.java46
-rw-r--r--luni/src/main/java/java/security/Signature.java217
-rw-r--r--luni/src/main/java/java/security/SignatureSpi.java5
-rw-r--r--luni/src/main/java/java/security/cert/CRLReason.java40
-rw-r--r--luni/src/main/java/java/security/cert/CertPathValidator.java3
-rw-r--r--luni/src/main/java/java/security/cert/CertStore.java4
-rw-r--r--luni/src/main/java/java/security/cert/Certificate.java10
-rw-r--r--luni/src/main/java/java/security/cert/CertificateFactory.java7
-rw-r--r--luni/src/main/java/java/security/cert/CertificateFactorySpi.java8
-rw-r--r--luni/src/main/java/java/security/cert/CertificateRevokedException.java155
-rw-r--r--luni/src/main/java/java/security/cert/Extension.java65
-rw-r--r--luni/src/main/java/java/security/cert/X509CRLEntry.java25
-rw-r--r--luni/src/main/java/java/security/interfaces/DSAParams.java4
-rw-r--r--luni/src/main/java/java/security/security.properties8
-rw-r--r--luni/src/main/java/java/security/spec/ECParameterSpec.java24
-rw-r--r--luni/src/main/java/java/sql/Date.java26
-rw-r--r--luni/src/main/java/java/sql/Timestamp.java70
-rw-r--r--luni/src/main/java/java/text/Bidi.java49
-rw-r--r--luni/src/main/java/java/text/BreakIterator.java35
-rw-r--r--luni/src/main/java/java/text/CollationElementIterator.java36
-rw-r--r--luni/src/main/java/java/text/DateFormat.java16
-rw-r--r--luni/src/main/java/java/text/DateFormatSymbols.java46
-rw-r--r--luni/src/main/java/java/text/DecimalFormat.java136
-rw-r--r--luni/src/main/java/java/text/DecimalFormatSymbols.java23
-rw-r--r--luni/src/main/java/java/text/FieldPosition.java244
-rw-r--r--luni/src/main/java/java/text/MessageFormat.java4
-rw-r--r--luni/src/main/java/java/text/NumberFormat.java45
-rw-r--r--luni/src/main/java/java/text/RuleBasedCollator.java304
-rw-r--r--luni/src/main/java/java/text/SimpleDateFormat.java106
-rw-r--r--luni/src/main/java/java/text/spi/BreakIteratorProvider.java90
-rw-r--r--luni/src/main/java/java/text/spi/CollatorProvider.java50
-rw-r--r--luni/src/main/java/java/text/spi/DateFormatProvider.java81
-rw-r--r--luni/src/main/java/java/text/spi/DateFormatSymbolsProvider.java50
-rw-r--r--luni/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java51
-rw-r--r--luni/src/main/java/java/text/spi/NumberFormatProvider.java93
-rw-r--r--luni/src/main/java/java/util/Arrays.java53
-rw-r--r--luni/src/main/java/java/util/Calendar.java16
-rw-r--r--luni/src/main/java/java/util/Collections.java2
-rw-r--r--luni/src/main/java/java/util/Currency.java14
-rw-r--r--luni/src/main/java/java/util/EnumMap.java4
-rw-r--r--luni/src/main/java/java/util/Formatter.java21
-rw-r--r--luni/src/main/java/java/util/GregorianCalendar.java60
-rw-r--r--luni/src/main/java/java/util/HashMap.java33
-rw-r--r--luni/src/main/java/java/util/IllformedLocaleException.java57
-rw-r--r--luni/src/main/java/java/util/LinkedHashMap.java5
-rw-r--r--luni/src/main/java/java/util/Locale.java1702
-rw-r--r--luni/src/main/java/java/util/Properties.java2
-rw-r--r--luni/src/main/java/java/util/Random.java17
-rw-r--r--luni/src/main/java/java/util/Scanner.java105
-rw-r--r--luni/src/main/java/java/util/TimeZone.java46
-rw-r--r--luni/src/main/java/java/util/Timer.java7
-rw-r--r--luni/src/main/java/java/util/TreeSet.java16
-rw-r--r--luni/src/main/java/java/util/UUID.java25
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java3892
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java2
-rw-r--r--luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java2
-rw-r--r--luni/src/main/java/java/util/concurrent/CountedCompleter.java113
-rw-r--r--luni/src/main/java/java/util/concurrent/ForkJoinPool.java1659
-rw-r--r--luni/src/main/java/java/util/concurrent/ForkJoinTask.java142
-rw-r--r--luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java18
-rw-r--r--luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/Phaser.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/RecursiveAction.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/RecursiveTask.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java2
-rw-r--r--luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/TransferQueue.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/atomic/Fences.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java1
-rw-r--r--luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java1
-rw-r--r--luni/src/main/java/java/util/jar/Attributes.java9
-rw-r--r--luni/src/main/java/java/util/jar/JarEntry.java143
-rw-r--r--luni/src/main/java/java/util/jar/JarFile.java226
-rw-r--r--luni/src/main/java/java/util/jar/JarInputStream.java163
-rw-r--r--luni/src/main/java/java/util/jar/JarVerifier.java177
-rw-r--r--luni/src/main/java/java/util/jar/Manifest.java80
-rw-r--r--luni/src/main/java/java/util/jar/StrictJarFile.java232
-rw-r--r--luni/src/main/java/java/util/logging/SocketHandler.java7
-rw-r--r--luni/src/main/java/java/util/prefs/FilePreferencesFactoryImpl.java7
-rw-r--r--luni/src/main/java/java/util/prefs/FilePreferencesImpl.java25
-rw-r--r--luni/src/main/java/java/util/prefs/Preferences.java41
-rw-r--r--luni/src/main/java/java/util/regex/MatchResult.java58
-rw-r--r--luni/src/main/java/java/util/regex/MatchResultImpl.java2
-rw-r--r--luni/src/main/java/java/util/regex/Matcher.java199
-rw-r--r--luni/src/main/java/java/util/regex/Pattern.java2
-rw-r--r--luni/src/main/java/java/util/spi/CurrencyNameProvider.java49
-rw-r--r--luni/src/main/java/java/util/spi/LocaleNameProvider.java75
-rw-r--r--luni/src/main/java/java/util/spi/LocaleServiceProvider.java40
-rw-r--r--luni/src/main/java/java/util/spi/TimeZoneNameProvider.java51
-rw-r--r--luni/src/main/java/java/util/zip/Deflater.java8
-rw-r--r--luni/src/main/java/java/util/zip/DeflaterInputStream.java7
-rw-r--r--luni/src/main/java/java/util/zip/DeflaterOutputStream.java5
-rw-r--r--luni/src/main/java/java/util/zip/GZIPInputStream.java176
-rw-r--r--luni/src/main/java/java/util/zip/GZIPOutputStream.java7
-rw-r--r--luni/src/main/java/java/util/zip/Inflater.java9
-rw-r--r--luni/src/main/java/java/util/zip/InflaterInputStream.java7
-rw-r--r--luni/src/main/java/java/util/zip/ZipEntry.java72
-rw-r--r--luni/src/main/java/java/util/zip/ZipFile.java48
-rw-r--r--luni/src/main/java/java/util/zip/ZipInputStream.java41
-rw-r--r--luni/src/main/java/java/util/zip/ZipOutputStream.java61
-rw-r--r--luni/src/main/java/javax/crypto/Cipher.java358
-rw-r--r--luni/src/main/java/javax/crypto/CipherInputStream.java73
-rw-r--r--luni/src/main/java/javax/crypto/ExemptionMechanism.java1
-rw-r--r--luni/src/main/java/javax/crypto/KeyAgreement.java156
-rw-r--r--luni/src/main/java/javax/crypto/KeyGenerator.java3
-rw-r--r--luni/src/main/java/javax/crypto/Mac.java162
-rw-r--r--luni/src/main/java/javax/crypto/SealedObject.java72
-rw-r--r--luni/src/main/java/javax/crypto/SecretKeyFactory.java3
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLContext.java142
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLEngine.java623
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLEngineResult.java8
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLParameters.java1
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java9
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLSocket.java719
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLSocketFactory.java47
-rw-r--r--luni/src/main/java/javax/security/cert/Certificate.java11
-rw-r--r--luni/src/main/java/javax/xml/transform/overview.html12
-rw-r--r--luni/src/main/java/libcore/icu/CollationElementIteratorICU.java9
-rw-r--r--luni/src/main/java/libcore/icu/DateIntervalFormat.java8
-rw-r--r--luni/src/main/java/libcore/icu/ICU.java277
-rw-r--r--luni/src/main/java/libcore/icu/LocaleData.java35
-rw-r--r--luni/src/main/java/libcore/icu/NativeBreakIterator.java18
-rw-r--r--luni/src/main/java/libcore/icu/NativeCollation.java9
-rw-r--r--luni/src/main/java/libcore/icu/NativeDecimalFormat.java195
-rw-r--r--luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java2
-rw-r--r--luni/src/main/java/libcore/icu/TimeZoneNames.java15
-rw-r--r--luni/src/main/java/libcore/io/BlockGuardOs.java140
-rw-r--r--luni/src/main/java/libcore/io/DeleteOnExit.java82
-rw-r--r--luni/src/main/java/libcore/io/ErrnoException.java65
-rw-r--r--luni/src/main/java/libcore/io/ForwardingOs.java47
-rw-r--r--luni/src/main/java/libcore/io/GaiException.java66
-rw-r--r--luni/src/main/java/libcore/io/IoBridge.java105
-rw-r--r--luni/src/main/java/libcore/io/IoUtils.java4
-rw-r--r--luni/src/main/java/libcore/io/Memory.java57
-rw-r--r--luni/src/main/java/libcore/io/MemoryMappedFile.java6
-rw-r--r--luni/src/main/java/libcore/io/Os.java47
-rw-r--r--luni/src/main/java/libcore/io/OsConstants.java762
-rw-r--r--luni/src/main/java/libcore/io/Posix.java55
-rw-r--r--luni/src/main/java/libcore/io/Streams.java5
-rw-r--r--luni/src/main/java/libcore/io/StructAddrinfo.java51
-rw-r--r--luni/src/main/java/libcore/io/StructFlock.java39
-rw-r--r--luni/src/main/java/libcore/io/StructGroupReq.java36
-rw-r--r--luni/src/main/java/libcore/io/StructLinger.java42
-rw-r--r--luni/src/main/java/libcore/io/StructPasswd.java38
-rw-r--r--luni/src/main/java/libcore/io/StructPollfd.java48
-rw-r--r--luni/src/main/java/libcore/io/StructStat.java90
-rw-r--r--luni/src/main/java/libcore/io/StructStatVfs.java71
-rw-r--r--luni/src/main/java/libcore/io/StructTimeval.java48
-rw-r--r--luni/src/main/java/libcore/io/StructUcred.java41
-rw-r--r--luni/src/main/java/libcore/io/StructUtsname.java47
-rw-r--r--luni/src/main/java/libcore/net/MimeUtils.java48
-rw-r--r--luni/src/main/java/libcore/net/RawSocket.java142
-rw-r--r--luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java79
-rw-r--r--luni/src/main/java/libcore/net/event/NetworkEventListener.java27
-rw-r--r--luni/src/main/java/libcore/net/url/FileURLConnection.java165
-rw-r--r--luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java10
-rw-r--r--luni/src/main/java/libcore/reflect/AnnotationAccess.java83
-rw-r--r--luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java15
-rw-r--r--luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java29
-rw-r--r--luni/src/main/java/libcore/util/EmptyArray.java2
-rw-r--r--luni/src/main/java/libcore/util/MutableBoolean.java25
-rw-r--r--luni/src/main/java/libcore/util/MutableByte.java25
-rw-r--r--luni/src/main/java/libcore/util/MutableChar.java25
-rw-r--r--luni/src/main/java/libcore/util/MutableDouble.java25
-rw-r--r--luni/src/main/java/libcore/util/MutableFloat.java25
-rw-r--r--luni/src/main/java/libcore/util/MutableInt.java25
-rw-r--r--luni/src/main/java/libcore/util/MutableLong.java25
-rw-r--r--luni/src/main/java/libcore/util/MutableShort.java25
-rw-r--r--luni/src/main/java/libcore/util/ZoneInfo.java693
-rw-r--r--luni/src/main/java/libcore/util/ZoneInfoDB.java71
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/util/DeleteOnExit.java78
-rw-r--r--luni/src/main/java/org/apache/harmony/security/fortress/Engine.java71
-rw-r--r--luni/src/main/java/org/apache/harmony/security/fortress/Services.java48
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/cert/Cache.java324
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/cert/DRLCertFactory.java44
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/cert/X509CRLEntryImpl.java179
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/cert/X509CRLImpl.java504
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertFactoryImpl.java858
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertImpl.java430
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertPathImpl.java451
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java49
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java217
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java159
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java171
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1_MessageDigestImpl.java306
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1withDSA_SignatureImpl.java423
-rw-r--r--luni/src/main/java/org/apache/harmony/security/provider/crypto/ThreeIntegerSequence.java73
-rw-r--r--luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java105
-rw-r--r--luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java175
-rw-r--r--luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java2
-rw-r--r--luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java13
-rw-r--r--luni/src/main/java/org/apache/harmony/security/x501/AttributeValue.java84
-rw-r--r--luni/src/main/java/org/apache/harmony/security/x509/Extension.java19
-rw-r--r--luni/src/main/java/org/apache/harmony/security/x509/Extensions.java8
-rw-r--r--luni/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java7
-rw-r--r--luni/src/main/java/org/apache/harmony/security/x509/ReasonCode.java9
-rw-r--r--luni/src/main/java/org/apache/harmony/xml/ExpatParser.java6
-rw-r--r--luni/src/main/native/AsynchronousCloseMonitor.cpp106
-rw-r--r--luni/src/main/native/AsynchronousCloseMonitor.h66
-rw-r--r--luni/src/main/native/AsynchronousSocketCloseMonitor.cpp99
-rw-r--r--luni/src/main/native/AsynchronousSocketCloseMonitor.h60
-rw-r--r--luni/src/main/native/IcuUtilities.cpp6
-rw-r--r--luni/src/main/native/IcuUtilities.h3
-rw-r--r--luni/src/main/native/NetworkUtilities.h2
-rw-r--r--luni/src/main/native/Portability.h14
-rw-r--r--luni/src/main/native/Register.cpp9
-rw-r--r--luni/src/main/native/android_system_OsConstants.cpp628
-rw-r--r--luni/src/main/native/canonicalize_path.cpp125
-rw-r--r--luni/src/main/native/java_io_Console.cpp51
-rw-r--r--luni/src/main/native/java_io_File.cpp188
-rw-r--r--luni/src/main/native/java_io_FileDescriptor.cpp35
-rw-r--r--luni/src/main/native/java_lang_Character.cpp34
-rw-r--r--luni/src/main/native/java_lang_Double.cpp14
-rw-r--r--luni/src/main/native/java_lang_Float.cpp15
-rw-r--r--luni/src/main/native/java_lang_Math.cpp1
-rw-r--r--luni/src/main/native/java_lang_ProcessManager.cpp2
-rw-r--r--luni/src/main/native/java_lang_System.cpp26
-rw-r--r--luni/src/main/native/java_math_NativeBN.cpp130
-rw-r--r--luni/src/main/native/java_util_jar_StrictJarFile.cpp173
-rw-r--r--luni/src/main/native/libcore_icu_AlphabeticIndex.cpp17
-rw-r--r--luni/src/main/native/libcore_icu_DateIntervalFormat.cpp8
-rw-r--r--luni/src/main/native/libcore_icu_ICU.cpp307
-rw-r--r--luni/src/main/native/libcore_icu_NativeBreakIterator.cpp20
-rw-r--r--luni/src/main/native/libcore_icu_NativeCollation.cpp112
-rw-r--r--luni/src/main/native/libcore_icu_NativeConverter.cpp8
-rw-r--r--luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp94
-rw-r--r--luni/src/main/native/libcore_icu_TimeZoneNames.cpp58
-rw-r--r--luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp6
-rw-r--r--luni/src/main/native/libcore_io_Memory.cpp52
-rw-r--r--luni/src/main/native/libcore_io_OsConstants.cpp549
-rw-r--r--luni/src/main/native/libcore_io_Posix.cpp300
-rw-r--r--luni/src/main/native/libcore_net_RawSocket.cpp219
-rw-r--r--luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp5
-rw-r--r--luni/src/main/native/realpath.cpp125
-rw-r--r--luni/src/main/native/sub.mk123
-rw-r--r--luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java2
-rw-r--r--luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java32
-rw-r--r--luni/src/test/java/dalvik/system/DexClassLoaderTest.java427
-rw-r--r--luni/src/test/java/dalvik/system/JniTest.java368
-rw-r--r--luni/src/test/java/dalvik/system/VMRuntimeTest.java135
-rw-r--r--luni/src/test/java/libcore/android/system/OsConstantsTest.java31
-rw-r--r--luni/src/test/java/libcore/icu/AlphabeticIndexTest.java23
-rw-r--r--luni/src/test/java/libcore/icu/DateIntervalFormatTest.java126
-rw-r--r--luni/src/test/java/libcore/icu/ICUTest.java162
-rw-r--r--luni/src/test/java/libcore/icu/LocaleDataTest.java210
-rw-r--r--luni/src/test/java/libcore/icu/NativePluralRulesTest.java6
-rw-r--r--luni/src/test/java/libcore/icu/TimeZoneNamesTest.java7
-rw-r--r--luni/src/test/java/libcore/io/MemoryTest.java18
-rw-r--r--luni/src/test/java/libcore/io/OsTest.java4
-rw-r--r--luni/src/test/java/libcore/java/io/FileTest.java35
-rwxr-xr-xluni/src/test/java/libcore/java/io/InterruptedStreamTest.java7
-rw-r--r--luni/src/test/java/libcore/java/io/OldBufferedInputStreamTest.java228
-rw-r--r--luni/src/test/java/libcore/java/io/OldFileInputStreamTest.java209
-rw-r--r--luni/src/test/java/libcore/java/io/OldFileTest.java116
-rw-r--r--luni/src/test/java/libcore/java/io/OldFilterInputStreamTest.java45
-rw-r--r--luni/src/test/java/libcore/java/io/SerializationTest.java104
-rw-r--r--luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java81
-rw-r--r--luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java154
-rw-r--r--luni/src/test/java/libcore/java/lang/CharacterTest.java30
-rw-r--r--luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java78
-rw-r--r--luni/src/test/java/libcore/java/lang/ClassNotFoundExceptionTest.java49
-rw-r--r--luni/src/test/java/libcore/java/lang/ClassTest.java53
-rw-r--r--luni/src/test/java/libcore/java/lang/DoubleTest.java15
-rw-r--r--luni/src/test/java/libcore/java/lang/IntegerTest.java125
-rw-r--r--luni/src/test/java/libcore/java/lang/LongTest.java101
-rw-r--r--luni/src/test/java/libcore/java/lang/OldAndroidParseIntTest.java108
-rw-r--r--luni/src/test/java/libcore/java/lang/OldClassTest.java20
-rw-r--r--luni/src/test/java/libcore/java/lang/OldIntegerTest.java69
-rw-r--r--luni/src/test/java/libcore/java/lang/OldLongTest.java83
-rw-r--r--luni/src/test/java/libcore/java/lang/OldObjectTest.java10
-rw-r--r--luni/src/test/java/libcore/java/lang/OldRuntimeTest.java26
-rw-r--r--luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java14
-rw-r--r--luni/src/test/java/libcore/java/lang/StringBuilderTest.java132
-rw-r--r--luni/src/test/java/libcore/java/lang/StringIndexOutOfBoundsExceptionTest.java47
-rw-r--r--luni/src/test/java/libcore/java/lang/StringTest.java128
-rw-r--r--luni/src/test/java/libcore/java/lang/SystemTest.java136
-rw-r--r--luni/src/test/java/libcore/java/lang/ThreadTest.java99
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java277
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java22
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java18
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/FieldTest.java23
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/MethodTest.java56
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/OldGenericReflectionCornerCases.java2
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/OldGenericTypesTest.java2
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java334
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java55
-rw-r--r--luni/src/test/java/libcore/java/math/BigIntegerTest.java28
-rw-r--r--luni/src/test/java/libcore/java/math/CSVTest.java88
-rw-r--r--luni/src/test/java/libcore/java/math/OldBigDecimalConvertTest.java4
-rw-r--r--luni/src/test/java/libcore/java/math/RunCSVTests.java109
-rw-r--r--luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java62
-rw-r--r--luni/src/test/java/libcore/java/net/DatagramSocketTest.java58
-rw-r--r--luni/src/test/java/libcore/java/net/InetAddressTest.java15
-rw-r--r--luni/src/test/java/libcore/java/net/InetSocketAddressTest.java3
-rw-r--r--luni/src/test/java/libcore/java/net/OldCookieHandlerTest.java73
-rw-r--r--luni/src/test/java/libcore/java/net/OldDatagramSocketTest.java2183
-rw-r--r--luni/src/test/java/libcore/java/net/OldFileNameMapTest.java22
-rw-r--r--luni/src/test/java/libcore/java/net/OldSocketTest.java22
-rw-r--r--luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java41
-rw-r--r--luni/src/test/java/libcore/java/net/ServerSocketTest.java32
-rw-r--r--luni/src/test/java/libcore/java/net/SocketTest.java69
-rw-r--r--luni/src/test/java/libcore/java/net/URITest.java46
-rw-r--r--luni/src/test/java/libcore/java/net/URLConnectionTest.java125
-rw-r--r--luni/src/test/java/libcore/java/net/URLTest.java18
-rw-r--r--luni/src/test/java/libcore/java/nio/BufferTest.java448
-rw-r--r--luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java116
-rw-r--r--luni/src/test/java/libcore/java/nio/channels/FileChannelTest.java119
-rw-r--r--luni/src/test/java/libcore/java/nio/channels/FileIOInterruptTest.java709
-rw-r--r--luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java19
-rw-r--r--luni/src/test/java/libcore/java/nio/channels/SelectorTest.java10
-rw-r--r--luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java114
-rw-r--r--luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java201
-rw-r--r--luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java172
-rw-r--r--luni/src/test/java/libcore/java/security/KeyStoreTest.java75
-rw-r--r--luni/src/test/java/libcore/java/security/MessageDigestTest.java46
-rw-r--r--luni/src/test/java/libcore/java/security/MockPrivateKey.java40
-rw-r--r--luni/src/test/java/libcore/java/security/MockPrivateKey2.java40
-rw-r--r--luni/src/test/java/libcore/java/security/MockPublicKey.java40
-rw-r--r--luni/src/test/java/libcore/java/security/MockSignatureSpi.java118
-rw-r--r--luni/src/test/java/libcore/java/security/OldDHTest.java3
-rw-r--r--luni/src/test/java/libcore/java/security/OldKeyPairGeneratorTestDH.java3
-rw-r--r--luni/src/test/java/libcore/java/security/ProviderTest.java433
-rw-r--r--luni/src/test/java/libcore/java/security/SignatureTest.java375
-rw-r--r--luni/src/test/java/libcore/java/security/cert/CRLReasonTest.java67
-rw-r--r--luni/src/test/java/libcore/java/security/cert/OldPKIXParametersTest.java3
-rw-r--r--luni/src/test/java/libcore/java/security/cert/X509CRLTest.java38
-rw-r--r--luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java3
-rw-r--r--luni/src/test/java/libcore/java/sql/ConnectionTest.java69
-rw-r--r--luni/src/test/java/libcore/java/sql/DriverTest.java76
-rw-r--r--luni/src/test/java/libcore/java/sql/OldResultSetTest.java2
-rw-r--r--luni/src/test/java/libcore/java/sql/OldTimestampTest.java41
-rw-r--r--luni/src/test/java/libcore/java/sql/TimestampTest.java147
-rw-r--r--luni/src/test/java/libcore/java/text/CollatorTest.java8
-rw-r--r--luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java11
-rw-r--r--luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java19
-rw-r--r--luni/src/test/java/libcore/java/text/DecimalFormatTest.java141
-rw-r--r--luni/src/test/java/libcore/java/text/NumberFormatTest.java42
-rw-r--r--luni/src/test/java/libcore/java/text/OldBidiTest.java22
-rw-r--r--luni/src/test/java/libcore/java/text/OldCollationElementIteratorTest.java52
-rw-r--r--luni/src/test/java/libcore/java/text/OldCollationKeyTest.java9
-rw-r--r--luni/src/test/java/libcore/java/text/OldDecimalFormatTest.java1007
-rw-r--r--luni/src/test/java/libcore/java/text/OldFieldPositionTest.java79
-rw-r--r--luni/src/test/java/libcore/java/text/OldMessageFormatTest.java463
-rw-r--r--luni/src/test/java/libcore/java/text/OldNumberFormatTest.java15
-rw-r--r--luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java539
-rw-r--r--luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java107
-rw-r--r--luni/src/test/java/libcore/java/util/AbstractResourceLeakageDetectorTestCase.java44
-rw-r--r--luni/src/test/java/libcore/java/util/CalendarTest.java29
-rw-r--r--luni/src/test/java/libcore/java/util/CurrencyTest.java8
-rw-r--r--luni/src/test/java/libcore/java/util/DateTest.java32
-rw-r--r--luni/src/test/java/libcore/java/util/GregorianCalendarTest.java56
-rw-r--r--luni/src/test/java/libcore/java/util/LocaleInternalsTest.java129
-rw-r--r--luni/src/test/java/libcore/java/util/LocaleTest.java1018
-rw-r--r--luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java17
-rw-r--r--luni/src/test/java/libcore/java/util/OldTimeZoneTest.java49
-rw-r--r--luni/src/test/java/libcore/java/util/ResourceLeakageDetector.java90
-rw-r--r--luni/src/test/java/libcore/java/util/ResourceLeakageDetectorTest.java73
-rw-r--r--luni/src/test/java/libcore/java/util/TimeZoneTest.java9
-rw-r--r--luni/src/test/java/libcore/java/util/UUIDTest.java53
-rw-r--r--luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java258
-rw-r--r--luni/src/test/java/libcore/java/util/jar/StrictJarFileTest.java181
-rw-r--r--luni/src/test/java/libcore/java/util/prefs/OldAbstractPreferencesTest.java22
-rw-r--r--luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java21
-rw-r--r--luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java21
-rw-r--r--luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java21
-rw-r--r--luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java16
-rw-r--r--luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java43
-rw-r--r--luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java122
-rw-r--r--luni/src/test/java/libcore/java/util/zip/GZIPOutputStreamTest.java16
-rw-r--r--luni/src/test/java/libcore/java/util/zip/OldZipFileTest.java39
-rw-r--r--luni/src/test/java/libcore/java/util/zip/ZipFileTest.java64
-rw-r--r--luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java25
-rw-r--r--luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java35
-rw-r--r--luni/src/test/java/libcore/javax/crypto/CipherInputStreamTest.java154
-rw-r--r--luni/src/test/java/libcore/javax/crypto/CipherTest.java486
-rw-r--r--luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java2
-rw-r--r--luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java136
-rw-r--r--luni/src/test/java/libcore/javax/crypto/MockKey.java40
-rw-r--r--luni/src/test/java/libcore/javax/crypto/MockKey2.java40
-rw-r--r--luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java2
-rw-r--r--luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java3
-rw-r--r--luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java3
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java3
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java4
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/PSKKeyManagerProxy.java104
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java376
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java355
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java28
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java66
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java2
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java193
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java445
-rw-r--r--luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java19
-rw-r--r--luni/src/test/java/libcore/net/MimeUtilsTest.java45
-rw-r--r--luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java78
-rw-r--r--luni/src/test/java/libcore/reflect/InternalNamesTest.java82
-rw-r--r--luni/src/test/java/libcore/sqlite/AbstractSqlTest.java213
-rw-r--r--luni/src/test/java/libcore/sqlite/OldBlobTest.java135
-rw-r--r--luni/src/test/java/libcore/sqlite/OldDatabaseTest.java1224
-rw-r--r--luni/src/test/java/libcore/sqlite/OldExceptionTest.java39
-rw-r--r--luni/src/test/java/libcore/sqlite/OldFunctionContextTest.java314
-rw-r--r--luni/src/test/java/libcore/sqlite/OldJDBCDriverFunctionalTest.java64
-rw-r--r--luni/src/test/java/libcore/sqlite/OldJDBCDriverTest.java113
-rw-r--r--luni/src/test/java/libcore/sqlite/OldSQLiteTest.java62
-rw-r--r--luni/src/test/java/libcore/sqlite/OldStmtTest.java823
-rw-r--r--luni/src/test/java/libcore/sqlite/QueryTimeoutTest.java165
-rw-r--r--luni/src/test/java/libcore/util/ZoneInfoDBTest.java55
-rw-r--r--luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java374
-rw-r--r--luni/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java1001
-rw-r--r--luni/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java505
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java4
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java134
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java206
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MockKeyAgreementSpi.java89
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MockMacSpi.java82
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java28
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java5
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java5
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java3
-rw-r--r--luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java4
-rw-r--r--luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java1043
-rw-r--r--luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java851
-rw-r--r--luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerFactoryTest.java147
-rw-r--r--luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java89
-rw-r--r--luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java3
-rw-r--r--luni/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java7
-rw-r--r--luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java10
-rw-r--r--luni/src/test/java/tests/api/java/io/ComputeSerialVersionUIDTest.java145
-rw-r--r--luni/src/test/java/tests/api/java/io/ObjectInputStreamTest.java687
-rw-r--r--luni/src/test/java/tests/api/java/io/SerializationTestClass.java335
-rw-r--r--luni/src/test/java/tests/api/java/lang/Process2Test.java87
-rw-r--r--luni/src/test/java/tests/api/java/lang/ProcessManagerTest.java223
-rw-r--r--luni/src/test/java/tests/api/java/lang/ProcessTest.java135
-rw-r--r--luni/src/test/java/tests/api/java/lang/StringTest.java49
-rw-r--r--luni/src/test/java/tests/api/java/lang/ref/PhantomReferenceTest.java141
-rw-r--r--luni/src/test/java/tests/api/java/lang/ref/ReferenceQueueTest.java253
-rw-r--r--luni/src/test/java/tests/api/java/lang/ref/ReferenceTest.java340
-rw-r--r--luni/src/test/java/tests/api/java/lang/ref/SoftReferenceTest.java143
-rw-r--r--luni/src/test/java/tests/api/java/lang/ref/WeakReferenceTest.java80
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/AccessibleObjectTest.java215
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/ArrayTest.java1001
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/BoundedGenericMethodsTests.java128
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/ConstructorTest.java443
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/FieldTest.java1868
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/GenericArrayTypeTest.java64
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/GenericMethodsTests.java121
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionTestsBase.java74
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/GenericSignatureFormatErrorTest.java101
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/InvocationTargetExceptionTest.java305
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/MalformedParameterizedTypeExceptionTests.java21
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/MethodTest.java881
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/ParameterizedTypeTest.java77
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/ProxyTest.java319
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/TypeVariableTest.java150
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/UndeclaredThrowableExceptionTests.java53
-rw-r--r--luni/src/test/java/tests/api/java/lang/reflect/WildcardTypeTest.java151
-rw-r--r--luni/src/test/java/tests/api/java/math/MathContextTest.java79
-rw-r--r--luni/src/test/java/tests/api/java/math/OldBigIntegerTest.java372
-rw-r--r--luni/src/test/java/tests/api/java/math/RoundingModeTest.java49
-rw-r--r--luni/src/test/java/tests/api/java/util/AbstractListTest.java293
-rw-r--r--luni/src/test/java/tests/api/java/util/AbstractMapTest.java327
-rw-r--r--luni/src/test/java/tests/api/java/util/AbstractQueueTest.java323
-rw-r--r--luni/src/test/java/tests/api/java/util/AbstractSequentialListTest.java603
-rw-r--r--luni/src/test/java/tests/api/java/util/ArrayListTest.java699
-rw-r--r--luni/src/test/java/tests/api/java/util/ArraysTest.java2403
-rw-r--r--luni/src/test/java/tests/api/java/util/BitSetTest.java1279
-rw-r--r--luni/src/test/java/tests/api/java/util/CalendarTest.java1099
-rw-r--r--luni/src/test/java/tests/api/java/util/CollectionsTest.java2226
-rw-r--r--luni/src/test/java/tests/api/java/util/ConcurrentModTest.java667
-rw-r--r--luni/src/test/java/tests/api/java/util/ConcurrentModificationExceptionTest.java107
-rw-r--r--luni/src/test/java/tests/api/java/util/CurrencyTest.java428
-rw-r--r--luni/src/test/java/tests/api/java/util/DateTest.java514
-rw-r--r--luni/src/test/java/tests/api/java/util/EmptyStackExceptionTest.java65
-rw-r--r--luni/src/test/java/tests/api/java/util/EnumMapTest.java1175
-rw-r--r--luni/src/test/java/tests/api/java/util/EnumSetTest.java2003
-rw-r--r--luni/src/test/java/tests/api/java/util/FormattableFlagsTest.java31
-rw-r--r--luni/src/test/java/tests/api/java/util/HashMapTest.java558
-rw-r--r--luni/src/test/java/tests/api/java/util/HashSetTest.java253
-rw-r--r--luni/src/test/java/tests/api/java/util/HashtableTest.java838
-rw-r--r--luni/src/test/java/tests/api/java/util/IdentityHashMapTest.java494
-rw-r--r--luni/src/test/java/tests/api/java/util/InvalidPropertiesFormatExceptionTest.java39
-rw-r--r--luni/src/test/java/tests/api/java/util/LinkedHashMapTest.java736
-rw-r--r--luni/src/test/java/tests/api/java/util/LinkedHashSetTest.java351
-rw-r--r--luni/src/test/java/tests/api/java/util/LinkedListTest.java658
-rw-r--r--luni/src/test/java/tests/api/java/util/ListResourceBundleTest.java78
-rw-r--r--luni/src/test/java/tests/api/java/util/LocaleTest.java416
-rw-r--r--luni/src/test/java/tests/api/java/util/MissingResourceExceptionTest.java85
-rw-r--r--luni/src/test/java/tests/api/java/util/NoSuchElementExceptionTest.java73
-rw-r--r--luni/src/test/java/tests/api/java/util/ObservableTest.java246
-rw-r--r--luni/src/test/java/tests/api/java/util/PropertyResourceBundleTest.java98
-rw-r--r--luni/src/test/java/tests/api/java/util/RandomTest.java298
-rw-r--r--luni/src/test/java/tests/api/java/util/ResourceBundleTest.java398
-rw-r--r--luni/src/test/java/tests/api/java/util/SampleBundleClass.java43
-rw-r--r--luni/src/test/java/tests/api/java/util/SimpleTimeZoneTest.java838
-rw-r--r--luni/src/test/java/tests/api/java/util/StackTest.java188
-rw-r--r--luni/src/test/java/tests/api/java/util/StringTokenizerTest.java225
-rw-r--r--luni/src/test/java/tests/api/java/util/TimerTaskTest.java248
-rw-r--r--luni/src/test/java/tests/api/java/util/TimerTest.java986
-rw-r--r--luni/src/test/java/tests/api/java/util/TooManyListenersExceptionTest.java64
-rw-r--r--luni/src/test/java/tests/api/java/util/VectorTest.java1198
-rw-r--r--luni/src/test/java/tests/api/java/util/WeakHashMapTest.java383
-rw-r--r--luni/src/test/java/tests/api/java/util/support/A.java13
-rw-r--r--luni/src/test/java/tests/api/java/util/support/B.java4
-rw-r--r--luni/src/test/java/tests/api/java/util/support/I.java5
-rw-r--r--luni/src/test/java/tests/api/java/util/support/P.java28
-rw-r--r--luni/src/test/java/tests/api/javax/net/SocketFactoryTest.java267
-rw-r--r--luni/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java1482
-rw-r--r--luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java641
-rw-r--r--luni/src/test/java/tests/api/javax/net/ssl/SSLSocketFactoryTest.java139
-rw-r--r--luni/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java631
-rw-r--r--luni/src/test/java/tests/api/javax/security/auth/CallbackHandlerTest.java47
-rw-r--r--luni/src/test/java/tests/api/javax/security/auth/DestroyFailedExceptionTest.java69
-rw-r--r--luni/src/test/java/tests/api/javax/security/auth/DestroyableTest.java64
-rw-r--r--luni/src/test/java/tests/api/javax/security/auth/LoginExceptionTest.java69
-rw-r--r--luni/src/test/java/tests/api/javax/security/auth/PasswordCallbackTest.java107
-rw-r--r--luni/src/test/java/tests/api/javax/security/auth/SubjectTest.java250
-rw-r--r--luni/src/test/java/tests/api/javax/security/auth/UnsupportedCallbackExceptionTest.java117
-rw-r--r--luni/src/test/java/tests/api/javax/security/auth/X500PrincipalTest.java270
-rw-r--r--luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java788
-rw-r--r--luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java922
-rw-r--r--luni/src/test/java/tests/java/sql/SqlDateTest.java50
-rw-r--r--luni/src/test/java/tests/security/cert/CertificateRevocationExceptionTest.java167
-rw-r--r--luni/src/test/native/dalvik_system_JniTest.cpp274
-rw-r--r--luni/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider2
-rw-r--r--luni/src/test/resources/math_important_numbers.csv738
-rw-r--r--luni/src/test/resources/math_java_only.csv4132
-rw-r--r--luni/src/test/resources/math_tests.csv5199
-rw-r--r--luni/src/test/resources/org/apache/harmony/tests/java/lang/test#.properties1
-rw-r--r--luni/src/test/resources/org/apache/harmony/tests/java/lang/test.properties1
-rw-r--r--luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.0.serbin113 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.1.serbin443 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.2.serbin329 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.3.serbin288 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.harmony.serbin329 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDClass.serbin798 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDConstructors.serbin890 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDFields.serbin1856 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDInterfaces.serbin1306 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDMethods.serbin1136 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/tests/api/java/util/EnumMapTest.golden.serbin270 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/tests/api/java/util/EnumSetTest.golden.serbin897 -> 0 bytes
-rw-r--r--luni/src/test/resources/serialization/tests/security/cert/CertificateRevocationExceptionTest.golden.serbin0 -> 2137 bytes
-rw-r--r--luni/src/test/resources/tests/resources/java/util/zip/EmptyArchive.zipbin0 -> 22 bytes
-rw-r--r--support/src/test/java/libcore/dalvik/system/CloseGuardTester.java68
-rw-r--r--support/src/test/java/libcore/java/lang/ref/FinalizationTester.java4
-rw-r--r--support/src/test/java/libcore/java/security/StandardNames.java409
-rw-r--r--support/src/test/java/libcore/java/security/TestKeyStore.java62
-rw-r--r--support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java5
-rw-r--r--support/src/test/java/libcore/javax/net/ssl/SSLDefaultConfigurationAsserts.java202
-rw-r--r--support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java66
-rw-r--r--support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java53
-rw-r--r--support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java8
-rw-r--r--support/src/test/java/org/apache/harmony/testframework/CharSinkTester.java209
-rw-r--r--support/src/test/java/org/apache/harmony/testframework/CharWrapperTester.java258
-rw-r--r--support/src/test/java/org/apache/harmony/testframework/SinkTester.java221
-rw-r--r--support/src/test/java/org/apache/harmony/testframework/WrapperTester.java243
-rw-r--r--support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java7
-rw-r--r--support/src/test/java/tests/io/MockOs.java4
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/AbstractService.java38
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/Service.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceDuplicateIn2File.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceFinalClass.java31
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceForAllCommentTest.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceForEmptyTest.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceForIllegalNameTest.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceForWrongNameTest.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceIn2File.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceIn2FileWithEmptyConfig.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceMoreThanOne.java31
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/ServiceWithDuplicateSons.java28
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/hyts_services.jarbin0 -> 12258 bytes
-rw-r--r--support/src/test/java/tests/resources/ServiceLoader/hyts_services2.jarbin0 -> 5749 bytes
-rw-r--r--support/src/test/java/tests/resources/cts_dalvikExecTest.jarbin1698 -> 0 bytes
-rw-r--r--support/src/test/java/tests/resources/cts_dalvikExecTest_classes.dexbin2108 -> 0 bytes
-rw-r--r--support/src/test/java/tests/resources/hyts_signed_ambiguousSignerArray.jarbin0 -> 4163 bytes
-rw-r--r--support/src/test/java/tests/resources/hyts_signed_sha256digest_sha256withecdsa.jarbin0 -> 2045 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cacert.pem19
-rw-r--r--support/src/test/java/tests/resources/x509/cakey.pem16
-rw-r--r--support/src/test/java/tests/resources/x509/cert-alt-dirname.derbin673 -> 934 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-alt-dns.derbin609 -> 870 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-alt-email.derbin609 -> 870 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-alt-none.derbin576 -> 837 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-alt-other.derbin607 -> 868 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-alt-rid.derbin596 -> 857 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-alt-uri.derbin630 -> 891 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-ca.derbin594 -> 855 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-caWithPathLen.derbin597 -> 858 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-crl-ca.derbin776 -> 776 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-dsa.derbin795 -> 794 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-ec.derbin482 -> 472 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.derbin596 -> 857 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-ipv6.derbin638 -> 899 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.derbin594 -> 855 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-rsa-dates.txt4
-rw-r--r--support/src/test/java/tests/resources/x509/cert-rsa-pubkey.derbin162 -> 294 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-rsa-serial.txt2
-rw-r--r--support/src/test/java/tests/resources/x509/cert-rsa-sig.derbin128 -> 256 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-rsa-tbs.derbin1065 -> 1197 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-rsa.derbin1216 -> 1477 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-sigopt.derbin1226 -> 1487 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-unsupported.derbin603 -> 864 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/cert-userWithPathLen.derbin594 -> 855 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/certs-pk7.derbin2060 -> 2320 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/certs-pk7.pem88
-rwxr-xr-xsupport/src/test/java/tests/resources/x509/create.sh66
-rw-r--r--support/src/test/java/tests/resources/x509/crl-empty.derbin297 -> 297 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/crl-rsa-dates.txt4
-rw-r--r--support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt4
-rw-r--r--support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.derbin382 -> 382 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.pem12
-rw-r--r--support/src/test/java/tests/resources/x509/crl-rsa-dsa.derbin372 -> 372 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/crl-rsa-sig.derbin128 -> 128 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/crl-rsa-tbs.derbin176 -> 176 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/crl-rsa.derbin327 -> 327 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/crl-unsupported.derbin399 -> 399 bytes
-rw-r--r--support/src/test/java/tests/resources/x509/dsapriv.pem12
-rw-r--r--support/src/test/java/tests/resources/x509/ecpriv.pem5
-rw-r--r--support/src/test/java/tests/resources/x509/privkey.pem27
-rw-r--r--support/src/test/java/tests/support/Streams.java58
-rw-r--r--support/src/test/java/tests/support/Support_Configuration.java2
-rw-r--r--support/src/test/java/tests/support/Support_MapTest.java191
-rw-r--r--support/src/test/java/tests/support/Support_PlatformFile.java36
-rw-r--r--support/src/test/java/tests/support/Support_PortManager.java105
-rw-r--r--support/src/test/java/tests/support/Support_TestWebData.java16
-rw-r--r--support/src/test/java/tests/support/Support_TimeZone.java82
-rw-r--r--support/src/test/java/tests/support/Support_UnmodifiableMapTest.java161
-rw-r--r--support/src/test/java/tests/support/resource/Support_Resources.java14
-rw-r--r--support/src/test/java/tests/util/SerializationTester.java192
-rw-r--r--xml/src/main/java/org/kxml2/io/KXmlParser.java9
-rw-r--r--xml/src/main/java/org/xmlpull/v1/XmlPullParser.java4
-rw-r--r--xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java302
-rw-r--r--xml/src/main/java/org/xmlpull/v1/sax2/Driver.java2
1961 files changed, 304965 insertions, 162015 deletions
diff --git a/Android.mk b/Android.mk
index 2e9b76e..fd9bcd1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -15,6 +15,12 @@
LOCAL_PATH := $(call my-dir)
+#
+# Subprojects with separate makefiles
+#
+
+subdirs := benchmarks
+subdir_makefiles := $(call all-named-subdir-makefiles,$(subdirs))
#
# Include the definitions to build the Java code.
@@ -22,7 +28,6 @@ LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/JavaLibrary.mk
-
#
# Include the definitions to build the native code.
#
@@ -36,11 +41,6 @@ include $(LOCAL_PATH)/NativeCode.mk
include $(LOCAL_PATH)/CaCerts.mk
#
-# Include the definitions to build the caliper benchmarks.
-#
-include $(LOCAL_PATH)/benchmarks/Android.mk
-
-#
# Disable test modules if LIBCORE_SKIP_TESTS environment variable is set.
#
@@ -50,25 +50,4 @@ $(info * libcore tests are skipped because environment variable LIBCORE_SKIP_TES
$(info ********************************************************************************)
endif
-
-#
-# "m dalvik-host" for quick minimal host build
-#
-
-ifeq ($(WITH_HOST_DALVIK),true)
- .PHONY: dalvik-host
- dalvik-host: \
- dalvik \
- $(HOST_OUT)/bin/dalvikvm \
- $(HOST_OUT)/bin/dexopt \
- $(HOST_OUT)/lib/libconscrypt_jni.so \
- $(HOST_OUT)/lib/libjavacore.so \
- cacerts-host \
- core-hostdex \
- conscrypt-hostdex \
- okhttp-hostdex \
- bouncycastle-hostdex \
- apache-xml-hostdex \
- apache-harmony-tests-hostdex \
- $(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)/classes.jar
-endif
+include $(subdir_makefiles)
diff --git a/CaCerts.mk b/CaCerts.mk
index 980d0fb..f85f524 100644
--- a/CaCerts.mk
+++ b/CaCerts.mk
@@ -50,10 +50,9 @@ cacerts: $(cacerts_target)
# This is so that build/target/product/core.mk can use cacerts in PRODUCT_PACKAGES
ALL_MODULES.cacerts.INSTALLED := $(cacerts_target)
-ifeq ($(WITH_HOST_DALVIK),true)
cacerts_host_directory := $(HOST_OUT)/etc/security/cacerts
$(foreach cacert, $(cacerts), $(eval $(call include-prebuilt-with-destination-directory,host-cacert-$(notdir $(cacert)),$(cacert),$(cacerts_host_directory))))
-endif
+
cacerts_host := $(addprefix $(cacerts_host_directory)/,$(foreach cacert,$(cacerts),$(notdir $(cacert))))
.PHONY: cacerts-host
cacerts-host: $(cacerts_host)
diff --git a/Docs.mk b/Docs.mk
index 48cfd03..a163d1f 100644
--- a/Docs.mk
+++ b/Docs.mk
@@ -1,31 +1,30 @@
# -*- mode: makefile -*-
# List of libcore directories to include in documentation.
# Shared between libcore and frameworks/base.
+# Exports: libcore_to_document as a list of .java files relative to libcore/.
-define libcoredoc-all-java-files-under
-$(patsubst ./%,%, \
- $(shell cd $(1) ; \
- find $(2) -name "*.java" -and -not -name ".*") \
- )
-endef
+ifndef libcore_docs_include_once
# List of libcore javadoc source files
-#
-# Note dalvik/system is non-recursive to exclude dalvik.system.profiler
#
-# $(1): directory for search (to support use from frameworks/base)
-define libcore_to_document
- $(call libcoredoc-all-java-files-under,$(1), \
+# Note dalvik/system is non-recursive to exclude dalvik.system.profiler
+libcore_to_document := \
+ $(call find-files-in-subdirs, libcore, \
+ "*.java", \
dalvik/src/main/java/dalvik/system/ -maxdepth 1) \
- $(call libcoredoc-all-java-files-under,$(1), \
+ $(call find-files-in-subdirs, libcore, \
+ "*.java", \
dalvik/src/main/java/dalvik/annotation \
dalvik/src/main/java/dalvik/bytecode \
json/src/main/java \
- libdvm/src/main/java/dalvik \
- libdvm/src/main/java/java \
+ libart/src/main/java/dalvik \
+ libart/src/main/java/java \
+ luni/src/main/java/android \
luni/src/main/java/java \
luni/src/main/java/javax \
luni/src/main/java/org/xml/sax \
luni/src/main/java/org/w3c \
xml/src/main/java/org/xmlpull/v1)
-endef
+
+libcore_docs_include_once := 1
+endif # libcore_docs_include_once
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index f4cde58..57a8f82 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -53,6 +53,7 @@ endef
common_core_src_files := $(call all-main-java-files-under,dalvik dex dom json luni xml)
core_resource_dirs := $(call all-core-resource-dirs,main)
test_resource_dirs := $(call all-core-resource-dirs,test)
+test_src_files := $(call all-test-java-files-under,dalvik dom harmony-tests json luni xml)
ifeq ($(EMMA_INSTRUMENT),true)
ifneq ($(EMMA_INSTRUMENT_STATIC),true)
@@ -61,7 +62,6 @@ ifneq ($(EMMA_INSTRUMENT_STATIC),true)
endif
endif
-libdvm_core_src_files += $(common_core_src_files) $(call all-main-java-files-under,libdvm)
libart_core_src_files += $(common_core_src_files) $(call all-main-java-files-under,libart)
local_javac_flags=-encoding UTF-8
@@ -75,18 +75,6 @@ local_javac_flags+=-Xmaxwarns 9999999
# Definitions to make the core library.
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(libdvm_core_src_files)
-LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_DX_FLAGS := --core-library
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := core
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-LOCAL_REQUIRED_MODULES := tzdata
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(libart_core_src_files)
LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
@@ -98,39 +86,14 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_REQUIRED_MODULES := tzdata
include $(BUILD_JAVA_LIBRARY)
-# Create the conscrypt library
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-main-java-files-under,crypto)
-LOCAL_JAVA_LIBRARIES := core
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_JARJAR_RULES := $(LOCAL_PATH)/crypto/jarjar-rules.txt
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := conscrypt
-LOCAL_REQUIRED_MODULES := libjavacrypto
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-include $(BUILD_JAVA_LIBRARY)
-
-# Create the conscrypt library without jarjar for tests
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-main-java-files-under,crypto)
-LOCAL_JAVA_LIBRARIES := core
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := conscrypt-nojarjar
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-
ifeq ($(LIBCORE_SKIP_TESTS),)
# Make the core-tests library.
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-test-java-files-under,dalvik dom harmony-tests json luni xml)
+LOCAL_SRC_FILES := $(test_src_files)
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := bouncycastle core core-junit okhttp
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support sqlite-jdbc mockwebserver nist-pkix-tests okhttp-tests
+LOCAL_JAVA_LIBRARIES := core-libart okhttp core-junit bouncycastle
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support sqlite-jdbc mockwebserver nist-pkix-tests
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE := core-tests
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
@@ -143,7 +106,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := bouncycastle core core-junit
+LOCAL_JAVA_LIBRARIES := core-libart core-junit bouncycastle
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE := core-tests-support
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
@@ -151,18 +114,14 @@ include $(BUILD_STATIC_JAVA_LIBRARY)
endif
ifeq ($(LIBCORE_SKIP_TESTS),)
-# Make the conscrypt-tests library.
+# Make the jsr166-tests library.
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-test-java-files-under,crypto)
+LOCAL_SRC_FILES := $(call all-test-java-files-under, jsr166-tests)
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := bouncycastle core core-junit
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support conscrypt-nojarjar
+LOCAL_JAVA_LIBRARIES := core-libart core-junit
LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := conscrypt-tests
-LOCAL_REQUIRED_MODULES := libjavacrypto
-LOCAL_JARJAR_RULES := $(LOCAL_PATH)/crypto/jarjar-rules.txt
+LOCAL_MODULE := jsr166-tests
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
endif
@@ -192,107 +151,46 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := dex-host
include $(BUILD_HOST_JAVA_LIBRARY)
-ifeq ($(WITH_HOST_DALVIK),true)
-
- # Definitions to make the core library.
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES := $(libdvm_core_src_files)
- LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_DX_FLAGS := --core-library
- LOCAL_BUILD_HOST_DEX := true
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := core-hostdex
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
- LOCAL_REQUIRED_MODULES := tzdata-host
- include $(BUILD_HOST_JAVA_LIBRARY)
-
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES := $(libart_core_src_files)
- LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_DX_FLAGS := --core-library
- LOCAL_BUILD_HOST_DEX := true
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := core-libart-hostdex
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
- LOCAL_REQUIRED_MODULES := tzdata-host
- include $(BUILD_HOST_JAVA_LIBRARY)
-
- # Make the conscrypt-hostdex library
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES := $(call all-main-java-files-under,crypto)
- LOCAL_JAVA_LIBRARIES := core-hostdex
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_JARJAR_RULES := $(LOCAL_PATH)/crypto/jarjar-rules.txt
- LOCAL_BUILD_HOST_DEX := true
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := conscrypt-hostdex
- LOCAL_REQUIRED_MODULES := libjavacrypto
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
- include $(BUILD_HOST_JAVA_LIBRARY)
-
- # Make the conscrypt-hostdex-nojarjar for tests
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES := $(call all-main-java-files-under,crypto)
- LOCAL_JAVA_LIBRARIES := core-hostdex
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_BUILD_HOST_DEX := true
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := conscrypt-hostdex-nojarjar
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
- include $(BUILD_HOST_JAVA_LIBRARY)
+# Definitions to make the core library.
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(libart_core_src_files)
+LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVACFLAGS := $(local_javac_flags)
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := core-libart-hostdex
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
+LOCAL_REQUIRED_MODULES := tzdata-host
+include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
- # Make the core-tests library.
- ifeq ($(LIBCORE_SKIP_TESTS),)
+# Make the core-tests library.
+ifeq ($(LIBCORE_SKIP_TESTS),)
include $(CLEAR_VARS)
- LOCAL_SRC_FILES := $(call all-test-java-files-under,dalvik dom json luni xml)
+ LOCAL_SRC_FILES := $(test_src_files)
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-hostdex core-junit-hostdex core-tests-support-hostdex okhttp-hostdex
+ LOCAL_JAVA_LIBRARIES := core-libart-hostdex okhttp-hostdex bouncycastle-hostdex core-junit-hostdex core-tests-support-hostdex
LOCAL_STATIC_JAVA_LIBRARIES := sqlite-jdbc-host mockwebserver-host nist-pkix-tests-host
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := core-tests-hostdex
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
- LOCAL_BUILD_HOST_DEX := true
- include $(BUILD_HOST_JAVA_LIBRARY)
- endif
+ include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
+endif
- # Make the core-tests-support library.
- ifeq ($(LIBCORE_SKIP_TESTS),)
+# Make the core-tests-support library.
+ifeq ($(LIBCORE_SKIP_TESTS),)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-hostdex core-junit-hostdex
+ LOCAL_JAVA_LIBRARIES := core-libart-hostdex core-junit-hostdex bouncycastle-hostdex
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := core-tests-support-hostdex
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
- LOCAL_BUILD_HOST_DEX := true
- include $(BUILD_HOST_JAVA_LIBRARY)
- endif
-
- # Make the conscrypt-tests library.
- ifeq ($(LIBCORE_SKIP_TESTS),)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES := $(call all-test-java-files-under,crypto)
- LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
- LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-hostdex core-junit-hostdex core-tests-support-hostdex conscrypt-hostdex-nojarjar
- LOCAL_JAVACFLAGS := $(local_javac_flags)
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := conscrypt-tests-hostdex
- LOCAL_REQUIRED_MODULES := libjavacrypto
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
- LOCAL_BUILD_HOST_DEX := true
- include $(BUILD_HOST_JAVA_LIBRARY)
- endif
+ include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
endif
#
@@ -319,7 +217,7 @@ include $(CLEAR_VARS)
# for shared defintion of libcore_to_document
include $(LOCAL_PATH)/Docs.mk
-LOCAL_SRC_FILES:=$(call libcore_to_document,$(LOCAL_PATH))
+LOCAL_SRC_FILES := $(libcore_to_document)
# rerun doc generation without recompiling the java
LOCAL_JAVA_LIBRARIES:=
LOCAL_JAVACFLAGS := $(local_javac_flags)
diff --git a/NOTICE b/NOTICE
index 818f6c5..951e506 100644
--- a/NOTICE
+++ b/NOTICE
@@ -32,7 +32,7 @@ License Agreement", informally known as the "Intel Harmony CLA".
== NOTICE file for the ICU License. ==
=========================================================================
-Copyright (c) 1995-2009 International Business Machines Corporation and others
+Copyright (c) 1995-2014 International Business Machines Corporation and others
All rights reserved.
@@ -66,250 +66,6 @@ property of their respective owners.
=========================================================================
- == NOTICE file for the JUnit License. ==
- =========================================================================
-
-Common Public License - v 1.0
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON
-PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
-THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
- a) in the case of the initial Contributor, the initial code and
- documentation distributed under this Agreement, and
- b) in the case of each subsequent Contributor:
-
- i) changes to the Program, and
-
- ii) additions to the Program;
-
- where such changes and/or additions to the Program originate
- from and are distributed by that particular Contributor. A
- Contribution 'originates' from a Contributor if it was added to
- the Program by such Contributor itself or anyone acting on such
- Contributor's behalf. Contributions do not include additions to
- the Program which: (i) are separate modules of software
- distributed in conjunction with the Program under their own
- license agreement, and (ii) are not derivative works of the
- Program.
-
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents " mean patent claims licensable by a Contributor
-which are necessarily infringed by the use or sale of its Contribution
-alone or when combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this
-Agreement.
-
-"Recipient" means anyone who receives the Program under this
-Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
- a) Subject to the terms of this Agreement, each Contributor
- hereby grants Recipient a non-exclusive, worldwide, royalty-free
- copyright license to reproduce, prepare derivative works of,
- publicly display, publicly perform, distribute and sublicense
- the Contribution of such Contributor, if any, and such
- derivative works, in source code and object code form.
-
- b) Subject to the terms of this Agreement, each Contributor
- hereby grants Recipient a non-exclusive, worldwide, royalty-free
- patent license under Licensed Patents to make, use, sell, offer
- to sell, import and otherwise transfer the Contribution of such
- Contributor, if any, in source code and object code form. This
- patent license shall apply to the combination of the
- Contribution and the Program if, at the time the Contribution is
- added by the Contributor, such addition of the Contribution
- causes such combination to be covered by the Licensed Patents.
- The patent license shall not apply to any other combinations
- which include the Contribution. No hardware per se is licensed
- hereunder.
-
- c) Recipient understands that although each Contributor grants
- the licenses to its Contributions set forth herein, no
- assurances are provided by any Contributor that the Program does
- not infringe the patent or other intellectual property rights of
- any other entity. Each Contributor disclaims any liability to
- Recipient for claims brought by any other entity based on
- infringement of intellectual property rights or otherwise. As a
- condition to exercising the rights and licenses granted
- hereunder, each Recipient hereby assumes sole responsibility to
- secure any other intellectual property rights needed, if any.
- For example, if a third party patent license is required to
- allow Recipient to distribute the Program, it is Recipient's
- responsibility to acquire that license before distributing the
- Program.
-
- d) Each Contributor represents that to its knowledge it has
- sufficient copyright rights in its Contribution, if any, to
- grant the copyright license set forth in this Agreement.
-
-3. REQUIREMENTS
-
-A Contributor may choose to distribute the Program in object code form
-under its own license agreement, provided that:
-
- a) it complies with the terms and conditions of this Agreement; and
-
- b) its license agreement:
-
- i) effectively disclaims on behalf of all Contributors all
- warranties and conditions, express and implied, including
- warranties or conditions of title and non-infringement, and
- implied warranties or conditions of merchantability and fitness
- for a particular purpose;
-
- ii) effectively excludes on behalf of all Contributors all
- liability for damages, including direct, indirect, special,
- incidental and consequential damages, such as lost profits;
-
- iii) states that any provisions which differ from this Agreement
- are offered by that Contributor alone and not by any other
- party; and
-
- iv) states that source code for the Program is available from
- such Contributor, and informs licensees how to obtain it in a
- reasonable manner on or through a medium customarily used for
- software exchange.
-
-When the Program is made available in source code form:
-
- a) it must be made available under this Agreement; and
-
- b) a copy of this Agreement must be included with each copy of
- the Program.
-
-Contributors may not remove or alter any copyright notices contained
-within the Program.
-
-Each Contributor must identify itself as the originator of its
-Contribution, if any, in a manner that reasonably allows subsequent
-Recipients to identify the originator of the Contribution.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain
-responsibilities with respect to end users, business partners and the
-like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a
-commercial product offering should do so in a manner which does not
-create potential liability for other Contributors. Therefore, if a
-Contributor includes the Program in a commercial product offering,
-such Contributor ("Commercial Contributor") hereby agrees to defend
-and indemnify every other Contributor ("Indemnified Contributor")
-against any losses, damages and costs (collectively "Losses") arising
-from claims, lawsuits and other legal actions brought by a third party
-against the Indemnified Contributor to the extent caused by the acts
-or omissions of such Commercial Contributor in connection with its
-distribution of the Program in a commercial product offering. The
-obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement.
-In order to qualify, an Indemnified Contributor must: a) promptly
-notify the Commercial Contributor in writing of such claim, and b)
-allow the Commercial Contributor to control, and cooperate with the
-Commercial Contributor in, the defense and any related settlement
-negotiations. The Indemnified Contributor may participate in any such
-claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial
-product offering, Product X. That Contributor is then a Commercial
-Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance
-claims and warranties are such Commercial Contributor's responsibility
-alone. Under this section, the Commercial Contributor would have to
-defend claims against the other Contributors related to those
-performance claims and warranties, and if a court requires any other
-Contributor to pay any damages as a result, the Commercial Contributor
-must pay those damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
-PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
-WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
-OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
-responsible for determining the appropriateness of using and
-distributing the Program and assumes all risks associated with its
-exercise of rights under this Agreement, including but not limited to
-the risks and costs of program errors, compliance with applicable
-laws, damage to or loss of data, programs or equipment, and
-unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
-ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
-WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
-DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
-HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under
-applicable law, it shall not affect the validity or enforceability of
-the remainder of the terms of this Agreement, and without further
-action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against a Contributor with
-respect to a patent applicable to software (including a cross-claim or
-counterclaim in a lawsuit), then any patent licenses granted by that
-Contributor to such Recipient under this Agreement shall terminate as
-of the date such litigation is filed. In addition, if Recipient
-institutes patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Program
-itself (excluding combinations of the Program with other software or
-hardware) infringes such Recipient's patent(s), then such Recipient's
-rights granted under Section 2(b) shall terminate as of the date such
-litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it
-fails to comply with any of the material terms or conditions of this
-Agreement and does not cure such failure in a reasonable period of
-time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use
-and distribution of the Program as soon as reasonably practicable.
-However, Recipient's obligations under this Agreement and any licenses
-granted by Recipient relating to the Program shall continue and
-survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement,
-but in order to avoid inconsistency the Agreement is copyrighted and
-may only be modified in the following manner. The Agreement Steward
-reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement
-Steward has the right to modify this Agreement. IBM is the initial
-Agreement Steward. IBM may assign the responsibility to serve as the
-Agreement Steward to a suitable separate entity. Each new version of
-the Agreement will be given a distinguishing version number. The
-Program (including Contributions) may always be distributed subject to
-the version of the Agreement under which it was received. In addition,
-after a new version of the Agreement is published, Contributor may
-elect to distribute the Program (including its Contributions) under
-the new version. Except as expressly stated in Sections 2(a) and 2(b)
-above, Recipient receives no rights or licenses to the intellectual
-property of any Contributor under this Agreement, whether expressly,
-by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and
-the intellectual property laws of the United States of America. No
-party to this Agreement will bring a legal action under this Agreement
-more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.
-
-
- =========================================================================
== NOTICE file for the KXML License. ==
=========================================================================
@@ -336,38 +92,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================================================
- == NOTICE file for the SQLite Java Wrapper License. ==
- =========================================================================
-
-This software is copyrighted by Christian Werner <chw@ch-werner.de>
-and others. The following terms apply to all files associated with the
-software unless explicitly disclaimed in individual files.
-
-The authors hereby grant permission to use, copy, modify, distribute,
-and license this software and its documentation for any purpose, provided
-that existing copyright notices are retained in all copies and that this
-notice is included verbatim in any distributions. No written agreement,
-license, or royalty fee is required for any of the authorized uses.
-Modifications to this software may be copyrighted by their authors
-and need not follow the licensing terms described here, provided that
-the new terms are clearly indicated on the first page of each file where
-they apply.
-
-IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
-FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
-DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
-IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
-NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
-MODIFICATIONS.
-
-
- =========================================================================
== NOTICE file for the W3C License. ==
=========================================================================
diff --git a/NativeCode.mk b/NativeCode.mk
index 1a47ee4..0ae615e 100644
--- a/NativeCode.mk
+++ b/NativeCode.mk
@@ -66,10 +66,11 @@ $(foreach dir, \
core_c_includes := libcore/include $(LOCAL_C_INCLUDES)
core_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
core_static_libraries := $(LOCAL_STATIC_LIBRARIES)
-core_cflags := -Wall -Wextra -Werror
+core_cflags := $(LOCAL_CFLAGS) -Wall -Wextra -Werror
core_cppflags += -std=gnu++11
core_test_files := \
+ luni/src/test/native/dalvik_system_JniTest.cpp \
luni/src/test/native/test_openssl_engine.cpp \
#
@@ -81,31 +82,14 @@ LOCAL_CFLAGS += $(core_cflags)
LOCAL_CPPFLAGS += $(core_cppflags)
LOCAL_SRC_FILES += $(core_src_files)
LOCAL_C_INCLUDES += $(core_c_includes)
-LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libcrypto libexpat libicuuc libicui18n libnativehelper libz
-LOCAL_STATIC_LIBRARIES += $(core_static_libraries)
+LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libcrypto libdl libexpat libicuuc libicui18n libnativehelper libz libutils
+LOCAL_STATIC_LIBRARIES += $(core_static_libraries) libziparchive
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libjavacore
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
include external/stlport/libstlport.mk
include $(BUILD_SHARED_LIBRARY)
-# Platform conscrypt crypto library
-include $(CLEAR_VARS)
-LOCAL_CFLAGS += $(core_cflags)
-LOCAL_CFLAGS += -DJNI_JARJAR_PREFIX="com/android/"
-LOCAL_CPPFLAGS += $(core_cppflags)
-LOCAL_SRC_FILES := \
- crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
-LOCAL_C_INCLUDES += $(core_c_includes) \
- libcore/luni/src/main/native
-LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libcrypto libssl libnativehelper libz libjavacore
-LOCAL_STATIC_LIBRARIES += $(core_static_libraries)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := libjavacrypto
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
-include external/stlport/libstlport.mk
-include $(BUILD_SHARED_LIBRARY)
-
# Test JNI library.
ifeq ($(LIBCORE_SKIP_TESTS),)
@@ -128,53 +112,27 @@ endif # LIBCORE_SKIP_TESTS
# Build for the host.
#
-ifeq ($(WITH_HOST_DALVIK),true)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES += $(core_src_files)
- LOCAL_CFLAGS += $(core_cflags)
- LOCAL_C_INCLUDES += $(core_c_includes)
- LOCAL_CPPFLAGS += $(core_cppflags)
- LOCAL_LDLIBS += -ldl -lpthread -lrt
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := libjavacore
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
- LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libexpat-host libicuuc-host libicui18n-host libcrypto-host libz-host
- LOCAL_STATIC_LIBRARIES += $(core_static_libraries)
- include $(BUILD_HOST_SHARED_LIBRARY)
-
- # Conscrypt native library for host
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES += \
- crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
- LOCAL_C_INCLUDES += $(core_c_includes) \
- libcore/luni/src/main/native
- LOCAL_CPPFLAGS += $(core_cppflags)
- LOCAL_LDLIBS += -lpthread
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := libjavacrypto
- LOCAL_CFLAGS += -DJNI_JARJAR_PREFIX="com/android/"
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
- LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libssl-host libcrypto-host libjavacore
- LOCAL_STATIC_LIBRARIES += $(core_static_libraries)
- include $(BUILD_HOST_SHARED_LIBRARY)
-
- # Conscrypt native library for nojarjar'd version
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES += \
- crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
- LOCAL_C_INCLUDES += $(core_c_includes) \
- libcore/luni/src/main/native
- LOCAL_CPPFLAGS += $(core_cppflags)
- LOCAL_LDLIBS += -lpthread
- LOCAL_MODULE_TAGS := optional
- LOCAL_MODULE := libconscrypt_jni
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
- LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libssl-host libcrypto-host libjavacore
- LOCAL_STATIC_LIBRARIES += $(core_static_libraries)
- include $(BUILD_HOST_SHARED_LIBRARY)
+include $(CLEAR_VARS)
+LOCAL_CLANG := true
+LOCAL_SRC_FILES += $(core_src_files)
+LOCAL_CFLAGS += $(core_cflags)
+LOCAL_C_INCLUDES += $(core_c_includes)
+LOCAL_CPPFLAGS += $(core_cppflags)
+LOCAL_LDLIBS += -ldl -lpthread
+ifeq ($(HOST_OS),linux)
+LOCAL_LDLIBS += -lrt
+endif
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libjavacore
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
+LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libexpat-host libicuuc-host libicui18n-host libcrypto-host libz-host
+LOCAL_STATIC_LIBRARIES += $(core_static_libraries) libziparchive-host libutils
+LOCAL_MULTILIB := both
+include $(BUILD_HOST_SHARED_LIBRARY)
- ifeq ($(LIBCORE_SKIP_TESTS),)
+ifeq ($(LIBCORE_SKIP_TESTS),)
include $(CLEAR_VARS)
+ LOCAL_CLANG := true
LOCAL_SRC_FILES += $(core_test_files)
LOCAL_CFLAGS += $(core_cflags)
LOCAL_C_INCLUDES += libcore/include external/openssl/include
@@ -185,5 +143,4 @@ ifeq ($(WITH_HOST_DALVIK),true)
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
LOCAL_SHARED_LIBRARIES := libcrypto-host
include $(BUILD_HOST_SHARED_LIBRARY)
- endif # LIBCORE_SKIP_TESTS
-endif
+endif # LIBCORE_SKIP_TESTS
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index 6902006..c0a38a0 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -1,32 +1,39 @@
+# -*- mode: makefile -*-
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
LOCAL_PATH:= $(call my-dir)
-##################################################
-include $(CLEAR_VARS)
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+ifeq ($(LIBCORE_SKIP_TESTS),)
+##################################################
+include $(CLEAR_VARS)
LOCAL_MODULE := benchmarks
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- caliper-prebuilt \
- core-tests
-
-LOCAL_JAVA_LIBRARIES := \
- bouncycastle \
- conscrypt \
- core
-
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := caliper-prebuilt core-tests
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-libart conscrypt core-junit bouncycastle framework
LOCAL_MODULE_TAGS := tests
-
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/data/caliperperf
-
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_JAVA_LIBRARY)
##################################################
# Prebuilt Java libraries
include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
- caliper-prebuilt:libs/caliper.jar
-
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := caliper-prebuilt:libs/caliper.jar
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_MULTI_PREBUILT)
+
+endif
diff --git a/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java b/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java
new file mode 100644
index 0000000..09b3186
--- /dev/null
+++ b/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+
+public class DeepArrayOpsBenchmark extends SimpleBenchmark {
+ @Param({"1", "4", "16", "256", "2048"}) int arrayLength;
+
+ private Object[] array;
+ private Object[] array2;
+
+ private Object[] array3;
+ private Object[] array4;
+
+ protected void setUp() throws Exception {
+ array = new Object[arrayLength * 13];
+ array2 = new Object[arrayLength * 13];
+ for (int i = 0; i < arrayLength; i += 13) {
+ array[i] = new IntWrapper(i);
+ array2[i] = new IntWrapper(i);
+
+ array[i + 1] = new16ElementObjectarray();
+ array2[i + 1] = new16ElementObjectarray();
+
+ array[i + 2] = new boolean[16];
+ array2[i + 2] = new boolean[16];
+
+ array[i + 3] = new byte[16];
+ array2[i + 3] = new byte[16];
+
+ array[i + 4] = new char[16];
+ array2[i + 4] = new char[16];
+
+ array[i + 5] = new short[16];
+ array2[i + 5] = new short[16];
+
+ array[i + 6] = new float[16];
+ array2[i + 6] = new float[16];
+
+ array[i + 7] = new long[16];
+ array2[i + 7] = new long[16];
+
+ array[i + 8] = new int[16];
+ array2[i + 8] = new int[16];
+
+ array[i + 9] = new double[16];
+ array2[i + 9] = new double[16];
+
+ // Subarray types are concrete objects.
+ array[i + 10] = new16ElementArray(String.class, String.class);
+ array2[i + 10] = new16ElementArray(String.class, String.class);
+
+ array[i + 11] = new16ElementArray(Integer.class, Integer.class);
+ array2[i + 11] = new16ElementArray(Integer.class, Integer.class);
+
+ // Subarray types is an interface.
+ array[i + 12] = new16ElementArray(CharSequence.class, String.class);
+ array2[i + 12] = new16ElementArray(CharSequence.class, String.class);
+ }
+ }
+
+ public void timeDeepHashCode(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ Arrays.deepHashCode(array);
+ }
+ }
+
+ public void timeEquals(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ Arrays.deepEquals(array, array2);
+ }
+ }
+
+ private static final Object[] new16ElementObjectarray() {
+ Object[] array = new Object[16];
+ for (int i = 0; i < 16; ++i) {
+ array[i] = new IntWrapper(i);
+ }
+
+ return array;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final <T, V> T[] new16ElementArray(Class<T> arrayType, Class<V> type)
+ throws Exception {
+ T[] array = (T []) Array.newInstance(type, 16);
+ if (!arrayType.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(arrayType + " is not assignable from " + type);
+ }
+
+ Constructor<V> constructor = type.getDeclaredConstructor(String.class);
+ for (int i = 0; i < 16; ++i) {
+ array[i] = (T) constructor.newInstance(String.valueOf(i + 1000));
+ }
+
+ return array;
+ }
+
+ /**
+ * A class that provides very basic equals() and hashCode() operations
+ * and doesn't resort to memoization tricks like {@link java.lang.Integer}.
+ *
+ * Useful for providing equal objects that aren't the same (a.equals(b) but
+ * a != b).
+ */
+ public static final class IntWrapper {
+ private final int wrapped;
+
+ public IntWrapper(int wrap) {
+ wrapped = wrap;
+ }
+
+ @Override
+ public int hashCode() {
+ return wrapped;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof IntWrapper)) {
+ return false;
+ }
+
+ return ((IntWrapper) o).wrapped == this.wrapped;
+ }
+ }
+}
+
diff --git a/benchmarks/src/benchmarks/ReferenceGetBenchmark.java b/benchmarks/src/benchmarks/ReferenceGetBenchmark.java
new file mode 100644
index 0000000..80142a1
--- /dev/null
+++ b/benchmarks/src/benchmarks/ReferenceGetBenchmark.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.*;
+
+public class ReferenceGetBenchmark extends SimpleBenchmark {
+ @Param boolean intrinsicDisabled;
+
+ private Object obj = "str";
+
+ protected void setUp() throws Exception {
+ Field intrinsicDisabledField = Reference.class.getDeclaredField("disableIntrinsic");
+ intrinsicDisabledField.setAccessible(true);
+ intrinsicDisabledField.setBoolean(null, intrinsicDisabled);
+ }
+
+ public void timeSoftReferenceGet(int reps) throws Exception {
+ Reference soft = new SoftReference(obj);
+ for (int i = 0; i < reps; i++) {
+ Object o = soft.get();
+ }
+ }
+
+ public void timeWeakReferenceGet(int reps) throws Exception {
+ Reference weak = new WeakReference(obj);
+ for (int i = 0; i < reps; i++) {
+ Object o = weak.get();
+ }
+ }
+
+ public void timeNonPreservedWeakReferenceGet(int reps) throws Exception {
+ Reference weak = new WeakReference(obj);
+ obj = null;
+ Runtime.getRuntime().gc();
+ for (int i = 0; i < reps; i++) {
+ Object o = weak.get();
+ }
+ }
+}
diff --git a/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java b/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java
new file mode 100644
index 0000000..5095ee1
--- /dev/null
+++ b/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class SystemArrayCopyBenchmark extends SimpleBenchmark {
+ @Param({"2", "4", "8", "16", "32", "64", "128", "256", "512", "1024",
+ "2048", "4096", "8192", "16384", "32768", "65536", "131072", "262144"})
+ int arrayLength;
+
+ // Provides benchmarking for different types of arrays using the arraycopy function.
+
+ public void timeSystemCharArrayCopy(int reps) {
+ final int len = arrayLength;
+ char[] src = new char[len];
+ char[] dst = new char[len];
+ for (int rep = 0; rep < reps; ++rep) {
+ System.arraycopy(src, 0, dst, 0, len);
+ }
+ }
+
+ public void timeSystemByteArrayCopy(int reps) {
+ final int len = arrayLength;
+ byte[] src = new byte[len];
+ byte[] dst = new byte[len];
+ for (int rep = 0; rep < reps; ++rep) {
+ System.arraycopy(src, 0, dst, 0, len);
+ }
+ }
+
+ public void timeSystemShortArrayCopy(int reps) {
+ final int len = arrayLength;
+ short[] src = new short[len];
+ short[] dst = new short[len];
+ for (int rep = 0; rep < reps; ++rep) {
+ System.arraycopy(src, 0, dst, 0, len);
+ }
+ }
+
+ public void timeSystemIntArrayCopy(int reps) {
+ final int len = arrayLength;
+ int[] src = new int[len];
+ int[] dst = new int[len];
+ for (int rep = 0; rep < reps; ++rep) {
+ System.arraycopy(src, 0, dst, 0, len);
+ }
+ }
+
+ public void timeSystemLongArrayCopy(int reps) {
+ final int len = arrayLength;
+ long[] src = new long[len];
+ long[] dst = new long[len];
+ for (int rep = 0; rep < reps; ++rep) {
+ System.arraycopy(src, 0, dst, 0, len);
+ }
+ }
+
+ public void timeSystemFloatArrayCopy(int reps) {
+ final int len = arrayLength;
+ float[] src = new float[len];
+ float[] dst = new float[len];
+ for (int rep = 0; rep < reps; ++rep) {
+ System.arraycopy(src, 0, dst, 0, len);
+ }
+ }
+
+ public void timeSystemDoubleArrayCopy(int reps) {
+ final int len = arrayLength;
+ double[] src = new double[len];
+ double[] dst = new double[len];
+ for (int rep = 0; rep < reps; ++rep) {
+ System.arraycopy(src, 0, dst, 0, len);
+ }
+ }
+
+ public void timeSystemBooleanArrayCopy(int reps) {
+ final int len = arrayLength;
+ boolean[] src = new boolean[len];
+ boolean[] dst = new boolean[len];
+ for (int rep = 0; rep < reps; ++rep) {
+ System.arraycopy(src, 0, dst, 0, len);
+ }
+ }
+}
diff --git a/benchmarks/src/benchmarks/regression/CipherInputStreamBenchmark.java b/benchmarks/src/benchmarks/regression/CipherInputStreamBenchmark.java
new file mode 100644
index 0000000..9dce12a
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/CipherInputStreamBenchmark.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.CipherInputStream;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * CipherInputStream benchmark.
+ */
+public class CipherInputStreamBenchmark extends SimpleBenchmark {
+
+ private static final int DATA_SIZE = 1024 * 1024;
+ private static final byte[] DATA = new byte[DATA_SIZE];
+
+ private static final int IV_SIZE = 16;
+ private static final byte[] IV = new byte[IV_SIZE];
+
+ static {
+ for (int i = 0; i < DATA_SIZE; i++) {
+ DATA[i] = (byte) i;
+ }
+ for (int i = 0; i < IV_SIZE; i++) {
+ IV[i] = (byte) i;
+ }
+ }
+
+ private SecretKey key;
+
+ private byte[] output = new byte[8192];
+
+ private Cipher cipherEncrypt;
+
+ private AlgorithmParameterSpec spec;
+
+ @Override protected void setUp() throws Exception {
+ KeyGenerator generator = KeyGenerator.getInstance("AES");
+ generator.init(128);
+ key = generator.generateKey();
+
+ spec = new IvParameterSpec(IV);
+
+ cipherEncrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipherEncrypt.init(Cipher.ENCRYPT_MODE, key, spec);
+ }
+
+ public void timeEncrypt(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ cipherEncrypt.init(Cipher.ENCRYPT_MODE, key, spec);
+ InputStream is = new CipherInputStream(new ByteArrayInputStream(DATA), cipherEncrypt);
+ while (is.read(output) != -1) {
+ }
+ }
+ }
+}
diff --git a/benchmarks/src/benchmarks/regression/EqualsHashCodeBenchmark.java b/benchmarks/src/benchmarks/regression/EqualsHashCodeBenchmark.java
index a15a41a..72bb216 100644
--- a/benchmarks/src/benchmarks/regression/EqualsHashCodeBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/EqualsHashCodeBenchmark.java
@@ -36,6 +36,8 @@ public final class EqualsHashCodeBenchmark extends SimpleBenchmark {
abstract Object newInstance(String text) throws Exception;
}
+ private static final String QUERY = "%E0%AE%A8%E0%AE%BE%E0%AE%AE%E0%AF%8D+%E0%AE%AE%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%AF%E0%AE%AE%E0%AE%BE%E0%AE%A9%2C+%E0%AE%9A%E0%AF%81%E0%AE%B5%E0%AE%BE%E0%AE%B0%E0%AE%B8%E0%AF%8D%E0%AE%AF%E0%AE%AE%E0%AE%BE%E0%AE%A9+%E0%AE%87%E0%AE%B0%E0%AF%81%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AF%87%E0%AE%BE%E0%AE%AE%E0%AF%8D%2C+%E0%AE%86%E0%AE%A9%E0%AE%BE%E0%AE%B2%E0%AF%8D+%E0%AE%9A%E0%AE%BF%E0%AE%B2+%E0%AE%A8%E0%AF%87%E0%AE%B0%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%9A%E0%AF%82%E0%AE%B4%E0%AF%8D%E0%AE%A8%E0%AE%BF%E0%AE%B2%E0%AF%88+%E0%AE%8F%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%8E%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AE%BE%E0%AE%B2%E0%AF%8D+%E0%AE%AA%E0%AE%A3%E0%AE%BF%E0%AE%AF%E0%AF%88%E0%AE%AF%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%B5%E0%AE%B2%E0%AE%BF+%E0%AE%85%E0%AE%B5%E0%AE%B0%E0%AF%88+%E0%AE%9A%E0%AE%BF%E0%AE%B2+%E0%AE%AA%E0%AF%86%E0%AE%B0%E0%AE%BF%E0%AE%AF+%E0%AE%95%E0%AF%86%E0%AE%BE%E0%AE%B3%E0%AF%8D%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D+%E0%AE%AE%E0%AF%81%E0%AE%9F%E0%AE%BF%E0%AE%AF%E0%AF%81%E0%AE%AE%E0%AF%8D.+%E0%AE%85%E0%AE%A4%E0%AF%81+%E0%AE%9A%E0%AE%BF%E0%AE%B2+%E0%AE%A8%E0%AE%A9%E0%AF%8D%E0%AE%AE%E0%AF%88%E0%AE%95%E0%AE%B3%E0%AF%88+%E0%AE%AA%E0%AF%86%E0%AE%B1+%E0%AE%A4%E0%AE%B5%E0%AE%BF%E0%AE%B0%2C+%E0%AE%8E%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AF%87%E0%AE%BE%E0%AE%A4%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%89%E0%AE%B4%E0%AF%88%E0%AE%95%E0%AF%8D%E0%AE%95+%E0%AE%89%E0%AE%9F%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AE%AF%E0%AE%BF%E0%AE%B1%E0%AF%8D%E0%AE%9A%E0%AE%BF+%E0%AE%AE%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AF%86%E0%AE%BE%E0%AE%B3%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%B1%E0%AE%A4%E0%AF%81+%E0%AE%8E%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81+%E0%AE%87%E0%AE%A4%E0%AF%81+%E0%AE%92%E0%AE%B0%E0%AF%81+%E0%AE%9A%E0%AE%BF%E0%AE%B1%E0%AE%BF%E0%AE%AF+%E0%AE%89%E0%AE%A4%E0%AE%BE%E0%AE%B0%E0%AE%A3%E0%AE%AE%E0%AF%8D%2C+%E0%AE%8E%E0%AE%9F%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95.+%E0%AE%B0%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%8E%E0%AE%A8%E0%AF%8D%E0%AE%A4+%E0%AE%B5%E0%AE%BF%E0%AE%B3%E0%AF%88%E0%AE%B5%E0%AE%BE%E0%AE%95+%E0%AE%87%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%AE%E0%AF%8D+%E0%AE%86%E0%AE%A9%E0%AF%8D%E0%AE%B2%E0%AF%88%E0%AE%A9%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%9F%E0%AF%81%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%87%E0%AE%B0%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95+%E0%AE%B5%E0%AF%87%E0%AE%A3%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%AF%E0%AE%BE%E0%AE%B0%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%B5%E0%AE%B1%E0%AF%81+%E0%AE%95%E0%AE%A3%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AA%E0%AE%BF%E0%AE%9F%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95+%E0%AE%B5%E0%AE%B0%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%A8%E0%AE%BE%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AF%87%E0%AE%BE%E0%AE%A4%E0%AF%81+%E0%AE%87%E0%AE%B0%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%B1%E0%AF%87%E0%AE%BE%E0%AE%AE%E0%AF%8D.+%E0%AE%87%E0%AE%A8%E0%AF%8D%E0%AE%A4+%E0%AE%A8%E0%AE%BF%E0%AE%95%E0%AE%B4%E0%AF%8D%E0%AE%B5%E0%AF%81%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%A4%E0%AE%AA%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%85%E0%AE%AE%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%95%E0%AE%A3%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81%2C+%E0%AE%85%E0%AE%B5%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%A4%E0%AE%B5%E0%AE%B1%E0%AF%81+%E0%AE%B5%E0%AE%BF%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81+quae+%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AE%B1%E0%AF%88+%E0%AE%A8%E0%AF%80%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%AA%E0%AE%B0%E0%AE%BF%E0%AE%A8%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B0%E0%AF%88%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%B1%E0%AF%87%E0%AE%BE%E0%AE%AE%E0%AF%8D+%E0%AE%AE%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%95+%E0%AE%AE%E0%AE%BE%E0%AE%B1%E0%AF%81%E0%AE%AE%E0%AF%8D";
+
@Param Type type;
Object a1;
@@ -43,11 +45,18 @@ public final class EqualsHashCodeBenchmark extends SimpleBenchmark {
Object b1;
Object b2;
+ Object c1;
+ Object c2;
+
@Override protected void setUp() throws Exception {
a1 = type.newInstance("https://mail.google.com/mail/u/0/?shva=1#inbox");
a2 = type.newInstance("https://mail.google.com/mail/u/0/?shva=1#inbox");
b1 = type.newInstance("http://developer.android.com/reference/java/net/URI.html");
b2 = type.newInstance("http://developer.android.com/reference/java/net/URI.html");
+
+ c1 = type.newInstance("http://developer.android.com/query?q=" + QUERY);
+ // Replace the very last char.
+ c2 = type.newInstance("http://developer.android.com/query?q=" + QUERY.substring(0, QUERY.length() - 3) + "%AF");
}
public void timeEquals(int reps) {
@@ -64,4 +73,10 @@ public final class EqualsHashCodeBenchmark extends SimpleBenchmark {
b1.hashCode();
}
}
+
+ public void timeEqualsWithHeavilyEscapedComponent(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ c1.equals(c2);
+ }
+ }
}
diff --git a/benchmarks/src/benchmarks/regression/IcuBenchmark.java b/benchmarks/src/benchmarks/regression/IcuBenchmark.java
index ee8270a..2aed36b 100644
--- a/benchmarks/src/benchmarks/regression/IcuBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/IcuBenchmark.java
@@ -26,7 +26,7 @@ import libcore.icu.ICU;
public class IcuBenchmark extends SimpleBenchmark {
public void time_getBestDateTimePattern(int reps) throws Exception {
for (int rep = 0; rep < reps; ++rep) {
- ICU.getBestDateTimePattern("dEEEMMM", "US");
+ ICU.getBestDateTimePattern("dEEEMMM", new Locale("en", "US"));
}
}
}
diff --git a/benchmarks/src/benchmarks/regression/MathBenchmark.java b/benchmarks/src/benchmarks/regression/MathBenchmark.java
index 25a871d..19b2162 100644
--- a/benchmarks/src/benchmarks/regression/MathBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/MathBenchmark.java
@@ -30,339 +30,456 @@ public class MathBenchmark extends SimpleBenchmark {
private final int i = 1;
private final long l = 1L;
- public void timeAbsD(int reps) {
+ // NOTE: To avoid the benchmarked function from being optimized away, we store the result
+ // and use it as the benchmark's return value. This is good enough for now but may not be in
+ // the future, a smart compiler could determine that the result value will depend on whether
+ // we get into the loop or not and turn the whole loop into an if statement.
+
+ public double timeAbsD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.abs(d);
+ result = Math.abs(d);
}
+ return result;
}
- public void timeAbsF(int reps) {
+ public float timeAbsF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.abs(f);
+ result = Math.abs(f);
}
+ return result;
}
- public void timeAbsI(int reps) {
+ public int timeAbsI(int reps) {
+ int result = i;
for (int rep = 0; rep < reps; ++rep) {
- Math.abs(i);
+ result = Math.abs(i);
}
+ return result;
}
- public void timeAbsL(int reps) {
+ public long timeAbsL(int reps) {
+ long result = l;
for (int rep = 0; rep < reps; ++rep) {
- Math.abs(l);
+ result = Math.abs(l);
}
+ return result;
}
- public void timeAcos(int reps) {
+ public double timeAcos(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.acos(d);
+ result = Math.acos(d);
}
+ return result;
}
- public void timeAsin(int reps) {
+ public double timeAsin(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.asin(d);
+ result = Math.asin(d);
}
+ return result;
}
- public void timeAtan(int reps) {
+ public double timeAtan(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.atan(d);
+ result = Math.atan(d);
}
+ return result;
}
- public void timeAtan2(int reps) {
+ public double timeAtan2(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.atan2(3, 4);
+ result = Math.atan2(3, 4);
}
+ return result;
}
- public void timeCbrt(int reps) {
+ public double timeCbrt(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.cbrt(d);
+ result = Math.cbrt(d);
}
+ return result;
}
- public void timeCeil(int reps) {
+ public double timeCeil(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.ceil(d);
+ result = Math.ceil(d);
}
+ return result;
}
- public void timeCopySignD(int reps) {
+ public double timeCopySignD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.copySign(d, d);
+ result = Math.copySign(d, d);
}
+ return result;
}
- public void timeCopySignF(int reps) {
+ public float timeCopySignF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.copySign(f, f);
+ result = Math.copySign(f, f);
}
+ return result;
}
- public void timeCopySignD_strict(int reps) {
+ public double timeCopySignD_strict(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- StrictMath.copySign(d, d);
+ result = StrictMath.copySign(d, d);
}
+ return result;
}
- public void timeCopySignF_strict(int reps) {
+ public float timeCopySignF_strict(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- StrictMath.copySign(f, f);
+ result = StrictMath.copySign(f, f);
}
+ return result;
}
- public void timeCos(int reps) {
+ public double timeCos(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.cos(d);
+ result = Math.cos(d);
}
+ return result;
}
- public void timeCosh(int reps) {
+ public double timeCosh(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.cosh(d);
+ result = Math.cosh(d);
}
+ return result;
}
- public void timeExp(int reps) {
+ public double timeExp(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.exp(d);
+ result = Math.exp(d);
}
+ return result;
}
- public void timeExpm1(int reps) {
+ public double timeExpm1(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.expm1(d);
+ result = Math.expm1(d);
}
+ return result;
}
- public void timeFloor(int reps) {
+ public double timeFloor(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.floor(d);
+ result = Math.floor(d);
}
+ return result;
}
- public void timeGetExponentD(int reps) {
+ public int timeGetExponentD(int reps) {
+ int result = i;
for (int rep = 0; rep < reps; ++rep) {
- Math.getExponent(d);
+ result = Math.getExponent(d);
}
+ return result;
}
- public void timeGetExponentF(int reps) {
+ public int timeGetExponentF(int reps) {
+ int result = i;
for (int rep = 0; rep < reps; ++rep) {
- Math.getExponent(f);
+ result = Math.getExponent(f);
}
+ return result;
}
- public void timeHypot(int reps) {
+ public double timeHypot(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.hypot(d, d);
+ result = Math.hypot(d, d);
}
+ return result;
}
- public void timeIEEEremainder(int reps) {
+ public double timeIEEEremainder(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.IEEEremainder(d, d);
+ result = Math.IEEEremainder(d, d);
}
+ return result;
}
- public void timeLog(int reps) {
+ public double timeLog(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.log(d);
+ result = Math.log(d);
}
+ return result;
}
- public void timeLog10(int reps) {
+ public double timeLog10(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.log10(d);
+ result = Math.log10(d);
}
+ return result;
}
- public void timeLog1p(int reps) {
+ public double timeLog1p(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.log1p(d);
+ result = Math.log1p(d);
}
+ return result;
}
- public void timeMaxD(int reps) {
+ public double timeMaxD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.max(d, d);
+ result = Math.max(d, d);
}
+ return result;
}
- public void timeMaxF(int reps) {
+ public float timeMaxF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.max(f, f);
+ result = Math.max(f, f);
}
+ return result;
}
- public void timeMaxI(int reps) {
+ public int timeMaxI(int reps) {
+ int result = i;
for (int rep = 0; rep < reps; ++rep) {
- Math.max(i, i);
+ result = Math.max(i, i);
}
+ return result;
}
- public void timeMaxL(int reps) {
+ public long timeMaxL(int reps) {
+ long result = l;
for (int rep = 0; rep < reps; ++rep) {
- Math.max(l, l);
+ result = Math.max(l, l);
}
+ return result;
}
- public void timeMinD(int reps) {
+ public double timeMinD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.min(d, d);
+ result = Math.min(d, d);
}
+ return result;
}
- public void timeMinF(int reps) {
+ public float timeMinF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.min(f, f);
+ result = Math.min(f, f);
}
+ return result;
}
- public void timeMinI(int reps) {
+ public int timeMinI(int reps) {
+ int result = i;
for (int rep = 0; rep < reps; ++rep) {
- Math.min(i, i);
+ result = Math.min(i, i);
}
+ return result;
}
- public void timeMinL(int reps) {
+ public long timeMinL(int reps) {
+ long result = l;
for (int rep = 0; rep < reps; ++rep) {
- Math.min(l, l);
+ result = Math.min(l, l);
}
+ return result;
}
- public void timeNextAfterD(int reps) {
+ public double timeNextAfterD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.nextAfter(d, d);
+ result = Math.nextAfter(d, d);
}
+ return result;
}
- public void timeNextAfterF(int reps) {
+ public float timeNextAfterF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.nextAfter(f, f);
+ result = Math.nextAfter(f, f);
}
+ return result;
}
- public void timeNextUpD(int reps) {
+ public double timeNextUpD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.nextUp(d);
+ result = Math.nextUp(d);
}
+ return result;
}
- public void timeNextUpF(int reps) {
+ public float timeNextUpF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.nextUp(f);
+ result = Math.nextUp(f);
}
+ return result;
}
- public void timePow(int reps) {
+ public double timePow(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.pow(d, d);
+ result = Math.pow(d, d);
}
+ return result;
}
- public void timeRandom(int reps) {
+ public double timeRandom(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.random();
+ result = Math.random();
}
+ return result;
}
- public void timeRint(int reps) {
+ public double timeRint(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.rint(d);
+ result = Math.rint(d);
}
+ return result;
}
- public void timeRoundD(int reps) {
+ public long timeRoundD(int reps) {
+ long result = l;
for (int rep = 0; rep < reps; ++rep) {
- Math.round(d);
+ result = Math.round(d);
}
+ return result;
}
- public void timeRoundF(int reps) {
+ public int timeRoundF(int reps) {
+ int result = i;
for (int rep = 0; rep < reps; ++rep) {
- Math.round(f);
+ result = Math.round(f);
}
+ return result;
}
- public void timeScalbD(int reps) {
+ public double timeScalbD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.scalb(d, 5);
+ result = Math.scalb(d, 5);
}
+ return result;
}
- public void timeScalbF(int reps) {
+ public float timeScalbF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.scalb(f, 5);
+ result = Math.scalb(f, 5);
}
+ return result;
}
- public void timeSignumD(int reps) {
+ public double timeSignumD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.signum(d);
+ result = Math.signum(d);
}
+ return result;
}
- public void timeSignumF(int reps) {
+ public float timeSignumF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.signum(f);
+ result = Math.signum(f);
}
+ return result;
}
- public void timeSin(int reps) {
+ public double timeSin(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.sin(d);
+ result = Math.sin(d);
}
+ return result;
}
- public void timeSinh(int reps) {
+ public double timeSinh(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.sinh(d);
+ result = Math.sinh(d);
}
+ return result;
}
- public void timeSqrt(int reps) {
+ public double timeSqrt(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.sqrt(d);
+ result = Math.sqrt(d);
}
+ return result;
}
- public void timeTan(int reps) {
+ public double timeTan(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.tan(d);
+ result = Math.tan(d);
}
+ return result;
}
- public void timeTanh(int reps) {
+ public double timeTanh(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.tanh(d);
+ result = Math.tanh(d);
}
+ return result;
}
- public void timeToDegrees(int reps) {
+ public double timeToDegrees(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.toDegrees(d);
+ result = Math.toDegrees(d);
}
+ return result;
}
- public void timeToRadians(int reps) {
+ public double timeToRadians(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.toRadians(d);
+ result = Math.toRadians(d);
}
+ return result;
}
- public void timeUlpD(int reps) {
+ public double timeUlpD(int reps) {
+ double result = d;
for (int rep = 0; rep < reps; ++rep) {
- Math.ulp(d);
+ result = Math.ulp(d);
}
+ return result;
}
- public void timeUlpF(int reps) {
+ public float timeUlpF(int reps) {
+ float result = f;
for (int rep = 0; rep < reps; ++rep) {
- Math.ulp(f);
+ result = Math.ulp(f);
}
+ return result;
}
}
diff --git a/benchmarks/src/benchmarks/regression/SSLLoopbackBenchmark.java b/benchmarks/src/benchmarks/regression/SSLLoopbackBenchmark.java
new file mode 100644
index 0000000..0d9a792
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/SSLLoopbackBenchmark.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks.regression;
+
+import com.google.caliper.SimpleBenchmark;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URL;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+
+import libcore.java.security.TestKeyStore;
+import libcore.javax.net.ssl.TestSSLContext;
+import libcore.javax.net.ssl.TestSSLSocketPair;
+
+public class SSLLoopbackBenchmark extends SimpleBenchmark {
+
+ public void time(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ TestSSLContext context = TestSSLContext.create(
+ TestKeyStore.getClient(), TestKeyStore.getServer());
+ SSLSocket[] sockets = TestSSLSocketPair.connect(context, null, null);
+ context.close();
+ sockets[0].close();
+ sockets[1].close();
+ }
+ }
+}
diff --git a/benchmarks/src/benchmarks/regression/SSLSocketBenchmark.java b/benchmarks/src/benchmarks/regression/SSLSocketBenchmark.java
index fd72a79..5be890e 100644
--- a/benchmarks/src/benchmarks/regression/SSLSocketBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/SSLSocketBenchmark.java
@@ -69,24 +69,10 @@ public class SSLSocketBenchmark extends SimpleBenchmark {
}
}
- @Param private Implementation implementation;
-
- public enum Implementation { OPENSSL, HARMONY };
-
private SocketFactory sf;
@Override protected void setUp() throws Exception {
- SSLContext sslContext;
- switch (implementation) {
- case OPENSSL:
- sslContext = SSLContext.getInstance("SSL", "AndroidOpenSSL");
- break;
- case HARMONY:
- sslContext = SSLContext.getInstance("SSL", "HarmonyJSSE");
- break;
- default:
- throw new RuntimeException(implementation.toString());
- }
+ SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, null, null);
this.sf = sslContext.getSocketFactory();
}
diff --git a/benchmarks/src/benchmarks/regression/SSLSocketFactoryBenchmark.java b/benchmarks/src/benchmarks/regression/SSLSocketFactoryBenchmark.java
new file mode 100644
index 0000000..d0448d6
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/SSLSocketFactoryBenchmark.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+import javax.net.ssl.SSLSocketFactory;
+
+public class SSLSocketFactoryBenchmark extends SimpleBenchmark {
+ public void time(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ SSLSocketFactory.getDefault();
+ }
+ }
+}
diff --git a/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java b/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
index ba5b59e..ae6b6b6 100644
--- a/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
@@ -78,6 +78,14 @@ public class StringCaseMappingBenchmark extends SimpleBenchmark {
}
}
+ // toUpperCase for Greek is an extra-hard case that uses icu4c's Transliterator.
+ public void timeToUpperCase_el_GR(int reps) {
+ Locale el_GR = new Locale("el", "GR");
+ for (int i = 0; i < reps; ++i) {
+ s.value.toUpperCase(el_GR);
+ }
+ }
+
public void timeToLowerCase_US(int reps) {
for (int i = 0; i < reps; ++i) {
s.value.toUpperCase(Locale.US);
@@ -98,13 +106,13 @@ public class StringCaseMappingBenchmark extends SimpleBenchmark {
public void timeToUpperCase_ICU(int reps) {
for (int i = 0; i < reps; ++i) {
- libcore.icu.ICU.toUpperCase(s.value, Locale.US.toString());
+ libcore.icu.ICU.toUpperCase(s.value, Locale.US);
}
}
public void timeToLowerCase_ICU(int reps) {
for (int i = 0; i < reps; ++i) {
- libcore.icu.ICU.toLowerCase(s.value, Locale.US.toString());
+ libcore.icu.ICU.toLowerCase(s.value, Locale.US);
}
}
diff --git a/crypto/jarjar-rules.txt b/crypto/jarjar-rules.txt
deleted file mode 100644
index 0eb6ac2..0000000
--- a/crypto/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-rule org.conscrypt.** com.android.@0
diff --git a/crypto/src/main/java/org/conscrypt/AbstractSessionContext.java b/crypto/src/main/java/org/conscrypt/AbstractSessionContext.java
deleted file mode 100644
index 4aed70c..0000000
--- a/crypto/src/main/java/org/conscrypt/AbstractSessionContext.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-
-/**
- * Supports SSL session caches.
- */
-abstract class AbstractSessionContext implements SSLSessionContext {
-
- volatile int maximumSize;
- volatile int timeout;
-
- final long sslCtxNativePointer = NativeCrypto.SSL_CTX_new();
-
- /** Identifies OpenSSL sessions. */
- static final int OPEN_SSL = 1;
-
- private final Map<ByteArray, SSLSession> sessions
- = new LinkedHashMap<ByteArray, SSLSession>() {
- @Override
- protected boolean removeEldestEntry(
- Map.Entry<ByteArray, SSLSession> eldest) {
- boolean remove = maximumSize > 0 && size() > maximumSize;
- if (remove) {
- remove(eldest.getKey());
- sessionRemoved(eldest.getValue());
- }
- return false;
- }
- };
-
- /**
- * Constructs a new session context.
- *
- * @param maximumSize of cache
- * @param timeout for cache entries
- */
- AbstractSessionContext(int maximumSize, int timeout) {
- this.maximumSize = maximumSize;
- this.timeout = timeout;
- }
-
- /**
- * Returns the collection of sessions ordered from oldest to newest
- */
- private Iterator<SSLSession> sessionIterator() {
- synchronized (sessions) {
- SSLSession[] array = sessions.values().toArray(
- new SSLSession[sessions.size()]);
- return Arrays.asList(array).iterator();
- }
- }
-
- public final Enumeration<byte[]> getIds() {
- final Iterator<SSLSession> i = sessionIterator();
- return new Enumeration<byte[]>() {
- private SSLSession next;
- public boolean hasMoreElements() {
- if (next != null) {
- return true;
- }
- while (i.hasNext()) {
- SSLSession session = i.next();
- if (session.isValid()) {
- next = session;
- return true;
- }
- }
- next = null;
- return false;
- }
- public byte[] nextElement() {
- if (hasMoreElements()) {
- byte[] id = next.getId();
- next = null;
- return id;
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- public final int getSessionCacheSize() {
- return maximumSize;
- }
-
- public final int getSessionTimeout() {
- return timeout;
- }
-
- /**
- * Makes sure cache size is < maximumSize.
- */
- protected void trimToSize() {
- synchronized (sessions) {
- int size = sessions.size();
- if (size > maximumSize) {
- int removals = size - maximumSize;
- Iterator<SSLSession> i = sessions.values().iterator();
- do {
- SSLSession session = i.next();
- i.remove();
- sessionRemoved(session);
- } while (--removals > 0);
- }
- }
- }
-
- public void setSessionTimeout(int seconds)
- throws IllegalArgumentException {
- if (seconds < 0) {
- throw new IllegalArgumentException("seconds < 0");
- }
- timeout = seconds;
-
- synchronized (sessions) {
- Iterator<SSLSession> i = sessions.values().iterator();
- while (i.hasNext()) {
- SSLSession session = i.next();
- // SSLSession's know their context and consult the
- // timeout as part of their validity condition.
- if (!session.isValid()) {
- i.remove();
- sessionRemoved(session);
- }
- }
- }
- }
-
- /**
- * Called when a session is removed. Used by ClientSessionContext
- * to update its host-and-port based cache.
- */
- protected abstract void sessionRemoved(SSLSession session);
-
- public final void setSessionCacheSize(int size)
- throws IllegalArgumentException {
- if (size < 0) {
- throw new IllegalArgumentException("size < 0");
- }
-
- int oldMaximum = maximumSize;
- maximumSize = size;
-
- // Trim cache to size if necessary.
- if (size < oldMaximum) {
- trimToSize();
- }
- }
-
- /**
- * Converts the given session to bytes.
- *
- * @return session data as bytes or null if the session can't be converted
- */
- byte[] toBytes(SSLSession session) {
- // TODO: Support SSLSessionImpl, too.
- if (!(session instanceof OpenSSLSessionImpl)) {
- return null;
- }
-
- OpenSSLSessionImpl sslSession = (OpenSSLSessionImpl) session;
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream daos = new DataOutputStream(baos);
-
- daos.writeInt(OPEN_SSL); // session type ID
-
- // Session data.
- byte[] data = sslSession.getEncoded();
- daos.writeInt(data.length);
- daos.write(data);
-
- // Certificates.
- Certificate[] certs = session.getPeerCertificates();
- daos.writeInt(certs.length);
-
- for (Certificate cert : certs) {
- data = cert.getEncoded();
- daos.writeInt(data.length);
- daos.write(data);
- }
- // TODO: local certificates?
-
- return baos.toByteArray();
- } catch (IOException e) {
- log(e);
- return null;
- } catch (CertificateEncodingException e) {
- log(e);
- return null;
- }
- }
-
- /**
- * Creates a session from the given bytes.
- *
- * @return a session or null if the session can't be converted
- */
- SSLSession toSession(byte[] data, String host, int port) {
- ByteArrayInputStream bais = new ByteArrayInputStream(data);
- DataInputStream dais = new DataInputStream(bais);
- try {
- int type = dais.readInt();
- if (type != OPEN_SSL) {
- log(new AssertionError("Unexpected type ID: " + type));
- return null;
- }
-
- int length = dais.readInt();
- byte[] sessionData = new byte[length];
- dais.readFully(sessionData);
-
- int count = dais.readInt();
- X509Certificate[] certs = new X509Certificate[count];
- for (int i = 0; i < count; i++) {
- length = dais.readInt();
- byte[] certData = new byte[length];
- dais.readFully(certData);
- certs[i] = OpenSSLX509Certificate.fromX509Der(certData);
- }
-
- return new OpenSSLSessionImpl(sessionData, host, port, certs, this);
- } catch (IOException e) {
- log(e);
- return null;
- }
- }
-
- public SSLSession getSession(byte[] sessionId) {
- if (sessionId == null) {
- throw new NullPointerException("sessionId == null");
- }
- ByteArray key = new ByteArray(sessionId);
- SSLSession session;
- synchronized (sessions) {
- session = sessions.get(key);
- }
- if (session != null && session.isValid()) {
- return session;
- }
- return null;
- }
-
- void putSession(SSLSession session) {
- byte[] id = session.getId();
- if (id.length == 0) {
- return;
- }
- ByteArray key = new ByteArray(id);
- synchronized (sessions) {
- sessions.put(key, session);
- }
- }
-
- static void log(Throwable t) {
- System.logW("Error converting session.", t);
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- NativeCrypto.SSL_CTX_free(sslCtxNativePointer);
- } finally {
- super.finalize();
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/AlertException.java b/crypto/src/main/java/org/conscrypt/AlertException.java
deleted file mode 100644
index a483021..0000000
--- a/crypto/src/main/java/org/conscrypt/AlertException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLException;
-
-/**
- * This exception is used to signal that a fatal alert has occurred while working through the
- * protocol.
- */
-public class AlertException extends RuntimeException {
-
- private static final long serialVersionUID = -4448327177165687581L;
- // SSLException to be thrown to application side
- private final SSLException reason;
- // alert description code
- private final byte description;
-
- /**
- * Constructs the instance.
- *
- * @param description The alert description code from {@link AlertProtocol}
- * @param reason The SSLException to be thrown to application side after alert processing
- * (sending the record with alert, shutdown work, etc).
- * @see AlertProtocol
- */
- protected AlertException(byte description, SSLException reason) {
- super(reason);
- this.reason = reason;
- this.description = description;
- }
-
- /**
- * Returns the reason of alert. This reason should be rethrown after alert processing.
- *
- * @return the reason of alert.
- */
- protected SSLException getReason() {
- return reason;
- }
-
- /**
- * Returns alert's description code.
- *
- * @return alert description code from {@link AlertProtocol}
- * @see AlertProtocol for more information about possible reason codes.
- */
- protected byte getDescriptionCode() {
- return description;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/AlertProtocol.java b/crypto/src/main/java/org/conscrypt/AlertProtocol.java
deleted file mode 100644
index 0330e79..0000000
--- a/crypto/src/main/java/org/conscrypt/AlertProtocol.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * This class encapsulates the functionality of Alert Protocol.
- * Constant values are taken according to the TLS v1 specification
- * (http://www.ietf.org/rfc/rfc2246.txt), p 7.2.
- */
-public class AlertProtocol {
-
- // ------------------------ AlertLevel codes --------------------------
- /**
- * Defines the severity of alert as warning
- */
- protected static final byte WARNING = 1;
- /**
- * Defines the severity of alert as fatal
- */
- protected static final byte FATAL = 2;
-
- // --------------------- AlertDescription codes -----------------------
- /**
- * Defines the description code of the close_notify alert
- */
- protected static final byte CLOSE_NOTIFY = 0;
- /**
- * Defines the description code of the unexpected_message alert
- */
- protected static final byte UNEXPECTED_MESSAGE = 10;
- /**
- * Defines the description code of the bad_record_mac alert
- */
- protected static final byte BAD_RECORD_MAC = 20;
- /**
- * Defines the description code of the decryption_failed alert
- */
- protected static final byte DECRYPTION_FAILED = 21;
- /**
- * Defines the description code of the record_overflow alert
- */
- protected static final byte RECORD_OVERFLOW = 22;
- /**
- * Defines the description code of the decompression_failure alert
- */
- protected static final byte DECOMPRESSION_FAILURE = 30;
- /**
- * Defines the description code of the handshake_failure alert
- */
- protected static final byte HANDSHAKE_FAILURE = 40;
- /**
- * Defines the description code of the bad_certificate alert
- */
- protected static final byte BAD_CERTIFICATE = 42;
- /**
- * Defines the description code of the unsupported_certificate alert
- */
- protected static final byte UNSUPPORTED_CERTIFICATE = 43;
- /**
- * Defines the description code of the certificate_revoked alert
- */
- protected static final byte CERTIFICATE_REVOKED = 44;
- /**
- * Defines the description code of the certificate_expired alert
- */
- protected static final byte CERTIFICATE_EXPIRED = 45;
- /**
- * Defines the description code of the certificate_unknown alert
- */
- protected static final byte CERTIFICATE_UNKNOWN = 46;
- /**
- * Defines the description code of the illegal_parameter alert
- */
- protected static final byte ILLEGAL_PARAMETER = 47;
- /**
- * Defines the description code of the unknown_ca alert
- */
- protected static final byte UNKNOWN_CA = 48;
- /**
- * Defines the description code of the access_denied alert
- */
- protected static final byte ACCESS_DENIED = 49;
- /**
- * Defines the description code of the decode_error alert
- */
- protected static final byte DECODE_ERROR = 50;
- /**
- * Defines the description code of the decrypt_error alert
- */
- protected static final byte DECRYPT_ERROR = 51;
- /**
- * Defines the description code of the export_restriction alert
- */
- protected static final byte EXPORT_RESTRICTION = 60;
- /**
- * Defines the description code of the protocol_version alert
- */
- protected static final byte PROTOCOL_VERSION = 70;
- /**
- * Defines the description code of the insufficient_security alert
- */
- protected static final byte INSUFFICIENT_SECURITY = 71;
- /**
- * Defines the description code of the internal_error alert
- */
- protected static final byte INTERNAL_ERROR = 80;
- /**
- * Defines the description code of the user_canceled alert
- */
- protected static final byte USER_CANCELED = 90;
- /**
- * Defines the description code of the no_renegotiation alert
- */
- protected static final byte NO_RENEGOTIATION = 100;
- // holds level and description codes
- private final byte[] alert = new byte[2];
- // record protocol to be used to wrap the alerts
- private SSLRecordProtocol recordProtocol;
-
- private Logger.Stream logger = Logger.getStream("alert");
-
- /**
- * Creates the instance of AlertProtocol.
- * Note that class is not ready to work without providing of
- * record protocol
- * @see #setRecordProtocol
- */
- protected AlertProtocol() {}
-
- /**
- * Sets up the record protocol to be used by this allert protocol.
- */
- protected void setRecordProtocol(SSLRecordProtocol recordProtocol) {
- this.recordProtocol = recordProtocol;
- }
-
- /**
- * Reports an alert to be sent/received by transport.
- * This method is usually called during processing
- * of the income TSL record: if it contains alert message from another
- * peer, or if warning alert occured during the processing of the
- * message and this warning should be sent to another peer.
- * @param level alert level code
- * @param description alert description code
- */
- protected void alert(byte level, byte description) {
- if (logger != null) {
- logger.println("Alert.alert: "+level+" "+description);
- }
- this.alert[0] = level;
- this.alert[1] = description;
- }
-
- /**
- * Returns the description code of alert or -100 if there
- * is no alert.
- */
- protected byte getDescriptionCode() {
- return (alert[0] != 0) ? alert[1] : -100;
- }
-
- /**
- * Resets the protocol to be in "no alert" state.
- * This method shoud be called after processing of the reported alert.
- */
- protected void setProcessed() {
- // free the info about alert
- if (logger != null) {
- logger.println("Alert.setProcessed");
- }
- this.alert[0] = 0;
- }
-
- /**
- * Checks if any alert has occured.
- */
- protected boolean hasAlert() {
- return (alert[0] != 0);
- }
-
- /**
- * Checks if occured alert is fatal alert.
- */
- protected boolean isFatalAlert() {
- return (alert[0] == 2);
- }
-
- /**
- * Returns the string representation of occured alert.
- * If no alert has occured null is returned.
- */
- protected String getAlertDescription() {
- switch (alert[1]) {
- case CLOSE_NOTIFY:
- return "close_notify";
- case UNEXPECTED_MESSAGE:
- return "unexpected_message";
- case BAD_RECORD_MAC:
- return "bad_record_mac";
- case DECRYPTION_FAILED:
- return "decryption_failed";
- case RECORD_OVERFLOW:
- return "record_overflow";
- case DECOMPRESSION_FAILURE:
- return "decompression_failure";
- case HANDSHAKE_FAILURE:
- return "handshake_failure";
- case BAD_CERTIFICATE:
- return "bad_certificate";
- case UNSUPPORTED_CERTIFICATE:
- return "unsupported_certificate";
- case CERTIFICATE_REVOKED:
- return "certificate_revoked";
- case CERTIFICATE_EXPIRED:
- return "certificate_expired";
- case CERTIFICATE_UNKNOWN:
- return "certificate_unknown";
- case ILLEGAL_PARAMETER:
- return "illegal_parameter";
- case UNKNOWN_CA:
- return "unknown_ca";
- case ACCESS_DENIED:
- return "access_denied";
- case DECODE_ERROR:
- return "decode_error";
- case DECRYPT_ERROR:
- return "decrypt_error";
- case EXPORT_RESTRICTION:
- return "export_restriction";
- case PROTOCOL_VERSION:
- return "protocol_version";
- case INSUFFICIENT_SECURITY:
- return "insufficient_security";
- case INTERNAL_ERROR:
- return "internal_error";
- case USER_CANCELED:
- return "user_canceled";
- case NO_RENEGOTIATION:
- return "no_renegotiation";
- }
- return null;
- }
-
- /**
- * Returns the record with reported alert message.
- * The returned array of bytes is ready to be sent to another peer.
- * Note, that this method does not automatically set the state of alert
- * protocol in "no alert" state, so after wrapping the method setProcessed
- * should be called.
- */
- protected byte[] wrap() {
- byte[] res = recordProtocol.wrap(ContentType.ALERT, alert, 0, 2);
- return res;
- }
-
- /**
- * Shutdown the protocol. It will be impossible to use the instance
- * after the calling of this method.
- */
- protected void shutdown() {
- alert[0] = 0;
- alert[1] = 0;
- recordProtocol = null;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/Appendable.java b/crypto/src/main/java/org/conscrypt/Appendable.java
deleted file mode 100644
index d22c5a8..0000000
--- a/crypto/src/main/java/org/conscrypt/Appendable.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * This interface represents the ability of the input stream related classes to provide additional
- * data to be read.
- */
-public interface Appendable {
-
- /**
- * Provides the additional data to be read.
- *
- * @param src the source data to be appended.
- */
- public void append(byte[] src);
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/ByteArray.java b/crypto/src/main/java/org/conscrypt/ByteArray.java
deleted file mode 100644
index be682de..0000000
--- a/crypto/src/main/java/org/conscrypt/ByteArray.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.util.Arrays;
-
-/**
- * Byte array wrapper for hashtable use. Implements equals() and hashCode().
- */
-final class ByteArray {
- private final byte[] bytes;
- private final int hashCode;
-
- ByteArray(byte[] bytes) {
- this.bytes = bytes;
- this.hashCode = Arrays.hashCode(bytes);
- }
-
- @Override public int hashCode() {
- return hashCode;
- }
-
- @Override public boolean equals(Object o) {
- if (!(o instanceof ByteArray)) {
- return false;
- }
- ByteArray lhs = (ByteArray) o;
- return Arrays.equals(bytes, lhs.bytes);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/CertPinManager.java b/crypto/src/main/java/org/conscrypt/CertPinManager.java
deleted file mode 100644
index 22578fc..0000000
--- a/crypto/src/main/java/org/conscrypt/CertPinManager.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import libcore.io.IoUtils;
-import libcore.util.BasicLruCache;
-
-/**
- * This class provides a simple interface for cert pinning.
- */
-public class CertPinManager {
-
- private long lastModified;
-
- private final Map<String, PinListEntry> entries = new HashMap<String, PinListEntry>();
- private final BasicLruCache<String, String> hostnameCache = new BasicLruCache<String, String>(10);
-
- private boolean initialized = false;
- private static final boolean DEBUG = false;
-
- private final File pinFile;
- private final TrustedCertificateStore certStore;
-
- public CertPinManager(TrustedCertificateStore store) throws PinManagerException {
- pinFile = new File("/data/misc/keychain/pins");
- certStore = store;
- rebuild();
- }
-
- /** Test only */
- public CertPinManager(String path, TrustedCertificateStore store) throws PinManagerException {
- if (path == null) {
- throw new NullPointerException("path == null");
- }
- pinFile = new File(path);
- certStore = store;
- rebuild();
- }
-
- /**
- * This is the public interface for cert pinning.
- *
- * Given a hostname and a certificate chain this verifies that the chain includes
- * certs from the pinned list provided.
- *
- * If the chain doesn't include those certs and is in enforcing mode, then this method
- * returns true and the certificate check should fail.
- */
- public boolean chainIsNotPinned(String hostname, List<X509Certificate> chain)
- throws PinManagerException {
- // lookup the entry
- PinListEntry entry = lookup(hostname);
-
- // return its result or false if there's no pin
- if (entry != null) {
- return entry.chainIsNotPinned(chain);
- }
- return false;
- }
-
- private synchronized void rebuild() throws PinManagerException {
- // reread the pin file
- String pinFileContents = readPinFile();
-
- if (pinFileContents != null) {
- // rebuild the pinned certs
- for (String entry : getPinFileEntries(pinFileContents)) {
- try {
- PinListEntry pin = new PinListEntry(entry, certStore);
- entries.put(pin.getCommonName(), pin);
- } catch (PinEntryException e) {
- log("Pinlist contains a malformed pin: " + entry, e);
- }
- }
-
- // clear the cache
- hostnameCache.evictAll();
-
- // set the last modified time
- lastModified = pinFile.lastModified();
-
- // we've been fully initialized and are ready to go
- initialized = true;
- }
- }
-
- private String readPinFile() throws PinManagerException {
- try {
- return IoUtils.readFileAsString(pinFile.getPath());
- } catch (FileNotFoundException e) {
- // there's no pin list, all certs are unpinned
- return null;
- } catch (IOException e) {
- // this is unexpected, fail
- throw new PinManagerException("Unexpected error reading pin list; failing.", e);
- }
- }
-
- private static String[] getPinFileEntries(String pinFileContents) {
- return pinFileContents.split("\n");
- }
-
- private synchronized PinListEntry lookup(String hostname) throws PinManagerException {
-
- // if we don't have any data, don't bother
- if (!initialized) {
- return null;
- }
-
- // check to see if our cache is valid
- if (cacheIsNotValid()) {
- rebuild();
- }
-
- // if so, check the hostname cache
- String cn = hostnameCache.get(hostname);
- if (cn != null) {
- // if we hit, return the corresponding entry
- return entries.get(cn);
- }
-
- // otherwise, get the matching cn
- cn = getMatchingCN(hostname);
- if (cn != null) {
- hostnameCache.put(hostname, cn);
- // we have a matching CN, return that entry
- return entries.get(cn);
- }
-
- // if we got here, we don't have a matching CN for this hostname
- return null;
- }
-
- private boolean cacheIsNotValid() {
- return pinFile.lastModified() != lastModified;
- }
-
- private String getMatchingCN(String hostname) {
- String bestMatch = "";
- for (String cn : entries.keySet()) {
- // skip shorter CNs since they can't be better matches
- if (cn.length() < bestMatch.length()) {
- continue;
- }
- // now verify that the CN matches at all
- if (isHostnameMatchedBy(hostname, cn)) {
- bestMatch = cn;
- }
- }
- return bestMatch;
- }
-
- /**
- * Returns true if {@code hostName} matches the name or pattern {@code cn}.
- *
- * @param hostName lowercase host name.
- * @param cn certificate host name. May include wildcards like
- * {@code *.android.com}.
- */
- private static boolean isHostnameMatchedBy(String hostName, String cn) {
- if (hostName == null || hostName.isEmpty() || cn == null || cn.isEmpty()) {
- return false;
- }
-
- cn = cn.toLowerCase(Locale.US);
-
- if (!cn.contains("*")) {
- return hostName.equals(cn);
- }
-
- if (cn.startsWith("*.") && hostName.regionMatches(0, cn, 2, cn.length() - 2)) {
- return true; // "*.foo.com" matches "foo.com"
- }
-
- int asterisk = cn.indexOf('*');
- int dot = cn.indexOf('.');
- if (asterisk > dot) {
- return false; // malformed; wildcard must be in the first part of
- // the cn
- }
-
- if (!hostName.regionMatches(0, cn, 0, asterisk)) {
- return false; // prefix before '*' doesn't match
- }
-
- int suffixLength = cn.length() - (asterisk + 1);
- int suffixStart = hostName.length() - suffixLength;
- if (hostName.indexOf('.', asterisk) < suffixStart) {
- return false; // wildcard '*' can't match a '.'
- }
-
- if (!hostName.regionMatches(suffixStart, cn, asterisk + 1, suffixLength)) {
- return false; // suffix after '*' doesn't match
- }
-
- return true;
- }
-
- private static void log(String s, Exception e) {
- if (DEBUG) {
- System.out.println("PINFILE: " + s);
- if (e != null) {
- e.printStackTrace();
- }
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/CertificateMessage.java b/crypto/src/main/java/org/conscrypt/CertificateMessage.java
deleted file mode 100644
index 0c0e092..0000000
--- a/crypto/src/main/java/org/conscrypt/CertificateMessage.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-
-/**
- * Represents server/client certificate message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS
- * 1.0 spec., 7.4.2. Server certificate; 7.4.6. Client certificate</a>
- *
- */
-public class CertificateMessage extends Message {
-
- /**
- * Certificates
- */
- X509Certificate[] certs;
-
- /**
- * Certificates in encoded form
- */
- byte[][] encoded_certs;
-
- /**
- * Creates inbound message
- *
- * @param in
- * @param length
- * @throws IOException
- */
- public CertificateMessage(HandshakeIODataStream in, int length) throws IOException {
- int l = in.readUint24(); // total_length
- if (l == 0) { // message contais no certificates
- if (length != 3) { // no more bytes after total_length
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect CertificateMessage");
- }
- certs = new X509Certificate[0];
- encoded_certs = new byte[0][0];
- this.length = 3;
- return;
- }
- CertificateFactory cf;
- try {
- cf = CertificateFactory.getInstance("X509");
- } catch (CertificateException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
- return;
- }
- ArrayList<X509Certificate> certsList = new ArrayList<X509Certificate>();
- int size = 0;
- int enc_size = 0;
- while (l > 0) {
- size = in.readUint24();
- l -= 3;
- try {
- certsList.add((X509Certificate) cf.generateCertificate(in));
- } catch (CertificateException e) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR", e);
- }
- l -= size;
- enc_size += size;
- }
- certs = certsList.toArray(new X509Certificate[certsList.size()]);
- this.length = 3 + 3 * certs.length + enc_size;
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect CertificateMessage");
- }
- }
-
- /**
- * Creates outbound message
- *
- * @param certs
- */
- public CertificateMessage(X509Certificate[] certs) {
- if (certs == null) {
- this.certs = new X509Certificate[0];
- encoded_certs = new byte[0][0];
- length = 3;
- return;
- }
- this.certs = certs;
- if (encoded_certs == null) {
- encoded_certs = new byte[certs.length][];
- for (int i = 0; i < certs.length; i++) {
- try {
- encoded_certs[i] = certs[i].getEncoded();
- } catch (CertificateEncodingException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR",
- e);
- }
- }
- }
- length = 3 + 3 * encoded_certs.length;
- for (int i = 0; i < encoded_certs.length; i++) {
- length += encoded_certs[i].length;
- }
- }
-
- /**
- * Sends message
- *
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
-
- int total_length = 0;
- if (encoded_certs == null) {
- encoded_certs = new byte[certs.length][];
- for (int i = 0; i < certs.length; i++) {
- try {
- encoded_certs[i] = certs[i].getEncoded();
- } catch (CertificateEncodingException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR",
- e);
- }
- }
- }
- total_length = 3 * encoded_certs.length;
- for (int i = 0; i < encoded_certs.length; i++) {
- total_length += encoded_certs[i].length;
- }
- out.writeUint24(total_length);
- for (int i = 0; i < encoded_certs.length; i++) {
- out.writeUint24(encoded_certs[i].length);
- out.write(encoded_certs[i]);
- }
-
- }
-
- public String getAuthType() {
- return certs[0].getPublicKey().getAlgorithm();
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CERTIFICATE;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/CertificateRequest.java b/crypto/src/main/java/org/conscrypt/CertificateRequest.java
deleted file mode 100644
index 6d08cc2..0000000
--- a/crypto/src/main/java/org/conscrypt/CertificateRequest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import javax.security.auth.x500.X500Principal;
-import libcore.io.Streams;
-
-/**
- *
- * Represents certificate request message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.4.
- * Certificate request</a>
- */
-public class CertificateRequest extends Message {
-
- /**
- * Requested certificate types
- */
- final byte[] certificate_types;
-
- /**
- * Certificate authorities
- */
- final X500Principal[] certificate_authorities;
-
- /**
- * Requested certificate types as Strings
- * ("RSA", "DSA", "DH_RSA" or "DH_DSA")
- */
- private String[] types;
-
- /**
- * Encoded form of certificate authorities
- */
- private byte[][] encoded_principals;
-
- /**
- * Creates outbound message
- *
- * @param certificate_types
- * @param accepted - array of certificate authority certificates
- */
- public CertificateRequest(byte[] certificate_types,
- X509Certificate[] accepted) {
-
- if (accepted == null) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "CertificateRequest: array of certificate authority certificates is null");
- }
- this.certificate_types = certificate_types;
-
- int totalPrincipalsLength = 0;
- certificate_authorities = new X500Principal[accepted.length];
- encoded_principals = new byte[accepted.length][];
- for (int i = 0; i < accepted.length; i++) {
- certificate_authorities[i] = accepted[i].getIssuerX500Principal();
- encoded_principals[i] = certificate_authorities[i].getEncoded();
- totalPrincipalsLength += encoded_principals[i].length + 2;
- }
-
- length = 3 + certificate_types.length + totalPrincipalsLength;
- }
-
- /**
- * Creates inbound message
- *
- * @param in
- * @param length
- * @throws IOException
- */
- public CertificateRequest(HandshakeIODataStream in, int length) throws IOException {
- int size = in.readUint8();
- certificate_types = new byte[size];
- Streams.readFully(in, certificate_types);
- size = in.readUint16();
- int totalPrincipalsLength = 0;
- int principalLength = 0;
- ArrayList<X500Principal> principals = new ArrayList<X500Principal>();
- while (totalPrincipalsLength < size) {
- principalLength = in.readUint16(); // encoded X500Principal size
- principals.add(new X500Principal(in));
- totalPrincipalsLength += 2;
- totalPrincipalsLength += principalLength;
- }
- certificate_authorities = principals.toArray(new X500Principal[principals.size()]);
- this.length = 3 + certificate_types.length + totalPrincipalsLength;
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect CertificateRequest");
- }
- }
-
- /**
- * Sends message
- *
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
-
- out.writeUint8(certificate_types.length);
- for (int i = 0; i < certificate_types.length; i++) {
- out.write(certificate_types[i]);
- }
- int authoritiesLength = 0;
- for (int i = 0; i < certificate_authorities.length; i++) {
- authoritiesLength += encoded_principals[i].length +2;
- }
- out.writeUint16(authoritiesLength);
- for (int i = 0; i < certificate_authorities.length; i++) {
- out.writeUint16(encoded_principals[i].length);
- out.write(encoded_principals[i]);
- }
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CERTIFICATE_REQUEST;
- }
-
- /**
- * Returns requested certificate types as array of strings
- */
- public String[] getTypesAsString() {
- if (types == null) {
- types = new String[certificate_types.length];
- for (int i = 0; i < types.length; i++) {
- String type = CipherSuite.getClientKeyType(certificate_types[i]);
- if (type == null) {
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect CertificateRequest");
- }
- types[i] = type;
- }
- }
- return types;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/CertificateVerify.java b/crypto/src/main/java/org/conscrypt/CertificateVerify.java
deleted file mode 100644
index 8ba394a..0000000
--- a/crypto/src/main/java/org/conscrypt/CertificateVerify.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- * Represents certificate verify message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.8.
- * Certificate verify</a>
- */
-public class CertificateVerify extends Message {
-
- /**
- * Signature
- */
- byte[] signedHash;
-
- /**
- * Creates outbound message
- *
- * @param hash
- */
- public CertificateVerify(byte[] hash) {
- if (hash == null || hash.length == 0) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "INTERNAL ERROR: incorrect certificate verify hash");
- }
- this.signedHash = hash;
- length = hash.length + 2;
- }
-
- /**
- * Creates inbound message
- *
- * @param in
- * @param length
- * @throws IOException
- */
- public CertificateVerify(HandshakeIODataStream in, int length)
- throws IOException {
- if (length == 0) {
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect CertificateVerify");
- } else {
- if (in.readUint16() != length - 2) {
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect CertificateVerify");
- }
- signedHash = in.read(length -2);
- }
- this.length = length;
- }
-
- /**
- * Sends message
- *
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- if (signedHash.length != 0) {
- out.writeUint16(signedHash.length);
- out.write(signedHash);
- }
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CERTIFICATE_VERIFY;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ChainStrengthAnalyzer.java b/crypto/src/main/java/org/conscrypt/ChainStrengthAnalyzer.java
deleted file mode 100644
index dc4f9b7..0000000
--- a/crypto/src/main/java/org/conscrypt/ChainStrengthAnalyzer.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPublicKey;
-
-public final class ChainStrengthAnalyzer {
-
- private static final int MIN_MODULUS = 1024;
- private static final String[] OID_BLACKLIST = {"1.2.840.113549.1.1.4"}; // MD5withRSA
-
- public static final void check(X509Certificate[] chain) throws CertificateException {
- for (X509Certificate cert : chain) {
- checkCert(cert);
- }
- }
-
- private static final void checkCert(X509Certificate cert) throws CertificateException {
- checkModulusLength(cert);
- checkNotMD5(cert);
- }
-
- private static final void checkModulusLength(X509Certificate cert) throws CertificateException {
- Object pubkey = cert.getPublicKey();
- if (pubkey instanceof RSAPublicKey) {
- int modulusLength = ((RSAPublicKey) pubkey).getModulus().bitLength();
- if(!(modulusLength >= MIN_MODULUS)) {
- throw new CertificateException("Modulus is < 1024 bits");
- }
- }
- }
-
- private static final void checkNotMD5(X509Certificate cert) throws CertificateException {
- String oid = cert.getSigAlgOID();
- for (String blacklisted : OID_BLACKLIST) {
- if (oid.equals(blacklisted)) {
- throw new CertificateException("Signature uses an insecure hash function");
- }
- }
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/CipherSuite.java b/crypto/src/main/java/org/conscrypt/CipherSuite.java
deleted file mode 100644
index 6d2a3e8..0000000
--- a/crypto/src/main/java/org/conscrypt/CipherSuite.java
+++ /dev/null
@@ -1,1184 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.GeneralSecurityException;
-import java.util.Hashtable;
-import javax.crypto.Cipher;
-
-/**
- * Represents Cipher Suite as defined in TLS 1.0 spec.,
- * A.5. The CipherSuite;
- * C. CipherSuite definitions.
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec.</a>
- *
- */
-public class CipherSuite {
-
- /**
- * true if this cipher suite is supported
- */
- boolean supported = true;
-
- /**
- * cipher suite key exchange
- */
- final int keyExchange;
-
- /**
- * algorithm used for authentication ("RSA", "DSA", "DH", null for anonymous)
- */
- final String authType;
-
- /**
- * cipher
- */
- final String cipherName;
-
- /**
- * Cipher information
- */
- final int keyMaterial;
- final int expandedKeyMaterial;
- final int effectiveKeyBytes;
- final int ivSize;
- final private int blockSize;
-
- // cipher suite code
- private final byte[] cipherSuiteCode;
-
- // cipher suite name
- private final String name;
-
- // true if cipher suite is exportable
- private final boolean isExportable;
-
- // Hash algorithm
- final private String hashName;
-
- // MAC algorithm
- final private String hmacName;
-
- // Hash size
- final private int hashSize;
-
- /**
- * key exchange values
- */
- static final int KEY_EXCHANGE_RSA = 1;
- static final int KEY_EXCHANGE_RSA_EXPORT = 2;
- static final int KEY_EXCHANGE_DHE_DSS = 3;
- static final int KEY_EXCHANGE_DHE_DSS_EXPORT = 4;
- static final int KEY_EXCHANGE_DHE_RSA = 5;
- static final int KEY_EXCHANGE_DHE_RSA_EXPORT = 6;
- // BEGIN android-removed
- // static final int KEY_EXCHANGE_DH_DSS = 7;
- // static final int KEY_EXCHANGE_DH_RSA = 8;
- // END android-removed
- static final int KEY_EXCHANGE_DH_anon = 9;
- static final int KEY_EXCHANGE_DH_anon_EXPORT = 10;
- // BEGIN android-removed
- // static final int KEY_EXCHANGE_DH_DSS_EXPORT = 11;
- // static final int KEY_EXCHANGE_DH_RSA_EXPORT = 12;
- // END android-removed
- static final int KEY_EXCHANGE_ECDH_ECDSA = 13;
- static final int KEY_EXCHANGE_ECDHE_ECDSA = 14;
- static final int KEY_EXCHANGE_ECDH_RSA = 15;
- static final int KEY_EXCHANGE_ECDHE_RSA = 16;
- static final int KEY_EXCHANGE_ECDH_anon = 17;
-
- /**
- * TLS cipher suite codes
- */
- static final byte[] CODE_SSL_NULL_WITH_NULL_NULL = { 0x00, 0x00 };
- static final byte[] CODE_SSL_RSA_WITH_NULL_MD5 = { 0x00, 0x01 };
- static final byte[] CODE_SSL_RSA_WITH_NULL_SHA = { 0x00, 0x02 };
- static final byte[] CODE_SSL_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x03 };
- static final byte[] CODE_SSL_RSA_WITH_RC4_128_MD5 = { 0x00, 0x04 };
- static final byte[] CODE_SSL_RSA_WITH_RC4_128_SHA = { 0x00, 0x05 };
- static final byte[] CODE_SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00, 0x06 };
- // BEGIN android-removed
- // static final byte[] CODE_TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00, 0x07 };
- // END android-removed
- static final byte[] CODE_SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x08 };
- static final byte[] CODE_SSL_RSA_WITH_DES_CBC_SHA = { 0x00, 0x09 };
- static final byte[] CODE_SSL_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0A };
- // BEGIN android-removed
- // static final byte[] CODE_SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B };
- // static final byte[] CODE_SSL_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C };
- // static final byte[] CODE_SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0D };
- // static final byte[] CODE_SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0E };
- // static final byte[] CODE_SSL_DH_RSA_WITH_DES_CBC_SHA = { 0x00, 0x0F };
- // static final byte[] CODE_SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x10 };
- // END android-removed
- static final byte[] CODE_SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x11 };
- static final byte[] CODE_SSL_DHE_DSS_WITH_DES_CBC_SHA = { 0x00, 0x12 };
- static final byte[] CODE_SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x13 };
- static final byte[] CODE_SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x14 };
- static final byte[] CODE_SSL_DHE_RSA_WITH_DES_CBC_SHA = { 0x00, 0x15 };
- static final byte[] CODE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x16 };
- static final byte[] CODE_SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 };
- static final byte[] CODE_SSL_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 };
- static final byte[] CODE_SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x19 };
- static final byte[] CODE_SSL_DH_anon_WITH_DES_CBC_SHA = { 0x00, 0x1A };
- static final byte[] CODE_SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x1B };
-
- // AES Cipher Suites from RFC 3268 - http://www.ietf.org/rfc/rfc3268.txt
- static final byte[] CODE_TLS_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x2F };
- //static final byte[] CODE_TLS_DH_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x30 };
- //static final byte[] CODE_TLS_DH_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x31 };
- static final byte[] CODE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x32 };
- static final byte[] CODE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x33 };
- static final byte[] CODE_TLS_DH_anon_WITH_AES_128_CBC_SHA = { 0x00, 0x34 };
- static final byte[] CODE_TLS_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x35 };
- //static final byte[] CODE_TLS_DH_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x36 };
- //static final byte[] CODE_TLS_DH_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x37 };
- static final byte[] CODE_TLS_DHE_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x38 };
- static final byte[] CODE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x39 };
- static final byte[] CODE_TLS_DH_anon_WITH_AES_256_CBC_SHA = { 0x00, 0x3A };
-
- // EC Cipher Suites from RFC 4492 - http://www.ietf.org/rfc/rfc4492.txt
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_NULL_SHA = { (byte) 0xc0, 0x01};
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_RC4_128_SHA = { (byte) 0xc0, 0x02};
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x03};
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x04};
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x05};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_NULL_SHA = { (byte) 0xc0, 0x06};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = { (byte) 0xc0, 0x07};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x08};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x09};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x0A};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_NULL_SHA = { (byte) 0xc0, 0x0B};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_RC4_128_SHA = { (byte) 0xc0, 0x0C};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x0D};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x0E};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x0F};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_NULL_SHA = { (byte) 0xc0, 0x10};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_RC4_128_SHA = { (byte) 0xc0, 0x11};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x12};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x13};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x14};
- static final byte[] CODE_TLS_ECDH_anon_WITH_NULL_SHA = { (byte) 0xc0, 0x15};
- static final byte[] CODE_TLS_ECDH_anon_WITH_RC4_128_SHA = { (byte) 0xc0, 0x16};
- static final byte[] CODE_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x17};
- static final byte[] CODE_TLS_ECDH_anon_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x18};
- static final byte[] CODE_TLS_ECDH_anon_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x19};
-
- static final CipherSuite SSL_NULL_WITH_NULL_NULL = new CipherSuite(
- "SSL_NULL_WITH_NULL_NULL", true, 0, null, null, null,
- CODE_SSL_NULL_WITH_NULL_NULL);
-
- static final CipherSuite SSL_RSA_WITH_NULL_MD5 = new CipherSuite(
- "SSL_RSA_WITH_NULL_MD5", true, KEY_EXCHANGE_RSA, "RSA", null, "MD5",
- CODE_SSL_RSA_WITH_NULL_MD5);
-
- static final CipherSuite SSL_RSA_WITH_NULL_SHA = new CipherSuite(
- "SSL_RSA_WITH_NULL_SHA", true, KEY_EXCHANGE_RSA, "RSA", null, "SHA",
- CODE_SSL_RSA_WITH_NULL_SHA);
-
- static final CipherSuite SSL_RSA_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
- "SSL_RSA_EXPORT_WITH_RC4_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT,
- "RSA", "RC4_40", "MD5", CODE_SSL_RSA_EXPORT_WITH_RC4_40_MD5);
-
- static final CipherSuite SSL_RSA_WITH_RC4_128_MD5 = new CipherSuite(
- "SSL_RSA_WITH_RC4_128_MD5", false, KEY_EXCHANGE_RSA, "RSA", "RC4_128",
- "MD5", CODE_SSL_RSA_WITH_RC4_128_MD5);
-
- static final CipherSuite SSL_RSA_WITH_RC4_128_SHA = new CipherSuite(
- "SSL_RSA_WITH_RC4_128_SHA", false, KEY_EXCHANGE_RSA, "RSA", "RC4_128",
- "SHA", CODE_SSL_RSA_WITH_RC4_128_SHA);
-
- static final CipherSuite SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = new CipherSuite(
- "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT,
- "RSA", "RC2_CBC_40", "MD5", CODE_SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5);
-
- // BEGIN android-removed
- // static final CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = new CipherSuite(
- // "TLS_RSA_WITH_IDEA_CBC_SHA", false, KEY_EXCHANGE_RSA, "RSA", "IDEA_CBC",
- // "SHA", CODE_TLS_RSA_WITH_IDEA_CBC_SHA);
- // END android-removed
-
- static final CipherSuite SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", true, KEY_EXCHANGE_RSA_EXPORT,
- "RSA", "DES40_CBC", "SHA", CODE_SSL_RSA_EXPORT_WITH_DES40_CBC_SHA);
-
- static final CipherSuite SSL_RSA_WITH_DES_CBC_SHA = new CipherSuite(
- "SSL_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_RSA, "RSA", "DES_CBC",
- "SHA", CODE_SSL_RSA_WITH_DES_CBC_SHA);
-
- static final CipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "SSL_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_RSA,
- "RSA", "3DES_EDE_CBC", "SHA", CODE_SSL_RSA_WITH_3DES_EDE_CBC_SHA);
-
- // BEGIN android-removed
- // static final CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- // "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
- // KEY_EXCHANGE_DH_DSS_EXPORT, "DH", "DES40_CBC", "SHA",
- // CODE_SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA = new CipherSuite(
- // "SSL_DH_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
- // "DH", "DES_CBC", "SHA", CODE_SSL_DH_DSS_WITH_DES_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- // "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
- // "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- // "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
- // KEY_EXCHANGE_DH_RSA_EXPORT, "DH", "DES40_CBC", "SHA",
- // CODE_SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_RSA_WITH_DES_CBC_SHA = new CipherSuite(
- // "SSL_DH_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
- // "DH", "DES_CBC", "SHA", CODE_SSL_DH_RSA_WITH_DES_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- // "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
- // "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA);
- // END android-removed
-
- static final CipherSuite SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
- KEY_EXCHANGE_DHE_DSS_EXPORT, "DSA", "DES40_CBC", "SHA",
- CODE_SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
-
- static final CipherSuite SSL_DHE_DSS_WITH_DES_CBC_SHA = new CipherSuite(
- "SSL_DHE_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS,
- "DSA", "DES_CBC", "SHA", CODE_SSL_DHE_DSS_WITH_DES_CBC_SHA);
-
- static final CipherSuite SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS,
- "DSA", "3DES_EDE_CBC", "SHA", CODE_SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA);
-
- static final CipherSuite SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
- KEY_EXCHANGE_DHE_RSA_EXPORT, "RSA", "DES40_CBC", "SHA",
- CODE_SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
-
- static final CipherSuite SSL_DHE_RSA_WITH_DES_CBC_SHA = new CipherSuite(
- "SSL_DHE_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA,
- "RSA", "DES_CBC", "SHA", CODE_SSL_DHE_RSA_WITH_DES_CBC_SHA);
-
- static final CipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA,
- "RSA", "3DES_EDE_CBC", "SHA", CODE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
-
- static final CipherSuite SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
- "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", true,
- KEY_EXCHANGE_DH_anon_EXPORT, "DH", "RC4_40", "MD5",
- CODE_SSL_DH_anon_EXPORT_WITH_RC4_40_MD5);
-
- static final CipherSuite SSL_DH_anon_WITH_RC4_128_MD5 = new CipherSuite(
- "SSL_DH_anon_WITH_RC4_128_MD5", false, KEY_EXCHANGE_DH_anon,
- "DH", "RC4_128", "MD5", CODE_SSL_DH_anon_WITH_RC4_128_MD5);
-
- static final CipherSuite SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", true,
- KEY_EXCHANGE_DH_anon_EXPORT, "DH", "DES40_CBC", "SHA",
- CODE_SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA);
-
- static final CipherSuite SSL_DH_anon_WITH_DES_CBC_SHA = new CipherSuite(
- "SSL_DH_anon_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_anon,
- "DH", "DES_CBC", "SHA", CODE_SSL_DH_anon_WITH_DES_CBC_SHA);
-
- static final CipherSuite SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_anon,
- "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_anon_WITH_3DES_EDE_CBC_SHA);
-
- static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_RSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_RSA,
- "RSA",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_RSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_DHE_DSS,
- "DSA",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_DHE_RSA,
- "RSA",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_DH_anon_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_DH_anon,
- "DH",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_DH_anon_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_RSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_RSA,
- "RSA",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_RSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_DHE_DSS,
- "DSA",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_DHE_DSS_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_DHE_RSA,
- "RSA",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_DH_anon_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_DH_anon,
- "DH",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_DH_anon_WITH_AES_256_CBC_SHA);
-
- static final CipherSuite TLS_ECDH_ECDSA_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDH_ECDSA_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDH_anon_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDH_anon_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDH_anon_WITH_AES_256_CBC_SHA);
-
- // arrays for quick access to cipher suite by code
- private static final CipherSuite[] SUITES_BY_CODE_0x00 = {
- // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
- SSL_NULL_WITH_NULL_NULL, // { 0x00, 0x00 };
- SSL_RSA_WITH_NULL_MD5, // { 0x00, 0x01 };
- SSL_RSA_WITH_NULL_SHA, // { 0x00, 0x02 };
- SSL_RSA_EXPORT_WITH_RC4_40_MD5, // { 0x00, 0x03 };
- SSL_RSA_WITH_RC4_128_MD5, // { 0x00, 0x04 };
- SSL_RSA_WITH_RC4_128_SHA, // { 0x00, 0x05 };
- // BEGIN android-changed
- null, // SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, // { 0x00, 0x06 };
- null, // TLS_RSA_WITH_IDEA_CBC_SHA, // { 0x00, 0x07 };
- // END android-changed
- SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x08 };
- SSL_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x09 };
- SSL_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x0a };
- // BEGIN android-changed
- null, // SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA // { 0x00, 0x0b };
- null, // SSL_DH_DSS_WITH_DES_CBC_SHA, // { 0x00, 0x0c };
- null, // SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x0d };
- null, // SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x0e };
- null, // SSL_DH_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x0f };
- null, // SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x10 };
- // END android-changed
- SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x11 };
- SSL_DHE_DSS_WITH_DES_CBC_SHA, // { 0x00, 0x12 };
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x13 };
- SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x14 };
- SSL_DHE_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x15 };
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x16 };
- SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, // { 0x00, 0x17 };
- SSL_DH_anon_WITH_RC4_128_MD5, // { 0x00, 0x18 };
- SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x19 };
- SSL_DH_anon_WITH_DES_CBC_SHA, // { 0x00, 0x1A };
- SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x1B };
- // BEGIN android-added
- null, // SSL_FORTEZZA_KEA_WITH_NULL_SHA // { 0x00, 0x1C };
- null, // SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA // { 0x00, 0x1D };
- null, // TLS_KRB5_WITH_DES_CBC_SHA // { 0x00, 0x1E };
- null, // TLS_KRB5_WITH_3DES_EDE_CBC_SHA // { 0x00, 0x1F };
- null, // TLS_KRB5_WITH_RC4_128_SHA // { 0x00, 0x20 };
- null, // TLS_KRB5_WITH_IDEA_CBC_SHA // { 0x00, 0x21 };
- null, // TLS_KRB5_WITH_DES_CBC_MD5 // { 0x00, 0x22 };
- null, // TLS_KRB5_WITH_3DES_EDE_CBC_MD5 // { 0x00, 0x23 };
- null, // TLS_KRB5_WITH_RC4_128_MD5 // { 0x00, 0x24 };
- null, // TLS_KRB5_WITH_IDEA_CBC_MD5 // { 0x00, 0x25 };
- null, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA // { 0x00, 0x26 };
- null, // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA // { 0x00, 0x27 };
- null, // TLS_KRB5_EXPORT_WITH_RC4_40_SHA // { 0x00, 0x28 };
- null, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 // { 0x00, 0x29 };
- null, // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 // { 0x00, 0x2A };
- null, // TLS_KRB5_EXPORT_WITH_RC4_40_MD5 // { 0x00, 0x2B };
- null, // TLS_PSK_WITH_NULL_SHA // { 0x00, 0x2C };
- null, // TLS_DHE_PSK_WITH_NULL_SHA // { 0x00, 0x2D };
- null, // TLS_RSA_PSK_WITH_NULL_SHA // { 0x00, 0x2E };
- TLS_RSA_WITH_AES_128_CBC_SHA, // { 0x00, 0x2F };
- null, // TLS_DH_DSS_WITH_AES_128_CBC_SHA // { 0x00, 0x30 };
- null, // TLS_DH_RSA_WITH_AES_128_CBC_SHA // { 0x00, 0x31 };
- TLS_DHE_DSS_WITH_AES_128_CBC_SHA, // { 0x00, 0x32 };
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA, // { 0x00, 0x33 };
- TLS_DH_anon_WITH_AES_128_CBC_SHA, // { 0x00, 0x34 };
- TLS_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x35 };
- null, // TLS_DH_DSS_WITH_AES_256_CBC_SHA, // { 0x00, 0x36 };
- null, // TLS_DH_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x37 };
- TLS_DHE_DSS_WITH_AES_256_CBC_SHA, // { 0x00, 0x38 };
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x39 };
- TLS_DH_anon_WITH_AES_256_CBC_SHA, // { 0x00, 0x3A };
- // END android-added
- };
- private static final CipherSuite[] SUITES_BY_CODE_0xc0 = {
- null, // { 0xc0, 0x00};
- TLS_ECDH_ECDSA_WITH_NULL_SHA, // { 0xc0, 0x01};
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA, // { 0xc0, 0x02};
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x03};
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x04};
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x05};
- TLS_ECDHE_ECDSA_WITH_NULL_SHA, // { 0xc0, 0x06};
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, // { 0xc0, 0x07};
- TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x08};
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x09};
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x0A};
- TLS_ECDH_RSA_WITH_NULL_SHA, // { 0xc0, 0x0B};
- TLS_ECDH_RSA_WITH_RC4_128_SHA, // { 0xc0, 0x0C};
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x0D};
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x0E};
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x0F};
- TLS_ECDHE_RSA_WITH_NULL_SHA, // { 0xc0, 0x10};
- TLS_ECDHE_RSA_WITH_RC4_128_SHA, // { 0xc0, 0x11};
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x12};
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x13};
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x14};
- TLS_ECDH_anon_WITH_NULL_SHA, // { 0xc0, 0x15};
- TLS_ECDH_anon_WITH_RC4_128_SHA, // { 0xc0, 0x16};
- TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x17};
- TLS_ECDH_anon_WITH_AES_128_CBC_SHA, // { 0xc0, 0x18};
- TLS_ECDH_anon_WITH_AES_256_CBC_SHA, // { 0xc0, 0x19};
- // TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x1A};
- // TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x1B};
- // TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x1C};
- // TLS_SRP_SHA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x1D};
- // TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x1E};
- // TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, // { 0xc0, 0x1F};
- // TLS_SRP_SHA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x20};
- // TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x21};
- // TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, // { 0xc0, 0x22};
- // TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x23};
- // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x24};
- // TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x25};
- // TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x26};
- // TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x27};
- // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x28};
- // TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x29};
- // TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x2A};
- // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, // { 0xc0, 0x2B};
- // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, // { 0xc0, 0x2C};
- // TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, // { 0xc0, 0x2D};
- // TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, // { 0xc0, 0x2E};
- // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // { 0xc0, 0x2F};
- // TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, // { 0xc0, 0x30};
- // TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, // { 0xc0, 0x31};
- // TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, // { 0xc0, 0x32};
- // TLS_ECDHE_PSK_WITH_RC4_128_SHA, // { 0xc0, 0x33};
- // TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x34};
- // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, // { 0xc0, 0x35};
- // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, // { 0xc0, 0x36};
- // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x37};
- // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x38};
- // TLS_ECDHE_PSK_WITH_NULL_SHA, // { 0xc0, 0x39};
- // TLS_ECDHE_PSK_WITH_NULL_SHA256, // { 0xc0, 0x3A};
- // TLS_ECDHE_PSK_WITH_NULL_SHA384, // { 0xc0, 0x3B};
- };
-
- // hash for quick access to cipher suite by name
- private static final Hashtable<String, CipherSuite> SUITES_BY_NAME;
-
- /**
- * array of supported cipher suites.
- * Set of supported suites is defined at the moment provider's start
- */
- // TODO Dynamically supported suites: new providers may be dynamically
- // added/removed and the set of supported suites may be changed
- static final CipherSuite[] SUPPORTED_CIPHER_SUITES;
-
- /**
- * array of supported cipher suites names
- */
- static final String[] SUPPORTED_CIPHER_SUITE_NAMES;
-
- /**
- * default cipher suites
- */
- static final CipherSuite[] DEFAULT_CIPHER_SUITES;
-
- static {
- SUITES_BY_NAME = new Hashtable<String, CipherSuite>();
- int count_0x00 = registerCipherSuitesByCode(SUITES_BY_CODE_0x00);
- int count_0xc0 = registerCipherSuitesByCode(SUITES_BY_CODE_0xc0);
- int count = count_0x00 + count_0xc0;
- SUPPORTED_CIPHER_SUITES = new CipherSuite[count];
- SUPPORTED_CIPHER_SUITE_NAMES = new String[count];
- registerSupportedCipherSuites(0, SUITES_BY_CODE_0x00);
- registerSupportedCipherSuites(count_0x00, SUITES_BY_CODE_0xc0);
-
- CipherSuite[] defaultCipherSuites = {
- SSL_RSA_WITH_RC4_128_MD5,
- SSL_RSA_WITH_RC4_128_SHA,
- TLS_RSA_WITH_AES_128_CBC_SHA,
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- SSL_RSA_WITH_3DES_EDE_CBC_SHA,
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- SSL_RSA_WITH_DES_CBC_SHA,
- SSL_DHE_RSA_WITH_DES_CBC_SHA,
- SSL_DHE_DSS_WITH_DES_CBC_SHA,
- SSL_RSA_EXPORT_WITH_RC4_40_MD5,
- SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
- SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
- };
- count = 0;
- for (int i = 0; i < defaultCipherSuites.length; i++) {
- if (defaultCipherSuites[i].supported) {
- count++;
- }
- }
- DEFAULT_CIPHER_SUITES = new CipherSuite[count];
- count = 0;
- for (int i = 0; i < defaultCipherSuites.length; i++) {
- if (defaultCipherSuites[i].supported) {
- DEFAULT_CIPHER_SUITES[count++] = defaultCipherSuites[i];
- }
- }
- }
- private static int registerCipherSuitesByCode(CipherSuite[] cipherSuites) {
- int count = 0;
- for (int i = 0; i < cipherSuites.length; i++) {
- if (cipherSuites[i] == SSL_NULL_WITH_NULL_NULL) {
- continue;
- }
- if (cipherSuites[i] == null) {
- continue;
- }
- SUITES_BY_NAME.put(cipherSuites[i].getName(), cipherSuites[i]);
- if (cipherSuites[i].supported) {
- count++;
- }
- }
- return count;
- }
- private static void registerSupportedCipherSuites(int offset, CipherSuite[] cipherSuites) {
- int count = offset;
- for (int i = 0; i < cipherSuites.length; i++) {
- if (cipherSuites[i] == SSL_NULL_WITH_NULL_NULL) {
- continue;
- }
- if (cipherSuites[i] == null) {
- continue;
- }
- if (cipherSuites[i].supported) {
- SUPPORTED_CIPHER_SUITES[count] = cipherSuites[i];
- SUPPORTED_CIPHER_SUITE_NAMES[count] = SUPPORTED_CIPHER_SUITES[count].getName();
- count++;
- }
- }
- }
-
- /**
- * Returns CipherSuite by name
- */
- public static CipherSuite getByName(String name) {
- return SUITES_BY_NAME.get(name);
- }
-
- /**
- * Returns CipherSuite based on TLS CipherSuite code
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., A.5. The CipherSuite</a>
- */
- public static CipherSuite getByCode(byte b1, byte b2) {
- int i1 = b1 & 0xff;
- int i2 = b2 & 0xff;
- CipherSuite cs = getCipherSuiteByCode(0, i1, i2);
- if (cs != null) {
- return cs;
- }
- return new CipherSuite("UNKNOWN_" + i1 + "_" + i2, false, 0, null,
- null, null, new byte[] { b1, b2 });
- }
-
- /**
- * Returns CipherSuite based on V2CipherSpec code
- * as described in TLS 1.0 spec., E. Backward Compatibility With SSL
- */
- public static CipherSuite getByCode(byte b1, byte b2, byte b3) {
- int i1 = b1 & 0xff;
- int i2 = b2 & 0xff;
- int i3 = b3 & 0xff;
- CipherSuite cs = getCipherSuiteByCode(i1, i2, i3);
- if (cs != null) {
- return cs;
- }
- return new CipherSuite("UNKNOWN_" + i1 + "_" + i2 + "_" + i3, false, 0,
- null, null, null, new byte[] { b1, b2, b3 });
- }
-
- private static CipherSuite getCipherSuiteByCode(int i1, int i2, int i3) {
- CipherSuite[] cipherSuites;
- if (i1 == 0x00 && i2 == 0x00) {
- cipherSuites = SUITES_BY_CODE_0x00;
- } else if (i1 == 0x00 && i2 == 0xc0) {
- cipherSuites = SUITES_BY_CODE_0xc0;
- } else {
- return null;
- }
- if (i3 >= cipherSuites.length) {
- return null;
- }
- return cipherSuites[i3];
- }
-
- /**
- * Creates CipherSuite
- */
- private CipherSuite(String name, boolean isExportable, int keyExchange,
- String authType, String cipherName, String hash, byte[] code) {
- this.name = name;
- this.keyExchange = keyExchange;
- this.authType = authType;
- this.isExportable = isExportable;
- if (cipherName == null) {
- this.cipherName = null;
- keyMaterial = 0;
- expandedKeyMaterial = 0;
- effectiveKeyBytes = 0;
- ivSize = 0;
- blockSize = 0;
- // BEGIN android-removed
- // } else if ("IDEA_CBC".equals(cipherName)) {
- // this.cipherName = "IDEA/CBC/NoPadding";
- // keyMaterial = 16;
- // expandedKeyMaterial = 16;
- // effectiveKeyBytes = 16;
- // ivSize = 8;
- // blockSize = 8;
- // } else if ("RC2_CBC_40".equals(cipherName)) {
- // this.cipherName = "RC2/CBC/NoPadding";
- // keyMaterial = 5;
- // expandedKeyMaterial = 16;
- // effectiveKeyBytes = 5;
- // ivSize = 8;
- // blockSize = 8;
- // END android-removed
- } else if ("RC4_40".equals(cipherName)) {
- this.cipherName = "RC4";
- keyMaterial = 5;
- expandedKeyMaterial = 16;
- effectiveKeyBytes = 5;
- ivSize = 0;
- blockSize = 0;
- } else if ("RC4_128".equals(cipherName)) {
- this.cipherName = "RC4";
- keyMaterial = 16;
- expandedKeyMaterial = 16;
- effectiveKeyBytes = 16;
- ivSize = 0;
- blockSize = 0;
- } else if ("DES40_CBC".equals(cipherName)) {
- this.cipherName = "DES/CBC/NoPadding";
- keyMaterial = 5;
- expandedKeyMaterial = 8;
- effectiveKeyBytes = 5;
- ivSize = 8;
- blockSize = 8;
- } else if ("DES_CBC".equals(cipherName)) {
- this.cipherName = "DES/CBC/NoPadding";
- keyMaterial = 8;
- expandedKeyMaterial = 8;
- effectiveKeyBytes = 7;
- ivSize = 8;
- blockSize = 8;
- } else if ("3DES_EDE_CBC".equals(cipherName)) {
- this.cipherName = "DESede/CBC/NoPadding";
- keyMaterial = 24;
- expandedKeyMaterial = 24;
- effectiveKeyBytes = 24;
- ivSize = 8;
- blockSize = 8;
- } else if ("AES_128_CBC".equals(cipherName)) {
- this.cipherName = "AES/CBC/NoPadding";
- keyMaterial = 16;
- expandedKeyMaterial = 16;
- effectiveKeyBytes = 16;
- ivSize = 16;
- blockSize = 16;
- } else if ("AES_256_CBC".equals(cipherName)) {
- this.cipherName = "AES/CBC/NoPadding";
- keyMaterial = 32;
- expandedKeyMaterial = 32;
- effectiveKeyBytes = 32;
- ivSize = 16;
- blockSize = 16;
- } else {
- this.cipherName = cipherName;
- keyMaterial = 0;
- expandedKeyMaterial = 0;
- effectiveKeyBytes = 0;
- ivSize = 0;
- blockSize = 0;
- }
-
- if ("MD5".equals(hash)) {
- this.hmacName = "HmacMD5";
- this.hashName = "MD5";
- hashSize = 16;
- } else if ("SHA".equals(hash)) {
- this.hmacName = "HmacSHA1";
- this.hashName = "SHA-1";
- hashSize = 20;
- } else {
- this.hmacName = null;
- this.hashName = null;
- hashSize = 0;
- }
-
- cipherSuiteCode = code;
-
- if (this.cipherName != null) {
- try {
- Cipher.getInstance(this.cipherName);
- } catch (GeneralSecurityException e) {
- supported = false;
- }
- }
-
- // We define the Elliptic Curve cipher suites for use with
- // code shared by OpenSSL, but they are not supported by
- // SSLEngine or SSLSocket's built with SSLEngine.
- if (this.name.startsWith("TLS_EC")) {
- supported = false;
- }
- }
-
- /**
- * Returns true if cipher suite is anonymous
- */
- public boolean isAnonymous() {
- if (keyExchange == KEY_EXCHANGE_DH_anon
- || keyExchange == KEY_EXCHANGE_DH_anon_EXPORT
- || keyExchange == KEY_EXCHANGE_ECDH_anon) {
- return true;
- }
- return false;
- }
-
- /**
- * Returns array of supported CipherSuites
- */
- public static CipherSuite[] getSupported() {
- return SUPPORTED_CIPHER_SUITES;
- }
-
- /**
- * Returns array of supported cipher suites names
- */
- public static String[] getSupportedCipherSuiteNames() {
- return SUPPORTED_CIPHER_SUITE_NAMES.clone();
- }
-
- /**
- * Returns cipher suite name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns cipher suite code as byte array
- */
- public byte[] toBytes() {
- return cipherSuiteCode;
- }
-
- /**
- * Returns cipher suite description
- */
- @Override
- public String toString() {
- return name + ": " + cipherSuiteCode[0] + " " + cipherSuiteCode[1];
- }
-
- /**
- * Returns cipher algorithm name
- */
- public String getBulkEncryptionAlgorithm() {
- return cipherName;
- }
-
- /**
- * Returns cipher block size
- */
- public int getBlockSize() {
- return blockSize;
- }
-
- /**
- * Returns MAC algorithm name
- */
- public String getHmacName() {
- return hmacName;
- }
-
- /**
- * Returns hash algorithm name
- */
- public String getHashName() {
- return hashName;
- }
-
- /**
- * Returns hash size
- */
- public int getMACLength() {
- return hashSize;
- }
-
- /**
- * Indicates whether this cipher suite is exportable
- */
- public boolean isExportable() {
- return isExportable;
- }
-
- static final String KEY_TYPE_RSA = "RSA";
- static final String KEY_TYPE_DSA = "DSA";
- static final String KEY_TYPE_DH_RSA = "DH_RSA";
- static final String KEY_TYPE_DH_DSA = "DH_DSA";
- static final String KEY_TYPE_EC = "EC";
- static final String KEY_TYPE_EC_EC = "EC_EC";
- static final String KEY_TYPE_EC_RSA = "EC_RSA";
-
- /**
- * Returns key type constant suitable for calling
- * X509KeyManager.chooseServerAlias or
- * X509ExtendedKeyManager.chooseEngineServerAlias.
- */
- public String getServerKeyType() {
- switch (keyExchange) {
- case KEY_EXCHANGE_DHE_RSA:
- case KEY_EXCHANGE_DHE_RSA_EXPORT:
- case KEY_EXCHANGE_ECDHE_RSA:
- case KEY_EXCHANGE_RSA:
- case KEY_EXCHANGE_RSA_EXPORT:
- return KEY_TYPE_RSA;
- case KEY_EXCHANGE_DHE_DSS:
- case KEY_EXCHANGE_DHE_DSS_EXPORT:
- return KEY_TYPE_DSA;
- case KEY_EXCHANGE_ECDH_ECDSA:
- case KEY_EXCHANGE_ECDHE_ECDSA:
- return KEY_TYPE_EC_EC;
- case KEY_EXCHANGE_ECDH_RSA:
- return KEY_TYPE_EC_RSA;
- case KEY_EXCHANGE_DH_anon:
- case KEY_EXCHANGE_DH_anon_EXPORT:
- case KEY_EXCHANGE_ECDH_anon:
- return null;
- default:
- throw new IllegalStateException("Unknown key type for key exchange " + keyExchange);
- }
- }
-
- /**
- * Client certificate types as defined in
- * TLS 1.0 spec., 7.4.4. Certificate request.
- * EC constants from RFC 4492.
- * Names match openssl constants.
- */
- static final byte TLS_CT_RSA_SIGN = 1;
- static final byte TLS_CT_DSS_SIGN = 2;
- static final byte TLS_CT_RSA_FIXED_DH = 3;
- static final byte TLS_CT_DSS_FIXED_DH = 4;
- static final byte TLS_CT_ECDSA_SIGN = 64;
- static final byte TLS_CT_RSA_FIXED_ECDH = 65;
- static final byte TLS_CT_ECDSA_FIXED_ECDH = 66;
-
- /**
- * Similar to getServerKeyType, but returns value given TLS
- * ClientCertificateType byte values from a CertificateRequest
- * message for use with X509KeyManager.chooseClientAlias or
- * X509ExtendedKeyManager.chooseEngineClientAlias.
- */
- public static String getClientKeyType(byte keyType) {
- // See also http://www.ietf.org/assignments/tls-parameters/tls-parameters.xml
- switch (keyType) {
- case TLS_CT_RSA_SIGN:
- return KEY_TYPE_RSA; // RFC rsa_sign
- case TLS_CT_DSS_SIGN:
- return KEY_TYPE_DSA; // RFC dss_sign
- case TLS_CT_RSA_FIXED_DH:
- return KEY_TYPE_DH_RSA; // RFC rsa_fixed_dh
- case TLS_CT_DSS_FIXED_DH:
- return KEY_TYPE_DH_DSA; // RFC dss_fixed_dh
- case TLS_CT_ECDSA_SIGN:
- return KEY_TYPE_EC; // RFC ecdsa_sign
- case TLS_CT_RSA_FIXED_ECDH:
- return KEY_TYPE_EC_RSA; // RFC rsa_fixed_ecdh
- case TLS_CT_ECDSA_FIXED_ECDH:
- return KEY_TYPE_EC_EC; // RFC ecdsa_fixed_ecdh
- default:
- return null;
- }
- }
-
- private static final String AUTH_TYPE_RSA = "RSA";
- private static final String AUTH_TYPE_RSA_EXPORT = "RSA_EXPORT";
- private static final String AUTH_TYPE_DHE_DSS = "DHE_DSS";
- private static final String AUTH_TYPE_DHE_RSA = "DHE_RSA";
- private static final String AUTH_TYPE_DH_DSS = "DH_DSS";
- private static final String AUTH_TYPE_DH_RSA = "DH_RSA";
- private static final String AUTH_TYPE_ECDH_ECDSA = "ECDH_ECDSA";
- private static final String AUTH_TYPE_ECDH_RSA = "ECDH_RSA";
- private static final String AUTH_TYPE_ECDHE_ECDSA = "ECDHE_ECDSA";
- private static final String AUTH_TYPE_ECDHE_RSA = "ECDHE_RSA";
-
- /**
- * Returns auth type constant suitable for calling X509TrustManager.checkServerTrusted.
- */
- public String getAuthType(boolean emphemeral) {
- switch (keyExchange) {
- case KEY_EXCHANGE_RSA:
- return AUTH_TYPE_RSA;
- case KEY_EXCHANGE_RSA_EXPORT:
- return emphemeral ? AUTH_TYPE_RSA_EXPORT : AUTH_TYPE_RSA;
- case KEY_EXCHANGE_DHE_DSS:
- case KEY_EXCHANGE_DHE_DSS_EXPORT:
- return AUTH_TYPE_DHE_DSS;
- case KEY_EXCHANGE_DHE_RSA:
- case KEY_EXCHANGE_DHE_RSA_EXPORT:
- return AUTH_TYPE_DHE_RSA;
- case KEY_EXCHANGE_ECDH_ECDSA:
- return AUTH_TYPE_ECDH_ECDSA;
- case KEY_EXCHANGE_ECDHE_ECDSA:
- return AUTH_TYPE_ECDHE_ECDSA;
- case KEY_EXCHANGE_ECDH_RSA:
- return AUTH_TYPE_ECDH_RSA;
- case KEY_EXCHANGE_ECDHE_RSA:
- return AUTH_TYPE_ECDHE_RSA;
- case KEY_EXCHANGE_DH_anon:
- case KEY_EXCHANGE_DH_anon_EXPORT:
- case KEY_EXCHANGE_ECDH_anon:
- return null;
- default:
- throw new IllegalStateException("Unknown auth type for key exchange " + keyExchange);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ClientHandshakeImpl.java b/crypto/src/main/java/org/conscrypt/ClientHandshakeImpl.java
deleted file mode 100644
index 8706ec0..0000000
--- a/crypto/src/main/java/org/conscrypt/ClientHandshakeImpl.java
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.DHPublicKeySpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * Client side handshake protocol implementation.
- * Handshake protocol operates on top of the Record Protocol.
- * It is responsible for session negotiating.
- *
- * The implementation processes inbound server handshake messages,
- * creates and sends respond messages. Outbound messages are supplied
- * to Record Protocol. Detected errors are reported to the Alert protocol.
- *
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7. The
- * TLS Handshake Protocol</a>
- *
- */
-public class ClientHandshakeImpl extends HandshakeProtocol {
-
- /**
- * Creates Client Handshake Implementation
- *
- * @param owner
- */
- ClientHandshakeImpl(Object owner) {
- super(owner);
- }
-
- /**
- * Starts handshake
- *
- */
- @Override
- public void start() {
- if (session == null) { // initial handshake
- session = findSessionToResume();
- } else { // start session renegotiation
- if (clientHello != null && this.status != FINISHED) {
- // current negotiation has not completed
- return; // ignore
- }
- if (!session.isValid()) {
- session = null;
- }
- }
- if (session != null) {
- isResuming = true;
- } else if (parameters.getEnableSessionCreation()){
- isResuming = false;
- session = new SSLSessionImpl(parameters.getSecureRandom());
- if (engineOwner != null) {
- session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
- } else {
- session.setPeer(socketOwner.getPeerHostName(), socketOwner.getPeerPort());
- }
- session.protocol = ProtocolVersion.getLatestVersion(parameters.getEnabledProtocols());
- recordProtocol.setVersion(session.protocol.version);
- } else {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "SSL Session may not be created ");
- }
- startSession();
- }
-
- /**
- * Starts renegotiation on a new session
- *
- */
- private void renegotiateNewSession() {
- if (parameters.getEnableSessionCreation()){
- isResuming = false;
- session = new SSLSessionImpl(parameters.getSecureRandom());
- if (engineOwner != null) {
- session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
- } else {
- session.setPeer(socketOwner.getPeerHostName(), socketOwner.getPeerPort());
- }
- session.protocol = ProtocolVersion.getLatestVersion(parameters.getEnabledProtocols());
- recordProtocol.setVersion(session.protocol.version);
- startSession();
- } else {
- status = NOT_HANDSHAKING;
- sendWarningAlert(AlertProtocol.NO_RENEGOTIATION);
- }
- }
-
- /*
- * Starts/resumes session
- */
- private void startSession() {
- CipherSuite[] cipher_suites;
- if (isResuming) {
- cipher_suites = new CipherSuite[] { session.cipherSuite };
- } else {
- cipher_suites = parameters.getEnabledCipherSuitesMember();
- }
- clientHello = new ClientHello(parameters.getSecureRandom(),
- session.protocol.version, session.id, cipher_suites);
- session.clientRandom = clientHello.random;
- send(clientHello);
- status = NEED_UNWRAP;
- }
-
- /**
- * Processes inbound handshake messages
- * @param bytes
- */
- @Override
- public void unwrap(byte[] bytes) {
- if (this.delegatedTaskErr != null) {
- Exception e = this.delegatedTaskErr;
- this.delegatedTaskErr = null;
- this.fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Error in delegated task", e);
- }
- int handshakeType;
- io_stream.append(bytes);
- while (io_stream.available() > 0) {
- io_stream.mark();
- int length;
- try {
- handshakeType = io_stream.read();
- length = io_stream.readUint24();
- if (io_stream.available() < length) {
- io_stream.reset();
- return;
- }
- switch (handshakeType) {
- case 0: // HELLO_REQUEST
- // we don't need to take this message into account
- // during FINISH message verification, so remove it
- io_stream.removeFromMarkedPosition();
- if (clientHello != null
- && (clientFinished == null || serverFinished == null)) {
- //currently negotiating - ignore
- break;
- }
- // renegotiate
- if (session.isValid()) {
- session = (SSLSessionImpl) session.clone();
- isResuming = true;
- startSession();
- } else {
- // if SSLSession is invalidated (e.g. timeout limit is
- // exceeded) connection can't resume the session.
- renegotiateNewSession();
- }
- break;
- case 2: // SERVER_HELLO
- if (clientHello == null || serverHello != null) {
- unexpectedMessage();
- return;
- }
- serverHello = new ServerHello(io_stream, length);
-
- //check protocol version
- ProtocolVersion servProt = ProtocolVersion.getByVersion(serverHello.server_version);
- String[] enabled = parameters.getEnabledProtocols();
- find: {
- for (int i = 0; i < enabled.length; i++) {
- if (servProt.equals(ProtocolVersion.getByName(enabled[i]))) {
- break find;
- }
- }
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello protocol version");
- }
-
- // check compression method
- if (serverHello.compression_method != 0) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello compression method");
- }
-
- //check cipher_suite
- CipherSuite[] enabledSuites = parameters.getEnabledCipherSuitesMember();
- find: {
- for (int i = 0; i < enabledSuites.length; i++) {
- if (serverHello.cipher_suite.equals(enabledSuites[i])) {
- break find;
- }
- }
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello cipher suite");
- }
-
- if (isResuming) {
- if (serverHello.session_id.length == 0) {
- // server is not willing to establish the new connection
- // using specified session
- isResuming = false;
- } else if (!Arrays.equals(serverHello.session_id, clientHello.session_id)) {
- isResuming = false;
- } else if (!session.protocol.equals(servProt)) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello protocol version");
- } else if (!session.cipherSuite.equals(serverHello.cipher_suite)) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello cipher suite");
- }
- if (serverHello.server_version[1] == 1) {
- computerReferenceVerifyDataTLS("server finished");
- } else {
- computerReferenceVerifyDataSSLv3(SSLv3Constants.server);
- }
- }
- session.protocol = servProt;
- recordProtocol.setVersion(session.protocol.version);
- session.cipherSuite = serverHello.cipher_suite;
- session.id = serverHello.session_id.clone();
- session.serverRandom = serverHello.random;
- break;
- case 11: // CERTIFICATE
- if (serverHello == null || serverKeyExchange != null
- || serverCert != null || isResuming) {
- unexpectedMessage();
- return;
- }
- serverCert = new CertificateMessage(io_stream, length);
- break;
- case 12: // SERVER_KEY_EXCHANGE
- if (serverHello == null || serverKeyExchange != null
- || isResuming) {
- unexpectedMessage();
- return;
- }
- serverKeyExchange = new ServerKeyExchange(io_stream,
- length, session.cipherSuite.keyExchange);
- break;
- case 13: // CERTIFICATE_REQUEST
- if (serverCert == null || certificateRequest != null
- || session.cipherSuite.isAnonymous() || isResuming) {
- unexpectedMessage();
- return;
- }
- certificateRequest = new CertificateRequest(io_stream, length);
- break;
- case 14: // SERVER_HELLO_DONE
- if (serverHello == null || serverHelloDone != null || isResuming) {
- unexpectedMessage();
- return;
- }
- serverHelloDone = new ServerHelloDone(io_stream, length);
- if (this.nonBlocking) {
- delegatedTasks.add(new DelegatedTask(new Runnable() {
- public void run() {
- processServerHelloDone();
- }
- }, this));
- return;
- }
- processServerHelloDone();
- break;
- case 20: // FINISHED
- if (!changeCipherSpecReceived) {
- unexpectedMessage();
- return;
- }
- serverFinished = new Finished(io_stream, length);
- verifyFinished(serverFinished.getData());
- session.lastAccessedTime = System.currentTimeMillis();
- session.context = parameters.getClientSessionContext();
- parameters.getClientSessionContext().putSession(session);
- if (isResuming) {
- sendChangeCipherSpec();
- } else {
- session.lastAccessedTime = System.currentTimeMillis();
- status = FINISHED;
- }
- // XXX there is no cleanup work
- break;
- default:
- unexpectedMessage();
- return;
- }
- } catch (IOException e) {
- // io stream dosn't contain complete handshake message
- io_stream.reset();
- return;
- }
- }
-
- }
-
- /**
- * Processes SSLv2 Hello message.
- * SSLv2 client hello message message is an unexpected message
- * for client side of handshake protocol.
- * See TLS 1.0 spec., E.1. Version 2 client hello
- * @param bytes
- */
- @Override
- public void unwrapSSLv2(byte[] bytes) {
- unexpectedMessage();
- }
-
- /**
- * Creates and sends Finished message
- */
- @Override
- protected void makeFinished() {
- byte[] verify_data;
- if (serverHello.server_version[1] == 1) {
- verify_data = new byte[12];
- computerVerifyDataTLS("client finished", verify_data);
- } else {
- verify_data = new byte[36];
- computerVerifyDataSSLv3(SSLv3Constants.client, verify_data);
- }
- clientFinished = new Finished(verify_data);
- send(clientFinished);
- if (isResuming) {
- session.lastAccessedTime = System.currentTimeMillis();
- status = FINISHED;
- } else {
- if (serverHello.server_version[1] == 1) {
- computerReferenceVerifyDataTLS("server finished");
- } else {
- computerReferenceVerifyDataSSLv3(SSLv3Constants.server);
- }
- status = NEED_UNWRAP;
- }
- }
-
- /**
- * Processes ServerHelloDone: makes verification of the server messages; sends
- * client messages, computers masterSecret, sends ChangeCipherSpec
- */
- void processServerHelloDone() {
- PrivateKey clientKey = null;
-
- if (serverCert != null) {
- if (session.cipherSuite.isAnonymous()) {
- unexpectedMessage();
- return;
- }
- verifyServerCert();
- } else {
- if (!session.cipherSuite.isAnonymous()) {
- unexpectedMessage();
- return;
- }
- }
-
- // Client certificate
- if (certificateRequest != null) {
- X509Certificate[] certs = null;
- // obtain certificates from key manager
- String alias = null;
- String[] certTypes = certificateRequest.getTypesAsString();
- X500Principal[] issuers = certificateRequest.certificate_authorities;
- X509KeyManager km = parameters.getKeyManager();
- if (km instanceof X509ExtendedKeyManager) {
- X509ExtendedKeyManager ekm = (X509ExtendedKeyManager)km;
- if (this.socketOwner != null) {
- alias = ekm.chooseClientAlias(certTypes, issuers, this.socketOwner);
- } else {
- alias = ekm.chooseEngineClientAlias(certTypes, issuers, this.engineOwner);
- }
- if (alias != null) {
- certs = ekm.getCertificateChain(alias);
- }
- } else {
- alias = km.chooseClientAlias(certTypes, issuers, this.socketOwner);
- if (alias != null) {
- certs = km.getCertificateChain(alias);
- }
- }
-
- session.localCertificates = certs;
- clientCert = new CertificateMessage(certs);
- clientKey = km.getPrivateKey(alias);
- send(clientCert);
- }
- // Client key exchange
- if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- // RSA encrypted premaster secret message
- Cipher c;
- try {
- c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- if (serverKeyExchange != null) {
- if (!session.cipherSuite.isAnonymous()) {
- DigitalSignature ds = new DigitalSignature(serverCert.getAuthType());
- ds.init(serverCert.certs[0]);
- ds.update(clientHello.getRandom());
- ds.update(serverHello.getRandom());
- if (!serverKeyExchange.verifySignature(ds)) {
- fatalAlert(AlertProtocol.DECRYPT_ERROR, "Cannot verify RSA params");
- return;
- }
- }
- c.init(Cipher.WRAP_MODE, serverKeyExchange
- .getRSAPublicKey());
- } else {
- c.init(Cipher.WRAP_MODE, serverCert.certs[0]);
- }
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "Unexpected exception", e);
- return;
- }
- preMasterSecret = new byte[48];
- parameters.getSecureRandom().nextBytes(preMasterSecret);
- System.arraycopy(clientHello.client_version, 0, preMasterSecret, 0, 2);
- try {
- clientKeyExchange = new ClientKeyExchange(c
- .wrap(new SecretKeySpec(preMasterSecret, "preMasterSecret")),
- serverHello.server_version[1] == 1);
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "Unexpected exception", e);
- return;
- }
- } else if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) {
- /*
- * All other key exchanges should have had a DH key communicated via
- * ServerKeyExchange beforehand.
- */
- if (serverKeyExchange == null) {
- fatalAlert(AlertProtocol.UNEXPECTED_MESSAGE, "Expected ServerKeyExchange");
- return;
- }
- if (session.cipherSuite.isAnonymous() != serverKeyExchange.isAnonymous()) {
- fatalAlert(AlertProtocol.DECRYPT_ERROR, "Wrong type in ServerKeyExchange");
- return;
- }
- try {
- if (!session.cipherSuite.isAnonymous()) {
- DigitalSignature ds = new DigitalSignature(serverCert.getAuthType());
- ds.init(serverCert.certs[0]);
- ds.update(clientHello.getRandom());
- ds.update(serverHello.getRandom());
- if (!serverKeyExchange.verifySignature(ds)) {
- fatalAlert(AlertProtocol.DECRYPT_ERROR, "Cannot verify DH params");
- return;
- }
- }
- KeyFactory kf = KeyFactory.getInstance("DH");
- KeyAgreement agreement = KeyAgreement.getInstance("DH");
- KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
- PublicKey serverDhPublic = kf.generatePublic(new DHPublicKeySpec(
- serverKeyExchange.par3, serverKeyExchange.par1,
- serverKeyExchange.par2));
- DHParameterSpec spec = new DHParameterSpec(serverKeyExchange.par1,
- serverKeyExchange.par2);
- kpg.initialize(spec);
- KeyPair kp = kpg.generateKeyPair();
- DHPublicKey pubDhKey = (DHPublicKey) kp.getPublic();
- clientKeyExchange = new ClientKeyExchange(pubDhKey.getY());
- PrivateKey privDhKey = kp.getPrivate();
- agreement.init(privDhKey);
- agreement.doPhase(serverDhPublic, true);
- preMasterSecret = agreement.generateSecret();
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "Unexpected exception", e);
- return;
- }
- } else {
- fatalAlert(AlertProtocol.DECRYPT_ERROR, "Unsupported handshake type");
- return;
- }
-
- if (clientKeyExchange != null) {
- send(clientKeyExchange);
- }
-
- computerMasterSecret();
-
- // send certificate verify for all certificates except those containing
- // fixed DH parameters
- if (clientCert != null && clientCert.certs.length > 0 && !clientKeyExchange.isEmpty()) {
- // Certificate verify
- String authType = clientKey.getAlgorithm();
- DigitalSignature ds = new DigitalSignature(authType);
- ds.init(clientKey);
-
- if ("RSA".equals(authType)) {
- ds.setMD5(io_stream.getDigestMD5());
- ds.setSHA(io_stream.getDigestSHA());
- } else if ("DSA".equals(authType)) {
- ds.setSHA(io_stream.getDigestSHA());
- // The Signature should be empty in case of anonymous signature algorithm:
- // } else if ("DH".equals(authType)) {
- }
- certificateVerify = new CertificateVerify(ds.sign());
- send(certificateVerify);
- }
-
- sendChangeCipherSpec();
- }
-
- /*
- * Verifies certificate path
- */
- private void verifyServerCert() {
- String authType = session.cipherSuite.getAuthType(serverKeyExchange != null);
- if (authType == null) {
- return;
- }
- String hostname = null;
- if (engineOwner != null) {
- hostname = engineOwner.getPeerHost();
- } else {
- // we don't want to do an inet address lookup here in case we're talking to a proxy
- hostname = socketOwner.getWrappedHostName();
- }
- try {
- X509TrustManager x509tm = parameters.getTrustManager();
- if (x509tm instanceof TrustManagerImpl) {
- TrustManagerImpl tm = (TrustManagerImpl) x509tm;
- tm.checkServerTrusted(serverCert.certs, authType, hostname);
- } else {
- x509tm.checkServerTrusted(serverCert.certs, authType);
- }
- } catch (CertificateException e) {
- fatalAlert(AlertProtocol.BAD_CERTIFICATE, "Not trusted server certificate", e);
- return;
- }
- session.peerCertificates = serverCert.certs;
- }
-
- /**
- * Processes ChangeCipherSpec message
- */
- @Override
- public void receiveChangeCipherSpec() {
- if (isResuming) {
- if (serverHello == null) {
- unexpectedMessage();
- }
- } else if (clientFinished == null) {
- unexpectedMessage();
- }
- changeCipherSpecReceived = true;
- }
-
- // Find session to resume in client session context
- private SSLSessionImpl findSessionToResume() {
- String host = null;
- int port = -1;
- if (engineOwner != null) {
- host = engineOwner.getPeerHost();
- port = engineOwner.getPeerPort();
- } else {
- host = socketOwner.getPeerHostName();
- port = socketOwner.getPeerPort();
- }
- if (host == null || port == -1) {
- return null; // starts new session
- }
-
- ClientSessionContext context = parameters.getClientSessionContext();
- SSLSessionImpl session
- = (SSLSessionImpl) context.getSession(host, port);
- if (session != null) {
- session = (SSLSessionImpl) session.clone();
- }
- return session;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/ClientHello.java b/crypto/src/main/java/org/conscrypt/ClientHello.java
deleted file mode 100644
index 2bf9f5f..0000000
--- a/crypto/src/main/java/org/conscrypt/ClientHello.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import libcore.io.Streams;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * Represents Client Hello message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.1.2.
- * Client hello</a>
- *
- */
-public class ClientHello extends Message {
-
- /**
- * Client version
- */
- final byte[] client_version;
-
- /**
- * Random bytes
- */
- final byte[] random = new byte[32];
-
- /**
- * Session id
- */
- final byte[] session_id;
-
- /**
- * Cipher suites supported by the client
- */
- final CipherSuite[] cipher_suites;
-
- /**
- * Compression methods supported by the client
- */
- final byte[] compression_methods;
-
- /**
- * Creates outbound message
- * @param sr
- * @param version
- * @param ses_id
- * @param cipher_suite
- */
- public ClientHello(SecureRandom sr, byte[] version, byte[] ses_id,
- CipherSuite[] cipher_suite) {
- client_version = version;
- long gmt_unix_time = System.currentTimeMillis()/1000;
- sr.nextBytes(random);
- random[0] = (byte) (gmt_unix_time & 0xFF000000 >>> 24);
- random[1] = (byte) (gmt_unix_time & 0xFF0000 >>> 16);
- random[2] = (byte) (gmt_unix_time & 0xFF00 >>> 8);
- random[3] = (byte) (gmt_unix_time & 0xFF);
- session_id = ses_id;
- this.cipher_suites = cipher_suite;
- compression_methods = new byte[] { 0 }; // CompressionMethod.null
- length = 38 + session_id.length + (this.cipher_suites.length << 1)
- + compression_methods.length;
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public ClientHello(HandshakeIODataStream in, int length) throws IOException {
- client_version = new byte[2];
- client_version[0] = (byte) in.readUint8();
- client_version[1] = (byte) in.readUint8();
- Streams.readFully(in, random);
- int size = in.read();
- session_id = new byte[size];
- in.read(session_id, 0, size);
- int l = in.readUint16();
- if ((l & 0x01) == 0x01) { // cipher suites length must be an even number
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect ClientHello");
- }
- size = l >> 1;
- cipher_suites = new CipherSuite[size];
- for (int i = 0; i < size; i++) {
- byte b0 = (byte) in.read();
- byte b1 = (byte) in.read();
- cipher_suites[i] = CipherSuite.getByCode(b0, b1);
- }
- size = in.read();
- compression_methods = new byte[size];
- in.read(compression_methods, 0, size);
- this.length = 38 + session_id.length + (cipher_suites.length << 1)
- + compression_methods.length;
- if (this.length > length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ClientHello");
- }
- // for forward compatibility, extra data is permitted;
- // must be ignored
- if (this.length < length) {
- in.skip(length - this.length);
- this.length = length;
- }
- }
- /**
- * Parse V2ClientHello
- * @param in
- * @throws IOException
- */
- public ClientHello(HandshakeIODataStream in) throws IOException {
- if (in.readUint8() != 1) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect V2ClientHello");
- }
- client_version = new byte[2];
- client_version[0] = (byte) in.readUint8();
- client_version[1] = (byte) in.readUint8();
- int cipher_spec_length = in.readUint16();
- if (in.readUint16() != 0) { // session_id_length
- // as client already knows the protocol known to a server it should
- // initiate the connection in that native protocol
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect V2ClientHello, cannot be used for resuming");
- }
- int challenge_length = in.readUint16();
- if (challenge_length < 16) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect V2ClientHello, short challenge data");
- }
- session_id = EmptyArray.BYTE;
- cipher_suites = new CipherSuite[cipher_spec_length/3];
- for (int i = 0; i < cipher_suites.length; i++) {
- byte b0 = (byte) in.read();
- byte b1 = (byte) in.read();
- byte b2 = (byte) in.read();
- cipher_suites[i] = CipherSuite.getByCode(b0, b1, b2);
- }
- compression_methods = new byte[] { 0 }; // CompressionMethod.null
-
- if (challenge_length < 32) {
- Arrays.fill(random, 0, 32 - challenge_length, (byte)0);
- System.arraycopy(in.read(challenge_length), 0, random, 32 - challenge_length, challenge_length);
- } else if (challenge_length == 32) {
- System.arraycopy(in.read(32), 0, random, 0, 32);
- } else {
- System.arraycopy(in.read(challenge_length), challenge_length - 32, random, 0, 32);
- }
- if (in.available() > 0) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect V2ClientHello, extra data");
- }
- this.length = 38 + session_id.length + (cipher_suites.length << 1)
- + compression_methods.length;
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- out.write(client_version);
- out.write(random);
- out.writeUint8(session_id.length);
- out.write(session_id);
- int size = cipher_suites.length << 1;
- out.writeUint16(size);
- for (int i = 0; i < cipher_suites.length; i++) {
- out.write(cipher_suites[i].toBytes());
- }
- out.writeUint8(compression_methods.length);
- for (int i = 0; i < compression_methods.length; i++) {
- out.write(compression_methods[i]);
- }
- }
-
- /**
- * Returns client random
- * @return client random
- */
- public byte[] getRandom() {
- return random;
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CLIENT_HELLO;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ClientKeyExchange.java b/crypto/src/main/java/org/conscrypt/ClientKeyExchange.java
deleted file mode 100644
index 5cad36b..0000000
--- a/crypto/src/main/java/org/conscrypt/ClientKeyExchange.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import libcore.io.Streams;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * Represents client key exchange message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.7.
- * Client key exchange message</a>
- *
- */
-public class ClientKeyExchange extends Message {
-
- /**
- * Exchange keys
- */
- final byte[] exchange_keys;
-
- /**
- * Equals true if TLS1.0 protocol is used
- */
- boolean isTLS;
-
- /**
- * Equals true if key exchange algorithm is RSA
- */
- final boolean isRSA;
-
- /**
- * Creates outbound message
- * @param encrypted_pre_master_secret
- * @param isTLS
- */
- public ClientKeyExchange(byte[] encrypted_pre_master_secret, boolean isTLS) {
- this.exchange_keys = encrypted_pre_master_secret;
- length = this.exchange_keys.length;
- if (isTLS) {
- length += 2;
- }
- this.isTLS = isTLS;
- isRSA = true;
- }
-
- /**
- * Creates outbound message
- * @param dh_Yc
- */
- public ClientKeyExchange(BigInteger dh_Yc) {
- byte[] bb = dh_Yc.toByteArray();
- if (bb[0] == 0) {
- exchange_keys = new byte[bb.length-1];
- System.arraycopy(bb, 1, exchange_keys, 0, exchange_keys.length);
- } else {
- exchange_keys = bb;
- }
- length = exchange_keys.length +2;
- isRSA = false;
- }
-
- /**
- * Creates empty message
- *
- */
- public ClientKeyExchange() {
- exchange_keys = EmptyArray.BYTE;
- length = 0;
- isRSA = false;
- }
-
- /**
- * Creates inbound message
- * @param length
- * @param isTLS
- * @param isRSA
- * @throws IOException
- */
- public ClientKeyExchange(HandshakeIODataStream in, int length, boolean isTLS, boolean isRSA)
- throws IOException {
- this.isTLS = isTLS;
- this.isRSA = isRSA;
- if (length == 0) {
- this.length = 0;
- exchange_keys = EmptyArray.BYTE;
- } else {
- int size;
- if (isRSA && !isTLS) {// SSL3.0 RSA
- size = length;
- this.length = size;
- } else { // DH or TLSv1 RSA
- size = in.readUint16();
- this.length = 2 + size;
- }
- exchange_keys = new byte[size];
- Streams.readFully(in, exchange_keys);
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ClientKeyExchange");
- }
- }
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- if (exchange_keys.length != 0) {
- if (!isRSA || isTLS) {// DH or TLSv1 RSA
- out.writeUint16(exchange_keys.length);
- }
- out.write(exchange_keys);
- }
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CLIENT_KEY_EXCHANGE;
- }
-
- /**
- * Returns true if the message is empty (in case of implicit DH Yc)
- */
- public boolean isEmpty() {
- return (exchange_keys.length == 0);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ClientSessionContext.java b/crypto/src/main/java/org/conscrypt/ClientSessionContext.java
deleted file mode 100644
index 27a39cf..0000000
--- a/crypto/src/main/java/org/conscrypt/ClientSessionContext.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.net.ssl.SSLSession;
-
-/**
- * Caches client sessions. Indexes by host and port. Users are typically
- * looking to reuse any session for a given host and port.
- */
-public class ClientSessionContext extends AbstractSessionContext {
-
- /**
- * Sessions indexed by host and port. Protect from concurrent
- * access by holding a lock on sessionsByHostAndPort.
- */
- final Map<HostAndPort, SSLSession> sessionsByHostAndPort
- = new HashMap<HostAndPort, SSLSession>();
-
- private SSLClientSessionCache persistentCache;
-
- public ClientSessionContext() {
- super(10, 0);
- }
-
- public int size() {
- return sessionsByHostAndPort.size();
- }
-
- public void setPersistentCache(SSLClientSessionCache persistentCache) {
- this.persistentCache = persistentCache;
- }
-
- protected void sessionRemoved(SSLSession session) {
- String host = session.getPeerHost();
- int port = session.getPeerPort();
- if (host == null) {
- return;
- }
- HostAndPort hostAndPortKey = new HostAndPort(host, port);
- synchronized (sessionsByHostAndPort) {
- sessionsByHostAndPort.remove(hostAndPortKey);
- }
- }
-
- /**
- * Finds a cached session for the given host name and port.
- *
- * @param host of server
- * @param port of server
- * @return cached session or null if none found
- */
- public SSLSession getSession(String host, int port) {
- if (host == null) {
- return null;
- }
- SSLSession session;
- HostAndPort hostAndPortKey = new HostAndPort(host, port);
- synchronized (sessionsByHostAndPort) {
- session = sessionsByHostAndPort.get(hostAndPortKey);
- }
- if (session != null && session.isValid()) {
- return session;
- }
-
- // Look in persistent cache.
- if (persistentCache != null) {
- byte[] data = persistentCache.getSessionData(host, port);
- if (data != null) {
- session = toSession(data, host, port);
- if (session != null && session.isValid()) {
- super.putSession(session);
- synchronized (sessionsByHostAndPort) {
- sessionsByHostAndPort.put(hostAndPortKey, session);
- }
- return session;
- }
- }
- }
-
- return null;
- }
-
- @Override
- public void putSession(SSLSession session) {
- super.putSession(session);
-
- String host = session.getPeerHost();
- int port = session.getPeerPort();
- if (host == null) {
- return;
- }
-
- HostAndPort hostAndPortKey = new HostAndPort(host, port);
- synchronized (sessionsByHostAndPort) {
- sessionsByHostAndPort.put(hostAndPortKey, session);
- }
-
- // TODO: This in a background thread.
- if (persistentCache != null) {
- byte[] data = toBytes(session);
- if (data != null) {
- persistentCache.putSessionData(session, data);
- }
- }
- }
-
- static class HostAndPort {
- final String host;
- final int port;
-
- HostAndPort(String host, int port) {
- this.host = host;
- this.port = port;
- }
-
- @Override public int hashCode() {
- return host.hashCode() * 31 + port;
- }
-
- @Override public boolean equals(Object o) {
- if (!(o instanceof HostAndPort)) {
- return false;
- }
- HostAndPort lhs = (HostAndPort) o;
- return host.equals(lhs.host) && port == lhs.port;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ConnectionState.java b/crypto/src/main/java/org/conscrypt/ConnectionState.java
deleted file mode 100644
index 82fbf3c..0000000
--- a/crypto/src/main/java/org/conscrypt/ConnectionState.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.crypto.Cipher;
-
-/**
- * This abstract class is a base for Record Protocol operating environmet
- * of different SSL protocol versions.
- */
-public abstract class ConnectionState {
-
- /**
- * The cipher used for encode operations
- */
- protected Cipher encCipher;
-
- /**
- * The cipher used for decode operations
- */
- protected Cipher decCipher;
-
- /**
- * The block size, or zero if not a block cipher
- */
- protected int block_size;
-
- /**
- * The size of MAC used under this connection state
- */
- protected int hash_size;
-
- /**
- * Write sequence number which is incremented after each
- * encrypt call
- */
- protected final byte[] write_seq_num = {0, 0, 0, 0, 0, 0, 0, 0};
-
- /**
- * Read sequence number which is incremented after each
- * decrypt call
- */
- protected final byte[] read_seq_num = {0, 0, 0, 0, 0, 0, 0, 0};
-
- protected Logger.Stream logger = Logger.getStream("conn_state");
-
- /**
- * Returns the minimal possible size of the
- * Generic[Stream|Block]Cipher structure under this
- * connection state.
- */
- protected int getMinFragmentSize() {
- // block ciphers return value with padding included
- return encCipher.getOutputSize(1+hash_size); // 1 byte for data
- }
-
- /**
- * Returns the size of the Generic[Stream|Block]Cipher structure
- * corresponding to the content data of specified size.
- */
- protected int getFragmentSize(int content_size) {
- return encCipher.getOutputSize(content_size+hash_size);
- }
-
- /**
- * Returns the minimal upper bound of the content size enclosed
- * into the Generic[Stream|Block]Cipher structure of specified size.
- * For stream ciphers the returned value will be exact value.
- */
- protected int getContentSize(int generic_cipher_size) {
- //it does not take the padding of block ciphered structures
- //into account (so returned value can be greater than actual)
- return decCipher.getOutputSize(generic_cipher_size)-hash_size;
- }
-
- /**
- * Returns the number of bytes of padding required to round the
- * content up to the required block size. Assumes power of two
- * block size.
- */
- protected int getPaddingSize(int content_size) {
- int mask = block_size - 1;
- return (block_size - (content_size & mask));
- }
-
- /**
- * Creates the GenericStreamCipher or GenericBlockCipher
- * data structure for specified data of specified type.
- * @param type - the ContentType of the provided data
- * @param fragment - the byte array containing the
- * data to be encrypted under the current connection state.
- */
- protected byte[] encrypt(byte type, byte[] fragment) {
- return encrypt(type, fragment, 0, fragment.length);
- }
-
- /**
- * Creates the GenericStreamCipher or GenericBlockCipher
- * data structure for specified data of specified type.
- * @param type - the ContentType of the provided data
- * @param fragment - the byte array containing the
- * data to be encrypted under the current connection state.
- * @param offset - the offset from which the data begins with.
- * @param len - the length of the data.
- */
- protected abstract byte[] encrypt
- (byte type, byte[] fragment, int offset, int len);
-
- /**
- * Retrieves the fragment of the Plaintext structure of
- * the specified type from the provided data.
- * @param type - the ContentType of the data to be decrypted.
- * @param fragment - the byte array containing the
- * data to be encrypted under the current connection state.
- */
- protected byte[] decrypt(byte type, byte[] fragment) {
- return decrypt(type, fragment, 0, fragment.length);
- }
-
- /**
- * Retrieves the fragment of the Plaintext structure of
- * the specified type from the provided data.
- * @param type - the ContentType of the data to be decrypted.
- * @param fragment - the byte array containing the
- * data to be encrypted under the current connection state.
- * @param offset - the offset from which the data begins with.
- * @param len - the length of the data.
- */
- protected abstract byte[] decrypt
- (byte type, byte[] fragment, int offset, int len);
-
- /**
- * Increments the sequence number.
- */
- protected static void incSequenceNumber(byte[] seq_num) {
- int octet = 7;
- while (octet >= 0) {
- seq_num[octet] ++;
- if (seq_num[octet] == 0) {
- // characteristic overflow, so
- // carrying a number in adding
- octet --;
- } else {
- return;
- }
- }
- }
-
- /**
- * Shutdownes the protocol. It will be impossiblke to use the instance
- * after the calling of this method.
- */
- protected void shutdown() {
- encCipher = null;
- decCipher = null;
- for (int i=0; i<write_seq_num.length; i++) {
- write_seq_num[i] = 0;
- read_seq_num[i] = 0;
- }
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/ConnectionStateSSLv3.java b/crypto/src/main/java/org/conscrypt/ConnectionStateSSLv3.java
deleted file mode 100644
index 84b8483..0000000
--- a/crypto/src/main/java/org/conscrypt/ConnectionStateSSLv3.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.util.Arrays;
-import javax.crypto.Cipher;
-import javax.crypto.NullCipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.SSLProtocolException;
-
-/**
- * This class encapsulates the operating environment of the SSL v3
- * (http://wp.netscape.com/eng/ssl3) Record Protocol and provides
- * relating encryption/decryption functionality.
- * The work functionality is based on the security
- * parameters negotiated during the handshake.
- */
-public class ConnectionStateSSLv3 extends ConnectionState {
-
- // digest to create and check the message integrity info
- private final MessageDigest messageDigest;
- private final byte[] mac_write_secret;
- private final byte[] mac_read_secret;
-
- // paddings
- private final byte[] pad_1;
- private final byte[] pad_2;
- // array will hold the part of the MAC material:
- // length of 3 == 1(SSLCompressed.type) + 2(SSLCompressed.length)
- // (more on SSLv3 MAC computation and payload protection see
- // SSL v3 specification, p. 5.2.3)
- private final byte[] mac_material_part = new byte[3];
-
- /**
- * Creates the instance of SSL v3 Connection State. All of the
- * security parameters are provided by session object.
- * @param session the sessin object which incapsulates
- * all of the security parameters established by handshake protocol.
- * The key calculation for the state is done according
- * to the SSL v3 Protocol specification.
- * (http://www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt)
- */
- protected ConnectionStateSSLv3(SSLSessionImpl session) {
- try {
- CipherSuite cipherSuite = session.cipherSuite;
-
- boolean is_exportabe = cipherSuite.isExportable();
- hash_size = cipherSuite.getMACLength();
- int key_size = (is_exportabe)
- ? cipherSuite.keyMaterial
- : cipherSuite.expandedKeyMaterial;
- int iv_size = cipherSuite.ivSize;
- block_size = cipherSuite.getBlockSize();
-
- String algName = cipherSuite.getBulkEncryptionAlgorithm();
- String hashName = cipherSuite.getHashName();
- if (logger != null) {
- logger.println("ConnectionStateSSLv3.create:");
- logger.println(" cipher suite name: "
- + session.getCipherSuite());
- logger.println(" encryption alg name: " + algName);
- logger.println(" hash alg name: " + hashName);
- logger.println(" hash size: " + hash_size);
- logger.println(" block size: " + block_size);
- logger.println(" IV size:" + iv_size);
- logger.println(" key size: " + key_size);
- }
-
- byte[] clientRandom = session.clientRandom;
- byte[] serverRandom = session.serverRandom;
- // so we need PRF value of size of
- // 2*hash_size + 2*key_size + 2*iv_size
- byte[] key_block = new byte[2*hash_size + 2*key_size + 2*iv_size];
- byte[] seed = new byte[clientRandom.length + serverRandom.length];
- System.arraycopy(serverRandom, 0, seed, 0, serverRandom.length);
- System.arraycopy(clientRandom, 0, seed, serverRandom.length,
- clientRandom.length);
-
- PRF.computePRF_SSLv3(key_block, session.master_secret, seed);
-
- byte[] client_mac_secret = new byte[hash_size];
- byte[] server_mac_secret = new byte[hash_size];
- byte[] client_key = new byte[key_size];
- byte[] server_key = new byte[key_size];
-
- boolean is_client = !session.isServer;
-
- System.arraycopy(key_block, 0, client_mac_secret, 0, hash_size);
- System.arraycopy(key_block, hash_size,
- server_mac_secret, 0, hash_size);
- System.arraycopy(key_block, 2*hash_size, client_key, 0, key_size);
- System.arraycopy(key_block, 2*hash_size+key_size,
- server_key, 0, key_size);
-
- IvParameterSpec clientIV = null;
- IvParameterSpec serverIV = null;
-
- if (is_exportabe) {
- if (logger != null) {
- logger.println("ConnectionStateSSLv3: is_exportable");
- }
-
- MessageDigest md5 = MessageDigest.getInstance("MD5");
- md5.update(client_key);
- md5.update(clientRandom);
- md5.update(serverRandom);
- client_key = md5.digest();
-
- md5.update(server_key);
- md5.update(serverRandom);
- md5.update(clientRandom);
- server_key = md5.digest();
-
- key_size = cipherSuite.expandedKeyMaterial;
-
- if (block_size != 0) {
- md5.update(clientRandom);
- md5.update(serverRandom);
- clientIV = new IvParameterSpec(md5.digest(), 0, iv_size);
- md5.update(serverRandom);
- md5.update(clientRandom);
- serverIV = new IvParameterSpec(md5.digest(), 0, iv_size);
- }
- } else if (block_size != 0) {
- clientIV = new IvParameterSpec(key_block,
- 2*hash_size+2*key_size, iv_size);
- serverIV = new IvParameterSpec(key_block,
- 2*hash_size+2*key_size+iv_size, iv_size);
- }
-
- if (logger != null) {
- logger.println("is exportable: "+is_exportabe);
- logger.println("master_secret");
- logger.print(session.master_secret);
- logger.println("client_random");
- logger.print(clientRandom);
- logger.println("server_random");
- logger.print(serverRandom);
- //logger.println("key_block");
- //logger.print(key_block);
- logger.println("client_mac_secret");
- logger.print(client_mac_secret);
- logger.println("server_mac_secret");
- logger.print(server_mac_secret);
- logger.println("client_key");
- logger.print(client_key, 0, key_size);
- logger.println("server_key");
- logger.print(server_key, 0, key_size);
- if (clientIV != null) {
- logger.println("client_iv");
- logger.print(clientIV.getIV());
- logger.println("server_iv");
- logger.print(serverIV.getIV());
- } else {
- logger.println("no IV.");
- }
- }
-
- if (algName == null) {
- encCipher = new NullCipher();
- decCipher = new NullCipher();
- } else {
- encCipher = Cipher.getInstance(algName);
- decCipher = Cipher.getInstance(algName);
- if (is_client) { // client side
- encCipher.init(Cipher.ENCRYPT_MODE,
- new SecretKeySpec(client_key, 0, key_size, algName),
- clientIV);
- decCipher.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(server_key, 0, key_size, algName),
- serverIV);
- } else { // server side
- encCipher.init(Cipher.ENCRYPT_MODE,
- new SecretKeySpec(server_key, 0, key_size, algName),
- serverIV);
- decCipher.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(client_key, 0, key_size, algName),
- clientIV);
- }
- }
-
- messageDigest = MessageDigest.getInstance(hashName);
- if (is_client) { // client side
- mac_write_secret = client_mac_secret;
- mac_read_secret = server_mac_secret;
- } else { // server side
- mac_write_secret = server_mac_secret;
- mac_read_secret = client_mac_secret;
- }
- if (hashName.equals("MD5")) {
- pad_1 = SSLv3Constants.MD5pad1;
- pad_2 = SSLv3Constants.MD5pad2;
- } else {
- pad_1 = SSLv3Constants.SHApad1;
- pad_2 = SSLv3Constants.SHApad2;
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException(
- "Error during computation of security parameters"));
- }
- }
-
- /**
- * Creates the GenericStreamCipher or GenericBlockCipher
- * data structure for specified data of specified type.
- * @throws AlertException if alert was occurred.
- */
- @Override
- protected byte[] encrypt(byte type, byte[] fragment, int offset, int len) {
- try {
- int content_mac_length = len + hash_size;
- int padding_length = (block_size == 0) ? 0 : getPaddingSize(++content_mac_length);
- byte[] res = new byte[content_mac_length + padding_length];
- System.arraycopy(fragment, offset, res, 0, len);
-
- mac_material_part[0] = type;
- mac_material_part[1] = (byte) ((0x00FF00 & len) >> 8);
- mac_material_part[2] = (byte) (0x0000FF & len);
-
- messageDigest.update(mac_write_secret);
- messageDigest.update(pad_1);
- messageDigest.update(write_seq_num);
- messageDigest.update(mac_material_part);
- messageDigest.update(fragment, offset, len);
- byte[] digest = messageDigest.digest();
- messageDigest.update(mac_write_secret);
- messageDigest.update(pad_2);
- messageDigest.update(digest);
- digest = messageDigest.digest();
- System.arraycopy(digest, 0, res, len, hash_size);
-
- //if (logger != null) {
- // logger.println("MAC Material:");
- // logger.print(write_seq_num);
- // logger.print(mac_material_header);
- // logger.print(fragment, offset, len);
- //}
-
- if (block_size != 0) {
- // do padding:
- Arrays.fill(res, content_mac_length-1,
- res.length, (byte) (padding_length));
- }
- if (logger != null) {
- logger.println("SSLRecordProtocol.encrypt: "
- + (block_size != 0
- ? "GenericBlockCipher with padding["
- +padding_length+"]:"
- : "GenericStreamCipher:"));
- logger.print(res);
- }
- byte[] rez = new byte[encCipher.getOutputSize(res.length)];
- encCipher.update(res, 0, res.length, rez);
- incSequenceNumber(write_seq_num);
- return rez;
- } catch (GeneralSecurityException e) {
- e.printStackTrace();
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException("Error during the encryption"));
- }
- }
-
- /**
- * Retrieves the fragment of the Plaintext structure of
- * the specified type from the provided data.
- * @throws AlertException if alert was occured.
- */
- @Override
- protected byte[] decrypt(byte type, byte[] fragment,
- int offset, int len) {
- // plain data of the Generic[Stream|Block]Cipher structure
- byte[] data = decCipher.update(fragment, offset, len);
- // the 'content' part of the structure
- byte[] content;
- if (block_size != 0) {
- // check padding
- int padding_length = data[data.length-1] & 0xFF;
- for (int i=0; i<padding_length; i++) {
- if ((data[data.length-2-i] & 0xFF) != padding_length) {
- throw new AlertException(
- AlertProtocol.DECRYPTION_FAILED,
- new SSLProtocolException(
- "Received message has bad padding"));
- }
- }
- content = new byte[data.length - hash_size - padding_length - 1];
- } else {
- content = new byte[data.length - hash_size];
- }
-
- byte[] mac_value;
-
- mac_material_part[0] = type;
- mac_material_part[1] = (byte) ((0x00FF00 & content.length) >> 8);
- mac_material_part[2] = (byte) (0x0000FF & content.length);
-
- messageDigest.update(mac_read_secret);
- messageDigest.update(pad_1);
- messageDigest.update(read_seq_num);
- messageDigest.update(mac_material_part);
- messageDigest.update(data, 0, content.length);
- mac_value = messageDigest.digest();
- messageDigest.update(mac_read_secret);
- messageDigest.update(pad_2);
- messageDigest.update(mac_value);
- mac_value = messageDigest.digest();
-
- if (logger != null) {
- logger.println("Decrypted:");
- logger.print(data);
- //logger.println("MAC Material:");
- //logger.print(read_seq_num);
- //logger.print(mac_material_header);
- //logger.print(data, 0, content.length);
- logger.println("Expected mac value:");
- logger.print(mac_value);
- }
- // checking the mac value
- for (int i=0; i<hash_size; i++) {
- if (mac_value[i] != data[i+content.length]) {
- throw new AlertException(AlertProtocol.BAD_RECORD_MAC,
- new SSLProtocolException("Bad record MAC"));
- }
- }
- System.arraycopy(data, 0, content, 0, content.length);
- incSequenceNumber(read_seq_num);
- return content;
- }
-
- /**
- * Shutdown the protocol. It will be impossible to use the instance
- * after the calling of this method.
- */
- @Override
- protected void shutdown() {
- Arrays.fill(mac_write_secret, (byte) 0);
- Arrays.fill(mac_read_secret, (byte) 0);
- super.shutdown();
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/ConnectionStateTLS.java b/crypto/src/main/java/org/conscrypt/ConnectionStateTLS.java
deleted file mode 100644
index a4d9de8..0000000
--- a/crypto/src/main/java/org/conscrypt/ConnectionStateTLS.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.GeneralSecurityException;
-import java.util.Arrays;
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import javax.crypto.NullCipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.SSLProtocolException;
-
-/**
- * This class encapsulates the operating environment of the TLS v1
- * (http://www.ietf.org/rfc/rfc2246.txt) Record Protocol and provides
- * relating encryption/decryption functionality.
- * The work functionality is based on the security
- * parameters negotiated during the handshake.
- */
-public class ConnectionStateTLS extends ConnectionState {
-
- // Pre-calculated prf label values:
- // "key expansion".getBytes()
- private static byte[] KEY_EXPANSION_LABEL = {
- (byte) 0x6B, (byte) 0x65, (byte) 0x79, (byte) 0x20, (byte) 0x65,
- (byte) 0x78, (byte) 0x70, (byte) 0x61, (byte) 0x6E, (byte) 0x73,
- (byte) 0x69, (byte) 0x6F, (byte) 0x6E };
-
- // "client write key".getBytes()
- private static byte[] CLIENT_WRITE_KEY_LABEL = {
- (byte) 0x63, (byte) 0x6C, (byte) 0x69, (byte) 0x65, (byte) 0x6E,
- (byte) 0x74, (byte) 0x20, (byte) 0x77, (byte) 0x72, (byte) 0x69,
- (byte) 0x74, (byte) 0x65, (byte) 0x20, (byte) 0x6B, (byte) 0x65,
- (byte) 0x79 };
-
- // "server write key".getBytes()
- private static byte[] SERVER_WRITE_KEY_LABEL = {
- (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65,
- (byte) 0x72, (byte) 0x20, (byte) 0x77, (byte) 0x72, (byte) 0x69,
- (byte) 0x74, (byte) 0x65, (byte) 0x20, (byte) 0x6B, (byte) 0x65,
- (byte) 0x79 };
-
- // "IV block".getBytes()
- private static byte[] IV_BLOCK_LABEL = {
- (byte) 0x49, (byte) 0x56, (byte) 0x20, (byte) 0x62, (byte) 0x6C,
- (byte) 0x6F, (byte) 0x63, (byte) 0x6B };
-
- // MACs to create and check the message integrity info
- private final Mac encMac;
- private final Mac decMac;
-
- // Once created permanently used array:
- // is used to create the header of the MAC material value:
- // 5 == 1(TLSCompressed.type) + 2(TLSCompressed.version) +
- // 2(TLSCompressed.length)
- private final byte[] mac_material_header = new byte[] {0, 3, 1, 0, 0};
-
- /**
- * Creates the instance of TLS v1 Connection State. All of the
- * security parameters are provided by session object.
- * @param session the sessin object which incapsulates
- * all of the security parameters established by handshake protocol.
- * The key calculation for the state is done according
- * to the TLS v 1.0 Protocol specification.
- * (http://www.ietf.org/rfc/rfc2246.txt)
- */
- protected ConnectionStateTLS(SSLSessionImpl session) {
- try {
- CipherSuite cipherSuite = session.cipherSuite;
-
- hash_size = cipherSuite.getMACLength();
- boolean is_exportabe = cipherSuite.isExportable();
- int key_size = (is_exportabe)
- ? cipherSuite.keyMaterial
- : cipherSuite.expandedKeyMaterial;
- int iv_size = cipherSuite.ivSize;
- block_size = cipherSuite.getBlockSize();
-
- String algName = cipherSuite.getBulkEncryptionAlgorithm();
- String macName = cipherSuite.getHmacName();
- if (logger != null) {
- logger.println("ConnectionStateTLS.create:");
- logger.println(" cipher suite name: "
- + cipherSuite.getName());
- logger.println(" encryption alg name: " + algName);
- logger.println(" mac alg name: " + macName);
- logger.println(" hash size: " + hash_size);
- logger.println(" block size: " + block_size);
- logger.println(" IV size:" + iv_size);
- logger.println(" key size: " + key_size);
- }
-
- byte[] clientRandom = session.clientRandom;
- byte[] serverRandom = session.serverRandom;
- // so we need PRF value of size of
- // 2*hash_size + 2*key_size + 2*iv_size
- byte[] key_block = new byte[2*hash_size + 2*key_size + 2*iv_size];
- byte[] seed = new byte[clientRandom.length + serverRandom.length];
- System.arraycopy(serverRandom, 0, seed, 0, serverRandom.length);
- System.arraycopy(clientRandom, 0, seed, serverRandom.length,
- clientRandom.length);
-
- PRF.computePRF(key_block, session.master_secret,
- KEY_EXPANSION_LABEL, seed);
-
- byte[] client_mac_secret = new byte[hash_size];
- byte[] server_mac_secret = new byte[hash_size];
- byte[] client_key = new byte[key_size];
- byte[] server_key = new byte[key_size];
-
- boolean is_client = !session.isServer;
-
- System.arraycopy(key_block, 0, client_mac_secret, 0, hash_size);
- System.arraycopy(key_block, hash_size,
- server_mac_secret, 0, hash_size);
- System.arraycopy(key_block, 2*hash_size, client_key, 0, key_size);
- System.arraycopy(key_block, 2*hash_size+key_size,
- server_key, 0, key_size);
-
- IvParameterSpec clientIV = null;
- IvParameterSpec serverIV = null;
-
- if (is_exportabe) {
- System.arraycopy(clientRandom, 0,
- seed, 0, clientRandom.length);
- System.arraycopy(serverRandom, 0,
- seed, clientRandom.length, serverRandom.length);
- byte[] final_client_key =
- new byte[cipherSuite.expandedKeyMaterial];
- byte[] final_server_key =
- new byte[cipherSuite.expandedKeyMaterial];
- PRF.computePRF(final_client_key, client_key,
- CLIENT_WRITE_KEY_LABEL, seed);
- PRF.computePRF(final_server_key, server_key,
- SERVER_WRITE_KEY_LABEL, seed);
- client_key = final_client_key;
- server_key = final_server_key;
- if (block_size != 0) {
- byte[] iv_block = new byte[2*iv_size];
- PRF.computePRF(iv_block, null, IV_BLOCK_LABEL, seed);
- clientIV = new IvParameterSpec(iv_block, 0, iv_size);
- serverIV = new IvParameterSpec(iv_block, iv_size, iv_size);
- }
- } else if (block_size != 0) {
- clientIV = new IvParameterSpec(key_block,
- 2*(hash_size+key_size), iv_size);
- serverIV = new IvParameterSpec(key_block,
- 2*(hash_size+key_size)+iv_size, iv_size);
- }
-
- if (logger != null) {
- logger.println("is exportable: "+is_exportabe);
- logger.println("master_secret");
- logger.print(session.master_secret);
- logger.println("client_random");
- logger.print(clientRandom);
- logger.println("server_random");
- logger.print(serverRandom);
- //logger.println("key_block");
- //logger.print(key_block);
- logger.println("client_mac_secret");
- logger.print(client_mac_secret);
- logger.println("server_mac_secret");
- logger.print(server_mac_secret);
- logger.println("client_key");
- logger.print(client_key);
- logger.println("server_key");
- logger.print(server_key);
- if (clientIV == null) {
- logger.println("no IV.");
- } else {
- logger.println("client_iv");
- logger.print(clientIV.getIV());
- logger.println("server_iv");
- logger.print(serverIV.getIV());
- }
- }
-
- if (algName == null) {
- encCipher = new NullCipher();
- decCipher = new NullCipher();
- } else {
- encCipher = Cipher.getInstance(algName);
- decCipher = Cipher.getInstance(algName);
- if (is_client) { // client side
- encCipher.init(Cipher.ENCRYPT_MODE,
- new SecretKeySpec(client_key, algName), clientIV);
- decCipher.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(server_key, algName), serverIV);
- } else { // server side
- encCipher.init(Cipher.ENCRYPT_MODE,
- new SecretKeySpec(server_key, algName), serverIV);
- decCipher.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(client_key, algName), clientIV);
- }
- }
-
- encMac = Mac.getInstance(macName);
- decMac = Mac.getInstance(macName);
- if (is_client) { // client side
- encMac.init(new SecretKeySpec(client_mac_secret, macName));
- decMac.init(new SecretKeySpec(server_mac_secret, macName));
- } else { // server side
- encMac.init(new SecretKeySpec(server_mac_secret, macName));
- decMac.init(new SecretKeySpec(client_mac_secret, macName));
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException(
- "Error during computation of security parameters"));
- }
- }
-
- /**
- * Creates the GenericStreamCipher or GenericBlockCipher
- * data structure for specified data of specified type.
- * @throws AlertException if alert was occurred.
- */
- @Override
- protected byte[] encrypt(byte type, byte[] fragment, int offset, int len) {
- try {
- int content_mac_length = len + hash_size;
- int padding_length = (block_size == 0) ? 0 : getPaddingSize(++content_mac_length);
- byte[] res = new byte[content_mac_length + padding_length];
- System.arraycopy(fragment, offset, res, 0, len);
-
- mac_material_header[0] = type;
- mac_material_header[3] = (byte) ((0x00FF00 & len) >> 8);
- mac_material_header[4] = (byte) (0x0000FF & len);
-
- encMac.update(write_seq_num);
- encMac.update(mac_material_header);
- encMac.update(fragment, offset, len);
- encMac.doFinal(res, len);
-
- //if (logger != null) {
- // logger.println("MAC Material:");
- // logger.print(write_seq_num);
- // logger.print(mac_material_header);
- // logger.print(fragment, offset, len);
- //}
-
- if (block_size != 0) {
- // do padding:
- Arrays.fill(res, content_mac_length-1,
- res.length, (byte) (padding_length));
- }
- if (logger != null) {
- logger.println("SSLRecordProtocol.do_encryption: Generic"
- + (block_size != 0
- ? "BlockCipher with padding["+padding_length+"]:"
- : "StreamCipher:"));
- logger.print(res);
- }
- byte[] rez = new byte[encCipher.getOutputSize(res.length)];
- // We should not call just doFinal because it reinitialize
- // the cipher, but as says rfc 2246:
- // "For stream ciphers that do not use a synchronization
- // vector (such as RC4), the stream cipher state from the end
- // of one record is simply used on the subsequent packet."
- // and for block ciphers:
- // "The IV for subsequent records is the last ciphertext block from
- // the previous record."
- // i.e. we should keep the cipher state.
- encCipher.update(res, 0, res.length, rez);
- incSequenceNumber(write_seq_num);
- return rez;
- } catch (GeneralSecurityException e) {
- e.printStackTrace();
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException("Error during the encryption"));
- }
- }
-
- /**
- * Retrieves the fragment of the Plaintext structure of
- * the specified type from the provided data representing
- * the Generic[Stream|Block]Cipher structure.
- * @throws AlertException if alert was occurred.
- */
- @Override
- protected byte[] decrypt(byte type, byte[] fragment,
- int offset, int len) {
- // plain data of the Generic[Stream|Block]Cipher structure
- byte[] data = decCipher.update(fragment, offset, len);
- // the 'content' part of the structure
- byte[] content;
- if (block_size != 0) {
- // check padding
- int padding_length = data[data.length - 1] & 0xFF;
- for (int i=0; i<padding_length; i++) {
- if ((data[data.length-2-i] & 0xFF) != padding_length) {
- throw new AlertException(
- AlertProtocol.DECRYPTION_FAILED,
- new SSLProtocolException(
- "Received message has bad padding"));
- }
- }
- content = new byte[data.length - hash_size - padding_length - 1];
- } else {
- content = new byte[data.length - hash_size];
- }
-
- mac_material_header[0] = type;
- mac_material_header[3] = (byte) ((0x00FF00 & content.length) >> 8);
- mac_material_header[4] = (byte) (0x0000FF & content.length);
-
- decMac.update(read_seq_num);
- decMac.update(mac_material_header);
- decMac.update(data, 0, content.length); // mac.update(fragment);
- byte[] mac_value = decMac.doFinal();
- if (logger != null) {
- logger.println("Decrypted:");
- logger.print(data);
- //logger.println("MAC Material:");
- //logger.print(read_seq_num);
- //logger.print(mac_material_header);
- //logger.print(data, 0, content.length);
- logger.println("Expected mac value:");
- logger.print(mac_value);
- }
- // checking the mac value
- for (int i=0; i<hash_size; i++) {
- if (mac_value[i] != data[i+content.length]) {
- throw new AlertException(AlertProtocol.BAD_RECORD_MAC,
- new SSLProtocolException("Bad record MAC"));
- }
- }
- System.arraycopy(data, 0, content, 0, content.length);
- incSequenceNumber(read_seq_num);
- return content;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/ContentType.java b/crypto/src/main/java/org/conscrypt/ContentType.java
deleted file mode 100644
index b09f029..0000000
--- a/crypto/src/main/java/org/conscrypt/ContentType.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * This class incapsulates the constants determining the
- * types of SSL/TLS record's content data.
- * Constant values are taken according to the TLS v1 specification
- * (http://www.ietf.org/rfc/rfc2246.txt).
- */
-public class ContentType {
-
- /**
- * Identifies change cipher spec message
- */
- protected static final byte CHANGE_CIPHER_SPEC = 20;
-
- /**
- * Identifies alert message
- */
- protected static final byte ALERT = 21;
-
- /**
- * Identifies handshake message
- */
- protected static final byte HANDSHAKE = 22;
-
- /**
- * Identifies application data message
- */
- protected static final byte APPLICATION_DATA = 23;
-
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/DHParameters.java b/crypto/src/main/java/org/conscrypt/DHParameters.java
deleted file mode 100644
index 7a742b2..0000000
--- a/crypto/src/main/java/org/conscrypt/DHParameters.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-/**
- * This class contains well-known primes
- */
-public class DHParameters {
-
- // Well-known 512 bit prime
- // http://news.hping.org/sci.crypt.archive/2370.html
- private static byte[] prime512 = new byte[] { (byte) 0xF5, (byte) 0x2A, (byte) 0xFF,
- (byte) 0x3C, (byte) 0xE1, (byte) 0xB1, (byte) 0x29, (byte) 0x40,
- (byte) 0x18, (byte) 0x11, (byte) 0x8D, (byte) 0x7C, (byte) 0x84,
- (byte) 0xA7, (byte) 0x0A, (byte) 0x72, (byte) 0xD6, (byte) 0x86,
- (byte) 0xC4, (byte) 0x03, (byte) 0x19, (byte) 0xC8, (byte) 0x07,
- (byte) 0x29, (byte) 0x7A, (byte) 0xCA, (byte) 0x95, (byte) 0x0C,
- (byte) 0xD9, (byte) 0x96, (byte) 0x9F, (byte) 0xAB, (byte) 0xD0,
- (byte) 0x0A, (byte) 0x50, (byte) 0x9B, (byte) 0x02, (byte) 0x46,
- (byte) 0xD3, (byte) 0x08, (byte) 0x3D, (byte) 0x66, (byte) 0xA4,
- (byte) 0x5D, (byte) 0x41, (byte) 0x9F, (byte) 0x9C, (byte) 0x7C,
- (byte) 0xBD, (byte) 0x89, (byte) 0x4B, (byte) 0x22, (byte) 0x19,
- (byte) 0x26, (byte) 0xBA, (byte) 0xAB, (byte) 0xA2, (byte) 0x5E,
- (byte) 0xC3, (byte) 0x55, (byte) 0xE9, (byte) 0x2A, (byte) 0x05,
- (byte) 0x5F };
-
- // Well-Known Group 1: A 768 bit prime rfc 2539
- // (http://www.ietf.org/rfc/rfc2539.txt?number=2539)
- private static byte[] primeGroup1 = { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9,
- (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68,
- (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62,
- (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1,
- (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A,
- (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B,
- (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
- (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79,
- (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF,
- (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A,
- (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A,
- (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37,
- (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D,
- (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
- (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E,
- (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9,
- (byte) 0xA6, (byte) 0x3A, (byte) 0x36, (byte) 0x20, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF };
-
- // Well-Known Group 2: A 1024 bit prime rfc 2539
- // (http://www.ietf.org/rfc/rfc2539.txt?number=2539)
- private static byte[] primeGroup2 = { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9,
- (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68,
- (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62,
- (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1,
- (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A,
- (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B,
- (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
- (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79,
- (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF,
- (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A,
- (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A,
- (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37,
- (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D,
- (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
- (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E,
- (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9,
- (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B,
- (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06,
- (byte) 0xB7, (byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B,
- (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5,
- (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C,
- (byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28,
- (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE6, (byte) 0x53,
- (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF
- };
-
- private static byte[] prime;
-
- static {
-//TODO set prime depand on some system or security property
- prime = prime512;
- }
-
- /**
- * Returns prime bytes
- * @return
- */
- public static byte[] getPrime() {
- return prime;
- }
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/DataStream.java b/crypto/src/main/java/org/conscrypt/DataStream.java
deleted file mode 100644
index d65b01a..0000000
--- a/crypto/src/main/java/org/conscrypt/DataStream.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * This interface represents the ability of the
- * classes to provide the chunks of data.
- */
-public interface DataStream {
-
- /**
- * Checks if there is data to be read.
- * @return true if there is the input data in the stream,
- * false otherwise
- */
- public boolean hasData();
-
- /**
- * Retrieves the data of specified length from the stream.
- * If the data size in the stream is less than specified length,
- * method returns all the data contained in the stream.
- * @return byte array containing the demanded data.
- */
- public byte[] getData(int length);
-
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/DefaultSSLContextImpl.java b/crypto/src/main/java/org/conscrypt/DefaultSSLContextImpl.java
deleted file mode 100644
index c90787f..0000000
--- a/crypto/src/main/java/org/conscrypt/DefaultSSLContextImpl.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-/**
- * Support class for this package.
- */
-public final class DefaultSSLContextImpl extends OpenSSLContextImpl {
-
- /**
- * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
- * DefaultSSLContextImpl.class monitor
- */
- private static KeyManager[] KEY_MANAGERS;
-
- /**
- * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
- * DefaultSSLContextImpl.class monitor
- */
- private static TrustManager[] TRUST_MANAGERS;
-
- /**
- * DefaultSSLContextImpl delegates the work to the super class
- * since there is no way to put a synchronized around both the
- * call to super and the rest of this constructor to guarantee
- * that we don't have races in creating the state shared between
- * all default SSLContexts.
- */
- public DefaultSSLContextImpl() throws GeneralSecurityException, IOException {
- super(null);
- }
-
- // TODO javax.net.ssl.keyStoreProvider system property
- KeyManager[] getKeyManagers () throws GeneralSecurityException, IOException {
- if (KEY_MANAGERS != null) {
- return KEY_MANAGERS;
- }
- // find KeyStore, KeyManagers
- String keystore = System.getProperty("javax.net.ssl.keyStore");
- if (keystore == null) {
- return null;
- }
- String keystorepwd = System.getProperty("javax.net.ssl.keyStorePassword");
- char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
-
- KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
- InputStream is = null;
- try {
- is = new BufferedInputStream(new FileInputStream(keystore));
- ks.load(is, pwd);
- } finally {
- if (is != null) {
- is.close();
- }
- }
-
- String kmfAlg = KeyManagerFactory.getDefaultAlgorithm();
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlg);
- kmf.init(ks, pwd);
- KEY_MANAGERS = kmf.getKeyManagers();
- return KEY_MANAGERS;
- }
-
- // TODO javax.net.ssl.trustStoreProvider system property
- TrustManager[] getTrustManagers() throws GeneralSecurityException, IOException {
- if (TRUST_MANAGERS != null) {
- return TRUST_MANAGERS;
- }
-
- // find TrustStore, TrustManagers
- String keystore = System.getProperty("javax.net.ssl.trustStore");
- if (keystore == null) {
- return null;
- }
- String keystorepwd = System.getProperty("javax.net.ssl.trustStorePassword");
- char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
-
- // TODO Defaults: jssecacerts; cacerts
- KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
- InputStream is = null;
- try {
- is = new BufferedInputStream(new FileInputStream(keystore));
- ks.load(is, pwd);
- } finally {
- if (is != null) {
- is.close();
- }
- }
- String tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
- tmf.init(ks);
- TRUST_MANAGERS = tmf.getTrustManagers();
- return TRUST_MANAGERS;
- }
-
- @Override
- public void engineInit(KeyManager[] kms, TrustManager[] tms,
- SecureRandom sr) throws KeyManagementException {
- throw new KeyManagementException("Do not init() the default SSLContext ");
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/DelegatedTask.java b/crypto/src/main/java/org/conscrypt/DelegatedTask.java
deleted file mode 100644
index 8eab2ea..0000000
--- a/crypto/src/main/java/org/conscrypt/DelegatedTask.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * Delegated Runnable task for SSLEngine
- */
-public class DelegatedTask implements Runnable {
-
- private final HandshakeProtocol handshaker;
- private final Runnable action;
-
- public DelegatedTask(Runnable action, HandshakeProtocol handshaker) {
- this.action = action;
- this.handshaker = handshaker;
- }
-
- public void run() {
- synchronized (handshaker) {
- try {
- action.run();
- } catch (RuntimeException e) {
- // pass exception to HandshakeProtocol
- handshaker.delegatedTaskErr = e;
- }
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/DigitalSignature.java b/crypto/src/main/java/org/conscrypt/DigitalSignature.java
deleted file mode 100644
index e24056e..0000000
--- a/crypto/src/main/java/org/conscrypt/DigitalSignature.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-import java.security.DigestException;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.Certificate;
-import java.util.Arrays;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.net.ssl.SSLException;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * This class represents Signature type, as described in TLS v 1.0 Protocol
- * specification, 7.4.3. It allow to init, update and sign hash. Hash algorithm
- * depends on SignatureAlgorithm.
- *
- * select (SignatureAlgorithm)
- * { case anonymous: struct { };
- * case rsa:
- * digitally-signed struct {
- * opaque md5_hash[16];
- * opaque sha_hash[20];
- * };
- * case dsa:
- * digitally-signed struct {
- * opaque sha_hash[20];
- * };
- * } Signature;
- *
- * Digital signing description see in TLS spec., 4.7.
- * (http://www.ietf.org/rfc/rfc2246.txt)
- *
- */
-public class DigitalSignature {
-
- private final MessageDigest md5;
- private final MessageDigest sha;
- private final Signature signature;
- private final Cipher cipher;
-
- private byte[] md5_hash;
- private byte[] sha_hash;
-
- /**
- * Create Signature type
- * @param algorithm the key algorithm used for the signature
- */
- public DigitalSignature(String algorithm) {
- try {
- sha = MessageDigest.getInstance("SHA-1");
-
- if ("RSA".equals(algorithm)) {
- md5 = MessageDigest.getInstance("MD5");
- cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- signature = null;
- } else if ("DSA".equals(algorithm)) {
- // SignatureAlgorithm is dsa
- signature = Signature.getInstance("NONEwithDSA");
- cipher = null;
- md5 = null;
- } else {
- cipher = null;
- signature = null;
- md5 = null;
- }
- } catch (NoSuchAlgorithmException e) {
- // this should never happen
- throw new AssertionError(e);
- } catch (NoSuchPaddingException e) {
- // this should never happen
- throw new AssertionError(e);
- }
- }
-
- /**
- * Initiate Signature type by private key
- * @param key
- */
- public void init(PrivateKey key) {
- try {
- if (signature != null) {
- signature.initSign(key);
- } else if (cipher != null) {
- cipher.init(Cipher.ENCRYPT_MODE, key);
- }
- } catch (InvalidKeyException e){
- throw new AlertException(AlertProtocol.BAD_CERTIFICATE,
- new SSLException("init - invalid private key", e));
- }
- }
-
- /**
- * Initiate Signature type by certificate
- * @param cert
- */
- public void init(Certificate cert) {
- try {
- if (signature != null) {
- signature.initVerify(cert);
- } else if (cipher != null) {
- cipher.init(Cipher.DECRYPT_MODE, cert);
- }
- } catch (InvalidKeyException e){
- throw new AlertException(AlertProtocol.BAD_CERTIFICATE,
- new SSLException("init - invalid certificate", e));
- }
- }
-
- /**
- * Update Signature hash
- * @param data
- */
- public void update(byte[] data) {
- if (sha != null) {
- sha.update(data);
- }
- if (md5 != null) {
- md5.update(data);
- }
- }
-
- /**
- * Sets MD5 hash
- * @param data
- */
- public void setMD5(byte[] data) {
- md5_hash = data;
- }
-
- /**
- * Sets SHA hash
- * @param data
- */
- public void setSHA(byte[] data) {
- sha_hash = data;
- }
-
- /**
- * Sign hash
- * @return Signature bytes
- */
- public byte[] sign() {
- try {
- if (md5 != null && md5_hash == null) {
- md5_hash = new byte[16];
- md5.digest(md5_hash, 0, md5_hash.length);
- }
- if (md5_hash != null) {
- if (signature != null) {
- signature.update(md5_hash);
- } else if (cipher != null) {
- cipher.update(md5_hash);
- }
- }
- if (sha != null && sha_hash == null) {
- sha_hash = new byte[20];
- sha.digest(sha_hash, 0, sha_hash.length);
- }
- if (sha_hash != null) {
- if (signature != null) {
- signature.update(sha_hash);
- } else if (cipher != null) {
- cipher.update(sha_hash);
- }
- }
- if (signature != null) {
- return signature.sign();
- } else if (cipher != null) {
- return cipher.doFinal();
- }
- return EmptyArray.BYTE;
- } catch (DigestException e){
- return EmptyArray.BYTE;
- } catch (SignatureException e){
- return EmptyArray.BYTE;
- } catch (BadPaddingException e){
- return EmptyArray.BYTE;
- } catch (IllegalBlockSizeException e){
- return EmptyArray.BYTE;
- }
- }
-
- /**
- * Verifies the signature data.
- * @param data - the signature bytes
- * @return true if verified
- */
- public boolean verifySignature(byte[] data) {
- if (signature != null) {
- try {
- if (sha_hash == null) {
- sha_hash = sha.digest();
- }
- signature.update(sha_hash);
- return signature.verify(data);
- } catch (SignatureException e) {
- return false;
- }
- }
-
- if (cipher != null) {
- final byte[] decrypt;
- try {
- decrypt = cipher.doFinal(data);
- } catch (IllegalBlockSizeException e) {
- return false;
- } catch (BadPaddingException e) {
- return false;
- }
-
- final byte[] md5_sha;
- if (sha != null && sha_hash == null) {
- sha_hash = sha.digest();
- }
- if (md5 != null && md5_hash == null) {
- md5_hash = md5.digest();
- }
- if (md5_hash != null && sha_hash != null) {
- md5_sha = new byte[md5_hash.length + sha_hash.length];
- System.arraycopy(md5_hash, 0, md5_sha, 0, md5_hash.length);
- System.arraycopy(sha_hash, 0, md5_sha, md5_hash.length, sha_hash.length);
- } else if (md5_hash != null) {
- md5_sha = md5_hash;
- } else {
- md5_sha = sha_hash;
- }
-
- return Arrays.equals(decrypt, md5_sha);
- } else if (data == null || data.length == 0) {
- return true;
- } else {
- return false;
- }
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/EndOfBufferException.java b/crypto/src/main/java/org/conscrypt/EndOfBufferException.java
deleted file mode 100644
index acd3417..0000000
--- a/crypto/src/main/java/org/conscrypt/EndOfBufferException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- * This exception indicates that data could not be read from the stream because the underlying input
- * stream reached its end.
- */
-public class EndOfBufferException extends IOException {
-
- private static final long serialVersionUID = 1838636631255369519L;
-
- public EndOfBufferException() {
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/EndOfSourceException.java b/crypto/src/main/java/org/conscrypt/EndOfSourceException.java
deleted file mode 100644
index 4789cd8..0000000
--- a/crypto/src/main/java/org/conscrypt/EndOfSourceException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- * This exception indicates that data could not be read from the buffered stream because underlying
- * data buffer was exhausted.
- */
-public class EndOfSourceException extends IOException {
-
- private static final long serialVersionUID = -4673611435974054413L;
-
- public EndOfSourceException() {
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/FileClientSessionCache.java b/crypto/src/main/java/org/conscrypt/FileClientSessionCache.java
deleted file mode 100644
index e4dab13..0000000
--- a/crypto/src/main/java/org/conscrypt/FileClientSessionCache.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.net.ssl.SSLSession;
-import libcore.io.IoUtils;
-
-/**
- * File-based cache implementation. Only one process should access the
- * underlying directory at a time.
- */
-public class FileClientSessionCache {
-
- public static final int MAX_SIZE = 12; // ~72k
-
- private FileClientSessionCache() {}
-
- /**
- * This cache creates one file per SSL session using "host.port" for
- * the file name. Files are created or replaced when session data is put
- * in the cache (see {@link #putSessionData}). Files are read on
- * cache hits, but not on cache misses.
- *
- * <p>When the number of session files exceeds MAX_SIZE, we delete the
- * least-recently-used file. We don't current persist the last access time,
- * so the ordering actually ends up being least-recently-modified in some
- * cases and even just "not accessed in this process" if the filesystem
- * doesn't track last modified times.
- */
- static class Impl implements SSLClientSessionCache {
-
- /** Directory to store session files in. */
- final File directory;
-
- /**
- * Map of name -> File. Keeps track of the order files were accessed in.
- */
- Map<String, File> accessOrder = newAccessOrder();
-
- /** The number of files on disk. */
- int size;
-
- /**
- * The initial set of files. We use this to defer adding information
- * about all files to accessOrder until necessary.
- */
- String[] initialFiles;
-
- /**
- * Constructs a new cache backed by the given directory.
- */
- Impl(File directory) throws IOException {
- boolean exists = directory.exists();
- if (exists && !directory.isDirectory()) {
- throw new IOException(directory + " exists but is not a directory.");
- }
-
- if (exists) {
- // Read and sort initial list of files. We defer adding
- // information about these files to accessOrder until necessary
- // (see indexFiles()). Sorting the list enables us to detect
- // cache misses in getSessionData().
- // Note: Sorting an array here was faster than creating a
- // HashSet on Dalvik.
- initialFiles = directory.list();
- if (initialFiles == null) {
- // File.list() will return null in error cases without throwing IOException
- // http://b/3363561
- throw new IOException(directory + " exists but cannot list contents.");
- }
- Arrays.sort(initialFiles);
- size = initialFiles.length;
- } else {
- // Create directory.
- if (!directory.mkdirs()) {
- throw new IOException("Creation of " + directory + " directory failed.");
- }
- size = 0;
- }
-
- this.directory = directory;
- }
-
- /**
- * Creates a new access-ordered linked hash map.
- */
- private static Map<String, File> newAccessOrder() {
- return new LinkedHashMap<String, File>(
- MAX_SIZE, 0.75f, true /* access order */);
- }
-
- /**
- * Gets the file name for the given host and port.
- */
- private static String fileName(String host, int port) {
- if (host == null) {
- throw new NullPointerException("host == null");
- }
- return host + "." + port;
- }
-
- public synchronized byte[] getSessionData(String host, int port) {
- /*
- * Note: This method is only called when the in-memory cache
- * in SSLSessionContext misses, so it would be unnecessarily
- * redundant for this cache to store data in memory.
- */
-
- String name = fileName(host, port);
- File file = accessOrder.get(name);
-
- if (file == null) {
- // File wasn't in access order. Check initialFiles...
- if (initialFiles == null) {
- // All files are in accessOrder, so it doesn't exist.
- return null;
- }
-
- // Look in initialFiles.
- if (Arrays.binarySearch(initialFiles, name) < 0) {
- // Not found.
- return null;
- }
-
- // The file is on disk but not in accessOrder yet.
- file = new File(directory, name);
- accessOrder.put(name, file);
- }
-
- FileInputStream in;
- try {
- in = new FileInputStream(file);
- } catch (FileNotFoundException e) {
- logReadError(host, file, e);
- return null;
- }
- try {
- int size = (int) file.length();
- byte[] data = new byte[size];
- new DataInputStream(in).readFully(data);
- return data;
- } catch (IOException e) {
- logReadError(host, file, e);
- return null;
- } finally {
- IoUtils.closeQuietly(in);
- }
- }
-
- static void logReadError(String host, File file, Throwable t) {
- System.logW("Error reading session data for " + host + " from " + file + ".", t);
- }
-
- public synchronized void putSessionData(SSLSession session,
- byte[] sessionData) {
- String host = session.getPeerHost();
- if (sessionData == null) {
- throw new NullPointerException("sessionData == null");
- }
-
- String name = fileName(host, session.getPeerPort());
- File file = new File(directory, name);
-
- // Used to keep track of whether or not we're expanding the cache.
- boolean existedBefore = file.exists();
-
- FileOutputStream out;
- try {
- out = new FileOutputStream(file);
- } catch (FileNotFoundException e) {
- // We can't write to the file.
- logWriteError(host, file, e);
- return;
- }
-
- // If we expanded the cache (by creating a new file)...
- if (!existedBefore) {
- size++;
-
- // Delete an old file if necessary.
- makeRoom();
- }
-
- boolean writeSuccessful = false;
- try {
- out.write(sessionData);
- writeSuccessful = true;
- } catch (IOException e) {
- logWriteError(host, file, e);
- } finally {
- boolean closeSuccessful = false;
- try {
- out.close();
- closeSuccessful = true;
- } catch (IOException e) {
- logWriteError(host, file, e);
- } finally {
- if (!writeSuccessful || !closeSuccessful) {
- // Storage failed. Clean up.
- delete(file);
- } else {
- // Success!
- accessOrder.put(name, file);
- }
- }
- }
- }
-
- /**
- * Deletes old files if necessary.
- */
- private void makeRoom() {
- if (size <= MAX_SIZE) {
- return;
- }
-
- indexFiles();
-
- // Delete LRUed files.
- int removals = size - MAX_SIZE;
- Iterator<File> i = accessOrder.values().iterator();
- do {
- delete(i.next());
- i.remove();
- } while (--removals > 0);
- }
-
- /**
- * Lazily updates accessOrder to know about all files as opposed to
- * just the files accessed since this process started.
- */
- private void indexFiles() {
- String[] initialFiles = this.initialFiles;
- if (initialFiles != null) {
- this.initialFiles = null;
-
- // Files on disk only, sorted by last modified time.
- // TODO: Use last access time.
- Set<CacheFile> diskOnly = new TreeSet<CacheFile>();
- for (String name : initialFiles) {
- // If the file hasn't been accessed in this process...
- if (!accessOrder.containsKey(name)) {
- diskOnly.add(new CacheFile(directory, name));
- }
- }
-
- if (!diskOnly.isEmpty()) {
- // Add files not accessed in this process to the beginning
- // of accessOrder.
- Map<String, File> newOrder = newAccessOrder();
- for (CacheFile cacheFile : diskOnly) {
- newOrder.put(cacheFile.name, cacheFile);
- }
- newOrder.putAll(accessOrder);
-
- this.accessOrder = newOrder;
- }
- }
- }
-
- @SuppressWarnings("ThrowableInstanceNeverThrown")
- private void delete(File file) {
- if (!file.delete()) {
- System.logW("Failed to delete " + file + ".", new IOException());
- }
- size--;
- }
-
- static void logWriteError(String host, File file, Throwable t) {
- System.logW("Error writing session data for " + host + " to " + file + ".", t);
- }
- }
-
- /**
- * Maps directories to the cache instances that are backed by those
- * directories. We synchronize access using the cache instance, so it's
- * important that everyone shares the same instance.
- */
- static final Map<File, FileClientSessionCache.Impl> caches
- = new HashMap<File, FileClientSessionCache.Impl>();
-
- /**
- * Returns a cache backed by the given directory. Creates the directory
- * (including parent directories) if necessary. This cache should have
- * exclusive access to the given directory.
- *
- * @param directory to store files in
- * @return a cache backed by the given directory
- * @throws IOException if the file exists and is not a directory or if
- * creating the directories fails
- */
- public static synchronized SSLClientSessionCache usingDirectory(
- File directory) throws IOException {
- FileClientSessionCache.Impl cache = caches.get(directory);
- if (cache == null) {
- cache = new FileClientSessionCache.Impl(directory);
- caches.put(directory, cache);
- }
- return cache;
- }
-
- /** For testing. */
- static synchronized void reset() {
- caches.clear();
- }
-
- /** A file containing a piece of cached data. */
- static class CacheFile extends File {
-
- final String name;
-
- CacheFile(File dir, String name) {
- super(dir, name);
- this.name = name;
- }
-
- long lastModified = -1;
-
- @Override
- public long lastModified() {
- long lastModified = this.lastModified;
- if (lastModified == -1) {
- lastModified = this.lastModified = super.lastModified();
- }
- return lastModified;
- }
-
- @Override
- public int compareTo(File another) {
- // Sort by last modified time.
- long result = lastModified() - another.lastModified();
- if (result == 0) {
- return super.compareTo(another);
- }
- return result < 0 ? -1 : 1;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/Finished.java b/crypto/src/main/java/org/conscrypt/Finished.java
deleted file mode 100644
index e0b7eaa..0000000
--- a/crypto/src/main/java/org/conscrypt/Finished.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- *
- * Represents Finished message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.9.
- * Finished</a>
- *
- */
-public class Finished extends Message {
-
- // verify data
- private byte[] data;
-
- /**
- * Creates outbound message
- * @param bytes
- */
- public Finished(byte[] bytes) {
- data = bytes;
- length = data.length;
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public Finished(HandshakeIODataStream in, int length)
- throws IOException {
- if (length == 12 || length == 36) {
- data = in.read(length);
- this.length = data.length;
- } else {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect Finished");
- }
- }
-
- @Override
- public void send(HandshakeIODataStream out) {
- out.write(data);
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.FINISHED;
- }
-
- /**
- * Returns verify data
- */
- public byte[] getData() {
- return data;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/Handshake.java b/crypto/src/main/java/org/conscrypt/Handshake.java
deleted file mode 100644
index 7cee71b..0000000
--- a/crypto/src/main/java/org/conscrypt/Handshake.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- *
- * This class incapsulates the constants determining the types of handshake
- * messages as defined in TLS 1.0 spec., 7.4. Handshake protocol.
- * (http://www.ietf.org/rfc/rfc2246.txt)
- *
- */
-public class Handshake {
-
- /**
- *
- * hello_request handshake type
- */
- public static final byte HELLO_REQUEST = 0;
-
- /**
- *
- * client_hello handshake type
- */
- public static final byte CLIENT_HELLO = 1;
-
- /**
- *
- * server_hello handshake type
- */
- public static final byte SERVER_HELLO = 2;
-
- /**
- *
- * certificate handshake type
- */
- public static final byte CERTIFICATE = 11;
-
- /**
- *
- * server_key_exchange handshake type
- */
- public static final byte SERVER_KEY_EXCHANGE = 12;
-
- /**
- *
- * certificate_request handshake type
- */
- public static final byte CERTIFICATE_REQUEST = 13;
-
- /**
- *
- * server_hello_done handshake type
- */
- public static final byte SERVER_HELLO_DONE = 14;
-
- /**
- *
- * certificate_verify handshake type
- */
- public static final byte CERTIFICATE_VERIFY = 15;
-
- /**
- *
- * client_key_exchange handshake type
- */
- public static final byte CLIENT_KEY_EXCHANGE = 16;
-
- /**
- *
- * finished handshake type
- */
- public static final byte FINISHED = 20;
-
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/HandshakeIODataStream.java b/crypto/src/main/java/org/conscrypt/HandshakeIODataStream.java
deleted file mode 100644
index 0723820..0000000
--- a/crypto/src/main/java/org/conscrypt/HandshakeIODataStream.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.security.MessageDigest;
-import java.util.Arrays;
-import java.util.Locale;
-import javax.net.ssl.SSLHandshakeException;
-
-/**
- * This class provides Input/Output data functionality
- * for handshake layer. It provides read and write operations
- * and accumulates all sent/received handshake's data.
- * This class can be presented as a combination of 2 data pipes.
- * The first data pipe is a pipe of income data: append method
- * places the data at the beginning of the pipe, and read methods
- * consume the data from the pipe. The second pipe is an outcoming
- * data pipe: write operations plases the data into the pipe,
- * and getData methods consume the data.
- * It is important to note that work with pipe cound not be
- * started if there is unconsumed data in another pipe. It is
- * reasoned by the following: handshake protocol performs read
- * and write operations consecuently. I.e. it first reads all
- * income data and only than produces the responce and places it
- * into the stream.
- * The read operations of the stream presented by the methods
- * of SSLInputStream which in its turn is an extension of InputStream.
- * So this stream can be used as an InputStream parameter for
- * certificate generation.
- * Also input stream functionality supports marks. The marks
- * help to reset the position of the stream in case of incompleate
- * handshake records. Note that in case of exhausting
- * of income data the EndOfBufferException is thown which implies
- * the following:
- * 1. the stream contains scrappy handshake record,
- * 2. the read position should be reseted to marked,
- * 3. and more income data is expected.
- * The throwing of the exception (instead of returning of -1 value
- * or incompleate filling of destination buffer)
- * helps to speed up the process of scrappy data recognition and
- * processing.
- * For more information about TLS handshake process see
- * TLS v 1 specification at http://www.ietf.org/rfc/rfc2246.txt.
- */
-public class HandshakeIODataStream
- extends SSLInputStream implements org.conscrypt.Appendable, DataStream {
-
- // Objects are used to compute digests of data passed
- // during the handshake phase
- private static final MessageDigest md5;
- private static final MessageDigest sha;
-
- static {
- try {
- md5 = MessageDigest.getInstance("MD5");
- sha = MessageDigest.getInstance("SHA-1");
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException(
- "Could not initialize the Digest Algorithms.");
- }
- }
-
- public HandshakeIODataStream() {}
-
- // buffer is used to keep the handshaking data;
- private int buff_size = 1024;
- private int inc_buff_size = 1024;
- private byte[] buffer = new byte[buff_size];
-
-
- // ---------------- Input related functionality -----------------
-
- // position of the next byte to read
- private int read_pos;
- private int marked_pos;
- // position of the last byte to read + 1
- private int read_pos_end;
-
- @Override
- public int available() {
- return read_pos_end - read_pos;
- }
-
- @Override
- public boolean markSupported() {
- return true;
- }
-
- @Override
- public void mark(int limit) {
- marked_pos = read_pos;
- }
-
- public void mark() {
- marked_pos = read_pos;
- }
-
- @Override
- public void reset() {
- read_pos = marked_pos;
- }
-
- /**
- * Removes the data from the marked position to
- * the current read position. The method is usefull when it is needed
- * to delete one message from the internal buffer.
- */
- protected void removeFromMarkedPosition() {
- System.arraycopy(buffer, read_pos,
- buffer, marked_pos, read_pos_end - read_pos);
- read_pos_end -= (read_pos - marked_pos);
- read_pos = marked_pos;
- }
-
- /**
- * read an opaque value;
- * @param byte: byte
- * @return
- */
- @Override
- public int read() throws IOException {
- if (read_pos == read_pos_end) {
- //return -1;
- throw new EndOfBufferException();
- }
- return buffer[read_pos++] & 0xFF;
- }
-
- /**
- * reads vector of opaque values
- * @param new: long
- * @return
- */
- @Override
- public byte[] read(int length) throws IOException {
- if (length > available()) {
- throw new EndOfBufferException();
- }
- byte[] res = new byte[length];
- System.arraycopy(buffer, read_pos, res, 0, length);
- read_pos = read_pos + length;
- return res;
- }
-
- @Override
- public int read(byte[] dst, int offset, int length) throws IOException {
- if (length > available()) {
- throw new EndOfBufferException();
- }
- System.arraycopy(buffer, read_pos, dst, offset, length);
- read_pos = read_pos + length;
- return length;
- }
-
- // ------------------- Extending of the input data ---------------------
-
- /**
- * Appends the income data to be read by handshake protocol.
- * The attempts to overflow the buffer by means of this methods
- * seem to be futile because of:
- * 1. The SSL protocol specifies the maximum size of the record
- * and record protocol does not pass huge messages.
- * (see TLS v1 specification http://www.ietf.org/rfc/rfc2246.txt ,
- * p 6.2)
- * 2. After each call of this method, handshake protocol should
- * start (and starts) the operations on received data and recognize
- * the fake data if such was provided (to check the size of certificate
- * for example).
- */
- public void append(byte[] src) {
- append(src, 0, src.length);
- }
-
- private void append(byte[] src, int from, int length) {
- if (read_pos == read_pos_end) {
- // start reading state after writing
- if (write_pos_beg != write_pos) {
- // error: outboud handshake data was not sent,
- // but inbound handshake data has been received.
- throw new AlertException(
- AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLHandshakeException(
- "Handshake message has been received before "
- + "the last oubound message had been sent."));
- }
- if (read_pos < write_pos) {
- read_pos = write_pos;
- read_pos_end = read_pos;
- }
- }
- if (read_pos_end + length > buff_size) {
- enlargeBuffer(read_pos_end+length-buff_size);
- }
- System.arraycopy(src, from, buffer, read_pos_end, length);
- read_pos_end += length;
- }
-
- private void enlargeBuffer(int size) {
- buff_size = (size < inc_buff_size)
- ? buff_size + inc_buff_size
- : buff_size + size;
- byte[] new_buff = new byte[buff_size];
- System.arraycopy(buffer, 0, new_buff, 0, buffer.length);
- buffer = new_buff;
- }
-
- protected void clearBuffer() {
- read_pos = 0;
- marked_pos = 0;
- read_pos_end = 0;
- write_pos = 0;
- write_pos_beg = 0;
- Arrays.fill(buffer, (byte) 0);
- }
-
- // ------------------- Output related functionality --------------------
-
- // position in the buffer available for write
- private int write_pos;
- // position in the buffer where the last write session has begun
- private int write_pos_beg;
-
- // checks if the data can be written in the buffer
- private void check(int length) {
- // (write_pos == write_pos_beg) iff:
- // 1. there were not write operations yet
- // 2. all written data was demanded by getData methods
- if (write_pos == write_pos_beg) {
- // just started to write after the reading
- if (read_pos != read_pos_end) {
- // error: attempt to write outbound data into the stream before
- // all the inbound handshake data had been read
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLHandshakeException("Data was not fully read: "
- + read_pos + " " + read_pos_end));
- }
- // set up the write positions
- if (write_pos_beg < read_pos_end) {
- write_pos_beg = read_pos_end;
- write_pos = write_pos_beg;
- }
- }
- // if there is not enought free space in the buffer - enlarge it:
- if (write_pos + length >= buff_size) {
- enlargeBuffer(length);
- }
- }
-
- /**
- * Writes an opaque value
- * @param byte: byte
- */
- public void write(byte b) {
- check(1);
- buffer[write_pos++] = b;
- }
-
- /**
- * Writes Uint8 value
- * @param long: the value to be written (last byte)
- */
- public void writeUint8(long n) {
- check(1);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * Writes Uint16 value
- * @param long: the value to be written (last 2 bytes)
- */
- public void writeUint16(long n) {
- check(2);
- buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * Writes Uint24 value
- * @param long: the value to be written (last 3 bytes)
- */
- public void writeUint24(long n) {
- check(3);
- buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
- buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * Writes Uint32 value
- * @param long: the value to be written (last 4 bytes)
- */
- public void writeUint32(long n) {
- check(4);
- buffer[write_pos++] = (byte) ((n & 0x00ff000000) >> 24);
- buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
- buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * Writes Uint64 value
- * @param long: the value to be written
- */
- public void writeUint64(long n) {
- check(8);
- buffer[write_pos++] = (byte) ((n & 0x00ff00000000000000L) >> 56);
- buffer[write_pos++] = (byte) ((n & 0x00ff000000000000L) >> 48);
- buffer[write_pos++] = (byte) ((n & 0x00ff0000000000L) >> 40);
- buffer[write_pos++] = (byte) ((n & 0x00ff00000000L) >> 32);
- buffer[write_pos++] = (byte) ((n & 0x00ff000000) >> 24);
- buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
- buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * writes vector of opaque values
- * @param vector the vector to be written
- */
- public void write(byte[] vector) {
- check(vector.length);
- System.arraycopy(vector, 0, buffer, write_pos, vector.length);
- write_pos += vector.length;
- }
-
- // ------------------- Retrieve the written bytes ----------------------
-
- public boolean hasData() {
- return (write_pos > write_pos_beg);
- }
-
- /**
- * returns the chunk of stored data with the length no more than specified.
- * @param length: int
- * @return
- */
- public byte[] getData(int length) {
- byte[] res;
- if (write_pos - write_pos_beg < length) {
- res = new byte[write_pos - write_pos_beg];
- System.arraycopy(buffer, write_pos_beg,
- res, 0, write_pos-write_pos_beg);
- write_pos_beg = write_pos;
- } else {
- res = new byte[length];
- System.arraycopy(buffer, write_pos_beg, res, 0, length);
- write_pos_beg += length;
- }
- return res;
- }
-
- // ---------------------- Message Digest Functionality ----------------
-
- /**
- * Returns the MD5 digest of the data passed throught the stream
- * @return MD5 digest
- */
- protected byte[] getDigestMD5() {
- synchronized (md5) {
- int len = (read_pos_end > write_pos)
- ? read_pos_end
- : write_pos;
- md5.update(buffer, 0, len);
- return md5.digest();
- }
- }
-
- /**
- * Returns the SHA-1 digest of the data passed throught the stream
- * @return SHA-1 digest
- */
- protected byte[] getDigestSHA() {
- synchronized (sha) {
- int len = (read_pos_end > write_pos)
- ? read_pos_end
- : write_pos;
- sha.update(buffer, 0, len);
- return sha.digest();
- }
- }
-
- /**
- * Returns the MD5 digest of the data passed throught the stream
- * except last message
- * @return MD5 digest
- */
- protected byte[] getDigestMD5withoutLast() {
- synchronized (md5) {
- md5.update(buffer, 0, marked_pos);
- return md5.digest();
- }
- }
-
- /**
- * Returns the SHA-1 digest of the data passed throught the stream
- * except last message
- * @return SHA-1 digest
- */
- protected byte[] getDigestSHAwithoutLast() {
- synchronized (sha) {
- sha.update(buffer, 0, marked_pos);
- return sha.digest();
- }
- }
-
- /**
- * Returns all the data passed throught the stream
- * @return all the data passed throught the stream at the moment
- */
- protected byte[] getMessages() {
- int len = (read_pos_end > write_pos) ? read_pos_end : write_pos;
- byte[] res = new byte[len];
- System.arraycopy(buffer, 0, res, 0, len);
- return res;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/HandshakeProtocol.java b/crypto/src/main/java/org/conscrypt/HandshakeProtocol.java
deleted file mode 100644
index 73d00ae..0000000
--- a/crypto/src/main/java/org/conscrypt/HandshakeProtocol.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.GeneralSecurityException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.interfaces.RSAKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.RSAPublicKeySpec;
-import java.util.Arrays;
-import java.util.Vector;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-
-/**
- * Base class for ClientHandshakeImpl and ServerHandshakeImpl classes.
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.
- * Handshake protocol</a>
- *
- */
-public abstract class HandshakeProtocol {
-
- /**
- * Handshake status NEED_UNWRAP - HandshakeProtocol needs to receive data
- */
- public static final int NEED_UNWRAP = 1;
-
- /**
- * Handshake status NOT_HANDSHAKING - is not currently handshaking
- */
- public static final int NOT_HANDSHAKING = 2;
-
- /**
- * Handshake status FINISHED - HandshakeProtocol has just finished
- */
- public static final int FINISHED = 3;
-
- /**
- * Handshake status NEED_TASK - HandshakeProtocol needs the results of delegated task
- */
- public static final int NEED_TASK = 4;
-
- /**
- * Current handshake status
- */
- protected int status = NOT_HANDSHAKING;
-
- /**
- * IO stream for income/outcome handshake data
- */
- protected HandshakeIODataStream io_stream = new HandshakeIODataStream();
-
- /**
- * SSL Record Protocol implementation.
- */
- protected SSLRecordProtocol recordProtocol;
-
- /**
- * SSLParametersImpl suplied by SSLSocket or SSLEngine
- */
- protected SSLParametersImpl parameters;
-
- /**
- * Delegated tasks for this handshake implementation
- */
- protected Vector<DelegatedTask> delegatedTasks = new Vector<DelegatedTask>();
-
- /**
- * Indicates non-blocking handshake
- */
- protected boolean nonBlocking;
-
- /**
- * Pending session
- */
- protected SSLSessionImpl session;
-
- /**
- * Sent and received handshake messages
- */
- protected ClientHello clientHello;
- protected ServerHello serverHello;
- protected CertificateMessage serverCert;
- protected ServerKeyExchange serverKeyExchange;
- protected CertificateRequest certificateRequest;
- protected ServerHelloDone serverHelloDone;
- protected CertificateMessage clientCert;
- protected ClientKeyExchange clientKeyExchange;
- protected CertificateVerify certificateVerify;
- protected Finished clientFinished;
- protected Finished serverFinished;
-
- /**
- * Indicates that change cipher spec message has been received
- */
- protected boolean changeCipherSpecReceived = false;
-
- /**
- * Indicates previous session resuming
- */
- protected boolean isResuming = false;
-
- /**
- * Premaster secret
- */
- protected byte[] preMasterSecret;
-
- /**
- * Exception occured in delegated task
- */
- protected Exception delegatedTaskErr;
-
- // reference verify_data used to verify finished message
- private byte[] verify_data = new byte[12];
-
- // Encoding of "master secret" string: "master secret".getBytes()
- private byte[] master_secret_bytes =
- {109, 97, 115, 116, 101, 114, 32, 115, 101, 99, 114, 101, 116 };
-
- // indicates whether protocol needs to send change cipher spec message
- private boolean needSendCCSpec = false;
-
- // indicates whether protocol needs to send change cipher spec message
- protected boolean needSendHelloRequest = false;
-
- /**
- * SSLEngine owning this HandshakeProtocol
- */
- public SSLEngineImpl engineOwner;
-
- /**
- * SSLSocket owning this HandshakeProtocol
- */
- public SSLSocketImpl socketOwner;
-
- /**
- * Creates HandshakeProtocol instance
- * @param owner
- */
- protected HandshakeProtocol(Object owner) {
- if (owner instanceof SSLEngineImpl) {
- engineOwner = (SSLEngineImpl) owner;
- nonBlocking = true;
- this.parameters = engineOwner.sslParameters;
- }
- else if (owner instanceof SSLSocketImpl) {
- socketOwner = (SSLSocketImpl) owner;
- nonBlocking = false;
- this.parameters = socketOwner.sslParameters;
- }
- }
-
- /**
- * Sets SSL Record Protocol
- * @param recordProtocol
- */
- public void setRecordProtocol(SSLRecordProtocol recordProtocol) {
- this.recordProtocol = recordProtocol;
- }
-
- /**
- * Start session negotiation
- */
- public abstract void start();
-
- /**
- * Stops the current session renegotiation process.
- * Such functionality is needed when it is session renegotiation
- * process and no_renegotiation alert message is received
- * from another peer.
- * @param session
- */
- protected void stop() {
- clearMessages();
- status = NOT_HANDSHAKING;
- }
-
- /**
- * Returns handshake status
- */
- public SSLEngineResult.HandshakeStatus getStatus() {
- if (io_stream.hasData() || needSendCCSpec ||
- needSendHelloRequest || delegatedTaskErr != null) {
- return SSLEngineResult.HandshakeStatus.NEED_WRAP;
- }
- if (!delegatedTasks.isEmpty()) {
- return SSLEngineResult.HandshakeStatus.NEED_TASK;
- }
-
- switch (status) {
- case HandshakeProtocol.NEED_UNWRAP:
- return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
- case HandshakeProtocol.FINISHED:
- status = NOT_HANDSHAKING;
- clearMessages();
- return SSLEngineResult.HandshakeStatus.FINISHED;
- default: // HandshakeProtocol.NOT_HANDSHAKING:
- return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
- }
- }
-
- /**
- * Returns pending session
- * @return session
- */
- public SSLSessionImpl getSession() {
- return session;
- }
-
- protected void sendChangeCipherSpec() {
- needSendCCSpec = true;
- }
-
- protected void sendHelloRequest() {
- needSendHelloRequest = true;
- }
-
- /**
- * Proceses inbound ChangeCipherSpec message
- */
- abstract void receiveChangeCipherSpec();
-
- /**
- * Creates and sends finished message
- */
- abstract void makeFinished();
-
- /**
- * Proceses inbound handshake messages
- * @param bytes
- */
- public abstract void unwrap(byte[] bytes);
-
- /**
- * Processes SSLv2 Hello message
- * @param bytes
- */
- public abstract void unwrapSSLv2(byte[] bytes);
-
- /**
- * Processes outbound handshake messages
- */
- public byte[] wrap() {
- if (delegatedTaskErr != null) {
- // process error occured in delegated task
- Exception e = delegatedTaskErr;
- delegatedTaskErr = null;
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Error occured in delegated task:" + e.getMessage(), e);
- }
- if (io_stream.hasData()) {
- return recordProtocol.wrap(ContentType.HANDSHAKE, io_stream);
- } else if (needSendCCSpec) {
- makeFinished();
- needSendCCSpec = false;
- return recordProtocol.getChangeCipherSpecMesage(getSession());
- } else if (needSendHelloRequest) {
- needSendHelloRequest = false;
- return recordProtocol.wrap(ContentType.HANDSHAKE,
- // hello request message
- // (see TLS v 1 specification:
- // http://www.ietf.org/rfc/rfc2246.txt)
- new byte[] {0, 0, 0, 0}, 0, 4);
- } else {
- return null; // nothing to send;
- }
- }
-
- /**
- * Sends fatal alert, breaks execution
- *
- * @param description
- */
- protected void sendWarningAlert(byte description) {
- recordProtocol.alert(AlertProtocol.WARNING, description);
- }
-
- /**
- * Sends fatal alert, breaks execution
- *
- * @param description
- * @param reason
- */
- protected void fatalAlert(byte description, String reason) {
- throw new AlertException(description, new SSLHandshakeException(reason));
- }
-
- /**
- * Sends fatal alert, breaks execution
- *
- * @param description
- * @param reason
- * @param cause
- */
- protected void fatalAlert(byte description, String reason, Exception cause) {
- throw new AlertException(description, new SSLException(reason, cause));
- }
-
- /**
- * Sends fatal alert, breaks execution
- *
- * @param description
- * @param cause
- */
- protected void fatalAlert(byte description, SSLException cause) {
- throw new AlertException(description, cause);
- }
-
- /**
- * Computers reference TLS verify_data that is used to verify finished message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS spec. 7.4.9. Finished</a>
- * @param label
- */
- protected void computerReferenceVerifyDataTLS(String label) {
- computerVerifyDataTLS(label, verify_data);
- }
-
- /**
- * Computer TLS verify_data
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS spec. 7.4.9. Finished</a>
- * @param label
- * @param buf
- */
- protected void computerVerifyDataTLS(String label, byte[] buf) {
- byte[] md5_digest = io_stream.getDigestMD5();
- byte[] sha_digest = io_stream.getDigestSHA();
-
- byte[] digest = new byte[md5_digest.length + sha_digest.length];
- System.arraycopy(md5_digest, 0, digest, 0, md5_digest.length);
- System.arraycopy(sha_digest, 0, digest, md5_digest.length,
- sha_digest.length);
- try {
- PRF.computePRF(buf, session.master_secret,
- label.getBytes(), digest);
- } catch (GeneralSecurityException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "PRF error", e);
- }
- }
-
- /**
- * Computer reference SSLv3 verify_data that is used to verify finished message
- * @see "SSLv3 spec. 7.6.9. Finished"
- * @param label
- */
- protected void computerReferenceVerifyDataSSLv3(byte[] sender) {
- verify_data = new byte[36];
- computerVerifyDataSSLv3(sender, verify_data);
- }
-
- /**
- * Computer SSLv3 verify_data
- * @see "SSLv3 spec. 7.6.9. Finished"
- * @param label
- * @param buf
- */
- protected void computerVerifyDataSSLv3(byte[] sender, byte[] buf) {
- MessageDigest md5;
- MessageDigest sha;
- try {
- md5 = MessageDigest.getInstance("MD5");
- sha = MessageDigest.getInstance("SHA-1");
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "Could not initialize the Digest Algorithms.",
- e);
- return;
- }
- try {
- byte[] handshake_messages = io_stream.getMessages();
- md5.update(handshake_messages);
- md5.update(sender);
- md5.update(session.master_secret);
- byte[] b = md5.digest(SSLv3Constants.MD5pad1);
- md5.update(session.master_secret);
- md5.update(SSLv3Constants.MD5pad2);
- System.arraycopy(md5.digest(b), 0, buf, 0, 16);
-
- sha.update(handshake_messages);
- sha.update(sender);
- sha.update(session.master_secret);
- b = sha.digest(SSLv3Constants.SHApad1);
- sha.update(session.master_secret);
- sha.update(SSLv3Constants.SHApad2);
- System.arraycopy(sha.digest(b), 0, buf, 16, 20);
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
-
- }
- }
-
- /**
- * Verifies finished data
- *
- * @param data
- * @param isServer
- */
- protected void verifyFinished(byte[] data) {
- if (!Arrays.equals(verify_data, data)) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Incorrect FINISED");
- }
- }
-
- /**
- * Sends fatal alert "UNEXPECTED MESSAGE"
- *
- */
- protected void unexpectedMessage() {
- fatalAlert(AlertProtocol.UNEXPECTED_MESSAGE, "UNEXPECTED MESSAGE");
- }
-
- /**
- * Writes message to HandshakeIODataStream
- *
- * @param message
- */
- public void send(Message message) {
- io_stream.writeUint8(message.getType());
- io_stream.writeUint24(message.length());
- message.send(io_stream);
- }
-
- /**
- * Computers master secret
- *
- */
- public void computerMasterSecret() {
- byte[] seed = new byte[64];
- System.arraycopy(clientHello.getRandom(), 0, seed, 0, 32);
- System.arraycopy(serverHello.getRandom(), 0, seed, 32, 32);
- session.master_secret = new byte[48];
- if (serverHello.server_version[1] == 1) { // TLSv1
- try {
- PRF.computePRF(session.master_secret, preMasterSecret,
- master_secret_bytes, seed);
- } catch (GeneralSecurityException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "PRF error", e);
- }
- } else { // SSL3.0
- PRF.computePRF_SSLv3(session.master_secret, preMasterSecret, seed);
- }
-
- //delete preMasterSecret from memory
- Arrays.fill(preMasterSecret, (byte)0);
- preMasterSecret = null;
- }
-
- /**
- * Returns a delegated task.
- * @return Delegated task or null
- */
- public Runnable getTask() {
- if (delegatedTasks.isEmpty()) {
- return null;
- }
- return delegatedTasks.remove(0);
- }
-
- /**
- * Clears previously sent and received handshake messages
- */
- protected void clearMessages() {
- io_stream.clearBuffer();
- clientHello = null;
- serverHello = null;
- serverCert = null;
- serverKeyExchange = null;
- certificateRequest = null;
- serverHelloDone = null;
- clientCert = null;
- clientKeyExchange = null;
- certificateVerify = null;
- clientFinished = null;
- serverFinished = null;
- }
-
- /**
- * Returns RSA key length
- * @param pk
- * @return
- * @throws NoSuchAlgorithmException
- * @throws InvalidKeySpecException
- */
- protected static int getRSAKeyLength(PublicKey pk)
- throws NoSuchAlgorithmException, InvalidKeySpecException {
-
- BigInteger mod;
- if (pk instanceof RSAKey) {
- mod = ((RSAKey) pk).getModulus();
- } else {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- mod = kf.getKeySpec(pk, RSAPublicKeySpec.class)
- .getModulus();
- }
- return mod.bitLength();
- }
-
- /**
- * Shuts down the protocol. It will be impossible to use the instance
- * after calling this method.
- */
- protected void shutdown() {
- clearMessages();
- session = null;
- preMasterSecret = null;
- delegatedTasks.clear();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/HelloRequest.java b/crypto/src/main/java/org/conscrypt/HelloRequest.java
deleted file mode 100644
index 20efbfd..0000000
--- a/crypto/src/main/java/org/conscrypt/HelloRequest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- *
- * Represents Hello Request message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.1.1.
- * Hello request</a>
- *
- */
-public class HelloRequest extends Message {
-
- /**
- * Creates outbound message
- *
- */
- public HelloRequest() {
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public HelloRequest(HandshakeIODataStream in, int length)
- throws IOException {
- if (length != 0) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect HelloRequest");
- }
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- }
-
- @Override
- public int length() {
- return 0;
- }
-
- /**
- * Returns message type
- * @return
- */
- @Override
- public int getType() {
- return Handshake.HELLO_REQUEST;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/JSSEProvider.java b/crypto/src/main/java/org/conscrypt/JSSEProvider.java
deleted file mode 100644
index ad56976..0000000
--- a/crypto/src/main/java/org/conscrypt/JSSEProvider.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.Provider;
-
-/**
- * JSSE Provider implementation.
- *
- * This implementation is based on TLS v 1.0 and SSL v3 protocol specifications.
- *
- * <ul>
- * <li><a href="http://www.ietf.org/rfc/rfc2246.txt">TLS v 1.0 Protocol
- * specification</a></li>
- * <li><a href="http://wp.netscape.com/eng/ssl3">SSL v3 Protocol
- * specification</a></li>
- * </ul>
- *
- * Provider implementation supports the following cipher suites:
- * TLS_NULL_WITH_NULL_NULL
- * TLS_RSA_WITH_NULL_MD5
- * TLS_RSA_WITH_NULL_SHA
- * TLS_RSA_EXPORT_WITH_RC4_40_MD5
- * TLS_RSA_WITH_RC4_128_MD5
- * TLS_RSA_WITH_RC4_128_SHA
- * TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
- * TLS_RSA_WITH_IDEA_CBC_SHA
- * TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
- * TLS_RSA_WITH_DES_CBC_SHA
- * TLS_RSA_WITH_3DES_EDE_CBC_SHA
- * TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DH_DSS_WITH_DES_CBC_SHA
- * TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
- * TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DH_RSA_WITH_DES_CBC_SHA
- * TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
- * TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DHE_DSS_WITH_DES_CBC_SHA
- * TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
- * TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DHE_RSA_WITH_DES_CBC_SHA
- * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- * TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
- * TLS_DH_anon_WITH_RC4_128_MD5
- * TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DH_anon_WITH_DES_CBC_SHA
- * TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
- *
- * The real set of available cipher suites depends on set of available
- * crypto algorithms. These algorithms must be provided by some crypto
- * provider.
- *
- * The following cipher algorithms are used by different cipher suites:
- * IDEA/CBC/NoPadding
- * RC2/CBC/NoPadding
- * RC4
- * DES/CBC/NoPadding
- * DES/CBC/NoPadding
- * DESede/CBC/NoPadding
- *
- * Also the current JSSE provider implementation uses the following
- * crypto algorithms:
- *
- * Algorithms that MUST be provided by crypto provider:
- * Mac HmacMD5
- * Mac HmacSHA1
- * MessageDigest MD5
- * MessageDigest SHA-1
- * CertificateFactory X509
- *
- * The cipher suites with RSA key exchange may also require:
- * Cipher RSA
- * KeyPairGenerator RSA
- * KeyFactory RSA
- *
- * The cipher suites with DH key exchange may also require:
- * Signature NONEwithDSA
- * KeyPairGenerator DiffieHellman or DH
- * KeyFactory DiffieHellman or DH
- * KeyAgreement DiffieHellman or DH
- * KeyPairGenerator DiffieHellman or DH
- *
- * Trust manager implementation requires:
- * CertPathValidator PKIX
- * CertificateFactory X509
- *
- */
-public final class JSSEProvider extends Provider {
-
- private static final long serialVersionUID = 3075686092260669675L;
-
- public JSSEProvider() {
- super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
-
- put("SSLContext.SSL", SSLContextImpl.class.getName());
- put("SSLContext.SSLv3", SSLContextImpl.class.getName());
- put("SSLContext.TLS", SSLContextImpl.class.getName());
- put("SSLContext.TLSv1", SSLContextImpl.class.getName());
-
- put("KeyManagerFactory.PKIX", KeyManagerFactoryImpl.class.getName());
- put("Alg.Alias.KeyManagerFactory.X509", "PKIX");
-
- put("TrustManagerFactory.PKIX", TrustManagerFactoryImpl.class.getName());
- put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
-
- put("KeyStore.AndroidCAStore", TrustedCertificateKeyStoreSpi.class.getName());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/KeyManagerFactoryImpl.java b/crypto/src/main/java/org/conscrypt/KeyManagerFactoryImpl.java
deleted file mode 100644
index 3ad9be9..0000000
--- a/crypto/src/main/java/org/conscrypt/KeyManagerFactoryImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactorySpi;
-import javax.net.ssl.ManagerFactoryParameters;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * KeyManagerFactory implementation.
- * @see KeyManagerFactorySpi
- */
-public class KeyManagerFactoryImpl extends KeyManagerFactorySpi {
-
- // source of key material
- private KeyStore keyStore;
-
- //password
- private char[] pwd;
-
- /**
- * @see KeyManagerFactorySpi#engineInit(KeyStore ks, char[] password)
- */
- @Override
- protected void engineInit(KeyStore ks, char[] password)
- throws KeyStoreException, NoSuchAlgorithmException,
- UnrecoverableKeyException {
- if (ks != null) {
- keyStore = ks;
- if (password != null) {
- pwd = password.clone();
- } else {
- pwd = EmptyArray.CHAR;
- }
- } else {
- keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- String keyStoreName = System.getProperty("javax.net.ssl.keyStore");
- String keyStorePwd = null;
- if (keyStoreName == null || keyStoreName.equalsIgnoreCase("NONE") || keyStoreName.isEmpty()) {
- try {
- keyStore.load(null, null);
- } catch (IOException e) {
- throw new KeyStoreException(e);
- } catch (CertificateException e) {
- throw new KeyStoreException(e);
- }
- } else {
- keyStorePwd = System.getProperty("javax.net.ssl.keyStorePassword");
- if (keyStorePwd == null) {
- pwd = EmptyArray.CHAR;
- } else {
- pwd = keyStorePwd.toCharArray();
- }
- try {
- keyStore.load(new FileInputStream(new File(keyStoreName)), pwd);
- } catch (FileNotFoundException e) {
- throw new KeyStoreException(e);
- } catch (IOException e) {
- throw new KeyStoreException(e);
- } catch (CertificateException e) {
- throw new KeyStoreException(e);
- }
- }
-
- }
-
- }
-
- /**
- * @see KeyManagerFactorySpi#engineInit(ManagerFactoryParameters spec)
- */
- @Override
- protected void engineInit(ManagerFactoryParameters spec)
- throws InvalidAlgorithmParameterException {
- throw new InvalidAlgorithmParameterException(
- "ManagerFactoryParameters not supported");
-
- }
-
- /**
- * @see KeyManagerFactorySpi#engineGetKeyManagers()
- */
- @Override
- protected KeyManager[] engineGetKeyManagers() {
- if (keyStore == null) {
- throw new IllegalStateException("KeyManagerFactory is not initialized");
- }
- return new KeyManager[] { new KeyManagerImpl(keyStore, pwd) };
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/KeyManagerImpl.java b/crypto/src/main/java/org/conscrypt/KeyManagerImpl.java
deleted file mode 100644
index 7a6c92c..0000000
--- a/crypto/src/main/java/org/conscrypt/KeyManagerImpl.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-import java.net.Socket;
-import java.security.KeyStore;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.UnrecoverableEntryException;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Locale;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * KeyManager implementation.
- *
- * This implementation uses hashed key store information. It works faster than retrieving all of the
- * data from the key store. Any key store changes, that happen after key manager was created, have
- * no effect. The implementation does not use peer information (host, port) that may be obtained
- * from socket or engine.
- *
- * @see javax.net.ssl.KeyManager
- *
- */
-public class KeyManagerImpl extends X509ExtendedKeyManager {
-
- // hashed key store information
- private final Hashtable<String, PrivateKeyEntry> hash;
-
- /**
- * Creates Key manager
- *
- * @param keyStore
- * @param pwd
- */
- public KeyManagerImpl(KeyStore keyStore, char[] pwd) {
- this.hash = new Hashtable<String, PrivateKeyEntry>();
- final Enumeration<String> aliases;
- try {
- aliases = keyStore.aliases();
- } catch (KeyStoreException e) {
- return;
- }
- for (; aliases.hasMoreElements();) {
- final String alias = aliases.nextElement();
- try {
- if (keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
- final KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore
- .getEntry(alias, new KeyStore.PasswordProtection(pwd));
- hash.put(alias, entry);
- }
- } catch (KeyStoreException e) {
- continue;
- } catch (UnrecoverableEntryException e) {
- continue;
- } catch (NoSuchAlgorithmException e) {
- continue;
- }
- }
- }
-
- public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) {
- final String[] al = chooseAlias(keyTypes, issuers);
- return (al == null ? null : al[0]);
- }
-
- public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
- final String[] al = chooseAlias(new String[] { keyType }, issuers);
- return (al == null ? null : al[0]);
- }
-
- public X509Certificate[] getCertificateChain(String alias) {
- if (alias == null) {
- return null;
- }
- if (hash.containsKey(alias)) {
- Certificate[] certs = hash.get(alias).getCertificateChain();
- if (certs[0] instanceof X509Certificate) {
- X509Certificate[] xcerts = new X509Certificate[certs.length];
- for (int i = 0; i < certs.length; i++) {
- xcerts[i] = (X509Certificate) certs[i];
- }
- return xcerts;
- }
- }
- return null;
-
- }
-
- public String[] getClientAliases(String keyType, Principal[] issuers) {
- return chooseAlias(new String[] { keyType }, issuers);
- }
-
- public String[] getServerAliases(String keyType, Principal[] issuers) {
- return chooseAlias(new String[] { keyType }, issuers);
- }
-
- public PrivateKey getPrivateKey(String alias) {
- if (alias == null) {
- return null;
- }
- if (hash.containsKey(alias)) {
- return hash.get(alias).getPrivateKey();
- }
- return null;
- }
-
- @Override
- public String chooseEngineClientAlias(String[] keyTypes, Principal[] issuers, SSLEngine engine) {
- final String[] al = chooseAlias(keyTypes, issuers);
- return (al == null ? null : al[0]);
- }
-
- @Override
- public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
- final String[] al = chooseAlias(new String[] { keyType }, issuers);
- return (al == null ? null : al[0]);
- }
-
- private String[] chooseAlias(String[] keyTypes, Principal[] issuers) {
- if (keyTypes == null || keyTypes.length == 0) {
- return null;
- }
- List<Principal> issuersList = (issuers == null) ? null : Arrays.asList(issuers);
- ArrayList<String> found = new ArrayList<String>();
- for (Enumeration<String> aliases = hash.keys(); aliases.hasMoreElements();) {
- final String alias = aliases.nextElement();
- final KeyStore.PrivateKeyEntry entry = hash.get(alias);
- final Certificate[] chain = entry.getCertificateChain();
- final Certificate cert = chain[0];
- final String certKeyAlg = cert.getPublicKey().getAlgorithm();
- final String certSigAlg = (cert instanceof X509Certificate
- ? ((X509Certificate) cert).getSigAlgName().toUpperCase(Locale.US)
- : null);
- for (String keyAlgorithm : keyTypes) {
- if (keyAlgorithm == null) {
- continue;
- }
- final String sigAlgorithm;
- // handle cases like EC_EC and EC_RSA
- int index = keyAlgorithm.indexOf('_');
- if (index == -1) {
- sigAlgorithm = null;
- } else {
- sigAlgorithm = keyAlgorithm.substring(index + 1);
- keyAlgorithm = keyAlgorithm.substring(0, index);
- }
- // key algorithm does not match
- if (!certKeyAlg.equals(keyAlgorithm)) {
- continue;
- }
- /*
- * TODO find a more reliable test for signature
- * algorithm. Unfortunately value varies with
- * provider. For example for "EC" it could be
- * "SHA1WithECDSA" or simply "ECDSA".
- */
- // sig algorithm does not match
- if (sigAlgorithm != null && certSigAlg != null
- && !certSigAlg.contains(sigAlgorithm)) {
- continue;
- }
- // no issuers to match, just add to return list and continue
- if (issuers == null || issuers.length == 0) {
- found.add(alias);
- continue;
- }
- // check that a certificate in the chain was issued by one of the specified issuers
- for (Certificate certFromChain : chain) {
- if (!(certFromChain instanceof X509Certificate)) {
- // skip non-X509Certificates
- continue;
- }
- X509Certificate xcertFromChain = (X509Certificate) certFromChain;
- /*
- * Note use of X500Principal from
- * getIssuerX500Principal as opposed to Principal
- * from getIssuerDN. Principal.equals test does
- * not work in the case where
- * xcertFromChain.getIssuerDN is a bouncycastle
- * org.bouncycastle.jce.X509Principal.
- */
- X500Principal issuerFromChain = xcertFromChain.getIssuerX500Principal();
- if (issuersList.contains(issuerFromChain)) {
- found.add(alias);
- }
- }
- }
- }
- if (!found.isEmpty()) {
- return found.toArray(new String[found.size()]);
- }
- return null;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/Logger.java b/crypto/src/main/java/org/conscrypt/Logger.java
deleted file mode 100644
index 9241c8a..0000000
--- a/crypto/src/main/java/org/conscrypt/Logger.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.PrintStream;
-import java.util.Locale;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * This class provides debug logging for JSSE provider implementation
- * TODO: Use java.util.logging
- */
-public class Logger {
-
- public static class Stream extends PrintStream {
- private final String prefix;
- private static int indent = 0;
-
- public Stream(String name) {
- super(System.err);
- prefix = name + "["+Thread.currentThread().getName()+"] ";
- }
-
- @Override
- public void print(String msg) {
- for (int i=0; i<indent; i++) {
- super.print(" ");
- }
- super.print(msg);
- }
-
- public void newIndent() {
- indent ++;
- }
-
- public void endIndent() {
- indent --;
- }
-
- @Override
- public void println(String msg) {
- print(prefix);
- super.println(msg);
- }
-
- public void print(byte[] data) {
- printAsHex(16, " ", "", data, 0, data.length);
- }
-
- public void print(byte[] data, int offset, int len) {
- printAsHex(16, " ", "", data, offset, len);
- }
-
- public void printAsHex(int perLine, String prefix, String delimiter, byte[] data) {
- printAsHex(perLine, prefix, delimiter, data, 0, data.length);
- }
-
- public void printAsHex(int perLine, String prefix, String delimiter,
- byte[] data, int offset, int len) {
- StringBuilder line = new StringBuilder();
- for (int i = 0; i < len; i++) {
- line.append(prefix);
- line.append(Byte.toHexString(data[i+offset], false));
- line.append(delimiter);
-
- if (((i+1)%perLine) == 0) {
- super.println(line.toString());
- line = new StringBuilder();
- }
- }
- super.println(line.toString());
- }
- }
-
- private static String[] names;
-
- static {
- try {
- names = System.getProperty("jsse", "").split(",");
- } catch (Exception e) {
- names = EmptyArray.STRING;
- }
- }
-
- public static Stream getStream(String name) {
- for (int i=0; i<names.length; i++) {
- if (names[i].equals(name)) {
- return new Stream(name);
- }
- }
- return null;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/Message.java b/crypto/src/main/java/org/conscrypt/Message.java
deleted file mode 100644
index 3b932d0..0000000
--- a/crypto/src/main/java/org/conscrypt/Message.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-
-/**
- *
- * Base class for handshake messages
- */
-public abstract class Message {
-
- /*
- * Message length
- */
- protected int length;
-
- /**
- * Returns message type
- */
- abstract int getType();
-
- /**
- * Returns message length
- */
- public int length() {
- return length;
- }
-
- /**
- * Sends message
- * @param out
- */
- abstract void send(HandshakeIODataStream out);
-
- /**
- * Sends fatal alert
- * @param description
- * @param reason
- */
- protected void fatalAlert(byte description, String reason) {
- throw new AlertException(description, new SSLHandshakeException(reason));
- }
-
- /**
- * Sends fatal alert
- * @param description
- * @param reason
- * @param cause
- */
- protected void fatalAlert(byte description, String reason, Throwable cause) {
- throw new AlertException(description, new SSLException(reason, cause));
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/NativeCrypto.java b/crypto/src/main/java/org/conscrypt/NativeCrypto.java
deleted file mode 100644
index f60e286..0000000
--- a/crypto/src/main/java/org/conscrypt/NativeCrypto.java
+++ /dev/null
@@ -1,1097 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.SocketTimeoutException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SignatureException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateParsingException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.net.ssl.SSLException;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * Provides the Java side of our JNI glue for OpenSSL.
- */
-public final class NativeCrypto {
-
- // --- OpenSSL library initialization --------------------------------------
- static {
- /*
- * If we're compiled as part of Android, should use a different JNI
- * library name. Detect this by looking for the jarjar'd package name.
- */
- if ("com.android.org.conscrypt".equals(NativeCrypto.class.getPackage().getName())) {
- System.loadLibrary("javacrypto");
- } else {
- System.loadLibrary("conscrypt_jni");
- }
-
- clinit();
- }
-
- private native static void clinit();
-
- // --- ENGINE functions ----------------------------------------------------
- public static native void ENGINE_load_dynamic();
-
- public static native long ENGINE_by_id(String id);
-
- public static native int ENGINE_add(long e);
-
- public static native int ENGINE_init(long e);
-
- public static native int ENGINE_finish(long e);
-
- public static native int ENGINE_free(long e);
-
- public static native long ENGINE_load_private_key(long e, String key_id);
-
- public static native String ENGINE_get_id(long engineRef);
-
- public static native int ENGINE_ctrl_cmd_string(long engineRef, String cmd, String arg,
- int cmd_optional);
-
- // --- DSA/RSA public/private key handling functions -----------------------
-
- public static native long EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
- byte[] pub_key, byte[] priv_key);
-
- public static native long EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q,
- byte[] dmp1, byte[] dmq1, byte[] iqmp);
-
- public static native long EVP_PKEY_new_mac_key(int type, byte[] key);
-
- public static native int EVP_PKEY_size(long pkey);
-
- public static native int EVP_PKEY_type(long pkey);
-
- public static native String EVP_PKEY_print_public(long pkeyRef);
-
- public static native String EVP_PKEY_print_private(long pkeyRef);
-
- public static native void EVP_PKEY_free(long pkey);
-
- public static native int EVP_PKEY_cmp(long pkey1, long pkey2);
-
- public static native byte[] i2d_PKCS8_PRIV_KEY_INFO(long pkey);
-
- public static native long d2i_PKCS8_PRIV_KEY_INFO(byte[] data);
-
- public static native byte[] i2d_PUBKEY(long pkey);
-
- public static native long d2i_PUBKEY(byte[] data);
-
- public static native long RSA_generate_key_ex(int modulusBits, byte[] publicExponent);
-
- public static native int RSA_size(long pkey);
-
- public static native int RSA_private_encrypt(int flen, byte[] from, byte[] to, long pkey,
- int padding);
-
- public static native int RSA_public_decrypt(int flen, byte[] from, byte[] to, long pkey,
- int padding) throws BadPaddingException, SignatureException;
-
- public static native int RSA_public_encrypt(int flen, byte[] from, byte[] to, long pkey,
- int padding);
-
- public static native int RSA_private_decrypt(int flen, byte[] from, byte[] to, long pkey,
- int padding) throws BadPaddingException, SignatureException;
-
- /**
- * @return array of {n, e}
- */
- public static native byte[][] get_RSA_public_params(long rsa);
-
- /**
- * @return array of {n, e, d, p, q, dmp1, dmq1, iqmp}
- */
- public static native byte[][] get_RSA_private_params(long rsa);
-
- public static native long DSA_generate_key(int primeBits, byte[] seed, byte[] g, byte[] p,
- byte[] q);
-
- /**
- * @return array of {g, p, q, y(pub), x(priv)}
- */
- public static native byte[][] get_DSA_params(long dsa);
-
- public static native byte[] i2d_RSAPublicKey(long rsa);
-
- public static native byte[] i2d_RSAPrivateKey(long rsa);
-
- public static native byte[] i2d_DSAPublicKey(long dsa);
-
- public static native byte[] i2d_DSAPrivateKey(long dsa);
-
- // --- EC functions --------------------------
-
- /**
- * Used to request EC_GROUP_new_curve_GFp to EC_GROUP_new_curve
- */
- public static final int EC_CURVE_GFP = 1;
-
- /**
- * Used to request EC_GROUP_new_curve_GF2m to EC_GROUP_new_curve
- */
- public static final int EC_CURVE_GF2M = 2;
-
- /**
- * EC_GROUP_set_asn1_flag: indicates an EC_GROUP is a NamedCurve.
- */
- public static final int OPENSSL_EC_NAMED_CURVE = 0x001;
-
- /**
- * EC_GROUP_set_point_conversion_form: indicates compressed ASN.1 format
- */
- public static final int POINT_CONVERSION_COMPRESSED = 2;
-
- /**
- * EC_GROUP_set_point_conversion_form: indicates uncompressed ASN.1 format
- */
- public static final int POINT_CONVERSION_UNCOMPRESSED = 4;
-
- /**
- * EC_GROUP_set_point_conversion_form: indicates hybrid ASN.1 format
- */
- public static final int POINT_CONVERSION_HYBRID = 4;
-
- public static native long EVP_PKEY_new_EC_KEY(long groupRef, long pubkeyRef, byte[] privkey);
-
- public static native long EC_GROUP_new_by_curve_name(String curveName);
-
- public static native long EC_GROUP_new_curve(int type, byte[] p, byte[] a, byte[] b);
-
- public static native long EC_GROUP_dup(long groupRef);
-
- public static native void EC_GROUP_set_asn1_flag(long groupRef, int flag);
-
- public static native void EC_GROUP_set_point_conversion_form(long groupRef, int form);
-
- public static native String EC_GROUP_get_curve_name(long groupRef);
-
- public static native byte[][] EC_GROUP_get_curve(long groupRef);
-
- public static native void EC_GROUP_clear_free(long ctx);
-
- public static native boolean EC_GROUP_cmp(long ctx1, long ctx2);
-
- public static native void EC_GROUP_set_generator(long groupCtx, long pointCtx, byte[] n, byte[] h);
-
- public static native long EC_GROUP_get_generator(long groupCtx);
-
- public static native int get_EC_GROUP_type(long groupCtx);
-
- public static native byte[] EC_GROUP_get_order(long groupCtx);
-
- public static native int EC_GROUP_get_degree(long groupCtx);
-
- public static native byte[] EC_GROUP_get_cofactor(long groupCtx);
-
- public static native long EC_POINT_new(long groupRef);
-
- public static native void EC_POINT_clear_free(long pointRef);
-
- public static native boolean EC_POINT_cmp(long groupRef, long pointRef1, long pointRef2);
-
- public static native byte[][] EC_POINT_get_affine_coordinates(long groupCtx, long pointCtx);
-
- public static native void EC_POINT_set_affine_coordinates(long groupCtx, long pointCtx, byte[] x,
- byte[] y);
-
- public static native long EC_KEY_generate_key(long groupRef);
-
- public static native long EC_KEY_get0_group(long pkeyRef);
-
- public static native byte[] EC_KEY_get_private_key(long keyRef);
-
- public static native long EC_KEY_get_public_key(long keyRef);
-
- public static native int ECDH_compute_key(
- byte[] out, int outOffset, long publicKeyRef, long privateKeyRef);
-
- // --- Message digest functions --------------
-
- public static native long EVP_get_digestbyname(String name);
-
- public static native int EVP_MD_size(long evp_md);
-
- public static native int EVP_MD_block_size(long evp_md);
-
- // --- Message digest context functions --------------
-
- public static native long EVP_MD_CTX_create();
-
- public static native void EVP_MD_CTX_init(long ctx);
-
- public static native void EVP_MD_CTX_destroy(long ctx);
-
- public static native long EVP_MD_CTX_copy(long ctx);
-
- // --- Digest handling functions -------------------------------------------
-
- public static native long EVP_DigestInit(long evp_md);
-
- public static native void EVP_DigestUpdate(long ctx, byte[] buffer, int offset, int length);
-
- public static native int EVP_DigestFinal(long ctx, byte[] hash, int offset);
-
- // --- MAC handling functions ----------------------------------------------
-
- public static native void EVP_DigestSignInit(long evp_md_ctx, long evp_md, long evp_pkey);
-
- public static native void EVP_DigestSignUpdate(long evp_md_ctx, byte[] in);
-
- public static native byte[] EVP_DigestSignFinal(long evp_md_ctx);
-
- // --- Signature handling functions ----------------------------------------
-
- public static native long EVP_SignInit(String algorithm);
-
- public static native void EVP_SignUpdate(long ctx, byte[] buffer,
- int offset, int length);
-
- public static native int EVP_SignFinal(long ctx, byte[] signature, int offset, long key);
-
- public static native long EVP_VerifyInit(String algorithm);
-
- public static native void EVP_VerifyUpdate(long ctx, byte[] buffer,
- int offset, int length);
-
- public static native int EVP_VerifyFinal(long ctx, byte[] signature,
- int offset, int length, long key);
-
-
- // --- Block ciphers -------------------------------------------------------
-
- public static native long EVP_get_cipherbyname(String string);
-
- public static native void EVP_CipherInit_ex(long ctx, long evpCipher, byte[] key, byte[] iv,
- boolean encrypting);
-
- public static native int EVP_CipherUpdate(long ctx, byte[] out, int outOffset, byte[] in,
- int inOffset, int inLength);
-
- public static native int EVP_CipherFinal_ex(long ctx, byte[] out, int outOffset)
- throws BadPaddingException, IllegalBlockSizeException;
-
- public static native int EVP_CIPHER_iv_length(long evpCipher);
-
- public static native long EVP_CIPHER_CTX_new();
-
- public static native int EVP_CIPHER_CTX_block_size(long ctx);
-
- public static native int get_EVP_CIPHER_CTX_buf_len(long ctx);
-
- public static native void EVP_CIPHER_CTX_set_padding(long ctx, boolean enablePadding);
-
- public static native void EVP_CIPHER_CTX_set_key_length(long ctx, int keyBitSize);
-
- public static native void EVP_CIPHER_CTX_cleanup(long ctx);
-
- // --- RAND seeding --------------------------------------------------------
-
- public static final int RAND_SEED_LENGTH_IN_BYTES = 1024;
-
- public static native void RAND_seed(byte[] seed);
-
- public static native int RAND_load_file(String filename, long max_bytes);
-
- public static native void RAND_bytes(byte[] output);
-
- // --- ASN.1 objects -------------------------------------------------------
-
- public static native int OBJ_txt2nid(String oid);
-
- public static native String OBJ_txt2nid_longName(String oid);
-
- public static native String OBJ_txt2nid_oid(String oid);
-
- // --- X509_NAME -----------------------------------------------------------
-
- public static int X509_NAME_hash(X500Principal principal) {
- return X509_NAME_hash(principal, "SHA1");
- }
- public static int X509_NAME_hash_old(X500Principal principal) {
- return X509_NAME_hash(principal, "MD5");
- }
- private static int X509_NAME_hash(X500Principal principal, String algorithm) {
- try {
- byte[] digest = MessageDigest.getInstance(algorithm).digest(principal.getEncoded());
- int offset = 0;
- return (((digest[offset++] & 0xff) << 0) |
- ((digest[offset++] & 0xff) << 8) |
- ((digest[offset++] & 0xff) << 16) |
- ((digest[offset ] & 0xff) << 24));
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
- }
-
- public static native String X509_NAME_print_ex(long x509nameCtx, long flags);
-
- // --- X509 ----------------------------------------------------------------
-
- /** Used to request get_X509_GENERAL_NAME_stack get the "altname" field. */
- public static final int GN_STACK_SUBJECT_ALT_NAME = 1;
-
- /**
- * Used to request get_X509_GENERAL_NAME_stack get the issuerAlternativeName
- * extension.
- */
- public static final int GN_STACK_ISSUER_ALT_NAME = 2;
-
- /**
- * Used to request only non-critical types in get_X509*_ext_oids.
- */
- public static final int EXTENSION_TYPE_NON_CRITICAL = 0;
-
- /**
- * Used to request only critical types in get_X509*_ext_oids.
- */
- public static final int EXTENSION_TYPE_CRITICAL = 1;
-
- public static native long d2i_X509_bio(long bioCtx);
-
- public static native long d2i_X509(byte[] encoded);
-
- public static native long PEM_read_bio_X509(long bioCtx);
-
- public static native byte[] i2d_X509(long x509ctx);
-
- /** Takes an X509 context not an X509_PUBKEY context. */
- public static native byte[] i2d_X509_PUBKEY(long x509ctx);
-
- public static native byte[] ASN1_seq_pack_X509(long[] x509CertRefs);
-
- public static native long[] ASN1_seq_unpack_X509_bio(long bioRef);
-
- public static native void X509_free(long x509ctx);
-
- public static native int X509_cmp(long x509ctx1, long x509ctx2);
-
- public static native int get_X509_hashCode(long x509ctx);
-
- public static native void X509_print_ex(long bioCtx, long x509ctx, long nmflag, long certflag);
-
- public static native byte[] X509_get_issuer_name(long x509ctx);
-
- public static native byte[] X509_get_subject_name(long x509ctx);
-
- public static native String get_X509_sig_alg_oid(long x509ctx);
-
- public static native byte[] get_X509_sig_alg_parameter(long x509ctx);
-
- public static native boolean[] get_X509_issuerUID(long x509ctx);
-
- public static native boolean[] get_X509_subjectUID(long x509ctx);
-
- public static native long X509_get_pubkey(long x509ctx) throws NoSuchAlgorithmException;
-
- public static native String get_X509_pubkey_oid(long x509ctx);
-
- public static native byte[] X509_get_ext_oid(long x509ctx, String oid);
-
- public static native String[] get_X509_ext_oids(long x509ctx, int critical);
-
- public static native Object[][] get_X509_GENERAL_NAME_stack(long x509ctx, int type)
- throws CertificateParsingException;
-
- public static native boolean[] get_X509_ex_kusage(long x509ctx);
-
- public static native String[] get_X509_ex_xkusage(long x509ctx);
-
- public static native int get_X509_ex_pathlen(long x509ctx);
-
- public static native long X509_get_notBefore(long x509ctx);
-
- public static native long X509_get_notAfter(long x509ctx);
-
- public static native long X509_get_version(long x509ctx);
-
- public static native byte[] X509_get_serialNumber(long x509ctx);
-
- public static native void X509_verify(long x509ctx, long pkeyCtx);
-
- public static native byte[] get_X509_cert_info_enc(long x509ctx);
-
- public static native byte[] get_X509_signature(long x509ctx);
-
- public static native int get_X509_ex_flags(long x509ctx);
-
- public static native int X509_check_issued(long ctx, long ctx2);
-
- // --- X509 EXFLAG ---------------------------------------------------------
-
- public static final int EXFLAG_CA = 0x10;
-
- public static final int EXFLAG_CRITICAL = 0x200;
-
- // --- PKCS7 ---------------------------------------------------------------
-
- /** Used as the "which" field in d2i_PKCS7_bio and PEM_read_bio_PKCS7. */
- public static final int PKCS7_CERTS = 1;
-
- /** Used as the "which" field in d2i_PKCS7_bio and PEM_read_bio_PKCS7. */
- public static final int PKCS7_CRLS = 2;
-
- /** Returns an array of X509 or X509_CRL pointers. */
- public static native long[] d2i_PKCS7_bio(long bioCtx, int which);
-
- /** Returns an array of X509 or X509_CRL pointers. */
- public static native byte[] i2d_PKCS7(long[] certs);
-
- /** Returns an array of X509 or X509_CRL pointers. */
- public static native long[] PEM_read_bio_PKCS7(long bioCtx, int which);
-
- // --- X509_CRL ------------------------------------------------------------
-
- public static native long d2i_X509_CRL_bio(long bioCtx);
-
- public static native long PEM_read_bio_X509_CRL(long bioCtx);
-
- public static native byte[] i2d_X509_CRL(long x509CrlCtx);
-
- public static native void X509_CRL_free(long x509CrlCtx);
-
- public static native void X509_CRL_print(long bioCtx, long x509CrlCtx);
-
- public static native String get_X509_CRL_sig_alg_oid(long x509CrlCtx);
-
- public static native byte[] get_X509_CRL_sig_alg_parameter(long x509CrlCtx);
-
- public static native byte[] X509_CRL_get_issuer_name(long x509CrlCtx);
-
- /** Returns X509_REVOKED reference that is not duplicated! */
- public static native long X509_CRL_get0_by_cert(long x509CrlCtx, long x509Ctx);
-
- /** Returns X509_REVOKED reference that is not duplicated! */
- public static native long X509_CRL_get0_by_serial(long x509CrlCtx, byte[] serial);
-
- /** Returns an array of X509_REVOKED that are owned by the caller. */
- public static native long[] X509_CRL_get_REVOKED(long x509CrlCtx);
-
- public static native String[] get_X509_CRL_ext_oids(long x509ctx, int critical);
-
- public static native byte[] X509_CRL_get_ext_oid(long x509CrlCtx, String oid);
-
- public static native long X509_CRL_get_version(long x509CrlCtx);
-
- public static native long X509_CRL_get_ext(long x509CrlCtx, String oid);
-
- public static native byte[] get_X509_CRL_signature(long x509ctx);
-
- public static native void X509_CRL_verify(long x509CrlCtx, long pkeyCtx);
-
- public static native byte[] get_X509_CRL_crl_enc(long x509CrlCtx);
-
- public static native long X509_CRL_get_lastUpdate(long x509CrlCtx);
-
- public static native long X509_CRL_get_nextUpdate(long x509CrlCtx);
-
- // --- X509_REVOKED --------------------------------------------------------
-
- public static native long X509_REVOKED_dup(long x509RevokedCtx);
-
- public static native byte[] i2d_X509_REVOKED(long x509RevokedCtx);
-
- public static native String[] get_X509_REVOKED_ext_oids(long x509ctx, int critical);
-
- public static native byte[] X509_REVOKED_get_ext_oid(long x509RevokedCtx, String oid);
-
- public static native byte[] X509_REVOKED_get_serialNumber(long x509RevokedCtx);
-
- public static native long X509_REVOKED_get_ext(long x509RevokedCtx, String oid);
-
- /** Returns ASN1_TIME reference. */
- public static native long get_X509_REVOKED_revocationDate(long x509RevokedCtx);
-
- public static native void X509_REVOKED_print(long bioRef, long x509RevokedCtx);
-
- // --- X509_EXTENSION ------------------------------------------------------
-
- public static native int X509_supported_extension(long x509ExtensionRef);
-
- // --- ASN1_TIME -----------------------------------------------------------
-
- public static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal);
-
- // --- BIO stream creation -------------------------------------------------
-
- public static native long create_BIO_InputStream(OpenSSLBIOInputStream is);
-
- public static native long create_BIO_OutputStream(OutputStream os);
-
- public static native int BIO_read(long bioRef, byte[] buffer);
-
- public static native void BIO_write(long bioRef, byte[] buffer, int offset, int length)
- throws IOException;
-
- public static native void BIO_free(long bioRef);
-
- // --- SSL handling --------------------------------------------------------
-
- private static final String SUPPORTED_PROTOCOL_SSLV3 = "SSLv3";
- private static final String SUPPORTED_PROTOCOL_TLSV1 = "TLSv1";
- private static final String SUPPORTED_PROTOCOL_TLSV1_1 = "TLSv1.1";
- private static final String SUPPORTED_PROTOCOL_TLSV1_2 = "TLSv1.2";
-
- public static final Map<String, String> OPENSSL_TO_STANDARD_CIPHER_SUITES
- = new HashMap<String, String>();
- public static final Map<String, String> STANDARD_TO_OPENSSL_CIPHER_SUITES
- = new LinkedHashMap<String, String>();
-
- private static void add(String standard, String openssl) {
- OPENSSL_TO_STANDARD_CIPHER_SUITES.put(openssl, standard);
- STANDARD_TO_OPENSSL_CIPHER_SUITES.put(standard, openssl);
- }
-
- /**
- * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is RFC 5746's renegotiation
- * indication signaling cipher suite value. It is not a real
- * cipher suite. It is just an indication in the default and
- * supported cipher suite lists indicates that the implementation
- * supports secure renegotiation.
- *
- * In the RI, its presence means that the SCSV is sent in the
- * cipher suite list to indicate secure renegotiation support and
- * its absense means to send an empty TLS renegotiation info
- * extension instead.
- *
- * However, OpenSSL doesn't provide an API to give this level of
- * control, instead always sending the SCSV and always including
- * the empty renegotiation info if TLS is used (as opposed to
- * SSL). So we simply allow TLS_EMPTY_RENEGOTIATION_INFO_SCSV to
- * be passed for compatibility as to provide the hint that we
- * support secure renegotiation.
- */
- public static final String TLS_EMPTY_RENEGOTIATION_INFO_SCSV
- = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
-
- /**
- * TLS_FALLBACK_SCSV is from
- * https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
- * to indicate to the server that this is a fallback protocol
- * request.
- */
- public static final String TLS_FALLBACK_SCSV = "TLS_FALLBACK_SCSV";
-
- static {
- // Note these are added in priority order
- add("SSL_RSA_WITH_RC4_128_MD5", "RC4-MD5");
- add("SSL_RSA_WITH_RC4_128_SHA", "RC4-SHA");
- add("TLS_RSA_WITH_AES_128_CBC_SHA", "AES128-SHA");
- add("TLS_RSA_WITH_AES_256_CBC_SHA", "AES256-SHA");
- add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "ECDH-ECDSA-RC4-SHA");
- add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "ECDH-ECDSA-AES128-SHA");
- add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "ECDH-ECDSA-AES256-SHA");
- add("TLS_ECDH_RSA_WITH_RC4_128_SHA", "ECDH-RSA-RC4-SHA");
- add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "ECDH-RSA-AES128-SHA");
- add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "ECDH-RSA-AES256-SHA");
- add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "ECDHE-ECDSA-RC4-SHA");
- add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDHE-ECDSA-AES128-SHA");
- add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDHE-ECDSA-AES256-SHA");
- add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", "ECDHE-RSA-RC4-SHA");
- add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "ECDHE-RSA-AES128-SHA");
- add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "ECDHE-RSA-AES256-SHA");
- add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "DHE-RSA-AES128-SHA");
- add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "DHE-RSA-AES256-SHA");
- add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "DHE-DSS-AES128-SHA");
- add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "DHE-DSS-AES256-SHA");
- add("SSL_RSA_WITH_3DES_EDE_CBC_SHA", "DES-CBC3-SHA");
- add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDH-ECDSA-DES-CBC3-SHA");
- add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "ECDH-RSA-DES-CBC3-SHA");
- add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-ECDSA-DES-CBC3-SHA");
- add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-RSA-DES-CBC3-SHA");
- add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "EDH-RSA-DES-CBC3-SHA");
- add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "EDH-DSS-DES-CBC3-SHA");
- add("SSL_RSA_WITH_DES_CBC_SHA", "DES-CBC-SHA");
- add("SSL_DHE_RSA_WITH_DES_CBC_SHA", "EDH-RSA-DES-CBC-SHA");
- add("SSL_DHE_DSS_WITH_DES_CBC_SHA", "EDH-DSS-DES-CBC-SHA");
- add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", "EXP-RC4-MD5");
- add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-DES-CBC-SHA");
- add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-RSA-DES-CBC-SHA");
- add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-DSS-DES-CBC-SHA");
- add("SSL_RSA_WITH_NULL_MD5", "NULL-MD5");
- add("SSL_RSA_WITH_NULL_SHA", "NULL-SHA");
- add("TLS_ECDH_ECDSA_WITH_NULL_SHA", "ECDH-ECDSA-NULL-SHA");
- add("TLS_ECDH_RSA_WITH_NULL_SHA", "ECDH-RSA-NULL-SHA");
- add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", "ECDHE-ECDSA-NULL-SHA");
- add("TLS_ECDHE_RSA_WITH_NULL_SHA", "ECDHE-RSA-NULL-SHA");
- add("SSL_DH_anon_WITH_RC4_128_MD5", "ADH-RC4-MD5");
- add("TLS_DH_anon_WITH_AES_128_CBC_SHA", "ADH-AES128-SHA");
- add("TLS_DH_anon_WITH_AES_256_CBC_SHA", "ADH-AES256-SHA");
- add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", "ADH-DES-CBC3-SHA");
- add("SSL_DH_anon_WITH_DES_CBC_SHA", "ADH-DES-CBC-SHA");
- add("TLS_ECDH_anon_WITH_RC4_128_SHA", "AECDH-RC4-SHA");
- add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", "AECDH-AES128-SHA");
- add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", "AECDH-AES256-SHA");
- add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", "AECDH-DES-CBC3-SHA");
- add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", "EXP-ADH-RC4-MD5");
- add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", "EXP-ADH-DES-CBC-SHA");
- add("TLS_ECDH_anon_WITH_NULL_SHA", "AECDH-NULL-SHA");
-
- // No Kerberos in Android
- // add("TLS_KRB5_WITH_RC4_128_SHA", "KRB5-RC4-SHA");
- // add("TLS_KRB5_WITH_RC4_128_MD5", "KRB5-RC4-MD5");
- // add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", "KRB5-DES-CBC3-SHA");
- // add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", "KRB5-DES-CBC3-MD5");
- // add("TLS_KRB5_WITH_DES_CBC_SHA", "KRB5-DES-CBC-SHA");
- // add("TLS_KRB5_WITH_DES_CBC_MD5", "KRB5-DES-CBC-MD5");
- // add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", "EXP-KRB5-RC4-SHA");
- // add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "EXP-KRB5-RC4-MD5");
- // add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "EXP-KRB5-DES-CBC-SHA");
- // add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", "EXP-KRB5-DES-CBC-MD5");
-
- // not implemented by either RI or OpenSSL
- // add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", null);
- // add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", null);
-
- // EXPORT1024 suites were never standardized but were widely implemented.
- // OpenSSL 0.9.8c and later have disabled TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES
- // add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", "EXP1024-DES-CBC-SHA");
- // add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", "EXP1024-RC4-SHA");
-
- // No RC2
- // add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-RC2-CBC-MD5");
- // add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", "EXP-KRB5-RC2-CBC-SHA");
- // add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-KRB5-RC2-CBC-MD5");
-
- // PSK is Private Shared Key - didn't exist in Froyo's openssl - no JSSE equivalent
- // add(null, "PSK-3DES-EDE-CBC-SHA");
- // add(null, "PSK-AES128-CBC-SHA");
- // add(null, "PSK-AES256-CBC-SHA");
- // add(null, "PSK-RC4-SHA");
-
- // Signaling Cipher Suite Value for secure renegotiation handled as special case.
- // add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV", null);
-
- // Similarly, the fallback SCSV is handled as a special case.
- // add("TLS_FALLBACK_SCSV", null);
- }
-
- private static final String[] SUPPORTED_CIPHER_SUITES;
- static {
- int size = STANDARD_TO_OPENSSL_CIPHER_SUITES.size();
- SUPPORTED_CIPHER_SUITES = new String[size + 2];
- STANDARD_TO_OPENSSL_CIPHER_SUITES.keySet().toArray(SUPPORTED_CIPHER_SUITES);
- SUPPORTED_CIPHER_SUITES[size] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
- SUPPORTED_CIPHER_SUITES[size + 1] = TLS_FALLBACK_SCSV;
- }
-
- // EVP_PKEY types from evp.h and objects.h
- public static final int EVP_PKEY_RSA = 6; // NID_rsaEcnryption
- public static final int EVP_PKEY_DSA = 116; // NID_dsa
- public static final int EVP_PKEY_DH = 28; // NID_dhKeyAgreement
- public static final int EVP_PKEY_EC = 408; // NID_X9_62_id_ecPublicKey
- public static final int EVP_PKEY_HMAC = 855; // NID_hmac
- public static final int EVP_PKEY_CMAC = 894; // NID_cmac
-
- // RSA padding modes from rsa.h
- public static final int RSA_PKCS1_PADDING = 1;
- public static final int RSA_NO_PADDING = 3;
-
- // SSL mode from ssl.h
- public static final long SSL_MODE_HANDSHAKE_CUTTHROUGH = 0x00000020L;
- public static final long SSL_MODE_SEND_FALLBACK_SCSV = 0x00000200L;
-
- // SSL options from ssl.h
- public static final long SSL_OP_NO_TICKET = 0x00004000L;
- public static final long SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00010000L;
- public static final long SSL_OP_NO_SSLv3 = 0x02000000L;
- public static final long SSL_OP_NO_TLSv1 = 0x04000000L;
- public static final long SSL_OP_NO_TLSv1_1 = 0x10000000L;
- public static final long SSL_OP_NO_TLSv1_2 = 0x08000000L;
-
- public static native long SSL_CTX_new();
-
- public static String[] getDefaultCipherSuites() {
- return new String[] {
- "SSL_RSA_WITH_RC4_128_MD5",
- "SSL_RSA_WITH_RC4_128_SHA",
- "TLS_RSA_WITH_AES_128_CBC_SHA",
- "TLS_RSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
- "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDH_RSA_WITH_RC4_128_SHA",
- "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
- "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
- "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
- "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
- "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
- "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
- "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
- "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
- "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
- "SSL_RSA_WITH_DES_CBC_SHA",
- "SSL_DHE_RSA_WITH_DES_CBC_SHA",
- "SSL_DHE_DSS_WITH_DES_CBC_SHA",
- "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
- "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
- "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
- "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
- TLS_EMPTY_RENEGOTIATION_INFO_SCSV
- };
- }
-
- public static String[] getSupportedCipherSuites() {
- return SUPPORTED_CIPHER_SUITES.clone();
- }
-
- public static native void SSL_CTX_free(long ssl_ctx);
-
- public static native void SSL_CTX_set_session_id_context(long ssl_ctx, byte[] sid_ctx);
-
- public static native long SSL_new(long ssl_ctx) throws SSLException;
-
- public static native void SSL_enable_tls_channel_id(long ssl) throws SSLException;
-
- public static native byte[] SSL_get_tls_channel_id(long ssl) throws SSLException;
-
- public static native void SSL_set1_tls_channel_id(long ssl, long pkey);
-
- public static byte[][] encodeCertificates(Certificate[] certificates)
- throws CertificateEncodingException {
- byte[][] certificateBytes = new byte[certificates.length][];
- for (int i = 0; i < certificates.length; i++) {
- certificateBytes[i] = certificates[i].getEncoded();
- }
- return certificateBytes;
- }
-
- public static native void SSL_use_certificate(long ssl, byte[][] asn1DerEncodedCertificateChain);
-
- public static native void SSL_use_PrivateKey(long ssl, long pkey);
-
- public static native void SSL_check_private_key(long ssl) throws SSLException;
-
- public static native void SSL_set_client_CA_list(long ssl, byte[][] asn1DerEncodedX500Principals);
-
- public static native long SSL_get_mode(long ssl);
-
- public static native long SSL_set_mode(long ssl, long mode);
-
- public static native long SSL_clear_mode(long ssl, long mode);
-
- public static native long SSL_get_options(long ssl);
-
- public static native long SSL_set_options(long ssl, long options);
-
- public static native long SSL_clear_options(long ssl, long options);
-
- public static String[] getDefaultProtocols() {
- return new String[] { SUPPORTED_PROTOCOL_SSLV3,
- SUPPORTED_PROTOCOL_TLSV1,
- };
- }
-
- public static String[] getSupportedProtocols() {
- return new String[] { SUPPORTED_PROTOCOL_SSLV3,
- SUPPORTED_PROTOCOL_TLSV1,
- SUPPORTED_PROTOCOL_TLSV1_1,
- SUPPORTED_PROTOCOL_TLSV1_2,
- };
- }
-
- public static void setEnabledProtocols(long ssl, String[] protocols) {
- checkEnabledProtocols(protocols);
- // openssl uses negative logic letting you disable protocols.
- // so first, assume we need to set all (disable all) and clear none (enable none).
- // in the loop, selectively move bits from set to clear (from disable to enable)
- long optionsToSet = (SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
- long optionsToClear = 0;
- for (int i = 0; i < protocols.length; i++) {
- String protocol = protocols[i];
- if (protocol.equals(SUPPORTED_PROTOCOL_SSLV3)) {
- optionsToSet &= ~SSL_OP_NO_SSLv3;
- optionsToClear |= SSL_OP_NO_SSLv3;
- } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1)) {
- optionsToSet &= ~SSL_OP_NO_TLSv1;
- optionsToClear |= SSL_OP_NO_TLSv1;
- } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1)) {
- optionsToSet &= ~SSL_OP_NO_TLSv1_1;
- optionsToClear |= SSL_OP_NO_TLSv1_1;
- } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2)) {
- optionsToSet &= ~SSL_OP_NO_TLSv1_2;
- optionsToClear |= SSL_OP_NO_TLSv1_2;
- } else {
- // error checked by checkEnabledProtocols
- throw new IllegalStateException();
- }
- }
-
- SSL_set_options(ssl, optionsToSet);
- SSL_clear_options(ssl, optionsToClear);
- }
-
- public static String[] checkEnabledProtocols(String[] protocols) {
- if (protocols == null) {
- throw new IllegalArgumentException("protocols == null");
- }
- for (int i = 0; i < protocols.length; i++) {
- String protocol = protocols[i];
- if (protocol == null) {
- throw new IllegalArgumentException("protocols[" + i + "] == null");
- }
- if ((!protocol.equals(SUPPORTED_PROTOCOL_SSLV3))
- && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1))
- && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1))
- && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2))) {
- throw new IllegalArgumentException("protocol " + protocol
- + " is not supported");
- }
- }
- return protocols;
- }
-
- public static native void SSL_set_cipher_lists(long ssl, String[] ciphers);
-
- public static void setEnabledCipherSuites(long ssl, String[] cipherSuites) {
- checkEnabledCipherSuites(cipherSuites);
- List<String> opensslSuites = new ArrayList<String>();
- for (int i = 0; i < cipherSuites.length; i++) {
- String cipherSuite = cipherSuites[i];
- if (cipherSuite.equals(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
- continue;
- }
- if (cipherSuite.equals(TLS_FALLBACK_SCSV)) {
- SSL_set_mode(ssl, SSL_MODE_SEND_FALLBACK_SCSV);
- continue;
- }
- String openssl = STANDARD_TO_OPENSSL_CIPHER_SUITES.get(cipherSuite);
- String cs = (openssl == null) ? cipherSuite : openssl;
- opensslSuites.add(cs);
- }
- SSL_set_cipher_lists(ssl, opensslSuites.toArray(new String[opensslSuites.size()]));
- }
-
- public static String[] checkEnabledCipherSuites(String[] cipherSuites) {
- if (cipherSuites == null) {
- throw new IllegalArgumentException("cipherSuites == null");
- }
- // makes sure all suites are valid, throwing on error
- for (int i = 0; i < cipherSuites.length; i++) {
- String cipherSuite = cipherSuites[i];
- if (cipherSuite == null) {
- throw new IllegalArgumentException("cipherSuites[" + i + "] == null");
- }
- if (cipherSuite.equals(TLS_EMPTY_RENEGOTIATION_INFO_SCSV) ||
- cipherSuite.equals(TLS_FALLBACK_SCSV)) {
- continue;
- }
- if (STANDARD_TO_OPENSSL_CIPHER_SUITES.containsKey(cipherSuite)) {
- continue;
- }
- if (OPENSSL_TO_STANDARD_CIPHER_SUITES.containsKey(cipherSuite)) {
- // TODO log warning about using backward compatability
- continue;
- }
- throw new IllegalArgumentException("cipherSuite " + cipherSuite + " is not supported.");
- }
- return cipherSuites;
- }
-
- /*
- * See the OpenSSL ssl.h header file for more information.
- */
- public static final int SSL_VERIFY_NONE = 0x00;
- public static final int SSL_VERIFY_PEER = 0x01;
- public static final int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 0x02;
-
- public static native void SSL_set_verify(long sslNativePointer, int mode);
-
- public static native void SSL_set_session(long sslNativePointer, long sslSessionNativePointer)
- throws SSLException;
-
- public static native void SSL_set_session_creation_enabled(
- long sslNativePointer, boolean creationEnabled) throws SSLException;
-
- public static native void SSL_set_tlsext_host_name(long sslNativePointer, String hostname)
- throws SSLException;
- public static native String SSL_get_servername(long sslNativePointer);
-
- /**
- * Enables NPN for all SSL connections in the context.
- *
- * <p>For clients this causes the NPN extension to be included in the
- * ClientHello message.
- *
- * <p>For servers this causes the NPN extension to be included in the
- * ServerHello message. The NPN extension will not be included in the
- * ServerHello response if the client didn't include it in the ClientHello
- * request.
- *
- * <p>In either case the caller should pass a non-null byte array of NPN
- * protocols to {@link #SSL_do_handshake}.
- */
- public static native void SSL_CTX_enable_npn(long sslCtxNativePointer);
-
- /**
- * Disables NPN for all SSL connections in the context.
- */
- public static native void SSL_CTX_disable_npn(long sslCtxNativePointer);
-
- /**
- * For clients, sets the list of supported ALPN protocols in wire-format
- * (length-prefixed 8-bit strings) on an SSL context.
- */
- public static native int SSL_CTX_set_alpn_protos(long sslCtxPointer, byte[] protos);
-
- /**
- * Returns the selected ALPN protocol. If the server did not select a
- * protocol, {@code null} will be returned.
- */
- public static native byte[] SSL_get0_alpn_selected(long sslPointer);
-
- /**
- * Returns the sslSessionNativePointer of the negotiated session. If this is
- * a server negotiation, supplying the {@code alpnProtocols} will enable
- * ALPN negotiation.
- */
- public static native int SSL_do_handshake(long sslNativePointer,
- FileDescriptor fd,
- SSLHandshakeCallbacks shc,
- int timeoutMillis,
- boolean client_mode,
- byte[] npnProtocols,
- byte[] alpnProtocols)
- throws SSLException, SocketTimeoutException, CertificateException;
-
- public static native byte[] SSL_get_npn_negotiated_protocol(long sslNativePointer);
-
- /**
- * Currently only intended for forcing renegotiation for testing.
- * Not used within OpenSSLSocketImpl.
- */
- public static native void SSL_renegotiate(long sslNativePointer) throws SSLException;
-
- /**
- * Returns the local ASN.1 DER encoded X509 certificates.
- */
- public static native byte[][] SSL_get_certificate(long sslNativePointer);
-
- /**
- * Returns the peer ASN.1 DER encoded X509 certificates.
- */
- public static native byte[][] SSL_get_peer_cert_chain(long sslNativePointer);
-
- /**
- * Reads with the native SSL_read function from the encrypted data stream
- * @return -1 if error or the end of the stream is reached.
- */
- public static native int SSL_read(long sslNativePointer,
- FileDescriptor fd,
- SSLHandshakeCallbacks shc,
- byte[] b, int off, int len, int readTimeoutMillis)
- throws IOException;
-
- /**
- * Writes with the native SSL_write function to the encrypted data stream.
- */
- public static native void SSL_write(long sslNativePointer,
- FileDescriptor fd,
- SSLHandshakeCallbacks shc,
- byte[] b, int off, int len, int writeTimeoutMillis)
- throws IOException;
-
- public static native void SSL_interrupt(long sslNativePointer);
- public static native void SSL_shutdown(long sslNativePointer,
- FileDescriptor fd,
- SSLHandshakeCallbacks shc) throws IOException;
-
- public static native void SSL_free(long sslNativePointer);
-
- public static native byte[] SSL_SESSION_session_id(long sslSessionNativePointer);
-
- public static native long SSL_SESSION_get_time(long sslSessionNativePointer);
-
- public static native String SSL_SESSION_get_version(long sslSessionNativePointer);
-
- public static native String SSL_SESSION_cipher(long sslSessionNativePointer);
-
- public static native void SSL_SESSION_free(long sslSessionNativePointer);
-
- public static native byte[] i2d_SSL_SESSION(long sslSessionNativePointer);
-
- public static native long d2i_SSL_SESSION(byte[] data);
-
- /**
- * A collection of callbacks from the native OpenSSL code that are
- * related to the SSL handshake initiated by SSL_do_handshake.
- */
- public interface SSLHandshakeCallbacks {
- /**
- * Verify that we trust the certificate chain is trusted.
- *
- * @param asn1DerEncodedCertificateChain A chain of ASN.1 DER encoded certificates
- * @param authMethod auth algorithm name
- *
- * @throws CertificateException if the certificate is untrusted
- */
- public void verifyCertificateChain(byte[][] asn1DerEncodedCertificateChain, String authMethod)
- throws CertificateException;
-
- /**
- * Called on an SSL client when the server requests (or
- * requires a certificate). The client can respond by using
- * SSL_use_certificate and SSL_use_PrivateKey to set a
- * certificate if has an appropriate one available, similar to
- * how the server provides its certificate.
- *
- * @param keyTypes key types supported by the server,
- * convertible to strings with #keyType
- * @param asn1DerEncodedX500Principals CAs known to the server
- */
- public void clientCertificateRequested(byte[] keyTypes,
- byte[][] asn1DerEncodedX500Principals)
- throws CertificateEncodingException, SSLException;
-
- /**
- * Called when SSL handshake is completed. Note that this can
- * be after SSL_do_handshake returns when handshake cutthrough
- * is enabled.
- */
- public void handshakeCompleted();
- }
-
- public static native long ERR_peek_last_error();
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLBIOInputStream.java b/crypto/src/main/java/org/conscrypt/OpenSSLBIOInputStream.java
deleted file mode 100644
index 26971d5..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLBIOInputStream.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Provides an interface to OpenSSL's BIO system directly from a Java
- * InputStream. It allows an OpenSSL API to read directly from something more
- * flexible interface than a byte array.
- */
-public class OpenSSLBIOInputStream extends FilterInputStream {
- private long ctx;
-
- public OpenSSLBIOInputStream(InputStream is) {
- super(is);
-
- ctx = NativeCrypto.create_BIO_InputStream(this);
- }
-
- public long getBioContext() {
- return ctx;
- }
-
- /**
- * Similar to a {@code readLine} method, but matches what OpenSSL expects
- * from a {@code BIO_gets} method.
- */
- public int gets(byte[] buffer) throws IOException {
- if (buffer == null || buffer.length == 0) {
- return 0;
- }
-
- int offset = 0;
- int inputByte = 0;
- while (offset < buffer.length) {
- inputByte = read();
- if (inputByte == -1) {
- // EOF
- break;
- }
- if (inputByte == '\n') {
- if (offset == 0) {
- // If we haven't read anything yet, ignore CRLF.
- continue;
- } else {
- break;
- }
- }
-
- buffer[offset++] = (byte) inputByte;
- }
-
- return offset;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java b/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java
deleted file mode 100644
index 7acccc7..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.InvalidParameterSpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Arrays;
-import java.util.Locale;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.CipherSpi;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import org.conscrypt.util.EmptyArray;
-
-public abstract class OpenSSLCipher extends CipherSpi {
-
- /**
- * Modes that a block cipher may support.
- */
- protected static enum Mode {
- CBC,
- CFB, CFB1, CFB8, CFB128,
- CTR,
- CTS,
- ECB,
- OFB, OFB64, OFB128,
- PCBC,
- }
-
- /**
- * Paddings that a block cipher may support.
- */
- protected static enum Padding {
- NOPADDING,
- PKCS5PADDING,
- ISO10126PADDING,
- }
-
- /**
- * Native pointer for the OpenSSL EVP_CIPHER context.
- */
- private OpenSSLCipherContext cipherCtx = new OpenSSLCipherContext(
- NativeCrypto.EVP_CIPHER_CTX_new());
-
- /**
- * The current cipher mode.
- */
- private Mode mode = Mode.ECB;
-
- /**
- * The current cipher padding.
- */
- private Padding padding = Padding.PKCS5PADDING;
-
- /**
- * The Initial Vector (IV) used for the current cipher.
- */
- private byte[] iv;
-
- /**
- * Current cipher mode: encrypting or decrypting.
- */
- private boolean encrypting;
-
- /**
- * The block size of the current cipher.
- */
- private int blockSize;
-
- /**
- * The block size of the current mode.
- */
- private int modeBlockSize;
-
- /**
- * Whether the cipher has processed any data yet. OpenSSL doesn't like
- * calling "doFinal()" in decryption mode without processing any updates.
- */
- private boolean calledUpdate;
-
- protected OpenSSLCipher() {
- }
-
- protected OpenSSLCipher(Mode mode, Padding padding) {
- this.mode = mode;
- this.padding = padding;
- blockSize = getCipherBlockSize();
- }
-
- /**
- * Returns the standard name for the particular algorithm.
- */
- protected abstract String getBaseCipherName();
-
- /**
- * Returns the OpenSSL cipher name for the particular {@code keySize} and
- * cipher {@code mode}.
- */
- protected abstract String getCipherName(int keySize, Mode mode);
-
- /**
- * Checks whether the cipher supports this particular {@code keySize} (in
- * bytes) and throws {@code InvalidKeyException} if it doesn't.
- */
- protected abstract void checkSupportedKeySize(int keySize) throws InvalidKeyException;
-
- /**
- * Checks whether the cipher supports this particular cipher {@code mode}
- * and throws {@code NoSuchAlgorithmException} if it doesn't.
- */
- protected abstract void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException;
-
- /**
- * Checks whether the cipher supports this particular cipher {@code padding}
- * and throws {@code NoSuchPaddingException} if it doesn't.
- */
- protected abstract void checkSupportedPadding(Padding padding) throws NoSuchPaddingException;
-
- protected abstract int getCipherBlockSize();
-
- protected boolean supportsVariableSizeKey() {
- return false;
- }
-
- @Override
- protected void engineSetMode(String modeStr) throws NoSuchAlgorithmException {
- final Mode mode;
- try {
- mode = Mode.valueOf(modeStr.toUpperCase(Locale.US));
- } catch (IllegalArgumentException e) {
- NoSuchAlgorithmException newE = new NoSuchAlgorithmException("No such mode: "
- + modeStr);
- newE.initCause(e);
- throw newE;
- }
- checkSupportedMode(mode);
- this.mode = mode;
- }
-
- @Override
- protected void engineSetPadding(String paddingStr) throws NoSuchPaddingException {
- final String paddingStrUpper = paddingStr.toUpperCase(Locale.US);
- final Padding padding;
- try {
- padding = Padding.valueOf(paddingStrUpper);
- } catch (IllegalArgumentException e) {
- NoSuchPaddingException newE = new NoSuchPaddingException("No such padding: "
- + paddingStr);
- newE.initCause(e);
- throw newE;
- }
- checkSupportedPadding(padding);
- this.padding = padding;
- }
-
- @Override
- protected int engineGetBlockSize() {
- return blockSize;
- }
-
- /**
- * The size of output if {@code doFinal()} is called with this
- * {@code inputLen}. If padding is enabled and the size of the input puts it
- * right at the block size, it will add another block for the padding.
- */
- private int getOutputSize(int inputLen) {
- if (modeBlockSize == 1) {
- return inputLen;
- } else {
- final int buffered = NativeCrypto.get_EVP_CIPHER_CTX_buf_len(cipherCtx.getContext());
- if (padding == Padding.NOPADDING) {
- return buffered + inputLen;
- } else {
- final int totalLen = inputLen + buffered + modeBlockSize;
- return totalLen - (totalLen % modeBlockSize);
- }
- }
- }
-
- @Override
- protected int engineGetOutputSize(int inputLen) {
- return getOutputSize(inputLen);
- }
-
- @Override
- protected byte[] engineGetIV() {
- return iv;
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- if (iv != null && iv.length > 0) {
- try {
- AlgorithmParameters params = AlgorithmParameters.getInstance(getBaseCipherName());
- params.init(iv);
- return params;
- } catch (NoSuchAlgorithmException e) {
- return null;
- } catch (IOException e) {
- return null;
- }
- }
- return null;
- }
-
- private void engineInitInternal(int opmode, Key key, byte[] iv, SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) {
- encrypting = true;
- } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) {
- encrypting = false;
- } else {
- throw new InvalidParameterException("Unsupported opmode " + opmode);
- }
-
- if (!(key instanceof SecretKey)) {
- throw new InvalidKeyException("Only SecretKey is supported");
- }
-
- final byte[] encodedKey = key.getEncoded();
- if (encodedKey == null) {
- throw new InvalidKeyException("key.getEncoded() == null");
- }
-
- checkSupportedKeySize(encodedKey.length);
-
- final long cipherType = NativeCrypto.EVP_get_cipherbyname(getCipherName(encodedKey.length,
- mode));
- if (cipherType == 0) {
- throw new InvalidAlgorithmParameterException("Cannot find name for key length = "
- + (encodedKey.length * 8) + " and mode = " + mode);
- }
-
- final int ivLength = NativeCrypto.EVP_CIPHER_iv_length(cipherType);
- if (iv == null && ivLength != 0) {
- iv = new byte[ivLength];
- if (encrypting) {
- if (random == null) {
- random = new SecureRandom();
- }
- random.nextBytes(iv);
- }
- } else if (iv != null && iv.length != ivLength) {
- throw new InvalidAlgorithmParameterException("expected IV length of " + ivLength);
- }
-
- this.iv = iv;
-
- if (supportsVariableSizeKey()) {
- NativeCrypto.EVP_CipherInit_ex(cipherCtx.getContext(), cipherType, null, null,
- encrypting);
- NativeCrypto.EVP_CIPHER_CTX_set_key_length(cipherCtx.getContext(), encodedKey.length);
- NativeCrypto.EVP_CipherInit_ex(cipherCtx.getContext(), 0, encodedKey, iv, encrypting);
- } else {
- NativeCrypto.EVP_CipherInit_ex(cipherCtx.getContext(), cipherType, encodedKey, iv,
- encrypting);
- }
-
- // OpenSSL only supports PKCS5 Padding.
- NativeCrypto.EVP_CIPHER_CTX_set_padding(cipherCtx.getContext(),
- padding == Padding.PKCS5PADDING);
- modeBlockSize = NativeCrypto.EVP_CIPHER_CTX_block_size(cipherCtx.getContext());
- calledUpdate = false;
- }
-
- @Override
- protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- try {
- engineInitInternal(opmode, key, null, random);
- } catch (InvalidAlgorithmParameterException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- final byte[] iv;
- if (params instanceof IvParameterSpec) {
- IvParameterSpec ivParams = (IvParameterSpec) params;
- iv = ivParams.getIV();
- } else {
- iv = null;
- }
-
- engineInitInternal(opmode, key, iv, random);
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- final AlgorithmParameterSpec spec;
- try {
- spec = params.getParameterSpec(IvParameterSpec.class);
- } catch (InvalidParameterSpecException e) {
- throw new InvalidAlgorithmParameterException(e);
- }
-
- engineInit(opmode, key, spec, random);
- }
-
- private final int updateInternal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset, int maximumLen) throws ShortBufferException {
- final int intialOutputOffset = outputOffset;
-
- final int bytesLeft = output.length - outputOffset;
- if (bytesLeft < maximumLen) {
- throw new ShortBufferException("output buffer too small during update: " + bytesLeft
- + " < " + maximumLen);
- }
-
- outputOffset += NativeCrypto.EVP_CipherUpdate(cipherCtx.getContext(), output, outputOffset,
- input, inputOffset, inputLen);
-
- calledUpdate = true;
-
- return outputOffset - intialOutputOffset;
- }
-
- @Override
- protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
- final int maximumLen = getOutputSize(inputLen);
-
- /* See how large our output buffer would need to be. */
- final byte[] output;
- if (maximumLen > 0) {
- output = new byte[maximumLen];
- } else {
- output = EmptyArray.BYTE;
- }
-
- final int bytesWritten;
- try {
- bytesWritten = updateInternal(input, inputOffset, inputLen, output, 0, maximumLen);
- } catch (ShortBufferException e) {
- /* This shouldn't happen. */
- throw new RuntimeException("calculated buffer size was wrong: " + maximumLen);
- }
-
- if (output.length == bytesWritten) {
- return output;
- } else if (bytesWritten == 0) {
- return EmptyArray.BYTE;
- } else {
- return Arrays.copyOfRange(output, 0, bytesWritten);
- }
- }
-
- @Override
- protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException {
- final int maximumLen = getOutputSize(inputLen);
- return updateInternal(input, inputOffset, inputLen, output, outputOffset, maximumLen);
- }
-
- /**
- * Reset this Cipher instance state to process a new chunk of data.
- */
- private void reset() {
- NativeCrypto.EVP_CipherInit_ex(cipherCtx.getContext(), 0, null, null, encrypting);
- calledUpdate = false;
- }
-
- private int doFinalInternal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset, int maximumLen) throws IllegalBlockSizeException,
- BadPaddingException, ShortBufferException {
- /* Remember this so we can tell how many characters were written. */
- final int initialOutputOffset = outputOffset;
-
- if (inputLen > 0) {
- final int updateBytesWritten = updateInternal(input, inputOffset, inputLen, output,
- outputOffset, maximumLen);
- outputOffset += updateBytesWritten;
- maximumLen -= updateBytesWritten;
- }
-
- /*
- * If we're decrypting and haven't had any input, we should return null.
- * Otherwise OpenSSL will complain if we call final.
- */
- if (!encrypting && !calledUpdate) {
- return 0;
- }
-
- /* Allow OpenSSL to pad if necessary and clean up state. */
- final int bytesLeft = output.length - outputOffset;
- final int writtenBytes;
- if (bytesLeft >= maximumLen) {
- writtenBytes = NativeCrypto.EVP_CipherFinal_ex(cipherCtx.getContext(), output,
- outputOffset);
- } else {
- final byte[] lastBlock = new byte[maximumLen];
- writtenBytes = NativeCrypto.EVP_CipherFinal_ex(cipherCtx.getContext(), lastBlock, 0);
- if (writtenBytes > bytesLeft) {
- throw new ShortBufferException("buffer is too short: " + writtenBytes + " > "
- + bytesLeft);
- } else if (writtenBytes > 0) {
- System.arraycopy(lastBlock, 0, output, outputOffset, writtenBytes);
- }
- }
- outputOffset += writtenBytes;
-
- reset();
-
- return outputOffset - initialOutputOffset;
- }
-
- @Override
- protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
- throws IllegalBlockSizeException, BadPaddingException {
- /*
- * Other implementations return null if we've never called update()
- * while decrypting.
- */
- if (!encrypting && !calledUpdate && inputLen == 0) {
- reset();
- return null;
- }
-
- final int maximumLen = getOutputSize(inputLen);
- /* Assume that we'll output exactly on a byte boundary. */
- final byte[] output = new byte[maximumLen];
- final int bytesWritten;
- try {
- bytesWritten = doFinalInternal(input, inputOffset, inputLen, output, 0, maximumLen);
- } catch (ShortBufferException e) {
- /* This should not happen since we sized our own buffer. */
- throw new RuntimeException("our calculated buffer was too small", e);
- }
-
- if (bytesWritten == output.length) {
- return output;
- } else if (bytesWritten == 0) {
- return EmptyArray.BYTE;
- } else {
- return Arrays.copyOfRange(output, 0, bytesWritten);
- }
- }
-
- @Override
- protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException {
- if (output == null) {
- throw new NullPointerException("output == null");
- }
-
- final int maximumLen = getOutputSize(inputLen);
- return doFinalInternal(input, inputOffset, inputLen, output, outputOffset, maximumLen);
- }
-
- @Override
- protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
- try {
- byte[] encoded = key.getEncoded();
- return engineDoFinal(encoded, 0, encoded.length);
- } catch (BadPaddingException e) {
- IllegalBlockSizeException newE = new IllegalBlockSizeException();
- newE.initCause(e);
- throw newE;
- }
- }
-
- @Override
- protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
- throws InvalidKeyException, NoSuchAlgorithmException {
- try {
- byte[] encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
- if (wrappedKeyType == Cipher.PUBLIC_KEY) {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
- } else if (wrappedKeyType == Cipher.PRIVATE_KEY) {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
- } else if (wrappedKeyType == Cipher.SECRET_KEY) {
- return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
- } else {
- throw new UnsupportedOperationException("wrappedKeyType == " + wrappedKeyType);
- }
- } catch (IllegalBlockSizeException e) {
- throw new InvalidKeyException(e);
- } catch (BadPaddingException e) {
- throw new InvalidKeyException(e);
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- public static class AES extends OpenSSLCipher {
- private static final int AES_BLOCK_SIZE = 16;
-
- protected AES(Mode mode, Padding padding) {
- super(mode, padding);
- }
-
- public static class CBC extends AES {
- public CBC(Padding padding) {
- super(Mode.CBC, padding);
- }
-
- public static class NoPadding extends CBC {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CBC {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class CFB extends AES {
- public CFB(Padding padding) {
- super(Mode.CFB, padding);
- }
-
- public static class NoPadding extends CFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class CTR extends AES {
- public CTR(Padding padding) {
- super(Mode.CTR, padding);
- }
-
- public static class NoPadding extends CTR {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CTR {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class ECB extends AES {
- public ECB(Padding padding) {
- super(Mode.ECB, padding);
- }
-
- public static class NoPadding extends ECB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends ECB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class OFB extends AES {
- public OFB(Padding padding) {
- super(Mode.OFB, padding);
- }
-
- public static class NoPadding extends OFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends OFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- @Override
- protected void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
- switch (keyLength) {
- case 16: // AES 128
- case 24: // AES 192
- case 32: // AES 256
- return;
- default:
- throw new InvalidKeyException("Unsupported key size: " + keyLength + " bytes");
- }
- }
-
- @Override
- protected void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
- switch (mode) {
- case CBC:
- case CFB:
- case CFB1:
- case CFB8:
- case CFB128:
- case CTR:
- case ECB:
- case OFB:
- return;
- default:
- throw new NoSuchAlgorithmException("Unsupported mode " + mode.toString());
- }
- }
-
- @Override
- protected void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
- switch (padding) {
- case NOPADDING:
- case PKCS5PADDING:
- return;
- default:
- throw new NoSuchPaddingException("Unsupported padding " + padding.toString());
- }
- }
-
- @Override
- protected String getBaseCipherName() {
- return "AES";
- }
-
- @Override
- protected String getCipherName(int keyLength, Mode mode) {
- return "aes-" + (keyLength * 8) + "-" + mode.toString().toLowerCase(Locale.US);
- }
-
- @Override
- protected int getCipherBlockSize() {
- return AES_BLOCK_SIZE;
- }
- }
-
- public static class DESEDE extends OpenSSLCipher {
- private static int DES_BLOCK_SIZE = 8;
-
- public DESEDE(Mode mode, Padding padding) {
- super(mode, padding);
- }
-
- public static class CBC extends DESEDE {
- public CBC(Padding padding) {
- super(Mode.CBC, padding);
- }
-
- public static class NoPadding extends CBC {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CBC {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class CFB extends DESEDE {
- public CFB(Padding padding) {
- super(Mode.CFB, padding);
- }
-
- public static class NoPadding extends CFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class ECB extends DESEDE {
- public ECB(Padding padding) {
- super(Mode.ECB, padding);
- }
-
- public static class NoPadding extends ECB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends ECB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class OFB extends DESEDE {
- public OFB(Padding padding) {
- super(Mode.OFB, padding);
- }
-
- public static class NoPadding extends OFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends OFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- @Override
- protected String getBaseCipherName() {
- return "DESede";
- }
-
- @Override
- protected String getCipherName(int keySize, Mode mode) {
- final String baseCipherName;
- if (keySize == 16) {
- baseCipherName = "des-ede";
- } else {
- baseCipherName = "des-ede3";
- }
-
- if (mode == Mode.ECB) {
- return baseCipherName;
- } else {
- return baseCipherName + "-" + mode.toString().toLowerCase(Locale.US);
- }
- }
-
- @Override
- protected void checkSupportedKeySize(int keySize) throws InvalidKeyException {
- if (keySize != 16 && keySize != 24) {
- throw new InvalidKeyException("key size must be 128 or 192 bits");
- }
- }
-
- @Override
- protected void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
- switch (mode) {
- case CBC:
- case CFB:
- case CFB1:
- case CFB8:
- case ECB:
- case OFB:
- return;
- default:
- throw new NoSuchAlgorithmException("Unsupported mode " + mode.toString());
- }
- }
-
- @Override
- protected void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
- switch (padding) {
- case NOPADDING:
- case PKCS5PADDING:
- return;
- default:
- throw new NoSuchPaddingException("Unsupported padding " + padding.toString());
- }
- }
-
- @Override
- protected int getCipherBlockSize() {
- return DES_BLOCK_SIZE;
- }
- }
-
- public static class ARC4 extends OpenSSLCipher {
- public ARC4() {
- }
-
- @Override
- protected String getBaseCipherName() {
- return "ARCFOUR";
- }
-
- @Override
- protected String getCipherName(int keySize, Mode mode) {
- return "rc4";
- }
-
- @Override
- protected void checkSupportedKeySize(int keySize) throws InvalidKeyException {
- }
-
- @Override
- protected void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
- throw new NoSuchAlgorithmException("ARC4 does not support modes");
- }
-
- @Override
- protected void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
- throw new NoSuchPaddingException("ARC4 does not support padding");
- }
-
- @Override
- protected int getCipherBlockSize() {
- return 0;
- }
-
- @Override
- protected boolean supportsVariableSizeKey() {
- return true;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLCipherContext.java b/crypto/src/main/java/org/conscrypt/OpenSSLCipherContext.java
deleted file mode 100644
index ffbcad4..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLCipherContext.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-class OpenSSLCipherContext {
- private final long context;
-
- OpenSSLCipherContext(long ctx) {
- if (ctx == 0) {
- throw new NullPointerException("ctx == 0");
- }
-
- this.context = ctx;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- NativeCrypto.EVP_CIPHER_CTX_cleanup(context);
- } finally {
- super.finalize();
- }
- }
-
- long getContext() {
- return context;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLCipherRSA.java b/crypto/src/main/java/org/conscrypt/OpenSSLCipherRSA.java
deleted file mode 100644
index 9e2f426..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLCipherRSA.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.SignatureException;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Arrays;
-import java.util.Locale;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.CipherSpi;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.SecretKeySpec;
-import org.conscrypt.util.EmptyArray;
-
-public abstract class OpenSSLCipherRSA extends CipherSpi {
- /**
- * The current OpenSSL key we're operating on.
- */
- private OpenSSLKey key;
-
- /**
- * Current key type: private or public.
- */
- private boolean usingPrivateKey;
-
- /**
- * Current cipher mode: encrypting or decrypting.
- */
- private boolean encrypting;
-
- /**
- * Buffer for operations
- */
- private byte[] buffer;
-
- /**
- * Current offset in the buffer.
- */
- private int bufferOffset;
-
- /**
- * Flag that indicates an exception should be thrown when the input is too
- * large during doFinal.
- */
- private boolean inputTooLarge;
-
- /**
- * Current padding mode
- */
- private int padding = NativeCrypto.RSA_PKCS1_PADDING;
-
- protected OpenSSLCipherRSA(int padding) {
- this.padding = padding;
- }
-
- @Override
- protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
- final String modeUpper = mode.toUpperCase(Locale.ROOT);
- if ("NONE".equals(modeUpper) || "ECB".equals(modeUpper)) {
- return;
- }
-
- throw new NoSuchAlgorithmException("mode not supported: " + mode);
- }
-
- @Override
- protected void engineSetPadding(String padding) throws NoSuchPaddingException {
- final String paddingUpper = padding.toUpperCase(Locale.ROOT);
- if ("PKCS1PADDING".equals(paddingUpper)) {
- this.padding = NativeCrypto.RSA_PKCS1_PADDING;
- return;
- }
- if ("NOPADDING".equals(paddingUpper)) {
- this.padding = NativeCrypto.RSA_NO_PADDING;
- return;
- }
-
- throw new NoSuchPaddingException("padding not supported: " + padding);
- }
-
- @Override
- protected int engineGetBlockSize() {
- if (encrypting) {
- return paddedBlockSizeBytes();
- }
- return keySizeBytes();
- }
-
- @Override
- protected int engineGetOutputSize(int inputLen) {
- if (encrypting) {
- return keySizeBytes();
- }
- return paddedBlockSizeBytes();
- }
-
- private int paddedBlockSizeBytes() {
- int paddedBlockSizeBytes = keySizeBytes();
- if (padding == NativeCrypto.RSA_PKCS1_PADDING) {
- paddedBlockSizeBytes--; // for 0 prefix
- paddedBlockSizeBytes -= 10; // PKCS1 padding header length
- }
- return paddedBlockSizeBytes;
- }
-
- private int keySizeBytes() {
- if (key == null) {
- throw new IllegalStateException("cipher is not initialized");
- }
- return NativeCrypto.RSA_size(this.key.getPkeyContext());
- }
-
- @Override
- protected byte[] engineGetIV() {
- return null;
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- return null;
- }
-
- private void engineInitInternal(int opmode, Key key) throws InvalidKeyException {
- if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) {
- encrypting = true;
- } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) {
- encrypting = false;
- } else {
- throw new InvalidParameterException("Unsupported opmode " + opmode);
- }
-
- if (key instanceof OpenSSLRSAPrivateKey) {
- OpenSSLRSAPrivateKey rsaPrivateKey = (OpenSSLRSAPrivateKey) key;
- usingPrivateKey = true;
- this.key = rsaPrivateKey.getOpenSSLKey();
- } else if (key instanceof RSAPrivateCrtKey) {
- RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) key;
- usingPrivateKey = true;
- this.key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
- } else if (key instanceof RSAPrivateKey) {
- RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) key;
- usingPrivateKey = true;
- this.key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
- } else if (key instanceof OpenSSLRSAPublicKey) {
- OpenSSLRSAPublicKey rsaPublicKey = (OpenSSLRSAPublicKey) key;
- usingPrivateKey = false;
- this.key = rsaPublicKey.getOpenSSLKey();
- } else if (key instanceof RSAPublicKey) {
- RSAPublicKey rsaPublicKey = (RSAPublicKey) key;
- usingPrivateKey = false;
- this.key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
- } else {
- throw new InvalidKeyException("Need RSA private or public key");
- }
-
- buffer = new byte[NativeCrypto.RSA_size(this.key.getPkeyContext())];
- inputTooLarge = false;
- }
-
- @Override
- protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- engineInitInternal(opmode, key);
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("unknown param type: "
- + params.getClass().getName());
- }
-
- engineInitInternal(opmode, key);
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("unknown param type: "
- + params.getClass().getName());
- }
-
- engineInitInternal(opmode, key);
- }
-
- @Override
- protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
- if (bufferOffset + inputLen > buffer.length) {
- inputTooLarge = true;
- return EmptyArray.BYTE;
- }
-
- System.arraycopy(input, inputOffset, buffer, bufferOffset, inputLen);
- bufferOffset += inputLen;
- return EmptyArray.BYTE;
- }
-
- @Override
- protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException {
- engineUpdate(input, inputOffset, inputLen);
- return 0;
- }
-
- @Override
- protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
- throws IllegalBlockSizeException, BadPaddingException {
- if (input != null) {
- engineUpdate(input, inputOffset, inputLen);
- }
-
- if (inputTooLarge) {
- throw new IllegalBlockSizeException("input must be under " + buffer.length + " bytes");
- }
-
- final byte[] tmpBuf;
- if (bufferOffset != buffer.length) {
- if (padding == NativeCrypto.RSA_NO_PADDING) {
- tmpBuf = new byte[buffer.length];
- System.arraycopy(buffer, 0, tmpBuf, buffer.length - bufferOffset, bufferOffset);
- } else {
- tmpBuf = Arrays.copyOf(buffer, bufferOffset);
- }
- } else {
- tmpBuf = buffer;
- }
-
- byte[] output = new byte[buffer.length];
- int resultSize;
- if (encrypting) {
- if (usingPrivateKey) {
- resultSize = NativeCrypto.RSA_private_encrypt(tmpBuf.length, tmpBuf, output,
- key.getPkeyContext(), padding);
- } else {
- resultSize = NativeCrypto.RSA_public_encrypt(tmpBuf.length, tmpBuf, output,
- key.getPkeyContext(), padding);
- }
- } else {
- try {
- if (usingPrivateKey) {
- resultSize = NativeCrypto.RSA_private_decrypt(tmpBuf.length, tmpBuf, output,
- key.getPkeyContext(), padding);
- } else {
- resultSize = NativeCrypto.RSA_public_decrypt(tmpBuf.length, tmpBuf, output,
- key.getPkeyContext(), padding);
- }
- } catch (SignatureException e) {
- IllegalBlockSizeException newE = new IllegalBlockSizeException();
- newE.initCause(e);
- throw newE;
- }
- }
- if (!encrypting && resultSize != output.length) {
- output = Arrays.copyOf(output, resultSize);
- }
-
- bufferOffset = 0;
- return output;
- }
-
- @Override
- protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException {
- byte[] b = engineDoFinal(input, inputOffset, inputLen);
-
- final int lastOffset = outputOffset + b.length;
- if (lastOffset > output.length) {
- throw new ShortBufferException("output buffer is too small " + output.length + " < "
- + lastOffset);
- }
-
- System.arraycopy(b, 0, output, outputOffset, b.length);
- return b.length;
- }
-
- @Override
- protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
- try {
- byte[] encoded = key.getEncoded();
- return engineDoFinal(encoded, 0, encoded.length);
- } catch (BadPaddingException e) {
- IllegalBlockSizeException newE = new IllegalBlockSizeException();
- newE.initCause(e);
- throw newE;
- }
- }
-
- @Override
- protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
- int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
- try {
- byte[] encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
- if (wrappedKeyType == Cipher.PUBLIC_KEY) {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
- } else if (wrappedKeyType == Cipher.PRIVATE_KEY) {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
- } else if (wrappedKeyType == Cipher.SECRET_KEY) {
- return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
- } else {
- throw new UnsupportedOperationException("wrappedKeyType == " + wrappedKeyType);
- }
- } catch (IllegalBlockSizeException e) {
- throw new InvalidKeyException(e);
- } catch (BadPaddingException e) {
- throw new InvalidKeyException(e);
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- public static class PKCS1 extends OpenSSLCipherRSA {
- public PKCS1() {
- super(NativeCrypto.RSA_PKCS1_PADDING);
- }
- }
-
- public static class Raw extends OpenSSLCipherRSA {
- public Raw() {
- super(NativeCrypto.RSA_NO_PADDING);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLContextImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLContextImpl.java
deleted file mode 100644
index 6b0e5f9..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLContextImpl.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * Overrides the original SSLContextImpl to provide OpenSSL-based
- * SSLSocketFactory and SSLServerSocketFactory instances.
- */
-public class OpenSSLContextImpl extends SSLContextImpl {
-
- public OpenSSLContextImpl() {}
-
- protected OpenSSLContextImpl(DefaultSSLContextImpl dummy)
- throws GeneralSecurityException, IOException {
- super(dummy);
- }
-
- @Override
- public SSLSocketFactory engineGetSocketFactory() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- return new OpenSSLSocketFactoryImpl(sslParameters);
- }
-
- @Override
- public SSLServerSocketFactory engineGetServerSocketFactory() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- return new OpenSSLServerSocketFactoryImpl(sslParameters);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyFactory.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyFactory.java
deleted file mode 100644
index a9f7067..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyFactory.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactorySpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-public class OpenSSLDSAKeyFactory extends KeyFactorySpi {
-
- @Override
- protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof DSAPublicKeySpec) {
- return new OpenSSLDSAPublicKey((DSAPublicKeySpec) keySpec);
- } else if (keySpec instanceof X509EncodedKeySpec) {
- return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeCrypto.EVP_PKEY_DSA);
- }
- throw new InvalidKeySpecException("Must use DSAPublicKeySpec or X509EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof DSAPrivateKeySpec) {
- return new OpenSSLDSAPrivateKey((DSAPrivateKeySpec) keySpec);
- } else if (keySpec instanceof PKCS8EncodedKeySpec) {
- return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
- NativeCrypto.EVP_PKEY_DSA);
- }
- throw new InvalidKeySpecException("Must use DSAPrivateKeySpec or PKCS8EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
- throws InvalidKeySpecException {
- if (key == null) {
- throw new InvalidKeySpecException("key == null");
- }
-
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (!"DSA".equals(key.getAlgorithm())) {
- throw new InvalidKeySpecException("Key must be a DSA key");
- }
-
- if (key instanceof DSAPublicKey && DSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
- DSAPublicKey dsaKey = (DSAPublicKey) key;
- DSAParams params = dsaKey.getParams();
- return (T) new DSAPublicKeySpec(dsaKey.getY(), params.getP(), params.getQ(),
- params.getG());
- } else if (key instanceof PublicKey && DSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid X.509 encoding");
- }
- DSAPublicKey dsaKey =
- (DSAPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
- DSAParams params = dsaKey.getParams();
- return (T) new DSAPublicKeySpec(dsaKey.getY(), params.getP(), params.getQ(),
- params.getG());
- } else if (key instanceof DSAPrivateKey
- && DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- DSAPrivateKey dsaKey = (DSAPrivateKey) key;
- DSAParams params = dsaKey.getParams();
- return (T) new DSAPrivateKeySpec(dsaKey.getX(), params.getP(), params.getQ(),
- params.getG());
- } else if (key instanceof PrivateKey && DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
- }
- DSAPrivateKey dsaKey =
- (DSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- DSAParams params = dsaKey.getParams();
- return (T) new DSAPrivateKeySpec(dsaKey.getX(), params.getP(), params.getQ(),
- params.getG());
- } else if (key instanceof PrivateKey
- && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new PKCS8EncodedKeySpec(encoded);
- } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be X.509; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new X509EncodedKeySpec(encoded);
- } else {
- throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
- + key.getClass().getName() + ", keySpec=" + keySpec.getName());
- }
- }
-
- @Override
- protected Key engineTranslateKey(Key key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
- if ((key instanceof OpenSSLDSAPublicKey) || (key instanceof OpenSSLDSAPrivateKey)) {
- return key;
- } else if (key instanceof DSAPublicKey) {
- DSAPublicKey dsaKey = (DSAPublicKey) key;
-
- BigInteger y = dsaKey.getY();
-
- DSAParams params = dsaKey.getParams();
- BigInteger p = params.getP();
- BigInteger q = params.getQ();
- BigInteger g = params.getG();
-
- try {
- return engineGeneratePublic(new DSAPublicKeySpec(y, p, q, g));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if (key instanceof DSAPrivateKey) {
- DSAPrivateKey dsaKey = (DSAPrivateKey) key;
-
- BigInteger x = dsaKey.getX();
-
- DSAParams params = dsaKey.getParams();
- BigInteger p = params.getP();
- BigInteger q = params.getQ();
- BigInteger g = params.getG();
-
- try {
- return engineGeneratePrivate(new DSAPrivateKeySpec(x, p, q, g));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PrivateKey) && ("PKCS#8".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PublicKey) && ("X.509".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePublic(new X509EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else {
- throw new InvalidKeyException("Key must be DSA public or private key; was "
- + key.getClass().getName());
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyPairGenerator.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyPairGenerator.java
deleted file mode 100644
index 3428fcc..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyPairGenerator.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGeneratorSpi;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.DSAParameterSpec;
-
-public class OpenSSLDSAKeyPairGenerator extends KeyPairGeneratorSpi {
-
- private int primeBits = 1024;
-
- private SecureRandom random = null;
-
- private byte[] g;
-
- private byte[] p;
-
- private byte[] q;
-
- @Override
- public KeyPair generateKeyPair() {
- final byte[] seed;
- if (random == null) {
- seed = null;
- } else {
- seed = new byte[20];
- random.nextBytes(seed);
- }
-
- final OpenSSLKey key = new OpenSSLKey(NativeCrypto.DSA_generate_key(primeBits, seed, g, p,
- q));
-
- final OpenSSLDSAPrivateKey privKey = new OpenSSLDSAPrivateKey(key);
- final OpenSSLDSAPublicKey pubKey = new OpenSSLDSAPublicKey(key);
-
- return new KeyPair(pubKey, privKey);
- }
-
- @Override
- public void initialize(int keysize, SecureRandom random) {
- primeBits = keysize;
- this.random = random;
- }
-
- @Override
- public void initialize(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- this.random = random;
-
- if (params instanceof DSAParameterSpec) {
- DSAParameterSpec dsaParams = (DSAParameterSpec) params;
-
- BigInteger gInt = dsaParams.getG();
- if (gInt != null) {
- g = gInt.toByteArray();
- }
-
- BigInteger pInt = dsaParams.getP();
- if (pInt != null) {
- p = pInt.toByteArray();
- }
-
- BigInteger qInt = dsaParams.getQ();
- if (qInt != null) {
- q = qInt.toByteArray();
- }
- } else if (params != null) {
- throw new InvalidAlgorithmParameterException("Params must be DSAParameterSpec");
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAParams.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAParams.java
deleted file mode 100644
index fd0edf7..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAParams.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.interfaces.DSAParams;
-import java.security.spec.AlgorithmParameterSpec;
-
-public class OpenSSLDSAParams implements DSAParams, AlgorithmParameterSpec {
-
- private OpenSSLKey key;
-
- private boolean fetchedParams;
-
- private BigInteger g;
-
- private BigInteger p;
-
- private BigInteger q;
-
- private BigInteger y;
-
- private BigInteger x;
-
- OpenSSLDSAParams(OpenSSLKey key) {
- this.key = key;
- }
-
- OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- private synchronized final void ensureReadParams() {
- if (fetchedParams) {
- return;
- }
-
- byte[][] params = NativeCrypto.get_DSA_params(key.getPkeyContext());
- if (params[0] != null) {
- g = new BigInteger(params[0]);
- }
- if (params[1] != null) {
- p = new BigInteger(params[1]);
- }
- if (params[2] != null) {
- q = new BigInteger(params[2]);
- }
- if (params[3] != null) {
- y = new BigInteger(params[3]);
- }
- if (params[4] != null) {
- x = new BigInteger(params[4]);
- }
-
- fetchedParams = true;
- }
-
- @Override
- public BigInteger getG() {
- ensureReadParams();
- return g;
- }
-
- @Override
- public BigInteger getP() {
- ensureReadParams();
- return p;
- }
-
- @Override
- public BigInteger getQ() {
- ensureReadParams();
- return q;
- }
-
- boolean hasParams() {
- ensureReadParams();
- return (g != null) && (p != null) && (q != null);
- }
-
- BigInteger getY() {
- ensureReadParams();
- return y;
- }
-
- BigInteger getX() {
- ensureReadParams();
- return x;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLDSAParams) {
- OpenSSLDSAParams other = (OpenSSLDSAParams) o;
-
- /*
- * We can shortcut the true case, but it still may be equivalent but
- * different copies.
- */
- if (key == other.getOpenSSLKey()) {
- return true;
- }
- }
-
- if (!(o instanceof DSAParams)) {
- return false;
- }
-
- ensureReadParams();
-
- DSAParams other = (DSAParams) o;
- return g.equals(other.getG()) && p.equals(other.getP()) && q.equals(other.getQ());
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
-
- return g.hashCode() ^ p.hashCode() ^ q.hashCode();
- }
-
- @Override
- public String toString() {
- ensureReadParams();
-
- final StringBuilder sb = new StringBuilder("OpenSSLDSAParams{");
- sb.append("G=");
- sb.append(g.toString(16));
- sb.append(",P=");
- sb.append(p.toString(16));
- sb.append(",Q=");
- sb.append(q.toString(16));
- sb.append('}');
-
- return sb.toString();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAPrivateKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAPrivateKey.java
deleted file mode 100644
index 0fc4db7..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAPrivateKey.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.InvalidKeySpecException;
-
-public class OpenSSLDSAPrivateKey implements DSAPrivateKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 6524734576187424628L;
-
- private transient OpenSSLKey key;
-
- private transient OpenSSLDSAParams params;
-
- OpenSSLDSAPrivateKey(OpenSSLKey key) {
- this.key = key;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- OpenSSLDSAPrivateKey(DSAPrivateKeySpec dsaKeySpec) throws InvalidKeySpecException {
- try {
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- dsaKeySpec.getP().toByteArray(),
- dsaKeySpec.getQ().toByteArray(),
- dsaKeySpec.getG().toByteArray(),
- null,
- dsaKeySpec.getX().toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- private void ensureReadParams() {
- if (params == null) {
- params = new OpenSSLDSAParams(key);
- }
- }
-
- static OpenSSLKey getInstance(DSAPrivateKey dsaPrivateKey) throws InvalidKeyException {
- try {
- DSAParams dsaParams = dsaPrivateKey.getParams();
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- dsaParams.getP().toByteArray(),
- dsaParams.getQ().toByteArray(),
- dsaParams.getG().toByteArray(),
- null,
- dsaPrivateKey.getX().toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public DSAParams getParams() {
- ensureReadParams();
- return params;
- }
-
- @Override
- public String getAlgorithm() {
- return "DSA";
- }
-
- @Override
- public String getFormat() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return "PKCS#8";
- }
-
- @Override
- public byte[] getEncoded() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext());
- }
-
- @Override
- public BigInteger getX() {
- if (key.isEngineBased()) {
- throw new UnsupportedOperationException("private key value X cannot be extracted");
- }
-
- ensureReadParams();
- return params.getX();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLDSAPrivateKey) {
- OpenSSLDSAPrivateKey other = (OpenSSLDSAPrivateKey) o;
-
- /*
- * We can shortcut the true case, but it still may be equivalent but
- * different copies.
- */
- if (key.equals(other.getOpenSSLKey())) {
- return true;
- }
- }
-
- if (!(o instanceof DSAPrivateKey)) {
- return false;
- }
-
- ensureReadParams();
-
- final BigInteger x = params.getX();
- if (x == null) {
- /*
- * If our X is null, we can't tell if these two private keys are
- * equivalent. This usually happens if this key is ENGINE-based. If
- * the other key was ENGINE-based, we should have caught it in the
- * OpenSSLDSAPrivateKey case.
- */
- return false;
- }
-
- final DSAPrivateKey other = (DSAPrivateKey) o;
- return x.equals(other.getX()) && params.equals(other.getParams());
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
-
- int hash = 1;
-
- final BigInteger x = getX();
- if (x != null) {
- hash = hash * 3 + x.hashCode();
- }
-
- hash = hash * 7 + params.hashCode();
-
- return hash;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("OpenSSLDSAPrivateKey{");
-
- if (key.isEngineBased()) {
- sb.append("key=");
- sb.append(key);
- sb.append('}');
- return sb.toString();
- }
-
- ensureReadParams();
- sb.append("X=");
- sb.append(params.getX().toString(16));
- sb.append(',');
- sb.append("params=");
- sb.append(params.toString());
- sb.append('}');
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- final BigInteger g = (BigInteger) stream.readObject();
- final BigInteger p = (BigInteger) stream.readObject();
- final BigInteger q = (BigInteger) stream.readObject();
- final BigInteger x = (BigInteger) stream.readObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- p.toByteArray(),
- q.toByteArray(),
- g.toByteArray(),
- null,
- x.toByteArray()));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- stream.defaultWriteObject();
-
- ensureReadParams();
- stream.writeObject(params.getG());
- stream.writeObject(params.getP());
- stream.writeObject(params.getQ());
- stream.writeObject(params.getX());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAPublicKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAPublicKey.java
deleted file mode 100644
index 1c0bf74..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAPublicKey.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-
-public class OpenSSLDSAPublicKey implements DSAPublicKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 5238609500353792232L;
-
- private transient OpenSSLKey key;
-
- private transient OpenSSLDSAParams params;
-
- OpenSSLDSAPublicKey(OpenSSLKey key) {
- this.key = key;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- OpenSSLDSAPublicKey(DSAPublicKeySpec dsaKeySpec) throws InvalidKeySpecException {
- try {
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- dsaKeySpec.getP().toByteArray(),
- dsaKeySpec.getQ().toByteArray(),
- dsaKeySpec.getG().toByteArray(),
- dsaKeySpec.getY().toByteArray(),
- null));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- private void ensureReadParams() {
- if (params == null) {
- params = new OpenSSLDSAParams(key);
- }
- }
-
- static OpenSSLKey getInstance(DSAPublicKey dsaPublicKey) throws InvalidKeyException {
- try {
- final DSAParams dsaParams = dsaPublicKey.getParams();
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- dsaParams.getP().toByteArray(),
- dsaParams.getQ().toByteArray(),
- dsaParams.getG().toByteArray(),
- dsaPublicKey.getY().toByteArray(),
- null));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public DSAParams getParams() {
- ensureReadParams();
-
- /*
- * DSA keys can lack parameters if they're part of a certificate
- * chain. In this case, we just return null.
- */
- if (!params.hasParams()) {
- return null;
- }
-
- return params;
- }
-
- @Override
- public String getAlgorithm() {
- return "DSA";
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return NativeCrypto.i2d_PUBKEY(key.getPkeyContext());
- }
-
- @Override
- public BigInteger getY() {
- ensureReadParams();
- return params.getY();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLDSAPublicKey) {
- OpenSSLDSAPublicKey other = (OpenSSLDSAPublicKey) o;
-
- /*
- * We can shortcut the true case, but it still may be equivalent but
- * different copies.
- */
- if (key.equals(other.getOpenSSLKey())) {
- return true;
- }
- }
-
- if (!(o instanceof DSAPublicKey)) {
- return false;
- }
-
- ensureReadParams();
-
- DSAPublicKey other = (DSAPublicKey) o;
- return params.getY().equals(other.getY()) && params.equals(other.getParams());
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
-
- return params.getY().hashCode() ^ params.hashCode();
- }
-
- @Override
- public String toString() {
- ensureReadParams();
-
- final StringBuilder sb = new StringBuilder("OpenSSLDSAPublicKey{");
- sb.append("Y=");
- sb.append(params.getY().toString(16));
- sb.append(',');
- sb.append("params=");
- sb.append(params.toString());
- sb.append('}');
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- final BigInteger g = (BigInteger) stream.readObject();
- final BigInteger p = (BigInteger) stream.readObject();
- final BigInteger q = (BigInteger) stream.readObject();
- final BigInteger y = (BigInteger) stream.readObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- p.toByteArray(),
- q.toByteArray(),
- g.toByteArray(),
- y.toByteArray(),
- null));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
- stream.defaultWriteObject();
-
- ensureReadParams();
- stream.writeObject(params.getG());
- stream.writeObject(params.getP());
- stream.writeObject(params.getQ());
- stream.writeObject(params.getY());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDigestContext.java b/crypto/src/main/java/org/conscrypt/OpenSSLDigestContext.java
deleted file mode 100644
index b11a862..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDigestContext.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-public class OpenSSLDigestContext {
- private final long context;
-
- public OpenSSLDigestContext(long ctx) {
- if (ctx == 0) {
- throw new NullPointerException("ctx == 0");
- }
-
- this.context = ctx;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- NativeCrypto.EVP_MD_CTX_destroy(context);
- } finally {
- super.finalize();
- }
- }
-
- long getContext() {
- return context;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECDHKeyAgreement.java b/crypto/src/main/java/org/conscrypt/OpenSSLECDHKeyAgreement.java
deleted file mode 100644
index 0d8729c..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECDHKeyAgreement.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import javax.crypto.KeyAgreementSpi;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * Elliptic Curve Diffie-Hellman key agreement backed by the OpenSSL engine.
- */
-public final class OpenSSLECDHKeyAgreement extends KeyAgreementSpi {
-
- /** OpenSSL handle of the private key. Only available after the engine has been initialized. */
- private OpenSSLKey mOpenSslPrivateKey;
-
- /**
- * Expected length (in bytes) of the agreed key ({@link #mResult}). Only available after the
- * engine has been initialized.
- */
- private int mExpectedResultLength;
-
- /** Agreed key. Only available after {@link #engineDoPhase(Key, boolean)} completes. */
- private byte[] mResult;
-
- @Override
- public Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException {
- if (mOpenSslPrivateKey == null) {
- throw new IllegalStateException("Not initialized");
- }
- if (!lastPhase) {
- throw new IllegalStateException("ECDH only has one phase");
- }
-
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
- if (!(key instanceof PublicKey)) {
- throw new InvalidKeyException("Not a public key: " + key.getClass());
- }
- OpenSSLKey openSslPublicKey = translateKeyToEcOpenSSLKey(key);
-
- byte[] buffer = new byte[mExpectedResultLength];
- int actualResultLength = NativeCrypto.ECDH_compute_key(
- buffer,
- 0,
- openSslPublicKey.getPkeyContext(),
- mOpenSslPrivateKey.getPkeyContext());
- byte[] result;
- if (actualResultLength == -1) {
- throw new RuntimeException("Engine returned " + actualResultLength);
- } else if (actualResultLength == mExpectedResultLength) {
- // The output is as long as expected -- use the whole buffer
- result = buffer;
- } else if (actualResultLength < mExpectedResultLength) {
- // The output is shorter than expected -- use only what's produced by the engine
- result = new byte[actualResultLength];
- System.arraycopy(buffer, 0, mResult, 0, mResult.length);
- } else {
- // The output is longer than expected
- throw new RuntimeException("Engine produced a longer than expected result. Expected: "
- + mExpectedResultLength + ", actual: " + actualResultLength);
- }
- mResult = result;
-
- return null; // No intermediate key
- }
-
- @Override
- protected int engineGenerateSecret(byte[] sharedSecret, int offset)
- throws ShortBufferException {
- checkCompleted();
- int available = sharedSecret.length - offset;
- if (mResult.length > available) {
- throw new ShortBufferException(
- "Needed: " + mResult.length + ", available: " + available);
- }
-
- System.arraycopy(mResult, 0, sharedSecret, offset, mResult.length);
- return mResult.length;
- }
-
- @Override
- protected byte[] engineGenerateSecret() {
- checkCompleted();
- return mResult;
- }
-
- @Override
- protected SecretKey engineGenerateSecret(String algorithm) {
- checkCompleted();
- return new SecretKeySpec(engineGenerateSecret(), algorithm);
- }
-
- @Override
- protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
- if (!(key instanceof PrivateKey)) {
- throw new InvalidKeyException("Not a private key: " + key.getClass());
- }
-
- OpenSSLKey openSslKey = translateKeyToEcOpenSSLKey(key);
- int fieldSizeBits = NativeCrypto.EC_GROUP_get_degree(NativeCrypto.EC_KEY_get0_group(
- openSslKey.getPkeyContext()));
- mExpectedResultLength = (fieldSizeBits + 7) / 8;
- mOpenSslPrivateKey = openSslKey;
- }
-
- @Override
- protected void engineInit(Key key, AlgorithmParameterSpec params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- // ECDH doesn't need an AlgorithmParameterSpec
- if (params != null) {
- throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
- }
- engineInit(key, random);
- }
-
- private void checkCompleted() {
- if (mResult == null) {
- throw new IllegalStateException("Key agreement not completed");
- }
- }
-
- private static OpenSSLKey translateKeyToEcOpenSSLKey(Key key) throws InvalidKeyException {
- try {
- return ((OpenSSLKeyHolder) KeyFactory.getInstance(
- "EC", OpenSSLProvider.PROVIDER_NAME).translateKey(key)).getOpenSSLKey();
- } catch (Exception e) {
- throw new InvalidKeyException("Failed to translate key to OpenSSL EC key", e);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECGroupContext.java b/crypto/src/main/java/org/conscrypt/OpenSSLECGroupContext.java
deleted file mode 100644
index f7f52a6..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECGroupContext.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidParameterException;
-import java.security.spec.ECField;
-import java.security.spec.ECFieldF2m;
-import java.security.spec.ECFieldFp;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.EllipticCurve;
-
-public final class OpenSSLECGroupContext {
- private final long groupCtx;
-
- public OpenSSLECGroupContext(long groupCtx) {
- this.groupCtx = groupCtx;
- }
-
- public static OpenSSLECGroupContext getCurveByName(String curveName) {
- // Workaround for OpenSSL not supporting SECG names for NIST P-192 and P-256
- // (aka ANSI X9.62 prime192v1 and prime256v1) curve names.
- if ("secp256r1".equals(curveName)) {
- curveName = "prime256v1";
- } else if ("secp192r1".equals(curveName)) {
- curveName = "prime192v1";
- }
-
- final long ctx = NativeCrypto.EC_GROUP_new_by_curve_name(curveName);
- if (ctx == 0) {
- return null;
- }
-
- NativeCrypto.EC_GROUP_set_point_conversion_form(ctx,
- NativeCrypto.POINT_CONVERSION_UNCOMPRESSED);
- NativeCrypto.EC_GROUP_set_asn1_flag(ctx, NativeCrypto.OPENSSL_EC_NAMED_CURVE);
-
- return new OpenSSLECGroupContext(ctx);
- }
-
- public static OpenSSLECGroupContext getInstance(int type, BigInteger p, BigInteger a,
- BigInteger b, BigInteger x, BigInteger y, BigInteger n, BigInteger h) {
- final long ctx = NativeCrypto.EC_GROUP_new_curve(type, p.toByteArray(), a.toByteArray(),
- b.toByteArray());
- if (ctx == 0) {
- return null;
- }
-
- NativeCrypto.EC_GROUP_set_point_conversion_form(ctx,
- NativeCrypto.POINT_CONVERSION_UNCOMPRESSED);
-
- OpenSSLECGroupContext group = new OpenSSLECGroupContext(ctx);
-
- OpenSSLECPointContext generator = new OpenSSLECPointContext(group,
- NativeCrypto.EC_POINT_new(ctx));
-
- NativeCrypto.EC_POINT_set_affine_coordinates(ctx, generator.getContext(),
- x.toByteArray(), y.toByteArray());
-
- NativeCrypto.EC_GROUP_set_generator(ctx, generator.getContext(), n.toByteArray(),
- h.toByteArray());
-
- return group;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (groupCtx != 0) {
- NativeCrypto.EC_GROUP_clear_free(groupCtx);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof OpenSSLECGroupContext)) {
- return false;
- }
-
- final OpenSSLECGroupContext other = (OpenSSLECGroupContext) o;
- return NativeCrypto.EC_GROUP_cmp(groupCtx, other.groupCtx);
- }
-
- @Override
- public int hashCode() {
- // TODO Auto-generated method stub
- return super.hashCode();
- }
-
- public long getContext() {
- return groupCtx;
- }
-
- public static OpenSSLECGroupContext getInstance(ECParameterSpec params)
- throws InvalidAlgorithmParameterException {
- final String curveName = params.getCurveName();
- if (curveName != null) {
- return OpenSSLECGroupContext.getCurveByName(curveName);
- }
-
- final EllipticCurve curve = params.getCurve();
- final ECField field = curve.getField();
-
- final int type;
- final BigInteger p;
- if (field instanceof ECFieldFp) {
- type = NativeCrypto.EC_CURVE_GFP;
- p = ((ECFieldFp) field).getP();
- } else if (field instanceof ECFieldF2m) {
- type = NativeCrypto.EC_CURVE_GF2M;
- p = ((ECFieldF2m) field).getReductionPolynomial();
- } else {
- throw new InvalidParameterException("unhandled field class "
- + field.getClass().getName());
- }
-
- final ECPoint generator = params.getGenerator();
- return OpenSSLECGroupContext.getInstance(type, p, curve.getA(), curve.getB(),
- generator.getAffineX(), generator.getAffineY(), params.getOrder(),
- BigInteger.valueOf(params.getCofactor()));
- }
-
- public ECParameterSpec getECParameterSpec() {
- final String curveName = NativeCrypto.EC_GROUP_get_curve_name(groupCtx);
-
- final byte[][] curveParams = NativeCrypto.EC_GROUP_get_curve(groupCtx);
- final BigInteger p = new BigInteger(curveParams[0]);
- final BigInteger a = new BigInteger(curveParams[1]);
- final BigInteger b = new BigInteger(curveParams[2]);
-
- final ECField field;
- final int type = NativeCrypto.get_EC_GROUP_type(groupCtx);
- if (type == NativeCrypto.EC_CURVE_GFP) {
- field = new ECFieldFp(p);
- } else if (type == NativeCrypto.EC_CURVE_GF2M) {
- field = new ECFieldF2m(p.bitLength() - 1, p);
- } else {
- throw new RuntimeException("unknown curve type " + type);
- }
-
- final EllipticCurve curve = new EllipticCurve(field, a, b);
-
- final OpenSSLECPointContext generatorCtx = new OpenSSLECPointContext(this,
- NativeCrypto.EC_GROUP_get_generator(groupCtx));
- final ECPoint generator = generatorCtx.getECPoint();
-
- final BigInteger order = new BigInteger(NativeCrypto.EC_GROUP_get_order(groupCtx));
- final BigInteger cofactor = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(groupCtx));
-
- return new ECParameterSpec(curve, generator, order, cofactor.intValue(), curveName);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECKeyFactory.java b/crypto/src/main/java/org/conscrypt/OpenSSLECKeyFactory.java
deleted file mode 100644
index b39a611..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECKeyFactory.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactorySpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPrivateKeySpec;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-public class OpenSSLECKeyFactory extends KeyFactorySpi {
-
- @Override
- protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof ECPublicKeySpec) {
- return new OpenSSLECPublicKey((ECPublicKeySpec) keySpec);
- } else if (keySpec instanceof X509EncodedKeySpec) {
- return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeCrypto.EVP_PKEY_EC);
- }
- throw new InvalidKeySpecException("Must use ECPublicKeySpec or X509EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof ECPrivateKeySpec) {
- return new OpenSSLECPrivateKey((ECPrivateKeySpec) keySpec);
- } else if (keySpec instanceof PKCS8EncodedKeySpec) {
- return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
- NativeCrypto.EVP_PKEY_EC);
- }
- throw new InvalidKeySpecException("Must use ECPrivateKeySpec or PKCS8EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
- throws InvalidKeySpecException {
- if (key == null) {
- throw new InvalidKeySpecException("key == null");
- }
-
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (!"EC".equals(key.getAlgorithm())) {
- throw new InvalidKeySpecException("Key must be an EC key");
- }
-
- if (key instanceof ECPublicKey && ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
- ECPublicKey ecKey = (ECPublicKey) key;
- return (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
- } else if (key instanceof PublicKey && ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid X.509 encoding");
- }
- ECPublicKey ecKey = (ECPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
- return (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
- } else if (key instanceof ECPrivateKey
- && ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- ECPrivateKey ecKey = (ECPrivateKey) key;
- return (T) new ECPrivateKeySpec(ecKey.getS(), ecKey.getParams());
- } else if (key instanceof PrivateKey && ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
- }
- ECPrivateKey ecKey =
- (ECPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- return (T) new ECPrivateKeySpec(ecKey.getS(), ecKey.getParams());
- } else if (key instanceof PrivateKey
- && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new PKCS8EncodedKeySpec(encoded);
- } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be X.509; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new X509EncodedKeySpec(encoded);
- } else {
- throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
- + key.getClass().getName() + ", keySpec=" + keySpec.getName());
- }
- }
-
- @Override
- protected Key engineTranslateKey(Key key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
- if ((key instanceof OpenSSLECPublicKey) || (key instanceof OpenSSLECPrivateKey)) {
- return key;
- } else if (key instanceof ECPublicKey) {
- ECPublicKey ecKey = (ECPublicKey) key;
-
- ECPoint w = ecKey.getW();
-
- ECParameterSpec params = ecKey.getParams();
-
- try {
- return engineGeneratePublic(new ECPublicKeySpec(w, params));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if (key instanceof ECPrivateKey) {
- ECPrivateKey ecKey = (ECPrivateKey) key;
-
- BigInteger s = ecKey.getS();
-
- ECParameterSpec params = ecKey.getParams();
-
- try {
- return engineGeneratePrivate(new ECPrivateKeySpec(s, params));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PrivateKey) && ("PKCS#8".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PublicKey) && ("X.509".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePublic(new X509EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else {
- throw new InvalidKeyException("Key must be EC public or private key; was "
- + key.getClass().getName());
- }
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECKeyPairGenerator.java b/crypto/src/main/java/org/conscrypt/OpenSSLECKeyPairGenerator.java
deleted file mode 100644
index 21c8984..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECKeyPairGenerator.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.util.HashMap;
-import java.util.Map;
-
-public final class OpenSSLECKeyPairGenerator extends KeyPairGenerator {
- private static final String ALGORITHM = "EC";
-
- private static final int DEFAULT_KEY_SIZE = 192;
-
- private static final Map<Integer, String> SIZE_TO_CURVE_NAME = new HashMap<Integer, String>();
-
- static {
- /* NIST curves */
- SIZE_TO_CURVE_NAME.put(192, "prime192v1");
- SIZE_TO_CURVE_NAME.put(224, "secp224r1");
- SIZE_TO_CURVE_NAME.put(256, "prime256v1");
- SIZE_TO_CURVE_NAME.put(384, "secp384r1");
- SIZE_TO_CURVE_NAME.put(521, "secp521r1");
- }
-
- private OpenSSLECGroupContext group;
-
- public OpenSSLECKeyPairGenerator() {
- super(ALGORITHM);
- }
-
- @Override
- public KeyPair generateKeyPair() {
- if (group == null) {
- final String curveName = SIZE_TO_CURVE_NAME.get(DEFAULT_KEY_SIZE);
- group = OpenSSLECGroupContext.getCurveByName(curveName);
- }
-
- final OpenSSLKey key = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group.getContext()));
- return new KeyPair(new OpenSSLECPublicKey(group, key), new OpenSSLECPrivateKey(group, key));
- }
-
- @Override
- public void initialize(int keysize, SecureRandom random) {
- final String name = SIZE_TO_CURVE_NAME.get(keysize);
- if (name == null) {
- throw new InvalidParameterException("unknown key size " + keysize);
- }
-
- /*
- * Store the group in a temporary variable until we know this is a valid
- * group.
- */
- final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext.getCurveByName(name);
- if (possibleGroup == null) {
- throw new InvalidParameterException("unknown curve " + name);
- }
-
- group = possibleGroup;
- }
-
- @Override
- public void initialize(AlgorithmParameterSpec param, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- if (param instanceof ECParameterSpec) {
- ECParameterSpec ecParam = (ECParameterSpec) param;
-
- group = OpenSSLECGroupContext.getInstance(ecParam);
- } else if (param instanceof ECGenParameterSpec) {
- ECGenParameterSpec ecParam = (ECGenParameterSpec) param;
-
- final String curveName = ecParam.getName();
-
- /*
- * Store the group in a temporary variable until we know this is a
- * valid group.
- */
- final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext
- .getCurveByName(curveName);
- if (possibleGroup == null) {
- throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
- }
-
- group = possibleGroup;
- } else {
- throw new InvalidAlgorithmParameterException(
- "parameter must be ECParameterSpec or ECGenParameterSpec");
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECPointContext.java b/crypto/src/main/java/org/conscrypt/OpenSSLECPointContext.java
deleted file mode 100644
index 49bdaf1..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECPointContext.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.spec.ECPoint;
-
-final class OpenSSLECPointContext {
- private final OpenSSLECGroupContext group;
- private final long pointCtx;
-
- OpenSSLECPointContext(OpenSSLECGroupContext group, long pointCtx) {
- this.group = group;
- this.pointCtx = pointCtx;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (pointCtx != 0) {
- NativeCrypto.EC_POINT_clear_free(pointCtx);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof OpenSSLECPointContext)) {
- return false;
- }
-
- final OpenSSLECPointContext other = (OpenSSLECPointContext) o;
- if (!NativeCrypto.EC_GROUP_cmp(group.getContext(), other.group.getContext())) {
- return false;
- }
-
- return NativeCrypto.EC_POINT_cmp(group.getContext(), pointCtx, other.pointCtx);
- }
-
- public ECPoint getECPoint() {
- final byte[][] generatorCoords = NativeCrypto.EC_POINT_get_affine_coordinates(
- group.getContext(), pointCtx);
- final BigInteger x = new BigInteger(generatorCoords[0]);
- final BigInteger y = new BigInteger(generatorCoords[1]);
- return new ECPoint(x, y);
- }
-
- @Override
- public int hashCode() {
- // TODO Auto-generated method stub
- return super.hashCode();
- }
-
- public long getContext() {
- return pointCtx;
- }
-
- public static OpenSSLECPointContext getInstance(int curveType, OpenSSLECGroupContext group,
- ECPoint javaPoint) {
- OpenSSLECPointContext point = new OpenSSLECPointContext(group,
- NativeCrypto.EC_POINT_new(group.getContext()));
- NativeCrypto.EC_POINT_set_affine_coordinates(group.getContext(),
- point.getContext(), javaPoint.getAffineX().toByteArray(),
- javaPoint.getAffineY().toByteArray());
- return point;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECPrivateKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLECPrivateKey.java
deleted file mode 100644
index 4010ec5..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECPrivateKey.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.ECPrivateKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPrivateKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-public final class OpenSSLECPrivateKey implements ECPrivateKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = -4036633595001083922L;
-
- private static final String ALGORITHM = "EC";
-
- protected transient OpenSSLKey key;
-
- protected transient OpenSSLECGroupContext group;
-
- public OpenSSLECPrivateKey(OpenSSLECGroupContext group, OpenSSLKey key) {
- this.group = group;
- this.key = key;
- }
-
- public OpenSSLECPrivateKey(OpenSSLKey key) {
- final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
- this.group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
- this.key = key;
- }
-
- public OpenSSLECPrivateKey(ECPrivateKeySpec ecKeySpec) throws InvalidKeySpecException {
- try {
- group = OpenSSLECGroupContext.getInstance(ecKeySpec.getParams());
- final BigInteger privKey = ecKeySpec.getS();
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getContext(), 0,
- privKey.toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- public static OpenSSLKey getInstance(ECPrivateKey ecPrivateKey) throws InvalidKeyException {
- try {
- OpenSSLECGroupContext group = OpenSSLECGroupContext.getInstance(ecPrivateKey
- .getParams());
- final BigInteger privKey = ecPrivateKey.getS();
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getContext(), 0,
- privKey.toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public String getAlgorithm() {
- return ALGORITHM;
- }
-
- @Override
- public String getFormat() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return "PKCS#8";
- }
-
- @Override
- public byte[] getEncoded() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext());
- }
-
- @Override
- public ECParameterSpec getParams() {
- return group.getECParameterSpec();
- }
-
- @Override
- public BigInteger getS() {
- if (key.isEngineBased()) {
- throw new UnsupportedOperationException("private key value S cannot be extracted");
- }
-
- return getPrivateKey();
- }
-
- private BigInteger getPrivateKey() {
- return new BigInteger(NativeCrypto.EC_KEY_get_private_key(key.getPkeyContext()));
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLECPrivateKey) {
- OpenSSLECPrivateKey other = (OpenSSLECPrivateKey) o;
- return key.equals(other.key);
- }
-
- if (!(o instanceof ECPrivateKey)) {
- return false;
- }
-
- final ECPrivateKey other = (ECPrivateKey) o;
- if (!getPrivateKey().equals(other.getS())) {
- return false;
- }
-
- final ECParameterSpec spec = getParams();
- final ECParameterSpec otherSpec = other.getParams();
-
- return spec.getCurve().equals(otherSpec.getCurve())
- && spec.getGenerator().equals(otherSpec.getGenerator())
- && spec.getOrder().equals(otherSpec.getOrder())
- && spec.getCofactor() == otherSpec.getCofactor();
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext()));
- }
-
- @Override
- public String toString() {
- return NativeCrypto.EVP_PKEY_print_private(key.getPkeyContext());
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- byte[] encoded = (byte[]) stream.readObject();
-
- key = new OpenSSLKey(NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(encoded));
-
- final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
- group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (key.isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- stream.defaultWriteObject();
- stream.writeObject(getEncoded());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECPublicKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLECPublicKey.java
deleted file mode 100644
index 8f3a0c6..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECPublicKey.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-public final class OpenSSLECPublicKey implements ECPublicKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 3215842926808298020L;
-
- private static final String ALGORITHM = "EC";
-
- protected transient OpenSSLKey key;
-
- protected transient OpenSSLECGroupContext group;
-
- public OpenSSLECPublicKey(OpenSSLECGroupContext group, OpenSSLKey key) {
- this.group = group;
- this.key = key;
- }
-
- public OpenSSLECPublicKey(OpenSSLKey key) {
- final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
- this.group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
- this.key = key;
- }
-
- public OpenSSLECPublicKey(ECPublicKeySpec ecKeySpec) throws InvalidKeySpecException {
- try {
- group = OpenSSLECGroupContext.getInstance(ecKeySpec.getParams());
- OpenSSLECPointContext pubKey = OpenSSLECPointContext.getInstance(
- NativeCrypto.get_EC_GROUP_type(group.getContext()), group, ecKeySpec.getW());
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getContext(),
- pubKey.getContext(), null));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- public static OpenSSLKey getInstance(ECPublicKey ecPublicKey) throws InvalidKeyException {
- try {
- OpenSSLECGroupContext group = OpenSSLECGroupContext
- .getInstance(ecPublicKey.getParams());
- OpenSSLECPointContext pubKey = OpenSSLECPointContext.getInstance(
- NativeCrypto.get_EC_GROUP_type(group.getContext()), group, ecPublicKey.getW());
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getContext(),
- pubKey.getContext(), null));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public String getAlgorithm() {
- return ALGORITHM;
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return NativeCrypto.i2d_PUBKEY(key.getPkeyContext());
- }
-
- @Override
- public ECParameterSpec getParams() {
- return group.getECParameterSpec();
- }
-
- private ECPoint getPublicKey() {
- final OpenSSLECPointContext pubKey = new OpenSSLECPointContext(group,
- NativeCrypto.EC_KEY_get_public_key(key.getPkeyContext()));
-
- return pubKey.getECPoint();
- }
-
- @Override
- public ECPoint getW() {
- return getPublicKey();
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLECPrivateKey) {
- OpenSSLECPrivateKey other = (OpenSSLECPrivateKey) o;
- return key.equals(other.key);
- }
-
- if (!(o instanceof ECPublicKey)) {
- return false;
- }
-
- final ECPublicKey other = (ECPublicKey) o;
- if (!getPublicKey().equals(other.getW())) {
- return false;
- }
-
- final ECParameterSpec spec = getParams();
- final ECParameterSpec otherSpec = other.getParams();
-
- return spec.getCurve().equals(otherSpec.getCurve())
- && spec.getGenerator().equals(otherSpec.getGenerator())
- && spec.getOrder().equals(otherSpec.getOrder())
- && spec.getCofactor() == otherSpec.getCofactor();
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(NativeCrypto.i2d_PUBKEY(key.getPkeyContext()));
- }
-
- @Override
- public String toString() {
- return NativeCrypto.EVP_PKEY_print_public(key.getPkeyContext());
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- byte[] encoded = (byte[]) stream.readObject();
-
- key = new OpenSSLKey(NativeCrypto.d2i_PUBKEY(encoded));
-
- final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
- group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (key.isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- stream.defaultWriteObject();
- stream.writeObject(getEncoded());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLEngine.java b/crypto/src/main/java/org/conscrypt/OpenSSLEngine.java
deleted file mode 100644
index 380e73f..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLEngine.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import javax.crypto.SecretKey;
-
-public class OpenSSLEngine {
- static {
- NativeCrypto.ENGINE_load_dynamic();
- }
-
- private static final Object mLoadingLock = new Object();
-
- /** The ENGINE's native handle. */
- private final long ctx;
-
- public static OpenSSLEngine getInstance(String engine) throws IllegalArgumentException {
- if (engine == null) {
- throw new NullPointerException("engine == null");
- }
-
- final long engineCtx;
- synchronized (mLoadingLock) {
- engineCtx = NativeCrypto.ENGINE_by_id(engine);
- if (engineCtx == 0) {
- throw new IllegalArgumentException("Unknown ENGINE id: " + engine);
- }
-
- NativeCrypto.ENGINE_add(engineCtx);
- }
-
- return new OpenSSLEngine(engineCtx);
- }
-
- private OpenSSLEngine(long engineCtx) {
- ctx = engineCtx;
-
- if (NativeCrypto.ENGINE_init(engineCtx) == 0) {
- NativeCrypto.ENGINE_free(engineCtx);
- throw new IllegalArgumentException("Could not initialize engine");
- }
- }
-
- public PrivateKey getPrivateKeyById(String id) throws InvalidKeyException {
- if (id == null) {
- throw new NullPointerException("id == null");
- }
-
- final long keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
- if (keyRef == 0) {
- return null;
- }
-
- OpenSSLKey pkey = new OpenSSLKey(keyRef, this, id);
- try {
- return pkey.getPrivateKey();
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- public SecretKey getSecretKeyById(String id, String algorithm) throws InvalidKeyException {
- if (id == null) {
- throw new NullPointerException("id == null");
- }
-
- final long keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
- if (keyRef == 0) {
- return null;
- }
-
- OpenSSLKey pkey = new OpenSSLKey(keyRef, this, id);
- try {
- return pkey.getSecretKey(algorithm);
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- long getEngineContext() {
- return ctx;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- NativeCrypto.ENGINE_finish(ctx);
- NativeCrypto.ENGINE_free(ctx);
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof OpenSSLEngine)) {
- return false;
- }
-
- OpenSSLEngine other = (OpenSSLEngine) o;
-
- if (other.getEngineContext() == ctx) {
- return true;
- }
-
- final String id = NativeCrypto.ENGINE_get_id(ctx);
- if (id == null) {
- return false;
- }
-
- return id.equals(NativeCrypto.ENGINE_get_id(other.getEngineContext()));
- }
-
- @Override
- public int hashCode() {
- return (int) ctx;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLKey.java
deleted file mode 100644
index fa9a258..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLKey.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import javax.crypto.SecretKey;
-
-public class OpenSSLKey {
- private final long ctx;
-
- private final OpenSSLEngine engine;
-
- private final String alias;
-
- public OpenSSLKey(long ctx) {
- this.ctx = ctx;
- engine = null;
- alias = null;
- }
-
- public OpenSSLKey(long ctx, OpenSSLEngine engine, String alias) {
- this.ctx = ctx;
- this.engine = engine;
- this.alias = alias;
- }
-
- /**
- * Returns the raw pointer to the EVP_PKEY context for use in JNI calls. The
- * life cycle of this native pointer is managed by the {@code OpenSSLKey}
- * instance and must not be destroyed or freed by users of this API.
- */
- public long getPkeyContext() {
- return ctx;
- }
-
- OpenSSLEngine getEngine() {
- return engine;
- }
-
- boolean isEngineBased() {
- return engine != null;
- }
-
- public String getAlias() {
- return alias;
- }
-
- public static OpenSSLKey fromPrivateKey(PrivateKey key) throws InvalidKeyException {
- if (key instanceof OpenSSLKeyHolder) {
- return ((OpenSSLKeyHolder) key).getOpenSSLKey();
- }
-
- if ("PKCS#8".equals(key.getFormat())) {
- return new OpenSSLKey(NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(key.getEncoded()));
- } else {
- throw new InvalidKeyException("Unknown key format " + key.getFormat());
- }
- }
-
- public PublicKey getPublicKey() throws NoSuchAlgorithmException {
- switch (NativeCrypto.EVP_PKEY_type(ctx)) {
- case NativeCrypto.EVP_PKEY_RSA:
- return new OpenSSLRSAPublicKey(this);
- case NativeCrypto.EVP_PKEY_DSA:
- return new OpenSSLDSAPublicKey(this);
- case NativeCrypto.EVP_PKEY_EC:
- return new OpenSSLECPublicKey(this);
- default:
- throw new NoSuchAlgorithmException("unknown PKEY type");
- }
- }
-
- static PublicKey getPublicKey(X509EncodedKeySpec keySpec, int type)
- throws InvalidKeySpecException {
- X509EncodedKeySpec x509KeySpec = (X509EncodedKeySpec) keySpec;
-
- final OpenSSLKey key;
- try {
- key = new OpenSSLKey(NativeCrypto.d2i_PUBKEY(x509KeySpec.getEncoded()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
-
- if (NativeCrypto.EVP_PKEY_type(key.getPkeyContext()) != type) {
- throw new InvalidKeySpecException("Unexpected key type");
- }
-
- try {
- return key.getPublicKey();
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- public PrivateKey getPrivateKey() throws NoSuchAlgorithmException {
- switch (NativeCrypto.EVP_PKEY_type(ctx)) {
- case NativeCrypto.EVP_PKEY_RSA:
- return new OpenSSLRSAPrivateKey(this);
- case NativeCrypto.EVP_PKEY_DSA:
- return new OpenSSLDSAPrivateKey(this);
- case NativeCrypto.EVP_PKEY_EC:
- return new OpenSSLECPrivateKey(this);
- default:
- throw new NoSuchAlgorithmException("unknown PKEY type");
- }
- }
-
- static PrivateKey getPrivateKey(PKCS8EncodedKeySpec keySpec, int type)
- throws InvalidKeySpecException {
- PKCS8EncodedKeySpec pkcs8KeySpec = (PKCS8EncodedKeySpec) keySpec;
-
- final OpenSSLKey key;
- try {
- key = new OpenSSLKey(NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(pkcs8KeySpec.getEncoded()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
-
- if (NativeCrypto.EVP_PKEY_type(key.getPkeyContext()) != type) {
- throw new InvalidKeySpecException("Unexpected key type");
- }
-
- try {
- return key.getPrivateKey();
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- public SecretKey getSecretKey(String algorithm) throws NoSuchAlgorithmException {
- switch (NativeCrypto.EVP_PKEY_type(ctx)) {
- case NativeCrypto.EVP_PKEY_HMAC:
- case NativeCrypto.EVP_PKEY_CMAC:
- return new OpenSSLSecretKey(algorithm, this);
- default:
- throw new NoSuchAlgorithmException("unknown PKEY type");
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof OpenSSLKey)) {
- return false;
- }
-
- OpenSSLKey other = (OpenSSLKey) o;
- if (ctx == other.getPkeyContext()) {
- return true;
- }
-
- /*
- * ENGINE-based keys must be checked in a special way.
- */
- if (engine == null) {
- if (other.getEngine() != null) {
- return false;
- }
- } else if (!engine.equals(other.getEngine())) {
- return false;
- } else {
- if (alias != null) {
- return alias.equals(other.getAlias());
- } else if (other.getAlias() != null) {
- return false;
- }
- }
-
- return NativeCrypto.EVP_PKEY_cmp(ctx, other.getPkeyContext()) == 1;
- }
-
- @Override
- public int hashCode() {
- int hash = 1;
- hash = hash * 17 + (int) ctx;
- hash = hash * 31 + (int) (engine == null ? 0 : engine.getEngineContext());
- return hash;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLKeyHolder.java b/crypto/src/main/java/org/conscrypt/OpenSSLKeyHolder.java
deleted file mode 100644
index 09af21c..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLKeyHolder.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-public interface OpenSSLKeyHolder {
- public OpenSSLKey getOpenSSLKey();
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLMac.java b/crypto/src/main/java/org/conscrypt/OpenSSLMac.java
deleted file mode 100644
index 824e6b9..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLMac.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.MacSpi;
-import javax.crypto.SecretKey;
-
-public abstract class OpenSSLMac extends MacSpi {
- private final OpenSSLDigestContext ctx = new OpenSSLDigestContext(
- NativeCrypto.EVP_MD_CTX_create());
-
- /**
- * Holds the EVP_MD for the hashing algorithm, e.g.
- * EVP_get_digestbyname("sha1");
- */
- private final long evp_md;
-
- /**
- * The key type of the secret key.
- */
- private final int evp_pkey_type;
-
- /**
- * The secret key used in this keyed MAC.
- */
- private OpenSSLKey macKey;
-
- /**
- * Holds the output size of the message digest.
- */
- private final int size;
-
- /**
- * Holds a dummy buffer for writing single bytes to the digest.
- */
- private final byte[] singleByte = new byte[1];
-
- private OpenSSLMac(long evp_md, int size, int evp_pkey_type) {
- this.evp_md = evp_md;
- this.size = size;
- this.evp_pkey_type = evp_pkey_type;
- }
-
- @Override
- protected int engineGetMacLength() {
- return size;
- }
-
- @Override
- protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
- InvalidAlgorithmParameterException {
- if (!(key instanceof SecretKey)) {
- throw new InvalidKeyException("key must be a SecretKey");
- }
-
- if (params != null) {
- throw new InvalidAlgorithmParameterException("unknown parameter type");
- }
-
- if (key instanceof OpenSSLKeyHolder) {
- macKey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
- } else {
- final byte[] keyBytes = key.getEncoded();
- if (keyBytes == null) {
- throw new InvalidKeyException("key cannot be encoded");
- }
-
- macKey = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(evp_pkey_type, keyBytes));
- }
-
- NativeCrypto.EVP_MD_CTX_init(ctx.getContext());
-
- reset();
- }
-
- private void reset() {
- NativeCrypto.EVP_DigestSignInit(ctx.getContext(), evp_md, macKey.getPkeyContext());
- }
-
- @Override
- protected void engineUpdate(byte input) {
- singleByte[0] = input;
- engineUpdate(singleByte, 0, 1);
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- NativeCrypto.EVP_DigestUpdate(ctx.getContext(), input, offset, len);
- }
-
- @Override
- protected byte[] engineDoFinal() {
- final byte[] output = NativeCrypto.EVP_DigestSignFinal(ctx.getContext());
- reset();
- return output;
- }
-
- @Override
- protected void engineReset() {
- reset();
- }
-
- public static class HmacMD5 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacMD5() {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-
- public static class HmacSHA1 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacSHA1() {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-
- public static class HmacSHA256 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacSHA256() throws NoSuchAlgorithmException {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-
- public static class HmacSHA384 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacSHA384() throws NoSuchAlgorithmException {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-
- public static class HmacSHA512 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacSHA512() {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLMessageDigestJDK.java b/crypto/src/main/java/org/conscrypt/OpenSSLMessageDigestJDK.java
deleted file mode 100644
index 763ff65..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLMessageDigestJDK.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * Implements the JDK MessageDigest interface using OpenSSL's EVP API.
- */
-public class OpenSSLMessageDigestJDK extends MessageDigest implements Cloneable {
-
- /**
- * Holds a pointer to the native message digest context.
- */
- private long ctx;
-
- /**
- * Holds the EVP_MD for the hashing algorithm, e.g. EVP_get_digestbyname("sha1");
- */
- private final long evp_md;
-
- /**
- * Holds the output size of the message digest.
- */
- private final int size;
-
- /**
- * Holds a dummy buffer for writing single bytes to the digest.
- */
- private final byte[] singleByte = new byte[1];
-
- /**
- * Creates a new OpenSSLMessageDigest instance for the given algorithm
- * name.
- */
- private OpenSSLMessageDigestJDK(String algorithm, long evp_md, int size)
- throws NoSuchAlgorithmException {
- super(algorithm);
- this.evp_md = evp_md;
- this.size = size;
- }
-
- @Override
- protected void engineReset() {
- free();
- }
-
- @Override
- protected int engineGetDigestLength() {
- return size;
- }
-
- @Override
- protected void engineUpdate(byte input) {
- singleByte[0] = input;
- engineUpdate(singleByte, 0, 1);
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- NativeCrypto.EVP_DigestUpdate(getCtx(), input, offset, len);
- }
-
- @Override
- protected byte[] engineDigest() {
- byte[] result = new byte[size];
- NativeCrypto.EVP_DigestFinal(getCtx(), result, 0);
- ctx = 0; // EVP_DigestFinal frees the context as a side effect
- return result;
- }
-
- public Object clone() throws CloneNotSupportedException {
- OpenSSLMessageDigestJDK d = (OpenSSLMessageDigestJDK) super.clone();
- d.ctx = NativeCrypto.EVP_MD_CTX_copy(getCtx());
- return d;
- }
-
- private long getCtx() {
- if (ctx == 0) {
- ctx = NativeCrypto.EVP_DigestInit(evp_md);
- }
- return ctx;
- }
-
- private void free() {
- if (ctx != 0) {
- NativeCrypto.EVP_MD_CTX_destroy(ctx);
- ctx = 0;
- }
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- free();
- } finally {
- super.finalize();
- }
- }
-
- public static class MD5 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public MD5() throws NoSuchAlgorithmException {
- super("MD5",EVP_MD, SIZE);
- }
- }
-
- public static class SHA1 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public SHA1() throws NoSuchAlgorithmException {
- super("SHA-1", EVP_MD, SIZE);
- }
- }
-
- public static class SHA256 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public SHA256() throws NoSuchAlgorithmException {
- super("SHA-256", EVP_MD, SIZE);
- }
- }
-
- public static class SHA384 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public SHA384() throws NoSuchAlgorithmException {
- super("SHA-384", EVP_MD, SIZE);
- }
- }
-
- public static class SHA512 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public SHA512() throws NoSuchAlgorithmException {
- super("SHA-512", EVP_MD, SIZE);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java b/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java
deleted file mode 100644
index 4055e50..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.Provider;
-
-/**
- * Provider that goes through OpenSSL for operations.
- * <p>
- * Every algorithm should have its IANA assigned OID as an alias. See the following URLs for each type:
- * <ul>
- * <li><a href="http://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xml">Hash functions</a></li>
- * <li><a href="http://www.iana.org/assignments/dssc/dssc.xml">Signature algorithms</a></li>
- * <li><a href="http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html">NIST cryptographic algorithms</a></li>
- * </ul>
- */
-public final class OpenSSLProvider extends Provider {
- private static final long serialVersionUID = 2996752495318905136L;
-
- public static final String PROVIDER_NAME = "AndroidOpenSSL";
-
- public OpenSSLProvider() {
- super(PROVIDER_NAME, 1.0, "Android's OpenSSL-backed security provider");
-
- // Make sure the platform is initialized.
- Platform.setup();
-
- final String prefix = getClass().getPackage().getName() + ".";
-
- /* === SSL Contexts === */
- final String classOpenSSLContextImpl = prefix + "OpenSSLContextImpl";
- put("SSLContext.SSL", classOpenSSLContextImpl);
- put("SSLContext.SSLv3", classOpenSSLContextImpl);
- put("SSLContext.TLS", classOpenSSLContextImpl);
- put("SSLContext.TLSv1", classOpenSSLContextImpl);
- put("SSLContext.TLSv1.1", classOpenSSLContextImpl);
- put("SSLContext.TLSv1.2", classOpenSSLContextImpl);
- put("SSLContext.Default", prefix + "DefaultSSLContextImpl");
-
- /* === Message Digests === */
- put("MessageDigest.SHA-1", prefix + "OpenSSLMessageDigestJDK$SHA1");
- put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
- put("Alg.Alias.MessageDigest.SHA", "SHA-1");
- put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA-1");
-
- put("MessageDigest.SHA-256", prefix + "OpenSSLMessageDigestJDK$SHA256");
- put("Alg.Alias.MessageDigest.SHA256", "SHA-256");
- put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256");
-
- put("MessageDigest.SHA-384", prefix + "OpenSSLMessageDigestJDK$SHA384");
- put("Alg.Alias.MessageDigest.SHA384", "SHA-384");
- put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.2", "SHA-384");
-
- put("MessageDigest.SHA-512", prefix + "OpenSSLMessageDigestJDK$SHA512");
- put("Alg.Alias.MessageDigest.SHA512", "SHA-512");
- put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
-
- // iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) md5(5)
- put("MessageDigest.MD5", prefix + "OpenSSLMessageDigestJDK$MD5");
- put("Alg.Alias.MessageDigest.1.2.840.113549.2.5", "MD5");
-
- /* == KeyPairGenerators == */
- put("KeyPairGenerator.RSA", prefix + "OpenSSLRSAKeyPairGenerator");
- put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1.1", "RSA");
-
- put("KeyPairGenerator.DSA", prefix + "OpenSSLDSAKeyPairGenerator");
-
- put("KeyPairGenerator.EC", prefix + "OpenSSLECKeyPairGenerator");
-
- /* == KeyFactory == */
- put("KeyFactory.RSA", prefix + "OpenSSLRSAKeyFactory");
- put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.1", "RSA");
-
- put("KeyFactory.DSA", prefix + "OpenSSLDSAKeyFactory");
-
- put("KeyFactory.EC", prefix + "OpenSSLECKeyFactory");
-
- /* == KeyAgreement == */
- put("KeyAgreement.ECDH", prefix + "OpenSSLECDHKeyAgreement");
-
- /* == Signatures == */
- put("Signature.MD5WithRSA", prefix + "OpenSSLSignature$MD5RSA");
- put("Alg.Alias.Signature.MD5WithRSAEncryption", "MD5WithRSA");
- put("Alg.Alias.Signature.MD5/RSA", "MD5WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.2.5with1.2.840.113549.1.1.1", "MD5WithRSA");
-
- put("Signature.SHA1WithRSA", prefix + "OpenSSLSignature$SHA1RSA");
- put("Alg.Alias.Signature.SHA1WithRSAEncryption", "SHA1WithRSA");
- put("Alg.Alias.Signature.SHA1/RSA", "SHA1WithRSA");
- put("Alg.Alias.Signature.SHA-1/RSA", "SHA1WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1WithRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.1", "SHA1WithRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.5", "SHA1WithRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1WithRSA");
-
- put("Signature.SHA256WithRSA", prefix + "OpenSSLSignature$SHA256RSA");
- put("Alg.Alias.Signature.SHA256WithRSAEncryption", "SHA256WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256WithRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.1",
- "SHA256WithRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.11",
- "SHA256WithRSA");
-
- put("Signature.SHA384WithRSA", prefix + "OpenSSLSignature$SHA384RSA");
- put("Alg.Alias.Signature.SHA384WithRSAEncryption", "SHA384WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384WithRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.113549.1.1.1",
- "SHA384WithRSA");
-
- put("Signature.SHA512WithRSA", prefix + "OpenSSLSignature$SHA512RSA");
- put("Alg.Alias.Signature.SHA512WithRSAEncryption", "SHA512WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512WithRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.113549.1.1.1",
- "SHA512WithRSA");
-
- put("Signature.SHA1withDSA", prefix + "OpenSSLSignature$SHA1DSA");
- put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
- put("Alg.Alias.Signature.DSA", "SHA1withDSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10040.4.1", "SHA1withDSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10040.4.3", "SHA1withDSA");
- put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
- put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
-
- put("Signature.NONEwithRSA", prefix + "OpenSSLSignatureRawRSA");
-
- put("Signature.ECDSA", prefix + "OpenSSLSignature$SHA1ECDSA");
- put("Alg.Alias.Signature.SHA1withECDSA", "ECDSA");
- put("Alg.Alias.Signature.ECDSAwithSHA1", "ECDSA");
- // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA1(1)
- put("Alg.Alias.Signature.1.2.840.10045.4.1", "ECDSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10045.2.1", "ECDSA");
-
- // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA2(3)
- put("Signature.SHA256withECDSA", prefix + "OpenSSLSignature$SHA256ECDSA");
- // ecdsa-with-SHA256(2)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.2", "SHA256withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.10045.2.1", "SHA256withECDSA");
-
- put("Signature.SHA384withECDSA", prefix + "OpenSSLSignature$SHA384ECDSA");
- // ecdsa-with-SHA384(3)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.3", "SHA384withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.10045.2.1", "SHA384withECDSA");
-
- put("Signature.SHA512withECDSA", prefix + "OpenSSLSignature$SHA512ECDSA");
- // ecdsa-with-SHA512(4)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.4", "SHA512withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.10045.2.1", "SHA512withECDSA");
-
- /* === SecureRandom === */
- /*
- * We have to specify SHA1PRNG because various documentation mentions
- * that algorithm by name instead of just recommending calling
- * "new SecureRandom()"
- */
- put("SecureRandom.SHA1PRNG", prefix + "OpenSSLRandom");
- put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
-
- /* === Cipher === */
- put("Cipher.RSA/ECB/NoPadding", prefix + "OpenSSLCipherRSA$Raw");
- put("Alg.Alias.Cipher.RSA/None/NoPadding", "RSA/ECB/NoPadding");
- put("Cipher.RSA/ECB/PKCS1Padding", prefix + "OpenSSLCipherRSA$PKCS1");
- put("Alg.Alias.Cipher.RSA/None/PKCS1Padding", "RSA/ECB/PKCS1Padding");
-
- /*
- * OpenSSL only supports a subset of modes, so we'll name them
- * explicitly here.
- */
- put("Cipher.AES/ECB/NoPadding", prefix + "OpenSSLCipher$AES$ECB$NoPadding");
- put("Cipher.AES/ECB/PKCS5Padding", prefix + "OpenSSLCipher$AES$ECB$PKCS5Padding");
- put("Cipher.AES/CBC/NoPadding", prefix + "OpenSSLCipher$AES$CBC$NoPadding");
- put("Cipher.AES/CBC/PKCS5Padding", prefix + "OpenSSLCipher$AES$CBC$PKCS5Padding");
- put("Cipher.AES/CFB/NoPadding", prefix + "OpenSSLCipher$AES$CFB$NoPadding");
- put("Cipher.AES/CFB/PKCS5Padding", prefix + "OpenSSLCipher$AES$CFB$PKCS5Padding");
- put("Cipher.AES/CTR/NoPadding", prefix + "OpenSSLCipher$AES$CTR$NoPadding");
- put("Cipher.AES/CTR/PKCS5Padding", prefix + "OpenSSLCipher$AES$CTR$PKCS5Padding");
- put("Cipher.AES/OFB/NoPadding", prefix + "OpenSSLCipher$AES$OFB$NoPadding");
- put("Cipher.AES/OFB/PKCS5Padding", prefix + "OpenSSLCipher$AES$OFB$PKCS5Padding");
-
- put("Cipher.DESEDE/CBC/NoPadding", prefix + "OpenSSLCipher$DESEDE$CBC$NoPadding");
- put("Cipher.DESEDE/CBC/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$CBC$PKCS5Padding");
- put("Cipher.DESEDE/CFB/NoPadding", prefix + "OpenSSLCipher$DESEDE$CFB$NoPadding");
- put("Cipher.DESEDE/CFB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$CFB$PKCS5Padding");
- put("Cipher.DESEDE/ECB/NoPadding", prefix + "OpenSSLCipher$DESEDE$ECB$NoPadding");
- put("Cipher.DESEDE/ECB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$ECB$PKCS5Padding");
- put("Cipher.DESEDE/OFB/NoPadding", prefix + "OpenSSLCipher$DESEDE$OFB$NoPadding");
- put("Cipher.DESEDE/OFB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$OFB$PKCS5Padding");
-
- put("Cipher.ARC4", prefix + "OpenSSLCipher$ARC4");
-
- /* === Mac === */
-
- put("Mac.HmacMD5", prefix + "OpenSSLMac$HmacMD5");
-
- // PKCS#2 - iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2)
- // http://www.oid-info.com/get/1.2.840.113549.2
-
- // HMAC-SHA-1 PRF (7)
- put("Mac.HmacSHA1", prefix + "OpenSSLMac$HmacSHA1");
- put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1");
- put("Alg.Alias.Mac.HMAC-SHA1", "HmacSHA1");
- put("Alg.Alias.Mac.HMAC/SHA1", "HmacSHA1");
-
- // id-hmacWithSHA256 (9)
- put("Mac.HmacSHA256", prefix + "OpenSSLMac$HmacSHA256");
- put("Alg.Alias.Mac.1.2.840.113549.2.9", "HmacSHA256");
- put("Alg.Alias.Mac.HMAC-SHA256", "HmacSHA256");
- put("Alg.Alias.Mac.HMAC/SHA256", "HmacSHA256");
-
- // id-hmacWithSHA384 (10)
- put("Mac.HmacSHA384", prefix + "OpenSSLMac$HmacSHA384");
- put("Alg.Alias.Mac.1.2.840.113549.2.10", "HmacSHA384");
- put("Alg.Alias.Mac.HMAC-SHA384", "HmacSHA384");
- put("Alg.Alias.Mac.HMAC/SHA384", "HmacSHA384");
-
- // id-hmacWithSHA384 (11)
- put("Mac.HmacSHA512", prefix + "OpenSSLMac$HmacSHA512");
- put("Alg.Alias.Mac.1.2.840.113549.2.11", "HmacSHA512");
- put("Alg.Alias.Mac.HMAC-SHA512", "HmacSHA512");
- put("Alg.Alias.Mac.HMAC/SHA512", "HmacSHA512");
-
- /* === Certificate === */
-
- put("CertificateFactory.X509", prefix + "OpenSSLX509CertificateFactory");
- put("Alg.Alias.CertificateFactory.X.509", "X509");
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyFactory.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyFactory.java
deleted file mode 100644
index c785ac6..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyFactory.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactorySpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.RSAPrivateCrtKeySpec;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-public class OpenSSLRSAKeyFactory extends KeyFactorySpi {
-
- @Override
- protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof RSAPublicKeySpec) {
- return new OpenSSLRSAPublicKey((RSAPublicKeySpec) keySpec);
- } else if (keySpec instanceof X509EncodedKeySpec) {
- return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeCrypto.EVP_PKEY_RSA);
- }
- throw new InvalidKeySpecException("Must use RSAPublicKeySpec or X509EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof RSAPrivateCrtKeySpec) {
- return new OpenSSLRSAPrivateCrtKey((RSAPrivateCrtKeySpec) keySpec);
- } else if (keySpec instanceof RSAPrivateKeySpec) {
- return new OpenSSLRSAPrivateKey((RSAPrivateKeySpec) keySpec);
- } else if (keySpec instanceof PKCS8EncodedKeySpec) {
- return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
- NativeCrypto.EVP_PKEY_RSA);
- }
- throw new InvalidKeySpecException("Must use RSAPublicKeySpec or PKCS8EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
- throws InvalidKeySpecException {
- if (key == null) {
- throw new InvalidKeySpecException("key == null");
- }
-
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (!"RSA".equals(key.getAlgorithm())) {
- throw new InvalidKeySpecException("Key must be a RSA key");
- }
-
- if (key instanceof RSAPublicKey && RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
- RSAPublicKey rsaKey = (RSAPublicKey) key;
- return (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
- } else if (key instanceof PublicKey && RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid X.509 encoding");
- }
- RSAPublicKey rsaKey =
- (RSAPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
- return (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
- } else if (key instanceof RSAPrivateCrtKey
- && RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
- RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
- return (T) new RSAPrivateCrtKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent(),
- rsaKey.getPrivateExponent(), rsaKey.getPrimeP(), rsaKey.getPrimeQ(),
- rsaKey.getPrimeExponentP(), rsaKey.getPrimeExponentQ(),
- rsaKey.getCrtCoefficient());
- } else if (key instanceof RSAPrivateCrtKey
- && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
- return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
- } else if (key instanceof RSAPrivateKey
- && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- RSAPrivateKey rsaKey = (RSAPrivateKey) key;
- return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
- } else if (key instanceof PrivateKey
- && RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
- }
- RSAPrivateKey privKey =
- (RSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- if (privKey instanceof RSAPrivateCrtKey) {
- RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) privKey;
- return (T) new RSAPrivateCrtKeySpec(rsaKey.getModulus(),
- rsaKey.getPublicExponent(), rsaKey.getPrivateExponent(),
- rsaKey.getPrimeP(), rsaKey.getPrimeQ(), rsaKey.getPrimeExponentP(),
- rsaKey.getPrimeExponentQ(), rsaKey.getCrtCoefficient());
- } else {
- throw new InvalidKeySpecException("Encoded key is not an RSAPrivateCrtKey");
- }
- } else if (key instanceof PrivateKey && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
- }
- RSAPrivateKey rsaKey =
- (RSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
- } else if (key instanceof PrivateKey
- && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new PKCS8EncodedKeySpec(encoded);
- } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be X.509; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new X509EncodedKeySpec(encoded);
- } else {
- throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
- + key.getClass().getName() + ", keySpec=" + keySpec.getName());
- }
- }
-
- @Override
- protected Key engineTranslateKey(Key key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
-
- if ((key instanceof OpenSSLRSAPublicKey) || (key instanceof OpenSSLRSAPrivateKey)) {
- return key;
- } else if (key instanceof RSAPublicKey) {
- RSAPublicKey rsaKey = (RSAPublicKey) key;
-
- try {
- return engineGeneratePublic(new RSAPublicKeySpec(rsaKey.getModulus(),
- rsaKey.getPublicExponent()));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if (key instanceof RSAPrivateCrtKey) {
- RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
- BigInteger modulus = rsaKey.getModulus();
- BigInteger publicExponent = rsaKey.getPublicExponent();
- BigInteger privateExponent = rsaKey.getPrivateExponent();
- BigInteger primeP = rsaKey.getPrimeP();
- BigInteger primeQ = rsaKey.getPrimeQ();
- BigInteger primeExponentP = rsaKey.getPrimeExponentP();
- BigInteger primeExponentQ = rsaKey.getPrimeExponentQ();
- BigInteger crtCoefficient = rsaKey.getCrtCoefficient();
-
- try {
- return engineGeneratePrivate(new RSAPrivateCrtKeySpec(modulus, publicExponent,
- privateExponent, primeP, primeQ, primeExponentP, primeExponentQ,
- crtCoefficient));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if (key instanceof RSAPrivateKey) {
- RSAPrivateKey rsaKey = (RSAPrivateKey) key;
- BigInteger modulus = rsaKey.getModulus();
- BigInteger privateExponent = rsaKey.getPrivateExponent();
-
- try {
- return engineGeneratePrivate(new RSAPrivateKeySpec(modulus, privateExponent));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PrivateKey) && ("PKCS#8".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PublicKey) && ("X.509".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePublic(new X509EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else {
- throw new InvalidKeyException("Key must be an RSA public or private key; was "
- + key.getClass().getName());
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyPairGenerator.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyPairGenerator.java
deleted file mode 100644
index a00219f..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyPairGenerator.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGeneratorSpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
-
-public class OpenSSLRSAKeyPairGenerator extends KeyPairGeneratorSpi {
- /**
- * Default modulus size is 0x10001 (65537)
- */
- private byte[] publicExponent = new byte[] {
- 0x01, 0x00, 0x01
- };
-
- /**
- * Default RSA key size 2048 bits.
- */
- private int modulusBits = 2048;
-
- @Override
- public KeyPair generateKeyPair() {
- final OpenSSLKey key = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(modulusBits,
- publicExponent));
-
- PrivateKey privKey = OpenSSLRSAPrivateKey.getInstance(key);
- PublicKey pubKey = new OpenSSLRSAPublicKey(key);
-
- return new KeyPair(pubKey, privKey);
- }
-
- @Override
- public void initialize(int keysize, SecureRandom random) {
- this.modulusBits = keysize;
- }
-
- @Override
- public void initialize(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- if (!(params instanceof RSAKeyGenParameterSpec)) {
- throw new InvalidAlgorithmParameterException("Only RSAKeyGenParameterSpec supported");
- }
-
- RSAKeyGenParameterSpec spec = (RSAKeyGenParameterSpec) params;
-
- final BigInteger publicExponent = spec.getPublicExponent();
- if (publicExponent != null) {
- this.publicExponent = publicExponent.toByteArray();
- }
-
- this.modulusBits = spec.getKeysize();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java
deleted file mode 100644
index 1cbf5de..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.RSAPrivateCrtKeySpec;
-
-public class OpenSSLRSAPrivateCrtKey extends OpenSSLRSAPrivateKey implements RSAPrivateCrtKey {
- private static final long serialVersionUID = 3785291944868707197L;
-
- private BigInteger publicExponent;
-
- private BigInteger primeP;
-
- private BigInteger primeQ;
-
- private BigInteger primeExponentP;
-
- private BigInteger primeExponentQ;
-
- private BigInteger crtCoefficient;
-
- OpenSSLRSAPrivateCrtKey(OpenSSLKey key) {
- super(key);
- }
-
- OpenSSLRSAPrivateCrtKey(OpenSSLKey key, byte[][] params) {
- super(key, params);
- }
-
- public OpenSSLRSAPrivateCrtKey(RSAPrivateCrtKeySpec rsaKeySpec) throws InvalidKeySpecException {
- super(init(rsaKeySpec));
- }
-
- private static OpenSSLKey init(RSAPrivateCrtKeySpec rsaKeySpec) throws InvalidKeySpecException {
- BigInteger modulus = rsaKeySpec.getModulus();
- BigInteger privateExponent = rsaKeySpec.getPrivateExponent();
-
- if (modulus == null) {
- throw new InvalidKeySpecException("modulus == null");
- } else if (privateExponent == null) {
- throw new InvalidKeySpecException("privateExponent == null");
- }
-
- try {
- /*
- * OpenSSL uses the public modulus to do RSA blinding. If
- * the public modulus is not available, the call to
- * EVP_PKEY_new_RSA will turn off blinding for this key
- * instance.
- */
- final BigInteger publicExponent = rsaKeySpec.getPublicExponent();
- final BigInteger primeP = rsaKeySpec.getPrimeP();
- final BigInteger primeQ = rsaKeySpec.getPrimeQ();
- final BigInteger primeExponentP = rsaKeySpec.getPrimeExponentP();
- final BigInteger primeExponentQ = rsaKeySpec.getPrimeExponentQ();
- final BigInteger crtCoefficient = rsaKeySpec.getCrtCoefficient();
-
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- publicExponent == null ? null : publicExponent.toByteArray(),
- privateExponent.toByteArray(),
- primeP == null ? null : primeP.toByteArray(),
- primeQ == null ? null : primeQ.toByteArray(),
- primeExponentP == null ? null : primeExponentP.toByteArray(),
- primeExponentQ == null ? null : primeExponentQ.toByteArray(),
- crtCoefficient == null ? null : crtCoefficient.toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- static OpenSSLKey getInstance(RSAPrivateCrtKey rsaPrivateKey) throws InvalidKeyException {
- BigInteger modulus = rsaPrivateKey.getModulus();
- BigInteger privateExponent = rsaPrivateKey.getPrivateExponent();
-
- if (modulus == null) {
- throw new InvalidKeyException("modulus == null");
- } else if (privateExponent == null) {
- throw new InvalidKeyException("privateExponent == null");
- }
-
- try {
- /*
- * OpenSSL uses the public modulus to do RSA blinding. If
- * the public modulus is not available, the call to
- * EVP_PKEY_new_RSA will turn off blinding for this key
- * instance.
- */
- final BigInteger publicExponent = rsaPrivateKey.getPublicExponent();
- final BigInteger primeP = rsaPrivateKey.getPrimeP();
- final BigInteger primeQ = rsaPrivateKey.getPrimeQ();
- final BigInteger primeExponentP = rsaPrivateKey.getPrimeExponentP();
- final BigInteger primeExponentQ = rsaPrivateKey.getPrimeExponentQ();
- final BigInteger crtCoefficient = rsaPrivateKey.getCrtCoefficient();
-
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- publicExponent == null ? null : publicExponent.toByteArray(),
- privateExponent.toByteArray(),
- primeP == null ? null : primeP.toByteArray(),
- primeQ == null ? null : primeQ.toByteArray(),
- primeExponentP == null ? null : primeExponentP.toByteArray(),
- primeExponentQ == null ? null : primeExponentQ.toByteArray(),
- crtCoefficient == null ? null : crtCoefficient.toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- synchronized void readParams(byte[][] params) {
- super.readParams(params);
- // params[0] read in super.readParams
- if (params[1] != null) {
- publicExponent = new BigInteger(params[1]);
- }
- // params[2] read in super.readParams
- if (params[3] != null) {
- primeP = new BigInteger(params[3]);
- }
- if (params[4] != null) {
- primeQ = new BigInteger(params[4]);
- }
- if (params[5] != null) {
- primeExponentP = new BigInteger(params[5]);
- }
- if (params[6] != null) {
- primeExponentQ = new BigInteger(params[6]);
- }
- if (params[7] != null) {
- crtCoefficient = new BigInteger(params[7]);
- }
- }
-
- @Override
- public BigInteger getPublicExponent() {
- ensureReadParams();
- return publicExponent;
- }
-
- @Override
- public BigInteger getPrimeP() {
- ensureReadParams();
- return primeP;
- }
-
- @Override
- public BigInteger getPrimeQ() {
- ensureReadParams();
- return primeQ;
- }
-
- @Override
- public BigInteger getPrimeExponentP() {
- ensureReadParams();
- return primeExponentP;
- }
-
- @Override
- public BigInteger getPrimeExponentQ() {
- ensureReadParams();
- return primeExponentQ;
- }
-
- @Override
- public BigInteger getCrtCoefficient() {
- ensureReadParams();
- return crtCoefficient;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLRSAPrivateKey) {
- OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
- return getOpenSSLKey().equals(other.getOpenSSLKey());
- }
-
- if (o instanceof RSAPrivateCrtKey) {
- ensureReadParams();
- RSAPrivateCrtKey other = (RSAPrivateCrtKey) o;
-
- if (getOpenSSLKey().isEngineBased()) {
- return getModulus().equals(other.getModulus())
- && publicExponent.equals(other.getPublicExponent());
- } else {
- return getModulus().equals(other.getModulus())
- && publicExponent.equals(other.getPublicExponent())
- && getPrivateExponent().equals(other.getPrivateExponent())
- && primeP.equals(other.getPrimeP()) && primeQ.equals(other.getPrimeQ())
- && primeExponentP.equals(other.getPrimeExponentP())
- && primeExponentQ.equals(other.getPrimeExponentQ())
- && crtCoefficient.equals(other.getCrtCoefficient());
- }
- } else if (o instanceof RSAPrivateKey) {
- ensureReadParams();
- RSAPrivateKey other = (RSAPrivateKey) o;
-
- if (getOpenSSLKey().isEngineBased()) {
- return getModulus().equals(other.getModulus());
- } else {
- return getModulus().equals(other.getModulus())
- && getPrivateExponent().equals(other.getPrivateExponent());
- }
- }
-
- return false;
- }
-
- @Override
- public final int hashCode() {
- int hashCode = super.hashCode();
- if (publicExponent != null) {
- hashCode ^= publicExponent.hashCode();
- }
- return hashCode;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateCrtKey{");
-
- final boolean engineBased = getOpenSSLKey().isEngineBased();
- if (engineBased) {
- sb.append("key=");
- sb.append(getOpenSSLKey());
- sb.append('}');
- }
-
- ensureReadParams();
- sb.append("modulus=");
- sb.append(getModulus().toString(16));
- sb.append(',');
-
- if (publicExponent != null) {
- sb.append("publicExponent=");
- sb.append(publicExponent.toString(16));
- sb.append(',');
- }
-
- if (!engineBased) {
- sb.append("privateExponent=");
- sb.append(getPrivateExponent().toString(16));
- sb.append(',');
- }
-
- if (primeP != null) {
- sb.append("primeP=");
- sb.append(primeP.toString(16));
- sb.append(',');
- }
-
- if (primeQ != null) {
- sb.append("primeQ=");
- sb.append(primeQ.toString(16));
- sb.append(',');
- }
-
- if (primeExponentP != null) {
- sb.append("primeExponentP=");
- sb.append(primeExponentP.toString(16));
- sb.append(',');
- }
-
- if (primeExponentQ != null) {
- sb.append("primeExponentQ=");
- sb.append(primeExponentQ.toString(16));
- sb.append(',');
- }
-
- if (crtCoefficient != null) {
- sb.append("crtCoefficient=");
- sb.append(crtCoefficient.toString(16));
- sb.append(',');
- }
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- publicExponent == null ? null : publicExponent.toByteArray(),
- privateExponent.toByteArray(),
- primeP == null ? null : primeP.toByteArray(),
- primeQ == null ? null : primeQ.toByteArray(),
- primeExponentP == null ? null : primeExponentP.toByteArray(),
- primeExponentQ == null ? null : primeExponentQ.toByteArray(),
- crtCoefficient == null ? null : crtCoefficient.toByteArray()));
- fetchedParams = true;
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- ensureReadParams();
- stream.defaultWriteObject();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java
deleted file mode 100644
index 20db293..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.RSAPrivateKeySpec;
-
-public class OpenSSLRSAPrivateKey implements RSAPrivateKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 4872170254439578735L;
-
- protected transient OpenSSLKey key;
-
- protected transient boolean fetchedParams;
-
- protected BigInteger modulus;
-
- protected BigInteger privateExponent;
-
- OpenSSLRSAPrivateKey(OpenSSLKey key) {
- this.key = key;
- }
-
- OpenSSLRSAPrivateKey(OpenSSLKey key, byte[][] params) {
- this(key);
- readParams(params);
- fetchedParams = true;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- public OpenSSLRSAPrivateKey(RSAPrivateKeySpec rsaKeySpec) throws InvalidKeySpecException {
- this(init(rsaKeySpec));
- }
-
- private static OpenSSLKey init(RSAPrivateKeySpec rsaKeySpec) throws InvalidKeySpecException {
- final BigInteger modulus = rsaKeySpec.getModulus();
- final BigInteger privateExponent = rsaKeySpec.getPrivateExponent();
-
- if (modulus == null) {
- throw new InvalidKeySpecException("modulus == null");
- } else if (privateExponent == null) {
- throw new InvalidKeySpecException("privateExponent == null");
- }
-
- try {
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- null,
- privateExponent.toByteArray(),
- null,
- null,
- null,
- null,
- null));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
- byte[][] params = NativeCrypto.get_RSA_private_params(key.getPkeyContext());
- if (params[1] != null) {
- return new OpenSSLRSAPrivateCrtKey(key, params);
- }
- return new OpenSSLRSAPrivateKey(key, params);
- }
-
- static OpenSSLKey getInstance(RSAPrivateKey rsaPrivateKey) throws InvalidKeyException {
- final BigInteger modulus = rsaPrivateKey.getModulus();
- final BigInteger privateExponent = rsaPrivateKey.getPrivateExponent();
-
- if (modulus == null) {
- throw new InvalidKeyException("modulus == null");
- } else if (privateExponent == null) {
- throw new InvalidKeyException("privateExponent == null");
- }
-
- try {
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- null,
- privateExponent.toByteArray(),
- null,
- null,
- null,
- null,
- null));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- synchronized final void ensureReadParams() {
- if (fetchedParams) {
- return;
- }
- readParams(NativeCrypto.get_RSA_private_params(key.getPkeyContext()));
- fetchedParams = true;
- }
-
- void readParams(byte[][] params) {
- if (params[0] == null) {
- throw new NullPointerException("modulus == null");
- } else if (params[2] == null && !key.isEngineBased()) {
- throw new NullPointerException("privateExponent == null");
- }
-
- modulus = new BigInteger(params[0]);
-
- // ENGINE-based keys are not guaranteed to have a private exponent.
- if (params[2] != null) {
- privateExponent = new BigInteger(params[2]);
- }
- }
-
- @Override
- public final BigInteger getPrivateExponent() {
- if (key.isEngineBased()) {
- throw new UnsupportedOperationException("private exponent cannot be extracted");
- }
-
- ensureReadParams();
- return privateExponent;
- }
-
- @Override
- public final BigInteger getModulus() {
- ensureReadParams();
- return modulus;
- }
-
- @Override
- public final byte[] getEncoded() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext());
- }
-
- public final String getFormat() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return "PKCS#8";
- }
-
- @Override
- public final String getAlgorithm() {
- return "RSA";
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLRSAPrivateKey) {
- OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
- return key.equals(other.getOpenSSLKey());
- }
-
- if (o instanceof RSAPrivateKey) {
- ensureReadParams();
- RSAPrivateKey other = (RSAPrivateKey) o;
-
- return modulus.equals(other.getModulus())
- && privateExponent.equals(other.getPrivateExponent());
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
- int hash = 1;
-
- hash = hash * 3 + modulus.hashCode();
- if (privateExponent != null) {
- hash = hash * 7 + privateExponent.hashCode();
- }
-
- return hash;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");
-
- final boolean engineBased = key.isEngineBased();
- if (engineBased) {
- sb.append("key=");
- sb.append(key);
- sb.append('}');
- }
-
- ensureReadParams();
- sb.append("modulus=");
- sb.append(modulus.toString(16));
- sb.append(',');
-
- if (!engineBased) {
- sb.append("privateExponent=");
- sb.append(privateExponent.toString(16));
- sb.append(',');
- }
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- null,
- privateExponent.toByteArray(),
- null,
- null,
- null,
- null,
- null));
- fetchedParams = true;
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- ensureReadParams();
- stream.defaultWriteObject();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPublicKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAPublicKey.java
deleted file mode 100644
index 4bbd7e3..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPublicKey.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.RSAPublicKeySpec;
-
-public class OpenSSLRSAPublicKey implements RSAPublicKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 123125005824688292L;
-
- private transient OpenSSLKey key;
-
- private BigInteger publicExponent;
-
- private BigInteger modulus;
-
- private transient boolean fetchedParams;
-
- OpenSSLRSAPublicKey(OpenSSLKey key) {
- this.key = key;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- OpenSSLRSAPublicKey(RSAPublicKeySpec spec) throws InvalidKeySpecException {
- try {
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- spec.getModulus().toByteArray(),
- spec.getPublicExponent().toByteArray(),
- null,
- null,
- null,
- null,
- null,
- null));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- static OpenSSLKey getInstance(RSAPublicKey rsaPublicKey) throws InvalidKeyException {
- try {
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- rsaPublicKey.getModulus().toByteArray(),
- rsaPublicKey.getPublicExponent().toByteArray(),
- null,
- null,
- null,
- null,
- null,
- null));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public String getAlgorithm() {
- return "RSA";
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return NativeCrypto.i2d_PUBKEY(key.getPkeyContext());
- }
-
- private void ensureReadParams() {
- if (fetchedParams) {
- return;
- }
-
- byte[][] params = NativeCrypto.get_RSA_public_params(key.getPkeyContext());
- modulus = new BigInteger(params[0]);
- publicExponent = new BigInteger(params[1]);
-
- fetchedParams = true;
- }
-
- @Override
- public BigInteger getModulus() {
- ensureReadParams();
- return modulus;
- }
-
- @Override
- public BigInteger getPublicExponent() {
- ensureReadParams();
- return publicExponent;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLRSAPublicKey) {
- OpenSSLRSAPublicKey other = (OpenSSLRSAPublicKey) o;
-
- /*
- * We can shortcut the true case, but it still may be equivalent but
- * different copies.
- */
- if (key.equals(other.getOpenSSLKey())) {
- return true;
- }
- }
-
- if (!(o instanceof RSAPublicKey)) {
- return false;
- }
-
- ensureReadParams();
-
- RSAPublicKey other = (RSAPublicKey) o;
- return modulus.equals(other.getModulus())
- && publicExponent.equals(other.getPublicExponent());
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
-
- return modulus.hashCode() ^ publicExponent.hashCode();
- }
-
- @Override
- public String toString() {
- ensureReadParams();
-
- final StringBuilder sb = new StringBuilder("OpenSSLRSAPublicKey{");
- sb.append("modulus=");
- sb.append(modulus.toString(16));
- sb.append(',');
- sb.append("publicExponent=");
- sb.append(publicExponent.toString(16));
- sb.append('}');
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- publicExponent.toByteArray(),
- null,
- null,
- null,
- null,
- null,
- null));
- fetchedParams = true;
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- ensureReadParams();
- stream.defaultWriteObject();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRandom.java b/crypto/src/main/java/org/conscrypt/OpenSSLRandom.java
deleted file mode 100644
index 1683bb8..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRandom.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.Serializable;
-import java.security.SecureRandomSpi;
-
-public class OpenSSLRandom extends SecureRandomSpi implements Serializable {
- private static final long serialVersionUID = 8506210602917522860L;
-
- @Override
- protected void engineSetSeed(byte[] seed) {
- NativeCrypto.RAND_seed(seed);
- }
-
- @Override
- protected void engineNextBytes(byte[] bytes) {
- NativeCrypto.RAND_bytes(bytes);
- }
-
- @Override
- protected byte[] engineGenerateSeed(int numBytes) {
- byte[] output = new byte[numBytes];
- NativeCrypto.RAND_bytes(output);
- return output;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSecretKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLSecretKey.java
deleted file mode 100644
index 193356e..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSecretKey.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.security.InvalidKeyException;
-import java.util.Arrays;
-
-import javax.crypto.SecretKey;
-
-public class OpenSSLSecretKey implements SecretKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 1831053062911514589L;
-
- private final String algorithm;
- private final int type;
- private final byte[] encoded;
-
- private transient OpenSSLKey key;
-
- public OpenSSLSecretKey(String algorithm, byte[] encoded) {
- this.algorithm = algorithm;
- this.encoded = encoded;
-
- type = NativeCrypto.EVP_PKEY_HMAC;
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(type, encoded));
- }
-
- public OpenSSLSecretKey(String algorithm, OpenSSLKey key) {
- this.algorithm = algorithm;
- this.key = key;
-
- type = NativeCrypto.EVP_PKEY_type(key.getPkeyContext());
- encoded = null;
- }
-
- public static OpenSSLKey getInstance(SecretKey key) throws InvalidKeyException {
- try {
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(NativeCrypto.EVP_PKEY_HMAC,
- key.getEncoded()));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public String getAlgorithm() {
- return algorithm;
- }
-
- @Override
- public String getFormat() {
- if (key.isEngineBased()) {
- return null;
- }
-
- return "RAW";
- }
-
- @Override
- public byte[] getEncoded() {
- if (key.isEngineBased()) {
- return null;
- }
-
- return encoded;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof SecretKey)) {
- return false;
- }
-
- SecretKey other = (SecretKey) o;
- if (!algorithm.equals(other.getAlgorithm())) {
- return false;
- }
-
- if (o instanceof OpenSSLSecretKey) {
- OpenSSLSecretKey otherOpenSSL = (OpenSSLSecretKey) o;
- return key.equals(otherOpenSSL.getOpenSSLKey());
- } else if (key.isEngineBased()) {
- return false;
- }
-
- if (!getFormat().equals(other.getFormat())) {
- return false;
- }
-
- return Arrays.equals(encoded, other.getEncoded());
- }
-
- @Override
- public int hashCode() {
- return key.hashCode();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(type, encoded));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- stream.defaultWriteObject();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
deleted file mode 100644
index d14e921..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.security.KeyManagementException;
-
-public class OpenSSLServerSocketFactoryImpl extends javax.net.ssl.SSLServerSocketFactory {
-
- private SSLParametersImpl sslParameters;
- private IOException instantiationException;
-
- public OpenSSLServerSocketFactoryImpl() {
- try {
- this.sslParameters = SSLParametersImpl.getDefault();
- this.sslParameters.setUseClientMode(false);
- } catch (KeyManagementException e) {
- instantiationException =
- new IOException("Delayed instantiation exception:");
- instantiationException.initCause(e);
- }
- }
-
- public OpenSSLServerSocketFactoryImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = (SSLParametersImpl) sslParameters.clone();
- this.sslParameters.setUseClientMode(false);
- }
-
- public String[] getDefaultCipherSuites() {
- return NativeCrypto.getDefaultCipherSuites();
- }
-
- public String[] getSupportedCipherSuites() {
- return NativeCrypto.getSupportedCipherSuites();
- }
-
- public ServerSocket createServerSocket() throws IOException {
- return new OpenSSLServerSocketImpl((SSLParametersImpl) sslParameters.clone());
- }
-
- public ServerSocket createServerSocket(int port) throws IOException {
- return new OpenSSLServerSocketImpl(port, (SSLParametersImpl) sslParameters.clone());
- }
-
- public ServerSocket createServerSocket(int port, int backlog)
- throws IOException {
- return new OpenSSLServerSocketImpl(port,
- backlog,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- public ServerSocket createServerSocket(int port,
- int backlog,
- InetAddress iAddress) throws IOException {
- return new OpenSSLServerSocketImpl(port,
- backlog,
- iAddress,
- (SSLParametersImpl) sslParameters.clone());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java
deleted file mode 100644
index adcfa1d..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.security.PrivateKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.RSAPrivateKey;
-import javax.net.ssl.SSLException;
-
-/**
- * OpenSSL-based implementation of server sockets.
- */
-public class OpenSSLServerSocketImpl extends javax.net.ssl.SSLServerSocket {
- private final SSLParametersImpl sslParameters;
- private String[] enabledProtocols = NativeCrypto.getSupportedProtocols();
- private String[] enabledCipherSuites = NativeCrypto.getDefaultCipherSuites();
- private boolean channelIdEnabled;
-
- protected OpenSSLServerSocketImpl(SSLParametersImpl sslParameters) throws IOException {
- this.sslParameters = sslParameters;
- }
-
- protected OpenSSLServerSocketImpl(int port, SSLParametersImpl sslParameters)
- throws IOException {
- super(port);
- this.sslParameters = sslParameters;
- }
-
- protected OpenSSLServerSocketImpl(int port, int backlog, SSLParametersImpl sslParameters)
- throws IOException {
- super(port, backlog);
- this.sslParameters = sslParameters;
- }
-
- protected OpenSSLServerSocketImpl(int port,
- int backlog,
- InetAddress iAddress,
- SSLParametersImpl sslParameters)
- throws IOException {
- super(port, backlog, iAddress);
- this.sslParameters = sslParameters;
- }
-
- @Override
- public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
- @Override
- public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- /**
- * The names of the protocols' versions that may be used on this SSL
- * connection.
- * @return an array of protocols names
- */
- @Override
- public String[] getSupportedProtocols() {
- return NativeCrypto.getSupportedProtocols();
- }
-
- /**
- * The names of the protocols' versions that in use on this SSL connection.
- *
- * @return an array of protocols names
- */
- @Override
- public String[] getEnabledProtocols() {
- return enabledProtocols.clone();
- }
-
- /**
- * This method enables the protocols' versions listed by
- * getSupportedProtocols().
- *
- * @param protocols names of all the protocols to enable.
- *
- * @throws IllegalArgumentException when one or more of the names in the
- * array are not supported, or when the array is null.
- */
- @Override
- public void setEnabledProtocols(String[] protocols) {
- enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols);
- }
-
- @Override
- public String[] getSupportedCipherSuites() {
- return NativeCrypto.getSupportedCipherSuites();
- }
-
- @Override
- public String[] getEnabledCipherSuites() {
- return enabledCipherSuites.clone();
- }
-
- /**
- * Enables/disables the TLS Channel ID extension for this server socket.
- */
- public void setChannelIdEnabled(boolean enabled) {
- channelIdEnabled = enabled;
- }
-
- /**
- * Checks whether the TLS Channel ID extension is enabled for this server socket.
- */
- public boolean isChannelIdEnabled() {
- return channelIdEnabled;
- }
-
- /**
- * This method enables the cipher suites listed by
- * getSupportedCipherSuites().
- *
- * @param suites the names of all the cipher suites to enable
- * @throws IllegalArgumentException when one or more of the ciphers in array
- * suites are not supported, or when the array is null.
- */
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites);
- }
-
- @Override
- public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- @Override
- public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- @Override
- public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- @Override
- public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- @Override
- public void setUseClientMode(boolean mode) {
- sslParameters.setUseClientMode(mode);
- }
-
- @Override
- public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- @Override
- public Socket accept() throws IOException {
-
- if (!sslParameters.getUseClientMode()) {
- checkEnabledCipherSuites();
- }
-
- OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters,
- enabledProtocols.clone(),
- enabledCipherSuites.clone());
- socket.setChannelIdEnabled(channelIdEnabled);
- implAccept(socket);
- return socket;
- }
-
- /**
- * Check if any of the enabled cipher suites has a chance to work.
- * Not 100% accurate, just a useful diagnostic that the RI does.
- */
- private void checkEnabledCipherSuites() throws SSLException {
- /* Loop over all enabled cipher suites. If we find a problem,
- * we just continue to the next one. If we find one that could
- * work, we return. This basically makes sure the caller has
- * configured some appropriate certificate/key unless
- * an anonymous cipher is picked.
- */
- for (String enabledCipherSuite : enabledCipherSuites) {
- if (enabledCipherSuite.equals(NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
- || enabledCipherSuite.equals(NativeCrypto.TLS_FALLBACK_SCSV)) {
- continue;
- }
- String keyType = CipherSuite.getByName(enabledCipherSuite).getServerKeyType();
- if (keyType == null) {
- // anonymous always work
- return;
- }
- if (keyType.equals(CipherSuite.KEY_TYPE_RSA)
- || keyType.equals(CipherSuite.KEY_TYPE_DH_RSA)) {
- if (checkForPrivateKey(keyType, RSAPrivateKey.class)) {
- return;
- }
- continue;
- }
- if (keyType.equals(CipherSuite.KEY_TYPE_DSA)
- || keyType.equals(CipherSuite.KEY_TYPE_DH_DSA)) {
- if (checkForPrivateKey(keyType, DSAPrivateKey.class)) {
- return;
- }
- continue;
- }
- if (keyType.equals(CipherSuite.KEY_TYPE_EC)
- || keyType.equals(CipherSuite.KEY_TYPE_EC_RSA)
- || keyType.equals(CipherSuite.KEY_TYPE_EC_EC)) {
- if (checkForPrivateKey(keyType, ECPrivateKey.class)) {
- return;
- }
- continue;
- }
- throw new IllegalStateException("Unknown key type " + keyType);
- }
- throw new SSLException("Could not find any key store entries "
- + "to support the enabled cipher suites.");
- }
-
- private boolean checkForPrivateKey(String keyType, Class<?> keyClass) {
- String alias = sslParameters.getKeyManager().chooseServerAlias(keyType, null, null);
- if (alias == null) {
- return false;
- }
- PrivateKey key = sslParameters.getKeyManager().getPrivateKey(alias);
- return (key != null && keyClass.isAssignableFrom(key.getClass()));
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSessionImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLSessionImpl.java
deleted file mode 100644
index 3b7328d..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSessionImpl.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.Principal;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionBindingEvent;
-import javax.net.ssl.SSLSessionBindingListener;
-import javax.net.ssl.SSLSessionContext;
-import javax.security.cert.CertificateException;
-
-/**
- * Implementation of the class OpenSSLSessionImpl
- * based on OpenSSL.
- */
-public class OpenSSLSessionImpl implements SSLSession {
-
- private long creationTime = 0;
- long lastAccessedTime = 0;
- final X509Certificate[] localCertificates;
- final X509Certificate[] peerCertificates;
-
- private boolean isValid = true;
- private final Map<String, Object> values = new HashMap<String, Object>();
- private volatile javax.security.cert.X509Certificate[] peerCertificateChain;
- protected long sslSessionNativePointer;
- private String peerHost;
- private int peerPort = -1;
- private String cipherSuite;
- private String protocol;
- private AbstractSessionContext sessionContext;
- private byte[] id;
-
- /**
- * Class constructor creates an SSL session context given the appropriate
- * SSL parameters.
- */
- protected OpenSSLSessionImpl(long sslSessionNativePointer, X509Certificate[] localCertificates,
- X509Certificate[] peerCertificates, String peerHost, int peerPort,
- AbstractSessionContext sessionContext) {
- this.sslSessionNativePointer = sslSessionNativePointer;
- this.localCertificates = localCertificates;
- this.peerCertificates = peerCertificates;
- this.peerHost = peerHost;
- this.peerPort = peerPort;
- this.sessionContext = sessionContext;
- }
-
- /**
- * Constructs a session from a byte[] containing DER data. This
- * allows loading the saved session.
- * @throws IOException
- */
- OpenSSLSessionImpl(byte[] derData,
- String peerHost, int peerPort,
- X509Certificate[] peerCertificates,
- AbstractSessionContext sessionContext)
- throws IOException {
- this(NativeCrypto.d2i_SSL_SESSION(derData),
- null,
- peerCertificates,
- peerHost,
- peerPort,
- sessionContext);
- // TODO move this check into native code so we can throw an error with more information
- if (this.sslSessionNativePointer == 0) {
- throw new IOException("Invalid session data");
- }
- }
-
- /**
- * Gets the identifier of the actual SSL session
- * @return array of sessions' identifiers.
- */
- public byte[] getId() {
- if (id == null) {
- resetId();
- }
- return id;
- }
-
- /**
- * Reset the id field to the current value found in the native
- * SSL_SESSION. It can change during the lifetime of the session
- * because while a session is created during initial handshake,
- * with handshake_cutthrough, the SSL_do_handshake may return
- * before we have read the session ticket from the server side and
- * therefore have computed no id based on the SHA of the ticket.
- */
- void resetId() {
- id = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer);
- }
-
- /**
- * Get the session object in DER format. This allows saving the session
- * data or sharing it with other processes.
- */
- byte[] getEncoded() {
- return NativeCrypto.i2d_SSL_SESSION(sslSessionNativePointer);
- }
-
- /**
- * Gets the creation time of the SSL session.
- * @return the session's creation time in milliseconds since the epoch
- */
- public long getCreationTime() {
- if (creationTime == 0) {
- creationTime = NativeCrypto.SSL_SESSION_get_time(sslSessionNativePointer);
- }
- return creationTime;
- }
-
- /**
- * Returns the last time this concrete SSL session was accessed. Accessing
- * here is to mean that a new connection with the same SSL context data was
- * established.
- *
- * @return the session's last access time in milliseconds since the epoch
- */
- public long getLastAccessedTime() {
- return (lastAccessedTime == 0) ? getCreationTime() : lastAccessedTime;
- }
-
- /**
- * Returns the largest buffer size for the application's data bound to this
- * concrete SSL session.
- * @return the largest buffer size
- */
- public int getApplicationBufferSize() {
- return SSLRecordProtocol.MAX_DATA_LENGTH;
- }
-
- /**
- * Returns the largest SSL/TLS packet size one can expect for this concrete
- * SSL session.
- * @return the largest packet size
- */
- public int getPacketBufferSize() {
- return SSLRecordProtocol.MAX_SSL_PACKET_SIZE;
- }
-
- /**
- * Returns the principal (subject) of this concrete SSL session used in the
- * handshaking phase of the connection.
- * @return a X509 certificate or null if no principal was defined
- */
- public Principal getLocalPrincipal() {
- if (localCertificates != null && localCertificates.length > 0) {
- return localCertificates[0].getSubjectX500Principal();
- } else {
- return null;
- }
- }
-
- /**
- * Returns the certificate(s) of the principal (subject) of this concrete SSL
- * session used in the handshaking phase of the connection. The OpenSSL
- * native method supports only RSA certificates.
- * @return an array of certificates (the local one first and then eventually
- * that of the certification authority) or null if no certificate
- * were used during the handshaking phase.
- */
- public Certificate[] getLocalCertificates() {
- return localCertificates;
- }
-
- /**
- * Returns the certificate(s) of the peer in this SSL session
- * used in the handshaking phase of the connection.
- * Please notice hat this method is superseded by
- * <code>getPeerCertificates()</code>.
- * @return an array of X509 certificates (the peer's one first and then
- * eventually that of the certification authority) or null if no
- * certificate were used during the SSL connection.
- * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
- * was used (i.e. Kerberos certificates) or the peer could not
- * be verified.
- */
- public javax.security.cert.X509Certificate[] getPeerCertificateChain()
- throws SSLPeerUnverifiedException {
- checkPeerCertificatesPresent();
- javax.security.cert.X509Certificate[] result = peerCertificateChain;
- if (result == null) {
- // single-check idiom
- peerCertificateChain = result = createPeerCertificateChain();
- }
- return result;
- }
-
- /**
- * Provide a value to initialize the volatile peerCertificateChain
- * field based on the native SSL_SESSION
- */
- private javax.security.cert.X509Certificate[] createPeerCertificateChain()
- throws SSLPeerUnverifiedException {
- try {
- javax.security.cert.X509Certificate[] chain
- = new javax.security.cert.X509Certificate[peerCertificates.length];
-
- for (int i = 0; i < peerCertificates.length; i++) {
- byte[] encoded = peerCertificates[i].getEncoded();
- chain[i] = javax.security.cert.X509Certificate.getInstance(encoded);
- }
- return chain;
- } catch (CertificateEncodingException e) {
- SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage());
- exception.initCause(exception);
- throw exception;
- } catch (CertificateException e) {
- SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage());
- exception.initCause(exception);
- throw exception;
- }
- }
-
- /**
- * Return the identity of the peer in this SSL session
- * determined via certificate(s).
- * @return an array of X509 certificates (the peer's one first and then
- * eventually that of the certification authority) or null if no
- * certificate were used during the SSL connection.
- * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
- * was used (i.e. Kerberos certificates) or the peer could not
- * be verified.
- */
- public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
- checkPeerCertificatesPresent();
- return peerCertificates;
- }
-
- /**
- * Throw SSLPeerUnverifiedException on null or empty peerCertificates array
- */
- private void checkPeerCertificatesPresent() throws SSLPeerUnverifiedException {
- if (peerCertificates == null || peerCertificates.length == 0) {
- throw new SSLPeerUnverifiedException("No peer certificates");
- }
- }
-
- /**
- * The identity of the principal that was used by the peer during the SSL
- * handshake phase is returned by this method.
- * @return a X500Principal of the last certificate for X509-based
- * cipher suites.
- * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
- * was used (i.e. Kerberos certificates) or the peer does not exist.
- *
- */
- public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
- checkPeerCertificatesPresent();
- return peerCertificates[0].getSubjectX500Principal();
- }
-
- /**
- * The peer's host name used in this SSL session is returned. It is the host
- * name of the client for the server; and that of the server for the client.
- * It is not a reliable way to get a fully qualified host name: it is mainly
- * used internally to implement links for a temporary cache of SSL sessions.
- *
- * @return the host name of the peer, or null if no information is
- * available.
- *
- */
- public String getPeerHost() {
- return peerHost;
- }
-
- /**
- * Returns the peer's port number for the actual SSL session. It is the port
- * number of the client for the server; and that of the server for the
- * client. It is not a reliable way to get a peer's port number: it is
- * mainly used internally to implement links for a temporary cache of SSL
- * sessions.
- * @return the peer's port number, or -1 if no one is available.
- *
- */
- public int getPeerPort() {
- return peerPort;
- }
-
- /**
- * Returns a string identifier of the crypto tools used in the actual SSL
- * session. For example AES_256_WITH_MD5.
- */
- public String getCipherSuite() {
- if (cipherSuite == null) {
- String name = NativeCrypto.SSL_SESSION_cipher(sslSessionNativePointer);
- cipherSuite = NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.get(name);
- if (cipherSuite == null) {
- cipherSuite = name;
- }
- }
- return cipherSuite;
- }
-
- /**
- * Returns the standard version name of the SSL protocol used in all
- * connections pertaining to this SSL session.
- */
- public String getProtocol() {
- if (protocol == null) {
- protocol = NativeCrypto.SSL_SESSION_get_version(sslSessionNativePointer);
- }
- return protocol;
- }
-
- /**
- * Returns the context to which the actual SSL session is bound. A SSL
- * context consists of (1) a possible delegate, (2) a provider and (3) a
- * protocol.
- * @return the SSL context used for this session, or null if it is
- * unavailable.
- */
- public SSLSessionContext getSessionContext() {
- return sessionContext;
- }
-
- /**
- * Returns a boolean flag signaling whether a SSL session is valid
- * and available for resuming or joining or not.
- *
- * @return true if this session may be resumed.
- */
- public boolean isValid() {
- SSLSessionContext context = sessionContext;
- if (isValid
- && context != null
- && context.getSessionTimeout() != 0
- && getCreationTime() + (context.getSessionTimeout() * 1000)
- < System.currentTimeMillis()) {
- isValid = false;
- }
- return isValid;
- }
-
- /**
- * It invalidates a SSL session forbidding any resumption.
- */
- public void invalidate() {
- isValid = false;
- sessionContext = null;
- }
-
- /**
- * Returns the object which is bound to the the input parameter name.
- * This name is a sort of link to the data of the SSL session's application
- * layer, if any exists.
- *
- * @param name the name of the binding to find.
- * @return the value bound to that name, or null if the binding does not
- * exist.
- * @throws IllegalArgumentException if the argument is null.
- */
- public Object getValue(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name == null");
- }
- return values.get(name);
- }
-
- /**
- * Returns an array with the names (sort of links) of all the data
- * objects of the application layer bound into the SSL session.
- *
- * @return a non-null (possibly empty) array of names of the data objects
- * bound to this SSL session.
- */
- public String[] getValueNames() {
- return values.keySet().toArray(new String[values.size()]);
- }
-
- /**
- * A link (name) with the specified value object of the SSL session's
- * application layer data is created or replaced. If the new (or existing)
- * value object implements the <code>SSLSessionBindingListener</code>
- * interface, that object will be notified in due course.
- *
- * @param name the name of the link (no null are
- * accepted!)
- * @param value data object that shall be bound to
- * name.
- * @throws IllegalArgumentException if one or both argument(s) is null.
- */
- public void putValue(String name, Object value) {
- if (name == null || value == null) {
- throw new IllegalArgumentException("name == null || value == null");
- }
- Object old = values.put(name, value);
- if (value instanceof SSLSessionBindingListener) {
- ((SSLSessionBindingListener) value)
- .valueBound(new SSLSessionBindingEvent(this, name));
- }
- if (old instanceof SSLSessionBindingListener) {
- ((SSLSessionBindingListener) old)
- .valueUnbound(new SSLSessionBindingEvent(this, name));
- }
- }
-
- /**
- * Removes a link (name) with the specified value object of the SSL
- * session's application layer data.
- *
- * <p>If the value object implements the <code>SSLSessionBindingListener</code>
- * interface, the object will receive a <code>valueUnbound</code> notification.
- *
- * @param name the name of the link (no null are
- * accepted!)
- * @throws IllegalArgumentException if the argument is null.
- */
- public void removeValue(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name == null");
- }
- Object old = values.remove(name);
- if (old instanceof SSLSessionBindingListener) {
- SSLSessionBindingListener listener = (SSLSessionBindingListener) old;
- listener.valueUnbound(new SSLSessionBindingEvent(this, name));
- }
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- NativeCrypto.SSL_SESSION_free(sslSessionNativePointer);
- } finally {
- super.finalize();
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSignature.java b/crypto/src/main/java/org/conscrypt/OpenSSLSignature.java
deleted file mode 100644
index 8576010..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSignature.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-
-/**
- * Implements the subset of the JDK Signature interface needed for
- * signature verification using OpenSSL.
- */
-public class OpenSSLSignature extends Signature {
- private static enum EngineType {
- RSA, DSA, EC,
- };
-
- /**
- * Holds a pointer to the native message digest context.
- */
- private long ctx;
-
- /**
- * The current OpenSSL key we're operating on.
- */
- private OpenSSLKey key;
-
- /**
- * Holds the type of the Java algorithm.
- */
- private final EngineType engineType;
-
- /**
- * Holds the OpenSSL name of the algorithm (lower case, no dashes).
- */
- private final String evpAlgorithm;
-
- /**
- * Holds a dummy buffer for writing single bytes to the digest.
- */
- private final byte[] singleByte = new byte[1];
-
- /**
- * Creates a new OpenSSLSignature instance for the given algorithm name.
- *
- * @param algorithm OpenSSL name of the algorithm, e.g. "RSA-SHA1".
- */
- private OpenSSLSignature(String algorithm, EngineType engineType)
- throws NoSuchAlgorithmException {
- super(algorithm);
-
- // We don't support MD2
- if ("RSA-MD2".equals(algorithm)) {
- throw new NoSuchAlgorithmException(algorithm);
- }
-
- this.engineType = engineType;
- this.evpAlgorithm = algorithm;
- }
-
- @Override
- protected void engineUpdate(byte input) {
- singleByte[0] = input;
- engineUpdate(singleByte, 0, 1);
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- if (state == SIGN) {
- if (ctx == 0) {
- try {
- ctx = NativeCrypto.EVP_SignInit(evpAlgorithm);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- NativeCrypto.EVP_SignUpdate(ctx, input, offset, len);
- } else {
- if (ctx == 0) {
- try {
- ctx = NativeCrypto.EVP_VerifyInit(evpAlgorithm);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- NativeCrypto.EVP_VerifyUpdate(ctx, input, offset, len);
- }
- }
-
- @Override
- protected Object engineGetParameter(String param) throws InvalidParameterException {
- return null;
- }
-
- private void checkEngineType(OpenSSLKey pkey) throws InvalidKeyException {
- final int pkeyType = NativeCrypto.EVP_PKEY_type(pkey.getPkeyContext());
-
- switch (engineType) {
- case RSA:
- if (pkeyType != NativeCrypto.EVP_PKEY_RSA) {
- throw new InvalidKeyException("Signature not initialized as RSA");
- }
- break;
- case DSA:
- if (pkeyType != NativeCrypto.EVP_PKEY_DSA) {
- throw new InvalidKeyException("Signature not initialized as DSA");
- }
- break;
- case EC:
- if (pkeyType != NativeCrypto.EVP_PKEY_EC) {
- throw new InvalidKeyException("Signature not initialized as EC");
- }
- break;
- default:
- throw new InvalidKeyException("Need DSA or RSA or EC private key");
- }
- }
-
- @Override
- protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
- destroyContextIfExists();
-
- if (privateKey instanceof OpenSSLKeyHolder) {
- OpenSSLKey pkey = ((OpenSSLKeyHolder) privateKey).getOpenSSLKey();
- checkEngineType(pkey);
- key = pkey;
- } else if (privateKey instanceof RSAPrivateCrtKey) {
- if (engineType != EngineType.RSA) {
- throw new InvalidKeyException("Signature not initialized as RSA");
- }
-
- RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey;
- key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
- } else if (privateKey instanceof RSAPrivateKey) {
- if (engineType != EngineType.RSA) {
- throw new InvalidKeyException("Signature not initialized as RSA");
- }
-
- RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
- key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
- } else if (privateKey instanceof DSAPrivateKey) {
- if (engineType != EngineType.DSA) {
- throw new InvalidKeyException("Signature not initialized as DSA");
- }
-
- DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privateKey;
- key = OpenSSLDSAPrivateKey.getInstance(dsaPrivateKey);
- } else if (privateKey instanceof ECPrivateKey) {
- if (engineType != EngineType.EC) {
- throw new InvalidKeyException("Signature not initialized as EC");
- }
-
- ECPrivateKey ecPrivateKey = (ECPrivateKey) privateKey;
- key = OpenSSLECPrivateKey.getInstance(ecPrivateKey);
- } else {
- throw new InvalidKeyException("Need DSA or RSA or EC private key");
- }
- }
-
- @Override
- protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
- // If we had an existing context, destroy it first.
- destroyContextIfExists();
-
- if (publicKey instanceof OpenSSLKeyHolder) {
- OpenSSLKey pkey = ((OpenSSLKeyHolder) publicKey).getOpenSSLKey();
- checkEngineType(pkey);
- key = pkey;
- } else if (publicKey instanceof RSAPublicKey) {
- if (engineType != EngineType.RSA) {
- throw new InvalidKeyException("Signature not initialized as RSA");
- }
-
- RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
- key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
- } else if (publicKey instanceof DSAPublicKey) {
- if (engineType != EngineType.DSA) {
- throw new InvalidKeyException("Signature not initialized as DSA");
- }
-
- DSAPublicKey dsaPublicKey = (DSAPublicKey) publicKey;
- key = OpenSSLDSAPublicKey.getInstance(dsaPublicKey);
- } else if (publicKey instanceof ECPublicKey) {
- if (engineType != EngineType.EC) {
- throw new InvalidKeyException("Signature not initialized as EC");
- }
-
- ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
- key = OpenSSLECPublicKey.getInstance(ecPublicKey);
- } else {
- throw new InvalidKeyException("Need DSA or RSA or EC public key");
- }
- }
-
- @Override
- protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
- }
-
- @Override
- protected byte[] engineSign() throws SignatureException {
- if (key == null) {
- // This can't actually happen, but you never know...
- throw new SignatureException("Need DSA or RSA or EC private key");
- }
-
- try {
- byte[] buffer = new byte[NativeCrypto.EVP_PKEY_size(key.getPkeyContext())];
- int bytesWritten = NativeCrypto.EVP_SignFinal(ctx, buffer, 0, key.getPkeyContext());
-
- byte[] signature = new byte[bytesWritten];
- System.arraycopy(buffer, 0, signature, 0, bytesWritten);
-
- return signature;
- } catch (Exception ex) {
- throw new SignatureException(ex);
- } finally {
- /*
- * Java expects the digest context to be reset completely after sign
- * calls.
- */
- destroyContextIfExists();
- }
- }
-
- @Override
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- if (key == null) {
- // This can't actually happen, but you never know...
- throw new SignatureException("Need DSA or RSA public key");
- }
-
- try {
- int result = NativeCrypto.EVP_VerifyFinal(ctx, sigBytes, 0, sigBytes.length,
- key.getPkeyContext());
- return result == 1;
- } catch (Exception ex) {
- return false;
- } finally {
- /*
- * Java expects the digest context to be reset completely after
- * verify calls.
- */
- destroyContextIfExists();
- }
- }
-
- private void destroyContextIfExists() {
- if (ctx != 0) {
- NativeCrypto.EVP_MD_CTX_destroy(ctx);
- ctx = 0;
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (ctx != 0) {
- NativeCrypto.EVP_MD_CTX_destroy(ctx);
- }
- } finally {
- super.finalize();
- }
- }
-
- public static final class MD5RSA extends OpenSSLSignature {
- public MD5RSA() throws NoSuchAlgorithmException {
- super("RSA-MD5", EngineType.RSA);
- }
- }
- public static final class SHA1RSA extends OpenSSLSignature {
- public SHA1RSA() throws NoSuchAlgorithmException {
- super("RSA-SHA1", EngineType.RSA);
- }
- }
- public static final class SHA256RSA extends OpenSSLSignature {
- public SHA256RSA() throws NoSuchAlgorithmException {
- super("RSA-SHA256", EngineType.RSA);
- }
- }
- public static final class SHA384RSA extends OpenSSLSignature {
- public SHA384RSA() throws NoSuchAlgorithmException {
- super("RSA-SHA384", EngineType.RSA);
- }
- }
- public static final class SHA512RSA extends OpenSSLSignature {
- public SHA512RSA() throws NoSuchAlgorithmException {
- super("RSA-SHA512", EngineType.RSA);
- }
- }
- public static final class SHA1DSA extends OpenSSLSignature {
- public SHA1DSA() throws NoSuchAlgorithmException {
- super("DSA-SHA1", EngineType.DSA);
- }
- }
- public static final class SHA1ECDSA extends OpenSSLSignature {
- public SHA1ECDSA() throws NoSuchAlgorithmException {
- super("SHA1", EngineType.EC);
- }
- }
- public static final class SHA256ECDSA extends OpenSSLSignature {
- public SHA256ECDSA() throws NoSuchAlgorithmException {
- super("SHA256", EngineType.EC);
- }
- }
- public static final class SHA384ECDSA extends OpenSSLSignature {
- public SHA384ECDSA() throws NoSuchAlgorithmException {
- super("SHA384", EngineType.EC);
- }
- }
- public static final class SHA512ECDSA extends OpenSSLSignature {
- public SHA512ECDSA() throws NoSuchAlgorithmException {
- super("SHA512", EngineType.EC);
- }
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSignatureRawRSA.java b/crypto/src/main/java/org/conscrypt/OpenSSLSignatureRawRSA.java
deleted file mode 100644
index 9c4e4ad..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSignatureRawRSA.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-
-/**
- * Implements the JDK Signature interface needed for RAW RSA signature
- * generation and verification using OpenSSL.
- */
-public class OpenSSLSignatureRawRSA extends Signature {
- /**
- * The current OpenSSL key we're operating on.
- */
- private OpenSSLKey key;
-
- /**
- * Buffer to hold value to be signed or verified.
- */
- private byte[] inputBuffer;
-
- /**
- * Current offset in input buffer.
- */
- private int inputOffset;
-
- /**
- * Provides a flag to specify when the input is too long.
- */
- private boolean inputIsTooLong;
-
- /**
- * Creates a new OpenSSLSignature instance for the given algorithm name.
- */
- public OpenSSLSignatureRawRSA() throws NoSuchAlgorithmException {
- super("NONEwithRSA");
- }
-
- @Override
- protected void engineUpdate(byte input) {
- final int oldOffset = inputOffset++;
-
- if (inputOffset > inputBuffer.length) {
- inputIsTooLong = true;
- return;
- }
-
- inputBuffer[oldOffset] = input;
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- final int oldOffset = inputOffset;
- inputOffset += len;
-
- if (inputOffset > inputBuffer.length) {
- inputIsTooLong = true;
- return;
- }
-
- System.arraycopy(input, offset, inputBuffer, oldOffset, len);
- }
-
- @Override
- protected Object engineGetParameter(String param) throws InvalidParameterException {
- return null;
- }
-
- @Override
- protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
- if (privateKey instanceof OpenSSLRSAPrivateKey) {
- OpenSSLRSAPrivateKey rsaPrivateKey = (OpenSSLRSAPrivateKey) privateKey;
- key = rsaPrivateKey.getOpenSSLKey();
- } else if (privateKey instanceof RSAPrivateCrtKey) {
- RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey;
- key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
- } else if (privateKey instanceof RSAPrivateKey) {
- RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
- key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
- } else {
- throw new InvalidKeyException("Need RSA private key");
- }
-
- // Allocate buffer according to RSA modulus size.
- int maxSize = NativeCrypto.RSA_size(key.getPkeyContext());
- inputBuffer = new byte[maxSize];
- inputOffset = 0;
- }
-
- @Override
- protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
- if (publicKey instanceof OpenSSLRSAPublicKey) {
- OpenSSLRSAPublicKey rsaPublicKey = (OpenSSLRSAPublicKey) publicKey;
- key = rsaPublicKey.getOpenSSLKey();
- } else if (publicKey instanceof RSAPublicKey) {
- RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
- key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
- } else {
- throw new InvalidKeyException("Need RSA public key");
- }
-
- // Allocate buffer according to RSA modulus size.
- int maxSize = NativeCrypto.RSA_size(key.getPkeyContext());
- inputBuffer = new byte[maxSize];
- inputOffset = 0;
- }
-
- @Override
- protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
- }
-
- @Override
- protected byte[] engineSign() throws SignatureException {
- if (key == null) {
- // This can't actually happen, but you never know...
- throw new SignatureException("Need RSA private key");
- }
-
- if (inputIsTooLong) {
- throw new SignatureException("input length " + inputOffset + " != "
- + inputBuffer.length + " (modulus size)");
- }
-
- byte[] outputBuffer = new byte[inputBuffer.length];
- try {
- NativeCrypto.RSA_private_encrypt(inputOffset, inputBuffer, outputBuffer,
- key.getPkeyContext(), NativeCrypto.RSA_PKCS1_PADDING);
- return outputBuffer;
- } catch (Exception ex) {
- throw new SignatureException(ex);
- } finally {
- inputOffset = 0;
- }
- }
-
- @Override
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- if (key == null) {
- // This can't actually happen, but you never know...
- throw new SignatureException("Need RSA public key");
- }
-
- if (inputIsTooLong) {
- return false;
- }
-
- byte[] outputBuffer = new byte[inputBuffer.length];
- try {
- final int resultSize;
- try {
- resultSize = NativeCrypto.RSA_public_decrypt(sigBytes.length, sigBytes,
- outputBuffer, key.getPkeyContext(), NativeCrypto.RSA_PKCS1_PADDING);
- } catch (SignatureException e) {
- throw e;
- } catch (Exception e) {
- return false;
- }
- /* Make this constant time by comparing every byte. */
- boolean matches = (resultSize == inputOffset);
- for (int i = 0; i < resultSize; i++) {
- if (inputBuffer[i] != outputBuffer[i]) {
- matches = false;
- }
- }
- return matches;
- } catch (Exception ex) {
- throw new SignatureException(ex);
- } finally {
- inputOffset = 0;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java
deleted file mode 100644
index 72fd89f..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.KeyManagementException;
-
-public class OpenSSLSocketFactoryImpl extends javax.net.ssl.SSLSocketFactory {
-
- private final SSLParametersImpl sslParameters;
- private final IOException instantiationException;
-
- public OpenSSLSocketFactoryImpl() {
- SSLParametersImpl sslParametersLocal = null;
- IOException instantiationExceptionLocal = null;
- try {
- sslParametersLocal = SSLParametersImpl.getDefault();
- } catch (KeyManagementException e) {
- instantiationExceptionLocal = new IOException("Delayed instantiation exception:");
- instantiationExceptionLocal.initCause(e);
- }
- this.sslParameters = sslParametersLocal;
- this.instantiationException = instantiationExceptionLocal;
- }
-
- public OpenSSLSocketFactoryImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = sslParameters;
- this.instantiationException = null;
- }
-
- public String[] getDefaultCipherSuites() {
- return NativeCrypto.getDefaultCipherSuites();
- }
-
- public String[] getSupportedCipherSuites() {
- return NativeCrypto.getSupportedCipherSuites();
- }
-
- public Socket createSocket() throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new OpenSSLSocketImpl((SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
- return new OpenSSLSocketImpl(host, port, (SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
- throws IOException, UnknownHostException {
- return new OpenSSLSocketImpl(host,
- port,
- localHost,
- localPort,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(InetAddress host, int port) throws IOException {
- return new OpenSSLSocketImpl(host, port, (SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(InetAddress address,
- int port,
- InetAddress localAddress,
- int localPort)
- throws IOException {
- return new OpenSSLSocketImpl(address,
- port,
- localAddress,
- localPort,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(Socket s, String host, int port, boolean autoClose)
- throws IOException {
- return new OpenSSLSocketImplWrapper(s,
- host,
- port,
- autoClose,
- (SSLParametersImpl) sslParameters.clone());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
deleted file mode 100644
index 4b705d7..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
+++ /dev/null
@@ -1,1137 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import dalvik.system.BlockGuard;
-import dalvik.system.CloseGuard;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.security.InvalidKeyException;
-import java.security.PrivateKey;
-import java.security.SecureRandom;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import javax.net.ssl.HandshakeCompletedEvent;
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLProtocolException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.X509TrustManager;
-import javax.security.auth.x500.X500Principal;
-import static libcore.io.OsConstants.*;
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.Streams;
-import libcore.io.StructTimeval;
-
-/**
- * Implementation of the class OpenSSLSocketImpl based on OpenSSL.
- * <p>
- * Extensions to SSLSocket include:
- * <ul>
- * <li>handshake timeout
- * <li>session tickets
- * <li>Server Name Indication
- * </ul>
- */
-public class OpenSSLSocketImpl
- extends javax.net.ssl.SSLSocket
- implements NativeCrypto.SSLHandshakeCallbacks {
-
- private long sslNativePointer;
- private InputStream is;
- private OutputStream os;
- private final Object handshakeLock = new Object();
- private final Object readLock = new Object();
- private final Object writeLock = new Object();
- private SSLParametersImpl sslParameters;
- private byte[] npnProtocols;
- private byte[] alpnProtocols;
- private String[] enabledProtocols;
- private String[] enabledCipherSuites;
- private boolean useSessionTickets;
- private String hostname;
- /** Whether the TLS Channel ID extension is enabled. This field is server-side only. */
- private boolean channelIdEnabled;
- /** Private key for the TLS Channel ID extension. This field is client-side only. */
- private OpenSSLKey channelIdPrivateKey;
- private OpenSSLSessionImpl sslSession;
- private final Socket socket;
- private boolean autoClose;
- private boolean handshakeStarted = false;
- private final CloseGuard guard = CloseGuard.get();
-
- /**
- * Not set to true until the update from native that tells us the
- * full handshake is complete, since SSL_do_handshake can return
- * before the handshake is completely done due to
- * handshake_cutthrough support.
- */
- private boolean handshakeCompleted = false;
-
- private ArrayList<HandshakeCompletedListener> listeners;
-
- /**
- * Local cache of timeout to avoid getsockopt on every read and
- * write for non-wrapped sockets. Note that
- * OpenSSLSocketImplWrapper overrides setSoTimeout and
- * getSoTimeout to delegate to the wrapped socket.
- */
- private int readTimeoutMilliseconds = 0;
- private int writeTimeoutMilliseconds = 0;
-
- private int handshakeTimeoutMilliseconds = -1; // -1 = same as timeout; 0 = infinite
- private String wrappedHost;
- private int wrappedPort;
-
- protected OpenSSLSocketImpl(SSLParametersImpl sslParameters) throws IOException {
- this.socket = this;
- init(sslParameters);
- }
-
- protected OpenSSLSocketImpl(SSLParametersImpl sslParameters,
- String[] enabledProtocols,
- String[] enabledCipherSuites) throws IOException {
- this.socket = this;
- init(sslParameters, enabledProtocols, enabledCipherSuites);
- }
-
- protected OpenSSLSocketImpl(String host, int port, SSLParametersImpl sslParameters)
- throws IOException {
- super(host, port);
- this.socket = this;
- init(sslParameters);
- }
-
- protected OpenSSLSocketImpl(InetAddress address, int port, SSLParametersImpl sslParameters)
- throws IOException {
- super(address, port);
- this.socket = this;
- init(sslParameters);
- }
-
-
- protected OpenSSLSocketImpl(String host, int port,
- InetAddress clientAddress, int clientPort,
- SSLParametersImpl sslParameters) throws IOException {
- super(host, port, clientAddress, clientPort);
- this.socket = this;
- init(sslParameters);
- }
-
- protected OpenSSLSocketImpl(InetAddress address, int port,
- InetAddress clientAddress, int clientPort,
- SSLParametersImpl sslParameters) throws IOException {
- super(address, port, clientAddress, clientPort);
- this.socket = this;
- init(sslParameters);
- }
-
- /**
- * Create an SSL socket that wraps another socket. Invoked by
- * OpenSSLSocketImplWrapper constructor.
- */
- protected OpenSSLSocketImpl(Socket socket, String host, int port,
- boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
- this.socket = socket;
- this.wrappedHost = host;
- this.wrappedPort = port;
- this.autoClose = autoClose;
- init(sslParameters);
-
- // this.timeout is not set intentionally.
- // OpenSSLSocketImplWrapper.getSoTimeout will delegate timeout
- // to wrapped socket
- }
-
- /**
- * Initialize the SSL socket and set the certificates for the
- * future handshaking.
- */
- private void init(SSLParametersImpl sslParameters) throws IOException {
- init(sslParameters,
- NativeCrypto.getDefaultProtocols(),
- NativeCrypto.getDefaultCipherSuites());
- }
-
- /**
- * Initialize the SSL socket and set the certificates for the
- * future handshaking.
- */
- private void init(SSLParametersImpl sslParameters,
- String[] enabledProtocols,
- String[] enabledCipherSuites) throws IOException {
- this.sslParameters = sslParameters;
- this.enabledProtocols = enabledProtocols;
- this.enabledCipherSuites = enabledCipherSuites;
- }
-
- /**
- * Gets the suitable session reference from the session cache container.
- */
- private OpenSSLSessionImpl getCachedClientSession(ClientSessionContext sessionContext) {
- String hostName = getPeerHostName();
- int port = getPeerPort();
- if (hostName == null) {
- return null;
- }
- OpenSSLSessionImpl session = (OpenSSLSessionImpl) sessionContext.getSession(hostName, port);
- if (session == null) {
- return null;
- }
-
- String protocol = session.getProtocol();
- boolean protocolFound = false;
- for (String enabledProtocol : enabledProtocols) {
- if (protocol.equals(enabledProtocol)) {
- protocolFound = true;
- break;
- }
- }
- if (!protocolFound) {
- return null;
- }
-
- String cipherSuite = session.getCipherSuite();
- boolean cipherSuiteFound = false;
- for (String enabledCipherSuite : enabledCipherSuites) {
- if (cipherSuite.equals(enabledCipherSuite)) {
- cipherSuiteFound = true;
- break;
- }
- }
- if (!cipherSuiteFound) {
- return null;
- }
-
- return session;
- }
-
- private void checkOpen() throws SocketException {
- if (isClosed()) {
- throw new SocketException("Socket is closed");
- }
- }
-
- /**
- * Starts a TLS/SSL handshake on this connection using some native methods
- * from the OpenSSL library. It can negotiate new encryption keys, change
- * cipher suites, or initiate a new session. The certificate chain is
- * verified if the correspondent property in java.Security is set. All
- * listeners are notified at the end of the TLS/SSL handshake.
- */
- @Override public synchronized void startHandshake() throws IOException {
- synchronized (handshakeLock) {
- checkOpen();
- if (!handshakeStarted) {
- handshakeStarted = true;
- } else {
- return;
- }
- }
-
- // note that this modifies the global seed, not something specific to the connection
- final int seedLengthInBytes = NativeCrypto.RAND_SEED_LENGTH_IN_BYTES;
- final SecureRandom secureRandom = sslParameters.getSecureRandomMember();
- if (secureRandom == null) {
- NativeCrypto.RAND_load_file("/dev/urandom", seedLengthInBytes);
- } else {
- NativeCrypto.RAND_seed(secureRandom.generateSeed(seedLengthInBytes));
- }
-
- final boolean client = sslParameters.getUseClientMode();
-
- final long sslCtxNativePointer = (client) ?
- sslParameters.getClientSessionContext().sslCtxNativePointer :
- sslParameters.getServerSessionContext().sslCtxNativePointer;
-
- this.sslNativePointer = 0;
- boolean exception = true;
- try {
- sslNativePointer = NativeCrypto.SSL_new(sslCtxNativePointer);
- guard.open("close");
-
- if (npnProtocols != null) {
- NativeCrypto.SSL_CTX_enable_npn(sslCtxNativePointer);
- }
-
- if (client && alpnProtocols != null) {
- NativeCrypto.SSL_CTX_set_alpn_protos(sslCtxNativePointer, alpnProtocols);
- }
-
- // setup server certificates and private keys.
- // clients will receive a call back to request certificates.
- if (!client) {
- Set<String> keyTypes = new HashSet<String>();
- for (String enabledCipherSuite : enabledCipherSuites) {
- if (enabledCipherSuite.equals(NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
- || enabledCipherSuite.equals(NativeCrypto.TLS_FALLBACK_SCSV)) {
- continue;
- }
- String keyType = CipherSuite.getByName(enabledCipherSuite).getServerKeyType();
- if (keyType != null) {
- keyTypes.add(keyType);
- }
- }
- for (String keyType : keyTypes) {
- try {
- setCertificate(sslParameters.getKeyManager().chooseServerAlias(keyType,
- null,
- this));
- } catch (CertificateEncodingException e) {
- throw new IOException(e);
- }
- }
- }
-
- NativeCrypto.setEnabledProtocols(sslNativePointer, enabledProtocols);
- NativeCrypto.setEnabledCipherSuites(sslNativePointer, enabledCipherSuites);
- if (useSessionTickets) {
- NativeCrypto.SSL_clear_options(sslNativePointer, NativeCrypto.SSL_OP_NO_TICKET);
- }
- if (hostname != null) {
- NativeCrypto.SSL_set_tlsext_host_name(sslNativePointer, hostname);
- }
-
- boolean enableSessionCreation = sslParameters.getEnableSessionCreation();
- if (!enableSessionCreation) {
- NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer,
- enableSessionCreation);
- }
-
- AbstractSessionContext sessionContext;
- OpenSSLSessionImpl sessionToReuse;
- if (client) {
- // look for client session to reuse
- ClientSessionContext clientSessionContext = sslParameters.getClientSessionContext();
- sessionContext = clientSessionContext;
- sessionToReuse = getCachedClientSession(clientSessionContext);
- if (sessionToReuse != null) {
- NativeCrypto.SSL_set_session(sslNativePointer,
- sessionToReuse.sslSessionNativePointer);
- }
- } else {
- sessionContext = sslParameters.getServerSessionContext();
- sessionToReuse = null;
- }
-
- // setup peer certificate verification
- if (client) {
- // TODO support for anonymous cipher would require us to
- // conditionally use SSL_VERIFY_NONE
- } else {
- // needing client auth takes priority...
- boolean certRequested;
- if (sslParameters.getNeedClientAuth()) {
- NativeCrypto.SSL_set_verify(sslNativePointer,
- NativeCrypto.SSL_VERIFY_PEER
- | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
- certRequested = true;
- // ... over just wanting it...
- } else if (sslParameters.getWantClientAuth()) {
- NativeCrypto.SSL_set_verify(sslNativePointer,
- NativeCrypto.SSL_VERIFY_PEER);
- certRequested = true;
- // ... and it defaults properly so don't call SSL_set_verify in the common case.
- } else {
- certRequested = false;
- }
-
- if (certRequested) {
- X509TrustManager trustManager = sslParameters.getTrustManager();
- X509Certificate[] issuers = trustManager.getAcceptedIssuers();
- if (issuers != null && issuers.length != 0) {
- byte[][] issuersBytes;
- try {
- issuersBytes = encodeIssuerX509Principals(issuers);
- } catch (CertificateEncodingException e) {
- throw new IOException("Problem encoding principals", e);
- }
- NativeCrypto.SSL_set_client_CA_list(sslNativePointer, issuersBytes);
- }
- }
- }
-
- // Temporarily use a different timeout for the handshake process
- int savedReadTimeoutMilliseconds = getSoTimeout();
- int savedWriteTimeoutMilliseconds = getSoWriteTimeout();
- if (handshakeTimeoutMilliseconds >= 0) {
- setSoTimeout(handshakeTimeoutMilliseconds);
- setSoWriteTimeout(handshakeTimeoutMilliseconds);
- }
-
- // TLS Channel ID
- if (channelIdEnabled) {
- if (client) {
- // Client-side TLS Channel ID
- if (channelIdPrivateKey == null) {
- throw new SSLHandshakeException("Invalid TLS channel ID key specified");
- }
- NativeCrypto.SSL_set1_tls_channel_id(sslNativePointer,
- channelIdPrivateKey.getPkeyContext());
- } else {
- // Server-side TLS Channel ID
- NativeCrypto.SSL_enable_tls_channel_id(sslNativePointer);
- }
- }
-
- int sslSessionNativePointer;
- try {
- sslSessionNativePointer = NativeCrypto.SSL_do_handshake(sslNativePointer,
- socket.getFileDescriptor$(), this, getSoTimeout(), client, npnProtocols,
- client ? null : alpnProtocols);
- } catch (CertificateException e) {
- SSLHandshakeException wrapper = new SSLHandshakeException(e.getMessage());
- wrapper.initCause(e);
- throw wrapper;
- }
- byte[] sessionId = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer);
- if (sessionToReuse != null && Arrays.equals(sessionToReuse.getId(), sessionId)) {
- this.sslSession = sessionToReuse;
- sslSession.lastAccessedTime = System.currentTimeMillis();
- NativeCrypto.SSL_SESSION_free(sslSessionNativePointer);
- } else {
- if (!enableSessionCreation) {
- // Should have been prevented by NativeCrypto.SSL_set_session_creation_enabled
- throw new IllegalStateException("SSL Session may not be created");
- }
- X509Certificate[] localCertificates
- = createCertChain(NativeCrypto.SSL_get_certificate(sslNativePointer));
- X509Certificate[] peerCertificates
- = createCertChain(NativeCrypto.SSL_get_peer_cert_chain(sslNativePointer));
- this.sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates,
- peerCertificates, getPeerHostName(), getPeerPort(), sessionContext);
- // if not, putSession later in handshakeCompleted() callback
- if (handshakeCompleted) {
- sessionContext.putSession(sslSession);
- }
- }
-
- // Restore the original timeout now that the handshake is complete
- if (handshakeTimeoutMilliseconds >= 0) {
- setSoTimeout(savedReadTimeoutMilliseconds);
- setSoWriteTimeout(savedWriteTimeoutMilliseconds);
- }
-
- // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback
- if (handshakeCompleted) {
- notifyHandshakeCompletedListeners();
- }
-
- exception = false;
- } catch (SSLProtocolException e) {
- throw new SSLHandshakeException(e);
- } finally {
- // on exceptional exit, treat the socket as closed
- if (exception) {
- close();
- }
- }
- }
-
- private static byte[][] encodeIssuerX509Principals(X509Certificate[] certificates)
- throws CertificateEncodingException {
- byte[][] principalBytes = new byte[certificates.length][];
- for (int i = 0; i < certificates.length; i++) {
- principalBytes[i] = certificates[i].getIssuerX500Principal().getEncoded();
- }
- return principalBytes;
- }
-
- String getPeerHostName() {
- if (wrappedHost != null) {
- return wrappedHost;
- }
- InetAddress inetAddress = super.getInetAddress();
- if (inetAddress != null) {
- return inetAddress.getHostName();
- }
- return null;
- }
-
- int getPeerPort() {
- return wrappedHost == null ? super.getPort() : wrappedPort;
- }
-
- /**
- * Return a possibly null array of X509Certificates given the
- * possibly null array of DER encoded bytes.
- */
- private static X509Certificate[] createCertChain(byte[][] certificatesBytes) throws IOException {
- if (certificatesBytes == null) {
- return null;
- }
- X509Certificate[] certificates = new X509Certificate[certificatesBytes.length];
- for (int i = 0; i < certificatesBytes.length; i++) {
- certificates[i] = OpenSSLX509Certificate.fromX509Der(certificatesBytes[i]);
- }
- return certificates;
- }
-
- private void setCertificate(String alias) throws CertificateEncodingException, SSLException {
- if (alias == null) {
- return;
- }
- PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias);
- if (privateKey == null) {
- return;
- }
- X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias);
- if (certificates == null) {
- return;
- }
-
- // Note that OpenSSL says to use SSL_use_certificate before SSL_use_PrivateKey.
-
- byte[][] certificateBytes = NativeCrypto.encodeCertificates(certificates);
- NativeCrypto.SSL_use_certificate(sslNativePointer, certificateBytes);
-
- try {
- final OpenSSLKey key = OpenSSLKey.fromPrivateKey(privateKey);
- NativeCrypto.SSL_use_PrivateKey(sslNativePointer, key.getPkeyContext());
- } catch (InvalidKeyException e) {
- throw new SSLException(e);
- }
-
- // checks the last installed private key and certificate,
- // so need to do this once per loop iteration
- NativeCrypto.SSL_check_private_key(sslNativePointer);
- }
-
- @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / client_cert_cb
- public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals)
- throws CertificateEncodingException, SSLException {
-
- String[] keyTypes = new String[keyTypeBytes.length];
- for (int i = 0; i < keyTypeBytes.length; i++) {
- keyTypes[i] = CipherSuite.getClientKeyType(keyTypeBytes[i]);
- }
-
- X500Principal[] issuers;
- if (asn1DerEncodedPrincipals == null) {
- issuers = null;
- } else {
- issuers = new X500Principal[asn1DerEncodedPrincipals.length];
- for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) {
- issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]);
- }
- }
- setCertificate(sslParameters.getKeyManager().chooseClientAlias(keyTypes, issuers, this));
- }
-
- @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / info_callback
- public void handshakeCompleted() {
- handshakeCompleted = true;
-
- // If sslSession is null, the handshake was completed during
- // the call to NativeCrypto.SSL_do_handshake and not during a
- // later read operation. That means we do not need to fix up
- // the SSLSession and session cache or notify
- // HandshakeCompletedListeners, it will be done in
- // startHandshake.
- if (sslSession == null) {
- return;
- }
-
- // reset session id from the native pointer and update the
- // appropriate cache.
- sslSession.resetId();
- AbstractSessionContext sessionContext =
- (sslParameters.getUseClientMode())
- ? sslParameters.getClientSessionContext()
- : sslParameters.getServerSessionContext();
- sessionContext.putSession(sslSession);
-
- // let listeners know we are finally done
- notifyHandshakeCompletedListeners();
- }
-
- private void notifyHandshakeCompletedListeners() {
- if (listeners != null && !listeners.isEmpty()) {
- // notify the listeners
- HandshakeCompletedEvent event =
- new HandshakeCompletedEvent(this, sslSession);
- for (HandshakeCompletedListener listener : listeners) {
- try {
- listener.handshakeCompleted(event);
- } catch (RuntimeException e) {
- // The RI runs the handlers in a separate thread,
- // which we do not. But we try to preserve their
- // behavior of logging a problem and not killing
- // the handshaking thread just because a listener
- // has a problem.
- Thread thread = Thread.currentThread();
- thread.getUncaughtExceptionHandler().uncaughtException(thread, e);
- }
- }
- }
- }
-
- @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks
- @Override public void verifyCertificateChain(byte[][] bytes, String authMethod)
- throws CertificateException {
- try {
- if (bytes == null || bytes.length == 0) {
- throw new SSLException("Peer sent no certificate");
- }
- X509Certificate[] peerCertificateChain = new X509Certificate[bytes.length];
- for (int i = 0; i < bytes.length; i++) {
- peerCertificateChain[i] = OpenSSLX509Certificate.fromX509Der(bytes[i]);
- }
- boolean client = sslParameters.getUseClientMode();
- if (client) {
- X509TrustManager x509tm = sslParameters.getTrustManager();
- if (x509tm instanceof TrustManagerImpl) {
- TrustManagerImpl tm = (TrustManagerImpl) x509tm;
- tm.checkServerTrusted(peerCertificateChain, authMethod, wrappedHost);
- } else {
- x509tm.checkServerTrusted(peerCertificateChain, authMethod);
- }
- } else {
- String authType = peerCertificateChain[0].getPublicKey().getAlgorithm();
- sslParameters.getTrustManager().checkClientTrusted(peerCertificateChain,
- authType);
- }
-
- } catch (CertificateException e) {
- throw e;
- } catch (Exception e) {
- throw new CertificateException(e);
- }
- }
-
- @Override public InputStream getInputStream() throws IOException {
- checkOpen();
- synchronized (this) {
- if (is == null) {
- is = new SSLInputStream();
- }
-
- return is;
- }
- }
-
- @Override public OutputStream getOutputStream() throws IOException {
- checkOpen();
- synchronized (this) {
- if (os == null) {
- os = new SSLOutputStream();
- }
-
- return os;
- }
- }
-
- /**
- * This inner class provides input data stream functionality
- * for the OpenSSL native implementation. It is used to
- * read data received via SSL protocol.
- */
- private class SSLInputStream extends InputStream {
- SSLInputStream() throws IOException {
- /*
- * Note: When startHandshake() throws an exception, no
- * SSLInputStream object will be created.
- */
- OpenSSLSocketImpl.this.startHandshake();
- }
-
- /**
- * Reads one byte. If there is no data in the underlying buffer,
- * this operation can block until the data will be
- * available.
- * @return read value.
- * @throws <code>IOException</code>
- */
- @Override
- public int read() throws IOException {
- return Streams.readSingleByte(this);
- }
-
- /**
- * Method acts as described in spec for superclass.
- * @see java.io.InputStream#read(byte[],int,int)
- */
- @Override
- public int read(byte[] buf, int offset, int byteCount) throws IOException {
- BlockGuard.getThreadPolicy().onNetwork();
- synchronized (readLock) {
- checkOpen();
- Arrays.checkOffsetAndCount(buf.length, offset, byteCount);
- if (byteCount == 0) {
- return 0;
- }
- return NativeCrypto.SSL_read(sslNativePointer, socket.getFileDescriptor$(),
- OpenSSLSocketImpl.this, buf, offset, byteCount, getSoTimeout());
- }
- }
- }
-
- /**
- * This inner class provides output data stream functionality
- * for the OpenSSL native implementation. It is used to
- * write data according to the encryption parameters given in SSL context.
- */
- private class SSLOutputStream extends OutputStream {
- SSLOutputStream() throws IOException {
- /*
- * Note: When startHandshake() throws an exception, no
- * SSLOutputStream object will be created.
- */
- OpenSSLSocketImpl.this.startHandshake();
- }
-
- /**
- * Method acts as described in spec for superclass.
- * @see java.io.OutputStream#write(int)
- */
- @Override
- public void write(int oneByte) throws IOException {
- Streams.writeSingleByte(this, oneByte);
- }
-
- /**
- * Method acts as described in spec for superclass.
- * @see java.io.OutputStream#write(byte[],int,int)
- */
- @Override
- public void write(byte[] buf, int offset, int byteCount) throws IOException {
- BlockGuard.getThreadPolicy().onNetwork();
- synchronized (writeLock) {
- checkOpen();
- Arrays.checkOffsetAndCount(buf.length, offset, byteCount);
- if (byteCount == 0) {
- return;
- }
- NativeCrypto.SSL_write(sslNativePointer, socket.getFileDescriptor$(),
- OpenSSLSocketImpl.this, buf, offset, byteCount, writeTimeoutMilliseconds);
- }
- }
- }
-
-
- @Override public SSLSession getSession() {
- if (sslSession == null) {
- try {
- startHandshake();
- } catch (IOException e) {
- // return an invalid session with
- // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
- return SSLSessionImpl.getNullSession();
- }
- }
- return sslSession;
- }
-
- @Override public void addHandshakeCompletedListener(
- HandshakeCompletedListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("Provided listener is null");
- }
- if (listeners == null) {
- listeners = new ArrayList<HandshakeCompletedListener>();
- }
- listeners.add(listener);
- }
-
- @Override public void removeHandshakeCompletedListener(
- HandshakeCompletedListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("Provided listener is null");
- }
- if (listeners == null) {
- throw new IllegalArgumentException(
- "Provided listener is not registered");
- }
- if (!listeners.remove(listener)) {
- throw new IllegalArgumentException(
- "Provided listener is not registered");
- }
- }
-
- @Override public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
- @Override public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- @Override public String[] getSupportedCipherSuites() {
- return NativeCrypto.getSupportedCipherSuites();
- }
-
- @Override public String[] getEnabledCipherSuites() {
- return enabledCipherSuites.clone();
- }
-
- @Override public void setEnabledCipherSuites(String[] suites) {
- enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites);
- }
-
- @Override public String[] getSupportedProtocols() {
- return NativeCrypto.getSupportedProtocols();
- }
-
- @Override public String[] getEnabledProtocols() {
- return enabledProtocols.clone();
- }
-
- @Override public void setEnabledProtocols(String[] protocols) {
- enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols);
- }
-
- /**
- * This method enables session ticket support.
- *
- * @param useSessionTickets True to enable session tickets
- */
- public void setUseSessionTickets(boolean useSessionTickets) {
- this.useSessionTickets = useSessionTickets;
- }
-
- /**
- * This method enables Server Name Indication
- *
- * @param hostname the desired SNI hostname, or null to disable
- */
- public void setHostname(String hostname) {
- this.hostname = hostname;
- }
-
- /**
- * Enables/disables TLS Channel ID for this server socket.
- *
- * <p>This method needs to be invoked before the handshake starts.
- *
- * @throws IllegalStateException if this is a client socket or if the handshake has already
- * started.
-
- */
- public void setChannelIdEnabled(boolean enabled) {
- if (getUseClientMode()) {
- throw new IllegalStateException("Client mode");
- }
- if (handshakeStarted) {
- throw new IllegalStateException(
- "Could not enable/disable Channel ID after the initial handshake has"
- + " begun.");
- }
- this.channelIdEnabled = enabled;
- }
-
- /**
- * Gets the TLS Channel ID for this server socket. Channel ID is only available once the
- * handshake completes.
- *
- * @return channel ID or {@code null} if not available.
- *
- * @throws IllegalStateException if this is a client socket or if the handshake has not yet
- * completed.
- * @throws SSLException if channel ID is available but could not be obtained.
- */
- public byte[] getChannelId() throws SSLException {
- if (getUseClientMode()) {
- throw new IllegalStateException("Client mode");
- }
- if (!handshakeCompleted) {
- throw new IllegalStateException(
- "Channel ID is only available after handshake completes");
- }
- return NativeCrypto.SSL_get_tls_channel_id(sslNativePointer);
- }
-
- /**
- * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket.
- *
- * <p>This method needs to be invoked before the handshake starts.
- *
- * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
- * TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
- * P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
- *
- * @throws IllegalStateException if this is a server socket or if the handshake has already
- * started.
- */
- public void setChannelIdPrivateKey(PrivateKey privateKey) {
- if (!getUseClientMode()) {
- throw new IllegalStateException("Server mode");
- }
- if (handshakeStarted) {
- throw new IllegalStateException(
- "Could not change Channel ID private key after the initial handshake has"
- + " begun.");
- }
- if (privateKey == null) {
- this.channelIdEnabled = false;
- this.channelIdPrivateKey = null;
- } else {
- this.channelIdEnabled = true;
- try {
- this.channelIdPrivateKey = OpenSSLKey.fromPrivateKey(privateKey);
- } catch (InvalidKeyException e) {
- // Will have error in startHandshake
- }
- }
- }
-
- @Override public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- @Override public void setUseClientMode(boolean mode) {
- if (handshakeStarted) {
- throw new IllegalArgumentException(
- "Could not change the mode after the initial handshake has begun.");
- }
- sslParameters.setUseClientMode(mode);
- }
-
- @Override public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- @Override public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- @Override public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- @Override public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- @Override public void sendUrgentData(int data) throws IOException {
- throw new SocketException("Method sendUrgentData() is not supported.");
- }
-
- @Override public void setOOBInline(boolean on) throws SocketException {
- throw new SocketException("Methods sendUrgentData, setOOBInline are not supported.");
- }
-
- @Override public void setSoTimeout(int readTimeoutMilliseconds) throws SocketException {
- super.setSoTimeout(readTimeoutMilliseconds);
- this.readTimeoutMilliseconds = readTimeoutMilliseconds;
- }
-
- @Override public int getSoTimeout() throws SocketException {
- return readTimeoutMilliseconds;
- }
-
- /**
- * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
- */
- public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
- this.writeTimeoutMilliseconds = writeTimeoutMilliseconds;
-
- StructTimeval tv = StructTimeval.fromMillis(writeTimeoutMilliseconds);
- try {
- Libcore.os.setsockoptTimeval(getFileDescriptor$(), SOL_SOCKET, SO_SNDTIMEO, tv);
- } catch (ErrnoException errnoException) {
- throw errnoException.rethrowAsSocketException();
- }
- }
-
- /**
- * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
- */
- public int getSoWriteTimeout() throws SocketException {
- return writeTimeoutMilliseconds;
- }
-
- /**
- * Set the handshake timeout on this socket. This timeout is specified in
- * milliseconds and will be used only during the handshake process.
- */
- public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
- this.handshakeTimeoutMilliseconds = handshakeTimeoutMilliseconds;
- }
-
- @Override public void close() throws IOException {
- // TODO: Close SSL sockets using a background thread so they close gracefully.
-
- synchronized (handshakeLock) {
- if (!handshakeStarted) {
- // prevent further attempts to start handshake
- handshakeStarted = true;
-
- synchronized (this) {
- free();
-
- if (socket != this) {
- if (autoClose && !socket.isClosed()) socket.close();
- } else {
- if (!super.isClosed()) super.close();
- }
- }
-
- return;
- }
- }
-
- synchronized (this) {
-
- // Interrupt any outstanding reads or writes before taking the writeLock and readLock
- NativeCrypto.SSL_interrupt(sslNativePointer);
-
- synchronized (writeLock) {
- synchronized (readLock) {
- // Shut down the SSL connection, per se.
- try {
- if (handshakeStarted) {
- BlockGuard.getThreadPolicy().onNetwork();
- NativeCrypto.SSL_shutdown(sslNativePointer, socket.getFileDescriptor$(),
- this);
- }
- } catch (IOException ignored) {
- /*
- * Note that although close() can throw
- * IOException, the RI does not throw if there
- * is problem sending a "close notify" which
- * can happen if the underlying socket is closed.
- */
- } finally {
- /*
- * Even if the above call failed, it is still safe to free
- * the native structs, and we need to do so lest we leak
- * memory.
- */
- free();
-
- if (socket != this) {
- if (autoClose && !socket.isClosed()) {
- socket.close();
- }
- } else {
- if (!super.isClosed()) {
- super.close();
- }
- }
- }
- }
- }
- }
- }
-
- private void free() {
- if (sslNativePointer == 0) {
- return;
- }
- NativeCrypto.SSL_free(sslNativePointer);
- sslNativePointer = 0;
- guard.close();
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- /*
- * Just worry about our own state. Notably we do not try and
- * close anything. The SocketImpl, either our own
- * PlainSocketImpl, or the Socket we are wrapping, will do
- * that. This might mean we do not properly SSL_shutdown, but
- * if you want to do that, properly close the socket yourself.
- *
- * The reason why we don't try to SSL_shutdown, is that there
- * can be a race between finalizers where the PlainSocketImpl
- * finalizer runs first and closes the socket. However, in the
- * meanwhile, the underlying file descriptor could be reused
- * for another purpose. If we call SSL_shutdown, the
- * underlying socket BIOs still have the old file descriptor
- * and will write the close notify to some unsuspecting
- * reader.
- */
- if (guard != null) {
- guard.warnIfOpen();
- }
- free();
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public FileDescriptor getFileDescriptor$() {
- if (socket == this) {
- return super.getFileDescriptor$();
- } else {
- return socket.getFileDescriptor$();
- }
- }
-
- /**
- * Returns the protocol agreed upon by client and server, or null if no
- * protocol was agreed upon.
- */
- public byte[] getNpnSelectedProtocol() {
- return NativeCrypto.SSL_get_npn_negotiated_protocol(sslNativePointer);
- }
-
- /**
- * Returns the protocol agreed upon by client and server, or {@code null} if
- * no protocol was agreed upon.
- */
- public byte[] getAlpnSelectedProtocol() {
- return NativeCrypto.SSL_get0_alpn_selected(sslNativePointer);
- }
-
- /**
- * Sets the list of protocols this peer is interested in. If null no
- * protocols will be used.
- *
- * @param npnProtocols a non-empty array of protocol names. From
- * SSL_select_next_proto, "vector of 8-bit, length prefixed byte
- * strings. The length byte itself is not included in the length. A byte
- * string of length 0 is invalid. No byte string may be truncated.".
- */
- public void setNpnProtocols(byte[] npnProtocols) {
- if (npnProtocols != null && npnProtocols.length == 0) {
- throw new IllegalArgumentException("npnProtocols.length == 0");
- }
- this.npnProtocols = npnProtocols;
- }
-
- /**
- * Sets the list of protocols this peer is interested in. If the list is
- * {@code null}, no protocols will be used.
- *
- * @param alpnProtocols a non-empty array of protocol names. From
- * SSL_select_next_proto, "vector of 8-bit, length prefixed byte
- * strings. The length byte itself is not included in the length.
- * A byte string of length 0 is invalid. No byte string may be
- * truncated.".
- */
- public void setAlpnProtocols(byte[] alpnProtocols) {
- if (alpnProtocols != null && alpnProtocols.length == 0) {
- throw new IllegalArgumentException("alpnProtocols.length == 0");
- }
- this.alpnProtocols = alpnProtocols;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java b/crypto/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java
deleted file mode 100644
index b6f43fa..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-
-/**
- * This class wraps the SSL functionality over an existing connected socket.
- */
-public class OpenSSLSocketImplWrapper extends OpenSSLSocketImpl {
-
- private Socket socket;
-
- protected OpenSSLSocketImplWrapper(Socket socket, String host, int port,
- boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
- super(socket, host, port, autoClose, sslParameters);
- if (!socket.isConnected()) {
- throw new SocketException("Socket is not connected.");
- }
- this.socket = socket;
- }
-
- @Override
- public void connect(SocketAddress sockaddr, int timeout)
- throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public void connect(SocketAddress sockaddr) throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public void bind(SocketAddress sockaddr) throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public SocketAddress getRemoteSocketAddress() {
- return socket.getRemoteSocketAddress();
- }
-
- @Override
- public SocketAddress getLocalSocketAddress() {
- return socket.getLocalSocketAddress();
- }
-
- @Override
- public InetAddress getLocalAddress() {
- return socket.getLocalAddress();
- }
-
- @Override
- public InetAddress getInetAddress() {
- return socket.getInetAddress();
- }
-
- @Override
- public String toString() {
- return "SSL socket over " + socket.toString();
- }
-
- @Override
- public void setSoLinger(boolean on, int linger) throws SocketException {
- socket.setSoLinger(on, linger);
- }
-
- @Override
- public void setTcpNoDelay(boolean on) throws SocketException {
- socket.setTcpNoDelay(on);
- }
-
- @Override
- public void setReuseAddress(boolean on) throws SocketException {
- socket.setReuseAddress(on);
- }
-
- @Override
- public void setKeepAlive(boolean on) throws SocketException {
- socket.setKeepAlive(on);
- }
-
- @Override
- public void setTrafficClass(int tos) throws SocketException {
- socket.setTrafficClass(tos);
- }
-
- @Override
- public void setSoTimeout(int to) throws SocketException {
- socket.setSoTimeout(to);
- super.setSoTimeout(to);
- }
-
- @Override
- public void setSendBufferSize(int size) throws SocketException {
- socket.setSendBufferSize(size);
- }
-
- @Override
- public void setReceiveBufferSize(int size) throws SocketException {
- socket.setReceiveBufferSize(size);
- }
-
- @Override
- public boolean getTcpNoDelay() throws SocketException {
- return socket.getTcpNoDelay();
- }
-
- @Override
- public boolean getReuseAddress() throws SocketException {
- return socket.getReuseAddress();
- }
-
- @Override
- public boolean getOOBInline() throws SocketException {
- return socket.getOOBInline();
- }
-
- @Override
- public boolean getKeepAlive() throws SocketException {
- return socket.getKeepAlive();
- }
-
- @Override
- public int getTrafficClass() throws SocketException {
- return socket.getTrafficClass();
- }
-
- @Override
- public int getSoTimeout() throws SocketException {
- return socket.getSoTimeout();
- }
-
- @Override
- public int getSoLinger() throws SocketException {
- return socket.getSoLinger();
- }
-
- @Override
- public int getSendBufferSize() throws SocketException {
- return socket.getSendBufferSize();
- }
-
- @Override
- public int getReceiveBufferSize() throws SocketException {
- return socket.getReceiveBufferSize();
- }
-
- @Override
- public boolean isConnected() {
- return socket.isConnected();
- }
-
- @Override
- public boolean isClosed() {
- return socket.isClosed();
- }
-
- @Override
- public boolean isBound() {
- return socket.isBound();
- }
-
- @Override
- public boolean isOutputShutdown() {
- return socket.isOutputShutdown();
- }
-
- @Override
- public boolean isInputShutdown() {
- return socket.isInputShutdown();
- }
-
- @Override
- public int getPort() {
- return socket.getPort();
- }
-
- @Override
- public int getLocalPort() {
- return socket.getLocalPort();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509CRL.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509CRL.java
deleted file mode 100644
index 56b99cc..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509CRL.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CRLException;
-import java.security.cert.Certificate;
-import java.security.cert.X509CRL;
-import java.security.cert.X509CRLEntry;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TimeZone;
-import javax.security.auth.x500.X500Principal;
-
-public class OpenSSLX509CRL extends X509CRL {
- private final long mContext;
-
- private OpenSSLX509CRL(long ctx) {
- mContext = ctx;
- }
-
- public static OpenSSLX509CRL fromX509DerInputStream(InputStream is) throws ParsingException {
- final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- try {
- final long crlCtx = NativeCrypto.d2i_X509_CRL_bio(bis.getBioContext());
- if (crlCtx == 0) {
- return null;
- }
- return new OpenSSLX509CRL(crlCtx);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
- }
-
- public static List<OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is)
- throws ParsingException {
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.d2i_PKCS7_bio(bis.getBioContext(), NativeCrypto.PKCS7_CRLS);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- final List<OpenSSLX509CRL> certs = new ArrayList<OpenSSLX509CRL>(certRefs.length);
- for (int i = 0; i < certRefs.length; i++) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509CRL(certRefs[i]));
- }
- return certs;
- }
-
- public static OpenSSLX509CRL fromX509PemInputStream(InputStream is) throws ParsingException {
- final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- try {
- final long crlCtx = NativeCrypto.PEM_read_bio_X509_CRL(bis.getBioContext());
- if (crlCtx == 0) {
- return null;
- }
- return new OpenSSLX509CRL(crlCtx);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
- }
-
- public static List<OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is)
- throws ParsingException {
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.PEM_read_bio_PKCS7(bis.getBioContext(),
- NativeCrypto.PKCS7_CRLS);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- final List<OpenSSLX509CRL> certs = new ArrayList<OpenSSLX509CRL>(certRefs.length);
- for (int i = 0; i < certRefs.length; i++) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509CRL(certRefs[i]));
- }
- return certs;
- }
-
- @Override
- public Set<String> getCriticalExtensionOIDs() {
- String[] critOids =
- NativeCrypto.get_X509_CRL_ext_oids(mContext, NativeCrypto.EXTENSION_TYPE_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no critical extensions, we'll check
- * non-critical extensions.
- */
- if ((critOids.length == 0)
- && (NativeCrypto.get_X509_CRL_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(critOids));
- }
-
- @Override
- public byte[] getExtensionValue(String oid) {
- return NativeCrypto.X509_CRL_get_ext_oid(mContext, oid);
- }
-
- @Override
- public Set<String> getNonCriticalExtensionOIDs() {
- String[] nonCritOids =
- NativeCrypto.get_X509_CRL_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no non-critical extensions, we'll
- * check critical extensions.
- */
- if ((nonCritOids.length == 0)
- && (NativeCrypto.get_X509_CRL_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(nonCritOids));
- }
-
- @Override
- public boolean hasUnsupportedCriticalExtension() {
- final String[] criticalOids =
- NativeCrypto.get_X509_CRL_ext_oids(mContext, NativeCrypto.EXTENSION_TYPE_CRITICAL);
- for (String oid : criticalOids) {
- final long extensionRef = NativeCrypto.X509_CRL_get_ext(mContext, oid);
- if (NativeCrypto.X509_supported_extension(extensionRef) != 1) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public byte[] getEncoded() throws CRLException {
- return NativeCrypto.i2d_X509_CRL(mContext);
- }
-
- private void verifyOpenSSL(OpenSSLKey pkey) throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException {
- NativeCrypto.X509_CRL_verify(mContext, pkey.getPkeyContext());
- }
-
- private void verifyInternal(PublicKey key, String sigProvider) throws CRLException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- String sigAlg = getSigAlgName();
- if (sigAlg == null) {
- sigAlg = getSigAlgOID();
- }
-
- final Signature sig;
- if (sigProvider == null) {
- sig = Signature.getInstance(sigAlg);
- } else {
- sig = Signature.getInstance(sigAlg, sigProvider);
- }
-
- sig.initVerify(key);
- sig.update(getTBSCertList());
- if (!sig.verify(getSignature())) {
- throw new SignatureException("signature did not verify");
- }
- }
-
- @Override
- public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException {
- if (key instanceof OpenSSLKeyHolder) {
- OpenSSLKey pkey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
- verifyOpenSSL(pkey);
- return;
- }
-
- verifyInternal(key, null);
- }
-
- @Override
- public void verify(PublicKey key, String sigProvider) throws CRLException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- verifyInternal(key, sigProvider);
- }
-
- @Override
- public int getVersion() {
- return (int) NativeCrypto.X509_CRL_get_version(mContext) + 1;
- }
-
- @Override
- public Principal getIssuerDN() {
- return getIssuerX500Principal();
- }
-
- @Override
- public X500Principal getIssuerX500Principal() {
- final byte[] issuer = NativeCrypto.X509_CRL_get_issuer_name(mContext);
- return new X500Principal(issuer);
- }
-
- @Override
- public Date getThisUpdate() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.X509_CRL_get_lastUpdate(mContext),
- calendar);
- return calendar.getTime();
- }
-
- @Override
- public Date getNextUpdate() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.X509_CRL_get_nextUpdate(mContext),
- calendar);
- return calendar.getTime();
- }
-
- @Override
- public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) {
- final long revokedRef = NativeCrypto.X509_CRL_get0_by_serial(mContext,
- serialNumber.toByteArray());
- if (revokedRef == 0) {
- return null;
- }
-
- return new OpenSSLX509CRLEntry(NativeCrypto.X509_REVOKED_dup(revokedRef));
- }
-
- @Override
- public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
- if (certificate instanceof OpenSSLX509Certificate) {
- OpenSSLX509Certificate osslCert = (OpenSSLX509Certificate) certificate;
- final long x509RevokedRef = NativeCrypto.X509_CRL_get0_by_cert(mContext,
- osslCert.getContext());
-
- if (x509RevokedRef == 0) {
- return null;
- }
-
- return new OpenSSLX509CRLEntry(NativeCrypto.X509_REVOKED_dup(x509RevokedRef));
- }
-
- return getRevokedCertificate(certificate.getSerialNumber());
- }
-
- @Override
- public Set<? extends X509CRLEntry> getRevokedCertificates() {
- final long[] entryRefs = NativeCrypto.X509_CRL_get_REVOKED(mContext);
- if (entryRefs == null || entryRefs.length == 0) {
- return null;
- }
-
- final Set<OpenSSLX509CRLEntry> crlSet = new HashSet<OpenSSLX509CRLEntry>();
- for (long entryRef : entryRefs) {
- crlSet.add(new OpenSSLX509CRLEntry(entryRef));
- }
-
- return crlSet;
- }
-
- @Override
- public byte[] getTBSCertList() throws CRLException {
- return NativeCrypto.get_X509_CRL_crl_enc(mContext);
- }
-
- @Override
- public byte[] getSignature() {
- return NativeCrypto.get_X509_CRL_signature(mContext);
- }
-
- @Override
- public String getSigAlgName() {
- return AlgNameMapper.map2AlgName(getSigAlgOID());
- }
-
- @Override
- public String getSigAlgOID() {
- return NativeCrypto.get_X509_CRL_sig_alg_oid(mContext);
- }
-
- @Override
- public byte[] getSigAlgParams() {
- return NativeCrypto.get_X509_CRL_sig_alg_parameter(mContext);
- }
-
- @Override
- public boolean isRevoked(Certificate cert) {
- if (!(cert instanceof X509Certificate)) {
- return false;
- }
-
- final OpenSSLX509Certificate osslCert;
- if (cert instanceof OpenSSLX509Certificate) {
- osslCert = (OpenSSLX509Certificate) cert;
- } else {
- try {
- osslCert = OpenSSLX509Certificate.fromX509DerInputStream(new ByteArrayInputStream(
- cert.getEncoded()));
- } catch (Exception e) {
- throw new RuntimeException("cannot convert certificate", e);
- }
- }
-
- final long x509RevokedRef = NativeCrypto.X509_CRL_get0_by_cert(mContext,
- osslCert.getContext());
-
- return x509RevokedRef != 0;
- }
-
- @Override
- public String toString() {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- final long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
- try {
- NativeCrypto.X509_CRL_print(bioCtx, mContext);
- return os.toString();
- } finally {
- NativeCrypto.BIO_free(bioCtx);
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mContext != 0) {
- NativeCrypto.X509_CRL_free(mContext);
- }
- } finally {
- super.finalize();
- }
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java
deleted file mode 100644
index 470cc98..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.ByteArrayOutputStream;
-import java.math.BigInteger;
-import java.security.cert.CRLException;
-import java.security.cert.X509CRLEntry;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TimeZone;
-
-public class OpenSSLX509CRLEntry extends X509CRLEntry {
- private final long mContext;
-
- OpenSSLX509CRLEntry(long ctx) {
- mContext = ctx;
- }
-
- @Override
- public Set<String> getCriticalExtensionOIDs() {
- String[] critOids =
- NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no critical extensions, we'll check
- * non-critical extensions.
- */
- if ((critOids.length == 0)
- && (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(critOids));
- }
-
- @Override
- public byte[] getExtensionValue(String oid) {
- return NativeCrypto.X509_REVOKED_get_ext_oid(mContext, oid);
- }
-
- @Override
- public Set<String> getNonCriticalExtensionOIDs() {
- String[] critOids =
- NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no non-critical extensions, we'll
- * check critical extensions.
- */
- if ((critOids.length == 0)
- && (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(critOids));
- }
-
- @Override
- public boolean hasUnsupportedCriticalExtension() {
- final String[] criticalOids =
- NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL);
- for (String oid : criticalOids) {
- final long extensionRef = NativeCrypto.X509_REVOKED_get_ext(mContext, oid);
- if (NativeCrypto.X509_supported_extension(extensionRef) != 1) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public byte[] getEncoded() throws CRLException {
- return NativeCrypto.i2d_X509_REVOKED(mContext);
- }
-
- @Override
- public BigInteger getSerialNumber() {
- return new BigInteger(NativeCrypto.X509_REVOKED_get_serialNumber(mContext));
- }
-
- @Override
- public Date getRevocationDate() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.get_X509_REVOKED_revocationDate(mContext),
- calendar);
- return calendar.getTime();
- }
-
- @Override
- public boolean hasExtensions() {
- return (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length != 0)
- || (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL).length != 0);
- }
-
- @Override
- public String toString() {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
- try {
- NativeCrypto.X509_REVOKED_print(bioCtx, mContext);
- return os.toString();
- } finally {
- NativeCrypto.BIO_free(bioCtx);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509CertPath.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509CertPath.java
deleted file mode 100644
index 57568b8..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509CertPath.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.security.cert.CertPath;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
-
-public class OpenSSLX509CertPath extends CertPath {
- private static final byte[] PKCS7_MARKER = "-----BEGIN PKCS7".getBytes();
-
- private static final int PUSHBACK_SIZE = 64;
-
- /**
- * Supported encoding types for CerthPath. Used by the various APIs that
- * encode this into bytes such as {@link #getEncoded()}.
- */
- private enum Encoding {
- PKI_PATH("PkiPath"),
- PKCS7("PKCS7");
-
- private final String apiName;
-
- Encoding(String apiName) {
- this.apiName = apiName;
- }
-
- static Encoding findByApiName(String apiName) throws CertificateEncodingException {
- for (Encoding element : values()) {
- if (element.apiName.equals(apiName)) {
- return element;
- }
- }
-
- return null;
- }
- }
-
- /** Unmodifiable list of encodings for the API. */
- private static final List<String> ALL_ENCODINGS = Collections.unmodifiableList(Arrays
- .asList(new String[] {
- Encoding.PKI_PATH.apiName,
- Encoding.PKCS7.apiName,
- }));
-
- private static final Encoding DEFAULT_ENCODING = Encoding.PKI_PATH;
-
- private final List<? extends X509Certificate> mCertificates;
-
- static Iterator<String> getEncodingsIterator() {
- return ALL_ENCODINGS.iterator();
- }
-
- protected OpenSSLX509CertPath(List<? extends X509Certificate> certificates) {
- super("X.509");
-
- mCertificates = certificates;
- }
-
- @Override
- public List<? extends Certificate> getCertificates() {
- return Collections.unmodifiableList(mCertificates);
- }
-
- private byte[] getEncoded(Encoding encoding) throws CertificateEncodingException {
- final OpenSSLX509Certificate[] certs = new OpenSSLX509Certificate[mCertificates.size()];
- final long[] certRefs = new long[certs.length];
-
- for (int i = 0, j = certs.length - 1; j >= 0; i++, j--) {
- final X509Certificate cert = mCertificates.get(i);
-
- if (cert instanceof OpenSSLX509Certificate) {
- certs[j] = (OpenSSLX509Certificate) cert;
- } else {
- certs[j] = OpenSSLX509Certificate.fromX509Der(cert.getEncoded());
- }
-
- certRefs[j] = certs[j].getContext();
- }
-
- switch (encoding) {
- case PKI_PATH:
- return NativeCrypto.ASN1_seq_pack_X509(certRefs);
- case PKCS7:
- return NativeCrypto.i2d_PKCS7(certRefs);
- default:
- throw new CertificateEncodingException("Unknown encoding");
- }
- }
-
- @Override
- public byte[] getEncoded() throws CertificateEncodingException {
- return getEncoded(DEFAULT_ENCODING);
- }
-
- @Override
- public byte[] getEncoded(String encoding) throws CertificateEncodingException {
- Encoding enc = Encoding.findByApiName(encoding);
- if (enc == null) {
- throw new CertificateEncodingException("Invalid encoding: " + encoding);
- }
-
- return getEncoded(enc);
- }
-
- @Override
- public Iterator<String> getEncodings() {
- return getEncodingsIterator();
- }
-
- private static CertPath fromPkiPathEncoding(InputStream inStream) throws CertificateException {
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(inStream);
-
- final boolean markable = inStream.markSupported();
- if (markable) {
- inStream.mark(PUSHBACK_SIZE);
- }
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.ASN1_seq_unpack_X509_bio(bis.getBioContext());
- } catch (Exception e) {
- if (markable) {
- try {
- inStream.reset();
- } catch (IOException ignored) {
- }
- }
- throw new CertificateException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- if (certRefs == null) {
- return new OpenSSLX509CertPath(Collections.<X509Certificate> emptyList());
- }
-
- final List<OpenSSLX509Certificate> certs =
- new ArrayList<OpenSSLX509Certificate>(certRefs.length);
- for (int i = certRefs.length - 1; i >= 0; i--) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509Certificate(certRefs[i]));
- }
-
- return new OpenSSLX509CertPath(certs);
- }
-
- private static CertPath fromPkcs7Encoding(InputStream inStream) throws CertificateException {
- try {
- if (inStream == null || inStream.available() == 0) {
- return new OpenSSLX509CertPath(Collections.<X509Certificate> emptyList());
- }
- } catch (IOException e) {
- throw new CertificateException("Problem reading input stream", e);
- }
-
- final boolean markable = inStream.markSupported();
- if (markable) {
- inStream.mark(PUSHBACK_SIZE);
- }
-
- /* Attempt to see if this is a PKCS#7 bag. */
- final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE);
- try {
- final byte[] buffer = new byte[PKCS7_MARKER.length];
-
- final int len = pbis.read(buffer);
- if (len < 0) {
- /* No need to reset here. The stream was empty or EOF. */
- throw new ParsingException("inStream is empty");
- }
- pbis.unread(buffer, 0, len);
-
- if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
- return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7PemInputStream(pbis));
- }
-
- return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7DerInputStream(pbis));
- } catch (Exception e) {
- if (markable) {
- try {
- inStream.reset();
- } catch (IOException ignored) {
- }
- }
- throw new CertificateException(e);
- }
- }
-
- private static CertPath fromEncoding(InputStream inStream, Encoding encoding)
- throws CertificateException {
- switch (encoding) {
- case PKI_PATH:
- return fromPkiPathEncoding(inStream);
- case PKCS7:
- return fromPkcs7Encoding(inStream);
- default:
- throw new CertificateEncodingException("Unknown encoding");
- }
- }
-
- public static CertPath fromEncoding(InputStream inStream, String encoding)
- throws CertificateException {
- if (inStream == null) {
- throw new CertificateException("inStream == null");
- }
-
- Encoding enc = Encoding.findByApiName(encoding);
- if (enc == null) {
- throw new CertificateException("Invalid encoding: " + encoding);
- }
-
- return fromEncoding(inStream, enc);
- }
-
- public static CertPath fromEncoding(InputStream inStream) throws CertificateException {
- return fromEncoding(inStream, DEFAULT_ENCODING);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509Certificate.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509Certificate.java
deleted file mode 100644
index b1cd986..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509Certificate.java
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TimeZone;
-import javax.security.auth.x500.X500Principal;
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
-
-public class OpenSSLX509Certificate extends X509Certificate {
- private final long mContext;
-
- OpenSSLX509Certificate(long ctx) {
- mContext = ctx;
- }
-
- public static OpenSSLX509Certificate fromX509DerInputStream(InputStream is)
- throws ParsingException {
- @SuppressWarnings("resource")
- final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- try {
- final long certCtx = NativeCrypto.d2i_X509_bio(bis.getBioContext());
- if (certCtx == 0) {
- return null;
- }
- return new OpenSSLX509Certificate(certCtx);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
- }
-
- public static OpenSSLX509Certificate fromX509Der(byte[] encoded) {
- final long certCtx = NativeCrypto.d2i_X509(encoded);
- if (certCtx == 0) {
- return null;
- }
- return new OpenSSLX509Certificate(certCtx);
- }
-
- public static List<OpenSSLX509Certificate> fromPkcs7DerInputStream(InputStream is)
- throws ParsingException {
- @SuppressWarnings("resource")
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.d2i_PKCS7_bio(bis.getBioContext(), NativeCrypto.PKCS7_CERTS);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- if (certRefs == null) {
- return Collections.emptyList();
- }
-
- final List<OpenSSLX509Certificate> certs = new ArrayList<OpenSSLX509Certificate>(
- certRefs.length);
- for (int i = 0; i < certRefs.length; i++) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509Certificate(certRefs[i]));
- }
- return certs;
- }
-
- public static OpenSSLX509Certificate fromX509PemInputStream(InputStream is)
- throws ParsingException {
- @SuppressWarnings("resource")
- final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- try {
- final long certCtx = NativeCrypto.PEM_read_bio_X509(bis.getBioContext());
- if (certCtx == 0L) {
- return null;
- }
- return new OpenSSLX509Certificate(certCtx);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
- }
-
- public static List<OpenSSLX509Certificate> fromPkcs7PemInputStream(InputStream is)
- throws ParsingException {
- @SuppressWarnings("resource")
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.PEM_read_bio_PKCS7(bis.getBioContext(),
- NativeCrypto.PKCS7_CERTS);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- final List<OpenSSLX509Certificate> certs = new ArrayList<OpenSSLX509Certificate>(
- certRefs.length);
- for (int i = 0; i < certRefs.length; i++) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509Certificate(certRefs[i]));
- }
- return certs;
- }
-
- @Override
- public Set<String> getCriticalExtensionOIDs() {
- String[] critOids =
- NativeCrypto.get_X509_ext_oids(mContext, NativeCrypto.EXTENSION_TYPE_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no critical extensions, we'll check
- * non-critical extensions.
- */
- if ((critOids.length == 0)
- && (NativeCrypto.get_X509_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(critOids));
- }
-
- @Override
- public byte[] getExtensionValue(String oid) {
- return NativeCrypto.X509_get_ext_oid(mContext, oid);
- }
-
- @Override
- public Set<String> getNonCriticalExtensionOIDs() {
- String[] nonCritOids =
- NativeCrypto.get_X509_ext_oids(mContext, NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no non-critical extensions, we'll
- * check critical extensions.
- */
- if ((nonCritOids.length == 0)
- && (NativeCrypto.get_X509_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(nonCritOids));
- }
-
- @Override
- public boolean hasUnsupportedCriticalExtension() {
- return (NativeCrypto.get_X509_ex_flags(mContext) & NativeCrypto.EXFLAG_CRITICAL) != 0;
- }
-
- @Override
- public void checkValidity() throws CertificateExpiredException,
- CertificateNotYetValidException {
- checkValidity(new Date());
- }
-
- @Override
- public void checkValidity(Date date) throws CertificateExpiredException,
- CertificateNotYetValidException {
- if (getNotBefore().compareTo(date) > 0) {
- throw new CertificateNotYetValidException();
- }
-
- if (getNotAfter().compareTo(date) < 0) {
- throw new CertificateExpiredException();
- }
- }
-
- @Override
- public int getVersion() {
- return (int) NativeCrypto.X509_get_version(mContext) + 1;
- }
-
- @Override
- public BigInteger getSerialNumber() {
- return new BigInteger(NativeCrypto.X509_get_serialNumber(mContext));
- }
-
- @Override
- public Principal getIssuerDN() {
- return getIssuerX500Principal();
- }
-
- @Override
- public Principal getSubjectDN() {
- return getSubjectX500Principal();
- }
-
- @Override
- public Date getNotBefore() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.X509_get_notBefore(mContext), calendar);
- return calendar.getTime();
- }
-
- @Override
- public Date getNotAfter() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.X509_get_notAfter(mContext), calendar);
- return calendar.getTime();
- }
-
- @Override
- public byte[] getTBSCertificate() throws CertificateEncodingException {
- return NativeCrypto.get_X509_cert_info_enc(mContext);
- }
-
- @Override
- public byte[] getSignature() {
- return NativeCrypto.get_X509_signature(mContext);
- }
-
- @Override
- public String getSigAlgName() {
- return AlgNameMapper.map2AlgName(getSigAlgOID());
- }
-
- @Override
- public String getSigAlgOID() {
- return NativeCrypto.get_X509_sig_alg_oid(mContext);
- }
-
- @Override
- public byte[] getSigAlgParams() {
- return NativeCrypto.get_X509_sig_alg_parameter(mContext);
- }
-
- @Override
- public boolean[] getIssuerUniqueID() {
- return NativeCrypto.get_X509_issuerUID(mContext);
- }
-
- @Override
- public boolean[] getSubjectUniqueID() {
- return NativeCrypto.get_X509_subjectUID(mContext);
- }
-
- @Override
- public boolean[] getKeyUsage() {
- final boolean[] kusage = NativeCrypto.get_X509_ex_kusage(mContext);
- if (kusage == null) {
- return null;
- }
-
- if (kusage.length >= 9) {
- return kusage;
- }
-
- final boolean resized[] = new boolean[9];
- System.arraycopy(kusage, 0, resized, 0, kusage.length);
- return resized;
- }
-
- @Override
- public int getBasicConstraints() {
- if ((NativeCrypto.get_X509_ex_flags(mContext) & NativeCrypto.EXFLAG_CA) == 0) {
- return -1;
- }
-
- final int pathLen = NativeCrypto.get_X509_ex_pathlen(mContext);
- if (pathLen == -1) {
- return Integer.MAX_VALUE;
- }
-
- return pathLen;
- }
-
- @Override
- public byte[] getEncoded() throws CertificateEncodingException {
- return NativeCrypto.i2d_X509(mContext);
- }
-
- private void verifyOpenSSL(OpenSSLKey pkey) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- try {
- NativeCrypto.X509_verify(mContext, pkey.getPkeyContext());
- } catch (RuntimeException e) {
- throw new CertificateException(e);
- }
- }
-
- private void verifyInternal(PublicKey key, String sigProvider) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- String sigAlg = getSigAlgName();
- if (sigAlg == null) {
- sigAlg = getSigAlgOID();
- }
-
- final Signature sig;
- if (sigProvider == null) {
- sig = Signature.getInstance(sigAlg);
- } else {
- sig = Signature.getInstance(sigAlg, sigProvider);
- }
-
- sig.initVerify(key);
- sig.update(getTBSCertificate());
- if (!sig.verify(getSignature())) {
- throw new SignatureException("signature did not verify");
- }
- }
-
- @Override
- public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException {
- if (key instanceof OpenSSLKeyHolder) {
- OpenSSLKey pkey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
- verifyOpenSSL(pkey);
- return;
- }
-
- verifyInternal(key, null);
- }
-
- @Override
- public void verify(PublicKey key, String sigProvider) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- verifyInternal(key, sigProvider);
- }
-
- @Override
- public String toString() {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
- try {
- NativeCrypto.X509_print_ex(bioCtx, mContext, 0, 0);
- return os.toString();
- } finally {
- NativeCrypto.BIO_free(bioCtx);
- }
- }
-
- @Override
- public PublicKey getPublicKey() {
- /* First try to generate the key from supported OpenSSL key types. */
- try {
- OpenSSLKey pkey = new OpenSSLKey(NativeCrypto.X509_get_pubkey(mContext));
- return pkey.getPublicKey();
- } catch (NoSuchAlgorithmException ignored) {
- }
-
- /* Try generating the key using other Java providers. */
- String oid = NativeCrypto.get_X509_pubkey_oid(mContext);
- byte[] encoded = NativeCrypto.i2d_X509_PUBKEY(mContext);
- try {
- KeyFactory kf = KeyFactory.getInstance(oid);
- return kf.generatePublic(new X509EncodedKeySpec(encoded));
- } catch (NoSuchAlgorithmException ignored) {
- } catch (InvalidKeySpecException ignored) {
- }
-
- /*
- * We couldn't find anything else, so just return a nearly-unusable
- * X.509-encoded key.
- */
- return new X509PublicKey(oid, encoded);
- }
-
- @Override
- public X500Principal getIssuerX500Principal() {
- final byte[] issuer = NativeCrypto.X509_get_issuer_name(mContext);
- return new X500Principal(issuer);
- }
-
- @Override
- public X500Principal getSubjectX500Principal() {
- final byte[] subject = NativeCrypto.X509_get_subject_name(mContext);
- return new X500Principal(subject);
- }
-
- @Override
- public List<String> getExtendedKeyUsage() throws CertificateParsingException {
- String[] extUsage = NativeCrypto.get_X509_ex_xkusage(mContext);
- if (extUsage == null) {
- return null;
- }
-
- return Arrays.asList(extUsage);
- }
-
- private static Collection<List<?>> alternativeNameArrayToList(Object[][] altNameArray) {
- if (altNameArray == null) {
- return null;
- }
-
- Collection<List<?>> coll = new ArrayList<List<?>>(altNameArray.length);
- for (int i = 0; i < altNameArray.length; i++) {
- coll.add(Collections.unmodifiableList(Arrays.asList(altNameArray[i])));
- }
-
- return Collections.unmodifiableCollection(coll);
- }
-
- @Override
- public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
- return alternativeNameArrayToList(NativeCrypto.get_X509_GENERAL_NAME_stack(mContext,
- NativeCrypto.GN_STACK_SUBJECT_ALT_NAME));
- }
-
- @Override
- public Collection<List<?>> getIssuerAlternativeNames() throws CertificateParsingException {
- return alternativeNameArrayToList(NativeCrypto.get_X509_GENERAL_NAME_stack(mContext,
- NativeCrypto.GN_STACK_ISSUER_ALT_NAME));
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof OpenSSLX509Certificate) {
- OpenSSLX509Certificate o = (OpenSSLX509Certificate) other;
-
- return NativeCrypto.X509_cmp(mContext, o.mContext) == 0;
- }
-
- return super.equals(other);
- }
-
- @Override
- public int hashCode() {
- /* Make this faster since we might be in hash-based structures. */
- return NativeCrypto.get_X509_hashCode(mContext);
- }
-
- long getContext() {
- return mContext;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mContext != 0) {
- NativeCrypto.X509_free(mContext);
- }
- } finally {
- super.finalize();
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java
deleted file mode 100644
index 75fdedb..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.security.cert.CRL;
-import java.security.cert.CRLException;
-import java.security.cert.CertPath;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactorySpi;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-public class OpenSSLX509CertificateFactory extends CertificateFactorySpi {
- private static final byte[] PKCS7_MARKER = "-----BEGIN PKCS7".getBytes();
-
- private static final int PUSHBACK_SIZE = 64;
-
- static class ParsingException extends Exception {
- private static final long serialVersionUID = 8390802697728301325L;
-
- public ParsingException(String message) {
- super(message);
- }
-
- public ParsingException(Exception cause) {
- super(cause);
- }
-
- public ParsingException(String message, Exception cause) {
- super(message, cause);
- }
- }
-
- /**
- * The code for X509 Certificates and CRL is pretty much the same. We use
- * this abstract class to share the code between them. This makes it ugly,
- * but it's already written in this language anyway.
- */
- private static abstract class Parser<T> {
- public T generateItem(InputStream inStream) throws ParsingException {
- if (inStream == null) {
- throw new ParsingException("inStream == null");
- }
-
- final boolean markable = inStream.markSupported();
- if (markable) {
- inStream.mark(PKCS7_MARKER.length);
- }
-
- final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE);
- try {
- final byte[] buffer = new byte[PKCS7_MARKER.length];
-
- final int len = pbis.read(buffer);
- if (len < 0) {
- /* No need to reset here. The stream was empty or EOF. */
- throw new ParsingException("inStream is empty");
- }
- pbis.unread(buffer, 0, len);
-
- if (buffer[0] == '-') {
- if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
- List<? extends T> items = fromPkcs7PemInputStream(pbis);
- if (items.size() == 0) {
- return null;
- }
- items.get(0);
- } else {
- return fromX509PemInputStream(pbis);
- }
- }
-
- /* PKCS#7 bags have a byte 0x06 at position 4 in the stream. */
- if (buffer[4] == 0x06) {
- List<? extends T> certs = fromPkcs7DerInputStream(pbis);
- if (certs.size() == 0) {
- return null;
- }
- return certs.get(0);
- } else {
- return fromX509DerInputStream(pbis);
- }
- } catch (Exception e) {
- if (markable) {
- try {
- inStream.reset();
- } catch (IOException ignored) {
- }
- }
- throw new ParsingException(e);
- }
- }
-
- public Collection<? extends T> generateItems(InputStream inStream)
- throws ParsingException {
- if (inStream == null) {
- throw new ParsingException("inStream == null");
- }
- try {
- if (inStream.available() == 0) {
- return Collections.emptyList();
- }
- } catch (IOException e) {
- throw new ParsingException("Problem reading input stream", e);
- }
-
- final boolean markable = inStream.markSupported();
- if (markable) {
- inStream.mark(PUSHBACK_SIZE);
- }
-
- /* Attempt to see if this is a PKCS#7 bag. */
- final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE);
- try {
- final byte[] buffer = new byte[PKCS7_MARKER.length];
-
- final int len = pbis.read(buffer);
- if (len < 0) {
- /* No need to reset here. The stream was empty or EOF. */
- throw new ParsingException("inStream is empty");
- }
- pbis.unread(buffer, 0, len);
-
- if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
- return fromPkcs7PemInputStream(pbis);
- }
-
- /* PKCS#7 bags have a byte 0x06 at position 4 in the stream. */
- if (buffer[4] == 0x06) {
- return fromPkcs7DerInputStream(pbis);
- }
- } catch (Exception e) {
- if (markable) {
- try {
- inStream.reset();
- } catch (IOException ignored) {
- }
- }
- throw new ParsingException(e);
- }
-
- /*
- * It wasn't, so just try to keep grabbing certificates until we
- * can't anymore.
- */
- final List<T> coll = new ArrayList<T>();
- T c = null;
- do {
- /*
- * If this stream supports marking, try to mark here in case
- * there is an error during certificate generation.
- */
- if (markable) {
- inStream.mark(PUSHBACK_SIZE);
- }
-
- try {
- c = generateItem(pbis);
- coll.add(c);
- } catch (ParsingException e) {
- /*
- * If this stream supports marking, attempt to reset it to
- * the mark before the failure.
- */
- if (markable) {
- try {
- inStream.reset();
- } catch (IOException ignored) {
- }
- }
-
- c = null;
- }
- } while (c != null);
-
- return coll;
- }
-
- protected abstract T fromX509PemInputStream(InputStream pbis) throws ParsingException;
-
- protected abstract T fromX509DerInputStream(InputStream pbis) throws ParsingException;
-
- protected abstract List<? extends T> fromPkcs7PemInputStream(InputStream is)
- throws ParsingException;
-
- protected abstract List<? extends T> fromPkcs7DerInputStream(InputStream is)
- throws ParsingException;
- }
-
- private Parser<OpenSSLX509Certificate> certificateParser =
- new Parser<OpenSSLX509Certificate>() {
- @Override
- public OpenSSLX509Certificate fromX509PemInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509Certificate.fromX509PemInputStream(is);
- }
-
- @Override
- public OpenSSLX509Certificate fromX509DerInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509Certificate.fromX509DerInputStream(is);
- }
-
- @Override
- public List<? extends OpenSSLX509Certificate>
- fromPkcs7PemInputStream(InputStream is) throws ParsingException {
- return OpenSSLX509Certificate.fromPkcs7PemInputStream(is);
- }
-
- @Override
- public List<? extends OpenSSLX509Certificate>
- fromPkcs7DerInputStream(InputStream is) throws ParsingException {
- return OpenSSLX509Certificate.fromPkcs7DerInputStream(is);
- }
- };
-
- private Parser<OpenSSLX509CRL> crlParser =
- new Parser<OpenSSLX509CRL>() {
- @Override
- public OpenSSLX509CRL fromX509PemInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509CRL.fromX509PemInputStream(is);
- }
-
- @Override
- public OpenSSLX509CRL fromX509DerInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509CRL.fromX509DerInputStream(is);
- }
-
- @Override
- public List<? extends OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509CRL.fromPkcs7PemInputStream(is);
- }
-
- @Override
- public List<? extends OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509CRL.fromPkcs7DerInputStream(is);
- }
- };
-
- @Override
- public Certificate engineGenerateCertificate(InputStream inStream) throws CertificateException {
- try {
- return certificateParser.generateItem(inStream);
- } catch (ParsingException e) {
- throw new CertificateException(e);
- }
- }
-
- @Override
- public Collection<? extends Certificate> engineGenerateCertificates(
- InputStream inStream) throws CertificateException {
- try {
- return certificateParser.generateItems(inStream);
- } catch (ParsingException e) {
- throw new CertificateException(e);
- }
- }
-
- @Override
- public CRL engineGenerateCRL(InputStream inStream) throws CRLException {
- try {
- return crlParser.generateItem(inStream);
- } catch (ParsingException e) {
- throw new CRLException(e);
- }
- }
-
- @Override
- public Collection<? extends CRL> engineGenerateCRLs(InputStream inStream) throws CRLException {
- if (inStream == null) {
- return Collections.emptyList();
- }
-
- try {
- return crlParser.generateItems(inStream);
- } catch (ParsingException e) {
- throw new CRLException(e);
- }
- }
-
- @Override
- public Iterator<String> engineGetCertPathEncodings() {
- return OpenSSLX509CertPath.getEncodingsIterator();
- }
-
- @Override
- public CertPath engineGenerateCertPath(InputStream inStream) throws CertificateException {
- return OpenSSLX509CertPath.fromEncoding(inStream);
- }
-
- @Override
- public CertPath engineGenerateCertPath(InputStream inStream, String encoding)
- throws CertificateException {
- return OpenSSLX509CertPath.fromEncoding(inStream, encoding);
- }
-
- @Override
- public CertPath engineGenerateCertPath(List<? extends Certificate> certificates)
- throws CertificateException {
- final List<X509Certificate> filtered = new ArrayList<X509Certificate>(certificates.size());
- for (int i = 0; i < certificates.size(); i++) {
- final Certificate c = certificates.get(i);
-
- if (!(c instanceof X509Certificate)) {
- throw new CertificateException("Certificate not X.509 type at index " + i);
- }
-
- filtered.add((X509Certificate) c);
- }
-
- return new OpenSSLX509CertPath(filtered);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/PRF.java b/crypto/src/main/java/org/conscrypt/PRF.java
deleted file mode 100644
index afbbb45..0000000
--- a/crypto/src/main/java/org/conscrypt/PRF.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.SSLException;
-
-/**
- * This class provides functionality for computation
- * of PRF values for TLS (http://www.ietf.org/rfc/rfc2246.txt)
- * and SSL v3 (http://wp.netscape.com/eng/ssl3) protocols.
- */
-public class PRF {
- private static Logger.Stream logger = Logger.getStream("prf");
-
- private static Mac md5_mac;
- private static Mac sha_mac;
- protected static MessageDigest md5;
- protected static MessageDigest sha;
- private static int md5_mac_length;
- private static int sha_mac_length;
-
- static private void init() {
- try {
- md5_mac = Mac.getInstance("HmacMD5");
- sha_mac = Mac.getInstance("HmacSHA1");
- } catch (NoSuchAlgorithmException e) {
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLException(
- "There is no provider of HmacSHA1 or HmacMD5 "
- + "algorithms installed in the system"));
- }
- md5_mac_length = md5_mac.getMacLength();
- sha_mac_length = sha_mac.getMacLength();
- try {
- md5 = MessageDigest.getInstance("MD5");
- sha = MessageDigest.getInstance("SHA-1");
- } catch (Exception e) {
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLException(
- "Could not initialize the Digest Algorithms."));
- }
- }
-
- /**
- * Computes the value of SSLv3 pseudo random function.
- * @param out: the buffer to fill up with the value of the function.
- * @param secret: the buffer containing the secret value to generate prf.
- * @param seed: the seed to be used.
- */
- static synchronized void computePRF_SSLv3(byte[] out, byte[] secret, byte[] seed) {
- if (sha == null) {
- init();
- }
- int pos = 0;
- int iteration = 1;
- byte[] digest;
- while (pos < out.length) {
- byte[] pref = new byte[iteration];
- Arrays.fill(pref, (byte) (64 + iteration++));
- sha.update(pref);
- sha.update(secret);
- sha.update(seed);
- md5.update(secret);
- md5.update(sha.digest());
- digest = md5.digest(); // length == 16
- if (pos + 16 > out.length) {
- System.arraycopy(digest, 0, out, pos, out.length - pos);
- pos = out.length;
- } else {
- System.arraycopy(digest, 0, out, pos, 16);
- pos += 16;
- }
- }
- }
-
- /**
- * Computes the value of TLS pseudo random function.
- * @param out: the buffer to fill up with the value of the function.
- * @param secret: the buffer containing the secret value to generate prf.
- * @param str_bytes: the label bytes to be used.
- * @param seed: the seed to be used.
- */
- synchronized static void computePRF(byte[] out, byte[] secret,
- byte[] str_byts, byte[] seed) throws GeneralSecurityException {
- if (sha_mac == null) {
- init();
- }
- // Do concatenation of the label with the seed:
- // (metterings show that is is faster to concatenate the arrays
- // and to call HMAC.update on cancatenation, than twice call for
- // each of the part, i.e.:
- // time(HMAC.update(label+seed))
- // < time(HMAC.update(label)) + time(HMAC.update(seed))
- // but it takes more memmory (approximaty on 4%)
- /*
- byte[] tmp_seed = new byte[seed.length + str_byts.length];
- System.arraycopy(str_byts, 0, tmp_seed, 0, str_byts.length);
- System.arraycopy(seed, 0, tmp_seed, str_byts.length, seed.length);
- seed = tmp_seed;
- */
- SecretKeySpec keyMd5;
- SecretKeySpec keySha1;
- if ((secret == null) || (secret.length == 0)) {
- secret = new byte[8];
- keyMd5 = new SecretKeySpec(secret, "HmacMD5");
- keySha1 = new SecretKeySpec(secret, "HmacSHA1");
- } else {
- int length = secret.length >> 1; // division by 2
- int offset = secret.length & 1; // remainder
- keyMd5 = new SecretKeySpec(secret, 0, length + offset,
- "HmacMD5");
- keySha1 = new SecretKeySpec(secret, length, length
- + offset, "HmacSHA1");
- }
-
- //byte[] str_byts = label.getBytes();
-
- if (logger != null) {
- logger.println("secret["+secret.length+"]: ");
- logger.printAsHex(16, "", " ", secret);
- logger.println("label["+str_byts.length+"]: ");
- logger.printAsHex(16, "", " ", str_byts);
- logger.println("seed["+seed.length+"]: ");
- logger.printAsHex(16, "", " ", seed);
- logger.println("MD5 key:");
- logger.printAsHex(16, "", " ", keyMd5.getEncoded());
- logger.println("SHA1 key:");
- logger.printAsHex(16, "", " ", keySha1.getEncoded());
- }
-
- md5_mac.init(keyMd5);
- sha_mac.init(keySha1);
-
- int pos = 0;
- md5_mac.update(str_byts);
- byte[] hash = md5_mac.doFinal(seed); // A(1)
- while (pos < out.length) {
- md5_mac.update(hash);
- md5_mac.update(str_byts);
- md5_mac.update(seed);
- if (pos + md5_mac_length < out.length) {
- md5_mac.doFinal(out, pos);
- pos += md5_mac_length;
- } else {
- System.arraycopy(md5_mac.doFinal(), 0, out,
- pos, out.length - pos);
- break;
- }
- // make A(i)
- hash = md5_mac.doFinal(hash);
- }
- if (logger != null) {
- logger.println("P_MD5:");
- logger.printAsHex(md5_mac_length, "", " ", out);
- }
-
- pos = 0;
- sha_mac.update(str_byts);
- hash = sha_mac.doFinal(seed); // A(1)
- byte[] sha1hash;
- while (pos < out.length) {
- sha_mac.update(hash);
- sha_mac.update(str_byts);
- sha1hash = sha_mac.doFinal(seed);
- for (int i = 0; (i < sha_mac_length) & (pos < out.length); i++) {
- out[pos++] ^= sha1hash[i];
- }
- // make A(i)
- hash = sha_mac.doFinal(hash);
- }
-
- if (logger != null) {
- logger.println("PRF:");
- logger.printAsHex(sha_mac_length, "", " ", out);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/PinEntryException.java b/crypto/src/main/java/org/conscrypt/PinEntryException.java
deleted file mode 100644
index 8c651db..0000000
--- a/crypto/src/main/java/org/conscrypt/PinEntryException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-// public for testing by CertPinManagerTest
-public class PinEntryException extends Exception {
-
- PinEntryException() {
- }
-
- PinEntryException(String msg) {
- super(msg);
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/PinFailureLogger.java b/crypto/src/main/java/org/conscrypt/PinFailureLogger.java
deleted file mode 100644
index bdb44a9..0000000
--- a/crypto/src/main/java/org/conscrypt/PinFailureLogger.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.List;
-import libcore.io.Base64;
-import libcore.io.DropBox;
-
-public class PinFailureLogger {
-
- private static final long LOG_INTERVAL_NANOS = 1000 * 1000 * 1000 * 60 * 60;
-
- private static long lastLoggedNanos = 0;
-
- public static synchronized void log(String cn, boolean chainContainsUserCert,
- boolean pinIsEnforcing,
- List<X509Certificate> chain) {
- // if we've logged recently, don't do it again
- if (!timeToLog()) {
- return;
- }
- // otherwise, log the event
- writeToLog(cn, chainContainsUserCert, pinIsEnforcing, chain);
- // update the last logged time
- lastLoggedNanos = System.nanoTime();
- }
-
- protected static synchronized void writeToLog(String cn, boolean chainContainsUserCert,
- boolean pinIsEnforcing,
- List<X509Certificate> chain) {
- StringBuilder sb = new StringBuilder();
- sb.append(cn);
- sb.append("|");
- sb.append(chainContainsUserCert);
- sb.append("|");
- sb.append(pinIsEnforcing);
- sb.append("|");
- for (X509Certificate cert : chain) {
- try {
- sb.append(Base64.encode(cert.getEncoded()));
- } catch (CertificateEncodingException e) {
- sb.append("Error: could not encode certificate");
- }
- sb.append("|");
- }
- DropBox.addText("exp_det_cert_pin_failure", sb.toString());
- }
-
- protected static boolean timeToLog() {
- long currentTimeNanos = System.nanoTime();
- return ((currentTimeNanos - lastLoggedNanos) > LOG_INTERVAL_NANOS);
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/PinListEntry.java b/crypto/src/main/java/org/conscrypt/PinListEntry.java
deleted file mode 100644
index a401700..0000000
--- a/crypto/src/main/java/org/conscrypt/PinListEntry.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import libcore.io.EventLogger;
-
-/**
- * This class represents a single entry in the pin file.
- */
-// public for testing by CertPinManagerTest
-public class PinListEntry {
-
- /** The Common Name (CN) as used on the SSL certificate */
- private final String cn;
-
- /**
- * Determines whether a failed match here will prevent the chain from being accepted. If true,
- * an unpinned chain will log and cause a match failure. If false, it will merely log.
- */
- private final boolean enforcing;
-
- private final Set<String> pinnedFingerprints = new HashSet<String>();
-
- private static final boolean DEBUG = false;
-
- private final TrustedCertificateStore certStore;
-
- public String getCommonName() {
- return cn;
- }
-
- public boolean getEnforcing() {
- return enforcing;
- }
-
- public PinListEntry(String entry, TrustedCertificateStore store) throws PinEntryException {
- if (entry == null) {
- throw new NullPointerException("entry == null");
- }
- certStore = store;
- // Examples:
- // *.google.com=true|34c8a0d...9e04ca05f,9e04ca05f...34c8a0d
- // *.android.com=true|ca05f...8a0d34c
- // clients.google.com=false|9e04ca05f...34c8a0d,34c8a0d...9e04ca05f
- String[] values = entry.split("[=,|]");
- // entry must have a CN, an enforcement value, and at least one pin
- if (values.length < 3) {
- throw new PinEntryException("Received malformed pin entry");
- }
- // get the cn
- cn = values[0]; // is there more validation we can do here?
- enforcing = enforcementValueFromString(values[1]);
- // the remainder should be pins
- addPins(Arrays.copyOfRange(values, 2, values.length));
- }
-
- private static boolean enforcementValueFromString(String val) throws PinEntryException {
- if (val.equals("true")) {
- return true;
- } else if (val.equals("false")) {
- return false;
- } else {
- throw new PinEntryException("Enforcement status is not a valid value");
- }
- }
-
- /**
- * Checks the given chain against the pin list corresponding to this entry.
- *
- * If the pin list does not contain the required certs and the enforcing field is true then
- * this returns true, indicating a verification error. Otherwise, it returns false and
- * verification should proceed.
- */
- public boolean chainIsNotPinned(List<X509Certificate> chain) {
- for (X509Certificate cert : chain) {
- String fingerprint = getFingerprint(cert);
- if (pinnedFingerprints.contains(fingerprint)) {
- return false;
- }
- }
- logPinFailure(chain);
- return enforcing;
- }
-
- private static String getFingerprint(X509Certificate cert) {
- try {
- MessageDigest dgst = MessageDigest.getInstance("SHA512");
- byte[] encoded = cert.getPublicKey().getEncoded();
- byte[] fingerprint = dgst.digest(encoded);
- return IntegralToString.bytesToHexString(fingerprint, false);
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
- }
-
- private void addPins(String[] pins) {
- for (String pin : pins) {
- validatePin(pin);
- }
- Collections.addAll(pinnedFingerprints, pins);
- }
-
- private static void validatePin(String pin) {
- // check to make sure the length is correct
- if (pin.length() != 128) {
- throw new IllegalArgumentException("Pin is not a valid length");
- }
- // check to make sure that it's a valid hex string
- try {
- new BigInteger(pin, 16);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Pin is not a valid hex string", e);
- }
- }
-
- private boolean chainContainsUserCert(List<X509Certificate> chain) {
- if (certStore == null) {
- return false;
- }
- for (X509Certificate cert : chain) {
- if (certStore.isUserAddedCertificate(cert)) {
- return true;
- }
- }
- return false;
- }
-
- private void logPinFailure(List<X509Certificate> chain) {
- PinFailureLogger.log(cn, chainContainsUserCert(chain), enforcing, chain);
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/PinManagerException.java b/crypto/src/main/java/org/conscrypt/PinManagerException.java
deleted file mode 100644
index e52ae83..0000000
--- a/crypto/src/main/java/org/conscrypt/PinManagerException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-class PinManagerException extends Exception {
-
- PinManagerException() {
- }
-
- PinManagerException(String msg) {
- super(msg);
- }
-
- PinManagerException(String msg, Exception e) {
- super(msg, e);
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/Platform.java b/crypto/src/main/java/org/conscrypt/Platform.java
deleted file mode 100644
index 3a577ce..0000000
--- a/crypto/src/main/java/org/conscrypt/Platform.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.apache.harmony.security.utils.AlgNameMapperSource;
-
-class Platform {
- private static class NoPreloadHolder {
- public static final Platform MAPPER = new Platform();
- }
-
- /**
- * Runs all the setup for the platform that only needs to run once.
- */
- public static void setup() {
- NoPreloadHolder.MAPPER.ping();
- }
-
- /**
- * Just a placeholder to make sure the class is initialized.
- */
- private void ping() {
- }
-
- private Platform() {
- AlgNameMapper.setSource(new OpenSSLMapper());
- }
-
- private static class OpenSSLMapper implements AlgNameMapperSource {
- @Override
- public String mapNameToOid(String algName) {
- return NativeCrypto.OBJ_txt2nid_oid(algName);
- }
-
- @Override
- public String mapOidToName(String oid) {
- return NativeCrypto.OBJ_txt2nid_longName(oid);
- }
- }
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/ProtocolVersion.java b/crypto/src/main/java/org/conscrypt/ProtocolVersion.java
deleted file mode 100644
index 4e2555c..0000000
--- a/crypto/src/main/java/org/conscrypt/ProtocolVersion.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-import java.util.Hashtable;
-
-/**
- *
- * Represents Protocol Version
- */
-public class ProtocolVersion {
- /**
- * Protocols supported by this provider implementation
- */
- public static final String[] supportedProtocols = new String[] { "TLSv1",
- "SSLv3" };
-
- private static Hashtable<String, ProtocolVersion> protocolsByName = new Hashtable<String, ProtocolVersion>(4);
-
- /**
- *
- * Returns true if protocol version is supported
- *
- * @param version
- */
- public static boolean isSupported(byte[] version) {
- if (version[0] != 3 || (version[1] != 0 && version[1] != 1)) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns ProtocolVersion
- *
- * @param version
- * @return
- */
- public static ProtocolVersion getByVersion(byte[] version) {
- if (version[0] == 3) {
- if (version[1] == 1) {
- return TLSv1;
- }
- if (version[1] == 0) {
- return SSLv3;
- }
- }
- return null;
- }
-
- /**
- * Returns true if provider supports protocol version
- *
- * @param name
- * @return
- */
- public static boolean isSupported(String name) {
- return protocolsByName.containsKey(name);
- }
-
- /**
- * Returns ProtocolVersion
- *
- * @param name
- * @return
- */
- public static ProtocolVersion getByName(String name) {
- return protocolsByName.get(name);
- }
-
- /**
- * Highest protocol version supported by provider implementation
- *
- * @param protocols
- * @return
- */
- public static ProtocolVersion getLatestVersion(String[] protocols) {
- if (protocols == null || protocols.length == 0) {
- return null;
- }
- ProtocolVersion latest = getByName(protocols[0]);
- ProtocolVersion current;
- for (int i = 1; i < protocols.length; i++) {
- current = getByName(protocols[i]);
- if (current == null) {
- continue;
- }
- if ((latest == null)
- || (latest.version[0] < current.version[0])
- || (latest.version[0] == current.version[0] && latest.version[1] < current.version[1])) {
- latest = current;
- }
- }
- return latest;
-
- }
-
- /**
- * SSL 3.0 protocol version
- */
- public static final ProtocolVersion SSLv3 = new ProtocolVersion("SSLv3",
- new byte[] { 3, 0 });
-
- /**
- * TLS 1.0 protocol version
- */
- public static final ProtocolVersion TLSv1 = new ProtocolVersion("TLSv1",
- new byte[] { 3, 1 });
-
- static {
- protocolsByName.put(SSLv3.name, SSLv3);
- protocolsByName.put(TLSv1.name, TLSv1);
- protocolsByName.put("SSL", SSLv3);
- protocolsByName.put("TLS", TLSv1);
- }
-
- /**
- * Protocol name
- */
- public final String name;
-
- /**
- * Protocol version as byte array
- */
- public final byte[] version;
-
- private ProtocolVersion(String name, byte[] version) {
- this.name = name;
- this.version = version;
- }
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/SSLBufferedInput.java b/crypto/src/main/java/org/conscrypt/SSLBufferedInput.java
deleted file mode 100644
index d2834d3..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLBufferedInput.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * This is a wrapper input stream for ByteBuffer data source.
- * Among with the read functionality it provides info
- * about number of cunsumed bytes from the source ByteBuffer.
- * The source ByteBuffer object can be reseted.
- * So one instance of this wrapper can be reused for several
- * ByteBuffer data sources.
- */
-public class SSLBufferedInput extends SSLInputStream {
-
- private ByteBuffer in;
- private int bytik;
- private int consumed = 0;
-
- /**
- * Constructor
- */
- protected SSLBufferedInput() {}
-
- /**
- * Sets the buffer as a data source
- */
- protected void setSourceBuffer(ByteBuffer in) {
- consumed = 0;
- this.in = in;
- }
-
- @Override
- public int available() throws IOException {
- // in assumption that the buffer has been set
- return in.remaining();
- }
-
- /**
- * Returns the number of consumed bytes.
- */
- protected int consumed() {
- return consumed;
- }
-
- /**
- * Reads the following byte value. If there are no bytes in the source
- * buffer, method throws java.nio.BufferUnderflowException.
- */
- @Override
- public int read() throws IOException {
- // TODO: implement optimized read(int)
- // and read(byte[], int, int) methods
- bytik = in.get() & 0x00FF;
- consumed ++;
- return bytik;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLClientSessionCache.java b/crypto/src/main/java/org/conscrypt/SSLClientSessionCache.java
deleted file mode 100644
index d070a02..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLClientSessionCache.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLSession;
-
-/**
- * A persistent {@link javax.net.ssl.SSLSession} cache used by
- * {@link javax.net.ssl.SSLSessionContext} to share client-side SSL sessions
- * across processes. For example, this cache enables applications to
- * persist and reuse sessions across restarts.
- *
- * <p>The {@code SSLSessionContext} implementation converts
- * {@code SSLSession}s into raw bytes and vice versa. The exact makeup of the
- * session data is dependent upon the caller's implementation and is opaque to
- * the {@code SSLClientSessionCache} implementation.
- */
-public interface SSLClientSessionCache {
-
- /**
- * Gets data from a pre-existing session for a given server host and port.
- *
- * @param host from {@link javax.net.ssl.SSLSession#getPeerHost()}
- * @param port from {@link javax.net.ssl.SSLSession#getPeerPort()}
- * @return the session data or null if none is cached
- * @throws NullPointerException if host is null
- */
- public byte[] getSessionData(String host, int port);
-
- /**
- * Stores session data for the given session.
- *
- * @param session to cache data for
- * @param sessionData to cache
- * @throws NullPointerException if session, result of
- * {@code session.getPeerHost()} or data is null
- */
- public void putSessionData(SSLSession session, byte[] sessionData);
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/SSLContextImpl.java b/crypto/src/main/java/org/conscrypt/SSLContextImpl.java
deleted file mode 100644
index 75aed4f..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLContextImpl.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.KeyManagementException;
-import java.security.SecureRandom;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContextSpi;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-/**
- * Implementation of SSLContext service provider interface.
- */
-public class SSLContextImpl extends SSLContextSpi {
-
- /**
- * The default SSLContextImpl for use with SSLContext.getInstance("Default").
- * Protected by the DefaultSSLContextImpl.class monitor.
- */
- private static DefaultSSLContextImpl DEFAULT_SSL_CONTEXT_IMPL;
-
- /** Client session cache. */
- private final ClientSessionContext clientSessionContext;
-
- /** Server session cache. */
- private final ServerSessionContext serverSessionContext;
-
- protected SSLParametersImpl sslParameters;
-
- public SSLContextImpl() {
- clientSessionContext = new ClientSessionContext();
- serverSessionContext = new ServerSessionContext();
- }
-
- /**
- * Constuctor for the DefaultSSLContextImpl.
- * @param dummy is null, used to distinguish this case from the
- * public SSLContextImpl() constructor.
- */
- protected SSLContextImpl(DefaultSSLContextImpl dummy)
- throws GeneralSecurityException, IOException {
- synchronized (DefaultSSLContextImpl.class) {
- if (DEFAULT_SSL_CONTEXT_IMPL == null) {
- clientSessionContext = new ClientSessionContext();
- serverSessionContext = new ServerSessionContext();
- DEFAULT_SSL_CONTEXT_IMPL = (DefaultSSLContextImpl)this;
- } else {
- clientSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetClientSessionContext();
- serverSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetServerSessionContext();
- }
- sslParameters = new SSLParametersImpl(DEFAULT_SSL_CONTEXT_IMPL.getKeyManagers(),
- DEFAULT_SSL_CONTEXT_IMPL.getTrustManagers(),
- null,
- clientSessionContext,
- serverSessionContext);
- }
- }
-
- /**
- * Initializes this {@code SSLContext} instance. All of the arguments are
- * optional, and the security providers will be searched for the required
- * implementations of the needed algorithms.
- *
- * @param kms the key sources or {@code null}
- * @param tms the trust decision sources or {@code null}
- * @param sr the randomness source or {@code null}
- * @throws KeyManagementException if initializing this instance fails
- */
- @Override
- public void engineInit(KeyManager[] kms, TrustManager[] tms,
- SecureRandom sr) throws KeyManagementException {
- sslParameters = new SSLParametersImpl(kms, tms, sr,
- clientSessionContext, serverSessionContext);
- }
-
- @Override
- public SSLSocketFactory engineGetSocketFactory() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- return new SSLSocketFactoryImpl(sslParameters);
- }
-
- @Override
- public SSLServerSocketFactory engineGetServerSocketFactory() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- return new SSLServerSocketFactoryImpl(sslParameters);
- }
-
- @Override
- public SSLEngine engineCreateSSLEngine(String host, int port) {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
- p.setUseClientMode(false);
- return new SSLEngineImpl(host, port, p);
- }
-
- @Override
- public SSLEngine engineCreateSSLEngine() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
- p.setUseClientMode(false);
- return new SSLEngineImpl(p);
- }
-
- @Override
- public ServerSessionContext engineGetServerSessionContext() {
- return serverSessionContext;
- }
-
- @Override
- public ClientSessionContext engineGetClientSessionContext() {
- return clientSessionContext;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLEngineAppData.java b/crypto/src/main/java/org/conscrypt/SSLEngineAppData.java
deleted file mode 100644
index f2cb77d..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLEngineAppData.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.nio.ByteBuffer;
-import javax.net.ssl.SSLException;
-
-/**
- * This class is used to retrieve the application data
- * arrived for the SSLEngine.
- */
-public class SSLEngineAppData implements Appendable {
-
- /**
- * Buffer containing received application data.
- */
- byte[] buffer;
-
- /**
- * Constructor
- */
- protected SSLEngineAppData() {}
-
- /**
- * Stores received data. The source data is not cloned,
- * just the array reference is remembered into the buffer field.
- */
- public void append(byte[] src) {
- if (buffer != null) {
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLException("Attempt to override the data"));
- }
- buffer = src;
- }
-
- /**
- * Places the data from the buffer into the array of destination
- * ByteBuffer objects.
- */
- protected int placeTo(ByteBuffer[] dsts, int offset, int length) {
- if (buffer == null) {
- return 0;
- }
- int pos = 0;
- int len = buffer.length;
- int rem;
- // write data to the buffers
- for (int i=offset; i<offset+length; i++) {
- rem = dsts[i].remaining();
- // TODO: optimization work - use hasArray, array(), arraycopy
- if (len - pos < rem) {
- // can fully write remaining data into buffer
- dsts[i].put(buffer, pos, len - pos);
- pos = len;
- // data was written, exit
- break;
- }
- // write chunk of data
- dsts[i].put(buffer, pos, rem);
- pos += rem;
- }
- if (pos != len) {
- // The data did not feet into the buffers,
- // it should not happen, because the destination buffers
- // had been checked for the space before record unwrapping.
- // But if it so, we should allert about internal error.
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLException(
- "The received application data could not be fully written"
- + "into the destination buffers"));
- }
- buffer = null;
- return len;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/SSLEngineDataStream.java b/crypto/src/main/java/org/conscrypt/SSLEngineDataStream.java
deleted file mode 100644
index f4a2d2d..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLEngineDataStream.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.nio.ByteBuffer;
-
-/**
- * This class provides the DataStream functionality
- * implemented over the array of ByteBuffer instances.
- * Among with the data chunks read functionality
- * it provides the info about amount of consumed data.
- * The source ByteBuffer objects can be replaced by other.
- * So one instance of this wrapper can be reused for several
- * data sources.
- */
-public class SSLEngineDataStream implements DataStream {
-
- private ByteBuffer[] srcs;
- private int offset;
- private int limit;
-
- private int available;
- private int consumed;
-
- protected SSLEngineDataStream() {}
-
- protected void setSourceBuffers(ByteBuffer[] srcs, int offset, int length) {
- this.srcs = srcs;
- this.offset = offset;
- this.limit = offset+length;
- this.consumed = 0;
- this.available = 0;
- for (int i=offset; i<limit; i++) {
- if (srcs[i] == null) {
- throw new IllegalStateException(
- "Some of the input parameters are null");
- }
- available += srcs[i].remaining();
- }
- }
-
- public int available() {
- return available;
- }
-
- public boolean hasData() {
- return available > 0;
- }
-
- public byte[] getData(int length) {
- // TODO: optimization work:
- // use ByteBuffer.get(byte[],int,int)
- // and ByteBuffer.hasArray() methods
- int len = (length < available) ? length : available;
- available -= len;
- consumed += len;
- byte[] res = new byte[len];
- int pos = 0;
- loop:
- for (; offset<limit; offset++) {
- while (srcs[offset].hasRemaining()) {
- res[pos++] = srcs[offset].get();
- len --;
- if (len == 0) {
- break loop;
- }
- }
- }
- return res;
- }
-
- protected int consumed() {
- return consumed;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java b/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java
deleted file mode 100644
index 3ed9980..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ReadOnlyBufferException;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLSession;
-
-/**
- * Implementation of SSLEngine.
- * @see javax.net.ssl.SSLEngine class documentation for more information.
- */
-public class SSLEngineImpl extends SSLEngine {
-
- // indicates if peer mode was set
- private boolean peer_mode_was_set = false;
- // indicates if handshake has been started
- private boolean handshake_started = false;
- // indicates if inbound operations finished
- private boolean isInboundDone = false;
- // indicates if outbound operations finished
- private boolean isOutboundDone = false;
- // indicates if close_notify alert had been sent to another peer
- private boolean close_notify_was_sent = false;
- // indicates if close_notify alert had been received from another peer
- private boolean close_notify_was_received = false;
- // indicates if engine was closed (it means that
- // all the works on it are done, except (probably) some finalizing work)
- private boolean engine_was_closed = false;
- // indicates if engine was shutted down (it means that
- // all cleaning work had been done and the engine is not operable)
- private boolean engine_was_shutteddown = false;
-
- // record protocol to be used
- protected SSLRecordProtocol recordProtocol;
- // input stream for record protocol
- private SSLBufferedInput recProtIS;
- // handshake protocol to be used
- private HandshakeProtocol handshakeProtocol;
- // alert protocol to be used
- private AlertProtocol alertProtocol;
- // place where application data will be stored
- private SSLEngineAppData appData;
- // outcoming application data stream
- private SSLEngineDataStream dataStream = new SSLEngineDataStream();
- // active session object
- private SSLSessionImpl session;
-
- // peer configuration parameters
- protected SSLParametersImpl sslParameters;
-
- // in case of emergency situations when data could not be
- // placed in destination buffers it will be stored in this
- // fields
- private byte[] remaining_wrapped_data = null;
- private byte[] remaining_hsh_data = null;
-
- // logger
- private Logger.Stream logger = Logger.getStream("engine");
-
- protected SSLEngineImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = sslParameters;
- }
-
- protected SSLEngineImpl(String host, int port, SSLParametersImpl sslParameters) {
- super(host, port);
- this.sslParameters = sslParameters;
- }
-
- /**
- * Starts the handshake.
- * @throws SSLException
- * @see javax.net.ssl.SSLEngine#beginHandshake() method documentation
- * for more information
- */
- @Override
- public void beginHandshake() throws SSLException {
- if (engine_was_closed) {
- throw new SSLException("Engine has already been closed.");
- }
- if (!peer_mode_was_set) {
- throw new IllegalStateException("Client/Server mode was not set");
- }
- if (!handshake_started) {
- handshake_started = true;
- if (getUseClientMode()) {
- handshakeProtocol = new ClientHandshakeImpl(this);
- } else {
- handshakeProtocol = new ServerHandshakeImpl(this);
- }
- appData = new SSLEngineAppData();
- alertProtocol = new AlertProtocol();
- recProtIS = new SSLBufferedInput();
- recordProtocol = new SSLRecordProtocol(handshakeProtocol,
- alertProtocol, recProtIS, appData);
- }
- handshakeProtocol.start();
- }
-
- /**
- * Closes inbound operations of this engine
- * @throws SSLException
- * @see javax.net.ssl.SSLEngine#closeInbound() method documentation
- * for more information
- */
- @Override
- public void closeInbound() throws SSLException {
- if (logger != null) {
- logger.println("closeInbound() "+isInboundDone);
- }
- if (isInboundDone) {
- return;
- }
- isInboundDone = true;
- engine_was_closed = true;
- if (handshake_started) {
- if (!close_notify_was_received) {
- if (session != null) {
- session.invalidate();
- }
- alertProtocol.alert(AlertProtocol.FATAL,
- AlertProtocol.INTERNAL_ERROR);
- throw new SSLException("Inbound is closed before close_notify "
- + "alert has been received.");
- }
- } else {
- // engine is closing before initial handshake has been made
- shutdown();
- }
- }
-
- /**
- * Closes outbound operations of this engine
- * @see javax.net.ssl.SSLEngine#closeOutbound() method documentation
- * for more information
- */
- @Override
- public void closeOutbound() {
- if (logger != null) {
- logger.println("closeOutbound() "+isOutboundDone);
- }
- if (isOutboundDone) {
- return;
- }
- isOutboundDone = true;
- if (handshake_started) {
- // initial handshake had been started
- alertProtocol.alert(AlertProtocol.WARNING,
- AlertProtocol.CLOSE_NOTIFY);
- close_notify_was_sent = true;
- } else {
- // engine is closing before initial handshake has been made
- shutdown();
- }
- engine_was_closed = true;
- }
-
- /**
- * Returns handshake's delegated tasks to be run
- * @return the delegated task to be executed.
- * @see javax.net.ssl.SSLEngine#getDelegatedTask() method documentation
- * for more information
- */
- @Override
- public Runnable getDelegatedTask() {
- return handshakeProtocol.getTask();
- }
-
- /**
- * Returns names of supported cipher suites.
- * @return array of strings containing the names of supported cipher suites
- * @see javax.net.ssl.SSLEngine#getSupportedCipherSuites() method
- * documentation for more information
- */
- @Override
- public String[] getSupportedCipherSuites() {
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- // --------------- SSLParameters based methods ---------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getEnabledCipherSuites() method
- * documentation for more information
- */
- @Override
- public String[] getEnabledCipherSuites() {
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setEnabledCipherSuites(String[]) method
- * documentation for more information
- */
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- sslParameters.setEnabledCipherSuites(suites);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getSupportedProtocols() method
- * documentation for more information
- */
- @Override
- public String[] getSupportedProtocols() {
- return ProtocolVersion.supportedProtocols.clone();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getEnabledProtocols() method
- * documentation for more information
- */
- @Override
- public String[] getEnabledProtocols() {
- return sslParameters.getEnabledProtocols();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setEnabledProtocols(String[]) method
- * documentation for more information
- */
- @Override
- public void setEnabledProtocols(String[] protocols) {
- sslParameters.setEnabledProtocols(protocols);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setUseClientMode(boolean) method
- * documentation for more information
- */
- @Override
- public void setUseClientMode(boolean mode) {
- if (handshake_started) {
- throw new IllegalArgumentException(
- "Could not change the mode after the initial handshake has begun.");
- }
- sslParameters.setUseClientMode(mode);
- peer_mode_was_set = true;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getUseClientMode() method
- * documentation for more information
- */
- @Override
- public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setNeedClientAuth(boolean) method
- * documentation for more information
- */
- @Override
- public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getNeedClientAuth() method
- * documentation for more information
- */
- @Override
- public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setWantClientAuth(boolean) method
- * documentation for more information
- */
- @Override
- public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getWantClientAuth() method
- * documentation for more information
- */
- @Override
- public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setEnableSessionCreation(boolean) method
- * documentation for more information
- */
- @Override
- public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getEnableSessionCreation() method
- * documentation for more information
- */
- @Override
- public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
- // -----------------------------------------------------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getHandshakeStatus() method
- * documentation for more information
- */
- @Override
- public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
- if (!handshake_started || engine_was_shutteddown) {
- // initial handshake has not been started yet
- return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
- }
- if (alertProtocol.hasAlert()) {
- // need to send an alert
- return SSLEngineResult.HandshakeStatus.NEED_WRAP;
- }
- if (close_notify_was_sent && !close_notify_was_received) {
- // waiting for "close_notify" response
- return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
- }
- return handshakeProtocol.getStatus();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getSession() method
- * documentation for more information
- */
- @Override
- public SSLSession getSession() {
- if (session != null) {
- return session;
- }
- return SSLSessionImpl.getNullSession();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#isInboundDone() method
- * documentation for more information
- */
- @Override
- public boolean isInboundDone() {
- return isInboundDone || engine_was_closed;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#isOutboundDone() method
- * documentation for more information
- */
- @Override
- public boolean isOutboundDone() {
- return isOutboundDone;
- }
-
- /**
- * Decodes one complete SSL/TLS record provided in the source buffer.
- * If decoded record contained application data, this data will
- * be placed in the destination buffers.
- * For more information about TLS record fragmentation see
- * TLS v 1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 6.2.
- * @param src source buffer containing SSL/TLS record.
- * @param dsts destination buffers to place received application data.
- * @see javax.net.ssl.SSLEngine#unwrap(ByteBuffer,ByteBuffer[],int,int)
- * method documentation for more information
- */
- @Override
- public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts,
- int offset, int length) throws SSLException {
- if (engine_was_shutteddown) {
- return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0);
- }
- if ((src == null) || (dsts == null)) {
- throw new IllegalStateException(
- "Some of the input parameters are null");
- }
-
- if (!handshake_started) {
- beginHandshake();
- }
-
- SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
- // If is is initial handshake or connection closure stage,
- // check if this call was made in spite of handshake status
- if ((session == null || engine_was_closed) && (
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_WRAP) ||
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_TASK))) {
- return new SSLEngineResult(
- getEngineStatus(), handshakeStatus, 0, 0);
- }
-
- if (src.remaining() < recordProtocol.getMinRecordSize()) {
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_UNDERFLOW,
- getHandshakeStatus(), 0, 0);
- }
-
- try {
- src.mark();
- // check the destination buffers and count their capacity
- int capacity = 0;
- for (int i=offset; i<offset+length; i++) {
- if (dsts[i] == null) {
- throw new IllegalStateException(
- "Some of the input parameters are null");
- }
- if (dsts[i].isReadOnly()) {
- throw new ReadOnlyBufferException();
- }
- capacity += dsts[i].remaining();
- }
- if (capacity < recordProtocol.getDataSize(src.remaining())) {
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- getHandshakeStatus(), 0, 0);
- }
- recProtIS.setSourceBuffer(src);
- // unwrap the record contained in source buffer, pass it
- // to appropriate client protocol (alert, handshake, or app)
- // and retrieve the type of unwrapped data
- int type = recordProtocol.unwrap();
- // process the data and return the result
- switch (type) {
- case ContentType.HANDSHAKE:
- case ContentType.CHANGE_CIPHER_SPEC:
- if (handshakeProtocol.getStatus().equals(
- SSLEngineResult.HandshakeStatus.FINISHED)) {
- session = recordProtocol.getSession();
- }
- break;
- case ContentType.APPLICATION_DATA:
- break;
- case ContentType.ALERT:
- if (alertProtocol.isFatalAlert()) {
- alertProtocol.setProcessed();
- if (session != null) {
- session.invalidate();
- }
- String description = "Fatal alert received "
- + alertProtocol.getAlertDescription();
- shutdown();
- throw new SSLException(description);
- } else {
- if (logger != null) {
- logger.println("Warning allert has been received: "
- + alertProtocol.getAlertDescription());
- }
- switch(alertProtocol.getDescriptionCode()) {
- case AlertProtocol.CLOSE_NOTIFY:
- alertProtocol.setProcessed();
- close_notify_was_received = true;
- if (!close_notify_was_sent) {
- closeOutbound();
- closeInbound();
- } else {
- closeInbound();
- shutdown();
- }
- break;
- case AlertProtocol.NO_RENEGOTIATION:
- alertProtocol.setProcessed();
- if (session == null) {
- // message received during the initial
- // handshake
- throw new AlertException(
- AlertProtocol.HANDSHAKE_FAILURE,
- new SSLHandshakeException(
- "Received no_renegotiation "
- + "during the initial handshake"));
- } else {
- // just stop the handshake
- handshakeProtocol.stop();
- }
- break;
- default:
- alertProtocol.setProcessed();
- }
- }
- break;
- }
- return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(),
- recProtIS.consumed(),
- // place the app. data (if any) into the dest. buffers
- // and get the number of produced bytes:
- appData.placeTo(dsts, offset, length));
- } catch (BufferUnderflowException e) {
- // there was not enought data ource buffer to make complete packet
- src.reset();
- return new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW,
- getHandshakeStatus(), 0, 0);
- } catch (AlertException e) {
- // fatal alert occured
- alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode());
- engine_was_closed = true;
- src.reset();
- if (session != null) {
- session.invalidate();
- }
- // shutdown work will be made after the alert will be sent
- // to another peer (by wrap method)
- throw e.getReason();
- } catch (SSLException e) {
- throw e;
- } catch (IOException e) {
- alertProtocol.alert(AlertProtocol.FATAL,
- AlertProtocol.INTERNAL_ERROR);
- engine_was_closed = true;
- // shutdown work will be made after the alert will be sent
- // to another peer (by wrap method)
- throw new SSLException(e.getMessage());
- }
- }
-
- /**
- * Encodes the application data into SSL/TLS record. If handshake status
- * of the engine differs from NOT_HANDSHAKING the operation can work
- * without consuming of the source data.
- * For more information about TLS record fragmentation see
- * TLS v 1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 6.2.
- * @param srcs the source buffers with application data to be encoded
- * into SSL/TLS record.
- * @param offset the offset in the destination buffers array pointing to
- * the first buffer with the source data.
- * @param len specifies the maximum number of buffers to be procesed.
- * @param dst the destination buffer where encoded data will be placed.
- * @see javax.net.ssl.SSLEngine#wrap(ByteBuffer[],int,int,ByteBuffer) method
- * documentation for more information
- */
- @Override
- public SSLEngineResult wrap(ByteBuffer[] srcs, int offset,
- int len, ByteBuffer dst) throws SSLException {
- if (engine_was_shutteddown) {
- return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0);
- }
- if ((srcs == null) || (dst == null)) {
- throw new IllegalStateException(
- "Some of the input parameters are null");
- }
- if (dst.isReadOnly()) {
- throw new ReadOnlyBufferException();
- }
-
- if (!handshake_started) {
- beginHandshake();
- }
-
- SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
- // If it is an initial handshake or connection closure stage,
- // check if this call was made in spite of handshake status
- if ((session == null || engine_was_closed) && (
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_UNWRAP) ||
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_TASK))) {
- return new SSLEngineResult(
- getEngineStatus(), handshakeStatus, 0, 0);
- }
-
- int capacity = dst.remaining();
- int produced = 0;
-
- if (alertProtocol.hasAlert()) {
- // we have an alert to be sent
- if (capacity < recordProtocol.getRecordSize(2)) {
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
- byte[] alert_data = alertProtocol.wrap();
- // place the alert record into destination
- dst.put(alert_data);
- if (alertProtocol.isFatalAlert()) {
- alertProtocol.setProcessed();
- if (session != null) {
- session.invalidate();
- }
- // fatal alert has been sent, so shut down the engine
- shutdown();
- return new SSLEngineResult(
- SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
- 0, alert_data.length);
- } else {
- alertProtocol.setProcessed();
- // check if the works on this engine have been done
- if (close_notify_was_sent && close_notify_was_received) {
- shutdown();
- return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
- 0, alert_data.length);
- }
- return new SSLEngineResult(
- getEngineStatus(),
- getHandshakeStatus(),
- 0, alert_data.length);
- }
- }
-
- if (capacity < recordProtocol.getMinRecordSize()) {
- if (logger != null) {
- logger.println("Capacity of the destination("
- +capacity+") < MIN_PACKET_SIZE("
- +recordProtocol.getMinRecordSize()+")");
- }
- return new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
-
- try {
- if (!handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
- // so we wraps application data
- dataStream.setSourceBuffers(srcs, offset, len);
- if ((capacity < SSLRecordProtocol.MAX_SSL_PACKET_SIZE) &&
- (capacity < recordProtocol.getRecordSize(
- dataStream.available()))) {
- if (logger != null) {
- logger.println("The destination buffer("
- +capacity+") can not take the resulting packet("
- + recordProtocol.getRecordSize(
- dataStream.available())+")");
- }
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
- if (remaining_wrapped_data == null) {
- remaining_wrapped_data =
- recordProtocol.wrap(ContentType.APPLICATION_DATA,
- dataStream);
- }
- if (capacity < remaining_wrapped_data.length) {
- // It should newer happen because we checked the destination
- // buffer size, but there is a possibility
- // (if dest buffer was filled outside)
- // so we just remember the data into remaining_wrapped_data
- // and will enclose it during the the next call
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, dataStream.consumed(), 0);
- } else {
- dst.put(remaining_wrapped_data);
- produced = remaining_wrapped_data.length;
- remaining_wrapped_data = null;
- return new SSLEngineResult(getEngineStatus(),
- handshakeStatus, dataStream.consumed(), produced);
- }
- } else {
- if (remaining_hsh_data == null) {
- remaining_hsh_data = handshakeProtocol.wrap();
- }
- if (capacity < remaining_hsh_data.length) {
- // It should newer happen because we checked the destination
- // buffer size, but there is a possibility
- // (if dest buffer was filled outside)
- // so we just remember the data into remaining_hsh_data
- // and will enclose it during the the next call
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- } else {
- dst.put(remaining_hsh_data);
- produced = remaining_hsh_data.length;
- remaining_hsh_data = null;
-
- handshakeStatus = handshakeProtocol.getStatus();
- if (handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.FINISHED)) {
- session = recordProtocol.getSession();
- }
- }
- return new SSLEngineResult(
- getEngineStatus(), getHandshakeStatus(), 0, produced);
- }
- } catch (AlertException e) {
- // fatal alert occured
- alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode());
- engine_was_closed = true;
- if (session != null) {
- session.invalidate();
- }
- // shutdown work will be made after the alert will be sent
- // to another peer (by wrap method)
- throw e.getReason();
- }
- }
-
- // Shutdownes the engine and makes all cleanup work.
- private void shutdown() {
- engine_was_closed = true;
- engine_was_shutteddown = true;
- isOutboundDone = true;
- isInboundDone = true;
- if (handshake_started) {
- alertProtocol.shutdown();
- alertProtocol = null;
- handshakeProtocol.shutdown();
- handshakeProtocol = null;
- recordProtocol.shutdown();
- recordProtocol = null;
- }
- }
-
-
- private SSLEngineResult.Status getEngineStatus() {
- return (engine_was_closed)
- ? SSLEngineResult.Status.CLOSED
- : SSLEngineResult.Status.OK;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLInputStream.java b/crypto/src/main/java/org/conscrypt/SSLInputStream.java
deleted file mode 100644
index c8a5eca..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLInputStream.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class is a base for all input stream classes used
- * in protocol implementation. It extends an InputStream with
- * some additional read methods allowing to read TLS specific
- * data types such as uint8, uint32 etc (see TLS v 1 specification
- * at http://www.ietf.org/rfc/rfc2246.txt).
- */
-public abstract class SSLInputStream extends InputStream {
-
- @Override
- public abstract int available() throws IOException;
-
- /**
- * Reads the following byte value. Note that in the case of
- * reaching of the end of the data this methods throws the
- * exception, not return -1. The type of exception depends
- * on implementation. It was done for simplifying and speeding
- * up of processing of such cases.
- * @see org.conscrypt.SSLStreamedInput#read()
- * @see org.conscrypt.SSLBufferedInput#read()
- * @see org.conscrypt.HandshakeIODataStream#read()
- */
- @Override
- public abstract int read() throws IOException;
-
- /**
- * Reads and returns uint8 value.
- */
- public int readUint8() throws IOException {
- return read() & 0x00FF;
- }
-
- /**
- * Reads and returns uint16 value.
- */
- public int readUint16() throws IOException {
- return (read() << 8) | (read() & 0x00FF);
- }
-
- /**
- * Reads and returns uint24 value.
- */
- public int readUint24() throws IOException {
- return (read() << 16) | (read() << 8) | (read() & 0x00FF);
- }
-
- /**
- * Reads and returns uint32 value.
- */
- public long readUint32() throws IOException {
- return (read() << 24) | (read() << 16)
- | (read() << 8) | (read() & 0x00FF);
- }
-
- /**
- * Reads and returns uint64 value.
- */
- public long readUint64() throws IOException {
- long hi = readUint32();
- long lo = readUint32();
- return (hi << 32) | lo;
- }
-
- /**
- * Returns the vector of opaque values of specified length;
- * @param length - the length of the vector to be read.
- * @return the read data
- * @throws IOException if read operation could not be finished.
- */
- public byte[] read(int length) throws IOException {
- byte[] res = new byte[length];
- for (int i=0; i<length; i++) {
- res[i] = (byte) read();
- }
- return res;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- int read_b;
- int i = 0;
- do {
- if ((read_b = read()) == -1) {
- return (i == 0) ? -1 : i;
- }
- b[off+i] = (byte) read_b;
- i++;
- } while ((available() != 0) && (i<len));
- return i;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLParametersImpl.java b/crypto/src/main/java/org/conscrypt/SSLParametersImpl.java
deleted file mode 100644
index 21b8ae2..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLParametersImpl.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.util.Arrays;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * The instances of this class encapsulate all the info
- * about enabled cipher suites and protocols,
- * as well as the information about client/server mode of
- * ssl socket, whether it require/want client authentication or not,
- * and controls whether new SSL sessions may be established by this
- * socket or not.
- */
-public class SSLParametersImpl implements Cloneable {
-
- // default source of authentication keys
- private static volatile X509KeyManager defaultKeyManager;
- // default source of authentication trust decisions
- private static volatile X509TrustManager defaultTrustManager;
- // default source of random numbers
- private static volatile SecureRandom defaultSecureRandom;
- // default SSL parameters
- private static volatile SSLParametersImpl defaultParameters;
-
- // client session context contains the set of reusable
- // client-side SSL sessions
- private final ClientSessionContext clientSessionContext;
- // server session context contains the set of reusable
- // server-side SSL sessions
- private final ServerSessionContext serverSessionContext;
- // source of authentication keys
- private X509KeyManager keyManager;
- // source of authentication trust decisions
- private X509TrustManager trustManager;
- // source of random numbers
- private SecureRandom secureRandom;
-
- // cipher suites available for SSL connection
- private CipherSuite[] enabledCipherSuites;
- // string representations of available cipher suites
- private String[] enabledCipherSuiteNames = null;
-
- // protocols available for SSL connection
- private String[] enabledProtocols = ProtocolVersion.supportedProtocols;
-
- // if the peer with this parameters tuned to work in client mode
- private boolean client_mode = true;
- // if the peer with this parameters tuned to require client authentication
- private boolean need_client_auth = false;
- // if the peer with this parameters tuned to request client authentication
- private boolean want_client_auth = false;
- // if the peer with this parameters allowed to cteate new SSL session
- private boolean enable_session_creation = true;
-
- protected CipherSuite[] getEnabledCipherSuitesMember() {
- if (enabledCipherSuites == null) {
- this.enabledCipherSuites = CipherSuite.DEFAULT_CIPHER_SUITES;
- }
- return enabledCipherSuites;
- }
-
- /**
- * Initializes the parameters. Naturally this constructor is used
- * in SSLContextImpl.engineInit method which directly passes its
- * parameters. In other words this constructor holds all
- * the functionality provided by SSLContext.init method.
- * See {@link javax.net.ssl.SSLContext#init(KeyManager[],TrustManager[],
- * SecureRandom)} for more information
- */
- protected SSLParametersImpl(KeyManager[] kms, TrustManager[] tms,
- SecureRandom sr, ClientSessionContext clientSessionContext,
- ServerSessionContext serverSessionContext)
- throws KeyManagementException {
- this.serverSessionContext = serverSessionContext;
- this.clientSessionContext = clientSessionContext;
-
- // It's not described by the spec of SSLContext what should happen
- // if the arrays of length 0 are specified. This implementation
- // behave as for null arrays (i.e. use installed security providers)
-
- // initialize keyManager
- if ((kms == null) || (kms.length == 0)) {
- keyManager = getDefaultKeyManager();
- } else {
- keyManager = findX509KeyManager(kms);
- }
-
- // initialize trustManager
- if ((tms == null) || (tms.length == 0)) {
- trustManager = getDefaultTrustManager();
- } else {
- trustManager = findX509TrustManager(tms);
- }
- // initialize secure random
- // BEGIN android-removed
- // if (sr == null) {
- // if (defaultSecureRandom == null) {
- // defaultSecureRandom = new SecureRandom();
- // }
- // secureRandom = defaultSecureRandom;
- // } else {
- // secureRandom = sr;
- // }
- // END android-removed
- // BEGIN android-added
- // We simply use the SecureRandom passed in by the caller. If it's
- // null, we don't replace it by a new instance. The native code below
- // then directly accesses /dev/urandom. Not the most elegant solution,
- // but faster than going through the SecureRandom object.
- secureRandom = sr;
- // END android-added
- }
-
- protected static SSLParametersImpl getDefault() throws KeyManagementException {
- SSLParametersImpl result = defaultParameters;
- if (result == null) {
- // single-check idiom
- defaultParameters = result = new SSLParametersImpl(null,
- null,
- null,
- new ClientSessionContext(),
- new ServerSessionContext());
- }
- return (SSLParametersImpl) result.clone();
- }
-
- /**
- * @return server session context
- */
- protected ServerSessionContext getServerSessionContext() {
- return serverSessionContext;
- }
-
- /**
- * @return client session context
- */
- protected ClientSessionContext getClientSessionContext() {
- return clientSessionContext;
- }
-
- /**
- * @return key manager
- */
- protected X509KeyManager getKeyManager() {
- return keyManager;
- }
-
- /**
- * @return trust manager
- */
- protected X509TrustManager getTrustManager() {
- return trustManager;
- }
-
- /**
- * @return secure random
- */
- protected SecureRandom getSecureRandom() {
- if (secureRandom != null) {
- return secureRandom;
- }
- SecureRandom result = defaultSecureRandom;
- if (result == null) {
- // single-check idiom
- defaultSecureRandom = result = new SecureRandom();
- }
- secureRandom = result;
- return secureRandom;
- }
-
- /**
- * @return the secure random member reference, even it is null
- */
- protected SecureRandom getSecureRandomMember() {
- return secureRandom;
- }
-
- /**
- * @return the names of enabled cipher suites
- */
- protected String[] getEnabledCipherSuites() {
- if (enabledCipherSuiteNames == null) {
- CipherSuite[] enabledCipherSuites = getEnabledCipherSuitesMember();
- enabledCipherSuiteNames = new String[enabledCipherSuites.length];
- for (int i = 0; i< enabledCipherSuites.length; i++) {
- enabledCipherSuiteNames[i] = enabledCipherSuites[i].getName();
- }
- }
- return enabledCipherSuiteNames.clone();
- }
-
- /**
- * Sets the set of available cipher suites for use in SSL connection.
- * @param suites: String[]
- * @return
- */
- protected void setEnabledCipherSuites(String[] suites) {
- if (suites == null) {
- throw new IllegalArgumentException("suites == null");
- }
- CipherSuite[] cipherSuites = new CipherSuite[suites.length];
- for (int i=0; i<suites.length; i++) {
- String suite = suites[i];
- if (suite == null) {
- throw new IllegalArgumentException("suites[" + i + "] == null");
- }
- cipherSuites[i] = CipherSuite.getByName(suite);
- if (cipherSuites[i] == null || !cipherSuites[i].supported) {
- throw new IllegalArgumentException(suite + " is not supported.");
- }
- }
- enabledCipherSuites = cipherSuites;
- enabledCipherSuiteNames = suites;
- }
-
- /**
- * @return the set of enabled protocols
- */
- protected String[] getEnabledProtocols() {
- return enabledProtocols.clone();
- }
-
- /**
- * Sets the set of available protocols for use in SSL connection.
- * @param protocols String[]
- */
- protected void setEnabledProtocols(String[] protocols) {
- if (protocols == null) {
- throw new IllegalArgumentException("protocols == null");
- }
- for (int i=0; i<protocols.length; i++) {
- String protocol = protocols[i];
- if (protocol == null) {
- throw new IllegalArgumentException("protocols[" + i + "] == null");
- }
- if (!ProtocolVersion.isSupported(protocol)) {
- throw new IllegalArgumentException("Protocol " + protocol + " is not supported.");
- }
- }
- enabledProtocols = protocols;
- }
-
- /**
- * Tunes the peer holding this parameters to work in client mode.
- * @param mode if the peer is configured to work in client mode
- */
- protected void setUseClientMode(boolean mode) {
- client_mode = mode;
- }
-
- /**
- * Returns the value indicating if the parameters configured to work
- * in client mode.
- */
- protected boolean getUseClientMode() {
- return client_mode;
- }
-
- /**
- * Tunes the peer holding this parameters to require client authentication
- */
- protected void setNeedClientAuth(boolean need) {
- need_client_auth = need;
- // reset the want_client_auth setting
- want_client_auth = false;
- }
-
- /**
- * Returns the value indicating if the peer with this parameters tuned
- * to require client authentication
- */
- protected boolean getNeedClientAuth() {
- return need_client_auth;
- }
-
- /**
- * Tunes the peer holding this parameters to request client authentication
- */
- protected void setWantClientAuth(boolean want) {
- want_client_auth = want;
- // reset the need_client_auth setting
- need_client_auth = false;
- }
-
- /**
- * Returns the value indicating if the peer with this parameters
- * tuned to request client authentication
- * @return
- */
- protected boolean getWantClientAuth() {
- return want_client_auth;
- }
-
- /**
- * Allows/disallows the peer holding this parameters to
- * create new SSL session
- */
- protected void setEnableSessionCreation(boolean flag) {
- enable_session_creation = flag;
- }
-
- /**
- * Returns the value indicating if the peer with this parameters
- * allowed to cteate new SSL session
- */
- protected boolean getEnableSessionCreation() {
- return enable_session_creation;
- }
-
- /**
- * Returns the clone of this object.
- * @return the clone.
- */
- @Override
- protected Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
- private static X509KeyManager getDefaultKeyManager() throws KeyManagementException {
- X509KeyManager result = defaultKeyManager;
- if (result == null) {
- // single-check idiom
- defaultKeyManager = result = createDefaultKeyManager();
- }
- return result;
- }
- private static X509KeyManager createDefaultKeyManager() throws KeyManagementException {
- try {
- String algorithm = KeyManagerFactory.getDefaultAlgorithm();
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
- kmf.init(null, null);
- KeyManager[] kms = kmf.getKeyManagers();
- return findX509KeyManager(kms);
- } catch (NoSuchAlgorithmException e) {
- throw new KeyManagementException(e);
- } catch (KeyStoreException e) {
- throw new KeyManagementException(e);
- } catch (UnrecoverableKeyException e) {
- throw new KeyManagementException(e);
- }
- }
- private static X509KeyManager findX509KeyManager(KeyManager[] kms) throws KeyManagementException {
- for (KeyManager km : kms) {
- if (km instanceof X509KeyManager) {
- return (X509KeyManager)km;
- }
- }
- throw new KeyManagementException("Failed to find an X509KeyManager in " + Arrays.toString(kms));
- }
-
- /**
- * Gets the default trust manager.
- *
- * TODO: Move this to a published API under dalvik.system.
- */
- public static X509TrustManager getDefaultTrustManager() throws KeyManagementException {
- X509TrustManager result = defaultTrustManager;
- if (result == null) {
- // single-check idiom
- defaultTrustManager = result = createDefaultTrustManager();
- }
- return result;
- }
- private static X509TrustManager createDefaultTrustManager() throws KeyManagementException {
- try {
- String algorithm = TrustManagerFactory.getDefaultAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- tmf.init((KeyStore) null);
- TrustManager[] tms = tmf.getTrustManagers();
- X509TrustManager trustManager = findX509TrustManager(tms);
- return trustManager;
- } catch (NoSuchAlgorithmException e) {
- throw new KeyManagementException(e);
- } catch (KeyStoreException e) {
- throw new KeyManagementException(e);
- }
- }
- private static X509TrustManager findX509TrustManager(TrustManager[] tms) throws KeyManagementException {
- for (TrustManager tm : tms) {
- if (tm instanceof X509TrustManager) {
- return (X509TrustManager)tm;
- }
- }
- throw new KeyManagementException("Failed to find an X509TrustManager in " + Arrays.toString(tms));
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLRecordProtocol.java b/crypto/src/main/java/org/conscrypt/SSLRecordProtocol.java
deleted file mode 100644
index 24b6c61..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLRecordProtocol.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import javax.net.ssl.SSLProtocolException;
-
-/**
- * This class performs functionality dedicated to SSL record layer.
- * It unpacks and routes income data to the appropriate
- * client protocol (handshake, alert, application data protocols)
- * and packages outcome data into SSL/TLS records.
- * Initially created object has null connection state and does not
- * perform any cryptography computations over the income/outcome data.
- * After handshake protocol agreed upon security parameters they are placed
- * into SSLSessionImpl object and available for record protocol as
- * pending session. The order of setting up of the pending session
- * as an active session differs for client and server modes.
- * So for client mode the parameters are provided by handshake protocol
- * during retrieving of change_cipher_spec message to be sent (by calling of
- * getChangeCipherSpecMesage method).
- * For server side mode record protocol retrieves the parameters from
- * handshake protocol after receiving of client's change_cipher_spec message.
- * After the pending session has been set up as a current session,
- * new connection state object is created and used for encryption/decryption
- * of the messages.
- * Among with base functionality this class provides the information about
- * constrains on the data length, and information about correspondence
- * of plain and encrypted data lengths.
- * For more information on TLS v1 see http://www.ietf.org/rfc/rfc2246.txt,
- * on SSL v3 see http://wp.netscape.com/eng/ssl3,
- * on SSL v2 see http://wp.netscape.com/eng/security/SSL_2.html.
- */
-public class SSLRecordProtocol {
-
- /**
- * Maximum length of allowed plain data fragment
- * as specified by TLS specification.
- */
- protected static final int MAX_DATA_LENGTH = 16384; // 2^14
- /**
- * Maximum length of allowed compressed data fragment
- * as specified by TLS specification.
- */
- protected static final int MAX_COMPRESSED_DATA_LENGTH
- = MAX_DATA_LENGTH + 1024;
- /**
- * Maximum length of allowed ciphered data fragment
- * as specified by TLS specification.
- */
- protected static final int MAX_CIPHERED_DATA_LENGTH
- = MAX_COMPRESSED_DATA_LENGTH + 1024;
- /**
- * Maximum length of ssl record. It is counted as:
- * type(1) + version(2) + length(2) + MAX_CIPHERED_DATA_LENGTH
- */
- protected static final int MAX_SSL_PACKET_SIZE
- = MAX_CIPHERED_DATA_LENGTH + 5;
- // the SSL session used for connection
- private SSLSessionImpl session;
- // protocol version of the connection
- private byte[] version;
- // input stream of record protocol
- private SSLInputStream in;
- // handshake protocol object to which handshaking data will be transmitted
- private HandshakeProtocol handshakeProtocol;
- // alert protocol to indicate alerts occurred/received
- private AlertProtocol alertProtocol;
- // application data object to which application data will be transmitted
- private Appendable appData;
- // connection state holding object
- private ConnectionState
- activeReadState, activeWriteState, pendingConnectionState;
-
- // logger
- private Logger.Stream logger = Logger.getStream("record");
-
- // flag indicating if session object has been changed after
- // handshake phase (to distinguish session pending state)
- private boolean sessionWasChanged = false;
-
- // change cipher spec message content
- private static final byte[] change_cipher_spec_byte = new byte[] {1};
-
- /**
- * Creates an instance of record protocol and tunes
- * up the client protocols to use ut.
- * @param handshakeProtocol: HandshakeProtocol
- * @param alertProtocol: AlertProtocol
- * @param in: SSLInputStream
- * @param appData: Appendable
- */
- protected SSLRecordProtocol(HandshakeProtocol handshakeProtocol,
- AlertProtocol alertProtocol,
- SSLInputStream in,
- Appendable appData) {
- this.handshakeProtocol = handshakeProtocol;
- this.handshakeProtocol.setRecordProtocol(this);
- this.alertProtocol = alertProtocol;
- this.alertProtocol.setRecordProtocol(this);
- this.in = in;
- this.appData = appData;
- }
-
- /**
- * Returns the session obtained during the handshake negotiation.
- * If the handshake process was not completed, method returns null.
- * @return the session in effect.
- */
- protected SSLSessionImpl getSession() {
- return session;
- }
-
- /**
- * Returns the minimum possible length of the SSL record.
- * @return
- */
- protected int getMinRecordSize() {
- return (activeReadState == null)
- ? 6 // type + version + length + 1 byte of data
- : 5 + activeReadState.getMinFragmentSize();
- }
-
- /**
- * Returns the record length for the specified incoming data length.
- * If actual resulting record length is greater than
- * MAX_CIPHERED_DATA_LENGTH, MAX_CIPHERED_DATA_LENGTH is returned.
- */
- protected int getRecordSize(int data_size) {
- if (activeWriteState == null) {
- return 5+data_size; // type + version + length + data_size
- } else {
- int res = 5 + activeWriteState.getFragmentSize(data_size);
- return (res > MAX_CIPHERED_DATA_LENGTH)
- ? MAX_CIPHERED_DATA_LENGTH // so the source data should be
- // split into several packets
- : res;
- }
- }
-
- /**
- * Returns the upper bound of length of data containing in the record with
- * specified length.
- * If the provided record_size is greater or equal to
- * MAX_CIPHERED_DATA_LENGTH the returned value will be
- * MAX_DATA_LENGTH
- * counted as for data with
- * MAX_CIPHERED_DATA_LENGTH length.
- */
- protected int getDataSize(int record_size) {
- record_size -= 5; // - (type + version + length + data_size)
- if (record_size > MAX_CIPHERED_DATA_LENGTH) {
- // the data of such size consists of the several packets
- return MAX_DATA_LENGTH;
- }
- if (activeReadState == null) {
- return record_size;
- }
- return activeReadState.getContentSize(record_size);
- }
-
- /**
- * Depending on the Connection State (Session) encrypts and compress
- * the provided data, and packs it into TLSCiphertext structure.
- * @param content_type: int
- * @return ssl packet created over the current connection state
- */
- protected byte[] wrap(byte content_type, DataStream dataStream) {
- byte[] fragment = dataStream.getData(MAX_DATA_LENGTH);
- return wrap(content_type, fragment, 0, fragment.length);
- }
-
- /**
- * Depending on the Connection State (Session) encrypts and compress
- * the provided data, and packs it into TLSCiphertext structure.
- * @param content_type: int
- * @param fragment: byte[]
- * @return ssl packet created over the current connection state
- */
- protected byte[] wrap(byte content_type,
- byte[] fragment, int offset, int len) {
- if (logger != null) {
- logger.println("SSLRecordProtocol.wrap: TLSPlaintext.fragment["
- +len+"]:");
- logger.print(fragment, offset, len);
- }
- if (len > MAX_DATA_LENGTH) {
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException(
- "The provided chunk of data is too big: " + len
- + " > MAX_DATA_LENGTH == "+MAX_DATA_LENGTH));
- }
- byte[] ciphered_fragment = fragment;
- if (activeWriteState != null) {
- ciphered_fragment =
- activeWriteState.encrypt(content_type, fragment, offset, len);
- if (ciphered_fragment.length > MAX_CIPHERED_DATA_LENGTH) {
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException(
- "The ciphered data increased more than on 1024 bytes"));
- }
- if (logger != null) {
- logger.println("SSLRecordProtocol.wrap: TLSCiphertext.fragment["
- +ciphered_fragment.length+"]:");
- logger.print(ciphered_fragment);
- }
- }
- return packetize(content_type, version, ciphered_fragment);
- }
-
- private byte[] packetize(byte type, byte[] version, byte[] fragment) {
- byte[] buff = new byte[5+fragment.length];
- buff[0] = type;
- if (version != null) {
- buff[1] = version[0];
- buff[2] = version[1];
- } else {
- buff[1] = 3;
- buff[2] = 1;
- }
- buff[3] = (byte) ((0x00FF00 & fragment.length) >> 8);
- buff[4] = (byte) (0x0000FF & fragment.length);
- System.arraycopy(fragment, 0, buff, 5, fragment.length);
- return buff;
- }
-
- /**
- * Set the ssl session to be used after sending the changeCipherSpec message
- * @param session: SSLSessionImpl
- */
- private void setSession(SSLSessionImpl session) {
- if (!sessionWasChanged) {
- // session was not changed for current handshake process
- if (logger != null) {
- logger.println("SSLRecordProtocol.setSession: Set pending session");
- logger.println(" cipher name: " + session.getCipherSuite());
- }
- this.session = session;
- // create new connection state
- pendingConnectionState = ((version == null) || (version[1] == 1))
- ? (ConnectionState) new ConnectionStateTLS(getSession())
- : (ConnectionState) new ConnectionStateSSLv3(getSession());
- sessionWasChanged = true;
- } else {
- // wait for rehandshaking's session
- sessionWasChanged = false;
- }
- }
-
- /**
- * Returns the change cipher spec message to be sent to another peer.
- * The pending connection state will be built on the base of provided
- * session object
- * The calling of this method triggers pending write connection state to
- * be active.
- * @return ssl record containing the "change cipher spec" message.
- */
- protected byte[] getChangeCipherSpecMesage(SSLSessionImpl session) {
- // make change_cipher_spec_message:
- byte[] change_cipher_spec_message;
- if (activeWriteState == null) {
- change_cipher_spec_message = new byte[] {
- ContentType.CHANGE_CIPHER_SPEC, version[0],
- version[1], 0, 1, 1
- };
- } else {
- change_cipher_spec_message =
- packetize(ContentType.CHANGE_CIPHER_SPEC, version,
- activeWriteState.encrypt(ContentType.CHANGE_CIPHER_SPEC,
- change_cipher_spec_byte, 0, 1));
- }
- setSession(session);
- activeWriteState = pendingConnectionState;
- if (logger != null) {
- logger.println("SSLRecordProtocol.getChangeCipherSpecMesage");
- logger.println("activeWriteState = pendingConnectionState");
- logger.print(change_cipher_spec_message);
- }
- return change_cipher_spec_message;
- }
-
- /**
- * Retrieves the fragment field of TLSCiphertext, and than
- * depending on the established Connection State
- * decrypts and decompresses it. The following structure is expected
- * on the input at the moment of the call:
- *
- * struct {
- * ContentType type;
- * ProtocolVersion version;
- * uint16 length;
- * select (CipherSpec.cipher_type) {
- * case stream: GenericStreamCipher;
- * case block: GenericBlockCipher;
- * } fragment;
- * } TLSCiphertext;
- *
- * (as specified by RFC 2246, TLS v1 Protocol specification)
- *
- * In addition this method can recognize SSLv2 hello message which
- * are often used to establish the SSL/TLS session.
- *
- * @throws IOException if some io errors have been occurred
- * @throws EndOfSourceException if underlying input stream
- * has ran out of data.
- * @throws EndOfBufferException if there was not enough data
- * to build complete ssl packet.
- * @return the type of unwrapped message.
- */
- protected int unwrap() throws IOException {
- if (logger != null) {
- logger.println("SSLRecordProtocol.unwrap: BEGIN [");
- }
- int type = in.readUint8();
- if ((type < ContentType.CHANGE_CIPHER_SPEC)
- || (type > ContentType.APPLICATION_DATA)) {
- if (logger != null) {
- logger.println("Non v3.1 message type:" + type);
- }
- if (type >= 0x80) {
- // it is probably SSL v2 client_hello message
- // (see SSL v2 spec at:
- // http://wp.netscape.com/eng/security/SSL_2.html)
- int length = (type & 0x7f) << 8 | in.read();
- byte[] fragment = in.read(length);
- handshakeProtocol.unwrapSSLv2(fragment);
- if (logger != null) {
- logger.println(
- "SSLRecordProtocol:unwrap ] END, SSLv2 type");
- }
- return ContentType.HANDSHAKE;
- }
- throw new AlertException(AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLProtocolException(
- "Unexpected message type has been received: "+type));
- }
- if (logger != null) {
- logger.println("Got the message of type: " + type);
- }
- if (version != null) {
- if ((in.read() != version[0])
- || (in.read() != version[1])) {
- throw new AlertException(AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLProtocolException(
- "Unexpected message type has been received: " +
- type));
- }
- } else {
- in.skip(2); // just skip the version number
- }
- int length = in.readUint16();
- if (logger != null) {
- logger.println("TLSCiphertext.fragment["+length+"]: ...");
- }
- if (length > MAX_CIPHERED_DATA_LENGTH) {
- throw new AlertException(AlertProtocol.RECORD_OVERFLOW,
- new SSLProtocolException(
- "Received message is too big."));
- }
- byte[] fragment = in.read(length);
- if (logger != null) {
- logger.print(fragment);
- }
- if (activeReadState != null) {
- fragment = activeReadState.decrypt((byte) type, fragment);
- if (logger != null) {
- logger.println("TLSPlaintext.fragment:");
- logger.print(fragment);
- }
- }
- if (fragment.length > MAX_DATA_LENGTH) {
- throw new AlertException(AlertProtocol.DECOMPRESSION_FAILURE,
- new SSLProtocolException(
- "Decompressed plain data is too big."));
- }
- switch (type) {
- case ContentType.CHANGE_CIPHER_SPEC:
- // notify handshake protocol:
- handshakeProtocol.receiveChangeCipherSpec();
- setSession(handshakeProtocol.getSession());
- // change cipher spec message has been received, so:
- if (logger != null) {
- logger.println("activeReadState = pendingConnectionState");
- }
- activeReadState = pendingConnectionState;
- break;
- case ContentType.ALERT:
- alert(fragment[0], fragment[1]);
- break;
- case ContentType.HANDSHAKE:
- handshakeProtocol.unwrap(fragment);
- break;
- case ContentType.APPLICATION_DATA:
- if (logger != null) {
- logger.println(
- "TLSCiphertext.unwrap: APP DATA["+length+"]:");
- logger.println(new String(fragment));
- }
- appData.append(fragment);
- break;
- default:
- throw new AlertException(AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLProtocolException(
- "Unexpected message type has been received: " +
- type));
- }
- if (logger != null) {
- logger.println("SSLRecordProtocol:unwrap ] END, type: " + type);
- }
- return type;
- }
-
- /**
- * Passes the alert information to the alert protocol.
- * @param level: byte
- * @param description: byte
- */
- protected void alert(byte level, byte description) {
- if (logger != null) {
- logger.println("SSLRecordProtocol.allert: "+level+" "+description);
- }
- alertProtocol.alert(level, description);
- }
-
- /**
- * Sets up the SSL version used in this connection.
- * This method is calling from the handshake protocol after
- * it becomes known which protocol version will be used.
- * @param ver: byte[]
- * @return
- */
- protected void setVersion(byte[] ver) {
- this.version = ver;
- }
-
- /**
- * Shuts down the protocol. It will be impossible to use the instance
- * after the calling of this method.
- */
- protected void shutdown() {
- session = null;
- version = null;
- in = null;
- handshakeProtocol = null;
- alertProtocol = null;
- appData = null;
- if (pendingConnectionState != null) {
- pendingConnectionState.shutdown();
- }
- pendingConnectionState = null;
- if (activeReadState != null) {
- activeReadState.shutdown();
- }
- activeReadState = null;
- if (activeReadState != null) {
- activeReadState.shutdown();
- }
- activeWriteState = null;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLServerSessionCache.java b/crypto/src/main/java/org/conscrypt/SSLServerSessionCache.java
deleted file mode 100644
index a380ce9..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLServerSessionCache.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLSession;
-
-/**
- * A persistent {@link javax.net.ssl.SSLSession} cache used by
- * {@link javax.net.ssl.SSLSessionContext} to share server-side SSL sessions
- * across processes. For example, this cache enables one server to resume
- * a session started by a different server based on a session ID provided
- * by the client.
- *
- * <p>The {@code SSLSessionContext} implementation converts
- * {@code SSLSession}s into raw bytes and vice versa. The exact makeup of the
- * session data is dependent upon the caller's implementation and is opaque to
- * the {@code SSLServerSessionCache} implementation.
- */
-public interface SSLServerSessionCache {
-
- /**
- * Gets the session data for given session ID.
- *
- * @param id from {@link javax.net.ssl.SSLSession#getId()}
- * @return the session data or null if none is cached
- * @throws NullPointerException if id is null
- */
- public byte[] getSessionData(byte[] id);
-
- /**
- * Stores session data for the given session.
- *
- * @param session to cache data for
- * @param sessionData to cache
- * @throws NullPointerException if session or data is null
- */
- public void putSessionData(SSLSession session, byte[] sessionData);
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/SSLServerSocketFactoryImpl.java b/crypto/src/main/java/org/conscrypt/SSLServerSocketFactoryImpl.java
deleted file mode 100644
index 5b16f85..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLServerSocketFactoryImpl.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.security.KeyManagementException;
-import javax.net.ssl.SSLServerSocketFactory;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * Implementation of SSLServerSocketFactory.
- */
-public class SSLServerSocketFactoryImpl extends SSLServerSocketFactory {
-
- private SSLParametersImpl sslParameters;
- private IOException instantiationException;
-
- /**
- * Constructor.
- */
- public SSLServerSocketFactoryImpl() {
- try {
- this.sslParameters = SSLParametersImpl.getDefault();
- this.sslParameters.setUseClientMode(false);
- } catch (KeyManagementException e) {
- instantiationException =
- new IOException("Delayed instantiation exception:");
- instantiationException.initCause(e);
- }
- }
-
- /**
- * Constructor.
- */
- protected SSLServerSocketFactoryImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = (SSLParametersImpl) sslParameters.clone();
- this.sslParameters.setUseClientMode(false);
- }
-
- /**
- * @see javax.net.ssl.SSLServerSocketFactory#getDefaultCipherSuites()
- */
- @Override
- public String[] getDefaultCipherSuites() {
- if (instantiationException != null) {
- return EmptyArray.STRING;
- }
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * @see javax.net.ssl.SSLServerSocketFactory#getSupportedCipherSuites()
- */
- @Override
- public String[] getSupportedCipherSuites() {
- if (instantiationException != null) {
- return EmptyArray.STRING;
- }
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- /**
- * @see javax.net.ServerSocketFactory#createServerSocket()
- */
- @Override
- public ServerSocket createServerSocket() throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLServerSocketImpl((SSLParametersImpl) sslParameters.clone());
- }
-
-
- /**
- * @see javax.net.ServerSocketFactory#createServerSocket(int)
- */
- @Override
- public ServerSocket createServerSocket(int port) throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLServerSocketImpl(port,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.ServerSocketFactory#createServerSocket(int,int)
- */
- @Override
- public ServerSocket createServerSocket(int port, int backlog)
- throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLServerSocketImpl(port, backlog,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.ServerSocketFactory#createServerSocket(int,int,InetAddress)
- */
- @Override
- public ServerSocket createServerSocket(int port, int backlog,
- InetAddress iAddress) throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLServerSocketImpl(port, backlog, iAddress,
- (SSLParametersImpl) sslParameters.clone());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLServerSocketImpl.java b/crypto/src/main/java/org/conscrypt/SSLServerSocketImpl.java
deleted file mode 100644
index a30e3b4..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLServerSocketImpl.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import javax.net.ssl.SSLServerSocket;
-
-/**
- * SSLServerSocket implementation
- * @see javax.net.ssl.SSLServerSocket class documentation for more information.
- */
-public class SSLServerSocketImpl extends SSLServerSocket {
-
- // the sslParameters object encapsulates all the info
- // about supported and enabled cipher suites and protocols,
- // as well as the information about client/server mode of
- // ssl socket, whether it require/want client authentication or not,
- // and controls whether new SSL sessions may be established by this
- // socket or not.
- private final SSLParametersImpl sslParameters;
-
- // logger
- private Logger.Stream logger = Logger.getStream("ssocket");
-
- /**
- * Ctor
- * @param sslParameters: SSLParameters
- * @throws IOException
- */
- protected SSLServerSocketImpl(SSLParametersImpl sslParameters) throws IOException {
- this.sslParameters = sslParameters;
- }
-
- /**
- * Ctor
- * @param port: int
- * @param sslParameters: SSLParameters
- * @throws IOException
- */
- protected SSLServerSocketImpl(int port, SSLParametersImpl sslParameters)
- throws IOException {
- super(port);
- this.sslParameters = sslParameters;
- }
-
- /**
- * Ctor
- * @param port: int
- * @param backlog: int
- * @param sslParameters: SSLParameters
- * @throws IOException
- */
- protected SSLServerSocketImpl(int port, int backlog,
- SSLParametersImpl sslParameters) throws IOException {
- super(port, backlog);
- this.sslParameters = sslParameters;
- }
-
- /**
- * Ctor
- * @param port: int
- * @param backlog: int
- * @param iAddress: InetAddress
- * @param sslParameters: SSLParameters
- * @throws IOException
- */
- protected SSLServerSocketImpl(int port, int backlog,
- InetAddress iAddress,
- SSLParametersImpl sslParameters)
- throws IOException {
- super(port, backlog, iAddress);
- this.sslParameters = sslParameters;
- }
-
- // --------------- SSLParameters based methods ---------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getSupportedCipherSuites()
- * method documentation for more information
- */
- @Override
- public String[] getSupportedCipherSuites() {
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getEnabledCipherSuites()
- * method documentation for more information
- */
- @Override
- public String[] getEnabledCipherSuites() {
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setEnabledCipherSuites(String[])
- * method documentation for more information
- */
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- sslParameters.setEnabledCipherSuites(suites);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getSupportedProtocols()
- * method documentation for more information
- */
- @Override
- public String[] getSupportedProtocols() {
- return ProtocolVersion.supportedProtocols.clone();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getEnabledProtocols()
- * method documentation for more information
- */
- @Override
- public String[] getEnabledProtocols() {
- return sslParameters.getEnabledProtocols();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setEnabledProtocols(String[])
- * method documentation for more information
- */
- @Override
- public void setEnabledProtocols(String[] protocols) {
- sslParameters.setEnabledProtocols(protocols);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setUseClientMode(boolean)
- * method documentation for more information
- */
- @Override
- public void setUseClientMode(boolean mode) {
- sslParameters.setUseClientMode(mode);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getUseClientMode()
- * method documentation for more information
- */
- @Override
- public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setNeedClientAuth(boolean)
- * method documentation for more information
- */
- @Override
- public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getNeedClientAuth()
- * method documentation for more information
- */
- @Override
- public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setWantClientAuth(boolean)
- * method documentation for more information
- */
- @Override
- public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getWantClientAuth()
- * method documentation for more information
- */
- @Override
- public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setEnableSessionCreation(boolean)
- * method documentation for more information
- */
- @Override
- public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getEnableSessionCreation()
- * method documentation for more information
- */
- @Override
- public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
-
- // ------------- ServerSocket's methods overridings ----------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see java.net.ServerSocket#accept()
- * method documentation for more information
- */
- @Override
- public Socket accept() throws IOException {
- if (logger != null) {
- logger.println("SSLServerSocketImpl.accept ..");
- }
- SSLSocketImpl s = new SSLSocketImpl(
- (SSLParametersImpl) sslParameters.clone());
- implAccept(s);
- s.init();
- if (logger != null) {
- logger.println("SSLServerSocketImpl: accepted, initialized");
- }
- return s;
- }
-
- /**
- * Returns the string representation of the object.
- */
- @Override
- public String toString() {
- return "[SSLServerSocketImpl]";
- }
-
- // -----------------------------------------------------------------
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java b/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java
deleted file mode 100644
index 9631b1e..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.Principal;
-import java.security.SecureRandom;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionBindingEvent;
-import javax.net.ssl.SSLSessionBindingListener;
-import javax.net.ssl.SSLSessionContext;
-import org.conscrypt.util.EmptyArray;
-
-public final class SSLSessionImpl implements SSLSession, Cloneable {
-
- /*
- * Holds default instances so class preloading doesn't create an instance of
- * it.
- */
- private static class DefaultHolder {
- public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(null);
- }
-
- private long creationTime;
- private boolean isValid = true;
- private final Map<String, Object> values = new HashMap<String, Object>();
-
- byte[] id;
- long lastAccessedTime;
- ProtocolVersion protocol;
- CipherSuite cipherSuite;
- SSLSessionContext context;
- X509Certificate[] localCertificates;
- X509Certificate[] peerCertificates;
- private String peerHost;
- private int peerPort = -1;
- byte[] master_secret;
- byte[] clientRandom;
- byte[] serverRandom;
- final boolean isServer;
-
- public static SSLSessionImpl getNullSession() {
- return DefaultHolder.NULL_SESSION;
- }
-
- public SSLSessionImpl(CipherSuite cipher_suite, SecureRandom secureRandom) {
- creationTime = System.currentTimeMillis();
- lastAccessedTime = creationTime;
- if (cipher_suite == null) {
- this.cipherSuite = CipherSuite.SSL_NULL_WITH_NULL_NULL;
- id = EmptyArray.BYTE;
- isServer = false;
- isValid = false;
- } else {
- this.cipherSuite = cipher_suite;
- id = new byte[32];
- secureRandom.nextBytes(id);
- long time = creationTime / 1000;
- id[28] = (byte) ((time & 0xFF000000) >>> 24);
- id[29] = (byte) ((time & 0x00FF0000) >>> 16);
- id[30] = (byte) ((time & 0x0000FF00) >>> 8);
- id[31] = (byte) ((time & 0x000000FF));
- isServer = true;
- }
-
- }
-
- public SSLSessionImpl(SecureRandom secureRandom) {
- this(null, secureRandom);
- }
-
- public int getApplicationBufferSize() {
- return SSLRecordProtocol.MAX_DATA_LENGTH;
- }
-
- public String getCipherSuite() {
- return cipherSuite.getName();
- }
-
- public long getCreationTime() {
- return creationTime;
- }
-
- public byte[] getId() {
- return id;
- }
-
- public long getLastAccessedTime() {
- return lastAccessedTime;
- }
-
- public Certificate[] getLocalCertificates() {
- return localCertificates;
- }
-
- public Principal getLocalPrincipal() {
- if (localCertificates != null && localCertificates.length > 0) {
- return localCertificates[0].getSubjectX500Principal();
- }
- return null;
- }
-
- public int getPacketBufferSize() {
- return SSLRecordProtocol.MAX_SSL_PACKET_SIZE;
- }
-
- public javax.security.cert.X509Certificate[] getPeerCertificateChain()
- throws SSLPeerUnverifiedException {
- if (peerCertificates == null) {
- throw new SSLPeerUnverifiedException("No peer certificate");
- }
- javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[peerCertificates.length];
- for (int i = 0; i < certs.length; i++) {
- try {
- certs[i] = javax.security.cert.X509Certificate.getInstance(peerCertificates[i]
- .getEncoded());
- } catch (javax.security.cert.CertificateException ignored) {
- } catch (CertificateEncodingException ignored) {
- }
- }
- return certs;
- }
-
- public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
- if (peerCertificates == null) {
- throw new SSLPeerUnverifiedException("No peer certificate");
- }
- return peerCertificates;
- }
-
- public String getPeerHost() {
- return peerHost;
- }
-
- public int getPeerPort() {
- return peerPort;
- }
-
- public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
- if (peerCertificates == null) {
- throw new SSLPeerUnverifiedException("No peer certificate");
- }
- return peerCertificates[0].getSubjectX500Principal();
- }
-
- public String getProtocol() {
- return (protocol == null) ? "NONE" : protocol.name;
- }
-
- public SSLSessionContext getSessionContext() {
- return context;
- }
-
- public Object getValue(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name == null");
- }
- return values.get(name);
- }
-
- public String[] getValueNames() {
- return values.keySet().toArray(new String[values.size()]);
- }
-
- public void invalidate() {
- isValid = false;
- context = null;
- }
-
- public boolean isValid() {
- if (isValid && context != null && context.getSessionTimeout() != 0
- && lastAccessedTime + context.getSessionTimeout() > System.currentTimeMillis()) {
- isValid = false;
- }
- return isValid;
- }
-
- public void putValue(String name, Object value) {
- if (name == null || value == null) {
- throw new IllegalArgumentException("name == null || value == null");
- }
- Object old = values.put(name, value);
- if (value instanceof SSLSessionBindingListener) {
- ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name));
- }
- if (old instanceof SSLSessionBindingListener) {
- ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name));
- }
-
- }
-
- public void removeValue(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name == null");
- }
- Object old = values.remove(name);
- if (old instanceof SSLSessionBindingListener) {
- SSLSessionBindingListener listener = (SSLSessionBindingListener) old;
- listener.valueUnbound(new SSLSessionBindingEvent(this, name));
- }
- }
-
- @Override
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
- void setPeer(String peerHost, int peerPort) {
- this.peerHost = peerHost;
- this.peerPort = peerPort;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketFactoryImpl.java b/crypto/src/main/java/org/conscrypt/SSLSocketFactoryImpl.java
deleted file mode 100644
index dc971ac..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketFactoryImpl.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.KeyManagementException;
-import javax.net.ssl.SSLSocketFactory;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * Implementation of SSLSocketFactory.
- */
-public class SSLSocketFactoryImpl extends SSLSocketFactory {
-
- private final SSLParametersImpl sslParameters;
- private final IOException instantiationException;
-
- /**
- * Constructor.
- */
- public SSLSocketFactoryImpl() {
- SSLParametersImpl sslParametersLocal = null;
- IOException instantiationExceptionLocal = null;
- try {
- sslParametersLocal = SSLParametersImpl.getDefault();
- } catch (KeyManagementException e) {
- instantiationExceptionLocal = new IOException("Delayed instantiation exception:");
- instantiationExceptionLocal.initCause(e);
- }
- this.sslParameters = sslParametersLocal;
- this.instantiationException = instantiationExceptionLocal;
- }
-
- /**
- * Constructor.
- */
- protected SSLSocketFactoryImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = sslParameters;
- this.instantiationException = null;
- }
-
- /**
- * @see javax.net.ssl.SSLSocketFactory#getDefaultCipherSuites()
- */
- @Override
- public String[] getDefaultCipherSuites() {
- if (instantiationException != null) {
- return EmptyArray.STRING;
- }
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * @see javax.net.ssl.SSLSocketFactory#getSupportedCipherSuites()
- */
- @Override
- public String[] getSupportedCipherSuites() {
- if (instantiationException != null) {
- return EmptyArray.STRING;
- }
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- /**
- * @see javax.net.ssl.SSLSocketFactory#createSocket(Socket,String,int,boolean)
- */
- @Override
- public Socket createSocket(Socket s, String host, int port,
- boolean autoClose) throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketWrapper(s, host, port, autoClose, (SSLParametersImpl) sslParameters
- .clone());
- }
-
- // -------------- Methods inherided from SocketFactory --------------
-
- /**
- * @see javax.net.SocketFactory#createSocket()
- */
- @Override
- public Socket createSocket() throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl((SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.SocketFactory#createSocket(String,int)
- */
- @Override
- public Socket createSocket(String host, int port)
- throws IOException, UnknownHostException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl(host, port,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.SocketFactory#createSocket(String,int,InetAddress,int)
- */
- @Override
- public Socket createSocket(String host, int port,
- InetAddress localHost, int localPort) throws IOException,
- UnknownHostException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl(host, port, localHost, localPort,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.SocketFactory#createSocket(InetAddress,int)
- */
- @Override
- public Socket createSocket(InetAddress host, int port)
- throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl(host, port,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.SocketFactory#createSocket(InetAddress,int,InetAddress,int)
- */
- @Override
- public Socket createSocket(InetAddress address, int port,
- InetAddress localAddress, int localPort) throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl(address, port, localAddress, localPort,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- // ------------------------------------------------------------------
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java b/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java
deleted file mode 100644
index 138a143..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import javax.net.ssl.HandshakeCompletedEvent;
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-
-/**
- * SSLSocket implementation.
- * @see javax.net.ssl.SSLSocket class documentation for more information.
- */
-public class SSLSocketImpl extends SSLSocket {
-
- // indicates if handshake has been started
- private boolean handshake_started = false;
-
- // used when we're wrapping a socket
- private final String wrappedHost;
- private final int wrappedPort;
-
- // record protocol to be used
- protected SSLRecordProtocol recordProtocol;
- // handshake protocol to be used
- private HandshakeProtocol handshakeProtocol;
- // alert protocol to be used
- private AlertProtocol alertProtocol;
- // application data input stream, this stream is presented by
- // ssl socket as an input stream. Additionally this object is a
- // place where application data will be stored by record protocol
- private SSLSocketInputStream appDataIS;
- // outgoing application data stream
- private SSLSocketOutputStream appDataOS;
- // active session object
- private SSLSessionImpl session;
-
- private boolean socket_was_closed = false;
-
- // the sslParameters object encapsulates all the info
- // about supported and enabled cipher suites and protocols,
- // as well as the information about client/server mode of
- // ssl socket, whether it require/want client authentication or not,
- // and controls whether new SSL sessions may be established by this
- // socket or not.
- protected SSLParametersImpl sslParameters;
- // super's streams to be wrapped:
- protected InputStream input;
- protected OutputStream output;
- // handshake complete listeners
- private ArrayList<HandshakeCompletedListener> listeners;
- // logger
- private Logger.Stream logger = Logger.getStream("socket");
-
- // ----------------- Constructors and initializers --------------------
-
- /**
- * Constructor
- * @param sslParameters: SSLParametersImpl
- * @see javax.net.ssl.SSLSocket#SSLSocket() method documentation
- * for more information.
- */
- protected SSLSocketImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = sslParameters;
- this.wrappedHost = null;
- this.wrappedPort = -1;
- // init should be called after creation!
- }
-
- /**
- * Constructor
- * @param host: String
- * @param port: int
- * @param sslParameters: SSLParametersImpl
- * @throws IOException
- * @throws UnknownHostException
- * @see javax.net.ssl.SSLSocket#SSLSocket(String,int)
- * method documentation for more information.
- */
- protected SSLSocketImpl(String host, int port, SSLParametersImpl sslParameters)
- throws IOException, UnknownHostException {
- super(host, port);
- this.wrappedHost = host;
- this.wrappedPort = port;
- this.sslParameters = sslParameters;
- init();
- }
-
- /**
- * Constructor
- * @param host: String
- * @param port: int
- * @param localHost: InetAddress
- * @param localPort: int
- * @param sslParameters: SSLParametersImpl
- * @throws IOException
- * @throws UnknownHostException
- * @see javax.net.ssl.SSLSocket#SSLSocket(String,int,InetAddress,int)
- * method documentation for more information.
- */
- protected SSLSocketImpl(String host, int port,
- InetAddress localHost, int localPort,
- SSLParametersImpl sslParameters) throws IOException,
- UnknownHostException {
- super(host, port, localHost, localPort);
- this.wrappedHost = host;
- this.wrappedPort = port;
- this.sslParameters = sslParameters;
- init();
- }
-
- /**
- * Constructor
- * @param host: InetAddress
- * @param port: int
- * @param sslParameters: SSLParametersImpl
- * @return
- * @throws IOException
- * @see javax.net.ssl.SSLSocket#SSLSocket(InetAddress,int)
- * method documentation for more information.
- */
- protected SSLSocketImpl(InetAddress host, int port,
- SSLParametersImpl sslParameters) throws IOException {
- super(host, port);
- this.sslParameters = sslParameters;
- this.wrappedHost = null;
- this.wrappedPort = -1;
- init();
- }
-
- /**
- * Constructor
- * @param address: InetAddress
- * @param port: int
- * @param localAddress: InetAddress
- * @param localPort: int
- * @param sslParameters: SSLParametersImpl
- * @return
- * @throws IOException
- * @see javax.net.ssl.SSLSocket#SSLSocket(InetAddress,int,InetAddress,int)
- * method documentation for more information.
- */
- protected SSLSocketImpl(InetAddress address, int port,
- InetAddress localAddress, int localPort,
- SSLParametersImpl sslParameters) throws IOException {
- super(address, port, localAddress, localPort);
- this.sslParameters = sslParameters;
- this.wrappedHost = null;
- this.wrappedPort = -1;
- init();
- }
-
- /**
- * Initialize the SSL socket.
- */
- protected void init() throws IOException {
- if (appDataIS != null) {
- // already initialized
- return;
- }
- initTransportLayer();
- appDataIS = new SSLSocketInputStream(this);
- appDataOS = new SSLSocketOutputStream(this);
- }
-
- /**
- * Initialize the transport data streams.
- */
- protected void initTransportLayer() throws IOException {
- input = super.getInputStream();
- output = super.getOutputStream();
- }
-
- /**
- * Closes the transport data streams.
- */
- protected void closeTransportLayer() throws IOException {
- super.close();
- if (input != null) {
- input.close();
- output.close();
- }
- }
-
- String getWrappedHostName() {
- return wrappedHost;
- }
-
- int getWrappedPort() {
- return wrappedPort;
- }
-
- String getPeerHostName() {
- if (wrappedHost != null) {
- return wrappedHost;
- }
- InetAddress inetAddress = super.getInetAddress();
- if (inetAddress != null) {
- return inetAddress.getHostName();
- }
- return null;
- }
-
- int getPeerPort() {
- return (wrappedPort == -1) ? super.getPort() : wrappedPort;
- }
-
- // --------------- SSLParameters based methods ---------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getSupportedCipherSuites()
- * method documentation for more information
- */
- @Override
- public String[] getSupportedCipherSuites() {
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getEnabledCipherSuites()
- * method documentation for more information
- */
- @Override
- public String[] getEnabledCipherSuites() {
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setEnabledCipherSuites(String[])
- * method documentation for more information
- */
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- sslParameters.setEnabledCipherSuites(suites);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getSupportedProtocols()
- * method documentation for more information
- */
- @Override
- public String[] getSupportedProtocols() {
- return ProtocolVersion.supportedProtocols.clone();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getEnabledProtocols()
- * method documentation for more information
- */
- @Override
- public String[] getEnabledProtocols() {
- return sslParameters.getEnabledProtocols();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setEnabledProtocols(String[])
- * method documentation for more information
- */
- @Override
- public void setEnabledProtocols(String[] protocols) {
- sslParameters.setEnabledProtocols(protocols);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setUseClientMode(boolean)
- * method documentation for more information
- */
- @Override
- public void setUseClientMode(boolean mode) {
- if (handshake_started) {
- throw new IllegalArgumentException(
- "Could not change the mode after the initial handshake has begun.");
- }
- sslParameters.setUseClientMode(mode);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getUseClientMode()
- * method documentation for more information
- */
- @Override
- public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setNeedClientAuth(boolean)
- * method documentation for more information
- */
- @Override
- public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getNeedClientAuth()
- * method documentation for more information
- */
- @Override
- public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setWantClientAuth(boolean)
- * method documentation for more information
- */
- @Override
- public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getWantClientAuth()
- * method documentation for more information
- */
- @Override
- public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setEnableSessionCreation(boolean)
- * method documentation for more information
- */
- @Override
- public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getEnableSessionCreation()
- * method documentation for more information
- */
- @Override
- public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
- // -----------------------------------------------------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getSession()
- * method documentation for more information
- */
- @Override
- public SSLSession getSession() {
- if (!handshake_started) {
- try {
- startHandshake();
- } catch (IOException e) {
- // return an invalid session with
- // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
- return SSLSessionImpl.getNullSession();
- }
- }
- return session;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#addHandshakeCompletedListener(HandshakeCompletedListener)
- * method documentation for more information
- */
- @Override
- public void addHandshakeCompletedListener(
- HandshakeCompletedListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("Provided listener is null");
- }
- if (listeners == null) {
- listeners = new ArrayList<HandshakeCompletedListener>();
- }
- listeners.add(listener);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#removeHandshakeCompletedListener(HandshakeCompletedListener)
- * method documentation for more information
- */
- @Override
- public void removeHandshakeCompletedListener(
- HandshakeCompletedListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("Provided listener is null");
- }
- if (listeners == null) {
- throw new IllegalArgumentException(
- "Provided listener is not registered");
- }
- if (!listeners.remove(listener)) {
- throw new IllegalArgumentException(
- "Provided listener is not registered");
- }
- }
-
- /**
- * Performs the handshake process over the SSL/TLS connection
- * as described in rfc 2246, TLS v1 specification
- * http://www.ietf.org/rfc/rfc2246.txt. If the initial handshake
- * has been already done, this method initiates rehandshake.
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#startHandshake()
- * method documentation for more information
- */
- @Override
- public void startHandshake() throws IOException {
- if (appDataIS == null) {
- throw new IOException("Socket is not connected.");
- }
- if (socket_was_closed) {
- throw new IOException("Socket has already been closed.");
- }
-
- if (!handshake_started) {
- handshake_started = true;
- if (sslParameters.getUseClientMode()) {
- if (logger != null) {
- logger.println("SSLSocketImpl: CLIENT");
- }
- handshakeProtocol = new ClientHandshakeImpl(this);
- } else {
- if (logger != null) {
- logger.println("SSLSocketImpl: SERVER");
- }
- handshakeProtocol = new ServerHandshakeImpl(this);
- }
-
- alertProtocol = new AlertProtocol();
- recordProtocol = new SSLRecordProtocol(handshakeProtocol,
- alertProtocol, new SSLStreamedInput(input),
- appDataIS.dataPoint);
- }
-
- if (logger != null) {
- logger.println("SSLSocketImpl.startHandshake");
- }
-
- handshakeProtocol.start();
-
- doHandshake();
-
- if (logger != null) {
- logger.println("SSLSocketImpl.startHandshake: END");
- }
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getInputStream()
- * method documentation for more information
- */
- @Override
- public InputStream getInputStream() throws IOException {
- if (socket_was_closed) {
- throw new IOException("Socket has already been closed.");
- }
- return appDataIS;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getOutputStream()
- * method documentation for more information
- */
- @Override
- public OutputStream getOutputStream() throws IOException {
- if (socket_was_closed) {
- throw new IOException("Socket has already been closed.");
- }
- return appDataOS;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see java.net.Socket#connect(SocketAddress)
- * method documentation for more information
- */
- @Override
- public void connect(SocketAddress endpoint) throws IOException {
- super.connect(endpoint);
- init();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see java.net.Socket#connect(SocketAddress,int)
- * method documentation for more information
- */
- @Override
- public void connect(SocketAddress endpoint, int timeout)
- throws IOException {
- super.connect(endpoint, timeout);
- init();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#close()
- * method documentation for more information
- */
- @Override
- public void close() throws IOException {
- if (logger != null) {
- logger.println("SSLSocket.close "+socket_was_closed);
- }
- if (!socket_was_closed) {
- if (handshake_started) {
- alertProtocol.alert(AlertProtocol.WARNING,
- AlertProtocol.CLOSE_NOTIFY);
- try {
- output.write(alertProtocol.wrap());
- } catch (IOException ex) { }
- alertProtocol.setProcessed();
- }
- shutdown();
- closeTransportLayer();
- socket_was_closed = true;
- }
- }
-
- /**
- * This method is not supported for SSLSocket implementation.
- */
- @Override
- public void sendUrgentData(int data) throws IOException {
- throw new SocketException(
- "Method sendUrgentData() is not supported.");
- }
-
- /**
- * This method is not supported for SSLSocket implementation.
- */
- @Override
- public void setOOBInline(boolean on) throws SocketException {
- throw new SocketException(
- "Methods sendUrgentData, setOOBInline are not supported.");
- }
-
- // -----------------------------------------------------------------
-
- private void shutdown() {
- if (handshake_started) {
- alertProtocol.shutdown();
- alertProtocol = null;
- handshakeProtocol.shutdown();
- handshakeProtocol = null;
- recordProtocol.shutdown();
- recordProtocol = null;
- }
- socket_was_closed = true;
- }
-
- /**
- * This method is called by SSLSocketInputStream class
- * when client application tries to read application data from
- * the stream, but there is no data in its underlying buffer.
- * @throws IOException
- */
- protected void needAppData() throws IOException {
- if (!handshake_started) {
- startHandshake();
- }
- int type;
- if (logger != null) {
- logger.println("SSLSocket.needAppData..");
- }
- try {
- while(appDataIS.available() == 0) {
- // read and unwrap the record contained in the transport
- // input stream (SSLStreamedInput), pass it
- // to appropriate client protocol (alert, handshake, or app)
- // and retrieve the type of unwrapped data
- switch (type = recordProtocol.unwrap()) {
- case ContentType.HANDSHAKE:
- if (!handshakeProtocol.getStatus().equals(
- SSLEngineResult.HandshakeStatus
- .NOT_HANDSHAKING)) {
- // handshake protocol got addressed to it message
- // and did not ignore it, so it's a rehandshake
- doHandshake();
- }
- break;
- case ContentType.ALERT:
- processAlert();
- if (socket_was_closed) {
- return;
- }
- break;
- case ContentType.APPLICATION_DATA:
- if (logger != null) {
- logger.println(
- "SSLSocket.needAppData: got the data");
- }
- break;
- default:
- // will throw exception
- reportFatalAlert(AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLException("Unexpected message of type "
- + type + " has been got"));
- }
- if (alertProtocol.hasAlert()) {
- // warning alert occurred during wrap or unwrap
- // (note: fatal alert causes AlertException
- // to be thrown)
- output.write(alertProtocol.wrap());
- alertProtocol.setProcessed();
- }
- if (socket_was_closed) {
- appDataIS.setEnd();
- return;
- }
- }
- } catch (AlertException e) {
- // will throw exception
- reportFatalAlert(e.getDescriptionCode(), e.getReason());
- } catch (EndOfSourceException e) {
- // end of socket's input stream has been reached
- appDataIS.setEnd();
- }
- if (logger != null) {
- logger.println("SSLSocket.needAppData: app data len: "
- + appDataIS.available());
- }
- }
-
- /**
- * This method is called by SSLSocketOutputStream when a client application
- * tries to send the data over ssl protocol.
- */
- protected void writeAppData(byte[] data, int offset, int len) throws IOException {
- if (!handshake_started) {
- startHandshake();
- }
- if (logger != null) {
- logger.println("SSLSocket.writeAppData: " +
- len + " " + SSLRecordProtocol.MAX_DATA_LENGTH);
- //logger.println(new String(data, offset, len));
- }
- try {
- if (len < SSLRecordProtocol.MAX_DATA_LENGTH) {
- output.write(recordProtocol.wrap(ContentType.APPLICATION_DATA,
- data, offset, len));
- } else {
- while (len >= SSLRecordProtocol.MAX_DATA_LENGTH) {
- output.write(recordProtocol.wrap(
- ContentType.APPLICATION_DATA, data, offset,
- SSLRecordProtocol.MAX_DATA_LENGTH));
- offset += SSLRecordProtocol.MAX_DATA_LENGTH;
- len -= SSLRecordProtocol.MAX_DATA_LENGTH;
- }
- if (len > 0) {
- output.write(
- recordProtocol.wrap(ContentType.APPLICATION_DATA,
- data, offset, len));
- }
- }
- } catch (AlertException e) {
- // will throw exception
- reportFatalAlert(e.getDescriptionCode(), e.getReason());
- }
- }
-
- /*
- * Performs handshake process over this connection. The handshake
- * process is directed by the handshake status code provided by
- * handshake protocol. If this status is NEED_WRAP, method retrieves
- * handshake message from handshake protocol and sends it to another peer.
- * If this status is NEED_UNWRAP, method receives and processes handshake
- * message from another peer. Each of this stages (wrap/unwrap) change
- * the state of handshake protocol and this process is performed
- * until handshake status is FINISHED. After handshake process is finished
- * handshake completed event are sent to the registered listeners.
- * For more information about the handshake process see
- * TLS v1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 7.3.
- */
- private void doHandshake() throws IOException {
- SSLEngineResult.HandshakeStatus status;
- int type;
- try {
- while (!(status = handshakeProtocol.getStatus()).equals(
- SSLEngineResult.HandshakeStatus.FINISHED)) {
- if (logger != null) {
- String s = (status.equals(
- SSLEngineResult.HandshakeStatus.NEED_WRAP))
- ? "NEED_WRAP"
- : (status.equals(
- SSLEngineResult.HandshakeStatus.NEED_UNWRAP))
- ? "NEED_UNWRAP"
- : "STATUS: OTHER!";
- logger.println("SSLSocketImpl: HS status: "+s+" "+status);
- }
- if (status.equals(SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
- output.write(handshakeProtocol.wrap());
- } else if (status.equals(
- SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) {
- // read and unwrap the record contained in the transport
- // input stream (SSLStreamedInput), pass it
- // to appropriate client protocol (alert, handshake, or app)
- // and retrieve the type of unwrapped data
- switch (type = recordProtocol.unwrap()) {
- case ContentType.HANDSHAKE:
- case ContentType.CHANGE_CIPHER_SPEC:
- break;
- case ContentType.APPLICATION_DATA:
- // So it's rehandshake and
- // if app data buffer will be overloaded
- // it will throw alert exception.
- // Probably we should count the number of
- // not handshaking data and make additional
- // constraints (do not expect buffer overflow).
- break;
- case ContentType.ALERT:
- processAlert();
- if (socket_was_closed) {
- return;
- }
- break;
- default:
- // will throw exception
- reportFatalAlert(AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLException(
- "Unexpected message of type "
- + type + " has been got"));
- }
- } else {
- // will throw exception
- reportFatalAlert(AlertProtocol.INTERNAL_ERROR,
- new SSLException(
- "Handshake passed unexpected status: "+status));
- }
- if (alertProtocol.hasAlert()) {
- // warning alert occurred during wrap or unwrap
- // (note: fatal alert causes AlertException
- // to be thrown)
- output.write(alertProtocol.wrap());
- alertProtocol.setProcessed();
- }
- }
- } catch (EndOfSourceException e) {
- appDataIS.setEnd();
- throw new IOException("Connection was closed");
- } catch (AlertException e) {
- // will throw exception
- reportFatalAlert(e.getDescriptionCode(), e.getReason());
- }
-
- session = recordProtocol.getSession();
- if (listeners != null) {
- // notify the listeners
- HandshakeCompletedEvent event =
- new HandshakeCompletedEvent(this, session);
- int size = listeners.size();
- for (int i=0; i<size; i++) {
- listeners.get(i)
- .handshakeCompleted(event);
- }
- }
- }
-
- /*
- * Process received alert message
- */
- private void processAlert() throws IOException {
- if (!alertProtocol.hasAlert()) {
- return;
- }
- if (alertProtocol.isFatalAlert()) {
- alertProtocol.setProcessed();
- String description = "Fatal alert received "
- + alertProtocol.getAlertDescription();
- shutdown();
- throw new SSLException(description);
- }
-
- if (logger != null) {
- logger.println("Warning alert received: "
- + alertProtocol.getAlertDescription());
- }
- switch(alertProtocol.getDescriptionCode()) {
- case AlertProtocol.CLOSE_NOTIFY:
- alertProtocol.setProcessed();
- appDataIS.setEnd();
- close();
- return;
- default:
- alertProtocol.setProcessed();
- // TODO: process other warning messages
- }
- }
-
- /*
- * Sends fatal alert message and throws exception
- */
- private void reportFatalAlert(byte description_code,
- SSLException reason) throws IOException {
- alertProtocol.alert(AlertProtocol.FATAL, description_code);
- try {
- // the output stream can be closed
- output.write(alertProtocol.wrap());
- } catch (IOException ex) { }
- alertProtocol.setProcessed();
- shutdown();
- throw reason;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketInputStream.java b/crypto/src/main/java/org/conscrypt/SSLSocketInputStream.java
deleted file mode 100644
index 36c5c03..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketInputStream.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-import javax.net.ssl.SSLException;
-
-/**
- * This class provides input data stream functionality
- * for SSLSocket. It accumulates the application data
- * received by SSL protocol.
- */
-public final class SSLSocketInputStream extends InputStream {
-
- // The size of the internal data buffer.
- // It should not be less than maximum data chunk enclosed
- // in one ssl packet.
- private static final int BUFFER_SIZE = SSLRecordProtocol.MAX_DATA_LENGTH;
-
- // Internal buffer accumulating the received application data
- private byte[] buffer = new byte[BUFFER_SIZE];
-
- // position of the next byte to read from the buffer
- private int pos;
-
- // position of the last byte to read + 1
- private int end;
-
- // the ssl socket owning the stream
- private final SSLSocketImpl owner;
-
- // the flag indicating that the end of the (owner's) input stream
- // has been reached
- private boolean end_reached = false;
-
- /**
- * Creates the application data input stream for specified socket.
- * @param owner the socket which will provide this input stream
- * to client applications.
- */
- protected SSLSocketInputStream(SSLSocketImpl owner) {
- this.owner = owner;
- }
-
- // The helper delivering the application data from the record layer
- protected Adapter dataPoint = new Adapter();
-
- /**
- * Tells to the stream that the end of the income data has
- * been reached.
- */
- protected void setEnd() {
- end_reached = true;
- }
-
- // ------------------ InputStream implementation -------------------
-
- /**
- * Returns the number of bytes available for reading without blocking.
- * @return the number of available bytes.
- * @throws IOException
- */
- @Override
- public int available() throws IOException {
- return end - pos;
- }
-
- /**
- * Closes the stream
- * @throws IOException
- */
- @Override
- public void close() throws IOException {
- buffer = null;
- }
-
- /**
- * Reads one byte. If there is no data in the underlying buffer,
- * this operation can block until the data will be
- * available.
- * @return read value.
- * @throws IOException
- */
- @Override
- public int read() throws IOException {
- if (buffer == null) {
- throw new IOException("Stream was closed.");
- }
- while (pos == end) {
- if (end_reached) {
- return -1;
- }
- // If there is no data in the buffer
- // - will block until the data will be provided by
- // record layer
- owner.needAppData();
- }
- return buffer[pos++] & 0xFF;
- }
-
- @Override public int read(byte[] b, int off, int len) throws IOException {
- int read_b;
- int i = 0;
- do {
- if ((read_b = read()) == -1) {
- return (i == 0) ? -1 : i;
- }
- b[off+i] = (byte) read_b;
- i++;
- } while ((available() != 0) && (i<len));
- return i;
- }
-
- // The helper class delivering the application data from the record layer
- // to this input stream.
- // It 'adapts' the InputStream interface to Appendable, which is used for
- // transmission of income data from the record protocol to its clients.
- private class Adapter implements org.conscrypt.Appendable {
- /**
- * Appends the data to the stream.
- * This method could be implemented in the outer class
- * itself, but it could be insecure.
- */
- public void append(byte[] src) {
- int length = src.length;
- if (BUFFER_SIZE - (end - pos) < length) {
- // If the size of the buffer is greater than or equals to
- // SSLRecordProtocol.MAX_DATA_LENGTH this situation will
- // happen iff:
- // 1. the length of received data fragment is greater
- // than allowed by the spec
- // 2. it is rehandshaking stage and we have got several
- // extra app data messages.
- // In any case it is better to throw alert exception.
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLException("Could not accept income app data."));
- }
- if (end + length > BUFFER_SIZE) {
- // move the content of the buffer to the beginning
- System.arraycopy(buffer, pos, buffer, 0, end-pos);
- end -= pos;
- pos = 0;
- }
- System.arraycopy(src, 0, buffer, end, length);
- end = end + length;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketOutputStream.java b/crypto/src/main/java/org/conscrypt/SSLSocketOutputStream.java
deleted file mode 100644
index e3afed7..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketOutputStream.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import libcore.io.Streams;
-
-/**
- * This is a application data output stream used in SSLSocket
- * implementation.
- * The written bytes are encrypted, packed into the records,
- * and then sent to the peer host.
- */
-public class SSLSocketOutputStream extends OutputStream {
- private final SSLSocketImpl owner;
-
- protected SSLSocketOutputStream(SSLSocketImpl owner) {
- this.owner = owner;
- }
-
- @Override public void write(int b) throws IOException {
- Streams.writeSingleByte(this, b);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- owner.writeAppData(b, off, len);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketWrapper.java b/crypto/src/main/java/org/conscrypt/SSLSocketWrapper.java
deleted file mode 100644
index 2110aea..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketWrapper.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-
-/**
- * This class wraps the SSL fuctionality over existing conneted socket.
- */
-public class SSLSocketWrapper extends SSLSocketImpl {
-
- private final Socket socket;
- private final boolean autoClose;
-
- protected SSLSocketWrapper(Socket socket, String host, int port, boolean autoClose,
- SSLParametersImpl sslParameters) throws IOException {
- super(host, port, sslParameters);
- if (!socket.isConnected()) {
- throw new SocketException("Socket is not connected.");
- }
- this.socket = socket;
- this.autoClose = autoClose;
- init();
- }
-
- @Override
- protected void initTransportLayer() throws IOException {
- input = socket.getInputStream();
- output = socket.getOutputStream();
- }
-
- @Override
- protected void closeTransportLayer() throws IOException {
- if (autoClose && (input != null)) {
- socket.close();
- input.close();
- output.close();
- }
- }
-
- // ------------------- Wrapping method implementations ---------------
-
- @Override
- public void connect(SocketAddress sockaddr, int timeout)
- throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public void connect(SocketAddress sockaddr) throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public void bind(SocketAddress sockaddr) throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public SocketAddress getRemoteSocketAddress() {
- return socket.getRemoteSocketAddress();
- }
-
- @Override
- public SocketAddress getLocalSocketAddress() {
- return socket.getLocalSocketAddress();
- }
-
- @Override
- public InetAddress getLocalAddress() {
- return socket.getLocalAddress();
- }
-
- @Override
- public InetAddress getInetAddress() {
- return socket.getInetAddress();
- }
-
- @Override
- public String toString() {
- return "SSL socket over " + socket.toString();
- }
-
- @Override
- public void setSoLinger(boolean on, int linger) throws SocketException {
- socket.setSoLinger(on, linger);
- }
-
- @Override
- public void setTcpNoDelay(boolean on) throws SocketException {
- socket.setTcpNoDelay(on);
- }
-
- @Override
- public void setReuseAddress(boolean on) throws SocketException {
- socket.setReuseAddress(on);
- }
-
- @Override
- public void setKeepAlive(boolean on) throws SocketException {
- socket.setKeepAlive(on);
- }
-
- @Override
- public void setTrafficClass(int tos) throws SocketException {
- socket.setTrafficClass(tos);
- }
-
- @Override
- public void setSoTimeout(int to) throws SocketException {
- socket.setSoTimeout(to);
- }
-
- @Override
- public void setSendBufferSize(int size) throws SocketException {
- socket.setSendBufferSize(size);
- }
-
- @Override
- public void setReceiveBufferSize(int size) throws SocketException {
- socket.setReceiveBufferSize(size);
- }
-
- @Override
- public boolean getTcpNoDelay() throws SocketException {
- return socket.getTcpNoDelay();
- }
-
- @Override
- public boolean getReuseAddress() throws SocketException {
- return socket.getReuseAddress();
- }
-
- @Override
- public boolean getOOBInline() throws SocketException {
- return socket.getOOBInline();
- }
-
- @Override
- public boolean getKeepAlive() throws SocketException {
- return socket.getKeepAlive();
- }
-
- @Override
- public int getTrafficClass() throws SocketException {
- return socket.getTrafficClass();
- }
-
- @Override
- public int getSoTimeout() throws SocketException {
- return socket.getSoTimeout();
- }
-
- @Override
- public int getSoLinger() throws SocketException {
- return socket.getSoLinger();
- }
-
- @Override
- public int getSendBufferSize() throws SocketException {
- return socket.getSendBufferSize();
- }
-
- @Override
- public int getReceiveBufferSize() throws SocketException {
- return socket.getReceiveBufferSize();
- }
-
- @Override
- public boolean isConnected() {
- return socket.isConnected();
- }
-
- @Override
- public boolean isClosed() {
- return socket.isClosed();
- }
-
- @Override
- public boolean isBound() {
- return socket.isBound();
- }
-
- @Override
- public boolean isOutputShutdown() {
- return socket.isOutputShutdown();
- }
-
- @Override
- public boolean isInputShutdown() {
- return socket.isInputShutdown();
- }
-
- @Override
- public int getPort() {
- return socket.getPort();
- }
-
- @Override
- public int getLocalPort() {
- return socket.getLocalPort();
- }
-
- @Override
- public FileDescriptor getFileDescriptor$() {
- return socket.getFileDescriptor$();
- }
-
- // -------------------------------------------------------------------
-
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/SSLStreamedInput.java b/crypto/src/main/java/org/conscrypt/SSLStreamedInput.java
deleted file mode 100644
index 4c8a885..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLStreamedInput.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class acts like a filtered input stream: it takes
- * the bytes from another InputStream.
- */
-public class SSLStreamedInput extends SSLInputStream {
-
- private InputStream in;
-
- public SSLStreamedInput(InputStream in) {
- this.in = in;
- }
-
- @Override
- public int available() throws IOException {
- return in.available();
- }
-
- /**
- * Read an opaque value from the stream.
- * @return the value read from the underlying stream.
- * @throws IOException if the data could not be read from
- * the underlying stream
- * @throws org.conscrypt.EndOfSourceException if the end of the underlying
- * stream has been reached.
- */
- @Override
- public int read() throws IOException {
- int res = in.read();
- if (res < 0) {
- throw new EndOfSourceException();
- }
- return res;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/SSLv3Constants.java b/crypto/src/main/java/org/conscrypt/SSLv3Constants.java
deleted file mode 100644
index ea6482f..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLv3Constants.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- *
- * Contains SSL 3.0 constants
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec.</a>
- */
-public class SSLv3Constants {
-
- /**
- * Client is a sender. Used in hash calculating for finished message.
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.6.9
- * Finished</a>
- */
- static final byte[] client = new byte[] { 0x43, 0x4C, 0x4E, 0x54 };
-
- /**
- * Server is a sender. Used in hash calculating for finished message.
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.6.9
- * Finished</a>
- */
- static final byte[] server = new byte[] { 0x53, 0x52, 0x56, 0x52 };
-
- /**
- * pad_1 for MD5
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.2.3.1
- * Null or standard stream cipher</a>
- */
- static final byte[] MD5pad1 = new byte[] { 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 };
-
- /**
- * pad_1 for SHA
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.2.3.1
- * Null or standard stream cipher</a>
- */
- static final byte[] SHApad1 = new byte[] { 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36 };
-
- /**
- * pad_2 for MD5
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.2.3.1
- * Null or standard stream cipher</a>
- */
- static final byte[] MD5pad2 = new byte[] { 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C };
-
- /**
- * pad_2 for SHA
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.2.3.1
- * Null or standard stream cipher</a>
- */
- static final byte[] SHApad2 = new byte[] { 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C };
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerHandshakeImpl.java b/crypto/src/main/java/org/conscrypt/ServerHandshakeImpl.java
deleted file mode 100644
index 2e55c0d..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerHandshakeImpl.java
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PrivilegedExceptionAction;
-import java.security.PublicKey;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPublicKey;
-import java.util.Arrays;
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.DHPublicKeySpec;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * Server side handshake protocol implementation.
- * Handshake protocol operates on top of the Record Protocol.
- * It responsible for negotiating a session.
- *
- * The implementation processes inbound client handshake messages,
- * creates and sends respond messages. Outbound messages are supplied
- * to Record Protocol. Detected errors are reported to the Alert protocol.
- *
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.
- * Handshake protocol.</a>
- *
- */
-public class ServerHandshakeImpl extends HandshakeProtocol {
-
- // private key used in key exchange
- private PrivateKey privKey;
-
- /**
- * Creates Server Handshake Implementation
- *
- * @param owner
- */
- public ServerHandshakeImpl(Object owner) {
- super(owner);
- status = NEED_UNWRAP;
- }
-
- /**
- * Start session negotiation
- */
- @Override
- public void start() {
- if (session == null) { // initial handshake
- status = NEED_UNWRAP;
- return; // wait client hello
- }
- if (clientHello != null && this.status != FINISHED) {
- // current negotiation has not completed
- return; // ignore
- }
-
- // renegotiation
- sendHelloRequest();
- status = NEED_UNWRAP;
- }
-
- /**
- * Proceses inbound handshake messages
- * @param bytes
- */
- @Override
- public void unwrap(byte[] bytes) {
-
- io_stream.append(bytes);
- while (io_stream.available() > 0) {
- int handshakeType;
- int length;
- io_stream.mark();
- try {
- handshakeType = io_stream.read();
- length = io_stream.readUint24();
- if (io_stream.available() < length) {
- io_stream.reset();
- return;
- }
-
- switch (handshakeType) {
- case 1: // CLIENT_HELLO
- if (clientHello != null && this.status != FINISHED) {
- // Client hello has been received during handshake
- unexpectedMessage();
- return;
- }
- // if protocol planed to send Hello Request message
- // - cancel this demand.
- needSendHelloRequest = false;
- clientHello = new ClientHello(io_stream, length);
- if (nonBlocking) {
- delegatedTasks.add(new DelegatedTask(new Runnable() {
- public void run() {
- processClientHello();
- }
- }, this));
- return;
- }
- processClientHello();
- break;
-
- case 11: // CLIENT CERTIFICATE
- if (isResuming || certificateRequest == null
- || serverHelloDone == null || clientCert != null) {
- unexpectedMessage();
- return;
- }
- clientCert = new CertificateMessage(io_stream, length);
- if (clientCert.certs.length == 0) {
- if (parameters.getNeedClientAuth()) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "HANDSHAKE FAILURE: no client certificate received");
- }
- } else {
- String authType = clientCert.getAuthType();
- try {
- parameters.getTrustManager().checkClientTrusted(
- clientCert.certs, authType);
- } catch (CertificateException e) {
- fatalAlert(AlertProtocol.BAD_CERTIFICATE,
- "Untrusted Client Certificate ", e);
- }
- session.peerCertificates = clientCert.certs;
- }
- break;
-
- case 15: // CERTIFICATE_VERIFY
- if (isResuming
- || clientKeyExchange == null
- || clientCert == null
- || clientKeyExchange.isEmpty() //client certificate
- // contains fixed DH
- // parameters
- || certificateVerify != null
- || changeCipherSpecReceived) {
- unexpectedMessage();
- return;
- }
- certificateVerify = new CertificateVerify(io_stream, length);
-
- String authType = clientCert.getAuthType();
- DigitalSignature ds = new DigitalSignature(authType);
- ds.init(clientCert.certs[0]);
- byte[] md5_hash = null;
- byte[] sha_hash = null;
-
- if ("RSA".equals(authType)) {
- md5_hash = io_stream.getDigestMD5withoutLast();
- sha_hash = io_stream.getDigestSHAwithoutLast();
- } else if ("DSA".equals(authType)) {
- sha_hash = io_stream.getDigestSHAwithoutLast();
- // The Signature should be empty in case of anonymous signature algorithm:
- // } else if ("DH".equals(authType)) {
- }
- ds.setMD5(md5_hash);
- ds.setSHA(sha_hash);
- if (!ds.verifySignature(certificateVerify.signedHash)) {
- fatalAlert(AlertProtocol.DECRYPT_ERROR,
- "DECRYPT ERROR: CERTIFICATE_VERIFY incorrect signature");
- }
- break;
- case 16: // CLIENT_KEY_EXCHANGE
- if (isResuming
- || serverHelloDone == null
- || clientKeyExchange != null
- || (clientCert == null && parameters.getNeedClientAuth())) {
- unexpectedMessage();
- return;
- }
- if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- clientKeyExchange = new ClientKeyExchange(io_stream,
- length, serverHello.server_version[1] == 1,
- true);
- Cipher c = null;
- try {
- c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- c.init(Cipher.UNWRAP_MODE, privKey);
- preMasterSecret = c.unwrap(clientKeyExchange.exchange_keys,
- "preMasterSecret",
- Cipher.SECRET_KEY).getEncoded();
- // check preMasterSecret:
- if (preMasterSecret.length != 48
- || preMasterSecret[0] != clientHello.client_version[0]
- || preMasterSecret[1] != clientHello.client_version[1]) {
- // incorrect preMasterSecret
- // prevent an attack (see TLS 1.0 spec., 7.4.7.1.)
- preMasterSecret = new byte[48];
- parameters.getSecureRandom().nextBytes(
- preMasterSecret);
- }
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "INTERNAL ERROR", e);
- }
- } else { // diffie hellman key exchange
- clientKeyExchange = new ClientKeyExchange(io_stream,
- length, serverHello.server_version[1] == 1,
- false);
- if (clientKeyExchange.isEmpty()) {
- // TODO check that client cert. DH params
- // matched server cert. DH params
-
- // client cert. contains fixed DH parameters
- preMasterSecret = ((DHPublicKey) clientCert.certs[0].getPublicKey()).getY().toByteArray();
- } else {
- try {
- KeyFactory kf = KeyFactory.getInstance("DH");
- KeyAgreement agreement = KeyAgreement.getInstance("DH");
- PublicKey clientPublic = kf.generatePublic(new DHPublicKeySpec(
- new BigInteger(
- 1,
- clientKeyExchange.exchange_keys),
- serverKeyExchange.par1,
- serverKeyExchange.par2));
- agreement.init(privKey);
- agreement.doPhase(clientPublic, true);
- preMasterSecret = agreement.generateSecret();
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "INTERNAL ERROR", e);
- return;
- }
- }
- }
-
- computerMasterSecret();
- break;
-
- case 20: // FINISHED
- if (!isResuming && !changeCipherSpecReceived) {
- unexpectedMessage();
- return;
- }
-
- clientFinished = new Finished(io_stream, length);
- verifyFinished(clientFinished.getData());
- session.context = parameters.getServerSessionContext();
- parameters.getServerSessionContext().putSession(session);
- if (!isResuming) {
- sendChangeCipherSpec();
- } else {
- session.lastAccessedTime = System.currentTimeMillis();
- status = FINISHED;
- }
- break;
- default:
- unexpectedMessage();
- return;
- }
- } catch (IOException e) {
- // io stream dosn't contain complete handshake message
- io_stream.reset();
- return;
- }
- }
- }
- /**
- * Processes SSLv2 Hello message
- * @ see TLS 1.0 spec., E.1. Version 2 client hello
- * @param bytes
- */
- @Override
- public void unwrapSSLv2(byte[] bytes) {
- io_stream.append(bytes);
- io_stream.mark();
- try {
- clientHello = new ClientHello(io_stream);
- } catch (IOException e) {
- io_stream.reset();
- return;
- }
- if (nonBlocking) {
- delegatedTasks.add(new DelegatedTask(new Runnable() {
- public void run() {
- processClientHello();
- }
- }, this));
- return;
- }
- processClientHello();
- }
-
- /**
- *
- * Processes Client Hello message.
- * Server responds to client hello message with server hello
- * and (if necessary) server certificate, server key exchange,
- * certificate request, and server hello done messages.
- */
- void processClientHello() {
- CipherSuite cipher_suite;
-
- // check that clientHello contains CompressionMethod.null
- checkCompression: {
- for (int i = 0; i < clientHello.compression_methods.length; i++) {
- if (clientHello.compression_methods[i] == 0) {
- break checkCompression;
- }
- }
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "HANDSHAKE FAILURE. Incorrect client hello message");
- }
-
- byte[] server_version = clientHello.client_version;
- if (!ProtocolVersion.isSupported(clientHello.client_version)) {
- if (clientHello.client_version[0] >= 3) {
- // Protocol from the future, admit that the newest thing we know is TLSv1
- server_version = ProtocolVersion.TLSv1.version;
- } else {
- fatalAlert(AlertProtocol.PROTOCOL_VERSION,
- "PROTOCOL VERSION. Unsupported client version "
- + clientHello.client_version[0]
- + clientHello.client_version[1]);
- }
- }
-
- isResuming = false;
- FIND: if (clientHello.session_id.length != 0) {
- // client wishes to reuse session
-
- SSLSessionImpl sessionToResume;
- boolean reuseCurrent = false;
-
- // reuse current session
- if (session != null
- && Arrays.equals(session.id, clientHello.session_id)) {
- if (session.isValid()) {
- isResuming = true;
- break FIND;
- }
- reuseCurrent = true;
- }
-
- // find session in cash
- sessionToResume = findSessionToResume(clientHello.session_id);
- if (sessionToResume == null || !sessionToResume.isValid()) {
- if (!parameters.getEnableSessionCreation()) {
- if (reuseCurrent) {
- // we can continue current session
- sendWarningAlert(AlertProtocol.NO_RENEGOTIATION);
- status = NOT_HANDSHAKING;
- clearMessages();
- return;
- }
- // throw AlertException
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "SSL Session may not be created");
- }
- session = null;
- } else {
- session = (SSLSessionImpl)sessionToResume.clone();
- isResuming = true;
- }
- }
-
- if (isResuming) {
- cipher_suite = session.cipherSuite;
- // clientHello.cipher_suites must include at least cipher_suite from the session
- checkCipherSuite: {
- for (int i = 0; i < clientHello.cipher_suites.length; i++) {
- if (cipher_suite.equals(clientHello.cipher_suites[i])) {
- break checkCipherSuite;
- }
- }
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "HANDSHAKE FAILURE. Incorrect client hello message");
- }
- } else {
- cipher_suite = selectSuite(clientHello.cipher_suites);
- if (cipher_suite == null) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "HANDSHAKE FAILURE. NO COMMON SUITE");
- }
- if (!parameters.getEnableSessionCreation()) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "SSL Session may not be created");
- }
- session = new SSLSessionImpl(cipher_suite, parameters.getSecureRandom());
- if (engineOwner != null) {
- session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
- } else {
- session.setPeer(socketOwner.getInetAddress().getHostName(), socketOwner.getPort());
- }
- }
-
- recordProtocol.setVersion(server_version);
- session.protocol = ProtocolVersion.getByVersion(server_version);
- session.clientRandom = clientHello.random;
-
- // create server hello message
- serverHello = new ServerHello(parameters.getSecureRandom(),
- server_version,
- session.getId(), cipher_suite, (byte) 0); //CompressionMethod.null
- session.serverRandom = serverHello.random;
- send(serverHello);
- if (isResuming) {
- sendChangeCipherSpec();
- return;
- }
-
- // create and send server certificate message if needed
- if (!cipher_suite.isAnonymous()) { // need to send server certificate
- X509Certificate[] certs = null;
- String certType = cipher_suite.getServerKeyType();
- if (certType == null) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "NO CERT TYPE FOR " + cipher_suite.getName());
- }
- // obtain certificates from key manager
- String alias = null;
- X509KeyManager km = parameters.getKeyManager();
- if (km instanceof X509ExtendedKeyManager) {
- X509ExtendedKeyManager ekm = (X509ExtendedKeyManager)km;
- if (this.socketOwner != null) {
- alias = ekm.chooseServerAlias(certType, null,
- this.socketOwner);
- } else {
- alias = ekm.chooseEngineServerAlias(certType, null,
- this.engineOwner);
- }
- if (alias != null) {
- certs = ekm.getCertificateChain(alias);
- }
- } else {
- alias = km.chooseServerAlias(certType, null, this.socketOwner);
- if (alias != null) {
- certs = km.getCertificateChain(alias);
- }
- }
-
- if (certs == null) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "NO SERVER CERTIFICATE FOUND");
- return;
- }
- session.localCertificates = certs;
- serverCert = new CertificateMessage(certs);
- privKey = km.getPrivateKey(alias);
- send(serverCert);
- }
-
- // create and send server key exchange message if needed
- RSAPublicKey rsakey = null;
- DHPublicKeySpec dhkeySpec = null;
- byte[] hash = null;
- BigInteger p = null;
- BigInteger g = null;
-
- KeyPairGenerator kpg = null;
-
- try {
- if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- PublicKey pk = serverCert.certs[0].getPublicKey();
- if (getRSAKeyLength(pk) > 512) {
- // key is longer than 512 bits
- kpg = KeyPairGenerator.getInstance("RSA");
- kpg.initialize(512);
- }
- } else if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) {
- kpg = KeyPairGenerator.getInstance("DH");
- p = new BigInteger(1, DHParameters.getPrime());
- g = new BigInteger("2");
- DHParameterSpec spec = new DHParameterSpec(p, g);
- kpg.initialize(spec);
- }
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
- }
-
- if (kpg != null) {
- // need to send server key exchange message
- DigitalSignature ds = new DigitalSignature(cipher_suite.authType);
- KeyPair kp = null;
- try {
- kp = kpg.genKeyPair();
- if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- rsakey = (RSAPublicKey) kp.getPublic();
- } else {
- DHPublicKey dhkey = (DHPublicKey) kp.getPublic();
- KeyFactory kf = KeyFactory.getInstance("DH");
- dhkeySpec = kf.getKeySpec(dhkey, DHPublicKeySpec.class);
- }
- if (!cipher_suite.isAnonymous()) { // calculate signed_params
-
- // init by private key which correspond to
- // server certificate
- ds.init(privKey);
-
- // use emphemeral key for key exchange
- privKey = kp.getPrivate();
- ds.update(clientHello.getRandom());
- ds.update(serverHello.getRandom());
-
-//FIXME 1_byte==0x00
- if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- ServerKeyExchange.updateSignatureRsa(ds, rsakey.getModulus(),
- rsakey.getPublicExponent());
- } else {
- ServerKeyExchange.updateSignatureDh(ds, dhkeySpec.getP(), dhkeySpec.getG(),
- dhkeySpec.getY());
- }
- hash = ds.sign();
- } else {
- privKey = kp.getPrivate(); // use emphemeral key for key exchange
- }
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
- }
-
- if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- serverKeyExchange = new ServerKeyExchange(rsakey.getModulus(),
- rsakey.getPublicExponent(), null, hash);
- } else {
- serverKeyExchange = new ServerKeyExchange(p,
- g, dhkeySpec.getY(), hash);
- }
- send(serverKeyExchange);
- }
-
- // CERTIFICATE_REQUEST
- certRequest: if (parameters.getWantClientAuth()
- || parameters.getNeedClientAuth()) {
- X509Certificate[] accepted;
- try {
- X509TrustManager tm = parameters.getTrustManager();
- accepted = tm.getAcceptedIssuers();
- } catch (ClassCastException e) {
- // don't send certificateRequest
- break certRequest;
- }
- byte[] requestedClientCertTypes = { CipherSuite.TLS_CT_RSA_SIGN,
- CipherSuite.TLS_CT_DSS_SIGN };
- certificateRequest = new CertificateRequest(
- requestedClientCertTypes, accepted);
- send(certificateRequest);
- }
-
- // SERVER_HELLO_DONE
- serverHelloDone = new ServerHelloDone();
- send(serverHelloDone);
- status = NEED_UNWRAP;
- }
-
- /**
- * Creates and sends finished message
- */
- @Override
- protected void makeFinished() {
- byte[] verify_data;
- boolean isTLS = (serverHello.server_version[1] == 1); // TLS 1.0 protocol
- if (isTLS) {
- verify_data = new byte[12];
- computerVerifyDataTLS("server finished", verify_data);
- } else { // SSL 3.0 protocol (http://wp.netscape.com/eng/ssl3)
- verify_data = new byte[36];
- computerVerifyDataSSLv3(SSLv3Constants.server, verify_data);
- }
- serverFinished = new Finished(verify_data);
- send(serverFinished);
- if (isResuming) {
- if (isTLS) {
- computerReferenceVerifyDataTLS("client finished");
- } else {
- computerReferenceVerifyDataSSLv3(SSLv3Constants.client);
- }
- status = NEED_UNWRAP;
- } else {
- session.lastAccessedTime = System.currentTimeMillis();
- status = FINISHED;
- }
- }
-
- // find sesssion in the session hash
- private SSLSessionImpl findSessionToResume(byte[] session_id) {
- return (SSLSessionImpl)parameters.getServerSessionContext().getSession(session_id);
- }
-
- // find appropriate cipher_suite in the client suites
- private CipherSuite selectSuite(CipherSuite[] clientSuites) {
- for (CipherSuite clientSuite : clientSuites) {
- if (!clientSuite.supported) {
- continue;
- }
- for (CipherSuite enabledCipherSuite : parameters.getEnabledCipherSuitesMember()) {
- if (clientSuite.equals(enabledCipherSuite)) {
- return clientSuite;
- }
- }
- }
- return null;
- }
-
- /**
- * Processes inbound ChangeCipherSpec message
- */
- @Override
- public void receiveChangeCipherSpec() {
- if (isResuming) {
- if (serverFinished == null) {
- unexpectedMessage();
- } else {
- changeCipherSpecReceived = true;
- }
- } else {
- if ((parameters.getNeedClientAuth() && clientCert == null)
- || clientKeyExchange == null
- || (clientCert != null && clientCert.certs.length > 0
- && !clientKeyExchange.isEmpty()
- && certificateVerify == null)) {
- unexpectedMessage();
- } else {
- changeCipherSpecReceived = true;
- }
- if (serverHello.server_version[1] == 1) {
- computerReferenceVerifyDataTLS("client finished");
- } else {
- computerReferenceVerifyDataSSLv3(SSLv3Constants.client);
- }
- }
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerHello.java b/crypto/src/main/java/org/conscrypt/ServerHello.java
deleted file mode 100644
index 3cc3b46..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerHello.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.SecureRandom;
-import libcore.io.Streams;
-
-/**
- *
- * Represents server hello message.
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.1.3.
- * Server hello.</a>
- */
-public class ServerHello extends Message {
-
- /**
- * Server version
- */
- byte[] server_version = new byte[2];
-
- /**
- * Random bytes
- */
- byte[] random = new byte[32];
-
- /**
- * Session id
- */
- byte[] session_id;
-
- /**
- * Selected cipher suite
- */
- CipherSuite cipher_suite;
-
- /**
- * Selected compression method
- */
- byte compression_method;
-
- /**
- * Creates outbound message
- * @param sr
- * @param server_version
- * @param session_id
- * @param cipher_suite
- * @param compression_method
- */
- public ServerHello(SecureRandom sr, byte[] server_version,
- byte[] session_id, CipherSuite cipher_suite, byte compression_method) {
- long gmt_unix_time = new java.util.Date().getTime() / 1000;
- sr.nextBytes(random);
- random[0] = (byte) ((gmt_unix_time & 0xFF000000) >>> 24);
- random[1] = (byte) ((gmt_unix_time & 0xFF0000) >>> 16);
- random[2] = (byte) ((gmt_unix_time & 0xFF00) >>> 8);
- random[3] = (byte) (gmt_unix_time & 0xFF);
- this.session_id = session_id;
- this.cipher_suite = cipher_suite;
- this.compression_method = compression_method;
- this.server_version = server_version;
- length = 38 + session_id.length;
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public ServerHello(HandshakeIODataStream in, int length) throws IOException {
-
- server_version[0] = (byte) in.read();
- server_version[1] = (byte) in.read();
- Streams.readFully(in, random);
- int size = in.readUint8();
- session_id = new byte[size];
- in.read(session_id, 0, size);
- byte b0 = (byte) in.read();
- byte b1 = (byte) in.read();
- cipher_suite = CipherSuite.getByCode(b0, b1);
- compression_method = (byte) in.read();
- this.length = 38 + session_id.length;
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ServerHello");
- }
-
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- out.write(server_version);
- out.write(random);
- out.writeUint8(session_id.length);
- out.write(session_id);
- out.write(cipher_suite.toBytes());
- out.write(compression_method);
- length = 38 + session_id.length;
- }
-
- /**
- * Returns server random
- * @return
- */
- public byte[] getRandom() {
- return random;
- }
-
- /**
- * Returns message type
- * @return
- */
- @Override
- public int getType() {
- return Handshake.SERVER_HELLO;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerHelloDone.java b/crypto/src/main/java/org/conscrypt/ServerHelloDone.java
deleted file mode 100644
index 3e40f9a..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerHelloDone.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- *
- * Represents server hello done message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.5.
- * Server hello done</a>
- *
- */
-public class ServerHelloDone extends Message {
-
- /**
- * Creates outbound message
- *
- */
- public ServerHelloDone() {
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public ServerHelloDone(HandshakeIODataStream in, int length)
- throws IOException {
- if (length != 0) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ServerHelloDone");
- }
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- }
-
- /**
- * Returns message length
- * @return
- */
- @Override
- public int length() {
- return 0;
- }
-
- /**
- * Returns message type
- * @return
- */
- @Override
- public int getType() {
- return Handshake.SERVER_HELLO_DONE;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerKeyExchange.java b/crypto/src/main/java/org/conscrypt/ServerKeyExchange.java
deleted file mode 100644
index d949850..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerKeyExchange.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.RSAPublicKeySpec;
-
-/**
- *
- * Represents server key exchange message.
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.3.
- * Server key exchange message.</a>
- *
- */
-public class ServerKeyExchange extends Message {
-
- // ServerRSAParams ServerDHParams
- final BigInteger par1; // rsa_modulus dh_p
- final byte[] bytes1;
-
- final BigInteger par2; // rsa_exponent dh_g
- final byte[] bytes2;
-
- final BigInteger par3; // dh_Ys
- final byte[] bytes3;
-
- /**
- * Signature
- */
- final byte[] hash;
-
- private RSAPublicKey key;
-
- /**
- * Creates outbound message
- * @param par1 rsa_modulus or dh_p
- * @param par2 rsa_exponent or dh_g
- * @param par3 dh_Ys for ServerDHParams; should be null for ServerRSAParams
- * @param hash should be null for anonymous SignatureAlgorithm
- */
- public ServerKeyExchange(BigInteger par1, BigInteger par2, BigInteger par3,
- byte[] hash) {
- this.par1 = par1;
- this.par2 = par2;
- this.par3 = par3;
- this.hash = hash;
-
- bytes1 = toUnsignedByteArray(this.par1);
-
- bytes2 = toUnsignedByteArray(this.par2);
-
- length = 4 + bytes1.length + bytes2.length;
- if (hash != null) {
- length += 2 + hash.length;
- }
- if (par3 == null) {
- bytes3 = null;
- return;
- }
- bytes3 = toUnsignedByteArray(this.par3);
- length += 2 + bytes3.length;
- }
-
- /**
- * Remove first byte if 0. Needed because BigInteger.toByteArray() sometimes
- * returns a zero prefix.
- */
- public static byte[] toUnsignedByteArray(BigInteger bi) {
- if (bi == null) {
- return null;
- }
- byte[] bb = bi.toByteArray();
- // bb is not null, and has at least 1 byte - ZERO is represented as [0]
- if (bb[0] == 0) {
- byte[] noZero = new byte[bb.length - 1];
- System.arraycopy(bb, 1, noZero, 0, noZero.length);
- return noZero;
- } else {
- return bb;
- }
- }
-
- public static void updateSignatureRsa(DigitalSignature ds, BigInteger modulus,
- BigInteger publicExponent) {
- byte[] tmp;
- byte[] tmpLength = new byte[2];
- tmp = ServerKeyExchange.toUnsignedByteArray(modulus);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- tmp = ServerKeyExchange.toUnsignedByteArray(publicExponent);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- }
-
- public static void updateSignatureDh(DigitalSignature ds, BigInteger p, BigInteger g,
- BigInteger y) {
- byte[] tmp;
- byte[] tmpLength = new byte[2];
- tmp = ServerKeyExchange.toUnsignedByteArray(p);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- tmp = ServerKeyExchange.toUnsignedByteArray(g);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- tmp = ServerKeyExchange.toUnsignedByteArray(y);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- }
-
- public boolean verifySignature(DigitalSignature ds) {
- if (par3 != null) {
- updateSignatureDh(ds, par1, par2, par3);
- } else {
- updateSignatureRsa(ds, par1, par2);
- }
- return ds.verifySignature(hash);
- }
-
- /**
- * Will return {@code true} if the signature is {@code null} since this is
- * considered anonymous.
- */
- public boolean isAnonymous() {
- return hash == null;
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @param keyExchange
- * @throws IOException
- */
- public ServerKeyExchange(HandshakeIODataStream in, int length,
- int keyExchange) throws IOException {
-
- int size = in.readUint16();
- bytes1 = in.read(size);
- par1 = new BigInteger(1, bytes1);
- this.length = 2 + bytes1.length;
- size = in.readUint16();
- bytes2 = in.read(size);
- par2 = new BigInteger(1, bytes2);
- this.length += 2 + bytes2.length;
- if (keyExchange != CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- size = in.readUint16();
- bytes3 = in.read(size);
- par3 = new BigInteger(1, bytes3);
- this.length += 2 + bytes3.length;
- } else {
- par3 = null;
- bytes3 = null;
- }
- if (keyExchange != CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT
- && keyExchange != CipherSuite.KEY_EXCHANGE_DH_anon) {
- size = in.readUint16();
- hash = in.read(size);
- this.length += 2 + hash.length;
- } else {
- hash = null;
- }
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect ServerKeyExchange");
- }
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- out.writeUint16(bytes1.length);
- out.write(bytes1);
- out.writeUint16(bytes2.length);
- out.write(bytes2);
- if (bytes3 != null) {
- out.writeUint16(bytes3.length);
- out.write(bytes3);
- }
- if (hash != null) {
- out.writeUint16(hash.length);
- out.write(hash);
- }
- }
-
- /**
- * Returns RSAPublicKey generated using ServerRSAParams
- * (rsa_modulus and rsa_exponent).
- *
- * @return
- */
- public RSAPublicKey getRSAPublicKey() {
- if (key != null) {
- return key;
- }
- try {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- key = (RSAPublicKey) kf.generatePublic(new RSAPublicKeySpec(par1,
- par2));
- } catch (Exception e) {
- return null;
- }
- return key;
- }
-
- /**
- * Returns message type
- * @return
- */
- @Override
- public int getType() {
- return Handshake.SERVER_KEY_EXCHANGE;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerSessionContext.java b/crypto/src/main/java/org/conscrypt/ServerSessionContext.java
deleted file mode 100644
index 8bd8b0f..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerSessionContext.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLSession;
-
-/**
- * Caches server sessions. Indexes by session ID. Users typically look up
- * sessions using the ID provided by an SSL client.
- */
-public class ServerSessionContext extends AbstractSessionContext {
-
- private SSLServerSessionCache persistentCache;
-
- public ServerSessionContext() {
- super(100, 0);
-
- // TODO make sure SSL_CTX does not automaticaly clear sessions we want it to cache
- // SSL_CTX_set_session_cache_mode(sslCtxNativePointer, SSL_SESS_CACHE_NO_AUTO_CLEAR);
-
- // TODO remove SSL_CTX session cache limit so we can manage it
- // SSL_CTX_sess_set_cache_size(sslCtxNativePointer, 0);
-
- // TODO override trimToSize and removeEldestEntry to use
- // SSL_CTX_sessions to remove from native cache
-
- // Set a trivial session id context. OpenSSL uses this to make
- // sure you don't reuse sessions externalized with i2d_SSL_SESSION
- // between apps. However our sessions are either in memory or
- // exported to a app's SSLServerSessionCache.
- NativeCrypto.SSL_CTX_set_session_id_context(sslCtxNativePointer, new byte[] { ' ' });
- }
-
- public void setPersistentCache(SSLServerSessionCache persistentCache) {
- this.persistentCache = persistentCache;
- }
-
- protected void sessionRemoved(SSLSession session) {}
-
- @Override
- public SSLSession getSession(byte[] sessionId) {
- SSLSession session = super.getSession(sessionId);
- if (session != null) {
- return session;
- }
-
- // Check persistent cache.
- if (persistentCache != null) {
- byte[] data = persistentCache.getSessionData(sessionId);
- if (data != null) {
- session = toSession(data, null, -1);
- if (session != null && session.isValid()) {
- super.putSession(session);
- return session;
- }
- }
- }
-
- return null;
- }
-
- @Override
- void putSession(SSLSession session) {
- super.putSession(session);
-
- // TODO: In background thread.
- if (persistentCache != null) {
- byte[] data = toBytes(session);
- if (data != null) {
- persistentCache.putSessionData(session, data);
- }
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustManagerFactoryImpl.java b/crypto/src/main/java/org/conscrypt/TrustManagerFactoryImpl.java
deleted file mode 100644
index 150d018..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustManagerFactoryImpl.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import javax.net.ssl.ManagerFactoryParameters;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactorySpi;
-
-/**
- *
- * TrustManagerFactory service provider interface implementation.
- *
- * @see javax.net.ssl.TrustManagerFactorySpi
- */
-public class TrustManagerFactoryImpl extends TrustManagerFactorySpi {
-
- private KeyStore keyStore;
-
- /**
- * @see javax.net.ssl.TrustManagerFactorySpi#engineInit(KeyStore)
- */
- @Override
- public void engineInit(KeyStore ks) throws KeyStoreException {
- if (ks != null) {
- keyStore = ks;
- } else {
- keyStore = KeyStore.getInstance("AndroidCAStore");
- try {
- keyStore.load(null, null);
- } catch (IOException e) {
- throw new KeyStoreException(e);
- } catch (CertificateException e) {
- throw new KeyStoreException(e);
- } catch (NoSuchAlgorithmException e) {
- throw new KeyStoreException(e);
- }
- }
- }
-
- /**
- * @see javax.net.ssl#engineInit(ManagerFactoryParameters)
- */
- @Override
- public void engineInit(ManagerFactoryParameters spec)
- throws InvalidAlgorithmParameterException {
- throw new InvalidAlgorithmParameterException(
- "ManagerFactoryParameters not supported");
- }
-
- /**
- * @see javax.net.ssl#engineGetTrustManagers()
- */
- @Override
- public TrustManager[] engineGetTrustManagers() {
- if (keyStore == null) {
- throw new IllegalStateException(
- "TrustManagerFactory is not initialized");
- }
- return new TrustManager[] { new TrustManagerImpl(keyStore) };
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustManagerImpl.java b/crypto/src/main/java/org/conscrypt/TrustManagerImpl.java
deleted file mode 100644
index ef366d2..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustManagerImpl.java
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.cert.CertPath;
-import java.security.cert.CertPathValidator;
-import java.security.cert.CertPathValidatorException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.PKIXCertPathChecker;
-import java.security.cert.PKIXParameters;
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.net.ssl.X509TrustManager;
-import libcore.io.EventLogger;
-
-/**
- *
- * TrustManager implementation. The implementation is based on CertPathValidator
- * PKIX and CertificateFactory X509 implementations. This implementations should
- * be provided by some certification provider.
- *
- * @see javax.net.ssl.X509TrustManager
- */
-public final class TrustManagerImpl implements X509TrustManager {
-
- /**
- * The AndroidCAStore if non-null, null otherwise.
- */
- private final KeyStore rootKeyStore;
-
- /**
- * The CertPinManager, which validates the chain against a host-to-pin mapping
- */
- private CertPinManager pinManager;
-
- /**
- * The backing store for the AndroidCAStore if non-null. This will
- * be null when the rootKeyStore is null, implying we are not
- * using the AndroidCAStore.
- */
- private final TrustedCertificateStore trustedCertificateStore;
-
- private final CertPathValidator validator;
-
- /**
- * An index of TrustAnchor instances that we've seen. Unlike the
- * TrustedCertificateStore, this may contain intermediate CAs.
- */
- private final TrustedCertificateIndex trustedCertificateIndex;
-
- /**
- * This is lazily initialized in the AndroidCAStore case since it
- * forces us to bring all the CAs into memory. In the
- * non-AndroidCAStore, we initialize this as part of the
- * constructor.
- */
- private final X509Certificate[] acceptedIssuers;
-
- private final Exception err;
- private final CertificateFactory factory;
-
- /**
- * Creates X509TrustManager based on a keystore
- *
- * @param ks
- */
- public TrustManagerImpl(KeyStore keyStore) {
- this(keyStore, null);
- }
-
- /**
- * For testing only
- */
- public TrustManagerImpl(KeyStore keyStore, CertPinManager manager) {
- CertPathValidator validatorLocal = null;
- CertificateFactory factoryLocal = null;
- KeyStore rootKeyStoreLocal = null;
- TrustedCertificateStore trustedCertificateStoreLocal = null;
- TrustedCertificateIndex trustedCertificateIndexLocal = null;
- X509Certificate[] acceptedIssuersLocal = null;
- Exception errLocal = null;
- try {
- validatorLocal = CertPathValidator.getInstance("PKIX");
- factoryLocal = CertificateFactory.getInstance("X509");
-
- // if we have an AndroidCAStore, we will lazily load CAs
- if ("AndroidCAStore".equals(keyStore.getType())) {
- rootKeyStoreLocal = keyStore;
- trustedCertificateStoreLocal = new TrustedCertificateStore();
- acceptedIssuersLocal = null;
- trustedCertificateIndexLocal = new TrustedCertificateIndex();
- } else {
- rootKeyStoreLocal = null;
- trustedCertificateStoreLocal = null;
- acceptedIssuersLocal = acceptedIssuers(keyStore);
- trustedCertificateIndexLocal
- = new TrustedCertificateIndex(trustAnchors(acceptedIssuersLocal));
- }
-
- } catch (Exception e) {
- errLocal = e;
- }
-
- if (manager != null) {
- this.pinManager = manager;
- } else {
- try {
- pinManager = new CertPinManager(trustedCertificateStoreLocal);
- } catch (PinManagerException e) {
- throw new SecurityException("Could not initialize CertPinManager", e);
- }
- }
-
- this.rootKeyStore = rootKeyStoreLocal;
- this.trustedCertificateStore = trustedCertificateStoreLocal;
- this.validator = validatorLocal;
- this.factory = factoryLocal;
- this.trustedCertificateIndex = trustedCertificateIndexLocal;
- this.acceptedIssuers = acceptedIssuersLocal;
- this.err = errLocal;
- }
-
- private static X509Certificate[] acceptedIssuers(KeyStore ks) {
- try {
- // Note that unlike the PKIXParameters code to create a Set of
- // TrustAnchors from a KeyStore, this version takes from both
- // TrustedCertificateEntry and PrivateKeyEntry, not just
- // TrustedCertificateEntry, which is why TrustManagerImpl
- // cannot just use an PKIXParameters(KeyStore)
- // constructor.
-
- // TODO remove duplicates if same cert is found in both a
- // PrivateKeyEntry and TrustedCertificateEntry
- List<X509Certificate> trusted = new ArrayList<X509Certificate>();
- for (Enumeration<String> en = ks.aliases(); en.hasMoreElements();) {
- final String alias = en.nextElement();
- final X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
- if (cert != null) {
- trusted.add(cert);
- }
- }
- return trusted.toArray(new X509Certificate[trusted.size()]);
- } catch (KeyStoreException e) {
- return new X509Certificate[0];
- }
- }
-
- private static Set<TrustAnchor> trustAnchors(X509Certificate[] certs) {
- Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>(certs.length);
- for (X509Certificate cert : certs) {
- trustAnchors.add(new TrustAnchor(cert, null));
- }
- return trustAnchors;
- }
-
- @Override public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- checkTrusted(chain, authType, null, true);
- }
-
- @Override public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- checkTrusted(chain, authType, null, false);
- }
-
- /**
- * Validates whether a server is trusted. If hostname is given and non-null it also checks if
- * chain is pinned appropriately for that host. If null, it does not check for pinned certs.
- * The return value is a list of the certificates used for making the trust decision.
- */
- public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
- String host) throws CertificateException {
- return checkTrusted(chain, authType, host, false);
- }
-
- public void handleTrustStorageUpdate() {
- if (acceptedIssuers == null) {
- trustedCertificateIndex.reset();
- } else {
- trustedCertificateIndex.reset(trustAnchors(acceptedIssuers));
- }
- }
-
- private List<X509Certificate> checkTrusted(X509Certificate[] chain, String authType,
- String host, boolean clientAuth)
- throws CertificateException {
- if (chain == null || chain.length == 0 || authType == null || authType.length() == 0) {
- throw new IllegalArgumentException("null or zero-length parameter");
- }
- if (err != null) {
- throw new CertificateException(err);
- }
-
- // get the cleaned up chain and trust anchor
- Set<TrustAnchor> trustAnchor = new HashSet<TrustAnchor>(); // there can only be one!
- X509Certificate[] newChain = cleanupCertChainAndFindTrustAnchors(chain, trustAnchor);
-
- // add the first trust anchor to the chain, which may be an intermediate
- List<X509Certificate> wholeChain = new ArrayList<X509Certificate>();
- wholeChain.addAll(Arrays.asList(newChain));
- // trustAnchor is actually just a single element
- for (TrustAnchor trust : trustAnchor) {
- wholeChain.add(trust.getTrustedCert());
- }
-
- // add all the cached certificates from the cert index, avoiding loops
- // this gives us a full chain from leaf to root, which we use for cert pinning and pass
- // back out to callers when we return.
- X509Certificate last = wholeChain.get(wholeChain.size() - 1);
- while (true) {
- TrustAnchor cachedTrust = trustedCertificateIndex.findByIssuerAndSignature(last);
- // the cachedTrust can be null if there isn't anything in the index or if a user has
- // trusted a non-self-signed cert.
- if (cachedTrust == null) {
- break;
- }
-
- // at this point we have a cached trust anchor, but don't know if its one we got from
- // the server. Extract the cert, compare it to the last element in the chain, and add it
- // if we haven't seen it before.
- X509Certificate next = cachedTrust.getTrustedCert();
- if (next != last) {
- wholeChain.add(next);
- last = next;
- } else {
- // if next == last then we found a self-signed cert and the chain is done
- break;
- }
- }
-
- // build the cert path from the array of certs sans trust anchors
- CertPath certPath = factory.generateCertPath(Arrays.asList(newChain));
-
- if (host != null) {
- boolean chainIsNotPinned = true;
- try {
- chainIsNotPinned = pinManager.chainIsNotPinned(host, wholeChain);
- } catch (PinManagerException e) {
- throw new CertificateException(e);
- }
- if (chainIsNotPinned) {
- throw new CertificateException(new CertPathValidatorException(
- "Certificate path is not properly pinned.", null, certPath, -1));
- }
- }
-
- if (newChain.length == 0) {
- // chain was entirely trusted, skip the validator
- return wholeChain;
- }
-
- if (trustAnchor.isEmpty()) {
- throw new CertificateException(new CertPathValidatorException(
- "Trust anchor for certification path not found.", null, certPath, -1));
- }
-
- // There's no point in checking trust anchors here, and it will throw off the MD5 check,
- // so we just hand it the chain without anchors
- ChainStrengthAnalyzer.check(newChain);
-
- try {
- PKIXParameters params = new PKIXParameters(trustAnchor);
- params.setRevocationEnabled(false);
- params.addCertPathChecker(new ExtendedKeyUsagePKIXCertPathChecker(clientAuth,
- newChain[0]));
- validator.validate(certPath, params);
- // Add intermediate CAs to the index to tolerate sites
- // that assume that the browser will have cached these.
- // The server certificate is skipped by skipping the
- // zeroth element of new chain and note that the root CA
- // will have been removed in
- // cleanupCertChainAndFindTrustAnchors. http://b/3404902
- for (int i = 1; i < newChain.length; i++) {
- trustedCertificateIndex.index(newChain[i]);
- }
- } catch (InvalidAlgorithmParameterException e) {
- throw new CertificateException(e);
- } catch (CertPathValidatorException e) {
- throw new CertificateException(e);
- }
-
- return wholeChain;
- }
-
- /**
- * Clean up the certificate chain, returning a cleaned up chain,
- * which may be a new array instance if elements were removed.
- * Theoretically, we shouldn't have to do this, but various web
- * servers in practice are mis-configured to have out-of-order
- * certificates, expired self-issued root certificate, or CAs with
- * unsupported signature algorithms such as
- * md2WithRSAEncryption. This also handles removing old certs
- * after bridge CA certs.
- */
- private X509Certificate[] cleanupCertChainAndFindTrustAnchors(X509Certificate[] chain,
- Set<TrustAnchor> trustAnchors) {
- X509Certificate[] original = chain;
-
- // 1. Clean the received certificates chain.
- int currIndex;
- // Start with the first certificate in the chain, assuming it
- // is the leaf certificate (server or client cert).
- for (currIndex = 0; currIndex < chain.length; currIndex++) {
- // Walk the chain to find a "subject" matching
- // the "issuer" of the current certificate. In a properly
- // ordered chain this should be the next cert and be fast.
- // If not, we reorder things to be as the validator will
- // expect.
- boolean foundNext = false;
- for (int nextIndex = currIndex + 1; nextIndex < chain.length; nextIndex++) {
- if (chain[currIndex].getIssuerDN().equals(chain[nextIndex].getSubjectDN())) {
- foundNext = true;
- // Exchange certificates so that 0 through currIndex + 1 are in proper order
- if (nextIndex != currIndex + 1) {
- // don't mutuate original chain, which may be directly from an SSLSession
- if (chain == original) {
- chain = original.clone();
- }
- X509Certificate tempCertificate = chain[nextIndex];
- chain[nextIndex] = chain[currIndex + 1];
- chain[currIndex + 1] = tempCertificate;
- }
- break;
- }
- }
- // If we can't find the next in the chain, just give up
- // and use what we found so far. This drops unrelated
- // certificates that have nothing to do with the cert
- // chain.
- if (!foundNext) {
- break;
- }
- }
-
- // 2. Find the trust anchor in the chain, if any
- int anchorIndex;
- for (anchorIndex = 0; anchorIndex <= currIndex; anchorIndex++) {
- // If the current cert is a TrustAnchor, we can ignore the rest of the chain.
- // This avoids including "bridge" CA certs that added for legacy compatibility.
- TrustAnchor trustAnchor = findTrustAnchorBySubjectAndPublicKey(chain[anchorIndex]);
- if (trustAnchor != null) {
- trustAnchors.add(trustAnchor);
- break;
- }
- }
-
- // 3. If the chain is now shorter, copy to an appropriately sized array.
- int chainLength = anchorIndex;
- X509Certificate[] newChain = ((chainLength == chain.length)
- ? chain
- : Arrays.copyOf(chain, chainLength));
-
- // 4. If we didn't find a trust anchor earlier, look for one now
- if (trustAnchors.isEmpty()) {
- TrustAnchor trustAnchor = findTrustAnchorByIssuerAndSignature(newChain[anchorIndex-1]);
- if (trustAnchor != null) {
- trustAnchors.add(trustAnchor);
- }
- }
- return newChain;
- }
-
- /**
- * If an EKU extension is present in the end-entity certificate,
- * it MUST contain an appropriate key usage. For servers, this
- * includes anyExtendedKeyUsage, serverAuth, or the historical
- * Server Gated Cryptography options of nsSGC or msSGC. For
- * clients, this includes anyExtendedKeyUsage and clientAuth.
- */
- private static class ExtendedKeyUsagePKIXCertPathChecker extends PKIXCertPathChecker {
-
- private static final String EKU_OID = "2.5.29.37";
-
- private static final String EKU_anyExtendedKeyUsage = "2.5.29.37.0";
- private static final String EKU_clientAuth = "1.3.6.1.5.5.7.3.2";
- private static final String EKU_serverAuth = "1.3.6.1.5.5.7.3.1";
- private static final String EKU_nsSGC = "2.16.840.1.113730.4.1";
- private static final String EKU_msSGC = "1.3.6.1.4.1.311.10.3.3";
-
- private static final Set<String> SUPPORTED_EXTENSIONS
- = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(EKU_OID)));
-
- private final boolean clientAuth;
- private final X509Certificate leaf;
-
- private ExtendedKeyUsagePKIXCertPathChecker(boolean clientAuth, X509Certificate leaf) {
- this.clientAuth = clientAuth;
- this.leaf = leaf;
- }
-
- @Override public void init(boolean forward) throws CertPathValidatorException {
- }
-
- @Override public boolean isForwardCheckingSupported() {
- return true;
- }
-
- @Override public Set<String> getSupportedExtensions() {
- return SUPPORTED_EXTENSIONS;
- }
-
- @Override public void check(Certificate c, Collection<String> unresolvedCritExts)
- throws CertPathValidatorException {
- // We only want to validate the EKU on the leaf certificate.
- if (c != leaf) {
- return;
- }
- List<String> ekuOids;
- try {
- ekuOids = leaf.getExtendedKeyUsage();
- } catch (CertificateParsingException e) {
- // A malformed EKU is bad news, consider it fatal.
- throw new CertPathValidatorException(e);
- }
- // We are here to check EKU, but there is none.
- if (ekuOids == null) {
- return;
- }
-
- boolean goodExtendedKeyUsage = false;
- for (String ekuOid : ekuOids) {
- // anyExtendedKeyUsage for clients and servers
- if (ekuOid.equals(EKU_anyExtendedKeyUsage)) {
- goodExtendedKeyUsage = true;
- break;
- }
-
- // clients
- if (clientAuth) {
- if (ekuOid.equals(EKU_clientAuth)) {
- goodExtendedKeyUsage = true;
- break;
- }
- continue;
- }
-
- // servers
- if (ekuOid.equals(EKU_serverAuth)) {
- goodExtendedKeyUsage = true;
- break;
- }
- if (ekuOid.equals(EKU_nsSGC)) {
- goodExtendedKeyUsage = true;
- break;
- }
- if (ekuOid.equals(EKU_msSGC)) {
- goodExtendedKeyUsage = true;
- break;
- }
- }
- if (goodExtendedKeyUsage) {
- // Mark extendedKeyUsage as resolved if present.
- unresolvedCritExts.remove(EKU_OID);
- } else {
- throw new CertPathValidatorException("End-entity certificate does not have a valid "
- + "extendedKeyUsage.");
- }
- }
- }
-
- private TrustAnchor findTrustAnchorByIssuerAndSignature(X509Certificate lastCert) {
- TrustAnchor trustAnchor = trustedCertificateIndex.findByIssuerAndSignature(lastCert);
- if (trustAnchor != null) {
- return trustAnchor;
- }
- if (trustedCertificateStore == null) {
- return null;
- }
- // we have a KeyStore and the issuer of the last cert in
- // the chain seems to be missing from the
- // TrustedCertificateIndex, check the KeyStore for a hit
- X509Certificate issuer = trustedCertificateStore.findIssuer(lastCert);
- if (issuer != null) {
- return trustedCertificateIndex.index(issuer);
- }
- return null;
- }
-
- /**
- * Check the trustedCertificateIndex for the cert to see if it is
- * already trusted and failing that check the KeyStore if it is
- * available.
- */
- private TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) {
- TrustAnchor trustAnchor = trustedCertificateIndex.findBySubjectAndPublicKey(cert);
- if (trustAnchor != null) {
- return trustAnchor;
- }
- if (trustedCertificateStore == null) {
- // not trusted and no TrustedCertificateStore to check
- return null;
- }
- // probe KeyStore for a cert. AndroidCAStore stores its
- // contents hashed by cert subject on the filesystem to make
- // this faster than scanning all key store entries.
- if (trustedCertificateStore.isTrustAnchor(cert)) {
- // add new TrustAnchor to params index to avoid
- // checking filesystem next time around.
- return trustedCertificateIndex.index(cert);
- }
- return null;
- }
-
- @Override public X509Certificate[] getAcceptedIssuers() {
- return (acceptedIssuers != null) ? acceptedIssuers.clone() : acceptedIssuers(rootKeyStore);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustedCertificateIndex.java b/crypto/src/main/java/org/conscrypt/TrustedCertificateIndex.java
deleted file mode 100644
index b322cd1..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustedCertificateIndex.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.PublicKey;
-import java.security.cert.CertPathValidatorException;
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * Indexes {@code TrustAnchor} instances so they can be found in O(1)
- * time instead of O(N).
- */
-public final class TrustedCertificateIndex {
-
- private final Map<X500Principal, List<TrustAnchor>> subjectToTrustAnchors
- = new HashMap<X500Principal, List<TrustAnchor>>();
-
- public TrustedCertificateIndex() {}
-
- public TrustedCertificateIndex(Set<TrustAnchor> anchors) {
- index(anchors);
- }
-
- private void index(Set<TrustAnchor> anchors) {
- for (TrustAnchor anchor : anchors) {
- index(anchor);
- }
- }
-
- public TrustAnchor index(X509Certificate cert) {
- TrustAnchor anchor = new TrustAnchor(cert, null);
- index(anchor);
- return anchor;
- }
-
- public void index(TrustAnchor anchor) {
- X500Principal subject;
- X509Certificate cert = anchor.getTrustedCert();
- if (cert != null) {
- subject = cert.getSubjectX500Principal();
- } else {
- subject = anchor.getCA();
- }
-
- synchronized (subjectToTrustAnchors) {
- List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
- if (anchors == null) {
- anchors = new ArrayList<TrustAnchor>(1);
- subjectToTrustAnchors.put(subject, anchors);
- }
- anchors.add(anchor);
- }
- }
-
- public void reset() {
- synchronized (subjectToTrustAnchors) {
- subjectToTrustAnchors.clear();
- }
- }
-
- public void reset(Set<TrustAnchor> anchors) {
- synchronized (subjectToTrustAnchors) {
- reset();
- index(anchors);
- }
- }
-
- public TrustAnchor findByIssuerAndSignature(X509Certificate cert) {
- X500Principal issuer = cert.getIssuerX500Principal();
- synchronized (subjectToTrustAnchors) {
- List<TrustAnchor> anchors = subjectToTrustAnchors.get(issuer);
- if (anchors == null) {
- return null;
- }
-
- for (TrustAnchor anchor : anchors) {
- PublicKey publicKey;
- try {
- X509Certificate caCert = anchor.getTrustedCert();
- if (caCert != null) {
- publicKey = caCert.getPublicKey();
- } else {
- publicKey = anchor.getCAPublicKey();
- }
- cert.verify(publicKey);
- return anchor;
- } catch (Exception ignored) {
- }
- }
- }
- return null;
- }
-
- public TrustAnchor findBySubjectAndPublicKey(X509Certificate cert) {
- X500Principal subject = cert.getSubjectX500Principal();
- synchronized (subjectToTrustAnchors) {
- List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
- if (anchors == null) {
- return null;
- }
- return findBySubjectAndPublicKey(cert, anchors);
- }
- }
-
- private static TrustAnchor findBySubjectAndPublicKey(X509Certificate cert,
- Collection<TrustAnchor> anchors) {
- PublicKey certPublicKey = cert.getPublicKey();
- for (TrustAnchor anchor : anchors) {
- PublicKey caPublicKey;
- try {
- X509Certificate caCert = anchor.getTrustedCert();
- if (caCert != null) {
- caPublicKey = caCert.getPublicKey();
- } else {
- caPublicKey = anchor.getCAPublicKey();
- }
- if (caPublicKey.equals(certPublicKey)) {
- return anchor;
- }
- } catch (Exception e) {
- // can happen with unsupported public key types
- }
- }
- return null;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java b/crypto/src/main/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java
deleted file mode 100644
index c2d5c33..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.Key;
-import java.security.KeyStoreSpi;
-import java.security.cert.Certificate;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-
-/**
- * A KeyStoreSpi wrapper for the TrustedCertificateStore.
- */
-public final class TrustedCertificateKeyStoreSpi extends KeyStoreSpi {
-
- private final TrustedCertificateStore store = new TrustedCertificateStore();
-
- @Override public Key engineGetKey(String alias, char[] password) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- return null;
- }
-
- @Override public Certificate[] engineGetCertificateChain(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- return null;
- }
-
- @Override public Certificate engineGetCertificate(String alias) {
- return store.getCertificate(alias);
- }
-
- @Override public Date engineGetCreationDate(String alias) {
- return store.getCreationDate(alias);
- }
-
- @Override public void engineSetKeyEntry(
- String alias, Key key, char[] password, Certificate[] chain) {
- throw new UnsupportedOperationException();
- }
-
- @Override public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) {
- throw new UnsupportedOperationException();
- }
-
- @Override public void engineSetCertificateEntry(String alias, Certificate cert) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- throw new UnsupportedOperationException();
- }
-
- @Override public void engineDeleteEntry(String alias) {
- throw new UnsupportedOperationException();
- }
-
- @Override public Enumeration<String> engineAliases() {
- return Collections.enumeration(store.aliases());
- }
-
- @Override public boolean engineContainsAlias(String alias) {
- return store.containsAlias(alias);
- }
-
- @Override public int engineSize() {
- return store.aliases().size();
- }
-
- @Override public boolean engineIsKeyEntry(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- return false;
- }
-
- @Override public boolean engineIsCertificateEntry(String alias) {
- return engineContainsAlias(alias);
- }
-
- @Override public String engineGetCertificateAlias(Certificate c) {
- return store.getCertificateAlias(c);
- }
-
- @Override public void engineStore(OutputStream stream, char[] password) {
- throw new UnsupportedOperationException();
- }
-
- @Override public void engineLoad(InputStream stream, char[] password) {
- if (stream != null) {
- throw new UnsupportedOperationException();
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java b/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java
deleted file mode 100644
index 1356776..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-import libcore.io.IoUtils;
-
-/**
- * A source for trusted root certificate authority (CA) certificates
- * supporting an immutable system CA directory along with mutable
- * directories allowing the user addition of custom CAs and user
- * removal of system CAs. This store supports the {@code
- * TrustedCertificateKeyStoreSpi} wrapper to allow a traditional
- * KeyStore interface for use with {@link
- * javax.net.ssl.TrustManagerFactory.init}.
- *
- * <p>The CAs are accessed via {@code KeyStore} style aliases. Aliases
- * are made up of a prefix identifying the source ("system:" vs
- * "user:") and a suffix based on the OpenSSL X509_NAME_hash_old
- * function of the CA's subject name. For example, the system CA for
- * "C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification
- * Authority" could be represented as "system:7651b327.0". By using
- * the subject hash, operations such as {@link #getCertificateAlias
- * getCertificateAlias} can be implemented efficiently without
- * scanning the entire store.
- *
- * <p>In addition to supporting the {@code
- * TrustedCertificateKeyStoreSpi} implementation, {@code
- * TrustedCertificateStore} also provides the additional public
- * methods {@link #isTrustAnchor} and {@link #findIssuer} to allow
- * efficient lookup operations for CAs again based on the file naming
- * convention.
- *
- * <p>The KeyChainService users the {@link installCertificate} and
- * {@link #deleteCertificateEntry} to install user CAs as well as
- * delete those user CAs as well as system CAs. The deletion of system
- * CAs is performed by placing an exact copy of that CA in the deleted
- * directory. Such deletions are intended to persist across upgrades
- * but not intended to mask a CA with a matching name or public key
- * but is otherwise reissued in a system update. Reinstalling a
- * deleted system certificate simply removes the copy from the deleted
- * directory, reenabling the original in the system directory.
- *
- * <p>Note that the default mutable directory is created by init via
- * configuration in the system/core/rootdir/init.rc file. The
- * directive "mkdir /data/misc/keychain 0775 system system"
- * ensures that its owner and group are the system uid and system
- * gid and that it is world readable but only writable by the system
- * user.
- */
-public final class TrustedCertificateStore {
-
- private static final String PREFIX_SYSTEM = "system:";
- private static final String PREFIX_USER = "user:";
-
- public static final boolean isSystem(String alias) {
- return alias.startsWith(PREFIX_SYSTEM);
- }
- public static final boolean isUser(String alias) {
- return alias.startsWith(PREFIX_USER);
- }
-
- private static final File CA_CERTS_DIR_SYSTEM;
- private static final File CA_CERTS_DIR_ADDED;
- private static final File CA_CERTS_DIR_DELETED;
- private static final CertificateFactory CERT_FACTORY;
- static {
- String ANDROID_ROOT = System.getenv("ANDROID_ROOT");
- String ANDROID_DATA = System.getenv("ANDROID_DATA");
- CA_CERTS_DIR_SYSTEM = new File(ANDROID_ROOT + "/etc/security/cacerts");
- CA_CERTS_DIR_ADDED = new File(ANDROID_DATA + "/misc/keychain/cacerts-added");
- CA_CERTS_DIR_DELETED = new File(ANDROID_DATA + "/misc/keychain/cacerts-removed");
-
- try {
- CERT_FACTORY = CertificateFactory.getInstance("X509");
- } catch (CertificateException e) {
- throw new AssertionError(e);
- }
- }
-
- private final File systemDir;
- private final File addedDir;
- private final File deletedDir;
-
- public TrustedCertificateStore() {
- this(CA_CERTS_DIR_SYSTEM, CA_CERTS_DIR_ADDED, CA_CERTS_DIR_DELETED);
- }
-
- public TrustedCertificateStore(File systemDir, File addedDir, File deletedDir) {
- this.systemDir = systemDir;
- this.addedDir = addedDir;
- this.deletedDir = deletedDir;
- }
-
- public Certificate getCertificate(String alias) {
- return getCertificate(alias, false);
- }
-
- public Certificate getCertificate(String alias, boolean includeDeletedSystem) {
-
- File file = fileForAlias(alias);
- if (file == null || (isUser(alias) && isTombstone(file))) {
- return null;
- }
- X509Certificate cert = readCertificate(file);
- if (cert == null || (isSystem(alias)
- && !includeDeletedSystem
- && isDeletedSystemCertificate(cert))) {
- // skip malformed certs as well as deleted system ones
- return null;
- }
- return cert;
- }
-
- private File fileForAlias(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- File file;
- if (isSystem(alias)) {
- file = new File(systemDir, alias.substring(PREFIX_SYSTEM.length()));
- } else if (isUser(alias)) {
- file = new File(addedDir, alias.substring(PREFIX_USER.length()));
- } else {
- return null;
- }
- if (!file.exists() || isTombstone(file)) {
- // silently elide tombstones
- return null;
- }
- return file;
- }
-
- private boolean isTombstone(File file) {
- return file.length() == 0;
- }
-
- private X509Certificate readCertificate(File file) {
- if (!file.isFile()) {
- return null;
- }
- InputStream is = null;
- try {
- is = new BufferedInputStream(new FileInputStream(file));
- return (X509Certificate) CERT_FACTORY.generateCertificate(is);
- } catch (IOException e) {
- return null;
- } catch (CertificateException e) {
- // reading a cert while its being installed can lead to this.
- // just pretend like its not available yet.
- return null;
- } finally {
- IoUtils.closeQuietly(is);
- }
- }
-
- private void writeCertificate(File file, X509Certificate cert)
- throws IOException, CertificateException {
- File dir = file.getParentFile();
- dir.mkdirs();
- dir.setReadable(true, false);
- dir.setExecutable(true, false);
- OutputStream os = null;
- try {
- os = new FileOutputStream(file);
- os.write(cert.getEncoded());
- } finally {
- IoUtils.closeQuietly(os);
- }
- file.setReadable(true, false);
- }
-
- private boolean isDeletedSystemCertificate(X509Certificate x) {
- return getCertificateFile(deletedDir, x).exists();
- }
-
- public Date getCreationDate(String alias) {
- // containsAlias check ensures the later fileForAlias result
- // was not a deleted system cert.
- if (!containsAlias(alias)) {
- return null;
- }
- File file = fileForAlias(alias);
- if (file == null) {
- return null;
- }
- long time = file.lastModified();
- if (time == 0) {
- return null;
- }
- return new Date(time);
- }
-
- public Set<String> aliases() {
- Set<String> result = new HashSet<String>();
- addAliases(result, PREFIX_USER, addedDir);
- addAliases(result, PREFIX_SYSTEM, systemDir);
- return result;
- }
-
- public Set<String> userAliases() {
- Set<String> result = new HashSet<String>();
- addAliases(result, PREFIX_USER, addedDir);
- return result;
- }
-
- private void addAliases(Set<String> result, String prefix, File dir) {
- String[] files = dir.list();
- if (files == null) {
- return;
- }
- for (String filename : files) {
- String alias = prefix + filename;
- if (containsAlias(alias)) {
- result.add(alias);
- }
- }
- }
-
- public Set<String> allSystemAliases() {
- Set<String> result = new HashSet<String>();
- String[] files = systemDir.list();
- if (files == null) {
- return result;
- }
- for (String filename : files) {
- String alias = PREFIX_SYSTEM + filename;
- if (containsAlias(alias, true)) {
- result.add(alias);
- }
- }
- return result;
- }
-
- public boolean containsAlias(String alias) {
- return containsAlias(alias, false);
- }
-
- private boolean containsAlias(String alias, boolean includeDeletedSystem) {
- return getCertificate(alias, includeDeletedSystem) != null;
- }
-
- public String getCertificateAlias(Certificate c) {
- if (c == null || !(c instanceof X509Certificate)) {
- return null;
- }
- X509Certificate x = (X509Certificate) c;
- File user = getCertificateFile(addedDir, x);
- if (user.exists()) {
- return PREFIX_USER + user.getName();
- }
- if (isDeletedSystemCertificate(x)) {
- return null;
- }
- File system = getCertificateFile(systemDir, x);
- if (system.exists()) {
- return PREFIX_SYSTEM + system.getName();
- }
- return null;
- }
-
- /**
- * Returns true to indicate that the certificate was added by the
- * user, false otherwise.
- */
- public boolean isUserAddedCertificate(X509Certificate cert) {
- return getCertificateFile(addedDir, cert).exists();
- }
-
- /**
- * Returns a File for where the certificate is found if it exists
- * or where it should be installed if it does not exist. The
- * caller can disambiguate these cases by calling {@code
- * File.exists()} on the result.
- */
- private File getCertificateFile(File dir, final X509Certificate x) {
- // compare X509Certificate.getEncoded values
- CertSelector selector = new CertSelector() {
- @Override public boolean match(X509Certificate cert) {
- return cert.equals(x);
- }
- };
- return findCert(dir, x.getSubjectX500Principal(), selector, File.class);
- }
-
- /**
- * This non-{@code KeyStoreSpi} public interface is used by {@code
- * TrustManagerImpl} to locate a CA certificate with the same name
- * and public key as the provided {@code X509Certificate}. We
- * match on the name and public key and not the entire certificate
- * since a CA may be reissued with the same name and PublicKey but
- * with other differences (for example when switching signature
- * from md2WithRSAEncryption to SHA1withRSA)
- */
- public boolean isTrustAnchor(final X509Certificate c) {
- // compare X509Certificate.getPublicKey values
- CertSelector selector = new CertSelector() {
- @Override public boolean match(X509Certificate ca) {
- return ca.getPublicKey().equals(c.getPublicKey());
- }
- };
- boolean user = findCert(addedDir,
- c.getSubjectX500Principal(),
- selector,
- Boolean.class);
- if (user) {
- return true;
- }
- X509Certificate system = findCert(systemDir,
- c.getSubjectX500Principal(),
- selector,
- X509Certificate.class);
- return system != null && !isDeletedSystemCertificate(system);
- }
-
- /**
- * This non-{@code KeyStoreSpi} public interface is used by {@code
- * TrustManagerImpl} to locate the CA certificate that signed the
- * provided {@code X509Certificate}.
- */
- public X509Certificate findIssuer(final X509Certificate c) {
- // match on verified issuer of Certificate
- CertSelector selector = new CertSelector() {
- @Override public boolean match(X509Certificate ca) {
- try {
- c.verify(ca.getPublicKey());
- return true;
- } catch (Exception e) {
- return false;
- }
- }
- };
- X500Principal issuer = c.getIssuerX500Principal();
- X509Certificate user = findCert(addedDir, issuer, selector, X509Certificate.class);
- if (user != null) {
- return user;
- }
- X509Certificate system = findCert(systemDir, issuer, selector, X509Certificate.class);
- if (system != null && !isDeletedSystemCertificate(system)) {
- return system;
- }
- return null;
- }
-
- private static boolean isSelfIssuedCertificate(OpenSSLX509Certificate cert) {
- final long ctx = cert.getContext();
- return NativeCrypto.X509_check_issued(ctx, ctx) == 0;
- }
-
- /**
- * Converts the {@code cert} to the internal OpenSSL X.509 format so we can
- * run {@link NativeCrypto} methods on it.
- */
- private static OpenSSLX509Certificate convertToOpenSSLIfNeeded(X509Certificate cert)
- throws CertificateException {
- if (cert == null) {
- return null;
- }
-
- if (cert instanceof OpenSSLX509Certificate) {
- return (OpenSSLX509Certificate) cert;
- }
-
- try {
- return OpenSSLX509Certificate.fromX509Der(cert.getEncoded());
- } catch (Exception e) {
- throw new CertificateException(e);
- }
- }
-
- /**
- * Attempt to build a certificate chain from the supplied {@code leaf}
- * argument through the chain of issuers as high up as known. If the chain
- * can't be completed, the most complete chain available will be returned.
- * This means that a list with only the {@code leaf} certificate is returned
- * if no issuer certificates could be found.
- *
- * @throws CertificateException if there was a problem parsing the
- * certificates
- */
- public List<X509Certificate> getCertificateChain(X509Certificate leaf)
- throws CertificateException {
- final List<OpenSSLX509Certificate> chain = new ArrayList<OpenSSLX509Certificate>();
- chain.add(convertToOpenSSLIfNeeded(leaf));
-
- for (int i = 0; true; i++) {
- OpenSSLX509Certificate cert = chain.get(i);
- if (isSelfIssuedCertificate(cert)) {
- break;
- }
- OpenSSLX509Certificate issuer = convertToOpenSSLIfNeeded(findIssuer(cert));
- if (issuer == null) {
- break;
- }
- chain.add(issuer);
- }
-
- return new ArrayList<X509Certificate>(chain);
- }
-
- // like java.security.cert.CertSelector but with X509Certificate and without cloning
- private static interface CertSelector {
- public boolean match(X509Certificate cert);
- }
-
- private <T> T findCert(
- File dir, X500Principal subject, CertSelector selector, Class<T> desiredReturnType) {
-
- String hash = hash(subject);
- for (int index = 0; true; index++) {
- File file = file(dir, hash, index);
- if (!file.isFile()) {
- // could not find a match, no file exists, bail
- if (desiredReturnType == Boolean.class) {
- return (T) Boolean.FALSE;
- }
- if (desiredReturnType == File.class) {
- // we return file so that caller that wants to
- // write knows what the next available has
- // location is
- return (T) file;
- }
- return null;
- }
- if (isTombstone(file)) {
- continue;
- }
- X509Certificate cert = readCertificate(file);
- if (cert == null) {
- // skip problem certificates
- continue;
- }
- if (selector.match(cert)) {
- if (desiredReturnType == X509Certificate.class) {
- return (T) cert;
- }
- if (desiredReturnType == Boolean.class) {
- return (T) Boolean.TRUE;
- }
- if (desiredReturnType == File.class) {
- return (T) file;
- }
- throw new AssertionError();
- }
- }
- }
-
- private String hash(X500Principal name) {
- int hash = NativeCrypto.X509_NAME_hash_old(name);
- return IntegralToString.intToHexString(hash, false, 8);
- }
-
- private File file(File dir, String hash, int index) {
- return new File(dir, hash + '.' + index);
- }
-
- /**
- * This non-{@code KeyStoreSpi} public interface is used by the
- * {@code KeyChainService} to install new CA certificates. It
- * silently ignores the certificate if it already exists in the
- * store.
- */
- public void installCertificate(X509Certificate cert) throws IOException, CertificateException {
- if (cert == null) {
- throw new NullPointerException("cert == null");
- }
- File system = getCertificateFile(systemDir, cert);
- if (system.exists()) {
- File deleted = getCertificateFile(deletedDir, cert);
- if (deleted.exists()) {
- // we have a system cert that was marked deleted.
- // remove the deleted marker to expose the original
- if (!deleted.delete()) {
- throw new IOException("Could not remove " + deleted);
- }
- return;
- }
- // otherwise we just have a dup of an existing system cert.
- // return taking no further action.
- return;
- }
- File user = getCertificateFile(addedDir, cert);
- if (user.exists()) {
- // we have an already installed user cert, bail.
- return;
- }
- // install the user cert
- writeCertificate(user, cert);
- }
-
- /**
- * This could be considered the implementation of {@code
- * TrustedCertificateKeyStoreSpi.engineDeleteEntry} but we
- * consider {@code TrustedCertificateKeyStoreSpi} to be read
- * only. Instead, this is used by the {@code KeyChainService} to
- * delete CA certificates.
- */
- public void deleteCertificateEntry(String alias) throws IOException, CertificateException {
- if (alias == null) {
- return;
- }
- File file = fileForAlias(alias);
- if (file == null) {
- return;
- }
- if (isSystem(alias)) {
- X509Certificate cert = readCertificate(file);
- if (cert == null) {
- // skip problem certificates
- return;
- }
- File deleted = getCertificateFile(deletedDir, cert);
- if (deleted.exists()) {
- // already deleted system certificate
- return;
- }
- // write copy of system cert to marked as deleted
- writeCertificate(deleted, cert);
- return;
- }
- if (isUser(alias)) {
- // truncate the file to make a tombstone by opening and closing.
- // we need ensure that we don't leave a gap before a valid cert.
- new FileOutputStream(file).close();
- removeUnnecessaryTombstones(alias);
- return;
- }
- // non-existant user cert, nothing to delete
- }
-
- private void removeUnnecessaryTombstones(String alias) throws IOException {
- if (!isUser(alias)) {
- throw new AssertionError(alias);
- }
- int dotIndex = alias.lastIndexOf('.');
- if (dotIndex == -1) {
- throw new AssertionError(alias);
- }
-
- String hash = alias.substring(PREFIX_USER.length(), dotIndex);
- int lastTombstoneIndex = Integer.parseInt(alias.substring(dotIndex + 1));
-
- if (file(addedDir, hash, lastTombstoneIndex + 1).exists()) {
- return;
- }
- while (lastTombstoneIndex >= 0) {
- File file = file(addedDir, hash, lastTombstoneIndex);
- if (!isTombstone(file)) {
- break;
- }
- if (!file.delete()) {
- throw new IOException("Could not remove " + file);
- }
- lastTombstoneIndex--;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/X509PublicKey.java b/crypto/src/main/java/org/conscrypt/X509PublicKey.java
deleted file mode 100644
index 8d09fc2..0000000
--- a/crypto/src/main/java/org/conscrypt/X509PublicKey.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.PublicKey;
-import java.util.Arrays;
-
-/**
- * A simple but useless key class that holds X.509 public key information when
- * the appropriate KeyFactory for the key algorithm is not available.
- */
-public class X509PublicKey implements PublicKey {
- private static final long serialVersionUID = -8610156854731664298L;
-
- private final String algorithm;
-
- private final byte[] encoded;
-
- public X509PublicKey(String algorithm, byte[] encoded) {
- this.algorithm = algorithm;
- this.encoded = encoded;
- }
-
- @Override
- public String getAlgorithm() {
- return algorithm;
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return encoded;
- }
-
- @Override
- public String toString() {
- return "X509PublicKey [algorithm=" + algorithm + ", encoded=" + Arrays.toString(encoded)
- + "]";
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((algorithm == null) ? 0 : algorithm.hashCode());
- result = prime * result + Arrays.hashCode(encoded);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- X509PublicKey other = (X509PublicKey) obj;
- if (algorithm == null) {
- if (other.algorithm != null)
- return false;
- } else if (!algorithm.equals(other.algorithm))
- return false;
- if (!Arrays.equals(encoded, other.encoded))
- return false;
- return true;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/util/EmptyArray.java b/crypto/src/main/java/org/conscrypt/util/EmptyArray.java
deleted file mode 100644
index e474562..0000000
--- a/crypto/src/main/java/org/conscrypt/util/EmptyArray.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Copied from libcore.util.EmptyArray
-
-package org.conscrypt.util;
-
-public final class EmptyArray {
- private EmptyArray() {}
-
- public static final boolean[] BOOLEAN = new boolean[0];
- public static final byte[] BYTE = new byte[0];
- public static final char[] CHAR = new char[0];
- public static final double[] DOUBLE = new double[0];
- public static final int[] INT = new int[0];
-
- public static final Class<?>[] CLASS = new Class[0];
- public static final Object[] OBJECT = new Object[0];
- public static final String[] STRING = new String[0];
- public static final Throwable[] THROWABLE = new Throwable[0];
- public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
-} \ No newline at end of file
diff --git a/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp b/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
deleted file mode 100644
index cc5abbd..0000000
--- a/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
+++ /dev/null
@@ -1,8244 +0,0 @@
-/*
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Native glue for Java class org.conscrypt.NativeCrypto
- */
-
-#define TO_STRING1(x) #x
-#define TO_STRING(x) TO_STRING1(x)
-#ifndef JNI_JARJAR_PREFIX
-#define CONSCRYPT_UNBUNDLED
-#define JNI_JARJAR_PREFIX
-#endif
-
-#define LOG_TAG "NativeCrypto"
-
-#include <algorithm>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <vector>
-
-#include <jni.h>
-
-#include <openssl/asn1t.h>
-#include <openssl/dsa.h>
-#include <openssl/engine.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/ssl.h>
-#include <openssl/x509v3.h>
-
-#include "AsynchronousSocketCloseMonitor.h"
-#include "cutils/log.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "NetFd.h"
-#include "ScopedLocalRef.h"
-#include "ScopedPrimitiveArray.h"
-#include "ScopedUtfChars.h"
-#include "UniquePtr.h"
-
-#undef WITH_JNI_TRACE
-#undef WITH_JNI_TRACE_DATA
-
-/*
- * How to use this for debugging with Wireshark:
- *
- * 1. Pull lines from logcat to a file that looks like (without quotes):
- * "RSA Session-ID:... Master-Key:..." <CR>
- * "RSA Session-ID:... Master-Key:..." <CR>
- * <etc>
- * 2. Start Wireshark
- * 3. Go to Edit -> Preferences -> SSL -> (Pre-)Master-Key log and fill in
- * the file you put the lines in above.
- * 4. Follow the stream that corresponds to the desired "Session-ID" in
- * the Server Hello.
- */
-#undef WITH_JNI_TRACE_KEYS
-
-#ifdef WITH_JNI_TRACE
-#define JNI_TRACE(...) \
- ((void)ALOG(LOG_INFO, LOG_TAG "-jni", __VA_ARGS__)); \
-/*
- ((void)printf("I/" LOG_TAG "-jni:")); \
- ((void)printf(__VA_ARGS__)); \
- ((void)printf("\n"))
-*/
-#else
-#define JNI_TRACE(...) ((void)0)
-#endif
-// don't overwhelm logcat
-#define WITH_JNI_TRACE_DATA_CHUNK_SIZE 512
-
-static JavaVM* gJavaVM;
-static jclass openSslOutputStreamClass;
-
-static jclass byteArrayClass;
-static jclass calendarClass;
-static jclass objectClass;
-static jclass objectArrayClass;
-static jclass integerClass;
-static jclass inputStreamClass;
-static jclass outputStreamClass;
-static jclass stringClass;
-
-static jmethodID calendar_setMethod;
-static jmethodID inputStream_readMethod;
-static jmethodID integer_valueOfMethod;
-static jmethodID openSslInputStream_readLineMethod;
-static jmethodID outputStream_writeMethod;
-static jmethodID outputStream_flushMethod;
-
-struct OPENSSL_Delete {
- void operator()(void* p) const {
- OPENSSL_free(p);
- }
-};
-typedef UniquePtr<unsigned char, OPENSSL_Delete> Unique_OPENSSL_str;
-
-struct BIO_Delete {
- void operator()(BIO* p) const {
- BIO_free(p);
- }
-};
-typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
-
-struct BIGNUM_Delete {
- void operator()(BIGNUM* p) const {
- BN_free(p);
- }
-};
-typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
-
-struct ASN1_INTEGER_Delete {
- void operator()(ASN1_INTEGER* p) const {
- ASN1_INTEGER_free(p);
- }
-};
-typedef UniquePtr<ASN1_INTEGER, ASN1_INTEGER_Delete> Unique_ASN1_INTEGER;
-
-struct DH_Delete {
- void operator()(DH* p) const {
- DH_free(p);
- }
-};
-typedef UniquePtr<DH, DH_Delete> Unique_DH;
-
-struct DSA_Delete {
- void operator()(DSA* p) const {
- DSA_free(p);
- }
-};
-typedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
-
-struct EC_GROUP_Delete {
- void operator()(EC_GROUP* p) const {
- EC_GROUP_clear_free(p);
- }
-};
-typedef UniquePtr<EC_GROUP, EC_GROUP_Delete> Unique_EC_GROUP;
-
-struct EC_POINT_Delete {
- void operator()(EC_POINT* p) const {
- EC_POINT_clear_free(p);
- }
-};
-typedef UniquePtr<EC_POINT, EC_POINT_Delete> Unique_EC_POINT;
-
-struct EC_KEY_Delete {
- void operator()(EC_KEY* p) const {
- EC_KEY_free(p);
- }
-};
-typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
-
-struct EVP_MD_CTX_Delete {
- void operator()(EVP_MD_CTX* p) const {
- EVP_MD_CTX_destroy(p);
- }
-};
-typedef UniquePtr<EVP_MD_CTX, EVP_MD_CTX_Delete> Unique_EVP_MD_CTX;
-
-struct EVP_CIPHER_CTX_Delete {
- void operator()(EVP_CIPHER_CTX* p) const {
- EVP_CIPHER_CTX_cleanup(p);
- }
-};
-typedef UniquePtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Delete> Unique_EVP_CIPHER_CTX;
-
-struct EVP_PKEY_Delete {
- void operator()(EVP_PKEY* p) const {
- EVP_PKEY_free(p);
- }
-};
-typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
-
-struct PKCS8_PRIV_KEY_INFO_Delete {
- void operator()(PKCS8_PRIV_KEY_INFO* p) const {
- PKCS8_PRIV_KEY_INFO_free(p);
- }
-};
-typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
-
-struct RSA_Delete {
- void operator()(RSA* p) const {
- RSA_free(p);
- }
-};
-typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
-
-struct ASN1_BIT_STRING_Delete {
- void operator()(ASN1_BIT_STRING* p) const {
- ASN1_BIT_STRING_free(p);
- }
-};
-typedef UniquePtr<ASN1_BIT_STRING, ASN1_BIT_STRING_Delete> Unique_ASN1_BIT_STRING;
-
-struct ASN1_OBJECT_Delete {
- void operator()(ASN1_OBJECT* p) const {
- ASN1_OBJECT_free(p);
- }
-};
-typedef UniquePtr<ASN1_OBJECT, ASN1_OBJECT_Delete> Unique_ASN1_OBJECT;
-
-struct ASN1_GENERALIZEDTIME_Delete {
- void operator()(ASN1_GENERALIZEDTIME* p) const {
- ASN1_GENERALIZEDTIME_free(p);
- }
-};
-typedef UniquePtr<ASN1_GENERALIZEDTIME, ASN1_GENERALIZEDTIME_Delete> Unique_ASN1_GENERALIZEDTIME;
-
-struct SSL_Delete {
- void operator()(SSL* p) const {
- SSL_free(p);
- }
-};
-typedef UniquePtr<SSL, SSL_Delete> Unique_SSL;
-
-struct SSL_CTX_Delete {
- void operator()(SSL_CTX* p) const {
- SSL_CTX_free(p);
- }
-};
-typedef UniquePtr<SSL_CTX, SSL_CTX_Delete> Unique_SSL_CTX;
-
-struct X509_Delete {
- void operator()(X509* p) const {
- X509_free(p);
- }
-};
-typedef UniquePtr<X509, X509_Delete> Unique_X509;
-
-class X509Chain {
- public:
- X509Chain(size_t n) : x509s_(n) {}
-
- ~X509Chain() {
- for (const auto& x509 : x509s_) {
- X509_free(x509);
- }
- }
-
- X509*& operator[](size_t n) {
- return x509s_[n];
- }
-
- X509* operator[](size_t n) const {
- return x509s_[n];
- }
-
- X509* release(size_t i) {
- X509* x = x509s_[i];
- x509s_[i] = NULL;
- return x;
- }
-
- private:
- std::vector<X509*> x509s_;
-};
-
-struct X509_NAME_Delete {
- void operator()(X509_NAME* p) const {
- X509_NAME_free(p);
- }
-};
-typedef UniquePtr<X509_NAME, X509_NAME_Delete> Unique_X509_NAME;
-
-struct PKCS7_Delete {
- void operator()(PKCS7* p) const {
- PKCS7_free(p);
- }
-};
-typedef UniquePtr<PKCS7, PKCS7_Delete> Unique_PKCS7;
-
-struct sk_SSL_CIPHER_Delete {
- void operator()(STACK_OF(SSL_CIPHER)* p) const {
- // We don't own SSL_CIPHER references, so no need for pop_free
- sk_SSL_CIPHER_free(p);
- }
-};
-typedef UniquePtr<STACK_OF(SSL_CIPHER), sk_SSL_CIPHER_Delete> Unique_sk_SSL_CIPHER;
-
-struct sk_X509_Delete {
- void operator()(STACK_OF(X509)* p) const {
- sk_X509_pop_free(p, X509_free);
- }
-};
-typedef UniquePtr<STACK_OF(X509), sk_X509_Delete> Unique_sk_X509;
-
-struct sk_X509_NAME_Delete {
- void operator()(STACK_OF(X509_NAME)* p) const {
- sk_X509_NAME_pop_free(p, X509_NAME_free);
- }
-};
-typedef UniquePtr<STACK_OF(X509_NAME), sk_X509_NAME_Delete> Unique_sk_X509_NAME;
-
-struct sk_ASN1_OBJECT_Delete {
- void operator()(STACK_OF(ASN1_OBJECT)* p) const {
- sk_ASN1_OBJECT_pop_free(p, ASN1_OBJECT_free);
- }
-};
-typedef UniquePtr<STACK_OF(ASN1_OBJECT), sk_ASN1_OBJECT_Delete> Unique_sk_ASN1_OBJECT;
-
-struct sk_GENERAL_NAME_Delete {
- void operator()(STACK_OF(GENERAL_NAME)* p) const {
- sk_GENERAL_NAME_pop_free(p, GENERAL_NAME_free);
- }
-};
-typedef UniquePtr<STACK_OF(GENERAL_NAME), sk_GENERAL_NAME_Delete> Unique_sk_GENERAL_NAME;
-
-/**
- * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
- * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
- * without triggering a warning by not using the result of release().
- */
-#define OWNERSHIP_TRANSFERRED(obj) \
- typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
-
-/**
- * Frees the SSL error state.
- *
- * OpenSSL keeps an "error stack" per thread, and given that this code
- * can be called from arbitrary threads that we don't keep track of,
- * we err on the side of freeing the error state promptly (instead of,
- * say, at thread death).
- */
-static void freeOpenSslErrorState(void) {
- ERR_clear_error();
- ERR_remove_state(0);
-}
-
-/**
- * Throws a OutOfMemoryError with the given string as a message.
- */
-static void jniThrowOutOfMemory(JNIEnv* env, const char* message) {
- jniThrowException(env, "java/lang/OutOfMemoryError", message);
-}
-
-/**
- * Throws a BadPaddingException with the given string as a message.
- */
-static void throwBadPaddingException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwBadPaddingException %s", message);
- jniThrowException(env, "javax/crypto/BadPaddingException", message);
-}
-
-/**
- * Throws a SignatureException with the given string as a message.
- */
-static void throwSignatureException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwSignatureException %s", message);
- jniThrowException(env, "java/security/SignatureException", message);
-}
-
-/**
- * Throws a InvalidKeyException with the given string as a message.
- */
-static void throwInvalidKeyException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwInvalidKeyException %s", message);
- jniThrowException(env, "java/security/InvalidKeyException", message);
-}
-
-/**
- * Throws a SignatureException with the given string as a message.
- */
-static void throwIllegalBlockSizeException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwIllegalBlockSizeException %s", message);
- jniThrowException(env, "javax/crypto/IllegalBlockSizeException", message);
-}
-
-/**
- * Throws a NoSuchAlgorithmException with the given string as a message.
- */
-static void throwNoSuchAlgorithmException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwUnknownAlgorithmException %s", message);
- jniThrowException(env, "java/security/NoSuchAlgorithmException", message);
-}
-
-static void throwForAsn1Error(JNIEnv* env, int reason, const char *message) {
- switch (reason) {
- case ASN1_R_UNABLE_TO_DECODE_RSA_KEY:
- case ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY:
- case ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE:
- case ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE:
- case ASN1_R_WRONG_PUBLIC_KEY_TYPE:
- throwInvalidKeyException(env, message);
- break;
- case ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM:
- throwNoSuchAlgorithmException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
-}
-
-static void throwForEvpError(JNIEnv* env, int reason, const char *message) {
- switch (reason) {
- case EVP_R_BAD_DECRYPT:
- throwBadPaddingException(env, message);
- break;
- case EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
- case EVP_R_WRONG_FINAL_BLOCK_LENGTH:
- throwIllegalBlockSizeException(env, message);
- break;
- case EVP_R_BAD_KEY_LENGTH:
- case EVP_R_BN_DECODE_ERROR:
- case EVP_R_BN_PUBKEY_ERROR:
- case EVP_R_INVALID_KEY_LENGTH:
- case EVP_R_MISSING_PARAMETERS:
- case EVP_R_UNSUPPORTED_KEY_SIZE:
- case EVP_R_UNSUPPORTED_KEYLENGTH:
- throwInvalidKeyException(env, message);
- break;
- case EVP_R_WRONG_PUBLIC_KEY_TYPE:
- throwSignatureException(env, message);
- break;
- case EVP_R_UNSUPPORTED_ALGORITHM:
- throwNoSuchAlgorithmException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
-}
-
-static void throwForRsaError(JNIEnv* env, int reason, const char *message) {
- switch (reason) {
- case RSA_R_BLOCK_TYPE_IS_NOT_01:
- case RSA_R_BLOCK_TYPE_IS_NOT_02:
- throwBadPaddingException(env, message);
- break;
- case RSA_R_ALGORITHM_MISMATCH:
- case RSA_R_BAD_SIGNATURE:
- case RSA_R_DATA_GREATER_THAN_MOD_LEN:
- case RSA_R_DATA_TOO_LARGE_FOR_MODULUS:
- case RSA_R_INVALID_MESSAGE_LENGTH:
- case RSA_R_WRONG_SIGNATURE_LENGTH:
- throwSignatureException(env, message);
- break;
- case RSA_R_UNKNOWN_ALGORITHM_TYPE:
- throwNoSuchAlgorithmException(env, message);
- break;
- case RSA_R_MODULUS_TOO_LARGE:
- case RSA_R_NO_PUBLIC_EXPONENT:
- throwInvalidKeyException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
-}
-
-static void throwForX509Error(JNIEnv* env, int reason, const char *message) {
- switch (reason) {
- case X509_R_UNSUPPORTED_ALGORITHM:
- throwNoSuchAlgorithmException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
-}
-
-/*
- * Checks this thread's OpenSSL error queue and throws a RuntimeException if
- * necessary.
- *
- * @return true if an exception was thrown, false if not.
- */
-static bool throwExceptionIfNecessary(JNIEnv* env, const char* location __attribute__ ((unused))) {
- const char* file;
- int line;
- const char* data;
- int flags;
- unsigned long error = ERR_get_error_line_data(&file, &line, &data, &flags);
- int result = false;
-
- if (error != 0) {
- char message[256];
- ERR_error_string_n(error, message, sizeof(message));
- int library = ERR_GET_LIB(error);
- int reason = ERR_GET_REASON(error);
- JNI_TRACE("OpenSSL error in %s error=%lx library=%x reason=%x (%s:%d): %s %s",
- location, error, library, reason, file, line, message,
- (flags & ERR_TXT_STRING) ? data : "(no data)");
- switch (library) {
- case ERR_LIB_RSA:
- throwForRsaError(env, reason, message);
- break;
- case ERR_LIB_ASN1:
- throwForAsn1Error(env, reason, message);
- break;
- case ERR_LIB_EVP:
- throwForEvpError(env, reason, message);
- break;
- case ERR_LIB_X509:
- throwForX509Error(env, reason, message);
- break;
- case ERR_LIB_DSA:
- throwInvalidKeyException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
- result = true;
- }
-
- freeOpenSslErrorState();
- return result;
-}
-
-/**
- * Throws an SocketTimeoutException with the given string as a message.
- */
-static void throwSocketTimeoutException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwSocketTimeoutException %s", message);
- jniThrowException(env, "java/net/SocketTimeoutException", message);
-}
-
-/**
- * Throws a javax.net.ssl.SSLException with the given string as a message.
- */
-static void throwSSLExceptionStr(JNIEnv* env, const char* message) {
- JNI_TRACE("throwSSLExceptionStr %s", message);
- jniThrowException(env, "javax/net/ssl/SSLException", message);
-}
-
-/**
- * Throws a javax.net.ssl.SSLProcotolException with the given string as a message.
- */
-static void throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) {
- JNI_TRACE("throwSSLProtocolExceptionStr %s", message);
- jniThrowException(env, "javax/net/ssl/SSLProtocolException", message);
-}
-
-/**
- * Throws an SSLException with a message constructed from the current
- * SSL errors. This will also log the errors.
- *
- * @param env the JNI environment
- * @param ssl the possibly NULL SSL
- * @param sslErrorCode error code returned from SSL_get_error() or
- * SSL_ERROR_NONE to probe with ERR_get_error
- * @param message null-ok; general error message
- */
-static void throwSSLExceptionWithSslErrors(
- JNIEnv* env, SSL* ssl, int sslErrorCode, const char* message) {
-
- if (message == NULL) {
- message = "SSL error";
- }
-
- // First consult the SSL error code for the general message.
- const char* sslErrorStr = NULL;
- switch (sslErrorCode) {
- case SSL_ERROR_NONE:
- if (ERR_peek_error() == 0) {
- sslErrorStr = "OK";
- } else {
- sslErrorStr = "";
- }
- break;
- case SSL_ERROR_SSL:
- sslErrorStr = "Failure in SSL library, usually a protocol error";
- break;
- case SSL_ERROR_WANT_READ:
- sslErrorStr = "SSL_ERROR_WANT_READ occurred. You should never see this.";
- break;
- case SSL_ERROR_WANT_WRITE:
- sslErrorStr = "SSL_ERROR_WANT_WRITE occurred. You should never see this.";
- break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- sslErrorStr = "SSL_ERROR_WANT_X509_LOOKUP occurred. You should never see this.";
- break;
- case SSL_ERROR_SYSCALL:
- sslErrorStr = "I/O error during system call";
- break;
- case SSL_ERROR_ZERO_RETURN:
- sslErrorStr = "SSL_ERROR_ZERO_RETURN occurred. You should never see this.";
- break;
- case SSL_ERROR_WANT_CONNECT:
- sslErrorStr = "SSL_ERROR_WANT_CONNECT occurred. You should never see this.";
- break;
- case SSL_ERROR_WANT_ACCEPT:
- sslErrorStr = "SSL_ERROR_WANT_ACCEPT occurred. You should never see this.";
- break;
- default:
- sslErrorStr = "Unknown SSL error";
- }
-
- // Prepend either our explicit message or a default one.
- char* str;
- if (asprintf(&str, "%s: ssl=%p: %s", message, ssl, sslErrorStr) <= 0) {
- // problem with asprintf, just throw argument message, log everything
- throwSSLExceptionStr(env, message);
- ALOGV("%s: ssl=%p: %s", message, ssl, sslErrorStr);
- freeOpenSslErrorState();
- return;
- }
-
- char* allocStr = str;
-
- // For protocol errors, SSL might have more information.
- if (sslErrorCode == SSL_ERROR_NONE || sslErrorCode == SSL_ERROR_SSL) {
- // Append each error as an additional line to the message.
- for (;;) {
- char errStr[256];
- const char* file;
- int line;
- const char* data;
- int flags;
- unsigned long err = ERR_get_error_line_data(&file, &line, &data, &flags);
- if (err == 0) {
- break;
- }
-
- ERR_error_string_n(err, errStr, sizeof(errStr));
-
- int ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)",
- (allocStr == NULL) ? "" : allocStr,
- errStr,
- file,
- line,
- (flags & ERR_TXT_STRING) ? data : "(no data)",
- flags);
-
- if (ret < 0) {
- break;
- }
-
- free(allocStr);
- allocStr = str;
- }
- // For errors during system calls, errno might be our friend.
- } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
- if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
- free(allocStr);
- allocStr = str;
- }
- // If the error code is invalid, print it.
- } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) {
- if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) {
- free(allocStr);
- allocStr = str;
- }
- }
-
- if (sslErrorCode == SSL_ERROR_SSL) {
- throwSSLProtocolExceptionStr(env, allocStr);
- } else {
- throwSSLExceptionStr(env, allocStr);
- }
-
- ALOGV("%s", allocStr);
- free(allocStr);
- freeOpenSslErrorState();
-}
-
-/**
- * Helper function that grabs the casts an ssl pointer and then checks for nullness.
- * If this function returns NULL and <code>throwIfNull</code> is
- * passed as <code>true</code>, then this function will call
- * <code>throwSSLExceptionStr</code> before returning, so in this case of
- * NULL, a caller of this function should simply return and allow JNI
- * to do its thing.
- *
- * @param env the JNI environment
- * @param ssl_address; the ssl_address pointer as an integer
- * @param throwIfNull whether to throw if the SSL pointer is NULL
- * @returns the pointer, which may be NULL
- */
-static SSL_CTX* to_SSL_CTX(JNIEnv* env, jlong ssl_ctx_address, bool throwIfNull) {
- SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
- if ((ssl_ctx == NULL) && throwIfNull) {
- JNI_TRACE("ssl_ctx == null");
- jniThrowNullPointerException(env, "ssl_ctx == null");
- }
- return ssl_ctx;
-}
-
-static SSL* to_SSL(JNIEnv* env, jlong ssl_address, bool throwIfNull) {
- SSL* ssl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
- if ((ssl == NULL) && throwIfNull) {
- JNI_TRACE("ssl == null");
- jniThrowNullPointerException(env, "ssl == null");
- }
- return ssl;
-}
-
-static SSL_SESSION* to_SSL_SESSION(JNIEnv* env, jlong ssl_session_address, bool throwIfNull) {
- SSL_SESSION* ssl_session
- = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
- if ((ssl_session == NULL) && throwIfNull) {
- JNI_TRACE("ssl_session == null");
- jniThrowNullPointerException(env, "ssl_session == null");
- }
- return ssl_session;
-}
-
-/**
- * Converts a Java byte[] to an OpenSSL BIGNUM, allocating the BIGNUM on the
- * fly. Returns true on success. If the return value is false, there is a
- * pending exception.
- */
-static bool arrayToBignum(JNIEnv* env, jbyteArray source, BIGNUM** dest) {
- JNI_TRACE("arrayToBignum(%p, %p)", source, *dest);
-
- ScopedByteArrayRO sourceBytes(env, source);
- if (sourceBytes.get() == NULL) {
- JNI_TRACE("arrayToBignum(%p) => NULL", source);
- return false;
- }
- *dest = BN_bin2bn(reinterpret_cast<const unsigned char*>(sourceBytes.get()),
- sourceBytes.size(),
- NULL);
- if (*dest == NULL) {
- jniThrowRuntimeException(env, "Conversion to BIGNUM failed");
- JNI_TRACE("arrayToBignum(%p) => threw exception", source);
- return false;
- }
-
- JNI_TRACE("arrayToBignum(%p) => %p", source, *dest);
- return true;
-}
-
-/**
- * Converts an OpenSSL BIGNUM to a Java byte[] array.
- */
-static jbyteArray bignumToArray(JNIEnv* env, const BIGNUM* source, const char* sourceName) {
- JNI_TRACE("bignumToArray(%p, %s)", source, sourceName);
-
- if (source == NULL) {
- jniThrowNullPointerException(env, sourceName);
- return NULL;
- }
-
- jbyteArray javaBytes = env->NewByteArray(BN_num_bytes(source) + 1);
- ScopedByteArrayRW bytes(env, javaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("bignumToArray(%p, %s) => NULL", source, sourceName);
- return NULL;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
-
- // Set the sign for the Java code.
- if (BN_is_negative(source)) {
- *tmp = 0xFF;
- } else {
- *tmp = 0x00;
- }
-
- if (BN_num_bytes(source) > 0 && BN_bn2bin(source, tmp + 1) <= 0) {
- throwExceptionIfNecessary(env, "bignumToArray");
- return NULL;
- }
-
- JNI_TRACE("bignumToArray(%p, %s) => %p", source, sourceName, javaBytes);
- return javaBytes;
-}
-
-/**
- * Converts various OpenSSL ASN.1 types to a jbyteArray with DER-encoded data
- * inside. The "i2d_func" function pointer is a function of the "i2d_<TYPE>"
- * from the OpenSSL ASN.1 API.
- */
-template<typename T, int (*i2d_func)(T*, unsigned char**)>
-jbyteArray ASN1ToByteArray(JNIEnv* env, T* obj) {
- if (obj == NULL) {
- jniThrowNullPointerException(env, "ASN1 input == null");
- JNI_TRACE("ASN1ToByteArray(%p) => null input", obj);
- return NULL;
- }
-
- int derLen = i2d_func(obj, NULL);
- if (derLen < 0) {
- throwExceptionIfNecessary(env, "ASN1ToByteArray");
- JNI_TRACE("ASN1ToByteArray(%p) => measurement failed", obj);
- return NULL;
- }
-
- ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(derLen));
- if (byteArray.get() == NULL) {
- JNI_TRACE("ASN1ToByteArray(%p) => creating byte array failed", obj);
- return NULL;
- }
-
- ScopedByteArrayRW bytes(env, byteArray.get());
- if (bytes.get() == NULL) {
- JNI_TRACE("ASN1ToByteArray(%p) => using byte array failed", obj);
- return NULL;
- }
-
- unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
- int ret = i2d_func(obj, &p);
- if (ret < 0) {
- throwExceptionIfNecessary(env, "ASN1ToByteArray");
- JNI_TRACE("ASN1ToByteArray(%p) => final conversion failed", obj);
- return NULL;
- }
-
- JNI_TRACE("ASN1ToByteArray(%p) => success (%d bytes written)", obj, ret);
- return byteArray.release();
-}
-
-template<typename T, T* (*d2i_func)(T**, const unsigned char**, long)>
-T* ByteArrayToASN1(JNIEnv* env, jbyteArray byteArray) {
- ScopedByteArrayRO bytes(env, byteArray);
- if (bytes.get() == NULL) {
- JNI_TRACE("ByteArrayToASN1(%p) => using byte array failed", byteArray);
- return 0;
- }
-
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
- return d2i_func(NULL, &tmp, bytes.size());
-}
-
-/**
- * Converts ASN.1 BIT STRING to a jbooleanArray.
- */
-jbooleanArray ASN1BitStringToBooleanArray(JNIEnv* env, ASN1_BIT_STRING* bitStr) {
- int size = bitStr->length * 8;
- if (bitStr->flags & ASN1_STRING_FLAG_BITS_LEFT) {
- size -= bitStr->flags & 0x07;
- }
-
- ScopedLocalRef<jbooleanArray> bitsRef(env, env->NewBooleanArray(size));
- if (bitsRef.get() == NULL) {
- return NULL;
- }
-
- ScopedBooleanArrayRW bitsArray(env, bitsRef.get());
- for (int i = 0; i < static_cast<int>(bitsArray.size()); i++) {
- bitsArray[i] = ASN1_BIT_STRING_get_bit(bitStr, i);
- }
-
- return bitsRef.release();
-}
-
-/**
- * To avoid the round-trip to ASN.1 and back in X509_dup, we just up the reference count.
- */
-static X509* X509_dup_nocopy(X509* x509) {
- CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
- return x509;
-}
-
-/**
- * BIO for InputStream
- */
-class BIO_Stream {
-public:
- BIO_Stream(jobject stream) :
- mEof(false) {
- JNIEnv* env = getEnv();
- mStream = env->NewGlobalRef(stream);
- }
-
- ~BIO_Stream() {
- JNIEnv* env = getEnv();
-
- env->DeleteGlobalRef(mStream);
- }
-
- bool isEof() const {
- JNI_TRACE("isEof? %s", mEof ? "yes" : "no");
- return mEof;
- }
-
- int flush() {
- JNIEnv* env = getEnv();
- if (env == NULL) {
- return -1;
- }
-
- env->CallVoidMethod(mStream, outputStream_flushMethod);
- if (env->ExceptionCheck()) {
- return -1;
- }
-
- return 1;
- }
-
-protected:
- jobject getStream() {
- return mStream;
- }
-
- void setEof(bool eof) {
- mEof = eof;
- }
-
- JNIEnv* getEnv() {
- JNIEnv* env;
-
- if (gJavaVM->AttachCurrentThread(&env, NULL) < 0) {
- return NULL;
- }
-
- return env;
- }
-
-private:
- jobject mStream;
- bool mEof;
-};
-
-class BIO_InputStream : public BIO_Stream {
-public:
- BIO_InputStream(jobject stream) :
- BIO_Stream(stream) {
- }
-
- int read(char *buf, int len) {
- return read_internal(buf, len, inputStream_readMethod);
- }
-
- int gets(char *buf, int len) {
- if (len > PEM_LINE_LENGTH) {
- len = PEM_LINE_LENGTH;
- }
-
- int read = read_internal(buf, len - 1, openSslInputStream_readLineMethod);
- buf[read] = '\0';
- JNI_TRACE("BIO::gets \"%s\"", buf);
- return read;
- }
-
-private:
- int read_internal(char *buf, int len, jmethodID method) {
- JNIEnv* env = getEnv();
- if (env == NULL) {
- JNI_TRACE("BIO_InputStream::read could not get JNIEnv");
- return -1;
- }
-
- ScopedLocalRef<jbyteArray> javaBytes(env, env->NewByteArray(len));
- if (javaBytes.get() == NULL) {
- JNI_TRACE("BIO_InputStream::read failed call to NewByteArray");
- return -1;
- }
-
- jint read = env->CallIntMethod(getStream(), method, javaBytes.get());
- if (env->ExceptionCheck()) {
- JNI_TRACE("BIO_InputStream::read failed call to InputStream#read");
- return -1;
- }
-
- /* Java uses -1 to indicate EOF condition. */
- if (read == -1) {
- setEof(true);
- read = 0;
- } else if (read > 0) {
- env->GetByteArrayRegion(javaBytes.get(), 0, read, reinterpret_cast<jbyte*>(buf));
- }
-
- return read;
- }
-
-public:
- /** Length of PEM-encoded line (64) plus CR plus NULL */
- static const int PEM_LINE_LENGTH = 66;
-};
-
-class BIO_OutputStream : public BIO_Stream {
-public:
- BIO_OutputStream(jobject stream) :
- BIO_Stream(stream) {
- }
-
- int write(const char *buf, int len) {
- JNIEnv* env = getEnv();
- if (env == NULL) {
- JNI_TRACE("BIO_OutputStream::write => could not get JNIEnv");
- return -1;
- }
-
- ScopedLocalRef<jbyteArray> javaBytes(env, env->NewByteArray(len));
- if (javaBytes.get() == NULL) {
- JNI_TRACE("BIO_OutputStream::write => failed call to NewByteArray");
- return -1;
- }
-
- env->SetByteArrayRegion(javaBytes.get(), 0, len, reinterpret_cast<const jbyte*>(buf));
-
- env->CallVoidMethod(getStream(), outputStream_writeMethod, javaBytes.get());
- if (env->ExceptionCheck()) {
- JNI_TRACE("BIO_OutputStream::write => failed call to OutputStream#write");
- return -1;
- }
-
- return len;
- }
-};
-
-static int bio_stream_create(BIO *b) {
- b->init = 1;
- b->num = 0;
- b->ptr = NULL;
- b->flags = 0;
- return 1;
-}
-
-static int bio_stream_destroy(BIO *b) {
- if (b == NULL) {
- return 0;
- }
-
- if (b->ptr != NULL) {
- delete static_cast<BIO_Stream*>(b->ptr);
- b->ptr = NULL;
- }
-
- b->init = 0;
- b->flags = 0;
- return 1;
-}
-
-static int bio_stream_read(BIO *b, char *buf, int len) {
- BIO_InputStream* stream = static_cast<BIO_InputStream*>(b->ptr);
- return stream->read(buf, len);
-}
-
-static int bio_stream_write(BIO *b, const char *buf, int len) {
- BIO_OutputStream* stream = static_cast<BIO_OutputStream*>(b->ptr);
- return stream->write(buf, len);
-}
-
-static int bio_stream_puts(BIO *b, const char *buf) {
- BIO_OutputStream* stream = static_cast<BIO_OutputStream*>(b->ptr);
- return stream->write(buf, strlen(buf));
-}
-
-static int bio_stream_gets(BIO *b, char *buf, int len) {
- BIO_InputStream* stream = static_cast<BIO_InputStream*>(b->ptr);
- return stream->gets(buf, len);
-}
-
-static void bio_stream_assign(BIO *b, BIO_Stream* stream) {
- b->ptr = static_cast<void*>(stream);
-}
-
-static long bio_stream_ctrl(BIO *b, int cmd, long, void *) {
- BIO_Stream* stream = static_cast<BIO_Stream*>(b->ptr);
-
- switch (cmd) {
- case BIO_CTRL_EOF:
- return stream->isEof() ? 1 : 0;
- case BIO_CTRL_FLUSH:
- return stream->flush();
- default:
- return 0;
- }
-}
-
-static BIO_METHOD stream_bio_method = {
- ( 100 | 0x0400 ), /* source/sink BIO */
- "InputStream/OutputStream BIO",
- bio_stream_write, /* bio_write */
- bio_stream_read, /* bio_read */
- bio_stream_puts, /* bio_puts */
- bio_stream_gets, /* bio_gets */
- bio_stream_ctrl, /* bio_ctrl */
- bio_stream_create, /* bio_create */
- bio_stream_destroy, /* bio_free */
- NULL, /* no bio_callback_ctrl */
-};
-
-/**
- * Copied from libnativehelper NetworkUtilites.cpp
- */
-static bool setBlocking(int fd, bool blocking) {
- int flags = fcntl(fd, F_GETFL);
- if (flags == -1) {
- return false;
- }
-
- if (!blocking) {
- flags |= O_NONBLOCK;
- } else {
- flags &= ~O_NONBLOCK;
- }
-
- int rc = fcntl(fd, F_SETFL, flags);
- return (rc != -1);
-}
-
-/**
- * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
- * suppose there are not many other ways to do this on a Linux system (modulo
- * isomorphism).
- */
-#define MUTEX_TYPE pthread_mutex_t
-#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
-#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
-#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
-#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
-#define THREAD_ID pthread_self()
-#define THROW_SSLEXCEPTION (-2)
-#define THROW_SOCKETTIMEOUTEXCEPTION (-3)
-#define THROWN_EXCEPTION (-4)
-
-static MUTEX_TYPE* mutex_buf = NULL;
-
-static void locking_function(int mode, int n, const char*, int) {
- if (mode & CRYPTO_LOCK) {
- MUTEX_LOCK(mutex_buf[n]);
- } else {
- MUTEX_UNLOCK(mutex_buf[n]);
- }
-}
-
-static unsigned long id_function(void) {
- return ((unsigned long)THREAD_ID);
-}
-
-int THREAD_setup(void) {
- mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
- if (!mutex_buf) {
- return 0;
- }
-
- for (int i = 0; i < CRYPTO_num_locks(); ++i) {
- MUTEX_SETUP(mutex_buf[i]);
- }
-
- CRYPTO_set_id_callback(id_function);
- CRYPTO_set_locking_callback(locking_function);
-
- return 1;
-}
-
-int THREAD_cleanup(void) {
- if (!mutex_buf) {
- return 0;
- }
-
- CRYPTO_set_id_callback(NULL);
- CRYPTO_set_locking_callback(NULL);
-
- for (int i = 0; i < CRYPTO_num_locks( ); i++) {
- MUTEX_CLEANUP(mutex_buf[i]);
- }
-
- free(mutex_buf);
- mutex_buf = NULL;
-
- return 1;
-}
-
-/**
- * Initialization phase for every OpenSSL job: Loads the Error strings, the
- * crypto algorithms and reset the OpenSSL library
- */
-static void NativeCrypto_clinit(JNIEnv*, jclass)
-{
- SSL_load_error_strings();
- ERR_load_crypto_strings();
- SSL_library_init();
- OpenSSL_add_all_algorithms();
- THREAD_setup();
-}
-
-static void NativeCrypto_ENGINE_load_dynamic(JNIEnv*, jclass) {
- JNI_TRACE("ENGINE_load_dynamic()");
-
- ENGINE_load_dynamic();
-}
-
-static jlong NativeCrypto_ENGINE_by_id(JNIEnv* env, jclass, jstring idJava) {
- JNI_TRACE("ENGINE_by_id(%p)", idJava);
-
- ScopedUtfChars id(env, idJava);
- if (id.c_str() == NULL) {
- JNI_TRACE("ENGINE_by_id(%p) => id == null", idJava);
- return 0;
- }
- JNI_TRACE("ENGINE_by_id(\"%s\")", id.c_str());
-
- ENGINE* e = ENGINE_by_id(id.c_str());
- if (e == NULL) {
- freeOpenSslErrorState();
- }
-
- JNI_TRACE("ENGINE_by_id(\"%s\") => %p", id.c_str(), e);
- return reinterpret_cast<uintptr_t>(e);
-}
-
-static jint NativeCrypto_ENGINE_add(JNIEnv* env, jclass, jlong engineRef) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_add(%p)", e);
-
- if (e == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
- return 0;
- }
-
- int ret = ENGINE_add(e);
-
- /*
- * We tolerate errors, because the most likely error is that
- * the ENGINE is already in the list.
- */
- freeOpenSslErrorState();
-
- JNI_TRACE("ENGINE_add(%p) => %d", e, ret);
- return ret;
-}
-
-static jint NativeCrypto_ENGINE_init(JNIEnv* env, jclass, jlong engineRef) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_init(%p)", e);
-
- if (e == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
- return 0;
- }
-
- int ret = ENGINE_init(e);
- JNI_TRACE("ENGINE_init(%p) => %d", e, ret);
- return ret;
-}
-
-static jint NativeCrypto_ENGINE_finish(JNIEnv* env, jclass, jlong engineRef) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_finish(%p)", e);
-
- if (e == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
- return 0;
- }
-
- int ret = ENGINE_finish(e);
- JNI_TRACE("ENGINE_finish(%p) => %d", e, ret);
- return ret;
-}
-
-static jint NativeCrypto_ENGINE_free(JNIEnv* env, jclass, jlong engineRef) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_free(%p)", e);
-
- if (e == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
- return 0;
- }
-
- int ret = ENGINE_free(e);
- JNI_TRACE("ENGINE_free(%p) => %d", e, ret);
- return ret;
-}
-
-static jlong NativeCrypto_ENGINE_load_private_key(JNIEnv* env, jclass, jlong engineRef,
- jstring idJava) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_load_private_key(%p, %p)", e, idJava);
-
- ScopedUtfChars id(env, idJava);
- if (id.c_str() == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "id == NULL");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(ENGINE_load_private_key(e, id.c_str(), NULL, NULL));
- if (pkey.get() == NULL) {
- throwExceptionIfNecessary(env, "ENGINE_load_private_key");
- return 0;
- }
-
- JNI_TRACE("ENGINE_load_private_key(%p, %p) => %p", e, idJava, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jstring NativeCrypto_ENGINE_get_id(JNIEnv* env, jclass, jlong engineRef)
-{
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_get_id(%p)", e);
-
- if (e == NULL) {
- jniThrowNullPointerException(env, "engine == null");
- JNI_TRACE("ENGINE_get_id(%p) => engine == null", e);
- return NULL;
- }
-
- const char *id = ENGINE_get_id(e);
- ScopedLocalRef<jstring> idJava(env, env->NewStringUTF(id));
-
- JNI_TRACE("ENGINE_get_id(%p) => \"%s\"", e, id);
- return idJava.release();
-}
-
-static jint NativeCrypto_ENGINE_ctrl_cmd_string(JNIEnv* env, jclass, jlong engineRef,
- jstring cmdJava, jstring argJava, jint cmd_optional)
-{
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, %p, %p, %d)", e, cmdJava, argJava, cmd_optional);
-
- if (e == NULL) {
- jniThrowNullPointerException(env, "engine == null");
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, %p, %p, %d) => engine == null", e, cmdJava, argJava,
- cmd_optional);
- return 0;
- }
-
- ScopedUtfChars cmdChars(env, cmdJava);
- if (cmdChars.c_str() == NULL) {
- return 0;
- }
-
- UniquePtr<ScopedUtfChars> arg;
- const char* arg_c_str = NULL;
- if (argJava != NULL) {
- arg.reset(new ScopedUtfChars(env, argJava));
- arg_c_str = arg->c_str();
- if (arg_c_str == NULL) {
- return 0;
- }
- }
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d)", e, cmdChars.c_str(), arg_c_str,
- cmd_optional);
-
- int ret = ENGINE_ctrl_cmd_string(e, cmdChars.c_str(), arg_c_str, cmd_optional);
- if (ret != 1) {
- throwExceptionIfNecessary(env, "ENGINE_ctrl_cmd_string");
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d) => threw error", e,
- cmdChars.c_str(), arg_c_str, cmd_optional);
- return 0;
- }
-
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d) => %d", e, cmdChars.c_str(),
- arg_c_str, cmd_optional, ret);
- return ret;
-}
-
-/**
- * public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
- * byte[] pub_key, byte[] priv_key);
- */
-static jlong NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass,
- jbyteArray p, jbyteArray q, jbyteArray g,
- jbyteArray pub_key, jbyteArray priv_key) {
- JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p)",
- p, q, g, pub_key, priv_key);
-
- Unique_DSA dsa(DSA_new());
- if (dsa.get() == NULL) {
- jniThrowRuntimeException(env, "DSA_new failed");
- return 0;
- }
-
- if (!arrayToBignum(env, p, &dsa->p)) {
- return 0;
- }
-
- if (!arrayToBignum(env, q, &dsa->q)) {
- return 0;
- }
-
- if (!arrayToBignum(env, g, &dsa->g)) {
- return 0;
- }
-
- if (pub_key != NULL && !arrayToBignum(env, pub_key, &dsa->pub_key)) {
- return 0;
- }
-
- if (priv_key != NULL && !arrayToBignum(env, priv_key, &dsa->priv_key)) {
- return 0;
- }
-
- if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL
- || (dsa->pub_key == NULL && dsa->priv_key == NULL)) {
- jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- jniThrowRuntimeException(env, "EVP_PKEY_new failed");
- return 0;
- }
- if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
- jniThrowRuntimeException(env, "EVP_PKEY_assign_DSA failed");
- return 0;
- }
- OWNERSHIP_TRANSFERRED(dsa);
- JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p) => %p",
- p, q, g, pub_key, priv_key, pkey.get());
- return reinterpret_cast<jlong>(pkey.release());
-}
-
-/**
- * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
- */
-static jlong NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass,
- jbyteArray n, jbyteArray e, jbyteArray d,
- jbyteArray p, jbyteArray q,
- jbyteArray dmp1, jbyteArray dmq1,
- jbyteArray iqmp) {
- JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p, dmp1=%p, dmq1=%p, iqmp=%p)",
- n, e, d, p, q, dmp1, dmq1, iqmp);
-
- Unique_RSA rsa(RSA_new());
- if (rsa.get() == NULL) {
- jniThrowRuntimeException(env, "RSA_new failed");
- return 0;
- }
-
- if (e == NULL && d == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "e == NULL && d == NULL");
- JNI_TRACE("NativeCrypto_EVP_PKEY_new_RSA => e == NULL && d == NULL");
- return 0;
- }
-
- if (!arrayToBignum(env, n, &rsa->n)) {
- return 0;
- }
-
- if (e != NULL && !arrayToBignum(env, e, &rsa->e)) {
- return 0;
- }
-
- if (d != NULL && !arrayToBignum(env, d, &rsa->d)) {
- return 0;
- }
-
- if (p != NULL && !arrayToBignum(env, p, &rsa->p)) {
- return 0;
- }
-
- if (q != NULL && !arrayToBignum(env, q, &rsa->q)) {
- return 0;
- }
-
- if (dmp1 != NULL && !arrayToBignum(env, dmp1, &rsa->dmp1)) {
- return 0;
- }
-
- if (dmq1 != NULL && !arrayToBignum(env, dmq1, &rsa->dmq1)) {
- return 0;
- }
-
- if (iqmp != NULL && !arrayToBignum(env, iqmp, &rsa->iqmp)) {
- return 0;
- }
-
-#ifdef WITH_JNI_TRACE
- if (p != NULL && q != NULL) {
- int check = RSA_check_key(rsa.get());
- JNI_TRACE("EVP_PKEY_new_RSA(...) RSA_check_key returns %d", check);
- }
-#endif
-
- if (rsa->n == NULL || (rsa->e == NULL && rsa->d == NULL)) {
- jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
- return 0;
- }
-
- /*
- * If the private exponent is available, there is the potential to do signing
- * operations. If the public exponent is also available, OpenSSL will do RSA
- * blinding. Enable it if possible.
- */
- if (rsa->d != NULL) {
- if (rsa->e != NULL) {
- JNI_TRACE("EVP_PKEY_new_RSA(...) enabling RSA blinding => %p", rsa.get());
- RSA_blinding_on(rsa.get(), NULL);
- } else {
- JNI_TRACE("EVP_PKEY_new_RSA(...) disabling RSA blinding => %p", rsa.get());
- RSA_blinding_off(rsa.get());
- }
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- jniThrowRuntimeException(env, "EVP_PKEY_new failed");
- return 0;
- }
- if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
- jniThrowRuntimeException(env, "EVP_PKEY_new failed");
- return 0;
- }
- OWNERSHIP_TRANSFERRED(rsa);
- JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p dmp1=%p, dmq1=%p, iqmp=%p) => %p",
- n, e, d, p, q, dmp1, dmq1, iqmp, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jlong NativeCrypto_EVP_PKEY_new_EC_KEY(JNIEnv* env, jclass, jlong groupRef,
- jlong pubkeyRef, jbyteArray keyJavaBytes) {
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- const EC_POINT* pubkey = reinterpret_cast<const EC_POINT*>(pubkeyRef);
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p)", group, pubkey, keyJavaBytes);
-
- Unique_BIGNUM key(NULL);
- if (keyJavaBytes != NULL) {
- BIGNUM* keyRef;
- if (!arrayToBignum(env, keyJavaBytes, &keyRef)) {
- return 0;
- }
- key.reset(keyRef);
- }
-
- Unique_EC_KEY eckey(EC_KEY_new());
- if (eckey.get() == NULL) {
- jniThrowRuntimeException(env, "EC_KEY_new failed");
- return 0;
- }
-
- if (EC_KEY_set_group(eckey.get(), group) != 1) {
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) > EC_KEY_set_group failed", group, pubkey,
- keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_set_group");
- return 0;
- }
-
- if (pubkey != NULL) {
- if (EC_KEY_set_public_key(eckey.get(), pubkey) != 1) {
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => EC_KEY_set_private_key failed", group,
- pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_set_public_key");
- return 0;
- }
- }
-
- if (key.get() != NULL) {
- if (EC_KEY_set_private_key(eckey.get(), key.get()) != 1) {
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => EC_KEY_set_private_key failed", group,
- pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_set_private_key");
- return 0;
- }
- if (pubkey == NULL) {
- Unique_EC_POINT calcPubkey(EC_POINT_new(group));
- if (!EC_POINT_mul(group, calcPubkey.get(), key.get(), NULL, NULL, NULL)) {
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => can't calulate public key", group,
- pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_set_private_key");
- return 0;
- }
- EC_KEY_set_public_key(eckey.get(), calcPubkey.get());
- }
- }
-
- if (!EC_KEY_check_key(eckey.get())) {
- JNI_TRACE("EVP_KEY_new_EC_KEY(%p, %p, %p) => invalid key created", group, pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_check_key");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- JNI_TRACE("EVP_PKEY_new_EC(%p, %p, %p) => threw error", group, pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EVP_PKEY_new failed");
- return 0;
- }
- if (EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get()) != 1) {
- JNI_TRACE("EVP_PKEY_new_EC(%p, %p, %p) => threw error", group, pubkey, keyJavaBytes);
- jniThrowRuntimeException(env, "EVP_PKEY_assign_EC_KEY failed");
- return 0;
- }
- OWNERSHIP_TRANSFERRED(eckey);
-
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => %p", group, pubkey, keyJavaBytes, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jlong NativeCrypto_EVP_PKEY_new_mac_key(JNIEnv* env, jclass, jint pkeyType,
- jbyteArray keyJavaBytes)
-{
- JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p)", pkeyType, keyJavaBytes);
-
- ScopedByteArrayRO key(env, keyJavaBytes);
- if (key.get() == NULL) {
- return 0;
- }
-
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(key.get());
- Unique_EVP_PKEY pkey(EVP_PKEY_new_mac_key(pkeyType, (ENGINE *) NULL, tmp, key.size()));
- if (pkey.get() == NULL) {
- JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p) => threw error", pkeyType, keyJavaBytes);
- throwExceptionIfNecessary(env, "ENGINE_load_private_key");
- return 0;
- }
-
- JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p) => %p", pkeyType, keyJavaBytes, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static int NativeCrypto_EVP_PKEY_type(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_type(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- int result = EVP_PKEY_type(pkey->type);
- JNI_TRACE("EVP_PKEY_type(%p) => %d", pkey, result);
- return result;
-}
-
-/**
- * private static native int EVP_PKEY_size(int pkey);
- */
-static int NativeCrypto_EVP_PKEY_size(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_size(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- int result = EVP_PKEY_size(pkey);
- JNI_TRACE("EVP_PKEY_size(%p) => %d", pkey, result);
- return result;
-}
-
-static jstring NativeCrypto_EVP_PKEY_print_public(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_print_public(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return NULL;
- }
-
- Unique_BIO buffer(BIO_new(BIO_s_mem()));
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate BIO");
- return NULL;
- }
-
- if (EVP_PKEY_print_public(buffer.get(), pkey, 0, (ASN1_PCTX*) NULL) != 1) {
- throwExceptionIfNecessary(env, "EVP_PKEY_print_public");
- return NULL;
- }
- // Null terminate this
- BIO_write(buffer.get(), "\0", 1);
-
- char *tmp;
- BIO_get_mem_data(buffer.get(), &tmp);
- jstring description = env->NewStringUTF(tmp);
-
- JNI_TRACE("EVP_PKEY_print_public(%p) => \"%s\"", pkey, tmp);
- return description;
-}
-
-static jstring NativeCrypto_EVP_PKEY_print_private(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_print_private(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return NULL;
- }
-
- Unique_BIO buffer(BIO_new(BIO_s_mem()));
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate BIO");
- return NULL;
- }
-
- if (EVP_PKEY_print_private(buffer.get(), pkey, 0, (ASN1_PCTX*) NULL) != 1) {
- throwExceptionIfNecessary(env, "EVP_PKEY_print_private");
- return NULL;
- }
- // Null terminate this
- BIO_write(buffer.get(), "\0", 1);
-
- char *tmp;
- BIO_get_mem_data(buffer.get(), &tmp);
- jstring description = env->NewStringUTF(tmp);
-
- JNI_TRACE("EVP_PKEY_print_private(%p) => \"%s\"", pkey, tmp);
- return description;
-}
-
-static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_free(%p)", pkey);
-
- if (pkey != NULL) {
- EVP_PKEY_free(pkey);
- }
-}
-
-static jint NativeCrypto_EVP_PKEY_cmp(JNIEnv* env, jclass, jlong pkey1Ref, jlong pkey2Ref) {
- EVP_PKEY* pkey1 = reinterpret_cast<EVP_PKEY*>(pkey1Ref);
- EVP_PKEY* pkey2 = reinterpret_cast<EVP_PKEY*>(pkey2Ref);
- JNI_TRACE("EVP_PKEY_cmp(%p, %p)", pkey1, pkey2);
-
- if (pkey1 == NULL) {
- JNI_TRACE("EVP_PKEY_cmp(%p, %p) => failed pkey1 == NULL", pkey1, pkey2);
- jniThrowNullPointerException(env, "pkey1 == NULL");
- return -1;
- } else if (pkey2 == NULL) {
- JNI_TRACE("EVP_PKEY_cmp(%p, %p) => failed pkey2 == NULL", pkey1, pkey2);
- jniThrowNullPointerException(env, "pkey2 == NULL");
- return -1;
- }
-
- int result = EVP_PKEY_cmp(pkey1, pkey2);
- JNI_TRACE("EVP_PKEY_cmp(%p, %p) => %d", pkey1, pkey2, result);
- return result;
-}
-
-/*
- * static native byte[] i2d_PKCS8_PRIV_KEY_INFO(int, byte[])
- */
-static jbyteArray NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("i2d_PKCS8_PRIV_KEY_INFO(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return NULL;
- }
-
- Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey));
- if (pkcs8.get() == NULL) {
- throwExceptionIfNecessary(env, "NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO");
- JNI_TRACE("key=%p i2d_PKCS8_PRIV_KEY_INFO => error from key to PKCS8", pkey);
- return NULL;
- }
-
- return ASN1ToByteArray<PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO>(env, pkcs8.get());
-}
-
-/*
- * static native int d2i_PKCS8_PRIV_KEY_INFO(byte[])
- */
-static jlong NativeCrypto_d2i_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jbyteArray keyJavaBytes) {
- JNI_TRACE("d2i_PKCS8_PRIV_KEY_INFO(%p)", keyJavaBytes);
-
- ScopedByteArrayRO bytes(env, keyJavaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => threw exception", keyJavaBytes);
- return 0;
- }
-
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
- Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &tmp, bytes.size()));
- if (pkcs8.get() == NULL) {
- throwExceptionIfNecessary(env, "d2i_PKCS8_PRIV_KEY_INFO");
- JNI_TRACE("ssl=%p d2i_PKCS8_PRIV_KEY_INFO => error from DER to PKCS8", keyJavaBytes);
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
- if (pkey.get() == NULL) {
- throwExceptionIfNecessary(env, "d2i_PKCS8_PRIV_KEY_INFO");
- JNI_TRACE("ssl=%p d2i_PKCS8_PRIV_KEY_INFO => error from PKCS8 to key", keyJavaBytes);
- return 0;
- }
-
- JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => %p", keyJavaBytes, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-/*
- * static native byte[] i2d_PUBKEY(int)
- */
-static jbyteArray NativeCrypto_i2d_PUBKEY(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("i2d_PUBKEY(%p)", pkey);
- return ASN1ToByteArray<EVP_PKEY, i2d_PUBKEY>(env, pkey);
-}
-
-/*
- * static native int d2i_PUBKEY(byte[])
- */
-static jlong NativeCrypto_d2i_PUBKEY(JNIEnv* env, jclass, jbyteArray javaBytes) {
- JNI_TRACE("d2i_PUBKEY(%p)", javaBytes);
-
- ScopedByteArrayRO bytes(env, javaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("d2i_PUBKEY(%p) => threw error", javaBytes);
- return 0;
- }
-
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
- Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, bytes.size()));
- if (pkey.get() == NULL) {
- JNI_TRACE("bytes=%p d2i_PUBKEY => threw exception", javaBytes);
- throwExceptionIfNecessary(env, "d2i_PUBKEY");
- return 0;
- }
-
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-/*
- * public static native int RSA_generate_key(int modulusBits, byte[] publicExponent);
- */
-static jlong NativeCrypto_RSA_generate_key_ex(JNIEnv* env, jclass, jint modulusBits,
- jbyteArray publicExponent) {
- JNI_TRACE("RSA_generate_key_ex(%d, %p)", modulusBits, publicExponent);
-
- BIGNUM* eRef;
- if (!arrayToBignum(env, publicExponent, &eRef)) {
- return 0;
- }
- Unique_BIGNUM e(eRef);
-
- Unique_RSA rsa(RSA_new());
- if (rsa.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate RSA key");
- return 0;
- }
-
- if (RSA_generate_key_ex(rsa.get(), modulusBits, e.get(), NULL) < 0) {
- throwExceptionIfNecessary(env, "RSA_generate_key_ex");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- jniThrowRuntimeException(env, "RSA_generate_key_ex failed");
- return 0;
- }
-
- if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
- jniThrowRuntimeException(env, "RSA_generate_key_ex failed");
- return 0;
- }
-
- OWNERSHIP_TRANSFERRED(rsa);
- JNI_TRACE("RSA_generate_key_ex(n=%d, e=%p) => %p", modulusBits, publicExponent, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jint NativeCrypto_RSA_size(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("RSA_size(%p)", pkey);
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- jniThrowRuntimeException(env, "RSA_size failed");
- return 0;
- }
-
- return static_cast<jint>(RSA_size(rsa.get()));
-}
-
-typedef int RSACryptOperation(int flen, const unsigned char* from, unsigned char* to, RSA* rsa,
- int padding);
-
-static jint RSA_crypt_operation(RSACryptOperation operation,
- const char* caller __attribute__ ((unused)), JNIEnv* env, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("%s(%d, %p, %p, %p)", caller, flen, fromJavaBytes, toJavaBytes, pkey);
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- return -1;
- }
-
- ScopedByteArrayRO from(env, fromJavaBytes);
- if (from.get() == NULL) {
- return -1;
- }
-
- ScopedByteArrayRW to(env, toJavaBytes);
- if (to.get() == NULL) {
- return -1;
- }
-
- int resultSize = operation(static_cast<int>(flen),
- reinterpret_cast<const unsigned char*>(from.get()),
- reinterpret_cast<unsigned char*>(to.get()), rsa.get(), padding);
- if (resultSize == -1) {
- JNI_TRACE("%s => failed", caller);
- throwExceptionIfNecessary(env, "RSA_crypt_operation");
- return -1;
- }
-
- JNI_TRACE("%s(%d, %p, %p, %p) => %d", caller, flen, fromJavaBytes, toJavaBytes, pkey,
- resultSize);
- return static_cast<jint>(resultSize);
-}
-
-static jint NativeCrypto_RSA_private_encrypt(JNIEnv* env, jclass, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- return RSA_crypt_operation(RSA_private_encrypt, __FUNCTION__,
- env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
-}
-static jint NativeCrypto_RSA_public_decrypt(JNIEnv* env, jclass, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- return RSA_crypt_operation(RSA_public_decrypt, __FUNCTION__,
- env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
-}
-static jint NativeCrypto_RSA_public_encrypt(JNIEnv* env, jclass, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- return RSA_crypt_operation(RSA_public_encrypt, __FUNCTION__,
- env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
-}
-static jint NativeCrypto_RSA_private_decrypt(JNIEnv* env, jclass, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- return RSA_crypt_operation(RSA_private_decrypt, __FUNCTION__,
- env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
-}
-
-/*
- * public static native byte[][] get_RSA_public_params(int);
- */
-static jobjectArray NativeCrypto_get_RSA_public_params(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("get_RSA_public_params(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return 0;
- }
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- throwExceptionIfNecessary(env, "get_RSA_public_params failed");
- return 0;
- }
-
- jobjectArray joa = env->NewObjectArray(2, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- jbyteArray n = bignumToArray(env, rsa->n, "n");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, n);
-
- jbyteArray e = bignumToArray(env, rsa->e, "e");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, e);
-
- return joa;
-}
-
-/*
- * public static native byte[][] get_RSA_private_params(int);
- */
-static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("get_RSA_public_params(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return 0;
- }
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- throwExceptionIfNecessary(env, "get_RSA_public_params failed");
- return 0;
- }
-
- jobjectArray joa = env->NewObjectArray(8, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- jbyteArray n = bignumToArray(env, rsa->n, "n");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, n);
-
- if (rsa->e != NULL) {
- jbyteArray e = bignumToArray(env, rsa->e, "e");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, e);
- }
-
- if (rsa->d != NULL) {
- jbyteArray d = bignumToArray(env, rsa->d, "d");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 2, d);
- }
-
- if (rsa->p != NULL) {
- jbyteArray p = bignumToArray(env, rsa->p, "p");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 3, p);
- }
-
- if (rsa->q != NULL) {
- jbyteArray q = bignumToArray(env, rsa->q, "q");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 4, q);
- }
-
- if (rsa->dmp1 != NULL) {
- jbyteArray dmp1 = bignumToArray(env, rsa->dmp1, "dmp1");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 5, dmp1);
- }
-
- if (rsa->dmq1 != NULL) {
- jbyteArray dmq1 = bignumToArray(env, rsa->dmq1, "dmq1");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 6, dmq1);
- }
-
- if (rsa->iqmp != NULL) {
- jbyteArray iqmp = bignumToArray(env, rsa->iqmp, "iqmp");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 7, iqmp);
- }
-
- return joa;
-}
-
-/*
- * public static native int DSA_generate_key(int, byte[]);
- */
-static jlong NativeCrypto_DSA_generate_key(JNIEnv* env, jclass, jint primeBits,
- jbyteArray seedJavaBytes, jbyteArray gBytes, jbyteArray pBytes, jbyteArray qBytes) {
- JNI_TRACE("DSA_generate_key(%d, %p, %p, %p, %p)", primeBits, seedJavaBytes,
- gBytes, pBytes, qBytes);
-
- UniquePtr<unsigned char[]> seedPtr;
- unsigned long seedSize = 0;
- if (seedJavaBytes != NULL) {
- ScopedByteArrayRO seed(env, seedJavaBytes);
- if (seed.get() == NULL) {
- return 0;
- }
-
- seedSize = seed.size();
- seedPtr.reset(new unsigned char[seedSize]);
-
- memcpy(seedPtr.get(), seed.get(), seedSize);
- }
-
- Unique_DSA dsa(DSA_new());
- if (dsa.get() == NULL) {
- JNI_TRACE("DSA_generate_key failed");
- jniThrowOutOfMemory(env, "Unable to allocate DSA key");
- freeOpenSslErrorState();
- return 0;
- }
-
- if (gBytes != NULL && pBytes != NULL && qBytes != NULL) {
- JNI_TRACE("DSA_generate_key parameters specified");
-
- if (!arrayToBignum(env, gBytes, &dsa->g)) {
- return 0;
- }
-
- if (!arrayToBignum(env, pBytes, &dsa->p)) {
- return 0;
- }
-
- if (!arrayToBignum(env, qBytes, &dsa->q)) {
- return 0;
- }
- } else {
- JNI_TRACE("DSA_generate_key generating parameters");
-
- if (!DSA_generate_parameters_ex(dsa.get(), primeBits, seedPtr.get(), seedSize, NULL, NULL, NULL)) {
- JNI_TRACE("DSA_generate_key => param generation failed");
- throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_parameters_ex failed");
- return 0;
- }
- }
-
- if (!DSA_generate_key(dsa.get())) {
- JNI_TRACE("DSA_generate_key failed");
- throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_key failed");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- JNI_TRACE("DSA_generate_key failed");
- jniThrowRuntimeException(env, "NativeCrypto_DSA_generate_key failed");
- freeOpenSslErrorState();
- return 0;
- }
-
- if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
- JNI_TRACE("DSA_generate_key failed");
- throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_key failed");
- return 0;
- }
-
- OWNERSHIP_TRANSFERRED(dsa);
- JNI_TRACE("DSA_generate_key(n=%d, e=%p) => %p", primeBits, seedPtr.get(), pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-/*
- * public static native byte[][] get_DSA_params(int);
- */
-static jobjectArray NativeCrypto_get_DSA_params(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("get_DSA_params(%p)", pkey);
-
- Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
- if (dsa.get() == NULL) {
- throwExceptionIfNecessary(env, "get_DSA_params failed");
- return 0;
- }
-
- jobjectArray joa = env->NewObjectArray(5, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- if (dsa->g != NULL) {
- jbyteArray g = bignumToArray(env, dsa->g, "g");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, g);
- }
-
- if (dsa->p != NULL) {
- jbyteArray p = bignumToArray(env, dsa->p, "p");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, p);
- }
-
- if (dsa->q != NULL) {
- jbyteArray q = bignumToArray(env, dsa->q, "q");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 2, q);
- }
-
- if (dsa->pub_key != NULL) {
- jbyteArray pub_key = bignumToArray(env, dsa->pub_key, "pub_key");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 3, pub_key);
- }
-
- if (dsa->priv_key != NULL) {
- jbyteArray priv_key = bignumToArray(env, dsa->priv_key, "priv_key");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 4, priv_key);
- }
-
- return joa;
-}
-
-#define EC_CURVE_GFP 1
-#define EC_CURVE_GF2M 2
-
-/**
- * Return group type or 0 if unknown group.
- * EC_GROUP_GFP or EC_GROUP_GF2M
- */
-static int get_EC_GROUP_type(const EC_GROUP* group)
-{
- const EC_METHOD* method = EC_GROUP_method_of(group);
- if (method == EC_GFp_nist_method()
- || method == EC_GFp_mont_method()
- || method == EC_GFp_simple_method()) {
- return EC_CURVE_GFP;
- } else if (method == EC_GF2m_simple_method()) {
- return EC_CURVE_GF2M;
- }
-
- return 0;
-}
-
-static jlong NativeCrypto_EC_GROUP_new_by_curve_name(JNIEnv* env, jclass, jstring curveNameJava)
-{
- JNI_TRACE("EC_GROUP_new_by_curve_name(%p)", curveNameJava);
-
- ScopedUtfChars curveName(env, curveNameJava);
- if (curveName.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("EC_GROUP_new_by_curve_name(%s)", curveName.c_str());
-
- int nid = OBJ_sn2nid(curveName.c_str());
- if (nid == NID_undef) {
- JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => unknown NID name", curveName.c_str());
- return 0;
- }
-
- EC_GROUP* group = EC_GROUP_new_by_curve_name(nid);
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => unknown NID %d", curveName.c_str(), nid);
- freeOpenSslErrorState();
- return 0;
- }
-
- JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => %p", curveName.c_str(), group);
- return reinterpret_cast<uintptr_t>(group);
-}
-
-static void NativeCrypto_EC_GROUP_set_asn1_flag(JNIEnv* env, jclass, jlong groupRef,
- jint flag)
-{
- EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_set_asn1_flag(%p, %d)", group, flag);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_set_asn1_flag => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return;
- }
-
- EC_GROUP_set_asn1_flag(group, flag);
- JNI_TRACE("EC_GROUP_set_asn1_flag(%p, %d) => success", group, flag);
-}
-
-static void NativeCrypto_EC_GROUP_set_point_conversion_form(JNIEnv* env, jclass,
- jlong groupRef, jint form)
-{
- EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_set_point_conversion_form(%p, %d)", group, form);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_set_point_conversion_form => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return;
- }
-
- EC_GROUP_set_point_conversion_form(group, static_cast<point_conversion_form_t>(form));
- JNI_TRACE("EC_GROUP_set_point_conversion_form(%p, %d) => success", group, form);
-}
-
-static jlong NativeCrypto_EC_GROUP_new_curve(JNIEnv* env, jclass, jint type, jbyteArray pJava,
- jbyteArray aJava, jbyteArray bJava)
-{
- JNI_TRACE("EC_GROUP_new_curve(%d, %p, %p, %p)", type, pJava, aJava, bJava);
-
- BIGNUM* pRef;
- if (!arrayToBignum(env, pJava, &pRef)) {
- return 0;
- }
- Unique_BIGNUM p(pRef);
-
- BIGNUM* aRef;
- if (!arrayToBignum(env, aJava, &aRef)) {
- return 0;
- }
- Unique_BIGNUM a(aRef);
-
- BIGNUM* bRef;
- if (!arrayToBignum(env, bJava, &bRef)) {
- return 0;
- }
- Unique_BIGNUM b(bRef);
-
- EC_GROUP* group;
- switch (type) {
- case EC_CURVE_GFP:
- group = EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), (BN_CTX*) NULL);
- break;
- case EC_CURVE_GF2M:
- group = EC_GROUP_new_curve_GF2m(p.get(), a.get(), b.get(), (BN_CTX*) NULL);
- break;
- default:
- jniThrowRuntimeException(env, "invalid group");
- return 0;
- }
-
- if (group == NULL) {
- throwExceptionIfNecessary(env, "EC_GROUP_new_curve");
- }
-
- JNI_TRACE("EC_GROUP_new_curve(%d, %p, %p, %p) => %p", type, pJava, aJava, bJava, group);
- return reinterpret_cast<uintptr_t>(group);
-}
-
-static jlong NativeCrypto_EC_GROUP_dup(JNIEnv* env, jclass, jlong groupRef) {
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_dup(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_dup => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return 0;
- }
-
- EC_GROUP* groupDup = EC_GROUP_dup(group);
- JNI_TRACE("EC_GROUP_dup(%p) => %p", group, groupDup);
- return reinterpret_cast<uintptr_t>(groupDup);
-}
-
-static jstring NativeCrypto_EC_GROUP_get_curve_name(JNIEnv* env, jclass, jlong groupRef) {
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_curve_name(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_get_curve_name => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return 0;
- }
-
- int nid = EC_GROUP_get_curve_name(group);
- if (nid == NID_undef) {
- JNI_TRACE("EC_GROUP_get_curve_name(%p) => unnamed curve", group);
- return NULL;
- }
-
- const char* shortName = OBJ_nid2sn(nid);
- JNI_TRACE("EC_GROUP_get_curve_name(%p) => \"%s\"", group, shortName);
- return env->NewStringUTF(shortName);
-}
-
-static jobjectArray NativeCrypto_EC_GROUP_get_curve(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_curve(%p)", group);
-
- Unique_BIGNUM p(BN_new());
- Unique_BIGNUM a(BN_new());
- Unique_BIGNUM b(BN_new());
-
- int ret;
- switch (get_EC_GROUP_type(group)) {
- case EC_CURVE_GFP:
- ret = EC_GROUP_get_curve_GFp(group, p.get(), a.get(), b.get(), (BN_CTX*) NULL);
- break;
- case EC_CURVE_GF2M:
- ret = EC_GROUP_get_curve_GF2m(group, p.get(), a.get(), b.get(), (BN_CTX*)NULL);
- break;
- default:
- jniThrowRuntimeException(env, "invalid group");
- return NULL;
- }
- if (ret != 1) {
- throwExceptionIfNecessary(env, "EC_GROUP_get_curve");
- return NULL;
- }
-
- jobjectArray joa = env->NewObjectArray(3, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- jbyteArray pArray = bignumToArray(env, p.get(), "p");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, pArray);
-
- jbyteArray aArray = bignumToArray(env, a.get(), "a");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, aArray);
-
- jbyteArray bArray = bignumToArray(env, b.get(), "b");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 2, bArray);
-
- JNI_TRACE("EC_GROUP_get_curve(%p) => %p", group, joa);
- return joa;
-}
-
-static jbyteArray NativeCrypto_EC_GROUP_get_order(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_order(%p)", group);
-
- Unique_BIGNUM order(BN_new());
- if (order.get() == NULL) {
- JNI_TRACE("EC_GROUP_get_order(%p) => can't create BN", group);
- jniThrowOutOfMemory(env, "BN_new");
- return NULL;
- }
-
- if (EC_GROUP_get_order(group, order.get(), NULL) != 1) {
- JNI_TRACE("EC_GROUP_get_order(%p) => threw error", group);
- throwExceptionIfNecessary(env, "EC_GROUP_get_order");
- return NULL;
- }
-
- jbyteArray orderArray = bignumToArray(env, order.get(), "order");
- if (env->ExceptionCheck()) {
- return NULL;
- }
-
- JNI_TRACE("EC_GROUP_get_order(%p) => %p", group, orderArray);
- return orderArray;
-}
-
-static jint NativeCrypto_EC_GROUP_get_degree(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_degree(%p)", group);
-
- jint degree = EC_GROUP_get_degree(group);
- if (degree == 0) {
- JNI_TRACE("EC_GROUP_get_degree(%p) => unsupported", group);
- jniThrowRuntimeException(env, "not supported");
- return 0;
- }
-
- JNI_TRACE("EC_GROUP_get_degree(%p) => %d", group, degree);
- return degree;
-}
-
-static jbyteArray NativeCrypto_EC_GROUP_get_cofactor(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_cofactor(%p)", group);
-
- Unique_BIGNUM cofactor(BN_new());
- if (cofactor.get() == NULL) {
- JNI_TRACE("EC_GROUP_get_cofactor(%p) => can't create BN", group);
- jniThrowOutOfMemory(env, "BN_new");
- return NULL;
- }
-
- if (EC_GROUP_get_cofactor(group, cofactor.get(), NULL) != 1) {
- JNI_TRACE("EC_GROUP_get_cofactor(%p) => threw error", group);
- throwExceptionIfNecessary(env, "EC_GROUP_get_cofactor");
- return NULL;
- }
-
- jbyteArray cofactorArray = bignumToArray(env, cofactor.get(), "cofactor");
- if (env->ExceptionCheck()) {
- return NULL;
- }
-
- JNI_TRACE("EC_GROUP_get_cofactor(%p) => %p", group, cofactorArray);
- return cofactorArray;
-}
-
-static jint NativeCrypto_get_EC_GROUP_type(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("get_EC_GROUP_type(%p)", group);
-
- int type = get_EC_GROUP_type(group);
- if (type == 0) {
- JNI_TRACE("get_EC_GROUP_type(%p) => curve type", group);
- jniThrowRuntimeException(env, "unknown curve type");
- } else {
- JNI_TRACE("get_EC_GROUP_type(%p) => %d", group, type);
- }
- return type;
-}
-
-static void NativeCrypto_EC_GROUP_clear_free(JNIEnv* env, jclass, jlong groupRef)
-{
- EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_clear_free(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_clear_free => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return;
- }
-
- EC_GROUP_clear_free(group);
- JNI_TRACE("EC_GROUP_clear_free(%p) => success", group);
-}
-
-static jboolean NativeCrypto_EC_GROUP_cmp(JNIEnv* env, jclass, jlong group1Ref, jlong group2Ref)
-{
- const EC_GROUP* group1 = reinterpret_cast<const EC_GROUP*>(group1Ref);
- const EC_GROUP* group2 = reinterpret_cast<const EC_GROUP*>(group2Ref);
- JNI_TRACE("EC_GROUP_cmp(%p, %p)", group1, group2);
-
- if (group1 == NULL || group2 == NULL) {
- JNI_TRACE("EC_GROUP_cmp(%p, %p) => group1 == null || group2 == null", group1, group2);
- jniThrowNullPointerException(env, "group1 == null || group2 == null");
- return false;
- }
-
- int ret = EC_GROUP_cmp(group1, group2, (BN_CTX*)NULL);
-
- JNI_TRACE("ECP_GROUP_cmp(%p, %p) => %d", group1, group2, ret);
- return ret == 0;
-}
-
-static void NativeCrypto_EC_GROUP_set_generator(JNIEnv* env, jclass, jlong groupRef, jlong pointRef, jbyteArray njavaBytes, jbyteArray hjavaBytes)
-{
- EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
- const EC_POINT* point = reinterpret_cast<const EC_POINT*>(pointRef);
- JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p)", group, point, njavaBytes, hjavaBytes);
-
- if (group == NULL || point == NULL) {
- JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p) => group == null || point == null",
- group, point, njavaBytes, hjavaBytes);
- jniThrowNullPointerException(env, "group == null || point == null");
- return;
- }
-
- BIGNUM* nRef;
- if (!arrayToBignum(env, njavaBytes, &nRef)) {
- return;
- }
- Unique_BIGNUM n(nRef);
-
- BIGNUM* hRef;
- if (!arrayToBignum(env, hjavaBytes, &hRef)) {
- return;
- }
- Unique_BIGNUM h(hRef);
-
- int ret = EC_GROUP_set_generator(group, point, n.get(), h.get());
- if (ret == 0) {
- throwExceptionIfNecessary(env, "EC_GROUP_set_generator");
- }
-
- JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p) => %d", group, point, njavaBytes, hjavaBytes, ret);
-}
-
-static jlong NativeCrypto_EC_GROUP_get_generator(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_generator(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_POINT_get_generator(%p) => group == null", group);
- jniThrowNullPointerException(env, "group == null");
- return 0;
- }
-
- const EC_POINT* generator = EC_GROUP_get0_generator(group);
-
- Unique_EC_POINT dup(EC_POINT_dup(generator, group));
- if (dup.get() == NULL) {
- JNI_TRACE("EC_GROUP_get_generator(%p) => oom error", group);
- jniThrowOutOfMemory(env, "unable to dupe generator");
- return 0;
- }
-
- JNI_TRACE("EC_GROUP_get_generator(%p) => %p", group, dup.get());
- return reinterpret_cast<uintptr_t>(dup.release());
-}
-
-static jlong NativeCrypto_EC_POINT_new(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_POINT_new(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_POINT_new(%p) => group == null", group);
- jniThrowNullPointerException(env, "group == null");
- return 0;
- }
-
- EC_POINT* point = EC_POINT_new(group);
- if (point == NULL) {
- jniThrowOutOfMemory(env, "Unable create an EC_POINT");
- return 0;
- }
-
- return reinterpret_cast<uintptr_t>(point);
-}
-
-static void NativeCrypto_EC_POINT_clear_free(JNIEnv* env, jclass, jlong groupRef) {
- EC_POINT* group = reinterpret_cast<EC_POINT*>(groupRef);
- JNI_TRACE("EC_POINT_clear_free(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_POINT_clear_free => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return;
- }
-
- EC_POINT_clear_free(group);
- JNI_TRACE("EC_POINT_clear_free(%p) => success", group);
-}
-
-static jboolean NativeCrypto_EC_POINT_cmp(JNIEnv* env, jclass, jlong groupRef, jlong point1Ref, jlong point2Ref)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- const EC_POINT* point1 = reinterpret_cast<const EC_POINT*>(point1Ref);
- const EC_POINT* point2 = reinterpret_cast<const EC_POINT*>(point2Ref);
- JNI_TRACE("EC_POINT_cmp(%p, %p, %p)", group, point1, point2);
-
- if (group == NULL || point1 == NULL || point2 == NULL) {
- JNI_TRACE("EC_POINT_cmp(%p, %p, %p) => group == null || point1 == null || point2 == null",
- group, point1, point2);
- jniThrowNullPointerException(env, "group == null || point1 == null || point2 == null");
- return false;
- }
-
- int ret = EC_POINT_cmp(group, point1, point2, (BN_CTX*)NULL);
-
- JNI_TRACE("ECP_GROUP_cmp(%p, %p) => %d", point1, point2, ret);
- return ret == 0;
-}
-
-static void NativeCrypto_EC_POINT_set_affine_coordinates(JNIEnv* env, jclass,
- jlong groupRef, jlong pointRef, jbyteArray xjavaBytes, jbyteArray yjavaBytes)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- EC_POINT* point = reinterpret_cast<EC_POINT*>(pointRef);
- JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p)", group, point, xjavaBytes,
- yjavaBytes);
-
- if (group == NULL || point == NULL) {
- JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p) => group == null || point == null",
- group, point, xjavaBytes, yjavaBytes);
- jniThrowNullPointerException(env, "group == null || point == null");
- return;
- }
-
- BIGNUM* xRef;
- if (!arrayToBignum(env, xjavaBytes, &xRef)) {
- return;
- }
- Unique_BIGNUM x(xRef);
-
- BIGNUM* yRef;
- if (!arrayToBignum(env, yjavaBytes, &yRef)) {
- return;
- }
- Unique_BIGNUM y(yRef);
-
- int ret;
- switch (get_EC_GROUP_type(group)) {
- case EC_CURVE_GFP:
- ret = EC_POINT_set_affine_coordinates_GFp(group, point, x.get(), y.get(), NULL);
- break;
- case EC_CURVE_GF2M:
- ret = EC_POINT_set_affine_coordinates_GF2m(group, point, x.get(), y.get(), NULL);
- break;
- default:
- jniThrowRuntimeException(env, "invalid curve type");
- return;
- }
-
- if (ret != 1) {
- throwExceptionIfNecessary(env, "EC_POINT_set_affine_coordinates");
- }
-
- JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p) => %d", group, point,
- xjavaBytes, yjavaBytes, ret);
-}
-
-static jobjectArray NativeCrypto_EC_POINT_get_affine_coordinates(JNIEnv* env, jclass, jlong groupRef,
- jlong pointRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- const EC_POINT* point = reinterpret_cast<const EC_POINT*>(pointRef);
- JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p)", group, point);
-
- Unique_BIGNUM x(BN_new());
- Unique_BIGNUM y(BN_new());
-
- int ret;
- switch (get_EC_GROUP_type(group)) {
- case EC_CURVE_GFP:
- ret = EC_POINT_get_affine_coordinates_GFp(group, point, x.get(), y.get(), NULL);
- break;
- case EC_CURVE_GF2M:
- ret = EC_POINT_get_affine_coordinates_GF2m(group, point, x.get(), y.get(), NULL);
- break;
- default:
- jniThrowRuntimeException(env, "invalid curve type");
- return NULL;
- }
- if (ret != 1) {
- JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p)", group, point);
- throwExceptionIfNecessary(env, "EC_POINT_get_affine_coordinates");
- return NULL;
- }
-
- jobjectArray joa = env->NewObjectArray(2, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- jbyteArray xBytes = bignumToArray(env, x.get(), "x");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, xBytes);
-
- jbyteArray yBytes = bignumToArray(env, y.get(), "y");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, yBytes);
-
- JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p) => %p", group, point, joa);
- return joa;
-}
-
-static jlong NativeCrypto_EC_KEY_generate_key(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_KEY_generate_key(%p)", group);
-
- Unique_EC_KEY eckey(EC_KEY_new());
- if (eckey.get() == NULL) {
- JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_new() oom", group);
- jniThrowOutOfMemory(env, "Unable to create an EC_KEY");
- return 0;
- }
-
- if (EC_KEY_set_group(eckey.get(), group) != 1) {
- JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_set_group error", group);
- throwExceptionIfNecessary(env, "EC_KEY_set_group");
- return 0;
- }
-
- if (EC_KEY_generate_key(eckey.get()) != 1) {
- JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_generate_key error", group);
- throwExceptionIfNecessary(env, "EC_KEY_set_group");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- JNI_TRACE("EC_KEY_generate_key(%p) => threw error", group);
- throwExceptionIfNecessary(env, "EC_KEY_generate_key");
- return 0;
- }
- if (EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get()) != 1) {
- jniThrowRuntimeException(env, "EVP_PKEY_assign_EC_KEY failed");
- return 0;
- }
- OWNERSHIP_TRANSFERRED(eckey);
-
- JNI_TRACE("EC_KEY_generate_key(%p) => %p", group, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jlong NativeCrypto_EC_KEY_get0_group(JNIEnv* env, jclass, jlong pkeyRef)
-{
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EC_KEY_get0_group(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("EC_KEY_get0_group(%p) => pkey == null", pkey);
- return 0;
- }
-
- if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {
- jniThrowRuntimeException(env, "not EC key");
- JNI_TRACE("EC_KEY_get0_group(%p) => not EC key (type == %d)", pkey,
- EVP_PKEY_type(pkey->type));
- return 0;
- }
-
- const EC_GROUP* group = EC_KEY_get0_group(pkey->pkey.ec);
- JNI_TRACE("EC_KEY_get0_group(%p) => %p", pkey, group);
- return reinterpret_cast<uintptr_t>(group);
-}
-
-static jbyteArray NativeCrypto_EC_KEY_get_private_key(JNIEnv* env, jclass, jlong pkeyRef)
-{
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EC_KEY_get_private_key(%p)", pkey);
-
- Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
- if (eckey.get() == NULL) {
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY");
- return NULL;
- }
-
- const BIGNUM *privkey = EC_KEY_get0_private_key(eckey.get());
-
- jbyteArray privBytes = bignumToArray(env, privkey, "privkey");
- if (env->ExceptionCheck()) {
- JNI_TRACE("EC_KEY_get_private_key(%p) => threw error", pkey);
- return NULL;
- }
-
- JNI_TRACE("EC_KEY_get_private_key(%p) => %p", pkey, privBytes);
- return privBytes;
-}
-
-static jlong NativeCrypto_EC_KEY_get_public_key(JNIEnv* env, jclass, jlong pkeyRef)
-{
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EC_KEY_get_public_key(%p)", pkey);
-
- Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
- if (eckey.get() == NULL) {
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY");
- return 0;
- }
-
- Unique_EC_POINT dup(EC_POINT_dup(EC_KEY_get0_public_key(eckey.get()),
- EC_KEY_get0_group(eckey.get())));
- if (dup.get() == NULL) {
- JNI_TRACE("EC_KEY_get_public_key(%p) => can't dup public key", pkey);
- jniThrowRuntimeException(env, "EC_POINT_dup");
- return 0;
- }
-
- JNI_TRACE("EC_KEY_get_public_key(%p) => %p", pkey, dup.get());
- return reinterpret_cast<uintptr_t>(dup.release());
-}
-
-static jint NativeCrypto_ECDH_compute_key(JNIEnv* env, jclass,
- jbyteArray outArray, jint outOffset, jlong pubkeyRef, jlong privkeyRef)
-{
- EVP_PKEY* pubPkey = reinterpret_cast<EVP_PKEY*>(pubkeyRef);
- EVP_PKEY* privPkey = reinterpret_cast<EVP_PKEY*>(privkeyRef);
- JNI_TRACE("ECDH_compute_key(%p, %d, %p, %p)", outArray, outOffset, pubPkey, privPkey);
-
- ScopedByteArrayRW out(env, outArray);
- if (out.get() == NULL) {
- JNI_TRACE("ECDH_compute_key(%p, %d, %p, %p) can't get output buffer",
- outArray, outOffset, pubPkey, privPkey);
- return -1;
- }
-
- if ((outOffset < 0) || ((size_t) outOffset >= out.size())) {
- jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
- return -1;
- }
-
- Unique_EC_KEY pubkey(EVP_PKEY_get1_EC_KEY(pubPkey));
- if (pubkey.get() == NULL) {
- JNI_TRACE("ECDH_compute_key(%p) => can't get public key", pubPkey);
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY public");
- return -1;
- }
-
- const EC_POINT* pubkeyPoint = EC_KEY_get0_public_key(pubkey.get());
- if (pubkeyPoint == NULL) {
- JNI_TRACE("ECDH_compute_key(%p) => can't get public key point", pubPkey);
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY public");
- return -1;
- }
-
- Unique_EC_KEY privkey(EVP_PKEY_get1_EC_KEY(privPkey));
- if (privkey.get() == NULL) {
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY private");
- return -1;
- }
-
- int outputLength = ECDH_compute_key(
- &out[outOffset],
- out.size() - outOffset,
- pubkeyPoint,
- privkey.get(),
- NULL // No KDF
- );
- if (outputLength == -1) {
- throwExceptionIfNecessary(env, "ECDH_compute_key");
- return -1;
- }
-
- return outputLength;
-}
-
-static jlong NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) {
- JNI_TRACE("EVP_MD_CTX_create()");
-
- Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable create a EVP_MD_CTX");
- return 0;
- }
-
- JNI_TRACE("EVP_MD_CTX_create() => %p", ctx.get());
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-static void NativeCrypto_EVP_MD_CTX_init(JNIEnv*, jclass, jlong ctxRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_MD_CTX_init(%p)", ctx);
-
- if (ctx != NULL) {
- EVP_MD_CTX_init(ctx);
- }
-}
-
-static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, jlong ctxRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_MD_CTX_destroy(%p)", ctx);
-
- if (ctx != NULL) {
- EVP_MD_CTX_destroy(ctx);
- }
-}
-
-static jlong NativeCrypto_EVP_MD_CTX_copy(JNIEnv* env, jclass, jlong ctxRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p)", ctx);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- return 0;
- }
-
- EVP_MD_CTX* copy = EVP_MD_CTX_create();
- if (copy == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate copy of EVP_MD_CTX");
- return 0;
- }
-
- EVP_MD_CTX_init(copy);
- int result = EVP_MD_CTX_copy_ex(copy, ctx);
- if (result == 0) {
- EVP_MD_CTX_destroy(copy);
- jniThrowRuntimeException(env, "Unable to copy EVP_MD_CTX");
- freeOpenSslErrorState();
- return 0;
- }
-
- JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p) => %p", ctx, copy);
- return reinterpret_cast<uintptr_t>(copy);
-}
-
-/*
- * public static native int EVP_DigestFinal(int, byte[], int)
- */
-static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, jlong ctxRef,
- jbyteArray hash, jint offset) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d)", ctx, hash, offset);
-
- if (ctx == NULL || hash == NULL) {
- jniThrowNullPointerException(env, "ctx == null || hash == null");
- return -1;
- }
-
- ScopedByteArrayRW hashBytes(env, hash);
- if (hashBytes.get() == NULL) {
- return -1;
- }
- unsigned int bytesWritten = -1;
- int ok = EVP_DigestFinal(ctx,
- reinterpret_cast<unsigned char*>(hashBytes.get() + offset),
- &bytesWritten);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestFinal");
- }
- EVP_MD_CTX_destroy(ctx);
-
- JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d) => %d", ctx, hash, offset, bytesWritten);
- return bytesWritten;
-}
-
-/*
- * public static native int EVP_DigestInit(int)
- */
-static jlong NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, jlong evpMdRef) {
- EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
- JNI_TRACE("NativeCrypto_EVP_DigestInit(%p)", evp_md);
-
- if (evp_md == NULL) {
- jniThrowNullPointerException(env, NULL);
- return 0;
- }
-
- Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate EVP_MD_CTX");
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_DigestInit ctx=%p", ctx.get());
-
- int ok = EVP_DigestInit(ctx.get(), evp_md);
- if (ok == 0) {
- bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestInit");
- if (exception) {
- return 0;
- }
- }
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-/*
- * public static native int EVP_get_digestbyname(java.lang.String)
- */
-static jlong NativeCrypto_EVP_get_digestbyname(JNIEnv* env, jclass, jstring algorithm) {
- JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%p)", algorithm);
-
- if (algorithm == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- ScopedUtfChars algorithmChars(env, algorithm);
- if (algorithmChars.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s)", algorithmChars.c_str());
-
- const EVP_MD* evp_md = EVP_get_digestbyname(algorithmChars.c_str());
- if (evp_md == NULL) {
- jniThrowRuntimeException(env, "Hash algorithm not found");
- return 0;
- }
-
- JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s) => %p", algorithmChars.c_str(), evp_md);
- return reinterpret_cast<uintptr_t>(evp_md);
-}
-
-/*
- * public static native int EVP_MD_size(int)
- */
-static jint NativeCrypto_EVP_MD_size(JNIEnv* env, jclass, jint evpMdRef) {
- EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
- JNI_TRACE("NativeCrypto_EVP_MD_size(%p)", evp_md);
-
- if (evp_md == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- int result = EVP_MD_size(evp_md);
- JNI_TRACE("NativeCrypto_EVP_MD_size(%p) => %d", evp_md, result);
- return result;
-}
-
-/*
- * public static int void EVP_MD_block_size(int)
- */
-static jint NativeCrypto_EVP_MD_block_size(JNIEnv* env, jclass, jlong evpMdRef) {
- EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
- JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p)", evp_md);
-
- if (evp_md == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- int result = EVP_MD_block_size(evp_md);
- JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p) => %d", evp_md, result);
- return result;
-}
-
-/*
- * public static native void EVP_DigestUpdate(int, byte[], int, int)
- */
-static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, jlong ctxRef,
- jbyteArray buffer, jint offset, jint length) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_DigestUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
-
- if (offset < 0 || length < 0) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
- return;
- }
-
- if (ctx == NULL || buffer == NULL) {
- jniThrowNullPointerException(env, NULL);
- return;
- }
-
- ScopedByteArrayRO bufferBytes(env, buffer);
- if (bufferBytes.get() == NULL) {
- return;
- }
- int ok = EVP_DigestUpdate(ctx,
- reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
- length);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestUpdate");
- }
-}
-
-static void NativeCrypto_EVP_DigestSignInit(JNIEnv* env, jclass, jlong evpMdCtxRef,
- const jlong evpMdRef, jlong pkeyRef) {
- EVP_MD_CTX* mdCtx = reinterpret_cast<EVP_MD_CTX*>(evpMdCtxRef);
- const EVP_MD* md = reinterpret_cast<const EVP_MD*>(evpMdRef);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_DigestSignInit(%p, %p, %p)", mdCtx, md, pkey);
-
- if (mdCtx == NULL) {
- jniThrowNullPointerException(env, "mdCtx == null");
- return;
- }
-
- if (md == NULL) {
- jniThrowNullPointerException(env, "md == null");
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return;
- }
-
- if (EVP_DigestSignInit(mdCtx, (EVP_PKEY_CTX **) NULL, md, (ENGINE *) NULL, pkey) <= 0) {
- JNI_TRACE("ctx=%p EVP_DigestSignInit => threw exception", mdCtx);
- throwExceptionIfNecessary(env, "EVP_DigestSignInit");
- return;
- }
-
- JNI_TRACE("EVP_DigestSignInit(%p, %p, %p) => success", mdCtx, md, pkey);
-}
-
-static void NativeCrypto_EVP_DigestSignUpdate(JNIEnv* env, jclass, jint evpMdCtxRef,
- jbyteArray inJavaBytes, jint inOffset, jint inLength)
-{
- EVP_MD_CTX* mdCtx = reinterpret_cast<EVP_MD_CTX*>(evpMdCtxRef);
- JNI_TRACE("EVP_DigestSignUpdate(%p, %p, %d, %d)", mdCtx, inJavaBytes, inOffset, inLength);
-
- if (mdCtx == NULL) {
- jniThrowNullPointerException(env, "mdCtx == null");
- return;
- }
-
- ScopedByteArrayRO inBytes(env, inJavaBytes);
- if (inBytes.get() == NULL) {
- return;
- }
-
- if (inOffset < 0 || size_t(inOffset) > inBytes.size()) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException", "inOffset");
- return;
- }
-
- const ssize_t inEnd = inOffset + inLength;
- if (inEnd < 0 || size_t(inEnd) >= inBytes.size()) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException", "inLength");
- return;
- }
-
- const unsigned char *tmp = reinterpret_cast<const unsigned char *>(inBytes.get());
- if (!EVP_DigestSignUpdate(mdCtx, tmp + inOffset, inLength)) {
- JNI_TRACE("ctx=%p EVP_DigestSignUpdate => threw exception", mdCtx);
- throwExceptionIfNecessary(env, "EVP_DigestSignUpdate");
- }
-
- JNI_TRACE("EVP_DigestSignUpdate(%p, %p, %d, %d) => success", mdCtx, inJavaBytes, inOffset,
- inLength);
-}
-
-static jbyteArray NativeCrypto_EVP_DigestSignFinal(JNIEnv* env, jclass, jlong evpMdCtxRef)
-{
- EVP_MD_CTX* mdCtx = reinterpret_cast<EVP_MD_CTX*>(evpMdCtxRef);
- JNI_TRACE("EVP_DigestSignFinal(%p)", mdCtx);
-
- if (mdCtx == NULL) {
- jniThrowNullPointerException(env, "mdCtx == null");
- return NULL;
- }
-
- const size_t expectedSize = EVP_MD_CTX_size(mdCtx);
- ScopedLocalRef<jbyteArray> outJavaBytes(env, env->NewByteArray(expectedSize));
- if (outJavaBytes.get() == NULL) {
- return NULL;
- }
- ScopedByteArrayRW outBytes(env, outJavaBytes.get());
- if (outBytes.get() == NULL) {
- return NULL;
- }
- unsigned char *tmp = reinterpret_cast<unsigned char*>(outBytes.get());
- size_t len;
- if (!EVP_DigestSignFinal(mdCtx, tmp, &len)) {
- JNI_TRACE("ctx=%p EVP_DigestSignFinal => threw exception", mdCtx);
- throwExceptionIfNecessary(env, "EVP_DigestSignFinal");
- return 0;
- }
-
- if (len != expectedSize) {
- jniThrowRuntimeException(env, "hash size unexpected");
- return 0;
- }
-
- JNI_TRACE("EVP_DigestSignFinal(%p) => %p", mdCtx, outJavaBytes.get());
- return outJavaBytes.release();
-}
-
-static jlong NativeCrypto_EVP_SignInit(JNIEnv* env, jclass, jstring algorithm) {
- JNI_TRACE("NativeCrypto_EVP_SignInit(%p)", algorithm);
-
- if (algorithm == NULL) {
- jniThrowNullPointerException(env, NULL);
- return 0;
- }
-
- Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate EVP_MD_CTX");
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_SignInit ctx=%p", ctx.get());
-
- ScopedUtfChars algorithmChars(env, algorithm);
- if (algorithmChars.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_SignInit algorithmChars=%s", algorithmChars.c_str());
-
- const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
- if (digest == NULL) {
- JNI_TRACE("NativeCrypto_EVP_SignInit(%s) => hash not found", algorithmChars.c_str());
- throwExceptionIfNecessary(env, "Hash algorithm not found");
- return 0;
- }
-
- int ok = EVP_SignInit(ctx.get(), digest);
- if (ok == 0) {
- bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignInit");
- if (exception) {
- JNI_TRACE("NativeCrypto_EVP_SignInit(%s) => threw exception", algorithmChars.c_str());
- return 0;
- }
- }
-
- JNI_TRACE("NativeCrypto_EVP_SignInit(%s) => %p", algorithmChars.c_str(), ctx.get());
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-/*
- * public static native void EVP_SignUpdate(int, byte[], int, int)
- */
-static void NativeCrypto_EVP_SignUpdate(JNIEnv* env, jclass, jlong ctxRef,
- jbyteArray buffer, jint offset, jint length) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_SignUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
-
- if (ctx == NULL || buffer == NULL) {
- jniThrowNullPointerException(env, NULL);
- return;
- }
-
- ScopedByteArrayRO bufferBytes(env, buffer);
- if (bufferBytes.get() == NULL) {
- return;
- }
- int ok = EVP_SignUpdate(ctx,
- reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
- length);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignUpdate");
- }
-}
-
-/*
- * public static native int EVP_SignFinal(int, byte[], int, int)
- */
-static jint NativeCrypto_EVP_SignFinal(JNIEnv* env, jclass, jlong ctxRef, jbyteArray signature,
- jint offset, jlong pkeyRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p)", ctx, signature, offset, pkey);
-
- if (ctx == NULL || pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- ScopedByteArrayRW signatureBytes(env, signature);
- if (signatureBytes.get() == NULL) {
- return -1;
- }
- unsigned int bytesWritten = -1;
- int ok = EVP_SignFinal(ctx,
- reinterpret_cast<unsigned char*>(signatureBytes.get() + offset),
- &bytesWritten,
- pkey);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignFinal");
- }
- JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p) => %u",
- ctx, signature, offset, pkey, bytesWritten);
-
- return bytesWritten;
-}
-
-/*
- * public static native int EVP_VerifyInit(java.lang.String)
- */
-static jlong NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, jstring algorithm) {
- JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p)", algorithm);
-
- if (algorithm == NULL) {
- jniThrowNullPointerException(env, NULL);
- return 0;
- }
-
- Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate EVP_MD_CTX");
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_VerifyInit ctx=%p", ctx.get());
-
- ScopedUtfChars algorithmChars(env, algorithm);
- if (algorithmChars.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_VerifyInit algorithmChars=%s", algorithmChars.c_str());
-
- const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
- if (digest == NULL) {
- jniThrowRuntimeException(env, "Hash algorithm not found");
- return 0;
- }
-
- int ok = EVP_VerifyInit(ctx.get(), digest);
- if (ok == 0) {
- bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyInit");
- if (exception) {
- return 0;
- }
- }
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-/*
- * public static native void EVP_VerifyUpdate(int, byte[], int, int)
- */
-static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, jlong ctxRef,
- jbyteArray buffer, jint offset, jint length) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_VerifyUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
-
- if (ctx == NULL || buffer == NULL) {
- jniThrowNullPointerException(env, NULL);
- return;
- }
-
- ScopedByteArrayRO bufferBytes(env, buffer);
- if (bufferBytes.get() == NULL) {
- return;
- }
- int ok = EVP_VerifyUpdate(ctx,
- reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
- length);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyUpdate");
- }
-}
-
-/*
- * public static native int EVP_VerifyFinal(int, byte[], int, int, int)
- */
-static jint NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, jlong ctxRef, jbyteArray buffer,
- jint offset, jint length, jlong pkeyRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p)",
- ctx, buffer, offset, length, pkey);
-
- if (ctx == NULL || buffer == NULL || pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- ScopedByteArrayRO bufferBytes(env, buffer);
- if (bufferBytes.get() == NULL) {
- return -1;
- }
- int ok = EVP_VerifyFinal(ctx,
- reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
- length,
- pkey);
- if (ok < 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyFinal");
- }
-
- /*
- * For DSA keys, OpenSSL appears to have a bug where it returns
- * errors for any result != 1. See dsa_ossl.c in dsa_do_verify
- */
- freeOpenSslErrorState();
-
- JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p) => %d",
- ctx, buffer, offset, length, pkey, ok);
-
- return ok;
-}
-
-static jlong NativeCrypto_EVP_get_cipherbyname(JNIEnv* env, jclass, jstring algorithm) {
- JNI_TRACE("EVP_get_cipherbyname(%p)", algorithm);
- if (algorithm == NULL) {
- JNI_TRACE("EVP_get_cipherbyname(%p) => threw exception algorithm == null", algorithm);
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- ScopedUtfChars algorithmChars(env, algorithm);
- if (algorithmChars.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("EVP_get_cipherbyname(%p) => algorithm = %s", algorithm, algorithmChars.c_str());
-
- const EVP_CIPHER* evp_cipher = EVP_get_cipherbyname(algorithmChars.c_str());
- if (evp_cipher == NULL) {
- freeOpenSslErrorState();
- }
-
- JNI_TRACE("EVP_get_cipherbyname(%s) => %p", algorithmChars.c_str(), evp_cipher);
- return reinterpret_cast<uintptr_t>(evp_cipher);
-}
-
-static void NativeCrypto_EVP_CipherInit_ex(JNIEnv* env, jclass, jlong ctxRef, jlong evpCipherRef,
- jbyteArray keyArray, jbyteArray ivArray, jboolean encrypting) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- const EVP_CIPHER* evpCipher = reinterpret_cast<const EVP_CIPHER*>(evpCipherRef);
- JNI_TRACE("EVP_CipherInit_ex(%p, %p, %p, %p, %d)", ctx, evpCipher, keyArray, ivArray,
- encrypting ? 1 : 0);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("EVP_CipherUpdate => ctx == null");
- return;
- }
-
- // The key can be null if we need to set extra parameters.
- UniquePtr<unsigned char[]> keyPtr;
- if (keyArray != NULL) {
- ScopedByteArrayRO keyBytes(env, keyArray);
- if (keyBytes.get() == NULL) {
- return;
- }
-
- keyPtr.reset(new unsigned char[keyBytes.size()]);
- memcpy(keyPtr.get(), keyBytes.get(), keyBytes.size());
- }
-
- // The IV can be null if we're using ECB.
- UniquePtr<unsigned char[]> ivPtr;
- if (ivArray != NULL) {
- ScopedByteArrayRO ivBytes(env, ivArray);
- if (ivBytes.get() == NULL) {
- return;
- }
-
- ivPtr.reset(new unsigned char[ivBytes.size()]);
- memcpy(ivPtr.get(), ivBytes.get(), ivBytes.size());
- }
-
- if (!EVP_CipherInit_ex(ctx, evpCipher, NULL, keyPtr.get(), ivPtr.get(), encrypting ? 1 : 0)) {
- throwExceptionIfNecessary(env, "EVP_CipherInit_ex");
- JNI_TRACE("EVP_CipherInit_ex => error initializing cipher");
- return;
- }
-
- JNI_TRACE("EVP_CipherInit_ex(%p, %p, %p, %p, %d) => success", ctx, evpCipher, keyArray, ivArray,
- encrypting ? 1 : 0);
-}
-
-/*
- * public static native int EVP_CipherUpdate(int ctx, byte[] out, int outOffset, byte[] in,
- * int inOffset);
- */
-static jint NativeCrypto_EVP_CipherUpdate(JNIEnv* env, jclass, jlong ctxRef, jbyteArray outArray,
- jint outOffset, jbyteArray inArray, jint inOffset, jint inLength) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d)", ctx, outArray, outOffset, inArray, inOffset);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CipherUpdate => ctx == null", ctx);
- return 0;
- }
-
- ScopedByteArrayRO inBytes(env, inArray);
- if (inBytes.get() == NULL) {
- return 0;
- }
- const size_t inSize = inBytes.size();
- if (size_t(inOffset + inLength) > inSize) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException",
- "in.length < (inSize + inOffset)");
- return 0;
- }
-
- ScopedByteArrayRW outBytes(env, outArray);
- if (outBytes.get() == NULL) {
- return 0;
- }
- const size_t outSize = outBytes.size();
- if (size_t(outOffset + inLength) > outSize) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException",
- "out.length < inSize + outOffset + blockSize - 1");
- return 0;
- }
-
- JNI_TRACE("ctx=%p EVP_CipherUpdate in=%p in.length=%d inOffset=%d inLength=%d out=%p out.length=%d outOffset=%d",
- ctx, inBytes.get(), inBytes.size(), inOffset, inLength, outBytes.get(), outBytes.size(), outOffset);
-
- unsigned char* out = reinterpret_cast<unsigned char*>(outBytes.get());
- const unsigned char* in = reinterpret_cast<const unsigned char*>(inBytes.get());
-
- int outl;
- if (!EVP_CipherUpdate(ctx, out + outOffset, &outl, in + inOffset, inLength)) {
- throwExceptionIfNecessary(env, "EVP_CipherUpdate");
- JNI_TRACE("ctx=%p EVP_CipherUpdate => threw error", ctx);
- return 0;
- }
-
- JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d) => %d", ctx, outArray, outOffset, inArray,
- inOffset, outl);
- return outl;
-}
-
-static jint NativeCrypto_EVP_CipherFinal_ex(JNIEnv* env, jclass, jlong ctxRef, jbyteArray outArray,
- jint outOffset) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CipherFinal_ex(%p, %p, %d)", ctx, outArray, outOffset);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CipherFinal_ex => ctx == null", ctx);
- return 0;
- }
-
- ScopedByteArrayRW outBytes(env, outArray);
- if (outBytes.get() == NULL) {
- return 0;
- }
-
- unsigned char* out = reinterpret_cast<unsigned char*>(outBytes.get());
-
- int outl;
- if (!EVP_CipherFinal_ex(ctx, out + outOffset, &outl)) {
- throwExceptionIfNecessary(env, "EVP_CipherFinal_ex");
- JNI_TRACE("ctx=%p EVP_CipherFinal_ex => threw error", ctx);
- return 0;
- }
-
- JNI_TRACE("EVP_CipherFinal(%p, %p, %d) => %d", ctx, outArray, outOffset, outl);
- return outl;
-}
-
-static jint NativeCrypto_EVP_CIPHER_iv_length(JNIEnv* env, jclass, jlong evpCipherRef) {
- const EVP_CIPHER* evpCipher = reinterpret_cast<const EVP_CIPHER*>(evpCipherRef);
- JNI_TRACE("EVP_CIPHER_iv_length(%p)", evpCipher);
-
- if (evpCipher == NULL) {
- jniThrowNullPointerException(env, "evpCipher == null");
- JNI_TRACE("EVP_CIPHER_iv_length => evpCipher == null");
- return 0;
- }
-
- const int ivLength = EVP_CIPHER_iv_length(evpCipher);
- JNI_TRACE("EVP_CIPHER_iv_length(%p) => %d", evpCipher, ivLength);
- return ivLength;
-}
-
-static jlong NativeCrypto_EVP_CIPHER_CTX_new(JNIEnv* env, jclass) {
- JNI_TRACE("EVP_CIPHER_CTX_new()");
-
- Unique_EVP_CIPHER_CTX ctx(EVP_CIPHER_CTX_new());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate cipher context");
- JNI_TRACE("EVP_CipherInit_ex => context allocation error");
- return 0;
- }
-
- JNI_TRACE("EVP_CIPHER_CTX_new() => %p", ctx.get());
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-static jint NativeCrypto_EVP_CIPHER_CTX_block_size(JNIEnv* env, jclass, jlong ctxRef) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CIPHER_CTX_block_size(%p)", ctx);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CIPHER_CTX_block_size => ctx == null", ctx);
- return 0;
- }
-
- int blockSize = EVP_CIPHER_CTX_block_size(ctx);
- JNI_TRACE("EVP_CIPHER_CTX_block_size(%p) => %d", ctx, blockSize);
- return blockSize;
-}
-
-static jint NativeCrypto_get_EVP_CIPHER_CTX_buf_len(JNIEnv* env, jclass, jlong ctxRef) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("get_EVP_CIPHER_CTX_buf_len(%p)", ctx);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p get_EVP_CIPHER_CTX_buf_len => ctx == null", ctx);
- return 0;
- }
-
- int buf_len = ctx->buf_len;
- JNI_TRACE("get_EVP_CIPHER_CTX_buf_len(%p) => %d", ctx, buf_len);
- return buf_len;
-}
-
-static void NativeCrypto_EVP_CIPHER_CTX_set_padding(JNIEnv* env, jclass, jlong ctxRef, jboolean enablePaddingBool) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- jint enablePadding = enablePaddingBool ? 1 : 0;
- JNI_TRACE("EVP_CIPHER_CTX_set_padding(%p, %d)", ctx, enablePadding);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CIPHER_CTX_set_padding => ctx == null", ctx);
- return;
- }
-
- EVP_CIPHER_CTX_set_padding(ctx, enablePadding); // Not void, but always returns 1.
- JNI_TRACE("EVP_CIPHER_CTX_set_padding(%p, %d) => success", ctx, enablePadding);
-}
-
-static void NativeCrypto_EVP_CIPHER_CTX_set_key_length(JNIEnv* env, jclass, jlong ctxRef,
- jint keySizeBits) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CIPHER_CTX_set_key_length(%p, %d)", ctx, keySizeBits);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CIPHER_CTX_set_key_length => ctx == null", ctx);
- return;
- }
-
- if (!EVP_CIPHER_CTX_set_key_length(ctx, keySizeBits)) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_CIPHER_CTX_set_key_length");
- JNI_TRACE("NativeCrypto_EVP_CIPHER_CTX_set_key_length => threw error");
- return;
- }
- JNI_TRACE("EVP_CIPHER_CTX_set_key_length(%p, %d) => success", ctx, keySizeBits);
-}
-
-static void NativeCrypto_EVP_CIPHER_CTX_cleanup(JNIEnv* env, jclass, jlong ctxRef) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CIPHER_CTX_cleanup(%p)", ctx);
-
- if (ctx != NULL) {
- if (!EVP_CIPHER_CTX_cleanup(ctx)) {
- throwExceptionIfNecessary(env, "EVP_CIPHER_CTX_cleanup");
- JNI_TRACE("EVP_CIPHER_CTX_cleanup => threw error");
- return;
- }
- }
- JNI_TRACE("EVP_CIPHER_CTX_cleanup(%p) => success", ctx);
-}
-
-/**
- * public static native void RAND_seed(byte[]);
- */
-static void NativeCrypto_RAND_seed(JNIEnv* env, jclass, jbyteArray seed) {
- JNI_TRACE("NativeCrypto_RAND_seed seed=%p", seed);
- ScopedByteArrayRO randseed(env, seed);
- if (randseed.get() == NULL) {
- return;
- }
- RAND_seed(randseed.get(), randseed.size());
-}
-
-static jint NativeCrypto_RAND_load_file(JNIEnv* env, jclass, jstring filename, jlong max_bytes) {
- JNI_TRACE("NativeCrypto_RAND_load_file filename=%p max_bytes=%lld", filename, max_bytes);
- ScopedUtfChars file(env, filename);
- if (file.c_str() == NULL) {
- return -1;
- }
- int result = RAND_load_file(file.c_str(), max_bytes);
- JNI_TRACE("NativeCrypto_RAND_load_file file=%s => %d", file.c_str(), result);
- return result;
-}
-
-static void NativeCrypto_RAND_bytes(JNIEnv* env, jclass, jbyteArray output) {
- JNI_TRACE("NativeCrypto_RAND_bytes(%p)", output);
-
- ScopedByteArrayRW outputBytes(env, output);
- if (outputBytes.get() == NULL) {
- return;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(outputBytes.get());
- if (RAND_bytes(tmp, outputBytes.size()) <= 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_RAND_bytes");
- JNI_TRACE("tmp=%p NativeCrypto_RAND_bytes => threw error", tmp);
- return;
- }
-
- JNI_TRACE("NativeCrypto_RAND_bytes(%p) => success", output);
-}
-
-static jint NativeCrypto_OBJ_txt2nid(JNIEnv* env, jclass, jstring oidStr) {
- JNI_TRACE("OBJ_txt2nid(%p)", oidStr);
-
- ScopedUtfChars oid(env, oidStr);
- if (oid.c_str() == NULL) {
- return 0;
- }
-
- int nid = OBJ_txt2nid(oid.c_str());
- JNI_TRACE("OBJ_txt2nid(%s) => %d", oid.c_str(), nid);
- return nid;
-}
-
-static jstring NativeCrypto_OBJ_txt2nid_longName(JNIEnv* env, jclass, jstring oidStr) {
- JNI_TRACE("OBJ_txt2nid_longName(%p)", oidStr);
-
- ScopedUtfChars oid(env, oidStr);
- if (oid.c_str() == NULL) {
- return NULL;
- }
-
- JNI_TRACE("OBJ_txt2nid_longName(%s)", oid.c_str());
-
- int nid = OBJ_txt2nid(oid.c_str());
- if (nid == NID_undef) {
- JNI_TRACE("OBJ_txt2nid_longName(%s) => NID_undef", oid.c_str());
- freeOpenSslErrorState();
- return NULL;
- }
-
- const char* longName = OBJ_nid2ln(nid);
- JNI_TRACE("OBJ_txt2nid_longName(%s) => %s", oid.c_str(), longName);
- return env->NewStringUTF(longName);
-}
-
-static jstring ASN1_OBJECT_to_OID_string(JNIEnv* env, ASN1_OBJECT* obj) {
- /*
- * The OBJ_obj2txt API doesn't "measure" if you pass in NULL as the buffer.
- * Just make a buffer that's large enough here. The documentation recommends
- * 80 characters.
- */
- char output[128];
- int ret = OBJ_obj2txt(output, sizeof(output), obj, 1);
- if (ret < 0) {
- throwExceptionIfNecessary(env, "ASN1_OBJECT_to_OID_string");
- return NULL;
- } else if (size_t(ret) >= sizeof(output)) {
- jniThrowRuntimeException(env, "ASN1_OBJECT_to_OID_string buffer too small");
- return NULL;
- }
-
- JNI_TRACE("ASN1_OBJECT_to_OID_string(%p) => %s", obj, output);
- return env->NewStringUTF(output);
-}
-
-static jlong NativeCrypto_create_BIO_InputStream(JNIEnv* env, jclass, jobject streamObj) {
- JNI_TRACE("create_BIO_InputStream(%p)", streamObj);
-
- if (streamObj == NULL) {
- jniThrowNullPointerException(env, "stream == null");
- return 0;
- }
-
- Unique_BIO bio(BIO_new(&stream_bio_method));
- if (bio.get() == NULL) {
- return 0;
- }
-
- bio_stream_assign(bio.get(), new BIO_InputStream(streamObj));
-
- JNI_TRACE("create_BIO_InputStream(%p) => %p", streamObj, bio.get());
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(bio.release()));
-}
-
-static jlong NativeCrypto_create_BIO_OutputStream(JNIEnv* env, jclass, jobject streamObj) {
- JNI_TRACE("create_BIO_OutputStream(%p)", streamObj);
-
- if (streamObj == NULL) {
- jniThrowNullPointerException(env, "stream == null");
- return 0;
- }
-
- Unique_BIO bio(BIO_new(&stream_bio_method));
- if (bio.get() == NULL) {
- return 0;
- }
-
- bio_stream_assign(bio.get(), new BIO_OutputStream(streamObj));
-
- JNI_TRACE("create_BIO_OutputStream(%p) => %p", streamObj, bio.get());
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(bio.release()));
-}
-
-static int NativeCrypto_BIO_read(JNIEnv* env, jclass, jlong bioRef, jbyteArray outputJavaBytes) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("BIO_read(%p, %p)", bio, outputJavaBytes);
-
- if (outputJavaBytes == NULL) {
- jniThrowNullPointerException(env, "output == null");
- JNI_TRACE("BIO_read(%p, %p) => output == null", bio, outputJavaBytes);
- return 0;
- }
-
- int outputSize = env->GetArrayLength(outputJavaBytes);
-
- UniquePtr<unsigned char[]> buffer(new unsigned char[outputSize]);
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate buffer for read");
- return 0;
- }
-
- int read = BIO_read(bio, buffer.get(), outputSize);
- if (read <= 0) {
- jniThrowException(env, "java/io/IOException", "BIO_read");
- JNI_TRACE("BIO_read(%p, %p) => threw IO exception", bio, outputJavaBytes);
- return 0;
- }
-
- env->SetByteArrayRegion(outputJavaBytes, 0, read, reinterpret_cast<jbyte*>(buffer.get()));
- JNI_TRACE("BIO_read(%p, %p) => %d", bio, outputJavaBytes, read);
- return read;
-}
-
-static void NativeCrypto_BIO_write(JNIEnv* env, jclass, jlong bioRef, jbyteArray inputJavaBytes,
- jint offset, jint length) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("BIO_write(%p, %p, %d, %d)", bio, inputJavaBytes, offset, length);
-
- if (inputJavaBytes == NULL) {
- jniThrowNullPointerException(env, "input == null");
- return;
- }
-
- if (offset < 0 || length < 0) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException", "offset < 0 || length < 0");
- JNI_TRACE("BIO_write(%p, %p, %d, %d) => IOOB", bio, inputJavaBytes, offset, length);
- return;
- }
-
- int inputSize = env->GetArrayLength(inputJavaBytes);
- if (inputSize < offset + length) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException",
- "input.length < offset + length");
- JNI_TRACE("BIO_write(%p, %p, %d, %d) => IOOB", bio, inputJavaBytes, offset, length);
- return;
- }
-
- UniquePtr<unsigned char[]> buffer(new unsigned char[length]);
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate buffer for write");
- return;
- }
-
- env->GetByteArrayRegion(inputJavaBytes, offset, length, reinterpret_cast<jbyte*>(buffer.get()));
- if (BIO_write(bio, buffer.get(), length) != length) {
- freeOpenSslErrorState();
- jniThrowException(env, "java/io/IOException", "BIO_write");
- JNI_TRACE("BIO_write(%p, %p, %d, %d) => IO error", bio, inputJavaBytes, offset, length);
- return;
- }
-
- JNI_TRACE("BIO_write(%p, %p, %d, %d) => success", bio, inputJavaBytes, offset, length);
-}
-
-static void NativeCrypto_BIO_free(JNIEnv* env, jclass, jlong bioRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("BIO_free(%p)", bio);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- return;
- }
-
- BIO_free(bio);
-}
-
-static jstring X509_NAME_to_jstring(JNIEnv* env, X509_NAME* name, unsigned long flags) {
- JNI_TRACE("X509_NAME_to_jstring(%p)", name);
-
- Unique_BIO buffer(BIO_new(BIO_s_mem()));
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate BIO");
- JNI_TRACE("X509_NAME_to_jstring(%p) => threw error", name);
- return NULL;
- }
-
- /* Don't interpret the string. */
- flags &= ~(ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_MSB);
-
- /* Write in given format and null terminate. */
- X509_NAME_print_ex(buffer.get(), name, 0, flags);
- BIO_write(buffer.get(), "\0", 1);
-
- char *tmp;
- BIO_get_mem_data(buffer.get(), &tmp);
- JNI_TRACE("X509_NAME_to_jstring(%p) => \"%s\"", name, tmp);
- return env->NewStringUTF(tmp);
-}
-
-
-/**
- * Converts GENERAL_NAME items to the output format expected in
- * X509Certificate#getSubjectAlternativeNames and
- * X509Certificate#getIssuerAlternativeNames return.
- */
-static jobject GENERAL_NAME_to_jobject(JNIEnv* env, GENERAL_NAME* gen) {
- switch (gen->type) {
- case GEN_EMAIL:
- case GEN_DNS:
- case GEN_URI: {
- // This must not be a T61String and must not contain NULLs.
- const char* data = reinterpret_cast<const char*>(ASN1_STRING_data(gen->d.ia5));
- ssize_t len = ASN1_STRING_length(gen->d.ia5);
- if ((len == static_cast<ssize_t>(strlen(data)))
- && (ASN1_PRINTABLE_type(ASN1_STRING_data(gen->d.ia5), len) != V_ASN1_T61STRING)) {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => Email/DNS/URI \"%s\"", gen, data);
- return env->NewStringUTF(data);
- } else {
- jniThrowException(env, "java/security/cert/CertificateParsingException",
- "Invalid dNSName encoding");
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => Email/DNS/URI invalid", gen);
- return NULL;
- }
- }
- case GEN_DIRNAME:
- /* Write in RFC 2253 format */
- return X509_NAME_to_jstring(env, gen->d.directoryName, XN_FLAG_RFC2253);
- case GEN_IPADD: {
- const void *ip = reinterpret_cast<const void *>(gen->d.ip->data);
- if (gen->d.ip->length == 4) {
- // IPv4
- UniquePtr<char[]> buffer(new char[INET_ADDRSTRLEN]);
- if (inet_ntop(AF_INET, ip, buffer.get(), INET_ADDRSTRLEN) != NULL) {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv4 %s", gen, buffer.get());
- return env->NewStringUTF(buffer.get());
- } else {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv4 failed %s", gen, strerror(errno));
- }
- } else if (gen->d.ip->length == 16) {
- // IPv6
- UniquePtr<char[]> buffer(new char[INET6_ADDRSTRLEN]);
- if (inet_ntop(AF_INET6, ip, buffer.get(), INET6_ADDRSTRLEN) != NULL) {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv6 %s", gen, buffer.get());
- return env->NewStringUTF(buffer.get());
- } else {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv6 failed %s", gen, strerror(errno));
- }
- }
-
- /* Invalid IP encodings are pruned out without throwing an exception. */
- return NULL;
- }
- case GEN_RID:
- return ASN1_OBJECT_to_OID_string(env, gen->d.registeredID);
- case GEN_OTHERNAME:
- case GEN_X400:
- default:
- return ASN1ToByteArray<GENERAL_NAME, i2d_GENERAL_NAME>(env, gen);
- }
-
- return NULL;
-}
-
-#define GN_STACK_SUBJECT_ALT_NAME 1
-#define GN_STACK_ISSUER_ALT_NAME 2
-
-static jobjectArray NativeCrypto_get_X509_GENERAL_NAME_stack(JNIEnv* env, jclass, jlong x509Ref,
- jint type) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d)", x509, type);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => x509 == null", x509, type);
- return NULL;
- }
-
- X509_check_ca(x509);
-
- STACK_OF(GENERAL_NAME)* gn_stack;
- Unique_sk_GENERAL_NAME stackHolder;
- if (type == GN_STACK_SUBJECT_ALT_NAME) {
- gn_stack = x509->altname;
- } else if (type == GN_STACK_ISSUER_ALT_NAME) {
- stackHolder.reset(
- static_cast<STACK_OF(GENERAL_NAME)*>(X509_get_ext_d2i(x509, NID_issuer_alt_name,
- NULL, NULL)));
- gn_stack = stackHolder.get();
- } else {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => unknown type", x509, type);
- return NULL;
- }
-
- int count = sk_GENERAL_NAME_num(gn_stack);
- if (count <= 0) {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => null (no entries)", x509, type);
- return NULL;
- }
-
- /*
- * Keep track of how many originally so we can ignore any invalid
- * values later.
- */
- const int origCount = count;
-
- ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, objectArrayClass, NULL));
- for (int i = 0, j = 0; i < origCount; i++, j++) {
- GENERAL_NAME* gen = sk_GENERAL_NAME_value(gn_stack, i);
- ScopedLocalRef<jobject> val(env, GENERAL_NAME_to_jobject(env, gen));
- if (env->ExceptionCheck()) {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => threw exception parsing gen name",
- x509, type);
- return NULL;
- }
-
- /*
- * If it's NULL, we'll have to skip this, reduce the number of total
- * entries, and fix up the array later.
- */
- if (val.get() == NULL) {
- j--;
- count--;
- continue;
- }
-
- ScopedLocalRef<jobjectArray> item(env, env->NewObjectArray(2, objectClass, NULL));
-
- ScopedLocalRef<jobject> type(env, env->CallStaticObjectMethod(integerClass,
- integer_valueOfMethod, gen->type));
- env->SetObjectArrayElement(item.get(), 0, type.get());
- env->SetObjectArrayElement(item.get(), 1, val.get());
-
- env->SetObjectArrayElement(joa.get(), j, item.get());
- }
-
- if (count == 0) {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) shrunk from %d to 0; returning NULL",
- x509, type, origCount);
- joa.reset(NULL);
- } else if (origCount != count) {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) shrunk from %d to %d", x509, type,
- origCount, count);
-
- ScopedLocalRef<jobjectArray> joa_copy(env, env->NewObjectArray(count, objectArrayClass,
- NULL));
-
- for (int i = 0; i < count; i++) {
- ScopedLocalRef<jobject> item(env, env->GetObjectArrayElement(joa.get(), i));
- env->SetObjectArrayElement(joa_copy.get(), i, item.get());
- }
-
- joa.reset(joa_copy.release());
- }
-
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => %d entries", x509, type, count);
- return joa.release();
-}
-
-static jlong NativeCrypto_X509_get_notBefore(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_notBefore(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_notBefore(%p) => x509 == null", x509);
- return 0;
- }
-
- ASN1_TIME* notBefore = X509_get_notBefore(x509);
- JNI_TRACE("X509_get_notBefore(%p) => %p", x509, notBefore);
- return reinterpret_cast<uintptr_t>(notBefore);
-}
-
-static jlong NativeCrypto_X509_get_notAfter(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_notAfter(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_notAfter(%p) => x509 == null", x509);
- return 0;
- }
-
- ASN1_TIME* notAfter = X509_get_notAfter(x509);
- JNI_TRACE("X509_get_notAfter(%p) => %p", x509, notAfter);
- return reinterpret_cast<uintptr_t>(notAfter);
-}
-
-static long NativeCrypto_X509_get_version(JNIEnv*, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_version(%p)", x509);
-
- long version = X509_get_version(x509);
- JNI_TRACE("X509_get_version(%p) => %ld", x509, version);
- return version;
-}
-
-template<typename T>
-static jbyteArray get_X509Type_serialNumber(JNIEnv* env, T* x509Type, ASN1_INTEGER* (*get_serial_func)(T*)) {
- JNI_TRACE("get_X509Type_serialNumber(%p)", x509Type);
-
- if (x509Type == NULL) {
- jniThrowNullPointerException(env, "x509Type == null");
- JNI_TRACE("get_X509Type_serialNumber(%p) => x509Type == null", x509Type);
- return NULL;
- }
-
- ASN1_INTEGER* serialNumber = get_serial_func(x509Type);
- Unique_BIGNUM serialBn(ASN1_INTEGER_to_BN(serialNumber, NULL));
- if (serialBn.get() == NULL) {
- JNI_TRACE("X509_get_serialNumber(%p) => threw exception", x509Type);
- return NULL;
- }
-
- ScopedLocalRef<jbyteArray> serialArray(env, bignumToArray(env, serialBn.get(), "serialBn"));
- if (env->ExceptionCheck()) {
- JNI_TRACE("X509_get_serialNumber(%p) => threw exception", x509Type);
- return NULL;
- }
-
- JNI_TRACE("X509_get_serialNumber(%p) => %p", x509Type, serialArray.get());
- return serialArray.release();
-}
-
-/* OpenSSL includes set_serialNumber but not get. */
-#if !defined(X509_REVOKED_get_serialNumber)
-static ASN1_INTEGER* X509_REVOKED_get_serialNumber(X509_REVOKED* x) {
- return x->serialNumber;
-}
-#endif
-
-static jbyteArray NativeCrypto_X509_get_serialNumber(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_serialNumber(%p)", x509);
- return get_X509Type_serialNumber<X509>(env, x509, X509_get_serialNumber);
-}
-
-static jbyteArray NativeCrypto_X509_REVOKED_get_serialNumber(JNIEnv* env, jclass, jlong x509RevokedRef) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_get_serialNumber(%p)", revoked);
- return get_X509Type_serialNumber<X509_REVOKED>(env, revoked, X509_REVOKED_get_serialNumber);
-}
-
-static void NativeCrypto_X509_verify(JNIEnv* env, jclass, jlong x509Ref, jlong pkeyRef) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("X509_verify(%p, %p)", x509, pkey);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_verify(%p, %p) => x509 == null", x509, pkey);
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("X509_verify(%p, %p) => pkey == null", x509, pkey);
- return;
- }
-
- if (X509_verify(x509, pkey) != 1) {
- throwExceptionIfNecessary(env, "X509_verify");
- JNI_TRACE("X509_verify(%p, %p) => verify failure", x509, pkey);
- } else {
- JNI_TRACE("X509_verify(%p, %p) => verify success", x509, pkey);
- }
-}
-
-static jbyteArray NativeCrypto_get_X509_cert_info_enc(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_cert_info_enc(%p)", x509);
- return ASN1ToByteArray<X509_CINF, i2d_X509_CINF>(env, x509->cert_info);
-}
-
-static jint NativeCrypto_get_X509_ex_flags(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_ex_flags(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_ex_flags(%p) => x509 == null", x509);
- return 0;
- }
-
- X509_check_ca(x509);
-
- return x509->ex_flags;
-}
-
-static jboolean NativeCrypto_X509_check_issued(JNIEnv*, jclass, jlong x509Ref1, jlong x509Ref2) {
- X509* x509_1 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref1));
- X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
- JNI_TRACE("X509_check_issued(%p, %p)", x509_1, x509_2);
-
- int ret = X509_check_issued(x509_1, x509_2);
- JNI_TRACE("X509_check_issued(%p, %p) => %d", x509_1, x509_2, ret);
- return ret;
-}
-
-static void get_X509_signature(X509 *x509, ASN1_BIT_STRING** signature) {
- *signature = x509->signature;
-}
-
-static void get_X509_CRL_signature(X509_CRL *crl, ASN1_BIT_STRING** signature) {
- *signature = crl->signature;
-}
-
-template<typename T>
-static jbyteArray get_X509Type_signature(JNIEnv* env, T* x509Type, void (*get_signature_func)(T*, ASN1_BIT_STRING**)) {
- JNI_TRACE("get_X509Type_signature(%p)", x509Type);
-
- if (x509Type == NULL) {
- jniThrowNullPointerException(env, "x509Type == null");
- JNI_TRACE("get_X509Type_signature(%p) => x509Type == null", x509Type);
- return NULL;
- }
-
- ASN1_BIT_STRING* signature;
- get_signature_func(x509Type, &signature);
-
- ScopedLocalRef<jbyteArray> signatureArray(env, env->NewByteArray(signature->length));
- if (env->ExceptionCheck()) {
- JNI_TRACE("get_X509Type_signature(%p) => threw exception", x509Type);
- return NULL;
- }
-
- ScopedByteArrayRW signatureBytes(env, signatureArray.get());
- if (signatureBytes.get() == NULL) {
- JNI_TRACE("get_X509Type_signature(%p) => using byte array failed", x509Type);
- return NULL;
- }
-
- memcpy(signatureBytes.get(), signature->data, signature->length);
-
- JNI_TRACE("get_X509Type_signature(%p) => %p (%d bytes)", x509Type, signatureArray.get(),
- signature->length);
- return signatureArray.release();
-}
-
-static jbyteArray NativeCrypto_get_X509_signature(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_signature(%p)", x509);
- return get_X509Type_signature<X509>(env, x509, get_X509_signature);
-}
-
-static jbyteArray NativeCrypto_get_X509_CRL_signature(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("get_X509_CRL_signature(%p)", crl);
- return get_X509Type_signature<X509_CRL>(env, crl, get_X509_CRL_signature);
-}
-
-static jlong NativeCrypto_X509_CRL_get0_by_cert(JNIEnv* env, jclass, jlong x509crlRef, jlong x509Ref) {
- X509_CRL* x509crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509crlRef));
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p)", x509crl, x509);
-
- if (x509crl == NULL) {
- jniThrowNullPointerException(env, "x509crl == null");
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => x509crl == null", x509crl, x509);
- return 0;
- } else if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => x509 == null", x509crl, x509);
- return 0;
- }
-
- X509_REVOKED* revoked = NULL;
- int ret = X509_CRL_get0_by_cert(x509crl, &revoked, x509);
- if (ret == 0) {
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => none", x509crl, x509);
- return 0;
- }
-
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => %p", x509crl, x509, revoked);
- return reinterpret_cast<uintptr_t>(revoked);
-}
-
-static jlong NativeCrypto_X509_CRL_get0_by_serial(JNIEnv* env, jclass, jlong x509crlRef, jbyteArray serialArray) {
- X509_CRL* x509crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509crlRef));
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p)", x509crl, serialArray);
-
- if (x509crl == NULL) {
- jniThrowNullPointerException(env, "x509crl == null");
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => crl == null", x509crl, serialArray);
- return 0;
- }
-
- Unique_BIGNUM serialBn(BN_new());
- if (serialBn.get() == NULL) {
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN allocation failed", x509crl, serialArray);
- return 0;
- }
-
- BIGNUM* serialBare = serialBn.get();
- if (!arrayToBignum(env, serialArray, &serialBare)) {
- if (!env->ExceptionCheck()) {
- jniThrowNullPointerException(env, "serial == null");
- }
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN conversion failed", x509crl, serialArray);
- return 0;
- }
-
- Unique_ASN1_INTEGER serialInteger(BN_to_ASN1_INTEGER(serialBn.get(), NULL));
- if (serialInteger.get() == NULL) {
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN conversion failed", x509crl, serialArray);
- return 0;
- }
-
- X509_REVOKED* revoked = NULL;
- int ret = X509_CRL_get0_by_serial(x509crl, &revoked, serialInteger.get());
- if (ret == 0) {
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => none", x509crl, serialArray);
- return 0;
- }
-
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => %p", x509crl, serialArray, revoked);
- return reinterpret_cast<uintptr_t>(revoked);
-}
-
-
-/* This appears to be missing from OpenSSL. */
-#if !defined(X509_REVOKED_dup)
-X509_REVOKED* X509_REVOKED_dup(X509_REVOKED* x) {
- return reinterpret_cast<X509_REVOKED*>(ASN1_item_dup(ASN1_ITEM_rptr(X509_REVOKED), x));
-}
-#endif
-
-static jlongArray NativeCrypto_X509_CRL_get_REVOKED(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_REVOKED(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- return NULL;
- }
-
- STACK_OF(X509_REVOKED)* stack = X509_CRL_get_REVOKED(crl);
- if (stack == NULL) {
- JNI_TRACE("X509_CRL_get_REVOKED(%p) => stack is null", crl);
- return NULL;
- }
-
- size_t size = sk_X509_REVOKED_num(stack);
-
- ScopedLocalRef<jlongArray> revokedArray(env, env->NewLongArray(size));
- ScopedLongArrayRW revoked(env, revokedArray.get());
- for (size_t i = 0; i < size; i++) {
- X509_REVOKED* item = reinterpret_cast<X509_REVOKED*>(sk_X509_REVOKED_value(stack, i));
- revoked[i] = reinterpret_cast<uintptr_t>(X509_REVOKED_dup(item));
- }
-
- JNI_TRACE("X509_CRL_get_REVOKED(%p) => %p [size=%d]", stack, revokedArray.get(), size);
- return revokedArray.release();
-}
-
-static jbyteArray NativeCrypto_i2d_X509_CRL(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("i2d_X509_CRL(%p)", crl);
- return ASN1ToByteArray<X509_CRL, i2d_X509_CRL>(env, crl);
-}
-
-static void NativeCrypto_X509_CRL_free(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_free(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_free(%p) => crl == null", crl);
- return;
- }
-
- X509_CRL_free(crl);
-}
-
-static void NativeCrypto_X509_CRL_print(JNIEnv* env, jclass, jlong bioRef, jlong x509CrlRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_print(%p, %p)", bio, crl);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("X509_CRL_print(%p, %p) => bio == null", bio, crl);
- return;
- }
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_print(%p, %p) => crl == null", bio, crl);
- return;
- }
-
- if (!X509_CRL_print(bio, crl)) {
- throwExceptionIfNecessary(env, "X509_CRL_print");
- JNI_TRACE("X509_CRL_print(%p, %p) => threw error", bio, crl);
- } else {
- JNI_TRACE("X509_CRL_print(%p, %p) => success", bio, crl);
- }
-}
-
-static jstring NativeCrypto_get_X509_CRL_sig_alg_oid(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("get_X509_CRL_sig_alg_oid(%p)", crl);
-
- if (crl == NULL || crl->sig_alg == NULL) {
- jniThrowNullPointerException(env, "crl == NULL || crl->sig_alg == NULL");
- JNI_TRACE("get_X509_CRL_sig_alg_oid(%p) => crl == NULL", crl);
- return NULL;
- }
-
- return ASN1_OBJECT_to_OID_string(env, crl->sig_alg->algorithm);
-}
-
-static jbyteArray NativeCrypto_get_X509_CRL_sig_alg_parameter(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p) => crl == null", crl);
- return NULL;
- }
-
- if (crl->sig_alg->parameter == NULL) {
- JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p) => null", crl);
- return NULL;
- }
-
- return ASN1ToByteArray<ASN1_TYPE, i2d_ASN1_TYPE>(env, crl->sig_alg->parameter);
-}
-
-static jbyteArray NativeCrypto_X509_CRL_get_issuer_name(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_issuer_name(%p)", crl);
- return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_CRL_get_issuer(crl));
-}
-
-static long NativeCrypto_X509_CRL_get_version(JNIEnv*, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_version(%p)", crl);
-
- long version = X509_CRL_get_version(crl);
- JNI_TRACE("X509_CRL_get_version(%p) => %ld", crl, version);
- return version;
-}
-
-template<typename T, int (*get_ext_by_OBJ_func)(T*, ASN1_OBJECT*, int),
- X509_EXTENSION* (*get_ext_func)(T*, int)>
-static X509_EXTENSION *X509Type_get_ext(JNIEnv* env, T* x509Type, jstring oidString) {
- JNI_TRACE("X509Type_get_ext(%p)", x509Type);
-
- if (x509Type == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- return NULL;
- }
-
- ScopedUtfChars oid(env, oidString);
- if (oid.c_str() == NULL) {
- return NULL;
- }
-
- Unique_ASN1_OBJECT asn1(OBJ_txt2obj(oid.c_str(), 1));
- if (asn1.get() == NULL) {
- JNI_TRACE("X509Type_get_ext(%p, %s) => oid conversion failed", x509Type, oid.c_str());
- freeOpenSslErrorState();
- return NULL;
- }
-
- int extIndex = get_ext_by_OBJ_func(x509Type, asn1.get(), -1);
- if (extIndex == -1) {
- JNI_TRACE("X509Type_get_ext(%p, %s) => ext not found", x509Type, oid.c_str());
- return NULL;
- }
-
- X509_EXTENSION* ext = get_ext_func(x509Type, extIndex);
- JNI_TRACE("X509Type_get_ext(%p, %s) => %p", x509Type, oid.c_str(), ext);
- return ext;
-}
-
-template<typename T, int (*get_ext_by_OBJ_func)(T*, ASN1_OBJECT*, int),
- X509_EXTENSION* (*get_ext_func)(T*, int)>
-static jbyteArray X509Type_get_ext_oid(JNIEnv* env, T* x509Type, jstring oidString) {
- X509_EXTENSION* ext = X509Type_get_ext<T, get_ext_by_OBJ_func, get_ext_func>(env, x509Type,
- oidString);
- if (ext == NULL) {
- JNI_TRACE("X509Type_get_ext_oid(%p, %p) => fetching extension failed", x509Type, oidString);
- return NULL;
- }
-
- JNI_TRACE("X509Type_get_ext_oid(%p, %p) => %p", x509Type, oidString, ext->value);
- return ASN1ToByteArray<ASN1_OCTET_STRING, i2d_ASN1_OCTET_STRING>(env, ext->value);
-}
-
-static jint NativeCrypto_X509_CRL_get_ext(JNIEnv* env, jclass, jlong x509CrlRef, jstring oid) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_ext(%p, %p)", crl, oid);
- X509_EXTENSION* ext = X509Type_get_ext<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(
- env, crl, oid);
- JNI_TRACE("X509_CRL_get_ext(%p, %p) => %p", crl, oid, ext);
- return reinterpret_cast<uintptr_t>(ext);
-}
-
-static jint NativeCrypto_X509_REVOKED_get_ext(JNIEnv* env, jclass, jlong x509RevokedRef,
- jstring oid) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_get_ext(%p, %p)", revoked, oid);
- X509_EXTENSION* ext = X509Type_get_ext<X509_REVOKED, X509_REVOKED_get_ext_by_OBJ,
- X509_REVOKED_get_ext>(env, revoked, oid);
- JNI_TRACE("X509_REVOKED_get_ext(%p, %p) => %p", revoked, oid, ext);
- return reinterpret_cast<uintptr_t>(ext);
-}
-
-static jlong NativeCrypto_X509_REVOKED_dup(JNIEnv* env, jclass, jlong x509RevokedRef) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_dup(%p)", revoked);
-
- if (revoked == NULL) {
- jniThrowNullPointerException(env, "revoked == null");
- JNI_TRACE("X509_REVOKED_dup(%p) => revoked == null", revoked);
- return 0;
- }
-
- X509_REVOKED* dup = X509_REVOKED_dup(revoked);
- JNI_TRACE("X509_REVOKED_dup(%p) => %p", revoked, dup);
- return reinterpret_cast<uintptr_t>(dup);
-}
-
-static jlong NativeCrypto_get_X509_REVOKED_revocationDate(JNIEnv* env, jclass, jlong x509RevokedRef) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("get_X509_REVOKED_revocationDate(%p)", revoked);
-
- if (revoked == NULL) {
- jniThrowNullPointerException(env, "revoked == null");
- JNI_TRACE("get_X509_REVOKED_revocationDate(%p) => revoked == null", revoked);
- return 0;
- }
-
- JNI_TRACE("get_X509_REVOKED_revocationDate(%p) => %p", revoked, revoked->revocationDate);
- return reinterpret_cast<uintptr_t>(revoked->revocationDate);
-}
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wwrite-strings"
-static void NativeCrypto_X509_REVOKED_print(JNIEnv* env, jclass, jlong bioRef, jlong x509RevokedRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_print(%p, %p)", bio, revoked);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("X509_REVOKED_print(%p, %p) => bio == null", bio, revoked);
- return;
- }
-
- if (revoked == NULL) {
- jniThrowNullPointerException(env, "revoked == null");
- JNI_TRACE("X509_REVOKED_print(%p, %p) => revoked == null", bio, revoked);
- return;
- }
-
- BIO_printf(bio, "Serial Number: ");
- i2a_ASN1_INTEGER(bio, revoked->serialNumber);
- BIO_printf(bio, "\nRevocation Date: ");
- ASN1_TIME_print(bio, revoked->revocationDate);
- BIO_printf(bio, "\n");
- X509V3_extensions_print(bio, "CRL entry extensions", revoked->extensions, 0, 0);
-}
-#pragma GCC diagnostic pop
-
-static jbyteArray NativeCrypto_get_X509_CRL_crl_enc(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("get_X509_CRL_crl_enc(%p)", crl);
- return ASN1ToByteArray<X509_CRL_INFO, i2d_X509_CRL_INFO>(env, crl->crl);
-}
-
-static void NativeCrypto_X509_CRL_verify(JNIEnv* env, jclass, jlong x509CrlRef, jlong pkeyRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("X509_CRL_verify(%p, %p)", crl, pkey);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_verify(%p, %p) => crl == null", crl, pkey);
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("X509_CRL_verify(%p, %p) => pkey == null", crl, pkey);
- return;
- }
-
- if (X509_CRL_verify(crl, pkey) != 1) {
- throwExceptionIfNecessary(env, "X509_CRL_verify");
- JNI_TRACE("X509_CRL_verify(%p, %p) => verify failure", crl, pkey);
- } else {
- JNI_TRACE("X509_CRL_verify(%p, %p) => verify success", crl, pkey);
- }
-}
-
-static jlong NativeCrypto_X509_CRL_get_lastUpdate(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_lastUpdate(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_lastUpdate(%p) => crl == null", crl);
- return 0;
- }
-
- ASN1_TIME* lastUpdate = X509_CRL_get_lastUpdate(crl);
- JNI_TRACE("X509_CRL_get_lastUpdate(%p) => %p", crl, lastUpdate);
- return reinterpret_cast<uintptr_t>(lastUpdate);
-}
-
-static jlong NativeCrypto_X509_CRL_get_nextUpdate(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_nextUpdate(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_nextUpdate(%p) => crl == null", crl);
- return 0;
- }
-
- ASN1_TIME* nextUpdate = X509_CRL_get_nextUpdate(crl);
- JNI_TRACE("X509_CRL_get_nextUpdate(%p) => %p", crl, nextUpdate);
- return reinterpret_cast<uintptr_t>(nextUpdate);
-}
-
-static jbyteArray NativeCrypto_i2d_X509_REVOKED(JNIEnv* env, jclass, jlong x509RevokedRef) {
- X509_REVOKED* x509Revoked =
- reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("i2d_X509_REVOKED(%p)", x509Revoked);
- return ASN1ToByteArray<X509_REVOKED, i2d_X509_REVOKED>(env, x509Revoked);
-}
-
-static jint NativeCrypto_X509_supported_extension(JNIEnv* env, jclass, jlong x509ExtensionRef) {
- X509_EXTENSION* ext = reinterpret_cast<X509_EXTENSION*>(static_cast<uintptr_t>(x509ExtensionRef));
-
- if (ext == NULL) {
- jniThrowNullPointerException(env, "ext == NULL");
- return 0;
- }
-
- return X509_supported_extension(ext);
-}
-
-static inline void get_ASN1_TIME_data(char **data, int* output, size_t len) {
- char c = **data;
- **data = '\0';
- *data -= len;
- *output = atoi(*data);
- *(*data + len) = c;
-}
-
-static void NativeCrypto_ASN1_TIME_to_Calendar(JNIEnv* env, jclass, jlong asn1TimeRef, jobject calendar) {
- ASN1_TIME* asn1Time = reinterpret_cast<ASN1_TIME*>(static_cast<uintptr_t>(asn1TimeRef));
- JNI_TRACE("ASN1_TIME_to_Calendar(%p, %p)", asn1Time, calendar);
-
- if (asn1Time == NULL) {
- jniThrowNullPointerException(env, "asn1Time == null");
- return;
- }
-
- Unique_ASN1_GENERALIZEDTIME gen(ASN1_TIME_to_generalizedtime(asn1Time, NULL));
- if (gen.get() == NULL) {
- jniThrowNullPointerException(env, "asn1Time == null");
- return;
- }
-
- if (gen->length < 14 || gen->data == NULL) {
- jniThrowNullPointerException(env, "gen->length < 14 || gen->data == NULL");
- return;
- }
-
- int sec, min, hour, mday, mon, year;
-
- char *p = (char*) &gen->data[14];
-
- get_ASN1_TIME_data(&p, &sec, 2);
- get_ASN1_TIME_data(&p, &min, 2);
- get_ASN1_TIME_data(&p, &hour, 2);
- get_ASN1_TIME_data(&p, &mday, 2);
- get_ASN1_TIME_data(&p, &mon, 2);
- get_ASN1_TIME_data(&p, &year, 4);
-
- env->CallVoidMethod(calendar, calendar_setMethod, year, mon - 1, mday, hour, min, sec);
-}
-
-static jstring NativeCrypto_OBJ_txt2nid_oid(JNIEnv* env, jclass, jstring oidStr) {
- JNI_TRACE("OBJ_txt2nid_oid(%p)", oidStr);
-
- ScopedUtfChars oid(env, oidStr);
- if (oid.c_str() == NULL) {
- return NULL;
- }
-
- JNI_TRACE("OBJ_txt2nid_oid(%s)", oid.c_str());
-
- int nid = OBJ_txt2nid(oid.c_str());
- if (nid == NID_undef) {
- JNI_TRACE("OBJ_txt2nid_oid(%s) => NID_undef", oid.c_str());
- freeOpenSslErrorState();
- return NULL;
- }
-
- Unique_ASN1_OBJECT obj(OBJ_nid2obj(nid));
- if (obj.get() == NULL) {
- throwExceptionIfNecessary(env, "OBJ_nid2obj");
- return NULL;
- }
-
- ScopedLocalRef<jstring> ouputStr(env, ASN1_OBJECT_to_OID_string(env, obj.get()));
- JNI_TRACE("OBJ_txt2nid_oid(%s) => %p", oid.c_str(), ouputStr.get());
- return ouputStr.release();
-}
-
-static jstring NativeCrypto_X509_NAME_print_ex(JNIEnv* env, jclass, jlong x509NameRef, jlong jflags) {
- X509_NAME* x509name = reinterpret_cast<X509_NAME*>(static_cast<uintptr_t>(x509NameRef));
- unsigned long flags = static_cast<unsigned long>(jflags);
- JNI_TRACE("X509_NAME_print_ex(%p, %ld)", x509name, flags);
-
- if (x509name == NULL) {
- jniThrowNullPointerException(env, "x509name == null");
- JNI_TRACE("X509_NAME_print_ex(%p, %ld) => x509name == null", x509name, flags);
- return NULL;
- }
-
- return X509_NAME_to_jstring(env, x509name, flags);
-}
-
-template <typename T, T* (*d2i_func)(BIO*, T**)>
-static jlong d2i_ASN1Object_to_jlong(JNIEnv* env, jlong bioRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("d2i_ASN1Object_to_jlong(%p)", bio);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- return 0;
- }
-
- T* x = d2i_func(bio, NULL);
- if (x == NULL) {
- throwExceptionIfNecessary(env, "d2i_ASN1Object_to_jlong");
- return 0;
- }
-
- return reinterpret_cast<uintptr_t>(x);
-}
-
-static jlong NativeCrypto_d2i_X509_CRL_bio(JNIEnv* env, jclass, jlong bioRef) {
- return d2i_ASN1Object_to_jlong<X509_CRL, d2i_X509_CRL_bio>(env, bioRef);
-}
-
-static jlong NativeCrypto_d2i_X509_bio(JNIEnv* env, jclass, jlong bioRef) {
- return d2i_ASN1Object_to_jlong<X509, d2i_X509_bio>(env, bioRef);
-}
-
-static jlong NativeCrypto_d2i_X509(JNIEnv* env, jclass, jbyteArray certBytes) {
- X509* x = ByteArrayToASN1<X509, d2i_X509>(env, certBytes);
- return reinterpret_cast<uintptr_t>(x);
-}
-
-static jbyteArray NativeCrypto_i2d_X509(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("i2d_X509(%p)", x509);
- return ASN1ToByteArray<X509, i2d_X509>(env, x509);
-}
-
-static jbyteArray NativeCrypto_i2d_X509_PUBKEY(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("i2d_X509_PUBKEY(%p)", x509);
- return ASN1ToByteArray<X509_PUBKEY, i2d_X509_PUBKEY>(env, X509_get_X509_PUBKEY(x509));
-}
-
-
-template<typename T, T* (*PEM_read_func)(BIO*, T**, pem_password_cb*, void*)>
-static jlong PEM_ASN1Object_to_jlong(JNIEnv* env, jlong bioRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("PEM_ASN1Object_to_jlong(%p)", bio);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => bio == null", bio);
- return 0;
- }
-
- T* x = PEM_read_func(bio, NULL, NULL, NULL);
- if (x == NULL) {
- throwExceptionIfNecessary(env, "PEM_ASN1Object_to_jlong");
- // Sometimes the PEM functions fail without pushing an error
- if (!env->ExceptionCheck()) {
- jniThrowRuntimeException(env, "Failure parsing PEM");
- }
- JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => threw exception", bio);
- return 0;
- }
-
- JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => %p", bio, x);
- return reinterpret_cast<uintptr_t>(x);
-}
-
-static jlong NativeCrypto_PEM_read_bio_X509(JNIEnv* env, jclass, jlong bioRef) {
- JNI_TRACE("PEM_read_bio_X509(0x%llx)", bioRef);
- return PEM_ASN1Object_to_jlong<X509, PEM_read_bio_X509>(env, bioRef);
-}
-
-static jlong NativeCrypto_PEM_read_bio_X509_CRL(JNIEnv* env, jclass, jlong bioRef) {
- JNI_TRACE("PEM_read_bio_X509_CRL(0x%llx)", bioRef);
- return PEM_ASN1Object_to_jlong<X509_CRL, PEM_read_bio_X509_CRL>(env, bioRef);
-}
-
-static STACK_OF(X509)* PKCS7_get_certs(PKCS7* pkcs7) {
- if (PKCS7_type_is_signed(pkcs7)) {
- return pkcs7->d.sign->cert;
- } else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) {
- return pkcs7->d.signed_and_enveloped->cert;
- } else {
- JNI_TRACE("PKCS7_get_certs(%p) => unknown PKCS7 type", pkcs7);
- return NULL;
- }
-}
-
-static STACK_OF(X509_CRL)* PKCS7_get_CRLs(PKCS7* pkcs7) {
- if (PKCS7_type_is_signed(pkcs7)) {
- return pkcs7->d.sign->crl;
- } else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) {
- return pkcs7->d.signed_and_enveloped->crl;
- } else {
- JNI_TRACE("PKCS7_get_CRLs(%p) => unknown PKCS7 type", pkcs7);
- return NULL;
- }
-}
-
-template <typename T, typename T_stack>
-static jlongArray PKCS7_to_ItemArray(JNIEnv* env, T_stack* stack, T* (*dup_func)(T*))
-{
- if (stack == NULL) {
- return NULL;
- }
-
- ScopedLocalRef<jlongArray> ref_array(env, NULL);
- size_t size = sk_num(reinterpret_cast<_STACK*>(stack));
- ref_array.reset(env->NewLongArray(size));
- ScopedLongArrayRW items(env, ref_array.get());
- for (size_t i = 0; i < size; i++) {
- T* item = reinterpret_cast<T*>(sk_value(reinterpret_cast<_STACK*>(stack), i));
- items[i] = reinterpret_cast<uintptr_t>(dup_func(item));
- }
-
- JNI_TRACE("PKCS7_to_ItemArray(%p) => %p [size=%d]", stack, ref_array.get(), size);
- return ref_array.release();
-}
-
-#define PKCS7_CERTS 1
-#define PKCS7_CRLS 2
-
-static jlongArray NativeCrypto_PEM_read_bio_PKCS7(JNIEnv* env, jclass, jlong bioRef, jint which) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p)", bio);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p) => bio == null", bio);
- return 0;
- }
-
- Unique_PKCS7 pkcs7(PEM_read_bio_PKCS7(bio, NULL, NULL, NULL));
- if (pkcs7.get() == NULL) {
- throwExceptionIfNecessary(env, "PEM_read_bio_PKCS7_CRLs");
- JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p) => threw exception", bio);
- return 0;
- }
-
- switch (which) {
- case PKCS7_CERTS:
- return PKCS7_to_ItemArray<X509, STACK_OF(X509)>(env, PKCS7_get_certs(pkcs7.get()), X509_dup);
- case PKCS7_CRLS:
- return PKCS7_to_ItemArray<X509_CRL, STACK_OF(X509_CRL)>(env, PKCS7_get_CRLs(pkcs7.get()),
- X509_CRL_dup);
- default:
- jniThrowRuntimeException(env, "unknown PKCS7 field");
- return NULL;
- }
-}
-
-static jlongArray NativeCrypto_d2i_PKCS7_bio(JNIEnv* env, jclass, jlong bioRef, jint which) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("d2i_PKCS7_bio(%p, %d)", bio, which);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("d2i_PKCS7_bio(%p, %d) => bio == null", bio, which);
- return 0;
- }
-
- Unique_PKCS7 pkcs7(d2i_PKCS7_bio(bio, NULL));
- if (pkcs7.get() == NULL) {
- throwExceptionIfNecessary(env, "d2i_PKCS7_bio");
- JNI_TRACE("d2i_PKCS7_bio(%p, %d) => threw exception", bio, which);
- return 0;
- }
-
- switch (which) {
- case PKCS7_CERTS:
- return PKCS7_to_ItemArray<X509, STACK_OF(X509)>(env, PKCS7_get_certs(pkcs7.get()), X509_dup);
- case PKCS7_CRLS:
- return PKCS7_to_ItemArray<X509_CRL, STACK_OF(X509_CRL)>(env, PKCS7_get_CRLs(pkcs7.get()),
- X509_CRL_dup);
- default:
- jniThrowRuntimeException(env, "unknown PKCS7 field");
- return NULL;
- }
-}
-
-static jbyteArray NativeCrypto_i2d_PKCS7(JNIEnv* env, jclass, jlongArray certsArray) {
- JNI_TRACE("i2d_PKCS7(%p)", certsArray);
-
- Unique_PKCS7 pkcs7(PKCS7_new());
- if (pkcs7.get() == NULL) {
- jniThrowNullPointerException(env, "pkcs7 == null");
- JNI_TRACE("i2d_PKCS7(%p) => pkcs7 == null", certsArray);
- return NULL;
- }
-
- if (PKCS7_set_type(pkcs7.get(), NID_pkcs7_signed) != 1) {
- throwExceptionIfNecessary(env, "PKCS7_set_type");
- return NULL;
- }
-
- ScopedLongArrayRO certs(env, certsArray);
- for (size_t i = 0; i < certs.size(); i++) {
- X509* item = reinterpret_cast<X509*>(certs[i]);
- if (PKCS7_add_certificate(pkcs7.get(), item) != 1) {
- throwExceptionIfNecessary(env, "i2d_PKCS7");
- return NULL;
- }
- }
-
- JNI_TRACE("i2d_PKCS7(%p) => %d certs", certsArray, certs.size());
- return ASN1ToByteArray<PKCS7, i2d_PKCS7>(env, pkcs7.get());
-}
-
-typedef STACK_OF(X509) PKIPATH;
-
-ASN1_ITEM_TEMPLATE(PKIPATH) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PkiPath, X509)
-ASN1_ITEM_TEMPLATE_END(PKIPATH)
-
-static jlongArray NativeCrypto_ASN1_seq_unpack_X509_bio(JNIEnv* env, jclass, jlong bioRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("ASN1_seq_unpack_X509_bio(%p)", bio);
-
- Unique_sk_X509 path((PKIPATH*) ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKIPATH), bio, NULL));
- if (path.get() == NULL) {
- throwExceptionIfNecessary(env, "ASN1_seq_unpack_X509_bio");
- return NULL;
- }
-
- size_t size = sk_X509_num(path.get());
-
- ScopedLocalRef<jlongArray> certArray(env, env->NewLongArray(size));
- ScopedLongArrayRW certs(env, certArray.get());
- for (size_t i = 0; i < size; i++) {
- X509* item = reinterpret_cast<X509*>(sk_X509_shift(path.get()));
- certs[i] = reinterpret_cast<uintptr_t>(item);
- }
-
- JNI_TRACE("ASN1_seq_unpack_X509_bio(%p) => returns %d items", bio, size);
- return certArray.release();
-}
-
-static jbyteArray NativeCrypto_ASN1_seq_pack_X509(JNIEnv* env, jclass, jlongArray certs) {
- JNI_TRACE("ASN1_seq_pack_X509(%p)", certs);
- ScopedLongArrayRO certsArray(env, certs);
- if (certsArray.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => failed to get certs array", certs);
- return NULL;
- }
-
- Unique_sk_X509 certStack(sk_X509_new_null());
- if (certStack.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => failed to make cert stack", certs);
- return NULL;
- }
-
- for (size_t i = 0; i < certsArray.size(); i++) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(certsArray[i]));
- sk_X509_push(certStack.get(), X509_dup_nocopy(x509));
- }
-
- int len;
- Unique_OPENSSL_str encoded(ASN1_seq_pack(
- reinterpret_cast<STACK_OF(OPENSSL_BLOCK)*>(
- reinterpret_cast<uintptr_t>(certStack.get())),
- reinterpret_cast<int (*)(void*, unsigned char**)>(i2d_X509), NULL, &len));
- if (encoded.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => trouble encoding", certs);
- return NULL;
- }
-
- ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
- if (byteArray.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => creating byte array failed", certs);
- return NULL;
- }
-
- ScopedByteArrayRW bytes(env, byteArray.get());
- if (bytes.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => using byte array failed", certs);
- return NULL;
- }
-
- unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
- memcpy(p, encoded.get(), len);
-
- return byteArray.release();
-}
-
-static void NativeCrypto_X509_free(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_free(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_free(%p) => x509 == null", x509);
- return;
- }
-
- X509_free(x509);
-}
-
-static jint NativeCrypto_X509_cmp(JNIEnv* env, jclass, jlong x509Ref1, jlong x509Ref2) {
- X509* x509_1 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref1));
- X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
- JNI_TRACE("X509_cmp(%p, %p)", x509_1, x509_2);
-
- if (x509_1 == NULL) {
- jniThrowNullPointerException(env, "x509_1 == null");
- JNI_TRACE("X509_cmp(%p, %p) => x509_1 == null", x509_1, x509_2);
- return -1;
- }
-
- if (x509_2 == NULL) {
- jniThrowNullPointerException(env, "x509_2 == null");
- JNI_TRACE("X509_cmp(%p, %p) => x509_2 == null", x509_1, x509_2);
- return -1;
- }
-
- int ret = X509_cmp(x509_1, x509_2);
- JNI_TRACE("X509_cmp(%p, %p) => %d", x509_1, x509_2, ret);
- return ret;
-}
-
-static jint NativeCrypto_get_X509_hashCode(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_hashCode(%p) => x509 == null", x509);
- return 0;
- }
-
- // Force caching extensions.
- X509_check_ca(x509);
-
- jint hashCode = 0L;
- for (int i = 0; i < SHA_DIGEST_LENGTH; i++) {
- hashCode = 31 * hashCode + x509->sha1_hash[i];
- }
- return hashCode;
-}
-
-static void NativeCrypto_X509_print_ex(JNIEnv* env, jclass, jlong bioRef, jlong x509Ref,
- jlong nmflagJava, jlong certflagJava) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- long nmflag = static_cast<long>(nmflagJava);
- long certflag = static_cast<long>(certflagJava);
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld)", bio, x509, nmflag, certflag);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => bio == null", bio, x509, nmflag, certflag);
- return;
- }
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => x509 == null", bio, x509, nmflag, certflag);
- return;
- }
-
- if (!X509_print_ex(bio, x509, nmflag, certflag)) {
- throwExceptionIfNecessary(env, "X509_print_ex");
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => threw error", bio, x509, nmflag, certflag);
- } else {
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => success", bio, x509, nmflag, certflag);
- }
-}
-
-static jlong NativeCrypto_X509_get_pubkey(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_pubkey(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_pubkey(%p) => x509 == null", x509);
- return 0;
- }
-
- Unique_EVP_PKEY pkey(X509_get_pubkey(x509));
- if (pkey.get() == NULL) {
- throwExceptionIfNecessary(env, "X509_get_pubkey");
- return 0;
- }
-
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jbyteArray NativeCrypto_X509_get_issuer_name(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_issuer_name(%p)", x509);
- return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_get_issuer_name(x509));
-}
-
-static jbyteArray NativeCrypto_X509_get_subject_name(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_subject_name(%p)", x509);
- return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_get_subject_name(x509));
-}
-
-static jstring NativeCrypto_get_X509_pubkey_oid(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_pubkey_oid(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_pubkey_oid(%p) => x509 == null", x509);
- return NULL;
- }
-
- X509_PUBKEY* pubkey = X509_get_X509_PUBKEY(x509);
- return ASN1_OBJECT_to_OID_string(env, pubkey->algor->algorithm);
-}
-
-static jstring NativeCrypto_get_X509_sig_alg_oid(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_sig_alg_oid(%p)", x509);
-
- if (x509 == NULL || x509->sig_alg == NULL) {
- jniThrowNullPointerException(env, "x509 == NULL || x509->sig_alg == NULL");
- JNI_TRACE("get_X509_sig_alg_oid(%p) => x509 == NULL", x509);
- return NULL;
- }
-
- return ASN1_OBJECT_to_OID_string(env, x509->sig_alg->algorithm);
-}
-
-static jbyteArray NativeCrypto_get_X509_sig_alg_parameter(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_sig_alg_parameter(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_sig_alg_parameter(%p) => x509 == null", x509);
- return NULL;
- }
-
- if (x509->sig_alg->parameter == NULL) {
- JNI_TRACE("get_X509_sig_alg_parameter(%p) => null", x509);
- return NULL;
- }
-
- return ASN1ToByteArray<ASN1_TYPE, i2d_ASN1_TYPE>(env, x509->sig_alg->parameter);
-}
-
-static jbooleanArray NativeCrypto_get_X509_issuerUID(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_issuerUID(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_issuerUID(%p) => x509 == null", x509);
- return NULL;
- }
-
- if (x509->cert_info->issuerUID == NULL) {
- JNI_TRACE("get_X509_issuerUID(%p) => null", x509);
- return NULL;
- }
-
- return ASN1BitStringToBooleanArray(env, x509->cert_info->issuerUID);
-}
-static jbooleanArray NativeCrypto_get_X509_subjectUID(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_subjectUID(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_subjectUID(%p) => x509 == null", x509);
- return NULL;
- }
-
- if (x509->cert_info->subjectUID == NULL) {
- JNI_TRACE("get_X509_subjectUID(%p) => null", x509);
- return NULL;
- }
-
- return ASN1BitStringToBooleanArray(env, x509->cert_info->subjectUID);
-}
-
-static jbooleanArray NativeCrypto_get_X509_ex_kusage(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_ex_kusage(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_ex_kusage(%p) => x509 == null", x509);
- return NULL;
- }
-
- Unique_ASN1_BIT_STRING bitStr(static_cast<ASN1_BIT_STRING*>(
- X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL)));
- if (bitStr.get() == NULL) {
- JNI_TRACE("get_X509_ex_kusage(%p) => null", x509);
- return NULL;
- }
-
- return ASN1BitStringToBooleanArray(env, bitStr.get());
-}
-
-static jobjectArray NativeCrypto_get_X509_ex_xkusage(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_ex_xkusage(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_ex_xkusage(%p) => x509 == null", x509);
- return NULL;
- }
-
- Unique_sk_ASN1_OBJECT objArray(static_cast<STACK_OF(ASN1_OBJECT)*>(
- X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL)));
- if (objArray.get() == NULL) {
- JNI_TRACE("get_X509_ex_xkusage(%p) => null", x509);
- return NULL;
- }
-
- size_t size = sk_ASN1_OBJECT_num(objArray.get());
- ScopedLocalRef<jobjectArray> exKeyUsage(env, env->NewObjectArray(size, stringClass, NULL));
- if (exKeyUsage.get() == NULL) {
- return NULL;
- }
-
- for (size_t i = 0; i < size; i++) {
- ScopedLocalRef<jstring> oidStr(env, ASN1_OBJECT_to_OID_string(env,
- sk_ASN1_OBJECT_value(objArray.get(), i)));
- env->SetObjectArrayElement(exKeyUsage.get(), i, oidStr.get());
- }
-
- JNI_TRACE("get_X509_ex_xkusage(%p) => success (%d entries)", x509, size);
- return exKeyUsage.release();
-}
-
-static jint NativeCrypto_get_X509_ex_pathlen(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_ex_pathlen(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_ex_pathlen(%p) => x509 == null", x509);
- return 0;
- }
-
- /* Just need to do this to cache the ex_* values. */
- X509_check_ca(x509);
-
- JNI_TRACE("get_X509_ex_pathlen(%p) => %ld", x509, x509->ex_pathlen);
- return x509->ex_pathlen;
-}
-
-static jbyteArray NativeCrypto_X509_get_ext_oid(JNIEnv* env, jclass, jlong x509Ref,
- jstring oidString) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_ext_oid(%p, %p)", x509, oidString);
- return X509Type_get_ext_oid<X509, X509_get_ext_by_OBJ, X509_get_ext>(env, x509, oidString);
-}
-
-static jbyteArray NativeCrypto_X509_CRL_get_ext_oid(JNIEnv* env, jclass, jlong x509CrlRef,
- jstring oidString) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_ext_oid(%p, %p)", crl, oidString);
- return X509Type_get_ext_oid<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(env, crl,
- oidString);
-}
-
-static jbyteArray NativeCrypto_X509_REVOKED_get_ext_oid(JNIEnv* env, jclass, jlong x509RevokedRef,
- jstring oidString) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_get_ext_oid(%p, %p)", revoked, oidString);
- return X509Type_get_ext_oid<X509_REVOKED, X509_REVOKED_get_ext_by_OBJ, X509_REVOKED_get_ext>(
- env, revoked, oidString);
-}
-
-template<typename T, int (*get_ext_by_critical_func)(T*, int, int), X509_EXTENSION* (*get_ext_func)(T*, int)>
-static jobjectArray get_X509Type_ext_oids(JNIEnv* env, jlong x509Ref, jint critical) {
- T* x509 = reinterpret_cast<T*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509Type_ext_oids(%p, %d)", x509, critical);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509Type_ext_oids(%p, %d) => x509 == null", x509, critical);
- return NULL;
- }
-
- int lastPos = -1;
- int count = 0;
- while ((lastPos = get_ext_by_critical_func(x509, critical, lastPos)) != -1) {
- count++;
- }
-
- JNI_TRACE("get_X509Type_ext_oids(%p, %d) has %d entries", x509, critical, count);
-
- ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, stringClass, NULL));
- if (joa.get() == NULL) {
- JNI_TRACE("get_X509Type_ext_oids(%p, %d) => fail to allocate result array", x509, critical);
- return NULL;
- }
-
- lastPos = -1;
- count = 0;
- while ((lastPos = get_ext_by_critical_func(x509, critical, lastPos)) != -1) {
- X509_EXTENSION* ext = get_ext_func(x509, lastPos);
-
- ScopedLocalRef<jstring> extOid(env, ASN1_OBJECT_to_OID_string(env, ext->object));
- if (extOid.get() == NULL) {
- JNI_TRACE("get_X509Type_ext_oids(%p) => couldn't get OID", x509);
- return NULL;
- }
-
- env->SetObjectArrayElement(joa.get(), count++, extOid.get());
- }
-
- JNI_TRACE("get_X509Type_ext_oids(%p, %d) => success", x509, critical);
- return joa.release();
-}
-
-static jobjectArray NativeCrypto_get_X509_ext_oids(JNIEnv* env, jclass, jlong x509Ref,
- jint critical) {
- JNI_TRACE("get_X509_ext_oids(0x%llx, %d)", x509Ref, critical);
- return get_X509Type_ext_oids<X509, X509_get_ext_by_critical, X509_get_ext>(env, x509Ref,
- critical);
-}
-
-static jobjectArray NativeCrypto_get_X509_CRL_ext_oids(JNIEnv* env, jclass, jlong x509CrlRef,
- jint critical) {
- JNI_TRACE("get_X509_CRL_ext_oids(0x%llx, %d)", x509CrlRef, critical);
- return get_X509Type_ext_oids<X509_CRL, X509_CRL_get_ext_by_critical, X509_CRL_get_ext>(env,
- x509CrlRef, critical);
-}
-
-static jobjectArray NativeCrypto_get_X509_REVOKED_ext_oids(JNIEnv* env, jclass, jlong x509RevokedRef,
- jint critical) {
- JNI_TRACE("get_X509_CRL_ext_oids(0x%llx, %d)", x509RevokedRef, critical);
- return get_X509Type_ext_oids<X509_REVOKED, X509_REVOKED_get_ext_by_critical,
- X509_REVOKED_get_ext>(env, x509RevokedRef, critical);
-}
-
-#ifdef WITH_JNI_TRACE
-/**
- * Based on example logging call back from SSL_CTX_set_info_callback man page
- */
-static void info_callback_LOG(const SSL* s __attribute__ ((unused)), int where, int ret)
-{
- int w = where & ~SSL_ST_MASK;
- const char* str;
- if (w & SSL_ST_CONNECT) {
- str = "SSL_connect";
- } else if (w & SSL_ST_ACCEPT) {
- str = "SSL_accept";
- } else {
- str = "undefined";
- }
-
- if (where & SSL_CB_LOOP) {
- JNI_TRACE("ssl=%p %s:%s %s", s, str, SSL_state_string(s), SSL_state_string_long(s));
- } else if (where & SSL_CB_ALERT) {
- str = (where & SSL_CB_READ) ? "read" : "write";
- JNI_TRACE("ssl=%p SSL3 alert %s:%s:%s %s %s",
- s,
- str,
- SSL_alert_type_string(ret),
- SSL_alert_desc_string(ret),
- SSL_alert_type_string_long(ret),
- SSL_alert_desc_string_long(ret));
- } else if (where & SSL_CB_EXIT) {
- if (ret == 0) {
- JNI_TRACE("ssl=%p %s:failed exit in %s %s",
- s, str, SSL_state_string(s), SSL_state_string_long(s));
- } else if (ret < 0) {
- JNI_TRACE("ssl=%p %s:error exit in %s %s",
- s, str, SSL_state_string(s), SSL_state_string_long(s));
- } else if (ret == 1) {
- JNI_TRACE("ssl=%p %s:ok exit in %s %s",
- s, str, SSL_state_string(s), SSL_state_string_long(s));
- } else {
- JNI_TRACE("ssl=%p %s:unknown exit %d in %s %s",
- s, str, ret, SSL_state_string(s), SSL_state_string_long(s));
- }
- } else if (where & SSL_CB_HANDSHAKE_START) {
- JNI_TRACE("ssl=%p handshake start in %s %s",
- s, SSL_state_string(s), SSL_state_string_long(s));
- } else if (where & SSL_CB_HANDSHAKE_DONE) {
- JNI_TRACE("ssl=%p handshake done in %s %s",
- s, SSL_state_string(s), SSL_state_string_long(s));
- } else {
- JNI_TRACE("ssl=%p %s:unknown where %d in %s %s",
- s, str, where, SSL_state_string(s), SSL_state_string_long(s));
- }
-}
-#endif
-
-/**
- * Returns an array containing all the X509 certificate's bytes.
- */
-static jobjectArray getCertificateBytes(JNIEnv* env, const STACK_OF(X509)* chain)
-{
- if (chain == NULL) {
- // Chain can be NULL if the associated cipher doesn't do certs.
- return NULL;
- }
-
- int count = sk_X509_num(chain);
- if (count <= 0) {
- return NULL;
- }
-
- jobjectArray joa = env->NewObjectArray(count, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- for (int i = 0; i < count; i++) {
- X509* cert = sk_X509_value(chain, i);
-
- ScopedLocalRef<jbyteArray> byteArray(env, ASN1ToByteArray<X509, i2d_X509>(env, cert));
- if (byteArray.get() == NULL) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, i, byteArray.get());
- }
-
- return joa;
-}
-
-/**
- * Returns an array containing all the X500 principal's bytes.
- */
-static jobjectArray getPrincipalBytes(JNIEnv* env, const STACK_OF(X509_NAME)* names)
-{
- if (names == NULL) {
- return NULL;
- }
-
- int count = sk_X509_NAME_num(names);
- if (count <= 0) {
- return NULL;
- }
-
- ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, byteArrayClass, NULL));
- if (joa.get() == NULL) {
- return NULL;
- }
-
- for (int i = 0; i < count; i++) {
- X509_NAME* principal = sk_X509_NAME_value(names, i);
-
- ScopedLocalRef<jbyteArray> byteArray(env, ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env,
- principal));
- if (byteArray.get() == NULL) {
- return NULL;
- }
- env->SetObjectArrayElement(joa.get(), i, byteArray.get());
- }
-
- return joa.release();
-}
-
-/**
- * Our additional application data needed for getting synchronization right.
- * This maybe warrants a bit of lengthy prose:
- *
- * (1) We use a flag to reflect whether we consider the SSL connection alive.
- * Any read or write attempt loops will be cancelled once this flag becomes 0.
- *
- * (2) We use an int to count the number of threads that are blocked by the
- * underlying socket. This may be at most two (one reader and one writer), since
- * the Java layer ensures that no more threads will enter the native code at the
- * same time.
- *
- * (3) The pipe is used primarily as a means of cancelling a blocking select()
- * when we want to close the connection (aka "emergency button"). It is also
- * necessary for dealing with a possible race condition situation: There might
- * be cases where both threads see an SSL_ERROR_WANT_READ or
- * SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
- * If one leaves the select() successfully before the other enters it, the
- * "success" event is already consumed and the second thread will be blocked,
- * possibly forever (depending on network conditions).
- *
- * The idea for solving the problem looks like this: Whenever a thread is
- * successful in moving around data on the network, and it knows there is
- * another thread stuck in a select(), it will write a byte to the pipe, waking
- * up the other thread. A thread that returned from select(), on the other hand,
- * knows whether it's been woken up by the pipe. If so, it will consume the
- * byte, and the original state of affairs has been restored.
- *
- * The pipe may seem like a bit of overhead, but it fits in nicely with the
- * other file descriptors of the select(), so there's only one condition to wait
- * for.
- *
- * (4) Finally, a mutex is needed to make sure that at most one thread is in
- * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
- * requirement. We use the same mutex to guard the field for counting the
- * waiting threads.
- *
- * Note: The current implementation assumes that we don't have to deal with
- * problems induced by multiple cores or processors and their respective
- * memory caches. One possible problem is that of inconsistent views on the
- * "aliveAndKicking" field. This could be worked around by also enclosing all
- * accesses to that field inside a lock/unlock sequence of our mutex, but
- * currently this seems a bit like overkill. Marking volatile at the very least.
- *
- * During handshaking, additional fields are used to up-call into
- * Java to perform certificate verification and handshake
- * completion. These are also used in any renegotiation.
- *
- * (5) the JNIEnv so we can invoke the Java callback
- *
- * (6) a NativeCrypto.SSLHandshakeCallbacks instance for callbacks from native to Java
- *
- * (7) a java.io.FileDescriptor wrapper to check for socket close
- *
- * We store the NPN protocols list so we can either send it (from the server) or
- * select a protocol (on the client). We eagerly acquire a pointer to the array
- * data so the callback doesn't need to acquire resources that it cannot
- * release.
- *
- * Because renegotiation can be requested by the peer at any time,
- * care should be taken to maintain an appropriate JNIEnv on any
- * downcall to openssl since it could result in an upcall to Java. The
- * current code does try to cover these cases by conditionally setting
- * the JNIEnv on calls that can read and write to the SSL such as
- * SSL_do_handshake, SSL_read, SSL_write, and SSL_shutdown.
- *
- * Finally, we have two emphemeral keys setup by OpenSSL callbacks:
- *
- * (8) a set of ephemeral RSA keys that is lazily generated if a peer
- * wants to use an exportable RSA cipher suite.
- *
- * (9) a set of ephemeral EC keys that is lazily generated if a peer
- * wants to use an TLS_ECDHE_* cipher suite.
- *
- */
-class AppData {
- public:
- volatile int aliveAndKicking;
- int waitingThreads;
- int fdsEmergency[2];
- MUTEX_TYPE mutex;
- JNIEnv* env;
- jobject sslHandshakeCallbacks;
- jobject fileDescriptor;
- jbyteArray npnProtocolsArray;
- jbyte* npnProtocolsData;
- size_t npnProtocolsLength;
- jbyteArray alpnProtocolsArray;
- jbyte* alpnProtocolsData;
- size_t alpnProtocolsLength;
- Unique_RSA ephemeralRsa;
- Unique_EC_KEY ephemeralEc;
-
- /**
- * Creates the application data context for the SSL*.
- */
- public:
- static AppData* create() {
- UniquePtr<AppData> appData(new AppData());
- if (pipe(appData.get()->fdsEmergency) == -1) {
- ALOGE("AppData::create pipe(2) failed: %s", strerror(errno));
- return NULL;
- }
- if (!setBlocking(appData.get()->fdsEmergency[0], false)) {
- ALOGE("AppData::create fcntl(2) failed: %s", strerror(errno));
- return NULL;
- }
- if (MUTEX_SETUP(appData.get()->mutex) == -1) {
- ALOGE("pthread_mutex_init(3) failed: %s", strerror(errno));
- return NULL;
- }
- return appData.release();
- }
-
- ~AppData() {
- aliveAndKicking = 0;
- if (fdsEmergency[0] != -1) {
- close(fdsEmergency[0]);
- }
- if (fdsEmergency[1] != -1) {
- close(fdsEmergency[1]);
- }
- clearCallbackState();
- MUTEX_CLEANUP(mutex);
- }
-
- private:
- AppData() :
- aliveAndKicking(1),
- waitingThreads(0),
- env(NULL),
- sslHandshakeCallbacks(NULL),
- npnProtocolsArray(NULL),
- npnProtocolsData(NULL),
- npnProtocolsLength(-1),
- alpnProtocolsArray(NULL),
- alpnProtocolsData(NULL),
- alpnProtocolsLength(-1),
- ephemeralRsa(NULL),
- ephemeralEc(NULL) {
- fdsEmergency[0] = -1;
- fdsEmergency[1] = -1;
- }
-
- public:
- /**
- * Used to set the SSL-to-Java callback state before each SSL_*
- * call that may result in a callback. It should be cleared after
- * the operation returns with clearCallbackState.
- *
- * @param env The JNIEnv
- * @param shc The SSLHandshakeCallbacks
- * @param fd The FileDescriptor
- * @param npnProtocols NPN protocols so that they may be advertised (by the
- * server) or selected (by the client). Has no effect
- * unless NPN is enabled.
- * @param alpnProtocols ALPN protocols so that they may be advertised (by the
- * server) or selected (by the client). Passing non-NULL
- * enables ALPN.
- */
- bool setCallbackState(JNIEnv* e, jobject shc, jobject fd, jbyteArray npnProtocols,
- jbyteArray alpnProtocols) {
- NetFd netFd(e, fd);
- if (netFd.isClosed()) {
- return false;
- }
- env = e;
- sslHandshakeCallbacks = shc;
- fileDescriptor = fd;
- if (npnProtocols != NULL) {
- npnProtocolsData = e->GetByteArrayElements(npnProtocols, NULL);
- if (npnProtocolsData == NULL) {
- clearCallbackState();
- return false;
- }
- npnProtocolsArray = npnProtocols;
- npnProtocolsLength = e->GetArrayLength(npnProtocols);
- }
- if (alpnProtocols != NULL) {
- alpnProtocolsData = e->GetByteArrayElements(alpnProtocols, NULL);
- if (alpnProtocolsData == NULL) {
- clearCallbackState();
- return false;
- }
- alpnProtocolsArray = alpnProtocols;
- alpnProtocolsLength = e->GetArrayLength(alpnProtocols);
- }
- return true;
- }
-
- void clearCallbackState() {
- sslHandshakeCallbacks = NULL;
- fileDescriptor = NULL;
- if (npnProtocolsArray != NULL) {
- env->ReleaseByteArrayElements(npnProtocolsArray, npnProtocolsData, JNI_ABORT);
- npnProtocolsArray = NULL;
- npnProtocolsData = NULL;
- npnProtocolsLength = -1;
- }
- if (alpnProtocolsArray != NULL) {
- env->ReleaseByteArrayElements(alpnProtocolsArray, alpnProtocolsData, JNI_ABORT);
- alpnProtocolsArray = NULL;
- alpnProtocolsData = NULL;
- alpnProtocolsLength = -1;
- }
- env = NULL;
- }
-
-};
-
-/**
- * Dark magic helper function that checks, for a given SSL session, whether it
- * can SSL_read() or SSL_write() without blocking. Takes into account any
- * concurrent attempts to close the SSLSocket from the Java side. This is
- * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket
- * while thread #2 is sitting in a blocking read or write. The type argument
- * specifies whether we are waiting for readability or writability. It expects
- * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
- * only need to wait in case one of these problems occurs.
- *
- * @param env
- * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
- * @param fdObject The FileDescriptor, since appData->fileDescriptor should be NULL
- * @param appData The application data structure with mutex info etc.
- * @param timeout_millis The timeout value for select call, with the special value
- * 0 meaning no timeout at all (wait indefinitely). Note: This is
- * the Java semantics of the timeout value, not the usual
- * select() semantics.
- * @return The result of the inner select() call,
- * THROW_SOCKETEXCEPTION if a SocketException was thrown, -1 on
- * additional errors
- */
-static int sslSelect(JNIEnv* env, int type, jobject fdObject, AppData* appData, int timeout_millis) {
- // This loop is an expanded version of the NET_FAILURE_RETRY
- // macro. It cannot simply be used in this case because select
- // cannot be restarted without recreating the fd_sets and timeout
- // structure.
- int result;
- fd_set rfds;
- fd_set wfds;
- do {
- NetFd fd(env, fdObject);
- if (fd.isClosed()) {
- result = THROWN_EXCEPTION;
- break;
- }
- int intFd = fd.get();
- JNI_TRACE("sslSelect type=%s fd=%d appData=%p timeout_millis=%d",
- (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE", intFd, appData, timeout_millis);
-
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
-
- if (type == SSL_ERROR_WANT_READ) {
- FD_SET(intFd, &rfds);
- } else {
- FD_SET(intFd, &wfds);
- }
-
- FD_SET(appData->fdsEmergency[0], &rfds);
-
- int maxFd = (intFd > appData->fdsEmergency[0]) ? intFd : appData->fdsEmergency[0];
-
- // Build a struct for the timeout data if we actually want a timeout.
- timeval tv;
- timeval* ptv;
- if (timeout_millis > 0) {
- tv.tv_sec = timeout_millis / 1000;
- tv.tv_usec = (timeout_millis % 1000) * 1000;
- ptv = &tv;
- } else {
- ptv = NULL;
- }
-
- AsynchronousSocketCloseMonitor monitor(intFd);
- result = select(maxFd + 1, &rfds, &wfds, NULL, ptv);
- JNI_TRACE("sslSelect %s fd=%d appData=%p timeout_millis=%d => %d",
- (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE",
- fd.get(), appData, timeout_millis, result);
- if (result == -1) {
- if (fd.isClosed()) {
- result = THROWN_EXCEPTION;
- break;
- }
- if (errno != EINTR) {
- break;
- }
- }
- } while (result == -1);
-
- if (MUTEX_LOCK(appData->mutex) == -1) {
- return -1;
- }
-
- if (result > 0) {
- // We have been woken up by a token in the emergency pipe. We
- // can't be sure the token is still in the pipe at this point
- // because it could have already been read by the thread that
- // originally wrote it if it entered sslSelect and acquired
- // the mutex before we did. Thus we cannot safely read from
- // the pipe in a blocking way (so we make the pipe
- // non-blocking at creation).
- if (FD_ISSET(appData->fdsEmergency[0], &rfds)) {
- char token;
- do {
- read(appData->fdsEmergency[0], &token, 1);
- } while (errno == EINTR);
- }
- }
-
- // Tell the world that there is now one thread less waiting for the
- // underlying network.
- appData->waitingThreads--;
-
- MUTEX_UNLOCK(appData->mutex);
-
- return result;
-}
-
-/**
- * Helper function that wakes up a thread blocked in select(), in case there is
- * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
- * before closing the connection.
- *
- * @param data The application data structure with mutex info etc.
- */
-static void sslNotify(AppData* appData) {
- // Write a byte to the emergency pipe, so a concurrent select() can return.
- // Note we have to restore the errno of the original system call, since the
- // caller relies on it for generating error messages.
- int errnoBackup = errno;
- char token = '*';
- do {
- errno = 0;
- write(appData->fdsEmergency[1], &token, 1);
- } while (errno == EINTR);
- errno = errnoBackup;
-}
-
-static AppData* toAppData(const SSL* ssl) {
- return reinterpret_cast<AppData*>(SSL_get_app_data(ssl));
-}
-
-/**
- * Verify the X509 certificate via SSL_CTX_set_cert_verify_callback
- */
-static int cert_verify_callback(X509_STORE_CTX* x509_store_ctx, void* arg __attribute__ ((unused)))
-{
- /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
- SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(x509_store_ctx,
- SSL_get_ex_data_X509_STORE_CTX_idx()));
- JNI_TRACE("ssl=%p cert_verify_callback x509_store_ctx=%p arg=%p", ssl, x509_store_ctx, arg);
-
- AppData* appData = toAppData(ssl);
- JNIEnv* env = appData->env;
- if (env == NULL) {
- ALOGE("AppData->env missing in cert_verify_callback");
- JNI_TRACE("ssl=%p cert_verify_callback => 0", ssl);
- return 0;
- }
- jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
-
- jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
- jmethodID methodID
- = env->GetMethodID(cls, "verifyCertificateChain", "([[BLjava/lang/String;)V");
-
- jobjectArray objectArray = getCertificateBytes(env, x509_store_ctx->untrusted);
-
- const char* authMethod = SSL_authentication_method(ssl);
- JNI_TRACE("ssl=%p cert_verify_callback calling verifyCertificateChain authMethod=%s",
- ssl, authMethod);
- jstring authMethodString = env->NewStringUTF(authMethod);
- env->CallVoidMethod(sslHandshakeCallbacks, methodID, objectArray, authMethodString);
-
- int result = (env->ExceptionCheck()) ? 0 : 1;
- JNI_TRACE("ssl=%p cert_verify_callback => %d", ssl, result);
- return result;
-}
-
-/**
- * Call back to watch for handshake to be completed. This is necessary
- * for SSL_MODE_HANDSHAKE_CUTTHROUGH support, since SSL_do_handshake
- * returns before the handshake is completed in this case.
- */
-static void info_callback(const SSL* ssl, int where, int ret __attribute__ ((unused))) {
- JNI_TRACE("ssl=%p info_callback where=0x%x ret=%d", ssl, where, ret);
-#ifdef WITH_JNI_TRACE
- info_callback_LOG(ssl, where, ret);
-#endif
- if (!(where & SSL_CB_HANDSHAKE_DONE)) {
- JNI_TRACE("ssl=%p info_callback ignored", ssl);
- return;
- }
-
- AppData* appData = toAppData(ssl);
- JNIEnv* env = appData->env;
- if (env == NULL) {
- ALOGE("AppData->env missing in info_callback");
- JNI_TRACE("ssl=%p info_callback env error", ssl);
- return;
- }
- if (env->ExceptionCheck()) {
- JNI_TRACE("ssl=%p info_callback already pending exception", ssl);
- return;
- }
-
- jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
-
- jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
- jmethodID methodID = env->GetMethodID(cls, "handshakeCompleted", "()V");
-
- JNI_TRACE("ssl=%p info_callback calling handshakeCompleted", ssl);
- env->CallVoidMethod(sslHandshakeCallbacks, methodID);
-
- if (env->ExceptionCheck()) {
- JNI_TRACE("ssl=%p info_callback exception", ssl);
- }
- JNI_TRACE("ssl=%p info_callback completed", ssl);
-}
-
-/**
- * Call back to ask for a client certificate. There are three possible exit codes:
- *
- * 1 is success. x509Out and pkeyOut should point to the correct private key and certificate.
- * 0 is unable to find key. x509Out and pkeyOut should be NULL.
- * -1 is error and it doesn't matter what x509Out and pkeyOut are.
- */
-static int client_cert_cb(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) {
- JNI_TRACE("ssl=%p client_cert_cb x509Out=%p pkeyOut=%p", ssl, x509Out, pkeyOut);
-
- /* Clear output of key and certificate in case of early exit due to error. */
- *x509Out = NULL;
- *pkeyOut = NULL;
-
- AppData* appData = toAppData(ssl);
- JNIEnv* env = appData->env;
- if (env == NULL) {
- ALOGE("AppData->env missing in client_cert_cb");
- JNI_TRACE("ssl=%p client_cert_cb env error => 0", ssl);
- return 0;
- }
- if (env->ExceptionCheck()) {
- JNI_TRACE("ssl=%p client_cert_cb already pending exception => 0", ssl);
- return -1;
- }
- jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
-
- jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
- jmethodID methodID
- = env->GetMethodID(cls, "clientCertificateRequested", "([B[[B)V");
-
- // Call Java callback which can use SSL_use_certificate and SSL_use_PrivateKey to set values
- char ssl2_ctype = SSL3_CT_RSA_SIGN;
- const char* ctype = NULL;
- int ctype_num = 0;
- jobjectArray issuers = NULL;
- switch (ssl->version) {
- case SSL2_VERSION:
- ctype = &ssl2_ctype;
- ctype_num = 1;
- break;
- case SSL3_VERSION:
- case TLS1_VERSION:
- case TLS1_1_VERSION:
- case TLS1_2_VERSION:
- case DTLS1_VERSION:
- ctype = ssl->s3->tmp.ctype;
- ctype_num = ssl->s3->tmp.ctype_num;
- issuers = getPrincipalBytes(env, ssl->s3->tmp.ca_names);
- break;
- }
-#ifdef WITH_JNI_TRACE
- for (int i = 0; i < ctype_num; i++) {
- JNI_TRACE("ssl=%p clientCertificateRequested keyTypes[%d]=%d", ssl, i, ctype[i]);
- }
-#endif
-
- jbyteArray keyTypes = env->NewByteArray(ctype_num);
- if (keyTypes == NULL) {
- JNI_TRACE("ssl=%p client_cert_cb bytes == null => 0", ssl);
- return 0;
- }
- env->SetByteArrayRegion(keyTypes, 0, ctype_num, reinterpret_cast<const jbyte*>(ctype));
-
- JNI_TRACE("ssl=%p clientCertificateRequested calling clientCertificateRequested "
- "keyTypes=%p issuers=%p", ssl, keyTypes, issuers);
- env->CallVoidMethod(sslHandshakeCallbacks, methodID, keyTypes, issuers);
-
- if (env->ExceptionCheck()) {
- JNI_TRACE("ssl=%p client_cert_cb exception => 0", ssl);
- return -1;
- }
-
- // Check for values set from Java
- X509* certificate = SSL_get_certificate(ssl);
- EVP_PKEY* privatekey = SSL_get_privatekey(ssl);
- int result = 0;
- if (certificate != NULL && privatekey != NULL) {
- *x509Out = certificate;
- *pkeyOut = privatekey;
- result = 1;
- } else {
- // Some error conditions return NULL, so make sure it doesn't linger.
- freeOpenSslErrorState();
- }
- JNI_TRACE("ssl=%p client_cert_cb => *x509=%p *pkey=%p %d", ssl, *x509Out, *pkeyOut, result);
- return result;
-}
-
-static RSA* rsaGenerateKey(int keylength) {
- Unique_BIGNUM bn(BN_new());
- if (bn.get() == NULL) {
- return NULL;
- }
- int setWordResult = BN_set_word(bn.get(), RSA_F4);
- if (setWordResult != 1) {
- return NULL;
- }
- Unique_RSA rsa(RSA_new());
- if (rsa.get() == NULL) {
- return NULL;
- }
- int generateResult = RSA_generate_key_ex(rsa.get(), keylength, bn.get(), NULL);
- if (generateResult != 1) {
- return NULL;
- }
- return rsa.release();
-}
-
-/**
- * Call back to ask for an ephemeral RSA key for SSL_RSA_EXPORT_WITH_RC4_40_MD5 (aka EXP-RC4-MD5)
- */
-static RSA* tmp_rsa_callback(SSL* ssl __attribute__ ((unused)),
- int is_export __attribute__ ((unused)),
- int keylength) {
- JNI_TRACE("ssl=%p tmp_rsa_callback is_export=%d keylength=%d", ssl, is_export, keylength);
-
- AppData* appData = toAppData(ssl);
- if (appData->ephemeralRsa.get() == NULL) {
- JNI_TRACE("ssl=%p tmp_rsa_callback generating ephemeral RSA key", ssl);
- appData->ephemeralRsa.reset(rsaGenerateKey(keylength));
- }
- JNI_TRACE("ssl=%p tmp_rsa_callback => %p", ssl, appData->ephemeralRsa.get());
- return appData->ephemeralRsa.get();
-}
-
-static DH* dhGenerateParameters(int keylength) {
-
- /*
- * The SSL_CTX_set_tmp_dh_callback(3SSL) man page discusses two
- * different options for generating DH keys. One is generating the
- * keys using a single set of DH parameters. However, generating
- * DH parameters is slow enough (minutes) that they suggest doing
- * it once at install time. The other is to generate DH keys from
- * DSA parameters. Generating DSA parameters is faster than DH
- * parameters, but to prevent small subgroup attacks, they needed
- * to be regenerated for each set of DH keys. Setting the
- * SSL_OP_SINGLE_DH_USE option make sure OpenSSL will call back
- * for new DH parameters every type it needs to generate DH keys.
- */
-#if 0
- // Slow path that takes minutes but could be cached
- Unique_DH dh(DH_new());
- if (!DH_generate_parameters_ex(dh.get(), keylength, 2, NULL)) {
- return NULL;
- }
- return dh.release();
-#else
- // Faster path but must have SSL_OP_SINGLE_DH_USE set
- Unique_DSA dsa(DSA_new());
- if (!DSA_generate_parameters_ex(dsa.get(), keylength, NULL, 0, NULL, NULL, NULL)) {
- return NULL;
- }
- DH* dh = DSA_dup_DH(dsa.get());
- return dh;
-#endif
-}
-
-/**
- * Call back to ask for Diffie-Hellman parameters
- */
-static DH* tmp_dh_callback(SSL* ssl __attribute__ ((unused)),
- int is_export __attribute__ ((unused)),
- int keylength) {
- JNI_TRACE("ssl=%p tmp_dh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
- DH* tmp_dh = dhGenerateParameters(keylength);
- JNI_TRACE("ssl=%p tmp_dh_callback => %p", ssl, tmp_dh);
- return tmp_dh;
-}
-
-static EC_KEY* ecGenerateKey(int keylength __attribute__ ((unused))) {
- // TODO selected curve based on keylength
- Unique_EC_KEY ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
- if (ec.get() == NULL) {
- return NULL;
- }
- return ec.release();
-}
-
-/**
- * Call back to ask for an ephemeral EC key for TLS_ECDHE_* cipher suites
- */
-static EC_KEY* tmp_ecdh_callback(SSL* ssl __attribute__ ((unused)),
- int is_export __attribute__ ((unused)),
- int keylength) {
- JNI_TRACE("ssl=%p tmp_ecdh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
- AppData* appData = toAppData(ssl);
- if (appData->ephemeralEc.get() == NULL) {
- JNI_TRACE("ssl=%p tmp_ecdh_callback generating ephemeral EC key", ssl);
- appData->ephemeralEc.reset(ecGenerateKey(keylength));
- }
- JNI_TRACE("ssl=%p tmp_ecdh_callback => %p", ssl, appData->ephemeralEc.get());
- return appData->ephemeralEc.get();
-}
-
-/*
- * public static native int SSL_CTX_new();
- */
-static jlong NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) {
- Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method()));
- if (sslCtx.get() == NULL) {
- throwExceptionIfNecessary(env, "SSL_CTX_new");
- return 0;
- }
- SSL_CTX_set_options(sslCtx.get(),
- SSL_OP_ALL
- // Note: We explicitly do not allow SSLv2 to be used.
- | SSL_OP_NO_SSLv2
- // We also disable session tickets for better compatibility b/2682876
- | SSL_OP_NO_TICKET
- // We also disable compression for better compatibility b/2710492 b/2710497
- | SSL_OP_NO_COMPRESSION
- // Because dhGenerateParameters uses DSA_generate_parameters_ex
- | SSL_OP_SINGLE_DH_USE
- // Because ecGenerateParameters uses a fixed named curve
- | SSL_OP_SINGLE_ECDH_USE);
-
- int mode = SSL_CTX_get_mode(sslCtx.get());
- /*
- * Turn on "partial write" mode. This means that SSL_write() will
- * behave like Posix write() and possibly return after only
- * writing a partial buffer. Note: The alternative, perhaps
- * surprisingly, is not that SSL_write() always does full writes
- * but that it will force you to retry write calls having
- * preserved the full state of the original call. (This is icky
- * and undesirable.)
- */
- mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
-
- // Reuse empty buffers within the SSL_CTX to save memory
- mode |= SSL_MODE_RELEASE_BUFFERS;
-
- SSL_CTX_set_mode(sslCtx.get(), mode);
-
- SSL_CTX_set_cert_verify_callback(sslCtx.get(), cert_verify_callback, NULL);
- SSL_CTX_set_info_callback(sslCtx.get(), info_callback);
- SSL_CTX_set_client_cert_cb(sslCtx.get(), client_cert_cb);
- SSL_CTX_set_tmp_rsa_callback(sslCtx.get(), tmp_rsa_callback);
- SSL_CTX_set_tmp_dh_callback(sslCtx.get(), tmp_dh_callback);
- SSL_CTX_set_tmp_ecdh_callback(sslCtx.get(), tmp_ecdh_callback);
-
- JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get());
- return (jlong) sslCtx.release();
-}
-
-/**
- * public static native void SSL_CTX_free(int ssl_ctx)
- */
-static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
- jclass, jlong ssl_ctx_address)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx);
- if (ssl_ctx == NULL) {
- return;
- }
- SSL_CTX_free(ssl_ctx);
-}
-
-static void NativeCrypto_SSL_CTX_set_session_id_context(JNIEnv* env, jclass,
- jlong ssl_ctx_address, jbyteArray sid_ctx)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context sid_ctx=%p", ssl_ctx, sid_ctx);
- if (ssl_ctx == NULL) {
- return;
- }
-
- ScopedByteArrayRO buf(env, sid_ctx);
- if (buf.get() == NULL) {
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => threw exception", ssl_ctx);
- return;
- }
-
- unsigned int length = buf.size();
- if (length > SSL_MAX_SSL_SESSION_ID_LENGTH) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "length > SSL_MAX_SSL_SESSION_ID_LENGTH");
- JNI_TRACE("NativeCrypto_SSL_CTX_set_session_id_context => length = %d", length);
- return;
- }
- const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buf.get());
- int result = SSL_CTX_set_session_id_context(ssl_ctx, bytes, length);
- if (result == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_SSL_CTX_set_session_id_context");
- return;
- }
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => ok", ssl_ctx);
-}
-
-/**
- * public static native int SSL_new(int ssl_ctx) throws SSLException;
- */
-static jlong NativeCrypto_SSL_new(JNIEnv* env, jclass, jlong ssl_ctx_address)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx);
- if (ssl_ctx == NULL) {
- return 0;
- }
- Unique_SSL ssl(SSL_new(ssl_ctx));
- if (ssl.get() == NULL) {
- throwSSLExceptionWithSslErrors(env, NULL, SSL_ERROR_NONE,
- "Unable to create SSL structure");
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx);
- return 0;
- }
-
- /* Java code in class OpenSSLSocketImpl does the verification. Meaning of
- * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
- * (by default disabled), the server will send a certificate which will
- * be checked. The result of the certificate verification process can be
- * checked after the TLS/SSL handshake using the SSL_get_verify_result(3)
- * function. The handshake will be continued regardless of the
- * verification result.
- */
- SSL_set_verify(ssl.get(), SSL_VERIFY_NONE, NULL);
-
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl.get());
- return (jlong) ssl.release();
-}
-
-
-static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_enable_tls_channel_id", ssl);
- if (ssl == NULL) {
- return;
- }
-
- long ret = SSL_enable_tls_channel_id(ssl);
- if (ret != 1L) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error enabling Channel ID");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_tls_channel_id => error", ssl);
- return;
- }
-}
-
-static jbyteArray NativeCrypto_SSL_get_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id", ssl);
- if (ssl == NULL) {
- return NULL;
- }
-
- // Channel ID is 64 bytes long. Unfortunately, OpenSSL doesn't declare this length
- // as a constant anywhere.
- jbyteArray javaBytes = env->NewByteArray(64);
- ScopedByteArrayRW bytes(env, javaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => NULL", ssl);
- return NULL;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
- // Unfortunately, the SSL_get_tls_channel_id method below always returns 64 (upon success)
- // regardless of the number of bytes copied into the output buffer "tmp". Thus, the correctness
- // of this code currently relies on the "tmp" buffer being exactly 64 bytes long.
- long ret = SSL_get_tls_channel_id(ssl, tmp, 64);
- if (ret == 0) {
- // Channel ID either not set or did not verify
- JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => not available", ssl);
- return NULL;
- } else if (ret != 64) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error getting Channel ID");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_tls_channel_id => error, returned %ld", ssl, ret);
- return NULL;
- }
-
- JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id() => %p", ssl, javaBytes);
- return javaBytes;
-}
-
-static void NativeCrypto_SSL_set1_tls_channel_id(JNIEnv* env, jclass,
- jlong ssl_address, jlong pkeyRef)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("ssl=%p SSL_set1_tls_channel_id privatekey=%p", ssl, pkey);
- if (ssl == NULL) {
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => pkey == null", ssl);
- return;
- }
-
- // SSL_set1_tls_channel_id requires ssl->server to be set to 0.
- // Unfortunately, the default value is 1 and it's only changed to 0 just
- // before the handshake starts (see NativeCrypto_SSL_do_handshake).
- ssl->server = 0;
- long ret = SSL_set1_tls_channel_id(ssl, pkey);
-
- if (ret != 1L) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(
- env, ssl, SSL_ERROR_NONE, "Error setting private key for Channel ID");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => error", ssl);
- return;
- }
- // SSL_set1_tls_channel_id expects to take ownership of the EVP_PKEY, but
- // we have an external reference from the caller such as an OpenSSLKey,
- // so we manually increment the reference count here.
- CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY);
-
- JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => ok", ssl);
-}
-
-static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass, jlong ssl_address, jlong pkeyRef) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("ssl=%p SSL_use_PrivateKey privatekey=%p", ssl, pkey);
- if (ssl == NULL) {
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("ssl=%p SSL_use_PrivateKey => pkey == null", ssl);
- return;
- }
-
- int ret = SSL_use_PrivateKey(ssl, pkey);
- if (ret != 1) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p SSL_use_PrivateKey => error", ssl);
- return;
- }
- // SSL_use_PrivateKey expects to take ownership of the EVP_PKEY,
- // but we have an external reference from the caller such as an
- // OpenSSLKey, so we manually increment the reference count here.
- CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY);
-
- JNI_TRACE("ssl=%p SSL_use_PrivateKey => ok", ssl);
-}
-
-static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
- jlong ssl_address, jobjectArray certificates)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificates);
- if (ssl == NULL) {
- return;
- }
-
- if (certificates == NULL) {
- jniThrowNullPointerException(env, "certificates == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
- return;
- }
-
- int length = env->GetArrayLength(certificates);
- if (length == 0) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl);
- return;
- }
-
- X509Chain certificatesX509(length);
- for (int i = 0; i < length; i++) {
- ScopedLocalRef<jbyteArray> certificate(env,
- reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(certificates, i)));
- if (certificate.get() == NULL) {
- jniThrowNullPointerException(env, "certificates element == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates element null", ssl);
- return;
- }
-
- ScopedByteArrayRO buf(env, certificate.get());
- if (buf.get() == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => threw exception", ssl);
- return;
- }
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
- certificatesX509[i] = d2i_X509(NULL, &tmp, buf.size());
-
- if (certificatesX509[i] == NULL) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
- return;
- }
- }
-
- int ret = SSL_use_certificate(ssl, certificatesX509[0]);
- if (ret == 1) {
- certificatesX509.release(0);
- } else {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
- return;
- }
-
- Unique_sk_X509 chain(sk_X509_new_null());
- if (chain.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
- return;
- }
- for (int i = 1; i < length; i++) {
- if (!sk_X509_push(chain.get(), certificatesX509.release(i))) {
- jniThrowOutOfMemory(env, "Unable to push certificate");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificate push error", ssl);
- return;
- }
- }
- int chainResult = SSL_use_certificate_chain(ssl, chain.get());
- if (chainResult == 0) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error",
- ssl);
- return;
- } else {
- OWNERSHIP_TRANSFERRED(chain);
- }
-
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
-}
-
-static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
- if (ssl == NULL) {
- return;
- }
- int ret = SSL_check_private_key(ssl);
- if (ret != 1) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
- return;
- }
- JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl);
-}
-
-static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
- jlong ssl_address, jobjectArray principals)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
- if (ssl == NULL) {
- return;
- }
-
- if (principals == NULL) {
- jniThrowNullPointerException(env, "principals == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl);
- return;
- }
-
- int length = env->GetArrayLength(principals);
- if (length == 0) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl);
- return;
- }
-
- Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null());
- if (principalsStack.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate principal stack");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl);
- return;
- }
- for (int i = 0; i < length; i++) {
- ScopedLocalRef<jbyteArray> principal(env,
- reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i)));
- if (principal.get() == NULL) {
- jniThrowNullPointerException(env, "principals element == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl);
- return;
- }
-
- ScopedByteArrayRO buf(env, principal.get());
- if (buf.get() == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl);
- return;
- }
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
- Unique_X509_NAME principalX509Name(d2i_X509_NAME(NULL, &tmp, buf.size()));
-
- if (principalX509Name.get() == NULL) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
- ssl);
- return;
- }
-
- if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) {
- jniThrowOutOfMemory(env, "Unable to push principal");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl);
- return;
- }
- }
-
- SSL_set_client_CA_list(ssl, principalsStack.release());
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl);
-}
-
-/**
- * public static native long SSL_get_mode(int ssl);
- */
-static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jlong ssl_address) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
- if (ssl == NULL) {
- return 0;
- }
- long mode = SSL_get_mode(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode);
- return mode;
-}
-
-/**
- * public static native long SSL_set_mode(int ssl, long mode);
- */
-static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
- jlong ssl_address, jlong mode) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode);
- if (ssl == NULL) {
- return 0;
- }
- long result = SSL_set_mode(ssl, mode);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result);
- return result;
-}
-
-/**
- * public static native long SSL_clear_mode(int ssl, long mode);
- */
-static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
- jlong ssl_address, jlong mode) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode);
- if (ssl == NULL) {
- return 0;
- }
- long result = SSL_clear_mode(ssl, mode);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result);
- return result;
-}
-
-/**
- * public static native long SSL_get_options(int ssl);
- */
-static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
- jlong ssl_address) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
- if (ssl == NULL) {
- return 0;
- }
- long options = SSL_get_options(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options);
- return options;
-}
-
-/**
- * public static native long SSL_set_options(int ssl, long options);
- */
-static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
- jlong ssl_address, jlong options) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options);
- if (ssl == NULL) {
- return 0;
- }
- long result = SSL_set_options(ssl, options);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result);
- return result;
-}
-
-/**
- * public static native long SSL_clear_options(int ssl, long options);
- */
-static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
- jlong ssl_address, jlong options) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options);
- if (ssl == NULL) {
- return 0;
- }
- long result = SSL_clear_options(ssl, options);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result);
- return result;
-}
-
-/**
- * Sets the ciphers suites that are enabled in the SSL
- */
-static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass,
- jlong ssl_address, jobjectArray cipherSuites)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
- if (ssl == NULL) {
- return;
- }
- if (cipherSuites == NULL) {
- jniThrowNullPointerException(env, "cipherSuites == null");
- return;
- }
-
- Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null());
- if (cipherstack.get() == NULL) {
- jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed");
- return;
- }
-
- const SSL_METHOD* ssl_method = ssl->method;
- int num_ciphers = ssl_method->num_ciphers();
-
- int length = env->GetArrayLength(cipherSuites);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists length=%d", ssl, length);
- for (int i = 0; i < length; i++) {
- ScopedLocalRef<jstring> cipherSuite(env,
- reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
- ScopedUtfChars c(env, cipherSuite.get());
- if (c.c_str() == NULL) {
- return;
- }
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuite=%s", ssl, c.c_str());
- bool found = false;
- for (int j = 0; j < num_ciphers; j++) {
- const SSL_CIPHER* cipher = ssl_method->get_cipher(j);
- if ((strcmp(c.c_str(), cipher->name) == 0)
- && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) {
- if (!sk_SSL_CIPHER_push(cipherstack.get(), cipher)) {
- jniThrowOutOfMemory(env, "Unable to push cipher");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists => cipher push error", ssl);
- return;
- }
- found = true;
- }
- }
- if (!found) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "Could not find cipher suite.");
- return;
- }
- }
-
- int rc = SSL_set_cipher_lists(ssl, cipherstack.get());
- if (rc == 0) {
- freeOpenSslErrorState();
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "Illegal cipher suite strings.");
- } else {
- OWNERSHIP_TRANSFERRED(cipherstack);
- }
-}
-
-/**
- * Sets certificate expectations, especially for server to request client auth
- */
-static void NativeCrypto_SSL_set_verify(JNIEnv* env,
- jclass, jlong ssl_address, jint mode)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
- if (ssl == NULL) {
- return;
- }
- SSL_set_verify(ssl, (int)mode, NULL);
-}
-
-/**
- * Sets the ciphers suites that are enabled in the SSL
- */
-static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
- jlong ssl_address, jlong ssl_session_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session);
- if (ssl == NULL) {
- return;
- }
-
- int ret = SSL_set_session(ssl, ssl_session);
- if (ret != 1) {
- /*
- * Translate the error, and throw if it turns out to be a real
- * problem.
- */
- int sslErrorCode = SSL_get_error(ssl, ret);
- if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
- throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
- SSL_clear(ssl);
- }
- }
-}
-
-/**
- * Sets the ciphers suites that are enabled in the SSL
- */
-static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
- jlong ssl_address, jboolean creation_enabled)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
- ssl, creation_enabled);
- if (ssl == NULL) {
- return;
- }
- SSL_set_session_creation_enabled(ssl, creation_enabled);
-}
-
-static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
- jlong ssl_address, jstring hostname)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
- ssl, hostname);
- if (ssl == NULL) {
- return;
- }
-
- ScopedUtfChars hostnameChars(env, hostname);
- if (hostnameChars.c_str() == NULL) {
- return;
- }
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s",
- ssl, hostnameChars.c_str());
-
- int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
- if (ret != 1) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
- return;
- }
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
-}
-
-static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jlong ssl_address) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername);
- return env->NewStringUTF(servername);
-}
-
-/**
- * A common selection path for both NPN and ALPN since they're essentially the
- * same protocol. The list of protocols in "primary" is considered the order
- * which should take precedence.
- */
-static int proto_select(SSL* ssl __attribute__ ((unused)),
- unsigned char **out, unsigned char *outLength,
- const unsigned char *primary, const unsigned int primaryLength,
- const unsigned char *secondary, const unsigned int secondaryLength) {
- if (primary != NULL) {
- JNI_TRACE("primary=%p, length=%d", primary, primaryLength);
-
- int status = SSL_select_next_proto(out, outLength, primary, primaryLength, secondary,
- secondaryLength);
- switch (status) {
- case OPENSSL_NPN_NEGOTIATED:
- JNI_TRACE("ssl=%p proto_select NPN/ALPN negotiated", ssl);
- return SSL_TLSEXT_ERR_OK;
- break;
- case OPENSSL_NPN_UNSUPPORTED:
- JNI_TRACE("ssl=%p proto_select NPN/ALPN unsupported", ssl);
- break;
- case OPENSSL_NPN_NO_OVERLAP:
- JNI_TRACE("ssl=%p proto_select NPN/ALPN no overlap", ssl);
- break;
- }
- } else {
- if (out != NULL && outLength != NULL) {
- *out = NULL;
- *outLength = 0;
- }
- JNI_TRACE("protocols=NULL");
- }
- return SSL_TLSEXT_ERR_NOACK;
-}
-
-/**
- * Callback for the server to select an ALPN protocol.
- */
-static int alpn_select_callback(SSL* ssl, const unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen, void *) {
- JNI_TRACE("ssl=%p alpn_select_callback", ssl);
-
- AppData* appData = toAppData(ssl);
- JNI_TRACE("AppData=%p", appData);
-
- return proto_select(ssl, const_cast<unsigned char **>(out), outlen,
- reinterpret_cast<unsigned char*>(appData->alpnProtocolsData),
- appData->alpnProtocolsLength, in, inlen);
-}
-
-/**
- * Callback for the client to select an NPN protocol.
- */
-static int next_proto_select_callback(SSL* ssl, unsigned char** out, unsigned char* outlen,
- const unsigned char* in, unsigned int inlen, void*)
-{
- JNI_TRACE("ssl=%p next_proto_select_callback", ssl);
-
- AppData* appData = toAppData(ssl);
- JNI_TRACE("AppData=%p", appData);
-
- // Enable False Start on the client if the server understands NPN
- // http://www.imperialviolet.org/2012/04/11/falsestart.html
- SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
-
- return proto_select(ssl, out, outlen, in, inlen,
- reinterpret_cast<unsigned char*>(appData->npnProtocolsData),
- appData->npnProtocolsLength);
-}
-
-/**
- * Callback for the server to advertise available protocols.
- */
-static int next_protos_advertised_callback(SSL* ssl,
- const unsigned char **out, unsigned int *outlen, void *)
-{
- JNI_TRACE("ssl=%p next_protos_advertised_callback", ssl);
- AppData* appData = toAppData(ssl);
- unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData);
- if (npnProtocols != NULL) {
- *out = npnProtocols;
- *outlen = appData->npnProtocolsLength;
- return SSL_TLSEXT_ERR_OK;
- } else {
- *out = NULL;
- *outlen = 0;
- return SSL_TLSEXT_ERR_NOACK;
- }
-}
-
-static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- if (ssl_ctx == NULL) {
- return;
- }
- SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, NULL); // client
- SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_protos_advertised_callback, NULL); // server
-}
-
-static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- if (ssl_ctx == NULL) {
- return;
- }
- SSL_CTX_set_next_proto_select_cb(ssl_ctx, NULL, NULL); // client
- SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, NULL, NULL); // server
-}
-
-static jbyteArray NativeCrypto_SSL_get_npn_negotiated_protocol(JNIEnv* env, jclass,
- jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_npn_negotiated_protocol", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- const jbyte* npn;
- unsigned npnLength;
- SSL_get0_next_proto_negotiated(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
- if (npnLength == 0) {
- return NULL;
- }
- jbyteArray result = env->NewByteArray(npnLength);
- if (result != NULL) {
- env->SetByteArrayRegion(result, 0, npnLength, npn);
- }
- return result;
-}
-
-static int NativeCrypto_SSL_CTX_set_alpn_protos(JNIEnv* env, jclass, jlong ssl_ctx_address,
- jbyteArray protos) {
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- if (ssl_ctx == NULL) {
- return 0;
- }
-
- JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p", ssl_ctx, protos);
-
- if (protos == NULL) {
- JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=NULL", ssl_ctx);
- return 1;
- }
-
- ScopedByteArrayRO protosBytes(env, protos);
- if (protosBytes.get() == NULL) {
- JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p => protosBytes == NULL", ssl_ctx,
- protos);
- return 0;
- }
-
- const unsigned char *tmp = reinterpret_cast<const unsigned char*>(protosBytes.get());
- int ret = SSL_CTX_set_alpn_protos(ssl_ctx, tmp, protosBytes.size());
- JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p => ret=%d", ssl_ctx, protos, ret);
- return ret;
-}
-
-static jbyteArray NativeCrypto_SSL_get0_alpn_selected(JNIEnv* env, jclass,
- jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p SSL_get0_alpn_selected", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- const jbyte* npn;
- unsigned npnLength;
- SSL_get0_alpn_selected(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
- if (npnLength == 0) {
- return NULL;
- }
- jbyteArray result = env->NewByteArray(npnLength);
- if (result != NULL) {
- env->SetByteArrayRegion(result, 0, npnLength, npn);
- }
- return result;
-}
-
-#ifdef WITH_JNI_TRACE_KEYS
-static inline char hex_char(unsigned char in)
-{
- if (in < 10) {
- return '0' + in;
- } else if (in <= 0xF0) {
- return 'A' + in - 10;
- } else {
- return '?';
- }
-}
-
-static void hex_string(char **dest, unsigned char* input, int len)
-{
- *dest = (char*) malloc(len * 2 + 1);
- char *output = *dest;
- for (int i = 0; i < len; i++) {
- *output++ = hex_char(input[i] >> 4);
- *output++ = hex_char(input[i] & 0xF);
- }
- *output = '\0';
-}
-
-static void debug_print_session_key(SSL_SESSION* session)
-{
- char *session_id_str;
- char *master_key_str;
- const char *key_type;
- char *keyline;
-
- hex_string(&session_id_str, session->session_id, session->session_id_length);
- hex_string(&master_key_str, session->master_key, session->master_key_length);
-
- X509* peer = SSL_SESSION_get0_peer(session);
- EVP_PKEY* pkey = X509_PUBKEY_get(peer->cert_info->key);
- switch (EVP_PKEY_type(pkey->type)) {
- case EVP_PKEY_RSA:
- key_type = "RSA";
- break;
- case EVP_PKEY_DSA:
- key_type = "DSA";
- break;
- case EVP_PKEY_EC:
- key_type = "EC";
- break;
- default:
- key_type = "Unknown";
- break;
- }
-
- asprintf(&keyline, "%s Session-ID:%s Master-Key:%s\n", key_type, session_id_str,
- master_key_str);
- JNI_TRACE("ssl_session=%p %s", session, keyline);
-
- free(session_id_str);
- free(master_key_str);
- free(keyline);
-}
-#endif /* WITH_JNI_TRACE_KEYS */
-
-/**
- * Perform SSL handshake
- */
-static jlong NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
- jobject shc, jint timeout_millis, jboolean client_mode, jbyteArray npnProtocols,
- jbyteArray alpnProtocols) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout_millis=%d client_mode=%d npn=%p",
- ssl, fdObject, shc, timeout_millis, client_mode, npnProtocols);
- if (ssl == NULL) {
- return 0;
- }
- if (fdObject == NULL) {
- jniThrowNullPointerException(env, "fd == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd == null => 0", ssl);
- return 0;
- }
- if (shc == NULL) {
- jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslHandshakeCallbacks == null => 0", ssl);
- return 0;
- }
-
- NetFd fd(env, fdObject);
- if (fd.isClosed()) {
- // SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd.isClosed() => 0", ssl);
- return 0;
- }
-
- int ret = SSL_set_fd(ssl, fd.get());
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get());
-
- if (ret != 1) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
- "Error setting the file descriptor");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake SSL_set_fd => 0", ssl);
- return 0;
- }
-
- /*
- * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
- * forever and we can use select() to find out if the socket is ready.
- */
- if (!setBlocking(fd.get(), false)) {
- throwSSLExceptionStr(env, "Unable to make socket non blocking");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setBlocking => 0", ssl);
- return 0;
- }
-
- /*
- * Create our special application data.
- */
- AppData* appData = AppData::create();
- if (appData == NULL) {
- throwSSLExceptionStr(env, "Unable to create application data");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
- return 0;
- }
-
- SSL_set_app_data(ssl, reinterpret_cast<char*>(appData));
- JNI_TRACE("ssl=%p AppData::create => %p", ssl, appData);
-
- if (client_mode) {
- SSL_set_connect_state(ssl);
- } else {
- SSL_set_accept_state(ssl);
- if (alpnProtocols != NULL) {
- SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(ssl), alpn_select_callback, NULL);
- }
- }
-
- ret = 0;
- while (appData->aliveAndKicking) {
- errno = 0;
-
- if (!appData->setCallbackState(env, shc, fdObject, npnProtocols, alpnProtocols)) {
- // SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setCallbackState => 0", ssl);
- return 0;
- }
- ret = SSL_do_handshake(ssl);
- appData->clearCallbackState();
- // cert_verify_callback threw exception
- if (env->ExceptionCheck()) {
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake exception => 0", ssl);
- return 0;
- }
- // success case
- if (ret == 1) {
- break;
- }
- // retry case
- if (errno == EINTR) {
- continue;
- }
- // error case
- int sslError = SSL_get_error(ssl, ret);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout_millis=%d",
- ssl, ret, errno, sslError, timeout_millis);
-
- /*
- * If SSL_do_handshake doesn't succeed due to the socket being
- * either unreadable or unwritable, we use sslSelect to
- * wait for it to become ready. If that doesn't happen
- * before the specified timeout or an error occurs, we
- * cancel the handshake. Otherwise we try the SSL_connect
- * again.
- */
- if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
- appData->waitingThreads++;
- int selectResult = sslSelect(env, sslError, fdObject, appData, timeout_millis);
-
- if (selectResult == THROWN_EXCEPTION) {
- // SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslSelect => 0", ssl);
- return 0;
- }
- if (selectResult == -1) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == -1 => 0", ssl);
- return 0;
- }
- if (selectResult == 0) {
- throwSocketTimeoutException(env, "SSL handshake timed out");
- SSL_clear(ssl);
- freeOpenSslErrorState();
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == 0 => 0", ssl);
- return 0;
- }
- } else {
- // ALOGE("Unknown error %d during handshake", error);
- break;
- }
- }
-
- // clean error. See SSL_do_handshake(3SSL) man page.
- if (ret == 0) {
- /*
- * The other side closed the socket before the handshake could be
- * completed, but everything is within the bounds of the TLS protocol.
- * We still might want to find out the real reason of the failure.
- */
- int sslError = SSL_get_error(ssl, ret);
- if (sslError == SSL_ERROR_NONE || (sslError == SSL_ERROR_SYSCALL && errno == 0)) {
- throwSSLExceptionStr(env, "Connection closed by peer");
- } else {
- throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake terminated");
- }
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake clean error => 0", ssl);
- return 0;
- }
-
- // unclean error. See SSL_do_handshake(3SSL) man page.
- if (ret < 0) {
- /*
- * Translate the error and throw exception. We are sure it is an error
- * at this point.
- */
- int sslError = SSL_get_error(ssl, ret);
- throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake aborted");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake unclean error => 0", ssl);
- return 0;
- }
- SSL_SESSION* ssl_session = SSL_get1_session(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
-#ifdef WITH_JNI_TRACE_KEYS
- debug_print_session_key(ssl_session);
-#endif
- return (jlong) ssl_session;
-}
-
-/**
- * Perform SSL renegotiation
- */
-static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
- if (ssl == NULL) {
- return;
- }
- int result = SSL_renegotiate(ssl);
- if (result != 1) {
- throwSSLExceptionStr(env, "Problem with SSL_renegotiate");
- return;
- }
- // first call asks client to perform renegotiation
- int ret = SSL_do_handshake(ssl);
- if (ret != 1) {
- int sslError = SSL_get_error(ssl, ret);
- throwSSLExceptionWithSslErrors(env, ssl, sslError,
- "Problem with SSL_do_handshake after SSL_renegotiate");
- return;
- }
- // if client agrees, set ssl state and perform renegotiation
- ssl->state = SSL_ST_ACCEPT;
- SSL_do_handshake(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl);
-}
-
-/**
- * public static native byte[][] SSL_get_certificate(int ssl);
- */
-static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- X509* certificate = SSL_get_certificate(ssl);
- if (certificate == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
- // SSL_get_certificate can return NULL during an error as well.
- freeOpenSslErrorState();
- return NULL;
- }
-
- Unique_sk_X509 chain(sk_X509_new_null());
- if (chain.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl);
- return NULL;
- }
- if (!sk_X509_push(chain.get(), X509_dup_nocopy(certificate))) {
- jniThrowOutOfMemory(env, "Unable to push local certificate");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
- return NULL;
- }
- STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate);
- for (int i=0; i<sk_X509_num(cert_chain); i++) {
- if (!sk_X509_push(chain.get(), X509_dup_nocopy(sk_X509_value(cert_chain, i)))) {
- jniThrowOutOfMemory(env, "Unable to push local certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
- return NULL;
- }
- }
-
- jobjectArray objectArray = getCertificateBytes(env, chain.get());
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, objectArray);
- return objectArray;
-}
-
-// Fills a byte[][] with the peer certificates in the chain.
-static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
- Unique_sk_X509 chain_copy(NULL);
- if (ssl->server) {
- X509* x509 = SSL_get_peer_certificate(ssl);
- if (x509 == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl);
- return NULL;
- }
- chain_copy.reset(sk_X509_new_null());
- if (chain_copy.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate peer certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl);
- return NULL;
- }
- size_t chain_size = sk_X509_num(chain);
- for (size_t i = 0; i < chain_size; i++) {
- if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(sk_X509_value(chain, i)))) {
- jniThrowOutOfMemory(env, "Unable to push server's peer certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate chain push error", ssl);
- return NULL;
- }
- }
- if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(x509))) {
- jniThrowOutOfMemory(env, "Unable to push server's peer certificate");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl);
- return NULL;
- }
- chain = chain_copy.get();
- }
- jobjectArray objectArray = getCertificateBytes(env, chain);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, objectArray);
- return objectArray;
-}
-
-/**
- * Helper function which does the actual reading. The Java layer guarantees that
- * at most one thread will enter this function at any given time.
- *
- * @param ssl non-null; the SSL context
- * @param buf non-null; buffer to read into
- * @param len length of the buffer, in bytes
- * @param sslReturnCode original SSL return code
- * @param sslErrorCode filled in with the SSL error code in case of error
- * @return number of bytes read on success, -1 if the connection was
- * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
- */
-static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
- int* sslReturnCode, int* sslErrorCode, int read_timeout_millis) {
- JNI_TRACE("ssl=%p sslRead buf=%p len=%d", ssl, buf, len);
-
- if (len == 0) {
- // Don't bother doing anything in this case.
- return 0;
- }
-
- BIO* bio = SSL_get_rbio(ssl);
-
- AppData* appData = toAppData(ssl);
- if (appData == NULL) {
- return THROW_SSLEXCEPTION;
- }
-
- while (appData->aliveAndKicking) {
- errno = 0;
-
- if (MUTEX_LOCK(appData->mutex) == -1) {
- return -1;
- }
-
- unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
-
- if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
- MUTEX_UNLOCK(appData->mutex);
- return THROWN_EXCEPTION;
- }
- int result = SSL_read(ssl, buf, len);
- appData->clearCallbackState();
- // callbacks can happen if server requests renegotiation
- if (env->ExceptionCheck()) {
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p sslRead => THROWN_EXCEPTION", ssl);
- return THROWN_EXCEPTION;
- }
- int sslError = SSL_ERROR_NONE;
- if (result <= 0) {
- sslError = SSL_get_error(ssl, result);
- freeOpenSslErrorState();
- }
- JNI_TRACE("ssl=%p sslRead SSL_read result=%d sslError=%d", ssl, result, sslError);
-#ifdef WITH_JNI_TRACE_DATA
- for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
- int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE);
- JNI_TRACE("ssl=%p sslRead data: %d:\n%.*s", ssl, n, n, buf+i);
- }
-#endif
-
- // If we have been successful in moving data around, check whether it
- // might make sense to wake up other blocked threads, so they can give
- // it a try, too.
- if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
- && appData->waitingThreads > 0) {
- sslNotify(appData);
- }
-
- // If we are blocked by the underlying socket, tell the world that
- // there will be one more waiting thread now.
- if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
- appData->waitingThreads++;
- }
-
- MUTEX_UNLOCK(appData->mutex);
-
- switch (sslError) {
- // Successfully read at least one byte.
- case SSL_ERROR_NONE: {
- return result;
- }
-
- // Read zero bytes. End of stream reached.
- case SSL_ERROR_ZERO_RETURN: {
- return -1;
- }
-
- // Need to wait for availability of underlying layer, then retry.
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE: {
- int selectResult = sslSelect(env, sslError, fdObject, appData, read_timeout_millis);
- if (selectResult == THROWN_EXCEPTION) {
- return THROWN_EXCEPTION;
- }
- if (selectResult == -1) {
- *sslReturnCode = -1;
- *sslErrorCode = sslError;
- return THROW_SSLEXCEPTION;
- }
- if (selectResult == 0) {
- return THROW_SOCKETTIMEOUTEXCEPTION;
- }
-
- break;
- }
-
- // A problem occurred during a system call, but this is not
- // necessarily an error.
- case SSL_ERROR_SYSCALL: {
- // Connection closed without proper shutdown. Tell caller we
- // have reached end-of-stream.
- if (result == 0) {
- return -1;
- }
-
- // System call has been interrupted. Simply retry.
- if (errno == EINTR) {
- break;
- }
-
- // Note that for all other system call errors we fall through
- // to the default case, which results in an Exception.
- }
-
- // Everything else is basically an error.
- default: {
- *sslReturnCode = result;
- *sslErrorCode = sslError;
- return THROW_SSLEXCEPTION;
- }
- }
- }
-
- return -1;
-}
-
-/**
- * OpenSSL read function (2): read into buffer at offset n chunks.
- * Returns 1 (success) or value <= 0 (failure).
- */
-static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
- jobject shc, jbyteArray b, jint offset, jint len,
- jint read_timeout_millis)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d read_timeout_millis=%d",
- ssl, fdObject, shc, b, offset, len, read_timeout_millis);
- if (ssl == NULL) {
- return 0;
- }
- if (fdObject == NULL) {
- jniThrowNullPointerException(env, "fd == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl);
- return 0;
- }
- if (shc == NULL) {
- jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl);
- return 0;
- }
-
- ScopedByteArrayRW bytes(env, b);
- if (bytes.get() == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl);
- return 0;
- }
- int returnCode = 0;
- int sslErrorCode = SSL_ERROR_NONE;;
-
- int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
- &returnCode, &sslErrorCode, read_timeout_millis);
-
- int result;
- switch (ret) {
- case THROW_SSLEXCEPTION:
- // See sslRead() regarding improper failure to handle normal cases.
- throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error");
- result = -1;
- break;
- case THROW_SOCKETTIMEOUTEXCEPTION:
- throwSocketTimeoutException(env, "Read timed out");
- result = -1;
- break;
- case THROWN_EXCEPTION:
- // SocketException thrown by NetFd.isClosed
- // or RuntimeException thrown by callback
- result = -1;
- break;
- default:
- result = ret;
- break;
- }
-
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result);
- return result;
-}
-
-/**
- * Helper function which does the actual writing. The Java layer guarantees that
- * at most one thread will enter this function at any given time.
- *
- * @param ssl non-null; the SSL context
- * @param buf non-null; buffer to write
- * @param len length of the buffer, in bytes
- * @param sslReturnCode original SSL return code
- * @param sslErrorCode filled in with the SSL error code in case of error
- * @return number of bytes read on success, -1 if the connection was
- * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
- */
-static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
- int* sslReturnCode, int* sslErrorCode, int write_timeout_millis) {
- JNI_TRACE("ssl=%p sslWrite buf=%p len=%d write_timeout_millis=%d",
- ssl, buf, len, write_timeout_millis);
-
- if (len == 0) {
- // Don't bother doing anything in this case.
- return 0;
- }
-
- BIO* bio = SSL_get_wbio(ssl);
-
- AppData* appData = toAppData(ssl);
- if (appData == NULL) {
- return THROW_SSLEXCEPTION;
- }
-
- int count = len;
-
- while (appData->aliveAndKicking && ((len > 0) || (ssl->s3->wbuf.left > 0))) {
- errno = 0;
-
- if (MUTEX_LOCK(appData->mutex) == -1) {
- return -1;
- }
-
- unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
-
- if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
- MUTEX_UNLOCK(appData->mutex);
- return THROWN_EXCEPTION;
- }
- JNI_TRACE("ssl=%p sslWrite SSL_write len=%d left=%d", ssl, len, ssl->s3->wbuf.left);
- int result = SSL_write(ssl, buf, len);
- appData->clearCallbackState();
- // callbacks can happen if server requests renegotiation
- if (env->ExceptionCheck()) {
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p sslWrite exception => THROWN_EXCEPTION", ssl);
- return THROWN_EXCEPTION;
- }
- int sslError = SSL_ERROR_NONE;
- if (result <= 0) {
- sslError = SSL_get_error(ssl, result);
- freeOpenSslErrorState();
- }
- JNI_TRACE("ssl=%p sslWrite SSL_write result=%d sslError=%d left=%d",
- ssl, result, sslError, ssl->s3->wbuf.left);
-#ifdef WITH_JNI_TRACE_DATA
- for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
- int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE);
- JNI_TRACE("ssl=%p sslWrite data: %d:\n%.*s", ssl, n, n, buf+i);
- }
-#endif
-
- // If we have been successful in moving data around, check whether it
- // might make sense to wake up other blocked threads, so they can give
- // it a try, too.
- if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
- && appData->waitingThreads > 0) {
- sslNotify(appData);
- }
-
- // If we are blocked by the underlying socket, tell the world that
- // there will be one more waiting thread now.
- if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
- appData->waitingThreads++;
- }
-
- MUTEX_UNLOCK(appData->mutex);
-
- switch (sslError) {
- // Successfully wrote at least one byte.
- case SSL_ERROR_NONE: {
- buf += result;
- len -= result;
- break;
- }
-
- // Wrote zero bytes. End of stream reached.
- case SSL_ERROR_ZERO_RETURN: {
- return -1;
- }
-
- // Need to wait for availability of underlying layer, then retry.
- // The concept of a write timeout doesn't really make sense, and
- // it's also not standard Java behavior, so we wait forever here.
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE: {
- int selectResult = sslSelect(env, sslError, fdObject, appData, write_timeout_millis);
- if (selectResult == THROWN_EXCEPTION) {
- return THROWN_EXCEPTION;
- }
- if (selectResult == -1) {
- *sslReturnCode = -1;
- *sslErrorCode = sslError;
- return THROW_SSLEXCEPTION;
- }
- if (selectResult == 0) {
- return THROW_SOCKETTIMEOUTEXCEPTION;
- }
-
- break;
- }
-
- // A problem occurred during a system call, but this is not
- // necessarily an error.
- case SSL_ERROR_SYSCALL: {
- // Connection closed without proper shutdown. Tell caller we
- // have reached end-of-stream.
- if (result == 0) {
- return -1;
- }
-
- // System call has been interrupted. Simply retry.
- if (errno == EINTR) {
- break;
- }
-
- // Note that for all other system call errors we fall through
- // to the default case, which results in an Exception.
- }
-
- // Everything else is basically an error.
- default: {
- *sslReturnCode = result;
- *sslErrorCode = sslError;
- return THROW_SSLEXCEPTION;
- }
- }
- }
- JNI_TRACE("ssl=%p sslWrite => count=%d", ssl, count);
-
- return count;
-}
-
-/**
- * OpenSSL write function (2): write into buffer at offset n chunks.
- */
-static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
- jobject shc, jbyteArray b, jint offset, jint len, jint write_timeout_millis)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d write_timeout_millis=%d",
- ssl, fdObject, shc, b, offset, len, write_timeout_millis);
- if (ssl == NULL) {
- return;
- }
- if (fdObject == NULL) {
- jniThrowNullPointerException(env, "fd == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl);
- return;
- }
- if (shc == NULL) {
- jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl);
- return;
- }
-
- ScopedByteArrayRO bytes(env, b);
- if (bytes.get() == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl);
- return;
- }
- int returnCode = 0;
- int sslErrorCode = SSL_ERROR_NONE;
- int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
- len, &returnCode, &sslErrorCode, write_timeout_millis);
-
- switch (ret) {
- case THROW_SSLEXCEPTION:
- // See sslWrite() regarding improper failure to handle normal cases.
- throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error");
- break;
- case THROW_SOCKETTIMEOUTEXCEPTION:
- throwSocketTimeoutException(env, "Write timed out");
- break;
- case THROWN_EXCEPTION:
- // SocketException thrown by NetFd.isClosed
- break;
- default:
- break;
- }
-}
-
-/**
- * Interrupt any pending I/O before closing the socket.
- */
-static void NativeCrypto_SSL_interrupt(
- JNIEnv* env, jclass, jlong ssl_address) {
- SSL* ssl = to_SSL(env, ssl_address, false);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
- if (ssl == NULL) {
- return;
- }
-
- /*
- * Mark the connection as quasi-dead, then send something to the emergency
- * file descriptor, so any blocking select() calls are woken up.
- */
- AppData* appData = toAppData(ssl);
- if (appData != NULL) {
- appData->aliveAndKicking = 0;
-
- // At most two threads can be waiting.
- sslNotify(appData);
- sslNotify(appData);
- }
-}
-
-/**
- * OpenSSL close SSL socket function.
- */
-static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jlong ssl_address,
- jobject fdObject, jobject shc) {
- SSL* ssl = to_SSL(env, ssl_address, false);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
- if (ssl == NULL) {
- return;
- }
- if (fdObject == NULL) {
- jniThrowNullPointerException(env, "fd == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl);
- return;
- }
- if (shc == NULL) {
- jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
- return;
- }
-
- AppData* appData = toAppData(ssl);
- if (appData != NULL) {
- if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
- // SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
- freeOpenSslErrorState();
- return;
- }
-
- /*
- * Try to make socket blocking again. OpenSSL literature recommends this.
- */
- int fd = SSL_get_fd(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd);
- if (fd != -1) {
- setBlocking(fd, true);
- }
-
- int ret = SSL_shutdown(ssl);
- appData->clearCallbackState();
- // callbacks can happen if server requests renegotiation
- if (env->ExceptionCheck()) {
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
- return;
- }
- switch (ret) {
- case 0:
- /*
- * Shutdown was not successful (yet), but there also
- * is no error. Since we can't know whether the remote
- * server is actually still there, and we don't want to
- * get stuck forever in a second SSL_shutdown() call, we
- * simply return. This is not security a problem as long
- * as we close the underlying socket, which we actually
- * do, because that's where we are just coming from.
- */
- break;
- case 1:
- /*
- * Shutdown was successful. We can safely return. Hooray!
- */
- break;
- default:
- /*
- * Everything else is a real error condition. We should
- * let the Java layer know about this by throwing an
- * exception.
- */
- int sslError = SSL_get_error(ssl, ret);
- throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
- break;
- }
- }
-
- SSL_clear(ssl);
- freeOpenSslErrorState();
-}
-
-/**
- * public static native void SSL_free(int ssl);
- */
-static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
- if (ssl == NULL) {
- return;
- }
-
- AppData* appData = toAppData(ssl);
- SSL_set_app_data(ssl, NULL);
- delete appData;
- SSL_free(ssl);
-}
-
-/**
- * Gets and returns in a byte array the ID of the actual SSL session.
- */
-static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
- jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
- if (ssl_session == NULL) {
- return NULL;
- }
- jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
- if (result != NULL) {
- jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
- env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
- }
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d",
- ssl_session, result, ssl_session->session_id_length);
- return result;
-}
-
-/**
- * Gets and returns in a long integer the creation's time of the
- * actual SSL session.
- */
-static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
- if (ssl_session == NULL) {
- return 0;
- }
- // result must be jlong, not long or *1000 will overflow
- jlong result = SSL_SESSION_get_time(ssl_session);
- result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, result);
- return result;
-}
-
-/**
- * Gets and returns in a string the version of the SSL protocol. If it
- * returns the string "unknown" it means that no connection is established.
- */
-static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
- if (ssl_session == NULL) {
- return NULL;
- }
- const char* protocol = SSL_SESSION_get_version(ssl_session);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol);
- return env->NewStringUTF(protocol);
-}
-
-/**
- * Gets and returns in a string the cipher negotiated for the SSL session.
- */
-static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
- if (ssl_session == NULL) {
- return NULL;
- }
- const SSL_CIPHER* cipher = ssl_session->cipher;
- const char* name = SSL_CIPHER_get_name(cipher);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name);
- return env->NewStringUTF(name);
-}
-
-/**
- * Frees the SSL session.
- */
-static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
- if (ssl_session == NULL) {
- return;
- }
- SSL_SESSION_free(ssl_session);
-}
-
-
-/**
- * Serializes the native state of the session (ID, cipher, and keys but
- * not certificates). Returns a byte[] containing the DER-encoded state.
- * See apache mod_ssl.
- */
-static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
- if (ssl_session == NULL) {
- return NULL;
- }
- return ASN1ToByteArray<SSL_SESSION, i2d_SSL_SESSION>(env, ssl_session);
-}
-
-/**
- * Deserialize the session.
- */
-static jlong NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
- JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
-
- ScopedByteArrayRO bytes(env, javaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception");
- return 0;
- }
- const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get());
- SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, bytes.size());
-
- // Initialize SSL_SESSION cipher field based on cipher_id http://b/7091840
- if (ssl_session != NULL) {
- // based on ssl_get_prev_session
- uint32_t cipher_id_network_order = htonl(ssl_session->cipher_id);
- uint8_t* cipher_id_byte_pointer = reinterpret_cast<uint8_t*>(&cipher_id_network_order);
- if (ssl_session->ssl_version >= SSL3_VERSION_MAJOR) {
- cipher_id_byte_pointer += 2; // skip first two bytes for SSL3+
- } else {
- cipher_id_byte_pointer += 1; // skip first byte for SSL2
- }
- ssl_session->cipher = SSLv23_method()->get_cipher_by_char(cipher_id_byte_pointer);
- JNI_TRACE("NativeCrypto_d2i_SSL_SESSION cipher_id=%lx hton=%x 0=%x 1=%x cipher=%s",
- ssl_session->cipher_id, cipher_id_network_order,
- cipher_id_byte_pointer[0], cipher_id_byte_pointer[1],
- SSL_CIPHER_get_name(ssl_session->cipher));
- } else {
- freeOpenSslErrorState();
- }
-
- JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
- return reinterpret_cast<uintptr_t>(ssl_session);
-}
-
-static jlong NativeCrypto_ERR_peek_last_error(JNIEnv*, jclass) {
- return ERR_peek_last_error();
-}
-
-#define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;"
-#define SSL_CALLBACKS "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto$SSLHandshakeCallbacks;"
-static JNINativeMethod sNativeCryptoMethods[] = {
- NATIVE_METHOD(NativeCrypto, clinit, "()V"),
- NATIVE_METHOD(NativeCrypto, ENGINE_load_dynamic, "()V"),
- NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, ENGINE_add, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ENGINE_init, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ENGINE_free, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(JLjava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, ENGINE_get_id, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, ENGINE_ctrl_cmd_string, "(JLjava/lang/String;Ljava/lang/String;I)I"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)J"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)J"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_EC_KEY, "(JJ[B)J"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_mac_key, "(I[B)J"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_public, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_private, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_cmp, "(JJ)I"),
- NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)J"),
- NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)J"),
- NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)J"),
- NATIVE_METHOD(NativeCrypto, RSA_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, RSA_private_encrypt, "(I[B[BJI)I"),
- NATIVE_METHOD(NativeCrypto, RSA_public_decrypt, "(I[B[BJI)I"),
- NATIVE_METHOD(NativeCrypto, RSA_public_encrypt, "(I[B[BJI)I"),
- NATIVE_METHOD(NativeCrypto, RSA_private_decrypt, "(I[B[BJI)I"),
- NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, DSA_generate_key, "(I[B[B[B[B)J"),
- NATIVE_METHOD(NativeCrypto, get_DSA_params, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_new_by_curve_name, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_new_curve, "(I[B[B[B)J"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_dup, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_set_asn1_flag, "(JI)V"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_set_point_conversion_form, "(JI)V"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve_name, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_order, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_degree, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_cofactor, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_clear_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_cmp, "(JJ)Z"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_generator, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_set_generator, "(JJ[B[B)V"),
- NATIVE_METHOD(NativeCrypto, get_EC_GROUP_type, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_new, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_clear_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_cmp, "(JJJ)Z"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_set_affine_coordinates, "(JJ[B[B)V"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_get_affine_coordinates, "(JJ)[[B"),
- NATIVE_METHOD(NativeCrypto, EC_KEY_generate_key, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_KEY_get0_group, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_KEY_get_private_key, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, EC_KEY_get_public_key, "(J)J"),
- NATIVE_METHOD(NativeCrypto, ECDH_compute_key, "([BIJJ)I"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()J"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_init, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(J[BI)I"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(J[BII)V"),
- NATIVE_METHOD(NativeCrypto, EVP_SignInit, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EVP_SignUpdate, "(J[BII)V"),
- NATIVE_METHOD(NativeCrypto, EVP_SignFinal, "(J[BIJ)I"),
- NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(J[BII)V"),
- NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(J[BIIJ)I"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestSignInit, "(JJJ)V"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestSignUpdate, "(J[B)V"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestSignFinal, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(JJ[B[BZ)V"),
- NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(J[BI[BII)I"),
- NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(J[BI)I"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_iv_length, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_new, "()J"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_block_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, get_EVP_CIPHER_CTX_buf_len, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_padding, "(JZ)V"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_key_length, "(JI)V"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_cleanup, "(J)V"),
- NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
- NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
- NATIVE_METHOD(NativeCrypto, RAND_bytes, "([B)V"),
- NATIVE_METHOD(NativeCrypto, OBJ_txt2nid, "(Ljava/lang/String;)I"),
- NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_longName, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_oid, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, create_BIO_InputStream, ("(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream;)J")),
- NATIVE_METHOD(NativeCrypto, create_BIO_OutputStream, "(Ljava/io/OutputStream;)J"),
- NATIVE_METHOD(NativeCrypto, BIO_read, "(J[B)I"),
- NATIVE_METHOD(NativeCrypto, BIO_write, "(J[BII)V"),
- NATIVE_METHOD(NativeCrypto, BIO_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, X509_NAME_print_ex, "(JJ)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, d2i_X509_bio, "(J)J"),
- NATIVE_METHOD(NativeCrypto, d2i_X509, "([B)J"),
- NATIVE_METHOD(NativeCrypto, i2d_X509, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, i2d_X509_PUBKEY, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509, "(J)J"),
- NATIVE_METHOD(NativeCrypto, PEM_read_bio_PKCS7, "(JI)[J"),
- NATIVE_METHOD(NativeCrypto, d2i_PKCS7_bio, "(JI)[J"),
- NATIVE_METHOD(NativeCrypto, i2d_PKCS7, "([J)[B"),
- NATIVE_METHOD(NativeCrypto, ASN1_seq_unpack_X509_bio, "(J)[J"),
- NATIVE_METHOD(NativeCrypto, ASN1_seq_pack_X509, "([J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, X509_cmp, "(JJ)I"),
- NATIVE_METHOD(NativeCrypto, get_X509_hashCode, "(J)I"),
- NATIVE_METHOD(NativeCrypto, X509_print_ex, "(JJJJ)V"),
- NATIVE_METHOD(NativeCrypto, X509_get_pubkey, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_get_issuer_name, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_get_subject_name, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_pubkey_oid, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_oid, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_parameter, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_issuerUID, "(J)[Z"),
- NATIVE_METHOD(NativeCrypto, get_X509_subjectUID, "(J)[Z"),
- NATIVE_METHOD(NativeCrypto, get_X509_ex_kusage, "(J)[Z"),
- NATIVE_METHOD(NativeCrypto, get_X509_ex_xkusage, "(J)[Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_ex_pathlen, "(J)I"),
- NATIVE_METHOD(NativeCrypto, X509_get_ext_oid, "(JLjava/lang/String;)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext_oid, "(JLjava/lang/String;)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_crl_enc, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_verify, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_lastUpdate, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_nextUpdate, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext_oid, "(JLjava/lang/String;)[B"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_serialNumber, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_print, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_revocationDate, "(J)J"),
- NATIVE_METHOD(NativeCrypto, get_X509_ext_oids, "(JI)[Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_ext_oids, "(JI)[Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_ext_oids, "(JI)[Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_GENERAL_NAME_stack, "(JI)[[Ljava/lang/Object;"),
- NATIVE_METHOD(NativeCrypto, X509_get_notBefore, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_get_notAfter, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_get_version, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_get_serialNumber, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_verify, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, get_X509_cert_info_enc, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_signature, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_signature, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_ex_flags, "(J)I"),
- NATIVE_METHOD(NativeCrypto, X509_check_issued, "(JJ)I"),
- NATIVE_METHOD(NativeCrypto, d2i_X509_CRL_bio, "(J)J"),
- NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509_CRL, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_cert, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_serial, "(J[B)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_REVOKED, "(J)[J"),
- NATIVE_METHOD(NativeCrypto, i2d_X509_CRL, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_print, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_oid, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_parameter, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_issuer_name, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_version, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext, "(JLjava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext, "(JLjava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_dup, "(J)J"),
- NATIVE_METHOD(NativeCrypto, i2d_X509_REVOKED, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_supported_extension, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ASN1_TIME_to_Calendar, "(JLjava/util/Calendar;)V"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()J"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(J[B)V"),
- NATIVE_METHOD(NativeCrypto, SSL_new, "(J)J"),
- NATIVE_METHOD(NativeCrypto, SSL_enable_tls_channel_id, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_tls_channel_id, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, SSL_set1_tls_channel_id, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(J[[B)V"),
- NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(J[[B)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(J)J"),
- NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, SSL_get_options, "(J)J"),
- NATIVE_METHOD(NativeCrypto, SSL_set_options, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(J[Ljava/lang/String;)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(JI)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_session, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(JZ)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(JLjava/lang/String;)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B[B)I"),
- NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, SSL_read, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
- NATIVE_METHOD(NativeCrypto, SSL_write, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"),
- NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(J" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
- NATIVE_METHOD(NativeCrypto, SSL_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(J)J"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)J"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_set_alpn_protos, "(J[B)I"),
- NATIVE_METHOD(NativeCrypto, SSL_get0_alpn_selected, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, ERR_peek_last_error, "()J"),
-};
-
-static void initialize_conscrypt(JNIEnv* env) {
- jniRegisterNativeMethods(env, TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto",
- sNativeCryptoMethods, NELEM(sNativeCryptoMethods));
-
- ScopedLocalRef<jclass> localClass(env,
- env->FindClass(TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream"));
- openSslOutputStreamClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
- if (openSslOutputStreamClass == NULL) {
- ALOGE("failed to find class OpenSSLBIOInputStream");
- abort();
- }
-
- calendar_setMethod = env->GetMethodID(calendarClass, "set", "(IIIIII)V");
- inputStream_readMethod = env->GetMethodID(inputStreamClass, "read", "([B)I");
- integer_valueOfMethod = env->GetStaticMethodID(integerClass, "valueOf",
- "(I)Ljava/lang/Integer;");
- openSslInputStream_readLineMethod = env->GetMethodID(openSslOutputStreamClass, "gets",
- "([B)I");
- outputStream_writeMethod = env->GetMethodID(outputStreamClass, "write", "([B)V");
- outputStream_flushMethod = env->GetMethodID(outputStreamClass, "flush", "()V");
-}
-
-static jclass findClass(JNIEnv* env, const char* name) {
- ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
- jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
- if (result == NULL) {
- ALOGE("failed to find class '%s'", name);
- abort();
- }
- return result;
-}
-
-// Use JNI_OnLoad for when we're standalone
-int JNI_OnLoad(JavaVM *vm, void*) {
- JNI_TRACE("JNI_OnLoad NativeCrypto");
- gJavaVM = vm;
-
- JNIEnv *env;
- if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
- ALOGE("Could not get JNIEnv");
- return JNI_ERR;
- }
-
- byteArrayClass = findClass(env, "[B");
- calendarClass = findClass(env, "java/util/Calendar");
- inputStreamClass = findClass(env, "java/io/InputStream");
- integerClass = findClass(env, "java/lang/Integer");
- objectClass = findClass(env, "java/lang/Object");
- objectArrayClass = findClass(env, "[Ljava/lang/Object;");
- outputStreamClass = findClass(env, "java/io/OutputStream");
- stringClass = findClass(env, "java/lang/String");
-
- initialize_conscrypt(env);
- return JNI_VERSION_1_6;
-}
diff --git a/crypto/src/main/native/sub.mk b/crypto/src/main/native/sub.mk
deleted file mode 100644
index 62f8672..0000000
--- a/crypto/src/main/native/sub.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- mode: makefile -*-
-# This file is included by the top-level libcore Android.mk.
-# It's not a normal makefile, so we don't include CLEAR_VARS
-# or BUILD_*_LIBRARY.
-
-LOCAL_SRC_FILES := \
- org_conscrypt_NativeCrypto.cpp
-
-LOCAL_C_INCLUDES += \
- libcore/luni/src/main/native
-
-# Any shared/static libs that are listed here must also
-# be listed in libs/nativehelper/Android.mk.
-# TODO: fix this requirement
-
-#LOCAL_SHARED_LIBRARIES +=
-
-#LOCAL_STATIC_LIBRARIES +=
diff --git a/crypto/src/test/java/org/conscrypt/CertPinManagerTest.java b/crypto/src/test/java/org/conscrypt/CertPinManagerTest.java
deleted file mode 100644
index 04890f6..0000000
--- a/crypto/src/test/java/org/conscrypt/CertPinManagerTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.security.cert.X509Certificate;
-import java.security.KeyStore;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.List;
-import junit.framework.TestCase;
-import libcore.java.security.TestKeyStore;
-
-public class CertPinManagerTest extends TestCase {
-
- private X509Certificate[] chain;
- private List<X509Certificate> shortChain;
- private List<X509Certificate> longChain;
- private String shortPin;
- private String longPin;
- private List<File> tmpFiles = new ArrayList<File>();
-
- private String writeTmpPinFile(String text) throws Exception {
- File tmp = File.createTempFile("pins", null);
- FileWriter fstream = new FileWriter(tmp);
- fstream.write(text);
- fstream.close();
- tmpFiles.add(tmp);
- return tmp.getPath();
- }
-
- private static String getFingerprint(X509Certificate cert) throws NoSuchAlgorithmException {
- MessageDigest dgst = MessageDigest.getInstance("SHA512");
- byte[] encoded = cert.getPublicKey().getEncoded();
- byte[] fingerprint = dgst.digest(encoded);
- return IntegralToString.bytesToHexString(fingerprint, false);
- }
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- // build some valid chains
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- chain = (X509Certificate[]) pke.getCertificateChain();
- X509Certificate root = chain[2];
- X509Certificate server = chain[0];
-
- // build the short and long chains
- shortChain = new ArrayList<X509Certificate>();
- shortChain.add(root);
- longChain = new ArrayList<X509Certificate>();
- longChain.add(server);
-
- // we'll use the root as the pin for the short entry and the server as the pin for the long
- shortPin = getFingerprint(root);
- longPin = getFingerprint(server);
- }
-
- @Override
- public void tearDown() throws Exception {
- try {
- for (File f : tmpFiles) {
- f.delete();
- }
- tmpFiles.clear();
- } finally {
- super.tearDown();
- }
- }
-
- public void testPinFileMaximumLookup() throws Exception {
-
- // write a pinfile with two entries, one longer than the other
- String shortEntry = "*.google.com=true|" + shortPin;
- String longEntry = "*.clients.google.com=true|" + longPin;
-
- // create the pinFile
- String path = writeTmpPinFile(shortEntry + "\n" + longEntry);
- CertPinManager pf = new CertPinManager(path, new TrustedCertificateStore());
-
- // verify that the shorter chain doesn't work for a name matching the longer
- assertTrue("short chain long uri failed",
- pf.chainIsNotPinned("android.clients.google.com", shortChain));
- // verify that the longer chain doesn't work for a name matching the shorter
- assertTrue("long chain short uri failed",
- pf.chainIsNotPinned("android.google.com", longChain));
- // verify that the shorter chain works for the shorter domain
- assertTrue("short chain short uri failed",
- !pf.chainIsNotPinned("android.google.com", shortChain));
- // and the same for the longer
- assertTrue("long chain long uri failed",
- !pf.chainIsNotPinned("android.clients.google.com", longChain));
- }
-
- public void testPinEntryMalformedEntry() throws Exception {
- // set up the pinEntry with a bogus entry
- String entry = "*.google.com=";
- try {
- new PinListEntry(entry, new TrustedCertificateStore());
- fail("Accepted an empty pin list entry.");
- } catch (PinEntryException expected) {
- }
- }
-
- public void testPinEntryNull() throws Exception {
- // set up the pinEntry with a bogus entry
- String entry = null;
- try {
- new PinListEntry(entry, new TrustedCertificateStore());
- fail("Accepted a basically wholly bogus entry.");
- } catch (NullPointerException expected) {
- }
- }
-
- public void testPinEntryEmpty() throws Exception {
- // set up the pinEntry with a bogus entry
- try {
- new PinListEntry("", new TrustedCertificateStore());
- fail("Accepted an empty entry.");
- } catch (PinEntryException expected) {
- }
- }
-
- public void testPinEntryPinFailure() throws Exception {
- // write a pinfile with two entries, one longer than the other
- String shortEntry = "*.google.com=true|" + shortPin;
-
- // set up the pinEntry with a pinlist that doesn't match what we'll give it
- PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
- assertTrue("Not enforcing!", e.getEnforcing());
- // verify that it doesn't accept
- boolean retval = e.chainIsNotPinned(longChain);
- assertTrue("Accepted an incorrect pinning, this is very bad", retval);
- }
-
- public void testPinEntryPinSuccess() throws Exception {
- // write a pinfile with two entries, one longer than the other
- String shortEntry = "*.google.com=true|" + shortPin;
-
- // set up the pinEntry with a pinlist that matches what we'll give it
- PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
- assertTrue("Not enforcing!", e.getEnforcing());
- // verify that it accepts
- boolean retval = e.chainIsNotPinned(shortChain);
- assertTrue("Failed on a correct pinning, this is very bad", !retval);
- }
-
- public void testPinEntryNonEnforcing() throws Exception {
- // write a pinfile with two entries, one longer than the other
- String shortEntry = "*.google.com=false|" + shortPin;
-
- // set up the pinEntry with a pinlist that matches what we'll give it
- PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
- assertFalse("Enforcing!", e.getEnforcing());
- // verify that it accepts
- boolean retval = e.chainIsNotPinned(shortChain);
- assertTrue("Failed on an unenforced pinning, this is bad-ish", !retval);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/ChainStrengthAnalyzerTest.java b/crypto/src/test/java/org/conscrypt/ChainStrengthAnalyzerTest.java
deleted file mode 100644
index 7663789..0000000
--- a/crypto/src/test/java/org/conscrypt/ChainStrengthAnalyzerTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import junit.framework.TestCase;
-
-public class ChainStrengthAnalyzerTest extends TestCase {
-
- //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
- //-newkey rsa:2048 -sha256 -keyout k.pem -out good.pem
- private static final String GOOD_PEM = "" +
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIDYTCCAkmgAwIBAgIJAPFX8KGuEZcgMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNV\n" +
- "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
- "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQ0MTBaFw0xMzEwMTUyMTQ0MTBa\n" +
- "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
- "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
- "ADCCAQoCggEBAM44hz3eTINuAIS9OYmg6DkUIj3MItn5dgbcMEdbXrhNpeWY93ho\n" +
- "WQFfsqcSSx28NzqKJmnX+cyinzIUfVde/qciP9P7fxRDokRsf34DJ6gXQplz6P2t\n" +
- "s4CWjYM+WXJrvEUgLUQ3CBV0CCrtYvG1B9wYsBdAdWkVaMxTvEt7aVxcvJYzp+KU\n" +
- "ME7HDg0PVxptvUExIskcqKVmW7i748AgBLhd0r1nFWLuH20d42Aowja0Wi19fWl2\n" +
- "SEMErDRjG8jIPUdSoOLPVLGTktEpex51xnAaZ+I7hy6zs55dq8ua/hE/v2cXIkiQ\n" +
- "ZXpWyvI/MaKEfeydLnNpa7J3GpH3KW93HQcCAwEAAaNQME4wHQYDVR0OBBYEFA0M\n" +
- "RI+3hIPCSpVVArisr3Y3/sheMB8GA1UdIwQYMBaAFA0MRI+3hIPCSpVVArisr3Y3\n" +
- "/sheMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFgUNyuy2qaJvgDO\n" +
- "plYudTrJR38O3id1B5oKOzgTEgRrfmHHfyloY4fL5gjAGNp7vdlDKSHC2Ebo23/X\n" +
- "Wg535MJ2296R855jaTMdkSE0+4ASpdmon1D007H0FhLyojlKVta3pqMAF1zsp0YF\n" +
- "Mf3V/rVMDxCOnbSnqAX0+1nW8Qm4Jgrr3AAMafZk6ypq0xuNQn+sUWuIWw3Xv5Jl\n" +
- "KehjnuKtMgVYkn2ItRNnUdhm2dQK+Phdb5Yg8WHXN/r9sZQdORg8FQS9TfQJmimB\n" +
- "CVYuqA9Dt0JJZPuO/Pd1yAxWP4NpxX1xr3lNQ5jrTO702QA3gOrscluULLzrYR50\n" +
- "FoAjeos=\n" +
- "-----END CERTIFICATE-----";
-
- //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
- //-newkey rsa:2048 -md5 -keyout k.pem -out md5.pem
- private static final String MD5_PEM = "" +
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIDYTCCAkmgAwIBAgIJAJsffMf2cyx0MA0GCSqGSIb3DQEBBAUAMEcxCzAJBgNV\n" +
- "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
- "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQzMzZaFw0xMzEwMTUyMTQzMzZa\n" +
- "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
- "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
- "ADCCAQoCggEBAOJyiUwgf/VsdbTTdx6dsb742adeBFBY1FpSWCeQW/JVtdMephbK\n" +
- "AA00nu8Xq3dNx9bp8AqvzeyHi/RBsZOtb2eAsOXE3RbFy28ehDTHdG34fRQNT6kp\n" +
- "RUHw8wrUGovMVqS8j+iW8HfAy3sjArje0ygz2NIETlNQbEOifAJtY+AEfZwZE0/0\n" +
- "IMVP4hwTmIgyReJBDmAx31clwsWZSPar9x+WQfeJ3rfy5LBCtf3RUbdgnvynBHFk\n" +
- "FjucwoqgOOXviCWxIa0F+ZAmZJBj5+pLN/V92RXOu0c2fR3Mf68J67OJ+K4ueo1N\n" +
- "nBhRsulWMmGqIVjYOZQxiNzWYcOVXj3DTRMCAwEAAaNQME4wHQYDVR0OBBYEFJbY\n" +
- "TU06RuJaiMBs2vzx5y0MbaQOMB8GA1UdIwQYMBaAFJbYTU06RuJaiMBs2vzx5y0M\n" +
- "baQOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBAFEky0jLTmKefDVX\n" +
- "8O84KoupmQ2qQQBaQF3F5GEuhi0qJRwnmsWkCmsxPP55S67WDFp3JH+LX14UxL4T\n" +
- "fbG2CXHt/BF1yU3Z8JBwx3bDmfUnUOAFkO3nmByb11FyZTHMzq4jp03DexWREv4q\n" +
- "Ai5+5Xb56VECgCH/hnGqhQeFGhlZUcSXobVhAU+39L6azWELXxk1K4bpVxYFGn1N\n" +
- "uZ+dWmb6snPKDzG6J5IIX8QIs6G8H6ptj+QNoU/qTcZEnuzMJxpqMsyq10AA+bY/\n" +
- "VAYyXeZm3XZrtqYosDeiUdmcL0jjmyQtyOcAoVUQWj1EJuRjXg4BvI6xxRAIPWYT\n" +
- "EDeWHJE=\n" +
- "-----END CERTIFICATE-----";
-
- //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
- //-newkey rsa:512 -sha256 -keyout k.pem -out short.pem
- private static final String SHORT_PEM = "" +
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIB1zCCAYGgAwIBAgIJAOxaz9TreDNIMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNV\n" +
- "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
- "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQzMjNaFw0xMzEwMTUyMTQzMjNa\n" +
- "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
- "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC\n" +
- "QQCoMgxK9HG0L+hXEht1mKq6ApN3+3lmIEVUcWQKL7EMmn9+L6rVSJyOAGwpTVG7\n" +
- "eZ5uulC0Lkm5/bzKFSrCf1jlAgMBAAGjUDBOMB0GA1UdDgQWBBTda66RZsgUvR4e\n" +
- "2RSsq65K1xcz0jAfBgNVHSMEGDAWgBTda66RZsgUvR4e2RSsq65K1xcz0jAMBgNV\n" +
- "HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EAZWYgoNDn6yEzcmWgsYnG3w2BT6fL\n" +
- "Npi0+APKWkwxnEJk1kgpdeSTMgaHAphQ8qksHnSgeBAJSs2ZCQMinVPgOg==\n" +
- "-----END CERTIFICATE-----";
-
- public void testMD5() throws Exception {
- assertBad(MD5_PEM, "Weak hash check did not fail as expected");
- }
-
- public void test512() throws Exception {
- assertBad(SHORT_PEM, "Short modulus check did not fail as expected");
- }
-
- public void testGoodChain() throws Exception {
- assertGood(GOOD_PEM);
- }
-
- private static void assertBad(String pem, String msg) throws Exception {
- try {
- check(createCert(pem));
- fail(msg);
- } catch (CertificateException expected) {
- }
- }
-
- private static void assertGood(String pem) throws Exception {
- check(createCert(pem));
- }
-
- private static void check(X509Certificate cert) throws Exception {
- X509Certificate[] chain = {cert};
- ChainStrengthAnalyzer.check(chain);
- }
-
- private static X509Certificate createCert(String pem) throws Exception {
- CertificateFactory cf = CertificateFactory.getInstance("X509");
- InputStream pemInput = new ByteArrayInputStream(pem.getBytes());
- return (X509Certificate) cf.generateCertificate(pemInput);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/CipherSuiteTest.java b/crypto/src/test/java/org/conscrypt/CipherSuiteTest.java
deleted file mode 100644
index 3255de8..0000000
--- a/crypto/src/test/java/org/conscrypt/CipherSuiteTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-
-public class CipherSuiteTest extends TestCase {
- public void test_getByName() throws Exception {
- for (String name : StandardNames.CIPHER_SUITES) {
- if (name.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)
- || name.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
- assertNull(CipherSuite.getByName(name));
- } else {
- test_CipherSuite(name);
- }
- }
-
- assertNull(CipherSuite.getByName("bogus"));
- try {
- CipherSuite.getByName(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- private void test_CipherSuite(String name) throws Exception {
- CipherSuite cs = CipherSuite.getByName(name);
- assertNotNull(name, cs);
- assertEquals(name, cs.getName());
- test_CipherSuite(cs);
- }
-
- private void test_CipherSuite(CipherSuite cs) throws Exception {
- assertNotNull(cs);
-
- String name = cs.getName();
- assertNotNull(name);
- assertSame(name, cs, CipherSuite.getByName(name));
- assertTrue(name, StandardNames.CIPHER_SUITES.contains(name));
- assertTrue(name, name.startsWith("SSL_") || name.startsWith("TLS_"));
-
- assertEquals(cs.isAnonymous(), name.contains("_anon_"));
-
- byte[] bytes = cs.toBytes();
- assertNotNull(name, bytes);
- assertEquals(name, 2, bytes.length);
- assertTrue(name + bytes[0], bytes[0] == (byte) 0x00 || bytes[0] == (byte) 0xc0);
- assertSame(name, cs, CipherSuite.getByCode(bytes[0], bytes[1]));
- assertSame(name, cs, CipherSuite.getByCode((byte) 0, bytes[0], bytes[1]));
-
- assertTrue(name, cs.toString().contains(name));
-
- String bulkEncryptionAlgorithm = cs.getBulkEncryptionAlgorithm();
- int blockSize = cs.getBlockSize();
- if (bulkEncryptionAlgorithm == null) {
- assertTrue(name, name.contains("_NULL_"));
- assertEquals(name, 0, blockSize);
- } else {
- assertNotNull(name, Cipher.getInstance(cs.getBulkEncryptionAlgorithm()));
- assertTrue(name, blockSize == 0 || blockSize == 8 || blockSize == 16);
- }
-
- String hmacName = cs.getHmacName();
- assertNotNull(name, hmacName);
- assertNotNull(name, Mac.getInstance(hmacName));
-
- String hashName = cs.getHashName();
- assertNotNull(name, hashName);
- assertNotNull(name, MessageDigest.getInstance(hashName));
-
- int macLength = cs.getMACLength();
- assertTrue(name, macLength == 0 || macLength == 16 || macLength == 20);
-
- assertTrue(name,
- cs.isExportable() == name.contains("_EXPORT_")
- || cs.isExportable() == name.contains("_NULL_"));
-
- String keyType = cs.getServerKeyType();
- assertEquals(name, cs.isAnonymous(), keyType == null);
- assertTrue(name, keyType == null || StandardNames.KEY_TYPES.contains(keyType));
- }
-
- public void test_getByCode() {
- // CipherSuite.getByCode is also covered by test_CipherSuite
- assertUnknown(CipherSuite.getByCode((byte) 0x12, (byte) 0x34));
- assertUnknown(CipherSuite.getByCode((byte) 0x12, (byte) 0x34, (byte) 0x56));
- assertUnknown(CipherSuite.getByCode((byte) -1, (byte) -1));
- assertUnknown(CipherSuite.getByCode((byte) -1, (byte) -1, (byte) -1));
- }
- private void assertUnknown(CipherSuite cs) {
- assertNotNull(cs);
- assertNotNull(cs.getName().contains("UNKNOWN"));
- }
-
- public void test_getSupported() throws Exception {
- CipherSuite[] suites = CipherSuite.getSupported();
- List<String> names = new ArrayList<String>(suites.length);
- for (CipherSuite cs : suites) {
- test_CipherSuite(cs);
- names.add(cs.getName());
- }
- assertEquals(Arrays.asList(CipherSuite.getSupportedCipherSuiteNames()), names);
- }
-
- public void test_getSupportedCipherSuiteNames() throws Exception {
- String[] names = CipherSuite.getSupportedCipherSuiteNames();
- StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES_SSLENGINE, names);
- for (String name : names) {
- test_CipherSuite(name);
- }
- }
-
- public void test_getClientKeyType() throws Exception {
- byte b = Byte.MIN_VALUE;
- do {
- String byteString = Byte.toString(b);
- String keyType = CipherSuite.getClientKeyType(b);
- switch (b) {
- case 1:
- assertEquals(byteString, "RSA", keyType);
- break;
- case 2:
- assertEquals(byteString, "DSA", keyType);
- break;
- case 3:
- assertEquals(byteString, "DH_RSA", keyType);
- break;
- case 4:
- assertEquals(byteString, "DH_DSA", keyType);
- break;
- case 64:
- assertEquals(byteString, "EC", keyType);
- break;
- case 65:
- assertEquals(byteString, "EC_RSA", keyType);
- break;
- case 66:
- assertEquals(byteString, "EC_EC", keyType);
- break;
- default:
- assertNull(byteString, keyType);
- }
- b++;
- } while (b != Byte.MIN_VALUE);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/ClientSessionContextTest.java b/crypto/src/test/java/org/conscrypt/ClientSessionContextTest.java
deleted file mode 100644
index 93037db..0000000
--- a/crypto/src/test/java/org/conscrypt/ClientSessionContextTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-import javax.net.ssl.SSLSession;
-import junit.framework.TestCase;
-import libcore.javax.net.ssl.FakeSSLSession;
-
-public final class ClientSessionContextTest extends TestCase {
-
- public void testSimpleAddition() {
- ClientSessionContext context = new ClientSessionContext();
- SSLSession a = new ValidSSLSession("a");
- SSLSession b = new ValidSSLSession("b");
-
- context.putSession(a);
- assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b });
-
- context.putSession(b);
- assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[0]);
- }
-
- public void testTrimToSize() {
- ClientSessionContext context = new ClientSessionContext();
- ValidSSLSession a = new ValidSSLSession("a");
- ValidSSLSession b = new ValidSSLSession("b");
- ValidSSLSession c = new ValidSSLSession("c");
- ValidSSLSession d = new ValidSSLSession("d");
-
- context.putSession(a);
- assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b, c, d });
-
- context.putSession(b);
- assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[] { c, d });
-
- context.putSession(c);
- assertSessionContextContents(context, new SSLSession[] { a, b, c }, new SSLSession[] { d });
-
- context.putSession(d);
- assertSessionContextContents(context, new SSLSession[] { a, b, c, d }, new SSLSession[0]);
-
- context.setSessionCacheSize(2);
- assertSessionContextContents(context, new SSLSession[] { c, d }, new SSLSession[] { a, b });
- }
-
- public void testImplicitRemovalOfOldest() {
- ClientSessionContext context = new ClientSessionContext();
- context.setSessionCacheSize(2);
- ValidSSLSession a = new ValidSSLSession("a");
- ValidSSLSession b = new ValidSSLSession("b");
- ValidSSLSession c = new ValidSSLSession("c");
- ValidSSLSession d = new ValidSSLSession("d");
-
- context.putSession(a);
- assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b, c, d });
-
- context.putSession(b);
- assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[] { c, d });
-
- context.putSession(c);
- assertSessionContextContents(context, new SSLSession[] { b, c }, new SSLSession[] { a, d });
-
- context.putSession(d);
- assertSessionContextContents(context, new SSLSession[] { c, d }, new SSLSession[] { a, b });
- }
-
- private static void assertSessionContextContents(ClientSessionContext context,
- SSLSession[] contains,
- SSLSession[] exludes) {
- assertEquals(contains.length, context.size());
-
- for (SSLSession s : contains) {
- assertSame(s.getPeerHost(), s, context.getSession(s.getId()));
- assertSame(s.getPeerHost(), s, context.getSession(s.getPeerHost(), 443));
- }
- for (SSLSession s : exludes) {
- assertNull(s.getPeerHost(), context.getSession(s.getId()));
- assertNull(s.getPeerHost(), context.getSession(s.getPeerHost(), 443));
- }
-
- Set<SSLSession> sessions = new HashSet<SSLSession>();
- Enumeration<byte[]> ids = context.getIds();
- while (ids.hasMoreElements()) {
- byte[] id = ids.nextElement();
- sessions.add(context.getSession(id));
- }
-
- Set<SSLSession> expected = new HashSet<SSLSession>();
- for (SSLSession s : sessions) {
- expected.add(s);
- }
- assertEquals(expected, sessions);
- }
-
- static class ValidSSLSession extends FakeSSLSession {
- ValidSSLSession(String host) {
- super(host);
- }
- @Override public boolean isValid() {
- return true;
- }
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/FileClientSessionCacheTest.java b/crypto/src/test/java/org/conscrypt/FileClientSessionCacheTest.java
deleted file mode 100644
index 9d7e2ec..0000000
--- a/crypto/src/test/java/org/conscrypt/FileClientSessionCacheTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.IOException;
-import junit.framework.TestCase;
-import libcore.javax.net.ssl.FakeSSLSession;
-
-public class FileClientSessionCacheTest extends TestCase {
-
- public void testMaxSize() throws IOException, InterruptedException {
- String tmpDir = System.getProperty("java.io.tmpdir");
- if (tmpDir == null) {
- fail("Please set 'java.io.tmpdir' system property.");
- }
- File cacheDir = new File(tmpDir
- + "/" + FileClientSessionCacheTest.class.getName() + "/cache");
- final SSLClientSessionCache cache
- = FileClientSessionCache.usingDirectory(cacheDir);
- Thread[] threads = new Thread[10];
- final int iterations = FileClientSessionCache.MAX_SIZE * 10;
- for (int i = 0; i < threads.length; i++) {
- final int id = i;
- threads[i] = new Thread() {
- @Override
- public void run() {
- for (int i = 0; i < iterations; i++) {
- cache.putSessionData(new FakeSSLSession(id + "" + i), new byte[10]);
- }
- }
- };
- }
- for (Thread thread : threads) {
- thread.start();
- }
- for (Thread thread : threads) {
- thread.join();
- }
- assertEquals(FileClientSessionCache.MAX_SIZE, cacheDir.list().length);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/MacTest.java b/crypto/src/test/java/org/conscrypt/MacTest.java
deleted file mode 100644
index 304ecdb..0000000
--- a/crypto/src/test/java/org/conscrypt/MacTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import junit.framework.TestCase;
-
-public class MacTest extends TestCase {
- public void test_getInstance_OpenSSL_ENGINE() throws Exception {
- final String secret = "-HMAC-test1";
- final byte[] testString = "testing123".getBytes();
-
- Provider p = Security.getProvider(OpenSSLProvider.PROVIDER_NAME);
- NativeCryptoTest.loadTestEngine();
- OpenSSLEngine engine = OpenSSLEngine.getInstance(NativeCryptoTest.TEST_ENGINE_ID);
-
- /*
- * The "-HMAC-" prefix is a special prefix recognized by
- * test_openssl_engine.cpp
- */
- SecretKey key1 = engine.getSecretKeyById(secret, "HmacSHA256");
- SecretKey key1dupe = engine.getSecretKeyById(secret, "HmacSHA256");
-
- /* Non-ENGINE-based SecretKey */
- SecretKey key2 = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
-
- /* The one that is ENGINE-based can't be equal to a non-ENGINE one. */
- assertFalse(key1.equals(key2));
- assertEquals(key1, key1dupe);
- assertNull(key1.getFormat());
- assertNull(key1.getEncoded());
- assertEquals("RAW", key2.getFormat());
- assertEquals(Arrays.toString(secret.getBytes()), Arrays.toString(key2.getEncoded()));
-
- Mac mac1 = Mac.getInstance("HmacSHA256", p);
- mac1.init(key1);
- mac1.update(testString);
- byte[] output1 = mac1.doFinal();
- assertEquals(mac1.getMacLength(), output1.length);
-
- Mac mac2 = Mac.getInstance("HmacSHA256", p);
- mac2.init(key2);
- mac2.update(testString);
- byte[] output2 = mac2.doFinal();
-
- assertEquals(Arrays.toString(output2), Arrays.toString(output1));
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/NativeCryptoTest.java b/crypto/src/test/java/org/conscrypt/NativeCryptoTest.java
deleted file mode 100644
index ca5f498..0000000
--- a/crypto/src/test/java/org/conscrypt/NativeCryptoTest.java
+++ /dev/null
@@ -1,2629 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import dalvik.system.BaseDexClassLoader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketTimeoutException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECPrivateKeySpec;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLProtocolException;
-import javax.security.auth.x500.X500Principal;
-import junit.framework.TestCase;
-import libcore.io.IoUtils;
-import libcore.java.security.StandardNames;
-import libcore.java.security.TestKeyStore;
-import org.conscrypt.NativeCrypto.SSLHandshakeCallbacks;
-import static org.conscrypt.NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH;
-
-public class NativeCryptoTest extends TestCase {
- /** Corresponds to the native test library "libjavacoretests.so" */
- public static final String TEST_ENGINE_ID = "javacoretests";
-
- private static final long NULL = 0;
- private static final FileDescriptor INVALID_FD = new FileDescriptor();
- private static final SSLHandshakeCallbacks DUMMY_CB
- = new TestSSLHandshakeCallbacks(null, 0, null);
-
- private static final long TIMEOUT_SECONDS = 5;
-
- private static OpenSSLKey SERVER_PRIVATE_KEY;
- private static byte[][] SERVER_CERTIFICATES;
- private static OpenSSLKey CLIENT_PRIVATE_KEY;
- private static byte[][] CLIENT_CERTIFICATES;
- private static byte[][] CA_PRINCIPALS;
- private static OpenSSLKey CHANNEL_ID_PRIVATE_KEY;
- private static byte[] CHANNEL_ID;
-
- @Override
- protected void tearDown() throws Exception {
- assertEquals(0, NativeCrypto.ERR_peek_last_error());
- }
-
- private static OpenSSLKey getServerPrivateKey() {
- initCerts();
- return SERVER_PRIVATE_KEY;
- }
-
- private static byte[][] getServerCertificates() {
- initCerts();
- return SERVER_CERTIFICATES;
- }
-
- private static OpenSSLKey getClientPrivateKey() {
- initCerts();
- return CLIENT_PRIVATE_KEY;
- }
-
- private static byte[][] getClientCertificates() {
- initCerts();
- return CLIENT_CERTIFICATES;
- }
-
- private static byte[][] getCaPrincipals() {
- initCerts();
- return CA_PRINCIPALS;
- }
-
- /**
- * Lazily create shared test certificates.
- */
- private static synchronized void initCerts() {
- if (SERVER_PRIVATE_KEY != null) {
- return;
- }
-
- try {
- PrivateKeyEntry serverPrivateKeyEntry
- = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- SERVER_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(serverPrivateKeyEntry.getPrivateKey());
- SERVER_CERTIFICATES = NativeCrypto.encodeCertificates(
- serverPrivateKeyEntry.getCertificateChain());
-
- PrivateKeyEntry clientPrivateKeyEntry
- = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
- CLIENT_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(clientPrivateKeyEntry.getPrivateKey());
- CLIENT_CERTIFICATES = NativeCrypto.encodeCertificates(
- clientPrivateKeyEntry.getCertificateChain());
-
- KeyStore ks = TestKeyStore.getClient().keyStore;
- String caCertAlias = ks.aliases().nextElement();
- X509Certificate certificate = (X509Certificate) ks.getCertificate(caCertAlias);
- X500Principal principal = certificate.getIssuerX500Principal();
- CA_PRINCIPALS = new byte[][] { principal.getEncoded() };
- initChannelIdKey();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private static synchronized void initChannelIdKey() throws Exception {
- if (CHANNEL_ID_PRIVATE_KEY != null) {
- return;
- }
-
- // NIST P-256 aka SECG secp256r1 aka X9.62 prime256v1
- OpenSSLECGroupContext openSslSpec = OpenSSLECGroupContext.getCurveByName("prime256v1");
- BigInteger s = new BigInteger(
- "229cdbbf489aea584828a261a23f9ff8b0f66f7ccac98bf2096ab3aee41497c5", 16);
- CHANNEL_ID_PRIVATE_KEY = new OpenSSLECPrivateKey(
- new ECPrivateKeySpec(s, openSslSpec.getECParameterSpec())).getOpenSSLKey();
-
- // Channel ID is the concatenation of the X and Y coordinates of the public key.
- CHANNEL_ID = new BigInteger(
- "702b07871fd7955c320b26f15e244e47eed60272124c92b9ebecf0b42f90069b" +
- "ab53592ebfeb4f167dbf3ce61513afb0e354c479b1c1b69874fa471293494f77",
- 16).toByteArray();
- }
-
- public static void assertEqualSessions(long expected, long actual) {
- assertEqualByteArrays(NativeCrypto.SSL_SESSION_session_id(expected),
- NativeCrypto.SSL_SESSION_session_id(actual));
- }
- public static void assertEqualByteArrays(byte[] expected, byte[] actual) {
- assertEquals(Arrays.toString(expected), Arrays.toString(actual));
- }
-
- public static void assertEqualPrincipals(byte[][] expected, byte[][] actual) {
- assertEqualByteArrays(expected, actual);
- }
- public static void assertEqualCertificateChains(byte[][] expected, byte[][] actual) {
- assertEqualByteArrays(expected, actual);
- }
- public static void assertEqualByteArrays(byte[][] expected, byte[][] actual) {
- assertEquals(Arrays.deepToString(expected), Arrays.deepToString(actual));
- }
-
- public void test_EVP_PKEY_cmp() throws Exception {
- try {
- NativeCrypto.EVP_PKEY_cmp(NULL, NULL);
- fail("Should throw NullPointerException when arguments are NULL");
- } catch (NullPointerException expected) {
- }
-
- KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
- kpg.initialize(512);
-
- KeyPair kp1 = kpg.generateKeyPair();
- RSAPrivateCrtKey privKey1 = (RSAPrivateCrtKey) kp1.getPrivate();
-
- KeyPair kp2 = kpg.generateKeyPair();
- RSAPrivateCrtKey privKey2 = (RSAPrivateCrtKey) kp2.getPrivate();
-
- long pkey1 = 0, pkey1_copy = 0, pkey2 = 0;
- try {
- pkey1 = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
- privKey1.getPublicExponent().toByteArray(),
- privKey1.getPrivateExponent().toByteArray(),
- privKey1.getPrimeP().toByteArray(),
- privKey1.getPrimeQ().toByteArray(),
- privKey1.getPrimeExponentP().toByteArray(),
- privKey1.getPrimeExponentQ().toByteArray(),
- privKey1.getCrtCoefficient().toByteArray());
- assertNotSame(NULL, pkey1);
-
- pkey1_copy = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
- privKey1.getPublicExponent().toByteArray(),
- privKey1.getPrivateExponent().toByteArray(),
- privKey1.getPrimeP().toByteArray(),
- privKey1.getPrimeQ().toByteArray(),
- privKey1.getPrimeExponentP().toByteArray(),
- privKey1.getPrimeExponentQ().toByteArray(),
- privKey1.getCrtCoefficient().toByteArray());
- assertNotSame(NULL, pkey1_copy);
-
- pkey2 = NativeCrypto.EVP_PKEY_new_RSA(privKey2.getModulus().toByteArray(),
- privKey2.getPublicExponent().toByteArray(),
- privKey2.getPrivateExponent().toByteArray(),
- privKey2.getPrimeP().toByteArray(),
- privKey2.getPrimeQ().toByteArray(),
- privKey2.getPrimeExponentP().toByteArray(),
- privKey2.getPrimeExponentQ().toByteArray(),
- privKey2.getCrtCoefficient().toByteArray());
- assertNotSame(NULL, pkey2);
-
- try {
- NativeCrypto.EVP_PKEY_cmp(pkey1, NULL);
- fail("Should throw NullPointerException when arguments are NULL");
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.EVP_PKEY_cmp(NULL, pkey1);
- fail("Should throw NullPointerException when arguments are NULL");
- } catch (NullPointerException expected) {
- }
-
- assertEquals("Same keys should be the equal", 1,
- NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1));
-
- assertEquals("Same keys should be the equal", 1,
- NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1_copy));
-
- assertEquals("Different keys should not be equal", 0,
- NativeCrypto.EVP_PKEY_cmp(pkey1, pkey2));
- } finally {
- if (pkey1 != 0) {
- NativeCrypto.EVP_PKEY_free(pkey1);
- }
- if (pkey1_copy != 0) {
- NativeCrypto.EVP_PKEY_free(pkey1_copy);
- }
- if (pkey2 != 0) {
- NativeCrypto.EVP_PKEY_free(pkey2);
- }
- }
- }
-
- public void test_SSL_CTX_new() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- assertTrue(c != NULL);
- long c2 = NativeCrypto.SSL_CTX_new();
- assertTrue(c != c2);
- NativeCrypto.SSL_CTX_free(c);
- NativeCrypto.SSL_CTX_free(c2);
- }
-
- public void test_SSL_CTX_free() throws Exception {
- try {
- NativeCrypto.SSL_CTX_free(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_CTX_free(NativeCrypto.SSL_CTX_new());
- }
-
- public void test_SSL_CTX_set_session_id_context() throws Exception {
- byte[] empty = new byte[0];
- try {
- NativeCrypto.SSL_CTX_set_session_id_context(NULL, empty);
- fail();
- } catch (NullPointerException expected) {
- }
- long c = NativeCrypto.SSL_CTX_new();
- try {
- NativeCrypto.SSL_CTX_set_session_id_context(c, null);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_CTX_set_session_id_context(c, empty);
- NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[32]);
- try {
- NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[33]);
- } catch (IllegalArgumentException expected) {
- }
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_new() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- assertTrue(s != NULL);
- assertTrue((NativeCrypto.SSL_get_options(s) & 0x01000000L) != 0); // SSL_OP_NO_SSLv2
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1) == 0);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_1) == 0);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_2) == 0);
-
- long s2 = NativeCrypto.SSL_new(c);
- assertTrue(s != s2);
- NativeCrypto.SSL_free(s2);
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_use_certificate() throws Exception {
- try {
- NativeCrypto.SSL_use_certificate(NULL, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_use_certificate(s, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_use_certificate(s, getServerCertificates());
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_use_PrivateKey_for_tls_channel_id() throws Exception {
- initChannelIdKey();
-
- try {
- NativeCrypto.SSL_set1_tls_channel_id(NULL, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_set1_tls_channel_id(s, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Use the key natively. This works because the initChannelIdKey method ensures that the
- // key is backed by OpenSSL.
- NativeCrypto.SSL_set1_tls_channel_id(s, CHANNEL_ID_PRIVATE_KEY.getPkeyContext());
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_use_PrivateKey() throws Exception {
- try {
- NativeCrypto.SSL_use_PrivateKey(NULL, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_use_PrivateKey(s, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getPkeyContext());
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_check_private_key_null() throws Exception {
- try {
- NativeCrypto.SSL_check_private_key(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_SSL_check_private_key_no_key_no_cert() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- // neither private or certificate set
- try {
- NativeCrypto.SSL_check_private_key(s);
- fail();
- } catch (SSLException expected) {
- }
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_check_private_key_cert_then_key() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- // first certificate, then private
- NativeCrypto.SSL_use_certificate(s, getServerCertificates());
-
- try {
- NativeCrypto.SSL_check_private_key(s);
- fail();
- } catch (SSLException expected) {
- }
-
- NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getPkeyContext());
- NativeCrypto.SSL_check_private_key(s);
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
- public void test_SSL_check_private_key_key_then_cert() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- // first private, then certificate
- NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getPkeyContext());
-
- try {
- NativeCrypto.SSL_check_private_key(s);
- fail();
- } catch (SSLException expected) {
- }
-
- NativeCrypto.SSL_use_certificate(s, getServerCertificates());
- NativeCrypto.SSL_check_private_key(s);
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_get_mode() throws Exception {
- try {
- NativeCrypto.SSL_get_mode(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertTrue(NativeCrypto.SSL_get_mode(s) != 0);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_set_mode_and_clear_mode() throws Exception {
- try {
- NativeCrypto.SSL_set_mode(NULL, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- // check SSL_MODE_HANDSHAKE_CUTTHROUGH off by default
- assertEquals(0, NativeCrypto.SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
- // set SSL_MODE_HANDSHAKE_CUTTHROUGH on
- NativeCrypto.SSL_set_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
- assertTrue((NativeCrypto.SSL_get_mode(s)
- & SSL_MODE_HANDSHAKE_CUTTHROUGH) != 0);
- // clear SSL_MODE_HANDSHAKE_CUTTHROUGH off
- NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
- assertTrue((NativeCrypto.SSL_get_mode(s)
- & SSL_MODE_HANDSHAKE_CUTTHROUGH) == 0);
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_get_options() throws Exception {
- try {
- NativeCrypto.SSL_get_options(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertTrue(NativeCrypto.SSL_get_options(s) != 0);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_set_options() throws Exception {
- try {
- NativeCrypto.SSL_set_options(NULL, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
- NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_clear_options() throws Exception {
- try {
- NativeCrypto.SSL_clear_options(NULL, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
- NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0);
- NativeCrypto.SSL_clear_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_set_cipher_lists() throws Exception {
- try {
- NativeCrypto.SSL_set_cipher_lists(NULL, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_set_cipher_lists(s, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_set_cipher_lists(s, new String[] {});
-
- try {
- NativeCrypto.SSL_set_cipher_lists(s, new String[] { null });
- fail();
- } catch (NullPointerException expected) {
- }
-
- // see OpenSSL ciphers man page
- String[] illegals = new String[] {
- // empty
- "",
- // never standardized
- "EXP1024-DES-CBC-SHA", "EXP1024-RC4-SHA", "DHE-DSS-RC4-SHA",
- // IDEA
- "IDEA-CBC-SHA", "IDEA-CBC-MD5"
- };
-
- for (String illegal : illegals) {
- try {
- NativeCrypto.SSL_set_cipher_lists(s, new String[] { illegal });
- fail(illegal);
- } catch (IllegalArgumentException expected) {
- }
- }
-
- List<String> ciphers
- = new ArrayList<String>(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.keySet());
- NativeCrypto.SSL_set_cipher_lists(s, ciphers.toArray(new String[ciphers.size()]));
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_set_verify() throws Exception {
- try {
- NativeCrypto.SSL_set_verify(NULL, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_NONE);
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
- NativeCrypto.SSL_set_verify(s, (NativeCrypto.SSL_VERIFY_PEER
- | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT));
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- private static final boolean DEBUG = false;
-
- public static class Hooks {
- private OpenSSLKey channelIdPrivateKey;
-
- public long getContext() throws SSLException {
- return NativeCrypto.SSL_CTX_new();
- }
- public long beforeHandshake(long context) throws SSLException {
- long s = NativeCrypto.SSL_new(context);
- // without this SSL_set_cipher_lists call the tests were
- // negotiating DHE-RSA-AES256-SHA by default which had
- // very slow ephemeral RSA key generation
- NativeCrypto.SSL_set_cipher_lists(s, new String[] { "RC4-MD5" });
-
- if (channelIdPrivateKey != null) {
- NativeCrypto.SSL_set1_tls_channel_id(s, channelIdPrivateKey.getPkeyContext());
- }
- return s;
- }
- public void clientCertificateRequested(long s) {}
- public void afterHandshake(long session, long ssl, long context,
- Socket socket, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- if (session != NULL) {
- NativeCrypto.SSL_SESSION_free(session);
- }
- if (ssl != NULL) {
- try {
- NativeCrypto.SSL_shutdown(ssl, fd, callback);
- } catch (IOException e) {
- }
- NativeCrypto.SSL_free(ssl);
- }
- if (context != NULL) {
- NativeCrypto.SSL_CTX_free(context);
- }
- if (socket != null) {
- socket.close();
- }
- }
- }
-
- public static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks {
- private final Socket socket;
- private final long sslNativePointer;
- private final Hooks hooks;
-
- public TestSSLHandshakeCallbacks(Socket socket,
- long sslNativePointer,
- Hooks hooks) {
- this.socket = socket;
- this.sslNativePointer = sslNativePointer;
- this.hooks = hooks;
- }
-
- public byte[][] asn1DerEncodedCertificateChain;
- public String authMethod;
- public boolean verifyCertificateChainCalled;
-
- public void verifyCertificateChain(byte[][] asn1DerEncodedCertificateChain,
- String authMethod)
- throws CertificateException {
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
- + " verifyCertificateChain"
- + " asn1DerEncodedCertificateChain="
- + asn1DerEncodedCertificateChain
- + " authMethod=" + authMethod);
- }
- this.asn1DerEncodedCertificateChain = asn1DerEncodedCertificateChain;
- this.authMethod = authMethod;
- this.verifyCertificateChainCalled = true;
- }
-
- public byte[] keyTypes;
- public byte[][] asn1DerEncodedX500Principals;
- public boolean clientCertificateRequestedCalled;
- public void clientCertificateRequested(byte[] keyTypes,
- byte[][] asn1DerEncodedX500Principals) {
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
- + " clientCertificateRequested"
- + " keyTypes=" + keyTypes
- + " asn1DerEncodedX500Principals="
- + asn1DerEncodedX500Principals);
- }
- this.keyTypes = keyTypes;
- this.asn1DerEncodedX500Principals = asn1DerEncodedX500Principals;
- this.clientCertificateRequestedCalled = true;
- if (hooks != null ) {
- hooks.clientCertificateRequested(sslNativePointer);
- }
- }
-
- public boolean handshakeCompletedCalled;
- public void handshakeCompleted() {
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
- + " handshakeCompleted");
- }
- this.handshakeCompletedCalled = true;
- }
-
- public Socket getSocket() {
- return socket;
- }
- }
-
- public static class ServerHooks extends Hooks {
- private final OpenSSLKey privateKey;
- private final byte[][] certificates;
- private boolean channelIdEnabled;
- private byte[] channelIdAfterHandshake;
- private Throwable channelIdAfterHandshakeException;
-
- public ServerHooks(OpenSSLKey privateKey, byte[][] certificates) {
- this.privateKey = privateKey;
- this.certificates = certificates;
- }
-
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- if (privateKey != null) {
- NativeCrypto.SSL_use_PrivateKey(s, privateKey.getPkeyContext());
- }
- if (certificates != null) {
- NativeCrypto.SSL_use_certificate(s, certificates);
- }
- if (channelIdEnabled) {
- NativeCrypto.SSL_enable_tls_channel_id(s);
- }
- return s;
- }
-
- @Override
- public void afterHandshake(long session, long ssl, long context,
- Socket socket, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- if (channelIdEnabled) {
- try {
- channelIdAfterHandshake = NativeCrypto.SSL_get_tls_channel_id(ssl);
- } catch (Exception e) {
- channelIdAfterHandshakeException = e;
- }
- }
- super.afterHandshake(session, ssl, context, socket, fd, callback);
- }
-
- public void clientCertificateRequested(long s) {
- fail("Server asked for client certificates");
- }
- }
-
- public static Future<TestSSLHandshakeCallbacks> handshake(final ServerSocket listener,
- final int timeout, final boolean client, final Hooks hooks, final byte[] npnProtocols,
- final byte[] alpnProtocols) {
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<TestSSLHandshakeCallbacks> future = executor.submit(
- new Callable<TestSSLHandshakeCallbacks>() {
- @Override public TestSSLHandshakeCallbacks call() throws Exception {
- Socket socket = (client
- ? new Socket(listener.getInetAddress(),
- listener.getLocalPort())
- : listener.accept());
- if (timeout == -1) {
- return new TestSSLHandshakeCallbacks(socket, 0, null);
- }
- FileDescriptor fd = socket.getFileDescriptor$();
- long c = hooks.getContext();
- long s = hooks.beforeHandshake(c);
- TestSSLHandshakeCallbacks callback
- = new TestSSLHandshakeCallbacks(socket, s, hooks);
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(s, 16)
- + " handshake"
- + " context=0x" + Long.toString(c, 16)
- + " socket=" + socket
- + " fd=" + fd
- + " timeout=" + timeout
- + " client=" + client);
- }
- long session = NULL;
- try {
- session = NativeCrypto.SSL_do_handshake(s, fd, callback, timeout, client,
- npnProtocols, alpnProtocols);
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(s, 16)
- + " handshake"
- + " session=0x" + Long.toString(session, 16));
- }
- } finally {
- // Ensure afterHandshake is called to free resources
- hooks.afterHandshake(session, s, c, socket, fd, callback);
- }
- return callback;
- }
- });
- executor.shutdown();
- return future;
- }
-
- public void test_SSL_do_handshake_NULL_SSL() throws Exception {
- try {
- NativeCrypto.SSL_do_handshake(NULL, null, null, 0, false, null, null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_SSL_do_handshake_null_args() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_do_handshake(s, null, null, 0, true, null, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.SSL_do_handshake(s, INVALID_FD, null, 0, true, null, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_do_handshake_normal() throws Exception {
- // normal client and server case
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertFalse(serverCallback.verifyCertificateChainCalled);
- assertFalse(clientCallback.clientCertificateRequestedCalled);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- }
-
- public void test_SSL_do_handshake_optional_client_certificate() throws Exception {
- // optional client certificate case
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void clientCertificateRequested(long s) {
- super.clientCertificateRequested(s);
- NativeCrypto.SSL_use_PrivateKey(s, getClientPrivateKey().getPkeyContext());
- NativeCrypto.SSL_use_certificate(s, getClientCertificates());
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals());
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
- return s;
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertTrue(serverCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getClientCertificates(),
- serverCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", serverCallback.authMethod);
-
- assertTrue(clientCallback.clientCertificateRequestedCalled);
- assertNotNull(clientCallback.keyTypes);
- // this depends on the SSL_set_cipher_lists call in beforeHandshake
- // the three returned are the non-ephemeral cases.
- assertEquals(3, clientCallback.keyTypes.length);
- assertEquals("RSA", CipherSuite.getClientKeyType(clientCallback.keyTypes[0]));
- assertEquals("DSA", CipherSuite.getClientKeyType(clientCallback.keyTypes[1]));
- assertEquals("EC", CipherSuite.getClientKeyType(clientCallback.keyTypes[2]));
- assertEqualPrincipals(getCaPrincipals(),
- clientCallback.asn1DerEncodedX500Principals);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
-
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- }
-
- public void test_SSL_do_handshake_missing_required_certificate() throws Exception {
- // required client certificate negative case
- final ServerSocket listener = new ServerSocket(0);
- try {
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals());
- NativeCrypto.SSL_set_verify(s,
- NativeCrypto.SSL_VERIFY_PEER
- | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
- return s;
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SSLProtocolException.class, expected.getCause().getClass());
- }
- }
-
- /**
- * Usually if a RuntimeException is thrown by the
- * clientCertificateRequestedCalled callback, the caller sees it
- * during the call to NativeCrypto_SSL_do_handshake. However, IIS
- * does not request client certs until after the initial
- * handshake. It does an SSL renegotiation, which means we need to
- * be able to deliver the callback's exception in cases like
- * SSL_read, SSL_write, and SSL_shutdown.
- */
- public void test_SSL_do_handshake_clientCertificateRequested_throws_after_renegotiate()
- throws Exception {
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public long beforeHandshake(long context) throws SSLException {
- long s = super.beforeHandshake(context);
- NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
- return s;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
- fail();
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- @Override
- public void clientCertificateRequested(long s) {
- super.clientCertificateRequested(s);
- throw new RuntimeException("expected");
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- try {
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
- NativeCrypto.SSL_set_options(
- s, NativeCrypto.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
- NativeCrypto.SSL_renegotiate(s);
- NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1,
- (int) ((TIMEOUT_SECONDS * 1000) / 2));
- } catch (IOException expected) {
- } finally {
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- try {
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- } catch (ExecutionException e) {
- if (!"expected".equals(e.getCause().getMessage())) {
- throw e;
- }
- }
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_do_handshake_client_timeout() throws Exception {
- // client timeout
- final ServerSocket listener = new ServerSocket(0);
- Socket serverSocket = null;
- try {
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 1, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, -1, false, sHooks, null,
- null);
- serverSocket = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- if (SocketTimeoutException.class != expected.getCause().getClass()) {
- expected.printStackTrace();
- }
- assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
- } finally {
- // Manually close peer socket when testing timeout
- IoUtils.closeQuietly(serverSocket);
- }
- }
-
- public void test_SSL_do_handshake_server_timeout() throws Exception {
- // server timeout
- final ServerSocket listener = new ServerSocket(0);
- Socket clientSocket = null;
- try {
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, -1, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 1, false, sHooks, null, null);
- clientSocket = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
- } finally {
- // Manually close peer socket when testing timeout
- IoUtils.closeQuietly(clientSocket);
- }
- }
-
- public void test_SSL_do_handshake_with_channel_id_normal() throws Exception {
- initChannelIdKey();
-
- // Normal handshake with TLS Channel ID.
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks();
- cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY;
- ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- sHooks.channelIdEnabled = true;
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertFalse(serverCallback.verifyCertificateChainCalled);
- assertFalse(clientCallback.clientCertificateRequestedCalled);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- assertNull(sHooks.channelIdAfterHandshakeException);
- assertEqualByteArrays(CHANNEL_ID, sHooks.channelIdAfterHandshake);
- }
-
- public void test_SSL_do_handshake_with_channel_id_not_supported_by_server() throws Exception {
- initChannelIdKey();
-
- // Client tries to use TLS Channel ID but the server does not enable/offer the extension.
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks();
- cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY;
- ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- sHooks.channelIdEnabled = false;
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertFalse(serverCallback.verifyCertificateChainCalled);
- assertFalse(clientCallback.clientCertificateRequestedCalled);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- assertNull(sHooks.channelIdAfterHandshakeException);
- assertNull(sHooks.channelIdAfterHandshake);
- }
-
- public void test_SSL_do_handshake_with_channel_id_not_enabled_by_client() throws Exception {
- initChannelIdKey();
-
- // Client does not use TLS Channel ID when the server has the extension enabled/offered.
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks();
- cHooks.channelIdPrivateKey = null;
- ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- sHooks.channelIdEnabled = true;
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertFalse(serverCallback.verifyCertificateChainCalled);
- assertFalse(clientCallback.clientCertificateRequestedCalled);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- assertNull(sHooks.channelIdAfterHandshakeException);
- assertNull(sHooks.channelIdAfterHandshake);
- }
-
- public void test_SSL_set_session() throws Exception {
- try {
- NativeCrypto.SSL_set_session(NULL, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- NativeCrypto.SSL_set_session(s, NULL);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- {
- final long clientContext = NativeCrypto.SSL_CTX_new();
- final long serverContext = NativeCrypto.SSL_CTX_new();
- final ServerSocket listener = new ServerSocket(0);
- final long[] clientSession = new long[] { NULL };
- final long[] serverSession = new long[] { NULL };
- {
- Hooks cHooks = new Hooks() {
- @Override
- public long getContext() throws SSLException {
- return clientContext;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- super.afterHandshake(NULL, s, NULL, sock, fd, callback);
- clientSession[0] = session;
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long getContext() throws SSLException {
- return serverContext;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- super.afterHandshake(NULL, s, NULL, sock, fd, callback);
- serverSession[0] = session;
- }
- };
- Future<TestSSLHandshakeCallbacks> client
- = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server
- = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
- assertEqualSessions(clientSession[0], serverSession[0]);
- {
- Hooks cHooks = new Hooks() {
- @Override
- public long getContext() throws SSLException {
- return clientContext;
- }
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = NativeCrypto.SSL_new(clientContext);
- NativeCrypto.SSL_set_session(s, clientSession[0]);
- return s;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertEqualSessions(clientSession[0], session);
- super.afterHandshake(NULL, s, NULL, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long getContext() throws SSLException {
- return serverContext;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertEqualSessions(serverSession[0], session);
- super.afterHandshake(NULL, s, NULL, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client
- = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server
- = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
- NativeCrypto.SSL_SESSION_free(clientSession[0]);
- NativeCrypto.SSL_SESSION_free(serverSession[0]);
- NativeCrypto.SSL_CTX_free(serverContext);
- NativeCrypto.SSL_CTX_free(clientContext);
- }
- }
-
- public void test_SSL_set_session_creation_enabled() throws Exception {
- try {
- NativeCrypto.SSL_set_session_creation_enabled(NULL, false);
- fail();
- } catch (NullPointerException expected) {
- }
-
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- NativeCrypto.SSL_set_session_creation_enabled(s, false);
- NativeCrypto.SSL_set_session_creation_enabled(s, true);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- // negative test case for SSL_set_session_creation_enabled(false) on client
- try {
- Hooks cHooks = new Hooks() {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_session_creation_enabled(s, false);
- return s;
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SSLProtocolException.class, expected.getCause().getClass());
- }
-
- // negative test case for SSL_set_session_creation_enabled(false) on server
- try {
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_session_creation_enabled(s, false);
- return s;
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SSLProtocolException.class, expected.getCause().getClass());
- }
- }
-
- public void test_SSL_set_tlsext_host_name() throws Exception {
- // NULL SSL
- try {
- NativeCrypto.SSL_set_tlsext_host_name(NULL, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final String hostname = "www.android.com";
-
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- // null hostname
- try {
- NativeCrypto.SSL_set_tlsext_host_name(s, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // too long hostname
- try {
- char[] longHostname = new char[256];
- Arrays.fill(longHostname, 'w');
- NativeCrypto.SSL_set_tlsext_host_name(s, new String(longHostname));
- fail();
- } catch (SSLException expected) {
- }
-
- assertNull(NativeCrypto.SSL_get_servername(s));
- NativeCrypto.SSL_set_tlsext_host_name(s, new String(hostname));
- assertEquals(hostname, NativeCrypto.SSL_get_servername(s));
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- // normal
- Hooks cHooks = new Hooks() {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_tlsext_host_name(s, hostname);
- return s;
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertEquals(hostname, NativeCrypto.SSL_get_servername(s));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_NpnNegotiateSuccess() throws Exception {
- final byte[] clientNpnProtocols = new byte[] {
- 8, 'h', 't', 't', 'p', '/', '1', '.', '1',
- 3, 'f', 'o', 'o',
- 6, 's', 'p', 'd', 'y', '/', '2',
- };
- final byte[] serverNpnProtocols = new byte[] {
- 6, 's', 'p', 'd', 'y', '/', '2',
- 3, 'f', 'o', 'o',
- 3, 'b', 'a', 'r',
- };
-
- Hooks cHooks = new Hooks() {
- @Override public long beforeHandshake(long context) throws SSLException {
- NativeCrypto.SSL_CTX_enable_npn(context);
- return super.beforeHandshake(context);
- }
- @Override public void afterHandshake(long session, long ssl, long context, Socket socket,
- FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
- byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl);
- assertEquals("spdy/2", new String(negotiated));
- assertTrue("NPN should enable cutthrough on the client",
- 0 != (NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH));
- super.afterHandshake(session, ssl, context, socket, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override public long beforeHandshake(long context) throws SSLException {
- NativeCrypto.SSL_CTX_enable_npn(context);
- return super.beforeHandshake(context);
- }
- @Override public void afterHandshake(long session, long ssl, long c, Socket sock,
- FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
- byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl);
- assertEquals("spdy/2", new String(negotiated));
- assertEquals("NPN should not enable cutthrough on the server",
- 0, NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
- super.afterHandshake(session, ssl, c, sock, fd, callback);
- }
- };
-
- ServerSocket listener = new ServerSocket(0);
- Future<TestSSLHandshakeCallbacks> client
- = handshake(listener, 0, true, cHooks, clientNpnProtocols, null);
- Future<TestSSLHandshakeCallbacks> server
- = handshake(listener, 0, false, sHooks, serverNpnProtocols, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_AlpnNegotiateSuccess() throws Exception {
- final byte[] clientAlpnProtocols = new byte[] {
- 8, 'h', 't', 't', 'p', '/', '1', '.', '1',
- 3, 'f', 'o', 'o',
- 6, 's', 'p', 'd', 'y', '/', '2',
- };
- final byte[] serverAlpnProtocols = new byte[] {
- 6, 's', 'p', 'd', 'y', '/', '2',
- 3, 'f', 'o', 'o',
- 3, 'b', 'a', 'r',
- };
-
- Hooks cHooks = new Hooks() {
- @Override public long beforeHandshake(long context) throws SSLException {
- NativeCrypto.SSL_CTX_set_alpn_protos(context, clientAlpnProtocols);
- return super.beforeHandshake(context);
- }
- @Override public void afterHandshake(long session, long ssl, long context, Socket socket,
- FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
- byte[] negotiated = NativeCrypto.SSL_get0_alpn_selected(ssl);
- assertEquals("spdy/2", new String(negotiated));
- /*
- * There is no callback on the client, so we can't enable
- * cut-through
- */
- assertEquals("ALPN should not enable cutthrough on the client", 0,
- NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
- super.afterHandshake(session, ssl, context, socket, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override public void afterHandshake(long session, long ssl, long c, Socket sock,
- FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
- byte[] negotiated = NativeCrypto.SSL_get0_alpn_selected(ssl);
- assertEquals("spdy/2", new String(negotiated));
- assertEquals("ALPN should not enable cutthrough on the server",
- 0, NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
- super.afterHandshake(session, ssl, c, sock, fd, callback);
- }
- };
-
- ServerSocket listener = new ServerSocket(0);
- Future<TestSSLHandshakeCallbacks> client
- = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server
- = handshake(listener, 0, false, sHooks, null, serverAlpnProtocols);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_get_servername_null() throws Exception {
- // NULL SSL
- try {
- NativeCrypto.SSL_get_servername(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertNull(NativeCrypto.SSL_get_servername(s));
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
-
- // additional positive testing by test_SSL_set_tlsext_host_name
- }
-
- public void test_SSL_renegotiate() throws Exception {
- try {
- NativeCrypto.SSL_renegotiate(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[] buffer = new byte[1];
- NativeCrypto.SSL_read(s, fd, callback, buffer, 0, 1, 0);
- assertEquals(42, buffer[0]);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_renegotiate(s);
- NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1, 0);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_get_certificate() throws Exception {
- try {
- NativeCrypto.SSL_get_certificate(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertNull(NativeCrypto.SSL_get_certificate(s));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertEqualCertificateChains(
- getServerCertificates(),
- NativeCrypto.SSL_get_certificate(s));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_get_peer_cert_chain() throws Exception {
- try {
- NativeCrypto.SSL_get_peer_cert_chain(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[][] cc = NativeCrypto.SSL_get_peer_cert_chain(s);
- assertEqualCertificateChains(getServerCertificates(), cc);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- final byte[] BYTES = new byte[] { 2, -3, 5, 127, 0, -128 };
-
- public void test_SSL_read() throws Exception {
-
- // NULL ssl
- try {
- NativeCrypto.SSL_read(NULL, null, null, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // null FileDescriptor
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_read(s, null, DUMMY_CB, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // null SSLHandshakeCallbacks
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_read(s, INVALID_FD, null, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // null byte array
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // handshaking not yet performed
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
- fail();
- } catch (SSLException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- // normal case
- {
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[] in = new byte[256];
- assertEquals(BYTES.length,
- NativeCrypto.SSL_read(s,
- fd,
- callback,
- in,
- 0,
- BYTES.length,
- 0));
- for (int i = 0; i < BYTES.length; i++) {
- assertEquals(BYTES[i], in[i]);
- }
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_write(s, fd, callback, BYTES, 0, BYTES.length, 0);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- // timeout case
- try {
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 1);
- fail();
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
- }
- }
-
- public void test_SSL_write() throws Exception {
- try {
- NativeCrypto.SSL_write(NULL, null, null, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // null FileDescriptor
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_write(s, null, DUMMY_CB, null, 0, 1, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // null SSLHandshakeCallbacks
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_write(s, INVALID_FD, null, null, 0, 1, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // null byte array
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, null, 0, 1, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // handshaking not yet performed
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
- fail();
- } catch (SSLException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // positively tested by test_SSL_read
- }
-
- public void test_SSL_interrupt() throws Exception {
- // SSL_interrupt is a rare case that tolerates a null SSL argument
- NativeCrypto.SSL_interrupt(NULL);
-
- // also works without handshaking
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- NativeCrypto.SSL_interrupt(s);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, final long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- new Thread() {
- public void run() {
- try {
- Thread.sleep(1*1000);
- NativeCrypto.SSL_interrupt(s);
- } catch (Exception e) {
- }
- }
- }.start();
- assertEquals(-1, NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_shutdown() throws Exception {
-
- // null FileDescriptor
- try {
- NativeCrypto.SSL_shutdown(NULL, null, DUMMY_CB);
- } catch (NullPointerException expected) {
- }
-
- // null SSLHandshakeCallbacks
- try {
- NativeCrypto.SSL_shutdown(NULL, INVALID_FD, null);
- } catch (NullPointerException expected) {
- }
-
- // SSL_shutdown is a rare case that tolerates a null SSL argument
- NativeCrypto.SSL_shutdown(NULL, INVALID_FD, DUMMY_CB);
-
- // handshaking not yet performed
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_shutdown(s, INVALID_FD, DUMMY_CB);
- } catch (SSLProtocolException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
-
- // positively tested elsewhere because handshake uses use
- // SSL_shutdown to ensure SSL_SESSIONs are reused.
- }
-
- public void test_SSL_free() throws Exception {
- try {
- NativeCrypto.SSL_free(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- NativeCrypto.SSL_free(NativeCrypto.SSL_new(c));
- NativeCrypto.SSL_CTX_free(c);
-
- // additional positive testing elsewhere because handshake
- // uses use SSL_free to cleanup in afterHandshake.
- }
-
- public void test_SSL_SESSION_session_id() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_session_id(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[] id = NativeCrypto.SSL_SESSION_session_id(session);
- assertNotNull(id);
- assertEquals(32, id.length);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_SESSION_get_time() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_get_time(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- {
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- long time = NativeCrypto.SSL_SESSION_get_time(session);
- assertTrue(time != 0);
- assertTrue(time < System.currentTimeMillis());
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
- }
-
- public void test_SSL_SESSION_get_version() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_get_version(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- String v = NativeCrypto.SSL_SESSION_get_version(session);
- assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(v));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_SESSION_cipher() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_cipher(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- String a = NativeCrypto.SSL_SESSION_cipher(session);
- assertTrue(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.containsKey(a));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_SESSION_free() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_free(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // additional positive testing elsewhere because handshake
- // uses use SSL_SESSION_free to cleanup in afterHandshake.
- }
-
- public void test_i2d_SSL_SESSION() throws Exception {
- try {
- NativeCrypto.i2d_SSL_SESSION(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[] b = NativeCrypto.i2d_SSL_SESSION(session);
- assertNotNull(b);
- long session2 = NativeCrypto.d2i_SSL_SESSION(b);
- assertTrue(session2 != NULL);
-
- // Make sure d2i_SSL_SESSION retores SSL_SESSION_cipher value http://b/7091840
- assertTrue(NativeCrypto.SSL_SESSION_cipher(session2) != null);
- assertEquals(NativeCrypto.SSL_SESSION_cipher(session),
- NativeCrypto.SSL_SESSION_cipher(session2));
-
- NativeCrypto.SSL_SESSION_free(session2);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_d2i_SSL_SESSION() throws Exception {
- try {
- NativeCrypto.d2i_SSL_SESSION(null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- assertEquals(NULL, NativeCrypto.d2i_SSL_SESSION(new byte[0]));
- assertEquals(NULL, NativeCrypto.d2i_SSL_SESSION(new byte[1]));
-
- // positive testing by test_i2d_SSL_SESSION
- }
-
- public void test_X509_NAME_hashes() {
- // ensure these hash functions are stable over time since the
- // /system/etc/security/cacerts CA filenames have to be
- // consistent with the output.
- X500Principal name = new X500Principal("CN=localhost");
- assertEquals(-1372642656, NativeCrypto.X509_NAME_hash(name)); // SHA1
- assertEquals(-1626170662, NativeCrypto.X509_NAME_hash_old(name)); // MD5
- }
-
- public void test_ENGINE_by_id_Failure() throws Exception {
- NativeCrypto.ENGINE_load_dynamic();
-
- long engine = NativeCrypto.ENGINE_by_id("non-existent");
- if (engine != 0) {
- NativeCrypto.ENGINE_free(engine);
- fail("should not acquire reference to non-existent engine");
- }
- }
-
- /**
- * Loads the test OpenSSL ENGINE. If it's already loaded, returns
- * immediately.
- */
- public static void loadTestEngine() throws Exception {
- long testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
- if (testEngine != 0) {
- NativeCrypto.ENGINE_free(testEngine);
- return;
- }
-
- NativeCrypto.ENGINE_load_dynamic();
- long dynEngine = NativeCrypto.ENGINE_by_id("dynamic");
- try {
- ClassLoader loader = NativeCryptoTest.class.getClassLoader();
-
- final String libraryPaths;
- if (loader instanceof BaseDexClassLoader) {
- libraryPaths = ((BaseDexClassLoader) loader).getLdLibraryPath();
- } else {
- libraryPaths = System.getProperty("java.library.path");
- }
- assertNotNull(libraryPaths);
-
- String[] libraryPathArray = libraryPaths.split(":");
- for (String path : libraryPathArray) {
- assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "DIR_ADD", path, 0));
- }
-
- // We must add this to the list of ENGINEs
- assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LIST_ADD", "2", 0));
-
- // Do a direct load of the ENGINE.
- assertEquals(1,
- NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "ID", TEST_ENGINE_ID, 0));
- assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LOAD", null, 0));
- } finally {
- NativeCrypto.ENGINE_free(dynEngine);
- }
-
- testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
- if (testEngine == 0) {
- fail("could not load test engine");
- }
- NativeCrypto.ENGINE_free(testEngine);
- }
-
- public void test_ENGINE_by_id_TestEngine() throws Exception {
- loadTestEngine();
-
- long engine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
- assertTrue(engine != 0);
- NativeCrypto.ENGINE_add(engine);
- NativeCrypto.ENGINE_init(engine);
-
- long pkey = NULL;
- try {
- final String rsaPem =
- "-----BEGIN RSA PRIVATE KEY-----\n"
- + "MIICXAIBAAKBgQCvvsYz1VKhU9PT0NHlotX22tcCjeaiVFNg0JrkjoK2XuMb+7a6\n"
- + "R5bzgIr24+OnBB0LqgaKnHwxZTA73lo/Wy/Ms5Kvg4yX9UMkNE+PvH5vzcQBbFdI\n"
- + "lwETFPvFokHO5OyOcEY+iVWG2fDloteH2JsrKYLh9Sx3Br5pHFCCm5qT5wIDAQAB\n"
- + "AoGAWDxoNs371pPH3qkROUIwOuhU2ytziDzeP9V8bxQ9/GJXlE0kyRH4b/kxzBNO\n"
- + "0SP3kUukTSOUFxi+xtA0b2rQ7Be2txtjzW1TGOHSCWbFrJAdTqeBcmQJSaZay8n1\n"
- + "LOpk4/zvBl7VScBth1IgXP44v6lOzthsrDhMlUYs07ymwYECQQDonaLOhkmVThPa\n"
- + "CIThdE5CN/wF5UDzGOz+ZBz3dt8D8QQMu0aZaPzibq9BC462j/fWeWS5OFzbq2+T\n"
- + "+cor3nwPAkEAwWmTQdra6GMPEc40zNsM5ehF2FjOpX8aU8267eG56y0Y+GbHx2BN\n"
- + "zAHfPxGBBH8cZ0cLhk4RSo/po7Vv+cRyqQJAAQz1N0mT+4Cmxk1TjFEiKVpnYP9w\n"
- + "E6kBKQT6vINk7negNQ6Dex3mRn+Jexm6Q0jTLbzOn6eJg9R6ZIi0SQ5wMQJAKX2n\n"
- + "fGohqdaORgiRZRzcsHlaemXatsAEetPYdO2Gf7/l6mvKEahEKC6CoLn1jmxiQHmK\n"
- + "LF6U8QTcXyUuB0uwOQJBAIwWWjQGGc2sAQ1HW0C2wwCQbWneeBkiRBedonDBHtiB\n"
- + "Wz0zS2CMCtBPNeHQmmsXH2Ca+ADdh53sKTuperLiuiw=\n"
- + "-----END RSA PRIVATE KEY-----";
- pkey = NativeCrypto.ENGINE_load_private_key(engine, rsaPem);
- assertTrue(pkey != 0);
- } finally {
- if (pkey != NULL) {
- NativeCrypto.EVP_PKEY_free(pkey);
- }
-
- NativeCrypto.ENGINE_free(engine);
- NativeCrypto.ENGINE_finish(engine);
- }
- }
-
- public void test_RAND_bytes_Success() throws Exception {
- byte[] output = new byte[128];
- NativeCrypto.RAND_bytes(output);
-
- boolean isZero = true;
- for (int i = 0; i < output.length; i++) {
- isZero &= (output[i] == 0);
- }
-
- assertFalse("Random output was zero. This is a very low probability event (1 in 2^128) "
- + "and probably indicates an error.", isZero);
- }
-
- public void test_RAND_bytes_Null_Failure() throws Exception {
- byte[] output = null;
- try {
- NativeCrypto.RAND_bytes(output);
- fail("Should be an error on null buffer input");
- } catch (RuntimeException expected) {
- }
- }
-
- public void test_EVP_get_digestbyname() throws Exception {
- assertTrue(NativeCrypto.EVP_get_digestbyname("sha256") != NULL);
-
- try {
- NativeCrypto.EVP_get_digestbyname(null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.EVP_get_digestbyname("");
- NativeCrypto.EVP_get_digestbyname("foobar");
- fail();
- } catch (RuntimeException expected) {
- }
- }
-
- public void test_EVP_SignInit() throws Exception {
- final long ctx = NativeCrypto.EVP_SignInit("RSA-SHA256");
- assertTrue(ctx != NULL);
- NativeCrypto.EVP_MD_CTX_destroy(ctx);
-
- try {
- NativeCrypto.EVP_SignInit("foobar");
- fail();
- } catch (RuntimeException expected) {
- }
- }
-
- public void test_get_RSA_private_params() throws Exception {
- try {
- NativeCrypto.get_RSA_private_params(NULL);
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.get_RSA_private_params(NULL);
- } catch (NullPointerException expected) {
- }
-
- // Test getting params for the wrong kind of key.
- final byte[] seed = new byte[20];
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
- assertTrue(ctx != NULL);
- try {
- NativeCrypto.get_RSA_private_params(ctx);
- fail();
- } catch (RuntimeException expected) {
- }
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
-
- public void test_get_RSA_public_params() throws Exception {
- try {
- NativeCrypto.get_RSA_public_params(NULL);
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.get_RSA_public_params(NULL);
- } catch (NullPointerException expected) {
- }
-
- // Test getting params for the wrong kind of key.
- final byte[] seed = new byte[20];
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
- assertTrue(ctx != NULL);
- try {
- NativeCrypto.get_RSA_public_params(ctx);
- fail();
- } catch (RuntimeException expected) {
- }
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
-
- final byte[] dsa2048_p = {
- (byte) 0xC3, (byte) 0x16, (byte) 0xD4, (byte) 0xBA, (byte) 0xDC, (byte) 0x0E,
- (byte) 0xB8, (byte) 0xFC, (byte) 0x40, (byte) 0xDB, (byte) 0xB0, (byte) 0x76,
- (byte) 0x47, (byte) 0xB8, (byte) 0x8D, (byte) 0xC1, (byte) 0xF1, (byte) 0xAB,
- (byte) 0x9B, (byte) 0x80, (byte) 0x9D, (byte) 0xDC, (byte) 0x55, (byte) 0x33,
- (byte) 0xEC, (byte) 0xB6, (byte) 0x09, (byte) 0x8F, (byte) 0xB7, (byte) 0xD9,
- (byte) 0xA5, (byte) 0x7F, (byte) 0xC1, (byte) 0xE3, (byte) 0xAD, (byte) 0xE1,
- (byte) 0x7A, (byte) 0x58, (byte) 0xF4, (byte) 0x2D, (byte) 0xB9, (byte) 0x61,
- (byte) 0xCF, (byte) 0x5B, (byte) 0xCA, (byte) 0x41, (byte) 0x9F, (byte) 0x73,
- (byte) 0x8D, (byte) 0x81, (byte) 0x62, (byte) 0xD2, (byte) 0x19, (byte) 0x7D,
- (byte) 0x18, (byte) 0xDB, (byte) 0xB3, (byte) 0x04, (byte) 0xE7, (byte) 0xB2,
- (byte) 0x28, (byte) 0x59, (byte) 0x14, (byte) 0x73, (byte) 0x43, (byte) 0xF1,
- (byte) 0x45, (byte) 0xC7, (byte) 0x47, (byte) 0xCC, (byte) 0xD1, (byte) 0x12,
- (byte) 0x8E, (byte) 0x19, (byte) 0x00, (byte) 0x2C, (byte) 0xD0, (byte) 0x86,
- (byte) 0x54, (byte) 0x64, (byte) 0x2D, (byte) 0x42, (byte) 0x6C, (byte) 0x6B,
- (byte) 0x5C, (byte) 0x2D, (byte) 0x4D, (byte) 0x97, (byte) 0x6A, (byte) 0x1D,
- (byte) 0x89, (byte) 0xB1, (byte) 0x2C, (byte) 0xA0, (byte) 0x05, (byte) 0x2B,
- (byte) 0x3C, (byte) 0xDB, (byte) 0x1F, (byte) 0x89, (byte) 0x03, (byte) 0x03,
- (byte) 0x92, (byte) 0x63, (byte) 0xB6, (byte) 0x08, (byte) 0x32, (byte) 0x50,
- (byte) 0xB2, (byte) 0x54, (byte) 0xA3, (byte) 0xFE, (byte) 0x6C, (byte) 0x35,
- (byte) 0x17, (byte) 0x2F, (byte) 0x7F, (byte) 0x54, (byte) 0xA4, (byte) 0xAE,
- (byte) 0x96, (byte) 0x1E, (byte) 0x31, (byte) 0x83, (byte) 0xF1, (byte) 0x3F,
- (byte) 0x9E, (byte) 0xB9, (byte) 0x5D, (byte) 0xD3, (byte) 0xA9, (byte) 0xCB,
- (byte) 0xE5, (byte) 0x2F, (byte) 0xBC, (byte) 0xA4, (byte) 0x1A, (byte) 0x31,
- (byte) 0x41, (byte) 0x91, (byte) 0x2C, (byte) 0xA0, (byte) 0xF4, (byte) 0x83,
- (byte) 0xAC, (byte) 0xD5, (byte) 0xBA, (byte) 0x3D, (byte) 0x19, (byte) 0xED,
- (byte) 0xF1, (byte) 0x6C, (byte) 0xD9, (byte) 0x3F, (byte) 0x30, (byte) 0xDA,
- (byte) 0x80, (byte) 0x06, (byte) 0x56, (byte) 0x3A, (byte) 0x8C, (byte) 0x74,
- (byte) 0x63, (byte) 0xF2, (byte) 0xED, (byte) 0x1E, (byte) 0xE3, (byte) 0x86,
- (byte) 0x95, (byte) 0x64, (byte) 0x2A, (byte) 0xC4, (byte) 0x5F, (byte) 0xB2,
- (byte) 0x64, (byte) 0x40, (byte) 0x9D, (byte) 0xA6, (byte) 0xB8, (byte) 0xF5,
- (byte) 0x84, (byte) 0x03, (byte) 0x2E, (byte) 0x4A, (byte) 0x7A, (byte) 0x1A,
- (byte) 0xB0, (byte) 0x0E, (byte) 0xBA, (byte) 0xB1, (byte) 0xF5, (byte) 0xD2,
- (byte) 0xE7, (byte) 0x65, (byte) 0xCE, (byte) 0xEE, (byte) 0x2C, (byte) 0x7C,
- (byte) 0x68, (byte) 0x20, (byte) 0x50, (byte) 0x53, (byte) 0x0F, (byte) 0x60,
- (byte) 0x92, (byte) 0x81, (byte) 0xC0, (byte) 0x2C, (byte) 0x2A, (byte) 0xEA,
- (byte) 0xE9, (byte) 0xB3, (byte) 0x2A, (byte) 0x81, (byte) 0xDA, (byte) 0x0F,
- (byte) 0xBB, (byte) 0xFA, (byte) 0x5B, (byte) 0x47, (byte) 0xDA, (byte) 0x57,
- (byte) 0x4E, (byte) 0xFC, (byte) 0x05, (byte) 0x2C, (byte) 0x6A, (byte) 0x90,
- (byte) 0xA0, (byte) 0x99, (byte) 0x88, (byte) 0x71, (byte) 0x8A, (byte) 0xCC,
- (byte) 0xD2, (byte) 0x97, (byte) 0x11, (byte) 0xB1, (byte) 0xCE, (byte) 0xF7,
- (byte) 0x47, (byte) 0x53, (byte) 0x53, (byte) 0x68, (byte) 0xE1, (byte) 0x2A,
- (byte) 0x56, (byte) 0xD5, (byte) 0x3D, (byte) 0xDF, (byte) 0x08, (byte) 0x16,
- (byte) 0x1F, (byte) 0xAA, (byte) 0x54, (byte) 0x15,
- };
-
- final byte[] dsa2048_q = {
- (byte) 0xAA, (byte) 0xDD, (byte) 0xE2, (byte) 0xCE, (byte) 0x08, (byte) 0xC0,
- (byte) 0x0E, (byte) 0x91, (byte) 0x8C, (byte) 0xD9, (byte) 0xBC, (byte) 0x1E,
- (byte) 0x05, (byte) 0x70, (byte) 0x07, (byte) 0x3B, (byte) 0xB5, (byte) 0xA9,
- (byte) 0xB5, (byte) 0x8B, (byte) 0x21, (byte) 0x68, (byte) 0xA2, (byte) 0x76,
- (byte) 0x53, (byte) 0x1E, (byte) 0x68, (byte) 0x1B, (byte) 0x4F, (byte) 0x88,
- (byte) 0x6D, (byte) 0xCF,
- };
-
- final byte[] dsa2048_g = {
- (byte) 0x6B, (byte) 0x4D, (byte) 0x21, (byte) 0x92, (byte) 0x24, (byte) 0x76,
- (byte) 0xE5, (byte) 0xA2, (byte) 0xCE, (byte) 0x02, (byte) 0x85, (byte) 0x32,
- (byte) 0x73, (byte) 0x70, (byte) 0xFF, (byte) 0xB9, (byte) 0xD4, (byte) 0x51,
- (byte) 0xBA, (byte) 0x22, (byte) 0x8B, (byte) 0x75, (byte) 0x29, (byte) 0xE3,
- (byte) 0xF2, (byte) 0x2E, (byte) 0x20, (byte) 0xF5, (byte) 0x6A, (byte) 0xD9,
- (byte) 0x75, (byte) 0xA0, (byte) 0xC0, (byte) 0x3B, (byte) 0x12, (byte) 0x2F,
- (byte) 0x4F, (byte) 0x9A, (byte) 0xF8, (byte) 0x5D, (byte) 0x45, (byte) 0xC5,
- (byte) 0x80, (byte) 0x6C, (byte) 0x9B, (byte) 0x56, (byte) 0xBE, (byte) 0x8E,
- (byte) 0x40, (byte) 0xF9, (byte) 0x0A, (byte) 0xF0, (byte) 0x3D, (byte) 0xD7,
- (byte) 0x7C, (byte) 0xDE, (byte) 0x22, (byte) 0x10, (byte) 0x24, (byte) 0xCC,
- (byte) 0xAE, (byte) 0x8A, (byte) 0xC0, (byte) 0x05, (byte) 0xCD, (byte) 0xDC,
- (byte) 0x10, (byte) 0x29, (byte) 0x4D, (byte) 0xFC, (byte) 0xEC, (byte) 0xEF,
- (byte) 0x51, (byte) 0x4B, (byte) 0xF9, (byte) 0xCC, (byte) 0x99, (byte) 0x84,
- (byte) 0x1B, (byte) 0x14, (byte) 0x68, (byte) 0xEC, (byte) 0xF0, (byte) 0x5E,
- (byte) 0x07, (byte) 0x10, (byte) 0x09, (byte) 0xA9, (byte) 0x2C, (byte) 0x04,
- (byte) 0xD0, (byte) 0x14, (byte) 0xBF, (byte) 0x88, (byte) 0x9E, (byte) 0xBB,
- (byte) 0xE3, (byte) 0x3F, (byte) 0xDE, (byte) 0x92, (byte) 0xE1, (byte) 0x64,
- (byte) 0x07, (byte) 0x28, (byte) 0xC1, (byte) 0xCA, (byte) 0x48, (byte) 0xC1,
- (byte) 0x1D, (byte) 0x33, (byte) 0xE4, (byte) 0x35, (byte) 0xBE, (byte) 0xDF,
- (byte) 0x5E, (byte) 0x50, (byte) 0xF9, (byte) 0xC2, (byte) 0x0E, (byte) 0x25,
- (byte) 0x0D, (byte) 0x20, (byte) 0x8C, (byte) 0x01, (byte) 0x0A, (byte) 0x23,
- (byte) 0xD4, (byte) 0x6E, (byte) 0x42, (byte) 0x47, (byte) 0xE1, (byte) 0x9E,
- (byte) 0x36, (byte) 0x91, (byte) 0xC8, (byte) 0x65, (byte) 0x44, (byte) 0xE0,
- (byte) 0x04, (byte) 0x86, (byte) 0x2F, (byte) 0xD4, (byte) 0x90, (byte) 0x16,
- (byte) 0x09, (byte) 0x14, (byte) 0xB1, (byte) 0xC5, (byte) 0x7D, (byte) 0xB2,
- (byte) 0x7C, (byte) 0x36, (byte) 0x0D, (byte) 0x9C, (byte) 0x1F, (byte) 0x83,
- (byte) 0x57, (byte) 0x94, (byte) 0x26, (byte) 0x32, (byte) 0x9C, (byte) 0x86,
- (byte) 0x8E, (byte) 0xE5, (byte) 0x80, (byte) 0x3A, (byte) 0xA9, (byte) 0xAF,
- (byte) 0x4A, (byte) 0x95, (byte) 0x78, (byte) 0x8D, (byte) 0xE6, (byte) 0xC3,
- (byte) 0x0C, (byte) 0x78, (byte) 0x83, (byte) 0x4B, (byte) 0xF5, (byte) 0x40,
- (byte) 0x04, (byte) 0x20, (byte) 0x90, (byte) 0x5C, (byte) 0xA1, (byte) 0x19,
- (byte) 0xEB, (byte) 0x95, (byte) 0x70, (byte) 0x2B, (byte) 0x94, (byte) 0xA3,
- (byte) 0x43, (byte) 0xDD, (byte) 0xEB, (byte) 0xD4, (byte) 0x0C, (byte) 0xBC,
- (byte) 0xBD, (byte) 0x58, (byte) 0x2D, (byte) 0x75, (byte) 0xB0, (byte) 0x8D,
- (byte) 0x8B, (byte) 0x70, (byte) 0xB9, (byte) 0xE7, (byte) 0xA3, (byte) 0xCC,
- (byte) 0x8C, (byte) 0xB4, (byte) 0xCD, (byte) 0xBB, (byte) 0x4B, (byte) 0xB1,
- (byte) 0x15, (byte) 0x18, (byte) 0x79, (byte) 0xDF, (byte) 0x22, (byte) 0xA6,
- (byte) 0x5C, (byte) 0x90, (byte) 0x7C, (byte) 0x1F, (byte) 0xEA, (byte) 0x1B,
- (byte) 0xF2, (byte) 0x89, (byte) 0x87, (byte) 0xB2, (byte) 0xEC, (byte) 0x57,
- (byte) 0xFF, (byte) 0xB2, (byte) 0xDA, (byte) 0xF5, (byte) 0xAD, (byte) 0x73,
- (byte) 0xC0, (byte) 0xA0, (byte) 0x20, (byte) 0x8B, (byte) 0x78, (byte) 0xA1,
- (byte) 0x5D, (byte) 0x04, (byte) 0x0A, (byte) 0x29, (byte) 0xE3, (byte) 0xD7,
- (byte) 0x37, (byte) 0xF6, (byte) 0xA2, (byte) 0xCA,
- };
-
- public void test_DSA_generate_key() throws Exception {
- final byte[] seed = new byte[20];
-
- // Real key
- {
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
- assertTrue(ctx != NULL);
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
-
- // Real key with minimum bit size (should be 512 bits)
- {
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(0, null, null, null, null);
- assertTrue(ctx != NULL);
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
-
- // Bad DSA params.
- {
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(0, null, new byte[] {}, new byte[] {},
- new byte[] {});
- fail();
- } catch (RuntimeException expected) {
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
- }
-
- /*
- * Test vector generation:
- * openssl rand -hex 16
- */
- private static final byte[] AES_128_KEY = new byte[] {
- (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2,
- (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29,
- (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f,
- };
-
- private static final byte[] AES_IV_ZEROES = new byte[] {
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- };
-
- public void testEC_GROUP() throws Exception {
- /* Test using NIST's P-256 curve */
- check_EC_GROUP(NativeCrypto.EC_CURVE_GFP, "prime256v1",
- "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
- "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
- "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
- "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
- "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
- "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
- 1L);
-
- check_EC_GROUP(NativeCrypto.EC_CURVE_GF2M, "sect283r1",
- "0800000000000000000000000000000000000000000000000000000000000000000010A1",
- "000000000000000000000000000000000000000000000000000000000000000000000001",
- "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
- "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
- "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
- "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
- 2L);
- }
-
- private void check_EC_GROUP(int type, String name, String pStr, String aStr, String bStr,
- String xStr, String yStr, String nStr, long hLong) throws Exception {
- long group1 = NULL, group2 = NULL, point1 = NULL, point2 = NULL, key1 = NULL;
- try {
- group1 = NativeCrypto.EC_GROUP_new_by_curve_name(name);
- assertTrue(group1 != NULL);
- assertEquals(NativeCrypto.OBJ_txt2nid_longName(name),
- NativeCrypto.EC_GROUP_get_curve_name(group1));
- assertEquals(type, NativeCrypto.get_EC_GROUP_type(group1));
-
- // prime
- BigInteger p = new BigInteger(pStr, 16);
- // first coefficient
- BigInteger a = new BigInteger(aStr, 16);
- // second coefficient
- BigInteger b = new BigInteger(bStr, 16);
- // x affine coordinate of generator
- BigInteger x = new BigInteger(xStr, 16);
- // y affine coordinate of generator
- BigInteger y = new BigInteger(yStr, 16);
- // order of the generator
- BigInteger n = new BigInteger(nStr, 16);
- // cofactor of generator
- BigInteger h = BigInteger.valueOf(hLong);
-
- group2 = NativeCrypto.EC_GROUP_new_curve(type, p.toByteArray(),
- a.toByteArray(), b.toByteArray());
- assertEquals(type, NativeCrypto.get_EC_GROUP_type(group2));
-
- point2 = NativeCrypto.EC_POINT_new(group2);
-
- NativeCrypto.EC_POINT_set_affine_coordinates(group2, point2, x.toByteArray(),
- y.toByteArray());
-
- NativeCrypto.EC_GROUP_set_generator(group2, point2, n.toByteArray(), h.toByteArray());
-
- point1 = NativeCrypto.EC_GROUP_get_generator(group2);
- assertTrue(NativeCrypto.EC_POINT_cmp(group1, point1, point2));
-
- byte[][] pab = NativeCrypto.EC_GROUP_get_curve(group2);
- assertEquals(3, pab.length);
-
- BigInteger p2 = new BigInteger(pab[0]);
- assertEquals(p, p2);
-
- BigInteger a2 = new BigInteger(pab[1]);
- assertEquals(a, a2);
-
- BigInteger b2 = new BigInteger(pab[2]);
- assertEquals(b, b2);
-
- byte[][] xy = NativeCrypto.EC_POINT_get_affine_coordinates(group2, point2);
- assertEquals(2, xy.length);
-
- BigInteger x2 = new BigInteger(xy[0]);
- assertEquals(x, x2);
-
- BigInteger y2 = new BigInteger(xy[1]);
- assertEquals(y, y2);
-
- BigInteger n2 = new BigInteger(NativeCrypto.EC_GROUP_get_order(group1));
- assertEquals(n, n2);
-
- BigInteger h2 = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(group2));
- assertEquals(h, h2);
-
- assertTrue(NativeCrypto.EC_GROUP_cmp(group1, group2));
-
- key1 = NativeCrypto.EC_KEY_generate_key(group1);
- long groupTmp = NativeCrypto.EC_KEY_get0_group(key1);
- assertEquals(NativeCrypto.EC_GROUP_get_curve_name(group1),
- NativeCrypto.EC_GROUP_get_curve_name(groupTmp));
-
- } finally {
- if (group1 != NULL) {
- NativeCrypto.EC_GROUP_clear_free(group1);
- }
-
- if (group2 != NULL) {
- NativeCrypto.EC_GROUP_clear_free(group2);
- }
-
- if (point1 != NULL) {
- NativeCrypto.EC_POINT_clear_free(point1);
- }
-
- if (point2 != NULL) {
- NativeCrypto.EC_POINT_clear_free(point2);
- }
-
- if (key1 != NULL) {
- NativeCrypto.EVP_PKEY_free(key1);
- }
- }
- }
-
- public void test_EVP_CipherInit_ex_Null_Failure() throws Exception {
- final long ctx = NativeCrypto.EVP_CIPHER_CTX_new();
- try {
- final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
-
- try {
- NativeCrypto.EVP_CipherInit_ex(NULL, evpCipher, null, null, true);
- fail("Null context should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
-
- /* Initialize encrypting. */
- NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, true);
- NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, true);
-
- /* Initialize decrypting. */
- NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, false);
- NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, false);
- } finally {
- NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx);
- }
- }
-
- public void test_EVP_CipherInit_ex_Success() throws Exception {
- final long ctx = NativeCrypto.EVP_CIPHER_CTX_new();
- try {
- final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
- NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, AES_128_KEY, null, true);
- } finally {
- NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx);
- }
- }
-
- public void test_EVP_CIPHER_iv_length() throws Exception {
- long aes128ecb = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
- assertEquals(0, NativeCrypto.EVP_CIPHER_iv_length(aes128ecb));
-
- long aes128cbc = NativeCrypto.EVP_get_cipherbyname("aes-128-cbc");
- assertEquals(16, NativeCrypto.EVP_CIPHER_iv_length(aes128cbc));
- }
-
- public void test_OpenSSLKey_toJava() throws Exception {
- OpenSSLKey key1;
-
- BigInteger e = BigInteger.valueOf(65537);
- key1 = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(1024, e.toByteArray()));
- assertTrue(key1.getPublicKey() instanceof RSAPublicKey);
-
- key1 = new OpenSSLKey(NativeCrypto.DSA_generate_key(1024, null, null, null, null));
- assertTrue(key1.getPublicKey() instanceof DSAPublicKey);
-
- long group1 = NULL;
- try {
- group1 = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1");
- assertTrue(group1 != NULL);
- key1 = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group1));
- } finally {
- if (group1 != NULL) {
- NativeCrypto.EC_GROUP_clear_free(group1);
- }
- }
- assertTrue(key1.getPublicKey() instanceof ECPublicKey);
- }
-
- public void test_create_BIO_InputStream() throws Exception {
- byte[] actual = "Test".getBytes();
- ByteArrayInputStream is = new ByteArrayInputStream(actual);
-
- long ctx = NativeCrypto.create_BIO_InputStream(new OpenSSLBIOInputStream(is));
- try {
- byte[] buffer = new byte[1024];
- int numRead = NativeCrypto.BIO_read(ctx, buffer);
- assertEquals(actual.length, numRead);
- assertEquals(Arrays.toString(actual),
- Arrays.toString(Arrays.copyOfRange(buffer, 0, numRead)));
- } finally {
- NativeCrypto.BIO_free(ctx);
- }
-
- }
-
- public void test_create_BIO_OutputStream() throws Exception {
- byte[] actual = "Test".getBytes();
- ByteArrayOutputStream os = new ByteArrayOutputStream();
-
- long ctx = NativeCrypto.create_BIO_OutputStream(os);
- try {
- NativeCrypto.BIO_write(ctx, actual, 0, actual.length);
- assertEquals(actual.length, os.size());
- assertEquals(Arrays.toString(actual), Arrays.toString(os.toByteArray()));
- } finally {
- NativeCrypto.BIO_free(ctx);
- }
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/OpenSSLSignatureTest.java b/crypto/src/test/java/org/conscrypt/OpenSSLSignatureTest.java
deleted file mode 100644
index 045c509..0000000
--- a/crypto/src/test/java/org/conscrypt/OpenSSLSignatureTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.NoSuchAlgorithmException;
-import junit.framework.TestCase;
-
-public class OpenSSLSignatureTest extends TestCase {
-
- public void test_getInstance() throws Exception {
- try {
- OpenSSLSignature.getInstance("SHA1WITHDSA");
- OpenSSLSignature.getInstance("MD5WITHRSAENCRYPTION");
- OpenSSLSignature.getInstance("SHA1WITHRSAENCRYPTION");
- OpenSSLSignature.getInstance("SHA256WITHRSAENCRYPTION");
- OpenSSLSignature.getInstance("SHA384WITHRSAENCRYPTION");
- OpenSSLSignature.getInstance("SHA512WITHRSAENCRYPTION");
- } catch (NoSuchAlgorithmException e) {
- fail("getInstance is not case insensitive");
- }
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/SignatureTest.java b/crypto/src/test/java/org/conscrypt/SignatureTest.java
deleted file mode 100644
index d6679c4..0000000
--- a/crypto/src/test/java/org/conscrypt/SignatureTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.Signature;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Set;
-import junit.framework.TestCase;
-
-public class SignatureTest extends TestCase {
- // 20 bytes for DSA
- private final byte[] DATA = new byte[20];
-
- public void test_getInstance_OpenSSL_ENGINE() throws Exception {
- final String pem_private = "-----BEGIN RSA PRIVATE KEY-----\n"
- + "MIICXAIBAAKBgQDpm4KamxulJnycEzNONGM7p0CvAaoZxJEd5Dvio5b6BROdCtRN\n"
- + "lEsB+9vtB5thkyDVC7N+IW0AjtyDE6h2QP+AWa+c4dh0RM2uNVXkUWPrA8C++GHv\n"
- + "EDlxZzRGiQEMuippYfIyBVkO+4+GRvnkG4dKjzxrQYPqKUK3C4PgFW2FewIDAQAB\n"
- + "AoGAGUTSBsk6X03fcr588TundD9uNr/2V1002Ufj1msdnKPJ8FXIiy+8QVWt/2Cw\n"
- + "RQi2J3VhkAYrlUDex2rr8Qas3E9uuwKgg/MZ4EsJbnKKgkd7uBZfmZ2ogcNJ82u7\n"
- + "teVijFpdsVLDa9aczEppt5sZzyTaBrovrRb+AIRDpMw3I0ECQQD3JkWeQUA9Is1V\n"
- + "z0X/ly/kaQKQLlrwYNdiKF0qOpyTLAguI7asAS72Zj7fThk5bHLM+mmgYwkicIIb\n"
- + "67J32GQbAkEA8fkXqEnwMFYSkRmT9M/qUkwWUsMW12/AoZFI5gwKNDHZYxytGGLw\n"
- + "mC//0qKnyeUG00vz06vLApe4/Sq4ODe6IQJBALEGastF9ZtUuDsEciD2y8kRJlLb\n"
- + "wSt4Ug3u13yN6uTHnzxdPFTLrDW1WsdcC1lEQp5rpwjIpxxR9f/FvVl2V40CQHOY\n"
- + "F6EhkUjGFaCTo4b0PHCMQK3Q3PyWOmP0z+p2HfnJRpx+eoKH4YASjhfF9HoSmywd\n"
- + "wKGCFD1s1ca7vb29gYECQH86GmYZsDoLNWurEVJbkmCr7X1+xwim6umdrNKR27P7\n"
- + "F1y0Sa3YY+LiiRb+IRSWE/onlP+28LIzWGF4lcTfDMc=\n"
- + "-----END RSA PRIVATE KEY-----";
-
- final byte[] der_public = new byte[] {
- (byte) 0x30, (byte) 0x81, (byte) 0x9F, (byte) 0x30, (byte) 0x0D, (byte) 0x06,
- (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7,
- (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00,
- (byte) 0x03, (byte) 0x81, (byte) 0x8D, (byte) 0x00, (byte) 0x30, (byte) 0x81,
- (byte) 0x89, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xE9,
- (byte) 0x9B, (byte) 0x82, (byte) 0x9A, (byte) 0x9B, (byte) 0x1B, (byte) 0xA5,
- (byte) 0x26, (byte) 0x7C, (byte) 0x9C, (byte) 0x13, (byte) 0x33, (byte) 0x4E,
- (byte) 0x34, (byte) 0x63, (byte) 0x3B, (byte) 0xA7, (byte) 0x40, (byte) 0xAF,
- (byte) 0x01, (byte) 0xAA, (byte) 0x19, (byte) 0xC4, (byte) 0x91, (byte) 0x1D,
- (byte) 0xE4, (byte) 0x3B, (byte) 0xE2, (byte) 0xA3, (byte) 0x96, (byte) 0xFA,
- (byte) 0x05, (byte) 0x13, (byte) 0x9D, (byte) 0x0A, (byte) 0xD4, (byte) 0x4D,
- (byte) 0x94, (byte) 0x4B, (byte) 0x01, (byte) 0xFB, (byte) 0xDB, (byte) 0xED,
- (byte) 0x07, (byte) 0x9B, (byte) 0x61, (byte) 0x93, (byte) 0x20, (byte) 0xD5,
- (byte) 0x0B, (byte) 0xB3, (byte) 0x7E, (byte) 0x21, (byte) 0x6D, (byte) 0x00,
- (byte) 0x8E, (byte) 0xDC, (byte) 0x83, (byte) 0x13, (byte) 0xA8, (byte) 0x76,
- (byte) 0x40, (byte) 0xFF, (byte) 0x80, (byte) 0x59, (byte) 0xAF, (byte) 0x9C,
- (byte) 0xE1, (byte) 0xD8, (byte) 0x74, (byte) 0x44, (byte) 0xCD, (byte) 0xAE,
- (byte) 0x35, (byte) 0x55, (byte) 0xE4, (byte) 0x51, (byte) 0x63, (byte) 0xEB,
- (byte) 0x03, (byte) 0xC0, (byte) 0xBE, (byte) 0xF8, (byte) 0x61, (byte) 0xEF,
- (byte) 0x10, (byte) 0x39, (byte) 0x71, (byte) 0x67, (byte) 0x34, (byte) 0x46,
- (byte) 0x89, (byte) 0x01, (byte) 0x0C, (byte) 0xBA, (byte) 0x2A, (byte) 0x69,
- (byte) 0x61, (byte) 0xF2, (byte) 0x32, (byte) 0x05, (byte) 0x59, (byte) 0x0E,
- (byte) 0xFB, (byte) 0x8F, (byte) 0x86, (byte) 0x46, (byte) 0xF9, (byte) 0xE4,
- (byte) 0x1B, (byte) 0x87, (byte) 0x4A, (byte) 0x8F, (byte) 0x3C, (byte) 0x6B,
- (byte) 0x41, (byte) 0x83, (byte) 0xEA, (byte) 0x29, (byte) 0x42, (byte) 0xB7,
- (byte) 0x0B, (byte) 0x83, (byte) 0xE0, (byte) 0x15, (byte) 0x6D, (byte) 0x85,
- (byte) 0x7B, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01
- };
-
- // We only need to test this on the OpenSSL provider.
- Provider p = Security.getProvider(OpenSSLProvider.PROVIDER_NAME);
-
- /* ENGINE-based private key */
- NativeCryptoTest.loadTestEngine();
- OpenSSLEngine engine = OpenSSLEngine.getInstance(NativeCryptoTest.TEST_ENGINE_ID);
- PrivateKey privKey = engine.getPrivateKeyById(pem_private);
- assertTrue(privKey instanceof RSAPrivateKey);
-
- /* Non-ENGINE-based public key */
- KeyFactory kf = KeyFactory.getInstance("RSA", p);
- PublicKey pubKey = kf.generatePublic(new X509EncodedKeySpec(der_public));
-
- KeyPair kp = new KeyPair(pubKey, privKey);
-
- Set<Provider.Service> services = p.getServices();
- for (Provider.Service service : services) {
- if ("Signature".equals(service.getType()) && service.getAlgorithm().contains("RSA")) {
- Signature sig1 = Signature.getInstance(service.getAlgorithm(), p);
- test_Signature(sig1, kp);
- }
- }
- }
-
- private void test_Signature(Signature sig, KeyPair keyPair) throws Exception {
- sig.initSign(keyPair.getPrivate());
- sig.update(DATA);
- byte[] signature = sig.sign();
- assertNotNull(sig.getAlgorithm(), signature);
- assertTrue(sig.getAlgorithm(), signature.length > 0);
-
- sig.initVerify(keyPair.getPublic());
- sig.update(DATA);
- assertTrue(sig.getAlgorithm(), sig.verify(signature));
-
- // After verify, should be reusable as if we are after initVerify
- sig.update(DATA);
- assertTrue(sig.getAlgorithm(), sig.verify(signature));
-
- // Calling Signature.verify a second time should not throw
- // http://code.google.com/p/android/issues/detail?id=34933
- sig.verify(signature);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/TrustManagerImplTest.java b/crypto/src/test/java/org/conscrypt/TrustManagerImplTest.java
deleted file mode 100644
index 639ed95..0000000
--- a/crypto/src/test/java/org/conscrypt/TrustManagerImplTest.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.KeyStore;
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-import junit.framework.TestCase;
-import libcore.java.security.TestKeyStore;
-
-public class TrustManagerImplTest extends TestCase {
-
- private List<File> tmpFiles = new ArrayList<File>();
-
- private String getFingerprint(X509Certificate cert) throws Exception {
- MessageDigest dgst = MessageDigest.getInstance("SHA512");
- byte[] encoded = cert.getPublicKey().getEncoded();
- byte[] fingerprint = dgst.digest(encoded);
- return IntegralToString.bytesToHexString(fingerprint, false);
- }
-
- private String writeTmpPinFile(String text) throws Exception {
- File tmp = File.createTempFile("pins", null);
- FileWriter fstream = new FileWriter(tmp);
- fstream.write(text);
- fstream.close();
- tmpFiles.add(tmp);
- return tmp.getPath();
- }
-
- @Override
- public void tearDown() throws Exception {
- try {
- for (File f : tmpFiles) {
- f.delete();
- }
- tmpFiles.clear();
- } finally {
- super.tearDown();
- }
- }
-
- /**
- * Ensure that our non-standard behavior of learning to trust new
- * intermediate CAs does not regress. http://b/3404902
- */
- public void testLearnIntermediate() throws Exception {
- // chain3 should be server/intermediate/root
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
- X509Certificate root = chain3[2];
- X509Certificate intermediate = chain3[1];
- X509Certificate server = chain3[0];
- X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
- X509Certificate[] chain1 = new X509Certificate[] { server };
-
- // Normal behavior
- assertValid(chain3, trustManager(root));
- assertValid(chain2, trustManager(root));
- assertInvalid(chain1, trustManager(root));
- assertValid(chain3, trustManager(intermediate));
- assertValid(chain2, trustManager(intermediate));
- assertValid(chain1, trustManager(intermediate));
- assertValid(chain3, trustManager(server));
- assertValid(chain2, trustManager(server));
- assertValid(chain1, trustManager(server));
-
- // non-standard behavior
- X509TrustManager tm = trustManager(root);
- // fail on short chain with only root trusted
- assertInvalid(chain1, tm);
- // succeed on longer chain, learn intermediate
- assertValid(chain2, tm);
- // now we can validate the short chain
- assertValid(chain1, tm);
- }
-
- // We should ignore duplicate cruft in the certificate chain
- // See https://code.google.com/p/android/issues/detail?id=52295 http://b/8313312
- public void testDuplicateInChain() throws Exception {
- // chain3 should be server/intermediate/root
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
- X509Certificate root = chain3[2];
- X509Certificate intermediate = chain3[1];
- X509Certificate server = chain3[0];
-
- X509Certificate[] chain4 = new X509Certificate[] { server, intermediate,
- server, intermediate
- };
- assertValid(chain4, trustManager(root));
- }
-
- public void testGetFullChain() throws Exception {
- // build the trust manager
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
- X509Certificate root = chain3[2];
- X509TrustManager tm = trustManager(root);
-
- // build the chains we'll use for testing
- X509Certificate intermediate = chain3[1];
- X509Certificate server = chain3[0];
- X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
- X509Certificate[] chain1 = new X509Certificate[] { server };
-
- assertTrue(tm instanceof TrustManagerImpl);
- TrustManagerImpl tmi = (TrustManagerImpl) tm;
- List<X509Certificate> certs = tmi.checkServerTrusted(chain2, "RSA", "purple.com");
- assertEquals(Arrays.asList(chain3), certs);
- certs = tmi.checkServerTrusted(chain1, "RSA", "purple.com");
- assertEquals(Arrays.asList(chain3), certs);
- }
-
- public void testCertPinning() throws Exception {
- // chain3 should be server/intermediate/root
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain3 = (X509Certificate[]) pke.getCertificateChain();
- X509Certificate root = chain3[2];
- X509Certificate intermediate = chain3[1];
- X509Certificate server = chain3[0];
- X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
- X509Certificate[] chain1 = new X509Certificate[] { server };
-
- // test without a hostname, expecting failure
- assertInvalidPinned(chain1, trustManager(root, "gugle.com", root), null);
- // test without a hostname, expecting success
- assertValidPinned(chain3, trustManager(root, "gugle.com", root), null, chain3);
- // test an unpinned hostname that should fail
- assertInvalidPinned(chain1, trustManager(root, "gugle.com", root), "purple.com");
- // test an unpinned hostname that should succeed
- assertValidPinned(chain3, trustManager(root, "gugle.com", root), "purple.com", chain3);
- // test a pinned hostname that should fail
- assertInvalidPinned(chain1, trustManager(intermediate, "gugle.com", root), "gugle.com");
- // test a pinned hostname that should succeed
- assertValidPinned(chain2, trustManager(intermediate, "gugle.com", server), "gugle.com",
- chain2);
- }
-
- private X509TrustManager trustManager(X509Certificate ca) throws Exception {
- KeyStore keyStore = TestKeyStore.createKeyStore();
- keyStore.setCertificateEntry("alias", ca);
-
- String algorithm = TrustManagerFactory.getDefaultAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- tmf.init(keyStore);
- return (X509TrustManager) tmf.getTrustManagers()[0];
- }
-
- private TrustManagerImpl trustManager(X509Certificate ca, String hostname, X509Certificate pin)
- throws Exception {
- // build the cert pin manager
- CertPinManager cm = certManager(hostname, pin);
- // insert it into the trust manager
- KeyStore keyStore = TestKeyStore.createKeyStore();
- keyStore.setCertificateEntry("alias", ca);
- return new TrustManagerImpl(keyStore, cm);
- }
-
- private CertPinManager certManager(String hostname, X509Certificate pin) throws Exception {
- String pinString = "";
- if (pin != null) {
- pinString = hostname + "=true|" + getFingerprint(pin);
- }
- // write it to a pinfile
- String path = writeTmpPinFile(pinString);
- // build the certpinmanager
- return new CertPinManager(path, new TrustedCertificateStore());
- }
-
- private void assertValid(X509Certificate[] chain, X509TrustManager tm) throws Exception {
- if (tm instanceof TrustManagerImpl) {
- TrustManagerImpl tmi = (TrustManagerImpl) tm;
- tmi.checkServerTrusted(chain, "RSA");
- }
- tm.checkServerTrusted(chain, "RSA");
- }
-
- private void assertValidPinned(X509Certificate[] chain, X509TrustManager tm, String hostname,
- X509Certificate[] fullChain) throws Exception {
- if (tm instanceof TrustManagerImpl) {
- TrustManagerImpl tmi = (TrustManagerImpl) tm;
- List<X509Certificate> checkedChain = tmi.checkServerTrusted(chain, "RSA", hostname);
- assertEquals(checkedChain, Arrays.asList(fullChain));
- }
- tm.checkServerTrusted(chain, "RSA");
- }
-
- private void assertInvalid(X509Certificate[] chain, X509TrustManager tm) {
- try {
- tm.checkClientTrusted(chain, "RSA");
- fail();
- } catch (CertificateException expected) {
- }
- try {
- tm.checkServerTrusted(chain, "RSA");
- fail();
- } catch (CertificateException expected) {
- }
- }
-
- private void assertInvalidPinned(X509Certificate[] chain, X509TrustManager tm, String hostname)
- throws Exception {
- assertTrue(tm.getClass().getName(), tm instanceof TrustManagerImpl);
- try {
- TrustManagerImpl tmi = (TrustManagerImpl) tm;
- tmi.checkServerTrusted(chain, "RSA", hostname);
- fail();
- } catch (CertificateException expected) {
- }
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java b/crypto/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java
deleted file mode 100644
index a8e9475..0000000
--- a/crypto/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-import junit.framework.TestCase;
-import libcore.java.security.TestKeyStore;
-
-public class TrustedCertificateStoreTest extends TestCase {
-
- private static final File DIR_TEMP = new File(System.getProperty("java.io.tmpdir"));
- private static final File DIR_TEST = new File(DIR_TEMP, "test");
- private static final File DIR_SYSTEM = new File(DIR_TEST, "system");
- private static final File DIR_ADDED = new File(DIR_TEST, "added");
- private static final File DIR_DELETED = new File(DIR_TEST, "removed");
-
- private static X509Certificate CA1;
- private static X509Certificate CA2;
-
- private static KeyStore.PrivateKeyEntry PRIVATE;
- private static X509Certificate[] CHAIN;
-
- private static X509Certificate CA3_WITH_CA1_SUBJECT;
- private static String ALIAS_SYSTEM_CA1;
- private static String ALIAS_SYSTEM_CA2;
- private static String ALIAS_USER_CA1;
- private static String ALIAS_USER_CA2;
-
- private static String ALIAS_SYSTEM_CHAIN0;
- private static String ALIAS_SYSTEM_CHAIN1;
- private static String ALIAS_SYSTEM_CHAIN2;
- private static String ALIAS_USER_CHAIN0;
- private static String ALIAS_USER_CHAIN1;
- private static String ALIAS_USER_CHAIN2;
-
- private static String ALIAS_SYSTEM_CA3;
- private static String ALIAS_SYSTEM_CA3_COLLISION;
- private static String ALIAS_USER_CA3;
- private static String ALIAS_USER_CA3_COLLISION;
-
- private static X509Certificate getCa1() {
- initCerts();
- return CA1;
- }
- private static X509Certificate getCa2() {
- initCerts();
- return CA2;
- }
-
- private static KeyStore.PrivateKeyEntry getPrivate() {
- initCerts();
- return PRIVATE;
- }
- private static X509Certificate[] getChain() {
- initCerts();
- return CHAIN;
- }
-
- private static X509Certificate getCa3WithCa1Subject() {
- initCerts();
- return CA3_WITH_CA1_SUBJECT;
- }
-
- private static String getAliasSystemCa1() {
- initCerts();
- return ALIAS_SYSTEM_CA1;
- }
- private static String getAliasSystemCa2() {
- initCerts();
- return ALIAS_SYSTEM_CA2;
- }
- private static String getAliasUserCa1() {
- initCerts();
- return ALIAS_USER_CA1;
- }
- private static String getAliasUserCa2() {
- initCerts();
- return ALIAS_USER_CA2;
- }
-
- private static String getAliasSystemChain0() {
- initCerts();
- return ALIAS_SYSTEM_CHAIN0;
- }
- private static String getAliasSystemChain1() {
- initCerts();
- return ALIAS_SYSTEM_CHAIN1;
- }
- private static String getAliasSystemChain2() {
- initCerts();
- return ALIAS_SYSTEM_CHAIN2;
- }
- private static String getAliasUserChain0() {
- initCerts();
- return ALIAS_USER_CHAIN0;
- }
- private static String getAliasUserChain1() {
- initCerts();
- return ALIAS_USER_CHAIN1;
- }
- private static String getAliasUserChain2() {
- initCerts();
- return ALIAS_USER_CHAIN2;
- }
-
- private static String getAliasSystemCa3() {
- initCerts();
- return ALIAS_SYSTEM_CA3;
- }
- private static String getAliasSystemCa3Collision() {
- initCerts();
- return ALIAS_SYSTEM_CA3_COLLISION;
- }
- private static String getAliasUserCa3() {
- initCerts();
- return ALIAS_USER_CA3;
- }
- private static String getAliasUserCa3Collision() {
- initCerts();
- return ALIAS_USER_CA3_COLLISION;
- }
-
- /**
- * Lazily create shared test certificates.
- */
- private static synchronized void initCerts() {
- if (CA1 != null) {
- return;
- }
- try {
- CA1 = TestKeyStore.getClient().getRootCertificate("RSA");
- CA2 = TestKeyStore.getClientCA2().getRootCertificate("RSA");
- PRIVATE = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- CHAIN = (X509Certificate[]) PRIVATE.getCertificateChain();
- CA3_WITH_CA1_SUBJECT = new TestKeyStore.Builder()
- .aliasPrefix("unused")
- .subject(CA1.getSubjectX500Principal())
- .ca(true)
- .build().getRootCertificate("RSA");
-
-
- ALIAS_SYSTEM_CA1 = alias(false, CA1, 0);
- ALIAS_SYSTEM_CA2 = alias(false, CA2, 0);
- ALIAS_USER_CA1 = alias(true, CA1, 0);
- ALIAS_USER_CA2 = alias(true, CA2, 0);
-
- ALIAS_SYSTEM_CHAIN0 = alias(false, getChain()[0], 0);
- ALIAS_SYSTEM_CHAIN1 = alias(false, getChain()[1], 0);
- ALIAS_SYSTEM_CHAIN2 = alias(false, getChain()[2], 0);
- ALIAS_USER_CHAIN0 = alias(true, getChain()[0], 0);
- ALIAS_USER_CHAIN1 = alias(true, getChain()[1], 0);
- ALIAS_USER_CHAIN2 = alias(true, getChain()[2], 0);
-
- ALIAS_SYSTEM_CA3 = alias(false, CA3_WITH_CA1_SUBJECT, 0);
- ALIAS_SYSTEM_CA3_COLLISION = alias(false, CA3_WITH_CA1_SUBJECT, 1);
- ALIAS_USER_CA3 = alias(true, CA3_WITH_CA1_SUBJECT, 0);
- ALIAS_USER_CA3_COLLISION = alias(true, CA3_WITH_CA1_SUBJECT, 1);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private TrustedCertificateStore store;
-
- @Override protected void setUp() {
- setupStore();
- }
-
- private void setupStore() {
- DIR_SYSTEM.mkdirs();
- createStore();
- }
-
- private void createStore() {
- store = new TrustedCertificateStore(DIR_SYSTEM, DIR_ADDED, DIR_DELETED);
- }
-
- @Override protected void tearDown() {
- cleanStore();
- }
-
- private void cleanStore() {
- for (File dir : new File[] { DIR_SYSTEM, DIR_ADDED, DIR_DELETED, DIR_TEST }) {
- File[] files = dir.listFiles();
- if (files == null) {
- continue;
- }
- for (File file : files) {
- assertTrue(file.delete());
- }
- }
- store = null;
- }
-
- private void resetStore() {
- cleanStore();
- setupStore();
- }
-
- public void testEmptyDirectories() throws Exception {
- assertEmpty();
- }
-
- public void testOneSystemOneDeleted() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
- }
-
- public void testTwoSystemTwoDeleted() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.deleteCertificateEntry(getAliasSystemCa1());
- install(getCa2(), getAliasSystemCa2());
- store.deleteCertificateEntry(getAliasSystemCa2());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
- assertDeleted(getCa2(), getAliasSystemCa2());
- }
-
- public void testPartialFileIsIgnored() throws Exception {
- File file = file(getAliasSystemCa1());
- OutputStream os = new FileOutputStream(file);
- os.write(0);
- os.close();
- assertTrue(file.exists());
- assertEmpty();
- assertTrue(file.exists());
- }
-
- private void assertEmpty() throws Exception {
- try {
- store.getCertificate(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertNull(store.getCertificate(""));
-
- try {
- store.getCreationDate(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertNull(store.getCreationDate(""));
-
- Set<String> s = store.aliases();
- assertNotNull(s);
- assertTrue(s.isEmpty());
- assertAliases();
-
- Set<String> u = store.userAliases();
- assertNotNull(u);
- assertTrue(u.isEmpty());
-
- try {
- store.containsAlias(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertFalse(store.containsAlias(""));
-
- assertNull(store.getCertificateAlias(null));
- assertNull(store.getCertificateAlias(getCa1()));
-
- try {
- store.isTrustAnchor(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertFalse(store.isTrustAnchor(getCa1()));
-
- try {
- store.findIssuer(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertNull(store.findIssuer(getCa1()));
-
- try {
- store.installCertificate(null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- store.deleteCertificateEntry(null);
- store.deleteCertificateEntry("");
-
- String[] userFiles = DIR_ADDED.list();
- assertTrue(userFiles == null || userFiles.length == 0);
- }
-
- public void testTwoSystem() throws Exception {
- testTwo(getCa1(), getAliasSystemCa1(),
- getCa2(), getAliasSystemCa2());
- }
-
- public void testTwoUser() throws Exception {
- testTwo(getCa1(), getAliasUserCa1(),
- getCa2(), getAliasUserCa2());
- }
-
- public void testOneSystemOneUser() throws Exception {
- testTwo(getCa1(), getAliasSystemCa1(),
- getCa2(), getAliasUserCa2());
- }
-
- public void testTwoSystemSameSubject() throws Exception {
- testTwo(getCa1(), getAliasSystemCa1(),
- getCa3WithCa1Subject(), getAliasSystemCa3Collision());
- }
-
- public void testTwoUserSameSubject() throws Exception {
- testTwo(getCa1(), getAliasUserCa1(),
- getCa3WithCa1Subject(), getAliasUserCa3Collision());
-
- store.deleteCertificateEntry(getAliasUserCa1());
- assertDeleted(getCa1(), getAliasUserCa1());
- assertTombstone(getAliasUserCa1());
- assertRootCa(getCa3WithCa1Subject(), getAliasUserCa3Collision());
- assertAliases(getAliasUserCa3Collision());
-
- store.deleteCertificateEntry(getAliasUserCa3Collision());
- assertDeleted(getCa3WithCa1Subject(), getAliasUserCa3Collision());
- assertNoTombstone(getAliasUserCa3Collision());
- assertNoTombstone(getAliasUserCa1());
- assertEmpty();
- }
-
- public void testOneSystemOneUserSameSubject() throws Exception {
- testTwo(getCa1(), getAliasSystemCa1(),
- getCa3WithCa1Subject(), getAliasUserCa3());
- testTwo(getCa1(), getAliasUserCa1(),
- getCa3WithCa1Subject(), getAliasSystemCa3());
- }
-
- private void testTwo(X509Certificate x1, String alias1,
- X509Certificate x2, String alias2) {
- install(x1, alias1);
- install(x2, alias2);
- assertRootCa(x1, alias1);
- assertRootCa(x2, alias2);
- assertAliases(alias1, alias2);
- }
-
-
- public void testOneSystemOneUserOneDeleted() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.installCertificate(getCa2());
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertDeleted(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa2(), getAliasUserCa2());
- assertAliases(getAliasUserCa2());
- }
-
- public void testOneSystemOneUserOneDeletedSameSubject() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.installCertificate(getCa3WithCa1Subject());
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertDeleted(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa3WithCa1Subject(), getAliasUserCa3());
- assertAliases(getAliasUserCa3());
- }
-
- public void testUserMaskingSystem() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- install(getCa1(), getAliasUserCa1());
- assertMasked(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa1(), getAliasUserCa1());
- assertAliases(getAliasSystemCa1(), getAliasUserCa1());
- }
-
- public void testChain() throws Exception {
- testChain(getAliasSystemChain1(), getAliasSystemChain2());
- testChain(getAliasSystemChain1(), getAliasUserChain2());
- testChain(getAliasUserChain1(), getAliasSystemCa1());
- testChain(getAliasUserChain1(), getAliasUserChain2());
- }
-
- private void testChain(String alias1, String alias2) throws Exception {
- install(getChain()[1], alias1);
- install(getChain()[2], alias2);
- assertIntermediateCa(getChain()[1], alias1);
- assertRootCa(getChain()[2], alias2);
- assertAliases(alias1, alias2);
- assertEquals(getChain()[2], store.findIssuer(getChain()[1]));
- assertEquals(getChain()[1], store.findIssuer(getChain()[0]));
-
- X509Certificate[] expected = getChain();
- List<X509Certificate> actualList = store.getCertificateChain(expected[0]);
-
- assertEquals("Generated CA list should be same length", expected.length, actualList.size());
- for (int i = 0; i < expected.length; i++) {
- assertEquals("Chain value should be the same for position " + i, expected[i],
- actualList.get(i));
- }
- resetStore();
- }
-
- public void testMissingSystemDirectory() throws Exception {
- cleanStore();
- createStore();
- assertEmpty();
- }
-
- public void testWithExistingUserDirectories() throws Exception {
- DIR_ADDED.mkdirs();
- DIR_DELETED.mkdirs();
- install(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
- }
-
- public void testIsTrustAnchorWithReissuedgetCa() throws Exception {
- PublicKey publicKey = getPrivate().getCertificate().getPublicKey();
- PrivateKey privateKey = getPrivate().getPrivateKey();
- String name = "CN=CA4";
- X509Certificate ca1 = TestKeyStore.createCa(publicKey, privateKey, name);
- Thread.sleep(1 * 1000); // wait to ensure CAs vary by expiration
- X509Certificate ca2 = TestKeyStore.createCa(publicKey, privateKey, name);
- assertFalse(ca1.equals(ca2));
-
- String systemAlias = alias(false, ca1, 0);
- install(ca1, systemAlias);
- assertRootCa(ca1, systemAlias);
- assertTrue(store.isTrustAnchor(ca2));
- assertEquals(ca1, store.findIssuer(ca2));
- resetStore();
-
- String userAlias = alias(true, ca1, 0);
- store.installCertificate(ca1);
- assertRootCa(ca1, userAlias);
- assertTrue(store.isTrustAnchor(ca2));
- assertEquals(ca1, store.findIssuer(ca2));
- resetStore();
- }
-
- public void testInstallEmpty() throws Exception {
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasUserCa1());
- assertAliases(getAliasUserCa1());
-
- // reinstalling should not change anything
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasUserCa1());
- assertAliases(getAliasUserCa1());
- }
-
- public void testInstallEmptySystemExists() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
-
- // reinstalling should not affect system CA
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
-
- }
-
- public void testInstallEmptyDeletedSystemExists() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
-
- // installing should restore deleted system CA
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
- }
-
- public void testDeleteEmpty() throws Exception {
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
- }
-
- public void testDeleteUser() throws Exception {
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasUserCa1());
- assertAliases(getAliasUserCa1());
-
- store.deleteCertificateEntry(getAliasUserCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasUserCa1());
- assertNoTombstone(getAliasUserCa1());
- }
-
- public void testDeleteSystem() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
-
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
-
- // deleting again should not change anything
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
- }
-
- public void testIsUserAddedCertificate() throws Exception {
- assertFalse(store.isUserAddedCertificate(getCa1()));
- assertFalse(store.isUserAddedCertificate(getCa2()));
- install(getCa1(), getAliasSystemCa1());
- assertFalse(store.isUserAddedCertificate(getCa1()));
- assertFalse(store.isUserAddedCertificate(getCa2()));
- install(getCa1(), getAliasUserCa1());
- assertTrue(store.isUserAddedCertificate(getCa1()));
- assertFalse(store.isUserAddedCertificate(getCa2()));
- install(getCa2(), getAliasUserCa2());
- assertTrue(store.isUserAddedCertificate(getCa1()));
- assertTrue(store.isUserAddedCertificate(getCa2()));
- store.deleteCertificateEntry(getAliasUserCa1());
- assertFalse(store.isUserAddedCertificate(getCa1()));
- assertTrue(store.isUserAddedCertificate(getCa2()));
- store.deleteCertificateEntry(getAliasUserCa2());
- assertFalse(store.isUserAddedCertificate(getCa1()));
- assertFalse(store.isUserAddedCertificate(getCa2()));
- }
-
- private void assertRootCa(X509Certificate x, String alias) {
- assertIntermediateCa(x, alias);
- assertEquals(x, store.findIssuer(x));
- }
-
- private void assertTrusted(X509Certificate x, String alias) {
- assertEquals(x, store.getCertificate(alias));
- assertEquals(file(alias).lastModified(), store.getCreationDate(alias).getTime());
- assertTrue(store.containsAlias(alias));
- assertTrue(store.isTrustAnchor(x));
- }
-
- private void assertIntermediateCa(X509Certificate x, String alias) {
- assertTrusted(x, alias);
- assertEquals(alias, store.getCertificateAlias(x));
- }
-
- private void assertMasked(X509Certificate x, String alias) {
- assertTrusted(x, alias);
- assertFalse(alias.equals(store.getCertificateAlias(x)));
- }
-
- private void assertDeleted(X509Certificate x, String alias) {
- assertNull(store.getCertificate(alias));
- assertFalse(store.containsAlias(alias));
- assertNull(store.getCertificateAlias(x));
- assertFalse(store.isTrustAnchor(x));
- assertEquals(store.allSystemAliases().contains(alias),
- store.getCertificate(alias, true) != null);
- }
-
- private void assertTombstone(String alias) {
- assertTrue(TrustedCertificateStore.isUser(alias));
- File file = file(alias);
- assertTrue(file.exists());
- assertEquals(0, file.length());
- }
-
- private void assertNoTombstone(String alias) {
- assertTrue(TrustedCertificateStore.isUser(alias));
- assertFalse(file(alias).exists());
- }
-
- private void assertAliases(String... aliases) {
- Set<String> expected = new HashSet<String>(Arrays.asList(aliases));
- Set<String> actual = new HashSet<String>();
- for (String alias : store.aliases()) {
- boolean system = TrustedCertificateStore.isSystem(alias);
- boolean user = TrustedCertificateStore.isUser(alias);
- if (system || user) {
- assertEquals(system, store.allSystemAliases().contains(alias));
- assertEquals(user, store.userAliases().contains(alias));
- actual.add(alias);
- } else {
- throw new AssertionError(alias);
- }
- }
- assertEquals(expected, actual);
- }
-
- /**
- * format a certificate alias
- */
- private static String alias(boolean user, X509Certificate x, int index) {
- String prefix = user ? "user:" : "system:";
-
- X500Principal subject = x.getSubjectX500Principal();
- int intHash = NativeCrypto.X509_NAME_hash_old(subject);
- String strHash = IntegralToString.intToHexString(intHash, false, 8);
-
- return prefix + strHash + '.' + index;
- }
-
- /**
- * Install certificate under specified alias
- */
- private static void install(X509Certificate x, String alias) {
- try {
- File file = file(alias);
- file.getParentFile().mkdirs();
- OutputStream out = new FileOutputStream(file);
- out.write(x.getEncoded());
- out.close();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Compute file for an alias
- */
- private static File file(String alias) {
- File dir;
- if (TrustedCertificateStore.isSystem(alias)) {
- dir = DIR_SYSTEM;
- } else if (TrustedCertificateStore.isUser(alias)) {
- dir = DIR_ADDED;
- } else {
- throw new IllegalArgumentException(alias);
- }
-
- int index = alias.lastIndexOf(":");
- if (index == -1) {
- throw new IllegalArgumentException(alias);
- }
- String filename = alias.substring(index+1);
-
- return new File(dir, filename);
- }
-}
diff --git a/dalvik/src/main/java/dalvik/annotation/BrokenTest.java b/dalvik/src/main/java/dalvik/annotation/BrokenTest.java
index 401d652..16788d0 100644
--- a/dalvik/src/main/java/dalvik/annotation/BrokenTest.java
+++ b/dalvik/src/main/java/dalvik/annotation/BrokenTest.java
@@ -25,6 +25,8 @@ import java.lang.annotation.Target;
* Marks a test case as broken. This means the test case should be fixed.
*
* @hide
+ *
+ * @deprecated - use expectations/brokentests.txt instead
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
diff --git a/dalvik/src/main/java/dalvik/annotation/SideEffect.java b/dalvik/src/main/java/dalvik/annotation/SideEffect.java
index b92e9bc..2d691e3 100644
--- a/dalvik/src/main/java/dalvik/annotation/SideEffect.java
+++ b/dalvik/src/main/java/dalvik/annotation/SideEffect.java
@@ -27,6 +27,8 @@ import java.lang.annotation.Target;
* isolated manner.
*
* @hide
+ *
+ * @deprecated - use expectations/brokentests.txt instead
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
diff --git a/dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java b/dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java
index 1209b2e..349fbed 100644
--- a/dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java
+++ b/dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java
@@ -39,8 +39,6 @@ public final class OpcodeInfo {
* <p><b>Note:</b>: This is constant in any given VM incarnation,
* but it is subject to change over time, so it is not appropriate
* to represent as a compile-time constant value.</p>
- *
- * @see dalvik.system.VMDebug.getInstructionCount()
*/
public static final int MAXIMUM_PACKED_VALUE;
@@ -60,22 +58,17 @@ public final class OpcodeInfo {
}
/**
- * This class is not instantiable.
+ * Backwards compatibility stub for obsolete interpreter functionality.
+ * @hide
*/
- private OpcodeInfo() {
- // This space intentionally left blank.
+ public static boolean isInvoke(int packedOpcode) {
+ return false;
}
/**
- * Returns whether the given packed opcode value represents a
- * method invocation operation. This includes most things that
- * look like method invocation at the source level, but it notably
- * excludes methods that are implemented directly in the VM as
- * well as ones the VM knows to have empty implementations.
- *
- * @hide Unclear if this is useful enough to publish as supported API.
- *
- * @param opcode one of the values defined in {@link Opcodes}
+ * This class is not instantiable.
*/
- public static native boolean isInvoke(int packedOpcode);
+ private OpcodeInfo() {
+ // This space intentionally left blank.
+ }
}
diff --git a/dalvik/src/main/java/dalvik/system/DexClassLoader.java b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
index ac2a70a..a645f42 100644
--- a/dalvik/src/main/java/dalvik/system/DexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
@@ -24,9 +24,9 @@ import java.io.File;
* installed as part of an application.
*
* <p>This class loader requires an application-private, writable directory to
- * cache optimized classes. Use {@code Context.getDir(String, int)} to create
+ * cache optimized classes. Use {@code Context.getCodeCacheDir()} to create
* such a directory: <pre> {@code
- * File dexOutputDir = context.getDir("dex", 0);
+ * File dexOutputDir = context.getCodeCacheDir();
* }</pre>
*
* <p><strong>Do not cache optimized classes on external storage.</strong>
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index d2fd5da..86bb531 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -16,15 +16,15 @@
package dalvik.system;
+import android.system.ErrnoException;
+import android.system.StructStat;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
-import libcore.io.ErrnoException;
import libcore.io.Libcore;
-import libcore.io.StructStat;
/**
* Manipulates DEX files. The class is similar in principle to
@@ -34,7 +34,7 @@ import libcore.io.StructStat;
* read-only by the VM.
*/
public final class DexFile {
- private int mCookie;
+ private long mCookie;
private final String mFileName;
private final CloseGuard guard = CloseGuard.get();
@@ -80,7 +80,7 @@ public final class DexFile {
mCookie = openDexFile(fileName, null, 0);
mFileName = fileName;
guard.open("close");
- //System.out.println("DEX FILE cookie is " + mCookie);
+ //System.out.println("DEX FILE cookie is " + mCookie + " fileName=" + fileName);
}
/**
@@ -111,7 +111,7 @@ public final class DexFile {
mCookie = openDexFile(sourceName, outputName, flags);
mFileName = sourceName;
guard.open("close");
- //System.out.println("DEX FILE cookie is " + mCookie);
+ //System.out.println("DEX FILE cookie is " + mCookie + " sourceName=" + sourceName + " outputName=" + outputName);
}
/**
@@ -160,6 +160,10 @@ public final class DexFile {
return mFileName;
}
+ @Override public String toString() {
+ return getName();
+ }
+
/**
* Closes the DEX file.
* <p>
@@ -215,7 +219,7 @@ public final class DexFile {
return defineClass(name, loader, mCookie, suppressed);
}
- private static Class defineClass(String name, ClassLoader loader, int cookie,
+ private static Class defineClass(String name, ClassLoader loader, long cookie,
List<Throwable> suppressed) {
Class result = null;
try {
@@ -232,9 +236,6 @@ public final class DexFile {
return result;
}
- private static native Class defineClassNative(String name, ClassLoader loader, int cookie)
- throws ClassNotFoundException, NoClassDefFoundError;
-
/**
* Enumerate the names of the classes in this DEX file.
*
@@ -266,9 +267,6 @@ public final class DexFile {
}
}
- /* return a String array with class names */
- native private static String[] getClassNameList(int cookie);
-
/**
* Called when the class is finalized. Makes sure the DEX file is closed.
*
@@ -287,24 +285,27 @@ public final class DexFile {
}
}
+
/*
* Open a DEX file. The value returned is a magic VM cookie. On
* failure, an IOException is thrown.
*/
- private static int openDexFile(String sourceName, String outputName,
- int flags) throws IOException {
- return openDexFileNative(new File(sourceName).getCanonicalPath(),
- (outputName == null) ? null : new File(outputName).getCanonicalPath(),
+ private static long openDexFile(String sourceName, String outputName, int flags) throws IOException {
+ // Use absolute paths to enable the use of relative paths when testing on host.
+ return openDexFileNative(new File(sourceName).getAbsolutePath(),
+ (outputName == null) ? null : new File(outputName).getAbsolutePath(),
flags);
}
- native private static int openDexFileNative(String sourceName, String outputName,
- int flags) throws IOException;
-
+ private static native void closeDexFile(long cookie);
+ private static native Class defineClassNative(String name, ClassLoader loader, long cookie)
+ throws ClassNotFoundException, NoClassDefFoundError;
+ private static native String[] getClassNameList(long cookie);
/*
- * Close DEX file.
+ * Open a DEX file. The value returned is a magic VM cookie. On
+ * failure, an IOException is thrown.
*/
- native private static void closeDexFile(int cookie);
+ private static native long openDexFileNative(String sourceName, String outputName, int flags);
/**
* Returns true if the VM believes that the apk/jar file is out of date
@@ -320,6 +321,52 @@ public final class DexFile {
* @throws dalvik.system.StaleDexCacheError if the optimized dex file
* is stale but exists on a read-only partition.
*/
- native public static boolean isDexOptNeeded(String fileName)
+ public static native boolean isDexOptNeeded(String fileName)
+ throws FileNotFoundException, IOException;
+
+ /**
+ * See {@link #isDexOptNeededInternal(String, String, String, boolean)}.
+ *
+ * @hide
+ */
+ public static final byte UP_TO_DATE = 0;
+
+ /**
+ * See {@link #isDexOptNeededInternal(String, String, String, boolean)}.
+ *
+ * @hide
+ */
+ public static final byte PATCHOAT_NEEDED = 1;
+
+ /**
+ * See {@link #isDexOptNeededInternal(String, String, String, boolean)}.
+ *
+ * @hide
+ */
+ public static final byte DEXOPT_NEEDED = 2;
+
+ /**
+ * Returns UP_TO_DATE if the VM believes that the apk/jar file
+ * is up to date, PATCHOAT_NEEDED if it believes that the file is up
+ * to date but it must be relocated to match the base address offset,
+ * and DEXOPT_NEEDED if it believes that it is out of date and should
+ * be passed through "dexopt" again.
+ *
+ * @param fileName the absolute path to the apk/jar file to examine.
+ * @return DEXOPT_NEEDED if dexopt should be called on the file,
+ * PATCHOAT_NEEDED if we need to run "patchoat" on it and
+ * UP_TO_DATE otherwise.
+ * @throws java.io.FileNotFoundException if fileName is not readable,
+ * not a file, or not present.
+ * @throws java.io.IOException if fileName is not a valid apk/jar file or
+ * if problems occur while parsing it.
+ * @throws java.lang.NullPointerException if fileName is null.
+ * @throws dalvik.system.StaleDexCacheError if the optimized dex file
+ * is stale but exists on a read-only partition.
+ *
+ * @hide
+ */
+ public static native byte isDexOptNeededInternal(String fileName, String pkgname,
+ String instructionSet, boolean defer)
throws FileNotFoundException, IOException;
}
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index ff0be41..e364e40 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -16,6 +16,8 @@
package dalvik.system;
+import android.system.ErrnoException;
+import android.system.StructStat;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -26,11 +28,9 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipFile;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;
-import libcore.io.StructStat;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* A pair of lists of entries, associated with a {@code ClassLoader}.
@@ -47,9 +47,6 @@ import static libcore.io.OsConstants.*;
*/
/*package*/ final class DexPathList {
private static final String DEX_SUFFIX = ".dex";
- private static final String JAR_SUFFIX = ".jar";
- private static final String ZIP_SUFFIX = ".zip";
- private static final String APK_SUFFIX = ".apk";
/** class definition context */
private final ClassLoader definingContext;
@@ -215,34 +212,36 @@ import static libcore.io.OsConstants.*;
DexFile dex = null;
String name = file.getName();
- if (name.endsWith(DEX_SUFFIX)) {
- // Raw dex file (not inside a zip/jar).
- try {
- dex = loadDexFile(file, optimizedDirectory);
- } catch (IOException ex) {
- System.logE("Unable to load dex file: " + file, ex);
- }
- } else if (name.endsWith(APK_SUFFIX) || name.endsWith(JAR_SUFFIX)
- || name.endsWith(ZIP_SUFFIX)) {
- zip = file;
-
- try {
- dex = loadDexFile(file, optimizedDirectory);
- } catch (IOException suppressed) {
- /*
- * IOException might get thrown "legitimately" by the DexFile constructor if the
- * zip file turns out to be resource-only (that is, no classes.dex file in it).
- * Let dex == null and hang on to the exception to add to the tea-leaves for
- * when findClass returns null.
- */
- suppressedExceptions.add(suppressed);
- }
- } else if (file.isDirectory()) {
+ if (file.isDirectory()) {
// We support directories for looking up resources.
// This is only useful for running libcore tests.
elements.add(new Element(file, true, null, null));
+ } else if (file.isFile()){
+ if (name.endsWith(DEX_SUFFIX)) {
+ // Raw dex file (not inside a zip/jar).
+ try {
+ dex = loadDexFile(file, optimizedDirectory);
+ } catch (IOException ex) {
+ System.logE("Unable to load dex file: " + file, ex);
+ }
+ } else {
+ zip = file;
+
+ try {
+ dex = loadDexFile(file, optimizedDirectory);
+ } catch (IOException suppressed) {
+ /*
+ * IOException might get thrown "legitimately" by the DexFile constructor if
+ * the zip file turns out to be resource-only (that is, no classes.dex file
+ * in it).
+ * Let dex == null and hang on to the exception to add to the tea-leaves for
+ * when findClass returns null.
+ */
+ suppressedExceptions.add(suppressed);
+ }
+ }
} else {
- System.logW("Unknown file type for: " + file);
+ System.logW("ClassLoader referenced unknown path: " + file);
}
if ((zip != null) || (dex != null)) {
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index a46119f..4b606e6 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -156,9 +156,13 @@ public final class VMDebug {
* as <code>0</code>, it defaults to 8MB.
* @param flags flags to control method tracing. The only one that
* is currently defined is {@link #TRACE_COUNT_ALLOCS}.
+ * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
+ * method instrumentation is used.
+ * @param intervalUs the time between samples in microseconds when
+ * sampling is enabled.
*/
- public static void startMethodTracing(String traceFileName, int bufferSize, int flags) {
- startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags);
+ public static void startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
+ startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
}
/**
@@ -166,11 +170,11 @@ public final class VMDebug {
* FileDescriptor in which the trace is written. The file name is also
* supplied simply for logging. Makes a dup of the file descriptor.
*/
- public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize, int flags) {
+ public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
if (fd == null) {
throw new NullPointerException("fd == null");
}
- startMethodTracingFd(traceFileName, fd, checkBufferSize(bufferSize), flags);
+ startMethodTracingFd(traceFileName, fd, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
}
/**
@@ -194,8 +198,8 @@ public final class VMDebug {
}
private static native void startMethodTracingDdmsImpl(int bufferSize, int flags, boolean samplingEnabled, int intervalUs);
- private static native void startMethodTracingFd(String traceFileName, FileDescriptor fd, int bufferSize, int flags);
- private static native void startMethodTracingFilename(String traceFileName, int bufferSize, int flags);
+ private static native void startMethodTracingFd(String traceFileName, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs);
+ private static native void startMethodTracingFilename(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs);
/**
* Determine whether method tracing is currently active and what type is
diff --git a/dalvik/src/main/java/dalvik/system/Zygote.java b/dalvik/src/main/java/dalvik/system/Zygote.java
deleted file mode 100644
index ea9dbdc..0000000
--- a/dalvik/src/main/java/dalvik/system/Zygote.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.system;
-
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-
-import java.io.File;
-
-/**
- * Provides access to the Dalvik "zygote" feature, which allows a VM instance to
- * be partially initialized and then fork()'d from the partially initialized
- * state.
- *
- * @hide
- */
-public class Zygote {
- /*
- * Bit values for "debugFlags" argument. The definitions are duplicated
- * in the native code.
- */
- /** enable debugging over JDWP */
- public static final int DEBUG_ENABLE_DEBUGGER = 1;
- /** enable JNI checks */
- public static final int DEBUG_ENABLE_CHECKJNI = 1 << 1;
- /** enable Java programming language "assert" statements */
- public static final int DEBUG_ENABLE_ASSERT = 1 << 2;
- /** disable the JIT compiler */
- public static final int DEBUG_ENABLE_SAFEMODE = 1 << 3;
- /** Enable logging of third-party JNI activity. */
- public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
-
- /** No external storage should be mounted. */
- public static final int MOUNT_EXTERNAL_NONE = 0;
- /** Single-user external storage should be mounted. */
- public static final int MOUNT_EXTERNAL_SINGLEUSER = 1;
- /** Multi-user external storage should be mounted. */
- public static final int MOUNT_EXTERNAL_MULTIUSER = 2;
- /** All multi-user external storage should be mounted. */
- public static final int MOUNT_EXTERNAL_MULTIUSER_ALL = 3;
-
- /**
- * When set by the system server, all subsequent apps will be launched in
- * VM safe mode.
- */
- public static boolean systemInSafeMode = false;
-
- private Zygote() {}
-
- private static void preFork() {
- Daemons.stop();
- waitUntilAllThreadsStopped();
- }
-
- /**
- * We must not fork until we're single-threaded again. Wait until /proc shows we're
- * down to just one thread.
- */
- private static void waitUntilAllThreadsStopped() {
- File tasks = new File("/proc/self/task");
- while (tasks.list().length > 1) {
- try {
- // Experimentally, booting and playing about with a stingray, I never saw us
- // go round this loop more than once with a 10ms sleep.
- Thread.sleep(10);
- } catch (InterruptedException ignored) {
- }
- }
- }
-
- private static void postFork() {
- Daemons.start();
- }
-
- /**
- * Forks a new Zygote instance, but does not leave the zygote mode.
- * The current VM must have been started with the -Xzygote flag. The
- * new child is expected to eventually call forkAndSpecialize()
- *
- * @return 0 if this is the child, pid of the child
- * if this is the parent, or -1 on error
- */
- public static int fork() {
- preFork();
- int pid = nativeFork();
- postFork();
- return pid;
- }
-
- native public static int nativeFork();
-
- /**
- * Forks a new VM instance. The current VM must have been started
- * with the -Xzygote flag. <b>NOTE: new instance keeps all
- * root capabilities. The new process is expected to call capset()</b>.
- *
- * @param uid the UNIX uid that the new process should setuid() to after
- * fork()ing and and before spawning any threads.
- * @param gid the UNIX gid that the new process should setgid() to after
- * fork()ing and and before spawning any threads.
- * @param gids null-ok; a list of UNIX gids that the new process should
- * setgroups() to after fork and before spawning any threads.
- * @param debugFlags bit flags that enable debugging features.
- * @param rlimits null-ok an array of rlimit tuples, with the second
- * dimension having a length of 3 and representing
- * (resource, rlim_cur, rlim_max). These are set via the posix
- * setrlimit(2) call.
- * @param seInfo null-ok a string specifying SELinux information for
- * the new process.
- * @param niceName null-ok a string specifying the process name.
- *
- * @return 0 if this is the child, pid of the child
- * if this is the parent, or -1 on error.
- */
- public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, int mountExternal, String seInfo, String niceName) {
- preFork();
- int pid = nativeForkAndSpecialize(
- uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName);
- postFork();
- return pid;
- }
-
- native public static int nativeForkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, int mountExternal, String seInfo, String niceName);
-
- /**
- * Special method to start the system server process. In addition to the
- * common actions performed in forkAndSpecialize, the pid of the child
- * process is recorded such that the death of the child process will cause
- * zygote to exit.
- *
- * @param uid the UNIX uid that the new process should setuid() to after
- * fork()ing and and before spawning any threads.
- * @param gid the UNIX gid that the new process should setgid() to after
- * fork()ing and and before spawning any threads.
- * @param gids null-ok; a list of UNIX gids that the new process should
- * setgroups() to after fork and before spawning any threads.
- * @param debugFlags bit flags that enable debugging features.
- * @param rlimits null-ok an array of rlimit tuples, with the second
- * dimension having a length of 3 and representing
- * (resource, rlim_cur, rlim_max). These are set via the posix
- * setrlimit(2) call.
- * @param permittedCapabilities argument for setcap()
- * @param effectiveCapabilities argument for setcap()
- *
- * @return 0 if this is the child, pid of the child
- * if this is the parent, or -1 on error.
- */
- public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
- preFork();
- int pid = nativeForkSystemServer(
- uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
- postFork();
- return pid;
- }
-
- native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
-
- /**
- * Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.
- * This method throws a runtime exception if exec() failed, otherwise, this
- * method never returns.
- *
- * @param command The shell command to execute.
- */
- public static void execShell(String command) {
- String[] args = { "/system/bin/sh", "-c", command };
- try {
- Libcore.os.execv(args[0], args);
- } catch (ErrnoException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Appends quotes shell arguments to the specified string builder.
- * The arguments are quoted using single-quotes, escaped if necessary,
- * prefixed with a space, and appended to the command.
- *
- * @param command A string builder for the shell command being constructed.
- * @param args An array of argument strings to be quoted and appended to the command.
- * @see #execShell(String)
- */
- public static void appendQuotedShellArgs(StringBuilder command, String[] args) {
- for (String arg : args) {
- command.append(" '").append(arg.replace("'", "'\\''")).append("'");
- }
- }
-}
diff --git a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
new file mode 100644
index 0000000..11ea286
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+import java.io.File;
+
+/**
+ * Provides hooks for the zygote to call back into the runtime to perform
+ * parent or child specific initialization..
+ *
+ * @hide
+ */
+public final class ZygoteHooks {
+ private long token;
+
+ /**
+ * Called by the zygote prior to every fork. Each call to {@code preFork}
+ * is followed by a matching call to {@link #postForkChild(int)} on the child
+ * process and {@link #postForkCommon()} on both the parent and the child
+ * process. {@code postForkCommon} is called after {@code postForkChild} in
+ * the child process.
+ */
+ public void preFork() {
+ Daemons.stop();
+ waitUntilAllThreadsStopped();
+ token = nativePreFork();
+ }
+
+ /**
+ * Called by the zygote in the child process after every fork. The debug
+ * flags from {@code debugFlags} are applied to the child process. The string
+ * {@code instructionSet} determines whether to use a native bridge.
+ */
+ public void postForkChild(int debugFlags, String instructionSet) {
+ nativePostForkChild(token, debugFlags, instructionSet);
+ }
+
+ /**
+ * Called by the zygote in both the parent and child processes after
+ * every fork. In the child process, this method is called after
+ * {@code postForkChild}.
+ */
+ public void postForkCommon() {
+ Daemons.start();
+ }
+
+ private static native long nativePreFork();
+ private static native void nativePostForkChild(long token, int debugFlags,
+ String instructionSet);
+
+ /**
+ * We must not fork until we're single-threaded again. Wait until /proc shows we're
+ * down to just one thread.
+ */
+ private static void waitUntilAllThreadsStopped() {
+ File tasks = new File("/proc/self/task");
+ while (tasks.list().length > 1) {
+ try {
+ // Experimentally, booting and playing about with a stingray, I never saw us
+ // go round this loop more than once with a 10ms sleep.
+ Thread.sleep(10);
+ } catch (InterruptedException ignored) {
+ }
+ }
+ }
+}
diff --git a/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java b/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java
new file mode 100644
index 0000000..b5bf380
--- /dev/null
+++ b/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package dalvik.system;
+
+import dalvik.system.CloseGuard.Reporter;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Provides support for detecting issues found by {@link CloseGuard} from within tests.
+ *
+ * <p>This is a best effort as it relies on both {@link CloseGuard} being enabled and being able to
+ * force a GC and finalization, none of which are directly controllable by this.
+ *
+ * <p>This is loaded using reflection by the AbstractResourceLeakageDetectorTestCase class as that
+ * class needs to run on the reference implementation which does not have this class. It implements
+ * {@link Runnable} because that is simpler than trying to manage a specialized interface.
+ *
+ * @hide
+ */
+public class CloseGuardMonitor implements Runnable {
+ /**
+ * The {@link Reporter} instance used to receive warnings from {@link CloseGuard}.
+ */
+ private final Reporter closeGuardReporter;
+
+ /**
+ * The list of allocation sites that {@link CloseGuard} has reported as not being released.
+ *
+ * <p>Is thread safe as this will be called during finalization and so there are no guarantees
+ * as to whether it will be called concurrently or not.
+ */
+ private final List<Throwable> closeGuardAllocationSites = new CopyOnWriteArrayList<>();
+
+ /**
+ * Default constructor required for reflection.
+ */
+ public CloseGuardMonitor() {
+ System.logI("Creating CloseGuard monitor");
+
+ // Save current reporter.
+ closeGuardReporter = CloseGuard.getReporter();
+
+ // Override the reporter with our own which collates the allocation sites.
+ CloseGuard.setReporter(new Reporter() {
+ @Override
+ public void report(String message, Throwable allocationSite) {
+ // Ignore message as it's always the same.
+ closeGuardAllocationSites.add(allocationSite);
+ }
+ });
+ }
+
+ /**
+ * Check to see whether any resources monitored by {@link CloseGuard} were not released before
+ * they were garbage collected.
+ */
+ @Override
+ public void run() {
+ // Create a weak reference to an object so that we can detect when it is garbage collected.
+ WeakReference<Object> reference = new WeakReference<>(new Object());
+
+ try {
+ // 'Force' a GC and finalize to cause CloseGuards to report warnings. Doesn't loop
+ // forever as there are no guarantees that the following code does anything at all so
+ // don't want a potential infinite loop.
+ Runtime runtime = Runtime.getRuntime();
+ for (int i = 0; i < 20; ++i) {
+ runtime.gc();
+ System.runFinalization();
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ }
+
+ // Check to see if the weak reference has been garbage collected.
+ if (reference.get() == null) {
+ System.logI("Sentry object has been freed so assuming CloseGuards have reported"
+ + " any resource leakages");
+ break;
+ }
+ }
+ } finally {
+ // Restore the reporter.
+ CloseGuard.setReporter(closeGuardReporter);
+ }
+
+ if (!closeGuardAllocationSites.isEmpty()) {
+ StringWriter writer = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(writer);
+ int i = 0;
+ for (Throwable allocationSite : closeGuardAllocationSites) {
+ printWriter.print(++i);
+ printWriter.print(") ");
+ allocationSite.printStackTrace(printWriter);
+ printWriter.println(" --------------------------------");
+ }
+ throw new AssertionError("Potential resource leakage detected:\n" + writer);
+ }
+ }
+}
diff --git a/dex/src/main/java/com/android/dex/Dex.java b/dex/src/main/java/com/android/dex/Dex.java
index 116a33c..ea9b627 100644
--- a/dex/src/main/java/com/android/dex/Dex.java
+++ b/dex/src/main/java/com/android/dex/Dex.java
@@ -469,7 +469,7 @@ public final class Dex {
}
/**
- * Look up a type index index from a class def index.
+ * Look up an annotation directory offset from a class def index.
*/
public int annotationDirectoryOffsetFromClassDefIndex(int classDefIndex) {
checkBounds(classDefIndex, tableOfContents.classDefs.size);
@@ -882,7 +882,7 @@ public final class Dex {
/**
* Returns the number of bytes used by this section.
*/
- public int used () {
+ public int used() {
return data.position() - initialPosition;
}
}
@@ -896,7 +896,7 @@ public final class Dex {
@Override public int size() {
return tableOfContents.stringIds.size;
}
- };
+ }
private final class TypeIndexToDescriptorIndexTable extends AbstractList<Integer>
implements RandomAccess {
@@ -906,7 +906,7 @@ public final class Dex {
@Override public int size() {
return tableOfContents.typeIds.size;
}
- };
+ }
private final class TypeIndexToDescriptorTable extends AbstractList<String>
implements RandomAccess {
@@ -916,7 +916,7 @@ public final class Dex {
@Override public int size() {
return tableOfContents.typeIds.size;
}
- };
+ }
private final class ProtoIdTable extends AbstractList<ProtoId> implements RandomAccess {
@Override public ProtoId get(int index) {
@@ -927,7 +927,7 @@ public final class Dex {
@Override public int size() {
return tableOfContents.protoIds.size;
}
- };
+ }
private final class FieldIdTable extends AbstractList<FieldId> implements RandomAccess {
@Override public FieldId get(int index) {
@@ -938,7 +938,7 @@ public final class Dex {
@Override public int size() {
return tableOfContents.fieldIds.size;
}
- };
+ }
private final class MethodIdTable extends AbstractList<MethodId> implements RandomAccess {
@Override public MethodId get(int index) {
@@ -949,7 +949,7 @@ public final class Dex {
@Override public int size() {
return tableOfContents.methodIds.size;
}
- };
+ }
private final class ClassDefIterator implements Iterator<ClassDef> {
private final Dex.Section in = open(tableOfContents.classDefs.off);
@@ -971,7 +971,7 @@ public final class Dex {
public void remove() {
throw new UnsupportedOperationException();
}
- };
+ }
private final class ClassDefIterable implements Iterable<ClassDef> {
public Iterator<ClassDef> iterator() {
@@ -979,5 +979,5 @@ public final class Dex {
? Collections.<ClassDef>emptySet().iterator()
: new ClassDefIterator();
}
- };
+ }
}
diff --git a/dex/src/main/java/com/android/dex/DexException.java b/dex/src/main/java/com/android/dex/DexException.java
index a30a46f..ee0af18 100644
--- a/dex/src/main/java/com/android/dex/DexException.java
+++ b/dex/src/main/java/com/android/dex/DexException.java
@@ -22,7 +22,7 @@ import com.android.dex.util.ExceptionWithContext;
* Thrown when there's a format problem reading, writing, or generally
* processing a dex file.
*/
-public final class DexException extends ExceptionWithContext {
+public class DexException extends ExceptionWithContext {
public DexException(String message) {
super(message);
}
diff --git a/dex/src/main/java/com/android/dex/DexIndexOverflowException.java b/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
new file mode 100644
index 0000000..3226207
--- /dev/null
+++ b/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dex;
+
+/**
+ * Thrown when there's an index overflow writing a dex file.
+ */
+public final class DexIndexOverflowException extends DexException {
+ public DexIndexOverflowException(String message) {
+ super(message);
+ }
+
+ public DexIndexOverflowException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/expectations/brokentests.txt b/expectations/brokentests.txt
index 24813dd..aa06985 100644
--- a/expectations/brokentests.txt
+++ b/expectations/brokentests.txt
@@ -8,45 +8,18 @@
bug: 5834665
},
{
- description: "FIONREAD/SIOCINQ returns the wrong result on sockets (5731252 is the root cause of 5534202)",
- name: "libcore.java.net.SocketTest#testAvailable",
- bug: 5731252
-},
-{
description: "libcore.java.net.URLConnectionTest#testServerShutdownInput fails on ICL27 mysid-userdebug (5534202 is caused by 5731252)",
name: "libcore.java.net.URLConnectionTest#testServerShutdownInput",
bug: 5534202
},
{
- description: "Support digest authentication in HttpURLConnection",
- name: "libcore.net.http.ParsedHeadersTest#testParseChallengesWithManyParameters",
- bug: 6156454
-},
-{
- description: "Without no security manager, we don't care if checkPermission's argument is null",
- name: "org.apache.harmony.security.tests.java.security.AccessController2Test#test_checkPermission_NullParameter",
- result: EXEC_FAILED
-},
-{
- description: "This test and testGetKeepAlive have been failing in our continuous build recently.",
+ description: "This test has been failing in our continuous build recently.",
names: [
- "libcore.java.net.URLConnectionTest#testConnectTimeouts",
- "libcore.java.net.URLConnectionTest#testGetKeepAlive"
+ "libcore.java.net.URLConnectionTest#testConnectTimeouts"
],
bug: 3441111
},
{
- description: "on the RI, writing the two halves of the surrogate pair in separate writes
- is an error because the CharsetEncoder doesn't remember it's half-way through a
- surrogate pair across the two calls!",
- result: EXEC_FAILED,
- names: [
- "libcore.java.nio.charset.CharsetEncoderTest#testCharsetEncoderSurrogatesBrokenByDesign_IGNORE_RI",
- "libcore.java.nio.charset.CharsetEncoderTest#testCharsetEncoderSurrogatesBrokenByDesign_REPLACE_RI",
- "libcore.java.nio.charset.CharsetEncoderTest#testCharsetEncoderSurrogatesBrokenByDesign_REPORT_RI"
- ]
-},
-{
description: "We're retiring the security manager. Unfortunately, tests all over the place
need to check that they're secure, so they all fail when we refuse to install
a security manager. This suppresses all of these failures.",
@@ -62,827 +35,125 @@
pattern: ".*\\.java:\\d+: cannot find symbol.*"
},
{
- description: "These tests assert the exact bytes of the compressed form. Since we use a
- different zlib configuration, we get a different (but valid) compressed form.",
- result: EXEC_FAILED,
- names: [
- "org.apache.harmony.archive.tests.java.util.zip.DeflaterInputStreamTest#testAvailable",
- "org.apache.harmony.archive.tests.java.util.zip.DeflaterInputStreamTest#testRead",
- "org.apache.harmony.archive.tests.java.util.zip.DeflaterInputStreamTest#testReadByteArrayIntInt",
- "org.apache.harmony.archive.tests.java.util.zip.DeflaterTest#test_deflate_beforeSetInput"
- ]
-},
-{
- description: "The RI avoids blocking calls when '\\r' is the last character. We don't
- bother since that adds complexity to every other read call, and '\\r' as the
- last character will be diminishingly rare anyway.",
- result: EXEC_FAILED,
- name: "java.io.BufferedReader.ReadLine",
- substring: "java.lang.RuntimeException: Read past limit"
-},
-{
- description: "The RI avoids blocking calls when '\\r' is the last character. We don't
- bother since that adds complexity to every other read call, and '\\r' as the
- last character will be diminishingly rare anyway.",
- result: EXEC_FAILED,
- name: "java.io.BufferedReader.Ready",
- substring: "Hit infinite wait condition"
-},
-{
- description: "The test is checking that the implementation doesn't read any characters
- earlier than it absolutely needs to. This is a bogus requirement; streams
- are allowed to buffer input as necessary.",
- result: EXEC_FAILED,
- name: "java.io.StreamTokenizer.Reset",
- substring: "Test failed: should get token [, but get -1"
-},
-{
- description: "These tests only pass if the root logger hasn't yet been initialized. They
- incorrectly assume that resetting the LogManager will clear the root logger's
- resource bundle; this isn't the case.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.logging.tests.java.util.logging.OldLoggerTest#testGetLoggerWithRes_InvalidResourceBundle",
- substring: "java.lang.IllegalArgumentException: Resource bundle name 'impossible_not_existing' is inconsistent"
-},
-{
- description: "These tests only pass if the root logger hasn't yet been initialized. They
- incorrectly assume that resetting the LogManager will clear the root logger's
- resource bundle; this isn't the case.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.logging.tests.java.util.logging.LoggerTest#testGetLogger_Empty",
- substring: "junit.framework.AssertionFailedError"
-},
-{
- description: "This tests implementation details",
- result: UNSUPPORTED,
- name: "java.util.EnumSet.OneUniverse"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.Cipher.AES.Test4513830",
- "com.sun.crypto.provider.Cipher.AES.Test4512704",
- "com.sun.crypto.provider.Cipher.AES.Test4512524",
- "com.sun.crypto.provider.Cipher.AES.Test4511676",
- "com.sun.crypto.provider.Cipher.AES.Test4517355"
- ],
- substring: "NoClassDefFoundError: com.sun.crypto.provider.SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.AES.TestISO10126Padding",
- substring: " java.security.NoSuchProviderException: SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.AES.Test4626070",
- substring: "NoClassDefFoundError: com.sun.crypto.provider.SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.Cipher.AES.TestShortBuffer",
- "com.sun.crypto.provider.Cipher.CTS.CTSMode"
- ],
- substring: "Provider SunJCE is not available"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.Cipher.DES.DesAPITest",
- "com.sun.crypto.provider.Cipher.DES.DoFinalReturnLen",
- "com.sun.crypto.provider.Cipher.DES.FlushBug"
- ],
- substring: "java.lang.NoClassDefFoundError: com.sun.crypto.provider.SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.DES.KeyWrapping",
- substring: "Provider SunJCE is not available"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.Cipher.DES.PaddingTest",
- "com.sun.crypto.provider.Cipher.DES.Sealtest",
- "com.sun.crypto.provider.Cipher.DES.PerformanceTest"
- ],
- substring: "java.lang.NoClassDefFoundError: com.sun.crypto.provider.SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.Cipher.PBE.DecryptWithoutParameters",
- "com.sun.crypto.provider.Cipher.PBE.PBEInvalidParamsTest"
- ],
- substring: "Provider SunJCE is not available"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.PBE.PBEKeysAlgorithmNames",
- substring: "java.security.NoSuchProviderException: SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.Cipher.PBE.PBEParametersTest",
- "com.sun.crypto.provider.Cipher.PBE.PKCS12Oid",
- "com.sun.crypto.provider.Cipher.UTIL.StrongOrUnlimited",
- "com.sun.crypto.provider.Cipher.KeyWrap.NISTWrapKAT"
- ],
- substring: "Provider SunJCE is not available"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.KeyAgreement.DHGenSecretKey",
- substring: "java.security.NoSuchProviderException: SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.KeyAgreement.DHGenSharedSecret",
- "com.sun.crypto.provider.KeyAgreement.DHKeyAgreement3",
- "com.sun.crypto.provider.KeyAgreement.DHKeyFactory",
- "com.sun.crypto.provider.KeyAgreement.DHKeyGenSpeed"
- ],
- substring: "java.lang.NoClassDefFoundError: com.sun.crypto.provider.SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.KeyAgreement.TestExponentSize",
- "com.sun.crypto.provider.KeyFactory.TestProviderLeak",
- "com.sun.crypto.provider.KeyFactory.PBKDF2HmacSHA1FactoryTest"
- ],
- substring: "java.security.NoSuchProviderException: SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- names: [
- "com.sun.crypto.provider.KeyGenerator.Test4628062",
- "com.sun.crypto.provider.KeyGenerator.TestExplicitKeyLength"
- ],
- substring: "java.lang.NoClassDefFoundError: com.sun.crypto.provider.SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Mac.HmacPBESHA1",
- substring: "java.security.NoSuchProviderException: SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Mac.HmacMD5",
- substring: "java.lang.NoClassDefFoundError: com.sun.crypto.provider.SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Mac.MacClone",
- substring: "java.security.NoSuchProviderException: SunJCE"
-},
-{
- description: "Dalvik doesn't include the SunJCE crypto provider",
- result: EXEC_FAILED,
- failure: "JKS keystore not found",
- substring: "KeyStore JKS implementation not found"
-},
-{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.PBE.PKCS12Cipher",
- pattern: ".*PKCS12Cipher.java\\:87\\).*NullPointerException.*"
-},
-{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.PBE.PKCS12CipherKAT",
- pattern: ".*NullPointerException.*PKCS12CipherKAT.java\\:183\\).*"
-},
-{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.RC2ArcFour.CipherKAT",
- pattern: ".*NullPointerException.*CipherKAT.java\\:205\\).*"
-},
-{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.RSA.TestOAEP_KAT",
- pattern: ".*TestOAEP_KAT.java\\:62\\).*NullPointerException.*"
-},
-{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.RSA.TestOAEP",
- pattern: ".*TestOAEP.java\\:50\\).*NullPointerException.*"
-},
-{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.RSA.TestOAEPParameterSpec",
- pattern: ".*TestOAEPParameterSpec.java\\:124\\).*NullPointerException.*"
-},
-{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
- result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.RSA.TestOAEPWithParams",
- pattern: ".*TestOAEPWithParams.java\\:58\\).*NullPointerException.*"
-},
-{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
+ description: "the average length of possible UTF-8 sequences is 2 bytes.",
result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Cipher.RSA.TestRSA",
- pattern: ".*TestRSA.java\\:171\\).*NullPointerException.*"
+ name: "org.apache.harmony.tests.java.nio.charset.UTFCharsetEncoderTest#testSpecificDefaultValue",
+ substring: "junit.framework.AssertionFailedError: expected:<1.1> but was:<2.0>"
},
{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
+ description: "Some tests (ExcludedProxyTest) connect to a public webserver to check that the HTTP client works",
result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Mac.HmacSaltLengths",
- pattern: ".*HmacSaltLengths.java\\:83\\).*java.lang.NullPointerException.*"
+ failure: "connect to the Internet",
+ pattern: ".*java.net.UnknownHostException:.*jcltest.apache.org.*"
},
{
- description: "These NPEs all happen while calling Provider#getName on the result of
- Security#getProvider(). Unfortunately, that method is permitted to return
- null if the system has no provider with the requested name. And since we don't
- have the SunJCE provider, tests fail",
+ description: "Some tests depend on ICU data, which has changed. Others make assumptions about floating point rounding",
result: EXEC_FAILED,
- name: "com.sun.crypto.provider.Mac.MacKAT",
- pattern: ".*MacKAT.java\\:228\\).*java.lang.NullPointerException.*"
-},
-{
- description: "These tests call into misc Sun classes that we don't have",
- result: COMPILE_FAILED,
- name: "com.sun.crypto.provider.KeyAgreement.DHKeyAgreement2",
- pattern: ".*cannot find symbol.*sun.misc.HexDumpEncoder.*"
-},
-{
- description: "These tests call into misc Sun classes that we don't have",
- result: COMPILE_FAILED,
- name: "com.sun.crypto.provider.Cipher.KeyWrap.XMLEncKAT",
- pattern: ".*cannot find symbol.*sun.misc.BASE64Decoder.*"
-},
-{
- description: "These tests call into misc Sun classes that we don't have",
- result: COMPILE_FAILED,
- names: [
- "com.sun.crypto.provider.TLS.TestKeyMaterial",
- "com.sun.crypto.provider.TLS.TestMasterSecret",
- "com.sun.crypto.provider.TLS.TestPremaster",
- "com.sun.crypto.provider.TLS.TestPRF"
- ],
- substring: "package sun.security.internal.spec does not exist"
-},
-{
- description: "We don't have most com.sun packages.",
- result: COMPILE_FAILED,
- failure: "Dalvik doesn't include Sun packages",
- pattern: ".*package (com\\.)?sun\\.[\\w\\.]+ does not exist.*"
-},
-{
- description: "We don't have several Java packages either.",
- result: COMPILE_FAILED,
- failure: "Dalvik doesn't include applets",
- substring: "package java.applet does not exist"
-},
-{
- description: "We don't have several Java packages either.",
- result: COMPILE_FAILED,
- failure: "Dalvik doesn't include AWT (bug it has java.awt.font)",
- pattern: ".*package java.awt(\\.image)? does not exist.*"
-},
-{
- description: "We don't have several Java packages either.",
- result: "COMPILE_FAILED",
- failure: "Dalvik doesn't include NIO.2",
- substring: "package java.nio.file does not exist"
-},
-{
- description: "We don't have several Java packages either.",
- result: "COMPILE_FAILED",
- failure: "Dalvik doesn't include RMI",
- substring: "package java.rmi does not exist"
-},
-{
- description: "We don't have several Java packages either.",
- result: "COMPILE_FAILED",
- failure: "Dalvik doesn't include JNDI",
- substring: "package javax.naming does not exist"
-},
-{
- description: "We don't have several Java packages either.",
- result: "COMPILE_FAILED",
- failure: "Dalvik doesn't include JMX",
- substring: "package java.lang.management does not exist"
-},
-{
- description: "We don't have several Java packages either.",
- result: "COMPILE_FAILED",
- failure: "Dalvik doesn't include Swing",
- substring: "package javax.swing.tree does not exist"
-},
-{
- description: "We don't have several Java packages either.",
- result: "COMPILE_FAILED",
- failure: "Dalvik doesn't include javax.crypto",
- substring: "package javax.xml.crypto does not exist"
-},
-{
- description: "Dalvik doesn't include a com.sun.net HTTP server",
- result: UNSUPPORTED,
- names: [
- "com.sun.net.httpserver",
- "sun.net.www"
- ]
-},
-{
- description: "Dalvik doesn't include AWT except the font package",
- result: UNSUPPORTED,
- name: "java.awt"
-},
-{
- description: "Dalvik doesn't include AWT except the font package",
- result: "SUCCESS",
names: [
- "java.awt.FontClass",
- "java.awt.font"
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalExceptionOrder",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionE",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionF",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionG",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalExceptionOrder",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionOther",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_LineSeparator",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_Percent",
+ "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_Width"
]
},
{
- description: "Dalvik doesn't include java.beans except for property listeners",
- result: UNSUPPORTED,
- name: "java.beans"
-},
-{
- description: "Dalvik doesn't include java.beans except for property listeners",
- result: "SUCCESS",
- name: "java.beans.PropertyChangeSupport"
-},
-{
- description: "Dalvik doesn't include java.lang.instrument",
- result: UNSUPPORTED,
- name: "java.lang.instrument"
-},
-{
- description: "Dalvik doesn't include java.lang.management",
- result: UNSUPPORTED,
- name: "java.lang.management"
-},
-{
- description: "Dalvik doesn't include RMI",
- result: UNSUPPORTED,
+ description: "(Needs investigation) Some tests make assertions that don't make sense, others use broken port allocation logic.",
+ result: EXEC_FAILED,
names: [
- "java.rmi",
- "sun.rmi"
+ "org.apache.harmony.tests.java.net.Inet6AddressTest#test_getByNameLjava_lang_String",
+ "org.apache.harmony.tests.java.net.InetAddressTest#test_equalsLjava_lang_Object",
+ "org.apache.harmony.tests.java.net.InetAddressTest#test_getByNameLjava_lang_String",
+ "org.apache.harmony.tests.java.net.InetAddressTest#test_isReachableLjava_net_NetworkInterfaceII_loopbackInterface"
]
},
{
- description: "Dalvik doesn't include javax.imageio",
- result: UNSUPPORTED,
- name: "javax.imageio"
-},
-{
- description: "Dalvik doesn't include javax.management",
- result: UNSUPPORTED,
- name: "javax.management"
-},
-{
- description: "Dalvik doesn't include javax.naming",
- result: UNSUPPORTED,
- name: "javax.naming"
-},
-{
- description: "Dalvik doesn't include javax.print",
- result: UNSUPPORTED,
- name: "javax.print"
-},
-{
- description: "Dalvik doesn't include javax.script",
- result: UNSUPPORTED,
- name: "javax.script"
-},
-{
- description: "Dalvik doesn't include javax.sound",
- result: UNSUPPORTED,
- name: "javax.sound"
-},
-{
- description: "Dalvik doesn't include javax.swing",
- result: UNSUPPORTED,
- name: "javax.swing"
-},
-{
- description: "Dalvik doesn't include sun.management",
- result: UNSUPPORTED,
- name: "sun.management"
-},
-{
- description: "Dalvik doesn't include javax.smartcardio",
- result: UNSUPPORTED,
- name: "sun.security.smartcardio"
-},
-{
- description: "Our exception messages don't match the RIs",
+ description: "(Needs investigation) Test failures from the harmony import of external/apache-harmony/archive",
+ bug: 12189307,
result: EXEC_FAILED,
names: [
- "java.lang.StringBuilder.Exceptions",
- "java.lang.StringBuffer.Exceptions"
- ],
- substring: "got java.lang.StringIndexOutOfBoundsException: null - FAILED"
-},
-{
- description: "ICU doesn't like 3-letter names like CST because they're ambiguous.
- Harmony prefers them because they're more human readable. We'll be
- consistent with ICU, since that seems least fragile.
- See https://issues.apache.org/jira/browse/HARMONY-5468
- and http://bugs.icu-project.org/trac/ticket/6174",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.DateTest#test_toString",
- substring: "GMT-07:00"
-},
-{
- description: "This test fails because on Android, RuleBasedCollators default to
- CANONICAL_DECOMPOSITION, not NO_DECOMPOSITION.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.text.tests.java.text.RuleBasedCollatorTest#testEqualsObject",
- substring: "expected:<0> but was:<1>"
-},
-{
- description: "These Harmony tests are enforcing a buggy behaviour in TreeMap, presumably to be bug-compatible
- with the RI. Our implementation is more conservative and throws on the bogus inputs.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.TreeMapExtendTest#test_AscendingSubMapKeySet_headSet",
- substring: "java.lang.IllegalArgumentException: 100 not in range (100..109]"
+ "org.apache.harmony.tests.java.util.jar.ManifestTest#testNul",
+ "org.apache.harmony.tests.java.util.jar.ManifestTest#testRead",
+ "org.apache.harmony.tests.java.util.jar.ManifestTest#testStreamConstructor"
+ ]
},
{
- description: "These Harmony tests are enforcing a buggy behaviour in TreeMap, presumably to be bug-compatible
- with the RI. Our implementation is more conservative and throws on the bogus inputs.",
+ description: "Potentially flakey because they rely on a specific local TCP port being free.",
result: EXEC_FAILED,
names: [
- "org.apache.harmony.luni.tests.java.util.TreeMapExtendTest#test_AscendingSubMapKeySet_tailSet",
- "org.apache.harmony.luni.tests.java.util.TreeMapExtendTest#test_DescendingSubMapKeySet_headSet"
- ],
- substring: "java.lang.IllegalArgumentException: null not in range [100..109)"
+ "org.apache.harmony.tests.java.nio.channels.ServerSocketChannelTest#test_bind_explicitPort"
+ ]
},
{
- description: "These Harmony tests are enforcing a buggy behaviour in TreeMap, presumably to be bug-compatible
- with the RI. Our implementation is more conservative and throws on the bogus inputs.",
+ description: "The ResourceBundle code under test is probably not used much on Android and needs a lot of attention.",
+ bug: 13747957,
result: EXEC_FAILED,
names: [
- "org.apache.harmony.luni.tests.java.util.TreeMapExtendTest#test_DescendingSubMap_tailMap",
- "org.apache.harmony.luni.tests.java.util.TreeMapExtendTest#test_DescendingSubMapKeySet_tailSet",
- "org.apache.harmony.luni.tests.java.util.TreeMapExtendTest#test_SubMap_headMap"
- ],
- substring: "java.lang.IllegalArgumentException: 100 not in range (100..109]"
-},
-{
- description: "why are they using reflection to test implementation details?",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.ArraysTest#test_swap_I_I_$Ljava_lang_Object",
- substring: "java.lang.NoSuchMethodException"
-},
-{
- description: "all these tests rely on a Harmony bug where TreeMaps may have a singleton null, which we choose
- to disallow.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.SimpleImmutableEntryTest#test_SimpleImmutableEntry_Constructor_LEntry",
- pattern: ".*java.lang.NullPointerException.*at java.util.TreeMap.find.*"
+ "org.apache.harmony.tests.java.util.ControlTest#test_needsReload_LStringLLocaleLStringLClassLoaderResourceBundleJ"
+ ]
},
{
- description: "all these tests rely on a Harmony bug where TreeMaps may have a singleton null, which we choose
- to disallow.",
+ description: "Fails in CTS, passes in CoreTestRunner.",
result: EXEC_FAILED,
names: [
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_ceilingEntry",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_ceilingKey",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_floorEntry",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_floorKey",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_higherEntry",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_higherKey",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_lowerEntry",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_lowerKey"
- ],
- substring: "java.lang.NullPointerException"
-},
-{
- description: "all these tests rely on a Harmony bug where TreeMaps may have a singleton null, which we choose
- to disallow.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_illegalFirstNullKey",
- pattern: ".*java.lang.NullPointerException.*at java.util.TreeMap.find.*"
-},
-{
- description: "this is testing exception priorities",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_subMapLjava_lang_ObjectLjava_lang_Object",
- substring: "java.lang.ClassCastException: java.lang.Object"
-},
-{
- description: "the null-friendly comparator isn't symmetric",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_subMapLjava_lang_ObjectZLjava_lang_ObjectZ",
- substring: "java.lang.NullPointerException"
+ "org.apache.harmony.tests.java.net.URLConnection#test_getContentEncoding",
+ "libcore.java.text.OldNumberFormatTest#test_parseLjava_lang_String",
+ "libcore.java.nio.channels.OldSocketChannelTest#test_writeLjava_nio_ByteBuffer_Nonblocking_HugeData",
+ "org.apache.harmony.tests.java.lang.ProcessManagerTest#testSleep",
+ "libcore.java.security.cert.OldPKIXParametersTest#testPKIXParametersKeyStore04"
+ ]
},
{
- description: "we fail fast on not-comparable objects",
+ description: "Suffers from DH slowness, disabling for now.",
result: EXEC_FAILED,
names: [
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_equals",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_putLjava_lang_ObjectLjava_lang_Object"
- ],
- substring: "java.lang.ClassCastException: java.lang.Object"
-},
-{
- description: "tests that depend on the iteration order of a hash",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.CollectionsTest#test_unmodifiable_toString_methods",
- substring: "expected:<...one=1, two=2...> but was:<...two=2, one=1...>"
-},
-{
- description: "tests that depend on the iteration order of a hash",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashtableTest#test_keySet_subtest1",
- pattern: ".*java.lang.IllegalStateException.*at java.util.Hashtable.*"
-},
-{
- description: "tests that depend on the iteration order of a hash",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashtableTest#test_elements_subtest0",
- substring: "junit.framework.AssertionFailedError: unexpected: b"
-},
-{
- description: "tests that depend on the iteration order of a hash",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashMapTest#test_rehash",
- substring: "junit.framework.AssertionFailedError: expected same"
-},
-{
- description: "tests that depend on the iteration order of a hash",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.PropertiesTest#test_SequentialpropertyNames",
- substring: "expected:<current.b.key> but was:<current.a.key>"
-},
-{
- description: "tests that depend on the iteration order of a hash",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.PropertiesTest#test_SequentialstringPropertyNames",
- substring: "junit.framework.ComparisonFailure"
-},
-{
- description: "tests that depend on the iteration order of a hash",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.PropertiesTest#test_propertyNames_sequence",
- substring: "junit.framework.AssertionFailedError: expected:<current.b.key> but was:<current.a.key>"
-},
-{
- description: "tests that use secret type information to reason about behavior",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashtableTest#test_keySet",
- substring: "junit.framework.ComparisonFailure: Not synchronized expected:<...Collections$Synchronized...> but was:<...Hashtable$Key...>"
-},
-{
- description: "tests that use secret type information to reason about behavior",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashtableTest#test_entrySet",
- substring: "junit.framework.ComparisonFailure: Not synchronized expected:<...Collections$Synchronized...> but was:<...Hashtable$Entry...>"
-},
-{
- description: "tests that use secret type information to reason about behavior",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashtableTest#test_values",
- substring: "junit.framework.ComparisonFailure: Not synchronized expected:<...Collections$SynchronizedCollection> but was:<...Hashtable$Values>"
-},
-{
- description: "this test is invalid, proxy.equals isn't symmetric",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashMapTest#test_proxies"
-},
-{
- description: "this test is invalid, the mock map's entry set isn't to spec",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashMapTest#test_putAllLjava_util_Map",
- substring: "java.lang.NullPointerException"
-},
-{
- description: "this test assumes remove acts on equals() equality, not comparator equality",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.PriorityQueueTest#test_remove_Ljava_lang_Object_using_comparator",
- substring: "junit.framework.AssertionFailedError"
-},
-{
- description: "tests that violate the API and then guess about the outcomes",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.HashtableTest#test_getLjava_lang_Object",
- substring: "junit.framework.AssertionFailedError"
-},
-{
- description: "this test assumes Integer.toString() always returns a new instance",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.IdentityHashMap2Test#test_containsKeyLjava_lang_Object",
- substring: "junit.framework.AssertionFailedError: Returned true for copy of valid key"
-},
-{
- description: "tests that cast to Harmony-specific types",
- result: EXEC_FAILED,
- failure: "bogus cast to harmony Hashtable$KeyEnumeration",
- substring: "java.util.Hashtable$KeyEnumeration"
-},
-{
- description: "tests that cast to Harmony-specific types",
- result: EXEC_FAILED,
- failure: "bogus cast to Hashtable$ValueEnumeration",
- substring: "java.util.Hashtable$ValueEnumeration"
+ "libcore.java.security.OldDHTest#testDHGen",
+ "libcore.java.security.OldKeyPairGeneratorTestDH#testKeyPairGenerator",
+ "libcore.javax.crypto.spec.KeyPairGeneratorTestDH#testKeyPairGenerator",
+ "libcore.javax.crypto.spec.AlgorithmParametersTestDH#testAlgorithmParameters",
+ "libcore.javax.crypto.spec.AlgorithmParameterGeneratorTestDH#testAlgorithmParameterGenerator"
+ ]
},
{
- description: "test doesn't expect it, but the spec permits the exception. RI also throws here.",
+ description: "Destroys MD5 provider, hurts succeeding tests",
result: EXEC_FAILED,
names: [
- "org.apache.harmony.luni.tests.java.util.PriorityQueueTest#test_remove_Ljava_lang_Object_not_Compatible",
- "org.apache.harmony.luni.tests.java.util.PriorityQueueTest#test_remove_Ljava_lang_Object_not_exists"
- ],
- substring: "java.lang.ClassCastException"
-},
-{
- description: "localization tests where our data disagree",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.LocaleTest#test_getAvailableLocales",
- substring: "Wrong number of locales"
-},
-{
- description: "test that enforce redundant implements clauses",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.LinkedHashMapTest#test_getInterfaces",
- substring: "junit.framework.AssertionFailedError: expected:<3> but was:<2>"
-},
-{
- description: "ICU doesn't provide localized pattern characters, and these tests assume the locale they're using has them.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.text.tests.java.text.SimpleDateFormatTest#test_applyLocalizedPatternLjava_lang_String",
- substring: "java.lang.IllegalArgumentException: Invalid pattern character 'u' in 'GuMtkHmsSEDFwWahKz'"
-},
-{
- description: "ICU doesn't provide localized pattern characters, and these tests assume the locale they're using has them.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.text.tests.java.text.SimpleDateFormatTest#test_toLocalizedPattern",
- substring: "junit.framework.AssertionFailedError: Wrong pattern: GyMdkHmsSEDFwWahKz"
-},
-{
- description: "ICU doesn't provide localized pattern characters, and these tests assume the locale they're using has them.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.text.tests.java.text.DateFormatSymbolsTest#test_getLocalPatternChars",
- substring: "junit.framework.ComparisonFailure: Returned incorrect pattern string expected:<...YeugAZvcLQqV> but was:<...Z>"
-},
-{
- description: "we don't support the CharsetProvider spi, so we don't have \"mockCharset00\".",
- result: EXEC_FAILED,
- name: "tests.api.java.nio.charset.CharsetTest#test_availableCharsets",
- substring: "junit.framework.AssertionFailedError"
+ "tests.api.javax.security.cert.X509CertificateTest#testVerifyPublicKey",
+ "tests.api.javax.security.cert.X509CertificateTest#testVerifyPublicKeyString"
+ ]
},
{
- description: "we don't support the CharsetProvider spi, so we don't have \"mockCharset00\".",
+ description: "Suffers from side effect of other, currently unknown test",
result: EXEC_FAILED,
- name: "tests.api.java.nio.charset.CharsetTest#test_forNameLString",
- substring: "java.nio.charset.UnsupportedCharsetException: mockCharset00"
-},
-{
- description: "the average length of possible UTF-8 sequences is 2 bytes.",
- result: EXEC_FAILED,
- name: "tests.api.java.nio.charset.UTFCharsetEncoderTest#testSpecificDefaultValue",
- substring: "junit.framework.AssertionFailedError: expected:<1.1> but was:<2.0>"
-},
-{
- description: "this test needs external interaction",
- result: UNSUPPORTED,
names: [
- "com.sun.tools.attach.Application",
- "java.io.SystemInAvailable",
- "sun.jvmstat.testlibrary.Sleeper"
+ "org.apache.harmony.luni.tests.internal.net.www.protocol.http.HttpURLConnectionTest#testProxyAuthorization"
]
},
{
- description: "these benchmarks take a long time and don't demonstrate correctness",
- result: UNSUPPORTED,
+ description: "Support_TestWebServer requires isolation.",
+ result: EXEC_FAILED,
names: [
- "java.lang.Class.TypeCheckMicroBenchmark",
- "java.nio.Buffer.SwapMicroBenchmark",
- "java.util.ArrayList.RangeCheckMicroBenchmark",
- "java.util.ArrayList.IteratorMicroBenchmark"
+ "libcore.java.net.OldURLClassLoaderTest#test_findResourceLjava_lang_String"
]
},
{
- description: "The RI is still on Unicode 4.0, we're on 5.2, and Harmony is inconsistent
- between its test for isJavaIdentifierPart(char) and isJavaIdentifierPart(int).",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.lang.CharacterTest#test_isJavaIdentifierPartC"
-},
-{
- description: "We removed this: we don't support Pack200.",
- result: UNSUPPORTED,
- name: "org.apache.harmony.archive.tests.java.util.jar.Pack200Test"
-},
-{
- description: "We removed this: we don't cache canonical paths.",
- result: UNSUPPORTED,
- name: "org.apache.harmony.luni.tests.java.io.FileCanonPathCacheTest"
-},
-{
- description: "We removed this: we don't throw NotYetImplementedException.",
- result: UNSUPPORTED,
- name: "org.apache.harmony.luni.tests.util.NYITest"
-},
-{
- description: "We removed this: we don't support localized exceptions.",
- result: UNSUPPORTED,
- name: "org.apache.harmony.luni.tests.internal.nls.MessagesTest"
-},
-{
- description: "These test implementation details we don't share.",
+ description: "Causes OutOfMemoryError to test finalization",
result: EXEC_FAILED,
names: [
- "org.apache.harmony.text.tests.java.text.BreakIteratorTest#test_getInt",
- "org.apache.harmony.text.tests.java.text.BreakIteratorTest#test_getLong",
- "org.apache.harmony.text.tests.java.text.BreakIteratorTest#test_getShort"
+ "org.apache.harmony.tests.java.lang.ref.SoftReferenceTest#test_get_SoftReference",
+ "org.apache.harmony.crypto.tests.javax.crypto#ExemptionMechanismTest#test_finalize"
]
},
{
- description: "These format specifiers are documented to not take flags, but the RI accepts and ignores them.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_LineSeparator",
- substring: "java.util.IllegalFormatFlagsException: %n doesn't take an argument"
-},
-{
- description: "These format specifiers are documented to not take flags, but the RI accepts and ignores them.",
+ description: "Causes open dex file error",
result: EXEC_FAILED,
names: [
- "org.apache.harmony.luni.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_Percent",
- "org.apache.harmony.luni.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_Width"
- ],
- substring: "java.util.IllegalFormatFlagsException: %% doesn't take an argument"
-},
-{
- description: "Some tests (ExcludedProxyTest) connect to a public webserver to check that the HTTP client works",
- result: EXEC_FAILED,
- failure: "connect to the Internet",
- pattern: ".*java.net.UnknownHostException:.*jcltest.apache.org.*"
-},
-{
- description: "These tests violate visibility rules when trying to unit test internal classes",
- result: EXEC_FAILED,
- name: "javax.net.ssl.DefaultSSLSocketFactoryTest",
- substring: "java.lang.IllegalAccessError: tried to access class javax.net.ssl.DefaultSSLSocketFactory from class javax.net.ssl.DefaultSSLSocketFactoryTest"
-},
-{
- description: "These tests expect to be called with commandline arguments",
- result: EXEC_FAILED,
- name: "java.io.FileOutputStream.FileOpenNeg",
- substring: "java.lang.ArrayIndexOutOfBoundsException"
-},
-{
- description: "",
- result: EXEC_FAILED,
- name: "java.io.FileOutputStream.FileOpenPos",
- substring: "java.lang.ArrayIndexOutOfBoundsException"
+ "org.apache.harmony.tests.java.lang.reflect.GenericSignatureFormatErrorTest#test_signatureFormatError"
+ ]
}
]
diff --git a/expectations/icebox.txt b/expectations/icebox.txt
index 09e05e2..8764185 100644
--- a/expectations/icebox.txt
+++ b/expectations/icebox.txt
@@ -3,16 +3,6 @@
*/
[
{
- description: "javasqlite doesn't honor query timeouts",
- bug: 5213614,
- names: [
- "libcore.sqlite.QueryTimeoutTest#testExecuteUpdate",
- "libcore.sqlite.QueryTimeoutTest#testPreparedStatementFetch",
- "libcore.sqlite.QueryTimeoutTest#testPreparedStatementUpdate",
- "libcore.sqlite.QueryTimeoutTest#testTimeoutAndStatementReuse"
- ]
-},
-{
description: "Dalvik doesn't support XML Schemas, DTDs or validation",
bug: 3268630,
name: "libcore.xml.DomTest#testEntityDeclarations",
@@ -87,43 +77,12 @@
substring: "java.lang.ClassCastException: org.apache.harmony.xml.dom.EntityReferenceImpl"
},
{
- description: "Dalvik doesn't support XML Schemas, DTDs or validation",
- bug: 3268630,
- name: "libcore.xml.DeclarationTest.testGetXmlVersion",
- substring: "This implementation doesn't parse the version from the XML declaration"
-},
-{
- description: "the lack of schema parsing also extends to XML parsing in prefs",
- result: EXEC_FAILED,
- name: "org.apache.harmony.prefs.tests.java.util.prefs.PreferencesTest#testImportPreferences",
- substring: "junit.framework.AssertionFailedError: should throw InvalidPreferencesFormatException"
-},
-{
description: "many tests attempt to fork a Java executable, but fork the wrong one",
result: "EXEC_FAILED",
failure: "should fork a dalvikvm, not a JVM",
substring: "/system/bin.*IOException"
},
{
- description: "a low impact bug, we can't produce tiny random, probable prime big integers",
- result: EXEC_FAILED,
- name: "tests.api.java.math.BigIntegerTest#test_ConstructorIILjava_util_Random",
- substring: "junit.framework.AssertionFailedError: Random number one is too big"
-},
-{
- description: "we don't support CANON_EQ in regex
- http://code.google.com/p/android/issues/detail?id=8592",
- result: EXEC_FAILED,
- names: [
- "org.apache.harmony.tests.java.util.regex.PatternTest#testCanonEqFlagWithSupplementaryCharacters",
- "org.apache.harmony.tests.java.util.regex.PatternTest#testCanonEqFlag",
- "org.apache.harmony.tests.java.util.regex.PatternErrorTest#testCompileErrors",
- "org.apache.harmony.tests.java.util.regex.PatternTest#testCompileNonCaptGroup",
- "org.apache.harmony.tests.java.util.regex.PatternTest#testIndexesCanonicalEq"
- ],
- substring: "UnsupportedOperationException: CANON_EQ flag not supported"
-},
-{
description: "low-impact XML bugs:",
result: EXEC_FAILED,
name: "libcore.xml.DomTest#testAttributeNamedIdIsNotAnIdByDefault",
@@ -171,13 +130,6 @@
substring: "java.lang.UnsupportedOperationException: This parser does not support specification \"Unknown\" version \"0.0\""
},
{
- description: "a low-impact bug: \"Shared FileDescriptors get closed too early\"
- http://code.google.com/p/android/issues/detail?id=5923",
- result: EXEC_FAILED,
- name: "java.io.FileDescriptor.Finalize",
- pattern: ".*java.io.IOException.*openCheck.*"
-},
-{
description: "a low-impact bug, also present in Crockford's implementation of org.json",
result: EXEC_FAILED,
name: "org.json.ParsingTest#test64BitHexValues",
@@ -189,26 +141,9 @@
name: "tests.api.javax.xml.parsers.SAXParserTest#test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandlerLjava_lang_String"
},
{
- description: "these enforce a bug where an exception is incorrectly unthrown, but should maybe be fixed for
- compatibility.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_headMapLjava_lang_ObjectZL",
- substring: "java.lang.IllegalArgumentException: null not in range ...5)"
-},
-{
- description: "these enforce a bug where an exception is incorrectly unthrown, but should maybe be fixed for
- compatibility.",
- result: EXEC_FAILED,
- names: [
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_tailMapLjava_lang_ObjectZL",
- "org.apache.harmony.luni.tests.java.util.TreeMapTest#test_descendingMap_subMap"
- ],
- substring: "java.lang.IllegalArgumentException: 5 not in range (5..."
-},
-{
description: "BouncyCastle allows unrecognized algorithms, but RI does not, not clear if this is a bug",
result: EXEC_FAILED,
name: "org.apache.harmony.crypto.tests.javax.crypto.KeyAgreementTest#test_generateSecretLjava_lang_String",
substring: "junit.framework.AssertionFailedError: NoSuchAlgorithmException expected"
}
-] \ No newline at end of file
+]
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 5055cbf..1293b27 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -3,139 +3,21 @@
*/
[
{
- description: "four known CharsetDecoder-/CharsetEncoder-related failures",
- names: [
- "org.apache.harmony.nio_char.tests.java.nio.charset.ASCIICharsetEncoderTest#testCanEncodeSurrogate",
- "org.apache.harmony.nio_char.tests.java.nio.charset.ASCIICharsetEncoderTest#testMultiStepEncode",
- "org.apache.harmony.nio_char.tests.java.nio.charset.CharsetDecoderTest#testInvalidDecoding",
- "org.apache.harmony.nio_char.tests.java.nio.charset.CharsetDecoderTest#test_decode"
- ],
- bug: 10729779
-},
-{
description: "can't compile a pattern with negative look-behind and quantifiers with upper bounds",
name: "org.apache.harmony.regex.tests.java.util.regex.PatternTest#test_bug_40103",
bug: 40103
},
{
- description: "our regex implementation calls toString on CharSequences",
- name: "org.apache.harmony.luni.tests.java.util.ScannerParseLargeFileBenchmarkTest#testParseLargeFile",
- bug: 10133206
-},
-{
description: "Package.getPackages(), ClassLoader.getPackages() both omit results",
name: "libcore.java.lang.PackageTest#testGetPackages",
bug: 5171136
},
{
- description: "Deserialization shouldn't set transient fields",
- name: "libcore.java.io.SerializationTest#testSerializeFieldMadeTransient",
- bug: 4471249
-},
-{
- description: "Investigate InterruptedIOException + InputStream.read(), OutputStream.write()",
- names: [
- "libcore.java.io.InterruptedStreamTest#testInterruptSocketInputStream",
- "libcore.java.io.InterruptedStreamTest#testInterruptSocketOutputStream"
- ],
- bug: 4181738
-},
-{
- description: "SimpleDateFormat assumes DST always uses 60 minute offset; this fails for zones like Lord Howe Daylight Time",
- name: "libcore.java.text.SimpleDateFormatTest#testDstZoneWithNonDstTimestampForNonHourDstZone",
- bug: 4723412
-},
-{
- description: "Expat uses an unbounded number of global references",
- name: "libcore.xml.ExpatSaxParserTest#testGlobalReferenceTableOverflow",
- bug: 2772628
-},
-{
- description: "Test fails, Intermediate certificate lacks BasicConstraints",
- name: "com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpiTest#testTrustAndRemoteCertificatesWithDifferentEncodings",
- bug: 3474648
-},
-{
- description: "DHParametersHelper.generateSafePrimes sometimes takes long time, other times takes a very long time",
- name: "org.apache.harmony.crypto.tests.javax.crypto.interfaces.DHPrivateKeyTest#test_getParams",
- bug: 3474446
-},
-{
description: "KeyAgreementFunctionalTest times out even with an absurdly long timeout",
name: "org.apache.harmony.crypto.tests.javax.crypto.func.KeyAgreementFunctionalTest#test_KeyAgreement",
bug: 3473300
},
{
- name: "libcore.java.lang.StringTest#testCaseMapping_en_US",
- bug: 3387655
-},
-{
- name: "libcore.java.io.FileTest#test_emptyFilename",
- bug: 3387758
-},
-{
- description: "KxmlPullParser doesn't enforce top-level document element",
- names: [
- "libcore.xml.KxmlPullParserDtdTest#testDoctypeInDocumentElement",
- "libcore.xml.KxmlPullParserDtdTest#testDoctypeAfterDocumentElement"
- ],
- bug: 3452274
-},
-{
- description: "URLConnection fails on URLs containing {}",
- name: "libcore.java.net.URLConnectionTest#testMalformedUrl",
- bug: 1158780,
- substring: "java.net.URISyntaxException"
-},
-{
- description: "KxmlParser doesn't expose DTD text",
- name: "libcore.xml.KxmlPullParserDtdTest#testDoctypeWithNextToken",
- bug: 3241492
-},
-{
- description: "Expat relaxed is different from Kxml relaxed",
- names: [
- "libcore.xml.ExpatPullParserTest#testAttributeNoValueWithRelaxed",
- "libcore.xml.ExpatPullParserTest#testAttributeUnquotedValueWithRelaxed",
- "libcore.xml.ExpatPullParserTest#testMissingEntitiesWithRelaxed",
- "libcore.xml.ExpatPullParserTest#testUnterminatedEntityWithRelaxed"
- ],
- bug: 3090550
-},
-{
- description: "ExpatPullParser doesn't support nextToken() or line numbers",
- names: [
- "libcore.xml.ExpatPullParserDtdTest#testDoctypeWithNextToken",
- "libcore.xml.ExpatPullParserTest#testCdataUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testCommentUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testCustomEntitiesAreNotEvaluated",
- "libcore.xml.ExpatPullParserTest#testCustomEntitiesUsingNext",
- "libcore.xml.ExpatPullParserTest#testCustomEntitiesUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testEmptyCdataUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testEmptyComment",
- "libcore.xml.ExpatPullParserTest#testEmptyEntityReferenceUsingNext",
- "libcore.xml.ExpatPullParserTest#testEmptyEntityReferenceUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testEntityInAttributeUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testLinesAndColumns",
- "libcore.xml.ExpatPullParserTest#testMissingEntitiesInAttributesUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testMissingEntitiesInAttributesUsingNextTokenWithRelaxed",
- "libcore.xml.ExpatPullParserTest#testMissingEntitiesInAttributesUsingNextWithRelaxed",
- "libcore.xml.ExpatPullParserTest#testMissingEntitiesUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testMissingEntitiesUsingNextTokenWithRelaxed",
- "libcore.xml.ExpatPullParserTest#testProcessingInstructionUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testRegularNumericEntities",
- "libcore.xml.ExpatPullParserTest#testWhitespaceUsingNextToken",
- "libcore.xml.ExpatPullParserTest#testXmlDeclaration",
- "libcore.xml.ExpatPullParserTest#testXmlDeclarationExtraAttributes"
- ],
- bug: 3090550
-},
-{
- description: "ExpatPullParser doesn't handle surrogates properly",
- name: "libcore.xml.ExpatPullParserTest#testCharacterReferenceOfLastUtf16Surrogate",
- bug: 3090550
-},
-{
description: "RandomAccessFile missing finalizer",
name: "libcore.java.io.RandomAccessFileTest#testRandomAccessFileHasCleanupFinalizer",
bug: 3015023
@@ -146,48 +28,11 @@
bug: 2541757
},
{
- description: "Root locale uses INF for infinity but unknown locales use \u221e",
- name: "libcore.java.text.DecimalFormatSymbolsTest#test_getInstance_unknown_or_invalid_locale",
- bug: 3056617
-},
-{
- description: "Minimal days in first week is broken",
- names: [
- "libcore.java.text.OldSimpleDateFormatTest#testFormattingWeekOfYear",
- "libcore.java.text.OldSimpleDateFormatTest#testDefaultMinimalDaysInFirstWeek"
- ],
- bug: 1613709
-},
-{
- description: "Custom SimpleTimeZones not honored by SimpleDateFormat",
- name: "libcore.java.text.OldSimpleDateFormatTest#testFormattingTimezones",
- bug: 3049014
-},
-{
description: "NaN character not found when deserializing DecimalFormatSymbols",
name: "libcore.java.text.OldDecimalFormatSymbolsTest#test_RIHarmony_compatible",
bug: 3056792
},
{
- description: "DecimalFormat.formatToCharacterIterator() is failing tests",
- names: [
- "libcore.java.text.OldDecimalFormatTest#test_formatToCharacterIterator",
- "org.apache.harmony.text.tests.java.text.DecimalFormatTest#test_formatToCharacterIteratorLjava_lang_Object",
- "org.apache.harmony.text.tests.java.text.DecimalFormatTest#test_formatToCharacterIteratorLjava_lang_Object__ArithmeticException"
- ],
- bug: 3056865
-},
-{
- description: "DecimalFormat.parse returns wrong type with multiplier: expected Long but was Double",
- name: "libcore.java.text.OldDecimalFormatTest#test_parseLjava_lang_StringLjava_text_ParsePosition",
- bug: 3057080
-},
-{
- description: "DecimalFormat FieldPosition not updated with correct begin and end indices",
- name: "libcore.java.text.OldDecimalFormatTest#test_formatDLjava_lang_StringBufferLjava_text_FieldPosition",
- bug: 3057090
-},
-{
description: "DecimalFormat is limited to 127 digits",
name: "libcore.java.text.DecimalFormatTest#test_setMaximumIntegerDigits",
bug: 2400429
@@ -198,54 +43,14 @@
bug: 3042192
},
{
- description: "Cookie tests failing on the host",
- bug: 3041920,
- names: [
- "libcore.java.net.CookiesTest#testNetscapeResponse",
- "libcore.java.net.CookiesTest#testQuotedAttributeValues",
- "libcore.java.net.CookiesTest#testRfc2109Response",
- "libcore.java.net.CookiesTest#testRfc2965Response",
- "libcore.java.net.CookiesTest#testSendingCookiesFromStore"
- ],
- modes: [ "host" ]
-},
-{
- description: "Math failures when running on the host",
- names: [
- "libcore.java.lang.OldAndroidStrictMathTest#testLog1pD",
- "libcore.java.lang.OldAndroidStrictMathTest#testRintD",
- "org.apache.harmony.luni.tests.java.lang.MathTest#test_cbrt_D",
- "org.apache.harmony.luni.tests.java.lang.MathTest#test_powDD",
- "org.apache.harmony.luni.tests.java.lang.MathTest#test_sinh_D",
- "org.apache.harmony.luni.tests.java.lang.StrictMathTest#test_log1p_D",
- "org.apache.harmony.luni.tests.java.lang.StrictMathTest#test_rintD"
- ],
- bug: 2931959,
- modes: [ "host" ]
-},
-{
- description: "Double.parseDouble().toString does wrong rounding",
- names: [
- "libcore.java.lang.OldDoubleTest#test_parseDoubleLjava_lang_String",
- "libcore.java.lang.DoubleTest#testParseLargestSubnormalDoublePrecision"
- ],
- bug: 1607938
-},
-{
description: "We fake support for these by substituting similar (but not identical) charsets",
names: [
"libcore.java.nio.charset.OldCharset_MultiByte_Big5#test_Decode",
"libcore.java.nio.charset.OldCharset_MultiByte_Big5#test_Encode",
- "libcore.java.nio.charset.OldCharset_MultiByte_EUC_JP#test_CodecDynamic",
- "libcore.java.nio.charset.OldCharset_MultiByte_EUC_JP#test_Decode",
- "libcore.java.nio.charset.OldCharset_MultiByte_EUC_JP#test_Encode",
"libcore.java.nio.charset.OldCharset_MultiByte_GB2312#test_Decode",
"libcore.java.nio.charset.OldCharset_MultiByte_GB2312#test_Encode",
"libcore.java.nio.charset.OldCharset_MultiByte_GB2312#test_nameMatch",
- "libcore.java.nio.charset.OldCharset_MultiByte_GBK#test_Decode",
"libcore.java.nio.charset.OldCharset_MultiByte_GBK#test_Encode",
- "libcore.java.nio.charset.OldCharset_MultiByte_ISO_2022_JP#test_Decode",
- "libcore.java.nio.charset.OldCharset_MultiByte_ISO_2022_JP#test_Encode",
"libcore.java.nio.charset.OldCharset_MultiByte_x_windows_950#test_Encode",
"libcore.java.nio.charset.OldCharset_MultiByte_x_windows_950#test_nameMatch"
],
@@ -256,41 +61,19 @@
names: [
"libcore.java.nio.charset.CharsetEncoderTest#test_defaultReplacementBytesUtf_16",
"libcore.java.nio.charset.OldCharset_MultiByte_UTF_16#test_Encode",
- "tests.api.java.nio.charset.CharsetTest#test_UTF_16",
- "tests.api.java.nio.charset.CharsetTest#test_UTF_32",
- "tests.api.java.nio.charset.CharsetTest#test_UTF_16BE",
- "tests.api.java.nio.charset.CharsetTest#test_UTF_16LE",
- "tests.api.java.nio.charset.CharsetTest#test_UTF_32BE",
- "tests.api.java.nio.charset.CharsetTest#test_UTF_32LE",
- "tests.api.java.nio.charset.CharsetTest#test_x_UTF_16LE_BOM",
- "tests.api.java.nio.charset.CharsetTest#test_X_UTF_32BE_BOM",
- "tests.api.java.nio.charset.CharsetTest#test_X_UTF_32LE_BOM"
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_UTF_16",
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_UTF_16BE",
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_UTF_16LE",
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_UTF_32",
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_UTF_32BE",
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_UTF_32LE",
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_x_UTF_16LE_BOM",
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_X_UTF_32BE_BOM",
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#test_X_UTF_32LE_BOM"
],
bug: 2702411
},
{
- description: "HTTPS proxy broken on host",
- names: [
- "org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnectionTest#testConsequentProxyConnection",
- "org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnectionTest#testProxyAuthConnection",
- "org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnectionTest#testProxyAuthConnection_doOutput",
- "org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnectionTest#testProxyConnection",
- "org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnectionTest#testProxyConnection_Not_Found_Response"
- ],
- bug: 3032875,
- modes: [ "host" ]
-},
-{
- description: "Defining classes from byte[] not supported in Android",
- result: EXEC_FAILED,
- name: "libcore.java.lang.OldClassTest#test_getClasses_subtest0"
-},
-{
- description: "There is no protection domain set in Android.",
- result: EXEC_FAILED,
- name: "libcore.java.lang.OldClassTest#test_getProtectionDomain"
-},
-{
description: "Runtime.getRuntime().traceMethodCalls(true) doesn't return on the host, fails in CTS",
bug: 3447964,
name: "libcore.java.lang.OldRuntimeTest#test_traceMethodCalls"
@@ -299,18 +82,7 @@
description: "It's not allowed to pass null as parent class loader to a new ClassLoader anymore. Maybe we need
to change URLClassLoader to allow this? It's not specified.",
result: EXEC_FAILED,
- name: "tests.api.java.util.ResourceBundleTest#test_getBundleLjava_lang_StringLjava_util_LocaleLjava_lang_ClassLoader"
-},
-{
- description: "Fails (probably) because no protection domain is set.",
- result: EXEC_FAILED,
- names: [
- "org.apache.harmony.security.tests.java.security.AccessController2Test#test_checkPermission_InvalidPermission",
- "org.apache.harmony.security.tests.java.security.AccessController2Test#test_doPrivilegedLjava_security_PrivilegedAction",
- "org.apache.harmony.security.tests.java.security.AccessController2Test#test_doPrivilegedLjava_security_PrivilegedActionLjava_security_AccessControlContext",
- "org.apache.harmony.security.tests.java.security.AccessController2Test#test_doPrivilegedLjava_security_PrivilegedExceptionAction",
- "org.apache.harmony.security.tests.java.security.AccessController2Test#test_doPrivilegedLjava_security_PrivilegedExceptionActionLjava_security_AccessControlContext"
- ]
+ name: "org.apache.harmony.tests.java.util.ResourceBundleTest#test_getBundleLjava_lang_StringLjava_util_LocaleLjava_lang_ClassLoader"
},
{
description: "Android throws IllegalArgumentException, RI throws NullPointerException",
@@ -318,21 +90,11 @@
name: "org.apache.harmony.security.tests.java.security.SignatureTest#testUpdatebyteArrayintint2"
},
{
- description: "Android doesn't support protection domains.",
- result: EXEC_FAILED,
- name: "tests.api.java.security.PermissionCollectionTest#test_impliesLjava_security_Permission"
-},
-{
description: "Android doesn't allow null parent.",
result: EXEC_FAILED,
name: "tests.java.security.SecureClassLoaderTest#testSecureClassLoaderClassLoader"
},
{
- description: "Not all Drivers are loaded in testsetup. ClassLoader issue in DriverManager.",
- result: EXEC_FAILED,
- name: "org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testDeregisterDriver"
-},
-{
description: "not supported",
result: EXEC_FAILED,
names: [
@@ -350,7 +112,7 @@
name: "tests.java.sql.DatabaseMetaDataTest#test_getColumnsArbitrary"
},
{
- description: "Wildcard operator does not seem wo work correctly.",
+ description: "Wildcard operator does not seem to work correctly.",
result: EXEC_FAILED,
name: "tests.java.sql.DatabaseMetaDataTest#test_getColumnsSpecific"
},
@@ -809,19 +571,12 @@
]
},
{
- description: "res.close() does not wrap up",
- bug: 3403706,
- name: "libcore.java.sql.OldResultSetTest#testAfterLast"
-},
-{
description: "statement.close() does not wrap up",
bug: 3403706,
- name: "libcore.java.sql.OldResultSetTest#testBeforeFirst"
-},
-{
- description: "Not supported",
- bug: 3403706,
- name: "libcore.java.sql.OldResultSetTest#testClearWarnings"
+ names: [
+ "libcore.java.sql.OldResultSetTest#testBeforeFirst",
+ "libcore.java.sql.OldResultSetTest#testAfterLast"
+ ]
},
{
description: "Resultset.close() does not wrap up",
@@ -961,144 +716,12 @@
name: "libcore.java.sql.OldStatementTest#testGetUpdateCount"
},
{
- description: "Handshake Status is never finished. NPE in ClientSessionContext$HostAndPort.hashCode() when host
- is null",
- bug: 3403706,
- name: "tests.api.javax.net.ssl.SSLEngineTest#testHandshake"
-},
-{
- description: "com.android.org.conscrypt.SSLEngineImpl#getDelegatedTask() throws NPE instead of
- returning null",
- bug: 3403706,
- name: "tests.api.javax.net.ssl.SSLEngineTest#test_getDelegatedTask"
-},
-{
- description: "Fixed in DonutBurger, boundary checks missing",
- bug: 3403706,
- name: "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_02"
-},
-{
- description: "Fixed on DonutBurger, Wrong Exception thrown",
- bug: 3403706,
- names: [
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_03",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_04",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_ByteBuffer$ByteBuffer_02",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_ByteBuffer$ByteBuffer_03",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_ByteBuffer_ByteBuffer_02",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_ByteBuffer_ByteBuffer_03"
- ]
-},
-{
- description: "Fixed in DonutBurger, boundary checks missing",
- bug: 3403706,
- name: "tests.api.javax.net.ssl.SSLEngineTest#test_wrap_02"
-},
-{
- description: "Fixed on DonutBurger, Wrong Exception thrown",
- bug: 3403706,
- names: [
- "tests.api.javax.net.ssl.SSLEngineTest#test_wrap_04",
- "tests.api.javax.net.ssl.SSLEngineTest#test_wrap_ByteBuffer$ByteBuffer_03",
- "tests.api.javax.net.ssl.SSLEngineTest#test_wrap_ByteBuffer_ByteBuffer_03"
- ]
-},
-{
description: "ManagerFactoryParameters object is not supported and InvalidAlgorithmParameterException was
thrown.",
bug: 3403706,
name: "tests.api.javax.net.ssl.TrustManagerFactory1Test#test_initLjavax_net_ssl_ManagerFactoryParameters"
},
{
- description: "HostnameVerifier doesn't verify IP addresses",
- bug: 3299188,
- name: "tests.api.javax.net.ssl.HostnameVerifierTest#testVerifyIpAddress"
-},
-{
- description: "NO SERVER CERTIFICATE FOUND - selectSuite should not pick a suite that needs a certificate if it is missing",
- bug: 3045163,
- name: "libcore.javax.net.ssl.SSLEngineTest#test_SSLEngine_beginHandshake_noKeyStore"
-},
-{
- description: "AlertException instead of SSLException",
- bug: 3045163,
- name: "libcore.javax.net.ssl.SSLEngineTest#test_SSLEngine_setEnableSessionCreation_client"
-},
-{
- description: "SSLException instead of failure to handshake",
- bug: 3045163,
- name: "libcore.javax.net.ssl.SSLEngineTest#test_SSLEngine_setEnableSessionCreation_server"
-},
-{
- description: "SSLHandshakeException instead of failure to handshake",
- bug: 3045163,
- name: "libcore.javax.net.ssl.SSLEngineTest#test_SSLEngine_setUseClientMode"
-},
-{
- description: "method test fails once in a while. Cannot be sure that exception is thrown in every test execution.",
- bug: 3403706,
- name: "libcore.sqlite.OldDatabaseTest#testBusy_handler"
-},
-{
- description: "Database does not lock values",
- bug: 3403706,
- name: "libcore.sqlite.OldDatabaseTest#testBusy_timeout"
-},
-{
- description: "Returns wrong number for updates: returns value > 1 for select.",
- bug: 3403706,
- name: "libcore.sqlite.OldDatabaseTest#testChanges"
-},
-{
- description: "Aggregation function not called",
- bug: 3403706,
- name: "libcore.sqlite.OldDatabaseTest#testCreate_aggregate"
-},
-{
- description: "Reason for failure unknown: Database should be locked. Specification of interrupt is scarce.",
- result: EXEC_FAILED,
- name: "libcore.sqlite.OldDatabaseTest#testInterrupt"
-},
-{
- description: "not supported",
- bug: 3403706,
- name: "libcore.sqlite.OldDatabaseTest#testOpen_blob"
-},
-{
- description: "Callback never made for authorization. Results of private table are returned without further checks.",
- bug: 3403706,
- name: "libcore.sqlite.OldDatabaseTest#testSet_authorizer"
-},
-{
- description: "ASCII encoding does not work: a UTF encoded val is returned. Spec is not sufficient. Might be that test impl is wrong or String constructor for the ASCII encoding.",
- bug: 3403706,
- name: "libcore.sqlite.OldDatabaseTest#testSet_encoding"
-},
-{
- description: "db.open_blob is not supported.",
- bug: 3403706,
- name: "libcore.sqlite.OldBlobTest#testBlob"
-},
-{
- description: "Wrong value is returned in case of a prepared statement to which a '*' bound",
- bug: 3403706,
- name: "libcore.sqlite.OldStmtTest#testColumn_count"
-},
-{
- description: "ZeroBlob not supported",
- bug: 3403706,
- name: "libcore.sqlite.OldFunctionContextTest#testSet_result_zeroblob"
-},
-{
- description: "SQLite test fail",
- bug: 3403706,
- names: [
- "libcore.sqlite.OldDatabaseTest#testGet_tableString",
- "libcore.sqlite.OldDatabaseTest#testGet_tableStringStringArrayTableResult",
- "libcore.sqlite.OldStmtTest#testColumn_type"
- ]
-},
-{
modes: [ "jvm" ],
description: "The RI's formatter doesn't localize arabic properly",
names: [
@@ -1674,26 +1297,11 @@
description: "Android's PKIX validation fails on many NIST PKIX tests",
bug: 8030138,
names: [
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testBasicCertificateRevocationTests_InvalidLongSerialNumberTest18",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testBasicCertificateRevocationTests_InvalidNegativeSerialNumberTest15",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testBasicCertificateRevocationTests_InvalidRevokedCATest2",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testBasicCertificateRevocationTests_InvalidRevokedEETest3",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testBasicCertificateRevocationTests_InvalidSeparateCertificateandCRLKeysTest20",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testBasicCertificateRevocationTests_InvalidSeparateCertificateandCRLKeysTest21",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testBasicCertificateRevocationTests_InvalidUnknownCRLEntryExtensionTest8",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testBasicCertificateRevocationTests_ValidSeparateCertificateandCRLKeysTest19",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDeltaCRLs_InvaliddeltaCRLTest3",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testDeltaCRLs_InvaliddeltaCRLTest4",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDeltaCRLs_InvaliddeltaCRLTest6",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDeltaCRLs_InvaliddeltaCRLTest9",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_InvalidIDPwithindirectCRLTest23",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_InvalidcRLIssuerTest34",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_InvaliddistributionPointTest2",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_InvaliddistributionPointTest6",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_InvalidonlySomeReasonsTest15",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_InvalidonlySomeReasonsTest16",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_InvalidonlySomeReasonsTest20",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_InvalidonlySomeReasonsTest21",
+ "libcore.java.security.cert.X509CertificateNistPkitsTest#testDeltaCRLs_ValiddeltaCRLTest5",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_ValidIDPwithindirectCRLTest24",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_ValidIDPwithindirectCRLTest25",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_ValidcRLIssuerTest28",
@@ -1702,9 +1310,216 @@
"libcore.java.security.cert.X509CertificateNistPkitsTest#testDistributionPoints_ValidcRLIssuerTest33",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testKeyUsage_ValidSelfIssuedDNnameConstraintsTest19",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testVerifyingNameChaining_ValidRFC3280OptionalAttributeTypesTest8",
- "libcore.java.security.cert.X509CertificateNistPkitsTest#testVerifyingPathswithSelfIssuedCertificates_InvalidBasicSelfIssuedOldWithNewTest2",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testVerifyingPathswithSelfIssuedCertificates_ValidBasicSelfIssuedCRLSigningKeyTest6",
"libcore.java.security.cert.X509CertificateNistPkitsTest#testVerifyingPathswithSelfIssuedCertificates_ValidBasicSelfIssuedNewWithOldTest4"
]
+},
+{
+ description: "Known failure in MathTest 1^NAN should be NAN",
+ bug: 11669804,
+ name: "org.apache.harmony.tests.java.lang.MathTest#test_powDD"
+},
+{
+ description: "Known failures in PropertiesTest: We don't deal with comments in store()",
+ bug: 11686302,
+ names: [
+ "org.apache.harmony.tests.java.util.PropertiesTest#testStore_scenario0",
+ "org.apache.harmony.tests.java.util.PropertiesTest#testStore_scenario1",
+ "org.apache.harmony.tests.java.util.PropertiesTest#testStore_scenario2",
+ "org.apache.harmony.tests.java.util.PropertiesTest#testStore_scenario3",
+ "org.apache.harmony.tests.java.util.PropertiesTest#testStore_scenario9",
+ "org.apache.harmony.tests.java.util.PropertiesTest#testStore_scenario11"
+ ]
+},
+{
+ description: "Known failures in URLTest and URLDecoderTest",
+ bug: 11686814,
+ names: [
+ "org.apache.harmony.tests.java.net.URLTest#test_ConstructorLjava_net_URLLjava_lang_String",
+ "org.apache.harmony.tests.java.net.URLTest#test_sameFileLjava_net_URL",
+ "org.apache.harmony.tests.java.net.URLDecoderTest#test_decodeLjava_lang_String_Ljava_lang_String"
+ ]
+},
+{
+ description: "ScannerParseLargeFileBenchmark can cause a failure due to a timeout",
+ bug: 14865710,
+ name: "org.apache.harmony.tests.java.util.ScannerParseLargeFileBenchmarkTest"
+},
+{
+ description: "external/apache-harmony tests for java.sql are broken for various reasons. java.sql is not a high enough priority to fix.",
+ bug: 17342415,
+ names: [
+ "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testGetDataSize",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testGetIndex",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testGetParameter",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testGetRead",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testGetTransferSize",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DataTruncationTest#testDataTruncationintbooleanbooleanintint",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DateTest#test_valueOf_IllegalArgumentException",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testDeregisterDriver",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetConnectionString",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetConnectionStringProperties",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetConnectionStringStringString",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetDriver",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetDrivers",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetLogStream",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetLogWriter",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testGetLoginTimeout",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testPrintln",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testRegisterDriver",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testSetLogStream",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testSetLogWriter",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#testSetLoginTimeout",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#test_getConnection_LStringLProperties",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#test_initClass",
+ "com.android.org.apache.harmony.sql.tests.java.sql.DriverManagerTest#test_registerDriver_MultiTimes",
+ "com.android.org.apache.harmony.sql.tests.java.sql.TimestampTest#testCompareToDate",
+ "com.android.org.apache.harmony.sql.tests.java.sql.TimestampTest#testOverridingTimestamp"
+ ]
+},
+{
+ description: "java.util.logging: Android introduced config fallback behavior in LogManager.readConfiguration()",
+ bug: 13882147,
+ names: [
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.LogManagerTest#testNotExistConfigFile",
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.LoggerTest#testGetLogger_Empty",
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.LoggerTest#testGetLogger_Null",
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.LoggerTest#testGetLoggerWithRes_InvalidRes",
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.LoggerTest#testGetLoggerWithRes_Empty"
+ ]
+},
+{
+ description: "java.util.logging: Android's user.home system property cannot be cleared",
+ bug: 13882147,
+ names: [
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.FileHandlerTest#testConstructor_NoUsrHome",
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.FileHandlerTest#testConstructor_NoTmpDir_NoUsrHome"
+ ]
+},
+{
+ description: "java.util.logging: Android's user.home system property points to root (/) dir",
+ bug: 13882147,
+ name: "com.android.org.apache.harmony.logging.tests.java.util.logging.FileHandlerTest#testConstructor_NoTmpDir"
+},
+{
+ description: "java.util.logging: The defaults for FileHandler don't work on Android because they try to write to the read-only user.home dir",
+ bug: 13882147,
+ name: "com.android.org.apache.harmony.logging.tests.java.util.logging.FileHandlerTest#testDefaultValue"
+},
+{
+ description: "java.util.logging: Android's classes have been stubbed in places.",
+ bug: 13882147,
+ names: [
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.LogManagerTest#testGetLoggingMXBean"
+ ]
+},
+{
+ description: "java.util.logging: the serialized form references org.apache not com.android.org.apache",
+ bug: 13882147,
+ name: "com.android.org.apache.harmony.logging.tests.java.util.logging.LevelTest#testSerializationCompatibility"
+},
+{
+ description: "java.util.logging: Tests that require java.util.logging code changes to fix.",
+ bug: 13882147,
+ names: [
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.SocketHandlerTest#testConstructor_NoProperties",
+ "com.android.org.apache.harmony.logging.tests.java.util.logging.XMLFormatterTest#test_TestFileHandlerClass_constructor"
+ ]
+},
+{
+ description: "java.util.beans: the harmony tests were broken by Android commit 19a270e90b1e992c1f6639f355ae13564c2f3a6a",
+ bug: 17394106,
+ names: [
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testSerialization",
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testGetPropertyChangeListener_String_Normal",
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testAddPropertyChangeListener_PropertyChangeListener_String_Normal",
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testAddPropertyChangeListener_PropertyChangeListener_Normal"
+ ]
+},
+{
+ description: "java.util.beans: the serialized form references org.apache not com.android.org.apache",
+ bug: 17394106,
+ names: [
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testSerializationCompatibility"
+ ]
+},
+{
+ description: "Known precision issue in DecimalFormat",
+ bug: 17656132,
+ names: [
+ "org.apache.harmony.tests.java.text.DecimalFormatTest#test_formatDouble_bug17656132",
+ "org.apache.harmony.tests.java.text.DecimalFormatTest#test_formatDouble_roundingProblemCases"
+ ]
+},
+{
+ description: "Known failure in GregorianCalendarTest",
+ bug: 12778197,
+ name: "org.apache.harmony.tests.java.util.GregorianCalendarTest#test_computeTime"
+},
+{
+ description: "SpdyConnection issue https://github.com/square/okhttp/issues/644 crashes the test app. Android does not provide SPDY/HTTP_2 connections by default so have been suppressed.",
+ bug: 14462336,
+ names: [
+ "com.squareup.okhttp.ConnectionPoolTest",
+ "com.squareup.okhttp.internal.spdy.SpdyConnectionTest",
+ "com.squareup.okhttp.internal.http.HttpOverHttp20Draft09Test",
+ "com.squareup.okhttp.internal.http.HttpOverSpdy3Test",
+ "com.squareup.okhttp.internal.http.ResponseCacheAdapterTest",
+ "com.squareup.okhttp.internal.http.URLConnectionTest#npnSetsProtocolHeader_SPDY_3",
+ "com.squareup.okhttp.internal.http.URLConnectionTest#npnSetsProtocolHeader_HTTP_2",
+ "com.squareup.okhttp.internal.http.URLConnectionTest#zeroLengthPost_SPDY_3",
+ "com.squareup.okhttp.internal.http.URLConnectionTest#zeroLengthPost_HTTP_2",
+ "com.squareup.okhttp.internal.http.URLConnectionTest#zeroLengthPut_SPDY_3",
+ "com.squareup.okhttp.internal.http.URLConnectionTest#zeroLengthPut_HTTP_2"
+ ]
+},
+{
+ description: "Some OkHttp tests were written before the introduction of TLS_FALLBACK_SCSV and have only been fixed for APIs used by Android",
+ bug: 17962997,
+ names: [
+ "com.squareup.okhttp.SyncApiTest#recoverFromTlsHandshakeFailure",
+ "com.squareup.okhttp.AsyncApiTest#recoverFromTlsHandshakeFailure"
+ ]
+},
+{
+ description: "JavaApiConverterTest#createOkResponse_fromJavaHttpsUrlConnection works independently but fails when run with some other test(s).",
+ bug: 17962997,
+ name: "com.squareup.okhttp.internal.http.JavaApiConverterTest#createOkResponse_fromJavaHttpsUrlConnection"
+},
+{
+ description: "Okhttp test hardcodes the TLS version expected.",
+ bug: 14462336,
+ names: [
+ "com.squareup.okhttp.internal.http.URLConnectionTest#sslFallbackNotUsedWhenRecycledConnectionFails"
+ ]
+},
+{
+ description: "The test relies on SimpleDateFormat zzz producing GMT not GMT+00:00 as it does on Android. Android issue 66136.",
+ bug: 14462336,
+ names: [
+ "com.squareup.okhttp.internal.http.HttpResponseCacheTest#setIfModifiedSince"
+ ]
+},
+{
+ description: "libcore.java.text.DecimalFormatSymbolsTest#test_getInstance_unknown_or_invalid_locale assumes fallback to locale other than en_US_POSIX.",
+ bug: 17374604,
+ names: [
+ "libcore.java.text.DecimalFormatSymbolsTest#test_getInstance_unknown_or_invalid_locale"
+ ]
+},
+{
+ description: "libcore test failures on devices with a constrained (48mb) max heap size.",
+ bug : 18256012,
+ names: [
+ "com.squareup.okhttp.internal.spdy.Http20Draft09Test#tooLargeDataFrame",
+ "com.squareup.okhttp.internal.spdy.Spdy3Test#tooLargeDataFrame",
+ "libcore.java.util.zip.GZIPInputStreamTest#testLongMessage",
+ "libcore.java.util.zip.GZIPOutputStreamTest#testLongMessage",
+ "libcore.java.util.zip.ZipFileTest#testZip64Support",
+ "libcore.java.util.zip.ZipFileTest#testZipFileWithLotsOfEntries",
+ "libcore.java.util.zip.ZipInputStreamTest#testLongMessage",
+ "libcore.java.util.zip.ZipOutputStreamTest#testLongMessage"
+ ]
}
]
+
diff --git a/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/io/BufferedReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/io/BufferedReaderTest.java
deleted file mode 100644
index f101c73..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/io/BufferedReaderTest.java
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.tests.java.io;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.CharArrayReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PipedReader;
-import java.io.Reader;
-import java.io.StringReader;
-
-import junit.framework.TestCase;
-import tests.support.Support_StringReader;
-
-public class BufferedReaderTest extends TestCase {
-
- BufferedReader br;
-
- String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
-
- /**
- * The spec says that BufferedReader.readLine() considers only "\r", "\n"
- * and "\r\n" to be line separators. We must not permit additional separator
- * characters.
- */
- public void test_readLine_IgnoresEbcdic85Characters() throws IOException {
- assertLines("A\u0085B", "A\u0085B");
- }
-
- public void test_readLine_Separators() throws IOException {
- assertLines("A\nB\nC", "A", "B", "C");
- assertLines("A\rB\rC", "A", "B", "C");
- assertLines("A\r\nB\r\nC", "A", "B", "C");
- assertLines("A\n\rB\n\rC", "A", "", "B", "", "C");
- assertLines("A\n\nB\n\nC", "A", "", "B", "", "C");
- assertLines("A\r\rB\r\rC", "A", "", "B", "", "C");
- assertLines("A\n\n", "A", "");
- assertLines("A\n\r", "A", "");
- assertLines("A\r\r", "A", "");
- assertLines("A\r\n", "A");
- assertLines("A\r\n\r\n", "A", "");
- }
-
- private void assertLines(String in, String... lines) throws IOException {
- BufferedReader bufferedReader
- = new BufferedReader(new Support_StringReader(in));
- for (String line : lines) {
- assertEquals(line, bufferedReader.readLine());
- }
- assertNull(bufferedReader.readLine());
- }
-
- /**
- * @tests java.io.BufferedReader#BufferedReader(java.io.Reader)
- */
- public void test_ConstructorLjava_io_Reader() {
- // Test for method java.io.BufferedReader(java.io.Reader)
- assertTrue("Used in tests", true);
- }
-
- /**
- * @tests java.io.BufferedReader#BufferedReader(java.io.Reader, int)
- */
- public void test_ConstructorLjava_io_ReaderI() {
- // Test for method java.io.BufferedReader(java.io.Reader, int)
- assertTrue("Used in tests", true);
- }
-
- /**
- * @tests java.io.BufferedReader#close()
- */
- public void test_close() {
- // Test for method void java.io.BufferedReader.close()
- try {
- br = new BufferedReader(new Support_StringReader(testString));
- br.close();
- br.read();
- fail("Read on closed stream");
- } catch (IOException x) {
- return;
- }
- }
-
- /**
- * @tests java.io.BufferedReader#mark(int)
- */
- public void test_markI() throws IOException {
- // Test for method void java.io.BufferedReader.mark(int)
- char[] buf = null;
- br = new BufferedReader(new Support_StringReader(testString));
- br.skip(500);
- br.mark(1000);
- br.skip(250);
- br.reset();
- buf = new char[testString.length()];
- br.read(buf, 0, 500);
- assertTrue("Failed to set mark properly", testString.substring(500,
- 1000).equals(new String(buf, 0, 500)));
-
- try {
- br = new BufferedReader(new Support_StringReader(testString), 800);
- br.skip(500);
- br.mark(250);
- br.read(buf, 0, 1000);
- br.reset();
- fail("Failed to invalidate mark properly");
- } catch (IOException x) {
- // Expected
- }
-
- char[] chars = new char[256];
- for (int i = 0; i < 256; i++)
- chars[i] = (char) i;
- Reader in = new BufferedReader(new Support_StringReader(new String(
- chars)), 12);
-
- in.skip(6);
- in.mark(14);
- in.read(new char[14], 0, 14);
- in.reset();
- assertTrue("Wrong chars", in.read() == (char) 6
- && in.read() == (char) 7);
-
- in = new BufferedReader(new Support_StringReader(new String(chars)), 12);
- in.skip(6);
- in.mark(8);
- in.skip(7);
- in.reset();
- assertTrue("Wrong chars 2", in.read() == (char) 6
- && in.read() == (char) 7);
-
- BufferedReader br = new BufferedReader(new StringReader("01234"), 2);
- br.mark(3);
- char[] carray = new char[3];
- int result = br.read(carray);
- assertEquals(3, result);
- assertEquals("Assert 0:", '0', carray[0]);
- assertEquals("Assert 1:", '1', carray[1]);
- assertEquals("Assert 2:", '2', carray[2]);
- assertEquals("Assert 3:", '3', br.read());
-
- br = new BufferedReader(new StringReader("01234"), 2);
- br.mark(3);
- carray = new char[4];
- result = br.read(carray);
- assertEquals("Assert 4:", 4, result);
- assertEquals("Assert 5:", '0', carray[0]);
- assertEquals("Assert 6:", '1', carray[1]);
- assertEquals("Assert 7:", '2', carray[2]);
- assertEquals("Assert 8:", '3', carray[3]);
- assertEquals("Assert 9:", '4', br.read());
- assertEquals("Assert 10:", -1, br.read());
-
- BufferedReader reader = new BufferedReader(new StringReader("01234"));
- reader.mark(Integer.MAX_VALUE);
- reader.read();
- reader.close();
- }
-
- /**
- * @tests java.io.BufferedReader#markSupported()
- */
- public void test_markSupported() {
- // Test for method boolean java.io.BufferedReader.markSupported()
- br = new BufferedReader(new Support_StringReader(testString));
- assertTrue("markSupported returned false", br.markSupported());
- }
-
- /**
- * @tests java.io.BufferedReader#read()
- */
- public void test_read() throws IOException {
- // Test for method int java.io.BufferedReader.read()
- try {
- br = new BufferedReader(new Support_StringReader(testString));
- int r = br.read();
- assertTrue("Char read improperly", testString.charAt(0) == r);
- br = new BufferedReader(new Support_StringReader(new String(
- new char[] { '\u8765' })));
- assertTrue("Wrong double byte character", br.read() == '\u8765');
- } catch (java.io.IOException e) {
- fail("Exception during read test");
- }
-
- char[] chars = new char[256];
- for (int i = 0; i < 256; i++)
- chars[i] = (char) i;
- Reader in = new BufferedReader(new Support_StringReader(new String(
- chars)), 12);
- try {
- assertEquals("Wrong initial char", 0, in.read()); // Fill the
- // buffer
- char[] buf = new char[14];
- in.read(buf, 0, 14); // Read greater than the buffer
- assertTrue("Wrong block read data", new String(buf)
- .equals(new String(chars, 1, 14)));
- assertEquals("Wrong chars", 15, in.read()); // Check next byte
- } catch (IOException e) {
- fail("Exception during read test 2:" + e);
- }
-
- // regression test for HARMONY-841
- assertTrue(new BufferedReader(new CharArrayReader(new char[5], 1, 0), 2).read() == -1);
- }
-
- /**
- * @tests java.io.BufferedReader#read(char[], int, int)
- */
- public void test_read$CII() throws Exception{
- char[] ca = new char[2];
- BufferedReader toRet = new BufferedReader(new InputStreamReader(
- new ByteArrayInputStream(new byte[0])));
-
- /* Null buffer should throw NPE even when len == 0 */
- try {
- toRet.read(null, 1, 0);
- fail("null buffer reading zero bytes should throw NPE");
- } catch (NullPointerException e) {
- //expected
- }
-
- try {
- toRet.close();
- } catch (IOException e) {
- fail("unexpected 1: " + e);
- }
-
- try {
- toRet.read(null, 1, 0);
- fail("null buffer reading zero bytes on closed stream should throw IOException");
- } catch (IOException e) {
- //expected
- }
-
- /* Closed reader should throw IOException reading zero bytes */
- try {
- toRet.read(ca, 0, 0);
- fail("Reading zero bytes on a closed reader should not work");
- } catch (IOException e) {
- // expected
- }
-
- /*
- * Closed reader should throw IOException in preference to index out of
- * bounds
- */
- try {
- // Read should throw IOException before
- // ArrayIndexOutOfBoundException
- toRet.read(ca, 1, 5);
- fail("IOException should have been thrown");
- } catch (IOException e) {
- // expected
- }
-
- // Test to ensure that a drained stream returns 0 at EOF
- toRet = new BufferedReader(new InputStreamReader(
- new ByteArrayInputStream(new byte[2])));
- try {
- assertEquals("Emptying the reader should return two bytes", 2,
- toRet.read(ca, 0, 2));
- assertEquals("EOF on a reader should be -1", -1, toRet.read(ca, 0,
- 2));
- assertEquals("Reading zero bytes at EOF should work", 0, toRet
- .read(ca, 0, 0));
- } catch (IOException ex) {
- fail("Unexpected IOException : " + ex.getLocalizedMessage());
- }
-
- // Test for method int java.io.BufferedReader.read(char [], int, int)
- try {
- char[] buf = new char[testString.length()];
- br = new BufferedReader(new Support_StringReader(testString));
- br.read(buf, 50, 500);
- assertTrue("Chars read improperly", new String(buf, 50, 500)
- .equals(testString.substring(0, 500)));
- } catch (java.io.IOException e) {
- fail("Exception during read test");
- }
-
- BufferedReader bufin = new BufferedReader(new Reader() {
- int size = 2, pos = 0;
-
- char[] contents = new char[size];
-
- public int read() throws IOException {
- if (pos >= size)
- throw new IOException("Read past end of data");
- return contents[pos++];
- }
-
- public int read(char[] buf, int off, int len) throws IOException {
- if (pos >= size)
- throw new IOException("Read past end of data");
- int toRead = len;
- if (toRead > (size - pos))
- toRead = size - pos;
- System.arraycopy(contents, pos, buf, off, toRead);
- pos += toRead;
- return toRead;
- }
-
- public boolean ready() throws IOException {
- return size - pos > 0;
- }
-
- public void close() throws IOException {
- }
- });
- try {
- bufin.read();
- int result = bufin.read(new char[2], 0, 2);
- assertTrue("Incorrect result: " + result, result == 1);
- } catch (IOException e) {
- fail("Unexpected: " + e);
- }
-
- //regression for HARMONY-831
- try{
- new BufferedReader(new PipedReader(), 9).read(new char[] {}, 7, 0);
- fail("should throw IndexOutOfBoundsException");
- }catch(IndexOutOfBoundsException e){
- }
-
- // Regression for HARMONY-54
- char[] ch = {};
- BufferedReader reader = new BufferedReader(new CharArrayReader(ch));
- try {
- // Check exception thrown when the reader is open.
- reader.read(null, 1, 0);
- fail("Assert 0: NullPointerException expected");
- } catch (NullPointerException e) {
- // Expected
- }
-
- // Now check IOException is thrown in preference to
- // NullPointerexception when the reader is closed.
- reader.close();
- try {
- reader.read(null, 1, 0);
- fail("Assert 1: IOException expected");
- } catch (IOException e) {
- // Expected
- }
-
- try {
- // And check that the IOException is thrown before
- // ArrayIndexOutOfBoundException
- reader.read(ch, 0, 42);
- fail("Assert 2: IOException expected");
- } catch (IOException e) {
- // expected
- }
- }
-
- /**
- * @tests java.io.BufferedReader#read(char[], int, int)
- */
- public void test_read_$CII_Exception() throws IOException {
- br = new BufferedReader(new Support_StringReader(testString));
- char[] nullCharArray = null;
- char[] charArray = testString.toCharArray();
-
- try {
- br.read(nullCharArray, -1, -1);
- fail();
- } catch (NullPointerException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- br.read(nullCharArray, -1, 0);
- fail();
- } catch (NullPointerException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- br.read(nullCharArray, 0, -1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- br.read(nullCharArray, 0, 0);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- br.read(nullCharArray, 0, 1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- br.read(charArray, -1, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- br.read(charArray, -1, 0);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- br.read(charArray, 0, 0);
- br.read(charArray, 0, charArray.length);
- br.read(charArray, charArray.length, 0);
-
- try {
- br.read(charArray, charArray.length + 1, 0);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- br.read(charArray, charArray.length + 1, 1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- br.close();
-
- try {
- br.read(nullCharArray, -1, -1);
- fail("should throw IOException");
- } catch (IOException e) {
- // expected
- }
-
- try {
- br.read(charArray, -1, 0);
- fail("should throw IOException");
- } catch (IOException e) {
- // expected
- }
-
- try {
- br.read(charArray, 0, -1);
- fail("should throw IOException");
- } catch (IOException e) {
- // expected
- }
- }
- /**
- * @tests java.io.BufferedReader#readLine()
- */
- public void test_readLine() {
- // Test for method java.lang.String java.io.BufferedReader.readLine()
- try {
- br = new BufferedReader(new Support_StringReader(testString));
- String r = br.readLine();
- assertEquals("readLine returned incorrect string", "Test_All_Tests", r
- );
- } catch (java.io.IOException e) {
- fail("Exception during readLine test");
- }
- }
-
- /**
- * @tests java.io.BufferedReader#ready()
- */
- public void test_ready() {
- // Test for method boolean java.io.BufferedReader.ready()
- try {
- br = new BufferedReader(new Support_StringReader(testString));
- assertTrue("ready returned false", br.ready());
- } catch (java.io.IOException e) {
- fail("Exception during ready test" + e.toString());
- }
- }
-
- /**
- * @tests java.io.BufferedReader#reset()
- */
- public void test_reset() {
- // Test for method void java.io.BufferedReader.reset()
- try {
- br = new BufferedReader(new Support_StringReader(testString));
- br.skip(500);
- br.mark(900);
- br.skip(500);
- br.reset();
- char[] buf = new char[testString.length()];
- br.read(buf, 0, 500);
- assertTrue("Failed to reset properly", testString.substring(500,
- 1000).equals(new String(buf, 0, 500)));
- } catch (java.io.IOException e) {
- fail("Exception during reset test");
- }
- try {
- br = new BufferedReader(new Support_StringReader(testString));
- br.skip(500);
- br.reset();
- fail("Reset succeeded on unmarked stream");
- } catch (IOException x) {
- return;
-
- }
- }
-
- public void test_reset_IOException() throws Exception {
- int[] expected = new int[] { '1', '2', '3', '4', '5', '6', '7', '8',
- '9', '0', -1 };
- br = new BufferedReader(new Support_StringReader("1234567890"), 9);
- br.mark(9);
- for (int i = 0; i < 11; i++) {
- assertEquals(expected[i], br.read());
- }
- try {
- br.reset();
- fail("should throw IOException");
- } catch (IOException e) {
- // Expected
- }
- for (int i = 0; i < 11; i++) {
- assertEquals(-1, br.read());
- }
-
- br = new BufferedReader(new Support_StringReader("1234567890"));
- br.mark(10);
- for (int i = 0; i < 10; i++) {
- assertEquals(expected[i], br.read());
- }
- br.reset();
- for (int i = 0; i < 11; i++) {
- assertEquals(expected[i], br.read());
- }
- }
-
- /**
- * @tests java.io.BufferedReader#skip(long)
- */
- public void test_skipJ() {
- // Test for method long java.io.BufferedReader.skip(long)
- try {
- br = new BufferedReader(new Support_StringReader(testString));
- br.skip(500);
- char[] buf = new char[testString.length()];
- br.read(buf, 0, 500);
- assertTrue("Failed to set skip properly", testString.substring(500,
- 1000).equals(new String(buf, 0, 500)));
- } catch (java.io.IOException e) {
- fail("Exception during skip test");
- }
-
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- try {
- br.close();
- } catch (Exception e) {
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/ScannerParseLargeFileBenchmarkTest.java b/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/ScannerParseLargeFileBenchmarkTest.java
deleted file mode 100644
index 117f211..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/ScannerParseLargeFileBenchmarkTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.luni.tests.java.util;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Scanner;
-
-import junit.framework.TestCase;
-
-public class ScannerParseLargeFileBenchmarkTest extends TestCase {
-
- /**
- * This test will check when parse a large file like more than 200M bytes if
- * the Scanner will exhaust all heap memory
- */
- public void testParseLargeFile() throws Exception {
- MyReader reader = new MyReader();
- String delimiter = "\r?\n";
- Scanner scanner = new Scanner(reader).useDelimiter(delimiter);
-
- while (scanner.hasNext()) {
- scanner.next();
- }
- scanner.close();
- reader.close();
- }
-
- private static class MyReader extends Reader {
- static final char[] CONTENT = "large file!\n".toCharArray();
-
- static long fileLength = (8 << 21) * 12;
-
- static boolean first = true;
-
- static int position = 0;
-
- private int count = 0;
-
- @Override
- public void close() throws IOException {
- }
-
- @Override
- public int read(char[] buf, int offset, int length) {
- if (count >= fileLength) {
- return -1;
- }
- if (first == true) {
- position = 0;
- first = false;
- }
- for (int i = offset; i < length; i++) {
- buf[i] = CONTENT[(i + position) % CONTENT.length];
- count++;
- }
-
- position = (length + position) % CONTENT.length;
-
- return length - offset;
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/ScannerTest.java b/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/ScannerTest.java
deleted file mode 100644
index b3e1abc..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/ScannerTest.java
+++ /dev/null
@@ -1,5634 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.luni.tests.java.util;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.io.StringReader;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.nio.channels.FileChannel;
-import java.nio.channels.IllegalBlockingModeException;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.InputMismatchException;
-import java.util.List;
-import java.util.Locale;
-import java.util.NoSuchElementException;
-import java.util.regex.MatchResult;
-import java.util.regex.Pattern;
-import java.util.Scanner;
-
-import junit.framework.TestCase;
-
-public class ScannerTest extends TestCase {
-
- private Scanner s;
-
- private ServerSocket server;
-
- private SocketAddress address;
-
- private SocketChannel client;
-
- private Socket serverSocket;
-
- private OutputStream os;
-
- private static class MockCloseable implements Closeable, Readable {
-
- public void close() throws IOException {
- throw new IOException();
- }
-
- public int read(CharBuffer cb) throws IOException {
- throw new EOFException();
- }
-
- }
-
- /**
- * @tests java.util.Scanner#Scanner(File)
- */
- public void test_ConstructorLjava_io_File() throws IOException {
- File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
- s = new Scanner(tmpFile);
- assertNotNull(s);
- s.close();
- assertTrue(tmpFile.delete());
-
- try {
- s = new Scanner(tmpFile);
- fail();
- } catch (FileNotFoundException expected) {
- }
-
- tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
- FileOutputStream fos = new FileOutputStream(tmpFile);
- fos.write("test".getBytes());
- fos.close();
-
- s = new Scanner(tmpFile);
- s.close();
- tmpFile.delete();
-
- // Scanner(File = null)
- try {
- s = new Scanner((File) null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // TODO: test if the default charset is used.
- }
-
- /**
- * @tests java.util.Scanner#Scanner(File, String)
- */
- public void test_ConstructorLjava_io_FileLjava_lang_String()
- throws IOException {
- File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
- s = new Scanner(tmpFile, Charset.defaultCharset().name());
- assertNotNull(s);
- s.close();
- assertTrue(tmpFile.delete());
-
- try {
- s = new Scanner(tmpFile, Charset.defaultCharset().name());
- fail();
- } catch (FileNotFoundException expected) {
- }
-
- try {
- s = new Scanner(tmpFile, null);
- fail();
- } catch (FileNotFoundException expected) {
- }
-
- tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
- try {
- s = new Scanner(tmpFile, "invalid charset");
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- //fail on RI. File is opened but not closed when exception is thrown on
- // RI.
- assertTrue(tmpFile.delete());
-
- // Scanner(File = null, Charset = null)
- try {
- s = new Scanner((File) null, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Scanner(File = null, Charset = UTF-8)
- try {
- s = new Scanner((File) null, "UTF-8");
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Scanner(File = null, Charset = invalid)
- try {
- s = new Scanner((File) null, "invalid");
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Scanner(File, Charset = null)
- try {
- File f = File.createTempFile("test", ".tmp");
- s = new Scanner(f, null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- // TODO: test if the specified charset is used.
- }
-
- /**
- * @tests java.util.Scanner#Scanner(InputStream)
- */
- public void test_ConstructorLjava_io_InputStream() {
- s = new Scanner(new PipedInputStream());
- assertNotNull(s);
- s.close();
-
- // Scanner(InputStream)
- try {
- s = new Scanner((InputStream) null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // TODO: test if the default charset is used.
- }
-
- /**
- * @tests java.util.Scanner#Scanner(InputStream, String)
- */
- public void test_ConstructorLjava_io_InputStreamLjava_lang_String() {
- s = new Scanner(new PipedInputStream(), Charset.defaultCharset().name());
- assertNotNull(s);
- s.close();
-
- try {
- s = new Scanner((PipedInputStream) null, "invalid charset");
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- s = new Scanner(new PipedInputStream(), null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- s = new Scanner(new PipedInputStream(), "invalid charset");
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- // TODO: test if the specified charset is used.
- }
-
- /**
- * @tests java.util.Scanner#Scanner(Readable)
- */
- public void test_ConstructorLjava_lang_Readable() {
- s = new Scanner(new StringReader("test string"));
- assertNotNull(s);
- s.close();
-
- // Scanner(Readable)
- try {
- s = new Scanner((Readable) null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- /**
- * @tests java.util.Scanner#Scanner(ReadableByteChannel)
- */
- public void test_ConstructorLjava_nio_channels_ReadableByteChannel()
- throws IOException {
- File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
- FileChannel fc = new FileOutputStream(tmpFile).getChannel();
- s = new Scanner(fc);
- assertNotNull(s);
- s.close();
- assertTrue(tmpFile.delete());
-
- // Scanner(ReadableByteChannel)
- try {
- s = new Scanner((ReadableByteChannel) null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Test if the default charset is used.
- String sampleData = "1 2 3 4 5 6 7 8 9 10";
- File tempFile = File.createTempFile("harmony", "test");
- tempFile.deleteOnExit();
- FileOutputStream os = new FileOutputStream(tempFile);
- os.write(sampleData.getBytes());
- os.close();
-
- FileInputStream is = new FileInputStream(tempFile);
- FileChannel channel = is.getChannel();
-
- Scanner s = new Scanner(channel);
- int count = 0;
- while (s.hasNextInt()) {
- s.nextInt();
- count++;
- }
- channel.close();
- assertEquals(10, count);
- }
-
- /**
- * @tests java.util.Scanner#Scanner(ReadableByteChannel, String)
- */
- public void test_ConstructorLjava_nio_channels_ReadableByteChannelLjava_lang_String()
- throws IOException {
- File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
- FileChannel fc = new FileOutputStream(tmpFile).getChannel();
- s = new Scanner(fc, Charset.defaultCharset().name());
- assertNotNull(s);
- s.close();
-
- fc = new FileOutputStream(tmpFile).getChannel();
- try {
- s = new Scanner(fc, "invalid charset");
- fail();
- } catch (IllegalArgumentException expected) {
- }
- fc.close();
- assertTrue(tmpFile.delete());
-
- // Scanner(ReadableByteChannel = null, Charset = null)
- try {
- s = new Scanner((ReadableByteChannel) null, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Scanner(ReadableByteChannel = null, Charset = invalid)
- try {
- s = new Scanner((ReadableByteChannel) null, "invalid");
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Scanner(ReadableByteChannel, Charset = null)
- try {
- s = new Scanner(fc, null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- // TODO: test if the specified charset is used.
- }
-
- public void test_Constructor_LReadableByteChannel() throws IOException {
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(null);
-
- SocketChannel sc = SocketChannel.open();
- sc.connect(ssc.socket().getLocalSocketAddress());
- sc.configureBlocking(false);
- assertFalse(sc.isBlocking());
-
- ssc.accept().close();
- ssc.close();
- assertFalse(sc.isBlocking());
-
- Scanner s = new Scanner(sc);
- try {
- s.hasNextInt();
- fail();
- } catch (IllegalBlockingModeException expected) {
- }
-
- sc.close();
- }
-
- /**
- * @tests java.util.Scanner#Scanner(String)
- */
- public void test_ConstructorLjava_lang_String() {
- s = new Scanner("test string");
- assertNotNull(s);
- s.close();
-
- // Scanner(String)
- try {
- s = new Scanner((String) null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- /**
- * @tests java.util.Scanner#close()
- */
- public void test_close() throws IOException {
- File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
- FileOutputStream fos = new FileOutputStream(tmpFile);
- FileChannel fc = fos.getChannel();
- s = new Scanner(fc);
-
- // Write out a int before the scanner is closed, should be OK.
- fos.write(12);
-
- s.close();
- assertFalse(fc.isOpen());
-
- // Write out a int after the scanner is closed, IOException should be
- // thrown out.
- try {
- fos.write(12);
- fail();
- } catch (IOException expected) {
- }
-
- s.close(); // no exception should be thrown
- assertTrue(tmpFile.delete());
- }
-
- /**
- * @tests java.util.Scanner#ioException()
- */
- public void test_ioException() throws IOException {
- MockCloseable mc = new MockCloseable();
- s = new Scanner(mc);
- assertNull(s.ioException()); // No operation, no exception
-
- s.close(); // IOException should be cached
- assertNotNull(s.ioException());
- assertTrue(s.ioException() instanceof IOException);
- }
-
- /**
- * @tests java.util.Scanner#delimiter()
- */
- public void test_delimiter() {
- s = new Scanner("test");
- Pattern pattern = s.delimiter();
- assertEquals("\\p{javaWhitespace}+", pattern.toString());
- }
-
- /**
- * @tests java.util.Scanner#useDelimiter(Pattern)
- */
- public void test_useDelimiter_LPattern() {
- s = new Scanner("test");
- s.useDelimiter(Pattern.compile("\\w+"));
- assertEquals("\\w+", s.delimiter().toString());
-
- s = new Scanner("test");
- s.useDelimiter((Pattern) null);
- assertNull(s.delimiter());
- }
-
- /**
- * @tests java.util.Scanner#useDelimiter(String)
- */
- public void test_useDelimiter_String() {
- s = new Scanner("test");
- try {
- s.useDelimiter((String) null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- s = new Scanner("test");
- s.useDelimiter("\\w+");
- assertEquals("\\w+", s.delimiter().toString());
- }
-
- /**
- * @tests java.util.Scanner#locale()
- */
- public void test_locale() {
- s = new Scanner("test");
- assertEquals(Locale.getDefault(), s.locale());
- }
-
- /**
- * @tests java.util.Scanner#useLocale(Locale)
- */
- public void test_useLocale_LLocale() {
- s = new Scanner("test");
- try {
- s.useLocale(null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- s.useLocale(new Locale("test", "test"));
- assertEquals(new Locale("test", "test"), s.locale());
- }
-
- /**
- * @tests java.util.Scanner#radix()
- */
- public void test_radix() {
- s = new Scanner("test");
- assertEquals(10, s.radix());
- }
-
- /**
- * @tests java.util.Scanner#useRadix()
- */
- public void test_useRadix_I() {
- s = new Scanner("test");
- try {
- s.useRadix(Character.MIN_RADIX - 1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- s.useRadix(Character.MAX_RADIX + 1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- s.useRadix(11);
- assertEquals(11, s.radix());
- }
-
- /**
- * @tests java.util.Scanner#remove()
- */
- public void test_remove() {
- s = new Scanner("aab*b*").useDelimiter("\\*");
- try {
- s.remove();
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- /**
- * @tests java.util.Scanner#match()
- */
- public void test_match() {
- MatchResult result ;
- s = new Scanner("1 2 ");
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
- assertEquals("1", s.next());
- assertEquals("2", s.next());
- result = s.match();
- assertEquals(2, result.start());
- assertEquals(3, result.end());
- assertEquals(2, result.start(0));
- assertEquals(3, result.end(0));
- assertEquals("2", result.group());
- assertEquals("2", result.group(0));
- assertEquals(0, result.groupCount());
- try {
- result.start(1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("True faLse");
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
- assertTrue(s.nextBoolean());
- result = s.match();
- assertEquals(0, result.start());
- assertEquals(4, result.end());
- assertEquals(0, result.start(0));
- assertEquals(4, result.end(0));
- assertEquals("True", result.group());
- assertEquals(0, result.groupCount());
- assertFalse(s.nextBoolean());
- try {
- s.nextBoolean();
- fail();
- } catch (NoSuchElementException expected) {
- }
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("True faLse");
- assertTrue(s.nextBoolean());
- result = s.match();
- assertEquals(0, result.start());
- assertEquals(4, result.end());
- assertEquals(0, result.start(0));
- assertEquals(4, result.end(0));
- assertEquals("True", result.group());
- assertEquals(0, result.groupCount());
- s.close();
- try {
- s.nextBoolean();
- fail();
- } catch (IllegalStateException expected) {
- }
- result = s.match();
- assertEquals(0, result.start());
- assertEquals(4, result.end());
- assertEquals(0, result.start(0));
- assertEquals(4, result.end(0));
- assertEquals("True", result.group());
- assertEquals(0, result.groupCount());
-
- s = new Scanner("True fase");
- assertTrue(s.nextBoolean());
- assertEquals(0, result.groupCount());
- try {
- s.nextBoolean();
- fail();
- } catch (InputMismatchException expected) {
- }
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("True fase");
- assertTrue(s.nextBoolean());
- try {
- s.next((Pattern)null);
- fail();
- } catch (NullPointerException expected) {
- }
- result = s.match();
- assertEquals(0, result.start());
- assertEquals(4, result.end());
- assertEquals(0, result.start(0));
- assertEquals(4, result.end(0));
- assertEquals("True", result.group());
- assertEquals(0, result.groupCount());
-
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#next()
- */
- public void test_next() throws IOException {
- // use special delimiter
- s = new Scanner("1**2").useDelimiter("\\*");
- assertEquals("1", s.next());
- assertEquals("", s.next());
- assertEquals("2", s.next());
-
- s = new Scanner(" \t 1 \t 2").useDelimiter("\\s*");
- assertEquals("1", s.next());
- assertEquals("2", s.next());
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("a").useDelimiter("a?");
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("aa").useDelimiter("a?");
- assertEquals("", s.next());
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
-
- s = new Scanner("word( )test( )").useDelimiter("\\( \\)");
- assertEquals("word", s.next());
- assertEquals("test", s.next());
-
- s = new Scanner("? next ").useDelimiter("( )");
- assertEquals("?", s.next());
- assertEquals("next", s.next());
- assertEquals("", s.next());
-
- s = new Scanner("word1 word2 ");
- assertEquals("word1", s.next());
- assertEquals("word2", s.next());
- // test boundary case
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // just delimiter exists in this scanner
- s = new Scanner(" ");
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // nothing exists in this scanner
- s = new Scanner("");
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // no delimiter exists in this scanner
- s = new Scanner("test");
- assertEquals("test", s.next());
-
- // input resourse starts with delimiter
- s = new Scanner(" test");
- assertEquals("test", s.next());
-
- // input resource ends with delimiter
- s = new Scanner(" test ");
- assertEquals("test", s.next());
-
- // Harmony uses 1024 as default buffer size,
- // What if a sentence can not be read in all in once.
- StringBuilder longSentence = new StringBuilder(1025);
- for (int i = 0; i < 11; i++) {
- longSentence.append(" ");
- }
- for (int i = 11; i < 1026; i++) {
- longSentence.append("a");
- }
- s = new Scanner(longSentence.toString());
- assertEquals(longSentence.toString().trim(), s.next());
-
- s = new Scanner(" test test");
- assertEquals("test", s.next());
- assertEquals("test", s.next());
-
- // What if use a delimiter of length 0.
- s = new Scanner("test\ntest").useDelimiter(Pattern.compile("^",
- Pattern.MULTILINE));
- assertEquals("test\n", s.next());
- assertEquals("test", s.next());
-
- s = new Scanner("").useDelimiter(Pattern.compile("^",
- Pattern.MULTILINE));
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("").useDelimiter(Pattern.compile("^*",
- Pattern.MULTILINE));
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("test\ntest").useDelimiter(Pattern.compile("^*",
- Pattern.MULTILINE));
- assertEquals("t", s.next());
- assertEquals("e", s.next());
-
- s = new Scanner("\ntest\ntest").useDelimiter(Pattern.compile("$",
- Pattern.MULTILINE));
- assertEquals("\ntest", s.next());
- assertEquals("\ntest", s.next());
-
- // test socket inputStream
- // Harmony uses 1024 as default buffer size,
- // what if the leading delimiter is larger than 1023
- for (int i = 0; i < 1024; i++) {
- os.write(" ".getBytes());
- }
- os.write(" 1 2 ".getBytes());
- s = new Scanner(client);
- assertEquals("1", s.next());
- assertEquals("2", s.next());
- os.write(" 1 2".getBytes());
- serverSocket.close();
- assertEquals("1", s.next());
- assertEquals("2", s.next());
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#next(Pattern)
- */
- public void test_nextLPattern() throws IOException {
- Pattern pattern;
- s = new Scanner("aab*2*").useDelimiter("\\*");
- pattern = Pattern.compile("a*b");
- assertEquals("aab", s.next(pattern));
- try {
- s.next(pattern);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("word ? ");
- pattern = Pattern.compile("\\w+");
- assertEquals("word", s.next(pattern));
- try {
- s.next(pattern);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("word1 word2 ");
- pattern = Pattern.compile("\\w+");
- assertEquals("word1", s.next(pattern));
- assertEquals("word2", s.next(pattern));
- // test boundary case
- try {
- s.next(pattern);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // test socket inputStream
-
- os.write("aab 2".getBytes());
- serverSocket.close();
-
- s = new Scanner(client);
- pattern = Pattern.compile("a*b");
- assertEquals("aab", s.next(pattern));
- try {
- s.next(pattern);
- fail();
- } catch (InputMismatchException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#next(String)
- */
- public void test_nextLString() throws IOException {
- s = new Scanner("b*a*").useDelimiter("\\*");
- assertEquals("b", s.next("a*b"));
- try {
- s.next("a*b");
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("word ? ");
- assertEquals("word", s.next("\\w+"));
- try {
- s.next("\\w+");
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("word1 next ");
- assertEquals("word1", s.next("\\w+"));
- assertEquals("next", s.next("\\w+"));
- // test boundary case
- try {
- s.next("\\w+");
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // test socket inputStream
- os.write("aab 2".getBytes());
- serverSocket.close();
-
- s = new Scanner(client);
- assertEquals("aab", s.next("a*b"));
- try {
- s.next("a*b");
- fail();
- } catch (InputMismatchException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextBoolean()
- */
- public void test_nextBoolean() throws IOException {
- // case insensitive
- s = new Scanner("TRue");
- assertTrue(s.nextBoolean());
-
- s = new Scanner("tRue false");
- assertTrue(s.nextBoolean());
- assertFalse(s.nextBoolean());
- try {
- s.nextBoolean();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("true1");
- try {
- s.nextBoolean();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- try {
- s = new Scanner("");
- s.nextBoolean();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // test socket inputStream
- os.write("true false".getBytes());
- serverSocket.close();
-
- s = new Scanner(client);
- assertTrue(s.nextBoolean());
- assertFalse(s.nextBoolean());
-
- // ues '*' as delimiter
- s = new Scanner("true**false").useDelimiter("\\*");
- assertTrue(s.nextBoolean());
- try {
- s.nextBoolean();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("false( )").useDelimiter("\\( \\)");
- assertFalse(s.nextBoolean());
-
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextInt(int)
- */
- public void test_nextIntI() throws IOException {
- s = new Scanner("123 456");
- assertEquals(123, s.nextInt(10));
- assertEquals(456, s.nextInt(10));
- try {
- s.nextInt(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- assertEquals(38, s.nextInt(5));
- try {
- s.nextInt(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789123456789123456789123456789");
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextInt(10));
- assertEquals(23456, s.nextInt(10));
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextInt(10));
- assertEquals(23456, s.nextInt(10));
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(102, s.nextInt(10));
- try {
- s.nextInt(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertEquals(162, s.nextInt(10));
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextInt(10));
- assertEquals(23456, s.nextInt(10));
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertEquals(3456, s.nextInt(10));
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(3456, s.nextInt(10));
-
- s = new Scanner("E3456");
- assertEquals(930902, s.nextInt(16));
- // The following test case fails on RI, because RI does not support
- // letter as leading digit
- s = new Scanner("E3,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(930902, s.nextInt(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextInt(10));
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextInt(10));
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextInt(10));
-
- /*
- * There are three types of negative prefix all in all. '' '-' '(' There
- * are three types of negative suffix all in all. '' '-' ')' '(' and ')'
- * must be used togethor. Prefix '-' and suffix '-' must be used
- * exclusively.
- */
-
- /*
- * According to Integer regular expression: Integer :: = ( [-+]? (*
- * Numeral ) ) | LocalPositivePrefix Numeral LocalPositiveSuffix |
- * LocalNegativePrefix Numeral LocalNegativeSuffix 123- should be
- * recognized by scanner with locale ar_AE, (123) shouble be recognized
- * by scanner with locale mk_MK. But this is not the case on RI.
- */
- s = new Scanner("-123 123- -123-");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(-123, s.nextInt(10));
- // The following test case fails on RI
- assertEquals(-123, s.nextInt(10));
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("-123 123-");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(-123, s.nextInt(10));
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
- // Skip the un-recognizable token 123-.
- assertEquals("123-", s.next());
-
- // If the parameter radix is illegal, the following test cases fail on
- // RI
- try {
- s.nextInt(Character.MIN_RADIX - 1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- s.nextInt(Character.MAX_RADIX + 1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextInt()
- */
- public void test_nextInt() throws IOException {
- s = new Scanner("123 456");
- assertEquals(123, s.nextInt());
- assertEquals(456, s.nextInt());
- try {
- s.nextInt();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- s.useRadix(5);
- assertEquals(38, s.nextInt());
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789123456789123456789123456789");
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextInt());
- assertEquals(23456, s.nextInt());
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextInt());
- assertEquals(23456, s.nextInt());
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(102, s.nextInt());
- s.useRadix(5);
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertEquals(162, s.nextInt());
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextInt());
- assertEquals(23456, s.nextInt());
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertEquals(3456, s.nextInt());
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(3456, s.nextInt());
-
- s = new Scanner("E3456");
- s.useRadix(16);
- assertEquals(930902, s.nextInt());
-
- // The following test case fails on RI, because RI does not support
- // letter as leading digit
- s = new Scanner("E3,456");
- s.useLocale(Locale.ENGLISH);
- s.useRadix(16);
- assertEquals(930902, s.nextInt());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextInt());
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextInt());
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextInt());
-
- /*
- * There are three types of negative prefix all in all. '' '-' '(' There
- * are three types of negative suffix all in all. '' '-' ')' '(' and ')'
- * must be used togethor. Prefix '-' and suffix '-' must be used
- * exclusively.
- */
-
- /*
- * According to Integer regular expression: Integer :: = ( [-+]? (*
- * Numeral ) ) | LocalPositivePrefix Numeral LocalPositiveSuffix |
- * LocalNegativePrefix Numeral LocalNegativeSuffix 123- should be
- * recognized by scanner with locale ar_AE, (123) shouble be recognized
- * by scanner with locale mk_MK. But this is not the case on RI.
- */
- s = new Scanner("-123 123- -123-");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(-123, s.nextInt());
- // The following test case fails on RI
- assertEquals(-123, s.nextInt());
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("-123 123-");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(-123, s.nextInt());
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
- // Skip the un-recognizable token 123-.
- assertEquals("123-", s.next());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextByte(int)
- */
- public void test_nextByteI() throws IOException {
- s = new Scanner("123 126");
- assertEquals(123, s.nextByte(10));
- assertEquals(126, s.nextByte(10));
- try {
- s.nextByte(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 126");
- assertEquals(38, s.nextByte(5));
- try {
- s.nextByte(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("1234");
- try {
- s.nextByte(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 12\u0666");
- assertEquals(102, s.nextByte(10));
- try {
- s.nextByte(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertEquals(126, s.nextByte(10));
-
- s = new Scanner("012");
- assertEquals(12, s.nextByte(10));
-
- s = new Scanner("E");
- assertEquals(14, s.nextByte(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("100");
- s.useLocale(Locale.CHINESE);
- assertEquals(100, s.nextByte(10));
-
- s = new Scanner("1\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(100, s.nextByte(10));
-
- s = new Scanner("1\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(100, s.nextByte(10));
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(-123, s.nextByte(10));
-
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(-123, s.nextByte(10));
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextByte()
- */
- public void test_nextByte() throws IOException {
- s = new Scanner("123 126");
- assertEquals(123, s.nextByte());
- assertEquals(126, s.nextByte());
- try {
- s.nextByte();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 126");
- s.useRadix(5);
- assertEquals(38, s.nextByte());
- try {
- s.nextByte();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("1234");
- try {
- s.nextByte();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 12\u0666");
- assertEquals(102, s.nextByte());
- s.useRadix(5);
- try {
- s.nextByte();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertEquals(126, s.nextByte());
-
- s = new Scanner("012");
- assertEquals(12, s.nextByte());
-
- s = new Scanner("E");
- s.useRadix(16);
- assertEquals(14, s.nextByte());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("100");
- s.useLocale(Locale.CHINESE);
- assertEquals(100, s.nextByte());
-
- s = new Scanner("1\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(100, s.nextByte());
-
- s = new Scanner("1\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(100, s.nextByte());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(-123, s.nextByte());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(-123, s.nextByte());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextFloat()
- */
- public void test_nextFloat() throws IOException {
- s = new Scanner("123 45\u0666. 123.4 .123 ");
- s.useLocale(Locale.ENGLISH);
- assertEquals((float)123.0, s.nextFloat());
- assertEquals((float)456.0, s.nextFloat());
- assertEquals((float)123.4, s.nextFloat());
- assertEquals((float)0.123, s.nextFloat());
- try {
- s.nextFloat();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
- s.useLocale(Locale.ENGLISH);
- assertEquals((float)123.4, s.nextFloat());
- assertEquals((float)-456.7, s.nextFloat());
- assertEquals((float)123456.789, s.nextFloat());
- try {
- s.nextFloat();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // Scientific notation
- s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
- s.useLocale(Locale.ENGLISH);
- assertEquals((float)1.234E12, s.nextFloat());
- assertEquals((float)-4.567E14, s.nextFloat());
- assertEquals((float)1.23456789E-5, s.nextFloat());
-
- s = new Scanner("NaN Infinity -Infinity");
- assertEquals(Float.NaN, s.nextFloat());
- assertEquals(Float.POSITIVE_INFINITY, s.nextFloat());
- assertEquals(Float.NEGATIVE_INFINITY, s.nextFloat());
-
- String str=String.valueOf(Float.MAX_VALUE*2);
- s=new Scanner(str);
- assertEquals(Float.POSITIVE_INFINITY,s.nextFloat());
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals((float)23456.0, s.nextFloat());
- s.useLocale(Locale.GERMANY);
- assertEquals((float)23.456, s.nextFloat());
-
- s = new Scanner("23.456 23.456");
- s.useLocale(Locale.ENGLISH);
- assertEquals((float)23.456, s.nextFloat());
- s.useLocale(Locale.GERMANY);
- assertEquals((float)23456.0, s.nextFloat());
-
- s = new Scanner("23,456.7 23.456,7");
- s.useLocale(Locale.ENGLISH);
- assertEquals((float)23456.7, s.nextFloat());
- s.useLocale(Locale.GERMANY);
- assertEquals((float)23456.7, s.nextFloat());
-
- s = new Scanner("-123.4 123.4- -123.4-");
- s.useLocale(new Locale("ar", "AE"));
- // FIXME
-// assertEquals((float)-123.4, s.nextFloat());
-// //The following test case fails on RI
-// assertEquals((float)-123.4, s.nextFloat());
- try {
- s.nextFloat();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("123- -123");
- s.useLocale(new Locale("mk", "MK"));
- try {
- s.nextFloat();
- fail();
- } catch (InputMismatchException expected) {
- }
- // Skip the un-recognizable token 123-.
- assertEquals("123-", s.next());
- assertEquals((float)-123.0, s.nextFloat());
-
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextBigInteger(int)
- */
- public void test_nextBigIntegerI() throws IOException {
- s = new Scanner("123 456");
- assertEquals(new BigInteger("123"), s.nextBigInteger(10));
- assertEquals(new BigInteger("456"), s.nextBigInteger(10));
- try {
- s.nextBigInteger(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- assertEquals(new BigInteger("38"), s.nextBigInteger(5));
- try {
- s.nextBigInteger(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextBigInteger(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextBigInteger(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(new BigInteger("102"), s.nextBigInteger(10));
- try {
- s.nextBigInteger(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertEquals(new BigInteger("162"), s.nextBigInteger(10));
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- try {
- s.nextBigInteger(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- try {
- s.nextBigInteger(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertEquals(new BigInteger("3456"), s.nextBigInteger(10));
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigInteger("3456"), s.nextBigInteger(10));
-
- s = new Scanner("E34");
- assertEquals(new BigInteger("3636"), s.nextBigInteger(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(new BigInteger("-123"), s.nextBigInteger(10));
-
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(new BigInteger("-123"), s.nextBigInteger(10));
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextBigInteger()
- */
- public void test_nextBigInteger() throws IOException {
- s = new Scanner("123 456");
- assertEquals(new BigInteger("123"), s.nextBigInteger());
- assertEquals(new BigInteger("456"), s.nextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- s.useRadix(5);
- assertEquals(new BigInteger("38"), s.nextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(new BigInteger("102"), s.nextBigInteger());
- s.useRadix(5);
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertEquals(new BigInteger("162"), s.nextBigInteger());
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertEquals(new BigInteger("3456"), s.nextBigInteger());
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigInteger("3456"), s.nextBigInteger());
-
- s = new Scanner("E34");
- s.useRadix(16);
- assertEquals(new BigInteger("3636"), s.nextBigInteger());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertEquals(new BigInteger("12300"), s.nextBigInteger());
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(new BigInteger("12300"), s.nextBigInteger());
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(new BigInteger("12300"), s.nextBigInteger());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(new BigInteger("-123"), s.nextBigInteger());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(new BigInteger("-123"), s.nextBigInteger());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextShort(int)
- */
- public void test_nextShortI() throws IOException {
- s = new Scanner("123 456");
- assertEquals(123, s.nextShort(10));
- assertEquals(456, s.nextShort(10));
- try {
- s.nextShort(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- assertEquals(38, s.nextShort(5));
- try {
- s.nextShort(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789");
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextShort(10));
- assertEquals(23456, s.nextShort(10));
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextShort(10));
- assertEquals(23456, s.nextShort(10));
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(102, s.nextShort(10));
- try {
- s.nextShort(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertEquals(162, s.nextShort(10));
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextShort(10));
- assertEquals(23456, s.nextShort(10));
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertEquals(3456, s.nextShort(10));
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(3456, s.nextShort(10));
-
- s = new Scanner("E34");
- assertEquals(3636, s.nextShort(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextShort(10));
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextShort(10));
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextShort(10));
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(-123, s.nextShort(10));
-
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(-123, s.nextShort(10));
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextShort()
- */
- public void test_nextShort() throws IOException {
- s = new Scanner("123 456");
- assertEquals(123, s.nextShort());
- assertEquals(456, s.nextShort());
- try {
- s.nextShort();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- s.useRadix(5);
- assertEquals(38, s.nextShort());
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789");
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextShort());
- assertEquals(23456, s.nextShort());
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextShort());
- assertEquals(23456, s.nextShort());
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(102, s.nextShort());
- s.useRadix(5);
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertEquals(162, s.nextShort());
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextShort());
- assertEquals(23456, s.nextShort());
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertEquals(3456, s.nextShort());
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(3456, s.nextShort());
-
- s = new Scanner("E34");
- s.useRadix(16);
- assertEquals(3636, s.nextShort());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextShort());
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextShort());
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextShort());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(-123, s.nextShort());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(-123, s.nextShort());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextLong(int)
- */
- public void test_nextLongI() throws IOException {
- s = new Scanner("123 456");
- assertEquals(123, s.nextLong(10));
- assertEquals(456, s.nextLong(10));
- try {
- s.nextLong(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- assertEquals(38, s.nextLong(5));
- try {
- s.nextLong(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789123456789123456789123456789");
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextLong(10));
- assertEquals(23456, s.nextLong(10));
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextLong(10));
- assertEquals(23456, s.nextLong(10));
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(102, s.nextLong(10));
- try {
- s.nextLong(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertEquals(162, s.nextLong(10));
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextLong(10));
- assertEquals(23456, s.nextLong(10));
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertEquals(3456, s.nextLong(10));
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(3456, s.nextLong(10));
-
- s = new Scanner("E34");
- assertEquals(3636, s.nextLong(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextLong(10));
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextLong(10));
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextLong(10));
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(-123, s.nextLong(10));
-
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(-123, s.nextLong(10));
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextLong()
- */
- public void test_nextLong() throws IOException {
- s = new Scanner("123 456");
- assertEquals(123, s.nextLong());
- assertEquals(456, s.nextLong());
- try {
- s.nextLong();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- s.useRadix(5);
- assertEquals(38, s.nextLong());
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789123456789123456789123456789");
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextLong());
- assertEquals(23456, s.nextLong());
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextLong());
- assertEquals(23456, s.nextLong());
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(102, s.nextLong());
- s.useRadix(5);
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertEquals(162, s.nextLong());
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertEquals(23456, s.nextLong());
- assertEquals(23456, s.nextLong());
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertEquals(3456, s.nextLong());
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(3456, s.nextLong());
-
- s = new Scanner("E34");
- s.useRadix(16);
- assertEquals(3636, s.nextLong());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextLong());
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextLong());
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertEquals(12300, s.nextLong());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertEquals(-123, s.nextLong());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertEquals(-123, s.nextLong());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNext()
- */
- public void test_hasNext() throws IOException {
- s = new Scanner("1##2").useDelimiter("\\#");
- assertTrue(s.hasNext());
- assertEquals("1", s.next());
- assertEquals("", s.next());
- assertEquals("2", s.next());
- assertFalse(s.hasNext());
- s.close();
- try {
- s.hasNext();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("1( )2( )").useDelimiter("\\( \\)");
- assertTrue(s.hasNext());
- assertTrue(s.hasNext());
- assertEquals("1", s.next());
- assertEquals("2", s.next());
-
- s = new Scanner("1 2 ").useDelimiter("( )");
- assertEquals("1", s.next());
- assertEquals("2", s.next());
- assertTrue(s.hasNext());
- assertEquals("", s.next());
-
- s = new Scanner("1\n2 ");
- assertEquals("1", s.next());
- assertTrue(s.hasNext());
- assertEquals("2", s.next());
- assertFalse(s.hasNext());
- // test boundary case
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("1'\n'2 ");
- assertEquals("1'", s.next());
- assertTrue(s.hasNext());
- assertEquals("'2", s.next());
- assertFalse(s.hasNext());
- // test boundary case
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner(" ");
- assertFalse(s.hasNext());
-
- // test socket inputStream
-
- os.write("1 2".getBytes());
- serverSocket.close();
-
- s = new Scanner(client);
- assertEquals("1", s.next());
- assertTrue(s.hasNext());
- assertEquals("2", s.next());
- assertFalse(s.hasNext());
- try {
- s.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNext(Pattern)
- */
- public void test_hasNextLPattern() throws IOException {
- Pattern pattern;
- s = new Scanner("aab@2@abb@").useDelimiter("\\@");
- pattern = Pattern.compile("a*b");
- assertTrue(s.hasNext(pattern));
- assertEquals("aab", s.next(pattern));
- assertFalse(s.hasNext(pattern));
- try {
- s.next(pattern);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("word ? ");
- pattern = Pattern.compile("\\w+");
- assertTrue(s.hasNext(pattern));
- assertEquals("word", s.next(pattern));
- assertFalse(s.hasNext(pattern));
- try {
- s.next(pattern);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("word1 WorD2 ");
- pattern = Pattern.compile("\\w+");
- assertTrue(s.hasNext(pattern));
- assertEquals("word1", s.next(pattern));
- assertTrue(s.hasNext(pattern));
- assertEquals("WorD2", s.next(pattern));
- assertFalse(s.hasNext(pattern));
- try {
- s.next(pattern);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("word1 WorD2 ");
- pattern = Pattern.compile("\\w+");
- try {
- s.hasNext((Pattern) null);
- fail();
- } catch (NullPointerException expected) {
- }
- s.close();
- try {
- s.hasNext(pattern);
- fail();
- } catch (IllegalStateException expected) {
- }
-
- // test socket inputStream
- os.write("aab b".getBytes());
- serverSocket.close();
-
- s = new Scanner(client);
- pattern = Pattern.compile("a+b");
- assertTrue(s.hasNext(pattern));
- assertEquals("aab", s.next(pattern));
- assertFalse(s.hasNext(pattern));
- try {
- s.next(pattern);
- fail();
- } catch (InputMismatchException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNext(String)
- */
- public void test_hasNextLString() throws IOException {
- s = new Scanner("aab@2@abb@").useDelimiter("\\@");
- try {
- s.hasNext((String)null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- s = new Scanner("aab*b*").useDelimiter("\\*");
- assertTrue(s.hasNext("a+b"));
- assertEquals("aab", s.next("a+b"));
- assertFalse(s.hasNext("a+b"));
- try {
- s.next("a+b");
- fail();
- } catch (InputMismatchException expected) {
- }
- s.close();
- try {
- s.hasNext("a+b");
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("WORD ? ");
- assertTrue(s.hasNext("\\w+"));
- assertEquals("WORD", s.next("\\w+"));
- assertFalse(s.hasNext("\\w+"));
- try {
- s.next("\\w+");
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("word1 word2 ");
- assertEquals("word1", s.next("\\w+"));
- assertEquals("word2", s.next("\\w+"));
- // test boundary case
- try {
- s.next("\\w+");
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // test socket inputStream
-
- os.write("aab 2".getBytes());
- serverSocket.close();
-
- s = new Scanner(client);
- assertTrue(s.hasNext("a*b"));
- assertEquals("aab", s.next("a*b"));
- assertFalse(s.hasNext("a*b"));
- try {
- s.next("a*b");
- fail();
- } catch (InputMismatchException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextBoolean()
- */
- public void test_hasNextBoolean() throws IOException {
-
- s = new Scanner("TRue");
- assertTrue(s.hasNextBoolean());
- assertTrue(s.nextBoolean());
-
- s = new Scanner("tRue false");
- assertTrue(s.hasNextBoolean());
- assertTrue(s.nextBoolean());
- assertTrue(s.hasNextBoolean());
- assertFalse(s.nextBoolean());
-
- s = new Scanner("");
- assertFalse(s.hasNextBoolean());
-
- // test socket inputStream
-
- os.write("true false ".getBytes());
- serverSocket.close();
-
- s = new Scanner(client);
- assertTrue(s.hasNextBoolean());
- assertTrue(s.nextBoolean());
-
- // ues '*' as delimiter
- s = new Scanner("true**false").useDelimiter("\\*");
- assertTrue(s.hasNextBoolean());
- assertTrue(s.nextBoolean());
- assertFalse(s.hasNextBoolean());
- try {
- s.nextBoolean();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("false( )").useDelimiter("\\( \\)");
- assertTrue(s.hasNextBoolean());
- assertFalse(s.nextBoolean());
- assertFalse(s.hasNextBoolean());
-
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextByte(int)
- */
- public void test_hasNextByteI() throws IOException {
- s = new Scanner("123 126");
- assertTrue(s.hasNextByte(10));
- assertEquals(123, s.nextByte(10));
- assertTrue(s.hasNextByte(10));
- assertEquals(126, s.nextByte(10));
- assertFalse(s.hasNextByte(10));
- try {
- s.nextByte(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 126");
- assertTrue(s.hasNextByte(5));
- assertEquals(38, s.nextByte(5));
- assertFalse(s.hasNextByte(5));
- try {
- s.nextByte(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("1234");
- assertFalse(s.hasNextByte(10));
- try {
- s.nextByte(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 12\u0666");
- assertTrue(s.hasNextByte(10));
- assertEquals(102, s.nextByte(10));
- assertFalse(s.hasNextByte(5));
- try {
- s.nextByte(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertTrue(s.hasNextByte(10));
- assertEquals(126, s.nextByte(10));
-
- s = new Scanner("012");
- assertTrue(s.hasNextByte(10));
- assertEquals(12, s.nextByte(10));
-
- s = new Scanner("E");
- assertTrue(s.hasNextByte(16));
- assertEquals(14, s.nextByte(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("100");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextByte(10));
- assertEquals(100, s.nextByte(10));
-
- s = new Scanner("1\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextByte(10));
- assertEquals(100, s.nextByte(10));
-
- s = new Scanner("1\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextByte(10));
- assertEquals(100, s.nextByte(10));
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextByte(10));
- assertEquals(-123, s.nextByte(10));
-
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextByte(10));
- assertEquals(-123, s.nextByte(10));
- }
-
- public void test_hasNextByteI_cache() throws IOException{
- //regression for HARMONY-2063
- s = new Scanner("123 45");
- assertTrue(s.hasNextByte(8));
- assertEquals(83, s.nextByte());
- assertEquals(45, s.nextByte());
-
- s = new Scanner("123 45");
- assertTrue(s.hasNextByte(10));
- assertTrue(s.hasNextByte(8));
- assertEquals(83, s.nextByte());
- assertEquals(45, s.nextByte());
-
- s = new Scanner("-123 -45");
- assertTrue(s.hasNextByte(8));
- assertEquals(-123, s.nextInt());
- assertEquals(-45, s.nextByte());
-
- s = new Scanner("123 45");
- assertTrue(s.hasNextByte());
- s.close();
- try {
- s.nextByte();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- public void test_hasNextByte() throws IOException {
- s = new Scanner("123 126");
- assertTrue(s.hasNextByte());
- assertEquals(123, s.nextByte());
- assertTrue(s.hasNextByte());
- assertEquals(126, s.nextByte());
- assertFalse(s.hasNextByte());
- try {
- s.nextByte();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 126");
- s.useRadix(5);
- assertTrue(s.hasNextByte());
- assertEquals(38, s.nextByte());
- assertFalse(s.hasNextByte());
- try {
- s.nextByte();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("1234");
- assertFalse(s.hasNextByte());
- try {
- s.nextByte();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 12\u0666");
- assertTrue(s.hasNextByte());
- assertEquals(102, s.nextByte());
- s.useRadix(5);
- assertFalse(s.hasNextByte());
- try {
- s.nextByte();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertTrue(s.hasNextByte());
- assertEquals(126, s.nextByte());
-
- s = new Scanner("012");
- assertEquals(12, s.nextByte());
-
- s = new Scanner("E");
- s.useRadix(16);
- assertTrue(s.hasNextByte());
- assertEquals(14, s.nextByte());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("100");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextByte());
- assertEquals(100, s.nextByte());
-
- s = new Scanner("1\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextByte());
- assertEquals(100, s.nextByte());
-
- s = new Scanner("1\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextByte());
- assertEquals(100, s.nextByte());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextByte());
- assertEquals(-123, s.nextByte());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextByte());
- assertEquals(-123, s.nextByte());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextBigInteger(int)
- */
- public void test_hasNextBigIntegerI() throws IOException {
- s = new Scanner("123 456");
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("123"), s.nextBigInteger(10));
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("456"), s.nextBigInteger(10));
- assertFalse(s.hasNextBigInteger(10));
- try {
- s.nextBigInteger(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- assertTrue(s.hasNextBigInteger(5));
- assertEquals(new BigInteger("38"), s.nextBigInteger(5));
- assertFalse(s.hasNextBigInteger(5));
- try {
- s.nextBigInteger(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextBigInteger(10));
- try {
- s.nextBigInteger(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextBigInteger(10));
- try {
- s.nextBigInteger(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("102"), s.nextBigInteger(10));
- assertFalse(s.hasNextBigInteger(5));
- try {
- s.nextBigInteger(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("162"), s.nextBigInteger(10));
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- assertFalse(s.hasNextBigInteger(10));
- try {
- s.nextBigInteger(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- assertFalse(s.hasNextBigInteger(10));
- try {
- s.nextBigInteger(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("3456"), s.nextBigInteger(10));
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("3456"), s.nextBigInteger(10));
-
- s = new Scanner("E34");
- assertTrue(s.hasNextBigInteger(16));
- assertEquals(new BigInteger("3636"), s.nextBigInteger(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("-123"), s.nextBigInteger(10));
-
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("-123"), s.nextBigInteger(10));
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextBigInteger(int)
- */
- public void test_hasNextBigIntegerI_cache() throws IOException {
- //regression for HARMONY-2063
- s = new Scanner("123 123456789123456789");
- assertTrue(s.hasNextBigInteger(16));
- assertEquals(new BigInteger("291"), s.nextBigInteger());
- assertEquals(new BigInteger("123456789123456789"), s.nextBigInteger());
-
- s = new Scanner("123456789123456789 456");
- assertTrue(s.hasNextBigInteger(16));
- assertTrue(s.hasNextBigInteger(10));
- assertEquals(new BigInteger("123456789123456789"), s.nextBigInteger());
- assertEquals(new BigInteger("456"), s.nextBigInteger());
-
- s = new Scanner("-123 -123456789123456789");
- assertTrue(s.hasNextBigInteger(8));
- assertEquals(-123, s.nextShort());
- assertEquals(new BigInteger("-123456789123456789"), s.nextBigInteger());
-
- s = new Scanner("123 456");
- assertTrue(s.hasNextBigInteger());
- s.close();
- try {
- s.nextBigInteger();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextBigInteger()
- */
- public void test_hasNextBigInteger() throws IOException {
- s = new Scanner("123 456");
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("123"), s.nextBigInteger());
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("456"), s.nextBigInteger());
- assertFalse(s.hasNextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- s.useRadix(5);
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("38"), s.nextBigInteger());
- assertFalse(s.hasNextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(new BigInteger("102"), s.nextBigInteger());
- s.useRadix(5);
- assertFalse(s.hasNextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("162"), s.nextBigInteger());
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- assertFalse(s.hasNextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("23456"), s.nextBigInteger());
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- assertFalse(s.hasNextBigInteger());
- try {
- s.nextBigInteger();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("3456"), s.nextBigInteger());
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("3456"), s.nextBigInteger());
-
- s = new Scanner("E34");
- s.useRadix(16);
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("3636"), s.nextBigInteger());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("12300"), s.nextBigInteger());
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("12300"), s.nextBigInteger());
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("12300"), s.nextBigInteger());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("-123"), s.nextBigInteger());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextBigInteger());
- assertEquals(new BigInteger("-123"), s.nextBigInteger());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextInt(int)
- */
- public void test_hasNextIntI() throws IOException {
- s = new Scanner("123 456");
- assertEquals(123, s.nextInt(10));
- assertTrue(s.hasNextInt(10));
- assertEquals(456, s.nextInt(10));
- assertFalse(s.hasNextInt(10));
- try {
- s.nextInt(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- assertTrue(s.hasNextInt(5));
- assertEquals(38, s.nextInt(5));
- assertFalse(s.hasNextInt(5));
- try {
- s.nextInt(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789123456789123456789123456789");
- assertFalse(s.hasNextInt(10));
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextInt(10));
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextInt(10));
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextInt(10));
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextInt(10));
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06662");
- assertTrue(s.hasNextInt(10));
- assertFalse(s.hasNextInt(5));
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666");
- s.useLocale(Locale.CHINESE);
- assertFalse(s.hasNextInt(10));
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextInt(10));
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- assertFalse(s.hasNextInt(10));
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertTrue(s.hasNextInt(10));
- assertEquals(3456, s.nextInt(10));
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextInt(10));
- assertEquals(3456, s.nextInt(10));
-
- s = new Scanner("E3456");
- assertTrue(s.hasNextInt(16));
- assertEquals(930902, s.nextInt(16));
- // The following test case fails on RI, because RI does not support
- // letter as leading digit
- s = new Scanner("E3,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextInt(16));
- assertEquals(930902, s.nextInt(16));
-
- // If parameter radix is illegal, the following test case fails on RI
- try {
- s.hasNextInt(Character.MIN_RADIX - 1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextInt(10));
- assertEquals(12300, s.nextInt(10));
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextInt(10));
- assertEquals(12300, s.nextInt(10));
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextInt(10));
- assertEquals(12300, s.nextInt(10));
-
- /*
- * There are three types of negative prefix all in all. '' '-' '(' There
- * are three types of negative suffix all in all. '' '-' ')' '(' and ')'
- * must be used together. Prefix '-' and suffix '-' must be used
- * exclusively.
- */
-
- /*
- * According to Integer regular expression: Integer :: = ( [-+]? (*
- * Numeral ) ) | LocalPositivePrefix Numeral LocalPositiveSuffix |
- * LocalNegativePrefix Numeral LocalNegativeSuffix 123- should be
- * recognized by scanner with locale ar_AE, (123) should be recognized
- * by scanner with locale mk_MK. But this is not the case on RI.
- */
- s = new Scanner("-123 123- -123-");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextInt(10));
- assertEquals(-123, s.nextInt(10));
- // The following test case fails on RI
- assertTrue(s.hasNextInt(10));
- assertEquals(-123, s.nextInt(10));
- assertFalse(s.hasNextInt(10));
- try {
- s.nextInt(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("-123 123-");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextInt(10));
- assertEquals(-123, s.nextInt(10));
- assertFalse(s.hasNextInt(10));
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
- // Skip the un-recognizable token 123-.
- assertEquals("123-", s.next());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextInt(int)
- */
- public void test_hasNextIntI_cache() throws IOException {
- //regression for HARMONY-2063
- s = new Scanner("123 456");
- assertTrue(s.hasNextInt(16));
- assertEquals(291, s.nextInt(10));
- assertEquals(456, s.nextInt());
-
- s = new Scanner("123 456");
- assertTrue(s.hasNextInt(16));
- assertTrue(s.hasNextInt(8));
- assertEquals(83, s.nextInt());
- assertEquals(456, s.nextInt());
-
- s = new Scanner("-123 -456 -789");
- assertTrue(s.hasNextInt(8));
- assertEquals(-123, s.nextShort());
- assertEquals(-456, s.nextInt());
- assertTrue(s.hasNextShort(16));
- assertEquals(-789, s.nextInt());
-
- s = new Scanner("123 456");
- assertTrue(s.hasNextInt());
- s.close();
- try {
- s.nextInt();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextInt()
- */
- public void test_hasNextInt() throws IOException {
- s = new Scanner("123 456");
- assertTrue(s.hasNextInt());
- assertEquals(123, s.nextInt());
- assertEquals(456, s.nextInt());
- assertFalse(s.hasNextInt());
- try {
- s.nextInt();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- s.useRadix(5);
- assertTrue(s.hasNextInt());
- assertEquals(38, s.nextInt());
- assertFalse(s.hasNextInt());
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789123456789123456789123456789");
- assertFalse(s.hasNextInt());
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextInt());
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextInt());
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextInt());
- s.useLocale(new Locale("it", "CH"));
- assertTrue(s.hasNextInt());
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06662");
- s.useRadix(5);
- assertFalse(s.hasNextInt());
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666");
- s.useLocale(Locale.CHINESE);
- assertFalse(s.hasNextInt());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextInt());
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- assertFalse(s.hasNextInt());
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertTrue(s.hasNextInt());
- assertEquals(3456, s.nextInt());
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(3456, s.nextInt());
-
- s = new Scanner("E3456");
- s.useRadix(16);
- assertTrue(s.hasNextInt());
- assertEquals(930902, s.nextInt());
-
- // The following test case fails on RI, because RI does not support
- // letter as leading digit
- s = new Scanner("E3,456");
- s.useLocale(Locale.ENGLISH);
- s.useRadix(16);
- assertTrue(s.hasNextInt());
- assertEquals(930902, s.nextInt());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextInt());
- assertEquals(12300, s.nextInt());
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextInt());
- assertEquals(12300, s.nextInt());
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextInt());
- assertEquals(12300, s.nextInt());
-
- /*
- * There are three types of negative prefix all in all. '' '-' '(' There
- * are three types of negative suffix all in all. '' '-' ')' '(' and ')'
- * must be used togethor. Prefix '-' and suffix '-' must be used
- * exclusively.
- */
-
- /*
- * According to Integer regular expression: Integer :: = ( [-+]? (*
- * Numeral ) ) | LocalPositivePrefix Numeral LocalPositiveSuffix |
- * LocalNegativePrefix Numeral LocalNegativeSuffix 123- should be
- * recognized by scanner with locale ar_AE, (123) shouble be recognized
- * by scanner with locale mk_MK. But this is not the case on RI.
- */
- s = new Scanner("-123 123- -123-");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextInt());
- assertEquals(-123, s.nextInt());
- // The following test case fails on RI
- assertTrue(s.hasNextInt());
- assertEquals(-123, s.nextInt());
- assertFalse(s.hasNextInt());
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("-123 123-");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextInt());
- assertEquals(-123, s.nextInt());
- try {
- s.nextInt();
- fail();
- } catch (InputMismatchException expected) {
- }
- // Skip the un-recognizable token 123-.
- assertEquals("123-", s.next());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextFloat()
- */
- public void test_hasNextFloat() throws IOException {
- s = new Scanner("123 45\u0666. 123.4 .123 ");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextFloat());
- assertEquals((float)123.0, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals((float)456.0, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals((float)123.4, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals((float)0.123, s.nextFloat());
- assertFalse(s.hasNextFloat());
- try {
- s.nextFloat();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextFloat());
- assertEquals((float)123.4, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals((float)-456.7, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals((float)123456.789, s.nextFloat());
- assertFalse(s.hasNextFloat());
- try {
- s.nextFloat();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // Scientific notation
- s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextFloat());
- assertEquals((float)1.234E12, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals((float)-4.567E14, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals((float)1.23456789E-5, s.nextFloat());
-
- s = new Scanner("NaN Infinity -Infinity");
- assertTrue(s.hasNextFloat());
- assertEquals(Float.NaN, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals(Float.POSITIVE_INFINITY, s.nextFloat());
- assertTrue(s.hasNextFloat());
- assertEquals(Float.NEGATIVE_INFINITY, s.nextFloat());
-
- String str=String.valueOf(Float.MAX_VALUE*2);
- s=new Scanner(str);
- assertTrue(s.hasNextFloat());
- assertEquals(Float.POSITIVE_INFINITY,s.nextFloat());
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextFloat());
- assertEquals((float)23456.0, s.nextFloat());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextFloat());
- assertEquals((float)23.456, s.nextFloat());
-
- s = new Scanner("23.456 23.456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextFloat());
- assertEquals((float)23.456, s.nextFloat());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextFloat());
- assertEquals((float)23456.0, s.nextFloat());
-
- s = new Scanner("23,456.7 23.456,7");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextFloat());
- assertEquals((float)23456.7, s.nextFloat());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextFloat());
- assertEquals((float)23456.7, s.nextFloat());
-
- //FIXME
-// s = new Scanner("-123.4 123.4- -123.4-");
-// s.useLocale(new Locale("ar", "AE"));
-// assertTrue(s.hasNextFloat());
-// assertEquals((float)-123.4, s.nextFloat());
-// //The following test case fails on RI
-// assertTrue(s.hasNextFloat());
-// assertEquals((float)-123.4, s.nextFloat());
-// try {
-// s.nextFloat();
-// fail();
-// } catch (InputMismatchException expected) {
-// }
-
- s = new Scanner("123- -123");
- s.useLocale(new Locale("mk", "MK"));
- assertFalse(s.hasNextFloat());
- try {
- s.nextFloat();
- fail();
- } catch (InputMismatchException expected) {
- }
- // Skip the un-recognizable token 123-.
- assertEquals("123-", s.next());
- assertTrue(s.hasNextFloat());
- assertEquals((float)-123.0, s.nextFloat());
-
- s = new Scanner("+123.4 -456.7");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextFloat());
- s.close();
- try{
- s.nextFloat();
- fail();
- }catch(IllegalStateException expected) {
- }
-
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextShort(int)
- */
- public void test_hasNextShortI() throws IOException {
- s = new Scanner("123 456");
- assertTrue(s.hasNextShort(10));
- assertEquals(123, s.nextShort(10));
- assertTrue(s.hasNextShort(10));
- assertEquals(456, s.nextShort(10));
- assertFalse(s.hasNextShort(10));
- try {
- s.nextShort(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- assertTrue(s.hasNextShort(5));
- assertEquals(38, s.nextShort(5));
- assertFalse(s.hasNextShort(5));
- try {
- s.nextShort(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789");
- assertFalse(s.hasNextShort(10));
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextShort(10));
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextShort(10));
- assertEquals(23456, s.nextInt(10));
- assertTrue(s.hasNextShort(10));
- assertEquals(23456, s.nextInt(10));
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextShort(10));
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextShort(10));
- assertEquals(23456, s.nextShort(10));
- assertTrue(s.hasNextShort(10));
- assertEquals(23456, s.nextShort(10));
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertTrue(s.hasNextShort(10));
- assertEquals(102, s.nextShort(10));
- assertFalse(s.hasNextShort(5));
- try {
- s.nextShort(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertTrue(s.hasNextShort(10));
- assertEquals(162, s.nextShort(10));
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- assertFalse(s.hasNextShort(10));
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextShort(10));
- assertEquals(23456, s.nextShort(10));
- assertTrue(s.hasNextShort(10));
- assertEquals(23456, s.nextShort(10));
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- assertFalse(s.hasNextShort(10));
- try {
- s.nextShort(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertTrue(s.hasNextShort(10));
- assertEquals(3456, s.nextShort(10));
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextShort(10));
- assertEquals(3456, s.nextShort(10));
-
- s = new Scanner("E34");
- assertTrue(s.hasNextShort(16));
- assertEquals(3636, s.nextShort(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextShort(10));
- assertEquals(12300, s.nextShort(10));
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextShort(10));
- assertEquals(12300, s.nextShort(10));
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextShort(10));
- assertEquals(12300, s.nextShort(10));
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextShort(10));
- assertEquals(-123, s.nextShort(10));
-
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextShort(10));
- assertEquals(-123, s.nextShort(10));
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextShort()
- */
- public void test_hasNextShort() throws IOException {
- s = new Scanner("123 456");
- assertTrue(s.hasNextShort());
- assertEquals(123, s.nextShort());
- assertTrue(s.hasNextShort());
- assertEquals(456, s.nextShort());
- assertFalse(s.hasNextShort());
- try {
- s.nextShort();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- s.useRadix(5);
- assertTrue(s.hasNextShort());
- assertEquals(38, s.nextShort());
- assertFalse(s.hasNextShort());
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789");
- assertFalse(s.hasNextShort());
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextShort());
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextShort());
- assertEquals(23456, s.nextShort());
- assertTrue(s.hasNextShort());
- assertEquals(23456, s.nextShort());
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextShort());
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextShort());
- assertEquals(23456, s.nextShort());
- assertTrue(s.hasNextShort());
- assertEquals(23456, s.nextShort());
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(102, s.nextShort());
- s.useRadix(5);
- assertFalse(s.hasNextShort());
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertTrue(s.hasNextShort());
- assertEquals(162, s.nextShort());
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- assertFalse(s.hasNextShort());
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextShort());
- assertEquals(23456, s.nextShort());
- assertTrue(s.hasNextShort());
- assertEquals(23456, s.nextShort());
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- assertFalse(s.hasNextShort());
- try {
- s.nextShort();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertTrue(s.hasNextShort());
- assertEquals(3456, s.nextShort());
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextShort());
- assertEquals(3456, s.nextShort());
-
- s = new Scanner("E34");
- s.useRadix(16);
- assertTrue(s.hasNextShort());
- assertEquals(3636, s.nextShort());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextShort());
- assertEquals(12300, s.nextShort());
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextShort());
- assertEquals(12300, s.nextShort());
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextShort());
- assertEquals(12300, s.nextShort());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextShort());
- assertEquals(-123, s.nextShort());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextShort());
- assertEquals(-123, s.nextShort());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextShort(int)
- */
- public void test_hasNextShortI_cache() throws IOException {
- //regression for HARMONY-2063
- s = new Scanner("123 456");
- assertTrue(s.hasNextShort(16));
- assertEquals(291, s.nextShort());
- assertEquals(456, s.nextShort());
-
- s = new Scanner("123 456");
- assertTrue(s.hasNextShort(16));
- assertTrue(s.hasNextShort(8));
- assertEquals(83, s.nextShort());
- assertEquals(456, s.nextShort());
-
- s = new Scanner("-123 -456 -789");
- assertTrue(s.hasNextShort(8));
- assertEquals(-123, s.nextInt());
- assertEquals(-456, s.nextShort());
- assertTrue(s.hasNextInt(16));
- assertEquals(-789, s.nextShort());
-
- s = new Scanner("123 456");
- assertTrue(s.hasNextShort());
- s.close();
- try {
- s.nextShort();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextLong(int)
- */
- public void test_hasNextLongI() throws IOException {
- s = new Scanner("123 456");
- assertTrue(s.hasNextLong(10));
- assertEquals(123, s.nextLong(10));
- assertTrue(s.hasNextLong(10));
- assertEquals(456, s.nextLong(10));
- assertFalse(s.hasNextLong(10));
- try {
- s.nextLong(10);
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- assertTrue(s.hasNextLong(5));
- assertEquals(38, s.nextLong(5));
- assertFalse(s.hasNextLong(5));
- try {
- s.nextLong(5);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789123456789123456789123456789");
- assertFalse(s.hasNextLong(10));
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextShort(10));
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextLong(10));
- assertEquals(23456, s.nextLong(10));
- assertTrue(s.hasNextLong(10));
- assertEquals(23456, s.nextLong(10));
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextLong(10));
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextLong(10));
- assertEquals(23456, s.nextLong(10));
- assertTrue(s.hasNextLong(10));
- assertEquals(23456, s.nextLong(10));
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertTrue(s.hasNextLong(10));
- assertEquals(102, s.nextLong(10));
- assertFalse(s.hasNextLong(5));
- try {
- s.nextLong(5);
- fail();
- } catch (InputMismatchException expected) {
- }
- assertTrue(s.hasNextLong(10));
- assertEquals(162, s.nextLong(10));
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- assertFalse(s.hasNextLong(10));
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextLong(10));
- assertEquals(23456, s.nextLong(10));
- assertTrue(s.hasNextLong(10));
- assertEquals(23456, s.nextLong(10));
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- assertFalse(s.hasNextLong(10));
- try {
- s.nextLong(10);
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertTrue(s.hasNextLong(10));
- assertEquals(3456, s.nextLong(10));
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextLong(10));
- assertEquals(3456, s.nextLong(10));
-
- s = new Scanner("E34");
- assertTrue(s.hasNextLong(16));
- assertEquals(3636, s.nextLong(16));
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextLong(10));
- assertEquals(12300, s.nextLong(10));
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextLong(10));
- assertEquals(12300, s.nextLong(10));
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextLong(10));
- assertEquals(12300, s.nextLong(10));
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextLong(10));
- assertEquals(-123, s.nextLong(10));
-
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextLong(10));
- assertEquals(-123, s.nextLong(10));
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextLong(int)
- */
- public void test_hasNextLongI_cache() throws IOException {
- //regression for HARMONY-2063
- s = new Scanner("123 456");
- assertTrue(s.hasNextLong(16));
- assertEquals(291, s.nextLong());
- assertEquals(456, s.nextLong());
-
- s = new Scanner("123 456");
- assertTrue(s.hasNextLong(16));
- assertTrue(s.hasNextLong(8));
- assertEquals(83, s.nextLong());
- assertEquals(456, s.nextLong());
-
- s = new Scanner("-123 -456 -789");
- assertTrue(s.hasNextLong(8));
- assertEquals(-123, s.nextInt());
- assertEquals(-456, s.nextLong());
- assertTrue(s.hasNextShort(16));
- assertEquals(-789, s.nextLong());
-
- s = new Scanner("123 456");
- assertTrue(s.hasNextLong());
- s.close();
- try {
- s.nextLong();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextLong()
- */
- public void test_hasNextLong() throws IOException {
- s = new Scanner("123 456");
- assertTrue(s.hasNextLong());
- assertEquals(123, s.nextLong());
- assertTrue(s.hasNextLong());
- assertEquals(456, s.nextLong());
- assertFalse(s.hasNextLong());
- try {
- s.nextLong();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- // If the radix is different from 10
- s = new Scanner("123 456");
- s.useRadix(5);
- assertTrue(s.hasNextLong());
- assertEquals(38, s.nextLong());
- assertFalse(s.hasNextLong());
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // If the number is out of range
- s = new Scanner("123456789123456789123456789123456789");
- assertFalse(s.hasNextLong());
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextLong());
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.ENGLISH);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextLong());
- assertEquals(23456, s.nextLong());
- assertTrue(s.hasNextLong());
- assertEquals(23456, s.nextLong());
-
- /*
- * ''' is used in many locales as group separator.
- */
- s = new Scanner("23'456 23'456");
- s.useLocale(Locale.GERMANY);
- assertFalse(s.hasNextLong());
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(new Locale("it", "CH"));
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextLong());
- assertEquals(23456, s.nextLong());
- assertTrue(s.hasNextLong());
- assertEquals(23456, s.nextLong());
-
- /*
- * The input string has Arabic-Indic digits.
- */
- s = new Scanner("1\u06602 1\u06662");
- assertEquals(102, s.nextLong());
- s.useRadix(5);
- assertFalse(s.hasNextLong());
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useRadix(10);
- assertTrue(s.hasNextLong());
- assertEquals(162, s.nextLong());
-
- /*
- * '.' is used in many locales as group separator. The input string
- * has Arabic-Indic digits .
- */
- s = new Scanner("23.45\u0666 23.456");
- s.useLocale(Locale.CHINESE);
- assertFalse(s.hasNextLong());
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
- s.useLocale(Locale.GERMANY);
- // If exception is thrown out, input will not be advanced.
- assertTrue(s.hasNextLong());
- assertEquals(23456, s.nextLong());
- assertTrue(s.hasNextLong());
- assertEquals(23456, s.nextLong());
-
- // The input string starts with zero
- s = new Scanner("03,456");
- s.useLocale(Locale.ENGLISH);
- assertFalse(s.hasNextLong());
- try {
- s.nextLong();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- s = new Scanner("03456");
- assertTrue(s.hasNextLong());
- assertEquals(3456, s.nextLong());
-
- s = new Scanner("\u06603,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextLong());
- assertEquals(3456, s.nextLong());
-
- s = new Scanner("E34");
- s.useRadix(16);
- assertTrue(s.hasNextLong());
- assertEquals(3636, s.nextLong());
-
- /*
- * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
- * respectively, but they are not differentiated.
- */
- s = new Scanner("12300");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextLong());
- assertEquals(12300, s.nextLong());
-
- s = new Scanner("123\u0966\u0966");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextLong());
- assertEquals(12300, s.nextLong());
-
- s = new Scanner("123\u0e50\u0e50");
- s.useLocale(Locale.CHINESE);
- assertTrue(s.hasNextLong());
- assertEquals(12300, s.nextLong());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("ar", "AE"));
- assertTrue(s.hasNextLong());
- assertEquals(-123, s.nextLong());
-
- s = new Scanner("-123");
- s.useLocale(new Locale("mk", "MK"));
- assertTrue(s.hasNextLong());
- assertEquals(-123, s.nextLong());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextDouble()
- */
- public void test_hasNextDouble() throws IOException {
- s = new Scanner("123 45\u0666. 123.4 .123 ");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextDouble());
- assertEquals(123.0, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(456.0, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(123.4, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(0.123, s.nextDouble());
- assertFalse(s.hasNextDouble());
- try {
- s.nextDouble();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextDouble());
- assertEquals(123.4, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(-456.7, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(123456.789, s.nextDouble());
- assertFalse(s.hasNextDouble());
- try {
- s.nextDouble();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // Scientific notation
- s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextDouble());
- assertEquals(1.234E12, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(-4.567E14, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(1.23456789E-5, s.nextDouble());
-
- s = new Scanner("NaN Infinity -Infinity");
- assertTrue(s.hasNextDouble());
- assertEquals(Double.NaN, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(Double.POSITIVE_INFINITY, s.nextDouble());
- assertTrue(s.hasNextDouble());
- assertEquals(Double.NEGATIVE_INFINITY, s.nextDouble());
-
- String str=String.valueOf(Double.MAX_VALUE*2);
- s=new Scanner(str);
- assertTrue(s.hasNextDouble());
- assertEquals(Double.POSITIVE_INFINITY,s.nextDouble());
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextDouble());
- assertEquals(23456.0, s.nextDouble());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextDouble());
- assertEquals(23.456, s.nextDouble());
-
- s = new Scanner("23.456 23.456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextDouble());
- assertEquals(23.456, s.nextDouble());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextDouble());
- assertEquals(23456.0, s.nextDouble());
-
- s = new Scanner("23,456.7 23.456,7");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextDouble());
- assertEquals(23456.7, s.nextDouble());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextDouble());
- assertEquals(23456.7, s.nextDouble());
-
- s = new Scanner("-123.4");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextDouble());
- assertEquals(-123.4, s.nextDouble());
-
- s = new Scanner("+123.4 -456.7");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextDouble());
- s.close();
- try{
- s.nextDouble();
- fail();
- }catch(IllegalStateException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#hasNextBigDecimal()
- */
- public void test_hasNextBigDecimal() throws IOException {
- s = new Scanner("123 45\u0666. 123.4 .123 ");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("123"), s.nextBigDecimal());
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("456"), s.nextBigDecimal());
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("123.4"), s.nextBigDecimal());
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("0.123"), s.nextBigDecimal());
- assertFalse(s.hasNextBigDecimal());
- try {
- s.nextBigDecimal();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("123.4"), s.nextBigDecimal());
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("-456.7"), s.nextBigDecimal());
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("123456.789"), s.nextBigDecimal());
- assertFalse(s.hasNextBigDecimal());
- try {
- s.nextBigDecimal();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // Scientific notation
- s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("1.234E12"), s.nextBigDecimal());
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("-4.567E14"), s.nextBigDecimal());
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("1.23456789E-5"), s.nextBigDecimal());
-
- s = new Scanner("NaN");
- assertFalse(s.hasNextBigDecimal());
- try {
- s.nextBigDecimal();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("23456"), s.nextBigDecimal());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("23.456"), s.nextBigDecimal());
-
- s = new Scanner("23.456 23.456");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("23.456"), s.nextBigDecimal());
- s.useLocale(Locale.GERMANY);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("23456"), s.nextBigDecimal());
-
- s = new Scanner("23,456.7");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("23456.7"), s.nextBigDecimal());
-
- s = new Scanner("-123.4");
- s.useLocale(Locale.ENGLISH);
- assertTrue(s.hasNextBigDecimal());
- assertEquals(new BigDecimal("-123.4"), s.nextBigDecimal());
- }
-
- private static class MockStringReader extends StringReader {
-
- public MockStringReader(String param) {
- super(param);
- }
-
- public int read(CharBuffer target) throws IOException {
- target.append('t');
- target.append('e');
- target.append('s');
- target.append('t');
- throw new IOException();
- }
-
- }
-
- private static class MockStringReader2Read extends StringReader {
- int timesRead = 0;
-
- public MockStringReader2Read(String param) {
- super(param);
- }
-
- public int read(CharBuffer target) throws IOException {
- if (timesRead == 0) {
- target.append('1');
- target.append('2');
- target.append('3');
- timesRead++;
- return 3;
- } else if (timesRead == 1) {
- target.append('t');
- timesRead++;
- return 1;
- } else {
- throw new IOException();
- }
- }
-
- }
-
- // https://code.google.com/p/android/issues/detail?id=40555
- public void test_40555() throws Exception {
- MockStringReader2Read reader = new MockStringReader2Read("MockStringReader");
- s = new Scanner(reader);
- // We should get a match straight away.
- String result = s.findWithinHorizon("1", 0);
- assertEquals("1", result);
- // The stream should not be consumed as there's already a match after the first read.
- assertEquals(1, reader.timesRead);
- }
-
- /**
- * @tests java.util.Scanner#findWithinHorizon(Pattern, int)
- */
- public void test_findWithinHorizon_LPatternI() {
-
- // This method searches through the input up to the specified search
- // horizon(exclusive).
- s = new Scanner("123test");
- String result = s.findWithinHorizon(Pattern.compile("\\p{Lower}"), 5);
- assertEquals("t", result);
- MatchResult mresult = s.match();
- assertEquals(3, mresult.start());
- assertEquals(4, mresult.end());
-
- s = new Scanner("12345test1234test next");
- /*
- * If the pattern is found the scanner advances past the input that
- * matched and returns the string that matched the pattern.
- */
- result = s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), 2);
- assertEquals("12", result);
- mresult = s.match();
- assertEquals(0, mresult.start());
- assertEquals(2, mresult.end());
- // Position is now pointing at the bar. "12|345test1234test next"
-
- result = s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), 6);
- assertEquals("345", result);
-
- mresult = s.match();
- assertEquals(2, mresult.start());
- assertEquals(5, mresult.end());
- // Position is now pointing at the bar. "12345|test1234test next"
-
- // If no such pattern is detected then the null is returned and the
- // scanner's position remains unchanged.
- result = s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), 3);
- assertNull(result);
-
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
- assertEquals("345", mresult.group());
- assertEquals(2, mresult.start());
- assertEquals(5, mresult.end());
- // Position is now still pointing at the bar. "12345|test1234test next"
-
- // If horizon is 0, then the horizon is ignored and this method
- // continues to search through the input looking for the specified
- // pattern without bound.
- result = s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), 0);
- mresult = s.match();
- assertEquals(9, mresult.start());
- assertEquals(13, mresult.end());
- // Position is now pointing at the bar. "12345test1234|test next"
-
- assertEquals("test", s.next());
- mresult = s.match();
- assertEquals(13, mresult.start());
- assertEquals(17, mresult.end());
-
- assertEquals("next", s.next());
- mresult = s.match();
- assertEquals(18, mresult.start());
- assertEquals(22, mresult.end());
-
- try {
- s.findWithinHorizon((Pattern) null, -1);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- s.close();
- try {
- s.findWithinHorizon((Pattern) null, -1);
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("test");
- result = s.findWithinHorizon(Pattern.compile("\\w+"), 10);
- assertEquals("test", result);
-
- s = new Scanner("aa\n\rb");
- result = s.findWithinHorizon(Pattern.compile("a"), 5);
- assertEquals("a", result);
- mresult = s.match();
- assertEquals(0, mresult.start());
- assertEquals(1, mresult.end());
-
- result = s.findWithinHorizon(Pattern.compile("^(a)$", Pattern.MULTILINE), 5);
- assertNull(result);
-
- try {
- mresult = s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("");
- result = s.findWithinHorizon(Pattern.compile("^"), 0);
- assertEquals("", result);
- MatchResult matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(0, matchResult.end());
-
- result = s.findWithinHorizon(Pattern.compile("$"), 0);
- assertEquals("", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(0, matchResult.end());
-
- s = new Scanner("1 fish 2 fish red fish blue fish");
- result = s.findWithinHorizon(Pattern
- .compile("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)"), 10);
- assertNull(result);
-
- try {
- mresult = s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
- assertEquals(0, mresult.groupCount());
-
- result = s.findWithinHorizon(Pattern
- .compile("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)"), 100);
- assertEquals("1 fish 2 fish red fish blue", result);
- mresult = s.match();
- assertEquals(4, mresult.groupCount());
- assertEquals("1", mresult.group(1));
- assertEquals("2", mresult.group(2));
- assertEquals("red", mresult.group(3));
- assertEquals("blue", mresult.group(4));
-
- s = new Scanner("test");
- s.close();
- try {
- s.findWithinHorizon(Pattern.compile("test"), 1);
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("word1 WorD2 ");
- s.close();
- try {
- s.findWithinHorizon(Pattern.compile("\\d+"), 10);
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("word1 WorD2 wOrd3 ");
- Pattern pattern = Pattern.compile("\\d+");
- assertEquals("1", s.findWithinHorizon(pattern, 10));
- assertEquals("WorD2", s.next());
- assertEquals("3", s.findWithinHorizon(pattern, 15));
-
- // Regression test
- s = new Scanner(new MockStringReader("MockStringReader"));
- pattern = Pattern.compile("test");
- result = s.findWithinHorizon(pattern, 10);
- assertEquals("test", result);
-
- // Test the situation when input length is longer than buffer size.
- StringBuilder stringBuilder = new StringBuilder();
- for (int i = 0; i < 1026; i++) {
- stringBuilder.append('a');
- }
- s = new Scanner(stringBuilder.toString());
- pattern = Pattern.compile("\\p{Lower}+");
- result = s.findWithinHorizon(pattern, 1026);
- assertEquals(stringBuilder.toString().length(), result.length());
- assertEquals(stringBuilder.toString(), result);
-
- // Test the situation when input length is longer than buffer size and
- // set horizon to buffer size.
- stringBuilder = new StringBuilder();
- for (int i = 0; i < 1026; i++) {
- stringBuilder.append('a');
- }
- s = new Scanner(stringBuilder.toString());
- pattern = Pattern.compile("\\p{Lower}+");
- result = s.findWithinHorizon(pattern, 1022);
- assertEquals(1022, result.length());
- assertEquals(stringBuilder.subSequence(0, 1022), result);
-
- // Test the situation, under which pattern is clipped by buffer.
- stringBuilder = new StringBuilder();
- for (int i = 0; i < 1022; i++) {
- stringBuilder.append(' ');
- }
- stringBuilder.append("bbc");
- assertEquals(1025, stringBuilder.length());
- s = new Scanner(stringBuilder.toString());
- pattern = Pattern.compile("bbc");
- result = s.findWithinHorizon(pattern, 1025);
- assertEquals(3, result.length());
- assertEquals(stringBuilder.subSequence(1022, 1025), result);
-
- stringBuilder = new StringBuilder();
- for (int i = 0; i < 1026; i++) {
- stringBuilder.append('a');
- }
- s = new Scanner(stringBuilder.toString());
- pattern = Pattern.compile("\\p{Lower}+");
- result = s.findWithinHorizon(pattern, 0);
- assertEquals(stringBuilder.toString(), result);
-
- stringBuilder = new StringBuilder();
- for (int i = 0; i < 10240; i++) {
- stringBuilder.append('-');
- }
- stringBuilder.replace(0, 2, "aa");
- s = new Scanner(stringBuilder.toString());
- result = s.findWithinHorizon(Pattern.compile("aa"), 0);
- assertEquals("aa", result);
-
- s = new Scanner("aaaa");
- result = s.findWithinHorizon(Pattern.compile("a*"), 0);
- assertEquals("aaaa", result);
- }
-
- /**
- * @tests java.util.Scanner#findInLine(Pattern)
- */
- public void test_findInLine_LPattern() {
-
- Scanner s = new Scanner("");
- try {
- s.findInLine((Pattern) null);
- fail();
- } catch (NullPointerException expected) {
- }
- String result = s.findInLine(Pattern.compile("^"));
- assertEquals("", result);
- MatchResult matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(0, matchResult.end());
-
- result = s.findInLine(Pattern.compile("$"));
- assertEquals("", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(0, matchResult.end());
-
- /*
- * When we use the operation of findInLine(Pattern), the match region
- * should not span the line separator.
- */
- s = new Scanner("aa\nb.b");
- result = s.findInLine(Pattern.compile("a\nb*"));
- assertNull(result);
-
- s = new Scanner("aa\nbb.b");
- result = s.findInLine(Pattern.compile("\\."));
- assertNull(result);
-
- s = new Scanner("abcd1234test\n");
- result = s.findInLine(Pattern.compile("\\p{Lower}+"));
- assertEquals("abcd", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(4, matchResult.end());
-
- result = s.findInLine(Pattern.compile("\\p{Digit}{5}"));
- assertNull(result);
- try {
- matchResult = s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
- assertEquals(0, matchResult.start());
- assertEquals(4, matchResult.end());
-
- result = s.findInLine(Pattern.compile("\\p{Lower}+"));
- assertEquals("test", result);
- matchResult = s.match();
- assertEquals(8, matchResult.start());
- assertEquals(12, matchResult.end());
-
- char[] chars = new char[2048];
- Arrays.fill(chars, 'a');
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append(chars);
- stringBuilder.append("1234");
- s = new Scanner(stringBuilder.toString());
- result = s.findInLine(Pattern.compile("\\p{Digit}+"));
- assertEquals("1234", result);
- matchResult = s.match();
- assertEquals(2048, matchResult.start());
- assertEquals(2052, matchResult.end());
-
- s = new Scanner("test");
- s.close();
- try {
- s.findInLine((Pattern) null);
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("test1234\n1234 test");
- result = s.findInLine(Pattern.compile("test"));
- assertEquals("test", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(4, matchResult.end());
-
- int number = s.nextInt();
- assertEquals(1234, number);
- matchResult = s.match();
- assertEquals(4, matchResult.start());
- assertEquals(8, matchResult.end());
-
- result = s.next();
- assertEquals("1234", result);
- matchResult = s.match();
- assertEquals(9, matchResult.start());
- assertEquals(13, matchResult.end());
-
- result = s.findInLine(Pattern.compile("test"));
- assertEquals("test", result);
- matchResult = s.match();
- assertEquals(14, matchResult.start());
- assertEquals(18, matchResult.end());
-
- s = new Scanner("test\u0085\ntest");
- result = s.findInLine("est");
- assertEquals("est", result);
- result = s.findInLine("est");
- assertEquals("est", result);
-
- s = new Scanner("test\ntest");
- result = s.findInLine("est");
- assertEquals("est", result);
- result = s.findInLine("est");
- assertEquals("est", result);
-
- s = new Scanner("test\n123\ntest");
- result = s.findInLine("est");
- assertEquals("est", result);
- result = s.findInLine("est");
- // RI fails. It is a RI's bug.
- assertNull(result);
-
- s = new Scanner( " *\n");
- result = s.findInLine(Pattern.compile( "^\\s*(?:\\*(?=[^/]))"));
- assertEquals(" *", result);
- }
-
- public void test_findInLine_LString_NPEs() {
- s = new Scanner("test");
- try {
- s.findInLine((String) null);
- fail();
- } catch (NullPointerException expected) {
- }
- s.close();
- try {
- s.findInLine((String) null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- s.findInLine("test");
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- public void test_findInLine_LString() {
- Scanner s = new Scanner("");
- String result = s.findInLine("^");
- assertEquals("", result);
- MatchResult matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(0, matchResult.end());
-
- result = s.findInLine("$");
- assertEquals("", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(0, matchResult.end());
-
- // When we use the operation of findInLine(Pattern), the match region
- // should not span the line separator.
- s = new Scanner("aa\nb.b");
- result = s.findInLine("a\nb*");
- assertNull(result);
-
- s = new Scanner("aa\nbb.b");
- result = s.findInLine("\\.");
- assertNull(result);
-
- s = new Scanner("abcd1234test\n");
- result = s.findInLine("\\p{Lower}+");
- assertEquals("abcd", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(4, matchResult.end());
-
- result = s.findInLine("\\p{Digit}{5}");
- assertNull(result);
- try {
- matchResult = s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
- assertEquals(0, matchResult.start());
- assertEquals(4, matchResult.end());
-
- result = s.findInLine("\\p{Lower}+");
- assertEquals("test", result);
- matchResult = s.match();
- assertEquals(8, matchResult.start());
- assertEquals(12, matchResult.end());
-
- char[] chars = new char[2048];
- Arrays.fill(chars, 'a');
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append(chars);
- stringBuilder.append("1234");
- s = new Scanner(stringBuilder.toString());
- result = s.findInLine("\\p{Digit}+");
- assertEquals("1234", result);
- matchResult = s.match();
- assertEquals(2048, matchResult.start());
- assertEquals(2052, matchResult.end());
-
- s = new Scanner("test1234\n1234 test");
- result = s.findInLine("test");
- assertEquals("test", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(4, matchResult.end());
-
- int number = s.nextInt();
- assertEquals(1234, number);
- matchResult = s.match();
- assertEquals(4, matchResult.start());
- assertEquals(8, matchResult.end());
-
- result = s.next();
- assertEquals("1234", result);
- matchResult = s.match();
- assertEquals(9, matchResult.start());
- assertEquals(13, matchResult.end());
-
- result = s.findInLine("test");
- assertEquals("test", result);
- matchResult = s.match();
- assertEquals(14, matchResult.start());
- assertEquals(18, matchResult.end());
-
- s = new Scanner("test\u0085\ntest");
- result = s.findInLine("est");
- assertEquals("est", result);
- result = s.findInLine("est");
- assertEquals("est", result);
-
- s = new Scanner("test\ntest");
- result = s.findInLine("est");
- assertEquals("est", result);
- result = s.findInLine("est");
- assertEquals("est", result);
-
- s = new Scanner("test\n123\ntest");
- result = s.findInLine("est");
- assertEquals("est", result);
- result = s.findInLine("est");
- }
-
- /**
- * @tests java.util.Scanner#skip(Pattern)
- */
- public void test_skip_LPattern() {
- s = new Scanner("test");
- try {
- s.skip((String) null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // If pattern does not match, NoSuchElementException will be thrown out.
- s = new Scanner("1234");
- try {
- s.skip(Pattern.compile("\\p{Lower}"));
- fail();
- } catch (NoSuchElementException expected) {
- }
- // Then, no matchResult will be thrown out.
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s.skip(Pattern.compile("\\p{Digit}"));
- MatchResult matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
-
- s.skip(Pattern.compile("\\p{Digit}+"));
- matchResult = s.match();
- assertEquals(1, matchResult.start());
- assertEquals(4, matchResult.end());
-
- s.close();
- try {
- s.skip(Pattern.compile("test"));
- fail();
- } catch (IllegalStateException expected) {
- }
-
- MockStringReader2Read reader = new MockStringReader2Read("test");
- s = new Scanner(reader);
- try {
- s.skip(Pattern.compile("\\p{Digit}{4}"));
- fail();
- } catch (NoSuchElementException expected) {
- }
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
- s.skip(Pattern.compile("\\p{Digit}{3}\\p{Lower}"));
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(4, matchResult.end());
-
- s.close();
- try {
- s.skip((Pattern) null);
- fail();
- } catch (IllegalStateException expected) {
- }
-
- StringBuilder stringBuilder = new StringBuilder();
- char [] chars = new char[1024];
- Arrays.fill(chars, 'a');
- stringBuilder.append(chars);
- stringBuilder.append('3');
- s = new Scanner(stringBuilder.toString());
- s.skip(Pattern.compile("\\p{Lower}+\\p{Digit}"));
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1025, matchResult.end());
-
- // Large amount of input may be cached
- chars = new char[102400];
- Arrays.fill(chars, 'a');
- stringBuilder = new StringBuilder();
- stringBuilder.append(chars);
- s = new Scanner(stringBuilder.toString());
- s.skip(Pattern.compile(".*"));
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(102400, matchResult.end());
-
- // skip something without risking a NoSuchElementException
- s.skip(Pattern.compile("[ \t]*"));
- matchResult = s.match();
- assertEquals(102400, matchResult.start());
- assertEquals(102400, matchResult.end());
- }
-
- /**
- * @tests java.util.Scanner#skip(String)
- */
- public void test_skip_LString() {
- s = new Scanner("test");
- try {
- s.skip((String) null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextDouble()
- */
- public void test_nextDouble() throws IOException {
- s = new Scanner("123 45\u0666. 123.4 .123 ");
- s.useLocale(Locale.ENGLISH);
- assertEquals(123.0, s.nextDouble());
- assertEquals(456.0, s.nextDouble());
- assertEquals(123.4, s.nextDouble());
- assertEquals(0.123, s.nextDouble());
- try {
- s.nextDouble();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
- s.useLocale(Locale.ENGLISH);
- assertEquals(123.4, s.nextDouble());
- assertEquals(-456.7, s.nextDouble());
- assertEquals(123456.789, s.nextDouble());
- try {
- s.nextDouble();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // Scientific notation
- s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
- s.useLocale(Locale.ENGLISH);
- assertEquals(1.234E12, s.nextDouble());
- assertEquals(-4.567E14, s.nextDouble());
- assertEquals(1.23456789E-5, s.nextDouble());
-
- s = new Scanner("NaN Infinity -Infinity");
- assertEquals(Double.NaN, s.nextDouble());
- assertEquals(Double.POSITIVE_INFINITY, s.nextDouble());
- assertEquals(Double.NEGATIVE_INFINITY, s.nextDouble());
-
- //The following test case fails on RI
- s=new Scanner("\u221e");
- s.useLocale(Locale.ENGLISH);
- assertEquals(Double.POSITIVE_INFINITY, s.nextDouble());
-
- String str=String.valueOf(Double.MAX_VALUE*2);
- s=new Scanner(str);
- assertEquals(Double.POSITIVE_INFINITY,s.nextDouble());
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(23456.0, s.nextDouble());
- s.useLocale(Locale.GERMANY);
- assertEquals(23.456, s.nextDouble());
-
- s = new Scanner("23.456 23.456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(23.456, s.nextDouble());
- s.useLocale(Locale.GERMANY);
- assertEquals(23456.0, s.nextDouble());
-
- s = new Scanner("23,456.7 23.456,7");
- s.useLocale(Locale.ENGLISH);
- assertEquals(23456.7, s.nextDouble());
- s.useLocale(Locale.GERMANY);
- assertEquals(23456.7, s.nextDouble());
-
- s = new Scanner("-123.4");
- s.useLocale(Locale.ENGLISH);
- assertEquals(-123.4, s.nextDouble());
- }
-
- /**
- * @throws IOException
- * @tests java.util.Scanner#nextBigDecimal()
- */
- public void test_nextBigDecimal() throws IOException {
- s = new Scanner("123 45\u0666. 123.4 .123 ");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigDecimal("123"), s.nextBigDecimal());
- assertEquals(new BigDecimal("456"), s.nextBigDecimal());
- assertEquals(new BigDecimal("123.4"), s.nextBigDecimal());
- assertEquals(new BigDecimal("0.123"), s.nextBigDecimal());
- try {
- s.nextBigDecimal();
- fail();
- } catch (NoSuchElementException expected) {
- }
-
- s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigDecimal("123.4"), s.nextBigDecimal());
- assertEquals(new BigDecimal("-456.7"), s.nextBigDecimal());
- assertEquals(new BigDecimal("123456.789"), s.nextBigDecimal());
- try {
- s.nextBigDecimal();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- // Scientific notation
- s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigDecimal("1.234E12"), s.nextBigDecimal());
- assertEquals(new BigDecimal("-4.567E14"), s.nextBigDecimal());
- assertEquals(new BigDecimal("1.23456789E-5"), s.nextBigDecimal());
-
- s = new Scanner("NaN");
- try {
- s.nextBigDecimal();
- fail();
- } catch (InputMismatchException expected) {
- }
-
- /*
- * Different locale can only recognize corresponding locale sensitive
- * string. ',' is used in many locales as group separator.
- */
- s = new Scanner("23,456 23,456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigDecimal("23456"), s.nextBigDecimal());
- s.useLocale(Locale.GERMANY);
- assertEquals(new BigDecimal("23.456"), s.nextBigDecimal());
-
- s = new Scanner("23.456 23.456");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigDecimal("23.456"), s.nextBigDecimal());
- s.useLocale(Locale.GERMANY);
- assertEquals(new BigDecimal("23456"), s.nextBigDecimal());
-
- s = new Scanner("23,456.7");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigDecimal("23456.7"), s.nextBigDecimal());
-
- s = new Scanner("-123.4");
- s.useLocale(Locale.ENGLISH);
- assertEquals(new BigDecimal("-123.4"), s.nextBigDecimal());
- }
-
- /**
- * @tests java.util.Scanner#toString()
- */
- public void test_toString() {
- s = new Scanner("test");
- assertNotNull(s.toString());
- }
-
- /**
- * @tests java.util.Scanner#nextLine()
- */
- public void test_nextLine() {
- s = new Scanner("");
- s.close();
- try {
- s.nextLine();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("test\r\ntest");
- String result = s.nextLine();
- assertEquals("test", result);
- MatchResult matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(6, matchResult.end());
-
- s = new Scanner("\u0085");
- result = s.nextLine();
- assertEquals("", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
-
- s = new Scanner("\u2028");
- result = s.nextLine();
- assertEquals("", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
-
- s = new Scanner("\u2029");
- result = s.nextLine();
- assertEquals("", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
-
- s = new Scanner("");
- try {
- result = s.nextLine();
- fail();
- } catch (NoSuchElementException expected) {
- }
- try {
- s.match();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("Ttest");
- result = s.nextLine();
- assertEquals("Ttest", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(5, matchResult.end());
-
- s = new Scanner("\r\n");
- result = s.nextLine();
- assertEquals("", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(2, matchResult.end());
-
- char[] chars = new char[1024];
- Arrays.fill(chars, 'a');
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append(chars);
- chars = new char[] { '+', '-' };
- stringBuilder.append(chars);
- stringBuilder.append("\u2028");
- s = new Scanner(stringBuilder.toString());
- result = s.nextLine();
-
- assertEquals(stringBuilder.toString().substring(0, 1026), result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1027, matchResult.end());
-
- chars = new char[1023];
- Arrays.fill(chars, 'a');
- stringBuilder = new StringBuilder();
- stringBuilder.append(chars);
- stringBuilder.append("\r\n");
- s = new Scanner(stringBuilder.toString());
- result = s.nextLine();
-
- assertEquals(stringBuilder.toString().substring(0, 1023), result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1025, matchResult.end());
-
- s = new Scanner(" ");
- result = s.nextLine();
- assertEquals(" ", result);
-
- s = new Scanner("test\n\n\n");
- result = s.nextLine();
- assertEquals("test", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(5, matchResult.end());
- result = s.nextLine();
- matchResult = s.match();
- assertEquals(5, matchResult.start());
- assertEquals(6, matchResult.end());
-
- s = new Scanner("\n\n\n");
- result = s.nextLine();
- assertEquals("", result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
- result = s.nextLine();
- matchResult = s.match();
- assertEquals(1, matchResult.start());
- assertEquals(2, matchResult.end());
-
- s = new Scanner("123 test\n ");
- int value = s.nextInt();
- assertEquals(123, value);
-
- result = s.nextLine();
- assertEquals(" test", result);
-
- s = new Scanner("test\n ");
- result = s.nextLine();
- assertEquals("test", result);
-
- // Regression test for Harmony-4774
- class CountReadable implements Readable {
- int counter = 0;
- public int read(CharBuffer charBuffer) throws IOException {
- counter++;
- charBuffer.append("hello\n");
- return 6;
- }
- }
- CountReadable cr = new CountReadable();
- s = new Scanner(cr);
- result = s.nextLine();
- // We expect read() to be called only once, otherwise we see the problem
- // when reading from System.in described in Harmony-4774
- assertEquals(1, cr.counter);
- assertEquals("hello", result);
- }
-
- /**
- * @tests java.util.Scanner#hasNextLine()
- */
- public void test_hasNextLine() {
- s = new Scanner("");
- s.close();
- try {
- s.hasNextLine();
- fail();
- } catch (IllegalStateException expected) {
- }
-
- s = new Scanner("test\r\ntest");
- boolean result = s.hasNextLine();
- assertTrue(result);
- MatchResult matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(6, matchResult.end());
-
- s = new Scanner("\u0085");
- result = s.hasNextLine();
- assertTrue(result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
-
- s = new Scanner("\u2028");
- result = s.hasNextLine();
- assertTrue(result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
-
- s = new Scanner("\u2029");
- result = s.hasNextLine();
- assertTrue(result);
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
-
- s = new Scanner("test\n");
- assertTrue(s.hasNextLine());
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(5, matchResult.end());
-
- char[] chars = new char[2048];
- Arrays.fill(chars, 'a');
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append(chars);
- s = new Scanner(stringBuilder.toString());
- result = s.hasNextLine();
- assertTrue(result);
-
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(2048, matchResult.end());
-
- s = new Scanner("\n\n\n");
- assertTrue(s.hasNextLine());
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
-
- // The scanner will not advance any input.
- assertTrue(s.hasNextLine());
- matchResult = s.match();
- assertEquals(0, matchResult.start());
- assertEquals(1, matchResult.end());
- }
-
- public void test_hasNextLine_sequence() throws IOException {
- final PipedInputStream pis = new PipedInputStream();
- final PipedOutputStream pos = new PipedOutputStream();
- final Scanner scanner = new Scanner(pis);
- pis.connect(pos);
- final List<String> result = new ArrayList<String>();
- Thread thread = new Thread(new Runnable() {
- public void run() {
- while (scanner.hasNextLine()) {
- String line = scanner.nextLine();
- result.add(line);
- }
- }
- });
- thread.start();
- for (int index = 0; index < 5; index++) {
- String line = "line" + index + "\n";
- pos.write(line.getBytes());
- pos.flush();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ignored) {
- }
- assertEquals(index + 1, result.size());
- }
- pis.close();
- pos.close();
- try {
- thread.join(1000);
- } catch (InterruptedException ignored) {
- }
- assertFalse(scanner.hasNextLine());
- }
-
- protected void setUp() throws Exception {
- super.setUp();
-
- server = new ServerSocket(0);
- address = new InetSocketAddress("127.0.0.1", server.getLocalPort());
-
- client = SocketChannel.open();
- client.connect(address);
- serverSocket = server.accept();
-
- os = serverSocket.getOutputStream();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
-
- try {
- serverSocket.close();
- } catch (Exception ignored) {
- }
- try {
- client.close();
- } catch (Exception ignored) {
- }
- try {
- server.close();
- } catch (Exception ignored) {
- }
- }
-
- // http://code.google.com/p/android/issues/detail?id=57050
- public void testPerformance() throws Exception {
- int count = 100000;
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- BufferedWriter out = new BufferedWriter(new OutputStreamWriter(baos));
- for (int i = 0; i < count; ++i) {
- out.write(Integer.toString(123) + " ");
- }
- out.close();
-
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- bais.mark(-1);
-
- Scanner s = new Scanner(new BufferedReader(new InputStreamReader(bais)));
- for (int i = 0; i < count; ++i) {
- if (s.nextInt() != 123) {
- fail();
- }
- }
-
- bais.reset();
- s = new Scanner(new BufferedReader(new InputStreamReader(bais)));
- for (int i = 0; i < count; ++i) {
- if (s.nextFloat() != 123.0) {
- fail();
- }
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/UUIDTest.java b/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/UUIDTest.java
deleted file mode 100644
index d8f4cc4..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/luni/tests/java/util/UUIDTest.java
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package org.apache.harmony.luni.tests.java.util;
-
-import java.util.UUID;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-import junit.framework.TestCase;
-
-public class UUIDTest extends TestCase {
-
- /**
- * @see UUID#UUID(long, long)
- */
- public void test_ConstructorJJ() {
- UUID uuid = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
- assertEquals(2, uuid.variant());
- assertEquals(1, uuid.version());
- assertEquals(0x1d07decf81d4faeL, uuid.timestamp());
- assertEquals(130742845922168750L, uuid.timestamp());
- assertEquals(0x2765, uuid.clockSequence());
- assertEquals(0xA0C91E6BF6L, uuid.node());
- }
-
- /**
- * @see UUID#getLeastSignificantBits()
- */
- public void test_getLeastSignificantBits() {
- UUID uuid = new UUID(0, 0);
- assertEquals(0, uuid.getLeastSignificantBits());
- uuid = new UUID(0, Long.MIN_VALUE);
- assertEquals(Long.MIN_VALUE, uuid.getLeastSignificantBits());
- uuid = new UUID(0, Long.MAX_VALUE);
- assertEquals(Long.MAX_VALUE, uuid.getLeastSignificantBits());
- }
-
- /**
- * @see UUID#getMostSignificantBits()
- */
- public void test_getMostSignificantBits() {
- UUID uuid = new UUID(0, 0);
- assertEquals(0, uuid.getMostSignificantBits());
- uuid = new UUID(Long.MIN_VALUE, 0);
- assertEquals(Long.MIN_VALUE, uuid.getMostSignificantBits());
- uuid = new UUID(Long.MAX_VALUE, 0);
- assertEquals(Long.MAX_VALUE, uuid.getMostSignificantBits());
- }
-
- /**
- * @see UUID#version()
- */
- public void test_version() {
- UUID uuid = new UUID(0, 0);
- assertEquals(0, uuid.version());
- uuid = new UUID(0x0000000000001000L, 0);
- assertEquals(1, uuid.version());
- uuid = new UUID(0x0000000000002000L, 0);
- assertEquals(2, uuid.version());
- uuid = new UUID(0x0000000000003000L, 0);
- assertEquals(3, uuid.version());
- uuid = new UUID(0x0000000000004000L, 0);
- assertEquals(4, uuid.version());
- uuid = new UUID(0x0000000000005000L, 0);
- assertEquals(5, uuid.version());
- }
-
- /**
- * @see UUID#variant()
- */
- public void test_variant() {
- UUID uuid = new UUID(0, 0x0000000000000000L);
- assertEquals(0, uuid.variant());
- uuid = new UUID(0, 0x7000000000000000L);
- assertEquals(0, uuid.variant());
- uuid = new UUID(0, 0x3000000000000000L);
- assertEquals(0, uuid.variant());
- uuid = new UUID(0, 0x1000000000000000L);
- assertEquals(0, uuid.variant());
-
- uuid = new UUID(0, 0x8000000000000000L);
- assertEquals(2, uuid.variant());
- uuid = new UUID(0, 0xB000000000000000L);
- assertEquals(2, uuid.variant());
- uuid = new UUID(0, 0xA000000000000000L);
- assertEquals(2, uuid.variant());
- uuid = new UUID(0, 0x9000000000000000L);
- assertEquals(2, uuid.variant());
-
- uuid = new UUID(0, 0xC000000000000000L);
- assertEquals(6, uuid.variant());
- uuid = new UUID(0, 0xD000000000000000L);
- assertEquals(6, uuid.variant());
-
- uuid = new UUID(0, 0xE000000000000000L);
- assertEquals(7, uuid.variant());
- uuid = new UUID(0, 0xF000000000000000L);
- assertEquals(7, uuid.variant());
- }
-
- /**
- * @see UUID#timestamp()
- */
- public void test_timestamp() {
- UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
- assertEquals(0x0, uuid.timestamp());
-
- uuid = new UUID(0x7777777755551333L, 0x8000000000000000L);
- assertEquals(0x333555577777777L, uuid.timestamp());
-
- uuid = new UUID(0x0000000000000000L, 0x8000000000000000L);
- try {
- uuid.timestamp();
- fail("No UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {}
-
- uuid = new UUID(0x0000000000002000L, 0x8000000000000000L);
- try {
- uuid.timestamp();
- fail("No UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {}
- }
-
- /**
- * @see UUID#clockSequence()
- */
- public void test_clockSequence() {
- UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
- assertEquals(0x0, uuid.clockSequence());
-
- uuid = new UUID(0x0000000000001000L, 0x8FFF000000000000L);
- assertEquals(0x0FFF, uuid.clockSequence());
-
- uuid = new UUID(0x0000000000001000L, 0xBFFF000000000000L);
- assertEquals(0x3FFF, uuid.clockSequence());
-
- uuid = new UUID(0x0000000000000000L, 0x8000000000000000L);
- try {
- uuid.clockSequence();
- fail("No UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {}
-
- uuid = new UUID(0x0000000000002000L, 0x8000000000000000L);
- try {
- uuid.clockSequence();
- fail("No UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {}
- }
-
- /**
- * @see UUID#node()
- */
- public void test_node() {
- UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
- assertEquals(0x0, uuid.node());
-
- uuid = new UUID(0x0000000000001000L, 0x8000FFFFFFFFFFFFL);
- assertEquals(0xFFFFFFFFFFFFL, uuid.node());
-
- uuid = new UUID(0x0000000000000000L, 0x8000000000000000L);
- try {
- uuid.node();
- fail("No UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {}
-
- uuid = new UUID(0x0000000000002000L, 0x8000000000000000L);
- try {
- uuid.node();
- fail("No UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {}
- }
-
- /**
- * @see UUID#compareTo(UUID)
- */
- public void test_compareTo() {
- UUID uuid1 = new UUID(0, 0);
- assertEquals(0, uuid1.compareTo(uuid1));
- UUID uuid2 = new UUID(1, 0);
- assertEquals(-1, uuid1.compareTo(uuid2));
- assertEquals(1, uuid2.compareTo(uuid1));
-
- uuid2 = new UUID(0, 1);
- assertEquals(-1, uuid1.compareTo(uuid2));
- assertEquals(1, uuid2.compareTo(uuid1));
- }
-
- /**
- * @see UUID#hashCode()
- */
- public void test_hashCode() {
- UUID uuid = new UUID(0, 0);
- assertEquals(0, uuid.hashCode());
- uuid = new UUID(123, 123);
- UUID uuidClone = new UUID(123, 123);
- assertEquals(uuid.hashCode(), uuidClone.hashCode());
- }
-
- /**
- * @see UUID#equals(Object)
- */
- public void test_equalsObject() {
- UUID uuid1 = new UUID(0, 0);
- assertEquals(uuid1, uuid1);
- assertFalse(uuid1.equals(null));
- assertFalse(uuid1.equals("NOT A UUID"));
- UUID uuid2 = new UUID(0, 0);
- assertEquals(uuid1, uuid2);
- assertEquals(uuid2, uuid1);
-
- uuid1 = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
- uuid2 = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
- assertEquals(uuid1, uuid2);
- assertEquals(uuid2, uuid1);
-
- uuid2 = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf7L);
- assertFalse(uuid1.equals(uuid2));
- assertFalse(uuid2.equals(uuid1));
- }
-
- /**
- * @see UUID#toString()
- */
- public void test_toString() {
- UUID uuid = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
- String actual = uuid.toString();
- assertEquals("f81d4fae-7dec-11d0-a765-00a0c91e6bf6", actual);
-
- uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
- actual = uuid.toString();
- assertEquals("00000000-0000-1000-8000-000000000000", actual);
- }
-
- /**
- * @tests serialization/deserialization.
- */
- public void testSerializationSelf() throws Exception {
- SerializationTest.verifySelf(new UUID(0xf81d4fae7dec11d0L,
- 0xa76500a0c91e6bf6L));
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
- SerializationTest.verifyGolden(this, new UUID(0xf81d4fae7dec11d0L,
- 0xa76500a0c91e6bf6L));
- }
-
- /**
- * @see UUID#randomUUID()
- */
- public void test_randomUUID() {
- UUID uuid = UUID.randomUUID();
- assertEquals(2, uuid.variant());
- assertEquals(4, uuid.version());
- }
-
- /**
- * @see UUID#nameUUIDFromBytes(byte[])
- */
- public void test_nameUUIDFromBytes() throws Exception {
- byte[] name = { (byte) 0x6b, (byte) 0xa7, (byte) 0xb8, (byte) 0x11,
- (byte) 0x9d, (byte) 0xad, (byte) 0x11, (byte) 0xd1,
- (byte) 0x80, (byte) 0xb4, (byte) 0x00, (byte) 0xc0,
- (byte) 0x4f, (byte) 0xd4, (byte) 0x30, (byte) 0xc8 };
-
- UUID uuid = UUID.nameUUIDFromBytes(name);
-
- assertEquals(2, uuid.variant());
- assertEquals(3, uuid.version());
-
- assertEquals(0xaff565bc2f771745L, uuid.getLeastSignificantBits());
- assertEquals(0x14cdb9b4de013faaL, uuid.getMostSignificantBits());
-
- uuid = UUID.nameUUIDFromBytes(new byte[0]);
- assertEquals(2, uuid.variant());
- assertEquals(3, uuid.version());
-
- assertEquals(0xa9800998ecf8427eL, uuid.getLeastSignificantBits());
- assertEquals(0xd41d8cd98f003204L, uuid.getMostSignificantBits());
-
- try {
- UUID.nameUUIDFromBytes(null);
- fail("No NPE");
- } catch (NullPointerException e) {}
- }
-
- /**
- * @see UUID#fromString(String)
- */
- public void test_fromString() {
- UUID actual = UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
- UUID expected = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
- assertEquals(expected, actual);
-
- assertEquals(2, actual.variant());
- assertEquals(1, actual.version());
- assertEquals(130742845922168750L, actual.timestamp());
- assertEquals(10085, actual.clockSequence());
- assertEquals(690568981494L, actual.node());
-
- actual = UUID.fromString("00000000-0000-1000-8000-000000000000");
- expected = new UUID(0x0000000000001000L, 0x8000000000000000L);
- assertEquals(expected, actual);
-
- assertEquals(2, actual.variant());
- assertEquals(1, actual.version());
- assertEquals(0L, actual.timestamp());
- assertEquals(0, actual.clockSequence());
- assertEquals(0L, actual.node());
-
- try {
- UUID.fromString(null);
- fail("No NPE");
- } catch (NullPointerException e) {}
-
- try {
- UUID.fromString("");
- fail("No IAE");
- } catch (IllegalArgumentException e) {}
-
- try {
- UUID.fromString("f81d4fae_7dec-11d0-a765-00a0c91e6bf6");
- fail("No IAE");
- } catch (IllegalArgumentException e) {}
-
- try {
- UUID.fromString("f81d4fae-7dec_11d0-a765-00a0c91e6bf6");
- fail("No IAE");
- } catch (IllegalArgumentException e) {}
-
- try {
- UUID.fromString("f81d4fae-7dec-11d0_a765-00a0c91e6bf6");
- fail("No IAE");
- } catch (IllegalArgumentException e) {}
-
- try {
- UUID.fromString("f81d4fae-7dec-11d0-a765_00a0c91e6bf6");
- fail("No IAE");
- } catch (IllegalArgumentException e) {}
- }
-
- /**
- * @tests java.util.UUID#fromString(String)
- */
- public void test_fromString_LString_Exception() {
-
- UUID uuid = UUID.fromString("0-0-0-0-0");
-
- try {
- uuid = UUID.fromString("0-0-0-0-");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- uuid = UUID.fromString("-0-0-0-0-0");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- uuid = UUID.fromString("-0-0-0-0");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- uuid = UUID.fromString("-0-0-0-");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- uuid = UUID.fromString("0--0-0-0");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- uuid = UUID.fromString("0-0-0-0-");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- uuid = UUID.fromString("-1-0-0-0-0");
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- uuid = UUID.fromString("123456789-0-0-0-0");
- assertEquals(0x2345678900000000L, uuid.getMostSignificantBits());
- assertEquals(0x0L, uuid.getLeastSignificantBits());
-
- uuid = UUID.fromString("111123456789-0-0-0-0");
- assertEquals(0x2345678900000000L, uuid.getMostSignificantBits());
- assertEquals(0x0L, uuid.getLeastSignificantBits());
-
- uuid = UUID.fromString("7fffffffffffffff-0-0-0-0");
- assertEquals(0xffffffff00000000L, uuid.getMostSignificantBits());
- assertEquals(0x0L, uuid.getLeastSignificantBits());
-
- try {
- uuid = UUID.fromString("8000000000000000-0-0-0-0");
- fail("should throw NumberFormatException");
- } catch (NumberFormatException e) {
- // expected
- }
-
- uuid = UUID
- .fromString("7fffffffffffffff-7fffffffffffffff-7fffffffffffffff-0-0");
- assertEquals(0xffffffffffffffffL, uuid.getMostSignificantBits());
- assertEquals(0x0L, uuid.getLeastSignificantBits());
-
- uuid = UUID.fromString("0-0-0-7fffffffffffffff-7fffffffffffffff");
- assertEquals(0x0L, uuid.getMostSignificantBits());
- assertEquals(0xffffffffffffffffL, uuid.getLeastSignificantBits());
-
- try {
- uuid = UUID.fromString("0-0-0-8000000000000000-0");
- fail("should throw NumberFormatException");
- } catch (NumberFormatException e) {
- // expected
- }
-
- try {
- uuid = UUID.fromString("0-0-0-0-8000000000000000");
- fail("should throw NumberFormatException");
- } catch (NumberFormatException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/AbstractBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/AbstractBufferTest.java
deleted file mode 100644
index eb48992..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/AbstractBufferTest.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.InvalidMarkException;
-
-import junit.framework.TestCase;
-
-/**
- * Tests a java.nio.Buffer instance.
- */
-public class AbstractBufferTest extends TestCase {
-
- protected Buffer baseBuf;
-
- protected void setUp() throws Exception{
- super.setUp();
- baseBuf = ByteBuffer.allocate(10);
- }
-
- protected void tearDown() throws Exception{
- super.tearDown();
- }
-
- public void testCapacity() {
- assertTrue(0 <= baseBuf.position() && baseBuf.position() <= baseBuf.limit()
- && baseBuf.limit() <= baseBuf.capacity());
- }
-
- public void testClear() {
- // save state
- int oldPosition = baseBuf.position();
- int oldLimit = baseBuf.limit();
-
- Buffer ret = baseBuf.clear();
- assertSame(ret, baseBuf);
- assertEquals(baseBuf.position(), 0);
- assertEquals(baseBuf.limit(), baseBuf.capacity());
- try {
- baseBuf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$S
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // restore state
- baseBuf.limit(oldLimit);
- baseBuf.position(oldPosition);
- }
-
- public void testFlip() {
- // save state
- int oldPosition = baseBuf.position();
- int oldLimit = baseBuf.limit();
-
- Buffer ret = baseBuf.flip();
- assertSame(ret, baseBuf);
- assertEquals(baseBuf.position(), 0);
- assertEquals(baseBuf.limit(), oldPosition);
- try {
- baseBuf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // restore state
- baseBuf.limit(oldLimit);
- baseBuf.position(oldPosition);
- }
-
- public void testHasRemaining() {
- // save state
- int oldPosition = baseBuf.position();
- int oldLimit = baseBuf.limit();
-
- assertEquals(baseBuf.hasRemaining(), baseBuf.position() < baseBuf.limit());
- baseBuf.position(baseBuf.limit());
- assertFalse(baseBuf.hasRemaining());
-
- // restore state
- baseBuf.limit(oldLimit);
- baseBuf.position(oldPosition);
- }
-
- public void testIsReadOnly() {
- baseBuf.isReadOnly();
- }
-
- /*
- * Class under test for int limit()
- */
- public void testLimit() {
- assertTrue(0 <= baseBuf.position() && baseBuf.position() <= baseBuf.limit()
- && baseBuf.limit() <= baseBuf.capacity());
- }
-
- /*
- * Class under test for Buffer limit(int)
- */
- public void testLimitint() {
- // save state
- int oldPosition = baseBuf.position();
- int oldLimit = baseBuf.limit();
-
- Buffer ret = baseBuf.limit(baseBuf.limit());
- assertSame(ret, baseBuf);
-
- baseBuf.mark();
- baseBuf.limit(baseBuf.capacity());
- assertEquals(baseBuf.limit(), baseBuf.capacity());
- // position should not change
- assertEquals(baseBuf.position(), oldPosition);
- // mark should be valid
- baseBuf.reset();
-
- if (baseBuf.capacity() > 0) {
- baseBuf.limit(baseBuf.capacity());
- baseBuf.position(baseBuf.capacity());
- baseBuf.mark();
- baseBuf.limit(baseBuf.capacity() - 1);
- // position should be the new limit
- assertEquals(baseBuf.position(), baseBuf.limit());
- // mark should be invalid
- try {
- baseBuf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- try {
- baseBuf.limit(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- baseBuf.limit(baseBuf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- // restore state
- baseBuf.limit(oldLimit);
- baseBuf.position(oldPosition);
- }
-
- public void testMark() {
- // save state
- int oldPosition = baseBuf.position();
- int oldLimit = baseBuf.limit();
-
- Buffer ret = baseBuf.mark();
- assertSame(ret, baseBuf);
-
- baseBuf.mark();
- baseBuf.position(baseBuf.limit());
- baseBuf.reset();
- assertEquals(baseBuf.position(), oldPosition);
-
- baseBuf.mark();
- baseBuf.position(baseBuf.limit());
- baseBuf.reset();
- assertEquals(baseBuf.position(), oldPosition);
-
- // restore state
- baseBuf.limit(oldLimit);
- baseBuf.position(oldPosition);
- }
-
- /*
- * Class under test for int position()
- */
- public void testPosition() {
- assertTrue(0 <= baseBuf.position() && baseBuf.position() <= baseBuf.limit()
- && baseBuf.limit() <= baseBuf.capacity());
- }
-
- /*
- * Class under test for Buffer position(int)
- */
- public void testPositionint() {
- // save state
- int oldPosition = baseBuf.position();
- int oldLimit = baseBuf.limit();
-
- try {
- baseBuf.position(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- baseBuf.position(baseBuf.limit() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- baseBuf.mark();
- baseBuf.position(baseBuf.position());
- baseBuf.reset();
- assertEquals(baseBuf.position(), oldPosition);
-
- baseBuf.position(0);
- assertEquals(baseBuf.position(), 0);
- baseBuf.position(baseBuf.limit());
- assertEquals(baseBuf.position(), baseBuf.limit());
-
- if (baseBuf.capacity() > 0) {
- baseBuf.limit(baseBuf.capacity());
- baseBuf.position(baseBuf.limit());
- baseBuf.mark();
- baseBuf.position(baseBuf.limit() - 1);
- assertEquals(baseBuf.position(), baseBuf.limit() - 1);
- // mark should be invalid
- try {
- baseBuf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- Buffer ret = baseBuf.position(0);
- assertSame(ret, baseBuf);
-
- // restore state
- baseBuf.limit(oldLimit);
- baseBuf.position(oldPosition);
- }
-
- public void testRemaining() {
- assertEquals(baseBuf.remaining(), baseBuf.limit() - baseBuf.position());
- }
-
- public void testReset() {
- // save state
- int oldPosition = baseBuf.position();
- int oldLimit = baseBuf.limit();
-
- baseBuf.mark();
- baseBuf.position(baseBuf.limit());
- baseBuf.reset();
- assertEquals(baseBuf.position(), oldPosition);
-
- baseBuf.mark();
- baseBuf.position(baseBuf.limit());
- baseBuf.reset();
- assertEquals(baseBuf.position(), oldPosition);
-
- Buffer ret = baseBuf.reset();
- assertSame(ret, baseBuf);
-
- baseBuf.clear();
- try {
- baseBuf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // restore state
- baseBuf.limit(oldLimit);
- baseBuf.position(oldPosition);
- }
-
- public void testRewind() {
- // save state
- int oldPosition = baseBuf.position();
- int oldLimit = baseBuf.limit();
-
- Buffer ret = baseBuf.rewind();
- assertEquals(baseBuf.position(), 0);
- assertSame(ret, baseBuf);
- try {
- baseBuf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // restore state
- baseBuf.limit(oldLimit);
- baseBuf.position(oldPosition);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.java
deleted file mode 100644
index 39059fe..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferOverflowException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-public class BufferOverflowExceptionTest extends TestCase {
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new BufferOverflowException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new BufferOverflowException());
- }
-
- /**
- *@tests {@link java.nio.BufferOverflowException#BufferOverflowException()}
- */
- public void test_Constructor() {
- BufferOverflowException exception = new BufferOverflowException();
- assertNull(exception.getMessage());
- assertNull(exception.getLocalizedMessage());
- assertNull(exception.getCause());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.java
deleted file mode 100644
index a056ebf..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferUnderflowException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for BufferUnderflowException
- */
-public class BufferUnderflowExceptionTest extends TestCase {
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new BufferUnderflowException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new BufferUnderflowException());
- }
-
- /**
- *@tests {@link java.nio.BufferUnderflowException#BufferUnderflowException()}
- */
- public void test_Constructor() {
- BufferUnderflowException exception = new BufferUnderflowException();
- assertNull(exception.getMessage());
- assertNull(exception.getLocalizedMessage());
- assertNull(exception.getCause());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteBufferTest.java
deleted file mode 100644
index d6d8681..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteBufferTest.java
+++ /dev/null
@@ -1,2177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.CharBuffer;
-import java.nio.DoubleBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.InvalidMarkException;
-import java.nio.LongBuffer;
-import java.nio.ReadOnlyBufferException;
-import java.nio.ShortBuffer;
-import java.util.Arrays;
-
-/**
- * Tests java.nio.ByteBuffer
- *
- */
-public class ByteBufferTest extends AbstractBufferTest {
- protected static final int SMALL_TEST_LENGTH = 5;
- protected static final int BUFFER_LENGTH = 250;
-
- protected ByteBuffer buf;
-
- protected void setUp() throws Exception {
- buf = ByteBuffer.allocate(10);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testArray() {
- if (buf.hasArray()) {
- byte array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- } else {
- if (buf.isReadOnly()) {
- try {
- buf.array();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- // expected
- // Note:can not tell when to throw
- // UnsupportedOperationException
- // or ReadOnlyBufferException, so catch all.
- }
- } else {
- try {
- buf.array();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- // expected
- }
- }
- }
- }
-
- public void testArrayOffset() {
- if (buf.hasArray()) {
- byte array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- } else {
- if (buf.isReadOnly()) {
- try {
- buf.arrayOffset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- // expected
- // Note:can not tell when to throw
- // UnsupportedOperationException
- // or ReadOnlyBufferException, so catch all.
- }
- } else {
- try {
- buf.arrayOffset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- // expected
- }
- }
- }
- }
-
- public void testAsReadOnlyBuffer() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // readonly's contents should be the same as buf
- ByteBuffer readonly = buf.asReadOnlyBuffer();
- assertNotSame(buf, readonly);
- assertTrue(readonly.isReadOnly());
- assertEquals(buf.position(), readonly.position());
- assertEquals(buf.limit(), readonly.limit());
- assertEquals(buf.isDirect(), readonly.isDirect());
- assertEquals(buf.order(), readonly.order());
- assertContentEquals(buf, readonly);
-
- // readonly's position, mark, and limit should be independent to buf
- readonly.reset();
- assertEquals(readonly.position(), 0);
- readonly.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
- }
-
- public void testCompact() {
- if (buf.isReadOnly()) {
- try {
- buf.compact();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- // case: buffer is full
- buf.clear();
- buf.mark();
- loadTestData1(buf);
- ByteBuffer ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), buf.capacity());
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (byte) 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: buffer is empty
- buf.position(0);
- buf.limit(0);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 0);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (byte) 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: normal
- assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
- buf.position(1);
- buf.limit(SMALL_TEST_LENGTH);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 4);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (byte) 1, 4);
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- public void testCompareTo() {
- // compare to self
- assertEquals(0, buf.compareTo(buf));
-
- // normal cases
- if (!buf.isReadOnly()) {
- assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
- buf.clear();
- ByteBuffer other = ByteBuffer.allocate(buf.capacity());
- loadTestData1(buf);
- loadTestData1(other);
- assertEquals(0, buf.compareTo(other));
- assertEquals(0, other.compareTo(buf));
- buf.position(1);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- other.position(2);
- assertTrue(buf.compareTo(other) < 0);
- assertTrue(other.compareTo(buf) > 0);
- buf.position(2);
- other.limit(SMALL_TEST_LENGTH);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- }
-
- assertTrue(ByteBuffer.wrap(new byte[21]).compareTo(ByteBuffer.allocateDirect(21)) == 0);
- }
-
- public void testDuplicate() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // duplicate's contents should be the same as buf
- ByteBuffer duplicate = buf.duplicate();
- assertNotSame(buf, duplicate);
- assertEquals(buf.position(), duplicate.position());
- assertEquals(buf.limit(), duplicate.limit());
- assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
- assertEquals(buf.isDirect(), duplicate.isDirect());
- assertEquals(buf.order(), duplicate.order());
- assertContentEquals(buf, duplicate);
-
- // duplicate's position, mark, and limit should be independent to buf
- duplicate.reset();
- assertEquals(duplicate.position(), 0);
- duplicate.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
-
- // duplicate share the same content with buf
- if (!duplicate.isReadOnly()) {
- loadTestData1(buf);
- assertContentEquals(buf, duplicate);
- loadTestData2(duplicate);
- assertContentEquals(buf, duplicate);
- }
- }
-
- public void testEquals() {
- // equal to self
- assertTrue(buf.equals(buf));
- ByteBuffer readonly = buf.asReadOnlyBuffer();
- assertTrue(buf.equals(readonly));
- ByteBuffer duplicate = buf.duplicate();
- assertTrue(buf.equals(duplicate));
-
- // always false, if type mismatch
- assertFalse(buf.equals(Boolean.TRUE));
-
- assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
-
- buf.limit(buf.capacity()).position(0);
- readonly.limit(readonly.capacity()).position(1);
- assertFalse(buf.equals(readonly));
-
- buf.limit(buf.capacity() - 1).position(0);
- duplicate.limit(duplicate.capacity()).position(0);
- assertFalse(buf.equals(duplicate));
- }
-
- /*
- * Class under test for byte get()
- */
- public void testGet() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.ByteBuffer get(byte[])
- */
- public void testGetbyteArray() {
- byte array[] = new byte[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- ByteBuffer ret = buf.get(array);
- assertEquals(array[0], buf.get(i));
- assertSame(ret, buf);
- }
- try {
- buf.get(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- try {
- buf.get((byte[])null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.ByteBuffer get(byte[], int, int)
- */
- public void testGetbyteArrayintint() {
- buf.clear();
- byte array[] = new byte[buf.capacity()];
-
- try {
- buf.get(new byte[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.get(array, array.length, 0);
- try {
- buf.get(array, array.length + 1, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get((byte[])null, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.get(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
-
- buf.clear();
- ByteBuffer ret = buf.get(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for byte get(int)
- */
- public void testGetint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(buf.limit());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testHasArray() {
- if (buf.hasArray()) {
- assertNotNull(buf.array());
- } else {
- if (buf.isReadOnly()) {
- try {
- buf.array();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- // expected
- // Note:can not tell when to throw
- // UnsupportedOperationException
- // or ReadOnlyBufferException, so catch all.
- }
- } else {
- try {
- buf.array();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- // expected
- }
- }
- }
- }
-
- public void testHashCode() {
- buf.clear();
- loadTestData1(buf);
- ByteBuffer readonly = buf.asReadOnlyBuffer();
- ByteBuffer duplicate = buf.duplicate();
- assertTrue(buf.hashCode() == readonly.hashCode());
- assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
- duplicate.position(buf.capacity()/2);
- assertTrue(buf.hashCode()!= duplicate.hashCode());
- }
-
- //for the testHashCode() method of readonly subclasses
- protected void readOnlyHashCode() {
- //create a new buffer initiated with some data
- ByteBuffer buf = ByteBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- buf.clear();
- ByteBuffer readonly = buf.asReadOnlyBuffer();
- ByteBuffer duplicate = buf.duplicate();
- assertEquals(buf.hashCode(),readonly.hashCode());
- duplicate.position(buf.capacity()/2);
- assertTrue(buf.hashCode()!= duplicate.hashCode());
- }
-
- public void testIsDirect() {
- buf.isDirect();
- }
-
- public void testOrder() {
- // BIG_ENDIAN is the default byte order
- assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
-
- buf.order(ByteOrder.LITTLE_ENDIAN);
- assertEquals(ByteOrder.LITTLE_ENDIAN, buf.order());
-
- buf.order(ByteOrder.BIG_ENDIAN);
- assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
-
- // Regression test for HARMONY-798
- buf.order((ByteOrder)null);
- assertEquals(ByteOrder.LITTLE_ENDIAN, buf.order());
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- /*
- * Class under test for java.nio.ByteBuffer put(byte)
- */
- public void testPutbyte() {
- if (buf.isReadOnly()) {
- try {
- buf.clear();
- buf.put((byte) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- ByteBuffer ret = buf.put((byte) i);
- assertEquals(buf.get(i), (byte) i);
- assertSame(ret, buf);
- }
- try {
- buf.put((byte) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.ByteBuffer put(byte[])
- */
- public void testPutbyteArray() {
- byte array[] = new byte[1];
- if (buf.isReadOnly()) {
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- array[0] = (byte) i;
- ByteBuffer ret = buf.put(array);
- assertEquals(buf.get(i), (byte) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.put((byte[])null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.ByteBuffer put(byte[], int, int)
- */
- public void testPutbyteArrayintint() {
- buf.clear();
- byte array[] = new byte[buf.capacity()];
- if (buf.isReadOnly()) {
- try {
- buf.put(array, 0, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- try {
- buf.put(new byte[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, array.length + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.put(array, array.length, 0);
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- buf.put(array, 2, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put((byte[])null, 2, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
-
- assertEquals(buf.position(), 0);
-
- loadTestData2(array, 0, array.length);
- ByteBuffer ret = buf.put(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.ByteBuffer put(java.nio.ByteBuffer)
- */
- public void testPutByteBuffer() {
- ByteBuffer other = ByteBuffer.allocate(buf.capacity());
- if (buf.isReadOnly()) {
- try {
- buf.clear();
- buf.put(other);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.clear();
- buf.put((ByteBuffer)null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- try {
- buf.put(buf);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- buf.put(ByteBuffer.allocate(buf.capacity() + 1));
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
-
- try {
- buf.put((ByteBuffer)null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- loadTestData2(other);
- other.clear();
- buf.clear();
- ByteBuffer ret = buf.put(other);
- assertEquals(other.position(), other.capacity());
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(other, buf);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.ByteBuffer put(int, byte)
- */
- public void testPutintbyte() {
- if (buf.isReadOnly()) {
- try {
- buf.put(0, (byte) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), 0);
- ByteBuffer ret = buf.put(i, (byte) i);
- assertEquals(buf.get(i), (byte) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(-1, (byte) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(buf.limit(), (byte) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testSlice() {
- assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
- buf.position(1);
- buf.limit(buf.capacity() - 1);
-
- ByteBuffer slice = buf.slice();
- assertEquals(buf.isReadOnly(), slice.isReadOnly());
- assertEquals(buf.isDirect(), slice.isDirect());
- assertEquals(buf.order(), slice.order());
- assertEquals(slice.position(), 0);
- assertEquals(slice.limit(), buf.remaining());
- assertEquals(slice.capacity(), buf.remaining());
- try {
- slice.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // slice share the same content with buf
- if (!slice.isReadOnly()) {
- loadTestData1(slice);
- assertContentLikeTestData1(buf, 1, (byte) 0, slice.capacity());
- buf.put(2, (byte) 100);
- assertEquals(slice.get(1), 100);
- }
- }
-
- public void testToString() {
- String str = buf.toString();
- assertTrue(str.indexOf("Byte") >= 0 || str.indexOf("byte") >= 0);
- assertTrue(str.indexOf("" + buf.position()) >= 0);
- assertTrue(str.indexOf("" + buf.limit()) >= 0);
- assertTrue(str.indexOf("" + buf.capacity()) >= 0);
- }
-
- public void testAsCharBuffer() {
- CharBuffer charBuffer;
- byte bytes[] = new byte[2];
- char value;
-
- // test BIG_ENDIAN char buffer, read
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- charBuffer = buf.asCharBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, charBuffer.order());
- while (charBuffer.remaining() > 0) {
- buf.get(bytes);
- value = charBuffer.get();
- assertEquals(bytes2char(bytes, buf.order()), value);
- }
-
- // test LITTLE_ENDIAN char buffer, read
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- charBuffer = buf.asCharBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, charBuffer.order());
- while (charBuffer.remaining() > 0) {
- buf.get(bytes);
- value = charBuffer.get();
- assertEquals(bytes2char(bytes, buf.order()), value);
- }
-
- if (!buf.isReadOnly()) {
- // test BIG_ENDIAN char buffer, write
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- charBuffer = buf.asCharBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, charBuffer.order());
- while (charBuffer.remaining() > 0) {
- value = (char) charBuffer.remaining();
- charBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, char2bytes(value, buf.order())));
- }
-
- // test LITTLE_ENDIAN char buffer, write
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- charBuffer = buf.asCharBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, charBuffer.order());
- while (charBuffer.remaining() > 0) {
- value = (char) charBuffer.remaining();
- charBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, char2bytes(value, buf.order())));
- }
- }
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testAsDoubleBuffer() {
- DoubleBuffer doubleBuffer;
- byte bytes[] = new byte[8];
- double value;
-
- // test BIG_ENDIAN double buffer, read
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- doubleBuffer = buf.asDoubleBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, doubleBuffer.order());
- while (doubleBuffer.remaining() > 0) {
- buf.get(bytes);
- value = doubleBuffer.get();
- if (!(Double.isNaN(bytes2double(bytes, buf.order())) && Double
- .isNaN(value))) {
- assertEquals(bytes2double(bytes, buf.order()), value, 0.00);
- }
- }
-
- // test LITTLE_ENDIAN double buffer, read
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- doubleBuffer = buf.asDoubleBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, doubleBuffer.order());
- while (doubleBuffer.remaining() > 0) {
- buf.get(bytes);
- value = doubleBuffer.get();
- if (!(Double.isNaN(bytes2double(bytes, buf.order())) && Double
- .isNaN(value))) {
- assertEquals(bytes2double(bytes, buf.order()), value, 0.00);
- }
- }
-
- if (!buf.isReadOnly()) {
- // test BIG_ENDIAN double buffer, write
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- doubleBuffer = buf.asDoubleBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, doubleBuffer.order());
- while (doubleBuffer.remaining() > 0) {
- value = (double) doubleBuffer.remaining();
- doubleBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, double2bytes(value, buf.order())));
- }
-
- // test LITTLE_ENDIAN double buffer, write
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- doubleBuffer = buf.asDoubleBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, doubleBuffer.order());
- while (doubleBuffer.remaining() > 0) {
- value = (double) doubleBuffer.remaining();
- doubleBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, double2bytes(value, buf.order())));
- }
- }
-
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testAsFloatBuffer() {
- FloatBuffer floatBuffer;
- byte bytes[] = new byte[4];
- float value;
-
- // test BIG_ENDIAN float buffer, read
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- floatBuffer = buf.asFloatBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, floatBuffer.order());
- while (floatBuffer.remaining() > 0) {
- buf.get(bytes);
- value = floatBuffer.get();
- if (!(Float.isNaN(bytes2float(bytes, buf.order())) && Float
- .isNaN(value))) {
- assertEquals(bytes2float(bytes, buf.order()), value, 0.00);
- }
- }
-
- // test LITTLE_ENDIAN float buffer, read
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- floatBuffer = buf.asFloatBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, floatBuffer.order());
- while (floatBuffer.remaining() > 0) {
- buf.get(bytes);
- value = floatBuffer.get();
- if (!(Float.isNaN(bytes2float(bytes, buf.order())) && Float
- .isNaN(value))) {
- assertEquals(bytes2float(bytes, buf.order()), value, 0.00);
- }
- }
-
- if (!buf.isReadOnly()) {
- // test BIG_ENDIAN float buffer, write
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- floatBuffer = buf.asFloatBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, floatBuffer.order());
- while (floatBuffer.remaining() > 0) {
- value = (float) floatBuffer.remaining();
- floatBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, float2bytes(value, buf.order())));
- }
-
- // test LITTLE_ENDIAN float buffer, write
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- floatBuffer = buf.asFloatBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, floatBuffer.order());
- while (floatBuffer.remaining() > 0) {
- value = (float) floatBuffer.remaining();
- floatBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, float2bytes(value, buf.order())));
- }
- }
-
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testAsIntBuffer() {
- IntBuffer intBuffer;
- byte bytes[] = new byte[4];
- int value;
-
- // test BIG_ENDIAN int buffer, read
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- intBuffer = buf.asIntBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, intBuffer.order());
- while (intBuffer.remaining() > 0) {
- buf.get(bytes);
- value = intBuffer.get();
- assertEquals(bytes2int(bytes, buf.order()), value);
- }
-
- // test LITTLE_ENDIAN int buffer, read
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- intBuffer = buf.asIntBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, intBuffer.order());
- while (intBuffer.remaining() > 0) {
- buf.get(bytes);
- value = intBuffer.get();
- assertEquals(bytes2int(bytes, buf.order()), value);
- }
-
- if (!buf.isReadOnly()) {
- // test BIG_ENDIAN int buffer, write
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- intBuffer = buf.asIntBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, intBuffer.order());
- while (intBuffer.remaining() > 0) {
- value = (int) intBuffer.remaining();
- intBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, int2bytes(value, buf.order())));
- }
-
- // test LITTLE_ENDIAN int buffer, write
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- intBuffer = buf.asIntBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, intBuffer.order());
- while (intBuffer.remaining() > 0) {
- value = (int) intBuffer.remaining();
- intBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, int2bytes(value, buf.order())));
- }
- }
-
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testAsLongBuffer() {
- LongBuffer longBuffer;
- byte bytes[] = new byte[8];
- long value;
-
- // test BIG_ENDIAN long buffer, read
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- longBuffer = buf.asLongBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, longBuffer.order());
- while (longBuffer.remaining() > 0) {
- buf.get(bytes);
- value = longBuffer.get();
- assertEquals(bytes2long(bytes, buf.order()), value);
- }
-
- // test LITTLE_ENDIAN long buffer, read
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- longBuffer = buf.asLongBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, longBuffer.order());
- while (longBuffer.remaining() > 0) {
- buf.get(bytes);
- value = longBuffer.get();
- assertEquals(bytes2long(bytes, buf.order()), value);
- }
-
- if (!buf.isReadOnly()) {
- // test BIG_ENDIAN long buffer, write
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- longBuffer = buf.asLongBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, longBuffer.order());
- while (longBuffer.remaining() > 0) {
- value = (long) longBuffer.remaining();
- longBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, long2bytes(value, buf.order())));
- }
-
- // test LITTLE_ENDIAN long buffer, write
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- longBuffer = buf.asLongBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, longBuffer.order());
- while (longBuffer.remaining() > 0) {
- value = (long) longBuffer.remaining();
- longBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, long2bytes(value, buf.order())));
- }
- }
-
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testAsShortBuffer() {
- ShortBuffer shortBuffer;
- byte bytes[] = new byte[2];
- short value;
-
- // test BIG_ENDIAN short buffer, read
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- shortBuffer = buf.asShortBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, shortBuffer.order());
- while (shortBuffer.remaining() > 0) {
- buf.get(bytes);
- value = shortBuffer.get();
- assertEquals(bytes2short(bytes, buf.order()), value);
- }
-
- // test LITTLE_ENDIAN short buffer, read
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- shortBuffer = buf.asShortBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, shortBuffer.order());
- while (shortBuffer.remaining() > 0) {
- buf.get(bytes);
- value = shortBuffer.get();
- assertEquals(bytes2short(bytes, buf.order()), value);
- }
-
- if (!buf.isReadOnly()) {
- // test BIG_ENDIAN short buffer, write
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- shortBuffer = buf.asShortBuffer();
- assertSame(ByteOrder.BIG_ENDIAN, shortBuffer.order());
- while (shortBuffer.remaining() > 0) {
- value = (short) shortBuffer.remaining();
- shortBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, short2bytes(value, buf.order())));
- }
-
- // test LITTLE_ENDIAN short buffer, write
- buf.clear();
- buf.order(ByteOrder.LITTLE_ENDIAN);
- shortBuffer = buf.asShortBuffer();
- assertSame(ByteOrder.LITTLE_ENDIAN, shortBuffer.order());
- while (shortBuffer.remaining() > 0) {
- value = (short) shortBuffer.remaining();
- shortBuffer.put(value);
- buf.get(bytes);
- assertTrue(Arrays.equals(bytes, short2bytes(value, buf.order())));
- }
- }
-
- buf.clear();
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetChar() {
- int nbytes = 2;
- byte bytes[] = new byte[nbytes];
- char value;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- assertEquals(i * nbytes, buf.position());
- buf.mark();
- buf.get(bytes);
- buf.reset();
- value = buf.getChar();
- assertEquals(bytes2char(bytes, buf.order()), value);
- }
-
- try {
- buf.getChar();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetCharint() {
- int nbytes = 2;
- byte bytes[] = new byte[nbytes];
- char value;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- buf.position(i);
- value = buf.getChar(i);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertEquals(bytes2char(bytes, buf.order()), value);
- }
-
- try {
- buf.getChar(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.getChar(buf.limit() - nbytes + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutChar() {
- if (buf.isReadOnly()) {
- try {
- buf.clear();
- buf.putChar((char) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 2;
- byte bytes[] = new byte[nbytes];
- char value = 0;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (char) i;
- buf.mark();
- buf.putChar(value);
- assertEquals((i + 1) * nbytes, buf.position());
- buf.reset();
- buf.get(bytes);
- assertTrue(Arrays.equals(char2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putChar(value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutCharint() {
- if (buf.isReadOnly()) {
- try {
- buf.putChar(0, (char) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 2;
- byte bytes[] = new byte[nbytes];
- char value = 0;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (char) i;
- buf.position(i);
- buf.putChar(i, value);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertTrue(Arrays.equals(char2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putChar(-1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.putChar(buf.limit() - nbytes + 1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
-
- try {
- ByteBuffer.allocateDirect(16).putChar(Integer.MAX_VALUE, 'h');
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- public void testGetDouble() {
- int nbytes = 8;
- byte bytes[] = new byte[nbytes];
- double value;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- assertEquals(i * nbytes, buf.position());
- buf.mark();
- buf.get(bytes);
- buf.reset();
- value = buf.getDouble();
- if (!(Double.isNaN(bytes2double(bytes, buf.order())) && Double
- .isNaN(value))) {
- assertEquals(bytes2double(bytes, buf.order()), value, 0.00);
- }
- }
-
- try {
- buf.getDouble();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetDoubleint() {
- int nbytes = 8;
- byte bytes[] = new byte[nbytes];
- double value;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- buf.position(i);
- value = buf.getDouble(i);
- assertEquals(i, buf.position());
- buf.get(bytes);
- if (!(Double.isNaN(bytes2double(bytes, buf.order())) && Double
- .isNaN(value))) {
- assertEquals(bytes2double(bytes, buf.order()), value, 0.00);
- }
- }
-
- try {
- buf.getDouble(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.getDouble(buf.limit() - nbytes + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
-
- try {
- ByteBuffer.allocateDirect(16).getDouble(Integer.MAX_VALUE);
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- public void testPutDouble() {
- if (buf.isReadOnly()) {
- try {
- buf.clear();
- buf.putDouble((double) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 8;
- byte bytes[] = new byte[nbytes];
- double value = 0;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (double) i;
- buf.mark();
- buf.putDouble(value);
- assertEquals((i + 1) * nbytes, buf.position());
- buf.reset();
- buf.get(bytes);
- assertTrue(Arrays.equals(double2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putDouble(value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutDoubleint() {
- if (buf.isReadOnly()) {
- try {
- buf.putDouble(0, (double) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 8;
- byte bytes[] = new byte[nbytes];
- double value = 0;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (double) i;
- buf.position(i);
- buf.putDouble(i, value);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertTrue(Arrays.equals(double2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putDouble(-1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.putDouble(buf.limit() - nbytes + 1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetFloat() {
- int nbytes = 4;
- byte bytes[] = new byte[nbytes];
- float value;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- assertEquals(i * nbytes, buf.position());
- buf.mark();
- buf.get(bytes);
- buf.reset();
- value = buf.getFloat();
- if (!(Float.isNaN(bytes2float(bytes, buf.order())) && Float
- .isNaN(value))) {
- assertEquals(bytes2float(bytes, buf.order()), value, 0.00);
- }
- }
-
- try {
- buf.getFloat();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetFloatint() {
- int nbytes = 4;
- byte bytes[] = new byte[nbytes];
- float value;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- buf.position(i);
- value = buf.getFloat(i);
- assertEquals(i, buf.position());
- buf.get(bytes);
- if (!(Float.isNaN(bytes2float(bytes, buf.order())) && Float
- .isNaN(value))) {
- assertEquals(bytes2float(bytes, buf.order()), value, 0.00);
- }
- }
-
- try {
- buf.getFloat(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.getFloat(buf.limit() - nbytes + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutFloat() {
- if (buf.isReadOnly()) {
- try {
- buf.clear();
- buf.putFloat((float) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 4;
- byte bytes[] = new byte[nbytes];
- float value = 0;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (float) i;
- buf.mark();
- buf.putFloat(value);
- assertEquals((i + 1) * nbytes, buf.position());
- buf.reset();
- buf.get(bytes);
- assertTrue(Arrays.equals(float2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putFloat(value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutFloatint() {
- if (buf.isReadOnly()) {
- try {
- buf.putFloat(0, (float) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 4;
- byte bytes[] = new byte[nbytes];
- float value = 0;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (float) i;
- buf.position(i);
- buf.putFloat(i, value);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertTrue(Arrays.equals(float2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putFloat(-1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.putFloat(buf.limit() - nbytes + 1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetInt() {
- int nbytes = 4;
- byte bytes[] = new byte[nbytes];
- int value;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- assertEquals(i * nbytes, buf.position());
- buf.mark();
- buf.get(bytes);
- buf.reset();
- value = buf.getInt();
- assertEquals(bytes2int(bytes, buf.order()), value);
- }
-
- try {
- buf.getInt();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetIntint() {
- int nbytes = 4;
- byte bytes[] = new byte[nbytes];
- int value;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- buf.position(i);
- value = buf.getInt(i);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertEquals(bytes2int(bytes, buf.order()), value);
- }
-
- try {
- buf.getInt(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.getInt(buf.limit() - nbytes + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- try {
- ByteBuffer.allocateDirect(16).getInt(Integer.MAX_VALUE);
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- public void testPutInt() {
- if (buf.isReadOnly()) {
- try {
- buf.clear();
- buf.putInt((int) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 4;
- byte bytes[] = new byte[nbytes];
- int value = 0;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (int) i;
- buf.mark();
- buf.putInt(value);
- assertEquals((i + 1) * nbytes, buf.position());
- buf.reset();
- buf.get(bytes);
- assertTrue(Arrays.equals(int2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putInt(value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutIntint() {
- if (buf.isReadOnly()) {
- try {
- buf.putInt(0, (int) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 4;
- byte bytes[] = new byte[nbytes];
- int value = 0;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (int) i;
- buf.position(i);
- buf.putInt(i, value);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertTrue(Arrays.equals(int2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putInt(-1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.putInt(buf.limit() - nbytes + 1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetLong() {
- int nbytes = 8;
- byte bytes[] = new byte[nbytes];
- long value;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- assertEquals(i * nbytes, buf.position());
- buf.mark();
- buf.get(bytes);
- buf.reset();
- value = buf.getLong();
- assertEquals(bytes2long(bytes, buf.order()), value);
- }
-
- try {
- buf.getLong();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetLongint() {
- int nbytes = 8;
- byte bytes[] = new byte[nbytes];
- long value;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- buf.position(i);
- value = buf.getLong(i);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertEquals(bytes2long(bytes, buf.order()), value);
- }
-
- try {
- buf.getLong(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.getLong(buf.limit() - nbytes + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutLong() {
- if (buf.isReadOnly()) {
- try {
- buf.clear();
- buf.putLong((long) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 8;
- byte bytes[] = new byte[nbytes];
- long value = 0;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (long) i;
- buf.mark();
- buf.putLong(value);
- assertEquals((i + 1) * nbytes, buf.position());
- buf.reset();
- buf.get(bytes);
- assertTrue(Arrays.equals(long2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putLong(value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutLongint() {
- if (buf.isReadOnly()) {
- try {
- buf.putLong(0, (long) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 8;
- byte bytes[] = new byte[nbytes];
- long value = 0;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (long) i;
- buf.position(i);
- buf.putLong(i, value);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertTrue(Arrays.equals(long2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putLong(-1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.putLong(buf.limit() - nbytes + 1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetShort() {
- int nbytes = 2;
- byte bytes[] = new byte[nbytes];
- short value;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- assertEquals(i * nbytes, buf.position());
- buf.mark();
- buf.get(bytes);
- buf.reset();
- value = buf.getShort();
- assertEquals(bytes2short(bytes, buf.order()), value);
- }
-
- try {
- buf.getShort();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testGetShortint() {
- int nbytes = 2;
- byte bytes[] = new byte[nbytes];
- short value;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- buf.position(i);
- value = buf.getShort(i);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertEquals(bytes2short(bytes, buf.order()), value);
- }
-
- try {
- buf.getShort(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.getShort(buf.limit() - nbytes + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutShort() {
- if (buf.isReadOnly()) {
- try {
- buf.clear();
- buf.putShort((short) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 2;
- byte bytes[] = new byte[nbytes];
- short value = 0;
- buf.clear();
- for (int i = 0; buf.remaining() >= nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (short) i;
- buf.mark();
- buf.putShort(value);
- assertEquals((i + 1) * nbytes, buf.position());
- buf.reset();
- buf.get(bytes);
- assertTrue(Arrays.equals(short2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putShort(value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- public void testPutShortint() {
- if (buf.isReadOnly()) {
- try {
- buf.putShort(0, (short) 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- return;
- }
-
- int nbytes = 2;
- byte bytes[] = new byte[nbytes];
- short value = 0;
- buf.clear();
- for (int i = 0; i <= buf.limit() - nbytes; i++) {
- buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
- : ByteOrder.LITTLE_ENDIAN);
- value = (short) i;
- buf.position(i);
- buf.putShort(i, value);
- assertEquals(i, buf.position());
- buf.get(bytes);
- assertTrue(Arrays.equals(short2bytes(value, buf.order()), bytes));
- }
-
- try {
- buf.putShort(-1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.putShort(buf.limit() - nbytes + 1, value);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- buf.order(ByteOrder.BIG_ENDIAN);
- }
-
- /**
- * @tests java.nio.ByteBuffer.wrap(byte[],int,int)
- */
- public void testWrappedByteBuffer_null_array() {
- // Regression for HARMONY-264
- byte array[] = null;
- try {
- ByteBuffer.wrap(array, -1, 0);
- fail("Should throw NPE"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- }
- try {
- ByteBuffer.wrap(new byte[10], Integer.MAX_VALUE, 2);
- fail("Should throw IndexOutOfBoundsException"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- }
- }
-
- private void loadTestData1(byte array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (byte) i;
- }
- }
-
- private void loadTestData2(byte array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (byte) (length - i);
- }
- }
-
- private void loadTestData1(ByteBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (byte) i);
- }
- }
-
- private void loadTestData2(ByteBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (byte) (buf.capacity() - i));
- }
- }
-
- private void assertContentEquals(ByteBuffer buf, byte array[],
- int offset, int length) {
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(i), array[offset + i]);
- }
- }
-
- private void assertContentEquals(ByteBuffer buf, ByteBuffer other) {
- assertEquals(buf.capacity(), other.capacity());
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.get(i), other.get(i));
- }
- }
-
- private void assertContentLikeTestData1(ByteBuffer buf,
- int startIndex, byte startValue, int length) {
- byte value = startValue;
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(startIndex + i), value);
- value = (byte) (value + 1);
- }
- }
-
- private int bytes2int(byte bytes[], ByteOrder order) {
- int nbytes = 4, bigHead, step;
- if (order == ByteOrder.BIG_ENDIAN) {
- bigHead = 0;
- step = 1;
- } else {
- bigHead = nbytes - 1;
- step = -1;
- }
- int result = 0;
- int p = bigHead;
- for (int i = 0; i < nbytes; i++) {
- result = result << 8;
- result = result | (bytes[p] & 0xff);
- p += step;
- }
- return result;
- }
-
- private long bytes2long(byte bytes[], ByteOrder order) {
- int nbytes = 8, bigHead, step;
- if (order == ByteOrder.BIG_ENDIAN) {
- bigHead = 0;
- step = 1;
- } else {
- bigHead = nbytes - 1;
- step = -1;
- }
- long result = 0;
- int p = bigHead;
- for (int i = 0; i < nbytes; i++) {
- result = result << 8;
- result = result | (bytes[p] & 0xff);
- p += step;
- }
- return result;
- }
-
- private short bytes2short(byte bytes[], ByteOrder order) {
- int nbytes = 2, bigHead, step;
- if (order == ByteOrder.BIG_ENDIAN) {
- bigHead = 0;
- step = 1;
- } else {
- bigHead = nbytes - 1;
- step = -1;
- }
- short result = 0;
- int p = bigHead;
- for (int i = 0; i < nbytes; i++) {
- result = (short) (result << 8);
- result = (short) (result | (bytes[p] & 0xff));
- p += step;
- }
- return result;
- }
-
- private char bytes2char(byte bytes[], ByteOrder order) {
- return (char) bytes2short(bytes, order);
- }
-
- private float bytes2float(byte bytes[], ByteOrder order) {
- return Float.intBitsToFloat(bytes2int(bytes, order));
- }
-
- private double bytes2double(byte bytes[], ByteOrder order) {
- return Double.longBitsToDouble(bytes2long(bytes, order));
- }
-
- private byte[] int2bytes(int value, ByteOrder order) {
- int nbytes = 4, smallHead, step;
- if (order == ByteOrder.BIG_ENDIAN) {
- smallHead = nbytes - 1;
- step = -1;
- } else {
- smallHead = 0;
- step = 1;
- }
- byte bytes[] = new byte[nbytes];
- int p = smallHead;
- for (int i = 0; i < nbytes; i++) {
- bytes[p] = (byte) (value & 0xff);
- value = value >> 8;
- p += step;
- }
- return bytes;
- }
-
- private byte[] long2bytes(long value, ByteOrder order) {
- int nbytes = 8, smallHead, step;
- if (order == ByteOrder.BIG_ENDIAN) {
- smallHead = nbytes - 1;
- step = -1;
- } else {
- smallHead = 0;
- step = 1;
- }
- byte bytes[] = new byte[nbytes];
- int p = smallHead;
- for (int i = 0; i < nbytes; i++) {
- bytes[p] = (byte) (value & 0xff);
- value = value >> 8;
- p += step;
- }
- return bytes;
- }
-
- private byte[] short2bytes(short value, ByteOrder order) {
- int nbytes = 2, smallHead, step;
- if (order == ByteOrder.BIG_ENDIAN) {
- smallHead = nbytes - 1;
- step = -1;
- } else {
- smallHead = 0;
- step = 1;
- }
- byte bytes[] = new byte[nbytes];
- int p = smallHead;
- for (int i = 0; i < nbytes; i++) {
- bytes[p] = (byte) (value & 0xff);
- value = (short) (value >> 8);
- p += step;
- }
- return bytes;
- }
-
- private byte[] char2bytes(char value, ByteOrder order) {
- return short2bytes((short) value, order);
- }
-
- private byte[] float2bytes(float value, ByteOrder order) {
- return int2bytes(Float.floatToRawIntBits(value), order);
- }
-
- private byte[] double2bytes(double value, ByteOrder order) {
- return long2bytes(Double.doubleToRawLongBits(value), order);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteOrderTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteOrderTest.java
deleted file mode 100644
index 8f41904..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteOrderTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteOrder;
-
-import junit.framework.TestCase;
-
-/**
- * Test java.nio.ByteOrder
- *
- */
-public class ByteOrderTest extends TestCase {
-
- public void testToString() {
- assertEquals(ByteOrder.BIG_ENDIAN.toString(), "BIG_ENDIAN");
- assertEquals(ByteOrder.LITTLE_ENDIAN.toString(), "LITTLE_ENDIAN");
- }
-
- public void testNativeOrder() {
- ByteOrder o = ByteOrder.nativeOrder();
- assertTrue(o == ByteOrder.BIG_ENDIAN || o == ByteOrder.LITTLE_ENDIAN);
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java
deleted file mode 100644
index 8a7c5f3..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.io.IOException;
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteOrder;
-import java.nio.CharBuffer;
-import java.nio.InvalidMarkException;
-import java.nio.ReadOnlyBufferException;
-
-/**
- * Tests java.nio.CharBuffer
- *
- */
-public class CharBufferTest extends AbstractBufferTest {
- protected static final int SMALL_TEST_LENGTH = 5;
-
- protected static final int BUFFER_LENGTH = 20;
-
- protected CharBuffer buf;
-
- private static char[] chars = "123456789a".toCharArray();
-
- protected void setUp() throws Exception{
- char[] charscopy = new char[chars.length];
- System.arraycopy(chars, 0, charscopy, 0, chars.length);
- buf = CharBuffer.wrap(charscopy);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception{
- buf = null;
- baseBuf = null;
- }
-
- public void testArray() {
- char array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testArrayOffset() {
- char array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testAsReadOnlyBuffer() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // readonly's contents should be the same as buf
- CharBuffer readonly = buf.asReadOnlyBuffer();
- assertNotSame(buf, readonly);
- assertTrue(readonly.isReadOnly());
- assertEquals(buf.position(), readonly.position());
- assertEquals(buf.limit(), readonly.limit());
- assertEquals(buf.isDirect(), readonly.isDirect());
- assertEquals(buf.order(), readonly.order());
- assertEquals(buf.capacity(), readonly.capacity());
- assertContentEquals(buf, readonly);
-
- // readonly's position, mark, and limit should be independent to buf
- readonly.reset();
- assertEquals(readonly.position(), 0);
- readonly.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
-
- buf.clear();
- int originalPosition = (buf.position() + buf.limit()) / 2;
- buf.position(originalPosition);
- buf.mark();
- buf.position(buf.limit());
-
- // readonly's contents should be the same as buf
- readonly = buf.asReadOnlyBuffer();
- assertNotSame(buf, readonly);
- assertTrue(readonly.isReadOnly());
- assertEquals(buf.position(), readonly.position());
- assertEquals(buf.limit(), readonly.limit());
- assertEquals(buf.isDirect(), readonly.isDirect());
- assertEquals(buf.order(), readonly.order());
- assertEquals(buf.capacity(), readonly.capacity());
- assertContentEquals(buf, readonly);
-
- // readonly's position, mark, and limit should be independent to buf
- readonly.reset();
- assertEquals(readonly.position(), originalPosition);
- readonly.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), originalPosition);
- }
-
- public void testCompact() {
- // case: buffer is full
- buf.clear();
- buf.mark();
- loadTestData1(buf);
- CharBuffer ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), buf.capacity());
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (char) 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: buffer is empty
- buf.position(0);
- buf.limit(0);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 0);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (char) 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: normal
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(5);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 4);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (char) 1, 4);
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- public void testCompareTo() {
- // compare to self
- assertEquals(0, buf.compareTo(buf));
-
- assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
- buf.clear();
- CharBuffer other = CharBuffer.allocate(buf.capacity());
- other.put(buf);
- other.clear();
- buf.clear();
- assertEquals(0, buf.compareTo(other));
- assertEquals(0, other.compareTo(buf));
- buf.position(1);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- other.position(2);
- assertTrue(buf.compareTo(other) < 0);
- assertTrue(other.compareTo(buf) > 0);
- buf.position(2);
- assertTrue(buf.compareTo(other) == 0);
- assertTrue(other.compareTo(buf) == 0);
- other.limit(SMALL_TEST_LENGTH);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- }
-
- public void testDuplicate() {
- // mark the position 0
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // duplicate's contents should be the same as buf
- CharBuffer duplicate = buf.duplicate();
- assertNotSame(buf, duplicate);
- assertEquals(buf.position(), duplicate.position());
- assertEquals(buf.limit(), duplicate.limit());
- assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
- assertEquals(buf.isDirect(), duplicate.isDirect());
- assertEquals(buf.order(), duplicate.order());
- assertEquals(buf.capacity(), duplicate.capacity());
- assertContentEquals(buf, duplicate);
-
- // duplicate's position, mark, and limit should be independent to
- // buf
- duplicate.reset();
- assertEquals(duplicate.position(), 0);
- duplicate.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
-
- // mark another position
- buf.clear();
- int originalPosition = (buf.position() + buf.limit()) / 2;
- buf.position(originalPosition);
- buf.mark();
- buf.position(buf.limit());
-
- // duplicate's contents should be the same as buf
- duplicate = buf.duplicate();
- assertNotSame(buf, duplicate);
- assertEquals(buf.position(), duplicate.position());
- assertEquals(buf.limit(), duplicate.limit());
- assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
- assertEquals(buf.isDirect(), duplicate.isDirect());
- assertEquals(buf.order(), duplicate.order());
- assertEquals(buf.capacity(), duplicate.capacity());
- assertContentEquals(buf, duplicate);
-
- // duplicate's position, mark, and limit should be independent to
- // buf
- duplicate.reset();
- assertEquals(duplicate.position(), originalPosition);
- duplicate.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), originalPosition);
-
- // duplicate share the same content with buf
- if (!duplicate.isReadOnly()) {
- loadTestData1(buf);
- assertContentEquals(buf, duplicate);
- loadTestData2(duplicate);
- assertContentEquals(buf, duplicate);
- }
- }
-
- public void testEquals() {
- // equal to self
- assertTrue(buf.equals(buf));
- CharBuffer readonly = buf.asReadOnlyBuffer();
- assertTrue(buf.equals(readonly));
- CharBuffer duplicate = buf.duplicate();
- assertTrue(buf.equals(duplicate));
-
- // always false, if type mismatch
- assertFalse(buf.equals(Boolean.TRUE));
-
- assertTrue(buf.capacity() > 5);
-
- buf.limit(buf.capacity()).position(0);
- readonly.limit(readonly.capacity()).position(1);
- assertFalse(buf.equals(readonly));
-
- buf.limit(buf.capacity() - 1).position(0);
- duplicate.limit(duplicate.capacity()).position(0);
- assertFalse(buf.equals(duplicate));
- }
-
- /*
- * Class under test for char get()
- */
- public void testGet() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.CharBuffer get(char[])
- */
- public void testGetcharArray() {
- char array[] = new char[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- CharBuffer ret = buf.get(array);
- assertEquals(array[0], buf.get(i));
- assertSame(ret, buf);
- }
- try {
- buf.get(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.CharBuffer get(char[], int, int)
- */
- public void testGetcharArrayintint() {
- buf.clear();
- char array[] = new char[buf.capacity()];
-
- try {
- buf.get(new char[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.get(array, array.length, 0);
- try {
- buf.get(array, array.length + 1, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get((char[])null, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.get(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- buf.get(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
-
- buf.clear();
- CharBuffer ret = buf.get(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for char get(int)
- */
- public void testGetint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(buf.limit());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testHashCode() {
- buf.clear();
- loadTestData1(buf);
- CharBuffer readonly = buf.asReadOnlyBuffer();
- CharBuffer duplicate = buf.duplicate();
- assertTrue(buf.hashCode() == readonly.hashCode());
- assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
- duplicate.position(buf.capacity() / 2);
- assertTrue(buf.hashCode() != duplicate.hashCode());
- }
-
- /*
- * Class under test for java.nio.CharBuffer put(char)
- */
- public void testPutchar() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- CharBuffer ret = buf.put((char) i);
- assertEquals(buf.get(i), (char) i);
- assertSame(ret, buf);
- }
- try {
- buf.put((char) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.CharBuffer put(char[])
- */
- public void testPutcharArray() {
- char array[] = new char[1];
-
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- array[0] = (char) i;
- CharBuffer ret = buf.put(array);
- assertEquals(buf.get(i), (char) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.put((char[]) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.CharBuffer put(char[], int, int)
- */
- public void testPutcharArrayintint() {
- buf.clear();
- char array[] = new char[buf.capacity()];
- try {
- buf.put((char[]) null, 0, 1);
- fail("Should throw NullPointerException"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.put(new char[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, array.length + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.put(array, array.length, 0);
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put((char[])null, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.put(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- assertEquals(buf.position(), 0);
-
- loadTestData2(array, 0, array.length);
- CharBuffer ret = buf.put(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.CharBuffer put(java.nio.CharBuffer)
- */
- public void testPutCharBuffer() {
- CharBuffer other = CharBuffer.allocate(buf.capacity());
-
- try {
- buf.put((CharBuffer) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.put(buf);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- buf.put(CharBuffer.allocate(buf.capacity() + 1));
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.flip();
- buf.put((CharBuffer)null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
-
- loadTestData2(other);
- other.clear();
- buf.clear();
- CharBuffer ret = buf.put(other);
- assertEquals(other.position(), other.capacity());
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(other, buf);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.CharBuffer put(int, char)
- */
- public void testPutintchar() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), 0);
- CharBuffer ret = buf.put(i, (char) i);
- assertEquals(buf.get(i), (char) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(-1, (char) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(buf.limit(), (char) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testSlice() {
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(buf.capacity() - 1);
-
- CharBuffer slice = buf.slice();
- assertEquals(buf.isReadOnly(), slice.isReadOnly());
- assertEquals(buf.isDirect(), slice.isDirect());
- assertEquals(buf.order(), slice.order());
- assertEquals(slice.position(), 0);
- assertEquals(slice.limit(), buf.remaining());
- assertEquals(slice.capacity(), buf.remaining());
- try {
- slice.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // slice share the same content with buf
- if (!slice.isReadOnly()) {
- loadTestData1(slice);
- assertContentLikeTestData1(buf, 1, (char) 0, slice.capacity());
- buf.put(2, (char) 500);
- assertEquals(slice.get(1), 500);
- }
- }
-
- public void testToString() {
- String expected = "";
- for (int i = buf.position(); i < buf.limit(); i++) {
- expected += buf.get(i);
- }
- String str = buf.toString();
- assertEquals(expected, str);
- }
-
- public void testCharAt() {
- for (int i = 0; i < buf.remaining(); i++) {
- assertEquals(buf.get(buf.position() + i), buf.charAt(i));
- }
- try {
- buf.charAt(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.charAt(buf.remaining());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testLength() {
- assertEquals(buf.length(), buf.remaining());
- }
-
- public void testSubSequence() {
- try {
- buf.subSequence(-1, buf.length());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.subSequence(buf.length() + 1, buf.length() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.subSequence(buf.length(), buf.length()).length(), 0);
- try {
- buf.subSequence(1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.subSequence(1, buf.length() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- assertEquals(buf.subSequence(0, buf.length()).toString(), buf
- .toString());
-
- if (buf.length() >= 2) {
- assertEquals(buf.subSequence(1, buf.length() - 1).toString(), buf
- .toString().substring(1, buf.length() - 1));
- }
- }
-
- public void testPutString() {
- String str = " ";
-
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- str = "" + (char) i;
- CharBuffer ret = buf.put(str);
- assertEquals(buf.get(i), (char) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(str);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.put((String) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testPutStringintint() {
- buf.clear();
- String str = String.valueOf(new char[buf.capacity()]);
-
- // Throw a BufferOverflowException and no character is transfered to
- // CharBuffer
- try {
- buf.put(String.valueOf(new char[buf.capacity() + 1]), 0, buf
- .capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.put((String) null, 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- assertEquals(0, buf.position());
-
- buf.clear();
- try {
- buf.put(str, -1, str.length());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(str, str.length() + 1, str.length() + 2);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put((String) null, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- buf.put(str, str.length(), str.length());
- assertEquals(buf.position(), 0);
- try {
- buf.put(str, 2, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(str, 2, str.length() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
-
- char array[] = new char[buf.capacity()];
- loadTestData2(array, 0, array.length);
- str = String.valueOf(array);
-
- CharBuffer ret = buf.put(str, 0, str.length());
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, str.toCharArray(), 0, str.length());
- assertSame(ret, buf);
- }
-
- void loadTestData1(char array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (char) i;
- }
- }
-
- void loadTestData2(char array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (char) (length - i);
- }
- }
-
- void loadTestData1(CharBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (char) i);
- }
- }
-
- void loadTestData2(CharBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (char) (buf.capacity() - i));
- }
- }
-
- private void assertContentEquals(CharBuffer buf, char array[], int offset,
- int length) {
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(i), array[offset + i]);
- }
- }
-
- private void assertContentEquals(CharBuffer buf, CharBuffer other) {
- assertEquals(buf.capacity(), other.capacity());
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.get(i), other.get(i));
- }
- }
-
- private void assertContentLikeTestData1(CharBuffer buf, int startIndex,
- char startValue, int length) {
- char value = startValue;
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(startIndex + i), value);
- value = (char) (value + 1);
- }
- }
-
- public void testAppendSelf() throws Exception {
- CharBuffer cb = CharBuffer.allocate(10);
- CharBuffer cb2 = cb.duplicate();
- cb.append(cb);
- assertEquals(10, cb.position());
- cb.clear();
- assertEquals(cb2, cb);
-
- cb.put("abc");
- cb2 = cb.duplicate();
- cb.append(cb);
- assertEquals(10, cb.position());
- cb.clear();
- cb2.clear();
- assertEquals(cb2, cb);
-
- cb.put("edfg");
- cb.clear();
- cb2 = cb.duplicate();
- cb.append(cb);
- assertEquals(10, cb.position());
- cb.clear();
- cb2.clear();
- assertEquals(cb, cb2);
- }
-
- public void testAppendOverFlow() throws IOException {
- CharBuffer cb = CharBuffer.allocate(1);
- CharSequence cs = "String";
- cb.put('A');
- try {
- cb.append('C');
- fail("should throw BufferOverflowException.");
- } catch (BufferOverflowException ex) {
- // expected;
- }
- try {
- cb.append(cs);
- fail("should throw BufferOverflowException.");
- } catch (BufferOverflowException ex) {
- // expected;
- }
- try {
- cb.append(cs, 1, 2);
- fail("should throw BufferOverflowException.");
- } catch (BufferOverflowException ex) {
- // expected;
- }
- }
-
- public void testReadOnlyMap() throws IOException {
- CharBuffer cb = CharBuffer.wrap("ABCDE").asReadOnlyBuffer();
- CharSequence cs = "String";
- try {
- cb.append('A');
- fail("should throw ReadOnlyBufferException.");
- } catch (ReadOnlyBufferException ex) {
- // expected;
- }
- try {
- cb.append(cs);
- fail("should throw ReadOnlyBufferException.");
- } catch (ReadOnlyBufferException ex) {
- // expected;
- }
- try {
- cb.append(cs, 1, 2);
- fail("should throw ReadOnlyBufferException.");
- } catch (ReadOnlyBufferException ex) {
- // expected;
- }
- cb.append(cs, 1, 1);
- }
-
- public void testAppendCNormal() throws IOException {
- CharBuffer cb = CharBuffer.allocate(2);
- cb.put('A');
- assertSame(cb, cb.append('B'));
- assertEquals('B', cb.get(1));
- }
-
- public void testAppendCharSequenceNormal() throws IOException {
- CharBuffer cb = CharBuffer.allocate(10);
- cb.put('A');
- assertSame(cb, cb.append("String"));
- assertEquals("AString", cb.flip().toString());
- cb.append(null);
- assertEquals("null", cb.flip().toString());
- }
-
- public void testAppendCharSequenceIINormal() throws IOException {
- CharBuffer cb = CharBuffer.allocate(10);
- cb.put('A');
- assertSame(cb, cb.append("String", 1, 3));
- assertEquals("Atr", cb.flip().toString());
-
- cb.append(null, 0, 1);
- assertEquals("n", cb.flip().toString());
- }
-
- public void testAppendCharSequenceII_IllegalArgument() throws IOException {
- CharBuffer cb = CharBuffer.allocate(10);
- cb.append("String", 0, 0);
- cb.append("String", 2, 2);
- try {
- cb.append("String", -1, 1);
- fail("should throw IndexOutOfBoundsException.");
- } catch (IndexOutOfBoundsException ex) {
- // expected;
- }
- try {
- cb.append("String", -1, -1);
- fail("should throw IndexOutOfBoundsException.");
- } catch (IndexOutOfBoundsException ex) {
- // expected;
- }
- try {
- cb.append("String", 3, 2);
- fail("should throw IndexOutOfBoundsException.");
- } catch (IndexOutOfBoundsException ex) {
- // expected;
- }
- try {
- cb.append("String", 3, 0);
- fail("should throw IndexOutOfBoundsException.");
- } catch (IndexOutOfBoundsException ex) {
- // expected;
- }
- try {
- cb.append("String", 3, 110);
- fail("should throw IndexOutOfBoundsException.");
- } catch (IndexOutOfBoundsException ex) {
- // expected;
- }
- }
-
- public void testReadCharBuffer() throws IOException {
- CharBuffer source = CharBuffer.wrap("String");
- CharBuffer target = CharBuffer.allocate(10);
- assertEquals(6, source.read(target));
- assertEquals("String", target.flip().toString());
- // return -1 when nothing to read
- assertEquals(-1, source.read(target));
- // NullPointerException
- try {
- assertEquals(-1, source.read(null));
- fail("should throw NullPointerException.");
- } catch (NullPointerException ex) {
- // expected;
- }
-
- }
-
- public void testReadReadOnly() throws IOException {
- CharBuffer source = CharBuffer.wrap("String");
- CharBuffer target = CharBuffer.allocate(10).asReadOnlyBuffer();
- try {
- source.read(target);
- fail("should throw ReadOnlyBufferException.");
- } catch (ReadOnlyBufferException ex) {
- // expected;
- }
- // if target has no remaining, needn't to check the isReadOnly
- target.flip();
- assertEquals(0, source.read(target));
- }
-
- public void testReadOverflow() throws IOException {
- CharBuffer source = CharBuffer.wrap("String");
- CharBuffer target = CharBuffer.allocate(1);
- assertEquals(1, source.read(target));
- assertEquals("S", target.flip().toString());
- assertEquals(1, source.position());
- }
-
- public void testReadSelf() throws Exception {
- CharBuffer source = CharBuffer.wrap("abuffer");
- try {
- source.read(source);
- fail("should throw IAE.");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- public void testRead_scenario1() throws Exception {
- char[] charArray = new char[] { 'a', 'b' };
- CharBuffer charBuffer = CharBuffer.wrap(charArray);
- try {
- charBuffer.read(charBuffer);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- charBuffer.put(charArray);
- assertEquals(-1, charBuffer.read(charBuffer));
- }
-
- public void testRead_scenario2() throws Exception {
- CharBuffer charBufferA = CharBuffer.allocate(0);
- CharBuffer allocateBuffer = CharBuffer.allocate(1);
- CharBuffer charBufferB = CharBuffer.wrap(allocateBuffer);
- assertEquals(-1, charBufferA.read(charBufferB));
-
- allocateBuffer.append(allocateBuffer);
- charBufferB = CharBuffer.wrap(allocateBuffer);
- assertEquals(-1, charBufferA.read(charBufferB));
- }
-
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- public void testHasArray() {
- assertTrue(buf.hasArray());
- }
-
- public void testOrder() {
- assertEquals(ByteOrder.nativeOrder(), buf.order());
- }
-
- public void testIsReadOnly() {
- assertFalse(buf.isReadOnly());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectByteBufferTest.java
deleted file mode 100644
index f274676..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectByteBufferTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-
-public class DirectByteBufferTest extends ByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = ByteBuffer.allocateDirect(BUFFER_LENGTH);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- /**
- * @tests java.nio.ByteBuffer#allocateDirect(int)
- *
- */
- public void testAllocatedByteBuffer_IllegalArg() {
- try {
- ByteBuffer.allocateDirect(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void testIsDirect() {
- assertTrue(buf.isDirect());
- }
-
- public void testHasArray() {
- // Android direct byte buffers have backing arrays.
- assertTrue(buf.hasArray());
- // assertFalse(buf.hasArray());
- }
-
- public void testIsReadOnly() {
- assertFalse(buf.isReadOnly());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectCharBufferTest.java
deleted file mode 100644
index 83cfc9d..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectCharBufferTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-public class DirectCharBufferTest extends CharBufferTest {
-
- public void setUp(){
- buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*2).asCharBuffer();
- super.loadTestData1(buf);
- baseBuf = buf;
- }
-
- public void tearDown(){
- buf = null;
- baseBuf = null;
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testIsDirect() {
- assertTrue(buf.isDirect());
- }
-
- public void testOrder() {
- assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectDoubleBufferTest.java
deleted file mode 100644
index 561c0fa..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectDoubleBufferTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-public class DirectDoubleBufferTest extends DoubleBufferTest {
- public void setUp(){
- buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*8).asDoubleBuffer();
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- public void tearDown(){
- buf = null;
- baseBuf = null;
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testIsDirect() {
- assertTrue(buf.isDirect());
- }
-
- public void testOrder() {
- assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectFloatBufferTest.java
deleted file mode 100644
index 8739c1b..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectFloatBufferTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-public class DirectFloatBufferTest extends FloatBufferTest {
- public void setUp(){
- buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*4).asFloatBuffer();
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- public void tearDown(){
- buf = null;
- baseBuf = null;
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void testIsDirect() {
- assertTrue(buf.isDirect());
- }
-
- public void testOrder() {
- assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectIntBufferTest.java
deleted file mode 100644
index 393366e..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectIntBufferTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-public class DirectIntBufferTest extends IntBufferTest {
- public void setUp(){
- buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*4).asIntBuffer();
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- public void tearDown(){
- buf = null;
- baseBuf = null;
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void testIsDirect() {
- assertTrue(buf.isDirect());
- }
-
- public void testOrder() {
- assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectLongBufferTest.java
deleted file mode 100644
index 245cd25..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectLongBufferTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-
-public class DirectLongBufferTest extends LongBufferTest {
- public void setUp(){
- buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*8).asLongBuffer();
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- public void tearDown(){
- buf = null;
- baseBuf = null;
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void testIsDirect() {
- assertTrue(buf.isDirect());
- }
-
- public void testOrder() {
- assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectShortBufferTest.java
deleted file mode 100644
index 9ae290a..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectShortBufferTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-public class DirectShortBufferTest extends ShortBufferTest {
- public void setUp(){
- buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*2).asShortBuffer();
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- public void tearDown(){
- buf = null;
- baseBuf = null;
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void testIsDirect() {
- assertTrue(buf.isDirect());
- }
-
- public void testOrder() {
- assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java
deleted file mode 100644
index 40ff2e0..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.DoubleBuffer;
-import java.nio.InvalidMarkException;
-
-/**
- * Tests java.nio.DoubleBuffer
- */
-public class DoubleBufferTest extends AbstractBufferTest {
-
- protected static final int SMALL_TEST_LENGTH = 5;
-
- protected static final int BUFFER_LENGTH = 20;
-
- protected DoubleBuffer buf;
-
- protected void setUp() throws Exception {
- buf = DoubleBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- buf = null;
- baseBuf = null;
- }
-
- /*
- * Test with bit sequences that represent the IEEE754 doubles Positive
- * infinity, negative infinity, and NaN.
- */
- public void testNaNs() {
- long[] nans = new long[] { 0x7ff0000000000000L, 0xfff0000000000000L,
- 0x7ff8000000000000L };
- for (int i = 0; i < nans.length; i++) {
- long longBitsIn = nans[i];
- double dbl = Double.longBitsToDouble(longBitsIn);
- long longBitsOut = Double.doubleToRawLongBits(dbl);
- // Sanity check
- assertTrue(longBitsIn == longBitsOut);
-
- // Store the double and retrieve it
- ByteBuffer buffer = ByteBuffer.allocate(8);
- buffer.putDouble(dbl);
- double bufDoubleOut = buffer.getDouble(0);
-
- // Check the bits sequence was not normalized
- long bufLongOut = Double.doubleToRawLongBits(bufDoubleOut);
- assertTrue(longBitsIn == bufLongOut);
- }
- }
-
- public void testArray() {
- double array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testArrayOffset() {
- double array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testAsReadOnlyBuffer() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // readonly's contents should be the same as buf
- DoubleBuffer readonly = buf.asReadOnlyBuffer();
- assertNotSame(buf, readonly);
- assertTrue(readonly.isReadOnly());
- assertEquals(buf.position(), readonly.position());
- assertEquals(buf.limit(), readonly.limit());
- assertEquals(buf.isDirect(), readonly.isDirect());
- assertEquals(buf.order(), readonly.order());
- assertContentEquals(buf, readonly);
-
- // readonly's position, mark, and limit should be independent to buf
- readonly.reset();
- assertEquals(readonly.position(), 0);
- readonly.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
- }
-
- public void testCompact() {
- // case: buffer is full
- buf.clear();
- buf.mark();
- loadTestData1(buf);
- DoubleBuffer ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), buf.capacity());
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 0.0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: buffer is empty
- buf.position(0);
- buf.limit(0);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 0);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 0.0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: normal
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(5);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 4);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 1.0, 4);
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- public void testCompareTo() {
- DoubleBuffer other = DoubleBuffer.allocate(buf.capacity());
- loadTestData1(other);
- assertEquals(0, buf.compareTo(other));
- assertEquals(0, other.compareTo(buf));
- buf.position(1);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- other.position(2);
- assertTrue(buf.compareTo(other) < 0);
- assertTrue(other.compareTo(buf) > 0);
- buf.position(2);
- other.limit(5);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
-
- DoubleBuffer dbuffer1 = DoubleBuffer.wrap(new double[] { Double.NaN });
- DoubleBuffer dbuffer2 = DoubleBuffer.wrap(new double[] { Double.NaN });
- DoubleBuffer dbuffer3 = DoubleBuffer.wrap(new double[] { 42d });
-
- assertEquals("Failed equal comparison with NaN entry", 0, dbuffer1
- .compareTo(dbuffer2));
- assertEquals("Failed greater than comparison with NaN entry", 1, dbuffer3
- .compareTo(dbuffer1));
- assertEquals("Failed greater than comparison with NaN entry", 1, dbuffer1
- .compareTo(dbuffer3));
- }
-
- public void testDuplicate() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // duplicate's contents should be the same as buf
- DoubleBuffer duplicate = buf.duplicate();
- assertNotSame(buf, duplicate);
- assertEquals(buf.position(), duplicate.position());
- assertEquals(buf.limit(), duplicate.limit());
- assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
- assertEquals(buf.isDirect(), duplicate.isDirect());
- assertEquals(buf.order(), duplicate.order());
- assertContentEquals(buf, duplicate);
-
- // duplicate's position, mark, and limit should be independent to buf
- duplicate.reset();
- assertEquals(duplicate.position(), 0);
- duplicate.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
-
- // duplicate share the same content with buf
- // FIXME
- if (!duplicate.isReadOnly()) {
- loadTestData1(buf);
- assertContentEquals(buf, duplicate);
- loadTestData2(duplicate);
- assertContentEquals(buf, duplicate);
- }
- }
-
- public void testEquals() {
- // equal to self
- assertTrue(buf.equals(buf));
- DoubleBuffer readonly = buf.asReadOnlyBuffer();
- assertTrue(buf.equals(readonly));
- DoubleBuffer duplicate = buf.duplicate();
- assertTrue(buf.equals(duplicate));
-
- // always false, if type mismatch
- assertFalse(buf.equals(Boolean.TRUE));
-
- assertTrue(buf.capacity() > 5);
-
- buf.limit(buf.capacity()).position(0);
- readonly.limit(readonly.capacity()).position(1);
- assertFalse(buf.equals(readonly));
-
- buf.limit(buf.capacity() - 1).position(0);
- duplicate.limit(duplicate.capacity()).position(0);
- assertFalse(buf.equals(duplicate));
- }
-
- /*
- * Class under test for double get()
- */
- public void testGet() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i), 0.01);
- }
- try {
- buf.get();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.DoubleBuffer get(double[])
- */
- public void testGetdoubleArray() {
- double array[] = new double[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- DoubleBuffer ret = buf.get(array);
- assertEquals(array[0], buf.get(i), 0.01);
- assertSame(ret, buf);
- }
- try {
- buf.get(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.DoubleBuffer get(double[], int, int)
- */
- public void testGetdoubleArrayintint() {
- buf.clear();
- double array[] = new double[buf.capacity()];
-
- try {
- buf.get(new double[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.get(array, array.length, 0);
- try {
- buf.get(array, array.length + 1, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get((double[])null, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.get(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- buf.get(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
-
- buf.clear();
- DoubleBuffer ret = buf.get(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for double get(int)
- */
- public void testGetint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i), 0.01);
- }
- try {
- buf.get(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(buf.limit());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testHasArray() {
- assertTrue(buf.hasArray());
- }
-
- public void testHashCode() {
- buf.clear();
- DoubleBuffer readonly = buf.asReadOnlyBuffer();
- DoubleBuffer duplicate = buf.duplicate();
- assertTrue(buf.hashCode() == readonly.hashCode());
-
- assertTrue(buf.capacity() > 5);
- duplicate.position(buf.capacity() / 2);
- assertTrue(buf.hashCode() != duplicate.hashCode());
- }
-
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- public void testOrder() {
- assertEquals(ByteOrder.nativeOrder(), buf.order());
- }
-
- /*
- * Class under test for java.nio.DoubleBuffer put(double)
- */
- public void testPutdouble() {
-
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- DoubleBuffer ret = buf.put((double) i);
- assertEquals(buf.get(i), (double) i, 0.0);
- assertSame(ret, buf);
- }
- try {
- buf.put(0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.DoubleBuffer put(double[])
- */
- public void testPutdoubleArray() {
- double array[] = new double[1];
-
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- array[0] = (double) i;
- DoubleBuffer ret = buf.put(array);
- assertEquals(buf.get(i), (double) i, 0.0);
- assertSame(ret, buf);
- }
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.DoubleBuffer put(double[], int, int)
- */
- public void testPutdoubleArrayintint() {
- buf.clear();
- double array[] = new double[buf.capacity()];
-
- try {
- buf.put(new double[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, array.length + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.put(array, array.length, 0);
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put((double[])null, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.put(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- assertEquals(buf.position(), 0);
-
- loadTestData2(array, 0, array.length);
- DoubleBuffer ret = buf.put(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.DoubleBuffer put(java.nio.DoubleBuffer)
- */
- public void testPutDoubleBuffer() {
- DoubleBuffer other = DoubleBuffer.allocate(buf.capacity());
-
- try {
- buf.put(buf);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- buf.put(DoubleBuffer.allocate(buf.capacity() + 1));
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
-
- loadTestData2(other);
- other.clear();
- buf.clear();
- DoubleBuffer ret = buf.put(other);
- assertEquals(other.position(), other.capacity());
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(other, buf);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.DoubleBuffer put(int, double)
- */
- public void testPutintdouble() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), 0);
- DoubleBuffer ret = buf.put(i, (double) i);
- assertEquals(buf.get(i), (double) i, 0.0);
- assertSame(ret, buf);
- }
- try {
- buf.put(-1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(buf.limit(), 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testSlice() {
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(buf.capacity() - 1);
-
- DoubleBuffer slice = buf.slice();
- assertEquals(buf.isReadOnly(), slice.isReadOnly());
- assertEquals(buf.isDirect(), slice.isDirect());
- assertEquals(buf.order(), slice.order());
- assertEquals(slice.position(), 0);
- assertEquals(slice.limit(), buf.remaining());
- assertEquals(slice.capacity(), buf.remaining());
- try {
- slice.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // slice share the same content with buf
- // FIXME:
- if (!slice.isReadOnly()) {
- loadTestData1(slice);
- assertContentLikeTestData1(buf, 1, 0, slice.capacity());
- buf.put(2, 500);
- assertEquals(slice.get(1), 500, 0.0);
- }
- }
-
- public void testToString() {
- String str = buf.toString();
- assertTrue(str.indexOf("Double") >= 0 || str.indexOf("double") >= 0);
- assertTrue(str.indexOf("" + buf.position()) >= 0);
- assertTrue(str.indexOf("" + buf.limit()) >= 0);
- assertTrue(str.indexOf("" + buf.capacity()) >= 0);
- }
-
- void loadTestData1(double array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (double) i;
- }
- }
-
- void loadTestData2(double array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (double) length - i;
- }
- }
-
- void loadTestData1(DoubleBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (double) i);
- }
- }
-
- void loadTestData2(DoubleBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (double) buf.capacity() - i);
- }
- }
-
- private void assertContentEquals(DoubleBuffer buf, double array[],
- int offset, int length) {
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(i), array[offset + i], 0.01);
- }
- }
-
- private void assertContentEquals(DoubleBuffer buf, DoubleBuffer other) {
- assertEquals(buf.capacity(), other.capacity());
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.get(i), other.get(i), 0.01);
- }
- }
-
- private void assertContentLikeTestData1(DoubleBuffer buf, int startIndex,
- double startValue, int length) {
- double value = startValue;
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(startIndex + i), value, 0.01);
- value = value + 1.0;
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateDirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateDirectByteBufferTest.java
deleted file mode 100644
index 656241a..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateDirectByteBufferTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class DuplicateDirectByteBufferTest extends DirectByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.duplicate();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateHeapByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateHeapByteBufferTest.java
deleted file mode 100644
index 9f44d7a..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateHeapByteBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class DuplicateHeapByteBufferTest extends HeapByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.duplicate();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateWrappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateWrappedByteBufferTest.java
deleted file mode 100644
index 2796b88..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/DuplicateWrappedByteBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class DuplicateWrappedByteBufferTest extends WrappedByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.duplicate();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java
deleted file mode 100644
index cfef096..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteOrder;
-import java.nio.DoubleBuffer;
-import java.nio.FloatBuffer;
-import java.nio.InvalidMarkException;
-
-/**
- * Tests java.nio.FloatBuffer
- *
- */
-public class FloatBufferTest extends AbstractBufferTest {
-
- protected static final int SMALL_TEST_LENGTH = 5;
-
- protected static final int BUFFER_LENGTH = 20;
-
- protected FloatBuffer buf;
-
- protected void setUp() throws Exception {
- buf = FloatBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- buf = null;
- baseBuf = null;
- }
-
- public void testArray() {
- float array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testArrayOffset() {
- float array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testAsReadOnlyBuffer() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // readonly's contents should be the same as buf
- FloatBuffer readonly = buf.asReadOnlyBuffer();
- assertNotSame(buf, readonly);
- assertTrue(readonly.isReadOnly());
- assertEquals(buf.position(), readonly.position());
- assertEquals(buf.limit(), readonly.limit());
- assertEquals(buf.isDirect(), readonly.isDirect());
- assertEquals(buf.order(), readonly.order());
- assertContentEquals(buf, readonly);
-
- // readonly's position, mark, and limit should be independent to buf
- readonly.reset();
- assertEquals(readonly.position(), 0);
- readonly.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
- }
-
- public void testCompact() {
-
- // case: buffer is full
- buf.clear();
- buf.mark();
- loadTestData1(buf);
- FloatBuffer ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), buf.capacity());
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 0.0f, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: buffer is empty
- buf.position(0);
- buf.limit(0);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 0);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 0.0f, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: normal
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(5);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 4);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 1.0f, 4);
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- public void testCompareTo() {
- try {
- buf.compareTo(null);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // expected
- }
-
- // compare to self
- assertEquals(0, buf.compareTo(buf));
-
- // normal cases
- assertTrue(buf.capacity() > 5);
- buf.clear();
- FloatBuffer other = FloatBuffer.allocate(buf.capacity());
- loadTestData1(other);
- assertEquals(0, buf.compareTo(other));
- assertEquals(0, other.compareTo(buf));
- buf.position(1);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- other.position(2);
- assertTrue(buf.compareTo(other) < 0);
- assertTrue(other.compareTo(buf) > 0);
- buf.position(2);
- other.limit(5);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
-
- FloatBuffer fbuffer1 = FloatBuffer.wrap(new float[] { Float.NaN });
- FloatBuffer fbuffer2 = FloatBuffer.wrap(new float[] { Float.NaN });
- FloatBuffer fbuffer3 = FloatBuffer.wrap(new float[] { 42f });
-
- assertEquals("Failed equal comparison with NaN entry", 0, fbuffer1
- .compareTo(fbuffer2));
- assertEquals("Failed greater than comparison with NaN entry", 1, fbuffer3
- .compareTo(fbuffer1));
- assertEquals("Failed greater than comparison with NaN entry", 1, fbuffer1
- .compareTo(fbuffer3));
-
- }
-
- public void testDuplicate() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // duplicate's contents should be the same as buf
- FloatBuffer duplicate = buf.duplicate();
- assertNotSame(buf, duplicate);
- assertEquals(buf.position(), duplicate.position());
- assertEquals(buf.limit(), duplicate.limit());
- assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
- assertEquals(buf.isDirect(), duplicate.isDirect());
- assertEquals(buf.order(), duplicate.order());
- assertContentEquals(buf, duplicate);
-
- // duplicate's position, mark, and limit should be independent to buf
- duplicate.reset();
- assertEquals(duplicate.position(), 0);
- duplicate.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
-
- // duplicate share the same content with buf
- if (!duplicate.isReadOnly()) {
- loadTestData1(buf);
- assertContentEquals(buf, duplicate);
- loadTestData2(duplicate);
- assertContentEquals(buf, duplicate);
- }
- }
-
- public void testEquals() {
- // equal to self
- assertTrue(buf.equals(buf));
- FloatBuffer readonly = buf.asReadOnlyBuffer();
- assertTrue(buf.equals(readonly));
- FloatBuffer duplicate = buf.duplicate();
- assertTrue(buf.equals(duplicate));
-
- // always false, if type mismatch
- assertFalse(buf.equals(Boolean.TRUE));
-
- assertTrue(buf.capacity() > 5);
-
- buf.limit(buf.capacity()).position(0);
- readonly.limit(readonly.capacity()).position(1);
- assertFalse(buf.equals(readonly));
-
- buf.limit(buf.capacity() - 1).position(0);
- duplicate.limit(duplicate.capacity()).position(0);
- assertFalse(buf.equals(duplicate));
- }
-
- /*
- * Class under test for float get()
- */
- public void testGet() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i), 0.01);
- }
- try {
- buf.get();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.FloatBuffer get(float[])
- */
- public void testGetfloatArray() {
- float array[] = new float[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- FloatBuffer ret = buf.get(array);
- assertEquals(array[0], buf.get(i), 0.01);
- assertSame(ret, buf);
- }
- try {
- buf.get(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- try {
- buf.position(buf.limit());
- buf.get((float[])null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- buf.get(new float[0]);
- }
-
- /*
- * Class under test for java.nio.FloatBuffer get(float[], int, int)
- */
- public void testGetfloatArrayintint() {
- buf.clear();
- float array[] = new float[buf.capacity()];
-
- try {
- buf.get(new float[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.get(array, array.length, 0);
- try {
- buf.get(array, array.length + 1, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get((float[])null, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.get(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- buf.get(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
-
- buf.clear();
- FloatBuffer ret = buf.get(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for float get(int)
- */
- public void testGetint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i), 0.01);
- }
- try {
- buf.get(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(buf.limit());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testHasArray() {
- assertNotNull(buf.array());
- }
-
- public void testHashCode() {
- buf.clear();
- FloatBuffer readonly = buf.asReadOnlyBuffer();
- FloatBuffer duplicate = buf.duplicate();
- assertTrue(buf.hashCode() == readonly.hashCode());
-
- assertTrue(buf.capacity() > 5);
- duplicate.position(buf.capacity() / 2);
- assertTrue(buf.hashCode() != duplicate.hashCode());
- }
-
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- public void testOrder() {
- buf.order();
- if (buf.hasArray()) {
- assertEquals(ByteOrder.nativeOrder(), buf.order());
- }
- }
-
- /*
- * Class under test for java.nio.FloatBuffer put(float)
- */
- public void testPutfloat() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- FloatBuffer ret = buf.put((float) i);
- assertEquals(buf.get(i), (float) i, 0.0);
- assertSame(ret, buf);
- }
- try {
- buf.put(0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.FloatBuffer put(float[])
- */
- public void testPutfloatArray() {
- float array[] = new float[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- array[0] = (float) i;
- FloatBuffer ret = buf.put(array);
- assertEquals(buf.get(i), (float) i, 0.0);
- assertSame(ret, buf);
- }
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.position(buf.limit());
- buf.put((float[])null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.FloatBuffer put(float[], int, int)
- */
- public void testPutfloatArrayintint() {
- buf.clear();
- float array[] = new float[buf.capacity()];
- try {
- buf.put(new float[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, array.length + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.put(array, array.length, 0);
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put((float[])null, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.put(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- assertEquals(buf.position(), 0);
-
- loadTestData2(array, 0, array.length);
- FloatBuffer ret = buf.put(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.FloatBuffer put(java.nio.FloatBuffer)
- */
- public void testPutFloatBuffer() {
- FloatBuffer other = FloatBuffer.allocate(buf.capacity());
- try {
- buf.put(buf);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- buf.put(FloatBuffer.allocate(buf.capacity() + 1));
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.flip();
- buf.put((FloatBuffer)null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- buf.clear();
- loadTestData2(other);
- other.clear();
- buf.clear();
- FloatBuffer ret = buf.put(other);
- assertEquals(other.position(), other.capacity());
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(other, buf);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.FloatBuffer put(int, float)
- */
- public void testPutintfloat() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), 0);
- FloatBuffer ret = buf.put(i, (float) i);
- assertEquals(buf.get(i), (float) i, 0.0);
- assertSame(ret, buf);
- }
- try {
- buf.put(-1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(buf.limit(), 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testSlice() {
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(buf.capacity() - 1);
-
- FloatBuffer slice = buf.slice();
- assertEquals(buf.isReadOnly(), slice.isReadOnly());
- assertEquals(buf.isDirect(), slice.isDirect());
- assertEquals(buf.order(), slice.order());
- assertEquals(slice.position(), 0);
- assertEquals(slice.limit(), buf.remaining());
- assertEquals(slice.capacity(), buf.remaining());
- try {
- slice.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // slice share the same content with buf
- if (!slice.isReadOnly()) {
- loadTestData1(slice);
- assertContentLikeTestData1(buf, 1, 0, slice.capacity());
- buf.put(2, 500);
- assertEquals(slice.get(1), 500, 0.0);
- }
- }
-
- public void testToString() {
- String str = buf.toString();
- assertTrue(str.indexOf("Float") >= 0 || str.indexOf("float") >= 0);
- assertTrue(str.indexOf("" + buf.position()) >= 0);
- assertTrue(str.indexOf("" + buf.limit()) >= 0);
- assertTrue(str.indexOf("" + buf.capacity()) >= 0);
- }
-
- void loadTestData1(float array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (float) i;
- }
- }
-
- void loadTestData2(float array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (float) length - i;
- }
- }
-
- void loadTestData1(FloatBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (float) i);
- }
- }
-
- void loadTestData2(FloatBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (float) buf.capacity() - i);
- }
- }
-
- void assertContentEquals(FloatBuffer buf, float array[],
- int offset, int length) {
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(i), array[offset + i], 0.01);
- }
- }
-
- void assertContentEquals(FloatBuffer buf, FloatBuffer other) {
- assertEquals(buf.capacity(), other.capacity());
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.get(i), other.get(i), 0.01);
- }
- }
-
- void assertContentLikeTestData1(FloatBuffer buf,
- int startIndex, float startValue, int length) {
- float value = startValue;
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(startIndex + i), value, 0.01);
- value = value + 1.0f;
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapByteBufferTest.java
deleted file mode 100644
index 2f8e44b..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapByteBufferTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-
-
-public class HeapByteBufferTest extends ByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = ByteBuffer.allocate(BUFFER_LENGTH);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- /**
- * @tests java.nio.ByteBuffer#allocate(int)
- *
- */
- public void testAllocatedByteBuffer_IllegalArg() {
- try {
- ByteBuffer.allocate(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- public void testHasArray() {
- assertTrue(buf.hasArray());
- }
-
- public void testIsReadOnly() {
- assertFalse(buf.isReadOnly());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapCharBufferTest.java
deleted file mode 100644
index a0c8d74..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapCharBufferTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.CharBuffer;
-
-
-public class HeapCharBufferTest extends CharBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = CharBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- public void testAllocatedCharBuffer_IllegalArg() {
- try {
- CharBuffer.allocate(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapDoubleBufferTest.java
deleted file mode 100644
index 2985899..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapDoubleBufferTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.DoubleBuffer;
-
-public class HeapDoubleBufferTest extends DoubleBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = DoubleBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- public void testAllocatedDoubleBuffer_IllegalArg() {
- try {
- DoubleBuffer.allocate(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapFloatBufferTest.java
deleted file mode 100644
index f90b34e..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapFloatBufferTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.FloatBuffer;
-
-public class HeapFloatBufferTest extends FloatBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = FloatBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- public void testAllocatedFloatBuffer_IllegalArg() {
- try {
- FloatBuffer.allocate(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapIntBufferTest.java
deleted file mode 100644
index 0d68835..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapIntBufferTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.IntBuffer;
-
-public class HeapIntBufferTest extends IntBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = IntBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- public void testAllocatedIntBuffer_IllegalArg() {
- try {
- IntBuffer.allocate(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapLongBufferTest.java
deleted file mode 100644
index f4f2ae1..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapLongBufferTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.LongBuffer;
-
-public class HeapLongBufferTest extends LongBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = LongBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- public void testAllocatedLongBuffer_IllegalArg() {
- try {
- LongBuffer.allocate(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapShortBufferTest.java
deleted file mode 100644
index 327a035..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapShortBufferTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ShortBuffer;
-
-public class HeapShortBufferTest extends ShortBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = ShortBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- public void testAllocatedShortBuffer_IllegalArg() {
- try {
- ShortBuffer.allocate(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/IntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/IntBufferTest.java
deleted file mode 100644
index 97babcf..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/IntBufferTest.java
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteOrder;
-import java.nio.IntBuffer;
-import java.nio.InvalidMarkException;
-
-/**
- * Tests java.nio.IntBuffer
- *
- */
-public class IntBufferTest extends AbstractBufferTest {
-
-
- protected static final int SMALL_TEST_LENGTH = 5;
-
- protected static final int BUFFER_LENGTH = 20;
-
- protected IntBuffer buf;
-
- protected void setUp() throws Exception {
- buf = IntBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- buf = null;
- baseBuf = null;
- }
-
- public void testArray() {
- int array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testArrayOffset() {
- int array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testAsReadOnlyBuffer() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // readonly's contents should be the same as buf
- IntBuffer readonly = buf.asReadOnlyBuffer();
- assertNotSame(buf, readonly);
- assertTrue(readonly.isReadOnly());
- assertEquals(buf.position(), readonly.position());
- assertEquals(buf.limit(), readonly.limit());
- assertEquals(buf.isDirect(), readonly.isDirect());
- assertEquals(buf.order(), readonly.order());
- assertContentEquals(buf, readonly);
-
- // readonly's position, mark, and limit should be independent to buf
- readonly.reset();
- assertEquals(readonly.position(), 0);
- readonly.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
- }
-
- public void testCompact() {
- // case: buffer is full
- buf.clear();
- buf.mark();
- loadTestData1(buf);
- IntBuffer ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), buf.capacity());
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: buffer is empty
- buf.position(0);
- buf.limit(0);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 0);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: normal
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(5);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 4);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 1, 4);
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- public void testCompareTo() {
- // compare to self
- assertEquals(0, buf.compareTo(buf));
-
- // normal cases
- assertTrue(buf.capacity() > 5);
- buf.clear();
- IntBuffer other = IntBuffer.allocate(buf.capacity());
- loadTestData1(other);
- assertEquals(0, buf.compareTo(other));
- assertEquals(0, other.compareTo(buf));
- buf.position(1);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- other.position(2);
- assertTrue(buf.compareTo(other) < 0);
- assertTrue(other.compareTo(buf) > 0);
- buf.position(2);
- other.limit(5);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- }
-
- public void testDuplicate() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // duplicate's contents should be the same as buf
- IntBuffer duplicate = buf.duplicate();
- assertNotSame(buf, duplicate);
- assertEquals(buf.position(), duplicate.position());
- assertEquals(buf.limit(), duplicate.limit());
- assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
- assertEquals(buf.isDirect(), duplicate.isDirect());
- assertEquals(buf.order(), duplicate.order());
- assertContentEquals(buf, duplicate);
-
- // duplicate's position, mark, and limit should be independent to buf
- duplicate.reset();
- assertEquals(duplicate.position(), 0);
- duplicate.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
-
- // duplicate share the same content with buf
- if (!duplicate.isReadOnly()) {
- loadTestData1(buf);
- assertContentEquals(buf, duplicate);
- loadTestData2(duplicate);
- assertContentEquals(buf, duplicate);
- }
- }
-
- public void testEquals() {
- // equal to self
- assertTrue(buf.equals(buf));
- IntBuffer readonly = buf.asReadOnlyBuffer();
- assertTrue(buf.equals(readonly));
- IntBuffer duplicate = buf.duplicate();
- assertTrue(buf.equals(duplicate));
-
- // always false, if type mismatch
- assertFalse(buf.equals(Boolean.TRUE));
-
- assertTrue(buf.capacity() > 5);
-
- buf.limit(buf.capacity()).position(0);
- readonly.limit(readonly.capacity()).position(1);
- assertFalse(buf.equals(readonly));
-
- buf.limit(buf.capacity() - 1).position(0);
- duplicate.limit(duplicate.capacity()).position(0);
- assertFalse(buf.equals(duplicate));
- }
-
- /*
- * Class under test for int get()
- */
- public void testGet() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.IntBuffer get(int[])
- */
- public void testGetintArray() {
- int array[] = new int[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- IntBuffer ret = buf.get(array);
- assertEquals(array[0], buf.get(i));
- assertSame(ret, buf);
- }
- try {
- buf.get(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- try {
- buf.get((int[])null);
- fail("Should throw NPE"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.IntBuffer get(int[], int, int)
- */
- public void testGetintArrayintint() {
- buf.clear();
- int array[] = new int[buf.capacity()];
-
- try {
- buf.get(new int[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.get(array, array.length, 0);
- try {
- buf.get(array, array.length + 1, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get((int[])null, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.get(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- buf.get(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
-
- buf.clear();
- IntBuffer ret = buf.get(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for int get(int)
- */
- public void testGetint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(buf.limit());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testHasArray() {
- assertNotNull(buf.array());
- }
-
- public void testHashCode() {
- buf.clear();
- IntBuffer readonly = buf.asReadOnlyBuffer();
- IntBuffer duplicate = buf.duplicate();
- assertTrue(buf.hashCode() == readonly.hashCode());
-
- assertTrue(buf.capacity() > 5);
- duplicate.position(buf.capacity() / 2);
- assertTrue(buf.hashCode() != duplicate.hashCode());
- }
-
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- public void testOrder() {
- buf.order();
- assertEquals(ByteOrder.nativeOrder(), buf.order());
- }
-
- /*
- * Class under test for java.nio.IntBuffer put(int)
- */
- public void testPutint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- IntBuffer ret = buf.put((int) i);
- assertEquals(buf.get(i), (int) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.IntBuffer put(int[])
- */
- public void testPutintArray() {
- int array[] = new int[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- array[0] = (int) i;
- IntBuffer ret = buf.put(array);
- assertEquals(buf.get(i), (int) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.position(buf.limit());
- buf.put((int[])null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.IntBuffer put(int[], int, int)
- */
- public void testPutintArrayintint() {
- buf.clear();
- int array[] = new int[buf.capacity()];
- try {
- buf.put(new int[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, array.length + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.put(array, array.length, 0);
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put((int[])null, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.put(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- assertEquals(buf.position(), 0);
-
- loadTestData2(array, 0, array.length);
- IntBuffer ret = buf.put(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.IntBuffer put(java.nio.IntBuffer)
- */
- public void testPutIntBuffer() {
- IntBuffer other = IntBuffer.allocate(buf.capacity());
- try {
- buf.put(buf);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- buf.put(IntBuffer.allocate(buf.capacity() + 1));
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.flip();
- buf.put((IntBuffer)null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
-
- loadTestData2(other);
- other.clear();
- buf.clear();
- IntBuffer ret = buf.put(other);
- assertEquals(other.position(), other.capacity());
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(other, buf);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.IntBuffer put(int, int)
- */
- public void testPutintint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), 0);
- IntBuffer ret = buf.put(i, (int) i);
- assertEquals(buf.get(i), (int) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(-1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(buf.limit(), 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testSlice() {
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(buf.capacity() - 1);
-
- IntBuffer slice = buf.slice();
- assertEquals(buf.isReadOnly(), slice.isReadOnly());
- assertEquals(buf.isDirect(), slice.isDirect());
- assertEquals(buf.order(), slice.order());
- assertEquals(slice.position(), 0);
- assertEquals(slice.limit(), buf.remaining());
- assertEquals(slice.capacity(), buf.remaining());
- try {
- slice.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // slice share the same content with buf
- if (!slice.isReadOnly()) {
- loadTestData1(slice);
- assertContentLikeTestData1(buf, 1, 0, slice.capacity());
- buf.put(2, 500);
- assertEquals(slice.get(1), 500);
- }
- }
-
- public void testToString() {
- String str = buf.toString();
- assertTrue(str.indexOf("Int") >= 0 || str.indexOf("int") >= 0);
- assertTrue(str.indexOf("" + buf.position()) >= 0);
- assertTrue(str.indexOf("" + buf.limit()) >= 0);
- assertTrue(str.indexOf("" + buf.capacity()) >= 0);
- }
-
- void loadTestData1(int array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (int) i;
- }
- }
-
- void loadTestData2(int array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (int) length - i;
- }
- }
-
- void loadTestData1(IntBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (int) i);
- }
- }
-
- void loadTestData2(IntBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (int) buf.capacity() - i);
- }
- }
-
- void assertContentEquals(IntBuffer buf, int array[],
- int offset, int length) {
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(i), array[offset + i]);
- }
- }
-
- void assertContentEquals(IntBuffer buf, IntBuffer other) {
- assertEquals(buf.capacity(), other.capacity());
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.get(i), other.get(i));
- }
- }
-
- void assertContentLikeTestData1(IntBuffer buf,
- int startIndex, int startValue, int length) {
- int value = startValue;
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(startIndex + i), value);
- value = value + 1;
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.java
deleted file mode 100644
index 4b7682d..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.InvalidMarkException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-public class InvalidMarkExceptionTest extends TestCase {
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new InvalidMarkException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new InvalidMarkException());
- }
-
- /**
- *@tests {@link java.nio.InvalidMarkException#InvalidMarkException()}
- */
- public void test_Constructor() {
- InvalidMarkException exception = new InvalidMarkException();
- assertNull(exception.getMessage());
- assertNull(exception.getLocalizedMessage());
- assertNull(exception.getCause());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/LongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/LongBufferTest.java
deleted file mode 100644
index 371351b..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/LongBufferTest.java
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteOrder;
-import java.nio.InvalidMarkException;
-import java.nio.LongBuffer;
-
-/**
- * Tests java.nio.LongBuffer
- *
- */
-public class LongBufferTest extends AbstractBufferTest {
-
-
- protected static final int SMALL_TEST_LENGTH = 5;
-
- protected static final int BUFFER_LENGTH = 20;
-
- protected LongBuffer buf;
-
- protected void setUp() throws Exception {
- buf = LongBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- buf = null;
- baseBuf = null;
- }
-
- public void testArray() {
- long array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testArrayOffset() {
- long array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testAsReadOnlyBuffer() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // readonly's contents should be the same as buf
- LongBuffer readonly = buf.asReadOnlyBuffer();
- assertNotSame(buf, readonly);
- assertTrue(readonly.isReadOnly());
- assertEquals(buf.position(), readonly.position());
- assertEquals(buf.limit(), readonly.limit());
- assertEquals(buf.isDirect(), readonly.isDirect());
- assertEquals(buf.order(), readonly.order());
- assertContentEquals(buf, readonly);
-
- // readonly's position, mark, and limit should be independent to buf
- readonly.reset();
- assertEquals(readonly.position(), 0);
- readonly.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
- }
-
- public void testCompact() {
- // case: buffer is full
- buf.clear();
- buf.mark();
- loadTestData1(buf);
- LongBuffer ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), buf.capacity());
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: buffer is empty
- buf.position(0);
- buf.limit(0);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 0);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: normal
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(5);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 4);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, 1, 4);
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- public void testCompareTo() {
- // compare to self
- assertEquals(0, buf.compareTo(buf));
-
- // normal cases
- assertTrue(buf.capacity() > 5);
- buf.clear();
- LongBuffer other = LongBuffer.allocate(buf.capacity());
- loadTestData1(other);
- assertEquals(0, buf.compareTo(other));
- assertEquals(0, other.compareTo(buf));
- buf.position(1);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- other.position(2);
- assertTrue(buf.compareTo(other) < 0);
- assertTrue(other.compareTo(buf) > 0);
- buf.position(2);
- other.limit(5);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- }
-
- public void testDuplicate() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // duplicate's contents should be the same as buf
- LongBuffer duplicate = buf.duplicate();
- assertNotSame(buf, duplicate);
- assertEquals(buf.position(), duplicate.position());
- assertEquals(buf.limit(), duplicate.limit());
- assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
- assertEquals(buf.isDirect(), duplicate.isDirect());
- assertEquals(buf.order(), duplicate.order());
- assertContentEquals(buf, duplicate);
-
- // duplicate's position, mark, and limit should be independent to buf
- duplicate.reset();
- assertEquals(duplicate.position(), 0);
- duplicate.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
-
- // duplicate share the same content with buf
- if (!duplicate.isReadOnly()) {
- loadTestData1(buf);
- assertContentEquals(buf, duplicate);
- loadTestData2(duplicate);
- assertContentEquals(buf, duplicate);
- }
- }
-
- public void testEquals() {
- // equal to self
- assertTrue(buf.equals(buf));
- LongBuffer readonly = buf.asReadOnlyBuffer();
- assertTrue(buf.equals(readonly));
- LongBuffer duplicate = buf.duplicate();
- assertTrue(buf.equals(duplicate));
-
- // always false, if type mismatch
- assertFalse(buf.equals(Boolean.TRUE));
-
- assertTrue(buf.capacity() > 5);
-
- buf.limit(buf.capacity()).position(0);
- readonly.limit(readonly.capacity()).position(1);
- assertFalse(buf.equals(readonly));
-
- buf.limit(buf.capacity() - 1).position(0);
- duplicate.limit(duplicate.capacity()).position(0);
- assertFalse(buf.equals(duplicate));
- }
-
- /*
- * Class under test for long get()
- */
- public void testGet() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.LongBuffer get(long[])
- */
- public void testGetlongArray() {
- long array[] = new long[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- LongBuffer ret = buf.get(array);
- assertEquals(array[0], buf.get(i));
- assertSame(ret, buf);
- }
- try {
- buf.get(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- try {
- buf.position(buf.limit());
- buf.get((long[])null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.LongBuffer get(long[], int, int)
- */
- public void testGetlongArrayintint() {
- buf.clear();
- long array[] = new long[buf.capacity()];
-
- try {
- buf.get(new long[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.get(array, array.length, 0);
- try {
- buf.get(array, array.length + 1, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get((long[])null, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.get(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- buf.get(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
-
- buf.clear();
- LongBuffer ret = buf.get(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for long get(int)
- */
- public void testGetint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(buf.limit());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testHasArray() {
- assertNotNull(buf.array());
- }
-
- public void testHashCode() {
- buf.clear();
- LongBuffer readonly = buf.asReadOnlyBuffer();
- LongBuffer duplicate = buf.duplicate();
- assertTrue(buf.hashCode() == readonly.hashCode());
-
- assertTrue(buf.capacity() > 5);
- duplicate.position(buf.capacity() / 2);
- assertTrue(buf.hashCode() != duplicate.hashCode());
- }
-
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- public void testOrder() {
- buf.order();
- assertEquals(ByteOrder.nativeOrder(), buf.order());
- }
-
- /*
- * Class under test for java.nio.LongBuffer put(long)
- */
- public void testPutlong() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- LongBuffer ret = buf.put((long) i);
- assertEquals(buf.get(i), (long) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.LongBuffer put(long[])
- */
- public void testPutlongArray() {
- long array[] = new long[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- array[0] = (long) i;
- LongBuffer ret = buf.put(array);
- assertEquals(buf.get(i), (long) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.position(buf.limit());
- buf.put((long[])null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.LongBuffer put(long[], int, int)
- */
- public void testPutlongArrayintint() {
- buf.clear();
- long array[] = new long[buf.capacity()];
- try {
- buf.put(new long[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, array.length + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.put(array, array.length, 0);
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put((long[])null, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.put(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- assertEquals(buf.position(), 0);
-
- loadTestData2(array, 0, array.length);
- LongBuffer ret = buf.put(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.LongBuffer put(java.nio.LongBuffer)
- */
- public void testPutLongBuffer() {
- LongBuffer other = LongBuffer.allocate(buf.capacity());
- try {
- buf.put(buf);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- buf.put(LongBuffer.allocate(buf.capacity() + 1));
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.flip();
- buf.put((LongBuffer)null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
-
- loadTestData2(other);
- other.clear();
- buf.clear();
- LongBuffer ret = buf.put(other);
- assertEquals(other.position(), other.capacity());
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(other, buf);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.LongBuffer put(int, long)
- */
- public void testPutintlong() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), 0);
- LongBuffer ret = buf.put(i, (long) i);
- assertEquals(buf.get(i), (long) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(-1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(buf.limit(), 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testSlice() {
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(buf.capacity() - 1);
-
- LongBuffer slice = buf.slice();
- assertEquals(buf.isReadOnly(), slice.isReadOnly());
- assertEquals(buf.isDirect(), slice.isDirect());
- assertEquals(buf.order(), slice.order());
- assertEquals(slice.position(), 0);
- assertEquals(slice.limit(), buf.remaining());
- assertEquals(slice.capacity(), buf.remaining());
- try {
- slice.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // slice share the same content with buf
- if (!slice.isReadOnly()) {
- loadTestData1(slice);
- assertContentLikeTestData1(buf, 1, 0, slice.capacity());
- buf.put(2, 500);
- assertEquals(slice.get(1), 500);
- }
- }
-
- public void testToString() {
- String str = buf.toString();
- assertTrue(str.indexOf("Long") >= 0 || str.indexOf("long") >= 0);
- assertTrue(str.indexOf("" + buf.position()) >= 0);
- assertTrue(str.indexOf("" + buf.limit()) >= 0);
- assertTrue(str.indexOf("" + buf.capacity()) >= 0);
- }
-
- void loadTestData1(long array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (long) i;
- }
- }
-
- void loadTestData2(long array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (long) length - i;
- }
- }
-
- void loadTestData1(LongBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (long) i);
- }
- }
-
- void loadTestData2(LongBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (long) buf.capacity() - i);
- }
- }
-
- void assertContentEquals(LongBuffer buf, long array[],
- int offset, int length) {
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(i), array[offset + i]);
- }
- }
-
- void assertContentEquals(LongBuffer buf, LongBuffer other) {
- assertEquals(buf.capacity(), other.capacity());
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.get(i), other.get(i));
- }
- }
-
- void assertContentLikeTestData1(LongBuffer buf,
- int startIndex, long startValue, int length) {
- long value = startValue;
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(startIndex + i), value);
- value = value + 1;
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/MappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/MappedByteBufferTest.java
deleted file mode 100644
index 308db21..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/MappedByteBufferTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.NonWritableChannelException;
-import java.nio.channels.FileChannel.MapMode;
-
-import junit.framework.TestCase;
-
-public class MappedByteBufferTest extends TestCase {
-
- File tmpFile, emptyFile;
-
- /**
- * A regression test for failing to correctly set capacity of underlying
- * wrapped buffer from a mapped byte buffer.
- */
- public void testasIntBuffer() throws IOException {
- // Map file
- FileInputStream fis = new FileInputStream(tmpFile);
- FileChannel fc = fis.getChannel();
- MappedByteBuffer mmb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc
- .size());
- int len = mmb.capacity();
- assertEquals("Got wrong number of bytes", 46, len); //$NON-NLS-1$
-
- // Read in our 26 bytes
- for (int i = 0; i < 26; i++) {
- byte b = mmb.get();
- assertEquals("Got wrong byte value", (byte) 'A' + i, b); //$NON-NLS-1$
- }
-
- // Now convert to an IntBuffer to read our ints
- IntBuffer ibuffer = mmb.asIntBuffer();
- for (int i = 0; i < 5; i++) {
- int val = ibuffer.get();
- assertEquals("Got wrong int value", i + 1, val); //$NON-NLS-1$
- }
- fc.close();
- }
-
- /**
- * Regression for HARMONY-6315 - FileChannel.map throws IOException
- * when called with size 0
- *
- * @throws IOException
- */
- public void testEmptyBuffer() throws IOException {
- // Map empty file
- FileInputStream fis = new FileInputStream(emptyFile);
- FileChannel fc = fis.getChannel();
- MappedByteBuffer mmb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
-
- // check non-null
- assertNotNull("MappedByteBuffer created from empty file should not be null",
- mmb);
-
- // check capacity is 0
- int len = mmb.capacity();
- assertEquals("MappedByteBuffer created from empty file should have 0 capacity",
- 0, len);
-
- assertFalse("MappedByteBuffer from empty file shouldn't be backed by an array ",
- mmb.hasArray());
-
- try
- {
- byte b = mmb.get();
- fail("Calling MappedByteBuffer.get() on empty buffer should throw a BufferUnderflowException");
- }
- catch (BufferUnderflowException e)
- {
- // expected behaviour
- }
-
- // test expected exceptions thrown
- try
- {
- mmb = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());
- fail("Expected NonWritableChannelException to be thrown");
- }
- catch (NonWritableChannelException e)
- {
- // expected behaviour
- }
- try
- {
- mmb = fc.map(FileChannel.MapMode.PRIVATE, 0, fc.size());
- fail("Expected NonWritableChannelException to be thrown");
- }
- catch (NonWritableChannelException e)
- {
- // expected behaviour
- }
- fc.close();
- }
-
- /**
- * @tests {@link java.nio.MappedByteBuffer#force()}
- */
- public void test_force() throws IOException {
- // buffer was not mapped in read/write mode
- FileInputStream fileInputStream = new FileInputStream(tmpFile);
- FileChannel fileChannelRead = fileInputStream.getChannel();
- MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0,
- fileChannelRead.size());
-
- mmbRead.force();
-
- FileInputStream inputStream = new FileInputStream(tmpFile);
- FileChannel fileChannelR = inputStream.getChannel();
- MappedByteBuffer resultRead = fileChannelR.map(MapMode.READ_ONLY, 0,
- fileChannelR.size());
-
- //If this buffer was not mapped in read/write mode, then invoking this method has no effect.
- assertEquals(
- "Invoking force() should have no effect when this buffer was not mapped in read/write mode",
- mmbRead, resultRead);
-
- // Buffer was mapped in read/write mode
- RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw");
- FileChannel fileChannelReadWrite = randomFile.getChannel();
- MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map(
- FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size());
-
- mmbReadWrite.put((byte) 'o');
- mmbReadWrite.force();
-
- RandomAccessFile random = new RandomAccessFile(tmpFile, "rw");
- FileChannel fileChannelRW = random.getChannel();
- MappedByteBuffer resultReadWrite = fileChannelRW.map(
- FileChannel.MapMode.READ_WRITE, 0, fileChannelRW.size());
-
- // Invoking force() will change the buffer
- assertFalse(mmbReadWrite.equals(resultReadWrite));
-
- fileChannelRead.close();
- fileChannelR.close();
- fileChannelReadWrite.close();
- fileChannelRW.close();
- }
-
- /**
- * @tests {@link java.nio.MappedByteBuffer#load()}
- */
- public void test_load() throws IOException {
- FileInputStream fileInputStream = new FileInputStream(tmpFile);
- FileChannel fileChannelRead = fileInputStream.getChannel();
- MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0,
- fileChannelRead.size());
-
- assertEquals(mmbRead, mmbRead.load());
-
- RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw");
- FileChannel fileChannelReadWrite = randomFile.getChannel();
- MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map(
- FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size());
-
- assertEquals(mmbReadWrite, mmbReadWrite.load());
-
- fileChannelRead.close();
- fileChannelReadWrite.close();
- }
-
- protected void setUp() throws IOException {
- // Create temp file with 26 bytes and 5 ints
- tmpFile = File.createTempFile("harmony", "test"); //$NON-NLS-1$//$NON-NLS-2$
- tmpFile.deleteOnExit();
- FileOutputStream fileOutputStream = new FileOutputStream(tmpFile);
- FileChannel fileChannel = fileOutputStream.getChannel();
- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(26 + 20);
- for (int i = 0; i < 26; i++) {
- byteBuffer.put((byte) ('A' + i));
- }
- for (int i = 0; i < 5; i++) {
- byteBuffer.putInt(i + 1);
- }
- byteBuffer.rewind();
- fileChannel.write(byteBuffer);
- fileChannel.close();
- fileOutputStream.close();
-
- emptyFile = File.createTempFile("harmony", "test"); //$NON-NLS-1$//$NON-NLS-2$
- emptyFile.deleteOnExit();
- }
-
- public void test_position() throws IOException {
- File tmp = File.createTempFile("hmy", "tmp");
- tmp.deleteOnExit();
- RandomAccessFile f = new RandomAccessFile(tmp, "rw");
- FileChannel ch = f.getChannel();
- MappedByteBuffer mbb = ch.map(MapMode.READ_WRITE, 0L, 100L);
- ch.close();
-
- mbb.putInt(1, 1);
- mbb.position(50);
- mbb.putInt(50);
-
- mbb.flip();
- mbb.get();
- assertEquals(1, mbb.getInt());
-
- mbb.position(50);
- assertEquals(50, mbb.getInt());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.java
deleted file mode 100644
index cbacbc5..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ReadOnlyBufferException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-public class ReadOnlyBufferExceptionTest extends TestCase {
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new ReadOnlyBufferException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new ReadOnlyBufferException());
- }
-
- /**
- *@tests {@link java.nio.ReadOnlyBufferException#ReadOnlyBufferException()}
- */
- public void test_Constructor() {
- ReadOnlyBufferException exception = new ReadOnlyBufferException();
- assertNull(exception.getMessage());
- assertNull(exception.getLocalizedMessage());
- assertNull(exception.getCause());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyCharBufferTest.java
deleted file mode 100644
index f951962..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyCharBufferTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.CharBuffer;
-import java.nio.ReadOnlyBufferException;
-
-public class ReadOnlyCharBufferTest extends CharBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- buf = null;
- baseBuf = null;
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- }
- }
-
- public void testHashCode() {
- CharBuffer duplicate = buf.duplicate();
- assertEquals(buf.hashCode(), duplicate.hashCode());
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testCompact() {
- try {
- buf.compact();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutchar() {
- try {
- buf.put((char) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutcharArray() {
- char array[] = new char[1];
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((char[]) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testPutcharArrayintint() {
- char array[] = new char[1];
- try {
- buf.put(array, 0, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((char[]) null, 0, 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(new char[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(array, -1, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutCharBuffer() {
- CharBuffer other = CharBuffer.allocate(1);
- try {
- buf.put(other);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((CharBuffer) null);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(buf);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutintchar() {
- try {
- buf.put(0, (char) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(-1, (char) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutStringintint() {
- buf.clear();
- String str = String.valueOf(new char[buf.capacity()]);
- try {
- buf.put(str, 0, str.length());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((String) null, 0, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException expected) {
- } catch (NullPointerException expected) {
- }
- try {
- buf.put(str, -1, str.length());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException expected) {
- } catch (NullPointerException expected) {
- }
- String longStr = String.valueOf(new char[buf.capacity()+1]);
- try {
- buf.put(longStr, 0, longStr.length());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutString() {
- String str = " ";
- try {
- buf.put(str);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((String)null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyDirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyDirectByteBufferTest.java
deleted file mode 100644
index 20c7914..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyDirectByteBufferTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class ReadOnlyDirectByteBufferTest extends DirectByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testHashCode() {
- super.readOnlyHashCode();
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyDoubleBufferTest.java
deleted file mode 100644
index d87e81d..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyDoubleBufferTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.DoubleBuffer;
-import java.nio.ReadOnlyBufferException;
-
-public class ReadOnlyDoubleBufferTest extends DoubleBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- }
- }
-
- public void testHashCode() {
- DoubleBuffer duplicate = buf.duplicate();
- assertEquals(buf.hashCode(), duplicate.hashCode());
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testCompact() {
- try {
- buf.compact();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutdouble() {
- try {
- buf.put(0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutdoubleArray() {
- double array[] = new double[1];
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((double[]) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testPutdoubleArrayintint() {
- double array[] = new double[1];
- try {
- buf.put(array, 0, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((double[]) null, 0, 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(new double[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(array, -1, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutDoubleBuffer() {
- DoubleBuffer other = DoubleBuffer.allocate(1);
- try {
- buf.put(other);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((DoubleBuffer) null);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(buf);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutintdouble() {
- try {
- buf.put(0, (double) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(-1, (double) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyFloatBufferTest.java
deleted file mode 100644
index 3acc5c4..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyFloatBufferTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.FloatBuffer;
-import java.nio.ReadOnlyBufferException;
-
-public class ReadOnlyFloatBufferTest extends FloatBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- //expected
- }
- }
-
- public void testHashCode() {
- FloatBuffer duplicate = buf.duplicate();
- assertEquals(buf.hashCode(), duplicate.hashCode());
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void testCompact() {
- try {
- buf.compact();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutfloat() {
- try {
- buf.put(0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutfloatArray() {
- float array[] = new float[1];
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((float[]) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testPutfloatArrayintint() {
- float array[] = new float[1];
- try {
- buf.put(array, 0, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((float[]) null, 0, 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(new float[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(array, -1, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutFloatBuffer() {
- FloatBuffer other = FloatBuffer.allocate(1);
- try {
- buf.put(other);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((FloatBuffer) null);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(buf);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutintfloat() {
- try {
- buf.put(0, (float) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(-1, (float) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapByteBufferTest.java
deleted file mode 100644
index 7452a24..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapByteBufferTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class ReadOnlyHeapByteBufferTest extends HeapByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testHashCode() {
- super.readOnlyHashCode();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapCharBufferTest.java
deleted file mode 100644
index 4c7792a..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapCharBufferTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.CharBuffer;
-
-
-public class ReadOnlyHeapCharBufferTest extends ReadOnlyCharBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = CharBuffer.allocate(BUFFER_LENGTH);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapDoubleBufferTest.java
deleted file mode 100644
index f95c4c2..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapDoubleBufferTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.DoubleBuffer;
-
-public class ReadOnlyHeapDoubleBufferTest extends ReadOnlyDoubleBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = DoubleBuffer.allocate(BUFFER_LENGTH);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapFloatBufferTest.java
deleted file mode 100644
index f2c6644..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapFloatBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.FloatBuffer;
-
-public class ReadOnlyHeapFloatBufferTest extends ReadOnlyFloatBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = FloatBuffer.allocate(BUFFER_LENGTH);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapIntBufferTest.java
deleted file mode 100644
index f9a3877..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapIntBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.IntBuffer;
-
-public class ReadOnlyHeapIntBufferTest extends ReadOnlyIntBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = IntBuffer.allocate(BUFFER_LENGTH);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapLongBufferTest.java
deleted file mode 100644
index efba978..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapLongBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.LongBuffer;
-
-public class ReadOnlyHeapLongBufferTest extends ReadOnlyLongBufferTest{
- protected void setUp() throws Exception {
- super.setUp();
- buf = LongBuffer.allocate(BUFFER_LENGTH);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapShortBufferTest.java
deleted file mode 100644
index bbbd616..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyHeapShortBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ShortBuffer;
-
-public class ReadOnlyHeapShortBufferTest extends ReadOnlyShortBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = ShortBuffer.allocate(BUFFER_LENGTH);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyIntBufferTest.java
deleted file mode 100644
index 61e78a6..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyIntBufferTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.IntBuffer;
-import java.nio.ReadOnlyBufferException;
-
-public class ReadOnlyIntBufferTest extends IntBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- //expected
- }
- }
-
- public void testHashCode() {
- IntBuffer duplicate = buf.duplicate();
- assertEquals(buf.hashCode(), duplicate.hashCode());
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void testCompact() {
- try {
- buf.compact();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutint() {
- try {
- buf.put(0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutintArray() {
- int array[] = new int[1];
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((int[]) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testPutintArrayintint() {
- int array[] = new int[1];
- try {
- buf.put(array, 0, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((int[]) null, -1, 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(new int[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(array, -1, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutIntBuffer() {
- IntBuffer other = IntBuffer.allocate(1);
- try {
- buf.put(other);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((IntBuffer) null);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(buf);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutintint() {
- try {
- buf.put(0, (int) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(-1, (int) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyLongBufferTest.java
deleted file mode 100644
index b670606..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyLongBufferTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.LongBuffer;
-import java.nio.ReadOnlyBufferException;
-
-public class ReadOnlyLongBufferTest extends LongBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- //expected
- }
- }
-
- public void testHashCode() {
- LongBuffer duplicate = buf.duplicate();
- assertEquals(buf.hashCode(), duplicate.hashCode());
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void testCompact() {
- try {
- buf.compact();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutlong() {
- try {
- buf.put(0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutlongArray() {
- long array[] = new long[1];
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((long[]) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testPutlongArrayintint() {
- long array[] = new long[1];
- try {
- buf.put(array, 0, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((long[]) null, 0, 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(new long[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(array, -1, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutLongBuffer() {
- LongBuffer other = LongBuffer.allocate(1);
- try {
- buf.put(other);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((LongBuffer) null);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(buf);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutintlong() {
- try {
- buf.put(0, (long) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(-1, (long) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyShortBufferTest.java
deleted file mode 100644
index 611f6bf..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyShortBufferTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ReadOnlyBufferException;
-import java.nio.ShortBuffer;
-
-public class ReadOnlyShortBufferTest extends ShortBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- //expected
- }
- }
-
- public void testHashCode() {
- ShortBuffer duplicate = buf.duplicate();
- assertEquals(buf.hashCode(), duplicate.hashCode());
- }
-
- public void testArrayOffset() {
- try {
- buf.arrayOffset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void testCompact() {
- try {
- buf.compact();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutshort() {
- try {
- buf.put((short)0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutshortArray() {
- short array[] = new short[1];
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((short[]) null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testPutshortArrayintint() {
- short array[] = new short[1];
- try {
- buf.put(array, 0, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((short[]) null, 0, 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(new short[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(array, -1, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutShortBuffer() {
- ShortBuffer other = ShortBuffer.allocate(1);
- try {
- buf.put(other);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((ShortBuffer) null);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(buf);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-
- public void testPutintshort() {
- try {
- buf.put(0, (short) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put(-1, (short) 0);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedByteBufferTest.java
deleted file mode 100644
index 031d75b..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedByteBufferTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class ReadOnlyWrappedByteBufferTest extends WrappedByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testIsReadOnly() {
- assertTrue(buf.isReadOnly());
- }
-
- public void testHasArray() {
- assertFalse(buf.hasArray());
- }
-
- public void testHashCode() {
- super.readOnlyHashCode();
- }
-
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java
deleted file mode 100644
index 57c04bf..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.CharBuffer;
-
-public class ReadOnlyWrappedCharBufferTest1 extends ReadOnlyCharBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = CharBuffer.wrap(new char[BUFFER_LENGTH]);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java
deleted file mode 100644
index d1ba9df..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.DoubleBuffer;
-
-public class ReadOnlyWrappedDoubleBufferTest extends ReadOnlyDoubleBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = DoubleBuffer.wrap(new double[BUFFER_LENGTH]);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java
deleted file mode 100644
index affddaa..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.FloatBuffer;
-
-public class ReadOnlyWrappedFloatBufferTest extends ReadOnlyFloatBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = FloatBuffer.wrap(new float[BUFFER_LENGTH]);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedIntBufferTest.java
deleted file mode 100644
index a4d0155..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedIntBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.IntBuffer;
-
-public class ReadOnlyWrappedIntBufferTest extends ReadOnlyIntBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = IntBuffer.wrap(new int[BUFFER_LENGTH]);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedLongBufferTest.java
deleted file mode 100644
index 58491da..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedLongBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.LongBuffer;
-
-public class ReadOnlyWrappedLongBufferTest extends ReadOnlyLongBufferTest{
- protected void setUp() throws Exception {
- super.setUp();
- buf = LongBuffer.wrap(new long[BUFFER_LENGTH]);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedShortBufferTest.java
deleted file mode 100644
index 0ecb3a4..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedShortBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ShortBuffer;
-
-public class ReadOnlyWrappedShortBufferTest extends ReadOnlyShortBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = ShortBuffer.wrap(new short[BUFFER_LENGTH]);
- super.loadTestData1(buf);
- buf = buf.asReadOnlyBuffer();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ShortBufferTest.java
deleted file mode 100644
index 98d7659..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/ShortBufferTest.java
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteOrder;
-import java.nio.InvalidMarkException;
-import java.nio.ShortBuffer;
-
-/**
- * Tests java.nio.ShortBuffer
- *
- */
-public class ShortBufferTest extends AbstractBufferTest {
-
- protected static final int SMALL_TEST_LENGTH = 5;
-
- protected static final int BUFFER_LENGTH = 20;
-
- protected ShortBuffer buf;
-
- protected void setUp() throws Exception {
- buf = ShortBuffer.allocate(BUFFER_LENGTH);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- buf = null;
- baseBuf = null;
- }
-
- public void testArray() {
- short array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testArrayOffset() {
- short array[] = buf.array();
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(array, buf.arrayOffset(), buf.capacity());
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData1(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
-
- loadTestData2(buf);
- assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
- }
-
- public void testAsReadOnlyBuffer() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // readonly's contents should be the same as buf
- ShortBuffer readonly = buf.asReadOnlyBuffer();
- assertNotSame(buf, readonly);
- assertTrue(readonly.isReadOnly());
- assertEquals(buf.position(), readonly.position());
- assertEquals(buf.limit(), readonly.limit());
- assertEquals(buf.isDirect(), readonly.isDirect());
- assertEquals(buf.order(), readonly.order());
- assertContentEquals(buf, readonly);
-
- // readonly's position, mark, and limit should be independent to buf
- readonly.reset();
- assertEquals(readonly.position(), 0);
- readonly.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
- }
-
- public void testCompact() {
- // case: buffer is full
- buf.clear();
- buf.mark();
- loadTestData1(buf);
- ShortBuffer ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), buf.capacity());
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (short) 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: buffer is empty
- buf.position(0);
- buf.limit(0);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 0);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (short) 0, buf.capacity());
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // case: normal
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(5);
- buf.mark();
- ret = buf.compact();
- assertSame(ret, buf);
- assertEquals(buf.position(), 4);
- assertEquals(buf.limit(), buf.capacity());
- assertContentLikeTestData1(buf, 0, (short) 1, 4);
- try {
- buf.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
- }
-
- public void testCompareTo() {
- // compare to self
- assertEquals(0, buf.compareTo(buf));
-
- // normal cases
- assertTrue(buf.capacity() > 5);
- buf.clear();
- ShortBuffer other = ShortBuffer.allocate(buf.capacity());
- loadTestData1(other);
- assertEquals(0, buf.compareTo(other));
- assertEquals(0, other.compareTo(buf));
- buf.position(1);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- other.position(2);
- assertTrue(buf.compareTo(other) < 0);
- assertTrue(other.compareTo(buf) > 0);
- buf.position(2);
- other.limit(5);
- assertTrue(buf.compareTo(other) > 0);
- assertTrue(other.compareTo(buf) < 0);
- }
-
- public void testDuplicate() {
- buf.clear();
- buf.mark();
- buf.position(buf.limit());
-
- // duplicate's contents should be the same as buf
- ShortBuffer duplicate = buf.duplicate();
- assertNotSame(buf, duplicate);
- assertEquals(buf.position(), duplicate.position());
- assertEquals(buf.limit(), duplicate.limit());
- assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
- assertEquals(buf.isDirect(), duplicate.isDirect());
- assertEquals(buf.order(), duplicate.order());
- assertContentEquals(buf, duplicate);
-
- // duplicate's position, mark, and limit should be independent to buf
- duplicate.reset();
- assertEquals(duplicate.position(), 0);
- duplicate.clear();
- assertEquals(buf.position(), buf.limit());
- buf.reset();
- assertEquals(buf.position(), 0);
-
- // duplicate share the same content with buf
- if (!duplicate.isReadOnly()) {
- loadTestData1(buf);
- assertContentEquals(buf, duplicate);
- loadTestData2(duplicate);
- assertContentEquals(buf, duplicate);
- }
- }
-
- public void testEquals() {
- // equal to self
- assertTrue(buf.equals(buf));
- ShortBuffer readonly = buf.asReadOnlyBuffer();
- assertTrue(buf.equals(readonly));
- ShortBuffer duplicate = buf.duplicate();
- assertTrue(buf.equals(duplicate));
-
- // always false, if type mismatch
- assertFalse(buf.equals(Boolean.TRUE));
-
- assertTrue(buf.capacity() > 5);
-
- buf.limit(buf.capacity()).position(0);
- readonly.limit(readonly.capacity()).position(1);
- assertFalse(buf.equals(readonly));
-
- buf.limit(buf.capacity() - 1).position(0);
- duplicate.limit(duplicate.capacity()).position(0);
- assertFalse(buf.equals(duplicate));
- }
-
- /*
- * Class under test for short get()
- */
- public void testGet() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.ShortBuffer get(short[])
- */
- public void testGetshortArray() {
- short array[] = new short[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- ShortBuffer ret = buf.get(array);
- assertEquals(array[0], buf.get(i));
- assertSame(ret, buf);
- }
- try {
- buf.get(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.ShortBuffer get(short[], int, int)
- */
- public void testGetshortArrayintint() {
- buf.clear();
- short array[] = new short[buf.capacity()];
-
- try {
- buf.get(new short[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.get(array, array.length, 0);
- try {
- buf.get(array, array.length + 1, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.get((short[])null, 2, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.get(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferUnderflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- buf.get(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
-
- buf.clear();
- ShortBuffer ret = buf.get(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for short get(int)
- */
- public void testGetint() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- assertEquals(buf.get(), buf.get(i));
- }
- try {
- buf.get(-1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.get(buf.limit());
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testHasArray() {
- assertNotNull(buf.array());
- }
-
- public void testHashCode() {
- buf.clear();
- ShortBuffer readonly = buf.asReadOnlyBuffer();
- ShortBuffer duplicate = buf.duplicate();
- assertTrue(buf.hashCode() == readonly.hashCode());
-
- assertTrue(buf.capacity() > 5);
- duplicate.position(buf.capacity() / 2);
- assertTrue(buf.hashCode() != duplicate.hashCode());
- }
-
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- public void testOrder() {
- buf.order();
- assertEquals(ByteOrder.nativeOrder(), buf.order());
- }
-
- /*
- * Class under test for java.nio.ShortBuffer put(short)
- */
- public void testPutshort() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- ShortBuffer ret = buf.put((short) i);
- assertEquals(buf.get(i), (short) i);
- assertSame(ret, buf);
- }
- try {
- buf.put((short) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.ShortBuffer put(short[])
- */
- public void testPutshortArray() {
- short array[] = new short[1];
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), i);
- array[0] = (short) i;
- ShortBuffer ret = buf.put(array);
- assertEquals(buf.get(i), (short) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(array);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.position(buf.limit());
- buf.put((short[])null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Class under test for java.nio.ShortBuffer put(short[], int, int)
- */
- public void testPutshortArrayintint() {
- buf.clear();
- short array[] = new short[buf.capacity()];
- try {
- buf.put(new short[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, -1, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, array.length + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- buf.put(array, array.length, 0);
- assertEquals(buf.position(), 0);
- try {
- buf.put(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put((short[])null, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- try {
- buf.put(array, 2, array.length);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- assertEquals(buf.position(), 0);
-
- loadTestData2(array, 0, array.length);
- ShortBuffer ret = buf.put(array, 0, array.length);
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(buf, array, 0, array.length);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.ShortBuffer put(java.nio.ShortBuffer)
- */
- public void testPutShortBuffer() {
- ShortBuffer other = ShortBuffer.allocate(buf.capacity());
- try {
- buf.put(buf);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- buf.put(ShortBuffer.allocate(buf.capacity() + 1));
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (BufferOverflowException e) {
- // expected
- }
- try {
- buf.flip();
- buf.put((ShortBuffer)null);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
-
- loadTestData2(other);
- other.clear();
- buf.clear();
- ShortBuffer ret = buf.put(other);
- assertEquals(other.position(), other.capacity());
- assertEquals(buf.position(), buf.capacity());
- assertContentEquals(other, buf);
- assertSame(ret, buf);
- }
-
- /*
- * Class under test for java.nio.ShortBuffer put(int, short)
- */
- public void testPutintshort() {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.position(), 0);
- ShortBuffer ret = buf.put(i, (short) i);
- assertEquals(buf.get(i), (short) i);
- assertSame(ret, buf);
- }
- try {
- buf.put(-1, (short) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- buf.put(buf.limit(), (short) 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- public void testSlice() {
- assertTrue(buf.capacity() > 5);
- buf.position(1);
- buf.limit(buf.capacity() - 1);
-
- ShortBuffer slice = buf.slice();
- assertEquals(buf.isReadOnly(), slice.isReadOnly());
- assertEquals(buf.isDirect(), slice.isDirect());
- assertEquals(buf.order(), slice.order());
- assertEquals(slice.position(), 0);
- assertEquals(slice.limit(), buf.remaining());
- assertEquals(slice.capacity(), buf.remaining());
- try {
- slice.reset();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (InvalidMarkException e) {
- // expected
- }
-
- // slice share the same content with buf
- if (!slice.isReadOnly()) {
- loadTestData1(slice);
- assertContentLikeTestData1(buf, 1, (short) 0, slice.capacity());
- buf.put(2, (short) 500);
- assertEquals(slice.get(1), 500);
- }
- }
-
- public void testToString() {
- String str = buf.toString();
- assertTrue(str.indexOf("Short") >= 0 || str.indexOf("short") >= 0);
- assertTrue(str.indexOf("" + buf.position()) >= 0);
- assertTrue(str.indexOf("" + buf.limit()) >= 0);
- assertTrue(str.indexOf("" + buf.capacity()) >= 0);
- }
-
- void loadTestData1(short array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (short) i;
- }
- }
-
- void loadTestData2(short array[], int offset, int length) {
- for (int i = 0; i < length; i++) {
- array[offset + i] = (short) (length - i);
- }
- }
-
- void loadTestData1(ShortBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (short) i);
- }
- }
-
- void loadTestData2(ShortBuffer buf) {
- buf.clear();
- for (int i = 0; i < buf.capacity(); i++) {
- buf.put(i, (short) (buf.capacity() - i));
- }
- }
-
- void assertContentEquals(ShortBuffer buf, short array[],
- int offset, int length) {
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(i), array[offset + i]);
- }
- }
-
- void assertContentEquals(ShortBuffer buf, ShortBuffer other) {
- assertEquals(buf.capacity(), other.capacity());
- for (int i = 0; i < buf.capacity(); i++) {
- assertEquals(buf.get(i), other.get(i));
- }
- }
-
- void assertContentLikeTestData1(ShortBuffer buf,
- int startIndex, short startValue, int length) {
- short value = startValue;
- for (int i = 0; i < length; i++) {
- assertEquals(buf.get(startIndex + i), value);
- value = (short) (value + 1);
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceDirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceDirectByteBufferTest.java
deleted file mode 100644
index 541cde0..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceDirectByteBufferTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class SliceDirectByteBufferTest extends DirectByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf.position(1).limit(BUFFER_LENGTH-1);
- buf = buf.slice();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceHeapByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceHeapByteBufferTest.java
deleted file mode 100644
index 9f9f7aa..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceHeapByteBufferTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class SliceHeapByteBufferTest extends HeapByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf.position(1).limit(BUFFER_LENGTH-1);
- buf = buf.slice();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceWrappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceWrappedByteBufferTest.java
deleted file mode 100644
index f1ddfb9..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceWrappedByteBufferTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-
-public class SliceWrappedByteBufferTest extends WrappedByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf.position(1).limit(BUFFER_LENGTH-1);
- buf = buf.slice();
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedByteBufferTest.java
deleted file mode 100644
index 6460d2e..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedByteBufferTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ByteBuffer;
-
-public class WrappedByteBufferTest extends ByteBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = ByteBuffer.wrap(new byte[BUFFER_LENGTH]);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- buf = null;
- baseBuf = null;
- }
-
- /**
- * @tests java.nio.ByteBuffer#allocate(byte[],int,int)
- *
- */
- public void testWrappedByteBuffer_IllegalArg() {
- byte array[] = new byte[BUFFER_LENGTH];
- try {
- ByteBuffer.wrap(array, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ByteBuffer.wrap(array, BUFFER_LENGTH + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ByteBuffer.wrap(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ByteBuffer.wrap(array, 0, BUFFER_LENGTH + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ByteBuffer.wrap(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ByteBuffer.wrap(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ByteBuffer.wrap((byte[])null, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- public void testHasArray() {
- assertTrue(buf.hasArray());
- }
-
- public void testIsReadOnly() {
- assertFalse(buf.isReadOnly());
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest1.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest1.java
deleted file mode 100644
index 9181a77..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest1.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.CharBuffer;
-
-public class WrappedCharBufferTest1 extends CharBufferTest {
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = CharBuffer.wrap(new char[BUFFER_LENGTH]);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- baseBuf = null;
- buf = null;
- }
-
- /**
- * @tests java.nio.CharBuffer#allocate(char[],int,int)
- *
- */
- public void testWrappedCharBuffer_IllegalArg() {
- char array[] = new char[BUFFER_LENGTH];
- try {
- CharBuffer.wrap(array, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap(array, BUFFER_LENGTH + 1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap(array, 0, BUFFER_LENGTH + 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap((char[])null, -1, 0);
- fail("Should throw NPE"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest2.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest2.java
deleted file mode 100644
index 5fa9335..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest2.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.BufferOverflowException;
-import java.nio.CharBuffer;
-import java.nio.ReadOnlyBufferException;
-
-public class WrappedCharBufferTest2 extends ReadOnlyCharBufferTest {
- protected static final String TEST_STRING = "123456789abcdef12345";
-
- protected void setUp() throws Exception {
- super.setUp();
- buf = CharBuffer.wrap(TEST_STRING);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- baseBuf = null;
- buf = null;
- }
-
- public void testWrappedCharSequence_IllegalArg() {
- String str = TEST_STRING;
- try {
- CharBuffer.wrap(str, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap(str, 21, 21);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap(str, 2, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap(str, 0, 21);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- CharBuffer.wrap((String)null, -1, 21);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void testArray() {
- try {
- buf.array();
- fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- }
- }
-
- public void testPutcharArrayintint() {
- char array[] = new char[1];
- try {
- buf.put(array, 0, array.length);
- fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException e) {
- // expected
- }
- try {
- buf.put((char[]) null, 0, 1);
- fail("Should throw NullPointerException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException expected) {
- } catch (NullPointerException expected) {
- }
- try {
- buf.put(new char[buf.capacity() + 1], 0, buf.capacity() + 1);
- fail("Should throw BufferOverflowException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException expected) {
- } catch (BufferOverflowException expected) {
- }
- try {
- buf.put(array, -1, array.length);
- fail("Should throw IndexOutOfBoundsException"); //$NON-NLS-1$
- } catch (ReadOnlyBufferException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void testPutCharBuffer() {
- CharBuffer other = CharBuffer.allocate(1);
- try {
- buf.put(other);
- fail();
- } catch (ReadOnlyBufferException expected) {
- }
- try {
- buf.put((CharBuffer) null);
- fail();
- } catch (ReadOnlyBufferException expected) {
- } catch (NullPointerException expected) {
- }
- try {
- buf.put(buf);
- fail();
- } catch (ReadOnlyBufferException expected) {
- } catch (IllegalArgumentException expected) {
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedDoubleBufferTest.java
deleted file mode 100644
index f970849..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedDoubleBufferTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.DoubleBuffer;
-
-public class WrappedDoubleBufferTest extends DoubleBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = DoubleBuffer.wrap(new double[BUFFER_LENGTH]);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- baseBuf = null;
- buf = null;
- }
-
- /**
- * @tests java.nio.CharBuffer#allocate(char[],int,int)
- *
- */
- public void testWrappedDoubleuffer_IllegalArg() {
- double array[] = new double[20];
- try {
- DoubleBuffer.wrap(array, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- DoubleBuffer.wrap(array, 21, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- DoubleBuffer.wrap(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- DoubleBuffer.wrap(array, 0, 21);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- DoubleBuffer.wrap(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- DoubleBuffer.wrap(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- DoubleBuffer.wrap((double[])null, -1, 0);
- fail("Should throw NPE"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- }
-
- DoubleBuffer buf = DoubleBuffer.wrap(array, 2, 16);
- assertEquals(buf.position(), 2);
- assertEquals(buf.limit(), 18);
- assertEquals(buf.capacity(), 20);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedFloatBufferTest.java
deleted file mode 100644
index 43b13c3..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedFloatBufferTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.FloatBuffer;
-
-public class WrappedFloatBufferTest extends FloatBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = FloatBuffer.wrap(new float[BUFFER_LENGTH]);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- baseBuf = null;
- buf = null;
- }
-
- /**
- * @tests java.nio.CharBuffer#allocate(char[],int,int)
- *
- */
- public void testWrappedFloatBuffer_IllegalArg() {
- float array[] = new float[20];
- try {
- FloatBuffer.wrap(array, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- FloatBuffer.wrap(array, 21, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- FloatBuffer.wrap(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- FloatBuffer.wrap(array, 0, 21);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- FloatBuffer.wrap(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- FloatBuffer.wrap(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- FloatBuffer.wrap((float[])null, -1, 0);
- fail("Should throw NPE"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- }
-
- FloatBuffer buf = FloatBuffer.wrap(array, 2, 16);
- assertEquals(buf.position(), 2);
- assertEquals(buf.limit(), 18);
- assertEquals(buf.capacity(), 20);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedIntBufferTest.java
deleted file mode 100644
index 383e964..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedIntBufferTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.IntBuffer;
-
-public class WrappedIntBufferTest extends IntBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = IntBuffer.wrap(new int[BUFFER_LENGTH]);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- baseBuf = null;
- buf = null;
- }
-
- /**
- * @tests java.nio.CharBuffer#allocate(char[],int,int)
- *
- */
- public void testWrappedIntBuffer_IllegalArg() {
- int array[] = new int[20];
- try {
- IntBuffer.wrap(array, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- IntBuffer.wrap(array, 21, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- IntBuffer.wrap(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- IntBuffer.wrap(array, 0, 21);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- IntBuffer.wrap(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- IntBuffer.wrap(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- IntBuffer.wrap((int[])null, -1, 0);
- fail("Should throw NPE"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- }
-
- IntBuffer buf = IntBuffer.wrap(array, 2, 16);
- assertEquals(buf.position(), 2);
- assertEquals(buf.limit(), 18);
- assertEquals(buf.capacity(), 20);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedLongBufferTest.java
deleted file mode 100644
index 581c912..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedLongBufferTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.LongBuffer;
-
-public class WrappedLongBufferTest extends LongBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = LongBuffer.wrap(new long[BUFFER_LENGTH]);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- baseBuf = null;
- buf = null;
- }
-
- /**
- * @tests java.nio.CharBuffer#allocate(char[],int,int)
- *
- */
- public void testWrappedLongBuffer_IllegalArg() {
- long array[] = new long[20];
- try {
- LongBuffer.wrap(array, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- LongBuffer.wrap(array, 21, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- LongBuffer.wrap(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- LongBuffer.wrap(array, 0, 21);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- LongBuffer.wrap(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- LongBuffer.wrap(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- LongBuffer.wrap((long[])null, -1, 0);
- fail("Should throw NPE"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- }
-
- LongBuffer buf = LongBuffer.wrap(array, 2, 16);
- assertEquals(buf.position(), 2);
- assertEquals(buf.limit(), 18);
- assertEquals(buf.capacity(), 20);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedShortBufferTest.java
deleted file mode 100644
index 9c6f781..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedShortBufferTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio;
-
-import java.nio.ShortBuffer;
-
-public class WrappedShortBufferTest extends ShortBufferTest {
- protected void setUp() throws Exception {
- super.setUp();
- buf = ShortBuffer.wrap(new short[BUFFER_LENGTH]);
- loadTestData1(buf);
- baseBuf = buf;
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- baseBuf = null;
- buf = null;
- }
-
- /**
- * @tests java.nio.CharBuffer#allocate(char[],int,int)
- *
- */
- public void testWrappedShortBuffer_IllegalArg() {
- short array[] = new short[20];
- try {
- ShortBuffer.wrap(array, -1, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ShortBuffer.wrap(array, 21, 0);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ShortBuffer.wrap(array, 0, -1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ShortBuffer.wrap(array, 0, 21);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ShortBuffer.wrap(array, Integer.MAX_VALUE, 1);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ShortBuffer.wrap(array, 1, Integer.MAX_VALUE);
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- ShortBuffer.wrap((short[])null, -1, 0);
- fail("Should throw NPE"); //$NON-NLS-1$
- } catch (NullPointerException e) {
- }
-
- ShortBuffer buf = ShortBuffer.wrap(array, 2, 16);
- assertEquals(buf.position(), 2);
- assertEquals(buf.limit(), 18);
- assertEquals(buf.capacity(), 20);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.java
deleted file mode 100644
index ac820a4..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.AlreadyConnectedException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for AlreadyConnectedException
- */
-public class AlreadyConnectedExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.AlreadyConnectedException#AlreadyConnectedException()}
- */
- public void test_Constructor() {
- AlreadyConnectedException e = new AlreadyConnectedException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new AlreadyConnectedException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new AlreadyConnectedException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.java
deleted file mode 100644
index 123eb1f..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.AsynchronousCloseException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for AsynchronousCloseException
- */
-public class AsynchronousCloseExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.AsynchronousCloseException#AsynchronousCloseException()}
- */
- public void test_Constructor() {
- AsynchronousCloseException e = new AsynchronousCloseException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new AsynchronousCloseException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new AsynchronousCloseException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.java
deleted file mode 100644
index 7a73322..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.CancelledKeyException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for CancelledKeyException
- */
-public class CancelledKeyExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.CancelledKeyException#CancelledKeyException()}
- */
- public void test_Constructor() {
- CancelledKeyException e = new CancelledKeyException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new CancelledKeyException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new CancelledKeyException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ChannelsTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ChannelsTest.java
deleted file mode 100644
index 4223fb8..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ChannelsTest.java
+++ /dev/null
@@ -1,622 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.IllegalBlockingModeException;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.WritableByteChannel;
-import java.nio.charset.Charset;
-import java.nio.charset.UnsupportedCharsetException;
-
-import tests.support.Support_PortManager;
-
-import junit.framework.TestCase;
-
-/**
- * Note: the test case uses a temp text file named "test" which contains 31
- * characters : "P@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]"
- *
- */
-
-public class ChannelsTest extends TestCase {
- private static final String CODE_SET = "GB2312"; //$NON-NLS-1$
-
- private static final String BAD_CODE_SET = "GB2313"; //$NON-NLS-1$
-
- private FileInputStream fins;
-
- private FileOutputStream fouts;
-
- private final int writebufSize = 60;
-
- private final int testNum = 10;
-
- private final int fileSize = 31;// the file size
-
- private File tmpFile;
-
- protected void setUp() throws Exception {
- super.setUp();
- // Make the test file same in every test
- tmpFile = File.createTempFile("test","tmp");
- tmpFile.deleteOnExit();
- this.writeFileSame();
- }
-
- protected void tearDown() throws Exception {
- if (null != this.fins) {
- this.fins.close();
- this.fins = null;
- }
- if (null != this.fouts) {
- this.fouts.close();
- this.fouts = null;
- }
-
- tmpFile.delete();
- super.tearDown();
-
- }
-
- private void writeFileSame() throws IOException {
- this.fouts = new FileOutputStream(tmpFile);
- byte[] bit = new byte[1];
- bit[0] = 80;
- this.fouts.write(bit);
- this.fouts.flush();
- String writebuf = ""; //$NON-NLS-1$
- for (int val = 0; val < this.writebufSize / 2; val++) {
- writebuf = writebuf + ((char) (val + 64));
- }
- this.fouts.write(writebuf.getBytes());
- }
-
- /*
- * This private method is to assert if the file size is the same as the
- * compare Number in the test
- */
- private void assertFileSizeSame(File fileToTest, int compareNumber)
- throws IOException {
- FileInputStream file = new FileInputStream(fileToTest);
- assertEquals(file.available(), compareNumber);
- file.close();
- }
-
- // test if new Channel to input is null
- public void testNewChannelInputStream_InputNull() throws IOException {
- ByteBuffer byteBuf = ByteBuffer.allocate(this.testNum);
- this.fins = null;
- int readres = this.testNum;
- try {
- ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
- assertNotNull(rbChannel);
- readres = rbChannel.read(byteBuf);
- fail();
- } catch (NullPointerException expected) {
- }
- assertEquals(this.testNum, readres);
- }
-
- // test if buffer to read is null
- public void testNewChannelInputStream_BufferNull() throws IOException {
- ByteBuffer byteBuf = ByteBuffer.allocate(this.testNum);
- int readres = this.testNum;
- this.fins = new FileInputStream(tmpFile);
- ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
- assertNotNull(rbChannel);
- try {
- readres = rbChannel.read(null);
- fail();
- } catch (NullPointerException e) {
- // correct
- }
- assertEquals(this.testNum, readres);
- readres = 0;
- try {
- readres = rbChannel.read(byteBuf);
- } catch (NullPointerException e) {
- fail();
- }
- assertEquals(this.testNum, readres);
- }
-
- /*
- * Test method for 'java.nio.channels.Channels.NewChannel'
- */
- public void testNewChannelInputStream() throws IOException {
- int bufSize = 10;
- int readres = 0;
- byte[] byteArray = new byte[bufSize];
- ByteBuffer byteBuf = ByteBuffer.allocate(bufSize);
- this.fins = new FileInputStream(tmpFile);
- readres = this.fins.read(byteArray);
-
- assertEquals(bufSize, readres);
- assertFalse(0 == this.fins.available());
-
- ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
- // fins still reads.
- assertFalse(0 == this.fins.available());
- readres = this.fins.read(byteArray);
- assertEquals(bufSize, readres);
-
- // rbChannel also reads.
- assertNotNull(rbChannel);
- readres = rbChannel.read(byteBuf);
-
- assertEquals(bufSize, readres);
- InputStream ins = Channels.newInputStream(rbChannel);
- assertNotNull(ins);
- assertEquals(0, ins.available());
- }
-
- // test if fout to change is null
- public void testNewChannelOutputStream_inputNull() throws IOException {
- int writeres = this.testNum;
- ByteBuffer writebuf = ByteBuffer.allocate(this.writebufSize);
- for (int val = 0; val < this.writebufSize / 2; val++) {
- writebuf.putChar((char) (val + 64));
- }
- this.fouts = null;
- try {
- WritableByteChannel rbChannel = Channels.newChannel(this.fouts);
- writeres = rbChannel.write(writebuf);
- assertEquals(0, writeres);
-
- writebuf.flip();
- writeres = rbChannel.write(writebuf);
- fail("Should throw NPE.");
- } catch (NullPointerException expected) {
- }
- }
-
- // test if write buf is null
- public void testNewChannelOutputStream_BufNull() throws IOException {
- int writeres = this.testNum;
- ByteBuffer writebuf = null;
- try {
- this.fouts = new FileOutputStream(tmpFile);
- } catch (FileNotFoundException e) {
- fail();
- }
-
- WritableByteChannel rbChannel = Channels.newChannel(this.fouts);
- try {
- writeres = rbChannel.write(writebuf);
- fail();
- } catch (NullPointerException e) {
- // correct
- }
- assertEquals(this.testNum, writeres);
- }
-
- /*
- * Test method for 'java.nio.channels.Channels.NewChannel(OutputStream)'
- */
- public void testNewChannelOutputStream() throws IOException {
- int writeNum = 0;
- ByteBuffer writebuf = ByteBuffer.allocateDirect(this.writebufSize);
- for (int val = 0; val < this.writebufSize / 2; val++) {
- writebuf.putChar((char) (val + 64));
- }
- this.fouts = new FileOutputStream(tmpFile);
- WritableByteChannel testChannel = this.fouts.getChannel();
- WritableByteChannel rbChannel = Channels.newChannel(this.fouts);
-
- assertTrue(testChannel.isOpen());
- assertTrue(rbChannel.isOpen());
-
- byte[] bit = new byte[1];
- bit[0] = 80;
- this.fouts.write(bit);
- this.fouts.flush();
- this.fins = new FileInputStream(tmpFile);
- assertEquals(this.fins.available(), 1);
- this.fins.close();
-
- writeNum = rbChannel.write(writebuf);
- // write success ,but output null
- assertEquals(0, writeNum);
- // close of fouts does not affect on channel
- this.fouts.close();
- writeNum = rbChannel.write(writebuf);
- assertEquals(0, writeNum);
- try {
- writeNum = testChannel.write(writebuf);
- fail();
- } catch (ClosedChannelException e) {
- // correct
- }
- assertEquals(0, writeNum);
- // close of rbchannel does affect on testchannel(same channel)
- rbChannel.close();
- try {
- writeNum = testChannel.write(writebuf);
- fail();
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testNewInputStreamReadableByteChannel_InputNull()
- throws Exception {
- byte[] readbuf = new byte[this.testNum];
- this.fins = new FileInputStream(tmpFile);
- ReadableByteChannel readbc = this.fins.getChannel();
- assertEquals(this.fileSize, this.fins.available());
- assertTrue(readbc.isOpen());
-
- try {
- InputStream testins = Channels.newInputStream(null);
- assertNotNull(testins);
- testins.read(readbuf);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testNewInputStreamReadableByteChannel() throws Exception {
- ByteBuffer readbcbuf = ByteBuffer.allocateDirect(this.testNum);
- byte[] readbuf = new byte[this.testNum];
- this.fins = new FileInputStream(tmpFile);
- ReadableByteChannel readbc = this.fins.getChannel();
- assertEquals(this.fileSize, this.fins.available());
- assertTrue(readbc.isOpen());
- InputStream testins = Channels.newInputStream(readbc);
- // read in testins and fins use the same pointer
- testins.read(readbuf);
- assertEquals(this.fins.available(), this.fileSize - this.testNum);
- int readNum = readbc.read(readbcbuf);
- assertEquals(readNum, this.testNum);
- assertEquals(this.fins.available(), this.fileSize - this.testNum * 2);
- testins.read(readbuf);
- assertEquals(this.fins.available(), this.fileSize - this.testNum * 3);
- // readbc.close() affect testins
- readbc.close();
- assertFalse(readbc.isOpen());
- try {
- testins.read(readbuf);
- fail();
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testNewOutputStreamWritableByteChannel_InputNull()
- throws Exception {
- byte[] writebuf = new byte[this.testNum];
- try {
- OutputStream testouts = Channels.newOutputStream(null);
- assertNotNull(testouts);
- testouts.write(writebuf);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- WritableByteChannel writebc = Channels.newChannel((OutputStream) null);
- assertTrue(writebc.isOpen());
- OutputStream testoutputS = Channels.newOutputStream(writebc);
- testoutputS.write(writebuf);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testNewOutputStreamWritableByteChannel() throws Exception {
- byte[] writebuf = new byte[this.testNum];
- ByteBuffer writebcbuf = ByteBuffer.allocateDirect(this.testNum);
- this.fouts = new FileOutputStream(tmpFile);
- WritableByteChannel writebc = this.fouts.getChannel();
-
- assertTrue(writebc.isOpen());
- OutputStream testouts = Channels.newOutputStream(writebc);
-
- // read in testins and fins use the same pointer
- testouts.write(writebuf);
- this.assertFileSizeSame(tmpFile, this.testNum);
- writebc.write(writebcbuf);
- this.assertFileSizeSame(tmpFile, this.testNum * 2);
- testouts.write(writebuf);
- this.assertFileSizeSame(tmpFile, this.testNum * 3);
- // readbc.close() affect testins
- writebc.close();
- assertFalse(writebc.isOpen());
- try {
- testouts.write(writebuf);
- fail();
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testnewReaderCharsetError() throws Exception {
- this.fins = new FileInputStream(tmpFile);
-
- ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
- try {
- Channels.newReader(rbChannel, Charset.forName(BAD_CODE_SET)
- .newDecoder(), //$NON-NLS-1$
- -1);
- fail();
- } catch (UnsupportedCharsetException e) {
- // correct
- }
- }
-
- public void testnewWriterCharsetError() throws Exception {
- this.fouts = new FileOutputStream(tmpFile);
- WritableByteChannel wbChannel = Channels.newChannel(this.fouts);
- try {
- Channels.newWriter(wbChannel, Charset.forName(BAD_CODE_SET)
- .newEncoder(), -1);
- fail();
- } catch (UnsupportedCharsetException e) {
- // correct
- }
- }
-
- /*
- * Test method for
- * 'java.nio.channels.Channels.newReader(ReadableByteChannel, String)'
- */
- public void testNewReaderReadableByteChannelString_InputNull()
- throws IOException {
- int bufSize = this.testNum;
- int readres = 0;
- CharBuffer charBuf = CharBuffer.allocate(bufSize);
- this.fins = new FileInputStream(tmpFile);
- // channel null
- Reader testReader;
- try {
- testReader = Channels.newReader(null, Charset.forName(CODE_SET).newDecoder(), -1);
- assertNotNull(testReader);
- assertFalse(testReader.ready());
- readres = testReader.read((CharBuffer) null);
- fail();
- } catch (NullPointerException e) {
- // correct
- }
- assertEquals(0, readres);
-
- this.fins = null;
- // channel with null inputs
- try {
- ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
- testReader = Channels.newReader(rbChannel, Charset.forName(CODE_SET).newDecoder(), -1);
- assertNotNull(testReader);
- assertFalse(testReader.ready());
- readres = testReader.read(charBuf);
- fail();
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- /*
- * Test method for
- * 'java.nio.channels.Channels.newReader(ReadableByteChannel, String)'
- */
- public void testNewReaderReadableByteChannelString_internalBufferZero()
- throws IOException {
- int bufSize = this.testNum;
- int readres = 0;
- CharBuffer charBuf = CharBuffer.allocate(bufSize);
- this.fins = new FileInputStream(tmpFile);
- // channel null
- Reader testReader;
- try {
- testReader = Channels.newReader(null, Charset.forName(CODE_SET).newDecoder(), 0);
- assertNotNull(testReader);
- assertFalse(testReader.ready());
- readres = testReader.read((CharBuffer) null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertEquals(0, readres);
-
- this.fins = null;
- // channel with null inputs
- try {
- ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
- testReader = Channels.newReader(rbChannel, Charset.forName(CODE_SET).newDecoder(), -1);
- assertNotNull(testReader);
- assertFalse(testReader.ready());
- readres = testReader.read(charBuf);
- fail();
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- /*
- * Test method for
- * 'java.nio.channels.Channels.newReader(ReadableByteChannel, String)'
- */
- public void testNewReaderReadableByteChannelString() throws IOException {
- int bufSize = this.testNum;
- int readres = 0;
- CharBuffer charBuf = CharBuffer.allocate(bufSize);
- this.fins = new FileInputStream(tmpFile);
- ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
- Reader testReader = Channels.newReader(rbChannel, Charset.forName(
- CODE_SET).newDecoder(), //$NON-NLS-1$
- -1);
- Reader testReader_s = Channels.newReader(rbChannel, CODE_SET); //$NON-NLS-1$
-
- assertEquals(this.fileSize, this.fins.available());
- // not ready...
- assertFalse(testReader.ready());
- assertFalse(testReader_s.ready());
- // still reads
- readres = testReader.read(charBuf);
- assertEquals(bufSize, readres);
- assertEquals(0, this.fins.available());
-
- try {
- readres = testReader.read((CharBuffer) null);
- fail();
- } catch (NullPointerException e) {
- // correct
- }
-
- readres = testReader_s.read(charBuf);
- assertEquals(0, readres);
- assertTrue(testReader.ready());
- assertFalse(testReader_s.ready());
- }
-
- /*
- * Zero-Buffer
- */
- public void testNewWriterWritableByteChannelString_internalBufZero()
- throws IOException {
-
- String writebuf = ""; //$NON-NLS-1$
- for (int val = 0; val < this.writebufSize / 2; val++) {
- writebuf = writebuf + ((char) (val + 64));
- }
- // null channel
- try {
- Writer testWriter = Channels.newWriter(null, Charset.forName(CODE_SET).newEncoder(), -1);
- } catch (NullPointerException expected) {
- }
-
- // channel with null input
- this.fouts = null;
- try {
- WritableByteChannel wbChannel = Channels.newChannel(this.fouts);
- } catch (NullPointerException expected) {
- }
- }
-
- /*
- * this test cannot be passed when buffer set to 0!
- */
- public void testNewWriterWritableByteChannelString_InputNull()
- throws IOException {
- this.fouts = new FileOutputStream(tmpFile);
- WritableByteChannel wbChannel = Channels.newChannel(this.fouts);
- Writer testWriter = Channels.newWriter(wbChannel, Charset.forName(
- CODE_SET).newEncoder(), //$NON-NLS-1$
- 1);
-
- String writebuf = ""; //$NON-NLS-1$
- for (int val = 0; val < this.writebufSize / 2; val++) {
- writebuf = writebuf + ((char) (val + 64));
- }
- // can write to buffer
- testWriter.write(writebuf);
- testWriter.flush();
- testWriter.close();
-
- }
-
- /*
- * Test method for
- * 'java.nio.channels.Channels.newWriter(WritableByteChannel, String)'
- */
- public void testNewWriterWritableByteChannelString() throws IOException {
- this.fouts = new FileOutputStream(tmpFile);
- WritableByteChannel wbChannel = Channels.newChannel(this.fouts);
- Writer testWriter = Channels.newWriter(wbChannel, CODE_SET); //$NON-NLS-1$
- Writer testWriter_s = Channels.newWriter(wbChannel, Charset.forName(
- CODE_SET).newEncoder(), //$NON-NLS-1$
- -1);
-
- String writebuf = ""; //$NON-NLS-1$
- for (int val = 0; val < this.writebufSize / 2; val++) {
- writebuf = writebuf + ((char) (val + 64));
- }
- byte[] bit = new byte[1];
- bit[0] = 80;
- this.fouts.write(bit);
- this.assertFileSizeSame(tmpFile, 1);
-
- // writer continues to write after '1',what the fouts write
- testWriter.write(writebuf);
- testWriter.flush();
- this.assertFileSizeSame(tmpFile, this.writebufSize / 2 + 1);
- // testwriter_s does not know if testwrite writes
- testWriter_s.write(writebuf);
- testWriter.flush();
- this.assertFileSizeSame(tmpFile, this.writebufSize / 2 + 1);
- // testwriter_s even does not know if himself writes?
- testWriter_s.write(writebuf);
- testWriter.flush();
- this.assertFileSizeSame(tmpFile, this.writebufSize / 2 + 1);
-
- // close the fouts, no longer writable for testWriter
- for (int val = 0; val < this.writebufSize; val++) {
- writebuf = writebuf + ((char) (val + 64));
- }
- this.fouts.close();
- testWriter_s.write(writebuf);
- testWriter.flush();
- this.assertFileSizeSame(tmpFile, this.writebufSize / 2 + 1);
- }
-
- /**
- * @tests java.nio.channels.Channels#newReader(ReadableByteChannel channel,
- * String charsetName)
- */
- public void test_newReader_LReadableByteChannel_LString()
- throws IOException {
- InetSocketAddress localAddr = new InetSocketAddress("127.0.0.1",
- Support_PortManager.getNextPort());
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(localAddr);
-
- SocketChannel sc = SocketChannel.open();
- sc.connect(localAddr);
- sc.configureBlocking(false);
- assertFalse(sc.isBlocking());
-
- ssc.accept().close();
- ssc.close();
- assertFalse(sc.isBlocking());
-
- Reader reader = Channels.newReader(sc, "UTF16");
- try {
- int i = reader.read();
- fail("should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException expected) {
- }
-
- try {
- Channels.newInputStream(sc).read();
- fail("should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException expected) {
- }
-
- sc.close();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.java
deleted file mode 100644
index aba37ec..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.ClosedByInterruptException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for ClosedByInterruptException
- */
-public class ClosedByInterruptExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.ClosedByInterruptException#ClosedByInterruptException()}
- */
- public void test_Constructor() {
- ClosedByInterruptException e = new ClosedByInterruptException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new ClosedByInterruptException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new ClosedByInterruptException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.java
deleted file mode 100644
index 3ba322f..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.ClosedChannelException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for ClosedChannelException
- */
-public class ClosedChannelExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.ClosedChannelException#ClosedChannelException()}
- */
- public void test_Constructor() {
- ClosedChannelException e = new ClosedChannelException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new ClosedChannelException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new ClosedChannelException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.java
deleted file mode 100644
index 745d697..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.ClosedSelectorException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for ClosedSelectorException
- */
-public class ClosedSelectorExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.ClosedSelectorException#ClosedSelectorException()}
- */
- public void test_Constructor() {
- ClosedSelectorException e = new ClosedSelectorException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new ClosedSelectorException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new ClosedSelectorException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.java
deleted file mode 100644
index 0e909ba..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.ConnectionPendingException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for ConnectionPendingException
- */
-public class ConnectionPendingExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.ConnectionPendingException#ConnectionPendingException()}
- */
- public void test_Constructor() {
- ConnectionPendingException e = new ConnectionPendingException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new ConnectionPendingException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new ConnectionPendingException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/DatagramChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/DatagramChannelTest.java
deleted file mode 100644
index cff718e..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/DatagramChannelTest.java
+++ /dev/null
@@ -1,2557 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.IllegalBlockingModeException;
-import java.nio.channels.NotYetConnectedException;
-import java.nio.channels.UnresolvedAddressException;
-import java.nio.channels.UnsupportedAddressTypeException;
-import java.nio.channels.spi.SelectorProvider;
-import java.security.Permission;
-
-import junit.framework.TestCase;
-import tests.support.Support_PortManager;
-
-/**
- * Test for DatagramChannel
- *
- */
-public class DatagramChannelTest extends TestCase {
-
- private static final int CAPACITY_NORMAL = 200;
-
- private static final int CAPACITY_1KB = 1024;
-
- private static final int CAPACITY_64KB = 65536;
-
- private static final int CAPACITY_ZERO = 0;
-
- private static final int CAPACITY_ONE = 1;
-
- private static final int TIME_UNIT = 500;
-
- private InetSocketAddress localAddr1;
-
- private InetSocketAddress localAddr2;
-
- private DatagramChannel channel1;
-
- private DatagramChannel channel2;
-
- private DatagramSocket datagramSocket1;
-
- private DatagramSocket datagramSocket2;
-
- // The port to be used in test cases.
- private int testPort;
-
- protected void setUp() throws Exception {
- super.setUp();
- this.channel1 = DatagramChannel.open();
- this.channel2 = DatagramChannel.open();
- int[] ports = Support_PortManager.getNextPortsForUDP(5);
- this.localAddr1 = new InetSocketAddress("127.0.0.1", ports[0]);
- this.localAddr2 = new InetSocketAddress("127.0.0.1", ports[1]);
- this.datagramSocket1 = new DatagramSocket(ports[2]);
- this.datagramSocket2 = new DatagramSocket(ports[3]);
- testPort = ports[4];
- }
-
- protected void tearDown() throws Exception {
- if (null != this.channel1) {
- try {
- this.channel1.close();
- } catch (Exception e) {
- //ignore
- }
- }
- if (null != this.channel2) {
- try {
- this.channel2.close();
- } catch (Exception e) {
- //ignore
- }
- }
- if (null != this.datagramSocket1) {
- try {
- this.datagramSocket1.close();
- } catch (Exception e) {
- //ignore
- }
- }
- if (null != this.datagramSocket2) {
- try {
- this.datagramSocket2.close();
- } catch (Exception e) {
- //ignore
- }
- }
- localAddr1 = null;
- localAddr2 = null;
- super.tearDown();
- }
-
- // -------------------------------------------------------------------
- // Test for methods in abstract class.
- // -------------------------------------------------------------------
- /*
- * Test method for 'java.nio.channels.DatagramChannel.validOps()'
- */
- public void testValidOps() {
- MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
- .provider());
- MockDatagramChannel testMocknull = new MockDatagramChannel(null);
- int val = this.channel1.validOps();
- assertEquals(5, val);
- assertEquals(val, testMock.validOps());
- assertEquals(val, testMocknull.validOps());
- }
-
- /*
- * Test method for 'java.nio.channels.DatagramChannel.open()'
- */
- public void testOpen() {
- MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
- .provider());
- MockDatagramChannel testMocknull = new MockDatagramChannel(null);
- assertNull(testMocknull.provider());
- assertNotNull(testMock.provider());
- assertEquals(this.channel1.provider(), testMock.provider());
- assertEquals(5, testMock.validOps());
- }
-
- /*
- * Test method for 'java.nio.channels.DatagramChannel.read(ByteBuffer)'
- */
- public void testReadByteBufferArray() throws IOException {
- final int testNum = 0;
- long readres = testNum;
- MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
- .provider());
- MockDatagramChannel testMocknull = new MockDatagramChannel(null);
- int bufSize = 10;
- ByteBuffer[] readBuf = null;
- try {
- this.channel1.read(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- readres = testMock.read(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- readBuf = new ByteBuffer[bufSize];
- try {
- readres = this.channel1.read(readBuf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- readres = testMock.read(readBuf);
- assertEquals(testNum, readres);
- readres = testMocknull.read(readBuf);
- assertEquals(testNum, readres);
- }
-
- /*
- * Test method for 'java.nio.channels.DatagramChannel.read(ByteBuffer)'
- */
- public void testReadByteBufferArray_BufNull() throws IOException {
- MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
- .provider());
- MockDatagramChannel testMocknull = new MockDatagramChannel(null);
-
- ByteBuffer[] readBuf = null;
- try {
- this.channel1.read(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMock.read(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMocknull.read(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- /*
- * Test method for 'java.nio.channels.DatagramChannel.write(ByteBuffer)'
- */
- public void testWriteByteBuffer() throws IOException {
- MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
- .provider());
- MockDatagramChannel testMocknull = new MockDatagramChannel(null);
- int bufSize = 10;
- ByteBuffer[] readBuf = null;
- try {
- this.channel1.write(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMock.write(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- readBuf = new ByteBuffer[bufSize];
- try {
- this.channel1.write(readBuf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- long writeres = 0;
- writeres = testMock.write(readBuf);
-
- assertEquals(0, writeres);
- writeres = testMocknull.write(readBuf);
- assertEquals(0, writeres);
- }
-
- /*
- * Test method for 'java.nio.channels.DatagramChannel.write(ByteBuffer)'
- */
- public void testWriteByteBuffer_Bufnull() throws IOException {
- MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
- .provider());
- MockDatagramChannel testMocknull = new MockDatagramChannel(null);
- ByteBuffer[] readBuf = null;
- try {
- this.channel1.write(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMock.write(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMocknull.write(readBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- // -------------------------------------------------------------------
- // Test for socket()
- // -------------------------------------------------------------------
-
- /**
- * Test method for 'DatagramChannelImpl.socket()'
- *
- * @throws SocketException
- */
- public void testSocket_BasicStatusBeforeConnect() throws SocketException {
- assertFalse(this.channel1.isConnected());// not connected
- DatagramSocket s1 = this.channel1.socket();
- assertSocketBeforeConnect(s1);
- DatagramSocket s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
-
- /**
- * Test method for 'DatagramChannelImpl.socket()'
- *
- * @throws IOException
- */
- public void testSocket_Block_BasicStatusAfterConnect() throws IOException {
- this.channel1.connect(localAddr1);
- DatagramSocket s1 = this.channel1.socket();
- assertSocketAfterConnect(s1);
- DatagramSocket s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
-
- public void testSocket_NonBlock_BasicStatusAfterConnect()
- throws IOException {
- this.channel1.connect(localAddr1);
- this.channel1.configureBlocking(false);
- DatagramSocket s1 = this.channel1.socket();
- assertSocketAfterConnect(s1);
- DatagramSocket s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
-
- /**
- * Test method for 'DatagramChannelImpl.socket()'
- *
- * @throws IOException
- */
- public void testSocket_ActionsBeforeConnect() throws IOException {
- assertFalse(this.channel1.isConnected());// not connected
- DatagramSocket s = this.channel1.socket();
- assertSocketActionBeforeConnect(s);
- }
-
- /**
- * Test method for 'DatagramChannelImpl.socket()'
- *
- * @throws IOException
- */
- public void testSocket_Block_ActionsAfterConnect() throws IOException {
- assertFalse(this.channel1.isConnected());// not connected
- this.channel1.connect(localAddr1);
- DatagramSocket s = this.channel1.socket();
- assertSocketActionAfterConnect(s);
- }
-
- public void testSocket_NonBlock_ActionsAfterConnect() throws IOException {
- this.channel1.connect(localAddr1);
- this.channel1.configureBlocking(false);
- DatagramSocket s = this.channel1.socket();
- assertSocketActionAfterConnect(s);
- }
-
- private void assertSocketBeforeConnect(DatagramSocket s)
- throws SocketException {
- assertFalse(s.isBound());
- assertFalse(s.isClosed());
- assertFalse(s.isConnected());
- assertFalse(s.getBroadcast());
- assertFalse(s.getReuseAddress());
- assertNull(s.getInetAddress());
- assertTrue(s.getLocalAddress().isAnyLocalAddress());
- assertEquals(s.getLocalPort(), 0);
- assertNull(s.getLocalSocketAddress());
- assertEquals(s.getPort(), -1);
- assertTrue(s.getReceiveBufferSize() >= 8192);
- assertNull(s.getRemoteSocketAddress());
- assertFalse(s.getReuseAddress());
- assertTrue(s.getSendBufferSize() >= 8192);
- assertEquals(s.getSoTimeout(), 0);
- assertEquals(s.getTrafficClass(), 0);
- }
-
- private void assertSocketAfterConnect(DatagramSocket s)
- throws SocketException {
- assertTrue(s.isBound());
- assertFalse(s.isClosed());
- assertTrue(s.isConnected());
- assertFalse(s.getBroadcast());
- assertFalse(s.getReuseAddress());
- assertSame(s.getInetAddress(), localAddr1.getAddress());
- assertEquals(s.getLocalAddress(), localAddr1.getAddress());
- assertNotNull(s.getLocalSocketAddress());
- assertEquals(s.getPort(), localAddr1.getPort());
- assertTrue(s.getReceiveBufferSize() >= 8192);
- // not same , but equals
- assertNotSame(s.getRemoteSocketAddress(), (SocketAddress) localAddr1);
- assertEquals(s.getRemoteSocketAddress(), (SocketAddress) localAddr1);
- assertFalse(s.getReuseAddress());
- assertTrue(s.getSendBufferSize() >= 8192);
- assertEquals(s.getSoTimeout(), 0);
- assertEquals(s.getTrafficClass(), 0);
- }
-
- private void assertSocketActionBeforeConnect(DatagramSocket s)
- throws IOException {
- s.connect(localAddr2);
- assertFalse(this.channel1.isConnected());
- assertFalse(s.isConnected());
-
- s.disconnect();
- assertFalse(this.channel1.isConnected());
- assertFalse(s.isConnected());
-
- s.close();
- assertTrue(s.isClosed());
- assertFalse(this.channel1.isOpen());
- }
-
- private void assertSocketActionAfterConnect(DatagramSocket s)
- throws IOException {
- assertEquals(s.getPort(), localAddr1.getPort());
- s.connect(localAddr2);
- assertTrue(this.channel1.isConnected());
- assertTrue(s.isConnected());
- // not changed
- assertEquals(s.getPort(), localAddr1.getPort());
-
- s.disconnect();
- assertFalse(this.channel1.isConnected());
- assertFalse(s.isConnected());
-
- s.close();
- assertTrue(s.isClosed());
- assertFalse(this.channel1.isOpen());
- }
-
- // -------------------------------------------------------------------
- // Test for configureBlocking()
- // -------------------------------------------------------------------
-
- public void testConfigureBlocking_Read() throws Exception {
- assertTrue(this.channel1.isBlocking());
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_1KB);
- new Thread() {
- public void run() {
- try {
- sleep(TIME_UNIT * 5);
- channel1.configureBlocking(false);
- assertFalse(channel1.isBlocking());
- datagramSocket1.close();
- } catch (Exception e) {
- // do nothing
- }
- }
- }.start();
- SocketAddress addr = channel1.receive(buf);
- assertNull(addr);
- }
-
- // -------------------------------------------------------------------
- // Test for isConnected()
- // -------------------------------------------------------------------
-
- /**
- * Test method for 'DatagramChannelImpl.isConnected()'
- *
- * @throws IOException
- */
- public void testIsConnected_WithServer() throws IOException {
- connectLocalServer();
- disconnectAfterConnected();
- this.datagramSocket1.close();
- this.channel1.close();
- assertFalse(this.channel1.isConnected());
- }
-
- // -------------------------------------------------------------------
- // Test for connect()
- // -------------------------------------------------------------------
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- */
- public void testConnect_BlockWithServer() throws IOException {
- // blocking mode
- assertTrue(this.channel1.isBlocking());
- connectLocalServer();
- datagramSocket1.close();
- disconnectAfterConnected();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- */
- public void testConnect_BlockNoServer() throws IOException {
- connectWithoutServer();
- disconnectAfterConnected();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- *
- * @throws IOException
- */
- public void testConnect_NonBlockWithServer() throws IOException {
- // Non blocking mode
- this.channel1.configureBlocking(false);
- connectLocalServer();
- datagramSocket1.close();
- disconnectAfterConnected();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- *
- * @throws IOException
- */
- public void testConnect_Null() throws IOException {
- assertFalse(this.channel1.isConnected());
- try {
- this.channel1.connect(null);
- fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- *
- * @throws IOException
- */
- public void testConnect_UnsupportedType() throws IOException {
- assertFalse(this.channel1.isConnected());
- class SubSocketAddress extends SocketAddress {
- private static final long serialVersionUID = 1L;
-
- public SubSocketAddress() {
- super();
- }
- }
- SocketAddress newTypeAddress = new SubSocketAddress();
- try {
- this.channel1.connect(newTypeAddress);
- fail("Should throw an UnsupportedAddressTypeException here.");
- } catch (UnsupportedAddressTypeException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- *
- * @throws IOException
- */
- public void testConnect_Unresolved() throws IOException {
- assertFalse(this.channel1.isConnected());
- InetSocketAddress unresolved = new InetSocketAddress(
- "unresolved address", 1080);
- try {
- this.channel1.connect(unresolved);
- fail("Should throw an UnresolvedAddressException here."); //$NON-NLS-1$
- } catch (UnresolvedAddressException e) {
- // OK.
- }
- }
-
- public void testConnect_EmptyHost() throws Exception {
- assertFalse(this.channel1.isConnected());
-
- assertEquals(this.channel1, this.channel1
- .connect(new InetSocketAddress("", 1081))); //$NON-NLS-1$
-
- }
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- *
- * @throws IOException
- *
- */
- public void testConnect_ClosedChannelException() throws IOException {
- assertFalse(this.channel1.isConnected());
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw ClosedChannelException."); //$NON-NLS-1$
- } catch (ClosedChannelException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- *
- * @throws IOException
- *
- */
- public void testConnect_IllegalStateException() throws IOException {
- assertFalse(this.channel1.isConnected());
- this.channel1.connect(localAddr1);
- assertTrue(this.channel1.isConnected());
- // connect after connected.
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw IllegalStateException."); //$NON-NLS-1$
- } catch (IllegalStateException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
- *
- * @throws IOException
- *
- */
- public void testConnect_CheckOpenBeforeStatus() throws IOException {
- assertFalse(this.channel1.isConnected());
- this.channel1.connect(localAddr1);
- assertTrue(this.channel1.isConnected());
- // connect after connected.
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- // checking open is before checking status.
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw ClosedChannelException."); //$NON-NLS-1$
- } catch (ClosedChannelException e) {
- // OK.
- }
- }
-
- private void disconnectAfterConnected() throws IOException {
- assertTrue(this.channel1.isConnected());
- this.channel1.disconnect();
- assertFalse(this.channel1.isConnected());
- }
-
- private void disconnectAfterClosed() throws IOException {
- assertFalse(this.channel1.isOpen());
- assertFalse(this.channel1.isConnected());
- this.channel1.disconnect();
- assertFalse(this.channel1.isConnected());
- }
-
- private void connectLocalServer() throws IOException {
- assertFalse(this.channel1.isConnected());
- assertTrue(this.datagramSocket1.isBound());
- assertSame(this.channel1, this.channel1.connect(localAddr1));
- assertTrue(this.channel1.isConnected());
- }
-
- private void connectWithoutServer() throws IOException {
- assertFalse(this.channel1.isConnected());
- this.datagramSocket1.close();
- assertTrue(this.datagramSocket1.isClosed());
- assertSame(this.channel1, this.channel1.connect(localAddr1));
- assertTrue(this.channel1.isConnected());
- }
-
- // -------------------------------------------------------------------
- // Test for disconnect()
- // -------------------------------------------------------------------
-
- /**
- * Test method for 'DatagramChannelImpl.disconnect()'
- *
- * @throws IOException
- */
- public void testDisconnect_BeforeConnect() throws IOException {
- assertFalse(this.channel1.isConnected());
- assertEquals(this.channel1, this.channel1.disconnect());
- assertFalse(this.channel1.isConnected());
- }
-
- /**
- * Test method for 'DatagramChannelImpl.disconnect()'
- *
- * @throws IOException
- */
- public void testDisconnect_UnconnectedClosed() throws IOException {
- assertFalse(this.channel1.isConnected());
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- assertEquals(this.channel1, this.channel1.disconnect());
- assertFalse(this.channel1.isConnected());
- }
-
- /**
- * Test method for 'DatagramChannelImpl.disconnect()'
- *
- * @throws IOException
- */
- public void testDisconnect_BlockWithServerChannelClosed()
- throws IOException {
- assertTrue(this.channel1.isBlocking());
- connectLocalServer();
- // disconnect after channel close
- this.channel1.close();
- disconnectAfterClosed();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.disconnect()'
- *
- * @throws IOException
- */
- public void testDisconnect_NonBlockWithServerChannelClosed()
- throws IOException {
- this.channel1.configureBlocking(false);
- connectLocalServer();
- // disconnect after channel close
- this.channel1.close();
- disconnectAfterClosed();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.disconnect()'
- *
- * @throws IOException
- */
- public void testDisconnect_BlockWithServerServerClosed() throws IOException {
- assertTrue(this.channel1.isBlocking());
- connectLocalServer();
- // disconnect after server close
- this.datagramSocket1.close();
- assertTrue(this.channel1.isOpen());
- assertTrue(this.channel1.isConnected());
- disconnectAfterConnected();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.disconnect()'
- *
- * @throws IOException
- */
- public void testDisconnect_NonBlockWithServerServerClosed()
- throws IOException {
- this.channel1.configureBlocking(false);
- assertFalse(this.channel1.isBlocking());
- connectLocalServer();
- // disconnect after server close
- this.datagramSocket1.close();
- assertTrue(this.channel1.isOpen());
- assertTrue(this.channel1.isConnected());
- disconnectAfterConnected();
- }
-
- // -------------------------------------------------------------------
- // Test for receive(): Behavior Without Server.
- // -------------------------------------------------------------------
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedNull() throws Exception {
- assertFalse(this.channel1.isConnected());
- try {
- this.channel1.receive(null);
- fail("Should throw a NPE here."); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedReadonly() throws Exception {
- assertFalse(this.channel1.isConnected());
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
- .asReadOnlyBuffer();
- assertTrue(dst.isReadOnly());
- try {
- this.channel1.receive(dst);
- fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedBufEmpty() throws Exception {
- this.channel1.configureBlocking(false);
- assertFalse(this.channel1.isConnected());
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- assertNull(this.channel1.receive(dst));
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedBufZero() throws Exception {
- assertFalse(this.channel1.isConnected());
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ZERO);
- assertNull(this.channel1.receive(dst));
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedBufNotEmpty() throws Exception {
- assertFalse(this.channel1.isConnected());
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- // buf is not empty
- dst.put((byte) 88);
- assertEquals(dst.position() + CAPACITY_NORMAL - 1, dst.limit());
- assertNull(this.channel1.receive(dst));
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedBufFull() throws Exception {
- assertFalse(this.channel1.isConnected());
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ONE);
- // buf is full
- dst.put((byte) 88);
- assertEquals(dst.position(), dst.limit());
- assertNull(this.channel1.receive(dst));
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedClose() throws Exception {
- assertFalse(this.channel1.isConnected());
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- try {
- assertNull(this.channel1.receive(dst));
- fail("Should throw a ClosedChannelException here."); //$NON-NLS-1$
- } catch (ClosedChannelException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedCloseNull() throws Exception {
- assertFalse(this.channel1.isConnected());
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- // checking buffer before checking open
- try {
- this.channel1.receive(null);
- fail("Should throw a NPE here."); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_UnconnectedCloseReadonly() throws Exception {
- assertFalse(this.channel1.isConnected());
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
- .asReadOnlyBuffer();
- assertTrue(dst.isReadOnly());
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- try {
- this.channel1.receive(dst);
- fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // OK.
- }
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerBufEmpty() throws Exception {
- this.channel1.configureBlocking(false);
- receiveNonBlockNoServer(CAPACITY_NORMAL);
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_BlockNoServerNull() throws Exception {
- assertTrue(this.channel1.isBlocking());
- receiveNoServerNull();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerNull() throws Exception {
- this.channel1.configureBlocking(false);
- receiveNoServerNull();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_BlockNoServerReadonly() throws Exception {
- assertTrue(this.channel1.isBlocking());
- receiveNoServerReadonly();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerReadonly() throws Exception {
- this.channel1.configureBlocking(false);
- receiveNoServerReadonly();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerBufZero() throws Exception {
- this.channel1.configureBlocking(false);
- receiveNonBlockNoServer(CAPACITY_ZERO);
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerBufNotEmpty() throws Exception {
- this.channel1.configureBlocking(false);
- connectWithoutServer();
- ByteBuffer dst = allocateNonEmptyBuf();
- assertNull(this.channel1.receive(dst));
- }
-
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerBufFull() throws Exception {
- this.channel1.configureBlocking(false);
- connectWithoutServer();
- ByteBuffer dst = allocateFullBuf();
- assertNull(this.channel1.receive(dst));
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_BlockNoServerChannelClose() throws Exception {
- assertTrue(this.channel1.isBlocking());
- receiveNoServerChannelClose();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerChannelClose() throws Exception {
- this.channel1.configureBlocking(false);
- receiveNoServerChannelClose();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_BlockNoServerCloseNull() throws Exception {
- assertTrue(this.channel1.isBlocking());
- receiveNoServerChannelCloseNull();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerCloseNull() throws Exception {
- this.channel1.configureBlocking(false);
- receiveNoServerChannelCloseNull();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_NonBlockNoServerCloseReadonly() throws Exception {
- this.channel1.configureBlocking(false);
- receiveNoServerChannelCloseReadonly();
- }
-
- /**
- * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
- *
- * @throws Exception
- */
- public void testReceive_BlockNoServerCloseReadonly() throws Exception {
- assertTrue(this.channel1.isBlocking());
- receiveNoServerChannelCloseReadonly();
- }
-
- private void receiveNoServerNull() throws IOException {
- connectWithoutServer();
- try {
- this.channel1.receive(null);
- fail("Should throw a NPE here."); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // OK.
- }
- }
-
- private void receiveNoServerReadonly() throws IOException {
- connectWithoutServer();
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
- .asReadOnlyBuffer();
- assertTrue(dst.isReadOnly());
- try {
- this.channel1.receive(dst);
- fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // OK.
- }
- }
-
- private void receiveNonBlockNoServer(int size) throws IOException {
- connectWithoutServer();
- ByteBuffer dst = ByteBuffer.allocateDirect(size);
- assertNull(this.channel1.receive(dst));
- }
-
- private void receiveNoServerChannelClose() throws IOException {
- connectWithoutServer();
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- try {
- assertNull(this.channel1.receive(dst));
- fail("Should throw a ClosedChannelException here."); //$NON-NLS-1$
- } catch (ClosedChannelException e) {
- // OK.
- }
- }
-
- private void receiveNoServerChannelCloseNull() throws IOException {
- connectWithoutServer();
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- try {
- this.channel1.receive(null);
- fail("Should throw a NPE here."); //$NON-NLS-1$
- } catch (NullPointerException e) {
- // OK.
- }
- }
-
- private void receiveNoServerChannelCloseReadonly() throws IOException {
- connectWithoutServer();
- this.channel1.close();
- assertFalse(this.channel1.isOpen());
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
- .asReadOnlyBuffer();
- assertTrue(dst.isReadOnly());
- try {
- this.channel1.receive(dst);
- fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // OK.
- }
- }
-
- private ByteBuffer allocateFullBuf() {
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ONE);
- // buf is full
- dst.put((byte) 88);
- assertEquals(dst.position(), dst.limit());
- return dst;
- }
-
- private ByteBuffer allocateNonEmptyBuf() {
- ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- // buf is not empty
- dst.put((byte) 88);
- dst.put((byte) 99);
- assertEquals(dst.position() + CAPACITY_NORMAL - 2, dst.limit());
- return dst;
- }
-
- // -------------------------------------------------------------------
- // Test for send(): Behavior without server.
- // -------------------------------------------------------------------
-
- private void sendDataBlocking(InetSocketAddress addr, ByteBuffer writeBuf)
- throws IOException {
- InetSocketAddress ipAddr = addr;
- assertEquals(CAPACITY_NORMAL, this.channel1.send(writeBuf, ipAddr));
- assertTrue(this.channel1.isOpen());
- assertTrue(this.channel1.isBlocking());
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- }
-
- private void sendDataNonBlocking(InetSocketAddress addr, ByteBuffer writeBuf)
- throws IOException {
- InetSocketAddress ipAddr = addr;
- this.channel1.configureBlocking(false);
- assertEquals(CAPACITY_NORMAL, this.channel1.send(writeBuf, ipAddr));
- assertTrue(this.channel1.isOpen());
- assertFalse(this.channel1.isBlocking());
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- }
-
- /*
- * Test method for 'DatagramChannelImpl.send(ByteBuffer, SocketAddress)'
- */
- public void testSend_NoServerBlockingCommon() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- sendDataBlocking(localAddr1, writeBuf);
- }
-
- public void testSend_NoServerNonblockingCommon() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- sendDataNonBlocking(localAddr1, writeBuf);
- }
-
- public void testSend_NoServerTwice() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- sendDataBlocking(localAddr1, writeBuf);
- // can not buffer twice!
- assertEquals(0, this.channel1.send(writeBuf, localAddr1));
- try {
- channel1.send(writeBuf, localAddr2);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // correct
- }
- }
-
- public void testSend_NoServerNonBlockingTwice() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- sendDataNonBlocking(localAddr1, writeBuf);
- // can not buffer twice!
- assertEquals(0, this.channel1.send(writeBuf, localAddr1));
- try {
- channel1.send(writeBuf, localAddr2);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // correct
- }
- }
-
- public void testSend_NoServerBufNull() throws IOException {
- try {
- sendDataBlocking(localAddr1, null);
- fail("Should throw a NPE here.");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- public void testSend_NoServerBufNullTwice() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- try {
- sendDataBlocking(localAddr1, null);
- fail("Should throw a NPE here.");
- } catch (NullPointerException e) {
- // correct
- }
- sendDataBlocking(localAddr1, writeBuf);
- try {
- channel1.send(null, localAddr2);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- public void testSend_NoServerAddrNull() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- try {
- sendDataBlocking(null, writeBuf);
- fail("Should throw a NPE here.");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- public void testSend_NoServerAddrNullTwice() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- try {
- sendDataBlocking(null, writeBuf);
- fail("Should throw a NPE here.");
- } catch (NullPointerException e) {
- // correct
- }
- sendDataBlocking(localAddr1, writeBuf);
- try {
- channel1.send(writeBuf, null);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- // -------------------------------------------------------------------
- // Test for receive()and send(): Send and Receive with Real Data
- // -------------------------------------------------------------------
-
- public void testReceiveSend_Block_Normal() throws Exception {
- this.channel1.socket().bind(localAddr2);
- sendByChannel("some normal string in testReceiveSend_Normal",
- localAddr2);
- receiveByChannel(CAPACITY_NORMAL, localAddr2,
- "some normal string in testReceiveSend_Normal");
- }
-
- public void testReceiveSend_Block_NotBound() throws Exception {
- // not bound
- sendByChannel("some normal string in testReceiveSend_Normal",
- localAddr2);
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
- assertNull(channel1.receive(buf));
- assertFalse(channel1.socket().isBound());
- }
-
- public void testReceiveSend_NonBlock_NotBound() throws Exception {
- // not bound
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
- sendByChannel("some normal string in testReceiveSend_Normal",
- localAddr2);
- ByteBuffer buf = ByteBuffer.wrap(new byte[CAPACITY_NORMAL]);
- assertNull((InetSocketAddress) this.channel1.receive(buf));
- }
-
- public void testReceiveSend_Block_Normal_S2C() throws Exception {
- this.channel1.socket().bind(localAddr2);
- sendByDatagramSocket(
- "some normal string in testReceiveSend_Normal_S2C", localAddr2);
- receiveByChannel(CAPACITY_NORMAL, localAddr2,
- "some normal string in testReceiveSend_Normal_S2C");
- }
-
- public void testReceiveSend_Block_Normal_C2S() throws Exception {
- this.datagramSocket1 = new DatagramSocket(localAddr2.getPort());
- String str1 = "some normal string in testReceiveSend_Normal_C2S";
- sendByChannel(str1, localAddr2);
- receiveByDatagramSocket(CAPACITY_NORMAL, localAddr2, str1);
- }
-
- public void testReceiveSend_NonBlock_Normal_C2S() throws Exception {
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
- this.datagramSocket1 = new DatagramSocket(localAddr2.getPort());
- String str1 = "some normal string in testReceiveSend_Normal_C2S";
- sendByChannel(str1, localAddr2);
- receiveByDatagramSocket(CAPACITY_NORMAL, localAddr2, str1);
- }
-
- public void testReceiveSend_Normal_S2S() throws Exception {
- String msg = "normal string in testReceiveSend_Normal_S2S";
- this.datagramSocket1 = new DatagramSocket(testPort);
- DatagramPacket rdp = new DatagramPacket(msg.getBytes(), msg.length(),
- localAddr2);
- datagramSocket2 = new DatagramSocket(localAddr2.getPort());
- this.datagramSocket1.send(rdp);
- byte[] buf = new byte[CAPACITY_NORMAL];
- this.datagramSocket2.setSoTimeout(TIME_UNIT);
- rdp = new DatagramPacket(buf, buf.length);
- this.datagramSocket2.receive(rdp);
- assertEquals(new String(buf, 0, CAPACITY_NORMAL).trim(), msg);
- }
-
- public void testReceiveSend_Block_Empty() throws Exception {
- this.channel1.socket().bind(localAddr2);
- sendByChannel("", localAddr2);
- receiveByChannel(CAPACITY_NORMAL, localAddr2, "");
- }
-
- public void testReceiveSend_NonBlock_Empty() throws Exception {
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
- this.channel1.socket().bind(localAddr2);
- sendByChannel("", localAddr2);
- receiveByChannel(CAPACITY_NORMAL, localAddr2, "");
- }
-
- public void testReceiveSend_Block_Empty_S2C() throws Exception {
- this.channel1.socket().bind(localAddr2);
- sendByDatagramSocket("", localAddr2);
- receiveByChannel(CAPACITY_NORMAL, localAddr2, "");
- }
-
- public void testReceiveSend_NonBlock_Empty_S2C() throws Exception {
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
- this.channel1.socket().bind(localAddr2);
- sendByDatagramSocket("", localAddr2);
- receiveByChannel(CAPACITY_NORMAL, localAddr2, "");
- }
-
- public void testReceiveSend_Block_Empty_C2S() throws Exception {
- this.datagramSocket1 = new DatagramSocket(localAddr2.getPort());
- sendByChannel("", localAddr2);
- receiveByDatagramSocket(CAPACITY_NORMAL, localAddr2, "");
- }
-
- public void testReceiveSend_NonBlock_Empty_C2S() throws Exception {
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
- this.datagramSocket1 = new DatagramSocket(localAddr2.getPort());
- sendByChannel("", localAddr2);
- receiveByDatagramSocket(CAPACITY_NORMAL, localAddr2, "");
- }
-
- public void testReceiveSend_Empty_S2S() throws Exception {
- String msg = "";
- this.datagramSocket1 = new DatagramSocket(testPort);
- DatagramPacket rdp = new DatagramPacket(msg.getBytes(), msg.length(),
- localAddr2);
- datagramSocket2 = new DatagramSocket(localAddr2.getPort());
- this.datagramSocket1.send(rdp);
- byte[] buf = new byte[CAPACITY_NORMAL];
- this.datagramSocket2.setSoTimeout(TIME_UNIT);
- rdp = new DatagramPacket(buf, buf.length);
- this.datagramSocket2.receive(rdp);
- assertEquals(new String(buf, 0, CAPACITY_NORMAL).trim(), msg);
- }
-
- public void testReceiveSend_Block_Oversize() throws Exception {
- this.channel1.socket().bind(localAddr2);
- sendByChannel("0123456789", localAddr2);
- receiveByChannel(5, localAddr2, "01234");
- }
-
- public void testReceiveSend_Block_Oversize_C2S() throws Exception {
- this.datagramSocket1 = new DatagramSocket(localAddr2.getPort());
- sendByChannel("0123456789", localAddr2);
- receiveByDatagramSocket(5, localAddr2, "01234");
- }
-
- public void testReceiveSend_NonBlock_Oversize_C2S() throws Exception {
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
- this.datagramSocket1 = new DatagramSocket(localAddr2.getPort());
- sendByChannel("0123456789", localAddr2);
- receiveByDatagramSocket(5, localAddr2, "01234");
- }
-
- public void testReceiveSend_Block_Oversize_S2C() throws Exception {
- this.channel1.socket().bind(localAddr2);
- sendByDatagramSocket("0123456789", localAddr2);
- receiveByChannel(5, localAddr2, "01234");
- }
-
- public void testReceiveSend_8K() throws Exception {
- StringBuffer str8k = new StringBuffer();
- for (int i = 0; i < 8 * CAPACITY_1KB; i++) {
- str8k.append('a');
- }
- String str = str8k.toString();
- this.channel1.socket().bind(localAddr2);
- sendByChannel(str, localAddr2);
- receiveByChannel(8 * CAPACITY_1KB, localAddr2, str);
- }
-
- public void testReceiveSend_64K() throws Exception {
- StringBuffer str64k = new StringBuffer();
- for (int i = 0; i < CAPACITY_64KB; i++) {
- str64k.append('a');
- }
- String str = str64k.toString();
- try {
- Thread.sleep(TIME_UNIT);
- channel2.send(ByteBuffer.wrap(str.getBytes()), localAddr1);
- fail("Should throw SocketException!");
- } catch (SocketException e) {
- //expected
- }
- }
-
- private void sendByChannel(String data, InetSocketAddress address)
- throws Exception {
- try {
- assertEquals(data.length(), this.channel2.send(ByteBuffer.wrap(data
- .getBytes()), address));
- } finally {
- this.channel2.close();
- }
- }
-
- private void sendByDatagramSocket(String data, InetSocketAddress address)
- throws Exception {
- this.datagramSocket1 = new DatagramSocket(testPort);
- DatagramPacket rdp = new DatagramPacket(data.getBytes(), data.length(),
- address);
- this.datagramSocket1.send(rdp);
- }
-
- private void receiveByChannel(int bufSize, InetSocketAddress address,
- String expectedString) throws IOException {
- try {
- ByteBuffer buf = ByteBuffer.wrap(new byte[bufSize]);
- InetSocketAddress returnAddr = null;
- long startTime = System.currentTimeMillis();
- do {
- returnAddr = (InetSocketAddress) this.channel1.receive(buf);
- // continue loop when channel1 is non-blocking and no data was
- // received.
- if (channel1.isBlocking() || null != returnAddr) {
- break;
- }
- // avoid dead loop
- assertTimeout(startTime, 10000);
- } while (true);
- int length = returnAddr.getAddress().getAddress().length;
- for (int i = 0; i < length; i++) {
- assertEquals(returnAddr.getAddress().getAddress()[i],
- InetAddress.getByName("127.0.0.1").getAddress()[i]);
- }
- // port is NOT equal
- assertFalse(returnAddr.getPort() == address.getPort());
- assertEquals(new String(buf.array(), 0, bufSize).trim(),
- expectedString);
- } finally {
- this.channel1.close();
- }
- }
-
- /*
- * Fails if the difference between current time and start time is greater
- * than timeout.
- */
- private void assertTimeout(long startTime, long timeout) {
- long currentTime = System.currentTimeMillis();
- if ((currentTime - startTime) > timeout) {
- fail("Timeout");
- }
- }
-
- private void receiveByDatagramSocket(int bufSize,
- InetSocketAddress address, String expectedString)
- throws IOException {
- byte[] buf = new byte[bufSize];
- this.datagramSocket1.setSoTimeout(6000);
- DatagramPacket rdp = new DatagramPacket(buf, buf.length);
- this.datagramSocket1.receive(rdp);
- assertEquals(new String(buf, 0, bufSize).trim(), expectedString);
- }
-
- public void testRead_NoSecurity() throws Exception {
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
- String strHello = "hello";
- localAddr1 = new InetSocketAddress("127.0.0.1", testPort);
- this.channel1.socket().bind(localAddr1);
- this.channel2.socket().bind(localAddr2);
- this.channel1.connect(localAddr2);
- this.channel2.send(ByteBuffer.wrap(strHello.getBytes()), localAddr1);
- assertEquals(strHello.length(), this.channel1.read(buf));
- assertAscii(buf, strHello);
- }
-
- public void testReceive_Peek_NoSecurity_Nonblocking() throws Exception {
- String strHello = "hello";
- localAddr1 = new InetSocketAddress("127.0.0.1", testPort);
- this.channel1.socket().bind(localAddr1);
- sendByChannel(strHello, localAddr1);
- this.channel1.configureBlocking(false);
- // for accepted addr, no problem.
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
- InetSocketAddress source = (InetSocketAddress) this.channel1.receive(buf);
- assertEquals(localAddr1.getAddress(), source.getAddress());
- assertAscii(buf, strHello);
- }
-
- private static void assertAscii(ByteBuffer b, String s) {
- assertEquals(s.length(), b.position());
- for (int i = 0; i < s.length(); ++i) {
- assertEquals(s.charAt(i), b.get(i));
- }
- }
-
- // -------------------------------------------------------------------
- // Test for write()
- // -------------------------------------------------------------------
-
- private void connectWriteBuf(InetSocketAddress ipAddr, ByteBuffer buf)
- throws IOException {
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- assertEquals(CAPACITY_NORMAL, this.channel1.write(buf));
- assertEquals(0, this.channel1.write(buf));
- }
-
- private void noconnectWrite(ByteBuffer buf) throws IOException {
- try {
- this.channel1.write(buf);
- fail("should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- }
-
- /*
- * Test method for 'DatagramChannelImpl.write(ByteBuffer)'
- */
- public void testWriteByteBuffer_Block() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- connectWriteBuf(localAddr1, writeBuf);
- }
-
- public void testWriteByteBuffer_NonBlock() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- this.channel1.configureBlocking(false);
- connectWriteBuf(localAddr1, writeBuf);
- }
-
- public void testWriteByteBuffer_Block_closed() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- noconnectWrite(writeBuf);
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- this.channel1.close();
- try {
- channel1.write(writeBuf);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testWriteByteBuffer_NonBlock_closed() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- // non block mode
- this.channel1.configureBlocking(false);
- noconnectWrite(writeBuf);
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- this.channel1.close();
- try {
- channel1.write(writeBuf);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testWriteByteBuffer_Block_BufNull() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(0);
- InetSocketAddress ipAddr = localAddr1;
- try {
- this.channel1.write((ByteBuffer) null);
- fail("Should throw NPE.");
- } catch (NullPointerException e) {
- // correct
- }
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- try {
- this.channel1.write((ByteBuffer) null);
- fail("Should throw NPE.");
- } catch (NullPointerException e) {
- // correct
- }
- assertEquals(0, this.channel1.write(writeBuf));
- datagramSocket1.close();
- try {
- this.channel1.write((ByteBuffer) null);
- fail("Should throw NPE.");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- public void testWriteByteBuffer_NonBlock_BufNull() throws IOException {
- ByteBuffer writeBuf = ByteBuffer.allocateDirect(0);
- InetSocketAddress ipAddr = localAddr1;
-
- // non block mode
- this.channel1.configureBlocking(false);
-
- try {
- this.channel1.write((ByteBuffer) null);
- fail("Should throw NPE.");
- } catch (NullPointerException e) {
- // correct
- }
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- try {
- this.channel1.write((ByteBuffer) null);
- fail("Should throw NPE.");
- } catch (NullPointerException e) {
- // correct
- }
- assertEquals(0, this.channel1.write(writeBuf));
- datagramSocket1.close();
- try {
- this.channel1.write((ByteBuffer) null);
- fail("Should throw NPE.");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- /*
- * Test method for 'DatagramChannelImpl.write(ByteBuffer[], int, int)'
- */
- public void testWriteByteBufferArrayIntInt_Block() throws IOException {
- ByteBuffer[] writeBuf = new ByteBuffer[2];
- writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- try {
- this.channel1.write(writeBuf, 0, 2);
- fail("Should throw NotYetConnectedException.");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
- // cannot be buffered again!
- assertEquals(0, this.channel1.write(writeBuf, 0, 1));
-
- }
-
- public void testWriteByteBufferArrayIntInt_NonBlock() throws IOException {
- ByteBuffer[] writeBuf = new ByteBuffer[2];
- writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- // non-block mode
- this.channel1.configureBlocking(false);
- try {
- this.channel1.write(writeBuf, 0, 2);
- fail("Should throw NotYetConnectedException.");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
- // cannot be buffered again!
- assertEquals(0, this.channel1.write(writeBuf, 0, 1));
-
- }
-
- public void testWriteByteBufferArrayIntInt_NoConnectIndexBad()
- throws IOException {
- ByteBuffer[] writeBuf = new ByteBuffer[2];
- writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- try {
- this.channel1.write(writeBuf, -1, 2);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // correct
- }
- try {
- this.channel1.write(writeBuf, 0, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // correct
- }
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
- // cannot be buffered again!
- assertEquals(0, this.channel1.write(writeBuf, 0, 1));
- }
-
- public void testWriteByteBufferArrayIntInt_ConnectedIndexBad()
- throws IOException {
- ByteBuffer[] writeBuf = new ByteBuffer[2];
- writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- try {
- this.channel1.write(writeBuf, -1, 2);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // correct
- }
- try {
- this.channel1.write(writeBuf, 0, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // correct
- }
- }
-
- public void testWriteByteBufferArrayIntInt_BufNullNoConnect()
- throws IOException {
- ByteBuffer[] writeBuf = new ByteBuffer[2];
- writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- try {
- this.channel1.write(null, 0, 2);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- this.channel1.write(writeBuf, -1, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.write(writeBuf, 0, 3);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void testWriteByteBufferArrayIntInt_BufNullConnect()
- throws IOException {
- ByteBuffer[] writeBuf = new ByteBuffer[2];
- writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- try {
- this.channel1.write(null, 0, 2);
- fail("should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- this.channel1.write(writeBuf, 0, 3);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // correct
- }
- datagramSocket1.close();
- try {
- this.channel1.write(null, 0, 2);
- fail("should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- // -------------------------------------------------------------------
- // Test for read()
- // -------------------------------------------------------------------
-
- /*
- * Test method for 'DatagramChannelImpl.read(ByteBuffer)'
- */
- public void testReadByteBuffer() throws IOException {
- ByteBuffer readBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- try {
- this.channel1.read(readBuf);
- fail("should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(localAddr1);
- assertTrue(this.channel1.isConnected());
- this.channel1.configureBlocking(false);
- // note : blocking-mode will make the read process endless!
- assertEquals(0, this.channel1.read(readBuf));
- this.channel1.close();
- try {
- this.channel1.read(readBuf);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // OK.
- }
- }
-
- public void testReadByteBuffer_bufNull() throws IOException {
- ByteBuffer readBuf = ByteBuffer.allocateDirect(0);
- InetSocketAddress ipAddr = localAddr1;
- try {
- this.channel1.read(readBuf);
- fail("should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- try {
- channel1.read((ByteBuffer) null);
- fail("should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- this.channel1.configureBlocking(false);
- // note : blocking-mode will make the read process endless!
- assertEquals(0, this.channel1.read(readBuf));
- datagramSocket1.close();
- }
-
- /*
- * Test method for 'DatagramChannelImpl.read(ByteBuffer[], int, int)'
- */
- public void testReadByteBufferArrayIntInt() throws IOException {
- ByteBuffer[] readBuf = new ByteBuffer[2];
- readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- try {
- this.channel1.read(readBuf, 0, 2);
- fail("should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- this.channel1.configureBlocking(false);
- // note : blocking-mode will make the read process endless!
- assertEquals(0, this.channel1.read(readBuf, 0, 1));
- assertEquals(0, this.channel1.read(readBuf, 0, 2));
- datagramSocket1.close();
- }
-
- public void testReadByteBufferArrayIntInt_exceptions() throws IOException {
- //regression test for HARMONY-932
- try {
- DatagramChannel.open().read(new ByteBuffer[] {}, 2, Integer.MAX_VALUE);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- DatagramChannel.open().read(new ByteBuffer[] {}, -1, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- DatagramChannel.open().read((ByteBuffer[]) null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testReadByteBufferArrayIntInt_BufNull() throws IOException {
- ByteBuffer[] readBuf = new ByteBuffer[2];
- readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- InetSocketAddress ipAddr = localAddr1;
- try {
- this.channel1.read(null, 0, 0);
- fail("should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- this.channel1.connect(ipAddr);
- assertTrue(this.channel1.isConnected());
- this.channel1.configureBlocking(false);
- // note : blocking-mode will make the read process endless!
- try {
- this.channel1.read(null, 0, 0);
- fail("should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- assertEquals(0, this.channel1.read(readBuf, 0, 1));
- try {
- this.channel1.read(readBuf, 0, 2);
- fail("should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- this.channel1.read(readBuf, 0, 3);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // correct
- }
- datagramSocket1.close();
- }
-
- // -------------------------------------------------------------------
- // test read and write
- // -------------------------------------------------------------------
-
- public void testReadWrite_configureBlock() throws Exception {
- byte[] targetArray = new byte[2];
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
-
- new Thread() {
- public void run() {
- try {
- Thread.sleep(TIME_UNIT);
- channel1.configureBlocking(false);
- channel1.close();
- } catch (Exception e) {
- //ignore
- }
- }
- }.start();
- try {
- this.channel1.read(targetBuf);
- fail("should throw AsynchronousCloseException");
- } catch (AsynchronousCloseException e) {
- // ok
- }
- }
-
- public void testReadWrite_Block_Zero() throws Exception {
- byte[] sourceArray = new byte[0];
- byte[] targetArray = new byte[0];
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(0, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- int readCount = this.channel2.read(targetBuf);
-
- assertEquals(0, readCount);
- }
-
- public void testReadWrite_Block_Normal() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- byte[] targetArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- readWriteReadData(this.channel1, sourceArray, this.channel2,
- targetArray, CAPACITY_NORMAL, "testReadWrite_Block_Normal");
- }
-
- public void testReadWrite_Block_Empty() throws Exception {
- // empty buf
- byte[] sourceArray = "".getBytes();
- byte[] targetArray = new byte[CAPACITY_NORMAL];
-
- // bind and connect
-
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(0, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- // empty message let the reader blocked
- closeBlockedReaderChannel2(targetBuf);
- }
-
- public void testReadWrite_changeBlock_Empty() throws Exception {
- // empty buf
- byte[] sourceArray = "".getBytes();
- byte[] targetArray = new byte[CAPACITY_NORMAL];
-
- // bind and connect
-
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(0, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- // empty message let the reader blocked
- new Thread() {
- public void run() {
- try {
- Thread.sleep(TIME_UNIT);
- channel2.configureBlocking(false);
- Thread.sleep(TIME_UNIT * 5);
- channel2.close();
- } catch (Exception e) {
- // do nothing
- }
- }
- }.start();
- try {
- assertTrue(this.channel2.isBlocking());
- this.channel2.read(targetBuf);
- fail("Should throw AsynchronousCloseException");
- } catch (AsynchronousCloseException e) {
- assertFalse(this.channel2.isBlocking());
- // OK.
- }
- }
-
- public void testReadWrite_Block_8KB() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_1KB * 8];
- byte[] targetArray = new byte[CAPACITY_1KB * 8];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- readWriteReadData(this.channel1, sourceArray, this.channel2,
- targetArray, 8 * CAPACITY_1KB, "testReadWrite_Block_8KB");
- }
-
- /*
- * sender write the sourceArray whose size is dataSize, and receiver read
- * the data into targetArray
- */
- private void readWriteReadData(DatagramChannel sender, byte[] sourceArray,
- DatagramChannel receiver, byte[] targetArray, int dataSize,
- String methodName) throws IOException {
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(dataSize, sender.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
-
- int count = 0;
- int total = 0;
- long beginTime = System.currentTimeMillis();
- while (total < dataSize && (count = receiver.read(targetBuf)) != -1) {
- total = total + count;
- // 3s timeout to avoid dead loop
- if (System.currentTimeMillis() - beginTime > 3000){
- break;
- }
- }
-
- assertEquals(dataSize, total);
- assertEquals(targetBuf.position(), total);
- targetBuf.flip();
- targetArray = targetBuf.array();
- for (int i = 0; i < targetArray.length; i++) {
- assertEquals(targetArray[i], (byte) i);
- }
- }
-
- public void testReadWrite_Block_64K() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_64KB];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- try {
- channel1.write(sourceBuf);
- fail("Should throw IOException");
- } catch (IOException e) {
- // too big
- }
- }
-
- public void testReadWrite_Block_DifferentAddr() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- byte[] targetArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr1);// the different addr
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- // the wrong connected addr will make the read blocked.
- // we close the blocked channel
- closeBlockedReaderChannel2(targetBuf);
- }
-
- public void testReadWrite_Block_WriterNotBind() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- byte[] targetArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- // bind and connect
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- closeBlockedReaderChannel2(targetBuf);
- }
-
- public void testReadWrite_Block_WriterBindLater() throws Exception {
-
- byte[] targetArray = new byte[CAPACITY_NORMAL];
-
- // bind and connect
- // writer channel1 is bound later
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- new Thread() {
- public void run() {
- try {
- Thread.sleep(TIME_UNIT);
- // bind later
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
- channel1.socket().bind(localAddr2);
- channel1.connect(localAddr1);
- // write later
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(CAPACITY_NORMAL, channel1.write(sourceBuf));
- } catch (Exception e) {
- // do nothing
- }
- }
- }.start();
-
- int count = 0;
- int total = 0;
- long beginTime = System.currentTimeMillis();
- while (total < CAPACITY_NORMAL && (count = channel2.read(targetBuf)) != -1) {
- total = total + count;
- // 3s timeout to avoid dead loop
- if (System.currentTimeMillis() - beginTime > 3000){
- break;
- }
- }
-
- assertEquals(CAPACITY_NORMAL, total);
- assertEquals(targetBuf.position(), total);
- targetBuf.flip();
- targetArray = targetBuf.array();
- for (int i = 0; i < targetArray.length; i++) {
- assertEquals(targetArray[i], (byte) i);
- }
-
- }
-
- public void testReadWrite_Block_ReaderNotBind() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- byte[] targetArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- // reader channel2 is not bound
- this.channel2.connect(localAddr2);
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- closeBlockedReaderChannel2(targetBuf);
-
- }
-
- private void closeBlockedReaderChannel2(ByteBuffer targetBuf)
- throws IOException {
- new Thread() {
- public void run() {
- try {
- Thread.sleep(TIME_UNIT);
- channel2.close();
- } catch (Exception e) {
- // do nothing
- }
- }
- }.start();
- try {
- assertTrue(this.channel2.isBlocking());
- this.channel2.read(targetBuf);
- fail("Should throw AsynchronousCloseException");
- } catch (AsynchronousCloseException e) {
- // OK.
- }
- }
-
- // -------------------------------------------------------------------
- // Test read and write in non-block mode.
- // -------------------------------------------------------------------
- public void testReadWrite_NonBlock_Normal() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- byte[] targetArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- readWriteReadData(this.channel1, sourceArray, this.channel2,
- targetArray, CAPACITY_NORMAL, "testReadWrite_NonBlock_Normal");
- }
-
- public void testReadWrite_NonBlock_8KB() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_1KB * 8];
- byte[] targetArray = new byte[CAPACITY_1KB * 8];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- readWriteReadData(this.channel1, sourceArray, this.channel2,
- targetArray, 8 * CAPACITY_1KB, "testReadWrite_NonBlock_8KB");
- }
-
- public void testReadWrite_NonBlock_DifferentAddr() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- byte[] targetArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr1);// the different addr
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- assertEquals(0, this.channel2.read(targetBuf));
- }
-
- public void testReadWrite_NonBlock_WriterNotBind() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- byte[] targetArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
-
- // bind and connect
- this.channel1.connect(localAddr1);
- this.channel2.socket().bind(localAddr1);
- this.channel2.connect(localAddr2);
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- assertEquals(0, this.channel2.read(targetBuf));
- }
-
- public void testReadWrite_NonBlock_ReaderNotBind() throws Exception {
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- byte[] targetArray = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < sourceArray.length; i++) {
- sourceArray[i] = (byte) i;
- }
-
- this.channel1.configureBlocking(false);
- this.channel2.configureBlocking(false);
-
- // bind and connect
- this.channel1.socket().bind(localAddr2);
- this.channel1.connect(localAddr1);
- this.channel2.connect(localAddr2);
-
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
-
- // read
- ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
- assertEquals(0, this.channel2.read(targetBuf));
- }
-
- public void test_write_LBuffer_positioned() throws Exception {
- // Regression test for Harmony-683
- int position = 16;
- DatagramChannel dc = DatagramChannel.open();
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- dc.connect(localAddr1);
- // write
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- sourceBuf.position(position);
- assertEquals(CAPACITY_NORMAL - position, dc.write(sourceBuf));
- }
-
- public void test_send_LBuffer_LSocketAddress_PositionNotZero()
- throws Exception {
- // regression test for Harmony-701
- int CAPACITY_NORMAL = 256;
- int position = 16;
- DatagramChannel dc = DatagramChannel.open();
- byte[] sourceArray = new byte[CAPACITY_NORMAL];
- // send ByteBuffer whose position is not zero
- ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
- sourceBuf.position(position);
- int ret = dc.send(sourceBuf, localAddr1);
- // assert send (256 - 16) bytes
- assertEquals(CAPACITY_NORMAL - position, ret);
- // assert the position of ByteBuffer has been set
- assertEquals(CAPACITY_NORMAL, sourceBuf.position());
- }
-
- /**
- * @tests DatagramChannel#read(ByteBuffer[])
- */
- public void test_read_$LByteBuffer() throws Exception {
- // regression test for Harmony-754
- channel2.socket().bind(localAddr1);
- channel1.socket().bind(localAddr2);
- channel1.connect(localAddr1);
- channel2.connect(localAddr2);
- channel2.write(ByteBuffer.allocate(CAPACITY_NORMAL));
-
- ByteBuffer[] readBuf = new ByteBuffer[2];
- readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
-
- channel1.configureBlocking(true);
- assertEquals(CAPACITY_NORMAL, channel1.read(readBuf));
- }
-
- /**
- * @tests DatagramChannel#read(ByteBuffer[],int,int)
- */
- public void test_read_$LByteBufferII() throws Exception {
- // regression test for Harmony-754
- channel2.socket().bind(localAddr1);
- channel1.socket().bind(localAddr2);
- channel1.connect(localAddr1);
- channel2.connect(localAddr2);
- channel2.write(ByteBuffer.allocate(CAPACITY_NORMAL));
-
- ByteBuffer[] readBuf = new ByteBuffer[2];
- readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
-
- channel1.configureBlocking(true);
- assertEquals(CAPACITY_NORMAL, channel1.read(readBuf,0,2));
- }
-
- /**
- * @tests DatagramChannel#read(ByteBuffer)
- */
- public void test_read_LByteBuffer_closed_nullBuf() throws Exception {
- // regression test for Harmony-754
- ByteBuffer c = null;
- DatagramChannel channel = DatagramChannel.open();
- channel.close();
- try{
- channel.read(c);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e){
- // expected
- }
- }
-
- /**
- * @tests DatagramChannel#read(ByteBuffer)
- */
- public void test_read_LByteBuffer_NotConnected_nullBuf() throws Exception {
- // regression test for Harmony-754
- ByteBuffer c = null;
- DatagramChannel channel = DatagramChannel.open();
- try{
- channel.read(c);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e){
- // expected
- }
- }
-
- /**
- * @tests DatagramChannel#read(ByteBuffer)
- */
- public void test_read_LByteBuffer_readOnlyBuf() throws Exception {
- // regression test for Harmony-754
- ByteBuffer c = ByteBuffer.allocate(1);
- DatagramChannel channel = DatagramChannel.open();
- try{
- channel.read(c.asReadOnlyBuffer());
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e){
- } catch (IllegalArgumentException e){
- // expected
- }
- channel.connect(localAddr1);
- try{
- channel.read(c.asReadOnlyBuffer());
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e){
- // expected
- }
- }
-
- /**
- * @tests DatagramChannel#send(ByteBuffer, SocketAddress)
- */
- public void test_send_LByteBuffer_LSocketAddress_closed() throws IOException{
- // regression test for Harmony-913
- channel1.close();
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
- try {
- channel1.send(buf, localAddr1);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- //pass
- }
- try {
- channel1.send(null,localAddr1);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- //pass
- }
- try {
- channel1.send(buf, null);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- //pass
- }
- try {
- channel1.send(null, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- //pass
- }
- }
-
- /**
- * @tests DatagramChannel#socket()
- */
- public void test_socket_IllegalBlockingModeException() throws Exception {
- // regression test for Harmony-1036
- DatagramChannel channel = DatagramChannel.open();
- channel.configureBlocking(false);
- DatagramSocket socket = channel.socket();
- try {
- socket.send(null);
- fail("should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- try {
- socket.receive(null);
- fail("should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- }
-
- public void test_bounded_harmony6493() throws IOException {
- DatagramChannel server = DatagramChannel.open();
- InetSocketAddress addr = new InetSocketAddress("localhost", 0);
- server.socket().bind(addr);
- SocketAddress boundedAddress = server.socket().getLocalSocketAddress();
-
- DatagramChannel client = DatagramChannel.open();
- ByteBuffer sent = ByteBuffer.allocate(1024);
- sent.put("test".getBytes());
- sent.flip();
- client.send(sent, boundedAddress);
- assertTrue(client.socket().isBound());
-
- server.close();
- client.close();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelLockingTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelLockingTest.java
deleted file mode 100644
index cb34343..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelLockingTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.channels.NonReadableChannelException;
-import java.nio.channels.NonWritableChannelException;
-import java.nio.channels.OverlappingFileLockException;
-
-import junit.framework.TestCase;
-
-/**
- * API tests for the NIO FileChannel locking APIs
- */
-public class FileChannelLockingTest extends TestCase {
-
- private FileChannel readOnlyChannel;
-
- private FileChannel writeOnlyChannel;
-
- private FileChannel readWriteChannel;
-
- private final String CONTENT = "The best things in life are nearest: Breath in your nostrils, light in your eyes, "
- + "flowers at your feet, duties at your hand, the path of right just before you. Then do not grasp at the stars, "
- + "but do life's plain, common work as it comes, certain that daily duties and daily bread are the sweetest "
- + " things in life.--Robert Louis Stevenson";
-
- protected void setUp() throws Exception {
- super.setUp();
-
- // Create a three temporary files with content.
- File[] tempFiles = new File[3];
- for (int i = 0; i < tempFiles.length; i++) {
- tempFiles[i] = File.createTempFile("testing", "tmp");
- tempFiles[i].deleteOnExit();
- FileWriter writer = new FileWriter(tempFiles[i]);
- writer.write(CONTENT);
- writer.close();
- }
-
- // Open read, write, and read/write channels on the temp files.
- FileInputStream fileInputStream = new FileInputStream(tempFiles[0]);
- readOnlyChannel = fileInputStream.getChannel();
-
- FileOutputStream fileOutputStream = new FileOutputStream(tempFiles[1]);
- writeOnlyChannel = fileOutputStream.getChannel();
-
- RandomAccessFile randomAccessFile = new RandomAccessFile(tempFiles[2],
- "rw");
- readWriteChannel = randomAccessFile.getChannel();
- }
-
- protected void tearDown() throws IOException {
- if (readOnlyChannel != null) {
- readOnlyChannel.close();
- }
- if (writeOnlyChannel != null) {
- writeOnlyChannel.close();
- }
- if (readWriteChannel != null) {
- readWriteChannel.close();
- }
- }
-
- public void test_illegalLocks() throws IOException {
- // Cannot acquire an exclusive lock on a read-only file channel
- try {
- readOnlyChannel.lock();
- fail("Acquiring a full exclusive lock on a read only channel should fail.");
- } catch (NonWritableChannelException ex) {
- // Expected.
- }
-
- // Cannot get a shared lock on a write-only file channel.
- try {
- writeOnlyChannel.lock(1, 10, true);
- fail("Acquiring a shared lock on a write-only channel should fail.");
- } catch (NonReadableChannelException ex) {
- // expected
- }
- }
-
- public void test_lockReadWrite() throws IOException {
- // Acquire an exclusive lock across the entire file.
- FileLock flock = readWriteChannel.lock();
- if (flock != null) {
- flock.release();
- }
- }
-
- public void test_illegalLockParameters() throws IOException {
- // Cannot lock negative positions
- try {
- readOnlyChannel.lock(-1, 10, true);
- fail("Passing illegal args to lock should fail.");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- try {
- writeOnlyChannel.lock(-1, 10, false);
- fail("Passing illegal args to lock should fail.");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- try {
- readWriteChannel.lock(-1, 10, false);
- fail("Passing illegal args to lock should fail.");
- } catch (IllegalArgumentException ex) {
- // expected
- }
-
- // Lock a range at the front, shared.
- FileLock flock1 = readWriteChannel.lock(22, 110, true);
-
- // Try to acquire an overlapping lock.
- try {
- readWriteChannel.lock(75, 210, true);
- } catch (OverlappingFileLockException exception) {
- // expected
- flock1.release();
- }
- }
-
- public void test_lockLLZ() throws IOException {
- // Lock a range at the front, non-shared.
- FileLock flock1 = readWriteChannel.lock(0, 10, false);
-
- // Lock a shared range further in the same file.
- FileLock flock2 = readWriteChannel.lock(22, 100, true);
-
- // The spec allows the impl to refuse shared locks
- flock1.release();
- flock2.release();
- }
-
- public void test_tryLock() throws IOException {
- try {
- readOnlyChannel.tryLock();
- fail("Acquiring a full exclusive lock on a read channel should have thrown an exception.");
- } catch (NonWritableChannelException ex) {
- // Expected.
- }
- }
-
- public void test_tryLockLLZ() throws IOException {
- // It is illegal to request an exclusive lock on a read-only channel
- try {
- readOnlyChannel.tryLock(0, 99, false);
- fail("Acquiring exclusive lock on read-only channel should fail");
- } catch (NonWritableChannelException ex) {
- // Expected
- }
-
- // It is invalid to request a lock starting before the file start
- try {
- readOnlyChannel.tryLock(-99, 0, true);
- fail("Acquiring an illegal lock value should fail.");
- } catch (IllegalArgumentException ex) {
- // expected
- }
-
- // Acquire a valid lock
- FileLock tmpLock = readOnlyChannel.tryLock(0, 10, true);
- assertTrue(tmpLock.isValid());
- tmpLock.release();
-
- // Acquire another valid lock -- and don't release it yet
- FileLock lock = readOnlyChannel.tryLock(10, 788, true);
- assertTrue(lock.isValid());
-
- // Overlapping locks are illegal
- try {
- readOnlyChannel.tryLock(1, 23, true);
- fail("Acquiring an overlapping lock should fail.");
- } catch (OverlappingFileLockException ex) {
- // Expected
- }
-
- // Adjacent locks are legal
- FileLock adjacentLock = readOnlyChannel.tryLock(1, 3, true);
- assertTrue(adjacentLock.isValid());
- adjacentLock.release();
-
- // Release longer lived lock
- lock.release();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java
deleted file mode 100644
index 9a89f7e..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java
+++ /dev/null
@@ -1,3121 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
-import java.nio.ReadOnlyBufferException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.channels.NonReadableChannelException;
-import java.nio.channels.NonWritableChannelException;
-import java.nio.channels.OverlappingFileLockException;
-import java.nio.channels.Pipe;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.WritableByteChannel;
-import java.nio.channels.FileChannel.MapMode;
-import java.util.Arrays;
-
-import junit.framework.TestCase;
-
-public class FileChannelTest extends TestCase {
-
- private static final int CAPACITY = 100;
-
- private static final int LIMITED_CAPACITY = 2;
-
- private static final int TIME_OUT = 10000;
-
- private static final String CONTENT = "MYTESTSTRING needs to be a little long";
-
- private static final byte[] TEST_BYTES;
-
- private static final byte[] CONTENT_AS_BYTES;
-
- private static final int CONTENT_AS_BYTES_LENGTH;
-
- static {
- try {
- TEST_BYTES = "test".getBytes("iso8859-1");
- CONTENT_AS_BYTES = CONTENT.getBytes("iso8859-1");
- CONTENT_AS_BYTES_LENGTH = CONTENT_AS_BYTES.length;
- } catch (UnsupportedEncodingException e) {
- throw new Error(e);
- }
- }
-
- private static final int CONTENT_LENGTH = CONTENT.length();
-
- private FileChannel readOnlyFileChannel;
-
- private FileChannel writeOnlyFileChannel;
-
- private FileChannel readWriteFileChannel;
-
- private File fileOfReadOnlyFileChannel;
-
- private File fileOfWriteOnlyFileChannel;
-
- private File fileOfReadWriteFileChannel;
-
- private ReadableByteChannel readByteChannel;
-
- private WritableByteChannel writableByteChannel;
-
- private DatagramChannel datagramChannelSender;
-
- private DatagramChannel datagramChannelReceiver;
-
- private ServerSocketChannel serverSocketChannel;
-
- private SocketChannel socketChannelSender;
-
- private SocketChannel socketChannelReceiver;
-
- private Pipe pipe;
-
- // to read content from FileChannel
- private FileInputStream fis;
-
- private FileLock fileLock;
-
- protected void setUp() throws Exception {
- fileOfReadOnlyFileChannel = File.createTempFile(
- "File_of_readOnlyFileChannel", "tmp");
- fileOfReadOnlyFileChannel.deleteOnExit();
- fileOfWriteOnlyFileChannel = File.createTempFile(
- "File_of_writeOnlyFileChannel", "tmp");
- fileOfWriteOnlyFileChannel.deleteOnExit();
- fileOfReadWriteFileChannel = File.createTempFile(
- "File_of_readWriteFileChannel", "tmp");
- fileOfReadWriteFileChannel.deleteOnExit();
- fis = null;
- fileLock = null;
- readOnlyFileChannel = new FileInputStream(fileOfReadOnlyFileChannel)
- .getChannel();
- writeOnlyFileChannel = new FileOutputStream(fileOfWriteOnlyFileChannel)
- .getChannel();
- readWriteFileChannel = new RandomAccessFile(fileOfReadWriteFileChannel,
- "rw").getChannel();
- }
-
- protected void tearDown() {
- if (null != readOnlyFileChannel) {
- try {
- readOnlyFileChannel.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != writeOnlyFileChannel) {
- try {
- writeOnlyFileChannel.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != readWriteFileChannel) {
- try {
- readWriteFileChannel.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != fis) {
- try {
- fis.close();
- } catch (IOException e) {
- // do nothing
- }
- }
-
- if (null != fileLock) {
- try {
- fileLock.release();
- } catch (IOException e) {
- // do nothing
- }
- }
-
- if (null != fileOfReadOnlyFileChannel) {
- fileOfReadOnlyFileChannel.delete();
- }
- if (null != fileOfWriteOnlyFileChannel) {
- fileOfWriteOnlyFileChannel.delete();
- }
- if (null != fileOfReadWriteFileChannel) {
- fileOfReadWriteFileChannel.delete();
- }
- if (null != datagramChannelSender) {
- try {
- datagramChannelSender.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != datagramChannelReceiver) {
- try {
- datagramChannelReceiver.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != serverSocketChannel) {
- try {
- serverSocketChannel.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != socketChannelSender) {
- try {
- socketChannelSender.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != socketChannelReceiver) {
- try {
- socketChannelReceiver.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != pipe) {
- if (null != pipe.source()) {
- try {
- pipe.source().close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != pipe.sink()) {
- try {
- pipe.sink().close();
- } catch (IOException e) {
- // do nothing
- }
- }
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#force(boolean)
- */
- public void test_forceJ() throws Exception {
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
- writeOnlyFileChannel.write(writeBuffer);
- writeOnlyFileChannel.force(true);
-
- byte[] readBuffer = new byte[CONTENT_AS_BYTES_LENGTH];
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- fis.read(readBuffer);
- assertTrue(Arrays.equals(CONTENT_AS_BYTES, readBuffer));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#force(boolean)
- */
- public void test_forceJ_closed() throws Exception {
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.force(true);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- try {
- writeOnlyFileChannel.force(false);
- fail();
- } catch (ClosedChannelException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#force(boolean)
- */
- public void test_forceJ_ReadOnlyChannel() throws Exception {
- // force on a read only file channel has no effect.
- readOnlyFileChannel.force(true);
- readOnlyFileChannel.force(false);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position()
- */
- public void test_position_Init() throws Exception {
- assertEquals(0, readOnlyFileChannel.position());
- assertEquals(0, writeOnlyFileChannel.position());
- assertEquals(0, readWriteFileChannel.position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position()
- */
- public void test_position_ReadOnly() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
-
- assertEquals(0, readOnlyFileChannel.position());
- ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
- readOnlyFileChannel.read(readBuffer);
- assertEquals(CONTENT_LENGTH, readOnlyFileChannel.position());
- }
-
- /**
- * Initializes test file.
- *
- * @param file
- * @throws FileNotFoundException
- * @throws IOException
- */
- private void writeDataToFile(File file) throws FileNotFoundException,
- IOException {
- FileOutputStream fos = new FileOutputStream(file);
- try {
- fos.write(CONTENT_AS_BYTES);
- } finally {
- fos.close();
- }
- }
-
- /**
- * Initializes large test file.
- *
- * @param file the file to be written
- * @param size the content size to be written
- * @throws FileNotFoundException
- * @throws IOException
- */
- private void writeLargeDataToFile(File file, int size) throws FileNotFoundException,
- IOException {
- FileOutputStream fos = new FileOutputStream(file);
- byte[] buf = new byte[size];
-
- try {
- // we don't care about content - just need a particular file size
- fos.write(buf);
- } finally {
- fos.close();
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position()
- */
- public void test_position_WriteOnly() throws Exception {
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
- writeOnlyFileChannel.write(writeBuffer);
- assertEquals(CONTENT_LENGTH, writeOnlyFileChannel.position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position()
- */
- public void test_position_ReadWrite() throws Exception {
- writeDataToFile(fileOfReadWriteFileChannel);
-
- assertEquals(0, readWriteFileChannel.position());
- ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
- readWriteFileChannel.read(readBuffer);
- assertEquals(CONTENT_LENGTH, readWriteFileChannel.position());
-
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
- readWriteFileChannel.write(writeBuffer);
- assertEquals(CONTENT_LENGTH * 2, readWriteFileChannel.position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position()
- */
- public void test_position_Closed() throws Exception {
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.position();
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException expected) {
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.position();
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException expected) {
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.position();
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position(long)
- */
- public void test_positionJ_Closed() throws Exception {
- final long POSITION = 100;
-
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.position(POSITION);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.position(POSITION);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.position(POSITION);
- fail();
- } catch (ClosedChannelException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position(long)
- */
- public void test_positionJ_Negative() throws Exception {
- final long NEGATIVE_POSITION = -1;
- try {
- readOnlyFileChannel.position(NEGATIVE_POSITION);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- writeOnlyFileChannel.position(NEGATIVE_POSITION);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.position(NEGATIVE_POSITION);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position(long)
- */
- public void test_positionJ_ReadOnly() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
-
- // set the position of the read only file channel to POSITION
- final int POSITION = 4;
- readOnlyFileChannel.position(POSITION);
-
- // reads the content left to readBuffer through read only file channel
- ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
- int count = readOnlyFileChannel.read(readBuffer);
- assertEquals(CONTENT_LENGTH - POSITION, count);
-
- // asserts the content read is the part which stays beyond the POSITION
- readBuffer.flip();
- int i = POSITION;
- while (readBuffer.hasRemaining()) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
- i++;
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position(long)
- */
- public void test_positionJ_WriteOnly() throws Exception {
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- // init data to write
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
-
- // set the position of the write only file channel to POSITION
- final int POSITION = 4;
- writeOnlyFileChannel.position(POSITION);
-
- // writes to the write only file channel
- writeOnlyFileChannel.write(writeBuffer);
- // force to write out.
- writeOnlyFileChannel.close();
-
- // gets the result of the write only file channel
- byte[] result = new byte[POSITION + CONTENT_LENGTH];
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- fis.read(result);
-
- // constructs the expected result which has content[0... POSITION] plus
- // content[0...length()]
- byte[] expectedResult = new byte[POSITION + CONTENT_LENGTH];
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, 0, POSITION);
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, POSITION,
- CONTENT_LENGTH);
-
- // asserts result of the write only file channel same as expected
- assertTrue(Arrays.equals(expectedResult, result));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#size()
- */
- public void test_size_Init() throws Exception {
- assertEquals(0, readOnlyFileChannel.size());
- assertEquals(0, writeOnlyFileChannel.size());
- assertEquals(0, readWriteFileChannel.size());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#size()
- */
- public void test_size() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
- assertEquals(fileOfReadOnlyFileChannel.length(), readOnlyFileChannel
- .size());
-
-
- // REGRESSION test for read(ByteBuffer[], int, int) on special files
- try {
- FileChannel specialFile =
- new FileInputStream("/dev/zero").getChannel();
- assertEquals(0, specialFile.size());
- ByteBuffer buf = ByteBuffer.allocate(8);
- assertEquals(8, specialFile.read(buf));
- ByteBuffer[] bufs = { ByteBuffer.allocate(8) };
- assertEquals(8, specialFile.read(bufs, 0, 1));
- specialFile.close();
- } catch (FileNotFoundException e) {
- // skip test if special file doesn't exist
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#size()
- */
- public void test_size_Closed() throws Exception {
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.size();
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.size();
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.size();
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#truncate(long)
- */
- public void test_truncateJ_Closed() throws Exception {
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.truncate(0);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.truncate(0);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.truncate(-1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#truncate(long)
- */
- public void test_truncateJ_IllegalArgument() throws Exception {
- // regression test for Harmony-941
- try {
- readOnlyFileChannel.truncate(-1);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- writeOnlyFileChannel.truncate(-1);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.truncate(-1);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#truncate(long)
- */
- public void test_truncateJ_ReadOnly() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
- try {
- readOnlyFileChannel.truncate(readOnlyFileChannel.size());
- fail("should throw NonWritableChannelException.");
- } catch (NonWritableChannelException e) {
- // expected
- }
-
- try {
- readOnlyFileChannel.truncate(0);
- fail("should throw NonWritableChannelException.");
- } catch (NonWritableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#truncate(long)
- */
- public void test_truncateJ() throws Exception {
- writeDataToFile(fileOfReadWriteFileChannel);
-
- int truncateLength = CONTENT_LENGTH + 2;
- assertEquals(readWriteFileChannel, readWriteFileChannel
- .truncate(truncateLength));
- assertEquals(CONTENT_LENGTH, fileOfReadWriteFileChannel.length());
-
- truncateLength = CONTENT_LENGTH;
- assertEquals(readWriteFileChannel, readWriteFileChannel
- .truncate(truncateLength));
- assertEquals(CONTENT_LENGTH, fileOfReadWriteFileChannel.length());
-
- truncateLength = CONTENT_LENGTH / 2;
- assertEquals(readWriteFileChannel, readWriteFileChannel
- .truncate(truncateLength));
- assertEquals(truncateLength, fileOfReadWriteFileChannel.length());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock()
- */
- public void test_lock() throws Exception {
- MockFileChannel mockFileChannel = new MockFileChannel();
- // Verify that calling lock() leads to the method
- // lock(long, long, boolean) being called with a 0 for the
- // first parameter, Long.MAX_VALUE as the second parameter and false
- // as the third parameter.
- mockFileChannel.lock();
- assertTrue(mockFileChannel.isLockCalled);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_Closed() throws Exception {
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.lock(0, 10, false);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.lock(0, 10, false);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.lock(0, 10, false);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // throws ClosedChannelException before IllegalArgumentException
- try {
- readWriteFileChannel.lock(-1, 0, false);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_IllegalArgument() throws Exception {
- try {
- writeOnlyFileChannel.lock(0, -1, false);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- writeOnlyFileChannel.lock(-1, 0, false);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.lock(-1, -1, false);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.lock(Long.MAX_VALUE, 1, false);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_NonWritable() throws Exception {
- try {
- readOnlyFileChannel.lock(0, 10, false);
- fail("should throw NonWritableChannelException");
- } catch (NonWritableChannelException e) {
- // expected
- }
-
- // throws NonWritableChannelException before IllegalArgumentException
- try {
- readOnlyFileChannel.lock(-1, 0, false);
- fail("should throw NonWritableChannelException");
- } catch (NonWritableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_NonReadable() throws Exception {
- try {
- writeOnlyFileChannel.lock(0, 10, true);
- fail("should throw NonReadableChannelException");
- } catch (NonReadableChannelException e) {
- // expected
- }
-
- // throws NonReadableChannelException before IllegalArgumentException
- try {
- writeOnlyFileChannel.lock(-1, 0, true);
- fail("should throw NonReadableChannelException");
- } catch (NonReadableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_Shared() throws Exception {
- final long POSITION = 100;
- final long SIZE = 200;
- fileLock = readOnlyFileChannel.lock(POSITION, SIZE, true);
- assertTrue(fileLock.isValid());
- // fileLock.isShared depends on whether the underlying platform support
- // shared lock, but it works on Windows & Linux.
- assertTrue(fileLock.isShared());
- assertSame(readOnlyFileChannel, fileLock.channel());
- assertEquals(POSITION, fileLock.position());
- assertEquals(SIZE, fileLock.size());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_NotShared() throws Exception {
- final long POSITION = 100;
- final long SIZE = 200;
- fileLock = writeOnlyFileChannel.lock(POSITION, SIZE, false);
- assertTrue(fileLock.isValid());
- assertFalse(fileLock.isShared());
- assertSame(writeOnlyFileChannel, fileLock.channel());
- assertEquals(POSITION, fileLock.position());
- assertEquals(SIZE, fileLock.size());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_Long_MAX_VALUE() throws Exception {
- final long POSITION = 0;
- final long SIZE = Long.MAX_VALUE;
- fileLock = readOnlyFileChannel.lock(POSITION, SIZE, true);
- assertTrue(fileLock.isValid());
- assertTrue(fileLock.isShared());
- assertEquals(POSITION, fileLock.position());
- assertEquals(SIZE, fileLock.size());
- assertSame(readOnlyFileChannel, fileLock.channel());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_Overlapping() throws Exception {
- final long POSITION = 100;
- final long SIZE = 200;
- fileLock = writeOnlyFileChannel.lock(POSITION, SIZE, false);
- assertTrue(fileLock.isValid());
-
- try {
- writeOnlyFileChannel.lock(POSITION + 1, SIZE, false);
- fail("should throw OverlappingFileLockException");
- } catch (OverlappingFileLockException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
- */
- public void test_lockJJZ_NotOverlapping() throws Exception {
- final long POSITION = 100;
- final long SIZE = 200;
- FileLock fileLock1 = writeOnlyFileChannel.lock(POSITION, SIZE, false);
- assertTrue(fileLock1.isValid());
- FileLock fileLock2 = writeOnlyFileChannel.lock(POSITION + SIZE, SIZE,
- false);
- assertTrue(fileLock2.isValid());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#lock(long,long,boolean)
- */
- public void test_lockJJZ_After_Release() throws Exception {
- fileLock = writeOnlyFileChannel.lock(0, 10, false);
- fileLock.release();
- // after release file lock can be obtained again.
- fileLock = writeOnlyFileChannel.lock(0, 10, false);
- assertTrue(fileLock.isValid());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock()
- */
- public void test_tryLock() throws Exception {
- MockFileChannel mockFileChannel = new MockFileChannel();
- // Verify that calling tryLock() leads to the method
- // tryLock(long, long, boolean) being called with a 0 for the
- // first parameter, Long.MAX_VALUE as the second parameter and false
- // as the third parameter.
- mockFileChannel.tryLock();
- assertTrue(mockFileChannel.isTryLockCalled);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_Closed() throws Exception {
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.tryLock(0, 10, false);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.tryLock(0, 10, false);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.tryLock(0, 10, false);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // throws ClosedChannelException before IllegalArgumentException
- try {
- readWriteFileChannel.tryLock(-1, 0, false);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_IllegalArgument() throws Exception {
- try {
- writeOnlyFileChannel.tryLock(0, -1, false);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- writeOnlyFileChannel.tryLock(-1, 0, false);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.tryLock(-1, -1, false);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.tryLock(Long.MAX_VALUE, 1, false);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_NonWritable() throws Exception {
- try {
- readOnlyFileChannel.tryLock(0, 10, false);
- fail("should throw NonWritableChannelException");
- } catch (NonWritableChannelException e) {
- // expected
- }
-
- // throws NonWritableChannelException before IllegalArgumentException
- try {
- readOnlyFileChannel.tryLock(-1, 0, false);
- fail("should throw NonWritableChannelException");
- } catch (NonWritableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_NonReadable() throws Exception {
- try {
- writeOnlyFileChannel.tryLock(0, 10, true);
- fail("should throw NonReadableChannelException");
- } catch (NonReadableChannelException e) {
- // expected
- }
-
- // throws NonReadableChannelException before IllegalArgumentException
- try {
- writeOnlyFileChannel.tryLock(-1, 0, true);
- fail("should throw NonReadableChannelException");
- } catch (NonReadableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_Shared() throws Exception {
- final long POSITION = 100;
- final long SIZE = 200;
- fileLock = readOnlyFileChannel.tryLock(POSITION, SIZE, true);
- assertTrue(fileLock.isValid());
- // fileLock.isShared depends on whether the underlying platform support
- // shared lock, but it works on Windows & Linux.
- assertTrue(fileLock.isShared());
- assertSame(readOnlyFileChannel, fileLock.channel());
- assertEquals(POSITION, fileLock.position());
- assertEquals(SIZE, fileLock.size());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_NotShared() throws Exception {
- final long POSITION = 100;
- final long SIZE = 200;
- fileLock = writeOnlyFileChannel.tryLock(POSITION, SIZE, false);
- assertTrue(fileLock.isValid());
- assertFalse(fileLock.isShared());
- assertSame(writeOnlyFileChannel, fileLock.channel());
- assertEquals(POSITION, fileLock.position());
- assertEquals(SIZE, fileLock.size());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_Long_MAX_VALUE() throws Exception {
- final long POSITION = 0;
- final long SIZE = Long.MAX_VALUE;
- fileLock = readOnlyFileChannel.tryLock(POSITION, SIZE, true);
- assertTrue(fileLock.isValid());
- assertTrue(fileLock.isShared());
- assertEquals(POSITION, fileLock.position());
- assertEquals(SIZE, fileLock.size());
- assertSame(readOnlyFileChannel, fileLock.channel());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_Overlapping() throws Exception {
- final long POSITION = 100;
- final long SIZE = 200;
- fileLock = writeOnlyFileChannel.lock(POSITION, SIZE, false);
- assertTrue(fileLock.isValid());
-
- try {
- writeOnlyFileChannel.lock(POSITION + 1, SIZE, false);
- fail("should throw OverlappingFileLockException");
- } catch (OverlappingFileLockException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
- */
- public void test_tryLockJJZ_NotOverlapping() throws Exception {
- final long POSITION = 100;
- final long SIZE = 200;
- FileLock fileLock1 = writeOnlyFileChannel
- .tryLock(POSITION, SIZE, false);
- assertTrue(fileLock1.isValid());
-
- FileLock fileLock2 = writeOnlyFileChannel.tryLock(POSITION + SIZE,
- SIZE, false);
- assertTrue(fileLock2.isValid());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#tryLock(long,long,boolean)
- */
- public void test_tryLockJJZ_After_Release() throws Exception {
- fileLock = writeOnlyFileChannel.tryLock(0, 10, false);
- fileLock.release();
-
- // after release file lock can be obtained again.
- fileLock = writeOnlyFileChannel.tryLock(0, 10, false);
- assertTrue(fileLock.isValid());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer)
- */
- public void test_readLByteBuffer_Null() throws Exception {
- ByteBuffer readBuffer = null;
-
- try {
- readOnlyFileChannel.read(readBuffer);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.read(readBuffer);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer)
- */
- public void test_readLByteBuffer_Closed() throws Exception {
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
-
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.read(readBuffer);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.read(readBuffer);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.read(readBuffer);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // should throw ClosedChannelException first
- readBuffer = null;
- try {
- readWriteFileChannel.read(readBuffer);
- fail();
- } catch (ClosedChannelException expected) {
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_readLByteBuffer_WriteOnly() throws Exception {
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
-
- try {
- writeOnlyFileChannel.read(readBuffer);
- fail();
- } catch (NonReadableChannelException expected) {
- }
-
- readBuffer = null;
- try {
- writeOnlyFileChannel.read(readBuffer);
- fail();
- } catch (NonReadableChannelException expected) {
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_readLByteBuffer_EmptyFile() throws Exception {
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
- int result = readOnlyFileChannel.read(readBuffer);
- assertEquals(-1, result);
- assertEquals(0, readBuffer.position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer)
- */
- public void test_readLByteBuffer_LimitedCapacity() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
-
- ByteBuffer readBuffer = ByteBuffer.allocate(LIMITED_CAPACITY);
- int result = readOnlyFileChannel.read(readBuffer);
- assertEquals(LIMITED_CAPACITY, result);
- assertEquals(LIMITED_CAPACITY, readBuffer.position());
- readBuffer.flip();
- for (int i = 0; i < LIMITED_CAPACITY; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
- }
- }
-
- public void test_readLByteBuffer() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
-
- ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_AS_BYTES_LENGTH);
- int result = readOnlyFileChannel.read(readBuffer);
- assertEquals(CONTENT_AS_BYTES_LENGTH, result);
- assertEquals(CONTENT_AS_BYTES_LENGTH, readBuffer.position());
- readBuffer.flip();
- for (int i = 0; i < CONTENT_AS_BYTES_LENGTH; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
- }
- }
-
- public void test_readLByteBufferJ_Null() throws Exception {
- try {
- readOnlyFileChannel.read(null, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- readWriteFileChannel.read(null, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_readLByteBufferJ_Closed() throws Exception {
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
-
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.read(readBuffer, 0);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.read(readBuffer, 0);
- fail();
- } catch (ClosedChannelException expected) {
- }
- }
-
- public void test_readLByteBufferJ_IllegalArgument() throws Exception {
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
-
- try {
- readOnlyFileChannel.read(readBuffer, -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- writeOnlyFileChannel.read(readBuffer, -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- readWriteFileChannel.read(readBuffer, -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void test_readLByteBufferJ_WriteOnly() throws Exception {
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
-
- try {
- writeOnlyFileChannel.read(readBuffer, 0);
- fail();
- } catch (NonReadableChannelException expected) {
- }
- }
-
- public void test_readLByteBufferJ_Emptyfile() throws Exception {
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
- int result = readOnlyFileChannel.read(readBuffer, 0);
- assertEquals(-1, result);
- assertEquals(0, readBuffer.position());
- }
-
- public void test_readLByteBufferJ_Position_BeyondFileLimit() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
-
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
- int result = readOnlyFileChannel.read(readBuffer,
- CONTENT_AS_BYTES.length);
- assertEquals(-1, result);
- assertEquals(0, readBuffer.position());
- }
-
- public void test_readLByteBufferJ_Position_As_Long() throws Exception {
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
- try {
- readOnlyFileChannel.read(readBuffer, Long.MAX_VALUE);
- } catch (IOException expected) {
- }
- }
-
- public void test_readLByteBufferJ() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
- ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
-
- final int BUFFER_POSITION = 1;
- readBuffer.position(BUFFER_POSITION);
-
- final int POSITION = 2;
- int result = readOnlyFileChannel.read(readBuffer, POSITION);
- assertEquals(CONTENT_AS_BYTES_LENGTH - POSITION, result);
- assertEquals(BUFFER_POSITION + result, readBuffer.position());
-
- readBuffer.flip();
- readBuffer.position(BUFFER_POSITION);
- for (int i = POSITION; i < CONTENT_AS_BYTES_LENGTH; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[])
- */
- public void test_read$LByteBuffer() throws Exception {
- // regression test for Harmony-849
- writeDataToFile(fileOfReadOnlyFileChannel);
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- readBuffers[0] = ByteBuffer.allocate(CAPACITY);
- readBuffers[1] = ByteBuffer.allocate(CAPACITY);
-
- long readCount = readOnlyFileChannel.read(readBuffers);
- assertEquals(CONTENT_AS_BYTES_LENGTH, readCount);
- assertEquals(CONTENT_AS_BYTES_LENGTH, readBuffers[0].position());
- assertEquals(0, readBuffers[1].position());
- readBuffers[0].flip();
- for (int i = 0; i < CONTENT_AS_BYTES_LENGTH; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffers[0].get());
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[])
- */
- public void test_read$LByteBuffer_mock() throws Exception {
- FileChannel mockChannel = new MockFileChannel();
- ByteBuffer[] buffers = new ByteBuffer[2];
- mockChannel.read(buffers);
- // Verify that calling read(ByteBuffer[] dsts) leads to the method
- // read(dsts, 0, dsts.length)
- assertTrue(((MockFileChannel)mockChannel).isReadCalled);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_Null() throws Exception {
- ByteBuffer[] readBuffers = null;
-
- try {
- readOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- readOnlyFileChannel.read(readBuffers, 1, 11);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- writeOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.read(readBuffers, 0, 1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- // first throws NullPointerException
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_Closed() throws Exception {
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- readBuffers[0] = ByteBuffer.allocate(CAPACITY);
-
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.read(readBuffers, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // regression test for Harmony-902
- readBuffers[0] = null;
- try {
- readOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- try {
- writeOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- try {
- readWriteFileChannel.read(readBuffers, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_WriteOnly() throws Exception {
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- readBuffers[0] = ByteBuffer.allocate(CAPACITY);
-
- try {
- writeOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw NonReadableChannelException");
- } catch (NonReadableChannelException e) {
- // expected
- }
-
- // first throws NonReadableChannelException.
- readBuffers[0] = null;
- try {
- writeOnlyFileChannel.read(readBuffers, 0, 1);
- fail("should throw NonReadableChannelException");
- } catch (NonReadableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_IndexOutOfBound() throws Exception {
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- readBuffers[0] = ByteBuffer.allocate(CAPACITY);
- readBuffers[1] = ByteBuffer.allocate(CAPACITY);
-
- try {
- readOnlyFileChannel.read(readBuffers, 2, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- readWriteFileChannel.read(null, -1, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- } catch (NullPointerException expected) {
- }
-
- try {
- writeOnlyFileChannel.read(readBuffers, 0, 3);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- readWriteFileChannel.read(readBuffers, -1, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.read(readBuffers, 0, 3);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_EmptyFile() throws Exception {
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- readBuffers[0] = ByteBuffer.allocate(CAPACITY);
- readBuffers[1] = ByteBuffer.allocate(CAPACITY);
- long result = readOnlyFileChannel.read(readBuffers, 0, 2);
- assertEquals(-1, result);
- assertEquals(0, readBuffers[0].position());
- assertEquals(0, readBuffers[1].position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_EmptyBuffers() throws Exception {
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- try {
- readOnlyFileChannel.read(readBuffers, 0, 2);
- } catch (NullPointerException e) {
- // expected
- }
-
- writeDataToFile(fileOfReadOnlyFileChannel);
- readBuffers[0] = ByteBuffer.allocate(CAPACITY);
- try {
- readOnlyFileChannel.read(readBuffers, 0, 2);
- } catch (NullPointerException e) {
- // expected
- }
-
- long result = readOnlyFileChannel.read(readBuffers, 0, 1);
- assertEquals(CONTENT_AS_BYTES_LENGTH, result);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_EmptyFile_EmptyBuffers()
- throws Exception {
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- // will not throw NullPointerException
- long result = readOnlyFileChannel.read(readBuffers, 0, 0);
- assertEquals(0, result);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_Length_Zero() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- readBuffers[0] = ByteBuffer.allocate(LIMITED_CAPACITY);
- readBuffers[1] = ByteBuffer.allocate(LIMITED_CAPACITY);
- long result = readOnlyFileChannel.read(readBuffers, 1, 0);
- assertEquals(0, result);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII_LimitedCapacity() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- readBuffers[0] = ByteBuffer.allocate(LIMITED_CAPACITY);
- readBuffers[1] = ByteBuffer.allocate(LIMITED_CAPACITY);
-
- // reads to the second buffer
- long result = readOnlyFileChannel.read(readBuffers, 1, 1);
- assertEquals(LIMITED_CAPACITY, result);
- assertEquals(0, readBuffers[0].position());
- assertEquals(LIMITED_CAPACITY, readBuffers[1].position());
-
- readBuffers[1].flip();
- for (int i = 0; i < LIMITED_CAPACITY; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffers[1].get());
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
- */
- public void test_read$LByteBufferII() throws Exception {
- writeDataToFile(fileOfReadOnlyFileChannel);
- ByteBuffer[] readBuffers = new ByteBuffer[2];
- readBuffers[0] = ByteBuffer.allocate(CAPACITY);
- readBuffers[1] = ByteBuffer.allocate(CAPACITY);
-
- // writes to the second buffer
- assertEquals(CONTENT_AS_BYTES_LENGTH, readOnlyFileChannel.read(
- readBuffers, 1, 1));
- assertEquals(0, readBuffers[0].position());
- assertEquals(CONTENT_AS_BYTES_LENGTH, readBuffers[1].position());
-
- readBuffers[1].flip();
- for (int i = 0; i < CONTENT_AS_BYTES_LENGTH; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffers[1].get());
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#isOpen()
- */
- public void test_isOpen() throws Exception {
- // Regression for HARMONY-40
- File logFile = File.createTempFile("out", "tmp");
- logFile.deleteOnExit();
- FileOutputStream out = new FileOutputStream(logFile, true);
- FileChannel channel = out.getChannel();
- out.write(1);
- out.close();
- assertFalse("Assert 0: Channel is still open", channel.isOpen());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#position()
- */
- public void test_position_append() throws Exception {
- // Regression test for Harmony-508
- File tmpfile = File.createTempFile("FileOutputStream", "tmp");
- tmpfile.deleteOnExit();
- FileOutputStream fos = new FileOutputStream(tmpfile);
- byte[] b = new byte[10];
- for (int i = 0; i < b.length; i++) {
- b[i] = (byte) i;
- }
- fos.write(b);
- fos.flush();
- fos.close();
- FileOutputStream f = new FileOutputStream(tmpfile, true);
- // Harmony expected 10, but the RI and Android report 0.
- assertEquals(0, f.getChannel().position());
- }
-
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_AbnormalMode() throws IOException {
- try {
- writeOnlyFileChannel.map(MapMode.READ_ONLY, 0, CONTENT_LENGTH);
- fail("should throw NonReadableChannelException.");
- } catch (NonReadableChannelException ex) {
- // expected;
- }
- try {
- writeOnlyFileChannel.map(MapMode.READ_WRITE, 0, CONTENT_LENGTH);
- fail("should throw NonReadableChannelException.");
- } catch (NonReadableChannelException ex) {
- // expected;
- }
- try {
- writeOnlyFileChannel.map(MapMode.PRIVATE, 0, CONTENT_LENGTH);
- fail("should throw NonReadableChannelException.");
- } catch (NonReadableChannelException ex) {
- // expected;
- }
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.map(MapMode.READ_WRITE, 0, -1);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException ex) {
- // expected;
- }
-
- try {
- readOnlyFileChannel.map(MapMode.READ_WRITE, 0, CONTENT_LENGTH);
- fail("should throw NonWritableChannelException .");
- } catch (NonWritableChannelException ex) {
- // expected;
- }
- try {
- readOnlyFileChannel.map(MapMode.PRIVATE, 0, CONTENT_LENGTH);
- fail("should throw NonWritableChannelException .");
- } catch (NonWritableChannelException ex) {
- // expected;
- }
- try {
- readOnlyFileChannel.map(MapMode.READ_WRITE, -1, CONTENT_LENGTH);
- fail("should throw IAE.");
- } catch (IllegalArgumentException ex) {
- // expected;
- }
- try {
- readOnlyFileChannel.map(MapMode.READ_WRITE, 0, -1);
- fail("should throw IAE.");
- } catch (IllegalArgumentException ex) {
- // expected;
- }
-
- try {
- readOnlyFileChannel.map(MapMode.READ_ONLY, 0, CONTENT_LENGTH + 1);
- fail();
- } catch (NonWritableChannelException expected) {
- } catch (IOException expected) {
- }
- try {
- readOnlyFileChannel.map(MapMode.READ_ONLY, 2, CONTENT_LENGTH - 1);
- fail();
- } catch (NonWritableChannelException expected) {
- } catch (IOException expected) {
- }
-
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.map(MapMode.READ_WRITE, 0, -1);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException ex) {
- // expected;
- }
- try {
- readOnlyFileChannel.map(MapMode.READ_ONLY, 2, CONTENT_LENGTH - 1);
- fail("should throw IOException.");
- } catch (IOException ex) {
- // expected;
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.map(MapMode.READ_WRITE, 0, -1);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException ex) {
- // expected;
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_ReadOnly_CloseChannel() throws IOException {
- // close channel has no effect on map if mapped
- assertEquals(0, readWriteFileChannel.size());
- MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.READ_ONLY,
- 0, CONTENT_LENGTH);
- assertEquals(CONTENT_LENGTH, readWriteFileChannel.size());
- readOnlyFileChannel.close();
- assertEquals(CONTENT_LENGTH, mapped.limit());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_Private_CloseChannel() throws IOException {
- MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.PRIVATE, 0,
- CONTENT_LENGTH);
- readWriteFileChannel.close();
- mapped.put(TEST_BYTES);
- assertEquals(CONTENT_LENGTH, mapped.limit());
- assertEquals("test".length(), mapped.position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_ReadOnly() throws IOException {
- MappedByteBuffer mapped = null;
- // try put something to readonly map
- writeDataToFile(fileOfReadOnlyFileChannel);
- mapped = readOnlyFileChannel.map(MapMode.READ_ONLY, 0, CONTENT_LENGTH);
- try {
- mapped.put(TEST_BYTES);
- fail("should throw ReadOnlyBufferException.");
- } catch (ReadOnlyBufferException ex) {
- // expected;
- }
- assertEquals(CONTENT_LENGTH, mapped.limit());
- assertEquals(CONTENT_LENGTH, mapped.capacity());
- assertEquals(0, mapped.position());
-
- // try to get a readonly map from read/write channel
- writeDataToFile(fileOfReadWriteFileChannel);
- mapped = readWriteFileChannel.map(MapMode.READ_ONLY, 0, CONTENT
- .length());
- assertEquals(CONTENT_LENGTH, mapped.limit());
- assertEquals(CONTENT_LENGTH, mapped.capacity());
- assertEquals(0, mapped.position());
-
- // map not change channel's position
- assertEquals(0, readOnlyFileChannel.position());
- assertEquals(0, readWriteFileChannel.position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_ReadOnly_NonZeroPosition() throws IOException {
- this.writeDataToFile(fileOfReadOnlyFileChannel);
- MappedByteBuffer mapped = readOnlyFileChannel.map(MapMode.READ_ONLY,
- 10, CONTENT_LENGTH - 10);
- assertEquals(CONTENT_LENGTH - 10, mapped.limit());
- assertEquals(CONTENT_LENGTH - 10, mapped.capacity());
- assertEquals(0, mapped.position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_Private() throws IOException {
- this.writeDataToFile(fileOfReadWriteFileChannel);
- MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.PRIVATE, 0,
- CONTENT_LENGTH);
- assertEquals(CONTENT_LENGTH, mapped.limit());
- // test copy on write if private
- ByteBuffer returnByPut = mapped.put(TEST_BYTES);
- assertSame(returnByPut, mapped);
- ByteBuffer checkBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
- mapped.force();
- readWriteFileChannel.read(checkBuffer);
- assertEquals(CONTENT, new String(checkBuffer.array(), "iso8859-1"));
-
- // test overflow
- try {
- mapped.put(("test" + CONTENT).getBytes("iso8859-1"));
- fail("should throw BufferOverflowException.");
- } catch (BufferOverflowException ex) {
- // expected;
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_Private_NonZeroPosition() throws IOException {
- MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.PRIVATE, 10,
- CONTENT_LENGTH - 10);
- assertEquals(CONTENT_LENGTH - 10, mapped.limit());
- assertEquals(CONTENT_LENGTH - 10, mapped.capacity());
- assertEquals(0, mapped.position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_ReadWrite() throws IOException {
- MappedByteBuffer mapped = null;
- writeDataToFile(fileOfReadWriteFileChannel);
- mapped = readWriteFileChannel.map(MapMode.READ_WRITE, 0, CONTENT
- .length());
-
- // put something will change its channel
- ByteBuffer returnByPut = mapped.put(TEST_BYTES);
- assertSame(returnByPut, mapped);
- String checkString = "test" + CONTENT.substring(4);
- ByteBuffer checkBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
- mapped.force();
- readWriteFileChannel.position(0);
- readWriteFileChannel.read(checkBuffer);
- assertEquals(checkString, new String(checkBuffer.array(), "iso8859-1"));
-
- try {
- mapped.put(("test" + CONTENT).getBytes("iso8859-1"));
- fail("should throw BufferOverflowException.");
- } catch (BufferOverflowException ex) {
- // expected;
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_ReadWrite_NonZeroPosition() throws IOException {
- // test position non-zero
- writeDataToFile(fileOfReadWriteFileChannel);
- MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.READ_WRITE,
- 10, CONTENT_LENGTH - 10);
- assertEquals(CONTENT_LENGTH - 10, mapped.limit());
- assertEquals(CONTENT.length() - 10, mapped.capacity());
- assertEquals(0, mapped.position());
- mapped.put(TEST_BYTES);
- ByteBuffer checkBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
- readWriteFileChannel.read(checkBuffer);
- String expected = CONTENT.substring(0, 10) + "test"
- + CONTENT.substring(10 + "test".length());
- assertEquals(expected, new String(checkBuffer.array(), "iso8859-1"));
- }
-
- /**
- * Tests map() method for the value of positions exceeding memory
- * page size and allocation granularity size.
- *
- * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
- */
- public void test_map_LargePosition() throws IOException {
- // Regression test for HARMONY-3085
- int[] sizes = {
- 4096, // 4K size (normal page size for Linux & Windows)
- 65536, // 64K size (alocation granularity size for Windows)
- };
- final int CONTENT_LEN = 10;
-
- for (int i = 0; i < sizes.length; ++i) {
- // reset the file and the channel for the iterations
- // (for the first iteration it was done by setUp()
- if (i > 0 ) {
- fileOfReadOnlyFileChannel = File.createTempFile(
- "File_of_readOnlyFileChannel", "tmp");
- fileOfReadOnlyFileChannel.deleteOnExit();
- readOnlyFileChannel = new FileInputStream(fileOfReadOnlyFileChannel)
- .getChannel();
- }
-
- writeLargeDataToFile(fileOfReadOnlyFileChannel, sizes[i] + 2 * CONTENT_LEN);
- MappedByteBuffer mapped = readOnlyFileChannel.map(MapMode.READ_ONLY,
- sizes[i], CONTENT_LEN);
- assertEquals("Incorrectly mapped file channel for " + sizes[i]
- + " position (capacity)", CONTENT_LEN, mapped.capacity());
- assertEquals("Incorrectly mapped file channel for " + sizes[i]
- + " position (limit)", CONTENT_LEN, mapped.limit());
- assertEquals("Incorrectly mapped file channel for " + sizes[i]
- + " position (position)", 0, mapped.position());
-
- // map not change channel's position
- assertEquals(0, readOnlyFileChannel.position());
-
- // Close the file and the channel before the next iteration
- readOnlyFileChannel.close();
- fileOfReadOnlyFileChannel.delete();
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer)
- */
- public void test_writeLByteBuffer_Null() throws Exception {
- ByteBuffer writeBuffer = null;
-
- try {
- writeOnlyFileChannel.write(writeBuffer);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.write(writeBuffer);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer)
- */
- public void test_writeLByteBuffer_Closed() throws Exception {
- ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
-
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.write(writeBuffer);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.write(writeBuffer);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.write(writeBuffer);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- writeBuffer = null;
- try {
- readWriteFileChannel.read(writeBuffer);
- fail();
- } catch (NullPointerException expected) {
- } catch (ClosedChannelException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer)
- */
- public void test_writeLByteBuffer_ReadOnly() throws Exception {
- ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
-
- try {
- readOnlyFileChannel.write(writeBuffer);
- fail("should throw NonWritableChannelException");
- } catch (NonWritableChannelException e) {
- // expected
- }
-
- // first throws NonWriteableChannelException
- writeBuffer = null;
- try {
- readOnlyFileChannel.write(writeBuffer);
- fail("should throw NonWritableChannelException");
- } catch (NonWritableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer)
- */
- public void test_writeLByteBuffer() throws Exception {
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
-
- int result = writeOnlyFileChannel.write(writeBuffer);
- assertEquals(CONTENT_AS_BYTES_LENGTH, result);
- assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffer.position());
- writeOnlyFileChannel.close();
-
- assertEquals(CONTENT_AS_BYTES_LENGTH, fileOfWriteOnlyFileChannel
- .length());
-
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- byte[] inputBuffer = new byte[CONTENT_AS_BYTES_LENGTH];
- fis.read(inputBuffer);
- assertTrue(Arrays.equals(CONTENT_AS_BYTES, inputBuffer));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer)
- */
- public void test_writeLByteBuffer_positioned() throws Exception {
- final int pos = 5;
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
- writeBuffer.position(pos);
- int result = writeOnlyFileChannel.write(writeBuffer);
- assertEquals(CONTENT_AS_BYTES_LENGTH - pos, result);
- assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffer.position());
- writeOnlyFileChannel.close();
-
- assertEquals(CONTENT_AS_BYTES_LENGTH - pos, fileOfWriteOnlyFileChannel
- .length());
-
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- byte[] inputBuffer = new byte[CONTENT_AS_BYTES_LENGTH - pos];
- fis.read(inputBuffer);
- String test = CONTENT.substring(pos);
- assertTrue(Arrays.equals(test.getBytes("iso8859-1"), inputBuffer));
- }
-
- public void test_writeLByteBufferJ_Null() throws Exception {
- try {
- readWriteFileChannel.write(null, 0);
- fail();
- } catch (NullPointerException expected) {
- } catch (NonWritableChannelException expected) {
- }
-
- try {
- writeOnlyFileChannel.write(null, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- readWriteFileChannel.write(null, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_writeLByteBufferJ_Closed() throws Exception {
- ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.write(writeBuffer, 0);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.write(writeBuffer, 0);
- fail();
- } catch (ClosedChannelException expected) {
- }
- }
-
- public void test_writeLByteBufferJ_ReadOnly() throws Exception {
- ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
- try {
- readOnlyFileChannel.write(writeBuffer, 10);
- fail();
- } catch (NonWritableChannelException expected) {
- }
- }
-
- public void test_writeLByteBufferJ_IllegalArgument() throws Exception {
- ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
-
- try {
- readOnlyFileChannel.write(writeBuffer, -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- writeOnlyFileChannel.write(writeBuffer, -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- readWriteFileChannel.write(writeBuffer, -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer,long)
- */
- public void test_writeLByteBufferJ() throws Exception {
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- final int POSITION = 4;
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
- int result = writeOnlyFileChannel.write(writeBuffer, POSITION);
- assertEquals(CONTENT_AS_BYTES_LENGTH, result);
- assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffer.position());
- writeOnlyFileChannel.close();
-
- assertEquals(POSITION + CONTENT_AS_BYTES_LENGTH,
- fileOfWriteOnlyFileChannel.length());
-
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- byte[] inputBuffer = new byte[POSITION + CONTENT_AS_BYTES_LENGTH];
- fis.read(inputBuffer);
- byte[] expectedResult = new byte[POSITION + CONTENT_AS_BYTES_LENGTH];
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, 0, POSITION);
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, POSITION,
- CONTENT_AS_BYTES_LENGTH);
- assertTrue(Arrays.equals(expectedResult, inputBuffer));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer[])
- */
- public void test_write$LByteBuffer() throws Exception {
- ByteBuffer[] writeBuffers = new ByteBuffer[2];
- MockFileChannel mockFileChannel = new MockFileChannel();
- mockFileChannel.write(writeBuffers);
- // verify that calling write(ByteBuffer[] srcs) leads to the method
- // write(srcs, 0, srcs.length)
- assertTrue(mockFileChannel.isWriteCalled);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
- */
- public void test_write$LByteBufferII_Null() throws Exception {
- ByteBuffer[] writeBuffers = null;
-
- try {
- readOnlyFileChannel.write(writeBuffers, 1, 2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- writeOnlyFileChannel.write(writeBuffers, 1, 2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.write(writeBuffers, 1, 2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- // first throws NullPointerException
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.write(writeBuffers, 0, 0);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
- */
- public void test_write$LByteBufferII_Closed() throws Exception {
- ByteBuffer[] writeBuffers = new ByteBuffer[2];
- writeBuffers[0] = ByteBuffer.allocate(CAPACITY);
- writeBuffers[1] = ByteBuffer.allocate(CAPACITY);
-
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.write(writeBuffers, 0, 2);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.write(writeBuffers, 0, 2);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.write(writeBuffers, 0, 2);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // throws ClosedChannelException first
- writeBuffers[0] = null;
- try {
- readWriteFileChannel.write(writeBuffers, 0, 2);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
- */
- public void test_write$LByteBufferII_ReadOnly() throws Exception {
- ByteBuffer[] writeBuffers = new ByteBuffer[2];
- writeBuffers[0] = ByteBuffer.allocate(CAPACITY);
- writeBuffers[1] = ByteBuffer.allocate(CAPACITY);
-
- try {
- readOnlyFileChannel.write(writeBuffers, 0, 2);
- fail();
- } catch (NonWritableChannelException e) {
- }
-
- try {
- readOnlyFileChannel.write(writeBuffers, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- writeBuffers = null;
- try {
- readOnlyFileChannel.write(writeBuffers, 0, 1);
- fail();
- } catch (NullPointerException expected) {
- }
-
- readOnlyFileChannel.close();
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
- */
- public void test_write$LByteBufferII_EmptyBuffers() throws Exception {
- ByteBuffer[] writeBuffers = new ByteBuffer[2];
- try {
- writeOnlyFileChannel.write(writeBuffers, 0, 2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.write(writeBuffers, 0, 2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
- */
- public void test_write$LByteBufferII() throws Exception {
- ByteBuffer[] writeBuffers = new ByteBuffer[2];
- writeBuffers[0] = ByteBuffer.wrap(CONTENT_AS_BYTES);
- writeBuffers[1] = ByteBuffer.wrap(CONTENT_AS_BYTES);
-
- long result = writeOnlyFileChannel.write(writeBuffers, 0, 2);
- assertEquals(CONTENT_AS_BYTES_LENGTH * 2, result);
- assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffers[0].position());
- assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffers[1].position());
- writeOnlyFileChannel.close();
-
- assertEquals(CONTENT_AS_BYTES_LENGTH * 2, fileOfWriteOnlyFileChannel
- .length());
-
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- byte[] inputBuffer = new byte[CONTENT_AS_BYTES_LENGTH];
- fis.read(inputBuffer);
- byte[] expectedResult = new byte[CONTENT_AS_BYTES_LENGTH * 2];
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, 0,
- CONTENT_AS_BYTES_LENGTH);
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult,
- CONTENT_AS_BYTES_LENGTH, CONTENT_AS_BYTES_LENGTH);
- assertTrue(Arrays.equals(CONTENT_AS_BYTES, inputBuffer));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_Closed()
- throws Exception {
- readByteChannel = DatagramChannel.open();
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.transferFrom(readByteChannel, 0, 0);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.transferFrom(readByteChannel, 0, 10);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.transferFrom(readByteChannel, 0, 0);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // should throw ClosedChannelException first.
- try {
- readWriteFileChannel.transferFrom(readByteChannel, 0, -1);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_SourceClosed()
- throws Exception {
- readByteChannel = DatagramChannel.open();
- readByteChannel.close();
-
- try {
- readOnlyFileChannel.transferFrom(readByteChannel, 0, 10);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- try {
- writeOnlyFileChannel.transferFrom(readByteChannel, 0, 10);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.transferFrom(readByteChannel, 0, 10);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // should throw ClosedChannelException first.
- try {
- readWriteFileChannel.transferFrom(readByteChannel, 0, -1);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_IllegalArgument()
- throws Exception {
- readByteChannel = DatagramChannel.open();
- try {
- writeOnlyFileChannel.transferFrom(readByteChannel, 10, -1);
- fail("should throw IllegalArgumentException.");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.transferFrom(readByteChannel, -1, -10);
- fail("should throw IllegalArgumentException.");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_NonWritable()
- throws Exception {
- readByteChannel = DatagramChannel.open();
- try {
- readOnlyFileChannel.transferFrom(readByteChannel, 0, 0);
- fail("should throw NonWritableChannelException.");
- } catch (NonWritableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_SourceNonReadable()
- throws Exception {
- try {
- readWriteFileChannel.transferFrom(writeOnlyFileChannel, 0, 0);
- fail("should throw NonReadableChannelException.");
- } catch (NonReadableChannelException e) {
- // expected
- }
-
- // not throws NonReadableChannelException first if position beyond file
- // size.
- readWriteFileChannel.transferFrom(writeOnlyFileChannel, 10, 10);
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_PositionBeyondSize()
- throws Exception {
- // init data to file.
- writeDataToFile(fileOfReadOnlyFileChannel);
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- final int READONLYFILECHANNELPOSITION = 2;
- readOnlyFileChannel.position(READONLYFILECHANNELPOSITION);
-
- final int POSITION = CONTENT_AS_BYTES_LENGTH * 2;
- final int LENGTH = 5;
- long result = writeOnlyFileChannel.transferFrom(readOnlyFileChannel,
- POSITION, LENGTH);
- assertEquals(0, result);
- assertEquals(0, writeOnlyFileChannel.position());
- assertEquals(READONLYFILECHANNELPOSITION, readOnlyFileChannel
- .position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_FileChannel()
- throws Exception {
- // init data to file.
- writeDataToFile(fileOfReadOnlyFileChannel);
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- final int READONLYFILECHANNELPOSITION = 2;
- final int WRITEONLYFILECHANNELPOSITION = 4;
- readOnlyFileChannel.position(READONLYFILECHANNELPOSITION);
- writeOnlyFileChannel.position(WRITEONLYFILECHANNELPOSITION);
-
- final int POSITION = 3;
- final int LENGTH = 5;
- long result = writeOnlyFileChannel.transferFrom(readOnlyFileChannel,
- POSITION, LENGTH);
- assertEquals(LENGTH, result);
- assertEquals(WRITEONLYFILECHANNELPOSITION, writeOnlyFileChannel
- .position());
- assertEquals(READONLYFILECHANNELPOSITION + LENGTH, readOnlyFileChannel
- .position());
- writeOnlyFileChannel.close();
-
- final int EXPECTED_LENGTH = POSITION + LENGTH;
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- byte[] resultContent = new byte[EXPECTED_LENGTH];
- fis.read(resultContent);
-
- byte[] expectedContent = new byte[EXPECTED_LENGTH];
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedContent, 0, POSITION);
- System.arraycopy(CONTENT_AS_BYTES, READONLYFILECHANNELPOSITION,
- expectedContent, POSITION, LENGTH);
- assertTrue(Arrays.equals(expectedContent, resultContent));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_DatagramChannel()
- throws Exception {
- // connects two datagramChannels.
- datagramChannelReceiver = DatagramChannel.open();
- datagramChannelReceiver.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0));
- datagramChannelSender = DatagramChannel.open();
- datagramChannelSender.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0));
- datagramChannelReceiver.socket().setSoTimeout(TIME_OUT);
- datagramChannelReceiver.connect(datagramChannelSender.socket()
- .getLocalSocketAddress());
- datagramChannelSender.socket().setSoTimeout(TIME_OUT);
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
- datagramChannelSender.socket().setSoTimeout(TIME_OUT);
- // sends data from datagramChannelSender to datagramChannelReceiver.
- datagramChannelSender.send(writeBuffer, datagramChannelReceiver
- .socket().getLocalSocketAddress());
- datagramChannelReceiver.socket().setSoTimeout(TIME_OUT);
-
- // transfers data from datagramChannelReceiver to fileChannel.
- long result = writeOnlyFileChannel.transferFrom(
- datagramChannelReceiver, 0, CONTENT_AS_BYTES_LENGTH);
- assertEquals(CONTENT_AS_BYTES_LENGTH, result);
- assertEquals(0, writeOnlyFileChannel.position());
- writeOnlyFileChannel.close();
-
- // gets content from file.
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- assertEquals(CONTENT_AS_BYTES_LENGTH, fileOfWriteOnlyFileChannel
- .length());
- byte[] resultContent = new byte[CONTENT_AS_BYTES_LENGTH];
- fis.read(resultContent);
-
- // compares contents.
- assertTrue(Arrays.equals(CONTENT_AS_BYTES, resultContent));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_SocketChannel()
- throws Exception {
- // connects two socketChannels.
- socketChannelReceiver = SocketChannel.open();
- serverSocketChannel = ServerSocketChannel.open();
- serverSocketChannel.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0));
- socketChannelReceiver.socket().setSoTimeout(TIME_OUT);
- socketChannelReceiver.connect(serverSocketChannel.socket()
- .getLocalSocketAddress());
- serverSocketChannel.socket().setSoTimeout(TIME_OUT);
- socketChannelSender = serverSocketChannel.accept();
- socketChannelSender.socket().setSoTimeout(TIME_OUT);
-
- // sends data from socketChannelSender to socketChannelReceiver.
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
- socketChannelSender.write(writeBuffer);
-
- // transfers data from socketChannelReceiver to fileChannel.
- long result = readWriteFileChannel.transferFrom(socketChannelReceiver,
- 0, CONTENT_AS_BYTES_LENGTH);
- assertEquals(CONTENT_AS_BYTES_LENGTH, result);
- assertEquals(0, readWriteFileChannel.position());
- readWriteFileChannel.close();
-
- // gets content from file.
- fis = new FileInputStream(fileOfReadWriteFileChannel);
- assertEquals(CONTENT_AS_BYTES_LENGTH, fileOfReadWriteFileChannel
- .length());
- byte[] resultContent = new byte[CONTENT_AS_BYTES_LENGTH];
- fis.read(resultContent);
-
- // compares content.
- assertTrue(Arrays.equals(CONTENT_AS_BYTES, resultContent));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
- */
- public void test_transferFromLReadableByteChannelJJ_Pipe() throws Exception {
- // inits data in file.
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- // inits pipe.
- pipe = Pipe.open();
-
- // writes content to pipe.
- ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
- pipe.sink().write(writeBuffer);
-
- // transfers data from pipe to fileChannel.
- final int OFFSET = 2;
- final int LENGTH = 4;
- long result = writeOnlyFileChannel.transferFrom(pipe.source(), OFFSET,
- LENGTH);
- assertEquals(LENGTH, result);
- writeOnlyFileChannel.close();
-
- // gets content from file.
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- byte[] resultBytes = new byte[OFFSET + LENGTH];
- fis.read(resultBytes);
-
- // compares content.
- byte[] expectedBytes = new byte[OFFSET + LENGTH];
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedBytes, 0, OFFSET);
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedBytes, OFFSET, LENGTH);
-
- assertTrue(Arrays.equals(expectedBytes, resultBytes));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_Null() throws Exception {
- writableByteChannel = null;
- try {
- readOnlyFileChannel.transferTo(0, 10, writableByteChannel);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- writeOnlyFileChannel.transferTo(0, 10, writableByteChannel);
- fail();
- } catch (NullPointerException expected) {
- } catch (NonReadableChannelException expected) {
- }
-
- try {
- readWriteFileChannel.transferTo(0, 10, writableByteChannel);
- fail();
- } catch (NullPointerException expected) {
- }
-
- readOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.transferTo(-1, 0, writableByteChannel);
- fail();
- } catch (NullPointerException expected) {
- } catch (NonReadableChannelException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_Closed() throws Exception {
- writableByteChannel = DatagramChannel.open();
- readOnlyFileChannel.close();
- try {
- readOnlyFileChannel.transferTo(0, 10, writableByteChannel);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- writeOnlyFileChannel.close();
- try {
- writeOnlyFileChannel.transferTo(0, 10, writableByteChannel);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- readWriteFileChannel.close();
- try {
- readWriteFileChannel.transferTo(0, 10, writableByteChannel);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // should throw ClosedChannelException first.
- try {
- readWriteFileChannel.transferTo(0, -1, writableByteChannel);
- fail("should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- public void test_transferToJJLWritableByteChannel_SourceClosed() throws Exception {
- writableByteChannel = DatagramChannel.open();
- writableByteChannel.close();
-
- try {
- readOnlyFileChannel.transferTo(0, 10, writableByteChannel);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- try {
- writeOnlyFileChannel.transferTo(0, 10, writableByteChannel);
- fail();
- } catch (ClosedChannelException expected) {
- } catch (NonReadableChannelException expected) {
- }
-
- try {
- readWriteFileChannel.transferTo(0, 10, writableByteChannel);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- try {
- readWriteFileChannel.transferTo(0, -1, writableByteChannel);
- fail();
- } catch (ClosedChannelException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_IllegalArgument()
- throws Exception {
- writableByteChannel = DatagramChannel.open();
- try {
- readOnlyFileChannel.transferTo(10, -1, writableByteChannel);
- fail("should throw IllegalArgumentException.");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.transferTo(-1, -10, writableByteChannel);
- fail("should throw IllegalArgumentException.");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void test_transferToJJLWritableByteChannel_NonReadable() throws Exception {
- writableByteChannel = DatagramChannel.open();
- try {
- writeOnlyFileChannel.transferTo(0, 10, writableByteChannel);
- fail();
- } catch (NonReadableChannelException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_TargetNonWritable()
- throws Exception {
- try {
- readWriteFileChannel.transferTo(0, 0, readOnlyFileChannel);
- fail("should throw NonWritableChannelException.");
- } catch (NonWritableChannelException e) {
- // expected
- }
-
- // first throws NonWritableChannelException even position out of file
- // size.
- try {
- readWriteFileChannel.transferTo(10, 10, readOnlyFileChannel);
- fail("should throw NonWritableChannelException.");
- } catch (NonWritableChannelException e) {
- // expected
- }
-
- // regression test for Harmony-941
- // first throws NonWritableChannelException even arguments are illegal.
- try {
- readWriteFileChannel.transferTo(-1, 10, readOnlyFileChannel);
- fail("should throw NonWritableChannelException.");
- } catch (NonWritableChannelException e) {
- // expected
- }
-
- try {
- readWriteFileChannel.transferTo(0, -1, readOnlyFileChannel);
- fail("should throw NonWritableChannelException.");
- } catch (NonWritableChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_PositionBeyondSize()
- throws Exception {
- // init data to file.
- writeDataToFile(fileOfReadOnlyFileChannel);
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- final int WRITEONLYFILECHANNELPOSITION = 2;
- writeOnlyFileChannel.position(WRITEONLYFILECHANNELPOSITION);
-
- final int POSITION = CONTENT_AS_BYTES_LENGTH * 2;
- final int LENGTH = 5;
- long result = readOnlyFileChannel.transferTo(POSITION, LENGTH,
- writeOnlyFileChannel);
- assertEquals(0, result);
- assertEquals(0, readOnlyFileChannel.position());
- assertEquals(WRITEONLYFILECHANNELPOSITION, writeOnlyFileChannel
- .position());
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_FileChannel()
- throws Exception {
- // init data to file.
- writeDataToFile(fileOfReadOnlyFileChannel);
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- final int READONLYFILECHANNELPOSITION = 2;
- final int WRITEONLYFILECHANNELPOSITION = 4;
- readOnlyFileChannel.position(READONLYFILECHANNELPOSITION);
- writeOnlyFileChannel.position(WRITEONLYFILECHANNELPOSITION);
-
- final int POSITION = 3;
- final int LENGTH = 5;
- long result = readOnlyFileChannel.transferTo(POSITION, LENGTH,
- writeOnlyFileChannel);
- assertEquals(LENGTH, result);
- assertEquals(READONLYFILECHANNELPOSITION, readOnlyFileChannel
- .position());
- assertEquals(WRITEONLYFILECHANNELPOSITION + LENGTH,
- writeOnlyFileChannel.position());
- writeOnlyFileChannel.close();
-
- final int EXPECTED_LENGTH = WRITEONLYFILECHANNELPOSITION + LENGTH;
- fis = new FileInputStream(fileOfWriteOnlyFileChannel);
- byte[] resultContent = new byte[EXPECTED_LENGTH];
- fis.read(resultContent);
-
- byte[] expectedContent = new byte[EXPECTED_LENGTH];
- System.arraycopy(CONTENT_AS_BYTES, 0, expectedContent, 0,
- WRITEONLYFILECHANNELPOSITION);
- System.arraycopy(CONTENT_AS_BYTES, POSITION, expectedContent,
- WRITEONLYFILECHANNELPOSITION, LENGTH);
- assertTrue(Arrays.equals(expectedContent, resultContent));
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_SocketChannel()
- throws Exception {
- // inits data into file.
- writeDataToFile(fileOfReadOnlyFileChannel);
-
- // connects two socketChannels.
- socketChannelReceiver = SocketChannel.open();
- socketChannelReceiver.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0));
- serverSocketChannel = ServerSocketChannel.open();
- serverSocketChannel.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0));
- socketChannelReceiver.socket().setSoTimeout(TIME_OUT);
- socketChannelReceiver.connect(serverSocketChannel.socket()
- .getLocalSocketAddress());
- serverSocketChannel.socket().setSoTimeout(TIME_OUT);
- socketChannelSender = serverSocketChannel.accept();
- socketChannelSender.socket().setSoTimeout(TIME_OUT);
-
- // position here should have no effect on transferTo since it uses
- // offset from file_begin
- final int POSITION = 10;
- readOnlyFileChannel.position(POSITION);
-
- // transfers data from file to socketChannelSender.
- final int OFFSET = 2;
- long result = readOnlyFileChannel.transferTo(OFFSET,
- CONTENT_AS_BYTES_LENGTH * 2, socketChannelSender);
- final int LENGTH = CONTENT_AS_BYTES_LENGTH - OFFSET;
- assertEquals(LENGTH, result);
- assertEquals(POSITION, readOnlyFileChannel.position());
- readOnlyFileChannel.close();
- socketChannelSender.close();
-
- // gets contents from socketChannelReceiver.
- ByteBuffer readBuffer = ByteBuffer.allocate(LENGTH + 1);
- int totalRead = 0;
- int countRead = 0;
- long beginTime = System.currentTimeMillis();
- while ((countRead = socketChannelReceiver.read(readBuffer)) != -1) {
- totalRead += countRead;
- // TIMEOUT
- if (System.currentTimeMillis() - beginTime > TIME_OUT) {
- break;
- }
- }
- assertEquals(LENGTH, totalRead);
-
- // compares contents.
- readBuffer.flip();
- for (int i = OFFSET; i < CONTENT_AS_BYTES_LENGTH; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_DatagramChannel()
- throws Exception {
- // inits data to file.
- writeDataToFile(fileOfReadOnlyFileChannel);
-
- // connects two datagramChannel
- datagramChannelReceiver = DatagramChannel.open();
- datagramChannelReceiver.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0));
- datagramChannelSender = DatagramChannel.open();
- datagramChannelSender.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0));
- datagramChannelSender.socket().setSoTimeout(TIME_OUT);
- datagramChannelSender.connect(datagramChannelReceiver.socket()
- .getLocalSocketAddress());
- datagramChannelReceiver.socket().setSoTimeout(TIME_OUT);
- datagramChannelReceiver.connect(datagramChannelSender.socket()
- .getLocalSocketAddress());
-
- // transfers data from fileChannel to datagramChannelSender
- long result = readOnlyFileChannel.transferTo(0,
- CONTENT_AS_BYTES_LENGTH, datagramChannelSender);
- assertEquals(CONTENT_AS_BYTES_LENGTH, result);
- assertEquals(0, readOnlyFileChannel.position());
- readOnlyFileChannel.close();
- datagramChannelSender.close();
-
- // gets contents from datagramChannelReceiver
- ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_AS_BYTES_LENGTH);
- long beginTime = System.currentTimeMillis();
- int totalRead = 0;
- while (totalRead < CONTENT_AS_BYTES_LENGTH) {
- totalRead += datagramChannelReceiver.read(readBuffer);
- if (System.currentTimeMillis() - beginTime > TIME_OUT) {
- break;
- }
- }
- assertEquals(CONTENT_AS_BYTES_LENGTH, totalRead);
-
- // compares contents.
- readBuffer.flip();
- for (int i = 0; i < CONTENT_AS_BYTES_LENGTH; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
- }
- }
-
- /**
- * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
- */
- public void test_transferToJJLWritableByteChannel_Pipe() throws Exception {
- // inits data in file.
- writeDataToFile(fileOfReadOnlyFileChannel);
-
- // inits pipe.
- pipe = Pipe.open();
-
- // transfers data from fileChannel to pipe.
- final int OFFSET = 2;
- final int LENGTH = 4;
- long result = readOnlyFileChannel.transferTo(OFFSET, LENGTH, pipe
- .sink());
- assertEquals(LENGTH, result);
- assertEquals(0, readOnlyFileChannel.position());
- readOnlyFileChannel.close();
-
- // gets content from pipe.
- ByteBuffer readBuffer = ByteBuffer.allocate(LENGTH);
- result = pipe.source().read(readBuffer);
- assertEquals(LENGTH, result);
-
- // compares content.
- readBuffer.flip();
- for (int i = OFFSET; i < OFFSET + LENGTH; i++) {
- assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
- }
- }
-
- /**
- * Regression test for Harmony-3324
- * Make sure we could delete the file after we called transferTo() method.
- */
- public void test_transferTo_couldDelete() throws Exception {
- // init data in files
- writeDataToFile(fileOfReadOnlyFileChannel);
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- // call transferTo() method
- readOnlyFileChannel.transferTo(0 , 2, writeOnlyFileChannel);
-
- // delete both files
- readOnlyFileChannel.close();
- writeOnlyFileChannel.close();
- boolean rDel = fileOfReadOnlyFileChannel.delete();
- boolean wDel = fileOfWriteOnlyFileChannel.delete();
-
- // make sure both files were deleted
- assertTrue("File " + readOnlyFileChannel + " exists", rDel);
- assertTrue("File " + writeOnlyFileChannel + " exists", wDel);
- }
-
- /**
- * Regression test for Harmony-3324
- * Make sure we could delete the file after we called transferFrom() method.
- */
- public void test_transferFrom_couldDelete() throws Exception {
- // init data in files
- writeDataToFile(fileOfReadOnlyFileChannel);
- writeDataToFile(fileOfWriteOnlyFileChannel);
-
- // call transferTo() method
- writeOnlyFileChannel.transferFrom(readOnlyFileChannel, 0 , 2);
-
- // delete both files
- readOnlyFileChannel.close();
- writeOnlyFileChannel.close();
- boolean rDel = fileOfReadOnlyFileChannel.delete();
- boolean wDel = fileOfWriteOnlyFileChannel.delete();
-
- // make sure both files were deleted
- assertTrue("File " + readOnlyFileChannel + " exists", rDel);
- assertTrue("File " + writeOnlyFileChannel + " exists", wDel);
- }
-
- private class MockFileChannel extends FileChannel {
-
- private boolean isLockCalled = false;
-
- private boolean isTryLockCalled = false;
-
- private boolean isReadCalled = false;
-
- private boolean isWriteCalled = false;
-
- public void force(boolean arg0) throws IOException {
- // do nothing
- }
-
- public FileLock lock(long position, long size, boolean shared)
- throws IOException {
- // verify that calling lock() leads to the method
- // lock(0, Long.MAX_VALUE, false).
- if (0 == position && Long.MAX_VALUE == size && false == shared) {
- isLockCalled = true;
- }
- return null;
- }
-
- public MappedByteBuffer map(MapMode arg0, long arg1, long arg2)
- throws IOException {
- return null;
- }
-
- public long position() throws IOException {
- return 0;
- }
-
- public FileChannel position(long arg0) throws IOException {
- return null;
- }
-
- public int read(ByteBuffer arg0) throws IOException {
- return 0;
- }
-
- public int read(ByteBuffer arg0, long arg1) throws IOException {
- return 0;
- }
-
- public long read(ByteBuffer[] srcs, int offset, int length)
- throws IOException {
- // verify that calling read(ByteBuffer[] srcs) leads to the method
- // read(srcs, 0, srcs.length)
- if (0 == offset && length == srcs.length) {
- isReadCalled = true;
- }
- return 0;
- }
-
- public long size() throws IOException {
- return 0;
- }
-
- public long transferFrom(ReadableByteChannel arg0, long arg1, long arg2)
- throws IOException {
- return 0;
- }
-
- public long transferTo(long arg0, long arg1, WritableByteChannel arg2)
- throws IOException {
- return 0;
- }
-
- public FileChannel truncate(long arg0) throws IOException {
- return null;
- }
-
- public FileLock tryLock(long position, long size, boolean shared)
- throws IOException {
- // verify that calling tryLock() leads to the method
- // tryLock(0, Long.MAX_VALUE, false).
- if (0 == position && Long.MAX_VALUE == size && false == shared) {
- isTryLockCalled = true;
- }
- return null;
- }
-
- public int write(ByteBuffer arg0) throws IOException {
- return 0;
- }
-
- public int write(ByteBuffer arg0, long arg1) throws IOException {
- return 0;
- }
-
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException {
- // verify that calling write(ByteBuffer[] srcs) leads to the method
- // write(srcs, 0, srcs.length)
- if(0 == offset && length == srcs.length){
- isWriteCalled = true;
- }
- return 0;
- }
-
- protected void implCloseChannel() throws IOException {
-
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.java
deleted file mode 100644
index b60096c..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.FileLockInterruptionException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for FileLockInterruptionException
- */
-public class FileLockInterruptionExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.FileLockInterruptionException#FileLockInterruptionException()}
- */
- public void test_Constructor() {
- FileLockInterruptionException e = new FileLockInterruptionException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new FileLockInterruptionException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this,
- new FileLockInterruptionException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java
deleted file mode 100644
index 12142e8..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-
-import junit.framework.TestCase;
-
-/**
- * Tests class FileLock.
- */
-public class FileLockTest extends TestCase {
-
- private FileChannel readWriteChannel;
-
- private MockFileLock mockLock;
-
- class MockFileLock extends FileLock {
-
- boolean isValid = true;
-
- protected MockFileLock(FileChannel channel, long position, long size,
- boolean shared) {
- super(channel, position, size, shared);
- }
-
- public boolean isValid() {
- return isValid;
- }
-
- public void release() throws IOException {
- isValid = false;
- }
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- File tempFile = File.createTempFile("testing", "tmp");
- tempFile.deleteOnExit();
- RandomAccessFile randomAccessFile = new RandomAccessFile(tempFile, "rw");
- readWriteChannel = randomAccessFile.getChannel();
- mockLock = new MockFileLock(readWriteChannel, 10, 100, false);
- }
-
- protected void tearDown() throws IOException {
- if (readWriteChannel != null) {
- readWriteChannel.close();
- }
- }
-
- /**
- * @tests java.nio.channels.FileLock#FileLock(FileChannel, long, long,
- * boolean)
- */
- public void test_Constructor_Ljava_nio_channels_FileChannelJJZ() {
- FileLock fileLock1 = new MockFileLock(null, 0, 0, false);
- assertNull(fileLock1.channel());
-
- try {
- new MockFileLock(readWriteChannel, -1, 0, false);
- fail("should throw IllegalArgumentException.");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- try {
- new MockFileLock(readWriteChannel, 0, -1, false);
- fail("should throw IllegalArgumentException.");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- // Harmony-682 regression test
- try {
- new MockFileLock(readWriteChannel, Long.MAX_VALUE, 1, false);
- fail("should throw IllegalArgumentException.");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.FileLock#channel()
- */
- public void test_channel() {
- assertSame(readWriteChannel, mockLock.channel());
- FileLock lock = new MockFileLock(null, 0, 10, true);
- assertNull(lock.channel());
- }
-
- /**
- * @tests java.nio.channels.FileLock#position()
- */
- public void test_position() {
- FileLock fileLock1 = new MockFileLock(readWriteChannel, 20, 100, true);
- assertEquals(20, fileLock1.position());
-
- final long position = ((long) Integer.MAX_VALUE + 1);
- FileLock fileLock2 = new MockFileLock(readWriteChannel, position, 100,
- true);
- assertEquals(position, fileLock2.position());
- }
-
- /**
- * @tests java.nio.channels.FileLock#size()
- */
- public void test_size() {
- FileLock fileLock1 = new MockFileLock(readWriteChannel, 20, 100, true);
- assertEquals(100, fileLock1.size());
-
- final long position = 0x0FFFFFFFFFFFFFFFL;
- final long size = ((long) Integer.MAX_VALUE + 1);
- FileLock fileLock2 = new MockFileLock(readWriteChannel, position, size,
- true);
- assertEquals(size, fileLock2.size());
- }
-
- /**
- * @tests java.nio.channels.FileLock#isShared()
- */
- public void test_isShared() {
- assertFalse(mockLock.isShared());
- FileLock lock = new MockFileLock(null, 0, 10, true);
- assertTrue(lock.isShared());
- }
-
- /**
- * @tests java.nio.channels.FileLock#overlaps(long, long)
- */
- public void test_overlaps_JJ() {
- assertTrue(mockLock.overlaps(0, 11));
- assertFalse(mockLock.overlaps(0, 10));
- assertTrue(mockLock.overlaps(100, 110));
- assertTrue(mockLock.overlaps(99, 110));
- assertFalse(mockLock.overlaps(-1, 10));
- //Harmony-671 regression test
- assertTrue(mockLock.overlaps(1, 120));
- assertTrue(mockLock.overlaps(20, 50));
- }
-
- /**
- * @tests java.nio.channels.FileLock#isValid()
- */
- public void test_isValid() throws IOException {
- FileLock fileLock = readWriteChannel.lock();
- assertTrue(fileLock.isValid());
- fileLock.release();
- assertFalse(fileLock.isValid());
- }
-
- /**
- * @tests java.nio.channels.FileLock#release()
- */
- public void test_release() throws Exception {
- File file = File.createTempFile("test", "tmp");
- file.deleteOnExit();
- FileOutputStream fout = new FileOutputStream(file);
- FileChannel fileChannel = fout.getChannel();
- FileLock fileLock = fileChannel.lock();
- fileChannel.close();
- try {
- fileLock.release();
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- // release after release
- fout = new FileOutputStream(file);
- fileChannel = fout.getChannel();
- fileLock = fileChannel.lock();
- fileLock.release();
- fileChannel.close();
- try {
- fileLock.release();
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- //expected
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java
deleted file mode 100644
index a8cdf83..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.IllegalBlockingModeException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for IllegalBlockingModeException
- */
-public class IllegalBlockingModeExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.IllegalBlockingModeException#IllegalBlockingModeException()}
- */
- public void test_Constructor() {
- IllegalBlockingModeException e = new IllegalBlockingModeException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new IllegalBlockingModeException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest
- .verifyGolden(this, new IllegalBlockingModeException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.java
deleted file mode 100644
index 2fa3171..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.IllegalSelectorException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for IllegalSelectorException
- */
-public class IllegalSelectorExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.IllegalSelectorException#IllegalSelectorException()}
- */
- public void test_Constructor() {
- IllegalSelectorException e = new IllegalSelectorException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new IllegalSelectorException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new IllegalSelectorException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MapModeTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MapModeTest.java
deleted file mode 100644
index 33234eb..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MapModeTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.FileChannel;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for FileChannel.MapMode
- */
-public class MapModeTest extends TestCase {
-
- /**
- * java.nio.channels.FileChannel.MapMode#PRIVATE,READONLY,READWRITE
- */
- public void test_PRIVATE_READONLY_READWRITE() {
- assertNotNull(FileChannel.MapMode.PRIVATE);
- assertNotNull(FileChannel.MapMode.READ_ONLY);
- assertNotNull(FileChannel.MapMode.READ_WRITE);
-
- assertFalse(FileChannel.MapMode.PRIVATE
- .equals(FileChannel.MapMode.READ_ONLY));
- assertFalse(FileChannel.MapMode.PRIVATE
- .equals(FileChannel.MapMode.READ_WRITE));
- assertFalse(FileChannel.MapMode.READ_ONLY
- .equals(FileChannel.MapMode.READ_WRITE));
- }
-
- /**
- * java.nio.channels.FileChannel.MapMode#toString()
- */
- public void test_toString() {
- assertNotNull(FileChannel.MapMode.PRIVATE.toString());
- assertNotNull(FileChannel.MapMode.READ_ONLY.toString());
- assertNotNull(FileChannel.MapMode.READ_WRITE.toString());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockDatagramChannel.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockDatagramChannel.java
deleted file mode 100644
index c8dc2af..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockDatagramChannel.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.spi.SelectorProvider;
-
-class MockDatagramChannel extends DatagramChannel {
-
- public MockDatagramChannel(SelectorProvider arg0) {
- super(arg0);
- }
-
- public DatagramSocket socket() {
- return null;
- }
-
- public boolean isConnected() {
- return false;
- }
-
- public DatagramChannel connect(SocketAddress arg0) throws IOException {
- return null;
- }
-
- public DatagramChannel disconnect() throws IOException {
- return null;
- }
-
- public SocketAddress receive(ByteBuffer arg0) throws IOException {
- return null;
- }
-
- public int send(ByteBuffer arg0, SocketAddress arg1) throws IOException {
- return 0;
- }
-
- public int read(ByteBuffer arg0) throws IOException {
- return 0;
- }
-
- public long read(ByteBuffer[] arg0, int arg1, int arg2) throws IOException {
- return 0;
- }
-
- public int write(ByteBuffer arg0) throws IOException {
- return 0;
- }
-
- public long write(ByteBuffer[] arg0, int arg1, int arg2) throws IOException {
- return 0;
- }
-
- protected void implCloseSelectableChannel() throws IOException {
- // empty
- }
-
- protected void implConfigureBlocking(boolean arg0) throws IOException {
- // empty
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockServerSocketChannel.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockServerSocketChannel.java
deleted file mode 100644
index 2058a7a..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockServerSocketChannel.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.spi.SelectorProvider;
-
-class MockServerSocketChannel extends ServerSocketChannel {
-
- protected MockServerSocketChannel(SelectorProvider arg0) {
- super(arg0);
- }
-
- public ServerSocket socket() {
- return null;
- }
-
- public SocketChannel accept() throws IOException {
- return null;
- }
-
- protected void implCloseSelectableChannel() throws IOException {
- }
-
- protected void implConfigureBlocking(boolean arg0) throws IOException {
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockSocketChannel.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockSocketChannel.java
deleted file mode 100644
index 9d130ca..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/MockSocketChannel.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.spi.SelectorProvider;
-
-class MockSocketChannel extends SocketChannel {
-
- protected MockSocketChannel(SelectorProvider arg0) {
- super(arg0);
- }
-
- public Socket socket() {
- return null;
- }
-
- public boolean isConnected() {
- return false;
- }
-
- public boolean isConnectionPending() {
- return false;
- }
-
- public boolean connect(SocketAddress arg0) throws IOException {
- return false;
- }
-
- public boolean finishConnect() throws IOException {
- return false;
- }
-
- public int read(ByteBuffer arg0) throws IOException {
- return 0;
- }
-
- public long read(ByteBuffer[] arg0, int arg1, int arg2) throws IOException {
- return 0;
- }
-
- public int write(ByteBuffer arg0) throws IOException {
- return 0;
- }
-
- public long write(ByteBuffer[] arg0, int arg1, int arg2) throws IOException {
- return 0;
- }
-
- protected void implCloseSelectableChannel() throws IOException {
- }
-
- protected void implConfigureBlocking(boolean arg0) throws IOException {
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.java
deleted file mode 100644
index 2ba7ba6..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.NoConnectionPendingException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for NoConnectionPendingException
- */
-public class NoConnectionPendingExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.NoConnectionPendingException#NoConnectionPendingException()}
- */
- public void test_Constructor() {
- NoConnectionPendingException e = new NoConnectionPendingException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new NoConnectionPendingException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest
- .verifyGolden(this, new NoConnectionPendingException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.java
deleted file mode 100644
index 8c44f17..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.NonReadableChannelException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for NonReadableChannelException
- */
-public class NonReadableChannelExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.NonReadableChannelException#NonReadableChannelException()}
- */
- public void test_Constructor() {
- NonReadableChannelException e = new NonReadableChannelException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new NonReadableChannelException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new NonReadableChannelException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.java
deleted file mode 100644
index 459d85a..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.NonWritableChannelException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for NonWritableChannelException
- */
-public class NonWritableChannelExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.NonWritableChannelException#NonWritableChannelException()}
- */
- public void test_Constructor() {
- NonWritableChannelException e = new NonWritableChannelException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new NonWritableChannelException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new NonWritableChannelException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.java
deleted file mode 100644
index d1c2d86..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.NotYetBoundException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for NotYetBoundException
- */
-public class NotYetBoundExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.NotYetBoundException#NotYetBoundException()}
- */
- public void test_Constructor() {
- NotYetBoundException e = new NotYetBoundException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new NotYetBoundException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new NotYetBoundException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.java
deleted file mode 100644
index 09e4c1c..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.NotYetConnectedException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for NotYetConnectedException
- */
-public class NotYetConnectedExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.NotYetConnectedException#NotYetConnectedException()}
- */
- public void test_Constructor() {
- NotYetConnectedException e = new NotYetConnectedException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new NotYetConnectedException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new NotYetConnectedException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.java
deleted file mode 100644
index d06f807..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.OverlappingFileLockException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for OverlappingFileLockException
- */
-public class OverlappingFileLockExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.OverlappingFileLockException#OverlappingFileLockException()}
- */
- public void test_Constructor() {
- OverlappingFileLockException e = new OverlappingFileLockException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new OverlappingFileLockException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest
- .verifyGolden(this, new OverlappingFileLockException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/PipeTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/PipeTest.java
deleted file mode 100644
index 53f19c4..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/PipeTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.net.NetPermission;
-import java.nio.channels.Pipe;
-import java.nio.channels.Pipe.SinkChannel;
-import java.nio.channels.Pipe.SourceChannel;
-import java.security.Permission;
-
-import junit.framework.TestCase;
-
-/*
- * Tests for Pipe and its default implementation
- */
-public class PipeTest extends TestCase {
-
- /**
- * @tests java.nio.channels.Pipe#open()
- */
- public void test_open() throws IOException{
- Pipe pipe = Pipe.open();
- assertNotNull(pipe);
- }
-
- /**
- * @tests java.nio.channels.Pipe#sink()
- */
- public void test_sink() throws IOException {
- Pipe pipe = Pipe.open();
- SinkChannel sink = pipe.sink();
- assertTrue(sink.isBlocking());
- }
-
- /**
- * @tests java.nio.channels.Pipe#source()
- */
- public void test_source() throws IOException {
- Pipe pipe = Pipe.open();
- SourceChannel source = pipe.source();
- assertTrue(source.isBlocking());
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectableChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectableChannelTest.java
deleted file mode 100644
index 25b5f00..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectableChannelTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.spi.SelectorProvider;
-import junit.framework.TestCase;
-
-/*
- * Tests for SelectableChannel
- */
-public class SelectableChannelTest extends TestCase {
-
- /**
- * @tests SelectableChannel#register(Selector, int)
- */
- public void test_register_LSelectorI() throws IOException {
- MockSelectableChannel msc = new MockSelectableChannel();
- // Verify that calling register(Selector, int) leads to the method
- // register(Selector, int, Object) being called with a null value
- // for the third argument.
- msc.register(Selector.open(), SelectionKey.OP_ACCEPT);
- assertTrue(msc.isCalled);
- }
-
- private class MockSelectableChannel extends SelectableChannel {
-
- private boolean isCalled = false;
-
- public Object blockingLock() {
- return null;
- }
-
- public SelectableChannel configureBlocking(boolean block)
- throws IOException {
- return null;
- }
-
- public boolean isBlocking() {
- return false;
- }
-
- public boolean isRegistered() {
- return false;
- }
-
- public SelectionKey keyFor(Selector sel) {
- return null;
- }
-
- public SelectorProvider provider() {
- return null;
- }
-
- public SelectionKey register(Selector sel, int ops, Object att)
- throws ClosedChannelException {
- if (null == att) {
- isCalled = true;
- }
- return null;
- }
-
- public int validOps() {
- return 0;
- }
-
- protected void implCloseChannel() throws IOException {
- // empty
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectionKeyTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectionKeyTest.java
deleted file mode 100644
index ed33752..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectionKeyTest.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.nio.channels.CancelledKeyException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-
-import junit.framework.TestCase;
-import tests.support.Support_PortManager;
-
-/*
- * Tests for SelectionKey and its default implementation
- */
-public class SelectionKeyTest extends TestCase {
-
- Selector selector;
-
- SocketChannel sc;
-
- SelectionKey selectionKey;
-
- private static String LOCAL_ADDR = "127.0.0.1";
-
- protected void setUp() throws Exception {
- super.setUp();
- selector = Selector.open();
- sc = SocketChannel.open();
- sc.configureBlocking(false);
- selectionKey = sc.register(selector, SelectionKey.OP_CONNECT);
- }
-
- protected void tearDown() throws Exception {
- selectionKey.cancel();
- selectionKey = null;
- selector.close();
- selector = null;
- super.tearDown();
- }
-
- static class MockSelectionKey extends SelectionKey {
- private int interestOps;
-
- MockSelectionKey(int ops) {
- interestOps = ops;
- }
-
- public void cancel() {
- // do nothing
- }
-
- public SelectableChannel channel() {
- return null;
- }
-
- public int interestOps() {
- return 0;
- }
-
- public SelectionKey interestOps(int operations) {
- return null;
- }
-
- public boolean isValid() {
- return true;
- }
-
- public int readyOps() {
- return interestOps;
- }
-
- public Selector selector() {
- return null;
- }
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#attach(Object)
- */
- public void test_attach() {
- MockSelectionKey mockSelectionKey = new MockSelectionKey(SelectionKey.OP_ACCEPT);
- // no previous, return null
- Object o = new Object();
- Object check = mockSelectionKey.attach(o);
- assertNull(check);
-
- // null parameter is ok
- check = mockSelectionKey.attach(null);
- assertSame(o, check);
-
- check = mockSelectionKey.attach(o);
- assertNull(check);
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#attachment()
- */
- public void test_attachment() {
- MockSelectionKey mockSelectionKey = new MockSelectionKey(SelectionKey.OP_ACCEPT);
- assertNull(mockSelectionKey.attachment());
- Object o = new Object();
- mockSelectionKey.attach(o);
- assertSame(o, mockSelectionKey.attachment());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#channel()
- */
- public void test_channel() {
- assertSame(sc, selectionKey.channel());
- // can be invoked even canceled
- selectionKey.cancel();
- assertSame(sc, selectionKey.channel());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#interestOps()
- */
- public void test_interestOps() {
- assertEquals(SelectionKey.OP_CONNECT, selectionKey.interestOps());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#interestOps(int)
- */
- public void test_interestOpsI() {
- selectionKey.interestOps(SelectionKey.OP_WRITE);
- assertEquals(SelectionKey.OP_WRITE, selectionKey.interestOps());
-
- try {
- selectionKey.interestOps(SelectionKey.OP_ACCEPT);
- fail("should throw IAE.");
- } catch (IllegalArgumentException ex) {
- // expected;
- }
-
- try {
- selectionKey.interestOps(~sc.validOps());
- fail("should throw IAE.");
- } catch (IllegalArgumentException ex) {
- // expected;
- }
- try {
- selectionKey.interestOps(-1);
- fail("should throw IAE.");
- } catch (IllegalArgumentException ex) {
- // expected;
- }
-
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#isValid()
- */
- public void test_isValid() {
- assertTrue(selectionKey.isValid());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#isValid()
- */
- public void test_isValid_KeyCancelled() {
- selectionKey.cancel();
- assertFalse(selectionKey.isValid());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#isValid()
- */
- public void test_isValid_ChannelColsed() throws IOException {
- sc.close();
- assertFalse(selectionKey.isValid());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#isValid()
- */
- public void test_isValid_SelectorClosed() throws IOException {
- selector.close();
- assertFalse(selectionKey.isValid());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#isAcceptable()
- */
- public void test_isAcceptable() throws IOException {
- MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
- assertTrue(mockSelectionKey1.isAcceptable());
- MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_CONNECT);
- assertFalse(mockSelectionKey2.isAcceptable());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#isConnectable()
- */
- public void test_isConnectable() {
- MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_CONNECT);
- assertTrue(mockSelectionKey1.isConnectable());
- MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
- assertFalse(mockSelectionKey2.isConnectable());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#isReadable()
- */
- public void test_isReadable() {
- MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_READ);
- assertTrue(mockSelectionKey1.isReadable());
- MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
- assertFalse(mockSelectionKey2.isReadable());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#isWritable()
- */
- public void test_isWritable() {
- MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_WRITE);
- assertTrue(mockSelectionKey1.isWritable());
- MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
- assertFalse(mockSelectionKey2.isWritable());
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#cancel()
- */
- public void test_cancel() {
- selectionKey.cancel();
- try {
- selectionKey.isAcceptable();
- fail("should throw CancelledKeyException.");
- } catch (CancelledKeyException ex) {
- // expected
- }
- try {
- selectionKey.isConnectable();
- fail("should throw CancelledKeyException.");
- } catch (CancelledKeyException ex) {
- // expected
- }
- try {
- selectionKey.isReadable();
- fail("should throw CancelledKeyException.");
- } catch (CancelledKeyException ex) {
- // expected
- }
- try {
- selectionKey.isWritable();
- fail("should throw CancelledKeyException.");
- } catch (CancelledKeyException ex) {
- // expected
- }
-
- try {
- selectionKey.readyOps();
- fail("should throw CancelledKeyException.");
- } catch (CancelledKeyException ex) {
- // expected
- }
-
- try {
- selectionKey.interestOps(SelectionKey.OP_CONNECT);
- fail("should throw CancelledKeyException.");
- } catch (CancelledKeyException ex) {
- // expected
- }
-
- try {
- selectionKey.interestOps();
- fail("should throw CancelledKeyException.");
- } catch (CancelledKeyException ex) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#readyOps()
- */
- public void test_readyOps() throws IOException {
- int port = Support_PortManager.getNextPort();
- ServerSocket ss = new ServerSocket(port);
- try {
- sc.connect(new InetSocketAddress(LOCAL_ADDR, port));
- assertEquals(0, selectionKey.readyOps());
- assertFalse(selectionKey.isConnectable());
- selector.select();
- assertEquals(SelectionKey.OP_CONNECT, selectionKey.readyOps());
- } finally {
- ss.close();
- ss = null;
- }
-
- }
-
- /**
- * @tests java.nio.channels.SelectionKey#selector()
- */
- public void test_selector() {
- assertSame(selector, selectionKey.selector());
- selectionKey.cancel();
- assertSame(selector, selectionKey.selector());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java
deleted file mode 100644
index 3617230..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java
+++ /dev/null
@@ -1,685 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.Pipe;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.Set;
-import junit.framework.TestCase;
-
-/*
- * Tests for Selector and its default implementation
- */
-public class SelectorTest extends TestCase {
- private static final int WAIT_TIME = 100;
-
- private SocketAddress localAddress;
-
- private Selector selector;
-
- private ServerSocketChannel ssc;
-
- private enum SelectType {
- NULL, TIMEOUT, NOW
- };
-
- protected void setUp() throws Exception {
- super.setUp();
- ssc = ServerSocketChannel.open();
- ssc.configureBlocking(false);
- ServerSocket ss = ssc.socket();
- ss.bind(null);
- localAddress = ss.getLocalSocketAddress();
- selector = Selector.open();
- }
-
- protected void tearDown() throws Exception {
- try {
- ssc.close();
- } catch (Exception e) {
- // do nothing
- }
- try {
- selector.close();
- } catch (Exception e) {
- // do nothing
- }
- super.tearDown();
- }
-
- /**
- * @tests java.nio.channels.Selector#open()
- */
- public void test_open() throws IOException {
- assertNotNull(selector);
- }
-
- /**
- * @tests Selector#isOpen()
- */
- public void test_isOpen() throws IOException {
- assertTrue(selector.isOpen());
- selector.close();
- assertFalse(selector.isOpen());
- }
-
- /**
- * @tests java.nio.channels.Selector#provider()
- */
- public void test_provider() throws IOException {
- // should be system default provider
- assertNotNull(selector.provider());
- assertSame(SelectorProvider.provider(), selector.provider());
- }
-
- /**
- * @tests java.nio.channels.Selector#keys()
- */
- public void test_keys() throws IOException {
- SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT);
-
- Set<SelectionKey> keySet = selector.keys();
- Set<SelectionKey> keySet2 = selector.keys();
-
- assertSame(keySet, keySet2);
- assertEquals(1,keySet.size());
- SelectionKey key2 = keySet.iterator().next();
- assertEquals(key,key2);
-
- // Any attempt to modify keys will cause UnsupportedOperationException
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- SelectionKey key3 = sc.register(selector, SelectionKey.OP_READ);
- try {
- keySet2.add(key3);
- fail("should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // expected
- }
- try {
- keySet2.remove(key3);
- fail("should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // expected
- }
- try {
- keySet2.clear();
- fail("should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // expected
- }
-
- selector.close();
- try {
- selector.keys();
- fail("should throw ClosedSelectorException");
- } catch (ClosedSelectorException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.Selector#keys()
- */
- public void test_selectedKeys() throws IOException {
- SocketChannel sc = SocketChannel.open();
- ssc.register(selector, SelectionKey.OP_ACCEPT);
- try {
- int count = 0;
- sc.connect(localAddress);
- count = blockingSelect(SelectType.NULL, 0);
- assertEquals(1, count);
- Set<SelectionKey> selectedKeys = selector.selectedKeys();
- Set<SelectionKey> selectedKeys2 = selector.selectedKeys();
- assertSame(selectedKeys, selectedKeys2);
-
- assertEquals(1, selectedKeys.size());
- assertEquals(ssc.keyFor(selector), selectedKeys.iterator().next());
- // add one key into selectedKeys
- try {
- selectedKeys.add(ssc.keyFor(selector));
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // expected
- }
-
- // no exception should be thrown
- selectedKeys.clear();
-
- Set<SelectionKey> selectedKeys3 = selector.selectedKeys();
- assertSame(selectedKeys, selectedKeys3);
-
- ssc.keyFor(selector).cancel();
- assertEquals(0, selectedKeys.size());
- selector.close();
- try {
- selector.selectedKeys();
- fail("should throw ClosedSelectorException");
- } catch (ClosedSelectorException e) {
- // expected
- }
- } finally {
- sc.close();
- }
- }
-
- /**
- * @tests java.nio.channel.Selector#selectNow()
- */
- public void test_selectNow() throws IOException {
- assert_select_OP_ACCEPT(SelectType.NOW, 0);
- assert_select_OP_CONNECT(SelectType.NOW, 0);
- assert_select_OP_READ(SelectType.NOW, 0);
- assert_select_OP_WRITE(SelectType.NOW, 0);
- }
-
- /**
- * @tests java.nio.channel.Selector#selectNow()
- */
- public void test_selectNow_SelectorClosed() throws IOException {
- assert_select_SelectorClosed(SelectType.NOW, 0);
- }
-
- /**
- * @test java.nio.channels.Selector#selectNow()
- */
- public void test_selectNow_Timeout() throws IOException {
- // make sure selectNow doesn't block
- selector.selectNow();
- }
-
- /**
- * @tests java.nio.channel.Selector#select()
- */
- public void test_select() throws IOException {
- assert_select_OP_ACCEPT(SelectType.NULL, 0);
- assert_select_OP_CONNECT(SelectType.NULL, 0);
- assert_select_OP_READ(SelectType.NULL, 0);
- assert_select_OP_WRITE(SelectType.NULL, 0);
- }
-
- /**
- * @tests java.nio.channel.Selector#select()
- */
- public void test_select_SelectorClosed() throws IOException {
- assert_select_SelectorClosed(SelectType.NULL, 0);
- }
-
- /**
- * @tests java.nio.channel.Selector#select(long)
- */
- public void test_selectJ() throws IOException {
- assert_select_OP_ACCEPT(SelectType.TIMEOUT, 0);
- assert_select_OP_CONNECT(SelectType.TIMEOUT, 0);
- assert_select_OP_READ(SelectType.TIMEOUT, 0);
- assert_select_OP_WRITE(SelectType.TIMEOUT, 0);
-
- assert_select_OP_ACCEPT(SelectType.TIMEOUT, WAIT_TIME);
- assert_select_OP_CONNECT(SelectType.TIMEOUT, WAIT_TIME);
- assert_select_OP_READ(SelectType.TIMEOUT, WAIT_TIME);
- assert_select_OP_WRITE(SelectType.TIMEOUT, WAIT_TIME);
- }
-
- /**
- * @tests java.nio.channel.Selector#select(long)
- */
- public void test_selectJ_SelectorClosed() throws IOException {
- assert_select_SelectorClosed(SelectType.TIMEOUT, 0);
- selector = Selector.open();
- assert_select_SelectorClosed(SelectType.TIMEOUT, WAIT_TIME);
- }
-
- /**
- * @tests java.nio.channel.Selector#select(long)
- */
- public void test_selectJ_Exception() throws IOException {
- try {
- selector.select(-1);
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * @test java.nio.channels.Selector#select(long)
- */
- public void test_selectJ_Timeout() throws IOException {
- // make sure select(timeout) doesn't block
- selector.select(WAIT_TIME);
- }
-
- /**
- * @test java.nio.channels.Selector#select(long)
- */
- public void test_selectJ_Empty_Keys() throws IOException {
- // regression test, see HARMONY-3888.
- // make sure select(long) does wait for specified amount of
- // time if keys.size() == 0 (initial state of selector).
-
- final long SELECT_TIMEOUT_MS = 2000;
-
- long t0 = System.nanoTime();
- selector.select(SELECT_TIMEOUT_MS);
- long t1 = System.nanoTime();
-
- long waitMs = (t1 - t0) / 1000L / 1000L;
- assertTrue(waitMs >= SELECT_TIMEOUT_MS);
- assertTrue(waitMs < 5*SELECT_TIMEOUT_MS);
- }
-
- /**
- * @tests java.nio.channels.Selector#wakeup()
- */
- public void test_wakeup() throws IOException {
- /*
- * make sure the test does not block on select
- */
- selector.wakeup();
- selectOnce(SelectType.NULL, 0);
- selector.wakeup();
- selectOnce(SelectType.TIMEOUT, 0);
-
- // try to wakeup select. The invocation sequence of wakeup and select
- // doesn't affect test result.
- new Thread() {
- public void run() {
-
- try {
- Thread.sleep(WAIT_TIME);
- } catch (InterruptedException e) {
- // ignore
- }
- selector.wakeup();
- }
- }.start();
- selectOnce(SelectType.NULL, 0);
-
- // try to wakeup select. The invocation sequence of wakeup and select
- // doesn't affect test result.
- new Thread() {
- public void run() {
-
- try {
- Thread.sleep(WAIT_TIME);
- } catch (InterruptedException e) {
- // ignore
- }
- selector.wakeup();
- }
- }.start();
- selectOnce(SelectType.TIMEOUT, 0);
- }
-
- public void test_keySetViewsModifications() throws IOException {
- Set<SelectionKey> keys = selector.keys();
-
- SelectionKey key1 = ssc.register(selector, SelectionKey.OP_ACCEPT);
-
- assertTrue(keys.contains(key1));
-
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- SelectionKey key2 = sc.register(selector, SelectionKey.OP_READ);
-
- assertTrue(keys.contains(key1));
- assertTrue(keys.contains(key2));
-
- key1.cancel();
- assertTrue(keys.contains(key1));
-
- selector.selectNow();
- assertFalse(keys.contains(key1));
- assertTrue(keys.contains(key2));
- }
-
- /**
- * This test cancels a key while selecting to verify that the cancelled
- * key set is processed both before and after the call to the underlying
- * operating system.
- */
- public void test_cancelledKeys() throws Exception {
- final AtomicReference<Throwable> failure = new AtomicReference<Throwable>();
- final AtomicBoolean complete = new AtomicBoolean();
-
- final Pipe pipe = Pipe.open();
- pipe.source().configureBlocking(false);
- final SelectionKey key = pipe.source().register(selector, SelectionKey.OP_READ);
-
- Thread thread = new Thread() {
- public void run() {
- try {
- // make sure to call key.cancel() while the main thread is selecting
- Thread.sleep(500);
- key.cancel();
- assertFalse(key.isValid());
- pipe.sink().write(ByteBuffer.allocate(4)); // unblock select()
- } catch (Throwable e) {
- failure.set(e);
- } finally {
- complete.set(true);
- }
- }
- };
- assertTrue(key.isValid());
-
- thread.start();
- do {
- assertEquals(0, selector.select(5000)); // blocks
- assertEquals(0, selector.selectedKeys().size());
- } while (!complete.get()); // avoid spurious interrupts
- assertFalse(key.isValid());
-
- thread.join();
- assertNull(failure.get());
- }
-
- public void testOpChange() throws Exception {
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- sc.register(selector, SelectionKey.OP_CONNECT);
- try {
- sc.connect(localAddress);
- int count = blockingSelect(SelectType.TIMEOUT, 100);
- assertEquals(1, count);
- Set<SelectionKey> selectedKeys = selector.selectedKeys();
- assertEquals(1, selectedKeys.size());
- SelectionKey key = selectedKeys.iterator().next();
- assertEquals(sc.keyFor(selector), key);
- assertEquals(SelectionKey.OP_CONNECT, key.readyOps());
- // select again, it should return 0
- count = selectOnce(SelectType.TIMEOUT, 100);
- assertEquals(0, count);
- // but selectedKeys remains the same as previous
- assertSame(selectedKeys, selector.selectedKeys());
- sc.finishConnect();
-
- // same selector, but op is changed
- SelectionKey key1 = sc.register(selector, SelectionKey.OP_WRITE);
- assertEquals(key, key1);
- count = blockingSelect(SelectType.TIMEOUT, 100);
- assertEquals(1, count);
- selectedKeys = selector.selectedKeys();
- assertEquals(1, selectedKeys.size());
- key = selectedKeys.iterator().next();
- assertEquals(key, key1);
- assertEquals(SelectionKey.OP_WRITE, key.readyOps());
-
- selectedKeys.clear();
- } finally {
- try {
- ssc.accept().close();
- } catch (Exception e) {
- // do nothing
- }
- try {
- sc.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- }
-
- public void test_nonBlockingConnect() throws IOException {
- SocketChannel channel = null;
- try {
- channel = SocketChannel.open();
- channel.configureBlocking(false);
- Selector selector = Selector.open();
- channel.register(selector, SelectionKey.OP_CONNECT);
- channel.connect(localAddress);
- channel.finishConnect();
- selector.select();
- assertEquals(0, selector.selectedKeys().size());
- } finally {
- channel.close();
- }
- }
-
- private void assert_select_SelectorClosed(SelectType type, int timeout)
- throws IOException {
- // selector is closed
- selector.close();
- try {
- selectOnce(type, timeout);
- fail("should throw ClosedSelectorException");
- } catch (ClosedSelectorException e) {
- // expected
- }
- }
-
- private void assert_select_OP_ACCEPT(SelectType type, int timeout)
- throws IOException, ClosedChannelException {
- SocketChannel sc = SocketChannel.open();
- SocketChannel client = null;
- try {
- ssc.register(selector, SelectionKey.OP_ACCEPT);
- sc.connect(localAddress);
- int count = blockingSelect(type, timeout);
- assertEquals(1, count);
- Set<SelectionKey> selectedKeys = selector.selectedKeys();
- assertEquals(1, selectedKeys.size());
- SelectionKey key = selectedKeys.iterator().next();
- assertEquals(ssc.keyFor(selector), key);
- assertEquals(SelectionKey.OP_ACCEPT, key.readyOps());
- // select again, it should return 0
- count = selectOnce(type, timeout);
- assertEquals(0,count);
- // but selectedKeys remains the same as previous
- assertSame(selectedKeys, selector.selectedKeys());
- client = ssc.accept();
- selectedKeys.clear();
- } finally {
- try {
- sc.close();
- } catch (IOException e) {
- // do nothing
- }
- if (null != client) {
- client.close();
- }
- }
- ssc.keyFor(selector).cancel();
- }
-
- private void assert_select_OP_CONNECT(SelectType type, int timeout)
- throws IOException, ClosedChannelException {
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- sc.register(selector, SelectionKey.OP_CONNECT);
- try {
- sc.connect(localAddress);
- int count = blockingSelect(type, timeout);
- assertEquals(1, count);
- Set<SelectionKey> selectedKeys = selector.selectedKeys();
- assertEquals(1, selectedKeys.size());
- SelectionKey key = selectedKeys.iterator().next();
- assertEquals(sc.keyFor(selector), key);
- assertEquals(SelectionKey.OP_CONNECT, key.readyOps());
- // select again, it should return 0
- count = selectOnce(type, timeout);
- assertEquals(0, count);
- // but selectedKeys remains the same as previous
- assertSame(selectedKeys, selector.selectedKeys());
- sc.finishConnect();
- selectedKeys.clear();
- } finally {
- try {
- ssc.accept().close();
- } catch (Exception e) {
- // do nothing
- }
-
- try {
- sc.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- }
-
- private void assert_select_OP_READ(SelectType type, int timeout)
- throws IOException {
- SocketChannel sc = SocketChannel.open();
- SocketChannel client = null;
- SocketChannel sc2 = SocketChannel.open();
- SocketChannel client2 = null;
- try {
- ssc.configureBlocking(true);
- sc.connect(localAddress);
- client = ssc.accept();
- sc.configureBlocking(false);
- sc.register(selector, SelectionKey.OP_READ);
- client.configureBlocking(true);
-
- sc2.connect(localAddress);
- client2 = ssc.accept();
- sc2.configureBlocking(false);
- sc2.register(selector, SelectionKey.OP_READ);
- client2.configureBlocking(true);
-
- client.write(ByteBuffer.wrap("a".getBytes()));
- int count = blockingSelect(type, timeout);
- assertEquals(1, count);
- Set<SelectionKey> selectedKeys = selector.selectedKeys();
- assertEquals(1, selectedKeys.size());
- SelectionKey key = selectedKeys.iterator().next();
- assertEquals(sc.keyFor(selector), key);
- assertEquals(SelectionKey.OP_READ, key.readyOps());
- // select again, it should return 0
- count = selectOnce(type, timeout);
- assertEquals(0, count);
- // but selectedKeys remains the same as previous
- assertSame(selectedKeys, selector.selectedKeys());
-
- sc.read(ByteBuffer.allocate(8));
-
- // the second SocketChannel should be selected this time
- client2.write(ByteBuffer.wrap("a".getBytes()));
- count = blockingSelect(type, timeout);
- assertEquals(1, count);
- // selectedKeys still includes the key of sc, because the key of sc
- // is not removed last time.
- selectedKeys = selector.selectedKeys();
- assertEquals(2, selectedKeys.size());
- } finally {
- if (null != client) {
- try {
- client.close();
- } catch (Exception e) {
- // ignore
- }
- }
- if (null != client2) {
- try {
- client2.close();
- } catch (Exception e) {
- // ignore
- }
- }
- try {
- sc.close();
- } catch (Exception e) {
- // ignore
- }
- try {
- sc2.close();
- } catch (Exception e) {
- // ignore
- }
- ssc.configureBlocking(false);
- }
- }
-
- private void assert_select_OP_WRITE(SelectType type, int timeout)
- throws IOException {
- SocketChannel sc = SocketChannel.open();
- SocketChannel client = null;
- try {
- sc.connect(localAddress);
- ssc.configureBlocking(true);
- client = ssc.accept();
- sc.configureBlocking(false);
- sc.register(selector, SelectionKey.OP_WRITE);
- int count = blockingSelect(type, timeout);
- assertEquals(1, count);
- Set<SelectionKey> selectedKeys = selector.selectedKeys();
- assertEquals(1, selectedKeys.size());
- SelectionKey key = selectedKeys.iterator().next();
- assertEquals(sc.keyFor(selector), key);
- assertEquals(SelectionKey.OP_WRITE, key.readyOps());
- // select again, it should return 0
- count = selectOnce(type, timeout);
- assertEquals(0, count);
- // but selectedKeys remains the same as previous
- assertSame(selectedKeys, selector.selectedKeys());
- } finally {
- if (null != client) {
- client.close();
- }
- try {
- sc.close();
- } catch (IOException e) {
- // do nothing
- }
- ssc.configureBlocking(false);
- }
- }
-
- private int blockingSelect(SelectType type, int timeout) throws IOException {
- int ret = 0;
- do {
- ret = selectOnce(type, timeout);
- if (ret > 0) {
- return ret;
- }
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- // ignore
- }
- } while (true);
- }
-
- private int selectOnce(SelectType type, int timeout) throws IOException {
- int ret = 0;
- switch (type) {
- case NULL:
- ret = selector.select();
- break;
- case TIMEOUT:
- ret = selector.select(timeout);
- break;
- case NOW:
- ret = selector.selectNow();
- break;
- }
- return ret;
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ServerSocketChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ServerSocketChannelTest.java
deleted file mode 100644
index fdbbc48..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ServerSocketChannelTest.java
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.nio.ByteBuffer;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.IllegalBlockingModeException;
-import java.nio.channels.NotYetBoundException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.spi.SelectorProvider;
-
-import junit.framework.TestCase;
-import tests.support.Support_PortManager;
-
-/*
- * test for ServerSocketChannel
- */
-public class ServerSocketChannelTest extends TestCase {
-
- private static final int CAPACITY_NORMAL = 200;
-
- private static final int CAPACITY_64KB = 65536;
-
- private static final int TIME_UNIT = 200;
-
- private InetSocketAddress localAddr1;
-
- private ServerSocketChannel serverChannel;
-
- private SocketChannel clientChannel;
-
- protected void setUp() throws Exception {
- super.setUp();
- this.localAddr1 = new InetSocketAddress(
- "127.0.0.1", Support_PortManager
- .getNextPort());
- this.serverChannel = ServerSocketChannel.open();
- this.clientChannel = SocketChannel.open();
- }
-
- protected void tearDown() throws Exception {
- if (null != this.serverChannel) {
- try {
- this.serverChannel.close();
- } catch (Exception e) {
- //ignore
- }
-
- }
- if (null != this.clientChannel) {
- try {
- this.clientChannel.close();
- } catch (Exception e) {
- //ignore
- }
- }
- super.tearDown();
- }
-
- // -------------------------------------------------------------------
- // Test for methods in abstract class.
- // -------------------------------------------------------------------
-
- /*
- * Test method for 'java.nio.channels.ServerSocketChannel.validOps()'
- */
- public void testValidOps() {
- MockServerSocketChannel testMSChnlnull = new MockServerSocketChannel(
- null);
- MockServerSocketChannel testMSChnl = new MockServerSocketChannel(
- SelectorProvider.provider());
- assertEquals(SelectionKey.OP_ACCEPT, this.serverChannel.validOps());
- assertEquals(SelectionKey.OP_ACCEPT, testMSChnl.validOps());
- assertEquals(SelectionKey.OP_ACCEPT, testMSChnlnull.validOps());
-
- }
-
- /*
- * Test method for 'java.nio.channels.ServerSocketChannel.open()'
- */
- public void testOpen() {
- MockServerSocketChannel testMSChnl = new MockServerSocketChannel(null);
- MockServerSocketChannel testMSChnlnotnull = new MockServerSocketChannel(
- SelectorProvider.provider());
- assertEquals(SelectionKey.OP_ACCEPT, testMSChnlnotnull.validOps());
- assertNull(testMSChnl.provider());
- assertNotNull(testMSChnlnotnull.provider());
- assertNotNull(this.serverChannel.provider());
- assertEquals(testMSChnlnotnull.provider(), this.serverChannel
- .provider());
- }
-
- // -------------------------------------------------------------------
- // Test for socket()
- // -------------------------------------------------------------------
-
- /*
- * Test method for 'java.nio.channels.ServerSocketChannel.socket()'
- */
- public void testSocket_Block_BeforeClose() throws Exception {
- assertTrue(this.serverChannel.isOpen());
- assertTrue(this.serverChannel.isBlocking());
- ServerSocket s1 = this.serverChannel.socket();
- assertFalse(s1.isClosed());
- assertSocketNotAccepted(s1);
- ServerSocket s2 = this.serverChannel.socket();
- // same
- assertSame(s1, s2);
-
- // socket close makes the channel close
- s1.close();
- assertFalse(this.serverChannel.isOpen());
-
- }
-
- public void testSocket_NonBlock_BeforeClose() throws Exception {
- assertTrue(this.serverChannel.isOpen());
- this.serverChannel.configureBlocking(false);
- ServerSocket s1 = this.serverChannel.socket();
- assertFalse(s1.isClosed());
- assertSocketNotAccepted(s1);
- ServerSocket s2 = this.serverChannel.socket();
- // same
- assertSame(s1, s2);
-
- // socket close makes the channel close
- s1.close();
- assertFalse(this.serverChannel.isOpen());
-
- }
-
- public void testSocket_Block_Closed() throws Exception {
- this.serverChannel.close();
- assertFalse(this.serverChannel.isOpen());
- assertTrue(this.serverChannel.isBlocking());
- ServerSocket s1 = this.serverChannel.socket();
- assertTrue(s1.isClosed());
- assertSocketNotAccepted(s1);
- ServerSocket s2 = this.serverChannel.socket();
- // same
- assertSame(s1, s2);
- }
-
- public void testSocket_NonBlock_Closed() throws Exception {
- this.serverChannel.configureBlocking(false);
- this.serverChannel.close();
- assertFalse(this.serverChannel.isBlocking());
- assertFalse(this.serverChannel.isOpen());
- ServerSocket s1 = this.serverChannel.socket();
- assertTrue(s1.isClosed());
- assertSocketNotAccepted(s1);
- ServerSocket s2 = this.serverChannel.socket();
- // same
- assertSame(s1, s2);
- }
-
- private void assertSocketNotAccepted(ServerSocket s) throws IOException {
- assertFalse(s.isBound());
- assertNull(s.getInetAddress());
- assertEquals(-1, s.getLocalPort());
- assertNull(s.getLocalSocketAddress());
- try {
- assertEquals(0, s.getSoTimeout());
- } catch (IOException expected) {
- // Android doesn't cache the timeout, so the getsockopt(2) fails and throws.
- }
- }
-
- public void testChannelBasicStatus() {
- ServerSocket gotSocket = this.serverChannel.socket();
- assertFalse(gotSocket.isClosed());
- assertTrue(this.serverChannel.isBlocking());
- assertFalse(this.serverChannel.isRegistered());
- assertEquals(SelectionKey.OP_ACCEPT, this.serverChannel.validOps());
- assertEquals(SelectorProvider.provider(), this.serverChannel.provider());
- }
-
- // -------------------------------------------------------------------
- // Test for accept()
- // -------------------------------------------------------------------
-
- /*
- * Test method for 'java.nio.channels.ServerSocketChannel.accept()'
- */
-
- public void testAccept_Block_NotYetBound() throws IOException {
- assertTrue(this.serverChannel.isOpen());
- assertTrue(this.serverChannel.isBlocking());
- try {
- this.serverChannel.accept();
- fail("Should throw NotYetBoundException");
- } catch (NotYetBoundException e) {
- // correct
- }
- }
-
- public void testAccept_NonBlock_NotYetBound() throws IOException {
- assertTrue(this.serverChannel.isOpen());
- this.serverChannel.configureBlocking(false);
- try {
- this.serverChannel.accept();
- fail("Should throw NotYetBoundException");
- } catch (NotYetBoundException e) {
- // correct
- }
- }
-
- public void testAccept_ClosedChannel() throws Exception {
- this.serverChannel.close();
- assertFalse(this.serverChannel.isOpen());
- try {
- this.serverChannel.accept();
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // OK.
- }
- }
-
- public void testAccept_Block_NoConnect() throws IOException {
- assertTrue(this.serverChannel.isBlocking());
- ServerSocket gotSocket = this.serverChannel.socket();
- gotSocket.bind(localAddr1);
- // blocking mode , will block and wait for ever...
- // so must close the server channel with another thread.
- new Thread() {
- public void run() {
- try {
- Thread.sleep(TIME_UNIT);
- ServerSocketChannelTest.this.serverChannel.close();
- } catch (Exception e) {
- fail("Fail to close the server channel because of"
- + e.getClass().getName());
- }
- }
- }.start();
- try {
- this.serverChannel.accept();
- fail("Should throw a AsynchronousCloseException");
- } catch (AsynchronousCloseException e) {
- // OK.
- }
- }
-
- public void testAccept_NonBlock_NoConnect() throws IOException {
- ServerSocket gotSocket = this.serverChannel.socket();
- gotSocket.bind(localAddr1);
- this.serverChannel.configureBlocking(false);
- // non-blocking mode , will immediately return
- assertNull(this.serverChannel.accept());
- }
-
- /**
- * @tests ServerSocketChannel#accept().socket()
- */
- public void test_read_Blocking_RealData() throws IOException {
- serverChannel.socket().bind(localAddr1);
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
-
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- buf.put((byte) i);
- }
- clientChannel.connect(localAddr1);
- Socket serverSocket = serverChannel.accept().socket();
- InputStream in = serverSocket.getInputStream();
- buf.flip();
- clientChannel.write(buf);
- clientChannel.close();
- assertReadResult(in,CAPACITY_NORMAL);
- }
-
- /**
- * Asserts read content. The read content should contain <code>size</code>
- * bytes, and the value should be a sequence from 0 to size-1
- * ([0,1,...size-1]). Otherwise, the method throws Exception.
- *
- */
- private void assertReadResult(InputStream in, int size) throws IOException{
- byte[] readContent = new byte[size + 1];
- int count = 0;
- int total = 0;
- while ((count = in.read(readContent, total, size + 1 - total)) != -1) {
- total = total + count;
- }
- assertEquals(size, total);
- for (int i = 0; i < size; i++) {
- assertEquals((byte) i, readContent[i]);
- }
- }
-
- /**
- * @tests ServerSocketChannel#accept().socket()
- */
- public void test_read_NonBlocking_RealData() throws Exception {
- serverChannel.configureBlocking(false);
- serverChannel.socket().bind(localAddr1);
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- buf.put((byte) i);
- }
- buf.flip();
- clientChannel.connect(localAddr1);
- Socket serverSocket = serverChannel.accept().socket();
- InputStream in = serverSocket.getInputStream();
- clientChannel.write(buf);
- clientChannel.close();
- assertReadResult(in,CAPACITY_NORMAL);
- }
-
- /**
- * @tests ServerSocketChannel#accept().socket()
- */
- public void test_write_Blocking_RealData() throws IOException {
- assertTrue(serverChannel.isBlocking());
- ServerSocket serverSocket = serverChannel.socket();
- serverSocket.bind(localAddr1);
-
- byte[] writeContent = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < writeContent.length; i++) {
- writeContent[i] = (byte) i;
- }
- clientChannel.connect(localAddr1);
- Socket socket = serverChannel.accept().socket();
- OutputStream out = socket.getOutputStream();
- out.write(writeContent);
- out.flush();
- socket.close();
- assertWriteResult(CAPACITY_NORMAL);
- }
-
-
- /**
- * @tests ServerSocketChannel#accept().socket()
- */
- public void test_write_NonBlocking_RealData() throws Exception {
- serverChannel.configureBlocking(false);
- ServerSocket serverSocket = serverChannel.socket();
- serverSocket.bind(localAddr1);
-
- byte[] writeContent = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- writeContent[i] = (byte) i;
- }
- clientChannel.connect(localAddr1);
- Socket clientSocket = serverChannel.accept().socket();
- OutputStream out = clientSocket.getOutputStream();
- out.write(writeContent);
- clientSocket.close();
- assertWriteResult(CAPACITY_NORMAL);
- }
-
- /**
- * @throws InterruptedException
- * @tests ServerSocketChannel#accept().socket()
- */
- public void test_read_LByteBuffer_Blocking_ReadWriteRealLargeData()
- throws IOException, InterruptedException {
- serverChannel.socket().bind(localAddr1);
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_64KB);
- for (int i = 0; i < CAPACITY_64KB; i++) {
- buf.put((byte) i);
- }
- buf.flip();
- clientChannel.connect(localAddr1);
- WriteChannelThread writeThread = new WriteChannelThread(clientChannel, buf);
- writeThread.start();
- Socket socket = serverChannel.accept().socket();
- InputStream in = socket.getInputStream();
- assertReadResult(in,CAPACITY_64KB);
- writeThread.join();
- // check if the thread threw any exceptions
- if (writeThread.exception != null) {
- throw writeThread.exception;
- }
- }
-
- class WriteChannelThread extends Thread {
- SocketChannel channel;
- ByteBuffer buffer;
- IOException exception;
-
- public WriteChannelThread(SocketChannel channel, ByteBuffer buffer) {
- this.channel = channel;
- this.buffer = buffer;
- }
-
- public void run() {
- try {
- channel.write(buffer);
- channel.close();
- } catch (IOException e) {
- exception = e;
- }
- }
- }
-
- /**
- * @tests ServerSocketChannel#accept().socket()
- */
- public void test_read_LByteBuffer_NonBlocking_ReadWriteRealLargeData()
- throws Exception {
- serverChannel.configureBlocking(false);
- serverChannel.socket().bind(localAddr1);
- ByteBuffer buf = ByteBuffer.allocate(CAPACITY_64KB);
- for (int i = 0; i < CAPACITY_64KB; i++) {
- buf.put((byte) i);
- }
- buf.flip();
- clientChannel.connect(localAddr1);
- WriteChannelThread writeThread = new WriteChannelThread(clientChannel, buf);
- writeThread.start();
- Socket socket = serverChannel.accept().socket();
- InputStream in = socket.getInputStream();
- assertReadResult(in,CAPACITY_64KB);
- writeThread.join();
- // check if the thread threw any exceptions
- if (writeThread.exception != null) {
- throw writeThread.exception;
- }
- }
-
- /**
- * @tests ServerSocketChannel#accept().socket()
- */
- public void test_write_LByteBuffer_NonBlocking_ReadWriteRealLargeData()
- throws Exception {
- serverChannel.configureBlocking(false);
- serverChannel.socket().bind(localAddr1);
- byte[] writeContent = new byte[CAPACITY_64KB];
- for (int i = 0; i < writeContent.length; i++) {
- writeContent[i] = (byte) i;
- }
- clientChannel.connect(localAddr1);
- Socket socket = serverChannel.accept().socket();
- WriteSocketThread writeThread = new WriteSocketThread(socket, writeContent);
- writeThread.start();
- assertWriteResult(CAPACITY_64KB);
- writeThread.join();
- // check if the thread threw any exceptions
- if (writeThread.exception != null) {
- throw writeThread.exception;
- }
- }
-
- class WriteSocketThread extends Thread {
- Socket socket;
- byte[] buffer;
- IOException exception;
-
- public WriteSocketThread(Socket socket, byte[] buffer) {
- this.socket = socket;
- this.buffer = buffer;
- }
-
- public void run() {
- try {
- OutputStream out = socket.getOutputStream();
- out.write(buffer);
- socket.close();
- } catch (IOException e) {
- exception = e;
- }
- }
- }
-
- /**
- * @tests ServerSocketChannel#accept().socket()
- */
- public void test_write_LByteBuffer_Blocking_ReadWriteRealLargeData()
- throws Exception {
- serverChannel.socket().bind(localAddr1);
- byte[] writeContent = new byte[CAPACITY_64KB];
- for (int i = 0; i < writeContent.length; i++) {
- writeContent[i] = (byte) i;
- }
- clientChannel.connect(localAddr1);
- Socket socket = serverChannel.accept().socket();
- WriteSocketThread writeThread = new WriteSocketThread(socket, writeContent);
- writeThread.start();
- assertWriteResult(CAPACITY_64KB);
- writeThread.join();
- // check if the thread threw any exceptions
- if (writeThread.exception != null) {
- throw writeThread.exception;
- }
- }
-
- /**
- * Uses SocketChannel.read(ByteBuffer) to verify write result.
- */
- private void assertWriteResult(int size) throws IOException{
- ByteBuffer buf = ByteBuffer.allocate(size + 1);
- int count = 0;
- int total = 0;
- long beginTime = System.currentTimeMillis();
- while ((count = clientChannel.read(buf)) != -1) {
- total = total + count;
- // 10s timeout to avoid dead loop
- if (System.currentTimeMillis() - beginTime > 10000){
- break;
- }
- }
- assertEquals(total, size);
- buf.flip();
- for (int i = 0; i < count; i++) {
- assertEquals((byte) i, buf.get(i));
- }
- }
-
- /**
- * @tests ServerSocketChannel#socket().getSoTimeout()
- */
- public void test_accept_SOTIMEOUT() throws IOException {
- // regression test for Harmony-707
- final int SO_TIMEOUT = 10;
- ServerSocketChannel sc = ServerSocketChannel.open();
- try {
- ServerSocket ss = sc.socket();
- ss.bind(localAddr1);
- sc.configureBlocking(false);
- ss.setSoTimeout(SO_TIMEOUT);
- SocketChannel client = sc.accept();
- // non blocking mode, returns null since there are no pending connections.
- assertNull(client);
- int soTimeout = ss.getSoTimeout();
- // Harmony fails here.
- assertEquals(SO_TIMEOUT, soTimeout);
- } finally {
- sc.close();
- }
- }
-
- /**
- * @tests ServerSocket#socket().accept()
- */
- public void test_socket_accept_Blocking_NotBound() throws IOException {
- // regression test for Harmony-748
- ServerSocket gotSocket = serverChannel.socket();
- serverChannel.configureBlocking(true);
- try {
- gotSocket.accept();
- fail("Should throw an IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- serverChannel.close();
- try {
- gotSocket.accept();
- fail("Should throw an IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- }
-
- /**
- * @tests ServerSocket#socket().accept()
- */
- public void test_socket_accept_Nonblocking_NotBound() throws IOException {
- // regression test for Harmony-748
- ServerSocket gotSocket = serverChannel.socket();
- serverChannel.configureBlocking(false);
- try {
- gotSocket.accept();
- fail("Should throw an IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- serverChannel.close();
- try {
- gotSocket.accept();
- fail("Should throw an IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- }
-
- /**
- * @tests ServerSocket#socket().accept()
- */
- public void test_socket_accept_Nonblocking_Bound() throws IOException {
- // regression test for Harmony-748
- serverChannel.configureBlocking(false);
- ServerSocket gotSocket = serverChannel.socket();
- gotSocket.bind(localAddr1);
- try {
- gotSocket.accept();
- fail("Should throw an IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- serverChannel.close();
- try {
- gotSocket.accept();
- fail("Should throw a ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests ServerSocket#socket().accept()
- */
- public void test_socket_accept_Blocking_Bound() throws IOException {
- // regression test for Harmony-748
- serverChannel.configureBlocking(true);
- ServerSocket gotSocket = serverChannel.socket();
- gotSocket.bind(localAddr1);
- serverChannel.close();
- try {
- gotSocket.accept();
- fail("Should throw a ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
- /**
- * Regression test for HARMONY-4961
- */
- public void test_socket_getLocalPort() throws IOException {
- serverChannel.socket().bind(localAddr1);
- clientChannel.connect(localAddr1);
- SocketChannel myChannel = serverChannel.accept();
- int port = myChannel.socket().getLocalPort();
- assertEquals(localAddr1.getPort(), port);
- myChannel.close();
- clientChannel.close();
- serverChannel.close();
- }
-
- /**
- * Regression test for HARMONY-6375
- */
- public void test_accept_configureBlocking() throws Exception {
- InetSocketAddress localAddr = new InetSocketAddress("localhost", 0);
- serverChannel.socket().bind(localAddr);
-
- // configure the channel non-blocking
- // when it is accepting in main thread
- new Thread() {
- public void run() {
- try {
- Thread.sleep(TIME_UNIT);
- serverChannel.configureBlocking(false);
- serverChannel.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }.start();
-
- try {
- serverChannel.accept();
- fail("should throw AsynchronousCloseException");
- } catch (AsynchronousCloseException e) {
- // expected
- }
- serverChannel.close();
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SinkChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SinkChannelTest.java
deleted file mode 100644
index 9e96fad..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SinkChannelTest.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.Pipe;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for Pipe.SinkChannel class
- */
-public class SinkChannelTest extends TestCase {
-
- private static final int BUFFER_SIZE = 5;
-
- private static final String ISO8859_1 = "ISO8859-1";
-
- private Pipe pipe;
-
- private Pipe.SinkChannel sink;
-
- private Pipe.SourceChannel source;
-
- private ByteBuffer buffer;
-
- private ByteBuffer positionedBuffer;
-
- protected void setUp() throws Exception {
- super.setUp();
- pipe = Pipe.open();
- sink = pipe.sink();
- source = pipe.source();
- buffer = ByteBuffer.wrap("bytes".getBytes(ISO8859_1));
- positionedBuffer = ByteBuffer.wrap("12345bytes".getBytes(ISO8859_1));
- positionedBuffer.position(BUFFER_SIZE);
- }
-
- /**
- * @tests java.nio.channels.Pipe.SinkChannel#validOps()
- */
- public void test_validOps() {
- assertEquals(SelectionKey.OP_WRITE, sink.validOps());
- }
-
- /**
- * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
- */
- public void test_write_LByteBuffer() throws IOException {
- ByteBuffer[] bufArray = { buffer, positionedBuffer };
- boolean[] sinkBlockingMode = { true, true, false, false };
- boolean[] sourceBlockingMode = { true, false, true, false };
- int oldPosition;
- int currentPosition;
- for (int i = 0; i < sinkBlockingMode.length; ++i) {
- sink.configureBlocking(sinkBlockingMode[i]);
- source.configureBlocking(sourceBlockingMode[i]);
- // if sink and source both are blocking mode, source only needs read
- // once to get what sink write.
- boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i];
- for (ByteBuffer buf : bufArray) {
- buf.mark();
- oldPosition = buf.position();
- sink.write(buf);
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- int totalCount = 0;
- do {
- int count = source.read(readBuf);
- if (count > 0) {
- totalCount += count;
- }
- } while (totalCount != BUFFER_SIZE && !isBlocking);
- currentPosition = buf.position();
- assertEquals(BUFFER_SIZE, currentPosition - oldPosition);
- assertEquals("bytes", new String(readBuf.array(), ISO8859_1));
- buf.reset();
- }
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
- */
- public void test_write_LByteBuffer_mutliThread() throws IOException,
- InterruptedException {
- final int THREAD_NUM = 20;
- final byte[] strbytes = "bytes".getBytes(ISO8859_1);
- Thread[] thread = new Thread[THREAD_NUM];
- for (int i = 0; i < THREAD_NUM; i++) {
- thread[i] = new Thread() {
- public void run() {
- try {
- sink.write(ByteBuffer.wrap(strbytes));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- };
- }
- for (int i = 0; i < THREAD_NUM; i++) {
- thread[i].start();
- }
- for (int i = 0; i < THREAD_NUM; i++) {
- thread[i].join();
- }
- ByteBuffer readBuf = ByteBuffer.allocate(THREAD_NUM * BUFFER_SIZE);
-
- long totalCount = 0;
- do {
- long count = source.read(readBuf);
- if (count < 0) {
- break;
- }
- totalCount += count;
- } while (totalCount != (THREAD_NUM * BUFFER_SIZE));
-
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < THREAD_NUM; i++) {
- buf.append("bytes");
- }
- String readString = buf.toString();
- assertEquals(readString, new String(readBuf.array(), ISO8859_1));
- }
-
- /**
- * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
- */
- public void test_write_LByteBuffer_Exception() throws IOException {
- // write null ByteBuffer
- ByteBuffer nullBuf = null;
- try {
- sink.write(nullBuf);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void test_write_LByteBuffer_SourceClosed() throws IOException {
- source.close();
- try {
- int written = sink.write(buffer);
- fail();
- } catch (IOException expected) {
- }
- }
-
- public void test_write_LByteBuffer_SinkClosed() throws IOException {
- sink.close();
- try {
- sink.write(buffer);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
- */
- public void test_write_$LByteBuffer() throws IOException {
- ByteBuffer[] bufArray = { buffer, positionedBuffer };
- boolean[] sinkBlockingMode = { true, true, false, false };
- boolean[] sourceBlockingMode = { true, false, true, false };
- for (int i = 0; i < sinkBlockingMode.length; ++i) {
- sink.configureBlocking(sinkBlockingMode[i]);
- source.configureBlocking(sourceBlockingMode[i]);
- buffer.position(0);
- positionedBuffer.position(BUFFER_SIZE);
- sink.write(bufArray);
- // if sink and source both are blocking mode, source only needs read
- // once to get what sink write.
- boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i];
- for (int j = 0; j < bufArray.length; ++j) {
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- int totalCount = 0;
- do {
- int count = source.read(readBuf);
- if (count < 0) {
- break;
- }
- totalCount += count;
- } while (totalCount != BUFFER_SIZE && !isBlocking);
- assertEquals("bytes", new String(readBuf.array(), ISO8859_1));
- }
- assertEquals(BUFFER_SIZE, buffer.position());
- assertEquals(10, positionedBuffer.position());
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
- */
- public void test_write_$LByteBuffer_Exception() throws IOException {
- // write null ByteBuffer[]
- ByteBuffer[] nullBufArrayRef = null;
- try {
- sink.write(nullBufArrayRef);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- // write ByteBuffer[] contains null element
- ByteBuffer nullBuf = null;
- ByteBuffer[] nullBufArray = { buffer, nullBuf };
- try {
- sink.write(nullBufArray);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void test_write_$LByteBuffer_SourceClosed() throws IOException {
- ByteBuffer[] bufArray = { buffer };
- source.close();
- try {
- long written = sink.write(bufArray);
- fail();
- } catch (IOException expected) {
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
- */
- public void test_write_$LByteBuffer_SinkClosed() throws IOException {
- ByteBuffer[] bufArray = { buffer };
- sink.close();
- try {
- sink.write(bufArray);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- ByteBuffer[] nullBufArrayRef = null;
- try {
- sink.write(nullBufArrayRef);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- ByteBuffer nullBuf = null;
- ByteBuffer[] nullBufArray = { nullBuf };
- // write ByteBuffer[] contains null element
- try {
- sink.write(nullBufArray);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[], int, int)
- */
- public void test_write_$LByteBufferII() throws IOException {
- ByteBuffer[] bufArray = { buffer, positionedBuffer };
- boolean[] sinkBlockingMode = { true, true, false, false };
- boolean[] sourceBlockingMode = { true, false, true, false };
- for (int i = 0; i < sinkBlockingMode.length; ++i) {
- sink.configureBlocking(sinkBlockingMode[i]);
- source.configureBlocking(sourceBlockingMode[i]);
- positionedBuffer.position(BUFFER_SIZE);
- sink.write(bufArray, 1, 1);
- // if sink and source both are blocking mode, source only needs read
- // once to get what sink write.
- boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i];
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- int totalCount = 0;
- do {
- int count = source.read(readBuf);
- if (count < 0) {
- break;
- }
- totalCount += count;
- } while (totalCount != BUFFER_SIZE && !isBlocking);
- assertEquals("bytes", new String(readBuf.array(), ISO8859_1));
- assertEquals(10, positionedBuffer.position());
- }
- }
-
- public void test_write_$LByteBufferII_Exception() throws IOException {
- try {
- sink.write(null, 0, 1);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- sink.write(new ByteBuffer[2], 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- // write ByteBuffer[] contains null element
- ByteBuffer nullBuf = null;
- ByteBuffer[] nullBufArray = { nullBuf };
- try {
- sink.write(nullBufArray, 0, 1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- sink.write(nullBufArray, 0, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- ByteBuffer[] bufArray = { buffer, nullBuf };
- try {
- sink.write(bufArray, 0, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- sink.write(bufArray, -1, 0);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- sink.write(bufArray, -1, 1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- sink.write(bufArray, 0, 3);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- sink.write(bufArray, 0, 2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- public void test_write_$LByteBufferII_SourceClosed() throws IOException {
- ByteBuffer[] bufArray = { buffer };
- source.close();
-
- try {
- long written = sink.write(bufArray, 0, 1);
- fail();
- } catch (IOException expected) {
- }
- }
-
- public void test_write_$LByteBufferII_SinkClosed() throws IOException {
- ByteBuffer[] bufArray = { buffer };
- sink.close();
- try {
- sink.write(bufArray, 0, 1);
- fail();
- } catch (ClosedChannelException expected) {
- }
-
- try {
- sink.write(null, 0, 1);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- sink.write(new ByteBuffer[2], 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- // write ByteBuffer[] contains null element
- ByteBuffer nullBuf = null;
- ByteBuffer[] nullBufArray = { nullBuf };
- try {
- sink.write(nullBufArray, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- // illegal array index
- try {
- sink.write(nullBufArray, 0, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- ByteBuffer[] bufArray2 = { buffer, nullBuf };
- // illegal array index
- try {
- sink.write(bufArray2, 0, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- sink.write(bufArray2, -1, 0);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- sink.write(bufArray2, -1, 1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- sink.write(bufArray2, 0, 3);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- sink.write(bufArray2, 0, 2);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- public void test_close() throws IOException {
- sink.close();
- assertFalse(sink.isOpen());
- }
-
- public void test_socketChannel_read_close() throws Exception {
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999));
- SocketChannel sc = SocketChannel.open();
- ByteBuffer buf = null;
- try{
- sc.write(buf);
- fail("should throw NPE");
- }catch (NullPointerException e){
- // expected
- }
- sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999));
- SocketChannel sock = ssc.accept();
- ssc.close();
- sc.close();
- try{
- sc.write(buf);
- fail("should throw NPE");
- }catch (NullPointerException e){
- // expected
- }
- sock.close();
- }
-
- public void test_socketChannel_read_write() throws Exception {
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999));
- SocketChannel sc = SocketChannel.open();
- sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999));
- SocketChannel sock = ssc.accept();
- ByteBuffer[] buf = {ByteBuffer.allocate(10),null};
- try {
- sc.write(buf,0,2);
- fail("should throw NPE");
- } catch (NullPointerException expected) {
- }
- ssc.close();
- sc.close();
- ByteBuffer target = ByteBuffer.allocate(10);
- assertEquals(-1, sock.read(target));
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
deleted file mode 100644
index 7325ba1..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
+++ /dev/null
@@ -1,3628 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.BindException;
-import java.net.ConnectException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.channels.AlreadyConnectedException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.ConnectionPendingException;
-import java.nio.channels.IllegalBlockingModeException;
-import java.nio.channels.NoConnectionPendingException;
-import java.nio.channels.NotYetConnectedException;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.UnresolvedAddressException;
-import java.nio.channels.UnsupportedAddressTypeException;
-import java.nio.channels.spi.SelectorProvider;
-
-import junit.framework.TestCase;
-import tests.support.Support_PortManager;
-
-/**
- * Tests for SocketChannel and its default implementation.
- */
-public class SocketChannelTest extends TestCase {
-
- private static final int CAPACITY_NORMAL = 200;
-
- private InetSocketAddress localAddr1;
-
- private InetSocketAddress localAddr2;
-
- private SocketChannel channel1;
-
- private SocketChannel channel2;
-
- private ServerSocket server1;
-
- private ServerSocket server2;
-
- private final static int TIMEOUT = 60000;
-
- private final static int EOF = -1;
-
- protected void setUp() throws Exception {
- super.setUp();
- this.localAddr1 = new InetSocketAddress("127.0.0.1",
- Support_PortManager.getNextPort());
- this.localAddr2 = new InetSocketAddress("127.0.0.1",
- Support_PortManager.getNextPort());
- this.channel1 = SocketChannel.open();
- this.channel2 = SocketChannel.open();
- this.server1 = new ServerSocket(localAddr1.getPort());
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- if (null != this.channel1) {
- try {
- this.channel1.close();
- } catch (Exception e) {
- //ignore
- }
- }
- if (null != this.channel2) {
- try {
- this.channel2.close();
- } catch (Exception e) {
- //ignore
- }
- }
- if (null != this.server1) {
- try {
- this.server1.close();
- } catch (Exception e) {
- //ignore
- }
- }
- if (null != this.server2) {
- try {
- this.server2.close();
- } catch (Exception e) {
- //ignore
- }
- }
- }
-
- // -------------------------------------------------------------------
- // Test for methods in abstract class.
- // -------------------------------------------------------------------
- /*
- * Test method for 'java.nio.channels.SocketChannel.validOps()'
- */
- public void testValidOps() {
- MockSocketChannel testMSChannel = new MockSocketChannel(null);
- assertEquals(13, this.channel1.validOps());
- assertEquals(13, testMSChannel.validOps());
- }
-
- /*
- * Test method for 'java.nio.channels.SocketChannel.open()'
- */
- public void testOpen() throws IOException {
- java.nio.ByteBuffer[] buf = new java.nio.ByteBuffer[1];
- buf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- MockSocketChannel testMSChannel = new MockSocketChannel(null);
- MockSocketChannel testMSChannelnotnull = new MockSocketChannel(
- SelectorProvider.provider());
- assertNull(testMSChannel.provider());
- assertNotNull(testMSChannelnotnull.provider());
- assertNotNull(this.channel1);
- assertEquals(this.channel1.provider(), testMSChannelnotnull.provider());
- try {
- this.channel1.write(buf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- }
-
- /*
- * Test method for 'java.nio.channels.SocketChannel.open(SocketAddress)'
- */
- public void testOpenSocketAddress_Null() throws IOException {
- SocketChannel channel1IP = null;
- try {
- channel1IP = SocketChannel.open(null);
- fail("Should throw an IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // correct
- }
- assertNull(channel1IP);
- }
-
- /*
- * Test method for 'java.nio.channels.SocketChannel.read(ByteBuffer[])'
- */
- public void testReadByteBufferArray() throws IOException {
- java.nio.ByteBuffer[] byteBuf = null;
- MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
- MockSocketChannel testMSChannel = new MockSocketChannel(
- SelectorProvider.provider());
- ServerSocket testServer = new ServerSocket(Support_PortManager
- .getNextPort());
- try {
- try {
- this.channel1.read(byteBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- byteBuf = new java.nio.ByteBuffer[CAPACITY_NORMAL];
- try {
- this.channel1.read(byteBuf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- long readNum = CAPACITY_NORMAL;
- readNum = testMSChannel.read(byteBuf);
- assertEquals(0, readNum);
- readNum = CAPACITY_NORMAL;
- readNum = testMSChannelnull.read(byteBuf);
- assertEquals(0, readNum);
- } finally {
- testServer.close();
- }
- }
-
- /*
- * Test method for 'java.nio.channels.SocketChannel.read(ByteBuffer[])'
- */
- public void testReadByteBufferArray_BufNull() throws IOException {
- java.nio.ByteBuffer[] byteBuf = null;
- MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
- MockSocketChannel testMSChannel = new MockSocketChannel(
- SelectorProvider.provider());
- try {
- this.channel1.read(byteBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMSChannel.read(byteBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMSChannelnull.read(byteBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- /*
- * Test method for 'java.nio.channels.SocketChannel.write(ByteBuffer[])'
- */
- public void testWriteByteBufferArray() throws IOException {
- java.nio.ByteBuffer[] byteBuf = null;
- MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
- MockSocketChannel testMSChannel = new MockSocketChannel(
- SelectorProvider.provider());
- try {
- this.channel1.write(byteBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- byteBuf = new java.nio.ByteBuffer[CAPACITY_NORMAL];
- try {
- this.channel1.write(byteBuf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- testMSChannel.write(byteBuf);
- testMSChannelnull.write(byteBuf);
- }
-
- /*
- * Test method for 'java.nio.channels.SocketChannel.write(ByteBuffer[])'
- */
- public void testWriteByteBufferArray_BufNull() throws IOException {
- java.nio.ByteBuffer[] byteBuf = null;
- MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
- MockSocketChannel testMSChannel = new MockSocketChannel(
- SelectorProvider.provider());
- try {
- this.channel1.write(byteBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMSChannel.write(byteBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- testMSChannelnull.write(byteBuf);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- public void testSocket_BasicStatusBeforeConnect() throws IOException {
- assertFalse(this.channel1.isConnected());// not connected
- Socket s1 = this.channel1.socket();
- assertSocketBeforeConnect(s1);
- Socket s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
-
- public void testSocket_Block_BasicStatusAfterConnect() throws IOException {
- assertFalse(this.channel1.isConnected());// not connected
- assertTrue(this.channel1.connect(localAddr1));
-
- assertTrue(this.channel1.isConnected());
- Socket s1 = this.channel1.socket();
-
- assertSocketAfterConnect(s1, localAddr1);
- Socket s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
-
- public void testSocket_NonBlock_BasicStatusAfterConnect() throws Exception {
- assertFalse(this.channel1.isConnected());// not connected
- this.channel1.configureBlocking(false);
- boolean connected = channel1.connect(localAddr1);
- Socket s1 = null;
- Socket s2 = null;
- if (!connected) {
- assertFalse(this.channel1.isConnected());
- assertTrue(this.channel1.isConnectionPending());
- s1 = this.channel1.socket();
- // status of not connected
- assertSocketBeforeConnect(s1);
- s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
-
- if (tryFinish()) {
- assertTrue(this.channel1.isConnected());
- s1 = this.channel1.socket();
- assertSocketAfterConnect(s1, localAddr1);
- s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
- }
-
- public void testSocket_Block_ActionsBeforeConnect() throws IOException {
- assertFalse(this.channel1.isConnected());// not connected
- Socket s = this.channel1.socket();
- assertSocketAction_Block_BeforeConnect(s);
- }
-
- public void testSocket_Block_ActionsAfterConnect() throws IOException {
- assertFalse(this.channel1.isConnected());// not connected
- assertTrue(this.channel1.connect(localAddr1));
- assertTrue(this.channel1.isConnected());
- Socket s = this.channel1.socket();
- assertSocketAction_Block_AfterConnect(s);
-
- }
-
- public void testSocket_NonBlock_ActionsAfterConnectBeforeFinish()
- throws IOException {
- assertFalse(this.channel1.isConnected());// not connected
- this.channel1.configureBlocking(false);
- boolean connected = channel1.connect(localAddr1);
- if (!connected) {
- assertFalse(this.channel1.isConnected());
- assertTrue(this.channel1.isConnectionPending());
- Socket s1 = this.channel1.socket();
- // Action of not connected
- assertSocketAction_NonBlock_BeforeConnect(s1);
- Socket s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
- }
-
- public void testSocket_NonBlock_ActionsAfterConnectAfterFinish()
- throws Exception {
- assertFalse(this.channel1.isConnected());// not connected
- this.channel1.configureBlocking(false);
- channel1.connect(localAddr1);
- if (tryFinish()) {
- Socket s1 = this.channel1.socket();
- assertSocketAction_NonBlock_AfterConnect(s1);
- Socket s2 = this.channel1.socket();
- // same
- assertSame(s1, s2);
- }
- }
-
- public void testSocket_getInetAddress() throws Exception {
- Socket socket = channel1.socket();
- assertNull(socket.getInetAddress());
-
- channel1.connect(localAddr1);
-
- assertNotNull(socket.getInetAddress());
- assertEquals(localAddr1.getAddress(), socket.getInetAddress());
- }
-
- public void testSocket_getRemoteSocketAddress() throws Exception {
- Socket socket = channel1.socket();
- assertNull(socket.getRemoteSocketAddress());
-
- channel1.connect(localAddr1);
-
- assertNotNull(socket.getRemoteSocketAddress());
- assertEquals(localAddr1, socket.getRemoteSocketAddress());
- }
-
- public void testSocket_getPort() throws Exception {
- Socket socket = channel1.socket();
- assertEquals(0, socket.getPort());
-
- channel1.connect(localAddr1);
-
- assertEquals(localAddr1.getPort(), socket.getPort());
- }
-
- public void testSocket_getLocalAddress() throws Exception {
- Socket socket = channel1.socket();
- assertNotNull(socket.getLocalAddress());
-
- channel1.connect(localAddr1);
-
- assertNotNull(socket.getLocalAddress());
- }
-
- public void testSocket_getLocalSocketAddress() throws Exception {
- Socket socket = channel1.socket();
- assertNull(socket.getLocalSocketAddress());
-
- channel1.connect(localAddr1);
-
- assertNotNull(socket.getLocalSocketAddress());
- }
-
- public void testSocket_getLocalPort() throws Exception {
- Socket socket = channel1.socket();
- assertEquals(-1, socket.getLocalPort());
-
- channel1.connect(localAddr1);
-
- assertTrue(-1 != socket.getLocalPort());
- assertTrue(0 != socket.getLocalPort());
- }
-
- public void testSocket_bind() throws Exception {
- Socket socket = channel1.socket();
- socket.bind(new InetSocketAddress("127.0.0.1", 0));
- assertEquals("127.0.0.1", socket.getLocalAddress().getHostAddress());
- assertTrue(socket.getLocalPort() != -1);
- }
-
- private void assertSocketBeforeConnect(Socket s) throws IOException {
- assertFalse(s.isBound());
- assertFalse(s.isClosed());
- assertFalse(s.isConnected());
- assertFalse(s.getKeepAlive());
- try {
- s.getInputStream();
- fail("Should throw SocketException.");
- } catch (SocketException e) {
- // OK.
- }
- assertFalse(s.getOOBInline());
- try {
- s.getOutputStream();
- fail("Should throw SocketException.");
- } catch (SocketException e) {
- // OK.
- }
- assertEquals(-1, s.getSoLinger());
- assertFalse(s.getTcpNoDelay());
-
- assertFalse(s.isInputShutdown());
- assertFalse(s.isOutputShutdown());
-
- assertNull(s.getInetAddress());
- assertEquals(s.getLocalAddress().getHostAddress(), "0.0.0.0");
- // RI fails here. RI returns 0 while spec says unbound socket should
- // return -1.
- assertEquals(-1, s.getLocalPort());
- assertFalse(s.getReuseAddress());
- assertNull(s.getLocalSocketAddress());
-
- // not connected
- assertEquals(0, s.getPort());
- assertTrue(s.getReceiveBufferSize() >= 8192);
- assertNull(s.getRemoteSocketAddress());
- assertTrue(s.getSendBufferSize() >= 8192);
- assertEquals(0, s.getSoTimeout());
- assertEquals(0, s.getTrafficClass());
-
- }
-
- private void assertSocketAfterConnect(Socket s, InetSocketAddress address)
- throws IOException {
- assertTrue(s.isBound());
- assertFalse(s.isClosed());
- assertTrue(s.isConnected());
- assertFalse(s.getKeepAlive());
-
- assertNotNull(s.getInputStream());
- assertNotNull(s.getOutputStream());
-
- assertFalse(s.getOOBInline());
- assertEquals(-1, s.getSoLinger());
- assertFalse(s.getTcpNoDelay());
-
- assertFalse(s.isInputShutdown());
- assertFalse(s.isOutputShutdown());
-
- assertSame(s.getInetAddress(), address.getAddress());
-
- assertEquals(s.getLocalAddress(), this.localAddr1.getAddress());
- assertEquals(s.getPort(), address.getPort());
- assertNotNull(s.getLocalSocketAddress());
- assertTrue(s.getReceiveBufferSize() >= 8192);
- assertEquals(s.getRemoteSocketAddress(), (SocketAddress) address);
- // assertFalse(s.getReuseAddress());
- assertTrue(s.getSendBufferSize() >= 8192);
- assertEquals(0, s.getSoTimeout());
- assertEquals(0, s.getTrafficClass());
- }
-
- private void assertSocketAction_Block_BeforeConnect(Socket s)
- throws IOException {
- assertFalse(this.channel1.isConnected());
- this.server2 = new ServerSocket(localAddr2.getPort());
- s.connect(localAddr2);
- assertTrue(this.channel1.isConnected());
- assertTrue(s.isConnected());
-
- assertSocketAfterConnect(s, localAddr2);
-
- try {
- s.bind(localAddr2);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
-
- s.close();
- assertTrue(s.isClosed());
- assertFalse(this.channel1.isOpen());
- }
-
- private void assertSocketAction_NonBlock_BeforeConnect(Socket s)
- throws IOException {
- assertFalse(this.channel1.isConnected());
- this.server2 = new ServerSocket(localAddr2.getPort());
- try {
- s.connect(localAddr2);
- fail("Should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e1) {
- // OK.
- }
-
- if (this.channel1.isConnectionPending()) {
- try {
- s.bind(localAddr2);
- fail("Should throw ConnectionPendingException");
- } catch (ConnectionPendingException e1) {
- // OK.
- }
- } else {
- try {
- s.bind(localAddr2);
- fail("Should throw BindException");
- } catch (BindException e1) {
- // OK.
- }
- }
-
- assertFalse(this.channel1.isConnected());
- assertFalse(s.isConnected());
-
- s.close();
- assertTrue(s.isClosed());
- assertFalse(this.channel1.isOpen());
- }
-
- private void assertSocketAction_Block_AfterConnect(Socket s)
- throws IOException {
- assertEquals(s.getPort(), localAddr1.getPort());
- assertTrue(this.channel1.isConnected());
- assertTrue(s.isConnected());
- try {
- s.connect(localAddr2);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
-
- try {
- s.bind(localAddr2);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
-
- s.close();
- assertTrue(s.isClosed());
- assertFalse(this.channel1.isOpen());
- }
-
- private void assertSocketAction_NonBlock_AfterConnect(Socket s)
- throws IOException {
- assertEquals(s.getPort(), localAddr1.getPort());
- assertTrue(this.channel1.isConnected());
- assertTrue(s.isConnected());
-
- if (this.channel1.isConnectionPending()) {
- try {
- s.connect(localAddr2);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- } else {
- try {
- s.connect(localAddr2);
- fail("Should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // OK.
- }
- }
-
- try {
- s.bind(localAddr2);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
-
- s.close();
- assertTrue(s.isClosed());
- assertFalse(this.channel1.isOpen());
- }
-
- // -------------------------------------------------------------------
- // Tests for connect(), finishConnect(),isConnected(),isConnectionPending()
- // These methods are very close, so we test them together, call them "CFII".
- // -------------------------------------------------------------------
- /**
- * connect-->finish-->close
- */
- public void testCFII_Norml_NoServer_Block() throws Exception {
- // ensure
- ensureServerClosed();
- assertTrue(this.channel1.isBlocking());
- statusNotConnected_NotPending();
- // connect
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectException here.");
- } catch (ConnectException e) {
- // OK.
- }
- statusChannelClosed();
- try {
- this.channel1.finishConnect();
- fail("Should throw a ClosedChannelException here.");
- } catch (ClosedChannelException e) {
- // OK.
- }
- }
-
- /**
- * connect-->finish-->close
- */
- public void testCFII_Norml_NoServer_NonBlock() throws Exception {
- connectNoServerNonBlock();
-
- this.channel1.close();
- statusChannelClosed();
- }
-
- /**
- * connect-->finish-->close
- */
- public void testCFII_Norml_Server_Block() throws Exception {
- connectServerBlock();
-
- this.channel1.close();
- statusChannelClosed();
-
- }
-
- /**
- * connect-->finish-->close
- */
- public void testCFII_Norml_Server_NonBlock() throws Exception {
- connectServerNonBlock();
-
- this.channel1.close();
- statusChannelClosed();
- }
-
- /**
- * connect-->server closed-->finish-->close
- */
- public void testCFII_ServerClosed_Block() throws Exception {
- // ensure
- ensureServerOpen();
- assertTrue(this.channel1.isBlocking());
- statusNotConnected_NotPending();
- // connect
- assertTrue(this.channel1.connect(localAddr1));
- statusConnected_NotPending();
-
- ensureServerClosed();
-
- tryFinish();
-
- this.channel1.close();
- statusChannelClosed();
-
- }
-
- /**
- * connect-->server closed-->finish-->close
- */
- public void testCFII_ServerClosed_NonBlock() throws Exception {
- // ensure
- ensureServerOpen();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // connect
- boolean connected = channel1.connect(localAddr1);
- if (!connected) {
- statusNotConnected_Pending();
- }
- ensureServerClosed();
-
- tryFinish();
-
- this.channel1.close();
- statusChannelClosed();
- }
-
- /**
- * connect-->finish-->server closed-->close
- */
- public void testCFII_ServerClosedAfterFinish_Block() throws Exception {
- connectServerBlock();
-
- ensureServerClosed();
- assertTrue(this.channel1.isOpen());
- this.channel1.close();
- statusChannelClosed();
-
- }
-
- /**
- * connect-->finish-->server closed-->close
- */
- public void testCFII_ServerClosedAfterFinish_NonBlock() throws Exception {
- connectServerNonBlock();
-
- ensureServerClosed();
- assertTrue(this.channel1.isOpen());
- this.channel1.close();
- statusChannelClosed();
- }
-
- /**
- * no server-->connect-->server open-->finish-->close
- */
- public void testCFII_ServerStartLater_Block() throws Exception {
- // ensure
- ensureServerClosed();
- assertTrue(this.channel1.isBlocking());
- statusNotConnected_NotPending();
- // connect
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectException here.");
- } catch (ConnectException e) {
- // OK.
- }
- statusChannelClosed();
- ensureServerOpen();
- try {
- this.channel1.finishConnect();
- fail("Should throw a ClosedChannelException here.");
- } catch (ClosedChannelException e) {
- // OK.
- }
- }
-
- /**
- * no server-->connect-->server open-->finish-->close
- */
- public void testCFII_ServerStartLater_NonBlock() throws Exception {
- // ensure
- ensureServerClosed();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // connect
- assertFalse(this.channel1.connect(localAddr1));
- statusNotConnected_Pending();
-
- ensureServerOpen();
-
- try {
- assertFalse(this.channel1.finishConnect());
- statusNotConnected_Pending();
- this.channel1.close();
- } catch (ConnectException e) {
- // FIXME: assertEquals(e.getMessage(), "Connection refused");
- }
- }
-
- /**
- * connect-->finish-->finish-->close
- */
- public void testCFII_FinishTwice_NoServer_NonBlock() throws Exception {
- // ensure
- ensureServerClosed();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // connect
- assertFalse(this.channel1.connect(localAddr1));
- statusNotConnected_Pending();
- try {
- assertFalse(this.channel1.finishConnect());
- statusNotConnected_Pending();
- assertFalse(this.channel1.finishConnect());
- statusNotConnected_Pending();
- this.channel1.close();
- } catch (ConnectException e) {
- // FIXME: assertEquals(e.getMessage(), "Connection refused");
- }
- statusChannelClosed();
- }
-
- /**
- * connect-->finish-->finish-->close
- */
- public void testCFII_FinishTwice_Server_Block() throws Exception {
- connectServerBlock();
- tryFinish();
- this.channel1.close();
- statusChannelClosed();
-
- }
-
- /**
- * connect-->finish-->finish-->close
- */
- public void testCFII_FinishTwice_Server_NonBlock() throws Exception {
- connectServerNonBlock();
- tryFinish();
- this.channel1.close();
- statusChannelClosed();
- }
-
- /**
- * connect-->finish-->connect-->close
- */
- public void testCFII_ConnectAfterFinish_NoServer_Block() throws Exception {
- // ensure
- ensureServerClosed();
- assertTrue(this.channel1.isBlocking());
- statusNotConnected_NotPending();
- // connect
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectException here.");
- } catch (ConnectException e) {
- // OK.
- }
- statusChannelClosed();
- try {
- this.channel1.finishConnect();
- fail("Should throw a ClosedChannelException here.");
- } catch (ClosedChannelException e) {
- // OK.
- }
- statusChannelClosed();
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ClosedChannelException here.");
- } catch (ClosedChannelException e) {
- // OK.
- }
- statusChannelClosed();
- }
-
- /**
- * connect-->finish-->connect-->close
- */
- public void testCFII_ConnectAfterFinish_NoServer_NonBlock()
- throws Exception {
- // ensure
- ensureServerClosed();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // connect
- assertFalse(this.channel1.connect(localAddr1));
- statusNotConnected_Pending();
- try {
- assertFalse(this.channel1.finishConnect());
- statusNotConnected_Pending();
- } catch (ConnectException e) {
- // FIXME: assertEquals(e.getMessage(), "Connection refused");
- }
-
- if (this.channel1.isOpen()) {
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
-
- // connect another addr
- try {
- this.channel1.connect(localAddr2);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
-
- // connect if server closed
- ensureServerClosed();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
-
- this.channel1.close();
- }
- statusChannelClosed();
- }
-
- /**
- * connect-->finish-->connect-->close
- */
- public void testCFII_ConnectAfterFinish_Server_Block() throws Exception {
- connectServerBlock();
-
- if (!this.channel1.isConnected()) {
- System.err
- .println("Connection fail, testCFII_ConnectAfterFinish_Server_Block is not finished.");
- return;
- }
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw an AlreadyConnectedException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- statusConnected_NotPending();
-
- // connect another addr
- try {
- this.channel1.connect(localAddr2);
- fail("Should throw an AlreadyConnectedException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- statusConnected_NotPending();
-
- // connect if server closed
- ensureServerClosed();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw an AlreadyConnectedException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- statusConnected_NotPending();
-
- this.channel1.close();
- statusChannelClosed();
-
- }
-
- /**
- * connect-->finish-->connect-->close
- */
- public void testCFII_ConnectAfterFinish_Server_NonBlock() throws Exception {
- connectServerNonBlock();
-
- if (!this.channel1.isConnected()) {
- System.err
- .println("Connection fail, testCFII_ConnectAfterFinish_Server_Block is not finished.");
- return;
- }
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw an AlreadyConnectedException or a ConnectionPendingException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
-
- statusConnected_NotPending();
-
- // connect another addr
- try {
- this.channel1.connect(localAddr2);
- fail("Should throw an AlreadyConnectedException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- statusConnected_NotPending();
-
- // connect if server closed
- ensureServerClosed();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw an AlreadyConnectedException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- statusConnected_NotPending();
-
- this.channel1.close();
- statusChannelClosed();
- }
-
- /**
- * connect-->connect-->finish-->close
- */
- public void testCFII_ConnectTwice_NoServer_NonBlock() throws Exception {
- // ensure
- ensureServerClosed();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // connect
- assertFalse(this.channel1.connect(localAddr1));
- statusNotConnected_Pending();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
-
- // connect another addr
- try {
- this.channel1.connect(localAddr2);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
-
- // connect if server closed
- ensureServerClosed();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
-
- try {
- assertFalse(this.channel1.finishConnect());
- statusNotConnected_Pending();
- this.channel1.close();
- } catch (ConnectException e) {
- // FIXME: assertEquals(e.getMessage(), "Connection refused");
- }
-
- statusChannelClosed();
- }
-
- /**
- * connect-->connect-->finish-->close
- */
- public void testCFII_ConnectTwice_Server_Block() throws Exception {
- // ensure
- ensureServerOpen();
- assertTrue(this.channel1.isBlocking());
- statusNotConnected_NotPending();
- // connect
- assertTrue(this.channel1.connect(localAddr1));
- statusConnected_NotPending();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw an AlreadyConnectedException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- statusConnected_NotPending();
-
- // connect another addr
- try {
- this.channel1.connect(localAddr2);
- fail("Should throw an AlreadyConnectedException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- statusConnected_NotPending();
-
- // connect if server closed
- ensureServerClosed();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw an AlreadyConnectedException here.");
- } catch (AlreadyConnectedException e) {
- // OK.
- }
- statusConnected_NotPending();
-
- tryFinish();
-
- this.channel1.close();
- statusChannelClosed();
-
- }
-
- /**
- * connect-->connect-->finish-->close
- */
- public void testCFII_ConnectTwice_Server_NonBlock() throws Exception {
- // ensure
- ensureServerOpen();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // connect
- boolean connected = channel1.connect(localAddr1);
- if (!connected) {
- statusNotConnected_Pending();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
-
- // connect another addr
- try {
- this.channel1.connect(localAddr2);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
-
- // connect if server closed
- ensureServerClosed();
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectionPendingException here.");
- } catch (ConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_Pending();
- }
- tryFinish();
-
- this.channel1.close();
- statusChannelClosed();
- }
-
- /**
- * finish-->connect-->finish-->close
- */
- public void testCFII_FinishFirst_NoServer_Block() throws Exception {
- // ensure
- ensureServerClosed();
- assertTrue(this.channel1.isBlocking());
- statusNotConnected_NotPending();
- // finish
- try {
- this.channel1.finishConnect();
- fail("Should throw NoConnectionPendingException");
- } catch (NoConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_NotPending();
- // connect
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw a ConnectException here.");
- } catch (ConnectException e) {
- // OK.
- }
- statusChannelClosed();
- try {
- this.channel1.finishConnect();
- fail("Should throw a ClosedChannelException here.");
- } catch (ClosedChannelException e) {
- // OK.
- }
- statusChannelClosed();
- }
-
- /**
- * finish-->connect-->finish-->close
- */
- public void testCFII_FinishFirst_NoServer_NonBlock() throws Exception {
- // ensure
- ensureServerClosed();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // finish
- try {
- this.channel1.finishConnect();
- fail("Should throw NoConnectionPendingException");
- } catch (NoConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_NotPending();
- // connect
- assertFalse(this.channel1.connect(localAddr1));
- statusNotConnected_Pending();
-
- try {
- assertFalse(this.channel1.finishConnect());
- statusNotConnected_Pending();
- this.channel1.close();
- } catch (ConnectException e) {
- // FIXME: assertEquals(e.getMessage(), "Connection refused");
- }
-
- statusChannelClosed();
- }
-
- /**
- * finish-->connect-->finish-->close
- */
- public void testCFII_FinishFirst_Server_Block() throws Exception {
- // ensure
- ensureServerOpen();
- assertTrue(this.channel1.isBlocking());
- statusNotConnected_NotPending();
- // finish
- try {
- this.channel1.finishConnect();
- fail("Should throw NoConnectionPendingException");
- } catch (NoConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_NotPending();
- // connect
- assertTrue(this.channel1.connect(localAddr1));
- statusConnected_NotPending();
-
- tryFinish();
-
- this.channel1.close();
- statusChannelClosed();
-
- }
-
- /**
- * finish-->connect-->finish-->close
- */
- public void testCFII_FinishFirst_Server_NonBlock() throws Exception {
- // ensure
- ensureServerOpen();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // finish
- try {
- this.channel1.finishConnect();
- fail("Should throw NoConnectionPendingException");
- } catch (NoConnectionPendingException e) {
- // OK.
- }
- statusNotConnected_NotPending();
- // connect
- boolean connected = channel1.connect(localAddr1);
- if (!connected) {
- statusNotConnected_Pending();
- }
- tryFinish();
-
- this.channel1.close();
- statusChannelClosed();
- }
-
- public void testCFII_Null() throws Exception {
- statusNotConnected_NotPending();
- try {
- this.channel1.connect(null);
- fail("Should throw an IllegalArgumentException here.");
- } catch (IllegalArgumentException e) {
- // OK.
- }
- }
-
- public void testCFII_UnsupportedType() throws Exception {
- class SubSocketAddress extends SocketAddress {
- private static final long serialVersionUID = 1L;
-
- //empty
- public SubSocketAddress() {
- super();
- }
- }
- statusNotConnected_NotPending();
- SocketAddress newTypeAddress = new SubSocketAddress();
- try {
- this.channel1.connect(newTypeAddress);
- fail("Should throw an UnsupportedAddressTypeException here.");
- } catch (UnsupportedAddressTypeException e) {
- // OK.
- }
- }
-
- public void testCFII_Unresolved() throws IOException {
- statusNotConnected_NotPending();
- InetSocketAddress unresolved = new InetSocketAddress(
- "unresolved address", 1080);
- try {
- this.channel1.connect(unresolved);
- fail("Should throw an UnresolvedAddressException here.");
- } catch (UnresolvedAddressException e) {
- // OK.
- }
- }
-
- public void testCFII_EmptyHost() throws Exception {
- statusNotConnected_NotPending();
- ServerSocket server = new ServerSocket(0);
- int port = server.getLocalPort();
- server.close();
- try {
- this.channel1.connect(new InetSocketAddress("", port));
- fail("Should throw ConnectException");
- } catch (ConnectException e) {
- // correct
- }
- }
-
- public void testCFII_CloseFirst() throws Exception {
- this.channel1.close();
- statusChannelClosed();
- ensureServerOpen();
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // OK.
- }
- statusChannelClosed();
- try {
- this.channel1.finishConnect();
- fail("Should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // OK.
- }
- statusChannelClosed();
- try {
- this.channel1.configureBlocking(false);
- fail("Should throw ClosedChannelException.");
- } catch (ClosedChannelException e) {
- // OK.
- }
- statusChannelClosed();
- }
-
- public void testCFII_StatusAfterFinish() throws Exception {
- // 1. close server, finish must return false, check the status
- ensureServerClosed();
-
- // 1.1 block mode
- assertTrue(this.channel1.isBlocking());
- try {
- channel1.connect(localAddr1);
- fail("Should throw ConnectException");
- } catch (ConnectException e) {
- // OK.
- }
- assertFalse(this.channel1.isOpen());
-
- assertFalse(this.channel1.isOpen());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnectionPending());
-
- // 1.2 non block mode
- this.channel1 = SocketChannel.open();
- this.channel1.configureBlocking(false);
- assertFalse(this.channel1.connect(localAddr1));
- try {
- assertFalse(this.channel1.finishConnect());
- statusNotConnected_Pending();
- this.channel1.close();
- } catch (ConnectException e) {
- System.out.println(e.getMessage());
- }
-
- // 2. start server, finish usually return true, check the status
- ensureServerOpen();
-
- // 2.1 block mode
- this.channel1 = SocketChannel.open();
- assertTrue(this.channel1.isBlocking());
- assertTrue(this.channel1.connect(localAddr1));
- assertTrue(this.channel1.finishConnect());
- statusConnected_NotPending();
- this.channel1.close();
-
- // 2.2 non block mode
- this.channel1 = SocketChannel.open();
- this.channel1.configureBlocking(false);
- assertFalse(this.channel1.connect(localAddr1));
- tryFinish();
- this.channel1.close();
- }
-
- private void ensureServerClosed() throws IOException {
- if (null != this.server1) {
- this.server1.close();
- assertTrue(this.server1.isClosed());
- }
- if (null != this.server2) {
- this.server2.close();
- assertTrue(this.server2.isClosed());
- }
- }
-
- private void ensureServerOpen() throws IOException {
- ensureServerClosed();
- this.server1 = new ServerSocket(localAddr1.getPort());
- this.server2 = new ServerSocket(localAddr2.getPort());
- assertTrue(this.server1.isBound());
- assertTrue(this.server2.isBound());
- }
-
- private void connectNoServerNonBlock() throws Exception {
- // ensure
- ensureServerClosed();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // connect
- assertFalse(this.channel1.connect(localAddr1));
- statusNotConnected_Pending();
- try {
- assertFalse(this.channel1.finishConnect());
- statusNotConnected_Pending();
- } catch (ConnectException e) {
- // FIXME: assertEquals(e.getMessage(), "Connection refused");
- }
- }
-
- private void connectServerNonBlock() throws Exception {
- // ensure
- ensureServerOpen();
- this.channel1.configureBlocking(false);
- statusNotConnected_NotPending();
- // connect
- boolean connected = channel1.connect(localAddr1);
- if (!connected) {
- statusNotConnected_Pending();
- }
- tryFinish();
- }
-
- private void connectServerBlock() throws Exception {
- // ensure
- ensureServerOpen();
- assertTrue(this.channel1.isBlocking());
- statusNotConnected_NotPending();
- // connect
- assertTrue(this.channel1.connect(localAddr1));
- statusConnected_NotPending();
- tryFinish();
- }
-
- private void statusChannelClosed() {
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertFalse(this.channel1.isOpen());
- }
-
- private void statusNotConnected_NotPending() {
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- }
-
- private void statusNotConnected_Pending() {
- assertFalse(this.channel1.isConnected());
- assertTrue(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- }
-
- private void statusConnected_NotPending() {
- assertTrue(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- }
-
- private boolean tryFinish() throws IOException {
- /*
- * the result of finish will be asserted in multi-thread tests.
- */
- boolean connected = false;
- assertTrue(this.channel1.isOpen());
- try {
- connected = this.channel1.finishConnect();
- } catch (SocketException e) {
- // Finish connection failed, probably due to reset by peer error.
- }
- if (connected) {
- statusConnected_NotPending();
- }
- return connected;
- }
-
- // -------------------------------------------------------------------
- // Original tests. Test method for CFII with real data.
- // -------------------------------------------------------------------
-
- /**
- *
- * 'SocketChannelImpl.connect(SocketAddress)'
- */
- public void testCFII_Data_ConnectWithServer() throws Exception {
- ensureServerOpen();
- java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
- .allocate(CAPACITY_NORMAL);
- java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
- writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
-
- this.channel1.connect(localAddr1);
-
- assertTrue(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1));
-
- this.channel1.configureBlocking(false);
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // correct
- }
-
- assertFalse(this.channel1.isRegistered());
- tryFinish();
- }
-
- /*
- * Test method for 'SocketChannelImpl.connect(SocketAddress)'
- */
- public void testCFII_Data_ConnectWithServer_nonBlocking() throws Exception {
- ensureServerOpen();
- java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
- .allocate(CAPACITY_NORMAL);
- java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
- writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- this.channel1.configureBlocking(false);
- this.channel1.connect(localAddr1);
-
- assertFalse(this.channel1.isBlocking());
- boolean connected = channel1.isConnected();
- if (!connected) {
- assertTrue(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- }
- if (tryFinish()) {
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1));
-
- this.channel1.configureBlocking(false);
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // correct
- }
- }
-
- assertFalse(this.channel1.isRegistered());
- tryFinish();
- }
-
- /*
- * Test method for 'SocketChannelImpl.finishConnect()'
- */
- public void testCFII_Data_FinishConnect_nonBlocking() throws IOException {
- ensureServerOpen();
-
- java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
- .allocate(CAPACITY_NORMAL);
- java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
- writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
-
- this.channel1.configureBlocking(false);
- try {
- this.channel1.finishConnect();
- fail("Should throw NoConnectionPendingException");
- } catch (NoConnectionPendingException e) {
- // correct
- }
- boolean connected = channel1.connect(localAddr1);
- if (!connected) {
- assertFalse(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertTrue(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- }
- this.server1.accept();
- if (tryFinish()) {
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1));
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // correct
- }
- }
- assertFalse(this.channel1.isRegistered());
- tryFinish();
- }
-
- public void testCFII_Data_FinishConnect_AddrSetServerStartLater()
- throws IOException, InterruptedException {
- ensureServerClosed();
- java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
- writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- this.channel1.configureBlocking(false);
- try {
- SocketChannel.open(localAddr1);
- fail("Should throw ConnectException");
- } catch (ConnectException e) {
- // correct
- }
- assertTrue(this.channel1.isOpen());
- assertFalse(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnectionPending());
- this.channel1.configureBlocking(true);
- try {
- this.channel1.finishConnect();
- fail("Should throw NoConnectionPendingException");
- } catch (NoConnectionPendingException e) {
- // correct
- }
- try {
- this.channel1.connect(localAddr2);
- fail("Should throw ConnectException");
- } catch (ConnectException e) {
- // correct
- }
-
- assertTrue(this.channel1.isBlocking());
- try {
- this.channel1.finishConnect();
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- assertFalse(this.channel1.isConnected());
- // finish after finish OK
- assertFalse(this.channel1.isConnectionPending());
- this.channel1 = SocketChannel.open();
- this.channel1.configureBlocking(false);
- this.channel1.connect(localAddr1);
- assertFalse(this.channel1.isConnected());
- ensureServerOpen();
- // cannot connect?
- try {
- assertFalse(this.channel1.finishConnect());
- assertFalse(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertTrue(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw ConnectionPendingException");
- } catch (ConnectionPendingException e) {
- // correct
- }
- this.channel1.configureBlocking(true);
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw ConnectionPendingException");
- } catch (ConnectionPendingException e) {
- // correct
- }
- tryFinish();
- } catch (ConnectException e) {
- // FIXME: assertEquals(e.getMessage(), "Connection refused");
- }
- }
-
- public void testCFII_Data_FinishConnect_ServerStartLater()
- throws IOException {
- ensureServerClosed();
- java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
- writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- this.channel1.configureBlocking(true);
- try {
- this.channel1.finishConnect();
- fail("Should throw NoConnectionPendingException");
- } catch (NoConnectionPendingException e) {
- // correct
- }
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw ConnectException");
- } catch (ConnectException e) {
- // correct
- }
-
- try {
- this.channel1.finishConnect();
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- assertFalse(this.channel1.isConnected());
- // finish after finish OK
- assertFalse(this.channel1.isConnectionPending());
- this.channel1 = SocketChannel.open();
- this.channel1.configureBlocking(false);
- this.channel1.connect(localAddr1);
- assertFalse(this.channel1.isConnected());
- ensureServerOpen();
- // cannot connect?
- try {
- assertFalse(this.channel1.finishConnect());
- assertFalse(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertTrue(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw ConnectionPendingException");
- } catch (ConnectionPendingException e) {
- // correct
- }
- this.channel1.configureBlocking(true);
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw ConnectionPendingException");
- } catch (ConnectionPendingException e) {
- // correct
- }
- tryFinish();
- } catch (ConnectException e) {
- // FIXME: assertEquals(e.getMessage(), "Connection refused");
- }
- }
-
- public void testCFII_Data_FinishConnect_Blocking() throws IOException {
- ensureServerOpen();
- java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
- .allocate(CAPACITY_NORMAL);
- java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
- writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- this.channel1.configureBlocking(true);
- try {
- this.channel1.finishConnect();
- fail("Should throw NoConnectionPendingException");
- } catch (NoConnectionPendingException e) {
- // correct
- }
-
- this.channel1.connect(localAddr1);
-
- assertTrue(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- if (tryFinish()) {
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1));
-
- try {
- this.channel1.connect(localAddr1);
- fail("Should throw AlreadyConnectedException");
- } catch (AlreadyConnectedException e) {
- // correct
- }
- }
- assertFalse(this.channel1.isRegistered());
- tryFinish();
- }
-
- /**
- * Regression test for Harmony-1947.
- */
- public void test_finishConnect() throws Exception {
- SocketAddress address = new InetSocketAddress("localhost", 0);
-
- ServerSocketChannel theServerChannel = ServerSocketChannel.open();
- ServerSocket serversocket = theServerChannel.socket();
- serversocket.setReuseAddress(true);
- // Bind the socket
- serversocket.bind(address);
-
- boolean doneNonBlockingConnect = false;
- // Loop so that we make sure we're definitely testing finishConnect()
- while (!doneNonBlockingConnect) {
- channel1 = SocketChannel.open();
-
- // Set the SocketChannel to non-blocking so that connect(..) does
- // not block
- channel1.configureBlocking(false);
- boolean connected = channel1.connect(new InetSocketAddress("localhost",serversocket.getLocalPort()));
- if (!connected) {
- // Now set the SocketChannel back to blocking so that
- // finishConnect() blocks.
- channel1.configureBlocking(true);
- doneNonBlockingConnect = channel1.finishConnect();
- }
- if (doneNonBlockingConnect) {
- tryFinish();
- }
- channel1.close();
- }
- if (!serversocket.isClosed()) {
- serversocket.close();
- }
- }
-
- // -------------------------------------------------------------------
- // End of original tests. Test method for CFII with real data.
- // -------------------------------------------------------------------
-
- /**
- * @tests java.nio.channels.SocketChannel#read(ByteBuffer)
- */
- public void test_readLjava_nio_ByteBuffer_Blocking() throws IOException {
- // initialize write content
- byte[] writeContent = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < writeContent.length; i++) {
- writeContent[i] = (byte) i;
- }
- // establish connection
- channel1.connect(localAddr1);
- Socket acceptedSocket = server1.accept();
-
- // use OutputStream.write to send CAPACITY_NORMAL bytes data
- OutputStream out = acceptedSocket.getOutputStream();
- out.write(writeContent);
- // use close to guarantee all data is sent
- acceptedSocket.close();
-
- ByteBuffer readContent = ByteBuffer.allocate(CAPACITY_NORMAL + 1);
- int totalCount = 0;
- int count = 0;
- long startTime = System.currentTimeMillis();
- // use SocketChannel.read to read data
- while (totalCount <= CAPACITY_NORMAL) {
- count = channel1.read(readContent);
- if (EOF == count) {
- break;
- }
- totalCount += count;
- // if the channel could not finish reading in TIMEOUT ms, the
- // test fails. It is used to guarantee the test never hangs even
- // if there are bugs of SocketChannel implementation. For
- // blocking read, it possibly returns 0 in some cases.
- assertTimeout(startTime, TIMEOUT);
- }
- assertEquals(CAPACITY_NORMAL, totalCount);
- readContent.flip();
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- assertEquals(writeContent[i], readContent.get());
- }
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#read(ByteBuffer)
- */
- public void test_readLjava_nio_ByteBuffer_Nonblocking() throws IOException {
- // initialize write content
- byte[] writeContent = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < writeContent.length; i++) {
- writeContent[i] = (byte) i;
- }
-
- // establish connection
- channel1.connect(localAddr1);
- Socket acceptedSocket = server1.accept();
- // use OutputStream.write to write CAPACITY_NORMAL bytes data.
- OutputStream out = acceptedSocket.getOutputStream();
- out.write(writeContent);
- // use close to guarantee all data is sent
- acceptedSocket.close();
-
- channel1.configureBlocking(false);
- ByteBuffer readContent = ByteBuffer.allocate(CAPACITY_NORMAL + 1);
- int totalCount = 0;
- int count = 0;
- long startTime = System.currentTimeMillis();
- // use SocketChannel.read to read data
- while (totalCount <= CAPACITY_NORMAL) {
- count = channel1.read(readContent);
- if (EOF == count) {
- break;
- }
- totalCount += count;
- // if the channel could not finish reading in TIMEOUT ms, the
- // test fails. It is used to guarantee the test never hangs even
- // if there are bugs of SocketChannel implementation.
- assertTimeout(startTime, TIMEOUT);
- }
-
- // assert read content
- assertEquals(CAPACITY_NORMAL, totalCount);
- assertEquals(CAPACITY_NORMAL, readContent.position());
- readContent.flip();
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- assertEquals(writeContent[i], readContent.get());
- }
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer)
- */
- public void test_writeLjava_nio_ByteBuffer_Blocking() throws IOException {
- // initialize write content
- ByteBuffer writeContent = ByteBuffer.allocate(CAPACITY_NORMAL);
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- writeContent.put((byte) i);
- }
- writeContent.flip();
- // establish connection
- channel1.connect(localAddr1);
- Socket acceptedSocket = server1.accept();
-
- // use SocketChannel.write(ByteBuffer) to write CAPACITY_NORMAL bytes
- // data
- int writtenCount = channel1.write(writeContent);
- // assert written count and ByteBuffer position
- assertEquals(CAPACITY_NORMAL, writtenCount);
- assertEquals(CAPACITY_NORMAL, writeContent.position());
- // use close to guarantee all data is sent
- channel1.close();
-
- InputStream in = acceptedSocket.getInputStream();
- int totalCount = 0;
- int count = 0;
- byte[] readContent = new byte[CAPACITY_NORMAL + 1];
- // if the channel could not finish reading in TIMEOUT ms, the test
- // fails. It is used to guarantee the test never hangs even if there
- // are bugs of SocketChannel implementation.
- acceptedSocket.setSoTimeout(TIMEOUT);
-
- // use InputStream.read to read data.
- while (totalCount <= CAPACITY_NORMAL) {
- count = in.read(readContent, totalCount, readContent.length
- - totalCount);
- if (EOF == count) {
- break;
- }
- totalCount += count;
- }
-
- // assert read content
- assertEquals(CAPACITY_NORMAL, totalCount);
- writeContent.flip();
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- assertEquals(writeContent.get(), readContent[i]);
- }
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer)
- */
- public void test_writeLjava_nio_ByteBuffer_NonBlocking() throws Exception {
- // initialize write content
- ByteBuffer writeContent = ByteBuffer.allocate(CAPACITY_NORMAL);
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- writeContent.put((byte) i);
- }
- writeContent.flip();
-
- // establish connection
- channel1.connect(localAddr1);
- Socket acceptedSocket = server1.accept();
-
- channel1.configureBlocking(false);
- int writtenTotalCount = 0;
- int writtenCount = 0;
- long startTime = System.currentTimeMillis();
- // use SocketChannel.write(ByteBuffer) to write CAPACITY_NORMAL bytes
- while (writtenTotalCount < CAPACITY_NORMAL) {
- writtenCount = channel1.write(writeContent);
- writtenTotalCount += writtenCount;
- // if the channel could not finish writing in TIMEOUT ms, the
- // test fails. It is used to guarantee the test never hangs even
- // if there are bugs of SocketChannel implementation.
- assertTimeout(startTime, TIMEOUT);
- }
- // assert written count and ByteBuffer position
- assertEquals(CAPACITY_NORMAL, writtenTotalCount);
- assertEquals(CAPACITY_NORMAL, writeContent.position());
- // use close to guarantee all data is sent
- channel1.close();
-
- InputStream in = acceptedSocket.getInputStream();
- byte[] readContent = new byte[CAPACITY_NORMAL + 1];
- int totalCount = 0;
- int count = 0;
- // if the channel could not finish reading in TIMEOUT ms, the test
- // fails. It is used to guarantee the test never hangs even if there
- // are bugs of SocketChannel implementation.
- acceptedSocket.setSoTimeout(TIMEOUT);
- // use InputStream.read to read data.
- while (totalCount <= CAPACITY_NORMAL) {
- count = in.read(readContent, totalCount, readContent.length
- - totalCount);
- if (EOF == count) {
- break;
- }
- totalCount += count;
- }
- // assert read content
- assertEquals(CAPACITY_NORMAL, totalCount);
- writeContent.flip();
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- assertEquals(writeContent.get(), readContent[i]);
- }
- }
-
- /*
- * Fails if the difference between current time and start time is greater
- * than timeout.
- */
- private void assertTimeout(long startTime, long timeout) {
- long currentTime = System.currentTimeMillis();
- if ((currentTime - startTime) > timeout) {
- fail("Timeout");
- }
- }
-
- // -------------------------------------------------
- // Test for read/write but no real data expressed
- // -------------------------------------------------
-
- public void testReadByteBuffer() throws Exception {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer readBuf = java.nio.ByteBuffer
- .allocate(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- // note: blocking-mode will make the read process endless!
- this.channel1.configureBlocking(false);
- try {
- channel1.read(readBuf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- boolean connected = this.channel1.connect(localAddr1);
- if (!connected) {
- assertFalse(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnectionPending());
- assertFalse(this.channel1.isConnected());
- }
- if (tryFinish()) {
- assertEquals(0, this.channel1.read(readBuf));
- }
-
- this.channel1.close();
- try {
- channel1.read(readBuf);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testReadByteBuffer_Direct() throws Exception {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer readBuf = java.nio.ByteBuffer
- .allocateDirect(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- // note: blocking-mode will make the read process endless!
- this.channel1.configureBlocking(false);
- try {
- channel1.read(readBuf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- boolean connected = this.channel1.connect(localAddr1);
- if (!connected) {
- assertFalse(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnectionPending());
- assertFalse(this.channel1.isConnected());
- }
- if (tryFinish()) {
- assertEquals(0, this.channel1.read(readBuf));
- }
-
- this.channel1.close();
- try {
- channel1.read(readBuf);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testReadByteBuffer_Direct2() throws IOException {
- byte[] request = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- ByteBuffer buffer = ByteBuffer.allocateDirect(128);
-
- ServerSocketChannel server = ServerSocketChannel.open();
- server.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0), 5);
- Socket client = new Socket(InetAddress.getLocalHost(), server.socket()
- .getLocalPort());
- client.setTcpNoDelay(false);
- Socket worker = server.socket().accept();
- SocketChannel workerChannel = worker.getChannel();
-
- OutputStream out = client.getOutputStream();
- out.write(request);
- out.close();
-
- buffer.limit(5);
- int bytesRead = workerChannel.read(buffer);
- assertEquals(5, bytesRead);
- assertEquals(5, buffer.position());
-
- buffer.limit(request.length);
- bytesRead = workerChannel.read(buffer);
- assertEquals(6, bytesRead);
-
- buffer.flip();
- assertEquals(request.length, buffer.limit());
-
- assertEquals(ByteBuffer.wrap(request), buffer);
-
- client.close();
- worker.close();
- server.close();
- }
-
- public void testReadByteBuffer_BufNull() throws Exception {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer readBuf = java.nio.ByteBuffer.allocate(0);
- // note: blocking-mode will make the read process endless!
- this.channel1.configureBlocking(false);
- try {
- channel1.read((java.nio.ByteBuffer) null);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- this.channel1.connect(localAddr1);
- if (tryFinish()) {
- try {
- this.channel1.read((java.nio.ByteBuffer) null);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- assertEquals(0, this.channel1.read(readBuf));
- }
- this.server1.close();
- try {
- channel1.read((java.nio.ByteBuffer) null);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- /*
- * SocketChannelImpl.read(ByteBuffer[], int, int)'
- */
- public void testReadByteBufferArrayIntInt() throws Exception {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer[] readBuf = new java.nio.ByteBuffer[2];
- readBuf[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- readBuf[1] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- // note: blocking-mode will make the read process endless!
- this.channel1.configureBlocking(false);
- try {
- channel1.read(readBuf, 0, 1);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- boolean connected = this.channel1.connect(localAddr1);
- if (!connected) {
- assertFalse(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnectionPending());
- assertFalse(this.channel1.isConnected());
- }
- if (tryFinish()) {
- assertEquals(0, this.channel1.read(readBuf, 0, 1));
- assertEquals(0, this.channel1.read(readBuf, 0, 2));
- }
-
- this.channel1.close();
- try {
- channel1.read(readBuf, 0, 1);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- /*
- * SocketChannelImpl.read(ByteBuffer[], int, int)'
- */
- public void testReadByteBufferArrayIntInt_Direct() throws Exception {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer[] readBuf = new java.nio.ByteBuffer[2];
- readBuf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- readBuf[1] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- // note: blocking-mode will make the read process endless!
- this.channel1.configureBlocking(false);
- try {
- channel1.read(readBuf, 0, 1);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- boolean connected = this.channel1.connect(localAddr1);
- if (!connected) {
- assertFalse(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnectionPending());
- assertFalse(this.channel1.isConnected());
- }
- if (tryFinish()) {
- assertEquals(0, this.channel1.read(readBuf, 0, 1));
- assertEquals(0, this.channel1.read(readBuf, 0, 2));
- }
-
- this.channel1.close();
- try {
- channel1.read(readBuf, 0, 1);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testReadByteBufferArrayIntInt_BufNull() throws Exception {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer[] readBuf = new java.nio.ByteBuffer[2];
- readBuf[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- // note: blocking-mode will make the read process endless!
- this.channel1.configureBlocking(false);
- try {
- channel1.read(null, 0, 0);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- this.channel1.connect(localAddr1);
- if (tryFinish()) {
-
- try {
- channel1.read(null, 0, 0);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- channel1.read(readBuf, 0, 2);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
-
- assertEquals(0, this.channel1.read(readBuf, 0, 1));
- }
- this.channel1.close();
- try {
- channel1.read(null, 0, 1);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- public void testWriteByteBuffer() throws IOException {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
- .allocate(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- try {
- channel1.write(writeBuf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(localAddr1);
- assertTrue(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
-
- this.channel1.close();
- try {
- channel1.write(writeBuf);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testWriteByteBuffer_Direct() throws IOException {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
- .allocateDirect(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- try {
- channel1.write(writeBuf);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(localAddr1);
- assertTrue(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
-
- this.channel1.close();
- try {
- channel1.write(writeBuf);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testWriteByteBuffer_BufNull() throws IOException {
- assertTrue(this.server1.isBound());
- java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer.allocate(0);
- this.channel1.connect(localAddr1);
- assertEquals(this.channel1.write(writeBuf), 0);
- try {
- this.channel1.write((java.nio.ByteBuffer) null);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- /*
- * SocketChannelImpl.write(ByteBuffer[], int, int)'
- */
- public void testWriteByteBufferArrayIntInt() throws IOException {
- java.nio.ByteBuffer[] writeBuf = new java.nio.ByteBuffer[2];
- writeBuf[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- writeBuf[1] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- try {
- channel1.write(writeBuf, 0, 1);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(localAddr1);
- assertTrue(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 1));
- // still writes the same size as above
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 2));
- writeBuf[0].flip();
- writeBuf[1].flip();
- assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
- this.channel1.close();
- try {
- channel1.write(writeBuf);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- /*
- * SocketChannelImpl.write(ByteBuffer[], int, int)'
- */
- public void testWriteByteBufferArrayIntInt_Direct() throws IOException {
- java.nio.ByteBuffer[] writeBuf = new java.nio.ByteBuffer[2];
- writeBuf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- writeBuf[1] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
- assertFalse(this.channel1.isRegistered());
- assertTrue(this.channel1.isBlocking());
- assertFalse(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- try {
- channel1.write(writeBuf, 0, 1);
- fail("Should throw NotYetConnectedException");
- } catch (NotYetConnectedException e) {
- // correct
- }
- this.channel1.connect(localAddr1);
- assertTrue(this.channel1.isBlocking());
- assertTrue(this.channel1.isConnected());
- assertFalse(this.channel1.isConnectionPending());
- assertTrue(this.channel1.isOpen());
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 1));
- // still writes the same size as above
- assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 2));
- writeBuf[0].flip();
- writeBuf[1].flip();
- assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
- this.channel1.close();
- try {
- channel1.write(writeBuf);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // correct
- }
- }
-
- public void testWriteByteBufferArrayIntInt_BufNull() throws IOException {
- java.nio.ByteBuffer[] writeBuf = new java.nio.ByteBuffer[0];
-
- this.channel1.connect(localAddr1);
- try {
- this.channel1.write(null, 0, 1);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- assertEquals(0, this.channel1.write(writeBuf, 0, 0));
- try {
- this.channel1.write(writeBuf, 0, 1);
- fail("Should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // correct
- }
- writeBuf = new java.nio.ByteBuffer[1];
- try {
- this.channel1.write(writeBuf, 0, 1);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- try {
- this.channel1.write(writeBuf, 0, 2);
- fail("Should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // correct
- }
- this.server1.close();
- try {
- channel1.read(null, 0, 1);
- fail("Should throw NPE");
- } catch (NullPointerException e) {
- // correct
- }
- }
-
- public void testWriteByteBufferArrayIntInt_SizeError() throws IOException {
- java.nio.ByteBuffer[] buf = new java.nio.ByteBuffer[1];
- this.channel1.connect(localAddr1);
- assertEquals(0, this.channel1.write(buf, 0, 0));
- try {
- this.channel1.write(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.write(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.write(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.write(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.write(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- this.server1.close();
- }
-
- public void testReadByteBufferArrayIntInt_SizeError() throws IOException {
- java.nio.ByteBuffer[] buf = new java.nio.ByteBuffer[1];
- this.channel1.connect(localAddr1);
- assertEquals(0, this.channel1.read(buf, 0, 0));
- try {
- this.channel1.read(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.read(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.read(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.read(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- this.channel1.read(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- this.server1.close();
- }
-
- /*
- * ==========================================================================
- * Tests for read/write real data
- * ==========================================================================
- */
-
-
- /**
- * @tests java.nio.channels.SocketChannel#read(ByteBuffer[])
- */
- public void test_read$LByteBuffer() throws IOException {
- MockSocketChannel sc = new MockSocketChannel(null);
- ByteBuffer [] byteBufferArray = { ByteBuffer.allocate(1), ByteBuffer.allocate(1)};
- // Verify that calling read(ByteBuffer[]) leads to the method
- // read(ByteBuffer[], int, int) being called with a 0 for the
- // second parameter and targets.length as the third parameter.
- sc.read(byteBufferArray);
- assertTrue(sc.isReadCalled);
- }
- /**
- * @tests java.nio.channels.SocketChannel#read(ByteBuffer[],int,int)
- */
- public void test_read$LByteBufferII_blocking() throws Exception {
- assert_read$LByteBuffer(true);
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#read(ByteBuffer[],int,int)
- */
- public void test_read$LByteBufferII_nonblocking() throws Exception {
- assert_read$LByteBuffer(false);
- }
-
- private void assert_read$LByteBuffer(boolean isBlocking) throws IOException {
- // initialize write content
- byte[] writeContent = new byte[CAPACITY_NORMAL * 2];
- for (int i = 0; i < CAPACITY_NORMAL * 2; i++) {
- writeContent[i] = (byte) i;
- }
- ByteBuffer[] readContents = new ByteBuffer[2];
- readContents[0] = ByteBuffer.allocate(CAPACITY_NORMAL);
- readContents[1] = ByteBuffer.allocate(CAPACITY_NORMAL + 1);
- // establish connection
- channel1.connect(localAddr1);
- Socket acceptedSocket = server1.accept();
- // use OutputStream.write to send CAPACITY_NORMAL * 2 bytes data
- OutputStream out = acceptedSocket.getOutputStream();
- out.write(writeContent);
- // use close to guarantee all data is sent
- acceptedSocket.close();
- // configure block/nonblock mode
- channel1.configureBlocking(isBlocking);
- long startTime = System.currentTimeMillis();
- long totalRead = 0;
- long countRead = 0;
-
- while (totalRead <= CAPACITY_NORMAL * 2) {
- countRead = channel1.read(readContents, 0, 2);
- if (0 == countRead && !readContents[1].hasRemaining()) {
- // read returns 0 because readContents is full
- break;
- }
- if (EOF == countRead) {
- break;
- }
- totalRead += countRead;
- // if the channel could not finish reading in TIMEOUT ms, the
- // test fails. It is used to guarantee the test never hangs even
- // if there are bugs of SocketChannel implementation. For
- // blocking read, it possibly returns 0 in some cases.
- assertTimeout(startTime, TIMEOUT);
- }
-
- // assert total bytes read and the position of ByteBuffers
- assertEquals(CAPACITY_NORMAL * 2, totalRead);
- assertEquals(CAPACITY_NORMAL, readContents[0].position());
- assertEquals(CAPACITY_NORMAL, readContents[1].position());
- // assert read content
- readContents[0].flip();
- readContents[1].flip();
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- assertEquals(writeContent[i], readContents[0].get());
- }
- for (int i = CAPACITY_NORMAL; i < CAPACITY_NORMAL * 2; i++) {
- assertEquals(writeContent[i], readContents[1].get());
- }
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[],int,int)
- */
- public void test_write$LByteBufferII_blocking() throws Exception {
- assert_write$LByteBuffer(true);
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[],int,int)
- */
- public void test_write$LByteBufferII_nonblocking()
- throws Exception {
- assert_write$LByteBuffer(false);
- }
-
- private void assert_write$LByteBuffer(boolean isBlocking)
- throws IOException {
- // initialize write contents
- ByteBuffer writeContents[] = new ByteBuffer[2];
- writeContents[0] = ByteBuffer.allocate(CAPACITY_NORMAL);
- writeContents[1] = ByteBuffer.allocate(CAPACITY_NORMAL);
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- writeContents[0].put((byte) i);
- }
- for (int i = CAPACITY_NORMAL; i < CAPACITY_NORMAL * 2; i++) {
- writeContents[1].put((byte) i);
- }
- writeContents[0].flip();
- writeContents[1].flip();
- // establish connection
- channel1.connect(localAddr1);
- Socket acceptedSocket = server1.accept();
- // set blocking/nonblocking mode
- channel1.configureBlocking(isBlocking);
-
- assertEquals(CAPACITY_NORMAL, channel1.write(writeContents, 0, 1));
- assertEquals(CAPACITY_NORMAL, channel1.write(writeContents, 1, 1));
-
- // assert written count and ByteBuffer position
- assertEquals(CAPACITY_NORMAL, writeContents[0].position());
- assertEquals(CAPACITY_NORMAL, writeContents[1].position());
- // use close to guarantee all data is sent
- channel1.close();
- InputStream in = acceptedSocket.getInputStream();
- byte[] readContent = new byte[CAPACITY_NORMAL * 2 + 1];
- int totalCount = 0;
- int count = 0;
- // if the channel could not finish reading in TIMEOUT ms, the test
- // fails. It is used to guarantee the test never hangs even if there
- // are bugs of SocketChannel implementation.
- acceptedSocket.setSoTimeout(TIMEOUT);
- // use InputStream.read to read data.
- while (totalCount <= CAPACITY_NORMAL) {
- count = in.read(readContent, totalCount, readContent.length
- - totalCount);
- if (EOF == count) {
- break;
- }
- totalCount += count;
- }
- // assert read content
- assertEquals(CAPACITY_NORMAL * 2, totalCount);
- writeContents[0].flip();
- writeContents[1].flip();
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- assertEquals(writeContents[0].get(), readContent[i]);
- }
- for (int i = CAPACITY_NORMAL; i < CAPACITY_NORMAL * 2; i++) {
- assertEquals(writeContents[1].get(), readContent[i]);
- }
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
- */
- public void test_write$LByteBuffer() throws IOException {
- MockSocketChannel sc = new MockSocketChannel(null);
- ByteBuffer [] byteBufferArray = { ByteBuffer.allocate(1), ByteBuffer.allocate(1)};
- // Verify that calling write(ByteBuffer[]) leads to the method
- // write(ByteBuffer[], int, int) being called with a 0 for the
- // second parameter and sources.length as the third parameter.
- sc.write(byteBufferArray);
- assertTrue(sc.isWriteCalled);
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
- */
- public void test_writev() throws Exception {
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(localAddr2);
- SocketChannel sc = SocketChannel.open();
- sc.connect(localAddr2);
- SocketChannel sock = ssc.accept();
- ByteBuffer[] buf = { ByteBuffer.allocate(10), ByteBuffer.allocateDirect(20) };
-
- while (buf[0].remaining() != 0 && buf[1].remaining() !=0) {
- assertTrue(sc.write(buf, 0, 2) >= 0);
- }
-
- ByteBuffer target = ByteBuffer.allocate(30);
-
- while (target.remaining() != 0) {
- assertTrue(sock.read(target) >=0);
- }
-
- ssc.close();
- sc.close();
- sock.close();
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
- */
- public void test_writev2() throws Exception {
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.configureBlocking(false);
- ssc.socket().bind(null);
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- boolean connected = sc.connect(ssc.socket().getLocalSocketAddress());
- SocketChannel sock = ssc.accept();
- if (!connected) {
- sc.finishConnect();
- }
-
- ByteBuffer buf1 = ByteBuffer.allocate(10);
- sc.socket().setSendBufferSize(512);
- int bufSize = sc.socket().getSendBufferSize();
- ByteBuffer buf2 = ByteBuffer.allocate(bufSize * 10);
-
- ByteBuffer[] sent = new ByteBuffer[2];
- sent[0] = buf1;
- sent[1] = buf2;
-
- long whole = buf1.remaining() + buf2.remaining();
-
- long write = sc.write(sent);
- ssc.close();
- sc.close();
- sock.close();
-
- assertTrue(whole == (write + buf1.remaining() + buf2.remaining()));
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
- *
- * In non-blocking mode, the native system call will return EAGAIN/EWOULDBLOCK error
- * code on Linux/Unix and return WSATRY_AGAIN/WSAEWOULDBLOCK error code on Windows.
- * These error code means try again but not fatal error, so we should not throw exception.
- */
- public void test_write$NonBlockingException() throws Exception {
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.configureBlocking(false);
- ssc.socket().bind(null);
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- boolean connected = sc.connect(ssc.socket().getLocalSocketAddress());
- SocketChannel sock = ssc.accept();
- if (!connected) {
- sc.finishConnect();
- }
-
- try {
- for (int i = 0; i < 100; i++) {
- ByteBuffer buf1 = ByteBuffer.allocate(10);
- sc.socket().setSendBufferSize(512);
- int bufSize = sc.socket().getSendBufferSize();
- ByteBuffer buf2 = ByteBuffer.allocate(bufSize * 10);
-
- ByteBuffer[] sent = new ByteBuffer[2];
- sent[0] = buf1;
- sent[1] = buf2;
-
- sc.write(sent);
- }
- } finally {
- ssc.close();
- sc.close();
- sock.close();
- }
-
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
- */
- public void test_write$LByteBuffer2() throws IOException {
- // Set-up
- ServerSocketChannel server = ServerSocketChannel.open();
- server.socket().bind(null);
- SocketChannel client = SocketChannel.open();
- client.connect(server.socket().getLocalSocketAddress());
- SocketChannel worker = server.accept();
-
- // Test overlapping buffers
- byte[] data = "Hello world!".getBytes("UTF-8");
- ByteBuffer[] buffers = new ByteBuffer[3];
- buffers[0] = ByteBuffer.wrap(data, 0, 6);
- buffers[1] = ByteBuffer.wrap(data, 6, data.length - 6);
- buffers[2] = ByteBuffer.wrap(data);
-
- // Write them out, read what we wrote and check it
- client.write(buffers);
- client.close();
- ByteBuffer readBuffer = ByteBuffer.allocate(1024);
- while (EOF != worker.read(readBuffer)) {};
- readBuffer.flip();
- Buffer expected = ByteBuffer.allocate(1024).put(data).put(data).flip();
- assertEquals(expected, readBuffer);
-
- // Tidy-up
- worker.close();
- server.close();
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
- */
- public void test_write$LByteBuffer_buffers() throws IOException {
- // Set-up
- ServerSocketChannel server = ServerSocketChannel.open();
- server.socket().bind(null);
- SocketChannel client = SocketChannel.open();
- client.connect(server.socket().getLocalSocketAddress());
- SocketChannel worker = server.accept();
-
- // A variety of buffer types to write
- byte[] data = "Hello world!".getBytes("UTF-8");
- ByteBuffer[] buffers = new ByteBuffer[3];
- buffers[0] = ByteBuffer.wrap(data, 0, 2);
- assertFalse(buffers[0].isDirect());
- assertTrue(buffers[0].hasArray());
-
- buffers[1] = ByteBuffer.wrap(data, 2, 4).asReadOnlyBuffer();
- assertFalse(buffers[1].isDirect());
- assertFalse(buffers[1].hasArray());
-
- buffers[2] = ByteBuffer.allocateDirect(42);
- buffers[2].put(data, 6, data.length - 6);
- buffers[2].flip();
- assertTrue(buffers[2].isDirect());
- // Android's direct buffers do have a backing array.
- assertTrue(buffers[2].hasArray());
-
- // Write them out, read what we wrote and check it
- client.write(buffers);
- client.close();
- ByteBuffer readBuffer = ByteBuffer.allocate(1024);
- while (EOF != worker.read(readBuffer)) {};
- readBuffer.flip();
- assertEquals(ByteBuffer.wrap(data), readBuffer);
-
- // Tidy-up
- worker.close();
- server.close();
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
- */
- public void test_write$LByteBuffer_writes() throws IOException {
- // Set-up
- ServerSocketChannel server = ServerSocketChannel.open();
- server.socket().bind(null);
- SocketChannel client = SocketChannel.open();
- client.connect(server.socket().getLocalSocketAddress());
- SocketChannel worker = server.accept();
-
- // Data to write
- byte[] data = "Hello world!".getBytes("UTF-8");
- ByteBuffer[] buffers = new ByteBuffer[3];
- buffers[0] = ByteBuffer.wrap(data, 0, 6);
- buffers[1] = ByteBuffer.wrap("world!".getBytes("UTF-8"));
- buffers[2] = buffers[0];
- assertTrue(buffers[0].hasArray());
-
- // Test a sequence of write calls
- client.write(buffers, 0, 0); // write nothing
- client.write(buffers, 1, 0); // write nothing
- client.write(buffers, 0, 1); // write "Hello "
- assertEquals("Failed to drain buffer 0", 0, buffers[0].remaining());
- assertEquals("Shouldn't touch buffer 1", buffers[1].limit(), buffers[1]
- .remaining());
- client.write(buffers, 0, 2); // writes "world!"
- assertEquals("Failed to drain buffer 1", 0, buffers[1].remaining());
- client.write(buffers, 0, 3); // write nothing
- client.close();
-
- // Read what we wrote and check it
- ByteBuffer readBuffer = ByteBuffer.allocate(1024);
- while (EOF != worker.read(readBuffer)) {};
- readBuffer.flip();
- assertEquals(ByteBuffer.wrap(data), readBuffer);
-
- // Tidy-up
- worker.close();
- server.close();
- }
-
- /**
- * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
- */
- public void test_write$LByteBuffer_invalid() throws IOException {
- // Set-up
- ServerSocketChannel server = ServerSocketChannel.open();
- server.socket().bind(null);
-
- SocketChannel client = SocketChannel.open();
- client.connect(server.socket().getLocalSocketAddress());
-
- SocketChannel worker = server.accept();
-
- // Do some stuff
- try {
- client.write((ByteBuffer[]) null);
- fail("Should throw a NPE");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- client.write((ByteBuffer[]) null, 0, 0);
- fail("Should throw a NPE");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- client.write((ByteBuffer[]) null, 1, 0);
- fail("Should throw a NPE");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- client.write((ByteBuffer[]) null, 0, 1);
- fail("Should throw a NPE");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- client.write((ByteBuffer[]) null, 1, 1);
- fail("Should throw a NPE");
- } catch (NullPointerException e) {
- // expected
- }
-
- ByteBuffer[] buffers = new ByteBuffer[1];
- buffers[0] = ByteBuffer.wrap("Hello ".getBytes("UTF-8"));
-
- try {
- client.write(buffers, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- client.write(buffers, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- client.write(buffers, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- client.write(buffers, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- client.write(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Tidy-up
- worker.close();
- client.close();
- server.close();
- }
-
- public void testSocket_configureblocking() throws IOException {
- byte[] serverWBuf = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < serverWBuf.length; i++) {
- serverWBuf[i] = (byte) i;
- }
- java.nio.ByteBuffer buf = java.nio.ByteBuffer
- .allocate(CAPACITY_NORMAL + 1);
- channel1.connect(localAddr1);
- server1.accept();
- Socket sock = this.channel1.socket();
- channel1.configureBlocking(false);
- assertFalse(channel1.isBlocking());
- OutputStream channelSocketOut = sock.getOutputStream();
- try {
- // write operation is not allowed in non-blocking mode
- channelSocketOut.write(buf.array());
- fail("Non-Blocking mode should cause IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // correct
- }
- channel1.configureBlocking(true);
- assertTrue(channel1.isBlocking());
- // write operation is allowed in blocking mode
- channelSocketOut.write(buf.array());
- }
-
- /**
- * @tests SocketChannel#read(ByteBuffer[], int, int) when remote server
- * closed
- */
- public void test_socketChannel_read_ByteBufferII_remoteClosed()
- throws Exception {
- // regression 1 for HARMONY-549
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(localAddr2);
- SocketChannel sc = SocketChannel.open();
- sc.connect(localAddr2);
- ssc.accept().close();
- ByteBuffer[] buf = { ByteBuffer.allocate(10) };
- assertEquals(-1, sc.read(buf, 0, 1));
- ssc.close();
- sc.close();
- }
-
- /**
- * @tests SocketChannel#write(ByteBuffer[], int, int)
- */
- public void test_socketChannel_write_ByteBufferII() throws Exception {
- // regression 2 for HARMONY-549
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(localAddr2);
- SocketChannel sc = SocketChannel.open();
- sc.connect(localAddr2);
- SocketChannel sock = ssc.accept();
- ByteBuffer[] buf = { ByteBuffer.allocate(10), null };
- try {
- sc.write(buf, 0, 2);
- fail("should throw NPE");
- } catch (NullPointerException e) {
- // expected
- }
- ssc.close();
- sc.close();
- ByteBuffer target = ByteBuffer.allocate(10);
- assertEquals(-1, sock.read(target));
- }
-
- /**
- * @tests SocketChannel#read(ByteBuffer[], int, int) with a null ByteBuffer
- */
- public void test_socketChannel_read_ByteBufferII_bufNULL() throws Exception {
- // regression 3 for HARMONY-549
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(localAddr2);
- SocketChannel sc = SocketChannel.open();
- sc.connect(localAddr2);
- ssc.accept();
- ByteBuffer[] buf = new ByteBuffer[2];
- buf[0] = ByteBuffer.allocate(1);
- // let buf[1] be null
- try {
- sc.read(buf, 0, 2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- ssc.close();
- sc.close();
- }
-
- /**
- * @tests SocketChannel#write(ByteBuffer) after close
- */
- public void test_socketChannel_write_close() throws Exception {
- // regression 4 for HARMONY-549
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(localAddr2);
- SocketChannel sc = SocketChannel.open();
- sc.connect(localAddr2);
- SocketChannel sock = ssc.accept();
- ByteBuffer buf = null;
- ssc.close();
- sc.close();
- try {
- sc.write(buf);
- fail("should throw NPE");
- } catch (NullPointerException e) {
- // expected
- }
- sock.close();
- }
-
- /**
- * @tests SocketChannel#write(ByteBuffer) if position is not zero
- */
- public void test_socketChannel_write_ByteBuffer_posNotZero()
- throws Exception {
- // regression 5 for HARMONY-549
- final String testStr = "Hello World";
- ByteBuffer readBuf = ByteBuffer.allocate(11);
- ByteBuffer buf = ByteBuffer.wrap(testStr.getBytes());
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(localAddr2);
- SocketChannel sc = SocketChannel.open();
- sc.connect(localAddr2);
- buf.position(2);
- ssc.accept().write(buf);
- assertEquals(9, sc.read(readBuf));
- buf.flip();
- readBuf.flip();
- byte[] read = new byte[9];
- byte[] write = new byte[11];
- buf.get(write);
- readBuf.get(read);
- for (int i = 0; i < 9; i++) {
- assertEquals(read[i], write[i + 2]);
- }
- }
-
- /**
- * @tests SocketChannelImpl#read(ByteBuffer[])
- */
- public void test_read_$ByteBuffer_Blocking() throws IOException {
- // regression test for Harmony-728
- byte[] data = new byte[CAPACITY_NORMAL];
- for (int i = 0; i < CAPACITY_NORMAL; i++) {
- data[i] = (byte) i;
- }
- ByteBuffer[] buf = new ByteBuffer[2];
- buf[0] = ByteBuffer.allocate(CAPACITY_NORMAL);
- buf[1] = ByteBuffer.allocate(CAPACITY_NORMAL);
- channel1.connect(localAddr1);
- Socket socket = null;
- try {
- socket = server1.accept();
- OutputStream out = socket.getOutputStream();
- out.write(data);
- // should not block here
- channel1.read(buf);
- } finally {
- if (null != socket) {
- socket.close();
- }
- }
- }
-
- public void test_socket_getOutputStream_nonBlocking_read_Exception() throws IOException {
- byte[] buf = new byte[1];
- channel1.connect(this.localAddr1);
- InputStream is = channel1.socket().getInputStream();
- channel1.configureBlocking(false);
- try {
- is.read();
- fail();
- } catch (IllegalBlockingModeException expected) {
- }
- try {
- is.read(null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- is.read(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- is.close();
-
- try {
- is.read();
- fail();
- } catch (IllegalBlockingModeException expected) {
- }
- try {
- is.read(null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- is.read(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_socket_getOutputStream_blocking_read_Exception() throws IOException {
- byte[] buf = new byte[1];
- channel1.connect(this.localAddr1);
- InputStream is = channel1.socket().getInputStream();
- try {
- is.read(null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- is.read(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- is.close();
-
- try {
- is.read(null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- is.read(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- is.read(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_socket_getOutputStream_nonBlocking_write_Exception() throws IOException {
- byte[] buf = new byte[1];
- channel1.connect(this.localAddr1);
- OutputStream os = channel1.socket().getOutputStream();
- channel1.configureBlocking(false);
-
- try {
- os.write(1);
- fail();
- } catch (IllegalBlockingModeException expected) {
- }
- try {
- os.write(null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- os.write(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- os.close();
-
- try {
- os.write(1);
- fail();
- } catch (IllegalBlockingModeException expected) {
- }
- try {
- os.write(null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- os.write(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_socket_getOutputStream_blocking_write_Exception() throws IOException {
- byte[] buf = new byte[1];
- channel1.connect(this.localAddr1);
- OutputStream os = channel1.socket().getOutputStream();
- try {
- os.write(null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- os.write(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- os.close();
-
- try {
- os.write(null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- os.write(buf, -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 0, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(buf, 2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- os.write(null, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- /**
- * @tests SocketChannelImpl#socket().getOutputStream().write(int)
- */
- public void test_socket_getOutputStream_write_oneByte()
- throws IOException {
-
- // Regression test for Harmony-3475
-
- int MAGIC = 123;
-
- channel1.connect(this.localAddr1);
-
- OutputStream os = channel1.socket().getOutputStream();
-
- Socket acceptedSocket = server1.accept();
-
- InputStream in = acceptedSocket.getInputStream();
-
- os.write(MAGIC);
- channel1.close();
-
- int lastByte = in.read();
- if (lastByte == -1) {
- fail("Server received nothing. Expected 1 byte.");
- } else if (lastByte != MAGIC) {
- fail("Server received wrong single byte: " + lastByte +
- ", expected: " + MAGIC);
- }
-
- lastByte = in.read();
- if (lastByte != -1) {
- fail("Server received too long sequence. Expected 1 byte.");
- }
- }
-
- public void testSocket_setOptions() throws IOException {
- channel1.connect(localAddr1);
- Socket socket = channel1.socket();
-
- ByteBuffer buffer = ByteBuffer.wrap(new byte[] {1, 2, 3});
- socket.setKeepAlive(true);
- channel1.write(buffer);
-
- socket.setOOBInline(true);
- channel1.write(buffer);
-
- socket.setReceiveBufferSize(100);
- channel1.write(buffer);
-
- socket.setReuseAddress(true);
- channel1.write(buffer);
-
- socket.setSendBufferSize(100);
- channel1.write(buffer);
-
- socket.setSoLinger(true, 100);
- channel1.write(buffer);
-
- socket.setSoTimeout(1000);
- channel1.write(buffer);
-
- socket.setTcpNoDelay(true);
- channel1.write(buffer);
-
- socket.setTrafficClass(10);
- channel1.write(buffer);
- }
-
- class MockSocketChannel extends SocketChannel{
-
- private boolean isWriteCalled = false;
-
- private boolean isReadCalled = false;
-
- public MockSocketChannel(SelectorProvider provider){
- super(provider);
- }
-
- public Socket socket() {
- return null;
- }
-
- public boolean isConnected() {
- return false;
- }
-
- public boolean isConnectionPending() {
- return false;
- }
-
- public boolean connect(SocketAddress address) throws IOException {
- return false;
- }
-
- public boolean finishConnect() throws IOException {
- return false;
- }
-
- public int read(ByteBuffer target) throws IOException {
- return 0;
- }
-
- public long read(ByteBuffer[] targets, int offset, int length) throws IOException {
- // Verify that calling read(ByteBuffer[]) leads to the method
- // read(ByteBuffer[], int, int) being called with a 0 for the
- // second parameter and targets.length as the third parameter.
- if(0 == offset && length == targets.length){
- isReadCalled = true;
- }
- return 0;
- }
-
- public int write(ByteBuffer source) throws IOException {
- return 0;
- }
-
- public long write(ByteBuffer[] sources, int offset, int length) throws IOException {
- // Verify that calling write(ByteBuffer[]) leads to the method
- // write(ByteBuffer[], int, int) being called with a 0 for the
- // second parameter and sources.length as the third parameter.
- if(0 == offset && length == sources.length){
- isWriteCalled = true;
- }
- return 0;
- }
-
- protected void implCloseSelectableChannel() throws IOException {
- // empty
- }
-
- protected void implConfigureBlocking(boolean blockingMode) throws IOException {
- // empty
- }
-
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SourceChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SourceChannelTest.java
deleted file mode 100644
index 53fdae4..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SourceChannelTest.java
+++ /dev/null
@@ -1,554 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.Pipe;
-import java.nio.channels.SelectionKey;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for java.nio.channels.Pipe.SourceChannel
- */
-public class SourceChannelTest extends TestCase {
-
- private static final int BUFFER_SIZE = 5;
-
- private static final String ISO8859_1 = "ISO8859-1";
-
- private Pipe pipe;
-
- private Pipe.SinkChannel sink;
-
- private Pipe.SourceChannel source;
-
- private ByteBuffer buffer;
-
- private ByteBuffer positionedBuffer;
-
- protected void setUp() throws Exception {
- super.setUp();
- pipe = Pipe.open();
- sink = pipe.sink();
- source = pipe.source();
- buffer = ByteBuffer.wrap("bytes".getBytes(ISO8859_1));
- positionedBuffer = ByteBuffer.wrap("12345bytes".getBytes(ISO8859_1));
- positionedBuffer.position(BUFFER_SIZE);
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#validOps()
- */
- public void test_validOps() {
- assertEquals(SelectionKey.OP_READ, source.validOps());
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_LByteBuffer_DataAvailable() throws IOException {
- // if anything can read, read method will not block
- sink.write(ByteBuffer.allocate(1));
- int count = source.read(ByteBuffer.allocate(10));
- assertEquals(1, count);
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_LByteBuffer_Exception() throws IOException {
- ByteBuffer nullBuf = null;
- try {
- source.read(nullBuf);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_LByteBuffer_SinkClosed() throws IOException {
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- sink.write(buffer);
- sink.close();
- long count = source.read(readBuf);
- assertEquals(BUFFER_SIZE, count);
- // readBuf is full, read 0 byte expected
- count = source.read(readBuf);
- assertEquals(0, count);
- // readBuf is not null, -1 is expected
- readBuf.position(0);
- count = source.read(readBuf);
- assertEquals(-1, count);
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_LByteBuffer_SourceClosed() throws IOException {
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- source.close();
- try {
- source.read(readBuf);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- readBuf.position(BUFFER_SIZE);
- try {
- // readBuf is full
- source.read(readBuf);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- ByteBuffer nullBuf = null;
- try {
- source.read(nullBuf);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- ByteBuffer[] bufArray = null;
- try {
- source.read(bufArray);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- ByteBuffer[] nullBufArray = {nullBuf};
- try {
- source.read(nullBufArray);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer[])
- */
- public void test_read_$LByteBuffer() throws IOException {
- ByteBuffer[] bufArray = { buffer, positionedBuffer };
- boolean[] sinkBlockingMode = { true, true, false, false };
- boolean[] sourceBlockingMode = { true, false, true, false };
- for (int i = 0; i < sinkBlockingMode.length; ++i) {
- // open new pipe everytime, will be closed in finally block
- pipe = Pipe.open();
- sink = pipe.sink();
- source = pipe.source();
- sink.configureBlocking(sinkBlockingMode[i]);
- source.configureBlocking(sourceBlockingMode[i]);
- buffer.position(0);
- positionedBuffer.position(BUFFER_SIZE);
- try {
- long writeCount = sink.write(bufArray);
- assertEquals(10, writeCount);
- // invoke close to ensure all data will be sent out
- sink.close();
- // read until EOF is meet or readBufArray is full.
- ByteBuffer[] readBufArray = { ByteBuffer.allocate(BUFFER_SIZE),
- ByteBuffer.allocate(BUFFER_SIZE) };
- long totalCount = 0;
- do {
- long count = source.read(readBufArray);
- if (count < 0) {
- break;
- }
- if (0 == count && BUFFER_SIZE == readBufArray[1].position()) {
- // source.read returns 0 because readBufArray is full
- break;
- }
- totalCount += count;
- } while (totalCount <= 10);
- // assert read result
- for (ByteBuffer readBuf : readBufArray) {
- // RI may fail because of its bug implementation
- assertEquals(BUFFER_SIZE, readBuf.position());
- assertEquals("bytes",
- new String(readBuf.array(), ISO8859_1));
- }
- } finally {
- // close pipe everytime
- sink.close();
- source.close();
- }
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_$LByteBuffer_Exception() throws IOException {
- ByteBuffer[] nullBufArrayRef = null;
- try {
- source.read(nullBufArrayRef);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- // ByteBuffer array contains null element
- ByteBuffer nullBuf = null;
- ByteBuffer[] nullBufArray1 = { nullBuf };
- try {
- source.read(nullBufArray1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
- try {
- source.read(nullBufArray2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_$LByteBuffer_SinkClosed() throws IOException {
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- ByteBuffer[] readBufArray = { readBuf };
- sink.write(buffer);
- sink.close();
- long count = source.read(readBufArray);
- assertEquals(BUFFER_SIZE, count);
- // readBuf is full, read 0 byte expected
- count = source.read(readBufArray);
- assertEquals(0, count);
- // readBuf is not null, -1 is expected
- readBuf.position(0);
- assertTrue(readBuf.hasRemaining());
- count = source.read(readBufArray);
- assertEquals(-1, count);
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_$LByteBuffer_SourceClosed() throws IOException {
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- ByteBuffer[] readBufArray = { readBuf };
- source.close();
- try {
- source.read(readBufArray);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- readBuf.position(BUFFER_SIZE);
- try {
- // readBuf is full
- source.read(readBufArray);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- ByteBuffer[] nullBufArrayRef = null;
- try {
- source.read(nullBufArrayRef);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- // ByteBuffer array contains null element
- ByteBuffer nullBuf = null;
- ByteBuffer[] nullBufArray1 = { nullBuf };
- try {
- source.read(nullBufArray1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer[], int, int)
- */
- public void test_read_$LByteBufferII() throws IOException {
- ByteBuffer[] bufArray = { buffer, positionedBuffer };
- boolean[] sinkBlockingMode = { true, true, false, false };
- boolean[] sourceBlockingMode = { true, false, true, false };
- for (int i = 0; i < sinkBlockingMode.length; ++i) {
- Pipe pipe = Pipe.open();
- sink = pipe.sink();
- source = pipe.source();
-
- sink.configureBlocking(sinkBlockingMode[i]);
- source.configureBlocking(sourceBlockingMode[i]);
-
- buffer.position(0);
- positionedBuffer.position(BUFFER_SIZE);
- try {
- sink.write(bufArray);
- // invoke close to ensure all data will be sent out
- sink.close();
- // read until EOF is meet or readBufArray is full.
- ByteBuffer[] readBufArray = { ByteBuffer.allocate(BUFFER_SIZE),
- ByteBuffer.allocate(BUFFER_SIZE) };
- long totalCount = 0;
- do {
- long count = source.read(readBufArray, 0, 2);
- if (count < 0) {
- break;
- }
- if (0 == count && BUFFER_SIZE == readBufArray[1].position()) {
- // source.read returns 0 because readBufArray is full
- break;
- }
- totalCount += count;
- } while (totalCount != 10);
-
- // assert read result
- for (ByteBuffer readBuf : readBufArray) {
- // RI may fail because of its bug implementation
- assertEquals(BUFFER_SIZE, readBuf.position());
- assertEquals("bytes",
- new String(readBuf.array(), ISO8859_1));
- }
- } finally {
- sink.close();
- source.close();
- }
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_$LByteBufferII_Exception() throws IOException {
-
- ByteBuffer[] nullBufArrayRef = null;
- try {
- source.read(nullBufArrayRef, 0, 1);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- source.read(nullBufArrayRef, 0, -1);
- fail();
- } catch (NullPointerException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- source.read(new ByteBuffer[0], 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- source.read(new ByteBuffer[0], -1, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- // ByteBuffer array contains null element
- ByteBuffer nullBuf = null;
- ByteBuffer[] nullBufArray1 = { nullBuf };
- try {
- source.read(nullBufArray1, 0, 1);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- source.read(nullBufArray1, 0, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- source.read(nullBufArray1, -1, 0);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- source.read(nullBufArray1, -1, 1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
-
- try {
- source.read(nullBufArray1, 1, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- source.read(nullBufArray2, 0, 3);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- source.read(nullBufArray2, 0, 2);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_$LByteBufferII_SinkClosed() throws IOException {
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- ByteBuffer[] readBufArray = { readBuf };
- sink.write(buffer);
- sink.close();
- long count = source.read(readBufArray, 0, 1);
- assertEquals(BUFFER_SIZE, count);
- // readBuf is full, read 0 byte expected
- count = source.read(readBufArray);
- assertEquals(0, count);
- // readBuf is not null, -1 is expected
- readBuf.position(0);
- count = source.read(readBufArray, 0, 1);
- assertEquals(-1, count);
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
- */
- public void test_read_$LByteBufferII_SourceClosed() throws IOException {
- ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
- ByteBuffer[] readBufArray = { readBuf };
- source.close();
- try {
- source.read(readBufArray, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- readBuf.position(BUFFER_SIZE);
- try {
- // readBuf is full
- source.read(readBufArray, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- ByteBuffer[] nullBufArrayRef = null;
- try {
- source.read(nullBufArrayRef, 0, 1);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- source.read(nullBufArrayRef, 0, -1);
- fail();
- } catch (NullPointerException expected) {
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- source.read(new ByteBuffer[0], 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- source.read(new ByteBuffer[0], -1, 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- // ByteBuffer array contains null element
- ByteBuffer nullBuf = null;
- ByteBuffer[] nullBufArray1 = { nullBuf };
- try {
- source.read(nullBufArray1, 0, 1);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- try {
- source.read(nullBufArray1, 0, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- source.read(nullBufArray1, -1, 0);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- try {
- source.read(nullBufArray1, -1, 1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
-
- try {
- source.read(nullBufArray1, 1, -1);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- source.read(nullBufArray2, 0, 3);
- fail("should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- source.read(nullBufArray2, 0, 2);
- fail("should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.channels.Pipe.SourceChannel#close()
- */
- public void test_close() throws IOException {
- sink.close();
- assertFalse(sink.isOpen());
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnixSelectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnixSelectorTest.java
deleted file mode 100644
index 8995394..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnixSelectorTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-
-import junit.framework.TestCase;
-
-public class UnixSelectorTest extends TestCase {
- static class Server {
- ServerSocketChannel serverChannel = ServerSocketChannel.open();
- ServerSocket socket = null;
-
- Server() throws Exception {
- serverChannel.configureBlocking(false);
- }
-
- public void initialize() throws Exception {
- this.socket = serverChannel.socket();
- socket.bind(null);
- }
-
- public void accept() {
- Thread serverThread = new Thread(new Runnable() {
- public void run() {
- try {
- while (serverChannel.accept() == null) {
- Thread.sleep(1000);
- }
- } catch (Exception e) {}
- }
- });
- serverThread.start();
- }
-
- public void close() throws Exception{
- serverChannel.close();
- }
- }
-
- public void testSelectorAcceptAndRead() throws Exception {
- Selector sel0 = Selector.open();
- Selector sel1 = Selector.open();
- Server server = new Server();
- SelectionKey mkey0 = server.serverChannel.register(sel0, SelectionKey.OP_ACCEPT);
- server.serverChannel.register(sel1, SelectionKey.OP_ACCEPT);
-
- // HUP is treating as acceptable
- assertEquals(1, sel0.select(100));
- assertEquals(true, sel0.selectedKeys().contains(mkey0));
- server.initialize();
- // after bind can not accept
- assertEquals(0, sel1.select(100));
- server.accept();
- Thread.sleep(1000);
- SocketChannel socketChannel = SocketChannel.open();
- socketChannel.configureBlocking(false);
- Selector sel2 = Selector.open();
- socketChannel.register(sel2, SelectionKey.OP_WRITE);
- boolean isConnected = socketChannel.connect(server.socket.getLocalSocketAddress());
- if (!isConnected) {
- socketChannel.finishConnect();
- }
-
- assertEquals(true, socketChannel.isConnected());
- server.close();
- Thread.sleep(3000);
- assertEquals(true, socketChannel.isConnected());
- assertEquals(1, sel2.select(100));
- }
-
- public void testSelectUnConnectedChannel() throws Exception {
- SocketChannel socketChannel2 = SocketChannel.open();
- socketChannel2.configureBlocking(false);
- Selector sel3 = Selector.open();
- SelectionKey mkey3 = socketChannel2.register(sel3, SelectionKey.OP_WRITE);
- // HUP is also treating as writable
- assertEquals(1, sel3.select(100));
- assertEquals(false, mkey3.isConnectable());
- // even the channel is not connected, the selector could be writable
- assertEquals(false, socketChannel2.isConnected());
- assertEquals(true, mkey3.isWritable());
-
- Selector sel4 = Selector.open();
- SelectionKey mkey4 = socketChannel2.register(sel4, SelectionKey.OP_CONNECT);
- assertEquals(1, sel4.select(100));
- assertEquals(false, mkey4.isWritable());
- assertEquals(true, mkey4.isConnectable());
-
- Selector sel5 = Selector.open();
- SelectionKey mkey5 = socketChannel2.register(sel5, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE);
- assertEquals(1, sel5.select(100));
- assertEquals(true, mkey5.isWritable());
- assertEquals(true, mkey5.isConnectable());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.java
deleted file mode 100644
index 827dcd7..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.UnresolvedAddressException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for UnresolvedAddressException
- */
-public class UnresolvedAddressExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.UnresolvedAddressException#UnresolvedAddressException()}
- */
- public void test_Constructor() {
- UnresolvedAddressException e = new UnresolvedAddressException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new UnresolvedAddressException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new UnresolvedAddressException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java
deleted file mode 100644
index e032ea4..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.nio.tests.java.nio.channels;
-
-import java.nio.channels.UnsupportedAddressTypeException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Tests for UnsupportedAddressTypeException
- */
-public class UnsupportedAddressTypeExceptionTest extends TestCase {
-
- /**
- * @tests {@link java.nio.channels.UnsupportedAddressTypeException#UnsupportedAddressTypeException()}
- */
- public void test_Constructor() {
- UnsupportedAddressTypeException e = new UnsupportedAddressTypeException();
- assertNull(e.getMessage());
- assertNull(e.getLocalizedMessage());
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new UnsupportedAddressTypeException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this,
- new UnsupportedAddressTypeException());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractInterruptibleChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractInterruptibleChannelTest.java
deleted file mode 100644
index 5072dc9..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractInterruptibleChannelTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels.spi;
-
-import java.io.IOException;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.spi.AbstractInterruptibleChannel;
-
-import junit.framework.TestCase;
-
-public class AbstractInterruptibleChannelTest extends TestCase {
-
- /**
- * @tests AbstractInterruptibleChannel#close()
- */
- public void test_close() throws IOException {
- MockInterruptibleChannel testMiChannel = new MockInterruptibleChannel();
- assertTrue(testMiChannel.isOpen());
- testMiChannel.isImplCloseCalled = false;
- testMiChannel.close();
- assertTrue(testMiChannel.isImplCloseCalled);
- assertFalse(testMiChannel.isOpen());
- }
-
- /**
- * @tests AbstractInterruptibleChannel#begin/end()
- */
- public void test_begin_end() throws IOException {
- boolean complete = false;
- MockInterruptibleChannel testChannel = new MockInterruptibleChannel();
- try {
- testChannel.superBegin();
- complete = true;
- } finally {
- testChannel.superEnd(complete);
- }
-
- try {
- testChannel.superBegin();
- complete = false;
- } finally {
- testChannel.superEnd(complete);
- }
-
- try {
- testChannel.superBegin();
- complete = true;
- } finally {
- testChannel.superEnd(complete);
- }
-
- testChannel.superBegin();
- try {
- testChannel.superBegin();
- complete = true;
- } finally {
- testChannel.superEnd(complete);
- }
- assertTrue(testChannel.isOpen());
- testChannel.close();
- }
-
- /**
- * @tests AbstractInterruptibleChannel#close/begin/end()
- */
- public void test_close_begin_end() throws IOException {
- boolean complete = false;
- MockInterruptibleChannel testChannel = new MockInterruptibleChannel();
- assertTrue(testChannel.isOpen());
- try {
- testChannel.superBegin();
- complete = true;
- } finally {
- testChannel.superEnd(complete);
- }
- assertTrue(testChannel.isOpen());
- testChannel.close();
- try {
- testChannel.superBegin();
- complete = false;
- } finally {
- try {
- testChannel.superEnd(complete);
- fail("should throw AsynchronousCloseException");
- } catch (AsynchronousCloseException e) {
- // expected
- }
- }
- assertFalse(testChannel.isOpen());
- try {
- testChannel.superBegin();
- complete = true;
- } finally {
- testChannel.superEnd(complete);
- }
- assertFalse(testChannel.isOpen());
- }
-
- private class MockInterruptibleChannel extends AbstractInterruptibleChannel {
-
- private boolean isImplCloseCalled = false;
-
- public MockInterruptibleChannel() {
- super();
- }
-
- protected void implCloseChannel() throws IOException {
- isImplCloseCalled = true;
- }
-
- // call super.begin() for test
- void superBegin() {
- super.begin();
- }
-
- // call super.end() for test
- void superEnd(boolean completed) throws AsynchronousCloseException {
- super.end(completed);
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java
deleted file mode 100644
index b396264..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels.spi;
-
-import java.io.IOException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.IllegalBlockingModeException;
-import java.nio.channels.IllegalSelectorException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.spi.AbstractSelectableChannel;
-import java.nio.channels.spi.SelectorProvider;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for AbstractSelectableChannel
- */
-public class AbstractSelectableChannelTest extends TestCase {
-
- private MockSelectableChannel testChannel;
-
- protected void setUp() throws Exception {
- super.setUp();
- testChannel = new MockSelectableChannel(SelectorProvider.provider());
- }
-
- protected void tearDown() throws Exception {
- if (testChannel.isOpen()) {
- testChannel.close();
- }
- }
-
- /**
- * @tests AbstractSelectableChannel#implCloseChannel()
- */
- public void test_implClose() throws IOException {
- testChannel.isImplCloseSelectableChannelCalled = false;
- testChannel.implCloseSelectableChannelCount = 0;
- testChannel.close();
- assertFalse(testChannel.isOpen());
- assertTrue(testChannel.isImplCloseSelectableChannelCalled);
- assertEquals(1, testChannel.implCloseSelectableChannelCount);
-
- testChannel = new MockSelectableChannel(SelectorProvider.provider());
- testChannel.isImplCloseSelectableChannelCalled = false;
- testChannel.implCloseSelectableChannelCount = 0;
- // close twice.
- // make sure implCloseSelectableChannelCount is called only once.
- testChannel.close();
- testChannel.close();
- assertFalse(testChannel.isOpen());
- assertTrue(testChannel.isImplCloseSelectableChannelCalled);
- assertEquals(1, testChannel.implCloseSelectableChannelCount);
- }
-
- /**
- * @tests AbstractSelectableChannel#provider()
- */
- public void test_provider() {
- SelectorProvider provider = testChannel.provider();
- assertSame(SelectorProvider.provider(), provider);
- testChannel = new MockSelectableChannel(null);
- provider = testChannel.provider();
- assertNull(provider);
- }
-
- /**
- * @tests AbstractSelectableChannel#isBlocking()
- */
- public void test_isBlocking() throws IOException {
- assertTrue(testChannel.isBlocking());
- testChannel.configureBlocking(false);
- assertFalse(testChannel.isBlocking());
- testChannel.configureBlocking(true);
- assertTrue(testChannel.isBlocking());
- }
-
- /**
- *
- * @tests AbstractSelectableChannel#blockingLock()
- */
- public void test_blockingLock() {
- Object gotObj = testChannel.blockingLock();
- assertNotNull(gotObj);
- }
-
- /**
- * @tests AbstractSelectableChannel#register(Selector, int, Object)
- */
- public void test_register_LSelectorILObject() throws IOException {
- assertFalse(testChannel.isRegistered());
- Selector acceptSelector1 = SelectorProvider.provider().openSelector();
- Selector acceptSelector2 = new MockAbstractSelector(SelectorProvider
- .provider());
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- SelectionKey acceptKey = sc.register(acceptSelector1,
- SelectionKey.OP_READ, null);
- assertNotNull(acceptKey);
- assertTrue(acceptKey.isValid());
- assertSame(sc, acceptKey.channel());
-
- //test that sc.register invokes Selector.register()
- acceptKey = sc.register(acceptSelector2, SelectionKey.OP_READ, null);
- assertNull(acceptKey);
-
- // Regression test to ensure acceptance of a selector with empty
- // interest set.
- SocketChannel channel = SocketChannel.open();
- channel.configureBlocking(false);
- Selector selector = Selector.open();
- channel.register(selector, 0);
- selector.close();
- channel.close();
- }
-
- /**
- * @tests AbstractSelectableChannel#register(Selector, int, Object)
- */
- public void test_register_LSelectorILObject_IllegalArgument()
- throws IOException {
- Selector acceptSelector = SelectorProvider.provider().openSelector();
- assertTrue(acceptSelector.isOpen());
- MockSelectableChannel msc = new MockSelectableChannel(SelectorProvider
- .provider());
- msc.configureBlocking(false);
- // in nonblocking mode
- try {
- //different SelectionKey with validOps
- msc.register(acceptSelector, SelectionKey.OP_READ, null);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- msc.register(null, 0, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- // in nonblocking mode, if selector closed
- acceptSelector.close();
- try {
- msc.register(acceptSelector, SelectionKey.OP_READ, null);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- msc.register(null, 0, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- msc.register(acceptSelector, 0, null);
- fail("Should throw IllegalSelectorException");
- } catch (IllegalSelectorException e) {
- // expected
- }
-
- acceptSelector = SelectorProvider.provider().openSelector();
- // test in blocking mode
- msc.configureBlocking(true);
- try {
- msc.register(acceptSelector, SelectionKey.OP_READ, null);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- msc.register(null, 0, null);
- fail("Should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- acceptSelector.close();
- // in blocking mode, if selector closed
- try {
- msc.register(acceptSelector, SelectionKey.OP_READ, null);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- msc.register(null, 0, null);
- fail("Should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
-
- // register with an object
- Object argObj = new Object();
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- try {
- sc.register(null, SelectionKey.OP_READ, argObj);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- // if channel closed
- msc.close();
- try {
- msc.register(acceptSelector, SelectionKey.OP_READ, null);
- fail("Should throw ClosedChannelException");
- } catch (ClosedChannelException e) {
- // expected
- }
-
- }
-
- /**
- * @tests AbstractSelectableChannel#keyFor(Selector)
- */
- public void test_keyfor_LSelector() throws Exception {
- SocketChannel sc = SocketChannel.open();
- Object argObj = new Object();
- sc.configureBlocking(false);
- Selector acceptSelector = SelectorProvider.provider().openSelector();
- Selector acceptSelectorOther = SelectorProvider.provider()
- .openSelector();
- SelectionKey acceptKey = sc.register(acceptSelector,
- SelectionKey.OP_READ, argObj);
- assertEquals(sc.keyFor(acceptSelector), acceptKey);
- SelectionKey acceptKeyObjNull = sc.register(acceptSelector,
- SelectionKey.OP_READ, null);
- assertSame(sc.keyFor(acceptSelector), acceptKeyObjNull);
- assertSame(acceptKeyObjNull, acceptKey);
- SelectionKey acceptKeyOther = sc.register(acceptSelectorOther,
- SelectionKey.OP_READ, null);
- assertSame(sc.keyFor(acceptSelectorOther), acceptKeyOther);
- }
-
- /**
- * @tests AbstractSelectableChannel#configureBlocking(boolean)
- */
- public void test_configureBlocking_Z_IllegalBlockingMode() throws Exception {
- SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false);
- Selector acceptSelector = SelectorProvider.provider().openSelector();
- SelectionKey acceptKey = sc.register(acceptSelector,
- SelectionKey.OP_READ, null);
- assertEquals(sc.keyFor(acceptSelector), acceptKey);
- SelectableChannel getChannel = sc.configureBlocking(false);
- assertEquals(getChannel, sc);
- try {
- sc.configureBlocking(true);
- fail("Should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- }
-
- /**
- * @tests AbstractSelectableChannel#configureBlocking(boolean)
- */
- public void test_configureBlocking_Z() throws Exception {
- MockSelectableChannel mock = new MockSelectableChannel(SelectorProvider
- .provider());
- //default blocking mode is true
- //the implConfigureBlocking is only invoked if the given mode is different with current one
- mock.configureBlocking(true);
- assertFalse(mock.implConfigureBlockingCalled);
- mock.configureBlocking(false);
- assertTrue(mock.implConfigureBlockingCalled);
- }
-
- private class MockSelectableChannel extends AbstractSelectableChannel {
-
- private boolean isImplCloseSelectableChannelCalled = false;
-
- private int implCloseSelectableChannelCount = 0;
-
- private boolean implConfigureBlockingCalled = false;
-
- public MockSelectableChannel(SelectorProvider arg0) {
- super(arg0);
- }
-
- protected void implCloseSelectableChannel() throws IOException {
- isImplCloseSelectableChannelCalled = true;
- ++implCloseSelectableChannelCount;
- }
-
- protected void implConfigureBlocking(boolean arg0) throws IOException {
- implConfigureBlockingCalled = true;
- }
-
- public int validOps() {
- return SelectionKey.OP_ACCEPT;
- }
-
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectionKeyTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectionKeyTest.java
deleted file mode 100644
index 1404fc1..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectionKeyTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels.spi;
-
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.spi.AbstractSelectionKey;
-
-import junit.framework.TestCase;
-
-public class AbstractSelectionKeyTest extends TestCase {
-
- /**
- * @tests AbstractSelectionKey#isValid() without selector
- */
- public void test_isValid() throws Exception {
- MockSelectionKey testKey = new MockSelectionKey();
- assertTrue(testKey.isValid());
- }
-
- /**
- * @tests AbstractSelectionKey#cancel
- */
- public void test_cancel() throws Exception {
- MockSelectionKey testKey = new MockSelectionKey();
- try {
- testKey.cancel();
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected: no selector available
- }
- assertFalse(testKey.isValid());
- }
-
- private class MockSelectionKey extends AbstractSelectionKey {
-
- MockSelectionKey() {
- super();
- }
-
- public SelectableChannel channel() {
- return null;
- }
-
- public Selector selector() {
- return null;
- }
-
- public int interestOps() {
- return 0;
- }
-
- public SelectionKey interestOps(int arg0) {
- return null;
- }
-
- public int readyOps() {
- return 0;
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectorTest.java
deleted file mode 100644
index 4b39001..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectorTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels.spi;
-
-import java.io.IOException;
-import java.nio.channels.IllegalBlockingModeException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.spi.SelectorProvider;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for AbstractSelector and register of its default implementation
- */
-public class AbstractSelectorTest extends TestCase {
-
- /**
- * @tests AbstractSelector#provider()
- */
- public void test_provider() throws IOException {
- Selector mockSelector = new MockAbstractSelector(SelectorProvider
- .provider());
- assertTrue(mockSelector.isOpen());
- assertSame(SelectorProvider.provider(), mockSelector.provider());
- mockSelector = new MockAbstractSelector(null);
- assertNull(mockSelector.provider());
- }
-
- /**
- * @tests AbstractSelector#close()
- */
- public void test_close() throws IOException {
- MockAbstractSelector mockSelector = new MockAbstractSelector(
- SelectorProvider.provider());
- mockSelector.close();
- assertTrue(mockSelector.isImplCloseSelectorCalled);
- }
-
- /**
- *
- * @tests AbstractSelector#begin/end()
- */
- public void test_begin_end() throws IOException {
- MockAbstractSelector mockSelector = new MockAbstractSelector(
- SelectorProvider.provider());
- try {
- mockSelector.superBegin();
- } finally {
- mockSelector.superEnd();
- }
-
- mockSelector = new MockAbstractSelector(SelectorProvider.provider());
- try {
- mockSelector.superBegin();
- mockSelector.close();
- } finally {
- mockSelector.superEnd();
- }
-
- try {
- // begin twice
- mockSelector.superBegin();
- mockSelector.superBegin();
- } finally {
- mockSelector.superEnd();
- }
-
- try {
- mockSelector.superBegin();
- } finally {
- // end twice
- mockSelector.superEnd();
- mockSelector.superEnd();
- }
-
- mockSelector.close();
- try {
- mockSelector.superBegin();
- } finally {
- mockSelector.superEnd();
- }
- }
-
- /**
- * @tests AbstractSelector#isOpen()
- */
- public void test_isOpen() throws Exception {
- Selector acceptSelector = SelectorProvider.provider().openSelector();
- assertTrue(acceptSelector.isOpen());
- acceptSelector.close();
- assertFalse(acceptSelector.isOpen());
- }
-
- /**
- * @tests AbstractSelector#register(Selector,int)
- */
- public void test_register_LSelectorI() throws Exception {
- Selector acceptSelector = SelectorProvider.provider().openSelector();
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.configureBlocking(false);
-
- assertFalse(ssc.isRegistered());
- SelectionKey acceptKey = ssc.register(acceptSelector,
- SelectionKey.OP_ACCEPT);
- assertTrue(ssc.isRegistered());
- assertNotNull(acceptKey);
- assertTrue(acceptSelector.keys().contains(acceptKey));
- }
-
- /**
- * @tests AbstractSelector#register(Selector,int)
- */
- public void test_register_LSelectorI_error() throws IOException {
- Selector acceptSelector = SelectorProvider.provider().openSelector();
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.configureBlocking(false);
- acceptSelector.close();
-
- assertFalse(acceptSelector.isOpen());
- try {
- ssc.register(acceptSelector, SelectionKey.OP_ACCEPT);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- assertFalse(ssc.isRegistered());
-
- acceptSelector = Selector.open();
- ssc.configureBlocking(true);
- try {
- ssc.register(acceptSelector, SelectionKey.OP_ACCEPT);
- fail("should throw IllegalBlockingModeException");
- } catch (IllegalBlockingModeException e) {
- // expected
- }
- assertFalse(ssc.isRegistered());
- ssc.configureBlocking(false);
- SelectionKey acceptKey = ssc.register(acceptSelector,
- SelectionKey.OP_ACCEPT);
- assertNotNull(acceptKey);
- assertTrue(acceptSelector.keys().contains(acceptKey));
- assertTrue(ssc.isRegistered());
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/MockAbstractSelector.java b/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/MockAbstractSelector.java
deleted file mode 100644
index 6e016b0..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/MockAbstractSelector.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio.tests.java.nio.channels.spi;
-
-import java.io.IOException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.spi.AbstractSelectableChannel;
-import java.nio.channels.spi.AbstractSelectionKey;
-import java.nio.channels.spi.AbstractSelector;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.Set;
-
-public class MockAbstractSelector extends AbstractSelector {
-
- public boolean isImplCloseSelectorCalled = false;
-
- public MockAbstractSelector(SelectorProvider arg0) {
- super(arg0);
- }
-
- public static MockAbstractSelector openSelector() {
- return new MockAbstractSelector(SelectorProvider.provider());
- }
-
- public Set getCancelledKeys() {
- return super.cancelledKeys();
- }
-
- protected void implCloseSelector() throws IOException {
- isImplCloseSelectorCalled = true;
- }
-
- protected SelectionKey register(AbstractSelectableChannel arg0, int arg1,
- Object arg2) {
- return null;
- }
-
- public void superBegin() {
- super.begin();
- }
-
- public void superEnd() {
- super.end();
- }
-
- protected void mockDeregister(AbstractSelectionKey key) {
- super.deregister(key);
- }
-
- public Set<SelectionKey> keys() {
- return null;
- }
-
- public Set<SelectionKey> selectedKeys() {
- return null;
- }
-
- public int selectNow() throws IOException {
- return 0;
- }
-
- public int select(long arg0) throws IOException {
- return 0;
- }
-
- public int select() throws IOException {
- return 0;
- }
-
- public Selector wakeup() {
- return null;
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/ASCIICharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/ASCIICharsetEncoderTest.java
deleted file mode 100644
index a85576c..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/ASCIICharsetEncoderTest.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.MalformedInputException;
-import java.nio.charset.UnmappableCharacterException;
-
-import junit.framework.TestCase;
-
-public class ASCIICharsetEncoderTest extends TestCase {
-
- // charset for ascii
- private static final Charset cs = Charset.forName("ascii");
- private static final CharsetEncoder encoder = cs.newEncoder();
- private static final int MAXCODEPOINT = 0x7F;
- /*
- * @see CharsetEncoderTest#setUp()
- */
- protected void setUp() throws Exception {
- }
-
- /*
- * @see CharsetEncoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- }
-
- public void testCanEncodeCharSequence() {
- // normal case for ascCS
- assertTrue(encoder.canEncode("\u0077"));
- assertFalse(encoder.canEncode("\uc2a3"));
- assertFalse(encoder.canEncode("\ud800\udc00"));
- try {
- encoder.canEncode(null);
- } catch (NullPointerException e) {
- }
- assertTrue(encoder.canEncode(""));
- }
-
- public void testCanEncodeSurrogate () {
- assertFalse(encoder.canEncode('\ud800'));
- assertFalse(encoder.canEncode("\udc00"));
- }
-
- public void testCanEncodechar() throws CharacterCodingException {
- assertTrue(encoder.canEncode('\u0077'));
- assertFalse(encoder.canEncode('\uc2a3'));
- }
-
- public void testSpecificDefaultValue() {
- assertEquals(1.0, encoder.averageBytesPerChar(), 0.0);
- assertEquals(1.0, encoder.maxBytesPerChar(), 0.0);
- }
-
- public void testMultiStepEncode() throws CharacterCodingException {
- encoder.onMalformedInput(CodingErrorAction.REPORT);
- encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- try {
- encoder.encode(CharBuffer.wrap("\ud800\udc00"));
- fail("should unmappable");
- } catch (UnmappableCharacterException e) {
- }
- encoder.reset();
- ByteBuffer out = ByteBuffer.allocate(10);
- assertTrue(encoder.encode(CharBuffer.wrap("\ud800"), out, true)
- .isMalformed());
- encoder.flush(out);
- encoder.reset();
- out = ByteBuffer.allocate(10);
- assertSame(CoderResult.UNDERFLOW, encoder.encode(CharBuffer
- .wrap("\ud800"), out, false));
- assertTrue(encoder.encode(CharBuffer.wrap("\udc00"), out, true)
- .isMalformed());
- }
-
- public void testEncodeMapping() throws CharacterCodingException {
- encoder.reset();
-
- for (int i =0; i <= MAXCODEPOINT; i++) {
- char[] chars = Character.toChars(i);
- CharBuffer cb = CharBuffer.wrap(chars);
- ByteBuffer bb = encoder.encode(cb);
- assertEquals(i, bb.get(0));
- }
-
- CharBuffer cb = CharBuffer.wrap("\u0080");
- try {
- encoder.encode(cb);
- } catch (UnmappableCharacterException e) {
- //expected
- }
-
- cb = CharBuffer.wrap("\ud800");
- try {
- encoder.encode(cb);
- } catch (MalformedInputException e) {
- //expected
- }
-
- ByteBuffer bb = ByteBuffer.allocate(0x10);
- cb = CharBuffer.wrap("A");
- encoder.reset();
- encoder.encode(cb, bb, false);
- try {
- encoder.encode(cb);
- } catch (IllegalStateException e) {
- //expected
- }
- }
-
- public void testInternalState() {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
-
- //normal encoding process
- encoder.reset();
- encoder.encode(in, out, false);
- in = CharBuffer.wrap("B");
- encoder.encode(in, out, true);
- encoder.flush(out);
- }
-
- //reset could be called at any time
- public void testInternalState_Reset() {
- CharsetEncoder newEncoder = cs.newEncoder();
- //Init - > reset
- newEncoder.reset();
-
- //reset - > reset
- newEncoder.reset();
-
- //encoding - >reset
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, false);
- newEncoder.reset();
- }
-
- //encoding end -> reset
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- newEncoder.reset();
- }
- //flused -> reset
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- newEncoder.flush(out);
- newEncoder.reset();
- }
- }
-
- public void testInternalState_Encoding() {
- CharsetEncoder newEncoder = cs.newEncoder();
- //Init - > encoding
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, false);
- }
-
- //reset - > encoding
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.reset();
- newEncoder.encode(in, out, false);
- }
- //reset - > encoding - > encoding
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, false);
- in = CharBuffer.wrap("BC");
- newEncoder.encode(in, out, false);
- }
-
- //encoding_end - > encoding
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- in = CharBuffer.wrap("BC");
- try {
- newEncoder.encode(in, out, false);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- //expected
- }
- }
- //flushed - > encoding
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- newEncoder.flush(out);
- in = CharBuffer.wrap("BC");
- try {
- newEncoder.encode(in, out, false);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- //expected
- }
- }
- }
-
- public void testInternalState_Encoding_END() {
- CharsetEncoder newEncoder = cs.newEncoder();
-
- //Init - >encoding_end
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- }
-
- //Reset -> encoding_end
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.reset();
- newEncoder.encode(in, out, true);
- }
-
- //encoding -> encoding_end
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, false);
- in = CharBuffer.wrap("BC");
- newEncoder.encode(in, out, true);
- }
-
- //Reset -> encoding_end
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- in = CharBuffer.wrap("BC");
- newEncoder.encode(in, out, true);
- }
-
- //Flushed -> encoding_end
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- newEncoder.flush(out);
- in = CharBuffer.wrap("BC");
- try {
- newEncoder.encode(in, out, true);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- //expected
- }
- }
- }
-
- public void testInternalState_Flushed() {
- CharsetEncoder newEncoder = cs.newEncoder();
-
- // init -> flushed
- {
- ByteBuffer out = ByteBuffer.allocate(0x10);
- try {
- newEncoder.flush(out);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- //expected
- }
-
- }
-
- // reset - > flushed
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- newEncoder.reset();
- try {
- newEncoder.flush(out);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- //expected
- }
- }
-
- //encoding - > flushed
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, false);
- try {
-
- newEncoder.flush(out);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // expected
- }
- }
-
- //encoding_end -> flushed
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- newEncoder.flush(out);
- }
-
- //flushd - > flushed
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- newEncoder.flush(out);
- newEncoder.flush(out);
- }
- }
-
- public void testInternalState_Encode() throws CharacterCodingException {
- CharsetEncoder newEncoder = cs.newEncoder();
- //Init - > encode
- {
- CharBuffer in = CharBuffer.wrap("A");
- newEncoder.encode(in);
- }
-
- //Reset - > encode
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- newEncoder.encode(in);
- }
-
- //Encoding -> encode
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, false);
- in = CharBuffer.wrap("BC");
- newEncoder.encode(in);
- }
-
- //Encoding_end -> encode
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- in = CharBuffer.wrap("BC");
- newEncoder.encode(in);
- }
-
- //Flushed -> reset
- {
- newEncoder.reset();
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.encode(in, out, true);
- in = CharBuffer.wrap("BC");
- newEncoder.flush(out);
- out = newEncoder.encode(in);
- }
- }
-
- public void testInternalState_from_Encode() throws CharacterCodingException {
- CharsetEncoder newEncoder = cs.newEncoder();
-
- //Encode -> Reset
- {
- CharBuffer in = CharBuffer.wrap("A");
- newEncoder.encode(in);
- newEncoder.reset();
- }
-
- // Encode -> encoding
- {
- CharBuffer in = CharBuffer.wrap("A");
- newEncoder.encode(in);
- ByteBuffer out = ByteBuffer.allocate(0x10);
- try {
- newEncoder.encode(in, out, false);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // expected
- }
- }
-
- //Encode -> Encoding_end
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = ByteBuffer.allocate(0x10);
- newEncoder.reset();
- newEncoder.encode(in, out, false);
- newEncoder.encode(in, out, true);
- }
-
- //Encode -> Flushed
- {
- CharBuffer in = CharBuffer.wrap("A");
- ByteBuffer out = newEncoder.encode(in);
- newEncoder.flush(out);
- }
-
- //Encode - > encode
- {
- CharBuffer in = CharBuffer.wrap("A");
- newEncoder.encode(in);
- in = CharBuffer.wrap("BC");
- newEncoder.encode(in);
- }
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharacterCodingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharacterCodingExceptionTest.java
deleted file mode 100644
index a45938f..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharacterCodingExceptionTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.io.IOException;
-import java.nio.charset.CharacterCodingException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Test CharacterCodingException
- */
-public class CharacterCodingExceptionTest extends TestCase {
-
- public void testConstructor() {
- CharacterCodingException ex = new CharacterCodingException();
- assertTrue(ex instanceof IOException);
- assertNull(ex.getCause());
- assertNull(ex.getMessage());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new CharacterCodingException());
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
- SerializationTest.verifyGolden(this, new CharacterCodingException());
-
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java
deleted file mode 100644
index 1a7b984..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.io.IOException;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderMalfunctionError;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.MalformedInputException;
-import java.util.Arrays;
-
-import junit.framework.TestCase;
-
-public class CharsetDecoderTest extends TestCase {
-
- /**
- * @tests java.nio.charset.CharsetDecoder.CharsetDecoder(Charset, float,
- * float)
- */
- public void test_ConstructorLjava_nio_charset_CharsetFF() {
- // Regression for HARMONY-142
- try {
- Charset cs = Charset.forName("UTF-8"); //$NON-NLS-1$
- new MockCharsetDecoderForHarmony142(cs, 1.1f, 1);
- fail("Assert 0: Should throw IllegalArgumentException."); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /*
- * MockCharsetDecoderForHarmony142: for constructor test
- */
- static class MockCharsetDecoderForHarmony142 extends CharsetDecoder {
- protected MockCharsetDecoderForHarmony142(Charset cs,
- float averageBytesPerChar, float maxBytesPerChar) {
- super(cs, averageBytesPerChar, maxBytesPerChar);
- }
-
- protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
- return null;
- }
- }
-
- /**
- * @tests java.nio.charset.CharsetDecoder#decode(java.nio.ByteBuffer)
- */
- public void test_decode() throws CharacterCodingException {
- // Regression for HARMONY-33
-// ByteBuffer bb = ByteBuffer.allocate(1);
-// bb.put(0, (byte) 77);
-// CharsetDecoder decoder = Charset.forName("UTF-16").newDecoder();
-// decoder.onMalformedInput(CodingErrorAction.REPLACE);
-// decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
-// decoder.decode(bb);
-
- // Regression for HARMONY-67
-// byte[] b = new byte[] { (byte) 1 };
-// ByteBuffer buf = ByteBuffer.wrap(b);
-// CharBuffer charbuf = Charset.forName("UTF-16").decode(buf);
-// assertEquals("Assert 0: charset UTF-16", 1, charbuf.length());
-//
-// charbuf = Charset.forName("UTF-16BE").decode(buf);
-// assertEquals("Assert 1: charset UTF-16BE", 0, charbuf.length());
-//
-// charbuf = Charset.forName("UTF-16LE").decode(buf);
-// assertEquals("Assert 2: charset UTF16LE", 0, charbuf.length());
-
- // Regression for HARMONY-99
- CharsetDecoder decoder2 = Charset.forName("UTF-16").newDecoder();
- decoder2.onMalformedInput(CodingErrorAction.REPORT);
- decoder2.onUnmappableCharacter(CodingErrorAction.REPORT);
- ByteBuffer in = ByteBuffer.wrap(new byte[] { 109, 97, 109 });
- try {
- decoder2.decode(in);
- fail("Assert 3: MalformedInputException should have thrown");
- } catch (MalformedInputException e) {
- //expected
- }
- }
-
- /*
- * Test malfunction decode(ByteBuffer)
- */
- public void test_decodeLjava_nio_ByteBuffer() throws Exception {
- MockMalfunctionCharset cs1 = new MockMalfunctionCharset(
- "Harmony-124-1", null); //$NON-NLS-1$
- try {
- cs1.newDecoder().onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(CodingErrorAction.REPLACE).decode(
- ByteBuffer.wrap(new byte[] { 0x00, 0x11 }));
- fail("Assert 0: should throw CoderMalfunctionError"); // NON-NLS-1$
- } catch (CoderMalfunctionError e) {
- // expected
- }
-
- MockMalfunctionCharset cs2 = new MockMalfunctionCharset(
- "Harmony-124-2", null); //$NON-NLS-1$
- try {
- cs2.decode(ByteBuffer.wrap(new byte[] { 0x00, 0x11 }));
- fail("Assert 1: Charset.decode should throw CoderMalfunctionError"); // NON-NLS-1
- } catch (CoderMalfunctionError e) {
- // expected
- }
- }
-
- /*
- * Mock charset class with malfunction decode & encode.
- */
- static final class MockMalfunctionCharset extends Charset {
-
- public MockMalfunctionCharset(String canonicalName, String[] aliases) {
- super(canonicalName, aliases);
- }
-
- public boolean contains(Charset cs) {
- return false;
- }
-
- public CharsetDecoder newDecoder() {
- return new MockMalfunctionDecoder(this);
- }
-
- public CharsetEncoder newEncoder() {
- return new MockMalfunctionEncoder(this);
- }
- }
-
- /*
- * Mock decoder. decodeLoop always throws unexpected exception.
- */
- static class MockMalfunctionDecoder extends java.nio.charset.CharsetDecoder {
-
- public MockMalfunctionDecoder(Charset cs) {
- super(cs, 1, 10);
- }
-
- protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
- throw new BufferOverflowException();
- }
- }
-
- /*
- * Mock encoder. encodeLoop always throws unexpected exception.
- */
- static class MockMalfunctionEncoder extends java.nio.charset.CharsetEncoder {
-
- public MockMalfunctionEncoder(Charset cs) {
- super(cs, 1, 3, new byte[] { (byte) '?' });
- }
-
- protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
- throw new BufferOverflowException();
- }
- }
-
- /*
- * Test the method decode(ByteBuffer) .
- */
- public void testDecodeLjava_nio_ByteBuffer_ReplaceOverflow()
- throws Exception {
- String replaceString = "a";
- Charset cs = Charset.forName("UTF-8");
- MockMalformedDecoder decoder = new MockMalformedDecoder(cs);
- decoder.onMalformedInput(CodingErrorAction.REPLACE);
- decoder.replaceWith(replaceString);
- CharBuffer out = CharBuffer.allocate(1);
- // MockMalformedDecoder treats the second byte '0x38' as malformed,
- // but "out" doesn't have enough space for replace string.
- ByteBuffer in = ByteBuffer.wrap(new byte[] { 0x45, 0x38, 0x45, 0x45 });
- CoderResult result = decoder.decode(in, out, false);
- assertTrue(result.isOverflow());
-
- // allocate enough space for "out"
- out = CharBuffer.allocate(10);
- // replace string should be put into "out" firstly,
- // and then decode "in".
- result = decoder.decode(in, out, true);
- out.flip();
- assertTrue(result.isUnderflow());
- assertEquals("bb", out.toString());
- }
-
- /*
- * Mock decoder. It treats byte whose value is less than "0x40" as
- * malformed.
- */
- static class MockMalformedDecoder extends java.nio.charset.CharsetDecoder {
-
- public MockMalformedDecoder(Charset cs) {
- super(cs, 1, 10);
- }
-
- /*
- * It treats byte whose value is less than "0x40" as malformed.
- * Otherwise, it's decoded as 'b'.
- */
- protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
- while (in.hasRemaining()) {
- byte b = in.get();
- if (b < 0x40) {
- return CoderResult.malformedForLength(1);
- }
- if (!out.hasRemaining()) {
- return CoderResult.OVERFLOW;
- }
- out.put((char) 'b');
- }
- return CoderResult.UNDERFLOW;
- }
- }
-
-
- public void testInvalidDecoding() throws IOException {
-
- byte[][] invalidSequences = new byte[][] {
- // overlong NULL
- { (byte) 0xC0, (byte) 0x80 },
- // overlong ascii 'A'
- { (byte) 0xC0, (byte) 0xC1 },
- // overlong "/../"
- { (byte) 0x2F, (byte) 0xC0, (byte) 0xAE, (byte) 0x2E, (byte) 0x2F },
- // Invalid encoding 2r11111000 (sequence too long)
- { (byte) 0xF8 },
- // Invalid encoding 2r10000000 (sequence too short)
- { (byte) 0x80 }
- };
-
- CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
- decoder.onMalformedInput(CodingErrorAction.REPORT);
- decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
-
- /*
- * When bytebuffer has a backing array...
- */
- for (byte[] bytes : invalidSequences) {
- try {
- CharBuffer cb = decoder.decode(ByteBuffer.wrap(bytes));
- fail("No exception thrown on " + Arrays.toString(bytes) + " '" + cb + "'");
- } catch (MalformedInputException expected) {
- }
- }
-
- /*
- * When bytebuffer has _not_ got a backing array...
- */
- for (byte[] bytes : invalidSequences) {
- try {
- ByteBuffer bb = ByteBuffer.allocateDirect(8);
- bb.put(bytes).flip();
- CharBuffer cb = decoder.decode(bb);
- fail("No exception thrown on " + Arrays.toString(bytes) + " '" + cb + "'");
- } catch (MalformedInputException expected) {
- }
- }
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetEncoderTest.java
deleted file mode 100644
index c3f1a8d..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetEncoderTest.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.io.IOException;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderMalfunctionError;
-import java.nio.charset.CoderResult;
-
-import junit.framework.TestCase;
-
-public class CharsetEncoderTest extends TestCase {
-
- /**
- * @tests java.nio.charset.CharsetEncoder.CharsetEncoder(
- * java.nio.charset.Charset, float, float)
- */
- public void test_ConstructorLjava_nio_charset_CharsetFF() {
- // Regression for HARMONY-141
- try {
- Charset cs = Charset.forName("UTF-8"); //$NON-NLS-1$
- new MockCharsetEncoderForHarmony141(cs, 1.1f, 1);
- fail("Assert 0: Should throw IllegalArgumentException."); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- Charset cs = Charset.forName("ISO8859-1"); //$NON-NLS-1$
- new MockCharsetEncoderForHarmony141(cs, 1.1f, 1,
- new byte[] { 0x1a });
- fail("Assert 1: Should throw IllegalArgumentException."); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * @tests java.nio.charset.CharsetEncoder.CharsetEncoder(
- * java.nio.charset.Charset, float, float)
- */
- public void test_ConstructorLjava_nio_charset_CharsetNull() {
- // Regression for HARMONY-491
- CharsetEncoder ech = new MockCharsetEncoderForHarmony491(null, 1, 1);
- assertNull(ech.charset());
- }
-
- /**
- * Helper for constructor tests
- */
-
- public static class MockCharsetEncoderForHarmony141 extends CharsetEncoder {
-
- protected MockCharsetEncoderForHarmony141(Charset cs,
- float averageBytesPerChar, float maxBytesPerChar) {
- super(cs, averageBytesPerChar, maxBytesPerChar);
- }
-
- public MockCharsetEncoderForHarmony141(Charset cs,
- float averageBytesPerChar, float maxBytesPerChar,
- byte[] replacement) {
- super(cs, averageBytesPerChar, maxBytesPerChar, replacement);
- }
-
- protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
- return null;
- }
- }
-
- public static class MockCharsetEncoderForHarmony491 extends CharsetEncoder {
-
- public MockCharsetEncoderForHarmony491(Charset arg0, float arg1,
- float arg2) {
- super(arg0, arg1, arg2);
- }
-
- protected CoderResult encodeLoop(CharBuffer arg0, ByteBuffer arg1) {
- return null;
- }
-
- public boolean isLegalReplacement(byte[] arg0) {
- return true;
- }
- }
-
- /*
- * Test malfunction encode(CharBuffer)
- */
- public void test_EncodeLjava_nio_CharBuffer() throws Exception {
- MockMalfunctionCharset cs = new MockMalfunctionCharset("mock", null);
- try {
- cs.encode(CharBuffer.wrap("AB"));
- fail("should throw CoderMalfunctionError");// NON-NLS-1$
- } catch (CoderMalfunctionError e) {
- // expected
- }
- }
-
- /*
- * Mock charset class with malfunction decode & encode.
- */
- static final class MockMalfunctionCharset extends Charset {
-
- public MockMalfunctionCharset(String canonicalName, String[] aliases) {
- super(canonicalName, aliases);
- }
-
- public boolean contains(Charset cs) {
- return false;
- }
-
- public CharsetDecoder newDecoder() {
- return Charset.forName("UTF-8").newDecoder();
- }
-
- public CharsetEncoder newEncoder() {
- return new MockMalfunctionEncoder(this);
- }
- }
-
- /*
- * Mock encoder. encodeLoop always throws unexpected exception.
- */
- static class MockMalfunctionEncoder extends java.nio.charset.CharsetEncoder {
-
- public MockMalfunctionEncoder(Charset cs) {
- super(cs, 1, 3, new byte[] { (byte) '?' });
- }
-
- protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
- throw new BufferOverflowException();
- }
- }
-
- /*
- * Test reserve bytes encode(CharBuffer,ByteBuffer,boolean)
- */
- public void test_EncodeLjava_nio_CharBufferLjava_nio_ByteBufferB() throws Exception {
- Charset utf8 = Charset.forName("utf-8");
- CharsetEncoder encoder = utf8.newEncoder();
- CharBuffer char1 = CharBuffer.wrap("\ud800");
- CharBuffer char2 = CharBuffer.wrap("\udc00");
- ByteBuffer bytes = ByteBuffer.allocate(4);
- encoder.reset();
-
- // If we supply just the high surrogate...
- CoderResult result = encoder.encode(char1, bytes, false);
- // ...we're not done...
- assertTrue(result.isUnderflow());
- assertEquals(4, bytes.remaining());
- // ...but if we then supply the low surrogate...
- result = encoder.encode(char2, bytes, true);
- assertTrue(result.isUnderflow());
- // ...we're done. Note that the RI loses its state in
- // between the two characters, so it can't do this.
- assertEquals(0, bytes.remaining());
-
- // Did we get the UTF-8 for U+10000?
- assertEquals(4, bytes.limit());
- assertEquals((byte) 0xf0, bytes.get(0));
- assertEquals((byte) 0x90, bytes.get(1));
- assertEquals((byte) 0x80, bytes.get(2));
- assertEquals((byte) 0x80, bytes.get(3));
-
- // See what we got in the output buffer by decoding and checking that we
- // get back the same surrogate pair.
- bytes.flip();
- CharBuffer chars = utf8.newDecoder().decode(bytes);
- assertEquals(0, bytes.remaining());
- assertEquals(2, chars.limit());
- assertEquals(0xd800, chars.get(0));
- assertEquals(0xdc00, chars.get(1));
- }
-
- /**
- * @tests {@link java.nio.charset.Charset#encode(java.nio.CharBuffer)
- */
- public void testUtf8Encoding() throws IOException {
- byte[] orig = new byte[] { (byte) 0xed, (byte) 0xa0,
- (byte) 0x80 };
- String s = new String(orig, "UTF-8");
- assertEquals(1, s.length());
- assertEquals(55296, s.charAt(0));
- Charset.forName("UTF-8").encode(CharBuffer.wrap(s));
-// ByteBuffer buf = <result>
-// for (byte o : orig) {
-// byte b = 0;
-// buf.get(b);
-// assertEquals(o, b);
-// }
- }
-
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CoderMalfunctionErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CoderMalfunctionErrorTest.java
deleted file mode 100644
index 8e6318f..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CoderMalfunctionErrorTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.nio.charset.CoderMalfunctionError;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-/**
- * Test java.nio.CoderMalfunctionError.
- */
-public class CoderMalfunctionErrorTest extends TestCase {
-
- /*
- * Test constructor with normal param.
- */
- public void testConstructor_Normal() {
- Exception ex = new Exception();
- CoderMalfunctionError e = new CoderMalfunctionError(ex);
- assertSame(ex, e.getCause());
- }
-
- /*
- * Test constructor with null param.
- */
- public void testConstructor_Null() {
- CoderMalfunctionError e = new CoderMalfunctionError(null);
- assertNull(e.getCause());
- }
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new CoderMalfunctionError(null));
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
- SerializationTest.verifyGolden(this, new CoderMalfunctionError(null));
-
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/IllegalCharsetNameExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/IllegalCharsetNameExceptionTest.java
deleted file mode 100644
index a514aef..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/IllegalCharsetNameExceptionTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.io.Serializable;
-import java.nio.charset.IllegalCharsetNameException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
-
-/**
- * Test class IllegalCharsetNameException.
- */
-public class IllegalCharsetNameExceptionTest extends TestCase {
-
- public void testConstructor() {
- IllegalCharsetNameException ex = new IllegalCharsetNameException(
- "impossible");
- assertTrue(ex instanceof IllegalArgumentException);
- assertNull(ex.getCause());
- assertEquals(ex.getCharsetName(), "impossible");
- assertTrue(ex.getMessage().indexOf("impossible") != -1);
-
- ex = new IllegalCharsetNameException("ascii");
- assertNull(ex.getCause());
- assertEquals(ex.getCharsetName(), "ascii");
- assertTrue(ex.getMessage().indexOf("ascii") != -1);
-
- ex = new IllegalCharsetNameException("");
- assertNull(ex.getCause());
- assertEquals(ex.getCharsetName(), "");
- ex.getMessage();
-
- ex = new IllegalCharsetNameException(null);
- assertNull(ex.getCause());
- assertNull(ex.getCharsetName());
- assertTrue(ex.getMessage().indexOf("null") != -1);
-
- }
-
- // comparator for IllegalCharsetNameException objects
- private static final SerializableAssert COMPARATOR = new SerializableAssert() {
- public void assertDeserialized(Serializable initial,
- Serializable deserialized) {
-
- // FIXME?: getMessage() returns more helpful string but
- // this leads to incompatible message in serial form
- //
- // do common checks for all throwable objects
- // SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
- // deserialized);
-
- IllegalCharsetNameException initEx = (IllegalCharsetNameException) initial;
- IllegalCharsetNameException desrEx = (IllegalCharsetNameException) deserialized;
-
- assertEquals("CharsetName", initEx.getCharsetName(), desrEx
- .getCharsetName());
- }
- };
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new IllegalCharsetNameException(
- "charsetName"), COMPARATOR);
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new IllegalCharsetNameException(
- "charsetName"), COMPARATOR);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/MalformedInputExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/MalformedInputExceptionTest.java
deleted file mode 100644
index f482d9d..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/MalformedInputExceptionTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.io.Serializable;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.MalformedInputException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
-
-/**
- * Test class MalformedInputException.
- */
-public class MalformedInputExceptionTest extends TestCase {
-
- public void testConstructor() {
- MalformedInputException ex = new MalformedInputException(3);
- assertTrue(ex instanceof CharacterCodingException);
- assertNull(ex.getCause());
- assertEquals(ex.getInputLength(), 3);
- assertTrue(ex.getMessage().indexOf("3") != -1);
-
- ex = new MalformedInputException(-3);
- assertNull(ex.getCause());
- assertEquals(ex.getInputLength(), -3);
- assertTrue(ex.getMessage().indexOf("-3") != -1);
-
- ex = new MalformedInputException(0);
- assertNull(ex.getCause());
- assertEquals(ex.getInputLength(), 0);
- assertTrue(ex.getMessage().indexOf("0") != -1);
- }
-
- // comparator for MalformedInputException objects
- private static final SerializableAssert COMPARATOR = new SerializableAssert() {
- public void assertDeserialized(Serializable initial,
- Serializable deserialized) {
-
- // do common checks for all throwable objects
- SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
- deserialized);
-
- MalformedInputException initEx = (MalformedInputException) initial;
- MalformedInputException desrEx = (MalformedInputException) deserialized;
-
- assertEquals("InputLength", initEx.getInputLength(), desrEx
- .getInputLength());
- }
- };
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new MalformedInputException(11),
- COMPARATOR);
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new MalformedInputException(11),
- COMPARATOR);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/UnmappableCharacterExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/UnmappableCharacterExceptionTest.java
deleted file mode 100644
index a6cf6a6..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/UnmappableCharacterExceptionTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.io.Serializable;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.UnmappableCharacterException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
-
-/**
- * Test class UnmappableCharacterException.
- */
-public class UnmappableCharacterExceptionTest extends TestCase {
-
- public void testConstructor() {
- UnmappableCharacterException ex = new UnmappableCharacterException(3);
- assertTrue(ex instanceof CharacterCodingException);
- assertNull(ex.getCause());
- assertEquals(ex.getInputLength(), 3);
- assertTrue(ex.getMessage().indexOf("3") != -1);
-
- ex = new UnmappableCharacterException(-3);
- assertNull(ex.getCause());
- assertEquals(ex.getInputLength(), -3);
- assertTrue(ex.getMessage().indexOf("-3") != -1);
-
- ex = new UnmappableCharacterException(0);
- assertNull(ex.getCause());
- assertEquals(ex.getInputLength(), 0);
- assertTrue(ex.getMessage().indexOf("0") != -1);
-
- }
-
- // comparator for UnmappableCharacterException objects
- private static final SerializableAssert COMPARATOR = new SerializableAssert() {
- public void assertDeserialized(Serializable initial,
- Serializable deserialized) {
-
- // do common checks for all throwable objects
- SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
- deserialized);
-
- UnmappableCharacterException initEx = (UnmappableCharacterException) initial;
- UnmappableCharacterException desrEx = (UnmappableCharacterException) deserialized;
-
- assertEquals("InputLength", initEx.getInputLength(), desrEx
- .getInputLength());
- }
- };
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new UnmappableCharacterException(11),
- COMPARATOR);
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new UnmappableCharacterException(
- 11), COMPARATOR);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/UnsupportedCharsetExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/UnsupportedCharsetExceptionTest.java
deleted file mode 100644
index 57ea31c..0000000
--- a/harmony-tests/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/UnsupportedCharsetExceptionTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio_char.tests.java.nio.charset;
-
-import java.io.Serializable;
-import java.nio.charset.UnsupportedCharsetException;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
-
-/**
- * Test class UnsupportedCharsetException.
- */
-public class UnsupportedCharsetExceptionTest extends TestCase {
-
- public void testConstructor() {
- UnsupportedCharsetException ex = new UnsupportedCharsetException(
- "impossible");
- assertTrue(ex instanceof IllegalArgumentException);
- assertNull(ex.getCause());
- assertEquals(ex.getCharsetName(), "impossible");
- assertTrue(ex.getMessage().indexOf("impossible") != -1);
-
- ex = new UnsupportedCharsetException("ascii");
- assertNull(ex.getCause());
- assertEquals(ex.getCharsetName(), "ascii");
- assertTrue(ex.getMessage().indexOf("ascii") != -1);
-
- ex = new UnsupportedCharsetException("");
- assertNull(ex.getCause());
- assertEquals(ex.getCharsetName(), "");
- ex.getMessage();
-
- ex = new UnsupportedCharsetException(null);
- assertNull(ex.getCause());
- assertNull(ex.getCharsetName());
- assertTrue(ex.getMessage().indexOf("null") != -1);
- }
-
- // comparator for UnsupportedCharsetException objects
- private static final SerializableAssert COMPARATOR = new SerializableAssert() {
- public void assertDeserialized(Serializable initial,
- Serializable deserialized) {
-
- // FIXME?: getMessage() returns more helpful string but
- // this leads to incompatible message in serial form
- //
- // do common checks for all throwable objects
- // SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
- // deserialized);
-
- UnsupportedCharsetException initEx = (UnsupportedCharsetException) initial;
- UnsupportedCharsetException desrEx = (UnsupportedCharsetException) deserialized;
-
- assertEquals("CharsetName", initEx.getCharsetName(), desrEx
- .getCharsetName());
- }
- };
-
- /**
- * @tests serialization/deserialization compatibility.
- */
- public void testSerializationSelf() throws Exception {
-
- SerializationTest.verifySelf(new UnsupportedCharsetException(
- "charsetName"), COMPARATOR);
- }
-
- /**
- * @tests serialization/deserialization compatibility with RI.
- */
- public void testSerializationCompatibility() throws Exception {
-
- SerializationTest.verifyGolden(this, new UnsupportedCharsetException(
- "charsetName"), COMPARATOR);
- }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/file/FileURLConnectionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/file/FileURLConnectionTest.java
new file mode 100644
index 0000000..d6f2c01
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/file/FileURLConnectionTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.internal.net.www.protocol.file;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import junit.framework.TestCase;
+import libcore.io.Streams;
+import libcore.net.url.FileURLConnection;
+
+/**
+ * Tests for <code>FileURLConnection</code> class constructors and methods.
+ */
+public class FileURLConnectionTest extends TestCase {
+
+ private static final String RESOURCE_NAME = "resources/test.rtf";
+
+ private final ClassLoader loader = FileURLConnectionTest.class.getClassLoader();
+
+ private URL createTempFileWithContent(String resourceName) throws IOException {
+ InputStream is = null;
+ OutputStream os = null;
+ try {
+ final URL url = loader.getResource(resourceName);
+ assertNotNull("Cannot find test resource " + resourceName, url);
+ is = url.openStream();
+ File file = File.createTempFile("FileURLConnectionTest",
+ resourceName.substring(resourceName.indexOf(".")));
+ os = new BufferedOutputStream(new FileOutputStream(file));
+ Streams.copy(is, os);
+
+ return new URL("file://" + file.getAbsolutePath());
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+
+ if (os != null) {
+ os.close();
+ }
+ }
+ }
+
+ private String getContentType(String fileName) throws IOException {
+ String resourceName = "resources/" + fileName;
+ URL url = createTempFileWithContent(resourceName);
+ return new FileURLConnection(url).getContentType();
+ }
+
+ public void testGetContentType() throws IOException {
+ // Regression for HARMONY-4699
+ assertEquals("text/rtf", getContentType("test.rtf"));
+ // RI would return "content/unknown"
+ assertEquals("application/msword", getContentType("test.doc"));
+ assertEquals("text/html", getContentType("test.htx"));
+ assertEquals("text/xml", getContentType("test.xml"));
+ assertEquals("text/html",
+ new FileURLConnection(new URL("file:///")).getContentType());
+ }
+
+ public void testGetInputStream() throws IOException {
+ // Regression for Harmony-5737
+ URL url = createTempFileWithContent(RESOURCE_NAME);
+ assertNotNull(url);
+ URL anchorUrl = new URL(url, "#anchor");
+ assertNotNull("Cannot find test resource " + RESOURCE_NAME, anchorUrl);
+
+ FileURLConnection conn = new FileURLConnection(anchorUrl);
+ assertNotNull(conn.getInputStream());
+ }
+
+ public void testGetInputStream_localHost() throws IOException {
+ // Regression for Harmony-5779
+ URL url = createTempFileWithContent(RESOURCE_NAME);
+ String localURLString = "file://localhost/" + url.getFile();
+ URL localURL = new URL(localURLString);
+ FileURLConnection conn = new FileURLConnection(localURL);
+ assertNotNull(conn.getInputStream());
+ assertEquals("file", conn.getURL().getProtocol());
+ }
+
+ public void testHeaderFunctions() throws IOException {
+ URL url = createTempFileWithContent(RESOURCE_NAME);
+ FileURLConnection conn = new FileURLConnection(url);
+ assertNotNull(conn.getInputStream());
+ assertEquals(conn.getContentType(), conn.getHeaderField("content-type"));
+
+ url = createTempFileWithContent(RESOURCE_NAME);
+ conn = new FileURLConnection(url);
+
+ assertNotNull(conn.getInputStream());
+ assertEquals(conn.getContentType(), conn.getHeaderField("content-type"));
+ assertEquals(Integer.toString(conn.getContentLength()),
+ conn.getHeaderField("content-length"));
+ assertEquals(conn.getHeaderField(0), conn.getHeaderField("content-type"));
+ assertEquals(conn.getHeaderField(1), conn.getHeaderField("content-length"));
+ assertEquals(conn.getHeaderField(2), conn.getHeaderField("last-modified"));
+ assertEquals("last-modified", conn.getHeaderFieldKey(2));
+ assertEquals("content-length", conn.getHeaderFieldKey(1));
+ assertEquals("content-type", conn.getHeaderFieldKey(0));
+ }
+
+ public void testHeader_BoundaryCheck() throws IOException {
+ URL url = createTempFileWithContent(RESOURCE_NAME);
+ URLConnection urlConnection = url.openConnection();
+ assertNull(urlConnection.getHeaderField(Integer.MIN_VALUE));
+ assertNull(urlConnection.getHeaderField(Integer.MAX_VALUE));
+ assertNull(urlConnection.getHeaderFieldKey(Integer.MIN_VALUE));
+ assertNull(urlConnection.getHeaderFieldKey(Integer.MAX_VALUE));
+ assertNull(urlConnection.getHeaderField(null));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedInputStreamTest.java
new file mode 100644
index 0000000..a5ba9e1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedInputStreamTest.java
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import junit.framework.TestCase;
+
+public class BufferedInputStreamTest extends TestCase {
+
+ private static final String INPUT =
+ "Test_All_Tests\n" +
+ "Test_BufferedInputStream\n" +
+ "Test_java_io_BufferedOutputStream\n" +
+ "Test_java_io_ByteArrayInputStream\n" +
+ "Test_java_io_ByteArrayOutputStream\n" +
+ "Test_java_io_DataInputStream\n" +
+ "Test_java_io_File\n" +
+ "Test_java_io_FileDescriptor\n" +
+ "Test_java_io_FileInputStream\n" +
+ "Test_java_io_FileNotFoundException\n" +
+ "Test_java_io_FileOutputStream\n" +
+ "Test_java_io_FilterInputStream\n" +
+ "Test_java_io_FilterOutputStream\n" +
+ "Test_java_io_InputStream\n" +
+ "Test_java_io_IOException\n" +
+ "Test_java_io_OutputStream\n" +
+ "Test_java_io_PrintStream\n" +
+ "Test_java_io_RandomAccessFile\n" +
+ "Test_java_io_SyncFailedException\n" +
+ "Test_java_lang_AbstractMethodError\n" +
+ "Test_java_lang_ArithmeticException\n" +
+ "Test_java_lang_ArrayIndexOutOfBoundsException\n" +
+ "Test_java_lang_ArrayStoreException\n" +
+ "Test_java_lang_Boolean\n" +
+ "Test_java_lang_Byte\n" +
+ "Test_java_lang_Character\n" +
+ "Test_All_Tests\n" +
+ "Test_BufferedInputStream\n" +
+ "Test_java_io_BufferedOutputStream\n" +
+ "Test_java_io_ByteArrayInputStream\n" +
+ "Test_java_io_ByteArrayOutputStream\n" +
+ "Test_java_io_DataInputStream\n" +
+ "Test_java_io_File\n" +
+ "Test_java_io_FileDescriptor\n" +
+ "Test_java_io_FileInputStream\n" +
+ "Test_java_io_FileNotFoundException\n" +
+ "Test_java_io_FileOutputStream\n" +
+ "Test_java_io_FilterInputStream\n" +
+ "Test_java_io_FilterOutputStream\n" +
+ "Test_java_io_InputStream\n" +
+ "Test_java_io_IOException\n" +
+ "Test_java_io_OutputStream\n" +
+ "Test_java_io_PrintStream\n" +
+ "Test_java_io_RandomAccessFile\n" +
+ "Test_java_io_SyncFailedException\n" +
+ "Test_java_lang_AbstractMethodError\n" +
+ "Test_java_lang_ArithmeticException\n" +
+ "Test_java_lang_ArrayIndexOutOfBoundsException\n" +
+ "Test_java_lang_ArrayStoreException\n" +
+ "Test_java_lang_Boolean\n" +
+ "Test_java_lang_Byte\n" +
+ "Test_java_lang_Character\n";
+
+ private BufferedInputStream is;
+ private InputStream isBytes;
+
+
+ /*
+ * java.io.BufferedInputStream(InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() {
+ try {
+ BufferedInputStream str = new BufferedInputStream(null);
+ str.read();
+ fail("Expected an IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /*
+ * java.io.BufferedInputStream(InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStreamI() throws IOException {
+ try {
+ BufferedInputStream str = new BufferedInputStream(null, 1);
+ str.read();
+ fail("Expected an IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ // Test for method java.io.BufferedInputStream(java.io.InputStream, int)
+
+ // Create buffer with hald size of file and fill it.
+ int bufferSize = INPUT.length() / 2;
+ is = new BufferedInputStream(isBytes, bufferSize);
+ // Ensure buffer gets filled by evaluating one read
+ is.read();
+ // Close underlying FileInputStream, all but 1 buffered bytes should
+ // still be available.
+ isBytes.close();
+ // Read the remaining buffered characters, no IOException should
+ // occur.
+ is.skip(bufferSize - 2);
+ is.read();
+ try {
+ // is.read should now throw an exception because it will have to
+ // be filled.
+ is.read();
+ fail("Exception should have been triggered by read()");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ // regression test for harmony-2407
+ new MockBufferedInputStream(null);
+ assertNotNull(MockBufferedInputStream.buf);
+ MockBufferedInputStream.buf = null;
+ new MockBufferedInputStream(null, 100);
+ assertNotNull(MockBufferedInputStream.buf);
+ }
+
+ static class MockBufferedInputStream extends BufferedInputStream {
+ static byte[] buf;
+
+ MockBufferedInputStream(InputStream is) throws IOException {
+ super(is);
+ buf = super.buf;
+ }
+
+ MockBufferedInputStream(InputStream is, int size) throws IOException {
+ super(is, size);
+ buf = super.buf;
+ }
+ }
+
+ /**
+ * java.io.BufferedInputStream#available()
+ */
+ public void test_available() throws IOException {
+ assertTrue("Returned incorrect number of available bytes", is
+ .available() == INPUT.length());
+
+ // Test that a closed stream throws an IOE for available()
+ BufferedInputStream bis = new BufferedInputStream(
+ new ByteArrayInputStream(new byte[] { 'h', 'e', 'l', 'l', 'o',
+ ' ', 't', 'i', 'm' }));
+ int available = bis.available();
+ bis.close();
+ assertTrue(available != 0);
+
+ try {
+ bis.available();
+ fail("Expected test to throw IOE.");
+ } catch (IOException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.BufferedInputStream#close()
+ */
+ public void test_close() throws IOException {
+ new BufferedInputStream(isBytes).close();
+
+ // regression for HARMONY-667
+ BufferedInputStream buf = new BufferedInputStream(null, 5);
+ buf.close();
+
+ InputStream in = new InputStream() {
+ Object lock = new Object();
+
+ @Override
+ public int read() {
+ return 1;
+ }
+
+ @Override
+ public int read(byte[] buf, int offset, int length) {
+ synchronized (lock) {
+ try {
+ lock.wait(3000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ return 1;
+ }
+
+ @Override
+ public void close() {
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ }
+ };
+ final BufferedInputStream bufin = new BufferedInputStream(in);
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(1000);
+ bufin.close();
+ } catch (Exception e) {
+ // Ignored
+ }
+ }
+ });
+ thread.start();
+ try {
+ bufin.read(new byte[100], 0, 99);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.BufferedInputStream#mark(int)
+ */
+ public void test_markI() throws IOException {
+ byte[] buf1 = new byte[100];
+ byte[] buf2 = new byte[100];
+ is.skip(50);
+ is.mark(500);
+ is.read(buf1, 0, buf1.length);
+ is.reset();
+ is.read(buf2, 0, buf2.length);
+ is.reset();
+ assertTrue("Failed to mark correct position", new String(buf1, 0,
+ buf1.length).equals(new String(buf2, 0, buf2.length)));
+
+ byte[] bytes = new byte[256];
+ for (int i = 0; i < 256; i++) {
+ bytes[i] = (byte) i;
+ }
+ InputStream in = new BufferedInputStream(
+ new ByteArrayInputStream(bytes), 12);
+ in.skip(6);
+ in.mark(14);
+ in.read(new byte[14], 0, 14);
+ in.reset();
+ assertTrue("Wrong bytes", in.read() == 6 && in.read() == 7);
+
+ in = new BufferedInputStream(new ByteArrayInputStream(bytes), 12);
+ in.skip(6);
+ in.mark(8);
+ in.skip(7);
+ in.reset();
+ assertTrue("Wrong bytes 2", in.read() == 6 && in.read() == 7);
+
+ BufferedInputStream buf = new BufferedInputStream(
+ new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4 }), 2);
+ buf.mark(3);
+ bytes = new byte[3];
+ int result = buf.read(bytes);
+ assertEquals(3, result);
+ assertEquals("Assert 0:", 0, bytes[0]);
+ assertEquals("Assert 1:", 1, bytes[1]);
+ assertEquals("Assert 2:", 2, bytes[2]);
+ assertEquals("Assert 3:", 3, buf.read());
+
+ buf = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 0,
+ 1, 2, 3, 4 }), 2);
+ buf.mark(3);
+ bytes = new byte[4];
+ result = buf.read(bytes);
+ assertEquals(4, result);
+ assertEquals("Assert 4:", 0, bytes[0]);
+ assertEquals("Assert 5:", 1, bytes[1]);
+ assertEquals("Assert 6:", 2, bytes[2]);
+ assertEquals("Assert 7:", 3, bytes[3]);
+ assertEquals("Assert 8:", 4, buf.read());
+ assertEquals("Assert 9:", -1, buf.read());
+
+ buf = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 0,
+ 1, 2, 3, 4 }), 2);
+ buf.mark(Integer.MAX_VALUE);
+ buf.read();
+ buf.close();
+ }
+
+ /**
+ * java.io.BufferedInputStream#markSupported()
+ */
+ public void test_markSupported() {
+ assertTrue("markSupported returned incorrect value", is.markSupported());
+ }
+
+ /**
+ * java.io.BufferedInputStream#read()
+ */
+ public void test_read() throws IOException {
+ InputStreamReader isr = new InputStreamReader(is);
+ int c = isr.read();
+ assertEquals(INPUT.charAt(0), c);
+
+ byte[] bytes = new byte[256];
+ for (int i = 0; i < 256; i++) {
+ bytes[i] = (byte) i;
+ }
+ InputStream in = new BufferedInputStream(
+ new ByteArrayInputStream(bytes), 12);
+ assertEquals("Wrong initial byte", 0, in.read()); // Fill the
+ // buffer
+ byte[] buf = new byte[14];
+ in.read(buf, 0, 14); // Read greater than the buffer
+ assertTrue("Wrong block read data", new String(buf, 0, 14)
+ .equals(new String(bytes, 1, 14)));
+ assertEquals("Wrong bytes", 15, in.read()); // Check next byte
+ }
+
+ /**
+ * java.io.BufferedInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII_Exception() throws IOException {
+ BufferedInputStream bis = new BufferedInputStream(null);
+ try {
+ bis.read(null, -1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bis.read(new byte[0], -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bis.read(new byte[0], 1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bis.read(new byte[0], 1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bis.close();
+
+ try {
+ bis.read(null, -1, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.BufferedInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException {
+ byte[] buf1 = new byte[100];
+ is.skip(500);
+ is.mark(500);
+ is.read(buf1, 0, buf1.length);
+ assertTrue("Failed to read correct data", new String(buf1, 0,
+ buf1.length).equals(INPUT.substring(500, 600)));
+
+ BufferedInputStream bufin = new BufferedInputStream(new InputStream() {
+ int size = 2
+ ,
+ pos = 0;
+
+ byte[] contents = new byte[size];
+
+ @Override
+ public int read() throws IOException {
+ if (pos >= size) {
+ throw new IOException("Read past end of data");
+ }
+ return contents[pos++];
+ }
+
+ @Override
+ public int read(byte[] buf, int off, int len) throws IOException {
+ if (pos >= size) {
+ throw new IOException("Read past end of data");
+ }
+ int toRead = len;
+ if (toRead > available()) {
+ toRead = available();
+ }
+ System.arraycopy(contents, pos, buf, off, toRead);
+ pos += toRead;
+ return toRead;
+ }
+
+ @Override
+ public int available() {
+ return size - pos;
+ }
+ });
+ bufin.read();
+ int result = bufin.read(new byte[2], 0, 2);
+ assertTrue("Incorrect result: " + result, result == 1);
+ }
+
+ /**
+ * java.io.BufferedInputStream#reset()
+ */
+ public void test_reset() throws IOException {
+ byte[] buf1 = new byte[10];
+ byte[] buf2 = new byte[10];
+ is.mark(2000);
+ is.read(buf1, 0, 10);
+ is.reset();
+ is.read(buf2, 0, 10);
+ is.reset();
+ assertTrue("Reset failed", new String(buf1, 0, buf1.length)
+ .equals(new String(buf2, 0, buf2.length)));
+
+ BufferedInputStream bIn = new BufferedInputStream(
+ new ByteArrayInputStream("1234567890".getBytes()));
+ bIn.mark(10);
+ for (int i = 0; i < 11; i++) {
+ bIn.read();
+ }
+ bIn.reset();
+ }
+
+ /**
+ * java.io.BufferedInputStream#reset()
+ */
+ public void test_reset_Exception() throws IOException {
+ BufferedInputStream bis = new BufferedInputStream(null);
+
+ // throws IOException with message "Mark has been invalidated"
+ try {
+ bis.reset();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ // does not throw IOException
+ bis.mark(1);
+ bis.reset();
+
+ bis.close();
+
+ // throws IOException with message "stream is closed"
+ try {
+ bis.reset();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.BufferedInputStream#reset()
+ */
+ public void test_reset_scenario1() throws IOException {
+ byte[] input = "12345678900".getBytes();
+ BufferedInputStream buffis = new BufferedInputStream(
+ new ByteArrayInputStream(input));
+ buffis.read();
+ buffis.mark(5);
+ buffis.skip(5);
+ buffis.reset();
+ }
+
+ /**
+ * java.io.BufferedInputStream#reset()
+ */
+ public void test_reset_scenario2() throws IOException {
+ byte[] input = "12345678900".getBytes();
+ BufferedInputStream buffis = new BufferedInputStream(
+ new ByteArrayInputStream(input));
+ buffis.mark(5);
+ buffis.skip(6);
+ buffis.reset();
+ }
+
+ /**
+ * java.io.BufferedInputStream#skip(long)
+ */
+ public void test_skipJ() throws IOException {
+ byte[] buf1 = new byte[10];
+ is.mark(2000);
+ is.skip(1000);
+ is.read(buf1, 0, buf1.length);
+ is.reset();
+ assertTrue("Failed to skip to correct position", new String(buf1, 0,
+ buf1.length).equals(INPUT.substring(1000, 1010)));
+
+ // regression for HARMONY-667
+ try {
+ BufferedInputStream buf = new BufferedInputStream(null, 5);
+ buf.skip(10);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.BufferedInputStream#skip(long)
+ */
+ public void test_skip_NullInputStream() throws IOException {
+ BufferedInputStream buf = new BufferedInputStream(null, 5);
+ assertEquals(0, buf.skip(0));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ @Override
+ protected void setUp() throws IOException {
+ File f = File.createTempFile("BufferedInputStreamTest", "tst");
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.write(INPUT.getBytes(StandardCharsets.US_ASCII));
+ fos.close();
+
+ isBytes = new FileInputStream(f.getAbsolutePath());
+ is = new BufferedInputStream(isBytes, INPUT.length() / 2);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ @Override
+ protected void tearDown() {
+ try {
+ is.close();
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedOutputStreamTest.java
new file mode 100644
index 0000000..9c5bb2d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedOutputStreamTest.java
@@ -0,0 +1,849 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class BufferedOutputStreamTest extends junit.framework.TestCase {
+
+ private java.io.OutputStream os;
+
+ java.io.ByteArrayOutputStream baos;
+
+ java.io.ByteArrayInputStream bais;
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ /**
+ * java.io.BufferedOutputStream#BufferedOutputStream(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() throws IOException {
+ baos = new java.io.ByteArrayOutputStream();
+ os = new java.io.BufferedOutputStream(baos);
+ os.write(fileString.getBytes(), 0, 500);
+ }
+
+ /**
+ * java.io.BufferedOutputStream#BufferedOutputStream(java.io.OutputStream,
+ *int)
+ */
+ public void test_ConstructorLjava_io_OutputStreamI() throws IOException {
+ baos = new java.io.ByteArrayOutputStream();
+ os = new java.io.BufferedOutputStream(baos, 1024);
+ os.write(fileString.getBytes(), 0, 500);
+ }
+
+ public void test_flush_Constructor_NullStream() throws IOException {
+ BufferedOutputStream buffos = new java.io.BufferedOutputStream(null);
+ try {
+ buffos.flush();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ buffos.close();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ buffos = new java.io.BufferedOutputStream(null, 10);
+ try {
+ buffos.flush();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ buffos.close();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ new java.io.BufferedOutputStream(null, 0);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ new java.io.BufferedOutputStream(null, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.BufferedOutputStream#flush()
+ */
+ public void test_flush() throws IOException {
+ baos = new ByteArrayOutputStream();
+ os = new java.io.BufferedOutputStream(baos, 600);
+ os.write(fileString.getBytes(), 0, 500);
+ os.flush();
+ assertEquals("Bytes not written after flush", 500,
+ ((ByteArrayOutputStream) baos).size());
+ }
+
+ private static class MockOutputStream extends OutputStream {
+ byte[] written;
+ int count;
+
+ public MockOutputStream(int size) {
+ written = new byte[size];
+ count = 0;
+ }
+
+ public void write(int b) {
+ written[count++] = (byte) b;
+ }
+
+ public String getWritten() {
+ return new String(written, 0, count);
+ }
+ }
+
+ /**
+ * java.io.BufferedOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() throws IOException {
+ os = new BufferedOutputStream(baos = new ByteArrayOutputStream(), 512);
+ os.write(fileString.getBytes(), 0, 500);
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ assertEquals("Bytes written, not buffered", 0, bais.available());
+ os.flush();
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ assertEquals("Bytes not written after flush", 500, bais.available());
+ os.write(fileString.getBytes(), 500, 513);
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ assertTrue("Bytes not written when buffer full",
+ bais.available() >= 1000);
+ byte[] wbytes = new byte[1013];
+ bais.read(wbytes, 0, 1013);
+ assertEquals("Incorrect bytes written", new String(wbytes, 0,
+ wbytes.length), fileString.substring(0, 1013));
+
+ // regression test for HARMONY-4177
+ MockOutputStream mos = new MockOutputStream(5);
+ BufferedOutputStream bos = new BufferedOutputStream(mos, 3);
+ bos.write("a".getBytes());
+ bos.write("bcde".getBytes());
+ assertEquals("Large data should be written directly", "abcde", mos
+ .getWritten());
+ mos = new MockOutputStream(4);
+ bos = new BufferedOutputStream(mos, 3);
+ bos.write("ab".getBytes());
+ bos.write("cd".getBytes());
+ assertEquals("Should flush before write", "ab", mos.getWritten());
+ }
+
+ /**
+ * java.io.BufferedOutputStream#write(byte[], int, int)
+ */
+ public void test_write_$BII_Exception() throws IOException {
+ OutputStream bos = new BufferedOutputStream(new ByteArrayOutputStream());
+ byte[] nullByteArray = null;
+ byte[] byteArray = new byte[10];
+
+ try {
+ bos.write(nullByteArray, -1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, -1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, -1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, -1, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, -1, 0);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, -1, 1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 0, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 0, byteArray.length + 1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 1, byteArray.length);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, -1, byteArray.length);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, byteArray.length, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ bos.write(byteArray, byteArray.length, 0);
+ try {
+ bos.write(byteArray, byteArray.length, 1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bos.write(byteArray, 0, 0);
+ bos.write(byteArray, 0, 1);
+ bos.write(byteArray, 1, byteArray.length - 1);
+ bos.write(byteArray, 0, byteArray.length);
+
+ try {
+ bos.write(byteArray, 1, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bos.write(byteArray, 1, 0);
+ bos.write(byteArray, 1, 1);
+
+ bos.write(byteArray, byteArray.length, 0);
+
+ try {
+ bos.write(byteArray, byteArray.length + 1, 0);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, byteArray.length + 1, 1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bos.close();
+
+ try {
+ bos.write(byteArray, -1, -1);
+ fail();
+ } catch (IOException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ bos.write(null, -1, -1);
+ fail();
+ } catch (IOException expected) {
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ bos.write(null, 0, 1);
+ fail();
+ } catch (IOException expected) {
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * java.io.BufferedOutputStream#write(byte[], int, int)
+ */
+ public void test_write_$BII_NullStream_NullArray() throws IOException {
+ OutputStream bos = new BufferedOutputStream(null);
+ byte[] nullByteArray = null;
+
+ try {
+ bos.write(nullByteArray, -1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, -1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, -1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.BufferedOutputStream#write(byte[], int, int)
+ */
+ public void test_write_$BII_NullStream_NullArray_Size() throws IOException {
+ OutputStream bos = new BufferedOutputStream(null, 1);
+ byte[] nullByteArray = null;
+
+ try {
+ bos.write(nullByteArray, -1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, -1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, -1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(nullByteArray, 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.BufferedOutputStream#write(byte[], int, int)
+ */
+ public void test_write_$BII_NullStream() throws IOException {
+ BufferedOutputStream bos = new BufferedOutputStream(null);
+ byte[] byteArray = new byte[10];
+
+ try {
+ bos.write(byteArray, -1, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 0, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 1, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, -1, 0);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bos.write(byteArray, 0, 0);
+
+ bos.write(byteArray, 1, 0);
+
+ bos.write(byteArray, byteArray.length, 0);
+
+ try {
+ bos.write(byteArray, byteArray.length + 1, 0);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, -1, 1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bos.write(byteArray, 0, 1);
+ bos.write(byteArray, 1, 1);
+
+ bos.write(byteArray, 0, byteArray.length);
+
+ try {
+ bos.write(byteArray, byteArray.length + 1, 1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.BufferedOutputStream#write(byte[], int, int)
+ */
+ public void test_write_$BII_NullStream_Size() throws IOException {
+ BufferedOutputStream bos = new BufferedOutputStream(null, 1);
+ byte[] byteArray = new byte[10];
+
+ try {
+ bos.write(byteArray, -1, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 0, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 1, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, -1, 0);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bos.write(byteArray, 0, 0);
+
+ bos.write(byteArray, 1, 0);
+
+ bos.write(byteArray, byteArray.length, 0);
+
+ try {
+ bos.write(byteArray, byteArray.length + 1, 0);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, -1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 0, byteArray.length);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bos.write(byteArray, byteArray.length + 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.BufferedOutputStream#write(int)
+ */
+ public void test_writeI() throws IOException {
+ baos = new java.io.ByteArrayOutputStream();
+ os = new java.io.BufferedOutputStream(baos);
+ os.write('t');
+ bais = new java.io.ByteArrayInputStream(baos.toByteArray());
+ assertEquals("Byte written, not buffered", 0, bais.available());
+ os.flush();
+ bais = new java.io.ByteArrayInputStream(baos.toByteArray());
+ assertEquals("Byte not written after flush", 1, bais.available());
+ byte[] wbytes = new byte[1];
+ bais.read(wbytes, 0, 1);
+ assertEquals("Incorrect byte written", 't', wbytes[0]);
+ }
+
+ public void test_write_Close() throws IOException {
+ BufferedOutputStream buffos = new BufferedOutputStream(
+ new ByteArrayOutputStream());
+ buffos.write(new byte[0]);
+ try {
+ buffos.write(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ byte[] buffer = "1234567890".getBytes();
+
+ buffos.write(Integer.MIN_VALUE);
+ buffos.write(Integer.MAX_VALUE);
+ buffos.write(buffer, 0, 10);
+ buffos.flush();
+
+ buffos.close();
+ }
+
+ public void test_write_Scenario1() throws IOException {
+ ByteArrayOutputStream byteArrayos = new ByteArrayOutputStream();
+ ByteArrayInputStream byteArrayis = null;
+ byte[] buffer = "1234567890".getBytes("UTF-8");
+
+ BufferedOutputStream buffos = new BufferedOutputStream(byteArrayos, 10);
+ buffos.write(buffer, 0, 10);
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 10, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 10, byteArrayis
+ .available());
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+
+ buffos.write(buffer, 0, 10);
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 20, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 20, byteArrayis
+ .available());
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+
+ buffos.write(buffer, 0, 10);
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 30, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 30, byteArrayis
+ .available());
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+ }
+
+ public void test_write_Scenario2() throws IOException {
+ ByteArrayOutputStream byteArrayos = new ByteArrayOutputStream();
+ ByteArrayInputStream byteArrayis = null;
+ byte[] buffer = "1234567890".getBytes("UTF-8");
+
+ BufferedOutputStream buffos = new BufferedOutputStream(byteArrayos, 20);
+ buffos.write(buffer, 0, 10);
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 0, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 10, byteArrayis
+ .available());
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+
+ byte[] buffer2 = new byte[] { 'a', 'b', 'c', 'd' };
+ buffos.write(buffer2, 0, 4);
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 10, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 14, byteArrayis
+ .available());
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+ for (int i = 0; i < 4; i++) {
+ assertEquals(buffer2[i], byteArrayis.read());
+ }
+
+ byte[] buffer3 = new byte[] { 'e', 'f', 'g', 'h', 'i' };
+ buffos.write(buffer3, 0, 5);
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 14, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 19, byteArrayis
+ .available());
+ for (int i = 0; i < 10; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+ for (int i = 0; i < 4; i++) {
+ assertEquals(buffer2[i], byteArrayis.read());
+ }
+ for (int i = 0; i < 5; i++) {
+ assertEquals(buffer3[i], byteArrayis.read());
+ }
+
+ buffos.write(new byte[] { 'j', 'k' });
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 19, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 21, byteArrayis
+ .available());
+
+ buffos.close();
+ }
+
+ public void test_write_Scenario3() throws IOException {
+ ByteArrayOutputStream byteArrayos = new ByteArrayOutputStream();
+ ByteArrayInputStream byteArrayis = null;
+ byte[] buffer = "1234567890".getBytes("UTF-8");
+
+ BufferedOutputStream buffos = new BufferedOutputStream(byteArrayos, 5);
+ buffos.write(buffer, 0, 4);
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 0, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 4, byteArrayis
+ .available());
+ for (int i = 0; i < 4; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+
+ buffos.write(buffer, 0, 5);
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes written, not buffered", 9, byteArrayis.available());
+ buffos.flush();
+ byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+ assertEquals("Bytes not written after flush", 9, byteArrayis
+ .available());
+ for (int i = 0; i < 4; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+ for (int i = 0; i < 5; i++) {
+ assertEquals(buffer[i], byteArrayis.read());
+ }
+ }
+
+ // Regression test for flush on closed stream
+ public void test_flush_on_closed_stream() throws IOException {
+ BufferedOutputStream bos = new BufferedOutputStream(new ByteArrayOutputStream());
+ bos.close();
+ try {
+ bos.flush(); // RI does not throw exception
+ } catch (IOException expected) { // but Android does
+ }
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() throws IOException {
+ if (bais != null) {
+ bais.close();
+ }
+ if (os != null) {
+ os.close();
+ }
+ if (baos != null) {
+ baos.close();
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedReaderTest.java
new file mode 100644
index 0000000..1da9502
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedReaderTest.java
@@ -0,0 +1,592 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PipedReader;
+import java.io.Reader;
+import java.io.StringReader;
+
+import junit.framework.TestCase;
+import tests.support.Support_StringReader;
+
+public class BufferedReaderTest extends TestCase {
+
+ BufferedReader br;
+
+ String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ /**
+ * The spec says that BufferedReader.readLine() considers only "\r", "\n"
+ * and "\r\n" to be line separators. We must not permit additional separator
+ * characters.
+ */
+ public void test_readLine_IgnoresEbcdic85Characters() throws IOException {
+ assertLines("A\u0085B", "A\u0085B");
+ }
+
+ public void test_readLine_Separators() throws IOException {
+ assertLines("A\nB\nC", "A", "B", "C");
+ assertLines("A\rB\rC", "A", "B", "C");
+ assertLines("A\r\nB\r\nC", "A", "B", "C");
+ assertLines("A\n\rB\n\rC", "A", "", "B", "", "C");
+ assertLines("A\n\nB\n\nC", "A", "", "B", "", "C");
+ assertLines("A\r\rB\r\rC", "A", "", "B", "", "C");
+ assertLines("A\n\n", "A", "");
+ assertLines("A\n\r", "A", "");
+ assertLines("A\r\r", "A", "");
+ assertLines("A\r\n", "A");
+ assertLines("A\r\n\r\n", "A", "");
+ }
+
+ private void assertLines(String in, String... lines) throws IOException {
+ BufferedReader bufferedReader
+ = new BufferedReader(new Support_StringReader(in));
+ for (String line : lines) {
+ assertEquals(line, bufferedReader.readLine());
+ }
+ assertNull(bufferedReader.readLine());
+ }
+
+ /**
+ * @tests java.io.BufferedReader#BufferedReader(java.io.Reader)
+ */
+ public void test_ConstructorLjava_io_Reader() {
+ // Test for method java.io.BufferedReader(java.io.Reader)
+ assertTrue("Used in tests", true);
+ }
+
+ /**
+ * @tests java.io.BufferedReader#BufferedReader(java.io.Reader, int)
+ */
+ public void test_ConstructorLjava_io_ReaderI() {
+ // Test for method java.io.BufferedReader(java.io.Reader, int)
+ assertTrue("Used in tests", true);
+ }
+
+ /**
+ * @tests java.io.BufferedReader#close()
+ */
+ public void test_close() {
+ // Test for method void java.io.BufferedReader.close()
+ try {
+ br = new BufferedReader(new Support_StringReader(testString));
+ br.close();
+ br.read();
+ fail("Read on closed stream");
+ } catch (IOException x) {
+ return;
+ }
+ }
+
+ /**
+ * @tests java.io.BufferedReader#mark(int)
+ */
+ public void test_markI() throws IOException {
+ // Test for method void java.io.BufferedReader.mark(int)
+ char[] buf = null;
+ br = new BufferedReader(new Support_StringReader(testString));
+ br.skip(500);
+ br.mark(1000);
+ br.skip(250);
+ br.reset();
+ buf = new char[testString.length()];
+ br.read(buf, 0, 500);
+ assertTrue("Failed to set mark properly", testString.substring(500,
+ 1000).equals(new String(buf, 0, 500)));
+
+ try {
+ br = new BufferedReader(new Support_StringReader(testString), 800);
+ br.skip(500);
+ br.mark(250);
+ br.read(buf, 0, 1000);
+ br.reset();
+ fail("Failed to invalidate mark properly");
+ } catch (IOException x) {
+ // Expected
+ }
+
+ char[] chars = new char[256];
+ for (int i = 0; i < 256; i++)
+ chars[i] = (char) i;
+ Reader in = new BufferedReader(new Support_StringReader(new String(
+ chars)), 12);
+
+ in.skip(6);
+ in.mark(14);
+ in.read(new char[14], 0, 14);
+ in.reset();
+ assertTrue("Wrong chars", in.read() == (char) 6
+ && in.read() == (char) 7);
+
+ in = new BufferedReader(new Support_StringReader(new String(chars)), 12);
+ in.skip(6);
+ in.mark(8);
+ in.skip(7);
+ in.reset();
+ assertTrue("Wrong chars 2", in.read() == (char) 6
+ && in.read() == (char) 7);
+
+ BufferedReader br = new BufferedReader(new StringReader("01234"), 2);
+ br.mark(3);
+ char[] carray = new char[3];
+ int result = br.read(carray);
+ assertEquals(3, result);
+ assertEquals("Assert 0:", '0', carray[0]);
+ assertEquals("Assert 1:", '1', carray[1]);
+ assertEquals("Assert 2:", '2', carray[2]);
+ assertEquals("Assert 3:", '3', br.read());
+
+ br = new BufferedReader(new StringReader("01234"), 2);
+ br.mark(3);
+ carray = new char[4];
+ result = br.read(carray);
+ assertEquals("Assert 4:", 4, result);
+ assertEquals("Assert 5:", '0', carray[0]);
+ assertEquals("Assert 6:", '1', carray[1]);
+ assertEquals("Assert 7:", '2', carray[2]);
+ assertEquals("Assert 8:", '3', carray[3]);
+ assertEquals("Assert 9:", '4', br.read());
+ assertEquals("Assert 10:", -1, br.read());
+
+ BufferedReader reader = new BufferedReader(new StringReader("01234"));
+ reader.mark(Integer.MAX_VALUE);
+ reader.read();
+ reader.close();
+ }
+
+ /**
+ * @tests java.io.BufferedReader#markSupported()
+ */
+ public void test_markSupported() {
+ // Test for method boolean java.io.BufferedReader.markSupported()
+ br = new BufferedReader(new Support_StringReader(testString));
+ assertTrue("markSupported returned false", br.markSupported());
+ }
+
+ /**
+ * @tests java.io.BufferedReader#read()
+ */
+ public void test_read() throws IOException {
+ // Test for method int java.io.BufferedReader.read()
+ try {
+ br = new BufferedReader(new Support_StringReader(testString));
+ int r = br.read();
+ assertTrue("Char read improperly", testString.charAt(0) == r);
+ br = new BufferedReader(new Support_StringReader(new String(
+ new char[] { '\u8765' })));
+ assertTrue("Wrong double byte character", br.read() == '\u8765');
+ } catch (java.io.IOException e) {
+ fail("Exception during read test");
+ }
+
+ char[] chars = new char[256];
+ for (int i = 0; i < 256; i++)
+ chars[i] = (char) i;
+ Reader in = new BufferedReader(new Support_StringReader(new String(
+ chars)), 12);
+ try {
+ assertEquals("Wrong initial char", 0, in.read()); // Fill the
+ // buffer
+ char[] buf = new char[14];
+ in.read(buf, 0, 14); // Read greater than the buffer
+ assertTrue("Wrong block read data", new String(buf)
+ .equals(new String(chars, 1, 14)));
+ assertEquals("Wrong chars", 15, in.read()); // Check next byte
+ } catch (IOException e) {
+ fail("Exception during read test 2:" + e);
+ }
+
+ // regression test for HARMONY-841
+ assertTrue(new BufferedReader(new CharArrayReader(new char[5], 1, 0), 2).read() == -1);
+ }
+
+ /**
+ * @tests java.io.BufferedReader#read(char[], int, int)
+ */
+ public void test_read$CII() throws Exception{
+ char[] ca = new char[2];
+ BufferedReader toRet = new BufferedReader(new InputStreamReader(
+ new ByteArrayInputStream(new byte[0])));
+
+ /* Null buffer should throw NPE even when len == 0 */
+ try {
+ toRet.read(null, 1, 0);
+ fail("null buffer reading zero bytes should throw NPE");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ try {
+ toRet.close();
+ } catch (IOException e) {
+ fail("unexpected 1: " + e);
+ }
+
+ try {
+ toRet.read(null, 1, 0);
+ fail("null buffer reading zero bytes on closed stream should throw IOException");
+ } catch (IOException e) {
+ //expected
+ }
+
+ /* Closed reader should throw IOException reading zero bytes */
+ try {
+ toRet.read(ca, 0, 0);
+ fail("Reading zero bytes on a closed reader should not work");
+ } catch (IOException e) {
+ // expected
+ }
+
+ /*
+ * Closed reader should throw IOException in preference to index out of
+ * bounds
+ */
+ try {
+ // Read should throw IOException before
+ // ArrayIndexOutOfBoundException
+ toRet.read(ca, 1, 5);
+ fail("IOException should have been thrown");
+ } catch (IOException e) {
+ // expected
+ }
+
+ // Test to ensure that a drained stream returns 0 at EOF
+ toRet = new BufferedReader(new InputStreamReader(
+ new ByteArrayInputStream(new byte[2])));
+ try {
+ assertEquals("Emptying the reader should return two bytes", 2,
+ toRet.read(ca, 0, 2));
+ assertEquals("EOF on a reader should be -1", -1, toRet.read(ca, 0,
+ 2));
+ assertEquals("Reading zero bytes at EOF should work", 0, toRet
+ .read(ca, 0, 0));
+ } catch (IOException ex) {
+ fail("Unexpected IOException : " + ex.getLocalizedMessage());
+ }
+
+ // Test for method int java.io.BufferedReader.read(char [], int, int)
+ try {
+ char[] buf = new char[testString.length()];
+ br = new BufferedReader(new Support_StringReader(testString));
+ br.read(buf, 50, 500);
+ assertTrue("Chars read improperly", new String(buf, 50, 500)
+ .equals(testString.substring(0, 500)));
+ } catch (java.io.IOException e) {
+ fail("Exception during read test");
+ }
+
+ BufferedReader bufin = new BufferedReader(new Reader() {
+ int size = 2, pos = 0;
+
+ char[] contents = new char[size];
+
+ public int read() throws IOException {
+ if (pos >= size)
+ throw new IOException("Read past end of data");
+ return contents[pos++];
+ }
+
+ public int read(char[] buf, int off, int len) throws IOException {
+ if (pos >= size)
+ throw new IOException("Read past end of data");
+ int toRead = len;
+ if (toRead > (size - pos))
+ toRead = size - pos;
+ System.arraycopy(contents, pos, buf, off, toRead);
+ pos += toRead;
+ return toRead;
+ }
+
+ public boolean ready() throws IOException {
+ return size - pos > 0;
+ }
+
+ public void close() throws IOException {
+ }
+ });
+ try {
+ bufin.read();
+ int result = bufin.read(new char[2], 0, 2);
+ assertTrue("Incorrect result: " + result, result == 1);
+ } catch (IOException e) {
+ fail("Unexpected: " + e);
+ }
+
+ //regression for HARMONY-831
+ try{
+ new BufferedReader(new PipedReader(), 9).read(new char[] {}, 7, 0);
+ fail("should throw IndexOutOfBoundsException");
+ }catch(IndexOutOfBoundsException e){
+ }
+
+ // Regression for HARMONY-54
+ char[] ch = {};
+ BufferedReader reader = new BufferedReader(new CharArrayReader(ch));
+ try {
+ // Check exception thrown when the reader is open.
+ reader.read(null, 1, 0);
+ fail("Assert 0: NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ // Now check IOException is thrown in preference to
+ // NullPointerexception when the reader is closed.
+ reader.close();
+ try {
+ reader.read(null, 1, 0);
+ fail("Assert 1: IOException expected");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ try {
+ // And check that the IOException is thrown before
+ // ArrayIndexOutOfBoundException
+ reader.read(ch, 0, 42);
+ fail("Assert 2: IOException expected");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.io.BufferedReader#read(char[], int, int)
+ */
+ public void test_read_$CII_Exception() throws IOException {
+ br = new BufferedReader(new Support_StringReader(testString));
+ char[] nullCharArray = null;
+ char[] charArray = testString.toCharArray();
+
+ try {
+ br.read(nullCharArray, -1, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ br.read(nullCharArray, -1, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ br.read(nullCharArray, 0, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ br.read(nullCharArray, 0, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ br.read(nullCharArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ br.read(charArray, -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ br.read(charArray, -1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ br.read(charArray, 0, 0);
+ br.read(charArray, 0, charArray.length);
+ br.read(charArray, charArray.length, 0);
+
+ try {
+ br.read(charArray, charArray.length + 1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ br.read(charArray, charArray.length + 1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ br.close();
+
+ try {
+ br.read(nullCharArray, -1, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ br.read(charArray, -1, 0);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ br.read(charArray, 0, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+ /**
+ * @tests java.io.BufferedReader#readLine()
+ */
+ public void test_readLine() {
+ // Test for method java.lang.String java.io.BufferedReader.readLine()
+ try {
+ br = new BufferedReader(new Support_StringReader(testString));
+ String r = br.readLine();
+ assertEquals("readLine returned incorrect string", "Test_All_Tests", r
+ );
+ } catch (java.io.IOException e) {
+ fail("Exception during readLine test");
+ }
+ }
+
+ /**
+ * @tests java.io.BufferedReader#ready()
+ */
+ public void test_ready() {
+ // Test for method boolean java.io.BufferedReader.ready()
+ try {
+ br = new BufferedReader(new Support_StringReader(testString));
+ assertTrue("ready returned false", br.ready());
+ } catch (java.io.IOException e) {
+ fail("Exception during ready test" + e.toString());
+ }
+ }
+
+ /**
+ * @tests java.io.BufferedReader#reset()
+ */
+ public void test_reset() {
+ // Test for method void java.io.BufferedReader.reset()
+ try {
+ br = new BufferedReader(new Support_StringReader(testString));
+ br.skip(500);
+ br.mark(900);
+ br.skip(500);
+ br.reset();
+ char[] buf = new char[testString.length()];
+ br.read(buf, 0, 500);
+ assertTrue("Failed to reset properly", testString.substring(500,
+ 1000).equals(new String(buf, 0, 500)));
+ } catch (java.io.IOException e) {
+ fail("Exception during reset test");
+ }
+ try {
+ br = new BufferedReader(new Support_StringReader(testString));
+ br.skip(500);
+ br.reset();
+ fail("Reset succeeded on unmarked stream");
+ } catch (IOException x) {
+ return;
+
+ }
+ }
+
+ public void test_reset_IOException() throws Exception {
+ int[] expected = new int[] { '1', '2', '3', '4', '5', '6', '7', '8',
+ '9', '0', -1 };
+ br = new BufferedReader(new Support_StringReader("1234567890"), 9);
+ br.mark(9);
+ for (int i = 0; i < 11; i++) {
+ assertEquals(expected[i], br.read());
+ }
+ try {
+ br.reset();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+ for (int i = 0; i < 11; i++) {
+ assertEquals(-1, br.read());
+ }
+
+ br = new BufferedReader(new Support_StringReader("1234567890"));
+ br.mark(10);
+ for (int i = 0; i < 10; i++) {
+ assertEquals(expected[i], br.read());
+ }
+ br.reset();
+ for (int i = 0; i < 11; i++) {
+ assertEquals(expected[i], br.read());
+ }
+ }
+
+ /**
+ * @tests java.io.BufferedReader#skip(long)
+ */
+ public void test_skipJ() {
+ // Test for method long java.io.BufferedReader.skip(long)
+ try {
+ br = new BufferedReader(new Support_StringReader(testString));
+ br.skip(500);
+ char[] buf = new char[testString.length()];
+ br.read(buf, 0, 500);
+ assertTrue("Failed to set skip properly", testString.substring(500,
+ 1000).equals(new String(buf, 0, 500)));
+ } catch (java.io.IOException e) {
+ fail("Exception during skip test");
+ }
+
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ br.close();
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedWriterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedWriterTest.java
new file mode 100644
index 0000000..d1bb971
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/BufferedWriterTest.java
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import tests.support.Support_StringWriter;
+
+public class BufferedWriterTest extends junit.framework.TestCase {
+
+ BufferedWriter bw;
+
+ Support_StringWriter sw;
+
+ public String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ /**
+ * java.io.BufferedWriter#BufferedWriter(java.io.Writer)
+ */
+ public void test_ConstructorLjava_io_Writer() {
+ sw = new Support_StringWriter();
+ bw = new BufferedWriter(sw);
+ sw.write("Hi");
+ assertEquals("Constructor failed", "Hi", sw.toString());
+ }
+
+ /**
+ * java.io.BufferedWriter#BufferedWriter(java.io.Writer, int)
+ */
+ public void test_ConstructorLjava_io_WriterI() {
+ assertTrue("Used in tests", true);
+ }
+
+ private static class MockWriter extends Writer {
+ StringBuffer sb = new StringBuffer();
+ boolean flushCalled = false;
+
+ public void write(char[] buf, int off, int len) throws IOException {
+ for (int i = off; i < off + len; i++) {
+ sb.append(buf[i]);
+ }
+ }
+
+ public void close() throws IOException {
+ // Empty
+ }
+
+ public void flush() throws IOException {
+ flushCalled = true;
+ }
+
+ public String getWritten() {
+ return sb.toString();
+ }
+
+ public boolean isFlushCalled() {
+ return flushCalled;
+ }
+ }
+
+ /**
+ * java.io.BufferedWriter#close()
+ */
+ public void test_close() throws IOException {
+ try {
+ bw.close();
+ bw.write(testString);
+ fail("Writing to a closed stream should throw IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+ assertTrue("Write after close", !sw.toString().equals(testString));
+
+ // Regression test for HARMONY-4178
+ MockWriter mw = new MockWriter();
+ BufferedWriter bw = new BufferedWriter(mw);
+ bw.write('a');
+ bw.close();
+
+ // flush should not be called on underlying stream
+ assertFalse("Flush was called in the underlying stream", mw
+ .isFlushCalled());
+
+ // on the other hand the BufferedWriter itself should flush the
+ // buffer
+ assertEquals("BufferdWriter do not flush itself before close", "a", mw
+ .getWritten());
+ }
+
+ /**
+ * @throws IOException
+ * java.io.BufferedWriter#close()
+ */
+ public void test_close2() throws IOException {
+ BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new ByteArrayOutputStream()));
+ bw.close();
+ }
+
+ /**
+ * java.io.BufferedWriter#flush()
+ */
+ public void test_flush() throws Exception {
+ bw.write("This should not cause a flush");
+ assertTrue("Bytes written without flush", sw.toString().equals(""));
+ bw.flush();
+ assertEquals("Bytes not flushed", "This should not cause a flush", sw
+ .toString());
+ }
+
+ /**
+ * java.io.BufferedWriter#newLine()
+ */
+ public void test_newLine() throws Exception {
+ String separator = System.getProperty("line.separator");
+ bw.write("Hello");
+ bw.newLine();
+ bw.write("World");
+ bw.flush();
+ assertTrue("Incorrect string written: " + sw.toString(), sw.toString()
+ .equals("Hello" + separator + "World"));
+ }
+
+ /**
+ * java.io.BufferedWriter#write(char[], int, int)
+ */
+ public void test_write$CII() throws Exception {
+ char[] testCharArray = testString.toCharArray();
+ bw.write(testCharArray, 500, 1000);
+ bw.flush();
+ assertTrue("Incorrect string written", sw.toString().equals(
+ testString.substring(500, 1500)));
+ }
+
+ /**
+ * java.io.BufferedWriter#write(char[], int, int)
+ */
+ public void test_write_$CII_Exception() throws IOException {
+ BufferedWriter bWriter = new BufferedWriter(sw);
+ char[] nullCharArray = null;
+
+ try {
+ bWriter.write(nullCharArray, -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ bWriter.write(nullCharArray, -1, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ bWriter.write(nullCharArray, 0, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ bWriter.write(nullCharArray, 0, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ char[] testCharArray = testString.toCharArray();
+
+ bWriter.write(testCharArray, 0, 0);
+
+ bWriter.write(testCharArray, testCharArray.length, 0);
+
+ try {
+ bWriter.write(testCharArray, testCharArray.length + 1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bWriter.close();
+
+ try {
+ bWriter.write(nullCharArray, -1, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.BufferedWriter#write(int)
+ */
+ public void test_writeI() throws Exception {
+ bw.write('T');
+ assertTrue("Char written without flush", sw.toString().equals(""));
+ bw.flush();
+ assertEquals("Incorrect char written", "T", sw.toString());
+ }
+
+ /**
+ * java.io.BufferedWriter#write(java.lang.String, int, int)
+ */
+ public void test_writeLjava_lang_StringII() throws Exception {
+ bw.write(testString);
+ bw.flush();
+ assertTrue("Incorrect string written", sw.toString().equals(testString));
+ }
+
+ /**
+ * java.io.BufferedWriter#write(java.lang.String, int, int)
+ */
+ public void test_write_LStringII_Exception() throws IOException {
+ BufferedWriter bWriter = new BufferedWriter(sw);
+
+ bWriter.write((String) null, -1, -1);
+ bWriter.write((String) null, -1, 0);
+ bWriter.write((String) null, 0, -1);
+ bWriter.write((String) null, 0, 0);
+
+ try {
+ bWriter.write((String) null, -1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ bWriter.write(testString, 0, 0);
+ bWriter.write(testString, testString.length(), 0);
+ bWriter.write(testString, testString.length() + 1, 0);
+
+ try {
+ bWriter.write(testString, testString.length() + 1, 1);
+ fail("should throw StringIndexOutOfBoundsException");
+ } catch (StringIndexOutOfBoundsException e) {
+ // expected
+ }
+
+ bWriter.close();
+
+ try {
+ bWriter.write((String) null, -1, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ bWriter.write((String) null, -1, 1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ bWriter.write(testString, -1, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ sw = new Support_StringWriter();
+ bw = new BufferedWriter(sw, 500);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ bw.close();
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ByteArrayInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ByteArrayInputStreamTest.java
new file mode 100644
index 0000000..4ab972d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ByteArrayInputStreamTest.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class ByteArrayInputStreamTest extends junit.framework.TestCase {
+
+ private InputStream is;
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+ /**
+ * ByteArrayInputStream#ByteArrayInputStream(byte[])
+ */
+ public void test_Constructor$B() throws IOException {
+ InputStream bis = new ByteArrayInputStream(fileString.getBytes());
+
+ assertTrue("Unable to create ByteArrayInputStream",
+ bis.available() == fileString.length());
+ }
+
+ /**
+ * ByteArrayInputStream#ByteArrayInputStream(byte[], int, int)
+ */
+ public void test_Constructor$BII() throws IOException {
+ byte[] zz = fileString.getBytes();
+ InputStream bis = new ByteArrayInputStream(zz, 0, 100);
+
+ assertEquals("Unable to create ByteArrayInputStream", 100, bis
+ .available());
+
+ // Regression test for Harmony-2405
+ new SubByteArrayInputStream(new byte[] { 1, 2 }, 444, 13);
+ assertEquals(444, SubByteArrayInputStream.pos);
+ assertEquals(444, SubByteArrayInputStream.mark);
+ assertEquals(2, SubByteArrayInputStream.count);
+ }
+
+ static class SubByteArrayInputStream extends ByteArrayInputStream {
+ public static byte[] buf;
+
+ public static int mark, pos, count;
+
+ SubByteArrayInputStream(byte[] buf, int offset, int length)
+ throws IOException {
+ super(buf, offset, length);
+ buf = super.buf;
+ mark = super.mark;
+ pos = super.pos;
+ count = super.count;
+ }
+ }
+
+ /**
+ * ByteArrayInputStream#available()
+ */
+ public void test_available() throws IOException {
+ assertTrue("Returned incorrect number of available bytes", is
+ .available() == fileString.length());
+ }
+
+ /**
+ * ByteArrayInputStream#close()
+ */
+ public void test_close() throws IOException {
+ is.read();
+ is.close();
+ is.read(); // Should be able to read from a closed stream
+ }
+
+ /**
+ * ByteArrayInputStream#mark(int)
+ */
+ public void test_markI() throws IOException {
+ byte[] buf1 = new byte[100];
+ byte[] buf2 = new byte[100];
+ is.skip(3000);
+ is.mark(1000);
+ is.read(buf1, 0, buf1.length);
+ is.reset();
+ is.read(buf2, 0, buf2.length);
+ is.reset();
+ assertTrue("Failed to mark correct position", new String(buf1, 0,
+ buf1.length).equals(new String(buf2, 0, buf2.length)));
+ }
+
+ /**
+ * ByteArrayInputStream#markSupported()
+ */
+ public void test_markSupported() {
+ assertTrue("markSupported returned incorrect value", is.markSupported());
+ }
+
+ /**
+ * ByteArrayInputStream#read()
+ */
+ public void test_read() throws IOException {
+ InputStreamReader isr = new InputStreamReader(is);
+ int c = isr.read();
+ is.reset();
+ assertTrue("read returned incorrect char", c == fileString.charAt(0));
+ }
+
+ /**
+ * ByteArrayInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException {
+ byte[] buf1 = new byte[20];
+ is.skip(50);
+ is.mark(100);
+ is.read(buf1, 0, buf1.length);
+ assertTrue("Failed to read correct data", new String(buf1, 0,
+ buf1.length).equals(fileString.substring(50, 70)));
+ }
+
+ /**
+ * ByteArrayInputStream#reset()
+ */
+ public void test_reset() throws IOException {
+ byte[] buf1 = new byte[10];
+ byte[] buf2 = new byte[10];
+ is.mark(200);
+ is.read(buf1, 0, 10);
+ is.reset();
+ is.read(buf2, 0, 10);
+ is.reset();
+ assertTrue("Reset failed", new String(buf1, 0, buf1.length)
+ .equals(new String(buf2, 0, buf2.length)));
+ }
+
+ /**
+ * ByteArrayInputStream#skip(long)
+ */
+ public void test_skipJ() throws IOException {
+ byte[] buf1 = new byte[10];
+ is.skip(100);
+ is.read(buf1, 0, buf1.length);
+ assertTrue("Failed to skip to correct position", new String(buf1, 0,
+ buf1.length).equals(fileString.substring(100, 110)));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ is = new ByteArrayInputStream(fileString.getBytes());
+
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ is.close();
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ByteArrayOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ByteArrayOutputStreamTest.java
new file mode 100644
index 0000000..9e95de1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ByteArrayOutputStreamTest.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import junit.framework.TestCase;
+
+/**
+ * Automated Test Suite for class java.io.ByteArrayOutputStream
+ *
+ * @see java.io.ByteArrayOutputStream
+ */
+public class ByteArrayOutputStreamTest extends TestCase {
+
+ ByteArrayOutputStream bos = null;
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() throws Exception {
+ try {
+ bos.close();
+ } catch (Exception ignore) {
+ }
+ super.tearDown();
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#ByteArrayOutputStream(int)
+ */
+ public void test_ConstructorI() {
+ bos = new ByteArrayOutputStream(100);
+ assertEquals("Failed to create stream", 0, bos.size());
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#ByteArrayOutputStream()
+ */
+ public void test_Constructor() {
+ bos = new ByteArrayOutputStream();
+ assertEquals("Failed to create stream", 0, bos.size());
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#close()
+ */
+ public void test_close() {
+ // close() does nothing for this implementation of OutputSteam
+
+ // The spec seems to say that a closed output stream can't be written
+ // to. We don't throw an exception if attempt is made to write.
+ // Right now our implementation doesn't do anything testable but
+ // should we decide to throw an exception if a closed stream is
+ // written to, the appropriate test is commented out below.
+
+ /***********************************************************************
+ * java.io.ByteArrayOutputStream bos = new
+ * java.io.ByteArrayOutputStream(); bos.write (fileString.getBytes(), 0,
+ * 100); try { bos.close(); } catch (java.io.IOException e) {
+ * fail("IOException closing stream"); } try { bos.write
+ * (fileString.getBytes(), 0, 100); bos.toByteArray(); fail("Wrote to
+ * closed stream"); } catch (Exception e) { }
+ **********************************************************************/
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#reset()
+ */
+ public void test_reset() {
+ bos = new java.io.ByteArrayOutputStream();
+ bos.write(fileString.getBytes(), 0, 100);
+ bos.reset();
+ assertEquals("reset failed", 0, bos.size());
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#size()
+ */
+ public void test_size() {
+ bos = new java.io.ByteArrayOutputStream();
+ bos.write(fileString.getBytes(), 0, 100);
+ assertEquals("size test failed", 100, bos.size());
+ bos.reset();
+ assertEquals("size test failed", 0, bos.size());
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#toByteArray()
+ */
+ public void test_toByteArray() {
+ byte[] bytes;
+ byte[] sbytes = fileString.getBytes();
+ bos = new java.io.ByteArrayOutputStream();
+ bos.write(fileString.getBytes(), 0, fileString.length());
+ bytes = bos.toByteArray();
+ for (int i = 0; i < fileString.length(); i++) {
+ assertTrue("Error in byte array", bytes[i] == sbytes[i]);
+ }
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#toString(java.lang.String)
+ */
+ public void test_toStringLjava_lang_String() throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ bos.write(fileString.getBytes("UTF-8"), 0, fileString.length());
+ assertTrue("Returned incorrect 8859-1 String", bos.toString("8859_1")
+ .equals(fileString));
+
+ bos = new ByteArrayOutputStream();
+ bos.write(fileString.getBytes("UTF-8"), 0, fileString.length());
+ assertTrue("Returned incorrect 8859-2 String", bos.toString("8859_2")
+ .equals(fileString));
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#toString()
+ */
+ public void test_toString() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ bos.write(fileString.getBytes(), 0, fileString.length());
+ assertTrue("Returned incorrect String", bos.toString().equals(
+ fileString));
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#toString(int)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_toStringI() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ bos.write(fileString.getBytes(), 0, fileString.length());
+ assertTrue("Returned incorrect String",
+ bos.toString(5).length() == fileString.length());
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#write(int)
+ */
+ public void test_writeI() throws UnsupportedEncodingException {
+ bos = new ByteArrayOutputStream();
+ bos.write('t');
+ byte[] result = bos.toByteArray();
+ assertEquals("Wrote incorrect bytes", "t", new String(result, 0,
+ result.length, "UTF-8"));
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ bos.write(fileString.getBytes(), 0, 100);
+ byte[] result = bos.toByteArray();
+ assertTrue("Wrote incorrect bytes",
+ new String(result, 0, result.length).equals(fileString
+ .substring(0, 100)));
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII_2() {
+ // Regression for HARMONY-387
+ ByteArrayOutputStream obj = new ByteArrayOutputStream();
+ try {
+ obj.write(new byte[] { (byte) 0x00 }, -1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.ByteArrayOutputStream#writeTo(java.io.OutputStream)
+ */
+ public void test_writeToLjava_io_OutputStream() throws Exception {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
+ bos.write(fileString.getBytes(), 0, 100);
+ bos.writeTo(bos2);
+ assertTrue("Returned incorrect String", bos2.toString().equals(
+ fileString.substring(0, 100)));
+
+ // Regression test for HARMONY-834
+ // no exception expected
+ new ByteArrayOutputStream().writeTo(new FileOutputStream(
+ new FileDescriptor()));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharArrayReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharArrayReaderTest.java
new file mode 100644
index 0000000..8865332
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharArrayReaderTest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.CharArrayReader;
+import java.io.IOException;
+
+public class CharArrayReaderTest extends junit.framework.TestCase {
+
+ char[] hw = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+
+ CharArrayReader cr;
+
+ /**
+ * java.io.CharArrayReader#CharArrayReader(char[])
+ */
+ public void test_Constructor$C() throws IOException {
+ cr = new CharArrayReader(hw);
+ assertTrue("Failed to create reader", cr.ready());
+ }
+
+ /**
+ * java.io.CharArrayReader#CharArrayReader(char[], int, int)
+ */
+ public void test_Constructor$CII() throws IOException {
+ cr = new CharArrayReader(hw, 5, 5);
+ assertTrue("Failed to create reader", cr.ready());
+
+ int c = cr.read();
+ assertTrue("Created incorrect reader--returned '" + (char) c
+ + "' intsead of 'W'", c == 'W');
+ }
+
+ /**
+ * java.io.CharArrayReader#close()
+ */
+ public void test_close() {
+ cr = new CharArrayReader(hw);
+ cr.close();
+ try {
+ cr.read();
+ fail("Failed to throw exception on read from closed stream");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ // No-op
+ cr.close();
+ }
+
+ /**
+ * java.io.CharArrayReader#mark(int)
+ */
+ public void test_markI() throws IOException {
+ cr = new CharArrayReader(hw);
+ cr.skip(5L);
+ cr.mark(100);
+ cr.read();
+ cr.reset();
+ assertEquals("Failed to mark correct position", 'W', cr.read());
+ }
+
+ /**
+ * java.io.CharArrayReader#markSupported()
+ */
+ public void test_markSupported() {
+ cr = new CharArrayReader(hw);
+ assertTrue("markSupported returned false", cr.markSupported());
+ }
+
+ /**
+ * java.io.CharArrayReader#read()
+ */
+ public void test_read() throws IOException {
+ cr = new CharArrayReader(hw);
+ assertEquals("Read returned incorrect char", 'H', cr.read());
+ cr = new CharArrayReader(new char[] { '\u8765' });
+ assertTrue("Incorrect double byte char", cr.read() == '\u8765');
+ }
+
+ /**
+ * java.io.CharArrayReader#read(char[], int, int)
+ */
+ public void test_read$CII() throws IOException {
+ char[] c = new char[11];
+ cr = new CharArrayReader(hw);
+ cr.read(c, 1, 10);
+ assertTrue("Read returned incorrect chars", new String(c, 1, 10)
+ .equals(new String(hw, 0, 10)));
+ }
+
+ /**
+ * java.io.CharArrayReader#ready()
+ */
+ public void test_ready() throws IOException {
+ cr = new CharArrayReader(hw);
+ assertTrue("ready returned false", cr.ready());
+ cr.skip(1000);
+ assertTrue("ready returned true", !cr.ready());
+ cr.close();
+
+ try {
+ cr.ready();
+ fail("No exception 1");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ cr = new CharArrayReader(hw);
+ cr.close();
+ cr.ready();
+ fail("No exception 2");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.CharArrayReader#reset()
+ */
+ public void test_reset() throws IOException {
+ cr = new CharArrayReader(hw);
+ cr.skip(5L);
+ cr.mark(100);
+ cr.read();
+ cr.reset();
+ assertEquals("Reset failed to return to marker position", 'W', cr
+ .read());
+
+ // Regression for HARMONY-4357
+ String str = "offsetHello world!";
+ char[] data = new char[str.length()];
+ str.getChars(0, str.length(), data, 0);
+ int offsetLength = 6;
+ int length = data.length - offsetLength;
+
+ CharArrayReader reader = new CharArrayReader(data, offsetLength, length);
+ reader.reset();
+ for (int i = 0; i < length; i++) {
+ assertEquals(data[offsetLength + i], (char) reader.read());
+ }
+ }
+
+ /**
+ * java.io.CharArrayReader#skip(long)
+ */
+ public void test_skipJ() throws IOException {
+ cr = new CharArrayReader(hw);
+ long skipped = cr.skip(5L);
+
+ assertEquals("Failed to skip correct number of chars", 5L, skipped);
+ assertEquals("Skip skipped wrong chars", 'W', cr.read());
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ if (cr != null)
+ cr.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharArrayWriterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharArrayWriterTest.java
new file mode 100644
index 0000000..951a1a1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharArrayWriterTest.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+
+public class CharArrayWriterTest extends junit.framework.TestCase {
+
+ char[] hw = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+
+ CharArrayWriter cw;
+
+ CharArrayReader cr;
+
+ /**
+ * java.io.CharArrayWriter#CharArrayWriter()
+ */
+ public void test_Constructor() {
+ cw = new CharArrayWriter(90);
+ assertEquals("Created incorrect writer", 0, cw.size());
+ }
+
+ /**
+ * java.io.CharArrayWriter#CharArrayWriter(int)
+ */
+ public void test_ConstructorI() {
+ cw = new CharArrayWriter();
+ assertEquals("Created incorrect writer", 0, cw.size());
+ }
+
+ /**
+ * java.io.CharArrayWriter#close()
+ */
+ public void test_close() {
+ cw.close();
+ }
+
+ /**
+ * java.io.CharArrayWriter#flush()
+ */
+ public void test_flush() {
+ cw.flush();
+ }
+
+ /**
+ * java.io.CharArrayWriter#reset()
+ */
+ public void test_reset() throws IOException {
+ cw.write("HelloWorld", 5, 5);
+ cw.reset();
+ cw.write("HelloWorld", 0, 5);
+ cr = new CharArrayReader(cw.toCharArray());
+ char[] c = new char[100];
+ cr.read(c, 0, 5);
+ assertEquals("Reset failed to reset buffer", "Hello", new String(c, 0,
+ 5));
+ }
+
+ /**
+ * java.io.CharArrayWriter#size()
+ */
+ public void test_size() {
+ assertEquals("Returned incorrect size", 0, cw.size());
+ cw.write(hw, 5, 5);
+ assertEquals("Returned incorrect size", 5, cw.size());
+ }
+
+ /**
+ * java.io.CharArrayWriter#toCharArray()
+ */
+ public void test_toCharArray() throws IOException {
+ cw.write("HelloWorld", 0, 10);
+ cr = new CharArrayReader(cw.toCharArray());
+ char[] c = new char[100];
+ cr.read(c, 0, 10);
+ assertEquals("toCharArray failed to return correct array",
+ "HelloWorld", new String(c, 0, 10));
+ }
+
+ /**
+ * java.io.CharArrayWriter#toString()
+ */
+ public void test_toString() {
+ cw.write("HelloWorld", 5, 5);
+ cr = new CharArrayReader(cw.toCharArray());
+ assertEquals("Returned incorrect string", "World", cw.toString());
+ }
+
+ /**
+ * java.io.CharArrayWriter#write(char[], int, int)
+ */
+ public void test_write$CII() throws IOException {
+ cw.write(hw, 5, 5);
+ cr = new CharArrayReader(cw.toCharArray());
+ char[] c = new char[100];
+ cr.read(c, 0, 5);
+ assertEquals("Writer failed to write correct chars", "World",
+ new String(c, 0, 5));
+ }
+
+ /**
+ * java.io.CharArrayWriter#write(char[], int, int)
+ */
+ public void test_write$CII_2() {
+ // Regression for HARMONY-387
+ CharArrayWriter obj = new CharArrayWriter();
+ try {
+ obj.write(new char[] { '0' }, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.CharArrayWriter#write(int)
+ */
+ public void test_writeI() throws IOException {
+ cw.write('T');
+ cr = new CharArrayReader(cw.toCharArray());
+ assertEquals("Writer failed to write char", 'T', cr.read());
+ }
+
+ /**
+ * java.io.CharArrayWriter#write(java.lang.String, int, int)
+ */
+ public void test_writeLjava_lang_StringII() throws IOException {
+ cw.write("HelloWorld", 5, 5);
+ cr = new CharArrayReader(cw.toCharArray());
+ char[] c = new char[100];
+ cr.read(c, 0, 5);
+ assertEquals("Writer failed to write correct chars", "World",
+ new String(c, 0, 5));
+ }
+
+ /**
+ * java.io.CharArrayWriter#write(java.lang.String, int, int)
+ */
+ public void test_writeLjava_lang_StringII_2()
+ throws StringIndexOutOfBoundsException {
+ // Regression for HARMONY-387
+ CharArrayWriter obj = new CharArrayWriter();
+ try {
+ obj.write((String) null, -1, 0);
+ fail("NullPointerException expected");
+ } catch (NullPointerException t) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.CharArrayWriter#writeTo(java.io.Writer)
+ */
+ public void test_writeToLjava_io_Writer() throws IOException {
+ cw.write("HelloWorld", 0, 10);
+ StringWriter sw = new StringWriter();
+ cw.writeTo(sw);
+ assertEquals("Writer failed to write correct chars", "HelloWorld", sw
+ .toString());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ cw = new CharArrayWriter();
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ if (cr != null) {
+ cr.close();
+ }
+ cw.close();
+ }
+
+ /**
+ * java.io.CharArrayWriter#append(char)
+ */
+ public void test_appendChar() throws IOException {
+ char testChar = ' ';
+ CharArrayWriter writer = new CharArrayWriter(10);
+ writer.append(testChar);
+ writer.flush();
+ assertEquals(String.valueOf(testChar), writer.toString());
+ writer.close();
+ }
+
+ /**
+ * java.io.CharArrayWriter#append(CharSequence)
+ */
+ public void test_appendCharSequence() {
+ String testString = "My Test String";
+ CharArrayWriter writer = new CharArrayWriter(10);
+ writer.append(testString);
+ writer.flush();
+ assertEquals(testString, writer.toString());
+ writer.close();
+ }
+
+ /**
+ * java.io.CharArrayWriter#append(CharSequence, int, int)
+ */
+ public void test_appendCharSequenceIntInt() {
+ String testString = "My Test String";
+ CharArrayWriter writer = new CharArrayWriter(10);
+ writer.append(testString, 1, 3);
+ writer.flush();
+ assertEquals(testString.substring(1, 3), writer.toString());
+ writer.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharConversionExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharConversionExceptionTest.java
new file mode 100644
index 0000000..c399793
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/CharConversionExceptionTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.CharConversionException;
+
+public class CharConversionExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.io.CharConversionException#CharConversionException()
+ */
+ public void test_Constructor() {
+ // Currently, there are no refs to CharConversionException so this is
+ // the best test we can do
+ try {
+ if (true) // BB: getting around LF
+ throw new CharConversionException();
+ fail("Exception not thrown");
+ } catch (CharConversionException e) {
+ assertNull(
+ "Exception defined with no message answers non-null to getMessage()",
+ e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.CharConversionException#CharConversionException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ try {
+ if (true) // getting around LF
+ throw new CharConversionException("Blah");
+ fail("Exception not thrown");
+ } catch (CharConversionException e) {
+ assertEquals(
+ "Exception defined with no message answers non-null to getMessage()",
+ "Blah", e.getMessage());
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ComputeSerialVersionUIDTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ComputeSerialVersionUIDTest.java
new file mode 100644
index 0000000..ee0e27d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ComputeSerialVersionUIDTest.java
@@ -0,0 +1,86 @@
+package org.apache.harmony.tests.java.io;
+
+import java.io.ObjectStreamClass;
+
+
+public class ComputeSerialVersionUIDTest extends junit.framework.TestCase {
+
+ public void testComputeSUIDClass() throws Exception {
+ assertEquals(-5877374382732244721L,
+ computeSerialVersionUID(SerializationTestClass.TestClassName1.class));
+ assertEquals(-2258784348609133821L,
+ computeSerialVersionUID(SerializationTestClass.TestClassName2T_T$T.class));
+ assertEquals(-5674447587118957354L,
+ computeSerialVersionUID(SerializationTestClass.TestClassModifierPublic.class));
+ assertEquals(8333249076871004334L,
+ computeSerialVersionUID(SerializationTestClass.TestClassModifierAbstract.class));
+ assertEquals(-6752991881983868187L,
+ computeSerialVersionUID(SerializationTestClass.TestClassModifierFinal.class));
+ assertEquals(-2046603329186110997L,
+ computeSerialVersionUID(SerializationTestClass.TestClassModifierInterface.class));
+ }
+
+ public void testComputeSUIDInterfaces() throws Exception {
+ assertEquals(2385879270919801624L, computeSerialVersionUID(SerializationTestClass.TestInterfaces.class));
+ assertEquals(-3876044724689092051L, computeSerialVersionUID(SerializationTestClass.TestInterfacesA.class));
+ assertEquals(6691168002125833763L, computeSerialVersionUID(SerializationTestClass.TestInterfacesAB.class));
+ assertEquals(-3862602835688739317L, computeSerialVersionUID(SerializationTestClass.TestInterfacesBA.class));
+ assertEquals(6153219913626150137L, computeSerialVersionUID(SerializationTestClass.TestInterfacesC.class));
+ assertEquals(-5230940296111061949L, computeSerialVersionUID(SerializationTestClass.TestInterfacesCA.class));
+ assertEquals(-561891731488612449L, computeSerialVersionUID(SerializationTestClass.TestInterfacesABC.class));
+ assertEquals(7173098887933679885L, computeSerialVersionUID(SerializationTestClass.TestInterfacesACB.class));
+ assertEquals(7417451177210251082L, computeSerialVersionUID(SerializationTestClass.TestInterfacesBAC.class));
+ assertEquals(6457265192863049241L, computeSerialVersionUID(SerializationTestClass.TestInterfacesBCA.class));
+ assertEquals( 5890948387530452778L, computeSerialVersionUID(SerializationTestClass.TestInterfacesCAB.class));
+ assertEquals(-7493935950381842313L, computeSerialVersionUID(SerializationTestClass.TestInterfacesCBA.class));
+ }
+
+
+ public void testComputeSUIDFields() throws Exception {
+ assertEquals(-30967666739349603L, computeSerialVersionUID(SerializationTestClass.TestFieldsNone.class));
+ assertEquals(8551211022820107208L, computeSerialVersionUID(SerializationTestClass.TestFieldsOneFinal.class));
+ assertEquals(-7774226929120968860L, computeSerialVersionUID(SerializationTestClass.TestFieldsTwoFinal.class));
+ assertEquals(-8196468848051541845L, computeSerialVersionUID(SerializationTestClass.TestFieldsOnePrivate.class));
+ assertEquals(-7861029019096564216L, computeSerialVersionUID(SerializationTestClass.TestFieldsTwoPrivate.class));
+ assertEquals(81248916710250820L, computeSerialVersionUID(SerializationTestClass.TestFieldsOneProtected.class));
+ assertEquals(280835377416490750L, computeSerialVersionUID(SerializationTestClass.TestFieldsTwoProtected.class));
+ assertEquals(-2290036437752730858L, computeSerialVersionUID(SerializationTestClass.TestFieldsOnePublic.class));
+ assertEquals(-6124932240571007214L, computeSerialVersionUID(SerializationTestClass.TestFieldsTwoPublic.class));
+ assertEquals(6101579853402497691L, computeSerialVersionUID(SerializationTestClass.TestFieldsOneStatic.class));
+ assertEquals(-7900976994549865116L, computeSerialVersionUID(SerializationTestClass.TestFieldsTwoStatic.class));
+ assertEquals(-4499355017417065560L, computeSerialVersionUID(SerializationTestClass.TestFieldsOneTransient.class));
+ assertEquals(3747907454018261619L, computeSerialVersionUID(SerializationTestClass.TestFieldsTwoTransient.class));
+ assertEquals(-4945042592592621725L, computeSerialVersionUID(SerializationTestClass.TestFieldsOneVolatile.class));
+ assertEquals(8983117060325881490L, computeSerialVersionUID(SerializationTestClass.TestFieldsTwoVolatile.class));
+ assertEquals(-8336483965186710722L, computeSerialVersionUID(SerializationTestClass.TestFieldSignatures.class));
+ }
+
+
+ public void testComputeSUIDConstructors() throws Exception {
+ assertEquals(-614706174292151857L, computeSerialVersionUID(SerializationTestClass.TestConstructorNone.class));
+ assertEquals(-3706135726712902027L, computeSerialVersionUID(SerializationTestClass.TestConstructorOne.class));
+ assertEquals(-8094991171016233719L, computeSerialVersionUID(SerializationTestClass.TestConstructorPrivate.class));
+ assertEquals(-8117933510362198687L, computeSerialVersionUID(SerializationTestClass.TestConstructorProtected.class));
+ assertEquals(9205589590060392077L, computeSerialVersionUID(SerializationTestClass.TestConstructorPublic.class));
+ assertEquals(5408111072458161992L, computeSerialVersionUID(SerializationTestClass.TestConstructorSignature.class));
+ assertEquals(625104530709630511L, computeSerialVersionUID(SerializationTestClass.TestConstructorTwo.class));
+ assertEquals(3737423569701135020L, computeSerialVersionUID(SerializationTestClass.TestConstructorTwoReverse.class));
+ }
+
+ public void testComputeSUIDMethods() throws Exception {
+ assertEquals(8872679581767836990L, computeSerialVersionUID(SerializationTestClass.TestMethodPrivate.class));
+ assertEquals(-4558121473827608582L, computeSerialVersionUID(SerializationTestClass.TestMethodAbstract.class));
+ assertEquals(4148772500508720405L, computeSerialVersionUID(SerializationTestClass.TestMethodFinal.class));
+ assertEquals(6329381817306256121L, computeSerialVersionUID(SerializationTestClass.TestMethodNative.class));
+ assertEquals(-2701115429311553102L, computeSerialVersionUID(SerializationTestClass.TestMethodProtected.class));
+ assertEquals(-4092306049997161465L, computeSerialVersionUID(SerializationTestClass.TestMethodPublic.class));
+ assertEquals(-7948580256486289776L, computeSerialVersionUID(SerializationTestClass.TestMethodStatic.class));
+ assertEquals(4085068229405300186L, computeSerialVersionUID(SerializationTestClass.TestMethodSignature.class));
+ assertEquals(-5743322978294773864L, computeSerialVersionUID(SerializationTestClass.TestMethodReturnSignature.class));
+ assertEquals(-6908429504335657476L, computeSerialVersionUID(SerializationTestClass.TestMethodSynchronized.class));
+ }
+
+ private static long computeSerialVersionUID(Class<?> clazz) {
+ return ObjectStreamClass.lookup(clazz).getSerialVersionUID();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ConsoleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ConsoleTest.java
new file mode 100644
index 0000000..99becf9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ConsoleTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import junit.framework.TestCase;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.lang.reflect.Constructor;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+/**
+ * This file is test for java.io.Console. Due to the redirect problem, it can
+ * only be run on Harmony.
+ *
+ * @since 1.6
+ */
+public class ConsoleTest extends TestCase {
+ private static final byte[] bytes = "hello world\n".getBytes();
+
+ private InputStream in = new ByteArrayInputStream(bytes);
+ private OutputStream out = new ByteArrayOutputStream();
+ private Console console = null;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ Constructor<Console> constructor =
+ Console.class.getDeclaredConstructor(InputStream.class, OutputStream.class);
+ constructor.setAccessible(true);
+ console = constructor.newInstance(in, out);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ console = null;
+ super.tearDown();
+ }
+
+ public void test_flush() {
+ console.flush();
+ assertFalse(console.writer().checkError());
+ }
+
+ public void test_format_LString_LObject() {
+ assertSame(console, console.format("%d %s", 1, "hello"));
+ String prompt = new String(((ByteArrayOutputStream) out).toByteArray());
+ assertEquals("1 hello", prompt);
+ }
+
+ public void test_printf_LString_LObject() {
+ Calendar c = new GregorianCalendar(1983, 2, 21);
+ assertSame(console, console.printf("%1$tm %1$te,%1$tY", c));
+ String prompt = new String(((ByteArrayOutputStream) out).toByteArray());
+ assertEquals("03 21,1983", prompt);
+ }
+
+ public void test_reader() throws IOException {
+ Reader reader1 = console.reader();
+ assertTrue(reader1.ready());
+ Reader reader2 = console.reader();
+ assertSame(reader1, reader2);
+ }
+
+ public void test_readLine() {
+ String line = console.readLine();
+ assertEquals("hello world", line);
+ }
+
+ public void test_readLine_LString_LObject() {
+ String line = console.readLine("%d %s", 2, "Please input a line of string to test:");
+ assertEquals("hello world", line);
+ String prompt = new String(((ByteArrayOutputStream) out).toByteArray());
+ assertEquals("2 Please input a line of string to test:", prompt);
+ }
+
+ /**
+ * {@link java.io.Console#writer()}
+ */
+ public void test_writer() {
+ PrintWriter writer1 = console.writer();
+ PrintWriter writer2 = console.writer();
+ assertSame(writer1, writer2);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataInputStreamTest.java
new file mode 100644
index 0000000..67a4e5f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataInputStreamTest.java
@@ -0,0 +1,594 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+
+public class DataInputStreamTest extends junit.framework.TestCase {
+
+ private DataOutputStream os;
+
+ private DataInputStream dis;
+
+ private ByteArrayOutputStream bos;
+
+ String unihw = "\u0048\u0065\u006C\u006C\u006F\u0020\u0057\u006F\u0072\u006C\u0064";
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_DataInputStream\n";
+
+ /**
+ * java.io.DataInputStream#DataInputStream(java.io.InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() throws IOException {
+ try {
+ os.writeChar('t');
+ os.close();
+ openDataInputStream();
+ } finally {
+ dis.close();
+ }
+ }
+
+ /**
+ * java.io.DataInputStream#read(byte[])
+ */
+ public void test_read$B() throws IOException {
+ os.write(fileString.getBytes());
+ os.close();
+ openDataInputStream();
+ byte rbytes[] = new byte[fileString.length()];
+ dis.read(rbytes);
+ assertTrue("Incorrect data read", new String(rbytes, 0, fileString
+ .length()).equals(fileString));
+ }
+
+ /**
+ * java.io.DataInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException {
+ os.write(fileString.getBytes());
+ os.close();
+ openDataInputStream();
+ byte rbytes[] = new byte[fileString.length()];
+ dis.read(rbytes, 0, rbytes.length);
+ assertTrue("Incorrect data read", new String(rbytes, 0, fileString
+ .length()).equals(fileString));
+ }
+
+ /**
+ * java.io.DataInputStream#readBoolean()
+ */
+ public void test_readBoolean() throws IOException {
+ os.writeBoolean(true);
+ os.close();
+ openDataInputStream();
+ assertTrue("Incorrect boolean written", dis.readBoolean());
+ }
+
+ /**
+ * java.io.DataInputStream#readByte()
+ */
+ public void test_readByte() throws IOException {
+ os.writeByte((byte) 127);
+ os.close();
+ openDataInputStream();
+ assertTrue("Incorrect byte read", dis.readByte() == (byte) 127);
+ }
+
+ /**
+ * java.io.DataInputStream#readChar()
+ */
+ public void test_readChar() throws IOException {
+ os.writeChar('t');
+ os.close();
+ openDataInputStream();
+ assertEquals("Incorrect char read", 't', dis.readChar());
+ }
+
+ /**
+ * java.io.DataInputStream#readDouble()
+ */
+ public void test_readDouble() throws IOException {
+ os.writeDouble(2345.76834720202);
+ os.close();
+ openDataInputStream();
+ assertEquals("Incorrect double read", 2345.76834720202, dis
+ .readDouble());
+ }
+
+ /**
+ * java.io.DataInputStream#readFloat()
+ */
+ public void test_readFloat() throws IOException {
+ os.writeFloat(29.08764f);
+ os.close();
+ openDataInputStream();
+ assertTrue("Incorrect float read", dis.readFloat() == 29.08764f);
+ }
+
+ /**
+ * java.io.DataInputStream#readFully(byte[])
+ */
+ public void test_readFully$B() throws IOException {
+ os.write(fileString.getBytes());
+ os.close();
+ openDataInputStream();
+ byte rbytes[] = new byte[fileString.length()];
+ dis.readFully(rbytes);
+ assertTrue("Incorrect data read", new String(rbytes, 0, fileString
+ .length()).equals(fileString));
+ }
+
+ /**
+ * java.io.DataInputStream#readFully(byte[], int, int)
+ */
+ public void test_readFully$BII() throws IOException {
+ os.write(fileString.getBytes());
+ os.close();
+ openDataInputStream();
+ byte rbytes[] = new byte[fileString.length()];
+ dis.readFully(rbytes, 0, fileString.length());
+ assertTrue("Incorrect data read", new String(rbytes, 0, fileString
+ .length()).equals(fileString));
+ }
+
+ /**
+ * java.io.DataInputStream#readFully(byte[], int, int)
+ */
+ public void test_readFully$BII_Exception() throws IOException {
+ DataInputStream is = new DataInputStream(new ByteArrayInputStream(
+ new byte[fileString.length()]));
+
+ byte[] byteArray = new byte[fileString.length()];
+
+ try {
+ is.readFully(byteArray, -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(byteArray, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(byteArray, 1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ is.readFully(byteArray, -1, 0);
+ is.readFully(byteArray, 0, 0);
+ is.readFully(byteArray, 1, 0);
+
+ try {
+ is.readFully(byteArray, -1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ is.readFully(byteArray, 0, 1);
+ is.readFully(byteArray, 1, 1);
+ try {
+ is.readFully(byteArray, 0, Integer.MAX_VALUE);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.DataInputStream#readFully(byte[], int, int)
+ */
+ public void test_readFully$BII_NullArray() throws IOException {
+ DataInputStream is = new DataInputStream(new ByteArrayInputStream(
+ new byte[fileString.length()]));
+
+ byte[] nullByteArray = null;
+
+ try {
+ is.readFully(nullByteArray, -1, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ is.readFully(nullByteArray, 0, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ is.readFully(nullByteArray, 1, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ is.readFully(nullByteArray, -1, 0);
+ is.readFully(nullByteArray, 0, 0);
+ is.readFully(nullByteArray, 1, 0);
+
+ try {
+ is.readFully(nullByteArray, -1, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ is.readFully(nullByteArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(nullByteArray, 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(nullByteArray, 0, Integer.MAX_VALUE);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.DataInputStream#readFully(byte[], int, int)
+ */
+ public void test_readFully$BII_NullStream() throws IOException {
+ DataInputStream is = new DataInputStream(null);
+ byte[] byteArray = new byte[fileString.length()];
+
+ try {
+ is.readFully(byteArray, -1, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ is.readFully(byteArray, 0, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ is.readFully(byteArray, 1, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ is.readFully(byteArray, -1, 0);
+ is.readFully(byteArray, 0, 0);
+ is.readFully(byteArray, 1, 0);
+
+ try {
+ is.readFully(byteArray, -1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(byteArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(byteArray, 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(byteArray, 0, Integer.MAX_VALUE);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.DataInputStream#readFully(byte[], int, int)
+ */
+ public void test_readFully$BII_NullStream_NullArray() throws IOException {
+ DataInputStream is = new DataInputStream(null);
+ byte[] nullByteArray = null;
+
+ try {
+ is.readFully(nullByteArray, -1, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ is.readFully(nullByteArray, 0, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ is.readFully(nullByteArray, 1, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ is.readFully(nullByteArray, -1, 0);
+ is.readFully(nullByteArray, 0, 0);
+ is.readFully(nullByteArray, 1, 0);
+
+ try {
+ is.readFully(nullByteArray, -1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(nullByteArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(nullByteArray, 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ is.readFully(nullByteArray, 0, Integer.MAX_VALUE);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.DataInputStream#readInt()
+ */
+ public void test_readInt() throws IOException {
+ os.writeInt(768347202);
+ os.close();
+ openDataInputStream();
+ assertEquals("Incorrect int read", 768347202, dis.readInt());
+ }
+
+ /**
+ * java.io.DataInputStream#readLine()
+ */
+ @SuppressWarnings("deprecation")
+ public void test_readLine() throws IOException {
+ os.writeBytes("Hello");
+ os.close();
+ openDataInputStream();
+ String line = dis.readLine();
+ assertTrue("Incorrect line read: " + line, line.equals("Hello"));
+ }
+
+ /**
+ * java.io.DataInputStream#readLong()
+ */
+ public void test_readLong() throws IOException {
+ os.writeLong(9875645283333L);
+ os.close();
+ openDataInputStream();
+ assertEquals("Incorrect long read", 9875645283333L, dis.readLong());
+ }
+
+ /**
+ * java.io.DataInputStream#readShort()
+ */
+ public void test_readShort() throws IOException {
+ os.writeShort(9875);
+ os.close();
+ openDataInputStream();
+ assertTrue("Incorrect short read", dis.readShort() == (short) 9875);
+ }
+
+ /**
+ * java.io.DataInputStream#readUnsignedByte()
+ */
+ public void test_readUnsignedByte() throws IOException {
+ os.writeByte((byte) -127);
+ os.close();
+ openDataInputStream();
+ assertEquals("Incorrect byte read", 129, dis.readUnsignedByte());
+ }
+
+ /**
+ * java.io.DataInputStream#readUnsignedShort()
+ */
+ public void test_readUnsignedShort() throws IOException {
+ os.writeShort(9875);
+ os.close();
+ openDataInputStream();
+ assertEquals("Incorrect short read", 9875, dis.readUnsignedShort());
+ }
+
+ /**
+ * java.io.DataInputStream#readUTF()
+ */
+ public void test_readUTF() throws IOException {
+ os.writeUTF(unihw);
+ os.close();
+ openDataInputStream();
+ assertTrue("Failed to write string in UTF format",
+ dis.available() == unihw.length() + 2);
+ assertTrue("Incorrect string read", dis.readUTF().equals(unihw));
+ }
+
+ static class TestDataInputStream implements DataInput {
+ public boolean readBoolean() throws IOException {
+ return false;
+ }
+
+ public byte readByte() throws IOException {
+ return (byte) 0;
+ }
+
+ public char readChar() throws IOException {
+ return (char) 0;
+ }
+
+ public double readDouble() throws IOException {
+ return 0.0;
+ }
+
+ public float readFloat() throws IOException {
+ return (float) 0.0;
+ }
+
+ public void readFully(byte[] buffer) throws IOException {
+ }
+
+ public void readFully(byte[] buffer, int offset, int count)
+ throws IOException {
+ }
+
+ public int readInt() throws IOException {
+ return 0;
+ }
+
+ public String readLine() throws IOException {
+ return null;
+ }
+
+ public long readLong() throws IOException {
+ return (long) 0;
+ }
+
+ public short readShort() throws IOException {
+ return (short) 0;
+ }
+
+ public int readUnsignedByte() throws IOException {
+ return 0;
+ }
+
+ public int readUnsignedShort() throws IOException {
+ return 0;
+ }
+
+ public String readUTF() throws IOException {
+ return DataInputStream.readUTF(this);
+ }
+
+ public int skipBytes(int count) throws IOException {
+ return 0;
+ }
+ }
+
+ /**
+ * java.io.DataInputStream#readUTF(java.io.DataInput)
+ */
+ public void test_readUTFLjava_io_DataInput() throws IOException {
+ os.writeUTF(unihw);
+ os.close();
+ openDataInputStream();
+ assertTrue("Failed to write string in UTF format",
+ dis.available() == unihw.length() + 2);
+ assertTrue("Incorrect string read", DataInputStream.readUTF(dis)
+ .equals(unihw));
+
+ // Regression test for HARMONY-5336
+ new TestDataInputStream().readUTF();
+ }
+
+ /**
+ * java.io.DataInputStream#skipBytes(int)
+ */
+ public void test_skipBytesI() throws IOException {
+ byte fileBytes[] = fileString.getBytes();
+ os.write(fileBytes);
+ os.close();
+ openDataInputStream();
+ dis.skipBytes(100);
+ byte rbytes[] = new byte[fileString.length()];
+ dis.read(rbytes, 0, 50);
+ dis.close();
+ assertTrue("Incorrect data read", new String(rbytes, 0, 50)
+ .equals(fileString.substring(100, 150)));
+
+ int skipped = 0;
+ openDataInputStream();
+ try {
+ skipped = dis.skipBytes(50000);
+ } catch (EOFException e) {
+ }
+ assertTrue("Skipped should report " + fileString.length() + " not "
+ + skipped, skipped == fileString.length());
+ }
+
+ private void openDataInputStream() throws IOException {
+ dis = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ bos = new ByteArrayOutputStream();
+ os = new DataOutputStream(bos);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ os.close();
+ } catch (Exception e) {
+ }
+ try {
+ dis.close();
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataOutputStreamTest.java
new file mode 100644
index 0000000..1f124f1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/DataOutputStreamTest.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class DataOutputStreamTest extends junit.framework.TestCase {
+
+ private DataOutputStream os;
+
+ private DataInputStream dis;
+
+ private ByteArrayOutputStream bos;
+
+ String unihw = "\u0048\u0065\u006C\u006C\u006F\u0020\u0057\u006F\u0072\u006C\u0064";
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+ /**
+ * java.io.DataOutputStream#DataOutputStream(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() {
+ assertTrue("Used in all tests", true);
+ }
+
+ /**
+ * java.io.DataOutputStream#flush()
+ */
+ public void test_flush() throws IOException {
+ os.writeInt(9087589);
+ os.flush();
+ openDataInputStream();
+ int c = dis.readInt();
+ dis.close();
+ assertEquals("Failed to flush correctly", 9087589, c);
+ }
+
+ /**
+ * java.io.DataOutputStream#size()
+ */
+ public void test_size() throws IOException {
+ os.write(fileString.getBytes(), 0, 150);
+ os.close();
+ openDataInputStream();
+ byte[] rbuf = new byte[150];
+ dis.read(rbuf, 0, 150);
+ dis.close();
+ assertEquals("Incorrect size returned", 150, os.size());
+ }
+
+ /**
+ * java.io.DataOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() throws IOException {
+ os.write(fileString.getBytes(), 0, 150);
+ os.close();
+ openDataInputStream();
+ byte[] rbuf = new byte[150];
+ dis.read(rbuf, 0, 150);
+ dis.close();
+ assertTrue("Incorrect bytes written", new String(rbuf, 0, 150)
+ .equals(fileString.substring(0, 150)));
+ }
+
+ /**
+ * java.io.DataOutputStream#write(int)
+ */
+ public void test_writeI() throws IOException {
+ os.write((int) 't');
+ os.close();
+ openDataInputStream();
+ int c = dis.read();
+ dis.close();
+ assertTrue("Incorrect int written", (int) 't' == c);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeBoolean(boolean)
+ */
+ public void test_writeBooleanZ() throws IOException {
+ os.writeBoolean(true);
+ os.close();
+ openDataInputStream();
+ boolean c = dis.readBoolean();
+ dis.close();
+ assertTrue("Incorrect boolean written", c);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeByte(int)
+ */
+ public void test_writeByteI() throws IOException {
+ os.writeByte((byte) 127);
+ os.close();
+ openDataInputStream();
+ byte c = dis.readByte();
+ dis.close();
+ assertTrue("Incorrect byte written", c == (byte) 127);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeBytes(java.lang.String)
+ */
+ public void test_writeBytesLjava_lang_String() throws IOException {
+ os.write(fileString.getBytes());
+ os.close();
+ openDataInputStream();
+ byte[] rbuf = new byte[4000];
+ dis.read(rbuf, 0, fileString.length());
+ dis.close();
+ assertTrue("Incorrect bytes written", new String(rbuf, 0, fileString
+ .length()).equals(fileString));
+
+ // regression test for HARMONY-1101
+ new DataOutputStream(null).writeBytes("");
+ }
+
+ /**
+ * java.io.DataOutputStream#writeChar(int)
+ */
+ public void test_writeCharI() throws IOException {
+ os.writeChar('T');
+ os.close();
+ openDataInputStream();
+ char c = dis.readChar();
+ dis.close();
+ assertEquals("Incorrect char written", 'T', c);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeChars(java.lang.String)
+ */
+ public void test_writeCharsLjava_lang_String() throws IOException {
+ os.writeChars("Test String");
+ os.close();
+ openDataInputStream();
+ char[] chars = new char[50];
+ int i, a = dis.available() / 2;
+ for (i = 0; i < a; i++)
+ chars[i] = dis.readChar();
+ assertEquals("Incorrect chars written", "Test String", new String(
+ chars, 0, i));
+ }
+
+ /**
+ * java.io.DataOutputStream#writeDouble(double)
+ */
+ public void test_writeDoubleD() throws IOException {
+ os.writeDouble(908755555456.98);
+ os.close();
+ openDataInputStream();
+ double c = dis.readDouble();
+ dis.close();
+ assertEquals("Incorrect double written", 908755555456.98, c);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeFloat(float)
+ */
+ public void test_writeFloatF() throws IOException {
+ os.writeFloat(9087.456f);
+ os.close();
+ openDataInputStream();
+ float c = dis.readFloat();
+ dis.close();
+ assertTrue("Incorrect float written", c == 9087.456f);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeInt(int)
+ */
+ public void test_writeIntI() throws IOException {
+ os.writeInt(9087589);
+ os.close();
+ openDataInputStream();
+ int c = dis.readInt();
+ dis.close();
+ assertEquals("Incorrect int written", 9087589, c);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeLong(long)
+ */
+ public void test_writeLongJ() throws IOException {
+ os.writeLong(908755555456L);
+ os.close();
+ openDataInputStream();
+ long c = dis.readLong();
+ dis.close();
+ assertEquals("Incorrect long written", 908755555456L, c);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeShort(int)
+ */
+ public void test_writeShortI() throws IOException {
+ os.writeShort((short) 9087);
+ os.close();
+ openDataInputStream();
+ short c = dis.readShort();
+ dis.close();
+ assertEquals("Incorrect short written", 9087, c);
+ }
+
+ /**
+ * java.io.DataOutputStream#writeUTF(java.lang.String)
+ */
+ public void test_writeUTFLjava_lang_String() throws IOException {
+ os.writeUTF(unihw);
+ os.close();
+ openDataInputStream();
+ assertTrue("Failed to write string in UTF format",
+ dis.available() == unihw.length() + 2);
+ assertTrue("Incorrect string returned", dis.readUTF().equals(unihw));
+ }
+
+ private void openDataInputStream() throws IOException {
+ dis = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ bos = new ByteArrayOutputStream();
+ os = new DataOutputStream(bos);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ if (os != null)
+ os.close();
+ if (dis != null)
+ dis.close();
+ } catch (IOException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/EOFExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/EOFExceptionTest.java
new file mode 100644
index 0000000..1610816
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/EOFExceptionTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+
+public class EOFExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.io.EOFException#EOFException()
+ */
+ public void test_Constructor() throws Exception {
+ try {
+ new DataInputStream(new ByteArrayInputStream(new byte[1]))
+ .readShort();
+ fail("Failed to generate EOFException");
+ } catch (EOFException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.EOFException#EOFException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws IOException {
+ try {
+ new DataInputStream(new ByteArrayInputStream(new byte[1]))
+ .readShort();
+ fail("Failed to generate EOFException");
+ } catch (EOFException e) {
+ // Expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileDescriptorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileDescriptorTest.java
new file mode 100644
index 0000000..5c18de3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileDescriptorTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.charset.StandardCharsets;
+import junit.framework.TestCase;
+
+public class FileDescriptorTest extends TestCase {
+
+ public void test_sync() throws IOException {
+ File f = File.createTempFile("FileDescriptorText", "txt");
+
+ FileOutputStream fos = null;
+ FileInputStream fis = null;
+ RandomAccessFile raf = null;
+
+ try {
+ fos = new FileOutputStream(f.getAbsolutePath());
+ fos.write("Test String".getBytes(StandardCharsets.US_ASCII));
+
+ fis = new FileInputStream(f.getPath());
+ FileDescriptor fd = fos.getFD();
+ fd.sync();
+
+ int length = "Test String".length();
+ assertEquals(length, fis.available());
+
+ // Regression test for Harmony-1494
+ fd = fis.getFD();
+ fd.sync();
+ assertEquals(length, fis.available());
+
+ raf = new RandomAccessFile(f, "r");
+ fd = raf.getFD();
+ fd.sync();
+ } finally {
+ if (fos != null) {
+ fos.close();
+ }
+ if (fis != null) {
+ fis.close();
+ }
+ if (raf != null) {
+ raf.close();
+ }
+ }
+ }
+
+ /**
+ * java.io.FileDescriptor#valid()
+ */
+ public void test_valid() throws IOException {
+ File f = File.createTempFile("FileDescriptorText", "txt");
+
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(f.getAbsolutePath());
+ FileDescriptor fd = fos.getFD();
+ assertTrue(fd.valid());
+ fos.close();
+ assertFalse(fd.valid());
+ } finally {
+ if (fos != null) {
+ fos.close();
+ }
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileInputStreamTest.java
new file mode 100644
index 0000000..af54d4b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileInputStreamTest.java
@@ -0,0 +1,482 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import junit.framework.TestCase;
+
+public class FileInputStreamTest extends TestCase {
+
+ private String fileName;
+
+ private java.io.InputStream is;
+
+ private static final String INPUT =
+ "Test_All_Tests\n" +
+ "Test_BufferedInputStream\n" +
+ "Test_java_io_BufferedOutputStream\n" +
+ "Test_java_io_ByteArrayInputStream\n" +
+ "Test_java_io_ByteArrayOutputStream\n" +
+ "Test_java_io_DataInputStream\n" +
+ "Test_java_io_File\n" +
+ "Test_java_io_FileDescriptor\n" +
+ "Test_java_io_FileInputStream\n" +
+ "Test_java_io_FileNotFoundException\n" +
+ "Test_java_io_FileOutputStream\n" +
+ "Test_java_io_FilterInputStream\n" +
+ "Test_java_io_FilterOutputStream\n" +
+ "Test_java_io_InputStream\n" +
+ "Test_java_io_IOException\n" +
+ "Test_java_io_OutputStream\n" +
+ "Test_java_io_PrintStream\n" +
+ "Test_java_io_RandomAccessFile\n" +
+ "Test_java_io_SyncFailedException\n" +
+ "Test_java_lang_AbstractMethodError\n" +
+ "Test_java_lang_ArithmeticException\n" +
+ "Test_java_lang_ArrayIndexOutOfBoundsException\n" +
+ "Test_java_lang_ArrayStoreException\n" +
+ "Test_java_lang_Boolean\n" +
+ "Test_java_lang_Byte\n" +
+ "Test_java_lang_Character\n" +
+ "Test_All_Tests\n" +
+ "Test_BufferedInputStream\n" +
+ "Test_java_io_BufferedOutputStream\n" +
+ "Test_java_io_ByteArrayInputStream\n" +
+ "Test_java_io_ByteArrayOutputStream\n" +
+ "Test_java_io_DataInputStream\n" +
+ "Test_java_io_File\n" +
+ "Test_java_io_FileDescriptor\n" +
+ "Test_java_io_FileInputStream\n" +
+ "Test_java_io_FileNotFoundException\n" +
+ "Test_java_io_FileOutputStream\n" +
+ "Test_java_io_FilterInputStream\n" +
+ "Test_java_io_FilterOutputStream\n" +
+ "Test_java_io_InputStream\n" +
+ "Test_java_io_IOException\n" +
+ "Test_java_io_OutputStream\n" +
+ "Test_java_io_PrintStream\n" +
+ "Test_java_io_RandomAccessFile\n" +
+ "Test_java_io_SyncFailedException\n" +
+ "Test_java_lang_AbstractMethodError\n" +
+ "Test_java_lang_ArithmeticException\n" +
+ "Test_java_lang_ArrayIndexOutOfBoundsException\n" +
+ "Test_java_lang_ArrayStoreException\n" +
+ "Test_java_lang_Boolean\n" +
+ "Test_java_lang_Byte\n" +
+ "Test_java_lang_Character\n";
+
+ @Override
+ protected void setUp() throws IOException {
+ File f = File.createTempFile("FileInputStreamTest", "tst");
+
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(f.getAbsolutePath());
+ fos.write(INPUT.getBytes(StandardCharsets.US_ASCII));
+ } finally {
+ fos.close();
+ }
+
+ fileName = f.getAbsolutePath();
+ }
+
+ /**
+ * java.io.FileInputStream#FileInputStream(java.io.File)
+ */
+ public void test_ConstructorLjava_io_File() throws IOException {
+ java.io.File f = new File(fileName);
+ is = new FileInputStream(f);
+ is.close();
+ }
+
+ /**
+ * java.io.FileInputStream#FileInputStream(java.io.FileDescriptor)
+ */
+ public void test_ConstructorLjava_io_FileDescriptor() throws IOException {
+ FileOutputStream fos = new FileOutputStream(fileName);
+ FileInputStream fis = new FileInputStream(fos.getFD());
+ fos.close();
+ fis.close();
+ }
+
+ /**
+ * java.io.FileInputStream#FileInputStream(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws IOException {
+ is = new FileInputStream(fileName);
+ is.close();
+ }
+
+ /**
+ * java.io.FileInputStream#FileInputStream(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String_I() throws IOException {
+ try {
+ is = new FileInputStream("");
+ fail("should throw FileNotFoundException.");
+ } catch (FileNotFoundException e) {
+ // Expected
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ try {
+ is = new FileInputStream(new File(""));
+ fail("should throw FileNotFoundException.");
+ } catch (FileNotFoundException e) {
+ // Expected
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ /**
+ * java.io.FileInputStream#available()
+ */
+ public void test_available() throws IOException {
+ try {
+ is = new FileInputStream(fileName);
+ assertTrue(is.available() == INPUT.length());
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ public void test_close() throws IOException {
+ is = new FileInputStream(fileName);
+ is.close();
+ try {
+ is.read();
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ public void test_close_shared_fd() throws IOException {
+ // Regression test for HARMONY-6642
+ FileInputStream fis1 = new FileInputStream(fileName);
+ FileInputStream fis2 = new FileInputStream(fis1.getFD());
+
+ try {
+ fis2.close();
+ // Should not throw, since the FD is owned by fis1.
+ fis1.read();
+ } finally {
+ try {
+ fis1.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * java.io.FileInputStream#getFD()
+ */
+ public void test_getFD() throws IOException {
+ FileInputStream fis = new FileInputStream(fileName);
+ assertTrue("Returned invalid fd", fis.getFD().valid());
+ fis.close();
+ assertTrue("Returned invalid fd", !fis.getFD().valid());
+ }
+
+ /**
+ * java.io.FileInputStream#read()
+ */
+ public void test_read() throws IOException {
+ InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName));
+ int c = isr.read();
+ isr.close();
+ assertEquals(INPUT.charAt(0), c);
+ }
+
+ /**
+ * java.io.FileInputStream#read(byte[])
+ */
+ public void test_read$B() throws IOException {
+ byte[] buf1 = new byte[100];
+ is = new FileInputStream(fileName);
+ is.skip(500);
+ is.read(buf1);
+ is.close();
+ assertEquals(INPUT.substring(500, 600),
+ new String(buf1, 0, buf1.length, StandardCharsets.US_ASCII));
+ }
+
+ /**
+ * java.io.FileInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException {
+ byte[] buf1 = new byte[100];
+ is = new FileInputStream(fileName);
+ is.skip(500);
+ is.read(buf1, 0, buf1.length);
+ is.close();
+ assertEquals(INPUT.substring(500, 600),
+ new String(buf1, 0, buf1.length, StandardCharsets.US_ASCII));
+
+ // Regression test for HARMONY-285
+ File tmpFile = File.createTempFile("FileOutputStream", "tmp");
+ FileInputStream in = new FileInputStream(tmpFile);
+ try {
+ in.read(null, 0, 0);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ } finally {
+ in.close();
+ tmpFile.delete();
+ }
+ }
+
+ /**
+ * java.io.FileInputStream#read(byte[], int, int)
+ */
+ public void test_read_$BII_IOException() throws IOException {
+ byte[] buf = new byte[1000];
+ try {
+ is = new FileInputStream(fileName);
+ is.read(buf, -1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+
+ try {
+ is = new FileInputStream(fileName);
+ is.read(buf, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+
+ try {
+ is = new FileInputStream(fileName);
+ is.read(buf, -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+
+ try {
+ is = new FileInputStream(fileName);
+ is.read(buf, 0, 1001);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+
+ try {
+ is = new FileInputStream(fileName);
+ is.read(buf, 1001, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+
+ try {
+ is = new FileInputStream(fileName);
+ is.read(buf, 500, 501);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+
+ try {
+ is = new FileInputStream(fileName);
+ is.close();
+ is.read(buf, 0, 100);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+
+ try {
+ is = new FileInputStream(fileName);
+ is.close();
+ is.read(buf, 0, 0);
+ } finally {
+ is.close();
+ }
+ }
+
+ /**
+ * java.io.FileInputStream#read(byte[], int, int)
+ */
+ public void test_read_$BII_NullPointerException() throws IOException {
+ byte[] buf = null;
+ try {
+ is = new FileInputStream(fileName);
+ is.read(buf, -1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+ }
+
+ /**
+ * java.io.FileInputStream#read(byte[], int, int)
+ */
+ public void test_read_$BII_IndexOutOfBoundsException() throws IOException {
+ byte[] buf = new byte[1000];
+ try {
+ is = new FileInputStream(fileName);
+ is.close();
+ is.read(buf, -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+ }
+
+ /**
+ * java.io.FileInputStream#skip(long)
+ */
+ public void test_skipJ() throws IOException {
+ byte[] buf1 = new byte[10];
+ is = new FileInputStream(fileName);
+ is.skip(1000);
+ is.read(buf1, 0, buf1.length);
+ is.close();
+ assertEquals(INPUT.substring(1000, 1010),
+ new String(buf1, 0, buf1.length, StandardCharsets.US_ASCII));
+
+ }
+
+ /**
+ * java.io.FileInputStream#read(byte[], int, int))
+ */
+ public void test_regressionNNN() throws IOException {
+ // Regression for HARMONY-434
+ FileInputStream fis = new FileInputStream(fileName);
+
+ try {
+ fis.read(new byte[1], -1, 1);
+ fail("IndexOutOfBoundsException must be thrown if off <0");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ fis.read(new byte[1], 0, -1);
+ fail("IndexOutOfBoundsException must be thrown if len <0");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ fis.read(new byte[1], 0, 5);
+ fail("IndexOutOfBoundsException must be thrown if off+len > b.length");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ fis.read(new byte[10], Integer.MAX_VALUE, 5);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ fis.read(new byte[10], 5, Integer.MAX_VALUE);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ fis.close();
+ }
+
+ /**
+ * java.io.FileInputStream#skip(long)
+ */
+ public void test_skipNegativeArgumentJ() throws IOException {
+ FileInputStream fis = new FileInputStream(fileName);
+ try {
+ fis.skip(-5);
+ fail("IOException must be thrown if number of bytes to skip <0");
+ } catch (IOException e) {
+ // Expected IOException
+ } finally {
+ fis.close();
+ }
+ }
+
+ public void test_getChannel() throws Exception {
+ FileInputStream fis = new FileInputStream(fileName);
+ assertEquals(0, fis.getChannel().position());
+ int r;
+ int count = 1;
+ while ((r = fis.read()) != -1) {
+ assertEquals(count++, fis.getChannel().position());
+ }
+ fis.close();
+
+ try {
+ fis.getChannel().position();
+ fail("should throw ClosedChannelException");
+ } catch (java.nio.channels.ClosedChannelException e) {
+ // Expected
+ }
+
+ fis = new FileInputStream(fileName);
+ assertEquals(0, fis.getChannel().position());
+ byte[] bs = new byte[10];
+ r = fis.read(bs);
+ assertEquals(10, fis.getChannel().position());
+ fis.close();
+
+ fis = new FileInputStream(fileName);
+ assertEquals(0, fis.getChannel().position());
+ bs = new byte[10];
+ fis.skip(100);
+ assertEquals(100, fis.getChannel().position());
+ r = fis.read(bs);
+ assertEquals(110, fis.getChannel().position());
+ fis.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileNotFoundExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileNotFoundExceptionTest.java
new file mode 100644
index 0000000..a1772cd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileNotFoundExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.FileNotFoundException;
+
+import junit.framework.TestCase;
+
+public class FileNotFoundExceptionTest extends TestCase {
+
+ /**
+ * java.io.FileNotFoundException#FileNotFoundException()
+ */
+ public void test_Constructor() {
+ FileNotFoundException e = new FileNotFoundException();
+ assertNull(e.getMessage());
+ }
+
+ /**
+ * java.io.FileNotFoundException#FileNotFoundException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ String message = "Cannot found file: 9://0//l";
+ FileNotFoundException e = new FileNotFoundException(message);
+ assertSame(message, e.getMessage());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileOutputStreamTest.java
new file mode 100644
index 0000000..6263cc5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileOutputStreamTest.java
@@ -0,0 +1,394 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class FileOutputStreamTest extends TestCase {
+
+ private FileOutputStream fos;
+ private FileInputStream fis;
+ private File f;
+ private byte[] bytes;
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ protected void setUp() {
+ bytes = new byte[10];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = (byte) i;
+ }
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (f != null) {
+ f.delete();
+ }
+ if (fis != null) {
+ fis.close();
+ }
+ if (fos != null) {
+ fos.close();
+ }
+ }
+
+ /**
+ * java.io.FileOutputStream#FileOutputStream(java.io.File)
+ */
+ public void test_ConstructorLjava_io_File() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ fos = new FileOutputStream(f);
+ }
+
+ /**
+ * java.io.FileOutputStream#FileOutputStream(java.io.FileDescriptor)
+ */
+ public void test_ConstructorLjava_io_FileDescriptor() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ String fileName = f.getAbsolutePath();
+ fos = new FileOutputStream(fileName);
+ fos.write('l');
+ fos.close();
+ fis = new FileInputStream(fileName);
+ fos = new FileOutputStream(fis.getFD());
+ fos.close();
+ fis.close();
+ }
+
+ /**
+ * java.io.FileOutputStream#FileOutputStream(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ String fileName = f.getAbsolutePath();
+ fos = new FileOutputStream(fileName);
+
+ // Harmony 4012.
+ fos = new FileOutputStream("/dev/null");
+ fos.close();
+ }
+
+ /**
+ * java.io.FileOutputStream#FileOutputStream(java.lang.String,
+ *boolean)
+ */
+ public void test_ConstructorLjava_lang_StringZ() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ fos = new FileOutputStream(f.getPath(), false);
+ fos.write("HI".getBytes(), 0, 2);
+ fos.close();
+ fos = new FileOutputStream(f.getPath(), true);
+ fos.write(fileString.getBytes());
+ fos.close();
+ byte[] buf = new byte[fileString.length() + 2];
+ fis = new FileInputStream(f.getPath());
+ fis.read(buf, 0, buf.length);
+ assertTrue("Failed to create appending stream", new String(buf, 0,
+ buf.length).equals("HI" + fileString));
+ }
+
+ /**
+ * java.io.FileOutputStream#FileOutputStream(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String_I() throws IOException {
+ try {
+ fos = new FileOutputStream("");
+ fail("should throw FileNotFoundException.");
+ } catch (FileNotFoundException e) {
+ // Expected
+ } finally {
+ if (fos != null) {
+ fos.close();
+ }
+ }
+ try {
+ fos = new FileOutputStream(new File(""));
+ fail("should throw FileNotFoundException.");
+ } catch (FileNotFoundException e) {
+ // Expected
+ } finally {
+ if (fos != null) {
+ fos.close();
+ }
+ }
+ }
+
+ /**
+ * java.io.FileOutputStream#close()
+ */
+ public void test_close() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ fos = new FileOutputStream(f.getPath());
+ fos.close();
+
+ try {
+ fos.write(fileString.getBytes());
+ fail("Close test failed - wrote to closed stream");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.FileOutputStream#getFD()
+ */
+ public void test_getFD() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ String fileName = f.getAbsolutePath();
+ fos = new FileOutputStream(f);
+ assertTrue("Returned invalid fd", fos.getFD().valid());
+ fos.close();
+ assertTrue("Returned invalid fd", !fos.getFD().valid());
+ }
+
+ /**
+ * java.io.FileOutputStream#write(byte[])
+ */
+ public void test_write$B() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ fos = new FileOutputStream(f.getPath());
+ fos.write(fileString.getBytes());
+ fis = new FileInputStream(f.getPath());
+ byte rbytes[] = new byte[4000];
+ fis.read(rbytes, 0, fileString.length());
+ assertTrue("Incorrect string returned", new String(rbytes, 0,
+ fileString.length()).equals(fileString));
+ }
+
+ /**
+ * java.io.FileOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ fos = new FileOutputStream(f.getPath());
+ fos.write(fileString.getBytes(), 0, fileString.length());
+ fis = new FileInputStream(f.getPath());
+ byte rbytes[] = new byte[4000];
+ fis.read(rbytes, 0, fileString.length());
+ assertTrue("Incorrect bytes written", new String(rbytes, 0, fileString
+ .length()).equals(fileString));
+
+ // Regression test for HARMONY-285
+ File file = File.createTempFile("FileOutputStreamTest", ".tmp");
+ FileOutputStream out = new FileOutputStream(file);
+ try {
+ out.write(null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+
+ } finally {
+ out.close();
+ file.delete();
+ }
+ }
+
+ /**
+ * java.io.FileOutputStream#write(int)
+ */
+ public void test_writeI() throws IOException {
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ fos = new FileOutputStream(f.getPath());
+ fos.write('t');
+ fis = new FileInputStream(f.getPath());
+ assertEquals("Incorrect char written", 't', fis.read());
+ }
+
+ /**
+ * java.io.FileOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII2() throws IOException {
+ // Regression for HARMONY-437
+ f = File.createTempFile("FileOutputStreamTest", "tst");
+ fos = new FileOutputStream(f.getPath());
+
+ try {
+ fos.write(null, 1, 1);
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ fos.write(new byte[1], -1, 1);
+ fail("IndexOutOfBoundsException must be thrown if off <0");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ fos.write(new byte[1], 0, -1);
+ fail("IndexOutOfBoundsException must be thrown if len <0");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ fos.write(new byte[1], 0, 5);
+ fail("IndexOutOfBoundsException must be thrown if off+len > b.length");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ fos.write(new byte[10], Integer.MAX_VALUE, 5);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ fos.write(new byte[10], 5, Integer.MAX_VALUE);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ fos.close();
+ }
+
+ /**
+ * java.io.FileOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII3() throws IOException {
+ // Regression for HARMONY-834
+ // no exception expected
+ new FileOutputStream(new FileDescriptor()).write(new byte[1], 0, 0);
+ }
+
+ /**
+ * java.io.FileOutputStream#getChannel()
+ */
+ public void test_getChannel() throws IOException {
+ // Regression for HARMONY-508
+ File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+ tmpfile.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmpfile);
+ fos.write(bytes);
+ fos.flush();
+ fos.close();
+ FileOutputStream f = new FileOutputStream(tmpfile, true);
+ // Harmony expected 10, but the RI and Android report 0.
+ assertEquals(0, f.getChannel().position());
+ }
+
+ public void test_getChannel_Append() throws IOException {
+ File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+ tmpfile.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmpfile, true);
+ assertEquals(0, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(10, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(20, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(30, fos.getChannel().position());
+ fos.close();
+
+ try {
+ fos.getChannel().position();
+ fail("should throw ClosedChannelException");
+ } catch (java.nio.channels.ClosedChannelException e) {
+ // Expected
+ }
+ }
+
+ public void test_getChannel_UnAppend() throws IOException {
+ File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+ tmpfile.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmpfile, false);
+ assertEquals(0, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(10, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(20, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(30, fos.getChannel().position());
+ fos.close();
+
+ try {
+ fos.getChannel().position();
+ fail("should throw ClosedChannelException");
+ } catch (java.nio.channels.ClosedChannelException e) {
+ // Expected
+ }
+ }
+
+ public void test_getChannel_Unappend_Unappend() throws IOException {
+ File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+ tmpfile.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmpfile, false);
+ assertEquals(0, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(10, fos.getChannel().position());
+ fos.close();
+
+ fos = new FileOutputStream(tmpfile, false);
+ assertEquals(0, fos.getChannel().position());
+ fos.close();
+ }
+
+ public void test_getChannel_Unappend_Append() throws IOException {
+ File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+ tmpfile.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmpfile, false);
+ assertEquals(0, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(10, fos.getChannel().position());
+ fos.close();
+
+ fos = new FileOutputStream(tmpfile, true);
+ // Harmony expected 10, but the RI and Android report 0.
+ assertEquals(0, fos.getChannel().position());
+ fos.close();
+ }
+
+ public void test_getChannel_Append_Unappend() throws IOException {
+ File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+ tmpfile.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmpfile, true);
+ assertEquals(0, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(10, fos.getChannel().position());
+ fos.close();
+
+ fos = new FileOutputStream(tmpfile, false);
+ assertEquals(0, fos.getChannel().position());
+ fos.close();
+ }
+
+ public void test_getChanne_Append_Append() throws IOException {
+ File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+ tmpfile.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmpfile, true);
+ assertEquals(0, fos.getChannel().position());
+ fos.write(bytes);
+ assertEquals(10, fos.getChannel().position());
+ fos.close();
+
+ fos = new FileOutputStream(tmpfile, true);
+ // Harmony expected 10, but the RI and Android report 0.
+ assertEquals(0, fos.getChannel().position());
+ fos.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileReaderTest.java
new file mode 100644
index 0000000..7f7c02c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileReaderTest.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class FileReaderTest extends TestCase {
+
+ FileReader br;
+
+ BufferedWriter bw;
+
+ FileInputStream fis;
+
+ File f;
+
+ /**
+ * java.io.FileReader#FileReader(java.io.File)
+ */
+ public void test_ConstructorLjava_io_File() throws IOException {
+ bw = new BufferedWriter(new FileWriter(f.getPath()));
+ bw.write(" After test string", 0, 18);
+ bw.close();
+ br = new FileReader(f);
+ char[] buf = new char[100];
+ int r = br.read(buf);
+ br.close();
+ assertEquals("Failed to read correct chars", " After test string",
+ new String(buf, 0, r));
+ }
+
+ /**
+ * java.io.FileReader#FileReader(java.io.FileDescriptor)
+ */
+ public void test_ConstructorLjava_io_FileDescriptor() throws IOException {
+ bw = new BufferedWriter(new FileWriter(f.getPath()));
+ bw.write(" After test string", 0, 18);
+ bw.close();
+ FileInputStream fis = new FileInputStream(f.getPath());
+ br = new FileReader(fis.getFD());
+ char[] buf = new char[100];
+ int r = br.read(buf);
+ br.close();
+ fis.close();
+ assertEquals("Failed to read correct chars", " After test string",
+ new String(buf, 0, r));
+ }
+
+ /**
+ * java.io.FileReader#FileReader(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws IOException {
+ bw = new BufferedWriter(new FileWriter(f.getPath()));
+ bw.write(" After test string", 0, 18);
+ bw.close();
+ br = new FileReader(f.getPath());
+ char[] buf = new char[100];
+ int r = br.read(buf);
+ br.close();
+ assertEquals("Failed to read correct chars", " After test string",
+ new String(buf, 0, r));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() throws IOException {
+ f = File.createTempFile("FileReaderTest", "tst");
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ bw.close();
+ } catch (Exception e) {
+ // Ignore
+ }
+ try {
+ br.close();
+ } catch (Exception e) {
+ // Ignore
+ }
+ try {
+ if (fis != null) {
+ fis.close();
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ f.delete();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java
new file mode 100644
index 0000000..5cc88f4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java
@@ -0,0 +1,2191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamField;
+import java.io.RandomAccessFile;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import junit.framework.TestCase;
+import libcore.io.Libcore;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class FileTest extends TestCase {
+
+ private static String platformId = "JDK"
+ + System.getProperty("java.vm.version").replace('.', '-');
+
+ private static void deleteTempFolder(File dir) {
+ String files[] = dir.list();
+ if (files != null) {
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ if (f.isDirectory()) {
+ deleteTempFolder(f);
+ } else {
+ f.delete();
+ }
+ }
+ }
+ dir.delete();
+ }
+
+ private static String addTrailingSlash(String path) {
+ if (File.separatorChar == path.charAt(path.length() - 1)) {
+ return path;
+ }
+ return path + File.separator;
+ }
+
+ /**
+ * Location to store tests in
+ */
+ private File tempDirectory;
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_File\nTest_FileDescriptor\nTest_FileInputStream\nTest_FileNotFoundException\nTest_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ protected void setUp() throws IOException {
+ /** Setup the temporary directory */
+ tempDirectory = new File(addTrailingSlash(System.getProperty("java.io.tmpdir")) + "harmony-test-" + getClass().getSimpleName() + File.separator);
+ tempDirectory.mkdirs();
+ }
+
+ protected void tearDown() {
+ if (tempDirectory != null) {
+ deleteTempFolder(tempDirectory);
+ tempDirectory = null;
+ }
+ }
+
+ /**
+ * java.io.File#File(java.io.File, java.lang.String)
+ */
+ public void test_ConstructorLjava_io_FileLjava_lang_String0() {
+ File f = new File(tempDirectory.getPath(), "input.tst");
+ assertEquals("Created Incorrect File ", addTrailingSlash(tempDirectory.getPath()) + "input.tst", f.getPath());
+ }
+
+ public void test_ConstructorLjava_io_FileLjava_lang_String1() {
+ try {
+ new File(tempDirectory, null);
+ fail("NullPointerException Not Thrown.");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_ConstructorLjava_io_FileLjava_lang_String2() throws IOException {
+ File f = new File((File) null, "input.tst");
+ assertEquals("Created Incorrect File",
+ new File("input.tst").getAbsolutePath(),
+ f.getAbsolutePath());
+ }
+
+ public void test_ConstructorLjava_io_FileLjava_lang_String3() {
+ // Regression test for HARMONY-382
+ File f = new File("/abc");
+ File d = new File((File) null, "/abc");
+ assertEquals("Test3: Created Incorrect File",
+ d.getAbsolutePath(), f.getAbsolutePath());
+ }
+
+ public void test_ConstructorLjava_io_FileLjava_lang_String4() {
+ // Regression test for HARMONY-21
+ File path = new File("/dir/file");
+ File root = new File("/");
+ File file = new File(root, "/dir/file");
+ assertEquals("Assert 1: wrong path result ", path.getPath(), file
+ .getPath());
+ if (File.separatorChar == '\\') {
+ assertTrue("Assert 1.1: path not absolute ", new File("\\\\\\a\b")
+ .isAbsolute());
+ } else {
+ assertFalse("Assert 1.1: path absolute ", new File("\\\\\\a\b")
+ .isAbsolute());
+ }
+ }
+
+ public void test_ConstructorLjava_io_FileLjava_lang_String5() {
+ // Test data used in a few places below
+ String dirName = tempDirectory.getPath();
+ String fileName = "input.tst";
+
+ // Check filename is preserved correctly
+ File d = new File(dirName);
+ File f = new File(d, fileName);
+ dirName = addTrailingSlash(dirName);
+ dirName += fileName;
+ assertEquals("Assert 1: Created incorrect file ",
+ dirName, f.getPath());
+
+ // Check null argument is handled
+ try {
+ f = new File(d, null);
+ fail("Assert 2: NullPointerException not thrown.");
+ } catch (NullPointerException e) {
+ // Expected.
+ }
+ }
+
+ public void test_ConstructorLjava_io_FileLjava_lang_String6() {
+ // Regression for HARMONY-46
+ File f1 = new File("a");
+ File f2 = new File("a/");
+ assertEquals("Trailing slash file name is incorrect", f1, f2);
+ }
+
+ /**
+ * java.io.File#File(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ String fileName = null;
+ try {
+ new File(fileName);
+ fail("NullPointerException Not Thrown.");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ fileName = addTrailingSlash(tempDirectory.getPath());
+ fileName += "input.tst";
+
+ File f = new File(fileName);
+ assertEquals("Created incorrect File", fileName, f.getPath());
+ }
+
+ /**
+ * java.io.File#File(java.lang.String, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_String() throws IOException {
+ String dirName = null;
+ String fileName = "input.tst";
+ File f = new File(dirName, fileName);
+ assertEquals("Test 1: Created Incorrect File",
+ new File("input.tst").getAbsolutePath(),
+ f.getAbsolutePath());
+
+ dirName = tempDirectory.getPath();
+ fileName = null;
+ try {
+ f = new File(dirName, fileName);
+ fail("NullPointerException Not Thrown.");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ fileName = "input.tst";
+ f = new File(dirName, fileName);
+ assertEquals("Test 2: Created Incorrect File",
+ addTrailingSlash(tempDirectory.getPath()) + "input.tst",
+ f.getPath());
+
+ // Regression test for HARMONY-382
+ String s = null;
+ f = new File("/abc");
+ File d = new File(s, "/abc");
+ assertEquals("Test3: Created Incorrect File", d.getAbsolutePath(), f
+ .getAbsolutePath());
+ }
+
+ /**
+ * java.io.File#File(java.lang.String, java.lang.String)
+ */
+ public void test_Constructor_String_String_112270() {
+ File ref1 = new File("/dir1/file1");
+
+ File file1 = new File("/", "/dir1/file1");
+ assertEquals("wrong result 1", ref1.getPath(), file1.getPath());
+ File file2 = new File("/", "//dir1/file1");
+ assertEquals("wrong result 2", ref1.getPath(), file2.getPath());
+
+ if (File.separatorChar == '\\') {
+ File file3 = new File("\\", "\\dir1\\file1");
+ assertEquals("wrong result 3", ref1.getPath(), file3.getPath());
+ File file4 = new File("\\", "\\\\dir1\\file1");
+ assertEquals("wrong result 4", ref1.getPath(), file4.getPath());
+ }
+
+ File ref2 = new File("/lib/content-types.properties");
+ File file5 = new File("/", "lib/content-types.properties");
+ assertEquals("wrong result 5", ref2.getPath(), file5.getPath());
+ }
+
+ /**
+ * java.io.File#File(java.io.File, java.lang.String)
+ */
+ public void test_Constructor_File_String_112270() {
+ File ref1 = new File("/dir1/file1");
+
+ File root = new File("/");
+ File file1 = new File(root, "/dir1/file1");
+ assertEquals("wrong result 1", ref1.getPath(), file1.getPath());
+ File file2 = new File(root, "//dir1/file1");
+ assertEquals("wrong result 2", ref1.getPath(), file2.getPath());
+
+ if (File.separatorChar == '\\') {
+ File file3 = new File(root, "\\dir1\\file1");
+ assertEquals("wrong result 3", ref1.getPath(), file3.getPath());
+ File file4 = new File(root, "\\\\dir1\\file1");
+ assertEquals("wrong result 4", ref1.getPath(), file4.getPath());
+ }
+
+ File ref2 = new File("/lib/content-types.properties");
+ File file5 = new File(root, "lib/content-types.properties");
+ assertEquals("wrong result 5", ref2.getPath(), file5.getPath());
+ }
+
+ /**
+ * java.io.File#File(java.net.URI)
+ */
+ public void test_ConstructorLjava_net_URI() throws URISyntaxException {
+ URI uri = null;
+ try {
+ new File(uri);
+ fail("NullPointerException Not Thrown.");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ // invalid file URIs
+ String[] uris = new String[] { "mailto:user@domain.com", // not
+ // hierarchical
+ "ftp:///path", // not file scheme
+ "//host/path/", // not absolute
+ "file://host/path", // non empty authority
+ "file:///path?query", // non empty query
+ "file:///path#fragment", // non empty fragment
+ "file:///path?", "file:///path#" };
+
+ for (int i = 0; i < uris.length; i++) {
+ uri = new URI(uris[i]);
+ try {
+ new File(uri);
+ fail("Expected IllegalArgumentException for new File(" + uri
+ + ")");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ // a valid File URI
+ File f = new File(new URI("file:///pa%20th/another\u20ac/pa%25th"));
+ assertTrue("Created incorrect File " + f.getPath(), f.getPath().equals(
+ File.separator + "pa th" + File.separator + "another\u20ac" + File.separator + "pa%th"));
+ }
+
+ /**
+ * java.io.File#canRead()
+ */
+ public void test_canRead() throws IOException {
+ // canRead only returns if the file exists so cannot be fully tested.
+ File f = new File(tempDirectory, platformId + "canRead.tst");
+ try {
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ assertTrue("canRead returned false", f.canRead());
+ } finally {
+ f.delete();
+ }
+ }
+
+ /**
+ * java.io.File#canWrite()
+ */
+ public void test_canWrite() throws IOException {
+ // canWrite only returns if the file exists so cannot be fully tested.
+ File f = new File(tempDirectory, platformId + "canWrite.tst");
+ try {
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ assertTrue("canWrite returned false", f.canWrite());
+ } finally {
+ f.delete();
+ }
+ }
+
+ /**
+ * java.io.File#compareTo(java.io.File)
+ */
+ public void test_compareToLjava_io_File() {
+ File f1 = new File("thisFile.file");
+ File f2 = new File("thisFile.file");
+ File f3 = new File("thatFile.file");
+ assertEquals("Equal files did not answer zero for compareTo", 0, f1
+ .compareTo(f2));
+ assertTrue("f3.compareTo(f1) did not result in value < 0", f3
+ .compareTo(f1) < 0);
+ assertTrue("f1.compareTo(f3) did not result in value > 0", f1
+ .compareTo(f3) > 0);
+ }
+
+ /**
+ * java.io.File#createNewFile()
+ */
+ public void test_createNewFile_EmptyString() {
+ File f = new File("");
+ try {
+ f.createNewFile();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.File#createNewFile()
+ */
+ public void test_createNewFile() throws IOException {
+ String base = tempDirectory.getPath();
+ boolean dirExists = true;
+ int numDir = 1;
+ File dir = new File(base, String.valueOf(numDir));
+ // Making sure that the directory does not exist.
+ while (dirExists) {
+ // If the directory exists, add one to the directory number
+ // (making it a new directory name.)
+ if (dir.exists()) {
+ numDir++;
+ dir = new File(base, String.valueOf(numDir));
+ } else {
+ dirExists = false;
+ }
+ }
+
+ // Test for trying to create a file in a directory that does not
+ // exist.
+ try {
+ // Try to create a file in a directory that does not exist
+ File f1 = new File(dir, "tempfile.tst");
+ f1.createNewFile();
+ fail("IOException not thrown");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ dir.mkdir();
+
+ File f1 = new File(dir, "tempfile.tst");
+ File f2 = new File(dir, "tempfile.tst");
+ f1.deleteOnExit();
+ f2.deleteOnExit();
+ dir.deleteOnExit();
+ assertFalse("File Should Not Exist", f1.isFile());
+ f1.createNewFile();
+ assertTrue("File Should Exist.", f1.isFile());
+ assertTrue("File Should Exist.", f2.isFile());
+ String dirName = f1.getParent();
+ if (!dirName.endsWith(File.separator)) {
+ dirName += File.separator;
+ }
+ assertEquals("File Saved To Wrong Directory.",
+ dir.getPath() + File.separator, dirName);
+ assertEquals("File Saved With Incorrect Name.", "tempfile.tst",
+ f1.getName());
+
+ // Test for creating a file that already exists.
+ assertFalse("File Already Exists, createNewFile Should Return False.",
+ f2.createNewFile());
+
+ // Test create an illegal file
+ String sep = File.separator;
+ f1 = new File(sep + "..");
+ try {
+ f1.createNewFile();
+ fail("should throw IOE");
+ } catch (IOException e) {
+ // expected;
+ }
+ f1 = new File(sep + "a" + sep + ".." + sep + ".." + sep);
+ try {
+ f1.createNewFile();
+ fail("should throw IOE");
+ } catch (IOException e) {
+ // expected;
+ }
+
+ // This test is invalid. createNewFile should return false
+ // not IOE when the file exists (in this case it exists and is
+ // a directory). TODO: We should probably replace this test
+ // with some that cover this behaviour. It might even be
+ // different on unix and windows since it directly reflects
+ // the open syscall behaviour.
+ //
+ // // Test create an exist path
+ // f1 = new File(base);
+ // try {
+ // assertFalse(f1.createNewFile());
+ // fail("should throw IOE");
+ // } catch (IOException e) {
+ // // expected;
+ // }
+ }
+
+ /**
+ * java.io.File#createTempFile(java.lang.String, java.lang.String)
+ */
+ public void test_createTempFileLjava_lang_StringLjava_lang_String()
+ throws IOException {
+ // Error protection against using a suffix without a "."?
+ File f1 = null;
+ File f2 = null;
+ try {
+ f1 = File.createTempFile("harmony-test-FileTest_tempFile_abc", ".tmp");
+ f2 = File.createTempFile("harmony-test-FileTest_tempFile_tf", null);
+
+ String fileLocation = addTrailingSlash(f1.getParent());
+
+ String tempDir = addTrailingSlash(System.getProperty("java.io.tmpdir"));
+
+ assertEquals(
+ "File did not save to the default temporary-file location.",
+ tempDir, fileLocation);
+
+ // Test to see if correct suffix was used to create the tempfile.
+ File currentFile;
+ String fileName;
+ // Testing two files, one with suffix ".tmp" and one with null
+ for (int i = 0; i < 2; i++) {
+ currentFile = i == 0 ? f1 : f2;
+ fileName = currentFile.getPath();
+ assertTrue("File Created With Incorrect Suffix.", fileName
+ .endsWith(".tmp"));
+ }
+
+ // Tests to see if the correct prefix was used to create the
+ // tempfiles.
+ fileName = f1.getName();
+ assertTrue("Test 1: File Created With Incorrect Prefix.", fileName
+ .startsWith("harmony-test-FileTest_tempFile_abc"));
+ fileName = f2.getName();
+ assertTrue("Test 2: File Created With Incorrect Prefix.", fileName
+ .startsWith("harmony-test-FileTest_tempFile_tf"));
+
+ // Tests for creating a tempfile with a filename shorter than 3
+ // characters.
+ try {
+ File f3 = File.createTempFile("ab", ".tst");
+ f3.delete();
+ fail("IllegalArgumentException Not Thrown.");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ File f3 = File.createTempFile("a", ".tst");
+ f3.delete();
+ fail("IllegalArgumentException Not Thrown.");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ File f3 = File.createTempFile("", ".tst");
+ f3.delete();
+ fail("IllegalArgumentException Not Thrown.");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } finally {
+ if (f1 != null) {
+ f1.delete();
+ }
+ if (f2 != null) {
+ f2.delete();
+ }
+ }
+ }
+
+ /**
+ * java.io.File#createTempFile(java.lang.String, java.lang.String,
+ *java.io.File)
+ */
+ public void test_createTempFileLjava_lang_StringLjava_lang_StringLjava_io_File()
+ throws IOException {
+ File f1 = null;
+ File f2 = null;
+ String base = System.getProperty("java.io.tmpdir");
+ try {
+ // Test to make sure that the tempfile was saved in the correct
+ // location and with the correct prefix/suffix.
+ f1 = File.createTempFile("harmony-test-FileTest_tempFile2_tf", null, null);
+ File dir = new File(base);
+ f2 = File.createTempFile("harmony-test-FileTest_tempFile2_tf", ".tmp", dir);
+ File currentFile;
+ String fileLocation;
+ String fileName;
+ for (int i = 0; i < 2; i++) {
+ currentFile = i == 0 ? f1 : f2;
+ fileLocation = addTrailingSlash(currentFile.getParent());
+ base = addTrailingSlash(base);
+ assertEquals(
+ "File not created in the default temporary-file location.",
+ base, fileLocation);
+ fileName = currentFile.getName();
+ assertTrue("File created with incorrect suffix.", fileName
+ .endsWith(".tmp"));
+ assertTrue("File created with incorrect prefix.", fileName
+ .startsWith("harmony-test-FileTest_tempFile2_tf"));
+ currentFile.delete();
+ }
+
+ // Test for creating a tempfile in a directory that does not exist.
+ int dirNumber = 1;
+ boolean dirExists = true;
+ // Set dir to a non-existent directory inside the temporary
+ // directory
+ dir = new File(base, String.valueOf(dirNumber));
+ // Making sure that the directory does not exist.
+ while (dirExists) {
+ // If the directory exists, add one to the directory number
+ // (making it
+ // a new directory name.)
+ if (dir.exists()) {
+ dirNumber++;
+ dir = new File(base, String.valueOf(dirNumber));
+ } else {
+ dirExists = false;
+ }
+ }
+ try {
+ // Try to create a file in a directory that does not exist
+ File f3 = File.createTempFile("harmony-test-FileTest_tempFile2_tf", null, dir);
+ f3.delete();
+ fail("IOException not thrown");
+ } catch (IOException e) {
+ // Expected
+ }
+ dir.delete();
+
+ // Tests for creating a tempfile with a filename shorter than 3
+ // characters.
+ try {
+ File f4 = File.createTempFile("ab", null, null);
+ f4.delete();
+ fail("IllegalArgumentException not thrown.");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ File f4 = File.createTempFile("a", null, null);
+ f4.delete();
+ fail("IllegalArgumentException not thrown.");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ File f4 = File.createTempFile("", null, null);
+ f4.delete();
+ fail("IllegalArgumentException not thrown.");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } finally {
+ if (f1 != null) {
+ f1.delete();
+ }
+ if (f2 != null) {
+ f1.delete();
+ }
+ }
+ }
+
+ /**
+ * java.io.File#delete()
+ */
+ public void test_delete() throws IOException {
+ File dir = new File(tempDirectory, platformId
+ + "filechk");
+ dir.mkdir();
+ assertTrue("Directory does not exist", dir.exists());
+ assertTrue("Directory is not directory", dir.isDirectory());
+ File f = new File(dir, "filechk.tst");
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ assertTrue("Error Creating File For Delete Test", f.exists());
+ dir.delete();
+ assertTrue("Directory Should Not Have Been Deleted.", dir.exists());
+ f.delete();
+ assertTrue("File Was Not Deleted", !f.exists());
+ dir.delete();
+ assertTrue("Directory Was Not Deleted", !dir.exists());
+ }
+
+ // GCH
+ // TODO : This test passes on Windows but fails on Linux with a
+ // java.lang.NoClassDefFoundError. Temporarily removing from the test
+ // suite while I investigate the cause.
+ // /**
+ // * java.io.File#deleteOnExit()
+ // */
+ // public void test_deleteOnExit() {
+ // File f1 = new File(System.getProperty("java.io.tmpdir"), platformId
+ // + "deleteOnExit.tst");
+ // try {
+ // FileOutputStream fos = new FileOutputStream(f1);
+ // fos.close();
+ // } catch (IOException e) {
+ // fail("Unexpected IOException During Test : " + e.getMessage());
+ // }
+ // assertTrue("File Should Exist.", f1.exists());
+ //
+ // try {
+ // Support_Exec.execJava(new String[] {
+ // "tests.support.Support_DeleteOnExitTest", f1.getPath() },
+ // null, true);
+ // } catch (IOException e) {
+ // fail("Unexpected IOException During Test + " + e.getMessage());
+ // } catch (InterruptedException e) {
+ // fail("Unexpected InterruptedException During Test: " + e);
+ // }
+ //
+ // boolean gone = !f1.exists();
+ // f1.delete();
+ // assertTrue("File Should Already Be Deleted.", gone);
+ // }
+
+ /**
+ * java.io.File#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() throws IOException {
+ File f1 = new File("filechk.tst");
+ File f2 = new File("filechk.tst");
+ File f3 = new File("xxxx");
+
+ assertTrue("Equality test failed", f1.equals(f2));
+ assertTrue("Files Should Not Return Equal.", !f1.equals(f3));
+
+ f1 = new File(tempDirectory, "casetest.tmp");
+ f2 = new File(tempDirectory, "CaseTest.tmp");
+ assertFalse(f1.equals(f2));
+ assertTrue(f1.createNewFile());
+ f1.delete();
+ }
+
+ /**
+ * java.io.File#exists()
+ */
+ public void test_exists() throws IOException {
+ File f = new File(tempDirectory, platformId
+ + "exists.tst");
+ assertTrue("Exists returned true for non-existent file", !f.exists());
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ assertTrue("Exists returned false file", f.exists());
+ f.delete();
+ }
+
+ /**
+ * java.io.File#getAbsoluteFile()
+ */
+ public void test_getAbsoluteFile() {
+ String base = addTrailingSlash(tempDirectory.getPath());
+ File f = new File(base, "temp.tst");
+ File f2 = f.getAbsoluteFile();
+ assertEquals("Test 1: Incorrect File Returned.", 0, f2.compareTo(f
+ .getAbsoluteFile()));
+ f = new File(base + "Temp" + File.separator + File.separator + "temp.tst");
+ f2 = f.getAbsoluteFile();
+ assertEquals("Test 2: Incorrect File Returned.", 0, f2.compareTo(f
+ .getAbsoluteFile()));
+ f = new File(base + File.separator + ".." + File.separator + "temp.tst");
+ f2 = f.getAbsoluteFile();
+ assertEquals("Test 3: Incorrect File Returned.", 0, f2.compareTo(f
+ .getAbsoluteFile()));
+ f.delete();
+ f2.delete();
+ }
+
+ /**
+ * java.io.File#getAbsolutePath()
+ */
+ public void test_getAbsolutePath() {
+ String base = addTrailingSlash(tempDirectory.getPath());
+ File f = new File(base, "temp.tst");
+ assertEquals("Test 1: Incorrect Path Returned.",
+ base + "temp.tst", f.getAbsolutePath());
+
+ f = new File(base + "Temp" + File.separator + File.separator + File.separator + "Testing" + File.separator
+ + "temp.tst");
+ assertEquals("Test 2: Incorrect Path Returned.",
+ base + "Temp" + File.separator + "Testing" + File.separator + "temp.tst",
+ f.getAbsolutePath());
+
+ f = new File(base + "a" + File.separator + File.separator + ".." + File.separator + "temp.tst");
+ assertEquals("Test 3: Incorrect Path Returned.",
+ base + "a" + File.separator + ".." + File.separator + "temp.tst",
+ f.getAbsolutePath());
+ f.delete();
+ }
+
+ /**
+ * java.io.File#getCanonicalFile()
+ */
+ public void test_getCanonicalFile() throws IOException {
+ String base = addTrailingSlash(tempDirectory.getPath());
+ File f = new File(base, "temp.tst");
+ File f2 = f.getCanonicalFile();
+ assertEquals("Test 1: Incorrect File Returned.", 0, f2
+ .getCanonicalFile().compareTo(f.getCanonicalFile()));
+ f = new File(base + "Temp" + File.separator + File.separator + "temp.tst");
+ f2 = f.getCanonicalFile();
+ assertEquals("Test 2: Incorrect File Returned.", 0, f2
+ .getCanonicalFile().compareTo(f.getCanonicalFile()));
+ f = new File(base + "Temp" + File.separator + File.separator + ".." + File.separator + "temp.tst");
+ f2 = f.getCanonicalFile();
+ assertEquals("Test 3: Incorrect File Returned.", 0, f2
+ .getCanonicalFile().compareTo(f.getCanonicalFile()));
+
+ // Test for when long directory/file names in Windows
+ boolean onWindows = File.separatorChar == '\\';
+ if (onWindows) {
+ File testdir = new File(base, "long-" + platformId);
+ testdir.mkdir();
+ File dir = new File(testdir, "longdirectory" + platformId);
+ try {
+ dir.mkdir();
+ f = new File(dir, "longfilename.tst");
+ f2 = f.getCanonicalFile();
+ assertEquals("Test 4: Incorrect File Returned.", 0, f2
+ .getCanonicalFile().compareTo(f.getCanonicalFile()));
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ f2 = new File(testdir + File.separator + "longdi~1" + File.separator
+ + "longfi~1.tst");
+ File canonicalf2 = f2.getCanonicalFile();
+ /*
+ * If the "short file name" doesn't exist, then assume that the
+ * 8.3 file name compatibility is disabled.
+ */
+ if (canonicalf2.exists()) {
+ assertTrue("Test 5: Incorrect File Returned: "
+ + canonicalf2, canonicalf2.compareTo(f
+ .getCanonicalFile()) == 0);
+ }
+ } finally {
+ f.delete();
+ f2.delete();
+ dir.delete();
+ testdir.delete();
+ }
+ }
+ }
+
+ /**
+ * java.io.File#getCanonicalPath()
+ */
+ public void test_getCanonicalPath() throws IOException {
+ // Should work for Unix/Windows.
+ String dots = "..";
+ String base = tempDirectory.getCanonicalPath();
+ base = addTrailingSlash(base);
+ File f = new File(base, "temp.tst");
+ assertEquals("Test 1: Incorrect Path Returned.", base + "temp.tst", f
+ .getCanonicalPath());
+ f = new File(base + "Temp" + File.separator + dots + File.separator + "temp.tst");
+ assertEquals("Test 2: Incorrect Path Returned.", base + "temp.tst", f
+ .getCanonicalPath());
+
+ // Finding a non-existent directory for tests 3 and 4
+ // This is necessary because getCanonicalPath is case sensitive and
+ // could cause a failure in the test if the directory exists but with
+ // different case letters (e.g "Temp" and "temp")
+ int dirNumber = 1;
+ boolean dirExists = true;
+ File dir1 = new File(base, String.valueOf(dirNumber));
+ while (dirExists) {
+ if (dir1.exists()) {
+ dirNumber++;
+ dir1 = new File(base, String.valueOf(dirNumber));
+ } else {
+ dirExists = false;
+ }
+ }
+ f = new File(base + dirNumber + File.separator + dots + File.separator + dirNumber
+ + File.separator + "temp.tst");
+ assertEquals("Test 3: Incorrect Path Returned.", base + dirNumber
+ + File.separator + "temp.tst", f.getCanonicalPath());
+ f = new File(base + dirNumber + File.separator + "Temp" + File.separator + dots + File.separator
+ + "Test" + File.separator + "temp.tst");
+ assertEquals("Test 4: Incorrect Path Returned.", base + dirNumber
+ + File.separator + "Test" + File.separator + "temp.tst", f.getCanonicalPath());
+
+ f = new File(base + "1234.567");
+ assertEquals("Test 5: Incorrect Path Returned.", base + "1234.567", f
+ .getCanonicalPath());
+
+ // Test for long file names on Windows
+ boolean onWindows = (File.separatorChar == '\\');
+ if (onWindows) {
+ File testdir = new File(base, "long-" + platformId);
+ testdir.mkdir();
+ File f1 = new File(testdir, "longfilename" + platformId + ".tst");
+ FileOutputStream fos = new FileOutputStream(f1);
+ File f2 = null, f3 = null, dir2 = null;
+ try {
+ fos.close();
+ String dirName1 = f1.getCanonicalPath();
+ File f4 = new File(testdir, "longfi~1.tst");
+ /*
+ * If the "short file name" doesn't exist, then assume that the
+ * 8.3 file name compatibility is disabled.
+ */
+ if (f4.exists()) {
+ String dirName2 = f4.getCanonicalPath();
+ assertEquals("Test 6: Incorrect Path Returned.", dirName1,
+ dirName2);
+ dir2 = new File(testdir, "longdirectory" + platformId);
+ if (!dir2.exists()) {
+ assertTrue("Could not create dir: " + dir2, dir2
+ .mkdir());
+ }
+ f2 = new File(testdir.getPath() + File.separator + "longdirectory"
+ + platformId + File.separator + "Test" + File.separator + dots
+ + File.separator + "longfilename.tst");
+ FileOutputStream fos2 = new FileOutputStream(f2);
+ fos2.close();
+ dirName1 = f2.getCanonicalPath();
+ f3 = new File(testdir.getPath() + File.separator + "longdi~1"
+ + File.separator + "Test" + File.separator + dots + File.separator
+ + "longfi~1.tst");
+ dirName2 = f3.getCanonicalPath();
+ assertEquals("Test 7: Incorrect Path Returned.", dirName1,
+ dirName2);
+ }
+ } finally {
+ f1.delete();
+ if (f2 != null) {
+ f2.delete();
+ }
+ if (dir2 != null) {
+ dir2.delete();
+ }
+ testdir.delete();
+ }
+ }
+ }
+
+ /**
+ * java.io.File#getName()
+ */
+ public void test_getName() {
+ File f = new File("name.tst");
+ assertEquals("Test 1: Returned incorrect name", "name.tst", f.getName());
+
+ f = new File("");
+ assertEquals("Test 2: Returned incorrect name", "", f.getName());
+
+ f.delete();
+ }
+
+ /**
+ * java.io.File#getParent()
+ */
+ public void test_getParent() {
+ File f = new File("p.tst");
+ assertNull("Incorrect path returned", f.getParent());
+ f = new File("/user/home/p.tst");
+ assertEquals("Incorrect path returned",
+ "/user/home", f.getParent());
+
+ File f1 = new File("/directory");
+ assertEquals("Wrong parent test 1", File.separator, f1.getParent());
+ f1 = new File("/directory/file");
+ assertEquals("Wrong parent test 2",
+ File.separator + "directory", f1.getParent());
+ f1 = new File("directory/file");
+ assertEquals("Wrong parent test 3", "directory", f1.getParent());
+ f1 = new File("/");
+ assertNull("Wrong parent test 4", f1.getParent());
+ f1 = new File("directory");
+ assertNull("Wrong parent test 5", f1.getParent());
+
+ if (File.separatorChar == '\\' && new File("d:/").isAbsolute()) {
+ f1 = new File("d:/directory");
+ assertEquals("Wrong parent test 1a", "d:" + File.separator, f1.getParent());
+ f1 = new File("d:/directory/file");
+ assertEquals("Wrong parent test 2a",
+ "d:" + File.separator + "directory", f1.getParent());
+ f1 = new File("d:directory/file");
+ assertEquals("Wrong parent test 3a", "d:directory", f1.getParent());
+ f1 = new File("d:/");
+ assertNull("Wrong parent test 4a", f1.getParent());
+ f1 = new File("d:directory");
+ assertEquals("Wrong parent test 5a", "d:", f1.getParent());
+ }
+ }
+
+ /**
+ * java.io.File#getParentFile()
+ */
+ public void test_getParentFile() {
+ File f = new File("tempfile.tst");
+ assertNull("Incorrect path returned", f.getParentFile());
+ f = new File(tempDirectory, "tempfile1.tmp");
+ File f2 = new File(tempDirectory, "tempfile2.tmp");
+ File f3 = new File(tempDirectory, "/a/tempfile.tmp");
+ assertEquals("Incorrect File Returned", 0, f.getParentFile().compareTo(
+ f2.getParentFile()));
+ assertTrue("Incorrect File Returned", f.getParentFile().compareTo(
+ f3.getParentFile()) != 0);
+ f.delete();
+ f2.delete();
+ f3.delete();
+ }
+
+ /**
+ * java.io.File#getPath()
+ */
+ public void test_getPath() {
+ String base = System.getProperty("user.home");
+ String fname;
+ File f1;
+ if (!base.regionMatches((base.length() - 1), File.separator, 0, 1)) {
+ base += File.separator;
+ }
+ fname = base + "filechk.tst";
+ f1 = new File(base, "filechk.tst");
+ File f2 = new File("filechk.tst");
+ File f3 = new File("c:");
+ File f4 = new File(base + "a" + File.separator + File.separator + ".." + File.separator
+ + "filechk.tst");
+ assertEquals("getPath returned incorrect path(f1)",
+ fname, f1.getPath());
+ assertEquals("getPath returned incorrect path(f2)",
+ "filechk.tst", f2.getPath());
+ assertEquals("getPath returned incorrect path(f3)", "c:", f3.getPath());
+ assertEquals("getPath returned incorrect path(f4)",
+ base + "a" + File.separator + ".." + File.separator + "filechk.tst",
+ f4.getPath());
+ f1.delete();
+ f2.delete();
+ f3.delete();
+ f4.delete();
+
+ // Regression for HARMONY-444
+ File file;
+ String separator = File.separator;
+
+ file = new File((File) null, "x/y/z");
+ assertEquals("x" + separator + "y" + separator + "z", file.getPath());
+
+ file = new File((String) null, "x/y/z");
+ assertEquals("x" + separator + "y" + separator + "z", file.getPath());
+
+ // Regression for HARMONY-829
+ String f1ParentName = "01";
+ f1 = new File(f1ParentName, "");
+ assertEquals(f1ParentName, f1.getPath());
+
+ String f2ParentName = "0";
+ f2 = new File(f2ParentName, "");
+
+ assertEquals(-1, f2.compareTo(f1));
+ assertEquals(1, f1.compareTo(f2));
+
+ File parent = tempDirectory;
+ f3 = new File(parent, "");
+
+ assertEquals(parent.getPath(), f3.getPath());
+
+ File file0 = new File("");
+ assertEquals("", file0.getPath());
+
+ // Regression for HARMONY-3869
+ // Behavior here is system-dependent according to the RI javadoc.
+ String path1 = new File("", "").getPath();
+ assertTrue(path1.equals(File.separator) || path1.isEmpty());
+ String path2 = new File(new File(""), "").getPath();
+ assertTrue(path2.equals(File.separator) || path2.isEmpty());
+ }
+
+ /**
+ * java.io.File#hashCode()
+ */
+ public void test_hashCode() {
+ // Regression for HARMONY-53
+ File mfile = new File("SoMe FiLeNaMe"); // Mixed case
+ File lfile = new File("some filename"); // Lower case
+
+ if (mfile.equals(lfile)) {
+ assertTrue("Assert 0: wrong hashcode", mfile.hashCode() == lfile
+ .hashCode());
+ } else {
+ assertFalse("Assert 1: wrong hashcode", mfile.hashCode() == lfile
+ .hashCode());
+ }
+ }
+
+ /**
+ * java.io.File#isAbsolute()
+ */
+ public void test_isAbsolute() {
+ if (File.separatorChar == '\\') {
+ File f = new File("c:\\test");
+ File f1 = new File("\\test");
+ // One or the other should be absolute on Windows or CE
+ assertTrue("Absolute returned false", (f.isAbsolute() && !f1
+ .isAbsolute())
+ || (!f.isAbsolute() && f1.isAbsolute()));
+
+ assertTrue(new File("C:/").isAbsolute());
+ assertTrue(new File("f:/").isAbsolute());
+ assertTrue(new File("f:\\").isAbsolute());
+ assertFalse(new File("f:").isAbsolute());
+ assertFalse(new File("K:").isAbsolute());
+ assertTrue(new File("\\\\").isAbsolute());
+ assertTrue(new File("\\\\\\").isAbsolute());
+ assertTrue(new File("\\\\hello").isAbsolute());
+ assertFalse(new File("\\").isAbsolute());
+ assertFalse(new File("/").isAbsolute());
+ } else {
+ File f = new File("/test");
+ File f1 = new File("\\test");
+ assertTrue("Absolute returned false", f.isAbsolute());
+ assertFalse("Absolute returned true", f1.isAbsolute());
+ assertTrue(new File("//test").isAbsolute());
+ assertFalse(new File("test").isAbsolute());
+ assertFalse(new File("c:/").isAbsolute());
+ assertFalse(new File("c:\\").isAbsolute());
+ assertFalse(new File("c:").isAbsolute());
+ assertFalse(new File("\\").isAbsolute());
+ assertFalse(new File("\\\\").isAbsolute());
+ }
+ assertTrue("Non-Absolute returned true", !new File("../test")
+ .isAbsolute());
+ }
+
+ /**
+ * java.io.File#isDirectory()
+ */
+ public void test_isDirectory() {
+ String base = addTrailingSlash(tempDirectory.getPath());
+ File f = new File(base);
+ assertTrue("Test 1: Directory Returned False", f.isDirectory());
+ f = new File(base + "zxzxzxz" + platformId);
+ assertTrue("Test 2: (Not Created) Directory Returned True.", !f
+ .isDirectory());
+ f.mkdir();
+ try {
+ assertTrue("Test 3: Directory Returned False.", f.isDirectory());
+ } finally {
+ f.delete();
+ }
+ }
+
+ /**
+ * java.io.File#isFile()
+ */
+ public void test_isFile() throws IOException {
+ String base = tempDirectory.getPath();
+ File f = new File(base);
+ assertFalse("Directory Returned True As Being A File.", f.isFile());
+
+ base = addTrailingSlash(base);
+ f = new File(base, platformId + "amiafile");
+ assertTrue("Non-existent File Returned True", !f.isFile());
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ assertTrue("File returned false", f.isFile());
+ f.delete();
+ }
+
+ public void test_isHidden() throws IOException, InterruptedException {
+ boolean onUnix = File.separatorChar == '/';
+ assertTrue(onUnix);
+
+ // On Unix hidden files are marked with a "." at the beginning
+ // of the file name.
+ File f1 = File.createTempFile("harmony-test-FileTest_notHidden_", ".tmp");
+ File f2 = File.createTempFile(".harmony-test-FileTest_isHidden_", ".tmp");
+ assertFalse(f1.isHidden());
+ assertTrue(f2.isHidden());
+ // We can still delete hidden files.
+ assertTrue(f2.delete());
+ f1.delete();
+ }
+
+ /**
+ * java.io.File#lastModified()
+ */
+ public void test_lastModified() throws IOException {
+ File f = new File(System.getProperty("java.io.tmpdir"), platformId
+ + "lModTest.tst");
+ f.delete();
+ long lastModifiedTime = f.lastModified();
+ assertEquals("LastModified Time Should Have Returned 0.", 0,
+ lastModifiedTime);
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ f.setLastModified(315550800000L);
+ lastModifiedTime = f.lastModified();
+ assertEquals("LastModified Time Incorrect",
+ 315550800000L, lastModifiedTime);
+ f.delete();
+
+ // Regression for HARMONY-2146
+ f = new File("/../");
+ assertTrue(f.lastModified() > 0);
+ }
+
+ /**
+ * java.io.File#length()
+ */
+ public void test_length() throws IOException {
+ File f = new File(tempDirectory, platformId
+ + "input.tst");
+ assertEquals("File Length Should Have Returned 0.", 0, f.length());
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.write(fileString.getBytes());
+ fos.close();
+ assertEquals("Incorrect file length returned",
+ fileString.length(), f.length());
+ f.delete();
+
+ // regression test for HARMONY-1497
+ f = File.createTempFile("test", "tmp");
+ f.deleteOnExit();
+ RandomAccessFile raf = new RandomAccessFile(f, "rwd");
+ raf.write(0x41);
+ assertEquals(1, f.length());
+ }
+
+ /**
+ * java.io.File#list()
+ */
+ public void test_list() throws IOException {
+ String base = tempDirectory.getPath();
+ // Old test left behind "garbage files" so this time it creates a
+ // directory that is guaranteed not to already exist (and deletes it
+ // afterward.)
+ int dirNumber = 1;
+ boolean dirExists = true;
+ File dir = null;
+ dir = new File(base, platformId + String.valueOf(dirNumber));
+ while (dirExists) {
+ if (dir.exists()) {
+ dirNumber++;
+ dir = new File(base, String.valueOf(dirNumber));
+ } else {
+ dirExists = false;
+ }
+ }
+
+ String[] flist = dir.list();
+
+ assertNull("Method list() Should Have Returned null.", flist);
+
+ assertTrue("Could not create parent directory for list test", dir
+ .mkdir());
+
+ String[] files = { "mtzz1.xx", "mtzz2.xx", "mtzz3.yy", "mtzz4.yy" };
+ try {
+ assertEquals(
+ "Method list() Should Have Returned An Array Of Length 0.",
+ 0, dir.list().length);
+
+ File file = new File(dir, "notADir.tst");
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.close();
+ assertNull(
+ "listFiles Should Have Returned Null When Used On A File Instead Of A Directory.",
+ file.list());
+ } finally {
+ file.delete();
+ }
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ }
+
+ flist = dir.list();
+ if (flist.length != files.length) {
+ fail("Incorrect list returned");
+ }
+
+ // Checking to make sure the correct files were are listed in the
+ // array.
+ boolean[] check = new boolean[flist.length];
+ for (int i = 0; i < check.length; i++) {
+ check[i] = false;
+ }
+ for (int i = 0; i < files.length; i++) {
+ for (int j = 0; j < flist.length; j++) {
+ if (flist[j].equals(files[i])) {
+ check[i] = true;
+ break;
+ }
+ }
+ }
+ int checkCount = 0;
+ for (int i = 0; i < check.length; i++) {
+ if (check[i] == false) {
+ checkCount++;
+ }
+ }
+ assertEquals("Invalid file returned in listing", 0, checkCount);
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ f.delete();
+ }
+
+ assertTrue("Could not delete parent directory for list test.", dir
+ .delete());
+ } finally {
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ f.delete();
+ }
+ dir.delete();
+ }
+ }
+
+ /**
+ * java.io.File#listFiles()
+ */
+ public void test_listFiles() throws IOException, InterruptedException {
+ String base = tempDirectory.getPath();
+ // Finding a non-existent directory to create.
+ int dirNumber = 1;
+ boolean dirExists = true;
+ File dir = new File(base, platformId + String.valueOf(dirNumber));
+ // Making sure that the directory does not exist.
+ while (dirExists) {
+ // If the directory exists, add one to the directory number
+ // (making it a new directory name.)
+ if (dir.exists()) {
+ dirNumber++;
+ dir = new File(base, String.valueOf(dirNumber));
+ } else {
+ dirExists = false;
+ }
+ }
+ // Test for attempting to call listFiles on a non-existent directory.
+ assertNull("listFiles Should Return Null.", dir.listFiles());
+
+ assertTrue("Failed To Create Parent Directory.", dir.mkdir());
+
+ String[] files = { "1.tst", "2.tst", "3.tst", "" };
+ try {
+ assertEquals("listFiles Should Return An Array Of Length 0.", 0,
+ dir.listFiles().length);
+
+ File file = new File(dir, "notADir.tst");
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.close();
+ assertNull(
+ "listFiles Should Have Returned Null When Used On A File Instead Of A Directory.",
+ file.listFiles());
+ } finally {
+ file.delete();
+ }
+
+ for (int i = 0; i < (files.length - 1); i++) {
+ File f = new File(dir, files[i]);
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ }
+
+ new File(dir, "doesNotExist.tst");
+ File[] flist = dir.listFiles();
+
+ // Test to make sure that only the 3 files that were created are
+ // listed.
+ assertEquals("Incorrect Number Of Files Returned.", 3, flist.length);
+
+ // Test to make sure that listFiles can read hidden files.
+ boolean onUnix = File.separatorChar == '/';
+ boolean onWindows = File.separatorChar == '\\';
+ if (onWindows) {
+ files[3] = "4.tst";
+ File f = new File(dir, "4.tst");
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ Runtime r = Runtime.getRuntime();
+ Process p = r.exec("attrib +h \"" + f.getPath() + "\"");
+ p.waitFor();
+ }
+ if (onUnix) {
+ files[3] = ".4.tst";
+ File f = new File(dir, ".4.tst");
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ }
+ flist = dir.listFiles();
+ assertEquals("Incorrect Number Of Files Returned.", 4, flist.length);
+
+ // Checking to make sure the correct files were are listed in
+ // the array.
+ boolean[] check = new boolean[flist.length];
+ for (int i = 0; i < check.length; i++) {
+ check[i] = false;
+ }
+ for (int i = 0; i < files.length; i++) {
+ for (int j = 0; j < flist.length; j++) {
+ if (flist[j].getName().equals(files[i])) {
+ check[i] = true;
+ break;
+ }
+ }
+ }
+ int checkCount = 0;
+ for (int i = 0; i < check.length; i++) {
+ if (check[i] == false) {
+ checkCount++;
+ }
+ }
+ assertEquals("Invalid file returned in listing", 0, checkCount);
+
+ if (onWindows) {
+ Runtime r = Runtime.getRuntime();
+ Process p = r.exec("attrib -h \""
+ + new File(dir, files[3]).getPath() + "\"");
+ p.waitFor();
+ }
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ f.delete();
+ }
+ assertTrue("Parent Directory Not Deleted.", dir.delete());
+ } finally {
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ f.delete();
+ }
+ dir.delete();
+ }
+ }
+
+ /**
+ * java.io.File#listFiles(java.io.FileFilter)
+ */
+ public void test_listFilesLjava_io_FileFilter() throws IOException {
+ String base = System.getProperty("java.io.tmpdir");
+ // Finding a non-existent directory to create.
+ int dirNumber = 1;
+ boolean dirExists = true;
+ File baseDir = new File(base, platformId + String.valueOf(dirNumber));
+ // Making sure that the directory does not exist.
+ while (dirExists) {
+ // If the directory exists, add one to the directory number (making
+ // it a new directory name.)
+ if (baseDir.exists()) {
+ dirNumber++;
+ baseDir = new File(base, String.valueOf(dirNumber));
+ } else {
+ dirExists = false;
+ }
+ }
+
+ // Creating a filter that catches directories.
+ FileFilter dirFilter = new FileFilter() {
+ public boolean accept(File f) {
+ return f.isDirectory();
+ }
+ };
+
+ assertNull("listFiles Should Return Null.", baseDir
+ .listFiles(dirFilter));
+
+ assertTrue("Failed To Create Parent Directory.", baseDir.mkdir());
+
+ File dir1 = null;
+ String[] files = { "1.tst", "2.tst", "3.tst" };
+ try {
+ assertEquals("listFiles Should Return An Array Of Length 0.", 0,
+ baseDir.listFiles(dirFilter).length);
+
+ File file = new File(baseDir, "notADir.tst");
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.close();
+ assertNull(
+ "listFiles Should Have Returned Null When Used On A File Instead Of A Directory.",
+ file.listFiles(dirFilter));
+ } finally {
+ file.delete();
+ }
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(baseDir, files[i]);
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ }
+ dir1 = new File(baseDir, "Temp1");
+ dir1.mkdir();
+
+ // Creating a filter that catches files.
+ FileFilter fileFilter = new FileFilter() {
+ public boolean accept(File f) {
+ return f.isFile();
+ }
+ };
+
+ // Test to see if the correct number of directories are returned.
+ File[] directories = baseDir.listFiles(dirFilter);
+ assertEquals("Incorrect Number Of Directories Returned.", 1,
+ directories.length);
+
+ // Test to see if the directory was saved with the correct name.
+ assertEquals("Incorrect Directory Returned.", 0, directories[0]
+ .compareTo(dir1));
+
+ // Test to see if the correct number of files are returned.
+ File[] flist = baseDir.listFiles(fileFilter);
+ assertEquals("Incorrect Number Of Files Returned.",
+ files.length, flist.length);
+
+ // Checking to make sure the correct files were are listed in the
+ // array.
+ boolean[] check = new boolean[flist.length];
+ for (int i = 0; i < check.length; i++) {
+ check[i] = false;
+ }
+ for (int i = 0; i < files.length; i++) {
+ for (int j = 0; j < flist.length; j++) {
+ if (flist[j].getName().equals(files[i])) {
+ check[i] = true;
+ break;
+ }
+ }
+ }
+ int checkCount = 0;
+ for (int i = 0; i < check.length; i++) {
+ if (check[i] == false) {
+ checkCount++;
+ }
+ }
+ assertEquals("Invalid file returned in listing", 0, checkCount);
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(baseDir, files[i]);
+ f.delete();
+ }
+ dir1.delete();
+ assertTrue("Parent Directory Not Deleted.", baseDir.delete());
+ } finally {
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(baseDir, files[i]);
+ f.delete();
+ }
+ if (dir1 != null) {
+ dir1.delete();
+ }
+ baseDir.delete();
+ }
+ }
+
+ /**
+ * java.io.File#listFiles(java.io.FilenameFilter)
+ */
+ public void test_listFilesLjava_io_FilenameFilter() throws IOException {
+ String base = System.getProperty("java.io.tmpdir");
+ // Finding a non-existent directory to create.
+ int dirNumber = 1;
+ boolean dirExists = true;
+ File dir = new File(base, platformId + String.valueOf(dirNumber));
+ // Making sure that the directory does not exist.
+ while (dirExists) {
+ // If the directory exists, add one to the directory number (making
+ // it a new directory name.)
+ if (dir.exists()) {
+ dirNumber++;
+ dir = new File(base, platformId + String.valueOf(dirNumber));
+ } else {
+ dirExists = false;
+ }
+ }
+
+ // Creating a filter that catches "*.tst" files.
+ FilenameFilter tstFilter = new FilenameFilter() {
+ public boolean accept(File f, String fileName) {
+ return fileName.endsWith(".tst");
+ }
+ };
+
+ assertNull("listFiles Should Return Null.", dir.listFiles(tstFilter));
+
+ assertTrue("Failed To Create Parent Directory.", dir.mkdir());
+
+ String[] files = { "1.tst", "2.tst", "3.tmp" };
+ try {
+ assertEquals("listFiles Should Return An Array Of Length 0.", 0,
+ dir.listFiles(tstFilter).length);
+
+ File file = new File(dir, "notADir.tst");
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.close();
+ assertNull(
+ "listFiles Should Have Returned Null When Used On A File Instead Of A Directory.",
+ file.listFiles(tstFilter));
+ } finally {
+ file.delete();
+ }
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ }
+
+ // Creating a filter that catches "*.tmp" files.
+ FilenameFilter tmpFilter = new FilenameFilter() {
+ public boolean accept(File f, String fileName) {
+ // If the suffix is ".tmp" then send it to the array
+ if (fileName.endsWith(".tmp")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+
+ // Tests to see if the correct number of files were returned.
+ File[] flist = dir.listFiles(tstFilter);
+ assertEquals("Incorrect Number Of Files Passed Through tstFilter.",
+ 2, flist.length);
+ for (int i = 0; i < flist.length; i++) {
+ assertTrue("File Should Not Have Passed The tstFilter.",
+ flist[i].getPath().endsWith(".tst"));
+ }
+
+ flist = dir.listFiles(tmpFilter);
+ assertEquals("Incorrect Number Of Files Passed Through tmpFilter.",
+ 1, flist.length);
+ assertTrue("File Should Not Have Passed The tmpFilter.", flist[0]
+ .getPath().endsWith(".tmp"));
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ f.delete();
+ }
+ assertTrue("Parent Directory Not Deleted.", dir.delete());
+ } finally {
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ f.delete();
+ }
+ dir.delete();
+ }
+ }
+
+ /**
+ * java.io.File#list(java.io.FilenameFilter)
+ */
+ public void test_listLjava_io_FilenameFilter() throws IOException {
+ String base = tempDirectory.getPath();
+ // Old test left behind "garbage files" so this time it creates a
+ // directory that is guaranteed not to already exist (and deletes it
+ // afterward.)
+ int dirNumber = 1;
+ boolean dirExists = true;
+ File dir = new File(base, platformId + String.valueOf(dirNumber));
+ while (dirExists) {
+ if (dir.exists()) {
+ dirNumber++;
+ dir = new File(base, String.valueOf(dirNumber));
+ } else {
+ dirExists = false;
+ }
+ }
+
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return !name.equals("mtzz1.xx");
+ }
+ };
+
+ String[] flist = dir.list(filter);
+ assertNull("Method list(FilenameFilter) Should Have Returned Null.",
+ flist);
+
+ assertTrue("Could not create parent directory for test", dir.mkdir());
+
+ String[] files = { "mtzz1.xx", "mtzz2.xx", "mtzz3.yy", "mtzz4.yy" };
+ try {
+ /*
+ * Do not return null when trying to use list(Filename Filter) on a
+ * file rather than a directory. All other "list" methods return
+ * null for this test case.
+ */
+ /*
+ * File file = new File(dir, "notADir.tst"); try { FileOutputStream
+ * fos = new FileOutputStream(file); fos.close(); } catch
+ * (IOException e) { fail("Unexpected IOException During Test."); }
+ * flist = dir.list(filter); assertNull("listFiles Should Have
+ * Returned Null When Used On A File Instead Of A Directory.",
+ * flist); file.delete();
+ */
+
+ flist = dir.list(filter);
+ assertEquals("Array Of Length 0 Should Have Returned.", 0,
+ flist.length);
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.close();
+ }
+
+ flist = dir.list(filter);
+
+ assertEquals("Incorrect list returned", flist.length,
+ files.length - 1);
+
+ // Checking to make sure the correct files were are listed in the
+ // array.
+ boolean[] check = new boolean[flist.length];
+ for (int i = 0; i < check.length; i++) {
+ check[i] = false;
+ }
+ String[] wantedFiles = { "mtzz2.xx", "mtzz3.yy", "mtzz4.yy" };
+ for (int i = 0; i < wantedFiles.length; i++) {
+ for (int j = 0; j < flist.length; j++) {
+ if (flist[j].equals(wantedFiles[i])) {
+ check[i] = true;
+ break;
+ }
+ }
+ }
+ int checkCount = 0;
+ for (int i = 0; i < check.length; i++) {
+ if (check[i] == false) {
+ checkCount++;
+ }
+ }
+ assertEquals("Invalid file returned in listing", 0, checkCount);
+
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ f.delete();
+ }
+ assertTrue("Could not delete parent directory for test.", dir
+ .delete());
+ } finally {
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(dir, files[i]);
+ f.delete();
+ }
+ dir.delete();
+ }
+ }
+
+ /**
+ * java.io.File#listRoots()
+ */
+ public void test_listRoots() {
+ File[] roots = File.listRoots();
+ boolean onUnix = File.separatorChar == '/';
+ boolean onWindows = File.separatorChar == '\\';
+ if (onUnix) {
+ assertEquals("Incorrect Number Of Root Directories.", 1,
+ roots.length);
+ String fileLoc = roots[0].getPath();
+ assertTrue("Incorrect Root Directory Returned.", fileLoc
+ .startsWith(File.separator));
+ } else if (onWindows) {
+ // Need better test for Windows
+ assertTrue("Incorrect Number Of Root Directories.",
+ roots.length > 0);
+ }
+ }
+
+ /**
+ * java.io.File#mkdir()
+ */
+ public void test_mkdir() throws IOException {
+ String base = tempDirectory.getPath();
+ // Old test left behind "garbage files" so this time it creates a
+ // directory that is guaranteed not to already exist (and deletes it
+ // afterward.)
+ int dirNumber = 1;
+ boolean dirExists = true;
+ File dir = new File(base, String.valueOf(dirNumber));
+ while (dirExists) {
+ if (dir.exists()) {
+ dirNumber++;
+ dir = new File(base, String.valueOf(dirNumber));
+ } else {
+ dirExists = false;
+ }
+ }
+
+ assertTrue("mkdir failed", dir.mkdir());
+ assertTrue("mkdir worked but exists check failed", dir.exists());
+ dir.deleteOnExit();
+
+ String longDirName = "abcdefghijklmnopqrstuvwx";// 24 chars
+ String newbase = new String(dir + File.separator);
+ StringBuilder sb = new StringBuilder(dir + File.separator);
+ StringBuilder sb2 = new StringBuilder(dir + File.separator);
+
+ // Test make a long path
+ while (dir.getCanonicalPath().length() < 256 - longDirName.length()) {
+ sb.append(longDirName + File.separator);
+ dir = new File(sb.toString());
+ assertTrue("mkdir failed", dir.mkdir());
+ assertTrue("mkdir worked but exists check failed", dir.exists());
+ dir.deleteOnExit();
+ }
+
+ while (dir.getCanonicalPath().length() < 256) {
+ sb.append(0);
+ dir = new File(sb.toString());
+ assertTrue("mkdir " + dir.getCanonicalPath().length() + " failed",
+ dir.mkdir());
+ assertTrue("mkdir " + dir.getCanonicalPath().length()
+ + " worked but exists check failed", dir.exists());
+ dir.deleteOnExit();
+ }
+ dir = new File(sb2.toString());
+ // Test make many paths
+ while (dir.getCanonicalPath().length() < 256) {
+ sb2.append(0);
+ dir = new File(sb2.toString());
+ assertTrue("mkdir " + dir.getCanonicalPath().length() + " failed",
+ dir.mkdir());
+ assertTrue("mkdir " + dir.getCanonicalPath().length()
+ + " worked but exists check failed", dir.exists());
+ dir.deleteOnExit();
+ }
+
+ // Regression test for HARMONY-3656
+ String[] ss = { "dir\u3400", "abc", "abc@123", "!@#$%^&",
+ "~\u4E00!\u4E8C@\u4E09$", "\u56DB\u4E94\u516D",
+ "\u4E03\u516B\u4E5D" };
+ for (int i = 0; i < ss.length; i++) {
+ dir = new File(newbase, ss[i]);
+ assertTrue("mkdir " + dir.getCanonicalPath() + " failed",
+ dir.mkdir());
+ assertTrue("mkdir " + dir.getCanonicalPath()
+ + " worked but exists check failed",
+ dir.exists());
+ dir.deleteOnExit();
+ }
+ }
+
+ /**
+ * java.io.File#mkdir()
+ * <p/>
+ * HARMONY-6041
+ */
+ public void test_mkdir_special_unicode() throws IOException {
+ File specialDir = new File(this.tempDirectory, "\u5C73");
+ int i = 0;
+ while (specialDir.exists()) {
+ specialDir = new File("\u5C73" + i);
+ ++i;
+ }
+ assertFalse(specialDir.exists());
+ assertTrue(specialDir.mkdir());
+ assertTrue(specialDir.exists());
+ }
+
+ /**
+ * java.io.File#mkdirs()
+ */
+ public void test_mkdirs() {
+ String userHome = addTrailingSlash(tempDirectory.getPath());
+ File f = new File(userHome + "mdtest" + platformId + File.separator + "mdtest2",
+ "p.tst");
+ File g = new File(userHome + "mdtest" + platformId + File.separator + "mdtest2");
+ File h = new File(userHome + "mdtest" + platformId);
+ f.mkdirs();
+ try {
+ assertTrue("Base Directory not created", h.exists());
+ assertTrue("Directories not created", g.exists());
+ assertTrue("File not created", f.exists());
+ } finally {
+ f.delete();
+ g.delete();
+ h.delete();
+ }
+ }
+
+ /**
+ * java.io.File#renameTo(java.io.File)
+ */
+ public void test_renameToLjava_io_File() throws IOException {
+ String base = tempDirectory.getPath();
+ File dir = new File(base, platformId);
+ dir.mkdir();
+ File f = new File(dir, "xxx.xxx");
+ File rfile = new File(dir, "yyy.yyy");
+ File f2 = new File(dir, "zzz.zzz");
+ try {
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.write(fileString.getBytes());
+ fos.close();
+ long lengthOfFile = f.length();
+
+ rfile.delete(); // in case it already exists
+
+ assertTrue("Test 1: File Rename Failed", f.renameTo(rfile));
+ assertTrue("Test 2: File Rename Failed.", rfile.exists());
+ assertEquals("Test 3: Size Of File Changed.",
+ lengthOfFile, rfile.length());
+
+ fos = new FileOutputStream(rfile);
+ fos.close();
+
+ f2.delete(); // in case it already exists
+ assertTrue("Test 4: File Rename Failed", rfile.renameTo(f2));
+ assertTrue("Test 5: File Rename Failed.", f2.exists());
+ } finally {
+ f.delete();
+ rfile.delete();
+ f2.delete();
+ dir.delete();
+ }
+ }
+
+ /**
+ * java.io.File#setLastModified(long)
+ */
+ public void test_setLastModifiedJ() throws IOException {
+ File f1 = null;
+ try {
+ f1 = File.createTempFile("harmony-test-FileTest_setLastModified", ".tmp");
+ long orgTime = f1.lastModified();
+ // Subtracting 100 000 milliseconds from the orgTime of File f1
+ f1.setLastModified(orgTime - 100000);
+ long lastModified = f1.lastModified();
+ assertEquals("Test 1: LastModifed time incorrect",
+ orgTime - 100000, lastModified);
+ // Subtracting 10 000 000 milliseconds from the orgTime of File f1
+ f1.setLastModified(orgTime - 10000000);
+ lastModified = f1.lastModified();
+ assertEquals("Test 2: LastModifed time incorrect",
+ orgTime - 10000000, lastModified);
+ // Adding 100 000 milliseconds to the orgTime of File f1
+ f1.setLastModified(orgTime + 100000);
+ lastModified = f1.lastModified();
+ assertEquals("Test 3: LastModifed time incorrect",
+ orgTime + 100000, lastModified);
+ // Adding 10 000 000 milliseconds from the orgTime of File f1
+ f1.setLastModified(orgTime + 10000000);
+ lastModified = f1.lastModified();
+ assertEquals("Test 4: LastModifed time incorrect",
+ orgTime + 10000000, lastModified);
+ // Trying to set time to an exact number
+ f1.setLastModified(315550800000L);
+ lastModified = f1.lastModified();
+ assertEquals("Test 5: LastModified time incorrect",
+ 315550800000L, lastModified);
+ String osName = System.getProperty("os.name", "unknown");
+ if (osName.equals("Windows 2000") || osName.equals("Windows NT")) {
+ // Trying to set time to a large exact number
+ boolean result = f1.setLastModified(4354837199000L);
+ long next = f1.lastModified();
+ // Dec 31 23:59:59 EST 2107 is overflow on FAT file systems, and
+ // the call fails
+ if (result) {
+ assertEquals("Test 6: LastModified time incorrect",
+ 4354837199000L, next);
+ }
+ }
+ // Trying to set time to a negative number
+ try {
+ f1.setLastModified(-25);
+ fail("IllegalArgumentException Not Thrown.");
+ } catch (IllegalArgumentException e) {
+ }
+ } finally {
+ if (f1 != null) {
+ f1.delete();
+ }
+ }
+ }
+
+ /**
+ * java.io.File#setReadOnly()
+ */
+ public void test_setReadOnly() throws Exception {
+ File f1 = null;
+ File f2 = null;
+ if (Libcore.os.getuid() == 0) {
+ System.err.println("Skipping #test_setReadOnly: test runner is root");
+ return;
+ }
+
+ try {
+ f1 = File.createTempFile("harmony-test-FileTest_setReadOnly", ".tmp");
+ f2 = File.createTempFile("harmony-test-FileTest_setReadOnly", ".tmp");
+ // Assert is flawed because canWrite does not work.
+ // assertTrue("File f1 Is Set To ReadOnly." , f1.canWrite());
+ assertTrue(f1.setReadOnly());
+ assertFalse(f1.canWrite());
+ // Assert is flawed because canWrite does not work.
+ // assertTrue("File f1 Is Not Set To ReadOnly." , !f1.canWrite());
+ try {
+ // Attempt to write to a file that is setReadOnly.
+ new FileOutputStream(f1);
+ fail("IOException not thrown.");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ Libcore.os.chmod(f1.getAbsolutePath(), 666);
+
+ // Assert is flawed because canWrite does not work.
+ // assertTrue("File f1 Is Set To ReadOnly." , f1.canWrite());
+ FileOutputStream fos = new FileOutputStream(f1);
+ fos.write(fileString.getBytes());
+ fos.close();
+ assertEquals(fileString.length(), f1.length());
+ assertTrue(f1.delete());
+
+ // Assert is flawed because canWrite does not work.
+ // assertTrue("File f2 Is Set To ReadOnly." , f2.canWrite());
+ fos = new FileOutputStream(f2);
+ // Write to a file.
+ fos.write(fileString.getBytes());
+ fos.close();
+ f2.setReadOnly();
+ // Assert is flawed because canWrite does not work.
+ // assertTrue("File f2 Is Not Set To ReadOnly." , !f2.canWrite());
+ try {
+ // Attempt to write to a file that has previously been written
+ // to.
+ // and is now set to read only.
+ fos = new FileOutputStream(f2);
+ fail("IOException not thrown.");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ Libcore.os.chmod(f2.getAbsolutePath(), 666);
+ assertTrue(f2.canWrite());
+ fos = new FileOutputStream(f2);
+ fos.write(fileString.getBytes());
+ fos.close();
+ f2.setReadOnly();
+ assertTrue(f2.delete());
+
+ // Similarly, trying to delete a read-only directory should succeed
+ f2 = new File(tempDirectory, "deltestdir");
+ f2.mkdir();
+ f2.setReadOnly();
+ assertTrue("Directory f2 Did Not Delete", f2.delete());
+ assertTrue("Directory f2 Did Not Delete", !f2.exists());
+ } finally {
+ if (f1 != null) {
+ f1.delete();
+ }
+ if (f2 != null) {
+ f2.delete();
+ }
+ }
+ }
+
+ /**
+ * java.io.File#toString()
+ */
+ public void test_toString() {
+ String fileName = System.getProperty("user.home");
+ if (!fileName.endsWith(File.separator)) {
+ fileName += File.separator;
+ }
+ fileName += "input.tst";
+ File f = new File(fileName);
+ assertEquals("Incorrect string returned", fileName, f.toString());
+
+ if (File.separatorChar == '\\') {
+ String result = new File("c:\\").toString();
+ assertEquals("Removed backslash", "c:\\", result);
+ }
+ }
+
+ /**
+ * java.io.File#toURI()
+ */
+ public void test_toURI() throws URISyntaxException {
+ // Need a directory that exists
+ File dir = tempDirectory;
+
+ // Test for toURI when the file is a directory.
+ String newURIPath = dir.getAbsolutePath();
+ newURIPath = newURIPath.replace(File.separatorChar, '/');
+ if (!newURIPath.startsWith("/")) {
+ newURIPath = "/" + newURIPath;
+ }
+ if (!newURIPath.endsWith("/")) {
+ newURIPath += '/';
+ }
+
+ URI uri = dir.toURI();
+ assertEquals("Test 1A: Incorrect URI Returned.", dir.getAbsoluteFile(), new File(uri));
+ assertEquals("Test 1B: Incorrect URI Returned.",
+ new URI("file", null, newURIPath, null, null), uri);
+
+ // Test for toURI with a file name with illegal chars.
+ File f = new File(dir, "te% \u20ac st.tst");
+ newURIPath = f.getAbsolutePath();
+ newURIPath = newURIPath.replace(File.separatorChar, '/');
+ if (!newURIPath.startsWith("/")) {
+ newURIPath = "/" + newURIPath;
+ }
+
+ uri = f.toURI();
+ assertEquals("Test 2A: Incorrect URI Returned.",
+ f.getAbsoluteFile(), new File(uri));
+ assertEquals("Test 2B: Incorrect URI Returned.",
+ new URI("file", null, newURIPath, null, null), uri);
+
+ // Regression test for HARMONY-3207
+ dir = new File(""); // current directory
+ uri = dir.toURI();
+ assertTrue("Test current dir: URI does not end with slash.", uri
+ .toString().endsWith("/"));
+ }
+
+ /**
+ * java.io.File#toURL()
+ */
+ public void test_toURL() throws MalformedURLException {
+ // Need a directory that exists
+ File dir = tempDirectory;
+
+ // Test for toURL when the file is a directory.
+ String newDirURL = dir.getAbsolutePath();
+ newDirURL = newDirURL.replace(File.separatorChar, '/');
+ if (newDirURL.startsWith("/")) {
+ newDirURL = "file:" + newDirURL;
+ } else {
+ newDirURL = "file:/" + newDirURL;
+ }
+ if (!newDirURL.endsWith("/")) {
+ newDirURL += '/';
+ }
+ assertEquals("Test 1: Incorrect URL Returned.",
+ dir.toURL().toString(), newDirURL);
+
+ // Test for toURL with a file.
+ File f = new File(dir, "test.tst");
+ String newURL = f.getAbsolutePath();
+ newURL = newURL.replace(File.separatorChar, '/');
+ if (newURL.startsWith("/")) {
+ newURL = "file:" + newURL;
+ } else {
+ newURL = "file:/" + newURL;
+ }
+ assertEquals("Test 2: Incorrect URL Returned.",
+ f.toURL().toString(), newURL);
+
+ // Regression test for HARMONY-3207
+ dir = new File(""); // current directory
+ newDirURL = dir.toURL().toString();
+ assertTrue("Test current dir: URL does not end with slash.", newDirURL
+ .endsWith("/"));
+ }
+
+ /**
+ * java.io.File#toURI()
+ */
+ public void test_toURI2() throws URISyntaxException {
+ File f = new File(tempDirectory, "a/b/c/../d/e/./f");
+
+ String path = f.getAbsolutePath();
+ path = path.replace(File.separatorChar, '/');
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+
+ URI uri1 = new URI("file", null, path, null);
+ URI uri2 = f.toURI();
+ assertEquals("uris not equal", uri1, uri2);
+ }
+
+ /**
+ * java.io.File#toURL()
+ */
+ public void test_toURL2() throws MalformedURLException {
+ File f = new File(tempDirectory, "a/b/c/../d/e/./f");
+
+ String path = f.getAbsolutePath();
+ path = path.replace(File.separatorChar, '/');
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+
+ URL url1 = new URL("file", "", path);
+ URL url2 = f.toURL();
+ assertEquals("urls not equal", url1, url2);
+ }
+
+ /**
+ * serialization
+ */
+ public void test_objectStreamClass_getFields() throws Exception {
+ // Regression for HARMONY-2674
+ ObjectStreamClass objectStreamClass = ObjectStreamClass
+ .lookup(File.class);
+ ObjectStreamField[] objectStreamFields = objectStreamClass.getFields();
+ assertEquals(1, objectStreamFields.length);
+ ObjectStreamField objectStreamField = objectStreamFields[0];
+ assertEquals("path", objectStreamField.getName());
+ assertEquals(String.class, objectStreamField.getType());
+ }
+
+ // Regression test for HARMONY-4493
+ public void test_list_withUnicodeFileName() throws Exception {
+ File rootDir = new File(System.getProperty("java.io.tmpdir")).getAbsoluteFile();
+ String dirName = new String("src\u3400");
+ File dir = new File(rootDir, dirName);
+ if (!dir.exists()) {
+ dir.mkdir();
+ dir.deleteOnExit();
+ }
+ boolean exist = false;
+ String[] fileNames = rootDir.list();
+ for (String fileName : fileNames) {
+ if (dirName.equals(fileName)) {
+ exist = true;
+ break;
+ }
+ }
+ assertTrue(exist);
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void test_serialization_self() throws Exception {
+ File testFile = new File("test.ser");
+ SerializationTest.verifySelf(testFile);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void test_serialization_compatibility() throws Exception {
+ File file = new File("FileTest.golden.ser");
+ SerializationTest.verifyGolden(this, file);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileWriterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileWriterTest.java
new file mode 100644
index 0000000..a3640b0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileWriterTest.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class FileWriterTest extends TestCase {
+ private FileInputStream fis;
+ private BufferedWriter bw;
+ private File f;
+ private FileOutputStream fos;
+ private BufferedReader br;
+
+ /**
+ * java.io.FileWriter#FileWriter(java.io.File)
+ */
+ public void test_ConstructorLjava_io_File() throws IOException {
+ fos = new FileOutputStream(f.getPath());
+ fos.write("Test String".getBytes());
+ fos.close();
+ bw = new BufferedWriter(new FileWriter(f));
+ bw.write(" After test string", 0, 18);
+ bw.close();
+ br = new BufferedReader(new FileReader(f.getPath()));
+ char[] buf = new char[100];
+ int r = br.read(buf);
+ br.close();
+ assertEquals("Failed to write correct chars", " After test string",
+ new String(buf, 0, r));
+ }
+
+ /**
+ * java.io.FileWriter#FileWriter(java.io.File, boolean)
+ */
+ public void test_ConstructorLjava_io_FileZ() throws IOException {
+ FileWriter fileWriter = new FileWriter(f);
+
+ String first = "The first string for testing. ";
+ fileWriter.write(first);
+ fileWriter.close();
+
+ fileWriter = new FileWriter(f, true);
+ String second = "The second String for testing.";
+ fileWriter.write(second);
+ fileWriter.close();
+
+ FileReader fileReader = new FileReader(f);
+ char[] out = new char[first.length() + second.length() + 10];
+ int length = fileReader.read(out);
+ fileReader.close();
+ assertEquals(first + second, new String(out, 0, length));
+
+ fileWriter = new FileWriter(f);
+ first = "The first string for testing. ";
+ fileWriter.write(first);
+ fileWriter.close();
+
+ fileWriter = new FileWriter(f, false);
+ second = "The second String for testing.";
+ fileWriter.write(second);
+ fileWriter.close();
+
+ fileReader = new FileReader(f);
+ out = new char[first.length() + second.length() + 10];
+ length = fileReader.read(out);
+ fileReader.close();
+ assertEquals(second, new String(out, 0, length));
+ }
+
+ /**
+ * java.io.FileWriter#FileWriter(java.io.FileDescriptor)
+ */
+ public void test_ConstructorLjava_io_FileDescriptor() throws IOException {
+ fos = new FileOutputStream(f.getPath());
+ fos.write("Test String".getBytes());
+ fos.close();
+ fis = new FileInputStream(f.getPath());
+ br = new BufferedReader(new FileReader(fis.getFD()));
+ char[] buf = new char[100];
+ int r = br.read(buf);
+ br.close();
+ fis.close();
+ assertTrue("Failed to write correct chars: " + new String(buf, 0, r),
+ new String(buf, 0, r).equals("Test String"));
+ }
+
+ /**
+ * java.io.FileWriter#FileWriter(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws IOException {
+ fos = new FileOutputStream(f.getPath());
+ fos.write("Test String".getBytes());
+ fos.close();
+ bw = new BufferedWriter(new FileWriter(f.getPath()));
+ bw.write(" After test string", 0, 18);
+ bw.close();
+ br = new BufferedReader(new FileReader(f.getPath()));
+ char[] buf = new char[100];
+ int r = br.read(buf);
+ br.close();
+ assertEquals("Failed to write correct chars", " After test string",
+ new String(buf, 0, r));
+ }
+
+ /**
+ * java.io.FileWriter#FileWriter(java.lang.String, boolean)
+ */
+ public void test_ConstructorLjava_lang_StringZ() throws IOException {
+ fos = new FileOutputStream(f.getPath());
+ fos.write("Test String".getBytes());
+ fos.close();
+ bw = new BufferedWriter(new FileWriter(f.getPath(), true));
+ bw.write(" After test string", 0, 18);
+ bw.close();
+ br = new BufferedReader(new FileReader(f.getPath()));
+ char[] buf = new char[100];
+ int r = br.read(buf);
+ br.close();
+ assertEquals("Failed to append to file",
+ "Test String After test string", new String(buf, 0, r));
+
+ fos = new FileOutputStream(f.getPath());
+ fos.write("Test String".getBytes());
+ fos.close();
+ bw = new BufferedWriter(new FileWriter(f.getPath(), false));
+ bw.write(" After test string", 0, 18);
+ bw.close();
+ br = new BufferedReader(new FileReader(f.getPath()));
+ buf = new char[100];
+ r = br.read(buf);
+ br.close();
+ assertEquals("Failed to overwrite file", " After test string",
+ new String(buf, 0, r));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ @Override
+ protected void setUp() throws Exception {
+ f = File.createTempFile("FileWriterTest", "tst");
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ @Override
+ protected void tearDown() {
+ try {
+ bw.close();
+ } catch (Exception e) {
+ }
+ try {
+ fis.close();
+ } catch (Exception e) {
+ }
+ f.delete();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterInputStreamTest.java
new file mode 100644
index 0000000..1e42770
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterInputStreamTest.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import junit.framework.TestCase;
+
+public class FilterInputStreamTest extends TestCase {
+
+ static class MyFilterInputStream extends FilterInputStream {
+ public MyFilterInputStream(InputStream is) {
+ super(is);
+ }
+ }
+
+ private String fileName;
+ private InputStream is;
+ private static final String INPUT =
+ "Test_All_Tests\n" +
+ "Test_BufferedInputStream\n" +
+ "Test_java_io_BufferedOutputStream\n" +
+ "Test_java_io_ByteArrayInputStream\n" +
+ "Test_java_io_ByteArrayOutputStream\n" +
+ "Test_java_io_DataInputStream\n" +
+ "Test_java_io_File\n" +
+ "Test_java_io_FileDescriptor\n" +
+ "Test_java_io_FileInputStream\n" +
+ "Test_java_io_FileNotFoundException\n" +
+ "Test_java_io_FileOutputStream\n" +
+ "Test_java_io_FilterInputStream\n" +
+ "Test_java_io_FilterOutputStream\n" +
+ "Test_java_io_InputStream\n" +
+ "Test_java_io_IOException\n" +
+ "Test_java_io_OutputStream\n" +
+ "Test_java_io_PrintStream\n" +
+ "Test_java_io_RandomAccessFile\n" +
+ "Test_java_io_SyncFailedException\n" +
+ "Test_java_lang_AbstractMethodError\n" +
+ "Test_java_lang_ArithmeticException\n" +
+ "Test_java_lang_ArrayIndexOutOfBoundsException\n" +
+ "Test_java_lang_ArrayStoreException\n" +
+ "Test_java_lang_Boolean\n" +
+ "Test_java_lang_Byte\n" +
+ "Test_java_lang_Character\n" +
+ "Test_All_Tests\n" +
+ "Test_BufferedInputStream\n" +
+ "Test_java_io_BufferedOutputStream\n" +
+ "Test_java_io_ByteArrayInputStream\n" +
+ "Test_java_io_ByteArrayOutputStream\n" +
+ "Test_java_io_DataInputStream\n" +
+ "Test_java_io_File\n" +
+ "Test_java_io_FileDescriptor\n" +
+ "Test_java_io_FileInputStream\n" +
+ "Test_java_io_FileNotFoundException\n" +
+ "Test_java_io_FileOutputStream\n" +
+ "Test_java_io_FilterInputStream\n" +
+ "Test_java_io_FilterOutputStream\n" +
+ "Test_java_io_InputStream\n" +
+ "Test_java_io_IOException\n" +
+ "Test_java_io_OutputStream\n" +
+ "Test_java_io_PrintStream\n" +
+ "Test_java_io_RandomAccessFile\n" +
+ "Test_java_io_SyncFailedException\n" +
+ "Test_java_lang_AbstractMethodError\n" +
+ "Test_java_lang_ArithmeticException\n" +
+ "Test_java_lang_ArrayIndexOutOfBoundsException\n" +
+ "Test_java_lang_ArrayStoreException\n" +
+ "Test_java_lang_Boolean\n" +
+ "Test_java_lang_Byte\n" +
+ "Test_java_lang_Character\n";
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ @Override
+ protected void setUp() throws IOException {
+ File temp = File.createTempFile("FilterInputStreamTest", "tst");
+ fileName = temp.getAbsolutePath();
+ OutputStream fos = new FileOutputStream(temp.getAbsolutePath());
+ fos.write(INPUT.getBytes(StandardCharsets.US_ASCII));
+ fos.close();
+ is = new MyFilterInputStream(new java.io.FileInputStream(fileName));
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ @Override
+ protected void tearDown() {
+ try {
+ is.close();
+ } catch (Exception e) {
+ // Ignored
+ }
+ new File(fileName).delete();
+ }
+
+ /**
+ * java.io.FilterInputStream#available()
+ */
+ public void test_available() throws IOException {
+ assertTrue("Returned incorrect number of available bytes", is
+ .available() == INPUT.length());
+ }
+
+ /**
+ * java.io.FilterInputStream#close()
+ */
+ public void test_close() throws IOException {
+ is.close();
+
+ try {
+ is.read();
+ fail("Able to read from closed stream");
+ } catch (java.io.IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.FilterInputStream#mark(int)
+ */
+ public void test_markI() {
+ assertTrue("Mark not supported by parent InputStream", true);
+ }
+
+ /**
+ * java.io.FilterInputStream#markSupported()
+ */
+ public void test_markSupported() {
+ assertTrue("markSupported returned true", !is.markSupported());
+ }
+
+ /**
+ * java.io.FilterInputStream#read()
+ */
+ public void test_read() throws Exception {
+ int c = is.read();
+ assertTrue("read returned incorrect char", c == INPUT.charAt(0));
+ }
+
+ /**
+ * java.io.FilterInputStream#read(byte[])
+ */
+ public void test_read$B() throws Exception {
+ byte[] buf1 = new byte[100];
+ is.read(buf1);
+ assertTrue("Failed to read correct data", new String(buf1, 0,
+ buf1.length, "UTF-8").equals(INPUT.substring(0, 100)));
+ }
+
+ /**
+ * java.io.FilterInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws Exception {
+ byte[] buf1 = new byte[100];
+ is.skip(500);
+ is.mark(1000);
+ is.read(buf1, 0, buf1.length);
+ assertTrue("Failed to read correct data", new String(buf1, 0,
+ buf1.length, "UTF-8").equals(INPUT.substring(500, 600)));
+ }
+
+ /**
+ * java.io.FilterInputStream#reset()
+ */
+ public void test_reset() {
+ try {
+ is.reset();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.FilterInputStream#skip(long)
+ */
+ public void test_skipJ() throws Exception {
+ byte[] buf1 = new byte[10];
+ is.skip(1000);
+ is.read(buf1, 0, buf1.length);
+ assertTrue("Failed to skip to correct position", new String(buf1, 0,
+ buf1.length, "UTF-8").equals(INPUT.substring(1000, 1010)));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java
new file mode 100644
index 0000000..666955d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+
+public class FilterOutputStreamTest extends TestCase {
+
+ private OutputStream os;
+
+ ByteArrayOutputStream bos;
+
+ ByteArrayInputStream bis;
+
+ byte[] ibuf = new byte[4096];
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ /**
+ * java.io.FilterOutputStream#FilterOutputStream(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() throws IOException {
+ bos = new ByteArrayOutputStream();
+ os = new FilterOutputStream(bos);
+ os.write('t');
+ }
+
+ /**
+ * java.io.FilterOutputStream#close()
+ */
+ public void test_close() throws IOException {
+ bos = new ByteArrayOutputStream();
+ os = new FilterOutputStream(bos);
+ os.write(fileString.getBytes(), 0, 500);
+ os.flush();
+ assertEquals("Bytes not written after flush", 500, bos.size());
+ os.close();
+ }
+
+ /**
+ * java.io.FilterOutputStream#flush()
+ */
+ public void test_flush() throws IOException {
+ bos = new ByteArrayOutputStream();
+ os = new FilterOutputStream(bos);
+ os.write(fileString.getBytes(), 0, 500);
+ os.flush();
+ assertEquals("Bytes not written after flush", 500, bos.size());
+ os.close();
+ }
+
+ /**
+ * java.io.FilterOutputStream#write(byte[])
+ */
+ public void test_write$B() throws IOException {
+ bos = new ByteArrayOutputStream();
+ os = new FilterOutputStream(bos);
+ os.write(fileString.getBytes());
+ bis = new ByteArrayInputStream(bos.toByteArray());
+ os.flush();
+ assertTrue("Bytes not written after flush",
+ bis.available() == fileString.length());
+ byte[] wbytes = new byte[fileString.length()];
+ bis.read(wbytes, 0, fileString.length());
+ assertTrue("Incorrect bytes written", fileString.equals(new String(
+ wbytes, 0, wbytes.length)));
+ }
+
+ /**
+ * java.io.FilterOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() throws IOException {
+ bos = new ByteArrayOutputStream();
+ os = new FilterOutputStream(bos);
+ os.write(fileString.getBytes(), 0, fileString.length());
+ bis = new ByteArrayInputStream(bos.toByteArray());
+ os.flush();
+ assertTrue("Bytes not written after flush",
+ bis.available() == fileString.length());
+ byte[] wbytes = new byte[fileString.length()];
+ bis.read(wbytes, 0, fileString.length());
+ assertTrue("Incorrect bytes written", fileString.equals(new String(
+ wbytes, 0, wbytes.length)));
+ }
+
+ /**
+ * java.io.FilterOutputStream#write(int)
+ */
+ public void test_writeI() throws IOException {
+ bos = new ByteArrayOutputStream();
+ os = new FilterOutputStream(bos);
+ os.write('t');
+ bis = new ByteArrayInputStream(bos.toByteArray());
+ os.flush();
+ assertEquals("Byte not written after flush", 1, bis.available());
+ byte[] wbytes = new byte[1];
+ bis.read(wbytes, 0, 1);
+ assertEquals("Incorrect byte written", 't', wbytes[0]);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ if (bos != null)
+ bos.close();
+ if (bis != null)
+ bis.close();
+ if (os != null)
+ os.close();
+ } catch (Exception e) {
+ // Ignored
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOErrorTest.java
new file mode 100644
index 0000000..b95adc9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOErrorTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOError;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import junit.framework.TestCase;
+
+public class IOErrorTest extends TestCase {
+
+ /**
+ * java.io.IOError#IOError(java.lang.Throwable)
+ * @since 1.6
+ */
+ public void test_IOError_LThrowable() {
+ IOError e = new IOError(null);
+ assertNull(e.getCause());
+
+ String errorMsg = "java.io.IOError"; //$NON-NLS-1$
+ assertTrue(e.toString().contains(errorMsg));
+
+ errorMsg = "A dummy error"; //$NON-NLS-1$
+ e = new IOError(new Throwable(errorMsg));
+ assertTrue(e.toString().contains(errorMsg));
+
+ try {
+ throw new IOError(null);
+ } catch (IOError error) {
+ return;
+ } catch (Error error) {
+ fail("Error during IOException test" + error.toString()); //$NON-NLS-1$
+ }
+ fail("Failed to generate error"); //$NON-NLS-1$
+ }
+
+ /**
+ * serialization/deserialization.
+ * @since 1.6
+ */
+ public void testSerializationSelf() throws Exception {
+ String errorMsg = "java.io.IOError";
+ IOError e = new IOError(new Throwable(errorMsg));
+ SerializationTest.verifySelf(e);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ * @since 1.6
+ */
+ public void testSerializationCompatibility() throws Exception {
+ String errorMsg = "java.io.IOError";
+ IOError e = new IOError(new Throwable(errorMsg));
+ SerializationTest.verifyGolden(this, e);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOExceptionTest.java
new file mode 100644
index 0000000..d0b26db
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOExceptionTest.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class IOExceptionTest extends TestCase {
+
+ /**
+ * java.io.IOException#IOException()
+ */
+ public void test_Constructor() {
+ try {
+ if (true) {
+ throw new IOException();
+ }
+ fail("Exception during IOException test");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.IOException#IOException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ try {
+ if (true) {
+ throw new IOException("Some error message");
+ }
+ fail("Failed to generate exception");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.IOException#IOException(java.lang.String,
+ *java.lang.Throwable)
+ * @since 1.6
+ */
+ public void test_ConstructorLString_LThrowable() {
+ // Test for constructor java.io.IOException(java.lang.String, java.lang.Throwable)
+
+ IOException ioException = new IOException(
+ "A dummy IOException", new Throwable("A dummy Throwable")); //$NON-NLS-1$//$NON-NLS-2$
+ assertEquals("A dummy IOException", ioException.getMessage()); //$NON-NLS-1$
+
+ try {
+ throw new IOException(
+ "A dummy error", new Throwable("Some error message")); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (IOException e) {
+ return;
+ } catch (Exception e) {
+ fail("Exception during IOException test" + e.toString()); //$NON-NLS-1$
+ }
+ fail("Failed to generate exception"); //$NON-NLS-1$
+ }
+
+ /**
+ * java.io.IOException#IOException(java.lang.Throwable)
+ * @since 1.6
+ */
+ public void test_Constructor_LThrowable() {
+ // Test for constructor java.io.IOException(java.lang.Throwable)
+ Throwable cause = new Throwable("A dummy Throwable"); //$NON-NLS-1$
+ IOException ioException = new IOException(cause);
+ assertEquals(cause.toString(), ioException.getMessage());
+
+ ioException = new IOException((Throwable) null);
+ assertNull(ioException.getMessage());
+
+ try {
+ throw new IOException(new Throwable("Some error message")); //$NON-NLS-1$
+ } catch (IOException e) {
+ return;
+ } catch (Exception e) {
+ fail("Exception during IOException test" + e.toString()); //$NON-NLS-1$
+ }
+ fail("Failed to generate exception"); //$NON-NLS-1$
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InputStreamReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InputStreamReaderTest.java
new file mode 100644
index 0000000..b84561a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InputStreamReaderTest.java
@@ -0,0 +1,529 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import junit.framework.TestCase;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.util.Arrays;
+
+public class InputStreamReaderTest extends TestCase {
+
+ static class LimitedByteArrayInputStream extends ByteArrayInputStream {
+
+ // A ByteArrayInputStream that only returns a single byte per read
+ byte[] bytes;
+
+ int count;
+
+ public LimitedByteArrayInputStream(int type) {
+ super(new byte[0]);
+ switch (type) {
+ case 0:
+ bytes = new byte[] { 0x61, 0x72 };
+ break;
+ case 1:
+ bytes = new byte[] { (byte) 0xff, (byte) 0xfe, 0x61, 0x72 };
+ break;
+ case 2:
+ bytes = new byte[] { '\u001b', '$', 'B', '6', 'e', 'B', 'h',
+ '\u001b', '(', 'B' };
+ break;
+ }
+ count = bytes.length;
+ }
+
+ @Override
+ public int available() {
+ return count;
+ }
+
+ @Override
+ public int read() {
+ if (count == 0) {
+ return -1;
+ }
+ count--;
+ return bytes[bytes.length - count];
+ }
+
+ @Override
+ public int read(byte[] buffer, int offset, int length) {
+ if (count == 0) {
+ return -1;
+ }
+ if (length == 0) {
+ return 0;
+ }
+ buffer[offset] = bytes[bytes.length - count];
+ count--;
+ return 1;
+ }
+ }
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+ private InputStream fis;
+
+ private InputStream in;
+
+ private InputStreamReader is;
+
+ private InputStreamReader reader;
+
+ private final String source = "This is a test message with Unicode character. \u4e2d\u56fd is China's name in Chinese";
+
+ /*
+ * @see TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ in = new ByteArrayInputStream(source.getBytes("UTF-8"));
+ reader = new InputStreamReader(in, "UTF-8");
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ OutputStreamWriter osw = new OutputStreamWriter(bos);
+ char[] buf = new char[fileString.length()];
+ fileString.getChars(0, fileString.length(), buf, 0);
+ osw.write(buf);
+ osw.close();
+ fis = new ByteArrayInputStream(bos.toByteArray());
+ is = new InputStreamReader(fis);
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ in.close();
+ is.close();
+ fis.close();
+ } catch (IOException e) {
+ // Ignored
+ }
+
+ super.tearDown();
+ }
+
+ /**
+ * java.io.InputStreamReader#close()
+ */
+ public void test_close() throws IOException {
+ is.close();
+ try {
+ is.read();
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ reader.close();
+ try {
+ reader.ready();
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ // Should be a no-op
+ reader.close();
+
+ // Tests after reader closed
+ in = new BufferedInputStream(
+ this
+ .getClass()
+ .getClassLoader()
+ .getResourceAsStream(
+ "org/apache/harmony/luni/tests/java/io/testfile-utf8.txt"));
+ reader = new InputStreamReader(in, "utf-8");
+ in.close();
+ try {
+ int count = reader.read(new char[1]);
+ fail("count:" + count);
+ } catch (IOException e) {
+ // Expected
+ }
+ try {
+ reader.read();
+ fail();
+ } catch (IOException e) {
+ // Expected
+ }
+
+ assertFalse(reader.ready());
+ Charset cs = Charset.forName("utf-8");
+ assertEquals(cs, Charset.forName(reader.getEncoding()));
+ }
+
+ /**
+ * java.io.InputStreamReader#InputStreamReader(java.io.InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() throws IOException {
+ try {
+ reader = new InputStreamReader(null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ InputStreamReader reader2 = new InputStreamReader(in);
+ reader2.close();
+ }
+
+ /**
+ * java.io.InputStreamReader#InputStreamReader(java.io.InputStream,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_lang_String()
+ throws IOException {
+ is = new InputStreamReader(fis, "8859_1");
+
+ try {
+ is = new InputStreamReader(fis, "Bogus");
+ fail("Failed to throw Unsupported Encoding exception");
+ } catch (UnsupportedEncodingException e) {
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ reader = new InputStreamReader(null, "utf-8");
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ reader = new InputStreamReader(in, (String) null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ reader = new InputStreamReader(in, "");
+ fail();
+ } catch (UnsupportedEncodingException e) {
+ // Expected
+ }
+ try {
+ reader = new InputStreamReader(in, "badname");
+ fail();
+ } catch (UnsupportedEncodingException e) {
+ // Expected
+ }
+ InputStreamReader reader2 = new InputStreamReader(in, "utf-8");
+ assertEquals(Charset.forName(reader2.getEncoding()), Charset
+ .forName("utf-8"));
+ reader2.close();
+ reader2 = new InputStreamReader(in, "utf8");
+ assertEquals(Charset.forName(reader2.getEncoding()), Charset
+ .forName("utf-8"));
+ reader2.close();
+ }
+
+ /**
+ * java.io.InputStreamReader(java.io.InputStream,
+ *java.nio.charset.Charset)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_nio_charset_Charset()
+ throws IOException {
+ Charset cs = Charset.forName("utf-8");
+ try {
+ reader = new InputStreamReader(null, cs);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ reader = new InputStreamReader(in, (Charset) null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ InputStreamReader reader2 = new InputStreamReader(in, cs);
+ assertEquals(Charset.forName(reader2.getEncoding()), cs);
+ reader2.close();
+ }
+
+ /**
+ * java.io.InputStreamReader(java.io.InputStream,
+ *java.nio.charset.CharsetDecoder)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_nio_charset_CharsetDecoder()
+ throws IOException {
+ CharsetDecoder decoder = Charset.forName("utf-8").newDecoder();
+ try {
+ reader = new InputStreamReader(null, decoder);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ reader = new InputStreamReader(in, (CharsetDecoder) null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ InputStreamReader reader2 = new InputStreamReader(in, decoder);
+ assertEquals(Charset.forName(reader2.getEncoding()), decoder.charset());
+ reader2.close();
+ }
+
+ /**
+ * Unlike the RI, we return a canonical encoding name and not something
+ * java specific.
+ */
+ public void test_getEncoding() throws IOException {
+ InputStreamReader isr = new InputStreamReader(fis, "8859_1");
+ assertEquals("ISO-8859-1", isr.getEncoding());
+
+ isr = new InputStreamReader(fis, "ISO-8859-1");
+ assertEquals("ISO-8859-1", isr.getEncoding());
+
+ byte b[] = new byte[5];
+ isr = new InputStreamReader(new ByteArrayInputStream(b), "UTF-16BE");
+ isr.close();
+ assertNull(isr.getEncoding());
+
+ try {
+ isr = new InputStreamReader(System.in, "UTF-16BE");
+ } catch (UnsupportedEncodingException e) {
+ // Ignored
+ }
+ assertEquals("UTF-16BE", isr.getEncoding());
+ }
+
+ /**
+ * java.io.InputStreamReader#read()
+ */
+ public void test_read() throws IOException {
+ assertEquals('T', (char) reader.read());
+ assertEquals('h', (char) reader.read());
+ assertEquals('i', (char) reader.read());
+ assertEquals('s', (char) reader.read());
+ assertEquals(' ', (char) reader.read());
+ reader.read(new char[source.length() - 5], 0, source.length() - 5);
+ assertEquals(-1, reader.read());
+
+ int c = is.read();
+ assertTrue("returned incorrect char", (char) c == fileString.charAt(0));
+ InputStreamReader reader = new InputStreamReader(
+ new ByteArrayInputStream(new byte[] { (byte) 0xe8, (byte) 0x9d,
+ (byte) 0xa5 }), "UTF8");
+ assertTrue("wrong double byte char", reader.read() == '\u8765');
+
+ // Regression for HARMONY-166
+ InputStream in;
+
+ in = new LimitedByteArrayInputStream(0);
+ reader = new InputStreamReader(in, "UTF-16BE");
+ assertEquals("Incorrect byte UTF-16BE", '\u6172', reader.read());
+
+ in = new LimitedByteArrayInputStream(0);
+ reader = new InputStreamReader(in, "UTF-16LE");
+ assertEquals("Incorrect byte UTF-16BE", '\u7261', reader.read());
+
+ in = new LimitedByteArrayInputStream(1);
+ reader = new InputStreamReader(in, "UTF-16");
+ assertEquals("Incorrect byte UTF-16BE", '\u7261', reader.read());
+
+ /*
+ * Temporarily commented out due to lack of ISO2022 support in ICU4J 3.8
+ * in = new LimitedByteArrayInputStream(2); reader = new
+ * InputStreamReader(in, "ISO2022JP"); assertEquals("Incorrect byte
+ * ISO2022JP 1", '\u4e5d', reader.read()); assertEquals("Incorrect byte
+ * ISO2022JP 2", '\u7b2c', reader.read());
+ */
+ }
+
+ /*
+ * Class under test for int read() Regression for Harmony-411
+ */
+ public void test_read_1() throws IOException {
+ // if the decoder is constructed by InputStreamReader itself, the
+ // decoder's default error action is REPLACE
+ InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(
+ new byte[] { -32, -96 }), "UTF-8");
+ assertEquals("read() return incorrect value", 65533, isr.read());
+
+ InputStreamReader isr2 = new InputStreamReader(
+ new ByteArrayInputStream(new byte[] { -32, -96 }), Charset
+ .forName("UTF-8"));
+ assertEquals("read() return incorrect value", 65533, isr2.read());
+
+ // if the decoder is passed in, keep its status intact
+ CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ InputStreamReader isr3 = new InputStreamReader(
+ new ByteArrayInputStream(new byte[] { -32, -96 }), decoder);
+ try {
+ isr3.read();
+ fail("Should throw MalformedInputException");
+ } catch (MalformedInputException e) {
+ // expected
+ }
+
+ CharsetDecoder decoder2 = Charset.forName("UTF-8").newDecoder();
+ decoder2.onMalformedInput(CodingErrorAction.IGNORE);
+ InputStreamReader isr4 = new InputStreamReader(
+ new ByteArrayInputStream(new byte[] { -32, -96 }), decoder2);
+ assertEquals("read() return incorrect value", -1, isr4.read());
+
+ CharsetDecoder decoder3 = Charset.forName("UTF-8").newDecoder();
+ decoder3.onMalformedInput(CodingErrorAction.REPLACE);
+ InputStreamReader isr5 = new InputStreamReader(
+ new ByteArrayInputStream(new byte[] { -32, -96 }), decoder3);
+ assertEquals("read() return incorrect value", 65533, isr5.read());
+ }
+
+ public void test_read_specialCharset() throws IOException {
+ reader.close();
+ in = this.getClass().getClassLoader().getResourceAsStream(
+ "tests/api/java/io/testfile-utf8.txt");
+ reader = new InputStreamReader(in, "utf-8");
+ int c;
+ StringBuffer sb = new StringBuffer();
+ while ((c = reader.read()) != -1) {
+ sb.append((char) c);
+ }
+ // delete BOM
+ assertEquals(source, sb.deleteCharAt(0).toString());
+
+ sb.setLength(0);
+ reader.close();
+ in = this.getClass().getClassLoader().getResourceAsStream(
+ "tests/api/java/io/testfile.txt");
+
+ reader = new InputStreamReader(in, "gb18030");
+ while ((c = reader.read()) != -1) {
+ sb.append((char) c);
+ }
+ assertEquals(source, sb.toString());
+ }
+
+ /**
+ * java.io.InputStreamReader#read(char[], int, int)
+ */
+ public void test_read$CII() throws IOException {
+ char[] rbuf = new char[100];
+ char[] sbuf = new char[100];
+ fileString.getChars(0, 100, sbuf, 0);
+ is.read(rbuf, 0, 100);
+ for (int i = 0; i < rbuf.length; i++) {
+ assertTrue("returned incorrect chars", rbuf[i] == sbuf[i]);
+ }
+
+ // Test successive reads
+ byte[] data = new byte[8192 * 2];
+ Arrays.fill(data, (byte) 116); // 116 = ISO-8859-1 value for 't'
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ InputStreamReader isr = new InputStreamReader(bis, "ISO-8859-1");
+
+ // One less than the InputStreamReader.BUFFER_SIZE
+ char[] buf = new char[8191];
+ int bytesRead = isr.read(buf, 0, buf.length);
+ assertFalse(-1 == bytesRead);
+ bytesRead = isr.read(buf, 0, buf.length);
+ assertFalse(-1 == bytesRead);
+
+ bis = new ByteArrayInputStream(source.getBytes("UTF-8"));
+ isr = new InputStreamReader(in, "UTF-8");
+ char[] chars = new char[source.length()];
+ assertEquals(source.length() - 3, isr.read(chars, 0, chars.length - 3));
+ assertEquals(3, isr.read(chars, 0, 10));
+ }
+
+ /*
+ * Class under test for int read(char[], int, int)
+ */
+ public void test_read$CII_1() throws IOException {
+ try {
+ reader.read(null, -1, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ reader.read(null, 0, -1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ reader.read(null, 0, 1);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ reader.read(new char[3], -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ reader.read(new char[3], 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ reader.read(new char[3], 1, 3);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ assertEquals(0, reader.read(new char[3], 3, 0));
+ char[] chars = new char[source.length()];
+ assertEquals(0, reader.read(chars, 0, 0));
+ assertEquals(0, chars[0]);
+ assertEquals(3, reader.read(chars, 0, 3));
+ assertEquals(5, reader.read(chars, 3, 5));
+ assertEquals(source.length() - 8, reader.read(chars, 8,
+ chars.length - 8));
+ assertTrue(Arrays.equals(chars, source.toCharArray()));
+ assertEquals(-1, reader.read(chars, 0, chars.length));
+ assertTrue(Arrays.equals(chars, source.toCharArray()));
+ }
+
+ /**
+ * java.io.InputStreamReader#ready()
+ */
+ public void test_ready() throws IOException {
+ assertTrue("Ready test failed", is.ready());
+ is.read();
+ assertTrue("More chars, but not ready", is.ready());
+
+ assertTrue(reader.ready());
+ reader.read(new char[source.length()]);
+ assertFalse(reader.ready());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InputStreamTest.java
new file mode 100644
index 0000000..f2543c3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InputStreamTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+public class InputStreamTest extends TestCase {
+ // Regression for HARMONY-4337
+ public void test1() throws IOException {
+ try {
+ InputStream in = new MockInputStream();
+ in.read(null, -1, 1);
+ fail("should throw NullPointerException.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ class MockInputStream extends InputStream {
+ public int read() throws IOException {
+ return 0;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InterruptedIOExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InterruptedIOExceptionTest.java
new file mode 100644
index 0000000..5fc3d44
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InterruptedIOExceptionTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.InterruptedIOException;
+
+import junit.framework.TestCase;
+
+public class InterruptedIOExceptionTest extends TestCase {
+
+ /**
+ * java.io.InterruptedIOException#InterruptedIOException()
+ */
+ public void test_Constructor() {
+ try {
+ throw new InterruptedIOException();
+ } catch (InterruptedIOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.InterruptedIOException#InterruptedIOException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ try {
+ throw new InterruptedIOException("Some error message");
+ } catch (InterruptedIOException e) {
+ // Expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InvalidClassExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InvalidClassExceptionTest.java
new file mode 100644
index 0000000..f0d30f2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/InvalidClassExceptionTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.InvalidClassException;
+
+import junit.framework.TestCase;
+
+public class InvalidClassExceptionTest extends TestCase {
+
+ /**
+ * java.io.InvalidClassException#InvalidClassException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ final String message = "A message";
+ try {
+ if (true) {
+ throw new InvalidClassException(message);
+ }
+ fail("Failed to throw exception");
+ } catch (InvalidClassException e) {
+ // correct
+ assertTrue("Incorrect message read", e.getMessage().equals(message));
+ }
+ }
+
+ /**
+ * java.io.InvalidClassException#InvalidClassException(java.lang.String,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+ final String message = "A message";
+ final String className = "Object";
+ try {
+ if (true) {
+ throw new InvalidClassException(className, message);
+ }
+ fail("Failed to throw exception");
+ } catch (InvalidClassException e) {
+ // correct
+ String returnedMessage = e.getMessage();
+ assertTrue("Incorrect message read: " + e.getMessage(),
+ returnedMessage.indexOf(className) >= 0
+ && returnedMessage.indexOf(message) >= 0);
+ }
+ }
+
+ /**
+ * java.io.InvalidClassException#getMessage()
+ */
+ public void test_getMessage() {
+ // Test for method java.lang.String
+ // java.io.InvalidClassException.getMessage()
+ // used to test
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/LineNumberInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/LineNumberInputStreamTest.java
new file mode 100644
index 0000000..de345f1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/LineNumberInputStreamTest.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.io;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.LineNumberInputStream;
+import java.io.UnsupportedEncodingException;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("deprecation")
+public class LineNumberInputStreamTest extends TestCase {
+
+ String text = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81\n82\n83\n84\n85\n86\n87\n88\n89\n90\n91\n92\n93\n94\n95\n96\n97\n98\n99\n100\n101\n102\n103\n104\n105\n106\n107\n108\n109\n110\n111\n112\n113\n114\n115\n116\n117\n118\n119\n120\n121\n122\n123\n124\n125\n126\n127\n128\n129\n130\n131\n132\n133\n134\n135\n136\n137\n138\n139\n140\n141\n142\n143\n144\n145\n146\n147\n148\n149\n150\n151\n152\n153\n154\n155\n156\n157\n158\n159\n160\n161\n162\n163\n164\n165\n166\n167\n168\n169\n170\n171\n172\n173\n174\n175\n176\n177\n178\n179\n180\n181\n182\n183\n184\n185\n186\n187\n188\n189\n190\n191\n192\n193\n194\n195\n196\n197\n198\n199\n200\n201\n202\n203\n204\n205\n206\n207\n208\n209\n210\n211\n212\n213\n214\n215\n216\n217\n218\n219\n220\n221\n222\n223\n224\n225\n226\n227\n228\n229\n230\n231\n232\n233\n234\n235\n236\n237\n238\n239\n240\n241\n242\n243\n244\n245\n246\n247\n248\n249\n250\n251\n252\n253\n254\n255\n256\n257\n258\n259\n260\n261\n262\n263\n264\n265\n266\n267\n268\n269\n270\n271\n272\n273\n274\n275\n276\n277\n278\n279\n280\n281\n282\n283\n284\n285\n286\n287\n288\n289\n290\n291\n292\n293\n294\n295\n296\n297\n298\n299\n300\n301\n302\n303\n304\n305\n306\n307\n308\n309\n310\n311\n312\n313\n314\n315\n316\n317\n318\n319\n320\n321\n322\n323\n324\n325\n326\n327\n328\n329\n330\n331\n332\n333\n334\n335\n336\n337\n338\n339\n340\n341\n342\n343\n344\n345\n346\n347\n348\n349\n350\n351\n352\n353\n354\n355\n356\n357\n358\n359\n360\n361\n362\n363\n364\n365\n366\n367\n368\n369\n370\n371\n372\n373\n374\n375\n376\n377\n378\n379\n380\n381\n382\n383\n384\n385\n386\n387\n388\n389\n390\n391\n392\n393\n394\n395\n396\n397\n398\n399\n400\n401\n402\n403\n404\n405\n406\n407\n408\n409\n410\n411\n412\n413\n414\n415\n416\n417\n418\n419\n420\n421\n422\n423\n424\n425\n426\n427\n428\n429\n430\n431\n432\n433\n434\n435\n436\n437\n438\n439\n440\n441\n442\n443\n444\n445\n446\n447\n448\n449\n450\n451\n452\n453\n454\n455\n456\n457\n458\n459\n460\n461\n462\n463\n464\n465\n466\n467\n468\n469\n470\n471\n472\n473\n474\n475\n476\n477\n478\n479\n480\n481\n482\n483\n484\n485\n486\n487\n488\n489\n490\n491\n492\n493\n494\n495\n496\n497\n498\n499\n500\n501";
+
+ String dosText = "0\r\n1\r\n2";
+
+ LineNumberInputStream lnis;
+
+ LineNumberInputStream lnis2;
+
+ /**
+ * java.io.LineNumberInputStream#LineNumberInputStream(java.io.InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() {
+ // Used in other tests
+ }
+
+ /**
+ * java.io.LineNumberInputStream#available()
+ */
+ public void test_available() throws IOException {
+ assertTrue("Returned incorrect number of available bytes", lnis
+ .available() == text.length() / 2);
+ }
+
+ /**
+ * java.io.LineNumberInputStream#getLineNumber()
+ */
+ public void test_getLineNumber() throws IOException {
+ assertEquals("New stream returned line number other than zero", 0, lnis
+ .getLineNumber());
+
+ lnis.read();
+ lnis.read();
+
+ assertEquals("stream returned incorrect line number after read", 1,
+ lnis.getLineNumber());
+
+ lnis.setLineNumber(89);
+ assertEquals("stream returned incorrect line number after set", 89,
+ lnis.getLineNumber());
+ }
+
+ /**
+ * java.io.LineNumberInputStream#mark(int)
+ */
+ public void test_markI() throws IOException {
+ lnis.mark(40);
+ lnis.skip(4);
+ lnis.reset();
+ assertEquals("Failed to mark", 0, lnis.getLineNumber());
+ assertEquals("Failed to mark", '0', lnis.read());
+ }
+
+ /**
+ * java.io.LineNumberInputStream#read()
+ */
+ public void test_read() throws IOException {
+ assertEquals("Failed to read correct byte", '0', lnis.read());
+ assertEquals("Failed to read correct byte on dos text", '0', lnis2
+ .read());
+ assertTrue("Failed to read correct byte on dos text",
+ lnis2.read() == '\n');
+ assertEquals("Failed to read correct byte on dos text", '1', lnis2
+ .read());
+ assertTrue("Failed to read correct byte on dos text",
+ lnis2.read() == '\n');
+ assertEquals("Failed to read correct byte on dos text", '2', lnis2
+ .read());
+ }
+
+ /**
+ * java.io.LineNumberInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException, UnsupportedEncodingException {
+ byte[] buf = new byte[100];
+ lnis.read(buf, 0, 100);
+ assertTrue("Failed to read correct bytes on normal text", new String(
+ buf, 0, 100, "UTF-8").equals(text.substring(0, 100)));
+ }
+
+ /**
+ * java.io.LineNumberInputStream#reset()
+ */
+ public void test_reset() throws IOException {
+ lnis.mark(40);
+ lnis.skip(4);
+ lnis.reset();
+ assertEquals("Failed to reset", 0, lnis.getLineNumber());
+ assertEquals("Failed to reset", '0', lnis.read());
+ lnis.reset();
+
+ // see comment for setup
+ try {
+ lnis.mark(5);
+ lnis.skip(100);
+ lnis.reset();
+ fail("Failed to invalidate mark");
+ } catch (IOException e) {
+ // Correct mark has been invalidated
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.LineNumberInputStream#setLineNumber(int)
+ */
+ public void test_setLineNumberI() {
+ lnis.setLineNumber(89);
+ assertEquals("Failed to set line number", 89, lnis.getLineNumber());
+ }
+
+ /**
+ * java.io.LineNumberInputStream#skip(long)
+ */
+ public void test_skipJ() throws IOException {
+ lnis.skip(4);
+ assertEquals("Skip failed to increment lineNumber", 2, lnis
+ .getLineNumber());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() throws UnsupportedEncodingException {
+ /*
+ * In order for IOException to be thrown in reset(),the inputStream to
+ * the constructor cannot be a byteArrayInputstream because the reset()
+ * in byteArrayInputStream does not throw IOException. When
+ * BufferedInputStream is used, the size of the buffer must be smaller
+ * than the readlimit in mark inorder for IOException to be thrown
+ */
+ BufferedInputStream buftemp = new BufferedInputStream(
+ new ByteArrayInputStream(text.getBytes("UTF-8")), 4);
+ lnis = new LineNumberInputStream(buftemp);
+ lnis2 = new LineNumberInputStream(new ByteArrayInputStream(dosText
+ .getBytes("UTF-8")));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/LineNumberReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/LineNumberReaderTest.java
new file mode 100644
index 0000000..d20b7af
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/LineNumberReaderTest.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.io.StringReader;
+
+import junit.framework.TestCase;
+
+public class LineNumberReaderTest extends TestCase {
+
+ String text = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81\n82\n83\n84\n85\n86\n87\n88\n89\n90\n91\n92\n93\n94\n95\n96\n97\n98\n99\n100\n101\n102\n103\n104\n105\n106\n107\n108\n109\n110\n111\n112\n113\n114\n115\n116\n117\n118\n119\n120\n121\n122\n123\n124\n125\n126\n127\n128\n129\n130\n131\n132\n133\n134\n135\n136\n137\n138\n139\n140\n141\n142\n143\n144\n145\n146\n147\n148\n149\n150\n151\n152\n153\n154\n155\n156\n157\n158\n159\n160\n161\n162\n163\n164\n165\n166\n167\n168\n169\n170\n171\n172\n173\n174\n175\n176\n177\n178\n179\n180\n181\n182\n183\n184\n185\n186\n187\n188\n189\n190\n191\n192\n193\n194\n195\n196\n197\n198\n199\n200\n201\n202\n203\n204\n205\n206\n207\n208\n209\n210\n211\n212\n213\n214\n215\n216\n217\n218\n219\n220\n221\n222\n223\n224\n225\n226\n227\n228\n229\n230\n231\n232\n233\n234\n235\n236\n237\n238\n239\n240\n241\n242\n243\n244\n245\n246\n247\n248\n249\n250\n251\n252\n253\n254\n255\n256\n257\n258\n259\n260\n261\n262\n263\n264\n265\n266\n267\n268\n269\n270\n271\n272\n273\n274\n275\n276\n277\n278\n279\n280\n281\n282\n283\n284\n285\n286\n287\n288\n289\n290\n291\n292\n293\n294\n295\n296\n297\n298\n299\n300\n301\n302\n303\n304\n305\n306\n307\n308\n309\n310\n311\n312\n313\n314\n315\n316\n317\n318\n319\n320\n321\n322\n323\n324\n325\n326\n327\n328\n329\n330\n331\n332\n333\n334\n335\n336\n337\n338\n339\n340\n341\n342\n343\n344\n345\n346\n347\n348\n349\n350\n351\n352\n353\n354\n355\n356\n357\n358\n359\n360\n361\n362\n363\n364\n365\n366\n367\n368\n369\n370\n371\n372\n373\n374\n375\n376\n377\n378\n379\n380\n381\n382\n383\n384\n385\n386\n387\n388\n389\n390\n391\n392\n393\n394\n395\n396\n397\n398\n399\n400\n401\n402\n403\n404\n405\n406\n407\n408\n409\n410\n411\n412\n413\n414\n415\n416\n417\n418\n419\n420\n421\n422\n423\n424\n425\n426\n427\n428\n429\n430\n431\n432\n433\n434\n435\n436\n437\n438\n439\n440\n441\n442\n443\n444\n445\n446\n447\n448\n449\n450\n451\n452\n453\n454\n455\n456\n457\n458\n459\n460\n461\n462\n463\n464\n465\n466\n467\n468\n469\n470\n471\n472\n473\n474\n475\n476\n477\n478\n479\n480\n481\n482\n483\n484\n485\n486\n487\n488\n489\n490\n491\n492\n493\n494\n495\n496\n497\n498\n499\n500\n";
+
+ LineNumberReader lnr;
+
+ /**
+ * java.io.LineNumberReader#LineNumberReader(java.io.Reader)
+ */
+ public void test_ConstructorLjava_io_Reader() {
+ lnr = new LineNumberReader(new StringReader(text), 4092);
+ assertEquals("Failed to create reader", 0, lnr.getLineNumber());
+ }
+
+ /**
+ * java.io.LineNumberReader#LineNumberReader(java.io.Reader, int)
+ */
+ public void test_ConstructorLjava_io_ReaderI() {
+ lnr = new LineNumberReader(new StringReader(text));
+ assertEquals("Failed to create reader", 0, lnr.getLineNumber());
+ }
+
+ /**
+ * java.io.LineNumberReader#getLineNumber()
+ */
+ public void test_getLineNumber() throws IOException {
+ lnr = new LineNumberReader(new StringReader(text));
+ assertEquals("Returned incorrect line number--expected 0, got ", 0, lnr
+ .getLineNumber());
+
+ lnr.readLine();
+ lnr.readLine();
+
+ assertTrue("Returned incorrect line number--expected 2, got: "
+ + lnr.getLineNumber(), lnr.getLineNumber() == 2);
+ }
+
+ /**
+ * java.io.LineNumberReader#mark(int)
+ */
+ public void test_markI() throws IOException {
+ lnr = new LineNumberReader(new StringReader(text));
+ String line;
+ lnr.skip(80);
+ lnr.mark(100);
+ line = lnr.readLine();
+ lnr.reset();
+ assertTrue("Failed to return to marked position", line.equals(lnr
+ .readLine()));
+ // The spec does not say the mark has to be invalidated
+ }
+
+ /**
+ * java.io.LineNumberReader#read()
+ */
+ public void test_read() throws IOException {
+ lnr = new LineNumberReader(new StringReader(text));
+
+ int c = lnr.read();
+ assertEquals("Read returned incorrect character", '0', c);
+
+ lnr.read();
+ assertEquals("Read failed to inc lineNumber", 1, lnr.getLineNumber());
+ }
+
+ /**
+ * java.io.LineNumberReader#read(char[], int, int)
+ */
+ public void test_read$CII() throws IOException {
+ lnr = new LineNumberReader(new StringReader(text));
+ char[] c = new char[100];
+ lnr.read(c, 0, 4);
+ assertTrue("Read returned incorrect characters", "0\n1\n"
+ .equals(new String(c, 0, 4)));
+ assertEquals("Read failed to inc lineNumber", 2, lnr.getLineNumber());
+ }
+
+ /**
+ * java.io.LineNumberReader#readLine()
+ */
+ public void test_readLine() throws IOException {
+ lnr = new LineNumberReader(new StringReader(text));
+ assertEquals("Returned incorrect line number", 0, lnr.getLineNumber());
+ String line = null;
+ lnr.readLine();
+ line = lnr.readLine();
+
+ assertEquals("Returned incorrect string", "1", line);
+ assertTrue("Returned incorrect line number :" + lnr.getLineNumber(),
+ lnr.getLineNumber() == 2);
+
+ // Regression for HARMONY-4294
+ byte[] buffer = new byte[] { '\r', '\n' };
+ LineNumberReader reader = new LineNumberReader(new InputStreamReader(
+ new ByteArrayInputStream(buffer), "UTF-8"));
+ assertEquals('\n', reader.read());
+ assertEquals(-1, reader.read());
+ reader = new LineNumberReader(new InputStreamReader(
+ new ByteArrayInputStream(buffer), "UTF-8"));
+ assertNotNull(reader.readLine());
+ assertNull(reader.readLine());
+ }
+
+ /**
+ * java.io.LineNumberReader#reset()
+ */
+ public void test_reset() throws IOException {
+ lnr = new LineNumberReader(new StringReader(text));
+ assertEquals("Returned incorrect line number", 0, lnr.getLineNumber());
+ String line = null;
+ lnr.mark(100);
+ lnr.readLine();
+ lnr.reset();
+ line = lnr.readLine();
+
+ assertEquals("Failed to reset reader", "0", line);
+ }
+
+ public void testReadLineSourceThrows() throws IOException {
+ lnr = new LineNumberReader(new Reader() {
+ private StringReader delegate = new StringReader("hello\nworld");
+ private int calls = 0;
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public int read(char[] buf, int offset, int len) throws IOException {
+ if (calls++ < 2) {
+ throw new IOException();
+ } else {
+ return delegate.read(buf, offset, len);
+ }
+ }
+ });
+
+ assertEquals(0, lnr.getLineNumber());
+ try {
+ lnr.readLine();
+ fail();
+ } catch (IOException expected) {
+ }
+
+ assertEquals(0, lnr.getLineNumber());
+ try {
+ lnr.readLine();
+ fail();
+ } catch (IOException expected) {
+ }
+
+ assertEquals(0, lnr.getLineNumber());
+ assertEquals("hello", lnr.readLine());
+ assertEquals(1, lnr.getLineNumber());
+ assertEquals("world", lnr.readLine());
+ assertEquals(2, lnr.getLineNumber());
+ }
+
+ public void testGetLineNumberAfterEnd() throws IOException {
+ lnr = new LineNumberReader(new StringReader("hello\nworld"));
+ assertEquals(0, lnr.getLineNumber());
+ assertEquals("hello", lnr.readLine());
+ assertEquals(1, lnr.getLineNumber());
+ assertEquals("world", lnr.readLine());
+ assertEquals(2, lnr.getLineNumber());
+ assertEquals(null, lnr.readLine());
+ assertEquals(2, lnr.getLineNumber());
+ assertEquals(null, lnr.readLine());
+ assertEquals(2, lnr.getLineNumber());
+ }
+
+ /**
+ * java.io.LineNumberReader#setLineNumber(int)
+ */
+ public void test_setLineNumberI() {
+ lnr = new LineNumberReader(new StringReader(text));
+ lnr.setLineNumber(1001);
+ assertEquals("set incorrect line number", 1001, lnr.getLineNumber());
+ }
+
+ /**
+ * java.io.LineNumberReader#skip(long)
+ */
+ public void test_skipJ() throws IOException {
+ lnr = new LineNumberReader(new StringReader(text));
+ char[] c = new char[100];
+ lnr.skip(80);
+ lnr.read(c, 0, 100);
+
+ assertTrue("Failed to skip to correct position", text
+ .substring(80, 180).equals(new String(c, 0, c.length)));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/NotActiveExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/NotActiveExceptionTest.java
new file mode 100644
index 0000000..cd62bbc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/NotActiveExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.NotActiveException;
+
+import junit.framework.TestCase;
+
+public class NotActiveExceptionTest extends TestCase {
+
+ /**
+ * java.io.NotActiveException#NotActiveException()
+ */
+ public void test_Constructor() {
+ NotActiveException e = new NotActiveException();
+ assertNull(e.getMessage());
+ }
+
+ /**
+ * java.io.NotActiveException#NotActiveException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ String message = "Exception message";
+ NotActiveException e = new NotActiveException(message);
+ assertSame(message, e.getMessage());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/NotSerializableExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/NotSerializableExceptionTest.java
new file mode 100644
index 0000000..9df51a0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/NotSerializableExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.NotSerializableException;
+
+import junit.framework.TestCase;
+
+public class NotSerializableExceptionTest extends TestCase {
+
+ /**
+ * java.io.NotSerializableException#NotSerializableException()
+ */
+ public void test_Constructor() {
+ NotSerializableException nse = new NotSerializableException();
+ assertNull(nse.getMessage());
+ }
+
+ /**
+ * java.io.NotSerializableException#NotSerializableException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ String message = "Test message";
+ NotSerializableException nse = new NotSerializableException(message);
+ assertSame(message, nse.getMessage());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java
new file mode 100644
index 0000000..af5fce5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidClassException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class ObjectInputStream2Test extends TestCase {
+
+ public void test_readUnshared() throws IOException, ClassNotFoundException {
+ // Regression test for HARMONY-819
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject("abc");
+ oos.writeObject("abc");
+ oos.close();
+
+ ObjectInputStream ois = new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray()));
+ ois.readUnshared();
+ ois.readObject();
+ ois.close();
+ fail("Expected ObjectStreamException");
+ } catch (ObjectStreamException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Micro-scenario of de/serialization of an object with non-serializable
+ * superclass. The super-constructor only should be invoked on the
+ * deserialized instance.
+ */
+ public void test_readObject_Hierarchy() throws IOException,
+ ClassNotFoundException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(new B());
+ oos.close();
+
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+ baos.toByteArray()));
+ B b = (B) ois.readObject();
+ ois.close();
+
+ assertTrue("should construct super", A.list.contains(b));
+ assertFalse("should not construct self", B.list.contains(b));
+ assertEquals("super field A.s", A.DEFAULT, ((A) b).s);
+ assertNull("transient field B.s", b.s);
+ }
+
+ /**
+ * {@link java.io.ObjectInputStream#readNewLongString()}
+ */
+ public void test_readNewLongString() throws Exception {
+ LongString longString = new LongString();
+ SerializationTest.verifySelf(longString);
+ }
+
+ @SuppressWarnings("serial")
+ private static class LongString implements Serializable {
+ String lString;
+
+ public LongString() {
+ StringBuilder builder = new StringBuilder();
+ // construct a string whose length > 64K
+ for (int i = 0; i < 65636; i++) {
+ builder.append('1');
+ }
+ lString = builder.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof LongString) {
+ LongString l = (LongString) o;
+ return l.lString.equals(l.lString);
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return lString.hashCode();
+ }
+ }
+
+ static class A {
+ static final ArrayList<A> list = new ArrayList<A>();
+ String s;
+ public static final String DEFAULT = "aaa";
+
+ public A() {
+ s = DEFAULT;
+ list.add(this);
+ }
+ }
+
+ static class B extends A implements Serializable {
+ private static final long serialVersionUID = 1L;
+ static final ArrayList<A> list = new ArrayList<A>();
+ transient String s;
+
+ public B() {
+ s = "bbb";
+ list.add(this);
+ }
+ }
+
+ class OIS extends ObjectInputStream {
+
+ OIS() throws IOException {
+ super();
+ }
+
+ void test() throws ClassNotFoundException, IOException {
+ readClassDescriptor();
+ }
+
+ }
+
+ public void test_readClassDescriptor() throws ClassNotFoundException,
+ IOException {
+ try {
+ new OIS().test();
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ static class TestObjectInputStream extends ObjectInputStream {
+ public TestObjectInputStream(InputStream in) throws IOException {
+ super(in);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Class resolveClass(ObjectStreamClass desc)
+ throws IOException, ClassNotFoundException {
+ if (desc.getName().endsWith("ObjectInputStream2Test$TestClass1")) {
+ return TestClass2.class;
+ }
+ return super.resolveClass(desc);
+ }
+ }
+
+ static class TestClass1 implements Serializable {
+ private static final long serialVersionUID = 11111L;
+ int i = 0;
+ }
+
+ static class TestClass2 implements Serializable {
+ private static final long serialVersionUID = 11111L;
+ int i = 0;
+ }
+
+ public void test_resolveClass_invalidClassName() throws Exception {
+ // Regression test for HARMONY-1920
+ TestClass1 to1 = new TestClass1();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ ByteArrayInputStream bais;
+ ObjectInputStream ois;
+
+ to1.i = 555;
+ oos.writeObject(to1);
+ oos.flush();
+ byte[] bytes = baos.toByteArray();
+ bais = new ByteArrayInputStream(bytes);
+ ois = new TestObjectInputStream(bais);
+
+ try {
+ ois.readObject();
+ fail("Should throw InvalidClassException");
+ } catch (InvalidClassException ice) {
+ // Excpected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectOutputStream2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectOutputStream2Test.java
new file mode 100644
index 0000000..99546c4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectOutputStream2Test.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import junit.framework.TestCase;
+
+public class ObjectOutputStream2Test extends TestCase {
+
+ private static enum MyEnum {
+ ONE {
+ public void anything() {
+ }
+ },
+ TWO {
+ public void anything() {
+ }
+ },
+ THREE {
+ public void anything() {
+ }
+ };
+
+ public abstract void anything();
+ }
+
+ public void test_writeReadEnum() throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+ os.writeObject(MyEnum.TWO);
+ os.close();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ ObjectInputStream is = new ObjectInputStream(bis);
+ Object readObj = is.readObject();
+ is.close();
+ assertSame(MyEnum.TWO, readObj);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectOutputStreamTest.java
new file mode 100644
index 0000000..1c98257
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectOutputStreamTest.java
@@ -0,0 +1,1323 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.NotActiveException;
+import java.io.NotSerializableException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamConstants;
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.SerializablePermission;
+import java.io.WriteAbortedException;
+import java.security.Permission;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings({ "unused", "serial" })
+public class ObjectOutputStreamTest extends TestCase implements Serializable {
+
+ File f;
+
+ public class SerializableTestHelper implements Serializable {
+ public String aField1;
+
+ public String aField2;
+
+ SerializableTestHelper() {
+ aField1 = null;
+ aField2 = null;
+ }
+
+ SerializableTestHelper(String s, String t) {
+ aField1 = s;
+ aField2 = t;
+ }
+
+ private void readObject(ObjectInputStream ois) throws IOException {
+ // note aField2 is not read
+ try {
+ ObjectInputStream.GetField fields = ois.readFields();
+ aField1 = (String) fields.get("aField1", "Zap");
+ } catch (Exception e) {
+ }
+ }
+
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ // note aField2 is not written
+ ObjectOutputStream.PutField fields = oos.putFields();
+ fields.put("aField1", aField1);
+ oos.writeFields();
+ }
+
+ public String getText1() {
+ return aField1;
+ }
+
+ public void setText1(String s) {
+ aField1 = s;
+ }
+
+ public String getText2() {
+ return aField2;
+ }
+
+ public void setText2(String s) {
+ aField2 = s;
+ }
+ }
+
+ private static class SerializationTest implements java.io.Serializable {
+ int anInt = INIT_INT_VALUE;
+
+ public SerializationTest() {
+ super();
+ }
+ }
+
+ private static class SerializationTestSubclass1 extends SerializationTest
+ implements Serializable {
+ String aString = INIT_STR_VALUE;
+
+ public SerializationTestSubclass1() {
+ super();
+ // Just to change default superclass init value
+ anInt = INIT_INT_VALUE / 2;
+ }
+ }
+
+ private static class SpecTestSuperClass implements Runnable, Serializable {
+ protected java.lang.String instVar;
+
+ public void run() {
+ }
+ }
+
+ private static class SpecTest extends SpecTestSuperClass implements
+ Cloneable, Serializable {
+ public java.lang.String instVar1;
+
+ public static java.lang.String staticVar1;
+
+ public static java.lang.String staticVar2;
+
+ {
+ instVar1 = "NonStaticInitialValue";
+ }
+
+ static {
+ staticVar1 = "StaticInitialValue";
+ staticVar1 = new String(staticVar1);
+ }
+
+ public Object method(Object objParam, Object objParam2) {
+ return new Object();
+ }
+
+ public boolean method(boolean bParam, Object objParam) {
+ return true;
+ }
+
+ public boolean method(boolean bParam, Object objParam, Object objParam2) {
+ return true;
+ }
+
+ }
+
+ private static class SpecTestSubclass extends SpecTest implements
+ Serializable {
+ public transient java.lang.String transientInstVar = "transientValue";
+ }
+
+ private static class ReadWriteObject implements java.io.Serializable {
+ public boolean calledWriteObject = false;
+
+ public boolean calledReadObject = false;
+
+ public ReadWriteObject() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ calledReadObject = true;
+ in.readObject();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
+ calledWriteObject = true;
+ out.writeObject(FOO);
+ }
+ }
+
+ private static class PublicReadWriteObject implements java.io.Serializable {
+ public boolean calledWriteObject = false;
+
+ public boolean calledReadObject = false;
+
+ public PublicReadWriteObject() {
+ super();
+ }
+
+ public void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ calledReadObject = true;
+ in.readObject();
+ }
+
+ public void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
+ calledWriteObject = true;
+ out.writeObject(FOO);
+ }
+ }
+
+ private static class FieldOrder implements Serializable {
+ String aaa1NonPrimitive = "aaa1";
+
+ int bbb1PrimitiveInt = 5;
+
+ boolean aaa2PrimitiveBoolean = true;
+
+ String bbb2NonPrimitive = "bbb2";
+ }
+
+ private static class JustReadObject implements java.io.Serializable {
+ public boolean calledReadObject = false;
+
+ public JustReadObject() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ calledReadObject = true;
+ in.defaultReadObject();
+ }
+ }
+
+ private static class JustWriteObject implements java.io.Serializable {
+ public boolean calledWriteObject = false;
+
+ public JustWriteObject() {
+ super();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ calledWriteObject = true;
+ out.defaultWriteObject();
+ }
+ }
+
+ private static class ClassBasedReplacementWhenDumping implements
+ java.io.Serializable {
+ public boolean calledReplacement = false;
+
+ public ClassBasedReplacementWhenDumping() {
+ super();
+ }
+
+ private Object writeReplace() {
+ calledReplacement = true;
+ return FOO; // Replacement is a String
+ }
+ }
+
+ private static class MultipleClassBasedReplacementWhenDumping implements
+ java.io.Serializable {
+ private static class C1 implements java.io.Serializable {
+ private Object writeReplace() {
+ return new C2();
+ }
+ }
+
+ private static class C2 implements java.io.Serializable {
+ private Object writeReplace() {
+ return new C3();
+ }
+ }
+
+ private static class C3 implements java.io.Serializable {
+ private Object writeReplace() {
+ return FOO;
+ }
+ }
+
+ public MultipleClassBasedReplacementWhenDumping() {
+ super();
+ }
+
+ private Object writeReplace() {
+ return new C1();
+ }
+ }
+
+ private static class ClassBasedReplacementWhenLoading implements
+ java.io.Serializable {
+ public ClassBasedReplacementWhenLoading() {
+ super();
+ }
+
+ private Object readResolve() {
+ return FOO; // Replacement is a String
+ }
+ }
+
+ private static class ClassBasedReplacementWhenLoadingViolatesFieldType
+ implements java.io.Serializable {
+ public ClassBasedReplacementWhenLoading classBasedReplacementWhenLoading = new ClassBasedReplacementWhenLoading();
+
+ public ClassBasedReplacementWhenLoadingViolatesFieldType() {
+ super();
+ }
+ }
+
+ private static class MyExceptionWhenDumping implements java.io.Serializable {
+ private static class MyException extends java.io.IOException {
+ }
+
+ ;
+
+ public boolean anInstanceVar = false;
+
+ public MyExceptionWhenDumping() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ throw new MyException();
+ }
+ }
+
+ private static class NonSerializableExceptionWhenDumping implements
+ java.io.Serializable {
+ public Object anInstanceVar = new Object();
+
+ public NonSerializableExceptionWhenDumping() {
+ super();
+ }
+ }
+
+ private static class MyUnserializableExceptionWhenDumping implements
+ java.io.Serializable {
+ private static class MyException extends java.io.IOException {
+ private Object notSerializable = new Object();
+ }
+
+ ;
+
+ public boolean anInstanceVar = false;
+
+ public MyUnserializableExceptionWhenDumping() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ throw new MyException();
+ }
+ }
+
+ private static class WithUnmatchingSerialPersistentFields implements
+ java.io.Serializable {
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ "value", String.class) };
+
+ public int anInstanceVar = 5;
+
+ public WithUnmatchingSerialPersistentFields() {
+ super();
+ }
+ }
+
+ private static class WithMatchingSerialPersistentFields implements
+ java.io.Serializable {
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ "anInstanceVar", String.class) };
+
+ public String anInstanceVar = FOO + FOO;
+
+ public WithMatchingSerialPersistentFields() {
+ super();
+ }
+ }
+
+ private static class SerialPersistentFields implements java.io.Serializable {
+ private static final String SIMULATED_FIELD_NAME = "text";
+
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ SIMULATED_FIELD_NAME, String.class) };
+
+ public int anInstanceVar = 5;
+
+ public SerialPersistentFields() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ ObjectInputStream.GetField fields = in.readFields();
+ anInstanceVar = Integer.parseInt((String) fields.get(
+ SIMULATED_FIELD_NAME, "-5"));
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ ObjectOutputStream.PutField fields = out.putFields();
+ fields.put(SIMULATED_FIELD_NAME, Integer.toString(anInstanceVar));
+ out.writeFields();
+ }
+ }
+
+ private static class WriteFieldsWithoutFetchingPutFields implements
+ java.io.Serializable {
+ private static final String SIMULATED_FIELD_NAME = "text";
+
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ SIMULATED_FIELD_NAME, String.class) };
+
+ public int anInstanceVar = 5;
+
+ public WriteFieldsWithoutFetchingPutFields() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ in.readFields();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ out.writeFields();
+ }
+ }
+
+ private static class SerialPersistentFieldsWithoutField implements
+ java.io.Serializable {
+ public int anInstanceVar = 5;
+
+ public SerialPersistentFieldsWithoutField() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ in.readFields();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ out.putFields();
+ out.writeFields();
+ }
+ }
+
+ private static class NotSerializable {
+ private int foo;
+
+ public NotSerializable() {
+ }
+
+ protected Object writeReplace() throws ObjectStreamException {
+ return new Integer(42);
+ }
+ }
+
+ private static class WriteReplaceObject implements Serializable {
+ private Object replaceObject;
+
+ private static enum Color {
+ red, blue, green
+ }
+
+ ;
+
+ public WriteReplaceObject(Object o) {
+ replaceObject = o;
+ }
+
+ protected Object writeReplace() throws ObjectStreamException {
+ return replaceObject;
+ }
+ }
+
+ private static class ExternalizableWithReplace implements Externalizable {
+ private int foo;
+
+ public ExternalizableWithReplace() {
+ }
+
+ protected Object writeReplace() throws ObjectStreamException {
+ return new Integer(42);
+ }
+
+ public void writeExternal(ObjectOutput out) {
+ }
+
+ public void readExternal(ObjectInput in) {
+ }
+ }
+
+ private static class ObjectOutputStreamWithReplace extends
+ ObjectOutputStream {
+ public ObjectOutputStreamWithReplace(OutputStream out)
+ throws IOException {
+ super(out);
+ enableReplaceObject(true);
+ }
+
+ protected Object replaceObject(Object obj) throws IOException {
+ if (obj instanceof NotSerializable) {
+ return new Long(10);
+ }
+ if (obj instanceof Integer) {
+ return new Long(((Integer) obj).longValue());
+ }
+ return super.replaceObject(obj);
+ }
+ }
+
+ private static class ObjectOutputStreamWithReplace2 extends
+ ObjectOutputStream {
+ public ObjectOutputStreamWithReplace2(OutputStream out)
+ throws IOException {
+ super(out);
+ enableReplaceObject(true);
+ }
+
+ protected Object replaceObject(Object obj) throws IOException {
+ return new Long(10);
+ }
+ }
+
+ private static class ObjectOutputStreamWriteOverride extends
+ ObjectOutputStream {
+ String test = "test";
+
+ protected ObjectOutputStreamWriteOverride() throws IOException,
+ SecurityException {
+ super();
+ }
+
+ @Override
+ protected void writeObjectOverride(Object object) throws IOException {
+ test = null;
+ super.writeObjectOverride(object);
+ }
+ }
+
+ protected static final String MODE_XLOAD = "xload";
+
+ protected static final String MODE_XDUMP = "xdump";
+
+ static final String FOO = "foo";
+
+ static final String MSG_WITE_FAILED = "Failed to write: ";
+
+ private static final boolean DEBUG = false;
+
+ protected static boolean xload = false;
+
+ protected static boolean xdump = false;
+
+ protected static String xFileName = null;
+
+ protected ObjectInputStream ois;
+
+ protected ObjectOutputStream oos;
+
+ protected ByteArrayOutputStream bao;
+
+ static final int INIT_INT_VALUE = 7;
+
+ static final String INIT_STR_VALUE = "a string that is blortz";
+
+ /**
+ * java.io.ObjectOutputStream#ObjectOutputStream(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() throws IOException {
+ // Test for method java.io.ObjectOutputStream(java.io.OutputStream)
+ oos.close();
+ oos = new ObjectOutputStream(new ByteArrayOutputStream());
+ oos.close();
+ }
+
+ /**
+ * java.io.ObjectOutputStream#close()
+ */
+ public void test_close() {
+ // Test for method void java.io.ObjectOutputStream.close()
+ }
+
+ /**
+ * java.io.ObjectOutputStream#defaultWriteObject()
+ */
+ public void test_defaultWriteObject() throws IOException {
+ // Test for method void java.io.ObjectOutputStream.defaultWriteObject()
+ try {
+ oos.defaultWriteObject();
+ fail("Failed to throw NotActiveException");
+ } catch (NotActiveException e) {
+ // Correct
+ }
+ }
+
+ /**
+ * java.io.ObjectOutputStream#flush()
+ */
+ public void test_flush() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.flush()
+ int size = bao.size();
+ oos.writeByte(127);
+ assertTrue("Data flushed already", bao.size() == size);
+ oos.flush();
+ assertTrue("Failed to flush data", bao.size() > size);
+ // we don't know how many bytes are actually written for 1
+ // byte, so we test > <before>
+ oos.close();
+ oos = null;
+ }
+
+ /**
+ * java.io.ObjectOutputStream#putFields()
+ */
+ public void test_putFields() throws Exception {
+ // Test for method java.io.ObjectOutputStream$PutField
+ // java.io.ObjectOutputStream.putFields()
+
+ SerializableTestHelper sth;
+
+ /*
+ * "SerializableTestHelper" is an object created for these tests with
+ * two fields (Strings) and simple implementations of readObject and
+ * writeObject which simply read and write the first field but not the
+ * second
+ */
+
+ oos.writeObject(new SerializableTestHelper("Gabba", "Jabba"));
+ oos.flush();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ sth = (SerializableTestHelper) (ois.readObject());
+ assertEquals("readFields / writeFields failed--first field not set",
+ "Gabba", sth.getText1());
+ assertNull(
+ "readFields / writeFields failed--second field should not have been set",
+ sth.getText2());
+ }
+
+ /**
+ * java.io.ObjectOutputStream#reset()
+ */
+ public void test_reset() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.reset()
+ String o = "HelloWorld";
+ oos.writeObject(o);
+ oos.writeObject(o);
+ oos.reset();
+ oos.writeObject(o);
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ois.close();
+ }
+
+ private static class ExternalTest implements Externalizable {
+ public String value;
+
+ public ExternalTest() {
+ }
+
+ public void setValue(String val) {
+ value = val;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void writeExternal(ObjectOutput output) {
+ try {
+ output.writeUTF(value);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void readExternal(ObjectInput input) {
+ try {
+ value = input.readUTF();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * java.io.ObjectOutputStream#useProtocolVersion(int)
+ */
+ public void test_useProtocolVersionI() throws Exception {
+ // Test for method void
+ // java.io.ObjectOutputStream.useProtocolVersion(int)
+ oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_1);
+ ExternalTest t1 = new ExternalTest();
+ t1.setValue("hello1");
+ oos.writeObject(t1);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ExternalTest t2 = (ExternalTest) ois.readObject();
+ ois.close();
+ assertTrue(
+ "Cannot read/write PROTOCAL_VERSION_1 Externalizable objects: "
+ + t2.getValue(), t1.getValue().equals(t2.getValue()));
+
+ // Cannot set protocol version when stream in-flight
+ ObjectOutputStream out = new ObjectOutputStream(
+ new ByteArrayOutputStream());
+ out.writeObject("hello world");
+ try {
+ out.useProtocolVersion(ObjectStreamConstants.PROTOCOL_VERSION_1);
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.ObjectOutputStream#write(byte[])
+ */
+ public void test_write$B() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.write(byte [])
+ byte[] buf = new byte[10];
+ oos.write("HelloWorld".getBytes());
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ois.read(buf, 0, 10);
+ ois.close();
+ assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
+ 10));
+ }
+
+ /**
+ * java.io.ObjectOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.write(byte [], int,
+ // int)
+ byte[] buf = new byte[10];
+ oos.write("HelloWorld".getBytes(), 0, 10);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ois.read(buf, 0, 10);
+ ois.close();
+ assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
+ 10));
+ }
+
+ /**
+ * java.io.ObjectOutputStream#write(int)
+ */
+ public void test_writeI() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.write(int)
+ oos.write('T');
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertEquals("Read incorrect byte", 'T', ois.read());
+ ois.close();
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeBoolean(boolean)
+ */
+ public void test_writeBooleanZ() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean)
+ oos.writeBoolean(true);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertTrue("Wrote incorrect byte value", ois.readBoolean());
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeByte(int)
+ */
+ public void test_writeByteI() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.writeByte(int)
+ oos.writeByte(127);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertEquals("Wrote incorrect byte value", 127, ois.readByte());
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeBytes(java.lang.String)
+ */
+ public void test_writeBytesLjava_lang_String() throws Exception {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeBytes(java.lang.String)
+ byte[] buf = new byte[10];
+ oos.writeBytes("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ois.readFully(buf);
+ ois.close();
+ assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(
+ buf, 0, 10, "UTF-8"));
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeChar(int)
+ */
+ public void test_writeCharI() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.writeChar(int)
+ oos.writeChar('T');
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertEquals("Wrote incorrect char value", 'T', ois.readChar());
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeChars(java.lang.String)
+ */
+ public void test_writeCharsLjava_lang_String() throws Exception {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeChars(java.lang.String)
+ int avail = 0;
+ char[] buf = new char[10];
+ oos.writeChars("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ // Number of prim data bytes in stream / 2 to give char index
+ avail = ois.available() / 2;
+ for (int i = 0; i < avail; ++i)
+ buf[i] = ois.readChar();
+ ois.close();
+ assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0,
+ 10));
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeDouble(double)
+ */
+ public void test_writeDoubleD() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.writeDouble(double)
+ oos.writeDouble(Double.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertTrue("Wrote incorrect double value",
+ ois.readDouble() == Double.MAX_VALUE);
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeFields()
+ */
+ public void test_writeFields() {
+ // Test for method void java.io.ObjectOutputStream.writeFields()
+ assertTrue("Used to test", true);
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeFloat(float)
+ */
+ public void test_writeFloatF() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.writeFloat(float)
+ oos.writeFloat(Float.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertTrue("Wrote incorrect double value",
+ ois.readFloat() == Float.MAX_VALUE);
+ ois.close();
+ ois = null;
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeInt(int)
+ */
+ public void test_writeIntI() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.writeInt(int)
+ oos.writeInt(Integer.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertTrue("Wrote incorrect double value",
+ ois.readInt() == Integer.MAX_VALUE);
+ ois.close();
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeLong(long)
+ */
+ public void test_writeLongJ() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.writeLong(long)
+ oos.writeLong(Long.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertTrue("Wrote incorrect double value",
+ ois.readLong() == Long.MAX_VALUE);
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeObject(java.lang.Object)
+ */
+ public void test_writeObjectLjava_lang_Object() throws Exception {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ SerialPersistentFieldsWithoutField spf = new SerialPersistentFieldsWithoutField();
+ final int CONST = -500;
+ spf.anInstanceVar = CONST;
+ objToSave = spf;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(
+ "serialPersistentFields do not work properly in this implementation",
+ ((SerialPersistentFieldsWithoutField) objLoaded).anInstanceVar != CONST);
+
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeObject(java.lang.Object)
+ */
+ public void test_writeObject_NotSerializable() throws Exception {
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(new ByteArrayOutputStream());
+ out.writeObject(new NotSerializable());
+ fail("Expected NotSerializableException");
+ } catch (NotSerializableException e) {
+ }
+ out.writeObject(new ExternalizableWithReplace());
+ }
+
+ /**
+ * {@link java.io.ObjectOutputStream#writeObjectOverride(Object)}
+ */
+ public void test_writeObject_WriteOverride() throws Exception {
+ ObjectOutputStreamWriteOverride mockOut = new ObjectOutputStreamWriteOverride();
+ mockOut.writeObject(new Object());
+ assertNull(mockOut.test);
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeShort(int)
+ */
+ public void test_writeShortI() throws Exception {
+ // Test for method void java.io.ObjectOutputStream.writeShort(int)
+ oos.writeShort(127);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertEquals("Wrote incorrect short value", 127, ois.readShort());
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeUTF(java.lang.String)
+ */
+ public void test_writeUTFLjava_lang_String() throws Exception {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeUTF(java.lang.String)
+ oos.writeUTF("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertEquals("Wrote incorrect UTF value", "HelloWorld", ois.readUTF());
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeObject(java.lang.Object)
+ */
+ public void test_writeObject_Exception() throws ClassNotFoundException,
+ IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ try {
+ oos.writeObject(new Object());
+ fail("should throw ObjectStreamException");
+ } catch (ObjectStreamException e) {
+ // expected
+ } finally {
+ oos.close();
+ baos.close();
+ }
+
+ byte[] bytes = baos.toByteArray();
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+ bytes));
+ try {
+ ois.readObject();
+ fail("should throw WriteAbortedException");
+ } catch (WriteAbortedException e) {
+ // expected
+ } finally {
+ ois.close();
+ }
+ }
+
+ /**
+ * {@link java.io.ObjectOutputStream#annotateProxyClass(java.lang.Class<T>)}
+ */
+ public void test_annotateProxyClass() throws SecurityException, IOException {
+ MockObjectOutputStream mockObjectOutputStream = new MockObjectOutputStream();
+ mockObjectOutputStream.annotateProxyClass(this.getClass());
+ assertEquals("The default implementation is doing nothing.",
+ mockObjectOutputStream, mockObjectOutputStream);
+
+ }
+
+ class MockObjectOutputStream extends ObjectOutputStream {
+
+ protected MockObjectOutputStream() throws IOException,
+ SecurityException {
+ super();
+ }
+
+ @Override
+ public void annotateProxyClass(Class<?> aClass) throws IOException {
+ super.annotateProxyClass(aClass);
+ }
+
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (oos != null) {
+ try {
+ oos.close();
+ } catch (Exception e) {
+ }
+ }
+ if (f != null && f.exists()) {
+ if (!f.delete()) {
+ fail("Error cleaning up files during teardown");
+ }
+ }
+ }
+
+ protected Object reload() throws IOException, ClassNotFoundException {
+
+ // Choose the load stream
+ if (xload || xdump) {
+ // Load from pre-existing file
+ ois = new ObjectInputStream(new FileInputStream(xFileName + "-"
+ + getName() + ".ser"));
+ } else {
+ // Just load from memory, we dumped to memory
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao
+ .toByteArray()));
+ }
+
+ try {
+ return ois.readObject();
+ } finally {
+ ois.close();
+ }
+ }
+
+ protected void dump(Object o) throws IOException, ClassNotFoundException {
+
+ // Choose the dump stream
+ if (xdump) {
+ oos = new ObjectOutputStream(new FileOutputStream(
+ f = new java.io.File(xFileName + "-" + getName() + ".ser")));
+ } else {
+ oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+ }
+
+ // Dump the object
+ try {
+ oos.writeObject(o);
+ } finally {
+ oos.close();
+ }
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeInt(int)
+ * java.io.ObjectOutputStream#writeObject(java.lang.Object)
+ * java.io.ObjectOutputStream#writeUTF(java.lang.String)
+ */
+
+ public void testMixPrimitivesAndObjects() throws Exception {
+ int i = 7;
+ String s1 = "string 1";
+ String s2 = "string 2";
+ byte[] bytes = { 1, 2, 3 };
+ try {
+ oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+ oos.writeInt(i);
+ oos.writeObject(s1);
+ oos.writeUTF(s2);
+ oos.writeObject(bytes);
+ oos.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao
+ .toByteArray()));
+
+ int j = ois.readInt();
+ assertTrue("Wrong int :" + j, i == j);
+
+ String l1 = (String) ois.readObject();
+ assertTrue("Wrong obj String :" + l1, s1.equals(l1));
+
+ String l2 = ois.readUTF();
+ assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
+
+ byte[] bytes2 = (byte[]) ois.readObject();
+ assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
+ } finally {
+ try {
+ if (oos != null)
+ oos.close();
+ if (ois != null)
+ ois.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeUnshared(java.lang.Object)
+ */
+ public void test_writeUnshared() throws Exception {
+ // Regression for HARMONY-187
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ Object o = "foobar";
+ oos.writeObject(o);
+ oos.writeUnshared(o);
+ oos.writeObject(o);
+ oos.flush();
+
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+ baos.toByteArray()));
+
+ Object[] oa = new Object[3];
+ for (int i = 0; i < oa.length; i++) {
+ oa[i] = ois.readObject();
+ }
+
+ oos.close();
+ ois.close();
+
+ // All three conditions must be met
+ assertNotSame("oa[0] != oa[1]", oa[0], oa[1]);
+ assertNotSame("oa[1] != oa[2]", oa[1], oa[2]);
+ assertSame("oa[0] == oa[2]", oa[0], oa[2]);
+ }
+
+ /**
+ * java.io.ObjectOutputStream#writeUnshared(java.lang.Object)
+ */
+ public void test_writeUnshared2() throws Exception {
+ // Regression for HARMONY-187
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ Object o = new Object[1];
+ oos.writeObject(o);
+ oos.writeUnshared(o);
+ oos.writeObject(o);
+ oos.flush();
+
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+ baos.toByteArray()));
+
+ Object[] oa = new Object[3];
+ for (int i = 0; i < oa.length; i++) {
+ oa[i] = ois.readObject();
+ }
+
+ oos.close();
+ ois.close();
+
+ // All three conditions must be met
+ assertNotSame("oa[0] != oa[1]", oa[0], oa[1]);
+ assertNotSame("oa[1] != oa[2]", oa[1], oa[2]);
+ assertSame("oa[0] == oa[2]", oa[0], oa[2]);
+ }
+
+ protected Object dumpAndReload(Object o) throws IOException,
+ ClassNotFoundException {
+ dump(o);
+ return reload();
+ }
+
+ /**
+ * java.io.ObjectOutputStream#useProtocolVersion(int)
+ */
+ public void test_useProtocolVersionI_2() throws Exception {
+ ObjectOutputStream oos = new ObjectOutputStream(
+ new ByteArrayOutputStream());
+
+ oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_1);
+ oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_2);
+ try {
+ oos.useProtocolVersion(3);
+ fail("Protocol 3 should not be accepted");
+ } catch (IllegalArgumentException e) {
+ // expected
+ } finally {
+ oos.close();
+ }
+ }
+
+ /**
+ * java.io.ObjectOutputStream#replaceObject(java.lang.Object)
+ */
+ public void test_replaceObject() throws Exception {
+ // Regression for HARMONY-1429
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStreamWithReplace oos = new ObjectOutputStreamWithReplace(
+ baos);
+
+ oos.writeObject(new NotSerializable());
+ oos.flush();
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+ baos.toByteArray()));
+ Object obj = ois.readObject();
+ oos.close();
+ ois.close();
+ assertTrue("replaceObject has not been called", (obj instanceof Long));
+
+ // Regression for HARMONY-2239
+ Object replaceObject = int.class;
+ baos = new ByteArrayOutputStream();
+ ObjectOutputStreamWithReplace2 oos2 = new ObjectOutputStreamWithReplace2(
+ baos);
+ oos2.writeObject(new WriteReplaceObject(replaceObject));
+ oos2.flush();
+ ois = new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray()));
+ obj = ois.readObject();
+ oos.close();
+ ois.close();
+ assertTrue("replaceObject has not been called", (obj instanceof Long));
+
+ replaceObject = ObjectStreamClass.lookup(Integer.class);
+ baos = new ByteArrayOutputStream();
+ oos2 = new ObjectOutputStreamWithReplace2(baos);
+ oos2.writeObject(new WriteReplaceObject(replaceObject));
+ oos2.flush();
+ ois = new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray()));
+ obj = ois.readObject();
+ oos.close();
+ ois.close();
+ assertTrue("replaceObject has not been called", (obj instanceof Long));
+
+ replaceObject = WriteReplaceObject.Color.red;
+ baos = new ByteArrayOutputStream();
+ oos2 = new ObjectOutputStreamWithReplace2(baos);
+ oos2.writeObject(new WriteReplaceObject(replaceObject));
+ oos2.flush();
+ ois = new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray()));
+ obj = ois.readObject();
+ oos.close();
+ ois.close();
+ assertTrue("replaceObject has not been called", (obj instanceof Long));
+
+ // Regression for HARMONY-3158
+ Object obj1;
+ Object obj2;
+ Object obj3;
+
+ baos = new ByteArrayOutputStream();
+ oos = new ObjectOutputStreamWithReplace(baos);
+
+ oos.writeObject(new Integer(99));
+ oos.writeObject(Integer.class);
+ oos.writeObject(ObjectStreamClass.lookup(Integer.class));
+ oos.flush();
+
+ ois = new ObjectInputStream(
+ new ByteArrayInputStream(baos.toByteArray()));
+ obj1 = ois.readObject();
+ obj2 = ois.readObject();
+ obj3 = ois.readObject();
+ oos.close();
+ ois.close();
+
+ assertTrue("1st replaceObject worked incorrectly", obj1 instanceof Long);
+ assertEquals("1st replaceObject worked incorrectly", 99, ((Long) obj1)
+ .longValue());
+ assertEquals("2nd replaceObject worked incorrectly", Integer.class,
+ obj2);
+ assertEquals("3rd replaceObject worked incorrectly",
+ ObjectStreamClass.class, obj3.getClass());
+ }
+
+ public void test_putFieldWrite() throws Exception {
+ // Regression test for HARMONY-6483
+ ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream());
+ try {
+ oos.writeObject(new OutputObject());
+ fail("Should throw an IllegalArgumentException");
+ } catch (IllegalArgumentException iae) {
+ // Expected
+ }
+ }
+
+ private static class OutputObject implements Serializable {
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ ObjectOutputStream oos2 = new ObjectOutputStream(new ByteArrayOutputStream());
+ ObjectOutputStream.PutField putField = oos.putFields();
+ putField.write(oos2);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
new file mode 100644
index 0000000..3806492
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import junit.framework.TestCase;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamField;
+import java.io.Serializable;
+import java.lang.reflect.Proxy;
+
+public class ObjectStreamClassTest extends TestCase {
+
+ static class DummyClass implements Serializable {
+ private static final long serialVersionUID = 999999999999999L;
+
+ long bam = 999L;
+
+ int ham = 9999;
+
+ public static long getUID() {
+ return serialVersionUID;
+ }
+ }
+
+ /**
+ * java.io.ObjectStreamClass#forClass()
+ */
+ public void test_forClass() {
+ // Need to test during serialization to be sure an instance is
+ // returned
+ ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+ assertEquals("forClass returned an object: " + osc.forClass(),
+ DummyClass.class, osc.forClass());
+ }
+
+ /**
+ * java.io.ObjectStreamClass#getField(java.lang.String)
+ */
+ public void test_getFieldLjava_lang_String() {
+ ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+ assertEquals("getField did not return correct field", 'J', osc
+ .getField("bam").getTypeCode());
+ assertNull("getField did not null for non-existent field", osc
+ .getField("wham"));
+ }
+
+ /**
+ * java.io.ObjectStreamClass#getFields()
+ */
+ public void test_getFields() {
+ ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+ ObjectStreamField[] osfArray = osc.getFields();
+ assertTrue(
+ "Array of fields should be of length 2 but is instead of length: "
+ + osfArray.length, osfArray.length == 2);
+ }
+
+ /**
+ * java.io.ObjectStreamClass#getName()
+ */
+ public void test_getName() {
+ ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+ assertEquals(
+ "getName returned incorrect name: " + osc.getName(),
+ "org.apache.harmony.tests.java.io.ObjectStreamClassTest$DummyClass",
+ osc.getName());
+ }
+
+ /**
+ * java.io.ObjectStreamClass#getSerialVersionUID()
+ */
+ public void test_getSerialVersionUID() {
+ ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+ assertTrue("getSerialversionUID returned incorrect uid: "
+ + osc.getSerialVersionUID() + " instead of "
+ + DummyClass.getUID(), osc.getSerialVersionUID() == DummyClass
+ .getUID());
+ }
+
+ static class SyntheticTest implements Serializable {
+ private int i;
+
+ private class X implements Serializable {
+ public int get() {
+ return i;
+ }
+ }
+
+ public X foo() {
+ return new X();
+ }
+ }
+
+ /**
+ * java.io.ObjectStreamClass#lookup(java.lang.Class)
+ */
+ public void test_lookupLjava_lang_Class() {
+ ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+ assertEquals(
+ "lookup returned wrong class: " + osc.getName(),
+ "org.apache.harmony.tests.java.io.ObjectStreamClassTest$DummyClass",
+ osc.getName());
+ }
+
+ /**
+ * java.io.ObjectStreamClass#toString()
+ */
+ public void test_toString() {
+ ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+ String oscString = osc.toString();
+
+ // The previous test was more specific than the spec so it was replaced
+ // with the test below
+ assertTrue("toString returned incorrect string: " + osc.toString(),
+ oscString.indexOf("serialVersionUID") >= 0
+ && oscString.indexOf("999999999999999L") >= 0);
+ }
+
+ public void testSerialization() {
+ ObjectStreamClass osc = ObjectStreamClass
+ .lookup(ObjectStreamClass.class);
+ assertEquals(0, osc.getFields().length);
+ }
+
+ public void test_specialTypes() {
+ Class<?> proxyClass = Proxy.getProxyClass(this.getClass()
+ .getClassLoader(), new Class[] { Runnable.class });
+
+ ObjectStreamClass proxyStreamClass = ObjectStreamClass
+ .lookup(proxyClass);
+
+ assertEquals("Proxy classes should have zero serialVersionUID", 0,
+ proxyStreamClass.getSerialVersionUID());
+ ObjectStreamField[] proxyFields = proxyStreamClass.getFields();
+ assertEquals("Proxy classes should have no serialized fields", 0,
+ proxyFields.length);
+
+ ObjectStreamClass enumStreamClass = ObjectStreamClass
+ .lookup(Thread.State.class);
+
+ assertEquals("Enum classes should have zero serialVersionUID", 0,
+ enumStreamClass.getSerialVersionUID());
+ ObjectStreamField[] enumFields = enumStreamClass.getFields();
+ assertEquals("Enum classes should have no serialized fields", 0,
+ enumFields.length);
+ }
+
+ /**
+ * @since 1.6
+ */
+ static class NonSerialzableClass {
+ private static final long serialVersionUID = 1l;
+
+ public static long getUID() {
+ return serialVersionUID;
+ }
+ }
+
+ /**
+ * @since 1.6
+ */
+ static class ExternalizableClass implements Externalizable {
+
+ private static final long serialVersionUID = -4285635779249689129L;
+
+ public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
+ throw new ClassNotFoundException();
+ }
+
+ public void writeExternal(ObjectOutput output) throws IOException {
+ throw new IOException();
+ }
+
+ }
+
+ /**
+ * java.io.ObjectStreamClass#lookupAny(java.lang.Class)
+ * @since 1.6
+ */
+ public void test_lookupAnyLjava_lang_Class() {
+ // Test for method java.io.ObjectStreamClass
+ // java.io.ObjectStreamClass.lookupAny(java.lang.Class)
+ ObjectStreamClass osc = ObjectStreamClass.lookupAny(DummyClass.class);
+ assertEquals("lookup returned wrong class: " + osc.getName(),
+ "org.apache.harmony.tests.java.io.ObjectStreamClassTest$DummyClass", osc
+ .getName());
+
+ osc = ObjectStreamClass.lookupAny(NonSerialzableClass.class);
+ assertEquals("lookup returned wrong class: " + osc.getName(),
+ "org.apache.harmony.tests.java.io.ObjectStreamClassTest$NonSerialzableClass",
+ osc.getName());
+
+ osc = ObjectStreamClass.lookupAny(ExternalizableClass.class);
+ assertEquals("lookup returned wrong class: " + osc.getName(),
+ "org.apache.harmony.tests.java.io.ObjectStreamClassTest$ExternalizableClass",
+ osc.getName());
+
+ osc = ObjectStreamClass.lookup(NonSerialzableClass.class);
+ assertNull(osc);
+
+ }
+
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamConstantsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamConstantsTest.java
new file mode 100644
index 0000000..7fbaa93
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamConstantsTest.java
@@ -0,0 +1,45 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ObjectStreamConstants;
+
+import junit.framework.TestCase;
+
+public class ObjectStreamConstantsTest extends TestCase {
+
+ /**
+ * java.io.ObjectStreamConstants#TC_ENUM
+ */
+ public void test_TC_ENUM() {
+ assertEquals(126, ObjectStreamConstants.TC_ENUM);
+ }
+
+ /**
+ * java.io.ObjectStreamConstants#SC_ENUM
+ */
+ public void test_SC_ENUM() {
+ assertEquals(16, ObjectStreamConstants.SC_ENUM);
+ }
+
+ /**
+ * java.io.ObjectStreamConstants#TC_MAX
+ */
+ public void test_TC_MAX() {
+ assertEquals(126, ObjectStreamConstants.TC_MAX);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamFieldTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamFieldTest.java
new file mode 100644
index 0000000..8dd12a4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamFieldTest.java
@@ -0,0 +1,395 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.NotActiveException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamField;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.StreamCorruptedException;
+import java.util.Date;
+
+public class ObjectStreamFieldTest extends junit.framework.TestCase {
+
+ static class DummyClass implements Serializable {
+ private static final long serialVersionUID = 999999999999998L;
+
+ long bam = 999L;
+
+ int ham = 9999;
+
+ int sam = 8888;
+
+ Object hola = new Object();
+
+ public static long getUID() {
+ return serialVersionUID;
+ }
+ }
+
+ ObjectStreamClass osc;
+
+ ObjectStreamField hamField;
+
+ ObjectStreamField samField;
+
+ ObjectStreamField bamField;
+
+ ObjectStreamField holaField;
+
+ /**
+ * java.io.ObjectStreamField#ObjectStreamField(java.lang.String,
+ *java.lang.Class)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_Class() {
+ assertTrue("Used to test", true);
+ }
+
+ public void test_equalsLjava_lang_Object() {
+ // Regression test for HARMONY-4273
+ assertTrue(samField.equals(samField));
+ assertFalse(samField.equals(hamField));
+ assertFalse(samField.equals("fish"));
+ assertFalse(samField.equals(null));
+ }
+
+ /**
+ * java.io.ObjectStreamField#compareTo(java.lang.Object)
+ */
+ public void test_compareToLjava_lang_Object() {
+ assertTrue("Object compared to int did not return > 0", holaField
+ .compareTo(hamField) > 0);
+ assertEquals("Int compared to itself did not return 0", 0, hamField
+ .compareTo(hamField));
+ assertTrue("(Int)ham compared to (Int)sam did not return < 0", hamField
+ .compareTo(samField) < 0);
+ }
+
+ /**
+ * java.io.ObjectStreamField#getName()
+ */
+ public void test_getName() {
+ assertEquals("Field did not return correct name", "hola", holaField
+ .getName());
+ }
+
+ /**
+ * java.io.ObjectStreamField#getOffset()
+ */
+ public void test_getOffset() {
+ ObjectStreamField[] osfArray;
+ osfArray = osc.getFields();
+ assertTrue("getOffset did not return reasonable values", osfArray[0]
+ .getOffset() != osfArray[1].getOffset());
+ assertEquals("getOffset for osfArray[0].getOffset() did not return 0",
+ 0, osfArray[0].getOffset());
+ assertEquals("osfArray[1].getOffset() did not return 8", 8, osfArray[1]
+ .getOffset());
+ assertEquals("osfArray[2].getOffset() did not return 12", 12,
+ osfArray[2].getOffset());
+ }
+
+ /**
+ * java.io.ObjectStreamField#getType()
+ */
+ public void test_getType() {
+ assertTrue("getType on an Object field did not answer Object",
+ holaField.getType().equals(Object.class));
+ }
+
+ /**
+ * java.io.ObjectStreamField#getTypeCode()
+ */
+ public void test_getTypeCode() {
+ assertEquals("getTypeCode on an Object field did not answer 'L'", 'L',
+ holaField.getTypeCode());
+ assertEquals("getTypeCode on a long field did not answer 'J'", 'J',
+ bamField.getTypeCode());
+ }
+
+ /**
+ * java.io.ObjectStreamField#getTypeString()
+ */
+ public void test_getTypeString() {
+ assertTrue("getTypeString returned: " + holaField.getTypeString(),
+ holaField.getTypeString().indexOf("Object") >= 0);
+ assertNull("Primitive types' strings should be null", hamField
+ .getTypeString());
+
+ ObjectStreamField osf = new ObjectStreamField("s", String.class, true);
+ assertTrue(osf.getTypeString() == "Ljava/lang/String;");
+ }
+
+ /**
+ * java.io.ObjectStreamField#toString()
+ */
+ public void test_toString() {
+ assertTrue("toString on a long returned: " + bamField.toString(),
+ bamField.toString().indexOf("bam") >= 0);
+ }
+
+ /**
+ * java.io.ObjectStreamField#getType()
+ */
+ public void test_getType_Deserialized() throws IOException,
+ ClassNotFoundException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(new SerializableObject());
+ oos.close();
+ baos.close();
+
+ byte[] bytes = baos.toByteArray();
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ SerializableObject obj = (SerializableObject) ois.readObject();
+
+ ObjectStreamClass oc = obj.getObjectStreamClass();
+ ObjectStreamField field = oc.getField("i");
+ assertEquals(Object.class, field.getType());
+ }
+
+ /**
+ * java.io.ObjectStreamField#getType()
+ */
+ public void test_getType_MockObjectInputStream() throws IOException,
+ ClassNotFoundException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(new SerializableObject());
+ oos.close();
+ baos.close();
+
+ byte[] bytes = baos.toByteArray();
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ MockObjectInputStream ois = new MockObjectInputStream(bais);
+ ois.readObject();
+
+ ObjectStreamClass oc = ois.getObjectStreamClass();
+ ObjectStreamField field = oc.getField("i");
+ assertEquals(Object.class, field.getType());
+ }
+
+ public void test_isUnshared() throws Exception {
+ SerializableObject2 obj = new SerializableObject2();
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(obj);
+ oos.close();
+ baos.close();
+ byte[] bytes = baos.toByteArray();
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ SerializableObject2 newObj = (SerializableObject2) ois.readObject();
+
+ ObjectInputStream.GetField getField = newObj.getGetField();
+ ObjectStreamClass objectStreamClass = getField.getObjectStreamClass();
+
+ assertTrue(objectStreamClass.getField("i").isUnshared());
+ assertFalse(objectStreamClass.getField("d").isUnshared());
+ assertTrue(objectStreamClass.getField("s").isUnshared());
+
+ assertEquals(1000, getField.get("i", null));
+ assertEquals(SerializableObject2.today, getField.get("d", null));
+ assertEquals("Richard", getField.get("s", null));
+
+ assertTrue(objectStreamClass.getField("s").getTypeString() == "Ljava/lang/String;");
+
+ assertEquals(0, objectStreamClass.getField("d").getOffset());
+ assertEquals(1, objectStreamClass.getField("i").getOffset());
+ assertEquals(2, objectStreamClass.getField("s").getOffset());
+ }
+
+
+ /**
+ * Write/serialize and read/de-serialize an object with primitive field
+ */
+ public void test_ObjectWithPrimitiveField()
+ throws IOException, ClassNotFoundException {
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final MyObjectOutputStream oos = new MyObjectOutputStream(baos);
+ oos.writeObject(new MockClass());
+ final byte[] bytes = baos.toByteArray();
+ final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ final MyObjectInputStream ois = new MyObjectInputStream(bais);
+ // NullPointerException is thrown by the readObject call below.
+ ois.readObject();
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ osc = ObjectStreamClass.lookup(DummyClass.class);
+ bamField = osc.getField("bam");
+ samField = osc.getField("sam");
+ hamField = osc.getField("ham");
+ holaField = osc.getField("hola");
+ }
+}
+
+class SerializableObject implements Serializable {
+ public ObjectInputStream.GetField getField = null;
+
+ private static final long serialVersionUID = -2953957835918368056L;
+
+ public Date d;
+
+ public Integer i;
+
+ public Exception e;
+
+ public SerializableObject() {
+ d = new Date();
+ i = new Integer(1);
+ e = new Exception("e");
+ }
+
+ private void writeObject(ObjectOutputStream o) throws IOException {
+ o.putFields().put("d", new Date());
+ o.putFields().put("i", new Integer(11));
+ o.writeFields();
+ }
+
+ private void readObject(ObjectInputStream in) throws NotActiveException,
+ IOException, ClassNotFoundException {
+ getField = in.readFields();
+ d = (Date) getField.get("d", null);
+ i = (Integer) getField.get("i", null);
+ }
+
+ public ObjectStreamClass getObjectStreamClass() {
+ return getField.getObjectStreamClass();
+ }
+}
+
+class MockObjectInputStream extends ObjectInputStream {
+ private ObjectStreamClass temp = null;
+
+ public MockObjectInputStream() throws SecurityException, IOException {
+ super();
+ }
+
+ public MockObjectInputStream(InputStream in)
+ throws StreamCorruptedException, IOException {
+ super(in);
+ }
+
+ public ObjectStreamClass readClassDescriptor() throws IOException,
+ ClassNotFoundException {
+ ObjectStreamClass osc = super.readClassDescriptor();
+ // To get the ObjectStreamClass of SerializableObject
+ if (osc.getSerialVersionUID() == -2953957835918368056L) {
+ temp = osc;
+ }
+ return osc;
+ }
+
+ public ObjectStreamClass getObjectStreamClass() {
+ return temp;
+ }
+}
+
+class SerializableObject2 implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("i", Integer.class, true),
+ new ObjectStreamField("d", Date.class, false),
+ new ObjectStreamField("s", String.class, true), };
+
+ private ObjectInputStream.GetField getField;
+
+ public static Date today = new Date(1172632429156l);
+
+ public ObjectInputStream.GetField getGetField() {
+ return getField;
+ }
+
+ private void writeObject(ObjectOutputStream o) throws IOException {
+ ObjectOutputStream.PutField putField = o.putFields();
+ putField.put("i", new Integer(1000));
+ putField.put("d", today);
+ putField.put("s", "Richard");
+ o.writeFields();
+ }
+
+ private void readObject(ObjectInputStream in) throws NotActiveException,
+ IOException, ClassNotFoundException {
+ getField = in.readFields();
+ }
+}
+
+
+// Primitive fields are necessary to cause the NullPointerException.
+class MockClass implements Serializable {
+ String str1 = "string 1";
+ String str2 = "string 2";
+ int int1 = 1;
+ int int2 = 2;
+ String str3 = "string 3";
+}
+
+
+// Overrides writeClassDescriptor to store ObjectStreamClass in map.
+class MyObjectOutputStream extends ObjectOutputStream {
+
+ // record the only ObjectStreamClass
+ static ObjectStreamClass descs;
+
+ MyObjectOutputStream(OutputStream out)
+ throws IOException {
+ super(out);
+ }
+
+ @Override
+ protected void writeClassDescriptor(ObjectStreamClass desc)
+ throws IOException {
+ descs = desc;
+ // Write a int
+ writeInt(1);
+ }
+}
+
+// Overrides readClassDescriptor to get ObjectStreamClass from map.
+class MyObjectInputStream extends ObjectInputStream {
+
+ MyObjectInputStream(InputStream in)
+ throws IOException {
+ super(in);
+ }
+
+ @Override
+ protected ObjectStreamClass readClassDescriptor()
+ throws IOException, ClassNotFoundException {
+ // Read a integer and get the only ObjectStreamClass for the test
+ final int id = readInt();
+ return MyObjectOutputStream.descs;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OpenRandomFileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OpenRandomFileTest.java
new file mode 100644
index 0000000..2341ee9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OpenRandomFileTest.java
@@ -0,0 +1,58 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import junit.framework.TestCase;
+
+public class OpenRandomFileTest extends TestCase {
+
+ public static void main(String[] args) throws IOException {
+ new OpenRandomFileTest().testOpenEmptyFile();
+ }
+
+ public OpenRandomFileTest() {
+ super();
+ }
+
+ public void testOpenNonEmptyFile() throws IOException {
+ File file = File.createTempFile("test", "tmp");
+ assertTrue(file.exists());
+ file.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
+ fos.close();
+
+ String fileName = file.getCanonicalPath();
+ RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
+ raf.close();
+ }
+
+ public void testOpenEmptyFile() throws IOException {
+ File file = File.createTempFile("test", "tmp");
+ assertTrue(file.exists());
+ file.deleteOnExit();
+
+ String fileName = file.getCanonicalPath();
+ RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
+ raf.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OutputStreamTesterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OutputStreamTesterTest.java
new file mode 100644
index 0000000..0b5dde1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OutputStreamTesterTest.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import junit.framework.TestSuite;
+import org.apache.harmony.testframework.SinkTester;
+import org.apache.harmony.testframework.WrapperTester;
+import tests.support.Streams;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Tests basic {@link OutputStream} behaviors for the luni implementations of
+ * the type.
+ */
+public class OutputStreamTesterTest {
+
+ // TODO: Rewrite this test so that id doesn't need a suite().
+ private static junit.framework.Test suite() {
+ TestSuite suite = new TestSuite();
+
+ // sink tests
+ suite.addTest(new FileOutputStreamSinkTester(true).createTests());
+ suite.addTest(new FileOutputStreamSinkTester(false).createTests());
+ suite.addTest(new ByteArrayOutputStreamSinkTester(0).setThrowsExceptions(false).createTests());
+ suite.addTest(new ByteArrayOutputStreamSinkTester(4).setThrowsExceptions(false).createTests());
+ suite.addTest(new PipedOutputStreamSinkTester().createTests());
+
+ // wrapper tests
+ suite.addTest(new BufferedOutputStreamTester(1).createTests());
+ suite.addTest(new BufferedOutputStreamTester(5).createTests());
+ suite.addTest(new BufferedOutputStreamTester(1024).createTests());
+ suite.addTest(new FilterOutputStreamTester().createTests());
+ suite.addTest(new DataOutputStreamTester().createTests());
+ // fails wrapperTestFlushThrowsViaClose() and sinkTestWriteAfterClose():
+ // suite.addTest(new ObjectOutputStreamTester().createTests());
+ suite.addTest(new PrintStreamTester().setThrowsExceptions(false).createTests());
+
+ return suite;
+ }
+
+ private static class FileOutputStreamSinkTester extends SinkTester {
+
+ private final boolean append;
+ private File file;
+
+ private FileOutputStreamSinkTester(boolean append) {
+ this.append = append;
+ }
+
+ public OutputStream create() throws IOException {
+ file = File.createTempFile("FileOutputStreamSinkTester", "tmp");
+ file.deleteOnExit();
+ return new FileOutputStream(file, append);
+ }
+
+ public byte[] getBytes() throws IOException {
+ return Streams.streamToBytes(new FileInputStream(file));
+ }
+ }
+
+ private static class ByteArrayOutputStreamSinkTester extends SinkTester {
+
+ private final int size;
+ private ByteArrayOutputStream stream;
+
+ private ByteArrayOutputStreamSinkTester(int size) {
+ this.size = size;
+ }
+
+ public OutputStream create() throws IOException {
+ stream = new ByteArrayOutputStream(size);
+ return stream;
+ }
+
+ public byte[] getBytes() throws IOException {
+ return stream.toByteArray();
+ }
+ }
+
+ private static class PipedOutputStreamSinkTester extends SinkTester {
+
+ private ExecutorService executor;
+ private Future<byte[]> future;
+
+ public OutputStream create() throws IOException {
+ final PipedInputStream in = new PipedInputStream();
+ PipedOutputStream out = new PipedOutputStream(in);
+
+ executor = Executors.newSingleThreadExecutor();
+ future = executor.submit(new Callable<byte[]>() {
+ final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+
+ public byte[] call() throws Exception {
+ byte[] buffer = new byte[256];
+ int count;
+ while ((count = in.read(buffer)) != -1) {
+ bytes.write(buffer, 0, count);
+ }
+ return bytes.toByteArray();
+ }
+ });
+
+ return out;
+ }
+
+ public byte[] getBytes() throws Exception {
+ executor.shutdown();
+ return future.get();
+ }
+ }
+
+ private static class FilterOutputStreamTester extends WrapperTester {
+
+ public OutputStream create(OutputStream delegate) throws Exception {
+ return new FilterOutputStream(delegate);
+ }
+
+ public byte[] decode(byte[] delegateBytes) throws Exception {
+ return delegateBytes;
+ }
+ }
+
+ private static class BufferedOutputStreamTester extends WrapperTester {
+ private final int bufferSize;
+
+ private BufferedOutputStreamTester(int bufferSize) {
+ this.bufferSize = bufferSize;
+ }
+
+ public OutputStream create(OutputStream delegate) throws Exception {
+ return new BufferedOutputStream(delegate, bufferSize);
+ }
+
+ public byte[] decode(byte[] delegateBytes) throws Exception {
+ return delegateBytes;
+ }
+ }
+
+ private static class DataOutputStreamTester extends WrapperTester {
+
+ public OutputStream create(OutputStream delegate) throws Exception {
+ return new DataOutputStream(delegate);
+ }
+
+ public byte[] decode(byte[] delegateBytes) throws Exception {
+ return delegateBytes;
+ }
+ }
+
+ private static class ObjectOutputStreamTester extends WrapperTester {
+
+ public OutputStream create(OutputStream delegate) throws Exception {
+ return new ObjectOutputStream(delegate);
+ }
+
+ public byte[] decode(byte[] delegateBytes) throws Exception {
+ return Streams.streamToBytes(new ObjectInputStream(
+ new ByteArrayInputStream(delegateBytes)));
+ }
+ }
+
+ private static class PrintStreamTester extends WrapperTester {
+
+ public OutputStream create(OutputStream delegate) throws Exception {
+ return new PrintStream(delegate);
+ }
+
+ public byte[] decode(byte[] delegateBytes) throws Exception {
+ return delegateBytes;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OutputStreamWriterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OutputStreamWriterTest.java
new file mode 100644
index 0000000..39b909e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/OutputStreamWriterTest.java
@@ -0,0 +1,701 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import junit.framework.TestCase;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+
+public class OutputStreamWriterTest extends TestCase {
+
+ private static final int UPPER = 0xd800;
+
+ private static final int BUFFER_SIZE = 10000;
+
+ private ByteArrayOutputStream out;
+
+ private OutputStreamWriter writer;
+
+ static private final String source = "This is a test message with Unicode character. \u4e2d\u56fd is China's name in Chinese";
+
+ static private final String[] MINIMAL_CHARSETS = new String[] { "US-ASCII",
+ "ISO-8859-1", "UTF-16BE", "UTF-16LE", "UTF-16", "UTF-8" };
+
+ OutputStreamWriter osw;
+
+ InputStreamReader isr;
+
+ private ByteArrayOutputStream fos;
+
+ String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+ /*
+ * @see TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ out = new ByteArrayOutputStream();
+ writer = new OutputStreamWriter(out, "utf-8");
+
+ fos = new ByteArrayOutputStream();
+ osw = new OutputStreamWriter(fos);
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ writer.close();
+
+ if (isr != null) {
+ isr.close();
+ }
+ osw.close();
+ } catch (Exception e) {
+ // Ignored
+ }
+
+ super.tearDown();
+ }
+
+ public void testClose() throws Exception {
+ writer.flush();
+ writer.close();
+ try {
+ writer.flush();
+ fail();
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ public void testFlush() throws Exception {
+ writer.write(source);
+ writer.flush();
+ String result = out.toString("utf-8");
+ assertEquals(source, result);
+ }
+
+ /*
+ * Class under test for void write(char[], int, int)
+ */
+ public void testWritecharArrayintint() throws IOException {
+ char[] chars = source.toCharArray();
+
+ // Throws IndexOutOfBoundsException if offset is negative
+ try {
+ writer.write((char[]) null, -1, -1);
+ fail();
+ } catch (NullPointerException exception) {
+ } catch (IndexOutOfBoundsException exception) {
+ }
+
+ // throws NullPointerException though count is negative
+ try {
+ writer.write((char[]) null, 1, -1);
+ fail();
+ } catch (NullPointerException exception) {
+ } catch (IndexOutOfBoundsException exception) {
+ }
+
+ try {
+ writer.write((char[]) null, 1, 1);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ writer.write(new char[0], 0, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ writer.write(chars, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ writer.write(chars, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ writer.write(chars, 1, chars.length);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ writer.write(chars, 1, 2);
+ writer.flush();
+ assertEquals("hi", out.toString("utf-8"));
+ writer.write(chars, 0, chars.length);
+ writer.flush();
+ assertEquals("hi" + source, out.toString("utf-8"));
+
+ writer.close();
+ // After the stream is closed, should throw IOException first
+ try {
+ writer.write((char[]) null, -1, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /*
+ * Class under test for void write(int)
+ */
+ public void testWriteint() throws IOException {
+ writer.write(1);
+ writer.flush();
+ String str = new String(out.toByteArray(), "utf-8");
+ assertEquals("\u0001", str);
+
+ writer.write(2);
+ writer.flush();
+ str = new String(out.toByteArray(), "utf-8");
+ assertEquals("\u0001\u0002", str);
+
+ writer.write(-1);
+ writer.flush();
+ str = new String(out.toByteArray(), "utf-8");
+ assertEquals("\u0001\u0002\uffff", str);
+
+ writer.write(0xfedcb);
+ writer.flush();
+ str = new String(out.toByteArray(), "utf-8");
+ assertEquals("\u0001\u0002\uffff\uedcb", str);
+
+ writer.close();
+ // After the stream is closed, should throw IOException
+ try {
+ writer.write(1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for void write(String, int, int)
+ */
+ public void testWriteStringintint() throws IOException {
+ try {
+ writer.write((String) null, 1, 1);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ writer.write("", 0, 1);
+ fail();
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ writer.write("abc", -1, 1);
+ fail();
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ writer.write("abc", 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ writer.write("abc", 1, 3);
+ fail();
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ writer.write((String) null, -1, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // Throws NullPointerException before StringIndexOutOfBoundsException
+ try {
+ writer.write((String) null, -1, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ writer.write("abc", 1, 2);
+ writer.flush();
+ assertEquals("bc", out.toString("utf-8"));
+ writer.write(source, 0, source.length());
+ writer.flush();
+ assertEquals("bc" + source, out.toString("utf-8"));
+
+ writer.close();
+ // Throws IndexOutOfBoundsException first if count is negative
+ try {
+ writer.write((String) null, 0, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ writer.write((String) null, -1, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ writer.write("abc", -1, 0);
+ fail("should throw StringIndexOutOfBoundsException");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ // Throws IOException
+ try {
+ writer.write("abc", 0, 1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for void OutputStreamWriter(OutputStream)
+ */
+ public void testOutputStreamWriterOutputStream() throws IOException {
+ try {
+ writer = new OutputStreamWriter(null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ OutputStreamWriter writer2 = new OutputStreamWriter(out);
+ writer2.close();
+ }
+
+ /*
+ * Class under test for void OutputStreamWriter(OutputStream, String)
+ */
+ public void testOutputStreamWriterOutputStreamString() throws IOException {
+ try {
+ writer = new OutputStreamWriter(null, "utf-8");
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ writer = new OutputStreamWriter(out, "");
+ fail();
+ } catch (UnsupportedEncodingException e) {
+ // Expected
+ }
+ try {
+ writer = new OutputStreamWriter(out, "badname");
+ fail();
+ } catch (UnsupportedEncodingException e) {
+ // Expected
+ }
+ try {
+ writer = new OutputStreamWriter(out, (String) null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ OutputStreamWriter writer2 = new OutputStreamWriter(out, "ascii");
+ assertEquals(Charset.forName("ascii"), Charset.forName(writer2
+ .getEncoding()));
+ writer2.close();
+ }
+
+ /*
+ * Class under test for void OutputStreamWriter(OutputStream)
+ */
+ public void testOutputStreamWriterOutputStreamCharset() throws IOException {
+ Charset cs = Charset.forName("ascii");
+ try {
+ writer = new OutputStreamWriter(null, cs);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ writer = new OutputStreamWriter(out, (Charset) null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ OutputStreamWriter writer2 = new OutputStreamWriter(out, cs);
+ assertEquals(cs, Charset.forName(writer2.getEncoding()));
+ writer2.close();
+ }
+
+ /*
+ * Class under test for void OutputStreamWriter(OutputStream, String)
+ */
+ public void testOutputStreamWriterOutputStreamCharsetEncoder()
+ throws IOException {
+ Charset cs = Charset.forName("ascii");
+ CharsetEncoder enc = cs.newEncoder();
+ try {
+ writer = new OutputStreamWriter(null, enc);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ writer = new OutputStreamWriter(out, (CharsetEncoder) null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ OutputStreamWriter writer2 = new OutputStreamWriter(out, enc);
+ assertEquals(cs, Charset.forName(writer2.getEncoding()));
+ writer2.close();
+ }
+
+ public void testGetEncoding() {
+ Charset cs = Charset.forName("utf-8");
+ assertEquals(cs, Charset.forName(writer.getEncoding()));
+ }
+
+ public void testHandleEarlyEOFChar_1() throws IOException {
+ String str = "All work and no play makes Jack a dull boy\n"; //$NON-NLS-1$
+ int NUMBER = 2048;
+ int j = 0;
+ int len = str.length() * NUMBER;
+ char[] strChars = new char[len];
+ for (int i = 0; i < NUMBER; ++i) {
+ for (int k = 0; k < str.length(); ++k) {
+ strChars[j++] = str.charAt(k);
+ }
+ }
+
+ File f = File.createTempFile("one", "by_one");
+ f.deleteOnExit();
+ FileWriter fw = new FileWriter(f);
+ fw.write(strChars);
+ fw.close();
+ FileInputStream fis = new FileInputStream(f);
+ InputStreamReader in = new InputStreamReader(fis);
+ for (int offset = 0; offset < strChars.length; ++offset) {
+ int b = in.read();
+ assertFalse("Early EOF at offset", -1 == b);
+ }
+ }
+
+ public void testHandleEarlyEOFChar_2() throws IOException {
+ int capacity = 65536;
+ byte[] bytes = new byte[capacity];
+ byte[] bs = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = bs[i / 8192];
+ }
+ String inputStr = new String(bytes);
+ int len = inputStr.length();
+ File f = File.createTempFile("FileWriterBugTest ", null); //$NON-NLS-1$
+ f.deleteOnExit();
+ FileWriter writer = new FileWriter(f);
+ writer.write(inputStr);
+ writer.close();
+ long flen = f.length();
+
+ FileReader reader = new FileReader(f);
+ char[] outChars = new char[capacity];
+ int outCount = reader.read(outChars);
+ String outStr = new String(outChars, 0, outCount);
+
+ assertEquals(len, flen);
+ assertEquals(inputStr, outStr);
+ }
+
+ public void testSingleCharIO() throws Exception {
+ InputStreamReader isr = null;
+ for (int i = 0; i < MINIMAL_CHARSETS.length; ++i) {
+ try {
+ out = new ByteArrayOutputStream();
+ writer = new OutputStreamWriter(out, MINIMAL_CHARSETS[i]);
+
+ int upper = UPPER;
+ switch (i) {
+ case 0:
+ upper = 128;
+ break;
+ case 1:
+ upper = 256;
+ break;
+ }
+
+ for (int c = 0; c < upper; ++c) {
+ writer.write(c);
+ }
+ writer.flush();
+ byte[] result = out.toByteArray();
+
+ isr = new InputStreamReader(new ByteArrayInputStream(result),
+ MINIMAL_CHARSETS[i]);
+ for (int expected = 0; expected < upper; ++expected) {
+ assertEquals("Error when reading bytes in "
+ + MINIMAL_CHARSETS[i], expected, isr.read());
+ }
+ } finally {
+ try {
+ isr.close();
+ } catch (Exception e) {
+ }
+ try {
+ writer.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+ public void testBlockIO() throws Exception {
+ InputStreamReader isr = null;
+ char[] largeBuffer = new char[BUFFER_SIZE];
+ for (int i = 0; i < MINIMAL_CHARSETS.length; ++i) {
+ try {
+ out = new ByteArrayOutputStream();
+ writer = new OutputStreamWriter(out, MINIMAL_CHARSETS[i]);
+
+ int upper = UPPER;
+ switch (i) {
+ case 0:
+ upper = 128;
+ break;
+ case 1:
+ upper = 256;
+ break;
+ }
+
+ int m = 0;
+ for (int c = 0; c < upper; ++c) {
+ largeBuffer[m++] = (char) c;
+ if (m == BUFFER_SIZE) {
+ writer.write(largeBuffer);
+ m = 0;
+ }
+ }
+ writer.write(largeBuffer, 0, m);
+ writer.flush();
+ byte[] result = out.toByteArray();
+
+ isr = new InputStreamReader(new ByteArrayInputStream(result),
+ MINIMAL_CHARSETS[i]);
+ int expected = 0, read = 0, j = 0;
+ while (expected < upper) {
+ if (j == read) {
+ read = isr.read(largeBuffer);
+ j = 0;
+ }
+ assertEquals("Error when reading bytes in "
+ + MINIMAL_CHARSETS[i], expected++, largeBuffer[j++]);
+ }
+ } finally {
+ try {
+ isr.close();
+ } catch (Exception e) {
+ }
+ try {
+ writer.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() {
+ assertTrue("Used in tests", true);
+ }
+
+ /**
+ * java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_io_OutputStreamLjava_lang_String()
+ throws UnsupportedEncodingException {
+ osw = new OutputStreamWriter(fos, "8859_1");
+ try {
+ osw = new OutputStreamWriter(fos, "Bogus");
+ fail("Failed to throw Unsupported Encoding exception");
+ } catch (UnsupportedEncodingException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.OutputStreamWriter#close()
+ */
+ public void test_close() throws IOException {
+ osw.close();
+
+ try {
+ osw.write(testString, 0, testString.length());
+ fail("Chars written after close");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ try {
+ OutputStreamWriter writer = new OutputStreamWriter(bout,
+ "ISO2022JP");
+ writer.write(new char[] { 'a' });
+ writer.close();
+ // the default is ASCII, there should not be any mode changes
+ String converted = new String(bout.toByteArray(), "ISO8859_1");
+ assertTrue("invalid conversion 1: " + converted, converted
+ .equals("a"));
+
+ bout.reset();
+ writer = new OutputStreamWriter(bout, "ISO2022JP");
+ writer.write(new char[] { '\u3048' });
+ writer.flush();
+ // the byte sequence should not switch to ASCII mode until the
+ // stream is closed
+ converted = new String(bout.toByteArray(), "ISO8859_1");
+ assertTrue("invalid conversion 2: " + converted, converted
+ .equals("\u001b$B$("));
+ writer.close();
+ converted = new String(bout.toByteArray(), "ISO8859_1");
+ assertTrue("invalid conversion 3: " + converted, converted
+ .equals("\u001b$B$(\u001b(B"));
+
+ bout.reset();
+ writer = new OutputStreamWriter(bout, "ISO2022JP");
+ writer.write(new char[] { '\u3048' });
+ writer.write(new char[] { '\u3048' });
+ writer.close();
+ // there should not be a mode switch between writes
+ assertEquals("invalid conversion 4", "\u001b$B$($(\u001b(B",
+ new String(bout.toByteArray(), "ISO8859_1"));
+ } catch (UnsupportedEncodingException e) {
+ // Can't test missing converter
+ System.out.println(e);
+ }
+ }
+
+ /**
+ * java.io.OutputStreamWriter#flush()
+ */
+ public void test_flush() throws IOException {
+ char[] buf = new char[testString.length()];
+ osw.write(testString, 0, testString.length());
+ osw.flush();
+ openInputStream();
+ isr.read(buf, 0, buf.length);
+ assertTrue("Chars not flushed", new String(buf, 0, buf.length)
+ .equals(testString));
+ }
+
+ /**
+ * Unlike the RI, we return the canonical encoding name and not something
+ * java specific.
+ */
+ public void test_getEncoding() throws IOException {
+ try {
+ osw = new OutputStreamWriter(fos, "8859_1");
+ } catch (UnsupportedEncodingException e) {
+ assertEquals("Returned incorrect encoding", "8859_1", osw
+ .getEncoding());
+ }
+
+ OutputStreamWriter out = new OutputStreamWriter(
+ new ByteArrayOutputStream(), "UTF-16BE");
+ out.close();
+
+ String result = out.getEncoding();
+ assertNull(result);
+
+ out = null;
+ try {
+ out = new OutputStreamWriter(new ByteArrayOutputStream(),
+ "UTF-16BE");
+ } catch (UnsupportedEncodingException e) {
+ // ok
+ }
+ result = out.getEncoding();
+ assertEquals("UTF-16BE", result);
+ }
+
+ /**
+ * java.io.OutputStreamWriter#write(char[], int, int)
+ */
+ public void test_write$CII() throws IOException {
+ char[] buf = new char[testString.length()];
+ osw.write(testString, 0, testString.length());
+ osw.close();
+ openInputStream();
+ isr.read(buf, 0, buf.length);
+ assertTrue("Incorrect chars returned", new String(buf, 0, buf.length)
+ .equals(testString));
+ }
+
+ /**
+ * java.io.OutputStreamWriter#write(int)
+ */
+ public void test_writeI() throws IOException {
+ osw.write('T');
+ osw.close();
+ openInputStream();
+ int c = isr.read();
+ assertEquals("Incorrect char returned", 'T', (char) c);
+ }
+
+ /**
+ * java.io.OutputStreamWriter#write(java.lang.String, int, int)
+ */
+ public void test_writeLjava_lang_StringII() throws IOException {
+ char[] buf = new char[testString.length()];
+ osw.write(testString, 0, testString.length());
+ osw.close();
+ openInputStream();
+ isr.read(buf);
+ assertTrue("Incorrect chars returned", new String(buf, 0, buf.length)
+ .equals(testString));
+ }
+
+ private void openInputStream() {
+ isr = new InputStreamReader(new ByteArrayInputStream(fos.toByteArray()));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedInputStreamTest.java
new file mode 100644
index 0000000..6122dbb
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedInputStreamTest.java
@@ -0,0 +1,448 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.concurrent.CountDownLatch;
+
+public class PipedInputStreamTest extends junit.framework.TestCase {
+
+ static class PWriter implements Runnable {
+ PipedOutputStream pos;
+
+ public byte bytes[];
+
+ public void run() {
+ try {
+ pos.write(bytes);
+ synchronized (this) {
+ notify();
+ }
+ } catch (IOException e) {
+ e.printStackTrace(System.out);
+ System.out.println("Could not write bytes");
+ }
+ }
+
+ public PWriter(PipedOutputStream pout, int nbytes) {
+ pos = pout;
+ bytes = new byte[nbytes];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = (byte) (System.currentTimeMillis() % 9);
+ }
+ }
+ }
+
+ Thread t;
+
+ PWriter pw;
+
+ PipedInputStream pis;
+
+ PipedOutputStream pos;
+
+ /**
+ * java.io.PipedInputStream#PipedInputStream()
+ */
+ public void test_Constructor() {
+ // Test for method java.io.PipedInputStream()
+ // Used in tests
+ }
+
+ /**
+ * java.io.PipedInputStream#PipedInputStream(java.io.PipedOutputStream)
+ */
+ public void test_ConstructorLjava_io_PipedOutputStream() throws Exception {
+ // Test for method java.io.PipedInputStream(java.io.PipedOutputStream)
+ pis = new PipedInputStream(new PipedOutputStream());
+ pis.available();
+ }
+
+
+ public void test_readException() throws IOException {
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream();
+
+ try {
+ pis.connect(pos);
+ t = new Thread(pw = new PWriter(pos, 1000));
+ t.start();
+ while (true) {
+ pis.read();
+ t.interrupt();
+ }
+ } catch (IOException expected) {
+ } finally {
+ try {
+ pis.close();
+ pos.close();
+ } catch (IOException ee) {
+ }
+ }
+ }
+
+ /**
+ * java.io.PipedInputStream#available()
+ */
+ public void test_available() throws Exception {
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream();
+
+ pis.connect(pos);
+ t = new Thread(pw = new PWriter(pos, 1000));
+ t.start();
+
+ synchronized (pw) {
+ pw.wait(10000);
+ }
+ assertTrue("Available returned incorrect number of bytes: "
+ + pis.available(), pis.available() == 1000);
+
+ PipedInputStream pin = new PipedInputStream();
+ PipedOutputStream pout = new PipedOutputStream(pin);
+ // We know the PipedInputStream buffer size is 1024.
+ // Writing another byte would cause the write to wait
+ // for a read before returning
+ for (int i = 0; i < 1024; i++) {
+ pout.write(i);
+ }
+ assertEquals("Incorrect available count", 1024, pin.available());
+ }
+
+ /**
+ * java.io.PipedInputStream#close()
+ */
+ public void test_close() throws IOException {
+ // Test for method void java.io.PipedInputStream.close()
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream();
+ pis.connect(pos);
+ pis.close();
+ try {
+ pos.write((byte) 127);
+ fail("Failed to throw expected exception");
+ } catch (IOException e) {
+ // The spec for PipedInput saya an exception should be thrown if
+ // a write is attempted to a closed input. The PipedOuput spec
+ // indicates that an exception should be thrown only when the
+ // piped input thread is terminated without closing
+ return;
+ }
+ }
+
+ /**
+ * java.io.PipedInputStream#connect(java.io.PipedOutputStream)
+ */
+ public void test_connectLjava_io_PipedOutputStream() throws Exception {
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream();
+ assertEquals("Non-conected pipe returned non-zero available bytes", 0,
+ pis.available());
+
+ pis.connect(pos);
+ t = new Thread(pw = new PWriter(pos, 1000));
+ t.start();
+
+ synchronized (pw) {
+ pw.wait(10000);
+ }
+ assertEquals("Available returned incorrect number of bytes", 1000, pis
+ .available());
+ }
+
+ /**
+ * java.io.PipedInputStream#read()
+ */
+ public void test_read() throws Exception {
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream();
+
+ pis.connect(pos);
+ t = new Thread(pw = new PWriter(pos, 1000));
+ t.start();
+
+ synchronized (pw) {
+ pw.wait(10000);
+ }
+ assertEquals("Available returned incorrect number of bytes", 1000, pis
+ .available());
+ assertEquals("read returned incorrect byte", pw.bytes[0], (byte) pis
+ .read());
+ }
+
+ /**
+ * java.io.PipedInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws Exception {
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream();
+
+ pis.connect(pos);
+ t = new Thread(pw = new PWriter(pos, 1000));
+ t.start();
+
+ byte[] buf = new byte[400];
+ synchronized (pw) {
+ pw.wait(10000);
+ }
+ assertTrue("Available returned incorrect number of bytes: "
+ + pis.available(), pis.available() == 1000);
+ pis.read(buf, 0, 400);
+ for (int i = 0; i < 400; i++) {
+ assertEquals("read returned incorrect byte[]", pw.bytes[i], buf[i]);
+ }
+ }
+
+ /**
+ * java.io.PipedInputStream#read(byte[], int, int)
+ * Regression for HARMONY-387
+ */
+ public void test_read$BII_2() throws IOException {
+ PipedInputStream obj = new PipedInputStream();
+ try {
+ obj.read(new byte[0], 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.PipedInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII_3() throws IOException {
+ PipedInputStream obj = new PipedInputStream();
+ try {
+ obj.read(new byte[0], -1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.PipedInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII_4() throws IOException {
+ PipedInputStream obj = new PipedInputStream();
+ try {
+ obj.read(new byte[0], -1, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.PipedInputStream#receive(int)
+ */
+ public void test_write_failsAfterReaderDead() throws Exception {
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream();
+
+ // test if writer recognizes dead reader
+ pis.connect(pos);
+
+ class WriteRunnable implements Runnable {
+
+ final CountDownLatch readerAlive = new CountDownLatch(1);
+
+ public void run() {
+ try {
+ pos.write(1);
+
+ try {
+ readerAlive.await();
+ } catch (InterruptedException ie) {
+ fail();
+ return;
+ }
+
+ try {
+ // should throw exception since reader thread
+ // is now dead
+ pos.write(1);
+ fail();
+ } catch (IOException expected) {
+ }
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ class ReadRunnable implements Runnable {
+ public void run() {
+ try {
+ pis.read();
+ } catch (IOException e) {
+ fail();
+ }
+ }
+ }
+
+ WriteRunnable writeRunnable = new WriteRunnable();
+ Thread writeThread = new Thread(writeRunnable);
+
+ ReadRunnable readRunnable = new ReadRunnable();
+ Thread readThread = new Thread(readRunnable);
+ writeThread.start();
+ readThread.start();
+ readThread.join();
+
+ writeRunnable.readerAlive.countDown();
+ writeThread.join();
+ }
+
+ static final class PipedInputStreamWithPublicReceive extends PipedInputStream {
+ @Override
+ public void receive(int oneByte) throws IOException {
+ super.receive(oneByte);
+ }
+ }
+
+
+ public void test_receive_failsIfWriterClosed() throws Exception {
+ // attempt to write to stream after writer closed
+ PipedInputStreamWithPublicReceive pis = new PipedInputStreamWithPublicReceive();
+
+ pos = new PipedOutputStream();
+ pos.connect(pis);
+ pos.close();
+ try {
+ pis.receive(1);
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ static class Worker extends Thread {
+ PipedOutputStream out;
+
+ Worker(PipedOutputStream pos) {
+ this.out = pos;
+ }
+
+ public void run() {
+ try {
+ out.write(20);
+ out.close();
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ public void test_read_after_write_close() throws Exception {
+ PipedInputStream in = new PipedInputStream();
+ PipedOutputStream out = new PipedOutputStream();
+ in.connect(out);
+ Thread worker = new Worker(out);
+ worker.start();
+ Thread.sleep(2000);
+ assertEquals("Should read 20.", 20, in.read());
+ worker.join();
+ assertEquals("Write end is closed, should return -1", -1, in.read());
+ byte[] buf = new byte[1];
+ assertEquals("Write end is closed, should return -1", -1, in.read(buf, 0, 1));
+ assertEquals("Buf len 0 should return first", 0, in.read(buf, 0, 0));
+ in.close();
+ out.close();
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() throws Exception {
+ try {
+ if (t != null) {
+ t.interrupt();
+ }
+ } catch (Exception ignore) {
+ }
+ super.tearDown();
+ }
+
+
+ /**
+ * java.io.PipedInputStream#PipedInputStream(java.io.PipedOutputStream,
+ *int)
+ * @since 1.6
+ */
+ public void test_Constructor_LPipedOutputStream_I() throws Exception {
+ // Test for method java.io.PipedInputStream(java.io.PipedOutputStream,
+ // int)
+ MockPipedInputStream mpis = new MockPipedInputStream(
+ new PipedOutputStream(), 100);
+ int bufferLength = mpis.bufferLength();
+ assertEquals(100, bufferLength);
+
+ try {
+ pis = new PipedInputStream(null, -1);
+ fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ pis = new PipedInputStream(null, 0);
+ fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PipedInputStream#PipedInputStream(int)
+ * @since 1.6
+ */
+ public void test_Constructor_I() throws Exception {
+ // Test for method java.io.PipedInputStream(int)
+ MockPipedInputStream mpis = new MockPipedInputStream(100);
+ int bufferLength = mpis.bufferLength();
+ assertEquals(100, bufferLength);
+
+ try {
+ pis = new PipedInputStream(-1);
+ fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ pis = new PipedInputStream(0);
+ fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ static class MockPipedInputStream extends PipedInputStream {
+
+ public MockPipedInputStream(java.io.PipedOutputStream src,
+ int bufferSize) throws IOException {
+ super(src, bufferSize);
+ }
+
+ public MockPipedInputStream(int bufferSize) {
+ super(bufferSize);
+ }
+
+ public int bufferLength() {
+ return super.buffer.length;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedOutputStreamTest.java
new file mode 100644
index 0000000..183606e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedOutputStreamTest.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.UnsupportedEncodingException;
+
+import junit.framework.TestCase;
+
+public class PipedOutputStreamTest extends TestCase {
+
+ static class PReader implements Runnable {
+ PipedInputStream reader;
+
+ public PipedInputStream getReader() {
+ return reader;
+ }
+
+ public PReader(PipedOutputStream out) {
+ try {
+ reader = new PipedInputStream(out);
+ } catch (Exception e) {
+ System.out.println("Couldn't start reader");
+ }
+ }
+
+ public int available() {
+ try {
+ return reader.available();
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ public void run() {
+ try {
+ while (true) {
+ Thread.sleep(1000);
+ Thread.yield();
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public String read(int nbytes) {
+ byte[] buf = new byte[nbytes];
+ try {
+ reader.read(buf, 0, nbytes);
+ return new String(buf, "UTF-8");
+ } catch (IOException e) {
+ System.out.println("Exception reading info");
+ return "ERROR";
+ }
+ }
+ }
+
+ Thread rt;
+
+ PReader reader;
+
+ PipedOutputStream out;
+
+ /**
+ * java.io.PipedOutputStream#PipedOutputStream()
+ */
+ public void test_Constructor() {
+ // Used in tests
+ }
+
+ /**
+ * java.io.PipedOutputStream#PipedOutputStream(java.io.PipedInputStream)
+ */
+ public void test_ConstructorLjava_io_PipedInputStream() throws Exception {
+ out = new PipedOutputStream(new PipedInputStream());
+ out.write('b');
+ }
+
+ /**
+ * java.io.PipedOutputStream#close()
+ */
+ public void test_close() throws Exception {
+ out = new PipedOutputStream();
+ rt = new Thread(reader = new PReader(out));
+ rt.start();
+ out.close();
+ }
+
+ /**
+ * java.io.PipedOutputStream#connect(java.io.PipedInputStream)
+ */
+ public void test_connectLjava_io_PipedInputStream_Exception()
+ throws IOException {
+ out = new PipedOutputStream();
+ out.connect(new PipedInputStream());
+ try {
+ out.connect(null);
+ fail("should throw NullPointerException"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PipedOutputStream#connect(java.io.PipedInputStream)
+ */
+ public void test_connectLjava_io_PipedInputStream() {
+ try {
+ out = new PipedOutputStream();
+ rt = new Thread(reader = new PReader(out));
+ rt.start();
+ out.connect(new PipedInputStream());
+ fail("Failed to throw exception attempting connect on already connected stream");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.PipedOutputStream#flush()
+ */
+ public void test_flush() throws IOException, UnsupportedEncodingException {
+ out = new PipedOutputStream();
+ rt = new Thread(reader = new PReader(out));
+ rt.start();
+ out.write("HelloWorld".getBytes("UTF-8"), 0, 10);
+ assertTrue("Bytes written before flush", reader.available() != 0);
+ out.flush();
+ assertEquals("Wrote incorrect bytes", "HelloWorld", reader.read(10));
+ }
+
+ /**
+ * java.io.PipedOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() throws IOException, UnsupportedEncodingException {
+ out = new PipedOutputStream();
+ rt = new Thread(reader = new PReader(out));
+ rt.start();
+ out.write("HelloWorld".getBytes("UTF-8"), 0, 10);
+ out.flush();
+ assertEquals("Wrote incorrect bytes", "HelloWorld", reader.read(10));
+ }
+
+ /**
+ * java.io.PipedOutputStream#write(byte[], int, int) Regression for
+ * HARMONY-387
+ */
+ public void test_write$BII_2() throws IOException {
+ PipedInputStream pis = new PipedInputStream();
+ PipedOutputStream pos = null;
+ try {
+ pos = new PipedOutputStream(pis);
+ pos.write(new byte[0], -1, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // Regression for HARMONY-4311
+ try {
+ pis = new PipedInputStream();
+ PipedOutputStream out = new PipedOutputStream(pis);
+ out.write(null, -10, 10);
+ fail("should throw NullPointerException.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream(pis);
+ pos.close();
+ pos.write(new byte[0], 0, 0);
+
+ try {
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream(pis);
+ pos.write(new byte[0], -1, 0);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException t) {
+ //expected
+ }
+
+ try {
+ pis = new PipedInputStream();
+ pos = new PipedOutputStream(pis);
+ pos.write(null, -10, 0);
+ fail("should throw NullPointerException.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * java.io.PipedOutputStream#write(int)
+ */
+ public void test_writeI() throws IOException {
+ out = new PipedOutputStream();
+ rt = new Thread(reader = new PReader(out));
+ rt.start();
+ out.write('c');
+ out.flush();
+ assertEquals("Wrote incorrect byte", "c", reader.read(1));
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ @Override
+ protected void tearDown() {
+ if (rt != null) {
+ rt.interrupt();
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedReaderTest.java
new file mode 100644
index 0000000..6802540
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedReaderTest.java
@@ -0,0 +1,399 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+
+import junit.framework.TestCase;
+
+public class PipedReaderTest extends TestCase {
+
+ static class PWriter implements Runnable {
+ public PipedWriter pw;
+
+ public PWriter(PipedReader reader) {
+ try {
+ pw = new PipedWriter(reader);
+ } catch (Exception e) {
+ System.out.println("Couldn't create writer");
+ }
+ }
+
+ public PWriter() {
+ pw = new PipedWriter();
+ }
+
+ public void run() {
+ try {
+ char[] c = new char[11];
+ "Hello World".getChars(0, 11, c, 0);
+ pw.write(c);
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ } catch (Exception e) {
+ System.out.println("Exception occurred: " + e.toString());
+ }
+ }
+ }
+
+ PipedReader preader;
+
+ PWriter pwriter;
+
+ Thread t;
+
+ /**
+ * java.io.PipedReader#PipedReader()
+ */
+ public void test_Constructor() {
+ // Used in test
+ }
+
+ /**
+ * java.io.PipedReader#PipedReader(java.io.PipedWriter)
+ */
+ public void test_ConstructorLjava_io_PipedWriter() throws IOException {
+ preader = new PipedReader(new PipedWriter());
+ }
+
+ /**
+ * java.io.PipedReader#PipedReader(java.io.PipedWriter,
+ *int)
+ * @since 1.6
+ */
+ public void test_Constructor_LPipedWriter_I() throws Exception {
+ // Test for method java.io.PipedReader(java.io.PipedWriter,
+ // int)
+ try {
+ preader = new PipedReader(null, -1);
+ fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ preader = new PipedReader(null, 0);
+ fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PipedReader#PipedReader(int)
+ * @since 1.6
+ */
+ public void test_Constructor_I() throws Exception {
+ // Test for method java.io.PipedReader(int)
+ try {
+ preader = new PipedReader(-1);
+ fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ preader = new PipedReader(0);
+ fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PipedReader#close()
+ */
+ public void test_close() throws Exception {
+ char[] c = null;
+ preader = new PipedReader();
+ t = new Thread(new PWriter(preader), "");
+ t.start();
+ Thread.sleep(500); // Allow writer to start
+ c = new char[11];
+ preader.read(c, 0, 11);
+ preader.close();
+ assertEquals("Read incorrect chars", "Hello World", new String(c));
+ }
+
+ /**
+ * java.io.PipedReader#connect(java.io.PipedWriter)
+ */
+ public void test_connectLjava_io_PipedWriter() throws Exception {
+ char[] c = null;
+
+ preader = new PipedReader();
+ t = new Thread(pwriter = new PWriter(), "");
+ preader.connect(pwriter.pw);
+ t.start();
+ Thread.sleep(500); // Allow writer to start
+ c = new char[11];
+ preader.read(c, 0, 11);
+
+ assertEquals("Read incorrect chars", "Hello World", new String(c));
+ try {
+ preader.connect(pwriter.pw);
+ fail("Failed to throw exception connecting to pre-connected reader");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.PipedReader#read()
+ */
+ public void test_read() throws Exception {
+ char[] c = null;
+ preader = new PipedReader();
+ t = new Thread(new PWriter(preader), "");
+ t.start();
+ Thread.sleep(500); // Allow writer to start
+ c = new char[11];
+ for (int i = 0; i < c.length; i++) {
+ c[i] = (char) preader.read();
+ }
+ assertEquals("Read incorrect chars", "Hello World", new String(c));
+ }
+
+ /**
+ * java.io.PipedReader#read(char[], int, int)
+ */
+ public void test_read$CII() throws Exception {
+ char[] c = null;
+ preader = new PipedReader();
+ t = new Thread(new PWriter(preader), "");
+ t.start();
+ Thread.sleep(500); // Allow writer to start
+ c = new char[11];
+ int n = 0;
+ int x = n;
+ while (x < 11) {
+ n = preader.read(c, x, 11 - x);
+ x = x + n;
+ }
+ assertEquals("Read incorrect chars", "Hello World", new String(c));
+ try {
+ preader.close();
+ preader.read(c, 8, 7);
+ fail("Failed to throw exception reading from closed reader");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ public void test_read$CII_ExceptionPriority() throws IOException {
+ // Regression for HARMONY-387
+ PipedWriter pw = new PipedWriter();
+ PipedReader obj = null;
+ try {
+ obj = new PipedReader(pw);
+ obj.read(new char[0], (int) 0, (int) -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_read$CII_ExceptionPriority2() throws IOException {
+ PipedWriter pw = new PipedWriter();
+ PipedReader obj = null;
+ try {
+ obj = new PipedReader(pw);
+ obj.read(new char[0], (int) -1, (int) 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_read$CII_ExceptionPriority3() throws IOException {
+ PipedWriter pw = new PipedWriter();
+ PipedReader obj = null;
+ try {
+ obj = new PipedReader(pw);
+ obj.read(new char[0], (int) -1, (int) -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_read$CII_ExceptionPriority4() throws IOException {
+ PipedWriter pw = new PipedWriter();
+ PipedReader pr = new PipedReader(pw);
+ try {
+ pr.read(null, -1, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_read_$CII_IOException() throws IOException {
+ PipedWriter pw = new PipedWriter();
+ PipedReader pr = new PipedReader(pw);
+ pr.close();
+ try {
+ pr.read(null, 0, 10);
+ fail("Should throws IOException"); //$NON-NLS-1$
+ } catch (IOException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+
+ pr = new PipedReader();
+ pr.close();
+ try {
+ pr.read(null, 0, 10);
+ fail("Should throws IOException"); //$NON-NLS-1$
+ } catch (IOException e) {
+ // expected
+ } finally {
+ pr = null;
+ }
+
+ pw = new PipedWriter();
+ pr = new PipedReader(pw);
+ pr.close();
+ try {
+ pr.read(new char[10], -1, 0);
+ fail("Should throws IOException"); //$NON-NLS-1$
+ } catch (IOException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+
+ pw = new PipedWriter();
+ pr = new PipedReader(pw);
+ pr.close();
+ try {
+ pr.read(new char[10], 0, -1);
+ fail("Should throws IOException"); //$NON-NLS-1$
+ } catch (IOException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+
+ pw = new PipedWriter();
+ pr = new PipedReader(pw);
+ pr.close();
+ try {
+ pr.read(new char[10], 1, 10);
+ fail("Should throws IOException"); //$NON-NLS-1$
+ } catch (IOException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+
+ pw = new PipedWriter();
+ pr = new PipedReader(pw);
+ pr.close();
+ try {
+ pr.read(new char[0], -1, -1);
+ fail("should throw IOException"); //$NON-NLS-1$
+ } catch (IOException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+
+ pw = new PipedWriter();
+ pr = new PipedReader(pw);
+ pr.close();
+ try {
+ pr.read(null, 0, 1);
+ fail("should throw IOException"); //$NON-NLS-1$
+ } catch (IOException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+
+ pw = new PipedWriter();
+ pr = new PipedReader(pw);
+ try {
+ pr.read(null, 0, -1);
+ fail("should throw NullPointerException"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+
+ pw = new PipedWriter();
+ pr = new PipedReader(pw);
+ try {
+ pr.read(new char[10], 11, 0);
+ fail("should throw IndexOutOfBoundsException"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+
+ pw = new PipedWriter();
+ pr = new PipedReader(pw);
+ try {
+ pr.read(null, 1, 0);
+ fail("should throw NullPointerException"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ } finally {
+ pw = null;
+ pr = null;
+ }
+ }
+
+ /**
+ * java.io.PipedReader#ready()
+ */
+ public void test_ready() throws Exception {
+ char[] c = null;
+ preader = new PipedReader();
+ t = new Thread(new PWriter(preader), "");
+ t.start();
+ Thread.sleep(500); // Allow writer to start
+ assertTrue("Reader should be ready", preader.ready());
+ c = new char[11];
+ for (int i = 0; i < c.length; i++)
+ c[i] = (char) preader.read();
+ assertFalse("Reader should not be ready after reading all chars",
+ preader.ready());
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() throws Exception {
+ if (t != null) {
+ t.interrupt();
+ }
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedWriterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedWriterTest.java
new file mode 100644
index 0000000..07c77b9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PipedWriterTest.java
@@ -0,0 +1,477 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+
+public class PipedWriterTest extends junit.framework.TestCase {
+
+ static class PReader implements Runnable {
+ public PipedReader pr;
+
+ public char[] buf = new char[10];
+
+ public PReader(PipedWriter pw) {
+ try {
+ pr = new PipedReader(pw);
+ } catch (IOException e) {
+ fail();
+ }
+ }
+
+ public PReader(PipedReader pr) {
+ this.pr = pr;
+ }
+
+ public void run() {
+ try {
+ int r = 0;
+ for (int i = 0; i < buf.length; i++) {
+ r = pr.read();
+ if (r == -1)
+ break;
+ buf[i] = (char) r;
+ }
+ } catch (Exception e) {
+ fail();
+ }
+ }
+ }
+
+ Thread rdrThread;
+
+ PReader reader;
+
+ PipedWriter pw;
+
+ /**
+ * java.io.PipedWriter#PipedWriter()
+ */
+ public void test_Constructor() {
+ // Test for method java.io.PipedWriter()
+ // Used in tests
+ }
+
+ /**
+ * java.io.PipedWriter#PipedWriter(java.io.PipedReader)
+ */
+ public void test_ConstructorLjava_io_PipedReader() throws Exception {
+ // Test for method java.io.PipedWriter(java.io.PipedReader)
+ char[] buf = new char[10];
+ "HelloWorld".getChars(0, 10, buf, 0);
+ PipedReader rd = new PipedReader();
+ pw = new PipedWriter(rd);
+ rdrThread = new Thread(reader = new PReader(rd), "Constructor(Reader)");
+ rdrThread.start();
+ pw.write(buf);
+ pw.close();
+ rdrThread.join();
+ assertEquals("Failed to construct writer", "HelloWorld", new String(
+ reader.buf));
+ }
+
+ /**
+ * java.io.PipedWriter#close()
+ */
+ public void test_close() throws Exception {
+ // Test for method void java.io.PipedWriter.close()
+ char[] buf = new char[10];
+ "HelloWorld".getChars(0, 10, buf, 0);
+ PipedReader rd = new PipedReader();
+ pw = new PipedWriter(rd);
+ reader = new PReader(rd);
+ pw.close();
+ try {
+ pw.write(buf);
+ fail("Should have thrown exception when attempting to write to closed writer.");
+ } catch (Exception e) {
+ // correct
+ }
+ }
+
+ /**
+ * java.io.PipedWriter#connect(java.io.PipedReader)
+ */
+ public void test_connectLjava_io_PipedReader() throws Exception {
+ // Test for method void java.io.PipedWriter.connect(java.io.PipedReader)
+ char[] buf = new char[10];
+ "HelloWorld".getChars(0, 10, buf, 0);
+ PipedReader rd = new PipedReader();
+ pw = new PipedWriter();
+ pw.connect(rd);
+ rdrThread = new Thread(reader = new PReader(rd), "connect");
+ rdrThread.start();
+ pw.write(buf);
+ pw.close();
+ rdrThread.join();
+ assertEquals("Failed to write correct chars", "HelloWorld", new String(
+ reader.buf));
+ }
+
+ /**
+ * java.io.PipedWriter#flush()
+ */
+ public void test_flush() throws Exception {
+ // Test for method void java.io.PipedWriter.flush()
+ char[] buf = new char[10];
+ "HelloWorld".getChars(0, 10, buf, 0);
+ pw = new PipedWriter();
+ rdrThread = new Thread(reader = new PReader(pw), "flush");
+ rdrThread.start();
+ pw.write(buf);
+ pw.flush();
+ rdrThread.join();
+ assertEquals("Failed to flush chars", "HelloWorld", new String(
+ reader.buf));
+ }
+
+ /**
+ * java.io.PipedWriter#flush()
+ * Regression HARMONY-6293
+ */
+ public void test_flushAfterClose() throws Exception {
+
+ PipedReader pr = new PipedReader();
+ pw = new PipedWriter(pr);
+ pw.close();
+ try {
+ pw.flush();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ pr = new PipedReader();
+ pw = new PipedWriter(pr);
+ pr.close();
+
+ try {
+ pw.flush();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PipedWriter#write(char[], int, int)
+ */
+ public void test_write$CII() throws Exception {
+ // Test for method void java.io.PipedWriter.write(char [], int, int)
+ char[] buf = new char[10];
+ "HelloWorld".getChars(0, 10, buf, 0);
+ pw = new PipedWriter();
+ rdrThread = new Thread(reader = new PReader(pw), "writeCII");
+ rdrThread.start();
+ pw.write(buf, 0, 10);
+ pw.close();
+ rdrThread.join();
+ assertEquals("Failed to write correct chars", "HelloWorld", new String(
+ reader.buf));
+ }
+
+ /**
+ * java.io.PipedWriter#write(char[], int, int) Regression for
+ * HARMONY-387
+ */
+ public void test_write$CII_2() throws IOException {
+ PipedReader pr = new PipedReader();
+ PipedWriter obj = null;
+ try {
+ obj = new java.io.PipedWriter(pr);
+ obj.write(new char[0], (int) 0, (int) -1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.PipedWriter#write(char[], int, int)
+ */
+ public void test_write$CII_3() throws IOException {
+ PipedReader pr = new PipedReader();
+ PipedWriter obj = null;
+ try {
+ obj = new java.io.PipedWriter(pr);
+ obj.write(new char[0], (int) -1, (int) 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.PipedWriter#write(char[], int, int)
+ */
+ public void test_write$CII_4() throws IOException {
+ PipedReader pr = new PipedReader();
+ PipedWriter obj = null;
+ try {
+ obj = new java.io.PipedWriter(pr);
+ obj.write(new char[0], (int) -1, (int) -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.PipedWriter#write(char[], int, int)
+ */
+ public void test_write$CII_5() throws IOException {
+ PipedReader pr = new PipedReader();
+ PipedWriter obj = null;
+ try {
+ obj = new PipedWriter(pr);
+ obj.write((char[]) null, (int) -1, (int) 0);
+ fail("NullPointerException expected");
+ } catch (IndexOutOfBoundsException t) {
+ fail("NullPointerException expected");
+ } catch (NullPointerException t) {
+ }
+ }
+
+ /**
+ * java.io.PipedWriter#write(char[], int, int)
+ */
+ public void test_write$CII_6() throws IOException {
+ PipedReader pr = new PipedReader();
+ PipedWriter obj = null;
+ try {
+ obj = new PipedWriter(pr);
+ obj.write((char[]) null, (int) -1, (int) -1);
+ fail("NullPointerException expected");
+ } catch (IndexOutOfBoundsException t) {
+ fail("NullPointerException expected");
+ } catch (NullPointerException t) {
+ }
+ }
+
+ /**
+ * java.io.PipedWriter#write(char[], int, int)
+ */
+ public void test_write$CII_notConnected() throws IOException {
+ // Regression test for Harmony-2404
+ // create not connected pipe
+ PipedWriter obj = new PipedWriter();
+
+ // char array is null
+ try {
+ obj.write((char[]) null, 0, 1);
+ fail("IOException expected");
+ } catch (IOException ioe) {
+ // expected
+ }
+
+ // negative offset
+ try {
+ obj.write(new char[] { 1 }, -10, 1);
+ fail("IOException expected");
+ } catch (IOException ioe) {
+ // expected
+ }
+
+ // wrong offset
+ try {
+ obj.write(new char[] { 1 }, 10, 1);
+ fail("IOException expected");
+ } catch (IOException ioe) {
+ // expected
+ }
+
+ // negative length
+ try {
+ obj.write(new char[] { 1 }, 0, -10);
+ fail("IOException expected");
+ } catch (IOException ioe) {
+ // expected
+ }
+
+ // all valid params
+ try {
+ obj.write(new char[] { 1, 1 }, 0, 1);
+ fail("IOException expected");
+ } catch (IOException ioe) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PipedWriter#write(int)
+ */
+ public void test_write_I_MultiThread() throws IOException {
+ final PipedReader pr = new PipedReader();
+ final PipedWriter pw = new PipedWriter();
+ // test if writer recognizes dead reader
+ pr.connect(pw);
+
+ class WriteRunnable implements Runnable {
+ boolean pass = false;
+ volatile boolean readerAlive = true;
+
+ public void run() {
+ try {
+ pw.write(1);
+ while (readerAlive) {
+ // wait the reader thread dead
+ }
+ try {
+ // should throw exception since reader thread
+ // is now dead
+ pw.write(1);
+ } catch (IOException e) {
+ pass = true;
+ }
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+ WriteRunnable writeRunnable = new WriteRunnable();
+ Thread writeThread = new Thread(writeRunnable);
+ class ReadRunnable implements Runnable {
+ boolean pass;
+
+ public void run() {
+ try {
+ pr.read();
+ pass = true;
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+ ReadRunnable readRunnable = new ReadRunnable();
+ Thread readThread = new Thread(readRunnable);
+ writeThread.start();
+ readThread.start();
+ while (readThread.isAlive()) {
+ //wait the reader thread dead
+ }
+ writeRunnable.readerAlive = false;
+ assertTrue("reader thread failed to read", readRunnable.pass);
+ while (writeThread.isAlive()) {
+ //wait the writer thread dead
+ }
+ assertTrue("writer thread failed to recognize dead reader",
+ writeRunnable.pass);
+ }
+
+ /**
+ * java.io.PipedWriter#write(char[], int, int)
+ */
+ public void test_write_$CII_MultiThread() throws Exception {
+ final PipedReader pr = new PipedReader();
+ final PipedWriter pw = new PipedWriter();
+
+ // test if writer recognizes dead reader
+ pr.connect(pw);
+
+ class WriteRunnable implements Runnable {
+ boolean pass = false;
+
+ volatile boolean readerAlive = true;
+
+ public void run() {
+ try {
+ pw.write(1);
+ while (readerAlive) {
+ // wait the reader thread dead
+ }
+ try {
+ // should throw exception since reader thread
+ // is now dead
+ char[] buf = new char[10];
+ pw.write(buf, 0, 10);
+ } catch (IOException e) {
+ pass = true;
+ }
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+ WriteRunnable writeRunnable = new WriteRunnable();
+ Thread writeThread = new Thread(writeRunnable);
+ class ReadRunnable implements Runnable {
+ boolean pass;
+
+ public void run() {
+ try {
+ pr.read();
+ pass = true;
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+ ReadRunnable readRunnable = new ReadRunnable();
+ Thread readThread = new Thread(readRunnable);
+ writeThread.start();
+ readThread.start();
+ while (readThread.isAlive()) {
+ //wait the reader thread dead
+ }
+ writeRunnable.readerAlive = false;
+ assertTrue("reader thread failed to read", readRunnable.pass);
+ while (writeThread.isAlive()) {
+ //wait the writer thread dead
+ }
+ assertTrue("writer thread failed to recognize dead reader",
+ writeRunnable.pass);
+ }
+
+ /**
+ * java.io.PipedWriter#write(int)
+ */
+ public void test_writeI() throws Exception {
+ // Test for method void java.io.PipedWriter.write(int)
+
+ pw = new PipedWriter();
+ rdrThread = new Thread(reader = new PReader(pw), "writeI");
+ rdrThread.start();
+ pw.write(1);
+ pw.write(2);
+ pw.write(3);
+ pw.close();
+ rdrThread.join(1000);
+ assertTrue("Failed to write correct chars: " + (int) reader.buf[0]
+ + " " + (int) reader.buf[1] + " " + (int) reader.buf[2],
+ reader.buf[0] == 1 && reader.buf[1] == 2 && reader.buf[2] == 3);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() throws Exception {
+ try {
+ if (rdrThread != null) {
+ rdrThread.interrupt();
+ }
+ } catch (Exception ignore) {
+ }
+ try {
+ if (pw != null) {
+ pw.close();
+ }
+ } catch (Exception ignore) {
+ }
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PrintStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PrintStreamTest.java
new file mode 100644
index 0000000..19a63af
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PrintStreamTest.java
@@ -0,0 +1,673 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+
+public class PrintStreamTest extends junit.framework.TestCase {
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ byte[] ibuf = new byte[4096];
+
+ private File testFile = null;
+
+ private String testFilePath = null;
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ private static class MockPrintStream extends PrintStream {
+
+ public MockPrintStream(String fileName) throws FileNotFoundException {
+ super(fileName);
+ }
+
+ public MockPrintStream(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException {
+ super(fileName, csn);
+ }
+
+ public MockPrintStream(OutputStream os) {
+ super(os);
+ }
+
+ @Override
+ public void clearError() {
+ super.clearError();
+ }
+
+ @Override
+ public void setError() {
+ super.setError();
+ }
+ }
+
+ /**
+ * {@link java.io.PrintStream#PrintStream(String)}
+ */
+ public void test_Constructor_Ljava_lang_String() throws IOException {
+ MockPrintStream os = new MockPrintStream(testFilePath);
+ assertNotNull(os);
+ os.close();
+ }
+
+ /**
+ * {@link java.io.PrintStream#PrintStream(String, String)}
+ */
+ public void test_Constructor_Ljava_lang_String_Ljava_lang_String() throws Exception {
+ MockPrintStream os = new MockPrintStream(testFilePath, "utf-8");
+ assertNotNull(os);
+ os.close();
+
+ // Test that a bogus charset is mentioned in the exception
+ try {
+ new PrintStream(testFilePath, "Bogus");
+ fail("Exception expected");
+ } catch (UnsupportedEncodingException e) {
+ assertNotNull(e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PrintStream#PrintStream(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() throws Exception {
+ // Test for method java.io.PrintStream(java.io.OutputStream)
+ PrintStream os = new PrintStream(bos);
+ os.print(2345.76834720202);
+ os.close();
+
+ // regression for HARMONY-1195
+ try {
+ os = new PrintStream(bos, true, null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.io.PrintStream#PrintStream(java.io.OutputStream, boolean)
+ */
+ public void test_ConstructorLjava_io_OutputStreamZ() {
+ // Test for method java.io.PrintStream(java.io.OutputStream, boolean)
+ PrintStream os = new PrintStream(bos);
+ os.println(2345.76834720202);
+ os.flush();
+ assertTrue("Bytes not written", bos.size() > 0);
+ os.close();
+ }
+
+ /**
+ * java.io.PrintStream#PrintStream(java.io.OutputStream, boolean, String)
+ */
+ public void test_ConstructorLjava_io_OutputStreamZLjava_lang_String() {
+ try {
+ new PrintStream(new ByteArrayOutputStream(), false,
+ "%Illegal_name!");
+ fail("Expected UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PrintStream#checkError()
+ */
+ public void test_checkError() throws Exception {
+ // Test for method boolean java.io.PrintStream.checkError()
+ PrintStream os = new PrintStream(new OutputStream() {
+
+ public void write(int b) throws IOException {
+ throw new IOException();
+ }
+
+ public void write(byte[] b, int o, int l) throws IOException {
+ throw new IOException();
+ }
+ });
+ os.print(fileString.substring(0, 501));
+
+ assertTrue("Checkerror should return true", os.checkError());
+ }
+
+ /**
+ * {@link java.io.PrintStream#clearError()}
+ */
+ public void test_clearError() throws FileNotFoundException {
+ MockPrintStream os = new MockPrintStream(testFilePath);
+ assertFalse(os.checkError());
+ os.setError();
+ assertTrue(os.checkError());
+ os.clearError();
+ assertFalse(os.checkError());
+ os.close();
+ }
+
+ /**
+ * java.io.PrintStream#close()
+ */
+ public void test_close() throws Exception {
+ // Test for method void java.io.PrintStream.close()
+ PrintStream os = new PrintStream(bos);
+ os.close();
+ bos.close();
+ }
+
+ /**
+ * java.io.PrintStream#flush()
+ */
+ public void test_flush() throws Exception {
+ // Test for method void java.io.PrintStream.flush()
+ PrintStream os = new PrintStream(bos);
+ os.print(fileString.substring(0, 501));
+ os.flush();
+ assertEquals("Bytes not written after flush", 501, bos.size());
+ bos.close();
+ os.close();
+ }
+
+ /**
+ * java.io.PrintStream#print(char[])
+ */
+ public void test_print$C() {
+ // Test for method void java.io.PrintStream.print(char [])
+ PrintStream os = new PrintStream(bos, true);
+ try {
+ os.print((char[]) null);
+ fail("NPE expected");
+ } catch (NullPointerException ok) {
+ }
+
+ os = new PrintStream(bos, true);
+ char[] sc = new char[4000];
+ fileString.getChars(0, fileString.length(), sc, 0);
+ os.print(sc);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ os.close();
+
+ byte[] rbytes = new byte[4000];
+ bis.read(rbytes, 0, fileString.length());
+ assertEquals("Incorrect char[] written", fileString, new String(rbytes,
+ 0, fileString.length()));
+ }
+
+ /**
+ * java.io.PrintStream#print(char)
+ */
+ public void test_printC() throws Exception {
+ // Test for method void java.io.PrintStream.print(char)
+ PrintStream os = new PrintStream(bos, true);
+ os.print('t');
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ assertEquals("Incorrect char written", 't', isr.read());
+ }
+
+ /**
+ * java.io.PrintStream#print(double)
+ */
+ public void test_printD() {
+ // Test for method void java.io.PrintStream.print(double)
+ byte[] rbuf = new byte[100];
+ PrintStream os = new PrintStream(bos, true);
+ os.print(2345.76834720202);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ bis.read(rbuf, 0, 16);
+ assertEquals("Incorrect double written", "2345.76834720202",
+ new String(rbuf, 0, 16));
+ }
+
+ /**
+ * java.io.PrintStream#print(float)
+ */
+ public void test_printF() {
+ // Test for method void java.io.PrintStream.print(float)
+ PrintStream os = new PrintStream(bos, true);
+ byte rbuf[] = new byte[10];
+ os.print(29.08764f);
+ os.flush();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ bis.read(rbuf, 0, 8);
+ assertEquals("Incorrect float written", "29.08764", new String(rbuf, 0,
+ 8));
+
+ }
+
+ /**
+ * java.io.PrintStream#print(int)
+ */
+ public void test_printI() {
+ // Test for method void java.io.PrintStream.print(int)
+ PrintStream os = new PrintStream(bos, true);
+ os.print(768347202);
+ byte[] rbuf = new byte[18];
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ bis.read(rbuf, 0, 9);
+ assertEquals("Incorrect int written", "768347202", new String(rbuf, 0,
+ 9));
+ }
+
+ /**
+ * java.io.PrintStream#print(long)
+ */
+ public void test_printJ() {
+ // Test for method void java.io.PrintStream.print(long)
+ byte[] rbuf = new byte[100];
+ PrintStream os = new PrintStream(bos, true);
+ os.print(9875645283333L);
+ os.close();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ bis.read(rbuf, 0, 13);
+ assertEquals("Incorrect long written", "9875645283333", new String(
+ rbuf, 0, 13));
+ }
+
+ /**
+ * java.io.PrintStream#print(java.lang.Object)
+ */
+ public void test_printLjava_lang_Object() throws Exception {
+ // Test for method void java.io.PrintStream.print(java.lang.Object)
+ PrintStream os = new PrintStream(bos, true);
+ os.print((Object) null);
+ os.flush();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ byte[] nullbytes = new byte[4];
+ bis.read(nullbytes, 0, 4);
+ assertEquals("null should be written", "null", new String(nullbytes, 0,
+ 4));
+
+ bis.close();
+ bos.close();
+ os.close();
+
+ ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
+ os = new PrintStream(bos1, true);
+ os.print(new java.util.Vector());
+ bis = new ByteArrayInputStream(bos1.toByteArray());
+ byte[] rbytes = new byte[2];
+ bis.read(rbytes, 0, 2);
+ assertEquals("Incorrect Object written", "[]", new String(rbytes, 0, 2));
+ }
+
+ /**
+ * java.io.PrintStream#print(java.lang.String)
+ */
+ public void test_printLjava_lang_String() throws Exception {
+ // Test for method void java.io.PrintStream.print(java.lang.String)
+ PrintStream os = new PrintStream(bos, true);
+ os.print((String) null);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ byte[] nullbytes = new byte[4];
+ bis.read(nullbytes, 0, 4);
+ assertEquals("null should be written", "null", new String(nullbytes, 0,
+ 4));
+
+ bis.close();
+ bos.close();
+ os.close();
+
+ ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
+ os = new PrintStream(bos1, true);
+ os.print("Hello World");
+ bis = new ByteArrayInputStream(bos1.toByteArray());
+ byte rbytes[] = new byte[100];
+ bis.read(rbytes, 0, 11);
+ assertEquals("Incorrect string written", "Hello World", new String(
+ rbytes, 0, 11));
+ }
+
+ /**
+ * java.io.PrintStream#print(boolean)
+ */
+ public void test_printZ() throws Exception {
+ // Test for method void java.io.PrintStream.print(boolean)
+ PrintStream os = new PrintStream(bos, true);
+ os.print(true);
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bos
+ .toByteArray()));
+
+ assertTrue("Incorrect boolean written", dis.readBoolean());
+ }
+
+ /**
+ * java.io.PrintStream#println()
+ */
+ public void test_println() throws Exception {
+ // Test for method void java.io.PrintStream.println()
+ char c;
+ PrintStream os = new PrintStream(bos, true);
+ os.println("");
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ assertTrue("Newline not written", (c = (char) isr.read()) == '\r'
+ || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#println(char[])
+ */
+ public void test_println$C() throws Exception {
+ // Test for method void java.io.PrintStream.println(char [])
+ PrintStream os = new PrintStream(bos, true);
+ char[] sc = new char[4000];
+ fileString.getChars(0, fileString.length(), sc, 0);
+ os.println(sc);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ byte[] rbytes = new byte[4000];
+ bis.read(rbytes, 0, fileString.length());
+ assertEquals("Incorrect char[] written", fileString, new String(rbytes,
+ 0, fileString.length()));
+
+ // In this particular test method, the end of data is not immediately
+ // followed by newLine separator in the reading buffer, instead its
+ // followed by zeros. The newline is written as the last entry
+ // in the inputStream buffer. Therefore, we must keep reading until we
+ // hit a new line.
+ int r;
+ boolean newline = false;
+ while ((r = isr.read()) != -1) {
+ if (r == '\r' || r == '\n')
+ newline = true;
+ }
+ assertTrue("Newline not written", newline);
+ }
+
+ /**
+ * java.io.PrintStream#println(char)
+ */
+ public void test_printlnC() throws Exception {
+ // Test for method void java.io.PrintStream.println(char)
+ int c;
+ PrintStream os = new PrintStream(bos, true);
+ os.println('t');
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ assertEquals("Incorrect char written", 't', isr.read());
+ assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#println(double)
+ */
+ public void test_printlnD() throws Exception {
+ // Test for method void java.io.PrintStream.println(double)
+ int c;
+ PrintStream os = new PrintStream(bos, true);
+ os.println(2345.76834720202);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ byte[] rbuf = new byte[100];
+ bis.read(rbuf, 0, 16);
+ assertEquals("Incorrect double written", "2345.76834720202",
+ new String(rbuf, 0, 16));
+ assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#println(float)
+ */
+ public void test_printlnF() throws Exception {
+ // Test for method void java.io.PrintStream.println(float)
+ int c;
+ byte[] rbuf = new byte[100];
+ PrintStream os = new PrintStream(bos, true);
+ os.println(29.08764f);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ bis.read(rbuf, 0, 8);
+ assertEquals("Incorrect float written", "29.08764", new String(rbuf, 0,
+ 8));
+ assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#println(int)
+ */
+ public void test_printlnI() throws Exception {
+ // Test for method void java.io.PrintStream.println(int)
+ int c;
+ PrintStream os = new PrintStream(bos, true);
+ os.println(768347202);
+ byte[] rbuf = new byte[100];
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ bis.read(rbuf, 0, 9);
+ assertEquals("Incorrect int written", "768347202", new String(rbuf, 0,
+ 9));
+ assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#println(long)
+ */
+ public void test_printlnJ() throws Exception {
+ // Test for method void java.io.PrintStream.println(long)
+ int c;
+ PrintStream os = new PrintStream(bos, true);
+ os.println(9875645283333L);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ byte[] rbuf = new byte[100];
+ bis.read(rbuf, 0, 13);
+ assertEquals("Incorrect long written", "9875645283333", new String(
+ rbuf, 0, 13));
+ assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#println(java.lang.Object)
+ */
+ public void test_printlnLjava_lang_Object() throws Exception {
+ // Test for method void java.io.PrintStream.println(java.lang.Object)
+ char c;
+ PrintStream os = new PrintStream(bos, true);
+ os.println(new java.util.Vector());
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ byte[] rbytes = new byte[2];
+ bis.read(rbytes, 0, 2);
+ assertEquals("Incorrect Vector written", "[]", new String(rbytes, 0, 2));
+ assertTrue("Newline not written", (c = (char) isr.read()) == '\r'
+ || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#println(java.lang.String)
+ */
+ public void test_printlnLjava_lang_String() throws Exception {
+ // Test for method void java.io.PrintStream.println(java.lang.String)
+ char c;
+ PrintStream os = new PrintStream(bos, true);
+ os.println("Hello World");
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ byte rbytes[] = new byte[100];
+ bis.read(rbytes, 0, 11);
+ assertEquals("Incorrect string written", "Hello World", new String(
+ rbytes, 0, 11));
+ assertTrue("Newline not written", (c = (char) isr.read()) == '\r'
+ || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#println(boolean)
+ */
+ public void test_printlnZ() throws Exception {
+ // Test for method void java.io.PrintStream.println(boolean)
+ int c;
+ PrintStream os = new PrintStream(bos, true);
+ os.println(true);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ InputStreamReader isr = new InputStreamReader(bis);
+ byte[] rbuf = new byte[100];
+ bis.read(rbuf, 0, 4);
+ assertEquals("Incorrect boolean written", "true",
+ new String(rbuf, 0, 4));
+ assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
+ }
+
+ /**
+ * java.io.PrintStream#write(byte[], int, int)
+ */
+ public void test_write$BII() {
+ // Test for method void java.io.PrintStream.write(byte [], int, int)
+ PrintStream os = new PrintStream(bos, true);
+ os.write(fileString.getBytes(), 0, fileString.length());
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ byte rbytes[] = new byte[4000];
+ bis.read(rbytes, 0, fileString.length());
+ assertTrue("Incorrect bytes written", new String(rbytes, 0, fileString
+ .length()).equals(fileString));
+ }
+
+ /**
+ * java.io.PrintStream#write(int)
+ */
+ public void test_writeI() {
+ // Test for method void java.io.PrintStream.write(int)
+ PrintStream os = new PrintStream(bos, true);
+ os.write('t');
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ assertEquals("Incorrect char written", 't', bis.read());
+ }
+
+ /**
+ * java.io.PrintStream#append(char)
+ */
+ public void test_appendChar() throws IOException {
+ char testChar = ' ';
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintStream printStream = new PrintStream(out);
+ printStream.append(testChar);
+ printStream.flush();
+ assertEquals(String.valueOf(testChar), out.toString());
+ printStream.close();
+ }
+
+ /**
+ * java.io.PrintStream#append(CharSequence)
+ */
+ public void test_appendCharSequence() {
+ String testString = "My Test String";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintStream printStream = new PrintStream(out);
+ printStream.append(testString);
+ printStream.flush();
+ assertEquals(testString, out.toString());
+ printStream.close();
+ }
+
+ /**
+ * java.io.PrintStream#append(CharSequence, int, int)
+ */
+ public void test_appendCharSequenceIntInt() {
+ String testString = "My Test String";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintStream printStream = new PrintStream(out);
+ printStream.append(testString, 1, 3);
+ printStream.flush();
+ assertEquals(testString.substring(1, 3), out.toString());
+ printStream.close();
+ }
+
+ /**
+ * java.io.PrintStream#format(java.lang.String, java.lang.Object...)
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object() {
+ PrintStream os = new PrintStream(bos, false);
+ os.format("%s %s", "Hello", "World");
+ os.flush();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ byte[] rbytes = new byte[11];
+ bis.read(rbytes, 0, rbytes.length);
+ assertEquals("Wrote incorrect string", "Hello World",
+ new String(rbytes));
+
+ }
+
+ /**
+ * java.io.PrintStream#format(java.util.Locale, java.lang.String,
+ *java.lang.Object...)
+ */
+ public void test_formatLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
+ PrintStream os = new PrintStream(bos, false);
+ os.format(Locale.US, "%s %s", "Hello", "World");
+ os.flush();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ byte[] rbytes = new byte[11];
+ bis.read(rbytes, 0, rbytes.length);
+ assertEquals("Wrote incorrect string", "Hello World",
+ new String(rbytes));
+ }
+
+ /**
+ * java.io.PrintStream#printf(java.lang.String, java.lang.Object...)
+ */
+ public void test_printfLjava_lang_String$Ljava_lang_Object() {
+ PrintStream os = new PrintStream(bos, false);
+ os.printf("%s %s", "Hello", "World");
+ os.flush();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ byte[] rbytes = new byte[11];
+ bis.read(rbytes, 0, rbytes.length);
+ assertEquals("Wrote incorrect string", "Hello World",
+ new String(rbytes));
+ }
+
+ /**
+ * java.io.PrintStream#printf(java.util.Locale, java.lang.String,
+ *java.lang.Object...)
+ */
+ public void test_printfLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
+ PrintStream os = new PrintStream(bos, false);
+ os.printf(Locale.US, "%s %s", "Hello", "World");
+ os.flush();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ byte[] rbytes = new byte[11];
+ bis.read(rbytes, 0, rbytes.length);
+ assertEquals("Wrote incorrect string", "Hello World",
+ new String(rbytes));
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ testFile = File.createTempFile("test", null);
+ testFilePath = testFile.getAbsolutePath();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ testFile.delete();
+ testFile = null;
+ testFilePath = null;
+ super.tearDown();
+ }
+
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PrintWriterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PrintWriterTest.java
new file mode 100644
index 0000000..9c60406
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PrintWriterTest.java
@@ -0,0 +1,779 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.util.Locale;
+
+import tests.support.Support_StringReader;
+import tests.support.Support_StringWriter;
+
+public class PrintWriterTest extends junit.framework.TestCase {
+
+ static class Bogus {
+ public String toString() {
+ return "Bogus";
+ }
+ }
+
+ /**
+ * @since 1.6
+ */
+ static class MockPrintWriter extends PrintWriter {
+
+ public MockPrintWriter(OutputStream out, boolean autoflush) {
+ super(out, autoflush);
+ }
+
+ @Override
+ public void clearError() {
+ super.clearError();
+ }
+
+ }
+
+ PrintWriter pw;
+
+ ByteArrayOutputStream bao;
+
+ ByteArrayInputStream bai;
+
+ BufferedReader br;
+
+ /**
+ * java.io.PrintWriter#PrintWriter(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() {
+ // Test for method java.io.PrintWriter(java.io.OutputStream)
+ String s;
+ pw.println("Random Chars");
+ pw.write("Hello World");
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ s = br.readLine();
+ assertTrue("Incorrect string written/read: " + s, s
+ .equals("Random Chars"));
+ s = br.readLine();
+ assertTrue("Incorrect string written/read: " + s, s
+ .equals("Hello World"));
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
+ */
+ public void test_ConstructorLjava_io_OutputStreamZ() {
+ // Test for method java.io.PrintWriter(java.io.OutputStream, boolean)
+ String s;
+ pw = new PrintWriter(bao, true);
+ pw.println("Random Chars");
+ pw.write("Hello World");
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ s = br.readLine();
+ assertTrue("Incorrect string written/read: " + s, s
+ .equals("Random Chars"));
+ pw.flush();
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ s = br.readLine();
+ assertTrue("Incorrect string written/read: " + s, s
+ .equals("Random Chars"));
+ s = br.readLine();
+ assertTrue("Incorrect string written/read: " + s, s
+ .equals("Hello World"));
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PrintWriter#PrintWriter(java.io.Writer)
+ */
+ public void test_ConstructorLjava_io_Writer() {
+ // Test for method java.io.PrintWriter(java.io.Writer)
+ Support_StringWriter sw;
+ pw = new PrintWriter(sw = new Support_StringWriter());
+ pw.print("Hello");
+ pw.flush();
+ assertEquals("Failed to construct proper writer",
+ "Hello", sw.toString());
+ }
+
+ /**
+ * java.io.PrintWriter#PrintWriter(java.io.Writer, boolean)
+ */
+ public void test_ConstructorLjava_io_WriterZ() {
+ // Test for method java.io.PrintWriter(java.io.Writer, boolean)
+ Support_StringWriter sw;
+ pw = new PrintWriter(sw = new Support_StringWriter(), true);
+ pw.print("Hello");
+ // Auto-flush should have happened
+ assertEquals("Failed to construct proper writer",
+ "Hello", sw.toString());
+ }
+
+ /**
+ * java.io.PrintWriter#PrintWriter(java.io.File)
+ */
+ public void test_ConstructorLjava_io_File() throws Exception {
+ File file = File.createTempFile(getClass().getName(), null);
+ try {
+ PrintWriter writer = new PrintWriter(file);
+ writer.close();
+ } finally {
+ file.delete();
+ }
+ }
+
+ /**
+ * java.io.PrintWriter#PrintWriter(java.io.File, java.lang.String)
+ */
+ public void test_ConstructorLjava_io_File_Ljava_lang_String() throws Exception {
+ File file = File.createTempFile(getClass().getName(), null);
+ try {
+ PrintWriter writer = new PrintWriter(file,
+ Charset.defaultCharset().name());
+ writer.close();
+ } finally {
+ file.delete();
+ }
+ }
+
+ /**
+ * java.io.PrintWriter#PrintWriter(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws Exception {
+ File file = File.createTempFile(getClass().getName(), null);
+ try {
+ PrintWriter writer = new PrintWriter(file.getPath());
+ writer.close();
+ } finally {
+ file.delete();
+ }
+ }
+
+ /**
+ * java.io.PrintWriter#PrintWriter(java.lang.String, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String_Ljava_lang_String() throws Exception {
+ File file = File.createTempFile(getClass().getName(), null);
+ try {
+ PrintWriter writer = new PrintWriter(file.getPath(),
+ Charset.defaultCharset().name());
+ writer.close();
+ } finally {
+ file.delete();
+ }
+ }
+
+ /**
+ * java.io.PrintWriter#checkError()
+ */
+ public void test_checkError() {
+ // Test for method boolean java.io.PrintWriter.checkError()
+ pw.close();
+ pw.print(490000000000.08765);
+ assertTrue("Failed to return error", pw.checkError());
+ }
+
+ /**
+ * java.io.PrintWriter#clearError()
+ * @since 1.6
+ */
+ public void test_clearError() {
+ // Test for method boolean java.io.PrintWriter.clearError()
+ MockPrintWriter mpw = new MockPrintWriter(new ByteArrayOutputStream(), false);
+ mpw.close();
+ mpw.print(490000000000.08765);
+ assertTrue("Failed to return error", mpw.checkError());
+ mpw.clearError();
+ assertFalse("Internal error state has not be cleared", mpw.checkError());
+ }
+
+ /**
+ * java.io.PrintWriter#close()
+ */
+ public void test_close() {
+ // Test for method void java.io.PrintWriter.close()
+ pw.close();
+ pw.println("l");
+ assertTrue("Write on closed stream failed to generate error", pw
+ .checkError());
+ }
+
+ /**
+ * java.io.PrintWriter#flush()
+ */
+ public void test_flush() {
+ // Test for method void java.io.PrintWriter.flush()
+ final double dub = 490000000000.08765;
+ pw.print(dub);
+ pw.flush();
+ assertTrue("Failed to flush", new String(bao.toByteArray())
+ .equals(String.valueOf(dub)));
+ }
+
+ /**
+ * java.io.PrintWriter#print(char[])
+ */
+ public void test_print$C() {
+ // Test for method void java.io.PrintWriter.print(char [])
+ String s = null;
+ char[] schars = new char[11];
+ "Hello World".getChars(0, 11, schars, 0);
+ pw.print(schars);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect char[] string: " + s, s
+ .equals("Hello World"));
+ int r = 0;
+ try {
+ pw.print((char[]) null);
+ } catch (NullPointerException e) {
+ r = 1;
+ }
+ assertEquals("null pointer exception for printing null char[] is not caught",
+ 1, r);
+ }
+
+ /**
+ * java.io.PrintWriter#print(char)
+ */
+ public void test_printC() {
+ // Test for method void java.io.PrintWriter.print(char)
+ pw.print('c');
+ pw.flush();
+ assertEquals("Wrote incorrect char string", "c", new String(bao.toByteArray())
+ );
+ }
+
+ /**
+ * java.io.PrintWriter#print(double)
+ */
+ public void test_printD() {
+ // Test for method void java.io.PrintWriter.print(double)
+ final double dub = 490000000000.08765;
+ pw.print(dub);
+ pw.flush();
+ assertTrue("Wrote incorrect double string", new String(bao
+ .toByteArray()).equals(String.valueOf(dub)));
+ }
+
+ /**
+ * java.io.PrintWriter#print(float)
+ */
+ public void test_printF() {
+ // Test for method void java.io.PrintWriter.print(float)
+ final float flo = 49.08765f;
+ pw.print(flo);
+ pw.flush();
+ assertTrue("Wrote incorrect float string",
+ new String(bao.toByteArray()).equals(String.valueOf(flo)));
+ }
+
+ /**
+ * java.io.PrintWriter#print(int)
+ */
+ public void test_printI() {
+ // Test for method void java.io.PrintWriter.print(int)
+ pw.print(4908765);
+ pw.flush();
+ assertEquals("Wrote incorrect int string", "4908765", new String(bao.toByteArray())
+ );
+ }
+
+ /**
+ * java.io.PrintWriter#print(long)
+ */
+ public void test_printJ() {
+ // Test for method void java.io.PrintWriter.print(long)
+ pw.print(49087650000L);
+ pw.flush();
+ assertEquals("Wrote incorrect long string", "49087650000", new String(bao.toByteArray())
+ );
+ }
+
+ /**
+ * java.io.PrintWriter#print(java.lang.Object)
+ */
+ public void test_printLjava_lang_Object() {
+ // Test for method void java.io.PrintWriter.print(java.lang.Object)
+ pw.print((Object) null);
+ pw.flush();
+ assertEquals("Did not write null", "null", new String(bao.toByteArray())
+ );
+ bao.reset();
+
+ pw.print(new Bogus());
+ pw.flush();
+ assertEquals("Wrote in incorrect Object string", "Bogus", new String(bao
+ .toByteArray()));
+ }
+
+ /**
+ * java.io.PrintWriter#print(java.lang.String)
+ */
+ public void test_printLjava_lang_String() {
+ // Test for method void java.io.PrintWriter.print(java.lang.String)
+ pw.print((String) null);
+ pw.flush();
+ assertEquals("did not write null", "null", new String(bao.toByteArray())
+ );
+ bao.reset();
+
+ pw.print("Hello World");
+ pw.flush();
+ assertEquals("Wrote incorrect string", "Hello World", new String(bao.toByteArray())
+ );
+ }
+
+ /**
+ * java.io.PrintWriter#print(boolean)
+ */
+ public void test_printZ() {
+ // Test for method void java.io.PrintWriter.print(boolean)
+ pw.print(true);
+ pw.flush();
+ assertEquals("Wrote in incorrect boolean string", "true", new String(bao
+ .toByteArray()));
+ }
+
+ /**
+ * java.io.PrintWriter#println()
+ */
+ public void test_println() {
+ // Test for method void java.io.PrintWriter.println()
+ String s;
+ pw.println("Blarg");
+ pw.println();
+ pw.println("Bleep");
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ s = br.readLine();
+ assertTrue("Wrote incorrect line: " + s, s.equals("Blarg"));
+ s = br.readLine();
+ assertTrue("Wrote incorrect line: " + s, s.equals(""));
+ s = br.readLine();
+ assertTrue("Wrote incorrect line: " + s, s.equals("Bleep"));
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PrintWriter#println(char[])
+ */
+ public void test_println$C() {
+ // Test for method void java.io.PrintWriter.println(char [])
+ String s = null;
+ char[] schars = new char[11];
+ "Hello World".getChars(0, 11, schars, 0);
+ pw.println("Random Chars");
+ pw.println(schars);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ s = br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect char[] string: " + s, s
+ .equals("Hello World"));
+ }
+
+ /**
+ * java.io.PrintWriter#println(char)
+ */
+ public void test_printlnC() {
+ // Test for method void java.io.PrintWriter.println(char)
+ String s = null;
+ pw.println("Random Chars");
+ pw.println('c');
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ s = br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect char string: " + s, s.equals("c"));
+ }
+
+ /**
+ * java.io.PrintWriter#println(double)
+ */
+ public void test_printlnD() {
+ // Test for method void java.io.PrintWriter.println(double)
+ String s = null;
+ final double dub = 4000000000000000.657483;
+ pw.println("Random Chars");
+ pw.println(dub);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect double string: " + s, s.equals(String
+ .valueOf(dub)));
+ }
+
+ /**
+ * java.io.PrintWriter#println(float)
+ */
+ public void test_printlnF() {
+ // Test for method void java.io.PrintWriter.println(float)
+ String s;
+ final float flo = 40.4646464f;
+ pw.println("Random Chars");
+ pw.println(flo);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ assertTrue("Wrote incorrect float string: " + s + " wanted: "
+ + String.valueOf(flo), s.equals(String.valueOf(flo)));
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+
+ }
+
+ /**
+ * java.io.PrintWriter#println(int)
+ */
+ public void test_printlnI() {
+ // Test for method void java.io.PrintWriter.println(int)
+ String s = null;
+ pw.println("Random Chars");
+ pw.println(400000);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect int string: " + s, s.equals("400000"));
+ }
+
+ /**
+ * java.io.PrintWriter#println(long)
+ */
+ public void test_printlnJ() {
+ // Test for method void java.io.PrintWriter.println(long)
+ String s = null;
+ pw.println("Random Chars");
+ pw.println(4000000000000L);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect long string: " + s, s
+ .equals("4000000000000"));
+ }
+
+ /**
+ * java.io.PrintWriter#println(java.lang.Object)
+ */
+ public void test_printlnLjava_lang_Object() {
+ // Test for method void java.io.PrintWriter.println(java.lang.Object)
+ String s = null;
+ pw.println("Random Chars");
+ pw.println(new Bogus());
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect Object string: " + s, s.equals("Bogus"));
+ }
+
+ /**
+ * java.io.PrintWriter#println(java.lang.String)
+ */
+ public void test_printlnLjava_lang_String() {
+ // Test for method void java.io.PrintWriter.println(java.lang.String)
+ String s = null;
+ pw.println("Random Chars");
+ pw.println("Hello World");
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect string: " + s, s.equals("Hello World"));
+ }
+
+ /**
+ * java.io.PrintWriter#println(boolean)
+ */
+ public void test_printlnZ() {
+ // Test for method void java.io.PrintWriter.println(boolean)
+ String s = null;
+ pw.println("Random Chars");
+ pw.println(false);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect boolean string: " + s, s.equals("false"));
+ }
+
+ /**
+ * java.io.PrintWriter#write(char[])
+ */
+ public void test_write$C() {
+ // Test for method void java.io.PrintWriter.write(char [])
+ String s = null;
+ char[] schars = new char[11];
+ "Hello World".getChars(0, 11, schars, 0);
+ pw.println("Random Chars");
+ pw.write(schars);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test: " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect char[] string: " + s, s
+ .equals("Hello World"));
+ }
+
+ /**
+ * java.io.PrintWriter#write(char[], int, int)
+ */
+ public void test_write$CII() {
+ // Test for method void java.io.PrintWriter.write(char [], int, int)
+ String s = null;
+ char[] schars = new char[11];
+ "Hello World".getChars(0, 11, schars, 0);
+ pw.println("Random Chars");
+ pw.write(schars, 6, 5);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect char[] string: " + s, s.equals("World"));
+ }
+
+ /**
+ * java.io.PrintWriter#write(int)
+ */
+ public void test_writeI() throws IOException {
+ // Test for method void java.io.PrintWriter.write(int)
+ char[] cab = new char[3];
+ pw.write('a');
+ pw.write('b');
+ pw.write('c');
+ pw.flush();
+ InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(bao.toByteArray()));
+ cab[0] = (char) isr.read();
+ cab[1] = (char) isr.read();
+ cab[2] = (char) isr.read();
+ assertTrue("Wrote incorrect ints", cab[0] == 'a' && cab[1] == 'b'
+ && cab[2] == 'c');
+
+ }
+
+ /**
+ * java.io.PrintWriter#write(java.lang.String)
+ */
+ public void test_writeLjava_lang_String() {
+ // Test for method void java.io.PrintWriter.write(java.lang.String)
+ String s = null;
+ pw.println("Random Chars");
+ pw.write("Hello World");
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect char[] string: " + s, s
+ .equals("Hello World"));
+ }
+
+ /**
+ * java.io.PrintWriter#write(java.lang.String, int, int)
+ */
+ public void test_writeLjava_lang_StringII() {
+ // Test for method void java.io.PrintWriter.write(java.lang.String, int,
+ // int)
+ String s = null;
+ pw.println("Random Chars");
+ pw.write("Hello World", 6, 5);
+ pw.flush();
+ try {
+ br = new BufferedReader(new Support_StringReader(bao.toString()));
+ br.readLine();
+ s = br.readLine();
+ } catch (IOException e) {
+ fail("IOException during test : " + e.getMessage());
+ }
+ assertTrue("Wrote incorrect char[] string: " + s, s.equals("World"));
+ }
+
+ /**
+ * java.io.PrintWriter#append(char)
+ */
+ public void test_appendChar() {
+ char testChar = ' ';
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintWriter printWriter = new PrintWriter(out);
+ printWriter.append(testChar);
+ printWriter.flush();
+ assertEquals(String.valueOf(testChar), out.toString());
+ printWriter.close();
+ }
+
+ /**
+ * java.io.PrintWriter#append(CharSequence)
+ */
+ public void test_appendCharSequence() {
+
+ String testString = "My Test String";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintWriter printWriter = new PrintWriter(out);
+ printWriter.append(testString);
+ printWriter.flush();
+ assertEquals(testString, out.toString());
+ printWriter.close();
+
+ }
+
+ /**
+ * java.io.PrintWriter#append(CharSequence, int, int)
+ */
+ public void test_appendCharSequenceIntInt() {
+ String testString = "My Test String";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintWriter printWriter = new PrintWriter(out);
+ printWriter.append(testString, 1, 3);
+ printWriter.flush();
+ assertEquals(testString.substring(1, 3), out.toString());
+ printWriter.close();
+
+ }
+
+ /**
+ * java.io.PrintWriter#format(java.lang.String, java.lang.Object...)
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object() {
+ pw.format("%s %s", "Hello", "World");
+ pw.flush();
+ assertEquals("Wrote incorrect string", "Hello World",
+ new String(bao.toByteArray()));
+ }
+
+ /**
+ * java.io.PrintWriter#format(java.util.Locale, java.lang.String, java.lang.Object...)
+ */
+ public void test_formatLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
+ pw.format(Locale.US, "%s %s", "Hello", "World");
+ pw.flush();
+ assertEquals("Wrote incorrect string", "Hello World",
+ new String(bao.toByteArray()));
+ }
+
+ /**
+ * java.io.PrintWriter#printf(java.lang.String, java.lang.Object...)
+ */
+ public void test_printfLjava_lang_String$Ljava_lang_Object() {
+ pw.printf("%s %s", "Hello", "World");
+ pw.flush();
+ assertEquals("Wrote incorrect string", "Hello World",
+ new String(bao.toByteArray()));
+ }
+
+ /**
+ * java.io.PrintWriter#printf(java.util.Locale, java.lang.String, java.lang.Object...)
+ */
+ public void test_printfLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
+ pw.printf(Locale.US, "%s %s", "Hello", "World");
+ pw.flush();
+ assertEquals("Wrote incorrect string", "Hello World",
+ new String(bao.toByteArray()));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ bao = new ByteArrayOutputStream();
+ pw = new PrintWriter(bao, false);
+
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ pw.close();
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PushbackInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PushbackInputStreamTest.java
new file mode 100644
index 0000000..8c56934
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PushbackInputStreamTest.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.PushbackInputStream;
+import java.io.UnsupportedEncodingException;
+
+public class PushbackInputStreamTest extends junit.framework.TestCase {
+
+ PushbackInputStream pis;
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ public void test_reset() {
+ PushbackInputStream pb = new PushbackInputStream(
+ new ByteArrayInputStream(new byte[] { 0 }), 2);
+ try {
+ pb.reset();
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ public void test_mark() {
+ PushbackInputStream pb = new PushbackInputStream(
+ new ByteArrayInputStream(new byte[] { 0 }), 2);
+ pb.mark(Integer.MAX_VALUE);
+ pb.mark(0);
+ pb.mark(-1);
+ pb.mark(Integer.MIN_VALUE);
+ }
+
+
+ /**
+ * java.io.PushbackInputStream#PushbackInputStream(java.io.InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() {
+ try {
+ PushbackInputStream str = new PushbackInputStream(null);
+ str.read();
+ fail("Expected IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ try {
+ pis = new PushbackInputStream(new ByteArrayInputStream("Hello"
+ .getBytes()));
+ pis.unread("He".getBytes());
+ fail("Failed to throw exception on unread when buffer full");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.PushbackInputStream#PushbackInputStream(java.io.InputStream,
+ *int)
+ */
+ public void test_ConstructorLjava_io_InputStreamI() {
+ // Test for method java.io.PushbackInputStream(java.io.InputStream, int)
+ try {
+ pis = new PushbackInputStream(new ByteArrayInputStream("Hello"
+ .getBytes()), 5);
+ pis.unread("Hellos".getBytes());
+ } catch (IOException e) {
+ // Correct
+ // Pushback buffer should be full
+ return;
+
+ }
+ fail("Failed to throw exception on unread when buffer full");
+ }
+
+ /*
+ * java.io.PushBackInputStream(InputStream, int)
+ */
+ public void test_ConstructorLjava_io_InputStreamL() {
+ try {
+ PushbackInputStream str = new PushbackInputStream(null, 1);
+ str.read();
+ fail("Expected IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.io.PushbackInputStream#available()
+ */
+ public void test_available() {
+ // Test for method int java.io.PushbackInputStream.available()
+ try {
+ assertTrue("Available returned incorrect number of bytes", pis
+ .available() == fileString.getBytes().length);
+ } catch (IOException e) {
+ fail("Exception during available test: " + e.toString());
+ }
+ }
+
+ /**
+ * java.io.PushbackInputStream#markSupported()
+ */
+ public void test_markSupported() {
+ // Test for method boolean java.io.PushbackInputStream.markSupported()
+ assertTrue("markSupported returned true", !pis.markSupported());
+ }
+
+ /**
+ * java.io.PushbackInputStream#read()
+ */
+ public void test_read() {
+ // Test for method int java.io.PushbackInputStream.read()
+ try {
+ assertTrue("Incorrect byte read", pis.read() == fileString
+ .getBytes("UTF-8")[0]);
+ } catch (IOException e) {
+ fail("Exception during read test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PushbackInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() {
+ // Test for method int java.io.PushbackInputStream.read(byte [], int,
+ // int)
+ try {
+ byte[] buf = new byte[100];
+ pis.read(buf, 0, buf.length);
+ assertTrue("Incorrect bytes read", new String(buf, "UTF-8")
+ .equals(fileString.substring(0, 100)));
+ } catch (IOException e) {
+ fail("Exception during read test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PushbackInputStream#skip(long)
+ */
+ public void test_skipJ() throws Exception {
+ // Test for method long java.io.PushbackInputStream.skip(long)
+ byte[] buf = new byte[50];
+ pis.skip(50);
+ pis.read(buf, 0, buf.length);
+ assertTrue("a) Incorrect bytes read", new String(buf, "UTF-8")
+ .equals(fileString.substring(50, 100)));
+ pis.unread(buf);
+ pis.skip(25);
+ byte[] buf2 = new byte[25];
+ pis.read(buf2, 0, buf2.length);
+ assertTrue("b) Incorrect bytes read", new String(buf2, "UTF-8")
+ .equals(fileString.substring(75, 100)));
+ }
+
+ /**
+ * java.io.PushbackInputStream#unread(byte[])
+ */
+ public void test_unread$B() {
+ // Test for method void java.io.PushbackInputStream.unread(byte [])
+ try {
+ byte[] buf = new byte[100];
+ pis.read(buf, 0, buf.length);
+ assertTrue("Incorrect bytes read", new String(buf, "UTF-8")
+ .equals(fileString.substring(0, 100)));
+ pis.unread(buf);
+ pis.read(buf, 0, 50);
+ assertTrue("Failed to unread bytes", new String(buf, 0, 50, "UTF-8")
+ .equals(fileString.substring(0, 50)));
+ } catch (IOException e) {
+ fail("IOException during unread test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PushbackInputStream#unread(byte[], int, int)
+ */
+ public void test_unread$BII() throws IOException {
+ // Test for method void java.io.PushbackInputStream.unread(byte [], int,
+ // int)
+ byte[] buf = new byte[100];
+ pis.read(buf, 0, buf.length);
+ assertTrue("Incorrect bytes read", new String(buf, "UTF-8")
+ .equals(fileString.substring(0, 100)));
+ pis.unread(buf, 50, 50);
+ pis.read(buf, 0, 50);
+ assertTrue("Failed to unread bytes", new String(buf, 0, 50, "UTF-8")
+ .equals(fileString.substring(50, 100)));
+
+ // Regression for HARMONY-49
+ try {
+ PushbackInputStream pb = new PushbackInputStream(
+ new ByteArrayInputStream(new byte[] { 0 }), 2);
+ pb.unread(new byte[1], 0, 5);
+ fail("Assert 0: should throw IOE");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PushbackInputStream#unread(int)
+ */
+ public void test_unreadI() {
+ // Test for method void java.io.PushbackInputStream.unread(int)
+ try {
+ int x;
+ assertTrue("Incorrect byte read", (x = pis.read()) == fileString
+ .getBytes("UTF-8")[0]);
+ pis.unread(x);
+ assertTrue("Failed to unread", pis.read() == x);
+ } catch (IOException e) {
+ fail("IOException during read test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() throws UnsupportedEncodingException {
+
+ pis = new PushbackInputStream(new ByteArrayInputStream(fileString
+ .getBytes("UTF-8")), 65535);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ pis.close();
+ } catch (IOException e) {
+ fail("IOException during tearDown : " + e.getMessage());
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PushbackReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PushbackReaderTest.java
new file mode 100644
index 0000000..d49ee53
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/PushbackReaderTest.java
@@ -0,0 +1,381 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.CharArrayReader;
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.Reader;
+import java.io.StringReader;
+
+public class PushbackReaderTest extends junit.framework.TestCase {
+
+ PushbackReader pbr;
+
+ String pbString = "Hello World";
+
+ /**
+ * java.io.PushbackReader#PushbackReader(java.io.Reader)
+ */
+ public void test_ConstructorLjava_io_Reader() {
+ // Test for method java.io.PushbackReader(java.io.Reader)
+ try {
+ pbr.close();
+ pbr = new PushbackReader(new StringReader(pbString));
+ char buf[] = new char[5];
+ pbr.read(buf, 0, 5);
+ pbr.unread(buf);
+ } catch (IOException e) {
+ // Correct
+ return;
+ }
+ fail("Created reader with buffer larger than 1");
+ }
+
+ /**
+ * java.io.PushbackReader#PushbackReader(java.io.Reader, int)
+ */
+ public void test_ConstructorLjava_io_ReaderI() {
+ // Test for method java.io.PushbackReader(java.io.Reader, int)
+ assertTrue("Used to test", true);
+ }
+
+ /**
+ * java.io.PushbackReader#close()
+ */
+ public void test_close() {
+ // Test for method void java.io.PushbackReader.close()
+ try {
+ pbr.close();
+ pbr.read();
+ } catch (Exception e) {
+ return;
+ }
+ fail("Failed to throw exception reading from closed reader");
+ }
+
+ /**
+ * java.io.PushbackReader#mark(int)
+ */
+ public void test_markI() {
+ try {
+ pbr.mark(3);
+ } catch (IOException e) {
+ // correct
+ return;
+ }
+ fail("mark failed to throw expected IOException");
+ }
+
+ /**
+ * java.io.PushbackReader#markSupported()
+ */
+ public void test_markSupported() {
+ // Test for method boolean java.io.PushbackReader.markSupported()
+ assertTrue("markSupported returned true", !pbr.markSupported());
+ }
+
+ /**
+ * java.io.PushbackReader#read()
+ */
+ public void test_read() {
+ // Test for method int java.io.PushbackReader.read()
+ try {
+ char c;
+ pbr.read();
+ c = (char) pbr.read();
+ assertTrue("Failed to read char: " + c, c == pbString.charAt(1));
+ Reader reader = new PushbackReader(new CharArrayReader(
+ new char[] { '\u8765' }));
+ assertTrue("Wrong double byte character", reader.read() == '\u8765');
+ } catch (IOException e) {
+ fail("IOException during read test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#read(char[], int, int)
+ */
+ public void test_read$CII() {
+ // Test for method int java.io.PushbackReader.read(char [], int, int)
+ try {
+ char[] c = new char[5];
+ pbr.read(c, 0, 5);
+ assertTrue("Failed to read chars", new String(c).equals(pbString
+ .substring(0, 5)));
+ } catch (IOException e) {
+ fail("IOException during read test : " + e.getMessage());
+ }
+ }
+
+ public void test_read_$CII_Exception() throws IOException {
+ pbr = new PushbackReader(new StringReader(pbString), 10);
+
+ char[] charArray = new char[10];
+
+ try {
+ pbr.read(null, 1, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ pbr.read(charArray, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ pbr.read(charArray, -1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ pbr.read(charArray, 0, 0);
+ pbr.read(charArray, 0, charArray.length);
+ pbr.read(charArray, charArray.length, 0);
+
+ try {
+ pbr.read(charArray, charArray.length + 1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ pbr.read(charArray, 0, charArray.length + 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // Can't read from a closed PushbackReader.
+ pbr.close();
+ try {
+ pbr.read(charArray, 0, 1);
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#ready()
+ */
+ public void test_ready() {
+ // Test for method boolean java.io.PushbackReader.ready()
+ try {
+ char[] c = new char[11];
+ if (c.length > 0)
+ ;// use c to avoid warning msg
+ assertTrue("Ready stream returned false to ready()", pbr.ready());
+ } catch (IOException e) {
+ fail("IOException during ready() test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#reset()
+ */
+ public void test_reset() {
+ try {
+ pbr.reset();
+ } catch (IOException e) {
+ // correct
+ return;
+ }
+ fail("mark failed to throw expected IOException");
+ }
+
+ /**
+ * java.io.PushbackReader#unread(char[])
+ */
+ public void test_unread$C() {
+ // Test for method void java.io.PushbackReader.unread(char [])
+ try {
+ char[] c = new char[5];
+ pbr.read(c, 0, 5);
+ pbr.unread(c);
+ pbr.read(c, 0, 5);
+ assertTrue("Failed to unread chars", new String(c).equals(pbString
+ .substring(0, 5)));
+ } catch (IOException e) {
+ fail("IOException during read test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#skip(long)
+ */
+ public void test_skip$J() {
+ char chars[] = new char[] { 'h', 'e', 'l', 'l', 'o' };
+ for (int i = 0; i < 3; i++) {
+ Reader reader, reader2;
+ switch (i) {
+ case 0:
+ reader = new StringReader(new String(chars));
+ reader2 = new StringReader(new String(chars));
+ break;
+ case 1:
+ reader = new FilterReader(new StringReader(new String(chars))) {
+ };
+ reader2 = new FilterReader(new StringReader(new String(chars))) {
+ };
+ break;
+ default:
+ reader = new CharArrayReader(chars);
+ reader2 = new CharArrayReader(chars);
+ }
+ PushbackReader pReader = new PushbackReader(reader, 2);
+ PushbackReader pReader2 = new PushbackReader(reader2, 2);
+ boolean skipped = false;
+ long numSkipped = 0;
+ try {
+ numSkipped = pReader2.skip(3);
+ pReader2.unread('a');
+ pReader2.unread('b');
+ numSkipped += pReader2.skip(10);
+ numSkipped += pReader2.skip(10);
+ numSkipped += pReader2.skip(10);
+ numSkipped += pReader2.skip(10);
+ numSkipped += pReader2.skip(10);
+ numSkipped += pReader2.skip(10);
+ assertEquals("Did not skip correct number of characters",
+ 7, numSkipped);
+ numSkipped = 0;
+ numSkipped += pReader.skip(2);
+ pReader.unread('i');
+ numSkipped += pReader.skip(2);
+ numSkipped += pReader.skip(0);
+ skipped = true;
+ numSkipped += pReader.skip(-1);
+ fail("Failed to throw "
+ + new IllegalArgumentException().getClass().getName());
+ } catch (IllegalArgumentException e) {
+ assertTrue("Failed to skip characters" + e, skipped);
+ } catch (IOException e) {
+ fail("Failed to skip characters" + e);
+ }
+ try {
+ numSkipped += pReader.skip(1);
+ numSkipped += pReader.skip(1);
+ numSkipped += pReader.skip(1);
+ assertEquals("Failed to skip all characters", 6, numSkipped);
+ long nextSkipped = pReader.skip(1);
+ assertEquals("skipped empty reader", 0, nextSkipped);
+ } catch (IOException e) {
+ fail("Failed to skip more characters" + e);
+ }
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#unread(char[], int, int)
+ */
+ public void test_unread$CII() {
+ // Test for method void java.io.PushbackReader.unread(char [], int, int)
+ try {
+ char[] c = new char[5];
+ pbr.read(c, 0, 5);
+ pbr.unread(c, 0, 2);
+ pbr.read(c, 0, 5);
+ assertTrue("Failed to unread chars", new String(c).equals(pbString
+ .substring(0, 2)
+ + pbString.substring(5, 8)));
+ } catch (IOException e) {
+ fail("IOException during unread test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#unread(char[], int, int)
+ */
+ public void test_unread_$CII_NullPointerException() throws IOException {
+ //a pushback reader with one character buffer
+ pbr = new PushbackReader(new StringReader(pbString));
+
+ try {
+ pbr.unread(null, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#unread(char[], int, int)
+ */
+ public void test_unread_$CII_Exception_InsufficientBuffer() throws IOException {
+ //a pushback reader with one character buffer
+ pbr = new PushbackReader(new StringReader(pbString));
+
+ //if count > buffer's size , should throw IOException
+ try {
+ pbr.unread(new char[pbString.length()], 0, 2);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#unread(char[], int, int)
+ */
+ public void test_unread_$CII_ArrayIndexOutOfBoundsException() throws IOException {
+ //a pushback reader with one character buffer
+ pbr = new PushbackReader(new StringReader(pbString));
+
+ try {
+ pbr.unread(new char[pbString.length()], -1, -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.io.PushbackReader#unread(int)
+ */
+ public void test_unreadI() {
+ // Test for method void java.io.PushbackReader.unread(int)
+
+ try {
+ int c;
+ pbr.read();
+ c = pbr.read();
+ pbr.unread(c);
+ assertTrue("Failed to unread char", pbr.read() == c);
+ } catch (IOException e) {
+ fail("IOException during unread test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ pbr = new PushbackReader(new StringReader(pbString), 10);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ try {
+ pbr.close();
+ } catch (IOException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/RandomAccessFileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/RandomAccessFileTest.java
new file mode 100644
index 0000000..f6784fb
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/RandomAccessFileTest.java
@@ -0,0 +1,1059 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.NonWritableChannelException;
+
+public class RandomAccessFileTest extends junit.framework.TestCase {
+
+ public String fileName;
+
+ public boolean ufile = true;
+
+ java.io.RandomAccessFile raf;
+
+ java.io.File f;
+
+ String unihw = "\u0048\u0065\u006C\u0801\u006C\u006F\u0020\u0057\u0081\u006F\u0072\u006C\u0064";
+
+ //java.io.FileOutputStream fos;
+
+ public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+ /**
+ * java.io.RandomAccessFile#RandomAccessFile(java.io.File,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_io_FileLjava_lang_String()
+ throws Exception {
+ // Test for method java.io.RandomAccessFile(java.io.File,
+ // java.lang.String)
+ RandomAccessFile raf = new java.io.RandomAccessFile(f, "rw");
+ raf.write(20);
+ raf.seek(0);
+ assertEquals("Incorrect int read/written", 20, raf.read());
+ raf.close();
+
+ raf = new java.io.RandomAccessFile(f, "rwd");
+ raf.write(20);
+ raf.seek(0);
+ assertEquals("Incorrect int read/written", 20, raf.read());
+ raf.close();
+
+ raf = new java.io.RandomAccessFile(f, "rws");
+ raf.write(20);
+ raf.seek(0);
+ assertEquals("Incorrect int read/written", 20, raf.read());
+ raf.close();
+
+ // Regression for HARMONY-50
+ File f = File.createTempFile("xxx", "yyy");
+ f.deleteOnExit();
+ raf = new RandomAccessFile(f, "rws");
+ raf.close();
+
+ f = File.createTempFile("xxx", "yyy");
+ f.deleteOnExit();
+ raf = new RandomAccessFile(f, "rwd");
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#RandomAccessFile(java.lang.String,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_String()
+ throws IOException {
+ // Test for method java.io.RandomAccessFile(java.lang.String,
+ // java.lang.String)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.write("Test".getBytes(), 0, 4);
+ raf.close();
+
+ raf = new java.io.RandomAccessFile(fileName, "rwd");
+ raf.write("Test".getBytes(), 0, 4);
+ raf.close();
+
+ raf = new java.io.RandomAccessFile(fileName, "rws");
+ raf.write("Test".getBytes(), 0, 4);
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#RandomAccessFile(java.lang.String,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_String_I()
+ throws IOException {
+ RandomAccessFile raf = null;
+ try {
+ raf = new RandomAccessFile("", "r");
+ fail("should throw FileNotFoundException.");
+ } catch (FileNotFoundException e) {
+ // Expected
+ } finally {
+ if (raf != null) {
+ raf.close();
+ raf = null;
+ }
+ }
+ try {
+ raf = new RandomAccessFile(new File(""), "r");
+ fail("should throw FileNotFoundException.");
+ } catch (FileNotFoundException e) {
+ // Expected
+ } finally {
+ if (raf != null) {
+ raf.close();
+ raf = null;
+ }
+ }
+ File dir = new File("/");
+ assertTrue(dir.isDirectory());
+ try {
+ raf = new RandomAccessFile(dir.getPath(), "r");
+ fail();
+ } catch (FileNotFoundException expected) {
+ } finally {
+ if (raf != null) {
+ raf.close();
+ raf = null;
+ }
+ }
+ }
+
+ /**
+ * java.io.RandomAccessFile#close()
+ */
+ public void test_close() {
+ // Test for method void java.io.RandomAccessFile.close()
+ try {
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.close();
+ raf.write("Test".getBytes(), 0, 4);
+ fail("Failed to close file properly");
+ } catch (IOException e) {
+ }
+ }
+
+ /**
+ * java.io.RandomAccessFile#getFD()
+ */
+ public void test_getFD() throws IOException {
+ // Test for method java.io.FileDescriptor
+ // java.io.RandomAccessFile.getFD()
+
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ assertTrue("Returned invalid fd", raf.getFD().valid());
+
+ raf.close();
+ assertFalse("Returned valid fd after close", raf.getFD().valid());
+ }
+
+ /**
+ * java.io.RandomAccessFile#getFilePointer()
+ */
+ public void test_getFilePointer() throws IOException {
+ // Test for method long java.io.RandomAccessFile.getFilePointer()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.write(fileString.getBytes(), 0, 1000);
+ assertEquals("Incorrect filePointer returned", 1000, raf
+ .getFilePointer());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#length()
+ */
+ public void test_length() throws IOException {
+ // Test for method long java.io.RandomAccessFile.length()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.write(fileString.getBytes());
+ assertEquals("Incorrect length returned", fileString.length(), raf
+ .length());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#read()
+ */
+ public void test_read() throws IOException {
+ // Test for method int java.io.RandomAccessFile.read()
+ FileOutputStream fos = new java.io.FileOutputStream(fileName);
+ fos.write(fileString.getBytes("UTF-8"), 0, fileString.length());
+ fos.close();
+
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+ assertEquals("Incorrect bytes returned from read",
+ fileString.charAt(0), raf.read());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#read(byte[])
+ */
+ public void test_read$B() throws IOException {
+ // Test for method int java.io.RandomAccessFile.read(byte [])
+ FileOutputStream fos = new java.io.FileOutputStream(fileName);
+ fos.write(fileString.getBytes(), 0, fileString.length());
+ fos.close();
+
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+ byte[] rbuf = new byte[4000];
+ raf.read(rbuf);
+ assertEquals("Incorrect bytes returned from read", fileString,
+ new String(rbuf, 0, fileString.length()));
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException {
+ // Test for method int java.io.RandomAccessFile.read(byte [], int, int)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ byte[] rbuf = new byte[4000];
+ FileOutputStream fos = new java.io.FileOutputStream(fileName);
+ fos.write(fileString.getBytes(), 0, fileString.length());
+ fos.close();
+ raf.read(rbuf, 0, fileString.length());
+ assertEquals("Incorrect bytes returned from read", fileString,
+ new String(rbuf, 0, fileString.length()));
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readBoolean()
+ */
+ public void test_readBoolean() throws IOException {
+ // Test for method boolean java.io.RandomAccessFile.readBoolean()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeBoolean(true);
+ raf.seek(0);
+ assertTrue("Incorrect boolean read/written", raf.readBoolean());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readByte()
+ */
+ public void test_readByte() throws IOException {
+ // Test for method byte java.io.RandomAccessFile.readByte()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeByte(127);
+ raf.seek(0);
+ assertEquals("Incorrect bytes read/written", 127, raf.readByte());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readChar()
+ */
+ public void test_readChar() throws IOException {
+ // Test for method char java.io.RandomAccessFile.readChar()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeChar('T');
+ raf.seek(0);
+ assertEquals("Incorrect char read/written", 'T', raf.readChar());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readDouble()
+ */
+ public void test_readDouble() throws IOException {
+ // Test for method double java.io.RandomAccessFile.readDouble()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeDouble(Double.MAX_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect double read/written", Double.MAX_VALUE, raf
+ .readDouble(), 0);
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readFloat()
+ */
+ public void test_readFloat() throws IOException {
+ // Test for method float java.io.RandomAccessFile.readFloat()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeFloat(Float.MAX_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect float read/written", Float.MAX_VALUE, raf
+ .readFloat(), 0);
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readFully(byte[])
+ */
+ public void test_readFully$B() throws IOException {
+ // Test for method void java.io.RandomAccessFile.readFully(byte [])
+ byte[] buf = new byte[10];
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeBytes("HelloWorld");
+ raf.seek(0);
+ raf.readFully(buf);
+ assertEquals("Incorrect bytes read/written", "HelloWorld", new String(
+ buf, 0, 10, "UTF-8"));
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readFully(byte[], int, int)
+ */
+ public void test_readFully$BII() throws IOException {
+ // Test for method void java.io.RandomAccessFile.readFully(byte [], int,
+ // int)
+ byte[] buf = new byte[10];
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeBytes("HelloWorld");
+ raf.seek(0);
+ raf.readFully(buf, 0, buf.length);
+ assertEquals("Incorrect bytes read/written", "HelloWorld", new String(
+ buf, 0, 10, "UTF-8"));
+ try {
+ raf.readFully(buf, 0, buf.length);
+ fail("Reading past end of buffer did not throw EOFException");
+ } catch (EOFException e) {
+ }
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readInt()
+ */
+ public void test_readInt() throws IOException {
+ // Test for method int java.io.RandomAccessFile.readInt()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeInt(Integer.MIN_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect int read/written", Integer.MIN_VALUE, raf
+ .readInt());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readLine()
+ */
+ public void test_readLine() throws IOException {
+ // Test for method java.lang.String java.io.RandomAccessFile.readLine()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ String s = "Goodbye\nCruel\nWorld\n";
+ raf.write(s.getBytes("UTF-8"), 0, s.length());
+ raf.seek(0);
+
+ assertEquals("Goodbye", raf.readLine());
+ assertEquals("Cruel", raf.readLine());
+ assertEquals("World", raf.readLine());
+
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readLong()
+ */
+ public void test_readLong() throws IOException {
+ // Test for method long java.io.RandomAccessFile.readLong()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeLong(Long.MAX_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect long read/written", Long.MAX_VALUE, raf
+ .readLong());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readShort()
+ */
+ public void test_readShort() throws IOException {
+ // Test for method short java.io.RandomAccessFile.readShort()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeShort(Short.MIN_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect long read/written", Short.MIN_VALUE, raf
+ .readShort());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readUnsignedByte()
+ */
+ public void test_readUnsignedByte() throws IOException {
+ // Test for method int java.io.RandomAccessFile.readUnsignedByte()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeByte(-1);
+ raf.seek(0);
+ assertEquals("Incorrect byte read/written", 255, raf.readUnsignedByte());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readUnsignedShort()
+ */
+ public void test_readUnsignedShort() throws IOException {
+ // Test for method int java.io.RandomAccessFile.readUnsignedShort()
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeShort(-1);
+ raf.seek(0);
+ assertEquals("Incorrect byte read/written", 65535, raf
+ .readUnsignedShort());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#readUTF()
+ */
+ public void test_readUTF() throws IOException {
+ // Test for method java.lang.String java.io.RandomAccessFile.readUTF()
+
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeUTF(unihw);
+ raf.seek(0);
+ assertEquals("Incorrect utf string read", unihw, raf.readUTF());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#seek(long)
+ */
+ public void test_seekJ() throws IOException {
+ // Test for method void java.io.RandomAccessFile.seek(long)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.write(fileString.getBytes(), 0, fileString.length());
+ raf.seek(12);
+ assertEquals("Seek failed to set filePointer", 12, raf.getFilePointer());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#skipBytes(int)
+ */
+ public void test_skipBytesI() throws IOException {
+ // Test for method int java.io.RandomAccessFile.skipBytes(int)
+ byte[] buf = new byte[5];
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeBytes("HelloWorld");
+ raf.seek(0);
+ raf.skipBytes(5);
+ raf.readFully(buf);
+ assertEquals("Failed to skip bytes", "World", new String(buf, 0, 5, "UTF-8"));
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#write(byte[])
+ */
+ public void test_write$B() throws IOException {
+ // Test for method void java.io.RandomAccessFile.write(byte [])
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+
+ byte[] nullByteArray = null;
+ try {
+ raf.write(nullByteArray);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ byte[] rbuf = new byte[4000];
+ raf.write(fileString.getBytes());
+ raf.close();
+
+ try {
+ raf.write(nullByteArray);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ //will not throw IOException if array's length is 0
+ raf.write(new byte[0]);
+
+ try {
+ raf.write(fileString.getBytes());
+ fail("should throw IOException");
+ } catch (IOException e) {
+ //expected
+ }
+
+ FileInputStream fis = new java.io.FileInputStream(fileName);
+ fis.read(rbuf, 0, fileString.length());
+ assertEquals("Incorrect bytes written", fileString, new String(rbuf, 0,
+ fileString.length()));
+ fis.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#write(byte[], int, int)
+ */
+ public void test_write$BII() throws IOException {
+ // Test for method void java.io.RandomAccessFile.write(byte [], int,
+ // int)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ byte[] rbuf = new byte[4000];
+ raf.write(fileString.getBytes(), 0, fileString.length());
+ raf.close();
+ FileInputStream fis = new java.io.FileInputStream(fileName);
+ fis.read(rbuf, 0, fileString.length());
+ assertEquals("Incorrect bytes written", fileString, new String(rbuf, 0,
+ fileString.length()));
+ fis.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#write(byte[], int, int)
+ */
+ public void test_write_$BII_Exception() throws IOException {
+ raf = new java.io.RandomAccessFile(f, "rw");
+ byte[] nullByteArray = null;
+ byte[] byteArray = new byte[10];
+
+ try {
+ raf.write(nullByteArray, -1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ raf.write(nullByteArray, 0, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ raf.write(nullByteArray, 1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ raf.write(nullByteArray, 1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ raf.write(nullByteArray, 1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ raf.write(byteArray, -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ raf.write(byteArray, -1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ raf.write(byteArray, -1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ raf.write(byteArray, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ raf.write(byteArray, 0, 0);
+ raf.write(byteArray, 0, byteArray.length);
+ raf.write(byteArray, 1, 0);
+ raf.write(byteArray, byteArray.length, 0);
+
+ try {
+ raf.write(byteArray, byteArray.length + 1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ raf.write(byteArray, byteArray.length + 1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ raf.close();
+
+ try {
+ raf.write(nullByteArray, -1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ raf.write(byteArray, -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ raf.write(byteArray, 0, 1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ //expected
+ }
+
+ try {
+ raf.write(byteArray, 0, byteArray.length);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ //expected
+ }
+
+ try {
+ raf.write(byteArray, 1, 1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ //expected
+ }
+
+ try {
+ raf.write(byteArray, byteArray.length + 1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ // will not throw IOException if count = 0
+ raf.write(byteArray, 0, 0);
+ raf.write(byteArray, byteArray.length, 0);
+ }
+
+
+ /**
+ * java.io.RandomAccessFile#write(int)
+ */
+ public void test_writeI() throws IOException {
+ // Test for method void java.io.RandomAccessFile.write(int)
+ byte[] rbuf = new byte[4000];
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.write('t');
+ raf.close();
+ FileInputStream fis = new java.io.FileInputStream(fileName);
+ fis.read(rbuf, 0, 1);
+ assertEquals("Incorrect byte written", 't', rbuf[0]);
+ fis.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeBoolean(boolean)
+ */
+ public void test_writeBooleanZ() throws IOException {
+ // Test for method void java.io.RandomAccessFile.writeBoolean(boolean)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeBoolean(true);
+ raf.seek(0);
+ assertTrue("Incorrect boolean read/written", raf.readBoolean());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeByte(int)
+ */
+ public void test_writeByteI() throws IOException {
+ // Test for method void java.io.RandomAccessFile.writeByte(int)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeByte(127);
+ raf.seek(0);
+ assertEquals("Incorrect byte read/written", 127, raf.readByte());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeBytes(java.lang.String)
+ */
+ public void test_writeBytesLjava_lang_String() throws IOException {
+ // Test for method void
+ // java.io.RandomAccessFile.writeBytes(java.lang.String)
+ byte[] buf = new byte[10];
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeBytes("HelloWorld");
+ raf.seek(0);
+ raf.readFully(buf);
+ assertEquals("Incorrect bytes read/written", "HelloWorld", new String(
+ buf, 0, 10, "UTF-8"));
+ raf.close();
+
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeChar(int)
+ */
+ public void test_writeCharI() throws IOException {
+ // Test for method void java.io.RandomAccessFile.writeChar(int)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeChar('T');
+ raf.seek(0);
+ assertEquals("Incorrect char read/written", 'T', raf.readChar());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeChars(java.lang.String)
+ */
+ public void test_writeCharsLjava_lang_String() throws IOException {
+ // Test for method void
+ // java.io.RandomAccessFile.writeChars(java.lang.String)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeChars("HelloWorld");
+ char[] hchars = new char[10];
+ "HelloWorld".getChars(0, 10, hchars, 0);
+ raf.seek(0);
+ for (int i = 0; i < hchars.length; i++)
+ assertEquals("Incorrect string written", hchars[i], raf.readChar());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeDouble(double)
+ */
+ public void test_writeDoubleD() throws IOException {
+ // Test for method void java.io.RandomAccessFile.writeDouble(double)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeDouble(Double.MAX_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect double read/written", Double.MAX_VALUE, raf
+ .readDouble(), 0);
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeFloat(float)
+ */
+ public void test_writeFloatF() throws IOException {
+ // Test for method void java.io.RandomAccessFile.writeFloat(float)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeFloat(Float.MAX_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect float read/written", Float.MAX_VALUE, raf
+ .readFloat(), 0);
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeInt(int)
+ */
+ public void test_writeIntI() throws IOException {
+ // Test for method void java.io.RandomAccessFile.writeInt(int)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeInt(Integer.MIN_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect int read/written", Integer.MIN_VALUE, raf
+ .readInt());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeLong(long)
+ */
+ public void test_writeLongJ() throws IOException {
+ // Test for method void java.io.RandomAccessFile.writeLong(long)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeLong(Long.MAX_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect long read/written", Long.MAX_VALUE, raf
+ .readLong());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeShort(int)
+ */
+ public void test_writeShortI() throws IOException {
+ // Test for method void java.io.RandomAccessFile.writeShort(int)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeShort(Short.MIN_VALUE);
+ raf.seek(0);
+ assertEquals("Incorrect long read/written", Short.MIN_VALUE, raf
+ .readShort());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#writeUTF(java.lang.String)
+ */
+ public void test_writeUTFLjava_lang_String() throws IOException {
+ // Test for method void
+ // java.io.RandomAccessFile.writeUTF(java.lang.String)
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ raf.writeUTF(unihw);
+ raf.seek(0);
+ assertEquals("Incorrect utf string", unihw, raf.readUTF());
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#seek(long)
+ * <p/>
+ * Regression for HARMONY-374
+ */
+ public void test_seekI() throws IOException {
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ try {
+ raf.seek(-1);
+ fail("IOException must be thrown if pos < 0");
+ } catch (IOException e) {
+ }
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#read(byte[], int, int)
+ * <p/>
+ * Regression for HARMONY-377
+ */
+ public void test_readBII() throws IOException {
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ try {
+ raf.read(new byte[1], -1, 1);
+ fail("IndexOutOfBoundsException must be thrown if off <0");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ raf.read(new byte[1], 0, -1);
+ fail("IndexOutOfBoundsException must be thrown if len <0");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ raf.read(new byte[1], 0, 5);
+ fail("IndexOutOfBoundsException must be thrown if off+len > b.length");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ raf.read(new byte[10], Integer.MAX_VALUE, 5);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ raf.read(new byte[10], 5, Integer.MAX_VALUE);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#read(byte[], int, int)
+ */
+ public void test_read_$BII_IndexOutOfBoundsException() throws IOException {
+ FileOutputStream fos = new java.io.FileOutputStream(fileName);
+ fos.write(fileString.getBytes(), 0, fileString.length());
+ fos.close();
+
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+ byte[] rbuf = new byte[100];
+ raf.close();
+ try {
+ raf.read(rbuf, -1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.io.RandomAccessFile#read(byte[], int, int)
+ */
+ public void test_read_$BII_IOException() throws IOException {
+ FileOutputStream fos = new java.io.FileOutputStream(fileName);
+ fos.write(fileString.getBytes(), 0, fileString.length());
+ fos.close();
+
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+ byte[] rbuf = new byte[100];
+ raf.close();
+ int read = raf.read(rbuf, 0, 0);
+ assertEquals(0, read);
+ }
+
+ /**
+ * java.io.RandomAccessFile#read(byte[])
+ */
+ public void test_read_$B_IOException() throws IOException {
+ FileOutputStream fos = new java.io.FileOutputStream(fileName);
+ fos.write(fileString.getBytes(), 0, fileString.length());
+ fos.close();
+
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+ byte[] rbuf = new byte[0];
+ raf.close();
+ int read = raf.read(rbuf);
+ assertEquals(0, read);
+ }
+
+ /**
+ * java.io.RandomAccessFile#read(byte[], int, int)
+ */
+ public void test_read_$BII_NullPointerException() throws IOException {
+ File f = File.createTempFile("tmp", "tmp");
+ f.deleteOnExit();
+ RandomAccessFile raf = new RandomAccessFile(f, "r");
+ byte[] rbuf = null;
+ try {
+ raf.read(rbuf, 0, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ raf.close();
+ }
+
+ /**
+ * java.io.RandomAccessFile#write(byte[], int, int)
+ * <p/>
+ * Regression for HARMONY-377
+ */
+ public void test_writeBII() throws IOException {
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+ try {
+ raf.write(new byte[1], -1, 1);
+ fail("IndexOutOfBoundsException must be thrown if off <0");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ raf.write(new byte[1], 0, -1);
+ fail("IndexOutOfBoundsException must be thrown if len <0");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ raf.write(new byte[1], 0, 5);
+ fail("IndexOutOfBoundsException must be thrown if off+len > b.length");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ raf.write(new byte[10], Integer.MAX_VALUE, 5);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ raf.write(new byte[10], 5, Integer.MAX_VALUE);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ raf.close();
+ }
+
+ /**
+ * Regression for HARMONY-69
+ */
+ public void testRandomAccessFile_String_String() throws IOException {
+ f.createNewFile();
+ RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+ FileChannel fcr = raf.getChannel();
+
+ try {
+ fcr.lock(0L, Long.MAX_VALUE, false);
+ fail("NonWritableChannelException expected!");
+ } catch (NonWritableChannelException e) {
+ }
+ raf.close();
+ }
+
+ // Regression test for HARMONY-6542
+ public void testRandomAccessFile_seekMoreThan2gb() throws IOException {
+ if (File.separator != "/") {
+ // skip windows until a test can be implemented that doesn't
+ // require 2GB of free disk space
+ return;
+ }
+ // (all?) unix platforms support sparse files so this should not
+ // need to have 2GB free disk space to pass
+ RandomAccessFile raf = new RandomAccessFile(f, "rw");
+ // write a few bytes so we get more helpful error messages
+ // if we land in the wrong places
+ raf.write(1);
+ raf.write(2);
+ raf.seek(2147483647);
+ raf.write(3);
+ raf.write(4);
+ raf.write(5);
+ raf.write(6);
+ raf.seek(0);
+ assertEquals("seek 0", 1, raf.read());
+ raf.seek(2147483649L);
+ assertEquals("seek >2gb", 5, raf.read());
+ raf.seek(0);
+ assertEquals("seek back to 0", 1, raf.read());
+ raf.close();
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ f = File.createTempFile("raf", "tst");
+ if (!f.delete()) {
+ fail("Unable to delete test file : " + f);
+ }
+ fileName = f.getAbsolutePath();
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ *
+ * @throws Exception
+ */
+ protected void tearDown() throws Exception {
+ if (f.exists()) {
+ f.delete();
+ }
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ReaderTest.java
new file mode 100644
index 0000000..f2b1439
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ReaderTest.java
@@ -0,0 +1,205 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.nio.CharBuffer;
+
+import junit.framework.TestCase;
+
+public class ReaderTest extends TestCase {
+
+ public void test_Reader_CharBuffer_null() throws IOException {
+ String s = "MY TEST STRING";
+ MockReader mockReader = new MockReader(s.toCharArray());
+ CharBuffer charBuffer = null;
+ try {
+ mockReader.read(charBuffer);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ //expected;
+ }
+ }
+
+ public void test_Reader_CharBuffer_ZeroChar() throws IOException {
+ //the charBuffer has the capacity of 0, then there the number of char read
+ // to the CharBuffer is 0. Furthermore, the MockReader is intact in its content.
+ String s = "MY TEST STRING";
+ char[] srcBuffer = s.toCharArray();
+ MockReader mockReader = new MockReader(srcBuffer);
+ CharBuffer charBuffer = CharBuffer.allocate(0);
+ int result = mockReader.read(charBuffer);
+ assertEquals(0, result);
+ char[] destBuffer = new char[srcBuffer.length];
+ mockReader.read(destBuffer);
+ assertEquals(s, String.valueOf(destBuffer));
+ }
+
+ public void test_Reader_CharBufferChar() throws IOException {
+ String s = "MY TEST STRING";
+ char[] srcBuffer = s.toCharArray();
+ final int CHARBUFFER_SIZE = 10;
+ MockReader mockReader = new MockReader(srcBuffer);
+ CharBuffer charBuffer = CharBuffer.allocate(CHARBUFFER_SIZE);
+ charBuffer.append('A');
+ final int CHARBUFFER_REMAINING = charBuffer.remaining();
+ int result = mockReader.read(charBuffer);
+ assertEquals(CHARBUFFER_REMAINING, result);
+ charBuffer.rewind();
+ assertEquals(s.substring(0, CHARBUFFER_REMAINING), charBuffer
+ .subSequence(CHARBUFFER_SIZE - CHARBUFFER_REMAINING,
+ CHARBUFFER_SIZE).toString());
+ char[] destBuffer = new char[srcBuffer.length - CHARBUFFER_REMAINING];
+ mockReader.read(destBuffer);
+ assertEquals(s.substring(CHARBUFFER_REMAINING), String
+ .valueOf(destBuffer));
+ }
+
+ /**
+ * {@link java.io.Reader#mark(int)}
+ */
+ public void test_mark() {
+ MockReader mockReader = new MockReader();
+ try {
+ mockReader.mark(0);
+ fail("Should throw IOException for Reader do not support mark");
+ } catch (IOException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * {@link java.io.Reader#read()}
+ */
+ public void test_read() throws IOException {
+ MockReader reader = new MockReader();
+
+ // return -1 when the stream is null;
+ assertEquals("Should be equal to -1", -1, reader.read());
+
+ String string = "MY TEST STRING";
+ char[] srcBuffer = string.toCharArray();
+ MockReader mockReader = new MockReader(srcBuffer);
+
+ // normal read
+ for (char c : srcBuffer) {
+ assertEquals("Should be equal to \'" + c + "\'", c, mockReader
+ .read());
+ }
+
+ // return -1 when read Out of Index
+ mockReader.read();
+ assertEquals("Should be equal to -1", -1, reader.read());
+
+ }
+
+ /**
+ * {@link java.io.Reader#ready()}
+ */
+ public void test_ready() throws IOException {
+ MockReader mockReader = new MockReader();
+ assertFalse("Should always return false", mockReader.ready());
+
+ }
+
+ /**
+ * {@link java.io.Reader#reset()}
+ */
+ public void test_reset() {
+ MockReader mockReader = new MockReader();
+ try {
+ mockReader.reset();
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * {@link java.io.Reader#skip(long)}
+ */
+ public void test_skip() throws IOException {
+ String string = "MY TEST STRING";
+ char[] srcBuffer = string.toCharArray();
+ int length = srcBuffer.length;
+ MockReader mockReader = new MockReader(srcBuffer);
+ assertEquals("Should be equal to \'M\'", 'M', mockReader.read());
+
+ // normal skip
+ mockReader.skip(length / 2);
+ assertEquals("Should be equal to \'S\'", 'S', mockReader.read());
+
+ // try to skip a bigger number of characters than the total
+ // Should do nothing
+ mockReader.skip(length);
+
+ // try to skip a negative number of characters throw IllegalArgumentException
+ try {
+ mockReader.skip(-1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Excepted
+ }
+ }
+
+ class MockReader extends Reader {
+
+ private char[] contents;
+
+ private int current_offset = 0;
+
+ private int length = 0;
+
+ public MockReader() {
+ super();
+ }
+
+ public MockReader(char[] data) {
+ contents = data;
+ length = contents.length;
+ }
+
+ @Override
+ public void close() throws IOException {
+
+ contents = null;
+ }
+
+ @Override
+ public int read(char[] buf, int offset, int count) throws IOException {
+
+ if (null == contents) {
+ return -1;
+ }
+ if (length <= current_offset) {
+ return -1;
+ }
+ if (buf.length < offset + count) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ count = Math.min(count, length - current_offset);
+ for (int i = 0; i < count; i++) {
+ buf[offset + i] = contents[current_offset + i];
+ }
+ current_offset += count;
+ return count;
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SequenceInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SequenceInputStreamTest.java
new file mode 100644
index 0000000..e4608db
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SequenceInputStreamTest.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+
+public class SequenceInputStreamTest extends junit.framework.TestCase {
+
+ SequenceInputStream si;
+
+ String s1 = "Hello";
+
+ String s2 = "World";
+
+ /**
+ * java.io.SequenceInputStream#SequenceInputStream(java.io.InputStream,
+ *java.io.InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_io_InputStream() {
+ // Test for method java.io.SequenceInputStream(java.io.InputStream,
+ // java.io.InputStream)
+ // Used in tests
+ }
+
+ /**
+ * SequenceInputStream#SequenceInputStream(java.io.InputStream,
+ *java.io.InputStream)
+ */
+ public void test_Constructor_LInputStreamLInputStream_Null() throws UnsupportedEncodingException {
+ try {
+ si = new SequenceInputStream(null, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ //will not throw NullPointerException if the first InputStream is not null
+ InputStream is = new ByteArrayInputStream(s1.getBytes("UTF-8"));
+ si = new SequenceInputStream(is, null);
+ }
+
+ /**
+ * java.io.SequenceInputStream#SequenceInputStream(java.util.Enumeration)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_ConstructorLjava_util_Enumeration() {
+ // Test for method java.io.SequenceInputStream(java.util.Enumeration)
+ class StreamEnumerator implements Enumeration {
+ InputStream streams[] = new InputStream[2];
+
+ int count = 0;
+
+ public StreamEnumerator() throws UnsupportedEncodingException {
+ streams[0] = new ByteArrayInputStream(s1.getBytes("UTF-8"));
+ streams[1] = new ByteArrayInputStream(s2.getBytes("UTF-8"));
+ }
+
+ public boolean hasMoreElements() {
+ return count < streams.length;
+ }
+
+ public Object nextElement() {
+ return streams[count++];
+ }
+ }
+
+ try {
+ si = new SequenceInputStream(new StreamEnumerator());
+ byte buf[] = new byte[s1.length() + s2.length()];
+ si.read(buf, 0, s1.length());
+ si.read(buf, s1.length(), s2.length());
+ assertTrue("Read incorrect bytes: " + new String(buf), new String(
+ buf, "UTF-8").equals(s1 + s2));
+ } catch (IOException e) {
+ fail("IOException during read test : " + e.getMessage());
+ }
+
+ }
+
+ /**
+ * java.io.SequenceInputStream#available()
+ */
+ public void test_available() {
+ // Test for method int java.io.SequenceInputStream.available()
+ try {
+
+ assertTrue("Returned incorrect number of bytes: " + si.available(),
+ si.available() == s1.length());
+ } catch (IOException e) {
+ fail("IOException during available test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.SequenceInputStream#close()
+ */
+ public void test_close() throws IOException {
+ si.close();
+ //will not throw IOException to close a stream which is closed already
+ si.close();
+ }
+
+ /**
+ * java.io.SequenceInputStream#read()
+ */
+ public void test_read() throws IOException {
+ // Test for method int java.io.SequenceInputStream.read()
+ try {
+ si.read();
+ assertTrue("Read incorrect char", (char) si.read() == s1.charAt(1));
+ } catch (IOException e) {
+ fail("IOException during read test: " + e.getMessage());
+ }
+
+ //returns -1 if the stream is closed , do not throw IOException
+ si.close();
+ int result = si.read();
+ assertEquals(-1, result);
+ }
+
+ /**
+ * java.io.SequenceInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException {
+ // Test for method int java.io.SequenceInputStream.read(byte [], int,
+ // int)
+ try {
+ byte buf[] = new byte[s1.length() + s2.length()];
+ si.read(buf, 0, s1.length());
+ si.read(buf, s1.length(), s2.length());
+ assertTrue("Read incorrect bytes: " + new String(buf), new String(
+ buf, "UTF-8").equals(s1 + s2));
+ } catch (IOException e) {
+ fail("IOException during read test : " + e.getMessage());
+ }
+
+ ByteArrayInputStream bis1 = new ByteArrayInputStream(
+ new byte[] { 1, 2, 3, 4 });
+ ByteArrayInputStream bis2 = new ByteArrayInputStream(
+ new byte[] { 5, 6, 7, 8 });
+ SequenceInputStream sis = new SequenceInputStream(bis1, bis2);
+
+ try {
+ sis.read(null, 0, -1);
+ fail("Expected NullPointerException exception");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ //returns -1 if the stream is closed , do not throw IOException
+ byte[] array = new byte[] { 1, 2, 3, 4 };
+ sis.close();
+ int result = sis.read(array, 0, 5);
+ assertEquals(-1, result);
+
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() throws UnsupportedEncodingException {
+ si = new SequenceInputStream(new ByteArrayInputStream(s1.getBytes("UTF-8")),
+ new ByteArrayInputStream(s2.getBytes("UTF-8")));
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest.java
new file mode 100644
index 0000000..5d9b18c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest.java
@@ -0,0 +1,1022 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.NotActiveException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.io.StreamCorruptedException;
+import java.io.WriteAbortedException;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.PropertyPermission;
+import java.util.Set;
+import java.util.SimpleTimeZone;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TimeZone;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+import libcore.io.Streams;
+
+/**
+ * Automated Test Suite for class java.io.ObjectOutputStream
+ */
+@SuppressWarnings("serial")
+public class SerializationStressTest extends junit.framework.TestCase implements
+ Serializable {
+
+ // protected static final String MODE_XLOAD = "xload";
+
+ // protected static final String MODE_XDUMP = "xdump";
+
+ static final String FOO = "foo";
+
+ static final String MSG_TEST_FAILED = "Failed to write/read/assertion checking: ";
+
+ protected static final boolean DEBUG = false;
+
+ protected static boolean xload = false;
+
+ protected static boolean xdump = false;
+
+ protected static String xFileName = null;
+
+ protected transient int dumpCount = 0;
+
+ protected transient ObjectInputStream ois;
+
+ protected transient ObjectOutputStream oos;
+
+ protected transient ByteArrayOutputStream bao;
+
+ // -----------------------------------------------------------------------------------
+
+ private static class ObjectInputStreamSubclass extends ObjectInputStream {
+ private Vector<Class> resolvedClasses = new Vector<Class>();
+
+ public ObjectInputStreamSubclass(InputStream in) throws IOException,
+ StreamCorruptedException {
+ super(in);
+ }
+
+ public Class<?> resolveClass(ObjectStreamClass osClass)
+ throws IOException, ClassNotFoundException {
+ Class result = super.resolveClass(osClass);
+ resolvedClasses.addElement(result);
+ return result;
+ }
+
+ public Class[] resolvedClasses() {
+ return (Class[]) resolvedClasses.toArray(new Class[resolvedClasses
+ .size()]);
+ }
+ }
+
+ static final Map<String, String> TABLE = new Hashtable<String, String>();
+
+ static final Map<String, String> MAP = new HashMap<String, String>();
+
+ static final SortedMap<String, String> TREE = new TreeMap<String, String>();
+
+ static final LinkedHashMap<String, String> LINKEDMAP = new LinkedHashMap<String, String>();
+
+ static final LinkedHashSet<String> LINKEDSET = new LinkedHashSet<String>();
+
+ static final IdentityHashMap<String, String> IDENTITYMAP = new IdentityHashMap<String, String>();
+
+ static final List<String> ALIST = Arrays.asList(new String[] { "a", "list", "of",
+ "strings" });
+
+ static final List<String> LIST = new ArrayList<String>(ALIST);
+
+ static final Set<String> SET = new HashSet<String>(Arrays.asList(new String[] { "one",
+ "two", "three" }));
+
+ static final SortedSet<String> SORTSET = new TreeSet<String>(Arrays.asList(new String[] {
+ "one", "two", "three" }));
+
+ static final java.text.DateFormat DATEFORM = java.text.DateFormat
+ .getInstance();
+
+ static final java.text.ChoiceFormat CHOICE = new java.text.ChoiceFormat(
+ "1#one|2#two|3#three");
+
+ static final java.text.NumberFormat NUMBERFORM = java.text.NumberFormat
+ .getInstance();
+
+ static final java.text.MessageFormat MESSAGE = new java.text.MessageFormat(
+ "the time: {0,time} and date {0,date}");
+
+ static final LinkedList<String> LINKEDLIST = new LinkedList<String>(Arrays
+ .asList(new String[] { "a", "linked", "list", "of", "strings" }));
+
+ static final SimpleTimeZone TIME_ZONE = new SimpleTimeZone(3600000,
+ "S-TEST");
+
+ static final Calendar CALENDAR = new GregorianCalendar(TIME_ZONE);
+
+ static {
+ TABLE.put("one", "1");
+ TABLE.put("two", "2");
+ TABLE.put("three", "3");
+ MAP.put("one", "1");
+ MAP.put("two", "2");
+ MAP.put("three", "3");
+ LINKEDMAP.put("one", "1");
+ LINKEDMAP.put("two", "2");
+ LINKEDMAP.put("three", "3");
+ IDENTITYMAP.put("one", "1");
+ IDENTITYMAP.put("two", "2");
+ IDENTITYMAP.put("three", "3");
+ LINKEDSET.add("one");
+ LINKEDSET.add("two");
+ LINKEDSET.add("three");
+ TREE.put("one", "1");
+ TREE.put("two", "2");
+ TREE.put("three", "3");
+ // To make sure they all use the same Calendar
+ CALENDAR.setTimeZone(new SimpleTimeZone(0, "GMT"));
+ CALENDAR.set(1999, Calendar.JUNE, 23, 15, 47, 13);
+ CALENDAR.set(Calendar.MILLISECOND, 553);
+ DATEFORM.setCalendar(CALENDAR);
+ java.text.DateFormatSymbols symbols = new java.text.DateFormatSymbols();
+ symbols.setZoneStrings(new String[][] { { "a", "b", "c", "d", "e" },
+ { "f", "g", "h", "i", "j" } });
+ ((java.text.SimpleDateFormat) DATEFORM).setDateFormatSymbols(symbols);
+ DATEFORM.setNumberFormat(new java.text.DecimalFormat("#0.#"));
+ DATEFORM.setTimeZone(TimeZone.getTimeZone("EST"));
+ ((java.text.DecimalFormat) NUMBERFORM).applyPattern("#0.#");
+ MESSAGE.setFormat(0, DATEFORM);
+ MESSAGE.setFormat(1, DATEFORM);
+ }
+
+ public SerializationStressTest() {
+ }
+
+ public SerializationStressTest(String name) {
+ super(name);
+ }
+
+ public String getDumpName() {
+ return getName() + dumpCount;
+ }
+
+ protected void dump(Object o) throws IOException, ClassNotFoundException {
+ if (dumpCount > 0)
+ setUp();
+ // Dump the object
+ try {
+ oos.writeObject(o);
+ } finally {
+ oos.close();
+ }
+ }
+
+ protected Object dumpAndReload(Object o) throws IOException,
+ ClassNotFoundException {
+ dump(o);
+ return reload();
+ }
+
+ protected InputStream loadStream() throws IOException {
+ // Choose the load stream
+ if (xload || xdump) {
+ // Load from pre-existing file
+ return new FileInputStream(xFileName + "-" + getDumpName() + ".ser");
+ } else {
+ // Just load from memory, we dumped to memory
+ return new ByteArrayInputStream(bao.toByteArray());
+ }
+ }
+
+ protected Object reload() throws IOException, ClassNotFoundException {
+ ois = new ObjectInputStream(loadStream());
+ dumpCount++;
+ try {
+ return ois.readObject();
+ } finally {
+ ois.close();
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ try {
+ if (xdump) {
+ oos = new ObjectOutputStream(new FileOutputStream(xFileName
+ + "-" + getDumpName() + ".ser"));
+ } else {
+ oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+ }
+ } catch (Exception e) {
+ fail("Exception thrown during setup : " + e.getMessage());
+ }
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ if (oos != null) {
+ try {
+ oos.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ public void test_1_Constructor() throws Exception {
+ // Test for method java.io.ObjectOutputStream(java.io.OutputStream)
+ oos.close();
+ oos = new ObjectOutputStream(new ByteArrayOutputStream());
+ oos.close();
+ }
+
+ public void test_2_close() {
+ // Test for method void java.io.ObjectOutputStream.close()
+ try {
+ oos.close();
+ oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+ oos.close();
+ oos.writeChar('T');
+ oos.writeObject(FOO);
+ // Writing to a closed stream does not cause problems. This is
+ // the expected behavior
+ } catch (IOException e) {
+ fail("Operation on closed stream threw IOException : "
+ + e.getMessage());
+ }
+ }
+
+ public void test_3_defaultWriteObject() {
+ // Test for method void java.io.ObjectOutputStream.defaultWriteObject()
+
+ try {
+ oos.defaultWriteObject();
+ } catch (NotActiveException e) {
+ // Correct
+ return;
+ } catch (IOException e) {
+ }
+ fail(
+ "Failed to throw NotActiveException when invoked outside readObject");
+ }
+
+ public void test_4_flush() {
+ // Test for method void java.io.ObjectOutputStream.flush()
+ try {
+ oos.close();
+ oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+ int size = bao.size();
+ oos.writeByte(127);
+ assertTrue("Data flushed already", bao.size() == size);
+ oos.flush();
+ assertTrue("Failed to flush data", bao.size() > size);
+ // we don't know how many bytes are actually written for 1 byte,
+ // so we test > <before>
+ oos.close();
+ oos = null;
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_5_reset() {
+ // Test for method void java.io.ObjectOutputStream.reset()
+ try {
+ String o = "HelloWorld";
+ oos.writeObject(o);
+ oos.writeObject(o);
+ oos.reset();
+ oos.writeObject(o);
+ ois = new ObjectInputStream(loadStream());
+ ois.close();
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_6_write() {
+ // Test for method void java.io.ObjectOutputStream.write(byte [], int,
+ // int)
+ try {
+ byte[] buf = new byte[255];
+ byte[] output = new byte[255];
+ for (int i = 0; i < output.length; i++)
+ output[i] = (byte) i;
+ oos.write(output, 0, output.length);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ ois.readFully(buf);
+ ois.close();
+ for (int i = 0; i < output.length; i++)
+ if (buf[i] != output[i])
+ fail("Read incorrect byte: " + i);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_6a_write() {
+ // Test for method void java.io.ObjectOutputStream.write(byte [], int,
+ // int)
+ try {
+ byte[] buf = new byte[256];
+ byte[] output = new byte[256];
+ for (int i = 0; i < output.length; i++)
+ output[i] = (byte) (i & 0xff);
+ oos.write(output, 0, output.length);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ ois.readFully(buf);
+ ois.close();
+ for (int i = 0; i < output.length; i++)
+ if (buf[i] != output[i])
+ fail("Read incorrect byte: " + i);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_7_write() {
+ // Test for method void java.io.ObjectOutputStream.write(int)
+ try {
+ oos.write('T');
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Read incorrect byte", 'T', ois.read());
+ ois.close();
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_8_write() {
+ // Test for method void java.io.ObjectOutputStream.write(byte [])
+ try {
+ byte[] buf = new byte[10];
+ oos.write("HelloWorld".getBytes());
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ ois.read(buf, 0, 10);
+ ois.close();
+ assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 10)
+ );
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_9_writeBoolean() {
+ // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean)
+ try {
+ oos.writeBoolean(true);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect byte value", ois.readBoolean());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_10_writeByte() {
+ // Test for method void java.io.ObjectOutputStream.writeByte(int)
+ try {
+ oos.writeByte(127);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Wrote incorrect byte value", 127, ois.readByte());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_11_writeBytes() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeBytes(java.lang.String)
+ try {
+ byte[] buf = new byte[10];
+ oos.writeBytes("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ ois.readFully(buf);
+ ois.close();
+ assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(buf, 0, 10, "UTF-8")
+ );
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_12_writeChar() {
+ // Test for method void java.io.ObjectOutputStream.writeChar(int)
+ try {
+ oos.writeChar('T');
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Wrote incorrect char value", 'T', ois.readChar());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_13_writeChars() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeChars(java.lang.String)
+ try {
+ int avail = 0;
+ char[] buf = new char[10];
+ oos.writeChars("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ // Number of prim data bytes in stream / 2 to give char index
+ avail = ois.available() / 2;
+ for (int i = 0; i < avail; ++i)
+ buf[i] = ois.readChar();
+ ois.close();
+ assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0, 10)
+ );
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_14_writeDouble() {
+ // Test for method void java.io.ObjectOutputStream.writeDouble(double)
+ try {
+ oos.writeDouble(Double.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect double value",
+ ois.readDouble() == Double.MAX_VALUE);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_15_writeFloat() {
+ // Test for method void java.io.ObjectOutputStream.writeFloat(float)
+ try {
+ oos.writeFloat(Float.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect double value",
+ ois.readFloat() == Float.MAX_VALUE);
+ ois.close();
+ ois = null;
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_16_writeInt() {
+ // Test for method void java.io.ObjectOutputStream.writeInt(int)
+ try {
+ oos.writeInt(Integer.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect double value",
+ ois.readInt() == Integer.MAX_VALUE);
+ ois.close();
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_17_writeLong() {
+ // Test for method void java.io.ObjectOutputStream.writeLong(long)
+ try {
+ oos.writeLong(Long.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect double value",
+ ois.readLong() == Long.MAX_VALUE);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_19_writeShort() {
+ // Test for method void java.io.ObjectOutputStream.writeShort(int)
+ try {
+ oos.writeShort(127);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Wrote incorrect short value", 127, ois.readShort());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_20_writeUTF() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeUTF(java.lang.String)
+ try {
+ oos.writeUTF("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Wrote incorrect UTF value",
+ "HelloWorld", ois.readUTF());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_25_available() {
+ try {
+ oos.writeObject(FOO);
+ oos.writeObject(FOO);
+ oos.flush();
+ int available1 = 0;
+ int available2 = 0;
+ Object obj1 = null;
+ Object obj2 = null;
+ ObjectInputStream ois = new ObjectInputStream(loadStream());
+ available1 = ois.available();
+ obj1 = ois.readObject();
+ available2 = ois.available();
+ obj2 = ois.readObject();
+
+ assertEquals("available returned incorrect value", 0, available1);
+ assertEquals("available returned incorrect value", 0, available2);
+
+ assertTrue("available caused incorrect reading", FOO.equals(obj1));
+ assertTrue("available returned incorrect value", FOO.equals(obj2));
+
+ } catch (IOException e) {
+ fail("IOException serializing object : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("Unable to read Object type : " + e.toString());
+ } catch (Error err) {
+ System.out.println("Error " + err);
+ throw err;
+ }
+
+ }
+
+ protected void t_MixPrimitivesAndObjects() throws IOException,
+ ClassNotFoundException {
+ int i = 7;
+ String s1 = "string 1";
+ String s2 = "string 2";
+ byte[] bytes = { 1, 2, 3 };
+
+ oos.writeInt(i);
+ oos.writeObject(s1);
+ oos.writeUTF(s2);
+ oos.writeObject(bytes);
+ oos.close();
+ try {
+ ois = new ObjectInputStream(loadStream());
+
+ int j = ois.readInt();
+ assertTrue("Wrong int :" + j, i == j);
+
+ String l1 = (String) ois.readObject();
+ assertTrue("Wrong obj String :" + l1, s1.equals(l1));
+
+ String l2 = (String) ois.readUTF();
+ assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
+
+ byte[] bytes2 = (byte[]) ois.readObject();
+ assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
+
+ } finally {
+ ois.close();
+ }
+ }
+
+ public void test_resolveClass() {
+ try {
+ oos.writeObject(new Object[] { Integer.class, new Integer(1) });
+ oos.close();
+
+ ois = new ObjectInputStreamSubclass(loadStream());
+ ois.readObject();
+ ois.close();
+ } catch (IOException e1) {
+ fail("IOException : " + e1.getMessage());
+ } catch (ClassNotFoundException e2) {
+ fail("ClassNotFoundException : " + e2.getMessage());
+ }
+
+ Class[] resolvedClasses = ((ObjectInputStreamSubclass) ois)
+ .resolvedClasses();
+ assertEquals("missing resolved", 3, resolvedClasses.length);
+ assertTrue("resolved class 1", resolvedClasses[0] == Object[].class);
+ assertTrue("resolved class 2", resolvedClasses[1] == Integer.class);
+ assertTrue("resolved class 3", resolvedClasses[2] == Number.class);
+ }
+
+ public void test_reset() throws IOException, ClassNotFoundException {
+ oos.reset();
+ oos.writeObject("R");
+ oos.reset();
+ oos.writeByte(24);
+ oos.close();
+
+ DataInputStream dis = new DataInputStream(loadStream());
+ byte[] input = Streams.readFully(dis);
+ byte[] result = new byte[] { (byte) 0xac, (byte) 0xed, (byte) 0,
+ (byte) 5, (byte) 0x79, (byte) 0x74, (byte) 0, (byte) 1,
+ (byte) 'R', (byte) 0x79, (byte) 0x77, (byte) 1, (byte) 24 };
+ assertTrue("incorrect output", Arrays.equals(input, result));
+
+ ois = new ObjectInputStreamSubclass(loadStream());
+ assertEquals("Wrong result from readObject()", "R", ois.readObject());
+ assertEquals("Wrong result from readByte()", 24, ois.readByte());
+ ois.close();
+ }
+
+ private static class ResolveObjectTest implements Serializable {
+ Object field1, field2;
+ }
+
+ private static class ResolveObjectInputStream extends ObjectInputStream {
+ ResolveObjectInputStream(InputStream in)
+ throws StreamCorruptedException, IOException {
+ super(in);
+ }
+
+ public void enableResolve() {
+ enableResolveObject(true);
+ }
+
+ public Object resolveObject(Object obj) {
+ if (obj instanceof Vector) // test_1_resolveObject()
+ return new Hashtable();
+ else if ("abc".equals(obj)) // test_2_resolveObject()
+ return "ABC";
+ else if (obj instanceof String) // test_3_resolveObject()
+ return String.valueOf(((String) obj).length());
+ else if (obj instanceof int[]) // test_4_resolveObject()
+ return new Object[1];
+ else if (obj instanceof Object[] && ((Object[]) obj).length == 2) // test_5_resolveObject()
+ return new char[1];
+ return obj;
+ }
+ }
+
+ public void test_1_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ obj.field1 = new Vector();
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ assertTrue("Object not resolved",
+ result.field1 instanceof Hashtable);
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_2_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ obj.field1 = "abc";
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ assertEquals("String not resolved", "ABC", result.field1);
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_3_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ char[] lchars = new char[70000];
+ obj.field1 = new String(lchars);
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ assertTrue("Long String not resolved", "70000"
+ .equals(result.field1));
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_4_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ obj.field1 = new int[5];
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ Class cl = new Object[0].getClass();
+ assertTrue("int[] not resolved", result.field1.getClass() == cl);
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_5_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ obj.field1 = new Object[2];
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ Class cl = new char[0].getClass();
+ assertTrue("int[] not resolved", result.field1.getClass() == cl);
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ static class WriteReplaceTestA implements Serializable {
+ public Object writeReplace() throws ObjectStreamException {
+ return new ReadResolveTestB();
+ }
+ }
+
+ static class WriteReplaceTestB extends WriteReplaceTestA {
+ }
+
+ static class WriteReplaceTestC extends WriteReplaceTestA {
+ public Object writeReplace() throws ObjectStreamException {
+ return new ReadResolveTestC();
+ }
+ }
+
+ static class WriteReplaceTestD implements Serializable {
+ private Object writeReplace() throws ObjectStreamException {
+ return new ReadResolveTestD();
+ }
+ }
+
+ static class WriteReplaceTestE extends WriteReplaceTestD {
+ }
+
+ static class WriteReplaceTestF implements Serializable {
+ int type, readType;
+
+ public WriteReplaceTestF(int type, int readType) {
+ this.type = type;
+ this.readType = readType;
+ }
+
+ public Object writeReplace() throws ObjectStreamException {
+ switch (type) {
+ case 0:
+ throw new InvalidObjectException("invalid");
+ case 1:
+ throw new RuntimeException("runtime");
+ case 2:
+ throw new Error("error");
+ default:
+ return new ReadResolveTestE(readType);
+ }
+ }
+ }
+
+ static class ReadResolveTestA implements Serializable {
+ public Object readResolve() throws ObjectStreamException {
+ return new ReadResolveTestA();
+ }
+ }
+
+ static class ReadResolveTestB extends ReadResolveTestA {
+ }
+
+ static class ReadResolveTestC implements Serializable {
+ private Object readResolve() throws ObjectStreamException {
+ return new ReadResolveTestB();
+ }
+ }
+
+ static class ReadResolveTestD extends ReadResolveTestC {
+ }
+
+ static class ReadResolveTestE implements Serializable {
+ int type;
+
+ public ReadResolveTestE(int type) {
+ this.type = type;
+ }
+
+ public Object readResolve() throws ObjectStreamException {
+ switch (type) {
+ case 0:
+ throw new InvalidObjectException("invalid");
+ case 1:
+ throw new RuntimeException("runtime");
+ case 2:
+ throw new Error("error");
+ case 3:
+ return this;
+ default:
+ return new ReadResolveTestF();
+ }
+ }
+ }
+
+ static class ReadResolveTestF implements Serializable {
+ }
+
+ public void test_1_writeReplace() {
+ try {
+ Vector<Object> v = new Vector<Object>();
+ v.addElement(new WriteReplaceTestA());
+ v.addElement(new WriteReplaceTestB());
+ v.addElement(new WriteReplaceTestB());
+ v.addElement(new WriteReplaceTestC());
+ v.addElement(new WriteReplaceTestD());
+ v.addElement(new WriteReplaceTestE());
+ oos.writeObject(v);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ Vector result = (Vector) ois.readObject();
+ assertTrue("invalid 0 : " + result.elementAt(0), result
+ .elementAt(0).getClass() == ReadResolveTestA.class);
+ assertTrue("invalid 1 : " + result.elementAt(1), result
+ .elementAt(1).getClass() == ReadResolveTestA.class);
+ assertTrue("invalid 2 : " + result.elementAt(2), result
+ .elementAt(2).getClass() == ReadResolveTestA.class);
+ assertTrue("invalid 3 : " + result.elementAt(3), result
+ .elementAt(3).getClass() == ReadResolveTestB.class);
+ assertTrue("invalid 4 : " + result.elementAt(4), result
+ .elementAt(4).getClass() == ReadResolveTestD.class);
+ assertTrue("invalid 5 : " + result.elementAt(5), result
+ .elementAt(5).getClass() == WriteReplaceTestE.class);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException serializing data : " + e.getMessage());
+ }
+ }
+
+ public void test_2_writeReplace() {
+ try {
+ boolean exception = false;
+ try {
+ oos.writeObject(new WriteReplaceTestF(0, -1));
+ } catch (ObjectStreamException e) {
+ exception = true;
+ }
+ assertTrue("Should throw ObjectStreamException", exception);
+ exception = false;
+ try {
+ oos.writeObject(new WriteReplaceTestF(1, -1));
+ } catch (RuntimeException e) {
+ exception = true;
+ }
+ assertTrue("Should throw RuntimeException", exception);
+ exception = false;
+ try {
+ oos.writeObject(new WriteReplaceTestF(2, -1));
+ } catch (Error e) {
+ exception = true;
+ }
+ assertTrue("Should throw Error", exception);
+
+ oos.writeObject(new WriteReplaceTestF(3, 0));
+ oos.writeObject(new WriteReplaceTestF(3, 1));
+ oos.writeObject(new WriteReplaceTestF(3, 2));
+ WriteReplaceTestF test = new WriteReplaceTestF(3, 3);
+ oos.writeObject(test);
+ oos.writeObject(test);
+ WriteReplaceTestF test2 = new WriteReplaceTestF(3, 4);
+ oos.writeObject(test2);
+ oos.writeObject(test2);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ try {
+ ois.readObject();
+ } catch (WriteAbortedException e) {
+ }
+
+ exception = false;
+ try {
+ ois.readObject();
+ } catch (ObjectStreamException e) {
+ exception = true;
+ }
+ assertTrue("Expected ObjectStreamException", exception);
+ exception = false;
+ try {
+ ois.readObject();
+ } catch (RuntimeException e) {
+ exception = true;
+ }
+ assertTrue("Expected RuntimeException", exception);
+ exception = false;
+ try {
+ ois.readObject();
+ } catch (Error e) {
+ exception = true;
+ }
+ assertTrue("Expected Error", exception);
+
+ Object readE1 = ois.readObject();
+ Object readE2 = ois.readObject();
+ assertTrue("Replaced objects should be identical", readE1 == readE2);
+ Object readF1 = ois.readObject();
+ Object readF2 = ois.readObject();
+ assertTrue("Replaced resolved objects should be identical: "
+ + readF1 + " " + readF2, readF1 == readF2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException serializing data : " + e.getMessage());
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest1.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest1.java
new file mode 100644
index 0000000..27d8b33
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest1.java
@@ -0,0 +1,1657 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Vector;
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest1 extends SerializationStressTest {
+
+ // The purpose of these two classes is to test if serialization, when
+ // loading, runs the object's constructor (wrong) or the constructor defined
+ // at the topmost Serializable superclass(correct).
+ static final int INIT_INT_VALUE = 7;
+
+ // HAS to be static class so that our constructor signature will remain
+ // untouched (no synthetic param)
+ private static class SerializationTest implements java.io.Serializable {
+ int anInt = INIT_INT_VALUE;
+
+ public SerializationTest() {
+ super();
+ }
+ }
+
+ static final String INIT_STR_VALUE = "a string that is blortz";
+
+ // HAS to be static class so that our constructor signature will remain
+ // untouched (no synthetic param)
+ private static class SerializationTestSubclass1 extends SerializationTest {
+ String aString = INIT_STR_VALUE;
+
+ public SerializationTestSubclass1() {
+ super();
+ // Just to change default superclass init value
+ anInt = INIT_INT_VALUE / 2;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+
+ private static class SpecTestSuperClass implements Runnable {
+ protected java.lang.String instVar;
+
+ public SpecTestSuperClass() {
+ }
+
+ public void run() {
+ }
+ }
+
+ private static class SpecTest extends SpecTestSuperClass implements
+ Cloneable, Serializable {
+ public java.lang.String instVar1;
+
+ public static java.lang.String staticVar1;
+
+ public static java.lang.String staticVar2;
+
+ {
+ instVar1 = "NonStaticInitialValue";
+ }
+
+ static {
+ staticVar1 = "StaticInitialValue";
+ staticVar1 = new String(staticVar1);
+ }
+
+ public Object method(Object objParam, Object objParam2) {
+ return new Object();
+ }
+
+ public boolean method(boolean bParam, Object objParam) {
+ return true;
+ }
+
+ public boolean method(boolean bParam, Object objParam, Object objParam2) {
+ return true;
+ }
+
+ }
+
+ private static class SpecTestSubclass extends SpecTest {
+ public transient java.lang.String transientInstVar = "transientValue";
+ }
+
+ // -----------------------------------------------------------------------------------
+
+ // This one tests what happens if the read/writeObject methods are defined
+ // Serialization should work fine.
+ private static class ReadWriteObject implements java.io.Serializable {
+ public boolean calledWriteObject = false;
+
+ public boolean calledReadObject = false;
+
+ public ReadWriteObject() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ calledReadObject = true;
+ in.readObject();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
+ calledWriteObject = true;
+ out.writeObject(FOO);
+ }
+ }
+
+ // This one tests what happens if the read/writeObject methods are not
+ // private.
+ // Serialization should fail.
+ private static class PublicReadWriteObject implements java.io.Serializable {
+ public boolean calledWriteObject = false;
+
+ public boolean calledReadObject = false;
+
+ public PublicReadWriteObject() {
+ super();
+ }
+
+ public void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ calledReadObject = true;
+ in.readObject();
+ }
+
+ public void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
+ calledWriteObject = true;
+ out.writeObject(FOO);
+ }
+ }
+
+ // This one tests if field names are serialized in the same way (sorting)
+ // across different VMs
+ private static class FieldOrder implements Serializable {
+ String aaa1NonPrimitive = "aaa1";
+
+ int bbb1PrimitiveInt = 5;
+
+ boolean aaa2PrimitiveBoolean = true;
+
+ String bbb2NonPrimitive = "bbb2";
+ }
+
+ // This one tests what happens if you define just readObject, but not
+ // writeObject.
+ // Does it run or not ?
+ private static class JustReadObject implements java.io.Serializable {
+ public boolean calledReadObject = false;
+
+ public JustReadObject() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ calledReadObject = true;
+ in.defaultReadObject();
+ }
+ }
+
+ // This one tests what happens if you define just writeObject, but not
+ // readObject.
+ // Does it run or not ?
+ private static class JustWriteObject implements java.io.Serializable {
+ public boolean calledWriteObject = false;
+
+ public JustWriteObject() {
+ super();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ calledWriteObject = true;
+ out.defaultWriteObject();
+ }
+ }
+
+ // This one tests class-based replacement when dumping
+ private static class ClassBasedReplacementWhenDumping implements
+ java.io.Serializable {
+ public boolean calledReplacement = false;
+
+ public ClassBasedReplacementWhenDumping() {
+ super();
+ }
+
+ private Object writeReplace() {
+ calledReplacement = true;
+ return FOO; // Replacement is a String
+ }
+ }
+
+ // This one tests whether class-based replacement supports multiple levels.
+ // MultipleClassBasedReplacementWhenDumping -> C1 -> C2 -> C3 -> FOO
+ private static class MultipleClassBasedReplacementWhenDumping implements
+ java.io.Serializable {
+ private static class C1 implements java.io.Serializable {
+ private Object writeReplace() {
+ return new C2();
+ }
+ }
+
+ private static class C2 implements java.io.Serializable {
+ private Object writeReplace() {
+ return new C3();
+ }
+ }
+
+ private static class C3 implements java.io.Serializable {
+ private Object writeReplace() {
+ return FOO;
+ }
+ }
+
+ public MultipleClassBasedReplacementWhenDumping() {
+ super();
+ }
+
+ private Object writeReplace() {
+ return new C1();
+ }
+ }
+
+ // This one tests class-based replacement when loading
+ private static class ClassBasedReplacementWhenLoading implements
+ java.io.Serializable {
+ public ClassBasedReplacementWhenLoading() {
+ super();
+ }
+
+ private Object readResolve() {
+ return FOO; // Replacement is a String
+ }
+ }
+
+ // This one tests what happens if a loading-replacement is not
+ // type-compatible with the original object
+ private static class ClassBasedReplacementWhenLoadingViolatesFieldType
+ implements java.io.Serializable {
+ public ClassBasedReplacementWhenLoading classBasedReplacementWhenLoading = new ClassBasedReplacementWhenLoading();
+
+ public ClassBasedReplacementWhenLoadingViolatesFieldType() {
+ super();
+ }
+ }
+
+ // What happens if dumping causes an error and you try to reload ?
+ // Should the load throw the same exception ?
+ private static class MyExceptionWhenDumping1 implements
+ java.io.Serializable {
+ private static class MyException extends java.io.IOException {
+ }
+
+ // A primitive instance variable exposes a bug in the serialization
+ // spec.
+ // Primitive instance variables are written without primitive data tags
+ // and so are read without checking for tags. If an exception is
+ // written, reading primitive data will just read bytes from the stream
+ // which may be tags
+ public boolean anInstanceVar = false;
+
+ public MyExceptionWhenDumping1() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ throw new MyException();
+ }
+ }
+
+ // What happens if dumping causes an error and you try to reload ?
+ // Should the load throw the same exception ?
+ private static class MyExceptionWhenDumping2 implements
+ java.io.Serializable {
+ private static class MyException extends java.io.IOException {
+ }
+
+ ;
+
+ public Integer anInstanceVar = new Integer(0xA1);
+
+ public MyExceptionWhenDumping2() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ throw new MyException();
+ }
+ }
+
+ // What happens if dumping causes an error (NonSerializable inst var) and
+ // you try to reload ?
+ // Should the load throw the same exception ?
+ private static class NonSerializableExceptionWhenDumping implements
+ java.io.Serializable {
+ public Object anInstanceVar = new Object();
+
+ public NonSerializableExceptionWhenDumping() {
+ super();
+ }
+ }
+
+ // What happens if dumping causes an error (which is not serializable) and
+ // you try to reload ?
+ // Should the load throw the same exception ?
+ private static class MyUnserializableExceptionWhenDumping implements
+ java.io.Serializable {
+ private static class MyException extends java.io.IOException {
+ private Object notSerializable = new Object();
+ }
+
+ public boolean anInstanceVar = false;
+
+ public MyUnserializableExceptionWhenDumping() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ throw new MyException();
+ }
+ }
+
+ public SerializationStressTest1(String name) {
+ super(name);
+ }
+
+ public void test_18_1_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = "HelloWorld";
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, (((String) objLoaded)
+ .equals((String) objToSave)));
+
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_2_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = null;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, objLoaded == objToSave);
+
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_3_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ byte[] bytes = { 0, 1, 2, 3 };
+ objToSave = bytes;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (byte[]) objLoaded, (byte[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_4_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ int[] ints = { 0, 1, 2, 3 };
+ objToSave = ints;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (int[]) objLoaded, (int[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_18_5_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ short[] shorts = { 0, 1, 2, 3 };
+ objToSave = shorts;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (short[]) objLoaded, (short[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_6_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ long[] longs = { 0, 1, 2, 3 };
+ objToSave = longs;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (long[]) objLoaded, (long[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_7_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ float[] floats = { 0.0f, 1.1f, 2.2f, 3.3f };
+ objToSave = floats;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (float[]) objLoaded, (float[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing data: " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_8_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ double[] doubles = { 0.0, 1.1, 2.2, 3.3 };
+ objToSave = doubles;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (double[]) objLoaded, (double[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_9_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ boolean[] booleans = { true, false, false, true };
+ objToSave = booleans;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (boolean[]) objLoaded, (boolean[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : " + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_10_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ String[] strings = { "foo", "bar", "java" };
+ objToSave = strings;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (Object[]) objLoaded, (Object[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("Unable to read Object type: " + e.toString());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_11_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ objToSave = new Object(); // Not serializable
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ boolean passed = false;
+ Throwable t = null;
+ try {
+ objLoaded = dumpAndReload(objToSave);
+ } catch (NotSerializableException ns) {
+ passed = true;
+ t = ns;
+ } catch (Exception wrongExc) {
+ passed = false;
+ t = wrongExc;
+ }
+ assertTrue(
+ "Failed to throw NotSerializableException when serializing "
+ + objToSave + " Threw(if non-null) this: " + t,
+ passed);
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_12_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ try {
+ if (DEBUG)
+ System.out.println("Obj = <mixed>");
+ t_MixPrimitivesAndObjects();
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when dumping mixed types");
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_13_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SerializationTestSubclass1 st = new SerializationTestSubclass1();
+ // Just change the default ivar values
+ st.anInt = Integer.MAX_VALUE;
+ st.aString = FOO;
+ objToSave = st;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // non-serializable inst var has to be initialized from top
+ // constructor
+ assertTrue(
+ MSG_TEST_FAILED + objToSave,
+ ((SerializationTestSubclass1) objLoaded).anInt == Integer.MAX_VALUE);
+ // but serialized var has to be restored as it was in the object
+ // when dumped
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ ((SerializationTestSubclass1) objLoaded).aString
+ .equals(FOO));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_14_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SpecTest specTest = new SpecTest();
+ // Just change the default ivar values
+ specTest.instVar = FOO;
+ specTest.instVar1 = specTest.instVar;
+ objToSave = specTest;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // non-serializable inst var has to be initialized from top
+ // constructor
+ assertNull(MSG_TEST_FAILED + objToSave,
+ ((SpecTest) objLoaded).instVar);
+ // instVar from non-serialized class, cant be saved/restored
+ // by serialization but serialized ivar has to be restored as it
+ // was in the object when dumped
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ ((SpecTest) objLoaded).instVar1.equals(FOO));
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_15_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SpecTestSubclass specTestSubclass = new SpecTestSubclass();
+ // Just change the default ivar values
+ specTestSubclass.transientInstVar = FOO;
+ objToSave = specTestSubclass;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // non-serializable inst var cant be saved, and it is not init'ed
+ // from top constructor in this case
+ assertNull(MSG_TEST_FAILED + objToSave,
+ ((SpecTestSubclass) objLoaded).transientInstVar);
+ // transient slot, cant be saved/restored by serialization
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_16_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ String[] strings = new String[2];
+ strings[0] = FOO;
+ strings[1] = (" " + FOO + " ").trim(); // Safe way to get a copy
+ // that is not ==
+ objToSave = strings;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ String[] stringsLoaded = (String[]) objLoaded;
+ // Serialization has to use identity-based table for assigning IDs
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ !(stringsLoaded[0] == stringsLoaded[1]));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_17_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ ReadWriteObject readWrite = new ReadWriteObject();
+ objToSave = readWrite;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // has to have called the writeObject on the instance to dump
+ assertTrue(MSG_TEST_FAILED + objToSave, readWrite.calledWriteObject);
+ // has to have called the readObject on the instance loaded
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ ((ReadWriteObject) objLoaded).calledReadObject);
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_18_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ PublicReadWriteObject publicReadWrite = new PublicReadWriteObject();
+ objToSave = publicReadWrite;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Can't have called the writeObject on the instance to dump
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ !publicReadWrite.calledWriteObject);
+ // Can't have called the readObject on the instance loaded
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ !((PublicReadWriteObject) objLoaded).calledReadObject);
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_19_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ FieldOrder fieldOrder = new FieldOrder();
+ objToSave = fieldOrder;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // This test is only useful for X-loading, so if it managed to
+ // dump&load, we passed the test
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_20_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = Class.forName("java.lang.Integer");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Classes with the same name are unique, so test for ==
+ assertTrue(MSG_TEST_FAILED + objToSave, objLoaded == objToSave);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_21_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ // Even though instances of java.lang.Object are not Serializable,
+ // instances of java.lang.Class are. So, the object
+ // java.lang.Object.class
+ // should be serializable
+ objToSave = Class.forName("java.lang.Object");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Classes with the same name are unique, so test for ==
+ assertTrue(MSG_TEST_FAILED + objToSave, objLoaded == objToSave);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_22_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ java.net.URL url = new java.net.URL("http://localhost/a.txt");
+ objToSave = url;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue("URLs are not the same: " + url + "\t,\t" + objLoaded,
+ url.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_23_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ JustReadObject justReadObject = new JustReadObject();
+ objToSave = justReadObject;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Only calls readObject on the instance loaded if writeObject was
+ // also defined
+ assertTrue("Called readObject on an object without a writeObject",
+ !((JustReadObject) objLoaded).calledReadObject);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_24_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ JustWriteObject justWriteObject = new JustWriteObject();
+ objToSave = justWriteObject;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Call writeObject on the instance even if it does not define
+ // readObject
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ justWriteObject.calledWriteObject);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_25_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Vector<String> vector = new Vector<String>(1);
+ vector.add(FOO);
+ objToSave = vector;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have the string there
+ assertTrue(MSG_TEST_FAILED + objToSave, FOO
+ .equals(((java.util.Vector) objLoaded).elementAt(0)));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_18_26_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Hashtable<String, String> hashTable = new Hashtable<String, String>(
+ 5);
+ hashTable.put(FOO, FOO);
+ objToSave = hashTable;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ java.util.Hashtable loadedHashTable = (java.util.Hashtable) objLoaded;
+ // Has to have the key/value there (FOO -> FOO)
+ assertTrue(MSG_TEST_FAILED + objToSave, FOO.equals(loadedHashTable
+ .get(FOO)));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_18_27_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ClassBasedReplacementWhenDumping classBasedReplacementWhenDumping = new ClassBasedReplacementWhenDumping();
+ objToSave = classBasedReplacementWhenDumping;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have run the replacement method
+ assertTrue("Did not run writeReplace",
+ classBasedReplacementWhenDumping.calledReplacement);
+
+ // Has to have loaded a String (replacement object)
+ assertTrue("Did not replace properly", FOO.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_28_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ MultipleClassBasedReplacementWhenDumping multipleClassBasedReplacementWhenDumping = new MultipleClassBasedReplacementWhenDumping();
+ objToSave = multipleClassBasedReplacementWhenDumping;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have loaded a String (replacement object)
+ assertTrue(
+ "Executed multiple levels of replacement (see PR 1F9RNT1), loaded= "
+ + objLoaded,
+ objLoaded instanceof MultipleClassBasedReplacementWhenDumping.C1);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.toString());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_29_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ClassBasedReplacementWhenLoading classBasedReplacementWhenLoading = new ClassBasedReplacementWhenLoading();
+ objToSave = classBasedReplacementWhenLoading;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have loaded a String (replacement object)
+ assertTrue("Did not run readResolve", FOO.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_30_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ClassBasedReplacementWhenLoadingViolatesFieldType classBasedReplacementWhenLoadingViolatesFieldType = new ClassBasedReplacementWhenLoadingViolatesFieldType();
+ objToSave = classBasedReplacementWhenLoadingViolatesFieldType;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // We cannot gere here, the load replacement must have caused a
+ // field type violation
+ fail(
+ "Loading replacements can cause field type violation in this implementation");
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (ClassCastException e) {
+ assertTrue(
+ "Loading replacements can NOT cause field type violation in this implementation",
+ true);
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_31_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ MyExceptionWhenDumping1 exceptionWhenDumping = new MyExceptionWhenDumping1();
+ objToSave = exceptionWhenDumping;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ boolean causedException = false;
+ try {
+ dump(objToSave);
+ } catch (MyExceptionWhenDumping1.MyException e) {
+ causedException = true;
+ }
+ ;
+ assertTrue("Should have caused an exception when dumping",
+ causedException);
+ causedException = false;
+ try {
+ objLoaded = reload();
+ // Although the spec says we should get a WriteAbortedException,
+ // the serialization format handle an Exception when reading
+ // primitive data so we get ClassCastException instead
+ } catch (ClassCastException e) {
+ causedException = true;
+ }
+ ;
+ assertTrue("Should have caused a ClassCastException when loading",
+ causedException);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_32_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ MyExceptionWhenDumping2 exceptionWhenDumping = new MyExceptionWhenDumping2();
+ objToSave = exceptionWhenDumping;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ boolean causedException = false;
+ try {
+ dump(objToSave);
+ } catch (MyExceptionWhenDumping2.MyException e) {
+ causedException = true;
+ }
+ ;
+ assertTrue("Should have caused an exception when dumping",
+ causedException);
+ causedException = false;
+ try {
+ objLoaded = reload();
+ } catch (java.io.WriteAbortedException e) {
+ causedException = true;
+ }
+ ;
+ assertTrue(
+ "Should have caused a java.io.WriteAbortedException when loading",
+ causedException);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (ClassCastException e) {
+ fail("ClassCastException : " + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_NonSerializableExceptionWhenDumping() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ NonSerializableExceptionWhenDumping nonSerializableExceptionWhenDumping = new NonSerializableExceptionWhenDumping();
+ objToSave = nonSerializableExceptionWhenDumping;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ boolean causedException = false;
+ try {
+ dump(objToSave);
+ } catch (java.io.NotSerializableException e) {
+ causedException = true;
+ }
+ ;
+ assertTrue("Should have caused an exception when dumping",
+ causedException);
+ causedException = false;
+ try {
+ objLoaded = reload();
+ } catch (java.io.WriteAbortedException e) {
+ causedException = true;
+ }
+ ;
+ assertTrue(
+ "Should have caused a java.io.WriteAbortedException when loading",
+ causedException);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_33_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ MyUnserializableExceptionWhenDumping exceptionWhenDumping = new MyUnserializableExceptionWhenDumping();
+ objToSave = exceptionWhenDumping;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ boolean causedException = false;
+ try {
+ dump(objToSave);
+ } catch (MyUnserializableExceptionWhenDumping.MyException e) {
+ causedException = true;
+ }
+
+ assertTrue("Should have caused an exception when dumping",
+ causedException);
+ // As the stream is corrupted, reading the stream will have
+ // undefined results
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_34_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ java.io.IOException ioe = new java.io.IOException();
+ objToSave = ioe;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_35_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = Class.forName("java.util.Hashtable");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Classes with the same name are unique, so test for ==
+ assertTrue(MSG_TEST_FAILED + objToSave, objLoaded == objToSave);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_36_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ java.io.IOException ex = new java.io.InvalidClassException(FOO);
+ objToSave = ex;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_37_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ java.io.IOException ex = new java.io.InvalidObjectException(FOO);
+ objToSave = ex;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_38_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ java.io.IOException ex = new java.io.NotActiveException(FOO);
+ objToSave = ex;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_39_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ java.io.IOException ex = new java.io.NotSerializableException(FOO);
+ objToSave = ex;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_40_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ java.io.IOException ex = new java.io.StreamCorruptedException(FOO);
+ objToSave = ex;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest2.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest2.java
new file mode 100644
index 0000000..359050e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest2.java
@@ -0,0 +1,2101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.NotActiveException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamConstants;
+import java.io.ObjectStreamField;
+import java.io.OptionalDataException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Locale;
+
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest2 extends SerializationStressTest {
+
+ private static class ReadWriteObjectAndPrimitiveData implements
+ java.io.Serializable {
+ transient long milliseconds;
+
+ public boolean calledWriteObject = false;
+
+ public boolean calledReadObject = false;
+
+ public ReadWriteObjectAndPrimitiveData() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ // This *has* to come after the call to defaultReadObject or the
+ // value from the stream will override
+ calledReadObject = true;
+ milliseconds = in.readLong();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
+ calledWriteObject = true;
+ out.defaultWriteObject();
+ out.writeLong(milliseconds);
+ }
+ }
+
+ // What happens if a class defines serialPersistentFields that do not match
+ // real fields but does not override read/writeObject
+ private static class WithUnmatchingSerialPersistentFields implements
+ java.io.Serializable {
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ "value", String.class) };
+
+ public int anInstanceVar = 5;
+
+ public WithUnmatchingSerialPersistentFields() {
+ super();
+ }
+ }
+
+ // What happens if a class defines serialPersistentFields which match actual
+ // fields
+ private static class WithMatchingSerialPersistentFields implements
+ java.io.Serializable {
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ "anInstanceVar", String.class) };
+
+ public String anInstanceVar = FOO + FOO;
+
+ public WithMatchingSerialPersistentFields() {
+ super();
+ }
+ }
+
+ // Tests the oficial behavior for serialPersistentFields
+ private static class SerialPersistentFields implements java.io.Serializable {
+ private static final String SIMULATED_FIELD_NAME = "text";
+
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ SIMULATED_FIELD_NAME, String.class) };
+
+ public int anInstanceVar = 5;
+
+ public SerialPersistentFields() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ ObjectInputStream.GetField fields = in.readFields();
+ anInstanceVar = Integer.parseInt((String) fields.get(
+ SIMULATED_FIELD_NAME, "-5"));
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ ObjectOutputStream.PutField fields = out.putFields();
+ fields.put(SIMULATED_FIELD_NAME, Integer.toString(anInstanceVar));
+ out.writeFields();
+ }
+ }
+
+ // Tests the behavior for serialPersistentFields when no fields are actually
+ // set
+ private static class WriteFieldsWithoutFetchingPutFields implements
+ java.io.Serializable {
+ private static final String SIMULATED_FIELD_NAME = "text";
+
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ SIMULATED_FIELD_NAME, String.class) };
+
+ public int anInstanceVar = 5;
+
+ public WriteFieldsWithoutFetchingPutFields() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ ObjectInputStream.GetField fields = in.readFields();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ out.writeFields();
+ }
+ }
+
+ // Tests what happens if one asks for PutField/getField when the class does
+ // not declare one
+ private static class SerialPersistentFieldsWithoutField implements
+ java.io.Serializable {
+ public int anInstanceVar = 5;
+
+ public SerialPersistentFieldsWithoutField() {
+ super();
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ ObjectInputStream.GetField fields = in.readFields();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ ObjectOutputStream.PutField fields = out.putFields();
+ out.writeFields();
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+
+ // writeObject writes extra primitive types and objects which readObject
+ // does not consume. Have to make sure we can load object properly AND
+ // object after it (to show the extra byte[] is consumed)
+ private static class OptionalDataNotRead implements java.io.Serializable {
+ private int field1, field2;
+
+ public OptionalDataNotRead() {
+ }
+
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("field1", Integer.TYPE),
+ new ObjectStreamField("field2", Integer.TYPE),
+ new ObjectStreamField("monthLength", byte[].class), };
+
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ ObjectOutputStream.PutField fields = stream.putFields();
+ fields.put("field1", 1);
+ fields.put("field2", 2);
+ fields.put("monthLength", new byte[] { 7, 8, 9 });
+ stream.writeFields();
+ stream.writeInt(4);
+ byte[] values = new byte[4];
+ values[0] = (byte) 16;
+ values[1] = (byte) 17;
+ values[2] = (byte) 18;
+ values[3] = (byte) 19;
+ stream.writeObject(values);
+ }
+
+ private void readObject(ObjectInputStream stream) throws IOException,
+ ClassNotFoundException {
+ ObjectInputStream.GetField fields = stream.readFields();
+ field1 = fields.get("field1", 0);
+ field2 = fields.get("field1", 0);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class NestedPutField implements java.io.Serializable {
+ public OptionalDataNotRead field1;
+
+ public NestedPutField() {
+ }
+
+ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+ "field1", OptionalDataNotRead.class), };
+
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ ObjectOutputStream.PutField fields = stream.putFields();
+ fields.put("field1", new OptionalDataNotRead());
+ stream.writeFields();
+ }
+
+ private void readObject(ObjectInputStream stream) throws IOException,
+ ClassNotFoundException {
+ ObjectInputStream.GetField fields = stream.readFields();
+ field1 = (OptionalDataNotRead) fields.get("field1", null);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+
+ // This one tests stream-based replacement when dumping
+ private static class StreamBasedReplacementWhenDumping extends
+ java.io.ObjectOutputStream {
+ public boolean calledArrayReplacement = false;
+
+ public boolean calledStringReplacement = false;
+
+ public boolean calledClassReplacement = false;
+
+ public boolean calledObjectStreamClassReplacement = false;
+
+ public StreamBasedReplacementWhenDumping(java.io.OutputStream output)
+ throws java.io.IOException {
+ super(output);
+ enableReplaceObject(true);
+ }
+
+ protected Object replaceObject(Object obj) throws IOException {
+ Class objClass = obj.getClass();
+ if (objClass == String.class)
+ calledStringReplacement = true;
+
+ if (objClass == Class.class)
+ calledClassReplacement = true;
+
+ if (objClass == ObjectStreamClass.class)
+ calledObjectStreamClassReplacement = true;
+
+ if (objClass.isArray())
+ calledArrayReplacement = true;
+
+ return obj;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+
+ private static class ArrayOfSerializable implements Serializable {
+ private Serializable[] testField = null;
+
+ public ArrayOfSerializable() {
+ testField = new Serializable[2];
+ testField[0] = "Hi";
+ testField[1] = "there!";
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+
+ private static class ClassSubClassTest0 extends java.lang.Object implements
+ java.io.Serializable {
+ String stringVar;
+
+ public ClassSubClassTest0(String init) {
+ stringVar = init;
+ }
+ }
+
+ private static class ClassSubClassTest1 extends ClassSubClassTest0 {
+ String subStringVar;
+
+ public ClassSubClassTest1(String superString, String subString) {
+ super(superString);
+ subStringVar = subString;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (!(obj instanceof ClassSubClassTest1))
+ return false;
+
+ ClassSubClassTest1 inst = (ClassSubClassTest1) obj;
+ return inst.subStringVar.equals(this.subStringVar)
+ && inst.stringVar.equals(this.stringVar);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class ConstructorTestA {
+ public String instVar_classA;
+
+ public final static String ConstrA = "Init in Constructor Class A";
+
+ public final static String ConstrB = "Init in Constructor Class B";
+
+ public final static String ConstrC = "Init in Constructor Class C";
+
+ public final static String ChangedC = "Changed before Serialize - Class C";
+
+ public ConstructorTestA() {
+ instVar_classA = ConstrA;
+ }
+ }
+
+ private static class ConstructorTestB extends ConstructorTestA implements
+ java.io.Serializable {
+ public String instVar_classB;
+
+ public ConstructorTestB() {
+ instVar_classA = ConstrB;
+ instVar_classB = ConstrB;
+ }
+ }
+
+ private static class ConstructorTestC extends ConstructorTestB {
+ public String instVar_classC;
+
+ public ConstructorTestC() {
+ instVar_classA = ConstrC;
+ instVar_classB = ConstrC;
+ instVar_classC = ConstrC;
+ }
+
+ public boolean verify(Object obj) {
+ if (obj == null)
+ return false;
+ if (!(obj instanceof ConstructorTestC))
+ return false;
+
+ ConstructorTestC inst = (ConstructorTestC) obj;
+ return inst.instVar_classC.equals(this.instVar_classC)
+ && inst.instVar_classB.equals(this.instVar_classB)
+ && inst.instVar_classA.equals(ConstrA);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class HashCodeTest implements java.io.Serializable {
+ private boolean serializationUsesHashCode = false;
+
+ public int hashCode() {
+ serializationUsesHashCode = true;
+ return super.hashCode();
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class InitializerFieldsTest implements java.io.Serializable {
+ public java.lang.String toBeSerialized;
+
+ public static java.lang.String toBeNotSerialized;
+
+ public static java.lang.String toBeNotSerialized2;
+
+ {
+ toBeSerialized = "NonStaticInitialValue";
+ }
+
+ static {
+ toBeNotSerialized = "StaticInitialValue";
+ toBeNotSerialized2 = new String(toBeNotSerialized);
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. It is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof InitializerFieldsTest))
+ return false;
+
+ InitializerFieldsTest inst = (InitializerFieldsTest) obj;
+ return inst.toBeSerialized.equals(this.toBeSerialized)
+ && InitializerFieldsTest.toBeNotSerialized.equals(toBeNotSerialized2);
+ }
+ }
+
+ private static class InitializerFieldsTest2 implements java.io.Serializable {
+ public java.lang.String toBeSerialized;
+
+ public static java.lang.String toBeNotSerialized;
+
+ public static java.lang.String toBeNotSerialized2;
+
+ {
+ toBeSerialized = "NonStaticInitialValue";
+ }
+
+ public java.lang.String toBeSerialized3;
+
+ public java.lang.String toBeSerialized4;
+
+ static {
+ toBeNotSerialized = "StaticInitialValue";
+ toBeNotSerialized2 = new String(toBeNotSerialized);
+ }
+
+ public java.lang.String toBeSerialized5;
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. It is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof InitializerFieldsTest2))
+ return false;
+
+ InitializerFieldsTest2 inst = (InitializerFieldsTest2) obj;
+ return inst.toBeSerialized.equals(this.toBeSerialized)
+ && inst.toBeSerialized3.equals(this.toBeSerialized3)
+ && inst.toBeSerialized4.equals(this.toBeSerialized4)
+ && inst.toBeSerialized5.equals(this.toBeSerialized5)
+ && InitializerFieldsTest2.toBeNotSerialized.equals(toBeNotSerialized2);
+ }
+ }
+
+ private static class InitializerFieldsTest3 extends InitializerFieldsTest2
+ implements java.io.Serializable {
+ public java.lang.String sub_toBeSerialized;
+
+ public static java.lang.String sub_toBeNotSerialized;
+
+ public static java.lang.String sub_toBeNotSerialized2;
+
+ {
+ sub_toBeSerialized = "NonStaticInitialValue";
+ }
+
+ public java.lang.String sub_toBeSerialized3;
+
+ public java.lang.String sub_toBeSerialized4;
+
+ static {
+ sub_toBeNotSerialized = "StaticInitialValue";
+ sub_toBeNotSerialized2 = new String(sub_toBeNotSerialized);
+ }
+
+ public java.lang.String sub_toBeSerialized5;
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. It is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (!super.equals(obj))
+ return false;
+ if (!(obj instanceof InitializerFieldsTest3))
+ return false;
+
+ InitializerFieldsTest3 inst = (InitializerFieldsTest3) obj;
+ return inst.sub_toBeSerialized.equals(this.sub_toBeSerialized)
+ && inst.sub_toBeSerialized3
+ .equals(this.sub_toBeSerialized3)
+ && inst.sub_toBeSerialized4
+ .equals(this.sub_toBeSerialized4)
+ && inst.sub_toBeSerialized5
+ .equals(this.sub_toBeSerialized5)
+ && InitializerFieldsTest3.sub_toBeNotSerialized
+ .equals(sub_toBeNotSerialized2);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class DeepNesting implements java.io.Serializable {
+ public float id;
+
+ public DeepNesting next;
+
+ public boolean dump;
+
+ public boolean load;
+
+ public DeepNesting(float id) {
+ this.id = id;
+ next = null;
+ dump = false;
+ load = false;
+ }
+
+ public DeepNesting(int howMany) {
+ DeepNesting prev = new DeepNesting(0.0F);
+ next(prev);
+ for (int i = 1; i < howMany; i++) {
+ prev = prev.next(new DeepNesting(i * 1.0F));
+ }
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (!(obj instanceof DeepNesting))
+ return false;
+
+ DeepNesting inst = (DeepNesting) obj;
+ if (inst.dump != this.dump || inst.load != this.load)
+ return false;
+
+ if (inst.next == null || this.next == null)
+ return inst.next == this.next; // both null
+ return this.next.equals(inst.next);
+ }
+
+ public DeepNesting next(DeepNesting ivt) {
+ next = ivt;
+ return ivt;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class DeepNestingWithWriteObject implements
+ java.io.Serializable {
+ public float id;
+
+ public DeepNestingWithWriteObject next;
+
+ public boolean dump;
+
+ public boolean load;
+
+ public DeepNestingWithWriteObject(float id) {
+ this.id = id;
+ next = null;
+ dump = false;
+ load = false;
+ }
+
+ public DeepNestingWithWriteObject(int howMany) {
+ DeepNestingWithWriteObject prev = new DeepNestingWithWriteObject(
+ 0.0F);
+ next(prev);
+ for (int i = 1; i < howMany; i++) {
+ prev = prev.next(new DeepNestingWithWriteObject(i * 1.0F));
+ }
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (!(obj instanceof DeepNestingWithWriteObject))
+ return false;
+
+ DeepNestingWithWriteObject inst = (DeepNestingWithWriteObject) obj;
+ if (inst.dump != this.dump || inst.load != this.load)
+ return false;
+
+ if (inst.next == null || this.next == null)
+ return inst.next == this.next; // both null;
+ return this.next.equals(inst.next);
+ }
+
+ public DeepNestingWithWriteObject next(DeepNestingWithWriteObject ivt) {
+ next = ivt;
+ return ivt;
+ }
+
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ s.defaultWriteObject();
+ }
+
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ static class NonPublicClassTest extends java.lang.Object implements
+ java.io.Serializable {
+ int field = 1;
+
+ public NonPublicClassTest() {
+ field = 10;
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof NonPublicClassTest)
+ return field == ((NonPublicClassTest) o).field;
+ return false;
+ }
+
+ public void x10() {
+ field *= 10;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class SameInstVarNameSuperClass {
+ private int foo;
+
+ public SameInstVarNameSuperClass() {
+ super();
+ }
+
+ public SameInstVarNameSuperClass(int fooValue) {
+ foo = fooValue;
+ }
+
+ public String toString() {
+ return "foo = " + foo;
+ }
+ }
+
+ private static class SameInstVarNameSubClass extends
+ SameInstVarNameSuperClass implements java.io.Serializable {
+ protected int foo;
+
+ public SameInstVarNameSubClass() {
+ super();
+ }
+
+ public SameInstVarNameSubClass(int fooValue) {
+ super(-fooValue);
+ foo = fooValue;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class SInterfaceTest implements java.io.Serializable {
+ public static int staticVar = 5;
+
+ public transient int[] transVar = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+
+ public int instanceVar = 7;
+
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (!(obj instanceof SInterfaceTest))
+ return false;
+
+ SInterfaceTest inst = (SInterfaceTest) obj;
+ if (this.instanceVar != inst.instanceVar)
+ return false;
+ if (inst.transVar == null || this.transVar == null)
+ return inst.transVar == this.transVar; // both null
+ for (int i = 0; i < transVar.length; i++)
+ if (inst.transVar[i] != this.transVar[i])
+ return false;
+ return true;
+ }
+
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ Object arr;
+ s.defaultReadObject();
+ arr = s.readObject();
+ transVar = (int[]) arr;
+ }
+
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ s.defaultWriteObject();
+ s.writeObject(transVar);
+ }
+
+ public void x10() {
+ for (int i = 0; i < transVar.length; i++)
+ transVar[i] = transVar[i] * 10;
+ instanceVar = instanceVar * 10;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class SInterfaceTest2 extends SInterfaceTest {
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ Object arr;
+ instanceVar = s.readInt();
+ arr = s.readObject();
+ transVar = (int[]) arr;
+ }
+
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ s.writeInt(instanceVar);
+ s.writeObject(transVar);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class SuperclassTest extends java.lang.Object implements
+ java.io.Serializable {
+ int superfield = 1;
+
+ public SuperclassTest() {
+ superfield = 10;
+ }
+
+ public boolean equals(Object o) {
+ if (o.getClass() == this.getClass())
+ return superfield == ((SuperclassTest) o).superfield;
+ return false;
+ }
+
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ superfield = s.readInt();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ s.writeInt(superfield);
+ }
+
+ public void x10() {
+ superfield *= 10;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class SuperclassTest2 extends SuperclassTest {
+ int subfield = 5;
+
+ public SuperclassTest2() {
+ subfield = 50;
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof SuperclassTest2)
+ if (subfield == ((SuperclassTest2) o).subfield)
+ return super.equals(o);
+ return false;
+ }
+
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ subfield = s.readInt();
+ }
+
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ s.writeInt(subfield);
+ }
+
+ public void x10() {
+ subfield *= 10;
+ super.x10();
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class SyntheticFieldTest implements java.io.Serializable {
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. It is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+ if (obj == null)
+ return false;
+ return obj instanceof SyntheticFieldTest;
+ }
+
+ public int hashCode() {
+ // Insert code to generate a hash code for the receiver here.
+ // This implementation forwards the message to super. You may
+ // replace or supplement this.
+ // NOTE: if two objects are equal (equals Object) returns true) they
+ // must have the same hash code
+ Class[] c = { String.class }; // *** synthetic field
+ return super.hashCode();
+ }
+ }
+
+ public SerializationStressTest2(String name) {
+ super(name);
+ }
+
+ public void test_18_41_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ java.io.IOException ex = new java.io.WriteAbortedException(FOO,
+ null);
+ objToSave = ex;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_42_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ WithUnmatchingSerialPersistentFields spf = new WithUnmatchingSerialPersistentFields();
+ objToSave = spf;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ boolean causedException = false;
+ try {
+ objLoaded = dumpAndReload(objToSave);
+ } catch (InvalidClassException ce) {
+ causedException = true;
+ }
+ assertTrue("serialPersistentFields do not match real fields",
+ causedException);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_43_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ WithMatchingSerialPersistentFields spf = new WithMatchingSerialPersistentFields();
+ spf.anInstanceVar = FOO;
+ objToSave = spf;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(
+ "serialPersistentFields do not work properly in this implementation",
+ FOO
+ .equals(((WithMatchingSerialPersistentFields) objLoaded).anInstanceVar));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_44_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SerialPersistentFields spf = new SerialPersistentFields();
+ final int CONST = -500;
+ spf.anInstanceVar = CONST;
+ objToSave = spf;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(
+ "serialPersistentFields do not work properly in this implementation",
+ ((SerialPersistentFields) objLoaded).anInstanceVar == CONST);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_45_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ WriteFieldsWithoutFetchingPutFields spf = new WriteFieldsWithoutFetchingPutFields();
+ objToSave = spf;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ boolean causedException = false;
+ try {
+ objLoaded = dumpAndReload(objToSave);
+ } catch (NotActiveException ce) {
+ causedException = true;
+ }
+ assertTrue("WriteFieldsWithoutFetchingPutFields", causedException);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_46_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = SerialPersistentFields.class; // Test for 1FA7TA6
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_47_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = ObjectStreamClass.lookup(SerialPersistentFields.class); // Test
+ // for
+ // 1FA7TA6
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to be able to save/load an exception
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_48_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SerialPersistentFieldsWithoutField spf = new SerialPersistentFieldsWithoutField();
+ final int CONST = -500;
+ spf.anInstanceVar = CONST;
+ objToSave = spf;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(
+ "serialPersistentFields do not work properly in this implementation",
+ ((SerialPersistentFieldsWithoutField) objLoaded).anInstanceVar != CONST);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_51_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ ReadWriteObjectAndPrimitiveData readWrite = new ReadWriteObjectAndPrimitiveData();
+ objToSave = readWrite;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // has to have called the writeObject on the instance to dump
+ assertTrue(MSG_TEST_FAILED + objToSave, readWrite.calledWriteObject);
+ // has to have called the readObject on the instance loaded
+ assertTrue(
+ MSG_TEST_FAILED + objToSave,
+ ((ReadWriteObjectAndPrimitiveData) objLoaded).calledReadObject);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_52_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ ArrayList list = new ArrayList<String>(Arrays.asList(new String[] { "a",
+ "list", "of", "strings" }));
+ objToSave = list;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_53_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+
+ objToSave = Locale.CHINESE;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_OptionalDataNotRead() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ OptionalDataNotRead test = new OptionalDataNotRead();
+ // Have to save an object after the one above, and when we read it,
+ // it cannot be a byte[]
+ Date now = new Date();
+ Object[] twoObjects = new Object[2];
+ twoObjects[0] = test;
+ twoObjects[1] = now;
+ objToSave = twoObjects;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ Object[] twoLoadedObjects = (Object[]) objLoaded;
+ assertTrue(MSG_TEST_FAILED + objToSave, twoLoadedObjects[0]
+ .getClass() == OptionalDataNotRead.class);
+ assertTrue(MSG_TEST_FAILED + objToSave, twoLoadedObjects[1]
+ .getClass() == Date.class);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_55_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object[] threeObjects = new Object[3];
+ threeObjects[0] = new Integer(2);
+ threeObjects[1] = Date.class;
+ threeObjects[2] = threeObjects[0]; // has to be the same
+ objToSave = threeObjects;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ Object[] threeLoadedObjects = (Object[]) objLoaded;
+ assertTrue(MSG_TEST_FAILED + objToSave, threeLoadedObjects[0]
+ .getClass() == Integer.class);
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ threeLoadedObjects[1] == Date.class);
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ threeLoadedObjects[0] == threeLoadedObjects[2]);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_56_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ // Test for 1FD24BY
+ NestedPutField test = new NestedPutField();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertNotNull(MSG_TEST_FAILED + objToSave,
+ ((NestedPutField) objLoaded).field1);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_57_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ByteArrayOutputStream out;
+ StreamBasedReplacementWhenDumping streamBasedReplacementWhenDumping;
+
+ out = new ByteArrayOutputStream();
+ streamBasedReplacementWhenDumping = new StreamBasedReplacementWhenDumping(out);
+ objToSave = FOO.getClass();
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ streamBasedReplacementWhenDumping.writeObject(objToSave);
+ // Has to have run the replacement method
+ assertTrue(streamBasedReplacementWhenDumping.calledClassReplacement);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (Error err) {
+ System.out.println("Error " + err + " when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_18_58_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ByteArrayOutputStream out;
+ StreamBasedReplacementWhenDumping streamBasedReplacementWhenDumping;
+
+ out = new ByteArrayOutputStream();
+ streamBasedReplacementWhenDumping = new StreamBasedReplacementWhenDumping(
+ out);
+
+ objToSave = ObjectStreamClass.lookup(FOO.getClass());
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ streamBasedReplacementWhenDumping.writeObject(objToSave);
+ // Has to have run the replacement method
+ assertTrue(streamBasedReplacementWhenDumping.calledObjectStreamClassReplacement);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (Error err) {
+ System.out.println("Error " + err + " when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_18_59_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ByteArrayOutputStream out;
+ StreamBasedReplacementWhenDumping streamBasedReplacementWhenDumping;
+
+ out = new ByteArrayOutputStream();
+ streamBasedReplacementWhenDumping = new StreamBasedReplacementWhenDumping(
+ out);
+ ;
+ objToSave = new int[3];
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ streamBasedReplacementWhenDumping.writeObject(objToSave);
+ // Has to have run the replacement method
+ assertTrue("DId not execute replacement when it should: "
+ + objToSave,
+ streamBasedReplacementWhenDumping.calledArrayReplacement);
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (Error err) {
+ System.out.println("Error " + err + " when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_18_60_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ByteArrayOutputStream out;
+ StreamBasedReplacementWhenDumping streamBasedReplacementWhenDumping;
+
+ out = new ByteArrayOutputStream();
+ streamBasedReplacementWhenDumping = new StreamBasedReplacementWhenDumping(
+ out);
+ ;
+ objToSave = FOO;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ streamBasedReplacementWhenDumping.writeObject(objToSave);
+ // Has to have run the replacement method
+ assertTrue("Did not execute replacement when it should: "
+ + objToSave,
+ streamBasedReplacementWhenDumping.calledStringReplacement);
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + "\t->"
+ + e.toString());
+ } catch (Error err) {
+ System.out.println("Error " + err + " when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_18_61_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ArrayOfSerializable test = new ArrayOfSerializable();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_62_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ClassSubClassTest1 test = new ClassSubClassTest1(
+ "SuperInitialString", "SubInitialString");
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_63_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ConstructorTestC test = new ConstructorTestC();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.verify(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_64_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ HashCodeTest test = new HashCodeTest();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ !((HashCodeTest) objLoaded).serializationUsesHashCode);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_65_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ InitializerFieldsTest test = new InitializerFieldsTest();
+ test.toBeSerialized = "serializing";
+ InitializerFieldsTest.toBeNotSerialized = "It should not have this value after loaded from a File";
+ InitializerFieldsTest.toBeNotSerialized2 = "Good-This is the rigth value.";
+
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ dump(objToSave);
+ InitializerFieldsTest.toBeNotSerialized = new String(
+ InitializerFieldsTest.toBeNotSerialized2);
+ objLoaded = reload();
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_66_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ InitializerFieldsTest2 test = new InitializerFieldsTest2();
+ test.toBeSerialized = "serializing";
+ test.toBeSerialized3 = "serializing3";
+ test.toBeSerialized4 = "serializing4";
+ test.toBeSerialized5 = "serializing5";
+ InitializerFieldsTest2.toBeNotSerialized = "It should not have this value after loaded from a File";
+ InitializerFieldsTest2.toBeNotSerialized2 = "Good-This is the rigth value.";
+
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ dump(objToSave);
+ InitializerFieldsTest2.toBeNotSerialized = new String(
+ InitializerFieldsTest2.toBeNotSerialized2);
+ objLoaded = reload();
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_67_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ InitializerFieldsTest3 test = new InitializerFieldsTest3();
+ test.toBeSerialized = "serializing";
+ test.toBeSerialized3 = "serializing3";
+ test.toBeSerialized4 = "serializing4";
+ test.toBeSerialized5 = "serializing5";
+ InitializerFieldsTest2.toBeNotSerialized = "It should not have this value after loaded from a File";
+ InitializerFieldsTest2.toBeNotSerialized2 = "Good-This is the rigth value.";
+ test.sub_toBeSerialized = "serializingSub";
+ test.sub_toBeSerialized3 = "serializing3sub";
+ test.sub_toBeSerialized4 = "serializing4sub";
+ test.sub_toBeSerialized5 = "serializing5sub";
+ InitializerFieldsTest3.sub_toBeNotSerialized = "(Subclass) It should not have this value after loaded from a File";
+ InitializerFieldsTest3.sub_toBeNotSerialized2 = "(Subclass) Good-This is the rigth value.";
+ // Before dumping the two static vars are differents.
+ // After dumping the value of toBeNotSerialized2 is put in
+ // toBeNotSerialized
+ // After loading it must be the same.
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ dump(objToSave);
+ InitializerFieldsTest2.toBeNotSerialized = new String(
+ InitializerFieldsTest2.toBeNotSerialized2);
+ InitializerFieldsTest3.sub_toBeNotSerialized = new String(
+ InitializerFieldsTest3.sub_toBeNotSerialized2);
+ objLoaded = reload();
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_DeepNesting() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ DeepNesting test = new DeepNesting(25);
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ // err.printStackTrace();
+ System.out.println("Error " + err + " when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_DeepNestingWithWriteObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ DeepNestingWithWriteObject test = new DeepNestingWithWriteObject(10);
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ // err.printStackTrace();
+ System.out.println("Error " + err + " when obj = " + objToSave);
+ throw err;
+ }
+ }
+
+ public void test_18_69_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ NonPublicClassTest test = new NonPublicClassTest();
+ test.x10();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_70_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ int[] test = new int[1];
+ int intValue = 0;
+ test[0] = intValue;
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(test,
+ (int[]) objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_71_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ int i, j, maxJ = 3, maxI = 200;
+ byte[][] obj = new byte[maxJ][maxI];
+ for (j = 0; j < maxJ; j++) {
+ for (i = 0; i < maxI; i++)
+ obj[j][i] = (byte) (i - 100);
+ }
+ objToSave = obj;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ byte[][] toCompare = (byte[][]) objLoaded;
+
+ boolean ok = true;
+ // Has to have worked
+ for (j = 0; j < maxJ; j++) {
+ for (i = 0; i < maxI; i++)
+ if (obj[j][i] != toCompare[j][i]) {
+ ok = false;
+ break;
+ }
+ }
+
+ assertTrue(MSG_TEST_FAILED + objToSave, ok);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_72_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ int i, j, maxJ = 3, maxI = 200;
+ int[][] obj = new int[maxJ][maxI];
+ for (j = 0; j < maxJ; j++) {
+ for (i = 0; i < maxI; i++)
+ obj[j][i] = (i - 100);
+ }
+ objToSave = obj;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ int[][] toCompare = (int[][]) objLoaded;
+
+ boolean ok = true;
+ // Has to have worked
+ for (j = 0; j < maxJ; j++) {
+ for (i = 0; i < maxI; i++)
+ if (obj[j][i] != toCompare[j][i]) {
+ ok = false;
+ break;
+ }
+ }
+
+ assertTrue(MSG_TEST_FAILED + objToSave, ok);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_73_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ String org = "abcdefghijklmnopqrstuvxyz1234567890abcdefghijklmnopqrstuvxyz1234567890";
+ int i, j, maxJ = 3, maxI = 70;
+ String[][] obj = new String[maxJ][maxI];
+ for (j = 0; j < maxJ; j++) {
+ for (i = 0; i < maxI; i++)
+ obj[j][i] = org.substring(0, i);
+ }
+ objToSave = obj;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ String[][] toCompare = (String[][]) objLoaded;
+
+ boolean ok = true;
+ // Has to have worked
+ for (j = 0; j < maxJ; j++) {
+ for (i = 0; i < maxI; i++)
+ if (!obj[j][i].equals(toCompare[j][i])) {
+ ok = false;
+ break;
+ }
+ }
+
+ assertTrue(MSG_TEST_FAILED + objToSave, ok);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_74_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SameInstVarNameSubClass test = new SameInstVarNameSubClass(100);
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ ((SameInstVarNameSubClass) objLoaded).foo == 100);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_75_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SInterfaceTest test = new SInterfaceTest();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_76_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SInterfaceTest2 test = new SInterfaceTest2();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_77_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SuperclassTest test = new SuperclassTest();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_78_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SuperclassTest2 test = new SuperclassTest2();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_79_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ SyntheticFieldTest test = new SyntheticFieldTest();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_80_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(out);
+ new ObjectOutputStream(dos); // just to make sure we get a header
+ dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA);
+ int length = 99;
+ dos.writeByte(length);
+ for (int i = 0; i < length; i++) {
+ dos.writeByte(0); // actual value does not matter
+ }
+ dos.flush();
+ int lengthRead = 0;
+ try {
+ ObjectInputStream ois = new ObjectInputStream(
+ new ByteArrayInputStream(out.toByteArray()));
+ Object obj = ois.readObject();
+ } catch (OptionalDataException e) {
+ lengthRead = e.length;
+ }
+ assertTrue("Did not throw exception with optional data size ",
+ length == lengthRead);
+ } catch (ClassNotFoundException e) {
+ fail("Unable to read BLOCKDATA: " + e.getMessage());
+ } catch (IOException e) {
+ fail("IOException testing BLOCKDATA : " + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error " + err + " when testing BLOCKDATA");
+ throw err;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest3.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest3.java
new file mode 100644
index 0000000..8087761
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest3.java
@@ -0,0 +1,1670 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamConstants;
+import java.io.ObjectStreamField;
+import java.io.OptionalDataException;
+import java.math.BigInteger;
+import java.security.PermissionCollection;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.PropertyPermission;
+import java.util.TimeZone;
+import java.util.Vector;
+
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest3 extends SerializationStressTest {
+
+ // -----------------------------------------------------------------------------------
+ private static class DefaultConstructor implements java.io.Serializable {
+ int f1;
+
+ static int valueAfterConstructor = 5;
+
+ DefaultConstructor() {
+ f1 = valueAfterConstructor;
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. It is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof DefaultConstructor))
+ return false;
+
+ DefaultConstructor inst = (DefaultConstructor) obj;
+ return inst.f1 == valueAfterConstructor;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class NonSerDefaultConstructor {
+ public int f1;
+
+ public static int valueAfterConstructor = 5;
+
+ NonSerDefaultConstructor() {
+ f1 = valueAfterConstructor;
+ }
+
+ public NonSerDefaultConstructor(String notUsed) {
+ }
+ }
+
+ private static class NonSerPrivateConstructor {
+ public int f1;
+
+ public static int valueAfterConstructor = 5;
+
+ private NonSerPrivateConstructor() {
+ f1 = valueAfterConstructor;
+ }
+
+ public NonSerPrivateConstructor(String notUsed) {
+ }
+ }
+
+ private static class NonSerProtectedConstructor {
+ public int f1;
+
+ public static int valueAfterConstructor = 5;
+
+ protected NonSerProtectedConstructor() {
+ f1 = valueAfterConstructor;
+ }
+ }
+
+ private static class NonSerPublicConstructor {
+ public int f1;
+
+ public static int valueAfterConstructor = 5;
+
+ public NonSerPublicConstructor() {
+ f1 = valueAfterConstructor;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class DefaultConstructorSub extends NonSerDefaultConstructor
+ implements java.io.Serializable {
+ int fsub;
+
+ static int subValueAfterConstructor = 11;
+
+ public DefaultConstructorSub() {
+ f1 = 7;
+ fsub = subValueAfterConstructor;
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. It is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof DefaultConstructorSub))
+ return false;
+
+ DefaultConstructorSub inst = (DefaultConstructorSub) obj;
+ if (inst.f1 != valueAfterConstructor)
+ return false;
+ return inst.fsub == subValueAfterConstructor;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class PrivateConstructor implements java.io.Serializable {
+ int f1;
+
+ static int valueAfterConstructor = 5;
+
+ private PrivateConstructor() {
+ f1 = valueAfterConstructor;
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. Is is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof PrivateConstructor))
+ return false;
+
+ PrivateConstructor inst = (PrivateConstructor) obj;
+ return inst.f1 == valueAfterConstructor;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class PrivateConstructorSub extends NonSerPrivateConstructor
+ implements java.io.Serializable {
+ int fsub;
+
+ static int subValueAfterConstructor = 11;
+
+ public PrivateConstructorSub() {
+ super("notUsed");
+ f1 = 7;
+ fsub = subValueAfterConstructor;
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. Is is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof PrivateConstructorSub))
+ return false;
+
+ PrivateConstructorSub inst = (PrivateConstructorSub) obj;
+ return inst.f1 == valueAfterConstructor
+ && inst.fsub == subValueAfterConstructor;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class ProtectedConstructor implements java.io.Serializable {
+ int f1;
+
+ static int valueAfterConstructor = 5;
+
+ protected ProtectedConstructor() {
+ f1 = valueAfterConstructor;
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. Is is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof ProtectedConstructor))
+ return false;
+
+ ProtectedConstructor inst = (ProtectedConstructor) obj;
+ return inst.f1 == valueAfterConstructor;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class ProtectedConstructorSub extends
+ NonSerProtectedConstructor implements java.io.Serializable {
+ int fsub;
+
+ static int subValueAfterConstructor = 11;
+
+ public ProtectedConstructorSub() {
+ f1 = 7;
+ fsub = subValueAfterConstructor;
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. Is is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof ProtectedConstructorSub))
+ return false;
+
+ ProtectedConstructorSub inst = (ProtectedConstructorSub) obj;
+ return inst.f1 == valueAfterConstructor
+ && inst.fsub == subValueAfterConstructor;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class PublicConstructor implements java.io.Serializable {
+ int f1;
+
+ static int valueAfterConstructor = 5;
+
+ public PublicConstructor() {
+ f1 = valueAfterConstructor;
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. Is is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof PublicConstructor))
+ return false;
+
+ PublicConstructor inst = (PublicConstructor) obj;
+ return inst.f1 == valueAfterConstructor;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------
+ private static class PublicConstructorSub extends NonSerPublicConstructor
+ implements java.io.Serializable {
+ int fsub;
+
+ static final int subValueAfterConstructor = 11;
+
+ public PublicConstructorSub() {
+ f1 = 7;
+ fsub = subValueAfterConstructor;
+ }
+
+ public boolean equals(Object obj) {
+ /*
+ * This method is not answering it the objs is equal. It is
+ * answering if the vars have the value that it have to have after
+ * dumping and loading
+ */
+
+ if (obj == null)
+ return false;
+ if (!(obj instanceof PublicConstructorSub))
+ return false;
+
+ PublicConstructorSub inst = (PublicConstructorSub) obj;
+ return inst.f1 == valueAfterConstructor
+ && inst.fsub == subValueAfterConstructor;
+ }
+ }
+
+ // Tests the behavior of ObjectOutputStream.PutField.write()
+ private static class WriteFieldsUsingPutFieldWrite implements
+ java.io.Serializable {
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("object1", Vector.class),
+ new ObjectStreamField("int1", Integer.TYPE) };
+
+ private static Vector v1 = new Vector<String>(Arrays.asList(new String[] {
+ "1st", "2nd" }));
+
+ private boolean passed = false;
+
+ public WriteFieldsUsingPutFieldWrite() {
+ super();
+ }
+
+ public boolean passed() {
+ return passed;
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, ClassNotFoundException {
+ int int1 = in.readInt();
+ Vector object1 = (Vector) in.readObject();
+ passed = int1 == 0xA9 && object1.equals(v1);
+ }
+
+ @SuppressWarnings("deprecation")
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException, ClassNotFoundException {
+ ObjectOutputStream.PutField fields = out.putFields();
+ fields.put("object1", v1);
+ fields.put("int1", 0xA9);
+ // Use fields.write() instead of out.writeFields();
+ fields.write(out);
+ }
+ }
+
+ public SerializationStressTest3(String name) {
+ super(name);
+ }
+
+ public void test_18_81_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(out);
+ new ObjectOutputStream(dos); // just to make sure we get a header
+ dos.writeByte(ObjectStreamConstants.TC_BLOCKDATALONG);
+ int length = 333; // Bigger than 1 byte
+ dos.writeInt(length);
+ for (int i = 0; i < length; i++) {
+ dos.writeByte(0); // actual value does not matter
+ }
+ dos.flush();
+ int lengthRead = 0;
+ try {
+ ObjectInputStream ois = new ObjectInputStream(
+ new ByteArrayInputStream(out.toByteArray()));
+ Object obj = ois.readObject();
+ } catch (OptionalDataException e) {
+ lengthRead = e.length;
+ }
+ assertTrue("Did not throw exception with optional data size ",
+ length == lengthRead);
+ } catch (ClassNotFoundException e) {
+ fail("Unable to read BLOCKDATA : " + e.getMessage());
+ } catch (IOException e) {
+ fail("IOException testing BLOCKDATALONG : " + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error " + err + " when testing BLOCKDATALONG");
+ throw err;
+ }
+ }
+
+ public void test_18_82_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ DefaultConstructor test = new DefaultConstructor();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_83_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ DefaultConstructorSub test = new DefaultConstructorSub();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_84_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ PrivateConstructor test = new PrivateConstructor();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_85_writeObject() throws Exception {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ PrivateConstructorSub test = new PrivateConstructorSub();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ try {
+ objLoaded = dumpAndReload(objToSave);
+ fail();
+ } catch (Exception expected) {
+ // It is an error to mark a class serializable if it derives
+ // from a non serializable class with an inaccessible constructor.
+ }
+ }
+
+ public void test_18_86_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ProtectedConstructor test = new ProtectedConstructor();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_87_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ ProtectedConstructorSub test = new ProtectedConstructorSub();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_88_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ PublicConstructor test = new PublicConstructor();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_89_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ PublicConstructorSub test = new PublicConstructorSub();
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_90_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = TABLE;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, TABLE.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_91_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.synchronizedMap(TABLE);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_92_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.unmodifiableMap(TABLE);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_93_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = MAP;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, MAP.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_94_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.synchronizedMap(MAP);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_95_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.unmodifiableMap(MAP);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_96_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = ALIST;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, ALIST.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_97_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = LIST;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, LIST.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_98_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.synchronizedList(LIST);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_99_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.unmodifiableList(LIST);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_100_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = SET;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, SET.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_101_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.synchronizedSet(SET);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_102_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.unmodifiableSet(SET);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_103_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = TREE;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, TREE.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_104_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.synchronizedSortedMap(TREE);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_105_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.unmodifiableSortedMap(TREE);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_106_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = SORTSET;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, SET.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_107_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.synchronizedSortedSet(SORTSET);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_108_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ Object col = Collections.unmodifiableSortedSet(SORTSET);
+ objToSave = col;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_109_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = CALENDAR;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, CALENDAR.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_110_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ TimeZone test = TimeZone.getTimeZone("EST");
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_111_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ TimeZone test = TimeZone.getTimeZone("EST");
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_112_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ TimeZone test = TimeZone.getTimeZone("GMT");
+ objToSave = test;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_113_writeObject() throws Exception {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ objToSave = DATEFORM;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertEquals(MSG_TEST_FAILED + objToSave, DATEFORM, objLoaded);
+ }
+
+ public void test_18_114_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = CHOICE;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, CHOICE.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_115_writeObject() throws Exception {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ objToSave = NUMBERFORM;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertEquals(MSG_TEST_FAILED + objToSave, NUMBERFORM, objLoaded);
+ }
+
+ public void test_18_116_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = MESSAGE;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, MESSAGE.toPattern().equals(
+ ((java.text.MessageFormat) objLoaded).toPattern()));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_119_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = Locale.CHINESE;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, Locale.CHINESE
+ .equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_120_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = LINKEDLIST;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, LINKEDLIST
+ .equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_121_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = java.text.AttributedCharacterIterator.Attribute.INPUT_METHOD_SEGMENT;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(
+ MSG_TEST_FAILED + objToSave,
+ java.text.AttributedCharacterIterator.Attribute.INPUT_METHOD_SEGMENT == objLoaded);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_122_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = java.text.AttributedCharacterIterator.Attribute.LANGUAGE;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(
+ MSG_TEST_FAILED + objToSave,
+ java.text.AttributedCharacterIterator.Attribute.LANGUAGE == objLoaded);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_123_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = java.text.AttributedCharacterIterator.Attribute.READING;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(
+ MSG_TEST_FAILED + objToSave,
+ java.text.AttributedCharacterIterator.Attribute.READING == objLoaded);
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_124_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = new Object[] { Integer.class, new Integer(1) };
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Classes with the same name are unique, so test for ==
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ ((Object[]) objLoaded)[0] == ((Object[]) objToSave)[0]
+ && ((Object[]) objLoaded)[1]
+ .equals(((Object[]) objToSave)[1]));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_125_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = new BigInteger[] { BigInteger.ZERO, BigInteger.ONE,
+ BigInteger.valueOf(-1), BigInteger.valueOf(255),
+ BigInteger.valueOf(-255),
+ new BigInteger("75881644843307850793466070"),
+ new BigInteger("-636104487142732527326202462") };
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (BigInteger[]) objLoaded, (BigInteger[]) objToSave));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_126_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = new WriteFieldsUsingPutFieldWrite();
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ ((WriteFieldsUsingPutFieldWrite) objLoaded).passed());
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_127_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ BitSet bs = new BitSet(64);
+ bs.set(1);
+ bs.set(10);
+ bs.set(100);
+ bs.set(1000);
+ objToSave = bs;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave, bs.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_18_128_writeObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ PropertyPermission test = new PropertyPermission("java.*",
+ "read,write");
+ PermissionCollection p = test.newPermissionCollection();
+ p.add(new PropertyPermission("java.*", "read"));
+ p.add(new PropertyPermission("java.*", "write"));
+ // System.out.println("Does implies work? " + p.implies(test));
+
+ objToSave = p;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ assertTrue(MSG_TEST_FAILED + objToSave,
+ ((PermissionCollection) objLoaded).implies(test));
+
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest4.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest4.java
new file mode 100644
index 0000000..c5dd4f0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationStressTest4.java
@@ -0,0 +1,1969 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import tests.support.Support_Proxy_I1;
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.NumberFormat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+import java.util.TimeZone;
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest4 extends SerializationStressTest {
+ // -----------------------------------------------------------------------------------
+ private static class GuardImplementation implements java.security.Guard,
+ java.io.Serializable {
+ public GuardImplementation() {
+ }
+
+ public void checkGuard(Object o) {
+ }
+ }
+
+ public SerializationStressTest4(String name) {
+ super(name);
+ }
+
+ public void test_writeObject_EventObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.EventObject)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.util.EventObject("Source");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = true;
+ // The the only data in EventObject that
+ // differentiates between instantiations is transient
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_Collections_EmptySet() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.EmptySet)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections.EMPTY_SET;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = objToSave.equals(objLoaded);
+ if (equals)
+ equals = ((Set) objLoaded).size() == 0;
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_EmptyMap() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.EmptySet)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections.EMPTY_MAP;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = objToSave.equals(objLoaded);
+ if (equals)
+ equals = ((Map) objLoaded).size() == 0;
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Character() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Character)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.lang.Character('c');
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_UnmodifiableCollection() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.UnmodifiableCollection)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = Collections.unmodifiableCollection(SET);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = ((java.util.Collection) objToSave).size() == ((java.util.Collection) objLoaded)
+ .size();
+ if (equals) {
+ java.util.Iterator iter1 = ((java.util.Collection) objToSave)
+ .iterator(), iter2 = ((java.util.Collection) objLoaded)
+ .iterator();
+ while (iter1.hasNext())
+ equals = equals && iter1.next().equals(iter2.next());
+ }
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Format() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.Format)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = null;
+ objToSave = new java.text.Format() {
+ String save = "default";
+
+ public StringBuffer format(Object p1, StringBuffer p2,
+ java.text.FieldPosition p3) {
+ return new StringBuffer();
+ }
+
+ public Object parseObject(String p1, java.text.ParsePosition p2) {
+ if (p1 != null)
+ save = p1;
+ return save;
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof java.text.Format))
+ return false;
+ return save.equals(((java.text.Format) obj).parseObject(
+ null, null));
+ }
+ };
+
+ ((java.text.Format) objToSave).parseObject("Test", null);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_BigDecimal() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.math.BigDecimal)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.math.BigDecimal("1.2345");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_SecureRandomSpi() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.security.SecureRandomSpi)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = null;
+ objToSave = new java.security.SecureRandomSpi() {
+ protected byte[] engineGenerateSeed(int p1) {
+ return new byte[0];
+ }
+
+ protected void engineNextBytes(byte[] p1) {
+ }
+
+ protected void engineSetSeed(byte[] p1) {
+ }
+
+ public boolean equals(Object obj) {
+ return true;
+ }
+ };
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_Short() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Short)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.lang.Short((short) 107);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Byte() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Byte)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.lang.Byte((byte) 107);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public void test_writeObject_String_CaseInsensitiveComparator() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.String.CaseInsensitiveComparator)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.lang.String.CASE_INSENSITIVE_ORDER;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = ((Comparator) objToSave).compare("apple", "Banana") == ((Comparator) objLoaded)
+ .compare("apple", "Banana");
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Calendar() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Calendar)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.util.Calendar(TimeZone.getTimeZone("EST"),
+ Locale.CANADA) {
+ public void add(int p1, int p2) {
+ }
+
+ protected void computeFields() {
+ }
+
+ protected void computeTime() {
+ }
+
+ public int getGreatestMinimum(int p1) {
+ return 0;
+ }
+
+ public int getLeastMaximum(int p1) {
+ return 0;
+ }
+
+ public int getMaximum(int p1) {
+ return 0;
+ }
+
+ public int getMinimum(int p1) {
+ return 0;
+ }
+
+ public void roll(int p1, boolean p2) {
+ }
+ };
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + "Calendar", objToSave
+ .equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_StringBuffer() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.StringBuffer)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.lang.StringBuffer("This is a test.");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = ((java.lang.StringBuffer) objToSave).toString().equals(
+ ((java.lang.StringBuffer) objLoaded).toString());
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_File() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.io.File)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new File("afile.txt");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_BitSet() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.BitSet)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.util.BitSet();
+ ((java.util.BitSet) objToSave).set(3);
+ ((java.util.BitSet) objToSave).set(5);
+ ((java.util.BitSet) objToSave).set(61, 89);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_DateFormat() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.DateFormat)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = null;
+ objToSave = new java.text.DateFormat() {
+ // Thu Feb 01 01:01:01 EST 2001
+ java.util.Date save = new java.util.Date(981007261000L);
+
+ public StringBuffer format(Date p1, StringBuffer p2,
+ java.text.FieldPosition p3) {
+ if (p1 != null)
+ save = p1;
+ return new StringBuffer(Long.toString(save.getTime()));
+ }
+
+ public Date parse(String p1, java.text.ParsePosition p2) {
+ return save;
+ }
+
+ public String toString() {
+ return save.toString();
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof java.text.DateFormat))
+ return false;
+ return save.equals(((java.text.DateFormat) obj).parse(null,
+ null));
+ }
+ };
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_CopiesList() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.CopiesList)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections.nCopies(2, new Integer(2));
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = ((List) objToSave).get(0)
+ .equals(((List) objLoaded).get(0));
+ if (equals)
+ equals = ((List) objToSave).get(1).equals(
+ ((List) objLoaded).get(1));
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Properties() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Properties)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.util.Properties();
+ ((java.util.Properties) objToSave).put("key1", "value1");
+ ((java.util.Properties) objToSave).put("key2", "value2");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ Enumeration enum1 = ((java.util.Properties) objToSave).elements(), enum2 = ((java.util.Properties) objLoaded)
+ .elements();
+
+ equals = true;
+ while (enum1.hasMoreElements() && equals) {
+ if (enum2.hasMoreElements())
+ equals = enum1.nextElement().equals(enum2.nextElement());
+ else
+ equals = false;
+ }
+
+ if (equals)
+ equals = !enum2.hasMoreElements();
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_NumberFormat() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.NumberFormat)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = null;
+ objToSave = new java.text.NumberFormat() {
+ long save = 107;
+
+ public StringBuffer format(double p1, StringBuffer p2,
+ java.text.FieldPosition p3) {
+ return new StringBuffer();
+ }
+
+ public StringBuffer format(long p1, StringBuffer p2,
+ java.text.FieldPosition p3) {
+ if (p1 != 0)
+ save = p1;
+ return new StringBuffer(Long.toString(save));
+ }
+
+ public Number parse(String p1, java.text.ParsePosition p2) {
+ return new Long(save);
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof java.text.NumberFormat))
+ return false;
+ return save == ((Long) ((java.text.NumberFormat) obj)
+ .parse(null, null)).longValue();
+ }
+ };
+
+ ((java.text.NumberFormat) objToSave).format(63L, null, null);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_TimeZone() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.TimeZone)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = null;
+ objToSave = new java.util.TimeZone() {
+ int save = 0;
+
+ public int getOffset(int p1, int p2, int p3, int p4, int p5,
+ int p6) {
+ return 0;
+ }
+
+ public int getRawOffset() {
+ return save;
+ }
+
+ public boolean inDaylightTime(java.util.Date p1) {
+ return false;
+ }
+
+ public void setRawOffset(int p1) {
+ save = p1;
+ }
+
+ public boolean useDaylightTime() {
+ return false;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof TimeZone)
+ return save == ((TimeZone) obj).getRawOffset();
+ return false;
+ }
+ };
+
+ ((java.util.TimeZone) objToSave).setRawOffset(48);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Double() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Double)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.lang.Double(1.23);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Number() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Number)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = null;
+ objToSave = new Number() {
+ int numCalls = 0;
+
+ public double doubleValue() {
+ return ++numCalls;
+ }
+
+ public float floatValue() {
+ return ++numCalls;
+ }
+
+ public int intValue() {
+ return numCalls;
+ }
+
+ public long longValue() {
+ return ++numCalls;
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof java.lang.Number))
+ return false;
+ return intValue() == ((Number) obj).intValue();
+ }
+ };
+ ((java.lang.Number) objToSave).doubleValue();
+ ((java.lang.Number) objToSave).floatValue();
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_ReverseComparator() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.ReverseComparator)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections.reverseOrder();
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = ((Comparator) objToSave).compare("Hello", "Jello") == ((Comparator) objLoaded)
+ .compare("Hello", "Jello");
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("IOException serializing " + objToSave + " : "
+ + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type : "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_DateFormatSymbols() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.DateFormatSymbols)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.text.DateFormatSymbols(Locale.CHINESE);
+ ((java.text.DateFormatSymbols) objToSave)
+ .setZoneStrings(new String[][] { { "a", "b", "c", "d", "e" },
+ { "e", "f", "g", "h", "i" } });
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_EmptyList() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.EmptyList)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections.EMPTY_LIST;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = objToSave.equals(objLoaded);
+ if (equals)
+ equals = ((List) objLoaded).size() == 0;
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Boolean() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Boolean)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.lang.Boolean(true);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_SingletonSet() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.SingletonSet)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections.singleton(new Byte((byte) 107));
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ java.util.Iterator iter = ((Set) objLoaded).iterator();
+ equals = iter.hasNext();
+ if (equals)
+ equals = iter.next().equals(new Byte((byte) 107));
+ if (equals)
+ equals = !iter.hasNext();
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_SingletonList() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.SingletonSet)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections
+ .singletonList(new Byte((byte) 107));
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ java.util.Iterator iter = ((List) objLoaded).iterator();
+ equals = objLoaded.equals(objToSave) && iter.hasNext()
+ && iter.next().equals(new Byte((byte) 107))
+ && !iter.hasNext();
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_SingletonMap() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.SingletonSet)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections.singletonMap("key", new Byte(
+ (byte) 107));
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ java.util.Iterator iter = ((Map) objLoaded).entrySet().iterator();
+ equals = objLoaded.equals(objToSave) && iter.hasNext();
+ Map.Entry entry = (Map.Entry) iter.next();
+ equals = equals && entry.getKey().equals("key")
+ && entry.getValue().equals(new Byte((byte) 107))
+ && !iter.hasNext();
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_SecureRandom() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.security.SecureRandom)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.security.SecureRandom();
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = true; // assume fine because of the nature of the class,
+ // it is difficult to determine if they are the same
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_InetAddress() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.net.InetAddress)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.net.InetAddress.getByName("127.0.0.1");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Inet6Address() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.net.Inet6Address)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.net.Inet6Address.getByName("fe80::20d:60ff:fe24:7410");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Date() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Date)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ // Thu Feb 01 01:01:01 EST 2001
+ objToSave = new java.util.Date(981007261000L);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Float() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Float)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.lang.Float(1.23f);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Stack() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Stack)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.util.Stack();
+ ((Stack) objToSave).push("String 1");
+ ((Stack) objToSave).push("String 2");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = true;
+ while (!((java.util.Stack) objToSave).empty() && equals) {
+ if (!((java.util.Stack) objLoaded).empty())
+ equals = ((java.util.Stack) objToSave).pop().equals(
+ ((java.util.Stack) objLoaded).pop());
+ else
+ equals = false;
+ }
+
+ if (equals)
+ equals = ((java.util.Stack) objLoaded).empty();
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_DecimalFormatSymbols() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.DecimalFormatSymbols)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.text.DecimalFormatSymbols(Locale.CHINESE);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_AttributedCharacterIterator_Attribute() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.AttributedCharacterIterator.Attribute)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.text.AttributedCharacterIterator.Attribute.LANGUAGE;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_Long() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Long)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.lang.Long(107L);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Collections_SynchronizedCollection() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Collections.SynchronizedCollection)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Collections.synchronizedCollection(SET);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = ((java.util.Collection) objToSave).size() == ((java.util.Collection) objLoaded)
+ .size();
+ if (equals) {
+ java.util.Iterator iter1 = ((java.util.Collection) objToSave)
+ .iterator(), iter2 = ((java.util.Collection) objLoaded)
+ .iterator();
+ while (iter1.hasNext())
+ equals = equals && iter1.next().equals(iter2.next());
+ }
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Random() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Random)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.util.Random(107L);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = ((java.util.Random) objToSave).nextInt() == ((java.util.Random) objLoaded)
+ .nextInt();
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_GuardedObject() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.security.GuardedObject)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = new java.security.GuardedObject("Test Object",
+ new GuardImplementation());
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ boolean equals;
+ equals = ((java.security.GuardedObject) objToSave).getObject()
+ .equals(
+ ((java.security.GuardedObject) objLoaded)
+ .getObject());
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ // TODO : Reintroduce when we have a working security implementation
+ // public void test_writeObject_KeyPair() {
+ // // Test for method void
+ // // java.io.ObjectOutputStream.writeObject(java.security.GuardedObject)
+ //
+ // Object objToSave = null;
+ // Object objLoaded = null;
+ //
+ // try {
+ // objToSave = new java.security.KeyPair(null, null);
+ // if (DEBUG)
+ // System.out.println("Obj = " + objToSave);
+ // objLoaded = dumpAndReload(objToSave);
+ //
+ // // Has to have worked
+ // boolean equals;
+ // equals = true;
+ // assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ // } catch (IOException e) {
+ // fail("IOException serializing " + objToSave + " : "
+ // + e.getMessage());
+ // } catch (ClassNotFoundException e) {
+ // fail("ClassNotFoundException reading Object type : " + e.getMessage());
+ // } catch (Error err) {
+ // System.out.println("Error when obj = " + objToSave);
+ // // err.printStackTrace();
+ // throw err;
+ // }
+ // }
+
+ static class MyInvocationHandler implements InvocationHandler, Serializable {
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ if (method.getName().equals("equals"))
+ return new Boolean(proxy == args[0]);
+ if (method.getName().equals("array"))
+ return new int[] { (int) ((long[]) args[0])[1], -1 };
+ if (method.getName().equals("string")) {
+ if ("error".equals(args[0]))
+ throw new ArrayStoreException();
+ if ("any".equals(args[0]))
+ throw new IllegalAccessException();
+ }
+ return null;
+ }
+ }
+
+ public void test_writeObject_Proxy() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.security.GuardedObject)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = Proxy.getProxyClass(Support_Proxy_I1.class
+ .getClassLoader(), new Class[] { Support_Proxy_I1.class });
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ assertTrue(MSG_TEST_FAILED + "not a proxy class", Proxy
+ .isProxyClass((Class) objLoaded));
+ Class[] interfaces = ((Class) objLoaded).getInterfaces();
+ assertTrue(MSG_TEST_FAILED + "wrong interfaces length",
+ interfaces.length == 1);
+ assertTrue(MSG_TEST_FAILED + "wrong interface",
+ interfaces[0] == Support_Proxy_I1.class);
+
+ InvocationHandler handler = new MyInvocationHandler();
+ objToSave = Proxy.newProxyInstance(Support_Proxy_I1.class
+ .getClassLoader(), new Class[] { Support_Proxy_I1.class },
+ handler);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ boolean equals = Proxy.getInvocationHandler(objLoaded).getClass() == MyInvocationHandler.class;
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_URI() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.net.URI)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ try {
+ objToSave = new URI[] {
+ // single arg constructor
+ new URI(
+ "http://user%60%20info@host/a%20path?qu%60%20ery#fr%5E%20ag"),
+ // escaped octets for illegal chars
+ new URI(
+ "http://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g"),
+ // escaped octets for unicode chars
+ new URI(
+ "ascheme://user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery#fr\u00E4\u00E8g"),
+ // multiple arg constructors
+ new URI("http", "user%60%20info", "host", 80,
+ "/a%20path", "qu%60%20ery", "fr%5E%20ag"),
+ // escaped octets for illegal
+ new URI("http", "user%C3%9F%C2%A3info", "host", -1,
+ "/a%E2%82%ACpath", "qu%C2%A9%C2%AEery",
+ "fr%C3%A4%C3%A8g"),
+ // escaped octets for unicode
+ new URI("ascheme", "user\u00DF\u00A3info", "host", 80,
+ "/a\u20ACpath", "qu\u00A9\u00AEery",
+ "fr\u00E4\u00E8g"),
+ new URI("http", "user` info", "host", 81, "/a path",
+ "qu` ery", "fr^ ag"), // illegal chars
+ new URI("http", "user%info", "host", 0, "/a%path",
+ "que%ry", "f%rag"),
+ // % as illegal char, not escaped octet urls with
+ // undefined components
+ new URI("mailto", "user@domain.com", null),
+ // no host, path, query or fragment
+ new URI("../adirectory/file.html#"),
+ // relative path with empty fragment;
+ new URI("news", "comp.infosystems.www.servers.unix",
+ null),
+ new URI(null, null, null, "fragment"),
+ // only fragment
+ new URI("telnet://server.org"), // only host
+ new URI("http://reg:istry?query"),
+ // malformed hostname, therefore registry-based,
+ // with query
+ new URI("file:///c:/temp/calculate.pl?")
+ // empty authority, non empty path, empty query
+ };
+ } catch (URISyntaxException e) {
+ fail("Unexpected Exception:" + e);
+ }
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+ (URI[]) objToSave, (URI[]) objLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_URISyntaxException() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.net.URISyntaxException)
+
+ URISyntaxException objToSave = null;
+ URISyntaxException objLoaded = null;
+
+ try {
+ objToSave = new URISyntaxException("str", "problem", 4);
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = (URISyntaxException) dumpAndReload(objToSave);
+
+ boolean equals = objToSave.getMessage().equals(
+ objLoaded.getMessage())
+ && objToSave.getInput().equals(objLoaded.getInput())
+ && objToSave.getIndex() == objLoaded.getIndex()
+ && objToSave.getReason().equals(objLoaded.getReason());
+
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, equals);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+
+ }
+
+ public void test_writeObject_Currency() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.util.Currency)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = java.util.Currency.getInstance("AMD");
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ // we need same instance for the same currency code
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave == objToSave);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_DateFormat_Field() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.DateFormat.Field)
+
+ DateFormat.Field[] objToSave = null;
+ DateFormat.Field[] objLoaded = null;
+
+ try {
+ objToSave = new DateFormat.Field[] { DateFormat.Field.AM_PM,
+ DateFormat.Field.DAY_OF_MONTH, DateFormat.Field.ERA,
+ DateFormat.Field.HOUR0, DateFormat.Field.HOUR1,
+ DateFormat.Field.HOUR_OF_DAY0,
+ DateFormat.Field.HOUR_OF_DAY1, DateFormat.Field.TIME_ZONE,
+ DateFormat.Field.YEAR,
+ DateFormat.Field.DAY_OF_WEEK_IN_MONTH };
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+
+ objLoaded = (DateFormat.Field[]) dumpAndReload(objToSave);
+
+ // Has to have worked
+ // we need same instances for the same field names
+ for (int i = 0; i < objToSave.length; i++) {
+ assertTrue(MSG_TEST_FAILED + objToSave[i],
+ objToSave[i] == objLoaded[i]);
+ }
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_NumberFormat_Field() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.NumberFormat.Field)
+
+ NumberFormat.Field[] objToSave = null;
+ NumberFormat.Field[] objLoaded = null;
+
+ try {
+ objToSave = new NumberFormat.Field[] { NumberFormat.Field.CURRENCY,
+ NumberFormat.Field.DECIMAL_SEPARATOR,
+ NumberFormat.Field.EXPONENT,
+ NumberFormat.Field.EXPONENT_SIGN,
+ NumberFormat.Field.EXPONENT_SYMBOL,
+ NumberFormat.Field.FRACTION,
+ NumberFormat.Field.GROUPING_SEPARATOR,
+ NumberFormat.Field.INTEGER, NumberFormat.Field.PERCENT,
+ NumberFormat.Field.PERMILLE, NumberFormat.Field.SIGN };
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+
+ objLoaded = (NumberFormat.Field[]) dumpAndReload(objToSave);
+
+ // Has to have worked
+ // we need same instances for the same field names
+ for (int i = 0; i < objToSave.length; i++) {
+ assertTrue(MSG_TEST_FAILED + objToSave[i],
+ objToSave[i] == objLoaded[i]);
+ }
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_MessageFormat_Field() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.text.MessageFormat.Field)
+
+ Object objToSave = null;
+ Object objLoaded = null;
+
+ try {
+ objToSave = MessageFormat.Field.ARGUMENT;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+
+ objLoaded = dumpAndReload(objToSave);
+
+ // Has to have worked
+ // we need same instance for the same field name
+ assertTrue(MSG_TEST_FAILED + objToSave, objToSave == objLoaded);
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_LinkedHashMap() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = LINKEDMAP;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, LINKEDMAP.equals(objLoaded));
+
+ Map mapLoaded = (Map) objLoaded;
+ Iterator loadedIterator = mapLoaded.keySet().iterator();
+ Iterator iterator = LINKEDMAP.keySet().iterator();
+ while (loadedIterator.hasNext()) {
+ assertTrue("invalid iterator order", loadedIterator.next()
+ .equals(iterator.next()));
+ }
+ assertTrue("invalid iterator size", !iterator.hasNext());
+
+ loadedIterator = mapLoaded.entrySet().iterator();
+ iterator = LINKEDMAP.entrySet().iterator();
+ while (loadedIterator.hasNext()) {
+ assertTrue("invalid entry set iterator order", loadedIterator
+ .next().equals(iterator.next()));
+ }
+ assertTrue("invalid entry set iterator size", !iterator.hasNext());
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_LinkedHashSet() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ Object objToSave = null;
+ Object objLoaded;
+
+ try {
+ objToSave = LINKEDSET;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = dumpAndReload(objToSave);
+ // Has to have worked
+ assertTrue(MSG_TEST_FAILED + objToSave, LINKEDSET.equals(objLoaded));
+
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+
+ public void test_writeObject_IdentityHashMap() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+ IdentityHashMap objToSave = null;
+ IdentityHashMap objLoaded;
+
+ try {
+ objToSave = IDENTITYMAP;
+ if (DEBUG)
+ System.out.println("Obj = " + objToSave);
+ objLoaded = (IdentityHashMap) dumpAndReload(objToSave);
+ // Has to have worked
+
+ // a serialized identity hash map will not be equal to its original
+ // because it is an "identity" mapping,
+ // so we simply check for the usual meaning of equality
+
+ assertEquals(
+ "Loaded IdentityHashMap is not of the same size as the saved one.",
+ objToSave.size(), objLoaded.size());
+ HashMap duplicateSaved = new HashMap();
+ duplicateSaved.putAll(objToSave);
+ HashMap duplicateLoaded = new HashMap();
+ duplicateLoaded.putAll(objLoaded);
+ assertTrue(MSG_TEST_FAILED + duplicateSaved, duplicateSaved
+ .equals(duplicateLoaded));
+ } catch (IOException e) {
+ fail("Exception serializing " + objToSave + " : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException reading Object type: "
+ + e.getMessage());
+ } catch (Error err) {
+ System.out.println("Error when obj = " + objToSave);
+ // err.printStackTrace();
+ throw err;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationTestClass.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationTestClass.java
new file mode 100644
index 0000000..e15a978
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SerializationTestClass.java
@@ -0,0 +1,337 @@
+package org.apache.harmony.tests.java.io;
+
+/**
+ * Test classes for {@link ComputeSerialVersionUIDTest}. Used to ensure
+ * that serial version UIDs are generated correctly for various combinations
+ * of interfaces, fields, constructors and methods.
+ */
+public class SerializationTestClass implements java.io.Serializable {
+
+ // Test class names
+ public static class TestClassName1 implements java.io.Serializable {
+ }
+
+ public static class TestClassName2T_T$T implements java.io.Serializable {
+ }
+
+ // Test Modifiers
+ public static class TestClassModifierPublic implements java.io.Serializable {
+ }
+
+ interface TestClassModifierInterfaceHelper extends java.io.Serializable {
+ }
+
+ public static class TestClassModifierInterface implements
+ TestClassModifierInterfaceHelper {
+ }
+
+ final static class TestClassModifierFinal implements java.io.Serializable {
+ }
+
+ abstract static class TestClassModifierAbstractHelper implements
+ java.io.Serializable {
+ }
+
+ public static class TestClassModifierAbstract extends
+ TestClassModifierAbstractHelper {
+ }
+
+
+ // TODO Arrays always are abstract
+
+ // TODO Non public interface has no abstract modifier
+
+
+ // Test interfaces
+ interface A extends java.io.Serializable {
+ }
+
+ interface B extends java.io.Serializable {
+ }
+
+ interface C extends A {
+ }
+
+ public static class TestInterfaces implements java.io.Serializable {
+ }
+
+ public static class TestInterfacesA implements A {
+ }
+
+ public static class TestInterfacesAB implements A, B {
+ }
+
+ public static class TestInterfacesBA implements B, A {
+ }
+
+ public static class TestInterfacesC implements C {
+ }
+
+ public static class TestInterfacesCA implements C, A {
+ }
+
+ public static class TestInterfacesABC implements A, B, C {
+ }
+
+ public static class TestInterfacesACB implements A, C, B {
+ }
+
+ public static class TestInterfacesBAC implements B, A, C {
+ }
+
+ public static class TestInterfacesBCA implements B, C, A {
+ }
+
+ public static class TestInterfacesCAB implements C, A, B {
+ }
+
+ public static class TestInterfacesCBA implements C, B, A {
+ }
+
+ /**
+ * Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.STATIC |
+ * Modifier.FINAL | Modifier.VOLATILE | Modifier.TRANSIENT
+ */
+ // Test Fields
+ public static class TestFieldsNone implements java.io.Serializable {
+ }
+
+ public static class TestFieldsOnePublic implements java.io.Serializable {
+ public int one;
+ }
+
+ public static class TestFieldsTwoPublic implements java.io.Serializable {
+ public int one;
+ public int two;
+ }
+
+ @SuppressWarnings("unused")
+ public static class TestFieldsOnePrivate implements java.io.Serializable {
+ private int one;
+ }
+
+ @SuppressWarnings("unused")
+ public static class TestFieldsTwoPrivate implements java.io.Serializable {
+ private int one;
+ private int two;
+ }
+
+ public static class TestFieldsOneProtected implements java.io.Serializable {
+ protected int one;
+ }
+
+ public static class TestFieldsTwoProtected implements java.io.Serializable {
+ protected int one;
+ protected int two;
+ }
+
+ public static class TestFieldsOneStatic implements java.io.Serializable {
+ static int one;
+ }
+
+ public static class TestFieldsTwoStatic implements java.io.Serializable {
+ static int one;
+ static int two;
+ }
+
+ public static class TestFieldsOneFinal implements java.io.Serializable {
+ final int one = 0;
+ }
+
+ public static class TestFieldsTwoFinal implements java.io.Serializable {
+ final int one = 0;
+ final int two = 0;
+ }
+
+ public static class TestFieldsOneVolatile implements java.io.Serializable {
+ volatile int one;
+ }
+
+ public static class TestFieldsTwoVolatile implements java.io.Serializable {
+ volatile int one;
+ volatile int two;
+ }
+
+ public static class TestFieldsOneTransient implements java.io.Serializable {
+ transient int one;
+ }
+
+ public static class TestFieldsTwoTransient implements java.io.Serializable {
+ transient int one;
+ transient int two;
+ }
+
+ public static class TestFieldSignatures implements java.io.Serializable {
+ Object l;
+ int i;
+ short s;
+ long j;
+ boolean z;
+ char c;
+ double d;
+ float f;
+ byte b;
+ }
+
+
+ // Test Constructors
+ public static class TestConstructorNone implements java.io.Serializable {
+ }
+
+ public static class TestConstructorOne implements java.io.Serializable {
+ public TestConstructorOne() {
+ }
+ }
+
+ public static class TestConstructorTwo implements java.io.Serializable {
+ public TestConstructorTwo(byte b) {
+ }
+
+ public TestConstructorTwo(char c) {
+ }
+ }
+
+ public static class TestConstructorTwoReverse implements java.io.Serializable {
+ public TestConstructorTwoReverse(char c) {
+ }
+
+ public TestConstructorTwoReverse(byte b) {
+ }
+ }
+
+
+ // Test Constructor Modifiers
+ public static class TestConstructorPublic implements java.io.Serializable {
+ public TestConstructorPublic() {
+ }
+ }
+
+ public static class TestConstructorPrivate implements java.io.Serializable {
+ private TestConstructorPrivate() {
+ }
+
+ public TestConstructorPrivate(int i) {
+ this();
+ }
+ }
+
+ public static class TestConstructorProtected implements java.io.Serializable {
+ protected TestConstructorProtected() {
+ }
+ }
+ // TODO constructor modifier strict?
+ // TODO constructor modifier static?
+ // TODO constructor modifier final?
+ // TODO constructor modifier synchronized?
+ // TODO constructor modifier native?
+ // TODO constructor modifier abstract?
+
+
+ // Test constructor signature
+ public static class TestConstructorSignature implements java.io.Serializable {
+ public TestConstructorSignature(boolean z, byte b, char c, short s,
+ int i, float f, double j, Object l) {
+ }
+ }
+
+
+ // Test Method Modifiers
+ public static class TestMethodPublic implements java.io.Serializable {
+ public void method() {
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public static class TestMethodPrivate implements java.io.Serializable {
+ private void method() {
+ }
+ }
+
+ public static class TestMethodProtected implements java.io.Serializable {
+ protected void method() {
+ }
+ }
+
+ public static class TestMethodStrict implements java.io.Serializable {
+ strictfp void method() {
+ }
+ }
+
+ public static class TestMethodStatic implements java.io.Serializable {
+ static void method() {
+ }
+ }
+
+ public static class TestMethodFinal implements java.io.Serializable {
+ final void method() {
+ }
+ }
+
+ public static class TestMethodSynchronized implements java.io.Serializable {
+ synchronized void method() {
+ }
+ }
+
+ public static class TestMethodNative implements java.io.Serializable {
+ native void method();
+ }
+
+ public static abstract class TestMethodAbstractHelper implements
+ java.io.Serializable {
+ abstract void method();
+ }
+
+ public static class TestMethodAbstract extends TestMethodAbstractHelper implements
+ java.io.Serializable {
+ @Override
+ void method() {
+ }
+ }
+
+
+ // Test method signature
+ public static class TestMethodSignature implements java.io.Serializable {
+ public void method(boolean z, byte b, char c, short s, int i, float f,
+ double j, Object l) {
+ }
+ }
+
+
+ // Test method return signature
+ public static class TestMethodReturnSignature implements java.io.Serializable {
+ public void methodV() {
+ }
+
+ public boolean methodZ() {
+ return false;
+ }
+
+ public byte methodB() {
+ return 0;
+ }
+
+ public char methodC() {
+ return '0';
+ }
+
+ public short methodS() {
+ return 0;
+ }
+
+ public int methodI() {
+ return 0;
+ }
+
+ public float methodF() {
+ return 0F;
+ }
+
+ public double methodD() {
+ return 0D;
+ }
+
+ public Object methodL() {
+ return null;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StreamCorruptedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StreamCorruptedExceptionTest.java
new file mode 100644
index 0000000..e9e6a70
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StreamCorruptedExceptionTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.io.StreamCorruptedException;
+
+public class StreamCorruptedExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.io.StreamCorruptedException#StreamCorruptedException()
+ */
+ public void test_Constructor() throws Exception {
+ // Test for method java.io.StreamCorruptedException()
+
+ try {
+ ObjectInputStream ois = new ObjectInputStream(
+ new ByteArrayInputStream(
+ "kLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLl"
+ .getBytes()));
+ ois.readObject();
+ } catch (StreamCorruptedException e) {
+ // Correct
+ return;
+ }
+
+ fail("Failed to throw StreamCorruptedException for non serialized stream");
+ }
+
+ /**
+ * java.io.StreamCorruptedException#StreamCorruptedException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws Exception {
+ // Test for method java.io.StreamCorruptedException(java.lang.String)
+ try {
+ ObjectInputStream ois = new ObjectInputStream(
+ new ByteArrayInputStream(
+ "kLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLl"
+ .getBytes()));
+ ois.readObject();
+ } catch (StreamCorruptedException e) {
+ // Correct
+ return;
+ }
+
+ fail("Failed to throw StreamCorruptedException for non serialized stream");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StreamTokenizerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StreamTokenizerTest.java
new file mode 100644
index 0000000..f4d4401
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StreamTokenizerTest.java
@@ -0,0 +1,448 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.Reader;
+import java.io.StreamTokenizer;
+import java.io.StringBufferInputStream;
+
+import tests.support.Support_StringReader;
+
+public class StreamTokenizerTest extends junit.framework.TestCase {
+ Support_StringReader r;
+
+ StreamTokenizer st;
+
+ String testString;
+
+ /**
+ * java.io.StreamTokenizer#StreamTokenizer(java.io.InputStream)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_ConstructorLjava_io_InputStream() throws IOException {
+ st = new StreamTokenizer(new StringBufferInputStream(
+ "/comments\n d 8 'h'"));
+
+ assertEquals("the next token returned should be the letter d",
+ StreamTokenizer.TT_WORD, st.nextToken());
+ assertEquals("the next token returned should be the letter d",
+ "d", st.sval);
+
+ assertEquals("the next token returned should be the digit 8",
+ StreamTokenizer.TT_NUMBER, st.nextToken());
+ assertEquals("the next token returned should be the digit 8",
+ 8.0, st.nval);
+
+ assertEquals("the next token returned should be the quote character",
+ 39, st.nextToken());
+ assertEquals("the next token returned should be the quote character",
+ "h", st.sval);
+ }
+
+ /**
+ * java.io.StreamTokenizer#StreamTokenizer(java.io.Reader)
+ */
+ public void test_ConstructorLjava_io_Reader() throws IOException {
+ setTest("/testing\n d 8 'h' ");
+ assertEquals("the next token returned should be the letter d skipping the comments",
+ StreamTokenizer.TT_WORD, st.nextToken());
+ assertEquals("the next token returned should be the letter d",
+ "d", st.sval);
+
+ assertEquals("the next token returned should be the digit 8",
+ StreamTokenizer.TT_NUMBER, st.nextToken());
+ assertEquals("the next token returned should be the digit 8",
+ 8.0, st.nval);
+
+ assertEquals("the next token returned should be the quote character",
+ 39, st.nextToken());
+ assertEquals("the next token returned should be the quote character",
+ "h", st.sval);
+ }
+
+ /**
+ * java.io.StreamTokenizer#commentChar(int)
+ */
+ public void test_commentCharI() throws IOException {
+ setTest("*comment \n / 8 'h' ");
+ st.ordinaryChar('/');
+ st.commentChar('*');
+ assertEquals("nextToken() did not return the character / skiping the comments starting with *",
+ 47, st.nextToken());
+ assertTrue("the next token returned should be the digit 8", st
+ .nextToken() == StreamTokenizer.TT_NUMBER
+ && st.nval == 8.0);
+ assertTrue("the next token returned should be the quote character",
+ st.nextToken() == 39 && st.sval.equals("h"));
+ }
+
+ /**
+ * java.io.StreamTokenizer#eolIsSignificant(boolean)
+ */
+ public void test_eolIsSignificantZ() throws IOException {
+ setTest("d 8\n");
+ // by default end of line characters are not significant
+ assertTrue("nextToken did not return d",
+ st.nextToken() == StreamTokenizer.TT_WORD
+ && st.sval.equals("d"));
+ assertTrue("nextToken did not return 8",
+ st.nextToken() == StreamTokenizer.TT_NUMBER
+ && st.nval == 8.0);
+ assertTrue("nextToken should be the end of file",
+ st.nextToken() == StreamTokenizer.TT_EOF);
+ setTest("d\n");
+ st.eolIsSignificant(true);
+ // end of line characters are significant
+ assertTrue("nextToken did not return d",
+ st.nextToken() == StreamTokenizer.TT_WORD
+ && st.sval.equals("d"));
+ assertTrue("nextToken is the end of line",
+ st.nextToken() == StreamTokenizer.TT_EOL);
+ }
+
+ /**
+ * java.io.StreamTokenizer#lineno()
+ */
+ public void test_lineno() throws IOException {
+ setTest("d\n 8\n");
+ assertEquals("the lineno should be 1", 1, st.lineno());
+ st.nextToken();
+ st.nextToken();
+ assertEquals("the lineno should be 2", 2, st.lineno());
+ st.nextToken();
+ assertEquals("the next line no should be 3", 3, st.lineno());
+ }
+
+ /**
+ * java.io.StreamTokenizer#lowerCaseMode(boolean)
+ */
+ public void test_lowerCaseModeZ() throws Exception {
+ // SM.
+ setTest("HELLOWORLD");
+ st.lowerCaseMode(true);
+
+ st.nextToken();
+ assertEquals("sval not converted to lowercase.", "helloworld", st.sval
+ );
+ }
+
+ /**
+ * java.io.StreamTokenizer#nextToken()
+ */
+ @SuppressWarnings("deprecation")
+ public void test_nextToken() throws IOException {
+ // SM.
+ setTest("\r\n/* fje fje 43.4 f \r\n f g */ 456.459 \r\n"
+ + "Hello / \r\n \r\n \n \r \257 Hi \'Hello World\'");
+ st.ordinaryChar('/');
+ st.slashStarComments(true);
+ st.nextToken();
+ assertTrue("Wrong Token type1: " + (char) st.ttype,
+ st.ttype == StreamTokenizer.TT_NUMBER);
+ st.nextToken();
+ assertTrue("Wrong Token type2: " + st.ttype,
+ st.ttype == StreamTokenizer.TT_WORD);
+ st.nextToken();
+ assertTrue("Wrong Token type3: " + st.ttype, st.ttype == '/');
+ st.nextToken();
+ assertTrue("Wrong Token type4: " + st.ttype,
+ st.ttype == StreamTokenizer.TT_WORD);
+ st.nextToken();
+ assertTrue("Wrong Token type5: " + st.ttype,
+ st.ttype == StreamTokenizer.TT_WORD);
+ st.nextToken();
+ assertTrue("Wrong Token type6: " + st.ttype, st.ttype == '\'');
+ assertTrue("Wrong Token type7: " + st.ttype, st.sval
+ .equals("Hello World"));
+ st.nextToken();
+ assertTrue("Wrong Token type8: " + st.ttype, st.ttype == -1);
+
+ final PipedInputStream pin = new PipedInputStream();
+ PipedOutputStream pout = new PipedOutputStream(pin);
+ pout.write("hello\n\r\r".getBytes("UTF-8"));
+ StreamTokenizer s = new StreamTokenizer(pin);
+ s.eolIsSignificant(true);
+ assertTrue("Wrong token 1,1",
+ s.nextToken() == StreamTokenizer.TT_WORD
+ && s.sval.equals("hello"));
+ assertTrue("Wrong token 1,2", s.nextToken() == '\n');
+ assertTrue("Wrong token 1,3", s.nextToken() == '\n');
+ assertTrue("Wrong token 1,4", s.nextToken() == '\n');
+ pout.close();
+ assertTrue("Wrong token 1,5",
+ s.nextToken() == StreamTokenizer.TT_EOF);
+ StreamTokenizer tokenizer = new StreamTokenizer(
+ new Support_StringReader("\n \r\n#"));
+ tokenizer.ordinaryChar('\n'); // make \n ordinary
+ tokenizer.eolIsSignificant(true);
+ assertTrue("Wrong token 2,1", tokenizer.nextToken() == '\n');
+ assertTrue("Wrong token 2,2", tokenizer.nextToken() == '\n');
+ assertEquals("Wrong token 2,3", '#', tokenizer.nextToken());
+ }
+
+ /**
+ * java.io.StreamTokenizer#ordinaryChar(int)
+ */
+ public void test_ordinaryCharI() throws IOException {
+ // SM.
+ setTest("Ffjein 893");
+ st.ordinaryChar('F');
+ st.nextToken();
+ assertTrue("OrdinaryChar failed." + (char) st.ttype,
+ st.ttype == 'F');
+ }
+
+ /**
+ * java.io.StreamTokenizer#ordinaryChars(int, int)
+ */
+ public void test_ordinaryCharsII() throws IOException {
+ // SM.
+ setTest("azbc iof z 893");
+ st.ordinaryChars('a', 'z');
+ assertEquals("OrdinaryChars failed.", 'a', st.nextToken());
+ assertEquals("OrdinaryChars failed.", 'z', st.nextToken());
+ }
+
+ /**
+ * java.io.StreamTokenizer#parseNumbers()
+ */
+ public void test_parseNumbers() throws IOException {
+ // SM
+ setTest("9.9 678");
+ assertTrue("Base behavior failed.",
+ st.nextToken() == StreamTokenizer.TT_NUMBER);
+ st.ordinaryChars('0', '9');
+ assertEquals("setOrdinary failed.", '6', st.nextToken());
+ st.parseNumbers();
+ assertTrue("parseNumbers failed.",
+ st.nextToken() == StreamTokenizer.TT_NUMBER);
+ }
+
+ /**
+ * java.io.StreamTokenizer#pushBack()
+ */
+ public void test_pushBack() throws IOException {
+ // SM.
+ setTest("Hello 897");
+ st.nextToken();
+ st.pushBack();
+ assertTrue("PushBack failed.",
+ st.nextToken() == StreamTokenizer.TT_WORD);
+ }
+
+ /**
+ * java.io.StreamTokenizer#quoteChar(int)
+ */
+ public void test_quoteCharI() throws IOException {
+ // SM
+ setTest("<Hello World< HelloWorldH");
+ st.quoteChar('<');
+ assertEquals("QuoteChar failed.", '<', st.nextToken());
+ assertEquals("QuoteChar failed.", "Hello World", st.sval);
+ st.quoteChar('H');
+ st.nextToken();
+ assertEquals("QuoteChar failed for word.", "elloWorld", st.sval
+ );
+ }
+
+ /**
+ * java.io.StreamTokenizer#resetSyntax()
+ */
+ public void test_resetSyntax() throws IOException {
+ // SM
+ setTest("H 9\' ello World");
+ st.resetSyntax();
+ assertTrue("resetSyntax failed1." + (char) st.ttype,
+ st.nextToken() == 'H');
+ assertTrue("resetSyntax failed1." + (char) st.ttype,
+ st.nextToken() == ' ');
+ assertTrue("resetSyntax failed2." + (char) st.ttype,
+ st.nextToken() == '9');
+ assertTrue("resetSyntax failed3." + (char) st.ttype,
+ st.nextToken() == '\'');
+ }
+
+ /**
+ * java.io.StreamTokenizer#slashSlashComments(boolean)
+ */
+ public void test_slashSlashCommentsZ() throws IOException {
+ // SM.
+ setTest("// foo \r\n /fiji \r\n -456");
+ st.ordinaryChar('/');
+ st.slashSlashComments(true);
+ assertEquals("Test failed.", '/', st.nextToken());
+ assertTrue("Test failed.",
+ st.nextToken() == StreamTokenizer.TT_WORD);
+ }
+
+ /**
+ * java.io.StreamTokenizer#slashSlashComments(boolean)
+ */
+ public void test_slashSlashComments_withSSOpen() throws IOException {
+ Reader reader = new CharArrayReader("t // t t t".toCharArray());
+
+ StreamTokenizer st = new StreamTokenizer(reader);
+ st.slashSlashComments(true);
+
+ assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+ assertEquals(StreamTokenizer.TT_EOF, st.nextToken());
+ }
+
+ /**
+ * java.io.StreamTokenizer#slashSlashComments(boolean)
+ */
+ public void test_slashSlashComments_withSSOpen_NoComment() throws IOException {
+ Reader reader = new CharArrayReader("// t".toCharArray());
+
+ StreamTokenizer st = new StreamTokenizer(reader);
+ st.slashSlashComments(true);
+ st.ordinaryChar('/');
+
+ assertEquals(StreamTokenizer.TT_EOF, st.nextToken());
+ }
+
+ /**
+ * java.io.StreamTokenizer#slashSlashComments(boolean)
+ */
+ public void test_slashSlashComments_withSSClosed() throws IOException {
+ Reader reader = new CharArrayReader("// t".toCharArray());
+
+ StreamTokenizer st = new StreamTokenizer(reader);
+ st.slashSlashComments(false);
+ st.ordinaryChar('/');
+
+ assertEquals('/', st.nextToken());
+ assertEquals('/', st.nextToken());
+ assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+ }
+
+ /**
+ * java.io.StreamTokenizer#slashStarComments(boolean)
+ */
+ public void test_slashStarCommentsZ() throws IOException {
+ setTest("/* foo \r\n /fiji \r\n*/ -456");
+ st.ordinaryChar('/');
+ st.slashStarComments(true);
+ assertTrue("Test failed.",
+ st.nextToken() == StreamTokenizer.TT_NUMBER);
+ }
+
+ /**
+ * java.io.StreamTokenizer#slashStarComments(boolean)
+ */
+ public void test_slashStarComments_withSTOpen() throws IOException {
+ Reader reader = new CharArrayReader("t /* t */ t".toCharArray());
+
+ StreamTokenizer st = new StreamTokenizer(reader);
+ st.slashStarComments(true);
+
+ assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+ assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+ assertEquals(StreamTokenizer.TT_EOF, st.nextToken());
+ }
+
+ /**
+ * java.io.StreamTokenizer#slashStarComments(boolean)
+ */
+ public void test_slashStarComments_withSTClosed() throws IOException {
+ Reader reader = new CharArrayReader("t /* t */ t".toCharArray());
+
+ StreamTokenizer st = new StreamTokenizer(reader);
+ st.slashStarComments(false);
+
+ assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+ assertEquals(StreamTokenizer.TT_EOF, st.nextToken());
+ }
+
+ /**
+ * java.io.StreamTokenizer#toString()
+ */
+ public void test_toString() throws IOException {
+ setTest("ABC Hello World");
+ st.nextToken();
+ assertTrue("toString failed." + st.toString(),
+ st.toString().equals(
+ "Token[ABC], line 1"));
+
+ // Regression test for HARMONY-4070
+ byte[] data = new byte[] { (byte) '-' };
+ StreamTokenizer tokenizer = new StreamTokenizer(
+ new ByteArrayInputStream(data));
+ tokenizer.nextToken();
+ String result = tokenizer.toString();
+ assertEquals("Token['-'], line 1", result);
+ }
+
+ /**
+ * java.io.StreamTokenizer#whitespaceChars(int, int)
+ */
+ public void test_whitespaceCharsII() throws IOException {
+ setTest("azbc iof z 893");
+ st.whitespaceChars('a', 'z');
+ assertTrue("OrdinaryChar failed.",
+ st.nextToken() == StreamTokenizer.TT_NUMBER);
+ }
+
+ /**
+ * java.io.StreamTokenizer#wordChars(int, int)
+ */
+ public void test_wordCharsII() throws IOException {
+ setTest("A893 -9B87");
+ st.wordChars('0', '9');
+ assertTrue("WordChar failed1.",
+ st.nextToken() == StreamTokenizer.TT_WORD);
+ assertEquals("WordChar failed2.", "A893", st.sval);
+ assertTrue("WordChar failed3.",
+ st.nextToken() == StreamTokenizer.TT_NUMBER);
+ st.nextToken();
+ assertEquals("WordChar failed4.", "B87", st.sval);
+
+ setTest(" Hello World");
+ st.wordChars(' ', ' ');
+ st.nextToken();
+ assertEquals("WordChars failed for whitespace.", "Hello World", st.sval
+ );
+
+ setTest(" Hello World\r\n \'Hello World\' Hello\' World");
+ st.wordChars(' ', ' ');
+ st.wordChars('\'', '\'');
+ st.nextToken();
+ assertTrue("WordChars failed for whitespace: " + st.sval, st.sval
+ .equals("Hello World"));
+ st.nextToken();
+ assertTrue("WordChars failed for quote1: " + st.sval, st.sval
+ .equals("\'Hello World\' Hello\' World"));
+ }
+
+ private void setTest(String s) {
+ testString = s;
+ r = new Support_StringReader(testString);
+ st = new StreamTokenizer(r);
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringBufferInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringBufferInputStreamTest.java
new file mode 100644
index 0000000..8ca4ca5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringBufferInputStreamTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.StringBufferInputStream;
+import java.io.UnsupportedEncodingException;
+
+@SuppressWarnings("deprecation")
+public class StringBufferInputStreamTest extends junit.framework.TestCase {
+
+ StringBufferInputStream sbis;
+
+ /**
+ * java.io.StringBufferInputStream#StringBufferInputStream(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.io.StringBufferInputStream(java.lang.String)
+ }
+
+ /**
+ * java.io.StringBufferInputStream#available()
+ */
+ public void test_available() {
+ // Test for method int java.io.StringBufferInputStream.available()
+ assertEquals("Returned incorrect number of available bytes", 11, sbis
+ .available());
+ }
+
+ /**
+ * java.io.StringBufferInputStream#read()
+ */
+ public void test_read() throws UnsupportedEncodingException {
+ // Test for method int java.io.StringBufferInputStream.read()
+ byte[] buf = new byte[5];
+ sbis.skip(6);
+ sbis.read(buf, 0, 5);
+ assertEquals("Returned incorrect chars", "World", new String(buf, "UTF-8"));
+ }
+
+ /**
+ * java.io.StringBufferInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() {
+ // Test for method int java.io.StringBufferInputStream.read(byte [],
+ // int, int)
+ assertEquals("Read returned incorrect char", 'H', sbis.read());
+ }
+
+ /**
+ * java.io.StringBufferInputStream#reset()
+ */
+ public void test_reset() {
+ // Test for method void java.io.StringBufferInputStream.reset()
+ long s = sbis.skip(6);
+ assertEquals("Unable to skip correct umber of chars", 6, s);
+ sbis.reset();
+ assertEquals("Failed to reset", 'H', sbis.read());
+ }
+
+ /**
+ * java.io.StringBufferInputStream#skip(long)
+ */
+ public void test_skipJ() {
+ // Test for method long java.io.StringBufferInputStream.skip(long)
+ long s = sbis.skip(6);
+ assertEquals("Unable to skip correct umber of chars", 6, s);
+ assertEquals("Skip positioned at incorrect char", 'W', sbis.read());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ sbis = new StringBufferInputStream("Hello World");
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringReaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringReaderTest.java
new file mode 100644
index 0000000..4d44d98
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringReaderTest.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+public class StringReaderTest extends junit.framework.TestCase {
+
+ String testString = "This is a test string";
+
+ StringReader sr;
+
+ /**
+ * java.io.StringReader#StringReader(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.io.StringReader(java.lang.String)
+ assertTrue("Used in tests", true);
+ }
+
+ /**
+ * java.io.StringReader#close()
+ */
+ public void test_close() throws Exception {
+ // Test for method void java.io.StringReader.close()
+ try {
+ sr = new StringReader(testString);
+ sr.close();
+ char[] buf = new char[10];
+ sr.read(buf, 0, 2);
+ fail("Close failed");
+ } catch (java.io.IOException e) {
+ return;
+ }
+ }
+
+ /**
+ * java.io.StringReader#mark(int)
+ */
+ public void test_markI() throws Exception {
+ // Test for method void java.io.StringReader.mark(int)
+ sr = new StringReader(testString);
+ sr.skip(5);
+ sr.mark(0);
+ sr.skip(5);
+ sr.reset();
+ char[] buf = new char[10];
+ sr.read(buf, 0, 2);
+ assertTrue("Failed to return to mark", new String(buf, 0, 2)
+ .equals(testString.substring(5, 7)));
+ }
+
+ /**
+ * java.io.StringReader#markSupported()
+ */
+ public void test_markSupported() {
+ // Test for method boolean java.io.StringReader.markSupported()
+
+ sr = new StringReader(testString);
+ assertTrue("markSupported returned false", sr.markSupported());
+ }
+
+ /**
+ * java.io.StringReader#read()
+ */
+ public void test_read() throws Exception {
+ // Test for method int java.io.StringReader.read()
+ sr = new StringReader(testString);
+ int r = sr.read();
+ assertEquals("Failed to read char", 'T', r);
+ sr = new StringReader(new String(new char[] { '\u8765' }));
+ assertTrue("Wrong double byte char", sr.read() == '\u8765');
+ }
+
+ /**
+ * java.io.StringReader#read(char[], int, int)
+ */
+ public void test_read$CII() throws Exception {
+ // Test for method int java.io.StringReader.read(char [], int, int)
+ sr = new StringReader(testString);
+ char[] buf = new char[testString.length()];
+ int r = sr.read(buf, 0, testString.length());
+ assertTrue("Failed to read chars", r == testString.length());
+ assertTrue("Read chars incorrectly", new String(buf, 0, r)
+ .equals(testString));
+ }
+
+ /**
+ * java.io.StringReader#ready()
+ */
+ public void test_ready() throws Exception {
+ // Test for method boolean java.io.StringReader.ready()
+ sr = new StringReader(testString);
+ assertTrue("Steam not ready", sr.ready());
+ sr.close();
+ int r = 0;
+ try {
+ sr.ready();
+ } catch (IOException e) {
+ r = 1;
+ }
+ assertEquals("Expected IOException not thrown in read()", 1, r);
+ }
+
+ /**
+ * java.io.StringReader#reset()
+ */
+ public void test_reset() throws Exception {
+ // Test for method void java.io.StringReader.reset()
+ sr = new StringReader(testString);
+ sr.skip(5);
+ sr.mark(0);
+ sr.skip(5);
+ sr.reset();
+ char[] buf = new char[10];
+ sr.read(buf, 0, 2);
+ assertTrue("Failed to reset properly", new String(buf, 0, 2)
+ .equals(testString.substring(5, 7)));
+ }
+
+ /**
+ * java.io.StringReader#skip(long)
+ */
+ public void test_skipJ() throws Exception {
+ // Test for method long java.io.StringReader.skip(long)
+ sr = new StringReader(testString);
+ sr.skip(5);
+ char[] buf = new char[10];
+ sr.read(buf, 0, 2);
+ assertTrue("Failed to skip properly", new String(buf, 0, 2)
+ .equals(testString.substring(5, 7)));
+ }
+
+ // Regression test for HARMONY-5077
+ static boolean finish = false;
+
+ public void test_synchronization() {
+ String anything = "Hello world";
+ final StringReader sr = new StringReader(anything);
+ Thread other = new Thread(new Runnable() {
+ public void run() {
+ sr.close();
+ finish = true;
+ }
+
+ ;
+ });
+
+ synchronized (anything) {
+ other.start();
+ while (!finish) {
+ Thread.yield();
+ }
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringWriterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringWriterTest.java
new file mode 100644
index 0000000..c3db539
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/StringWriterTest.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+public class StringWriterTest extends junit.framework.TestCase {
+
+ StringWriter sw;
+
+ /**
+ * java.io.StringWriter#StringWriter()
+ */
+ public void test_Constructor() {
+ // Test for method java.io.StringWriter()
+ assertTrue("Used in tests", true);
+ }
+
+ /**
+ * java.io.StringWriter#close()
+ */
+ public void test_close() {
+ // Test for method void java.io.StringWriter.close()
+ try {
+ sw.close();
+ } catch (IOException e) {
+ fail("IOException closing StringWriter : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.StringWriter#flush()
+ */
+ public void test_flush() {
+ // Test for method void java.io.StringWriter.flush()
+ sw.flush();
+ sw.write('c');
+ assertEquals("Failed to flush char", "c", sw.toString());
+ }
+
+ /**
+ * java.io.StringWriter#getBuffer()
+ */
+ public void test_getBuffer() {
+ // Test for method java.lang.StringBuffer
+ // java.io.StringWriter.getBuffer()
+
+ sw.write("This is a test string");
+ StringBuffer sb = sw.getBuffer();
+ assertEquals("Incorrect buffer returned",
+ "This is a test string", sb.toString());
+ }
+
+ /**
+ * java.io.StringWriter#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.io.StringWriter.toString()
+ sw.write("This is a test string");
+ assertEquals("Incorrect string returned",
+ "This is a test string", sw.toString());
+ }
+
+ /**
+ * java.io.StringWriter#write(char[], int, int)
+ */
+ public void test_write$CII() {
+ // Test for method void java.io.StringWriter.write(char [], int, int)
+ char[] c = new char[1000];
+ "This is a test string".getChars(0, 21, c, 0);
+ sw.write(c, 0, 21);
+ assertEquals("Chars not written properly",
+ "This is a test string", sw.toString());
+ }
+
+ /**
+ * java.io.StringWriter#write(char[], int, int)
+ * Regression for HARMONY-387
+ */
+ public void test_write$CII_2() {
+ StringWriter obj = null;
+ try {
+ obj = new StringWriter();
+ obj.write(new char[0], (int) 0, (int) -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.StringWriter#write(char[], int, int)
+ */
+ public void test_write$CII_3() {
+ StringWriter obj = null;
+ try {
+ obj = new StringWriter();
+ obj.write(new char[0], (int) -1, (int) 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.StringWriter#write(char[], int, int)
+ */
+ public void test_write$CII_4() {
+ StringWriter obj = null;
+ try {
+ obj = new StringWriter();
+ obj.write(new char[0], (int) -1, (int) -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * java.io.StringWriter#write(int)
+ */
+ public void test_writeI() {
+ // Test for method void java.io.StringWriter.write(int)
+ sw.write('c');
+ assertEquals("Char not written properly", "c", sw.toString());
+ }
+
+ /**
+ * java.io.StringWriter#write(java.lang.String)
+ */
+ public void test_writeLjava_lang_String() {
+ // Test for method void java.io.StringWriter.write(java.lang.String)
+ sw.write("This is a test string");
+ assertEquals("String not written properly",
+ "This is a test string", sw.toString());
+ }
+
+ /**
+ * java.io.StringWriter#write(java.lang.String, int, int)
+ */
+ public void test_writeLjava_lang_StringII() {
+ // Test for method void java.io.StringWriter.write(java.lang.String,
+ // int, int)
+ sw.write("This is a test string", 2, 2);
+ assertEquals("String not written properly", "is", sw.toString());
+ }
+
+ /**
+ * java.io.StringWriter#append(char)
+ */
+ public void test_appendChar() throws IOException {
+ char testChar = ' ';
+ StringWriter stringWriter = new StringWriter(20);
+ stringWriter.append(testChar);
+ assertEquals(String.valueOf(testChar), stringWriter.toString());
+ stringWriter.close();
+ }
+
+ /**
+ * java.io.PrintWriter#append(CharSequence)
+ */
+ public void test_appendCharSequence() throws IOException {
+
+ String testString = "My Test String";
+ StringWriter stringWriter = new StringWriter(20);
+ stringWriter.append(testString);
+ assertEquals(String.valueOf(testString), stringWriter.toString());
+ stringWriter.close();
+ }
+
+ /**
+ * java.io.PrintWriter#append(CharSequence, int, int)
+ */
+ public void test_appendCharSequenceIntInt() throws IOException {
+ String testString = "My Test String";
+ StringWriter stringWriter = new StringWriter(20);
+ stringWriter.append(testString, 1, 3);
+ assertEquals(testString.substring(1, 3), stringWriter.toString());
+ stringWriter.close();
+
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+
+ sw = new StringWriter();
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SyncFailedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SyncFailedExceptionTest.java
new file mode 100644
index 0000000..d1772a3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/SyncFailedExceptionTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.SyncFailedException;
+
+public class SyncFailedExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.io.SyncFailedException#SyncFailedException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws Exception {
+ // Test for method java.io.SyncFailedException(java.lang.String)
+ File f = null;
+ try {
+ f = File.createTempFile("SyncFailedExceptionTest", "tst");
+ FileOutputStream fos = new FileOutputStream(f.getAbsolutePath());
+ FileDescriptor fd = fos.getFD();
+ fos.close();
+ fd.sync();
+ } catch (SyncFailedException e) {
+ f.delete();
+ return;
+ }
+
+ fail("Failed to generate expected Exception");
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/UTFDataFormatExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/UTFDataFormatExceptionTest.java
new file mode 100644
index 0000000..cf5aa82
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/UTFDataFormatExceptionTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.UTFDataFormatException;
+
+public class UTFDataFormatExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.io.UTFDataFormatException#UTFDataFormatException()
+ */
+ public void test_Constructor() {
+ // Test for method java.io.UTFDataFormatException()
+ try {
+ int stringBufferSize = 70000;
+ int loopCount = 66;
+ StringBuffer sb = new StringBuffer(stringBufferSize);
+ for (int i = 0; i < (loopCount); i++)
+ sb
+ .append("qwertyuiopasdfghjklzxcvbnmlkjhgfdsaqwertyuioplkjhgqwertyuiopasdfghjklzxcvbnmlkjhgfdsaqwertyuioplkjhg");
+ DataOutputStream dos = new DataOutputStream(
+ new ByteArrayOutputStream());
+ dos.writeUTF(sb.toString());
+ } catch (UTFDataFormatException e) {
+ return;
+ } catch (Exception e) {
+ fail("Exception during Constructor test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.io.UTFDataFormatException#UTFDataFormatException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.io.UTFDataFormatException(java.lang.String)
+ try {
+ int stringBufferSize = 70000;
+ int loopCount = 66;
+ StringBuffer sb = new StringBuffer(stringBufferSize);
+ for (int i = 0; i < (loopCount); i++)
+ sb
+ .append("qwertyuiopasdfghjklzxcvbnmlkjhgfdsaqwertyuioplkjhgqwertyuiopasdfghjklzxcvbnmlkjhgfdsaqwertyuioplkjhg");
+ DataOutputStream dos = new DataOutputStream(
+ new ByteArrayOutputStream());
+ dos.writeUTF(sb.toString());
+ } catch (UTFDataFormatException e) {
+ return;
+ } catch (Exception e) {
+ fail("Exception during Constructor test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/UnsupportedEncodingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/UnsupportedEncodingExceptionTest.java
new file mode 100644
index 0000000..82b2dfb
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/UnsupportedEncodingExceptionTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+
+public class UnsupportedEncodingExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.io.UnsupportedEncodingException#UnsupportedEncodingException()
+ */
+ public void test_Constructor() {
+ // Test for method java.io.UnsupportedEncodingException()
+ try {
+ new OutputStreamWriter(new ByteArrayOutputStream(), "BogusEncoding");
+ } catch (UnsupportedEncodingException e) {
+ return;
+ }
+
+ fail("Failed to generate expected exception");
+ }
+
+ /**
+ * java.io.UnsupportedEncodingException#UnsupportedEncodingException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method
+ // java.io.UnsupportedEncodingException(java.lang.String)
+ try {
+ new OutputStreamWriter(new ByteArrayOutputStream(), "BogusEncoding");
+ } catch (UnsupportedEncodingException e) {
+ return;
+ }
+
+ fail("Failed to generate expected exception");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriteAbortedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriteAbortedExceptionTest.java
new file mode 100644
index 0000000..1c3f1e3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriteAbortedExceptionTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import java.io.WriteAbortedException;
+
+public class WriteAbortedExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.io.WriteAbortedException#WriteAbortedException(java.lang.String,
+ *java.lang.Exception)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_Exception() {
+ // Test for method java.io.WriteAbortedException(java.lang.String,
+ // java.lang.Exception)
+ try {
+ if (true)
+ throw new WriteAbortedException("HelloWorld",
+ new WriteAbortedException("ByeWorld", null));
+ } catch (WriteAbortedException e) {
+ return;
+ }
+ fail("Failed to generate expected Exception");
+ }
+
+ /**
+ * java.io.WriteAbortedException#getMessage()
+ */
+ public void test_getMessage() {
+ // Test for method java.lang.String
+ // java.io.WriteAbortedException.getMessage()
+ try {
+ if (true)
+ throw new WriteAbortedException("HelloWorld",
+ new WriteAbortedException("ByeWorld", null));
+ } catch (WriteAbortedException e) {
+ assertTrue("WriteAbortedException::getMessage() failed"
+ + e.getMessage(), e.getMessage().equals(
+ "HelloWorld; java.io.WriteAbortedException: ByeWorld"));
+ return;
+ }
+ fail("Failed to generate expected Exception");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriterTest.java
new file mode 100644
index 0000000..d4c33ea
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriterTest.java
@@ -0,0 +1,147 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.io;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import junit.framework.TestCase;
+
+public class WriterTest extends TestCase {
+
+ /**
+ * java.io.Writer#append(char)
+ */
+ public void test_appendChar() throws IOException {
+ char testChar = ' ';
+ MockWriter writer = new MockWriter(20);
+ writer.append(testChar);
+ assertEquals(String.valueOf(testChar), String.valueOf(writer
+ .getContents()));
+ writer.close();
+ }
+
+ /**
+ * java.io.Writer#append(CharSequence)
+ */
+ public void test_appendCharSequence() throws IOException {
+ String testString = "My Test String";
+ MockWriter writer = new MockWriter(20);
+ writer.append(testString);
+ assertEquals(testString, String.valueOf(writer.getContents()));
+ writer.close();
+
+ }
+
+ /**
+ * java.io.Writer#append(CharSequence, int, int)
+ */
+ public void test_appendCharSequenceIntInt() throws IOException {
+ String testString = "My Test String";
+ MockWriter writer = new MockWriter(20);
+ writer.append(testString, 1, 3);
+ assertEquals(testString.substring(1, 3), String.valueOf(writer
+ .getContents()));
+ writer.close();
+
+ }
+
+
+ /**
+ * java.io.Writer#write(String)
+ */
+ public void test_writeLjava_lang_String() throws IOException {
+ // Regression for HARMONY-51
+ Object lock = new Object();
+ Writer wr = new MockLockWriter(lock);
+ wr.write("Some string");
+ wr.close();
+ }
+
+ class MockLockWriter extends Writer {
+ final Object myLock;
+
+ MockLockWriter(Object lock) {
+ super(lock);
+ myLock = lock;
+ }
+
+ @Override
+ public synchronized void close() throws IOException {
+ // do nothing
+ }
+
+ @Override
+ public synchronized void flush() throws IOException {
+ // do nothing
+ }
+
+ @Override
+ public void write(char[] arg0, int arg1, int arg2) throws IOException {
+ assertTrue(Thread.holdsLock(myLock));
+ }
+ }
+
+
+ class MockWriter extends Writer {
+ private char[] contents;
+
+ private int length;
+
+ private int offset;
+
+ MockWriter(int capacity) {
+ contents = new char[capacity];
+ length = capacity;
+ offset = 0;
+ }
+
+ public synchronized void close() throws IOException {
+ flush();
+ contents = null;
+ }
+
+ public synchronized void flush() throws IOException {
+ // do nothing
+ }
+
+ public void write(char[] buffer, int offset, int count)
+ throws IOException {
+ if (null == contents) {
+ throw new IOException();
+ }
+ if (offset < 0 || count < 0 || offset >= buffer.length) {
+ throw new IndexOutOfBoundsException();
+ }
+ count = Math.min(count, buffer.length - offset);
+ count = Math.min(count, this.length - this.offset);
+ for (int i = 0; i < count; i++) {
+ contents[this.offset + i] = buffer[offset + i];
+ }
+ this.offset += count;
+
+ }
+
+ public char[] getContents() {
+ char[] result = new char[offset];
+ for (int i = 0; i < offset; i++) {
+ result[i] = contents[i];
+ }
+ return result;
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriterTesterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriterTesterTest.java
new file mode 100644
index 0000000..0995638
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/WriterTesterTest.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.io;
+
+import junit.framework.TestSuite;
+import org.apache.harmony.testframework.CharSinkTester;
+import org.apache.harmony.testframework.CharWrapperTester;
+import tests.support.Streams;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Tests basic {@link Writer} behaviors for the luni implementations of the type.
+ */
+public class WriterTesterTest {
+
+ // TODO: Rewrite this test so that id doesn't need a suite().
+ private static junit.framework.Test suite() {
+ TestSuite suite = new TestSuite();
+
+ // sink tests
+ suite.addTest(new FileWriterCharSinkTester(true).createTests());
+ suite.addTest(new FileWriterCharSinkTester(false).createTests());
+ suite.addTest(new CharArrayWriterCharSinkTester().setThrowsExceptions(false).createTests());
+ suite.addTest(new StringWriterCharSinkTester().setThrowsExceptions(false).createTests());
+ suite.addTest(new PipedWriterCharSinkTester().createTests());
+
+ // wrapper tests
+ suite.addTest(new BufferedWriterCharSinkTester(1).createTests());
+ suite.addTest(new BufferedWriterCharSinkTester(5).createTests());
+ suite.addTest(new BufferedWriterCharSinkTester(1024).createTests());
+ suite.addTest(new FilterWriterCharSinkTester().createTests());
+ suite.addTest(new PrintWriterCharSinkTester().setThrowsExceptions(false).createTests());
+ suite.addTest(new OutputStreamWriterCharSinkTester().createTests());
+
+ return suite;
+ }
+
+ private static class FileWriterCharSinkTester extends CharSinkTester {
+ private final boolean append;
+ private File file;
+
+ public FileWriterCharSinkTester(boolean append) {
+ this.append = append;
+ }
+
+ @Override
+ public Writer create() throws Exception {
+ file = File.createTempFile("FileOutputStreamSinkTester", "tmp");
+ file.deleteOnExit();
+ return new FileWriter(file, append);
+ }
+
+ @Override
+ public char[] getChars() throws Exception {
+ return Streams.streamToString(new FileReader(file)).toCharArray();
+ }
+ }
+
+ private static class CharArrayWriterCharSinkTester extends CharSinkTester {
+ private CharArrayWriter writer;
+
+ @Override
+ public Writer create() throws Exception {
+ writer = new CharArrayWriter();
+ return writer;
+ }
+
+ @Override
+ public char[] getChars() throws Exception {
+ return writer.toCharArray();
+ }
+ }
+
+ private static class PipedWriterCharSinkTester extends CharSinkTester {
+
+ private ExecutorService executor;
+ private Future<char[]> future;
+
+ public Writer create() throws IOException {
+ final PipedReader in = new PipedReader();
+ PipedWriter out = new PipedWriter(in);
+
+ executor = Executors.newSingleThreadExecutor();
+ future = executor.submit(new Callable<char[]>() {
+ final CharArrayWriter chars = new CharArrayWriter();
+
+ public char[] call() throws Exception {
+ char[] buffer = new char[256];
+ int count;
+ while ((count = in.read(buffer)) != -1) {
+ chars.write(buffer, 0, count);
+ }
+ return chars.toCharArray();
+ }
+ });
+
+ return out;
+ }
+
+ @Override
+ public char[] getChars() throws Exception {
+ executor.shutdown();
+ return future.get();
+ }
+ }
+
+ private static class StringWriterCharSinkTester extends CharSinkTester {
+ private StringWriter writer;
+
+ @Override
+ public Writer create() throws Exception {
+ writer = new StringWriter();
+ return writer;
+ }
+
+ @Override
+ public char[] getChars() throws Exception {
+ return writer.toString().toCharArray();
+ }
+ }
+
+ private static class BufferedWriterCharSinkTester extends CharWrapperTester {
+ private final int bufferSize;
+
+ private BufferedWriterCharSinkTester(int bufferSize) {
+ this.bufferSize = bufferSize;
+ }
+
+ @Override
+ public Writer create(Writer delegate) throws Exception {
+ return new BufferedWriter(delegate, bufferSize);
+ }
+
+ @Override
+ public char[] decode(char[] delegateChars) throws Exception {
+ return delegateChars;
+ }
+ }
+
+ private static class FilterWriterCharSinkTester extends CharWrapperTester {
+ @Override
+ public Writer create(Writer delegate) throws Exception {
+ return new FilterWriter(delegate) {
+ };
+ }
+
+ @Override
+ public char[] decode(char[] delegateChars) throws Exception {
+ return delegateChars;
+ }
+ }
+
+ private static class PrintWriterCharSinkTester extends CharWrapperTester {
+ @Override
+ public Writer create(Writer delegate) throws Exception {
+ return new PrintWriter(delegate) {
+ };
+ }
+
+ @Override
+ public char[] decode(char[] delegateChars) throws Exception {
+ return delegateChars;
+ }
+ }
+
+ private static class OutputStreamWriterCharSinkTester extends CharSinkTester {
+ private ByteArrayOutputStream out;
+
+ @Override
+ public Writer create() throws Exception {
+ out = new ByteArrayOutputStream();
+ return new OutputStreamWriter(out, "UTF-8");
+ }
+
+ @Override
+ public char[] getChars() throws Exception {
+ return new String(out.toByteArray(), "UTF-8").toCharArray();
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/AbstractMethodErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/AbstractMethodErrorTest.java
new file mode 100644
index 0000000..596792e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/AbstractMethodErrorTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class AbstractMethodErrorTest extends junit.framework.TestCase {
+
+ /**
+ * {@link java.lang.AbstractMethodError#AbstractMethodError()}
+ */
+ public void test_Constructor() {
+ // Test for method java.lang.AbstractMethodError()
+ Error error = new AbstractMethodError();
+ assertNull(error.getCause());
+ assertNull(error.getMessage());
+ }
+
+ /**
+ * {@link java.lang.AbstractMethodError#AbstractMethodError(String)}
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.lang.AbstractMethodError(java.lang.String)
+ Error error = new AbstractMethodError(null);
+ assertNull(error.getMessage());
+ assertNull(error.getCause());
+
+ error = new AbstractMethodError("msg");
+ assertEquals("msg", error.getMessage());
+ assertNull(error.getCause());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(new AbstractMethodError());
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ SerializationTest.verifyGolden(this, new AbstractMethodError());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArithmeticExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArithmeticExceptionTest.java
new file mode 100644
index 0000000..77e0671
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArithmeticExceptionTest.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ArithmeticExceptionTest extends TestCase {
+
+ /**
+ * java.lang.ArithmeticException#ArithmeticException()
+ */
+ public void test_Constructor() {
+ ArithmeticException e = new ArithmeticException();
+ assertNull(e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.ArithmeticException#ArithmeticException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ ArithmeticException e = new ArithmeticException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArrayIndexOutOfBoundsExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
new file mode 100644
index 0000000..3561dd9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ArrayIndexOutOfBoundsExceptionTest extends TestCase {
+
+ /**
+ * java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException(int)
+ */
+ public void test_ConstructorI() {
+ ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException(-1);
+ assertNotNull(e.getMessage());
+ assertTrue("Unable to find index value in 'message' property.", e.getMessage().indexOf(
+ "-1", 0) >= 0);
+
+ }
+
+ /**
+ * java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException()
+ */
+ public void test_Constructor() {
+ ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
+ assertNull(e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArrayStoreExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArrayStoreExceptionTest.java
new file mode 100644
index 0000000..0379769
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ArrayStoreExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ArrayStoreExceptionTest extends TestCase {
+
+ /**
+ * java.lang.ArrayStoreException#ArrayStoreException()
+ */
+ public void test_Constructor() {
+ ArrayStoreException e = new ArrayStoreException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.ArrayStoreException#ArrayStoreException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ ArrayStoreException e = new ArrayStoreException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/AssertionErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/AssertionErrorTest.java
new file mode 100644
index 0000000..8b6c80d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/AssertionErrorTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class AssertionErrorTest extends TestCase {
+
+ public void test_Constructor() {
+ AssertionError e = new AssertionError();
+ assertNull(e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ public void test_ConstructorObject() {
+ Object obj = "toString";
+ AssertionError e = new AssertionError(obj);
+ assertEquals("toString", e.getMessage());
+ assertNull(e.getCause());
+
+ NullPointerException npe = new NullPointerException("null value");
+ e = new AssertionError(npe);
+ assertEquals(npe.toString(), e.getMessage());
+ assertSame(npe, e.getCause());
+ }
+
+ public void test_ConstructorBoolean() {
+ AssertionError e = new AssertionError(true);
+ assertEquals("true", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ public void test_ConstructorChar() {
+ AssertionError e = new AssertionError('a');
+ assertEquals("a", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ public void test_ConstructorInt() {
+ AssertionError e = new AssertionError(1);
+ assertEquals("1", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ public void test_ConstructorLong() {
+ AssertionError e = new AssertionError(1L);
+ assertEquals("1", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ public void test_ConstructorFloat() {
+ AssertionError e = new AssertionError(1.0F);
+ assertEquals("1.0", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ public void test_ConstructorDouble() {
+ AssertionError e = new AssertionError(1.0D);
+ assertEquals("1.0", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/BooleanTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/BooleanTest.java
new file mode 100644
index 0000000..a6dda7a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/BooleanTest.java
@@ -0,0 +1,157 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class BooleanTest extends TestCase {
+
+ /**
+ * java.lang.Boolean#hashCode()
+ */
+ public void test_hashCode() {
+ assertEquals(1231, Boolean.TRUE.hashCode());
+ assertEquals(1237, Boolean.FALSE.hashCode());
+ }
+
+ /**
+ * java.lang.Boolean#Boolean(String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ assertEquals(Boolean.TRUE, new Boolean("TRUE"));
+ assertEquals(Boolean.TRUE, new Boolean("true"));
+ assertEquals(Boolean.TRUE, new Boolean("True"));
+
+ assertEquals(Boolean.FALSE, new Boolean("yes"));
+ assertEquals(Boolean.FALSE, new Boolean("false"));
+ }
+
+ /**
+ * java.lang.Boolean#Boolean(boolean)
+ */
+ public void test_ConstructorZ() {
+ assertEquals(Boolean.TRUE, new Boolean(true));
+ assertEquals(Boolean.FALSE, new Boolean(false));
+ }
+
+ /**
+ * java.lang.Boolean#booleanValue()
+ */
+ public void test_booleanValue() {
+ assertTrue(Boolean.TRUE.booleanValue());
+ assertFalse(Boolean.FALSE.booleanValue());
+ }
+
+ /**
+ * java.lang.Boolean#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertTrue(Boolean.TRUE.equals(Boolean.TRUE));
+ assertTrue(Boolean.TRUE.equals(new Boolean(true)));
+ assertFalse(Boolean.TRUE.equals("true"));
+ assertFalse(Boolean.TRUE.equals(null));
+ assertFalse(Boolean.FALSE.equals(Boolean.TRUE));
+ assertTrue(Boolean.FALSE.equals(Boolean.FALSE));
+ assertTrue(Boolean.FALSE.equals(new Boolean(false)));
+ }
+
+ /**
+ * java.lang.Boolean#getBoolean(String)
+ */
+ public void test_getBooleanLjava_lang_String() {
+ System.setProperty(getClass().getName(), "true");
+ assertTrue(Boolean.getBoolean(getClass().getName()));
+
+ System.setProperty(getClass().getName(), "TRUE");
+ assertTrue(Boolean.getBoolean(getClass().getName()));
+
+ System.setProperty(getClass().getName(), "false");
+ assertFalse(Boolean.getBoolean(getClass().getName()));
+ }
+
+ /**
+ * java.lang.Boolean#toString()
+ */
+ public void test_toString() {
+ assertEquals("true", Boolean.TRUE.toString());
+ assertEquals("false", Boolean.FALSE.toString());
+ }
+
+ /**
+ * java.lang.Boolean#toString(boolean)
+ */
+ public void test_toStringZ() {
+ assertEquals("true", Boolean.toString(true));
+ assertEquals("false", Boolean.toString(false));
+ }
+
+ /**
+ * java.lang.Boolean#valueOf(String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ assertEquals(Boolean.TRUE, Boolean.valueOf("true"));
+ assertEquals(Boolean.FALSE, Boolean.valueOf("false"));
+
+ assertEquals(Boolean.TRUE, Boolean.valueOf("TRUE"));
+ assertEquals(Boolean.FALSE, Boolean.valueOf("false"));
+
+ assertEquals(Boolean.FALSE, Boolean.valueOf(null));
+ assertEquals(Boolean.FALSE, Boolean.valueOf(""));
+ assertEquals(Boolean.FALSE, Boolean.valueOf("invalid"));
+
+ assertTrue("Failed to parse true to true", Boolean.valueOf("true").booleanValue());
+ assertTrue("Failed to parse mixed case true to true", Boolean.valueOf("TrUe")
+ .booleanValue());
+ assertTrue("parsed non-true to true", !Boolean.valueOf("ddddd").booleanValue());
+ }
+
+ /**
+ * java.lang.Boolean#valueOf(boolean)
+ */
+ public void test_valueOfZ() {
+ assertEquals(Boolean.TRUE, Boolean.valueOf(true));
+ assertEquals(Boolean.FALSE, Boolean.valueOf(false));
+ }
+
+ /**
+ * java.lang.Boolean#parseBoolean(String)
+ */
+ public void test_parseBooleanLjava_lang_String() {
+ assertTrue(Boolean.parseBoolean("true"));
+ assertTrue(Boolean.parseBoolean("TRUE"));
+ assertFalse(Boolean.parseBoolean("false"));
+ assertFalse(Boolean.parseBoolean(null));
+ assertFalse(Boolean.parseBoolean(""));
+ assertFalse(Boolean.parseBoolean("invalid"));
+ }
+
+ /**
+ * java.lang.Boolean#compareTo(Boolean)
+ */
+ public void test_compareToLjava_lang_Boolean() {
+ assertTrue(Boolean.TRUE.compareTo(Boolean.TRUE) == 0);
+ assertTrue(Boolean.FALSE.compareTo(Boolean.FALSE) == 0);
+ assertTrue(Boolean.TRUE.compareTo(Boolean.FALSE) > 0);
+ assertTrue(Boolean.FALSE.compareTo(Boolean.TRUE) < 0);
+
+ try {
+ Boolean.TRUE.compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ByteTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ByteTest.java
new file mode 100644
index 0000000..bbff653
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ByteTest.java
@@ -0,0 +1,672 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ByteTest extends TestCase {
+
+ /**
+ * java.lang.Byte#valueOf(byte)
+ */
+ public void test_valueOfB() {
+ assertEquals(new Byte(Byte.MIN_VALUE), Byte.valueOf(Byte.MIN_VALUE));
+ assertEquals(new Byte(Byte.MAX_VALUE), Byte.valueOf(Byte.MAX_VALUE));
+ assertEquals(new Byte((byte) 0), Byte.valueOf((byte) 0));
+
+ byte b = Byte.MIN_VALUE + 1;
+ while (b < Byte.MAX_VALUE) {
+ assertEquals(new Byte(b), Byte.valueOf(b));
+ assertSame(Byte.valueOf(b), Byte.valueOf(b));
+ b++;
+ }
+ }
+
+ /**
+ * java.lang.Byte#hashCode()
+ */
+ public void test_hashCode() {
+ assertEquals(1, new Byte((byte) 1).hashCode());
+ assertEquals(2, new Byte((byte) 2).hashCode());
+ assertEquals(0, new Byte((byte) 0).hashCode());
+ assertEquals(-1, new Byte((byte) -1).hashCode());
+ }
+
+ /**
+ * java.lang.Byte#Byte(String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ assertEquals(new Byte((byte) 0), new Byte("0"));
+ assertEquals(new Byte((byte) 1), new Byte("1"));
+ assertEquals(new Byte((byte) -1), new Byte("-1"));
+
+ try {
+ new Byte("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Byte("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Byte("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Byte(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#Byte(byte)
+ */
+ public void test_ConstructorB() {
+ assertEquals(1, new Byte((byte) 1).byteValue());
+ assertEquals(2, new Byte((byte) 2).byteValue());
+ assertEquals(0, new Byte((byte) 0).byteValue());
+ assertEquals(-1, new Byte((byte) -1).byteValue());
+ }
+
+ /**
+ * java.lang.Byte#byteValue()
+ */
+ public void test_booleanValue() {
+ assertEquals(1, new Byte((byte) 1).byteValue());
+ assertEquals(2, new Byte((byte) 2).byteValue());
+ assertEquals(0, new Byte((byte) 0).byteValue());
+ assertEquals(-1, new Byte((byte) -1).byteValue());
+ }
+
+ /**
+ * java.lang.Byte#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertEquals(new Byte((byte) 0), Byte.valueOf((byte) 0));
+ assertEquals(new Byte((byte) 1), Byte.valueOf((byte) 1));
+ assertEquals(new Byte((byte) -1), Byte.valueOf((byte) -1));
+
+ Byte fixture = new Byte((byte) 25);
+ assertEquals(fixture, fixture);
+ assertFalse(fixture.equals(null));
+ assertFalse(fixture.equals("Not a Byte"));
+ }
+
+ /**
+ * java.lang.Byte#toString()
+ */
+ public void test_toString() {
+ assertEquals("-1", new Byte((byte) -1).toString());
+ assertEquals("0", new Byte((byte) 0).toString());
+ assertEquals("1", new Byte((byte) 1).toString());
+ assertEquals("-1", new Byte((byte) 0xFF).toString());
+ }
+
+ /**
+ * java.lang.Byte#toString(byte)
+ */
+ public void test_toStringB() {
+ assertEquals("-1", Byte.toString((byte) -1));
+ assertEquals("0", Byte.toString((byte) 0));
+ assertEquals("1", Byte.toString((byte) 1));
+ assertEquals("-1", Byte.toString((byte) 0xFF));
+ }
+
+ /**
+ * java.lang.Byte#valueOf(String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ assertEquals(new Byte((byte) 0), Byte.valueOf("0"));
+ assertEquals(new Byte((byte) 1), Byte.valueOf("1"));
+ assertEquals(new Byte((byte) -1), Byte.valueOf("-1"));
+
+ try {
+ Byte.valueOf("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.valueOf("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.valueOf("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.valueOf(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#valueOf(String, int)
+ */
+ public void test_valueOfLjava_lang_StringI() {
+ assertEquals(new Byte((byte) 0), Byte.valueOf("0", 10));
+ assertEquals(new Byte((byte) 1), Byte.valueOf("1", 10));
+ assertEquals(new Byte((byte) -1), Byte.valueOf("-1", 10));
+
+ //must be consistent with Character.digit()
+ assertEquals(Character.digit('1', 2), Byte.valueOf("1", 2).byteValue());
+ assertEquals(Character.digit('F', 16), Byte.valueOf("F", 16).byteValue());
+
+ try {
+ Byte.valueOf("0x1", 10);
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.valueOf("9.2", 10);
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.valueOf("", 10);
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.valueOf(null, 10);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#parseByte(String)
+ */
+ public void test_parseByteLjava_lang_String() {
+ assertEquals(0, Byte.parseByte("0"));
+ assertEquals(1, Byte.parseByte("1"));
+ assertEquals(-1, Byte.parseByte("-1"));
+
+ try {
+ Byte.parseByte("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#parseByte(String, int)
+ */
+ public void test_parseByteLjava_lang_StringI() {
+ assertEquals(0, Byte.parseByte("0", 10));
+ assertEquals(1, Byte.parseByte("1", 10));
+ assertEquals(-1, Byte.parseByte("-1", 10));
+
+ //must be consistent with Character.digit()
+ assertEquals(Character.digit('1', 2), Byte.parseByte("1", 2));
+ assertEquals(Character.digit('F', 16), Byte.parseByte("F", 16));
+
+ try {
+ Byte.parseByte("0x1", 10);
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("9.2", 10);
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("", 10);
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte(null, 10);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#decode(String)
+ */
+ public void test_decodeLjava_lang_String() {
+ assertEquals(new Byte((byte) 0), Byte.decode("0"));
+ assertEquals(new Byte((byte) 1), Byte.decode("1"));
+ assertEquals(new Byte((byte) -1), Byte.decode("-1"));
+ assertEquals(new Byte((byte) 0xF), Byte.decode("0xF"));
+ assertEquals(new Byte((byte) 0xF), Byte.decode("#F"));
+ assertEquals(new Byte((byte) 0xF), Byte.decode("0XF"));
+ assertEquals(new Byte((byte) 07), Byte.decode("07"));
+
+ try {
+ Byte.decode("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.decode("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.decode(null);
+ //undocumented NPE, but seems consistent across JREs
+ fail("Expected NullPointerException with null string.");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#doubleValue()
+ */
+ public void test_doubleValue() {
+ assertEquals(-1D, new Byte((byte) -1).doubleValue(), 0D);
+ assertEquals(0D, new Byte((byte) 0).doubleValue(), 0D);
+ assertEquals(1D, new Byte((byte) 1).doubleValue(), 0D);
+ }
+
+ /**
+ * java.lang.Byte#floatValue()
+ */
+ public void test_floatValue() {
+ assertEquals(-1F, new Byte((byte) -1).floatValue(), 0F);
+ assertEquals(0F, new Byte((byte) 0).floatValue(), 0F);
+ assertEquals(1F, new Byte((byte) 1).floatValue(), 0F);
+ }
+
+ /**
+ * java.lang.Byte#intValue()
+ */
+ public void test_intValue() {
+ assertEquals(-1, new Byte((byte) -1).intValue());
+ assertEquals(0, new Byte((byte) 0).intValue());
+ assertEquals(1, new Byte((byte) 1).intValue());
+ }
+
+ /**
+ * java.lang.Byte#longValue()
+ */
+ public void test_longValue() {
+ assertEquals(-1L, new Byte((byte) -1).longValue());
+ assertEquals(0L, new Byte((byte) 0).longValue());
+ assertEquals(1L, new Byte((byte) 1).longValue());
+ }
+
+ /**
+ * java.lang.Byte#shortValue()
+ */
+ public void test_shortValue() {
+ assertEquals(-1, new Byte((byte) -1).shortValue());
+ assertEquals(0, new Byte((byte) 0).shortValue());
+ assertEquals(1, new Byte((byte) 1).shortValue());
+ }
+
+ /**
+ * java.lang.Byte#compareTo(Byte)
+ */
+ public void test_compareToLjava_lang_Byte() {
+ final Byte min = new Byte(Byte.MIN_VALUE);
+ final Byte zero = new Byte((byte) 0);
+ final Byte max = new Byte(Byte.MAX_VALUE);
+
+ assertTrue(max.compareTo(max) == 0);
+ assertTrue(min.compareTo(min) == 0);
+ assertTrue(zero.compareTo(zero) == 0);
+
+ assertTrue(max.compareTo(zero) > 0);
+ assertTrue(max.compareTo(min) > 0);
+
+ assertTrue(zero.compareTo(max) < 0);
+ assertTrue(zero.compareTo(min) > 0);
+
+ assertTrue(min.compareTo(zero) < 0);
+ assertTrue(min.compareTo(max) < 0);
+
+ try {
+ min.compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#Byte(byte)
+ */
+ public void test_ConstructorB2() {
+ // Test for method java.lang.Byte(byte)
+
+ Byte b = new Byte((byte) 127);
+ assertTrue("Byte creation failed", b.byteValue() == (byte) 127);
+ }
+
+ /**
+ * java.lang.Byte#Byte(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String2() {
+ // Test for method java.lang.Byte(java.lang.String)
+
+ Byte b = new Byte("127");
+ Byte nb = new Byte("-128");
+ assertTrue("Incorrect Byte Object created", b.byteValue() == (byte) 127
+ && (nb.byteValue() == (byte) -128));
+
+ }
+
+ /**
+ * java.lang.Byte#byteValue()
+ */
+ public void test_byteValue() {
+ // Test for method byte java.lang.Byte.byteValue()
+ assertTrue("Returned incorrect byte value",
+ new Byte((byte) 127).byteValue() == (byte) (127));
+ }
+
+ /**
+ * java.lang.Byte#compareTo(java.lang.Byte)
+ */
+ public void test_compareToLjava_lang_Byte2() {
+ // Test for method int java.lang.Byte.compareTo(java.lang.Byte)
+ assertTrue("Comparison failed", new Byte((byte) 1).compareTo(new Byte((byte) 2)) < 0);
+ assertTrue("Comparison failed", new Byte((byte) 1).compareTo(new Byte((byte) -2)) > 0);
+ assertEquals("Comparison failed", 0, new Byte((byte) 1).compareTo(new Byte((byte) 1)));
+ }
+
+ /**
+ * java.lang.Byte#decode(java.lang.String)
+ */
+ public void test_decodeLjava_lang_String2() {
+ // Test for method java.lang.Byte
+ // java.lang.Byte.decode(java.lang.String)
+ assertTrue("String decoded incorrectly, wanted: 1 got: " + Byte.decode("1").toString(),
+ Byte.decode("1").equals(new Byte((byte) 1)));
+ assertTrue("String decoded incorrectly, wanted: -1 got: "
+ + Byte.decode("-1").toString(), Byte.decode("-1").equals(new Byte((byte) -1)));
+ assertTrue("String decoded incorrectly, wanted: 127 got: "
+ + Byte.decode("127").toString(), Byte.decode("127")
+ .equals(new Byte((byte) 127)));
+ assertTrue("String decoded incorrectly, wanted: -128 got: "
+ + Byte.decode("-128").toString(), Byte.decode("-128").equals(
+ new Byte((byte) -128)));
+ assertTrue("String decoded incorrectly, wanted: 127 got: "
+ + Byte.decode("0x7f").toString(), Byte.decode("0x7f").equals(
+ new Byte((byte) 127)));
+ assertTrue("String decoded incorrectly, wanted: -128 got: "
+ + Byte.decode("-0x80").toString(), Byte.decode("-0x80").equals(
+ new Byte((byte) -128)));
+
+ boolean exception = false;
+ try {
+ Byte.decode("128");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Byte.decode("-129");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Byte.decode("0x80");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Byte.decode("-0x81");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MIN_VALUE - 1", exception);
+ }
+
+ /**
+ * java.lang.Byte#doubleValue()
+ */
+ public void test_doubleValue2() {
+ assertEquals(127D, new Byte((byte) 127).doubleValue(), 0.0);
+ }
+
+ /**
+ * java.lang.Byte#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object2() {
+ // Test for method boolean java.lang.Byte.equals(java.lang.Object)
+ Byte b1 = new Byte((byte) 90);
+ Byte b2 = new Byte((byte) 90);
+ Byte b3 = new Byte((byte) -90);
+ assertTrue("Equality test failed", b1.equals(b2));
+ assertTrue("Equality test failed", !b1.equals(b3));
+ }
+
+ /**
+ * java.lang.Byte#floatValue()
+ */
+ public void test_floatValue2() {
+ assertEquals(127F, new Byte((byte) 127).floatValue(), 0.0);
+ }
+
+ /**
+ * java.lang.Byte#hashCode()
+ */
+ public void test_hashCode2() {
+ // Test for method int java.lang.Byte.hashCode()
+ assertEquals("Incorrect hash returned", 127, new Byte((byte) 127).hashCode());
+ }
+
+ /**
+ * java.lang.Byte#intValue()
+ */
+ public void test_intValue2() {
+ // Test for method int java.lang.Byte.intValue()
+ assertEquals("Returned incorrect int value", 127, new Byte((byte) 127).intValue());
+ }
+
+ /**
+ * java.lang.Byte#longValue()
+ */
+ public void test_longValue2() {
+ // Test for method long java.lang.Byte.longValue()
+ assertEquals("Returned incorrect long value", 127L, new Byte((byte) 127).longValue());
+ }
+
+ /**
+ * java.lang.Byte#parseByte(java.lang.String)
+ */
+ public void test_parseByteLjava_lang_String2() {
+ assertEquals((byte) 127, Byte.parseByte("127"));
+ assertEquals((byte) -128, Byte.parseByte("-128"));
+ assertEquals((byte) 0, Byte.parseByte("0"));
+ assertEquals((byte) 0x80, Byte.parseByte("-128"));
+ assertEquals((byte) 0x7F, Byte.parseByte("127"));
+
+ try {
+ Byte.parseByte("-1000");
+ fail("No NumberFormatException");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("128");
+ fail("No NumberFormatException");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("-129");
+ fail("No NumberFormatException");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#parseByte(java.lang.String, int)
+ */
+ public void test_parseByteLjava_lang_StringI2() {
+ // Test for method byte java.lang.Byte.parseByte(java.lang.String, int)
+ byte b = Byte.parseByte("127", 10);
+ byte bn = Byte.parseByte("-128", 10);
+ assertTrue("Invalid parse of dec byte", b == (byte) 127 && (bn == (byte) -128));
+ assertEquals("Failed to parse hex value", 10, Byte.parseByte("A", 16));
+ assertEquals("Returned incorrect value for 0 hex", 0, Byte.parseByte("0", 16));
+ assertTrue("Returned incorrect value for most negative value hex", Byte.parseByte(
+ "-80", 16) == (byte) 0x80);
+ assertTrue("Returned incorrect value for most positive value hex", Byte.parseByte("7f",
+ 16) == 0x7f);
+ assertEquals("Returned incorrect value for 0 decimal", 0, Byte.parseByte("0", 10));
+ assertTrue("Returned incorrect value for most negative value decimal", Byte.parseByte(
+ "-128", 10) == (byte) 0x80);
+ assertTrue("Returned incorrect value for most positive value decimal", Byte.parseByte(
+ "127", 10) == 0x7f);
+
+ try {
+ Byte.parseByte("-1000", 10);
+ fail("Failed to throw exception");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("128", 10);
+ fail("Failed to throw exception for MAX_VALUE + 1");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("-129", 10);
+ fail("Failed to throw exception for MIN_VALUE - 1");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("80", 16);
+ fail("Failed to throw exception for hex MAX_VALUE + 1");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Byte.parseByte("-81", 16);
+ fail("Failed to throw exception for hex MIN_VALUE + 1");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#shortValue()
+ */
+ public void test_shortValue2() {
+ assertEquals((short) 127, new Byte((byte) 127).shortValue());
+ }
+
+ /**
+ * java.lang.Byte#toString()
+ */
+ public void test_toString2() {
+ assertEquals("Returned incorrect String", "127", new Byte((byte) 127).toString());
+ assertEquals("Returned incorrect String", "-127", new Byte((byte) -127).toString());
+ assertEquals("Returned incorrect String", "-128", new Byte((byte) -128).toString());
+ }
+
+ /**
+ * java.lang.Byte#toString(byte)
+ */
+ public void test_toStringB2() {
+ assertEquals("Returned incorrect String", "127", Byte.toString((byte) 127));
+ assertEquals("Returned incorrect String", "-127", Byte.toString((byte) -127));
+ assertEquals("Returned incorrect String", "-128", Byte.toString((byte) -128));
+ }
+
+ /**
+ * java.lang.Byte#valueOf(java.lang.String)
+ */
+ public void test_valueOfLjava_lang_String2() {
+ assertEquals("Returned incorrect byte", 0, Byte.valueOf("0").byteValue());
+ assertEquals("Returned incorrect byte", 127, Byte.valueOf("127").byteValue());
+ assertEquals("Returned incorrect byte", -127, Byte.valueOf("-127").byteValue());
+ assertEquals("Returned incorrect byte", -128, Byte.valueOf("-128").byteValue());
+
+ try {
+ Byte.valueOf("128");
+ fail("Failed to throw exception when passes value > byte");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Byte#valueOf(java.lang.String, int)
+ */
+ public void test_valueOfLjava_lang_StringI2() {
+ assertEquals("Returned incorrect byte", 10, Byte.valueOf("A", 16).byteValue());
+ assertEquals("Returned incorrect byte", 127, Byte.valueOf("127", 10).byteValue());
+ assertEquals("Returned incorrect byte", -127, Byte.valueOf("-127", 10).byteValue());
+ assertEquals("Returned incorrect byte", -128, Byte.valueOf("-128", 10).byteValue());
+ assertEquals("Returned incorrect byte", 127, Byte.valueOf("7f", 16).byteValue());
+ assertEquals("Returned incorrect byte", -127, Byte.valueOf("-7f", 16).byteValue());
+ assertEquals("Returned incorrect byte", -128, Byte.valueOf("-80", 16).byteValue());
+
+ try {
+ Byte.valueOf("128", 10);
+ fail("Failed to throw exception when passes value > byte");
+ } catch (NumberFormatException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CharacterImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CharacterImplTest.java
new file mode 100644
index 0000000..4db5b82
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CharacterImplTest.java
@@ -0,0 +1,38 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class CharacterImplTest extends TestCase {
+
+ public void test_valueOfC() {
+ // test the cache range
+ for (char c = '\u0000'; c < 128; c++) {
+ Character e = new Character(c);
+ Character a = Character.valueOf(c);
+ assertEquals(e, a);
+
+ // WARN: this assertion may not be valid on other JREs
+ assertSame(Character.valueOf(c), Character.valueOf(c));
+ }
+ // test the rest of the chars
+ for (int c = 128; c <= Character.MAX_VALUE; c++) {
+ assertEquals(new Character((char) c), Character.valueOf((char) c));
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CharacterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CharacterTest.java
new file mode 100644
index 0000000..eaaae86
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CharacterTest.java
@@ -0,0 +1,1637 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+public class CharacterTest extends TestCase {
+
+ public void test_isValidCodePointI() {
+ assertFalse(Character.isValidCodePoint(-1));
+ assertTrue(Character.isValidCodePoint(0));
+ assertTrue(Character.isValidCodePoint(1));
+ assertFalse(Character.isValidCodePoint(Integer.MAX_VALUE));
+
+ for (int c = '\u0000'; c <= 0x10FFFF; c++) {
+ assertTrue(Character.isValidCodePoint(c));
+ }
+
+ assertFalse(Character.isValidCodePoint(0x10FFFF + 1));
+ }
+
+ public void test_isSupplementaryCodePointI() {
+ assertFalse(Character.isSupplementaryCodePoint(-1));
+
+ for (int c = '\u0000'; c <= '\uFFFF'; c++) {
+ assertFalse(Character.isSupplementaryCodePoint(c));
+ }
+
+ for (int c = 0xFFFF + 1; c <= 0x10FFFF; c++) {
+ assertTrue(Character.isSupplementaryCodePoint(c));
+ }
+
+ assertFalse(Character.isSupplementaryCodePoint(0x10FFFF + 1));
+ }
+
+ public void test_isHighSurrogateC() {
+ // (\uD800-\uDBFF)
+ assertFalse(Character.isHighSurrogate((char) ('\uD800' - 1)));
+ for (int c = '\uD800'; c <= '\uDBFF'; c++) {
+ assertTrue(Character.isHighSurrogate((char) c));
+ }
+ assertFalse(Character.isHighSurrogate((char) ('\uDBFF' + 1)));
+ assertFalse(Character.isHighSurrogate('\uFFFF'));
+ }
+
+ public void test_isLowSurrogateC() {
+ // (\uDC00-\uDFFF)
+ assertFalse(Character.isLowSurrogate((char) ('\uDC00' - 1)));
+ for (int c = '\uDC00'; c <= '\uDFFF'; c++) {
+ assertTrue(Character.isLowSurrogate((char) c));
+ }
+ assertFalse(Character.isLowSurrogate((char) ('\uDFFF' + 1)));
+ }
+
+ public void test_isSurrogatePairCC() {
+ assertFalse(Character.isSurrogatePair('\u0000', '\u0000'));
+ assertFalse(Character.isSurrogatePair('\u0000', '\uDC00'));
+
+ assertTrue(Character.isSurrogatePair('\uD800', '\uDC00'));
+ assertTrue(Character.isSurrogatePair('\uD800', '\uDFFF'));
+ assertTrue(Character.isSurrogatePair('\uDBFF', '\uDFFF'));
+
+ assertFalse(Character.isSurrogatePair('\uDBFF', '\uF000'));
+ }
+
+ public void test_charCountI() {
+ for (int c = '\u0000'; c <= '\uFFFF'; c++) {
+ assertEquals(1, Character.charCount(c));
+ }
+
+ for (int c = 0xFFFF + 1; c <= 0x10FFFF; c++) {
+ assertEquals(2, Character.charCount(c));
+ }
+
+ // invalid code points work in this method
+ assertEquals(2, Character.charCount(Integer.MAX_VALUE));
+ }
+
+ public void test_toCodePointCC() {
+ int result = Character.toCodePoint('\uD800', '\uDC00');
+ assertEquals(0x00010000, result);
+
+ result = Character.toCodePoint('\uD800', '\uDC01');
+ assertEquals(0x00010001, result);
+
+ result = Character.toCodePoint('\uD801', '\uDC01');
+ assertEquals(0x00010401, result);
+
+ result = Character.toCodePoint('\uDBFF', '\uDFFF');
+ assertEquals(0x00010FFFF, result);
+ }
+
+ @SuppressWarnings("cast")
+ public void test_codePointAtLjava_lang_CharSequenceI() {
+ assertEquals('a', Character.codePointAt("abc", 0));
+ assertEquals('b', Character.codePointAt("abc", 1));
+ assertEquals('c', Character.codePointAt("abc", 2));
+ assertEquals(0x10000, Character.codePointAt("\uD800\uDC00", 0));
+ assertEquals('\uDC00', Character.codePointAt("\uD800\uDC00", 1));
+
+ try {
+ Character.codePointAt((CharSequence) null, 0);
+ fail("No NPE.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.codePointAt("abc", -1);
+ fail("No IOOBE, negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointAt("abc", 4);
+ fail("No IOOBE, index too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_codePointAt$CI() {
+ assertEquals('a', Character.codePointAt("abc".toCharArray(), 0));
+ assertEquals('b', Character.codePointAt("abc".toCharArray(), 1));
+ assertEquals('c', Character.codePointAt("abc".toCharArray(), 2));
+ assertEquals(0x10000, Character.codePointAt("\uD800\uDC00".toCharArray(), 0));
+ assertEquals('\uDC00', Character.codePointAt("\uD800\uDC00".toCharArray(), 1));
+
+ try {
+ Character.codePointAt((char[]) null, 0);
+ fail("No NPE.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.codePointAt("abc".toCharArray(), -1);
+ fail("No IOOBE, negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointAt("abc".toCharArray(), 4);
+ fail("No IOOBE, index too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_codePointAt$CII() {
+ assertEquals('a', Character.codePointAt("abc".toCharArray(), 0, 3));
+ assertEquals('b', Character.codePointAt("abc".toCharArray(), 1, 3));
+ assertEquals('c', Character.codePointAt("abc".toCharArray(), 2, 3));
+ assertEquals(0x10000, Character.codePointAt("\uD800\uDC00".toCharArray(), 0, 2));
+ assertEquals('\uDC00', Character.codePointAt("\uD800\uDC00".toCharArray(), 1, 2));
+ assertEquals('\uD800', Character.codePointAt("\uD800\uDC00".toCharArray(), 0, 1));
+
+ try {
+ Character.codePointAt(null, 0, 1);
+ fail("No NPE.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.codePointAt("abc".toCharArray(), -1, 3);
+ fail("No IOOBE, negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointAt("abc".toCharArray(), 4, 3);
+ fail("No IOOBE, index too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointAt("abc".toCharArray(), 2, 1);
+ fail("No IOOBE, index larger than limit.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointAt("abc".toCharArray(), 2, -1);
+ fail("No IOOBE, limit is negative.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ @SuppressWarnings("cast")
+ public void test_codePointBeforeLjava_lang_CharSequenceI() {
+ assertEquals('a', Character.codePointBefore("abc", 1));
+ assertEquals('b', Character.codePointBefore("abc", 2));
+ assertEquals('c', Character.codePointBefore("abc", 3));
+ assertEquals(0x10000, Character.codePointBefore("\uD800\uDC00", 2));
+ assertEquals('\uD800', Character.codePointBefore("\uD800\uDC00", 1));
+
+ try {
+ Character.codePointBefore((CharSequence) null, 0);
+ fail("No NPE.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.codePointBefore("abc", 0);
+ fail("No IOOBE, index below one.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointBefore("abc", 4);
+ fail("No IOOBE, index too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_codePointBefore$CI() {
+ assertEquals('a', Character.codePointBefore("abc".toCharArray(), 1));
+ assertEquals('b', Character.codePointBefore("abc".toCharArray(), 2));
+ assertEquals('c', Character.codePointBefore("abc".toCharArray(), 3));
+ assertEquals(0x10000, Character.codePointBefore("\uD800\uDC00".toCharArray(), 2));
+ assertEquals('\uD800', Character.codePointBefore("\uD800\uDC00".toCharArray(), 1));
+
+ try {
+ Character.codePointBefore((char[]) null, 0);
+ fail("No NPE.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.codePointBefore("abc".toCharArray(), -1);
+ fail("No IOOBE, negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointBefore("abc".toCharArray(), 4);
+ fail("No IOOBE, index too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_codePointBefore$CII() {
+ assertEquals('a', Character.codePointBefore("abc".toCharArray(), 1, 0));
+ assertEquals('b', Character.codePointBefore("abc".toCharArray(), 2, 0));
+ assertEquals('c', Character.codePointBefore("abc".toCharArray(), 3, 0));
+ assertEquals(0x10000, Character.codePointBefore("\uD800\uDC00".toCharArray(), 2, 0));
+ assertEquals('\uDC00', Character.codePointBefore("\uD800\uDC00".toCharArray(), 2, 1));
+ assertEquals('\uD800', Character.codePointBefore("\uD800\uDC00".toCharArray(), 1, 0));
+
+ try {
+ Character.codePointBefore(null, 1, 0);
+ fail("No NPE.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.codePointBefore("abc".toCharArray(), 0, 1);
+ fail("No IOOBE, index less than start.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointBefore("abc".toCharArray(), 4, 0);
+ fail("No IOOBE, index larger than length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointBefore("abc".toCharArray(), 2, -1);
+ fail("No IOOBE, start is negative.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointBefore("abc".toCharArray(), 2, 4);
+ fail("No IOOBE, start larger than length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_toCharsI$CI() {
+ char[] dst = new char[2];
+ int result = Character.toChars(0x10000, dst, 0);
+ assertEquals(2, result);
+ assertTrue(Arrays.equals(new char[] { '\uD800', '\uDC00' }, dst));
+
+ result = Character.toChars(0x10001, dst, 0);
+ assertEquals(2, result);
+ assertTrue(Arrays.equals(new char[] { '\uD800', '\uDC01' }, dst));
+
+ result = Character.toChars(0x10401, dst, 0);
+ assertEquals(2, result);
+ assertTrue(Arrays.equals(new char[] { '\uD801', '\uDC01' }, dst));
+
+ result = Character.toChars(0x10FFFF, dst, 0);
+ assertEquals(2, result);
+ assertTrue(Arrays.equals(new char[] { '\uDBFF', '\uDFFF' }, dst));
+
+ try {
+ Character.toChars(Integer.MAX_VALUE, new char[2], 0);
+ fail("No IAE, invalid code point.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ Character.toChars('a', null, 0);
+ fail("No NPE, null char[].");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.toChars('a', new char[1], -1);
+ fail("No IOOBE, negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.toChars('a', new char[1], 1);
+ fail("No IOOBE, index equal to length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_toCharsI() {
+ assertTrue(Arrays.equals(new char[] { '\uD800', '\uDC00' }, Character.toChars(0x10000)));
+ assertTrue(Arrays.equals(new char[] { '\uD800', '\uDC01' }, Character.toChars(0x10001)));
+ assertTrue(Arrays.equals(new char[] { '\uD801', '\uDC01' }, Character.toChars(0x10401)));
+ assertTrue(Arrays.equals(new char[] { '\uDBFF', '\uDFFF' }, Character.toChars(0x10FFFF)));
+
+ try {
+ Character.toChars(Integer.MAX_VALUE);
+ fail("No IAE, invalid code point.");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void test_codePointCountLjava_lang_CharSequenceII() {
+ assertEquals(1, Character.codePointCount("\uD800\uDC00", 0, 2));
+ assertEquals(1, Character.codePointCount("\uD800\uDC01", 0, 2));
+ assertEquals(1, Character.codePointCount("\uD801\uDC01", 0, 2));
+ assertEquals(1, Character.codePointCount("\uDBFF\uDFFF", 0, 2));
+
+ assertEquals(3, Character.codePointCount("a\uD800\uDC00b", 0, 4));
+ assertEquals(4, Character.codePointCount("a\uD800\uDC00b\uD800", 0, 5));
+
+ try {
+ Character.codePointCount((CharSequence) null, 0, 1);
+ fail("No NPE, null char sequence.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.codePointCount("abc", -1, 1);
+ fail("No IOOBE, negative start.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointCount("abc", 0, 4);
+ fail("No IOOBE, end greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.codePointCount("abc", 2, 1);
+ fail("No IOOBE, end greater than start.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_offsetByCodePointsLjava_lang_CharSequenceII() {
+ int result = Character.offsetByCodePoints("a\uD800\uDC00b", 0, 2);
+ assertEquals(3, result);
+
+ result = Character.offsetByCodePoints("abcd", 3, -1);
+ assertEquals(2, result);
+
+ result = Character.offsetByCodePoints("a\uD800\uDC00b", 0, 3);
+ assertEquals(4, result);
+
+ result = Character.offsetByCodePoints("a\uD800\uDC00b", 3, -1);
+ assertEquals(1, result);
+
+ result = Character.offsetByCodePoints("a\uD800\uDC00b", 3, 0);
+ assertEquals(3, result);
+
+ result = Character.offsetByCodePoints("\uD800\uDC00bc", 3, 0);
+ assertEquals(3, result);
+
+ result = Character.offsetByCodePoints("a\uDC00bc", 3, -1);
+ assertEquals(2, result);
+
+ result = Character.offsetByCodePoints("a\uD800bc", 3, -1);
+ assertEquals(2, result);
+
+ try {
+ Character.offsetByCodePoints(null, 0, 1);
+ fail();
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abc", -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abc", 4, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abc", 1, 3);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abc", 1, -2);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_offsetByCodePoints$CIIII() {
+ int result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(), 0, 4, 0, 2);
+ assertEquals(3, result);
+
+ result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(), 0, 4, 0, 3);
+ assertEquals(4, result);
+
+ result = Character.offsetByCodePoints("a\uD800\uDC00b\uD800c".toCharArray(), 0, 5, 0, 3);
+ assertEquals(4, result);
+
+ result = Character.offsetByCodePoints("abcd".toCharArray(), 0, 4, 3, -1);
+ assertEquals(2, result);
+
+ result = Character.offsetByCodePoints("abcd".toCharArray(), 1, 2, 3, -2);
+ assertEquals(1, result);
+
+ result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(), 0, 4, 3, -1);
+ assertEquals(1, result);
+
+ result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(), 0, 2, 2, -1);
+ assertEquals(1, result);
+
+ result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(), 0, 4, 3, 0);
+ assertEquals(3, result);
+
+ result = Character.offsetByCodePoints("\uD800\uDC00bc".toCharArray(), 0, 4, 3, 0);
+ assertEquals(3, result);
+
+ result = Character.offsetByCodePoints("a\uDC00bc".toCharArray(), 0, 4, 3, -1);
+ assertEquals(2, result);
+
+ result = Character.offsetByCodePoints("a\uD800bc".toCharArray(), 0, 4, 3, -1);
+ assertEquals(2, result);
+
+ try {
+ Character.offsetByCodePoints(null, 0, 4, 1, 1);
+ fail();
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abcd".toCharArray(), -1, 4, 1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abcd".toCharArray(), 0, -1, 1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abcd".toCharArray(), 2, 4, 1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abcd".toCharArray(), 1, 3, 0, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abcd".toCharArray(), 1, 1, 3, 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abc".toCharArray(), 0, 3, 1, 3);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abc".toCharArray(), 0, 2, 1, 2);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Character.offsetByCodePoints("abc".toCharArray(), 1, 3, 1, -2);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ /**
+ * java.lang.Character#compareTo(Character)
+ */
+ public void test_compareToLjava_lang_Byte() {
+ final Character min = new Character(Character.MIN_VALUE);
+ final Character mid = new Character((char) (Character.MAX_VALUE / 2));
+ final Character max = new Character(Character.MAX_VALUE);
+
+ assertTrue(max.compareTo(max) == 0);
+ assertTrue(min.compareTo(min) == 0);
+ assertTrue(mid.compareTo(mid) == 0);
+
+ assertTrue(max.compareTo(mid) > 0);
+ assertTrue(max.compareTo(min) > 0);
+
+ assertTrue(mid.compareTo(max) < 0);
+ assertTrue(mid.compareTo(min) > 0);
+
+ assertTrue(min.compareTo(mid) < 0);
+ assertTrue(min.compareTo(max) < 0);
+
+ try {
+ min.compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_codePointAt_Invalid() {
+ try {
+ Character.codePointAt(null, 6, 4);
+ fail("Expected IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ Character.codePointAt(null, 4, 6);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ Character.codePointAt(null, 0, 0);
+ fail("Expected IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.Character#Character(char)
+ */
+ public void test_ConstructorC() {
+ assertEquals("Constructor failed", 'T', new Character('T').charValue());
+ }
+
+ /**
+ * java.lang.Character#charValue()
+ */
+ public void test_charValue() {
+ assertEquals("Incorrect char value returned", 'T', new Character('T').charValue());
+ }
+
+ /**
+ * java.lang.Character#compareTo(java.lang.Character)
+ */
+ public void test_compareToLjava_lang_Character() {
+ Character c = new Character('c');
+ Character x = new Character('c');
+ Character y = new Character('b');
+ Character z = new Character('d');
+
+ assertEquals("Returned false for same Character", 0, c.compareTo(c));
+ assertEquals("Returned false for identical Character", 0, c.compareTo(x));
+ assertTrue("Returned other than less than for lesser char", c.compareTo(y) > 0);
+ assertTrue("Returned other than greater than for greater char", c.compareTo(z) < 0);
+ }
+
+ /**
+ * java.lang.Character#digit(char, int)
+ */
+ public void test_digitCI() {
+ assertEquals("Returned incorrect digit", 1, Character.digit('1', 10));
+ assertEquals("Returned incorrect digit", 15, Character.digit('F', 16));
+ }
+
+ /**
+ * java.lang.Character#digit(int, int)
+ */
+ public void test_digit_II() {
+ assertEquals(1, Character.digit((int) '1', 10));
+ assertEquals(15, Character.digit((int) 'F', 16));
+
+ assertEquals(-1, Character.digit(0x0000, 37));
+ assertEquals(-1, Character.digit(0x0045, 10));
+
+ assertEquals(10, Character.digit(0x0041, 20));
+ assertEquals(10, Character.digit(0x0061, 20));
+
+ assertEquals(-1, Character.digit(0x110000, 20));
+ }
+
+ /**
+ * java.lang.Character#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean java.lang.Character.equals(java.lang.Object)
+ assertTrue("Equality test failed", new Character('A').equals(new Character('A')));
+ assertFalse("Equality test failed", (new Character('A').equals(new Character('a'))));
+ }
+
+ /**
+ * java.lang.Character#forDigit(int, int)
+ */
+ public void test_forDigitII() {
+ char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f' };
+ for (int i = 0; i < hexChars.length; i++) {
+ assertTrue("Returned incorrect char for " + Integer.toString(i),
+ Character.forDigit(i, hexChars.length) == hexChars[i]);
+ }
+
+ char decimalChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+ for (int i = 0; i < decimalChars.length; i++) {
+ assertTrue(
+ "Returned incorrect char for " + Integer.toString(i),
+ Character.forDigit(i, decimalChars.length) == decimalChars[i]);
+ }
+
+ }
+
+ /**
+ * java.lang.Character#getNumericValue(char)
+ */
+ public void test_getNumericValueC() {
+ assertEquals("Returned incorrect numeric value 1", 1, Character.getNumericValue('1'));
+ assertEquals("Returned incorrect numeric value 2", 15, Character.getNumericValue('F'));
+ assertEquals("Returned incorrect numeric value 3", -1, Character.getNumericValue('\u221e'));
+ assertEquals("Returned incorrect numeric value 4", -2, Character.getNumericValue('\u00be'));
+ assertEquals("Returned incorrect numeric value 5", 10000,
+ Character.getNumericValue('\u2182'));
+ assertEquals("Returned incorrect numeric value 6", 2, Character.getNumericValue('\uff12'));
+ }
+
+ /**
+ * java.lang.Character#getNumericValue(int)
+ */
+ public void test_getNumericValue_I() {
+ assertEquals(1, Character.getNumericValue((int) '1'));
+ assertEquals(15, Character.getNumericValue((int) 'F'));
+ assertEquals(-1, Character.getNumericValue((int) '\u221e'));
+ assertEquals(-2, Character.getNumericValue((int) '\u00be'));
+ assertEquals(10000, Character.getNumericValue((int) '\u2182'));
+ assertEquals(2, Character.getNumericValue((int) '\uff12'));
+ assertEquals(-1, Character.getNumericValue(0xFFFF));
+
+ assertEquals(-1, Character.getNumericValue(0xFFFF));
+ assertEquals(0, Character.getNumericValue(0x1D7CE));
+ assertEquals(0, Character.getNumericValue(0x1D7D8));
+ assertEquals(-1, Character.getNumericValue(0x2F800));
+ assertEquals(-1, Character.getNumericValue(0x10FFFD));
+ assertEquals(-1, Character.getNumericValue(0x110000));
+
+ assertEquals(50, Character.getNumericValue(0x216C));
+
+ assertEquals(10, Character.getNumericValue(0x0041));
+ assertEquals(35, Character.getNumericValue(0x005A));
+ assertEquals(10, Character.getNumericValue(0x0061));
+ assertEquals(35, Character.getNumericValue(0x007A));
+ assertEquals(10, Character.getNumericValue(0xFF21));
+ assertEquals(35, Character.getNumericValue(0xFF3A));
+
+ assertEquals(10, Character.getNumericValue(0xFF41));
+ assertEquals(35, Character.getNumericValue(0xFF5A));
+ }
+
+ /**
+ * java.lang.Character#getType(char)
+ */
+ public void test_getTypeC() {
+ assertTrue("Returned incorrect type for: \n",
+ Character.getType('\n') == Character.CONTROL);
+ assertTrue("Returned incorrect type for: 1",
+ Character.getType('1') == Character.DECIMAL_DIGIT_NUMBER);
+ assertTrue("Returned incorrect type for: ' '",
+ Character.getType(' ') == Character.SPACE_SEPARATOR);
+ assertTrue("Returned incorrect type for: a",
+ Character.getType('a') == Character.LOWERCASE_LETTER);
+ assertTrue("Returned incorrect type for: A",
+ Character.getType('A') == Character.UPPERCASE_LETTER);
+ assertTrue("Returned incorrect type for: <",
+ Character.getType('<') == Character.MATH_SYMBOL);
+ assertTrue("Returned incorrect type for: ;",
+ Character.getType(';') == Character.OTHER_PUNCTUATION);
+ assertTrue("Returned incorrect type for: _",
+ Character.getType('_') == Character.CONNECTOR_PUNCTUATION);
+ assertTrue("Returned incorrect type for: $",
+ Character.getType('$') == Character.CURRENCY_SYMBOL);
+ assertTrue("Returned incorrect type for: \u2029",
+ Character.getType('\u2029') == Character.PARAGRAPH_SEPARATOR);
+
+ assertEquals("Wrong constant for FORMAT", 16, Character.FORMAT);
+ assertEquals("Wrong constant for PRIVATE_USE", 18, Character.PRIVATE_USE);
+ }
+
+ /**
+ * java.lang.Character#getType(int)
+ */
+ public void test_getType_I() {
+ assertTrue(Character.getType((int) '\n') == Character.CONTROL);
+ assertTrue(Character.getType((int) '1') == Character.DECIMAL_DIGIT_NUMBER);
+ assertTrue(Character.getType((int) ' ') == Character.SPACE_SEPARATOR);
+ assertTrue(Character.getType((int) 'a') == Character.LOWERCASE_LETTER);
+ assertTrue(Character.getType((int) 'A') == Character.UPPERCASE_LETTER);
+ assertTrue(Character.getType((int) '<') == Character.MATH_SYMBOL);
+ assertTrue(Character.getType((int) ';') == Character.OTHER_PUNCTUATION);
+ assertTrue(Character.getType((int) '_') == Character.CONNECTOR_PUNCTUATION);
+ assertTrue(Character.getType((int) '$') == Character.CURRENCY_SYMBOL);
+ assertTrue(Character.getType((int) '\u2029') == Character.PARAGRAPH_SEPARATOR);
+
+ assertTrue(Character.getType(0x9FFF) == Character.UNASSIGNED);
+ assertTrue(Character.getType(0x30000) == Character.UNASSIGNED);
+ assertTrue(Character.getType(0x110000) == Character.UNASSIGNED);
+
+ assertTrue(Character.getType(0x0041) == Character.UPPERCASE_LETTER);
+ assertTrue(Character.getType(0x10400) == Character.UPPERCASE_LETTER);
+
+ assertTrue(Character.getType(0x0061) == Character.LOWERCASE_LETTER);
+ assertTrue(Character.getType(0x10428) == Character.LOWERCASE_LETTER);
+
+ assertTrue(Character.getType(0x01C5) == Character.TITLECASE_LETTER);
+ assertTrue(Character.getType(0x1FFC) == Character.TITLECASE_LETTER);
+
+ assertTrue(Character.getType(0x02B0) == Character.MODIFIER_LETTER);
+ assertTrue(Character.getType(0xFF9F) == Character.MODIFIER_LETTER);
+
+ assertTrue(Character.getType(0x01BB) == Character.OTHER_LETTER);
+ assertTrue(Character.getType(0x2F888) == Character.OTHER_LETTER);
+
+ assertTrue(Character.getType(0x0F82) == Character.NON_SPACING_MARK);
+ assertTrue(Character.getType(0x1D180) == Character.NON_SPACING_MARK);
+
+ assertTrue(Character.getType(0x0488) == Character.ENCLOSING_MARK);
+ assertTrue(Character.getType(0x20DE) == Character.ENCLOSING_MARK);
+
+ assertTrue(Character.getType(0x1938) == Character.COMBINING_SPACING_MARK);
+ assertTrue(Character.getType(0x1D165) == Character.COMBINING_SPACING_MARK);
+
+ assertTrue(Character.getType(0x194D) == Character.DECIMAL_DIGIT_NUMBER);
+ assertTrue(Character.getType(0x1D7CE) == Character.DECIMAL_DIGIT_NUMBER);
+
+ assertTrue(Character.getType(0x2160) == Character.LETTER_NUMBER);
+ assertTrue(Character.getType(0x1034A) == Character.LETTER_NUMBER);
+
+ assertTrue(Character.getType(0x00B2) == Character.OTHER_NUMBER);
+ assertTrue(Character.getType(0x10120) == Character.OTHER_NUMBER);
+
+ assertTrue(Character.getType(0x0020) == Character.SPACE_SEPARATOR);
+ assertTrue(Character.getType(0x3000) == Character.SPACE_SEPARATOR);
+
+ assertTrue(Character.getType(0x2028) == Character.LINE_SEPARATOR);
+
+ assertTrue(Character.getType(0x2029) == Character.PARAGRAPH_SEPARATOR);
+
+ assertTrue(Character.getType(0x0000) == Character.CONTROL);
+ assertTrue(Character.getType(0x009F) == Character.CONTROL);
+
+ assertTrue(Character.getType(0x00AD) == Character.FORMAT);
+ assertTrue(Character.getType(0xE007F) == Character.FORMAT);
+
+ assertTrue(Character.getType(0xE000) == Character.PRIVATE_USE);
+ assertTrue(Character.getType(0x10FFFD) == Character.PRIVATE_USE);
+
+ assertTrue(Character.getType(0xD800) == Character.SURROGATE);
+ assertTrue(Character.getType(0xDFFF) == Character.SURROGATE);
+
+ assertTrue(Character.getType(0xFE31) == Character.DASH_PUNCTUATION);
+ assertTrue(Character.getType(0xFF0D) == Character.DASH_PUNCTUATION);
+
+ assertTrue(Character.getType(0x0028) == Character.START_PUNCTUATION);
+ assertTrue(Character.getType(0xFF62) == Character.START_PUNCTUATION);
+
+ assertTrue(Character.getType(0x0029) == Character.END_PUNCTUATION);
+ assertTrue(Character.getType(0xFF63) == Character.END_PUNCTUATION);
+
+ assertTrue(Character.getType(0x005F) == Character.CONNECTOR_PUNCTUATION);
+ assertTrue(Character.getType(0xFF3F) == Character.CONNECTOR_PUNCTUATION);
+
+ assertTrue(Character.getType(0x2034) == Character.OTHER_PUNCTUATION);
+ assertTrue(Character.getType(0x1039F) == Character.OTHER_PUNCTUATION);
+
+ assertTrue(Character.getType(0x002B) == Character.MATH_SYMBOL);
+ assertTrue(Character.getType(0x1D6C1) == Character.MATH_SYMBOL);
+
+ assertTrue(Character.getType(0x0024) == Character.CURRENCY_SYMBOL);
+ assertTrue(Character.getType(0xFFE6) == Character.CURRENCY_SYMBOL);
+
+ assertTrue(Character.getType(0x005E) == Character.MODIFIER_SYMBOL);
+ assertTrue(Character.getType(0xFFE3) == Character.MODIFIER_SYMBOL);
+
+ assertTrue(Character.getType(0x00A6) == Character.OTHER_SYMBOL);
+ assertTrue(Character.getType(0x1D356) == Character.OTHER_SYMBOL);
+
+ assertTrue(Character.getType(0x00AB) == Character.INITIAL_QUOTE_PUNCTUATION);
+ assertTrue(Character.getType(0x2039) == Character.INITIAL_QUOTE_PUNCTUATION);
+
+ assertTrue(Character.getType(0x00BB) == Character.FINAL_QUOTE_PUNCTUATION);
+ assertTrue(Character.getType(0x203A) == Character.FINAL_QUOTE_PUNCTUATION);
+ }
+
+ /**
+ * java.lang.Character#hashCode()
+ */
+ public void test_hashCode() {
+ assertEquals("Incorrect hash returned", 89, new Character('Y').hashCode());
+ }
+
+ /**
+ * java.lang.Character#isDefined(char)
+ */
+ public void test_isDefinedC() {
+ assertTrue("Defined character returned false", Character.isDefined('v'));
+ assertTrue("Defined character returned false", Character.isDefined('\u6039'));
+ }
+
+ /**
+ * java.lang.Character#isDefined(int)
+ */
+ public void test_isDefined_I() {
+ assertTrue(Character.isDefined((int) 'v'));
+ assertTrue(Character.isDefined((int) '\u6039'));
+ assertTrue(Character.isDefined(0x10300));
+
+ assertFalse(Character.isDefined(0x30000));
+ assertFalse(Character.isDefined(0x3FFFF));
+ assertFalse(Character.isDefined(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isDigit(char)
+ */
+ public void test_isDigitC() {
+ assertTrue("Digit returned false", Character.isDigit('1'));
+ assertFalse("Non-Digit returned false", Character.isDigit('A'));
+ }
+
+ /**
+ * java.lang.Character#isDigit(int)
+ */
+ public void test_isDigit_I() {
+ assertTrue(Character.isDigit((int) '1'));
+ assertFalse(Character.isDigit((int) 'A'));
+
+ assertTrue(Character.isDigit(0x0030));
+ assertTrue(Character.isDigit(0x0035));
+ assertTrue(Character.isDigit(0x0039));
+
+ assertTrue(Character.isDigit(0x0660));
+ assertTrue(Character.isDigit(0x0665));
+ assertTrue(Character.isDigit(0x0669));
+
+ assertTrue(Character.isDigit(0x06F0));
+ assertTrue(Character.isDigit(0x06F5));
+ assertTrue(Character.isDigit(0x06F9));
+
+ assertTrue(Character.isDigit(0x0966));
+ assertTrue(Character.isDigit(0x096A));
+ assertTrue(Character.isDigit(0x096F));
+
+ assertTrue(Character.isDigit(0xFF10));
+ assertTrue(Character.isDigit(0xFF15));
+ assertTrue(Character.isDigit(0xFF19));
+
+ assertTrue(Character.isDigit(0x1D7CE));
+ assertTrue(Character.isDigit(0x1D7D8));
+
+ assertFalse(Character.isDigit(0x2F800));
+ assertFalse(Character.isDigit(0x10FFFD));
+ assertFalse(Character.isDigit(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isIdentifierIgnorable(char)
+ */
+ public void test_isIdentifierIgnorableC() {
+ assertTrue("Ignorable whitespace returned false",
+ Character.isIdentifierIgnorable('\u0007'));
+ assertTrue("Ignorable non - whitespace control returned false",
+ Character.isIdentifierIgnorable('\u000f'));
+ assertTrue("Ignorable join control returned false",
+ Character.isIdentifierIgnorable('\u200e'));
+
+ // the spec is wrong, and our implementation is correct
+ assertTrue("Ignorable bidi control returned false",
+ Character.isIdentifierIgnorable('\u202b'));
+
+ assertTrue("Ignorable format control returned false",
+ Character.isIdentifierIgnorable('\u206c'));
+ assertTrue("Ignorable zero-width no-break returned false",
+ Character.isIdentifierIgnorable('\ufeff'));
+
+ assertFalse("Non-Ignorable returned true", Character.isIdentifierIgnorable('\u0065'));
+ }
+
+ /**
+ * java.lang.Character#isIdentifierIgnorable(int)
+ */
+ public void test_isIdentifierIgnorable_I() {
+ assertTrue(Character.isIdentifierIgnorable(0x0000));
+ assertTrue(Character.isIdentifierIgnorable(0x0004));
+ assertTrue(Character.isIdentifierIgnorable(0x0008));
+
+ assertTrue(Character.isIdentifierIgnorable(0x000E));
+ assertTrue(Character.isIdentifierIgnorable(0x0013));
+ assertTrue(Character.isIdentifierIgnorable(0x001B));
+
+ assertTrue(Character.isIdentifierIgnorable(0x007F));
+ assertTrue(Character.isIdentifierIgnorable(0x008F));
+ assertTrue(Character.isIdentifierIgnorable(0x009F));
+
+ assertTrue(Character.isIdentifierIgnorable(0x202b));
+ assertTrue(Character.isIdentifierIgnorable(0x206c));
+ assertTrue(Character.isIdentifierIgnorable(0xfeff));
+ assertFalse(Character.isIdentifierIgnorable(0x0065));
+
+ assertTrue(Character.isIdentifierIgnorable(0x1D173));
+
+ assertFalse(Character.isIdentifierIgnorable(0x10FFFD));
+ assertFalse(Character.isIdentifierIgnorable(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isMirrored(char)
+ */
+ public void test_isMirrored_C() {
+ assertTrue(Character.isMirrored('\u0028'));
+ assertFalse(Character.isMirrored('\uFFFF'));
+ }
+
+ /**
+ * java.lang.Character#isMirrored(int)
+ */
+ public void test_isMirrored_I() {
+ assertTrue(Character.isMirrored(0x0028));
+ assertFalse(Character.isMirrored(0xFFFF));
+ assertFalse(Character.isMirrored(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isISOControl(char)
+ */
+ public void test_isISOControlC() {
+ // Test for method boolean java.lang.Character.isISOControl(char)
+ for (int i = 0; i < 32; i++) {
+ assertTrue("ISOConstrol char returned false", Character.isISOControl((char) i));
+ }
+
+ for (int i = 127; i < 160; i++) {
+ assertTrue("ISOConstrol char returned false", Character.isISOControl((char) i));
+ }
+ }
+
+ /**
+ * java.lang.Character#isISOControl(int)
+ */
+ public void test_isISOControlI() {
+ // Test for method boolean java.lang.Character.isISOControl(char)
+ for (int i = 0; i < 32; i++) {
+ assertTrue("ISOConstrol char returned false", Character.isISOControl(i));
+ }
+
+ for (int i = 127; i < 160; i++) {
+ assertTrue("ISOConstrol char returned false", Character.isISOControl(i));
+ }
+
+ for (int i = 160; i < 260; i++) {
+ assertFalse("Not ISOConstrol char returned true", Character.isISOControl(i));
+ }
+ }
+
+
+ /**
+ * java.lang.Character#isJavaIdentifierPart(char)
+ */
+ public void test_isJavaIdentifierPartC() {
+ assertTrue("letter returned false", Character.isJavaIdentifierPart('l'));
+ assertTrue("currency returned false", Character.isJavaIdentifierPart('$'));
+ assertTrue("digit returned false", Character.isJavaIdentifierPart('9'));
+ assertTrue("connecting char returned false", Character.isJavaIdentifierPart('_'));
+ assertTrue("ignorable control returned false", Character.isJavaIdentifierPart('\u200b'));
+ assertFalse("semi returned true", Character.isJavaIdentifierPart(';'));
+ }
+
+ /**
+ * java.lang.Character#isJavaIdentifierPart(int)
+ */
+ public void test_isJavaIdentifierPart_I() {
+ assertTrue(Character.isJavaIdentifierPart((int) 'l'));
+ assertTrue(Character.isJavaIdentifierPart((int) '$'));
+ assertTrue(Character.isJavaIdentifierPart((int) '9'));
+ assertTrue(Character.isJavaIdentifierPart((int) '_'));
+ assertFalse(Character.isJavaIdentifierPart((int) ';'));
+
+ assertTrue(Character.isJavaIdentifierPart(0x0041));
+ assertTrue(Character.isJavaIdentifierPart(0x10400));
+ assertTrue(Character.isJavaIdentifierPart(0x0061));
+ assertTrue(Character.isJavaIdentifierPart(0x10428));
+ assertTrue(Character.isJavaIdentifierPart(0x01C5));
+ assertTrue(Character.isJavaIdentifierPart(0x1FFC));
+ assertTrue(Character.isJavaIdentifierPart(0x02B0));
+ assertTrue(Character.isJavaIdentifierPart(0xFF9F));
+ assertTrue(Character.isJavaIdentifierPart(0x01BB));
+ assertTrue(Character.isJavaIdentifierPart(0x2F888));
+
+ assertTrue(Character.isJavaIdentifierPart(0x0024));
+ assertTrue(Character.isJavaIdentifierPart(0xFFE6));
+
+ assertTrue(Character.isJavaIdentifierPart(0x005F));
+ assertTrue(Character.isJavaIdentifierPart(0xFF3F));
+
+ assertTrue(Character.isJavaIdentifierPart(0x194D));
+ assertTrue(Character.isJavaIdentifierPart(0x1D7CE));
+ assertTrue(Character.isJavaIdentifierPart(0x2160));
+ assertTrue(Character.isJavaIdentifierPart(0x1034A));
+
+ assertTrue(Character.isJavaIdentifierPart(0x0F82));
+ assertTrue(Character.isJavaIdentifierPart(0x1D180));
+
+ assertTrue(Character.isJavaIdentifierPart(0x0000));
+ assertTrue(Character.isJavaIdentifierPart(0x0008));
+ assertTrue(Character.isJavaIdentifierPart(0x000E));
+ assertTrue(Character.isJavaIdentifierPart(0x001B));
+ assertTrue(Character.isJavaIdentifierPart(0x007F));
+ assertTrue(Character.isJavaIdentifierPart(0x009F));
+ assertTrue(Character.isJavaIdentifierPart(0x00AD));
+ assertTrue(Character.isJavaIdentifierPart(0xE007F));
+
+ assertTrue(Character.isJavaIdentifierPart(0x200B));
+ }
+
+ /**
+ * java.lang.Character#isJavaIdentifierStart(char)
+ */
+ public void test_isJavaIdentifierStartC() {
+ assertTrue("letter returned false", Character.isJavaIdentifierStart('l'));
+ assertTrue("currency returned false", Character.isJavaIdentifierStart('$'));
+ assertTrue("connecting char returned false", Character.isJavaIdentifierStart('_'));
+ assertFalse("digit returned true", Character.isJavaIdentifierStart('9'));
+ assertFalse("ignorable control returned true", Character.isJavaIdentifierStart('\u200b'));
+ assertFalse("semi returned true", Character.isJavaIdentifierStart(';'));
+ }
+
+ /**
+ * java.lang.Character#isJavaIdentifierStart(int)
+ */
+ public void test_isJavaIdentifierStart_I() {
+ assertTrue(Character.isJavaIdentifierStart((int) 'l'));
+ assertTrue(Character.isJavaIdentifierStart((int) '$'));
+ assertTrue(Character.isJavaIdentifierStart((int) '_'));
+ assertFalse(Character.isJavaIdentifierStart((int) '9'));
+ assertFalse(Character.isJavaIdentifierStart((int) '\u200b'));
+ assertFalse(Character.isJavaIdentifierStart((int) ';'));
+
+ assertTrue(Character.isJavaIdentifierStart(0x0041));
+ assertTrue(Character.isJavaIdentifierStart(0x10400));
+ assertTrue(Character.isJavaIdentifierStart(0x0061));
+ assertTrue(Character.isJavaIdentifierStart(0x10428));
+ assertTrue(Character.isJavaIdentifierStart(0x01C5));
+ assertTrue(Character.isJavaIdentifierStart(0x1FFC));
+ assertTrue(Character.isJavaIdentifierStart(0x02B0));
+ assertTrue(Character.isJavaIdentifierStart(0xFF9F));
+ assertTrue(Character.isJavaIdentifierStart(0x01BB));
+ assertTrue(Character.isJavaIdentifierStart(0x2F888));
+
+ assertTrue(Character.isJavaIdentifierPart(0x0024));
+ assertTrue(Character.isJavaIdentifierPart(0xFFE6));
+
+ assertTrue(Character.isJavaIdentifierPart(0x005F));
+ assertTrue(Character.isJavaIdentifierPart(0xFF3F));
+
+ assertTrue(Character.isJavaIdentifierPart(0x2160));
+ assertTrue(Character.isJavaIdentifierPart(0x1034A));
+
+ assertFalse(Character.isJavaIdentifierPart(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isJavaLetter(char)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_isJavaLetterC() {
+ assertTrue("letter returned false", Character.isJavaLetter('l'));
+ assertTrue("currency returned false", Character.isJavaLetter('$'));
+ assertTrue("connecting char returned false", Character.isJavaLetter('_'));
+
+ assertFalse("digit returned true", Character.isJavaLetter('9'));
+ assertFalse("ignored control returned true", Character.isJavaLetter('\u200b'));
+ assertFalse("semi returned true", Character.isJavaLetter(';'));
+ }
+
+ /**
+ * java.lang.Character#isJavaLetterOrDigit(char)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_isJavaLetterOrDigitC() {
+ assertTrue("letter returned false", Character.isJavaLetterOrDigit('l'));
+ assertTrue("currency returned false", Character.isJavaLetterOrDigit('$'));
+ assertTrue("digit returned false", Character.isJavaLetterOrDigit('9'));
+ assertTrue("connecting char returned false", Character.isJavaLetterOrDigit('_'));
+ assertFalse("semi returned true", Character.isJavaLetterOrDigit(';'));
+ }
+
+ /**
+ * java.lang.Character#isLetter(char)
+ */
+ public void test_isLetterC() {
+ assertTrue("Letter returned false", Character.isLetter('L'));
+ assertFalse("Non-Letter returned true", Character.isLetter('9'));
+ }
+
+ /**
+ * java.lang.Character#isLetter(int)
+ */
+ public void test_isLetter_I() {
+ assertTrue(Character.isLetter((int) 'L'));
+ assertFalse(Character.isLetter((int) '9'));
+
+ assertTrue(Character.isLetter(0x1FA9));
+ assertTrue(Character.isLetter(0x1D400));
+ assertTrue(Character.isLetter(0x1D622));
+ assertTrue(Character.isLetter(0x10000));
+
+ assertFalse(Character.isLetter(0x1012C));
+ assertFalse(Character.isLetter(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isLetterOrDigit(char)
+ */
+ public void test_isLetterOrDigitC() {
+ assertTrue("Digit returned false", Character.isLetterOrDigit('9'));
+ assertTrue("Letter returned false", Character.isLetterOrDigit('K'));
+ assertFalse("Control returned true", Character.isLetterOrDigit('\n'));
+ assertFalse("Punctuation returned true", Character.isLetterOrDigit('?'));
+ }
+
+ /**
+ * java.lang.Character#isLetterOrDigit(int)
+ */
+ public void test_isLetterOrDigit_I() {
+ assertTrue(Character.isLetterOrDigit((int) '9'));
+ assertTrue(Character.isLetterOrDigit((int) 'K'));
+ assertFalse(Character.isLetterOrDigit((int) '\n'));
+ assertFalse(Character.isLetterOrDigit((int) '?'));
+
+ assertTrue(Character.isLetterOrDigit(0x1FA9));
+ assertTrue(Character.isLetterOrDigit(0x1D400));
+ assertTrue(Character.isLetterOrDigit(0x1D622));
+ assertTrue(Character.isLetterOrDigit(0x10000));
+
+ assertTrue(Character.isLetterOrDigit(0x1D7CE));
+ assertTrue(Character.isLetterOrDigit(0x1D7D8));
+
+ assertFalse(Character.isLetterOrDigit(0x10FFFD));
+ assertFalse(Character.isLetterOrDigit(0x1012C));
+ assertFalse(Character.isLetterOrDigit(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isLowerCase(char)
+ */
+ public void test_isLowerCaseC() {
+ assertTrue("lower returned false", Character.isLowerCase('a'));
+ assertFalse("upper returned true", Character.isLowerCase('T'));
+ }
+
+ /**
+ * java.lang.Character#isLowerCase(int)
+ */
+ public void test_isLowerCase_I() {
+ assertTrue(Character.isLowerCase((int) 'a'));
+ assertFalse(Character.isLowerCase((int) 'T'));
+
+ assertTrue(Character.isLowerCase(0x10428));
+ assertTrue(Character.isLowerCase(0x1D4EA));
+
+ assertFalse(Character.isLowerCase(0x1D504));
+ assertFalse(Character.isLowerCase(0x30000));
+ assertFalse(Character.isLowerCase(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isSpace(char)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_isSpaceC() {
+ // Test for method boolean java.lang.Character.isSpace(char)
+ assertTrue("space returned false", Character.isSpace('\n'));
+ assertFalse("non-space returned true", Character.isSpace('T'));
+ }
+
+ /**
+ * java.lang.Character#isSpaceChar(char)
+ */
+ public void test_isSpaceCharC() {
+ assertTrue("space returned false", Character.isSpaceChar('\u0020'));
+ assertFalse("non-space returned true", Character.isSpaceChar('\n'));
+ }
+
+ /**
+ * java.lang.Character#isSpaceChar(int)
+ */
+ public void test_isSpaceChar_I() {
+ assertTrue(Character.isSpaceChar((int) '\u0020'));
+ assertFalse(Character.isSpaceChar((int) '\n'));
+
+ assertTrue(Character.isSpaceChar(0x2000));
+ assertTrue(Character.isSpaceChar(0x200A));
+
+ assertTrue(Character.isSpaceChar(0x2028));
+ assertTrue(Character.isSpaceChar(0x2029));
+
+ assertFalse(Character.isSpaceChar(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isTitleCase(char)
+ */
+ public void test_isTitleCaseC() {
+ char[] tChars = { (char) 0x01c5, (char) 0x01c8, (char) 0x01cb,
+ (char) 0x01f2, (char) 0x1f88, (char) 0x1f89, (char) 0x1f8a,
+ (char) 0x1f8b, (char) 0x1f8c, (char) 0x1f8d, (char) 0x1f8e,
+ (char) 0x1f8f, (char) 0x1f98, (char) 0x1f99, (char) 0x1f9a,
+ (char) 0x1f9b, (char) 0x1f9c, (char) 0x1f9d, (char) 0x1f9e,
+ (char) 0x1f9f, (char) 0x1fa8, (char) 0x1fa9, (char) 0x1faa,
+ (char) 0x1fab, (char) 0x1fac, (char) 0x1fad, (char) 0x1fae,
+ (char) 0x1faf, (char) 0x1fbc, (char) 0x1fcc, (char) 0x1ffc };
+ byte tnum = 0;
+ for (char c = 0; c < 65535; c++) {
+ if (Character.isTitleCase(c)) {
+ tnum++;
+ int i;
+ for (i = 0; i < tChars.length; i++) {
+ if (tChars[i] == c) {
+ i = tChars.length + 1;
+ }
+ }
+ if (i < tChars.length) {
+ fail("Non Title Case char returned true");
+ }
+ }
+ }
+ assertTrue("Failed to find all Title Case chars", tnum == tChars.length);
+ }
+
+ /**
+ * java.lang.Character#isTitleCase(int)
+ */
+ public void test_isTitleCase_I() {
+ //all the titlecase characters
+ int[] titleCaseCharacters = { 0x01c5, 0x01c8, 0x01cb, 0x01f2, 0x1f88,
+ 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f98,
+ 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa8,
+ 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fbc,
+ 0x1fcc, 0x1ffc };
+
+ for (int titleCaseCharacter : titleCaseCharacters) {
+ assertTrue(Character.isTitleCase(titleCaseCharacter));
+ }
+
+ assertFalse(Character.isTitleCase(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isUnicodeIdentifierPart(char)
+ */
+ public void test_isUnicodeIdentifierPartC() {
+ assertTrue("'a' returned false", Character.isUnicodeIdentifierPart('a'));
+ assertTrue("'2' returned false", Character.isUnicodeIdentifierPart('2'));
+ assertFalse("'+' returned true", Character.isUnicodeIdentifierPart('+'));
+ }
+
+ /**
+ * java.lang.Character#isUnicodeIdentifierPart(int)
+ */
+ public void test_isUnicodeIdentifierPart_I() {
+ assertTrue(Character.isUnicodeIdentifierPart((int) 'a'));
+ assertTrue(Character.isUnicodeIdentifierPart((int) '2'));
+ assertFalse(Character.isUnicodeIdentifierPart((int) '+'));
+
+ assertTrue(Character.isUnicodeIdentifierPart(0x1FA9));
+ assertTrue(Character.isUnicodeIdentifierPart(0x1D400));
+ assertTrue(Character.isUnicodeIdentifierPart(0x1D622));
+ assertTrue(Character.isUnicodeIdentifierPart(0x10000));
+
+ assertTrue(Character.isUnicodeIdentifierPart(0x0030));
+ assertTrue(Character.isUnicodeIdentifierPart(0x0035));
+ assertTrue(Character.isUnicodeIdentifierPart(0x0039));
+
+ assertTrue(Character.isUnicodeIdentifierPart(0x0660));
+ assertTrue(Character.isUnicodeIdentifierPart(0x0665));
+ assertTrue(Character.isUnicodeIdentifierPart(0x0669));
+
+ assertTrue(Character.isUnicodeIdentifierPart(0x06F0));
+ assertTrue(Character.isUnicodeIdentifierPart(0x06F5));
+ assertTrue(Character.isUnicodeIdentifierPart(0x06F9));
+
+ assertTrue(Character.isUnicodeIdentifierPart(0x0966));
+ assertTrue(Character.isUnicodeIdentifierPart(0x096A));
+ assertTrue(Character.isUnicodeIdentifierPart(0x096F));
+
+ assertTrue(Character.isUnicodeIdentifierPart(0xFF10));
+ assertTrue(Character.isUnicodeIdentifierPart(0xFF15));
+ assertTrue(Character.isUnicodeIdentifierPart(0xFF19));
+
+ assertTrue(Character.isUnicodeIdentifierPart(0x1D7CE));
+ assertTrue(Character.isUnicodeIdentifierPart(0x1D7D8));
+
+ assertTrue(Character.isUnicodeIdentifierPart(0x16EE));
+ assertTrue(Character.isUnicodeIdentifierPart(0xFE33));
+ assertTrue(Character.isUnicodeIdentifierPart(0xFF10));
+ assertTrue(Character.isUnicodeIdentifierPart(0x1D165));
+ assertTrue(Character.isUnicodeIdentifierPart(0x1D167));
+ assertTrue(Character.isUnicodeIdentifierPart(0x1D173));
+
+ assertFalse(Character.isUnicodeIdentifierPart(0x10FFFF));
+ assertFalse(Character.isUnicodeIdentifierPart(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isUnicodeIdentifierStart(char)
+ */
+ public void test_isUnicodeIdentifierStartC() {
+ assertTrue("'a' returned false", Character.isUnicodeIdentifierStart('a'));
+ assertFalse("'2' returned true", Character.isUnicodeIdentifierStart('2'));
+ assertFalse("'+' returned true", Character.isUnicodeIdentifierStart('+'));
+ }
+
+ /**
+ * java.lang.Character#isUnicodeIdentifierStart(int)
+ */
+ public void test_isUnicodeIdentifierStart_I() {
+ assertTrue(Character.isUnicodeIdentifierStart((int) 'a'));
+ assertFalse(Character.isUnicodeIdentifierStart((int) '2'));
+ assertFalse(Character.isUnicodeIdentifierStart((int) '+'));
+
+ assertTrue(Character.isUnicodeIdentifierStart(0x1FA9));
+ assertTrue(Character.isUnicodeIdentifierStart(0x1D400));
+ assertTrue(Character.isUnicodeIdentifierStart(0x1D622));
+ assertTrue(Character.isUnicodeIdentifierStart(0x10000));
+
+ assertTrue(Character.isUnicodeIdentifierStart(0x16EE));
+
+ // number is not a valid start of a Unicode identifier
+ assertFalse(Character.isUnicodeIdentifierStart(0x0030));
+ assertFalse(Character.isUnicodeIdentifierStart(0x0039));
+ assertFalse(Character.isUnicodeIdentifierStart(0x0660));
+ assertFalse(Character.isUnicodeIdentifierStart(0x0669));
+ assertFalse(Character.isUnicodeIdentifierStart(0x06F0));
+ assertFalse(Character.isUnicodeIdentifierStart(0x06F9));
+
+ assertFalse(Character.isUnicodeIdentifierPart(0x10FFFF));
+ assertFalse(Character.isUnicodeIdentifierPart(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isUpperCase(char)
+ */
+ public void test_isUpperCaseC() {
+ assertFalse("Incorrect case value", Character.isUpperCase('t'));
+ assertTrue("Incorrect case value", Character.isUpperCase('T'));
+ }
+
+ /**
+ * java.lang.Character#isUpperCase(int)
+ */
+ public void test_isUpperCase_I() {
+ assertFalse(Character.isUpperCase((int) 't'));
+ assertTrue(Character.isUpperCase((int) 'T'));
+
+ assertTrue(Character.isUpperCase(0x1D504));
+ assertTrue(Character.isUpperCase(0x1D608));
+
+ assertFalse(Character.isUpperCase(0x1D656));
+ assertFalse(Character.isUpperCase(0x10FFFD));
+ assertFalse(Character.isUpperCase(0x110000));
+ }
+
+ /**
+ * java.lang.Character#isWhitespace(char)
+ */
+ public void test_isWhitespaceC() {
+ assertTrue("space returned false", Character.isWhitespace('\n'));
+ assertFalse("non-space returned true", Character.isWhitespace('T'));
+ }
+
+ /**
+ * java.lang.Character#isWhitespace(int)
+ */
+ public void test_isWhitespace_I() {
+ assertTrue(Character.isWhitespace((int) '\n'));
+ assertFalse(Character.isWhitespace((int) 'T'));
+
+ assertTrue(Character.isWhitespace(0x0009));
+ assertTrue(Character.isWhitespace(0x000A));
+ assertTrue(Character.isWhitespace(0x000B));
+ assertTrue(Character.isWhitespace(0x000C));
+ assertTrue(Character.isWhitespace(0x000D));
+ assertTrue(Character.isWhitespace(0x001C));
+ assertTrue(Character.isWhitespace(0x001D));
+ assertTrue(Character.isWhitespace(0x001F));
+ assertTrue(Character.isWhitespace(0x001E));
+
+ assertTrue(Character.isWhitespace(0x2000));
+ assertTrue(Character.isWhitespace(0x200A));
+
+ assertTrue(Character.isWhitespace(0x2028));
+ assertTrue(Character.isWhitespace(0x2029));
+
+ assertFalse(Character.isWhitespace(0x00A0));
+ assertFalse(Character.isWhitespace(0x202F));
+ assertFalse(Character.isWhitespace(0x110000));
+
+ assertFalse(Character.isWhitespace(0xFEFF));
+
+ assertFalse(Character.isWhitespace(0x2007));
+
+ }
+
+ /**
+ * java.lang.Character#reverseBytes(char)
+ */
+ public void test_reverseBytesC() {
+ char original[] = new char[] { 0x0000, 0x0010, 0x00AA, 0xB000, 0xCC00, 0xABCD, 0xFFAA };
+ char reversed[] = new char[] { 0x0000, 0x1000, 0xAA00, 0x00B0, 0x00CC, 0xCDAB, 0xAAFF };
+ assertTrue("Test self check", original.length == reversed.length);
+
+ for (int i = 0; i < original.length; i++) {
+ char origChar = original[i];
+ char reversedChar = reversed[i];
+ char origReversed = Character.reverseBytes(origChar);
+
+ assertTrue("java.lang.Character.reverseBytes failed: orig char="
+ + Integer.toHexString(origChar) + ", reversed char="
+ + Integer.toHexString(origReversed), reversedChar == origReversed);
+ }
+ }
+
+ /**
+ * java.lang.Character#toLowerCase(char)
+ */
+ public void test_toLowerCaseC() {
+ assertEquals("Failed to change case", 't', Character.toLowerCase('T'));
+ }
+
+ /**
+ * java.lang.Character#toLowerCase(int)
+ */
+ public void test_toLowerCase_I() {
+ assertEquals('t', Character.toLowerCase((int) 'T'));
+
+ assertEquals(0x10428, Character.toLowerCase(0x10400));
+ assertEquals(0x10428, Character.toLowerCase(0x10428));
+
+ assertEquals(0x1D504, Character.toLowerCase(0x1D504));
+ assertEquals(0x10FFFD, Character.toLowerCase(0x10FFFD));
+ assertEquals(0x110000, Character.toLowerCase(0x110000));
+ }
+
+ /**
+ * java.lang.Character#toString()
+ */
+ public void test_toString() {
+ assertEquals("Incorrect String returned", "T", new Character('T').toString());
+ }
+
+ /**
+ * java.lang.Character#toTitleCase(char)
+ */
+ public void test_toTitleCaseC() {
+ assertEquals("Incorrect title case for a", 'A', Character.toTitleCase('a'));
+ assertEquals("Incorrect title case for A", 'A', Character.toTitleCase('A'));
+ assertEquals("Incorrect title case for 1", '1', Character.toTitleCase('1'));
+ }
+
+ /**
+ * java.lang.Character#toTitleCase(int)
+ */
+ public void test_toTitleCase_I() {
+ assertEquals('A', Character.toTitleCase((int) 'a'));
+ assertEquals('A', Character.toTitleCase((int) 'A'));
+ assertEquals('1', Character.toTitleCase((int) '1'));
+
+ assertEquals(0x10400, Character.toTitleCase(0x10428));
+ assertEquals(0x10400, Character.toTitleCase(0x10400));
+
+ assertEquals(0x10FFFF, Character.toTitleCase(0x10FFFF));
+ assertEquals(0x110000, Character.toTitleCase(0x110000));
+ }
+
+ /**
+ * java.lang.Character#toUpperCase(char)
+ */
+ public void test_toUpperCaseC() {
+ // Test for method char java.lang.Character.toUpperCase(char)
+ assertEquals("Incorrect upper case for a", 'A', Character.toUpperCase('a'));
+ assertEquals("Incorrect upper case for A", 'A', Character.toUpperCase('A'));
+ assertEquals("Incorrect upper case for 1", '1', Character.toUpperCase('1'));
+ }
+
+ /**
+ * java.lang.Character#toUpperCase(int)
+ */
+ public void test_toUpperCase_I() {
+ assertEquals('A', Character.toUpperCase((int) 'a'));
+ assertEquals('A', Character.toUpperCase((int) 'A'));
+ assertEquals('1', Character.toUpperCase((int) '1'));
+
+ assertEquals(0x10400, Character.toUpperCase(0x10428));
+ assertEquals(0x10400, Character.toUpperCase(0x10400));
+
+ assertEquals(0x10FFFF, Character.toUpperCase(0x10FFFF));
+ assertEquals(0x110000, Character.toUpperCase(0x110000));
+ }
+
+ /**
+ * java.lang.Character#getDirectionality(int)
+ */
+ public void test_isDirectionaliy_I() {
+ assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character.getDirectionality(0xFFFE));
+ assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character.getDirectionality(0x30000));
+ assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character.getDirectionality(0x110000));
+ assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character.getDirectionality(-1));
+
+ assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT, Character.getDirectionality(0x0041));
+ assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT, Character.getDirectionality(0x10000));
+ assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT, Character.getDirectionality(0x104A9));
+
+ assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT, Character.getDirectionality(0xFB4F));
+ assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT, Character.getDirectionality(0x10838));
+ // Unicode standard 5.1 changed category of unicode point 0x0600 from AL to AN
+ assertEquals(Character.DIRECTIONALITY_ARABIC_NUMBER, Character.getDirectionality(0x0600));
+ assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC,
+ Character.getDirectionality(0xFEFC));
+
+ assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER, Character.getDirectionality(0x2070));
+ assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER,
+ Character.getDirectionality(0x1D7FF));
+
+ assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR,
+ Character.getDirectionality(0x002B));
+ assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR,
+ Character.getDirectionality(0xFF0B));
+
+ assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR,
+ Character.getDirectionality(0x0023));
+ assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR,
+ Character.getDirectionality(0x17DB));
+
+ assertEquals(Character.DIRECTIONALITY_ARABIC_NUMBER, Character.getDirectionality(0x0660));
+ assertEquals(Character.DIRECTIONALITY_ARABIC_NUMBER, Character.getDirectionality(0x066C));
+
+ assertEquals(Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR,
+ Character.getDirectionality(0x002C));
+ assertEquals(Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR,
+ Character.getDirectionality(0xFF1A));
+
+ assertEquals(Character.DIRECTIONALITY_NONSPACING_MARK, Character.getDirectionality(0x17CE));
+ assertEquals(Character.DIRECTIONALITY_NONSPACING_MARK,
+ Character.getDirectionality(0xE01DB));
+
+ assertEquals(Character.DIRECTIONALITY_BOUNDARY_NEUTRAL,
+ Character.getDirectionality(0x0000));
+ assertEquals(Character.DIRECTIONALITY_BOUNDARY_NEUTRAL,
+ Character.getDirectionality(0xE007F));
+
+ assertEquals(Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR,
+ Character.getDirectionality(0x000A));
+ assertEquals(Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR,
+ Character.getDirectionality(0x2029));
+
+ assertEquals(Character.DIRECTIONALITY_SEGMENT_SEPARATOR,
+ Character.getDirectionality(0x0009));
+ assertEquals(Character.DIRECTIONALITY_SEGMENT_SEPARATOR,
+ Character.getDirectionality(0x001F));
+
+ assertEquals(Character.DIRECTIONALITY_WHITESPACE, Character.getDirectionality(0x0020));
+ assertEquals(Character.DIRECTIONALITY_WHITESPACE, Character.getDirectionality(0x3000));
+
+ assertEquals(Character.DIRECTIONALITY_OTHER_NEUTRALS, Character.getDirectionality(0x2FF0));
+ assertEquals(Character.DIRECTIONALITY_OTHER_NEUTRALS, Character.getDirectionality(0x1D356));
+
+ assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING,
+ Character.getDirectionality(0x202A));
+
+ assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE,
+ Character.getDirectionality(0x202D));
+
+ assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING,
+ Character.getDirectionality(0x202B));
+
+ assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
+ Character.getDirectionality(0x202E));
+
+ assertEquals(Character.DIRECTIONALITY_POP_DIRECTIONAL_FORMAT,
+ Character.getDirectionality(0x202C));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Character_SubsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Character_SubsetTest.java
new file mode 100644
index 0000000..41408ec
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Character_SubsetTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class Character_SubsetTest extends TestCase {
+
+ /**
+ * java.lang.Character.Subset#Character.Subset(java.lang.String)
+ */
+ public void test_Ctor() {
+
+ try {
+ // Regression for HARMONY-888
+ new Character.Subset(null) {
+ };
+ fail("No expected NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Character.Subset#toString()
+ */
+ public void test_toString() {
+
+ String name = "name";
+ Character.Subset subset = new Character.Subset(name) {
+ };
+ assertSame(name, subset.toString());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Character_UnicodeBlockTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Character_UnicodeBlockTest.java
new file mode 100644
index 0000000..792ee3d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Character_UnicodeBlockTest.java
@@ -0,0 +1,822 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class Character_UnicodeBlockTest extends TestCase {
+
+ public void test_ofC() {
+ assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of((char) 0x0));
+ assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of((char) 0x7f));
+ assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.of((char) 0x80));
+ assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.of((char) 0xff));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.of((char) 0x100));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.of((char) 0x17f));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.of((char) 0x180));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.of((char) 0x24f));
+ assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.of((char) 0x250));
+ assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.of((char) 0x2af));
+ assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.of((char) 0x2b0));
+ assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.of((char) 0x2ff));
+ assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.of((char) 0x300));
+ assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.of((char) 0x36f));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.of((char) 0x370));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.of((char) 0x3ff));
+ assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.of((char) 0x400));
+ assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.of((char) 0x4ff));
+ assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.of((char) 0x500));
+ assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.of((char) 0x52f));
+ assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.of((char) 0x530));
+ assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.of((char) 0x58f));
+ assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.of((char) 0x590));
+ assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.of((char) 0x5ff));
+ assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.of((char) 0x600));
+ assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.of((char) 0x6ff));
+ assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.of((char) 0x700));
+ assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.of((char) 0x74f));
+ assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.of((char) 0x780));
+ assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.of((char) 0x7bf));
+ assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.of((char) 0x900));
+ assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.of((char) 0x97f));
+ assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.of((char) 0x980));
+ assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.of((char) 0x9ff));
+ assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.of((char) 0xa00));
+ assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.of((char) 0xa7f));
+ assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.of((char) 0xa80));
+ assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.of((char) 0xaff));
+ assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.of((char) 0xb00));
+ assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.of((char) 0xb7f));
+ assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.of((char) 0xb80));
+ assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.of((char) 0xbff));
+ assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.of((char) 0xc00));
+ assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.of((char) 0xc7f));
+ assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.of((char) 0xc80));
+ assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.of((char) 0xcff));
+ assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.of((char) 0xd00));
+ assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.of((char) 0xd7f));
+ assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.of((char) 0xd80));
+ assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.of((char) 0xdff));
+ assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.of((char) 0xe00));
+ assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.of((char) 0xe7f));
+ assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.of((char) 0xe80));
+ assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.of((char) 0xeff));
+ assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.of((char) 0xf00));
+ assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.of((char) 0xfff));
+ assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.of((char) 0x1000));
+ assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.of((char) 0x109f));
+ assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.of((char) 0x10a0));
+ assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.of((char) 0x10ff));
+ assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.of((char) 0x1100));
+ assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.of((char) 0x11ff));
+ assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.of((char) 0x1200));
+ assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.of((char) 0x137f));
+ assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.of((char) 0x13a0));
+ assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.of((char) 0x13ff));
+ assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.of((char) 0x1400));
+ assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.of((char) 0x167f));
+ assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.of((char) 0x1680));
+ assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.of((char) 0x169f));
+ assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.of((char) 0x16a0));
+ assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.of((char) 0x16ff));
+ assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.of((char) 0x1700));
+ assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.of((char) 0x171f));
+ assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.of((char) 0x1720));
+ assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.of((char) 0x173f));
+ assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.of((char) 0x1740));
+ assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.of((char) 0x175f));
+ assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.of((char) 0x1760));
+ assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.of((char) 0x177f));
+ assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.of((char) 0x1780));
+ assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.of((char) 0x17ff));
+ assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.of((char) 0x1800));
+ assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.of((char) 0x18af));
+ assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.of((char) 0x1900));
+ assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.of((char) 0x194f));
+ assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.of((char) 0x1950));
+ assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.of((char) 0x197f));
+ assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.of((char) 0x19e0));
+ assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.of((char) 0x19ff));
+ assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.of((char) 0x1d00));
+ assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.of((char) 0x1d7f));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.of((char) 0x1e00));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.of((char) 0x1eff));
+ assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.of((char) 0x1f00));
+ assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.of((char) 0x1fff));
+ assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.of((char) 0x2000));
+ assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.of((char) 0x206f));
+ assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.of((char) 0x2070));
+ assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.of((char) 0x209f));
+ assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.of((char) 0x20a0));
+ assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.of((char) 0x20cf));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.of((char) 0x20d0));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.of((char) 0x20ff));
+ assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.of((char) 0x2100));
+ assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.of((char) 0x214f));
+ assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.of((char) 0x2150));
+ assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.of((char) 0x218f));
+ assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.of((char) 0x2190));
+ assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.of((char) 0x21ff));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of((char) 0x2200));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of((char) 0x22ff));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.of((char) 0x2300));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.of((char) 0x23ff));
+ assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.of((char) 0x2400));
+ assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.of((char) 0x243f));
+ assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.of((char) 0x2440));
+ assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.of((char) 0x245f));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.of((char) 0x2460));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.of((char) 0x24ff));
+ assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.of((char) 0x2500));
+ assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.of((char) 0x257f));
+ assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.of((char) 0x2580));
+ assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.of((char) 0x259f));
+ assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.of((char) 0x25a0));
+ assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.of((char) 0x25ff));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.of((char) 0x2600));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.of((char) 0x26ff));
+ assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.of((char) 0x2700));
+ assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.of((char) 0x27bf));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.of((char) 0x27c0));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.of((char) 0x27ef));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.of((char) 0x27f0));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.of((char) 0x27ff));
+ assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.of((char) 0x2800));
+ assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.of((char) 0x28ff));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.of((char) 0x2900));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.of((char) 0x297f));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.of((char) 0x2980));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.of((char) 0x29ff));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of((char) 0x2a00));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of((char) 0x2aff));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.of((char) 0x2b00));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.of((char) 0x2bff));
+ assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.of((char) 0x2e80));
+ assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.of((char) 0x2eff));
+ assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.of((char) 0x2f00));
+ assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.of((char) 0x2fdf));
+ assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.of((char) 0x2ff0));
+ assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.of((char) 0x2fff));
+ assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of((char) 0x3000));
+ assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of((char) 0x303f));
+ assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.of((char) 0x3040));
+ assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.of((char) 0x309f));
+ assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.of((char) 0x30a0));
+ assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.of((char) 0x30ff));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.of((char) 0x3100));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.of((char) 0x312f));
+ assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.of((char) 0x3130));
+ assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.of((char) 0x318f));
+ assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.of((char) 0x3190));
+ assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.of((char) 0x319f));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.of((char) 0x31a0));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.of((char) 0x31bf));
+ assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.of((char) 0x31f0));
+ assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.of((char) 0x31ff));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.of((char) 0x3200));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.of((char) 0x32ff));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.of((char) 0x3300));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.of((char) 0x33ff));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.of((char) 0x3400));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.of((char) 0x4dbf));
+ assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.of((char) 0x4dc0));
+ assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.of((char) 0x4dff));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.of((char) 0x4e00));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.of((char) 0x9fff));
+ assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.of((char) 0xa000));
+ assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.of((char) 0xa48f));
+ assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.of((char) 0xa490));
+ assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.of((char) 0xa4cf));
+ assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.of((char) 0xac00));
+ assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.of((char) 0xd7af));
+ assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.of((char) 0xd800));
+ assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.of((char) 0xdb7f));
+ assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.of((char) 0xdb80));
+ assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.of((char) 0xdbff));
+ assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.of((char) 0xdc00));
+ assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.of((char) 0xdfff));
+ assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of((char) 0xe000));
+ assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of((char) 0xf8ff));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.of((char) 0xf900));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.of((char) 0xfaff));
+ assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.of((char) 0xfb00));
+ assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.of((char) 0xfb4f));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.of((char) 0xfb50));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.of((char) 0xfdff));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.of((char) 0xfe00));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.of((char) 0xfe0f));
+ assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.of((char) 0xfe20));
+ assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.of((char) 0xfe2f));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.of((char) 0xfe30));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.of((char) 0xfe4f));
+ assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.of((char) 0xfe50));
+ assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.of((char) 0xfe6f));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.of((char) 0xfe70));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.of((char) 0xfeff));
+ assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.of((char) 0xff00));
+ assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.of((char) 0xffef));
+ assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of((char) 0xfff0));
+ assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of((char) 0xffff));
+
+ // Negative test: The range [0x0860, 0x08A0) is currently unassigned.
+ assertEquals(null, Character.UnicodeBlock.of((char) 0x0860));
+ assertEquals(null, Character.UnicodeBlock.of((char) 0x089F));
+ }
+
+ public void test_ofI() {
+ assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of(0x0));
+ assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of(0x7f));
+ assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.of(0x80));
+ assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.of(0xff));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.of(0x100));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.of(0x17f));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.of(0x180));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.of(0x24f));
+ assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.of(0x250));
+ assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.of(0x2af));
+ assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.of(0x2b0));
+ assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.of(0x2ff));
+ assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.of(0x300));
+ assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.of(0x36f));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.of(0x370));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.of(0x3ff));
+ assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.of(0x400));
+ assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.of(0x4ff));
+ assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.of(0x500));
+ assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.of(0x52f));
+ assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.of(0x530));
+ assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.of(0x58f));
+ assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.of(0x590));
+ assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.of(0x5ff));
+ assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.of(0x600));
+ assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.of(0x6ff));
+ assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.of(0x700));
+ assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.of(0x74f));
+ assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.of(0x780));
+ assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.of(0x7bf));
+ assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.of(0x900));
+ assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.of(0x97f));
+ assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.of(0x980));
+ assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.of(0x9ff));
+ assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.of(0xa00));
+ assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.of(0xa7f));
+ assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.of(0xa80));
+ assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.of(0xaff));
+ assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.of(0xb00));
+ assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.of(0xb7f));
+ assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.of(0xb80));
+ assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.of(0xbff));
+ assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.of(0xc00));
+ assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.of(0xc7f));
+ assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.of(0xc80));
+ assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.of(0xcff));
+ assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.of(0xd00));
+ assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.of(0xd7f));
+ assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.of(0xd80));
+ assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.of(0xdff));
+ assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.of(0xe00));
+ assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.of(0xe7f));
+ assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.of(0xe80));
+ assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.of(0xeff));
+ assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.of(0xf00));
+ assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.of(0xfff));
+ assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.of(0x1000));
+ assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.of(0x109f));
+ assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.of(0x10a0));
+ assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.of(0x10ff));
+ assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.of(0x1100));
+ assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.of(0x11ff));
+ assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.of(0x1200));
+ assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.of(0x137f));
+ assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.of(0x13a0));
+ assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.of(0x13ff));
+ assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.of(0x1400));
+ assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.of(0x167f));
+ assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.of(0x1680));
+ assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.of(0x169f));
+ assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.of(0x16a0));
+ assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.of(0x16ff));
+ assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.of(0x1700));
+ assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.of(0x171f));
+ assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.of(0x1720));
+ assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.of(0x173f));
+ assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.of(0x1740));
+ assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.of(0x175f));
+ assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.of(0x1760));
+ assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.of(0x177f));
+ assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.of(0x1780));
+ assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.of(0x17ff));
+ assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.of(0x1800));
+ assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.of(0x18af));
+ assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.of(0x1900));
+ assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.of(0x194f));
+ assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.of(0x1950));
+ assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.of(0x197f));
+ assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.of(0x19e0));
+ assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.of(0x19ff));
+ assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.of(0x1d00));
+ assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.of(0x1d7f));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.of(0x1e00));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.of(0x1eff));
+ assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.of(0x1f00));
+ assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.of(0x1fff));
+ assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.of(0x2000));
+ assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.of(0x206f));
+ assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.of(0x2070));
+ assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.of(0x209f));
+ assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.of(0x20a0));
+ assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.of(0x20cf));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.of(0x20d0));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.of(0x20ff));
+ assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.of(0x2100));
+ assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.of(0x214f));
+ assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.of(0x2150));
+ assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.of(0x218f));
+ assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.of(0x2190));
+ assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.of(0x21ff));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of(0x2200));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of(0x22ff));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.of(0x2300));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.of(0x23ff));
+ assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.of(0x2400));
+ assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.of(0x243f));
+ assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.of(0x2440));
+ assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.of(0x245f));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.of(0x2460));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.of(0x24ff));
+ assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.of(0x2500));
+ assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.of(0x257f));
+ assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.of(0x2580));
+ assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.of(0x259f));
+ assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.of(0x25a0));
+ assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.of(0x25ff));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.of(0x2600));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.of(0x26ff));
+ assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.of(0x2700));
+ assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.of(0x27bf));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.of(0x27c0));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.of(0x27ef));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.of(0x27f0));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.of(0x27ff));
+ assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.of(0x2800));
+ assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.of(0x28ff));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.of(0x2900));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.of(0x297f));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.of(0x2980));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.of(0x29ff));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of(0x2a00));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of(0x2aff));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.of(0x2b00));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.of(0x2bff));
+ assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.of(0x2e80));
+ assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.of(0x2eff));
+ assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.of(0x2f00));
+ assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.of(0x2fdf));
+ assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.of(0x2ff0));
+ assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.of(0x2fff));
+ assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of(0x3000));
+ assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of(0x303f));
+ assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.of(0x3040));
+ assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.of(0x309f));
+ assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.of(0x30a0));
+ assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.of(0x30ff));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.of(0x3100));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.of(0x312f));
+ assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.of(0x3130));
+ assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.of(0x318f));
+ assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.of(0x3190));
+ assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.of(0x319f));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.of(0x31a0));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.of(0x31bf));
+ assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.of(0x31f0));
+ assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.of(0x31ff));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.of(0x3200));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.of(0x32ff));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.of(0x3300));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.of(0x33ff));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.of(0x3400));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.of(0x4dbf));
+ assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.of(0x4dc0));
+ assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.of(0x4dff));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.of(0x4e00));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.of(0x9fff));
+ assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.of(0xa000));
+ assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.of(0xa48f));
+ assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.of(0xa490));
+ assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.of(0xa4cf));
+ assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.of(0xac00));
+ assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.of(0xd7af));
+ assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.of(0xd800));
+ assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.of(0xdb7f));
+ assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.of(0xdb80));
+ assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.of(0xdbff));
+ assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.of(0xdc00));
+ assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.of(0xdfff));
+ assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of(0xe000));
+ assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of(0xf8ff));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.of(0xf900));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.of(0xfaff));
+ assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.of(0xfb00));
+ assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.of(0xfb4f));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.of(0xfb50));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.of(0xfdff));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.of(0xfe00));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.of(0xfe0f));
+ assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.of(0xfe20));
+ assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.of(0xfe2f));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.of(0xfe30));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.of(0xfe4f));
+ assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.of(0xfe50));
+ assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.of(0xfe6f));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.of(0xfe70));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.of(0xfeff));
+ assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.of(0xff00));
+ assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.of(0xffef));
+ assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of(0xfff0));
+ assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of(0xffff));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.of(0x10000));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.of(0x1007f));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.of(0x10080));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.of(0x100ff));
+ assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.of(0x10100));
+ assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.of(0x1013f));
+ assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.of(0x10300));
+ assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.of(0x1032f));
+ assertEquals(Character.UnicodeBlock.GOTHIC, Character.UnicodeBlock.of(0x10330));
+ assertEquals(Character.UnicodeBlock.GOTHIC, Character.UnicodeBlock.of(0x1034f));
+ assertEquals(Character.UnicodeBlock.UGARITIC, Character.UnicodeBlock.of(0x10380));
+ assertEquals(Character.UnicodeBlock.UGARITIC, Character.UnicodeBlock.of(0x1039f));
+ assertEquals(Character.UnicodeBlock.DESERET, Character.UnicodeBlock.of(0x10400));
+ assertEquals(Character.UnicodeBlock.DESERET, Character.UnicodeBlock.of(0x1044f));
+ assertEquals(Character.UnicodeBlock.SHAVIAN, Character.UnicodeBlock.of(0x10450));
+ assertEquals(Character.UnicodeBlock.SHAVIAN, Character.UnicodeBlock.of(0x1047f));
+ assertEquals(Character.UnicodeBlock.OSMANYA, Character.UnicodeBlock.of(0x10480));
+ assertEquals(Character.UnicodeBlock.OSMANYA, Character.UnicodeBlock.of(0x104af));
+ assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.of(0x10800));
+ assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.of(0x1083f));
+ assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.of(0x1d000));
+ assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.of(0x1d0ff));
+ assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.of(0x1d100));
+ assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.of(0x1d1ff));
+ assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.of(0x1d300));
+ assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.of(0x1d35f));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.of(0x1d400));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.of(0x1d7ff));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.of(0x20000));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.of(0x2a6df));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.of(0x2f800));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.of(0x2fa1f));
+ assertEquals(Character.UnicodeBlock.TAGS, Character.UnicodeBlock.of(0xe0000));
+ assertEquals(Character.UnicodeBlock.TAGS, Character.UnicodeBlock.of(0xe007f));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.of(0xe0100));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.of(0xe01ef));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.of(0xf0000));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.of(0xfffff));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.of(0x100000));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.of(0x10ffff));
+
+ // Negative test: The range [0x0860, 0x08A0) is currently unassigned.
+ assertEquals(null, Character.UnicodeBlock.of((char) 0x0860));
+ assertEquals(null, Character.UnicodeBlock.of((char) 0x089F));
+ }
+
+ public void test_ofIExceptions() {
+ try {
+ Character.UnicodeBlock.of(Character.MAX_CODE_POINT + 1);
+ fail("No illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void test_forNameLjava_lang_String() {
+ assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.forName("BASIC_LATIN"));
+ assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.forName("Basic Latin"));
+ assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.forName("BasicLatin"));
+ assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.forName("LATIN_1_SUPPLEMENT"));
+ assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.forName("Latin-1 Supplement"));
+ assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.forName("Latin-1Supplement"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.forName("LATIN_EXTENDED_A"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.forName("Latin Extended-A"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.forName("LatinExtended-A"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.forName("LATIN_EXTENDED_B"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.forName("Latin Extended-B"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.forName("LatinExtended-B"));
+ assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.forName("IPA_EXTENSIONS"));
+ assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.forName("IPA Extensions"));
+ assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.forName("IPAExtensions"));
+ assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.forName("SPACING_MODIFIER_LETTERS"));
+ assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.forName("Spacing Modifier Letters"));
+ assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.forName("SpacingModifierLetters"));
+ assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.forName("COMBINING_DIACRITICAL_MARKS"));
+ assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.forName("Combining Diacritical Marks"));
+ assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.forName("CombiningDiacriticalMarks"));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("GREEK"));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("Greek and Coptic"));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("GreekandCoptic"));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("Greek"));
+ assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("Greek"));
+ assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.forName("CYRILLIC"));
+ assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.forName("CYRILLIC_SUPPLEMENTARY"));
+ assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.forName("Cyrillic Supplementary"));
+ assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.forName("CyrillicSupplementary"));
+ assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.forName("ARMENIAN"));
+ assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.forName("HEBREW"));
+ assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.forName("ARABIC"));
+ assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.forName("SYRIAC"));
+ assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.forName("THAANA"));
+ assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.forName("DEVANAGARI"));
+ assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.forName("BENGALI"));
+ assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.forName("GURMUKHI"));
+ assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.forName("GUJARATI"));
+ assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.forName("ORIYA"));
+ assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.forName("TAMIL"));
+ assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.forName("TELUGU"));
+ assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.forName("KANNADA"));
+ assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.forName("MALAYALAM"));
+ assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.forName("SINHALA"));
+ assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.forName("THAI"));
+ assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.forName("LAO"));
+ assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.forName("TIBETAN"));
+ assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.forName("MYANMAR"));
+ assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.forName("GEORGIAN"));
+ assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.forName("HANGUL_JAMO"));
+ assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.forName("Hangul Jamo"));
+ assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.forName("HangulJamo"));
+ assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.forName("ETHIOPIC"));
+ assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.forName("CHEROKEE"));
+ assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.forName("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS"));
+ assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.forName("Unified Canadian Aboriginal Syllabics"));
+ assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.forName("UnifiedCanadianAboriginalSyllabics"));
+ assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.forName("OGHAM"));
+ assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.forName("RUNIC"));
+ assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.forName("TAGALOG"));
+ assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.forName("HANUNOO"));
+ assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.forName("BUHID"));
+ assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.forName("TAGBANWA"));
+ assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.forName("KHMER"));
+ assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.forName("MONGOLIAN"));
+ assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.forName("LIMBU"));
+ assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.forName("TAI_LE"));
+ assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.forName("Tai Le"));
+ assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.forName("TaiLe"));
+ assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.forName("KHMER_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.forName("Khmer Symbols"));
+ assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.forName("KhmerSymbols"));
+ assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("PHONETIC_EXTENSIONS"));
+ assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("Phonetic Extensions"));
+ assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("PhoneticExtensions"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.forName("LATIN_EXTENDED_ADDITIONAL"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.forName("Latin Extended Additional"));
+ assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.forName("LatinExtendedAdditional"));
+ assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.forName("GREEK_EXTENDED"));
+ assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.forName("Greek Extended"));
+ assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.forName("GreekExtended"));
+ assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.forName("GENERAL_PUNCTUATION"));
+ assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.forName("General Punctuation"));
+ assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.forName("GeneralPunctuation"));
+ assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.forName("SUPERSCRIPTS_AND_SUBSCRIPTS"));
+ assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.forName("Superscripts and Subscripts"));
+ assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.forName("SuperscriptsandSubscripts"));
+ assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.forName("CURRENCY_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.forName("Currency Symbols"));
+ assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.forName("CurrencySymbols"));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("COMBINING_MARKS_FOR_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("Combining Diacritical Marks for Symbols"));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("CombiningDiacriticalMarksforSymbols"));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("Combining Marks for Symbols"));
+ assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("CombiningMarksforSymbols"));
+ assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.forName("LETTERLIKE_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.forName("Letterlike Symbols"));
+ assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.forName("LetterlikeSymbols"));
+ assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.forName("NUMBER_FORMS"));
+ assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.forName("Number Forms"));
+ assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.forName("NumberForms"));
+ assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.forName("ARROWS"));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("MATHEMATICAL_OPERATORS"));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("Mathematical Operators"));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("MathematicalOperators"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.forName("MISCELLANEOUS_TECHNICAL"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.forName("Miscellaneous Technical"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.forName("MiscellaneousTechnical"));
+ assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.forName("CONTROL_PICTURES"));
+ assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.forName("Control Pictures"));
+ assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.forName("ControlPictures"));
+ assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.forName("OPTICAL_CHARACTER_RECOGNITION"));
+ assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.forName("Optical Character Recognition"));
+ assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.forName("OpticalCharacterRecognition"));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.forName("ENCLOSED_ALPHANUMERICS"));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.forName("Enclosed Alphanumerics"));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.forName("EnclosedAlphanumerics"));
+ assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.forName("BOX_DRAWING"));
+ assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.forName("Box Drawing"));
+ assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.forName("BoxDrawing"));
+ assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.forName("BLOCK_ELEMENTS"));
+ assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.forName("Block Elements"));
+ assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.forName("BlockElements"));
+ assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.forName("GEOMETRIC_SHAPES"));
+ assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.forName("Geometric Shapes"));
+ assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.forName("GeometricShapes"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.forName("MISCELLANEOUS_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.forName("Miscellaneous Symbols"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.forName("MiscellaneousSymbols"));
+ assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.forName("DINGBATS"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.forName("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.forName("Miscellaneous Mathematical Symbols-A"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.forName("MiscellaneousMathematicalSymbols-A"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.forName("SUPPLEMENTAL_ARROWS_A"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.forName("Supplemental Arrows-A"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.forName("SupplementalArrows-A"));
+ assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.forName("BRAILLE_PATTERNS"));
+ assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.forName("Braille Patterns"));
+ assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.forName("BraillePatterns"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.forName("SUPPLEMENTAL_ARROWS_B"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.forName("Supplemental Arrows-B"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.forName("SupplementalArrows-B"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.forName("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.forName("Miscellaneous Mathematical Symbols-B"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.forName("MiscellaneousMathematicalSymbols-B"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("SUPPLEMENTAL_MATHEMATICAL_OPERATORS"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("Supplemental Mathematical Operators"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("SupplementalMathematicalOperators"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.forName("MISCELLANEOUS_SYMBOLS_AND_ARROWS"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.forName("Miscellaneous Symbols and Arrows"));
+ assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.forName("MiscellaneousSymbolsandArrows"));
+ assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.forName("CJK_RADICALS_SUPPLEMENT"));
+ assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.forName("CJK Radicals Supplement"));
+ assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.forName("CJKRadicalsSupplement"));
+ assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.forName("KANGXI_RADICALS"));
+ assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.forName("Kangxi Radicals"));
+ assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.forName("KangxiRadicals"));
+ assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.forName("IDEOGRAPHIC_DESCRIPTION_CHARACTERS"));
+ assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.forName("Ideographic Description Characters"));
+ assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.forName("IdeographicDescriptionCharacters"));
+ assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.forName("CJK_SYMBOLS_AND_PUNCTUATION"));
+ assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.forName("CJK Symbols and Punctuation"));
+ assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.forName("CJKSymbolsandPunctuation"));
+ assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.forName("HIRAGANA"));
+ assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.forName("KATAKANA"));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.forName("BOPOMOFO"));
+ assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.forName("HANGUL_COMPATIBILITY_JAMO"));
+ assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.forName("Hangul Compatibility Jamo"));
+ assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.forName("HangulCompatibilityJamo"));
+ assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.forName("KANBUN"));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.forName("BOPOMOFO_EXTENDED"));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.forName("Bopomofo Extended"));
+ assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.forName("BopomofoExtended"));
+ assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("KATAKANA_PHONETIC_EXTENSIONS"));
+ assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("Katakana Phonetic Extensions"));
+ assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("KatakanaPhoneticExtensions"));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.forName("ENCLOSED_CJK_LETTERS_AND_MONTHS"));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.forName("Enclosed CJK Letters and Months"));
+ assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.forName("EnclosedCJKLettersandMonths"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.forName("CJK_COMPATIBILITY"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.forName("CJK Compatibility"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.forName("CJKCompatibility"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.forName("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.forName("CJK Unified Ideographs Extension A"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.forName("CJKUnifiedIdeographsExtensionA"));
+ assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.forName("YIJING_HEXAGRAM_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.forName("Yijing Hexagram Symbols"));
+ assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.forName("YijingHexagramSymbols"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.forName("CJK_UNIFIED_IDEOGRAPHS"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.forName("CJK Unified Ideographs"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.forName("CJKUnifiedIdeographs"));
+ assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.forName("YI_SYLLABLES"));
+ assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.forName("Yi Syllables"));
+ assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.forName("YiSyllables"));
+ assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.forName("YI_RADICALS"));
+ assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.forName("Yi Radicals"));
+ assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.forName("YiRadicals"));
+ assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.forName("HANGUL_SYLLABLES"));
+ assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.forName("Hangul Syllables"));
+ assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.forName("HangulSyllables"));
+ assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.forName("HIGH_SURROGATES"));
+ assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.forName("High Surrogates"));
+ assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.forName("HighSurrogates"));
+ assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.forName("HIGH_PRIVATE_USE_SURROGATES"));
+ assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.forName("High Private Use Surrogates"));
+ assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.forName("HighPrivateUseSurrogates"));
+ assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.forName("LOW_SURROGATES"));
+ assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.forName("Low Surrogates"));
+ assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.forName("LowSurrogates"));
+ assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.forName("PRIVATE_USE_AREA"));
+ assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.forName("Private Use Area"));
+ assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.forName("PrivateUseArea"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.forName("CJK_COMPATIBILITY_IDEOGRAPHS"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.forName("CJK Compatibility Ideographs"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.forName("CJKCompatibilityIdeographs"));
+ assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.forName("ALPHABETIC_PRESENTATION_FORMS"));
+ assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.forName("Alphabetic Presentation Forms"));
+ assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.forName("AlphabeticPresentationForms"));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.forName("ARABIC_PRESENTATION_FORMS_A"));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.forName("Arabic Presentation Forms-A"));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.forName("ArabicPresentationForms-A"));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.forName("VARIATION_SELECTORS"));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.forName("Variation Selectors"));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.forName("VariationSelectors"));
+ assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.forName("COMBINING_HALF_MARKS"));
+ assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.forName("Combining Half Marks"));
+ assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.forName("CombiningHalfMarks"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.forName("CJK_COMPATIBILITY_FORMS"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.forName("CJK Compatibility Forms"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.forName("CJKCompatibilityForms"));
+ assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.forName("SMALL_FORM_VARIANTS"));
+ assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.forName("Small Form Variants"));
+ assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.forName("SmallFormVariants"));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.forName("ARABIC_PRESENTATION_FORMS_B"));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.forName("Arabic Presentation Forms-B"));
+ assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.forName("ArabicPresentationForms-B"));
+ assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.forName("HALFWIDTH_AND_FULLWIDTH_FORMS"));
+ assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.forName("Halfwidth and Fullwidth Forms"));
+ assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.forName("HalfwidthandFullwidthForms"));
+ assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.forName("SPECIALS"));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.forName("LINEAR_B_SYLLABARY"));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.forName("Linear B Syllabary"));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.forName("LinearBSyllabary"));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.forName("LINEAR_B_IDEOGRAMS"));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.forName("Linear B Ideograms"));
+ assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.forName("LinearBIdeograms"));
+ assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.forName("AEGEAN_NUMBERS"));
+ assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.forName("Aegean Numbers"));
+ assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.forName("AegeanNumbers"));
+ assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.forName("OLD_ITALIC"));
+ assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.forName("Old Italic"));
+ assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.forName("OldItalic"));
+ assertEquals(Character.UnicodeBlock.GOTHIC, Character.UnicodeBlock.forName("GOTHIC"));
+ assertEquals(Character.UnicodeBlock.UGARITIC, Character.UnicodeBlock.forName("UGARITIC"));
+ assertEquals(Character.UnicodeBlock.DESERET, Character.UnicodeBlock.forName("DESERET"));
+ assertEquals(Character.UnicodeBlock.SHAVIAN, Character.UnicodeBlock.forName("SHAVIAN"));
+ assertEquals(Character.UnicodeBlock.OSMANYA, Character.UnicodeBlock.forName("OSMANYA"));
+ assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.forName("CYPRIOT_SYLLABARY"));
+ assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.forName("Cypriot Syllabary"));
+ assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.forName("CypriotSyllabary"));
+ assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("BYZANTINE_MUSICAL_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("Byzantine Musical Symbols"));
+ assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("ByzantineMusicalSymbols"));
+ assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("MUSICAL_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("Musical Symbols"));
+ assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("MusicalSymbols"));
+ assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.forName("TAI_XUAN_JING_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.forName("Tai Xuan Jing Symbols"));
+ assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.forName("TaiXuanJingSymbols"));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.forName("MATHEMATICAL_ALPHANUMERIC_SYMBOLS"));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.forName("Mathematical Alphanumeric Symbols"));
+ assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.forName("MathematicalAlphanumericSymbols"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.forName("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.forName("CJK Unified Ideographs Extension B"));
+ assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.forName("CJKUnifiedIdeographsExtensionB"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.forName("CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.forName("CJK Compatibility Ideographs Supplement"));
+ assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.forName("CJKCompatibilityIdeographsSupplement"));
+ assertEquals(Character.UnicodeBlock.TAGS, Character.UnicodeBlock.forName("TAGS"));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.forName("VARIATION_SELECTORS_SUPPLEMENT"));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.forName("Variation Selectors Supplement"));
+ assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.forName("VariationSelectorsSupplement"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.forName("SUPPLEMENTARY_PRIVATE_USE_AREA_A"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.forName("Supplementary Private Use Area-A"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.forName("SupplementaryPrivateUseArea-A"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.forName("SUPPLEMENTARY_PRIVATE_USE_AREA_B"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.forName("Supplementary Private Use Area-B"));
+ assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.forName("SupplementaryPrivateUseArea-B"));
+ }
+
+ public void test_forNameLjava_lang_StringExceptions() {
+ try {
+ Character.UnicodeBlock.forName(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ Character.UnicodeBlock.forName("INVALID_NAME");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // We don't map "SURROGATES_AREA" to the deprecated SURROGATES_AREA
+ // enum value. ICU doesn't have any block corresponding to this since it's
+ // now split into low surrogates and the high (normal/private use)
+ // surrogates. Also, the only API that makes any reference to this goes
+ // directly to ICU anyway.
+ try {
+ Character.UnicodeBlock.forName("SURROGATES_AREA");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassCastExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassCastExceptionTest.java
new file mode 100644
index 0000000..2863bd6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassCastExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ClassCastExceptionTest extends TestCase {
+
+ /**
+ * java.lang.ClassCastException#ClassCastException()
+ */
+ public void test_Constructor() {
+ ClassCastException e = new ClassCastException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.ClassCastException#ClassCastException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ ClassCastException e = new ClassCastException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassCircularityErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassCircularityErrorTest.java
new file mode 100644
index 0000000..54c5c4d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassCircularityErrorTest.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ClassCircularityErrorTest extends TestCase {
+ // Thrown when a circularity has been detected while initializing a class.
+
+ /**
+ * java.lang.ClassCircularityError#ClassCircularityError()
+ */
+ public void test_ClassCircularityError() {
+ new ClassCircularityError();
+ }
+
+ /**
+ * java.lang.ClassCircularityError#ClassCircularityError(java.lang.String)
+ */
+ public void test_ClassCircularityError_LString() {
+ ClassCircularityError e = new ClassCircularityError(
+ "Some Error message");
+ assertEquals("Wrong message", "Some Error message", e.getMessage());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassFormatErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassFormatErrorTest.java
new file mode 100644
index 0000000..f811c9a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassFormatErrorTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ClassFormatErrorTest extends TestCase {
+ /**
+ * Thrown when the Java Virtual Machine attempts to read a class file and
+ * determines that the file is malformed or otherwise cannot be interpreted
+ * as a class file.
+ */
+
+ /**
+ * java.lang.ClassFormatError#ClassFormatError()
+ */
+ public void test_ClassFormatError() {
+ new ClassFormatError();
+ }
+
+ /**
+ * java.lang.ClassFormatError#ClassFormatError(java.lang.String)
+ */
+ public void test_ClassFormatError_LString() {
+ ClassFormatError e = new ClassFormatError("Some Error Message");
+ assertEquals("Wrong message", "Some Error Message", e.getMessage());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassLoaderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassLoaderTest.java
new file mode 100644
index 0000000..2caab39
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassLoaderTest.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ClassLoaderTest extends TestCase {
+
+ /** A resource known to be present in the boot classpath. */
+ private static final String BOOT_RESOURCE_NAME = "java/util/logging/logging.properties";
+
+ /** A resource known to be present in the classpath associated with the test class. */
+ private static final String TEST_RESOURCE_NAME = ClassTest.RESOURCE_ABS_NAME;
+
+ private ClassLoader testClassLoader;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ testClassLoader = getClass().getClassLoader();
+ }
+
+ /**
+ * java.lang.ClassLoader#getSystemClassLoader()
+ */
+ public void test_getSystemClassLoader() {
+ // Test for method java.lang.ClassLoader
+ // java.lang.ClassLoader.getSystemClassLoader()
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+ assertNotNull(cl);
+
+ // The SystemClassLoader's parent should be the Boot classloader, which is used to load
+ // the various libcore classes.
+ assertNotNull(cl.getParent());
+ Class<?> libcoreClass = Integer.class;
+ assertSame(cl.getParent(), libcoreClass.getClassLoader());
+
+ // It is difficult to test further because the CTS tests run as an instrumented TestCase.
+ // Android apps do not have a system classpath, and rely on an application classloader to
+ // load app classes and resources, not the System ClassLoader. The System ClassLoader is not
+ // usually the parent of the application class loader.
+ }
+
+ /**
+ * java.lang.ClassLoader#getSystemResource(java.lang.String)
+ */
+ public void test_getSystemResourceLjava_lang_String() {
+ // Test for method java.net.URL
+ // java.lang.ClassLoader.getSystemResource(java.lang.String)
+
+ // It is difficult to test this because the CTS tests run as an instrumented TestCase.
+ // Android apps do not have a system classpath, and rely on an application classloader to
+ // load app classes and resources, not the System ClassLoader.
+ }
+
+ /**
+ * java.lang.ClassLoader#getResource(java.lang.String)
+ */
+ public void test_testClassLoader_getResourceLjava_lang_String() {
+ // Test for method java.net.URL
+ // java.lang.ClassLoader.getResource(java.lang.String)
+
+ // Test basic class loader behavior for the ClassLoader that was used to load the test
+ // class while being deliberately vague about which classloader it actually is.
+
+ ClassLoader parentClassLoader = testClassLoader.getParent();
+ assertNull(parentClassLoader.getResource(TEST_RESOURCE_NAME));
+ assertGetResourceIsValid(parentClassLoader, BOOT_RESOURCE_NAME);
+
+ assertGetResourceIsValid(testClassLoader, TEST_RESOURCE_NAME);
+ assertGetResourceIsValid(testClassLoader, BOOT_RESOURCE_NAME);
+ }
+
+ /**
+ * java.lang.ClassLoader#getResourceAsStream(java.lang.String)
+ */
+ public void test_testClassLoader_getResourceAsStreamLjava_lang_String() throws Exception {
+ // Test for method java.io.InputStream
+ // java.lang.ClassLoader.getResourceAsStream(java.lang.String)
+
+ // Test basic class loader behavior for the ClassLoader that was used to load the test
+ // class while being deliberately vague about which classloader it actually is.
+
+ ClassLoader parentClassLoader = testClassLoader.getParent();
+ assertGetResourceAsStreamNotNull(parentClassLoader, BOOT_RESOURCE_NAME);
+ assertNull(parentClassLoader.getResourceAsStream(TEST_RESOURCE_NAME));
+
+ assertGetResourceAsStreamNotNull(testClassLoader, BOOT_RESOURCE_NAME);
+ assertGetResourceAsStreamNotNull(testClassLoader, TEST_RESOURCE_NAME);
+ }
+
+ public void test_testClassLoader_loadClass() throws Exception {
+ // Test basic class loader behavior for the ClassLoader that was used to load the test
+ // class while being deliberately vague about which classloader it actually is.
+ String integerClassName = Integer.class.getName();
+ String testClassName = ClassLoaderTest.class.getName();
+
+ ClassLoader parentClassLoader = testClassLoader.getParent();
+ assertSame(Integer.class, parentClassLoader.loadClass(integerClassName));
+ try {
+ parentClassLoader.loadClass(testClassName);
+ fail();
+ } catch (ClassNotFoundException expected) {
+ }
+
+ assertSame(Integer.class, testClassLoader.loadClass(integerClassName));
+ assertSame(this.getClass(), testClassLoader.loadClass(testClassName));
+ }
+
+ //Regression Test for JIRA-2047
+ public void test_testClassLoader_getResourceAsStream_withSharpChar() throws Exception {
+ assertGetResourceAsStreamNotNull(testClassLoader, ClassTest.SHARP_RESOURCE_ABS_NAME);
+ }
+
+ private static void assertGetResourceAsStreamNotNull(ClassLoader classLoader,
+ String resourceName) throws IOException {
+ InputStream is = null;
+ try {
+ is = classLoader.getResourceAsStream(resourceName);
+ assertNotNull(is);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ private static void assertGetResourceIsValid(ClassLoader classLoader, String resourceName) {
+ java.net.URL u = classLoader.getResource(resourceName);
+ assertNotNull(u);
+ InputStream is = null;
+ try {
+ is = u.openStream();
+ assertNotNull(is);
+ is.close();
+ } catch (IOException e) {
+ fail("IOException getting stream for resource : " + e.getMessage());
+ }
+ }
+} \ No newline at end of file
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassNotFoundExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassNotFoundExceptionTest.java
new file mode 100644
index 0000000..e199aa2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassNotFoundExceptionTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class ClassNotFoundExceptionTest extends TestCase {
+ /**
+ * Thrown when an application tries to load in a class through its string
+ * name using the forName method in class Class.
+ */
+
+ /**
+ * java.lang.ClassNotFoundException#ClassNotFoundException()
+ */
+ public void test_Constructor() {
+ ClassNotFoundException e = new ClassNotFoundException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.ClassNotFoundException#ClassNotFoundException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ ClassNotFoundException e = new ClassNotFoundException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.ClassNotFoundException#ClassNotFoundException(java.lang.String, java.lang.Throwable)
+ */
+ public void test_ClassNotFoundException_LString_LThrowable() {
+ IOException in = new IOException();
+ ClassNotFoundException e = new ClassNotFoundException("SomeMessage", in);
+ assertEquals("Wrong Exception", in, e.getException());
+ assertEquals("Wrong message", "SomeMessage", e.getMessage());
+ assertEquals("Wrong cause", in, e.getCause());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassTest.java
new file mode 100644
index 0000000..379dad2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ClassTest.java
@@ -0,0 +1,642 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.DomainCombiner;
+import java.security.Permission;
+import java.security.ProtectionDomain;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Vector;
+
+public class ClassTest extends junit.framework.TestCase {
+
+ // Relative resource paths.
+ private static final String SHARP_RESOURCE_RELATIVE_NAME = "test#.properties";
+ private static final String RESOURCE_RELATIVE_NAME = "test.properties";
+
+ // Absolute resource paths.
+ private static final String ABS_PATH =
+ ClassTest.class.getPackage().getName().replace('.', '/');
+ public static final String SHARP_RESOURCE_ABS_NAME =
+ ABS_PATH + "/" + SHARP_RESOURCE_RELATIVE_NAME;
+ public static final String RESOURCE_ABS_NAME = ABS_PATH + "/" + RESOURCE_RELATIVE_NAME;
+
+ public static class TestClass {
+ @SuppressWarnings("unused")
+ private int privField = 1;
+
+ public int pubField = 2;
+
+ private Object cValue = null;
+
+ public Object ack = new Object();
+
+ @SuppressWarnings("unused")
+ private int privMethod() {
+ return 1;
+ }
+
+ public int pubMethod() {
+ return 2;
+ }
+
+ public Object cValue() {
+ return cValue;
+ }
+
+ public TestClass() {
+ }
+
+ @SuppressWarnings("unused")
+ private TestClass(Object o) {
+ }
+ }
+
+ public static class SubTestClass extends TestClass {
+ }
+
+ /**
+ * java.lang.Class#forName(java.lang.String)
+ */
+ public void test_forNameLjava_lang_String() throws Exception {
+ assertSame("Class for name failed for java.lang.Object",
+ Object.class, Class.forName("java.lang.Object"));
+ assertSame("Class for name failed for [[Ljava.lang.Object;",
+ Object[][].class, Class.forName("[[Ljava.lang.Object;"));
+
+ assertSame("Class for name failed for [I",
+ int[].class, Class.forName("[I"));
+
+ try {
+ Class.forName("int");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+
+ try {
+ Class.forName("byte");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+ try {
+ Class.forName("char");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+
+ try {
+ Class.forName("void");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+
+ try {
+ Class.forName("short");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+ try {
+ Class.forName("long");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+
+ try {
+ Class.forName("boolean");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+ try {
+ Class.forName("float");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+ try {
+ Class.forName("double");
+ fail();
+ } catch (ClassNotFoundException e) {
+ }
+
+ //regression test for JIRA 2162
+ try {
+ Class.forName("%");
+ fail("should throw ClassNotFoundException.");
+ } catch (ClassNotFoundException e) {
+ }
+
+ //Regression Test for HARMONY-3332
+ String securityProviderClassName;
+ int count = 1;
+ while ((securityProviderClassName = Security
+ .getProperty("security.provider." + count++)) != null) {
+ Class.forName(securityProviderClassName);
+ }
+ }
+
+ /**
+ * java.lang.Class#getClasses()
+ */
+ public void test_getClasses() {
+ assertEquals("Incorrect class array returned",
+ 2, ClassTest.class.getClasses().length);
+ }
+
+ /**
+ * java.lang.Class#getClasses()
+ */
+ public void test_getClasses_subtest0() {
+ final Permission privCheckPermission = new BasicPermission("Privilege check") {
+ private static final long serialVersionUID = 1L;
+ };
+
+ class MyCombiner implements DomainCombiner {
+ boolean combine;
+
+ public ProtectionDomain[] combine(ProtectionDomain[] executionDomains,
+ ProtectionDomain[] parentDomains) {
+ combine = true;
+ return new ProtectionDomain[0];
+ }
+
+ private boolean recurring = false;
+
+ public boolean isPriviledged() {
+ if (recurring) {
+ return true;
+ }
+ try {
+ recurring = true;
+ combine = false;
+ try {
+ AccessController.checkPermission(privCheckPermission);
+ } catch (SecurityException e) {
+ }
+ return !combine;
+ } finally {
+ recurring = false;
+ }
+ }
+ }
+ }
+
+ /**
+ * java.lang.Class#getComponentType()
+ */
+ public void test_getComponentType() {
+ assertSame("int array does not have int component type", int.class, int[].class
+ .getComponentType());
+ assertSame("Object array does not have Object component type", Object.class,
+ Object[].class.getComponentType());
+ assertNull("Object has non-null component type", Object.class.getComponentType());
+ }
+
+ /**
+ * java.lang.Class#getConstructor(java.lang.Class[])
+ */
+ public void test_getConstructor$Ljava_lang_Class()
+ throws NoSuchMethodException {
+ TestClass.class.getConstructor(new Class[0]);
+ try {
+ TestClass.class.getConstructor(Object.class);
+ fail("Found private constructor");
+ } catch (NoSuchMethodException e) {
+ // Correct - constructor with obj is private
+ }
+ }
+
+ /**
+ * java.lang.Class#getConstructors()
+ */
+ public void test_getConstructors() throws Exception {
+ Constructor[] c = TestClass.class.getConstructors();
+ assertEquals("Incorrect number of constructors returned", 1, c.length);
+ }
+
+ /**
+ * java.lang.Class#getDeclaredClasses()
+ */
+ public void test_getDeclaredClasses() {
+ assertEquals("Incorrect class array returned", 2, ClassTest.class.getClasses().length);
+ }
+
+ /**
+ * java.lang.Class#getDeclaredConstructor(java.lang.Class[])
+ */
+ public void test_getDeclaredConstructor$Ljava_lang_Class() throws Exception {
+ Constructor<TestClass> c = TestClass.class.getDeclaredConstructor(new Class[0]);
+ assertNull("Incorrect constructor returned", c.newInstance().cValue());
+ c = TestClass.class.getDeclaredConstructor(Object.class);
+ }
+
+ /**
+ * java.lang.Class#getDeclaredConstructors()
+ */
+ public void test_getDeclaredConstructors() throws Exception {
+ Constructor[] c = TestClass.class.getDeclaredConstructors();
+ assertEquals("Incorrect number of constructors returned", 2, c.length);
+ }
+
+ /**
+ * java.lang.Class#getDeclaredField(java.lang.String)
+ */
+ public void test_getDeclaredFieldLjava_lang_String() throws Exception {
+ Field f = TestClass.class.getDeclaredField("pubField");
+ assertEquals("Returned incorrect field", 2, f.getInt(new TestClass()));
+ }
+
+ /**
+ * java.lang.Class#getDeclaredFields()
+ */
+ public void test_getDeclaredFields() throws Exception {
+ Field[] f = TestClass.class.getDeclaredFields();
+ assertEquals("Returned incorrect number of fields", 4, f.length);
+ f = SubTestClass.class.getDeclaredFields();
+ // Declared fields do not include inherited
+ assertEquals("Returned incorrect number of fields", 0, f.length);
+ }
+
+ /**
+ * java.lang.Class#getDeclaredMethod(java.lang.String,
+ *java.lang.Class[])
+ */
+ public void test_getDeclaredMethodLjava_lang_String$Ljava_lang_Class() throws Exception {
+ Method m = TestClass.class.getDeclaredMethod("pubMethod", new Class[0]);
+ assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass())))
+ .intValue());
+ m = TestClass.class.getDeclaredMethod("privMethod", new Class[0]);
+ }
+
+ /**
+ * java.lang.Class#getDeclaredMethods()
+ */
+ public void test_getDeclaredMethods() throws Exception {
+ Method[] m = TestClass.class.getDeclaredMethods();
+ assertEquals("Returned incorrect number of methods", 3, m.length);
+ m = SubTestClass.class.getDeclaredMethods();
+ assertEquals("Returned incorrect number of methods", 0, m.length);
+ }
+
+ /**
+ * java.lang.Class#getDeclaringClass()
+ */
+ public void test_getDeclaringClass() {
+ assertEquals(ClassTest.class, TestClass.class.getDeclaringClass());
+ }
+
+ /**
+ * java.lang.Class#getField(java.lang.String)
+ */
+ public void test_getFieldLjava_lang_String() throws Exception {
+ Field f = TestClass.class.getField("pubField");
+ assertEquals("Returned incorrect field", 2, f.getInt(new TestClass()));
+ try {
+ f = TestClass.class.getField("privField");
+ fail("Private field access failed to throw exception");
+ } catch (NoSuchFieldException e) {
+ // Correct
+ }
+ }
+
+ /**
+ * java.lang.Class#getFields()
+ */
+ public void test_getFields() throws Exception {
+ Field[] f = TestClass.class.getFields();
+ assertEquals("Incorrect number of fields", 2, f.length);
+ f = SubTestClass.class.getFields();
+ // Check inheritance of pub fields
+ assertEquals("Incorrect number of fields", 2, f.length);
+ }
+
+ /**
+ * java.lang.Class#getInterfaces()
+ */
+ public void test_getInterfaces() {
+ Class[] interfaces;
+ List<?> interfaceList;
+ interfaces = Object.class.getInterfaces();
+ assertEquals("Incorrect interface list for Object", 0, interfaces.length);
+ interfaceList = Arrays.asList(Vector.class.getInterfaces());
+ assertTrue("Incorrect interface list for Vector", interfaceList
+ .contains(Cloneable.class)
+ && interfaceList.contains(Serializable.class)
+ && interfaceList.contains(List.class));
+ }
+
+ /**
+ * java.lang.Class#getMethod(java.lang.String, java.lang.Class[])
+ */
+ public void test_getMethodLjava_lang_String$Ljava_lang_Class() throws Exception {
+ Method m = TestClass.class.getMethod("pubMethod", new Class[0]);
+ assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass())))
+ .intValue());
+ try {
+ m = TestClass.class.getMethod("privMethod", new Class[0]);
+ fail("Failed to throw exception accessing private method");
+ } catch (NoSuchMethodException e) {
+ // Correct
+ return;
+ }
+ }
+
+ /**
+ * java.lang.Class#getMethods()
+ */
+ public void test_getMethods() throws Exception {
+ Method[] m = TestClass.class.getMethods();
+ assertEquals("Returned incorrect number of methods",
+ 2 + Object.class.getMethods().length, m.length);
+ m = SubTestClass.class.getMethods();
+ assertEquals("Returned incorrect number of sub-class methods",
+ 2 + Object.class.getMethods().length, m.length);
+ // Number of inherited methods
+ }
+
+ private static final class PrivateClass {
+ }
+
+ /**
+ * java.lang.Class#getModifiers()
+ */
+ public void test_getModifiers() {
+ int dcm = PrivateClass.class.getModifiers();
+ assertFalse("default class is public", Modifier.isPublic(dcm));
+ assertFalse("default class is protected", Modifier.isProtected(dcm));
+ assertTrue("default class is not private", Modifier.isPrivate(dcm));
+
+ int ocm = Object.class.getModifiers();
+ assertTrue("public class is not public", Modifier.isPublic(ocm));
+ assertFalse("public class is protected", Modifier.isProtected(ocm));
+ assertFalse("public class is private", Modifier.isPrivate(ocm));
+ }
+
+ /**
+ * java.lang.Class#getName()
+ */
+ public void test_getName() throws Exception {
+ String className = Class.forName("java.lang.Object").getName();
+ assertNotNull(className);
+
+ assertEquals("Class getName printed wrong value", "java.lang.Object", className);
+ assertEquals("Class getName printed wrong value", "int", int.class.getName());
+ className = Class.forName("[I").getName();
+ assertNotNull(className);
+ assertEquals("Class getName printed wrong value", "[I", className);
+
+ className = Class.forName("[Ljava.lang.Object;").getName();
+ assertNotNull(className);
+
+ assertEquals("Class getName printed wrong value", "[Ljava.lang.Object;", className);
+ }
+
+ /**
+ * java.lang.Class#getResource(java.lang.String)
+ */
+ public void test_getResourceLjava_lang_String() {
+ final String name = "/resources/test_resource.txt";
+ URL res = getClass().getResource(name);
+ assertNotNull(res);
+ }
+
+ /**
+ * java.lang.Class#getResourceAsStream(java.lang.String)
+ */
+ public void test_getResourceAsStreamLjava_lang_String() throws Exception {
+ final String name = "/resources/test_resource.txt";
+ InputStream str2 = getClass().getResourceAsStream(name);
+ assertNotNull("the file " + name + " can not be found in this directory", str2);
+
+ final String nameBadURI = "org/apache/harmony/luni/tests/test_resource.txt";
+ assertNull("the file " + nameBadURI + " should not be found in this directory",
+ getClass().getResourceAsStream(nameBadURI));
+
+ assertTrue("Cannot read single byte", str2.read() != -1);
+ assertEquals("Cannot read multiple bytes", 5, str2.read(new byte[5]));
+ str2.close();
+ }
+
+ /**
+ * java.lang.Class#getSuperclass()
+ */
+ public void test_getSuperclass() {
+ assertNull("Object has a superclass???", Object.class.getSuperclass());
+ assertSame("Normal class has bogus superclass", InputStream.class,
+ FileInputStream.class.getSuperclass());
+ assertSame("Array class has bogus superclass", Object.class, FileInputStream[].class
+ .getSuperclass());
+ assertNull("Base class has a superclass", int.class.getSuperclass());
+ assertNull("Interface class has a superclass", Cloneable.class.getSuperclass());
+ }
+
+ /**
+ * java.lang.Class#isArray()
+ */
+ public void test_isArray() throws ClassNotFoundException {
+ assertTrue("Non-array type claims to be.", !int.class.isArray());
+ Class<?> clazz = null;
+ clazz = Class.forName("[I");
+ assertTrue("int Array type claims not to be.", clazz.isArray());
+
+ clazz = Class.forName("[Ljava.lang.Object;");
+ assertTrue("Object Array type claims not to be.", clazz.isArray());
+
+ clazz = Class.forName("java.lang.Object");
+ assertTrue("Non-array Object type claims to be.", !clazz.isArray());
+ }
+
+ /**
+ * java.lang.Class#isAssignableFrom(java.lang.Class)
+ */
+ public void test_isAssignableFromLjava_lang_Class() {
+ Class<?> clazz1 = null;
+ Class<?> clazz2 = null;
+
+ clazz1 = Object.class;
+ clazz2 = Class.class;
+ assertTrue("returned false for superclass", clazz1.isAssignableFrom(clazz2));
+
+ clazz1 = TestClass.class;
+ assertTrue("returned false for same class", clazz1.isAssignableFrom(clazz1));
+
+ clazz1 = Runnable.class;
+ clazz2 = Thread.class;
+ assertTrue("returned false for implemented interface", clazz1.isAssignableFrom(clazz2));
+ }
+
+ /**
+ * java.lang.Class#isInterface()
+ */
+ public void test_isInterface() throws ClassNotFoundException {
+ assertTrue("Prim type claims to be interface.", !int.class.isInterface());
+ Class<?> clazz = null;
+ clazz = Class.forName("[I");
+ assertTrue("Prim Array type claims to be interface.", !clazz.isInterface());
+
+ clazz = Class.forName("java.lang.Runnable");
+ assertTrue("Interface type claims not to be interface.", clazz.isInterface());
+ clazz = Class.forName("java.lang.Object");
+ assertTrue("Object type claims to be interface.", !clazz.isInterface());
+
+ clazz = Class.forName("[Ljava.lang.Object;");
+ assertTrue("Array type claims to be interface.", !clazz.isInterface());
+ }
+
+ /**
+ * java.lang.Class#isPrimitive()
+ */
+ public void test_isPrimitive() {
+ assertFalse("Interface type claims to be primitive.", Runnable.class.isPrimitive());
+ assertFalse("Object type claims to be primitive.", Object.class.isPrimitive());
+ assertFalse("Prim Array type claims to be primitive.", int[].class.isPrimitive());
+ assertFalse("Array type claims to be primitive.", Object[].class.isPrimitive());
+ assertTrue("Prim type claims not to be primitive.", int.class.isPrimitive());
+ assertFalse("Object type claims to be primitive.", Object.class.isPrimitive());
+ }
+
+ /**
+ * java.lang.Class#newInstance()
+ */
+ public void test_newInstance() throws Exception {
+ Class<?> clazz = null;
+ clazz = Class.forName("java.lang.Object");
+ assertNotNull("new object instance was null", clazz.newInstance());
+
+ clazz = Class.forName("java.lang.Throwable");
+ assertSame("new Throwable instance was not a throwable",
+ clazz, clazz.newInstance().getClass());
+
+ clazz = Class.forName("java.lang.Integer");
+ try {
+ clazz.newInstance();
+ fail("Exception for instantiating a newInstance with no default constructor is not thrown");
+ } catch (InstantiationException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.Class#toString()
+ */
+ public void test_toString() throws ClassNotFoundException {
+ assertEquals("Class toString printed wrong value",
+ "int", int.class.toString());
+ Class<?> clazz = null;
+ clazz = Class.forName("[I");
+ assertEquals("Class toString printed wrong value",
+ "class [I", clazz.toString());
+
+ clazz = Class.forName("java.lang.Object");
+ assertEquals("Class toString printed wrong value",
+ "class java.lang.Object", clazz.toString());
+
+ clazz = Class.forName("[Ljava.lang.Object;");
+ assertEquals("Class toString printed wrong value",
+ "class [Ljava.lang.Object;", clazz.toString());
+ }
+
+
+ // Regression Test for JIRA-2047
+ public void test_getResourceAsStream_withSharpChar() throws Exception {
+ // Class.getResourceAsStream() requires a leading "/" for absolute paths.
+ assertNull(getClass().getResourceAsStream(SHARP_RESOURCE_ABS_NAME));
+ assertResourceExists("/" + SHARP_RESOURCE_ABS_NAME);
+ assertResourceExists(SHARP_RESOURCE_RELATIVE_NAME);
+
+
+ InputStream in =
+ this.getClass().getClassLoader().getResourceAsStream(SHARP_RESOURCE_ABS_NAME);
+ assertNotNull(in);
+ in.close();
+ }
+
+ public void test_getResourceAsStream() throws Exception {
+ // Class.getResourceAsStream() requires a leading "/" for absolute paths.
+ assertNull(getClass().getResourceAsStream(RESOURCE_ABS_NAME));
+ assertResourceExists("/" + RESOURCE_ABS_NAME);
+ assertResourceExists(RESOURCE_RELATIVE_NAME);
+
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream(RESOURCE_ABS_NAME);
+ assertNotNull(in);
+ in.close();
+ }
+
+ private void assertResourceExists(String resourceName) throws IOException {
+ InputStream in = getClass().getResourceAsStream(resourceName);
+ assertNotNull(in);
+ in.close();
+ }
+
+ /*
+ * Regression test for HARMONY-2644:
+ * Load system and non-system array classes via Class.forName()
+ */
+ public void test_forName_arrays() throws Exception {
+ Class c1 = getClass();
+ String s = c1.getName();
+ Class a1 = Class.forName("[L" + s + ";");
+ Class a2 = Class.forName("[[L" + s + ";");
+ assertSame(c1, a1.getComponentType());
+ assertSame(a1, a2.getComponentType());
+ Class l4 = Class.forName("[[[[[J");
+ assertSame(long[][][][][].class, l4);
+
+ try {
+ System.out.println(Class.forName("[;"));
+ fail("1");
+ } catch (ClassNotFoundException ok) {
+ }
+ try {
+ System.out.println(Class.forName("[["));
+ fail("2");
+ } catch (ClassNotFoundException ok) {
+ }
+ try {
+ System.out.println(Class.forName("[L"));
+ fail("3");
+ } catch (ClassNotFoundException ok) {
+ }
+ try {
+ System.out.println(Class.forName("[L;"));
+ fail("4");
+ } catch (ClassNotFoundException ok) {
+ }
+ try {
+ System.out.println(Class.forName(";"));
+ fail("5");
+ } catch (ClassNotFoundException ok) {
+ }
+ try {
+ System.out.println(Class.forName(""));
+ fail("6");
+ } catch (ClassNotFoundException ok) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CloneNotSupportedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CloneNotSupportedExceptionTest.java
new file mode 100644
index 0000000..0af1dbc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CloneNotSupportedExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class CloneNotSupportedExceptionTest extends TestCase {
+
+ /**
+ * java.lang.CloneNotSupportedException#CloneNotSupportedException()
+ */
+ public void test_Constructor() {
+ CloneNotSupportedException e = new CloneNotSupportedException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.CloneNotSupportedException#CloneNotSupportedException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ CloneNotSupportedException e = new CloneNotSupportedException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CompilerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CompilerTest.java
new file mode 100644
index 0000000..8584ce4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/CompilerTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class CompilerTest extends TestCase {
+
+ /**
+ * java.lang.Compiler#command(java.lang.Object)
+ */
+ public void test_commandLjava_lang_Object() {
+ assertNull("Incorrect behavior.", Compiler.command(new Object()));
+ }
+
+ /**
+ * java.lang.Compiler#compileClass(java.lang.Class)
+ */
+ public void test_compileClassLjava_lang_Class() {
+ // Do not test return value, may return true or false depending on
+ // if the jit is enabled. Make the call to ensure it doesn't crash.
+ Compiler.compileClass(Compiler.class);
+ }
+
+ /**
+ * java.lang.Compiler#compileClasses(java.lang.String)
+ */
+ public void test_compileClassesLjava_lang_String() {
+ // Do not test return value, may return true or false depending on
+ // if the jit is enabled. Make the call to ensure it doesn't crash.
+ Compiler.compileClasses("Compiler");
+ }
+
+ /**
+ * java.lang.Compiler#disable()
+ */
+ public void test_disable() {
+ Compiler.disable();
+ Compiler.compileClass(Compiler.class);
+ }
+
+ /**
+ * java.lang.Compiler#enable()
+ */
+ public void test_enable() {
+ Compiler.disable();
+ Compiler.enable();
+ Compiler.compileClass(Compiler.class);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/DoubleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/DoubleTest.java
new file mode 100644
index 0000000..79d81e8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/DoubleTest.java
@@ -0,0 +1,1444 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+public class DoubleTest extends TestCase {
+ private static final long rawBitsFor3_4en324ToN1[] = { 0x1L, 0x7L, 0x45L, 0x2b0L, 0x1ae2L,
+ 0x10cd1L, 0xa8028L, 0x69018dL, 0x41a0f7eL, 0x29049aedL, 0x19a2e0d44L,
+ 0x1005cc84acL, 0xa039fd2ebdL, 0x64243e3d361L, 0x3e96a6e641c6L, 0x271e284fe91b8L,
+ 0x1872d931f1b131L, 0x4e8f8f7e6e1d7dL, 0x8319b9af04d26eL, 0xb7e0281ac6070aL,
+ 0xedd832217788ccL, 0x122a71f54eab580L, 0x15750e72a2562e0L, 0x18d2520f4aebb98L,
+ 0x1c2373498ed353fL, 0x1f6c501bf28828eL, 0x22c76422ef2a332L, 0x261c9e95d57a5ffL,
+ 0x2963c63b4ad8f7fL, 0x2cbcb7ca1d8f35fL, 0x3015f2de527981bL, 0x335b6f95e717e22L,
+ 0x36b24b7b60dddabL, 0x3a0f6f2d1c8aa8bL, 0x3d534af863ad52dL, 0x40a81db67c98a79L,
+ 0x440912920ddf68bL, 0x474b5736915742eL, 0x4a9e2d0435ad13aL, 0x4e02dc22a18c2c4L,
+ 0x5143932b49ef375L, 0x549477f61c6b052L, 0x57f995f3a385c67L, 0x5b3bfdb846339c0L,
+ 0x5e8afd2657c0830L, 0x61edbc6fedb0a3dL, 0x653495c5f48e666L, 0x6881bb3771b1fffL,
+ 0x6be22a054e1e7ffL, 0x6f2d5a4350d30ffL, 0x7278b0d42507d3fL, 0x75d6dd092e49c8fL,
+ 0x79264a25bcee1daL, 0x7c6fdcaf2c29a50L, 0x7fcbd3daf7340e4L, 0x831f6468da8088eL,
+ 0x86673d831120ab2L, 0x89c10ce3d568d5fL, 0x8d18a80e656185bL, 0x905ed211feb9e72L,
+ 0x93b686967e6860eL, 0x9712141e0f013c9L, 0x9a56992592c18bbL, 0x9dac3f6ef771eeaL,
+ 0xa10ba7a55aa7352L, 0xa44e918eb151027L, 0xa7a235f25da5430L, 0xab0561b77a8749eL,
+ 0xae46ba2559291c6L, 0xb19868aeaf73637L, 0xb4fe82da5b503c5L, 0xb83f11c8791225bL,
+ 0xbb8ed63a9756af2L, 0xbef28bc93d2c5afL, 0xc237975dc63bb8dL, 0xc5857d3537caa70L,
+ 0xc8e6dc8285bd50cL, 0xcc3049d19396528L, 0xcf7c5c45f87be72L, 0xd2db7357769ae0eL,
+ 0xd6292816aa20cc9L, 0xd973721c54a8ffbL, 0xdcd04ea369d33faL, 0xe0223126222407cL,
+ 0xe36abd6faaad09bL, 0xe6c56ccb95584c2L, 0xea1b63ff3d572f9L, 0xed623cff0cacfb8L,
+ 0xf0bacc3ecfd83a5L, 0xf414bfa741e7247L, 0xf759ef911260ed9L, 0xfab06b7556f9290L,
+ 0xfe0e4329565bb9aL, 0x10151d3f3abf2a80L, 0x104a648f096ef520L, 0x10807ed965e55934L,
+ 0x10b49e8fbf5eaf81L, 0x10e9c633af365b61L, 0x11201be04d81f91dL, 0x115422d860e27764L,
+ 0x11892b8e791b153dL, 0x11bf76721761da8cL, 0x11f3aa074e9d2898L, 0x12289489224472beL,
+ 0x125eb9ab6ad58f6dL, 0x1293340b22c579a4L, 0x12c8010deb76d80dL, 0x12fe015166548e11L,
+ 0x1332c0d2dff4d8caL, 0x1367710797f20efdL, 0x139d4d497dee92bcL, 0x13d2504deeb51bb6L,
+ 0x1406e4616a6262a3L, 0x143c9d79c4fafb4cL, 0x1471e26c1b1cdd0fL, 0x14a65b0721e41453L,
+ 0x14dbf1c8ea5d1968L, 0x1511771d927a2fe1L, 0x1545d4e4f718bbd9L, 0x157b4a1e34deead0L,
+ 0x15b10e52e10b52c2L, 0x15e551e7994e2772L, 0x161aa6617fa1b14fL, 0x1650a7fcefc50ed1L,
+ 0x1684d1fc2bb65286L, 0x16ba067b36a3e727L, 0x16f0440d02267078L, 0x1724551042b00c96L,
+ 0x17596a54535c0fbcL, 0x178fc4e9683313abL, 0x17c3db11e11fec4bL, 0x17f8d1d65967e75eL,
+ 0x182f064befc1e135L, 0x186363ef75d92cc1L, 0x18983ceb534f77f1L, 0x18ce4c26282355eeL,
+ 0x1902ef97d91615b5L, 0x1937ab7dcf5b9b22L, 0x196d965d433281eaL, 0x19a27dfa49ff9132L,
+ 0x19d71d78dc7f757fL, 0x1a0ce4d7139f52dfL, 0x1a420f066c4393cbL, 0x1a7692c8075478beL,
+ 0x1aac377a092996edL, 0x1ae1a2ac45b9fe54L, 0x1b160b5757287de9L, 0x1b4b8e2d2cf29d64L,
+ 0x1b8138dc3c17a25eL, 0x1bb587134b1d8af6L, 0x1beae8d81de4edb4L, 0x1c20d18712af1490L,
+ 0x1c5505e8d75ad9b4L, 0x1c8a47630d319021L, 0x1cc06c9de83efa15L, 0x1cf487c5624eb89aL,
+ 0x1d29a9b6bae266c1L, 0x1d600a1234cd8038L, 0x1d940c96c200e046L, 0x1dc90fbc72811858L,
+ 0x1dff53ab8f215e6eL, 0x1e33944b3974db05L, 0x1e68795e07d211c6L, 0x1e9e97b589c69637L,
+ 0x1ed31ed1761c1de3L, 0x1f07e685d3a3255bL, 0x1f3de027488beeb2L, 0x1f72ac188d57752fL,
+ 0x1fa7571eb0ad527bL, 0x1fdd2ce65cd8a71aL, 0x20123c0ffa076870L, 0x2046cb13f889428cL,
+ 0x207c7dd8f6ab932fL, 0x20b1cea79a2b3bfeL, 0x20e6425180b60afdL, 0x211bd2e5e0e38dbcL,
+ 0x215163cfac8e3896L, 0x2185bcc397b1c6bbL, 0x21bb2bf47d9e386aL, 0x21f0fb78ce82e342L,
+ 0x22253a5702239c13L, 0x225a88ecc2ac8317L, 0x22909593f9abd1efL, 0x22c4baf8f816c66aL,
+ 0x22f9e9b7361c7805L, 0x2330321281d1cb03L, 0x23643e9722463dc4L, 0x23994e3cead7cd35L,
+ 0x23cfa1cc258dc082L, 0x2403c51f97789851L, 0x2438b6677d56be65L, 0x246ee4015cac6dffL,
+ 0x24a34e80d9ebc4bfL, 0x24d822211066b5efL, 0x250e2aa95480636bL, 0x2542daa9d4d03e23L,
+ 0x257791544a044dabL, 0x25ad75a95c856116L, 0x25e26989d9d35caeL, 0x261703ec504833d9L,
+ 0x264cc4e7645a40d0L, 0x2681fb109eb86882L, 0x26b679d4c66682a2L, 0x26ec1849f800234bL,
+ 0x27218f2e3b00160fL, 0x2755f2f9c9c01b93L, 0x278b6fb83c302277L, 0x27c125d3259e158bL,
+ 0x27f56f47ef059aedL, 0x282acb19eac701a8L, 0x2860bef032bc6109L, 0x2894eeac3f6b794cL,
+ 0x28ca2a574f46579eL, 0x29005a76918bf6c3L, 0x2934711435eef474L, 0x29698d59436ab191L,
+ 0x299ff0af94455df5L, 0x29d3f66dbcab5ab9L, 0x2a08f4092bd63167L, 0x2a3f310b76cbbdc1L,
+ 0x2a737ea72a3f5699L, 0x2aa85e50f4cf2c3fL, 0x2ade75e53202f74fL, 0x2b1309af3f41da91L,
+ 0x2b47cc1b0f125135L, 0x2b7dbf21d2d6e583L, 0x2bb2977523c64f72L, 0x2be73d526cb7e34eL,
+ 0x2c1d0ca707e5dc22L, 0x2c5227e864efa995L, 0x2c86b1e27e2b93faL, 0x2cbc5e5b1db678f9L,
+ 0x2cf1baf8f2920b9cL, 0x2d2629b72f368e83L, 0x2d5bb424fb043223L, 0x2d9150971ce29f56L,
+ 0x2dc5a4bce41b472bL, 0x2dfb0dec1d2218f6L, 0x2e30e8b392354f9aL, 0x2e6522e076c2a380L,
+ 0x2e9a6b9894734c61L, 0x2ed0833f5cc80fbcL, 0x2f04a40f33fa13abL, 0x2f39cd1300f89896L,
+ 0x2f70202be09b5f5eL, 0x2fa42836d8c23735L, 0x2fd932448ef2c503L, 0x300f7ed5b2af7643L,
+ 0x3043af458fada9eaL, 0x30789b16f3991465L, 0x30aec1dcb07f597eL, 0x30e33929ee4f97efL,
+ 0x3118077469e37deaL, 0x314e0951845c5d65L, 0x3182c5d2f2b9ba5fL, 0x31b77747af6828f7L,
+ 0x31ed55199b423335L, 0x3222553001096001L, 0x3256ea7c014bb801L, 0x328ca51b019ea601L,
+ 0x32c1e730e10327c1L, 0x32f660fd1943f1b1L, 0x332bf93c5f94ee1dL, 0x33617bc5bbbd14d2L,
+ 0x3395dab72aac5a07L, 0x33cb5164f5577089L, 0x340112df1956a655L, 0x34355796dfac4febL,
+ 0x346aad7c979763e5L, 0x34a0ac6ddebe9e6fL, 0x34d4d789566e460bL, 0x350a0d6bac09d78eL,
+ 0x354048634b8626b9L, 0x35745a7c1e67b067L, 0x35a9711b26019c81L, 0x35dfcd61ef8203a1L,
+ 0x3613e05d35b14245L, 0x3648d874831d92d6L, 0x367f0e91a3e4f78bL, 0x36b3691b066f1ab7L,
+ 0x36e84361c80ae165L, 0x371e543a3a0d99beL, 0x3752f4a464488017L, 0x3787b1cd7d5aa01cL,
+ 0x37bd9e40dcb14823L, 0x37f282e889eecd16L, 0x382723a2ac6a805cL, 0x385cec8b57852073L,
+ 0x389213d716b33448L, 0x38c698ccdc60015aL, 0x38fc3f00137801b0L, 0x3931a7600c2b010eL,
+ 0x396611380f35c151L, 0x399b9586130331a6L, 0x39d13d73cbe1ff08L, 0x3a058cd0beda7ec9L,
+ 0x3a3af004ee911e7cL, 0x3a70d603151ab30dL, 0x3aa50b83da615fd1L, 0x3ada4e64d0f9b7c5L,
+ 0x3b1070ff029c12dbL, 0x3b448d3ec3431792L, 0x3b79b08e7413dd76L, 0x3bb00e59088c6a6aL,
+ 0x3be411ef4aaf8504L, 0x3c19166b1d5b6646L, 0x3c4f5c05e4b23fd7L, 0x3c839983aeef67e6L,
+ 0x3cb87fe49aab41e0L, 0x3cee9fddc1561258L, 0x3d2323ea98d5cb77L, 0x3d57ece53f0b3e55L,
+ 0x3d8de81e8ece0deaL, 0x3dc2b1131940c8b2L, 0x3df75d57df90fadfL, 0x3e2d34add7753996L,
+ 0x3e6240eca6a943feL, 0x3e96d127d05394fdL, 0x3ecc8571c4687a3dL, 0x3f01d3671ac14c66L,
+ 0x3f364840e1719f80L, 0x3f6bda5119ce075fL, 0x3fa16872b020c49cL, 0x3fd5c28f5c28f5c3L,
+ 0x400B333333333333L };
+
+ private static final long rawBitsFor1_2e0To309[] = { 0x3ff3333333333333L, 0x4028000000000000L,
+ 0x405e000000000000L, 0x4092c00000000000L, 0x40c7700000000000L, 0x40fd4c0000000000L,
+ 0x41324f8000000000L, 0x4166e36000000000L, 0x419c9c3800000000L, 0x41d1e1a300000000L,
+ 0x42065a0bc0000000L, 0x423bf08eb0000000L, 0x427176592e000000L, 0x42a5d3ef79800000L,
+ 0x42db48eb57e00000L, 0x43110d9316ec0000L, 0x434550f7dca70000L, 0x437aa535d3d0c000L,
+ 0x43b0a741a4627800L, 0x43e4d1120d7b1600L, 0x441a055690d9db80L, 0x445043561a882930L,
+ 0x4484542ba12a337cL, 0x44b969368974c05bL, 0x44efc3842bd1f072L, 0x4523da329b633647L,
+ 0x4558d0bf423c03d9L, 0x458f04ef12cb04cfL, 0x45c363156bbee301L, 0x45f83bdac6ae9bc2L,
+ 0x462e4ad1785a42b2L, 0x4662eec2eb3869afL, 0x4697aa73a606841bL, 0x46cd95108f882522L,
+ 0x47027d2a59b51735L, 0x47371c74f0225d03L, 0x476ce3922c2af443L, 0x47a20e3b5b9ad8aaL,
+ 0x47d691ca32818ed5L, 0x480c363cbf21f28aL, 0x4841a1e5f7753796L, 0x48760a5f7552857cL,
+ 0x48ab8cf752a726daL, 0x48e1381a93a87849L, 0x491586213892965bL, 0x494ae7a986b73bf1L,
+ 0x4980d0c9f4328577L, 0x49b504fc713f26d5L, 0x49ea463b8d8ef08aL, 0x4a206be538795656L,
+ 0x4a5486de8697abecL, 0x4a89a896283d96e6L, 0x4ac0095dd9267e50L, 0x4af40bb54f701de4L,
+ 0x4b290ea2a34c255dL, 0x4b5f524b4c1f2eb4L, 0x4b93936f0f937d31L, 0x4bc8784ad3785c7dL,
+ 0x4bfe965d8856739cL, 0x4c331dfa75360842L, 0x4c67e57912838a52L, 0x4c9dded757246ce6L,
+ 0x4cd2ab469676c410L, 0x4d0756183c147514L, 0x4d3d2b9e4b199259L, 0x4d723b42eeeffb78L,
+ 0x4da6ca13aaabfa56L, 0x4ddc7c989556f8ebL, 0x4e11cddf5d565b93L, 0x4e46415734abf278L,
+ 0x4e7bd1ad01d6ef15L, 0x4eb1630c2126556dL, 0x4ee5bbcf296feac9L, 0x4f1b2ac2f3cbe57bL,
+ 0x4f50fab9d85f6f6dL, 0x4f8539684e774b48L, 0x4fba87c262151e1aL, 0x4ff094d97d4d32d0L,
+ 0x5024ba0fdca07f84L, 0x5059e893d3c89f65L, 0x5090315c645d639fL, 0x50c43db37d74bc87L,
+ 0x50f94d205cd1eba9L, 0x512fa06874066693L, 0x5163c4414884001cL, 0x5198b5519aa50023L,
+ 0x51cee2a6014e402cL, 0x52034da7c0d0e81bL, 0x52382111b1052222L, 0x526e29561d466aabL,
+ 0x52a2d9d5d24c02abL, 0x52d7904b46df0355L, 0x530d745e1896c42bL, 0x534268bacf5e3a9bL,
+ 0x537702e98335c941L, 0x53acc3a3e4033b92L, 0x53e1fa466e82053bL, 0x541678d80a22868aL,
+ 0x544c170e0cab282cL, 0x54818e68c7eaf91cL, 0x54b5f202f9e5b763L, 0x54eb6e83b85f253bL,
+ 0x55212512533b7745L, 0x55556e56e80a5516L, 0x558ac9eca20cea5cL, 0x55c0be33e5481279L,
+ 0x55f4edc0de9a1718L, 0x562a293116409cdeL, 0x566059beade8620bL, 0x5694702e59627a8dL,
+ 0x56c98c39efbb1931L, 0x56ffef486ba9df7dL, 0x5733f58d434a2baeL, 0x5768f2f0941cb699L,
+ 0x579f2facb923e440L, 0x57d37dcbf3b66ea8L, 0x58085d3ef0a40a52L, 0x583e748eaccd0ce6L,
+ 0x587308d92c002810L, 0x58a7cb0f77003214L, 0x58ddbdd354c03e99L, 0x591296a414f82720L,
+ 0x59473c4d1a3630e8L, 0x597d0b6060c3bd21L, 0x59b2271c3c7a5635L, 0x59e6b0e34b98ebc2L,
+ 0x5a1c5d1c1e7f26b3L, 0x5a51ba31930f7830L, 0x5a8628bdf7d3563cL, 0x5abbb2ed75c82bcaL,
+ 0x5af14fd4699d1b5fL, 0x5b25a3c984046236L, 0x5b5b0cbbe5057ac4L, 0x5b90e7f56f236cbaL,
+ 0x5bc521f2caec47e9L, 0x5bfa6a6f7da759e3L, 0x5c308285ae88982eL, 0x5c64a3271a2abe39L,
+ 0x5c99cbf0e0b56dc8L, 0x5cd01f768c71649dL, 0x5d0427542f8dbdc4L, 0x5d3931293b712d35L,
+ 0x5d6f7d738a4d7882L, 0x5da3ae6836706b51L, 0x5dd89a02440c8626L, 0x5e0ec082d50fa7afL,
+ 0x5e433851c529c8ceL, 0x5e78066636743b01L, 0x5eae07ffc41149c1L, 0x5ee2c4ffda8ace19L,
+ 0x5f17763fd12d819fL, 0x5f4d53cfc578e207L, 0x5f825461db6b8d44L, 0x5fb6e97a52467095L,
+ 0x5feca3d8e6d80cbbL, 0x6021e667904707f5L, 0x605660017458c9f2L, 0x608bf801d16efc6eL,
+ 0x60c17b0122e55dc5L, 0x60f5d9c16b9eb536L, 0x612b5031c6866284L, 0x6161121f1c13fd92L,
+ 0x619556a6e318fcf7L, 0x61caac509bdf3c34L, 0x6200abb2616b85a1L, 0x6234d69ef9c66709L,
+ 0x626a0c46b83800cbL, 0x62a047ac3323007fL, 0x62d459973febc09fL, 0x63096ffd0fe6b0c6L,
+ 0x633fcbfc53e05cf8L, 0x6373df7db46c3a1bL, 0x63a8d75d218748a2L, 0x63df0d3469e91acaL,
+ 0x64136840c231b0beL, 0x64484250f2be1ceeL, 0x647e52e52f6da42aL, 0x64b2f3cf3da4869aL,
+ 0x64e7b0c30d0da840L, 0x651d9cf3d0511251L, 0x655282186232ab72L, 0x6587229e7abf564fL,
+ 0x65bceb46196f2be3L, 0x65f2130bcfe57b6eL, 0x662697cec3deda49L, 0x665c3dc274d690dbL,
+ 0x6691a69989061a89L, 0x66c6103feb47a12bL, 0x66fb944fe6198976L, 0x67313cb1efcff5eaL,
+ 0x67658bde6bc3f364L, 0x679aeed606b4f03dL, 0x67d0d545c4311626L, 0x68050a97353d5bb0L,
+ 0x683a4d3d028cb29cL, 0x687070462197efa2L, 0x68a48c57a9fdeb8aL, 0x68d9af6d947d666cL,
+ 0x69100da47cce6004L, 0x6944110d9c01f805L, 0x6979155103027606L, 0x69af5aa543c31387L,
+ 0x69e398a74a59ec35L, 0x6a187ed11cf06742L, 0x6a4e9e85642c8112L, 0x6a8323135e9bd0abL,
+ 0x6ab7ebd83642c4d6L, 0x6aede6ce43d3760cL, 0x6b22b040ea6429c7L, 0x6b575c5124fd3439L,
+ 0x6b8d33656e3c8147L, 0x6bc2401f64e5d0cdL, 0x6bf6d0273e1f4500L, 0x6c2c84310da71640L,
+ 0x6c61d29ea8886de8L, 0x6c96474652aa8962L, 0x6ccbd917e7552bbaL, 0x6d0167aef0953b54L,
+ 0x6d35c19aacba8a29L, 0x6d6b320157e92cb4L, 0x6da0ff40d6f1bbf0L, 0x6dd53f110cae2aedL,
+ 0x6e0a8ed54fd9b5a8L, 0x6e40994551e81189L, 0x6e74bf96a66215ebL, 0x6ea9ef7c4ffa9b66L,
+ 0x6ee035adb1fca120L, 0x6f1443191e7bc967L, 0x6f4953df661abbc1L, 0x6f7fa8d73fa16ab2L,
+ 0x6fb3c98687c4e2afL, 0x6fe8bbe829b61b5bL, 0x701eeae23423a232L, 0x705352cd6096455fL,
+ 0x70882780b8bbd6b7L, 0x70be3160e6eacc64L, 0x70f2dedc9052bfbfL, 0x71279693b4676faeL,
+ 0x715d7c38a1814b9aL, 0x71926da364f0cf40L, 0x71c7090c3e2d0310L, 0x71fccb4f4db843d4L,
+ 0x7231ff1190932a65L, 0x72667ed5f4b7f4feL, 0x729c1e8b71e5f23dL, 0x72d19317272fb766L,
+ 0x7305f7dcf0fba540L, 0x733b75d42d3a8e90L, 0x737129a49c44991aL, 0x73a5740dc355bf60L,
+ 0x73dad111342b2f39L, 0x7410c2aac09afd83L, 0x7444f35570c1bce4L, 0x747a302accf22c1dL,
+ 0x74b05e1ac0175b92L, 0x74e475a1701d3277L, 0x75199309cc247f15L, 0x754ff7cc3f2d9edaL,
+ 0x7583fadfa77c8348L, 0x75b8f997915ba41aL, 0x75ef37fd75b28d21L, 0x762382fe698f9834L,
+ 0x765863be03f37e41L, 0x768e7cad84f05dd2L, 0x76c30dec73163aa3L, 0x76f7d1678fdbc94cL,
+ 0x772dc5c173d2bb9fL, 0x77629b98e863b543L, 0x7797427f227ca294L, 0x77cd131eeb1bcb39L,
+ 0x78022bf352f15f04L, 0x7836b6f027adb6c5L, 0x786c64ac31992476L, 0x78a1beeb9effb6caL,
+ 0x78d62ea686bfa47cL, 0x790bba50286f8d9bL, 0x794154721945b881L, 0x7975a98e9f9726a1L,
+ 0x79ab13f2477cf049L, 0x79e0ec776cae162eL, 0x7a15279547d99bb9L, 0x7a4a717a99d002a8L,
+ 0x7a8086eca02201a9L, 0x7ab4a8a7c82a8213L, 0x7ae9d2d1ba352298L, 0x7b2023c31461359fL,
+ 0x7b542cb3d9798307L, 0x7b8937e0cfd7e3c8L, 0x7bbf85d903cddcbaL, 0x7bf3b3a7a260a9f4L,
+ 0x7c28a0918af8d472L, 0x7c5ec8b5edb7098eL, 0x7c933d71b49265f9L, 0x7cc80cce21b6ff77L,
+ 0x7cfe1001aa24bf55L, 0x7d32ca010a56f795L, 0x7d677c814cecb57aL, 0x7d9d5ba1a027e2d9L,
+ 0x7dd259450418edc7L, 0x7e06ef96451f2939L, 0x7e3cab7bd666f388L, 0x7e71eb2d66005835L,
+ 0x7ea665f8bf806e42L, 0x7edbff76ef6089d2L, 0x7f117faa559c5623L, 0x7f45df94eb036bacL,
+ 0x7f7b577a25c44697L, 0x7fb116ac579aac1fL, 0x7fe55c576d815726L, 0x7ff0000000000000L };
+
+ private void doTestCompareRawBits(String originalDoubleString, long expectedRawBits,
+ String expectedString) {
+ double result;
+ long rawBits;
+ String convertedString;
+ result = Double.parseDouble(originalDoubleString);
+ rawBits = Double.doubleToLongBits(result);
+ convertedString = new Double(result).toString();
+ assertEquals(expectedRawBits, rawBits);
+ assertEquals(expectedString.toLowerCase(Locale.US), convertedString
+ .toLowerCase(Locale.US));
+ }
+
+ private void test_toString(double dd, String answer) {
+ assertEquals(answer, Double.toString(dd));
+ Double d = new Double(dd);
+ assertEquals(answer, Double.toString(d.doubleValue()));
+ assertEquals(answer, d.toString());
+ }
+
+ /**
+ * java.lang.Double#Double(double)
+ */
+ public void test_ConstructorD() {
+ Double d = new Double(39089.88888888888888888888888888888888);
+ assertEquals("Created incorrect double", 39089.88888888888888888888888888888888, d
+ .doubleValue(), 0D);
+ }
+
+ /**
+ * java.lang.Double#Double(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ Double d = new Double("39089.88888888888888888888888888888888");
+ assertEquals("Created incorrect double", 39089.88888888888888888888888888888888, d
+ .doubleValue(), 0D);
+
+ // Regression test for HARMONY-489
+ try {
+ d = new Double("1E+-20");
+ fail("new Double(\"1E+-20\") should throw exception");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ // Regression test for HARMONY-329
+ d = Double.parseDouble("-1.233999999999999965116738099630936817275852021384209929081813042837802886790127428328465579708849276001782791006814286802871737087810957327493372866733334925806221045495205250590286471187577636646208155890426896101636282423463443661040209738873506655844025580428394216030152374941053494694642722606658935546875E-112");
+ assertEquals("Failed to parse long string", -1.234E-112D, d.doubleValue(), 0D);
+ }
+
+ /**
+ * java.lang.Double#byteValue()
+ */
+ public void test_byteValue() {
+ Double d = new Double(1923311.47712);
+ assertEquals("Returned incorrect byte value", (byte) -17, d.byteValue());
+ }
+
+ /**
+ * java.lang.Double#compareTo(java.lang.Double)
+ * java.lang.Double#compare(double, double)
+ */
+ public void test_compare() {
+ double[] values = new double[] { Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, -2d,
+ -Double.MIN_VALUE, -0d, 0d, Double.MIN_VALUE, 2d, Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY, Double.NaN };
+ for (int i = 0; i < values.length; i++) {
+ double d1 = values[i];
+ assertTrue("compare() should be equal: " + d1, Double.compare(d1, d1) == 0);
+ Double D1 = new Double(d1);
+ assertTrue("compareTo() should be equal: " + d1, D1.compareTo(D1) == 0);
+ for (int j = i + 1; j < values.length; j++) {
+ double d2 = values[j];
+ assertTrue("compare() " + d1 + " should be less " + d2,
+ Double.compare(d1, d2) == -1);
+ assertTrue("compare() " + d2 + " should be greater " + d1, Double.compare(d2,
+ d1) == 1);
+ Double D2 = new Double(d2);
+ assertTrue("compareTo() " + d1 + " should be less " + d2,
+ D1.compareTo(D2) == -1);
+ assertTrue("compareTo() " + d2 + " should be greater " + d1,
+ D2.compareTo(D1) == 1);
+ }
+ }
+
+ try {
+ new Double(0.0D).compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Double#doubleToLongBits(double)
+ */
+ public void test_doubleToLongBitsD() {
+ // Test for method long java.lang.Double.doubleToLongBits(double)
+ Double d = new Double(Double.MAX_VALUE);
+ long lbits = Double.doubleToLongBits(d.doubleValue());
+ double r = Double.longBitsToDouble(lbits);
+
+ assertTrue("Bit conversion failed", d.doubleValue() == r);
+ }
+
+ /**
+ * java.lang.Double#doubleToRawLongBits(double)
+ */
+ public void test_doubleToRawLongBitsD() {
+ long l = 0x7ff80000000004d2L;
+ double d = Double.longBitsToDouble(l);
+ assertTrue("Wrong raw bits", Double.doubleToRawLongBits(d) == l);
+ }
+
+ /**
+ * java.lang.Double#doubleValue()
+ */
+ public void test_doubleValue() {
+ assertEquals("Incorrect double value returned", 999999999999999.9999999999999,
+ new Double(999999999999999.9999999999999).doubleValue(), 0D);
+ }
+
+ /**
+ * java.lang.Double#floatValue()
+ */
+ public void test_floatValue() {
+ // Test for method float java.lang.Double.floatValue()
+ assertTrue(
+ "Incorrect float value returned ",
+ Math
+ .abs(new Double(999999999999999.9999999999999d).floatValue() - 999999999999999.9999999999999f) < 1);
+ }
+
+ /**
+ * java.lang.Double#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.lang.Double.hashCode()
+ for (int i = -1000; i < 1000; i++) {
+ Double d = new Double(i);
+ Double dd = new Double(i);
+ assertTrue("Should not be identical ", d != dd);
+ assertTrue("Should be equals 1 ", d.equals(dd));
+ assertTrue("Should be equals 2 ", dd.equals(d));
+ assertTrue("Should have identical values ", dd.doubleValue() == d.doubleValue());
+ assertTrue("Invalid hash for equal but not identical doubles ", d.hashCode() == dd
+ .hashCode());
+ }
+ assertEquals("Magic assumption hasCode (0.0) = 0 failed", 0, new Double(0.0).hashCode());
+ }
+
+ /**
+ * java.lang.Double#intValue()
+ */
+ public void test_intValue() {
+ // Test for method int java.lang.Double.intValue()
+ Double d = new Double(1923311.47712);
+ assertEquals("Returned incorrect int value", 1923311, d.intValue());
+ }
+
+ /**
+ * java.lang.Double#isInfinite()
+ */
+ public void test_isInfinite() {
+ // Test for method boolean java.lang.Double.isInfinite()
+ assertTrue("NEGATIVE_INFINITY returned false", new Double(Double.NEGATIVE_INFINITY)
+ .isInfinite());
+ assertTrue("POSITIVE_INFINITY returned false", new Double(Double.POSITIVE_INFINITY)
+ .isInfinite());
+ assertTrue("Non infinite number returned true", !(new Double(1000).isInfinite()));
+ }
+
+ /**
+ * java.lang.Double#isInfinite(double)
+ */
+ public void test_isInfiniteD() {
+ // Test for method boolean java.lang.Double.isInfinite(double)
+ assertTrue("Infinity check failed", Double.isInfinite(Double.NEGATIVE_INFINITY)
+ && (Double.isInfinite(Double.POSITIVE_INFINITY))
+ && !(Double.isInfinite(Double.MAX_VALUE)));
+ }
+
+ /**
+ * java.lang.Double#isNaN()
+ */
+ public void test_isNaN() {
+ // Test for method boolean java.lang.Double.isNaN()
+ Double d = new Double(0.0 / 0.0);
+ assertTrue("NAN returned false", d.isNaN());
+ d = new Double(0);
+ assertTrue("Non NAN returned true", !d.isNaN());
+ }
+
+ /**
+ * java.lang.Double#isNaN(double)
+ */
+ public void test_isNaND() {
+ // Test for method boolean java.lang.Double.isNaN(double)
+
+ Double d = new Double(0.0 / 0.0);
+ assertTrue("NAN check failed", Double.isNaN(d.doubleValue()));
+ }
+
+ /**
+ * java.lang.Double#longBitsToDouble(long)
+ */
+ public void test_longBitsToDoubleJ() {
+ // Test for method double java.lang.Double.longBitsToDouble(long)
+
+ Double d = new Double(Double.MAX_VALUE);
+ long lbits = Double.doubleToLongBits(d.doubleValue());
+ double r = Double.longBitsToDouble(lbits);
+
+ assertTrue("Bit conversion failed", d.doubleValue() == r);
+ }
+
+ /**
+ * java.lang.Double#longValue()
+ */
+ public void test_longValue() {
+ // Test for method long java.lang.Double.longValue()
+ Double d = new Double(1923311.47712);
+ assertEquals("Returned incorrect long value", 1923311, d.longValue());
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDoubleLjava_lang_String() {
+ assertEquals("Incorrect double returned, expected zero.", 0.0, Double
+ .parseDouble("2.4703282292062327208828439643411e-324"), 0.0);
+ assertTrue("Incorrect double returned, expected minimum double.", Double
+ .parseDouble("2.4703282292062327208828439643412e-324") == Double.MIN_VALUE);
+
+ for (int i = 324; i > 0; i--) {
+ Double.parseDouble("3.4e-" + i);
+ }
+ for (int i = 0; i <= 309; i++) {
+ Double.parseDouble("1.2e" + i);
+ }
+
+ /*
+ * The first two cases and the last four cases have to placed outside
+ * the loop due to the difference in the expected output string.
+ */
+ doTestCompareRawBits("3.4e-324", rawBitsFor3_4en324ToN1[0], "4.9e-324");
+ doTestCompareRawBits("3.4e-323", rawBitsFor3_4en324ToN1[1], "3.5e-323");
+ for (int i = 322; i > 3; i--) {
+ String testString, expectedString;
+ testString = expectedString = "3.4e-" + i;
+ doTestCompareRawBits(testString, rawBitsFor3_4en324ToN1[324 - i], expectedString);
+ }
+ doTestCompareRawBits("3.4e-3", rawBitsFor3_4en324ToN1[321], "0.0034");
+ doTestCompareRawBits("3.4e-2", rawBitsFor3_4en324ToN1[322], "0.034");
+ doTestCompareRawBits("3.4e-1", rawBitsFor3_4en324ToN1[323], "0.34");
+ doTestCompareRawBits("3.4e-0", rawBitsFor3_4en324ToN1[324], "3.4");
+
+ doTestCompareRawBits("1.2e0", rawBitsFor1_2e0To309[0], "1.2");
+ doTestCompareRawBits("1.2e1", rawBitsFor1_2e0To309[1], "12.0");
+ doTestCompareRawBits("1.2e2", rawBitsFor1_2e0To309[2], "120.0");
+ doTestCompareRawBits("1.2e3", rawBitsFor1_2e0To309[3], "1200.0");
+ doTestCompareRawBits("1.2e4", rawBitsFor1_2e0To309[4], "12000.0");
+ doTestCompareRawBits("1.2e5", rawBitsFor1_2e0To309[5], "120000.0");
+ doTestCompareRawBits("1.2e6", rawBitsFor1_2e0To309[6], "1200000.0");
+ for (int i = 7; i <= 308; i++) {
+ String testString, expectedString;
+ testString = expectedString = "1.2e" + i;
+ doTestCompareRawBits(testString, rawBitsFor1_2e0To309[i], expectedString);
+ }
+ doTestCompareRawBits("1.2e309", rawBitsFor1_2e0To309[309], "Infinity");
+
+ doTestCompareRawBits(
+ "111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000.92233720368547758079223372036854775807",
+ 0x7e054218c295e43fL, "1.1122233344455567E299");
+ doTestCompareRawBits(
+ "-111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000.92233720368547758079223372036854775807",
+ 0xfe054218c295e43fL, "-1.1122233344455567E299");
+
+ doTestCompareRawBits("1.234123412431233E107", 0x562ae7a25fe706ebL,
+ "1.234123412431233E107");
+ doTestCompareRawBits("1.2341234124312331E107", 0x562ae7a25fe706ecL,
+ "1.2341234124312331E107");
+ doTestCompareRawBits("1.2341234124312332E107", 0x562ae7a25fe706ecL,
+ "1.2341234124312331E107");
+ doTestCompareRawBits("-1.234123412431233E107", 0xd62ae7a25fe706ebL,
+ "-1.234123412431233E107");
+ doTestCompareRawBits("-1.2341234124312331E107", 0xd62ae7a25fe706ecL,
+ "-1.2341234124312331E107");
+ doTestCompareRawBits("-1.2341234124312332E107", 0xd62ae7a25fe706ecL,
+ "-1.2341234124312331E107");
+
+ doTestCompareRawBits("1e23", 0x44b52d02c7e14af6L, "1.0e23");
+
+ /*
+ * These particular tests verify that the extreme boundary conditions
+ * are converted correctly.
+ */
+ doTestCompareRawBits("0.0e-309", 0L, "0.0");
+ doTestCompareRawBits("-0.0e-309", 0x8000000000000000L, "-0.0");
+ doTestCompareRawBits("0.0e309", 0L, "0.0");
+ doTestCompareRawBits("-0.0e309", 0x8000000000000000L, "-0.0");
+ doTestCompareRawBits("0.1e309", 0x7fe1ccf385ebc8a0L, "1.0e308");
+ doTestCompareRawBits("0.2e309", 0x7ff0000000000000L, "Infinity");
+ doTestCompareRawBits("65e-325", 1L, "4.9e-324");
+ doTestCompareRawBits("1000e-326", 2L, "1.0e-323");
+
+ doTestCompareRawBits("4.0e-306", 0x86789e3750f791L, "4.0e-306");
+ doTestCompareRawBits("2.22507e-308", 0xffffe2e8159d0L, "2.22507e-308");
+ doTestCompareRawBits(
+ "111222333444555666777888999000111228999000.92233720368547758079223372036854775807",
+ 0x48746da623f1dd8bL, "1.1122233344455567E41");
+ doTestCompareRawBits(
+ "-111222333444555666777888999000111228999000.92233720368547758079223372036854775807",
+ 0xc8746da623f1dd8bL, "-1.1122233344455567E41");
+ doTestCompareRawBits(
+ "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210",
+ 0x54820fe0ba17f469L, "1.2345678901234567E99");
+ doTestCompareRawBits(
+ "-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210",
+ 0xd4820fe0ba17f469L, "-1.2345678901234567E99");
+
+ doTestCompareRawBits(
+ "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.01",
+ 0x7fefffffffffffffL, "1.7976931348623157E308");
+ doTestCompareRawBits(
+ "-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.01",
+ 0xffefffffffffffffL, "-1.7976931348623157E308");
+ doTestCompareRawBits(
+ "1112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001234567890",
+ 0x7ff0000000000000L, "Infinity");
+ doTestCompareRawBits(
+ "-1112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001234567890",
+ 0xfff0000000000000L, "-Infinity");
+ doTestCompareRawBits(
+ "179769313486231590000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.01",
+ 0x7ff0000000000000L, "Infinity");
+ doTestCompareRawBits(
+ "-179769313486231590000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.01",
+ 0xfff0000000000000L, "-Infinity");
+ doTestCompareRawBits(
+ "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+ 0x2b392a32afcc661eL, "1.7976931348623157E-100");
+ doTestCompareRawBits(
+ "-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+ 0xab392a32afcc661eL, "-1.7976931348623157E-100");
+ doTestCompareRawBits(
+ "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+ 0x1b3432f0cb68e61L, "1.7976931348623157E-300");
+ doTestCompareRawBits(
+ "-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+ 0x81b3432f0cb68e61L, "-1.7976931348623157E-300");
+ doTestCompareRawBits(
+ "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+ 0x2117b590b942L, "1.79769313486234E-310");
+ doTestCompareRawBits(
+ "-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+ 0x80002117b590b942L, "-1.79769313486234E-310");
+ doTestCompareRawBits(
+ "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+ 0xe37L, "1.798E-320");
+ doTestCompareRawBits(
+ "-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+ 0x8000000000000e37L, "-1.798E-320");
+ doTestCompareRawBits(
+ "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ 0x2L, "1.0E-323");
+ doTestCompareRawBits(
+ "-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ 0x8000000000000002L, "-1.0E-323");
+ doTestCompareRawBits(
+ "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055595409854908458349204328908234982349050934129878452378432452458968024357823490509341298784523784324524589680243578234905093412987845237843245245896802435782349050934129878452378432452458968024357868024357823490509341298784523784324524589680243578234905093412987845237843245245896802435786802435782349050934129878452378432452458968024357823490509341298784523784324524589680243578",
+ 0x1L, "4.9E-324");
+ doTestCompareRawBits(
+ "-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055595409854908458349204328908234982349050934129878452378432452458968024357823490509341298784523784324524589680243578234905093412987845237843245245896802435782349050934129878452378432452458968024357868024357823490509341298784523784324524589680243578234905093412987845237843245245896802435786802435782349050934129878452378432452458968024357823490509341298784523784324524589680243578",
+ 0x8000000000000001L, "-4.9E-324");
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_Illegal() {
+ try {
+ Double.parseDouble("0.0p0D");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ Double.parseDouble("+0x.p1d");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ Double.parseDouble("0Xg.gp1D");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ Double.parseDouble("-0x1.1p");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ Double.parseDouble("+0x 1.1 p2d");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ Double.parseDouble("x1.1p2d");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ Double.parseDouble(" 0x-2.1p2");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ Double.parseDouble(" 0x2.1pad");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ Double.parseDouble(" 0x111.222p 22d");
+ fail("Should throw NumberFormatException.");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_FromHexString() {
+ double actual;
+ double expected;
+
+ actual = Double.parseDouble("0x0.0p0D");
+ assertEquals("Returned incorrect value", 0.0d, actual, 0.0D);
+
+ actual = Double.parseDouble("0xa.ap+9d");
+ assertEquals("Returned incorrect value", 5440.0d, actual, 0.0D);
+
+ actual = Double.parseDouble("+0Xb.10ap8");
+ assertEquals("Returned incorrect value", 2832.625d, actual, 0.0D);
+
+ actual = Double.parseDouble("-0X.a0P2D");
+ assertEquals("Returned incorrect value", -2.5d, actual, 0.0D);
+
+ actual = Double.parseDouble("\r 0x22.1p2d \t");
+ assertEquals("Returned incorrect value", 136.25d, actual, 0.0D);
+
+ actual = Double.parseDouble("0x1.0p-1");
+ assertEquals("Returned incorrect value", 0.5, actual, 0.0D);
+
+ actual = Double
+ .parseDouble("0x00000000000000000000000000000000001.0p-1");
+ assertEquals("Returned incorrect value", 0.5, actual, 0.0D);
+
+ actual = Double.parseDouble("0x1.0p-00000000000000000000000000001");
+ assertEquals("Returned incorrect value", 0.5, actual, 0.0D);
+
+ actual = Double.parseDouble("0x.100000000000000000000000000000000p1");
+ assertEquals("Returned incorrect value", 0.125, actual, 0.0D);
+
+ actual = Double.parseDouble("0x0.0p999999999999999999999999999999999999999999999999999999999999999");
+ assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+ actual = Double.parseDouble("0xf1.0p9999999999999999999999999999999999999999999999999999999999999999");
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+ actual = Double.parseDouble("0xffffffffffffffffffffffffffffffffffff.ffffffffffffffffffffffffffffffffffffffffffffffp1");
+ expected = Double.longBitsToDouble(0x4900000000000000L);
+ assertEquals("Returned incorrect value", expected, actual, 0.0D);
+
+ actual = Double.parseDouble("0x0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001p1600");
+ expected = Double.longBitsToDouble(0x7f30000000000000L);
+ assertEquals("Returned incorrect value", expected, actual, 0.0D);
+
+ actual = Double.parseDouble("0x0.0p-999999999999999999999999999999999999999999999999999999");
+ assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+ actual = Double.parseDouble("0xf1.0p-9999999999999999999999999999999999999999999999999999999999999999");
+ assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+ actual = Double.parseDouble("0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000p-1600");
+ expected = Double.longBitsToDouble(0xf0000000000000L);
+ assertEquals("Returned incorrect value", expected, actual, 0.0D);
+
+ actual = Double.parseDouble("0x1.p9223372036854775807");
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+ actual = Double.parseDouble("0x1.p9223372036854775808");
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+ actual = Double.parseDouble("0x10.p9223372036854775808");
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+ actual = Double.parseDouble("0xabcd.ffffffffp+2000");
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+ actual = Double.parseDouble("0x1.p-9223372036854775808");
+ assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+ actual = Double.parseDouble("0x1.p-9223372036854775809");
+ assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+ actual = Double.parseDouble("0x.1p-9223372036854775809");
+ assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+ actual = Double.parseDouble("0xabcd.ffffffffffffffp-2000");
+ assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_NormalPositiveExponent() {
+ long[] expecteds = {
+ 0x3f323456789abcdfL, 0x40e111012345678aL, 0x41a1110091a2b3c5L,
+ 0x4259998091a2b3c5L, 0x4311110048d159e2L, 0x43c5554048d159e2L,
+ 0x4479998048d159e2L, 0x452dddc048d159e2L, 0x45e111002468acf1L,
+ 0x469333202468acf1L, 0x4751011001234568L, 0x4802112101234568L,
+ 0x48b3213201234568L, 0x4964314301234568L, 0x4a15415401234568L,
+ 0x4ac6516501234568L, 0x4b77617601234568L, 0x4c28718701234568L,
+ 0x4cd9819801234568L, 0x4d9049048091a2b4L, 0x4e4101100091a2b4L,
+ 0x4ef189188091a2b4L, 0x4fa211210091a2b4L, 0x505299298091a2b4L,
+ 0x510321320091a2b4L, 0x51b3a93a8091a2b4L, 0x526431430091a2b4L,
+ 0x5314b94b8091a2b4L, 0x53c841840091a2b4L, 0x5478c98c8091a2b4L,
+ 0x552981980091a2b4L, 0x55da09a08091a2b4L, 0x568a91a90091a2b4L,
+ 0x573b19b18091a2b4L, 0x57eba1ba0091a2b4L, 0x589c29c28091a2b4L,
+ 0x594cb1cb0091a2b4L, 0x5a001d01c048d15aL, 0x5ab061060048d15aL,
+ 0x5b60a50a4048d15aL, 0x5c1101100048d15aL, 0x5cc145144048d15aL,
+ 0x5d7189188048d15aL, 0x5e21cd1cc048d15aL, 0x5ed211210048d15aL,
+ 0x5f8255254048d15aL, 0x603419418048d15aL, 0x60e45d45c048d15aL,
+ 0x6194a14a0048d15aL, 0x6244e54e4048d15aL, 0x62f541540048d15aL,
+ 0x63a585584048d15aL, 0x6455c95c8048d15aL, 0x65060d60c048d15aL,
+ 0x65b651650048d15aL, 0x666815814048d15aL, 0x671859858048d15aL,
+ 0x67c89d89c048d15aL, 0x6878e18e0048d15aL, 0x692925924048d15aL,
+ 0x69d981980048d15aL, 0x6a89c59c4048d15aL, 0x6b3a09a08048d15aL,
+ 0x6bea4da4c048d15aL, 0x6c9c11c10048d15aL, 0x6d4c55c54048d15aL,
+ 0x6dfc99c98048d15aL, 0x6eacddcdc048d15aL, 0x6f5d21d20048d15aL,
+ 0x700d65d64048d15aL, 0x70bdc1dc0048d15aL, 0x716e05e04048d15aL,
+ 0x721e49e48048d15aL, 0x72d00700602468adL, 0x73802902802468adL,
+ 0x74304b04a02468adL, 0x74e06d06c02468adL, 0x75908f08e02468adL,
+ 0x7640b10b002468adL, 0x76f0d30d202468adL, 0x77a10110002468adL,
+ 0x78512312202468adL, 0x79020520402468adL, 0x79b22722602468adL,
+ 0x7a624924802468adL, 0x7b126b26a02468adL, 0x7bc28d28c02468adL,
+ 0x7c72af2ae02468adL, 0x7d22d12d002468adL, 0x7dd2f32f202468adL,
+ 0x7e832132002468adL, 0x7f40011001012345L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L };
+
+ for (int i = 0; i < expecteds.length; i++) {
+ int part = i * 11;
+ String inputString = "0x" + part + "." + part + "0123456789abcdefp" + part;
+
+ double actual = Double.parseDouble(inputString);
+ double expected = Double.longBitsToDouble(expecteds[i]);
+
+ String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+ String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+ String errorMsg = i + "th input string is:<" + inputString
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0D);
+ }
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_NormalNegativeExponent() {
+ long[] expecteds = {
+ 0x3f323456789abcdfL, 0x3f8111012345678aL, 0x3ee1110091a2b3c5L,
+ 0x3e39998091a2b3c5L, 0x3d91110048d159e2L, 0x3ce5554048d159e2L,
+ 0x3c39998048d159e2L, 0x3b8dddc048d159e2L, 0x3ae111002468acf1L,
+ 0x3a3333202468acf1L, 0x3991011001234568L, 0x38e2112101234568L,
+ 0x3833213201234568L, 0x3784314301234568L, 0x36d5415401234568L,
+ 0x3626516501234568L, 0x3577617601234568L, 0x34c8718701234568L,
+ 0x3419819801234568L, 0x337049048091a2b4L, 0x32c101100091a2b4L,
+ 0x321189188091a2b4L, 0x316211210091a2b4L, 0x30b299298091a2b4L,
+ 0x300321320091a2b4L, 0x2f53a93a8091a2b4L, 0x2ea431430091a2b4L,
+ 0x2df4b94b8091a2b4L, 0x2d4841840091a2b4L, 0x2c98c98c8091a2b4L,
+ 0x2be981980091a2b4L, 0x2b3a09a08091a2b4L, 0x2a8a91a90091a2b4L,
+ 0x29db19b18091a2b4L, 0x292ba1ba0091a2b4L, 0x287c29c28091a2b4L,
+ 0x27ccb1cb0091a2b4L, 0x27201d01c048d15aL, 0x267061060048d15aL,
+ 0x25c0a50a4048d15aL, 0x251101100048d15aL, 0x246145144048d15aL,
+ 0x23b189188048d15aL, 0x2301cd1cc048d15aL, 0x225211210048d15aL,
+ 0x21a255254048d15aL, 0x20f419418048d15aL, 0x20445d45c048d15aL,
+ 0x1f94a14a0048d15aL, 0x1ee4e54e4048d15aL, 0x1e3541540048d15aL,
+ 0x1d8585584048d15aL, 0x1cd5c95c8048d15aL, 0x1c260d60c048d15aL,
+ 0x1b7651650048d15aL, 0x1ac815814048d15aL, 0x1a1859858048d15aL,
+ 0x19689d89c048d15aL, 0x18b8e18e0048d15aL, 0x180925924048d15aL,
+ 0x175981980048d15aL, 0x16a9c59c4048d15aL, 0x15fa09a08048d15aL,
+ 0x154a4da4c048d15aL, 0x149c11c10048d15aL, 0x13ec55c54048d15aL,
+ 0x133c99c98048d15aL, 0x128cddcdc048d15aL, 0x11dd21d20048d15aL,
+ 0x112d65d64048d15aL, 0x107dc1dc0048d15aL, 0xfce05e04048d15aL,
+ 0xf1e49e48048d15aL, 0xe700700602468adL, 0xdc02902802468adL,
+ 0xd104b04a02468adL, 0xc606d06c02468adL, 0xbb08f08e02468adL,
+ 0xb00b10b002468adL, 0xa50d30d202468adL, 0x9a10110002468adL,
+ 0x8f12312202468adL, 0x8420520402468adL, 0x7922722602468adL,
+ 0x6e24924802468adL, 0x6326b26a02468adL, 0x5828d28c02468adL,
+ 0x4d2af2ae02468adL, 0x422d12d002468adL, 0x372f32f202468adL,
+ 0x2c32132002468adL, 0x220011001012345L, 0x170121012012345L,
+ 0xc0231023012345L, 0x10341034012345L, 0x208a208a024L,
+ 0x41584158L, 0x83388L, 0x108L,
+ 0x0L, 0x0L, 0x0L,
+ 0x0L, 0x0L, 0x0L,
+ 0x0L, 0x0L, 0x0L,
+ 0x0L, 0x0L, 0x0L,
+ 0x0L, 0x0L };
+
+ for (int i = 0; i < expecteds.length; i++) {
+ int part = i * 11;
+ String inputString = "0x" + part + "." + part + "0123456789abcdefp-" + part;
+
+ double actual = Double.parseDouble(inputString);
+ double expected = Double.longBitsToDouble(expecteds[i]);
+
+ String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+ String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+ String errorMsg = i + "th input string is:<" + inputString
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0D);
+ }
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_MaxNormalBoundary() {
+ long[] expecteds = {
+ 0x7fefffffffffffffL, 0x7fefffffffffffffL, 0x7fefffffffffffffL,
+ 0x7fefffffffffffffL, 0x7fefffffffffffffL, 0x7fefffffffffffffL,
+ 0x7fefffffffffffffL, 0x7ff0000000000000L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+ 0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+
+ 0xffefffffffffffffL, 0xffefffffffffffffL, 0xffefffffffffffffL,
+ 0xffefffffffffffffL, 0xffefffffffffffffL, 0xffefffffffffffffL,
+ 0xffefffffffffffffL, 0xfff0000000000000L, 0xfff0000000000000L,
+ 0xfff0000000000000L, 0xfff0000000000000L, 0xfff0000000000000L,
+ 0xfff0000000000000L, 0xfff0000000000000L, 0xfff0000000000000L };
+
+ String[] inputs = {
+ "0x1.fffffffffffffp1023",
+ "0x1.fffffffffffff000000000000000000000000001p1023",
+ "0x1.fffffffffffff1p1023",
+ "0x1.fffffffffffff100000000000000000000000001p1023",
+ "0x1.fffffffffffff1fffffffffffffffffffffffffffffffffffffffffffffp1023",
+ "0x1.fffffffffffff7p1023",
+ "0x1.fffffffffffff700000000000000000000000001p1023",
+ "0x1.fffffffffffff8p1023",
+ "0x1.fffffffffffff800000000000000000000000001p1023",
+ "0x1.fffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffp1023",
+ "0x1.fffffffffffff9p1023",
+ "0x1.fffffffffffff900000000000000000000000001p1023",
+ "0x1.ffffffffffffffp1023",
+ "0x1.ffffffffffffff00000000000000000000000001p1023",
+ "0x1.fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp1023",
+
+ "-0x1.fffffffffffffp1023",
+ "-0x1.fffffffffffff000000000000000000000000001p1023",
+ "-0x1.fffffffffffff1p1023",
+ "-0x1.fffffffffffff100000000000000000000000001p1023",
+ "-0x1.fffffffffffff1fffffffffffffffffffffffffffffffffffffffffffffp1023",
+ "-0x1.fffffffffffff7p1023",
+ "-0x1.fffffffffffff700000000000000000000000001p1023",
+ "-0x1.fffffffffffff8p1023",
+ "-0x1.fffffffffffff800000000000000000000000001p1023",
+ "-0x1.fffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffp1023",
+ "-0x1.fffffffffffff9p1023",
+ "-0x1.fffffffffffff900000000000000000000000001p1023",
+ "-0x1.ffffffffffffffp1023",
+ "-0x1.ffffffffffffff00000000000000000000000001p1023",
+ "-0x1.fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp1023" };
+
+ for (int i = 0; i < inputs.length; i++) {
+ double actual = Double.parseDouble(inputs[i]);
+ double expected = Double.longBitsToDouble(expecteds[i]);
+
+ String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+ String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0D);
+ }
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_MinNormalBoundary() {
+ long[] expecteds = {
+ 0x10000000000000L, 0x10000000000000L, 0x10000000000000L,
+ 0x10000000000000L, 0x10000000000000L, 0x10000000000000L,
+ 0x10000000000000L, 0x10000000000000L, 0x10000000000001L,
+ 0x10000000000001L, 0x10000000000001L, 0x10000000000001L,
+ 0x10000000000001L, 0x10000000000001L, 0x10000000000001L,
+
+ 0x8010000000000000L, 0x8010000000000000L, 0x8010000000000000L,
+ 0x8010000000000000L, 0x8010000000000000L, 0x8010000000000000L,
+ 0x8010000000000000L, 0x8010000000000000L, 0x8010000000000001L,
+ 0x8010000000000001L, 0x8010000000000001L, 0x8010000000000001L,
+ 0x8010000000000001L, 0x8010000000000001L, 0x8010000000000001L };
+
+ String[] inputs = {
+ "0x1.0p-1022",
+ "0x1.00000000000001p-1022",
+ "0x1.000000000000010000000000000000001p-1022",
+ "0x1.00000000000001fffffffffffffffffffffffffffffffffp-1022",
+ "0x1.00000000000007p-1022",
+ "0x1.000000000000070000000000000000001p-1022",
+ "0x1.00000000000007fffffffffffffffffffffffffffffffffp-1022",
+ "0x1.00000000000008p-1022",
+ "0x1.000000000000080000000000000000001p-1022",
+ "0x1.00000000000008fffffffffffffffffffffffffffffffffp-1022",
+ "0x1.00000000000009p-1022",
+ "0x1.000000000000090000000000000000001p-1022",
+ "0x1.00000000000009fffffffffffffffffffffffffffffffffp-1022",
+ "0x1.0000000000000fp-1022",
+ "0x1.0000000000000ffffffffffffffffffffffffffffffffffp-1022",
+
+ "-0x1.0p-1022",
+ "-0x1.00000000000001p-1022",
+ "-0x1.000000000000010000000000000000001p-1022",
+ "-0x1.00000000000001fffffffffffffffffffffffffffffffffp-1022",
+ "-0x1.00000000000007p-1022",
+ "-0x1.000000000000070000000000000000001p-1022",
+ "-0x1.00000000000007fffffffffffffffffffffffffffffffffp-1022",
+ "-0x1.00000000000008p-1022",
+ "-0x1.000000000000080000000000000000001p-1022",
+ "-0x1.00000000000008fffffffffffffffffffffffffffffffffp-1022",
+ "-0x1.00000000000009p-1022",
+ "-0x1.000000000000090000000000000000001p-1022",
+ "-0x1.00000000000009fffffffffffffffffffffffffffffffffp-1022",
+ "-0x1.0000000000000fp-1022",
+ "-0x1.0000000000000ffffffffffffffffffffffffffffffffffp-1022" };
+
+ for (int i = 0; i < inputs.length; i++) {
+ double actual = Double.parseDouble(inputs[i]);
+ double expected = Double.longBitsToDouble(expecteds[i]);
+
+ String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+ String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0D);
+ }
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_MaxSubNormalBoundary() {
+ long[] expecteds = {
+ 0xfffffffffffffL, 0xfffffffffffffL, 0xfffffffffffffL,
+ 0xfffffffffffffL, 0xfffffffffffffL, 0xfffffffffffffL,
+ 0xfffffffffffffL, 0x10000000000000L, 0x10000000000000L,
+ 0x10000000000000L, 0x10000000000000L, 0x10000000000000L,
+ 0x10000000000000L, 0x10000000000000L, 0x10000000000000L,
+
+ 0x800fffffffffffffL, 0x800fffffffffffffL, 0x800fffffffffffffL,
+ 0x800fffffffffffffL, 0x800fffffffffffffL, 0x800fffffffffffffL,
+ 0x800fffffffffffffL, 0x8010000000000000L, 0x8010000000000000L,
+ 0x8010000000000000L, 0x8010000000000000L, 0x8010000000000000L,
+ 0x8010000000000000L, 0x8010000000000000L, 0x8010000000000000L };
+
+ String[] inputs = {
+ "0x0.fffffffffffffp-1022",
+ "0x0.fffffffffffff00000000000000000000000000000000001p-1022",
+ "0x0.fffffffffffff1p-1022",
+ "0x0.fffffffffffff10000000000000000000000000000000001p-1022",
+ "0x0.fffffffffffff1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+ "0x0.fffffffffffff7p-1022",
+ "0x0.fffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+ "0x0.fffffffffffff8p-1022",
+ "0x0.fffffffffffff80000000000000000000000000000000001p-1022",
+ "0x0.fffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+ "0x0.fffffffffffff9p-1022",
+ "0x0.fffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+ "0x0.ffffffffffffffp-1022",
+ "0x0.ffffffffffffff0000000000000000000000000000000001p-1022",
+ "0x0.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+
+ "-0x0.fffffffffffffp-1022",
+ "-0x0.fffffffffffff00000000000000000000000000000000001p-1022",
+ "-0x0.fffffffffffff1p-1022",
+ "-0x0.fffffffffffff10000000000000000000000000000000001p-1022",
+ "-0x0.fffffffffffff1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.fffffffffffff7p-1022",
+ "-0x0.fffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.fffffffffffff8p-1022",
+ "-0x0.fffffffffffff80000000000000000000000000000000001p-1022",
+ "-0x0.fffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.fffffffffffff9p-1022",
+ "-0x0.fffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.ffffffffffffffp-1022",
+ "-0x0.ffffffffffffff0000000000000000000000000000000001p-1022",
+ "-0x0.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022" };
+
+ for (int i = 0; i < inputs.length; i++) {
+ double actual = Double.parseDouble(inputs[i]);
+ double expected = Double.longBitsToDouble(expecteds[i]);
+
+ String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+ String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0D);
+ }
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_MinSubNormalBoundary() {
+ long[] expecteds = {
+ 0x1L, 0x1L, 0x2L,
+ 0x1L, 0x1L, 0x1L,
+ 0x2L, 0x2L, 0x2L,
+ 0x2L, 0x2L, 0x2L,
+ 0x2L, 0x2L, 0x2L,
+
+ 0x8000000000000001L, 0x8000000000000001L, 0x8000000000000002L,
+ 0x8000000000000001L, 0x8000000000000001L, 0x8000000000000001L,
+ 0x8000000000000002L, 0x8000000000000002L, 0x8000000000000002L,
+ 0x8000000000000002L, 0x8000000000000002L, 0x8000000000000002L,
+ 0x8000000000000002L, 0x8000000000000002L, 0x8000000000000002L };
+
+ String[] inputs = {
+ "0x0.0000000000001p-1022",
+ "0x0.00000000000010000000000000000001p-1022",
+ "0x0.0000000000001fffffffffffffffffffffffffffffffffp-1022",
+ "0x0.00000000000017p-1022",
+ "0x0.000000000000170000000000000000001p-1022",
+ "0x0.00000000000017fffffffffffffffffffffffffffffffffp-1022",
+ "0x0.00000000000018p-1022",
+ "0x0.000000000000180000000000000000001p-1022",
+ "0x0.00000000000018fffffffffffffffffffffffffffffffffp-1022",
+ "0x0.00000000000019p-1022",
+ "0x0.000000000000190000000000000000001p-1022",
+ "0x0.00000000000019fffffffffffffffffffffffffffffffffp-1022",
+ "0x0.0000000000001fp-1022",
+ "0x0.0000000000001f0000000000000000001p-1022",
+ "0x0.0000000000001ffffffffffffffffffffffffffffffffffp-1022",
+
+ "-0x0.0000000000001p-1022",
+ "-0x0.00000000000010000000000000000001p-1022",
+ "-0x0.0000000000001fffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.00000000000017p-1022",
+ "-0x0.000000000000170000000000000000001p-1022",
+ "-0x0.00000000000017fffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.00000000000018p-1022",
+ "-0x0.000000000000180000000000000000001p-1022",
+ "-0x0.00000000000018fffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.00000000000019p-1022",
+ "-0x0.000000000000190000000000000000001p-1022",
+ "-0x0.00000000000019fffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.0000000000001fp-1022",
+ "-0x0.0000000000001f0000000000000000001p-1022",
+ "-0x0.0000000000001ffffffffffffffffffffffffffffffffffp-1022" };
+
+ for (int i = 0; i < inputs.length; i++) {
+ double actual = Double.parseDouble(inputs[i]);
+ double expected = Double.longBitsToDouble(expecteds[i]);
+
+ String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+ String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0D);
+ }
+ }
+
+ /**
+ * java.lang.Double#parseDouble(java.lang.String)
+ */
+ public void test_parseDouble_LString_ZeroBoundary() {
+ long[] expecteds = {
+ 0x0L, 0x0L, 0x0L,
+ 0x1L, 0x1L, 0x1L,
+ 0x1L, 0x1L, 0x1L,
+ 0x8000000000000000L, 0x8000000000000000L, 0x8000000000000000L,
+ 0x8000000000000001L, 0x8000000000000001L, 0x8000000000000001L,
+ 0x8000000000000001L, 0x8000000000000001L, 0x8000000000000001L };
+
+ String[] inputs = {
+ "0x0.00000000000004p-1022",
+ "0x0.00000000000007ffffffffffffffffffffffp-1022",
+ "0x0.00000000000008p-1022",
+ "0x0.000000000000080000000000000000001p-1022",
+ "0x0.00000000000008fffffffffffffffffffffffffffffffp-1022",
+ "0x0.00000000000009p-1022",
+ "0x0.000000000000090000000000000000001p-1022",
+ "0x0.00000000000009fffffffffffffffffffffffffffffffffp-1022",
+ "0x0.0000000000000fffffffffffffffffffffffffffffffffffp-1022",
+
+ "-0x0.00000000000004p-1022",
+ "-0x0.00000000000007ffffffffffffffffffffffp-1022",
+ "-0x0.00000000000008p-1022",
+ "-0x0.000000000000080000000000000000001p-1022",
+ "-0x0.00000000000008fffffffffffffffffffffffffffffffp-1022",
+ "-0x0.00000000000009p-1022",
+ "-0x0.000000000000090000000000000000001p-1022",
+ "-0x0.00000000000009fffffffffffffffffffffffffffffffffp-1022",
+ "-0x0.0000000000000fffffffffffffffffffffffffffffffffffp-1022" };
+
+ for (int i = 0; i < inputs.length; i++) {
+ double actual = Double.parseDouble(inputs[i]);
+ double expected = Double.longBitsToDouble(expecteds[i]);
+
+ String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+ String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0D);
+ }
+ }
+
+ /**
+ * java.lang.Double#shortValue()
+ */
+ public void test_shortValue() {
+ // Test for method short java.lang.Double.shortValue()
+ Double d = new Double(1923311.47712);
+ assertEquals("Returned incorrect short value", 22767, d.shortValue());
+ }
+
+ /**
+ * java.lang.Double#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.lang.Double.toString()
+ test_toString(1.7976931348623157E308, "1.7976931348623157E308");
+ test_toString(5.0E-4, "5.0E-4");
+ }
+
+ /**
+ * java.lang.Double#toString(double)
+ */
+ public void test_toStringD() {
+ // Test for method java.lang.String java.lang.Double.toString(double)
+ test_toString(1.7976931348623157E308, "1.7976931348623157E308");
+ test_toString(1.0 / 0.0, "Infinity");
+ test_toString(0.0 / 0.0, "NaN");
+ test_toString(-1.0 / 0.0, "-Infinity");
+
+ double d;
+ d = Double.longBitsToDouble(0x470fffffffffffffL);
+ test_toString(d, "2.0769187434139308E34");
+ d = Double.longBitsToDouble(0x4710000000000000L);
+ test_toString(d, "2.076918743413931E34");
+
+ d = Double.longBitsToDouble(0x470000000000000aL);
+ test_toString(d, "1.0384593717069678E34");
+ d = Double.longBitsToDouble(0x470000000000000bL);
+ test_toString(d, "1.038459371706968E34");
+
+ d = Double.longBitsToDouble(0x4700000000000017L);
+ test_toString(d, "1.0384593717069708E34");
+ d = Double.longBitsToDouble(0x4700000000000018L);
+ test_toString(d, "1.038459371706971E34");
+
+ d = Double.longBitsToDouble(0x4700000000000024L);
+ test_toString(d, "1.0384593717069738E34");
+ d = Double.longBitsToDouble(0x4700000000000025L);
+ test_toString(d, "1.038459371706974E34");
+
+ d = Double.longBitsToDouble(0x4700000000000031L);
+ test_toString(d, "1.0384593717069768E34");
+ d = Double.longBitsToDouble(0x4700000000000032L);
+ test_toString(d, "1.038459371706977E34");
+
+ d = Double.longBitsToDouble(0x470000000000003eL);
+ test_toString(d, "1.0384593717069798E34");
+ d = Double.longBitsToDouble(0x470000000000003fL);
+ test_toString(d, "1.03845937170698E34");
+
+ d = Double.longBitsToDouble(0x7e00000000000003L);
+ test_toString(d, "8.371160993642719E298");
+ d = Double.longBitsToDouble(0x7e00000000000004L);
+ test_toString(d, "8.37116099364272E298");
+
+ d = Double.longBitsToDouble(0x7e00000000000008L);
+ test_toString(d, "8.371160993642728E298");
+ d = Double.longBitsToDouble(0x7e00000000000009L);
+ test_toString(d, "8.37116099364273E298");
+
+ d = Double.longBitsToDouble(0x7e00000000000013L);
+ test_toString(d, "8.371160993642749E298");
+ d = Double.longBitsToDouble(0x7e00000000000014L);
+ test_toString(d, "8.37116099364275E298");
+
+ d = Double.longBitsToDouble(0x7e00000000000023L);
+ test_toString(d, "8.371160993642779E298");
+ d = Double.longBitsToDouble(0x7e00000000000024L);
+ test_toString(d, "8.37116099364278E298");
+
+ d = Double.longBitsToDouble(0x7e0000000000002eL);
+ test_toString(d, "8.371160993642799E298");
+ d = Double.longBitsToDouble(0x7e0000000000002fL);
+ test_toString(d, "8.3711609936428E298");
+
+ d = Double.longBitsToDouble(0xda00000000000001L);
+ test_toString(d, "-3.3846065602060736E125");
+ d = Double.longBitsToDouble(0xda00000000000002L);
+ test_toString(d, "-3.384606560206074E125");
+
+ d = Double.longBitsToDouble(0xda00000000000005L);
+ test_toString(d, "-3.3846065602060766E125");
+ d = Double.longBitsToDouble(0xda00000000000006L);
+ test_toString(d, "-3.384606560206077E125");
+
+ d = Double.longBitsToDouble(0xda00000000000009L);
+ test_toString(d, "-3.3846065602060796E125");
+ d = Double.longBitsToDouble(0xda0000000000000aL);
+ test_toString(d, "-3.38460656020608E125");
+
+ d = Double.longBitsToDouble(0xda0000000000000dL);
+ test_toString(d, "-3.3846065602060826E125");
+ d = Double.longBitsToDouble(0xda0000000000000eL);
+ test_toString(d, "-3.384606560206083E125");
+ }
+
+ /**
+ * java.lang.Double#valueOf(java.lang.String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ // Test for method java.lang.Double
+ // java.lang.Double.valueOf(java.lang.String)
+ assertTrue("Incorrect double returned", Math.abs(Double.valueOf("999999999999.999")
+ .doubleValue() - 999999999999.999d) < 1);
+
+ try {
+ Double.valueOf(null);
+ fail("Expected Double.valueOf(null) to throw NPE.");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+
+ try {
+ Double.valueOf("");
+ fail("Expected Double.valueOf(\"\") to throw NFE");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ Double pi = Double.valueOf("3.141592654");
+ assertEquals(3.141592654, pi.doubleValue(), 0D);
+
+ Double posZero = Double.valueOf("+0.0");
+ Double negZero = Double.valueOf("-0.0");
+ assertFalse("Doubletest0", posZero.equals(negZero));
+
+ // Tests for double values by name.
+ Double expectedNaN = new Double(Double.NaN);
+
+ Double posNaN = Double.valueOf("NaN");
+ assertTrue("Doubletest1", posNaN.equals(expectedNaN));
+
+ Double posNaNSigned = Double.valueOf("+NaN");
+ assertTrue("Doubletest2", posNaNSigned.equals(expectedNaN));
+
+ Double negNaNSigned = Double.valueOf("-NaN");
+ assertTrue("Doubletest3", negNaNSigned.equals(expectedNaN));
+
+ Double posInfinite = Double.valueOf("Infinity");
+ assertTrue("Doubletest4", posInfinite.equals(new Double(Double.POSITIVE_INFINITY)));
+
+ Double posInfiniteSigned = Double.valueOf("+Infinity");
+ assertTrue("Doubletest5", posInfiniteSigned
+ .equals(new Double(Double.POSITIVE_INFINITY)));
+
+ Double negInfiniteSigned = Double.valueOf("-Infinity");
+ assertTrue("Doubletest6", negInfiniteSigned
+ .equals(new Double(Double.NEGATIVE_INFINITY)));
+ }
+
+ /**
+ * java.lang.Double#compareTo(java.lang.Double)
+ * java.lang.Double#compare(double, double)
+ */
+ public void test_compareToLjava_lang_Double() {
+ // A selection of double values in ascending order.
+ double[] values = new double[] { Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, -2d,
+ -Double.MIN_VALUE, -0d, 0d, Double.MIN_VALUE, 2d, Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY, Double.NaN };
+ for (int i = 0; i < values.length; i++) {
+ double d1 = values[i];
+
+ // Test that each value compares equal to itself; and each object is
+ // equal to another object like itself.
+ assertTrue("Assert 0: compare() should be equal: " + d1,
+ Double.compare(d1, d1) == 0);
+ Double objDouble = new Double(d1);
+ assertTrue("Assert 1: compareTo() should be equal: " + d1, objDouble
+ .compareTo(objDouble) == 0);
+
+ // Test that the Double-defined order is respected
+ for (int j = i + 1; j < values.length; j++) {
+ double d2 = values[j];
+ assertTrue("Assert 2: compare() " + d1 + " should be less " + d2, Double
+ .compare(d1, d2) == -1);
+ assertTrue("Assert 3: compare() " + d2 + " should be greater " + d1, Double
+ .compare(d2, d1) == 1);
+ Double D2 = new Double(d2);
+ assertTrue("Assert 4: compareTo() " + d1 + " should be less " + d2, objDouble
+ .compareTo(D2) == -1);
+ assertTrue("Assert 5: compareTo() " + d2 + " should be greater " + d1, D2
+ .compareTo(objDouble) == 1);
+ }
+ }
+
+ try {
+ new Double(0.0D).compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Double#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ Double d1 = new Double(87654321.12345d);
+ Double d2 = new Double(87654321.12345d);
+ Double d3 = new Double(0.0002f);
+ assertTrue("Assert 0: Equality test failed", d1.equals(d2) && !(d1.equals(d3)));
+
+ assertTrue("Assert 2: NaN should not be == Nan", Double.NaN != Double.NaN);
+ assertTrue("Assert 3: NaN should not be == Nan", new Double(Double.NaN)
+ .equals(new Double(Double.NaN)));
+ assertTrue("Assert 4: -0d should be == 0d", 0d == -0d);
+ assertTrue("Assert 5: -0d should not be equals() 0d", !new Double(0d)
+ .equals(new Double(-0d)));
+
+ Double dmax = new Double(Double.MAX_VALUE);
+ Double dmax1 = new Double(Double.MAX_VALUE);
+
+ assertTrue("Equality test failed", dmax.equals(dmax1) && !(dmax.equals(new Object())));
+ }
+
+ /**
+ * java.lang.Double#toHexString(double)
+ */
+ public void test_toHexStringF() {
+ // the follow values come from the Double Javadoc/Spec
+ assertEquals("0x0.0p0", Double.toHexString(0.0D));
+ assertEquals("-0x0.0p0", Double.toHexString(-0.0D));
+ assertEquals("0x1.0p0", Double.toHexString(1.0D));
+ assertEquals("-0x1.0p0", Double.toHexString(-1.0D));
+ assertEquals("0x1.0p1", Double.toHexString(2.0D));
+ assertEquals("0x1.8p1", Double.toHexString(3.0D));
+ assertEquals("0x1.0p-1", Double.toHexString(0.5D));
+ assertEquals("0x1.0p-2", Double.toHexString(0.25D));
+ assertEquals("0x1.fffffffffffffp1023", Double.toHexString(Double.MAX_VALUE));
+ assertEquals("0x0.0000000000001p-1022", Double.toHexString(Double.MIN_VALUE));
+
+ // test edge cases
+ assertEquals("NaN", Double.toHexString(Double.NaN));
+ assertEquals("-Infinity", Double.toHexString(Double.NEGATIVE_INFINITY));
+ assertEquals("Infinity", Double.toHexString(Double.POSITIVE_INFINITY));
+
+ // test various numbers
+ assertEquals("-0x1.da8p6", Double.toHexString(-118.625D));
+ assertEquals("0x1.2957874cccccdp23", Double.toHexString(9743299.65D));
+ assertEquals("0x1.2957874cccccdp23", Double.toHexString(9743299.65000D));
+ assertEquals("0x1.2957874cccf63p23", Double.toHexString(9743299.650001234D));
+ assertEquals("0x1.700d1061d3333p33", Double.toHexString(12349743299.65000D));
+
+ // test HARMONY-2132
+ assertEquals("0x1.01p10", Double.toHexString(0x1.01p10));
+ }
+
+ /**
+ * java.lang.Double#valueOf(double)
+ */
+ public void test_valueOfD() {
+ assertEquals(new Double(Double.MIN_VALUE), Double.valueOf(Double.MIN_VALUE));
+ assertEquals(new Double(Double.MAX_VALUE), Double.valueOf(Double.MAX_VALUE));
+ assertEquals(new Double(0), Double.valueOf(0));
+
+ int s = -128;
+ while (s < 128) {
+ assertEquals(new Double(s), Double.valueOf(s));
+ assertEquals(new Double(s + 0.1D), Double.valueOf(s + 0.1D));
+ s++;
+ }
+ }
+
+ /**
+ * {@link java.lang.Double#MAX_EXPONENT}
+ * @since 1.6
+ */
+ public void test_MAX_EXPONENT() {
+ assertTrue("Wrong value of java.lang.Double.MAX_EXPONENT",
+ Double.MAX_EXPONENT == 1023);
+ assertTrue("Wrong value of java.lang.Double.MAX_EXPONENT",
+ Double.MAX_EXPONENT == Math.getExponent(Double.MAX_VALUE));
+ }
+
+ /**
+ * {@link java.lang.Double#MIN_EXPONENT}
+ * @since 1.6
+ */
+ public void test_MIN_EXPONENT() {
+ assertTrue("Wrong value of java.lang.Double.MIN_EXPONENT",
+ Double.MIN_EXPONENT == -1022);
+ assertTrue("Wrong value of java.lang.Double.MIN_EXPONENT",
+ Double.MIN_EXPONENT == Math.getExponent(Double.MIN_NORMAL));
+ }
+
+ /**
+ * {@link java.lang.Double#MIN_NORMAL}
+ * @since 1.6
+ */
+ public void test_MIN_NORMAL() {
+ assertTrue("Wrong value of java.lang.Double.MIN_NORMAL",
+ Double.MIN_NORMAL == 0x1.0p-1022);
+ assertTrue("Wrong value of java.lang.Double.MIN_NORMAL",
+ Double.MIN_NORMAL == Double
+ .longBitsToDouble(0x0010000000000000L));
+ assertTrue("Wrong value of java.lang.Double.MIN_NORMAL",
+ Double.MIN_NORMAL == 2.2250738585072014E-308);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/EnumConstantNotPresentExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/EnumConstantNotPresentExceptionTest.java
new file mode 100644
index 0000000..e1d8085
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/EnumConstantNotPresentExceptionTest.java
@@ -0,0 +1,45 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class EnumConstantNotPresentExceptionTest extends TestCase {
+
+ public enum Fixture {
+ ONE, TWO, THREE
+ }
+
+ public void test_ConstructorLjava_lang_ClassLjava_lang_String() {
+ try {
+ new EnumConstantNotPresentException(null, "");
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_enumType() {
+ EnumConstantNotPresentException e = new EnumConstantNotPresentException(Fixture.class, "FOUR");
+ assertEquals(Fixture.class, e.enumType());
+ }
+
+ public void test_constantName() {
+ EnumConstantNotPresentException e = new EnumConstantNotPresentException(Fixture.class, "FOUR");
+ assertEquals("FOUR", e.constantName());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/EnumTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/EnumTest.java
new file mode 100644
index 0000000..3f2754c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/EnumTest.java
@@ -0,0 +1,261 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import tests.util.SerializationTester;
+
+public class EnumTest extends TestCase {
+
+ enum Sample {
+ LARRY, MOE, CURLY
+ }
+
+ Sample larry = Sample.LARRY;
+
+ Sample moe = Sample.MOE;
+
+ enum Empty {
+ }
+
+ enum Bogus {
+ UNUSED
+ }
+
+ enum Color {
+ Red, Green, Blue {};
+ }
+
+ enum MockCloneEnum {
+ ONE;
+
+ public void callClone() throws CloneNotSupportedException {
+ super.clone();
+ }
+ }
+
+ /**
+ * java.lang.Enum#compareTo(java.lang.Enum)
+ */
+ public void test_compareToLjava_lang_Enum() {
+ assertTrue(0 < Sample.MOE.compareTo(Sample.LARRY));
+ assertEquals(0, Sample.MOE.compareTo(Sample.MOE));
+ assertTrue(0 > Sample.MOE.compareTo(Sample.CURLY));
+ try {
+ Sample.MOE.compareTo((Sample) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.Enum#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertFalse(moe.equals("bob"));
+ assertTrue(moe.equals(Sample.MOE));
+ assertFalse(Sample.LARRY.equals(Sample.CURLY));
+ assertTrue(Sample.LARRY.equals(larry));
+ assertFalse(Sample.CURLY.equals(null));
+ }
+
+ /**
+ * java.lang.Enum#getDeclaringClass()
+ */
+ public void test_getDeclaringClass() {
+ assertEquals(Sample.class, moe.getDeclaringClass());
+ }
+
+ /**
+ * java.lang.Enum#hashCode()
+ */
+ public void test_hashCode() {
+ assertEquals(moe.hashCode(), moe.hashCode());
+ }
+
+ /**
+ * java.lang.Enum#name()
+ */
+ public void test_name() {
+ assertEquals("MOE", moe.name());
+ }
+
+ /**
+ * java.lang.Enum#ordinal()
+ */
+ public void test_ordinal() {
+ assertEquals(0, larry.ordinal());
+ assertEquals(1, moe.ordinal());
+ assertEquals(2, Sample.CURLY.ordinal());
+ }
+
+ /**
+ * java.lang.Enum#toString()
+ */
+ public void test_toString() {
+ assertTrue(moe.toString().equals("MOE"));
+ }
+
+ /**
+ * java.lang.Enum#valueOf(Class, String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ assertSame(Sample.CURLY, Sample.valueOf("CURLY"));
+ assertSame(Sample.LARRY, Sample.valueOf("LARRY"));
+ assertSame(moe, Sample.valueOf("MOE"));
+ try {
+ Sample.valueOf("non-existant");
+ fail("Expected an exception");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ Sample.valueOf(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // May be caused by some compilers' code
+ } catch (IllegalArgumentException e) {
+ // other compilers will throw this
+ }
+
+
+ Sample s = Enum.valueOf(Sample.class, "CURLY");
+ assertSame(s, Sample.CURLY);
+ s = Enum.valueOf(Sample.class, "LARRY");
+ assertSame(larry, s);
+ s = Enum.valueOf(Sample.class, "MOE");
+ assertSame(s, moe);
+ try {
+ Enum.valueOf(Bogus.class, "MOE");
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ Enum.valueOf((Class<Sample>) null, "a string");
+ fail("Expected an exception");
+ } catch (NullPointerException e) {
+ // May be caused by some compilers' code
+ } catch (IllegalArgumentException e) {
+ // other compilers will throw this
+ }
+ try {
+ Enum.valueOf(Sample.class, null);
+ fail("Expected an exception");
+ } catch (NullPointerException e) {
+ // May be caused by some compilers' code
+ } catch (IllegalArgumentException e) {
+ // other compilers will throw this
+ }
+ try {
+ Enum.valueOf((Class<Sample>) null, (String) null);
+ fail("Expected an exception");
+ } catch (NullPointerException e) {
+ // May be caused by some compilers' code
+ } catch (IllegalArgumentException e) {
+ // other compilers will throw this
+ }
+ }
+
+ /**
+ * java.lang.Enum#values
+ */
+ public void test_values() {
+ Sample[] myValues = Sample.values();
+ assertEquals(3, myValues.length);
+
+ assertEquals(Sample.LARRY, myValues[0]);
+ assertEquals(Sample.MOE, myValues[1]);
+ assertEquals(Sample.CURLY, myValues[2]);
+
+ assertEquals(0, Empty.values().length);
+ }
+
+ /**
+ * java.lang.Enum#clone()
+ */
+ public void test_clone() {
+ try {
+ MockCloneEnum.ONE.callClone();
+ fail("Should throw CloneNotSupprotedException");
+ } catch (CloneNotSupportedException e1) {
+ // expected
+ }
+
+ }
+
+ public void test_compatibilitySerialization_inClass_Complex_Harmony() throws Exception {
+ // TODO migrate to the new testing framework
+ assertTrue(SerializationTester.assertCompabilityEquals(new MockEnum2(),
+ "serialization/org/apache/harmony/tests/java/lang/EnumTest.harmony.ser"));
+ }
+
+ /**
+ * serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ // test a map class that has enums.
+ // regression test for Harmony-1163
+ HashMap<Color, Integer> enumColorMap = new HashMap<Color, Integer>();
+ enumColorMap.put(Color.Red, 1);
+ enumColorMap.put(Color.Blue, 3);
+
+ Object[] testCases = { enumColorMap, Sample.CURLY };
+
+ SerializationTest.verifySelf(testCases);
+
+ // test a class that has enums as its fields.
+ MockEnum mock = new MockEnum();
+ MockEnum test = (MockEnum) SerializationTest.copySerializable(mock);
+ assertEquals(mock.i, test.i);
+ assertEquals(mock.str, test.str);
+ assertEquals(mock.samEnum, test.samEnum);
+
+ // test a class that has enums and a string of same name as its fields.
+ MockEnum2 mock2 = new MockEnum2();
+ MockEnum2 test2 = (MockEnum2) SerializationTest.copySerializable(mock2);
+ assertEquals(mock2.i, test2.i);
+ assertEquals(mock2.str, test2.str);
+ assertEquals(mock2.samEnum, test2.samEnum);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ // regression test for Harmony-1163
+ HashMap<Color, Integer> enumColorMap = new HashMap<Color, Integer>();
+ enumColorMap.put(Color.Red, 1);
+ enumColorMap.put(Color.Blue, 3);
+
+ Object[] testCases = { Sample.CURLY, new MockEnum(),
+ // test a class that has enums and a string of same name as its fields.
+ new MockEnum2(),
+ // test a map class that has enums.
+ enumColorMap, };
+
+ SerializationTest.verifyGolden(this, testCases);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ErrorTest.java
new file mode 100644
index 0000000..f11cc64
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ErrorTest extends TestCase {
+
+ /**
+ * java.lang.Error#Error()
+ */
+ public void test_Constructor() {
+ Error e = new Error();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.Error#Error(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ Error e = new Error("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ExceptionInInitializerErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ExceptionInInitializerErrorTest.java
new file mode 100644
index 0000000..b2b034e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ExceptionInInitializerErrorTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+public class ExceptionInInitializerErrorTest extends junit.framework.TestCase {
+
+ /**
+ * java.lang.ExceptionInInitializerError#ExceptionInInitializerError()
+ */
+ public void test_Constructor() {
+ ExceptionInInitializerError e = new ExceptionInInitializerError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.ExceptionInInitializerError#ExceptionInInitializerError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ ExceptionInInitializerError e = new ExceptionInInitializerError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.ExceptionInInitializerExceptionInInitializerError#ExceptionInInitializerError(java.lang.Throwable)
+ */
+ public void test_ConstructorLjava_lang_Throwable() {
+ NullPointerException npe = new NullPointerException("fixture");
+ ExceptionInInitializerError e = new ExceptionInInitializerError(npe);
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertSame(npe, e.getException());
+ assertSame(npe, e.getCause());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ExceptionTest.java
new file mode 100644
index 0000000..1a0f1e4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ExceptionTest extends TestCase {
+
+ /**
+ * java.lang.Exception#Exception()
+ */
+ public void test_Constructor() {
+ Exception e = new Exception();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.Exception#Exception(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ Exception e = new Exception("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/FloatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/FloatTest.java
new file mode 100644
index 0000000..db61f1c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/FloatTest.java
@@ -0,0 +1,1077 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class FloatTest extends TestCase {
+
+ private static final int rawBitsFor3_4eN38To38[] = { 0x1394470, 0x2e7958c, 0x490bd77, 0x634ecd5,
+ 0x7e2280b, 0x98d5907, 0xb30af48, 0xcdcdb1a, 0xe8a08f0, 0x102c8b2d, 0x11d7adf8,
+ 0x1386ccbb, 0x15287fe9, 0x16d29fe4, 0x1883a3ee, 0x1a248cea, 0x1bcdb025, 0x1d808e17,
+ 0x1f20b19d, 0x20c8de04, 0x227b1585, 0x241ced73, 0x25c428d0, 0x27753303, 0x29193fe2,
+ 0x2abf8fdb, 0x2c6f73d1, 0x2e15a863, 0x2fbb127c, 0x3169d71a, 0x33122671, 0x34b6b00d,
+ 0x36645c10, 0x380eb98a, 0x39b267ec, 0x3b5f01e8, 0x3d0b6131, 0x3eae397d, 0x4059c7dc,
+ 0x42081cea, 0x43aa2424, 0x4554ad2d, 0x4704ec3c, 0x48a6274b, 0x4a4fb11e, 0x4c01ceb3,
+ 0x4da2425f, 0x4f4ad2f7, 0x50fd87b5, 0x529e74d1, 0x54461205, 0x55f79687, 0x579abe14,
+ 0x59416d99, 0x5af1c900, 0x5c971da0, 0x5e3ce508, 0x5fec1e4a, 0x619392ee, 0x633877a9,
+ 0x64e69594, 0x66901d7c, 0x683424dc, 0x69e12e12, 0x6b8cbccb, 0x6d2febfe, 0x6edbe6fe,
+ 0x7089705f, 0x722bcc76, 0x73d6bf94, 0x758637bc, 0x7727c5ac, 0x78d1b717, 0x7a83126e,
+ 0x7c23d70a, 0x7dcccccc, 0x7f7fffff };
+
+ private static final String expectedStringFor3_4eN38To38[] = { "3.4028235E-38", "3.4028235E-37",
+ "3.4028233E-36", "3.4028234E-35", "3.4028236E-34", "3.4028236E-33",
+ "3.4028234E-32", "3.4028234E-31", "3.4028233E-30", "3.4028236E-29",
+ "3.4028235E-28", "3.4028235E-27", "3.4028233E-26", "3.4028235E-25",
+ "3.4028233E-24", "3.4028235E-23", "3.4028236E-22", "3.4028235E-21",
+ "3.4028236E-20", "3.4028236E-19", "3.4028236E-18", "3.4028235E-17",
+ "3.4028236E-16", "3.4028234E-15", "3.4028234E-14", "3.4028235E-13",
+ "3.4028234E-12", "3.4028235E-11", "3.4028236E-10", "3.4028234E-9", "3.4028236E-8",
+ "3.4028236E-7", "3.4028235E-6", "3.4028235E-5", "3.4028233E-4", "0.0034028236",
+ "0.034028236", "0.34028235", "3.4028234", "34.028236", "340.28235", "3402.8235",
+ "34028.234", "340282.34", "3402823.5", "3.4028236E7", "3.40282336E8",
+ "3.40282342E9", "3.40282348E10", "3.40282343E11", "3.40282337E12", "3.40282353E13",
+ "3.4028234E14", "3.4028234E15", "3.40282356E16", "3.40282356E17", "3.40282356E18",
+ "3.4028236E19", "3.4028235E20", "3.4028233E21", "3.4028235E22", "3.4028233E23",
+ "3.4028236E24", "3.4028234E25", "3.4028233E26", "3.4028234E27", "3.4028235E28",
+ "3.4028236E29", "3.4028233E30", "3.4028235E31", "3.4028233E32", "3.4028236E33",
+ "3.4028236E34", "3.4028234E35", "3.4028236E36", "3.4028235E37", "3.4028235E38" };
+
+ private static final int rawBitsFor1_17eN38To38[] = { 0x80800000, 0x82200000, 0x83c80000,
+ 0x857a0000, 0x871c4000, 0x88c35000, 0x8a742400, 0x8c189680, 0x8dbebc20, 0x8f6e6b28,
+ 0x911502f9, 0x92ba43b7, 0x9468d4a5, 0x961184e7, 0x97b5e621, 0x99635fa9, 0x9b0e1bca,
+ 0x9cb1a2bc, 0x9e5e0b6b, 0xa00ac723, 0xa1ad78ec, 0xa358d727, 0xa5078678, 0xa6a96816,
+ 0xa853c21c, 0xaa045951, 0xaba56fa6, 0xad4ecb8f, 0xaf013f39, 0xb0a18f08, 0xb249f2ca,
+ 0xb3fc6f7c, 0xb59dc5ae, 0xb7453719, 0xb8f684df, 0xba9a130c, 0xbc4097ce, 0xbdf0bdc2,
+ 0xbf967699, 0xc13c1440, 0xc2eb1950, 0xc492efd2, 0xc637abc6, 0xc7e596b8, 0xc98f7e33,
+ 0xcb335dc0, 0xcce0352f, 0xce8c213e, 0xd02f298d, 0xd1daf3f0, 0xd388d876, 0xd52b0e94,
+ 0xd6d5d239, 0xd885a363, 0xda270c3c, 0xdbd0cf4b, 0xdd82818f, 0xdf2321f3, 0xe0cbea70,
+ 0xe27ee50b, 0xe41f4f27, 0xe5c722f1, 0xe778ebad, 0xe91b934c, 0xeac2781f, 0xec731627,
+ 0xee17edd8, 0xefbde94f, 0xf16d63a2, 0xf3145e45, 0xf4b975d7, 0xf667d34c, 0xf810e410,
+ 0xf9b51d14, 0xfb626459, 0xfd0d7eb7, 0xfeb0de65 };
+
+ private static final String expectedStringFor1_17eN38To38[] = { "-1.17549435E-38",
+ "-1.1754944E-37", "-1.17549435E-36", "-1.17549435E-35", "-1.1754944E-34",
+ "-1.17549435E-33", "-1.17549435E-32", "-1.1754944E-31", "-1.17549435E-30",
+ "-1.17549435E-29", "-1.1754944E-28", "-1.1754943E-27", "-1.17549435E-26",
+ "-1.1754943E-25", "-1.1754944E-24", "-1.1754943E-23", "-1.1754944E-22",
+ "-1.1754943E-21", "-1.1754943E-20", "-1.1754943E-19", "-1.1754944E-18",
+ "-1.1754944E-17", "-1.1754943E-16", "-1.1754943E-15", "-1.1754944E-14",
+ "-1.1754943E-13", "-1.1754944E-12", "-1.1754943E-11", "-1.1754943E-10",
+ "-1.1754944E-9", "-1.1754944E-8", "-1.1754943E-7", "-1.1754944E-6",
+ "-1.1754943E-5", "-1.1754943E-4", "-0.0011754944", "-0.011754943", "-0.117549434",
+ "-1.1754943", "-11.754944", "-117.54944", "-1175.4944", "-11754.943", "-117549.44",
+ "-1175494.4", "-1.1754944E7", "-1.17549432E8", "-1.1754944E9", "-1.17549435E10",
+ "-1.17549433E11", "-1.17549433E12", "-1.17549438E13", "-1.17549438E14",
+ "-1.1754943E15", "-1.17549432E16", "-1.17549432E17", "-1.17549434E18",
+ "-1.1754944E19", "-1.1754944E20", "-1.1754943E21", "-1.1754943E22",
+ "-1.1754944E23", "-1.17549434E24", "-1.1754943E25", "-1.1754943E26",
+ "-1.17549434E27", "-1.1754943E28", "-1.1754944E29", "-1.1754943E30",
+ "-1.1754943E31", "-1.1754944E32", "-1.1754943E33", "-1.1754944E34",
+ "-1.1754944E35", "-1.1754944E36", "-1.1754943E37", "-1.1754943E38" };
+
+ private void doTestCompareRawBits(String originalFloatString, int expectedRawBits,
+ String expectedString) {
+ int rawBits;
+ float result = Float.parseFloat(originalFloatString);
+ rawBits = Float.floatToIntBits(result);
+ assertEquals("Original float(" + originalFloatString + ") Converted float(" + result
+ + ") Expecting:" + Integer.toHexString(expectedRawBits) + " Got: "
+ + Integer.toHexString(rawBits), expectedRawBits, rawBits);
+ }
+
+ /**
+ * java.lang.Float#Float(float)
+ */
+ public void test_ConstructorF() {
+ // Test for method java.lang.Float(float)
+
+ Float f = new Float(900.89f);
+ assertTrue("Created incorrect float", f.floatValue() == 900.89f);
+ }
+
+ /**
+ * java.lang.Float#Float(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.lang.Float(java.lang.String)
+
+ Float f = new Float("900.89");
+ assertTrue("Created incorrect Float", f.floatValue() == 900.89f);
+ }
+
+ /**
+ * java.lang.Float#byteValue()
+ */
+ public void test_byteValue() {
+ // Test for method byte java.lang.Float.byteValue()
+ Float f = new Float(0.46874f);
+ Float f2 = new Float(90.8f);
+ assertTrue("Returned incorrect byte value", f.byteValue() == 0 && f2.byteValue() == 90);
+ }
+
+ /**
+ * java.lang.Float#compareTo(java.lang.Float)
+ * java.lang.Float#compare(float, float)
+ */
+ public void test_compare() {
+ float[] values = new float[] { Float.NEGATIVE_INFINITY, -Float.MAX_VALUE, -2f,
+ -Float.MIN_VALUE, -0f, 0f, Float.MIN_VALUE, 2f, Float.MAX_VALUE,
+ Float.POSITIVE_INFINITY, Float.NaN };
+ for (int i = 0; i < values.length; i++) {
+ float f1 = values[i];
+ assertTrue("compare() should be equal: " + f1, Float.compare(f1, f1) == 0);
+ Float F1 = new Float(f1);
+ assertTrue("compareTo() should be equal: " + f1, F1.compareTo(F1) == 0);
+ for (int j = i + 1; j < values.length; j++) {
+ float f2 = values[j];
+ assertTrue("compare() " + f1 + " should be less " + f2,
+ Float.compare(f1, f2) == -1);
+ assertTrue("compare() " + f2 + " should be greater " + f1, Float
+ .compare(f2, f1) == 1);
+ Float F2 = new Float(f2);
+ assertTrue("compareTo() " + f1 + " should be less " + f2,
+ F1.compareTo(F2) == -1);
+ assertTrue("compareTo() " + f2 + " should be greater " + f1,
+ F2.compareTo(F1) == 1);
+ }
+ }
+
+ try {
+ new Float(0.0F).compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Float#doubleValue()
+ */
+ public void test_doubleValue() {
+ // Test for method double java.lang.Float.doubleValue()
+ assertTrue("Incorrect double value returned", Math.abs(new Float(999999.999f)
+ .doubleValue() - 999999.999d) < 1);
+ }
+
+ /**
+ * java.lang.Float#floatToIntBits(float)
+ */
+ public void test_floatToIntBitsF() {
+ float f = 9876.2345f;
+ int bits = Float.floatToIntBits(f);
+ float r = Float.intBitsToFloat(bits);
+ assertTrue("Incorrect intBits returned", f == r);
+ }
+
+ /**
+ * java.lang.Float#floatToRawIntBits(float)
+ */
+ public void test_floatToRawIntBitsF() {
+ int i = 0x7fc004d2;
+ float f = Float.intBitsToFloat(i);
+ assertTrue("Wrong raw bits", Float.floatToRawIntBits(f) == i);
+ }
+
+ /**
+ * java.lang.Float#floatValue()
+ */
+ public void test_floatValue() {
+ // Test for method float java.lang.Float.floatValue()
+ Float f = new Float(87.657f);
+ Float f2 = new Float(-0.876f);
+ assertTrue("Returned incorrect floatValue", f.floatValue() == 87.657f
+ && (f2.floatValue() == -0.876f));
+
+ }
+
+ /**
+ * java.lang.Float#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.lang.Float.hashCode()
+ Float f = new Float(1908.8786f);
+ assertTrue("Returned invalid hash code for 1908.8786f", f.hashCode() == Float
+ .floatToIntBits(1908.8786f));
+
+ f = new Float(-1.112f);
+ assertTrue("Returned invalid hash code for -1.112", f.hashCode() == Float
+ .floatToIntBits(-1.112f));
+
+ f = new Float(0f);
+ assertTrue("Returned invalid hash code for 0", f.hashCode() == Float.floatToIntBits(0f));
+
+ }
+
+ /**
+ * java.lang.Float#intBitsToFloat(int)
+ */
+ public void test_intBitsToFloatI() {
+ float f = 9876.2345f;
+ int bits = Float.floatToIntBits(f);
+ float r = Float.intBitsToFloat(bits);
+ assertEquals("Incorrect intBits returned", f, r, 0F);
+ }
+
+ /**
+ * java.lang.Float#intValue()
+ */
+ public void test_intValue() {
+ // Test for method int java.lang.Float.intValue()
+ Float f = new Float(0.46874f);
+ Float f2 = new Float(90.8f);
+ assertTrue("Returned incorrect int value", f.intValue() == 0 && f2.intValue() == 90);
+ }
+
+ /**
+ * java.lang.Float#isInfinite()
+ */
+ public void test_isInfinite() {
+ // Test for method boolean java.lang.Float.isInfinite()
+ assertTrue("Infinity check failed",
+ (new Float(Float.POSITIVE_INFINITY).isInfinite() && new Float(
+ Float.NEGATIVE_INFINITY).isInfinite())
+ && !(new Float(0.13131414f).isInfinite()));
+ }
+
+ /**
+ * java.lang.Float#isInfinite(float)
+ */
+ public void test_isInfiniteF() {
+ // Test for method boolean java.lang.Float.isInfinite(float)
+
+ assertTrue("Infinity check failed", Float.isInfinite(Float.POSITIVE_INFINITY)
+ && (Float.isInfinite(Float.NEGATIVE_INFINITY)) && !(Float.isInfinite(1.0f)));
+ }
+
+ /**
+ * java.lang.Float#isNaN()
+ */
+ public void test_isNaN() {
+ // Test for method boolean java.lang.Float.isNaN()
+ assertTrue("NAN check failed", new Float(Float.NaN).isNaN()
+ && !(new Float(1.0f).isNaN()));
+ }
+
+ /**
+ * java.lang.Float#isNaN(float)
+ */
+ public void test_isNaNF() {
+ // Test for method boolean java.lang.Float.isNaN(float)
+ assertTrue("NaN check failed", Float.isNaN(Float.NaN) && !(Float.isNaN(12.09f)));
+ }
+
+ /**
+ * java.lang.Float#longValue()
+ */
+ public void test_longValue() {
+ // Test for method long java.lang.Float.longValue()
+ Float f = new Float(0.46874f);
+ Float f2 = new Float(90.8f);
+ assertTrue("Returned incorrect long value", f.longValue() == 0 && f2.longValue() == 90);
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloatLjava_lang_String() {
+ assertEquals("Incorrect float returned, expected zero.", 0.0, Float
+ .parseFloat("7.0064923216240853546186479164495e-46"), 0.0);
+ assertEquals("Incorrect float returned, expected minimum float.", Float.MIN_VALUE,
+ Float.parseFloat("7.0064923216240853546186479164496e-46"), 0.0);
+
+ doTestCompareRawBits(
+ "0.000000000000000000000000000000000000011754942807573642917278829910357665133228589927589904276829631184250030649651730385585324256680905818939208984375",
+ 0x800000, "1.17549435E-38");
+ doTestCompareRawBits(
+ "0.00000000000000000000000000000000000001175494280757364291727882991035766513322858992758990427682963118425003064965173038558532425668090581893920898437499999f",
+ 0x7fffff, "1.1754942E-38");
+
+ /* Test a set of regular floats with exponents from -38 to +38 */
+ for (int i = 38; i > 3; i--) {
+ String testString;
+ testString = "3.4028234663852886e-" + i;
+ doTestCompareRawBits(testString, rawBitsFor3_4eN38To38[38 - i],
+ expectedStringFor3_4eN38To38[38 - i]);
+ }
+ doTestCompareRawBits("3.4028234663852886e-3", rawBitsFor3_4eN38To38[38 - 3],
+ expectedStringFor3_4eN38To38[38 - 3]);
+ doTestCompareRawBits("3.4028234663852886e-2", rawBitsFor3_4eN38To38[38 - 2],
+ expectedStringFor3_4eN38To38[38 - 2]);
+ doTestCompareRawBits("3.4028234663852886e-1", rawBitsFor3_4eN38To38[38 - 1],
+ expectedStringFor3_4eN38To38[38 - 1]);
+ doTestCompareRawBits("3.4028234663852886e-0", rawBitsFor3_4eN38To38[38 - 0],
+ expectedStringFor3_4eN38To38[38 - 0]);
+ doTestCompareRawBits("3.4028234663852886e+1", rawBitsFor3_4eN38To38[38 + 1],
+ expectedStringFor3_4eN38To38[38 + 1]);
+ doTestCompareRawBits("3.4028234663852886e+2", rawBitsFor3_4eN38To38[38 + 2],
+ expectedStringFor3_4eN38To38[38 + 2]);
+ doTestCompareRawBits("3.4028234663852886e+3", rawBitsFor3_4eN38To38[38 + 3],
+ expectedStringFor3_4eN38To38[38 + 3]);
+ doTestCompareRawBits("3.4028234663852886e+4", rawBitsFor3_4eN38To38[38 + 4],
+ expectedStringFor3_4eN38To38[38 + 4]);
+ doTestCompareRawBits("3.4028234663852886e+5", rawBitsFor3_4eN38To38[38 + 5],
+ expectedStringFor3_4eN38To38[38 + 5]);
+ doTestCompareRawBits("3.4028234663852886e+6", rawBitsFor3_4eN38To38[38 + 6],
+ expectedStringFor3_4eN38To38[38 + 6]);
+
+ for (int i = 7; i < 39; i++) {
+ String testString;
+ testString = "3.4028234663852886e+" + i;
+ doTestCompareRawBits(testString, rawBitsFor3_4eN38To38[38 + i],
+ expectedStringFor3_4eN38To38[38 + i]);
+ }
+
+ /* Test another set of regular floats with exponents from -38 to +38 */
+ for (int i = 38; i > 3; i--) {
+ String testString;
+ testString = "-1.1754943508222875e-" + i;
+ doTestCompareRawBits(testString, rawBitsFor1_17eN38To38[38 - i],
+ expectedStringFor1_17eN38To38[38 - i]);
+ }
+ doTestCompareRawBits("-1.1754943508222875e-3", rawBitsFor1_17eN38To38[38 - 3],
+ expectedStringFor1_17eN38To38[38 - 3]);
+ doTestCompareRawBits("-1.1754943508222875e-2", rawBitsFor1_17eN38To38[38 - 2],
+ expectedStringFor1_17eN38To38[38 - 2]);
+ doTestCompareRawBits("-1.1754943508222875e-1", rawBitsFor1_17eN38To38[38 - 1],
+ expectedStringFor1_17eN38To38[38 - 1]);
+ doTestCompareRawBits("-1.1754943508222875e-0", rawBitsFor1_17eN38To38[38 - 0],
+ expectedStringFor1_17eN38To38[38 - 0]);
+ doTestCompareRawBits("-1.1754943508222875e+1", rawBitsFor1_17eN38To38[38 + 1],
+ expectedStringFor1_17eN38To38[38 + 1]);
+ doTestCompareRawBits("-1.1754943508222875e+2", rawBitsFor1_17eN38To38[38 + 2],
+ expectedStringFor1_17eN38To38[38 + 2]);
+ doTestCompareRawBits("-1.1754943508222875e+3", rawBitsFor1_17eN38To38[38 + 3],
+ expectedStringFor1_17eN38To38[38 + 3]);
+ doTestCompareRawBits("-1.1754943508222875e+4", rawBitsFor1_17eN38To38[38 + 4],
+ expectedStringFor1_17eN38To38[38 + 4]);
+ doTestCompareRawBits("-1.1754943508222875e+5", rawBitsFor1_17eN38To38[38 + 5],
+ expectedStringFor1_17eN38To38[38 + 5]);
+ doTestCompareRawBits("-1.1754943508222875e+6", rawBitsFor1_17eN38To38[38 + 6],
+ expectedStringFor1_17eN38To38[38 + 6]);
+
+ for (int i = 7; i < 39; i++) {
+ String testString;
+ testString = "-1.1754943508222875e+" + i;
+ doTestCompareRawBits(testString, rawBitsFor1_17eN38To38[38 + i],
+ expectedStringFor1_17eN38To38[38 + i]);
+ }
+
+ /* Test denormalized floats (floats with exponents <= -38 */
+ doTestCompareRawBits("1.1012984643248170E-45", 1, "1.4E-45");
+ doTestCompareRawBits("-1.1012984643248170E-45", 0x80000001, "-1.4E-45");
+ doTestCompareRawBits("1.0E-45", 1, "1.4E-45");
+ doTestCompareRawBits("-1.0E-45", 0x80000001, "-1.4E-45");
+ doTestCompareRawBits("0.9E-45", 1, "1.4E-45");
+ doTestCompareRawBits("-0.9E-45", 0x80000001, "-1.4E-45");
+ doTestCompareRawBits("4.203895392974451e-45", 3, "4.2E-45");
+ doTestCompareRawBits("-4.203895392974451e-45", 0x80000003, "-4.2E-45");
+ doTestCompareRawBits("0.004E-45", 0, "0.0");
+ doTestCompareRawBits("-0.004E-45", 0x80000000, "-0.0");
+
+ /*
+ * Test for large floats close to and greater than 3.4028235E38 and
+ * -3.4028235E38
+ */
+ doTestCompareRawBits("1.2E+38", 0x7eb48e52, "1.2E38");
+ doTestCompareRawBits("-1.2E+38", 0xfeb48e52, "-1.2E38");
+ doTestCompareRawBits("3.2E+38", 0x7f70bdc2, "3.2E38");
+ doTestCompareRawBits("-3.2E+38", 0xff70bdc2, "-3.2E38");
+ doTestCompareRawBits("3.4E+38", 0x7f7fc99e, "3.4E38");
+ doTestCompareRawBits("-3.4E+38", 0xff7fc99e, "-3.4E38");
+ doTestCompareRawBits("3.4028234663852886E+38", 0x7f7fffff, "3.4028235E38");
+ doTestCompareRawBits("-3.4028234663852886E+38", 0xff7fffff, "-3.4028235E38");
+ doTestCompareRawBits("3.405E+38", 0x7f800000, "Infinity");
+ doTestCompareRawBits("-3.405E+38", 0xff800000, "-Infinity");
+ doTestCompareRawBits("3.41E+38", 0x7f800000, "Infinity");
+ doTestCompareRawBits("-3.41E+38", 0xff800000, "-Infinity");
+ doTestCompareRawBits("3.42E+38", 0x7f800000, "Infinity");
+ doTestCompareRawBits("-3.42E+38", 0xff800000, "-Infinity");
+ doTestCompareRawBits("1.0E+39", 0x7f800000, "Infinity");
+ doTestCompareRawBits("-1.0E+39", 0xff800000, "-Infinity");
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_Unusual() {
+ float actual;
+
+ actual = Float.parseFloat("0x00000000000000000000000000000000000000000.0000000000000000000000000000000000000p0000000000000000000000000000000000");
+ assertEquals("Returned incorrect value", 0.0f, actual, 0.0F);
+
+ actual = Float.parseFloat("+0Xfffff.fffffffffffffffffffffffffffffffp+99F");
+ assertEquals("Returned incorrect value", 6.64614E35f, actual, 0.0F);
+
+ actual = Float.parseFloat("-0X.123456789abcdefp+99f");
+ assertEquals("Returned incorrect value", -4.5072022E28f, actual, 0.0F);
+
+ actual = Float.parseFloat("-0X123456789abcdef.p+1f");
+ assertEquals("Returned incorrect value", -1.63971062E17f, actual, 0.0F);
+
+ actual = Float.parseFloat("-0X000000000000000000000000000001abcdef.0000000000000000000000000001abefp00000000000000000000000000000000000000000004f");
+ assertEquals("Returned incorrect value", -4.48585472E8f, actual, 0.0F);
+
+ actual = Float.parseFloat("0X0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001234p600f");
+ assertEquals("Returned incorrect value", 5.907252E33f, actual, 0.0F);
+
+ actual = Float.parseFloat("0x1.p9223372036854775807");
+ assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, actual, 0.0F);
+
+ actual = Float.parseFloat("0x1.p9223372036854775808");
+ assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, actual, 0.0F);
+
+ actual = Float.parseFloat("0x10.p9223372036854775808");
+ assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, actual, 0.0F);
+
+ actual = Float.parseFloat("0xabcd.ffffffffp+2000");
+ assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, actual, 0.0F);
+
+ actual = Float.parseFloat("0x1.p-9223372036854775808");
+ assertEquals("Returned incorrect value", 0.0f, actual, 0.0F);
+
+ actual = Float.parseFloat("0x1.p-9223372036854775809");
+ assertEquals("Returned incorrect value", 0.0f, actual, 0.0F);
+
+ actual = Float.parseFloat("0x.1p-9223372036854775809");
+ assertEquals("Returned incorrect value", 0.0f, actual, 0.0F);
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_NormalPositiveExponent() {
+ int[] expecteds = {
+ 0x3991a2b4, 0x43cc0247, 0x47909009,
+ 0x4ac0c009, 0x4e109005, 0x5140c005,
+ 0x5458d805, 0x57848402, 0x5a909002,
+ 0x5da8a802, 0x60c0c002, 0x63cccc02,
+ 0x66e4e402, 0x69f0f002, 0x6d048401,
+ 0x70109001, 0x73169601, 0x76810810,
+ 0x79840840, 0x7c8a08a0, 0x7f800000,
+ 0x7f800000, 0x7f800000, 0x7f800000,
+ 0x7f800000,
+ };
+
+ for (int i = 0; i < expecteds.length; i++) {
+ int part = i * 6;
+ String inputString = "0x" + part + "." + part + "0123456789abcdefp" + part;
+
+ float actual = Float.parseFloat(inputString);
+ float expected = Float.intBitsToFloat(expecteds[i]);
+
+ String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+ String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+ String errorMsg = i + "th input string is:<" + inputString
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0F);
+ }
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_NormalNegativeExponent() {
+ int[] expecteds = {
+ 0x3991a2b4,
+ 0x3d6e0247,
+ 0x3aa0a009,
+ 0x37848405,
+ 0x3420a005,
+ 0x30d4d405,
+ 0x2d848402,
+ 0x2a129202,
+ 0x26acac02,
+ 0x2346c602,
+ 0x1fe0e002,
+ 0x1c6eee02,
+ 0x19048401,
+ 0x15919101,
+ 0x12189801,
+ 0xf028828,
+ 0xb890890,
+ 0x80c88c8,
+ 0x4930930,
+ 0x1198998,
+ 0x28028,
+ 0x51c,
+ 0xb,
+ 0x0,
+ 0x0,
+ };
+
+ for (int i = 0; i < expecteds.length; i++) {
+ int part = i * 7;
+ String inputString = "0x" + part + "." + part + "0123456789abcdefp-" + part;
+
+ float actual = Float.parseFloat(inputString);
+ float expected = Float.intBitsToFloat(expecteds[i]);
+
+ String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+ String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+ String errorMsg = i + "th input string is:<" + inputString
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0F);
+ }
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_MaxNormalBoundary() {
+ int[] expecteds = {
+ 0x7f7fffff,
+ 0x7f7fffff,
+ 0x7f7fffff,
+ 0x7f800000,
+ 0x7f800000,
+ 0x7f800000,
+
+ 0xff7fffff,
+ 0xff7fffff,
+ 0xff7fffff,
+ 0xff800000,
+ 0xff800000,
+ 0xff800000,
+ };
+
+ String[] inputs = {
+ "0x1.fffffep127",
+ "0x1.fffffe000000000000000000000000000000000000000000000001p127",
+ "0x1.fffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp127",
+ "0x1.ffffffp127",
+ "0x1.ffffff000000000000000000000000000000000000000000000001p127",
+ "0x1.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp127",
+
+ "-0x1.fffffep127",
+ "-0x1.fffffe000000000000000000000000000000000000000000000001p127",
+ "-0x1.fffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp127",
+ "-0x1.ffffffp127",
+ "-0x1.ffffff000000000000000000000000000000000000000000000001p127",
+ "-0x1.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp127",
+ };
+
+ for (int i = 0; i < inputs.length; i++) {
+ float actual = Float.parseFloat(inputs[i]);
+ float expected = Float.intBitsToFloat(expecteds[i]);
+
+ String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+ String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0F);
+ }
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_MinNormalBoundary() {
+ int expecteds[] = {
+ 0x800000,
+ 0x800000,
+ 0x800000,
+ 0x800000,
+ 0x800001,
+ 0x800001,
+
+ 0x80800000,
+ 0x80800000,
+ 0x80800000,
+ 0x80800000,
+ 0x80800001,
+ 0x80800001,
+ };
+
+ String inputs[] = {
+ "0x1.0p-126",
+ "0x1.00000000000000000000000000000000000000000000001p-126",
+ "0x1.000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ "0x1.000001p-126",
+ "0x1.000001000000000000000000000000000000000000000001p-126",
+ "0x1.000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+
+ "-0x1.0p-126",
+ "-0x1.00000000000000000000000000000000000000000000001p-126",
+ "-0x1.000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ "-0x1.000001p-126",
+ "-0x1.000001000000000000000000000000000000000000000001p-126",
+ "-0x1.000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ };
+
+ for (int i = 0; i < inputs.length; i++) {
+ float actual = Float.parseFloat(inputs[i]);
+ float expected = Float.intBitsToFloat(expecteds[i]);
+
+ String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+ String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0F);
+ }
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_MaxSubNormalBoundary() {
+ int expecteds[] = {
+ 0x7fffff,
+ 0x7fffff,
+ 0x7fffff,
+ 0x800000,
+ 0x800000,
+ 0x800000,
+
+ 0x807fffff,
+ 0x807fffff,
+ 0x807fffff,
+ 0x80800000,
+ 0x80800000,
+ 0x80800000,
+ };
+
+ String inputs[] = {
+ "0x0.fffffep-126",
+ "0x0.fffffe000000000000000000000000000000000000000000000000000001p-126",
+ "0x0.fffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ "0x0.ffffffp-126",
+ "0x0.ffffff0000000000000000000000000000000000000000000000000000001p-126",
+ "0x0.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+
+ "-0x0.fffffep-126",
+ "-0x0.fffffe000000000000000000000000000000000000000000000000000001p-126",
+ "-0x0.fffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ "-0x0.ffffffp-126",
+ "-0x0.ffffff0000000000000000000000000000000000000000000000000000001p-126",
+ "-0x0.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ };
+
+ for (int i = 0; i < inputs.length; i++) {
+ float actual = Float.parseFloat(inputs[i]);
+ float expected = Float.intBitsToFloat(expecteds[i]);
+
+ String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+ String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0F);
+ }
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_MinSubNormalBoundary() {
+ int expecteds[] = {
+ 0x1,
+ 0x1,
+ 0x1,
+ 0x2,
+ 0x2,
+ 0x2,
+
+ 0x80000001,
+ 0x80000001,
+ 0x80000001,
+ 0x80000002,
+ 0x80000002,
+ 0x80000002,
+ };
+
+ String inputs[] = {
+ "0x0.000002p-126",
+ "0x0.00000200000000000000000000000000000000000001p-126",
+ "0x0.000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ "0x0.000003p-126",
+ "0x0.000003000000000000000000000000000000000000001p-126",
+ "0x0.000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+
+ "-0x0.000002p-126",
+ "-0x0.00000200000000000000000000000000000000000001p-126",
+ "-0x0.000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ "-0x0.000003p-126",
+ "-0x0.000003000000000000000000000000000000000000001p-126",
+ "-0x0.000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ };
+
+ for (int i = 0; i < inputs.length; i++) {
+ float actual = Float.parseFloat(inputs[i]);
+ float expected = Float.intBitsToFloat(expecteds[i]);
+
+ String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+ String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0F);
+ }
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_ZeroBoundary() {
+ int expecteds[] = {
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x1,
+ 0x1,
+
+ 0x80000000,
+ 0x80000000,
+ 0x80000000,
+ 0x80000000,
+ 0x80000001,
+ 0x80000001,
+ };
+
+ String inputs[] = {
+ "0x0.000000000000000p-126",
+ "0x0.000000000000000000000000000000000000000000000001p-126",
+ "0x0.000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ "0x0.000001p-126",
+ "0x0.000001000000000000000000000000000000000000000001p-126",
+ "0x0.000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+
+ "-0x0.000000000000000p-126",
+ "-0x0.000000000000000000000000000000000000000000000001p-126",
+ "-0x0.000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ "-0x0.000001p-126",
+ "-0x0.000001000000000000000000000000000000000000000001p-126",
+ "-0x0.000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+ };
+
+ for (int i = 0; i < inputs.length; i++) {
+ float actual = Float.parseFloat(inputs[i]);
+ float expected = Float.intBitsToFloat(expecteds[i]);
+
+ String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+ String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+ String errorMsg = i + "th input string is:<" + inputs[i]
+ + ">.The expected result should be:<" + expectedString
+ + ">, but was: <" + actualString + ">. ";
+
+ assertEquals(errorMsg, expected, actual, 0.0F);
+ }
+ }
+
+ /**
+ * java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_Harmony6261() {
+ // Regression test for HARMONY-6261
+ float f = new Float("2147483648");
+ assertEquals("2.1474836E9", Float.toString(f));
+
+ doTestCompareRawBits("123456790528.000000000000000f", 0x51e5f4c9, "1.2345679E11");
+ doTestCompareRawBits("8589934592", 0x50000000, "8.5899346E9");
+ doTestCompareRawBits("8606711808", 0x50004000, "8.606712E9");
+ }
+
+ /**
+ * java.lang.Float#shortValue()
+ */
+ public void test_shortValue() {
+ // Test for method short java.lang.Float.shortValue()
+ Float f = new Float(0.46874f);
+ Float f2 = new Float(90.8f);
+ assertTrue("Returned incorrect short value", f.shortValue() == 0
+ && f2.shortValue() == 90);
+ }
+
+ /**
+ * java.lang.Float#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.lang.Float.toString()
+
+ test_toString(12.90898f, "12.90898");
+
+ test_toString(1.7014118346046924e+38F, "1.7014118E38");
+
+ test_toString(1E19F, "1.0E19");
+
+ test_toString(1E-36F, "1.0E-36");
+
+ test_toString(1.0E-38F, "1.0E-38");
+ }
+
+ /**
+ * java.lang.Float#toString(float)
+ */
+ public void test_toStringF() {
+ // Test for method java.lang.String java.lang.Float.toString(float)
+
+ float ff;
+ String answer;
+
+ ff = 12.90898f;
+ answer = "12.90898";
+ assertTrue("Incorrect String representation want " + answer + ", got "
+ + Float.toString(ff), Float.toString(ff).equals(answer));
+
+ ff = Float.MAX_VALUE;
+ answer = "3.4028235E38";
+ assertTrue("Incorrect String representation want " + answer + ", got "
+ + Float.toString(ff), Float.toString(ff).equals(answer));
+ }
+
+ /**
+ * java.lang.Float#valueOf(java.lang.String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ // Test for method java.lang.Float
+ // java.lang.Float.valueOf(java.lang.String)
+
+ Float wanted = new Float(432.1235f);
+ Float got = Float.valueOf("432.1235");
+ assertTrue("Incorrect float returned--wanted: " + wanted + " but got: " + got, got
+ .equals(wanted));
+
+ wanted = new Float(0f);
+ got = Float.valueOf("0");
+ assertTrue("Incorrect float returned--wanted: " + wanted + " but got: " + got, got
+ .equals(wanted));
+
+ wanted = new Float(-1212.3232f);
+ got = Float.valueOf("-1212.3232");
+ assertTrue("Incorrect float returned--wanted: " + wanted + " but got: " + got, got
+ .equals(wanted));
+
+ try {
+ Float.valueOf(null);
+ fail("Expected Float.valueOf(null) to throw NPE.");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+
+ try {
+ Float.valueOf("");
+ fail("Expected Float.valueOf(\"\") to throw NFE");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ Float posZero = Float.valueOf("+0.0");
+ Float negZero = Float.valueOf("-0.0");
+ assertFalse("Floattest0", posZero.equals(negZero));
+ assertTrue("Floattest1", 0.0f == -0.0f);
+
+ // Tests for float values by name.
+ Float expectedNaN = new Float(Float.NaN);
+
+ Float posNaN = Float.valueOf("NaN");
+ assertTrue("Floattest2", posNaN.equals(expectedNaN));
+
+ Float posNaNSigned = Float.valueOf("+NaN");
+ assertTrue("Floattest3", posNaNSigned.equals(expectedNaN));
+
+ Float negNaNSigned = Float.valueOf("-NaN");
+ assertTrue("Floattest4", negNaNSigned.equals(expectedNaN));
+
+ Float posInfinite = Float.valueOf("Infinity");
+ assertTrue("Floattest5", posInfinite.equals(new Float(Float.POSITIVE_INFINITY)));
+
+ Float posInfiniteSigned = Float.valueOf("+Infinity");
+ assertTrue("Floattest6", posInfiniteSigned.equals(new Float(Float.POSITIVE_INFINITY)));
+
+ Float negInfiniteSigned = Float.valueOf("-Infinity");
+ assertTrue("Floattest7", negInfiniteSigned.equals(new Float(Float.NEGATIVE_INFINITY)));
+
+ // test HARMONY-6641
+ posInfinite = Float.valueOf("320.0E+2147483647");
+ assertEquals("Floattest8", Float.POSITIVE_INFINITY, posInfinite);
+
+ negZero = Float.valueOf("-1.4E-2147483314");
+ assertEquals("Floattest9", -0.0f, negZero);
+ }
+
+ private void test_toString(float ff, String answer) {
+ // Test for method java.lang.String java.lang.Double.toString(double)
+ assertTrue("Incorrect String representation want " + answer + ", got ("
+ + Float.toString(ff) + ")", Float.toString(ff).equals(answer));
+ Float f = new Float(ff);
+ assertTrue("Incorrect String representation want " + answer + ", got ("
+ + Float.toString(f.floatValue()) + ")", Float.toString(f.floatValue()).equals(
+ answer));
+ assertTrue("Incorrect String representation want " + answer + ", got (" + f.toString()
+ + ")", f.toString().equals(answer));
+ }
+
+ /**
+ * java.lang.Float#compareTo(java.lang.Float)
+ * java.lang.Float#compare(float, float)
+ */
+ public void test_compareToLjava_lang_Float() {
+ // A selection of float values in ascending order.
+ float[] values = new float[] { Float.NEGATIVE_INFINITY, -Float.MAX_VALUE, -2f,
+ -Float.MIN_VALUE, -0f, 0f, Float.MIN_VALUE, 2f, Float.MAX_VALUE,
+ Float.POSITIVE_INFINITY, Float.NaN };
+
+ for (int i = 0; i < values.length; i++) {
+ float f1 = values[i];
+
+ // Test that each value compares equal to itself; and each object is
+ // equal to another object
+ // like itself
+ assertTrue("Assert 0: compare() should be equal: " + f1, Float.compare(f1, f1) == 0);
+ Float objFloat = new Float(f1);
+ assertTrue("Assert 1: compareTo() should be equal: " + objFloat, objFloat
+ .compareTo(objFloat) == 0);
+
+ // Test that the Float-defined order is respected
+ for (int j = i + 1; j < values.length; j++) {
+ float f2 = values[j];
+ assertTrue("Assert 2: compare() " + f1 + " should be less " + f2, Float
+ .compare(f1, f2) == -1);
+ assertTrue("Assert 3: compare() " + f2 + " should be greater " + f1, Float
+ .compare(f2, f1) == 1);
+
+ Float F2 = new Float(f2);
+ assertTrue("Assert 4: compareTo() " + f1 + " should be less " + f2, objFloat
+ .compareTo(F2) == -1);
+ assertTrue("Assert 5: compareTo() " + f2 + " should be greater " + f1, F2
+ .compareTo(objFloat) == 1);
+ }
+ }
+ }
+
+ /**
+ * java.lang.Float#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ Float f1 = new Float(8765.4321f);
+ Float f2 = new Float(8765.4321f);
+ Float f3 = new Float(-1.0f);
+ assertTrue("Assert 0: Equality test failed", f1.equals(f2) && !(f1.equals(f3)));
+
+ assertTrue("Assert 1: NaN should not be == Nan", Float.NaN != Float.NaN);
+ assertTrue("Assert 2: NaN should not be == Nan", new Float(Float.NaN).equals(new Float(
+ Float.NaN)));
+ assertTrue("Assert 3: -0f should be == 0f", 0f == -0f);
+ assertTrue("Assert 4: -0f should not be equals() 0f", !new Float(0f).equals(new Float(
+ -0f)));
+
+ f1 = new Float(1098.576f);
+ f2 = new Float(1098.576f);
+ f3 = new Float(1.0f);
+ assertTrue("Equality test failed", f1.equals(f2) && !(f1.equals(f3)));
+
+ assertTrue("NaN should not be == Nan", Float.NaN != Float.NaN);
+ assertTrue("NaN should not be == Nan", new Float(Float.NaN)
+ .equals(new Float(Float.NaN)));
+ assertTrue("-0f should be == 0f", 0f == -0f);
+ assertTrue("-0f should not be equals() 0f", !new Float(0f).equals(new Float(-0f)));
+ }
+
+ /**
+ * java.lang.Float#toHexString(float)
+ */
+ public void test_toHexStringF() {
+ // the follow values comes from the Float Javadoc/Spec
+ assertEquals("0x0.0p0", Float.toHexString(0.0F));
+ assertEquals("-0x0.0p0", Float.toHexString(-0.0F));
+ assertEquals("0x1.0p0", Float.toHexString(1.0F));
+ assertEquals("-0x1.0p0", Float.toHexString(-1.0F));
+ assertEquals("0x1.0p1", Float.toHexString(2.0F));
+ assertEquals("0x1.8p1", Float.toHexString(3.0F));
+ assertEquals("0x1.0p-1", Float.toHexString(0.5F));
+ assertEquals("0x1.0p-2", Float.toHexString(0.25F));
+ assertEquals("0x1.fffffep127", Float.toHexString(Float.MAX_VALUE));
+ assertEquals("0x0.000002p-126", Float.toHexString(Float.MIN_VALUE));
+
+ // test edge cases
+ assertEquals("NaN", Float.toHexString(Float.NaN));
+ assertEquals("-Infinity", Float.toHexString(Float.NEGATIVE_INFINITY));
+ assertEquals("Infinity", Float.toHexString(Float.POSITIVE_INFINITY));
+
+ // test various numbers
+ assertEquals("-0x1.da8p6", Float.toHexString(-118.625F));
+ assertEquals("0x1.295788p23", Float.toHexString(9743299.65F));
+ assertEquals("0x1.295788p23", Float.toHexString(9743299.65000F));
+ assertEquals("0x1.295788p23", Float.toHexString(9743299.650001234F));
+ assertEquals("0x1.700d1p33", Float.toHexString(12349743299.65000F));
+
+ // test HARMONY-2132
+ assertEquals("0x1.01p10", Float.toHexString(0x1.01p10f));
+ }
+
+ /**
+ * java.lang.Float#valueOf(float)
+ */
+ public void test_valueOfF() {
+ assertEquals(new Float(Float.MIN_VALUE), Float.valueOf(Float.MIN_VALUE));
+ assertEquals(new Float(Float.MAX_VALUE), Float.valueOf(Float.MAX_VALUE));
+ assertEquals(new Float(0), Float.valueOf(0));
+
+ int s = -128;
+ while (s < 128) {
+ assertEquals(new Float(s), Float.valueOf(s));
+ assertEquals(new Float(s + 0.1F), Float.valueOf(s + 0.1F));
+ assertEquals(Float.valueOf(s + 0.1F), Float.valueOf(s + 0.1F));
+ s++;
+ }
+ }
+
+ /**
+ * {@link java.lang.Float#MAX_EXPONENT}
+ * @since 1.6
+ */
+ public void test_MAX_EXPONENT() {
+ assertTrue("Wrong value of java.lang.Float.MAX_EXPONENT",
+ Float.MAX_EXPONENT == 127);
+ assertTrue("Wrong value of java.lang.Float.MAX_EXPONENT",
+ Float.MAX_EXPONENT == Math.getExponent(Float.MAX_VALUE));
+ }
+
+ /**
+ * {@link java.lang.Float#MIN_EXPONENT}
+ * @since 1.6
+ */
+ public void test_MIN_EXPONENT() {
+ assertTrue("Wrong value of java.lang.Float.MIN_EXPONENT",
+ Float.MIN_EXPONENT == -126);
+ assertTrue("Wrong value of java.lang.Float.MIN_EXPONENT",
+ Float.MIN_EXPONENT == Math.getExponent(Float.MIN_NORMAL));
+ }
+
+ /**
+ * {@link java.lang.Float#MIN_NORMAL}
+ * @since 1.6
+ */
+ public void test_MIN_NORMAL() {
+ assertTrue("Wrong value of java.lang.Float.MIN_NORMAL",
+ Float.MIN_NORMAL == 0x1.0p-126f);
+ assertTrue("Wrong value of java.lang.Float.MIN_NORMAL",
+ Float.MIN_NORMAL == Float.intBitsToFloat(0x00800000));
+ assertTrue("Wrong value of java.lang.Float.MIN_NORMAL",
+ Float.MIN_NORMAL == 1.1754943508222875E-38f);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalAccessErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalAccessErrorTest.java
new file mode 100644
index 0000000..052bca2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalAccessErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class IllegalAccessErrorTest extends TestCase {
+
+ /**
+ * java.lang.IllegalAccessError#IllegalAccessError()
+ */
+ public void test_Constructor() {
+ IllegalAccessError e = new IllegalAccessError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.IllegalAccessError#IllegalAccessError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ IllegalAccessError e = new IllegalAccessError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalAccessExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalAccessExceptionTest.java
new file mode 100644
index 0000000..eb3b021
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalAccessExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class IllegalAccessExceptionTest extends TestCase {
+
+ /**
+ * java.lang.IllegalAccessException#IllegalAccessException()
+ */
+ public void test_Constructor() {
+ IllegalAccessException e = new IllegalAccessException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.IllegalAccessException#IllegalAccessException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ IllegalAccessException e = new IllegalAccessException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalArgumentExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalArgumentExceptionTest.java
new file mode 100644
index 0000000..c126f86
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalArgumentExceptionTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class IllegalArgumentExceptionTest extends TestCase {
+
+ /**
+ * java.lang.IllegalArgumentException#IllegalArgumentException()
+ */
+ public void test_Constructor() {
+ IllegalArgumentException e = new IllegalArgumentException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.IllegalArgumentException#IllegalArgumentException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ IllegalArgumentException e = new IllegalArgumentException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * {@link java.lang.IllegalArgumentException#IllegalArgumentException(Throwable)}
+ */
+ public void test_ConstructorLjava_lang_Throwable() {
+ Throwable emptyThrowable = new Exception();
+ IllegalArgumentException emptyException = new IllegalArgumentException(emptyThrowable);
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getLocalizedMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+ Throwable exception = new Exception("msg");
+ IllegalArgumentException e = new IllegalArgumentException(exception);
+ assertEquals(exception.getClass().getName() + ": " + "msg", e.getMessage());
+ assertEquals(exception.getClass().getName(), emptyException.getLocalizedMessage());
+ assertEquals(exception.getClass().getName(), emptyException.getCause().toString());
+ }
+
+ /**
+ * java.lang.IllegalArgumentException#IllegalArgumentException(String, Throwable)
+ */
+ @SuppressWarnings("nls")
+ public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+ NullPointerException npe = new NullPointerException();
+ IllegalArgumentException e = new IllegalArgumentException("fixture",
+ npe);
+ assertSame("fixture", e.getMessage());
+ assertSame(npe, e.getCause());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(new IllegalArgumentException());
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ SerializationTest.verifyGolden(this, new IllegalArgumentException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalMonitorStateExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalMonitorStateExceptionTest.java
new file mode 100644
index 0000000..065b466
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalMonitorStateExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class IllegalMonitorStateExceptionTest extends TestCase {
+
+ /**
+ * java.lang.IllegalMonitorStateException#IllegalMonitorStateException()
+ */
+ public void test_Constructor() {
+ IllegalMonitorStateException e = new IllegalMonitorStateException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.IllegalMonitorStateException#IllegalMonitorStateException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ IllegalMonitorStateException e = new IllegalMonitorStateException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalStateExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalStateExceptionTest.java
new file mode 100644
index 0000000..e02ae18
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalStateExceptionTest.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class IllegalStateExceptionTest extends TestCase {
+
+ /**
+ * java.lang.IllegalStateException#IllegalStateException()
+ */
+ public void test_Constructor() {
+ IllegalStateException e = new IllegalStateException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.IllegalStateException#IllegalStateException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ IllegalStateException e = new IllegalStateException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * {@link java.land.IllegalStateException#IllIllegalStateException(java.lang.Throwable)}
+ */
+ public void test_ConstructorLjava_lang_Throwable() {
+ Throwable emptyThrowable = new Exception();
+ IllegalStateException emptyException = new IllegalStateException(emptyThrowable);
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getLocalizedMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+ Throwable throwable = new Exception("msg");
+ IllegalStateException exception = new IllegalStateException(throwable);
+ assertEquals(throwable.getClass().getName() + ": " + "msg", exception.getMessage());
+ assertEquals(throwable.getClass().getName(), emptyException.getLocalizedMessage());
+ assertEquals(throwable.getClass().getName(), emptyException.getCause().toString());
+ }
+
+ /**
+ * {@link java.land.IllegalStateException#IllIllegalStateException(java.lang.String, java.lang.Throwable)}
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+ Throwable emptyThrowable = new Exception();
+ IllegalStateException emptyException = new IllegalStateException("msg", emptyThrowable);
+ assertEquals("msg", emptyException.getMessage());
+ assertEquals("msg", emptyException.getLocalizedMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+ Throwable throwable = new Exception("msg_exception");
+ IllegalStateException exception = new IllegalStateException("msg", throwable);
+ assertEquals("msg", exception.getMessage());
+ assertEquals("msg", exception.getLocalizedMessage());
+ assertEquals(throwable.getClass().getName() + ": " + throwable.getMessage(), exception
+ .getCause().toString());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new IllegalStateException());
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new IllegalStateException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalThreadStateExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalThreadStateExceptionTest.java
new file mode 100644
index 0000000..c1c3763
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IllegalThreadStateExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class IllegalThreadStateExceptionTest extends TestCase {
+
+ /**
+ * java.lang.IllegalThreadStateException#IllegalThreadStateException()
+ */
+ public void test_Constructor() {
+ IllegalThreadStateException e = new IllegalThreadStateException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.IllegalThreadStateException#IllegalThreadStateException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ IllegalThreadStateException e = new IllegalThreadStateException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IncompatibleClassChangeErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IncompatibleClassChangeErrorTest.java
new file mode 100644
index 0000000..a8ef32f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IncompatibleClassChangeErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class IncompatibleClassChangeErrorTest extends TestCase {
+
+ /**
+ * java.lang.IncompatibleClassChangeError#IncompatibleClassChangeError()
+ */
+ public void test_Constructor() {
+ IncompatibleClassChangeError e = new IncompatibleClassChangeError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.IncompatibleClassChangeError#IncompatibleClassChangeError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ IncompatibleClassChangeError e = new IncompatibleClassChangeError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IndexOutOfBoundsExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IndexOutOfBoundsExceptionTest.java
new file mode 100644
index 0000000..7093d4e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IndexOutOfBoundsExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class IndexOutOfBoundsExceptionTest extends TestCase {
+
+ /**
+ * java.lang.IndexOutOfBoundsException#IndexOutOfBoundsException()
+ */
+ public void test_Constructor() {
+ IndexOutOfBoundsException e = new IndexOutOfBoundsException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.IndexOutOfBoundsException#IndexOutOfBoundsException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ IndexOutOfBoundsException e = new IndexOutOfBoundsException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InheritableThreadLocalTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InheritableThreadLocalTest.java
new file mode 100644
index 0000000..d693acd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InheritableThreadLocalTest.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class InheritableThreadLocalTest extends TestCase {
+
+ /**
+ * java.lang.InheritableThreadLocal#InheritableThreadLocal()
+ */
+ public void test_Constructor() {
+ InheritableThreadLocal<String> itl = new InheritableThreadLocal<String>();
+ assertNull(itl.get());
+ }
+
+ public void test_initialValue() {
+ InheritableThreadLocal<String> itl = new InheritableThreadLocal<String>() {
+ @Override
+ protected String initialValue() {
+ return "initial";
+ }
+ };
+ assertEquals("initial", itl.get());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InstantiationErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InstantiationErrorTest.java
new file mode 100644
index 0000000..a069dba
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InstantiationErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class InstantiationErrorTest extends TestCase {
+
+ /**
+ * java.lang.InstantiationError#InstantiationError()
+ */
+ public void test_Constructor() {
+ InstantiationError e = new InstantiationError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.InstantiationError#InstantiationError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ InstantiationError e = new InstantiationError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InstantiationExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InstantiationExceptionTest.java
new file mode 100644
index 0000000..757b209
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InstantiationExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class InstantiationExceptionTest extends TestCase {
+
+ /**
+ * java.lang.InstantiationException#InstantiationException()
+ */
+ public void test_Constructor() {
+ InstantiationException e = new InstantiationException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.InstantiationException#InstantiationException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ InstantiationException e = new InstantiationException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IntegerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IntegerTest.java
new file mode 100644
index 0000000..3c7faa3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/IntegerTest.java
@@ -0,0 +1,1231 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+public class IntegerTest extends TestCase {
+ private Properties orgProps;
+
+ @Override
+ protected void setUp() {
+ orgProps = System.getProperties();
+ }
+
+ @Override
+ protected void tearDown() {
+ System.setProperties(orgProps);
+ }
+
+ /**
+ * java.lang.Integer#byteValue()
+ */
+ public void test_byteValue() {
+ // Test for method byte java.lang.Integer.byteValue()
+ assertEquals("Returned incorrect byte value", -1, new Integer(65535)
+ .byteValue());
+ assertEquals("Returned incorrect byte value", 127, new Integer(127)
+ .byteValue());
+ }
+
+ /**
+ * java.lang.Integer#compareTo(java.lang.Integer)
+ */
+ public void test_compareToLjava_lang_Integer() {
+ // Test for method int java.lang.Integer.compareTo(java.lang.Integer)
+ assertTrue("-2 compared to 1 gave non-negative answer", new Integer(-2)
+ .compareTo(new Integer(1)) < 0);
+ assertEquals("-2 compared to -2 gave non-zero answer", 0, new Integer(-2)
+ .compareTo(new Integer(-2)));
+ assertTrue("3 compared to 2 gave non-positive answer", new Integer(3)
+ .compareTo(new Integer(2)) > 0);
+
+ try {
+ new Integer(0).compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Integer#decode(java.lang.String)
+ */
+ public void test_decodeLjava_lang_String2() {
+ // Test for method java.lang.Integer
+ // java.lang.Integer.decode(java.lang.String)
+ assertEquals("Failed for 132233",
+ 132233, Integer.decode("132233").intValue());
+ assertEquals("Failed for 07654321",
+ 07654321, Integer.decode("07654321").intValue());
+ assertTrue("Failed for #1234567",
+ Integer.decode("#1234567").intValue() == 0x1234567);
+ assertTrue("Failed for 0xdAd",
+ Integer.decode("0xdAd").intValue() == 0xdad);
+ assertEquals("Failed for -23", -23, Integer.decode("-23").intValue());
+ assertEquals("Returned incorrect value for 0 decimal", 0, Integer
+ .decode("0").intValue());
+ assertEquals("Returned incorrect value for 0 hex", 0, Integer.decode("0x0")
+ .intValue());
+ assertTrue("Returned incorrect value for most negative value decimal",
+ Integer.decode("-2147483648").intValue() == 0x80000000);
+ assertTrue("Returned incorrect value for most negative value hex",
+ Integer.decode("-0x80000000").intValue() == 0x80000000);
+ assertTrue("Returned incorrect value for most positive value decimal",
+ Integer.decode("2147483647").intValue() == 0x7fffffff);
+ assertTrue("Returned incorrect value for most positive value hex",
+ Integer.decode("0x7fffffff").intValue() == 0x7fffffff);
+
+ boolean exception = false;
+ try {
+ Integer.decode("0a");
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Failed to throw NumberFormatException for \"Oa\"",
+ exception);
+
+ exception = false;
+ try {
+ Integer.decode("2147483648");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Integer.decode("-2147483649");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Integer.decode("0x80000000");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Integer.decode("-0x80000001");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Integer.decode("9999999999");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for 9999999999", exception);
+
+ try {
+ Integer.decode("-");
+ fail("Expected exception for -");
+ } catch (NumberFormatException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode("0x");
+ fail("Expected exception for 0x");
+ } catch (NumberFormatException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode("#");
+ fail("Expected exception for #");
+ } catch (NumberFormatException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode("x123");
+ fail("Expected exception for x123");
+ } catch (NumberFormatException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode(null);
+ fail("Expected exception for null");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode("");
+ fail("Expected exception for empty string");
+ } catch (NumberFormatException ex) {
+ // Expected
+ }
+
+ try {
+ Integer.decode(" ");
+ fail("Expected exception for single space");
+ } catch (NumberFormatException ex) {
+ // Expected
+ }
+
+ }
+
+ /**
+ * java.lang.Integer#doubleValue()
+ */
+ public void test_doubleValue2() {
+ // Test for method double java.lang.Integer.doubleValue()
+ assertEquals("Returned incorrect double value", 2147483647.0, new Integer(2147483647)
+ .doubleValue(), 0.0D);
+ assertEquals("Returned incorrect double value", -2147483647.0, new Integer(-2147483647)
+ .doubleValue(), 0.0D);
+ }
+
+ /**
+ * java.lang.Integer#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object2() {
+ // Test for method boolean java.lang.Integer.equals(java.lang.Object)
+ Integer i1 = new Integer(1000);
+ Integer i2 = new Integer(1000);
+ Integer i3 = new Integer(-1000);
+ assertTrue("Equality test failed", i1.equals(i2) && !(i1.equals(i3)));
+ }
+
+ /**
+ * java.lang.Integer#floatValue()
+ */
+ public void test_floatValue2() {
+ // Test for method float java.lang.Integer.floatValue()
+ assertTrue("Returned incorrect float value", new Integer(65535)
+ .floatValue() == 65535.0f);
+ assertTrue("Returned incorrect float value", new Integer(-65535)
+ .floatValue() == -65535.0f);
+ }
+
+ /**
+ * java.lang.Integer#getInteger(java.lang.String)
+ */
+ public void test_getIntegerLjava_lang_String() {
+ // Test for method java.lang.Integer
+ // java.lang.Integer.getInteger(java.lang.String)
+ Properties tProps = new Properties();
+ tProps.put("testInt", "99");
+ System.setProperties(tProps);
+ assertTrue("returned incorrect Integer", Integer.getInteger("testInt")
+ .equals(new Integer(99)));
+ assertNull("returned incorrect default Integer", Integer
+ .getInteger("ff"));
+ }
+
+ /**
+ * java.lang.Integer#getInteger(java.lang.String, int)
+ */
+ public void test_getIntegerLjava_lang_StringI() {
+ // Test for method java.lang.Integer
+ // java.lang.Integer.getInteger(java.lang.String, int)
+ Properties tProps = new Properties();
+ tProps.put("testInt", "99");
+ System.setProperties(tProps);
+ assertTrue("returned incorrect Integer", Integer.getInteger("testInt",
+ 4).equals(new Integer(99)));
+ assertTrue("returned incorrect default Integer", Integer.getInteger(
+ "ff", 4).equals(new Integer(4)));
+ }
+
+ /**
+ * java.lang.Integer#getInteger(java.lang.String, java.lang.Integer)
+ */
+ public void test_getIntegerLjava_lang_StringLjava_lang_Integer() {
+ // Test for method java.lang.Integer
+ // java.lang.Integer.getInteger(java.lang.String, java.lang.Integer)
+ Properties tProps = new Properties();
+ tProps.put("testInt", "99");
+ System.setProperties(tProps);
+ assertTrue("returned incorrect Integer", Integer.getInteger("testInt",
+ new Integer(4)).equals(new Integer(99)));
+ assertTrue("returned incorrect default Integer", Integer.getInteger(
+ "ff", new Integer(4)).equals(new Integer(4)));
+ }
+
+ /**
+ * java.lang.Integer#hashCode()
+ */
+ public void test_hashCode2() {
+ // Test for method int java.lang.Integer.hashCode()
+
+ Integer i1 = new Integer(1000);
+ Integer i2 = new Integer(-1000);
+ assertTrue("Returned incorrect hashcode", i1.hashCode() == 1000
+ && (i2.hashCode() == -1000));
+ }
+
+ /**
+ * java.lang.Integer#intValue()
+ */
+ public void test_intValue2() {
+ // Test for method int java.lang.Integer.intValue()
+
+ Integer i = new Integer(8900);
+ assertEquals("Returned incorrect int value", 8900, i.intValue());
+ }
+
+ /**
+ * java.lang.Integer#longValue()
+ */
+ public void test_longValue2() {
+ // Test for method long java.lang.Integer.longValue()
+ Integer i = new Integer(8900);
+ assertEquals("Returned incorrect long value", 8900L, i.longValue());
+ }
+
+ /**
+ * java.lang.Integer#parseInt(java.lang.String)
+ */
+ public void test_parseIntLjava_lang_String2() {
+ // Test for method int java.lang.Integer.parseInt(java.lang.String)
+
+ int i = Integer.parseInt("-8900");
+ assertEquals("Returned incorrect int", -8900, i);
+ assertEquals("Returned incorrect value for 0", 0, Integer.parseInt("0"));
+ assertTrue("Returned incorrect value for most negative value", Integer
+ .parseInt("-2147483648") == 0x80000000);
+ assertTrue("Returned incorrect value for most positive value", Integer
+ .parseInt("2147483647") == 0x7fffffff);
+
+ boolean exception = false;
+ try {
+ Integer.parseInt("999999999999");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for value > int", exception);
+
+ exception = false;
+ try {
+ Integer.parseInt("2147483648");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Integer.parseInt("-2147483649");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+ }
+
+ /**
+ * java.lang.Integer#parseInt(java.lang.String, int)
+ */
+ public void test_parseIntLjava_lang_StringI2() {
+ // Test for method int java.lang.Integer.parseInt(java.lang.String, int)
+ assertEquals("Parsed dec val incorrectly",
+ -8000, Integer.parseInt("-8000", 10));
+ assertEquals("Parsed hex val incorrectly",
+ 255, Integer.parseInt("FF", 16));
+ assertEquals("Parsed oct val incorrectly",
+ 16, Integer.parseInt("20", 8));
+ assertEquals("Returned incorrect value for 0 hex", 0, Integer.parseInt("0",
+ 16));
+ assertTrue("Returned incorrect value for most negative value hex",
+ Integer.parseInt("-80000000", 16) == 0x80000000);
+ assertTrue("Returned incorrect value for most positive value hex",
+ Integer.parseInt("7fffffff", 16) == 0x7fffffff);
+ assertEquals("Returned incorrect value for 0 decimal", 0, Integer.parseInt(
+ "0", 10));
+ assertTrue("Returned incorrect value for most negative value decimal",
+ Integer.parseInt("-2147483648", 10) == 0x80000000);
+ assertTrue("Returned incorrect value for most positive value decimal",
+ Integer.parseInt("2147483647", 10) == 0x7fffffff);
+
+ boolean exception = false;
+ try {
+ Integer.parseInt("FFFF", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue(
+ "Failed to throw exception when passes hex string and dec parm",
+ exception);
+
+ exception = false;
+ try {
+ Integer.parseInt("2147483648", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Integer.parseInt("-2147483649", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Integer.parseInt("80000000", 16);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Integer.parseInt("-80000001", 16);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MIN_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Integer.parseInt("9999999999", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for 9999999999", exception);
+ }
+
+ /**
+ * java.lang.Integer#shortValue()
+ */
+ public void test_shortValue2() {
+ // Test for method short java.lang.Integer.shortValue()
+ Integer i = new Integer(2147450880);
+ assertEquals("Returned incorrect long value", -32768, i.shortValue());
+ }
+
+ /**
+ * java.lang.Integer#toBinaryString(int)
+ */
+ public void test_toBinaryStringI() {
+ // Test for method java.lang.String
+ // java.lang.Integer.toBinaryString(int)
+ assertEquals("Incorrect string returned", "1111111111111111111111111111111", Integer.toBinaryString(
+ Integer.MAX_VALUE));
+ assertEquals("Incorrect string returned", "10000000000000000000000000000000", Integer.toBinaryString(
+ Integer.MIN_VALUE));
+ }
+
+ /**
+ * java.lang.Integer#toHexString(int)
+ */
+ public void test_toHexStringI() {
+ // Test for method java.lang.String java.lang.Integer.toHexString(int)
+
+ String[] hexvals = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+ "a", "b", "c", "d", "e", "f" };
+
+ for (int i = 0; i < 16; i++) {
+ assertTrue("Incorrect string returned " + hexvals[i], Integer
+ .toHexString(i).equals(hexvals[i]));
+ }
+
+ assertTrue("Returned incorrect hex string: "
+ + Integer.toHexString(Integer.MAX_VALUE), Integer.toHexString(
+ Integer.MAX_VALUE).equals("7fffffff"));
+ assertTrue("Returned incorrect hex string: "
+ + Integer.toHexString(Integer.MIN_VALUE), Integer.toHexString(
+ Integer.MIN_VALUE).equals("80000000"));
+ }
+
+ /**
+ * java.lang.Integer#toOctalString(int)
+ */
+ public void test_toOctalStringI() {
+ // Test for method java.lang.String java.lang.Integer.toOctalString(int)
+ // Spec states that the int arg is treated as unsigned
+ assertEquals("Returned incorrect octal string", "17777777777", Integer.toOctalString(
+ Integer.MAX_VALUE));
+ assertEquals("Returned incorrect octal string", "20000000000", Integer.toOctalString(
+ Integer.MIN_VALUE));
+ }
+
+ /**
+ * java.lang.Integer#toString()
+ */
+ public void test_toString2() {
+ // Test for method java.lang.String java.lang.Integer.toString()
+
+ Integer i = new Integer(-80001);
+
+ assertEquals("Returned incorrect String", "-80001", i.toString());
+ }
+
+ /**
+ * java.lang.Integer#toString(int)
+ */
+ public void test_toStringI2() {
+ // Test for method java.lang.String java.lang.Integer.toString(int)
+
+ assertEquals("Returned incorrect String", "-80765", Integer.toString(-80765)
+ );
+ assertEquals("Returned incorrect octal string", "2147483647", Integer.toString(
+ Integer.MAX_VALUE));
+ assertEquals("Returned incorrect octal string", "-2147483647", Integer.toString(
+ -Integer.MAX_VALUE));
+ assertEquals("Returned incorrect octal string", "-2147483648", Integer.toString(
+ Integer.MIN_VALUE));
+
+ // Test for HARMONY-6068
+ assertEquals("Returned incorrect octal String", "-1000", Integer.toString(-1000));
+ assertEquals("Returned incorrect octal String", "1000", Integer.toString(1000));
+ assertEquals("Returned incorrect octal String", "0", Integer.toString(0));
+ assertEquals("Returned incorrect octal String", "708", Integer.toString(708));
+ assertEquals("Returned incorrect octal String", "-100", Integer.toString(-100));
+ assertEquals("Returned incorrect octal String", "-1000000008", Integer.toString(-1000000008));
+ assertEquals("Returned incorrect octal String", "2000000008", Integer.toString(2000000008));
+ }
+
+ /**
+ * java.lang.Integer#toString(int, int)
+ */
+ public void test_toStringII() {
+ // Test for method java.lang.String java.lang.Integer.toString(int, int)
+ assertEquals("Returned incorrect octal string", "17777777777", Integer.toString(
+ 2147483647, 8));
+ assertTrue("Returned incorrect hex string--wanted 7fffffff but got: "
+ + Integer.toString(2147483647, 16), Integer.toString(
+ 2147483647, 16).equals("7fffffff"));
+ assertEquals("Incorrect string returned", "1111111111111111111111111111111", Integer.toString(2147483647, 2)
+ );
+ assertEquals("Incorrect string returned", "2147483647", Integer
+ .toString(2147483647, 10));
+
+ assertEquals("Returned incorrect octal string", "-17777777777", Integer.toString(
+ -2147483647, 8));
+ assertTrue("Returned incorrect hex string--wanted -7fffffff but got: "
+ + Integer.toString(-2147483647, 16), Integer.toString(
+ -2147483647, 16).equals("-7fffffff"));
+ assertEquals("Incorrect string returned",
+ "-1111111111111111111111111111111", Integer
+ .toString(-2147483647, 2));
+ assertEquals("Incorrect string returned", "-2147483647", Integer.toString(-2147483647,
+ 10));
+
+ assertEquals("Returned incorrect octal string", "-20000000000", Integer.toString(
+ -2147483648, 8));
+ assertTrue("Returned incorrect hex string--wanted -80000000 but got: "
+ + Integer.toString(-2147483648, 16), Integer.toString(
+ -2147483648, 16).equals("-80000000"));
+ assertEquals("Incorrect string returned",
+ "-10000000000000000000000000000000", Integer
+ .toString(-2147483648, 2));
+ assertEquals("Incorrect string returned", "-2147483648", Integer.toString(-2147483648,
+ 10));
+ }
+
+ /**
+ * java.lang.Integer#valueOf(java.lang.String)
+ */
+ public void test_valueOfLjava_lang_String2() {
+ // Test for method java.lang.Integer
+ // java.lang.Integer.valueOf(java.lang.String)
+ assertEquals("Returned incorrect int", 8888888, Integer.valueOf("8888888")
+ .intValue());
+ assertTrue("Returned incorrect int", Integer.valueOf("2147483647")
+ .intValue() == Integer.MAX_VALUE);
+ assertTrue("Returned incorrect int", Integer.valueOf("-2147483648")
+ .intValue() == Integer.MIN_VALUE);
+
+ boolean exception = false;
+ try {
+ Integer.valueOf("2147483648");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception with MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Integer.valueOf("-2147483649");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception with MIN_VALUE - 1", exception);
+ }
+
+ /**
+ * java.lang.Integer#valueOf(java.lang.String, int)
+ */
+ public void test_valueOfLjava_lang_StringI2() {
+ // Test for method java.lang.Integer
+ // java.lang.Integer.valueOf(java.lang.String, int)
+ assertEquals("Returned incorrect int for hex string", 255, Integer.valueOf(
+ "FF", 16).intValue());
+ assertEquals("Returned incorrect int for oct string", 16, Integer.valueOf(
+ "20", 8).intValue());
+ assertEquals("Returned incorrect int for bin string", 4, Integer.valueOf(
+ "100", 2).intValue());
+
+ assertEquals("Returned incorrect int for - hex string", -255, Integer.valueOf(
+ "-FF", 16).intValue());
+ assertEquals("Returned incorrect int for - oct string", -16, Integer.valueOf(
+ "-20", 8).intValue());
+ assertEquals("Returned incorrect int for - bin string", -4, Integer.valueOf(
+ "-100", 2).intValue());
+ assertTrue("Returned incorrect int", Integer.valueOf("2147483647", 10)
+ .intValue() == Integer.MAX_VALUE);
+ assertTrue("Returned incorrect int", Integer.valueOf("-2147483648", 10)
+ .intValue() == Integer.MIN_VALUE);
+ assertTrue("Returned incorrect int", Integer.valueOf("7fffffff", 16)
+ .intValue() == Integer.MAX_VALUE);
+ assertTrue("Returned incorrect int", Integer.valueOf("-80000000", 16)
+ .intValue() == Integer.MIN_VALUE);
+
+ boolean exception = false;
+ try {
+ Integer.valueOf("FF", 2);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue(
+ "Failed to throw exception with hex string and base 2 radix",
+ exception);
+
+ exception = false;
+ try {
+ Integer.valueOf("2147483648", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception with MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Integer.valueOf("-2147483649", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception with MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Integer.valueOf("80000000", 16);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception with hex MAX_VALUE + 1",
+ exception);
+
+ exception = false;
+ try {
+ Integer.valueOf("-80000001", 16);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception with hex MIN_VALUE - 1",
+ exception);
+ }
+
+ /**
+ * java.lang.Integer#valueOf(byte)
+ */
+ public void test_valueOfI() {
+ assertEquals(new Integer(Integer.MIN_VALUE), Integer.valueOf(Integer.MIN_VALUE));
+ assertEquals(new Integer(Integer.MAX_VALUE), Integer.valueOf(Integer.MAX_VALUE));
+ assertEquals(new Integer(0), Integer.valueOf(0));
+
+ short s = -128;
+ while (s < 128) {
+ assertEquals(new Integer(s), Integer.valueOf(s));
+ assertSame(Integer.valueOf(s), Integer.valueOf(s));
+ s++;
+ }
+ }
+
+ /**
+ * java.lang.Integer#hashCode()
+ */
+ public void test_hashCode() {
+ assertEquals(1, new Integer(1).hashCode());
+ assertEquals(2, new Integer(2).hashCode());
+ assertEquals(0, new Integer(0).hashCode());
+ assertEquals(-1, new Integer(-1).hashCode());
+ }
+
+ /**
+ * java.lang.Integer#Integer(String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ assertEquals(new Integer(0), new Integer("0"));
+ assertEquals(new Integer(1), new Integer("1"));
+ assertEquals(new Integer(-1), new Integer("-1"));
+
+ try {
+ new Integer("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Integer("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Integer("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Integer(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Integer#Integer
+ */
+ public void test_ConstructorI() {
+ assertEquals(1, new Integer(1).intValue());
+ assertEquals(2, new Integer(2).intValue());
+ assertEquals(0, new Integer(0).intValue());
+ assertEquals(-1, new Integer(-1).intValue());
+
+ Integer i = new Integer(-89000);
+ assertEquals("Incorrect Integer created", -89000, i.intValue());
+ }
+
+ /**
+ * java.lang.Integer#byteValue()
+ */
+ public void test_booleanValue() {
+ assertEquals(1, new Integer(1).byteValue());
+ assertEquals(2, new Integer(2).byteValue());
+ assertEquals(0, new Integer(0).byteValue());
+ assertEquals(-1, new Integer(-1).byteValue());
+ }
+
+ /**
+ * java.lang.Integer#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertEquals(new Integer(0), Integer.valueOf(0));
+ assertEquals(new Integer(1), Integer.valueOf(1));
+ assertEquals(new Integer(-1), Integer.valueOf(-1));
+
+ Integer fixture = new Integer(25);
+ assertEquals(fixture, fixture);
+ assertFalse(fixture.equals(null));
+ assertFalse(fixture.equals("Not a Integer"));
+ }
+
+ /**
+ * java.lang.Integer#toString()
+ */
+ public void test_toString() {
+ assertEquals("-1", new Integer(-1).toString());
+ assertEquals("0", new Integer(0).toString());
+ assertEquals("1", new Integer(1).toString());
+ assertEquals("-1", new Integer(0xFFFFFFFF).toString());
+ }
+
+ /**
+ * java.lang.Integer#toString
+ */
+ public void test_toStringI() {
+ assertEquals("-1", Integer.toString(-1));
+ assertEquals("0", Integer.toString(0));
+ assertEquals("1", Integer.toString(1));
+ assertEquals("-1", Integer.toString(0xFFFFFFFF));
+ }
+
+ /**
+ * java.lang.Integer#valueOf(String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ assertEquals(new Integer(0), Integer.valueOf("0"));
+ assertEquals(new Integer(1), Integer.valueOf("1"));
+ assertEquals(new Integer(-1), Integer.valueOf("-1"));
+
+ try {
+ Integer.valueOf("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.valueOf("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.valueOf("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.valueOf(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Integer#valueOf(String, int)
+ */
+ public void test_valueOfLjava_lang_StringI() {
+ assertEquals(new Integer(0), Integer.valueOf("0", 10));
+ assertEquals(new Integer(1), Integer.valueOf("1", 10));
+ assertEquals(new Integer(-1), Integer.valueOf("-1", 10));
+
+ //must be consistent with Character.digit()
+ assertEquals(Character.digit('1', 2), Integer.valueOf("1", 2).byteValue());
+ assertEquals(Character.digit('F', 16), Integer.valueOf("F", 16).byteValue());
+
+ try {
+ Integer.valueOf("0x1", 10);
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.valueOf("9.2", 10);
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.valueOf("", 10);
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.valueOf(null, 10);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Integer#parseInt(String)
+ */
+ public void test_parseIntLjava_lang_String() {
+ assertEquals(0, Integer.parseInt("0"));
+ assertEquals(1, Integer.parseInt("1"));
+ assertEquals(-1, Integer.parseInt("-1"));
+
+ try {
+ Integer.parseInt("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.parseInt("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.parseInt("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.parseInt(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Integer#parseInt(String, int)
+ */
+ public void test_parseIntLjava_lang_StringI() {
+ assertEquals(0, Integer.parseInt("0", 10));
+ assertEquals(1, Integer.parseInt("1", 10));
+ assertEquals(-1, Integer.parseInt("-1", 10));
+
+ //must be consistent with Character.digit()
+ assertEquals(Character.digit('1', 2), Integer.parseInt("1", 2));
+ assertEquals(Character.digit('F', 16), Integer.parseInt("F", 16));
+
+ try {
+ Integer.parseInt("0x1", 10);
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.parseInt("9.2", 10);
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.parseInt("", 10);
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.parseInt(null, 10);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Integer#decode(String)
+ */
+ public void test_decodeLjava_lang_String() {
+ assertEquals(new Integer(0), Integer.decode("0"));
+ assertEquals(new Integer(1), Integer.decode("1"));
+ assertEquals(new Integer(-1), Integer.decode("-1"));
+ assertEquals(new Integer(0xF), Integer.decode("0xF"));
+ assertEquals(new Integer(0xF), Integer.decode("#F"));
+ assertEquals(new Integer(0xF), Integer.decode("0XF"));
+ assertEquals(new Integer(07), Integer.decode("07"));
+
+ try {
+ Integer.decode("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.decode("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Integer.decode(null);
+ //undocumented NPE, but seems consistent across JREs
+ fail("Expected NullPointerException with null string.");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Integer#doubleValue()
+ */
+ public void test_doubleValue() {
+ assertEquals(-1D, new Integer(-1).doubleValue(), 0D);
+ assertEquals(0D, new Integer(0).doubleValue(), 0D);
+ assertEquals(1D, new Integer(1).doubleValue(), 0D);
+ }
+
+ /**
+ * java.lang.Integer#floatValue()
+ */
+ public void test_floatValue() {
+ assertEquals(-1F, new Integer(-1).floatValue(), 0F);
+ assertEquals(0F, new Integer(0).floatValue(), 0F);
+ assertEquals(1F, new Integer(1).floatValue(), 0F);
+ }
+
+ /**
+ * java.lang.Integer#intValue()
+ */
+ public void test_intValue() {
+ assertEquals(-1, new Integer(-1).intValue());
+ assertEquals(0, new Integer(0).intValue());
+ assertEquals(1, new Integer(1).intValue());
+ }
+
+ /**
+ * java.lang.Integer#longValue()
+ */
+ public void test_longValue() {
+ assertEquals(-1L, new Integer(-1).longValue());
+ assertEquals(0L, new Integer(0).longValue());
+ assertEquals(1L, new Integer(1).longValue());
+ }
+
+ /**
+ * java.lang.Integer#shortValue()
+ */
+ public void test_shortValue() {
+ assertEquals(-1, new Integer(-1).shortValue());
+ assertEquals(0, new Integer(0).shortValue());
+ assertEquals(1, new Integer(1).shortValue());
+ }
+
+ /**
+ * java.lang.Integer#highestOneBit(int)
+ */
+ public void test_highestOneBitI() {
+ assertEquals(0x08, Integer.highestOneBit(0x0A));
+ assertEquals(0x08, Integer.highestOneBit(0x0B));
+ assertEquals(0x08, Integer.highestOneBit(0x0C));
+ assertEquals(0x08, Integer.highestOneBit(0x0F));
+ assertEquals(0x80, Integer.highestOneBit(0xFF));
+
+ assertEquals(0x080000, Integer.highestOneBit(0x0F1234));
+ assertEquals(0x800000, Integer.highestOneBit(0xFF9977));
+
+ assertEquals(0x80000000, Integer.highestOneBit(0xFFFFFFFF));
+
+ assertEquals(0, Integer.highestOneBit(0));
+ assertEquals(1, Integer.highestOneBit(1));
+ assertEquals(0x80000000, Integer.highestOneBit(-1));
+ }
+
+ /**
+ * java.lang.Integer#lowestOneBit(int)
+ */
+ public void test_lowestOneBitI() {
+ assertEquals(0x10, Integer.lowestOneBit(0xF0));
+
+ assertEquals(0x10, Integer.lowestOneBit(0x90));
+ assertEquals(0x10, Integer.lowestOneBit(0xD0));
+
+ assertEquals(0x10, Integer.lowestOneBit(0x123490));
+ assertEquals(0x10, Integer.lowestOneBit(0x1234D0));
+
+ assertEquals(0x100000, Integer.lowestOneBit(0x900000));
+ assertEquals(0x100000, Integer.lowestOneBit(0xD00000));
+
+ assertEquals(0x40, Integer.lowestOneBit(0x40));
+ assertEquals(0x40, Integer.lowestOneBit(0xC0));
+
+ assertEquals(0x4000, Integer.lowestOneBit(0x4000));
+ assertEquals(0x4000, Integer.lowestOneBit(0xC000));
+
+ assertEquals(0x4000, Integer.lowestOneBit(0x99994000));
+ assertEquals(0x4000, Integer.lowestOneBit(0x9999C000));
+
+ assertEquals(0, Integer.lowestOneBit(0));
+ assertEquals(1, Integer.lowestOneBit(1));
+ assertEquals(1, Integer.lowestOneBit(-1));
+ }
+
+ /**
+ * java.lang.Integer#numberOfLeadingZeros(int)
+ */
+ public void test_numberOfLeadingZerosI() {
+ assertEquals(32, Integer.numberOfLeadingZeros(0x0));
+ assertEquals(31, Integer.numberOfLeadingZeros(0x1));
+ assertEquals(30, Integer.numberOfLeadingZeros(0x2));
+ assertEquals(30, Integer.numberOfLeadingZeros(0x3));
+ assertEquals(29, Integer.numberOfLeadingZeros(0x4));
+ assertEquals(29, Integer.numberOfLeadingZeros(0x5));
+ assertEquals(29, Integer.numberOfLeadingZeros(0x6));
+ assertEquals(29, Integer.numberOfLeadingZeros(0x7));
+ assertEquals(28, Integer.numberOfLeadingZeros(0x8));
+ assertEquals(28, Integer.numberOfLeadingZeros(0x9));
+ assertEquals(28, Integer.numberOfLeadingZeros(0xA));
+ assertEquals(28, Integer.numberOfLeadingZeros(0xB));
+ assertEquals(28, Integer.numberOfLeadingZeros(0xC));
+ assertEquals(28, Integer.numberOfLeadingZeros(0xD));
+ assertEquals(28, Integer.numberOfLeadingZeros(0xE));
+ assertEquals(28, Integer.numberOfLeadingZeros(0xF));
+ assertEquals(27, Integer.numberOfLeadingZeros(0x10));
+ assertEquals(24, Integer.numberOfLeadingZeros(0x80));
+ assertEquals(24, Integer.numberOfLeadingZeros(0xF0));
+ assertEquals(23, Integer.numberOfLeadingZeros(0x100));
+ assertEquals(20, Integer.numberOfLeadingZeros(0x800));
+ assertEquals(20, Integer.numberOfLeadingZeros(0xF00));
+ assertEquals(19, Integer.numberOfLeadingZeros(0x1000));
+ assertEquals(16, Integer.numberOfLeadingZeros(0x8000));
+ assertEquals(16, Integer.numberOfLeadingZeros(0xF000));
+ assertEquals(15, Integer.numberOfLeadingZeros(0x10000));
+ assertEquals(12, Integer.numberOfLeadingZeros(0x80000));
+ assertEquals(12, Integer.numberOfLeadingZeros(0xF0000));
+ assertEquals(11, Integer.numberOfLeadingZeros(0x100000));
+ assertEquals(8, Integer.numberOfLeadingZeros(0x800000));
+ assertEquals(8, Integer.numberOfLeadingZeros(0xF00000));
+ assertEquals(7, Integer.numberOfLeadingZeros(0x1000000));
+ assertEquals(4, Integer.numberOfLeadingZeros(0x8000000));
+ assertEquals(4, Integer.numberOfLeadingZeros(0xF000000));
+ assertEquals(3, Integer.numberOfLeadingZeros(0x10000000));
+ assertEquals(0, Integer.numberOfLeadingZeros(0x80000000));
+ assertEquals(0, Integer.numberOfLeadingZeros(0xF0000000));
+
+ assertEquals(1, Integer.numberOfLeadingZeros(Integer.MAX_VALUE));
+ assertEquals(0, Integer.numberOfLeadingZeros(Integer.MIN_VALUE));
+ }
+
+ /**
+ * java.lang.Integer#numberOfTrailingZeros(int)
+ */
+ public void test_numberOfTrailingZerosI() {
+ assertEquals(32, Integer.numberOfTrailingZeros(0x0));
+ assertEquals(31, Integer.numberOfTrailingZeros(Integer.MIN_VALUE));
+ assertEquals(0, Integer.numberOfTrailingZeros(Integer.MAX_VALUE));
+
+ assertEquals(0, Integer.numberOfTrailingZeros(0x1));
+ assertEquals(3, Integer.numberOfTrailingZeros(0x8));
+ assertEquals(0, Integer.numberOfTrailingZeros(0xF));
+
+ assertEquals(4, Integer.numberOfTrailingZeros(0x10));
+ assertEquals(7, Integer.numberOfTrailingZeros(0x80));
+ assertEquals(4, Integer.numberOfTrailingZeros(0xF0));
+
+ assertEquals(8, Integer.numberOfTrailingZeros(0x100));
+ assertEquals(11, Integer.numberOfTrailingZeros(0x800));
+ assertEquals(8, Integer.numberOfTrailingZeros(0xF00));
+
+ assertEquals(12, Integer.numberOfTrailingZeros(0x1000));
+ assertEquals(15, Integer.numberOfTrailingZeros(0x8000));
+ assertEquals(12, Integer.numberOfTrailingZeros(0xF000));
+
+ assertEquals(16, Integer.numberOfTrailingZeros(0x10000));
+ assertEquals(19, Integer.numberOfTrailingZeros(0x80000));
+ assertEquals(16, Integer.numberOfTrailingZeros(0xF0000));
+
+ assertEquals(20, Integer.numberOfTrailingZeros(0x100000));
+ assertEquals(23, Integer.numberOfTrailingZeros(0x800000));
+ assertEquals(20, Integer.numberOfTrailingZeros(0xF00000));
+
+ assertEquals(24, Integer.numberOfTrailingZeros(0x1000000));
+ assertEquals(27, Integer.numberOfTrailingZeros(0x8000000));
+ assertEquals(24, Integer.numberOfTrailingZeros(0xF000000));
+
+ assertEquals(28, Integer.numberOfTrailingZeros(0x10000000));
+ assertEquals(31, Integer.numberOfTrailingZeros(0x80000000));
+ assertEquals(28, Integer.numberOfTrailingZeros(0xF0000000));
+ }
+
+ /**
+ * java.lang.Integer#bitCount(int)
+ */
+ public void test_bitCountI() {
+ assertEquals(0, Integer.bitCount(0x0));
+ assertEquals(1, Integer.bitCount(0x1));
+ assertEquals(1, Integer.bitCount(0x2));
+ assertEquals(2, Integer.bitCount(0x3));
+ assertEquals(1, Integer.bitCount(0x4));
+ assertEquals(2, Integer.bitCount(0x5));
+ assertEquals(2, Integer.bitCount(0x6));
+ assertEquals(3, Integer.bitCount(0x7));
+ assertEquals(1, Integer.bitCount(0x8));
+ assertEquals(2, Integer.bitCount(0x9));
+ assertEquals(2, Integer.bitCount(0xA));
+ assertEquals(3, Integer.bitCount(0xB));
+ assertEquals(2, Integer.bitCount(0xC));
+ assertEquals(3, Integer.bitCount(0xD));
+ assertEquals(3, Integer.bitCount(0xE));
+ assertEquals(4, Integer.bitCount(0xF));
+
+ assertEquals(8, Integer.bitCount(0xFF));
+ assertEquals(12, Integer.bitCount(0xFFF));
+ assertEquals(16, Integer.bitCount(0xFFFF));
+ assertEquals(20, Integer.bitCount(0xFFFFF));
+ assertEquals(24, Integer.bitCount(0xFFFFFF));
+ assertEquals(28, Integer.bitCount(0xFFFFFFF));
+ assertEquals(32, Integer.bitCount(0xFFFFFFFF));
+ }
+
+ /**
+ * java.lang.Integer#rotateLeft(int, int)
+ */
+ public void test_rotateLeftII() {
+ assertEquals(0xF, Integer.rotateLeft(0xF, 0));
+ assertEquals(0xF0, Integer.rotateLeft(0xF, 4));
+ assertEquals(0xF00, Integer.rotateLeft(0xF, 8));
+ assertEquals(0xF000, Integer.rotateLeft(0xF, 12));
+ assertEquals(0xF0000, Integer.rotateLeft(0xF, 16));
+ assertEquals(0xF00000, Integer.rotateLeft(0xF, 20));
+ assertEquals(0xF000000, Integer.rotateLeft(0xF, 24));
+ assertEquals(0xF0000000, Integer.rotateLeft(0xF, 28));
+ assertEquals(0xF0000000, Integer.rotateLeft(0xF0000000, 32));
+ }
+
+ /**
+ * java.lang.Integer#rotateRight(int, int)
+ */
+ public void test_rotateRightII() {
+ assertEquals(0xF, Integer.rotateRight(0xF0, 4));
+ assertEquals(0xF, Integer.rotateRight(0xF00, 8));
+ assertEquals(0xF, Integer.rotateRight(0xF000, 12));
+ assertEquals(0xF, Integer.rotateRight(0xF0000, 16));
+ assertEquals(0xF, Integer.rotateRight(0xF00000, 20));
+ assertEquals(0xF, Integer.rotateRight(0xF000000, 24));
+ assertEquals(0xF, Integer.rotateRight(0xF0000000, 28));
+ assertEquals(0xF0000000, Integer.rotateRight(0xF0000000, 32));
+ assertEquals(0xF0000000, Integer.rotateRight(0xF0000000, 0));
+
+ }
+
+ /**
+ * java.lang.Integer#reverseBytes(int)
+ */
+ public void test_reverseBytesI() {
+ assertEquals(0xAABBCCDD, Integer.reverseBytes(0xDDCCBBAA));
+ assertEquals(0x11223344, Integer.reverseBytes(0x44332211));
+ assertEquals(0x00112233, Integer.reverseBytes(0x33221100));
+ assertEquals(0x20000002, Integer.reverseBytes(0x02000020));
+ }
+
+ /**
+ * java.lang.Integer#reverse(int)
+ */
+ public void test_reverseI() {
+ assertEquals(-1, Integer.reverse(-1));
+ assertEquals(0x80000000, Integer.reverse(1));
+ }
+
+ /**
+ * java.lang.Integer#signum(int)
+ */
+ public void test_signumI() {
+ for (int i = -128; i < 0; i++) {
+ assertEquals(-1, Integer.signum(i));
+ }
+ assertEquals(0, Integer.signum(0));
+ for (int i = 1; i <= 127; i++) {
+ assertEquals(1, Integer.signum(i));
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InternalErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InternalErrorTest.java
new file mode 100644
index 0000000..d2ea2de
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InternalErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class InternalErrorTest extends TestCase {
+
+ /**
+ * java.lang.InternalError#InternalError()
+ */
+ public void test_Constructor() {
+ InternalError e = new InternalError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.InternalError#InternalError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ InternalError e = new InternalError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InterruptedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InterruptedExceptionTest.java
new file mode 100644
index 0000000..ecaac75
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/InterruptedExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class InterruptedExceptionTest extends TestCase {
+
+ /**
+ * java.lang.InterruptedException#InterruptedException()
+ */
+ public void test_Constructor() {
+ InterruptedException e = new InterruptedException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.InterruptedException#InterruptedException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ InterruptedException e = new InterruptedException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/LinkageErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/LinkageErrorTest.java
new file mode 100644
index 0000000..33ecc16
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/LinkageErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class LinkageErrorTest extends TestCase {
+
+ /**
+ * java.lang.LinkageError#LinkageError()
+ */
+ public void test_Constructor() {
+ LinkageError e = new LinkageError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.LinkageError#LinkageError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ LinkageError e = new LinkageError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/LongTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/LongTest.java
new file mode 100644
index 0000000..9da75cf
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/LongTest.java
@@ -0,0 +1,1067 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+public class LongTest extends TestCase {
+ private Properties orgProps;
+
+ @Override
+ protected void setUp() {
+ orgProps = System.getProperties();
+ }
+
+ @Override
+ protected void tearDown() {
+ System.setProperties(orgProps);
+ }
+
+ /**
+ * java.lang.Long#byteValue()
+ */
+ public void test_byteValue() {
+ // Test for method byte java.lang.Long.byteValue()
+ Long l = new Long(127);
+ assertEquals("Returned incorrect byte value", 127, l.byteValue());
+ assertEquals("Returned incorrect byte value", -1, new Long(Long.MAX_VALUE)
+ .byteValue());
+ }
+
+ /**
+ * java.lang.Long#compareTo(java.lang.Long)
+ */
+ public void test_compareToLjava_lang_Long() {
+ // Test for method int java.lang.Long.compareTo(java.lang.Long)
+ assertTrue("-2 compared to 1 gave non-negative answer", new Long(-2L)
+ .compareTo(new Long(1L)) < 0);
+ assertEquals("-2 compared to -2 gave non-zero answer", 0, new Long(-2L)
+ .compareTo(new Long(-2L)));
+ assertTrue("3 compared to 2 gave non-positive answer", new Long(3L)
+ .compareTo(new Long(2L)) > 0);
+
+ try {
+ new Long(0).compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Long#decode(java.lang.String)
+ */
+ public void test_decodeLjava_lang_String2() {
+ // Test for method java.lang.Long
+ // java.lang.Long.decode(java.lang.String)
+ assertEquals("Returned incorrect value for hex string", 255L, Long.decode(
+ "0xFF").longValue());
+ assertEquals("Returned incorrect value for dec string", -89000L, Long.decode(
+ "-89000").longValue());
+ assertEquals("Returned incorrect value for 0 decimal", 0, Long.decode("0")
+ .longValue());
+ assertEquals("Returned incorrect value for 0 hex", 0, Long.decode("0x0")
+ .longValue());
+ assertTrue(
+ "Returned incorrect value for most negative value decimal",
+ Long.decode("-9223372036854775808").longValue() == 0x8000000000000000L);
+ assertTrue(
+ "Returned incorrect value for most negative value hex",
+ Long.decode("-0x8000000000000000").longValue() == 0x8000000000000000L);
+ assertTrue(
+ "Returned incorrect value for most positive value decimal",
+ Long.decode("9223372036854775807").longValue() == 0x7fffffffffffffffL);
+ assertTrue(
+ "Returned incorrect value for most positive value hex",
+ Long.decode("0x7fffffffffffffff").longValue() == 0x7fffffffffffffffL);
+ assertTrue("Failed for 07654321765432", Long.decode("07654321765432")
+ .longValue() == 07654321765432l);
+
+ boolean exception = false;
+ try {
+ Long
+ .decode("999999999999999999999999999999999999999999999999999999");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for value > ilong", exception);
+
+ exception = false;
+ try {
+ Long.decode("9223372036854775808");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Long.decode("-9223372036854775809");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Long.decode("0x8000000000000000");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Long.decode("-0x8000000000000001");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Long.decode("42325917317067571199");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for 42325917317067571199",
+ exception);
+ }
+
+ /**
+ * java.lang.Long#getLong(java.lang.String)
+ */
+ public void test_getLongLjava_lang_String() {
+ // Test for method java.lang.Long
+ // java.lang.Long.getLong(java.lang.String)
+ Properties tProps = new Properties();
+ tProps.put("testLong", "99");
+ System.setProperties(tProps);
+ assertTrue("returned incorrect Long", Long.getLong("testLong").equals(
+ new Long(99)));
+ assertNull("returned incorrect default Long",
+ Long.getLong("ff"));
+ }
+
+ /**
+ * java.lang.Long#getLong(java.lang.String, long)
+ */
+ public void test_getLongLjava_lang_StringJ() {
+ // Test for method java.lang.Long
+ // java.lang.Long.getLong(java.lang.String, long)
+ Properties tProps = new Properties();
+ tProps.put("testLong", "99");
+ System.setProperties(tProps);
+ assertTrue("returned incorrect Long", Long.getLong("testLong", 4L)
+ .equals(new Long(99)));
+ assertTrue("returned incorrect default Long", Long.getLong("ff", 4L)
+ .equals(new Long(4)));
+ }
+
+ /**
+ * java.lang.Long#getLong(java.lang.String, java.lang.Long)
+ */
+ public void test_getLongLjava_lang_StringLjava_lang_Long() {
+ // Test for method java.lang.Long
+ // java.lang.Long.getLong(java.lang.String, java.lang.Long)
+ Properties tProps = new Properties();
+ tProps.put("testLong", "99");
+ System.setProperties(tProps);
+ assertTrue("returned incorrect Long", Long.getLong("testLong",
+ new Long(4)).equals(new Long(99)));
+ assertTrue("returned incorrect default Long", Long.getLong("ff",
+ new Long(4)).equals(new Long(4)));
+ }
+
+ /**
+ * java.lang.Long#parseLong(java.lang.String)
+ */
+ public void test_parseLongLjava_lang_String2() {
+ // Test for method long java.lang.Long.parseLong(java.lang.String)
+
+ long l = Long.parseLong("89000000005");
+ assertEquals("Parsed to incorrect long value", 89000000005L, l);
+ assertEquals("Returned incorrect value for 0", 0, Long.parseLong("0"));
+ assertTrue("Returned incorrect value for most negative value", Long
+ .parseLong("-9223372036854775808") == 0x8000000000000000L);
+ assertTrue("Returned incorrect value for most positive value", Long
+ .parseLong("9223372036854775807") == 0x7fffffffffffffffL);
+
+ boolean exception = false;
+ try {
+ Long.parseLong("9223372036854775808");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Long.parseLong("-9223372036854775809");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+ }
+
+ /**
+ * java.lang.Long#parseLong(java.lang.String, int)
+ */
+ public void test_parseLongLjava_lang_StringI() {
+ // Test for method long java.lang.Long.parseLong(java.lang.String, int)
+ assertEquals("Returned incorrect value",
+ 100000000L, Long.parseLong("100000000", 10));
+ assertEquals("Returned incorrect value from hex string", 68719476735L, Long.parseLong(
+ "FFFFFFFFF", 16));
+ assertTrue("Returned incorrect value from octal string: "
+ + Long.parseLong("77777777777"), Long.parseLong("77777777777",
+ 8) == 8589934591L);
+ assertEquals("Returned incorrect value for 0 hex", 0, Long
+ .parseLong("0", 16));
+ assertTrue("Returned incorrect value for most negative value hex", Long
+ .parseLong("-8000000000000000", 16) == 0x8000000000000000L);
+ assertTrue("Returned incorrect value for most positive value hex", Long
+ .parseLong("7fffffffffffffff", 16) == 0x7fffffffffffffffL);
+ assertEquals("Returned incorrect value for 0 decimal", 0, Long.parseLong(
+ "0", 10));
+ assertTrue(
+ "Returned incorrect value for most negative value decimal",
+ Long.parseLong("-9223372036854775808", 10) == 0x8000000000000000L);
+ assertTrue(
+ "Returned incorrect value for most positive value decimal",
+ Long.parseLong("9223372036854775807", 10) == 0x7fffffffffffffffL);
+
+ boolean exception = false;
+ try {
+ Long.parseLong("999999999999", 8);
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception when passed invalid string",
+ exception);
+
+ exception = false;
+ try {
+ Long.parseLong("9223372036854775808", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Long.parseLong("-9223372036854775809", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Long.parseLong("8000000000000000", 16);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Long.parseLong("-8000000000000001", 16);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MIN_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Long.parseLong("42325917317067571199", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for 42325917317067571199",
+ exception);
+ }
+
+ /**
+ * java.lang.Long#toBinaryString(long)
+ */
+ public void test_toBinaryStringJ() {
+ // Test for method java.lang.String java.lang.Long.toBinaryString(long)
+ assertEquals("Incorrect binary string returned", "11011001010010010000", Long.toBinaryString(
+ 890000L));
+ assertEquals("Incorrect binary string returned",
+
+ "1000000000000000000000000000000000000000000000000000000000000000", Long
+ .toBinaryString(Long.MIN_VALUE)
+ );
+ assertEquals("Incorrect binary string returned",
+
+ "111111111111111111111111111111111111111111111111111111111111111", Long
+ .toBinaryString(Long.MAX_VALUE)
+ );
+ }
+
+ /**
+ * java.lang.Long#toHexString(long)
+ */
+ public void test_toHexStringJ() {
+ // Test for method java.lang.String java.lang.Long.toHexString(long)
+ assertEquals("Incorrect hex string returned", "54e0845", Long.toHexString(89000005L)
+ );
+ assertEquals("Incorrect hex string returned", "8000000000000000", Long.toHexString(
+ Long.MIN_VALUE));
+ assertEquals("Incorrect hex string returned", "7fffffffffffffff", Long.toHexString(
+ Long.MAX_VALUE));
+ }
+
+ /**
+ * java.lang.Long#toOctalString(long)
+ */
+ public void test_toOctalStringJ() {
+ // Test for method java.lang.String java.lang.Long.toOctalString(long)
+ assertEquals("Returned incorrect oct string", "77777777777", Long.toOctalString(
+ 8589934591L));
+ assertEquals("Returned incorrect oct string", "1000000000000000000000", Long.toOctalString(
+ Long.MIN_VALUE));
+ assertEquals("Returned incorrect oct string", "777777777777777777777", Long.toOctalString(
+ Long.MAX_VALUE));
+ }
+
+ /**
+ * java.lang.Long#toString()
+ */
+ public void test_toString2() {
+ // Test for method java.lang.String java.lang.Long.toString()
+ Long l = new Long(89000000005L);
+ assertEquals("Returned incorrect String",
+ "89000000005", l.toString());
+ assertEquals("Returned incorrect String", "-9223372036854775808", new Long(Long.MIN_VALUE)
+ .toString());
+ assertEquals("Returned incorrect String", "9223372036854775807", new Long(Long.MAX_VALUE)
+ .toString());
+ }
+
+ /**
+ * java.lang.Long#toString(long)
+ */
+ public void test_toStringJ2() {
+ // Test for method java.lang.String java.lang.Long.toString(long)
+
+ assertEquals("Returned incorrect String", "89000000005", Long.toString(89000000005L)
+ );
+ assertEquals("Returned incorrect String", "-9223372036854775808", Long.toString(Long.MIN_VALUE)
+ );
+ assertEquals("Returned incorrect String", "9223372036854775807", Long.toString(Long.MAX_VALUE)
+ );
+ }
+
+ /**
+ * java.lang.Long#toString(long, int)
+ */
+ public void test_toStringJI() {
+ // Test for method java.lang.String java.lang.Long.toString(long, int)
+ assertEquals("Returned incorrect dec string", "100000000", Long.toString(100000000L,
+ 10));
+ assertEquals("Returned incorrect hex string", "fffffffff", Long.toString(68719476735L,
+ 16));
+ assertEquals("Returned incorrect oct string", "77777777777", Long.toString(8589934591L,
+ 8));
+ assertEquals("Returned incorrect bin string",
+ "1111111111111111111111111111111111111111111", Long.toString(
+ 8796093022207L, 2));
+ assertEquals("Returned incorrect min string", "-9223372036854775808", Long.toString(
+ 0x8000000000000000L, 10));
+ assertEquals("Returned incorrect max string", "9223372036854775807", Long.toString(
+ 0x7fffffffffffffffL, 10));
+ assertEquals("Returned incorrect min string", "-8000000000000000", Long.toString(
+ 0x8000000000000000L, 16));
+ assertEquals("Returned incorrect max string", "7fffffffffffffff", Long.toString(
+ 0x7fffffffffffffffL, 16));
+ }
+
+ /**
+ * java.lang.Long#valueOf(java.lang.String)
+ */
+ public void test_valueOfLjava_lang_String2() {
+ // Test for method java.lang.Long
+ // java.lang.Long.valueOf(java.lang.String)
+ assertEquals("Returned incorrect value", 100000000L, Long.valueOf("100000000")
+ .longValue());
+ assertTrue("Returned incorrect value", Long.valueOf(
+ "9223372036854775807").longValue() == Long.MAX_VALUE);
+ assertTrue("Returned incorrect value", Long.valueOf(
+ "-9223372036854775808").longValue() == Long.MIN_VALUE);
+
+ boolean exception = false;
+ try {
+ Long
+ .valueOf("999999999999999999999999999999999999999999999999999999999999");
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception when passed invalid string",
+ exception);
+
+ exception = false;
+ try {
+ Long.valueOf("9223372036854775808");
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception when passed invalid string",
+ exception);
+
+ exception = false;
+ try {
+ Long.valueOf("-9223372036854775809");
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception when passed invalid string",
+ exception);
+ }
+
+ /**
+ * java.lang.Long#valueOf(java.lang.String, int)
+ */
+ public void test_valueOfLjava_lang_StringI() {
+ // Test for method java.lang.Long
+ // java.lang.Long.valueOf(java.lang.String, int)
+ assertEquals("Returned incorrect value", 100000000L, Long.valueOf("100000000", 10)
+ .longValue());
+ assertEquals("Returned incorrect value from hex string", 68719476735L, Long.valueOf(
+ "FFFFFFFFF", 16).longValue());
+ assertTrue("Returned incorrect value from octal string: "
+ + Long.valueOf("77777777777", 8).toString(), Long.valueOf(
+ "77777777777", 8).longValue() == 8589934591L);
+ assertTrue("Returned incorrect value", Long.valueOf(
+ "9223372036854775807", 10).longValue() == Long.MAX_VALUE);
+ assertTrue("Returned incorrect value", Long.valueOf(
+ "-9223372036854775808", 10).longValue() == Long.MIN_VALUE);
+ assertTrue("Returned incorrect value", Long.valueOf("7fffffffffffffff",
+ 16).longValue() == Long.MAX_VALUE);
+ assertTrue("Returned incorrect value", Long.valueOf(
+ "-8000000000000000", 16).longValue() == Long.MIN_VALUE);
+
+ boolean exception = false;
+ try {
+ Long.valueOf("999999999999", 8);
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception when passed invalid string",
+ exception);
+
+ exception = false;
+ try {
+ Long.valueOf("9223372036854775808", 10);
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception when passed invalid string",
+ exception);
+
+ exception = false;
+ try {
+ Long.valueOf("-9223372036854775809", 10);
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception when passed invalid string",
+ exception);
+ }
+
+ /**
+ * java.lang.Long#valueOf(long)
+ */
+ public void test_valueOfJ() {
+ assertEquals(new Long(Long.MIN_VALUE), Long.valueOf(Long.MIN_VALUE));
+ assertEquals(new Long(Long.MAX_VALUE), Long.valueOf(Long.MAX_VALUE));
+ assertEquals(new Long(0), Long.valueOf(0));
+
+ long lng = -128;
+ while (lng < 128) {
+ assertEquals(new Long(lng), Long.valueOf(lng));
+ assertSame(Long.valueOf(lng), Long.valueOf(lng));
+ lng++;
+ }
+ }
+
+ /**
+ * java.lang.Long#hashCode()
+ */
+ public void test_hashCode() {
+ assertEquals((int) (1L ^ (1L >>> 32)), new Long(1).hashCode());
+ assertEquals((int) (2L ^ (2L >>> 32)), new Long(2).hashCode());
+ assertEquals((int) (0L ^ (0L >>> 32)), new Long(0).hashCode());
+ assertEquals((int) (-1L ^ (-1L >>> 32)), new Long(-1).hashCode());
+ }
+
+ /**
+ * java.lang.Long#Long(String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ assertEquals(new Long(0), new Long("0"));
+ assertEquals(new Long(1), new Long("1"));
+ assertEquals(new Long(-1), new Long("-1"));
+
+ try {
+ new Long("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Long("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Long("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Long(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Long#Long
+ */
+ public void test_ConstructorJ() {
+ assertEquals(1, new Long(1).intValue());
+ assertEquals(2, new Long(2).intValue());
+ assertEquals(0, new Long(0).intValue());
+ assertEquals(-1, new Long(-1).intValue());
+ }
+
+ /**
+ * java.lang.Long#byteValue()
+ */
+ public void test_booleanValue() {
+ assertEquals(1, new Long(1).byteValue());
+ assertEquals(2, new Long(2).byteValue());
+ assertEquals(0, new Long(0).byteValue());
+ assertEquals(-1, new Long(-1).byteValue());
+ }
+
+ /**
+ * java.lang.Long#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertEquals(new Long(0), Long.valueOf(0));
+ assertEquals(new Long(1), Long.valueOf(1));
+ assertEquals(new Long(-1), Long.valueOf(-1));
+
+ Long fixture = new Long(25);
+ assertEquals(fixture, fixture);
+ assertFalse(fixture.equals(null));
+ assertFalse(fixture.equals("Not a Long"));
+ }
+
+ /**
+ * java.lang.Long#toString()
+ */
+ public void test_toString() {
+ assertEquals("-1", new Long(-1).toString());
+ assertEquals("0", new Long(0).toString());
+ assertEquals("1", new Long(1).toString());
+ assertEquals("-1", new Long(0xFFFFFFFF).toString());
+ }
+
+ /**
+ * java.lang.Long#toString
+ */
+ public void test_toStringJ() {
+ assertEquals("-1", Long.toString(-1));
+ assertEquals("0", Long.toString(0));
+ assertEquals("1", Long.toString(1));
+ assertEquals("-1", Long.toString(0xFFFFFFFF));
+ }
+
+ /**
+ * java.lang.Long#valueOf(String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ assertEquals(new Long(0), Long.valueOf("0"));
+ assertEquals(new Long(1), Long.valueOf("1"));
+ assertEquals(new Long(-1), Long.valueOf("-1"));
+
+ try {
+ Long.valueOf("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.valueOf("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.valueOf("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.valueOf(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Long#valueOf(String, long)
+ */
+ public void test_valueOfLjava_lang_StringJ() {
+ assertEquals(new Long(0), Long.valueOf("0", 10));
+ assertEquals(new Long(1), Long.valueOf("1", 10));
+ assertEquals(new Long(-1), Long.valueOf("-1", 10));
+
+ //must be consistent with Character.digit()
+ assertEquals(Character.digit('1', 2), Long.valueOf("1", 2).byteValue());
+ assertEquals(Character.digit('F', 16), Long.valueOf("F", 16).byteValue());
+
+ try {
+ Long.valueOf("0x1", 10);
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.valueOf("9.2", 10);
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.valueOf("", 10);
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.valueOf(null, 10);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Long#parseLong(String)
+ */
+ public void test_parseLongLjava_lang_String() {
+ assertEquals(0, Long.parseLong("0"));
+ assertEquals(1, Long.parseLong("1"));
+ assertEquals(-1, Long.parseLong("-1"));
+
+ try {
+ Long.parseLong("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.parseLong("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.parseLong("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.parseLong(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Long#parseLong(String, long)
+ */
+ public void test_parseLongLjava_lang_StringJ() {
+ assertEquals(0, Long.parseLong("0", 10));
+ assertEquals(1, Long.parseLong("1", 10));
+ assertEquals(-1, Long.parseLong("-1", 10));
+
+ //must be consistent with Character.digit()
+ assertEquals(Character.digit('1', 2), Long.parseLong("1", 2));
+ assertEquals(Character.digit('F', 16), Long.parseLong("F", 16));
+
+ try {
+ Long.parseLong("0x1", 10);
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.parseLong("9.2", 10);
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.parseLong("", 10);
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.parseLong(null, 10);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Long#decode(String)
+ */
+ public void test_decodeLjava_lang_String() {
+ assertEquals(new Long(0), Long.decode("0"));
+ assertEquals(new Long(1), Long.decode("1"));
+ assertEquals(new Long(-1), Long.decode("-1"));
+ assertEquals(new Long(0xF), Long.decode("0xF"));
+ assertEquals(new Long(0xF), Long.decode("#F"));
+ assertEquals(new Long(0xF), Long.decode("0XF"));
+ assertEquals(new Long(07), Long.decode("07"));
+
+ try {
+ Long.decode("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.decode("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Long.decode(null);
+ //undocumented NPE, but seems consistent across JREs
+ fail("Expected NullPointerException with null string.");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Long#doubleValue()
+ */
+ public void test_doubleValue() {
+ assertEquals(-1D, new Long(-1).doubleValue(), 0D);
+ assertEquals(0D, new Long(0).doubleValue(), 0D);
+ assertEquals(1D, new Long(1).doubleValue(), 0D);
+ }
+
+ /**
+ * java.lang.Long#floatValue()
+ */
+ public void test_floatValue() {
+ assertEquals(-1F, new Long(-1).floatValue(), 0F);
+ assertEquals(0F, new Long(0).floatValue(), 0F);
+ assertEquals(1F, new Long(1).floatValue(), 0F);
+ }
+
+ /**
+ * java.lang.Long#intValue()
+ */
+ public void test_intValue() {
+ assertEquals(-1, new Long(-1).intValue());
+ assertEquals(0, new Long(0).intValue());
+ assertEquals(1, new Long(1).intValue());
+ }
+
+ /**
+ * java.lang.Long#longValue()
+ */
+ public void test_longValue() {
+ assertEquals(-1L, new Long(-1).longValue());
+ assertEquals(0L, new Long(0).longValue());
+ assertEquals(1L, new Long(1).longValue());
+ }
+
+ /**
+ * java.lang.Long#shortValue()
+ */
+ public void test_shortValue() {
+ assertEquals(-1, new Long(-1).shortValue());
+ assertEquals(0, new Long(0).shortValue());
+ assertEquals(1, new Long(1).shortValue());
+ }
+
+ /**
+ * java.lang.Long#highestOneBit(long)
+ */
+ public void test_highestOneBitJ() {
+ assertEquals(0x08, Long.highestOneBit(0x0A));
+ assertEquals(0x08, Long.highestOneBit(0x0B));
+ assertEquals(0x08, Long.highestOneBit(0x0C));
+ assertEquals(0x08, Long.highestOneBit(0x0F));
+ assertEquals(0x80, Long.highestOneBit(0xFF));
+
+ assertEquals(0x080000, Long.highestOneBit(0x0F1234));
+ assertEquals(0x800000, Long.highestOneBit(0xFF9977));
+
+ assertEquals(0x8000000000000000L, Long.highestOneBit(0xFFFFFFFFFFFFFFFFL));
+
+ assertEquals(0, Long.highestOneBit(0));
+ assertEquals(1, Long.highestOneBit(1));
+ assertEquals(0x8000000000000000L, Long.highestOneBit(-1));
+ }
+
+ /**
+ * java.lang.Long#lowestOneBit(long)
+ */
+ public void test_lowestOneBitJ() {
+ assertEquals(0x10, Long.lowestOneBit(0xF0));
+
+ assertEquals(0x10, Long.lowestOneBit(0x90));
+ assertEquals(0x10, Long.lowestOneBit(0xD0));
+
+ assertEquals(0x10, Long.lowestOneBit(0x123490));
+ assertEquals(0x10, Long.lowestOneBit(0x1234D0));
+
+ assertEquals(0x100000, Long.lowestOneBit(0x900000));
+ assertEquals(0x100000, Long.lowestOneBit(0xD00000));
+
+ assertEquals(0x40, Long.lowestOneBit(0x40));
+ assertEquals(0x40, Long.lowestOneBit(0xC0));
+
+ assertEquals(0x4000, Long.lowestOneBit(0x4000));
+ assertEquals(0x4000, Long.lowestOneBit(0xC000));
+
+ assertEquals(0x4000, Long.lowestOneBit(0x99994000));
+ assertEquals(0x4000, Long.lowestOneBit(0x9999C000));
+
+ assertEquals(0, Long.lowestOneBit(0));
+ assertEquals(1, Long.lowestOneBit(1));
+ assertEquals(1, Long.lowestOneBit(-1));
+ }
+
+ /**
+ * java.lang.Long#numberOfLeadingZeros(long)
+ */
+ public void test_numberOfLeadingZerosJ() {
+ assertEquals(64, Long.numberOfLeadingZeros(0x0L));
+ assertEquals(63, Long.numberOfLeadingZeros(0x1));
+ assertEquals(62, Long.numberOfLeadingZeros(0x2));
+ assertEquals(62, Long.numberOfLeadingZeros(0x3));
+ assertEquals(61, Long.numberOfLeadingZeros(0x4));
+ assertEquals(61, Long.numberOfLeadingZeros(0x5));
+ assertEquals(61, Long.numberOfLeadingZeros(0x6));
+ assertEquals(61, Long.numberOfLeadingZeros(0x7));
+ assertEquals(60, Long.numberOfLeadingZeros(0x8));
+ assertEquals(60, Long.numberOfLeadingZeros(0x9));
+ assertEquals(60, Long.numberOfLeadingZeros(0xA));
+ assertEquals(60, Long.numberOfLeadingZeros(0xB));
+ assertEquals(60, Long.numberOfLeadingZeros(0xC));
+ assertEquals(60, Long.numberOfLeadingZeros(0xD));
+ assertEquals(60, Long.numberOfLeadingZeros(0xE));
+ assertEquals(60, Long.numberOfLeadingZeros(0xF));
+ assertEquals(59, Long.numberOfLeadingZeros(0x10));
+ assertEquals(56, Long.numberOfLeadingZeros(0x80));
+ assertEquals(56, Long.numberOfLeadingZeros(0xF0));
+ assertEquals(55, Long.numberOfLeadingZeros(0x100));
+ assertEquals(52, Long.numberOfLeadingZeros(0x800));
+ assertEquals(52, Long.numberOfLeadingZeros(0xF00));
+ assertEquals(51, Long.numberOfLeadingZeros(0x1000));
+ assertEquals(48, Long.numberOfLeadingZeros(0x8000));
+ assertEquals(48, Long.numberOfLeadingZeros(0xF000));
+ assertEquals(47, Long.numberOfLeadingZeros(0x10000));
+ assertEquals(44, Long.numberOfLeadingZeros(0x80000));
+ assertEquals(44, Long.numberOfLeadingZeros(0xF0000));
+ assertEquals(43, Long.numberOfLeadingZeros(0x100000));
+ assertEquals(40, Long.numberOfLeadingZeros(0x800000));
+ assertEquals(40, Long.numberOfLeadingZeros(0xF00000));
+ assertEquals(39, Long.numberOfLeadingZeros(0x1000000));
+ assertEquals(36, Long.numberOfLeadingZeros(0x8000000));
+ assertEquals(36, Long.numberOfLeadingZeros(0xF000000));
+ assertEquals(35, Long.numberOfLeadingZeros(0x10000000));
+ assertEquals(0, Long.numberOfLeadingZeros(0x80000000));
+ assertEquals(0, Long.numberOfLeadingZeros(0xF0000000));
+
+ assertEquals(1, Long.numberOfLeadingZeros(Long.MAX_VALUE));
+ assertEquals(0, Long.numberOfLeadingZeros(Long.MIN_VALUE));
+ }
+
+ /**
+ * java.lang.Long#numberOfTrailingZeros(long)
+ */
+ public void test_numberOfTrailingZerosJ() {
+ assertEquals(64, Long.numberOfTrailingZeros(0x0));
+ assertEquals(63, Long.numberOfTrailingZeros(Long.MIN_VALUE));
+ assertEquals(0, Long.numberOfTrailingZeros(Long.MAX_VALUE));
+
+ assertEquals(0, Long.numberOfTrailingZeros(0x1));
+ assertEquals(3, Long.numberOfTrailingZeros(0x8));
+ assertEquals(0, Long.numberOfTrailingZeros(0xF));
+
+ assertEquals(4, Long.numberOfTrailingZeros(0x10));
+ assertEquals(7, Long.numberOfTrailingZeros(0x80));
+ assertEquals(4, Long.numberOfTrailingZeros(0xF0));
+
+ assertEquals(8, Long.numberOfTrailingZeros(0x100));
+ assertEquals(11, Long.numberOfTrailingZeros(0x800));
+ assertEquals(8, Long.numberOfTrailingZeros(0xF00));
+
+ assertEquals(12, Long.numberOfTrailingZeros(0x1000));
+ assertEquals(15, Long.numberOfTrailingZeros(0x8000));
+ assertEquals(12, Long.numberOfTrailingZeros(0xF000));
+
+ assertEquals(16, Long.numberOfTrailingZeros(0x10000));
+ assertEquals(19, Long.numberOfTrailingZeros(0x80000));
+ assertEquals(16, Long.numberOfTrailingZeros(0xF0000));
+
+ assertEquals(20, Long.numberOfTrailingZeros(0x100000));
+ assertEquals(23, Long.numberOfTrailingZeros(0x800000));
+ assertEquals(20, Long.numberOfTrailingZeros(0xF00000));
+
+ assertEquals(24, Long.numberOfTrailingZeros(0x1000000));
+ assertEquals(27, Long.numberOfTrailingZeros(0x8000000));
+ assertEquals(24, Long.numberOfTrailingZeros(0xF000000));
+
+ assertEquals(28, Long.numberOfTrailingZeros(0x10000000));
+ assertEquals(31, Long.numberOfTrailingZeros(0x80000000));
+ assertEquals(28, Long.numberOfTrailingZeros(0xF0000000));
+ }
+
+ /**
+ * java.lang.Long#bitCount(long)
+ */
+ public void test_bitCountJ() {
+ assertEquals(0, Long.bitCount(0x0));
+ assertEquals(1, Long.bitCount(0x1));
+ assertEquals(1, Long.bitCount(0x2));
+ assertEquals(2, Long.bitCount(0x3));
+ assertEquals(1, Long.bitCount(0x4));
+ assertEquals(2, Long.bitCount(0x5));
+ assertEquals(2, Long.bitCount(0x6));
+ assertEquals(3, Long.bitCount(0x7));
+ assertEquals(1, Long.bitCount(0x8));
+ assertEquals(2, Long.bitCount(0x9));
+ assertEquals(2, Long.bitCount(0xA));
+ assertEquals(3, Long.bitCount(0xB));
+ assertEquals(2, Long.bitCount(0xC));
+ assertEquals(3, Long.bitCount(0xD));
+ assertEquals(3, Long.bitCount(0xE));
+ assertEquals(4, Long.bitCount(0xF));
+
+ assertEquals(8, Long.bitCount(0xFF));
+ assertEquals(12, Long.bitCount(0xFFF));
+ assertEquals(16, Long.bitCount(0xFFFF));
+ assertEquals(20, Long.bitCount(0xFFFFF));
+ assertEquals(24, Long.bitCount(0xFFFFFF));
+ assertEquals(28, Long.bitCount(0xFFFFFFF));
+ assertEquals(64, Long.bitCount(0xFFFFFFFFFFFFFFFFL));
+ }
+
+ /**
+ * java.lang.Long#rotateLeft(long, long)
+ */
+ public void test_rotateLeftJI() {
+ assertEquals(0xF, Long.rotateLeft(0xF, 0));
+ assertEquals(0xF0, Long.rotateLeft(0xF, 4));
+ assertEquals(0xF00, Long.rotateLeft(0xF, 8));
+ assertEquals(0xF000, Long.rotateLeft(0xF, 12));
+ assertEquals(0xF0000, Long.rotateLeft(0xF, 16));
+ assertEquals(0xF00000, Long.rotateLeft(0xF, 20));
+ assertEquals(0xF000000, Long.rotateLeft(0xF, 24));
+ assertEquals(0xF0000000L, Long.rotateLeft(0xF, 28));
+ assertEquals(0xF000000000000000L, Long.rotateLeft(0xF000000000000000L, 64));
+ }
+
+ /**
+ * java.lang.Long#rotateRight(long, long)
+ */
+ public void test_rotateRightJI() {
+ assertEquals(0xF, Long.rotateRight(0xF0, 4));
+ assertEquals(0xF, Long.rotateRight(0xF00, 8));
+ assertEquals(0xF, Long.rotateRight(0xF000, 12));
+ assertEquals(0xF, Long.rotateRight(0xF0000, 16));
+ assertEquals(0xF, Long.rotateRight(0xF00000, 20));
+ assertEquals(0xF, Long.rotateRight(0xF000000, 24));
+ assertEquals(0xF, Long.rotateRight(0xF0000000L, 28));
+ assertEquals(0xF000000000000000L, Long.rotateRight(0xF000000000000000L, 64));
+ assertEquals(0xF000000000000000L, Long.rotateRight(0xF000000000000000L, 0));
+
+ }
+
+ /**
+ * java.lang.Long#reverseBytes(long)
+ */
+ public void test_reverseBytesJ() {
+ assertEquals(0xAABBCCDD00112233L, Long.reverseBytes(0x33221100DDCCBBAAL));
+ assertEquals(0x1122334455667788L, Long.reverseBytes(0x8877665544332211L));
+ assertEquals(0x0011223344556677L, Long.reverseBytes(0x7766554433221100L));
+ assertEquals(0x2000000000000002L, Long.reverseBytes(0x0200000000000020L));
+ }
+
+ /**
+ * java.lang.Long#reverse(long)
+ */
+ public void test_reverseJ() {
+ assertEquals(0, Long.reverse(0));
+ assertEquals(-1, Long.reverse(-1));
+ assertEquals(0x8000000000000000L, Long.reverse(1));
+ }
+
+ /**
+ * java.lang.Long#signum(long)
+ */
+ public void test_signumJ() {
+ for (int i = -128; i < 0; i++) {
+ assertEquals(-1, Long.signum(i));
+ }
+ assertEquals(0, Long.signum(0));
+ for (int i = 1; i <= 127; i++) {
+ assertEquals(1, Long.signum(i));
+ }
+ }
+} \ No newline at end of file
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MathTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MathTest.java
new file mode 100644
index 0000000..ed8e2b5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MathTest.java
@@ -0,0 +1,1960 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+public class MathTest extends junit.framework.TestCase {
+
+ double HYP = Math.sqrt(2.0);
+
+ double OPP = 1.0;
+
+ double ADJ = 1.0;
+
+ /* Required to make previous preprocessor flags work - do not remove */
+ int unused = 0;
+
+ /**
+ * java.lang.Math#abs(double)
+ */
+ public void test_absD() {
+ // Test for method double java.lang.Math.abs(double)
+
+ assertTrue("Incorrect double abs value",
+ (Math.abs(-1908.8976) == 1908.8976));
+ assertTrue("Incorrect double abs value",
+ (Math.abs(1908.8976) == 1908.8976));
+ }
+
+ /**
+ * java.lang.Math#abs(float)
+ */
+ public void test_absF() {
+ // Test for method float java.lang.Math.abs(float)
+ assertTrue("Incorrect float abs value",
+ (Math.abs(-1908.8976f) == 1908.8976f));
+ assertTrue("Incorrect float abs value",
+ (Math.abs(1908.8976f) == 1908.8976f));
+ }
+
+ /**
+ * java.lang.Math#abs(int)
+ */
+ public void test_absI() {
+ // Test for method int java.lang.Math.abs(int)
+ assertTrue("Incorrect int abs value", (Math.abs(-1908897) == 1908897));
+ assertTrue("Incorrect int abs value", (Math.abs(1908897) == 1908897));
+ }
+
+ /**
+ * java.lang.Math#abs(long)
+ */
+ public void test_absJ() {
+ // Test for method long java.lang.Math.abs(long)
+ assertTrue("Incorrect long abs value",
+ (Math.abs(-19088976000089L) == 19088976000089L));
+ assertTrue("Incorrect long abs value",
+ (Math.abs(19088976000089L) == 19088976000089L));
+ }
+
+ /**
+ * java.lang.Math#acos(double)
+ */
+ public void test_acosD() {
+ // Test for method double java.lang.Math.acos(double)
+ double r = Math.cos(Math.acos(ADJ / HYP));
+ long lr = Double.doubleToLongBits(r);
+ long t = Double.doubleToLongBits(ADJ / HYP);
+ assertTrue("Returned incorrect arc cosine", lr == t || (lr + 1) == t
+ || (lr - 1) == t);
+ }
+
+ /**
+ * java.lang.Math#asin(double)
+ */
+ public void test_asinD() {
+ // Test for method double java.lang.Math.asin(double)
+ double r = Math.sin(Math.asin(OPP / HYP));
+ long lr = Double.doubleToLongBits(r);
+ long t = Double.doubleToLongBits(OPP / HYP);
+ assertTrue("Returned incorrect arc sine", lr == t || (lr + 1) == t
+ || (lr - 1) == t);
+ }
+
+ /**
+ * java.lang.Math#atan(double)
+ */
+ public void test_atanD() {
+ // Test for method double java.lang.Math.atan(double)
+ double answer = Math.tan(Math.atan(1.0));
+ assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
+ && answer >= 9.9999999999999983E-1);
+ }
+
+ /**
+ * java.lang.Math#atan2(double, double)
+ */
+ public void test_atan2DD() {
+ // Test for method double java.lang.Math.atan2(double, double)
+ double answer = Math.atan(Math.tan(1.0));
+ assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
+ && answer >= 9.9999999999999983E-1);
+ }
+
+ /**
+ * java.lang.Math#cbrt(double)
+ */
+ public void test_cbrt_D() {
+ //Test for special situations
+ assertTrue(Double.isNaN(Math.cbrt(Double.NaN)));
+ assertEquals(Double.POSITIVE_INFINITY, Math.cbrt(Double.POSITIVE_INFINITY), 0D);
+ assertEquals(Double.NEGATIVE_INFINITY, Math.cbrt(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math.cbrt(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double.doubleToLongBits(Math.cbrt(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double.doubleToLongBits(Math.cbrt(-0.0)));
+
+ assertEquals(3.0, Math.cbrt(27.0), 0D);
+ assertEquals(23.111993172558684, Math.cbrt(12345.6), Math.ulp(23.111993172558684));
+ assertEquals(5.643803094122362E102, Math.cbrt(Double.MAX_VALUE), 0D);
+ assertEquals(0.01, Math.cbrt(0.000001), 0D);
+
+ assertEquals(-3.0, Math.cbrt(-27.0), 0D);
+ assertEquals(-23.111993172558684, Math.cbrt(-12345.6), Math.ulp(-23.111993172558684));
+ assertEquals(1.7031839360032603E-108, Math.cbrt(Double.MIN_VALUE), 0D);
+ assertEquals(-0.01, Math.cbrt(-0.000001), 0D);
+ }
+
+ /**
+ * java.lang.Math#ceil(double)
+ */
+ public void test_ceilD() {
+ // Test for method double java.lang.Math.ceil(double)
+ assertEquals("Incorrect ceiling for double",
+ 79, Math.ceil(78.89), 0);
+ assertEquals("Incorrect ceiling for double",
+ -78, Math.ceil(-78.89), 0);
+ }
+
+ /**
+ * cases for test_copySign_DD in MathTest/StrictMathTest
+ */
+ static final double[] COPYSIGN_DD_CASES = new double[] {
+ Double.POSITIVE_INFINITY, Double.MAX_VALUE, 3.4E302, 2.3,
+ Double.MIN_NORMAL, Double.MIN_NORMAL / 2, Double.MIN_VALUE, +0.0,
+ 0.0, -0.0, -Double.MIN_VALUE, -Double.MIN_NORMAL / 2,
+ -Double.MIN_NORMAL, -4.5, -3.4E102, -Double.MAX_VALUE,
+ Double.NEGATIVE_INFINITY };
+
+ /**
+ * {@link java.lang.Math#copySign(double, double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_copySign_DD() {
+ for (int i = 0; i < COPYSIGN_DD_CASES.length; i++) {
+ final double magnitude = COPYSIGN_DD_CASES[i];
+ final long absMagnitudeBits = Double.doubleToLongBits(Math
+ .abs(magnitude));
+ final long negMagnitudeBits = Double.doubleToLongBits(-Math
+ .abs(magnitude));
+
+ // cases for NaN
+ assertEquals("If the sign is NaN, the result should be positive.",
+ absMagnitudeBits, Double.doubleToLongBits(Math.copySign(
+ magnitude, Double.NaN)));
+ assertTrue("The result should be NaN.", Double.isNaN(Math.copySign(
+ Double.NaN, magnitude)));
+
+ for (int j = 0; j < COPYSIGN_DD_CASES.length; j++) {
+ final double sign = COPYSIGN_DD_CASES[j];
+ final long resultBits = Double.doubleToLongBits(Math.copySign(
+ magnitude, sign));
+
+ if (sign > 0 || Double.valueOf(+0.0).equals(sign)
+ || Double.valueOf(0.0).equals(sign)) {
+ assertEquals(
+ "If the sign is positive, the result should be positive.",
+ absMagnitudeBits, resultBits);
+ }
+ if (sign < 0 || Double.valueOf(-0.0).equals(sign)) {
+ assertEquals(
+ "If the sign is negative, the result should be negative.",
+ negMagnitudeBits, resultBits);
+ }
+ }
+ }
+
+ assertTrue("The result should be NaN.", Double.isNaN(Math.copySign(
+ Double.NaN, Double.NaN)));
+
+ try {
+ Math.copySign((Double) null, 2.3);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.copySign(2.3, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.copySign((Double) null, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * cases for test_copySign_FF in MathTest/StrictMathTest
+ */
+ static final float[] COPYSIGN_FF_CASES = new float[] {
+ Float.POSITIVE_INFINITY, Float.MAX_VALUE, 3.4E12f, 2.3f,
+ Float.MIN_NORMAL, Float.MIN_NORMAL / 2, Float.MIN_VALUE, +0.0f,
+ 0.0f, -0.0f, -Float.MIN_VALUE, -Float.MIN_NORMAL / 2,
+ -Float.MIN_NORMAL, -4.5f, -5.6442E21f, -Float.MAX_VALUE,
+ Float.NEGATIVE_INFINITY };
+
+ /**
+ * {@link java.lang.Math#copySign(float, float)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_copySign_FF() {
+ for (int i = 0; i < COPYSIGN_FF_CASES.length; i++) {
+ final float magnitude = COPYSIGN_FF_CASES[i];
+ final int absMagnitudeBits = Float.floatToIntBits(Math
+ .abs(magnitude));
+ final int negMagnitudeBits = Float.floatToIntBits(-Math
+ .abs(magnitude));
+
+ // cases for NaN
+ assertEquals("If the sign is NaN, the result should be positive.",
+ absMagnitudeBits, Float.floatToIntBits(Math.copySign(
+ magnitude, Float.NaN)));
+ assertTrue("The result should be NaN.", Float.isNaN(Math.copySign(
+ Float.NaN, magnitude)));
+
+ for (int j = 0; j < COPYSIGN_FF_CASES.length; j++) {
+ final float sign = COPYSIGN_FF_CASES[j];
+ final int resultBits = Float.floatToIntBits(Math.copySign(
+ magnitude, sign));
+ if (sign > 0 || Float.valueOf(+0.0f).equals(sign)
+ || Float.valueOf(0.0f).equals(sign)) {
+ assertEquals(
+ "If the sign is positive, the result should be positive.",
+ absMagnitudeBits, resultBits);
+ }
+ if (sign < 0 || Float.valueOf(-0.0f).equals(sign)) {
+ assertEquals(
+ "If the sign is negative, the result should be negative.",
+ negMagnitudeBits, resultBits);
+ }
+ }
+ }
+
+ assertTrue("The result should be NaN.", Float.isNaN(Math.copySign(
+ Float.NaN, Float.NaN)));
+
+ try {
+ Math.copySign((Float) null, 2.3f);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.copySign(2.3f, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.copySign((Float) null, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.Math#cos(double)
+ */
+ public void test_cosD() {
+ // Test for method double java.lang.Math.cos(double)
+ assertEquals("Incorrect answer", 1.0, Math.cos(0), 0D);
+ assertEquals("Incorrect answer", 0.5403023058681398, Math.cos(1), 0D);
+ }
+
+ /**
+ * java.lang.Math#cosh(double)
+ */
+ public void test_cosh_D() {
+ // Test for special situations
+ assertTrue(Double.isNaN(Math.cosh(Double.NaN)));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.cosh(Double.POSITIVE_INFINITY), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.cosh(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals("Should return 1.0", 1.0, Math.cosh(+0.0), 0D);
+ assertEquals("Should return 1.0", 1.0, Math.cosh(-0.0), 0D);
+
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.cosh(1234.56), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.cosh(-1234.56), 0D);
+ assertEquals("Should return 1.0000000000005", 1.0000000000005, Math
+ .cosh(0.000001), 0D);
+ assertEquals("Should return 1.0000000000005", 1.0000000000005, Math
+ .cosh(-0.000001), 0D);
+ assertEquals("Should return 5.212214351945598", 5.212214351945598, Math
+ .cosh(2.33482), 0D);
+
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.cosh(Double.MAX_VALUE), 0D);
+ assertEquals("Should return 1.0", 1.0, Math.cosh(Double.MIN_VALUE), 0D);
+ }
+
+ /**
+ * java.lang.Math#exp(double)
+ */
+ public void test_expD() {
+ // Test for method double java.lang.Math.exp(double)
+ assertTrue("Incorrect answer returned for simple power", Math.abs(Math
+ .exp(4D)
+ - Math.E * Math.E * Math.E * Math.E) < 0.1D);
+ assertTrue("Incorrect answer returned for larger power", Math.log(Math
+ .abs(Math.exp(5.5D)) - 5.5D) < 10.0D);
+ }
+
+ /**
+ * java.lang.Math#expm1(double)
+ */
+ public void test_expm1_D() {
+ // Test for special cases
+ assertTrue("Should return NaN", Double.isNaN(Math.expm1(Double.NaN)));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.expm1(Double.POSITIVE_INFINITY), 0D);
+ assertEquals("Should return -1.0", -1.0, Math
+ .expm1(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
+ .expm1(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(Math.expm1(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(Math.expm1(-0.0)));
+
+ assertEquals("Should return -9.999950000166666E-6",
+ -9.999950000166666E-6, Math.expm1(-0.00001), 0D);
+ assertEquals("Should return 1.0145103074469635E60",
+ 1.0145103074469635E60, Math.expm1(138.16951162), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math
+ .expm1(123456789123456789123456789.4521584223), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.expm1(Double.MAX_VALUE), 0D);
+ assertEquals("Should return MIN_VALUE", Double.MIN_VALUE, Math
+ .expm1(Double.MIN_VALUE), 0D);
+ }
+
+ /**
+ * java.lang.Math#floor(double)
+ */
+ public void test_floorD() {
+ assertEquals("Incorrect floor for int", 42, Math.floor(42), 0);
+ assertEquals("Incorrect floor for -int", -2, Math.floor(-2), 0);
+ assertEquals("Incorrect floor for zero", 0d, Math.floor(0d), 0);
+
+ assertEquals("Incorrect floor for +double", 78, Math.floor(78.89), 0);
+ assertEquals("Incorrect floor for -double", -79, Math.floor(-78.89), 0);
+ assertEquals("floor large +double", 3.7314645675925406E19, Math.floor(3.7314645675925406E19), 0);
+ assertEquals("floor large -double", -8.173521839218E12, Math.floor(-8.173521839218E12), 0);
+ assertEquals("floor small double", 0.0d, Math.floor(1.11895241315E-102), 0);
+
+ // Compare toString representations here since -0.0 = +0.0, and
+ // NaN != NaN and we need to distinguish
+ assertEquals("Floor failed for NaN",
+ Double.toString(Double.NaN), Double.toString(Math.floor(Double.NaN)));
+ assertEquals("Floor failed for +0.0",
+ Double.toString(+0.0d), Double.toString(Math.floor(+0.0d)));
+ assertEquals("Floor failed for -0.0",
+ Double.toString(-0.0d), Double.toString(Math.floor(-0.0d)));
+ assertEquals("Floor failed for +infinity",
+ Double.toString(Double.POSITIVE_INFINITY), Double.toString(Math.floor(Double.POSITIVE_INFINITY)));
+ assertEquals("Floor failed for -infinity",
+ Double.toString(Double.NEGATIVE_INFINITY), Double.toString(Math.floor(Double.NEGATIVE_INFINITY)));
+ }
+
+ /**
+ * cases for test_getExponent_D in MathTest/StrictMathTest
+ */
+ static final double GETEXPONENT_D_CASES[] = new double[] {
+ Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,
+ Double.MAX_VALUE, -Double.MAX_VALUE, 2.342E231, -2.342E231, 2800.0,
+ -2800.0, 5.323, -5.323, 1.323, -1.323, 0.623, -0.623, 0.323,
+ -0.323, Double.MIN_NORMAL * 24, -Double.MIN_NORMAL * 24,
+ Double.MIN_NORMAL, -Double.MIN_NORMAL, Double.MIN_NORMAL / 2,
+ -Double.MIN_NORMAL / 2, Double.MIN_VALUE, -Double.MIN_VALUE, +0.0,
+ 0.0, -0.0, Double.NaN };
+
+ /**
+ * result for test_getExponent_D in MathTest/StrictMathTest
+ */
+ static final int GETEXPONENT_D_RESULTS[] = new int[] {
+ Double.MAX_EXPONENT + 1, Double.MAX_EXPONENT + 1,
+ Double.MAX_EXPONENT, Double.MAX_EXPONENT, 768, 768, 11, 11, 2, 2,
+ 0, 0, -1, -1, -2, -2, -1018, -1018, Double.MIN_EXPONENT,
+ Double.MIN_EXPONENT, Double.MIN_EXPONENT - 1,
+ Double.MIN_EXPONENT - 1, Double.MIN_EXPONENT - 1,
+ Double.MIN_EXPONENT - 1, Double.MIN_EXPONENT - 1,
+ Double.MIN_EXPONENT - 1, Double.MIN_EXPONENT - 1,
+ Double.MAX_EXPONENT + 1 };
+
+ /**
+ * {@link java.lang.Math#getExponent(double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_getExponent_D() {
+ for (int i = 0; i < GETEXPONENT_D_CASES.length; i++) {
+ final double number = GETEXPONENT_D_CASES[i];
+ final int result = GETEXPONENT_D_RESULTS[i];
+ assertEquals("Wrong result of getExponent(double).", result, Math
+ .getExponent(number));
+ }
+
+ try {
+ Math.getExponent((Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * cases for test_getExponent_F in MathTest/StrictMathTest
+ */
+ static final float GETEXPONENT_F_CASES[] = new float[] {
+ Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.MAX_VALUE,
+ -Float.MAX_VALUE, 3.4256E23f, -3.4256E23f, 2800.0f, -2800.0f,
+ 5.323f, -5.323f, 1.323f, -1.323f, 0.623f, -0.623f, 0.323f, -0.323f,
+ Float.MIN_NORMAL * 24, -Float.MIN_NORMAL * 24, Float.MIN_NORMAL,
+ -Float.MIN_NORMAL, Float.MIN_NORMAL / 2, -Float.MIN_NORMAL / 2,
+ Float.MIN_VALUE, -Float.MIN_VALUE, +0.0f, 0.0f, -0.0f, Float.NaN, 1, Float.MIN_NORMAL * 1.5f };
+
+ /**
+ * result for test_getExponent_F in MathTest/StrictMathTest
+ */
+ static final int GETEXPONENT_F_RESULTS[] = new int[] {
+ Float.MAX_EXPONENT + 1, Float.MAX_EXPONENT + 1, Float.MAX_EXPONENT,
+ Float.MAX_EXPONENT, 78, 78, 11, 11, 2, 2, 0, 0, -1, -1, -2, -2,
+ -122, -122, Float.MIN_EXPONENT, Float.MIN_EXPONENT,
+ Float.MIN_EXPONENT - 1, Float.MIN_EXPONENT - 1,
+ Float.MIN_EXPONENT - 1, Float.MIN_EXPONENT - 1,
+ Float.MIN_EXPONENT - 1, Float.MIN_EXPONENT - 1,
+ Float.MIN_EXPONENT - 1, Float.MAX_EXPONENT + 1, 0, Float.MIN_EXPONENT };
+
+ /**
+ * {@link java.lang.Math#getExponent(float)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_getExponent_F() {
+ for (int i = 0; i < GETEXPONENT_F_CASES.length; i++) {
+ final float number = GETEXPONENT_F_CASES[i];
+ final int result = GETEXPONENT_F_RESULTS[i];
+ assertEquals("Wrong result of getExponent(float).", result, Math
+ .getExponent(number));
+ }
+ try {
+ Math.getExponent((Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.Math#hypot(double, double)
+ */
+ public void test_hypot_DD() {
+ // Test for special cases
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.hypot(Double.POSITIVE_INFINITY,
+ 1.0), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.hypot(Double.NEGATIVE_INFINITY,
+ 123.324), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.hypot(-758.2587,
+ Double.POSITIVE_INFINITY), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.hypot(5687.21,
+ Double.NEGATIVE_INFINITY), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.hypot(Double.POSITIVE_INFINITY,
+ Double.NEGATIVE_INFINITY), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.hypot(Double.NEGATIVE_INFINITY,
+ Double.POSITIVE_INFINITY), 0D);
+ assertTrue("Should be NaN", Double.isNaN(Math.hypot(Double.NaN,
+ 2342301.89843)));
+ assertTrue("Should be NaN", Double.isNaN(Math.hypot(-345.2680,
+ Double.NaN)));
+
+ assertEquals("Should return 2396424.905416697", 2396424.905416697, Math
+ .hypot(12322.12, -2396393.2258), 0D);
+ assertEquals("Should return 138.16958070558556", 138.16958070558556,
+ Math.hypot(-138.16951162, 0.13817035864), 0D);
+ assertEquals("Should return 1.7976931348623157E308",
+ 1.7976931348623157E308, Math.hypot(Double.MAX_VALUE, 211370.35), 0D);
+ assertEquals("Should return 5413.7185", 5413.7185, Math.hypot(
+ -5413.7185, Double.MIN_VALUE), 0D);
+ }
+
+ /**
+ * java.lang.Math#IEEEremainder(double, double)
+ */
+ public void test_IEEEremainderDD() {
+ // Test for method double java.lang.Math.IEEEremainder(double, double)
+ assertEquals("Incorrect remainder returned",
+ 0.0, Math.IEEEremainder(1.0, 1.0), 0D);
+ assertTrue("Incorrect remainder returned", Math.IEEEremainder(1.32,
+ 89.765) >= 1.4705063220631647E-2
+ || Math.IEEEremainder(1.32, 89.765) >= 1.4705063220631649E-2);
+ }
+
+ /**
+ * java.lang.Math#log(double)
+ */
+ public void test_logD() {
+ // Test for method double java.lang.Math.log(double)
+ for (double d = 10; d >= -10; d -= 0.5) {
+ double answer = Math.log(Math.exp(d));
+ assertTrue("Answer does not equal expected answer for d = " + d
+ + " answer = " + answer, Math.abs(answer - d) <= Math
+ .abs(d * 0.00000001));
+ }
+ }
+
+ /**
+ * java.lang.Math#log10(double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_log10_D() {
+ // Test for special cases
+ assertTrue(Double.isNaN(Math.log10(Double.NaN)));
+ assertTrue(Double.isNaN(Math.log10(-2541.05745687234187532)));
+ assertTrue(Double.isNaN(Math.log10(-0.1)));
+ assertEquals(Double.POSITIVE_INFINITY, Math.log10(Double.POSITIVE_INFINITY));
+ assertEquals(Double.NEGATIVE_INFINITY, Math.log10(0.0));
+ assertEquals(Double.NEGATIVE_INFINITY, Math.log10(+0.0));
+ assertEquals(Double.NEGATIVE_INFINITY, Math.log10(-0.0));
+
+ assertEquals(3.0, Math.log10(1000.0));
+ assertEquals(14.0, Math.log10(Math.pow(10, 14)));
+ assertEquals(3.7389561269540406, Math.log10(5482.2158));
+ assertEquals(14.661551142893833, Math.log10(458723662312872.125782332587));
+ assertEquals(-0.9083828622192334, Math.log10(0.12348583358871));
+ assertEquals(308.25471555991675, Math.log10(Double.MAX_VALUE));
+ assertEquals(-323.3062153431158, Math.log10(Double.MIN_VALUE));
+ }
+
+ /**
+ * java.lang.Math#log1p(double)
+ */
+ public void test_log1p_D() {
+ // Test for special cases
+ assertTrue("Should return NaN", Double.isNaN(Math.log1p(Double.NaN)));
+ assertTrue("Should return NaN", Double.isNaN(Math.log1p(-32.0482175)));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, Math.log1p(Double.POSITIVE_INFINITY), 0D);
+ assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
+ .log1p(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(Math.log1p(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(Math.log1p(-0.0)));
+
+ assertEquals("Should return -0.2941782295312541", -0.2941782295312541,
+ Math.log1p(-0.254856327), 0D);
+ assertEquals("Should return 7.368050685564151", 7.368050685564151, Math
+ .log1p(1583.542), 0D);
+ assertEquals("Should return 0.4633708685409921", 0.4633708685409921,
+ Math.log1p(0.5894227), 0D);
+ assertEquals("Should return 709.782712893384", 709.782712893384, Math
+ .log1p(Double.MAX_VALUE), 0D);
+ assertEquals("Should return Double.MIN_VALUE", Double.MIN_VALUE, Math
+ .log1p(Double.MIN_VALUE), 0D);
+ }
+
+ /**
+ * java.lang.Math#max(double, double)
+ */
+ public void test_maxDD() {
+ // Test for method double java.lang.Math.max(double, double)
+ assertEquals("Incorrect double max value", 1908897.6000089, Math.max(-1908897.6000089,
+ 1908897.6000089), 0D);
+ assertEquals("Incorrect double max value",
+ 1908897.6000089, Math.max(2.0, 1908897.6000089), 0D);
+ assertEquals("Incorrect double max value", -2.0, Math.max(-2.0,
+ -1908897.6000089), 0D);
+
+ // Compare toString representations here since -0.0 = +0.0, and
+ // NaN != NaN and we need to distinguish
+ assertEquals("Max failed for NaN",
+ Double.toString(Double.NaN), Double.toString(Math.max(Double.NaN, 42.0d)));
+ assertEquals("Max failed for NaN",
+ Double.toString(Double.NaN), Double.toString(Math.max(42.0d, Double.NaN)));
+ assertEquals("Max failed for 0.0",
+ Double.toString(+0.0d), Double.toString(Math.max(+0.0d, -0.0d)));
+ assertEquals("Max failed for 0.0",
+ Double.toString(+0.0d), Double.toString(Math.max(-0.0d, +0.0d)));
+ assertEquals("Max failed for -0.0d",
+ Double.toString(-0.0d), Double.toString(Math.max(-0.0d, -0.0d)));
+ assertEquals("Max failed for 0.0",
+ Double.toString(+0.0d), Double.toString(Math.max(+0.0d, +0.0d)));
+ }
+
+ /**
+ * java.lang.Math#max(float, float)
+ */
+ public void test_maxFF() {
+ // Test for method float java.lang.Math.max(float, float)
+ assertTrue("Incorrect float max value", Math.max(-1908897.600f,
+ 1908897.600f) == 1908897.600f);
+ assertTrue("Incorrect float max value",
+ Math.max(2.0f, 1908897.600f) == 1908897.600f);
+ assertTrue("Incorrect float max value",
+ Math.max(-2.0f, -1908897.600f) == -2.0f);
+
+ // Compare toString representations here since -0.0 = +0.0, and
+ // NaN != NaN and we need to distinguish
+ assertEquals("Max failed for NaN",
+ Float.toString(Float.NaN), Float.toString(Math.max(Float.NaN, 42.0f)));
+ assertEquals("Max failed for NaN",
+ Float.toString(Float.NaN), Float.toString(Math.max(42.0f, Float.NaN)));
+ assertEquals("Max failed for 0.0",
+ Float.toString(+0.0f), Float.toString(Math.max(+0.0f, -0.0f)));
+ assertEquals("Max failed for 0.0",
+ Float.toString(+0.0f), Float.toString(Math.max(-0.0f, +0.0f)));
+ assertEquals("Max failed for -0.0f",
+ Float.toString(-0.0f), Float.toString(Math.max(-0.0f, -0.0f)));
+ assertEquals("Max failed for 0.0",
+ Float.toString(+0.0f), Float.toString(Math.max(+0.0f, +0.0f)));
+ }
+
+ /**
+ * java.lang.Math#max(int, int)
+ */
+ public void test_maxII() {
+ // Test for method int java.lang.Math.max(int, int)
+ assertEquals("Incorrect int max value",
+ 19088976, Math.max(-19088976, 19088976));
+ assertEquals("Incorrect int max value",
+ 19088976, Math.max(20, 19088976));
+ assertEquals("Incorrect int max value", -20, Math.max(-20, -19088976));
+ }
+
+ /**
+ * java.lang.Math#max(long, long)
+ */
+ public void test_maxJJ() {
+ // Test for method long java.lang.Math.max(long, long)
+ assertEquals("Incorrect long max value", 19088976000089L, Math.max(-19088976000089L,
+ 19088976000089L));
+ assertEquals("Incorrect long max value",
+ 19088976000089L, Math.max(20, 19088976000089L));
+ assertEquals("Incorrect long max value",
+ -20, Math.max(-20, -19088976000089L));
+ }
+
+ /**
+ * java.lang.Math#min(double, double)
+ */
+ public void test_minDD() {
+ // Test for method double java.lang.Math.min(double, double)
+ assertEquals("Incorrect double min value", -1908897.6000089, Math.min(-1908897.6000089,
+ 1908897.6000089), 0D);
+ assertEquals("Incorrect double min value",
+ 2.0, Math.min(2.0, 1908897.6000089), 0D);
+ assertEquals("Incorrect double min value", -1908897.6000089, Math.min(-2.0,
+ -1908897.6000089), 0D);
+ assertEquals("Incorrect double min value", 1.0d, Math.min(1.0d, 1.0d));
+
+ // Compare toString representations here since -0.0 = +0.0, and
+ // NaN != NaN and we need to distinguish
+ assertEquals("Min failed for NaN",
+ Double.toString(Double.NaN), Double.toString(Math.min(Double.NaN, 42.0d)));
+ assertEquals("Min failed for NaN",
+ Double.toString(Double.NaN), Double.toString(Math.min(42.0d, Double.NaN)));
+ assertEquals("Min failed for -0.0",
+ Double.toString(-0.0d), Double.toString(Math.min(+0.0d, -0.0d)));
+ assertEquals("Min failed for -0.0",
+ Double.toString(-0.0d), Double.toString(Math.min(-0.0d, +0.0d)));
+ assertEquals("Min failed for -0.0d",
+ Double.toString(-0.0d), Double.toString(Math.min(-0.0d, -0.0d)));
+ assertEquals("Min failed for 0.0",
+ Double.toString(+0.0d), Double.toString(Math.min(+0.0d, +0.0d)));
+ }
+
+ /**
+ * java.lang.Math#min(float, float)
+ */
+ public void test_minFF() {
+ // Test for method float java.lang.Math.min(float, float)
+ assertTrue("Incorrect float min value", Math.min(-1908897.600f,
+ 1908897.600f) == -1908897.600f);
+ assertTrue("Incorrect float min value",
+ Math.min(2.0f, 1908897.600f) == 2.0f);
+ assertTrue("Incorrect float min value",
+ Math.min(-2.0f, -1908897.600f) == -1908897.600f);
+ assertEquals("Incorrect float min value", 1.0f, Math.min(1.0f, 1.0f));
+
+ // Compare toString representations here since -0.0 = +0.0, and
+ // NaN != NaN and we need to distinguish
+ assertEquals("Min failed for NaN",
+ Float.toString(Float.NaN), Float.toString(Math.min(Float.NaN, 42.0f)));
+ assertEquals("Min failed for NaN",
+ Float.toString(Float.NaN), Float.toString(Math.min(42.0f, Float.NaN)));
+ assertEquals("Min failed for -0.0",
+ Float.toString(-0.0f), Float.toString(Math.min(+0.0f, -0.0f)));
+ assertEquals("Min failed for -0.0",
+ Float.toString(-0.0f), Float.toString(Math.min(-0.0f, +0.0f)));
+ assertEquals("Min failed for -0.0f",
+ Float.toString(-0.0f), Float.toString(Math.min(-0.0f, -0.0f)));
+ assertEquals("Min failed for 0.0",
+ Float.toString(+0.0f), Float.toString(Math.min(+0.0f, +0.0f)));
+ }
+
+ /**
+ * java.lang.Math#min(int, int)
+ */
+ public void test_minII() {
+ // Test for method int java.lang.Math.min(int, int)
+ assertEquals("Incorrect int min value",
+ -19088976, Math.min(-19088976, 19088976));
+ assertEquals("Incorrect int min value", 20, Math.min(20, 19088976));
+ assertEquals("Incorrect int min value",
+ -19088976, Math.min(-20, -19088976));
+
+ }
+
+ /**
+ * java.lang.Math#min(long, long)
+ */
+ public void test_minJJ() {
+ // Test for method long java.lang.Math.min(long, long)
+ assertEquals("Incorrect long min value", -19088976000089L, Math.min(-19088976000089L,
+ 19088976000089L));
+ assertEquals("Incorrect long min value",
+ 20, Math.min(20, 19088976000089L));
+ assertEquals("Incorrect long min value",
+ -19088976000089L, Math.min(-20, -19088976000089L));
+ }
+
+ /**
+ * start number cases for test_nextAfter_DD in MathTest/StrictMathTest
+ * NEXTAFTER_DD_START_CASES[i][0] is the start number
+ * NEXTAFTER_DD_START_CASES[i][1] is the nextUp of start number
+ * NEXTAFTER_DD_START_CASES[i][2] is the nextDown of start number
+ */
+ static final double NEXTAFTER_DD_START_CASES[][] = new double[][] {
+ { 3.4, 3.4000000000000004, 3.3999999999999995 },
+ { -3.4, -3.3999999999999995, -3.4000000000000004 },
+ { 3.4233E109, 3.4233000000000005E109, 3.4232999999999996E109 },
+ { -3.4233E109, -3.4232999999999996E109, -3.4233000000000005E109 },
+ { +0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+ { 0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+ { -0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+ { Double.MIN_VALUE, 1.0E-323, +0.0 },
+ { -Double.MIN_VALUE, -0.0, -1.0E-323 },
+ { Double.MIN_NORMAL, 2.225073858507202E-308, 2.225073858507201E-308 },
+ { -Double.MIN_NORMAL, -2.225073858507201E-308,
+ -2.225073858507202E-308 },
+ { Double.MAX_VALUE, Double.POSITIVE_INFINITY,
+ 1.7976931348623155E308 },
+ { -Double.MAX_VALUE, -1.7976931348623155E308,
+ Double.NEGATIVE_INFINITY },
+ { Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY,
+ Double.MAX_VALUE },
+ { Double.NEGATIVE_INFINITY, -Double.MAX_VALUE,
+ Double.NEGATIVE_INFINITY } };
+
+ /**
+ * direction number cases for test_nextAfter_DD/test_nextAfter_FD in
+ * MathTest/StrictMathTest
+ */
+ static final double NEXTAFTER_DD_FD_DIRECTION_CASES[] = new double[] {
+ Double.POSITIVE_INFINITY, Double.MAX_VALUE, 8.8, 3.4, 1.4,
+ Double.MIN_NORMAL, Double.MIN_NORMAL / 2, Double.MIN_VALUE, +0.0,
+ 0.0, -0.0, -Double.MIN_VALUE, -Double.MIN_NORMAL / 2,
+ -Double.MIN_NORMAL, -1.4, -3.4, -8.8, -Double.MAX_VALUE,
+ Double.NEGATIVE_INFINITY };
+
+ /**
+ * {@link java.lang.Math#nextAfter(double, double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextAfter_DD() {
+ // test for most cases without exception
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ final double start = NEXTAFTER_DD_START_CASES[i][0];
+ final long nextUpBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+ final long nextDownBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][2]);
+
+ for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+ final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+ final long resultBits = Double.doubleToLongBits(Math.nextAfter(
+ start, direction));
+ final long directionBits = Double.doubleToLongBits(direction);
+ if (direction > start) {
+ assertEquals("Result should be next up-number.",
+ nextUpBits, resultBits);
+ } else if (direction < start) {
+ assertEquals("Result should be next down-number.",
+ nextDownBits, resultBits);
+ } else {
+ assertEquals("Result should be direction.", directionBits,
+ resultBits);
+ }
+ }
+ }
+
+ // test for cases with NaN
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Double.isNaN(Math
+ .nextAfter(NEXTAFTER_DD_START_CASES[i][0], Double.NaN)));
+ }
+ for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Double.isNaN(Math
+ .nextAfter(Double.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+ }
+ assertTrue("The result should be NaN.", Double.isNaN(Math.nextAfter(
+ Double.NaN, Double.NaN)));
+
+ // test for exception
+ try {
+ Math.nextAfter((Double) null, 2.3);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.nextAfter(2.3, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.nextAfter((Double) null, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * start number cases for test_nextAfter_FD in MathTest/StrictMathTest
+ * NEXTAFTER_FD_START_CASES[i][0] is the start number
+ * NEXTAFTER_FD_START_CASES[i][1] is the nextUp of start number
+ * NEXTAFTER_FD_START_CASES[i][2] is the nextDown of start number
+ */
+ static final float NEXTAFTER_FD_START_CASES[][] = new float[][] {
+ { 3.4f, 3.4000003f, 3.3999999f },
+ { -3.4f, -3.3999999f, -3.4000003f },
+ { 3.4233E19f, 3.4233002E19f, 3.4232998E19f },
+ { -3.4233E19f, -3.4232998E19f, -3.4233002E19f },
+ { +0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+ { 0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+ { -0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+ { Float.MIN_VALUE, 2.8E-45f, +0.0f },
+ { -Float.MIN_VALUE, -0.0f, -2.8E-45f },
+ { Float.MIN_NORMAL, 1.1754945E-38f, 1.1754942E-38f },
+ { -Float.MIN_NORMAL, -1.1754942E-38f, -1.1754945E-38f },
+ { Float.MAX_VALUE, Float.POSITIVE_INFINITY, 3.4028233E38f },
+ { -Float.MAX_VALUE, -3.4028233E38f, Float.NEGATIVE_INFINITY },
+ { Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.MAX_VALUE },
+ { Float.NEGATIVE_INFINITY, -Float.MAX_VALUE,
+ Float.NEGATIVE_INFINITY } };
+
+ /**
+ * {@link java.lang.Math#nextAfter(float, double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextAfter_FD() {
+ // test for most cases without exception
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ final float start = NEXTAFTER_FD_START_CASES[i][0];
+ final int nextUpBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+ final int nextDownBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][2]);
+
+ for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+ final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+ final int resultBits = Float.floatToIntBits(Math.nextAfter(
+ start, direction));
+ if (direction > start) {
+ assertEquals("Result should be next up-number.",
+ nextUpBits, resultBits);
+ } else if (direction < start) {
+ assertEquals("Result should be next down-number.",
+ nextDownBits, resultBits);
+ } else {
+ final int equivalentBits = Float.floatToIntBits(new Float(
+ direction));
+ assertEquals(
+ "Result should be a number equivalent to direction.",
+ equivalentBits, resultBits);
+ }
+ }
+ }
+
+ // test for cases with NaN
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+ NEXTAFTER_FD_START_CASES[i][0], Float.NaN)));
+ }
+ for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+ Float.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+ }
+ assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+ Float.NaN, Float.NaN)));
+
+ // test for exception
+ try {
+ Math.nextAfter((Float) null, 2.3);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.nextAfter(2.3, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.nextAfter((Float) null, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * {@link java.lang.Math#nextUp(double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextUp_D() {
+ // This method is semantically equivalent to nextAfter(d,
+ // Double.POSITIVE_INFINITY),
+ // so we use the data of test_nextAfter_DD
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ final double start = NEXTAFTER_DD_START_CASES[i][0];
+ final long nextUpBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+ final long resultBits = Double.doubleToLongBits(Math.nextUp(start));
+ assertEquals("Result should be next up-number.", nextUpBits,
+ resultBits);
+ }
+
+ // test for cases with NaN
+ assertTrue("The result should be NaN.", Double.isNaN(Math
+ .nextUp(Double.NaN)));
+
+ // test for exception
+ try {
+ Math.nextUp((Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * {@link java.lang.Math#nextUp(float)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextUp_F() {
+ // This method is semantically equivalent to nextAfter(f,
+ // Float.POSITIVE_INFINITY),
+ // so we use the data of test_nextAfter_FD
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ final float start = NEXTAFTER_FD_START_CASES[i][0];
+ final int nextUpBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+ final int resultBits = Float.floatToIntBits(Math.nextUp(start));
+ assertEquals("Result should be next up-number.", nextUpBits,
+ resultBits);
+ }
+
+ // test for cases with NaN
+ assertTrue("The result should be NaN.", Float.isNaN(Math
+ .nextUp(Float.NaN)));
+
+ // test for exception
+ try {
+ Math.nextUp((Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.Math#pow(double, double)
+ */
+ public void test_powDD() {
+ // Test for method double java.lang.Math.pow(double, double)
+ double NZERO = longTodouble(doubleTolong(0.0) ^ 0x8000000000000000L);
+ double p1 = 1.0;
+ double p2 = 2.0;
+ double p3 = 3.0;
+ double p4 = 4.0;
+ double p5 = 5.0;
+ double p6 = 6.0;
+ double p7 = 7.0;
+ double p8 = 8.0;
+ double p9 = 9.0;
+ double p10 = 10.0;
+ double p11 = 11.0;
+ double p12 = 12.0;
+ double p13 = 13.0;
+ double p14 = 14.0;
+ double p15 = 15.0;
+ double p16 = 16.0;
+ double[] values = { p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12,
+ p13, p14, p15, p16 };
+
+ for (int x = 0; x < values.length; x++) {
+ double dval = values[x];
+ double nagateDval = negateDouble(dval);
+ if (nagateDval == Double.NaN) {
+ continue;
+ }
+
+ // If the second argument is positive or negative zero, then the
+ // result is 1.0.
+ assertEquals("Result should be Math.pow(" + dval
+ + ",-0.0)=+1.0", 1.0, Math.pow(dval, NZERO));
+ assertEquals("Result should be Math.pow(" + nagateDval
+ + ",-0.0)=+1.0", 1.0, Math.pow(nagateDval, NZERO));
+ assertEquals("Result should be Math.pow(" + dval
+ + ",+0.0)=+1.0", 1.0, Math.pow(dval, +0.0));
+ assertEquals("Result should be Math.pow(" + nagateDval
+ + ",+0.0)=+1.0", 1.0, Math.pow(nagateDval, +0.0));
+
+ // If the second argument is 1.0, then the result is the same as the
+ // first argument.
+ assertEquals("Result should be Math.pow(" + dval + "," + 1.0 + ")="
+ + dval, dval, Math.pow(dval, 1.0));
+ assertEquals("Result should be Math.pow(" + nagateDval + "," + 1.0
+ + ")=" + nagateDval, nagateDval, Math.pow(nagateDval, 1.0));
+
+ // If the second argument is NaN, then the result is NaN.
+ assertEquals("Result should be Math.pow(" + dval + "," + Double.NaN
+ + ")=" + Double.NaN, Double.NaN, Math.pow(dval, Double.NaN));
+ assertEquals("Result should be Math.pow(" + nagateDval + ","
+ + Double.NaN + ")=" + Double.NaN, Double.NaN, Math.pow(nagateDval,
+ Double.NaN));
+
+ if (dval > 1) {
+ // If the first argument is NaN and the second argument is
+ // nonzero,
+ // then the result is NaN.
+ assertEquals("Result should be Math.pow(" + Double.NaN + ","
+ + dval + ")=" + Double.NaN, Double.NaN, Math.pow(Double.NaN, dval));
+ assertEquals("Result should be Math.pow(" + Double.NaN + ","
+ + nagateDval + ")=" + Double.NaN, Double.NaN, Math.pow(Double.NaN,
+ nagateDval));
+
+ /*
+ * If the first argument is positive zero and the second
+ * argument is greater than zero, or the first argument is
+ * positive infinity and the second argument is less than zero,
+ * then the result is positive zero.
+ */
+ assertEquals("Result should be Math.pow(" + 0.0 + "," + dval
+ + ")=" + 0.0, +0.0, Math.pow(0.0, dval));
+ assertEquals("Result should be Math.pow("
+ + Double.POSITIVE_INFINITY + "," + nagateDval + ")="
+ + 0.0, +0.0, Math.pow(Double.POSITIVE_INFINITY, nagateDval));
+
+ /*
+ * If the first argument is positive zero and the second
+ * argument is less than zero, or the first argument is positive
+ * infinity and the second argument is greater than zero, then
+ * the result is positive infinity.
+ */
+ assertEquals("Result should be Math.pow(" + 0.0 + ","
+ + nagateDval + ")=" + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY,
+ Math.pow(0.0, nagateDval));
+ assertEquals("Result should be Math.pow("
+ + Double.POSITIVE_INFINITY + "," + dval + ")="
+ + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Math.pow(
+ Double.POSITIVE_INFINITY, dval));
+
+ // Not a finite odd integer
+ if (dval % 2 == 0) {
+ /*
+ * If the first argument is negative zero and the second
+ * argument is greater than zero but not a finite odd
+ * integer, or the first argument is negative infinity and
+ * the second argument is less than zero but not a finite
+ * odd integer, then the result is positive zero.
+ */
+ assertEquals("Result should be Math.pow(" + NZERO + ","
+ + dval + ")=" + 0.0, +0.0, Math.pow(NZERO, dval));
+ assertEquals("Result should be Math.pow("
+ + Double.NEGATIVE_INFINITY + "," + nagateDval
+ + ")=" + 0.0, +0.0, Math.pow(Double.NEGATIVE_INFINITY,
+ nagateDval));
+
+ /*
+ * If the first argument is negative zero and the second
+ * argument is less than zero but not a finite odd integer,
+ * or the first argument is negative infinity and the second
+ * argument is greater than zero but not a finite odd
+ * integer, then the result is positive infinity.
+ */
+ assertEquals("Result should be Math.pow(" + NZERO + ","
+ + nagateDval + ")=" + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY,
+ Math.pow(NZERO, nagateDval));
+ assertEquals("Result should be Math.pow("
+ + Double.NEGATIVE_INFINITY + "," + dval + ")="
+ + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Math.pow(
+ Double.NEGATIVE_INFINITY, dval));
+ }
+
+ // finite odd integer
+ if (dval % 2 != 0) {
+ /*
+ * If the first argument is negative zero and the second
+ * argument is a positive finite odd integer, or the first
+ * argument is negative infinity and the second argument is
+ * a negative finite odd integer, then the result is
+ * negative zero.
+ */
+ assertEquals("Result should be Math.pow(" + NZERO + ","
+ + dval + ")=" + NZERO, NZERO, Math.pow(NZERO, dval));
+ assertEquals("Result should be Math.pow("
+ + Double.NEGATIVE_INFINITY + "," + nagateDval
+ + ")=" + NZERO, NZERO, Math.pow(Double.NEGATIVE_INFINITY,
+ nagateDval));
+ /*
+ * If the first argument is negative zero and the second
+ * argument is a negative finite odd integer, or the first
+ * argument is negative infinity and the second argument is
+ * a positive finite odd integer then the result is negative
+ * infinity.
+ */
+ assertEquals("Result should be Math.pow(" + NZERO + ","
+ + nagateDval + ")=" + Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY,
+ Math.pow(NZERO, nagateDval));
+ assertEquals("Result should be Math.pow("
+ + Double.NEGATIVE_INFINITY + "," + dval + ")="
+ + Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Math.pow(
+ Double.NEGATIVE_INFINITY, dval));
+ }
+
+ /**
+ * 1. If the first argument is finite and less than zero if the
+ * second argument is a finite even integer, the result is equal
+ * to the result of raising the absolute value of the first
+ * argument to the power of the second argument
+ *
+ * 2. if the second argument is a finite odd integer, the result is equal to the
+ * negative of the result of raising the absolute value of the
+ * first argument to the power of the second argument
+ *
+ * 3. if the second argument is finite and not an integer, then the result
+ * is NaN.
+ */
+ for (int j = 1; j < values.length; j++) {
+ double jval = values[j];
+ if (jval % 2.0 == 0.0) {
+ assertEquals("" + nagateDval + " " + jval, Math.pow(
+ dval, jval), Math.pow(nagateDval, jval));
+ } else {
+ assertEquals("" + nagateDval + " " + jval, -1.0
+ * Math.pow(dval, jval), Math.pow(nagateDval,
+ jval));
+ }
+ assertEquals(Double.NaN, Math
+ .pow(nagateDval, jval / 0.5467));
+ assertEquals(Double.NaN, Math.pow(nagateDval, -1.0 * jval
+ / 0.5467));
+ }
+ }
+
+ // If the absolute value of the first argument equals 1 and the
+ // second argument is infinite, then the result is NaN.
+ if (dval == 1) {
+ assertEquals("Result should be Math.pow(" + dval + ","
+ + Double.POSITIVE_INFINITY + ")=" + Double.NaN, Double.NaN, Math
+ .pow(dval, Double.POSITIVE_INFINITY));
+ assertEquals("Result should be Math.pow(" + dval + ","
+ + Double.NEGATIVE_INFINITY + ")=" + Double.NaN, Double.NaN, Math
+ .pow(dval, Double.NEGATIVE_INFINITY));
+
+ assertEquals("Result should be Math.pow(" + nagateDval + ","
+ + Double.POSITIVE_INFINITY + ")=" + Double.NaN, Double.NaN, Math
+ .pow(nagateDval, Double.POSITIVE_INFINITY));
+ assertEquals("Result should be Math.pow(" + nagateDval + ","
+ + Double.NEGATIVE_INFINITY + ")=" + Double.NaN, Double.NaN, Math
+ .pow(nagateDval, Double.NEGATIVE_INFINITY));
+ }
+
+ if (dval > 1) {
+ /*
+ * If the absolute value of the first argument is greater than 1
+ * and the second argument is positive infinity, or the absolute
+ * value of the first argument is less than 1 and the second
+ * argument is negative infinity, then the result is positive
+ * infinity.
+ */
+ assertEquals("Result should be Math.pow(" + dval + ","
+ + Double.POSITIVE_INFINITY + ")="
+ + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Math.pow(dval,
+ Double.POSITIVE_INFINITY));
+
+ assertEquals("Result should be Math.pow(" + nagateDval + ","
+ + Double.NEGATIVE_INFINITY + ")="
+ + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Math.pow(-0.13456,
+ Double.NEGATIVE_INFINITY));
+
+ /*
+ * If the absolute value of the first argument is greater than 1
+ * and the second argument is negative infinity, or the absolute
+ * value of the first argument is less than 1 and the second
+ * argument is positive infinity, then the result is positive
+ * zero.
+ */
+ assertEquals("Result should be Math.pow(" + dval + ","
+ + Double.NEGATIVE_INFINITY + ")= +0.0", +0.0, Math.pow(dval,
+ Double.NEGATIVE_INFINITY));
+ assertEquals("Result should be Math.pow(" + nagateDval + ","
+ + Double.POSITIVE_INFINITY + ")= +0.0", +0.0, Math.pow(
+ -0.13456, Double.POSITIVE_INFINITY));
+ }
+
+ assertEquals("Result should be Math.pow(" + 0.0 + "," + dval + ")="
+ + 0.0, 0.0, Math.pow(0.0, dval));
+ assertEquals("Result should be Math.pow(" + Double.NaN + "," + dval
+ + ")=" + Double.NaN, Double.NaN, Math.pow(Double.NaN, dval));
+ }
+ assertTrue("pow returned incorrect value",
+ (long) Math.pow(2, 8) == 256l);
+ assertTrue("pow returned incorrect value",
+ Math.pow(2, -8) == 0.00390625d);
+ assertEquals("Incorrect root returned1",
+ 2, Math.sqrt(Math.pow(Math.sqrt(2), 4)), 0);
+
+ assertEquals(Double.NEGATIVE_INFINITY, Math.pow(-10.0, 3.093403029238847E15));
+ assertEquals(Double.POSITIVE_INFINITY, Math.pow(10.0, 3.093403029238847E15));
+ }
+
+ private double longTodouble(long longvalue) {
+ return Double.longBitsToDouble(longvalue);
+ }
+
+ private long doubleTolong(double doublevalue) {
+ return Double.doubleToLongBits(doublevalue);
+ }
+
+ private double negateDouble(double doublevalue) {
+ return doublevalue * -1.0;
+ }
+
+ /**
+ * java.lang.Math#rint(double)
+ */
+ public void test_rintD() {
+ // Test for method double java.lang.Math.rint(double)
+ assertEquals("Failed to round properly - up to odd",
+ 3.0, Math.rint(2.9), 0D);
+ assertTrue("Failed to round properly - NaN", Double.isNaN(Math
+ .rint(Double.NaN)));
+ assertEquals("Failed to round properly down to even",
+ 2.0, Math.rint(2.1), 0D);
+ assertTrue("Failed to round properly " + 2.5 + " to even", Math
+ .rint(2.5) == 2.0);
+ assertTrue("Failed to round properly " + (+0.0d),
+ Math.rint(+0.0d) == +0.0d);
+ assertTrue("Failed to round properly " + (-0.0d),
+ Math.rint(-0.0d) == -0.0d);
+ }
+
+ /**
+ * java.lang.Math#round(double)
+ */
+ public void test_roundD() {
+ // Test for method long java.lang.Math.round(double)
+ assertEquals("Incorrect rounding of a float", -91, Math.round(-90.89d));
+ }
+
+ /**
+ * java.lang.Math#round(float)
+ */
+ public void test_roundF() {
+ // Test for method int java.lang.Math.round(float)
+ assertEquals("Incorrect rounding of a float", -91, Math.round(-90.89f));
+ }
+
+ /**
+ * {@link java.lang.Math#scalb(double, int)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_scalb_DI() {
+ // result is normal
+ assertEquals(4.1422946304E7, Math.scalb(1.2345, 25));
+ assertEquals(3.679096698760986E-8, Math.scalb(1.2345, -25));
+ assertEquals(1.2345, Math.scalb(1.2345, 0));
+ assertEquals(7868514.304, Math.scalb(0.2345, 25));
+
+ double normal = Math.scalb(0.2345, -25);
+ assertEquals(6.98864459991455E-9, normal);
+ // precision kept
+ assertEquals(0.2345, Math.scalb(normal, 25));
+
+ assertEquals(0.2345, Math.scalb(0.2345, 0));
+ assertEquals(-4.1422946304E7, Math.scalb(-1.2345, 25));
+ assertEquals(-6.98864459991455E-9, Math.scalb(-0.2345, -25));
+ assertEquals(2.0, Math.scalb(Double.MIN_NORMAL / 2, 1024));
+ assertEquals(64.0, Math.scalb(Double.MIN_VALUE, 1080));
+ assertEquals(234, Math.getExponent(Math.scalb(1.0, 234)));
+ assertEquals(3.9999999999999996, Math.scalb(Double.MAX_VALUE,
+ Double.MIN_EXPONENT));
+
+ // result is near infinity
+ double halfMax = Math.scalb(1.0, Double.MAX_EXPONENT);
+ assertEquals(8.98846567431158E307, halfMax);
+ assertEquals(Double.MAX_VALUE, halfMax - Math.ulp(halfMax) + halfMax);
+ assertEquals(Double.POSITIVE_INFINITY, halfMax + halfMax);
+ assertEquals(1.7976931348623155E308, Math.scalb(1.0 - Math.ulp(1.0),
+ Double.MAX_EXPONENT + 1));
+ assertEquals(Double.POSITIVE_INFINITY, Math.scalb(1.0 - Math.ulp(1.0),
+ Double.MAX_EXPONENT + 2));
+
+ halfMax = Math.scalb(-1.0, Double.MAX_EXPONENT);
+ assertEquals(-8.98846567431158E307, halfMax);
+ assertEquals(-Double.MAX_VALUE, halfMax + Math.ulp(halfMax) + halfMax);
+ assertEquals(Double.NEGATIVE_INFINITY, halfMax + halfMax);
+
+ assertEquals(Double.POSITIVE_INFINITY, Math.scalb(0.345, 1234));
+ assertEquals(Double.POSITIVE_INFINITY, Math.scalb(44.345E102, 934));
+ assertEquals(Double.NEGATIVE_INFINITY, Math.scalb(-44.345E102, 934));
+
+ assertEquals(Double.POSITIVE_INFINITY, Math.scalb(
+ Double.MIN_NORMAL / 2, 4000));
+ assertEquals(Double.POSITIVE_INFINITY, Math.scalb(Double.MIN_VALUE,
+ 8000));
+ assertEquals(Double.POSITIVE_INFINITY, Math.scalb(Double.MAX_VALUE, 1));
+ assertEquals(Double.POSITIVE_INFINITY, Math.scalb(
+ Double.POSITIVE_INFINITY, 0));
+ assertEquals(Double.POSITIVE_INFINITY, Math.scalb(
+ Double.POSITIVE_INFINITY, -1));
+ assertEquals(Double.NEGATIVE_INFINITY, Math.scalb(
+ Double.NEGATIVE_INFINITY, -1));
+ assertEquals(Double.NEGATIVE_INFINITY, Math.scalb(
+ Double.NEGATIVE_INFINITY, Double.MIN_EXPONENT));
+
+ // result is subnormal/zero
+ long posZeroBits = Double.doubleToLongBits(+0.0);
+ long negZeroBits = Double.doubleToLongBits(-0.0);
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(+0.0,
+ Integer.MAX_VALUE)));
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math
+ .scalb(+0.0, -123)));
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(+0.0, 0)));
+ assertEquals(negZeroBits, Double
+ .doubleToLongBits(Math.scalb(-0.0, 123)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(-0.0,
+ Integer.MIN_VALUE)));
+
+ assertEquals(Double.MIN_VALUE, Math.scalb(1.0, -1074));
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math
+ .scalb(1.0, -1075)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(-1.0,
+ -1075)));
+
+ // precision lost
+ assertEquals(Math.scalb(21.405, -1078), Math.scalb(21.405, -1079));
+ assertEquals(Double.MIN_VALUE, Math.scalb(21.405, -1079));
+ assertEquals(-Double.MIN_VALUE, Math.scalb(-21.405, -1079));
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(21.405,
+ -1080)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(-21.405,
+ -1080)));
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(
+ Double.MIN_VALUE, -1)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(
+ -Double.MIN_VALUE, -1)));
+ assertEquals(Double.MIN_VALUE, Math.scalb(Double.MIN_NORMAL, -52));
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(
+ Double.MIN_NORMAL, -53)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(
+ -Double.MIN_NORMAL, -53)));
+ assertEquals(Double.MIN_VALUE, Math.scalb(Double.MAX_VALUE, -2098));
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(
+ Double.MAX_VALUE, -2099)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(
+ -Double.MAX_VALUE, -2099)));
+ assertEquals(Double.MIN_VALUE, Math.scalb(Double.MIN_NORMAL / 3, -51));
+ assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(
+ Double.MIN_NORMAL / 3, -52)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(
+ -Double.MIN_NORMAL / 3, -52)));
+ double subnormal = Math.scalb(Double.MIN_NORMAL / 3, -25);
+ assertEquals(2.2104123E-316, subnormal);
+ // precision lost
+ assertFalse(Double.MIN_NORMAL / 3 == Math.scalb(subnormal, 25));
+
+ // NaN
+ assertTrue(Double.isNaN(Math.scalb(Double.NaN, 1)));
+ assertTrue(Double.isNaN(Math.scalb(Double.NaN, 0)));
+ assertTrue(Double.isNaN(Math.scalb(Double.NaN, -120)));
+
+ assertEquals(1283457024, Double.doubleToLongBits(Math.scalb(
+ Double.MIN_VALUE * 153, 23)));
+ assertEquals(-9223372035571318784L, Double.doubleToLongBits(Math.scalb(
+ -Double.MIN_VALUE * 153, 23)));
+ assertEquals(36908406321184768L, Double.doubleToLongBits(Math.scalb(
+ Double.MIN_VALUE * 153, 52)));
+ assertEquals(-9186463630533591040L, Double.doubleToLongBits(Math.scalb(
+ -Double.MIN_VALUE * 153, 52)));
+
+ // test for exception
+ try {
+ Math.scalb((Double) null, (Integer) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.scalb(1.0, (Integer) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.scalb((Double) null, 1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ long b1em1022 = 0x0010000000000000L; // bit representation of
+ // Double.MIN_NORMAL
+ long b1em1023 = 0x0008000000000000L; // bit representation of half of
+ // Double.MIN_NORMAL
+ // assert exact identity
+ assertEquals(b1em1023, Double.doubleToLongBits(Math.scalb(Double
+ .longBitsToDouble(b1em1022), -1)));
+ }
+
+ /**
+ * {@link java.lang.Math#scalb(float, int)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_scalb_FI() {
+ // result is normal
+ assertEquals(4.1422946304E7f, Math.scalb(1.2345f, 25));
+ assertEquals(3.679096698760986E-8f, Math.scalb(1.2345f, -25));
+ assertEquals(1.2345f, Math.scalb(1.2345f, 0));
+ assertEquals(7868514.304f, Math.scalb(0.2345f, 25));
+
+ float normal = Math.scalb(0.2345f, -25);
+ assertEquals(6.98864459991455E-9f, normal);
+ // precision kept
+ assertEquals(0.2345f, Math.scalb(normal, 25));
+
+ assertEquals(0.2345f, Math.scalb(0.2345f, 0));
+ assertEquals(-4.1422946304E7f, Math.scalb(-1.2345f, 25));
+ assertEquals(-6.98864459991455E-9f, Math.scalb(-0.2345f, -25));
+ assertEquals(2.0f, Math.scalb(Float.MIN_NORMAL / 2, 128));
+ assertEquals(64.0f, Math.scalb(Float.MIN_VALUE, 155));
+ assertEquals(34, Math.getExponent(Math.scalb(1.0f, 34)));
+ assertEquals(3.9999998f, Math
+ .scalb(Float.MAX_VALUE, Float.MIN_EXPONENT));
+
+ // result is near infinity
+ float halfMax = Math.scalb(1.0f, Float.MAX_EXPONENT);
+ assertEquals(1.7014118E38f, halfMax);
+ assertEquals(Float.MAX_VALUE, halfMax - Math.ulp(halfMax) + halfMax);
+ assertEquals(Float.POSITIVE_INFINITY, halfMax + halfMax);
+ assertEquals(3.4028233E38f, Math.scalb(1.0f - Math.ulp(1.0f),
+ Float.MAX_EXPONENT + 1));
+ assertEquals(Float.POSITIVE_INFINITY, Math.scalb(1.0f - Math.ulp(1.0f),
+ Float.MAX_EXPONENT + 2));
+
+ halfMax = Math.scalb(-1.0f, Float.MAX_EXPONENT);
+ assertEquals(-1.7014118E38f, halfMax);
+ assertEquals(-Float.MAX_VALUE, halfMax + Math.ulp(halfMax) + halfMax);
+ assertEquals(Float.NEGATIVE_INFINITY, halfMax + halfMax);
+
+ assertEquals(Float.POSITIVE_INFINITY, Math.scalb(0.345f, 1234));
+ assertEquals(Float.POSITIVE_INFINITY, Math.scalb(44.345E10f, 934));
+ assertEquals(Float.NEGATIVE_INFINITY, Math.scalb(-44.345E10f, 934));
+
+ assertEquals(Float.POSITIVE_INFINITY, Math.scalb(Float.MIN_NORMAL / 2,
+ 400));
+ assertEquals(Float.POSITIVE_INFINITY, Math.scalb(Float.MIN_VALUE, 800));
+ assertEquals(Float.POSITIVE_INFINITY, Math.scalb(Float.MAX_VALUE, 1));
+ assertEquals(Float.POSITIVE_INFINITY, Math.scalb(
+ Float.POSITIVE_INFINITY, 0));
+ assertEquals(Float.POSITIVE_INFINITY, Math.scalb(
+ Float.POSITIVE_INFINITY, -1));
+ assertEquals(Float.NEGATIVE_INFINITY, Math.scalb(
+ Float.NEGATIVE_INFINITY, -1));
+ assertEquals(Float.NEGATIVE_INFINITY, Math.scalb(
+ Float.NEGATIVE_INFINITY, Float.MIN_EXPONENT));
+
+ // result is subnormal/zero
+ int posZeroBits = Float.floatToIntBits(+0.0f);
+ int negZeroBits = Float.floatToIntBits(-0.0f);
+ assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(+0.0f,
+ Integer.MAX_VALUE)));
+ assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(+0.0f, -123)));
+ assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(+0.0f, 0)));
+ assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(-0.0f, 123)));
+ assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(-0.0f,
+ Integer.MIN_VALUE)));
+
+ assertEquals(Float.MIN_VALUE, Math.scalb(1.0f, -149));
+ assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(1.0f, -150)));
+ assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(-1.0f, -150)));
+
+ // precision lost
+ assertEquals(Math.scalb(21.405f, -154), Math.scalb(21.405f, -153));
+ assertEquals(Float.MIN_VALUE, Math.scalb(21.405f, -154));
+ assertEquals(-Float.MIN_VALUE, Math.scalb(-21.405f, -154));
+ assertEquals(posZeroBits, Float.floatToIntBits(Math
+ .scalb(21.405f, -155)));
+ assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(-21.405f,
+ -155)));
+ assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(
+ Float.MIN_VALUE, -1)));
+ assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(
+ -Float.MIN_VALUE, -1)));
+ assertEquals(Float.MIN_VALUE, Math.scalb(Float.MIN_NORMAL, -23));
+ assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(
+ Float.MIN_NORMAL, -24)));
+ assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(
+ -Float.MIN_NORMAL, -24)));
+ assertEquals(Float.MIN_VALUE, Math.scalb(Float.MAX_VALUE, -277));
+ assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(
+ Float.MAX_VALUE, -278)));
+ assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(
+ -Float.MAX_VALUE, -278)));
+ assertEquals(Float.MIN_VALUE, Math.scalb(Float.MIN_NORMAL / 3, -22));
+ assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(
+ Float.MIN_NORMAL / 3, -23)));
+ assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(
+ -Float.MIN_NORMAL / 3, -23)));
+ float subnormal = Math.scalb(Float.MIN_NORMAL / 3, -11);
+ assertEquals(1.913E-42f, subnormal);
+ // precision lost
+ assertFalse(Float.MIN_NORMAL / 3 == Math.scalb(subnormal, 11));
+
+ assertEquals(68747264, Float.floatToIntBits(Math.scalb(
+ Float.MIN_VALUE * 153, 23)));
+ assertEquals(-2078736384, Float.floatToIntBits(Math.scalb(
+ -Float.MIN_VALUE * 153, 23)));
+
+ assertEquals(4896, Float.floatToIntBits(Math.scalb(
+ Float.MIN_VALUE * 153, 5)));
+ assertEquals(-2147478752, Float.floatToIntBits(Math.scalb(
+ -Float.MIN_VALUE * 153, 5)));
+
+ // NaN
+ assertTrue(Float.isNaN(Math.scalb(Float.NaN, 1)));
+ assertTrue(Float.isNaN(Math.scalb(Float.NaN, 0)));
+ assertTrue(Float.isNaN(Math.scalb(Float.NaN, -120)));
+
+ // test for exception
+ try {
+ Math.scalb((Float) null, (Integer) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.scalb(1.0f, (Integer) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ Math.scalb((Float) null, 1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ int b1em126 = 0x00800000; // bit representation of Float.MIN_NORMAL
+ int b1em127 = 0x00400000; // bit representation of half
+ // Float.MIN_NORMAL
+ // assert exact identity
+ assertEquals(b1em127, Float.floatToIntBits(Math.scalb(Float
+ .intBitsToFloat(b1em126), -1)));
+ }
+
+ /**
+ * java.lang.Math#signum(double)
+ */
+ public void test_signum_D() {
+ assertTrue(Double.isNaN(Math.signum(Double.NaN)));
+ assertTrue(Double.isNaN(Math.signum(Double.NaN)));
+ assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
+ .signum(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(Math.signum(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(Math.signum(-0.0)));
+
+ assertEquals(1.0, Math.signum(253681.2187962), 0D);
+ assertEquals(-1.0, Math.signum(-125874693.56), 0D);
+ assertEquals(1.0, Math.signum(1.2587E-308), 0D);
+ assertEquals(-1.0, Math.signum(-1.2587E-308), 0D);
+
+ assertEquals(1.0, Math.signum(Double.MAX_VALUE), 0D);
+ assertEquals(1.0, Math.signum(Double.MIN_VALUE), 0D);
+ assertEquals(-1.0, Math.signum(-Double.MAX_VALUE), 0D);
+ assertEquals(-1.0, Math.signum(-Double.MIN_VALUE), 0D);
+ assertEquals(1.0, Math.signum(Double.POSITIVE_INFINITY), 0D);
+ assertEquals(-1.0, Math.signum(Double.NEGATIVE_INFINITY), 0D);
+ }
+
+ /**
+ * java.lang.Math#signum(float)
+ */
+ public void test_signum_F() {
+ assertTrue(Float.isNaN(Math.signum(Float.NaN)));
+ assertEquals(Float.floatToIntBits(0.0f), Float
+ .floatToIntBits(Math.signum(0.0f)));
+ assertEquals(Float.floatToIntBits(+0.0f), Float
+ .floatToIntBits(Math.signum(+0.0f)));
+ assertEquals(Float.floatToIntBits(-0.0f), Float
+ .floatToIntBits(Math.signum(-0.0f)));
+
+ assertEquals(1.0f, Math.signum(253681.2187962f), 0f);
+ assertEquals(-1.0f, Math.signum(-125874693.56f), 0f);
+ assertEquals(1.0f, Math.signum(1.2587E-11f), 0f);
+ assertEquals(-1.0f, Math.signum(-1.2587E-11f), 0f);
+
+ assertEquals(1.0f, Math.signum(Float.MAX_VALUE), 0f);
+ assertEquals(1.0f, Math.signum(Float.MIN_VALUE), 0f);
+ assertEquals(-1.0f, Math.signum(-Float.MAX_VALUE), 0f);
+ assertEquals(-1.0f, Math.signum(-Float.MIN_VALUE), 0f);
+ assertEquals(1.0f, Math.signum(Float.POSITIVE_INFINITY), 0f);
+ assertEquals(-1.0f, Math.signum(Float.NEGATIVE_INFINITY), 0f);
+ }
+
+ /**
+ * java.lang.Math#sin(double)
+ */
+ public void test_sinD() {
+ // Test for method double java.lang.Math.sin(double)
+ assertEquals("Incorrect answer", 0.0, Math.sin(0), 0D);
+ assertEquals("Incorrect answer", 0.8414709848078965, Math.sin(1), 0D);
+ }
+
+ /**
+ * java.lang.Math#sinh(double)
+ */
+ public void test_sinh_D() {
+ // Test for special situations
+ assertTrue(Double.isNaN(Math.sinh(Double.NaN)));
+ assertEquals(Double.POSITIVE_INFINITY, Math.sinh(Double.POSITIVE_INFINITY), 0D);
+ assertEquals(Double.NEGATIVE_INFINITY, Math.sinh(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math.sinh(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double.doubleToLongBits(Math.sinh(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double.doubleToLongBits(Math.sinh(-0.0)));
+
+ assertEquals(Double.POSITIVE_INFINITY, Math.sinh(1234.56), 0D);
+ assertEquals(Double.NEGATIVE_INFINITY, Math.sinh(-1234.56), 0D);
+ assertEquals(1.0000000000001666E-6, Math.sinh(0.000001), 0D);
+ assertEquals(-1.0000000000001666E-6, Math.sinh(-0.000001), 0D);
+ assertEquals(5.115386441963859, Math.sinh(2.33482), Math.ulp(5.115386441963859));
+ assertEquals(Double.POSITIVE_INFINITY, Math.sinh(Double.MAX_VALUE), 0D);
+ assertEquals(4.9E-324, Math.sinh(Double.MIN_VALUE), 0D);
+ }
+
+ /**
+ * java.lang.Math#sqrt(double)
+ */
+ public void test_sqrtD() {
+ // Test for method double java.lang.Math.sqrt(double)
+ assertEquals("Incorrect root returned2", 7, Math.sqrt(49), 0);
+ }
+
+ /**
+ * java.lang.Math#tan(double)
+ */
+ public void test_tanD() {
+ // Test for method double java.lang.Math.tan(double)
+ assertEquals("Incorrect answer", 0.0, Math.tan(0), 0D);
+ assertEquals("Incorrect answer", 1.5574077246549023, Math.tan(1), 0D);
+
+ }
+
+ /**
+ * java.lang.Math#tanh(double)
+ */
+ public void test_tanh_D() {
+ // Test for special situations
+ assertTrue("Should return NaN", Double.isNaN(Math.tanh(Double.NaN)));
+ assertEquals("Should return +1.0", +1.0, Math
+ .tanh(Double.POSITIVE_INFINITY), 0D);
+ assertEquals("Should return -1.0", -1.0, Math
+ .tanh(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
+ .tanh(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(Math.tanh(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(Math.tanh(-0.0)));
+
+ assertEquals("Should return 1.0", 1.0, Math.tanh(1234.56), 0D);
+ assertEquals("Should return -1.0", -1.0, Math.tanh(-1234.56), 0D);
+ assertEquals("Should return 9.999999999996666E-7",
+ 9.999999999996666E-7, Math.tanh(0.000001), 0D);
+ assertEquals("Should return 0.981422884124941", 0.981422884124941, Math
+ .tanh(2.33482), 0D);
+ assertEquals("Should return 1.0", 1.0, Math.tanh(Double.MAX_VALUE), 0D);
+ assertEquals("Should return 4.9E-324", 4.9E-324, Math
+ .tanh(Double.MIN_VALUE), 0D);
+ }
+
+ /**
+ * java.lang.Math#random()
+ */
+ public void test_random() {
+ // There isn't a place for these tests so just stick them here
+ assertEquals("Wrong value E",
+ 4613303445314885481L, Double.doubleToLongBits(Math.E));
+ assertEquals("Wrong value PI",
+ 4614256656552045848L, Double.doubleToLongBits(Math.PI));
+
+ for (int i = 500; i >= 0; i--) {
+ double d = Math.random();
+ assertTrue("Generated number is out of range: " + d, d >= 0.0
+ && d < 1.0);
+ }
+ }
+
+ /**
+ * java.lang.Math#toRadians(double)
+ */
+ public void test_toRadiansD() {
+ for (double d = 500; d >= 0; d -= 1.0) {
+ double converted = Math.toDegrees(Math.toRadians(d));
+ assertTrue("Converted number not equal to original. d = " + d,
+ converted >= d * 0.99999999 && converted <= d * 1.00000001);
+ }
+ }
+
+ /**
+ * java.lang.Math#toDegrees(double)
+ */
+ public void test_toDegreesD() {
+ for (double d = 500; d >= 0; d -= 1.0) {
+ double converted = Math.toRadians(Math.toDegrees(d));
+ assertTrue("Converted number not equal to original. d = " + d,
+ converted >= d * 0.99999999 && converted <= d * 1.00000001);
+ }
+ }
+
+ /**
+ * java.lang.Math#ulp(double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_ulp_D() {
+ // Test for special cases
+ assertTrue("Should return NaN", Double.isNaN(Math.ulp(Double.NaN)));
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, Math
+ .ulp(Double.POSITIVE_INFINITY), 0D);
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, Math
+ .ulp(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+ .ulp(0.0), 0D);
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+ .ulp(+0.0), 0D);
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+ .ulp(-0.0), 0D);
+ assertEquals("Returned incorrect value", Math.pow(2, 971), Math
+ .ulp(Double.MAX_VALUE), 0D);
+ assertEquals("Returned incorrect value", Math.pow(2, 971), Math
+ .ulp(-Double.MAX_VALUE), 0D);
+
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+ .ulp(Double.MIN_VALUE), 0D);
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+ .ulp(-Double.MIN_VALUE), 0D);
+
+ assertEquals("Returned incorrect value", 2.220446049250313E-16, Math
+ .ulp(1.0), 0D);
+ assertEquals("Returned incorrect value", 2.220446049250313E-16, Math
+ .ulp(-1.0), 0D);
+ assertEquals("Returned incorrect value", 2.2737367544323206E-13, Math
+ .ulp(1153.0), 0D);
+ }
+
+ /**
+ * java.lang.Math#ulp(float)
+ */
+ @SuppressWarnings("boxing")
+ public void test_ulp_f() {
+ // Test for special cases
+ assertTrue("Should return NaN", Float.isNaN(Math.ulp(Float.NaN)));
+ assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, Math
+ .ulp(Float.POSITIVE_INFINITY), 0f);
+ assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, Math
+ .ulp(Float.NEGATIVE_INFINITY), 0f);
+ assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
+ .ulp(0.0f), 0f);
+ assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
+ .ulp(+0.0f), 0f);
+ assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
+ .ulp(-0.0f), 0f);
+ assertEquals("Returned incorrect value", 2.028241E31f, Math
+ .ulp(Float.MAX_VALUE), 0f);
+ assertEquals("Returned incorrect value", 2.028241E31f, Math
+ .ulp(-Float.MAX_VALUE), 0f);
+
+ assertEquals("Returned incorrect value", 1.4E-45f, Math
+ .ulp(Float.MIN_VALUE), 0f);
+ assertEquals("Returned incorrect value", 1.4E-45f, Math
+ .ulp(-Float.MIN_VALUE), 0f);
+
+ assertEquals("Returned incorrect value", 1.1920929E-7f, Math.ulp(1.0f),
+ 0f);
+ assertEquals("Returned incorrect value", 1.1920929E-7f,
+ Math.ulp(-1.0f), 0f);
+ assertEquals("Returned incorrect value", 1.2207031E-4f, Math
+ .ulp(1153.0f), 0f);
+ assertEquals("Returned incorrect value", 5.6E-45f, Math
+ .ulp(9.403954E-38f), 0f);
+ }
+
+ /**
+ * {@link java.lang.Math#shiftIntBits(int, int)}
+ * @since 1.6
+ */
+ public void test_shiftIntBits_II() {
+ class Tuple {
+ public int result;
+
+ public int value;
+
+ public int factor;
+
+ public Tuple(int result, int value, int factor) {
+ this.result = result;
+ this.value = value;
+ this.factor = factor;
+ }
+ }
+ final Tuple[] TUPLES = new Tuple[] {
+ // sub-normal to sub-normal
+ new Tuple(0x00000000, 0x00000001, -1),
+ // round to even
+ new Tuple(0x00000002, 0x00000003, -1),
+ // round to even
+ new Tuple(0x00000001, 0x00000005, -3),
+ // round to infinity
+ new Tuple(0x00000002, 0x0000000d, -3),
+ // round to infinity
+
+ // normal to sub-normal
+ new Tuple(0x00000002, 0x01a00000, -24),
+ // round to even
+ new Tuple(0x00000004, 0x01e00000, -24),
+ // round to even
+ new Tuple(0x00000003, 0x01c80000, -24),
+ // round to infinity
+ new Tuple(0x00000004, 0x01e80000, -24),
+ // round to infinity
+ };
+ for (int i = 0; i < TUPLES.length; ++i) {
+ Tuple tuple = TUPLES[i];
+ assertEquals(tuple.result, Float.floatToIntBits(Math.scalb(Float
+ .intBitsToFloat(tuple.value), tuple.factor)));
+ assertEquals(tuple.result, Float.floatToIntBits(-Math.scalb(-Float
+ .intBitsToFloat(tuple.value), tuple.factor)));
+ }
+ }
+
+ /**
+ * {@link java.lang.Math#shiftLongBits(long, long)}
+ * <p/>
+ * Round result to nearest value on precision lost.
+ * @since 1.6
+ */
+ public void test_shiftLongBits_LL() {
+ class Tuple {
+ public long result;
+
+ public long value;
+
+ public int factor;
+
+ public Tuple(long result, long value, int factor) {
+ this.result = result;
+ this.value = value;
+ this.factor = factor;
+ }
+ }
+ final Tuple[] TUPLES = new Tuple[] {
+ // sub-normal to sub-normal
+ new Tuple(0x00000000L, 0x00000001L, -1),
+ //round to even
+ new Tuple(0x00000002L, 0x00000003L, -1),
+ //round to even
+ new Tuple(0x00000001L, 0x00000005L, -3),
+ //round to infinity
+ new Tuple(0x00000002L, 0x0000000dL, -3),
+ //round to infinity
+
+ // normal to sub-normal
+ new Tuple(0x0000000000000002L, 0x0034000000000000L, -53), // round to even
+ new Tuple(0x0000000000000004L, 0x003c000000000000L, -53), // round to even
+ new Tuple(0x0000000000000003L, 0x0035000000000000L, -53), // round to infinity
+ new Tuple(0x0000000000000004L, 0x003d000000000000L, -53), // round to infinity
+ };
+ for (int i = 0; i < TUPLES.length; ++i) {
+ Tuple tuple = TUPLES[i];
+ assertEquals(tuple.result, Double.doubleToLongBits(Math.scalb(
+ Double.longBitsToDouble(tuple.value), tuple.factor)));
+ assertEquals(tuple.result, Double.doubleToLongBits(-Math.scalb(
+ -Double.longBitsToDouble(tuple.value), tuple.factor)));
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MockEnum.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MockEnum.java
new file mode 100644
index 0000000..94260c4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MockEnum.java
@@ -0,0 +1,57 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.Serializable;
+
+class MockEnum implements Serializable {
+ private static final long serialVersionUID = -1678507713086705252L;
+
+ enum Sample {
+ LARRY, MOE, CURLY
+ }
+
+ enum Sample2 {
+ RED, BLUE, YELLO
+ }
+
+ String str;
+
+ int i;
+
+ Sample2 samEnum;
+
+ Sample larry = Sample.LARRY;
+
+ MockEnum() {
+ str = "test";
+ i = 99;
+ samEnum = Sample2.BLUE;
+ }
+
+ public boolean equals(Object arg0) {
+ if (!(arg0 instanceof MockEnum)) {
+ return false;
+ }
+ MockEnum test = (MockEnum) arg0;
+ if (str.equals(test.str) && i == test.i && samEnum == test.samEnum) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MockEnum2.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MockEnum2.java
new file mode 100644
index 0000000..1dc5341
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/MockEnum2.java
@@ -0,0 +1,61 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.Serializable;
+
+class MockEnum2 implements Serializable {
+
+ private static final long serialVersionUID = -4812214670022262730L;
+
+ enum Sample {
+ LARRY, MOE, CURLY
+ }
+
+ enum Sample2 {
+ RED, BLUE, YELLO
+ }
+
+ String str;
+
+ int i;
+
+ Sample samEnum;
+
+ Sample larry = Sample.LARRY;
+
+ String myStr = "LARRY";
+
+ MockEnum2() {
+ str = "test";
+ i = 99;
+ samEnum = larry;
+ }
+
+ public boolean equals(Object arg0) {
+ if (!(arg0 instanceof MockEnum2)) {
+ return false;
+ }
+ MockEnum2 test = (MockEnum2) arg0;
+ if (str.equals(test.str) && i == test.i && samEnum == test.samEnum
+ && myStr.equals(test.myStr)) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NegativeArraySizeExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NegativeArraySizeExceptionTest.java
new file mode 100644
index 0000000..1717f3a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NegativeArraySizeExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class NegativeArraySizeExceptionTest extends TestCase {
+
+ /**
+ * java.lang.NegativeArraySizeException#NegativeArraySizeException()
+ */
+ public void test_Constructor() {
+ NegativeArraySizeException e = new NegativeArraySizeException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.NegativeArraySizeException#NegativeArraySizeException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ NegativeArraySizeException e = new NegativeArraySizeException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoClassDefFoundErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoClassDefFoundErrorTest.java
new file mode 100644
index 0000000..9421a73
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoClassDefFoundErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class NoClassDefFoundErrorTest extends TestCase {
+
+ /**
+ * java.lang.NoClassDefFoundError#NoClassDefFoundError()
+ */
+ public void test_Constructor() {
+ NoClassDefFoundError e = new NoClassDefFoundError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.NoClassDefFoundError#NoClassDefFoundError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ NoClassDefFoundError e = new NoClassDefFoundError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchFieldErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchFieldErrorTest.java
new file mode 100644
index 0000000..e405599
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchFieldErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class NoSuchFieldErrorTest extends TestCase {
+
+ /**
+ * java.lang.NoSuchFieldError#NoSuchFieldError()
+ */
+ public void test_Constructor() {
+ NoSuchFieldError e = new NoSuchFieldError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.NoSuchFieldError#NoSuchFieldError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ NoSuchFieldError e = new NoSuchFieldError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchFieldExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchFieldExceptionTest.java
new file mode 100644
index 0000000..5562669
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchFieldExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class NoSuchFieldExceptionTest extends TestCase {
+
+ /**
+ * java.lang.NoSuchFieldException#NoSuchFieldException()
+ */
+ public void test_Constructor() {
+ NoSuchFieldException e = new NoSuchFieldException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.NoSuchFieldException#NoSuchFieldException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ NoSuchFieldException e = new NoSuchFieldException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchMethodErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchMethodErrorTest.java
new file mode 100644
index 0000000..1367e03
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchMethodErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class NoSuchMethodErrorTest extends TestCase {
+
+ /**
+ * java.lang.NoSuchMethodError#NoSuchMethodError()
+ */
+ public void test_Constructor() {
+ NoSuchMethodError e = new NoSuchMethodError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.NoSuchMethodError#NoSuchMethodError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ NoSuchMethodError e = new NoSuchMethodError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchMethodExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchMethodExceptionTest.java
new file mode 100644
index 0000000..7bd9e0a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NoSuchMethodExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class NoSuchMethodExceptionTest extends TestCase {
+
+ /**
+ * java.lang.NoSuchMethodException#NoSuchMethodException()
+ */
+ public void test_Constructor() {
+ NoSuchMethodException e = new NoSuchMethodException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.NoSuchMethodException#NoSuchMethodException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ NoSuchMethodException e = new NoSuchMethodException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NullPointerExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NullPointerExceptionTest.java
new file mode 100644
index 0000000..9c4a72b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NullPointerExceptionTest.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class NullPointerExceptionTest extends TestCase {
+
+ /**
+ * java.lang.NullPointerException#NullPointerException()
+ */
+ public void test_Constructor() {
+ NullPointerException e = new NullPointerException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.NullPointerException#NullPointerException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ NullPointerException e = new NullPointerException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NumberFormatExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NumberFormatExceptionTest.java
new file mode 100644
index 0000000..614c51b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NumberFormatExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class NumberFormatExceptionTest extends TestCase {
+
+ /**
+ * java.lang.NumberFormatException#NumberFormatException()
+ */
+ public void test_Constructor() {
+ NumberFormatException e = new NumberFormatException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.NumberFormatException#NumberFormatException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ NumberFormatException e = new NumberFormatException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NumberTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NumberTest.java
new file mode 100644
index 0000000..809a31a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/NumberTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+public class NumberTest extends junit.framework.TestCase {
+
+ /**
+ * java.lang.Number#byteValue()
+ */
+ public void test_byteValue() {
+ int number = 1231243;
+ assertTrue("Incorrect byte returned for: " + number,
+ ((byte) new Integer(number).intValue()) == new Integer(number)
+ .byteValue());
+ number = 0;
+ assertTrue("Incorrect byte returned for: " + number,
+ ((byte) new Integer(number).intValue()) == new Integer(number)
+ .byteValue());
+ number = -1;
+ assertTrue("Incorrect byte returned for: " + number,
+ ((byte) new Integer(number).intValue()) == new Integer(number)
+ .byteValue());
+ number = -84109328;
+ assertTrue("Incorrect byte returned for: " + number,
+ ((byte) new Integer(number).intValue()) == new Integer(number)
+ .byteValue());
+ }
+
+ /**
+ * java.lang.Number#shortValue()
+ */
+ public void test_shortValue() {
+ int number = 1231243;
+ assertTrue("Incorrect byte returned for: " + number,
+ ((short) new Integer(number).intValue()) == new Integer(number)
+ .shortValue());
+ number = 0;
+ assertTrue("Incorrect byte returned for: " + number,
+ ((short) new Integer(number).intValue()) == new Integer(number)
+ .shortValue());
+ number = -1;
+ assertTrue("Incorrect byte returned for: " + number,
+ ((short) new Integer(number).intValue()) == new Integer(number)
+ .shortValue());
+ number = -84109328;
+ assertTrue("Incorrect byte returned for: " + number,
+ ((short) new Integer(number).intValue()) == new Integer(number)
+ .shortValue());
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ObjectTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ObjectTest.java
new file mode 100644
index 0000000..9dca8e9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ObjectTest.java
@@ -0,0 +1,388 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang;
+
+public class ObjectTest extends junit.framework.TestCase {
+
+ /**
+ * Test objects.
+ */
+ Object obj1 = new Object();
+
+ Object obj2 = new Object();
+
+ /**
+ * Generic state indicator.
+ */
+ int status = 0;
+
+ int ready = 0;
+
+ /**
+ * java.lang.Object#Object()
+ */
+ public void test_Constructor() {
+ // Test for method java.lang.Object()
+ assertNotNull("Constructor failed !!!", new Object());
+ }
+
+ /**
+ * java.lang.Object#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean java.lang.Object.equals(java.lang.Object)
+ assertTrue("Same object should be equal", obj1.equals(obj1));
+ assertTrue("Different objects should not be equal", !obj1.equals(obj2));
+ }
+
+ /**
+ * java.lang.Object#getClass()
+ */
+ public void test_getClass() throws Exception {
+ // Test for method java.lang.Class java.lang.Object.getClass()
+ String classNames[] = { "java.lang.Object", "java.lang.Throwable",
+ "java.lang.StringBuffer" };
+ Class<?> classToTest = null;
+ Object instanceToTest = null;
+
+ status = 0;
+ for (int i = 0; i < classNames.length; ++i) {
+ classToTest = Class.forName(classNames[i]);
+ instanceToTest = classToTest.newInstance();
+ assertTrue("Instance didn't match creator class.",
+ instanceToTest.getClass() == classToTest);
+ assertTrue("Instance didn't match class with matching name.",
+ instanceToTest.getClass() == Class
+ .forName(classNames[i]));
+ }
+ }
+
+ /**
+ * java.lang.Object#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.lang.Object.hashCode()
+ assertTrue("Same object should have same hash.",
+ obj1.hashCode() == obj1.hashCode());
+ assertTrue("Same object should have same hash.",
+ obj2.hashCode() == obj2.hashCode());
+ }
+
+ /**
+ * java.lang.Object#notify()
+ */
+ public void test_notify() {
+ // Test for method void java.lang.Object.notify()
+
+ // Inner class to run test thread.
+ class TestThread implements Runnable {
+ public void run() {
+ synchronized (obj1) {
+ try {
+ ready += 1;
+ obj1.wait();// Wait for ever.
+ status += 1;
+ } catch (InterruptedException ex) {
+ status = -1000;
+ }
+ }
+ }
+ }
+ ;
+
+ // Start of test code.
+
+ // Warning:
+ // This code relies on each thread getting serviced within
+ // 200 mSec of when it is notified. Although this
+ // seems reasonable, it could lead to false-failures.
+
+ ready = 0;
+ status = 0;
+ final int readyWaitSecs = 3;
+
+ final int threadCount = 20;
+ for (int i = 0; i < threadCount; ++i) {
+ new Thread(new TestThread()).start();
+ }
+ synchronized (obj1) {
+ try {
+
+ // Wait up to readyWaitSeconds for all threads to be waiting on
+ // monitor
+ for (int i = 0; i < readyWaitSecs; i++) {
+ obj1.wait(1000, 0);
+ if (ready == threadCount) {
+ break;
+ }
+ }
+
+ // Check pre-conditions of testing notifyAll
+ assertTrue("Not all launched threads are waiting. (ready = "
+ + ready + ")", ready == threadCount);
+ assertTrue("Thread woke too early. (status = " + status + ")",
+ status == 0);
+
+ for (int i = 1; i <= threadCount; ++i) {
+ obj1.notify();
+ obj1.wait(200, 0);
+ assertTrue("Out of sync. (expected " + i + " but got "
+ + status + ")", status == i);
+ }
+
+ } catch (InterruptedException ex) {
+ fail(
+ "Unexpectedly got an InterruptedException. (status = "
+ + status + ")");
+ }
+ }
+ }
+
+ /**
+ * java.lang.Object#notifyAll()
+ */
+ public void test_notifyAll() {
+ // Test for method void java.lang.Object.notifyAll()
+
+ // Inner class to run test thread.
+ class TestThread implements Runnable {
+ public void run() {
+ synchronized (obj1) {
+ try {
+ ready += 1;
+ obj1.wait();// Wait for ever.
+ status += 1;
+ } catch (InterruptedException ex) {
+ status = -1000;
+ }
+ }
+ }
+ }
+ ;
+
+ // Start of test code.
+
+ // Warning:
+ // This code relies on all threads getting serviced within
+ // 5 seconds of when they are notified. Although this
+ // seems reasonable, it could lead to false-failures.
+
+ status = 0;
+ ready = 0;
+ final int readyWaitSecs = 3;
+ final int threadCount = 20;
+ for (int i = 0; i < threadCount; ++i) {
+ new Thread(new TestThread()).start();
+ }
+
+ synchronized (obj1) {
+
+ try {
+
+ // Wait up to readyWaitSeconds for all threads to be waiting on
+ // monitor
+ for (int i = 0; i < readyWaitSecs; i++) {
+ obj1.wait(1000, 0);
+ if (ready == threadCount) {
+ break;
+ }
+ }
+
+ // Check pre-conditions of testing notifyAll
+ assertTrue("Not all launched threads are waiting. (ready = "
+ + ready + ")", ready == threadCount);
+ assertTrue("At least one thread woke too early. (status = "
+ + status + ")", status == 0);
+
+ obj1.notifyAll();
+
+ obj1.wait(5000, 0);
+
+ assertTrue(
+ "At least one thread did not get notified. (status = "
+ + status + ")", status == threadCount);
+
+ } catch (InterruptedException ex) {
+ fail(
+ "Unexpectedly got an InterruptedException. (status = "
+ + status + ")");
+ }
+
+ }
+ }
+
+ /**
+ * java.lang.Object#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.lang.Object.toString()
+ assertNotNull("Object toString returned null.", obj1.toString());
+ }
+
+ /**
+ * java.lang.Object#wait()
+ */
+ public void test_wait() {
+ // Test for method void java.lang.Object.wait()
+
+ // Inner class to run test thread.
+ class TestThread implements Runnable {
+ public void run() {
+ synchronized (obj1) {
+ try {
+ obj1.wait();// Wait for ever.
+ status = 1;
+ } catch (InterruptedException ex) {
+ status = -1;
+ }
+ }
+ }
+ }
+ ;
+
+ // Start of test code.
+
+ // Warning:
+ // This code relies on threads getting serviced within
+ // 1 second of when they are notified. Although this
+ // seems reasonable, it could lead to false-failures.
+
+ status = 0;
+ new Thread(new TestThread()).start();
+ synchronized (obj1) {
+ try {
+ obj1.wait(1000, 0);
+ assertTrue("Thread woke too early. (status = " + status + ")",
+ status == 0);
+ obj1.notifyAll();
+ obj1.wait(1000, 0);
+ assertTrue("Thread did not get notified. (status = " + status
+ + ")", status == 1);
+ } catch (InterruptedException ex) {
+ fail(
+ "Unexpectedly got an InterruptedException. (status = "
+ + status + ")");
+ }
+ }
+ }
+
+ /**
+ * java.lang.Object#wait(long)
+ */
+ public void test_waitJ() {
+ // Test for method void java.lang.Object.wait(long)
+
+ // Start of test code.
+
+ final int loopCount = 20;
+ final int allowableError = 100; // millesconds
+ final int delay = 200; // milliseconds
+ synchronized (obj1) {
+ try {
+ int count = 0;
+ long[][] toLong = new long[3][3];
+ for (int i = 0; i < loopCount; ++i) {
+ long before = System.currentTimeMillis();
+ obj1.wait(delay, 0);
+ long after = System.currentTimeMillis();
+ long error = (after - before - delay);
+ if (error < 0)
+ error = -error;
+ if (i > 0 && error > allowableError) {
+ // Allow jit to warm up before testing
+ if (count < toLong.length) {
+ toLong[count][0] = i;
+ toLong[count][1] = before;
+ toLong[count][2] = after;
+ count++;
+ }
+ if (error > (1000 + delay) || count == toLong.length) {
+ StringBuffer sb = new StringBuffer();
+ for (int j = 0; j < count; j++) {
+ sb
+ .append("wakeup time too inaccurate, iteration ");
+ sb.append(toLong[j][0]);
+ sb.append(", before: ");
+ sb.append(toLong[j][1]);
+ sb.append(" after: ");
+ sb.append(toLong[j][2]);
+ sb.append(" diff: ");
+ sb.append(toLong[j][2] - toLong[j][1]);
+ sb.append("\n");
+ }
+ fail(sb.toString());
+ }
+ }
+ }
+ } catch (InterruptedException ex) {
+ fail(
+ "Unexpectedly got an InterruptedException. (status = "
+ + status + ")");
+ }
+ }
+ }
+
+ /**
+ * java.lang.Object#wait(long, int)
+ */
+ public void test_waitJI() {
+ // Test for method void java.lang.Object.wait(long, int)
+
+ // Inner class to run test thread.
+ class TestThread implements Runnable {
+ public void run() {
+ synchronized (obj1) {
+ try {
+ obj1.wait(0, 1); // Don't wait very long.
+ status = 1;
+ obj1.wait(0, 0); // Wait for ever.
+ status = 2;
+ } catch (InterruptedException ex) {
+ status = -1;
+ }
+ }
+ }
+ }
+ ;
+
+ // Start of test code.
+
+ // Warning:
+ // This code relies on threads getting serviced within
+ // 1 second of when they are notified. Although this
+ // seems reasonable, it could lead to false-failures.
+
+ status = 0;
+ new Thread(new TestThread()).start();
+ synchronized (obj1) {
+ try {
+ obj1.wait(1000, 0);
+ assertTrue("Thread did not wake after 1 ms. (status = "
+ + status + ")", status == 1);
+ obj1.notifyAll();
+ obj1.wait(1000, 0);
+ assertTrue("Thread did not get notified. (status = " + status
+ + ")", status == 2);
+ } catch (InterruptedException ex) {
+ fail(
+ "Unexpectedly got an InterruptedException. (status = "
+ + status + ")");
+ }
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/OutOfMemoryErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/OutOfMemoryErrorTest.java
new file mode 100644
index 0000000..b962455
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/OutOfMemoryErrorTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+public class OutOfMemoryErrorTest extends junit.framework.TestCase {
+
+ /**
+ * java.lang.OutOfMemoryError#OutOfMemoryError()
+ */
+ public void test_Constructor() {
+ // Test for method java.lang.OutOfMemoryError()
+ Error e = new OutOfMemoryError();
+ assertNull(e.getCause());
+ assertNull(e.getMessage());
+ }
+
+ /**
+ * java.lang.OutOfMemoryError#OutOfMemoryError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.lang.OutOfMemoryError(java.lang.String)
+ Error e = new OutOfMemoryError(null);
+ assertNull(e.getMessage());
+ assertNull(e.getCause());
+
+ e = new OutOfMemoryError("msg");
+ assertEquals("msg", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Process2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Process2Test.java
new file mode 100644
index 0000000..649488c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Process2Test.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import dalvik.annotation.AndroidOnly;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import tests.support.Support_Exec;
+import static tests.support.Support_Exec.javaProcessBuilder;
+
+public class Process2Test extends junit.framework.TestCase {
+ /**
+ * java.lang.Process#getInputStream(),
+ * java.lang.Process#getErrorStream()
+ * java.lang.Process#getOutputStream()
+ * Tests if these methods return buffered streams.
+ */
+ @AndroidOnly("dalvikvm specific")
+ public void test_streams()
+ throws IOException, InterruptedException {
+ Process p = javaProcessBuilder().start();
+ assertNotNull(p.getInputStream());
+ assertNotNull(p.getErrorStream());
+ assertNotNull(p.getOutputStream());
+ }
+
+ public void test_getErrorStream() {
+ String[] commands = {"ls"};
+ Process process = null;
+ try {
+ process = Runtime.getRuntime().exec(commands, null, null);
+ InputStream is = process.getErrorStream();
+ StringBuffer msg = new StringBuffer("");
+ while (true) {
+ int c = is.read();
+ if (c == -1)
+ break;
+ msg.append((char) c);
+ }
+ assertEquals("", msg.toString());
+ } catch (IOException e) {
+ fail("IOException was thrown.");
+ } finally {
+ process.destroy();
+ }
+
+ String[] unknownCommands = {"mkdir", "-u", "test"};
+ Process erProcess = null;
+ try {
+ erProcess = Runtime.getRuntime().exec(unknownCommands, null, null);
+ InputStream is = erProcess.getErrorStream();
+ StringBuffer msg = new StringBuffer("");
+ while (true) {
+ int c = is.read();
+ if (c == -1)
+ break;
+ msg.append((char) c);
+ }
+ assertTrue("Error stream should not be empty",
+ !"".equals(msg.toString()));
+ } catch (IOException e) {
+ fail("IOException was thrown.");
+ } finally {
+ erProcess.destroy();
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessBuilderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessBuilderTest.java
new file mode 100644
index 0000000..87cf88c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessBuilderTest.java
@@ -0,0 +1,171 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class ProcessBuilderTest extends TestCase {
+
+ public void testProcessBuilderStringArray() {
+
+ }
+
+ public void testProcessBuilderListOfString() {
+ try {
+ new ProcessBuilder((List<String>) null);
+ fail("no null pointer exception");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void testCommand() {
+ ProcessBuilder pb = new ProcessBuilder("command");
+ assertEquals(1, pb.command().size());
+ assertEquals("command", pb.command().get(0));
+
+ // Regression for HARMONY-2675
+ pb = new ProcessBuilder("AAA");
+ pb.command("BBB", "CCC");
+ List<String> list = pb.command();
+ list.add("DDD");
+ String[] command = new String[3];
+ list.toArray(command);
+ assertTrue(Arrays.equals(new String[] { "BBB", "CCC", "DDD" }, command));
+ }
+
+ public void testCommandStringArray() {
+ ProcessBuilder pb = new ProcessBuilder("command");
+ ProcessBuilder pbReturn = pb.command("cmd");
+ assertSame(pb, pbReturn);
+ assertEquals(1, pb.command().size());
+ assertEquals("cmd", pb.command().get(0));
+ }
+
+ public void testCommandListOfString() {
+ ProcessBuilder pb = new ProcessBuilder("command");
+ List<String> newCmd = new ArrayList<String>();
+ newCmd.add("cmd");
+ ProcessBuilder pbReturn = pb.command(newCmd);
+ assertSame(pb, pbReturn);
+ assertEquals(1, pb.command().size());
+ assertEquals("cmd", pb.command().get(0));
+
+ newCmd.add("arg");
+ assertEquals(2, pb.command().size());
+ assertEquals("cmd", pb.command().get(0));
+ assertEquals("arg", pb.command().get(1));
+ }
+
+ public void testDirectory() {
+ ProcessBuilder pb = new ProcessBuilder("command");
+ assertNull(pb.directory());
+ }
+
+ public void testDirectoryFile() {
+ ProcessBuilder pb = new ProcessBuilder("command");
+ File dir = new File(System.getProperty("java.io.tmpdir"));
+ ProcessBuilder pbReturn = pb.directory(dir);
+ assertSame(pb, pbReturn);
+ assertEquals(dir, pb.directory());
+
+ pbReturn = pb.directory(null);
+ assertSame(pb, pbReturn);
+ assertNull(pb.directory());
+ }
+
+ public void testEnvironment() {
+ ProcessBuilder pb = new ProcessBuilder("command");
+ Map<String, String> env = pb.environment();
+ assertEquals(System.getenv(), env);
+ env.clear();
+ env = pb.environment();
+ assertTrue(env.isEmpty());
+ try {
+ env.put(null, "");
+ fail("should throw NPE.");
+ } catch (NullPointerException e) {
+ // expected;
+ }
+ try {
+ env.put("", null);
+ fail("should throw NPE.");
+ } catch (NullPointerException e) {
+ // expected;
+ }
+ try {
+ env.get(null);
+ fail("should throw NPE.");
+ } catch (NullPointerException e) {
+ // expected;
+ }
+ try {
+ assertNull(env.get(new Object()));
+ // Android's get doesn't throw (because it's just a regular HashMap).
+ // fail("should throw ClassCastException.");
+ } catch (ClassCastException thrownByRi) {
+ }
+ }
+
+ public void testRedirectErrorStream() {
+ ProcessBuilder pb = new ProcessBuilder("command");
+ assertFalse(pb.redirectErrorStream());
+ }
+
+ public void testRedirectErrorStreamBoolean() {
+ ProcessBuilder pb = new ProcessBuilder("command");
+ ProcessBuilder pbReturn = pb.redirectErrorStream(true);
+ assertSame(pb, pbReturn);
+ assertTrue(pb.redirectErrorStream());
+ }
+
+ /**
+ * @throws IOException
+ * {@link java.lang.ProcessBuilder#start()}
+ */
+ @SuppressWarnings("nls")
+ public void testStart() throws IOException {
+ ProcessBuilder pb = new ProcessBuilder("ls", "-al");
+
+ // Call the test target
+ Process process = pb.start();
+ InputStream in = process.getInputStream();
+ InputStream err = process.getErrorStream();
+
+ while (true) {
+ try {
+ process.waitFor();
+ break;
+ } catch (InterruptedException e) {
+ // Ignored
+ }
+ }
+
+ byte[] buf = new byte[1024];
+ if (in.available() > 0) {
+ assertTrue(in.read(buf) > 0);
+ } else {
+ assertTrue(err.read(buf) > 0);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
new file mode 100644
index 0000000..9f7474a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+public class ProcessManagerTest extends TestCase {
+
+ Thread thread = null;
+ Process process = null;
+ boolean isThrown = false;
+
+ public void testCat() throws IOException, InterruptedException {
+ String[] commands = { "cat" };
+ Process process = Runtime.getRuntime().exec(commands, null, null);
+
+ OutputStream out = process.getOutputStream();
+ String greeting = "Hello, World!";
+ out.write(greeting.getBytes());
+ out.write('\n');
+ out.close();
+
+ assertEquals(greeting, readLine(process));
+ }
+
+ // BrokenTest: Sporadic failures in CTS, but not in CoreTestRunner
+ public void testSleep() throws IOException {
+ String[] commands = { "sleep", "1" };
+ process = Runtime.getRuntime().exec(commands, null, null);
+ try {
+ assertEquals(0, process.waitFor());
+
+ } catch(InterruptedException ie) {
+ fail("InterruptedException was thrown.");
+ }
+
+ isThrown = false;
+ thread = new Thread() {
+ public void run() {
+ String[] commands = { "sleep", "1000"};
+ try {
+ process = Runtime.getRuntime().exec(commands, null, null);
+ } catch (IOException e1) {
+ fail("IOException was thrown.");
+ }
+ try {
+ process.waitFor();
+ fail("InterruptedException was not thrown.");
+ } catch(InterruptedException ie) {
+ isThrown = true;
+ }
+ }
+ };
+
+ Thread interruptThread = new Thread() {
+ public void run() {
+ try {
+ sleep(10);
+ } catch(InterruptedException ie) {
+ fail("InterruptedException was thrown in " +
+ "the interruptThread.");
+ }
+ thread.interrupt();
+ }
+ };
+ thread.start();
+ interruptThread.start();
+ try {
+ interruptThread.join();
+ } catch (InterruptedException e) {
+ fail("InterruptedException was thrown.");
+ }
+ try {
+ Thread.sleep(100);
+ } catch(InterruptedException ie) {
+
+ }
+
+ thread.interrupt();
+ //process.destroy();
+ try {
+ Thread.sleep(100);
+ } catch(InterruptedException ie) {
+
+ }
+
+ assertTrue(isThrown);
+ }
+
+ public void testPwd() throws IOException, InterruptedException {
+ String[] commands = { "sh", "-c", "pwd" };
+ Process process = Runtime.getRuntime().exec(
+ commands, null, new File("/"));
+ logErrors(process);
+ assertEquals("/", readLine(process));
+ }
+
+ public void testEnvironment() throws IOException, InterruptedException {
+ String[] commands = { "sh", "-c", "echo $FOO" };
+
+ // Remember to set the path so we can find sh.
+ String[] environment = { "FOO=foo", "PATH=" + System.getenv("PATH") };
+ Process process = Runtime.getRuntime().exec(
+ commands, environment, null);
+ logErrors(process);
+ assertEquals("foo", readLine(process));
+ }
+
+ String readLine(Process process) throws IOException {
+ InputStream in = process.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ return reader.readLine();
+ }
+
+ void logErrors(final Process process) throws IOException {
+ Thread thread = new Thread() {
+ public void run() {
+ InputStream in = process.getErrorStream();
+ BufferedReader reader
+ = new BufferedReader(new InputStreamReader(in));
+ String line;
+ try {
+ while ((line = reader.readLine()) != null) {
+ System.err.println(line);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ public void testHeavyLoad() {
+ int i;
+ for (i = 0; i < 100; i++)
+ stuff();
+ }
+
+ private static void stuff() {
+ Runtime rt = Runtime.getRuntime();
+ try {
+ Process proc = rt.exec("ls");
+ proc.waitFor();
+ proc = null;
+ } catch (Exception ex) {
+ System.err.println("Failure: " + ex);
+ throw new RuntimeException(ex);
+ }
+ rt.gc();
+ rt = null;
+ }
+
+ InputStream in;
+
+ public void testCloseNonStandardFds()
+ throws IOException, InterruptedException {
+ String[] commands = { "ls", "/proc/self/fd" };
+
+ Process process = Runtime.getRuntime().exec(commands, null, null);
+ int before = countLines(process);
+
+ // Open a new fd.
+ this.in = new FileInputStream("/proc/version");
+
+ try {
+ process = Runtime.getRuntime().exec(commands, null, null);
+ int after = countLines(process);
+
+ // Assert that the new fd wasn't open in the second run.
+ assertEquals(before, after);
+ } finally {
+ this.in = null;
+ }
+ }
+
+ /**
+ * Counts lines of input from the given process. Equivalent to "wc -l".
+ */
+ private int countLines(Process process) throws IOException {
+ logErrors(process);
+ InputStream in = process.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ int count = 0;
+ while (reader.readLine() != null) {
+ count++;
+ }
+ return count;
+ }
+
+ public void testInvalidCommand()
+ throws IOException, InterruptedException {
+ try {
+ String[] commands = { "doesnotexist" };
+ Runtime.getRuntime().exec(commands, null, null);
+ } catch (IOException e) { /* expected */ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java
new file mode 100644
index 0000000..b87105b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+public class ProcessTest extends junit.framework.TestCase {
+
+ public void test_55017() throws Exception {
+ ArrayList<Process> children = new ArrayList<Process>();
+ for (int i = 0; i < 256; ++i) {
+ try {
+ children.add(Runtime.getRuntime().exec(new String[] { "/system/bin/does-not-exist" }, null, null));
+ System.gc();
+ } catch (IOException expected) {
+ }
+ }
+ assertEquals(0, children.size());
+
+ boolean onDevice = new File("/system/bin").exists();
+ String[] psCommand = onDevice ? new String[] { "ps" } : new String[] { "ps", "s" };
+ Process ps = Runtime.getRuntime().exec(psCommand, null, null);
+ int zombieCount = 0;
+ for (String line : readAndCloseStream(ps.getInputStream()).split("\n")) {
+ if (line.contains(" Z ") || line.contains(" Z+ ")) {
+ ++zombieCount;
+ }
+ }
+ assertEquals(0, zombieCount);
+ }
+
+ public void test_getOutputStream() throws Exception {
+ String[] commands = { "cat", "-"};
+ Process p = Runtime.getRuntime().exec(commands, null, null);
+ OutputStream os = p.getOutputStream();
+ // send data, and check if it is echoed back correctly
+ String str1 = "Some data for testing communication between processes\n";
+ String str2 = "More data that serves the same purpose.\n";
+ String str3 = "Here is some more data.\n";
+ os.write(str1.getBytes());
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ os.write(str2.getBytes());
+ os.write(str3.getBytes());
+ os.close();
+
+ String received = readAndCloseStream(p.getInputStream());
+ assertEquals(str1 + str2 + str3, received);
+
+ String stderr = readAndCloseStream(p.getErrorStream());
+ assertEquals("", stderr);
+
+ p.waitFor();
+ p.destroy();
+ }
+
+ public void test_getErrorStream() throws Exception {
+ String[] commands = { "cat", "--no-such-option"};
+ Process p = Runtime.getRuntime().exec(commands, null, null);
+
+ p.getOutputStream().close();
+
+ String received = readAndCloseStream(p.getInputStream());
+ assertEquals("", received);
+
+ String stderr = readAndCloseStream(p.getErrorStream());
+ assertTrue(stderr, stderr.contains("unrecognized option") || stderr.contains("invalid option"));
+
+ p.waitFor();
+ p.destroy();
+ }
+
+ private String readAndCloseStream(InputStream is) throws IOException {
+ StringBuffer result = new StringBuffer();
+ while (true) {
+ int c = is.read();
+ if (c == -1) {
+ break;
+ }
+ result.append((char) c);
+ }
+ is.close();
+ return result.toString();
+ }
+
+ public void test_exitValue() throws Exception {
+ String[] commands = { "ls" };
+ Process process = Runtime.getRuntime().exec(commands, null, null);
+ process.waitFor();
+ assertEquals(0, process.exitValue());
+
+ String[] commandsSleep = { "sleep", "3000" };
+ process = Runtime.getRuntime().exec(commandsSleep, null, null);
+ process.destroy();
+ process.waitFor(); // destroy is asynchronous.
+ assertTrue(process.exitValue() != 0);
+
+ process = Runtime.getRuntime().exec(new String[] { "sleep", "3000" }, null, null);
+ try {
+ process.exitValue();
+ fail();
+ } catch(IllegalThreadStateException expected) {
+ }
+ }
+
+ public void test_destroy() throws Exception {
+ String[] commands = { "ls"};
+ Process process = Runtime.getRuntime().exec(commands, null, null);
+ process.destroy();
+ process.destroy();
+ process.destroy();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeExceptionTest.java
new file mode 100644
index 0000000..748118a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeExceptionTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class RuntimeExceptionTest extends TestCase {
+
+ /**
+ * java.lang.RuntimeException#RuntimeException()
+ */
+ public void test_Constructor() {
+ RuntimeException e = new RuntimeException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.RuntimeException#RuntimeException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ RuntimeException e = new RuntimeException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * {@link java.lang.RuntimeException#RuntimeException(Throwable)}
+ */
+ public void test_ConstructorLjava_lang_Throwable() {
+ Throwable emptyThrowable = new Exception();
+ RuntimeException emptyException = new RuntimeException(emptyThrowable);
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getLocalizedMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+ Throwable throwable = new Exception("msg");
+ RuntimeException exception = new RuntimeException(throwable);
+ assertEquals(throwable.getClass().getName() + ": " + "msg", exception.getMessage());
+ assertEquals(throwable.getClass().getName(), emptyException.getLocalizedMessage());
+ assertEquals(throwable.getClass().getName(), emptyException.getCause().toString());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeTest.java
new file mode 100644
index 0000000..03a4aa0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeTest.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+public class RuntimeTest extends junit.framework.TestCase {
+
+ Runtime r = Runtime.getRuntime();
+
+ InputStream is;
+
+ String s;
+
+ static boolean flag = false;
+
+ static boolean ranFinalize = false;
+
+ class HasFinalizer {
+ String internalString;
+
+ HasFinalizer(String s) {
+ internalString = s;
+ }
+
+ @Override
+ protected void finalize() {
+ internalString = "hit";
+ }
+ }
+
+ @Override
+ protected void finalize() {
+ if (flag)
+ ranFinalize = true;
+ }
+
+ protected RuntimeTest createInstance() {
+ return new RuntimeTest("FT");
+ }
+
+ /**
+ * java.lang.Runtime#exit(int)
+ */
+ public void test_exitI() {
+ // Test for method void java.lang.Runtime.exit(int)
+ assertTrue("Can't really test this", true);
+ }
+
+ /**
+ * java.lang.Runtime#exec(java.lang.String)
+ */
+ public void test_exec() {
+ boolean success = false;
+
+ /* successful exec's are tested by java.lang.Process */
+ try {
+ Runtime.getRuntime().exec("AnInexistentProgram");
+ } catch (IOException e) {
+ success = true;
+ }
+ assertTrue(
+ "failed to throw IOException when exec'ed inexistent program",
+ success);
+ }
+
+ /**
+ * java.lang.Runtime#getRuntime()
+ */
+ public void test_getRuntime() {
+ // Test for method java.lang.Runtime java.lang.Runtime.getRuntime()
+ assertTrue("Used to test", true);
+ }
+
+ /**
+ * java.lang.Runtime#runFinalization()
+ */
+ public void test_runFinalization() {
+ // Test for method void java.lang.Runtime.runFinalization()
+
+ flag = true;
+ createInstance();
+ int count = 10;
+ // the gc below likely bogosifies the test, but will have to do for
+ // the moment
+ while (!ranFinalize && count-- > 0) {
+ r.gc();
+ r.runFinalization();
+ }
+ assertTrue("Failed to run finalization", ranFinalize);
+ }
+
+ /**
+ * java.lang.Runtime#freeMemory() / java.lang.Runtime#totalMemory() /
+ * java.lang.Runtime#maxMemory()
+ */
+ public void test_memory() {
+ assertTrue("freeMemory < 0", r.freeMemory() >= 0);
+ assertTrue("totalMemory() < freeMemory()", r.totalMemory() >= r.freeMemory());
+ assertTrue("maxMemory() < totalMemory()", r.maxMemory() >= r.totalMemory());
+ }
+
+ public RuntimeTest() {
+ }
+
+ public RuntimeTest(String name) {
+ super(name);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/SecurityExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/SecurityExceptionTest.java
new file mode 100644
index 0000000..a0d1cee
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/SecurityExceptionTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class SecurityExceptionTest extends TestCase {
+
+ /**
+ * java.lang.SecurityException#SecurityException()
+ */
+ public void test_Constructor() {
+ SecurityException e = new SecurityException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.SecurityException#SecurityException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ SecurityException e = new SecurityException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.SecurityException#SecurityException(String, Throwable)
+ */
+ @SuppressWarnings("nls")
+ public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+ NullPointerException npe = new NullPointerException();
+ SecurityException e = new SecurityException("fixture", npe);
+ assertSame("fixture", e.getMessage());
+ assertSame(npe, e.getCause());
+ }
+
+ /**
+ * java.lang.SecurityException#SecurityException(Throwable)
+ */
+ @SuppressWarnings("nls")
+ public void test_ConstructorLjava_lang_Throwable() {
+ NullPointerException npe = new NullPointerException();
+ SecurityException e = new SecurityException(npe);
+ assertSame(npe, e.getCause());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new SecurityException());
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new SecurityException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ShortTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ShortTest.java
new file mode 100644
index 0000000..bf747e7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ShortTest.java
@@ -0,0 +1,684 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ShortTest extends TestCase {
+ private Short sp = new Short((short) 18000);
+ private Short sn = new Short((short) -19000);
+
+ /**
+ * java.lang.Short#byteValue()
+ */
+ public void test_byteValue() {
+ // Test for method byte java.lang.Short.byteValue()
+ assertEquals("Returned incorrect byte value", 0, new Short(Short.MIN_VALUE)
+ .byteValue());
+ assertEquals("Returned incorrect byte value", -1, new Short(Short.MAX_VALUE)
+ .byteValue());
+ }
+
+ /**
+ * java.lang.Short#compareTo(java.lang.Short)
+ */
+ public void test_compareToLjava_lang_Short() {
+ // Test for method int java.lang.Short.compareTo(java.lang.Short)
+ Short s = new Short((short) 1);
+ Short x = new Short((short) 3);
+ assertTrue(
+ "Should have returned negative value when compared to greater short",
+ s.compareTo(x) < 0);
+ x = new Short((short) -1);
+ assertTrue(
+ "Should have returned positive value when compared to lesser short",
+ s.compareTo(x) > 0);
+ x = new Short((short) 1);
+ assertEquals("Should have returned zero when compared to equal short",
+ 0, s.compareTo(x));
+
+ try {
+ new Short((short) 0).compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Short#decode(java.lang.String)
+ */
+ public void test_decodeLjava_lang_String2() {
+ // Test for method java.lang.Short
+ // java.lang.Short.decode(java.lang.String)
+ assertTrue("Did not decode -1 correctly", Short.decode("-1")
+ .shortValue() == (short) -1);
+ assertTrue("Did not decode -100 correctly", Short.decode("-100")
+ .shortValue() == (short) -100);
+ assertTrue("Did not decode 23 correctly", Short.decode("23")
+ .shortValue() == (short) 23);
+ assertTrue("Did not decode 0x10 correctly", Short.decode("0x10")
+ .shortValue() == (short) 16);
+ assertTrue("Did not decode 32767 correctly", Short.decode("32767")
+ .shortValue() == (short) 32767);
+ assertTrue("Did not decode -32767 correctly", Short.decode("-32767")
+ .shortValue() == (short) -32767);
+ assertTrue("Did not decode -32768 correctly", Short.decode("-32768")
+ .shortValue() == (short) -32768);
+
+ boolean exception = false;
+ try {
+ Short.decode("123s");
+ } catch (NumberFormatException e) {
+ // correct
+ exception = true;
+ }
+ assertTrue("Did not throw NumberFormatException decoding 123s",
+ exception);
+
+ exception = false;
+ try {
+ Short.decode("32768");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Short.decode("-32769");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Short.decode("0x8000");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Short.decode("-0x8001");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MIN_VALUE - 1", exception);
+ }
+
+ /**
+ * java.lang.Short#parseShort(java.lang.String)
+ */
+ public void test_parseShortLjava_lang_String2() {
+ // Test for method short java.lang.Short.parseShort(java.lang.String)
+ short sp = Short.parseShort("32746");
+ short sn = Short.parseShort("-32746");
+
+ assertTrue("Incorrect parse of short", sp == (short) 32746
+ && (sn == (short) -32746));
+ assertEquals("Returned incorrect value for 0", 0, Short.parseShort("0"));
+ assertTrue("Returned incorrect value for most negative value", Short
+ .parseShort("-32768") == (short) 0x8000);
+ assertTrue("Returned incorrect value for most positive value", Short
+ .parseShort("32767") == 0x7fff);
+
+ boolean exception = false;
+ try {
+ Short.parseShort("32768");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Short.parseShort("-32769");
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+ }
+
+ /**
+ * java.lang.Short#parseShort(java.lang.String, int)
+ */
+ public void test_parseShortLjava_lang_StringI2() {
+ // Test for method short java.lang.Short.parseShort(java.lang.String,
+ // int)
+ boolean aThrow = true;
+ assertEquals("Incorrectly parsed hex string",
+ 255, Short.parseShort("FF", 16));
+ assertEquals("Incorrectly parsed oct string",
+ 16, Short.parseShort("20", 8));
+ assertEquals("Incorrectly parsed dec string",
+ 20, Short.parseShort("20", 10));
+ assertEquals("Incorrectly parsed bin string",
+ 4, Short.parseShort("100", 2));
+ assertEquals("Incorrectly parsed -hex string", -255, Short
+ .parseShort("-FF", 16));
+ assertEquals("Incorrectly parsed -oct string",
+ -16, Short.parseShort("-20", 8));
+ assertEquals("Incorrectly parsed -bin string", -4, Short
+ .parseShort("-100", 2));
+ assertEquals("Returned incorrect value for 0 hex", 0, Short.parseShort("0",
+ 16));
+ assertTrue("Returned incorrect value for most negative value hex",
+ Short.parseShort("-8000", 16) == (short) 0x8000);
+ assertTrue("Returned incorrect value for most positive value hex",
+ Short.parseShort("7fff", 16) == 0x7fff);
+ assertEquals("Returned incorrect value for 0 decimal", 0, Short.parseShort(
+ "0", 10));
+ assertTrue("Returned incorrect value for most negative value decimal",
+ Short.parseShort("-32768", 10) == (short) 0x8000);
+ assertTrue("Returned incorrect value for most positive value decimal",
+ Short.parseShort("32767", 10) == 0x7fff);
+
+ try {
+ Short.parseShort("FF", 2);
+ } catch (NumberFormatException e) {
+ // Correct
+ aThrow = false;
+ }
+ if (aThrow) {
+ fail(
+ "Failed to throw exception when passed hex string and base 2 radix");
+ }
+
+ boolean exception = false;
+ try {
+ Short.parseShort("10000000000", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue(
+ "Failed to throw exception when passed string larger than 16 bits",
+ exception);
+
+ exception = false;
+ try {
+ Short.parseShort("32768", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Short.parseShort("-32769", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+ exception = false;
+ try {
+ Short.parseShort("8000", 16);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+ exception = false;
+ try {
+ Short.parseShort("-8001", 16);
+ } catch (NumberFormatException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Failed to throw exception for hex MIN_VALUE + 1", exception);
+ }
+
+ /**
+ * java.lang.Short#toString()
+ */
+ public void test_toString2() {
+ // Test for method java.lang.String java.lang.Short.toString()
+ assertTrue("Invalid string returned", sp.toString().equals("18000")
+ && (sn.toString().equals("-19000")));
+ assertEquals("Returned incorrect string", "32767", new Short((short) 32767)
+ .toString());
+ assertEquals("Returned incorrect string", "-32767", new Short((short) -32767)
+ .toString());
+ assertEquals("Returned incorrect string", "-32768", new Short((short) -32768)
+ .toString());
+ }
+
+ /**
+ * java.lang.Short#toString(short)
+ */
+ public void test_toStringS2() {
+ // Test for method java.lang.String java.lang.Short.toString(short)
+ assertEquals("Returned incorrect string", "32767", Short.toString((short) 32767)
+ );
+ assertEquals("Returned incorrect string", "-32767", Short.toString((short) -32767)
+ );
+ assertEquals("Returned incorrect string", "-32768", Short.toString((short) -32768)
+ );
+ }
+
+ /**
+ * java.lang.Short#valueOf(java.lang.String)
+ */
+ public void test_valueOfLjava_lang_String2() {
+ // Test for method java.lang.Short
+ // java.lang.Short.valueOf(java.lang.String)
+ assertEquals("Returned incorrect short", -32768, Short.valueOf("-32768")
+ .shortValue());
+ assertEquals("Returned incorrect short", 32767, Short.valueOf("32767")
+ .shortValue());
+ }
+
+ /**
+ * java.lang.Short#valueOf(java.lang.String, int)
+ */
+ public void test_valueOfLjava_lang_StringI2() {
+ // Test for method java.lang.Short
+ // java.lang.Short.valueOf(java.lang.String, int)
+ boolean aThrow = true;
+ assertEquals("Incorrectly parsed hex string", 255, Short.valueOf("FF", 16)
+ .shortValue());
+ assertEquals("Incorrectly parsed oct string", 16, Short.valueOf("20", 8)
+ .shortValue());
+ assertEquals("Incorrectly parsed dec string", 20, Short.valueOf("20", 10)
+ .shortValue());
+ assertEquals("Incorrectly parsed bin string", 4, Short.valueOf("100", 2)
+ .shortValue());
+ assertEquals("Incorrectly parsed -hex string", -255, Short.valueOf("-FF", 16)
+ .shortValue());
+ assertEquals("Incorrectly parsed -oct string", -16, Short.valueOf("-20", 8)
+ .shortValue());
+ assertEquals("Incorrectly parsed -bin string", -4, Short.valueOf("-100", 2)
+ .shortValue());
+ assertTrue("Did not decode 32767 correctly", Short.valueOf("32767", 10)
+ .shortValue() == (short) 32767);
+ assertTrue("Did not decode -32767 correctly", Short.valueOf("-32767",
+ 10).shortValue() == (short) -32767);
+ assertTrue("Did not decode -32768 correctly", Short.valueOf("-32768",
+ 10).shortValue() == (short) -32768);
+ try {
+ Short.valueOf("FF", 2);
+ } catch (NumberFormatException e) {
+ // Correct
+ aThrow = false;
+ }
+ if (aThrow) {
+ fail(
+ "Failed to throw exception when passed hex string and base 2 radix");
+ }
+ try {
+ Short.valueOf("10000000000", 10);
+ } catch (NumberFormatException e) {
+ // Correct
+ return;
+ }
+ fail(
+ "Failed to throw exception when passed string larger than 16 bits");
+ }
+
+ /**
+ * java.lang.Short#valueOf(byte)
+ */
+ public void test_valueOfS() {
+ assertEquals(new Short(Short.MIN_VALUE), Short.valueOf(Short.MIN_VALUE));
+ assertEquals(new Short(Short.MAX_VALUE), Short.valueOf(Short.MAX_VALUE));
+ assertEquals(new Short((short) 0), Short.valueOf((short) 0));
+
+ short s = -128;
+ while (s < 128) {
+ assertEquals(new Short(s), Short.valueOf(s));
+ assertSame(Short.valueOf(s), Short.valueOf(s));
+ s++;
+ }
+ }
+
+ /**
+ * java.lang.Short#hashCode()
+ */
+ public void test_hashCode() {
+ assertEquals(1, new Short((short) 1).hashCode());
+ assertEquals(2, new Short((short) 2).hashCode());
+ assertEquals(0, new Short((short) 0).hashCode());
+ assertEquals(-1, new Short((short) -1).hashCode());
+ }
+
+ /**
+ * java.lang.Short#Short(String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ assertEquals(new Short((short) 0), new Short("0"));
+ assertEquals(new Short((short) 1), new Short("1"));
+ assertEquals(new Short((short) -1), new Short("-1"));
+
+ try {
+ new Short("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Short("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Short("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new Short(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Short#Short(short)
+ */
+ public void test_ConstructorS() {
+ assertEquals(1, new Short((short) 1).shortValue());
+ assertEquals(2, new Short((short) 2).shortValue());
+ assertEquals(0, new Short((short) 0).shortValue());
+ assertEquals(-1, new Short((short) -1).shortValue());
+ }
+
+ /**
+ * java.lang.Short#byteValue()
+ */
+ public void test_booleanValue() {
+ assertEquals(1, new Short((short) 1).byteValue());
+ assertEquals(2, new Short((short) 2).byteValue());
+ assertEquals(0, new Short((short) 0).byteValue());
+ assertEquals(-1, new Short((short) -1).byteValue());
+ }
+
+ /**
+ * java.lang.Short#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertEquals(new Short((short) 0), Short.valueOf((short) 0));
+ assertEquals(new Short((short) 1), Short.valueOf((short) 1));
+ assertEquals(new Short((short) -1), Short.valueOf((short) -1));
+
+ Short fixture = new Short((short) 25);
+ assertEquals(fixture, fixture);
+ assertFalse(fixture.equals(null));
+ assertFalse(fixture.equals("Not a Short"));
+ }
+
+ /**
+ * java.lang.Short#toString()
+ */
+ public void test_toString() {
+ assertEquals("-1", new Short((short) -1).toString());
+ assertEquals("0", new Short((short) 0).toString());
+ assertEquals("1", new Short((short) 1).toString());
+ assertEquals("-1", new Short((short) 0xFFFF).toString());
+ }
+
+ /**
+ * java.lang.Short#toString(short)
+ */
+ public void test_toStringS() {
+ assertEquals("-1", Short.toString((short) -1));
+ assertEquals("0", Short.toString((short) 0));
+ assertEquals("1", Short.toString((short) 1));
+ assertEquals("-1", Short.toString((short) 0xFFFF));
+ }
+
+ /**
+ * java.lang.Short#valueOf(String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ assertEquals(new Short((short) 0), Short.valueOf("0"));
+ assertEquals(new Short((short) 1), Short.valueOf("1"));
+ assertEquals(new Short((short) -1), Short.valueOf("-1"));
+
+ try {
+ Short.valueOf("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.valueOf("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.valueOf("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.valueOf(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Short#valueOf(String, int)
+ */
+ public void test_valueOfLjava_lang_StringI() {
+ assertEquals(new Short((short) 0), Short.valueOf("0", 10));
+ assertEquals(new Short((short) 1), Short.valueOf("1", 10));
+ assertEquals(new Short((short) -1), Short.valueOf("-1", 10));
+
+ //must be consistent with Character.digit()
+ assertEquals(Character.digit('1', 2), Short.valueOf("1", 2).byteValue());
+ assertEquals(Character.digit('F', 16), Short.valueOf("F", 16).byteValue());
+
+ try {
+ Short.valueOf("0x1", 10);
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.valueOf("9.2", 10);
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.valueOf("", 10);
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.valueOf(null, 10);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Short#parseShort(String)
+ */
+ public void test_parseShortLjava_lang_String() {
+ assertEquals(0, Short.parseShort("0"));
+ assertEquals(1, Short.parseShort("1"));
+ assertEquals(-1, Short.parseShort("-1"));
+
+ try {
+ Short.parseShort("0x1");
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.parseShort("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.parseShort("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.parseShort(null);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Short#parseShort(String, int)
+ */
+ public void test_parseShortLjava_lang_StringI() {
+ assertEquals(0, Short.parseShort("0", 10));
+ assertEquals(1, Short.parseShort("1", 10));
+ assertEquals(-1, Short.parseShort("-1", 10));
+
+ //must be consistent with Character.digit()
+ assertEquals(Character.digit('1', 2), Short.parseShort("1", 2));
+ assertEquals(Character.digit('F', 16), Short.parseShort("F", 16));
+
+ try {
+ Short.parseShort("0x1", 10);
+ fail("Expected NumberFormatException with hex string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.parseShort("9.2", 10);
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.parseShort("", 10);
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.parseShort(null, 10);
+ fail("Expected NumberFormatException with null string.");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * java.lang.Short#decode(String)
+ */
+ public void test_decodeLjava_lang_String() {
+ assertEquals(new Short((short) 0), Short.decode("0"));
+ assertEquals(new Short((short) 1), Short.decode("1"));
+ assertEquals(new Short((short) -1), Short.decode("-1"));
+ assertEquals(new Short((short) 0xF), Short.decode("0xF"));
+ assertEquals(new Short((short) 0xF), Short.decode("#F"));
+ assertEquals(new Short((short) 0xF), Short.decode("0XF"));
+ assertEquals(new Short((short) 07), Short.decode("07"));
+
+ try {
+ Short.decode("9.2");
+ fail("Expected NumberFormatException with floating point string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.decode("");
+ fail("Expected NumberFormatException with empty string.");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ Short.decode(null);
+ //undocumented NPE, but seems consistent across JREs
+ fail("Expected NullPointerException with null string.");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.Short#doubleValue()
+ */
+ public void test_doubleValue() {
+ assertEquals(-1D, new Short((short) -1).doubleValue(), 0D);
+ assertEquals(0D, new Short((short) 0).doubleValue(), 0D);
+ assertEquals(1D, new Short((short) 1).doubleValue(), 0D);
+ }
+
+ /**
+ * java.lang.Short#floatValue()
+ */
+ public void test_floatValue() {
+ assertEquals(-1F, new Short((short) -1).floatValue(), 0F);
+ assertEquals(0F, new Short((short) 0).floatValue(), 0F);
+ assertEquals(1F, new Short((short) 1).floatValue(), 0F);
+ }
+
+ /**
+ * java.lang.Short#intValue()
+ */
+ public void test_intValue() {
+ assertEquals(-1, new Short((short) -1).intValue());
+ assertEquals(0, new Short((short) 0).intValue());
+ assertEquals(1, new Short((short) 1).intValue());
+ }
+
+ /**
+ * java.lang.Short#longValue()
+ */
+ public void test_longValue() {
+ assertEquals(-1L, new Short((short) -1).longValue());
+ assertEquals(0L, new Short((short) 0).longValue());
+ assertEquals(1L, new Short((short) 1).longValue());
+ }
+
+ /**
+ * java.lang.Short#shortValue()
+ */
+ public void test_shortValue() {
+ assertEquals(-1, new Short((short) -1).shortValue());
+ assertEquals(0, new Short((short) 0).shortValue());
+ assertEquals(1, new Short((short) 1).shortValue());
+ }
+
+ /**
+ * java.lang.Short#reverseBytes(short)
+ */
+ public void test_reverseBytesS() {
+ assertEquals((short) 0xABCD, Short.reverseBytes((short) 0xCDAB));
+ assertEquals((short) 0x1234, Short.reverseBytes((short) 0x3412));
+ assertEquals((short) 0x0011, Short.reverseBytes((short) 0x1100));
+ assertEquals((short) 0x2002, Short.reverseBytes((short) 0x0220));
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StackOverflowErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StackOverflowErrorTest.java
new file mode 100644
index 0000000..b3f6f82
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StackOverflowErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class StackOverflowErrorTest extends TestCase {
+
+ /**
+ * java.lang.StackOverflowError#StackOverflowError()
+ */
+ public void test_Constructor() {
+ StackOverflowError e = new StackOverflowError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.StackOverflowError#StackOverflowError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ StackOverflowError e = new StackOverflowError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StrictMathTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StrictMathTest.java
new file mode 100644
index 0000000..cce8935
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StrictMathTest.java
@@ -0,0 +1,1490 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import static org.apache.harmony.tests.java.lang.MathTest.COPYSIGN_DD_CASES;
+import static org.apache.harmony.tests.java.lang.MathTest.COPYSIGN_FF_CASES;
+import static org.apache.harmony.tests.java.lang.MathTest.GETEXPONENT_D_CASES;
+import static org.apache.harmony.tests.java.lang.MathTest.GETEXPONENT_D_RESULTS;
+import static org.apache.harmony.tests.java.lang.MathTest.GETEXPONENT_F_CASES;
+import static org.apache.harmony.tests.java.lang.MathTest.GETEXPONENT_F_RESULTS;
+import static org.apache.harmony.tests.java.lang.MathTest.NEXTAFTER_DD_START_CASES;
+import static org.apache.harmony.tests.java.lang.MathTest.NEXTAFTER_DD_FD_DIRECTION_CASES;
+import static org.apache.harmony.tests.java.lang.MathTest.NEXTAFTER_FD_START_CASES;
+
+public class StrictMathTest extends junit.framework.TestCase {
+
+ private static final double HYP = StrictMath.sqrt(2.0);
+
+ private static final double OPP = 1.0;
+
+ private static final double ADJ = 1.0;
+
+ /* Required to make previous preprocessor flags work - do not remove */
+ int unused = 0;
+
+ /**
+ * java.lang.StrictMath#abs(double)
+ */
+ public void test_absD() {
+ // Test for method double java.lang.StrictMath.abs(double)
+
+ assertTrue("Incorrect double abs value",
+ (StrictMath.abs(-1908.8976) == 1908.8976));
+ assertTrue("Incorrect double abs value",
+ (StrictMath.abs(1908.8976) == 1908.8976));
+ }
+
+ /**
+ * java.lang.StrictMath#abs(float)
+ */
+ public void test_absF() {
+ // Test for method float java.lang.StrictMath.abs(float)
+ assertTrue("Incorrect float abs value",
+ (StrictMath.abs(-1908.8976f) == 1908.8976f));
+ assertTrue("Incorrect float abs value",
+ (StrictMath.abs(1908.8976f) == 1908.8976f));
+ }
+
+ /**
+ * java.lang.StrictMath#abs(int)
+ */
+ public void test_absI() {
+ // Test for method int java.lang.StrictMath.abs(int)
+ assertTrue("Incorrect int abs value",
+ (StrictMath.abs(-1908897) == 1908897));
+ assertTrue("Incorrect int abs value",
+ (StrictMath.abs(1908897) == 1908897));
+ }
+
+ /**
+ * java.lang.StrictMath#abs(long)
+ */
+ public void test_absJ() {
+ // Test for method long java.lang.StrictMath.abs(long)
+ assertTrue("Incorrect long abs value", (StrictMath
+ .abs(-19088976000089L) == 19088976000089L));
+ assertTrue("Incorrect long abs value",
+ (StrictMath.abs(19088976000089L) == 19088976000089L));
+ }
+
+ /**
+ * java.lang.StrictMath#acos(double)
+ */
+ public void test_acosD() {
+ // Test for method double java.lang.StrictMath.acos(double)
+ assertTrue("Returned incorrect arc cosine", StrictMath.cos(StrictMath
+ .acos(ADJ / HYP)) == ADJ / HYP);
+ }
+
+ /**
+ * java.lang.StrictMath#asin(double)
+ */
+ public void test_asinD() {
+ // Test for method double java.lang.StrictMath.asin(double)
+ assertTrue("Returned incorrect arc sine", StrictMath.sin(StrictMath
+ .asin(OPP / HYP)) == OPP / HYP);
+ }
+
+ /**
+ * java.lang.StrictMath#atan(double)
+ */
+ public void test_atanD() {
+ // Test for method double java.lang.StrictMath.atan(double)
+ double answer = StrictMath.tan(StrictMath.atan(1.0));
+ assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
+ && answer >= 9.9999999999999983E-1);
+ }
+
+ /**
+ * java.lang.StrictMath#atan2(double, double)
+ */
+ public void test_atan2DD() {
+ // Test for method double java.lang.StrictMath.atan2(double, double)
+ double answer = StrictMath.atan(StrictMath.tan(1.0));
+ assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
+ && answer >= 9.9999999999999983E-1);
+ }
+
+ /**
+ * java.lang.StrictMath#cbrt(double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_cbrt_D() {
+ // Test for special situations
+ assertTrue("Should return Double.NaN", Double.isNaN(StrictMath
+ .cbrt(Double.NaN)));
+ assertEquals("Should return Double.POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath
+ .cbrt(Double.POSITIVE_INFINITY));
+ assertEquals("Should return Double.NEGATIVE_INFINITY",
+ Double.NEGATIVE_INFINITY, StrictMath
+ .cbrt(Double.NEGATIVE_INFINITY));
+ assertEquals(Double.doubleToLongBits(0.0), Double
+ .doubleToLongBits(StrictMath.cbrt(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(StrictMath.cbrt(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(StrictMath.cbrt(-0.0)));
+
+ assertEquals("Should return 3.0", 3.0, StrictMath.cbrt(27.0));
+ assertEquals("Should return 23.111993172558684", 23.111993172558684,
+ StrictMath.cbrt(12345.6));
+ assertEquals("Should return 5.643803094122362E102",
+ 5.643803094122362E102, StrictMath.cbrt(Double.MAX_VALUE));
+ assertEquals("Should return 0.01", 0.01, StrictMath.cbrt(0.000001));
+
+ assertEquals("Should return -3.0", -3.0, StrictMath.cbrt(-27.0));
+ assertEquals("Should return -23.111993172558684", -23.111993172558684,
+ StrictMath.cbrt(-12345.6));
+ assertEquals("Should return 1.7031839360032603E-108",
+ 1.7031839360032603E-108, StrictMath.cbrt(Double.MIN_VALUE));
+ assertEquals("Should return -0.01", -0.01, StrictMath.cbrt(-0.000001));
+
+ try {
+ StrictMath.cbrt((Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.lang.StrictMath#ceil(double)
+ */
+ public void test_ceilD() {
+ // Test for method double java.lang.StrictMath.ceil(double)
+ assertEquals("Incorrect ceiling for double",
+ 79, StrictMath.ceil(78.89), 0.0);
+ assertEquals("Incorrect ceiling for double",
+ -78, StrictMath.ceil(-78.89), 0.0);
+ }
+
+ /**
+ * {@link java.lang.StrictMath#copySign(double, double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_copySign_DD() {
+ for (int i = 0; i < COPYSIGN_DD_CASES.length; i++) {
+ final double magnitude = COPYSIGN_DD_CASES[i];
+ final long absMagnitudeBits = Double.doubleToLongBits(StrictMath
+ .abs(magnitude));
+ final long negMagnitudeBits = Double.doubleToLongBits(-StrictMath
+ .abs(magnitude));
+
+ // cases for NaN
+ assertEquals("If the sign is NaN, the result should be positive.",
+ absMagnitudeBits, Double.doubleToLongBits(StrictMath
+ .copySign(magnitude, Double.NaN)));
+ assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+ .copySign(Double.NaN, magnitude)));
+
+ for (int j = 0; j < COPYSIGN_DD_CASES.length; j++) {
+ final double sign = COPYSIGN_DD_CASES[j];
+ final long resultBits = Double.doubleToLongBits(StrictMath
+ .copySign(magnitude, sign));
+
+ if (sign > 0 || Double.valueOf(+0.0).equals(sign)
+ || Double.valueOf(0.0).equals(sign)) {
+ assertEquals(
+ "If the sign is positive, the result should be positive.",
+ absMagnitudeBits, resultBits);
+ }
+ if (sign < 0 || Double.valueOf(-0.0).equals(sign)) {
+ assertEquals(
+ "If the sign is negative, the result should be negative.",
+ negMagnitudeBits, resultBits);
+ }
+ }
+ }
+
+ assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+ .copySign(Double.NaN, Double.NaN)));
+
+ try {
+ StrictMath.copySign((Double) null, 2.3);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.copySign(2.3, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.copySign((Double) null, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ double d = Double.longBitsToDouble(0xfff8000000000000L);
+ assertEquals(1.0, StrictMath.copySign(1.0, d), 0d);
+ }
+
+ /**
+ * {@link java.lang.StrictMath#copySign(float, float)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_copySign_FF() {
+ for (int i = 0; i < COPYSIGN_FF_CASES.length; i++) {
+ final float magnitude = COPYSIGN_FF_CASES[i];
+ final int absMagnitudeBits = Float.floatToIntBits(StrictMath
+ .abs(magnitude));
+ final int negMagnitudeBits = Float.floatToIntBits(-StrictMath
+ .abs(magnitude));
+
+ // cases for NaN
+ assertEquals("If the sign is NaN, the result should be positive.",
+ absMagnitudeBits, Float.floatToIntBits(StrictMath.copySign(
+ magnitude, Float.NaN)));
+ assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+ .copySign(Float.NaN, magnitude)));
+
+ for (int j = 0; j < COPYSIGN_FF_CASES.length; j++) {
+ final float sign = COPYSIGN_FF_CASES[j];
+ final int resultBits = Float.floatToIntBits(StrictMath
+ .copySign(magnitude, sign));
+ if (sign > 0 || Float.valueOf(+0.0f).equals(sign)
+ || Float.valueOf(0.0f).equals(sign)) {
+ assertEquals(
+ "If the sign is positive, the result should be positive.",
+ absMagnitudeBits, resultBits);
+ }
+ if (sign < 0 || Float.valueOf(-0.0f).equals(sign)) {
+ assertEquals(
+ "If the sign is negative, the result should be negative.",
+ negMagnitudeBits, resultBits);
+ }
+ }
+ }
+
+ assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+ .copySign(Float.NaN, Float.NaN)));
+
+ try {
+ StrictMath.copySign((Float) null, 2.3f);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.copySign(2.3f, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.copySign((Float) null, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ float f = Float.intBitsToFloat(0xffc00000);
+ assertEquals(1.0f, StrictMath.copySign(1.0f, f), 0f);
+ }
+
+ /**
+ * java.lang.StrictMath#cos(double)
+ */
+ public void test_cosD() {
+ // Test for method double java.lang.StrictMath.cos(double)
+
+ assertTrue("Returned incorrect cosine", StrictMath.cos(StrictMath
+ .acos(ADJ / HYP)) == ADJ / HYP);
+ }
+
+ /**
+ * java.lang.StrictMath#cosh(double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_cosh_D() {
+ // Test for special situations
+ assertTrue("Should return NaN", Double.isNaN(StrictMath
+ .cosh(Double.NaN)));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath
+ .cosh(Double.POSITIVE_INFINITY));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath
+ .cosh(Double.NEGATIVE_INFINITY));
+ assertEquals("Should return 1.0", 1.0, StrictMath.cosh(+0.0));
+ assertEquals("Should return 1.0", 1.0, StrictMath.cosh(-0.0));
+
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.cosh(1234.56));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.cosh(-1234.56));
+ assertEquals("Should return 1.0000000000005", 1.0000000000005,
+ StrictMath.cosh(0.000001));
+ assertEquals("Should return 1.0000000000005", 1.0000000000005,
+ StrictMath.cosh(-0.000001));
+ assertEquals("Should return 5.212214351945598", 5.212214351945598,
+ StrictMath.cosh(2.33482));
+
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.cosh(Double.MAX_VALUE));
+ assertEquals("Should return 1.0", 1.0, StrictMath
+ .cosh(Double.MIN_VALUE));
+ }
+
+ /**
+ * java.lang.StrictMath#exp(double)
+ */
+ public void test_expD() {
+ // Test for method double java.lang.StrictMath.exp(double)
+ assertTrue("Incorrect answer returned for simple power", StrictMath
+ .abs(StrictMath.exp(4D) - StrictMath.E * StrictMath.E
+ * StrictMath.E * StrictMath.E) < 0.1D);
+ assertTrue("Incorrect answer returned for larger power", StrictMath
+ .log(StrictMath.abs(StrictMath.exp(5.5D)) - 5.5D) < 10.0D);
+ }
+
+ /**
+ * java.lang.StrictMath#expm1(double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_expm1_D() {
+ //Test for special cases
+ assertTrue("Should return NaN", Double.isNaN(StrictMath.expm1(Double.NaN)));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.expm1(Double.POSITIVE_INFINITY));
+ assertEquals("Should return -1.0", -1.0, StrictMath
+ .expm1(Double.NEGATIVE_INFINITY));
+ assertEquals(Double.doubleToLongBits(0.0), Double
+ .doubleToLongBits(StrictMath.expm1(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(StrictMath.expm1(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(StrictMath.expm1(-0.0)));
+
+ assertEquals("Should return -9.999950000166666E-6",
+ -9.999950000166666E-6, StrictMath.expm1(-0.00001));
+ assertEquals("Should return 1.0145103074469635E60",
+ 1.0145103074469635E60, StrictMath.expm1(138.16951162));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath
+ .expm1(123456789123456789123456789.4521584223));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.expm1(Double.MAX_VALUE));
+ assertEquals("Should return MIN_VALUE", Double.MIN_VALUE, StrictMath
+ .expm1(Double.MIN_VALUE));
+
+ }
+
+ /**
+ * java.lang.StrictMath#floor(double)
+ */
+ public void test_floorD() {
+ // Test for method double java.lang.StrictMath.floor(double)
+ assertEquals("Incorrect floor for double",
+ 78, StrictMath.floor(78.89), 0.0);
+ assertEquals("Incorrect floor for double",
+ -79, StrictMath.floor(-78.89), 0.0);
+ }
+
+ /**
+ * {@link java.lang.StrictMath#getExponent(double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_getExponent_D() {
+ for (int i = 0; i < GETEXPONENT_D_CASES.length; i++) {
+ final double number = GETEXPONENT_D_CASES[i];
+ final int result = GETEXPONENT_D_RESULTS[i];
+ assertEquals("Wrong result of getExponent(double).", result,
+ StrictMath.getExponent(number));
+ }
+
+ try {
+ StrictMath.getExponent((Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * {@link java.lang.StrictMath#getExponent(float)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_getExponent_F() {
+ for (int i = 0; i < GETEXPONENT_F_CASES.length; i++) {
+ final float number = GETEXPONENT_F_CASES[i];
+ final int result = GETEXPONENT_F_RESULTS[i];
+ assertEquals("Wrong result of getExponent(float).", result,
+ StrictMath.getExponent(number));
+ }
+ try {
+ StrictMath.getExponent((Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StrictMath#hypot(double, double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_hypot_DD() {
+ // Test for special cases
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.hypot(Double.POSITIVE_INFINITY,
+ 1.0));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.hypot(Double.NEGATIVE_INFINITY,
+ 123.324));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.hypot(-758.2587,
+ Double.POSITIVE_INFINITY));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.hypot(5687.21,
+ Double.NEGATIVE_INFINITY));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.hypot(Double.POSITIVE_INFINITY,
+ Double.NEGATIVE_INFINITY));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.hypot(Double.NEGATIVE_INFINITY,
+ Double.POSITIVE_INFINITY));
+ assertTrue("Should return NaN", Double.isNaN(StrictMath.hypot(Double.NaN,
+ 2342301.89843)));
+ assertTrue("Should return NaN", Double.isNaN(StrictMath.hypot(-345.2680,
+ Double.NaN)));
+
+ assertEquals("Should return 2396424.905416697", 2396424.905416697, StrictMath
+ .hypot(12322.12, -2396393.2258));
+ assertEquals("Should return 138.16958070558556", 138.16958070558556,
+ StrictMath.hypot(-138.16951162, 0.13817035864));
+ assertEquals("Should return 1.7976931348623157E308",
+ 1.7976931348623157E308, StrictMath.hypot(Double.MAX_VALUE, 211370.35));
+ assertEquals("Should return 5413.7185", 5413.7185, StrictMath.hypot(
+ -5413.7185, Double.MIN_VALUE));
+
+ }
+
+ /**
+ * java.lang.StrictMath#IEEEremainder(double, double)
+ */
+ public void test_IEEEremainderDD() {
+ // Test for method double java.lang.StrictMath.IEEEremainder(double,
+ // double)
+ assertEquals("Incorrect remainder returned", 0.0, StrictMath.IEEEremainder(
+ 1.0, 1.0), 0.0);
+ assertTrue(
+ "Incorrect remainder returned",
+ StrictMath.IEEEremainder(1.32, 89.765) >= 1.4705063220631647E-2
+ || StrictMath.IEEEremainder(1.32, 89.765) >= 1.4705063220631649E-2);
+ }
+
+ /**
+ * java.lang.StrictMath#log(double)
+ */
+ public void test_logD() {
+ // Test for method double java.lang.StrictMath.log(double)
+ for (double d = 10; d >= -10; d -= 0.5) {
+ double answer = StrictMath.log(StrictMath.exp(d));
+ assertTrue("Answer does not equal expected answer for d = " + d
+ + " answer = " + answer,
+ StrictMath.abs(answer - d) <= StrictMath
+ .abs(d * 0.00000001));
+ }
+ }
+
+ /**
+ * java.lang.StrictMath#log10(double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_log10_D() {
+ // Test for special cases
+ assertTrue("Should return NaN", Double.isNaN(StrictMath
+ .log10(Double.NaN)));
+ assertTrue("Should return NaN", Double.isNaN(StrictMath
+ .log10(-2541.05745687234187532)));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath
+ .log10(Double.POSITIVE_INFINITY));
+ assertEquals("Should return NEGATIVE_INFINITY",
+ Double.NEGATIVE_INFINITY, StrictMath.log10(0.0));
+ assertEquals("Should return NEGATIVE_INFINITY",
+ Double.NEGATIVE_INFINITY, StrictMath.log10(+0.0));
+ assertEquals("Should return NEGATIVE_INFINITY",
+ Double.NEGATIVE_INFINITY, StrictMath.log10(-0.0));
+ assertEquals("Should return 14.0", 14.0, StrictMath.log10(StrictMath
+ .pow(10, 14)));
+
+ assertEquals("Should return 3.7389561269540406", 3.7389561269540406,
+ StrictMath.log10(5482.2158));
+ assertEquals("Should return 14.661551142893833", 14.661551142893833,
+ StrictMath.log10(458723662312872.125782332587));
+ assertEquals("Should return -0.9083828622192334", -0.9083828622192334,
+ StrictMath.log10(0.12348583358871));
+ assertEquals("Should return 308.25471555991675", 308.25471555991675,
+ StrictMath.log10(Double.MAX_VALUE));
+ assertEquals("Should return -323.3062153431158", -323.3062153431158,
+ StrictMath.log10(Double.MIN_VALUE));
+ }
+
+ /**
+ * java.lang.StrictMath#log1p(double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_log1p_D() {
+ // Test for special cases
+ assertTrue("Should return NaN", Double.isNaN(StrictMath
+ .log1p(Double.NaN)));
+ assertTrue("Should return NaN", Double.isNaN(StrictMath
+ .log1p(-32.0482175)));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath
+ .log1p(Double.POSITIVE_INFINITY));
+ assertEquals(Double.doubleToLongBits(0.0), Double
+ .doubleToLongBits(StrictMath.log1p(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(StrictMath.log1p(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(StrictMath.log1p(-0.0)));
+
+ assertEquals("Should return -0.2941782295312541", -0.2941782295312541,
+ StrictMath.log1p(-0.254856327));
+ assertEquals("Should return 7.368050685564151", 7.368050685564151,
+ StrictMath.log1p(1583.542));
+ assertEquals("Should return 0.4633708685409921", 0.4633708685409921,
+ StrictMath.log1p(0.5894227));
+ assertEquals("Should return 709.782712893384", 709.782712893384,
+ StrictMath.log1p(Double.MAX_VALUE));
+ assertEquals("Should return Double.MIN_VALUE", Double.MIN_VALUE,
+ StrictMath.log1p(Double.MIN_VALUE));
+ }
+
+ /**
+ * java.lang.StrictMath#max(double, double)
+ */
+ public void test_maxDD() {
+ // Test for method double java.lang.StrictMath.max(double, double)
+ assertEquals("Incorrect double max value", 1908897.6000089, StrictMath.max(
+ -1908897.6000089, 1908897.6000089), 0D);
+ assertEquals("Incorrect double max value", 1908897.6000089, StrictMath.max(2.0,
+ 1908897.6000089), 0D);
+ assertEquals("Incorrect double max value", -2.0, StrictMath.max(-2.0,
+ -1908897.6000089), 0D);
+
+ }
+
+ /**
+ * java.lang.StrictMath#max(float, float)
+ */
+ public void test_maxFF() {
+ // Test for method float java.lang.StrictMath.max(float, float)
+ assertTrue("Incorrect float max value", StrictMath.max(-1908897.600f,
+ 1908897.600f) == 1908897.600f);
+ assertTrue("Incorrect float max value", StrictMath.max(2.0f,
+ 1908897.600f) == 1908897.600f);
+ assertTrue("Incorrect float max value", StrictMath.max(-2.0f,
+ -1908897.600f) == -2.0f);
+ }
+
+ /**
+ * java.lang.StrictMath#max(int, int)
+ */
+ public void test_maxII() {
+ // Test for method int java.lang.StrictMath.max(int, int)
+ assertEquals("Incorrect int max value", 19088976, StrictMath.max(-19088976,
+ 19088976));
+ assertEquals("Incorrect int max value",
+ 19088976, StrictMath.max(20, 19088976));
+ assertEquals("Incorrect int max value",
+ -20, StrictMath.max(-20, -19088976));
+ }
+
+ /**
+ * java.lang.StrictMath#max(long, long)
+ */
+ public void test_maxJJ() {
+ // Test for method long java.lang.StrictMath.max(long, long)
+ assertEquals("Incorrect long max value", 19088976000089L, StrictMath.max(-19088976000089L,
+ 19088976000089L));
+ assertEquals("Incorrect long max value", 19088976000089L, StrictMath.max(20,
+ 19088976000089L));
+ assertEquals("Incorrect long max value", -20, StrictMath.max(-20,
+ -19088976000089L));
+ }
+
+ /**
+ * java.lang.StrictMath#min(double, double)
+ */
+ public void test_minDD() {
+ // Test for method double java.lang.StrictMath.min(double, double)
+ assertEquals("Incorrect double min value", -1908897.6000089, StrictMath.min(
+ -1908897.6000089, 1908897.6000089), 0D);
+ assertEquals("Incorrect double min value", 2.0, StrictMath.min(2.0,
+ 1908897.6000089), 0D);
+ assertEquals("Incorrect double min value", -1908897.6000089, StrictMath.min(-2.0,
+ -1908897.6000089), 0D);
+ }
+
+ /**
+ * java.lang.StrictMath#min(float, float)
+ */
+ public void test_minFF() {
+ // Test for method float java.lang.StrictMath.min(float, float)
+ assertTrue("Incorrect float min value", StrictMath.min(-1908897.600f,
+ 1908897.600f) == -1908897.600f);
+ assertTrue("Incorrect float min value", StrictMath.min(2.0f,
+ 1908897.600f) == 2.0f);
+ assertTrue("Incorrect float min value", StrictMath.min(-2.0f,
+ -1908897.600f) == -1908897.600f);
+ }
+
+ /**
+ * java.lang.StrictMath#min(int, int)
+ */
+ public void test_minII() {
+ // Test for method int java.lang.StrictMath.min(int, int)
+ assertEquals("Incorrect int min value", -19088976, StrictMath.min(-19088976,
+ 19088976));
+ assertEquals("Incorrect int min value",
+ 20, StrictMath.min(20, 19088976));
+ assertEquals("Incorrect int min value",
+ -19088976, StrictMath.min(-20, -19088976));
+
+ }
+
+ /**
+ * java.lang.StrictMath#min(long, long)
+ */
+ public void test_minJJ() {
+ // Test for method long java.lang.StrictMath.min(long, long)
+ assertEquals("Incorrect long min value", -19088976000089L, StrictMath.min(-19088976000089L,
+ 19088976000089L));
+ assertEquals("Incorrect long min value", 20, StrictMath.min(20,
+ 19088976000089L));
+ assertEquals("Incorrect long min value", -19088976000089L, StrictMath.min(-20,
+ -19088976000089L));
+ }
+
+ /**
+ * {@link java.lang.StrictMath#nextAfter(double, double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextAfter_DD() {
+ // test for most cases without exception
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ final double start = NEXTAFTER_DD_START_CASES[i][0];
+ final long nextUpBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+ final long nextDownBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][2]);
+
+ for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+ final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+ final long resultBits = Double.doubleToLongBits(StrictMath
+ .nextAfter(start, direction));
+ final long directionBits = Double.doubleToLongBits(direction);
+ if (direction > start) {
+ assertEquals("Result should be next up-number.",
+ nextUpBits, resultBits);
+ } else if (direction < start) {
+ assertEquals("Result should be next down-number.",
+ nextDownBits, resultBits);
+ } else {
+ assertEquals("Result should be direction.", directionBits,
+ resultBits);
+ }
+ }
+ }
+
+ // test for cases with NaN
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+ .nextAfter(NEXTAFTER_DD_START_CASES[i][0], Double.NaN)));
+ }
+ for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+ .nextAfter(Double.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+ }
+ assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+ .nextAfter(Double.NaN, Double.NaN)));
+
+ // test for exception
+ try {
+ StrictMath.nextAfter((Double) null, 2.3);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.nextAfter(2.3, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.nextAfter((Double) null, (Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * {@link java.lang.StrictMath#nextAfter(float, double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextAfter_FD() {
+ // test for most cases without exception
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ final float start = NEXTAFTER_FD_START_CASES[i][0];
+ final int nextUpBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+ final int nextDownBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][2]);
+
+ for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+ final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+ final int resultBits = Float.floatToIntBits(StrictMath
+ .nextAfter(start, direction));
+ if (direction > start) {
+ assertEquals("Result should be next up-number.",
+ nextUpBits, resultBits);
+ } else if (direction < start) {
+ assertEquals("Result should be next down-number.",
+ nextDownBits, resultBits);
+ } else {
+ final int equivalentBits = Float.floatToIntBits(new Float(
+ direction));
+ assertEquals(
+ "Result should be a number equivalent to direction.",
+ equivalentBits, resultBits);
+ }
+ }
+ }
+
+ // test for cases with NaN
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+ .nextAfter(NEXTAFTER_FD_START_CASES[i][0], Float.NaN)));
+ }
+ for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+ assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+ .nextAfter(Float.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+ }
+ assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+ .nextAfter(Float.NaN, Float.NaN)));
+
+ // test for exception
+ try {
+ StrictMath.nextAfter((Float) null, 2.3);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.nextAfter(2.3, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.nextAfter((Float) null, (Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * {@link java.lang.StrictMath#nextUp(double)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextUp_D() {
+ // This method is semantically equivalent to nextAfter(d,
+ // Double.POSITIVE_INFINITY),
+ // so we use the data of test_nextAfter_DD
+ for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+ final double start = NEXTAFTER_DD_START_CASES[i][0];
+ final long nextUpBits = Double
+ .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+ final long resultBits = Double.doubleToLongBits(StrictMath
+ .nextUp(start));
+ assertEquals("Result should be next up-number.", nextUpBits,
+ resultBits);
+ }
+
+ // test for cases with NaN
+ assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+ .nextUp(Double.NaN)));
+
+ // test for exception
+ try {
+ StrictMath.nextUp((Double) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * {@link java.lang.StrictMath#nextUp(float)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_nextUp_F() {
+ // This method is semantically equivalent to nextAfter(f,
+ // Float.POSITIVE_INFINITY),
+ // so we use the data of test_nextAfter_FD
+ for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+ final float start = NEXTAFTER_FD_START_CASES[i][0];
+ final int nextUpBits = Float
+ .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+ final int resultBits = Float.floatToIntBits(StrictMath
+ .nextUp(start));
+ assertEquals("Result should be next up-number.", nextUpBits,
+ resultBits);
+ }
+
+ // test for cases with NaN
+ assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+ .nextUp(Float.NaN)));
+
+ // test for exception
+ try {
+ StrictMath.nextUp((Float) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StrictMath#pow(double, double)
+ */
+ public void test_powDD() {
+ // Test for method double java.lang.StrictMath.pow(double, double)
+ assertTrue("pow returned incorrect value",
+ (long) StrictMath.pow(2, 8) == 256l);
+ assertTrue("pow returned incorrect value",
+ StrictMath.pow(2, -8) == 0.00390625d);
+ }
+
+ /**
+ * java.lang.StrictMath#rint(double)
+ */
+ public void test_rintD() {
+ // Test for method double java.lang.StrictMath.rint(double)
+ assertEquals("Failed to round properly - up to odd",
+ 3.0, StrictMath.rint(2.9), 0D);
+ assertTrue("Failed to round properly - NaN", Double.isNaN(StrictMath
+ .rint(Double.NaN)));
+ assertEquals("Failed to round properly down to even", 2.0, StrictMath
+ .rint(2.1), 0D);
+ assertTrue("Failed to round properly " + 2.5 + " to even", StrictMath
+ .rint(2.5) == 2.0);
+ }
+
+ /**
+ * java.lang.StrictMath#round(double)
+ */
+ public void test_roundD() {
+ // Test for method long java.lang.StrictMath.round(double)
+ assertEquals("Incorrect rounding of a float",
+ -91, StrictMath.round(-90.89d));
+ }
+
+ /**
+ * java.lang.StrictMath#round(float)
+ */
+ public void test_roundF() {
+ // Test for method int java.lang.StrictMath.round(float)
+ assertEquals("Incorrect rounding of a float",
+ -91, StrictMath.round(-90.89f));
+ }
+
+ /**
+ * {@link java.lang.StrictMath#scalb(double, int)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_scalb_DI() {
+ // result is normal
+ assertEquals(4.1422946304E7, StrictMath.scalb(1.2345, 25));
+ assertEquals(3.679096698760986E-8, StrictMath.scalb(1.2345, -25));
+ assertEquals(1.2345, StrictMath.scalb(1.2345, 0));
+ assertEquals(7868514.304, StrictMath.scalb(0.2345, 25));
+
+ double normal = StrictMath.scalb(0.2345, -25);
+ assertEquals(6.98864459991455E-9, normal);
+ // precision kept
+ assertEquals(0.2345, StrictMath.scalb(normal, 25));
+
+ assertEquals(0.2345, StrictMath.scalb(0.2345, 0));
+ assertEquals(-4.1422946304E7, StrictMath.scalb(-1.2345, 25));
+ assertEquals(-6.98864459991455E-9, StrictMath.scalb(-0.2345, -25));
+ assertEquals(2.0, StrictMath.scalb(Double.MIN_NORMAL / 2, 1024));
+ assertEquals(64.0, StrictMath.scalb(Double.MIN_VALUE, 1080));
+ assertEquals(234, StrictMath.getExponent(StrictMath.scalb(1.0, 234)));
+ assertEquals(3.9999999999999996, StrictMath.scalb(Double.MAX_VALUE,
+ Double.MIN_EXPONENT));
+
+ // result is near infinity
+ double halfMax = StrictMath.scalb(1.0, Double.MAX_EXPONENT);
+ assertEquals(8.98846567431158E307, halfMax);
+ assertEquals(Double.MAX_VALUE, halfMax - StrictMath.ulp(halfMax)
+ + halfMax);
+ assertEquals(Double.POSITIVE_INFINITY, halfMax + halfMax);
+ assertEquals(1.7976931348623155E308, StrictMath.scalb(1.0 - StrictMath
+ .ulp(1.0), Double.MAX_EXPONENT + 1));
+ assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+ 1.0 - StrictMath.ulp(1.0), Double.MAX_EXPONENT + 2));
+
+ halfMax = StrictMath.scalb(-1.0, Double.MAX_EXPONENT);
+ assertEquals(-8.98846567431158E307, halfMax);
+ assertEquals(-Double.MAX_VALUE, halfMax + StrictMath.ulp(halfMax)
+ + halfMax);
+ assertEquals(Double.NEGATIVE_INFINITY, halfMax + halfMax);
+
+ assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(0.345, 1234));
+ assertEquals(Double.POSITIVE_INFINITY, StrictMath
+ .scalb(44.345E102, 934));
+ assertEquals(Double.NEGATIVE_INFINITY, StrictMath.scalb(-44.345E102,
+ 934));
+
+ assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+ Double.MIN_NORMAL / 2, 4000));
+ assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+ Double.MIN_VALUE, 8000));
+ assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+ Double.MAX_VALUE, 1));
+ assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+ Double.POSITIVE_INFINITY, 0));
+ assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+ Double.POSITIVE_INFINITY, -1));
+ assertEquals(Double.NEGATIVE_INFINITY, StrictMath.scalb(
+ Double.NEGATIVE_INFINITY, -1));
+ assertEquals(Double.NEGATIVE_INFINITY, StrictMath.scalb(
+ Double.NEGATIVE_INFINITY, Double.MIN_EXPONENT));
+
+ // result is subnormal/zero
+ long posZeroBits = Double.doubleToLongBits(+0.0);
+ long negZeroBits = Double.doubleToLongBits(-0.0);
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ +0.0, Integer.MAX_VALUE)));
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ +0.0, -123)));
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ +0.0, 0)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ -0.0, 123)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ -0.0, Integer.MIN_VALUE)));
+
+ assertEquals(Double.MIN_VALUE, StrictMath.scalb(1.0, -1074));
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(1.0,
+ -1075)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ -1.0, -1075)));
+
+ // precision lost
+ assertEquals(StrictMath.scalb(21.405, -1078), StrictMath.scalb(21.405,
+ -1079));
+ assertEquals(Double.MIN_VALUE, StrictMath.scalb(21.405, -1079));
+ assertEquals(-Double.MIN_VALUE, StrictMath.scalb(-21.405, -1079));
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ 21.405, -1080)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ -21.405, -1080)));
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ Double.MIN_VALUE, -1)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ -Double.MIN_VALUE, -1)));
+ assertEquals(Double.MIN_VALUE, StrictMath.scalb(Double.MIN_NORMAL, -52));
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ Double.MIN_NORMAL, -53)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ -Double.MIN_NORMAL, -53)));
+ assertEquals(Double.MIN_VALUE, StrictMath
+ .scalb(Double.MAX_VALUE, -2098));
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ Double.MAX_VALUE, -2099)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ -Double.MAX_VALUE, -2099)));
+ assertEquals(Double.MIN_VALUE, StrictMath.scalb(Double.MIN_NORMAL / 3,
+ -51));
+ assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ Double.MIN_NORMAL / 3, -52)));
+ assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+ -Double.MIN_NORMAL / 3, -52)));
+ double subnormal = StrictMath.scalb(Double.MIN_NORMAL / 3, -25);
+ assertEquals(2.2104123E-316, subnormal);
+ // precision lost
+ assertFalse(Double.MIN_NORMAL / 3 == StrictMath.scalb(subnormal, 25));
+
+ // NaN
+ assertTrue(Double.isNaN(StrictMath.scalb(Double.NaN, 1)));
+ assertTrue(Double.isNaN(StrictMath.scalb(Double.NaN, 0)));
+ assertTrue(Double.isNaN(StrictMath.scalb(Double.NaN, -120)));
+
+ assertEquals(1283457024, Double.doubleToLongBits(StrictMath.scalb(
+ Double.MIN_VALUE * 153, 23)));
+ assertEquals(-9223372035571318784L, Double.doubleToLongBits(StrictMath
+ .scalb(-Double.MIN_VALUE * 153, 23)));
+ assertEquals(36908406321184768L, Double.doubleToLongBits(StrictMath
+ .scalb(Double.MIN_VALUE * 153, 52)));
+ assertEquals(-9186463630533591040L, Double.doubleToLongBits(StrictMath
+ .scalb(-Double.MIN_VALUE * 153, 52)));
+
+ // test for exception
+ try {
+ StrictMath.scalb((Double) null, (Integer) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.scalb(1.0, (Integer) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.scalb((Double) null, 1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * {@link java.lang.StrictMath#scalb(float, int)}
+ * @since 1.6
+ */
+ @SuppressWarnings("boxing")
+ public void test_scalb_FI() {
+ // result is normal
+ assertEquals(4.1422946304E7f, StrictMath.scalb(1.2345f, 25));
+ assertEquals(3.679096698760986E-8f, StrictMath.scalb(1.2345f, -25));
+ assertEquals(1.2345f, StrictMath.scalb(1.2345f, 0));
+ assertEquals(7868514.304f, StrictMath.scalb(0.2345f, 25));
+
+ float normal = StrictMath.scalb(0.2345f, -25);
+ assertEquals(6.98864459991455E-9f, normal);
+ // precision kept
+ assertEquals(0.2345f, StrictMath.scalb(normal, 25));
+
+ assertEquals(0.2345f, StrictMath.scalb(0.2345f, 0));
+ assertEquals(-4.1422946304E7f, StrictMath.scalb(-1.2345f, 25));
+ assertEquals(-6.98864459991455E-9f, StrictMath.scalb(-0.2345f, -25));
+ assertEquals(2.0f, StrictMath.scalb(Float.MIN_NORMAL / 2, 128));
+ assertEquals(64.0f, StrictMath.scalb(Float.MIN_VALUE, 155));
+ assertEquals(34, StrictMath.getExponent(StrictMath.scalb(1.0f, 34)));
+ assertEquals(3.9999998f, StrictMath.scalb(Float.MAX_VALUE,
+ Float.MIN_EXPONENT));
+
+ // result is near infinity
+ float halfMax = StrictMath.scalb(1.0f, Float.MAX_EXPONENT);
+ assertEquals(1.7014118E38f, halfMax);
+ assertEquals(Float.MAX_VALUE, halfMax - StrictMath.ulp(halfMax)
+ + halfMax);
+ assertEquals(Float.POSITIVE_INFINITY, halfMax + halfMax);
+ assertEquals(3.4028233E38f, StrictMath.scalb(1.0f - StrictMath
+ .ulp(1.0f), Float.MAX_EXPONENT + 1));
+ assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(
+ 1.0f - StrictMath.ulp(1.0f), Float.MAX_EXPONENT + 2));
+
+ halfMax = StrictMath.scalb(-1.0f, Float.MAX_EXPONENT);
+ assertEquals(-1.7014118E38f, halfMax);
+ assertEquals(-Float.MAX_VALUE, halfMax + StrictMath.ulp(halfMax)
+ + halfMax);
+ assertEquals(Float.NEGATIVE_INFINITY, halfMax + halfMax);
+
+ assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(0.345f, 1234));
+ assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(44.345E10f, 934));
+ assertEquals(Float.NEGATIVE_INFINITY, StrictMath
+ .scalb(-44.345E10f, 934));
+
+ assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(
+ Float.MIN_NORMAL / 2, 400));
+ assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(Float.MIN_VALUE,
+ 800));
+ assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(Float.MAX_VALUE,
+ 1));
+ assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(
+ Float.POSITIVE_INFINITY, 0));
+ assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(
+ Float.POSITIVE_INFINITY, -1));
+ assertEquals(Float.NEGATIVE_INFINITY, StrictMath.scalb(
+ Float.NEGATIVE_INFINITY, -1));
+ assertEquals(Float.NEGATIVE_INFINITY, StrictMath.scalb(
+ Float.NEGATIVE_INFINITY, Float.MIN_EXPONENT));
+
+ // result is subnormal/zero
+ int posZeroBits = Float.floatToIntBits(+0.0f);
+ int negZeroBits = Float.floatToIntBits(-0.0f);
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(+0.0f,
+ Integer.MAX_VALUE)));
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(+0.0f,
+ -123)));
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(+0.0f,
+ 0)));
+ assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(-0.0f,
+ 123)));
+ assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(-0.0f,
+ Integer.MIN_VALUE)));
+
+ assertEquals(Float.MIN_VALUE, StrictMath.scalb(1.0f, -149));
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(1.0f,
+ -150)));
+ assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(-1.0f,
+ -150)));
+
+ // precision lost
+ assertEquals(StrictMath.scalb(21.405f, -154), StrictMath.scalb(21.405f,
+ -153));
+ assertEquals(Float.MIN_VALUE, StrictMath.scalb(21.405f, -154));
+ assertEquals(-Float.MIN_VALUE, StrictMath.scalb(-21.405f, -154));
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ 21.405f, -155)));
+ assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ -21.405f, -155)));
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ Float.MIN_VALUE, -1)));
+ assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ -Float.MIN_VALUE, -1)));
+ assertEquals(Float.MIN_VALUE, StrictMath.scalb(Float.MIN_NORMAL, -23));
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ Float.MIN_NORMAL, -24)));
+ assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ -Float.MIN_NORMAL, -24)));
+ assertEquals(Float.MIN_VALUE, StrictMath.scalb(Float.MAX_VALUE, -277));
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ Float.MAX_VALUE, -278)));
+ assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ -Float.MAX_VALUE, -278)));
+ assertEquals(Float.MIN_VALUE, StrictMath.scalb(Float.MIN_NORMAL / 3,
+ -22));
+ assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ Float.MIN_NORMAL / 3, -23)));
+ assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+ -Float.MIN_NORMAL / 3, -23)));
+ float subnormal = StrictMath.scalb(Float.MIN_NORMAL / 3, -11);
+ assertEquals(1.913E-42f, subnormal);
+ // precision lost
+ assertFalse(Float.MIN_NORMAL / 3 == StrictMath.scalb(subnormal, 11));
+
+ assertEquals(68747264, Float.floatToIntBits(StrictMath.scalb(
+ Float.MIN_VALUE * 153, 23)));
+ assertEquals(-2078736384, Float.floatToIntBits(StrictMath.scalb(
+ -Float.MIN_VALUE * 153, 23)));
+
+ assertEquals(4896, Float.floatToIntBits(StrictMath.scalb(
+ Float.MIN_VALUE * 153, 5)));
+ assertEquals(-2147478752, Float.floatToIntBits(StrictMath.scalb(
+ -Float.MIN_VALUE * 153, 5)));
+
+ // NaN
+ assertTrue(Float.isNaN(StrictMath.scalb(Float.NaN, 1)));
+ assertTrue(Float.isNaN(StrictMath.scalb(Float.NaN, 0)));
+ assertTrue(Float.isNaN(StrictMath.scalb(Float.NaN, -120)));
+
+ // test for exception
+ try {
+ StrictMath.scalb((Float) null, (Integer) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.scalb(1.0f, (Integer) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ StrictMath.scalb((Float) null, 1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StrictMath#signum(double)
+ */
+ public void test_signum_D() {
+ assertTrue(Double.isNaN(StrictMath.signum(Double.NaN)));
+ assertEquals(Double.doubleToLongBits(0.0), Double
+ .doubleToLongBits(StrictMath.signum(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(StrictMath.signum(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(StrictMath.signum(-0.0)));
+
+ assertEquals(1.0, StrictMath.signum(253681.2187962), 0D);
+ assertEquals(-1.0, StrictMath.signum(-125874693.56), 0D);
+ assertEquals(1.0, StrictMath.signum(1.2587E-308), 0D);
+ assertEquals(-1.0, StrictMath.signum(-1.2587E-308), 0D);
+
+ assertEquals(1.0, StrictMath.signum(Double.MAX_VALUE), 0D);
+ assertEquals(1.0, StrictMath.signum(Double.MIN_VALUE), 0D);
+ assertEquals(-1.0, StrictMath.signum(-Double.MAX_VALUE), 0D);
+ assertEquals(-1.0, StrictMath.signum(-Double.MIN_VALUE), 0D);
+ assertEquals(1.0, StrictMath.signum(Double.POSITIVE_INFINITY), 0D);
+ assertEquals(-1.0, StrictMath.signum(Double.NEGATIVE_INFINITY), 0D);
+
+ }
+
+ /**
+ * java.lang.StrictMath#signum(float)
+ */
+ public void test_signum_F() {
+ assertTrue(Float.isNaN(StrictMath.signum(Float.NaN)));
+ assertEquals(Float.floatToIntBits(0.0f), Float
+ .floatToIntBits(StrictMath.signum(0.0f)));
+ assertEquals(Float.floatToIntBits(+0.0f), Float
+ .floatToIntBits(StrictMath.signum(+0.0f)));
+ assertEquals(Float.floatToIntBits(-0.0f), Float
+ .floatToIntBits(StrictMath.signum(-0.0f)));
+
+ assertEquals(1.0f, StrictMath.signum(253681.2187962f), 0f);
+ assertEquals(-1.0f, StrictMath.signum(-125874693.56f), 0f);
+ assertEquals(1.0f, StrictMath.signum(1.2587E-11f), 0f);
+ assertEquals(-1.0f, StrictMath.signum(-1.2587E-11f), 0f);
+
+ assertEquals(1.0f, StrictMath.signum(Float.MAX_VALUE), 0f);
+ assertEquals(1.0f, StrictMath.signum(Float.MIN_VALUE), 0f);
+ assertEquals(-1.0f, StrictMath.signum(-Float.MAX_VALUE), 0f);
+ assertEquals(-1.0f, StrictMath.signum(-Float.MIN_VALUE), 0f);
+ assertEquals(1.0f, StrictMath.signum(Float.POSITIVE_INFINITY), 0f);
+ assertEquals(-1.0f, StrictMath.signum(Float.NEGATIVE_INFINITY), 0f);
+ }
+
+ /**
+ * java.lang.StrictMath#sin(double)
+ */
+ public void test_sinD() {
+ // Test for method double java.lang.StrictMath.sin(double)
+ assertTrue("Returned incorrect sine", StrictMath.sin(StrictMath
+ .asin(OPP / HYP)) == OPP / HYP);
+ }
+
+ /**
+ * java.lang.StrictMath#sinh(double)
+ */
+ public void test_sinh_D() {
+ // Test for special situations
+ assertTrue(Double.isNaN(StrictMath.sinh(Double.NaN)));
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath
+ .sinh(Double.POSITIVE_INFINITY), 0D);
+ assertEquals("Should return NEGATIVE_INFINITY",
+ Double.NEGATIVE_INFINITY, StrictMath
+ .sinh(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals(Double.doubleToLongBits(0.0), Double
+ .doubleToLongBits(StrictMath.sinh(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(StrictMath.sinh(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(StrictMath.sinh(-0.0)));
+
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.sinh(1234.56), 0D);
+ assertEquals("Should return NEGATIVE_INFINITY",
+ Double.NEGATIVE_INFINITY, StrictMath.sinh(-1234.56), 0D);
+ assertEquals("Should return 1.0000000000001666E-6",
+ 1.0000000000001666E-6, StrictMath.sinh(0.000001), 0D);
+ assertEquals("Should return -1.0000000000001666E-6",
+ -1.0000000000001666E-6, StrictMath.sinh(-0.000001), 0D);
+ assertEquals("Should return 5.115386441963859", 5.115386441963859,
+ StrictMath.sinh(2.33482), 0D);
+ assertEquals("Should return POSITIVE_INFINITY",
+ Double.POSITIVE_INFINITY, StrictMath.sinh(Double.MAX_VALUE), 0D);
+ assertEquals("Should return 4.9E-324", 4.9E-324, StrictMath
+ .sinh(Double.MIN_VALUE), 0D);
+ }
+
+ /**
+ * java.lang.StrictMath#sqrt(double)
+ */
+ public void test_sqrtD() {
+ // Test for method double java.lang.StrictMath.sqrt(double)
+ assertEquals("Incorrect root returned1",
+ 2, StrictMath.sqrt(StrictMath.pow(StrictMath.sqrt(2), 4)), 0.0);
+ assertEquals("Incorrect root returned2", 7, StrictMath.sqrt(49), 0.0);
+ }
+
+ /**
+ * java.lang.StrictMath#tan(double)
+ */
+ public void test_tanD() {
+ // Test for method double java.lang.StrictMath.tan(double)
+ assertTrue(
+ "Returned incorrect tangent: ",
+ StrictMath.tan(StrictMath.atan(1.0)) <= 1.0
+ || StrictMath.tan(StrictMath.atan(1.0)) >= 9.9999999999999983E-1);
+ }
+
+ /**
+ * java.lang.StrictMath#tanh(double)
+ */
+ public void test_tanh_D() {
+ // Test for special situations
+ assertTrue(Double.isNaN(StrictMath.tanh(Double.NaN)));
+ assertEquals("Should return +1.0", +1.0, StrictMath
+ .tanh(Double.POSITIVE_INFINITY), 0D);
+ assertEquals("Should return -1.0", -1.0, StrictMath
+ .tanh(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals(Double.doubleToLongBits(0.0), Double
+ .doubleToLongBits(StrictMath.tanh(0.0)));
+ assertEquals(Double.doubleToLongBits(+0.0), Double
+ .doubleToLongBits(StrictMath.tanh(+0.0)));
+ assertEquals(Double.doubleToLongBits(-0.0), Double
+ .doubleToLongBits(StrictMath.tanh(-0.0)));
+
+ assertEquals("Should return 1.0", 1.0, StrictMath.tanh(1234.56), 0D);
+ assertEquals("Should return -1.0", -1.0, StrictMath.tanh(-1234.56), 0D);
+ assertEquals("Should return 9.999999999996666E-7",
+ 9.999999999996666E-7, StrictMath.tanh(0.000001), 0D);
+ assertEquals("Should return 0.981422884124941", 0.981422884124941,
+ StrictMath.tanh(2.33482), 0D);
+ assertEquals("Should return 1.0", 1.0, StrictMath
+ .tanh(Double.MAX_VALUE), 0D);
+ assertEquals("Should return 4.9E-324", 4.9E-324, StrictMath
+ .tanh(Double.MIN_VALUE), 0D);
+ }
+
+ /**
+ * java.lang.StrictMath#random()
+ */
+ public void test_random() {
+ // There isn't a place for these tests so just stick them here
+ assertEquals("Wrong value E",
+ 4613303445314885481L, Double.doubleToLongBits(StrictMath.E));
+ assertEquals("Wrong value PI",
+ 4614256656552045848L, Double.doubleToLongBits(StrictMath.PI));
+
+ for (int i = 500; i >= 0; i--) {
+ double d = StrictMath.random();
+ assertTrue("Generated number is out of range: " + d, d >= 0.0
+ && d < 1.0);
+ }
+ }
+
+ /**
+ * java.lang.StrictMath#toRadians(double)
+ */
+ public void test_toRadiansD() {
+ for (double d = 500; d >= 0; d -= 1.0) {
+ double converted = StrictMath.toDegrees(StrictMath.toRadians(d));
+ assertTrue("Converted number not equal to original. d = " + d,
+ converted >= d * 0.99999999 && converted <= d * 1.00000001);
+ }
+ }
+
+ /**
+ * java.lang.StrictMath#toDegrees(double)
+ */
+ public void test_toDegreesD() {
+ for (double d = 500; d >= 0; d -= 1.0) {
+ double converted = StrictMath.toRadians(StrictMath.toDegrees(d));
+ assertTrue("Converted number not equal to original. d = " + d,
+ converted >= d * 0.99999999 && converted <= d * 1.00000001);
+ }
+ }
+
+ /**
+ * java.lang.StrictMath#ulp(double)
+ */
+ @SuppressWarnings("boxing")
+ public void test_ulp_D() {
+ // Test for special cases
+ assertTrue("Should return NaN", Double
+ .isNaN(StrictMath.ulp(Double.NaN)));
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY,
+ StrictMath.ulp(Double.POSITIVE_INFINITY), 0D);
+ assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY,
+ StrictMath.ulp(Double.NEGATIVE_INFINITY), 0D);
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+ .ulp(0.0), 0D);
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+ .ulp(+0.0), 0D);
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+ .ulp(-0.0), 0D);
+ assertEquals("Returned incorrect value", StrictMath.pow(2, 971),
+ StrictMath.ulp(Double.MAX_VALUE), 0D);
+ assertEquals("Returned incorrect value", StrictMath.pow(2, 971),
+ StrictMath.ulp(-Double.MAX_VALUE), 0D);
+
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+ .ulp(Double.MIN_VALUE), 0D);
+ assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+ .ulp(-Double.MIN_VALUE), 0D);
+
+ assertEquals("Returned incorrect value", 2.220446049250313E-16,
+ StrictMath.ulp(1.0), 0D);
+ assertEquals("Returned incorrect value", 2.220446049250313E-16,
+ StrictMath.ulp(-1.0), 0D);
+ assertEquals("Returned incorrect value", 2.2737367544323206E-13,
+ StrictMath.ulp(1153.0), 0D);
+ }
+
+ /**
+ * java.lang.StrictMath#ulp(float)
+ */
+ @SuppressWarnings("boxing")
+ public void test_ulp_f() {
+ // Test for special cases
+ assertTrue("Should return NaN", Float.isNaN(StrictMath.ulp(Float.NaN)));
+ assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY,
+ StrictMath.ulp(Float.POSITIVE_INFINITY), 0f);
+ assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY,
+ StrictMath.ulp(Float.NEGATIVE_INFINITY), 0f);
+ assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
+ .ulp(0.0f), 0f);
+ assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
+ .ulp(+0.0f), 0f);
+ assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
+ .ulp(-0.0f), 0f);
+ assertEquals("Returned incorrect value", 2.028241E31f, StrictMath
+ .ulp(Float.MAX_VALUE), 0f);
+ assertEquals("Returned incorrect value", 2.028241E31f, StrictMath
+ .ulp(-Float.MAX_VALUE), 0f);
+
+ assertEquals("Returned incorrect value", 1.4E-45f, StrictMath
+ .ulp(Float.MIN_VALUE), 0f);
+ assertEquals("Returned incorrect value", 1.4E-45f, StrictMath
+ .ulp(-Float.MIN_VALUE), 0f);
+
+ assertEquals("Returned incorrect value", 1.1920929E-7f, StrictMath
+ .ulp(1.0f), 0f);
+ assertEquals("Returned incorrect value", 1.1920929E-7f, StrictMath
+ .ulp(-1.0f), 0f);
+ assertEquals("Returned incorrect value", 1.2207031E-4f, StrictMath
+ .ulp(1153.0f), 0f);
+ assertEquals("Returned incorrect value", 5.6E-45f, Math
+ .ulp(9.403954E-38f), 0f);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/String2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/String2Test.java
new file mode 100644
index 0000000..eecc601
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/String2Test.java
@@ -0,0 +1,978 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+
+public class String2Test extends junit.framework.TestCase {
+
+ String hw1 = "HelloWorld";
+
+ String hw2 = "HelloWorld";
+
+ String hwlc = "helloworld";
+
+ String hwuc = "HELLOWORLD";
+
+ String hello1 = "Hello";
+
+ String world1 = "World";
+
+ String comp11 = "Test String";
+
+ Object obj = new Object();
+
+ char[] buf = { 'W', 'o', 'r', 'l', 'd' };
+
+ char[] rbuf = new char[5];
+
+ /**
+ * java.lang.String#String()
+ */
+ public void test_Constructor() {
+ // Test for method java.lang.String()
+ assertTrue("Created incorrect string", new String().equals(""));
+ }
+
+ /**
+ * java.lang.String#String(byte[])
+ */
+ public void test_Constructor$B() {
+ // Test for method java.lang.String(byte [])
+ assertTrue("Failed to create string", new String(hw1.getBytes())
+ .equals(hw1));
+ }
+
+ /**
+ * java.lang.String#String(byte[], int)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_Constructor$BI() {
+ // Test for method java.lang.String(byte [], int)
+ String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0);
+ assertTrue("Incorrect string returned: " + s, s.equals("ABCDE"));
+ s = new String(new byte[] { 65, 66, 67, 68, 69 }, 1);
+ assertTrue("Did not use nonzero hibyte", !s.equals("ABCDE"));
+ }
+
+ /**
+ * java.lang.String#String(byte[], int, int)
+ */
+ public void test_Constructor$BII() {
+ // Test for method java.lang.String(byte [], int, int)
+ assertTrue("Failed to create string", new String(hw1.getBytes(), 0, hw1
+ .getBytes().length).equals(hw1));
+
+ boolean exception = false;
+ try {
+ new String(new byte[0], 0, Integer.MAX_VALUE);
+ } catch (IndexOutOfBoundsException e) {
+ exception = true;
+ }
+ assertTrue("Did not throw exception", exception);
+ }
+
+ /**
+ * java.lang.String#String(byte[], int, int, int)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_Constructor$BIII() {
+ // Test for method java.lang.String(byte [], int, int, int)
+ String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 1, 3);
+ assertTrue("Incorrect string returned: " + s, s.equals("BCD"));
+ s = new String(new byte[] { 65, 66, 67, 68, 69 }, 1, 0, 5);
+ assertTrue("Did not use nonzero hibyte", !s.equals("ABCDE"));
+ }
+
+ /**
+ * java.lang.String#String(byte[], int, int, java.lang.String)
+ */
+ public void test_Constructor$BIILjava_lang_String() throws Exception {
+ // Test for method java.lang.String(byte [], int, int, java.lang.String)
+ String s = null;
+ s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, "8859_1");
+ assertTrue("Incorrect string returned: " + s, s.equals("ABCDE"));
+ // Regression for HARMONY-1111
+ assertNotNull(new String(new byte[] { (byte) 0xC0 }, 0, 1, "UTF-8"));
+ }
+
+ /**
+ * java.lang.String#String(byte[], java.lang.String)
+ */
+ public void test_Constructor$BLjava_lang_String() throws Exception {
+ // Test for method java.lang.String(byte [], java.lang.String)
+ String s = null;
+ s = new String(new byte[] { 65, 66, 67, 68, 69 }, "8859_1");
+ assertTrue("Incorrect string returned: " + s, s.equals("ABCDE"));
+ }
+
+ /**
+ * java.lang.String#String(char[])
+ */
+ public void test_Constructor$C() {
+ // Test for method java.lang.String(char [])
+ assertEquals("Failed Constructor test", "World", new String(buf));
+ }
+
+ /**
+ * java.lang.String#String(char[], int, int)
+ */
+ public void test_Constructor$CII() {
+ // Test for method java.lang.String(char [], int, int)
+ char[] buf = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+ String s = new String(buf, 0, buf.length);
+ assertTrue("Incorrect string created", hw1.equals(s));
+
+ boolean exception = false;
+ try {
+ new String(new char[0], 0, Integer.MAX_VALUE);
+ } catch (IndexOutOfBoundsException e) {
+ exception = true;
+ }
+ assertTrue("Did not throw exception", exception);
+ }
+
+ /**
+ * java.lang.String#String(int[], int, int)
+ */
+ public void test_Constructor$III() {
+ // Test for method java.lang.String(int [], int, int)
+ try {
+ new String(new int[0], 2, Integer.MAX_VALUE);
+ fail("Did not throw exception");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.String#String(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.lang.String(java.lang.String)
+ String s = new String("Hello World");
+ assertEquals("Failed to construct correct string", "Hello World", s);
+ }
+
+ /**
+ * java.lang.String#String(java.lang.StringBuffer)
+ */
+ public void test_ConstructorLjava_lang_StringBuffer() {
+ // Test for method java.lang.String(java.lang.StringBuffer)
+ StringBuffer sb = new StringBuffer();
+ sb.append("HelloWorld");
+ assertEquals("Created incorrect string", "HelloWorld", new String(sb));
+ }
+
+ /**
+ * java.lang.String#charAt(int)
+ */
+ public void test_charAtI() {
+ // Test for method char java.lang.String.charAt(int)
+ assertTrue("Incorrect character returned", hw1.charAt(5) == 'W'
+ && (hw1.charAt(1) != 'Z'));
+ }
+
+ /**
+ * java.lang.String#compareTo(java.lang.String)
+ */
+ public void test_compareToLjava_lang_String() {
+ // Test for method int java.lang.String.compareTo(java.lang.String)
+ assertTrue("Returned incorrect value for first < second", "aaaaab"
+ .compareTo("aaaaac") < 0);
+ assertEquals("Returned incorrect value for first = second", 0, "aaaaac"
+ .compareTo("aaaaac"));
+ assertTrue("Returned incorrect value for first > second", "aaaaac"
+ .compareTo("aaaaab") > 0);
+ assertTrue("Considered case to not be of importance", !("A"
+ .compareTo("a") == 0));
+
+ try {
+ "fixture".compareTo(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.String#compareToIgnoreCase(java.lang.String)
+ */
+ public void test_compareToIgnoreCaseLjava_lang_String() {
+ // Test for method int
+ // java.lang.String.compareToIgnoreCase(java.lang.String)
+ assertTrue("Returned incorrect value for first < second", "aaaaab"
+ .compareToIgnoreCase("aaaaac") < 0);
+ assertEquals("Returned incorrect value for first = second", 0, "aaaaac"
+ .compareToIgnoreCase("aaaaac"));
+ assertTrue("Returned incorrect value for first > second", "aaaaac"
+ .compareToIgnoreCase("aaaaab") > 0);
+ assertEquals("Considered case to not be of importance", 0, "A"
+ .compareToIgnoreCase("a"));
+
+ assertTrue("0xbf should not compare = to 'ss'", "\u00df"
+ .compareToIgnoreCase("ss") != 0);
+ assertEquals("0x130 should compare = to 'i'", 0, "\u0130"
+ .compareToIgnoreCase("i"));
+ assertEquals("0x131 should compare = to 'i'", 0, "\u0131"
+ .compareToIgnoreCase("i"));
+
+ Locale defLocale = Locale.getDefault();
+ try {
+ Locale.setDefault(new Locale("tr", ""));
+ assertEquals("Locale tr: 0x130 should compare = to 'i'", 0,
+ "\u0130".compareToIgnoreCase("i"));
+ assertEquals("Locale tr: 0x131 should compare = to 'i'", 0,
+ "\u0131".compareToIgnoreCase("i"));
+ } finally {
+ Locale.setDefault(defLocale);
+ }
+
+ try {
+ "fixture".compareToIgnoreCase(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.String#concat(java.lang.String)
+ */
+ public void test_concatLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.lang.String.concat(java.lang.String)
+ assertTrue("Concatenation failed to produce correct string", hello1
+ .concat(world1).equals(hw1));
+ boolean exception = false;
+ try {
+ String a = new String("test");
+ String b = null;
+ a.concat(b);
+ } catch (NullPointerException e) {
+ exception = true;
+ }
+ assertTrue("Concatenation failed to throw NP exception (1)", exception);
+ exception = false;
+ try {
+ String a = new String("");
+ String b = null;
+ a.concat(b);
+ } catch (NullPointerException e) {
+ exception = true;
+ }
+ assertTrue("Concatenation failed to throw NP exception (2)", exception);
+
+ String s1 = "";
+ String s2 = "s2";
+ String s3 = s1.concat(s2);
+ assertEquals(s2, s3);
+ // The RI returns a new string even when it's the same as the argument string.
+ // assertNotSame(s2, s3);
+ s3 = s2.concat(s1);
+ assertEquals(s2, s3);
+ // Neither Android nor the RI returns a new string when it's the same as *this*.
+ // assertNotSame(s2, s3);
+
+ s3 = s2.concat(s1);
+ assertSame(s2, s3);
+ }
+
+ /**
+ * java.lang.String#copyValueOf(char[])
+ */
+ public void test_copyValueOf$C() {
+ // Test for method java.lang.String java.lang.String.copyValueOf(char
+ // [])
+ char[] t = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+ assertEquals("copyValueOf returned incorrect String", "HelloWorld",
+ String.copyValueOf(t));
+ }
+
+ /**
+ * java.lang.String#copyValueOf(char[], int, int)
+ */
+ public void test_copyValueOf$CII() {
+ // Test for method java.lang.String java.lang.String.copyValueOf(char
+ // [], int, int)
+ char[] t = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+ assertEquals("copyValueOf returned incorrect String", "World", String
+ .copyValueOf(t, 5, 5));
+ }
+
+ /**
+ * java.lang.String#endsWith(java.lang.String)
+ */
+ public void test_endsWithLjava_lang_String() {
+ // Test for method boolean java.lang.String.endsWith(java.lang.String)
+ assertTrue("Failed to fine ending string", hw1.endsWith("ld"));
+ }
+
+ /**
+ * java.lang.String#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertEquals("String not equal", hw1, hw2);
+ assertEquals("Empty string equals check", "", "");
+ assertEquals("Null string equals check", (String) null, (String) null);
+
+ assertFalse("Unequal strings reports as equal", hw1.equals(comp11));
+ assertFalse("Null string comparison failed", hw1.equals((String) null));
+ }
+
+ /**
+ * java.lang.String#equalsIgnoreCase(java.lang.String)
+ */
+ public void test_equalsIgnoreCaseLjava_lang_String() {
+ // Test for method boolean
+ // java.lang.String.equalsIgnoreCase(java.lang.String)
+ assertTrue("lc version returned unequal to uc", hwlc
+ .equalsIgnoreCase(hwuc));
+ }
+
+ /**
+ * java.lang.String#getBytes()
+ */
+ public void test_getBytes() {
+ // Test for method byte [] java.lang.String.getBytes()
+ byte[] sbytes = hw1.getBytes();
+
+ for (int i = 0; i < hw1.length(); i++) {
+ assertTrue("Returned incorrect bytes", sbytes[i] == (byte) hw1.charAt(i));
+ }
+
+ char[] chars = new char[1];
+ for (int i = 0; i < 65536; i++) {
+ // skip surrogates
+ if (i == 0xd800)
+ i = 0xe000;
+ byte[] result = null;
+ chars[0] = (char) i;
+ String string = new String(chars);
+ try {
+ result = string.getBytes("8859_1");
+ if (i < 256) {
+ assertEquals((byte) i, result[0]);
+ } else {
+ /*
+ * Substitute character should be 0x1A [1], but may be '?'
+ * character. [1]
+ * http://en.wikipedia.org/wiki/Substitute_character
+ */
+ assertTrue(result[0] == '?' || result[0] == 0x1a);
+ }
+ } catch (java.io.UnsupportedEncodingException e) {
+ }
+ try {
+ result = string.getBytes("UTF8");
+ int length = i < 0x80 ? 1 : (i < 0x800 ? 2 : 3);
+ assertTrue("Wrong length UTF8: " + Integer.toHexString(i),
+ result.length == length);
+ assertTrue(
+ "Wrong bytes UTF8: " + Integer.toHexString(i),
+ (i < 0x80 && result[0] == i)
+ || (i >= 0x80
+ && i < 0x800
+ && result[0] == (byte) (0xc0 | ((i & 0x7c0) >> 6)) && result[1] == (byte) (0x80 | (i & 0x3f)))
+ || (i >= 0x800
+ && result[0] == (byte) (0xe0 | (i >> 12))
+ && result[1] == (byte) (0x80 | ((i & 0xfc0) >> 6)) && result[2] == (byte) (0x80 | (i & 0x3f))));
+ } catch (java.io.UnsupportedEncodingException e) {
+ }
+
+ String bytes = null;
+ try {
+ bytes = new String(result, "UTF8");
+ assertTrue("Wrong UTF8 byte length: " + bytes.length() + "("
+ + i + ")", bytes.length() == 1);
+ assertTrue(
+ "Wrong char UTF8: "
+ + Integer.toHexString(bytes.charAt(0)) + " ("
+ + i + ")", bytes.charAt(0) == i);
+ } catch (java.io.UnsupportedEncodingException e) {
+ }
+ }
+
+ byte[] bytes = new byte[1];
+ for (int i = 0; i < 256; i++) {
+ bytes[0] = (byte) i;
+ String result = null;
+ try {
+ result = new String(bytes, "8859_1");
+ assertEquals("Wrong char length", 1, result.length());
+ assertTrue("Wrong char value", result.charAt(0) == (char) i);
+ } catch (java.io.UnsupportedEncodingException e) {
+ }
+ }
+ }
+
+ /**
+ * java.lang.String#getBytes(int, int, byte[], int)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_getBytesII$BI() {
+ // Test for method void java.lang.String.getBytes(int, int, byte [],
+ // int)
+ byte[] buf = new byte[5];
+ "Hello World".getBytes(6, 11, buf, 0);
+ assertEquals("Returned incorrect bytes", "World", new String(buf));
+
+ try {
+ "Hello World".getBytes(-1, 1, null, 0);
+ fail("Expected StringIndexOutOfBoundsException");
+ } catch (StringIndexOutOfBoundsException e) {
+ } catch (NullPointerException e) {
+ fail("Threw wrong exception");
+ }
+ }
+
+ /**
+ * java.lang.String#getBytes(java.lang.String)
+ */
+ public void test_getBytesLjava_lang_String() throws Exception {
+ // Test for method byte [] java.lang.String.getBytes(java.lang.String)
+ byte[] buf = "Hello World".getBytes();
+ assertEquals("Returned incorrect bytes", "Hello World", new String(buf));
+
+ try {
+ "string".getBytes("8849_1");
+ fail("No UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e) {
+ }
+
+ byte[] bytes = "\u3048".getBytes("UTF-8");
+ byte[] expected = new byte[] { (byte) 0xE3, (byte) 0x81, (byte) 0x88 };
+ assertEquals(expected[0], bytes[0]);
+ assertEquals(expected[1], bytes[1]);
+ assertEquals(expected[2], bytes[2]);
+
+ // Regression for HARMONY-663
+ try {
+ "string".getBytes("?Q?D??_??_6ffa?+vG?_??\u951f\ufffd??");
+ fail("No UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e) {
+ // expected
+ }
+
+ bytes = "-".getBytes("UTF-16");
+ expected = new byte[] { (byte) 0xff, (byte) 0xfe };
+ assertEquals(expected[0], bytes[0]);
+ assertEquals(expected[1], bytes[1]);
+
+ byte[] bytes2 = "-".getBytes("UTF-16LE");
+ assertEquals(bytes2[0], bytes[2]);
+ assertEquals(bytes2[1], bytes[3]);
+ }
+
+ /*
+ * java.lang.String#getBytes()
+ */
+ public void test_getBytes_NPE() throws Exception {
+ try {
+ "abc".getBytes((String) null);
+ fail("Should throw NullPointerException");
+ } catch (UnsupportedEncodingException whatTheRiDocumentsAndWeThrow) {
+ } catch (NullPointerException whatTheRiActuallyThrows) {
+ }
+
+ try {
+ "Hello World".getBytes(1, 2, null, 1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.String#getChars(int, int, char[], int)
+ */
+ public void test_getCharsII$CI() {
+ // Test for method void java.lang.String.getChars(int, int, char [],
+ // int)
+ hw1.getChars(5, hw1.length(), rbuf, 0);
+
+ for (int i = 0; i < rbuf.length; i++)
+ assertTrue("getChars returned incorrect char(s)", rbuf[i] == buf[i]);
+ }
+
+ /**
+ * java.lang.String#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.lang.String.hashCode()
+ int hwHashCode = 0;
+ final int hwLength = hw1.length();
+ int powerOfThirtyOne = 1;
+ for (int counter = hwLength - 1; counter >= 0; counter--) {
+ hwHashCode += hw1.charAt(counter) * powerOfThirtyOne;
+ powerOfThirtyOne *= 31;
+ }
+ assertEquals("String did not hash to correct value", hwHashCode, hw1.hashCode());
+ assertEquals("The empty string \"\" did not hash to zero", 0, "".hashCode());
+ assertEquals("Calculated wrong string hashcode", -1933545242, "Harmony".hashCode());
+ }
+
+ /**
+ * java.lang.String#indexOf(int)
+ */
+ public void test_indexOfI() {
+ // Test for method int java.lang.String.indexOf(int)
+ assertEquals("Invalid index returned", 1, hw1.indexOf('e'));
+ assertEquals("Invalid index returned", 1, "a\ud800\udc00".indexOf(0x10000));
+ }
+
+ /**
+ * java.lang.String#indexOf(int, int)
+ */
+ public void test_indexOfII() {
+ // Test for method int java.lang.String.indexOf(int, int)
+ assertEquals("Invalid character index returned", 5, hw1.indexOf('W', 2));
+ assertEquals("Invalid index returned", 2, "ab\ud800\udc00".indexOf(0x10000, 1));
+ }
+
+ /**
+ * java.lang.String#indexOf(java.lang.String)
+ */
+ public void test_indexOfLjava_lang_String() {
+ // Test for method int java.lang.String.indexOf(java.lang.String)
+ assertTrue("Failed to find string", hw1.indexOf("World") > 0);
+ assertTrue("Failed to find string", !(hw1.indexOf("ZZ") > 0));
+ }
+
+ /**
+ * java.lang.String#indexOf(java.lang.String, int)
+ */
+ public void test_indexOfLjava_lang_StringI() {
+ // Test for method int java.lang.String.indexOf(java.lang.String, int)
+ assertTrue("Failed to find string", hw1.indexOf("World", 0) > 0);
+ assertTrue("Found string outside index", !(hw1.indexOf("Hello", 6) > 0));
+ assertEquals("Did not accept valid negative starting position", 0,
+ hello1.indexOf("", -5));
+ assertEquals("Reported wrong error code", 5, hello1.indexOf("", 5));
+ assertEquals("Wrong for empty in empty", 0, "".indexOf("", 0));
+ }
+
+ /**
+ * java.lang.String#intern()
+ */
+ public void test_intern() {
+ // Test for method java.lang.String java.lang.String.intern()
+ assertTrue("Intern returned incorrect result", hw1.intern() == hw2
+ .intern());
+ }
+
+ /**
+ * java.lang.String#lastIndexOf(int)
+ */
+ public void test_lastIndexOfI() {
+ // Test for method int java.lang.String.lastIndexOf(int)
+ assertEquals("Failed to return correct index", 5, hw1.lastIndexOf('W'));
+ assertEquals("Returned index for non-existent char", -1, hw1
+ .lastIndexOf('Z'));
+ assertEquals("Failed to return correct index", 1, "a\ud800\udc00"
+ .lastIndexOf(0x10000));
+ }
+
+ /**
+ * java.lang.String#lastIndexOf(int, int)
+ */
+ public void test_lastIndexOfII() {
+ // Test for method int java.lang.String.lastIndexOf(int, int)
+ assertEquals("Failed to return correct index", 5, hw1.lastIndexOf('W',
+ 6));
+ assertEquals("Returned index for char out of specified range", -1, hw1
+ .lastIndexOf('W', 4));
+ assertEquals("Returned index for non-existent char", -1, hw1
+ .lastIndexOf('Z', 9));
+
+ }
+
+ /**
+ * java.lang.String#lastIndexOf(java.lang.String)
+ */
+ public void test_lastIndexOfLjava_lang_String() {
+ // Test for method int java.lang.String.lastIndexOf(java.lang.String)
+ assertEquals("Returned incorrect index", 5, hw1.lastIndexOf("World"));
+ assertEquals("Found String outside of index", -1, hw1
+ .lastIndexOf("HeKKKKKKKK"));
+ }
+
+ /**
+ * java.lang.String#lastIndexOf(java.lang.String, int)
+ */
+ public void test_lastIndexOfLjava_lang_StringI() {
+ // Test for method int java.lang.String.lastIndexOf(java.lang.String,
+ // int)
+ assertEquals("Returned incorrect index", 5, hw1.lastIndexOf("World", 9));
+ int result = hw1.lastIndexOf("Hello", 2);
+ assertTrue("Found String outside of index: " + result, result == 0);
+ assertEquals("Reported wrong error code", -1, hello1
+ .lastIndexOf("", -5));
+ assertEquals("Did not accept valid large starting position", 5, hello1
+ .lastIndexOf("", 5));
+ }
+
+ /**
+ * java.lang.String#length()
+ */
+ public void test_length() {
+ // Test for method int java.lang.String.length()
+ assertEquals("Invalid length returned", 11, comp11.length());
+ }
+
+ /**
+ * java.lang.String#regionMatches(int, java.lang.String, int, int)
+ */
+ public void test_regionMatchesILjava_lang_StringII() {
+ // Test for method boolean java.lang.String.regionMatches(int,
+ // java.lang.String, int, int)
+ String bogusString = "xxcedkedkleiorem lvvwr e''' 3r3r 23r";
+
+ assertTrue("identical regions failed comparison", hw1.regionMatches(2,
+ hw2, 2, 5));
+ assertTrue("Different regions returned true", !hw1.regionMatches(2,
+ bogusString, 2, 5));
+ }
+
+ /**
+ * java.lang.String#regionMatches(boolean, int, java.lang.String,
+ *int, int)
+ */
+ public void test_regionMatchesZILjava_lang_StringII() {
+ // Test for method boolean java.lang.String.regionMatches(boolean, int,
+ // java.lang.String, int, int)
+
+ String bogusString = "xxcedkedkleiorem lvvwr e''' 3r3r 23r";
+
+ assertTrue("identical regions failed comparison", hw1.regionMatches(
+ false, 2, hw2, 2, 5));
+ assertTrue("identical regions failed comparison with different cases",
+ hw1.regionMatches(true, 2, hw2, 2, 5));
+ assertTrue("Different regions returned true", !hw1.regionMatches(true,
+ 2, bogusString, 2, 5));
+ assertTrue("identical regions failed comparison with different cases",
+ hw1.regionMatches(false, 2, hw2, 2, 5));
+ }
+
+ /**
+ * java.lang.String#replace(char, char)
+ */
+ public void test_replaceCC() {
+ // Test for method java.lang.String java.lang.String.replace(char, char)
+ assertEquals("Failed replace", "HezzoWorzd", hw1.replace('l', 'z'));
+ }
+
+ /**
+ * java.lang.String#replace(CharSequence, CharSequence)
+ */
+ public void test_replaceLjava_langCharSequenceLjava_langCharSequence() {
+ assertEquals("Failed replace", "aaccdd", "aabbdd".replace(
+ new StringBuffer("bb"), "cc"));
+ assertEquals("Failed replace by bigger seq", "cccbccc", "aba".replace(
+ "a", "ccc"));
+ assertEquals("Failed replace by smaller seq", "$bba^", "$aaaaa^"
+ .replace(new StringBuilder("aa"), "b"));
+ assertEquals("Failed to replace empty string", "%%a%%b%%c%%",
+ "abc".replace("", "%%"));
+ assertEquals("Failed to replace with empty string", "aacc",
+ "aabbcc".replace("b", ""));
+ assertEquals("Failed to replace in empty string", "abc",
+ "".replace("", "abc"));
+ }
+
+ /**
+ * java.lang.String#startsWith(java.lang.String)
+ */
+ public void test_startsWithLjava_lang_String() {
+ // Test for method boolean java.lang.String.startsWith(java.lang.String)
+ assertTrue("Failed to find string", hw1.startsWith("Hello"));
+ assertTrue("Found incorrect string", !hw1.startsWith("T"));
+ }
+
+ /**
+ * java.lang.String#startsWith(java.lang.String, int)
+ */
+ public void test_startsWithLjava_lang_StringI() {
+ // Test for method boolean java.lang.String.startsWith(java.lang.String,
+ // int)
+ assertTrue("Failed to find string", hw1.startsWith("World", 5));
+ assertTrue("Found incorrect string", !hw1.startsWith("Hello", 5));
+ }
+
+ /**
+ * java.lang.String#substring(int)
+ */
+ public void test_substringI() {
+ // Test for method java.lang.String java.lang.String.substring(int)
+ assertEquals("Incorrect substring returned", "World", hw1.substring(5));
+ assertTrue("not identical", hw1.substring(0) == hw1);
+ }
+
+ /**
+ * java.lang.String#substring(int, int)
+ */
+ public void test_substringII() {
+ // Test for method java.lang.String java.lang.String.substring(int, int)
+ assertTrue("Incorrect substring returned", hw1.substring(0, 5).equals(
+ "Hello")
+ && (hw1.substring(5, 10).equals("World")));
+ assertTrue("not identical", hw1.substring(0, hw1.length()) == hw1);
+ }
+
+ /**
+ * java.lang.String#substring(int, int)
+ */
+ public void test_substringErrorMessage() {
+ try {
+ hw1.substring(-1, 1);
+ } catch (StringIndexOutOfBoundsException ex) {
+ String msg = ex.getMessage();
+ assertTrue("Expected message to contain -1: " + msg, msg
+ .indexOf("-1") != -1);
+ }
+ try {
+ hw1.substring(4, 1);
+ } catch (StringIndexOutOfBoundsException ex) {
+ String msg = ex.getMessage();
+ assertTrue("Expected message to contain -3: " + msg, msg
+ .indexOf("-3") != -1);
+ }
+ try {
+ hw1.substring(0, 100);
+ } catch (StringIndexOutOfBoundsException ex) {
+ String msg = ex.getMessage();
+ assertTrue("Expected message to contain 100: " + msg, msg
+ .indexOf("100") != -1);
+ }
+ }
+
+ /**
+ * java.lang.String#toCharArray()
+ */
+ public void test_toCharArray() {
+ // Test for method char [] java.lang.String.toCharArray()
+
+ String s = new String(buf, 0, buf.length);
+ char[] schars = s.toCharArray();
+ for (int i = 0; i < s.length(); i++)
+ assertTrue("Returned incorrect char aray", buf[i] == schars[i]);
+ }
+
+ /**
+ * java.lang.String#toLowerCase()
+ */
+ public void test_toLowerCase() {
+ // Test for method java.lang.String java.lang.String.toLowerCase()
+ assertTrue("toLowerCase case conversion did not succeed", hwuc
+ .toLowerCase().equals(hwlc));
+
+ assertEquals(
+ "a) Sigma has ordinary lower case value when isolated with Unicode 4.0",
+ "\u03c3", "\u03a3".toLowerCase());
+ assertEquals(
+ "b) Sigma has final form lower case value at end of word with Unicode 4.0",
+ "a\u03c2", "a\u03a3".toLowerCase());
+
+ assertEquals("toLowerCase case conversion did not succeed",
+ "\uD801\uDC44", "\uD801\uDC1C".toLowerCase());
+ }
+
+ /**
+ * java.lang.String#toLowerCase(java.util.Locale)
+ */
+ public void test_toLowerCaseLjava_util_Locale() {
+ // Test for method java.lang.String
+ // java.lang.String.toLowerCase(java.util.Locale)
+ assertTrue("toLowerCase case conversion did not succeed", hwuc
+ .toLowerCase(java.util.Locale.getDefault()).equals(hwlc));
+ assertEquals("Invalid \\u0049 for English", "\u0069", "\u0049"
+ .toLowerCase(Locale.ENGLISH));
+ assertEquals("Invalid \\u0049 for Turkish", "\u0131", "\u0049"
+ .toLowerCase(new Locale("tr", "")));
+ }
+
+ /**
+ * java.lang.String#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.lang.String.toString()
+ assertTrue("Incorrect string returned", hw1.toString().equals(hw1));
+ }
+
+ /**
+ * java.lang.String#toUpperCase()
+ */
+ public void test_toUpperCase() {
+ // Test for method java.lang.String java.lang.String.toUpperCase()
+ assertTrue("Returned string is not UpperCase", hwlc.toUpperCase()
+ .equals(hwuc));
+
+ assertEquals("Wrong conversion", "SS", "\u00df".toUpperCase());
+
+ String s = "a\u00df\u1f56";
+ assertTrue("Invalid conversion", !s.toUpperCase().equals(s));
+
+ assertEquals("toUpperCase case conversion did not succeed",
+ "\uD801\uDC1C", "\uD801\uDC44".toUpperCase());
+ }
+
+ /**
+ * java.lang.String#toUpperCase(java.util.Locale)
+ */
+ public void test_toUpperCaseLjava_util_Locale() {
+ // Test for method java.lang.String
+ // java.lang.String.toUpperCase(java.util.Locale)
+ assertTrue("Returned string is not UpperCase", hwlc.toUpperCase()
+ .equals(hwuc));
+ assertEquals("Invalid \\u0069 for English", "\u0049", "\u0069"
+ .toUpperCase(Locale.ENGLISH));
+ assertEquals("Invalid \\u0069 for Turkish", "\u0130", "\u0069"
+ .toUpperCase(new Locale("tr", "")));
+ }
+
+ /**
+ * java.lang.String#toUpperCase(java.util.Locale)
+ */
+ public void test_toUpperCaseLjava_util_Locale_subtest0() {
+ // Test for method java.lang.String
+ // java.lang.String.toUpperCase(java.util.Locale)
+ }
+
+ /**
+ * java.lang.String#trim()
+ */
+ public void test_trim() {
+ // Test for method java.lang.String java.lang.String.trim()
+ assertTrue("Incorrect string returned", " HelloWorld ".trim().equals(
+ hw1));
+ }
+
+ /**
+ * java.lang.String#valueOf(char[])
+ */
+ public void test_valueOf$C() {
+ // Test for method java.lang.String java.lang.String.valueOf(char [])
+ assertEquals("Returned incorrect String", "World", String.valueOf(buf));
+ }
+
+ /**
+ * java.lang.String#valueOf(char[], int, int)
+ */
+ public void test_valueOf$CII() {
+ // Test for method java.lang.String java.lang.String.valueOf(char [],
+ // int, int)
+ char[] t = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+ assertEquals("copyValueOf returned incorrect String", "World", String
+ .valueOf(t, 5, 5));
+ }
+
+ /**
+ * java.lang.String#valueOf(char)
+ */
+ public void test_valueOfC() {
+ // Test for method java.lang.String java.lang.String.valueOf(char)
+ for (int i = 0; i < 65536; i++)
+ assertTrue("Incorrect valueOf(char) returned: " + i, String
+ .valueOf((char) i).charAt(0) == (char) i);
+ }
+
+ /**
+ * java.lang.String#valueOf(double)
+ */
+ public void test_valueOfD() {
+ // Test for method java.lang.String java.lang.String.valueOf(double)
+ assertEquals("Incorrect double string returned",
+ "1.7976931348623157E308", String.valueOf(Double.MAX_VALUE));
+ }
+
+ /**
+ * java.lang.String#valueOf(float)
+ */
+ public void test_valueOfF() {
+ // Test for method java.lang.String java.lang.String.valueOf(float)
+ assertTrue("incorrect float string returned--got: "
+ + String.valueOf(1.0F) + " wanted: 1.0", String.valueOf(1.0F)
+ .equals("1.0"));
+ assertTrue("incorrect float string returned--got: "
+ + String.valueOf(0.9F) + " wanted: 0.9", String.valueOf(0.9F)
+ .equals("0.9"));
+ assertTrue("incorrect float string returned--got: "
+ + String.valueOf(109.567F) + " wanted: 109.567", String
+ .valueOf(109.567F).equals("109.567"));
+ }
+
+ /**
+ * java.lang.String#valueOf(int)
+ */
+ public void test_valueOfI() {
+ // Test for method java.lang.String java.lang.String.valueOf(int)
+ assertEquals("returned invalid int string", "1", String.valueOf(1));
+ }
+
+ /**
+ * java.lang.String#valueOf(long)
+ */
+ public void test_valueOfJ() {
+ // Test for method java.lang.String java.lang.String.valueOf(long)
+ assertEquals("returned incorrect long string", "927654321098", String
+ .valueOf(927654321098L));
+ }
+
+ /**
+ * java.lang.String#valueOf(java.lang.Object)
+ */
+ public void test_valueOfLjava_lang_Object() {
+ // Test for method java.lang.String
+ // java.lang.String.valueOf(java.lang.Object)
+ assertTrue("Incorrect Object string returned", obj.toString().equals(
+ String.valueOf(obj)));
+ }
+
+ /**
+ * java.lang.String#valueOf(boolean)
+ */
+ public void test_valueOfZ() {
+ // Test for method java.lang.String java.lang.String.valueOf(boolean)
+ assertTrue("Incorrect boolean string returned", String.valueOf(false)
+ .equals("false")
+ && (String.valueOf(true).equals("true")));
+ }
+
+ /**
+ * java.lang.String#contentEquals(CharSequence cs)
+ */
+ public void test_contentEqualsLjava_lang_CharSequence() {
+ // Test for method java.lang.String
+ // java.lang.String.contentEquals(CharSequence cs)
+ assertFalse("Incorrect result of compare", "qwerty".contentEquals(""));
+ }
+
+ /**
+ * java.lang.String#format(Locale, String, Object[])
+ */
+ @SuppressWarnings("boxing")
+ public void test_format() {
+ assertEquals("13% of sum is 0x11", String.format("%d%% of %s is 0x%x",
+ 13, "sum", 17));
+ assertEquals("empty format", "", String.format("", 123, this));
+ try {
+ String.format(null);
+ fail("NPE is expected on null format");
+ } catch (NullPointerException ok) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBuffer2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBuffer2Test.java
new file mode 100644
index 0000000..7e8144b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBuffer2Test.java
@@ -0,0 +1,610 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+public class StringBuffer2Test extends junit.framework.TestCase {
+
+ StringBuffer testBuffer;
+
+ /**
+ * java.lang.StringBuffer#StringBuffer()
+ */
+ public void test_Constructor() {
+ // Test for method java.lang.StringBuffer()
+ new StringBuffer();
+ assertTrue("Invalid buffer created", true);
+ }
+
+ /**
+ * java.lang.StringBuffer#StringBuffer(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.lang.StringBuffer(int)
+ StringBuffer sb = new StringBuffer(8);
+ assertEquals("Newly constructed buffer is of incorrect length", 0, sb
+ .length());
+ }
+
+ /**
+ * java.lang.StringBuffer#StringBuffer(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.lang.StringBuffer(java.lang.String)
+
+ StringBuffer sb = new StringBuffer("HelloWorld");
+
+ assertTrue("Invalid buffer created", sb.length() == 10
+ && (sb.toString().equals("HelloWorld")));
+
+ boolean pass = false;
+ try {
+ new StringBuffer(null);
+ } catch (NullPointerException e) {
+ pass = true;
+ }
+ assertTrue("Should throw NullPointerException", pass);
+ }
+
+ /**
+ * java.lang.StringBuffer#append(char[])
+ */
+ public void test_append$C() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(char [])
+ char buf[] = new char[4];
+ "char".getChars(0, 4, buf, 0);
+ testBuffer.append(buf);
+ assertEquals("Append of char[] failed",
+ "This is a test bufferchar", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#append(char[], int, int)
+ */
+ public void test_append$CII() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(char [], int, int)
+ StringBuffer sb = new StringBuffer();
+ char[] buf1 = { 'H', 'e', 'l', 'l', 'o' };
+ char[] buf2 = { 'W', 'o', 'r', 'l', 'd' };
+ sb.append(buf1, 0, buf1.length);
+ assertEquals("Buffer is invalid length after append", 5, sb.length());
+ sb.append(buf2, 0, buf2.length);
+ assertEquals("Buffer is invalid length after append", 10, sb.length());
+ assertTrue("Buffer contains invalid chars", (sb.toString()
+ .equals("HelloWorld")));
+ }
+
+ /**
+ * java.lang.StringBuffer#append(char)
+ */
+ public void test_appendC() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(char)
+ StringBuffer sb = new StringBuffer();
+ char buf1 = 'H';
+ char buf2 = 'W';
+ sb.append(buf1);
+ assertEquals("Buffer is invalid length after append", 1, sb.length());
+ sb.append(buf2);
+ assertEquals("Buffer is invalid length after append", 2, sb.length());
+ assertTrue("Buffer contains invalid chars",
+ (sb.toString().equals("HW")));
+ }
+
+ /**
+ * java.lang.StringBuffer#append(double)
+ */
+ public void test_appendD() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(double)
+ StringBuffer sb = new StringBuffer();
+ sb.append(Double.MAX_VALUE);
+ assertEquals("Buffer is invalid length after append", 22, sb.length());
+ assertEquals("Buffer contains invalid characters",
+ "1.7976931348623157E308", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#append(float)
+ */
+ public void test_appendF() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(float)
+ StringBuffer sb = new StringBuffer();
+ final float floatNum = 900.87654F;
+ sb.append(floatNum);
+ assertTrue("Buffer is invalid length after append: " + sb.length(), sb
+ .length() == String.valueOf(floatNum).length());
+ assertTrue("Buffer contains invalid characters", sb.toString().equals(
+ String.valueOf(floatNum)));
+ }
+
+ /**
+ * java.lang.StringBuffer#append(int)
+ */
+ public void test_appendI() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(int)
+ StringBuffer sb = new StringBuffer();
+ sb.append(9000);
+ assertEquals("Buffer is invalid length after append", 4, sb.length());
+ sb.append(1000);
+ assertEquals("Buffer is invalid length after append", 8, sb.length());
+ assertEquals("Buffer contains invalid characters",
+ "90001000", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#append(long)
+ */
+ public void test_appendJ() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(long)
+
+ StringBuffer sb = new StringBuffer();
+ long t = 927654321098L;
+ sb.append(t);
+ assertEquals("Buffer is of invlaid length", 12, sb.length());
+ assertEquals("Buffer contains invalid characters",
+ "927654321098", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#append(java.lang.Object)
+ */
+ public void test_appendLjava_lang_Object() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(java.lang.Object)
+ StringBuffer sb = new StringBuffer();
+ Object obj1 = new Object();
+ Object obj2 = new Object();
+ sb.append(obj1);
+ sb.append(obj2);
+ assertTrue("Buffer contains invalid characters", sb.toString().equals(
+ obj1.toString() + obj2.toString()));
+ }
+
+ /**
+ * java.lang.StringBuffer#append(java.lang.String)
+ */
+ public void test_appendLjava_lang_String() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(java.lang.String)
+ StringBuffer sb = new StringBuffer();
+ String buf1 = "Hello";
+ String buf2 = "World";
+ sb.append(buf1);
+ assertEquals("Buffer is invalid length after append", 5, sb.length());
+ sb.append(buf2);
+ assertEquals("Buffer is invalid length after append", 10, sb.length());
+ assertTrue("Buffer contains invalid chars", (sb.toString()
+ .equals("HelloWorld")));
+ }
+
+ /**
+ * java.lang.StringBuffer#append(boolean)
+ */
+ public void test_appendZ() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.append(boolean)
+ StringBuffer sb = new StringBuffer();
+ sb.append(false);
+ assertEquals("Buffer is invalid length after append", 5, sb.length());
+ sb.append(true);
+ assertEquals("Buffer is invalid length after append", 9, sb.length());
+ assertTrue("Buffer is invalid length after append", (sb.toString()
+ .equals("falsetrue")));
+ }
+
+ /**
+ * java.lang.StringBuffer#capacity()
+ */
+ public void test_capacity() {
+ // Test for method int java.lang.StringBuffer.capacity()
+ StringBuffer sb = new StringBuffer(10);
+ assertEquals("Returned incorrect capacity", 10, sb.capacity());
+ sb.ensureCapacity(100);
+ assertTrue("Returned incorrect capacity", sb.capacity() >= 100);
+ }
+
+ /**
+ * java.lang.StringBuffer#charAt(int)
+ */
+ public void test_charAtI() {
+ // Test for method char java.lang.StringBuffer.charAt(int)
+ assertEquals("Returned incorrect char", 's', testBuffer.charAt(3));
+
+ // Test for StringIndexOutOfBoundsException
+ boolean exception = false;
+ try {
+ testBuffer.charAt(-1);
+ } catch (StringIndexOutOfBoundsException e) {
+ exception = true;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ assertTrue("Should throw StringIndexOutOfBoundsException", exception);
+ }
+
+ /**
+ * java.lang.StringBuffer#delete(int, int)
+ */
+ public void test_deleteII() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.delete(int, int)
+ testBuffer.delete(7, 7);
+ assertEquals("Deleted chars when start == end", "This is a test buffer", testBuffer.toString()
+ );
+ testBuffer.delete(4, 14);
+ assertEquals("Deleted incorrect chars",
+ "This buffer", testBuffer.toString());
+
+ testBuffer = new StringBuffer("This is a test buffer");
+ String sharedStr = testBuffer.toString();
+ testBuffer.delete(0, testBuffer.length());
+ assertEquals("Didn't clone shared buffer", "This is a test buffer", sharedStr
+ );
+ assertTrue("Deleted incorrect chars", testBuffer.toString().equals(""));
+ testBuffer.append("more stuff");
+ assertEquals("Didn't clone shared buffer 2", "This is a test buffer", sharedStr
+ );
+ assertEquals("Wrong contents", "more stuff", testBuffer.toString());
+ try {
+ testBuffer.delete(-5, 2);
+ } catch (IndexOutOfBoundsException e) {
+ }
+ assertEquals("Wrong contents 2",
+ "more stuff", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#deleteCharAt(int)
+ */
+ public void test_deleteCharAtI() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.deleteCharAt(int)
+ testBuffer.deleteCharAt(3);
+ assertEquals("Deleted incorrect char",
+ "Thi is a test buffer", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#ensureCapacity(int)
+ */
+ public void test_ensureCapacityI() {
+ // Test for method void java.lang.StringBuffer.ensureCapacity(int)
+ StringBuffer sb = new StringBuffer(10);
+
+ sb.ensureCapacity(100);
+ assertTrue("Failed to increase capacity", sb.capacity() >= 100);
+ }
+
+ /**
+ * java.lang.StringBuffer#getChars(int, int, char[], int)
+ */
+ public void test_getCharsII$CI() {
+ // Test for method void java.lang.StringBuffer.getChars(int, int, char
+ // [], int)
+
+ char[] buf = new char[10];
+ testBuffer.getChars(4, 8, buf, 2);
+ assertTrue("Returned incorrect chars", new String(buf, 2, 4)
+ .equals(testBuffer.toString().substring(4, 8)));
+
+ boolean exception = false;
+ try {
+ StringBuffer buf2 = new StringBuffer("");
+ buf2.getChars(0, 0, new char[5], 2);
+ } catch (IndexOutOfBoundsException e) {
+ exception = true;
+ }
+ assertTrue("did not expect IndexOutOfBoundsException", !exception);
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, char[])
+ */
+ public void test_insertI$C() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, char [])
+ char buf[] = new char[4];
+ "char".getChars(0, 4, buf, 0);
+ testBuffer.insert(15, buf);
+ assertEquals("Insert test failed",
+ "This is a test charbuffer", testBuffer.toString());
+
+ boolean exception = false;
+ StringBuffer buf1 = new StringBuffer("abcd");
+ try {
+ buf1.insert(-1, (char[]) null);
+ } catch (StringIndexOutOfBoundsException e) {
+ exception = true;
+ } catch (NullPointerException e) {
+ }
+ assertTrue("Should throw StringIndexOutOfBoundsException", exception);
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, char[], int, int)
+ */
+ public void test_insertI$CII() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, char [], int, int)
+ char[] c = new char[] { 'n', 'o', 't', ' ' };
+ testBuffer.insert(8, c, 0, 4);
+ assertEquals("This is not a test buffer", testBuffer.toString());
+
+ StringBuffer buf1 = new StringBuffer("abcd");
+ try {
+ buf1.insert(-1, (char[]) null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+
+ try {
+ testBuffer.insert(testBuffer.length() - 1, c, -1, 1);
+ } catch (StringIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, char)
+ */
+ public void test_insertIC() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, char)
+ testBuffer.insert(15, 'T');
+ assertEquals("Insert test failed",
+ "This is a test Tbuffer", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, double)
+ */
+ public void test_insertID() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, double)
+ testBuffer.insert(15, Double.MAX_VALUE);
+ assertTrue("Insert test failed", testBuffer.toString().equals(
+ "This is a test " + Double.MAX_VALUE + "buffer"));
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, float)
+ */
+ public void test_insertIF() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, float)
+ testBuffer.insert(15, Float.MAX_VALUE);
+ String testBufferString = testBuffer.toString();
+ String expectedResult = "This is a test "
+ + String.valueOf(Float.MAX_VALUE) + "buffer";
+ assertTrue("Insert test failed, got: " + "\'" + testBufferString + "\'"
+ + " but wanted: " + "\'" + expectedResult + "\'",
+ testBufferString.equals(expectedResult));
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, int)
+ */
+ public void test_insertII() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, int)
+ testBuffer.insert(15, 100);
+ assertEquals("Insert test failed",
+ "This is a test 100buffer", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, long)
+ */
+ public void test_insertIJ() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, long)
+ testBuffer.insert(15, 88888888888888888L);
+ assertEquals("Insert test failed",
+ "This is a test 88888888888888888buffer", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, java.lang.Object)
+ */
+ public void test_insertILjava_lang_Object() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, java.lang.Object)
+ Object obj1 = new Object();
+ testBuffer.insert(15, obj1);
+ assertTrue("Insert test failed", testBuffer.toString().equals(
+ "This is a test " + obj1.toString() + "buffer"));
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, java.lang.String)
+ */
+ public void test_insertILjava_lang_String() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, java.lang.String)
+
+ testBuffer.insert(15, "STRING ");
+ assertEquals("Insert test failed",
+ "This is a test STRING buffer", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#insert(int, boolean)
+ */
+ public void test_insertIZ() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.insert(int, boolean)
+ testBuffer.insert(15, true);
+ assertEquals("Insert test failed",
+ "This is a test truebuffer", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#length()
+ */
+ public void test_length() {
+ // Test for method int java.lang.StringBuffer.length()
+ assertEquals("Incorrect length returned", 21, testBuffer.length());
+ }
+
+ /**
+ * java.lang.StringBuffer#replace(int, int, java.lang.String)
+ */
+ public void test_replaceIILjava_lang_String() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.replace(int, int, java.lang.String)
+ testBuffer.replace(5, 9, "is a replaced");
+ assertTrue("Replace failed, wanted: " + "\'"
+ + "This is a replaced test buffer" + "\'" + " but got: " + "\'"
+ + testBuffer.toString() + "\'", testBuffer.toString().equals(
+ "This is a replaced test buffer"));
+ assertEquals("insert1", "text", new StringBuffer().replace(0, 0, "text")
+ .toString());
+ assertEquals("insert2", "123text", new StringBuffer("123").replace(3, 3, "text")
+ .toString());
+ assertEquals("insert2", "1text23", new StringBuffer("123").replace(1, 1, "text")
+ .toString());
+ }
+
+ private String writeString(String in) {
+ StringBuffer result = new StringBuffer();
+ result.append("\"");
+ for (int i = 0; i < in.length(); i++) {
+ result.append(" 0x" + Integer.toHexString(in.charAt(i)));
+ }
+ result.append("\"");
+ return result.toString();
+ }
+
+ private void reverseTest(String id, String org, String rev, String back) {
+ // create non-shared StringBuffer
+ StringBuffer sb = new StringBuffer(org);
+ sb.reverse();
+ String reversed = sb.toString();
+ assertTrue("reversed surrogate " + id + ": " + writeString(reversed),
+ reversed.equals(rev));
+ // create non-shared StringBuffer
+ sb = new StringBuffer(reversed);
+ sb.reverse();
+ reversed = sb.toString();
+ assertTrue("reversed surrogate " + id + "a: " + writeString(reversed),
+ reversed.equals(back));
+
+ // test algorithm when StringBuffer is shared
+ sb = new StringBuffer(org);
+ String copy = sb.toString();
+ assertEquals(org, copy);
+ sb.reverse();
+ reversed = sb.toString();
+ assertTrue("reversed surrogate " + id + ": " + writeString(reversed),
+ reversed.equals(rev));
+ sb = new StringBuffer(reversed);
+ copy = sb.toString();
+ assertEquals(rev, copy);
+ sb.reverse();
+ reversed = sb.toString();
+ assertTrue("reversed surrogate " + id + "a: " + writeString(reversed),
+ reversed.equals(back));
+
+ }
+
+ /**
+ * java.lang.StringBuffer#reverse()
+ */
+ public void test_reverse() {
+ // Test for method java.lang.StringBuffer
+ // java.lang.StringBuffer.reverse()
+ String org;
+ org = "a";
+ reverseTest("0", org, org, org);
+
+ org = "ab";
+ reverseTest("1", org, "ba", org);
+
+ org = "abcdef";
+ reverseTest("2", org, "fedcba", org);
+
+ org = "abcdefg";
+ reverseTest("3", org, "gfedcba", org);
+
+ }
+
+ /**
+ * java.lang.StringBuffer#setCharAt(int, char)
+ */
+ public void test_setCharAtIC() {
+ // Test for method void java.lang.StringBuffer.setCharAt(int, char)
+ StringBuffer s = new StringBuffer("HelloWorld");
+ s.setCharAt(4, 'Z');
+ assertEquals("Returned incorrect char", 'Z', s.charAt(4));
+ }
+
+ /**
+ * java.lang.StringBuffer#setLength(int)
+ */
+ public void test_setLengthI() {
+ // Test for method void java.lang.StringBuffer.setLength(int)
+ testBuffer.setLength(1000);
+ assertEquals("Failed to increase length", 1000, testBuffer.length());
+ assertTrue("Increase in length trashed buffer", testBuffer.toString()
+ .startsWith("This is a test buffer"));
+ testBuffer.setLength(2);
+ assertEquals("Failed to decrease length", 2, testBuffer.length());
+ assertEquals("Decrease in length failed",
+ "Th", testBuffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer#substring(int)
+ */
+ public void test_substringI() {
+ // Test for method java.lang.String
+ // java.lang.StringBuffer.substring(int)
+ assertEquals("Returned incorrect substring", "is a test buffer", testBuffer.substring(5)
+ );
+ }
+
+ /**
+ * java.lang.StringBuffer#substring(int, int)
+ */
+ public void test_substringII() {
+ // Test for method java.lang.String
+ // java.lang.StringBuffer.substring(int, int)
+ assertEquals("Returned incorrect substring", "is", testBuffer.substring(5, 7)
+ );
+ }
+
+ /**
+ * java.lang.StringBuffer#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.lang.StringBuffer.toString()
+ assertEquals("Incorrect string value returned", "This is a test buffer", testBuffer.toString()
+ );
+ }
+
+ @Override
+ protected void setUp() {
+ testBuffer = new StringBuffer("This is a test buffer");
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBufferTest.java
new file mode 100644
index 0000000..112e005
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBufferTest.java
@@ -0,0 +1,623 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.Serializable;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class StringBufferTest extends TestCase {
+
+ /**
+ * java.lang.StringBuffer#setLength(int)
+ */
+ public void test_setLengthI() {
+ // Regression for HARMONY-90
+ StringBuffer buffer = new StringBuffer("abcde");
+ try {
+ buffer.setLength(-1);
+ fail("Assert 0: IndexOutOfBoundsException must be thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ assertEquals("abcde", buffer.toString());
+ buffer.setLength(1);
+ buffer.append('f');
+ assertEquals("af", buffer.toString());
+
+ buffer = new StringBuffer("abcde");
+ assertEquals("cde", buffer.substring(2));
+ buffer.setLength(3);
+ buffer.append('f');
+ assertEquals("abcf", buffer.toString());
+
+ buffer = new StringBuffer("abcde");
+ buffer.setLength(2);
+ try {
+ buffer.charAt(3);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ buffer = new StringBuffer();
+ buffer.append("abcdefg");
+ buffer.setLength(2);
+ buffer.setLength(5);
+ for (int i = 2; i < 5; i++) {
+ assertEquals(0, buffer.charAt(i));
+ }
+
+ buffer = new StringBuffer();
+ buffer.append("abcdefg");
+ buffer.delete(2, 4);
+ buffer.setLength(7);
+ assertEquals('a', buffer.charAt(0));
+ assertEquals('b', buffer.charAt(1));
+ assertEquals('e', buffer.charAt(2));
+ assertEquals('f', buffer.charAt(3));
+ assertEquals('g', buffer.charAt(4));
+ for (int i = 5; i < 7; i++) {
+ assertEquals(0, buffer.charAt(i));
+ }
+
+ buffer = new StringBuffer();
+ buffer.append("abcdefg");
+ buffer.replace(2, 5, "z");
+ buffer.setLength(7);
+ for (int i = 5; i < 7; i++) {
+ assertEquals(0, buffer.charAt(i));
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer#toString()
+ */
+ public void test_toString() throws Exception {
+ StringBuffer buffer = new StringBuffer();
+ assertEquals("", buffer.toString());
+
+ buffer.append("abcde");
+ assertEquals("abcde", buffer.toString());
+ buffer.setLength(1000);
+ byte[] bytes = buffer.toString().getBytes("GB18030");
+ for (int i = 5; i < bytes.length; i++) {
+ assertEquals(0, bytes[i]);
+ }
+
+ buffer.setLength(5);
+ buffer.append("fghij");
+ assertEquals("abcdefghij", buffer.toString());
+ }
+
+ /**
+ * StringBuffer.StringBuffer(CharSequence);
+ */
+ public void test_constructorLjava_lang_CharSequence() {
+ try {
+ new StringBuffer((CharSequence) null);
+ fail("Assert 0: NPE must be thrown.");
+ } catch (NullPointerException e) {
+ }
+
+ assertEquals("Assert 1: must equal 'abc'.", "abc", new StringBuffer((CharSequence) "abc").toString());
+ }
+
+ public void test_trimToSize() {
+ StringBuffer buffer = new StringBuffer(25);
+ buffer.append("abc");
+ int origCapacity = buffer.capacity();
+ buffer.trimToSize();
+ int trimCapacity = buffer.capacity();
+ assertTrue("Assert 0: capacity must be smaller.", trimCapacity < origCapacity);
+ assertEquals("Assert 1: length must still be 3", 3, buffer.length());
+ assertEquals("Assert 2: value must still be 'abc'.", "abc", buffer.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer.append(CharSequence)
+ */
+ public void test_appendLjava_lang_CharSequence() {
+ StringBuffer sb = new StringBuffer();
+ assertSame(sb, sb.append((CharSequence) "ab"));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) "cd"));
+ assertEquals("cd", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) null));
+ assertEquals("null", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer.append(CharSequence, int, int)
+ */
+ @SuppressWarnings("cast")
+ public void test_appendLjava_lang_CharSequenceII() {
+ StringBuffer sb = new StringBuffer();
+ assertSame(sb, sb.append((CharSequence) "ab", 0, 2));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) "cd", 0, 2));
+ assertEquals("cd", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) "abcd", 0, 2));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) "abcd", 2, 4));
+ assertEquals("cd", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) null, 0, 2));
+ assertEquals("nu", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer.append(char[], int, int)
+ */
+ public void test_append$CII_2() {
+ StringBuffer obj = new StringBuffer();
+ try {
+ obj.append(new char[0], -1, -1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.append(char[], int, int)
+ */
+ public void test_append$CII_3() throws Exception {
+ StringBuffer obj = new StringBuffer();
+ try {
+ obj.append((char[]) null, -1, -1);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.insert(int, CharSequence)
+ */
+ public void test_insertILjava_lang_CharSequence() {
+ final String fixture = "0000";
+ StringBuffer sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(0, (CharSequence) "ab"));
+ assertEquals("ab0000", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(2, (CharSequence) "ab"));
+ assertEquals("00ab00", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) "ab"));
+ assertEquals("0000ab", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) null));
+ assertEquals("0000null", sb.toString());
+ assertEquals(8, sb.length());
+
+ try {
+ sb = new StringBuffer(fixture);
+ sb.insert(-1, (CharSequence) "ab");
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuffer(fixture);
+ sb.insert(5, (CharSequence) "ab");
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.insert(int, CharSequence, int, int)
+ */
+ @SuppressWarnings("cast")
+ public void test_insertILjava_lang_CharSequenceII() {
+ final String fixture = "0000";
+ StringBuffer sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 2));
+ assertEquals("ab0000", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 1));
+ assertEquals("a0000", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 2));
+ assertEquals("00ab00", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 1));
+ assertEquals("00a00", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 2));
+ assertEquals("0000ab", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 1));
+ assertEquals("0000a", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuffer(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) null, 0, 2));
+ assertEquals("0000nu", sb.toString());
+ assertEquals(6, sb.length());
+
+ try {
+ sb = new StringBuffer(fixture);
+ sb.insert(-1, (CharSequence) "ab", 0, 2);
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuffer(fixture);
+ sb.insert(5, (CharSequence) "ab", 0, 2);
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuffer(fixture);
+ sb.insert(5, (CharSequence) "ab", -1, 2);
+ fail("no IOOBE, negative offset");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuffer(fixture);
+ sb.insert(5, new char[] { 'a', 'b' }, 0, -1);
+ fail("no IOOBE, negative length");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuffer(fixture);
+ sb.insert(5, new char[] { 'a', 'b' }, 0, 3);
+ fail("no IOOBE, too long");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.insert(int, char)
+ */
+ public void test_insertIC() {
+ StringBuffer obj = new StringBuffer();
+ try {
+ obj.insert(-1, ' ');
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.appendCodePoint(int)'
+ */
+ public void test_appendCodePointI() {
+ StringBuffer sb = new StringBuffer();
+ sb.appendCodePoint(0x10000);
+ assertEquals("\uD800\uDC00", sb.toString());
+ sb.append("fixture");
+ assertEquals("\uD800\uDC00fixture", sb.toString());
+ sb.appendCodePoint(0x00010FFFF);
+ assertEquals("\uD800\uDC00fixture\uDBFF\uDFFF", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuffer.codePointAt(int)
+ */
+ public void test_codePointAtI() {
+ StringBuffer sb = new StringBuffer("abc");
+ assertEquals('a', sb.codePointAt(0));
+ assertEquals('b', sb.codePointAt(1));
+ assertEquals('c', sb.codePointAt(2));
+
+ sb = new StringBuffer("\uD800\uDC00");
+ assertEquals(0x10000, sb.codePointAt(0));
+ assertEquals('\uDC00', sb.codePointAt(1));
+
+ try {
+ sb.codePointAt(-1);
+ fail("No IOOBE on negative index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointAt(sb.length());
+ fail("No IOOBE on index equal to length.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointAt(sb.length() + 1);
+ fail("No IOOBE on index greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.codePointBefore(int)
+ */
+ public void test_codePointBeforeI() {
+ StringBuffer sb = new StringBuffer("abc");
+ assertEquals('a', sb.codePointBefore(1));
+ assertEquals('b', sb.codePointBefore(2));
+ assertEquals('c', sb.codePointBefore(3));
+
+ sb = new StringBuffer("\uD800\uDC00");
+ assertEquals(0x10000, sb.codePointBefore(2));
+ assertEquals('\uD800', sb.codePointBefore(1));
+
+ try {
+ sb.codePointBefore(0);
+ fail("No IOOBE on zero index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointBefore(-1);
+ fail("No IOOBE on negative index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointBefore(sb.length() + 1);
+ fail("No IOOBE on index greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.codePointCount(int, int)
+ */
+ public void test_codePointCountII() {
+ assertEquals(1, new StringBuffer("\uD800\uDC00").codePointCount(0, 2));
+ assertEquals(1, new StringBuffer("\uD800\uDC01").codePointCount(0, 2));
+ assertEquals(1, new StringBuffer("\uD801\uDC01").codePointCount(0, 2));
+ assertEquals(1, new StringBuffer("\uDBFF\uDFFF").codePointCount(0, 2));
+
+ assertEquals(3, new StringBuffer("a\uD800\uDC00b").codePointCount(0, 4));
+ assertEquals(4, new StringBuffer("a\uD800\uDC00b\uD800").codePointCount(0, 5));
+
+ StringBuffer sb = new StringBuffer("abc");
+ try {
+ sb.codePointCount(-1, 2);
+ fail("No IOOBE for negative begin index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointCount(0, 4);
+ fail("No IOOBE for end index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointCount(3, 2);
+ fail("No IOOBE for begin index larger than end index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.getChars(int, int, char[], int)
+ */
+ public void test_getCharsII$CI() {
+ StringBuffer obj = new StringBuffer();
+ try {
+ obj.getChars(0, 0, new char[0], -1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuffer.offsetByCodePoints(int, int)'
+ */
+ public void test_offsetByCodePointsII() {
+ int result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(0, 2);
+ assertEquals(3, result);
+
+ result = new StringBuffer("abcd").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(0, 3);
+ assertEquals(4, result);
+
+ result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(3, -1);
+ assertEquals(1, result);
+
+ result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(3, 0);
+ assertEquals(3, result);
+
+ result = new StringBuffer("\uD800\uDC00bc").offsetByCodePoints(3, 0);
+ assertEquals(3, result);
+
+ result = new StringBuffer("a\uDC00bc").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ result = new StringBuffer("a\uD800bc").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ StringBuffer sb = new StringBuffer("abc");
+ try {
+ sb.offsetByCodePoints(-1, 1);
+ fail("No IOOBE for negative index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.offsetByCodePoints(0, 4);
+ fail("No IOOBE for offset that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.offsetByCodePoints(3, -4);
+ fail("No IOOBE for offset that's too small.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.offsetByCodePoints(3, 1);
+ fail("No IOOBE for index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.offsetByCodePoints(4, -1);
+ fail("No IOOBE for index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * {@link java.lang.StringBuffer#indexOf(String, int)}
+ */
+ @SuppressWarnings("nls")
+ public void test_IndexOfStringInt() {
+ final String fixture = "0123456789";
+ StringBuffer sb = new StringBuffer(fixture);
+ assertEquals(0, sb.indexOf("0"));
+ assertEquals(0, sb.indexOf("012"));
+ assertEquals(-1, sb.indexOf("02"));
+ assertEquals(8, sb.indexOf("89"));
+
+ assertEquals(0, sb.indexOf("0"), 0);
+ assertEquals(0, sb.indexOf("012"), 0);
+ assertEquals(-1, sb.indexOf("02"), 0);
+ assertEquals(8, sb.indexOf("89"), 0);
+
+ assertEquals(-1, sb.indexOf("0"), 5);
+ assertEquals(-1, sb.indexOf("012"), 5);
+ assertEquals(-1, sb.indexOf("02"), 0);
+ assertEquals(8, sb.indexOf("89"), 5);
+
+ try {
+ sb.indexOf(null, 0);
+ fail("Should throw a NullPointerExceptionE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * {@link java.lang.StringBuffer#lastIndexOf(String, int)}
+ */
+ @SuppressWarnings("nls")
+ public void test_lastIndexOfLjava_lang_StringI() {
+ final String fixture = "0123456789";
+ StringBuffer sb = new StringBuffer(fixture);
+ assertEquals(0, sb.lastIndexOf("0"));
+ assertEquals(0, sb.lastIndexOf("012"));
+ assertEquals(-1, sb.lastIndexOf("02"));
+ assertEquals(8, sb.lastIndexOf("89"));
+
+ assertEquals(0, sb.lastIndexOf("0"), 0);
+ assertEquals(0, sb.lastIndexOf("012"), 0);
+ assertEquals(-1, sb.lastIndexOf("02"), 0);
+ assertEquals(8, sb.lastIndexOf("89"), 0);
+
+ assertEquals(-1, sb.lastIndexOf("0"), 5);
+ assertEquals(-1, sb.lastIndexOf("012"), 5);
+ assertEquals(-1, sb.lastIndexOf("02"), 0);
+ assertEquals(8, sb.lastIndexOf("89"), 5);
+
+ try {
+ sb.lastIndexOf(null, 0);
+ fail("Should throw a NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ // comparator for StringBuffer objects
+ private static final SerializableAssert STRING_BUFFER_COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ StringBuffer init = (StringBuffer) initial;
+ StringBuffer desr = (StringBuffer) deserialized;
+
+ // serializable fields are: 'count', 'shared', 'value'
+ // serialization of 'shared' is not verified
+ // 'count' + 'value' should result in required string
+ assertEquals("toString", init.toString(), desr.toString());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new StringBuffer("0123456789"),
+ STRING_BUFFER_COMPARATOR);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new StringBuffer("0123456789"),
+ STRING_BUFFER_COMPARATOR);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBuilderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBuilderTest.java
new file mode 100644
index 0000000..febdfc4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringBuilderTest.java
@@ -0,0 +1,1986 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+// import org.apache.harmony.testframework.serialization.SerializationTest;
+// import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class StringBuilderTest extends TestCase {
+
+ /**
+ * java.lang.StringBuilder.StringBuilder()
+ */
+ public void test_Constructor() {
+ StringBuilder sb = new StringBuilder();
+ assertNotNull(sb);
+ assertEquals(16, sb.capacity());
+ }
+
+ /**
+ * java.lang.StringBuilder.StringBuilder(int)
+ */
+ public void test_ConstructorI() {
+ StringBuilder sb = new StringBuilder(24);
+ assertNotNull(sb);
+ assertEquals(24, sb.capacity());
+
+ try {
+ new StringBuilder(-1);
+ fail("no exception");
+ } catch (NegativeArraySizeException e) {
+ // Expected
+ }
+
+ assertNotNull(new StringBuilder(0));
+ }
+
+ /**
+ * java.lang.StringBuilder.StringBuilder(CharSequence)
+ */
+ @SuppressWarnings("cast")
+ public void test_ConstructorLjava_lang_CharSequence() {
+ StringBuilder sb = new StringBuilder((CharSequence) "fixture");
+ assertEquals("fixture", sb.toString());
+ assertEquals("fixture".length() + 16, sb.capacity());
+
+ sb = new StringBuilder((CharSequence) new StringBuffer("fixture"));
+ assertEquals("fixture", sb.toString());
+ assertEquals("fixture".length() + 16, sb.capacity());
+
+ try {
+ new StringBuilder((CharSequence) null);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.StringBuilder(String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ StringBuilder sb = new StringBuilder("fixture");
+ assertEquals("fixture", sb.toString());
+ assertEquals("fixture".length() + 16, sb.capacity());
+
+ try {
+ new StringBuilder((String) null);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.append(boolean)
+ */
+ public void test_appendZ() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(true));
+ assertEquals("true", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(false));
+ assertEquals("false", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(char)
+ */
+ public void test_appendC() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append('a'));
+ assertEquals("a", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append('b'));
+ assertEquals("b", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(char[])
+ */
+ public void test_append$C() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(new char[] { 'a', 'b' }));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(new char[] { 'c', 'd' }));
+ assertEquals("cd", sb.toString());
+ try {
+ sb.append((char[]) null);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.append(char[], int, int)
+ */
+ public void test_append$CII() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(new char[] { 'a', 'b' }, 0, 2));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(new char[] { 'c', 'd' }, 0, 2));
+ assertEquals("cd", sb.toString());
+
+ sb.setLength(0);
+ assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 0, 2));
+ assertEquals("ab", sb.toString());
+
+ sb.setLength(0);
+ assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 2));
+ assertEquals("cd", sb.toString());
+
+ sb.setLength(0);
+ assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 0));
+ assertEquals("", sb.toString());
+
+ try {
+ sb.append((char[]) null, 0, 2);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ sb.append(new char[] { 'a', 'b', 'c', 'd' }, -1, 2);
+ fail("no IOOBE, negative offset");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.append(new char[] { 'a', 'b', 'c', 'd' }, 0, -1);
+ fail("no IOOBE, negative length");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 3);
+ fail("no IOOBE, offset and length overflow");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.append(CharSequence)
+ */
+ public void test_appendLjava_lang_CharSequence() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append((CharSequence) "ab"));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) "cd"));
+ assertEquals("cd", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) null));
+ assertEquals("null", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(CharSequence, int, int)
+ */
+ @SuppressWarnings("cast")
+ public void test_appendLjava_lang_CharSequenceII() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append((CharSequence) "ab", 0, 2));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) "cd", 0, 2));
+ assertEquals("cd", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) "abcd", 0, 2));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) "abcd", 2, 4));
+ assertEquals("cd", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((CharSequence) null, 0, 2));
+ assertEquals("nu", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(double)
+ */
+ public void test_appendD() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(1D));
+ assertEquals(String.valueOf(1D), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(0D));
+ assertEquals(String.valueOf(0D), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(-1D));
+ assertEquals(String.valueOf(-1D), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Double.NaN));
+ assertEquals(String.valueOf(Double.NaN), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Double.NEGATIVE_INFINITY));
+ assertEquals(String.valueOf(Double.NEGATIVE_INFINITY), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Double.POSITIVE_INFINITY));
+ assertEquals(String.valueOf(Double.POSITIVE_INFINITY), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Double.MIN_VALUE));
+ assertEquals(String.valueOf(Double.MIN_VALUE), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Double.MAX_VALUE));
+ assertEquals(String.valueOf(Double.MAX_VALUE), sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(float)
+ */
+ public void test_appendF() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(1F));
+ assertEquals(String.valueOf(1F), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(0F));
+ assertEquals(String.valueOf(0F), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(-1F));
+ assertEquals(String.valueOf(-1F), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Float.NaN));
+ assertEquals(String.valueOf(Float.NaN), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Float.NEGATIVE_INFINITY));
+ assertEquals(String.valueOf(Float.NEGATIVE_INFINITY), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Float.POSITIVE_INFINITY));
+ assertEquals(String.valueOf(Float.POSITIVE_INFINITY), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Float.MIN_VALUE));
+ assertEquals(String.valueOf(Float.MIN_VALUE), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Float.MAX_VALUE));
+ assertEquals(String.valueOf(Float.MAX_VALUE), sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(int)
+ */
+ public void test_appendI() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(1));
+ assertEquals(String.valueOf(1), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(0));
+ assertEquals(String.valueOf(0), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(-1));
+ assertEquals(String.valueOf(-1), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Integer.MIN_VALUE));
+ assertEquals(String.valueOf(Integer.MIN_VALUE), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Integer.MAX_VALUE));
+ assertEquals(String.valueOf(Integer.MAX_VALUE), sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(long)
+ */
+ public void test_appendL() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(1L));
+ assertEquals(String.valueOf(1L), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(0L));
+ assertEquals(String.valueOf(0L), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(-1L));
+ assertEquals(String.valueOf(-1L), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Integer.MIN_VALUE));
+ assertEquals(String.valueOf(Integer.MIN_VALUE), sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(Integer.MAX_VALUE));
+ assertEquals(String.valueOf(Integer.MAX_VALUE), sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(Object)'
+ */
+ public void test_appendLjava_lang_Object() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(Fixture.INSTANCE));
+ assertEquals(Fixture.INSTANCE.toString(), sb.toString());
+
+ sb.setLength(0);
+ assertSame(sb, sb.append((Object) null));
+ assertEquals("null", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(String)
+ */
+ public void test_appendLjava_lang_String() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append("ab"));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append("cd"));
+ assertEquals("cd", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((String) null));
+ assertEquals("null", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.append(StringBuffer)
+ */
+ public void test_appendLjava_lang_StringBuffer() {
+ StringBuilder sb = new StringBuilder();
+ assertSame(sb, sb.append(new StringBuffer("ab")));
+ assertEquals("ab", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append(new StringBuffer("cd")));
+ assertEquals("cd", sb.toString());
+ sb.setLength(0);
+ assertSame(sb, sb.append((StringBuffer) null));
+ assertEquals("null", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.appendCodePoint(int)'
+ */
+ public void test_appendCodePointI() {
+ StringBuilder sb = new StringBuilder();
+ sb.appendCodePoint(0x10000);
+ assertEquals("\uD800\uDC00", sb.toString());
+ sb.append("fixture");
+ assertEquals("\uD800\uDC00fixture", sb.toString());
+ sb.appendCodePoint(0x00010FFFF);
+ assertEquals("\uD800\uDC00fixture\uDBFF\uDFFF", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.capacity()'
+ */
+ public void test_capacity() {
+ StringBuilder sb = new StringBuilder();
+ assertEquals(16, sb.capacity());
+ sb.append("0123456789ABCDEF0123456789ABCDEF");
+ assertTrue(sb.capacity() > 16);
+ }
+
+ /**
+ * java.lang.StringBuilder.charAt(int)'
+ */
+ public void test_charAtI() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ for (int i = 0; i < fixture.length(); i++) {
+ assertEquals((char) ('0' + i), sb.charAt(i));
+ }
+
+ try {
+ sb.charAt(-1);
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.charAt(fixture.length());
+ fail("no IOOBE, equal to length");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ sb.charAt(fixture.length() + 1);
+ fail("no IOOBE, greater than length");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.codePointAt(int)
+ */
+ public void test_codePointAtI() {
+ StringBuilder sb = new StringBuilder("abc");
+ assertEquals('a', sb.codePointAt(0));
+ assertEquals('b', sb.codePointAt(1));
+ assertEquals('c', sb.codePointAt(2));
+
+ sb = new StringBuilder("\uD800\uDC00");
+ assertEquals(0x10000, sb.codePointAt(0));
+ assertEquals('\uDC00', sb.codePointAt(1));
+
+ sb = new StringBuilder();
+ sb.append("abc");
+ try {
+ sb.codePointAt(-1);
+ fail("No IOOBE on negative index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointAt(sb.length());
+ fail("No IOOBE on index equal to length.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointAt(sb.length() + 1);
+ fail("No IOOBE on index greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.codePointBefore(int)
+ */
+ public void test_codePointBeforeI() {
+ StringBuilder sb = new StringBuilder("abc");
+ assertEquals('a', sb.codePointBefore(1));
+ assertEquals('b', sb.codePointBefore(2));
+ assertEquals('c', sb.codePointBefore(3));
+
+ sb = new StringBuilder("\uD800\uDC00");
+ assertEquals(0x10000, sb.codePointBefore(2));
+ assertEquals('\uD800', sb.codePointBefore(1));
+
+ sb = new StringBuilder();
+ sb.append("abc");
+
+ try {
+ sb.codePointBefore(0);
+ fail("No IOOBE on zero index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointBefore(-1);
+ fail("No IOOBE on negative index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointBefore(sb.length() + 1);
+ fail("No IOOBE on index greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.codePointCount(int, int)
+ */
+ public void test_codePointCountII() {
+ assertEquals(1, new StringBuilder("\uD800\uDC00").codePointCount(0, 2));
+ assertEquals(1, new StringBuilder("\uD800\uDC01").codePointCount(0, 2));
+ assertEquals(1, new StringBuilder("\uD801\uDC01").codePointCount(0, 2));
+ assertEquals(1, new StringBuilder("\uDBFF\uDFFF").codePointCount(0, 2));
+
+ assertEquals(3, new StringBuilder("a\uD800\uDC00b").codePointCount(0, 4));
+ assertEquals(4, new StringBuilder("a\uD800\uDC00b\uD800").codePointCount(0, 5));
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("abc");
+ try {
+ sb.codePointCount(-1, 2);
+ fail("No IOOBE for negative begin index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointCount(0, 4);
+ fail("No IOOBE for end index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.codePointCount(3, 2);
+ fail("No IOOBE for begin index larger than end index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.delete(int, int)
+ */
+ public void test_deleteII() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.delete(0, 0));
+ assertEquals(fixture, sb.toString());
+ assertSame(sb, sb.delete(5, 5));
+ assertEquals(fixture, sb.toString());
+ assertSame(sb, sb.delete(0, 1));
+ assertEquals("123456789", sb.toString());
+ assertEquals(9, sb.length());
+ assertSame(sb, sb.delete(0, sb.length()));
+ assertEquals("", sb.toString());
+ assertEquals(0, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.delete(0, 11));
+ assertEquals("", sb.toString());
+ assertEquals(0, sb.length());
+
+ try {
+ new StringBuilder(fixture).delete(-1, 2);
+ fail("no SIOOBE, negative start");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ new StringBuilder(fixture).delete(11, 12);
+ fail("no SIOOBE, start too far");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ new StringBuilder(fixture).delete(13, 12);
+ fail("no SIOOBE, start larger than end");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ // HARMONY 6212
+ sb = new StringBuilder();
+ sb.append("abcde");
+ String str = sb.toString();
+ sb.delete(0, sb.length());
+ sb.append("YY");
+ assertEquals("abcde", str);
+ assertEquals("YY", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.deleteCharAt(int)
+ */
+ public void test_deleteCharAtI() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.deleteCharAt(0));
+ assertEquals("123456789", sb.toString());
+ assertEquals(9, sb.length());
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.deleteCharAt(5));
+ assertEquals("012346789", sb.toString());
+ assertEquals(9, sb.length());
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.deleteCharAt(9));
+ assertEquals("012345678", sb.toString());
+ assertEquals(9, sb.length());
+
+ try {
+ new StringBuilder(fixture).deleteCharAt(-1);
+ fail("no SIOOBE, negative index");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ new StringBuilder(fixture).deleteCharAt(fixture.length());
+ fail("no SIOOBE, index equals length");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ new StringBuilder(fixture).deleteCharAt(fixture.length() + 1);
+ fail("no SIOOBE, index exceeds length");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.ensureCapacity(int)'
+ */
+ public void test_ensureCapacityI() {
+ StringBuilder sb = new StringBuilder(5);
+ assertEquals(5, sb.capacity());
+ sb.ensureCapacity(10);
+ assertEquals(12, sb.capacity());
+ sb.ensureCapacity(26);
+ assertEquals(26, sb.capacity());
+ sb.ensureCapacity(55);
+ assertEquals(55, sb.capacity());
+ }
+
+ /**
+ * java.lang.StringBuilder.getChars(int, int, char[], int)'
+ */
+ public void test_getCharsII$CI() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ char[] dst = new char[10];
+ sb.getChars(0, 10, dst, 0);
+ assertTrue(Arrays.equals(fixture.toCharArray(), dst));
+
+ Arrays.fill(dst, '\0');
+ sb.getChars(0, 5, dst, 0);
+ char[] fixtureChars = new char[10];
+ fixture.getChars(0, 5, fixtureChars, 0);
+ assertTrue(Arrays.equals(fixtureChars, dst));
+
+ Arrays.fill(dst, '\0');
+ Arrays.fill(fixtureChars, '\0');
+ sb.getChars(0, 5, dst, 5);
+ fixture.getChars(0, 5, fixtureChars, 5);
+ assertTrue(Arrays.equals(fixtureChars, dst));
+
+ Arrays.fill(dst, '\0');
+ Arrays.fill(fixtureChars, '\0');
+ sb.getChars(5, 10, dst, 1);
+ fixture.getChars(5, 10, fixtureChars, 1);
+ assertTrue(Arrays.equals(fixtureChars, dst));
+
+ try {
+ sb.getChars(0, 10, null, 0);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ sb.getChars(-1, 10, dst, 0);
+ fail("no IOOBE, srcBegin negative");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.getChars(0, 10, dst, -1);
+ fail("no IOOBE, dstBegin negative");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.getChars(5, 4, dst, 0);
+ fail("no IOOBE, srcBegin > srcEnd");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.getChars(0, 11, dst, 0);
+ fail("no IOOBE, srcEnd > length");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.getChars(0, 10, dst, 5);
+ fail("no IOOBE, dstBegin and src size too large for what's left in dst");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.indexOf(String)
+ */
+ public void test_indexOfLjava_lang_String() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertEquals(0, sb.indexOf("0"));
+ assertEquals(0, sb.indexOf("012"));
+ assertEquals(-1, sb.indexOf("02"));
+ assertEquals(8, sb.indexOf("89"));
+
+ try {
+ sb.indexOf(null);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.indexOf(String, int)
+ */
+ public void test_IndexOfStringInt() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertEquals(0, sb.indexOf("0"));
+ assertEquals(0, sb.indexOf("012"));
+ assertEquals(-1, sb.indexOf("02"));
+ assertEquals(8, sb.indexOf("89"));
+
+ assertEquals(0, sb.indexOf("0"), 0);
+ assertEquals(0, sb.indexOf("012"), 0);
+ assertEquals(-1, sb.indexOf("02"), 0);
+ assertEquals(8, sb.indexOf("89"), 0);
+
+ assertEquals(-1, sb.indexOf("0"), 5);
+ assertEquals(-1, sb.indexOf("012"), 5);
+ assertEquals(-1, sb.indexOf("02"), 0);
+ assertEquals(8, sb.indexOf("89"), 5);
+
+ try {
+ sb.indexOf(null, 0);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, boolean)
+ */
+ public void test_insertIZ() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, true));
+ assertEquals("true0000", sb.toString());
+ assertEquals(8, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, false));
+ assertEquals("false0000", sb.toString());
+ assertEquals(9, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, false));
+ assertEquals("00false00", sb.toString());
+ assertEquals(9, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, false));
+ assertEquals("0000false", sb.toString());
+ assertEquals(9, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, false);
+ fail("no SIOOBE, negative index");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, false);
+ fail("no SIOOBE, index too large index");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, char)
+ */
+ public void test_insertIC() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, 'a'));
+ assertEquals("a0000", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, 'b'));
+ assertEquals("b0000", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, 'b'));
+ assertEquals("00b00", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, 'b'));
+ assertEquals("0000b", sb.toString());
+ assertEquals(5, sb.length());
+
+ // FIXME this fails on Sun JRE 5.0_5
+// try {
+// sb = new StringBuilder(fixture);
+// sb.insert(-1, 'a');
+// fail("no SIOOBE, negative index");
+// } catch (StringIndexOutOfBoundsException e) {
+// // Expected
+// }
+
+ /*
+ * FIXME This fails on Sun JRE 5.0_5, but that seems like a bug, since
+ * the 'insert(int, char[]) behaves this way.
+ */
+// try {
+// sb = new StringBuilder(fixture);
+// sb.insert(5, 'a');
+// fail("no SIOOBE, index too large index");
+// } catch (StringIndexOutOfBoundsException e) {
+// // Expected
+// }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, char)
+ */
+ public void test_insertIC_2() {
+ StringBuilder obj = new StringBuilder();
+ try {
+ obj.insert(-1, '?');
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, char[])'
+ */
+ public void test_insertI$C() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }));
+ assertEquals("ab0000", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }));
+ assertEquals("00ab00", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }));
+ assertEquals("0000ab", sb.toString());
+ assertEquals(6, sb.length());
+
+ /*
+ * TODO This NPE is the behavior on Sun's JRE 5.0_5, but it's
+ * undocumented. The assumption is that this method behaves like
+ * String.valueOf(char[]), which does throw a NPE too, but that is also
+ * undocumented.
+ */
+
+ try {
+ sb.insert(0, (char[]) null);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, new char[] { 'a', 'b' });
+ fail("no SIOOBE, negative index");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, new char[] { 'a', 'b' });
+ fail("no SIOOBE, index too large index");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, char[], int, int)
+ */
+ public void test_insertI$CII() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }, 0, 2));
+ assertEquals("ab0000", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }, 0, 1));
+ assertEquals("a0000", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }, 0, 2));
+ assertEquals("00ab00", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }, 0, 1));
+ assertEquals("00a00", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }, 0, 2));
+ assertEquals("0000ab", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }, 0, 1));
+ assertEquals("0000a", sb.toString());
+ assertEquals(5, sb.length());
+
+ /*
+ * TODO This NPE is the behavior on Sun's JRE 5.0_5, but it's
+ * undocumented. The assumption is that this method behaves like
+ * String.valueOf(char[]), which does throw a NPE too, but that is also
+ * undocumented.
+ */
+
+ try {
+ sb.insert(0, (char[]) null, 0, 2);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, new char[] { 'a', 'b' }, 0, 2);
+ fail("no SIOOBE, negative index");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, new char[] { 'a', 'b' }, 0, 2);
+ fail("no SIOOBE, index too large index");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, new char[] { 'a', 'b' }, -1, 2);
+ fail("no SIOOBE, negative offset");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, new char[] { 'a', 'b' }, 0, -1);
+ fail("no SIOOBE, negative length");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, new char[] { 'a', 'b' }, 0, 3);
+ fail("no SIOOBE, too long");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, CharSequence)
+ */
+ public void test_insertILjava_lang_CharSequence() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, (CharSequence) "ab"));
+ assertEquals("ab0000", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, (CharSequence) "ab"));
+ assertEquals("00ab00", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) "ab"));
+ assertEquals("0000ab", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) null));
+ assertEquals("0000null", sb.toString());
+ assertEquals(8, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, (CharSequence) "ab");
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, (CharSequence) "ab");
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, CharSequence, int, int)
+ */
+ @SuppressWarnings("cast")
+ public void test_insertILjava_lang_CharSequenceII() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 2));
+ assertEquals("ab0000", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 1));
+ assertEquals("a0000", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 2));
+ assertEquals("00ab00", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 1));
+ assertEquals("00a00", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 2));
+ assertEquals("0000ab", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 1));
+ assertEquals("0000a", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, (CharSequence) null, 0, 2));
+ assertEquals("0000nu", sb.toString());
+ assertEquals(6, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, (CharSequence) "ab", 0, 2);
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, (CharSequence) "ab", 0, 2);
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, (CharSequence) "ab", -1, 2);
+ fail("no IOOBE, negative offset");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, new char[] { 'a', 'b' }, 0, -1);
+ fail("no IOOBE, negative length");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, new char[] { 'a', 'b' }, 0, 3);
+ fail("no IOOBE, too long");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, double)
+ */
+ public void test_insertID() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, -1D));
+ assertEquals("-1.00000", sb.toString());
+ assertEquals(8, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, 0D));
+ assertEquals("0.00000", sb.toString());
+ assertEquals(7, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, 1D));
+ assertEquals("001.000", sb.toString());
+ assertEquals(7, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, 2D));
+ assertEquals("00002.0", sb.toString());
+ assertEquals(7, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, 1D);
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, 1D);
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, float)
+ */
+ public void test_insertIF() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, -1F));
+ assertEquals("-1.00000", sb.toString());
+ assertEquals(8, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, 0F));
+ assertEquals("0.00000", sb.toString());
+ assertEquals(7, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, 1F));
+ assertEquals("001.000", sb.toString());
+ assertEquals(7, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, 2F));
+ assertEquals("00002.0", sb.toString());
+ assertEquals(7, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, 1F);
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, 1F);
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, int)
+ */
+ public void test_insertII() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, -1));
+ assertEquals("-10000", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, 0));
+ assertEquals("00000", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, 1));
+ assertEquals("00100", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, 2));
+ assertEquals("00002", sb.toString());
+ assertEquals(5, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, 1);
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, 1);
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, long)
+ */
+ public void test_insertIJ() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, -1L));
+ assertEquals("-10000", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, 0L));
+ assertEquals("00000", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, 1L));
+ assertEquals("00100", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, 2L));
+ assertEquals("00002", sb.toString());
+ assertEquals(5, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, 1L);
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, 1L);
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, Object)
+ */
+ public void test_insertILjava_lang_Object() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, Fixture.INSTANCE));
+ assertEquals("fixture0000", sb.toString());
+ assertEquals(11, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, Fixture.INSTANCE));
+ assertEquals("00fixture00", sb.toString());
+ assertEquals(11, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, Fixture.INSTANCE));
+ assertEquals("0000fixture", sb.toString());
+ assertEquals(11, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, (Object) null));
+ assertEquals("0000null", sb.toString());
+ assertEquals(8, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, Fixture.INSTANCE);
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, Fixture.INSTANCE);
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.insert(int, String)
+ */
+ public void test_insertILjava_lang_String() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(0, "fixture"));
+ assertEquals("fixture0000", sb.toString());
+ assertEquals(11, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(2, "fixture"));
+ assertEquals("00fixture00", sb.toString());
+ assertEquals(11, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, "fixture"));
+ assertEquals("0000fixture", sb.toString());
+ assertEquals(11, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.insert(4, (Object) null));
+ assertEquals("0000null", sb.toString());
+ assertEquals(8, sb.length());
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(-1, "fixture");
+ fail("no IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.insert(5, "fixture");
+ fail("no IOOBE, index too large index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.lastIndexOf(String)
+ */
+ public void test_lastIndexOfLjava_lang_String() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertEquals(0, sb.lastIndexOf("0"));
+ assertEquals(0, sb.lastIndexOf("012"));
+ assertEquals(-1, sb.lastIndexOf("02"));
+ assertEquals(8, sb.lastIndexOf("89"));
+
+ try {
+ sb.lastIndexOf(null);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.lastIndexOf(String, int)
+ */
+ public void test_lastIndexOfLjava_lang_StringI() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertEquals(0, sb.lastIndexOf("0"));
+ assertEquals(0, sb.lastIndexOf("012"));
+ assertEquals(-1, sb.lastIndexOf("02"));
+ assertEquals(8, sb.lastIndexOf("89"));
+
+ assertEquals(0, sb.lastIndexOf("0"), 0);
+ assertEquals(0, sb.lastIndexOf("012"), 0);
+ assertEquals(-1, sb.lastIndexOf("02"), 0);
+ assertEquals(8, sb.lastIndexOf("89"), 0);
+
+ assertEquals(-1, sb.lastIndexOf("0"), 5);
+ assertEquals(-1, sb.lastIndexOf("012"), 5);
+ assertEquals(-1, sb.lastIndexOf("02"), 0);
+ assertEquals(8, sb.lastIndexOf("89"), 5);
+
+ try {
+ sb.lastIndexOf(null, 0);
+ fail("no NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.length()
+ */
+ public void test_length() {
+ StringBuilder sb = new StringBuilder();
+ assertEquals(0, sb.length());
+ sb.append("0000");
+ assertEquals(4, sb.length());
+ }
+
+ /**
+ * java.lang.StringBuilder.offsetByCodePoints(int, int)'
+ */
+ public void test_offsetByCodePointsII() {
+ int result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(0, 2);
+ assertEquals(3, result);
+
+ result = new StringBuilder("abcd").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(0, 3);
+ assertEquals(4, result);
+
+ result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(3, -1);
+ assertEquals(1, result);
+
+ result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(3, 0);
+ assertEquals(3, result);
+
+ result = new StringBuilder("\uD800\uDC00bc").offsetByCodePoints(3, 0);
+ assertEquals(3, result);
+
+ result = new StringBuilder("a\uDC00bc").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ result = new StringBuilder("a\uD800bc").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("abc");
+ try {
+ sb.offsetByCodePoints(-1, 1);
+ fail("No IOOBE for negative index.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.offsetByCodePoints(0, 4);
+ fail("No IOOBE for offset that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.offsetByCodePoints(3, -4);
+ fail("No IOOBE for offset that's too small.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.offsetByCodePoints(3, 1);
+ fail("No IOOBE for index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+
+ try {
+ sb.offsetByCodePoints(4, -1);
+ fail("No IOOBE for index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.replace(int, int, String)'
+ */
+ public void test_replaceIILjava_lang_String() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.replace(1, 3, "11"));
+ assertEquals("0110", sb.toString());
+ assertEquals(4, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.replace(1, 2, "11"));
+ assertEquals("01100", sb.toString());
+ assertEquals(5, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.replace(4, 5, "11"));
+ assertEquals("000011", sb.toString());
+ assertEquals(6, sb.length());
+
+ sb = new StringBuilder(fixture);
+ assertSame(sb, sb.replace(4, 6, "11"));
+ assertEquals("000011", sb.toString());
+ assertEquals(6, sb.length());
+
+ // FIXME Undocumented NPE in Sun's JRE 5.0_5
+ try {
+ sb.replace(1, 2, null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.replace(-1, 2, "11");
+ fail("No SIOOBE, negative start");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.replace(5, 2, "11");
+ fail("No SIOOBE, start > length");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb = new StringBuilder(fixture);
+ sb.replace(3, 2, "11");
+ fail("No SIOOBE, start > end");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ // Regression for HARMONY-348
+ StringBuilder buffer = new StringBuilder("1234567");
+ buffer.replace(2, 6, "XXX");
+ assertEquals("12XXX7", buffer.toString());
+ }
+
+ private void reverseTest(String org, String rev, String back) {
+ // create non-shared StringBuilder
+ StringBuilder sb = new StringBuilder(org);
+ sb.reverse();
+ String reversed = sb.toString();
+ assertEquals(rev, reversed);
+ // create non-shared StringBuilder
+ sb = new StringBuilder(reversed);
+ sb.reverse();
+ reversed = sb.toString();
+ assertEquals(back, reversed);
+
+ // test algorithm when StringBuilder is shared
+ sb = new StringBuilder(org);
+ String copy = sb.toString();
+ assertEquals(org, copy);
+ sb.reverse();
+ reversed = sb.toString();
+ assertEquals(rev, reversed);
+ sb = new StringBuilder(reversed);
+ copy = sb.toString();
+ assertEquals(rev, copy);
+ sb.reverse();
+ reversed = sb.toString();
+ assertEquals(back, reversed);
+ }
+
+ /**
+ * java.lang.StringBuilder.reverse()
+ */
+ public void test_reverse() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertSame(sb, sb.reverse());
+ assertEquals("9876543210", sb.toString());
+
+ sb = new StringBuilder("012345678");
+ assertSame(sb, sb.reverse());
+ assertEquals("876543210", sb.toString());
+
+ sb.setLength(1);
+ assertSame(sb, sb.reverse());
+ assertEquals("8", sb.toString());
+
+ sb.setLength(0);
+ assertSame(sb, sb.reverse());
+ assertEquals("", sb.toString());
+
+ String str;
+ str = "a";
+ reverseTest(str, str, str);
+
+ str = "ab";
+ reverseTest(str, "ba", str);
+
+ str = "abcdef";
+ reverseTest(str, "fedcba", str);
+
+ str = "abcdefg";
+ reverseTest(str, "gfedcba", str);
+
+ str = "\ud800\udc00";
+ reverseTest(str, str, str);
+
+ str = "\udc00\ud800";
+ reverseTest(str, "\ud800\udc00", "\ud800\udc00");
+
+ str = "a\ud800\udc00";
+ reverseTest(str, "\ud800\udc00a", str);
+
+ str = "ab\ud800\udc00";
+ reverseTest(str, "\ud800\udc00ba", str);
+
+ str = "abc\ud800\udc00";
+ reverseTest(str, "\ud800\udc00cba", str);
+
+ str = "\ud800\udc00\udc01\ud801\ud802\udc02";
+ reverseTest(str, "\ud802\udc02\ud801\udc01\ud800\udc00",
+ "\ud800\udc00\ud801\udc01\ud802\udc02");
+
+ str = "\ud800\udc00\ud801\udc01\ud802\udc02";
+ reverseTest(str, "\ud802\udc02\ud801\udc01\ud800\udc00", str);
+
+ str = "\ud800\udc00\udc01\ud801a";
+ reverseTest(str, "a\ud801\udc01\ud800\udc00",
+ "\ud800\udc00\ud801\udc01a");
+
+ str = "a\ud800\udc00\ud801\udc01";
+ reverseTest(str, "\ud801\udc01\ud800\udc00a", str);
+
+ str = "\ud800\udc00\udc01\ud801ab";
+ reverseTest(str, "ba\ud801\udc01\ud800\udc00",
+ "\ud800\udc00\ud801\udc01ab");
+
+ str = "ab\ud800\udc00\ud801\udc01";
+ reverseTest(str, "\ud801\udc01\ud800\udc00ba", str);
+
+ str = "\ud800\udc00\ud801\udc01";
+ reverseTest(str, "\ud801\udc01\ud800\udc00", str);
+
+ str = "a\ud800\udc00z\ud801\udc01";
+ reverseTest(str, "\ud801\udc01z\ud800\udc00a", str);
+
+ str = "a\ud800\udc00bz\ud801\udc01";
+ reverseTest(str, "\ud801\udc01zb\ud800\udc00a", str);
+
+ str = "abc\ud802\udc02\ud801\udc01\ud800\udc00";
+ reverseTest(str, "\ud800\udc00\ud801\udc01\ud802\udc02cba", str);
+
+ str = "abcd\ud802\udc02\ud801\udc01\ud800\udc00";
+ reverseTest(str, "\ud800\udc00\ud801\udc01\ud802\udc02dcba", str);
+ }
+
+ /**
+ * java.lang.StringBuilder.setCharAt(int, char)
+ */
+ public void test_setCharAtIC() {
+ final String fixture = "0000";
+ StringBuilder sb = new StringBuilder(fixture);
+ sb.setCharAt(0, 'A');
+ assertEquals("A000", sb.toString());
+ sb.setCharAt(1, 'B');
+ assertEquals("AB00", sb.toString());
+ sb.setCharAt(2, 'C');
+ assertEquals("ABC0", sb.toString());
+ sb.setCharAt(3, 'D');
+ assertEquals("ABCD", sb.toString());
+
+ try {
+ sb.setCharAt(-1, 'A');
+ fail("No IOOBE, negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.setCharAt(4, 'A');
+ fail("No IOOBE, index == length");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.setCharAt(5, 'A');
+ fail("No IOOBE, index > length");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.setLength(int)'
+ */
+ public void test_setLengthI() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ sb.setLength(5);
+ assertEquals(5, sb.length());
+ assertEquals("01234", sb.toString());
+ sb.setLength(6);
+ assertEquals(6, sb.length());
+ assertEquals("01234\0", sb.toString());
+ sb.setLength(0);
+ assertEquals(0, sb.length());
+ assertEquals("", sb.toString());
+
+ try {
+ sb.setLength(-1);
+ fail("No IOOBE, negative length.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ sb = new StringBuilder("abcde");
+ assertEquals("abcde", sb.toString());
+ sb.setLength(1);
+ sb.append('g');
+ assertEquals("ag", sb.toString());
+
+ sb = new StringBuilder("abcde");
+ sb.setLength(3);
+ sb.append('g');
+ assertEquals("abcg", sb.toString());
+
+ sb = new StringBuilder("abcde");
+ sb.setLength(2);
+ try {
+ sb.charAt(3);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ sb = new StringBuilder();
+ sb.append("abcdefg");
+ sb.setLength(2);
+ sb.setLength(5);
+ for (int i = 2; i < 5; i++) {
+ assertEquals(0, sb.charAt(i));
+ }
+
+ sb = new StringBuilder();
+ sb.append("abcdefg");
+ sb.delete(2, 4);
+ sb.setLength(7);
+ assertEquals('a', sb.charAt(0));
+ assertEquals('b', sb.charAt(1));
+ assertEquals('e', sb.charAt(2));
+ assertEquals('f', sb.charAt(3));
+ assertEquals('g', sb.charAt(4));
+ for (int i = 5; i < 7; i++) {
+ assertEquals(0, sb.charAt(i));
+ }
+
+ sb = new StringBuilder();
+ sb.append("abcdefg");
+ sb.replace(2, 5, "z");
+ sb.setLength(7);
+ for (int i = 5; i < 7; i++) {
+ assertEquals(0, sb.charAt(i));
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.subSequence(int, int)
+ */
+ public void test_subSequenceII() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ CharSequence ss = sb.subSequence(0, 5);
+ assertEquals("01234", ss.toString());
+
+ ss = sb.subSequence(0, 0);
+ assertEquals("", ss.toString());
+
+ try {
+ sb.subSequence(-1, 1);
+ fail("No IOOBE, negative start.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.subSequence(0, -1);
+ fail("No IOOBE, negative end.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.subSequence(0, fixture.length() + 1);
+ fail("No IOOBE, end > length.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.subSequence(3, 2);
+ fail("No IOOBE, start > end.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.substring(int)
+ */
+ public void test_substringI() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ String ss = sb.substring(0);
+ assertEquals(fixture, ss);
+
+ ss = sb.substring(10);
+ assertEquals("", ss);
+
+ try {
+ sb.substring(-1);
+ fail("No SIOOBE, negative start.");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.substring(0, -1);
+ fail("No SIOOBE, negative end.");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.substring(fixture.length() + 1);
+ fail("No SIOOBE, start > length.");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.substring(int, int)
+ */
+ public void test_substringII() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ String ss = sb.substring(0, 5);
+ assertEquals("01234", ss);
+
+ ss = sb.substring(0, 0);
+ assertEquals("", ss);
+
+ try {
+ sb.substring(-1, 1);
+ fail("No SIOOBE, negative start.");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.substring(0, -1);
+ fail("No SIOOBE, negative end.");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.substring(0, fixture.length() + 1);
+ fail("No SIOOBE, end > length.");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ sb.substring(3, 2);
+ fail("No SIOOBE, start > end.");
+ } catch (StringIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.lang.StringBuilder.toString()'
+ */
+ public void test_toString() throws Exception {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertEquals(fixture, sb.toString());
+
+ sb.setLength(0);
+ sb.append("abcde");
+ assertEquals("abcde", sb.toString());
+ sb.setLength(1000);
+ byte[] bytes = sb.toString().getBytes("GB18030");
+ for (int i = 5; i < bytes.length; i++) {
+ assertEquals(0, bytes[i]);
+ }
+
+ sb.setLength(5);
+ sb.append("fghij");
+ assertEquals("abcdefghij", sb.toString());
+ }
+
+ /**
+ * java.lang.StringBuilder.trimToSize()'
+ */
+ public void test_trimToSize() {
+ final String fixture = "0123456789";
+ StringBuilder sb = new StringBuilder(fixture);
+ assertTrue(sb.capacity() > fixture.length());
+ assertEquals(fixture.length(), sb.length());
+ assertEquals(fixture, sb.toString());
+ int prevCapacity = sb.capacity();
+ sb.trimToSize();
+ assertTrue(prevCapacity > sb.capacity());
+ assertEquals(fixture.length(), sb.length());
+ assertEquals(fixture, sb.toString());
+ }
+
+ // comparator for StringBuilder objects
+ /*
+ private static final SerializableAssert STRING_BILDER_COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ StringBuilder init = (StringBuilder) initial;
+ StringBuilder desr = (StringBuilder) deserialized;
+
+ assertEquals("toString", init.toString(), desr.toString());
+ }
+ };
+ */
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ // SerializationTest.verifySelf(new StringBuilder("0123456789"),
+ // STRING_BILDER_COMPARATOR);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ //SerializationTest.verifyGolden(this, new StringBuilder("0123456789"),
+ // STRING_BILDER_COMPARATOR);
+ }
+
+ private static final class Fixture {
+ static final Fixture INSTANCE = new Fixture();
+
+ private Fixture() {
+ super();
+ }
+
+ @Override
+ public String toString() {
+ return "fixture";
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringIndexOutOfBoundsExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringIndexOutOfBoundsExceptionTest.java
new file mode 100644
index 0000000..6bdaa3a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringIndexOutOfBoundsExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class StringIndexOutOfBoundsExceptionTest extends TestCase {
+
+ /**
+ * java.lang.StringIndexOutOfBoundsException#StringIndexOutOfBoundsException()
+ */
+ public void test_Constructor() {
+ StringIndexOutOfBoundsException e = new StringIndexOutOfBoundsException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.StringIndexOutOfBoundsException#StringIndexOutOfBoundsException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ StringIndexOutOfBoundsException e = new StringIndexOutOfBoundsException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java
new file mode 100644
index 0000000..1b3659d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java
@@ -0,0 +1,697 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Constructor;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.SortedMap;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for the class {@link String}.
+ */
+public class StringTest extends TestCase {
+
+ private static final Constructor<String> UNSAFE_CONSTRUCTOR;
+
+ static {
+ Constructor<String> uc;
+ try {
+ uc = String.class.getDeclaredConstructor(new Class[] { int.class,
+ int.class, char[].class });
+ uc.setAccessible(true);
+ } catch (Exception e) {
+ uc = null;
+ }
+ UNSAFE_CONSTRUCTOR = uc;
+ }
+
+ private static String newString(int start, int len, char[] data) throws Exception {
+ if (UNSAFE_CONSTRUCTOR == null) {
+ return new String(data, start, len);
+ }
+
+ return UNSAFE_CONSTRUCTOR.newInstance(Integer.valueOf(start), Integer.valueOf(len),
+ data);
+ }
+
+ public void test_contains() {
+ assertTrue("aabc".contains("abc"));
+ assertTrue("abcd".contains("abc"));
+ assertFalse("abcd".contains("cba"));
+ }
+
+ public void test_charAt() {
+ assertTrue("abcd".charAt(0) == 'a');
+ assertTrue("abcd".charAt(3) == 'd');
+ }
+
+ public void test_StartsWith() {
+ assertTrue("abcd".startsWith("abc"));
+ assertFalse("abcd".startsWith("aabc"));
+ }
+
+ public void test_EndsWith() {
+ assertTrue("abcd".endsWith("bcd"));
+ assertFalse("abcd".endsWith("bcde"));
+ }
+
+ public void test_CASE_INSENSITIVE_ORDER() {
+ String s1 = "ABCDEFG";
+ String s2 = "abcdefg";
+
+ assertTrue(String.CASE_INSENSITIVE_ORDER.compare(s1, s2) == 0);
+ }
+
+ public void test_Constructor() {
+ assertEquals("Created incorrect string", "", new String());
+ }
+
+ public void test_Constructor$B() {
+ assertEquals("Failed to create string", "HelloWorld", new String(
+ "HelloWorld".getBytes()));
+ }
+
+ @SuppressWarnings("deprecation")
+ public void test_Constructor$BI() {
+ String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0);
+ assertEquals("Incorrect string returned: " + s, "ABCDE", s);
+ s = new String(new byte[] { 65, 66, 67, 68, 69 }, 1);
+ assertFalse("Did not use nonzero hibyte", s.equals("ABCDE"));
+ }
+
+ public void test_Constructor$BII() {
+ byte[] hwba = "HelloWorld".getBytes();
+ assertEquals("Failed to create string", "HelloWorld", new String(hwba,
+ 0, hwba.length));
+
+ try {
+ new String(new byte[0], 0, Integer.MAX_VALUE);
+ fail("No IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void test_Constructor$BIII() {
+ String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 1, 3);
+ assertEquals("Incorrect string returned: " + s, "BCD", s);
+ s = new String(new byte[] { 65, 66, 67, 68, 69 }, 1, 0, 5);
+ assertFalse("Did not use nonzero hibyte", s.equals("ABCDE"));
+ }
+
+ public void test_Constructor$BIILjava_lang_String() throws Exception {
+ String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, "8859_1");
+ assertEquals("Incorrect string returned: " + s, "ABCDE", s);
+
+ try {
+ new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, "");
+ fail("Should throw UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e) {
+ //expected
+ }
+ }
+
+ public void test_Constructor$BLjava_lang_String() throws Exception {
+ String s = new String(new byte[] { 65, 66, 67, 68, 69 }, "8859_1");
+ assertEquals("Incorrect string returned: " + s, "ABCDE", s);
+ }
+
+ public void test_Constructor$C() {
+ assertEquals("Failed Constructor test", "World", new String(new char[] {
+ 'W', 'o', 'r', 'l', 'd' }));
+ }
+
+ public void test_Constructor$CII() throws Exception {
+ char[] buf = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+ String s = new String(buf, 0, buf.length);
+ assertEquals("Incorrect string created", "HelloWorld", s);
+
+ try {
+ new String(new char[0], 0, Integer.MAX_VALUE);
+ fail("No IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_ConstructorLjava_lang_String() {
+ String s = new String("Hello World");
+ assertEquals("Failed to construct correct string", "Hello World", s);
+ }
+
+ public void test_ConstructorLjava_lang_StringBuffer() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("HelloWorld");
+ assertEquals("Created incorrect string", "HelloWorld", new String(sb));
+ }
+
+ public void test_ConstructorLjava_lang_StringBuilder() {
+ StringBuilder sb = new StringBuilder(32);
+ sb.append("HelloWorld");
+ assertEquals("HelloWorld", new String(sb));
+
+ try {
+ new String((StringBuilder) null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_Constructor$III() {
+ assertEquals("HelloWorld", new String(new int[] { 'H', 'e', 'l', 'l',
+ 'o', 'W', 'o', 'r', 'l', 'd' }, 0, 10));
+ assertEquals("Hello", new String(new int[] { 'H', 'e', 'l', 'l', 'o',
+ 'W', 'o', 'r', 'l', 'd' }, 0, 5));
+ assertEquals("World", new String(new int[] { 'H', 'e', 'l', 'l', 'o',
+ 'W', 'o', 'r', 'l', 'd' }, 5, 5));
+ assertEquals("", new String(new int[] { 'H', 'e', 'l', 'l', 'o', 'W',
+ 'o', 'r', 'l', 'd' }, 5, 0));
+
+ assertEquals("\uD800\uDC00", new String(new int[] { 0x010000 }, 0, 1));
+ assertEquals("\uD800\uDC00a\uDBFF\uDFFF", new String(new int[] {
+ 0x010000, 'a', 0x010FFFF }, 0, 3));
+
+ try {
+ new String((int[]) null, 0, 1);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ new String(new int[] { 'a', 'b' }, -1, 2);
+ fail("No IOOBE, negative offset");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ new String(new int[] { 'a', 'b' }, 0, -1);
+ fail("No IOOBE, negative count");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ new String(new int[] { 'a', 'b' }, 0, -1);
+ fail("No IOOBE, negative count");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ new String(new int[] { 'a', 'b' }, 0, 3);
+ fail("No IOOBE, too large");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_contentEqualsLjava_lang_CharSequence() throws Exception {
+ String s = "abc";
+ assertTrue(s.contentEquals((CharSequence) new StringBuffer("abc")));
+ assertFalse(s.contentEquals((CharSequence) new StringBuffer("def")));
+ assertFalse(s.contentEquals((CharSequence) new StringBuffer("ghij")));
+
+ s = newString(1, 3, "_abc_".toCharArray());
+ assertTrue(s.contentEquals((CharSequence) new StringBuffer("abc")));
+ assertFalse(s.contentEquals((CharSequence) new StringBuffer("def")));
+ assertFalse(s.contentEquals((CharSequence) new StringBuffer("ghij")));
+
+ try {
+ s.contentEquals((CharSequence) null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ @SuppressWarnings("nls")
+ public void test_boolean_contentEquals_StringBuffer() throws Exception {
+ String s = "abc";
+ assertTrue(s.contentEquals(new StringBuffer("abc")));
+ assertFalse(s.contentEquals(new StringBuffer("def")));
+ assertFalse(s.contentEquals(new StringBuffer("ghij")));
+
+ s = newString(1, 3, "_abc_".toCharArray());
+ assertTrue(s.contentEquals(new StringBuffer("abc")));
+ assertFalse(s.contentEquals(new StringBuffer("def")));
+ assertFalse(s.contentEquals(new StringBuffer("ghij")));
+
+ try {
+ s.contentEquals((StringBuffer) null);
+ fail("Should throw a NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ @SuppressWarnings("cast")
+ public void test_containsLjava_lang_CharSequence() throws Exception {
+ String s = "abcdefghijklmnopqrstuvwxyz";
+ assertTrue(s.contains((CharSequence) new StringBuffer("abc")));
+ assertTrue(s.contains((CharSequence) new StringBuffer("def")));
+ assertFalse(s.contains((CharSequence) new StringBuffer("ac")));
+
+ s = newString(1, 26, "_abcdefghijklmnopqrstuvwxyz_".toCharArray());
+ assertTrue(s.contains((CharSequence) new StringBuffer("abc")));
+ assertTrue(s.contains((CharSequence) new StringBuffer("def")));
+ assertFalse(s.contains((CharSequence) new StringBuffer("ac")));
+
+ try {
+ s.contentEquals((CharSequence) null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_offsetByCodePoints_II() throws Exception {
+ int result = new String("a\uD800\uDC00b").offsetByCodePoints(0, 2);
+ assertEquals(3, result);
+
+ result = new String("abcd").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ result = new String("a\uD800\uDC00b").offsetByCodePoints(0, 3);
+ assertEquals(4, result);
+
+ result = new String("a\uD800\uDC00b").offsetByCodePoints(3, -1);
+ assertEquals(1, result);
+
+ result = new String("a\uD800\uDC00b").offsetByCodePoints(3, 0);
+ assertEquals(3, result);
+
+ result = new String("\uD800\uDC00bc").offsetByCodePoints(3, 0);
+ assertEquals(3, result);
+
+ result = new String("a\uDC00bc").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ result = new String("a\uD800bc").offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray())
+ .offsetByCodePoints(0, 2);
+ assertEquals(3, result);
+
+ result = newString(2, 4, "__abcd__".toCharArray()).offsetByCodePoints(
+ 3, -1);
+ assertEquals(2, result);
+
+ result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray())
+ .offsetByCodePoints(0, 3);
+ assertEquals(4, result);
+
+ result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray())
+ .offsetByCodePoints(3, -1);
+ assertEquals(1, result);
+
+ result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray())
+ .offsetByCodePoints(3, 0);
+ assertEquals(3, result);
+
+ result = newString(2, 4, "__\uD800\uDC00bc__".toCharArray())
+ .offsetByCodePoints(3, 0);
+ assertEquals(3, result);
+
+ result = newString(2, 4, "__a\uDC00bc__".toCharArray())
+ .offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ result = newString(2, 4, "__a\uD800bc__".toCharArray())
+ .offsetByCodePoints(3, -1);
+ assertEquals(2, result);
+
+ String s = "abc";
+ try {
+ s.offsetByCodePoints(-1, 1);
+ fail("No IOOBE for negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.offsetByCodePoints(0, 4);
+ fail("No IOOBE for offset that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.offsetByCodePoints(3, -4);
+ fail("No IOOBE for offset that's too small.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.offsetByCodePoints(3, 1);
+ fail("No IOOBE for index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.offsetByCodePoints(4, -1);
+ fail("No IOOBE for index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ s = newString(2, 3, "__abc__".toCharArray());
+ try {
+ s.offsetByCodePoints(-1, 1);
+ fail("No IOOBE for negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.offsetByCodePoints(0, 4);
+ fail("No IOOBE for offset that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.offsetByCodePoints(3, -4);
+ fail("No IOOBE for offset that's too small.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.offsetByCodePoints(3, 1);
+ fail("No IOOBE for index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.offsetByCodePoints(4, -1);
+ fail("No IOOBE for index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_codePointAtI() throws Exception {
+ String s = "abc";
+ assertEquals('a', s.codePointAt(0));
+ assertEquals('b', s.codePointAt(1));
+ assertEquals('c', s.codePointAt(2));
+
+ s = newString(2, 3, "__abc__".toCharArray());
+ assertEquals('a', s.codePointAt(0));
+ assertEquals('b', s.codePointAt(1));
+ assertEquals('c', s.codePointAt(2));
+
+ s = "\uD800\uDC00";
+ assertEquals(0x10000, s.codePointAt(0));
+ assertEquals('\uDC00', s.codePointAt(1));
+
+ s = newString(2, 2, "__\uD800\uDC00__".toCharArray());
+ assertEquals(0x10000, s.codePointAt(0));
+ assertEquals('\uDC00', s.codePointAt(1));
+
+ s = "abc";
+ try {
+ s.codePointAt(-1);
+ fail("No IOOBE on negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointAt(s.length());
+ fail("No IOOBE on index equal to length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointAt(s.length() + 1);
+ fail("No IOOBE on index greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ s = newString(2, 3, "__abc__".toCharArray());
+ try {
+ s.codePointAt(-1);
+ fail("No IOOBE on negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointAt(s.length());
+ fail("No IOOBE on index equal to length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointAt(s.length() + 1);
+ fail("No IOOBE on index greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_codePointBeforeI() throws Exception {
+ String s = "abc";
+ assertEquals('a', s.codePointBefore(1));
+ assertEquals('b', s.codePointBefore(2));
+ assertEquals('c', s.codePointBefore(3));
+
+ s = newString(2, 3, "__abc__".toCharArray());
+ assertEquals('a', s.codePointBefore(1));
+ assertEquals('b', s.codePointBefore(2));
+ assertEquals('c', s.codePointBefore(3));
+
+ s = "\uD800\uDC00";
+ assertEquals(0x10000, s.codePointBefore(2));
+ assertEquals('\uD800', s.codePointBefore(1));
+
+ s = newString(2, 2, "__\uD800\uDC00__".toCharArray());
+ assertEquals(0x10000, s.codePointBefore(2));
+ assertEquals('\uD800', s.codePointBefore(1));
+
+ s = "abc";
+ try {
+ s.codePointBefore(0);
+ fail("No IOOBE on zero index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointBefore(-1);
+ fail("No IOOBE on negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointBefore(s.length() + 1);
+ fail("No IOOBE on index greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ s = newString(2, 3, "__abc__".toCharArray());
+ try {
+ s.codePointBefore(0);
+ fail("No IOOBE on zero index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointBefore(-1);
+ fail("No IOOBE on negative index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointBefore(s.length() + 1);
+ fail("No IOOBE on index greater than length.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_codePointCountII() throws Exception {
+ assertEquals(1, "\uD800\uDC00".codePointCount(0, 2));
+ assertEquals(1, "\uD800\uDC01".codePointCount(0, 2));
+ assertEquals(1, "\uD801\uDC01".codePointCount(0, 2));
+ assertEquals(1, "\uDBFF\uDFFF".codePointCount(0, 2));
+
+ assertEquals(3, "a\uD800\uDC00b".codePointCount(0, 4));
+ assertEquals(4, "a\uD800\uDC00b\uD800".codePointCount(0, 5));
+
+ assertEquals(1, newString(2, 2, "__\uD800\uDC00__".toCharArray()).codePointCount(0, 2));
+ assertEquals(1, newString(2, 2, "__\uD800\uDC01__".toCharArray()).codePointCount(0, 2));
+ assertEquals(1, newString(2, 2, "__\uD801\uDC01__".toCharArray()).codePointCount(0, 2));
+ assertEquals(1, newString(2, 2, "__\uDBFF\uDFFF__".toCharArray()).codePointCount(0, 2));
+
+ assertEquals(3, newString(2, 4, "__a\uD800\uDC00b__".toCharArray()).codePointCount(0, 4));
+ assertEquals(4, newString(2, 5, "__a\uD800\uDC00b\uD800__".toCharArray()).codePointCount(0, 5));
+
+ String s = "abc";
+ try {
+ s.codePointCount(-1, 2);
+ fail("No IOOBE for negative begin index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointCount(0, 4);
+ fail("No IOOBE for end index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointCount(3, 2);
+ fail("No IOOBE for begin index larger than end index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ s = newString(2, 3, "__abc__".toCharArray());
+ try {
+ s.codePointCount(-1, 2);
+ fail("No IOOBE for negative begin index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointCount(0, 4);
+ fail("No IOOBE for end index that's too large.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ s.codePointCount(3, 2);
+ fail("No IOOBE for begin index larger than end index.");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ public void test_ConstructorBIIL() throws Exception {
+ // can construct normally
+ new String(new byte[8], 0, 4, Charset.defaultCharset());
+ new String(new byte[8], 8, 0, Charset.defaultCharset());
+ new String(new byte[0], 0, 0, Charset.defaultCharset());
+ // throws exceptions
+ try {
+ new String(new byte[8], 0, 9, Charset.defaultCharset());
+ fail("should throw StringIndexOutOfBoundsException");
+ } catch (StringIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ new String(new byte[8], 9, 0, Charset.defaultCharset());
+ fail("should throw StringIndexOutOfBoundsException");
+ } catch (StringIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ new String(new byte[8], -1, 0, Charset.defaultCharset());
+ fail("should throw StringIndexOutOfBoundsException");
+ } catch (StringIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ new String(new byte[8], 9, -1, Charset.defaultCharset());
+ fail("should throw StringIndexOutOfBoundsException");
+ } catch (StringIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ new String(null, -1, 0, Charset.defaultCharset());
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+ try {
+ new String(null, 0, -1, Charset.defaultCharset());
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+ try {
+ new String(null, 0, 9, Charset.defaultCharset());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new String(null, 0, 0, Charset.defaultCharset());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new String(null, -1, 0, (Charset) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new String(new byte[8], -1, 0, (Charset) null);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+ try {
+ new String(new byte[8], 0, 9, (Charset) null);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+ try {
+ new String(new byte[8], 0, 4, (Charset) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void test_ConstructorBL() throws Exception {
+ new String(new byte[8], Charset.defaultCharset());
+ try {
+ new String(new byte[8], (Charset) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new String(new byte[0], (Charset) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new String(null, Charset.defaultCharset());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ new String(new byte[0], Charset.defaultCharset());
+ }
+
+ public void test_isEmpty() throws Exception {
+ assertTrue(new String(new byte[0], Charset.defaultCharset()).isEmpty());
+ assertTrue(new String(new byte[8], Charset.defaultCharset()).substring(0, 0).isEmpty());
+ }
+
+ public void test_getBytesLCharset() throws Exception {
+ byte[] emptyBytes = new byte[0];
+ byte[] someBytes = new byte[] { 'T', 'h', 'i', 's', ' ', ' ', 'i', 's', ' ', 't', 'e', 's', 't', ' ', 'b', 'y', 't', 'e', 's' };
+ assertEquals(0, new String(emptyBytes, Charset.defaultCharset()).getBytes(Charset.defaultCharset()).length);
+ try {
+ new String(emptyBytes, Charset.defaultCharset()).getBytes((Charset) null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertTrue(bytesEquals(someBytes, new String(someBytes, Charset.defaultCharset()).getBytes(Charset.defaultCharset())));
+ SortedMap<String, Charset> charsets = Charset.availableCharsets();
+ }
+
+ boolean bytesEquals(byte[] bytes1, byte[] bytes2) {
+ return Arrays.toString(bytes1).equals(Arrays.toString(bytes2));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/SystemTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/SystemTest.java
new file mode 100644
index 0000000..05a02c3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/SystemTest.java
@@ -0,0 +1,413 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Map;
+import java.util.Properties;
+
+public class SystemTest extends junit.framework.TestCase {
+
+ static boolean flag = false;
+
+ static boolean ranFinalize = false;
+
+ /**
+ * java.lang.System#setIn(java.io.InputStream)
+ */
+ public void test_setInLjava_io_InputStream() {
+ InputStream orgIn = System.in;
+ InputStream in = new ByteArrayInputStream(new byte[0]);
+ System.setIn(in);
+ assertTrue("in not set", System.in == in);
+ System.setIn(orgIn);
+ }
+
+ /**
+ * java.lang.System#setOut(java.io.PrintStream)
+ */
+ public void test_setOutLjava_io_PrintStream() {
+ PrintStream orgOut = System.out;
+ PrintStream out = new PrintStream(new ByteArrayOutputStream());
+ System.setOut(out);
+ assertTrue("out not set", System.out == out);
+ System.setOut(orgOut);
+ }
+
+ /**
+ * java.lang.System#setErr(java.io.PrintStream)
+ */
+ public void test_setErrLjava_io_PrintStream() {
+ PrintStream orgErr = System.err;
+ PrintStream err = new PrintStream(new ByteArrayOutputStream());
+ System.setErr(err);
+ assertTrue("err not set", System.err == err);
+ System.setErr(orgErr);
+ }
+
+ /**
+ * java.lang.System#arraycopy(java.lang.Object, int,
+ *java.lang.Object, int, int)
+ */
+ public void test_arraycopyLjava_lang_ObjectILjava_lang_ObjectII() {
+ // Test for method void java.lang.System.arraycopy(java.lang.Object,
+ // int, java.lang.Object, int, int)
+ Integer a[] = new Integer[20];
+ Integer b[] = new Integer[20];
+ int i = 0;
+ while (i < a.length) {
+ a[i] = new Integer(i);
+ ++i;
+ }
+ System.arraycopy(a, 0, b, 0, a.length);
+ for (i = 0; i < a.length; i++)
+ assertTrue("Copied elements incorrectly", a[i].equals(b[i]));
+
+ /* Non primitive array types don't need to be identical */
+ String[] source1 = new String[] { "element1" };
+ Object[] dest1 = new Object[1];
+ System.arraycopy(source1, 0, dest1, 0, dest1.length);
+ assertTrue("Invalid copy 1", dest1[0] == source1[0]);
+
+ char[][] source = new char[][] { { 'H', 'e', 'l', 'l', 'o' },
+ { 'W', 'o', 'r', 'l', 'd' } };
+ char[][] dest = new char[2][];
+ System.arraycopy(source, 0, dest, 0, dest.length);
+ assertTrue("Invalid copy 2", dest[0] == source[0]
+ && dest[1] == source[1]);
+ }
+
+ /**
+ * java.lang.System#currentTimeMillis()
+ */
+ public void test_currentTimeMillis() {
+ // Test for method long java.lang.System.currentTimeMillis()
+ long firstRead = System.currentTimeMillis();
+ try {
+ Thread.sleep(150);
+ } catch (InterruptedException e) {
+ }
+ long secondRead = System.currentTimeMillis();
+ assertTrue("Incorrect times returned: " + firstRead + ", "
+ + secondRead, firstRead < secondRead);
+ }
+
+ /**
+ * java.lang.System#exit(int)
+ */
+ public void test_exitI() {
+ // Test for method void java.lang.System.exit(int)
+ // Tested in destructive test: Test_System_Exit ???
+ }
+
+ /**
+ * java.lang.System#getProperties()
+ */
+ public void test_getProperties() {
+ // Test for method java.util.Properties java.lang.System.getProperties()
+ Properties p = System.getProperties();
+
+ // Ensure spec'ed properties are non-null. See System.getProperties()
+ // spec.
+ String[] props = { "java.version", "java.vendor", "java.vendor.url",
+ "java.home", "java.vm.specification.version",
+ "java.vm.specification.vendor", "java.vm.specification.name",
+ "java.vm.version", "java.vm.vendor", "java.vm.name",
+ "java.specification.name", "java.specification.vendor",
+ "java.specification.name", "java.class.version",
+ "java.class.path", "java.ext.dirs", "os.name", "os.arch",
+ "os.version", "file.separator", "path.separator",
+ "line.separator", "user.name", "user.home", "user.dir", };
+ for (int i = 0; i < props.length; i++) {
+ assertNotNull(props[i], System.getProperty(props[i]));
+ }
+ }
+
+ /**
+ * java.lang.System#getProperty(java.lang.String)
+ */
+ public void test_getPropertyLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.lang.System.getProperty(java.lang.String)
+
+ boolean is8859_1 = true;
+ String encoding = System.getProperty("file.encoding");
+ byte[] bytes = new byte[128];
+ char[] chars = new char[128];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = (byte) (i + 128);
+ chars[i] = (char) (i + 128);
+ }
+ String charResult = new String(bytes);
+ byte[] byteResult = new String(chars).getBytes();
+ if (charResult.length() == 128 && byteResult.length == 128) {
+ for (int i = 0; i < bytes.length; i++) {
+ if (charResult.charAt(i) != (char) (i + 128)
+ || byteResult[i] != (byte) (i + 128))
+ is8859_1 = false;
+ }
+ } else
+ is8859_1 = false;
+ String[] possibles = new String[] { "ISO8859_1", "8859_1", "ISO8859-1",
+ "ISO-8859-1", "ISO_8859-1", "ISO_8859-1:1978", "ISO-IR-100",
+ "LATIN1", "CSISOLATIN1" };
+ boolean found8859_1 = false;
+ for (int i = 0; i < possibles.length; i++) {
+ if (possibles[i].equals(encoding)) {
+ found8859_1 = true;
+ break;
+ }
+ }
+ assertTrue("Wrong encoding: " + encoding, !is8859_1 || found8859_1);
+ }
+
+ /**
+ * java.lang.System#getProperty(java.lang.String)
+ * Tests that there are no extra path separator in boot class path.
+ * Regression test for HARMONY-3298
+ */
+ public void test_getProperty_bootClassPath() {
+ String bootClassPath = System.getProperty("org.apache.harmony.boot.class.path");
+
+ if (bootClassPath == null) {
+ bootClassPath = System.getProperty("sun.boot.class.path");
+ }
+
+ if (bootClassPath != null
+ && (bootClassPath.indexOf(File.pathSeparator + File.pathSeparator) >= 0)) {
+ fail("Boot class path contains extra path separator: " + bootClassPath);
+ }
+ }
+
+ /**
+ * java.lang.System#getProperty(java.lang.String, java.lang.String)
+ */
+ public void test_getPropertyLjava_lang_StringLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.lang.System.getProperty(java.lang.String, java.lang.String)
+ assertTrue(!System.getProperty("java.version", "99999").equals("99999"));
+ assertEquals("Failed to return correct property value", "bogus", System
+ .getProperty("bogus.prop", "bogus"));
+ }
+
+ /**
+ * java.lang.System#setProperty(java.lang.String, java.lang.String)
+ */
+ public void test_setPropertyLjava_lang_StringLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.lang.System.setProperty(java.lang.String, java.lang.String)
+
+ assertNull("Failed to return null", System.setProperty("testing",
+ "value1"));
+ assertTrue("Failed to return old value", System.setProperty("testing",
+ "value2") == "value1");
+ assertTrue("Failed to find value",
+ System.getProperty("testing") == "value2");
+
+ boolean exception = false;
+ try {
+ System.setProperty("", "default");
+ } catch (IllegalArgumentException e) {
+ exception = true;
+ }
+ assertTrue("Expected IllegalArgumentException", exception);
+ }
+
+ /**
+ * java.lang.System#getSecurityManager()
+ */
+ public void test_getSecurityManager() {
+ // Test for method java.lang.SecurityManager
+ // java.lang.System.getSecurityManager()
+ assertNull("Returned incorrect SecurityManager", System
+ .getSecurityManager());
+ }
+
+ /**
+ * java.lang.System#identityHashCode(java.lang.Object)
+ */
+ public void test_identityHashCodeLjava_lang_Object() {
+ // Test for method int
+ // java.lang.System.identityHashCode(java.lang.Object)
+ Object o = new Object();
+ String s = "Gabba";
+ assertEquals("Nonzero returned for null",
+ 0, System.identityHashCode(null));
+ assertTrue("Nonequal has returned for Object", System
+ .identityHashCode(o) == o.hashCode());
+ assertTrue("Same as usual hash returned for String", System
+ .identityHashCode(s) != s.hashCode());
+ }
+
+ /**
+ * java.lang.System#runFinalization()
+ */
+ public void test_runFinalization() {
+ // Test for method void java.lang.System.runFinalization()
+
+ flag = true;
+ createInstance();
+ int count = 10;
+ // the gc below likely bogosifies the test, but will have to do for
+ // the moment
+ while (!ranFinalize && count-- > 0) {
+ System.gc();
+ System.runFinalization();
+ }
+ assertTrue("Failed to run finalization", ranFinalize);
+ }
+
+ /**
+ * java.lang.System#runFinalizersOnExit(boolean)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_runFinalizersOnExitZ() {
+ // Can we call the method at least?
+ System.runFinalizersOnExit(false);
+ }
+
+ /**
+ * java.lang.System#setProperties(java.util.Properties)
+ */
+ public void test_setPropertiesLjava_util_Properties() {
+ // Test for method void
+ // java.lang.System.setProperties(java.util.Properties)
+
+ Properties orgProps = System.getProperties();
+ java.util.Properties tProps = new java.util.Properties();
+ tProps.put("test.prop", "this is a test property");
+ tProps.put("bogus.prop", "bogus");
+ System.setProperties(tProps);
+ try {
+ assertEquals("Failed to set properties", "this is a test property", System.getProperties()
+ .getProperty("test.prop"));
+ } finally {
+ // restore the original properties
+ System.setProperties(orgProps);
+ }
+ }
+
+ //Regression Test for Harmony-2356
+ public void testEnvUnmodifiable() {
+ Map map = System.getenv();
+ try {
+ map.containsKey(null);
+ fail("Should throw NullPointerExcepiton.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ map.containsKey(new Integer(10));
+ fail("Should throw ClassCastException.");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ try {
+ map.containsValue(null);
+ fail("Should throw NullPointerExcepiton.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ map.containsValue(new Integer(10));
+ fail("Should throw ClassCastException.");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ try {
+ map.get(null);
+ fail("Should throw NullPointerExcepiton.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ map.get(new Integer(10));
+ fail("Should throw ClassCastException.");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ try {
+ map.put(null, "AAA");
+ fail("Should throw UnsupportedOperationExcepiton.");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ try {
+ map.put("AAA", new Integer(10));
+ fail("Should throw UnsupportedOperationException.");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ try {
+ map.put("AAA", "BBB");
+ fail("Should throw UnsupportedOperationException.");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ try {
+ map.clear();
+ fail("Should throw UnsupportedOperationException.");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ try {
+ map.remove(null);
+ // Android isn't as strict about requiring this exception; no modification takes place anyway
+ // fail("Should throw UnsupportedOperationException.");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ }
+
+ @Override
+ protected void setUp() {
+ flag = false;
+ ranFinalize = false;
+ }
+
+ protected SystemTest createInstance() {
+ return new SystemTest("FT");
+ }
+
+ @Override
+ protected void finalize() {
+ if (flag)
+ ranFinalize = true;
+ }
+
+ public SystemTest() {
+ }
+
+ public SystemTest(String name) {
+ super(name);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadDeathTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadDeathTest.java
new file mode 100644
index 0000000..1d21dd3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadDeathTest.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+public class ThreadDeathTest extends junit.framework.TestCase {
+
+ /**
+ * java.lang.ThreadDeath#ThreadDeath()
+ */
+ public void test_Constructor() {
+ ThreadDeath td = new ThreadDeath();
+ assertNull(td.getCause());
+ assertNull(td.getMessage());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadGroupTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadGroupTest.java
new file mode 100644
index 0000000..a437939
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadGroupTest.java
@@ -0,0 +1,795 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.util.Vector;
+
+public class ThreadGroupTest extends junit.framework.TestCase {
+
+ private TestThreadDefaultUncaughtExceptionHandler testThreadDefaultUncaughtExceptionHandler;
+ private ThreadGroup rootThreadGroup;
+ private ThreadGroup initialThreadGroup;
+ private Thread.UncaughtExceptionHandler originalThreadDefaultUncaughtExceptionHandler;
+
+ @Override
+ protected void setUp() {
+ initialThreadGroup = Thread.currentThread().getThreadGroup();
+ rootThreadGroup = initialThreadGroup;
+ while (rootThreadGroup.getParent() != null) {
+ rootThreadGroup = rootThreadGroup.getParent();
+ }
+
+ // When running as a CTS test Android will by default treat an uncaught exception as a
+ // fatal application error and kill the test. To avoid this the default
+ // UncaughtExceptionHandler is replaced for the duration of the test (if one exists). It
+ // also allows us to test that ultimately the default handler is called if a ThreadGroup's
+ // UncaughtExceptionHandler doesn't handle an exception.
+ originalThreadDefaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
+ testThreadDefaultUncaughtExceptionHandler = new TestThreadDefaultUncaughtExceptionHandler();
+ Thread.setDefaultUncaughtExceptionHandler(testThreadDefaultUncaughtExceptionHandler);
+ }
+
+ @Override
+ protected void tearDown() {
+ // Reset the uncaughtExceptionHandler to what it was when the test began.
+ Thread.setDefaultUncaughtExceptionHandler(originalThreadDefaultUncaughtExceptionHandler);
+ }
+
+ // Test for method java.lang.ThreadGroup(java.lang.String)
+ public void test_ConstructorLjava_lang_String() {
+ // Unfortunately we have to use other APIs as well as we test the constructor
+ ThreadGroup initial = initialThreadGroup;
+ final String name = "Test name";
+ ThreadGroup newGroup = new ThreadGroup(name);
+ assertTrue(
+ "Has to be possible to create a subgroup of current group using simple constructor",
+ newGroup.getParent() == initial);
+ assertTrue("Name has to be correct", newGroup.getName().equals(name));
+
+ // cleanup
+ newGroup.destroy();
+ }
+
+ // Test for method java.lang.ThreadGroup(java.lang.ThreadGroup, java.lang.String)
+ public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
+ // Unfortunately we have to use other APIs as well as we test the constructor
+ ThreadGroup newGroup = null;
+ try {
+ newGroup = new ThreadGroup(null, null);
+ } catch (NullPointerException e) {
+ }
+ assertNull("Can't create a ThreadGroup with a null parent", newGroup);
+
+ newGroup = new ThreadGroup(initialThreadGroup, null);
+ assertTrue("Has to be possible to create a subgroup of current group",
+ newGroup.getParent() == Thread.currentThread().getThreadGroup());
+
+ // Lets start all over
+ newGroup.destroy();
+
+ newGroup = new ThreadGroup(rootThreadGroup, "a name here");
+ assertTrue("Has to be possible to create a subgroup of root group",
+ newGroup.getParent() == rootThreadGroup);
+
+ // Lets start all over
+ newGroup.destroy();
+
+ try {
+ newGroup = new ThreadGroup(newGroup, "a name here");
+ } catch (IllegalThreadStateException e) {
+ newGroup = null;
+ }
+ assertNull("Can't create a subgroup of a destroyed group", newGroup);
+ }
+
+ // Test for method int java.lang.ThreadGroup.activeCount()
+ public void test_activeCount() {
+ ThreadGroup tg = new ThreadGroup("activeCount");
+ Thread t1 = new Thread(tg, new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ }
+ }
+ });
+ int count = tg.activeCount();
+ assertTrue("wrong active count: " + count, count == 0);
+ t1.start();
+ count = tg.activeCount();
+ assertTrue("wrong active count: " + count, count == 1);
+ t1.interrupt();
+ try {
+ t1.join();
+ } catch (InterruptedException e) {
+ }
+ // cleanup
+ tg.destroy();
+ }
+
+ // Test for method void java.lang.ThreadGroup.destroy()
+ public void test_destroy() {
+ final ThreadGroup originalCurrent = initialThreadGroup;
+ ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+ final int DEPTH = 4;
+ final Vector<ThreadGroup> subgroups = buildRandomTreeUnder(testRoot, DEPTH);
+
+ // destroy them all
+ testRoot.destroy();
+
+ for (int i = 0; i < subgroups.size(); i++) {
+ ThreadGroup child = subgroups.elementAt(i);
+ assertEquals("Destroyed child can't have children", 0, child.activeCount());
+ boolean passed = false;
+ try {
+ child.destroy();
+ } catch (IllegalThreadStateException e) {
+ passed = true;
+ }
+ assertTrue("Destroyed child can't be destroyed again", passed);
+ }
+
+ testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+ testRoot.setDaemon(true);
+
+ ThreadGroup child = new ThreadGroup(testRoot, "daemon child");
+
+ // If we destroy the last daemon's child, the daemon should get destroyed
+ // as well
+ child.destroy();
+
+ boolean passed = false;
+ try {
+ child.destroy();
+ } catch (IllegalThreadStateException e) {
+ passed = true;
+ }
+ assertTrue("Daemon should have been destroyed already", passed);
+
+ passed = false;
+ try {
+ testRoot.destroy();
+ } catch (IllegalThreadStateException e) {
+ passed = true;
+ }
+ assertTrue("Daemon parent should have been destroyed automatically",
+ passed);
+
+ assertTrue(
+ "Destroyed daemon's child should not be in daemon's list anymore",
+ !arrayIncludes(groups(testRoot), child));
+ assertTrue("Destroyed daemon should not be in parent's list anymore",
+ !arrayIncludes(groups(originalCurrent), testRoot));
+
+ testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+ testRoot.setDaemon(true);
+ Thread noOp = new Thread(testRoot, null, "no-op thread") {
+ @Override
+ public void run() {
+ }
+ };
+ noOp.start();
+
+ // Wait for the no-op thread to run inside daemon ThreadGroup
+ waitForThreadToDieUninterrupted(noOp);
+
+ passed = false;
+ try {
+ child.destroy();
+ } catch (IllegalThreadStateException e) {
+ passed = true;
+ }
+ assertTrue("Daemon group should have been destroyed already when last thread died", passed);
+
+ testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+ noOp = new Thread(testRoot, null, "no-op thread") {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ie) {
+ fail("Should not be interrupted");
+ }
+ }
+ };
+
+ // Has to execute the next lines in an interval < the sleep interval of the no-op thread
+ noOp.start();
+ passed = false;
+ try {
+ testRoot.destroy();
+ } catch (IllegalThreadStateException its) {
+ passed = true;
+ }
+ assertTrue("Can't destroy a ThreadGroup that has threads", passed);
+
+ // But after the thread dies, we have to be able to destroy the thread group
+ waitForThreadToDieUninterrupted(noOp);
+ passed = true;
+ try {
+ testRoot.destroy();
+ } catch (IllegalThreadStateException its) {
+ passed = false;
+ }
+ assertTrue("Should be able to destroy a ThreadGroup that has no threads", passed);
+ }
+
+ // Test for method java.lang.ThreadGroup.destroy()
+ public void test_destroy_subtest0() {
+ ThreadGroup group1 = new ThreadGroup("test_destroy_subtest0");
+ group1.destroy();
+ try {
+ new Thread(group1, "test_destroy_subtest0");
+ fail("should throw IllegalThreadStateException");
+ } catch (IllegalThreadStateException e) {
+ }
+ }
+
+ // Test for method int java.lang.ThreadGroup.getMaxPriority()
+ public void test_getMaxPriority() {
+ final ThreadGroup originalCurrent = initialThreadGroup;
+ ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+ boolean passed = true;
+ try {
+ testRoot.setMaxPriority(Thread.MIN_PRIORITY);
+ } catch (IllegalArgumentException iae) {
+ passed = false;
+ }
+ assertTrue("Should be able to set priority", passed);
+
+ assertTrue("New value should be the same as we set",
+ testRoot.getMaxPriority() == Thread.MIN_PRIORITY);
+
+ testRoot.destroy();
+ }
+
+ // Test for method java.lang.String java.lang.ThreadGroup.getName()
+ public void test_getName() {
+ final ThreadGroup originalCurrent = initialThreadGroup;
+ final String name = "Test group";
+ final ThreadGroup testRoot = new ThreadGroup(originalCurrent, name);
+
+ assertTrue("Setting a name&getting does not work", testRoot.getName().equals(name));
+
+ testRoot.destroy();
+ }
+
+ // Test for method java.lang.ThreadGroup java.lang.ThreadGroup.getParent()
+ public void test_getParent() {
+ final ThreadGroup originalCurrent = initialThreadGroup;
+ ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+ assertTrue("Parent is wrong", testRoot.getParent() == originalCurrent);
+
+ // Create some groups, nested some levels.
+ final int TOTAL_DEPTH = 5;
+ ThreadGroup current = testRoot;
+ Vector<ThreadGroup> groups = new Vector<ThreadGroup>();
+ // To maintain the invariant that a thread in the Vector is parent
+ // of the next one in the collection (and child of the previous one)
+ groups.addElement(testRoot);
+
+ for (int i = 0; i < TOTAL_DEPTH; i++) {
+ current = new ThreadGroup(current, "level " + i);
+ groups.addElement(current);
+ }
+
+ // Now we walk the levels down, checking if parent is ok
+ for (int i = 1; i < groups.size(); i++) {
+ current = groups.elementAt(i);
+ ThreadGroup previous = groups.elementAt(i - 1);
+ assertTrue("Parent is wrong", current.getParent() == previous);
+ }
+
+ testRoot.destroy();
+ }
+
+ // Test for method void java.lang.ThreadGroup.list()
+ public void test_list() {
+ final ThreadGroup originalCurrent = initialThreadGroup;
+ final ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+ // First save the original System.out
+ java.io.PrintStream originalOut = System.out;
+
+ try {
+ java.io.ByteArrayOutputStream contentsStream = new java.io.ByteArrayOutputStream(100);
+ java.io.PrintStream newOut = new java.io.PrintStream(contentsStream);
+
+ // We have to "redirect" System.out to test the method 'list'
+ System.setOut(newOut);
+
+ originalCurrent.list();
+
+ /*
+ * The output has to look like this:
+ *
+ * java.lang.ThreadGroup[name=main,maxpri=10] Thread[main,5,main]
+ * java.lang.ThreadGroup[name=Test group,maxpri=10]
+ */
+ String contents = new String(contentsStream.toByteArray());
+ boolean passed = (contents.indexOf("ThreadGroup[name=main") != -1) &&
+ (contents.indexOf("Thread[") != -1) &&
+ (contents.indexOf("ThreadGroup[name=Test group") != -1);
+ assertTrue("'list()' does not print expected contents. "
+ + "Result from list: "
+ + contents, passed);
+ // Do proper cleanup
+ testRoot.destroy();
+
+ } finally {
+ // No matter what, we need to restore the original System.out
+ System.setOut(originalOut);
+ }
+ }
+
+ // Test for method boolean java.lang.ThreadGroup.parentOf(java.lang.ThreadGroup)
+ public void test_parentOfLjava_lang_ThreadGroup() {
+ final ThreadGroup originalCurrent = initialThreadGroup;
+ final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+ "Test group");
+ final int DEPTH = 4;
+ buildRandomTreeUnder(testRoot, DEPTH);
+
+ final ThreadGroup[] allChildren = allGroups(testRoot);
+ for (ThreadGroup element : allChildren) {
+ assertTrue("Have to be parentOf all children", testRoot.parentOf(element));
+ }
+
+ assertTrue("Have to be parentOf itself", testRoot.parentOf(testRoot));
+
+ testRoot.destroy();
+ assertTrue("Parent can't have test group as subgroup anymore",
+ !arrayIncludes(groups(testRoot.getParent()), testRoot));
+ }
+
+ // Test for method boolean java.lang.ThreadGroup.isDaemon() and
+ // void java.lang.ThreadGroup.setDaemon(boolean)
+ public void test_setDaemon_isDaemon() {
+ final ThreadGroup originalCurrent = initialThreadGroup;
+ final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+ "Test group");
+
+ testRoot.setDaemon(true);
+ assertTrue("Setting daemon&getting does not work", testRoot.isDaemon());
+
+ testRoot.setDaemon(false);
+ assertTrue("Setting daemon&getting does not work", !testRoot.isDaemon());
+
+ testRoot.destroy();
+ }
+
+ /*
+ * java.lang.ThreadGroupt#setDaemon(boolean)
+ */
+ public void test_setDaemon_Parent_Child() {
+ ThreadGroup ptg = new ThreadGroup("Parent");
+ ThreadGroup ctg = new ThreadGroup(ptg, "Child");
+
+ ctg.setDaemon(true);
+ assertTrue(ctg.isDaemon());
+
+ ctg.setDaemon(false);
+ assertFalse(ctg.isDaemon());
+
+ ptg.setDaemon(true);
+ assertFalse(ctg.isDaemon());
+
+ ptg.setDaemon(false);
+ assertFalse(ctg.isDaemon());
+ }
+
+ // Test for method void java.lang.ThreadGroup.setMaxPriority(int)
+ public void test_setMaxPriorityI() {
+ final ThreadGroup originalCurrent = initialThreadGroup;
+ ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+ boolean passed;
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ int currentMax = testRoot.getMaxPriority();
+ testRoot.setMaxPriority(Thread.MAX_PRIORITY + 1);
+ passed = testRoot.getMaxPriority() == currentMax;
+ assertTrue(
+ "setMaxPriority: Any value higher than the current one is ignored. Before: "
+ + currentMax + " , after: " + testRoot.getMaxPriority(),
+ passed);
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ currentMax = testRoot.getMaxPriority();
+ testRoot.setMaxPriority(Thread.MIN_PRIORITY - 1);
+ passed = testRoot.getMaxPriority() == Thread.MIN_PRIORITY;
+ assertTrue(
+ "setMaxPriority: Any value smaller than MIN_PRIORITY is adjusted to MIN_PRIORITY. Before: "
+ + currentMax + " , after: " + testRoot.getMaxPriority(), passed);
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ testRoot.destroy();
+ testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+ // Create some groups, nested some levels. Each level will have maxPrio
+ // 1 unit smaller than the parent's. However, there can't be a group
+ // with priority < Thread.MIN_PRIORITY
+ final int TOTAL_DEPTH = testRoot.getMaxPriority() - Thread.MIN_PRIORITY
+ - 2;
+ ThreadGroup current = testRoot;
+ for (int i = 0; i < TOTAL_DEPTH; i++) {
+ current = new ThreadGroup(current, "level " + i);
+ }
+
+ // Now we walk the levels down, changing the maxPrio and later verifying
+ // that the value is indeed 1 unit smaller than the parent's maxPrio.
+ int maxPrio, parentMaxPrio;
+ current = testRoot;
+
+ // To maintain the invariant that when we are to modify a child,
+ // its maxPriority is always 1 unit smaller than its parent's.
+ // We have to set it for the root manually, and the loop does the rest
+ // for all the other sub-levels
+ current.setMaxPriority(current.getParent().getMaxPriority() - 1);
+
+ for (int i = 0; i < TOTAL_DEPTH; i++) {
+ maxPrio = current.getMaxPriority();
+ parentMaxPrio = current.getParent().getMaxPriority();
+
+ ThreadGroup[] children = groups(current);
+ assertEquals("Can only have 1 subgroup", 1, children.length);
+ current = children[0];
+ assertTrue(
+ "Had to be 1 unit smaller than parent's priority in iteration="
+ + i + " checking->" + current,
+ maxPrio == parentMaxPrio - 1);
+ current.setMaxPriority(maxPrio - 1);
+
+ // The next test is sort of redundant, since in next iteration it
+ // will be the parent tGroup, so the test will be done.
+ assertTrue("Had to be possible to change max priority", current
+ .getMaxPriority() == maxPrio - 1);
+ }
+
+ assertTrue(
+ "Priority of leaf child group has to be much smaller than original root group",
+ current.getMaxPriority() == testRoot.getMaxPriority() - TOTAL_DEPTH);
+
+ testRoot.destroy();
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ passed = true;
+ testRoot = new ThreadGroup(originalCurrent, "Test group");
+ try {
+ testRoot.setMaxPriority(Thread.MAX_PRIORITY);
+ } catch (IllegalArgumentException iae) {
+ passed = false;
+ }
+ assertTrue(
+ "Max Priority = Thread.MAX_PRIORITY should be possible if the test is run with default system ThreadGroup as root",
+ passed);
+ testRoot.destroy();
+ }
+
+ /*
+ * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread,
+ * java.lang.Throwable)
+ * Tests if a Thread tells its ThreadGroup about ThreadDeath.
+ */
+ public void test_uncaughtException_threadDeath() {
+ final boolean[] passed = new boolean[1];
+
+ ThreadGroup testRoot = new ThreadGroup(rootThreadGroup,
+ "Test Forcing a throw of ThreadDeath") {
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ if (e instanceof ThreadDeath) {
+ passed[0] = true;
+ }
+ // always forward, any exception
+ super.uncaughtException(t, e);
+ }
+ };
+
+ final ThreadDeath threadDeath = new ThreadDeath();
+ Thread thread = new Thread(testRoot, null, "suicidal thread") {
+ @Override
+ public void run() {
+ throw threadDeath;
+ }
+ };
+ thread.start();
+ waitForThreadToDieUninterrupted(thread);
+ testThreadDefaultUncaughtExceptionHandler.assertWasCalled(thread, threadDeath);
+
+ testRoot.destroy();
+ assertTrue(
+ "Any thread should notify its ThreadGroup about its own death, even if suicide:"
+ + testRoot, passed[0]);
+ }
+
+ /*
+ * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread,
+ * java.lang.Throwable)
+ * Test if a Thread tells its ThreadGroup about a natural (non-exception) death.
+ */
+ public void test_uncaughtException_naturalDeath() {
+ final boolean[] failed = new boolean[1];
+
+ ThreadGroup testRoot = new ThreadGroup(initialThreadGroup, "Test ThreadDeath") {
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ failed[0] = true;
+
+ // always forward any exception
+ super.uncaughtException(t, e);
+ }
+ };
+
+ Thread thread = new Thread(testRoot, null, "no-op thread");
+ thread.start();
+ waitForThreadToDieUninterrupted(thread);
+ testThreadDefaultUncaughtExceptionHandler.assertWasNotCalled();
+ testRoot.destroy();
+ assertFalse("A thread should not call uncaughtException when it dies:"
+ + testRoot, failed[0]);
+ }
+
+ /*
+ * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread,
+ * java.lang.Throwable)
+ * Test if a Thread tells its ThreadGroup about an Exception
+ */
+ public void test_uncaughtException_runtimeException() {
+ // Our own exception class
+ class TestException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ }
+
+ final boolean[] passed = new boolean[1];
+
+ ThreadGroup testRoot = new ThreadGroup(initialThreadGroup, "Test other Exception") {
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ if (e instanceof TestException) {
+ passed[0] = true;
+ }
+ // always forward any exception
+ super.uncaughtException(t, e);
+ }
+ };
+
+ final TestException testException = new TestException();
+ Thread thread = new Thread(testRoot, null, "RuntimeException thread") {
+ @Override
+ public void run() {
+ throw testException;
+ }
+ };
+ thread.start();
+ waitForThreadToDieUninterrupted(thread);
+ testThreadDefaultUncaughtExceptionHandler.assertWasCalled(thread, testException);
+ testRoot.destroy();
+ assertTrue(
+ "Any thread should notify its ThreadGroup about an uncaught exception:"
+ + testRoot, passed[0]);
+ }
+
+ /*
+ * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread,
+ * java.lang.Throwable)
+ * Test if a handler doesn't pass on the exception to super.uncaughtException that's ok.
+ */
+ public void test_uncaughtException_exceptionHandledByHandler() {
+ // Our own exception class
+ class TestException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ }
+
+ ThreadGroup testRoot = new ThreadGroup(initialThreadGroup, "Test other Exception") {
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ // Swallow TestException and always forward any other exception
+ if (!(e instanceof TestException)) {
+ super.uncaughtException(t, e);
+ }
+ }
+ };
+
+ final TestException testException = new TestException();
+ Thread thread = new Thread(testRoot, null, "RuntimeException thread") {
+ @Override
+ public void run() {
+ throw testException;
+ }
+ };
+ thread.start();
+ waitForThreadToDieUninterrupted(thread);
+ testThreadDefaultUncaughtExceptionHandler.assertWasNotCalled();
+ testRoot.destroy();
+ }
+
+ /*
+ * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread,
+ * java.lang.Throwable)
+ * Tests an exception thrown by the handler itself.
+ */
+ public void test_uncaughtException_exceptionInUncaughtException() {
+ // Our own uncaught exception classes
+ class UncaughtException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ }
+
+ ThreadGroup testRoot = new ThreadGroup(initialThreadGroup,
+ "Test Exception in uncaught exception") {
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ // This should be no-op according to the spec
+ throw new UncaughtException();
+ }
+ };
+
+ Thread thread = new Thread(testRoot, null, "no-op thread") {
+ @Override
+ public void run() {
+ throw new RuntimeException();
+ }
+ };
+ thread.start();
+ waitForThreadToDieUninterrupted(thread);
+ testThreadDefaultUncaughtExceptionHandler.assertWasNotCalled();
+ testRoot.destroy();
+ }
+
+ private static ThreadGroup[] allGroups(ThreadGroup parent) {
+ int count = parent.activeGroupCount();
+ ThreadGroup[] all = new ThreadGroup[count];
+ parent.enumerate(all, true);
+ return all;
+ }
+
+ private static void asyncBuildRandomTreeUnder(final ThreadGroup aGroup,
+ final int depth, final Vector<ThreadGroup> allCreated) {
+ if (depth <= 0) {
+ return;
+ }
+
+ final int maxImmediateSubgroups = random(3);
+ for (int i = 0; i < maxImmediateSubgroups; i++) {
+ final int iClone = i;
+ final String name = " Depth = " + depth + ",N = " + iClone
+ + ",Vector size at creation: " + allCreated.size();
+ // Use concurrency to maximize chance of exposing concurrency bugs
+ // in ThreadGroups
+ Thread t = new Thread(aGroup, name) {
+ @Override
+ public void run() {
+ ThreadGroup newGroup = new ThreadGroup(aGroup, name);
+ allCreated.addElement(newGroup);
+ asyncBuildRandomTreeUnder(newGroup, depth - 1, allCreated);
+ }
+ };
+ t.start();
+ }
+
+ }
+
+ private static Vector<ThreadGroup> asyncBuildRandomTreeUnder(final ThreadGroup aGroup,
+ final int depth) {
+ Vector<ThreadGroup> result = new Vector<ThreadGroup>();
+ asyncBuildRandomTreeUnder(aGroup, depth, result);
+ return result;
+
+ }
+
+ private static ThreadGroup[] groups(ThreadGroup parent) {
+ // No API to get the count of immediate children only ?
+ int count = parent.activeGroupCount();
+ ThreadGroup[] all = new ThreadGroup[count];
+ parent.enumerate(all, false);
+ // Now we may have nulls in the array, we must find the actual size
+ int actualSize = 0;
+ for (; actualSize < all.length; actualSize++) {
+ if (all[actualSize] == null) {
+ break;
+ }
+ }
+ ThreadGroup[] result;
+ if (actualSize == all.length) {
+ result = all;
+ } else {
+ result = new ThreadGroup[actualSize];
+ System.arraycopy(all, 0, result, 0, actualSize);
+ }
+
+ return result;
+
+ }
+
+ private static int random(int max) {
+ return 1 + ((new Object()).hashCode() % max);
+ }
+
+ private static Vector<ThreadGroup> buildRandomTreeUnder(ThreadGroup aGroup, int depth) {
+ Vector<ThreadGroup> result = asyncBuildRandomTreeUnder(aGroup, depth);
+ while (true) {
+ int sizeBefore = result.size();
+ try {
+ Thread.sleep(1000);
+ int sizeAfter = result.size();
+ // If no activity for a while, we assume async building may be
+ // done.
+ if (sizeBefore == sizeAfter) {
+ // It can only be done if no more threads. Unfortunately we
+ // are relying on this API to work as well.
+ // If it does not, we may loop forever.
+ if (aGroup.activeCount() == 0) {
+ break;
+ }
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+ return result;
+
+ }
+
+ private static boolean arrayIncludes(Object[] array, Object toTest) {
+ for (Object element : array) {
+ if (element == toTest) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void waitForThreadToDieUninterrupted(Thread thread) {
+ try {
+ thread.join();
+ } catch (InterruptedException ie) {
+ fail("Should not have been interrupted");
+ }
+ }
+
+ private static class TestThreadDefaultUncaughtExceptionHandler
+ implements Thread.UncaughtExceptionHandler {
+
+ private boolean called;
+ private Throwable ex;
+ private Thread thread;
+
+ @Override
+ public void uncaughtException(Thread thread, Throwable ex) {
+ this.called = true;
+ this.thread = thread;
+ this.ex = ex;
+ }
+
+ public void assertWasCalled(Thread thread, Throwable ex) {
+ assertTrue(called);
+ assertSame(this.thread, thread);
+ assertSame(this.ex, ex);
+ }
+
+ public void assertWasNotCalled() {
+ assertFalse(called);
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadLocalTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadLocalTest.java
new file mode 100644
index 0000000..400ff01
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadLocalTest.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class ThreadLocalTest extends TestCase {
+
+ /**
+ * java.lang.ThreadLocal#ThreadLocal()
+ */
+ public void test_Constructor() {
+ new ThreadLocal<Object>();
+ }
+
+ /**
+ * java.lang.ThreadLocal#remove()
+ */
+ public void test_remove() {
+ ThreadLocal<String> tl = new ThreadLocal<String>() {
+ @Override
+ protected String initialValue() {
+ return "initial";
+ }
+ };
+
+ assertEquals("initial", tl.get());
+ tl.set("fixture");
+ assertEquals("fixture", tl.get());
+ tl.remove();
+ assertEquals("initial", tl.get());
+ }
+
+ /**
+ * java.lang.ThreadLocal#get()
+ */
+ public void test_get() {
+ // Test for method java.lang.Object java.lang.ThreadLocal.get()
+ ThreadLocal<Object> l = new ThreadLocal<Object>();
+ assertNull("ThreadLocal's initial value is null", l.get());
+
+ // The ThreadLocal has to run once for each thread that touches the
+ // ThreadLocal
+ final Object INITIAL_VALUE = "'foo'";
+ final ThreadLocal<Object> l1 = new ThreadLocal<Object>() {
+ @Override
+ protected Object initialValue() {
+ return INITIAL_VALUE;
+ }
+ };
+
+ assertTrue("ThreadLocal's initial value should be " + INITIAL_VALUE
+ + " but is " + l1.get(), l1.get() == INITIAL_VALUE);
+
+ // We need this because inner types cannot assign to variables in
+ // container method. But assigning to object slots in the container
+ // method is ok.
+ class ResultSlot {
+ public Object result = null;
+ }
+
+ final ResultSlot THREADVALUE = new ResultSlot();
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ THREADVALUE.result = l1.get();
+ }
+ };
+
+ // Wait for the other Thread assign what it observes as the value of the
+ // variable
+ t.start();
+ try {
+ t.join();
+ } catch (InterruptedException ie) {
+ fail("Interrupted!!");
+ }
+
+ assertTrue("ThreadLocal's initial value in other Thread should be "
+ + INITIAL_VALUE, THREADVALUE.result == INITIAL_VALUE);
+
+ /* Regression test for implementation vulnerability reported
+ * on Harmony dev list.
+ */
+ ThreadLocal<Object> thrVar = new ThreadLocal<Object>() {
+ public int hashCode() {
+ fail("ThreadLocal should not be asked for it's hashCode");
+ return 0; // never reached
+ }
+ };
+ thrVar.get();
+ }
+
+ /**
+ * java.lang.ThreadLocal#set(java.lang.Object)
+ */
+ public void test_setLjava_lang_Object() {
+ // Test for method void java.lang.ThreadLocal.set(java.lang.Object)
+
+ final Object OBJ = new Object();
+ final ThreadLocal<Object> l = new ThreadLocal<Object>();
+ l.set(OBJ);
+ assertTrue("ThreadLocal's initial value is " + OBJ, l.get() == OBJ);
+
+ // We need this because inner types cannot assign to variables in
+ // container method.
+ // But assigning to object slots in the container method is ok.
+ class ResultSlot {
+ public Object result = null;
+ }
+
+ final ResultSlot THREADVALUE = new ResultSlot();
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ THREADVALUE.result = l.get();
+ }
+ };
+
+ // Wait for the other Thread assign what it observes as the value of the
+ // variable
+ t.start();
+ try {
+ t.join();
+ } catch (InterruptedException ie) {
+ fail("Interrupted!!");
+ }
+
+ // ThreadLocal is not inherited, so the other Thread should see it as
+ // null
+ assertNull("ThreadLocal's value in other Thread should be null",
+ THREADVALUE.result);
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadTest.java
new file mode 100644
index 0000000..956e1a4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadTest.java
@@ -0,0 +1,1011 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.Map;
+
+public class ThreadTest extends junit.framework.TestCase {
+
+ static class SimpleThread implements Runnable {
+ int delay;
+
+ public void run() {
+ try {
+ synchronized (this) {
+ this.notify();
+ this.wait(delay);
+ }
+ } catch (InterruptedException e) {
+ return;
+ }
+
+ }
+
+ public SimpleThread(int d) {
+ if (d >= 0)
+ delay = d;
+ }
+ }
+
+ static class YieldThread implements Runnable {
+ volatile int delay;
+
+ public void run() {
+ int x = 0;
+ while (true) {
+ ++x;
+ }
+ }
+
+ public YieldThread(int d) {
+ if (d >= 0)
+ delay = d;
+ }
+ }
+
+ static class ResSupThread implements Runnable {
+ Thread parent;
+
+ volatile int checkVal = -1;
+
+ public void run() {
+ try {
+ synchronized (this) {
+ this.notify();
+ }
+ while (true) {
+ checkVal++;
+ zz();
+ Thread.sleep(100);
+ }
+ } catch (InterruptedException e) {
+ return;
+ } catch (BogusException e) {
+ try {
+ // Give parent a chance to sleep
+ Thread.sleep(500);
+ } catch (InterruptedException x) {
+ }
+ parent.interrupt();
+ while (!Thread.currentThread().isInterrupted()) {
+ // Don't hog the CPU
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException x) {
+ // This is what we've been waiting for...don't throw it
+ // away!
+ break;
+ }
+ }
+ }
+ }
+
+ public void zz() throws BogusException {
+ }
+
+ public ResSupThread(Thread t) {
+ parent = t;
+ }
+
+ public synchronized int getCheckVal() {
+ return checkVal;
+ }
+ }
+
+ static class BogusException extends Throwable {
+
+ private static final long serialVersionUID = 1L;
+
+ public BogusException(String s) {
+ super(s);
+ }
+ }
+
+ Thread st, ct, spinner;
+
+ /**
+ * java.lang.Thread#Thread(java.lang.Runnable)
+ */
+ public void test_ConstructorLjava_lang_Runnable() {
+ // Test for method java.lang.Thread(java.lang.Runnable)
+ ct = new Thread(new SimpleThread(10));
+ ct.start();
+ }
+
+ /**
+ * java.lang.Thread#Thread(java.lang.Runnable, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_RunnableLjava_lang_String() {
+ // Test for method java.lang.Thread(java.lang.Runnable,
+ // java.lang.String)
+ Thread st1 = new Thread(new SimpleThread(1), "SimpleThread1");
+ assertEquals("Constructed thread with incorrect thread name", "SimpleThread1", st1
+ .getName());
+ st1.start();
+ }
+
+ /**
+ * java.lang.Thread#Thread(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.lang.Thread(java.lang.String)
+ Thread t = new Thread("Testing");
+ assertEquals("Created tread with incorrect name",
+ "Testing", t.getName());
+ t.start();
+ }
+
+ /**
+ * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable)
+ */
+ public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_Runnable() {
+ // Test for method java.lang.Thread(java.lang.ThreadGroup,
+ // java.lang.Runnable)
+ ThreadGroup tg = new ThreadGroup("Test Group1");
+ st = new Thread(tg, new SimpleThread(1), "SimpleThread2");
+ assertTrue("Returned incorrect thread group", st.getThreadGroup() == tg);
+ st.start();
+ try {
+ st.join();
+ } catch (InterruptedException e) {
+ }
+ tg.destroy();
+ }
+
+ /**
+ * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_RunnableLjava_lang_String() {
+ // Test for method java.lang.Thread(java.lang.ThreadGroup,
+ // java.lang.Runnable, java.lang.String)
+ ThreadGroup tg = new ThreadGroup("Test Group2");
+ st = new Thread(tg, new SimpleThread(1), "SimpleThread3");
+ assertTrue("Constructed incorrect thread", (st.getThreadGroup() == tg)
+ && st.getName().equals("SimpleThread3"));
+ st.start();
+ try {
+ st.join();
+ } catch (InterruptedException e) {
+ }
+ tg.destroy();
+
+ Runnable r = new Runnable() {
+ public void run() {
+ }
+ };
+
+ ThreadGroup foo = null;
+ try {
+ new Thread(foo = new ThreadGroup("foo"), r, null);
+ // Should not get here
+ fail("Null cannot be accepted as Thread name");
+ } catch (NullPointerException npe) {
+ assertTrue("Null cannot be accepted as Thread name", true);
+ foo.destroy();
+ }
+
+ }
+
+ /**
+ * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
+ // Test for method java.lang.Thread(java.lang.ThreadGroup,
+ // java.lang.String)
+ st = new Thread(new SimpleThread(1), "SimpleThread4");
+ assertEquals("Returned incorrect thread name",
+ "SimpleThread4", st.getName());
+ st.start();
+ }
+
+ /**
+ * java.lang.Thread#activeCount()
+ */
+ public void test_activeCount() {
+ // Test for method int java.lang.Thread.activeCount()
+ Thread t = new Thread(new SimpleThread(10));
+ int active = 0;
+ synchronized (t) {
+ t.start();
+ active = Thread.activeCount();
+ }
+ assertTrue("Incorrect activeCount for current group: " + active, active > 1);
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ /**
+ * java.lang.Thread#checkAccess()
+ */
+ public void test_checkAccess() {
+ // Test for method void java.lang.Thread.checkAccess()
+ ThreadGroup tg = new ThreadGroup("Test Group3");
+ try {
+ st = new Thread(tg, new SimpleThread(1), "SimpleThread5");
+ st.checkAccess();
+ assertTrue("CheckAccess passed", true);
+ } catch (SecurityException e) {
+ fail("CheckAccess failed : " + e.getMessage());
+ }
+ st.start();
+ try {
+ st.join();
+ } catch (InterruptedException e) {
+ }
+ tg.destroy();
+ }
+
+ /**
+ * java.lang.Thread#countStackFrames()
+ */
+ @SuppressWarnings("deprecation")
+ public void test_countStackFrames() {
+ /*
+ * Thread.countStackFrames() is unpredictable, so we just test that it
+ * doesn't throw an exception.
+ */
+ Thread.currentThread().countStackFrames();
+ }
+
+ /**
+ * java.lang.Thread#currentThread()
+ */
+ public void test_currentThread() {
+ assertNotNull(Thread.currentThread());
+ }
+
+ public void test_destroy_throwsUnsupportedOperationException() {
+ try {
+ new Thread().destroy();
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ /**
+ * java.lang.Thread#enumerate(java.lang.Thread[])
+ */
+ public void test_enumerate$Ljava_lang_Thread() {
+ // Test for method int java.lang.Thread.enumerate(java.lang.Thread [])
+ // The test has been updated according to HARMONY-1974 JIRA issue.
+
+ class MyThread extends Thread {
+ MyThread(ThreadGroup tg, String name) {
+ super(tg, name);
+ }
+
+ boolean failed = false;
+ String failMessage = null;
+
+ public void run() {
+ SimpleThread st1 = null;
+ SimpleThread st2 = null;
+ ThreadGroup mytg = null;
+ Thread firstOne = null;
+ Thread secondOne = null;
+ try {
+ int arrayLength = 10;
+ Thread[] tarray = new Thread[arrayLength];
+ st1 = new SimpleThread(-1);
+ st2 = new SimpleThread(-1);
+ mytg = new ThreadGroup("jp");
+ firstOne = new Thread(mytg, st1, "firstOne2");
+ secondOne = new Thread(mytg, st2, "secondOne1");
+ int count = Thread.enumerate(tarray);
+ assertEquals("Incorrect value returned1",
+ 1, count);
+ synchronized (st1) {
+ firstOne.start();
+ try {
+ st1.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ count = Thread.enumerate(tarray);
+ assertEquals("Incorrect value returned2",
+ 2, count);
+ synchronized (st2) {
+ secondOne.start();
+ try {
+ st2.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ count = Thread.enumerate(tarray);
+ assertEquals("Incorrect value returned3",
+ 3, count);
+ } catch (junit.framework.AssertionFailedError e) {
+ failed = true;
+ failMessage = e.getMessage();
+ } finally {
+ synchronized (st1) {
+ firstOne.interrupt();
+ }
+ synchronized (st2) {
+ secondOne.interrupt();
+ }
+ try {
+ firstOne.join();
+ secondOne.join();
+ } catch (InterruptedException e) {
+ }
+ mytg.destroy();
+ }
+ }
+ }
+ ;
+
+ ThreadGroup tg = new ThreadGroup("tg");
+ MyThread t = new MyThread(tg, "top");
+ t.start();
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ fail("Unexpected interrupt");
+ } finally {
+ tg.destroy();
+ }
+ assertFalse(t.failMessage, t.failed);
+ }
+
+ /**
+ * java.lang.Thread#getContextClassLoader()
+ */
+ public void test_getContextClassLoader() {
+ // Test for method java.lang.ClassLoader
+ // java.lang.Thread.getContextClassLoader()
+ Thread t = new Thread();
+ assertTrue("Incorrect class loader returned",
+ t.getContextClassLoader() == Thread.currentThread()
+ .getContextClassLoader());
+ t.start();
+
+ }
+
+ /**
+ * java.lang.Thread#getName()
+ */
+ public void test_getName() {
+ // Test for method java.lang.String java.lang.Thread.getName()
+ st = new Thread(new SimpleThread(1), "SimpleThread6");
+ assertEquals("Returned incorrect thread name",
+ "SimpleThread6", st.getName());
+ st.start();
+ }
+
+ /**
+ * java.lang.Thread#getPriority()
+ */
+ public void test_getPriority() {
+ // Test for method int java.lang.Thread.getPriority()
+ st = new Thread(new SimpleThread(1));
+ st.setPriority(Thread.MAX_PRIORITY);
+ assertTrue("Returned incorrect thread priority",
+ st.getPriority() == Thread.MAX_PRIORITY);
+ st.start();
+ }
+
+ /**
+ * java.lang.Thread#getThreadGroup()
+ */
+ public void test_getThreadGroup() {
+ // Test for method java.lang.ThreadGroup
+ // java.lang.Thread.getThreadGroup()
+ ThreadGroup tg = new ThreadGroup("Test Group4");
+ st = new Thread(tg, new SimpleThread(1), "SimpleThread8");
+ assertTrue("Returned incorrect thread group", st.getThreadGroup() == tg);
+ st.start();
+ try {
+ st.join();
+ } catch (InterruptedException e) {
+ }
+ assertNull("group should be null", st.getThreadGroup());
+ assertNotNull("toString() should not be null", st.toString());
+ tg.destroy();
+
+ final Object lock = new Object();
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ }
+ };
+ synchronized (lock) {
+ t.start();
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ int running = 0;
+ while (t.isAlive())
+ running++;
+ ThreadGroup group = t.getThreadGroup();
+ assertNull("ThreadGroup is not null", group);
+ }
+
+ /**
+ * java.lang.Thread#interrupt()
+ */
+ public void test_interrupt() {
+ // Test for method void java.lang.Thread.interrupt()
+ final Object lock = new Object();
+ class ChildThread1 extends Thread {
+ Thread parent;
+
+ boolean sync;
+
+ @Override
+ public void run() {
+ if (sync) {
+ synchronized (lock) {
+ lock.notify();
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ parent.interrupt();
+ }
+
+ public ChildThread1(Thread p, String name, boolean sync) {
+ super(name);
+ parent = p;
+ this.sync = sync;
+ }
+ }
+ boolean interrupted = false;
+ try {
+ ct = new ChildThread1(Thread.currentThread(), "Interrupt Test1",
+ false);
+ synchronized (lock) {
+ ct.start();
+ lock.wait();
+ }
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ assertTrue("Failed to Interrupt thread1", interrupted);
+
+ interrupted = false;
+ try {
+ ct = new ChildThread1(Thread.currentThread(), "Interrupt Test2",
+ true);
+ synchronized (lock) {
+ ct.start();
+ lock.wait();
+ lock.notify();
+ }
+ Thread.sleep(20000);
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ assertTrue("Failed to Interrupt thread2", interrupted);
+
+ }
+
+ /**
+ * java.lang.Thread#interrupted()
+ */
+ public void test_interrupted() {
+ assertFalse("Interrupted returned true for non-interrupted thread", Thread
+ .interrupted());
+ Thread.currentThread().interrupt();
+ assertTrue("Interrupted returned true for non-interrupted thread", Thread.interrupted());
+ assertFalse("Failed to clear interrupted flag", Thread.interrupted());
+ }
+
+ /**
+ * java.lang.Thread#isAlive()
+ */
+ public void test_isAlive() {
+ // Test for method boolean java.lang.Thread.isAlive()
+ SimpleThread simple;
+ st = new Thread(simple = new SimpleThread(500));
+ assertFalse("A thread that wasn't started is alive.", st.isAlive());
+ synchronized (simple) {
+ st.start();
+ try {
+ simple.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ assertTrue("Started thread returned false", st.isAlive());
+ try {
+ st.join();
+ } catch (InterruptedException e) {
+ fail("Thread did not die");
+ }
+ assertTrue("Stopped thread returned true", !st.isAlive());
+ }
+
+ /**
+ * java.lang.Thread#isDaemon()
+ */
+ public void test_isDaemon() {
+ // Test for method boolean java.lang.Thread.isDaemon()
+ st = new Thread(new SimpleThread(1), "SimpleThread10");
+ assertTrue("Non-Daemon thread returned true", !st.isDaemon());
+ st.setDaemon(true);
+ assertTrue("Daemon thread returned false", st.isDaemon());
+ st.start();
+ }
+
+ /**
+ * java.lang.Thread#isInterrupted()
+ */
+ public void test_isInterrupted() {
+ // Test for method boolean java.lang.Thread.isInterrupted()
+ class SpinThread implements Runnable {
+ public volatile boolean done = false;
+
+ public void run() {
+ while (!Thread.currentThread().isInterrupted())
+ ;
+ while (!done)
+ ;
+ }
+ }
+
+ SpinThread spin = new SpinThread();
+ spinner = new Thread(spin);
+ spinner.start();
+ Thread.yield();
+ try {
+ assertTrue("Non-Interrupted thread returned true", !spinner
+ .isInterrupted());
+ spinner.interrupt();
+ assertTrue("Interrupted thread returned false", spinner
+ .isInterrupted());
+ spin.done = true;
+ } finally {
+ spinner.interrupt();
+ spin.done = true;
+ }
+ }
+
+ /**
+ * java.lang.Thread#join()
+ */
+ public void test_join() {
+ // Test for method void java.lang.Thread.join()
+ SimpleThread simple;
+ try {
+ st = new Thread(simple = new SimpleThread(100));
+ // cause isAlive() to be compiled by the JIT, as it must be called
+ // within 100ms below.
+ assertTrue("Thread is alive", !st.isAlive());
+ synchronized (simple) {
+ st.start();
+ simple.wait();
+ }
+ st.join();
+ } catch (InterruptedException e) {
+ fail("Join failed ");
+ }
+ assertTrue("Joined thread is still alive", !st.isAlive());
+ boolean result = true;
+ Thread th = new Thread("test");
+ try {
+ th.join();
+ } catch (InterruptedException e) {
+ result = false;
+ }
+ assertTrue("Hung joining a non-started thread", result);
+ th.start();
+ }
+
+ /**
+ * java.lang.Thread#join(long)
+ */
+ public void test_joinJ() {
+ // Test for method void java.lang.Thread.join(long)
+ SimpleThread simple;
+ try {
+ st = new Thread(simple = new SimpleThread(1000), "SimpleThread12");
+ // cause isAlive() to be compiled by the JIT, as it must be called
+ // within 100ms below.
+ assertTrue("Thread is alive", !st.isAlive());
+ synchronized (simple) {
+ st.start();
+ simple.wait();
+ }
+ st.join(10);
+ } catch (InterruptedException e) {
+ fail("Join failed ");
+ }
+ assertTrue("Join failed to timeout", st.isAlive());
+
+ st.interrupt();
+ try {
+ st = new Thread(simple = new SimpleThread(100), "SimpleThread13");
+ synchronized (simple) {
+ st.start();
+ simple.wait();
+ }
+ st.join(1000);
+ } catch (InterruptedException e) {
+ fail("Join failed : " + e.getMessage());
+ return;
+ }
+ assertTrue("Joined thread is still alive", !st.isAlive());
+
+ final Object lock = new Object();
+ final Thread main = Thread.currentThread();
+ Thread killer = new Thread(new Runnable() {
+ public void run() {
+ try {
+ synchronized (lock) {
+ lock.notify();
+ }
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ return;
+ }
+ main.interrupt();
+ }
+ });
+ boolean result = true;
+ Thread th = new Thread("test");
+ try {
+ synchronized (lock) {
+ killer.start();
+ lock.wait();
+ }
+ th.join(200);
+ } catch (InterruptedException e) {
+ result = false;
+ }
+ killer.interrupt();
+ assertTrue("Hung joining a non-started thread", result);
+ th.start();
+ }
+
+ /**
+ * java.lang.Thread#join(long, int)
+ */
+ public void test_joinJI() throws Exception {
+ // Test for method void java.lang.Thread.join(long, int)
+ SimpleThread simple;
+ st = new Thread(simple = new SimpleThread(1000), "Squawk1");
+ assertTrue("Thread is alive", !st.isAlive());
+ synchronized (simple) {
+ st.start();
+ simple.wait();
+ }
+
+ long firstRead = System.currentTimeMillis();
+ st.join(100, 999999);
+ long secondRead = System.currentTimeMillis();
+ assertTrue("Did not join by appropriate time: " + secondRead + "-"
+ + firstRead + "=" + (secondRead - firstRead), secondRead
+ - firstRead <= 300);
+ assertTrue("Joined thread is not alive", st.isAlive());
+ st.interrupt();
+
+ final Object lock = new Object();
+ final Thread main = Thread.currentThread();
+ Thread killer = new Thread(new Runnable() {
+ public void run() {
+ try {
+ synchronized (lock) {
+ lock.notify();
+ }
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ return;
+ }
+ main.interrupt();
+ }
+ });
+ boolean result = true;
+ Thread th = new Thread("test");
+ try {
+ synchronized (lock) {
+ killer.start();
+ lock.wait();
+ }
+ th.join(200, 20);
+ } catch (InterruptedException e) {
+ result = false;
+ }
+ killer.interrupt();
+ assertTrue("Hung joining a non-started thread", result);
+ th.start();
+ }
+
+ /**
+ * java.lang.Thread#run()
+ */
+ public void test_run() {
+ // Test for method void java.lang.Thread.run()
+ class RunThread implements Runnable {
+ boolean didThreadRun = false;
+
+ public void run() {
+ didThreadRun = true;
+ }
+ }
+ RunThread rt = new RunThread();
+ Thread t = new Thread(rt);
+ try {
+ t.start();
+ int count = 0;
+ while (!rt.didThreadRun && count < 20) {
+ Thread.sleep(100);
+ count++;
+ }
+ assertTrue("Thread did not run", rt.didThreadRun);
+ t.join();
+ } catch (InterruptedException e) {
+ assertTrue("Joined thread was interrupted", true);
+ }
+ assertTrue("Joined thread is still alive", !t.isAlive());
+ }
+
+ /**
+ * java.lang.Thread#setDaemon(boolean)
+ */
+ public void test_setDaemonZ() {
+ // Test for method void java.lang.Thread.setDaemon(boolean)
+ st = new Thread(new SimpleThread(1), "SimpleThread14");
+ st.setDaemon(true);
+ assertTrue("Failed to set thread as daemon thread", st.isDaemon());
+ st.start();
+ }
+
+ /**
+ * java.lang.Thread#setName(java.lang.String)
+ */
+ public void test_setNameLjava_lang_String() {
+ // Test for method void java.lang.Thread.setName(java.lang.String)
+ st = new Thread(new SimpleThread(1), "SimpleThread15");
+ st.setName("Bogus Name");
+ assertEquals("Failed to set thread name",
+ "Bogus Name", st.getName());
+ try {
+ st.setName(null);
+ fail("Null should not be accepted as a valid name");
+ } catch (NullPointerException e) {
+ // success
+ assertTrue("Null should not be accepted as a valid name", true);
+ }
+ st.start();
+ }
+
+ /**
+ * java.lang.Thread#setPriority(int)
+ */
+ public void test_setPriorityI() {
+ // Test for method void java.lang.Thread.setPriority(int)
+ st = new Thread(new SimpleThread(1));
+ st.setPriority(Thread.MAX_PRIORITY);
+ assertTrue("Failed to set priority",
+ st.getPriority() == Thread.MAX_PRIORITY);
+ st.start();
+ }
+
+ /**
+ * java.lang.Thread#sleep(long)
+ */
+ public void test_sleepJ() {
+ // Test for method void java.lang.Thread.sleep(long)
+
+ // TODO : Test needs enhancing.
+ long stime = 0, ftime = 0;
+ try {
+ stime = System.currentTimeMillis();
+ Thread.sleep(1000);
+ ftime = System.currentTimeMillis();
+ } catch (InterruptedException e) {
+ fail("Unexpected interrupt received");
+ }
+ assertTrue("Failed to sleep long enough", (ftime - stime) >= 800);
+ }
+
+ /**
+ * java.lang.Thread#sleep(long, int)
+ */
+ public void test_sleepJI() {
+ // Test for method void java.lang.Thread.sleep(long, int)
+
+ // TODO : Test needs revisiting.
+ long stime = 0, ftime = 0;
+ try {
+ stime = System.currentTimeMillis();
+ Thread.sleep(1000, 999999);
+ ftime = System.currentTimeMillis();
+ } catch (InterruptedException e) {
+ fail("Unexpected interrupt received");
+ }
+ long result = ftime - stime;
+ assertTrue("Failed to sleep long enough: " + result, result >= 900
+ && result <= 1100);
+ }
+
+ /**
+ * java.lang.Thread#start()
+ */
+ public void test_start() {
+ // Test for method void java.lang.Thread.start()
+ try {
+ ResSupThread t = new ResSupThread(Thread.currentThread());
+ synchronized (t) {
+ ct = new Thread(t, "Interrupt Test4");
+ ct.start();
+ t.wait();
+ }
+ assertTrue("Thread is not running1", ct.isAlive());
+ // Let the child thread get going.
+ int orgval = t.getCheckVal();
+ Thread.sleep(150);
+ assertTrue("Thread is not running2", orgval != t.getCheckVal());
+ ct.interrupt();
+ } catch (InterruptedException e) {
+ fail("Unexpected interrupt occurred");
+ }
+ }
+
+ /**
+ * java.lang.Thread#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.lang.Thread.toString()
+ ThreadGroup tg = new ThreadGroup("Test Group5");
+ st = new Thread(tg, new SimpleThread(1), "SimpleThread17");
+ final String stString = st.toString();
+ final String expected = "Thread[SimpleThread17,5,Test Group5]";
+ assertTrue("Returned incorrect string: " + stString + "\t(expecting :"
+ + expected + ")", stString.equals(expected));
+ st.start();
+ try {
+ st.join();
+ } catch (InterruptedException e) {
+ }
+ tg.destroy();
+ }
+
+ /**
+ * java.lang.Thread#getAllStackTraces()
+ */
+ public void test_getAllStackTraces() {
+ Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
+ assertNotNull(stMap);
+ //TODO add security-based tests
+ }
+
+ /**
+ * java.lang.Thread#getDefaultUncaughtExceptionHandler
+ * java.lang.Thread#setDefaultUncaughtExceptionHandler
+ */
+ public void test_get_setDefaultUncaughtExceptionHandler() {
+ class Handler implements UncaughtExceptionHandler {
+ public void uncaughtException(Thread thread, Throwable ex) {
+ }
+ }
+
+ final Handler handler = new Handler();
+ Thread.setDefaultUncaughtExceptionHandler(handler);
+ assertSame(handler, Thread.getDefaultUncaughtExceptionHandler());
+
+ Thread.setDefaultUncaughtExceptionHandler(null);
+ assertNull(Thread.getDefaultUncaughtExceptionHandler());
+ //TODO add security-based tests
+ }
+
+ /**
+ * java.lang.Thread#getStackTrace()
+ */
+ public void test_getStackTrace() {
+ StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+
+ assertNotNull(stackTrace);
+
+ stack_trace_loop:
+ {
+ for (int i = 0; i < stackTrace.length; i++) {
+ StackTraceElement e = stackTrace[i];
+ if (getClass().getName().equals(e.getClassName())) {
+ if ("test_getStackTrace".equals(e.getMethodName())) {
+ break stack_trace_loop;
+ }
+ }
+ }
+ fail("class and method not found in stack trace");
+ }
+
+ //TODO add security-based tests
+ }
+
+ /**
+ * java.lang.Thread#getState()
+ */
+ public void test_getState() {
+ Thread.State state = Thread.currentThread().getState();
+ assertNotNull(state);
+ assertEquals(Thread.State.RUNNABLE, state);
+ //TODO add additional state tests
+ }
+
+ /**
+ * java.lang.Thread#getUncaughtExceptionHandler
+ * java.lang.Thread#setUncaughtExceptionHandler
+ */
+ public void test_get_setUncaughtExceptionHandler() {
+ class Handler implements UncaughtExceptionHandler {
+ public void uncaughtException(Thread thread, Throwable ex) {
+ }
+ }
+
+ final Handler handler = new Handler();
+ Thread.currentThread().setUncaughtExceptionHandler(handler);
+ assertSame(handler, Thread.currentThread().getUncaughtExceptionHandler());
+
+ Thread.currentThread().setUncaughtExceptionHandler(null);
+
+ //TODO add security-based tests
+ }
+
+ /**
+ * java.lang.Thread#getId()
+ */
+ public void test_getId() {
+ assertTrue("current thread's ID is not positive", Thread.currentThread().getId() > 0);
+
+ //check all the current threads for positive IDs
+ Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
+ for (Thread thread : stMap.keySet()) {
+ assertTrue("thread's ID is not positive: " + thread.getName(), thread.getId() > 0);
+ }
+ }
+
+
+ @Override
+ protected void tearDown() {
+ try {
+ if (st != null)
+ st.interrupt();
+ } catch (Exception e) {
+ }
+ try {
+ if (spinner != null)
+ spinner.interrupt();
+ } catch (Exception e) {
+ }
+ try {
+ if (ct != null)
+ ct.interrupt();
+ } catch (Exception e) {
+ }
+
+ try {
+ spinner = null;
+ st = null;
+ ct = null;
+ System.runFinalization();
+ } catch (Exception e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThrowableTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThrowableTest.java
new file mode 100644
index 0000000..dbe656f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThrowableTest.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import junit.framework.TestCase;
+
+public class ThrowableTest extends TestCase {
+
+ /**
+ * java.lang.Throwable#Throwable()
+ */
+ public void test_Constructor() {
+ Throwable e = new Throwable();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.Throwable#Throwable(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ Throwable e = new Throwable("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.Throwable#fillInStackTrace()
+ */
+ public void test_fillInStackTrace() {
+ // Test for method java.lang.Throwable
+ // java.lang.Throwable.fillInStackTrace()
+ class Test implements Runnable {
+ public int x;
+
+ public Test(int x) {
+ this.x = x;
+ }
+
+ public void anotherMethod() {
+ if (true)
+ throw new IndexOutOfBoundsException();
+ }
+
+ public void run() {
+ if (x == 0)
+ throw new IndexOutOfBoundsException();
+ try {
+ anotherMethod();
+ } catch (IndexOutOfBoundsException e) {
+ e.fillInStackTrace();
+ throw e;
+ }
+ }
+ }
+ ByteArrayOutputStream bao = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bao);
+ try {
+ new Test(0).run();
+ } catch (Throwable e) {
+ e.printStackTrace(ps);
+ }
+ ps.flush();
+ String s = fixStacktrace(new String(bao.toByteArray(), 0, bao.size()));
+
+ bao.reset();
+ try {
+ new Test(1).run();
+ } catch (Throwable e) {
+ e.printStackTrace(ps);
+ }
+ ps.close();
+ String s2 = fixStacktrace(new String(bao.toByteArray(), 0, bao.size()));
+ assertTrue("Invalid stackTrace? length: " + s2.length() + "\n" + s2, s2
+ .length() > 300);
+ assertTrue("Incorrect stackTrace printed: \n" + s2
+ + "\n\nCompared with:\n" + s, s2.equals(s));
+ }
+
+ private String fixStacktrace(String trace) {
+ // remove linenumbers
+ StringBuffer sb = new StringBuffer();
+ int lastIndex = 0;
+ while (lastIndex < trace.length()) {
+ int index = trace.indexOf('\n', lastIndex);
+ if (index == -1)
+ index = trace.length();
+ String line = trace.substring(lastIndex, index);
+ lastIndex = index + 1;
+
+ index = line.indexOf("(");
+ if (index > -1) {
+ line = line.substring(0, index);
+ }
+ // Usually the construction of the exception is removed
+ // however if running with the JIT, it may not be removed
+ if (line.indexOf("java.lang.Throwable") > -1)
+ continue;
+ sb.append(line);
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * java.lang.Throwable#printStackTrace()
+ */
+ public void test_printStackTrace() {
+ // Test for method void java.lang.Throwable.printStackTrace()
+ Throwable x = new ClassNotFoundException("A Test Message");
+ ByteArrayOutputStream bao = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bao);
+ PrintStream err = System.err;
+ System.setErr(ps);
+ x.printStackTrace();
+ System.setErr(err);
+ ps.close();
+ String s = new String(bao.toByteArray(), 0, bao.size());
+ assertTrue("Incorrect stackTrace printed:\n" + s, s != null
+ && s.length() > 400);
+ }
+
+ /**
+ * java.lang.Throwable#printStackTrace(java.io.PrintStream)
+ */
+ public void test_printStackTraceLjava_io_PrintStream() {
+ // Test for method void
+ // java.lang.Throwable.printStackTrace(java.io.PrintStream)
+ ByteArrayOutputStream bao = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bao);
+ Throwable x = new java.net.UnknownHostException("A Message");
+ x.printStackTrace(ps);
+ ps.close();
+ String s = new String(bao.toByteArray(), 0, bao.size());
+ assertTrue("Incorrect stackTrace printed:\n" + s, s != null
+ && s.length() > 400);
+ }
+
+ /**
+ * java.lang.Throwable#printStackTrace(java.io.PrintWriter)
+ */
+ public void test_printStackTraceLjava_io_PrintWriter() {
+ // Test for method void
+ // java.lang.Throwable.printStackTrace(java.io.PrintWriter)
+ // SM
+ ByteArrayOutputStream bao = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(bao);
+ Throwable x = new java.net.UnknownHostException("A Message");
+ x.printStackTrace(pw);
+ pw.close();
+ String s = new String(bao.toByteArray(), 0, bao.size());
+ assertTrue("Incorrect stackTrace printed:\n" + s, s != null
+ && s.length() > 400);
+ }
+
+ /**
+ * java.lang.Throwable#toString()
+ */
+ public void test_toString() {
+ Throwable e = new Throwable("Throw");
+ assertEquals("java.lang.Throwable: Throw", e.toString());
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/TypeNotPresentExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/TypeNotPresentExceptionTest.java
new file mode 100644
index 0000000..3f14e34
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/TypeNotPresentExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class TypeNotPresentExceptionTest extends TestCase {
+
+ /**
+ * java.lang.TypeNotPresentException.TypeNotPresentException(String, Throwable)
+ */
+ public void test_constructorLjava_lang_StringLjava_lang_Throwable() {
+ TypeNotPresentException e = new TypeNotPresentException(null, null);
+ assertNotNull(e);
+ String m = e.getMessage();
+ assertNotNull(m);
+
+ e = new TypeNotPresentException(getClass().getName(), null);
+ assertNotNull(e);
+ m = e.getMessage();
+ assertNotNull(m);
+
+ NullPointerException npe = new NullPointerException();
+ e = new TypeNotPresentException(getClass().getName(), npe);
+ assertNotNull(e.getMessage());
+ assertSame(npe, e.getCause());
+ }
+
+ /**
+ * java.lang.TypeNotPresentException.typeName()
+ */
+ public void test_typeName() {
+ TypeNotPresentException e = new TypeNotPresentException(null, null);
+ assertNull(e.typeName());
+
+ e = new TypeNotPresentException(getClass().getName(), null);
+ assertEquals(getClass().getName(), e.typeName());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnknownErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnknownErrorTest.java
new file mode 100644
index 0000000..8ec96a4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnknownErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class UnknownErrorTest extends TestCase {
+
+ /**
+ * java.lang.UnknownError#UnknownError()
+ */
+ public void test_Constructor() {
+ UnknownError e = new UnknownError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.UnknownError#UnknownError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ UnknownError e = new UnknownError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsatisfiedLinkErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsatisfiedLinkErrorTest.java
new file mode 100644
index 0000000..d6e06db
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsatisfiedLinkErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class UnsatisfiedLinkErrorTest extends TestCase {
+
+ /**
+ * java.lang.UnsatisfiedLinkError#UnsatisfiedLinkError()
+ */
+ public void test_Constructor() {
+ UnsatisfiedLinkError e = new UnsatisfiedLinkError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.UnsatisfiedLinkError#UnsatisfiedLinkError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ UnsatisfiedLinkError e = new UnsatisfiedLinkError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsupportedClassVersionErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsupportedClassVersionErrorTest.java
new file mode 100644
index 0000000..dcf09b8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsupportedClassVersionErrorTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class UnsupportedClassVersionErrorTest extends TestCase {
+ /**
+ * Thrown when the Java Virtual Machine attempts to read a class file and
+ * determines that the major and minor version numbers in the file are not
+ * supported.
+ */
+
+ /**
+ * java.lang.UnsupportedClassVersionError#UnsupportedClassVersionError()
+ */
+ public void test_UnsupportedClassVersionError() {
+ UnsupportedClassVersionError error = new UnsupportedClassVersionError();
+ assertNotNull(error);
+ assertNull(error.getMessage());
+ }
+
+ /**
+ * java.lang.UnsupportedClassVersionError#UnsupportedClassVersionError(java.lang.String)
+ */
+ public void test_UnsupportedClassVersionError_LString() {
+ UnsupportedClassVersionError e = new UnsupportedClassVersionError(
+ "Some Error Message");
+ assertEquals("Wrong message", "Some Error Message", e.getMessage());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsupportedOperationExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsupportedOperationExceptionTest.java
new file mode 100644
index 0000000..73cf5e6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/UnsupportedOperationExceptionTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class UnsupportedOperationExceptionTest extends TestCase {
+
+ /**
+ * java.lang.UnsupportedOperationException#UnsupportedOperationException()
+ */
+ public void test_Constructor() {
+ UnsupportedOperationException e = new UnsupportedOperationException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.UnsupportedOperationException#UnsupportedOperationException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ UnsupportedOperationException e = new UnsupportedOperationException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * {@link java.land.UnsupportedOperationException#UnsupportedOperationException(java.lang.Throwable)}
+ */
+ public void test_ConstructorLjava_lang_Throwable() {
+ Throwable emptyThrowable = new Exception();
+ UnsupportedOperationException emptyException = new UnsupportedOperationException(
+ emptyThrowable);
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getLocalizedMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+ Throwable throwable = new Exception("msg");
+ UnsupportedOperationException exception = new UnsupportedOperationException(throwable);
+ assertEquals(throwable.getClass().getName() + ": " + "msg", exception.getMessage());
+ assertEquals(throwable.getClass().getName(), emptyException.getLocalizedMessage());
+ assertEquals(throwable.getClass().getName(), emptyException.getCause().toString());
+ }
+
+ /**
+ * {@link java.land.UnsupportedOperationException#UnsupportedOperationException(java.lang.String, java.lang.Throwable)}
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+ Throwable emptyThrowable = new Exception();
+ UnsupportedOperationException emptyException = new UnsupportedOperationException(
+ "msg", emptyThrowable);
+ assertEquals("msg", emptyException.getMessage());
+ assertEquals("msg", emptyException.getLocalizedMessage());
+ assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+ Throwable throwable = new Exception("msg_exception");
+ UnsupportedOperationException exception = new UnsupportedOperationException(
+ "msg", throwable);
+ assertEquals("msg", exception.getMessage());
+ assertEquals("msg", exception.getLocalizedMessage());
+ assertEquals(throwable.getClass().getName() + ": " + throwable.getMessage(), exception
+ .getCause().toString());
+ }
+
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new UnsupportedOperationException());
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new UnsupportedOperationException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/VerifyErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/VerifyErrorTest.java
new file mode 100644
index 0000000..874ac57
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/VerifyErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+public class VerifyErrorTest extends TestCase {
+
+ /**
+ * java.lang.VerifyError#VerifyError()
+ */
+ public void test_Constructor() {
+ VerifyError e = new VerifyError();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.VerifyError#VerifyError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ VerifyError e = new VerifyError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/VirtualMachineErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/VirtualMachineErrorTest.java
new file mode 100644
index 0000000..60ed446
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/VirtualMachineErrorTest.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("serial")
+public class VirtualMachineErrorTest extends TestCase {
+
+ /**
+ * java.lang.VirtualMachineError#VirtualMachineError()
+ */
+ public void test_Constructor() {
+ VirtualMachineError e = new VirtualMachineError() {
+ };
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * java.lang.VirtualMachineError#VirtualMachineError(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ VirtualMachineError e = new VirtualMachineError("fixture") {
+ };
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/PhantomReferenceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/PhantomReferenceTest.java
new file mode 100644
index 0000000..5a80fde
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/PhantomReferenceTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.ref;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import libcore.java.lang.ref.FinalizationTester;
+
+//TODO: write a test to verify that the referent's finalize() happens
+// before the PhantomReference is enqueued.
+
+public class PhantomReferenceTest extends junit.framework.TestCase {
+ static Boolean bool;
+ public boolean isCalled = false;
+ protected void doneSuite() {
+ bool = null;
+ }
+
+ /**
+ * java.lang.ref.PhantomReference#get()
+ */
+ public void test_get() {
+ ReferenceQueue rq = new ReferenceQueue();
+ bool = new Boolean(false);
+ PhantomReference pr = new PhantomReference(bool, rq);
+ assertNull("get() should return null.", pr.get());
+ pr.enqueue();
+ assertNull("get() should return null.", pr.get());
+ pr.clear();
+ assertNull("get() should return null.", pr.get());
+ }
+
+ /**
+ * java.lang.Runtime#gc()
+ */
+ public void test_gcInteraction() {
+ class TestPhantomReference<T> extends PhantomReference<T> {
+ public TestPhantomReference(T referent,
+ ReferenceQueue<? super T> q) {
+ super(referent, q);
+ }
+ public boolean enqueue() {
+ // Initiate another GC from inside enqueue() to
+ // see if it causes any problems inside the VM.
+ Runtime.getRuntime().gc();
+ return super.enqueue();
+ }
+ }
+
+ final ReferenceQueue rq = new ReferenceQueue();
+ final PhantomReference[] tprs = new PhantomReference[4];
+
+ class TestThread extends Thread {
+ public void run() {
+ // Create the object in a separate thread to ensure
+ // it will be gc'ed.
+ Object obj = new Object();
+ tprs[0] = new TestPhantomReference(obj, rq);
+ tprs[1] = new TestPhantomReference(obj, rq);
+ tprs[2] = new TestPhantomReference(obj, rq);
+ tprs[3] = new TestPhantomReference(obj, rq);
+ }
+ }
+
+ try {
+ Thread t = new TestThread();
+ t.start();
+ t.join();
+
+ FinalizationTester.induceFinalization();
+
+ assertNull("get() should return null.", tprs[0].get());
+ assertNull("get() should return null.", tprs[1].get());
+ assertNull("get() should return null.", tprs[2].get());
+ assertNull("get() should return null.", tprs[3].get());
+
+ for (int i = 0; i < 4; i++) {
+ Reference r = rq.remove(100L);
+ assertNotNull("Reference should have been enqueued.", r);
+ }
+
+ // These are to make sure that tprs and its elements don't get
+ // optimized out.
+ assertNull("get() should return null.", tprs[0].get());
+ assertNull("get() should return null.", tprs[1].get());
+ assertNull("get() should return null.", tprs[2].get());
+ assertNull("get() should return null.", tprs[3].get());
+ } catch (InterruptedException e) {
+ fail("InterruptedException : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.ref.PhantomReference#PhantomReference(java.lang.Object,
+ * java.lang.ref.ReferenceQueue)
+ */
+ public void test_ConstructorLjava_lang_ObjectLjava_lang_ref_ReferenceQueue() {
+ ReferenceQueue rq = new ReferenceQueue();
+ bool = new Boolean(true);
+ try {
+ PhantomReference pr = new PhantomReference(bool, rq);
+ // Allow the finalizer to run to potentially enqueue
+ Thread.sleep(1000);
+ assertTrue("Initialization failed.", !pr.isEnqueued());
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ // need a reference to bool so the jit does not optimize it away
+ assertTrue("should always pass", bool.booleanValue());
+
+ boolean exception = false;
+ try {
+ new PhantomReference(bool, null);
+ } catch (NullPointerException e) {
+ exception = true;
+ }
+ assertTrue("Should not throw NullPointerException", !exception);
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceQueueTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceQueueTest.java
new file mode 100644
index 0000000..75a5218
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceQueueTest.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.ref;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import libcore.java.lang.ref.FinalizationTester;
+
+public class ReferenceQueueTest extends junit.framework.TestCase {
+ static Boolean b;
+
+ static Integer integer;
+ boolean isThrown = false;
+
+ protected void doneSuite() {
+ b = null;
+ integer = null;
+ }
+
+ public class ChildThread implements Runnable {
+ public ChildThread() {
+ }
+
+ public void run() {
+ try {
+ rq.wait(1000);
+ } catch (Exception e) {
+ }
+ synchronized (rq) {
+ // store in a static so it won't be gc'ed because the jit
+ // optimized it out
+ integer = new Integer(667);
+ SoftReference sr = new SoftReference(integer, rq);
+ sr.enqueue();
+ rq.notify();
+ }
+ }
+ }
+
+ ReferenceQueue rq;
+
+ /**
+ * java.lang.ref.ReferenceQueue#poll()
+ */
+ public void test_poll() {
+ // store in a static so it won't be gc'ed because the jit
+ // optimized it out
+ b = new Boolean(true);
+ Object obj = new Object();
+ String str = "Test";
+
+ SoftReference sr = new SoftReference(b, rq);
+ WeakReference wr = new WeakReference(obj, rq);
+ PhantomReference pr = new PhantomReference(str, rq);
+ assertNull(rq.poll());
+ sr.enqueue();
+ wr.enqueue();
+ pr.enqueue();
+
+ try {
+ assertTrue("Remove failed.", ((Boolean) rq.poll().get())
+ .booleanValue());
+ } catch (Exception e) {
+ fail("Exception during the test : " + e.getMessage());
+ }
+
+ try {
+ assertEquals("Remove failed.", obj, (rq.poll().get()));
+ } catch (Exception e) {
+ fail("Exception during the test : " + e.getMessage());
+ }
+
+ try {
+ assertNull("Remove failed.", rq.poll().get());
+ } catch (Exception e) {
+ fail("Exception during the test : " + e.getMessage());
+ }
+
+ assertNull(rq.poll());
+
+ sr.enqueue();
+ wr.enqueue();
+
+ FinalizationTester.induceFinalization();
+
+ assertNull(rq.poll());
+ }
+
+ /**
+ * java.lang.ref.ReferenceQueue#remove()
+ */
+ public void test_remove() {
+ // store in a static so it won't be gc'ed because the jit
+ // optimized it out
+ b = new Boolean(true);
+
+ SoftReference sr = new SoftReference(b, rq);
+ sr.enqueue();
+ try {
+ assertTrue("Remove failed.", ((Boolean) rq.remove().get())
+ .booleanValue());
+ } catch (Exception e) {
+ fail("Exception during the test : " + e.getMessage());
+ }
+
+ assertNull(rq.poll());
+
+ sr.enqueue();
+
+ class RemoveThread extends Thread {
+ public void run() {
+ try {
+ rq.remove();
+ } catch(InterruptedException ie) {
+ isThrown = true;
+ }
+ }
+ }
+ RemoveThread rt = new RemoveThread();
+ rt.start();
+ try {
+ Thread.sleep(100);
+ } catch(InterruptedException ie) {
+
+ }
+ rt.interrupt();
+ try {
+ Thread.sleep(100);
+ } catch(InterruptedException ie) {
+
+ }
+ assertTrue(isThrown);
+ assertNull(rq.poll());
+ }
+
+ /**
+ * java.lang.ref.ReferenceQueue#remove(long)
+ */
+ public void test_removeJ() {
+ try {
+ assertNull("Queue should be empty. (poll)", rq.poll());
+ assertNull("Queue should be empty. (remove(1))",
+ rq.remove((long) 1));
+ Thread ct = new Thread(new ChildThread());
+ ct.start();
+ Reference ret = rq.remove(0L);
+ assertNotNull("Delayed remove failed.", ret);
+ } catch (InterruptedException e) {
+ fail("InterruptedExeException during test : " + e.getMessage());
+ }
+ catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+
+ Object obj = new Object();
+ WeakReference wr = new WeakReference(obj, rq);
+ Boolean b = new Boolean(true);
+ SoftReference sr = new SoftReference(b, rq);
+ String str = "Test";
+ PhantomReference pr = new PhantomReference(str, rq);
+
+ pr.enqueue();
+ wr.enqueue();
+ sr.enqueue();
+
+ try {
+ Reference result = rq.remove(1L);
+ assertNull(result.get());
+ result = rq.remove(1L);
+ assertEquals(obj, result.get());
+ result = rq.remove(1L);
+ assertTrue((Boolean)result.get());
+ } catch (IllegalArgumentException e1) {
+ fail("IllegalArgumentException was thrown.");
+ } catch (InterruptedException e1) {
+ fail("InterruptedException was thrown.");
+ }
+ rq = new ReferenceQueue();
+ isThrown = false;
+ assertNull(rq.poll());
+
+ class RemoveThread extends Thread {
+ public void run() {
+ try {
+ rq.remove(1000L);
+ } catch(InterruptedException ie) {
+ isThrown = true;
+ }
+ }
+ }
+ RemoveThread rt = new RemoveThread();
+ rt.start();
+ try {
+ Thread.sleep(10);
+ } catch(InterruptedException ie) {
+
+ }
+ rt.interrupt();
+ try {
+ Thread.sleep(10);
+ } catch(InterruptedException ie) {
+
+ }
+ assertTrue(isThrown);
+ assertNull(rq.poll());
+
+ try {
+ rq.remove(-1);
+ fail("IllegalArgumentException expected.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ } catch (InterruptedException e) {
+ fail("Unexpected InterruptedException.");
+ }
+ }
+
+ /**
+ * java.lang.ref.ReferenceQueue#ReferenceQueue()
+ */
+ public void test_Constructor() {
+ ReferenceQueue rq = new ReferenceQueue();
+ assertNull(rq.poll());
+ try {
+ rq.remove(100L);
+ } catch (InterruptedException e) {
+ fail("InterruptedException was thrown.");
+ }
+ }
+
+ protected void setUp() {
+ rq = new ReferenceQueue();
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceTest.java
new file mode 100644
index 0000000..031502d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceTest.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang.ref;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import junit.framework.AssertionFailedError;
+import libcore.java.lang.ref.FinalizationTester;
+
+public class ReferenceTest extends junit.framework.TestCase {
+ Object tmpA, tmpB, tmpC, obj;
+
+ volatile Reference r;
+
+ /*
+ * For test_subclass().
+ */
+ static TestWeakReference twr;
+ static AssertionFailedError error;
+ static boolean testObjectFinalized;
+ static class TestWeakReference<T> extends WeakReference<T> {
+ public volatile boolean clearSeen = false;
+ public volatile boolean enqueueSeen = false;
+
+ public TestWeakReference(T referent) {
+ super(referent);
+ }
+
+ public TestWeakReference(T referent, ReferenceQueue<? super T> q) {
+ super(referent, q);
+ }
+
+ public void clear() {
+ clearSeen = true;
+ if (testObjectFinalized) {
+ error = new AssertionFailedError("Clear should happen " +
+ "before finalization.");
+ throw error;
+ }
+ if (enqueueSeen) {
+ error = new AssertionFailedError("Clear should happen " +
+ "before enqueue.");
+ throw error;
+ }
+ super.clear();
+ }
+
+ public boolean enqueue() {
+ enqueueSeen = true;
+ if (!clearSeen) {
+ error = new AssertionFailedError("Clear should happen " +
+ "before enqueue.");
+ throw error;
+ }
+
+ /* Do this last; it may notify the main test thread,
+ * and anything we'd do after it (e.g., setting clearSeen)
+ * wouldn't be seen.
+ */
+ return super.enqueue();
+ }
+ }
+
+ protected void doneSuite() {
+ tmpA = tmpB = obj = null;
+ }
+
+ /**
+ * java.lang.ref.Reference#clear()
+ */
+ public void test_clear() {
+ tmpA = new Object();
+ tmpB = new Object();
+ tmpC = new Object();
+ SoftReference sr = new SoftReference(tmpA, new ReferenceQueue());
+ WeakReference wr = new WeakReference(tmpB, new ReferenceQueue());
+ PhantomReference pr = new PhantomReference(tmpC, new ReferenceQueue());
+ assertTrue("Start: Object not cleared.", (sr.get() != null)
+ && (wr.get() != null));
+ assertNull("Referent is not null.", pr.get());
+ sr.clear();
+ wr.clear();
+ pr.clear();
+ assertTrue("End: Object cleared.", (sr.get() == null)
+ && (wr.get() == null));
+ assertNull("Referent is not null.", pr.get());
+ // Must reference tmpA and tmpB so the jit does not optimize them away
+ assertTrue("should always pass", tmpA != sr.get() && tmpB != wr.get());
+ }
+
+ /**
+ * java.lang.ref.Reference#enqueue()
+ */
+ public void test_enqueue() {
+ ReferenceQueue rq = new ReferenceQueue();
+ obj = new Object();
+ Reference ref = new SoftReference(obj, rq);
+ assertTrue("Enqueue failed.", (!ref.isEnqueued())
+ && ((ref.enqueue()) && (ref.isEnqueued())));
+ assertTrue("Not properly enqueued.", rq.poll().get() == obj);
+ // This fails...
+ assertTrue("Should remain enqueued.", !ref.isEnqueued());
+ assertTrue("Can not enqueue twice.", (!ref.enqueue())
+ && (rq.poll() == null));
+
+ rq = new ReferenceQueue();
+ obj = new Object();
+
+ ref = new WeakReference(obj, rq);
+ assertTrue("Enqueue failed2.", (!ref.isEnqueued())
+ && ((ref.enqueue()) && (ref.isEnqueued())));
+ assertTrue("Not properly enqueued2.", rq.poll().get() == obj);
+ assertTrue("Should remain enqueued2.", !ref.isEnqueued()); // This
+ // fails.
+ assertTrue("Can not enqueue twice2.", (!ref.enqueue())
+ && (rq.poll() == null));
+
+ ref = new PhantomReference(obj, rq);
+ assertTrue("Enqueue failed3.", (!ref.isEnqueued())
+ && ((ref.enqueue()) && (ref.isEnqueued())));
+ assertNull("Not properly enqueued3.", rq.poll().get());
+ assertTrue("Should remain enqueued3.", !ref.isEnqueued()); // This
+ // fails.
+ assertTrue("Can not enqueue twice3.", (!ref.enqueue())
+ && (rq.poll() == null));
+ }
+
+ public void test_get_WeakReference() throws Exception {
+ // Test the general/overall functionality of Reference.
+ ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+
+ r = newWeakReference(queue);
+ FinalizationTester.induceFinalization();
+ Reference ref = queue.remove();
+ assertNotNull("Object not enqueued.", ref);
+ assertSame("Unexpected ref1", ref, r);
+ assertNull("Object could not be reclaimed1.", r.get());
+
+ r = newWeakReference(queue);
+ FinalizationTester.induceFinalization();
+
+ // wait for the reference queue thread to enqueue the newly-finalized object
+ Thread.yield();
+ Thread.sleep(200);
+
+ ref = queue.poll();
+ assertNotNull("Object not enqueued.", ref);
+ assertSame("Unexpected ref2", ref, r);
+ assertNull("Object could not be reclaimed.", ref.get());
+ assertNull("Object could not be reclaimed.", r.get());
+ }
+
+ /**
+ * Makes sure that overridden versions of clear() and enqueue()
+ * get called, and that clear/enqueue/finalize happen in the
+ * right order for WeakReferences.
+ *
+ * java.lang.ref.Reference#clear()
+ * java.lang.ref.Reference#enqueue()
+ * java.lang.Object#finalize()
+ */
+ public void test_subclass() {
+ error = null;
+ testObjectFinalized = false;
+ twr = null;
+
+ class TestObject {
+ public TestWeakReference testWeakReference = null;
+
+ public void setTestWeakReference(TestWeakReference twr) {
+ testWeakReference = twr;
+ }
+
+ protected void finalize() {
+ testObjectFinalized = true;
+ }
+ }
+
+ final ReferenceQueue rq = new ReferenceQueue();
+
+ class TestThread extends Thread {
+ public void run() {
+ // Create the object in a separate thread to ensure it will be
+ // gc'ed
+ TestObject testObj = new TestObject();
+ twr = new TestWeakReference(testObj, rq);
+ testObj.setTestWeakReference(twr);
+ testObj = null;
+ }
+ }
+
+ Reference ref;
+
+ try {
+ Thread t = new TestThread();
+ t.start();
+ t.join();
+ FinalizationTester.induceFinalization();
+ ref = rq.remove(5000L); // Give up after five seconds.
+
+ assertNotNull("Object not garbage collected.", ref);
+ assertTrue("Unexpected reference.", ref == twr);
+ assertNull("Object could not be reclaimed.", twr.get());
+ //assertTrue("Overridden clear() should have been called.",
+ // twr.clearSeen);
+ //assertTrue("Overridden enqueue() should have been called.",
+ // twr.enqueueSeen);
+ assertTrue("finalize() should have been called.",
+ testObjectFinalized);
+ } catch (InterruptedException e) {
+ fail("InterruptedException : " + e.getMessage());
+ }
+
+ }
+
+ /**
+ * java.lang.ref.Reference#get()
+ */
+ public void test_get() {
+ WeakReference ref = newWeakReference(null);
+
+ FinalizationTester.induceFinalization();
+ assertNull("get() doesn't return null after gc for WeakReference", ref.get());
+
+ obj = new Object();
+ ref = new WeakReference<Object>(obj, new ReferenceQueue<Object>());
+ ref.clear();
+ assertNull("get() doesn't return null after clear for WeakReference", ref.get());
+ }
+
+ /**
+ * Helper method to prevent live-precise bugs from interfering with analysis
+ * of what is reachable. Do not inline this method; otherwise tests may fail
+ * on VMs that are not live-precise. http://b/4191345
+ */
+ private WeakReference<Object> newWeakReference(ReferenceQueue<Object> queue) {
+ Object o = new Object();
+ WeakReference<Object> ref = new WeakReference<Object>(o, queue);
+ assertSame(o, ref.get());
+ return ref;
+ }
+
+ /**
+ * java.lang.ref.Reference#isEnqueued()
+ */
+ public void test_isEnqueued() {
+ ReferenceQueue rq = new ReferenceQueue();
+ obj = new Object();
+ Reference ref = new SoftReference(obj, rq);
+ assertTrue("Should start off not enqueued.", !ref.isEnqueued());
+ ref.enqueue();
+ assertTrue("Should now be enqueued.", ref.isEnqueued());
+ ref.enqueue();
+ assertTrue("Should still be enqueued.", ref.isEnqueued());
+ rq.poll();
+ // This fails ...
+ assertTrue("Should now be not enqueued.", !ref.isEnqueued());
+ }
+
+ /* Contrives a situation where the only reference to a string
+ * is a WeakReference from an object that is being finalized.
+ * Checks to make sure that the referent of the WeakReference
+ * is still pointing to a valid object.
+ */
+ public void test_finalizeReferenceInteraction() {
+ error = null;
+ testObjectFinalized = false;
+
+ class TestObject {
+ WeakReference<String> stringRef;
+
+ public TestObject(String referent) {
+ stringRef = new WeakReference<String>(referent);
+ }
+
+ protected void finalize() {
+ try {
+ /* If a VM bug has caused the referent to get
+ * freed without the reference getting cleared,
+ * looking it up, assigning it to a local and
+ * doing a GC should cause some sort of exception.
+ */
+ String s = stringRef.get();
+ System.gc();
+ testObjectFinalized = true;
+ } catch (Throwable t) {
+ error = new AssertionFailedError("something threw '" + t +
+ "' in finalize()");
+ }
+ }
+ }
+
+ class TestThread extends Thread {
+ public void run() {
+ // Create the object in a separate thread to ensure it will be
+ // gc'ed
+ TestObject testObj = new TestObject(new String("sup /b/"));
+ }
+ }
+
+ try {
+ Thread t = new TestThread();
+ t.start();
+ t.join();
+ FinalizationTester.induceFinalization();
+ Thread.sleep(1000);
+ if (error != null) {
+ throw error;
+ }
+ assertTrue("finalize() should have been called.",
+ testObjectFinalized);
+ } catch (InterruptedException e) {
+ fail("InterruptedException : " + e.getMessage());
+ }
+ }
+
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/SoftReferenceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/SoftReferenceTest.java
new file mode 100644
index 0000000..f66cbbf
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/SoftReferenceTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang.ref;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.util.Vector;
+import libcore.java.lang.ref.FinalizationTester;
+
+public class SoftReferenceTest extends junit.framework.TestCase {
+ static Boolean bool;
+ SoftReference r;
+
+ protected void doneSuite() {
+ bool = null;
+ }
+
+ /**
+ * java.lang.ref.SoftReference#SoftReference(java.lang.Object,
+ * java.lang.ref.ReferenceQueue)
+ */
+ public void test_ConstructorLjava_lang_ObjectLjava_lang_ref_ReferenceQueue() {
+ ReferenceQueue rq = new ReferenceQueue();
+ bool = new Boolean(true);
+ try {
+ SoftReference sr = new SoftReference(bool, rq);
+ assertTrue("Initialization failed.", ((Boolean) sr.get())
+ .booleanValue());
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+
+ boolean exception = false;
+ try {
+ new SoftReference(bool, null);
+ } catch (NullPointerException e) {
+ exception = true;
+ }
+ assertTrue("Should not throw NullPointerException", !exception);
+ }
+
+ /**
+ * java.lang.ref.SoftReference#SoftReference(java.lang.Object)
+ */
+ public void test_ConstructorLjava_lang_Object() {
+ bool = new Boolean(true);
+ try {
+ SoftReference sr = new SoftReference(bool);
+ assertTrue("Initialization failed.", ((Boolean) sr.get())
+ .booleanValue());
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.ref.SoftReference#get()
+ */
+ public void test_get() {
+ bool = new Boolean(false);
+ SoftReference sr = new SoftReference(bool);
+ assertTrue("Same object not returned.", bool == sr.get());
+ }
+
+ // SideEffect: Causes OutOfMemoryError to test finalization
+ public void test_get_SoftReference() {
+
+ class TestObject {
+ public boolean finalized;
+ public TestObject() {
+ finalized = false;
+ }
+
+ protected void finalize() {
+ finalized = true;
+ }
+ }
+
+ final ReferenceQueue rq = new ReferenceQueue();
+
+ class TestThread extends Thread {
+ public void run() {
+ Object testObj = new TestObject();
+ r = new SoftReference(testObj, rq);
+ }
+ }
+ Reference ref;
+ try {
+ TestThread t = new TestThread();
+ t.start();
+ t.join();
+ Vector<StringBuffer> v = new Vector<StringBuffer>();
+ try {
+ while(true) {
+ v.add(new StringBuffer(10000));
+ }
+ } catch(OutOfMemoryError ofme) {
+ v = null;
+ }
+ } catch (InterruptedException e) {
+ fail("InterruptedException : " + e.getMessage());
+ }
+
+ assertNull("get() should return null " +
+ "if OutOfMemoryError is thrown.", r.get());
+
+ try {
+ TestThread t = new TestThread();
+ t.start();
+ t.join();
+ FinalizationTester.induceFinalization();
+ ref = rq.poll();
+ assertNotNull("Object not garbage collected.", ref);
+ assertNull("Object is not null.", ref.get());
+ assertNotNull("Object could not be reclaimed.", r.get());
+ } catch (Exception e) {
+ fail("Exception : " + e.getMessage());
+ }
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/WeakReferenceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/WeakReferenceTest.java
new file mode 100644
index 0000000..c881248
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/WeakReferenceTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+public class WeakReferenceTest extends junit.framework.TestCase {
+ static Boolean bool;
+
+ protected void doneSuite() {
+ bool = null;
+ }
+
+ /**
+ * java.lang.ref.WeakReference#WeakReference(java.lang.Object,
+ * java.lang.ref.ReferenceQueue)
+ */
+ public void test_ConstructorLjava_lang_ObjectLjava_lang_ref_ReferenceQueue() {
+ ReferenceQueue rq = new ReferenceQueue();
+ bool = new Boolean(true);
+ try {
+ // Allow the finalizer to run to potentially enqueue
+ WeakReference wr = new WeakReference(bool, rq);
+ assertTrue("Initialization failed.", ((Boolean) wr.get())
+ .booleanValue());
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ // need a reference to bool so the jit does not optimize it away
+ assertTrue("should always pass", bool.booleanValue());
+
+ boolean exception = false;
+ try {
+ new WeakReference(bool, null);
+ } catch (NullPointerException e) {
+ exception = true;
+ }
+ assertTrue("Should not throw NullPointerException", !exception);
+ }
+
+ /**
+ * java.lang.ref.WeakReference#WeakReference(java.lang.Object)
+ */
+ public void test_ConstructorLjava_lang_Object() {
+ bool = new Boolean(true);
+ try {
+ WeakReference wr = new WeakReference(bool);
+ // Allow the finalizer to run to potentially enqueue
+ Thread.sleep(1000);
+ assertTrue("Initialization failed.", ((Boolean) wr.get())
+ .booleanValue());
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ // need a reference to bool so the jit does not optimize it away
+ assertTrue("should always pass", bool.booleanValue());
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/AccessibleObjectTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/AccessibleObjectTest.java
new file mode 100644
index 0000000..60432d7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/AccessibleObjectTest.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.Set;
+
+public class AccessibleObjectTest extends junit.framework.TestCase {
+
+ public class TestClass {
+ public Object aField;
+
+ @InheritedRuntime
+ public void annotatedMethod(){}
+ }
+
+ public class SubTestClass extends TestClass{
+ @AnnotationRuntime0
+ @AnnotationRuntime1
+ @AnnotationClass0
+ @AnnotationSource0
+ public void annotatedMethod(){}
+ }
+
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target( {ElementType.METHOD})
+ static @interface AnnotationRuntime0 {
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target( { ElementType.METHOD})
+ static @interface AnnotationRuntime1 {
+ }
+
+ @Retention(RetentionPolicy.CLASS)
+ @Target( { ElementType.METHOD})
+ static @interface AnnotationClass0 {
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @Target( {ElementType.METHOD})
+ static @interface AnnotationSource0 {
+ }
+
+ @Inherited
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target( {ElementType.METHOD})
+ static @interface InheritedRuntime {
+ }
+
+ //used for constructor test
+ private static class MyAccessibleObject extends AccessibleObject{
+ public MyAccessibleObject() {
+ super();
+ }
+ }
+
+ /**
+ * java.lang.reflect.AccessibleObject#AccessibleObject()
+ */
+ public void test_Constructor() {
+ assertNotNull(new MyAccessibleObject());
+ }
+
+ /**
+ * java.lang.reflect.AccessibleObject#isAccessible()
+ */
+ public void test_isAccessible() {
+ // Test for method boolean
+ // java.lang.reflect.AccessibleObject.isAccessible()
+ try {
+ AccessibleObject ao = TestClass.class.getField("aField");
+ ao.setAccessible(true);
+ assertTrue("Returned false to isAccessible", ao.isAccessible());
+ ao.setAccessible(false);
+ assertTrue("Returned true to isAccessible", !ao.isAccessible());
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[],
+ * boolean)
+ */
+ public void test_setAccessible$Ljava_lang_reflect_AccessibleObjectZ() {
+ try {
+ AccessibleObject ao = TestClass.class.getField("aField");
+ AccessibleObject[] aoa = new AccessibleObject[] { ao };
+ AccessibleObject.setAccessible(aoa, true);
+ assertTrue("Returned false to isAccessible", ao.isAccessible());
+ AccessibleObject.setAccessible(aoa, false);
+ assertTrue("Returned true to isAccessible", !ao.isAccessible());
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.AccessibleObject#setAccessible(boolean)
+ */
+ public void test_setAccessible() throws Exception {
+ AccessibleObject ao = TestClass.class.getField("aField");
+ ao.setAccessible(true);
+ assertTrue("Returned false to isAccessible", ao.isAccessible());
+ ao.setAccessible(false);
+ assertFalse("Returned true to isAccessible", ao.isAccessible());
+ }
+
+ public void test_getAnnotation() throws Exception{
+ AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
+ //test error case
+ boolean npeThrown = false;
+ try {
+ ao.getAnnotation(null);
+ fail("NPE expected");
+ } catch (NullPointerException e) {
+ npeThrown = true;
+ }
+ assertTrue("NPE expected", npeThrown);
+
+ //test inherited on method has no effect
+ InheritedRuntime ir = ao.getAnnotation(InheritedRuntime.class);
+ assertNull("Inherited Annotations should have no effect", ir);
+
+ //test ordinary runtime annotation
+ AnnotationRuntime0 rt0 = ao.getAnnotation(AnnotationRuntime0.class);
+ assertNotNull("AnnotationRuntime0 instance expected", rt0);
+ }
+
+ public void test_getAnnotations() throws Exception {
+ AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
+ Annotation[] annotations = ao.getAnnotations();
+ assertEquals(2, annotations.length);
+
+ Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
+ ignoreOrder.add(annotations[0].annotationType());
+ ignoreOrder.add(annotations[1].annotationType());
+
+ assertTrue("Missing @AnnotationRuntime0",
+ ignoreOrder.contains(AnnotationRuntime0.class));
+ assertTrue("Missing @AnnotationRuntime1",
+ ignoreOrder.contains(AnnotationRuntime1.class));
+ }
+
+ public void test_getDeclaredAnnotations() throws Exception {
+ AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
+ Annotation[] annotations = ao.getDeclaredAnnotations();
+ assertEquals(2, annotations.length);
+
+ Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
+ ignoreOrder.add(annotations[0].annotationType());
+ ignoreOrder.add(annotations[1].annotationType());
+
+ assertTrue("Missing @AnnotationRuntime0",
+ ignoreOrder.contains(AnnotationRuntime0.class));
+ assertTrue("Missing @AnnotationRuntime1",
+ ignoreOrder.contains(AnnotationRuntime1.class));
+ }
+
+ public void test_isAnnotationPresent() throws Exception {
+ AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
+ assertTrue("Missing @AnnotationRuntime0",
+ ao.isAnnotationPresent(AnnotationRuntime0.class));
+ assertFalse("AnnotationSource0 should not be visible at runtime",
+ ao.isAnnotationPresent(AnnotationSource0.class));
+ boolean npeThrown = false;
+ try {
+ ao.isAnnotationPresent(null);
+ fail("NPE expected");
+ } catch (NullPointerException e) {
+ npeThrown = true;
+ }
+ assertTrue("NPE expected", npeThrown);
+ }
+
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ArrayTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ArrayTest.java
new file mode 100644
index 0000000..98dd034
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ArrayTest.java
@@ -0,0 +1,1001 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.Array;
+
+public class ArrayTest extends junit.framework.TestCase {
+
+ /**
+ * java.lang.reflect.Array#get(java.lang.Object, int)
+ */
+ public void test_getLjava_lang_ObjectI() {
+ // Test for method java.lang.Object
+ // java.lang.reflect.Array.get(java.lang.Object, int)
+
+ int[] x = { 1 };
+ Object ret = null;
+ boolean thrown = false;
+ try {
+ ret = Array.get(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value",
+ 1, ((Integer) ret).intValue());
+ try {
+ ret = Array.get(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.get(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ //same test with non primitive component type
+ Integer[] y = new Integer[]{ 1 };
+ ret = null;
+ thrown = false;
+ try {
+ ret = Array.get(y, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value",
+ 1, ((Integer) ret).intValue());
+ try {
+ ret = Array.get(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.get(y, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#getBoolean(java.lang.Object, int)
+ */
+ public void test_getBooleanLjava_lang_ObjectI() {
+ // Test for method boolean
+ // java.lang.reflect.Array.getBoolean(java.lang.Object, int)
+ boolean[] x = { true };
+ boolean ret = false;
+ boolean thrown = false;
+ try {
+ ret = Array.getBoolean(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertTrue("Get returned incorrect value", ret);
+ try {
+ ret = Array.getBoolean(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getBoolean(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getBoolean(null, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#getByte(java.lang.Object, int)
+ */
+ public void test_getByteLjava_lang_ObjectI() {
+ // Test for method byte
+ // java.lang.reflect.Array.getByte(java.lang.Object, int)
+ byte[] x = { 1 };
+ byte ret = 0;
+ boolean thrown = false;
+ try {
+ ret = Array.getByte(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, ret);
+ try {
+ ret = Array.getByte(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getByte(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getByte(null, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#getChar(java.lang.Object, int)
+ */
+ public void test_getCharLjava_lang_ObjectI() {
+ // Test for method char
+ // java.lang.reflect.Array.getChar(java.lang.Object, int)
+ char[] x = { 1 };
+ char ret = 0;
+ boolean thrown = false;
+ try {
+ ret = Array.getChar(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, ret);
+ try {
+ ret = Array.getChar(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getChar(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getChar(null, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#getDouble(java.lang.Object, int)
+ */
+ public void test_getDoubleLjava_lang_ObjectI() {
+ // Test for method double
+ // java.lang.reflect.Array.getDouble(java.lang.Object, int)
+ double[] x = { 1 };
+ double ret = 0;
+ boolean thrown = false;
+ try {
+ ret = Array.getDouble(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, ret, 0.0);
+ try {
+ ret = Array.getDouble(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getDouble(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getDouble(null, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#getFloat(java.lang.Object, int)
+ */
+ public void test_getFloatLjava_lang_ObjectI() {
+ // Test for method float
+ // java.lang.reflect.Array.getFloat(java.lang.Object, int)
+ float[] x = { 1 };
+ float ret = 0;
+ boolean thrown = false;
+ try {
+ ret = Array.getFloat(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, ret, 0.0);
+ try {
+ ret = Array.getFloat(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getFloat(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getFloat(null, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#getInt(java.lang.Object, int)
+ */
+ public void test_getIntLjava_lang_ObjectI() {
+ // Test for method int java.lang.reflect.Array.getInt(java.lang.Object,
+ // int)
+ int[] x = { 1 };
+ int ret = 0;
+ boolean thrown = false;
+ try {
+ ret = Array.getInt(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, ret);
+ try {
+ ret = Array.getInt(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getInt(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getInt(null, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#getLength(java.lang.Object)
+ */
+ public void test_getLengthLjava_lang_Object() {
+ // Test for method int
+ // java.lang.reflect.Array.getLength(java.lang.Object)
+ long[] x = { 1 };
+
+ assertEquals("Returned incorrect length", 1, Array.getLength(x));
+ assertEquals("Returned incorrect length", 10000, Array
+ .getLength(new Object[10000]));
+ try {
+ Array.getLength(new Object());
+ } catch (IllegalArgumentException e) {
+ // Correct
+ return;
+ }
+ fail("Failed to throw exception when passed non-array");
+ }
+
+ /**
+ * java.lang.reflect.Array#getLong(java.lang.Object, int)
+ */
+ public void test_getLongLjava_lang_ObjectI() {
+ // Test for method long
+ // java.lang.reflect.Array.getLong(java.lang.Object, int)
+ long[] x = { 1 };
+ long ret = 0;
+ boolean thrown = false;
+ try {
+ ret = Array.getLong(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, ret);
+ try {
+ ret = Array.getLong(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getLong(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getLong(null, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#getShort(java.lang.Object, int)
+ */
+ public void test_getShortLjava_lang_ObjectI() {
+ // Test for method short
+ // java.lang.reflect.Array.getShort(java.lang.Object, int)
+ short[] x = { 1 };
+ short ret = 0;
+ boolean thrown = false;
+ try {
+ ret = Array.getShort(x, 0);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, ret);
+ try {
+ ret = Array.getShort(new Object(), 0);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getShort(x, 4);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+ thrown = false;
+ try {
+ ret = Array.getShort(null, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#newInstance(java.lang.Class, int[])
+ */
+ public void test_newInstanceLjava_lang_Class$I() {
+ // Test for method java.lang.Object
+ // java.lang.reflect.Array.newInstance(java.lang.Class, int [])
+ int[][] x;
+ int[] y = { 2 };
+
+ x = (int[][]) Array.newInstance(int[].class, y);
+ assertEquals("Failed to instantiate array properly", 2, x.length);
+
+ boolean thrown = false;
+ try {
+ x = (int[][]) Array.newInstance(null, y);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+
+ thrown = false;
+ try {
+ Array.newInstance(int[].class, new int[]{1,-1});
+ } catch (NegativeArraySizeException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Negative array size failed to throw NegativeArraySizeException");
+ }
+
+ thrown = false;
+ try {
+ Array.newInstance(int[].class, new int[]{});
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Zero array size failed to throw IllegalArgumentException");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#newInstance(java.lang.Class, int)
+ */
+ public void test_newInstanceLjava_lang_ClassI() {
+ // Test for method java.lang.Object
+ // java.lang.reflect.Array.newInstance(java.lang.Class, int)
+ int[] x;
+
+ x = (int[]) Array.newInstance(int.class, 100);
+ assertEquals("Failed to instantiate array properly", 100, x.length);
+
+ boolean thrown = false;
+ try {
+ Array.newInstance(null, 100);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+
+ thrown = false;
+ try {
+ Array.newInstance(int[].class, -1);
+ } catch (NegativeArraySizeException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Negative array size failed to throw NegativeArraySizeException");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#set(java.lang.Object, int,
+ * java.lang.Object)
+ */
+ public void test_setLjava_lang_ObjectILjava_lang_Object() {
+ // Test for method void java.lang.reflect.Array.set(java.lang.Object,
+ // int, java.lang.Object)
+ int[] x = { 0 };
+ boolean thrown = false;
+ try {
+ Array.set(x, 0, new Integer(1));
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, ((Integer) Array.get(x, 0))
+ .intValue());
+ try {
+ Array.set(new Object(), 0, new Object());
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.set(x, 4, new Integer(1));
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ // trying to put null in a primitive array causes
+ // a IllegalArgumentException in 5.0
+ boolean exception = false;
+ try {
+ Array.set(new int[1], 0, null);
+ } catch (IllegalArgumentException e) {
+ exception = true;
+ }
+ assertTrue("expected exception not thrown", exception);
+
+ thrown = false;
+ try {
+ Array.set(null, 0, 2);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#setBoolean(java.lang.Object, int, boolean)
+ */
+ public void test_setBooleanLjava_lang_ObjectIZ() {
+ // Test for method void
+ // java.lang.reflect.Array.setBoolean(java.lang.Object, int, boolean)
+ boolean[] x = { false };
+ boolean thrown = false;
+ try {
+ Array.setBoolean(x, 0, true);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertTrue("Failed to set correct value", Array.getBoolean(x, 0));
+ try {
+ Array.setBoolean(new Object(), 0, false);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown){
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.setBoolean(x, 4, false);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ thrown = false;
+ try {
+ Array.setBoolean(null, 0, true);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#setByte(java.lang.Object, int, byte)
+ */
+ public void test_setByteLjava_lang_ObjectIB() {
+ // Test for method void
+ // java.lang.reflect.Array.setByte(java.lang.Object, int, byte)
+ byte[] x = { 0 };
+ boolean thrown = false;
+ try {
+ Array.setByte(x, 0, (byte) 1);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, Array.getByte(x, 0));
+ try {
+ Array.setByte(new Object(), 0, (byte) 9);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.setByte(x, 4, (byte) 9);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ thrown = false;
+ try {
+ Array.setByte(null, 0, (byte)0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#setChar(java.lang.Object, int, char)
+ */
+ public void test_setCharLjava_lang_ObjectIC() {
+ // Test for method void
+ // java.lang.reflect.Array.setChar(java.lang.Object, int, char)
+ char[] x = { 0 };
+ boolean thrown = false;
+ try {
+ Array.setChar(x, 0, (char) 1);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, Array.getChar(x, 0));
+ try {
+ Array.setChar(new Object(), 0, (char) 9);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.setChar(x, 4, (char) 9);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ thrown = false;
+ try {
+ Array.setChar(null, 0, (char)0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#setDouble(java.lang.Object, int, double)
+ */
+ public void test_setDoubleLjava_lang_ObjectID() {
+ // Test for method void
+ // java.lang.reflect.Array.setDouble(java.lang.Object, int, double)
+ double[] x = { 0 };
+ boolean thrown = false;
+ try {
+ Array.setDouble(x, 0, 1);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, Array.getDouble(x, 0), 0.0);
+ try {
+ Array.setDouble(new Object(), 0, 9);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.setDouble(x, 4, 9);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ thrown = false;
+ try {
+ Array.setDouble(null, 0, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#setFloat(java.lang.Object, int, float)
+ */
+ public void test_setFloatLjava_lang_ObjectIF() {
+ // Test for method void
+ // java.lang.reflect.Array.setFloat(java.lang.Object, int, float)
+ float[] x = { 0.0f };
+ boolean thrown = false;
+ try {
+ Array.setFloat(x, 0, (float) 1);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, Array.getFloat(x, 0), 0.0);
+ try {
+ Array.setFloat(new Object(), 0, (float) 9);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.setFloat(x, 4, (float) 9);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ thrown = false;
+ try {
+ Array.setFloat(null, 0, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#setInt(java.lang.Object, int, int)
+ */
+ public void test_setIntLjava_lang_ObjectII() {
+ // Test for method void java.lang.reflect.Array.setInt(java.lang.Object,
+ // int, int)
+ int[] x = { 0 };
+ boolean thrown = false;
+ try {
+ Array.setInt(x, 0, (int) 1);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, Array.getInt(x, 0));
+ try {
+ Array.setInt(new Object(), 0, (int) 9);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.setInt(x, 4, (int) 9);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ thrown = false;
+ try {
+ Array.setInt(null, 0, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#setLong(java.lang.Object, int, long)
+ */
+ public void test_setLongLjava_lang_ObjectIJ() {
+ // Test for method void
+ // java.lang.reflect.Array.setLong(java.lang.Object, int, long)
+ long[] x = { 0 };
+ boolean thrown = false;
+ try {
+ Array.setLong(x, 0, 1);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, Array.getLong(x, 0));
+ try {
+ Array.setLong(new Object(), 0, 9);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.setLong(x, 4, 9);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ thrown = false;
+ try {
+ Array.setLong(null, 0, 0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * java.lang.reflect.Array#setShort(java.lang.Object, int, short)
+ */
+ public void test_setShortLjava_lang_ObjectIS() {
+ // Test for method void
+ // java.lang.reflect.Array.setShort(java.lang.Object, int, short)
+ short[] x = { 0 };
+ boolean thrown = false;
+ try {
+ Array.setShort(x, 0, (short) 1);
+ } catch (Exception e) {
+ fail("Exception during get test : " + e.getMessage());
+ }
+ assertEquals("Get returned incorrect value", 1, Array.getShort(x, 0));
+ try {
+ Array.setShort(new Object(), 0, (short) 9);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Passing non-array failed to throw exception");
+ }
+ thrown = false;
+ try {
+ Array.setShort(x, 4, (short) 9);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Invalid index failed to throw exception");
+ }
+
+ thrown = false;
+ try {
+ Array.setShort(null, 0, (short)0);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Null argument failed to throw NPE");
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/BoundedGenericMethodsTests.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/BoundedGenericMethodsTests.java
new file mode 100644
index 0000000..130aa72
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/BoundedGenericMethodsTests.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+/**
+ * Tests bounded type parameters declared on methods.
+ */
+public class BoundedGenericMethodsTests extends GenericReflectionTestsBase {
+ @SuppressWarnings("unchecked")
+ static class BoundedGenericMethods<S> {
+
+ public <T extends BoundedGenericMethods> void noParamNoReturn() {}
+ public <T extends BoundedGenericMethods> void paramNoReturn(T param) {}
+
+ public <T extends BoundedGenericMethods> T noParamReturn() {
+ return (T) new Object();
+ }
+ public <T extends BoundedGenericMethods> T paramReturn(T t) {
+ return t;
+ }
+ }
+ @SuppressWarnings("unchecked")
+ private static Class<? extends BoundedGenericMethods> clazz = BoundedGenericMethodsTests.BoundedGenericMethods.class;
+
+ /**
+ * Tests whether the type parameter is upper bounded by BoundedGenericMethods.
+ * <T extends BoundedGenericMethods>.
+ *
+ * @param method
+ * the declaring method
+ */
+ private void checkBoundedTypeParameter(Method method) {
+ TypeVariable<Method> typeParameter = getTypeParameter(method);
+ assertEquals("T", typeParameter.getName());
+ assertEquals(method, typeParameter.getGenericDeclaration());
+
+ Type[] bounds = typeParameter.getBounds();
+ assertLenghtOne(bounds);
+ Type bound = bounds[0];
+ assertEquals(BoundedGenericMethods.class, bound);
+ }
+
+ /**
+ * Tests whether the specified method declares a parameter with the type of
+ * the type parameter.
+ *
+ * @param method
+ * the declaring method
+ */
+ private void parameterType(Method method) {
+ TypeVariable<Method> typeParameter = getTypeParameter(method);
+ assertLenghtOne(method.getGenericParameterTypes());
+ Type genericParameterType = method.getGenericParameterTypes()[0];
+ assertEquals(typeParameter, genericParameterType);
+ assertTrue(genericParameterType instanceof TypeVariable);
+ TypeVariable<?> typeVariable = (TypeVariable<?>) genericParameterType;
+ assertEquals(method, typeVariable.getGenericDeclaration());
+
+ Type[] paramBounds = typeVariable.getBounds();
+ assertLenghtOne(paramBounds);
+ Type paramBound = paramBounds[0];
+ assertEquals(BoundedGenericMethods.class, paramBound);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void checkReturnType(Method method) {
+ Type genericReturnType = method.getGenericReturnType();
+ assertEquals(getTypeParameter(method), genericReturnType);
+ assertTrue(genericReturnType instanceof TypeVariable);
+
+ TypeVariable<Method> returnTypeVariable = (TypeVariable<Method>) genericReturnType;
+ assertEquals(method, returnTypeVariable.getGenericDeclaration());
+
+ Type[] bounds = returnTypeVariable.getBounds();
+ assertLenghtOne(bounds);
+ Type bound = bounds[0];
+
+ assertEquals(BoundedGenericMethods.class, bound);
+ }
+
+
+
+ /**
+ * Tests that there are is one Type Parameter on the Class itself.
+ */
+ public void testBoundedGenericMethods() {
+ assertLenghtOne(clazz.getTypeParameters());
+ }
+ public void testNoParamNoReturn() throws SecurityException, NoSuchMethodException {
+ Method method = clazz.getMethod("noParamNoReturn");
+ checkBoundedTypeParameter(method);
+ }
+ public void testUnboundedParamNoReturn() throws SecurityException, NoSuchMethodException {
+ Method method = clazz.getMethod("paramNoReturn", BoundedGenericMethods.class);
+ checkBoundedTypeParameter(method);
+ parameterType(method);
+ }
+ public void testNoParamReturn() throws SecurityException, NoSuchMethodException {
+ Method method = clazz.getMethod("noParamReturn");
+ checkBoundedTypeParameter(method);
+ assertLenghtZero(method.getGenericParameterTypes());
+ checkReturnType(method);
+ }
+ public void testUnboundedParamReturn() throws SecurityException, NoSuchMethodException {
+ Method method = clazz.getMethod("paramReturn", BoundedGenericMethods.class);
+ checkBoundedTypeParameter(method);
+ parameterType(method);
+ checkReturnType(method);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ConstructorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ConstructorTest.java
new file mode 100644
index 0000000..ec133aa
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ConstructorTest.java
@@ -0,0 +1,442 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ConstructorTest extends junit.framework.TestCase {
+
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+ static @interface ConstructorTestAnnotationRuntime0 {
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+ static @interface ConstructorTestAnnotationRuntime1 {
+ }
+
+ @Retention(RetentionPolicy.CLASS)
+ @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+ static @interface ConstructorTestAnnotationClass0 {
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+ static @interface ConstructorTestAnnotationSource0 {
+ }
+
+ static class ConstructorTestHelper extends Object {
+ int cval;
+
+ @ConstructorTestAnnotationRuntime0
+ @ConstructorTestAnnotationRuntime1
+ @ConstructorTestAnnotationClass0
+ @ConstructorTestAnnotationSource0
+ public ConstructorTestHelper() throws IndexOutOfBoundsException {
+ cval = 99;
+ }
+
+ public ConstructorTestHelper(
+ @ConstructorTestAnnotationRuntime0
+ @ConstructorTestAnnotationRuntime1
+ @ConstructorTestAnnotationClass0
+ @ConstructorTestAnnotationSource0 Object x) {
+ }
+
+ public ConstructorTestHelper(String... x) {
+ }
+
+ private ConstructorTestHelper(int a) {
+ }
+
+ protected ConstructorTestHelper(long a) {
+ }
+
+ public int check() {
+ return cval;
+ }
+ }
+
+ static class GenericConstructorTestHelper<T, S extends T, E extends Exception> {
+ public GenericConstructorTestHelper(T t, S s) {}
+ public GenericConstructorTestHelper() throws E{}
+ }
+
+ static class NoPublicConstructorTestHelper {
+ // This class has no public constructor.
+ }
+
+// Used to test synthetic constructor.
+//
+// static class Outer {
+// private Outer(){}
+// class Inner {
+// {new Outer();}
+// }
+// }
+
+ public void test_getParameterAnnotations() throws Exception {
+ Constructor<ConstructorTestHelper> ctor1 = ConstructorTestHelper.class
+ .getConstructor(Object.class);
+ Annotation[][] paramAnnotations = ctor1.getParameterAnnotations();
+ assertEquals("Annotations for wrong number of parameters returned", 1,
+ paramAnnotations.length);
+ assertEquals("Wrong number of annotations returned", 2,
+ paramAnnotations[0].length);
+
+ Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
+ ignoreOrder.add(paramAnnotations[0][0].annotationType());
+ ignoreOrder.add(paramAnnotations[0][1].annotationType());
+
+ assertTrue("Missing ConstructorTestAnnotationRuntime0", ignoreOrder
+ .contains(ConstructorTestAnnotationRuntime0.class));
+ assertTrue("Missing ConstructorTestAnnotationRuntime1", ignoreOrder
+ .contains(ConstructorTestAnnotationRuntime1.class));
+ }
+
+
+ public void test_getDeclaredAnnotations() throws Exception {
+ Constructor<ConstructorTestHelper> ctor1 = null;
+ ctor1 = ConstructorTestHelper.class.getConstructor(new Class[0]);
+ Annotation[] annotations = ctor1.getDeclaredAnnotations();
+ assertEquals("Wrong number of annotations returned", 2,
+ annotations.length);
+ Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
+ ignoreOrder.add(annotations[0].annotationType());
+ ignoreOrder.add(annotations[1].annotationType());
+
+ assertTrue("Missing ConstructorTestAnnotationRuntime0", ignoreOrder
+ .contains(ConstructorTestAnnotationRuntime0.class));
+ assertTrue("Missing ConstructorTestAnnotationRuntime1", ignoreOrder
+ .contains(ConstructorTestAnnotationRuntime1.class));
+ }
+
+ public void test_isVarArgs() throws Exception {
+ Constructor<ConstructorTestHelper> varArgCtor = ConstructorTestHelper.class
+ .getConstructor(String[].class);
+ assertTrue("Vararg constructor not recognized", varArgCtor.isVarArgs());
+
+ Constructor<ConstructorTestHelper> nonVarArgCtor = ConstructorTestHelper.class
+ .getConstructor(Object.class);
+ assertFalse("Non vararg constructor recognized as vararg constructor",
+ nonVarArgCtor.isVarArgs());
+ }
+
+ public void test_hashCode() throws Exception {
+ Constructor<ConstructorTestHelper> constructor = ConstructorTestHelper.class
+ .getConstructor();
+ assertEquals(
+ "The constructor's hashCode is not equal to the hashCode of the name of the declaring class",
+ ConstructorTestHelper.class.getName().hashCode(), constructor
+ .hashCode());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void test_toGenericString() throws Exception {
+ Constructor<GenericConstructorTestHelper> genericCtor = GenericConstructorTestHelper.class
+ .getConstructor(Object.class, Object.class);
+ assertEquals(
+ "Wrong generic string returned",
+ "public org.apache.harmony.tests.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper(T,S)",
+ genericCtor.toGenericString());
+ Constructor<GenericConstructorTestHelper> ctor = GenericConstructorTestHelper.class
+ .getConstructor();
+ assertEquals(
+ "Wrong generic string returned",
+ "public org.apache.harmony.tests.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper() throws E",
+ ctor.toGenericString());
+ }
+
+ public void test_equalsLjava_lang_Object() {
+ Constructor<ConstructorTestHelper> ctor1 = null, ctor2 = null;
+ try {
+ ctor1 = ConstructorTestHelper.class.getConstructor(
+ new Class[0]);
+ ctor2 = ConstructorTestHelper.class.getConstructor(Object.class);
+ } catch (Exception e) {
+ fail("Exception during equals test : " + e.getMessage());
+ }
+ assertTrue("Different Contructors returned equal", !ctor1.equals(ctor2));
+ }
+
+ public void test_getDeclaringClass() {
+ boolean val = false;
+ try {
+ Class<? extends ConstructorTestHelper> pclass = new ConstructorTestHelper().getClass();
+ Constructor<? extends ConstructorTestHelper> ctor = pclass.getConstructor(new Class[0]);
+ val = ctor.getDeclaringClass().equals(pclass);
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ assertTrue("Returned incorrect declaring class", val);
+ }
+
+ public void test_getExceptionTypes() {
+ // Test for method java.lang.Class []
+ // java.lang.reflect.Constructor.getExceptionTypes()
+ Class[] exceptions = null;
+ Class<? extends IndexOutOfBoundsException> ex = null;
+ try {
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
+ .getConstructor(new Class[0]);
+ exceptions = ctor.getExceptionTypes();
+ ex = new IndexOutOfBoundsException().getClass();
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ assertEquals("Returned exception list of incorrect length",
+ 1, exceptions.length);
+ assertTrue("Returned incorrect exception", exceptions[0].equals(ex));
+ }
+
+ public void test_getModifiers() {
+ // Test for method int java.lang.reflect.Constructor.getModifiers()
+ int mod = 0;
+ try {
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
+ .getConstructor(new Class[0]);
+ mod = ctor.getModifiers();
+ assertTrue("Returned incorrect modifers for public ctor",
+ ((mod & Modifier.PUBLIC) == Modifier.PUBLIC)
+ && ((mod & Modifier.PRIVATE) == 0));
+ } catch (NoSuchMethodException e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ try {
+ Class[] cl = { int.class };
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
+ .getDeclaredConstructor(cl);
+ mod = ctor.getModifiers();
+ assertTrue("Returned incorrect modifers for private ctor",
+ ((mod & Modifier.PRIVATE) == Modifier.PRIVATE)
+ && ((mod & Modifier.PUBLIC) == 0));
+ } catch (NoSuchMethodException e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ try {
+ Class[] cl = { long.class };
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
+ .getDeclaredConstructor(cl);
+ mod = ctor.getModifiers();
+ assertTrue("Returned incorrect modifers for private ctor",
+ ((mod & Modifier.PROTECTED) == Modifier.PROTECTED)
+ && ((mod & Modifier.PUBLIC) == 0));
+ } catch (NoSuchMethodException e) {
+ fail("NoSuchMethodException during test : " + e.getMessage());
+ }
+ }
+
+ public void test_getName() {
+ // Test for method java.lang.String
+ // java.lang.reflect.Constructor.getName()
+ try {
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
+ .getConstructor(new Class[0]);
+ assertTrue(
+ "Returned incorrect name: " + ctor.getName(),
+ ctor
+ .getName()
+ .equals(
+ "org.apache.harmony.tests.java.lang.reflect.ConstructorTest$ConstructorTestHelper"));
+ } catch (Exception e) {
+ fail("Exception obtaining contructor : " + e.getMessage());
+ }
+ }
+
+ public void test_getParameterTypes() {
+ // Test for method java.lang.Class []
+ // java.lang.reflect.Constructor.getParameterTypes()
+ Class[] types = null;
+ try {
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
+ .getConstructor(new Class[0]);
+ types = ctor.getParameterTypes();
+ } catch (Exception e) {
+ fail("Exception during getParameterTypes test:"
+ + e.toString());
+ }
+ assertEquals("Incorrect parameter returned", 0, types.length);
+
+ Class[] parms = null;
+ try {
+ parms = new Class[1];
+ parms[0] = new Object().getClass();
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
+ .getConstructor(parms);
+ types = ctor.getParameterTypes();
+ } catch (Exception e) {
+ fail("Exception during getParameterTypes test:"
+ + e.toString());
+ }
+ assertTrue("Incorrect parameter returned", types[0].equals(parms[0]));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void test_getGenericParameterTypes() {
+ Type[] types = null;
+ try {
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
+ .getClass().getConstructor(new Class[0]);
+ types = ctor.getGenericParameterTypes();
+ } catch (Exception e) {
+ fail("Exception during getParameterTypes test:" + e.toString());
+ }
+ assertEquals("Incorrect parameter returned", 0, types.length);
+
+ Class<?>[] parms = null;
+ try {
+ parms = new Class[] {Object.class};
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
+ .getClass().getConstructor(parms);
+ types = ctor.getGenericParameterTypes();
+ } catch (Exception e) {
+ fail("Exception during getParameterTypes test:" + e.toString());
+ }
+ assertTrue("Incorrect parameter returned", types[0].equals(parms[0]));
+
+
+ try {
+ Constructor<GenericConstructorTestHelper> constructor = GenericConstructorTestHelper.class
+ .getConstructor(Object.class, Object.class);
+ types = constructor.getGenericParameterTypes();
+ } catch (Exception e) {
+ fail("Exception during getParameterTypes test:" + e.toString());
+ }
+
+ assertEquals("Wrong number of parameter types returned", 2,
+ types.length);
+
+ assertEquals("Wrong number of parameter types returned", "T",
+ ((TypeVariable)types[0]).getName());
+ assertEquals("Wrong number of parameter types returned", "S",
+ ((TypeVariable)types[1]).getName());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void test_getGenericExceptionTypes() {
+ Type[] types = null;
+
+ try {
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
+ .getClass().getConstructor(new Class[0]);
+ types = ctor.getGenericExceptionTypes();
+ } catch (Exception e) {
+ fail("Exception during getGenericExceptionTypes test:" + e.toString());
+ }
+ assertEquals("Wrong number of exception types returned", 1, types.length);
+
+
+ try {
+ Constructor<GenericConstructorTestHelper> constructor = GenericConstructorTestHelper.class
+ .getConstructor();
+ types = constructor.getGenericExceptionTypes();
+ } catch (Exception e) {
+ fail("Exception during getGenericExceptionTypes test:"
+ + e.toString());
+ }
+
+ assertEquals("Wrong number of exception types returned", 1,
+ types.length);
+
+ assertEquals("Wrong exception name returned.", "E",
+ ((TypeVariable)types[0]).getName());
+
+ }
+
+
+ public void test_newInstance$Ljava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.lang.reflect.Constructor.newInstance(java.lang.Object [])
+
+ ConstructorTestHelper test = null;
+ try {
+ Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
+ .getConstructor(new Class[0]);
+ test = ctor.newInstance((Object[])null);
+ } catch (Exception e) {
+ fail("Failed to create instance : " + e.getMessage());
+ }
+ assertEquals("improper instance created", 99, test.check());
+ }
+
+ public void test_toString() {
+ // Test for method java.lang.String
+ // java.lang.reflect.Constructor.toString()
+ Class[] parms = null;
+ Constructor<? extends ConstructorTestHelper> ctor = null;
+ try {
+ parms = new Class[1];
+ parms[0] = new Object().getClass();
+ ctor = new ConstructorTestHelper().getClass().getConstructor(parms);
+ } catch (Exception e) {
+ fail("Exception during getParameterTypes test:"
+ + e.toString());
+ }
+ assertTrue(
+ "Returned incorrect string representation: " + ctor.toString(),
+ ctor
+ .toString()
+ .equals(
+ "public org.apache.harmony.tests.java.lang.reflect.ConstructorTest$ConstructorTestHelper(java.lang.Object)"));
+ }
+
+ public void test_getConstructor() throws Exception {
+ // Passing new Class[0] should be equivalent to (Class[]) null.
+ Class<ConstructorTestHelper> c2 = ConstructorTestHelper.class;
+ assertEquals(c2.getConstructor(new Class[0]), c2.getConstructor((Class[]) null));
+ assertEquals(c2.getDeclaredConstructor(new Class[0]),
+ c2.getDeclaredConstructor((Class[]) null));
+
+ // We can get a non-public constructor via getDeclaredConstructor...
+ Class<NoPublicConstructorTestHelper> c1 = NoPublicConstructorTestHelper.class;
+ c1.getDeclaredConstructor((Class[]) null);
+ // ...but not with getConstructor (which only returns public constructors).
+ try {
+ c1.getConstructor((Class[]) null);
+ fail("Should throw NoSuchMethodException");
+ } catch (NoSuchMethodException ex) {
+ // Expected.
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/FieldTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/FieldTest.java
new file mode 100644
index 0000000..d5ce8c2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/FieldTest.java
@@ -0,0 +1,1639 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import tests.support.Support_Field;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.HashSet;
+import java.util.Set;
+
+public class FieldTest extends junit.framework.TestCase {
+
+ // BEGIN android-note
+ // This test had a couple of bugs in it. Some parts of the code were
+ // unreachable before. Also some tests expected the wrong excpetions
+ // to be thrown. This version has been validated to pass on a standard
+ // JDK 1.5.
+ // END android-note
+
+ public class TestClass {
+ @AnnotationRuntime0
+ @AnnotationRuntime1
+ @AnnotationClass0
+ @AnnotationSource0
+ public int annotatedField;
+ class Inner{}
+ }
+
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target( {ElementType.FIELD})
+ static @interface AnnotationRuntime0 {
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target( { ElementType.FIELD})
+ static @interface AnnotationRuntime1 {
+ }
+
+ @Retention(RetentionPolicy.CLASS)
+ @Target( { ElementType.FIELD})
+ static @interface AnnotationClass0 {
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @Target( {ElementType.FIELD})
+ static @interface AnnotationSource0 {
+ }
+
+ @Inherited
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target( {ElementType.FIELD})
+ static @interface InheritedRuntime {
+ }
+
+ public class GenericField<S, T extends Number> {
+ S field;
+ T boundedField;
+ int intField;
+ }
+
+
+ static class TestField {
+ public static int pubfield1;
+
+ private static int privfield1 = 123;
+
+ protected int intField = Integer.MAX_VALUE;
+ protected final int intFField = Integer.MAX_VALUE;
+ protected static int intSField = Integer.MAX_VALUE;
+ private final int intPFField = Integer.MAX_VALUE;
+
+ protected short shortField = Short.MAX_VALUE;
+ protected final short shortFField = Short.MAX_VALUE;
+ protected static short shortSField = Short.MAX_VALUE;
+ private final short shortPFField = Short.MAX_VALUE;
+
+ protected boolean booleanField = true;
+ protected static boolean booleanSField = true;
+ protected final boolean booleanFField = true;
+ private final boolean booleanPFField = true;
+
+ protected byte byteField = Byte.MAX_VALUE;
+ protected static byte byteSField = Byte.MAX_VALUE;
+ protected final byte byteFField = Byte.MAX_VALUE;
+ private final byte bytePFField = Byte.MAX_VALUE;
+
+ protected long longField = Long.MAX_VALUE;
+ protected final long longFField = Long.MAX_VALUE;
+ protected static long longSField = Long.MAX_VALUE;
+ private final long longPFField = Long.MAX_VALUE;
+
+ protected double doubleField = Double.MAX_VALUE;
+ protected static double doubleSField = Double.MAX_VALUE;
+ protected static final double doubleSFField = Double.MAX_VALUE;
+ protected final double doubleFField = Double.MAX_VALUE;
+ private final double doublePFField = Double.MAX_VALUE;
+
+ protected float floatField = Float.MAX_VALUE;
+ protected final float floatFField = Float.MAX_VALUE;
+ protected static float floatSField = Float.MAX_VALUE;
+ private final float floatPFField = Float.MAX_VALUE;
+
+ protected char charField = 'T';
+ protected static char charSField = 'T';
+ private final char charPFField = 'T';
+
+ protected final char charFField = 'T';
+
+ private static final int x = 1;
+
+ public volatile transient int y = 0;
+
+ protected static transient volatile int prsttrvol = 99;
+ }
+
+ public class TestFieldSub1 extends TestField {
+ }
+
+ public class TestFieldSub2 extends TestField {
+ }
+
+ static class A {
+ protected short shortField = Short.MAX_VALUE;
+ }
+
+ static enum TestEnum {
+ A, B, C;
+ int field;
+ }
+
+ /**
+ * java.lang.reflect.Field#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.lang.reflect.Field.equals(java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ try {
+ f = TestField.class.getDeclaredField("shortField");
+ } catch (Exception e) {
+ fail("Exception during getType test : " + e.getMessage());
+ }
+ try {
+ assertTrue("Same Field returned false", f.equals(f));
+ assertTrue("Inherited Field returned false", f.equals(TestField.class
+ .getDeclaredField("shortField")));
+ assertTrue("Identical Field from different class returned true", !f
+ .equals(A.class.getDeclaredField("shortField")));
+ } catch (Exception e) {
+ fail("Exception during getType test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#get(java.lang.Object)
+ */
+ public void test_getLjava_lang_Object() throws Throwable {
+ // Test for method java.lang.Object
+ // java.lang.reflect.Field.get(java.lang.Object)
+ TestField x = new TestField();
+ Field f = TestField.class.getDeclaredField("doubleField");
+ Double val = (Double) f.get(x);
+
+ assertTrue("Returned incorrect double field value",
+ val.doubleValue() == Double.MAX_VALUE);
+ // Test getting a static field;
+ f = TestField.class.getDeclaredField("doubleSField");
+ f.set(x, new Double(1.0));
+ val = (Double) f.get(x);
+ assertEquals("Returned incorrect double field value", 1.0, val.doubleValue());
+
+ // Try a get on a private field in nested member
+ // temporarily commented because it breaks J9 VM
+ // Regression for HARMONY-1309
+ //f = x.getClass().getDeclaredField("privfield1");
+ //assertEquals(x.privfield1, f.get(x));
+
+ // Try a get using an invalid class.
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.get(new String());
+ fail("No expected IllegalArgumentException");
+ } catch (IllegalArgumentException exc) {
+ // Correct - Passed an Object that does not declare or inherit f
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("intField");
+ f.get(null);
+ fail("Expected NullPointerException not thrown");
+ } catch (NullPointerException exc) {
+ // Correct - Passed an Object that does not declare or inherit f
+ thrown = true;
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static fields
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleSField");
+ f.get(null);
+ assertTrue("Exception thrown", true);
+ } catch (Exception exc) {
+ fail("No exception expected");
+ }
+ }
+
+ class SupportSubClass extends Support_Field {
+
+ Object getField(char primitiveType, Object o, Field f,
+ Class expected) {
+ Object res = null;
+ try {
+ primitiveType = Character.toUpperCase(primitiveType);
+ switch (primitiveType) {
+ case 'I': // int
+ res = new Integer(f.getInt(o));
+ break;
+ case 'J': // long
+ res = new Long(f.getLong(o));
+ break;
+ case 'Z': // boolean
+ res = new Boolean(f.getBoolean(o));
+ break;
+ case 'S': // short
+ res = new Short(f.getShort(o));
+ break;
+ case 'B': // byte
+ res = new Byte(f.getByte(o));
+ break;
+ case 'C': // char
+ res = new Character(f.getChar(o));
+ break;
+ case 'D': // double
+ res = new Double(f.getDouble(o));
+ break;
+ case 'F': // float
+ res = new Float(f.getFloat(o));
+ break;
+ default:
+ res = f.get(o);
+ }
+ // Since 2011, members are always accessible and throwing is optional
+ assertTrue("expected " + expected + " for " + f.getName(),
+ expected == null || expected == IllegalAccessException.class);
+ } catch (Exception e) {
+ if (expected == null) {
+ fail("unexpected exception " + e);
+ } else {
+ assertTrue("expected exception "
+ + expected.getName() + " and got " + e, e
+ .getClass().equals(expected));
+ }
+ }
+ return res;
+ }
+
+ void setField(char primitiveType, Object o, Field f,
+ Class expected, Object value) {
+ try {
+ primitiveType = Character.toUpperCase(primitiveType);
+ switch (primitiveType) {
+ case 'I': // int
+ f.setInt(o, ((Integer) value).intValue());
+ break;
+ case 'J': // long
+ f.setLong(o, ((Long) value).longValue());
+ break;
+ case 'Z': // boolean
+ f.setBoolean(o, ((Boolean) value).booleanValue());
+ break;
+ case 'S': // short
+ f.setShort(o, ((Short) value).shortValue());
+ break;
+ case 'B': // byte
+ f.setByte(o, ((Byte) value).byteValue());
+ break;
+ case 'C': // char
+ f.setChar(o, ((Character) value).charValue());
+ break;
+ case 'D': // double
+ f.setDouble(o, ((Double) value).doubleValue());
+ break;
+ case 'F': // float
+ f.setFloat(o, ((Float) value).floatValue());
+ break;
+ default:
+ f.set(o, value);
+ }
+ // Since 2011, members are always accessible and throwing is optional
+ assertTrue("expected " + expected + " for " + f.getName() + " = " + value,
+ expected == null || expected == IllegalAccessException.class);
+ } catch (Exception e) {
+ if (expected == null) {
+ e.printStackTrace();
+ fail("unexpected exception " + e + " for field "
+ + f.getName() + ", value " + value);
+ } else {
+ assertTrue("expected exception "
+ + expected.getName() + " and got " + e
+ + " for field " + f.getName() + ", value " + value,
+ e.getClass().equals(expected));
+ }
+ }
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#get(java.lang.Object)
+ * java.lang.reflect.Field#getByte(java.lang.Object)
+ * java.lang.reflect.Field#getBoolean(java.lang.Object)
+ * java.lang.reflect.Field#getShort(java.lang.Object)
+ * java.lang.reflect.Field#getInt(java.lang.Object)
+ * java.lang.reflect.Field#getLong(java.lang.Object)
+ * java.lang.reflect.Field#getFloat(java.lang.Object)
+ * java.lang.reflect.Field#getDouble(java.lang.Object)
+ * java.lang.reflect.Field#getChar(java.lang.Object)
+ * java.lang.reflect.Field#set(java.lang.Object, java.lang.Object)
+ * java.lang.reflect.Field#setByte(java.lang.Object, byte)
+ * java.lang.reflect.Field#setBoolean(java.lang.Object, boolean)
+ * java.lang.reflect.Field#setShort(java.lang.Object, short)
+ * java.lang.reflect.Field#setInt(java.lang.Object, int)
+ * java.lang.reflect.Field#setLong(java.lang.Object, long)
+ * java.lang.reflect.Field#setFloat(java.lang.Object, float)
+ * java.lang.reflect.Field#setDouble(java.lang.Object, double)
+ * java.lang.reflect.Field#setChar(java.lang.Object, char)
+ */
+ public void testProtectedFieldAccess() {
+ Class fieldClass = Support_Field.class;
+ String fieldName = null;
+ Field objectField = null;
+ Field booleanField = null;
+ Field byteField = null;
+ Field charField = null;
+ Field shortField = null;
+ Field intField = null;
+ Field longField = null;
+ Field floatField = null;
+ Field doubleField = null;
+ try {
+ fieldName = "objectField";
+ objectField = fieldClass.getDeclaredField(fieldName);
+
+ fieldName = "booleanField";
+ booleanField = fieldClass.getDeclaredField(fieldName);
+
+ fieldName = "byteField";
+ byteField = fieldClass.getDeclaredField(fieldName);
+
+ fieldName = "charField";
+ charField = fieldClass.getDeclaredField(fieldName);
+
+ fieldName = "shortField";
+ shortField = fieldClass.getDeclaredField(fieldName);
+
+ fieldName = "intField";
+ intField = fieldClass.getDeclaredField(fieldName);
+
+ fieldName = "longField";
+ longField = fieldClass.getDeclaredField(fieldName);
+
+ fieldName = "floatField";
+ floatField = fieldClass.getDeclaredField(fieldName);
+
+ fieldName = "doubleField";
+ doubleField = fieldClass.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e) {
+ fail("missing field " + fieldName + " in test support class "
+ + fieldClass.getName());
+ }
+
+ // create the various objects that might or might not have an instance
+ // of the field
+ Support_Field parentClass = new Support_Field();
+ SupportSubClass subclass = new SupportSubClass();
+ SupportSubClass otherSubclass = new SupportSubClass();
+ Object plainObject = new Object();
+
+ Class illegalAccessExceptionClass = IllegalAccessException.class;
+ Class illegalArgumentExceptionClass = IllegalArgumentException.class;
+
+ // The test will attempt to use pass an object to set for object, byte,
+ // short, ..., float and double fields
+ // and pass a byte to to setByte for byte, short, ..., float and double
+ // fields and so on.
+ // It will also test if IllegalArgumentException is thrown when the
+ // field does not exist in the given object and that
+ // IllegalAccessException is thrown when trying to access an
+ // inaccessible protected field.
+ // The test will also check that IllegalArgumentException is thrown for
+ // all other attempts.
+
+ // Ordered by widening conversion, except for 'L' at the beg (which
+ // stands for Object).
+ // If the object provided to set can be unwrapped to a primitive, then
+ // the set method can set
+ // primitive fields.
+ char types[] = { 'L', 'B', 'S', 'C', 'I', 'J', 'F', 'D' };
+ Field fields[] = { objectField, byteField, shortField, charField,
+ intField, longField, floatField, doubleField };
+ Object values[] = { new Byte((byte) 1), new Byte((byte) 1),
+ new Short((short) 1), new Character((char) 1), new Integer(1),
+ new Long(1), new Float(1), new Double(1) };
+
+ // test set methods
+ for (int i = 0; i < types.length; i++) {
+ char type = types[i];
+ Object value = values[i];
+ for (int j = i; j < fields.length; j++) {
+ Field field = fields[j];
+ fieldName = field.getName();
+
+ if (field == charField && type != 'C') {
+ // the exception is that bytes and shorts CANNOT be
+ // converted into chars even though chars CAN be
+ // converted into ints, longs, floats and doubles
+ subclass.setField(type, subclass, field,
+ illegalArgumentExceptionClass, value);
+ } else {
+ // setting type into field);
+ subclass.setField(type, subclass, field, null, value);
+ subclass.setField(type, otherSubclass, field, null, value);
+ subclass.setField(type, parentClass, field,
+ illegalAccessExceptionClass, value);
+ subclass.setField(type, plainObject, field,
+ illegalArgumentExceptionClass, value);
+ }
+ }
+ for (int j = 0; j < i; j++) {
+ Field field = fields[j];
+ fieldName = field.getName();
+ // not setting type into field);
+ subclass.setField(type, subclass, field,
+ illegalArgumentExceptionClass, value);
+ }
+ }
+
+ // test setBoolean
+ Boolean booleanValue = Boolean.TRUE;
+ subclass.setField('Z', subclass, booleanField, null, booleanValue);
+ subclass.setField('Z', otherSubclass, booleanField, null, booleanValue);
+ subclass.setField('Z', parentClass, booleanField,
+ illegalAccessExceptionClass, booleanValue);
+ subclass.setField('Z', plainObject, booleanField,
+ illegalArgumentExceptionClass, booleanValue);
+ for (int j = 0; j < fields.length; j++) {
+ Field listedField = fields[j];
+ fieldName = listedField.getName();
+ // not setting boolean into listedField
+ subclass.setField('Z', subclass, listedField,
+ illegalArgumentExceptionClass, booleanValue);
+ }
+ for (int i = 0; i < types.length; i++) {
+ char type = types[i];
+ Object value = values[i];
+ subclass.setField(type, subclass, booleanField,
+ illegalArgumentExceptionClass, value);
+ }
+
+ // We perform the analogous test on the get methods.
+
+ // ordered by widening conversion, except for 'L' at the end (which
+ // stands for Object), to which all primitives can be converted by
+ // wrapping
+ char newTypes[] = new char[] { 'B', 'S', 'C', 'I', 'J', 'F', 'D', 'L' };
+ Field newFields[] = { byteField, shortField, charField, intField,
+ longField, floatField, doubleField, objectField };
+ fields = newFields;
+ types = newTypes;
+ // test get methods
+ for (int i = 0; i < types.length; i++) {
+ char type = types[i];
+ for (int j = 0; j <= i; j++) {
+ Field field = fields[j];
+ fieldName = field.getName();
+ if (type == 'C' && field != charField) {
+ // the exception is that bytes and shorts CANNOT be
+ // converted into chars even though chars CAN be
+ // converted into ints, longs, floats and doubles
+ subclass.getField(type, subclass, field,
+ illegalArgumentExceptionClass);
+ } else {
+ // getting type from field
+ subclass.getField(type, subclass, field, null);
+ subclass.getField(type, otherSubclass, field, null);
+ subclass.getField(type, parentClass, field,
+ illegalAccessExceptionClass);
+ subclass.getField(type, plainObject, field,
+ illegalArgumentExceptionClass);
+ }
+ }
+ for (int j = i + 1; j < fields.length; j++) {
+ Field field = fields[j];
+ fieldName = field.getName();
+ subclass.getField(type, subclass, field,
+ illegalArgumentExceptionClass);
+ }
+ }
+
+ // test getBoolean
+ subclass.getField('Z', subclass, booleanField, null);
+ subclass.getField('Z', otherSubclass, booleanField, null);
+ subclass.getField('Z', parentClass, booleanField,
+ illegalAccessExceptionClass);
+ subclass.getField('Z', plainObject, booleanField,
+ illegalArgumentExceptionClass);
+ for (int j = 0; j < fields.length; j++) {
+ Field listedField = fields[j];
+ fieldName = listedField.getName();
+ // not getting boolean from listedField
+ subclass.getField('Z', subclass, listedField,
+ illegalArgumentExceptionClass);
+ }
+ for (int i = 0; i < types.length - 1; i++) {
+ char type = types[i];
+ subclass.getField(type, subclass, booleanField,
+ illegalArgumentExceptionClass);
+ }
+ Object res = subclass.getField('L', subclass, booleanField, null);
+ assertTrue("unexpected object " + res, res instanceof Boolean);
+ }
+
+ /**
+ * java.lang.reflect.Field#getBoolean(java.lang.Object)
+ */
+ public void test_getBooleanLjava_lang_Object() {
+ TestField x = new TestField();
+ Field f = null;
+ boolean val = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ val = f.getBoolean(x);
+ } catch (Exception e) {
+ fail("Exception during getBoolean test: " + e.toString());
+ }
+ assertTrue("Returned incorrect boolean field value", val);
+
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.getBoolean(x);
+ fail("IllegalArgumentException expected but not thrown");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("IllegalArgumentException expected but not thrown");
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.getBoolean(null);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static field
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanSField");
+ boolean staticValue = f.getBoolean(null);
+ assertTrue("Wrong value returned", staticValue);
+ } catch (Exception ex) {
+ fail("No exception expected");
+ }
+ }
+
+
+ /**
+ * java.lang.reflect.Field#getByte(java.lang.Object)
+ */
+ public void test_getByteLjava_lang_Object() {
+ // Test for method byte
+ // java.lang.reflect.Field.getByte(java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ byte val = 0;
+ try {
+ f = TestField.class.getDeclaredField("byteField");
+ val = f.getByte(x);
+ } catch (Exception e) {
+ fail("Exception during getbyte test : " + e.getMessage());
+ }
+ assertTrue("Returned incorrect byte field value", val == Byte.MAX_VALUE);
+
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.getByte(x);
+ fail("IllegalArgumentException expected but not thrown");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("IllegalArgumentException expected but not thrown");
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("byteField");
+ f.getByte(null);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static field
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("byteSField");
+ byte staticValue = f.getByte(null);
+ assertEquals("Wrong value returned", Byte.MAX_VALUE, staticValue);
+ } catch (Exception ex) {
+ fail("No exception expected "+ ex.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#getChar(java.lang.Object)
+ */
+ public void test_getCharLjava_lang_Object() {
+ // Test for method char
+ // java.lang.reflect.Field.getChar(java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ char val = 0;
+ try {
+ f = TestField.class.getDeclaredField("charField");
+ val = f.getChar(x);
+ } catch (Exception e) {
+ fail("Exception during getCharacter test: " + e.toString());
+ }
+ assertEquals("Returned incorrect char field value", 'T', val);
+
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.getChar(x);
+ fail("IllegalArgumentException expected but not thrown");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("IllegalArgumentException expected but not thrown");
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("charField");
+ f.getChar(null);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static field
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("charSField");
+ char staticValue = f.getChar(null);
+ assertEquals("Wrong value returned", 'T', staticValue);
+ } catch (Exception ex) {
+ fail("No exception expected "+ ex.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#getDeclaringClass()
+ */
+ public void test_getDeclaringClass() {
+ // Test for method java.lang.Class
+ // java.lang.reflect.Field.getDeclaringClass()
+ Field[] fields;
+
+ try {
+ fields = TestField.class.getFields();
+ assertTrue("Returned incorrect declaring class", fields[0]
+ .getDeclaringClass().equals(TestField.class));
+
+ // Check the case where the field is inherited to be sure the parent
+ // is returned as the declarer
+ fields = TestFieldSub1.class.getFields();
+ assertTrue("Returned incorrect declaring class", fields[0]
+ .getDeclaringClass().equals(TestField.class));
+ } catch (Exception e) {
+ fail("Exception : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#getDouble(java.lang.Object)
+ */
+ public void test_getDoubleLjava_lang_Object() {
+ // Test for method double
+ // java.lang.reflect.Field.getDouble(java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ double val = 0.0;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ val = f.getDouble(x);
+ } catch (Exception e) {
+ fail("Exception during getDouble test: " + e.toString());
+ }
+ assertTrue("Returned incorrect double field value",
+ val == Double.MAX_VALUE);
+
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.getDouble(x);
+ fail("IllegalArgumentException expected but not thrown");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("IllegalArgumentException expected but not thrown "
+ + ex.getMessage());
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.getDouble(null);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static field
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleSFField");
+ double staticValue = f.getDouble(null);
+ assertEquals("Wrong value returned", Double.MAX_VALUE, staticValue);
+ } catch (Exception ex) {
+ fail("No exception expected "+ ex.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#getFloat(java.lang.Object)
+ */
+ public void test_getFloatLjava_lang_Object() {
+ // Test for method float
+ // java.lang.reflect.Field.getFloat(java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ float val = 0;
+ try {
+ f = TestField.class.getDeclaredField("floatField");
+ val = f.getFloat(x);
+ } catch (Exception e) {
+ fail("Exception during getFloat test : " + e.getMessage());
+ }
+ assertTrue("Returned incorrect float field value",
+ val == Float.MAX_VALUE);
+
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.getFloat(x);
+ fail("IllegalArgumentException expected but not thrown");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("IllegalArgumentException expected but not thrown "
+ + ex.getMessage());
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("floatField");
+ f.getFloat(null);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static field
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("floatSField");
+ float staticValue = f.getFloat(null);
+ assertEquals("Wrong value returned", Float.MAX_VALUE, staticValue);
+ } catch (Exception ex) {
+ fail("No exception expected "+ ex.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#getInt(java.lang.Object)
+ */
+ public void test_getIntLjava_lang_Object() {
+ // Test for method int java.lang.reflect.Field.getInt(java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ int val = 0;
+ try {
+ f = TestField.class.getDeclaredField("intField");
+ val = f.getInt(x);
+ } catch (Exception e) {
+ fail("Exception during getInt test : " + e.getMessage());
+ }
+ assertTrue("Returned incorrect Int field value",
+ val == Integer.MAX_VALUE);
+
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.getInt(x);
+ fail("IllegalArgumentException expected but not thrown");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("IllegalArgumentException expected but not thrown "
+ + ex.getMessage());
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("intField");
+ f.getInt(null);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static field
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("intSField");
+ int staticValue = f.getInt(null);
+ assertEquals("Wrong value returned", Integer.MAX_VALUE, staticValue);
+ } catch (Exception ex) {
+ fail("No exception expected " + ex.getMessage());
+ }
+
+ }
+
+ /**
+ * java.lang.reflect.Field#getLong(java.lang.Object)
+ */
+ public void test_getLongLjava_lang_Object() {
+ // Test for method long
+ // java.lang.reflect.Field.getLong(java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ long val = 0;
+ try {
+ f = TestField.class.getDeclaredField("longField");
+ val = f.getLong(x);
+ } catch (Exception e) {
+ fail("Exception during getLong test : " + e.getMessage());
+ }
+
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.getLong(x);
+ fail("IllegalArgumentException expected but not thrown");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("IllegalArgumentException expected but not thrown "
+ + ex.getMessage());
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("longField");
+ f.getLong(null);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static field
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("longSField");
+ long staticValue = f.getLong(null);
+ assertEquals("Wrong value returned", Long.MAX_VALUE, staticValue);
+ } catch (Exception ex) {
+ fail("No exception expected "+ ex.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#getModifiers()
+ */
+ public void test_getModifiers() {
+ // Test for method int java.lang.reflect.Field.getModifiers()
+ TestField x = new TestField();
+ Field f = null;
+ try {
+ f = TestField.class.getDeclaredField("prsttrvol");
+ } catch (Exception e) {
+ fail("Exception during getModifiers test: " + e.toString());
+ }
+ int mod = f.getModifiers();
+ int mask = (Modifier.PROTECTED | Modifier.STATIC)
+ | (Modifier.TRANSIENT | Modifier.VOLATILE);
+ int nmask = (Modifier.PUBLIC | Modifier.NATIVE);
+ assertTrue("Returned incorrect field modifiers: ",
+ ((mod & mask) == mask) && ((mod & nmask) == 0));
+ }
+
+ /**
+ * java.lang.reflect.Field#getName()
+ */
+ public void test_getName() {
+ // Test for method java.lang.String java.lang.reflect.Field.getName()
+ TestField x = new TestField();
+ Field f = null;
+ try {
+ f = TestField.class.getDeclaredField("shortField");
+ } catch (Exception e) {
+ fail("Exception during getType test : " + e.getMessage());
+ }
+ assertEquals("Returned incorrect field name",
+ "shortField", f.getName());
+ }
+
+ /**
+ * java.lang.reflect.Field#getShort(java.lang.Object)
+ */
+ public void test_getShortLjava_lang_Object() {
+ // Test for method short
+ // java.lang.reflect.Field.getShort(java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ short val = 0;
+ ;
+ try {
+ f = TestField.class.getDeclaredField("shortField");
+ val = f.getShort(x);
+ } catch (Exception e) {
+ fail("Exception during getShort test : " + e.getMessage());
+ }
+ assertTrue("Returned incorrect short field value",
+ val == Short.MAX_VALUE);
+
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.getShort(x);
+ fail("IllegalArgumentException expected but not thrown");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("IllegalArgumentException expected but not thrown "
+ + ex.getMessage());
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("shortField");
+ f.getShort(null);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ //Test no NPE on static field
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("shortSField");
+ short staticValue = f.getShort(null);
+ assertEquals("Wrong value returned", Short.MAX_VALUE, staticValue);
+ } catch (Exception ex) {
+ fail("No exception expected "+ ex.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Field#getType()
+ */
+ public void test_getType() {
+ // Test for method java.lang.Class java.lang.reflect.Field.getType()
+ TestField x = new TestField();
+ Field f = null;
+ try {
+ f = TestField.class.getDeclaredField("shortField");
+ } catch (Exception e) {
+ fail("Exception during getType test : " + e.getMessage());
+ }
+ assertTrue("Returned incorrect field type: " + f.getType().toString(),
+ f.getType().equals(short.class));
+ }
+
+ /**
+ * java.lang.reflect.Field#set(java.lang.Object, java.lang.Object)
+ */
+ public void test_setLjava_lang_ObjectLjava_lang_Object() throws Exception{
+ // Test for method void java.lang.reflect.Field.set(java.lang.Object,
+ // java.lang.Object)
+ TestField x = new TestField();
+ Field f = null;
+ double val = 0.0;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.set(x, new Double(1.0));
+ val = f.getDouble(x);
+ } catch (Exception e) {
+ fail("Exception during set test : " + e.getMessage());
+ }
+ assertEquals("Returned incorrect double field value", 1.0, val);
+
+ //test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.set(x, new Double(1.0));
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.set(null, true);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("doubleSField");
+ f.set(null, new Double(1.0));
+ val = f.getDouble(x);
+ assertEquals("Returned incorrect double field value", 1.0, val);
+ }
+
+ /**
+ * java.lang.reflect.Field#setBoolean(java.lang.Object, boolean)
+ */
+ public void test_setBooleanLjava_lang_ObjectZ() throws Exception{
+ // Test for method void
+ // java.lang.reflect.Field.setBoolean(java.lang.Object, boolean)
+ TestField x = new TestField();
+ Field f = null;
+ boolean val = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setBoolean(x, false);
+ val = f.getBoolean(x);
+ } catch (Exception e) {
+ fail("Exception during setboolean test: " + e.toString());
+ }
+ assertTrue("Returned incorrect float field value", !val);
+
+ //test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.setBoolean(x, false);
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setBoolean(null, true);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("booleanSField");
+ f.setBoolean(null, false);
+ val = f.getBoolean(x);
+ assertFalse("Returned incorrect boolean field value", val);
+ }
+
+ /**
+ * java.lang.reflect.Field#setByte(java.lang.Object, byte)
+ */
+ public void test_setByteLjava_lang_ObjectB() throws Exception{
+ // Test for method void
+ // java.lang.reflect.Field.setByte(java.lang.Object, byte)
+ TestField x = new TestField();
+ Field f = null;
+ byte val = 0;
+ try {
+ f = TestField.class.getDeclaredField("byteField");
+ f.setByte(x, (byte) 1);
+ val = f.getByte(x);
+ } catch (Exception e) {
+ fail("Exception during setByte test : " + e.getMessage());
+ }
+ assertEquals("Returned incorrect float field value", 1, val);
+
+ //test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setByte(x, Byte.MIN_VALUE);
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("byteField");
+ f.setByte(null, Byte.MIN_VALUE);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("byteSField");
+ f.setByte(null, Byte.MIN_VALUE);
+ val = f.getByte(x);
+ assertEquals("Returned incorrect byte field value", Byte.MIN_VALUE,
+ val);
+ }
+
+ /**
+ * java.lang.reflect.Field#setChar(java.lang.Object, char)
+ */
+ public void test_setCharLjava_lang_ObjectC() throws Exception{
+ // Test for method void
+ // java.lang.reflect.Field.setChar(java.lang.Object, char)
+ TestField x = new TestField();
+ Field f = null;
+ char val = 0;
+ try {
+ f = TestField.class.getDeclaredField("charField");
+ f.setChar(x, (char) 1);
+ val = f.getChar(x);
+ } catch (Exception e) {
+ fail("Exception during setChar test : " + e.getMessage());
+ }
+ assertEquals("Returned incorrect float field value", 1, val);
+
+ //test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setChar(x, Character.MIN_VALUE);
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("charField");
+ f.setChar(null, Character.MIN_VALUE);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("charSField");
+ f.setChar(null, Character.MIN_VALUE);
+ val = f.getChar(x);
+ assertEquals("Returned incorrect char field value",
+ Character.MIN_VALUE, val);
+ }
+
+ /**
+ * java.lang.reflect.Field#setDouble(java.lang.Object, double)
+ */
+ public void test_setDoubleLjava_lang_ObjectD() throws Exception{
+ // Test for method void
+ // java.lang.reflect.Field.setDouble(java.lang.Object, double)
+ TestField x = new TestField();
+ Field f = null;
+ double val = 0.0;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.setDouble(x, Double.MIN_VALUE);
+ val = f.getDouble(x);
+ } catch (Exception e) {
+ fail("Exception during setDouble test: " + e.toString());
+ }
+ assertEquals("Returned incorrect double field value", Double.MIN_VALUE,
+ val);
+
+ //test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setDouble(x, Double.MIN_VALUE);
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("doubleField");
+ f.setDouble(null, Double.MIN_VALUE);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("doubleSField");
+ f.setDouble(null, Double.MIN_VALUE);
+ val = f.getDouble(x);
+ assertEquals("Returned incorrect double field value",
+ Double.MIN_VALUE, val);
+ }
+
+ /**
+ * java.lang.reflect.Field#setFloat(java.lang.Object, float)
+ */
+ public void test_setFloatLjava_lang_ObjectF() throws Exception{
+ // Test for method void
+ // java.lang.reflect.Field.setFloat(java.lang.Object, float)
+ TestField x = new TestField();
+ Field f = null;
+ float val = 0.0F;
+ try {
+ f = TestField.class.getDeclaredField("floatField");
+ f.setFloat(x, Float.MIN_VALUE);
+ val = f.getFloat(x);
+ } catch (Exception e) {
+ fail("Exception during setFloat test : " + e.getMessage());
+ }
+ assertEquals("Returned incorrect float field value", Float.MIN_VALUE,
+ val, 0.0);
+
+ //test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setFloat(x, Float.MIN_VALUE);
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ //Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("floatField");
+ f.setFloat(null, Float.MIN_VALUE);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("floatSField");
+ f.setFloat(null, Float.MIN_VALUE);
+ val = f.getFloat(x);
+ assertEquals("Returned incorrect float field value",
+ Float.MIN_VALUE, val);
+ }
+
+ /**
+ * java.lang.reflect.Field#setInt(java.lang.Object, int)
+ */
+ public void test_setIntLjava_lang_ObjectI() throws Exception{
+ // Test for method void java.lang.reflect.Field.setInt(java.lang.Object,
+ // int)
+ TestField x = new TestField();
+ Field f = null;
+ int val = 0;
+ try {
+ f = TestField.class.getDeclaredField("intField");
+ f.setInt(x, Integer.MIN_VALUE);
+ val = f.getInt(x);
+ } catch (Exception e) {
+ fail("Exception during setInteger test: " + e.toString());
+ }
+ assertEquals("Returned incorrect int field value", Integer.MIN_VALUE,
+ val);
+
+ // test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setInt(x, Integer.MIN_VALUE);
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ // Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("intField");
+ f.setInt(null, Integer.MIN_VALUE);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("intSField");
+ f.setInt(null, Integer.MIN_VALUE);
+ val = f.getInt(x);
+ assertEquals("Returned incorrect int field value",
+ Integer.MIN_VALUE, val);
+ }
+
+ /**
+ * java.lang.reflect.Field#setLong(java.lang.Object, long)
+ */
+ public void test_setLongLjava_lang_ObjectJ() throws Exception{
+ // Test for method void
+ // java.lang.reflect.Field.setLong(java.lang.Object, long)
+ TestField x = new TestField();
+ Field f = null;
+ long val = 0L;
+ try {
+ f = TestField.class.getDeclaredField("longField");
+ f.setLong(x, Long.MIN_VALUE);
+ val = f.getLong(x);
+ } catch (Exception e) {
+ fail("Exception during setLong test : " + e.getMessage());
+ }
+ assertEquals("Returned incorrect long field value", Long.MIN_VALUE, val);
+
+ // test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setLong(x, Long.MIN_VALUE);
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ // Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("longField");
+ f.setLong(null, Long.MIN_VALUE);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("longSField");
+ f.setLong(null, Long.MIN_VALUE);
+ val = f.getLong(x);
+ assertEquals("Returned incorrect long field value",
+ Long.MIN_VALUE, val);
+ }
+
+ /**
+ * java.lang.reflect.Field#setShort(java.lang.Object, short)
+ */
+ public void test_setShortLjava_lang_ObjectS() throws Exception{
+ // Test for method void
+ // java.lang.reflect.Field.setShort(java.lang.Object, short)
+ TestField x = new TestField();
+ Field f = null;
+ short val = 0;
+ try {
+ f = TestField.class.getDeclaredField("shortField");
+ f.setShort(x, Short.MIN_VALUE);
+ val = f.getShort(x);
+ } catch (Exception e) {
+ fail("Exception during setShort test : " + e.getMessage());
+ }
+ assertEquals("Returned incorrect short field value", Short.MIN_VALUE,
+ val);
+
+ // test wrong type
+ boolean thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("booleanField");
+ f.setShort(x, Short.MIN_VALUE);
+ fail("Accessed field of invalid type");
+ } catch (IllegalArgumentException ex) {
+ thrown = true;
+ }
+ assertTrue("IllegalArgumentException expected but not thrown", thrown);
+
+ // Test NPE
+ thrown = false;
+ try {
+ f = TestField.class.getDeclaredField("shortField");
+ f.setShort(null, Short.MIN_VALUE);
+ fail("NullPointerException expected but not thrown");
+ } catch (NullPointerException ex) {
+ thrown = true;
+ } catch (Exception ex) {
+ fail("NullPointerException expected but not thrown");
+ }
+ assertTrue("NullPointerException expected but not thrown", thrown);
+
+ // Test setting a static field;
+ f = TestField.class.getDeclaredField("shortSField");
+ f.setShort(null, Short.MIN_VALUE);
+ val = f.getShort(x);
+ assertEquals("Returned incorrect short field value",
+ Short.MIN_VALUE, val);
+ }
+
+ /**
+ * java.lang.reflect.Field#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.lang.reflect.Field.toString()
+ Field f = null;
+
+ try {
+ f = TestField.class.getDeclaredField("x");
+ } catch (Exception e) {
+ fail("Exception getting field : " + e.getMessage());
+ }
+ assertEquals("Field returned incorrect string",
+ "private static final int org.apache.harmony.tests.java.lang.reflect.FieldTest$TestField.x",
+ f.toString());
+ }
+
+ public void test_getDeclaredAnnotations() throws Exception {
+ Field field = TestClass.class.getField("annotatedField");
+ Annotation[] annotations = field.getDeclaredAnnotations();
+ assertEquals(2, annotations.length);
+
+ Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
+ ignoreOrder.add(annotations[0].annotationType());
+ ignoreOrder.add(annotations[1].annotationType());
+
+ assertTrue("Missing @AnnotationRuntime0", ignoreOrder
+ .contains(AnnotationRuntime0.class));
+ assertTrue("Missing @AnnotationRuntime1", ignoreOrder
+ .contains(AnnotationRuntime1.class));
+ }
+
+ public void test_isEnumConstant() throws Exception {
+ Field field = TestEnum.class.getDeclaredField("A");
+ assertTrue("Enum constant not recognized", field.isEnumConstant());
+
+ field = TestEnum.class.getDeclaredField("field");
+ assertFalse("Non enum constant wrongly stated as enum constant", field
+ .isEnumConstant());
+
+ field = TestClass.class.getDeclaredField("annotatedField");
+ assertFalse("Non enum constant wrongly stated as enum constant", field
+ .isEnumConstant());
+ }
+
+ public void test_isSynthetic() throws Exception {
+ Field[] fields = TestClass.Inner.class.getDeclaredFields();
+ assertEquals("Not exactly one field returned", 1, fields.length);
+
+ assertTrue("Enum constant not recognized", fields[0].isSynthetic());
+
+ Field field = TestEnum.class.getDeclaredField("field");
+ assertFalse("Non synthetic field wrongly stated as synthetic", field
+ .isSynthetic());
+
+ field = TestClass.class.getDeclaredField("annotatedField");
+ assertFalse("Non synthetic field wrongly stated as synthetic", field
+ .isSynthetic());
+ }
+
+
+ public void test_getGenericType() throws Exception {
+ Field field = GenericField.class.getDeclaredField("field");
+ Type type = field.getGenericType();
+ @SuppressWarnings("unchecked")
+ TypeVariable typeVar = (TypeVariable) type;
+ assertEquals("Wrong type name returned", "S", typeVar.getName());
+
+ Field boundedField = GenericField.class.getDeclaredField("boundedField");
+ Type boundedType = boundedField.getGenericType();
+ @SuppressWarnings("unchecked")
+ TypeVariable boundedTypeVar = (TypeVariable) boundedType;
+ assertEquals("Wrong type name returned", "T", boundedTypeVar.getName());
+ assertEquals("More than one bound found", 1,
+ boundedTypeVar.getBounds().length);
+ assertEquals("Wrong bound returned", Number.class,
+ boundedTypeVar.getBounds()[0]);
+ }
+
+
+ public void test_toGenericString() throws Exception {
+ Field field = GenericField.class.getDeclaredField("field");
+ assertEquals("Wrong generic string returned",
+ "S org.apache.harmony.tests.java.lang.reflect.FieldTest$GenericField.field",
+ field.toGenericString());
+
+ Field boundedField = GenericField.class
+ .getDeclaredField("boundedField");
+ assertEquals(
+ "Wrong generic string returned",
+ "T org.apache.harmony.tests.java.lang.reflect.FieldTest$GenericField.boundedField",
+ boundedField.toGenericString());
+
+ Field ordinary = GenericField.class.getDeclaredField("intField");
+ assertEquals(
+ "Wrong generic string returned",
+ "int org.apache.harmony.tests.java.lang.reflect.FieldTest$GenericField.intField",
+ ordinary.toGenericString());
+ }
+
+
+ public void test_hashCode() throws Exception {
+ Field field = TestClass.class.getDeclaredField("annotatedField");
+ assertEquals("Wrong hashCode returned", field.getName().hashCode()
+ ^ field.getDeclaringClass().getName().hashCode(), field
+ .hashCode());
+ }
+
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
+
+class TestAccess {
+ private static int xxx;
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericArrayTypeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericArrayTypeTest.java
new file mode 100644
index 0000000..4888fd2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericArrayTypeTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+/**
+ * Tests generic reflection on arrays with generic or parameterized component types.
+ */
+public class GenericArrayTypeTest extends GenericReflectionTestsBase {
+
+ static class A<T> {
+ T[] array;
+ }
+ public void testGetGenericComponentType() throws Exception {
+ @SuppressWarnings("unchecked")
+ Class<? extends A> clazz = GenericArrayTypeTest.A.class;
+ Field field = clazz.getDeclaredField("array");
+ Type genericType = field.getGenericType();
+ assertInstanceOf(GenericArrayType.class, genericType);
+ Type componentType = ((GenericArrayType) genericType).getGenericComponentType();
+ assertEquals(getTypeParameter(clazz), componentType);
+ assertInstanceOf(TypeVariable.class, componentType);
+ TypeVariable<?> componentTypeVariable = (TypeVariable<?>) componentType;
+ assertEquals("T", componentTypeVariable.getName());
+ assertEquals(clazz, componentTypeVariable.getGenericDeclaration());
+ }
+
+ static class B<T> {
+ B<T>[] array;
+ }
+ public void testParameterizedComponentType() throws Exception {
+ @SuppressWarnings("unchecked")
+ Class<? extends B> clazz = GenericArrayTypeTest.B.class;
+ Field field = clazz.getDeclaredField("array");
+ Type genericType = field.getGenericType();
+
+ assertInstanceOf(GenericArrayType.class, genericType);
+ GenericArrayType arrayType = (GenericArrayType) genericType;
+ Type componentType = arrayType.getGenericComponentType();
+ assertInstanceOf(ParameterizedType.class, componentType);
+ ParameterizedType parameteriezdType = (ParameterizedType) componentType;
+ assertEquals(clazz, parameteriezdType.getRawType());
+ assertEquals(clazz.getTypeParameters()[0], parameteriezdType.getActualTypeArguments()[0]);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericMethodsTests.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericMethodsTests.java
new file mode 100644
index 0000000..a209b21
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericMethodsTests.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+
+/**
+ * Tests unbounded type parameters declared on methods.
+ */
+public class GenericMethodsTests extends GenericReflectionTestsBase{
+
+ static class GenericMethods {
+
+ public <T> void noParamNoReturn() {}
+
+ public <T> void paramNoReturn(T param) {}
+
+ @SuppressWarnings("unchecked")
+ public <T> T noParamReturn() { return (T) new Object(); }
+
+ public <T> T paramReturn(T param) {return param;}
+ }
+
+ private static Class<? extends GenericMethods> clazz = GenericMethodsTests.GenericMethods.class;
+
+ /**
+ * Tests that there are no Type Parameters on the Class itself.
+ */
+ public void testGenericMethods() {
+ assertLenghtZero(clazz.getTypeParameters());
+ }
+
+ /**
+ * Tests whether the specified method declares a type parameter T.
+ * @param method the method
+ */
+ private void checkTypeParameter(Method method) {
+ TypeVariable<Method> typeParameter = getTypeParameter(method);
+ assertEquals("T", typeParameter.getName());
+ assertEquals(method, typeParameter.getGenericDeclaration());
+ }
+
+ /**
+ * Tests whether the specified method declares a parameter with the
+ * type of the type parameter.
+ * @param method the method
+ */
+ private void checkParameterType(Method method) {
+ TypeVariable<Method> typeParameter = getTypeParameter(method);
+ assertLenghtOne(method.getGenericParameterTypes());
+ Type genericParameterType = method.getGenericParameterTypes()[0];
+ assertEquals(typeParameter, genericParameterType);
+ assertInstanceOf(TypeVariable.class, genericParameterType);
+ assertEquals(method, ((TypeVariable<?>) genericParameterType).getGenericDeclaration());
+ }
+
+ /**
+ * Tests whether the type of the return type is the declared type parameter.
+ * @param method the declaring method
+ */
+ private void checkReturnType(Method method) {
+ TypeVariable<Method> typeParameter = getTypeParameter(method);
+ Type genericReturnType = method.getGenericReturnType();
+ assertEquals(typeParameter, genericReturnType);
+ assertInstanceOf(TypeVariable.class, genericReturnType);
+ assertEquals(method, ((TypeVariable<?>) genericReturnType).getGenericDeclaration());
+ }
+ public void testNoParamNoReturn() throws Exception {
+ Method method = clazz.getMethod("noParamNoReturn");
+ checkTypeParameter(method);
+ }
+
+ public void testParamNoReturn() throws Exception {
+ Method method = clazz.getMethod("paramNoReturn", Object.class);
+ checkTypeParameter(method);
+ checkParameterType(method);
+ }
+
+ public void testNoParamReturn() throws Exception {
+ Method method = clazz.getMethod("noParamReturn");
+ checkTypeParameter(method);
+ assertLenghtZero(method.getGenericParameterTypes());
+ checkReturnType(method);
+ }
+ public void testParamReturn() throws Exception {
+ Method method = clazz.getMethod("paramReturn", Object.class);
+ checkTypeParameter(method);
+ checkParameterType(method);
+ checkReturnType(method);
+ }
+ public void testIndependencyOfMethodTypeParameters() throws Exception {
+ Method method0 = clazz.getMethod("paramNoReturn", Object.class);
+ TypeVariable<Method> typeParameter0 = method0.getTypeParameters()[0];
+
+ Method method1 = clazz.getMethod("noParamNoReturn");
+ TypeVariable<Method> typeParameter1 = method1.getTypeParameters()[0];
+
+ //Generic method type parameters NAMES are equal
+ assertEquals(typeParameter0.getName(), typeParameter1.getName());
+ //Generic method type PARAMETERS are not equal
+ assertNotEquals(typeParameter0, typeParameter1);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericReflectionTestsBase.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericReflectionTestsBase.java
new file mode 100644
index 0000000..c08fef4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericReflectionTestsBase.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.TypeVariable;
+
+import junit.framework.TestCase;
+
+public class GenericReflectionTestsBase extends TestCase{
+
+ /**
+ * Returns the type parameter of the declaring method.
+ *
+ * @param method
+ * the declaring method
+ * @return the type parameter of the method
+ */
+ public TypeVariable<Method> getTypeParameter(Method method) {
+ TypeVariable<Method>[] typeParameters = method.getTypeParameters();
+ assertLenghtOne(typeParameters);
+ TypeVariable<Method> typeParameter = typeParameters[0];
+ return typeParameter;
+ }
+
+ /**
+ * Returns the type parameter of the declaring class.
+ *
+ * @param method
+ * the declaring method.
+ * @return the type parameter of the method.
+ */
+ @SuppressWarnings("unchecked")
+ public TypeVariable<Class> getTypeParameter(Class<?> clazz) {
+ TypeVariable[] typeParameters = clazz.getTypeParameters();
+ assertLenghtOne(typeParameters);
+ TypeVariable<Class> typeVariable = typeParameters[0];
+ assertEquals(clazz, typeVariable.getGenericDeclaration());
+ assertEquals("T", typeVariable.getName());
+ return typeVariable;
+ }
+
+ public static void assertLenghtOne(Object[] array) {
+ TestCase.assertEquals("Array does NOT contain exactly one element.", 1, array.length);
+ }
+
+ public static void assertLenghtZero(Object[] array) {
+ TestCase.assertEquals("Array has more than zero elements.", 0, array.length);
+ }
+
+ public static void assertInstanceOf(Class<?> expectedClass, Object actual) {
+ TestCase.assertTrue(actual.getClass().getName() + " is not instance of :" + expectedClass.getName(), expectedClass
+ .isInstance(actual));
+ }
+
+ public static void assertNotEquals(Object expected, Object actual) {
+ TestCase.assertFalse(actual.toString() + " has not to be equal to " + expected.toString(), expected.equals(actual));
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericSignatureFormatErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericSignatureFormatErrorTest.java
new file mode 100644
index 0000000..0cad681
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericSignatureFormatErrorTest.java
@@ -0,0 +1,100 @@
+package org.apache.harmony.tests.java.lang.reflect;
+
+import dalvik.annotation.AndroidOnly;
+import dalvik.system.DexFile;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.GenericSignatureFormatError;
+import java.lang.reflect.TypeVariable;
+
+import tests.support.Support_ClassLoader;
+
+public class GenericSignatureFormatErrorTest extends TestCase{
+
+ public void test_Constructor() {
+ assertNotNull(new GenericSignatureFormatError());
+ }
+
+ public void test_readResource() throws Exception {
+ File tf = File.createTempFile("classes", ".dex");
+ // System.out.println("GenericSignatureFormatErrorTest:"
+ // +tf.getAbsolutePath()+", canRead: "+tf.canRead()
+ // +", canWrite: "+tf.canWrite());
+ InputStream is = this.getClass().getResourceAsStream("/resources/dex1.bytes");
+ assertNotNull(is);
+ }
+
+
+ @AndroidOnly("Uses Android specific class dalvik.system.DexFile " +
+ "for loading classes.")
+ // SideEffect: strange issue (exception: 'could not open dex file',
+ // dalvikvm: 'waitpid failed' log msg - only occurs when @SideEffect is removed
+ // and this test is run via running tests.luni.AllTestsLang TestSuite
+ public void test_signatureFormatError() throws Exception {
+ /*
+ * dex1.bytes is a jar file with a classes.dex in it.
+ * the classes.dex was javac'ed, dx'ed and patched
+ * with the following java file:
+ *
+ * package demo;
+ * public class HelloWorld<U> {
+ * public HelloWorld(U t) {}
+ * }
+ *
+ * patch:
+ * the string constant (class generics signature string)
+ * "<U:" was changed to "<<:"
+ *
+ */
+
+ File tf = File.createTempFile("classes", ".dex");
+ // System.out.println("GenericSignatureFormatErrorTest:" +
+ // tf.getAbsolutePath() + ", canRead: " + tf.canRead() +
+ // ", canWrite: "+tf.canWrite());
+ InputStream is = this.getClass().getResourceAsStream("/resources/dex1.bytes");
+ assertNotNull(is);
+ OutputStream fos = new FileOutputStream(tf);
+ copy(is, fos);
+ fos.flush();
+ fos.close();
+
+
+ // class signature string "<U:" was changed to "<<:"
+ //System.out.println("file length:"+tf.length());
+ try {
+ // Was:
+ // DexFile df = new DexFile(tf);
+ // Class clazz = df.loadClass("demo/HelloWorld", this.getClass().getClassLoader());
+
+ ClassLoader cl = Support_ClassLoader.getInstance(tf.toURL(),
+ getClass().getClassLoader());
+
+ Class clazz = cl.loadClass("demo/HelloWorld");
+ TypeVariable[] tvs = clazz.getTypeParameters();
+ fail("expecting a GenericSignatureFormatError");
+ // for (TypeVariable tv : tvs) {
+ // System.out.println("tv:"+tv.toString());
+ // }
+ } catch (GenericSignatureFormatError gsfe) {
+ // expected
+ }
+ }
+
+ private void copy(InputStream is, OutputStream os) {
+ try {
+ int b;
+ while ((b = is.read()) != -1) {
+ os.write(b);
+ }
+ is.close();
+ } catch (IOException ex) {
+ throw new RuntimeException("io error", ex);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/InvocationTargetExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/InvocationTargetExceptionTest.java
new file mode 100644
index 0000000..3911447
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/InvocationTargetExceptionTest.java
@@ -0,0 +1,305 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class InvocationTargetExceptionTest extends junit.framework.TestCase {
+
+ static class TestMethod {
+ public TestMethod() {
+ }
+
+ public void voidMethod() throws IllegalArgumentException {
+ }
+
+ public void parmTest(int x, short y, String s, boolean bool, Object o,
+ long l, byte b, char c, double d, float f) {
+ }
+
+ public int intMethod() {
+ return 1;
+ }
+
+ public static final void printTest(int x, short y, String s,
+ boolean bool, Object o, long l, byte b, char c, double d,
+ float f) {
+ }
+
+ public double doubleMethod() {
+ return 1.0;
+ }
+
+ public short shortMethod() {
+ return (short) 1;
+ }
+
+ public byte byteMethod() {
+ return (byte) 1;
+ }
+
+ public float floatMethod() {
+ return 1.0f;
+ }
+
+ public long longMethod() {
+ return 1l;
+ }
+
+ public char charMethod() {
+ return 'T';
+ }
+
+ public Object objectMethod() {
+ return new Object();
+ }
+
+ private static void prstatic() {
+ }
+
+ public static void pustatic() {
+ }
+
+ public static synchronized void pustatsynch() {
+ }
+
+ public static int invokeStaticTest() {
+ return 1;
+ }
+
+ public int invokeInstanceTest() {
+ return 1;
+ }
+
+ private int privateInvokeTest() {
+ return 1;
+ }
+
+ public int invokeExceptionTest() throws NullPointerException {
+ throw new NullPointerException();
+ }
+
+ public static synchronized native void pustatsynchnat();
+
+ }
+
+ abstract class AbstractTestMethod {
+ public abstract void puabs();
+ }
+
+ class SubInvocationTargetException extends InvocationTargetException {}
+
+ /**
+ * java.lang.reflect.InvocationTargetException#InvocationTargetException()
+ */
+ public void test_Constructor() throws Exception {
+ Constructor<InvocationTargetException> ctor = InvocationTargetException.class
+ .getDeclaredConstructor();
+ assertNotNull("Parameterless constructor does not exist.", ctor);
+ assertTrue("Constructor is not protected", Modifier.isProtected(ctor
+ .getModifiers()));
+ //create an instance of a subtype using this constructor
+ SubInvocationTargetException subException = new SubInvocationTargetException();
+ }
+
+ /**
+ * java.lang.reflect.InvocationTargetException#InvocationTargetException(java.lang.Throwable)
+ */
+ public void test_ConstructorLjava_lang_Throwable() {
+ // Test for method
+ // java.lang.reflect.InvocationTargetException(java.lang.Throwable)
+ try {
+ Method mth = TestMethod.class.getDeclaredMethod(
+ "invokeExceptionTest", new Class[0]);
+ Object[] args = { Object.class };
+ Object ret = mth.invoke(new TestMethod(), new Object[0]);
+ } catch (InvocationTargetException e) {
+ // Correct behaviour
+ return;
+ } catch (NoSuchMethodException e) {
+ } catch (IllegalAccessException e) {
+ }
+ fail("Failed to throw exception");
+ }
+
+ /**
+ * java.lang.reflect.InvocationTargetException#InvocationTargetException(java.lang.Throwable,
+ * java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_ThrowableLjava_lang_String() {
+ // Test for method
+ // java.lang.reflect.InvocationTargetException(java.lang.Throwable,
+ // java.lang.String)
+ try {
+ Method mth = TestMethod.class.getDeclaredMethod(
+ "invokeExceptionTest", new Class[0]);
+ Object[] args = { Object.class };
+ Object ret = mth.invoke(new TestMethod(), new Object[0]);
+ } catch (InvocationTargetException e) {
+ // Correct behaviour
+ return;
+ } catch (NoSuchMethodException e) {
+ ;
+ } catch (IllegalAccessException e) {
+ }
+ fail("Failed to throw exception");
+ }
+
+ /**
+ * java.lang.reflect.InvocationTargetException#getTargetException()
+ */
+ public void test_getTargetException() {
+ // Test for method java.lang.Throwable
+ // java.lang.reflect.InvocationTargetException.getTargetException()
+ try {
+ Method mth = TestMethod.class.getDeclaredMethod(
+ "invokeExceptionTest", new Class[0]);
+ Object[] args = { Object.class };
+ Object ret = mth.invoke(new TestMethod(), new Object[0]);
+ } catch (InvocationTargetException e) {
+ // Correct behaviour
+ assertTrue("Returned incorrect target exception", e
+ .getTargetException() instanceof NullPointerException);
+ return;
+ } catch (Exception e) {
+ fail("Exception during constructor test : " + e.getMessage());
+ }
+ fail("Failed to throw exception");
+ }
+
+ /**
+ * java.lang.reflect.InvocationTargetException#getCause()
+ */
+ public void test_getCause() {
+ // java.lang.reflect.InvocationTargetException.getCause()
+ try {
+ Method mth = TestMethod.class.getDeclaredMethod(
+ "invokeExceptionTest", new Class[0]);
+ Object[] args = {Object.class};
+ Object ret = mth.invoke(new TestMethod(), new Object[0]);
+ } catch (InvocationTargetException e) {
+ // Correct behaviour
+ assertTrue("Returned incorrect cause",
+ e.getCause() instanceof NullPointerException);
+ return;
+ } catch (Exception e) {
+ fail("Exception during InvocationTargetException test : "
+ + e.getMessage());
+ }
+ fail("Failed to throw exception");
+ }
+
+ /**
+ * java.lang.reflect.InvocationTargetException#printStackTrace()
+ */
+ public void test_printStackTrace() {
+ // Test for method void
+ // java.lang.reflect.InvocationTargetException.printStackTrace()
+ try {
+ ByteArrayOutputStream bao = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bao);
+ PrintStream oldErr = System.err;
+ System.setErr(ps);
+ InvocationTargetException ite = new InvocationTargetException(null);
+ ite.printStackTrace();
+ System.setErr(oldErr);
+
+ String s = new String(bao.toByteArray());
+
+ assertTrue("Incorrect Stack trace: " + s, s != null
+ && s.length() > 300);
+ } catch (Exception e) {
+ fail("printStackTrace() caused exception : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.lang.reflect.InvocationTargetException#printStackTrace(java.io.PrintStream)
+ */
+ public void test_printStackTraceLjava_io_PrintStream() {
+ // Test for method void
+ // java.lang.reflect.InvocationTargetException.printStackTrace(java.io.PrintStream)
+ assertTrue("Tested via test_printStackTrace().", true);
+ ByteArrayOutputStream bao = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bao);
+ InvocationTargetException ite = new InvocationTargetException(
+ new InvocationTargetException(null));
+ ite.printStackTrace(ps);
+ String s = bao.toString();
+ assertTrue("printStackTrace failed." + s.length(), s != null
+ && s.length() > 400);
+ }
+
+ /**
+ * java.lang.reflect.InvocationTargetException#printStackTrace(java.io.PrintWriter)
+ */
+ public void test_printStackTraceLjava_io_PrintWriter() {
+ // Test for method void
+ // java.lang.reflect.InvocationTargetException.printStackTrace(java.io.PrintWriter)
+ try {
+ PrintWriter pw;
+ InvocationTargetException ite;
+ String s;
+ CharArrayWriter caw = new CharArrayWriter();
+ pw = new PrintWriter(caw);
+ ite = new InvocationTargetException(new InvocationTargetException(
+ null));
+ ite.printStackTrace(pw);
+
+ s = caw.toString();
+ assertTrue("printStackTrace failed." + s.length(), s != null
+ && s.length() > 400);
+ pw.close();
+
+ ByteArrayOutputStream bao = new ByteArrayOutputStream();
+ pw = new PrintWriter(bao);
+ ite = new InvocationTargetException(new InvocationTargetException(
+ null));
+ ite.printStackTrace(pw);
+
+ pw.flush(); // Test will fail if this line removed.
+ s = bao.toString();
+ assertTrue("printStackTrace failed." + s.length(), s != null
+ && s.length() > 400);
+
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MalformedParameterizedTypeExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MalformedParameterizedTypeExceptionTest.java
new file mode 100644
index 0000000..04266d5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MalformedParameterizedTypeExceptionTest.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.MalformedParameterizedTypeException;
+import junit.framework.TestCase;
+
+public class MalformedParameterizedTypeExceptionTest extends TestCase {
+
+ /**
+ * java.lang.reflect.MalformedParameterizedTypeException#
+ * MalformedParameterizedTypeException()
+ */
+ public void testMalformedParameterizedTypeException() {
+ MalformedParameterizedTypeException e = new MalformedParameterizedTypeException();
+ assertNotNull(e);
+ assertNull(e.getMessage());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MalformedParameterizedTypeExceptionTests.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MalformedParameterizedTypeExceptionTests.java
new file mode 100644
index 0000000..79ce85e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MalformedParameterizedTypeExceptionTests.java
@@ -0,0 +1,21 @@
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.MalformedParameterizedTypeException;
+import java.lang.reflect.Modifier;
+
+public class MalformedParameterizedTypeExceptionTests extends junit.framework.TestCase {
+
+ /**
+ * java.lang.reflect.MalformedParameterizedTypeException#MalformedParameterizedTypeException()
+ */
+ public void test_Constructor() throws Exception {
+ Constructor<MalformedParameterizedTypeException> ctor = MalformedParameterizedTypeException.class
+ .getDeclaredConstructor();
+ assertNotNull("Parameterless constructor does not exist.", ctor);
+ assertTrue("Constructor is not protected", Modifier.isPublic(ctor
+ .getModifiers()));
+ assertNotNull(ctor.newInstance());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MethodTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MethodTest.java
new file mode 100644
index 0000000..9f4f69e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/MethodTest.java
@@ -0,0 +1,881 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.HashSet;
+import java.util.Set;
+
+public class MethodTest extends junit.framework.TestCase {
+
+ static class TestMethod {
+ public TestMethod() {
+ }
+
+ public void voidMethod() throws IllegalArgumentException {
+ }
+
+ public void parmTest(int x, short y, String s, boolean bool, Object o,
+ long l, byte b, char c, double d, float f) {
+ }
+
+ public int intMethod() {
+ return 1;
+ }
+
+ public static final void printTest(int x, short y, String s,
+ boolean bool, Object o, long l, byte b, char c, double d,
+ float f) {
+ }
+
+ public double doubleMethod() {
+ return 1.0;
+ }
+
+ public short shortMethod() {
+ return (short) 1;
+ }
+
+ public byte byteMethod() {
+ return (byte) 1;
+ }
+
+ public float floatMethod() {
+ return 1.0f;
+ }
+
+ public long longMethod() {
+ return 1l;
+ }
+
+ public char charMethod() {
+ return 'T';
+ }
+
+ public Object objectMethod() {
+ return new Object();
+ }
+
+ private static void prstatic() {
+ }
+
+ public static void pustatic() {
+ }
+
+ public static synchronized void pustatsynch() {
+ }
+
+ public static int invokeStaticTest() {
+ return 1;
+ }
+
+ public int invokeInstanceTest() {
+ return 1;
+ }
+
+ private int privateInvokeTest() {
+ return 1;
+ }
+
+ public int invokeExceptionTest() throws NullPointerException {
+ throw new NullPointerException();
+ }
+
+ public static synchronized native void pustatsynchnat();
+
+ public void publicVoidVarargs(Object... param){}
+ public void publicVoidArray(Object[] param){}
+
+ public void annotatedParameter(@TestAnno @Deprecated int a,
+ @Deprecated int b, int c) {
+ }
+
+ @Deprecated
+ @TestAnno
+ public void annotatedMethod(){}
+
+ public void hashCodeTest(int i){}
+ public void hashCodeTest(String s){}
+
+ public void invokeCastTest1(byte param) {
+ }
+
+ public void invokeCastTest1(short param) {
+ }
+
+ public void invokeCastTest1(int param) {
+ }
+
+ public void invokeCastTest1(long param) {
+ }
+
+ public void invokeCastTest1(float param) {
+ }
+
+ public void invokeCastTest1(double param) {
+ }
+
+ public void invokeCastTest1(char param) {
+ }
+
+ public void invokeCastTest1(boolean param) {
+ }
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.PARAMETER, ElementType.METHOD})
+ public static @interface TestAnno{
+ public static final String DEFAULT_VALUE = "DEFAULT_VALUE";
+
+ String value() default DEFAULT_VALUE;
+ }
+
+ abstract class AbstractTestMethod {
+ public abstract void puabs();
+ }
+
+ class TestMethodSub extends TestMethod {
+ public int invokeInstanceTest() {
+ return 0;
+ }
+ }
+
+ static interface IBrigeTest<T>{
+ T m();
+ }
+
+ static class BrigeTest implements IBrigeTest<String> {
+ public String m(){ return null; }
+ }
+
+ static class ExceptionTest<T extends Exception>{
+ @SuppressWarnings("unused")
+ void exceptionTest() throws T{}
+ }
+
+ static class GenericReturnType<T> {
+ T returnGeneric(){return null;}
+ }
+
+ static class GenericString<T> {
+ public static final String GENERIC =
+ "T org.apache.harmony.tests.java.lang.reflect.MethodTest$GenericString.genericString(T)";
+ T genericString(T t) {
+ return null;
+ }
+ }
+
+ /**
+ * java.lang.reflect.Method#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.lang.reflect.Method.equals(java.lang.Object)
+
+ Method m1 = null, m2 = null;
+ try {
+ m1 = TestMethod.class.getMethod("invokeInstanceTest", new Class[0]);
+ m2 = TestMethodSub.class.getMethod("invokeInstanceTest",
+ new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during equals test : " + e.getMessage());
+ }
+ assertTrue("Overriden method returned equal", !m1.equals(m2));
+ assertTrue("Same method returned not-equal", m1.equals(m1));
+ try {
+ m1 = TestMethod.class.getMethod("invokeStaticTest", new Class[0]);
+ m2 = TestMethodSub.class
+ .getMethod("invokeStaticTest", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during equals test : " + e.getMessage());
+ }
+ assertTrue("Inherited method returned not-equal", m1.equals(m2));
+ }
+
+ /**
+ * java.lang.Class#getMethod(java.lang.String, java.lang.Class[])
+ */
+ public void test_getMethod() throws NoSuchMethodException, SecurityException {
+ // Check that getMethod treats null parameterTypes the same as an empty array.
+ Method m1 = TestMethod.class.getMethod("invokeInstanceTest", new Class[0]);
+ Method m2 = TestMethod.class.getMethod("invokeInstanceTest", (Class[]) null);
+ assertEquals(m1, m2);
+ }
+
+ /**
+ * java.lang.Class#getDeclaredMethod(java.lang.String, java.lang.Class[])
+ */
+ public void test_getDeclaredMethod() throws NoSuchMethodException, SecurityException {
+ // Check that getDeclaredMethod treats null parameterTypes the same as an empty array.
+ Method m1 = TestMethod.class.getDeclaredMethod("invokeInstanceTest", new Class[0]);
+ Method m2 = TestMethod.class.getDeclaredMethod("invokeInstanceTest", (Class[]) null);
+ assertEquals(m1, m2);
+ }
+
+ /**
+ * java.lang.reflect.Method#getDeclaringClass()
+ */
+ public void test_getDeclaringClass() {
+ // Test for method java.lang.Class
+ // java.lang.reflect.Method.getDeclaringClass()
+
+ Method[] mths;
+
+ try {
+ mths = TestMethod.class.getDeclaredMethods();
+ assertTrue("Returned incorrect declaring class: "
+ + mths[0].getDeclaringClass().toString(), mths[0]
+ .getDeclaringClass().equals(TestMethod.class));
+ } catch (Exception e) {
+ fail("Exception during getDeclaringClass test: "
+ + e.toString());
+ }
+ }
+
+ /**
+ * java.lang.reflect.Method#getExceptionTypes()
+ */
+ public void test_getExceptionTypes() {
+ // Test for method java.lang.Class []
+ // java.lang.reflect.Method.getExceptionTypes()
+
+ try {
+ Method mth = TestMethod.class.getMethod("voidMethod", new Class[0]);
+ Class[] ex = mth.getExceptionTypes();
+ assertEquals("Returned incorrect number of exceptions",
+ 1, ex.length);
+ assertTrue("Returned incorrect exception type", ex[0]
+ .equals(IllegalArgumentException.class));
+ mth = TestMethod.class.getMethod("intMethod", new Class[0]);
+ ex = mth.getExceptionTypes();
+ assertEquals("Returned incorrect number of exceptions",
+ 0, ex.length);
+ } catch (Exception e) {
+ fail("Exception during getExceptionTypes: " + e.toString());
+ }
+
+ }
+
+ /**
+ * java.lang.reflect.Method#getModifiers()
+ */
+ public void test_getModifiers() {
+ // Test for method int java.lang.reflect.Method.getModifiers()
+
+ Class cl = TestMethod.class;
+ int mods = 0;
+ Method mth = null;
+ int mask = 0;
+ try {
+ mth = cl.getMethod("pustatic", new Class[0]);
+ mods = mth.getModifiers();
+ } catch (Exception e) {
+ fail("Exception during getModfiers test: " + e.toString());
+ }
+ mask = Modifier.PUBLIC | Modifier.STATIC;
+ assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
+ try {
+ mth = cl.getDeclaredMethod("prstatic", new Class[0]);
+ mods = mth.getModifiers();
+ } catch (Exception e) {
+ fail("Exception during getModfiers test: " + e.toString());
+ }
+ mask = Modifier.PRIVATE | Modifier.STATIC;
+ assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
+ try {
+ mth = cl.getDeclaredMethod("pustatsynch", new Class[0]);
+ mods = mth.getModifiers();
+ } catch (Exception e) {
+ fail("Exception during getModfiers test: " + e.toString());
+ }
+ mask = (Modifier.PUBLIC | Modifier.STATIC) | Modifier.SYNCHRONIZED;
+ assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
+ try {
+ mth = cl.getDeclaredMethod("pustatsynchnat", new Class[0]);
+ mods = mth.getModifiers();
+ } catch (Exception e) {
+ fail("Exception during getModfiers test: " + e.toString());
+ }
+ mask = ((Modifier.PUBLIC | Modifier.STATIC) | Modifier.SYNCHRONIZED)
+ | Modifier.NATIVE;
+ assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
+ cl = AbstractTestMethod.class;
+ try {
+ mth = cl.getDeclaredMethod("puabs", new Class[0]);
+ mods = mth.getModifiers();
+ } catch (Exception e) {
+ fail("Exception during getModfiers test: " + e.toString());
+ }
+ mask = Modifier.PUBLIC | Modifier.ABSTRACT;
+ assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
+ }
+
+ /**
+ * java.lang.reflect.Method#getName()
+ */
+ public void test_getName() {
+ // Test for method java.lang.String java.lang.reflect.Method.getName()
+ Method mth = null;
+ try {
+ mth = TestMethod.class.getMethod("voidMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getMethodName(): " + e.toString());
+ }
+ assertEquals("Returned incorrect method name",
+ "voidMethod", mth.getName());
+ }
+
+ /**
+ * java.lang.reflect.Method#isVarArgs()
+ */
+ public void test_isVarArgs() throws Exception {
+ Method mth = TestMethod.class.getMethod("publicVoidVarargs",
+ Object[].class);
+ assertTrue("Varargs method stated as non vararg.", mth.isVarArgs());
+
+ mth = TestMethod.class.getDeclaredMethod("publicVoidArray",
+ Object[].class);
+ assertFalse("Non varargs method stated as vararg.", mth.isVarArgs());
+ }
+
+ /**
+ * java.lang.reflect.Method#isBridge()
+ */
+ public void test_isBridge() throws Exception {
+ Method[] declaredMethods = BrigeTest.class.getDeclaredMethods();
+ assertEquals("Bridge method not generated.", 2, declaredMethods.length);
+ boolean foundBridgeMethod = false;
+ for (Method method : declaredMethods) {
+ if (method.getReturnType().equals(Object.class)) {
+ assertTrue("Bridge method not stated as bridge.", method
+ .isBridge());
+ foundBridgeMethod = true;
+ }
+ }
+ assertTrue("Bridge method not found.", foundBridgeMethod);
+ }
+
+ /**
+ * java.lang.reflect.Method#isSynthetic()
+ */
+ public void test_isSynthetic() throws Exception {
+ Method[] declaredMethods = BrigeTest.class.getDeclaredMethods();
+ assertEquals("Synthetic method not generated.", 2,
+ declaredMethods.length);
+ boolean foundSyntheticMethod = false;
+ for (Method method : declaredMethods) {
+ if (method.getReturnType().equals(Object.class)) {
+ assertTrue("Synthetic method not stated as synthetic.", method
+ .isSynthetic());
+ foundSyntheticMethod = true;
+ }
+ }
+ assertTrue("Synthetic method not found.", foundSyntheticMethod);
+ }
+ /**
+ * java.lang.reflect.Method#getParameterAnnotations()
+ */
+ public void test_getParameterAnnotations() throws Exception {
+ Method method = TestMethod.class.getDeclaredMethod(
+ "annotatedParameter", new Class[] {
+ int.class, int.class, int.class});
+ Annotation[][] annotations = method.getParameterAnnotations();
+ assertEquals(3, annotations.length);
+ assertEquals(
+ "Wrong number of annotations returned for first parameter", 2,
+ annotations[0].length);
+ Set<Class<?>> annotationSet = new HashSet<Class<?>>();
+ annotationSet.add(annotations[0][0].annotationType());
+ annotationSet.add(annotations[0][1].annotationType());
+ assertTrue("Missing TestAnno annotation", annotationSet
+ .contains(TestAnno.class));
+ assertTrue("Missing Deprecated annotation", annotationSet
+ .contains(Deprecated.class));
+
+ assertEquals(
+ "Wrong number of annotations returned for second parameter",
+ 1, annotations[1].length);
+ annotationSet = new HashSet<Class<?>>();
+ annotationSet.add(annotations[1][0].annotationType());
+ assertTrue("Missing Deprecated annotation", annotationSet
+ .contains(Deprecated.class));
+ assertEquals(
+ "Wrong number of annotations returned for third parameter", 0,
+ annotations[2].length);
+ }
+
+ /**
+ * java.lang.reflect.Method#getDeclaredAnnotations()
+ */
+ public void test_getDeclaredAnnotations() throws Exception {
+ Method method = TestMethod.class.getDeclaredMethod("annotatedMethod");
+ Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
+ assertEquals(2, declaredAnnotations.length);
+
+ Set<Class<?>> annotationSet = new HashSet<Class<?>>();
+ annotationSet.add(declaredAnnotations[0].annotationType());
+ annotationSet.add(declaredAnnotations[1].annotationType());
+ assertTrue("Missing TestAnno annotation", annotationSet
+ .contains(TestAnno.class));
+ assertTrue("Missing Deprecated annotation", annotationSet
+ .contains(Deprecated.class));
+ }
+
+ /**
+ * java.lang.reflect.Method#getDefaultValue()
+ */
+ public void test_getDefaultValue() throws Exception {
+ Method method = TestAnno.class.getDeclaredMethod("value");
+ assertEquals("Wrong default value returned", TestAnno.DEFAULT_VALUE,
+ method.getDefaultValue());
+ }
+
+ /**
+ * java.lang.reflect.Method#getDefaultValue()
+ */
+ public void test_getGenericExceptionTypes() throws Exception {
+ Method method = ExceptionTest.class.getDeclaredMethod("exceptionTest");
+ Type[] genericExceptionTypes = method.getGenericExceptionTypes();
+ assertEquals(1, genericExceptionTypes.length);
+ assertTrue(genericExceptionTypes[0] instanceof TypeVariable<?>);
+ @SuppressWarnings("unchecked")
+ TypeVariable<Class<ExceptionTest<?>>> tv =
+ (TypeVariable<Class<ExceptionTest<?>>>) genericExceptionTypes[0];
+ assertEquals("T", tv.getName());
+ }
+
+ /**
+ * java.lang.reflect.Method#getGenericReturnType()
+ */
+ public void test_getGenericReturnType() throws Exception {
+ Method method = GenericReturnType.class
+ .getDeclaredMethod("returnGeneric");
+ Type returnType = method.getGenericReturnType();
+ assertNotNull("getGenericReturnType returned null", returnType);
+ assertTrue(returnType instanceof TypeVariable<?>);
+ @SuppressWarnings("unchecked")
+ TypeVariable<Class<ExceptionTest<?>>> tv =
+ (TypeVariable<Class<ExceptionTest<?>>>) returnType;
+ assertEquals("T", tv.getName());
+ }
+
+
+ /**
+ * java.lang.reflect.Method#toGenericString()
+ */
+ public void test_toGenericString() throws Exception {
+ Method method = GenericString.class.getDeclaredMethod("genericString",
+ Object.class);
+ assertEquals("Wrong generic String returned", GenericString.GENERIC,
+ method.toGenericString());
+ }
+
+
+
+
+
+
+ /**
+ * java.lang.reflect.Method#hashCode()
+ */
+ public void test_hashCode() throws Exception {
+ Method mth0 = TestMethod.class.getMethod("hashCodeTest", String.class);
+ Method mth1 = TestMethod.class.getDeclaredMethod("hashCodeTest",
+ int.class);
+ assertEquals("Methods with same name did not return same hashCode.",
+ mth0.hashCode(), mth1.hashCode());
+ }
+
+ /**
+ * java.lang.reflect.Method#getParameterTypes()
+ */
+ public void test_getParameterTypes() {
+ // Test for method java.lang.Class []
+ // java.lang.reflect.Method.getParameterTypes()
+ Class cl = TestMethod.class;
+ Method mth = null;
+ Class[] parms = null;
+ Method[] methods = null;
+ Class[] plist = { int.class, short.class, String.class, boolean.class,
+ Object.class, long.class, byte.class, char.class, double.class,
+ float.class };
+ try {
+ mth = cl.getMethod("voidMethod", new Class[0]);
+ parms = mth.getParameterTypes();
+ } catch (Exception e) {
+ fail("Exception during getParameterTypes test: "
+ + e.toString());
+ }
+ assertEquals("Returned incorrect parameterTypes", 0, parms.length);
+ try {
+ mth = cl.getMethod("parmTest", plist);
+ parms = mth.getParameterTypes();
+ } catch (Exception e) {
+ fail("Exception during getParameterTypes test: "
+ + e.toString());
+ }
+ assertTrue("Invalid number of parameters returned",
+ plist.length == parms.length);
+ for (int i = 0; i < plist.length; i++)
+ assertTrue("Incorrect parameter returned", plist[i]
+ .equals(parms[i]));
+
+ // Test same method. but this time pull it from the list of methods
+ // rather than asking for it explicitly
+ methods = cl.getDeclaredMethods();
+
+ int i;
+ for (i = 0; i < methods.length; i++)
+ if (methods[i].getName().equals("parmTest")) {
+ mth = methods[i];
+ i = methods.length + 1;
+ }
+ if (i < methods.length) {
+ parms = mth.getParameterTypes();
+ assertTrue("Incorrect number of parameters returned",
+ parms.length == plist.length);
+ for (i = 0; i < plist.length; i++)
+ assertTrue("Incorrect parameter returned", plist[i]
+ .equals(parms[i]));
+ }
+ }
+
+ /**
+ * java.lang.reflect.Method#getReturnType()
+ */
+ public void test_getReturnType() {
+ // Test for method java.lang.Class
+ // java.lang.reflect.Method.getReturnType()
+ Class cl = TestMethod.class;
+ Method mth = null;
+ try {
+ mth = cl.getMethod("charMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test : " + e.getMessage());
+ }
+ assertTrue("Gave incorrect returne type, wanted char", mth
+ .getReturnType().equals(char.class));
+ try {
+ mth = cl.getMethod("longMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test : " + e.getMessage());
+ }
+ assertTrue("Gave incorrect returne type, wanted long", mth
+ .getReturnType().equals(long.class));
+ try {
+ mth = cl.getMethod("shortMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test : " + e.getMessage());
+ }
+ assertTrue("Gave incorrect returne type, wanted short", mth
+ .getReturnType().equals(short.class));
+ try {
+ mth = cl.getMethod("intMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test : " + e.getMessage());
+ }
+ assertTrue("Gave incorrect returne type, wanted int: "
+ + mth.getReturnType(), mth.getReturnType().equals(int.class));
+ try {
+ mth = cl.getMethod("doubleMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test : " + e.getMessage());
+ }
+ assertTrue("Gave incorrect returne type, wanted double", mth
+ .getReturnType().equals(double.class));
+ try {
+ mth = cl.getMethod("byteMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test : " + e.getMessage());
+ }
+ assertTrue("Gave incorrect returne type, wanted byte", mth
+ .getReturnType().equals(byte.class));
+ try {
+ mth = cl.getMethod("byteMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test:" + e.toString());
+ }
+ assertTrue("Gave incorrect returne type, wanted byte", mth
+ .getReturnType().equals(byte.class));
+ try {
+ mth = cl.getMethod("objectMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test : " + e.getMessage());
+ }
+ assertTrue("Gave incorrect returne type, wanted Object", mth
+ .getReturnType().equals(Object.class));
+
+ try {
+ mth = cl.getMethod("voidMethod", new Class[0]);
+ } catch (Exception e) {
+ fail("Exception during getReturnType test : " + e.getMessage());
+ }
+ assertTrue("Gave incorrect returne type, wanted void", mth
+ .getReturnType().equals(void.class));
+ }
+
+ /**
+ * java.lang.reflect.Method#invoke(java.lang.Object,
+ * java.lang.Object[])
+ */
+ public void test_invokeLjava_lang_Object$Ljava_lang_Object() throws Exception{
+ // Test for method java.lang.Object
+ // java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object
+ // [])
+ Class cl = TestMethod.class;
+ Class[] dcl = new Class[0];
+
+ // Get and invoke a static method
+ Method mth = cl.getDeclaredMethod("invokeStaticTest", dcl);
+ Object ret = mth.invoke(null, new Object[0]);
+ assertEquals("Invoke returned incorrect value", 1, ((Integer) ret)
+ .intValue());
+
+ // Get and invoke an instance method
+ mth = cl.getDeclaredMethod("invokeInstanceTest", dcl);
+ ret = mth.invoke(new TestMethod(), new Object[0]);
+ assertEquals("Invoke returned incorrect value", 1, ((Integer) ret)
+ .intValue());
+
+ // Get and attempt to invoke a private method
+ mth = cl.getDeclaredMethod("privateInvokeTest", dcl);
+ try {
+ ret = mth.invoke(new TestMethod(), new Object[0]);
+ } catch (IllegalAccessException e) {
+ // Correct behaviour
+ } catch (Exception e) {
+ fail("Exception during invoke test : " + e.getMessage());
+ }
+ // Generate an IllegalArgumentException
+ mth = cl.getDeclaredMethod("invokeInstanceTest", dcl);
+
+ try {
+ Object[] args = { Object.class };
+ ret = mth.invoke(new TestMethod(), args);
+ } catch (IllegalArgumentException e) {
+ // Correct behaviour
+ } catch (Exception e) {
+ fail("Exception during invoke test : " + e.getMessage());
+ }
+
+ // Generate a NullPointerException
+ mth = cl.getDeclaredMethod("invokeInstanceTest", dcl);
+
+ try {
+ ret = mth.invoke(null, new Object[0]);
+ } catch (NullPointerException e) {
+ // Correct behaviour
+ } catch (Exception e) {
+ fail("Exception during invoke test : " + e.getMessage());
+ }
+
+ // Generate an InvocationTargetException
+ mth = cl.getDeclaredMethod("invokeExceptionTest", dcl);
+ try {
+ ret = mth.invoke(new TestMethod(), new Object[0]);
+ } catch (InvocationTargetException e) {
+ // Correct behaviour
+ } catch (Exception e) {
+ fail("Exception during invoke test : " + e.getMessage());
+ }
+
+ TestMethod testMethod = new TestMethod();
+ Method methods[] = cl.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i].getName().startsWith("invokeCastTest1")) {
+ Class param = methods[i].getParameterTypes()[0];
+
+ try {
+ methods[i].invoke(testMethod, new Object[] { new Byte(
+ (byte) 1) });
+ assertTrue("invalid invoke with Byte: " + methods[i],
+ param == Byte.TYPE || param == Short.TYPE
+ || param == Integer.TYPE
+ || param == Long.TYPE
+ || param == Float.TYPE
+ || param == Double.TYPE);
+ } catch (Exception e) {
+ assertTrue("Byte invalid exception: " + e,
+ e instanceof IllegalArgumentException);
+ assertTrue("Byte invalid failure: " + methods[i],
+ param == Boolean.TYPE || param == Character.TYPE);
+ }
+
+ try {
+ methods[i].invoke(testMethod, new Object[] { new Short(
+ (short) 1) });
+ assertTrue("invalid invoke with Short: " + methods[i],
+ param == Short.TYPE || param == Integer.TYPE
+ || param == Long.TYPE
+ || param == Float.TYPE
+ || param == Double.TYPE);
+ } catch (Exception e) {
+ assertTrue("Short invalid exception: " + e,
+ e instanceof IllegalArgumentException);
+ assertTrue("Short invalid failure: " + methods[i],
+ param == Byte.TYPE || param == Boolean.TYPE
+ || param == Character.TYPE);
+ }
+
+ try {
+ methods[i].invoke(testMethod,
+ new Object[] { new Integer(1) });
+ assertTrue("invalid invoke with Integer: " + methods[i],
+ param == Integer.TYPE || param == Long.TYPE
+ || param == Float.TYPE
+ || param == Double.TYPE);
+ } catch (Exception e) {
+ assertTrue("Integer invalid exception: " + e,
+ e instanceof IllegalArgumentException);
+ assertTrue("Integer invalid failure: " + methods[i],
+ param == Byte.TYPE || param == Short.TYPE
+ || param == Boolean.TYPE
+ || param == Character.TYPE);
+ }
+
+ try {
+ methods[i].invoke(testMethod, new Object[] { new Long(1) });
+ assertTrue("invalid invoke with Long: " + methods[i],
+ param == Long.TYPE || param == Float.TYPE
+ || param == Double.TYPE);
+ } catch (Exception e) {
+ assertTrue("Long invalid exception: " + e,
+ e instanceof IllegalArgumentException);
+ assertTrue("Long invalid failure: " + methods[i],
+ param == Byte.TYPE || param == Short.TYPE
+ || param == Integer.TYPE
+ || param == Boolean.TYPE
+ || param == Character.TYPE);
+ }
+
+ try {
+ methods[i].invoke(testMethod, new Object[] { new Character(
+ 'a') });
+ assertTrue("invalid invoke with Character: " + methods[i],
+ param == Character.TYPE || param == Integer.TYPE
+ || param == Long.TYPE
+ || param == Float.TYPE
+ || param == Double.TYPE);
+ } catch (Exception e) {
+ assertTrue("Character invalid exception: " + e,
+ e instanceof IllegalArgumentException);
+ assertTrue("Character invalid failure: " + methods[i],
+ param == Byte.TYPE || param == Short.TYPE
+ || param == Boolean.TYPE);
+ }
+
+ try {
+ methods[i]
+ .invoke(testMethod, new Object[] { new Float(1) });
+ assertTrue("invalid invoke with Float: " + methods[i],
+ param == Float.TYPE || param == Double.TYPE);
+ } catch (Exception e) {
+ assertTrue("Float invalid exception: " + e,
+ e instanceof IllegalArgumentException);
+ assertTrue("Float invalid failure: " + methods[i],
+ param == Byte.TYPE || param == Short.TYPE
+ || param == Integer.TYPE
+ || param == Long.TYPE
+ || param == Boolean.TYPE
+ || param == Character.TYPE);
+ }
+
+ try {
+ methods[i].invoke(testMethod,
+ new Object[] { new Double(1) });
+ assertTrue("invalid invoke with Double: " + methods[i],
+ param == Double.TYPE);
+ } catch (Exception e) {
+ assertTrue("Double invalid exception: " + e,
+ e instanceof IllegalArgumentException);
+ assertTrue("Double invalid failure: " + methods[i],
+ param == Byte.TYPE || param == Short.TYPE
+ || param == Integer.TYPE
+ || param == Long.TYPE
+ || param == Boolean.TYPE
+ || param == Character.TYPE
+ || param == Float.TYPE);
+ }
+
+ try {
+ methods[i].invoke(testMethod, new Object[] { new Boolean(
+ true) });
+ assertTrue("invalid invoke with Boolean: " + methods[i],
+ param == Boolean.TYPE);
+ } catch (Exception e) {
+ assertTrue("Boolean invalid exception: " + e,
+ e instanceof IllegalArgumentException);
+ assertTrue("Boolean invalid failure: " + methods[i],
+ param == Byte.TYPE || param == Short.TYPE
+ || param == Integer.TYPE
+ || param == Long.TYPE
+ || param == Character.TYPE
+ || param == Float.TYPE
+ || param == Double.TYPE);
+ }
+ }
+ }
+ }
+
+ /**
+ * java.lang.reflect.Method#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.lang.reflect.Method.toString()
+ Method mth = null;
+ Class[] parms = { int.class, short.class, String.class, boolean.class,
+ Object.class, long.class, byte.class, char.class, double.class,
+ float.class };
+ try {
+
+ mth = TestMethod.class.getDeclaredMethod("printTest", parms);
+ } catch (Exception e) {
+ fail("Exception during toString test : " + e.getMessage());
+ }
+
+ assertTrue(
+ "Returned incorrect string for method: " + mth.toString(),
+ mth
+ .toString()
+ .equals(
+ "public static final void org.apache.harmony.tests.java.lang.reflect.MethodTest$TestMethod.printTest(int,short,java.lang.String,boolean,java.lang.Object,long,byte,char,double,float)"));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ModifierTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ModifierTest.java
new file mode 100644
index 0000000..71c207f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ModifierTest.java
@@ -0,0 +1,435 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.Modifier;
+
+public class ModifierTest extends junit.framework.TestCase {
+
+ private static final int ALL_FLAGS = 0x7FF;
+
+ /**
+ * java.lang.reflect.Modifier#Modifier()
+ */
+ public void test_Constructor() {
+ // Test for method java.lang.reflect.Modifier()
+ new Modifier();
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isAbstract(int)
+ */
+ public void test_isAbstractI() {
+ // Test for method boolean java.lang.reflect.Modifier.isAbstract(int)
+ assertTrue("ABSTRACT returned false", Modifier.isAbstract(ALL_FLAGS));
+ assertTrue("ABSTRACT returned false", Modifier
+ .isAbstract(Modifier.ABSTRACT));
+ assertTrue("Non-ABSTRACT returned true", !Modifier
+ .isAbstract(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isFinal(int)
+ */
+ public void test_isFinalI() {
+ // Test for method boolean java.lang.reflect.Modifier.isFinal(int)
+ assertTrue("FINAL returned false", Modifier.isFinal(ALL_FLAGS));
+ assertTrue("FINAL returned false", Modifier.isFinal(Modifier.FINAL));
+ assertTrue("Non-FINAL returned true", !Modifier
+ .isFinal(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isInterface(int)
+ */
+ public void test_isInterfaceI() {
+ // Test for method boolean java.lang.reflect.Modifier.isInterface(int)
+ assertTrue("INTERFACE returned false", Modifier.isInterface(ALL_FLAGS));
+ assertTrue("INTERFACE returned false", Modifier
+ .isInterface(Modifier.INTERFACE));
+ assertTrue("Non-INTERFACE returned true", !Modifier
+ .isInterface(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isNative(int)
+ */
+ public void test_isNativeI() {
+ // Test for method boolean java.lang.reflect.Modifier.isNative(int)
+ assertTrue("NATIVE returned false", Modifier.isNative(ALL_FLAGS));
+ assertTrue("NATIVE returned false", Modifier.isNative(Modifier.NATIVE));
+ assertTrue("Non-NATIVE returned true", !Modifier
+ .isNative(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isPrivate(int)
+ */
+ public void test_isPrivateI() {
+ // Test for method boolean java.lang.reflect.Modifier.isPrivate(int)
+ assertTrue("PRIVATE returned false", Modifier.isPrivate(ALL_FLAGS));
+ assertTrue("PRIVATE returned false", Modifier
+ .isPrivate(Modifier.PRIVATE));
+ assertTrue("Non-PRIVATE returned true", !Modifier
+ .isPrivate(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isProtected(int)
+ */
+ public void test_isProtectedI() {
+ // Test for method boolean java.lang.reflect.Modifier.isProtected(int)
+ assertTrue("PROTECTED returned false", Modifier.isProtected(ALL_FLAGS));
+ assertTrue("PROTECTED returned false", Modifier
+ .isProtected(Modifier.PROTECTED));
+ assertTrue("Non-PROTECTED returned true", !Modifier
+ .isProtected(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isPublic(int)
+ */
+ public void test_isPublicI() {
+ // Test for method boolean java.lang.reflect.Modifier.isPublic(int)
+ assertTrue("PUBLIC returned false", Modifier.isPublic(ALL_FLAGS));
+ assertTrue("PUBLIC returned false", Modifier.isPublic(Modifier.PUBLIC));
+ assertTrue("Non-PUBLIC returned true", !Modifier
+ .isPublic(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isStatic(int)
+ */
+ public void test_isStaticI() {
+ // Test for method boolean java.lang.reflect.Modifier.isStatic(int)
+ assertTrue("STATIC returned false", Modifier.isStatic(ALL_FLAGS));
+ assertTrue("STATIC returned false", Modifier.isStatic(Modifier.STATIC));
+ assertTrue("Non-STATIC returned true", !Modifier
+ .isStatic(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isStrict(int)
+ */
+ public void test_isStrictI() {
+ // Test for method boolean java.lang.reflect.Modifier.isStrict(int)
+ assertTrue("STRICT returned false", Modifier.isStrict(Modifier.STRICT));
+ assertTrue("Non-STRICT returned true", !Modifier
+ .isStrict(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isSynchronized(int)
+ */
+ public void test_isSynchronizedI() {
+ // Test for method boolean
+ // java.lang.reflect.Modifier.isSynchronized(int)
+ assertTrue("Synchronized returned false", Modifier
+ .isSynchronized(ALL_FLAGS));
+ assertTrue("Non-Synchronized returned true", !Modifier
+ .isSynchronized(Modifier.VOLATILE));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isTransient(int)
+ */
+ public void test_isTransientI() {
+ // Test for method boolean java.lang.reflect.Modifier.isTransient(int)
+ assertTrue("Transient returned false", Modifier.isTransient(ALL_FLAGS));
+ assertTrue("Transient returned false", Modifier
+ .isTransient(Modifier.TRANSIENT));
+ assertTrue("Non-Transient returned true", !Modifier
+ .isTransient(Modifier.VOLATILE));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#isVolatile(int)
+ */
+ public void test_isVolatileI() {
+ // Test for method boolean java.lang.reflect.Modifier.isVolatile(int)
+ assertTrue("Volatile returned false", Modifier.isVolatile(ALL_FLAGS));
+ assertTrue("Volatile returned false", Modifier
+ .isVolatile(Modifier.VOLATILE));
+ assertTrue("Non-Volatile returned true", !Modifier
+ .isVolatile(Modifier.TRANSIENT));
+ }
+
+ /**
+ * java.lang.reflect.Modifier#toString(int)
+ */
+ public void test_toStringI() {
+ // Test for method java.lang.String
+ // java.lang.reflect.Modifier.toString(int)
+ assertTrue("Returned incorrect string value: "
+ + Modifier.toString(java.lang.reflect.Modifier.PUBLIC
+ + java.lang.reflect.Modifier.ABSTRACT), Modifier
+ .toString(
+ java.lang.reflect.Modifier.PUBLIC
+ + java.lang.reflect.Modifier.ABSTRACT).equals(
+ "public abstract"));
+
+ int i = 0xFFF;
+ String modification = "public protected private abstract static final transient "
+ + "volatile synchronized native strictfp interface";
+ assertTrue("Returned incorrect string value", Modifier.toString(i)
+ .equals(modification));
+ }
+
+ public void test_Constants_Value() {
+ assertEquals(1024, Modifier.ABSTRACT);
+ assertEquals(16, Modifier.FINAL);
+ assertEquals(512, Modifier.INTERFACE);
+ assertEquals(256, Modifier.NATIVE);
+ assertEquals(2, Modifier.PRIVATE);
+ assertEquals(4, Modifier.PROTECTED);
+ assertEquals(1, Modifier.PUBLIC);
+ assertEquals(8, Modifier.STATIC);
+ assertEquals(2048, Modifier.STRICT);
+ assertEquals(32, Modifier.SYNCHRONIZED);
+ assertEquals(128, Modifier.TRANSIENT);
+ assertEquals(64, Modifier.VOLATILE);
+ }
+
+ abstract class AbstractClazz {
+ }
+
+ final class FinalClazz {
+ }
+
+ static class StaticClazz {
+ }
+
+ interface InterfaceClazz {
+ }
+
+ public class PublicClazz {
+ }
+
+ protected class ProtectedClazz {
+ }
+
+ private class PrivateClazz {
+ }
+
+ public abstract class PublicAbstractClazz {
+ }
+
+ protected abstract class ProtectedAbstractClazz {
+ }
+
+ private abstract class PrivateAbstractClazz {
+ }
+
+ public final class PublicFinalClazz {
+ }
+
+ protected final class ProtectedFinalClazz {
+ }
+
+ private final class PrivateFinalClazz {
+ }
+
+ public static class PublicStaticClazz {
+ }
+
+ protected static class ProtectedStaticClazz {
+ }
+
+ private static class PrivateStaticClazz {
+ }
+
+ public interface PublicInterface {
+ }
+
+ protected interface ProtectedInterface {
+ }
+
+ private interface PrivateInterface {
+ }
+
+ static abstract class StaticAbstractClazz {
+ }
+
+ public static abstract class PublicStaticAbstractClazz {
+ }
+
+ protected static abstract class ProtectedStaticAbstractClazz {
+ }
+
+ private static abstract class PrivateStaticAbstractClazz {
+ }
+
+ static final class StaticFinalClazz {
+ }
+
+ public static final class PublicStaticFinalClazz {
+ }
+
+ protected static final class ProtectedStaticFinalClazz {
+ }
+
+ private static final class PrivateStaticFinalClazz {
+ }
+
+ static interface StaticInterface {
+ }
+
+ public static interface PublicStaticInterface {
+ }
+
+ protected static interface ProtectedStaticInterface {
+ }
+
+ private static interface PrivateStaticInterface {
+ }
+
+ static abstract interface StaticAbstractInterface {
+ }
+
+ public static abstract interface PublicStaticAbstractInterface {
+ }
+
+ protected static abstract interface ProtectedStaticAbstractInterface {
+ }
+
+ private static abstract interface PrivateStaticAbstractInterface {
+ }
+
+ public void test_Class_Modifier() {
+ assertEquals(Modifier.ABSTRACT, AbstractClazz.class.getModifiers());
+ assertEquals(Modifier.FINAL, FinalClazz.class.getModifiers());
+ assertEquals(Modifier.STATIC, StaticClazz.class.getModifiers());
+ assertEquals(Modifier.INTERFACE + Modifier.STATIC + Modifier.ABSTRACT,
+ InterfaceClazz.class.getModifiers());
+
+ assertEquals(Modifier.PUBLIC, PublicClazz.class.getModifiers());
+ assertEquals(Modifier.PROTECTED, ProtectedClazz.class.getModifiers());
+ assertEquals(Modifier.PRIVATE, PrivateClazz.class.getModifiers());
+
+ assertEquals(Modifier.PUBLIC + Modifier.ABSTRACT,
+ PublicAbstractClazz.class.getModifiers());
+ assertEquals(Modifier.PROTECTED + Modifier.ABSTRACT,
+ ProtectedAbstractClazz.class.getModifiers());
+ assertEquals(Modifier.PRIVATE + Modifier.ABSTRACT,
+ PrivateAbstractClazz.class.getModifiers());
+
+ assertEquals(Modifier.PUBLIC + Modifier.FINAL, PublicFinalClazz.class
+ .getModifiers());
+ assertEquals(Modifier.PROTECTED + Modifier.FINAL,
+ ProtectedFinalClazz.class.getModifiers());
+ assertEquals(Modifier.PRIVATE + Modifier.FINAL, PrivateFinalClazz.class
+ .getModifiers());
+
+ assertEquals(Modifier.PUBLIC + Modifier.STATIC, PublicStaticClazz.class
+ .getModifiers());
+ assertEquals(Modifier.PROTECTED + Modifier.STATIC,
+ ProtectedStaticClazz.class.getModifiers());
+ assertEquals(Modifier.PRIVATE + Modifier.STATIC,
+ PrivateStaticClazz.class.getModifiers());
+
+ assertEquals(Modifier.PUBLIC + Modifier.INTERFACE + Modifier.STATIC
+ + Modifier.ABSTRACT, PublicInterface.class.getModifiers());
+ assertEquals(Modifier.STATIC + Modifier.FINAL, StaticFinalClazz.class
+ .getModifiers());
+ assertEquals(Modifier.PRIVATE + Modifier.INTERFACE + Modifier.STATIC
+ + Modifier.ABSTRACT, PrivateInterface.class.getModifiers());
+
+ assertEquals(Modifier.STATIC + Modifier.ABSTRACT,
+ StaticAbstractClazz.class.getModifiers());
+ assertEquals(Modifier.PUBLIC + Modifier.STATIC + Modifier.ABSTRACT,
+ PublicStaticAbstractClazz.class.getModifiers());
+ assertEquals(Modifier.PROTECTED + Modifier.STATIC + Modifier.ABSTRACT,
+ ProtectedStaticAbstractClazz.class.getModifiers());
+ assertEquals(Modifier.PRIVATE + Modifier.STATIC + Modifier.ABSTRACT,
+ PrivateStaticAbstractClazz.class.getModifiers());
+
+ assertEquals(Modifier.STATIC + Modifier.FINAL, StaticFinalClazz.class
+ .getModifiers());
+ assertEquals(Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL,
+ PublicStaticFinalClazz.class.getModifiers());
+ assertEquals(Modifier.PROTECTED + Modifier.STATIC + Modifier.FINAL,
+ ProtectedStaticFinalClazz.class.getModifiers());
+ assertEquals(Modifier.PRIVATE + Modifier.STATIC + Modifier.FINAL,
+ PrivateStaticFinalClazz.class.getModifiers());
+
+ assertEquals(Modifier.INTERFACE + Modifier.STATIC + Modifier.ABSTRACT,
+ StaticInterface.class.getModifiers());
+ assertEquals(Modifier.PUBLIC + Modifier.INTERFACE + Modifier.STATIC
+ + Modifier.ABSTRACT, PublicStaticInterface.class.getModifiers());
+ assertEquals(Modifier.PROTECTED + Modifier.INTERFACE + Modifier.STATIC
+ + Modifier.ABSTRACT, ProtectedStaticInterface.class
+ .getModifiers());
+ assertEquals(Modifier.PRIVATE + Modifier.INTERFACE + Modifier.STATIC
+ + Modifier.ABSTRACT, PrivateStaticInterface.class
+ .getModifiers());
+
+ assertEquals(Modifier.INTERFACE + Modifier.STATIC + Modifier.ABSTRACT,
+ StaticAbstractInterface.class.getModifiers());
+ assertEquals(Modifier.PUBLIC + Modifier.INTERFACE + Modifier.STATIC
+ + Modifier.ABSTRACT, PublicStaticAbstractInterface.class
+ .getModifiers());
+ assertEquals(Modifier.PROTECTED + Modifier.INTERFACE + Modifier.STATIC
+ + Modifier.ABSTRACT, ProtectedStaticAbstractInterface.class
+ .getModifiers());
+ assertEquals(Modifier.PRIVATE + Modifier.INTERFACE + Modifier.STATIC
+ + Modifier.ABSTRACT, PrivateStaticAbstractInterface.class
+ .getModifiers());
+ }
+
+ static abstract class MethodClass {
+
+ public abstract void publicAbstractMethod();
+
+ public static void publicStaticMethod() {
+ }
+
+ public final void publicFinalMethod() {
+ }
+
+ public static final void publicStaticFinalMethod() {
+ }
+ }
+
+ public void test_Method_Modifier() throws Exception {
+ assertEquals(Modifier.PUBLIC + Modifier.ABSTRACT, MethodClass.class
+ .getMethod("publicAbstractMethod", new Class[0]).getModifiers());
+ assertEquals(Modifier.PUBLIC + Modifier.STATIC, MethodClass.class
+ .getMethod("publicStaticMethod", new Class[0]).getModifiers());
+
+ assertEquals(Modifier.PUBLIC + Modifier.FINAL, MethodClass.class
+ .getMethod("publicFinalMethod", new Class[0]).getModifiers());
+
+ assertEquals(Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL,
+ MethodClass.class.getMethod("publicStaticFinalMethod",
+ new Class[0]).getModifiers());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ParameterizedTypeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ParameterizedTypeTest.java
new file mode 100644
index 0000000..3b2614e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ParameterizedTypeTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/**
+ * Tests parameterized types and their properties.
+ */
+public class ParameterizedTypeTest extends GenericReflectionTestsBase {
+
+ static class A<T>{}
+ static class B extends A<String>{}
+
+ public void testStringParameterizedSuperClass() {
+ Class<? extends B> clazz = B.class;
+ Type genericSuperclass = clazz.getGenericSuperclass();
+ assertInstanceOf(ParameterizedType.class, genericSuperclass);
+ ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
+ assertEquals(ParameterizedTypeTest.class, parameterizedType.getOwnerType());
+ assertEquals(A.class, parameterizedType.getRawType());
+
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ assertLenghtOne(actualTypeArguments);
+ assertEquals(String.class, actualTypeArguments[0]);
+ }
+
+ static class C<T>{}
+ static class D<T> extends C<T>{}
+
+ public void testTypeParameterizedSuperClass() {
+ Class<? extends D> clazz = D.class;
+ Type genericSuperclass = clazz.getGenericSuperclass();
+ assertInstanceOf(ParameterizedType.class, genericSuperclass);
+ ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
+ assertEquals(ParameterizedTypeTest.class, parameterizedType.getOwnerType());
+ assertEquals(C.class, parameterizedType.getRawType());
+
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ assertLenghtOne(actualTypeArguments);
+ assertEquals(getTypeParameter(D.class), actualTypeArguments[0]);
+ }
+
+ static class E<T>{}
+ static class F<T>{
+ E<T> e;
+ }
+
+ public void testParameterizedMemeber() throws Exception{
+ Class<? extends F> clazz = F.class;
+ Field field = clazz.getDeclaredField("e");
+ assertInstanceOf(ParameterizedType.class, field.getGenericType());
+ ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
+ assertEquals(ParameterizedTypeTest.class, parameterizedType.getOwnerType());
+ assertEquals(E.class, parameterizedType.getRawType());
+
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ assertLenghtOne(actualTypeArguments);
+ assertEquals(getTypeParameter(clazz), actualTypeArguments[0]);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ProxyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ProxyTest.java
new file mode 100644
index 0000000..86383bd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ProxyTest.java
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import tests.support.Support_Proxy_I1;
+import tests.support.Support_Proxy_I2;
+import tests.support.Support_Proxy_ParentException;
+import tests.support.Support_Proxy_SubException;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.security.AllPermission;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+
+public class ProxyTest extends junit.framework.TestCase {
+
+ /*
+ * When multiple interfaces define the same method, the list of thrown
+ * exceptions are those which can be mapped to another exception in the
+ * other method:
+ *
+ * String foo(String s) throws SubException, LinkageError;
+ *
+ * UndeclaredThrowableException wrappers any checked exception which is not
+ * in the merged list. So ParentException would be wrapped, BUT LinkageError
+ * would not be since its not an Error/RuntimeException.
+ *
+ * interface I1 { String foo(String s) throws ParentException, LinkageError; }
+ * interface I2 { String foo(String s) throws SubException, Error; }
+ */
+
+ interface Broken1 {
+ public float method(float _number0, float _number1);
+ }
+
+ class Broken1Invoke implements InvocationHandler {
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return args[1];
+ }
+ }
+
+ class ProxyCoonstructorTest extends Proxy {
+ protected ProxyCoonstructorTest(InvocationHandler h) {
+ super(h);
+ }
+ }
+
+ /**
+ * java.lang.reflect.Proxy#getProxyClass(java.lang.ClassLoader,
+ * java.lang.Class[])
+ */
+ public void test_getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class() {
+ Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
+ .getClassLoader(), new Class[] { Support_Proxy_I1.class });
+
+ assertTrue("Did not create a Proxy subclass ",
+ proxy.getSuperclass() == Proxy.class);
+ assertTrue("Does not believe its a Proxy class ", Proxy
+ .isProxyClass(proxy));
+
+ assertTrue("Does not believe it's a Proxy class ", Proxy
+ .isProxyClass(Proxy.getProxyClass(null,
+ new Class[] { Comparable.class })));
+
+ try {
+ Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
+ (Class<?>[]) null);
+ fail("NPE expected");
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
+ new Class<?>[] {Support_Proxy_I1.class, null});
+ fail("NPE expected");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * java.lang.reflect.Proxy#Proxy(java.lang.reflect.InvocationHandler)
+ */
+ public void test_ProxyLjava_lang_reflect_InvocationHandler() {
+ assertNotNull(new ProxyCoonstructorTest(new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return null;
+ }
+ }));
+ }
+
+
+
+ /**
+ * java.lang.reflect.Proxy#newProxyInstance(java.lang.ClassLoader,
+ * java.lang.Class[], java.lang.reflect.InvocationHandler)
+ */
+ public void test_newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler()
+ throws Exception {
+ Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
+ .getClassLoader(), new Class[] { Support_Proxy_I1.class,
+ Support_Proxy_I2.class }, new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ if (method.getName().equals("equals"))
+ return new Boolean(proxy == args[0]);
+ if (method.getName().equals("array"))
+ return new int[] { (int) ((long[]) args[0])[1], -1 };
+ if (method.getName().equals("string")) {
+ if ("".equals(args[0]))
+ throw new Support_Proxy_SubException();
+ if ("clone".equals(args[0]))
+ throw new Support_Proxy_ParentException();
+ if ("error".equals(args[0]))
+ throw new ArrayStoreException();
+ if ("any".equals(args[0]))
+ throw new IllegalAccessException();
+ }
+ return null;
+ }
+ });
+
+ Support_Proxy_I1 proxy = (Support_Proxy_I1) p;
+ assertTrue("Failed identity test ", proxy.equals(proxy));
+ assertTrue("Failed not equals test ", !proxy.equals(""));
+ int[] result = (int[]) proxy.array(new long[] { 100L, -200L });
+ assertEquals("Failed primitive type conversion test ", -200, result[0]);
+
+ try {
+ proxy.string("");
+ fail("Problem converting exception");
+ } catch (Support_Proxy_SubException e) {
+ }
+
+ try {
+ proxy.string("clone");
+ fail("Problem converting exception");
+ } catch (UndeclaredThrowableException e) {
+ assertSame(Support_Proxy_ParentException.class, e.getCause().getClass());
+ }
+
+ try {
+ proxy.string("error");
+ fail("Problem converting exception");
+ } catch (ArrayStoreException e) {
+ }
+
+ try {
+ proxy.string("any");
+ fail("Problem converting exception");
+ } catch (UndeclaredThrowableException e) {
+ assertSame(IllegalAccessException.class, e.getCause().getClass());
+ }
+
+ Broken1 proxyObject = (Broken1) Proxy.newProxyInstance(Broken1.class
+ .getClassLoader(), new Class[] { Broken1.class },
+ new Broken1Invoke());
+
+ float brokenResult = proxyObject.method(2.1f, 5.8f);
+ assertTrue("Invalid invoke result", brokenResult == 5.8f);
+ }
+
+ /**
+ * java.lang.reflect.Proxy#isProxyClass(java.lang.Class)
+ */
+ public void test_isProxyClassLjava_lang_Class() {
+ Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
+ .getClassLoader(), new Class[] { Support_Proxy_I1.class });
+
+ class Fake extends Proxy {
+ Fake() {
+ super(null);
+ }
+ }
+
+ Proxy fake = new Proxy(new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return null;
+ }
+ }) {
+ };
+
+ assertTrue("Does not believe its a Proxy class ", Proxy
+ .isProxyClass(proxy));
+ assertTrue("Proxy subclasses do not count ", !Proxy
+ .isProxyClass(Fake.class));
+ assertTrue("Is not a runtime generated Proxy class ", !Proxy
+ .isProxyClass(fake.getClass()));
+ try{
+ Proxy.isProxyClass(null);
+ fail("NPE was not thrown");
+ } catch (NullPointerException expected){
+ }
+ }
+
+ /**
+ * java.lang.reflect.Proxy#getInvocationHandler(java.lang.Object)
+ */
+ public void test_getInvocationHandlerLjava_lang_Object() {
+ InvocationHandler handler = new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return null;
+ }
+ };
+
+ Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
+ .getClassLoader(), new Class[] { Support_Proxy_I1.class },
+ handler);
+
+ assertTrue("Did not return invocation handler ", Proxy
+ .getInvocationHandler(p) == handler);
+ try {
+ Proxy.getInvocationHandler("");
+ fail("Did not detect non proxy object");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ //Regression Test for HARMONY-2355
+ public void test_newProxyInstance_withCompatibleReturnTypes() {
+ Object o = Proxy
+ .newProxyInstance(this.getClass().getClassLoader(),
+ new Class[] { ITestReturnObject.class,
+ ITestReturnString.class },
+ new TestProxyHandler(new TestProxyImpl()));
+ assertNotNull(o);
+ }
+
+ public void test_newProxyInstance_withNonCompatibleReturnTypes() {
+ try {
+ Proxy.newProxyInstance(this.getClass().getClassLoader(),
+ new Class[] { ITestReturnInteger.class,
+ ITestReturnString.class }, new TestProxyHandler(
+ new TestProxyImpl()));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public void test_ProxyClass_withParentAndSubInThrowList() throws SecurityException, NoSuchMethodException {
+ TestParentIntf myImpl = new MyImplWithParentAndSubInThrowList();
+ Class<?> c = Proxy.getProxyClass(myImpl.getClass().getClassLoader(), myImpl.getClass().getInterfaces());
+ Method m = c.getMethod("test", (Class<?>[]) null);
+ Class<?>[] exceptions = m.getExceptionTypes();
+ ArrayList<Class> exps = new ArrayList<Class>();
+ for (Class<?> exp : exceptions) {
+ exps.add(exp);
+ }
+ assertTrue(exps.contains(Exception.class));
+ }
+
+ public static interface ITestReturnObject {
+ Object f();
+ }
+
+ public static interface ITestReturnString {
+ String f();
+ }
+
+ public static interface ITestReturnInteger {
+ Integer f();
+ }
+
+ public static class TestProxyImpl implements ITestReturnObject,
+ ITestReturnString {
+ public String f() {
+ // do nothing
+ return null;
+ }
+ }
+
+ public static class TestProxyHandler implements InvocationHandler {
+ private Object proxied;
+
+ public TestProxyHandler(Object object) {
+ proxied = object;
+ }
+
+ public Object invoke(Object object, Method method, Object[] args)
+ throws Throwable {
+ // do nothing
+ return method.invoke(proxied, args);
+ }
+
+ }
+
+ class MyImplWithParentAndSubInThrowList implements TestSubIntf {
+ public void test() throws Exception {
+ throw new Exception();
+ }
+ }
+
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
+
+interface PkgIntf {
+}
+
+interface TestParentIntf {
+ //IOException is a subclass of Exception
+ public void test() throws IOException, Exception;
+}
+
+interface TestSubIntf extends TestParentIntf {
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/TypeVariableTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/TypeVariableTest.java
new file mode 100644
index 0000000..d1c7ea9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/TypeVariableTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+/**
+ * Tests type variables and their properties.
+ */
+public class TypeVariableTest extends GenericReflectionTestsBase {
+
+ static class A<T>{}
+ public void testSimpleTypeVariableOnClass(){
+ Class<? extends A> clazz = A.class;
+ TypeVariable[] typeParameters = clazz.getTypeParameters();
+ assertLenghtOne(typeParameters);
+ TypeVariable<Class> typeVariable = typeParameters[0];
+ assertEquals(clazz, typeVariable.getGenericDeclaration());
+ assertEquals("T", typeVariable.getName());
+ Type[] bounds = typeVariable.getBounds();
+ assertLenghtOne(bounds);
+ assertEquals(Object.class, bounds[0]);
+ }
+
+ static class B{
+ <T> void b(){};
+ }
+ public void testSimpleTypeVariableOnMethod() throws Exception{
+ Class<? extends B> clazz = B.class;
+ Method method = clazz.getDeclaredMethod("b");
+ TypeVariable<Method>[] typeParameters = method.getTypeParameters();
+ assertLenghtOne(typeParameters);
+ TypeVariable<Method> typeVariable = typeParameters[0];
+ assertEquals(method, typeVariable.getGenericDeclaration());
+ assertEquals("T", typeVariable.getName());
+ Type[] bounds = typeVariable.getBounds();
+ assertLenghtOne(bounds);
+ assertEquals(Object.class, bounds[0]);
+ }
+
+ static class C {
+ <T>C(){}
+ }
+ public void testSimpleTypeVariableOnConstructor() throws Exception{
+ Class<? extends C> clazz = C.class;
+ Constructor<?> constructor = clazz.getDeclaredConstructor();
+ TypeVariable<?>[] typeParameters = constructor.getTypeParameters();
+ assertLenghtOne(typeParameters);
+ TypeVariable<?> typeVariable = typeParameters[0];
+ assertEquals(constructor, typeVariable.getGenericDeclaration());
+ assertEquals("T", typeVariable.getName());
+ Type[] bounds = typeVariable.getBounds();
+ assertLenghtOne(bounds);
+ assertEquals(Object.class, bounds[0]);
+ }
+
+ static class D<Q,R,S>{}
+ public void testMultipleTypeVariablesOnClass() throws Exception {
+ Class<? extends D> clazz = D.class;
+ TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
+ assertEquals(3, typeParameters.length);
+ assertEquals("Q", typeParameters[0].getName());
+ assertEquals(clazz, typeParameters[0].getGenericDeclaration());
+
+ assertEquals("R", typeParameters[1].getName());
+ assertEquals(clazz, typeParameters[1].getGenericDeclaration());
+
+ assertEquals("S", typeParameters[2].getName());
+ assertEquals(clazz, typeParameters[2].getGenericDeclaration());
+
+ }
+
+ static class E {
+ <Q,R,S> void e(){}
+ }
+ public void testMultipleTypeVariablesOnMethod() throws Exception {
+ Class<? extends E> clazz = E.class;
+ Method method = clazz.getDeclaredMethod("e");
+
+ TypeVariable<?>[] typeParameters = method.getTypeParameters();
+ assertEquals(3, typeParameters.length);
+ assertEquals("Q", typeParameters[0].getName());
+ assertEquals(method, typeParameters[0].getGenericDeclaration());
+
+ assertEquals("R", typeParameters[1].getName());
+ assertEquals(method, typeParameters[1].getGenericDeclaration());
+
+ assertEquals("S", typeParameters[2].getName());
+ assertEquals(method, typeParameters[2].getGenericDeclaration());
+ }
+
+ static class F {
+ <Q,R,S> F(){}
+ }
+ public void testMultipleTypeVariablesOnConstructor() throws Exception {
+ Class<? extends F> clazz = F.class;
+ Constructor<?> constructor = clazz.getDeclaredConstructor();
+
+ TypeVariable<?>[] typeParameters = constructor.getTypeParameters();
+ assertEquals(3, typeParameters.length);
+ assertEquals("Q", typeParameters[0].getName());
+ assertEquals(constructor, typeParameters[0].getGenericDeclaration());
+
+ assertEquals("R", typeParameters[1].getName());
+ assertEquals(constructor, typeParameters[1].getGenericDeclaration());
+
+ assertEquals("S", typeParameters[2].getName());
+ assertEquals(constructor, typeParameters[2].getGenericDeclaration());
+ }
+
+ static class G <T extends Number>{}
+
+ public void testSingleBound() throws Exception {
+ Class<? extends G> clazz = G.class;
+ TypeVariable[] typeParameters = clazz.getTypeParameters();
+ TypeVariable<Class> typeVariable = typeParameters[0];
+ Type[] bounds = typeVariable.getBounds();
+ assertLenghtOne(bounds);
+ assertEquals(Number.class, bounds[0]);
+ }
+
+ static class H <T extends Number & Serializable >{}
+ public void testMultipleBound() throws Exception {
+ Class<? extends H> clazz = H.class;
+ TypeVariable[] typeParameters = clazz.getTypeParameters();
+ TypeVariable<Class> typeVariable = typeParameters[0];
+ Type[] bounds = typeVariable.getBounds();
+ assertEquals(2, bounds.length);
+ assertEquals(Number.class, bounds[0]);
+ assertEquals(Serializable.class, bounds[1]);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/UndeclaredThrowableExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/UndeclaredThrowableExceptionTest.java
new file mode 100644
index 0000000..9f3679e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/UndeclaredThrowableExceptionTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.lang.reflect;
+
+import java.lang.reflect.UndeclaredThrowableException;
+
+import junit.framework.TestCase;
+
+public class UndeclaredThrowableExceptionTest extends TestCase {
+
+ /**
+ * {@link java.lang.reflect.UndeclaredThrowableException#UndeclaredThrowableException(java.lang.Throwable)}
+ */
+ public void test_UndeclaredThrowableException_LThrowable() {
+ UndeclaredThrowableException e = new UndeclaredThrowableException(
+ (Exception) null);
+ assertNotNull(e);
+ assertNull(e.getCause());
+
+ }
+
+ /**
+ * {@link java.lang.reflect.UndeclaredThrowableException#UndeclaredThrowableException(java.lang.Throwable, java.lang.String)}
+ */
+ public void test_UndeclaredThrowableException_LThrowable_LString() {
+ UndeclaredThrowableException e = new UndeclaredThrowableException(null,
+ "SomeMsg");
+ assertNotNull(e);
+ assertNull(e.getCause());
+ assertEquals("Wrong message", "SomeMsg", e.getMessage());
+ }
+
+ /**
+ * {@link java.lang.reflect.UndeclaredThrowableException#getUndeclaredThrowable()}
+ */
+ public void test_getUndeclaredThrowable() {
+ UndeclaredThrowableException e = new UndeclaredThrowableException(null);
+ assertNotNull(e);
+ assertNull(e.getUndeclaredThrowable());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/UndeclaredThrowableExceptionTests.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/UndeclaredThrowableExceptionTests.java
new file mode 100644
index 0000000..2112ed7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/UndeclaredThrowableExceptionTests.java
@@ -0,0 +1,53 @@
+package org.apache.harmony.tests.java.lang.reflect;
+
+import junit.framework.TestCase;
+
+import java.io.EOFException;
+import java.lang.reflect.UndeclaredThrowableException;
+
+public class UndeclaredThrowableExceptionTests extends TestCase {
+
+ private static EOFException throwable = new EOFException();
+ private static String msg = "TEST_MSG";
+ /**
+ * java.lang.reflect.UndeclaredThrowableException#getCause()
+ */
+ public void test_getCause() throws Exception {
+ UndeclaredThrowableException ute = new UndeclaredThrowableException(
+ throwable);
+ assertSame("Wrong cause returned", throwable, ute.getCause());
+ }
+
+ /**
+ * java.lang.reflect.UndeclaredThrowableException#getUndeclaredThrowable()
+ */
+ public void test_getUndeclaredThrowable() throws Exception {
+ UndeclaredThrowableException ute = new UndeclaredThrowableException(
+ throwable);
+ assertSame("Wrong undeclared throwable returned", throwable, ute
+ .getUndeclaredThrowable());
+ }
+
+ /**
+ * java.lang.reflect.UndeclaredThrowableException#UndeclaredThrowableException(java.lang.Throwable)
+ */
+ public void test_Constructor_Throwable() throws Exception {
+ UndeclaredThrowableException e = new UndeclaredThrowableException(
+ throwable);
+ assertEquals("Wrong cause returned", throwable, e.getCause());
+ assertEquals("Wrong throwable returned", throwable, e
+ .getUndeclaredThrowable());
+ }
+
+ /**
+ * java.lang.reflect.UndeclaredThrowableException#UndeclaredThrowableException(java.lang.Throwable, java.lang.String)
+ */
+ public void test_Constructor_Throwable_String() throws Exception {
+ UndeclaredThrowableException e = new UndeclaredThrowableException(
+ throwable, msg);
+ assertEquals("Wrong cause returned", throwable, e.getCause());
+ assertEquals("Wrong throwable returned", throwable, e
+ .getUndeclaredThrowable());
+ assertEquals("Wrong message returned", msg, e.getMessage());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/WildcardTypeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/WildcardTypeTest.java
new file mode 100644
index 0000000..e29fd47
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/WildcardTypeTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.lang.reflect;
+
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+
+/**
+ * Tests bounded type parameters declared on methods and bounded wildcards.
+ */
+public class WildcardTypeTest extends GenericReflectionTestsBase {
+ @SuppressWarnings({"unchecked", "hiding"})
+ static class BoundedWildcardsGenericMethods<T> {
+
+ public <T extends BoundedWildcardsGenericMethods> void lowerBoundedParamNoReturn( BoundedWildcardsGenericMethods<? super T> param) {}
+
+ public <T extends BoundedWildcardsGenericMethods> void upperBoundedParamNoReturn( BoundedWildcardsGenericMethods<? extends T> param) {}
+
+ public <T extends BoundedWildcardsGenericMethods> T lowerBoundedParamReturn(BoundedWildcardsGenericMethods<? super T> param) { return (T) new Object(); }
+
+ public <T extends BoundedWildcardsGenericMethods> T upperBoundedParamReturn(BoundedWildcardsGenericMethods<? extends T> param) { return (T) new Object();}
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Class<? extends BoundedWildcardsGenericMethods> clazz = BoundedWildcardsGenericMethods.class;
+
+ /**
+ * Tests that there are is one Type Parameter on the Class itself.
+ */
+ public void testBoundedGenericMethods() {
+ assertLenghtOne(clazz.getTypeParameters());
+ }
+
+ /**
+ * Tests whether the type parameter is bounded by BoundedGenericMethods like:
+ * <T extends BoundedGenericMethods>.
+ * @param method the declaring method
+ */
+ private void checkBoundedTypeParameter(Method method) {
+ TypeVariable<Method> typeParameter = getTypeParameter(method);
+ assertEquals("T", typeParameter.getName());
+ assertEquals(method, typeParameter.getGenericDeclaration());
+
+ Type[] bounds = typeParameter.getBounds();
+ assertLenghtOne(bounds);
+ Type bound = bounds[0];
+ assertEquals(BoundedWildcardsGenericMethods.class, bound);
+ }
+
+ private void checkLowerBoundedParameter(Method method) {
+ Type genericParameterType = method.getGenericParameterTypes()[0];
+ assertInstanceOf(ParameterizedType.class, genericParameterType);
+
+ ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
+
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ assertLenghtOne(actualTypeArguments);
+ assertInstanceOf(WildcardType.class, actualTypeArguments[0]);
+
+ WildcardType wildcardType = (WildcardType) actualTypeArguments[0];
+
+ Type[] lowerBounds = wildcardType.getLowerBounds();
+ assertLenghtOne(lowerBounds);
+ Type lowerBound = lowerBounds[0];
+ assertEquals(getTypeParameter(method), lowerBound);
+
+ Type[] upperBounds = wildcardType.getUpperBounds();
+ assertEquals(Object.class, upperBounds[0]);
+ }
+
+ private void checkUpperBoundedParameter(Method method) {
+ assertLenghtOne(method.getGenericParameterTypes());
+ Type genericParameterType = method.getGenericParameterTypes()[0];
+ assertInstanceOf(ParameterizedType.class, genericParameterType);
+
+ ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ assertLenghtOne(actualTypeArguments);
+ assertInstanceOf(WildcardType.class, actualTypeArguments[0]);
+
+ WildcardType wildcardType = (WildcardType) actualTypeArguments[0];
+ assertLenghtZero(wildcardType.getLowerBounds());
+
+ Type[] upperBounds = wildcardType.getUpperBounds();
+ assertLenghtOne(upperBounds);
+ Type upperBound = upperBounds[0];
+ assertEquals(getTypeParameter(method), upperBound);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void checkReturnType(Method method) {
+ Type genericReturnType = method.getGenericReturnType();
+ assertEquals(getTypeParameter(method), genericReturnType);
+ assertTrue(genericReturnType instanceof TypeVariable);
+
+ TypeVariable<Method> returnTypeVariable = (TypeVariable<Method>) genericReturnType;
+ assertEquals(method, returnTypeVariable.getGenericDeclaration());
+
+ Type[] bounds = returnTypeVariable.getBounds();
+ assertLenghtOne(bounds);
+ Type bound = bounds[0];
+
+ assertEquals(BoundedWildcardsGenericMethods.class, bound);
+ }
+
+ public void testUpperBoundedParamNoReturn() throws Exception {
+ Method method = clazz.getMethod("upperBoundedParamNoReturn", BoundedWildcardsGenericMethods.class);
+ checkBoundedTypeParameter(method);
+ checkUpperBoundedParameter(method);
+ }
+
+ public void testLowerBoundedParamReturn() throws Exception {
+ Method method = clazz.getMethod("lowerBoundedParamReturn", BoundedWildcardsGenericMethods.class);
+ checkBoundedTypeParameter(method);
+ checkLowerBoundedParameter(method);
+ checkReturnType(method);
+ }
+
+ public void testUpperBoundedParamReturn() throws Exception {
+ Method method = clazz.getMethod("upperBoundedParamReturn", BoundedWildcardsGenericMethods.class);
+ checkBoundedTypeParameter(method);
+ checkUpperBoundedParameter(method);
+ checkReturnType(method);
+ }
+
+ public void testLowerBoundedParamNoReturn() throws Exception {
+ Method method = clazz.getMethod("lowerBoundedParamNoReturn", BoundedWildcardsGenericMethods.class);
+ checkBoundedTypeParameter(method);
+ assertLenghtOne(method.getGenericParameterTypes());
+ checkLowerBoundedParameter(method);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java
new file mode 100644
index 0000000..20e9237
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java
@@ -0,0 +1,952 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.math;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.math.RoundingMode;
+
+
+public class BigDecimalTest extends junit.framework.TestCase {
+ BigInteger value = new BigInteger("12345908");
+
+ BigInteger value2 = new BigInteger("12334560000");
+
+ /**
+ * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger)
+ */
+ public void test_ConstructorLjava_math_BigInteger() {
+ BigDecimal big = new BigDecimal(value);
+ assertTrue("the BigDecimal value is not initialized properly", big
+ .unscaledValue().equals(value)
+ && big.scale() == 0);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger, int)
+ */
+ public void test_ConstructorLjava_math_BigIntegerI() {
+ BigDecimal big = new BigDecimal(value2, 5);
+ assertTrue("the BigDecimal value is not initialized properly", big
+ .unscaledValue().equals(value2)
+ && big.scale() == 5);
+ assertTrue("the BigDecimal value is not represented properly", big
+ .toString().equals("123345.60000"));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#BigDecimal(double)
+ */
+ public void test_ConstructorD() {
+ BigDecimal big = new BigDecimal(123E04);
+ assertTrue(
+ "the BigDecimal value taking a double argument is not initialized properly",
+ big.toString().equals("1230000"));
+ big = new BigDecimal(1.2345E-12);
+ assertTrue("the double representation is not correct", big
+ .doubleValue() == 1.2345E-12);
+ big = new BigDecimal(-12345E-3);
+ assertTrue("the double representation is not correct", big
+ .doubleValue() == -12.345);
+ big = new BigDecimal(5.1234567897654321e138);
+ assertTrue("the double representation is not correct", big
+ .doubleValue() == 5.1234567897654321E138
+ && big.scale() == 0);
+ big = new BigDecimal(0.1);
+ assertTrue(
+ "the double representation of 0.1 bigDecimal is not correct",
+ big.doubleValue() == 0.1);
+ big = new BigDecimal(0.00345);
+ assertTrue(
+ "the double representation of 0.00345 bigDecimal is not correct",
+ big.doubleValue() == 0.00345);
+ // regression test for HARMONY-2429
+ big = new BigDecimal(-0.0);
+ assertTrue(
+ "the double representation of -0.0 bigDecimal is not correct",
+ big.scale() == 0);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws NumberFormatException {
+ BigDecimal big = new BigDecimal("345.23499600293850");
+ assertTrue("the BigDecimal value is not initialized properly", big
+ .toString().equals("345.23499600293850")
+ && big.scale() == 14);
+ big = new BigDecimal("-12345");
+ assertTrue("the BigDecimal value is not initialized properly", big
+ .toString().equals("-12345")
+ && big.scale() == 0);
+ big = new BigDecimal("123.");
+ assertTrue("the BigDecimal value is not initialized properly", big
+ .toString().equals("123")
+ && big.scale() == 0);
+
+ new BigDecimal("1.234E02");
+ }
+
+ /**
+ * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
+ */
+ public void test_constructor_String_plus_exp() {
+ /*
+ * BigDecimal does not support a + sign in the exponent when converting
+ * from a String
+ */
+ new BigDecimal(+23e-0);
+ new BigDecimal(-23e+0);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
+ */
+ public void test_constructor_String_empty() {
+ try {
+ new BigDecimal("");
+ fail("NumberFormatException expected");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
+ */
+ public void test_constructor_String_plus_minus_exp() {
+ try {
+ new BigDecimal("+35e+-2");
+ fail("NumberFormatException expected");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new BigDecimal("-35e-+2");
+ fail("NumberFormatException expected");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigDecimal#BigDecimal(char[])
+ */
+ public void test_constructor_CC_plus_minus_exp() {
+ try {
+ new BigDecimal("+35e+-2".toCharArray());
+ fail("NumberFormatException expected");
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ new BigDecimal("-35e-+2".toCharArray());
+ fail("NumberFormatException expected");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigDecimal#abs()
+ */
+ public void test_abs() {
+ BigDecimal big = new BigDecimal("-1234");
+ BigDecimal bigabs = big.abs();
+ assertTrue("the absolute value of -1234 is not 1234", bigabs.toString()
+ .equals("1234"));
+ big = new BigDecimal(new BigInteger("2345"), 2);
+ bigabs = big.abs();
+ assertTrue("the absolute value of 23.45 is not 23.45", bigabs
+ .toString().equals("23.45"));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#add(java.math.BigDecimal)
+ */
+ public void test_addLjava_math_BigDecimal() {
+ BigDecimal add1 = new BigDecimal("23.456");
+ BigDecimal add2 = new BigDecimal("3849.235");
+ BigDecimal sum = add1.add(add2);
+ assertTrue("the sum of 23.456 + 3849.235 is wrong", sum.unscaledValue()
+ .toString().equals("3872691")
+ && sum.scale() == 3);
+ assertTrue("the sum of 23.456 + 3849.235 is not printed correctly", sum
+ .toString().equals("3872.691"));
+ BigDecimal add3 = new BigDecimal(12.34E02D);
+ assertTrue("the sum of 23.456 + 12.34E02 is not printed correctly",
+ (add1.add(add3)).toString().equals("1257.456"));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#compareTo(java.math.BigDecimal)
+ */
+ public void test_compareToLjava_math_BigDecimal() {
+ BigDecimal comp1 = new BigDecimal("1.00");
+ BigDecimal comp2 = new BigDecimal(1.000000D);
+ assertTrue("1.00 and 1.000000 should be equal",
+ comp1.compareTo(comp2) == 0);
+ BigDecimal comp3 = new BigDecimal("1.02");
+ assertTrue("1.02 should be bigger than 1.00",
+ comp3.compareTo(comp1) == 1);
+ BigDecimal comp4 = new BigDecimal(0.98D);
+ assertTrue("0.98 should be less than 1.00",
+ comp4.compareTo(comp1) == -1);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#divide(java.math.BigDecimal, int)
+ */
+ public void test_divideLjava_math_BigDecimalI() {
+ BigDecimal divd1 = new BigDecimal(value, 2);
+ BigDecimal divd2 = new BigDecimal("2.335");
+ BigDecimal divd3 = divd1.divide(divd2, BigDecimal.ROUND_UP);
+ assertTrue("123459.08/2.335 is not correct", divd3.toString().equals(
+ "52873.27")
+ && divd3.scale() == divd1.scale());
+ assertTrue(
+ "the unscaledValue representation of 123459.08/2.335 is not correct",
+ divd3.unscaledValue().toString().equals("5287327"));
+ divd2 = new BigDecimal(123.4D);
+ divd3 = divd1.divide(divd2, BigDecimal.ROUND_DOWN);
+ assertTrue("123459.08/123.4 is not correct", divd3.toString().equals(
+ "1000.47")
+ && divd3.scale() == 2);
+ divd2 = new BigDecimal(000D);
+
+ try {
+ divd1.divide(divd2, BigDecimal.ROUND_DOWN);
+ fail("divide by zero is not caught");
+ } catch (ArithmeticException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigDecimal#divide(java.math.BigDecimal, int, int)
+ */
+ public void test_divideLjava_math_BigDecimalII() {
+ BigDecimal divd1 = new BigDecimal(value2, 4);
+ BigDecimal divd2 = new BigDecimal("0.0023");
+ BigDecimal divd3 = divd1.divide(divd2, 3, BigDecimal.ROUND_HALF_UP);
+ assertTrue("1233456/0.0023 is not correct", divd3.toString().equals(
+ "536285217.391")
+ && divd3.scale() == 3);
+ divd2 = new BigDecimal(1345.5E-02D);
+ divd3 = divd1.divide(divd2, 0, BigDecimal.ROUND_DOWN);
+ assertTrue(
+ "1233456/13.455 is not correct or does not have the correct scale",
+ divd3.toString().equals("91672") && divd3.scale() == 0);
+ divd2 = new BigDecimal(0000D);
+
+ try {
+ divd1.divide(divd2, 4, BigDecimal.ROUND_DOWN);
+ fail("divide by zero is not caught");
+ } catch (ArithmeticException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigDecimal#doubleValue()
+ */
+ public void test_doubleValue() {
+ BigDecimal bigDB = new BigDecimal(-1.234E-112);
+// Commenting out this part because it causes an endless loop (see HARMONY-319 and HARMONY-329)
+// assertTrue(
+// "the double representation of this BigDecimal is not correct",
+// bigDB.doubleValue() == -1.234E-112);
+ bigDB = new BigDecimal(5.00E-324);
+ assertTrue("the double representation of bigDecimal is not correct",
+ bigDB.doubleValue() == 5.00E-324);
+ bigDB = new BigDecimal(1.79E308);
+ assertTrue("the double representation of bigDecimal is not correct",
+ bigDB.doubleValue() == 1.79E308 && bigDB.scale() == 0);
+ bigDB = new BigDecimal(-2.33E102);
+ assertTrue(
+ "the double representation of bigDecimal -2.33E102 is not correct",
+ bigDB.doubleValue() == -2.33E102 && bigDB.scale() == 0);
+ bigDB = new BigDecimal(Double.MAX_VALUE);
+ bigDB = bigDB.add(bigDB);
+ assertTrue(
+ "a + number out of the double range should return infinity",
+ bigDB.doubleValue() == Double.POSITIVE_INFINITY);
+ bigDB = new BigDecimal(-Double.MAX_VALUE);
+ bigDB = bigDB.add(bigDB);
+ assertTrue(
+ "a - number out of the double range should return neg infinity",
+ bigDB.doubleValue() == Double.NEGATIVE_INFINITY);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ BigDecimal equal1 = new BigDecimal(1.00D);
+ BigDecimal equal2 = new BigDecimal("1.0");
+ assertFalse("1.00 and 1.0 should not be equal",
+ equal1.equals(equal2));
+ equal2 = new BigDecimal(1.01D);
+ assertFalse("1.00 and 1.01 should not be equal",
+ equal1.equals(equal2));
+ equal2 = new BigDecimal("1.00");
+ assertFalse("1.00D and 1.00 should not be equal",
+ equal1.equals(equal2));
+ BigInteger val = new BigInteger("100");
+ equal1 = new BigDecimal("1.00");
+ equal2 = new BigDecimal(val, 2);
+ assertTrue("1.00(string) and 1.00(bigInteger) should be equal", equal1
+ .equals(equal2));
+ equal1 = new BigDecimal(100D);
+ equal2 = new BigDecimal("2.34576");
+ assertFalse("100D and 2.34576 should not be equal", equal1
+ .equals(equal2));
+ assertFalse("bigDecimal 100D does not equal string 23415", equal1
+ .equals("23415"));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#floatValue()
+ */
+ public void test_floatValue() {
+ BigDecimal fl1 = new BigDecimal("234563782344567");
+ assertTrue("the float representation of bigDecimal 234563782344567",
+ fl1.floatValue() == 234563782344567f);
+ BigDecimal fl2 = new BigDecimal(2.345E37);
+ assertTrue("the float representation of bigDecimal 2.345E37", fl2
+ .floatValue() == 2.345E37F);
+ fl2 = new BigDecimal(-1.00E-44);
+ assertTrue("the float representation of bigDecimal -1.00E-44", fl2
+ .floatValue() == -1.00E-44F);
+ fl2 = new BigDecimal(-3E12);
+ assertTrue("the float representation of bigDecimal -3E12", fl2
+ .floatValue() == -3E12F);
+ fl2 = new BigDecimal(Double.MAX_VALUE);
+ assertTrue(
+ "A number can't be represented by float should return infinity",
+ fl2.floatValue() == Float.POSITIVE_INFINITY);
+ fl2 = new BigDecimal(-Double.MAX_VALUE);
+ assertTrue(
+ "A number can't be represented by float should return infinity",
+ fl2.floatValue() == Float.NEGATIVE_INFINITY);
+
+ }
+
+ /**
+ * @tests java.math.BigDecimal#hashCode()
+ */
+ public void test_hashCode() {
+ // anything that is equal must have the same hashCode
+ BigDecimal hash = new BigDecimal("1.00");
+ BigDecimal hash2 = new BigDecimal(1.00D);
+ assertTrue("the hashCode of 1.00 and 1.00D is equal",
+ hash.hashCode() != hash2.hashCode() && !hash.equals(hash2));
+ hash2 = new BigDecimal("1.0");
+ assertTrue("the hashCode of 1.0 and 1.00 is equal",
+ hash.hashCode() != hash2.hashCode() && !hash.equals(hash2));
+ BigInteger val = new BigInteger("100");
+ hash2 = new BigDecimal(val, 2);
+ assertTrue("hashCode of 1.00 and 1.00(bigInteger) is not equal", hash
+ .hashCode() == hash2.hashCode()
+ && hash.equals(hash2));
+ hash = new BigDecimal(value, 2);
+ hash2 = new BigDecimal("-1233456.0000");
+ assertTrue("hashCode of 123459.08 and -1233456.0000 is not equal", hash
+ .hashCode() != hash2.hashCode()
+ && !hash.equals(hash2));
+ hash2 = new BigDecimal(value.negate(), 2);
+ assertTrue("hashCode of 123459.08 and -123459.08 is not equal", hash
+ .hashCode() != hash2.hashCode()
+ && !hash.equals(hash2));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#intValue()
+ */
+ public void test_intValue() {
+ BigDecimal int1 = new BigDecimal(value, 3);
+ assertTrue("the int value of 12345.908 is not 12345",
+ int1.intValue() == 12345);
+ int1 = new BigDecimal("1.99");
+ assertTrue("the int value of 1.99 is not 1", int1.intValue() == 1);
+ int1 = new BigDecimal("23423419083091823091283933");
+ // ran JDK and found representation for the above was -249268259
+ assertTrue("the int value of 23423419083091823091283933 is wrong", int1
+ .intValue() == -249268259);
+ int1 = new BigDecimal(-1235D);
+ assertTrue("the int value of -1235 is not -1235",
+ int1.intValue() == -1235);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#longValue()
+ */
+ public void test_longValue() {
+ BigDecimal long1 = new BigDecimal(value2.negate(), 0);
+ assertTrue("the long value of 12334560000 is not 12334560000", long1
+ .longValue() == -12334560000L);
+ long1 = new BigDecimal(-1345.348E-123D);
+ assertTrue("the long value of -1345.348E-123D is not zero", long1
+ .longValue() == 0);
+ long1 = new BigDecimal("31323423423419083091823091283933");
+ // ran JDK and found representation for the above was
+ // -5251313250005125155
+ assertTrue(
+ "the long value of 31323423423419083091823091283933 is wrong",
+ long1.longValue() == -5251313250005125155L);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#max(java.math.BigDecimal)
+ */
+ public void test_maxLjava_math_BigDecimal() {
+ BigDecimal max1 = new BigDecimal(value2, 1);
+ BigDecimal max2 = new BigDecimal(value2, 4);
+ assertTrue("1233456000.0 is not greater than 1233456", max1.max(max2)
+ .equals(max1));
+ max1 = new BigDecimal(-1.224D);
+ max2 = new BigDecimal(-1.2245D);
+ assertTrue("-1.224 is not greater than -1.2245", max1.max(max2).equals(
+ max1));
+ max1 = new BigDecimal(123E18);
+ max2 = new BigDecimal(123E19);
+ assertTrue("123E19 is the not the max", max1.max(max2).equals(max2));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#min(java.math.BigDecimal)
+ */
+ public void test_minLjava_math_BigDecimal() {
+ BigDecimal min1 = new BigDecimal(-12345.4D);
+ BigDecimal min2 = new BigDecimal(-12345.39D);
+ assertTrue("-12345.39 should have been returned", min1.min(min2)
+ .equals(min1));
+ min1 = new BigDecimal(value2, 5);
+ min2 = new BigDecimal(value2, 0);
+ assertTrue("123345.6 should have been returned", min1.min(min2).equals(
+ min1));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#movePointLeft(int)
+ */
+ public void test_movePointLeftI() {
+ BigDecimal movePtLeft = new BigDecimal("123456265.34");
+ BigDecimal alreadyMoved = movePtLeft.movePointLeft(5);
+ assertTrue("move point left 5 failed", alreadyMoved.scale() == 7
+ && alreadyMoved.toString().equals("1234.5626534"));
+ movePtLeft = new BigDecimal(value2.negate(), 0);
+ alreadyMoved = movePtLeft.movePointLeft(12);
+ assertTrue("move point left 12 failed", alreadyMoved.scale() == 12
+ && alreadyMoved.toString().equals("-0.012334560000"));
+ movePtLeft = new BigDecimal(123E18);
+ alreadyMoved = movePtLeft.movePointLeft(2);
+ assertTrue("move point left 2 failed",
+ alreadyMoved.scale() == movePtLeft.scale() + 2
+ && alreadyMoved.doubleValue() == 1.23E18);
+ movePtLeft = new BigDecimal(1.123E-12);
+ alreadyMoved = movePtLeft.movePointLeft(3);
+ assertTrue("move point left 3 failed",
+ alreadyMoved.scale() == movePtLeft.scale() + 3
+ && alreadyMoved.doubleValue() == 1.123E-15);
+ movePtLeft = new BigDecimal(value, 2);
+ alreadyMoved = movePtLeft.movePointLeft(-2);
+ assertTrue("move point left -2 failed",
+ alreadyMoved.scale() == movePtLeft.scale() - 2
+ && alreadyMoved.toString().equals("12345908"));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#movePointRight(int)
+ */
+ public void test_movePointRightI() {
+ BigDecimal movePtRight = new BigDecimal("-1.58796521458");
+ BigDecimal alreadyMoved = movePtRight.movePointRight(8);
+ assertTrue("move point right 8 failed", alreadyMoved.scale() == 3
+ && alreadyMoved.toString().equals("-158796521.458"));
+ movePtRight = new BigDecimal(value, 2);
+ alreadyMoved = movePtRight.movePointRight(4);
+ assertTrue("move point right 4 failed", alreadyMoved.scale() == 0
+ && alreadyMoved.toString().equals("1234590800"));
+ movePtRight = new BigDecimal(134E12);
+ alreadyMoved = movePtRight.movePointRight(2);
+ assertTrue("move point right 2 failed", alreadyMoved.scale() == 0
+ && alreadyMoved.toString().equals("13400000000000000"));
+ movePtRight = new BigDecimal(-3.4E-10);
+ alreadyMoved = movePtRight.movePointRight(5);
+ assertTrue("move point right 5 failed",
+ alreadyMoved.scale() == movePtRight.scale() - 5
+ && alreadyMoved.doubleValue() == -0.000034);
+ alreadyMoved = alreadyMoved.movePointRight(-5);
+ assertTrue("move point right -5 failed", alreadyMoved
+ .equals(movePtRight));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#multiply(java.math.BigDecimal)
+ */
+ public void test_multiplyLjava_math_BigDecimal() {
+ BigDecimal multi1 = new BigDecimal(value, 5);
+ BigDecimal multi2 = new BigDecimal(2.345D);
+ BigDecimal result = multi1.multiply(multi2);
+ assertTrue("123.45908 * 2.345 is not correct: " + result, result
+ .toString().startsWith("289.51154260")
+ && result.scale() == multi1.scale() + multi2.scale());
+ multi1 = new BigDecimal("34656");
+ multi2 = new BigDecimal("-2");
+ result = multi1.multiply(multi2);
+ assertTrue("34656 * 2 is not correct", result.toString().equals(
+ "-69312")
+ && result.scale() == 0);
+ multi1 = new BigDecimal(-2.345E-02);
+ multi2 = new BigDecimal(-134E130);
+ result = multi1.multiply(multi2);
+ assertTrue("-2.345E-02 * -134E130 is not correct " + result.doubleValue(),
+ result.doubleValue() == 3.1422999999999997E130
+ && result.scale() == multi1.scale() + multi2.scale());
+ multi1 = new BigDecimal("11235");
+ multi2 = new BigDecimal("0");
+ result = multi1.multiply(multi2);
+ assertTrue("11235 * 0 is not correct", result.doubleValue() == 0
+ && result.scale() == 0);
+ multi1 = new BigDecimal("-0.00234");
+ multi2 = new BigDecimal(13.4E10);
+ result = multi1.multiply(multi2);
+ assertTrue("-0.00234 * 13.4E10 is not correct",
+ result.doubleValue() == -313560000
+ && result.scale() == multi1.scale() + multi2.scale());
+ }
+
+ /**
+ * @tests java.math.BigDecimal#negate()
+ */
+ public void test_negate() {
+ BigDecimal negate1 = new BigDecimal(value2, 7);
+ assertTrue("the negate of 1233.4560000 is not -1233.4560000", negate1
+ .negate().toString().equals("-1233.4560000"));
+ negate1 = new BigDecimal("-23465839");
+ assertTrue("the negate of -23465839 is not 23465839", negate1.negate()
+ .toString().equals("23465839"));
+ negate1 = new BigDecimal(-3.456E6);
+ assertTrue("the negate of -3.456E6 is not 3.456E6", negate1.negate()
+ .negate().equals(negate1));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#scale()
+ */
+ public void test_scale() {
+ BigDecimal scale1 = new BigDecimal(value2, 8);
+ assertTrue("the scale of the number 123.34560000 is wrong", scale1
+ .scale() == 8);
+ BigDecimal scale2 = new BigDecimal("29389.");
+ assertTrue("the scale of the number 29389. is wrong",
+ scale2.scale() == 0);
+ BigDecimal scale3 = new BigDecimal(3.374E13);
+ assertTrue("the scale of the number 3.374E13 is wrong",
+ scale3.scale() == 0);
+ BigDecimal scale4 = new BigDecimal("-3.45E-203");
+ // note the scale is calculated as 15 digits of 345000.... + exponent -
+ // 1. -1 for the 3
+ assertTrue("the scale of the number -3.45E-203 is wrong: "
+ + scale4.scale(), scale4.scale() == 205);
+ scale4 = new BigDecimal("-345.4E-200");
+ assertTrue("the scale of the number -345.4E-200 is wrong", scale4
+ .scale() == 201);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#setScale(int)
+ */
+ public void test_setScaleI() {
+ // rounding mode defaults to zero
+ BigDecimal setScale1 = new BigDecimal(value, 3);
+ BigDecimal setScale2 = setScale1.setScale(5);
+ BigInteger setresult = new BigInteger("1234590800");
+ assertTrue("the number 12345.908 after setting scale is wrong",
+ setScale2.unscaledValue().equals(setresult)
+ && setScale2.scale() == 5);
+
+ try {
+ setScale2 = setScale1.setScale(2, BigDecimal.ROUND_UNNECESSARY);
+ fail("arithmetic Exception not caught as a result of loosing precision");
+ } catch (ArithmeticException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigDecimal#setScale(int, int)
+ */
+ public void test_setScaleII() {
+ BigDecimal setScale1 = new BigDecimal(2.323E102);
+ BigDecimal setScale2 = setScale1.setScale(4);
+ assertTrue("the number 2.323E102 after setting scale is wrong",
+ setScale2.scale() == 4);
+ assertTrue("the representation of the number 2.323E102 is wrong",
+ setScale2.doubleValue() == 2.323E102);
+ setScale1 = new BigDecimal("-1.253E-12");
+ setScale2 = setScale1.setScale(17, BigDecimal.ROUND_CEILING);
+ assertTrue("the number -1.253E-12 after setting scale is wrong",
+ setScale2.scale() == 17);
+ assertTrue(
+ "the representation of the number -1.253E-12 after setting scale is wrong, " + setScale2.toString(),
+ setScale2.toString().equals("-1.25300E-12"));
+
+ // testing rounding Mode ROUND_CEILING
+ setScale1 = new BigDecimal(value, 4);
+ setScale2 = setScale1.setScale(1, BigDecimal.ROUND_CEILING);
+ assertTrue(
+ "the number 1234.5908 after setting scale to 1/ROUND_CEILING is wrong",
+ setScale2.toString().equals("1234.6") && setScale2.scale() == 1);
+ BigDecimal setNeg = new BigDecimal(value.negate(), 4);
+ setScale2 = setNeg.setScale(1, BigDecimal.ROUND_CEILING);
+ assertTrue(
+ "the number -1234.5908 after setting scale to 1/ROUND_CEILING is wrong",
+ setScale2.toString().equals("-1234.5")
+ && setScale2.scale() == 1);
+
+ // testing rounding Mode ROUND_DOWN
+ setScale2 = setNeg.setScale(1, BigDecimal.ROUND_DOWN);
+ assertTrue(
+ "the number -1234.5908 after setting scale to 1/ROUND_DOWN is wrong",
+ setScale2.toString().equals("-1234.5")
+ && setScale2.scale() == 1);
+ setScale1 = new BigDecimal(value, 4);
+ setScale2 = setScale1.setScale(1, BigDecimal.ROUND_DOWN);
+ assertTrue(
+ "the number 1234.5908 after setting scale to 1/ROUND_DOWN is wrong",
+ setScale2.toString().equals("1234.5") && setScale2.scale() == 1);
+
+ // testing rounding Mode ROUND_FLOOR
+ setScale2 = setScale1.setScale(1, BigDecimal.ROUND_FLOOR);
+ assertTrue(
+ "the number 1234.5908 after setting scale to 1/ROUND_FLOOR is wrong",
+ setScale2.toString().equals("1234.5") && setScale2.scale() == 1);
+ setScale2 = setNeg.setScale(1, BigDecimal.ROUND_FLOOR);
+ assertTrue(
+ "the number -1234.5908 after setting scale to 1/ROUND_FLOOR is wrong",
+ setScale2.toString().equals("-1234.6")
+ && setScale2.scale() == 1);
+
+ // testing rounding Mode ROUND_HALF_DOWN
+ setScale2 = setScale1.setScale(3, BigDecimal.ROUND_HALF_DOWN);
+ assertTrue(
+ "the number 1234.5908 after setting scale to 3/ROUND_HALF_DOWN is wrong",
+ setScale2.toString().equals("1234.591")
+ && setScale2.scale() == 3);
+ setScale1 = new BigDecimal(new BigInteger("12345000"), 5);
+ setScale2 = setScale1.setScale(1, BigDecimal.ROUND_HALF_DOWN);
+ assertTrue(
+ "the number 123.45908 after setting scale to 1/ROUND_HALF_DOWN is wrong",
+ setScale2.toString().equals("123.4") && setScale2.scale() == 1);
+ setScale2 = new BigDecimal("-1234.5000").setScale(0,
+ BigDecimal.ROUND_HALF_DOWN);
+ assertTrue(
+ "the number -1234.5908 after setting scale to 0/ROUND_HALF_DOWN is wrong",
+ setScale2.toString().equals("-1234") && setScale2.scale() == 0);
+
+ // testing rounding Mode ROUND_HALF_EVEN
+ setScale1 = new BigDecimal(1.2345789D);
+ setScale2 = setScale1.setScale(4, BigDecimal.ROUND_HALF_EVEN);
+ assertTrue(
+ "the number 1.2345789 after setting scale to 4/ROUND_HALF_EVEN is wrong",
+ setScale2.doubleValue() == 1.2346D && setScale2.scale() == 4);
+ setNeg = new BigDecimal(-1.2335789D);
+ setScale2 = setNeg.setScale(2, BigDecimal.ROUND_HALF_EVEN);
+ assertTrue(
+ "the number -1.2335789 after setting scale to 2/ROUND_HALF_EVEN is wrong",
+ setScale2.doubleValue() == -1.23D && setScale2.scale() == 2);
+ setScale2 = new BigDecimal("1.2345000").setScale(3,
+ BigDecimal.ROUND_HALF_EVEN);
+ assertTrue(
+ "the number 1.2345789 after setting scale to 3/ROUND_HALF_EVEN is wrong",
+ setScale2.doubleValue() == 1.234D && setScale2.scale() == 3);
+ setScale2 = new BigDecimal("-1.2345000").setScale(3,
+ BigDecimal.ROUND_HALF_EVEN);
+ assertTrue(
+ "the number -1.2335789 after setting scale to 3/ROUND_HALF_EVEN is wrong",
+ setScale2.doubleValue() == -1.234D && setScale2.scale() == 3);
+
+ // testing rounding Mode ROUND_HALF_UP
+ setScale1 = new BigDecimal("134567.34650");
+ setScale2 = setScale1.setScale(3, BigDecimal.ROUND_HALF_UP);
+ assertTrue(
+ "the number 134567.34658 after setting scale to 3/ROUND_HALF_UP is wrong",
+ setScale2.toString().equals("134567.347")
+ && setScale2.scale() == 3);
+ setNeg = new BigDecimal("-1234.4567");
+ setScale2 = setNeg.setScale(0, BigDecimal.ROUND_HALF_UP);
+ assertTrue(
+ "the number -1234.4567 after setting scale to 0/ROUND_HALF_UP is wrong",
+ setScale2.toString().equals("-1234") && setScale2.scale() == 0);
+
+ // testing rounding Mode ROUND_UNNECESSARY
+ try {
+ setScale1.setScale(3, BigDecimal.ROUND_UNNECESSARY);
+ fail("arithmetic Exception not caught for round unnecessary");
+ } catch (ArithmeticException e) {
+ }
+
+ // testing rounding Mode ROUND_UP
+ setScale1 = new BigDecimal("100000.374");
+ setScale2 = setScale1.setScale(2, BigDecimal.ROUND_UP);
+ assertTrue(
+ "the number 100000.374 after setting scale to 2/ROUND_UP is wrong",
+ setScale2.toString().equals("100000.38")
+ && setScale2.scale() == 2);
+ setNeg = new BigDecimal(-134.34589D);
+ setScale2 = setNeg.setScale(2, BigDecimal.ROUND_UP);
+ assertTrue(
+ "the number -134.34589 after setting scale to 2/ROUND_UP is wrong",
+ setScale2.doubleValue() == -134.35D && setScale2.scale() == 2);
+
+ // testing invalid rounding modes
+ try {
+ setScale2 = setScale1.setScale(0, -123);
+ fail("IllegalArgumentException is not caught for wrong rounding mode");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigDecimal#signum()
+ */
+ public void test_signum() {
+ BigDecimal sign = new BigDecimal(123E-104);
+ assertTrue("123E-104 is not positive in signum()", sign.signum() == 1);
+ sign = new BigDecimal("-1234.3959");
+ assertTrue("-1234.3959 is not negative in signum()",
+ sign.signum() == -1);
+ sign = new BigDecimal(000D);
+ assertTrue("000D is not zero in signum()", sign.signum() == 0);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#subtract(java.math.BigDecimal)
+ */
+ public void test_subtractLjava_math_BigDecimal() {
+ BigDecimal sub1 = new BigDecimal("13948");
+ BigDecimal sub2 = new BigDecimal("2839.489");
+ BigDecimal result = sub1.subtract(sub2);
+ assertTrue("13948 - 2839.489 is wrong: " + result, result.toString()
+ .equals("11108.511")
+ && result.scale() == 3);
+ BigDecimal result2 = sub2.subtract(sub1);
+ assertTrue("2839.489 - 13948 is wrong", result2.toString().equals(
+ "-11108.511")
+ && result2.scale() == 3);
+ assertTrue("13948 - 2839.489 is not the negative of 2839.489 - 13948",
+ result.equals(result2.negate()));
+ sub1 = new BigDecimal(value, 1);
+ sub2 = new BigDecimal("0");
+ result = sub1.subtract(sub2);
+ assertTrue("1234590.8 - 0 is wrong", result.equals(sub1));
+ sub1 = new BigDecimal(1.234E-03);
+ sub2 = new BigDecimal(3.423E-10);
+ result = sub1.subtract(sub2);
+ assertTrue("1.234E-03 - 3.423E-10 is wrong, " + result.doubleValue(),
+ result.doubleValue() == 0.0012339996577);
+ sub1 = new BigDecimal(1234.0123);
+ sub2 = new BigDecimal(1234.0123000);
+ result = sub1.subtract(sub2);
+ assertTrue("1234.0123 - 1234.0123000 is wrong, " + result.doubleValue(),
+ result.doubleValue() == 0.0);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#toBigInteger()
+ */
+ public void test_toBigInteger() {
+ BigDecimal sub1 = new BigDecimal("-29830.989");
+ BigInteger result = sub1.toBigInteger();
+
+ assertTrue("the bigInteger equivalent of -29830.989 is wrong", result
+ .toString().equals("-29830"));
+ sub1 = new BigDecimal(-2837E10);
+ result = sub1.toBigInteger();
+ assertTrue("the bigInteger equivalent of -2837E10 is wrong", result
+ .doubleValue() == -2837E10);
+ sub1 = new BigDecimal(2.349E-10);
+ result = sub1.toBigInteger();
+ assertTrue("the bigInteger equivalent of 2.349E-10 is wrong", result
+ .equals(BigInteger.ZERO));
+ sub1 = new BigDecimal(value2, 6);
+ result = sub1.toBigInteger();
+ assertTrue("the bigInteger equivalent of 12334.560000 is wrong", result
+ .toString().equals("12334"));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#toString()
+ */
+ public void test_toString() {
+ BigDecimal toString1 = new BigDecimal("1234.000");
+ assertTrue("the toString representation of 1234.000 is wrong",
+ toString1.toString().equals("1234.000"));
+ toString1 = new BigDecimal("-123.4E-5");
+ assertTrue("the toString representation of -123.4E-5 is wrong: "
+ + toString1, toString1.toString().equals("-0.001234"));
+ toString1 = new BigDecimal("-1.455E-20");
+ assertTrue("the toString representation of -1.455E-20 is wrong",
+ toString1.toString().equals("-1.455E-20"));
+ toString1 = new BigDecimal(value2, 4);
+ assertTrue("the toString representation of 1233456.0000 is wrong",
+ toString1.toString().equals("1233456.0000"));
+ }
+
+ /**
+ * @tests java.math.BigDecimal#unscaledValue()
+ */
+ public void test_unscaledValue() {
+ BigDecimal unsVal = new BigDecimal("-2839485.000");
+ assertTrue("the unscaledValue of -2839485.000 is wrong", unsVal
+ .unscaledValue().toString().equals("-2839485000"));
+ unsVal = new BigDecimal(123E10);
+ assertTrue("the unscaledValue of 123E10 is wrong", unsVal
+ .unscaledValue().toString().equals("1230000000000"));
+ unsVal = new BigDecimal("-4.56E-13");
+ assertTrue("the unscaledValue of -4.56E-13 is wrong: "
+ + unsVal.unscaledValue(), unsVal.unscaledValue().toString()
+ .equals("-456"));
+ unsVal = new BigDecimal(value, 3);
+ assertTrue("the unscaledValue of 12345.908 is wrong", unsVal
+ .unscaledValue().toString().equals("12345908"));
+
+ }
+
+ /**
+ * @tests java.math.BigDecimal#valueOf(long)
+ */
+ public void test_valueOfJ() {
+ BigDecimal valueOfL = BigDecimal.valueOf(9223372036854775806L);
+ assertTrue("the bigDecimal equivalent of 9223372036854775806 is wrong",
+ valueOfL.unscaledValue().toString().equals(
+ "9223372036854775806")
+ && valueOfL.scale() == 0);
+ assertTrue(
+ "the toString representation of 9223372036854775806 is wrong",
+ valueOfL.toString().equals("9223372036854775806"));
+ valueOfL = BigDecimal.valueOf(0L);
+ assertTrue("the bigDecimal equivalent of 0 is wrong", valueOfL
+ .unscaledValue().toString().equals("0")
+ && valueOfL.scale() == 0);
+ }
+
+ /**
+ * @tests java.math.BigDecimal#valueOf(long, int)
+ */
+ public void test_valueOfJI() {
+ BigDecimal valueOfJI = BigDecimal.valueOf(9223372036854775806L, 5);
+ assertTrue(
+ "the bigDecimal equivalent of 92233720368547.75806 is wrong",
+ valueOfJI.unscaledValue().toString().equals(
+ "9223372036854775806")
+ && valueOfJI.scale() == 5);
+ assertTrue(
+ "the toString representation of 9223372036854775806 is wrong",
+ valueOfJI.toString().equals("92233720368547.75806"));
+ valueOfJI = BigDecimal.valueOf(1234L, 8);
+ assertTrue(
+ "the bigDecimal equivalent of 92233720368547.75806 is wrong",
+ valueOfJI.unscaledValue().toString().equals("1234")
+ && valueOfJI.scale() == 8);
+ assertTrue(
+ "the toString representation of 9223372036854775806 is wrong",
+ valueOfJI.toString().equals("0.00001234"));
+ valueOfJI = BigDecimal.valueOf(0, 3);
+ assertTrue(
+ "the bigDecimal equivalent of 92233720368547.75806 is wrong",
+ valueOfJI.unscaledValue().toString().equals("0")
+ && valueOfJI.scale() == 3);
+ assertTrue(
+ "the toString representation of 9223372036854775806 is wrong",
+ valueOfJI.toString().equals("0.000"));
+
+ }
+
+ public void test_BigDecimal_serialization() throws Exception {
+ // Regression for HARMONY-1896
+ char[] in = { '1', '5', '6', '7', '8', '7', '.', '0', '0' };
+ BigDecimal bd = new BigDecimal(in, 0, 9);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(bd);
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bis);
+ BigDecimal nbd = (BigDecimal) ois.readObject();
+
+ assertEquals(bd.intValue(), nbd.intValue());
+ assertEquals(bd.doubleValue(), nbd.doubleValue(), 0.0);
+ assertEquals(bd.toString(), nbd.toString());
+ }
+
+ /**
+ * @tests java.math.BigDecimal#stripTrailingZero(long)
+ */
+ public void test_stripTrailingZero() {
+ BigDecimal sixhundredtest = new BigDecimal("600.0");
+ assertTrue("stripTrailingZero failed for 600.0",
+ ((sixhundredtest.stripTrailingZeros()).scale() == -2)
+ );
+
+ /* Single digit, no trailing zero, odd number */
+ BigDecimal notrailingzerotest = new BigDecimal("1");
+ assertTrue("stripTrailingZero failed for 1",
+ ((notrailingzerotest.stripTrailingZeros()).scale() == 0)
+ );
+
+ // BEGIN android-changed: preserve RI compatibility, so BigDecimal.equals (which checks
+ // value *and* scale) continues to work. https://issues.apache.org/jira/browse/HARMONY-4623
+ /* Zero */
+ BigDecimal zerotest = new BigDecimal("0.0000");
+ assertEquals("stripTrailingZero failed for 0.0000", 4, zerotest.stripTrailingZeros().scale());
+ }
+
+ public void testMathContextConstruction() {
+ String a = "-12380945E+61";
+ BigDecimal aNumber = new BigDecimal(a);
+ int precision = 6;
+ RoundingMode rm = RoundingMode.HALF_DOWN;
+ MathContext mcIntRm = new MathContext(precision, rm);
+ MathContext mcStr = new MathContext("precision=6 roundingMode=HALF_DOWN");
+ MathContext mcInt = new MathContext(precision);
+ BigDecimal res = aNumber.abs(mcInt);
+ assertEquals("MathContext Constructer with int precision failed",
+ res,
+ new BigDecimal("1.23809E+68"));
+
+ assertEquals("Equal MathContexts are not Equal ",
+ mcIntRm,
+ mcStr);
+
+ assertEquals("Different MathContext are reported as Equal ",
+ mcInt.equals(mcStr),
+ false);
+
+ assertEquals("Equal MathContexts have different hashcodes ",
+ mcIntRm.hashCode(),
+ mcStr.hashCode());
+
+ assertEquals("MathContext.toString() returning incorrect value",
+ mcIntRm.toString(),
+ "precision=6 roundingMode=HALF_DOWN");
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java
new file mode 100644
index 0000000..337e7c4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java
@@ -0,0 +1,988 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.math;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+public class BigIntegerTest extends junit.framework.TestCase {
+
+ BigInteger minusTwo = new BigInteger("-2", 10);
+
+ BigInteger minusOne = new BigInteger("-1", 10);
+
+ BigInteger zero = new BigInteger("0", 10);
+
+ BigInteger one = new BigInteger("1", 10);
+
+ BigInteger two = new BigInteger("2", 10);
+
+ BigInteger ten = new BigInteger("10", 10);
+
+ BigInteger sixteen = new BigInteger("16", 10);
+
+ BigInteger oneThousand = new BigInteger("1000", 10);
+
+ BigInteger aZillion = new BigInteger(
+ "100000000000000000000000000000000000000000000000000", 10);
+
+ BigInteger twoToTheTen = new BigInteger("1024", 10);
+
+ BigInteger twoToTheSeventy = two.pow(70);
+
+ Random rand = new Random();
+
+ BigInteger bi;
+
+ BigInteger bi1;
+
+ BigInteger bi2;
+
+ BigInteger bi3;
+
+ BigInteger bi11;
+
+ BigInteger bi22;
+
+ BigInteger bi33;
+
+ BigInteger bi12;
+
+ BigInteger bi23;
+
+ BigInteger bi13;
+
+ BigInteger largePos;
+
+ BigInteger smallPos;
+
+ BigInteger largeNeg;
+
+ BigInteger smallNeg;
+
+ BigInteger[][] booleanPairs;
+
+ /**
+ * @tests java.math.BigInteger#BigInteger(int, java.util.Random)
+ */
+ public void test_ConstructorILjava_util_Random() {
+ // regression test for HARMONY-1047
+ try {
+ new BigInteger(Integer.MAX_VALUE, (Random)null);
+ fail("NegativeArraySizeException expected");
+ } catch (NegativeArraySizeException e) {
+ // PASSED
+ }
+
+ bi = new BigInteger(70, rand);
+ bi2 = new BigInteger(70, rand);
+ assertTrue("Random number is negative", bi.compareTo(zero) >= 0);
+ assertTrue("Random number is too big",
+ bi.compareTo(twoToTheSeventy) < 0);
+ assertTrue(
+ "Two random numbers in a row are the same (might not be a bug but it very likely is)",
+ !bi.equals(bi2));
+ assertTrue("Not zero", new BigInteger(0, rand).equals(BigInteger.ZERO));
+ }
+
+ /**
+ * @tests java.math.BigInteger#BigInteger(byte[])
+ */
+ public void test_Constructor$B() {
+ byte[] myByteArray;
+ myByteArray = new byte[] { (byte) 0x00, (byte) 0xFF, (byte) 0xFE };
+ bi = new BigInteger(myByteArray);
+ assertTrue("Incorrect value for pos number", bi.equals(BigInteger.ZERO
+ .setBit(16).subtract(two)));
+ myByteArray = new byte[] { (byte) 0xFF, (byte) 0xFE };
+ bi = new BigInteger(myByteArray);
+ assertTrue("Incorrect value for neg number", bi.equals(minusTwo));
+ }
+
+ /**
+ * @tests java.math.BigInteger#BigInteger(int, byte[])
+ */
+ public void test_ConstructorI$B() {
+ byte[] myByteArray;
+ myByteArray = new byte[] { (byte) 0xFF, (byte) 0xFE };
+ bi = new BigInteger(1, myByteArray);
+ assertTrue("Incorrect value for pos number", bi.equals(BigInteger.ZERO
+ .setBit(16).subtract(two)));
+ bi = new BigInteger(-1, myByteArray);
+ assertTrue("Incorrect value for neg number", bi.equals(BigInteger.ZERO
+ .setBit(16).subtract(two).negate()));
+ myByteArray = new byte[] { (byte) 0, (byte) 0 };
+ bi = new BigInteger(0, myByteArray);
+ assertTrue("Incorrect value for zero", bi.equals(zero));
+ myByteArray = new byte[] { (byte) 1 };
+ try {
+ new BigInteger(0, myByteArray);
+ fail("Failed to throw NumberFormatException");
+ } catch (NumberFormatException e) {
+ // correct
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#BigInteger(java.lang.String)
+ */
+ public void test_constructor_String_empty() {
+ try {
+ new BigInteger("");
+ fail("Expected NumberFormatException for new BigInteger(\"\")");
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#toByteArray()
+ */
+ public void test_toByteArray() {
+ byte[] myByteArray, anotherByteArray;
+ myByteArray = new byte[] { 97, 33, 120, 124, 50, 2, 0, 0, 0, 12, 124,
+ 42 };
+ anotherByteArray = new BigInteger(myByteArray).toByteArray();
+ assertTrue("Incorrect byte array returned",
+ myByteArray.length == anotherByteArray.length);
+ for (int counter = myByteArray.length - 1; counter >= 0; counter--) {
+ assertTrue("Incorrect values in returned byte array",
+ myByteArray[counter] == anotherByteArray[counter]);
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#isProbablePrime(int)
+ */
+ public void test_isProbablePrimeI() {
+ int fails = 0;
+ bi = new BigInteger(20, 20, rand);
+ if (!bi.isProbablePrime(17)) {
+ fails++;
+ }
+ bi = new BigInteger("4", 10);
+ if (bi.isProbablePrime(17)) {
+ fail("isProbablePrime failed for: " + bi);
+ }
+ bi = BigInteger.valueOf(17L * 13L);
+ if (bi.isProbablePrime(17)) {
+ fail("isProbablePrime failed for: " + bi);
+ }
+ for (long a = 2; a < 1000; a++) {
+ if (isPrime(a)) {
+ assertTrue("false negative on prime number <1000", BigInteger
+ .valueOf(a).isProbablePrime(5));
+ } else if (BigInteger.valueOf(a).isProbablePrime(17)) {
+ System.out.println("isProbablePrime failed for: " + a);
+ fails++;
+ }
+ }
+ for (int a = 0; a < 1000; a++) {
+ bi = BigInteger.valueOf(rand.nextInt(1000000)).multiply(
+ BigInteger.valueOf(rand.nextInt(1000000)));
+ if (bi.isProbablePrime(17)) {
+ System.out.println("isProbablePrime failed for: " + bi);
+ fails++;
+ }
+ }
+ for (int a = 0; a < 200; a++) {
+ bi = new BigInteger(70, rand).multiply(new BigInteger(70, rand));
+ if (bi.isProbablePrime(17)) {
+ System.out.println("isProbablePrime failed for: " + bi);
+ fails++;
+ }
+ }
+ assertTrue("Too many false positives - may indicate a problem",
+ fails <= 1);
+ }
+
+ /**
+ * @tests java.math.BigInteger#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertTrue("0=0", zero.equals(BigInteger.valueOf(0)));
+ assertTrue("-123=-123", BigInteger.valueOf(-123).equals(
+ BigInteger.valueOf(-123)));
+ assertTrue("0=1", !zero.equals(one));
+ assertTrue("0=-1", !zero.equals(minusOne));
+ assertTrue("1=-1", !one.equals(minusOne));
+ assertTrue("bi3=bi3", bi3.equals(bi3));
+ assertTrue("bi3=copy of bi3", bi3.equals(bi3.negate().negate()));
+ assertTrue("bi3=bi2", !bi3.equals(bi2));
+ }
+
+ /**
+ * @tests java.math.BigInteger#compareTo(java.math.BigInteger)
+ */
+ public void test_compareToLjava_math_BigInteger() {
+ assertTrue("Smaller number returned >= 0", one.compareTo(two) < 0);
+ assertTrue("Larger number returned >= 0", two.compareTo(one) > 0);
+ assertTrue("Equal numbers did not return 0", one.compareTo(one) == 0);
+ assertTrue("Neg number messed things up",
+ two.negate().compareTo(one) < 0);
+ }
+
+ /**
+ * @tests java.math.BigInteger#intValue()
+ */
+ public void test_intValue() {
+ assertTrue("Incorrect intValue for 2**70",
+ twoToTheSeventy.intValue() == 0);
+ assertTrue("Incorrect intValue for 2", two.intValue() == 2);
+ }
+
+ /**
+ * @tests java.math.BigInteger#longValue()
+ */
+ public void test_longValue() {
+ assertTrue("Incorrect longValue for 2**70",
+ twoToTheSeventy.longValue() == 0);
+ assertTrue("Incorrect longValue for 2", two.longValue() == 2);
+ }
+
+ /**
+ * @tests java.math.BigInteger#valueOf(long)
+ */
+ public void test_valueOfJ() {
+ assertTrue("Incurred number returned for 2", BigInteger.valueOf(2L)
+ .equals(two));
+ assertTrue("Incurred number returned for 200", BigInteger.valueOf(200L)
+ .equals(BigInteger.valueOf(139).add(BigInteger.valueOf(61))));
+ }
+
+ /**
+ * @tests java.math.BigInteger#add(java.math.BigInteger)
+ */
+ public void test_addLjava_math_BigInteger() {
+ assertTrue("Incorrect sum--wanted a zillion", aZillion.add(aZillion)
+ .add(aZillion.negate()).equals(aZillion));
+ assertTrue("0+0", zero.add(zero).equals(zero));
+ assertTrue("0+1", zero.add(one).equals(one));
+ assertTrue("1+0", one.add(zero).equals(one));
+ assertTrue("1+1", one.add(one).equals(two));
+ assertTrue("0+(-1)", zero.add(minusOne).equals(minusOne));
+ assertTrue("(-1)+0", minusOne.add(zero).equals(minusOne));
+ assertTrue("(-1)+(-1)", minusOne.add(minusOne).equals(minusTwo));
+ assertTrue("1+(-1)", one.add(minusOne).equals(zero));
+ assertTrue("(-1)+1", minusOne.add(one).equals(zero));
+
+ for (int i = 0; i < 200; i++) {
+ BigInteger midbit = zero.setBit(i);
+ assertTrue("add fails to carry on bit " + i, midbit.add(midbit)
+ .equals(zero.setBit(i + 1)));
+ }
+ BigInteger bi2p3 = bi2.add(bi3);
+ BigInteger bi3p2 = bi3.add(bi2);
+ assertTrue("bi2p3=bi3p2", bi2p3.equals(bi3p2));
+
+ // add large positive + small positive
+
+ // add large positive + small negative
+
+ // add large negative + small positive
+
+ // add large negative + small negative
+ }
+
+ /**
+ * @tests java.math.BigInteger#negate()
+ */
+ public void test_negate() {
+ assertTrue("Single negation of zero did not result in zero", zero
+ .negate().equals(zero));
+ assertTrue("Single negation resulted in original nonzero number",
+ !aZillion.negate().equals(aZillion));
+ assertTrue("Double negation did not result in original number",
+ aZillion.negate().negate().equals(aZillion));
+
+ assertTrue("0.neg", zero.negate().equals(zero));
+ assertTrue("1.neg", one.negate().equals(minusOne));
+ assertTrue("2.neg", two.negate().equals(minusTwo));
+ assertTrue("-1.neg", minusOne.negate().equals(one));
+ assertTrue("-2.neg", minusTwo.negate().equals(two));
+ assertTrue("0x62EB40FEF85AA9EBL*2.neg", BigInteger.valueOf(
+ 0x62EB40FEF85AA9EBL * 2).negate().equals(
+ BigInteger.valueOf(-0x62EB40FEF85AA9EBL * 2)));
+ for (int i = 0; i < 200; i++) {
+ BigInteger midbit = zero.setBit(i);
+ BigInteger negate = midbit.negate();
+ assertTrue("negate negate", negate.negate().equals(midbit));
+ assertTrue("neg fails on bit " + i, midbit.negate().add(midbit)
+ .equals(zero));
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#signum()
+ */
+ public void test_signum() {
+ assertTrue("Wrong positive signum", two.signum() == 1);
+ assertTrue("Wrong zero signum", zero.signum() == 0);
+ assertTrue("Wrong neg zero signum", zero.negate().signum() == 0);
+ assertTrue("Wrong neg signum", two.negate().signum() == -1);
+ }
+
+ /**
+ * @tests java.math.BigInteger#abs()
+ */
+ public void test_abs() {
+ assertTrue("Invalid number returned for zillion", aZillion.negate()
+ .abs().equals(aZillion.abs()));
+ assertTrue("Invalid number returned for zero neg", zero.negate().abs()
+ .equals(zero));
+ assertTrue("Invalid number returned for zero", zero.abs().equals(zero));
+ assertTrue("Invalid number returned for two", two.negate().abs()
+ .equals(two));
+ }
+
+ /**
+ * @tests java.math.BigInteger#pow(int)
+ */
+ public void test_powI() {
+ assertTrue("Incorrect exponent returned for 2**10", two.pow(10).equals(
+ twoToTheTen));
+ assertTrue("Incorrect exponent returned for 2**70", two.pow(30)
+ .multiply(two.pow(40)).equals(twoToTheSeventy));
+ assertTrue("Incorrect exponent returned for 10**50", ten.pow(50)
+ .equals(aZillion));
+ }
+
+ /**
+ * @tests java.math.BigInteger#modInverse(java.math.BigInteger)
+ */
+ public void test_modInverseLjava_math_BigInteger() {
+ BigInteger a = zero, mod, inv;
+ for (int j = 3; j < 50; j++) {
+ mod = BigInteger.valueOf(j);
+ for (int i = -j + 1; i < j; i++) {
+ try {
+ a = BigInteger.valueOf(i);
+ inv = a.modInverse(mod);
+ assertTrue("bad inverse: " + a + " inv mod " + mod
+ + " equals " + inv, one.equals(a.multiply(inv).mod(
+ mod)));
+ assertTrue("inverse greater than modulo: " + a
+ + " inv mod " + mod + " equals " + inv, inv
+ .compareTo(mod) < 0);
+ assertTrue("inverse less than zero: " + a + " inv mod "
+ + mod + " equals " + inv, inv
+ .compareTo(BigInteger.ZERO) >= 0);
+ } catch (ArithmeticException e) {
+ assertTrue("should have found inverse for " + a + " mod "
+ + mod, !one.equals(a.gcd(mod)));
+ }
+ }
+ }
+ for (int j = 1; j < 10; j++) {
+ mod = bi2.add(BigInteger.valueOf(j));
+ for (int i = 0; i < 20; i++) {
+ try {
+ a = bi3.add(BigInteger.valueOf(i));
+ inv = a.modInverse(mod);
+ assertTrue("bad inverse: " + a + " inv mod " + mod
+ + " equals " + inv, one.equals(a.multiply(inv).mod(
+ mod)));
+ assertTrue("inverse greater than modulo: " + a
+ + " inv mod " + mod + " equals " + inv, inv
+ .compareTo(mod) < 0);
+ assertTrue("inverse less than zero: " + a + " inv mod "
+ + mod + " equals " + inv, inv
+ .compareTo(BigInteger.ZERO) >= 0);
+ } catch (ArithmeticException e) {
+ assertTrue("should have found inverse for " + a + " mod "
+ + mod, !one.equals(a.gcd(mod)));
+ }
+ }
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#shiftRight(int)
+ */
+ public void test_shiftRightI() {
+ assertTrue("1 >> 0", BigInteger.valueOf(1).shiftRight(0).equals(
+ BigInteger.ONE));
+ assertTrue("1 >> 1", BigInteger.valueOf(1).shiftRight(1).equals(
+ BigInteger.ZERO));
+ assertTrue("1 >> 63", BigInteger.valueOf(1).shiftRight(63).equals(
+ BigInteger.ZERO));
+ assertTrue("1 >> 64", BigInteger.valueOf(1).shiftRight(64).equals(
+ BigInteger.ZERO));
+ assertTrue("1 >> 65", BigInteger.valueOf(1).shiftRight(65).equals(
+ BigInteger.ZERO));
+ assertTrue("1 >> 1000", BigInteger.valueOf(1).shiftRight(1000).equals(
+ BigInteger.ZERO));
+ assertTrue("-1 >> 0", BigInteger.valueOf(-1).shiftRight(0).equals(
+ minusOne));
+ assertTrue("-1 >> 1", BigInteger.valueOf(-1).shiftRight(1).equals(
+ minusOne));
+ assertTrue("-1 >> 63", BigInteger.valueOf(-1).shiftRight(63).equals(
+ minusOne));
+ assertTrue("-1 >> 64", BigInteger.valueOf(-1).shiftRight(64).equals(
+ minusOne));
+ assertTrue("-1 >> 65", BigInteger.valueOf(-1).shiftRight(65).equals(
+ minusOne));
+ assertTrue("-1 >> 1000", BigInteger.valueOf(-1).shiftRight(1000)
+ .equals(minusOne));
+
+ BigInteger a = BigInteger.ONE;
+ BigInteger c = bi3;
+ BigInteger E = bi3.negate();
+ BigInteger e = E;
+ for (int i = 0; i < 200; i++) {
+ BigInteger b = BigInteger.ZERO.setBit(i);
+ assertTrue("a==b", a.equals(b));
+ a = a.shiftLeft(1);
+ assertTrue("a non-neg", a.signum() >= 0);
+
+ BigInteger d = bi3.shiftRight(i);
+ assertTrue("c==d", c.equals(d));
+ c = c.shiftRight(1);
+ assertTrue(">>1 == /2", d.divide(two).equals(c));
+ assertTrue("c non-neg", c.signum() >= 0);
+
+ BigInteger f = E.shiftRight(i);
+ assertTrue("e==f", e.equals(f));
+ e = e.shiftRight(1);
+ assertTrue(">>1 == /2", f.subtract(one).divide(two).equals(e));
+ assertTrue("e negative", e.signum() == -1);
+
+ assertTrue("b >> i", b.shiftRight(i).equals(one));
+ assertTrue("b >> i+1", b.shiftRight(i + 1).equals(zero));
+ assertTrue("b >> i-1", b.shiftRight(i - 1).equals(two));
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#shiftLeft(int)
+ */
+ public void test_shiftLeftI() {
+ assertTrue("1 << 0", one.shiftLeft(0).equals(one));
+ assertTrue("1 << 1", one.shiftLeft(1).equals(two));
+ assertTrue("1 << 63", one.shiftLeft(63).equals(
+ new BigInteger("8000000000000000", 16)));
+ assertTrue("1 << 64", one.shiftLeft(64).equals(
+ new BigInteger("10000000000000000", 16)));
+ assertTrue("1 << 65", one.shiftLeft(65).equals(
+ new BigInteger("20000000000000000", 16)));
+ assertTrue("-1 << 0", minusOne.shiftLeft(0).equals(minusOne));
+ assertTrue("-1 << 1", minusOne.shiftLeft(1).equals(minusTwo));
+ assertTrue("-1 << 63", minusOne.shiftLeft(63).equals(
+ new BigInteger("-9223372036854775808")));
+ assertTrue("-1 << 64", minusOne.shiftLeft(64).equals(
+ new BigInteger("-18446744073709551616")));
+ assertTrue("-1 << 65", minusOne.shiftLeft(65).equals(
+ new BigInteger("-36893488147419103232")));
+
+ BigInteger a = bi3;
+ BigInteger c = minusOne;
+ for (int i = 0; i < 200; i++) {
+ BigInteger b = bi3.shiftLeft(i);
+ assertTrue("a==b", a.equals(b));
+ assertTrue("a >> i == bi3", a.shiftRight(i).equals(bi3));
+ a = a.shiftLeft(1);
+ assertTrue("<<1 == *2", b.multiply(two).equals(a));
+ assertTrue("a non-neg", a.signum() >= 0);
+ assertTrue("a.bitCount==b.bitCount", a.bitCount() == b.bitCount());
+
+ BigInteger d = minusOne.shiftLeft(i);
+ assertTrue("c==d", c.equals(d));
+ c = c.shiftLeft(1);
+ assertTrue("<<1 == *2 negative", d.multiply(two).equals(c));
+ assertTrue("c negative", c.signum() == -1);
+ assertTrue("d >> i == minusOne", d.shiftRight(i).equals(minusOne));
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#multiply(java.math.BigInteger)
+ */
+ public void test_multiplyLjava_math_BigInteger() {
+ assertTrue("Incorrect sum--wanted three zillion", aZillion
+ .add(aZillion).add(aZillion).equals(
+ aZillion.multiply(new BigInteger("3", 10))));
+
+ assertTrue("0*0", zero.multiply(zero).equals(zero));
+ assertTrue("0*1", zero.multiply(one).equals(zero));
+ assertTrue("1*0", one.multiply(zero).equals(zero));
+ assertTrue("1*1", one.multiply(one).equals(one));
+ assertTrue("0*(-1)", zero.multiply(minusOne).equals(zero));
+ assertTrue("(-1)*0", minusOne.multiply(zero).equals(zero));
+ assertTrue("(-1)*(-1)", minusOne.multiply(minusOne).equals(one));
+ assertTrue("1*(-1)", one.multiply(minusOne).equals(minusOne));
+ assertTrue("(-1)*1", minusOne.multiply(one).equals(minusOne));
+
+ testAllMults(bi1, bi1, bi11);
+ testAllMults(bi2, bi2, bi22);
+ testAllMults(bi3, bi3, bi33);
+ testAllMults(bi1, bi2, bi12);
+ testAllMults(bi1, bi3, bi13);
+ testAllMults(bi2, bi3, bi23);
+ }
+
+ /**
+ * @tests java.math.BigInteger#divide(java.math.BigInteger)
+ */
+ public void test_divideLjava_math_BigInteger() {
+ testAllDivs(bi33, bi3);
+ testAllDivs(bi22, bi2);
+ testAllDivs(bi11, bi1);
+ testAllDivs(bi13, bi1);
+ testAllDivs(bi13, bi3);
+ testAllDivs(bi12, bi1);
+ testAllDivs(bi12, bi2);
+ testAllDivs(bi23, bi2);
+ testAllDivs(bi23, bi3);
+ testAllDivs(largePos, bi1);
+ testAllDivs(largePos, bi2);
+ testAllDivs(largePos, bi3);
+ testAllDivs(largeNeg, bi1);
+ testAllDivs(largeNeg, bi2);
+ testAllDivs(largeNeg, bi3);
+ testAllDivs(largeNeg, largePos);
+ testAllDivs(largePos, largeNeg);
+ testAllDivs(bi3, bi3);
+ testAllDivs(bi2, bi2);
+ testAllDivs(bi1, bi1);
+ testDivRanges(bi1);
+ testDivRanges(bi2);
+ testDivRanges(bi3);
+ testDivRanges(smallPos);
+ testDivRanges(largePos);
+ testDivRanges(new BigInteger("62EB40FEF85AA9EB", 16));
+ testAllDivs(BigInteger.valueOf(0xCC0225953CL), BigInteger
+ .valueOf(0x1B937B765L));
+
+ try {
+ largePos.divide(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ bi1.divide(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ bi3.negate().divide(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ zero.divide(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#remainder(java.math.BigInteger)
+ */
+ public void test_remainderLjava_math_BigInteger() {
+ try {
+ largePos.remainder(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ bi1.remainder(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ bi3.negate().remainder(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ zero.remainder(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#mod(java.math.BigInteger)
+ */
+ public void test_modLjava_math_BigInteger() {
+ try {
+ largePos.mod(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ bi1.mod(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ bi3.negate().mod(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ zero.mod(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#divideAndRemainder(java.math.BigInteger)
+ */
+ public void test_divideAndRemainderLjava_math_BigInteger() {
+ try {
+ largePos.divideAndRemainder(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ bi1.divideAndRemainder(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ bi3.negate().divideAndRemainder(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+
+ try {
+ zero.divideAndRemainder(zero);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#BigInteger(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ assertTrue("new(0)", new BigInteger("0").equals(BigInteger.valueOf(0)));
+ assertTrue("new(1)", new BigInteger("1").equals(BigInteger.valueOf(1)));
+ assertTrue("new(12345678901234)", new BigInteger("12345678901234")
+ .equals(BigInteger.valueOf(12345678901234L)));
+ assertTrue("new(-1)", new BigInteger("-1").equals(BigInteger
+ .valueOf(-1)));
+ assertTrue("new(-12345678901234)", new BigInteger("-12345678901234")
+ .equals(BigInteger.valueOf(-12345678901234L)));
+ }
+
+ /**
+ * @tests java.math.BigInteger#BigInteger(java.lang.String, int)
+ */
+ public void test_ConstructorLjava_lang_StringI() {
+ assertTrue("new(0,16)", new BigInteger("0", 16).equals(BigInteger
+ .valueOf(0)));
+ assertTrue("new(1,16)", new BigInteger("1", 16).equals(BigInteger
+ .valueOf(1)));
+ assertTrue("new(ABF345678901234,16)", new BigInteger("ABF345678901234",
+ 16).equals(BigInteger.valueOf(0xABF345678901234L)));
+ assertTrue("new(abf345678901234,16)", new BigInteger("abf345678901234",
+ 16).equals(BigInteger.valueOf(0xABF345678901234L)));
+ assertTrue("new(-1,16)", new BigInteger("-1", 16).equals(BigInteger
+ .valueOf(-1)));
+ assertTrue("new(-ABF345678901234,16)", new BigInteger(
+ "-ABF345678901234", 16).equals(BigInteger
+ .valueOf(-0xABF345678901234L)));
+ assertTrue("new(-abf345678901234,16)", new BigInteger(
+ "-abf345678901234", 16).equals(BigInteger
+ .valueOf(-0xABF345678901234L)));
+ assertTrue("new(-101010101,2)", new BigInteger("-101010101", 2)
+ .equals(BigInteger.valueOf(-341)));
+ }
+
+ /**
+ * @tests java.math.BigInteger#toString()
+ */
+ public void test_toString() {
+ assertTrue("0.toString", "0".equals(BigInteger.valueOf(0).toString()));
+ assertTrue("1.toString", "1".equals(BigInteger.valueOf(1).toString()));
+ assertTrue("12345678901234.toString", "12345678901234"
+ .equals(BigInteger.valueOf(12345678901234L).toString()));
+ assertTrue("-1.toString", "-1"
+ .equals(BigInteger.valueOf(-1).toString()));
+ assertTrue("-12345678901234.toString", "-12345678901234"
+ .equals(BigInteger.valueOf(-12345678901234L).toString()));
+ }
+
+ /**
+ * @tests java.math.BigInteger#toString(int)
+ */
+ public void test_toStringI() {
+ assertTrue("0.toString(16)", "0".equals(BigInteger.valueOf(0).toString(
+ 16)));
+ assertTrue("1.toString(16)", "1".equals(BigInteger.valueOf(1).toString(
+ 16)));
+ assertTrue("ABF345678901234.toString(16)", "abf345678901234"
+ .equals(BigInteger.valueOf(0xABF345678901234L).toString(16)));
+ assertTrue("-1.toString(16)", "-1".equals(BigInteger.valueOf(-1)
+ .toString(16)));
+ assertTrue("-ABF345678901234.toString(16)", "-abf345678901234"
+ .equals(BigInteger.valueOf(-0xABF345678901234L).toString(16)));
+ assertTrue("-101010101.toString(2)", "-101010101".equals(BigInteger
+ .valueOf(-341).toString(2)));
+ }
+
+ /**
+ * @tests java.math.BigInteger#and(java.math.BigInteger)
+ */
+ public void test_andLjava_math_BigInteger() {
+ for (BigInteger[] element : booleanPairs) {
+ BigInteger i1 = element[0], i2 = element[1];
+ BigInteger res = i1.and(i2);
+ assertTrue("symmetry of and", res.equals(i2.and(i1)));
+ int len = Math.max(i1.bitLength(), i2.bitLength()) + 66;
+ for (int i = 0; i < len; i++) {
+ assertTrue("and", (i1.testBit(i) && i2.testBit(i)) == res
+ .testBit(i));
+ }
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#or(java.math.BigInteger)
+ */
+ public void test_orLjava_math_BigInteger() {
+ for (BigInteger[] element : booleanPairs) {
+ BigInteger i1 = element[0], i2 = element[1];
+ BigInteger res = i1.or(i2);
+ assertTrue("symmetry of or", res.equals(i2.or(i1)));
+ int len = Math.max(i1.bitLength(), i2.bitLength()) + 66;
+ for (int i = 0; i < len; i++) {
+ assertTrue("or", (i1.testBit(i) || i2.testBit(i)) == res
+ .testBit(i));
+ }
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#xor(java.math.BigInteger)
+ */
+ public void test_xorLjava_math_BigInteger() {
+ for (BigInteger[] element : booleanPairs) {
+ BigInteger i1 = element[0], i2 = element[1];
+ BigInteger res = i1.xor(i2);
+ assertTrue("symmetry of xor", res.equals(i2.xor(i1)));
+ int len = Math.max(i1.bitLength(), i2.bitLength()) + 66;
+ for (int i = 0; i < len; i++) {
+ assertTrue("xor", (i1.testBit(i) ^ i2.testBit(i)) == res
+ .testBit(i));
+ }
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#not()
+ */
+ public void test_not() {
+ for (BigInteger[] element : booleanPairs) {
+ BigInteger i1 = element[0];
+ BigInteger res = i1.not();
+ int len = i1.bitLength() + 66;
+ for (int i = 0; i < len; i++) {
+ assertTrue("not", !i1.testBit(i) == res.testBit(i));
+ }
+ }
+ }
+
+ /**
+ * @tests java.math.BigInteger#andNot(java.math.BigInteger)
+ */
+ public void test_andNotLjava_math_BigInteger() {
+ for (BigInteger[] element : booleanPairs) {
+ BigInteger i1 = element[0], i2 = element[1];
+ BigInteger res = i1.andNot(i2);
+ int len = Math.max(i1.bitLength(), i2.bitLength()) + 66;
+ for (int i = 0; i < len; i++) {
+ assertTrue("andNot", (i1.testBit(i) && !i2.testBit(i)) == res
+ .testBit(i));
+ }
+ // asymmetrical
+ i1 = element[1];
+ i2 = element[0];
+ res = i1.andNot(i2);
+ for (int i = 0; i < len; i++) {
+ assertTrue("andNot reversed",
+ (i1.testBit(i) && !i2.testBit(i)) == res.testBit(i));
+ }
+ }
+ //regression for HARMONY-4653
+ try{
+ BigInteger.ZERO.andNot(null);
+ fail("should throw NPE");
+ }catch(Exception e){
+ //expected
+ }
+ BigInteger bi = new BigInteger(0, new byte[]{});
+ assertEquals(BigInteger.ZERO, bi.andNot(BigInteger.ZERO));
+ }
+
+
+ public void testClone() {
+ // Regression test for HARMONY-1770
+ MyBigInteger myBigInteger = new MyBigInteger("12345");
+ myBigInteger = (MyBigInteger) myBigInteger.clone();
+ }
+
+ static class MyBigInteger extends BigInteger implements Cloneable {
+ public MyBigInteger(String val) {
+ super(val);
+ }
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+ }
+
+ @Override
+ protected void setUp() {
+ bi1 = new BigInteger("2436798324768978", 16);
+ bi2 = new BigInteger("4576829475724387584378543764555", 16);
+ bi3 = new BigInteger("43987298363278574365732645872643587624387563245",
+ 16);
+
+ bi33 = new BigInteger(
+ "10730846694701319120609898625733976090865327544790136667944805934175543888691400559249041094474885347922769807001",
+ 10);
+ bi22 = new BigInteger(
+ "33301606932171509517158059487795669025817912852219962782230629632224456249",
+ 10);
+ bi11 = new BigInteger("6809003003832961306048761258711296064", 10);
+ bi23 = new BigInteger(
+ "597791300268191573513888045771594235932809890963138840086083595706565695943160293610527214057",
+ 10);
+ bi13 = new BigInteger(
+ "270307912162948508387666703213038600031041043966215279482940731158968434008",
+ 10);
+ bi12 = new BigInteger(
+ "15058244971895641717453176477697767050482947161656458456", 10);
+
+ largePos = new BigInteger(
+ "834759814379857314986743298675687569845986736578576375675678998612743867438632986243982098437620983476924376",
+ 16);
+ smallPos = new BigInteger("48753269875973284765874598630960986276", 16);
+ largeNeg = new BigInteger(
+ "-878824397432651481891353247987891423768534321387864361143548364457698487264387568743568743265873246576467643756437657436587436",
+ 16);
+ smallNeg = new BigInteger("-567863254343798609857456273458769843", 16);
+ booleanPairs = new BigInteger[][] { { largePos, smallPos },
+ { largePos, smallNeg }, { largeNeg, smallPos },
+ { largeNeg, smallNeg } };
+ }
+
+ private void testDiv(BigInteger i1, BigInteger i2) {
+ BigInteger q = i1.divide(i2);
+ BigInteger r = i1.remainder(i2);
+ BigInteger[] temp = i1.divideAndRemainder(i2);
+
+ assertTrue("divide and divideAndRemainder do not agree", q
+ .equals(temp[0]));
+ assertTrue("remainder and divideAndRemainder do not agree", r
+ .equals(temp[1]));
+ assertTrue("signum and equals(zero) do not agree on quotient", q
+ .signum() != 0
+ || q.equals(zero));
+ assertTrue("signum and equals(zero) do not agree on remainder", r
+ .signum() != 0
+ || r.equals(zero));
+ assertTrue("wrong sign on quotient", q.signum() == 0
+ || q.signum() == i1.signum() * i2.signum());
+ assertTrue("wrong sign on remainder", r.signum() == 0
+ || r.signum() == i1.signum());
+ assertTrue("remainder out of range", r.abs().compareTo(i2.abs()) < 0);
+ assertTrue("quotient too small", q.abs().add(one).multiply(i2.abs())
+ .compareTo(i1.abs()) > 0);
+ assertTrue("quotient too large", q.abs().multiply(i2.abs()).compareTo(
+ i1.abs()) <= 0);
+ BigInteger p = q.multiply(i2);
+ BigInteger a = p.add(r);
+ assertTrue("(a/b)*b+(a%b) != a", a.equals(i1));
+ try {
+ BigInteger mod = i1.mod(i2);
+ assertTrue("mod is negative", mod.signum() >= 0);
+ assertTrue("mod out of range", mod.abs().compareTo(i2.abs()) < 0);
+ assertTrue("positive remainder == mod", r.signum() < 0
+ || r.equals(mod));
+ assertTrue("negative remainder == mod - divisor", r.signum() >= 0
+ || r.equals(mod.subtract(i2)));
+ } catch (ArithmeticException e) {
+ assertTrue("mod fails on negative divisor only", i2.signum() <= 0);
+ }
+ }
+
+ private void testDivRanges(BigInteger i) {
+ BigInteger bound = i.multiply(two);
+ for (BigInteger j = bound.negate(); j.compareTo(bound) <= 0; j = j
+ .add(i)) {
+ BigInteger innerbound = j.add(two);
+ BigInteger k = j.subtract(two);
+ for (; k.compareTo(innerbound) <= 0; k = k.add(one)) {
+ testDiv(k, i);
+ }
+ }
+ }
+
+ private boolean isPrime(long b) {
+ if (b == 2) {
+ return true;
+ }
+ // check for div by 2
+ if ((b & 1L) == 0) {
+ return false;
+ }
+ long maxlen = ((long) Math.sqrt(b)) + 2;
+ for (long x = 3; x < maxlen; x += 2) {
+ if (b % x == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void testAllMults(BigInteger i1, BigInteger i2, BigInteger ans) {
+ assertTrue("i1*i2=ans", i1.multiply(i2).equals(ans));
+ assertTrue("i2*i1=ans", i2.multiply(i1).equals(ans));
+ assertTrue("-i1*i2=-ans", i1.negate().multiply(i2).equals(ans.negate()));
+ assertTrue("-i2*i1=-ans", i2.negate().multiply(i1).equals(ans.negate()));
+ assertTrue("i1*-i2=-ans", i1.multiply(i2.negate()).equals(ans.negate()));
+ assertTrue("i2*-i1=-ans", i2.multiply(i1.negate()).equals(ans.negate()));
+ assertTrue("-i1*-i2=ans", i1.negate().multiply(i2.negate()).equals(ans));
+ assertTrue("-i2*-i1=ans", i2.negate().multiply(i1.negate()).equals(ans));
+ }
+
+ private void testAllDivs(BigInteger i1, BigInteger i2) {
+ testDiv(i1, i2);
+ testDiv(i1.negate(), i2);
+ testDiv(i1, i2.negate());
+ testDiv(i1.negate(), i2.negate());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/MathContextTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/MathContextTest.java
new file mode 100644
index 0000000..d9942d3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/MathContextTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.math;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
+
+public class MathContextTest extends junit.framework.TestCase {
+
+ /**
+ * java.math.MathContext#MathContext(...)
+ */
+ public void test_MathContextConstruction() {
+ String a = "-12380945E+61";
+ BigDecimal aNumber = new BigDecimal(a);
+ MathContext mcIntRm6hd = new MathContext(6, RoundingMode.HALF_DOWN);
+ MathContext mcStr6hd = new MathContext("precision=6 roundingMode=HALF_DOWN");
+ MathContext mcInt6 = new MathContext(6);
+ MathContext mcInt134 = new MathContext(134);
+
+ // getPrecision()
+ assertEquals("MathContext.getPrecision() returns incorrect value",
+ 6, mcIntRm6hd.getPrecision() );
+ assertEquals("MathContext.getPrecision() returns incorrect value",
+ 134, mcInt134.getPrecision() );
+
+ // getRoundingMode()
+ assertEquals("MathContext.getRoundingMode() returns incorrect value",
+ RoundingMode.HALF_UP,
+ mcInt6.getRoundingMode());
+ assertEquals("MathContext.getRoundingMode() returns incorrect value",
+ RoundingMode.HALF_DOWN, mcIntRm6hd.getRoundingMode() );
+
+ // toString()
+ assertEquals("MathContext.toString() returning incorrect value",
+ "precision=6 roundingMode=HALF_DOWN", mcIntRm6hd.toString() );
+ assertEquals("MathContext.toString() returning incorrect value",
+ "precision=6 roundingMode=HALF_UP", mcInt6.toString() );
+
+ // equals(.)
+ assertEquals("Equal MathContexts are not equal ",
+ mcIntRm6hd, mcStr6hd );
+ assertFalse("Different MathContexts are reported as equal ",
+ mcInt6.equals(mcStr6hd) );
+ assertFalse("Different MathContexts are reported as equal ",
+ mcInt6.equals(mcInt134) );
+
+ // hashCode(.)
+ assertEquals("Equal MathContexts have different hashcodes ",
+ mcIntRm6hd.hashCode(), mcStr6hd.hashCode() );
+ assertFalse("Different MathContexts have equal hashcodes ",
+ mcInt6.hashCode() == mcStr6hd.hashCode() );
+ assertFalse("Different MathContexts have equal hashcodes ",
+ mcInt6.hashCode() == mcInt134.hashCode() );
+
+ // other:
+ BigDecimal res = aNumber.abs(mcInt6);
+ assertEquals("MathContext Constructor with int precision failed",
+ new BigDecimal("1.23809E+68"),
+ res);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/OldBigIntegerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/OldBigIntegerTest.java
new file mode 100644
index 0000000..7d1f1b4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/OldBigIntegerTest.java
@@ -0,0 +1,372 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.math;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+public class OldBigIntegerTest extends junit.framework.TestCase {
+
+ BigInteger minusOne = new BigInteger("-1", 10);
+
+ BigInteger two = new BigInteger("2", 10);
+
+ BigInteger aZillion = new BigInteger("100000000000000000000000000000000000000000000000000", 10);
+
+ Random rand = new Random();
+
+ BigInteger bi;
+
+ BigInteger bi2;
+
+ BigInteger bi3;
+
+ /**
+ * java.math.BigInteger#BigInteger(int, java.util.Random)
+ */
+ public void test_ConstructorILjava_util_Random() {
+ // regression test for HARMONY-1047
+ try {
+ new BigInteger(128, (Random) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ bi = new BigInteger(70, rand);
+ bi2 = new BigInteger(70, rand);
+ assertTrue("Random number is negative", bi.compareTo(BigInteger.ZERO) >= 0);
+ assertTrue("Random number is too big", bi.compareTo(two.pow(70)) < 0);
+ assertTrue(
+ "Two random numbers in a row are the same (might not be a bug but it very likely is)",
+ !bi.equals(bi2));
+ assertTrue("Not zero", new BigInteger(0, rand).equals(BigInteger.ZERO));
+
+ try {
+ new BigInteger(-1, (Random)null);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // PASSED
+ }
+ }
+
+ /**
+ * java.math.BigInteger#BigInteger(int, int, java.util.Random)
+ */
+ // BIGNUM returns no Primes smaller than 16 bits.
+ public void test_ConstructorIILjava_util_Random() {
+ BigInteger bi1 = new BigInteger(10, 5, rand);
+ BigInteger bi2 = new BigInteger(10, 5, rand);
+ assertTrue(bi1 + " is negative", bi1.compareTo(BigInteger.ZERO) >= 0);
+ assertTrue(bi1 + " is too big", bi1.compareTo(new BigInteger("1024", 10)) < 0);
+ assertTrue(bi2 + " is negative", bi2.compareTo(BigInteger.ZERO) >= 0);
+ assertTrue(bi2 + " is too big", bi2.compareTo(new BigInteger("1024", 10)) < 0);
+
+ Random rand = new Random();
+ BigInteger bi;
+ int certainty[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -2, -1 };
+ for (int i = 2; i <= 20; i++) {
+ for (int c = 0; c < certainty.length; c++) {
+ bi = new BigInteger(i, c, rand); // Create BigInteger
+ assertEquals(i, bi.bitLength());
+ }
+ }
+
+ try {
+ new BigInteger(1, 80, (Random)null);
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException expected) {
+ }
+
+ try {
+ new BigInteger(-1, (Random)null);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+// public void test_SpecialPrimes() {
+// System.out.println("test_SpecialPrimes");
+// final BigInteger TWO = BigInteger.valueOf(2);
+// BigInteger p, q;
+// for (;;) {
+// p = new BigInteger(1024, 23, new Random());
+// q = p.subtract(BigInteger.ONE).divide(TWO);
+// if (q.isProbablePrime(20)) {
+// System.out.println(q);
+// System.out.println(p);
+// break;
+// }
+// System.out.print(".");
+// }
+// fail("isProbablePrime failed for: " + bi);
+// }
+
+ /**
+ * java.math.BigInteger#isProbablePrime(int)
+ */
+ public void test_isProbablePrimeI() {
+ int fails = 0;
+ bi = new BigInteger(20, 20, rand);
+ if (!bi.isProbablePrime(17)) {
+ fails++;
+ }
+ bi = new BigInteger("4", 10);
+ if (bi.isProbablePrime(17)) {
+ fail("isProbablePrime failed for: " + bi);
+ }
+ bi = BigInteger.valueOf(17L * 13L);
+ if (bi.isProbablePrime(17)) {
+ fail("isProbablePrime failed for: " + bi);
+ }
+ for (long a = 2; a < 1000; a++) {
+ if (isPrime(a)) {
+ assertTrue("false negative on prime number <1000", BigInteger
+ .valueOf(a).isProbablePrime(5));
+ } else if (BigInteger.valueOf(a).isProbablePrime(17)) {
+ System.out.println("isProbablePrime failed for: " + a);
+ fails++;
+ }
+ }
+ for (int a = 0; a < 1000; a++) {
+ bi = BigInteger.valueOf(rand.nextInt(1000000)).multiply(
+ BigInteger.valueOf(rand.nextInt(1000000)));
+ if (bi.isProbablePrime(17)) {
+ System.out.println("isProbablePrime failed for: " + bi);
+ fails++;
+ }
+ }
+ for (int a = 0; a < 200; a++) {
+ bi = new BigInteger(70, rand).multiply(new BigInteger(70, rand));
+ if (bi.isProbablePrime(17)) {
+ System.out.println("isProbablePrime failed for: " + bi);
+ fails++;
+ }
+ }
+ assertTrue("Too many false positives - may indicate a problem",
+ fails <= 1);
+
+ //
+ // And now some tests on real big integers:
+ //
+ bi = new BigInteger("153890972191202256150310830154922163807316525358455215516067727076235016932726922093888770552128767458882963869421440585369743", 10);
+ if (!bi.isProbablePrime(80)) {
+ fail("isProbablePrime failed for: " + bi);
+ }
+ bi = new BigInteger("2090575416269141767246491983797422123741252476560371649798066134123893524014911825188890458270426076468664046568752890122415061377308817346303546688282957897504000216241497550243010257911214329646877810655164658470278901030511157372440751259674247310396158238588463284702737181653", 10);
+ if (!bi.isProbablePrime(80)) {
+ fail("isProbablePrime failed for: " + bi);
+ }
+ //
+ for (int bitLength = 100; bitLength <= 600; bitLength += 100) {
+ BigInteger a = BigInteger.probablePrime(bitLength, rand);
+ BigInteger b = BigInteger.probablePrime(bitLength, rand);
+ BigInteger c = a.multiply(b);
+ assertFalse("isProbablePrime failed for product of two large primes" +
+ a + " * " + b + " = " + c +
+ " (bitLength = " + bitLength + ")",
+ c.isProbablePrime(80) );
+ }
+ }
+
+ /**
+ * java.math.BigInteger#nextProbablePrime()
+ */
+ public void test_nextProbablePrime() {
+ largePrimesProduct(
+ new BigInteger("2537895984043447429238717358455377929009126353874925049325287329295635198252046158619999217453233889378619619008359011789"),
+ new BigInteger("1711501451602688337873833423534849678524059393231999670806585630179374689152366029939952735718718709436427337762082614710093"),
+ "4343612660706993434504106787562106084038357258130862545477481433639575850237346784798851102536616749334772541987502120552264920040629526028540204698334741815536099373917351194423681128374184971846099257056996626343051832131340568120612204287123"
+ );
+
+ largePrimesProduct(
+ new BigInteger("4617974730611208463200675282934641082129817404749925308887287017217158545765190433369842932770197341032031682222405074564586462802072184047198214312142847809259437477387527466762251087500170588962277514858557309036550499896961735701485020851"),
+ new BigInteger("4313158964405728158057980867015758419530142215799386331265837224051830838583266274443105715022196238165196727467066901495701708590167750818040112544031694506528759169669442493029999154074962566165293254671176670719518898684698255068313216294333"),
+ "19918059106734861363335842730108905466210762564765297409619920041621379008685530738918145604092111306972524565803236031571858280032420140331838737621152630780261815015157696362550138161774466814661069892975003440654998880587960037013294137372709096788892473385003457361736563927256562678181177287998121131179907762285048659075843995525830945659905573174849006768920618442371027575308854641789533211132313916836205357976988977849024687805212304038260207820679964201211309384057458137851"
+ );
+ }
+
+ static void largePrimesProduct(BigInteger a, BigInteger b, String c) {
+ BigInteger wp = a.multiply(b);
+ assertFalse("isProbablePrime failed for product of two large primes" +
+ a + " * " + b + " = " + c,
+ wp.isProbablePrime(80) );
+ BigInteger wpMinusOne = wp.subtract(BigInteger.ONE);
+ BigInteger next = wpMinusOne.nextProbablePrime();
+// System.out.println(c);
+// System.out.println(next);
+ assertTrue("nextProbablePrime returns wrong number: " + next +
+ "instead of expected: " + c,
+ next.toString().equals(c) );
+ }
+
+ /**
+ * java.math.BigInteger#probablePrime(int, java.util.Random)
+ */
+ public void test_probablePrime() {
+ for (int bitLength = 50; bitLength <= 1050; bitLength += 100) {
+ BigInteger a = BigInteger.probablePrime(bitLength, rand);
+ assertTrue("isProbablePrime(probablePrime()) failed for: " + bi,
+ a.isProbablePrime(80));
+// System.out.println(a);
+// BigInteger prime = a.nextProbablePrime();
+// System.out.print("Next Probable Prime is ");
+// System.out.println(prime);
+ }
+ }
+
+// BEGIN android-added
+// public void testModPowPerformance() {
+// Random rnd = new Random();
+// for (int i = 0; i < 10; i++) {
+// BigInteger a = new BigInteger(512, rnd);
+// BigInteger m = new BigInteger(1024, rnd);
+// BigInteger p = new BigInteger(256, rnd);
+// BigInteger mp = a.modPow(p, m);
+// System.out.println(mp);
+// }
+// }
+
+// shows factor 20 speed up (BIGNUM to Harmony Java):
+// public void testNextProbablePrime() {
+// Random rnd = new Random();
+// rnd.setSeed(0);
+// for (int i = 1; i <= 32; i += 1) {
+// BigInteger a = new BigInteger(i, rnd);
+// System.out.println(a);
+// BigInteger prime = a.nextProbablePrime();
+// System.out.print("Next Probable Prime is ");
+// System.out.println(prime);
+// }
+// for (int i = 1; i <= 32; i += 4) {
+// BigInteger a = new BigInteger(32 * i, rnd);
+// System.out.println(a);
+// BigInteger prime = a.nextProbablePrime();
+// System.out.print("Next Probable Prime is ");
+// System.out.println(prime);
+// }
+// }
+
+// shows factor 20 speed up (BIGNUM to Harmony Java):
+// shows that certainty 80 is "practically aquivalent" to certainty 100
+// public void testPrimeGenPerformance() {
+// Random rnd = new Random();
+// rnd.setSeed(0);
+// for (int i = 1; i <= 32; i +=8 ) {
+// BigInteger a = new BigInteger(32 * i, 80, rnd);
+// System.out.println(a);
+// System.out.println("Now testing it again:");
+// if (a.isProbablePrime(100)) {
+// System.out.println("************************ PASSED! **************************");
+// } else {
+// System.out.println("************************ FAILED!!! **************************");
+// System.out.println("************************ FAILED!!! **************************");
+// System.out.println("************************ FAILED!!! **************************");
+// System.out.println("************************ FAILED!!! **************************");
+// System.out.println("************************ FAILED!!! **************************");
+// System.out.println("************************ FAILED!!! **************************");
+// }
+// }
+// }
+// END android-added
+
+
+
+ /**
+ * java.math.BigInteger#add(java.math.BigInteger)
+ */
+ public void test_addLjava_math_BigInteger() {
+ assertTrue("Incorrect sum--wanted a zillion", aZillion.add(aZillion)
+ .add(aZillion.negate()).equals(aZillion));
+ assertTrue("0+0", BigInteger.ZERO.add(BigInteger.ZERO).equals(BigInteger.ZERO));
+ assertTrue("0+1", BigInteger.ZERO.add(BigInteger.ONE).equals(BigInteger.ONE));
+ assertTrue("1+0", BigInteger.ONE.add(BigInteger.ZERO).equals(BigInteger.ONE));
+ assertTrue("1+1", BigInteger.ONE.add(BigInteger.ONE).equals(two));
+ assertTrue("0+(-1)", BigInteger.ZERO.add(minusOne).equals(minusOne));
+ assertTrue("(-1)+0", minusOne.add(BigInteger.ZERO).equals(minusOne));
+ assertTrue("(-1)+(-1)", minusOne.add(minusOne).equals(new BigInteger("-2", 10)));
+ assertTrue("1+(-1)", BigInteger.ONE.add(minusOne).equals(BigInteger.ZERO));
+ assertTrue("(-1)+1", minusOne.add(BigInteger.ONE).equals(BigInteger.ZERO));
+
+ for (int i = 0; i < 200; i++) {
+ BigInteger midbit = BigInteger.ZERO.setBit(i);
+ assertTrue("add fails to carry on bit " + i, midbit.add(midbit)
+ .equals(BigInteger.ZERO.setBit(i + 1)));
+ }
+ BigInteger bi2p3 = bi2.add(bi3);
+ BigInteger bi3p2 = bi3.add(bi2);
+ assertTrue("bi2p3=bi3p2", bi2p3.equals(bi3p2));
+
+
+ // BESSER UEBERGREIFENDE TESTS MACHEN IN FORM VON STRESS TEST.
+ // add large positive + small positive
+ BigInteger sum = aZillion;
+ BigInteger increment = BigInteger.ONE;
+ for (int i = 0; i < 20; i++) {
+
+ }
+
+ // add large positive + small negative
+
+ // add large negative + small positive
+
+ // add large negative + small negative
+ }
+
+ public void testClone() {
+ // Regression test for HARMONY-1770
+ MyBigInteger myBigInteger = new MyBigInteger("12345");
+ myBigInteger = (MyBigInteger) myBigInteger.clone();
+ }
+
+ static class MyBigInteger extends BigInteger implements Cloneable {
+ public MyBigInteger(String val) {
+ super(val);
+ }
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError(e); // android-changed
+ }
+ }
+ }
+
+ @Override
+ protected void setUp() {
+ bi2 = new BigInteger("4576829475724387584378543764555", 16);
+ bi3 = new BigInteger("43987298363278574365732645872643587624387563245", 16);
+ }
+
+ private boolean isPrime(long b) {
+ if (b == 2) {
+ return true;
+ }
+ // check for div by 2
+ if ((b & 1L) == 0) {
+ return false;
+ }
+ long maxlen = ((long) Math.sqrt(b)) + 2;
+ for (long x = 3; x < maxlen; x += 2) {
+ if (b % x == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/RoundingModeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/RoundingModeTest.java
new file mode 100644
index 0000000..4004ca3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/RoundingModeTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.math;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public class RoundingModeTest extends junit.framework.TestCase {
+
+ /**
+ * java.math.RoundingMode#valueOf(int)
+ */
+ public void test_valueOfI() {
+ assertEquals("valueOf failed for ROUND_CEILING", RoundingMode.valueOf(BigDecimal.ROUND_CEILING), RoundingMode.CEILING);
+ assertEquals("valueOf failed for ROUND_DOWN", RoundingMode.valueOf(BigDecimal.ROUND_DOWN), RoundingMode.DOWN);
+ assertEquals("valueOf failed for ROUND_FLOOR", RoundingMode.valueOf(BigDecimal.ROUND_FLOOR), RoundingMode.FLOOR);
+ assertEquals("valueOf failed for ROUND_HALF_DOWN", RoundingMode.valueOf(BigDecimal.ROUND_HALF_DOWN), RoundingMode.HALF_DOWN);
+ assertEquals("valueOf failed for ROUND_HALF_EVEN", RoundingMode.valueOf(BigDecimal.ROUND_HALF_EVEN), RoundingMode.HALF_EVEN);
+ assertEquals("valueOf failed for ROUND_HALF_UP", RoundingMode.valueOf(BigDecimal.ROUND_HALF_UP), RoundingMode.HALF_UP);
+ assertEquals("valueOf failed for ROUND_UNNECESSARY", RoundingMode.valueOf(BigDecimal.ROUND_UNNECESSARY), RoundingMode.UNNECESSARY);
+ assertEquals("valueOf failed for ROUND_UP", RoundingMode.valueOf(BigDecimal.ROUND_UP), RoundingMode.UP);
+ try {
+ RoundingMode.valueOf(13);
+ fail("IllegalArgumentException expected for RoundingMode(13)");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ RoundingMode.valueOf(-1);
+ fail("IllegalArgumentException expected for RoundingMode(-1)");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/BindExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/BindExceptionTest.java
new file mode 100644
index 0000000..799211e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/BindExceptionTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.BindException;
+
+public class BindExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.BindException#BindException()
+ */
+ public void test_Constructor() {
+ // Test for method java.net.BindException()
+ try {
+ throw new BindException();
+ } catch (BindException e) {
+ return;
+ } catch (Exception e) {
+ fail("Exception during BindException test" + e.toString());
+ }
+ fail("Failed to generate exception");
+ }
+
+ /**
+ * java.net.BindException#BindException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.net.BindException(java.lang.String)
+ try {
+ throw new BindException("Some error message");
+ } catch (BindException e) {
+ return;
+ } catch (Exception e) {
+ fail("Exception during BindException test : " + e.getMessage());
+ }
+ fail("Failed to generate exception");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ConnectExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ConnectExceptionTest.java
new file mode 100644
index 0000000..d0290ec
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ConnectExceptionTest.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.ConnectException;
+
+public class ConnectExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.ConnectException#ConnectException()
+ * java.net.ConnectException#ConnectException(java.lang.String)
+ */
+ public void test_Constructor() {
+ assertNull("Wrong message", new ConnectException().getMessage());
+ assertEquals("Wrong message", "message", new ConnectException("message").getMessage());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieHandlerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieHandlerTest.java
new file mode 100644
index 0000000..3cefc85
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieHandlerTest.java
@@ -0,0 +1,62 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.net.CookieHandler;
+import java.net.NetPermission;
+import java.net.URI;
+import java.security.Permission;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class CookieHandlerTest extends TestCase {
+
+ /**
+ * java.net.CookieHandler#getDefault()
+ */
+ public void test_GetDefault() {
+ assertNull(CookieHandler.getDefault());
+ }
+
+ /**
+ * java.net.CookieHandler#setDefault(CookieHandler)
+ */
+ public void test_SetDefault_java_net_cookieHandler() {
+ MockCookieHandler rc1 = new MockCookieHandler();
+ MockCookieHandler rc2 = new MockCookieHandler();
+ CookieHandler.setDefault(rc1);
+ assertSame(CookieHandler.getDefault(), rc1);
+ CookieHandler.setDefault(rc2);
+ assertSame(CookieHandler.getDefault(), rc2);
+ CookieHandler.setDefault(null);
+ assertNull(CookieHandler.getDefault());
+ }
+
+ class MockCookieHandler extends CookieHandler {
+
+ public Map get(URI uri, Map requestHeaders) throws IOException {
+ return null;
+ }
+
+ public void put(URI uri, Map responseHeaders) throws IOException {
+ // empty
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieManagerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieManagerTest.java
new file mode 100644
index 0000000..d0c4ee1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieManagerTest.java
@@ -0,0 +1,303 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.net;
+
+import junit.framework.TestCase;
+import java.io.IOException;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class CookieManagerTest extends TestCase {
+
+ private static void checkValidParams4Get(URI uri,
+ Map<String, List<String>> map) throws IOException {
+ CookieManager manager = new CookieManager();
+ try {
+ manager.get(uri, map);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ }
+
+ private static void checkValidParams4Put(URI uri,
+ Map<String, List<String>> map) throws IOException {
+ CookieManager manager = new CookieManager();
+ try {
+ manager.put(uri, map);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * {@link java.net.CookieManager#get(java.net.URI, java.util.Map)} &
+ * {@link java.net.CookieManager#put(java.net.URI, java.util.Map)}
+ * IllegalArgumentException
+ * @since 1.6
+ */
+ public void test_Put_Get_LURI_LMap_exception() throws IOException,
+ URISyntaxException {
+ // get
+ checkValidParams4Get(new URI(""), null);
+ checkValidParams4Get(new URI("http://www.test.com"), null);
+ checkValidParams4Get(null, null);
+ checkValidParams4Get(null, new HashMap<String, List<String>>());
+
+ // put
+ checkValidParams4Put(new URI(""), null);
+ checkValidParams4Put(new URI("http://www.test.com"), null);
+ checkValidParams4Put(null, null);
+ checkValidParams4Put(null, new HashMap<String, List<String>>());
+ }
+
+ private static Map<String, List<String>> addCookie(String[][] cookies) {
+ Map<String, List<String>> responseHeaders = new LinkedHashMap<String, List<String>>();
+ for (int i = 0; i < cookies.length; i++) {
+ List<String> fields = new ArrayList<String>();
+ for (int j = 1; j < cookies[i].length; j += 2) {
+ fields.add(cookies[i][j]);
+ }
+ responseHeaders.put(cookies[i][0], fields);
+ }
+ return responseHeaders;
+ }
+
+ private static CookieManager store(String[][] cookies,
+ Map<String, List<String>> responseHeaders, CookiePolicy policy)
+ throws IOException, URISyntaxException {
+ CookieManager manager = new CookieManager(null, policy);
+ // Put all cookies into manager
+ for (int i = 0; i < cookies.length; i++) {
+ for (int j = 2; j < cookies[i].length; j += 2) {
+ URI uri = new URI(cookies[i][j]);
+ manager.put(uri, responseHeaders);
+ }
+ }
+ return manager;
+ }
+
+ /**
+ * Unlike the RI, we flatten all matching cookies into a single Cookie header
+ * instead of sending down multiple cookie headers. Also, when no cookies match
+ * a given URI, we leave the requestHeaders unmodified.
+ *
+ * @since 1.6
+ */
+ public void test_Put_Get_LURI_LMap() throws IOException, URISyntaxException {
+ // cookie-key | (content, URI)...
+ String[][] cookies = {
+ { "Set-cookie",
+ "Set-cookie:PREF=test;path=/;domain=.b.c;", "http://a.b.c/",
+ "Set-cookie:PREF1=test2;path=/;domain=.beg.com;", "http://a.b.c/" },
+
+ { "Set-cookie2",
+ "Set-cookie2:NAME1=VALUE1;path=/te;domain=.b.c;", "http://a.b.c/test" },
+
+ { "Set-cookie",
+ "Set-cookie2:NAME=VALUE;path=/;domain=.beg.com;", "http://a.beg.com/test",
+ "Set-cookie2:NAME1=VALUE1;path=/;domain=.beg.com;", "http://a.beg.com/test" },
+
+ { "Set-cookie2",
+ "Set-cookie3:NAME=VALUE;path=/;domain=.test.org;", "http://a.test.org/test" },
+
+ { null,
+ "Set-cookie3:NAME=VALUE;path=/te;domain=.test.org;", "http://a.test.org/test" },
+
+ { "Set-cookie2",
+ "lala", "http://a.test.org/test" }
+
+ };
+
+ // requires path of cookie is the prefix of uri
+ // domain of cookie must match that of uri
+ Map<String, List<String>> responseHeaders = addCookie(new String[][] {
+ cookies[0], cookies[1] });
+ CookieManager manager = store(
+ new String[][] { cookies[0], cookies[1] }, responseHeaders,
+ null);
+
+ HashMap<String, List<String>> dummyMap = new HashMap<String, List<String>>();
+ Map<String, List<String>> map = manager.get(new URI("http://a.b.c/"),
+ dummyMap);
+
+ assertEquals(1, map.size());
+ List<String> list = map.get("Cookie");
+ assertEquals(1, list.size());
+
+ // requires path of cookie is the prefix of uri
+ map = manager.get(new URI("http://a.b.c/te"), dummyMap);
+ list = map.get("Cookie");
+ assertEquals(1, list.size());
+ assertTrue(list.get(0).contains("PREF=test"));
+ // Cookies from "/test" should *not* match the URI "/te".
+ assertFalse(list.get(0).contains("NAME=VALUE"));
+
+ // If all cookies are of version 1, then $version=1 will be added
+ // ,no matter the value cookie-key
+ responseHeaders = addCookie(new String[][] { cookies[2] });
+ manager = store(new String[][] { cookies[2] }, responseHeaders, null);
+ map = manager.get(new URI("http://a.beg.com/test"), dummyMap);
+ list = map.get("Cookie");
+ assertEquals(1, list.size());
+ assertTrue(list.get(0).startsWith("$Version=\"1\""));
+
+ // cookie-key will not have effect on determining cookie version
+ responseHeaders = addCookie(new String[][] { cookies[3] });
+ manager = store(new String[][] { cookies[3] }, responseHeaders, null);
+ map = manager.get(new URI("http://a.test.org/"), responseHeaders);
+ list = map.get("Cookie");
+ assertEquals(1, list.size());
+ assertEquals("Set-cookie3:NAME=VALUE", list.get(0));
+
+ // When key is null, no cookie can be stored/retrieved, even if policy =
+ // ACCEPT_ALL
+ responseHeaders = addCookie(new String[][] { cookies[4] });
+ manager = store(new String[][] { cookies[4] }, responseHeaders,
+ CookiePolicy.ACCEPT_ALL);
+ map = manager.get(new URI("http://a.test.org/"), responseHeaders);
+ list = map.get("Cookie");
+ assertNull(list);
+
+ // All cookies will be rejected if policy == ACCEPT_NONE
+ responseHeaders = addCookie(new String[][] { cookies[3] });
+ manager = store(new String[][] { cookies[3] }, responseHeaders,
+ CookiePolicy.ACCEPT_NONE);
+ map = manager.get(new URI("http://a.test.org/"), responseHeaders);
+ list = map.get("Cookie");
+ assertNull(list);
+
+ responseHeaders = addCookie(new String[][] { cookies[5] });
+ manager = store(new String[][] { cookies[5] }, responseHeaders,
+ CookiePolicy.ACCEPT_ALL);
+ list = map.get("Cookie");
+ assertNull(list);
+
+ try {
+ map.put(null, null);
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * {@link java.net.CookieManager#CookieManager()}
+ * @since 1.6
+ */
+ public void test_CookieManager() {
+ CookieManager cookieManager = new CookieManager();
+ assertNotNull(cookieManager);
+ assertNotNull(cookieManager.getCookieStore());
+ }
+
+ /**
+ * {@link java.net.CookieManager#CookieManager(java.net.CookieStore, java.net.CookiePolicy)}
+ * @since 1.6
+ */
+ public void testCookieManager_LCookieStore_LCookiePolicy() {
+ class DummyStore implements CookieStore {
+ public String getName() {
+ return "A dummy store";
+ }
+
+ public void add(URI uri, HttpCookie cookie) {
+ // expected
+ }
+
+ public List<HttpCookie> get(URI uri) {
+ return null;
+ }
+
+ public List<HttpCookie> getCookies() {
+ return null;
+ }
+
+ public List<URI> getURIs() {
+ return null;
+ }
+
+ public boolean remove(URI uri, HttpCookie cookie) {
+ return false;
+ }
+
+ public boolean removeAll() {
+ return false;
+ }
+ }
+ CookieStore store = new DummyStore();
+ CookieManager cookieManager = new CookieManager(store,
+ CookiePolicy.ACCEPT_ALL);
+ assertEquals("A dummy store", ((DummyStore) cookieManager
+ .getCookieStore()).getName());
+ assertSame(store, cookieManager.getCookieStore());
+ }
+
+ /**
+ * {@link java.net.CookieManager#setCookiePolicy(java.net.CookiePolicy)}
+ * @since 1.6
+ */
+ public void test_SetCookiePolicy_LCookiePolicy() throws URISyntaxException,
+ IOException {
+
+ // Policy = ACCEPT_NONE
+ CookieManager manager = new CookieManager();
+ manager.setCookiePolicy(CookiePolicy.ACCEPT_NONE);
+ Map<String, List<String>> responseHeaders = new TreeMap<String, List<String>>();
+ URI uri = new URI("http://a.b.c");
+ manager.put(uri, responseHeaders);
+ Map<String, List<String>> map = manager.get(uri,
+ new HashMap<String, List<String>>());
+
+ assertEquals(0, map.size());
+
+ // Policy = ACCEPT_ALL
+ manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
+ responseHeaders = new TreeMap<String, List<String>>();
+ ArrayList<String> list = new ArrayList<String>();
+ list.add("test=null");
+ responseHeaders.put("Set-cookie", list);
+ uri = new URI("http://b.c.d");
+ manager.put(uri, responseHeaders);
+ map = manager.get(uri, new HashMap<String, List<String>>());
+ assertEquals(1, map.size());
+ }
+
+ /**
+ * {@link java.net.CookieManager#getCookieStore()}
+ * @since 1.6
+ */
+ public void test_GetCookieStore() {
+ CookieManager cookieManager = new CookieManager();
+ CookieStore store = cookieManager.getCookieStore();
+ assertNotNull(store);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookiePolicyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookiePolicyTest.java
new file mode 100644
index 0000000..61eff1e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookiePolicyTest.java
@@ -0,0 +1,112 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.CookiePolicy;
+import java.net.HttpCookie;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import junit.framework.TestCase;
+
+public class CookiePolicyTest extends TestCase {
+
+ /**
+ * java.net.CookiePolicy#shouldAccept(java.net.URI,
+ *java.net.HttpCookie).
+ * @since 1.6
+ */
+ public void test_ShouldAccept_LURI_LHttpCookie() throws URISyntaxException {
+ HttpCookie cookie = new HttpCookie("Harmony_6", "ongoing");
+ URI uri = new URI("");
+ try {
+ CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(null, cookie);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(uri, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(null, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // Policy: ACCEPT_ALL, always returns true
+ boolean accept = CookiePolicy.ACCEPT_ALL.shouldAccept(null, cookie);
+ assertTrue(accept);
+
+ accept = CookiePolicy.ACCEPT_ALL.shouldAccept(null, null);
+ assertTrue(accept);
+
+ accept = CookiePolicy.ACCEPT_ALL.shouldAccept(uri, null);
+ assertTrue(accept);
+
+ // Policy: ACCEPT_NONE, always returns false
+ accept = CookiePolicy.ACCEPT_NONE.shouldAccept(null, cookie);
+ assertFalse(accept);
+
+ accept = CookiePolicy.ACCEPT_NONE.shouldAccept(null, null);
+ assertFalse(accept);
+
+ accept = CookiePolicy.ACCEPT_NONE.shouldAccept(uri, null);
+ assertFalse(accept);
+
+ // Policy: ACCEPT_ORIGINAL_SERVER
+ accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(uri, cookie);
+ assertFalse(accept);
+
+ cookie.setDomain(".b.c");
+ accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+ "schema://a.b.c"), cookie);
+ assertTrue(accept);
+
+ cookie.setDomain(".b.c");
+ accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+ "s://a.b.c.d"), cookie);
+ assertFalse(accept);
+
+ cookie.setDomain("b.c");
+ accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+ "s://a.b.c.d"), cookie);
+ assertFalse(accept);
+
+ cookie.setDomain("a.b.c.d");
+ accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+ "s://a.b.c.d"), cookie);
+ assertTrue(accept);
+
+ cookie.setDomain(".");
+ accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+ "s://a.b.c.d"), cookie);
+ assertFalse(accept);
+
+ cookie.setDomain("");
+ accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+ "s://a.b.c.d"), cookie);
+ assertFalse(accept);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieStoreTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieStoreTest.java
new file mode 100644
index 0000000..72be761
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/CookieStoreTest.java
@@ -0,0 +1,401 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.net;
+
+import junit.framework.TestCase;
+import java.net.CookieManager;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.RandomAccess;
+
+public class CookieStoreTest extends TestCase {
+
+ private CookieManager cookieManager;
+
+ private CookieStore cookieStore;
+
+ /**
+ * java.net.CookieStore#add(URI, HttpCookie)
+ * @since 1.6
+ */
+ public void test_add_LURI_LHttpCookie() throws URISyntaxException {
+ URI uri = new URI("http://harmony.test.unit.org");
+ HttpCookie cookie = new HttpCookie("name1", "value1");
+ cookie.setDiscard(true);
+
+ // This needn't throw. We should use the cookie's domain, if set.
+ // If no domain is set, this cookie will languish in the store until
+ // it expires.
+ cookieStore.add(null, cookie);
+
+ try {
+ cookieStore.add(uri, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ cookieStore.add(null, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ cookieStore.add(uri, cookie);
+ List<HttpCookie> list = cookieStore.get(uri);
+ assertEquals(1, list.size());
+ assertTrue(list.contains(cookie));
+
+ HttpCookie cookie2 = new HttpCookie(" NaME1 ", " TESTVALUE1 ");
+ cookieStore.add(uri, cookie2);
+ list = cookieStore.get(uri);
+ assertEquals(1, list.size());
+ assertEquals(" TESTVALUE1 ", list.get(0).getValue());
+ assertTrue(list.contains(cookie2));
+
+ // domain and path attributes works
+ HttpCookie anotherCookie = new HttpCookie("name1", "value1");
+ anotherCookie.setDomain("domain");
+ anotherCookie.setPath("Path");
+ cookieStore.add(uri, anotherCookie);
+ list = cookieStore.get(uri);
+ assertEquals(2, list.size());
+ assertNull(list.get(0).getDomain());
+ assertEquals("domain", list.get(1).getDomain());
+ assertEquals("Path", list.get(1).getPath());
+
+ URI uri2 = new URI("http://.test.unit.org");
+ HttpCookie cookie3 = new HttpCookie("NaME2", "VALUE2");
+ cookieStore.add(uri2, cookie3);
+ list = cookieStore.get(uri2);
+ assertEquals(1, list.size());
+ assertEquals("VALUE2", list.get(0).getValue());
+ list = cookieStore.getCookies();
+ assertEquals(3, list.size());
+
+ // expired cookie won't be selected.
+ HttpCookie cookie4 = new HttpCookie("cookie4", "value4");
+ cookie4.setMaxAge(-2);
+ assertTrue(cookie4.hasExpired());
+ cookieStore.add(uri2, cookie4);
+ list = cookieStore.getCookies();
+ assertEquals(3, list.size());
+ assertFalse(cookieStore.remove(uri2, cookie4));
+
+ cookie4.setMaxAge(3000);
+ cookie4.setDomain("domain");
+ cookie4.setPath("path");
+ cookieStore.add(uri2, cookie4);
+ list = cookieStore.get(uri2);
+ assertEquals(2, list.size());
+
+ cookieStore.add(uri, cookie4);
+ list = cookieStore.get(uri);
+ assertEquals(3, list.size());
+ list = cookieStore.get(uri2);
+ assertEquals(2, list.size());
+ list = cookieStore.getCookies();
+ assertEquals(4, list.size());
+
+ URI baduri = new URI("bad_url");
+ HttpCookie cookie6 = new HttpCookie("cookie5", "value5");
+ cookieStore.add(baduri, cookie6);
+ list = cookieStore.get(baduri);
+ assertTrue(list.contains(cookie6));
+ }
+
+ /**
+ * java.net.CookieStore#get(URI)
+ * @since 1.6
+ */
+ public void test_get_LURI() throws URISyntaxException {
+ try {
+ cookieStore.get(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ URI uri1 = new URI("http://get.uri1.test.org");
+ List<HttpCookie> list = cookieStore.get(uri1);
+ assertTrue(list.isEmpty());
+
+ HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
+ HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+ cookieStore.add(uri1, cookie1);
+ cookieStore.add(uri1, cookie2);
+ URI uri2 = new URI("http://get.uri2.test.org");
+ HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
+ cookieStore.add(uri2, cookie3);
+ list = cookieStore.get(uri1);
+ assertEquals(2, list.size());
+ list = cookieStore.get(uri2);
+ assertEquals(1, list.size());
+
+ // domain-match cookies also be selected.
+ HttpCookie cookie4 = new HttpCookie("cookie_name4", "cookie_value4");
+ cookie4.setDomain(".uri1.test.org");
+ cookieStore.add(uri2, cookie4);
+ list = cookieStore.get(uri1);
+ assertEquals(3, list.size());
+
+ cookieStore.add(uri1, cookie4);
+ list = cookieStore.get(uri1);
+ assertEquals(3, list.size());
+ list = cookieStore.get(uri2);
+ assertEquals(2, list.size());
+
+ // expired cookie won't be selected.
+ HttpCookie cookie5 = new HttpCookie("cookie_name5", "cookie_value5");
+ cookie5.setMaxAge(-333);
+ assertTrue(cookie5.hasExpired());
+ cookieStore.add(uri1, cookie5);
+ list = cookieStore.get(uri1);
+ assertEquals(3, list.size());
+ assertFalse(cookieStore.remove(uri1, cookie5));
+ list = cookieStore.getCookies();
+ assertEquals(4, list.size());
+
+ cookie4.setMaxAge(-123);
+ list = cookieStore.get(uri1);
+ assertEquals(2, list.size());
+ list = cookieStore.getCookies();
+ assertEquals(3, list.size());
+ // expired cookies are also deleted even if it domain-matches the URI
+ HttpCookie cookie6 = new HttpCookie("cookie_name6", "cookie_value6");
+ cookie6.setMaxAge(-2);
+ cookie6.setDomain(".uri1.test.org");
+ cookieStore.add(uri2, cookie6);
+ list = cookieStore.get(uri1);
+ assertEquals(2, list.size());
+ assertFalse(cookieStore.remove(null, cookie6));
+
+ URI uri3 = new URI("http://get.uri3.test.org");
+ assertTrue(cookieStore.get(uri3).isEmpty());
+ URI baduri = new URI("invalid_uri");
+ assertTrue(cookieStore.get(baduri).isEmpty());
+ }
+
+ /**
+ * java.net.CookieStore#getCookies()
+ * @since 1.6
+ */
+ public void test_getCookies() throws URISyntaxException {
+ List<HttpCookie> list = cookieStore.getCookies();
+ assertTrue(list.isEmpty());
+ assertTrue(list instanceof RandomAccess);
+
+ HttpCookie cookie1 = new HttpCookie("cookie_name", "cookie_value");
+ URI uri1 = new URI("http://getcookies1.test.org");
+ cookieStore.add(uri1, cookie1);
+ list = cookieStore.getCookies();
+ assertTrue(list.contains(cookie1));
+
+ HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+ URI uri2 = new URI("http://getcookies2.test.org");
+ cookieStore.add(uri2, cookie2);
+ list = cookieStore.getCookies();
+ assertEquals(2, list.size());
+ assertTrue(list.contains(cookie1));
+ assertTrue(list.contains(cookie2));
+
+ // duplicated cookie won't be selected.
+ cookieStore.add(uri2, cookie1);
+ list = cookieStore.getCookies();
+ assertEquals(2, list.size());
+ // expired cookie won't be selected.
+ HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
+ cookie3.setMaxAge(-1357);
+ cookieStore.add(uri1, cookie3);
+ list = cookieStore.getCookies();
+ assertEquals(2, list.size());
+
+ try {
+ list.add(new HttpCookie("readOnlyName", "readOnlyValue"));
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ try {
+ list.remove(new HttpCookie("readOnlyName", "readOnlyValue"));
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.net.CookieStore#getURIs()
+ * @since 1.6
+ */
+ public void test_getURIs() throws URISyntaxException {
+ List<URI> list = cookieStore.getURIs();
+ assertTrue(list.isEmpty());
+
+ URI uri1 = new URI("http://geturis1.test.com");
+ HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
+ cookieStore.add(uri1, cookie1);
+ list = cookieStore.getURIs();
+ assertEquals("geturis1.test.com", list.get(0).getHost());
+
+ HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+ cookieStore.add(uri1, cookie2);
+ list = cookieStore.getURIs();
+ assertEquals(1, list.size());
+
+ URI uri2 = new URI("http://geturis2.test.com");
+ cookieStore.add(uri2, cookie2);
+ list = cookieStore.getURIs();
+ assertEquals(2, list.size());
+ assertTrue(list.contains(uri1));
+ assertTrue(list.contains(uri2));
+ }
+
+ /**
+ * java.net.CookieStore#remove(URI, HttpCookie)
+ * @since 1.6
+ */
+ public void test_remove_LURI_LHttpCookie() throws URISyntaxException {
+ URI uri1 = new URI("http://remove1.test.com");
+ HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
+ try {
+ cookieStore.remove(uri1, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ assertFalse(cookieStore.remove(uri1, cookie1));
+ assertFalse(cookieStore.remove(null, cookie1));
+
+ cookieStore.add(uri1, cookie1);
+ URI uri2 = new URI("http://remove2.test.com");
+ HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+ cookieStore.add(uri2, cookie2);
+ assertTrue(cookieStore.remove(uri1, cookie1));
+ assertFalse(cookieStore.remove(uri1, cookie1));
+ assertEquals(2, cookieStore.getURIs().size());
+ assertEquals(1, cookieStore.getCookies().size());
+ assertTrue(cookieStore.remove(uri2, cookie2));
+ assertFalse(cookieStore.remove(uri2, cookie2));
+ assertEquals(2, cookieStore.getURIs().size());
+ assertEquals(0, cookieStore.getCookies().size());
+
+ assertTrue(cookieStore.removeAll());
+ cookieStore.add(uri1, cookie1);
+ cookieStore.add(uri2, cookie2);
+ HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
+ assertFalse(cookieStore.remove(null, cookie3));
+ // No guarantees on behavior if we call remove with a different
+ // uri from the one originally associated with the cookie.
+ assertFalse(cookieStore.remove(null, cookie1));
+ assertTrue(cookieStore.remove(uri1, cookie1));
+ assertFalse(cookieStore.remove(uri1, cookie1));
+
+ assertEquals(2, cookieStore.getURIs().size());
+ assertEquals(1, cookieStore.getCookies().size());
+ assertTrue(cookieStore.remove(uri2, cookie2));
+ assertFalse(cookieStore.remove(uri2, cookie2));
+ assertEquals(2, cookieStore.getURIs().size());
+ assertEquals(0, cookieStore.getCookies().size());
+
+ cookieStore.removeAll();
+ // expired cookies can also be deleted.
+ cookie2.setMaxAge(-34857);
+ cookieStore.add(uri2, cookie2);
+ assertTrue(cookieStore.remove(uri2, cookie2));
+ assertFalse(cookieStore.remove(uri2, cookie2));
+ assertEquals(0, cookieStore.getCookies().size());
+
+ cookie2.setMaxAge(34857);
+ cookieStore.add(uri1, cookie1);
+ cookieStore.add(uri2, cookie1);
+ cookieStore.add(uri2, cookie2);
+ assertTrue(cookieStore.remove(uri1, cookie1));
+ assertFalse(cookieStore.remove(uri1, cookie1));
+ assertTrue(cookieStore.get(uri2).contains(cookie1));
+ assertTrue(cookieStore.get(uri2).contains(cookie2));
+ assertEquals(0, cookieStore.get(uri1).size());
+ cookieStore.remove(uri2, cookie2);
+
+ cookieStore.removeAll();
+ cookieStore.add(uri2, cookie2);
+ cookieStore.add(uri1, cookie1);
+ assertEquals(2, cookieStore.getCookies().size());
+ assertFalse(cookieStore.remove(uri2, cookie1));
+ assertTrue(cookieStore.remove(uri1, cookie1));
+ assertEquals(2, cookieStore.getURIs().size());
+ assertEquals(1, cookieStore.getCookies().size());
+ assertTrue(cookieStore.getCookies().contains(cookie2));
+
+ cookieStore.removeAll();
+ URI uri3 = new URI("http://remove3.test.com");
+ URI uri4 = new URI("http://test.com");
+ HttpCookie cookie4 = new HttpCookie("cookie_name4", "cookie_value4");
+ cookie4.setDomain(".test.com");
+ cookie2.setMaxAge(-34857);
+ cookie3.setMaxAge(-22);
+ cookie4.setMaxAge(-45);
+ cookieStore.add(uri1, cookie1);
+ cookieStore.add(uri2, cookie2);
+ cookieStore.add(uri3, cookie3);
+ cookieStore.add(uri4, cookie4);
+ assertEquals(0, cookieStore.get(uri2).size());
+ assertFalse(cookieStore.remove(uri2, cookie2));
+ assertTrue(cookieStore.remove(uri3, cookie3));
+ assertFalse(cookieStore.remove(uri4, cookie4));
+ }
+
+ /**
+ * java.net.CookieStore#test_removeAll()
+ * @since 1.6
+ */
+ public void test_removeAll() throws URISyntaxException {
+ assertFalse(cookieStore.removeAll());
+
+ URI uri1 = new URI("http://removeAll1.test.com");
+ HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
+ cookieStore.add(uri1, cookie1);
+ URI uri2 = new URI("http://removeAll2.test.com");
+ HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+ cookieStore.add(uri2, cookie2);
+
+ assertTrue(cookieStore.removeAll());
+ assertTrue(cookieStore.getURIs().isEmpty());
+ assertTrue(cookieStore.getCookies().isEmpty());
+
+ assertFalse(cookieStore.removeAll());
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ cookieManager = new CookieManager();
+ cookieStore = cookieManager.getCookieStore();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ cookieManager = null;
+ cookieStore = null;
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramPacketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramPacketTest.java
new file mode 100644
index 0000000..2730b85
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramPacketTest.java
@@ -0,0 +1,338 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+
+import tests.support.Support_Configuration;
+
+public class DatagramPacketTest extends junit.framework.TestCase {
+
+ volatile boolean started = false;
+
+ /**
+ * java.net.DatagramPacket#DatagramPacket(byte[], int)
+ */
+ public void test_Constructor$BI() {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+ assertEquals("Created incorrect packet", "Hello", new String(dp
+ .getData(), 0, dp.getData().length));
+ assertEquals("Wrong length", 5, dp.getLength());
+
+ // Regression for HARMONY-890
+ dp = new DatagramPacket(new byte[942], 4);
+ assertEquals(-1, dp.getPort());
+ try {
+ dp.getSocketAddress();
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.net.DatagramPacket#DatagramPacket(byte[], int, int)
+ */
+ public void test_Constructor$BII() {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 2, 3);
+ assertEquals("Created incorrect packet", "Hello", new String(dp
+ .getData(), 0, dp.getData().length));
+ assertEquals("Wrong length", 3, dp.getLength());
+ assertEquals("Wrong offset", 2, dp.getOffset());
+ }
+
+ /**
+ * java.net.DatagramPacket#DatagramPacket(byte[], int, int,
+ *java.net.InetAddress, int)
+ */
+ public void test_Constructor$BIILjava_net_InetAddressI() throws IOException {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 2, 3,
+ InetAddress.getLocalHost(), 0);
+ assertEquals("Wrong host", InetAddress.getLocalHost(), dp.getAddress());
+ assertEquals("Wrong port", 0, dp.getPort());
+ assertEquals("Wrong length", 3, dp.getLength());
+ assertEquals("Wrong offset", 2, dp.getOffset());
+ }
+
+ /**
+ * java.net.DatagramPacket#DatagramPacket(byte[], int,
+ *java.net.InetAddress, int)
+ */
+ public void test_Constructor$BILjava_net_InetAddressI() throws IOException {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+ InetAddress.getLocalHost(), 0);
+ assertEquals("Wrong address", InetAddress.getLocalHost(), dp
+ .getAddress());
+ assertEquals("Wrong port", 0, dp.getPort());
+ assertEquals("Wrong length", 5, dp.getLength());
+ }
+
+ /**
+ * java.net.DatagramPacket#getAddress()
+ */
+ public void test_getAddress() throws IOException {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+ InetAddress.getLocalHost(), 0);
+ assertEquals("Incorrect address returned", InetAddress.getLocalHost(),
+ dp.getAddress());
+ }
+
+ /**
+ * java.net.DatagramPacket#getData()
+ */
+ public void test_getData() {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+ assertEquals("Incorrect length returned", "Hello", new String(dp
+ .getData(), 0, dp.getData().length));
+ }
+
+ /**
+ * java.net.DatagramPacket#getLength()
+ */
+ public void test_getLength() {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+ assertEquals("Incorrect length returned", 5, dp.getLength());
+ }
+
+ /**
+ * java.net.DatagramPacket#getOffset()
+ */
+ public void test_getOffset() {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 3, 2);
+ assertEquals("Incorrect length returned", 3, dp.getOffset());
+ }
+
+ /**
+ * java.net.DatagramPacket#getPort()
+ */
+ public void test_getPort() throws IOException {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+ InetAddress.getLocalHost(), 1000);
+ assertEquals("Incorrect port returned", 1000, dp.getPort());
+
+ final InetAddress localhost = InetAddress.getLocalHost();
+ DatagramSocket socket = new DatagramSocket(0, localhost);
+ final int port = socket.getLocalPort();
+
+ socket.setSoTimeout(3000);
+ DatagramPacket packet = new DatagramPacket(new byte[] { 1, 2, 3, 4, 5,
+ 6 }, 6, localhost, port);
+ socket.send(packet);
+ socket.receive(packet);
+ socket.close();
+ assertTrue("datagram received wrong port: " + packet.getPort(), packet
+ .getPort() == port);
+ }
+
+ /**
+ * java.net.DatagramPacket#setAddress(java.net.InetAddress)
+ */
+ public void test_setAddressLjava_net_InetAddress() throws IOException {
+ InetAddress ia = InetAddress.getByName("127.0.0.1");
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+ InetAddress.getLocalHost(), 0);
+ dp.setAddress(ia);
+ assertEquals("Incorrect address returned", ia, dp.getAddress());
+ }
+
+ /**
+ * java.net.DatagramPacket#setData(byte[], int, int)
+ */
+ public void test_setData$BII() {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+ dp.setData("Wagga Wagga".getBytes(), 2, 3);
+ assertEquals("Incorrect data set", "Wagga Wagga", new String(dp
+ .getData()));
+ }
+
+ /**
+ * java.net.DatagramPacket#setData(byte[])
+ */
+ public void test_setData$B() {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+ dp.setData("Ralph".getBytes());
+ assertEquals("Incorrect data set", "Ralph", new String(dp.getData(), 0,
+ dp.getData().length));
+ }
+
+ /**
+ * java.net.DatagramPacket#setLength(int)
+ */
+ public void test_setLengthI() {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+ dp.setLength(1);
+ assertEquals("Failed to set packet length", 1, dp.getLength());
+ }
+
+ /**
+ * java.net.DatagramPacket#setPort(int)
+ */
+ public void test_setPortI() throws Exception {
+ DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+ InetAddress.getLocalHost(), 1000);
+ dp.setPort(2000);
+ assertEquals("Port not set", 2000, dp.getPort());
+ }
+
+ /**
+ * java.net.DatagramPacket#DatagramPacket(byte[], int,
+ *java.net.SocketAddress)
+ */
+ public void test_Constructor$BILjava_net_SocketAddress() throws IOException {
+ @SuppressWarnings("serial")
+ class UnsupportedSocketAddress extends SocketAddress {
+
+ public UnsupportedSocketAddress() {
+ }
+ }
+
+ // Unsupported SocketAddress subclass
+ byte buf[] = new byte[1];
+ try {
+ new DatagramPacket(buf, 1, new UnsupportedSocketAddress());
+ fail("No exception when constructing using unsupported SocketAddress subclass");
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ }
+
+ // Case were we try to pass in null
+ try {
+ new DatagramPacket(buf, 1, null);
+ fail("No exception when constructing address using null");
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ }
+
+ // Now validate we can construct
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 2067);
+ DatagramPacket thePacket = new DatagramPacket(buf, 1, theAddress);
+ assertEquals("Socket address not set correctly (1)", theAddress,
+ thePacket.getSocketAddress());
+ assertEquals("Socket address not set correctly (2)", theAddress,
+ new InetSocketAddress(thePacket.getAddress(), thePacket
+ .getPort()));
+ }
+
+ /**
+ * java.net.DatagramPacket#DatagramPacket(byte[], int, int,
+ *java.net.SocketAddress)
+ */
+ public void test_Constructor$BIILjava_net_SocketAddress()
+ throws IOException {
+ @SuppressWarnings("serial")
+ class UnsupportedSocketAddress extends SocketAddress {
+
+ public UnsupportedSocketAddress() {
+ }
+ }
+
+ // Unsupported SocketAddress subclass
+ byte buf[] = new byte[2];
+ try {
+ new DatagramPacket(buf, 1, 1, new UnsupportedSocketAddress());
+ fail("No exception when constructing using unsupported SocketAddress subclass");
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ }
+
+ // Case were we try to pass in null
+ try {
+ new DatagramPacket(buf, 1, 1, null);
+ fail("No exception when constructing address using null");
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ }
+
+ // now validate we can construct
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 2067);
+ DatagramPacket thePacket = new DatagramPacket(buf, 1, 1, theAddress);
+ assertEquals("Socket address not set correctly (1)", theAddress,
+ thePacket.getSocketAddress());
+ assertEquals("Socket address not set correctly (2)", theAddress,
+ new InetSocketAddress(thePacket.getAddress(), thePacket
+ .getPort()));
+ assertEquals("Offset not set correctly", 1, thePacket.getOffset());
+ }
+
+ /**
+ * java.net.DatagramPacket#getSocketAddress()
+ */
+ public void test_getSocketAddress() throws IOException {
+ byte buf[] = new byte[1];
+ DatagramPacket thePacket = new DatagramPacket(buf, 1);
+
+ // Validate get returns the value we set
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 0);
+ thePacket = new DatagramPacket(buf, 1);
+ thePacket.setSocketAddress(theAddress);
+ assertEquals("Socket address not set correctly (1)", theAddress,
+ thePacket.getSocketAddress());
+ }
+
+ /**
+ * java.net.DatagramPacket#setSocketAddress(java.net.SocketAddress)
+ */
+ public void test_setSocketAddressLjava_net_SocketAddress()
+ throws IOException {
+
+ @SuppressWarnings("serial")
+ class UnsupportedSocketAddress extends SocketAddress {
+
+ public UnsupportedSocketAddress() {
+ }
+ }
+
+ // Unsupported SocketAddress subclass
+ byte buf[] = new byte[1];
+ DatagramPacket thePacket = new DatagramPacket(buf, 1);
+ try {
+ thePacket.setSocketAddress(new UnsupportedSocketAddress());
+ fail("No exception when setting address using unsupported SocketAddress subclass");
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ }
+
+ // Case were we try to pass in null
+ thePacket = new DatagramPacket(buf, 1);
+ try {
+ thePacket.setSocketAddress(null);
+ fail("No exception when setting address using null");
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ }
+
+ // Now validate we can set it correctly
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 2049);
+ thePacket = new DatagramPacket(buf, 1);
+ thePacket.setSocketAddress(theAddress);
+ assertEquals("Socket address not set correctly (1)", theAddress,
+ thePacket.getSocketAddress());
+ assertEquals("Socket address not set correctly (2)", theAddress,
+ new InetSocketAddress(thePacket.getAddress(), thePacket
+ .getPort()));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketImplTest.java
new file mode 100644
index 0000000..e94a963
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketImplTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocketImpl;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+
+public class DatagramSocketImplTest extends junit.framework.TestCase {
+ /**
+ * java.net.DatagramSocketImpl#DatagramSocketImpl()
+ */
+ public void test_Constructor() throws Exception {
+ // regression test for Harmony-1117
+ MockDatagramSocketImpl impl = new MockDatagramSocketImpl();
+ assertNull(impl.getFileDescriptor());
+ }
+
+
+ public void test_connect() throws Exception {
+ MockDatagramSocketImpl impl = new MockDatagramSocketImpl();
+ InetAddress localhost = InetAddress.getByName("localhost"); //$NON-NLS-1$
+ // connect do nothing, so will not throw exception
+ impl.test_connect(localhost, 0);
+ impl.test_connect(localhost, -1);
+ impl.test_connect(null, -1);
+ // disconnect
+ impl.test_disconnect();
+ }
+}
+
+class MockDatagramSocketImpl extends DatagramSocketImpl {
+
+ @Override
+ public FileDescriptor getFileDescriptor() {
+ return super.getFileDescriptor();
+ }
+
+ @Override
+ protected void bind(int port, InetAddress addr) throws SocketException {
+ // empty
+ }
+
+ @Override
+ protected void close() {
+ // empty
+ }
+
+ @Override
+ protected void create() throws SocketException {
+ // empty
+ }
+
+ public Object getOption(int optID) throws SocketException {
+ return null;
+ }
+
+ @Override
+ protected byte getTTL() throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected int getTimeToLive() throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected void join(InetAddress addr) throws IOException {
+ // empty
+ }
+
+ @Override
+ protected void joinGroup(SocketAddress addr, NetworkInterface netInterface)
+ throws IOException {
+ // empty
+ }
+
+ @Override
+ protected void leave(InetAddress addr) throws IOException {
+ // empty
+ }
+
+ @Override
+ protected void leaveGroup(SocketAddress addr, NetworkInterface netInterface)
+ throws IOException {
+ // empty
+ }
+
+ @Override
+ protected int peek(InetAddress sender) throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected int peekData(DatagramPacket pack) throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected void receive(DatagramPacket pack) throws IOException {
+ // empty
+ }
+
+ @Override
+ protected void send(DatagramPacket pack) throws IOException {
+ // empty
+
+ }
+
+ public void setOption(int optID, Object val) throws SocketException {
+ // empty
+ }
+
+ @Override
+ protected void setTTL(byte ttl) throws IOException {
+ // empty
+ }
+
+ @Override
+ protected void setTimeToLive(int ttl) throws IOException {
+ // empty
+ }
+
+ public void test_connect(InetAddress inetAddr, int port) throws SocketException {
+ super.connect(inetAddr, port);
+ }
+
+ public void test_disconnect() {
+ super.disconnect();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java
new file mode 100644
index 0000000..e585b14
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java
@@ -0,0 +1,940 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.BindException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.DatagramSocketImpl;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.nio.channels.DatagramChannel;
+
+public class DatagramSocketTest extends junit.framework.TestCase {
+
+ static final class DatagramServer extends Thread {
+
+ volatile boolean running = true;
+
+ private final boolean echo;
+ private final byte[] rbuf;
+ private final DatagramPacket rdp;
+ final DatagramSocket serverSocket;
+
+ public DatagramServer(InetAddress address, boolean echo)
+ throws IOException {
+ this.echo = echo;
+ rbuf = new byte[512];
+ rbuf[0] = -1;
+ rdp = new DatagramPacket(rbuf, rbuf.length);
+ serverSocket = new DatagramSocket(0, address);
+ serverSocket.setSoTimeout(2000);
+ }
+
+ public DatagramServer(InetAddress address) throws IOException {
+ this(address, true /* echo */);
+ }
+
+ public void run() {
+ try {
+ while (running) {
+ try {
+ serverSocket.receive(rdp);
+ if (echo) {
+ serverSocket.send(rdp);
+ }
+ } catch (InterruptedIOException e) {
+ }
+ }
+ } catch (IOException e) {
+ fail();
+ } finally {
+ serverSocket.close();
+ }
+ }
+
+ public int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ public void stopServer() {
+ running = false;
+ }
+ }
+
+ /**
+ * java.net.DatagramSocket#DatagramSocket()
+ */
+ public void test_Constructor() throws SocketException {
+ new DatagramSocket();
+ }
+
+ /**
+ * java.net.DatagramSocket#DatagramSocket(int)
+ */
+ public void test_ConstructorI() throws SocketException {
+ DatagramSocket ds = new DatagramSocket(0);
+ ds.close();
+ }
+
+ /**
+ * java.net.DatagramSocket#DatagramSocket(int, java.net.InetAddress)
+ */
+ public void test_ConstructorILjava_net_InetAddress() throws IOException {
+ DatagramSocket ds = new DatagramSocket(0, InetAddress.getLocalHost());
+ assertTrue("Created socket with incorrect port", ds.getLocalPort() != 0);
+ assertEquals("Created socket with incorrect address", InetAddress
+ .getLocalHost(), ds.getLocalAddress());
+ }
+
+ /**
+ * java.net.DatagramSocket#close()
+ */
+ public void test_close() throws UnknownHostException, SocketException {
+ DatagramSocket ds = new DatagramSocket(0);
+ DatagramPacket dp = new DatagramPacket("Test String".getBytes(), 11,
+ InetAddress.getLocalHost(), 0);
+ ds.close();
+ try {
+ ds.send(dp);
+ fail("Data sent after close");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ public void test_connectLjava_net_InetAddressI() throws Exception {
+ DatagramSocket ds = new DatagramSocket();
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ ds.connect(inetAddress, 0);
+ assertEquals("Incorrect InetAddress", inetAddress, ds.getInetAddress());
+ assertEquals("Incorrect Port", 0, ds.getPort());
+ ds.disconnect();
+
+ ds = new java.net.DatagramSocket();
+ inetAddress = InetAddress.getByName("FE80:0000:0000:0000:020D:60FF:FE0F:A776%4");
+ ds.connect(inetAddress, 0);
+ assertEquals(inetAddress, ds.getInetAddress());
+ ds.disconnect();
+ }
+
+ public void testConnect_connectToSelf() throws Exception {
+ // Create a connected datagram socket to test
+ // PlainDatagramSocketImpl.peek()
+ InetAddress localHost = InetAddress.getLocalHost();
+ final DatagramSocket ds = new DatagramSocket(0);
+ ds.connect(localHost, ds.getLocalPort());
+ DatagramPacket send = new DatagramPacket(new byte[10], 10, localHost,
+ ds.getLocalPort());
+ ds.send(send);
+
+ DatagramPacket receive = new DatagramPacket(new byte[20], 20);
+ ds.setSoTimeout(2000);
+ ds.receive(receive);
+ ds.close();
+
+ assertEquals(10, receive.getLength());
+ assertEquals(localHost, receive.getAddress());
+ }
+
+ private static void assertPacketDataEquals(DatagramPacket p1, DatagramPacket p2)
+ throws Exception {
+ assertEquals(p1.getLength(), p2.getLength());
+ final byte[] p1Bytes = p1.getData();
+ final byte[] p2Bytes = p2.getData();
+
+ for (int i = 0; i < p1.getLength(); ++i) {
+ if (p1Bytes[p1.getOffset() + i] != p2Bytes[p2.getOffset() + i]) {
+ String expected = new String(p1Bytes, p1.getOffset(), p1.getLength(),
+ "UTF-8");
+ String actual = new String(p2Bytes, p2.getOffset(), p2.getLength(),
+ "UTF-8");
+ fail("expected: " + expected + ", actual: " + actual);
+ }
+ }
+ }
+
+ public void testConnect_echoServer() throws Exception {
+ final DatagramSocket ds = new DatagramSocket(0);
+
+ final DatagramServer server = new DatagramServer(Inet6Address.LOOPBACK);
+ server.start();
+
+ ds.connect(Inet6Address.LOOPBACK, server.getPort());
+
+ final byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
+ final DatagramPacket send = new DatagramPacket(sendBytes, sendBytes.length);
+ final DatagramPacket receive = new DatagramPacket(new byte[20], 20);
+
+ ds.send(send);
+ ds.setSoTimeout(2000);
+ ds.receive(receive);
+ ds.close();
+
+ assertEquals(sendBytes.length, receive.getLength());
+ assertPacketDataEquals(send, receive);
+ assertEquals(Inet6Address.LOOPBACK, receive.getAddress());
+
+ server.stopServer();
+ }
+
+ // Validate that once connected we cannot send to another address.
+ public void testConnect_throwsOnAddressMismatch() throws Exception {
+ final DatagramSocket ds = new DatagramSocket(0);
+
+ DatagramServer s1 = new DatagramServer(Inet6Address.LOOPBACK);
+ DatagramServer s2 = new DatagramServer(Inet6Address.LOOPBACK);
+ try {
+ ds.connect(Inet6Address.LOOPBACK, s1.getPort());
+ ds.send(new DatagramPacket(new byte[10], 10, Inet6Address.LOOPBACK, s2.getPort()));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ } finally {
+ ds.close();
+ s1.stopServer();
+ s2.stopServer();
+ }
+ }
+
+ // Validate that we can connect, then disconnect, then connect then
+ // send/recv.
+ public void testConnect_connectDisconnectConnectThenSendRecv() throws Exception {
+ final DatagramSocket ds = new DatagramSocket(0);
+
+ final DatagramServer server = new DatagramServer(Inet6Address.LOOPBACK);
+ final DatagramServer broken = new DatagramServer(Inet6Address.LOOPBACK, false);
+ server.start();
+ broken.start();
+
+ final int serverPortNumber = server.getPort();
+ ds.connect(Inet6Address.LOOPBACK, broken.getPort());
+ ds.disconnect();
+ ds.connect(Inet6Address.LOOPBACK, serverPortNumber);
+
+ final byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
+ final DatagramPacket send = new DatagramPacket(sendBytes, sendBytes.length);
+ final DatagramPacket receive = new DatagramPacket(new byte[20], 20);
+ ds.send(send);
+ ds.setSoTimeout(2000);
+ ds.receive(receive);
+ ds.close();
+
+ assertPacketDataEquals(send, receive);
+ assertEquals(Inet6Address.LOOPBACK, receive.getAddress());
+
+ server.stopServer();
+ broken.stopServer();
+ }
+
+ // Validate that we can connect/disconnect then send/recv to any address
+ public void testConnect_connectDisconnectThenSendRecv() throws Exception {
+ final DatagramSocket ds = new DatagramSocket(0);
+
+ final DatagramServer server = new DatagramServer(Inet6Address.LOOPBACK);
+ server.start();
+
+ final int serverPortNumber = server.getPort();
+ ds.connect(Inet6Address.LOOPBACK, serverPortNumber);
+ ds.disconnect();
+
+ final byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
+ final DatagramPacket send = new DatagramPacket(sendBytes, sendBytes.length,
+ Inet6Address.LOOPBACK, serverPortNumber);
+ final DatagramPacket receive = new DatagramPacket(new byte[20], 20);
+ ds.send(send);
+ ds.setSoTimeout(2000);
+ ds.receive(receive);
+ ds.close();
+
+ assertPacketDataEquals(send, receive);
+ assertEquals(Inet6Address.LOOPBACK, receive.getAddress());
+
+ server.stopServer();
+ }
+
+ public void testConnect_connectTwice() throws Exception {
+ final DatagramSocket ds = new DatagramSocket(0);
+
+ final DatagramServer server = new DatagramServer(Inet6Address.LOOPBACK);
+ final DatagramServer broken = new DatagramServer(Inet6Address.LOOPBACK);
+ server.start();
+ broken.start();
+
+ final int serverPortNumber = server.getPort();
+ ds.connect(Inet6Address.LOOPBACK, broken.getPort());
+ ds.connect(Inet6Address.LOOPBACK, serverPortNumber);
+ ds.disconnect();
+
+ final byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
+ final DatagramPacket send = new DatagramPacket(sendBytes, sendBytes.length,
+ Inet6Address.LOOPBACK, serverPortNumber);
+ final DatagramPacket receive = new DatagramPacket(new byte[20], 20);
+ ds.send(send);
+ ds.setSoTimeout(2000);
+ ds.receive(receive);
+ ds.close();
+
+ assertPacketDataEquals(send, receive);
+ assertEquals(Inet6Address.LOOPBACK, receive.getAddress());
+
+ server.stopServer();
+ broken.stopServer();
+ }
+
+ public void testConnect_zeroAddress() throws Exception {
+ DatagramSocket ds = new DatagramSocket();
+ byte[] addressBytes = { 0, 0, 0, 0 };
+ InetAddress inetAddress = InetAddress.getByAddress(addressBytes);
+ ds.connect(inetAddress, 0);
+
+ ds = new java.net.DatagramSocket();
+ byte[] addressTestBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 };
+ inetAddress = InetAddress.getByAddress(addressTestBytes);
+ ds.connect(inetAddress, 0);
+ }
+
+ public void test_disconnect() throws Exception {
+ DatagramSocket ds = new DatagramSocket();
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ ds.connect(inetAddress, 0);
+ ds.disconnect();
+ assertNull("Incorrect InetAddress", ds.getInetAddress());
+ assertEquals("Incorrect Port", -1, ds.getPort());
+
+ ds = new DatagramSocket();
+ inetAddress = InetAddress.getByName("FE80:0000:0000:0000:020D:60FF:FE0F:A776%4");
+ ds.connect(inetAddress, 0);
+ ds.disconnect();
+ assertNull("Incorrect InetAddress", ds.getInetAddress());
+ assertEquals("Incorrect Port", -1, ds.getPort());
+ }
+
+ public void test_getLocalAddress() throws Exception {
+ // Test for method java.net.InetAddress
+ // java.net.DatagramSocket.getLocalAddress()
+ InetAddress local = InetAddress.getLocalHost();
+ DatagramSocket ds = new java.net.DatagramSocket(0, local);
+ assertEquals(InetAddress.getByName(InetAddress.getLocalHost().getHostName()), ds.getLocalAddress());
+
+ // now check behavior when the ANY address is returned
+ DatagramSocket s = new DatagramSocket(0);
+ assertTrue("ANY address not IPv6: " + s.getLocalSocketAddress(), s.getLocalAddress() instanceof Inet6Address);
+ s.close();
+ }
+
+ public void test_getLocalPort() throws SocketException {
+ DatagramSocket ds = new DatagramSocket();
+ assertTrue("Returned incorrect port", ds.getLocalPort() != 0);
+ }
+
+ public void test_getPort() throws IOException {
+ DatagramSocket theSocket = new DatagramSocket();
+ assertEquals("Expected -1 for remote port as not connected", -1,
+ theSocket.getPort());
+
+ // Now connect the socket and validate that we get the right port
+ int portNumber = 49152; // any valid port, even if it is unreachable
+ theSocket.connect(InetAddress.getLocalHost(), portNumber);
+ assertEquals("getPort returned wrong value", portNumber, theSocket
+ .getPort());
+ }
+
+ public void test_getReceiveBufferSize() throws Exception {
+ DatagramSocket ds = new DatagramSocket();
+ ds.setReceiveBufferSize(130);
+ assertTrue("Incorrect buffer size", ds.getReceiveBufferSize() >= 130);
+ ds.close();
+ try {
+ ds.getReceiveBufferSize();
+ fail("SocketException was not thrown.");
+ } catch(SocketException se) {
+ //expected
+ }
+ }
+
+ public void test_getSendBufferSize() throws Exception {
+ final DatagramSocket ds = new java.net.DatagramSocket(0);
+ ds.setSendBufferSize(134);
+ assertTrue("Incorrect buffer size", ds.getSendBufferSize() >= 134);
+ ds.close();
+ try {
+ ds.getSendBufferSize();
+ fail("SocketException was not thrown.");
+ } catch(SocketException se) {
+ //expected
+ }
+ }
+
+ public void test_getSoTimeout() throws Exception {
+ DatagramSocket ds = new DatagramSocket();
+ ds.setSoTimeout(100);
+ assertEquals("Returned incorrect timeout", 100, ds.getSoTimeout());
+ }
+
+ static final class TestDatagramSocketImpl extends DatagramSocketImpl {
+ // This field exists solely to force initialization of this class
+ // inside a test method.
+ public static final Object ACCESS = new Object();
+
+ @Override
+ protected void create() throws SocketException {
+ }
+
+ @Override
+ protected void bind(int arg0, InetAddress arg1)
+ throws SocketException {
+ }
+
+ @Override
+ protected void send(DatagramPacket arg0) throws IOException {
+ }
+
+ @Override
+ protected int peek(InetAddress arg0) throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected int peekData(DatagramPacket arg0) throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected void receive(DatagramPacket arg0) throws IOException {
+ }
+
+ @Override
+ protected void setTTL(byte arg0) throws IOException {
+ }
+
+ @Override
+ protected byte getTTL() throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected void setTimeToLive(int arg0) throws IOException {
+ }
+
+ @Override
+ protected int getTimeToLive() throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected void join(InetAddress arg0) throws IOException {
+ }
+
+ @Override
+ protected void joinGroup(SocketAddress addr, NetworkInterface netInterface) throws IOException {
+
+ }
+
+ @Override
+ protected void leave(InetAddress arg0) throws IOException {
+ }
+
+ @Override
+ protected void leaveGroup(SocketAddress arg0, NetworkInterface arg1)
+ throws IOException {
+ }
+
+ @Override
+ protected void close() {
+ }
+
+ public void setOption(int arg0, Object arg1) throws SocketException {
+ }
+
+ public Object getOption(int arg0) throws SocketException {
+ return null;
+ }
+ }
+
+ static final class TestDatagramSocket extends DatagramSocket {
+ // This field exists solely to force initialization of this class
+ // inside a test method.
+ public static final Object ACCESS = new Object();
+
+ public TestDatagramSocket(DatagramSocketImpl impl) {
+ super(impl);
+ }
+ }
+
+
+ public void testArchivedHarmonyRegressions() throws Exception {
+ // Regression for HARMONY-1118
+ assertNotNull(TestDatagramSocketImpl.ACCESS);
+ assertNotNull(TestDatagramSocket.ACCESS);
+
+ // Regression test for Harmony-2938
+ InetAddress i = InetAddress.getByName("127.0.0.1");
+ DatagramSocket d = new DatagramSocket(0, i);
+ try {
+ d.send(new DatagramPacket(new byte[] { 1 }, 1));
+ fail();
+ } catch (NullPointerException expected) {
+ } finally {
+ d.close();
+ }
+
+ // Regression test for Harmony-6413
+ InetSocketAddress addr = InetSocketAddress.createUnresolved(
+ "localhost", 0);
+ try {
+ new DatagramPacket(new byte[272], 3, addr);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_sendLjava_net_DatagramPacket_nullDestination() throws IOException {
+ DatagramSocket datagramSocket = new DatagramSocket(0);
+ byte[] data = { 65 };
+ DatagramPacket sendPacket = new DatagramPacket(data, data.length, null, 25000);
+ try {
+ datagramSocket.send(sendPacket);
+ fail();
+ } catch (NullPointerException expected) {
+ // Expected
+ } finally {
+ datagramSocket.close();
+ }
+
+ }
+
+ public void test_setSendBufferSizeI() throws Exception {
+ final DatagramSocket ds = new DatagramSocket(0);
+ ds.setSendBufferSize(134);
+ assertTrue("Incorrect buffer size", ds.getSendBufferSize() >= 134);
+ ds.close();
+ try {
+ ds.setSendBufferSize(1);
+ fail("SocketException was not thrown.");
+ } catch(SocketException se) {
+ //expected
+ }
+ }
+
+ public void test_setReceiveBufferSizeI() throws Exception {
+ final DatagramSocket ds = new DatagramSocket(0);
+ ds.setReceiveBufferSize(130);
+ assertTrue("Incorrect buffer size", ds.getReceiveBufferSize() >= 130);
+
+ try {
+ ds.setReceiveBufferSize(0);
+ fail("IllegalArgumentException was not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ ds.setReceiveBufferSize(-1);
+ fail("IllegalArgumentException was not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ ds.close();
+
+ try {
+ ds.setReceiveBufferSize(1);
+ fail("SocketException was not thrown.");
+ } catch (SocketException e) {
+ //expected
+ }
+ }
+
+
+ public void test_ConstructorLjava_net_DatagramSocketImpl() {
+ class SimpleTestDatagramSocket extends DatagramSocket {
+ public SimpleTestDatagramSocket(DatagramSocketImpl impl) {
+ super(impl);
+ }
+ }
+
+ try {
+ new SimpleTestDatagramSocket(null);
+ fail("exception expected");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
+ public void test_ConstructorLjava_net_SocketAddress() throws Exception {
+ class UnsupportedSocketAddress extends SocketAddress {
+ public UnsupportedSocketAddress() {
+ }
+ }
+
+ DatagramSocket ds = new DatagramSocket(new InetSocketAddress(
+ InetAddress.getLocalHost(), 0));
+ assertTrue(ds.getBroadcast());
+ assertTrue("Created socket with incorrect port", ds.getLocalPort() != 0);
+ assertEquals("Created socket with incorrect address", InetAddress
+ .getLocalHost(), ds.getLocalAddress());
+
+ try {
+ ds = new java.net.DatagramSocket(new UnsupportedSocketAddress());
+ fail("No exception when constructing datagramSocket with unsupported SocketAddress type");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // regression for HARMONY-894
+ ds = new DatagramSocket(null);
+ assertTrue(ds.getBroadcast());
+ }
+
+
+ public void test_bindLjava_net_SocketAddress_null() throws Exception {
+ // validate if we pass in null that it picks an address for us.
+ DatagramSocket theSocket = new DatagramSocket((SocketAddress) null);
+ theSocket.bind(null);
+ assertNotNull(theSocket.getLocalSocketAddress());
+ theSocket.close();
+ }
+
+ public void test_bindLjava_net_SocketAddress_address_in_use() throws Exception {
+ DatagramSocket socket1 = new DatagramSocket(0);
+ try {
+ new DatagramSocket(socket1.getLocalPort());
+ fail();
+ } catch (SocketException expected) {
+ }
+ socket1.close();
+ }
+
+ public void test_bindLjava_net_SocketAddress_unsupported_address_type() throws Exception {
+ class mySocketAddress extends SocketAddress {
+ public mySocketAddress() {
+ }
+ }
+
+ // unsupported SocketAddress subclass
+ DatagramSocket theSocket = new DatagramSocket((SocketAddress) null);
+ try {
+ theSocket.bind(new mySocketAddress());
+ fail("No exception when binding using unsupported SocketAddress subclass");
+ } catch (IllegalArgumentException expected) {
+ }
+ theSocket.close();
+ }
+
+ public void test_isBound() throws Exception {
+ DatagramSocket theSocket = new DatagramSocket(0);
+ assertTrue(theSocket.isBound());
+ theSocket.close();
+
+ theSocket = new DatagramSocket(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
+ assertTrue(theSocket.isBound());
+ theSocket.close();
+
+ theSocket = new DatagramSocket(null);
+ assertFalse(theSocket.isBound());
+ theSocket.close();
+
+ // connect causes implicit bind
+ theSocket = new DatagramSocket(null);
+ theSocket.connect(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
+ assertTrue(theSocket.isBound());
+ theSocket.close();
+
+ // now test when we bind explicitely
+ InetSocketAddress theLocalAddress = new InetSocketAddress(Inet6Address.LOOPBACK, 0);
+ theSocket = new DatagramSocket(null);
+ assertFalse(theSocket.isBound());
+ theSocket.bind(theLocalAddress);
+ assertTrue(theSocket.isBound());
+ theSocket.close();
+ assertTrue(theSocket.isBound());
+ }
+
+ public void test_isConnected() throws Exception {
+ DatagramServer ds = new DatagramServer(Inet6Address.LOOPBACK);
+
+ // base test
+ DatagramSocket theSocket = new DatagramSocket(0);
+ assertFalse(theSocket.isConnected());
+ theSocket.connect(new InetSocketAddress(Inet6Address.LOOPBACK, ds.getPort()));
+ assertTrue(theSocket.isConnected());
+
+ // reconnect the socket and make sure we get the right answer
+ theSocket.connect(new InetSocketAddress(Inet6Address.LOOPBACK, ds.getPort()));
+ assertTrue(theSocket.isConnected());
+
+ // now disconnect the socket and make sure we get the right answer
+ theSocket.disconnect();
+ assertFalse(theSocket.isConnected());
+ theSocket.close();
+
+ // now check behavior when socket is closed when connected
+ theSocket = new DatagramSocket(0);
+ theSocket.connect(new InetSocketAddress(Inet6Address.LOOPBACK, ds.getPort()));
+ theSocket.close();
+ assertTrue(theSocket.isConnected());
+ }
+
+ public void test_getRemoteSocketAddress() throws Exception {
+ DatagramServer server = new DatagramServer(Inet6Address.LOOPBACK);
+ DatagramSocket s = new DatagramSocket(0);
+ s.connect(new InetSocketAddress(Inet6Address.LOOPBACK, server.getPort()));
+
+ assertEquals(new InetSocketAddress(Inet6Address.LOOPBACK, server.getPort()),
+ s.getRemoteSocketAddress());
+ s.close();
+
+ // now create one that is not connected and validate that we get the
+ // right answer
+ DatagramSocket theSocket = new DatagramSocket(null);
+ theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ assertNull(theSocket.getRemoteSocketAddress());
+
+ // now connect and validate we get the right answer
+ theSocket.connect(new InetSocketAddress(Inet6Address.LOOPBACK, server.getPort()));
+ assertEquals(new InetSocketAddress(Inet6Address.LOOPBACK, server.getPort()),
+ theSocket.getRemoteSocketAddress());
+ theSocket.close();
+ }
+
+ public void test_getLocalSocketAddress_late_bind() throws Exception {
+ // An unbound socket should return null as its local address.
+ DatagramSocket theSocket = new DatagramSocket((SocketAddress) null);
+ assertNull(theSocket.getLocalSocketAddress());
+
+ // now bind the socket and make sure we get the right answer
+ InetSocketAddress localAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ theSocket.bind(localAddress);
+ assertEquals(localAddress.getAddress(), theSocket.getLocalAddress());
+ assertTrue(theSocket.getLocalPort() > 0);
+ theSocket.close();
+ }
+
+ public void test_getLocalSocketAddress_unbound() throws Exception {
+ InetSocketAddress localAddress1 = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ DatagramSocket s = new DatagramSocket(localAddress1);
+ assertEquals(localAddress1.getAddress(), s.getLocalAddress());
+ s.close();
+
+ InetSocketAddress remoteAddress = (InetSocketAddress) s.getRemoteSocketAddress();
+ assertNull(remoteAddress);
+ }
+
+ public void test_getLocalSocketAddress_ANY() throws Exception {
+ DatagramSocket s = new DatagramSocket(0);
+ try {
+ assertTrue("ANY address not IPv6: " + s.getLocalSocketAddress(),
+ ((InetSocketAddress) s.getLocalSocketAddress()).getAddress() instanceof Inet6Address);
+ } finally {
+ s.close();
+ }
+ }
+
+ public void test_setReuseAddressZ() throws Exception {
+ // test case were we set it to false
+ DatagramSocket theSocket1 = null;
+ DatagramSocket theSocket2 = null;
+ try {
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ theSocket1 = new DatagramSocket(null);
+ theSocket2 = new DatagramSocket(null);
+ theSocket1.setReuseAddress(false);
+ theSocket2.setReuseAddress(false);
+ theSocket1.bind(theAddress);
+ theSocket2.bind(new InetSocketAddress(InetAddress.getLocalHost(), theSocket1.getLocalPort()));
+ fail();
+ } catch (BindException expected) {
+ }
+ if (theSocket1 != null) {
+ theSocket1.close();
+ }
+ if (theSocket2 != null) {
+ theSocket2.close();
+ }
+
+ // test case were we set it to true
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ theSocket1 = new DatagramSocket(null);
+ theSocket2 = new DatagramSocket(null);
+ theSocket1.setReuseAddress(true);
+ theSocket2.setReuseAddress(true);
+ theSocket1.bind(theAddress);
+ theSocket2.bind(new InetSocketAddress(InetAddress.getLocalHost(), theSocket1.getLocalPort()));
+
+ if (theSocket1 != null) {
+ theSocket1.close();
+ }
+ if (theSocket2 != null) {
+ theSocket2.close();
+ }
+
+ // test the default case which we expect to be the same on all
+ // platforms
+ try {
+ theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ theSocket1 = new DatagramSocket(null);
+ theSocket2 = new DatagramSocket(null);
+ theSocket1.bind(theAddress);
+ theSocket2.bind(new InetSocketAddress(InetAddress.getLocalHost(), theSocket1.getLocalPort()));
+ fail("No exception when trying to connect to do duplicate socket bind with re-useaddr left as default");
+ } catch (BindException expected) {
+ }
+ if (theSocket1 != null) {
+ theSocket1.close();
+ }
+ if (theSocket2 != null) {
+ theSocket2.close();
+ }
+
+ try {
+ theSocket1.setReuseAddress(true);
+ fail("SocketException was not thrown.");
+ } catch(SocketException se) {
+ //expected
+ }
+ }
+
+ public void test_getReuseAddress() throws Exception {
+ DatagramSocket theSocket = new DatagramSocket();
+ theSocket.setReuseAddress(true);
+ assertTrue("getReuseAddress false when it should be true", theSocket.getReuseAddress());
+ theSocket.setReuseAddress(false);
+ assertFalse("getReuseAddress true when it should be False", theSocket.getReuseAddress());
+ theSocket.close();
+ try {
+ theSocket.getReuseAddress();
+ fail("SocketException was not thrown.");
+ } catch(SocketException se) {
+ //expected
+ }
+ }
+
+ public void test_setBroadcastZ() throws Exception {
+ DatagramSocket theSocket = new DatagramSocket(0);
+ theSocket.setBroadcast(false);
+ byte theBytes[] = { -1, -1, -1, -1 };
+
+ // validate we cannot connect to the broadcast address when
+ // setBroadcast is false
+ try {
+ theSocket.connect(new InetSocketAddress(InetAddress.getByAddress(theBytes), 0));
+ fail();
+ } catch (Exception expected) {
+ }
+
+ // now validate that we can connect to the broadcast address when
+ // setBroadcast is true
+ theSocket.setBroadcast(true);
+ theSocket.connect(new InetSocketAddress(InetAddress.getByAddress(theBytes), 0));
+
+ theSocket.close();
+ try {
+ theSocket.setBroadcast(false);
+ fail();
+ } catch(SocketException se) {
+ //expected
+ }
+ }
+
+ public void test_getBroadcast() throws Exception {
+ DatagramSocket theSocket = new DatagramSocket();
+ theSocket.setBroadcast(true);
+ assertTrue("getBroadcast false when it should be true", theSocket.getBroadcast());
+ theSocket.setBroadcast(false);
+ assertFalse("getBroadcast true when it should be False", theSocket.getBroadcast());
+ }
+
+ public void test_setTrafficClassI() throws Exception {
+ int IPTOS_LOWCOST = 0x2;
+ int IPTOS_THROUGHPUT = 0x8;
+ DatagramSocket theSocket = new DatagramSocket(0);
+
+ // validate that value set must be between 0 and 255
+ try {
+ theSocket.setTrafficClass(256);
+ fail("No exception when traffic class set to 256");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ theSocket.setTrafficClass(-1);
+ fail("No exception when traffic class set to -1");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // now validate that we can set it to some good values
+ theSocket.setTrafficClass(IPTOS_LOWCOST);
+ theSocket.setTrafficClass(IPTOS_THROUGHPUT);
+ }
+
+
+ public void test_isClosed() throws Exception {
+ DatagramSocket theSocket = new DatagramSocket();
+ // validate isClosed returns expected values
+ assertFalse(theSocket.isClosed());
+ theSocket.close();
+ assertTrue(theSocket.isClosed());
+
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 0);
+ theSocket = new DatagramSocket(theAddress);
+ assertFalse(theSocket.isClosed());
+ theSocket.close();
+ assertTrue(theSocket.isClosed());
+ }
+
+ public void test_getChannel() throws Exception {
+ assertNull(new DatagramSocket().getChannel());
+
+ DatagramServer server = new DatagramServer(Inet6Address.LOOPBACK);
+ DatagramSocket ds = new DatagramSocket(0);
+ assertNull(ds.getChannel());
+ ds.disconnect();
+ ds.close();
+ server.stopServer();
+
+ DatagramChannel channel = DatagramChannel.open();
+ DatagramSocket socket = channel.socket();
+ assertEquals(channel, socket.getChannel());
+ socket.close();
+ }
+
+ public void testReceiveOversizePacket() throws Exception {
+ DatagramSocket ds = new DatagramSocket(0);
+ DatagramSocket sds = new DatagramSocket(0);
+
+ DatagramPacket rdp = new DatagramPacket("0123456789".getBytes("UTF-8"),
+ 5, Inet6Address.LOOPBACK, ds.getLocalPort());
+ sds.send(rdp);
+ sds.close();
+
+ byte[] recvBuffer = new byte[5];
+ DatagramPacket receive = new DatagramPacket(recvBuffer, recvBuffer.length);
+ ds.receive(receive);
+ ds.close();
+ assertEquals(new String("01234"), new String(recvBuffer, 0, recvBuffer.length, "UTF-8"));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/HttpCookieTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/HttpCookieTest.java
new file mode 100644
index 0000000..d1cf18f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/HttpCookieTest.java
@@ -0,0 +1,978 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.harmony.tests.java.net;
+
+import junit.framework.TestCase;
+import java.net.HttpCookie;
+import java.util.List;
+import java.util.Locale;
+
+public class HttpCookieTest extends TestCase {
+ private Locale locale;
+
+ /**
+ * java.net.HttpCookie(String, String).
+ * @since 1.6
+ */
+ public void test_HttpCookie_LString_LString() {
+ assertNotNull(new HttpCookie("harmony_6", "test,sem"));
+ assertNotNull(new HttpCookie("harmony_6", null));
+ assertNotNull(new HttpCookie("harmony ", null));
+ assertEquals("harmony", new HttpCookie("harmony ", null).getName());
+
+ constructHttpCookie("", null);
+
+ String value = "value";
+ constructHttpCookie("", value);
+
+ constructHttpCookie("harmony,", value);
+ constructHttpCookie("harmony;", value);
+ constructHttpCookie("$harmony", value);
+ constructHttpCookie("n\tame", value);
+ constructHttpCookie("n\rame", value);
+ constructHttpCookie("n\r\name", value);
+ constructHttpCookie("Comment", value);
+ constructHttpCookie("CommentURL", value);
+ constructHttpCookie("Domain", value);
+ constructHttpCookie("Discard", value);
+ constructHttpCookie("Max-Age", value);
+ constructHttpCookie(" Path ", value);
+ constructHttpCookie("Port ", value);
+ constructHttpCookie("SeCure", value);
+ constructHttpCookie("VErsion", value);
+ constructHttpCookie("expires", value);
+ constructHttpCookie("na\u0085me", value);
+ constructHttpCookie("\u2028me", value);
+ constructHttpCookie("na\u2029me", value);
+
+ try {
+ new HttpCookie(null, value);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new HttpCookie("\u007f", value);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ HttpCookie cookie = new HttpCookie("harmony!", null);
+ assertEquals("harmony!", cookie.getName());
+
+ cookie = new HttpCookie("harmon$y", null);
+ assertEquals("harmon$y", cookie.getName());
+
+ }
+
+ private static void constructHttpCookie(String name, String value) {
+ try {
+ new HttpCookie(name, value);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.net.HttpCookie#domainMatches(String, String).
+ * @since 1.6
+ */
+ public void test_DomainMatches() {
+
+ /*
+ * Rule 1: A host isn't in a domain (RFC 2965 sec. 3.3.2) if: The value
+ * for the Domain attribute contains no embedded dots, and the value is
+ * not .local.
+ */
+ boolean match = HttpCookie.domainMatches("hostname", "hostname");
+ assertFalse(match);
+
+ match = HttpCookie.domainMatches(".com", "test.com");
+ assertFalse(match);
+
+ match = HttpCookie.domainMatches(".com.", "test.com");
+ assertFalse(match);
+
+ // During comparison, host name is transformed to effective host name
+ // first.
+ match = HttpCookie.domainMatches(".local", "hostname");
+ assertTrue(match);
+
+ /*
+ * Rule 3: The request-host is a HDN (not IP address) and has the form
+ * HD, where D is the value of the Domain attribute, and H is a string
+ * that contains one or more dots.
+ */
+ match = HttpCookie.domainMatches(".c.d", "a.b.c.d");
+ assertTrue(match);
+
+ match = HttpCookie.domainMatches("c.d", "a.b.c.d");
+ assertFalse(match);
+
+ match = HttpCookie.domainMatches(".foo.com", "y.x.foo.com");
+ assertTrue(match);
+
+ match = HttpCookie.domainMatches(".foo.com", "x.foo.com");
+ assertTrue(match);
+
+ match = HttpCookie.domainMatches(".local", "hostname.local");
+ assertTrue(match);
+
+ match = HttpCookie.domainMatches(".ajax.com", "a.ajax.com");
+ assertTrue(match);
+
+ match = HttpCookie.domainMatches(".ajax.com", "a.AJAX.com");
+ assertTrue(match);
+
+ match = HttpCookie.domainMatches("...", "test...");
+ assertFalse(match);
+
+ match = HttpCookie.domainMatches(".ajax.com", "b.a.AJAX.com");
+ assertTrue(match);
+
+ match = HttpCookie.domainMatches(".a", "b.a");
+ assertFalse(match);
+
+ // when either parameter is null
+ match = HttpCookie.domainMatches(".ajax.com", null);
+ assertFalse(match);
+
+ match = HttpCookie.domainMatches(null, null);
+ assertFalse(match);
+
+ match = HttpCookie.domainMatches(null, "b.a.AJAX.com");
+ assertFalse(match);
+ }
+
+ /**
+ * java.net.HttpCookie#getVersion(), setVersion(int).
+ * @since 1.6
+ */
+ public void test_Get_SetVersion() {
+ HttpCookie cookie = new HttpCookie("name", "value");
+ assertEquals(1, cookie.getVersion());
+ cookie.setVersion(0);
+ assertEquals(0, cookie.getVersion());
+ cookie.setVersion(1);
+ assertEquals(1, cookie.getVersion());
+
+ try {
+ cookie.setVersion(-1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ cookie.setVersion(2);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.net.HttpCookie#getValue(), setValue(String)
+ * @since 1.6
+ */
+ public void test_Get_SetValue() {
+ HttpCookie cookie = new HttpCookie("name", "value");
+ assertEquals("value", cookie.getValue());
+ cookie.setValue("newValue");
+ assertEquals("newValue", cookie.getValue());
+
+ cookie.setValue(null);
+ assertNull(cookie.getValue());
+
+ cookie.setValue("na\u64DEme");
+ assertEquals("na\u64DEme", cookie.getValue());
+ cookie.setVersion(0);
+ cookie.setValue("{(new value, 11)}");
+ assertEquals("{(new value, 11)}", cookie.getValue());
+ }
+
+ /**
+ * java.net.HttpCookie#getName()
+ * @since 1.6
+ */
+ public void test_GetName() {
+ HttpCookie cookie = new HttpCookie("testName", "value");
+ assertEquals("testName", cookie.getName());
+ }
+
+ /**
+ * java.net.HttpCookie#getSecure(), setSecure(boolean)
+ * @since 1.6
+ */
+ public void test_Get_SetSecure() {
+ HttpCookie cookie = new HttpCookie("testName", "value");
+ assertFalse(cookie.getSecure());
+ cookie.setVersion(0);
+ assertFalse(cookie.getSecure());
+
+ cookie.setSecure(true);
+ assertTrue(cookie.getSecure());
+ cookie.setSecure(false);
+ cookie.setVersion(1);
+ assertFalse(cookie.getSecure());
+ }
+
+ /**
+ * java.net.HttpCookie#getPath(), setPath(String)
+ * @since 1.6
+ */
+ public void test_Get_SetPath() {
+ HttpCookie cookie = new HttpCookie("name", "test new value");
+ assertNull(cookie.getPath());
+
+ cookie.setPath("{}() test,; 43!@");
+ assertEquals("{}() test,; 43!@", cookie.getPath());
+
+ cookie.setPath(" test");
+ assertEquals(" test", cookie.getPath());
+
+ cookie.setPath("\u63DF\u64DE");
+ cookie.setDomain("test");
+ assertEquals("\u63DF\u64DE", cookie.getPath());
+ }
+
+ /**
+ * java.net.HttpCookie#getMaxAge(), setMaxAge(long)
+ * @since 1.6
+ */
+ public void test_Get_SetMaxAge() {
+ HttpCookie cookie = new HttpCookie("name", "test new value");
+ assertEquals(-1, cookie.getMaxAge());
+
+ cookie.setMaxAge(Long.MAX_VALUE);
+ assertEquals(Long.MAX_VALUE, cookie.getMaxAge());
+
+ cookie.setMaxAge(Long.MIN_VALUE);
+ cookie.setDiscard(false);
+ assertEquals(Long.MIN_VALUE, cookie.getMaxAge());
+ }
+
+ /**
+ * java.net.HttpCookie#getDomain(), setDomain(String)
+ * @since 1.6
+ */
+ public void test_Get_SetDomain() {
+ HttpCookie cookie = new HttpCookie("name", "test new value");
+ assertNull(cookie.getDomain());
+
+ cookie.setDomain("a.b.d.c.com.");
+ assertEquals("a.b.d.c.com.", cookie.getDomain());
+
+ cookie.setDomain(" a.b.d.c.com. ");
+ assertEquals(" a.b.d.c.com. ", cookie.getDomain());
+
+ cookie.setPath("temp/subTemp");
+ cookie.setDomain("xy.foo.bar.de.edu");
+ assertEquals("xy.foo.bar.de.edu", cookie.getDomain());
+ }
+
+ /**
+ * java.net.HttpCookie#getPortlist(), setPortlist(String)
+ * @since 1.6
+ */
+ public void test_Get_SetPortlist() {
+ HttpCookie cookie = new HttpCookie("cookieName", "cookieName value");
+ assertNull(cookie.getPortlist());
+
+ cookie.setPortlist("80,23,20");
+ assertEquals("80,23,20", cookie.getPortlist());
+ cookie.setPortlist("abcdefg1234567");
+ cookie.setValue("cookie value again");
+ assertEquals("abcdefg1234567", cookie.getPortlist());
+ }
+
+ /**
+ * java.net.HttpCookie#getDiscard(), setDiscard(boolean)
+ * @since 1.6
+ */
+ public void test_Get_SetDiscard() {
+ HttpCookie cookie = new HttpCookie("cookie'sName",
+ "cookie's Test value");
+ assertFalse(cookie.getDiscard());
+
+ cookie.setDiscard(true);
+ assertTrue(cookie.getDiscard());
+ cookie.setDiscard(false);
+ cookie.setMaxAge(-1);
+ assertFalse(cookie.getDiscard());
+ }
+
+ /**
+ * java.net.HttpCookie#getCommentURL(), setCommentURL(String)
+ * @since 1.6
+ */
+ public void test_Get_SetCommentURL() {
+ HttpCookie cookie = new HttpCookie("cookie'\"sName",
+ "cookie's Test value");
+ assertNull(cookie.getCommentURL());
+
+ cookie.setCommentURL("http://www.test.com");
+ assertEquals("http://www.test.com", cookie.getCommentURL());
+
+ cookie.setCommentURL("schema://harmony.test.org");
+ cookie.setComment("just a comment");
+ assertEquals("schema://harmony.test.org", cookie.getCommentURL());
+ }
+
+ /**
+ * java.net.HttpCookie#getComment(), setComment(String)
+ * @since 1.6
+ */
+ public void test_Get_SetComment() {
+ HttpCookie cookie = new HttpCookie("cookie'\"sName?",
+ "cookie's Test??!@# value");
+ assertNull(cookie.getComment());
+
+ cookie.setComment("");
+ assertEquals("", cookie.getComment());
+
+ cookie.setComment("cookie''s @#$!&*()");
+ cookie.setVersion(0);
+ assertEquals("cookie''s @#$!&*()", cookie.getComment());
+ }
+
+ /**
+ * java.net.HttpCookie#hasExpired()
+ * @since 1.6
+ */
+ public void test_HasExpired() {
+ HttpCookie cookie = new HttpCookie("cookie'\"sName123456",
+ "cookie's Test?()!@# value");
+ assertFalse(cookie.hasExpired());
+
+ cookie.setMaxAge(0);
+ assertTrue(cookie.hasExpired());
+
+ cookie.setMaxAge(Long.MAX_VALUE);
+ cookie.setVersion(0);
+ assertFalse(cookie.hasExpired());
+
+ cookie.setMaxAge(Long.MIN_VALUE);
+ cookie.setDiscard(false);
+ assertTrue(cookie.hasExpired());
+
+ cookie.setDiscard(true);
+ cookie.setMaxAge(-1);
+ assertFalse(cookie.hasExpired());
+ }
+
+ /**
+ * java.net.HttpCookie#equals()
+ * @since 1.6
+ */
+ public void test_Equals() {
+ Object obj = new Object();
+ HttpCookie cookie = new HttpCookie("test", "testValue");
+ HttpCookie cookie2 = new HttpCookie("TesT", "TEstValue");
+
+ assertFalse(cookie.equals(obj));
+ assertFalse(cookie.equals(null));
+ assertTrue(cookie2.equals(cookie));
+ assertTrue(cookie.equals(cookie2));
+ assertTrue(cookie.equals(cookie));
+
+ cookie.setDomain(" test");
+ cookie2.setDomain("test");
+ assertFalse(cookie.equals(cookie2));
+ cookie.setDomain("TEST");
+ assertTrue(cookie.equals(cookie2));
+
+ cookie.setPath("temp\\e");
+ assertFalse(cookie.equals(cookie2));
+ cookie2.setPath("temp\\E");
+ assertFalse(cookie.equals(cookie2));
+
+ cookie.setDiscard(true);
+ cookie.setMaxAge(-1234);
+ cookie2.setPath("temp\\e");
+ assertTrue(cookie.equals(cookie2));
+ }
+
+ /**
+ * java.net.HttpCookie#clone()
+ * @since 1.6
+ */
+ public void test_Clone() {
+ HttpCookie cookie = new HttpCookie("test", "testValue");
+ cookie.setMaxAge(33l);
+ cookie.setComment("test comment");
+ HttpCookie cloneCookie = (HttpCookie) cookie.clone();
+ assertNotSame(cloneCookie, cookie);
+ assertEquals("test", cloneCookie.getName());
+ assertEquals(33l, cloneCookie.getMaxAge());
+ assertEquals("test comment", cloneCookie.getComment());
+ }
+
+ /**
+ * java.net.HttpCookie#toString()
+ * @since 1.6
+ */
+ public void test_ToString() {
+ HttpCookie cookie = new HttpCookie("test", "testValue");
+ cookie.setComment("ABCd");
+ cookie.setCommentURL("\u63DF");
+ cookie.setDomain(".B.com");
+ cookie.setDiscard(true);
+ cookie.setMaxAge(Integer.MAX_VALUE);
+ cookie.setPath("temp/22RuTh");
+ cookie.setPortlist("80.562Ab");
+ cookie.setSecure(true);
+ cookie.setVersion(1);
+
+ assertEquals(
+ "test=\"testValue\";$Path=\"temp/22RuTh\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
+ cookie.toString());
+
+ cookie.setPath(null);
+ assertEquals(
+ "test=\"testValue\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
+ cookie.toString());
+ cookie.setComment(null);
+ assertEquals(
+ "test=\"testValue\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
+ cookie.toString());
+ cookie.setPortlist(null);
+ assertEquals("test=\"testValue\";$Domain=\".b.com\"", cookie.toString());
+ cookie.setDomain(null);
+ assertEquals("test=\"testValue\"", cookie.toString());
+
+ cookie.setVersion(0);
+ cookie.setPortlist("80,8000");
+ assertEquals("test=testValue", cookie.toString());
+ }
+
+ /**
+ * java.net.HttpCookie#hashCode()
+ * @since 1.6
+ */
+ public void test_HashCode() {
+ HttpCookie cookie = new HttpCookie("nAmW_1", "value_1");
+ assertEquals(-1052814577, cookie.hashCode());
+
+ cookie.setDomain("a.b.c.de");
+ assertEquals(1222695220, cookie.hashCode());
+
+ cookie.setPath("3kmxiq;1");
+ assertEquals(-675006347, cookie.hashCode());
+ cookie.setPath("3KmxiQ;1");
+ assertEquals(989616181, cookie.hashCode());
+
+ cookie.setValue("Vw0,22_789");
+ assertEquals(989616181, cookie.hashCode());
+ cookie.setComment("comment");
+ assertEquals(989616181, cookie.hashCode());
+
+ cookie.setDomain("");
+ assertEquals(-1285893616, cookie.hashCode());
+ }
+
+ /**
+ * java.net.HttpCookie#parse(String) for exception cases
+ * @since 1.6
+ */
+ public void test_Parse_exception() {
+ try {
+ HttpCookie.parse(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ /*
+ * Please note that Netscape draft specification does not fully conform
+ * to the HTTP header format. Netscape draft does not specify whether
+ * multiple cookies may be sent in one header. Hence, comma character
+ * may be present in unquoted cookie value or unquoted parameter value.
+ * Refer to <a
+ * href="http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.html#parse(java.lang.String,%20int,%20java.lang.String,%20boolean,%20java.lang.String)">
+ * http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.html#parse(java.lang.String,%20int,%20java.lang.String,%20boolean,%20java.lang.String)
+ * </a>
+ */
+ // violates the cookie specification's syntax
+ checkInvalidCookie("invalid cookie name");
+ checkInvalidCookie("Set-Cookie2:");
+ checkInvalidCookie("name");
+ checkInvalidCookie("$name=");
+ checkInvalidCookie("Set-Cookie2:$name=");
+ checkInvalidCookie("Set-Cookie:$");
+ checkInvalidCookie("Set-Cookie");
+
+ // cookie name contains llegal characters
+ checkInvalidCookie("Set-Cookie:n,ame=");
+ checkInvalidCookie("Set-Cookie2:n\name=");
+ checkInvalidCookie("Set-Cookie2:n,ame=");
+ checkInvalidCookie("Set-Cookie2:n\tame=");
+ checkInvalidCookie("Set-Cookie2:n\rame=");
+ checkInvalidCookie("Set-Cookie2:n\r\name=");
+ checkInvalidCookie("Set-Cookie2:na\u0085me=");
+ checkInvalidCookie("Set-Cookie2:na\u2028me=");
+ checkInvalidCookie("Set-Cookie2:na\u2029me=");
+ checkInvalidCookie("Set-Cookie2:=");
+ checkInvalidCookie("Set-Cookie2:name=tes,t");
+
+ // 'CommentURL' is one of the tokens reserved, case-insensitive
+ checkInvalidCookie("Set-Cookie2:COmmentURL=\"lala\"");
+
+ // check value
+ checkInvalidCookie("Set-Cookie2:val,ue");
+ checkInvalidCookie("Set-Cookie2:name=test;comMent=sent,ence");
+ checkInvalidCookie("Set-Cookie2:name=test;comMentUrL=u,rl");
+ checkInvalidCookie("Set-Cookie2:name=test;Discard=fa,lse");
+ checkInvalidCookie("Set-Cookie2:name=test;Disc,ard");
+ checkInvalidCookie("Set-Cookie2:name=test;Domain=u,rl");
+ checkInvalidCookie("Set-Cookie2:name=test;Path=pa,th");
+ checkInvalidCookie("Set-Cookie2:name=test;Secure=se,cure");
+ checkInvalidCookie("Set-Cookie2:name=test;se,cure");
+ checkInvalidCookie("Set-Cookie2:name=test;Max-Age=se,cure");
+ checkInvalidCookie("Set-Cookie2:name=test;Max-Age=");
+ checkInvalidCookie("Set-Cookie2:name=test;Max-Age=max-age");
+ checkInvalidCookie("Set-Cookie2:name=test;Max-Age=1000.0");
+ }
+
+ /**
+ * java.net.HttpCookie#parse(String) for locales other than
+ * Locale.ENGLISH.
+ * @since 1.6
+ */
+ public void test_Parse_locale() {
+ Locale.setDefault(Locale.FRENCH);
+ List<HttpCookie> list = HttpCookie
+ .parse("Set-Cookie:name=test;expires=Thu, 30-Oct-2008 19:14:07 GMT;");
+ HttpCookie cookie = list.get(0);
+ assertTrue(cookie.hasExpired());
+
+ Locale.setDefault(Locale.GERMAN);
+ list = HttpCookie
+ .parse("Set-Cookie:name=test;expires=Sun, 30-Oct-2005 19:14:07 GMT;");
+ cookie = list.get(0);
+ assertTrue(cookie.hasExpired());
+
+ Locale.setDefault(Locale.KOREA);
+ list = HttpCookie
+ .parse("Set-Cookie:name=test;max-age=1234;expires=Sun, 30-Oct-2005 19:14:07 GMT;");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ assertEquals(1234, cookie.getMaxAge());
+ assertFalse(cookie.hasExpired());
+
+ Locale.setDefault(Locale.TAIWAN);
+ list = HttpCookie
+ .parse("Set-Cookie:name=test;max-age=-12345;");
+ cookie = list.get(0);
+ assertEquals(-12345, cookie.getMaxAge());
+ assertTrue(cookie.hasExpired());
+
+ // Locale does not affect version 1 cookie.
+ Locale.setDefault(Locale.ITALIAN);
+ list = HttpCookie.parse("Set-Cookie2:name=test;max-age=1000");
+ cookie = list.get(0);
+ assertEquals(1000, cookie.getMaxAge());
+ assertFalse(cookie.hasExpired());
+ }
+
+ /**
+ * java.net.HttpCookie#parse(String) for normal cases
+ * @since 1.6
+ */
+ public void test_Parse() {
+ List<HttpCookie> list = HttpCookie.parse("test=\"null\"");
+ HttpCookie cookie = list.get(0);
+ // when two '"' presents, the parser ignores it.
+ assertEquals("null", cookie.getValue());
+ assertNull(cookie.getComment());
+ assertNull(cookie.getCommentURL());
+ assertFalse(cookie.getDiscard());
+ assertNull(cookie.getDomain());
+ assertEquals(-1, cookie.getMaxAge());
+ assertNull(cookie.getPath());
+ assertNull(cookie.getPortlist());
+ assertFalse(cookie.getSecure());
+ // default version is 0
+ assertEquals(0, cookie.getVersion());
+
+ list = HttpCookie.parse("Set-cookie2:name=\"tes,t\"");
+ cookie = list.get(0);
+ // when two '"' presents, the parser ignores it.
+ assertEquals("tes,t", cookie.getValue());
+
+ // If cookie header = Set-Cookie2, version = 1
+ list = HttpCookie
+ .parse("Set-cookie2:test=null\";;Port=abde,82;Path=/temp;;;Discard;commentURl=http://harmonytest.org;Max-age=-10;");
+ cookie = list.get(0);
+ assertEquals("null\"", cookie.getValue());
+ assertEquals(1, cookie.getVersion());
+ assertEquals("/temp", cookie.getPath());
+ assertTrue(cookie.getDiscard());
+ assertEquals("http://harmonytest.org", cookie.getCommentURL());
+ assertEquals(-10l, cookie.getMaxAge());
+ assertTrue(cookie.hasExpired());
+ assertEquals("abde,82", cookie.getPortlist());
+ // Version 0 cookie
+ list = HttpCookie
+ .parse("Set-Cookie:name=tes,t;Comment=version1-cookie;Discard=false;commentURL=vers\nion1-cookie-url;Domain=x.y;");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ assertEquals("tes,t", cookie.getValue());
+ assertEquals("name", cookie.getName());
+ assertEquals("version1-cookie", cookie.getComment());
+ assertEquals("vers\nion1-cookie-url", cookie.getCommentURL());
+ assertEquals("x.y", cookie.getDomain());
+ assertTrue(cookie.getDiscard());
+
+ // Check value
+ checkValidValue("Set-Cookie:", "val,ue");
+ checkValidValue("Set-Cookie:", "val\nue");
+ checkValidValue("Set-Cookie:", "value=value");
+ checkValidValue("Set-Cookie2:", "val\nue");
+ checkValidValue("Set-Cookie2:", "val\u2029ue");
+ checkValidValue("Set-Cookie2:", "value=value");
+
+ // Check comment
+ // In RFC 2965 '=' is mandatory, but this is not the case in RI.
+ list = HttpCookie.parse("Set-Cookie:name=tes,t;Comment;");
+ cookie = list.get(0);
+ assertNull(cookie.getComment());
+
+ list = HttpCookie
+ .parse("Set-Cookie:name=tes,t;Comment=sentence;Comment=anotherSentence");
+ cookie = list.get(0);
+ assertEquals("sentence", cookie.getComment());
+
+ // Check CommentURL
+ list = HttpCookie
+ .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la)");
+ cookie = list.get(0);
+ assertEquals("(la,la)", cookie.getCommentURL());
+
+ // Check Domain
+ list = HttpCookie.parse("Set-Cookie:name=test;Domain=a_domain");
+ cookie = list.get(0);
+ assertEquals("a_domain", cookie.getDomain());
+
+ // Check Path
+ list = HttpCookie.parse("Set-Cookie:name=test;PaTh=pa$th");
+ cookie = list.get(0);
+ assertEquals("pa$th", cookie.getPath());
+
+ // Check Max-Age
+ list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=1000");
+ cookie = list.get(0);
+ assertEquals(1000, cookie.getMaxAge());
+
+ list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=-1000");
+ cookie = list.get(0);
+ assertEquals(-1000, cookie.getMaxAge());
+
+ // TODO: Uncomment when Long.parseLong() accepts numbers with a leading +
+ // list = HttpCookie.parse("Set-Cookie:name=test;max-age=+12345;");
+ // cookie = list.get(0);
+ // assertEquals(12345, cookie.getMaxAge());
+
+ list = HttpCookie.parse("Set-Cookie:name=test;max-age=0;");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getMaxAge());
+
+ // Check portlist
+ list = HttpCookie.parse("Set-Cookie:name=tes,t;port");
+ cookie = list.get(0);
+ assertEquals("", cookie.getPortlist());
+
+ list = HttpCookie.parse("Set-Cookie:name=tes,t;port=");
+ cookie = list.get(0);
+ assertEquals("", cookie.getPortlist());
+
+ list = HttpCookie.parse("Set-Cookie:name=tes,t;port=123 345");
+ cookie = list.get(0);
+ assertEquals("123 345", cookie.getPortlist());
+
+ list = HttpCookie.parse("Set-Cookie:name=tes,t;port=123,345");
+ cookie = list.get(0);
+ assertEquals("123,345", cookie.getPortlist());
+
+ // Check Secure
+ list = HttpCookie.parse("Set-Cookie:name=test;secure");
+ cookie = list.get(0);
+ assertTrue(cookie.getSecure());
+
+ list = HttpCookie.parse("Set-Cookie:name=test;secure=fa");
+ cookie = list.get(0);
+ assertTrue(cookie.getSecure());
+ assertFalse(cookie.hasExpired());
+
+ list = HttpCookie.parse("Set-Cookie2:name=test;secure=false");
+ cookie = list.get(0);
+ assertTrue(cookie.getSecure());
+
+ // Check expire
+ list = HttpCookie.parse("Set-Cookie:name=test;expires=2006-10-23");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getMaxAge());
+ assertTrue(cookie.hasExpired());
+
+ // Also recognize invalid date
+ list = HttpCookie
+ .parse("Set-Cookie:name=test;expires=Sun, 29-Feb-1999 19:14:07 GMT");
+ cookie = list.get(0);
+ assertTrue(cookie.getMaxAge() < 0);
+ assertTrue(cookie.hasExpired());
+
+ // Parse multiple cookies
+ list = HttpCookie
+ .parse("Set-Cookie2:name=test;,Set-Cookie2:name2=test2;comment=c234;");
+ cookie = list.get(0);
+ assertEquals("name", cookie.getName());
+ assertEquals(1, cookie.getVersion());
+ assertEquals("test", cookie.getValue());
+ cookie = list.get(1);
+ assertEquals(1, cookie.getVersion());
+ // From the second cookie, the "set-cookie2" header does not take effect
+ assertEquals("Set-Cookie2:name2", cookie.getName());
+ assertEquals("c234", cookie.getComment());
+
+ list = HttpCookie.parse("Set-Cookie2:name=test,name2=test2");
+ assertEquals(1, list.get(0).getVersion());
+ assertEquals(1, list.get(1).getVersion());
+
+ // Must begin with "set-cookie2" header
+ list = HttpCookie.parse("name=test,Set-Cookie2:name2=test2");
+ cookie = list.get(0);
+ assertEquals(1, list.size());
+
+ HttpCookie c = HttpCookie.parse(
+ "Set-cookie:NAME2=VALUE2;path=/t;domain=.b.c;version=1").get(0);
+ assertEquals(1, c.getVersion());
+
+ c = HttpCookie.parse(
+ "Set-cookie2:NAME2=VALUE2;path=/t;domain=.b.c;version=0")
+ .get(0);
+ assertEquals(1, c.getVersion());
+
+ list = HttpCookie.parse("Set-cookie:null=;Domain=null;Port=null");
+ cookie = list.get(0);
+
+ assertNotNull(cookie.getValue());
+ assertNotNull(cookie.getName());
+ assertNotNull(cookie.getDomain());
+ assertNotNull(cookie.getPortlist());
+
+ try {
+ list = HttpCookie
+ .parse("Set-Cookie:a name=tes,t;Commenturl;commentuRL=(la,la);path=hello");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException expected) {
+ }
+
+
+ list = HttpCookie
+ .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la);commentuRL=hello");
+ cookie = list.get(0);
+ assertEquals("(la,la)", cookie.getCommentURL());
+
+ list = HttpCookie
+ .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la); path =hello");
+ cookie = list.get(0);
+ assertEquals("(la,la)", cookie.getCommentURL());
+ assertEquals("hello", cookie.getPath());
+
+ try {
+ list = HttpCookie
+ .parse("a Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la);path=hello");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_Parse_httpOnly() {
+ // Default is !httpOnly.
+ List<HttpCookie> list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42");
+ HttpCookie cookie = list.get(0);
+
+ // Well formed, simple.
+ list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42; HttpOnly");
+ cookie = list.get(0);
+
+ // Well formed, other attributes present.
+ list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly");
+ cookie = list.get(0);
+ assertTrue(cookie.getSecure());
+ assertEquals("/", cookie.getPath());
+
+ // Mangled spacing, casing and attributes that have an (ignored) value.
+ list = HttpCookie.parse("Set-Cookie:SID=31d4d96e407aad42;Path=/;secure=false;httponly=false");
+ cookie = list.get(0);
+ assertTrue(cookie.getSecure());
+ assertEquals("/", cookie.getPath());
+ }
+
+ /**
+ * java.net.HttpCookie#parse(String) for version conflict cases
+ * @since 1.6
+ */
+ public void test_Parse_versionConflict() {
+ // If attribute expires presents, cookie will be recognized as version
+ // 0. No matter header is Set-cookie or Set-cookie2
+ List<HttpCookie> list = HttpCookie
+ .parse("Set-Cookie2:name=;expires=;discard");
+ HttpCookie cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ assertTrue(cookie.getDiscard());
+
+ list = HttpCookie.parse("Set-Cookie: name=value;port=80");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ assertEquals("80", cookie.getPortlist());
+
+ // In Set-Cookie header, max-age does not take effect when expires
+ // exists.
+ list = HttpCookie
+ .parse("Set-Cookie:name=test;expires=Tue, 27-Jan-1998 19:14:07 GMT;Max-Age=1000");
+ cookie = list.get(0);
+ assertTrue(cookie.getMaxAge() < 0);
+ assertTrue(cookie.hasExpired());
+ assertFalse(cookie.getDiscard());
+ // Reverse sequence. max-age takes effect and decides the result of
+ // hasExpired() method.
+ list = HttpCookie
+ .parse("Set-Cookie:name=value;max-age=1000;expires=Tue, 17-Jan-1998 19:14:07 GMT;version=1");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ assertEquals(1000, cookie.getMaxAge());
+ assertFalse(cookie.hasExpired());
+
+ // expires decides the version. Not take Set-cookie header, version into
+ // consideration if expires exists.
+ list = HttpCookie
+ .parse("Set-Cookie2:name=value;max-age=1000;version=1;expires=Tue, 17-Jan-1998 19:07:14 GMT;");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ assertEquals(1000, cookie.getMaxAge());
+ assertFalse(cookie.hasExpired());
+
+ // expires does not cover other version 1 attributes.
+ list = HttpCookie
+ .parse("Set-Cookie2: name=value;expires=Sun, 27-Jan-2018 19:14:07 GMT;comment=mycomment;port=80,8080");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ assertEquals("80,8080", cookie.getPortlist());
+ assertEquals("mycomment", cookie.getComment());
+
+ // When expires does not exist, version takes effect.
+ list = HttpCookie.parse("Set-Cookie:name=test;Version=1");
+ cookie = list.get(0);
+ assertEquals(1, cookie.getVersion());
+ assertEquals(-1, cookie.getMaxAge());
+ list = HttpCookie.parse("Set-Cookie:name=test;vERsion=0;Version=1;versioN=0;vErsIon=1");
+ cookie = list.get(0);
+ assertEquals(1, cookie.getVersion());
+
+ // When expires does not exist, max-age takes effect.
+ list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=11");
+ cookie = list.get(0);
+ assertEquals(1, cookie.getVersion());
+ assertEquals(11, cookie.getMaxAge());
+ // other version 1 attributes does not take effect
+ list = HttpCookie
+ .parse("Set-Cookie:name=test;comment=mycomment;commentURL=url;discard;domain=a.b.com;path=temp;port=79;secure");
+ cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ }
+
+ /**
+ * java.net.HttpCookie#parse(String) on multiple threads
+ * Regression test for HARMONY-6307
+ * @since 1.6
+ */
+ class ParseThread extends Thread {
+ public AssertionError error = null;
+
+ public void run() {
+ try {
+ for (int i = 0; i < 200; i++) {
+ List<HttpCookie> list = HttpCookie.parse("Set-cookie:PREF=test;path=/;domain=.b.c;");
+ assertEquals(1, list.size());
+ HttpCookie cookie = list.get(0);
+ assertEquals(0, cookie.getVersion());
+ assertEquals(".b.c", cookie.getDomain());
+ }
+ } catch (AssertionError e) {
+ error = e;
+ }
+ }
+ }
+
+ public void test_Parse_multipleThreads() throws InterruptedException {
+ ParseThread[] threads = new ParseThread[10];
+ // create threads
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new ParseThread();
+ }
+
+ // start threads
+ for (ParseThread thread : threads) {
+ thread.start();
+ }
+
+ // wait for threads to finish
+ for (ParseThread thread : threads) {
+ thread.join();
+ }
+
+ for (ParseThread thread : threads) {
+ if (thread.error != null) {
+ fail("Assertion thrown in thread " + thread + ": " + thread.error);
+ }
+ }
+ }
+
+ private void checkValidValue(String header, String value) {
+ List<HttpCookie> list = HttpCookie
+ .parse(header + "name=" + value + ";");
+ HttpCookie cookie = list.get(0);
+ assertEquals(value, cookie.getValue());
+ }
+
+ private void checkInvalidCookie(String header) {
+ try {
+ HttpCookie.parse(header);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ // version 0 cookie only takes effect on Locale.ENGLISH
+ locale = Locale.getDefault();
+ Locale.setDefault(Locale.ENGLISH);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ Locale.setDefault(locale);
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/IDNTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/IDNTest.java
new file mode 100644
index 0000000..dfd4d66
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/IDNTest.java
@@ -0,0 +1,156 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.IDN;
+
+import junit.framework.TestCase;
+
+public class IDNTest extends TestCase {
+
+ /**
+ * {@link java.net.IDN#toASCII(String)}
+ * @since 1.6
+ */
+ public void test_ToASCII_LString() {
+ try {
+ IDN.toASCII(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ IDN.toASCII("www.m\uE400kitorppa.edu");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ IDN.toASCII("www.\u672C\uFE73\uFFFF.jp");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals("www.xn--gwtq9nb2a.jp", IDN
+ .toASCII("www.\u65E5\u672C\u5E73.jp"));
+ assertEquals(
+ "www.xn--vckk7bxa0eza9ezc9d.com",
+ IDN
+ .toASCII("www.\u30CF\u30F3\u30C9\u30DC\u30FC\u30EB\u30B5\u30E0\u30BA.com"));
+ assertEquals("www.xn--frgbolaget-q5a.nu", IDN
+ .toASCII("www.f\u00E4rgbolaget.nu"));
+ assertEquals("www.xn--bcher-kva.de", IDN.toASCII("www.b\u00FCcher.de"));
+ assertEquals("www.xn--brndendekrlighed-vobh.com", IDN
+ .toASCII("www.br\u00E6ndendek\u00E6rlighed.com"));
+ assertEquals("www.xn--rksmrgs-5wao1o.se", IDN
+ .toASCII("www.r\u00E4ksm\u00F6rg\u00E5s.se"));
+ assertEquals("www.xn--9d0bm53a3xbzui.com", IDN
+ .toASCII("www.\uC608\uBE44\uAD50\uC0AC.com"));
+ assertEquals("xn--lck1c3crb1723bpq4a.com", IDN
+ .toASCII("\u7406\u5BB9\u30CA\u30AB\u30E0\u30E9.com"));
+ assertEquals("xn--l8je6s7a45b.org", IDN
+ .toASCII("\u3042\u30FC\u308B\u3044\u3093.org"));
+ assertEquals("www.xn--frjestadsbk-l8a.net", IDN
+ .toASCII("www.f\u00E4rjestadsbk.net"));
+ assertEquals("www.xn--mkitorppa-v2a.edu", IDN
+ .toASCII("www.m\u00E4kitorppa.edu"));
+ }
+
+ /**
+ * {@link java.net.IDN#toASCII(String, int)}
+ * @since 1.6
+ */
+ public void test_ToASCII_LString_I() {
+ try {
+ IDN.toASCII("www.br\u00E6ndendek\u00E6rlighed.com",
+ IDN.USE_STD3_ASCII_RULES);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ IDN.toASCII("www.r\u00E4ksm\u00F6rg\u00E5s.se",
+ IDN.USE_STD3_ASCII_RULES);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ IDN.toASCII("www.f\u00E4rjestadsbk.net", IDN.ALLOW_UNASSIGNED
+ | IDN.USE_STD3_ASCII_RULES);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals("www.xn--gwtq9nb2a.jp", IDN.toASCII(
+ "www.\u65E5\u672C\u5E73.jp", 0));
+ assertEquals(
+ "www.xn--vckk7bxa0eza9ezc9d.com",
+ IDN
+ .toASCII(
+ "www.\u30CF\u30F3\u30C9\u30DC\u30FC\u30EB\u30B5\u30E0\u30BA.com",
+ 0));
+ assertEquals("www.xn--frgbolaget-q5a.nu", IDN.toASCII(
+ "www.f\u00E4rgbolaget.nu", IDN.ALLOW_UNASSIGNED));
+ assertEquals("www.xn--bcher-kva.de", IDN.toASCII("www.b\u00FCcher.de",
+ IDN.ALLOW_UNASSIGNED));
+ assertEquals("www.google.com", IDN.toASCII("www.google\u002Ecom",
+ IDN.USE_STD3_ASCII_RULES));
+ }
+
+ /**
+ * {@link java.net.IDN#toUnicode(String)}
+ * @since 1.6
+ */
+ public void test_ToUnicode_LString() {
+ try {
+ IDN.toUnicode(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ assertEquals("", IDN.toUnicode(""));
+ assertEquals("www.bcher.de", IDN.toUnicode("www.bcher.de"));
+ assertEquals("www.b\u00FCcher.de", IDN.toUnicode("www.b\u00FCcher.de"));
+ assertEquals("www.\u65E5\u672C\u5E73.jp", IDN
+ .toUnicode("www.\u65E5\u672C\u5E73.jp"));
+ assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode("www\uFF0Exn--gwtq9nb2a\uFF61jp"));
+ assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode("www.xn--gwtq9nb2a.jp"));
+ }
+
+ /**
+ * {@link java.net.IDN#toUnicode(String, int)}
+ * @since 1.6
+ */
+ public void test_ToUnicode_LString_I() {
+ assertEquals("", IDN.toUnicode("", IDN.ALLOW_UNASSIGNED));
+ assertEquals("www.f\u00E4rgbolaget.nu", IDN.toUnicode(
+ "www.f\u00E4rgbolaget.nu", IDN.USE_STD3_ASCII_RULES));
+ assertEquals("www.r\u00E4ksm\u00F6rg\u00E5s.nu", IDN.toUnicode(
+ "www.r\u00E4ksm\u00F6rg\u00E5s\u3002nu",
+ IDN.USE_STD3_ASCII_RULES));
+ // RI bug. It cannot parse "www.xn--gwtq9nb2a.jp" when
+ // USE_STD3_ASCII_RULES is set.
+ assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode(
+ "www\uFF0Exn--gwtq9nb2a\uFF61jp", IDN.USE_STD3_ASCII_RULES));
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/Inet4AddressTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/Inet4AddressTest.java
new file mode 100644
index 0000000..94df634
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/Inet4AddressTest.java
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.Serializable;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class Inet4AddressTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.Inet4Address#isMulticastAddress()
+ */
+ public void test_isMulticastAddress() throws Exception {
+
+ // Create 2 IP v4 addresses and call "isMulticastAddress()"
+ // result should return true if the first 4 bits of the
+ // address are: 1110, false otherwise
+ // Make 1 address with 1110, and 1 without
+ String addrName = "";
+ addrName = "224.0.0.0"; // a multicast addr 1110 = 224-239
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("Multicast address " + addrName + " not detected.", addr
+ .isMulticastAddress());
+
+ addrName = "239.255.255.255"; // a multicast addr 1110 = 224-239
+ addr = InetAddress.getByName(addrName);
+ assertTrue("Multicast address " + addrName + " not detected.", addr
+ .isMulticastAddress());
+
+ addrName = "42.42.42.42"; // a non-multicast address
+ addr = InetAddress.getByName(addrName);
+ assertTrue("Non multicast address " + addrName
+ + " reporting as a multicast address.", !addr
+ .isMulticastAddress());
+
+ }
+
+ public void test_isAnyLocalAddress() throws Exception {
+ assertTrue(InetAddress.getByName("0.0.0.0").isAnyLocalAddress());
+ assertFalse(InetAddress.getByName("127.0.0.1").isAnyLocalAddress());
+ }
+
+ public void test_isLoopbackAddress() throws Exception {
+ // Create some IP V4 addresses and test if they are local...
+
+ String addrName = "";
+
+ addrName = "127.0.0.0"; // a loopback address should be 127.d.d.d
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("Loopback address " + addrName + " not detected.", addr
+ .isLoopbackAddress());
+
+ addrName = "127.42.42.42"; // a loopback address should be
+ // 127.d.d.d
+ addr = InetAddress.getByName(addrName);
+ assertTrue("Loopback address " + addrName + " not detected.", addr
+ .isLoopbackAddress());
+
+ addrName = "42.42.42.42"; // a loopback address should be
+ // 127.d.d.d
+ addr = InetAddress.getByName(addrName);
+ assertTrue("Address incorrectly " + addrName
+ + " detected as a loopback address.", !addr
+ .isLoopbackAddress());
+ }
+
+ /**
+ * java.net.Inet4Address#isLinkLocalAddress()
+ */
+ public void test_isLinkLocalAddress() throws Exception {
+
+ String addrName = "";
+ // There are no link local addresses for IPv4
+ // We'll test one to ensure we get "false"
+
+ addrName = "42.42.42.42";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 address " + addrName
+ + " incorrectly reporting as a link local address.", !addr
+ .isLinkLocalAddress());
+ }
+
+ /**
+ * java.net.Inet4Address#isSiteLocalAddress()
+ */
+ public void test_isSiteLocalAddress() throws Exception {
+ String addrName = "";
+ // There are no site local addresses for IPv4
+ // We'll test one to ensure we get "false"
+
+ addrName = "42.42.42.42";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 address " + addrName
+ + " incorrectly reporting as a site local address.", !addr
+ .isSiteLocalAddress());
+ }
+
+ /**
+ * java.net.Inet4Address#isMCGlobal()
+ */
+ public void test_isMCGlobal() throws Exception {
+
+ // Create an IPv4 mulitcast address. It should return
+ // false for globabl mutlicast. There are no valid IPv4
+ // global multicast addresses
+
+ String addrName = "";
+ addrName = "224.0.0.0"; // a multicast addr 1110
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 link-local multicast address " + addrName
+ + " incorrectly identified as a global multicast address.",
+ !addr.isMCGlobal());
+
+ addrName = "224.0.0.255"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 link-local multicast address " + addrName
+ + " incorrectly identified as a global multicast address.",
+ !addr.isMCGlobal());
+
+ addrName = "224.0.1.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 global multicast address " + addrName
+ + " not identified as a global multicast address.", addr
+ .isMCGlobal());
+
+ addrName = "238.255.255.255"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 global multicast address " + addrName
+ + " not identified as a global multicast address.", addr
+ .isMCGlobal());
+
+ addrName = "239.0.0.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 reserved multicast address " + addrName
+ + " incorrectly identified as a global multicast address.",
+ !addr.isMCGlobal());
+
+ addrName = "239.191.255.255"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 reserved multicast address " + addrName
+ + " incorrectly identified as a global multicast address.",
+ !addr.isMCGlobal());
+ }
+
+ /**
+ * java.net.Inet4Address#isMCNodeLocal()
+ */
+ public void test_isMCNodeLocal() throws Exception {
+ // Create an IPv4 mulitcast address. It should return
+ // false for node-local mutlicast. There are no valid IPv4
+ // node-local multicast addresses
+
+ String addrName = "";
+ addrName = "224.42.42.42"; // a multicast addr 1110 = 224
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv4 multicast address "
+ + addrName
+ + " incorrectly identified as a node-local multicast address.",
+ !addr.isMCNodeLocal());
+
+ addrName = "239.0.0.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv4 reserved multicast address "
+ + addrName
+ + " incorrectly identified as a node-local multicast address.",
+ !addr.isMCNodeLocal());
+ }
+
+ /**
+ * java.net.Inet4Address#isMCLinkLocal()
+ */
+ public void test_isMCLinkLocal() throws Exception {
+ // Create an IPv4 mulitcast address. It should return
+ // false for link-local mutlicast. There are no valid IPv4
+ // link-local multicast addresses
+
+ String addrName = "";
+ addrName = "224.0.0.0"; // a multicast addr 1110
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 link-local multicast address " + addrName
+ + " not identified as a link-local multicast address.",
+ addr.isMCLinkLocal());
+
+ addrName = "224.0.0.255"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 link-local multicast address " + addrName
+ + " not identified as a link-local multicast address.",
+ addr.isMCLinkLocal());
+
+ addrName = "224.0.1.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv4 global multicast address "
+ + addrName
+ + " incorrectly identified as a link-local multicast address.",
+ !addr.isMCLinkLocal());
+
+ addrName = "239.0.0.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv4 reserved multicast address "
+ + addrName
+ + " incorrectly identified as a link-local multicast address.",
+ !addr.isMCLinkLocal());
+ }
+
+ /**
+ * java.net.Inet4Address#isMCSiteLocal()
+ */
+ public void test_isMCSiteLocal() throws Exception {
+ // Create an IPv4 mulitcast address. It should return
+ // false for site-local mutlicast. There are no valid IPv4
+ // site-local multicast addresses
+
+ String addrName = "";
+ addrName = "240.0.0.0"; // a multicast addr 1110 = 224
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv4 multicast address "
+ + addrName
+ + " incorrectly identified as a site-local multicast address.",
+ !addr.isMCSiteLocal());
+
+ addrName = "239.0.0.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv4 reserved multicast address "
+ + addrName
+ + " incorrectly identified as a site-local multicast address.",
+ !addr.isMCSiteLocal());
+
+ addrName = "239.255.0.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 site-local multicast address " + addrName
+ + " not identified as a site-local multicast address.",
+ addr.isMCSiteLocal());
+
+ addrName = "239.255.255.255"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 site-local multicast address " + addrName
+ + " not identified as a site-local multicast address.",
+ addr.isMCSiteLocal());
+
+ addrName = "239.255.2.2"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 site-local multicast address " + addrName
+ + " not identified as a site-local multicast address.",
+ addr.isMCSiteLocal());
+ }
+
+ /**
+ * java.net.Inet4Address#isMCOrgLocal()
+ */
+ public void test_isMCOrgLocal() throws Exception {
+ // Create an IPv4 mulitcast address. It should return
+ // false for organization-local mutlicast. There are no valid IPv4
+ // organization-local multicast addresses
+
+ String addrName = "";
+
+ addrName = "239.191.255.255"; // a multicast addr 1110
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv4 reserved multicast address "
+ + addrName
+ + " incorrectly identified as a org-local multicast address.",
+ !addr.isMCOrgLocal());
+
+ addrName = "239.252.0.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv4 site-local multicast address "
+ + addrName
+ + " incorrectly identified as a org-local multicast address.",
+ !addr.isMCOrgLocal());
+
+ addrName = "239.192.0.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 org-local multicast address " + addrName
+ + " not identified as a org-local multicast address.", addr
+ .isMCOrgLocal());
+
+ addrName = "239.195.255.255"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 org-local multicast address " + addrName
+ + " not identified as a org-local multicast address.", addr
+ .isMCOrgLocal());
+ }
+
+ // comparator for Inet4Address objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ Inet4Address initAddr = (Inet4Address) initial;
+ Inet4Address desrAddr = (Inet4Address) deserialized;
+
+ byte[] iaAddresss = initAddr.getAddress();
+ byte[] deIAAddresss = desrAddr.getAddress();
+ for (int i = 0; i < iaAddresss.length; i++) {
+ assertEquals(iaAddresss[i], deIAAddresss[i]);
+ }
+ assertEquals(4, deIAAddresss.length);
+ assertEquals(initAddr.getHostName(), desrAddr.getHostName());
+ }
+ };
+
+ /**
+ * serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(Inet4Address.getByName("localhost"),
+ COMPARATOR);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, Inet4Address
+ .getByName("localhost"), COMPARATOR);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/Inet6AddressTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/Inet6AddressTest.java
new file mode 100644
index 0000000..77b8405
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/Inet6AddressTest.java
@@ -0,0 +1,916 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.Serializable;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.util.Locale;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class Inet6AddressTest extends junit.framework.TestCase {
+ public void test_isMulticastAddress() throws Exception {
+
+ String addrName = "";
+ InetAddress addr = null;
+
+ // IP V6 regular multicast and non-multicast tests
+ //
+ // Create 2 IP v6 addresses and call "isMulticastAddress()"
+ // A prefix of "11111111" means that the address is multicast
+ // The first one will be one with the prefix the second without
+
+ addrName = "FFFF::42:42"; // 11111111 = FFFF
+ addr = InetAddress.getByName(addrName);
+ assertTrue("Multicast address " + addrName + " not detected.", addr
+ .isMulticastAddress());
+
+ addrName = "42::42:42"; // an non-multicast address
+ addr = InetAddress.getByName(addrName);
+ assertTrue("Non multicast address " + addrName
+ + " reporting as a multicast address.", !addr
+ .isMulticastAddress());
+
+ // IPv4-compatible IPv6 address tests
+ //
+ // Now create 2 IP v6 addresses that are IP v4 compatable
+ // to IP v6 addresses. The address prefix for a multicast ip v4
+ // address is 1110 for the last 16 bits ::d.d.d.d
+ // We expect these to be false
+
+ addrName = "::224.42.42.42"; // an ipv4 multicast addr 1110 = 224
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 compatable address " + addrName
+ + " reported incorrectly as multicast.", !addr
+ .isMulticastAddress());
+
+ addrName = "::42.42.42.42"; // an ipv4 non-multicast address
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 compatable address " + addrName
+ + " reported incorrectly as multicast.", !addr
+ .isMulticastAddress());
+
+ // IPv4-mapped IPv6 address tests
+ //
+ // Now create 2 IP v6 addresses that are IP v4 compatable
+ // to IP v6 addresses. The address prefix for a multicast ip v4
+ // address is 1110 for the last 16 bits ::FFFF:d.d.d.d
+
+ addrName = "::FFFF:224.42.42.42"; // an ipv4 multicast addr 1110 =
+ // 224
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4-mapped IPv6 multicast address " + addrName
+ + " not detected.", addr.isMulticastAddress());
+
+ addrName = "::FFFF:42.42.42.42"; // an ipv4 non-multicast address
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4-mapped IPv6 non-multicast address " + addrName
+ + " reporting as a multicast address.", !addr
+ .isMulticastAddress());
+ }
+
+ public void test_isAnyLocalAddress() throws Exception {
+
+ String addrName = "";
+ InetAddress addr = null;
+
+ // test to ensure that the unspecified address returns tru
+ addrName = "::0"; // The unspecified address
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "The unspecified (also known as wildcard and any local address) "
+ + addrName + " not detected.", addr
+ .isAnyLocalAddress());
+
+ addrName = "::"; // another form of the unspecified address
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "The unspecified (also known as wildcard and any local address) "
+ + addrName + " not detected.", addr
+ .isAnyLocalAddress());
+
+ addrName = "::1"; // The loopback address
+ addr = InetAddress.getByName(addrName);
+ assertTrue("The addresses " + addrName
+ + " incorrectly reporting an the unspecified address.",
+ !addr.isAnyLocalAddress());
+ }
+
+ public void test_isLoopbackAddress() throws Exception {
+
+ String addrName = "";
+ // IP V6 regular address tests for loopback
+ // The loopback address for IPv6 is ::1
+
+ addrName = "::1";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 loopback address " + addrName + " not detected.",
+ addr.isLoopbackAddress());
+
+ addrName = "::2";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 address incorrectly " + addrName
+ + " detected as a loopback address.", !addr
+ .isLoopbackAddress());
+
+ // a loopback address should be 127.d.d.d
+ addrName = "42:42::42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 address incorrectly " + addrName
+ + " detected as a loopback address.", !addr
+ .isLoopbackAddress());
+
+ // IPv4-compatible IPv6 address tests
+ //
+ // Now create 2 IP v6 addresses that are IP v4 compatable
+ // to IP v6 addresses. The address prefix for a multicast ip v4
+ // address is 1110 for the last 16 bits ::d.d.d.d
+ // We expect these to be false, as they are not IPv4 addresses
+
+ // a loopback address should be 127.d.d.d
+ addrName = "::127.0.0.0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4-compatible IPv6 address " + addrName
+ + " detected incorrectly as a loopback.", !addr
+ .isLoopbackAddress());
+
+ addrName = "::127.42.42.42"; // a loopback address should be
+ // 127.d.d.d
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4-compatible IPv6 address " + addrName
+ + " detected incorrectly as a loopback.", !addr
+ .isLoopbackAddress());
+
+ // a loopback address should be 127.d.d.d
+ addrName = "::42.42.42.42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4-compatible IPv6 address " + addrName
+ + " detected incorrectly as a loopback.", !addr
+ .isLoopbackAddress());
+
+ // IPv4-mapped IPv6 address tests
+ //
+ // Now create 2 IP v6 addresses that are IP v4 compatable
+ // to IP v6 addresses. The address prefix for a multicast ip v4
+ // address is 1110 for the last 16 bits ::FFFF:d.d.d.d
+
+ // a loopback address should be 127.d.d.d
+ addrName = "::FFFF:127.0.0.0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4-compatible IPv6 loopback address " + addrName
+ + " not detected.", addr.isLoopbackAddress());
+
+ // a loopback address should be 127.d.d.d
+ addrName = "::FFFF:127.42.42.42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4-compatible IPv6 loopback address " + addrName
+ + " not detected.", addr.isLoopbackAddress());
+
+ // a loopback address should be 127.d.d.d
+ addrName = "::FFFF:42.42.42.42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4-compatible IPv6 address incorrectly " + addrName
+ + " detected as a loopback address.", !addr
+ .isLoopbackAddress());
+ }
+
+ public void test_isLinkLocalAddress() throws Exception {
+
+ String addrName = "";
+ // IP V6 regular address tests for link local addresses
+ //
+ // Link local addresses are FE80:: -
+ // FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+
+ addrName = "FE80::0";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 link local address " + addrName + " not detected.",
+ addr.isLinkLocalAddress());
+
+ addrName = "FEBF::FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 link local address " + addrName + " not detected.",
+ addr.isLinkLocalAddress());
+
+ addrName = "FEC0::1";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 address " + addrName
+ + " detected incorrectly as a link local address.", !addr
+ .isLinkLocalAddress());
+
+ addrName = "FD80::1:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 address " + addrName
+ + " detected incorrectly as a link local address.", !addr
+ .isLinkLocalAddress());
+
+ addrName = "FE7F::FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 address " + addrName
+ + " detected incorrectly as a link local address.", !addr
+ .isLinkLocalAddress());
+ }
+
+ public void test_isSiteLocalAddress() throws Exception {
+ String addrName = "";
+
+ // IP V6 regular address tests for link local addresses
+ //
+ // Link local addresses are FEC0::0 through to
+ // FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+
+ addrName = "FEC0::0";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 site local address " + addrName + " not detected.",
+ addr.isSiteLocalAddress());
+
+ addrName = "FEFF::FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 site local address " + addrName + " not detected.",
+ addr.isSiteLocalAddress());
+
+ addrName = "FEBF::FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 address " + addrName
+ + " detected incorrectly as a site local address.", !addr
+ .isSiteLocalAddress());
+
+ addrName = "FFC0::0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 address " + addrName
+ + " detected incorrectly as a site local address.", !addr
+ .isSiteLocalAddress());
+ }
+
+ public void test_isMCGlobal() throws Exception {
+ String addrName = "";
+ // IP V6 regular address tests for Mulitcase Global addresses
+ //
+ // Multicast global addresses are FFxE:/112 where x is
+ // a set of flags, and the addition 112 bits make up
+ // the global address space
+
+ addrName = "FF0E::0";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 global mutlicast address " + addrName
+ + " not detected.", addr.isMCGlobal());
+
+ addrName = "FF0E:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 global multicast address " + addrName
+ + " not detected.", addr.isMCGlobal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFFE::0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 global mutlicast address " + addrName
+ + " not detected.", addr.isMCGlobal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFFE:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 global multicast address " + addrName
+ + " not detected.", addr.isMCGlobal());
+
+ // a sample MC organizational address
+ addrName = "FF08:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 mulitcast organizational " + addrName
+ + " incorrectly indicated as a global address.", !addr
+ .isMCGlobal());
+
+ // a sample MC site address
+ addrName = "FF05:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 mulitcast site address " + addrName
+ + " incorrectly indicated as a global address.", !addr
+ .isMCGlobal());
+
+ // a sample MC link address
+ addrName = "FF02:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 mulitcast link address " + addrName
+ + " incorrectly indicated as a global address.", !addr
+ .isMCGlobal());
+
+ // a sample MC Node
+ addrName = "FF01:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 mulitcast node address " + addrName
+ + " incorrectly indicated as a global address.", !addr
+ .isMCGlobal());
+
+ // IPv4-mapped IPv6 address tests
+ addrName = "::FFFF:224.0.1.0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 global multicast address " + addrName
+ + " not identified as a global multicast address.", addr
+ .isMCGlobal());
+
+ addrName = "::FFFF:238.255.255.255";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 global multicast address " + addrName
+ + " not identified as a global multicast address.", addr
+ .isMCGlobal());
+ }
+
+ public void test_isMCNodeLocal() throws Exception {
+ String addrName = "";
+ // IP V6 regular address tests for Mulitcase node local addresses
+ //
+ // Multicast node local addresses are FFx1:/112 where x is
+ // a set of flags, and the addition 112 bits make up
+ // the global address space
+
+ addrName = "FF01::0";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 node-local mutlicast address " + addrName
+ + " not detected.", addr.isMCNodeLocal());
+
+ addrName = "FF01:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 node-local multicast address " + addrName
+ + " not detected.", addr.isMCNodeLocal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFF1::0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 node-local mutlicast address " + addrName
+ + " not detected.", addr.isMCNodeLocal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFF1:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 node-local multicast address " + addrName
+ + " not detected.", addr.isMCNodeLocal());
+
+ // a sample MC organizational address
+ addrName = "FF08:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 mulitcast organizational address " + addrName
+ + " incorrectly indicated as a node-local address.", !addr
+ .isMCNodeLocal());
+
+ // a sample MC site address
+ addrName = "FF05:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 mulitcast site address " + addrName
+ + " incorrectly indicated as a node-local address.", !addr
+ .isMCNodeLocal());
+
+ // a sample MC link address
+ addrName = "FF02:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 mulitcast link address " + addrName
+ + " incorrectly indicated as a node-local address.", !addr
+ .isMCNodeLocal());
+
+ // a sample MC global address
+ addrName = "FF0E:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 mulitcast node address " + addrName
+ + " incorrectly indicated as a node-local address.", !addr
+ .isMCNodeLocal());
+ }
+
+ public void test_isMCLinkLocal() throws Exception {
+ String addrName = "";
+ // IP V6 regular address tests for Mulitcase link local addresses
+ //
+ // Multicast link local addresses are FFx2:/112 where x is
+ // a set of flags, and the addition 112 bits make up
+ // the global address space
+
+ addrName = "FF02::0";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 link local multicast address " + addrName
+ + " not detected.", addr.isMCLinkLocal());
+
+ addrName = "FF02:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 link local multicast address " + addrName
+ + " not detected.", addr.isMCLinkLocal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFF2::0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 link local multicast address " + addrName
+ + " not detected.", addr.isMCLinkLocal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFF2:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 link local multicast address " + addrName
+ + " not detected.", addr.isMCLinkLocal());
+
+ // a sample MC organizational address
+ addrName = "FF08:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 organization multicast address "
+ + addrName
+ + " incorrectly indicated as a link-local mulitcast address.",
+ !addr.isMCLinkLocal());
+
+ // a sample MC site address
+ addrName = "FF05:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 site-local mulitcast address "
+ + addrName
+ + " incorrectly indicated as a link-local mulitcast address.",
+ !addr.isMCLinkLocal());
+
+ // a sample MC global address
+ addrName = "FF0E:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 global multicast address "
+ + addrName
+ + " incorrectly indicated as a link-local mulitcast address.",
+ !addr.isMCLinkLocal());
+
+ // a sample MC Node
+ addrName = "FF01:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 mulitcast node address "
+ + addrName
+ + " incorrectly indicated as a link-local mulitcast address.",
+ !addr.isMCLinkLocal());
+
+ // Ipv4-mapped IPv6 addresses
+
+ addrName = "::FFFF:224.0.0.0"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 link-local multicast address " + addrName
+ + " not identified as a link-local multicast address.",
+ addr.isMCLinkLocal());
+
+ addrName = "::FFFF:224.0.0.255"; // a multicast addr 1110
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 link-local multicast address " + addrName
+ + " not identified as a link-local multicast address.",
+ addr.isMCLinkLocal());
+ }
+
+ public void test_isMCSiteLocal() throws Exception {
+ String addrName = "";
+ // IP V6 regular address tests for Multicast site-local addresses
+ //
+ // Multicast global addresses are FFx5:/112 where x is
+ // a set of flags, and the addition 112 bits make up
+ // the global address space
+
+ addrName = "FF05::0";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 site-local mutlicast address " + addrName
+ + " not detected.", addr.isMCSiteLocal());
+
+ addrName = "FF05:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 site-local multicast address " + addrName
+ + " not detected.", addr.isMCSiteLocal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFF5::0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 site-local mutlicast address " + addrName
+ + " not detected.", addr.isMCSiteLocal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFF5:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 site-local multicast address " + addrName
+ + " not detected.", addr.isMCSiteLocal());
+
+ // a sample MC organizational address
+ addrName = "FF08:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 organization multicast address "
+ + addrName
+ + " incorrectly indicated as a site-local mulitcast address.",
+ !addr.isMCSiteLocal());
+
+ // a sample MC global address
+ addrName = "FF0E:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 global mulitcast address "
+ + addrName
+ + " incorrectly indicated as a site-local mulitcast address.",
+ !addr.isMCSiteLocal());
+
+ // a sample MC link address
+ addrName = "FF02:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 link-local multicast address "
+ + addrName
+ + " incorrectly indicated as a site-local mulitcast address.",
+ !addr.isMCSiteLocal());
+
+ // a sample MC Node
+ addrName = "FF01:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 mulitcast node address "
+ + addrName
+ + " incorrectly indicated as a site-local mulitcast address.",
+ !addr.isMCSiteLocal());
+
+ // IPv4-mapped IPv6 addresses
+ addrName = "::FFFF:239.255.0.0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 site-local multicast address " + addrName
+ + " not identified as a site-local multicast address.",
+ addr.isMCSiteLocal());
+
+ addrName = "::FFFF:239.255.255.255";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 site-local multicast address " + addrName
+ + " not identified as a site-local multicast address.",
+ addr.isMCSiteLocal());
+ }
+
+ public void test_isMCOrgLocal() throws Exception {
+ String addrName = "";
+ // IP V6 regular address tests for Mulitcase organization-local
+ // addresses
+ //
+ // Multicast global addresses are FFxE:/112 where x is
+ // a set of flags, and the addition 112 bits make up
+ // the global address space
+
+ addrName = "FF08::0";
+ InetAddress addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 organization-local mutlicast address " + addrName
+ + " not detected.", addr.isMCOrgLocal());
+
+ addrName = "FF08:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 organization-local multicast address " + addrName
+ + " not detected.", addr.isMCOrgLocal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFF8::0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 organization-local mutlicast address " + addrName
+ + " not detected.", addr.isMCOrgLocal());
+
+ // a currently invalid address as the prefix FFxE
+ // is only valid for x = {1,0} as the rest are reserved
+ addrName = "FFF8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv6 organization-local multicast address " + addrName
+ + " not detected.", addr.isMCOrgLocal());
+
+ // a sample MC global address
+ addrName = "FF0E:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 global multicast address "
+ + addrName
+ + " incorrectly indicated as an organization-local mulitcast address.",
+ !addr.isMCOrgLocal());
+
+ // a sample MC site address
+ addrName = "FF05:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 site-local mulitcast address "
+ + addrName
+ + " incorrectly indicated as an organization-local mulitcast address.",
+ !addr.isMCOrgLocal());
+
+ // a sample MC link address
+ addrName = "FF02:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 link-local multicast address "
+ + addrName
+ + " incorrectly indicated as an organization-local mulitcast address.",
+ !addr.isMCOrgLocal());
+
+ // a sample MC Node
+ addrName = "FF01:42:42:42:42:42:42:42";
+ addr = InetAddress.getByName(addrName);
+ assertTrue(
+ "IPv6 mulitcast node address "
+ + addrName
+ + " incorrectly indicated as an organization-local mulitcast address.",
+ !addr.isMCOrgLocal());
+
+ // IPv4-mapped IPv6 addresses
+
+ addrName = "::FFFF:239.192.0.0";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 org-local multicast address " + addrName
+ + " not identified as a org-local multicast address.", addr
+ .isMCOrgLocal());
+
+ addrName = "::FFFF:239.195.255.255";
+ addr = InetAddress.getByName(addrName);
+ assertTrue("IPv4 org-local multicast address " + addrName
+ + " not identified as a org-local multicast address.", addr
+ .isMCOrgLocal());
+ }
+
+ public void test_isIPv4CompatibleAddress() throws Exception {
+ String addrName = "";
+ Inet6Address addr = null;
+
+ // Tests a number of addresses to see if they are compatable with
+ // IPv6 addresses
+
+ addrName = "FFFF::42:42"; // 11111111 = FFFF
+ addr = (Inet6Address) InetAddress.getByName(addrName);
+ assertTrue("A non-compatable IPv6 address " + addrName
+ + " incorrectly identified as a IPv4 compatable address.",
+ !addr.isIPv4CompatibleAddress());
+
+ // IPv4-compatible IPv6 address tests
+ //
+ // Now create 2 IP v6 addresses that are IP v4 compatable
+ // to IP v6 addresses.
+
+ addrName = "::0.0.0.0";
+ addr = (Inet6Address) InetAddress.getByName(addrName);
+ assertTrue("IPv4 compatable address " + addrName
+ + " not detected correctly.", addr
+ .isIPv4CompatibleAddress());
+
+ addrName = "::255.255.255.255"; // an ipv4 non-multicast address
+ addr = (Inet6Address) InetAddress.getByName(addrName);
+ assertTrue("IPv4 compatable address " + addrName
+ + " not detected correctly.", addr
+ .isIPv4CompatibleAddress());
+ }
+
+ public void test_getByNameLjava_lang_String() throws Exception {
+ // ones to add "::255.255.255.255", "::FFFF:0.0.0.0",
+ // "0.0.0.0.0.0::255.255.255.255", "F:F:F:F:F:F:F:F",
+ // "[F:F:F:F:F:F:F:F]"
+ String validIPAddresses[] = { "::1.2.3.4", "::", "::", "1::0", "1::",
+ "::1", "0", /* jdk1.5 accepts 0 as valid */
+ "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF",
+ "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255",
+ "0:0:0:0:0:0:0:0", "0:0:0:0:0:0:0.0.0.0" };
+
+ String invalidIPAddresses[] = { "FFFF:FFFF" };
+
+ for (int i = 0; i < validIPAddresses.length; i++) {
+
+ InetAddress.getByName(validIPAddresses[i]);
+
+ //exercise positive cache
+ InetAddress.getByName(validIPAddresses[i]);
+
+ if (!validIPAddresses[i].equals("0")) {
+ String tempIPAddress = "[" + validIPAddresses[i] + "]";
+ InetAddress.getByName(tempIPAddress);
+ }
+ }
+
+ for (int i = 0; i < invalidIPAddresses.length; i++) {
+ try {
+ InetAddress.getByName(invalidIPAddresses[i]);
+ fail("Invalid IP address incorrectly recognized as valid: "
+ + invalidIPAddresses[i]);
+ } catch (Exception e) {
+ }
+
+ //exercise negative cache
+ try {
+ InetAddress.getByName(invalidIPAddresses[i]);
+ fail("Invalid IP address incorrectly recognized as valid: "
+ + invalidIPAddresses[i]);
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ public void test_getByAddressLString$BI() throws UnknownHostException {
+ try {
+ Inet6Address.getByAddress("123", null, 0);
+ fail("should throw UnknownHostException");
+ } catch (UnknownHostException uhe) {
+ // expected
+ }
+ byte[] addr1 = { (byte) 127, 0, 0, 1 };
+ try {
+ Inet6Address.getByAddress("123", addr1, 0);
+ fail("should throw UnknownHostException");
+ } catch (UnknownHostException uhe) {
+ // expected
+ }
+
+ byte[] addr2 = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02,
+ 0x11, 0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte) 0x7C,
+ (byte) 0xB2 };
+
+ // should not throw any exception
+ Inet6Address.getByAddress("123", addr2, 3);
+ Inet6Address.getByAddress("123", addr2, 0);
+ Inet6Address.getByAddress("123", addr2, -1);
+ }
+
+ public void test_getByAddressLString$BLNetworkInterface()
+ throws UnknownHostException {
+ NetworkInterface nif = null;
+ try {
+ Inet6Address.getByAddress("123", null, nif);
+ fail("should throw UnknownHostException");
+ } catch (UnknownHostException uhe) {
+ // expected
+ }
+ byte[] addr1 = { (byte) 127, 0, 0, 1 };
+ try {
+ Inet6Address.getByAddress("123", addr1, nif);
+ fail("should throw UnknownHostException");
+ } catch (UnknownHostException uhe) {
+ // expected
+ }
+ byte[] addr2 = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02,
+ 0x11, 0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte)
+
+ 0x7C, (byte) 0xB2 };
+ // should not throw any exception
+ Inet6Address.getByAddress("123", addr2, nif);
+ }
+
+ public void test_getHostAddress_() throws Exception {
+ byte[] ipAddress = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+ InetAddress ia = InetAddress.getByAddress(ipAddress);
+ assertEquals("::1", ia.getHostAddress().toLowerCase(Locale.US));
+
+ ipAddress = new byte[] { -2, -128, 0, 0, 0, 0, 0, 0, 2, 17, 37, -1, -2, -8, 124, -79 };
+ ia = InetAddress.getByAddress(ipAddress);
+ assertEquals("fe80::211:25ff:fef8:7cb1", ia.getHostAddress().toLowerCase(Locale.US));
+ }
+
+ public void test_getScopeID() throws UnknownHostException {
+ Inet6Address v6ia;
+ byte[] addr = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x11,
+ 0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte) 0x7C,
+ (byte) 0xB2 };
+
+ v6ia = Inet6Address.getByAddress("123", addr, 3);
+ assertEquals(3, v6ia.getScopeId());
+
+ v6ia = Inet6Address.getByAddress("123", addr, 0);
+ assertEquals(0, v6ia.getScopeId());
+
+ v6ia = Inet6Address.getByAddress("123", addr, -1);
+ assertEquals(0, v6ia.getScopeId());
+ }
+
+ public void test_getScopedInterface() throws UnknownHostException {
+ byte[] addr = { (byte) 0xFE, (byte) 0x80, (byte) 0x09, (byte) 0xb5,
+ (byte) 0x6b, (byte) 0xa4, 0, 0, 0, 0, 0, 0, (byte) 0x09,
+ (byte) 0xb5, (byte) 0x6b, (byte) 0xa4 };
+ Inet6Address v6Addr;
+ v6Addr = Inet6Address.getByAddress("123", addr, null);
+ assertNull(v6Addr.getScopedInterface());
+ }
+
+ public void test_hashCode() throws UnknownHostException {
+ byte[] addr = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x11,
+ 0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte) 0x7C,
+ (byte) 0xB2 };
+ Inet6Address address1, address2;
+
+ address1 = Inet6Address.getByAddress("123", addr, 0);
+ address2 = Inet6Address.getByAddress("1234", addr, 0);
+ assertEquals(address1.hashCode(), address2.hashCode());
+ }
+
+ int bytesToInt(byte bytes[], int start) {
+
+ int byteMask = 255;
+ int value = ((bytes[start + 3] & byteMask))
+ | ((bytes[start + 2] & byteMask) << 8)
+ | ((bytes[start + 1] & byteMask) << 16)
+ | ((bytes[start] & byteMask) << 24);
+ return value;
+
+ }
+
+ String byteArrayToHexString(byte bytes[], boolean leadingZeros) {
+
+ String fullString = "";
+ int times = bytes.length / 4;
+ int intArray[] = new int[times];
+ for (int i = 0; i < times; i++) {
+ intArray[i] = bytesToInt(bytes, i * 4);
+ }
+
+ return intArrayToHexString(intArray, leadingZeros);
+ }
+
+ void intToBytes(int value, byte bytes[], int start) {
+
+ int byteMask = 255;
+ bytes[start + 3] = (byte) (value & byteMask);
+ bytes[start + 2] = (byte) ((value >> 8) & byteMask);
+ bytes[start + 1] = (byte) ((value >> 16) & byteMask);
+ bytes[start] = (byte) ((value >> 24) & byteMask);
+ }
+
+ String intArrayToHexString(int ints[], boolean leadingZeros) {
+
+ String fullString = "";
+ String tempString;
+ int intsLength = ints.length;
+ for (int i = 0; i < intsLength; i++) {
+ tempString = Integer.toHexString(ints[i]);
+ while (tempString.length() < 4 && leadingZeros) {
+ tempString = "0" + tempString;
+ }
+ if (i + 1 < intsLength) {
+ tempString += ":";
+ }
+ fullString += tempString;
+ }
+
+ return fullString.toUpperCase();
+ }
+
+ // comparator for Inet6Address objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ Inet6Address initAddr = (Inet6Address) initial;
+ Inet6Address desrAddr = (Inet6Address) deserialized;
+
+ byte[] iaAddresss = initAddr.getAddress();
+ byte[] deIAAddresss = desrAddr.getAddress();
+ for (int i = 0; i < iaAddresss.length; i++) {
+ assertEquals(iaAddresss[i], deIAAddresss[i]);
+ }
+ assertEquals(initAddr.getScopeId(), desrAddr.getScopeId());
+ assertEquals(initAddr.getScopedInterface(), desrAddr
+ .getScopedInterface());
+ }
+ };
+
+ /**
+ * Tests serialization/deserialization compatibility with ourselves.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ byte[] localv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+ SerializationTest.verifySelf(InetAddress.getByAddress(localv6),
+ COMPARATOR);
+ }
+
+ /**
+ * Tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ byte[] localv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+ Object[] addresses = { InetAddress.getByAddress(localv6),
+ // Regression for Harmony-1039: ser-form has
+ // null interface name
+ InetAddress.getByAddress(localv6) };
+
+ SerializationTest.verifyGolden(this, addresses, COMPARATOR);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetAddressTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetAddressTest.java
new file mode 100644
index 0000000..42f88c1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetAddressTest.java
@@ -0,0 +1,443 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+
+public class InetAddressTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.InetAddress#getByName(String)
+ */
+ public void test_getByName_exceptionContainsUsefulMessage() {
+ // Related to HARMONY-5784
+ try {
+ InetAddress.getByName("1.2.3.4hello");
+ fail();
+ } catch (UnknownHostException e) {
+ assertTrue(e.getMessage().contains("1.2.3.4hello"));
+ }
+ }
+
+ public void test_equalsLjava_lang_Object() throws Exception {
+ InetAddress ia1 = InetAddress.getByName("localhost");
+ InetAddress ia2 = InetAddress.getByName("::1");
+ assertEquals(ia2, ia1);
+ }
+
+ /**
+ * java.net.InetAddress#getAddress()
+ */
+ public void test_getAddress() throws UnknownHostException {
+ // Test for method byte [] java.net.InetAddress.getAddress()
+ try {
+ InetAddress ia = InetAddress.getByName("127.0.0.1");
+ byte[] caddr = new byte[] { 127, 0, 0, 1 };
+ byte[] addr = ia.getAddress();
+ for (int i = 0; i < addr.length; i++)
+ assertTrue("Incorrect address returned", caddr[i] == addr[i]);
+ } catch (java.net.UnknownHostException e) {
+ }
+
+ byte[] origBytes = new byte[] { 0, 1, 2, 3 };
+ InetAddress address = InetAddress.getByAddress(origBytes);
+ origBytes[0] = -1;
+ byte[] newBytes = address.getAddress();
+ assertSame((byte) 0, newBytes[0]);
+ }
+
+ /**
+ * java.net.InetAddress#getAllByName(java.lang.String)
+ */
+ @SuppressWarnings("nls")
+ public void test_getAllByNameLjava_lang_String() throws Exception {
+ // Test for method java.net.InetAddress []
+ // java.net.InetAddress.getAllByName(java.lang.String)
+ InetAddress[] all = InetAddress.getAllByName("localhost");
+ assertNotNull(all);
+ // Number of aliases depends on individual test machine
+ assertTrue(all.length >= 1);
+ for (InetAddress alias : all) {
+ // Check that each alias has the same hostname. Intentionally not
+ // checking for exact string match.
+ assertTrue(alias.getHostName().startsWith("localhost"));
+ }// end for all aliases
+
+ //Regression for HARMONY-56
+ InetAddress[] ias = InetAddress.getAllByName(null);
+ assertEquals(2, ias.length);
+ for (InetAddress ia : ias) {
+ assertTrue(ia.isLoopbackAddress());
+ }
+ ias = InetAddress.getAllByName("");
+ assertEquals(2, ias.length);
+ for (InetAddress ia : ias) {
+ assertTrue(ia.isLoopbackAddress());
+ }
+
+ // Check that getting addresses by dotted string distinguish
+ // IPv4 and IPv6 subtypes.
+ InetAddress[] list = InetAddress.getAllByName("192.168.0.1");
+ for (InetAddress addr : list) {
+ assertFalse("Expected subclass returned",
+ addr.getClass().equals(InetAddress.class));
+ }
+ }
+
+ /**
+ * java.net.InetAddress#getByName(java.lang.String)
+ */
+ public void test_getByNameLjava_lang_String() throws Exception {
+ // Test for method java.net.InetAddress
+ // java.net.InetAddress.getByName(java.lang.String)
+ InetAddress ia2 = InetAddress.getByName("127.0.0.1");
+
+ // TODO : Test to ensure all the address formats are recognized
+ InetAddress i = InetAddress.getByName("1.2.3");
+ assertEquals("1.2.0.3", i.getHostAddress());
+ i = InetAddress.getByName("1.2");
+ assertEquals("1.0.0.2", i.getHostAddress());
+ i = InetAddress.getByName(String.valueOf(0xffffffffL));
+ assertEquals("255.255.255.255", i.getHostAddress());
+ }
+
+ /**
+ * java.net.InetAddress#getHostAddress()
+ */
+ public void test_getHostAddress() throws Exception {
+ assertEquals("1.2.3.4", InetAddress.getByName("1.2.3.4").getHostAddress());
+ assertEquals("::1", InetAddress.getByName("::1").getHostAddress());
+ }
+
+ /**
+ * java.net.InetAddress#getLocalHost()
+ */
+ public void test_getLocalHost() throws Exception {
+ // Test for method java.net.InetAddress
+ // java.net.InetAddress.getLocalHost()
+
+ // We don't know the host name or ip of the machine
+ // running the test, so we can't build our own address
+ DatagramSocket dg = new DatagramSocket(0, InetAddress
+ .getLocalHost());
+ assertTrue("Incorrect host returned", InetAddress.getLocalHost()
+ .equals(dg.getLocalAddress()));
+ dg.close();
+ }
+
+ /**
+ * java.net.InetAddress#getLocalHost()
+ */
+ public void test_getLocalHost_extended() throws Exception {
+ // Bogus, but we don't know the host name or ip of the machine
+ // running the test, so we can't build our own address
+ DatagramSocket dg = new DatagramSocket(0, InetAddress.getLocalHost());
+ assertEquals("Incorrect host returned", InetAddress.getLocalHost(), dg.getLocalAddress());
+ dg.close();
+ }
+
+ /**
+ * java.net.InetAddress#isMulticastAddress()
+ */
+ public void test_isMulticastAddress() throws UnknownHostException {
+ InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+ assertTrue(ia2.isMulticastAddress());
+ ia2 = InetAddress.getByName("localhost");
+ assertFalse(ia2.isMulticastAddress());
+ }
+
+ /**
+ * java.net.InetAddress#isAnyLocalAddress()
+ */
+ public void test_isAnyLocalAddress() throws UnknownHostException {
+ InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+ assertFalse(ia2.isAnyLocalAddress());
+ ia2 = InetAddress.getByName("localhost");
+ assertFalse(ia2.isAnyLocalAddress());
+ }
+
+ /**
+ * java.net.InetAddress#isLinkLocalAddress()
+ */
+ public void test_isLinkLocalAddress() throws UnknownHostException {
+ InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+ assertFalse(ia2.isLinkLocalAddress());
+ ia2 = InetAddress.getByName("localhost");
+ assertFalse(ia2.isLinkLocalAddress());
+ }
+
+ /**
+ * java.net.InetAddress#isLoopbackAddress()
+ */
+ public void test_isLoopbackAddress() throws UnknownHostException {
+ InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+ assertFalse(ia2.isLoopbackAddress());
+ ia2 = InetAddress.getByName("localhost");
+ assertTrue(ia2.isLoopbackAddress());
+ ia2 = InetAddress.getByName("127.0.0.2");
+ assertTrue(ia2.isLoopbackAddress());
+ }
+
+ /**
+ * java.net.InetAddress#isLoopbackAddress()
+ */
+ public void test_isSiteLocalAddress() throws UnknownHostException {
+ InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+ assertFalse(ia2.isSiteLocalAddress());
+ ia2 = InetAddress.getByName("localhost");
+ assertFalse(ia2.isSiteLocalAddress());
+ ia2 = InetAddress.getByName("127.0.0.2");
+ assertFalse(ia2.isSiteLocalAddress());
+ ia2 = InetAddress.getByName("243.243.45.3");
+ assertFalse(ia2.isSiteLocalAddress());
+ ia2 = InetAddress.getByName("10.0.0.2");
+ assertTrue(ia2.isSiteLocalAddress());
+ }
+
+ /**
+ * java.net.InetAddress#isMCGlobal()/isMCLinkLocal/isMCNodeLocal/isMCOrgLocal/isMCSiteLocal
+ */
+ public void test_isMCVerify() throws UnknownHostException {
+ InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+ assertFalse(ia2.isMCGlobal());
+ assertFalse(ia2.isMCLinkLocal());
+ assertFalse(ia2.isMCNodeLocal());
+ assertFalse(ia2.isMCOrgLocal());
+ assertTrue(ia2.isMCSiteLocal());
+ ia2 = InetAddress.getByName("243.243.45.3");
+ assertFalse(ia2.isMCGlobal());
+ assertFalse(ia2.isMCLinkLocal());
+ assertFalse(ia2.isMCNodeLocal());
+ assertFalse(ia2.isMCOrgLocal());
+ assertFalse(ia2.isMCSiteLocal());
+ ia2 = InetAddress.getByName("250.255.255.254");
+ assertFalse(ia2.isMCGlobal());
+ assertFalse(ia2.isMCLinkLocal());
+ assertFalse(ia2.isMCNodeLocal());
+ assertFalse(ia2.isMCOrgLocal());
+ assertFalse(ia2.isMCSiteLocal());
+ ia2 = InetAddress.getByName("10.0.0.2");
+ assertFalse(ia2.isMCGlobal());
+ assertFalse(ia2.isMCLinkLocal());
+ assertFalse(ia2.isMCNodeLocal());
+ assertFalse(ia2.isMCOrgLocal());
+ assertFalse(ia2.isMCSiteLocal());
+ }
+
+ /**
+ * java.net.InetAddress#toString()
+ */
+ public void test_toString() throws Exception {
+ // Test for method java.lang.String java.net.InetAddress.toString()
+ InetAddress ia2 = InetAddress.getByName("127.0.0.1");
+ assertEquals("/127.0.0.1", ia2.toString());
+ // Regression for HARMONY-84
+ InetAddress addr2 = InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 });
+ assertEquals("Assert 1: wrong string from address", "/127.0.0.1", addr2.toString());
+ }
+
+ /**
+ * java.net.InetAddress#getByAddress(java.lang.String, byte[])
+ */
+ public void test_getByAddressLjava_lang_String$B() {
+ // Check an IPv4 address with an IPv6 hostname
+ byte ipAddress[] = { 127, 0, 0, 1 };
+ String addressStr = "::1";
+ try {
+ InetAddress addr = InetAddress.getByAddress(addressStr, ipAddress);
+ addr = InetAddress.getByAddress(ipAddress);
+ } catch (UnknownHostException e) {
+ fail("Unexpected problem creating IP Address "
+ + ipAddress.length);
+ }
+
+ byte ipAddress2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 127, 0, 0,
+ 1 };
+ addressStr = "::1";
+ try {
+ InetAddress addr = InetAddress.getByAddress(addressStr, ipAddress2);
+ addr = InetAddress.getByAddress(ipAddress);
+ } catch (UnknownHostException e) {
+ fail("Unexpected problem creating IP Address "
+ + ipAddress.length);
+ }
+ }
+
+ /**
+ * java.net.InetAddress#getCanonicalHostName()
+ */
+ public void test_getCanonicalHostName() throws Exception {
+ InetAddress theAddress = null;
+ theAddress = InetAddress.getLocalHost();
+ assertTrue("getCanonicalHostName returned a zero length string ",
+ theAddress.getCanonicalHostName().length() != 0);
+ assertTrue("getCanonicalHostName returned an empty string ",
+ !theAddress.equals(""));
+ }
+
+ /**
+ * java.net.InetAddress#isReachableI
+ */
+ public void test_isReachableI() throws Exception {
+ InetAddress ia = Inet4Address.getByName("127.0.0.1");
+ assertTrue(ia.isReachable(10000));
+ ia = Inet4Address.getByName("127.0.0.1");
+ try {
+ ia.isReachable(-1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // correct
+ }
+ }
+
+ /**
+ * java.net.InetAddress#isReachableLjava_net_NetworkInterfaceII
+ */
+ public void test_isReachableLjava_net_NetworkInterfaceII() throws Exception {
+ // tests local address
+ InetAddress ia = Inet4Address.getByName("127.0.0.1");
+ assertTrue(ia.isReachable(null, 0, 10000));
+ ia = Inet4Address.getByName("127.0.0.1");
+ try {
+ ia.isReachable(null, -1, 10000);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // correct
+ }
+ try {
+ ia.isReachable(null, 0, -1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // correct
+ }
+ try {
+ ia.isReachable(null, -1, -1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // correct
+ }
+ // tests nowhere
+ ia = Inet4Address.getByName("1.1.1.1");
+ assertFalse(ia.isReachable(1000));
+ assertFalse(ia.isReachable(null, 0, 1000));
+
+ // Regression test for HARMONY-1842.
+ ia = InetAddress.getByName("localhost"); //$NON-NLS-1$
+ Enumeration<NetworkInterface> nif = NetworkInterface.getNetworkInterfaces();
+ NetworkInterface netif;
+ while (nif.hasMoreElements()) {
+ netif = nif.nextElement();
+ ia.isReachable(netif, 10, 1000);
+ }
+ }
+
+ // comparator for InetAddress objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ InetAddress initAddr = (InetAddress) initial;
+ InetAddress desrAddr = (InetAddress) deserialized;
+
+ byte[] iaAddresss = initAddr.getAddress();
+ byte[] deIAAddresss = desrAddr.getAddress();
+ for (int i = 0; i < iaAddresss.length; i++) {
+ assertEquals(iaAddresss[i], deIAAddresss[i]);
+ }
+ assertEquals(initAddr.getHostName(), desrAddr.getHostName());
+ }
+ };
+
+ // Regression Test for Harmony-2290
+ public void test_isReachableLjava_net_NetworkInterfaceII_loopbackInterface() throws IOException {
+ final int TTL = 20;
+ final int TIME_OUT = 3000;
+
+ NetworkInterface loopbackInterface = null;
+ ArrayList<InetAddress> localAddresses = new ArrayList<InetAddress>();
+ Enumeration<NetworkInterface> networkInterfaces = NetworkInterface
+ .getNetworkInterfaces();
+ while (networkInterfaces.hasMoreElements()) {
+ NetworkInterface networkInterface = networkInterfaces.nextElement();
+ Enumeration<InetAddress> addresses = networkInterface
+ .getInetAddresses();
+ while (addresses.hasMoreElements()) {
+ InetAddress address = addresses.nextElement();
+ if (address.isLoopbackAddress()) {
+ loopbackInterface = networkInterface;
+ } else {
+ localAddresses.add(address);
+ }
+ }
+ }
+
+ //loopbackInterface can reach local address
+ if (null != loopbackInterface) {
+ for (InetAddress destAddress : localAddresses) {
+ assertTrue(destAddress.isReachable(loopbackInterface, TTL, TIME_OUT));
+ }
+ }
+
+ //loopback Interface cannot reach outside address
+ InetAddress destAddress = InetAddress.getByName("www.google.com");
+ assertFalse(destAddress.isReachable(loopbackInterface, TTL, TIME_OUT));
+ }
+
+ /**
+ * serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(InetAddress.getByName("localhost"),
+ COMPARATOR);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ InetAddress.getByName("localhost"), COMPARATOR);
+ }
+
+ /**
+ * java.net.InetAddress#getByAddress(byte[])
+ */
+ public void test_getByAddress() {
+ // Regression for HARMONY-61
+ try {
+ InetAddress.getByAddress(null);
+ fail("Assert 0: UnknownHostException must be thrown");
+ } catch (UnknownHostException e) {
+ // Expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetAddressThreadTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetAddressThreadTest.java
new file mode 100644
index 0000000..840f28e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetAddressThreadTest.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.InetAddress;
+
+import tests.support.Support_Configuration;
+
+public class InetAddressThreadTest extends junit.framework.TestCase {
+
+ private static boolean someoneDone[] = new boolean[2];
+
+ protected static boolean threadedTestSucceeded;
+
+ protected static String threadedTestErrorString;
+
+ /**
+ * This class is used to test inet_ntoa, gethostbyaddr and gethostbyname
+ * functions in the VM to make sure they're threadsafe. getByName will cause
+ * the gethostbyname function to be called. getHostName will cause the
+ * gethostbyaddr to be called. getHostAddress will cause inet_ntoa to be
+ * called.
+ */
+ static class threadsafeTestThread extends Thread {
+ private String lookupName;
+
+ private InetAddress testAddress;
+
+ private int testType;
+
+ /*
+ * REP_NUM can be adjusted if desired. Since this error is
+ * non-deterministic it may not always occur. Setting REP_NUM higher,
+ * increases the chances of an error being detected, but causes the test
+ * to take longer. Because the Java threads spend a lot of time
+ * performing operations other than running the native code that may not
+ * be threadsafe, it is quite likely that several thousand iterations
+ * will elapse before the first error is detected.
+ */
+ private static final int REP_NUM = 20000;
+
+ public threadsafeTestThread(String name, String lookupName,
+ InetAddress testAddress, int type) {
+ super(name);
+ this.lookupName = lookupName;
+ this.testAddress = testAddress;
+ testType = type;
+ }
+
+ public void run() {
+ try {
+ String correctName = testAddress.getHostName();
+ String correctAddress = testAddress.getHostAddress();
+ long startTime = System.currentTimeMillis();
+
+ synchronized (someoneDone) {
+ }
+
+ for (int i = 0; i < REP_NUM; i++) {
+ if (someoneDone[testType]) {
+ break;
+ } else if ((i % 25) == 0
+ && System.currentTimeMillis() - startTime > 240000) {
+ System.out
+ .println("Exiting due to time limitation after "
+ + i + " iterations");
+ break;
+ }
+
+ InetAddress ia = InetAddress.getByName(lookupName);
+ String hostName = ia.getHostName();
+ String hostAddress = ia.getHostAddress();
+
+ // Intentionally not looking for exact name match so that
+ // the test works across different platforms that may or
+ // may not include a domain suffix on the hostname
+ if (!hostName.startsWith(correctName)) {
+ threadedTestSucceeded = false;
+ threadedTestErrorString = (testType == 0 ? "gethostbyname"
+ : "gethostbyaddr")
+ + ": getHostName() returned "
+ + hostName
+ + " instead of " + correctName;
+ break;
+ }
+ // IP addresses should match exactly
+ if (!correctAddress.equals(hostAddress)) {
+ threadedTestSucceeded = false;
+ threadedTestErrorString = (testType == 0 ? "gethostbyname"
+ : "gethostbyaddr")
+ + ": getHostName() returned "
+ + hostAddress
+ + " instead of " + correctAddress;
+ break;
+ }
+
+ }
+ someoneDone[testType] = true;
+ } catch (Exception e) {
+ threadedTestSucceeded = false;
+ threadedTestErrorString = e.toString();
+ }
+ }
+ }
+
+ /**
+ * java.net.InetAddress#getHostName()
+ */
+ public void test_getHostName() throws Exception {
+ // Test for method java.lang.String java.net.InetAddress.getHostName()
+
+ // Make sure there is no caching
+ String originalPropertyValue = System
+ .getProperty("networkaddress.cache.ttl");
+ System.setProperty("networkaddress.cache.ttl", "0");
+
+ // Test for threadsafety
+ try {
+ InetAddress lookup1 = InetAddress.getByName("localhost");
+ assertEquals("127.0.0.1", lookup1.getHostAddress());
+ InetAddress lookup2 = InetAddress.getByName("localhost");
+ assertEquals("127.0.0.1", lookup2.getHostAddress());
+ threadsafeTestThread thread1 = new threadsafeTestThread("1",
+ lookup1.getHostName(), lookup1, 0);
+ threadsafeTestThread thread2 = new threadsafeTestThread("2",
+ lookup2.getHostName(), lookup2, 0);
+ threadsafeTestThread thread3 = new threadsafeTestThread("3",
+ lookup1.getHostAddress(), lookup1, 1);
+ threadsafeTestThread thread4 = new threadsafeTestThread("4",
+ lookup2.getHostAddress(), lookup2, 1);
+
+ // initialize the flags
+ threadedTestSucceeded = true;
+ synchronized (someoneDone) {
+ thread1.start();
+ thread2.start();
+ thread3.start();
+ thread4.start();
+ }
+ thread1.join();
+ thread2.join();
+ thread3.join();
+ thread4.join();
+ /* FIXME: comment the assertion below because it is platform/configuration dependent
+ * Please refer to HARMONY-1664 (https://issues.apache.org/jira/browse/HARMONY-1664)
+ * for details
+ */
+// assertTrue(threadedTestErrorString, threadedTestSucceeded);
+ } finally {
+ // restore the old value of the property
+ if (originalPropertyValue == null)
+ // setting the property to -1 has the same effect as having the
+ // property be null
+ System.setProperty("networkaddress.cache.ttl", "-1");
+ else
+ System.setProperty("networkaddress.cache.ttl",
+ originalPropertyValue);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetSocketAddressTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetSocketAddressTest.java
new file mode 100644
index 0000000..916ee3e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InetSocketAddressTest.java
@@ -0,0 +1,131 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.net;
+
+import java.io.Serializable;
+import java.net.InetSocketAddress;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class InetSocketAddressTest extends TestCase {
+
+ /**
+ * java.net.InetSocketAddress#InetSocketAddress(String, int)
+ */
+ public void test_ConstructorLjava_lang_StringI() throws Exception {
+ // regression test for Harmony-1042
+ InetSocketAddress address = new InetSocketAddress("127.0.0.1", 0);
+ assertEquals("/127.0.0.1:0", address.toString());
+ String localhostName = address.getHostName();
+ assertNotNull(localhostName);
+ assertEquals(localhostName + "/127.0.0.1:0", address.toString());
+ }
+
+ /**
+ * java.net.InetSocketAddress#createUnresolved(String, int)
+ */
+ public void test_createUnresolvedLjava_lang_StringI() {
+ HostPortPair[] legalHostPortPairs = { new HostPortPair("127.0.0.1", 1234),
+ new HostPortPair("192.168.0.1", 10000), new HostPortPair("127.0.0", 0),
+ new HostPortPair("127.0.0", 65535),
+ new HostPortPair("strange host", 65535) };
+ for (int i = 0; i < legalHostPortPairs.length; i++) {
+ InetSocketAddress isa = InetSocketAddress.createUnresolved(
+ legalHostPortPairs[i].host, legalHostPortPairs[i].port);
+ assertTrue(isa.isUnresolved());
+ assertNull(isa.getAddress());
+ assertEquals(isa.getHostName(), legalHostPortPairs[i].host);
+ assertEquals(isa.getPort(), legalHostPortPairs[i].port);
+ }
+ }
+
+ /**
+ * java.net.InetSocketAddress#createUnresolved(String, int)
+ */
+ public void test_createUnresolvedLjava_lang_StringI_IllegalArgumentException() {
+ HostPortPair[] illegalHostPortPairs = { new HostPortPair(null, 1),
+ new HostPortPair("host", -1), new HostPortPair("host", 65536) };
+ for (int i = 0; i < illegalHostPortPairs.length; i++) {
+ try {
+ InetSocketAddress.createUnresolved(
+ illegalHostPortPairs[i].host,
+ illegalHostPortPairs[i].port);
+ fail("should throw IllegalArgumentException, host = "
+ + illegalHostPortPairs[i].host + ",port = "
+ + illegalHostPortPairs[i].port);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+ }
+
+ /*
+ * inner class for createUnresolved test convenience.
+ */
+ class HostPortPair {
+ String host;
+
+ int port;
+
+ public HostPortPair(String host, int port) {
+ this.host = host;
+ this.port = port;
+ }
+ }
+
+ ;
+
+ // comparator for InetSocketAddress objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ InetSocketAddress init = (InetSocketAddress) initial;
+ InetSocketAddress desr = (InetSocketAddress) deserialized;
+
+ assertEquals("HostName", init.getHostName(), desr.getHostName());
+ assertEquals("Port", init.getPort(), desr.getPort());
+ assertEquals("Address", init.getAddress(), desr.getAddress());
+ }
+ };
+
+ /**
+ * serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ Object[] testCases = {
+ InetSocketAddress.createUnresolved("badhost", 1000), // unresolved
+ new InetSocketAddress("Localhost", 1000) };
+
+ SerializationTest.verifySelf(testCases, COMPARATOR);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ Object[] testCases = {
+ InetSocketAddress.createUnresolved("badhost", 1000), // unresolved
+ new InetSocketAddress("Localhost", 1000) };
+
+ SerializationTest.verifyGolden(this, testCases, COMPARATOR);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InterfaceAddressTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InterfaceAddressTest.java
new file mode 100644
index 0000000..c4c2b90
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/InterfaceAddressTest.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.util.Enumeration;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class InterfaceAddressTest extends TestCase {
+ private InterfaceAddress interfaceAddr;
+
+ private InterfaceAddress anotherInterfaceAddr;
+
+ /**
+ * java.net.InterfaceAddress.hashCode()
+ * @since 1.6
+ */
+ public void test_hashCode() {
+ // RI may fail on this when both broadcast addresses are null
+ if (interfaceAddr != null) {
+ assertEquals(anotherInterfaceAddr, interfaceAddr);
+ assertEquals(anotherInterfaceAddr.hashCode(), interfaceAddr
+ .hashCode());
+ }
+ }
+
+ /**
+ * java.net.InterfaceAddress.equals(Object)
+ * @since 1.6
+ */
+ public void test_equals_LObject() {
+ // RI may fail on this when both broadcast addresses are null
+ if (interfaceAddr != null) {
+ assertFalse(interfaceAddr.equals(null));
+ assertFalse(interfaceAddr.equals(new Object()));
+
+ assertTrue(interfaceAddr.equals(anotherInterfaceAddr));
+ assertNotSame(anotherInterfaceAddr, interfaceAddr);
+ }
+ }
+
+ /**
+ * java.net.InterfaceAddress.toString()
+ * @since 1.6
+ */
+ public void test_toString() {
+ if (interfaceAddr != null) {
+ assertNotNull(interfaceAddr.toString());
+ assertEquals(anotherInterfaceAddr.toString(), interfaceAddr
+ .toString());
+ assertTrue(interfaceAddr.toString().contains("/"));
+ assertTrue(interfaceAddr.toString().contains("["));
+ assertTrue(interfaceAddr.toString().contains("]"));
+ }
+ }
+
+ /**
+ * java.net.InterfaceAddress.getAddress()
+ * @since 1.6
+ */
+ public void test_getAddress() {
+ if (interfaceAddr != null) {
+ InetAddress addr1 = interfaceAddr.getAddress();
+ assertNotNull(addr1);
+ InetAddress addr2 = anotherInterfaceAddr.getAddress();
+ assertNotNull(addr2);
+ assertEquals(addr2, addr1);
+ }
+ }
+
+ /**
+ * java.net.InterfaceAddress.getBroadcast()
+ * @since 1.6
+ */
+ public void test_getBroadcast() {
+ if (interfaceAddr != null) {
+ InetAddress addr = interfaceAddr.getAddress();
+ InetAddress addr1 = interfaceAddr.getBroadcast();
+ InetAddress addr2 = anotherInterfaceAddr.getBroadcast();
+ if (addr instanceof Inet4Address) {
+ assertEquals(addr2, addr1);
+ } else if (addr instanceof Inet6Address) {
+ assertNull(addr1);
+ assertNull(addr2);
+ }
+ }
+ }
+
+ /**
+ * java.net.InterfaceAddress.getNetworkPrefixLength()
+ * @since 1.6
+ */
+ public void test_getNetworkPrefixLength() {
+ if (interfaceAddr != null) {
+ short prefix1 = interfaceAddr.getNetworkPrefixLength();
+ short prefix2 = anotherInterfaceAddr.getNetworkPrefixLength();
+ assertEquals(prefix2, prefix1);
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ Enumeration<NetworkInterface> netifs = NetworkInterface
+ .getNetworkInterfaces();
+ NetworkInterface theInterface = null;
+ if (netifs != null) {
+ while (netifs.hasMoreElements()) {
+ theInterface = netifs.nextElement();
+ if (theInterface != null) {
+ List<InterfaceAddress> addrs = theInterface
+ .getInterfaceAddresses();
+ if (!(addrs == null || addrs.isEmpty())) {
+ interfaceAddr = addrs.get(0);
+ break;
+ }
+ }
+ }
+ }
+
+ // get another InterfaceAddress object if the interfaceAddr exists. It
+ // equals to interfaceAddr, but is not the same one.
+ if (theInterface != null && interfaceAddr != null) {
+ Enumeration<InetAddress> addresses = theInterface
+ .getInetAddresses();
+ if (addresses != null && addresses.hasMoreElements()) {
+ NetworkInterface anotherNetworkInter = NetworkInterface
+ .getByInetAddress(addresses.nextElement());
+ anotherInterfaceAddr = anotherNetworkInter
+ .getInterfaceAddresses().get(0);
+ }
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ interfaceAddr = null;
+ anotherInterfaceAddr = null;
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/JarURLConnectionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/JarURLConnectionTest.java
new file mode 100644
index 0000000..c938785
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/JarURLConnectionTest.java
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import tests.support.resource.Support_Resources;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class JarURLConnectionTest extends junit.framework.TestCase {
+
+ private JarURLConnection juc;
+
+ private URL copyAndOpenResourceStream(String jarFile, String inFile)
+ throws MalformedURLException {
+
+ File resources = Support_Resources.createTempFolder();
+
+ Support_Resources.copyFile(resources, "net", jarFile);
+ File file = new File(resources.toString() + "/net/" + jarFile);
+
+ return new URL("jar:file:" + file.getPath() + "!/" + inFile);
+ }
+
+
+ /**
+ * java.net.JarURLConnection#getAttributes()
+ */
+ public void test_getAttributes() throws Exception {
+ URL u = copyAndOpenResourceStream("lf.jar", "swt.dll");
+
+ juc = (JarURLConnection) u.openConnection();
+ java.util.jar.Attributes a = juc.getJarEntry().getAttributes();
+ assertEquals("Returned incorrect Attributes", "SHA MD5", a
+ .get(new java.util.jar.Attributes.Name("Digest-Algorithms")));
+ }
+
+ /**
+ * @throws Exception
+ * java.net.JarURLConnection#getEntryName()
+ */
+ public void test_getEntryName() throws Exception {
+ URL u = copyAndOpenResourceStream("lf.jar", "plus.bmp");
+ juc = (JarURLConnection) u.openConnection();
+ assertEquals("Returned incorrect entryName", "plus.bmp", juc
+ .getEntryName());
+ u = copyAndOpenResourceStream("lf.jar", "");
+ juc = (JarURLConnection) u.openConnection();
+ assertNull("Returned incorrect entryName", juc.getEntryName());
+// Regression test for harmony-3053
+ URL url = copyAndOpenResourceStream("lf.jar", "foo.jar!/Bugs/HelloWorld.class");
+ assertEquals("foo.jar!/Bugs/HelloWorld.class", ((JarURLConnection) url.openConnection()).getEntryName());
+ }
+
+ /**
+ * java.net.JarURLConnection#getJarEntry()
+ */
+ public void test_getJarEntry() throws Exception {
+ URL u = copyAndOpenResourceStream("lf.jar", "plus.bmp");
+ juc = (JarURLConnection) u.openConnection();
+ assertEquals("Returned incorrect JarEntry", "plus.bmp", juc
+ .getJarEntry().getName());
+ u = copyAndOpenResourceStream("lf.jar", "");
+ juc = (JarURLConnection) u.openConnection();
+ assertNull("Returned incorrect JarEntry", juc.getJarEntry());
+ }
+
+ /**
+ * java.net.JarURLConnection#getJarFile()
+ */
+ public void test_getJarFile() throws MalformedURLException, IOException {
+ URL url = copyAndOpenResourceStream("lf.jar", "missing");
+
+ JarURLConnection connection = null;
+ connection = (JarURLConnection) url.openConnection();
+ try {
+ connection.connect();
+ fail("Did not throw exception on connect");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ connection.getJarFile();
+ fail("Did not throw exception after connect");
+ } catch (IOException e) {
+ // expected
+ }
+
+ File resources = Support_Resources.createTempFolder();
+
+ Support_Resources.copyFile(resources, null, "hyts_att.jar");
+ File file = new File(resources.toString() + "/hyts_att.jar");
+ URL fUrl1 = new URL("jar:file:" + file.getPath() + "!/");
+ JarURLConnection con1 = (JarURLConnection) fUrl1.openConnection();
+ ZipFile jf1 = con1.getJarFile();
+ JarURLConnection con2 = (JarURLConnection) fUrl1.openConnection();
+ ZipFile jf2 = con2.getJarFile();
+ assertTrue("file: JarFiles not the same", jf1 == jf2);
+ jf1.close();
+ assertTrue("File should exist", file.exists());
+ con1 = (JarURLConnection) fUrl1.openConnection();
+ jf1 = con1.getJarFile();
+ con2 = (JarURLConnection) fUrl1.openConnection();
+ jf2 = con2.getJarFile();
+ assertTrue("http: JarFiles not the same", jf1 == jf2);
+ jf1.close();
+ }
+
+ /**
+ * java.net.JarURLConnection.getJarFile()
+ * <p/>
+ * Regression test for HARMONY-29
+ */
+ public void test_getJarFile29() throws Exception {
+ File jarFile = File.createTempFile("1+2 3", "test.jar");
+ jarFile.deleteOnExit();
+ JarOutputStream out = new JarOutputStream(new FileOutputStream(jarFile));
+ out.putNextEntry(new ZipEntry("test"));
+ out.closeEntry();
+ out.close();
+
+ JarURLConnection conn = (JarURLConnection) new URL("jar:file:"
+ + jarFile.getAbsolutePath().replaceAll(" ", "%20") + "!/")
+ .openConnection();
+ conn.getJarFile().entries();
+ }
+
+ //Regression for HARMONY-3436
+ public void test_setUseCaches() throws Exception {
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, "hyts_att.jar");
+ File file = new File(resources.toString() + "/hyts_att.jar");
+ URL url = new URL("jar:file:" + file.getPath() + "!/HasAttributes.txt");
+
+ JarURLConnection connection = (JarURLConnection) url.openConnection();
+ connection.setUseCaches(false);
+ InputStream in = connection.getInputStream();
+ JarFile jarFile1 = connection.getJarFile();
+ JarEntry jarEntry1 = connection.getJarEntry();
+ byte[] data = new byte[1024];
+ while (in.read(data) >= 0)
+ ;
+ in.close();
+ JarFile jarFile2 = connection.getJarFile();
+ JarEntry jarEntry2 = connection.getJarEntry();
+ assertSame(jarFile1, jarFile2);
+ assertSame(jarEntry1, jarEntry2);
+
+ try {
+ connection.getInputStream();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.net.JarURLConnection#getJarFileURL()
+ */
+ public void test_getJarFileURL() throws Exception {
+ // Regression test for harmony-3053
+ URL url = new URL("jar:file:///bar.jar!/foo.jar!/Bugs/HelloWorld.class");
+ assertEquals("file:///bar.jar", ((JarURLConnection) url.openConnection()).getJarFileURL().toString());
+ }
+
+ /**
+ * java.net.JarURLConnection#getMainAttributes()
+ */
+ public void test_getMainAttributes() throws Exception {
+ URL u = copyAndOpenResourceStream("lf.jar", "swt.dll");
+ juc = (JarURLConnection) u.openConnection();
+ java.util.jar.Attributes a = juc.getMainAttributes();
+ assertEquals("Returned incorrect Attributes", "1.0", a
+ .get(java.util.jar.Attributes.Name.MANIFEST_VERSION));
+ }
+
+ /**
+ * java.net.JarURLConnection#getInputStream()
+ */
+ public void test_getInputStream_DeleteJarFileUsingURLConnection()
+ throws Exception {
+ File file = File.createTempFile("JarUrlConnectionTest", "jar");
+ FileOutputStream jarFile = new FileOutputStream(file);
+ JarOutputStream out = new JarOutputStream(new BufferedOutputStream(
+ jarFile));
+ JarEntry jarEntry = new JarEntry("entry.txt");
+ out.putNextEntry(jarEntry);
+ out.write(new byte[] { 'a', 'b', 'c' });
+ out.close();
+
+ URL url = new URL("jar:file:" + file.getAbsolutePath() + "!/entry.txt");
+ URLConnection conn = url.openConnection();
+ conn.setUseCaches(false);
+ InputStream is = conn.getInputStream();
+ is.close();
+ assertTrue(file.delete());
+ }
+
+ /**
+ * java.net.JarURLConnection#getManifest()
+ */
+ public void test_getManifest() throws Exception {
+ URL u = copyAndOpenResourceStream("lf.jar", "plus.bmp");
+ juc = (JarURLConnection) u.openConnection();
+ Manifest mf = juc.getManifest();
+ assertNotNull(mf);
+ // equal but not same manifest
+ assertEquals(mf, juc.getManifest());
+ assertNotSame(mf, juc.getManifest());
+ // same main attributes
+ assertEquals(juc.getMainAttributes(), mf.getMainAttributes());
+ }
+
+ /**
+ * java.net.JarURLConnection#getCertificates()
+ */
+ public void test_getCertificates() throws Exception {
+ URL u = copyAndOpenResourceStream("lf.jar", "plus.bmp");
+ juc = (JarURLConnection) u.openConnection();
+ // read incomplete, shall return null
+ assertNull(juc.getCertificates());
+ assertEquals("Returned incorrect JarEntry", "plus.bmp", juc
+ .getJarEntry().getName());
+ // read them all
+ InputStream is = juc.getInputStream();
+ byte[] buf = new byte[80];
+ while (is.read(buf) > 0) ;
+ // still return null for this type of file
+ assertNull(juc.getCertificates());
+
+ URL fileURL = copyAndOpenResourceStream("lf.jar", "");
+ juc = (JarURLConnection) fileURL.openConnection();
+ is = juc.getJarFileURL().openStream();
+ while (is.read(buf) > 0) ;
+ // null for this jar file
+ assertNull(juc.getCertificates());
+ }
+
+ /**
+ * java.net.JarURLConnection#getContentLength()
+ * Regression test for HARMONY-3665
+ */
+ public void test_getContentLength() throws Exception {
+ // check length for jar file itself
+ URL u = copyAndOpenResourceStream("lf.jar", "");
+ assertEquals("Returned incorrect size for jar file", 33095,
+ u.openConnection().getContentLength());
+
+ // check length for jar entry
+ u = copyAndOpenResourceStream("lf.jar", "plus.bmp");
+ assertEquals("Returned incorrect size for the entry", 190,
+ u.openConnection().getContentLength());
+ }
+
+ /**
+ * java.net.JarURLConnection#getContentType()
+ * Regression test for HARMONY-3665
+ */
+ public void test_getContentType() throws Exception {
+ // check type for jar file itself
+ URL u = copyAndOpenResourceStream("lf.jar", "");
+ assertEquals("Returned incorrect type for jar file", "x-java/jar",
+ u.openConnection().getContentType());
+
+ // check type for jar entry with known type
+ u = copyAndOpenResourceStream("lf.jar", "plus.bmp");
+ assertEquals("Returned incorrect type for the entry with known type",
+ "image/x-ms-bmp", u.openConnection().getContentType());
+
+ // check type for jar entry with unknown type
+ u = copyAndOpenResourceStream("lf.jar", "Manifest.mf");
+ assertEquals("Returned incorrect type for the entry with known type",
+ "content/unknown", u.openConnection().getContentType());
+ }
+
+ public void test_getURLEncodedEntry() throws IOException {
+ URL url = copyAndOpenResourceStream("url-test.jar", "test%20folder%20for%20url%20test/test");
+ if (url != null) {
+ // Force existence check
+ InputStream is = url.openStream();
+ is.close();
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MalformedURLExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MalformedURLExceptionTest.java
new file mode 100644
index 0000000..d5c2287
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MalformedURLExceptionTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class MalformedURLExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.MalformedURLException#MalformedURLException()
+ */
+ public void test_Constructor() {
+ // Test for method java.net.MalformedURLException()
+ boolean passed;
+ passed = false;
+ try {
+ new URL("notAProtocol://www.ibm.com");
+ } catch (MalformedURLException e) {
+ // correct
+ passed = true;
+ }
+
+ assertTrue("Failed to throw correct exception", passed);
+ }
+
+ /**
+ * java.net.MalformedURLException#MalformedURLException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.net.MalformedURLException(java.lang.String)
+ final String myString = "Gawsh!";
+ try {
+ if (true)
+ throw new MalformedURLException(myString);
+ } catch (MalformedURLException e) {
+ assertTrue("Incorrect exception text", e.toString().indexOf(
+ myString) >= 0);
+ return;
+ }
+ fail("Exception not thrown");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
new file mode 100644
index 0000000..828dc99
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
@@ -0,0 +1,929 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.net.BindException;
+import java.net.DatagramPacket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+public class MulticastSocketTest extends junit.framework.TestCase {
+
+ private static InetAddress lookup(String s) {
+ try {
+ return InetAddress.getByName(s);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ // These IP addresses aren't inherently "good" or "bad"; they're just used like that.
+ // We use the "good" addresses for our actual group, and the "bad" addresses are for
+ // a group that we won't actually set up.
+
+ private static InetAddress GOOD_IPv4 = lookup("224.0.0.3");
+ private static InetAddress BAD_IPv4 = lookup("224.0.0.4");
+
+ private static InetAddress GOOD_IPv6 = lookup("ff05::7:7");
+ private static InetAddress BAD_IPv6 = lookup("ff05::7:8");
+
+ private NetworkInterface loopbackInterface;
+ private NetworkInterface ipv4NetworkInterface;
+ private NetworkInterface ipv6NetworkInterface;
+ private boolean supportsMulticast;
+
+ @Override
+ protected void setUp() throws Exception {
+ // The loopback interface isn't actually useful for sending/receiving multicast messages
+ // but it can be used as a dummy for tests where that does not matter.
+ loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress());
+ assertNotNull(loopbackInterface);
+ assertTrue(loopbackInterface.isLoopback());
+ assertFalse(loopbackInterface.supportsMulticast());
+
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+ assertNotNull(interfaces);
+
+ // Determine if the device is marked to support multicast or not. If this propery is not
+ // set we assume the device has an interface capable of supporting multicast.
+ supportsMulticast = Boolean.valueOf(
+ System.getProperty("android.cts.device.multicast", "true"));
+ if (!supportsMulticast) {
+ return;
+ }
+
+ while (interfaces.hasMoreElements()
+ && (ipv4NetworkInterface == null || ipv6NetworkInterface == null)) {
+ NetworkInterface nextInterface = interfaces.nextElement();
+ if (willWorkForMulticast(nextInterface)) {
+ Enumeration<InetAddress> addresses = nextInterface.getInetAddresses();
+ while (addresses.hasMoreElements()) {
+ final InetAddress nextAddress = addresses.nextElement();
+ if (nextAddress instanceof Inet6Address && ipv6NetworkInterface == null) {
+ ipv6NetworkInterface = nextInterface;
+ } else if (nextAddress instanceof Inet4Address && ipv4NetworkInterface == null) {
+ ipv4NetworkInterface = nextInterface;
+ }
+ }
+ }
+ }
+ assertTrue("Test environment must have at least one interface capable of multicast for IPv4"
+ + " and IPv6",
+ ipv4NetworkInterface != null && ipv6NetworkInterface != null);
+ }
+
+ public void test_Constructor() throws IOException {
+ if (!supportsMulticast) {
+ return;
+ }
+ // Regression test for 497.
+ MulticastSocket s = new MulticastSocket();
+ // Regression test for Harmony-1162.
+ assertTrue(s.getReuseAddress());
+
+ s.close();
+ }
+
+ public void test_ConstructorI() throws IOException {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket orig = new MulticastSocket();
+ int port = orig.getLocalPort();
+ orig.close();
+
+ MulticastSocket dup = new MulticastSocket(port);
+ // Regression test for Harmony-1162.
+ assertTrue(dup.getReuseAddress());
+ dup.close();
+ }
+
+ public void test_getInterface() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ // Validate that we get the expected response when one was not set.
+ MulticastSocket mss = new MulticastSocket(0);
+ // We expect an ANY address in this case.
+ assertTrue(mss.getInterface().isAnyLocalAddress());
+
+ // Validate that we get the expected response when we set via setInterface.
+ Enumeration addresses = ipv4NetworkInterface.getInetAddresses();
+ if (addresses.hasMoreElements()) {
+ InetAddress firstAddress = (InetAddress) addresses.nextElement();
+ mss.setInterface(firstAddress);
+ assertEquals("getNetworkInterface did not return interface set by setInterface",
+ firstAddress, mss.getInterface());
+
+ mss.close();
+ mss = new MulticastSocket(0);
+ mss.setNetworkInterface(ipv4NetworkInterface);
+ assertEquals("getInterface did not return interface set by setNetworkInterface",
+ ipv4NetworkInterface, NetworkInterface.getByInetAddress(mss.getInterface()));
+ }
+
+ mss.close();
+ }
+
+ public void test_getNetworkInterface() throws IOException {
+ if (!supportsMulticast) {
+ return;
+ }
+ // Validate that we get the expected response when one was not set.
+ MulticastSocket mss = new MulticastSocket(0);
+ NetworkInterface theInterface = mss.getNetworkInterface();
+ assertTrue(
+ "network interface returned wrong network interface when not set:" + theInterface,
+ theInterface.getInetAddresses().hasMoreElements());
+ InetAddress firstAddress = theInterface.getInetAddresses().nextElement();
+ // Validate we the first address in the network interface is the ANY address.
+ assertTrue(firstAddress.isAnyLocalAddress());
+
+ mss.setNetworkInterface(ipv4NetworkInterface);
+ assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
+ ipv4NetworkInterface, mss.getNetworkInterface());
+
+ mss.setNetworkInterface(loopbackInterface);
+ assertEquals(
+ "getNetworkInterface did not return network interface set by second"
+ + " setNetworkInterface call",
+ loopbackInterface, mss.getNetworkInterface());
+ mss.close();
+
+ if (ipv6NetworkInterface != null) {
+ mss = new MulticastSocket(0);
+ mss.setNetworkInterface(ipv6NetworkInterface);
+ assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
+ ipv6NetworkInterface, mss.getNetworkInterface());
+ mss.close();
+ }
+
+ // Validate that we get the expected response when we set via setInterface.
+ mss = new MulticastSocket(0);
+ Enumeration addresses = ipv4NetworkInterface.getInetAddresses();
+ if (addresses.hasMoreElements()) {
+ firstAddress = (InetAddress) addresses.nextElement();
+ mss.setInterface(firstAddress);
+ assertEquals("getNetworkInterface did not return interface set by setInterface",
+ ipv4NetworkInterface, mss.getNetworkInterface());
+ }
+ mss.close();
+ }
+
+ public void test_getTimeToLive() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket();
+ mss.setTimeToLive(120);
+ assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive());
+ mss.setTimeToLive(220);
+ assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive());
+ mss.close();
+ }
+
+ public void test_getTTL() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket();
+ mss.setTTL((byte) 120);
+ assertEquals("Returned incorrect TTL", 120, mss.getTTL());
+ mss.close();
+ }
+
+ public void test_joinGroupLjava_net_InetAddress_IPv4() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_joinGroupLjava_net_InetAddress(GOOD_IPv4);
+ }
+
+ public void test_joinGroupLjava_net_InetAddress_IPv6() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_joinGroupLjava_net_InetAddress(GOOD_IPv6);
+ }
+
+ private void test_joinGroupLjava_net_InetAddress(InetAddress group) throws Exception {
+ MulticastSocket receivingSocket = createReceivingSocket(0);
+ receivingSocket.joinGroup(group);
+
+ String msg = "Hello World";
+ MulticastSocket sendingSocket = new MulticastSocket(receivingSocket.getLocalPort());
+ InetSocketAddress groupAddress =
+ new InetSocketAddress(group, receivingSocket.getLocalPort());
+ DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+ sendingSocket.send(sdp, (byte) 10 /* ttl */);
+
+ DatagramPacket rdp = createReceiveDatagramPacket();
+ receivingSocket.receive(rdp);
+ String receivedMessage = extractMessage(rdp);
+ assertEquals("Group member did not recv data", msg, receivedMessage);
+
+ sendingSocket.close();
+ receivingSocket.close();
+ }
+
+ public void test_joinGroup_null_null() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket(0);
+ try {
+ mss.joinGroup(null, null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ mss.close();
+ }
+
+ public void test_joinGroup_non_multicast_address_IPv4() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket(0);
+ try {
+ mss.joinGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null);
+ fail();
+ } catch (IOException expected) {
+ }
+ mss.close();
+ }
+
+ public void test_joinGroup_non_multicast_address_IPv6() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket(0);
+ try {
+ mss.joinGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null);
+ fail();
+ } catch (IOException expected) {
+ }
+ mss.close();
+ }
+
+ public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()
+ throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+ ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4);
+ }
+
+ public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()
+ throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+ ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6);
+ }
+
+ private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+ NetworkInterface networkInterface, InetAddress group, InetAddress group2)
+ throws Exception {
+ // Check that we can join a group using a null network interface.
+ MulticastSocket sendingSocket = new MulticastSocket(0);
+ SocketAddress groupSockAddr = new InetSocketAddress(group, sendingSocket.getLocalPort());
+ sendingSocket.joinGroup(groupSockAddr, null);
+ sendingSocket.setTimeToLive(2);
+
+ MulticastSocket receivingSocket = createReceivingSocket(0);
+ InetSocketAddress groupAddress =
+ new InetSocketAddress(group, receivingSocket.getLocalPort());
+ receivingSocket.joinGroup(groupAddress, networkInterface);
+
+ String msg = "Hello World";
+ DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+ sendingSocket.send(sdp);
+
+ DatagramPacket rdp = createReceiveDatagramPacket();
+ receivingSocket.receive(rdp);
+ // Now validate that we received the data as expected.
+ assertEquals("Group member did not recv data", msg, extractMessage(rdp));
+ receivingSocket.close();
+ sendingSocket.close();
+
+ receivingSocket = createReceivingSocket(0);
+ groupAddress = new InetSocketAddress(group, receivingSocket.getLocalPort());
+ receivingSocket.joinGroup(groupAddress, networkInterface);
+
+ sendingSocket = new MulticastSocket(0);
+ sendingSocket.setTimeToLive(10);
+ msg = "Hello World - Different Group";
+ InetSocketAddress group2Address =
+ new InetSocketAddress(group2, receivingSocket.getLocalPort());
+ sdp = createSendDatagramPacket(group2Address, msg);
+ sendingSocket.send(sdp);
+
+ rdp = createReceiveDatagramPacket();
+ try {
+ receivingSocket.receive(rdp);
+ fail("Expected timeout");
+ } catch (SocketTimeoutException expected) {
+ }
+
+ receivingSocket.close();
+ sendingSocket.close();
+ }
+
+ public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ // Check that we can join on specific interfaces and that we only receive if data is
+ // received on that interface. This test is only really useful on devices with multiple
+ // non-loopback interfaces.
+
+ List<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
+ Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
+ while (theInterfaces.hasMoreElements()) {
+ NetworkInterface thisInterface = theInterfaces.nextElement();
+ // Skip interfaces that do not support multicast - there's no point in proving
+ // they cannot send / receive multicast messages.
+ if (willWorkForMulticast(thisInterface)) {
+ realInterfaces.add(thisInterface);
+ }
+ }
+
+ for (NetworkInterface thisInterface : realInterfaces) {
+ // Find a suitable group IP and interface to use to sent packets to thisInterface.
+ Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
+
+ NetworkInterface sendingInterface = null;
+ InetAddress group = null;
+ if (addresses.hasMoreElements()) {
+ InetAddress firstAddress = addresses.nextElement();
+ if (firstAddress instanceof Inet4Address) {
+ group = GOOD_IPv4;
+ sendingInterface = ipv4NetworkInterface;
+ } else {
+ // if this interface only seems to support IPV6 addresses
+ group = GOOD_IPv6;
+ sendingInterface = ipv6NetworkInterface;
+ }
+ }
+
+ // Create a receivingSocket which is joined to the group and has only asked for packets
+ // on thisInterface.
+ MulticastSocket receivingSocket = createReceivingSocket(0);
+ InetSocketAddress groupAddress =
+ new InetSocketAddress(group, receivingSocket.getLocalPort());
+ receivingSocket.joinGroup(groupAddress, thisInterface);
+
+ // Now send out a packet on sendingInterface. We should only see the packet if we send
+ // it on thisInterface.
+ MulticastSocket sendingSocket = new MulticastSocket(0);
+ sendingSocket.setNetworkInterface(sendingInterface);
+ String msg = "Hello World - Again " + thisInterface.getName();
+ DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+ sendingSocket.send(sdp);
+
+ DatagramPacket rdp = createReceiveDatagramPacket();
+ try {
+ receivingSocket.receive(rdp);
+
+ // If the packet is received....
+ assertEquals(thisInterface, sendingInterface);
+ assertEquals("Group member did not recv data when bound on specific interface",
+ msg, extractMessage(rdp));
+ } catch (SocketTimeoutException e) {
+ // If the packet was not received...
+ assertTrue(!thisInterface.equals(sendingInterface));
+ }
+
+ receivingSocket.close();
+ sendingSocket.close();
+ }
+ }
+
+ public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4()
+ throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+ ipv4NetworkInterface, GOOD_IPv4);
+ }
+
+ public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6()
+ throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+ ipv6NetworkInterface, GOOD_IPv6);
+ }
+
+ private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+ NetworkInterface networkInterface, InetAddress group) throws Exception {
+ // Validate that we can join the same address on two different interfaces but not on the
+ // same interface.
+ MulticastSocket mss = new MulticastSocket(0);
+ SocketAddress groupSockAddr = new InetSocketAddress(group, mss.getLocalPort());
+ mss.joinGroup(groupSockAddr, networkInterface);
+ mss.joinGroup(groupSockAddr, loopbackInterface);
+ try {
+ mss.joinGroup(groupSockAddr, networkInterface);
+ fail("Did not get expected exception when joining for second time on same interface");
+ } catch (IOException e) {
+ }
+ mss.close();
+ }
+
+ public void test_leaveGroupLjava_net_InetAddress_IPv4() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_leaveGroupLjava_net_InetAddress(GOOD_IPv4);
+ }
+
+ public void test_leaveGroupLjava_net_InetAddress_IPv6() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_leaveGroupLjava_net_InetAddress(GOOD_IPv6);
+ }
+
+ private void test_leaveGroupLjava_net_InetAddress(InetAddress group) throws Exception {
+ String msg = "Hello World";
+ MulticastSocket mss = new MulticastSocket(0);
+ InetSocketAddress groupAddress = new InetSocketAddress(group, mss.getLocalPort());
+ DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+ mss.send(sdp, (byte) 10 /* ttl */);
+ try {
+ // Try to leave a group we didn't join.
+ mss.leaveGroup(group);
+ fail();
+ } catch (IOException expected) {
+ }
+ mss.close();
+ }
+
+ public void test_leaveGroup_null_null() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket(0);
+ try {
+ mss.leaveGroup(null, null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ mss.close();
+ }
+
+ public void test_leaveGroup_non_multicast_address_IPv4() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket(0);
+ try {
+ mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null);
+ fail();
+ } catch (IOException expected) {
+ }
+ mss.close();
+ }
+
+ public void test_leaveGroup_non_multicast_address_IPv6() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket(0);
+ try {
+ mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null);
+ fail();
+ } catch (IOException expected) {
+ }
+ mss.close();
+ }
+
+ public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()
+ throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+ ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4);
+ }
+
+ public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()
+ throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+ ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6);
+ }
+
+ private void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+ NetworkInterface networkInterface, InetAddress group, InetAddress group2)
+ throws Exception {
+ SocketAddress groupSockAddr = null;
+ SocketAddress groupSockAddr2 = null;
+
+ MulticastSocket mss = new MulticastSocket(0);
+ groupSockAddr = new InetSocketAddress(group, mss.getLocalPort());
+ mss.joinGroup(groupSockAddr, null);
+ mss.leaveGroup(groupSockAddr, null);
+ try {
+ mss.leaveGroup(groupSockAddr, null);
+ fail("Did not get exception when trying to leave group that was already left");
+ } catch (IOException expected) {
+ }
+
+ groupSockAddr2 = new InetSocketAddress(group2, mss.getLocalPort());
+ mss.joinGroup(groupSockAddr, networkInterface);
+ try {
+ mss.leaveGroup(groupSockAddr2, networkInterface);
+ fail("Did not get exception when trying to leave group that was never joined");
+ } catch (IOException expected) {
+ }
+
+ mss.leaveGroup(groupSockAddr, networkInterface);
+
+ mss.joinGroup(groupSockAddr, networkInterface);
+ try {
+ mss.leaveGroup(groupSockAddr, loopbackInterface);
+ fail("Did not get exception when trying to leave group on wrong interface " +
+ "joined on [" + networkInterface + "] left on [" + loopbackInterface + "]");
+ } catch (IOException expected) {
+ }
+ }
+
+ public void test_sendLjava_net_DatagramPacketB_IPv4() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_sendLjava_net_DatagramPacketB(GOOD_IPv4);
+ }
+
+ public void test_sendLjava_net_DatagramPacketB_IPv6() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_sendLjava_net_DatagramPacketB(GOOD_IPv6);
+ }
+
+ private void test_sendLjava_net_DatagramPacketB(InetAddress group) throws Exception {
+ String msg = "Hello World";
+ MulticastSocket sendingSocket = new MulticastSocket(0);
+ MulticastSocket receivingSocket = createReceivingSocket(sendingSocket.getLocalPort());
+ receivingSocket.joinGroup(group);
+
+ InetSocketAddress groupAddress = new InetSocketAddress(group, sendingSocket.getLocalPort());
+ DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+ sendingSocket.send(sdp, (byte) 10 /* ttl */);
+ sendingSocket.close();
+
+ DatagramPacket rdp = createReceiveDatagramPacket();
+ receivingSocket.receive(rdp);
+ String receivedMessage = extractMessage(rdp);
+ assertEquals("Failed to send data. Received " + rdp.getLength(), msg, receivedMessage);
+ receivingSocket.close();
+ }
+
+ public void test_setInterfaceLjava_net_InetAddress() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket();
+ mss.setInterface(InetAddress.getLocalHost());
+ InetAddress theInterface = mss.getInterface();
+ // Under IPV6 we are not guaranteed to get the same address back as the address that was
+ // set, all we should be guaranteed is that we get an address on the same interface.
+ if (theInterface instanceof Inet6Address) {
+ assertEquals("Failed to return correct interface IPV6",
+ NetworkInterface.getByInetAddress(mss.getInterface()),
+ NetworkInterface.getByInetAddress(theInterface));
+ } else {
+ assertTrue("Failed to return correct interface IPV4 got:" + mss.getInterface() +
+ " expected: " + InetAddress.getLocalHost(),
+ mss.getInterface().equals(InetAddress.getLocalHost()));
+ }
+ mss.close();
+ }
+
+ public void test_setInterface_unbound_address_IPv4() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_setInterface_unbound_address(GOOD_IPv4);
+ }
+
+ public void test_setInterface_unbound_address_IPv6() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_setInterface_unbound_address(GOOD_IPv6);
+ }
+
+ // Regression test for Harmony-2410.
+ private void test_setInterface_unbound_address(InetAddress address) throws Exception {
+ MulticastSocket mss = new MulticastSocket();
+ try {
+ mss.setInterface(address);
+ fail();
+ } catch (SocketException expected) {
+ }
+ mss.close();
+ }
+
+ public void test_setNetworkInterfaceLjava_net_NetworkInterface_null() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ // Validate that null interface is handled ok.
+ MulticastSocket mss = new MulticastSocket();
+ try {
+ mss.setNetworkInterface(null);
+ fail("No socket exception when we set then network interface with NULL");
+ } catch (SocketException ex) {
+ }
+ mss.close();
+ }
+
+ public void test_setNetworkInterfaceLjava_net_NetworkInterface_round_trip() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ // Validate that we can get and set the interface.
+ MulticastSocket mss = new MulticastSocket();
+ mss.setNetworkInterface(ipv4NetworkInterface);
+ assertEquals("Interface did not seem to be set by setNeworkInterface",
+ ipv4NetworkInterface, mss.getNetworkInterface());
+ mss.close();
+ }
+
+ public void test_setNetworkInterfaceLjava_net_NetworkInterface_IPv4() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv4);
+ }
+
+ public void test_setNetworkInterfaceLjava_net_NetworkInterface_IPv6() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv6);
+ }
+
+ private void test_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group)
+ throws IOException, InterruptedException {
+ // Set up the receiving socket and join the group.
+ Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
+ while (theInterfaces.hasMoreElements()) {
+ NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement();
+ if (willWorkForMulticast(thisInterface)) {
+ if ((!(thisInterface.getInetAddresses().nextElement()).isLoopbackAddress())) {
+ MulticastSocket receivingSocket = createReceivingSocket(0);
+ InetSocketAddress groupAddress =
+ new InetSocketAddress(group, receivingSocket.getLocalPort());
+ receivingSocket.joinGroup(groupAddress, thisInterface);
+
+ // Send the packets on a particular interface. The source address in the
+ // received packet should be one of the addresses for the interface set.
+ MulticastSocket sendingSocket = new MulticastSocket(0);
+ sendingSocket.setNetworkInterface(thisInterface);
+ String msg = thisInterface.getName();
+ DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+ sendingSocket.send(sdp);
+
+ DatagramPacket rdp = createReceiveDatagramPacket();
+ receivingSocket.receive(rdp);
+ String receivedMessage = extractMessage(rdp);
+ assertEquals("Group member did not recv data sent on a specific interface",
+ msg, receivedMessage);
+ // Stop the server.
+ receivingSocket.close();
+ sendingSocket.close();
+ }
+ }
+ }
+ }
+
+ public void test_setTimeToLiveI() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket();
+ mss.setTimeToLive(120);
+ assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive());
+ mss.setTimeToLive(220);
+ assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive());
+ mss.close();
+ }
+
+ public void test_setTTLB() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket mss = new MulticastSocket();
+ mss.setTTL((byte) 120);
+ assertEquals("Failed to set TTL", 120, mss.getTTL());
+ mss.close();
+ }
+
+ public void test_ConstructorLjava_net_SocketAddress() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket ms = new MulticastSocket((SocketAddress) null);
+ assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected());
+ ms.bind(null);
+ assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
+ ms.close();
+ assertTrue("should be closed", ms.isClosed());
+
+ ms = new MulticastSocket(0);
+ assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
+ ms.close();
+ assertTrue("should be closed", ms.isClosed());
+
+ ms = new MulticastSocket(0);
+ assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
+ ms.close();
+ assertTrue("should be closed", ms.isClosed());
+
+ try {
+ new MulticastSocket(new InetSocketAddress("unresolvedname", 31415));
+ fail();
+ } catch (IOException expected) {
+ }
+
+ // Regression test for Harmony-1162.
+ InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
+ MulticastSocket s = new MulticastSocket(addr);
+ assertTrue(s.getReuseAddress());
+ s.close();
+ }
+
+ public void test_getLoopbackMode() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket ms = new MulticastSocket(null);
+ assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected());
+ ms.getLoopbackMode();
+ assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected());
+ ms.close();
+ assertTrue("should be closed", ms.isClosed());
+ }
+
+ public void test_setLoopbackModeZ() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ MulticastSocket ms = new MulticastSocket();
+ ms.setLoopbackMode(true);
+ assertTrue("loopback should be true", ms.getLoopbackMode());
+ ms.setLoopbackMode(false);
+ assertTrue("loopback should be false", !ms.getLoopbackMode());
+ ms.close();
+ assertTrue("should be closed", ms.isClosed());
+ }
+
+ public void test_setLoopbackModeSendReceive_IPv4() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_setLoopbackModeSendReceive(GOOD_IPv4);
+ }
+
+ public void test_setLoopbackModeSendReceive_IPv6() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ test_setLoopbackModeSendReceive(GOOD_IPv6);
+ }
+
+ private void test_setLoopbackModeSendReceive(InetAddress group) throws IOException {
+ // Test send receive.
+ final String message = "Hello, world!";
+
+ MulticastSocket socket = new MulticastSocket(0);
+ socket.setLoopbackMode(false); // false indicates doing loop back
+ socket.joinGroup(group);
+
+ // Send the datagram.
+ InetSocketAddress groupAddress = new InetSocketAddress(group, socket.getLocalPort());
+ DatagramPacket sendDatagram = createSendDatagramPacket(groupAddress, message);
+ socket.send(sendDatagram);
+
+ // Receive the datagram.
+ DatagramPacket recvDatagram = createReceiveDatagramPacket();
+ socket.setSoTimeout(5000); // Prevent eternal block in.
+ socket.receive(recvDatagram);
+ String recvMessage = extractMessage(recvDatagram);
+ assertEquals(message, recvMessage);
+ socket.close();
+ }
+
+ public void test_setReuseAddressZ() throws Exception {
+ if (!supportsMulticast) {
+ return;
+ }
+ // Test case were we to set ReuseAddress to false.
+ MulticastSocket theSocket1 = new MulticastSocket(null);
+ theSocket1.setReuseAddress(false);
+
+ MulticastSocket theSocket2 = new MulticastSocket(null);
+ theSocket2.setReuseAddress(false);
+
+ InetSocketAddress addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0);
+ theSocket1.bind(addr);
+ addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort());
+ try {
+ theSocket2.bind(addr);
+ fail("No exception when trying to connect to do duplicate socket bind with re-useaddr"
+ + " set to false");
+ } catch (BindException expected) {
+ }
+ theSocket1.close();
+ theSocket2.close();
+
+ // Test case were we set it to true.
+ theSocket1 = new MulticastSocket(null);
+ theSocket2 = new MulticastSocket(null);
+ theSocket1.setReuseAddress(true);
+ theSocket2.setReuseAddress(true);
+ addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0);
+ theSocket1.bind(addr);
+ addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort());
+ theSocket2.bind(addr);
+
+ theSocket1.close();
+ theSocket2.close();
+
+ // Test the default case which we expect to be the same on all platforms.
+ theSocket1 = new MulticastSocket(null);
+ theSocket2 = new MulticastSocket(null);
+ addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0);
+ theSocket1.bind(addr);
+ addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort());
+ theSocket2.bind(addr);
+ theSocket1.close();
+ theSocket2.close();
+ }
+
+ private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException {
+ return iface.isUp()
+ // Typically loopback interfaces do not support multicast, but we rule them out
+ // explicitly anyway.
+ && !iface.isLoopback() && iface.supportsMulticast()
+ && iface.getInetAddresses().hasMoreElements();
+ }
+
+ private static MulticastSocket createReceivingSocket(int aPort) throws IOException {
+ MulticastSocket ms = new MulticastSocket(aPort);
+ ms.setSoTimeout(2000);
+ return ms;
+ }
+
+ private static DatagramPacket createReceiveDatagramPacket() {
+ byte[] rbuf = new byte[512];
+ return new DatagramPacket(rbuf, rbuf.length);
+ }
+
+ private static DatagramPacket createSendDatagramPacket(
+ InetSocketAddress groupAndPort, String msg) {
+ return new DatagramPacket(
+ msg.getBytes(), msg.length(), groupAndPort.getAddress(), groupAndPort.getPort());
+ }
+
+ private static String extractMessage(DatagramPacket rdp) {
+ return new String(rdp.getData(), 0, rdp.getLength());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/NetworkInterfaceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/NetworkInterfaceTest.java
new file mode 100644
index 0000000..2a93f12
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/NetworkInterfaceTest.java
@@ -0,0 +1,496 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+public class NetworkInterfaceTest extends junit.framework.TestCase {
+
+ // private member variables used for tests
+ Enumeration<NetworkInterface> theInterfaces = null;
+
+ boolean atLeastOneInterface = false;
+
+ boolean atLeastTwoInterfaces = false;
+
+ private NetworkInterface networkInterface1 = null;
+
+ private NetworkInterface sameAsNetworkInterface1 = null;
+
+ private NetworkInterface networkInterface2 = null;
+
+ /**
+ * java.net.NetworkInterface#getName()
+ */
+ public void test_getName() {
+ if (atLeastOneInterface) {
+ assertNotNull("validate that non null name is returned",
+ networkInterface1.getName());
+ assertFalse("validate that non-zero length name is generated",
+ networkInterface1.getName().equals(""));
+ }
+ if (atLeastTwoInterfaces) {
+ assertFalse(
+ "Validate strings are different for different interfaces",
+ networkInterface1.getName().equals(
+ networkInterface2.getName()));
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#getInetAddresses()
+ */
+ public void test_getInetAddresses() throws Exception {
+ if (atLeastOneInterface) {
+ Enumeration theAddresses = networkInterface1.getInetAddresses();
+ while (theAddresses.hasMoreElements()) {
+ InetAddress theAddress = (InetAddress) theAddresses
+ .nextElement();
+ assertNotNull("validate that address is not null", theAddress);
+ }
+ }
+
+ if (atLeastTwoInterfaces) {
+ Enumeration theAddresses = networkInterface2.getInetAddresses();
+ while (theAddresses.hasMoreElements()) {
+ InetAddress theAddress = (InetAddress) theAddresses
+ .nextElement();
+ assertNotNull("validate that address is not null", theAddress);
+ }
+ }
+
+ // create the list of ok and not ok addresses to return
+ if (atLeastOneInterface) {
+ ArrayList okAddresses = new ArrayList();
+ Enumeration addresses = networkInterface1.getInetAddresses();
+ int index = 0;
+ ArrayList notOkAddresses = new ArrayList();
+ while (addresses.hasMoreElements()) {
+ InetAddress theAddress = (InetAddress) addresses.nextElement();
+ okAddresses.add(theAddress);
+ index++;
+ }
+
+ // do the same for network interface 2 if it exists
+ if (atLeastTwoInterfaces) {
+ addresses = networkInterface2.getInetAddresses();
+ index = 0;
+ while (addresses.hasMoreElements()) {
+ InetAddress theAddress = (InetAddress) addresses
+ .nextElement();
+ okAddresses.add(theAddress);
+ index++;
+ }
+ }
+
+ // validate not ok addresses are not returned
+ for (int i = 0; i < notOkAddresses.size(); i++) {
+ Enumeration reducedAddresses = networkInterface1
+ .getInetAddresses();
+ while (reducedAddresses.hasMoreElements()) {
+ InetAddress nextAddress = (InetAddress) reducedAddresses
+ .nextElement();
+ assertTrue(
+ "validate that address without permission is not returned",
+ !nextAddress.equals(notOkAddresses.get(i)));
+ }
+ if (atLeastTwoInterfaces) {
+ reducedAddresses = networkInterface2.getInetAddresses();
+ while (reducedAddresses.hasMoreElements()) {
+ InetAddress nextAddress = (InetAddress) reducedAddresses
+ .nextElement();
+ assertTrue(
+ "validate that address without permission is not returned",
+ !nextAddress.equals(notOkAddresses.get(i)));
+ }
+ }
+ }
+
+ // validate that ok addresses are returned
+ for (int i = 0; i < okAddresses.size(); i++) {
+ boolean addressReturned = false;
+ Enumeration reducedAddresses = networkInterface1
+ .getInetAddresses();
+ while (reducedAddresses.hasMoreElements()) {
+ InetAddress nextAddress = (InetAddress) reducedAddresses
+ .nextElement();
+ if (nextAddress.equals(okAddresses.get(i))) {
+ addressReturned = true;
+ }
+ }
+ if (atLeastTwoInterfaces) {
+ reducedAddresses = networkInterface2.getInetAddresses();
+ while (reducedAddresses.hasMoreElements()) {
+ InetAddress nextAddress = (InetAddress) reducedAddresses
+ .nextElement();
+ if (nextAddress.equals(okAddresses.get(i))) {
+ addressReturned = true;
+ }
+ }
+ }
+ assertTrue("validate that address with permission is returned",
+ addressReturned);
+ }
+
+ // validate that we can get the interface by specifying the address.
+ // This is to be compatible
+ for (int i = 0; i < notOkAddresses.size(); i++) {
+ assertNotNull(
+ "validate we cannot get the NetworkInterface with an address for which we have no privs",
+ NetworkInterface
+ .getByInetAddress((InetAddress) notOkAddresses
+ .get(i)));
+ }
+
+ // validate that we can get the network interface for the good
+ // addresses
+ for (int i = 0; i < okAddresses.size(); i++) {
+ assertNotNull(
+ "validate we cannot get the NetworkInterface with an address fro which we have no privs",
+ NetworkInterface
+ .getByInetAddress((InetAddress) okAddresses
+ .get(i)));
+ }
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#getDisplayName()
+ */
+ public void test_getDisplayName() {
+ if (atLeastOneInterface) {
+ assertNotNull("validate that non null display name is returned",
+ networkInterface1.getDisplayName());
+ assertFalse(
+ "validate that non-zero length display name is generated",
+ networkInterface1.getDisplayName().equals(""));
+ }
+ if (atLeastTwoInterfaces) {
+ assertFalse(
+ "Validate strings are different for different interfaces",
+ networkInterface1.getDisplayName().equals(
+ networkInterface2.getDisplayName()));
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#getByName(java.lang.String)
+ */
+ public void test_getByNameLjava_lang_String() throws Exception {
+ try {
+ assertNull("validate null handled ok",
+ NetworkInterface.getByName(null));
+ fail("getByName did not throw NullPointerException for null argument");
+ } catch (NullPointerException e) {
+ }
+
+ assertNull("validate handled ok if we ask for name not associated with any interface",
+ NetworkInterface.getByName("8not a name4"));
+
+ // for each address in an interface validate that we get the right
+ // interface for that name
+ if (atLeastOneInterface) {
+ String theName = networkInterface1.getName();
+ if (theName != null) {
+ assertEquals(
+ "validate that Interface can be obtained with its name",
+ networkInterface1, NetworkInterface.getByName(theName));
+ }
+ }
+
+ // validate that we get the right interface with the second interface as
+ // well (ie we just don't always get the first interface
+ if (atLeastTwoInterfaces) {
+ String theName = networkInterface2.getName();
+ if (theName != null) {
+ assertEquals(
+ "validate that Interface can be obtained with its name",
+ networkInterface2, NetworkInterface.getByName(theName));
+ }
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#getByInetAddress(java.net.InetAddress)
+ */
+ public void test_getByInetAddressLjava_net_InetAddress() throws Exception {
+
+ byte addressBytes[] = new byte[4];
+ addressBytes[0] = 0;
+ addressBytes[1] = 0;
+ addressBytes[2] = 0;
+ addressBytes[3] = 0;
+
+ try {
+ assertNull("validate null handled ok",
+ NetworkInterface.getByInetAddress(null));
+ fail("should not get here if getByInetAddress throws "
+ + "NullPointerException if null passed in");
+ } catch (NullPointerException e) {
+ }
+
+ assertNull("validate handled ok if we ask for address not associated with any interface",
+ NetworkInterface.getByInetAddress(InetAddress
+ .getByAddress(addressBytes)));
+
+ // for each address in an interface validate that we get the right
+ // interface for that address
+ if (atLeastOneInterface) {
+ Enumeration addresses = networkInterface1.getInetAddresses();
+ while (addresses.hasMoreElements()) {
+ InetAddress theAddress = (InetAddress) addresses.nextElement();
+ assertEquals(
+ "validate that Interface can be obtained with any one of its addresses",
+ networkInterface1, NetworkInterface
+ .getByInetAddress(theAddress));
+ }
+ }
+
+ // validate that we get the right interface with the second interface as
+ // well (ie we just don't always get the first interface
+ if (atLeastTwoInterfaces) {
+ Enumeration addresses = networkInterface2.getInetAddresses();
+ while (addresses.hasMoreElements()) {
+ InetAddress theAddress = (InetAddress) addresses.nextElement();
+ assertEquals(
+ "validate that Interface can be obtained with any one of its addresses",
+ networkInterface2, NetworkInterface
+ .getByInetAddress(theAddress));
+ }
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#getNetworkInterfaces()
+ */
+ public void test_getNetworkInterfaces() throws Exception {
+
+ // really this is tested by all of the other calls but just make sure we
+ // can call it and get a list of interfaces if they exist
+ Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
+ }
+
+ /**
+ * java.net.NetworkInterface#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.net.SocketPermission.equals(java.lang.Object)
+ if (atLeastOneInterface) {
+ assertEquals("If objects are the same true is returned",
+ sameAsNetworkInterface1, networkInterface1);
+ assertNotNull("Validate Null handled ok", networkInterface1);
+ }
+ if (atLeastTwoInterfaces) {
+ assertFalse("If objects are different false is returned",
+ networkInterface1.equals(networkInterface2));
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#hashCode()
+ */
+ public void test_hashCode() {
+
+ if (atLeastOneInterface) {
+ assertTrue(
+ "validate that hash codes are the same for two calls on the same object",
+ networkInterface1.hashCode() == networkInterface1
+ .hashCode());
+ assertTrue(
+ "validate that hash codes are the same for two objects for which equals is true",
+ networkInterface1.hashCode() == sameAsNetworkInterface1
+ .hashCode());
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#toString()
+ */
+ public void test_toString() {
+ if (atLeastOneInterface) {
+ assertNotNull("validate that non null string is generated",
+ networkInterface1.toString());
+ assertFalse("validate that non-zero length string is generated",
+ networkInterface1.toString().equals(""));
+
+ }
+ if (atLeastTwoInterfaces) {
+ assertFalse(
+ "Validate strings are different for different interfaces",
+ networkInterface1.toString().equals(
+ networkInterface2.toString()));
+
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#getInterfaceAddresses()
+ * @since 1.6
+ */
+ public void test_getInterfaceAddresses() throws SocketException {
+ if (theInterfaces != null) {
+ while (theInterfaces.hasMoreElements()) {
+ NetworkInterface netif = theInterfaces.nextElement();
+ assertEquals(netif.getName()
+ + " getInterfaceAddresses should contain no element", 0,
+ netif.getInterfaceAddresses().size());
+ }
+
+ theInterfaces = NetworkInterface.getNetworkInterfaces();
+ while (theInterfaces.hasMoreElements()) {
+ NetworkInterface netif = theInterfaces.nextElement();
+ List<InterfaceAddress> interfaceAddrs = netif.getInterfaceAddresses();
+ assertTrue(interfaceAddrs instanceof ArrayList);
+ for (InterfaceAddress addr : interfaceAddrs) {
+ assertNotNull(addr);
+ }
+
+ List<InterfaceAddress> interfaceAddrs2 = netif.getInterfaceAddresses();
+ // RI fails on this since it cannot tolerate null broadcast address.
+ assertEquals(interfaceAddrs, interfaceAddrs2);
+ }
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#isLoopback()
+ * @since 1.6
+ */
+ public void test_isLoopback() throws SocketException {
+ if (theInterfaces != null) {
+ while (theInterfaces.hasMoreElements()) {
+ NetworkInterface netif = theInterfaces.nextElement();
+ boolean loopback = false;
+ Enumeration<InetAddress> addrs = netif.getInetAddresses();
+ while (addrs != null && addrs.hasMoreElements()) {
+ if (addrs.nextElement().isLoopbackAddress()) {
+ loopback = true;
+ break;
+ }
+ }
+ assertEquals(loopback, netif.isLoopback());
+ }
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#getHardwareAddress()
+ * @since 1.6
+ */
+ public void test_getHardwareAddress() throws SocketException {
+ if (theInterfaces != null) {
+ while (theInterfaces.hasMoreElements()) {
+ NetworkInterface netif = theInterfaces.nextElement();
+ byte[] hwAddr = netif.getHardwareAddress();
+ if (netif.isLoopback()) {
+ assertTrue(hwAddr == null || hwAddr.length == 0);
+ } else {
+ assertTrue(hwAddr.length >= 0);
+ }
+ }
+ }
+ }
+
+ /**
+ * java.net.NetworkInterface#getHardwareAddress()
+ * @since 1.6
+ */
+ public void test_getMTU() throws SocketException {
+ if (theInterfaces != null) {
+ while (theInterfaces.hasMoreElements()) {
+ NetworkInterface netif = theInterfaces.nextElement();
+ assertTrue(netif.getName() + "has non-positive MTU", netif.getMTU() >= 0);
+ }
+ }
+ }
+
+ protected void setUp() throws SocketException {
+
+ Enumeration theInterfaces = null;
+ try {
+ theInterfaces = NetworkInterface.getNetworkInterfaces();
+ } catch (Exception e) {
+ fail("Exception occurred getting network interfaces : " + e);
+ }
+
+ // Set up NetworkInterface instance members. Note that because the call
+ // to NetworkInterface.getNetworkInterfaces() returns *all* of the
+ // interfaces on the test machine it is possible that one or more of
+ // them will not currently be bound to an InetAddress. e.g. a laptop
+ // running connected by a wire to the local network may also have a
+ // wireless interface that is not active and so has no InetAddress
+ // bound to it. For these tests only work with NetworkInterface objects
+ // that are bound to an InetAddress.
+ if ((theInterfaces != null) && (theInterfaces.hasMoreElements())) {
+ while ((theInterfaces.hasMoreElements())
+ && (atLeastOneInterface == false)) {
+ NetworkInterface theInterface = (NetworkInterface) theInterfaces
+ .nextElement();
+ if (theInterface.getInetAddresses().hasMoreElements()) {
+ // Ensure that the current NetworkInterface has at least
+ // one InetAddress bound to it.
+ Enumeration addrs = theInterface.getInetAddresses();
+ if ((addrs != null) && (addrs.hasMoreElements())) {
+ atLeastOneInterface = true;
+ networkInterface1 = theInterface;
+ }// end if
+ }
+ }
+
+ while ((theInterfaces.hasMoreElements())
+ && (atLeastTwoInterfaces == false)) {
+ NetworkInterface theInterface = (NetworkInterface) theInterfaces
+ .nextElement();
+ if (theInterface.getInetAddresses().hasMoreElements()) {
+ // Ensure that the current NetworkInterface has at least
+ // one InetAddress bound to it.
+ Enumeration addrs = theInterface.getInetAddresses();
+ if ((addrs != null) && (addrs.hasMoreElements())) {
+ atLeastTwoInterfaces = true;
+ networkInterface2 = theInterface;
+ }// end if
+ }
+ }
+
+ // Only set sameAsNetworkInterface1 if we succeeded in finding
+ // at least one good NetworkInterface
+ if (atLeastOneInterface) {
+ Enumeration addresses = networkInterface1.getInetAddresses();
+ if (addresses.hasMoreElements()) {
+ try {
+ if (addresses.hasMoreElements()) {
+ sameAsNetworkInterface1 = NetworkInterface
+ .getByInetAddress((InetAddress) addresses
+ .nextElement());
+ }
+ } catch (SocketException e) {
+ fail("SocketException occurred : " + e);
+ }
+ }
+ }// end if atLeastOneInterface
+ }
+ theInterfaces = NetworkInterface.getNetworkInterfaces();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/NoRouteToHostExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/NoRouteToHostExceptionTest.java
new file mode 100644
index 0000000..89fe4fd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/NoRouteToHostExceptionTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.NoRouteToHostException;
+
+public class NoRouteToHostExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.NoRouteToHostException#NoRouteToHostException()
+ */
+ public void test_Constructor() {
+ try {
+ if (true) {
+ throw new NoRouteToHostException();
+ }
+ fail("Failed to generate expected exception");
+ } catch (NoRouteToHostException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.NoRouteToHostException#NoRouteToHostException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Cannot test correctly without changing some routing tables !!
+ try {
+ if (true) {
+ throw new NoRouteToHostException("test");
+ }
+ fail("Failed to generate expected exception");
+ } catch (NoRouteToHostException e) {
+ assertEquals("Threw exception with incorrect message", "test", e
+ .getMessage());
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/PasswordAuthenticationTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/PasswordAuthenticationTest.java
new file mode 100644
index 0000000..bbb3011
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/PasswordAuthenticationTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.PasswordAuthentication;
+
+public class PasswordAuthenticationTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.PasswordAuthentication#PasswordAuthentication(java.lang.String,
+ *char[])
+ */
+ public void test_ConstructorLjava_lang_String$C() {
+ // Test for method java.net.PasswordAuthentication(java.lang.String,
+ // char [])
+ char[] password = new char[] { 'd', 'r', 'o', 'w', 's', 's', 'a', 'p' };
+ final String name = "Joe Blow";
+ PasswordAuthentication pa = new PasswordAuthentication(name, password);
+ char[] returnedPassword = pa.getPassword();
+ assertTrue("Incorrect name", pa.getUserName().equals(name));
+ assertTrue("Password was not cloned", returnedPassword != password);
+ assertTrue("Passwords not equal length",
+ returnedPassword.length == password.length);
+ for (int counter = password.length - 1; counter >= 0; counter--)
+ assertTrue("Passwords not equal",
+ returnedPassword[counter] == password[counter]);
+ }
+
+ /**
+ * java.net.PasswordAuthentication#getPassword()
+ */
+ public void test_getPassword() {
+ // Test for method char [] java.net.PasswordAuthentication.getPassword()
+ assertTrue("Used to test", true);
+ }
+
+ /**
+ * java.net.PasswordAuthentication#getUserName()
+ */
+ public void test_getUserName() {
+ // Test for method java.lang.String
+ // java.net.PasswordAuthentication.getUserName()
+ assertTrue("Used to test", true);
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProtocolExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProtocolExceptionTest.java
new file mode 100644
index 0000000..d0fe2d9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProtocolExceptionTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.ProtocolException;
+
+public class ProtocolExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.ProtocolException#ProtocolException()
+ */
+ public void test_Constructor() {
+ // Test for method java.net.ProtocolException()
+ try {
+ throw new ProtocolException();
+ } catch (ProtocolException e) {
+ return;
+ } catch (Exception e) {
+ fail("Exception during ProtocolException test : " + e.getMessage());
+ }
+ fail("Failed to generate expected exception");
+ }
+
+ /**
+ * java.net.ProtocolException#ProtocolException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.net.ProtocolException(java.lang.String)
+ try {
+ throw new ProtocolException("Some error message");
+ } catch (ProtocolException e) {
+ return;
+ } catch (Exception e) {
+ fail("Exception during ProtocolException test : " + e.getMessage());
+ }
+ fail("Failed to generate expected exception");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProxySelectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProxySelectorTest.java
new file mode 100644
index 0000000..3a3bbfe
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProxySelectorTest.java
@@ -0,0 +1,562 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.NetPermission;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.Permission;
+import java.util.List;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+public class ProxySelectorTest extends TestCase {
+
+ private static final String HTTP_PROXY_HOST = "127.0.0.1";
+
+ private static final int HTTP_PROXY_PORT = 80;
+
+ private static final String HTTPS_PROXY_HOST = "127.0.0.2";
+
+ private static final int HTTPS_PROXY_PORT = 443;
+
+ private static final String FTP_PROXY_HOST = "127.0.0.3";
+
+ private static final int FTP_PROXY_PORT = 80;
+
+ private static final String SOCKS_PROXY_HOST = "127.0.0.4";
+
+ private static final int SOCKS_PROXY_PORT = 1080;
+
+ private static URI httpUri;
+
+ private static URI ftpUri;
+
+ private static URI httpsUri;
+
+ private static URI tcpUri;
+
+ private List proxyList;
+
+ private ProxySelector selector = ProxySelector.getDefault();
+
+ static {
+ try {
+ httpUri = new URI("http://test.com");
+ ftpUri = new URI("ftp://test.com");
+ httpsUri = new URI("https://test.com");
+ tcpUri = new URI("socket://host.com");
+ } catch (URISyntaxException e) {
+
+ }
+ }
+
+ /*
+ * Original system properties must be restored after running each test case.
+ */
+ private Properties originalSystemProperties;
+
+ /**
+ * java.net.ProxySelector#getDefault()
+ */
+ public void test_getDefault() {
+ ProxySelector selector1 = ProxySelector.getDefault();
+ assertNotNull(selector1);
+
+ ProxySelector selector2 = ProxySelector.getDefault();
+ assertSame(selector1, selector2);
+ }
+
+ /**
+ * java.net.ProxySelector#setDefault(ProxySelector)}
+ */
+ public void test_setDefaultLjava_net_ProxySelector() {
+ ProxySelector originalSelector = ProxySelector.getDefault();
+ try {
+ ProxySelector newSelector = new MockProxySelector();
+ ProxySelector.setDefault(newSelector);
+ assertSame(newSelector, ProxySelector.getDefault());
+ // use null to unset
+ ProxySelector.setDefault(null);
+ assertSame(null, ProxySelector.getDefault());
+ } finally {
+ ProxySelector.setDefault(originalSelector);
+ }
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectExact()
+ throws URISyntaxException {
+ // no proxy, return a proxyList only contains NO_PROXY
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.NO_PROXY);
+
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+ System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST, HTTP_PROXY_PORT);
+
+ proxyList = selector.select(httpsUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTPS_PROXY_HOST, HTTPS_PROXY_PORT);
+
+ proxyList = selector.select(ftpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, FTP_PROXY_HOST, FTP_PROXY_PORT);
+
+ proxyList = selector.select(tcpUri);
+ assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectExact_NullHost()
+ throws URISyntaxException {
+ // regression test for Harmony-1063
+ httpUri = new URI("http://a@");
+ ftpUri = new URI("ftp://a@");
+ httpsUri = new URI("https://a@");
+ tcpUri = new URI("socket://a@");
+ // no proxy, return a proxyList only contains NO_PROXY
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.NO_PROXY);
+
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+ System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST,
+ HTTP_PROXY_PORT);
+
+ proxyList = selector.select(httpsUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTPS_PROXY_HOST,
+ HTTPS_PROXY_PORT);
+
+ proxyList = selector.select(ftpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, FTP_PROXY_HOST,
+ FTP_PROXY_PORT);
+
+ proxyList = selector.select(tcpUri);
+ assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST,
+ SOCKS_PROXY_PORT);
+
+ }
+
+ //Regression for HARMONY-4281
+ public void test_selectLjava_net_URI_SelectExact_NullHost_withNoProxyHostsProperty() {
+ System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1");
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+ System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST,
+ HTTP_PROXY_PORT);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectExact_DefaultPort()
+ throws URISyntaxException {
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST, HTTP_PROXY_PORT);
+
+ proxyList = selector.select(httpsUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTPS_PROXY_HOST, HTTPS_PROXY_PORT);
+
+ proxyList = selector.select(ftpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, FTP_PROXY_HOST, FTP_PROXY_PORT);
+
+ proxyList = selector.select(tcpUri);
+ assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectExact_InvalidPort()
+ throws URISyntaxException {
+ final String INVALID_PORT = "abc";
+
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", INVALID_PORT);
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", INVALID_PORT);
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", INVALID_PORT);
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+ System.setProperty("socksproxyPort", INVALID_PORT);
+
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST, HTTP_PROXY_PORT);
+
+ proxyList = selector.select(httpsUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTPS_PROXY_HOST, HTTPS_PROXY_PORT);
+
+ proxyList = selector.select(ftpUri);
+ assertProxyEquals(proxyList, Proxy.Type.HTTP, FTP_PROXY_HOST, FTP_PROXY_PORT);
+
+ proxyList = selector.select(tcpUri);
+ assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ // RI may fail this test case.
+ // Uncomment this test case when regex.jar is ready.
+ /*
+ public void test_selectLjava_net_URI_Select_NonProxyHosts()
+ throws URISyntaxException {
+ // RI's bug. Some RIs may fail this test case.
+ URI[] httpUris = { new URI("http://test.com"),
+ new URI("http://10.10.1.2"), new URI("http://a"),
+ new URI("http://def.abc.com") };
+ URI[] ftpUris = { new URI("ftp://test.com"),
+ new URI("ftp://10.10.1.2"), new URI("ftp://a"),
+ new URI("ftp://def.abc.com") };
+
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.nonProxyHosts", "a|b|tes*|10.10.*|*.abc.com");
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.nonProxyHosts", "a|b|tes*|10.10.*|*.abc.com");
+
+ for (int i = 0; i < httpUris.length; i++) {
+ proxyList = selector.select(httpUris[i]);
+ assertProxyEquals(proxyList,Proxy.NO_PROXY);
+ }
+
+ for (int i = 0; i < ftpUris.length; i++) {
+ proxyList = selector.select(ftpUris[i]);
+ assertProxyEquals(proxyList,Proxy.NO_PROXY);
+ }
+ }*/
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectLikeHTTP()
+ throws URISyntaxException {
+ System.setProperty("http.proxyHost", "");
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+ System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectNoHTTP()
+ throws URISyntaxException {
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+
+ proxyList = selector.select(httpUri);
+ assertProxyEquals(proxyList, Proxy.NO_PROXY);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectLikeHTTPS()
+ throws URISyntaxException {
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set https proxy host empty
+ System.setProperty("http.proxyHost", "");
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+ System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+ proxyList = selector.select(httpsUri);
+ assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectNoHTTPS()
+ throws URISyntaxException {
+ // set https proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+
+ proxyList = selector.select(httpsUri);
+ assertProxyEquals(proxyList, Proxy.NO_PROXY);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectLikeFTP()
+ throws URISyntaxException {
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set ftp host empty
+ System.setProperty("ftp.proxyHost", "");
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+ System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+ proxyList = selector.select(ftpUri);
+ assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectNoFTP()
+ throws URISyntaxException {
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+
+ proxyList = selector.select(ftpUri);
+ assertProxyEquals(proxyList, Proxy.NO_PROXY);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_SelectNoSOCKS()
+ throws URISyntaxException {
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+ // set socks proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+
+ proxyList = selector.select(tcpUri);
+ assertProxyEquals(proxyList, Proxy.NO_PROXY);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_connectionFailedLjava_net_URILjava_net_SocketAddressLjava_io_IOException()
+ throws URISyntaxException {
+ // set http proxy
+ System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+ System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+ // set https proxy
+ System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+ System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+ // set ftp proxy
+ System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+ System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+ // set socks proxy
+ System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+ System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+ List proxyList1 = selector.select(httpUri);
+ assertNotNull(proxyList1);
+ assertEquals(1, proxyList1.size());
+ Proxy proxy1 = (Proxy) proxyList1.get(0);
+ selector
+ .connectFailed(httpUri, proxy1.address(), new SocketException());
+
+ List proxyList2 = selector.select(httpUri);
+ assertNotNull(proxyList2);
+ assertEquals(1, proxyList2.size());
+ Proxy proxy2 = (Proxy) proxyList2.get(0);
+ // Default implementation doesn't change the proxy list
+ assertEquals(proxy1, proxy2);
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_connectionFailedLjava_net_URILjava_net_SocketAddressLjava_io_IOException_IllegalArguement()
+ throws URISyntaxException {
+ SocketAddress sa = InetSocketAddress.createUnresolved("127.0.0.1", 0);
+ try {
+ selector.connectFailed(null, sa, new SocketException());
+ fail("should throw IllegalArgumentException if any argument is null.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ selector.connectFailed(httpUri, null, new SocketException());
+ fail("should throw IllegalArgumentException if any argument is null.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ selector.connectFailed(httpUri, sa, null);
+ fail("should throw IllegalArgumentException if any argument is null.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * java.net.ProxySelector#select(URI)
+ */
+ public void test_selectLjava_net_URI_IllegalArgument()
+ throws URISyntaxException {
+ URI[] illegalUris = { new URI("abc"), new URI("http"), null };
+ for (int i = 0; i < illegalUris.length; i++) {
+ try {
+ selector.select(illegalUris[i]);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+ }
+
+ /*
+ * asserts whether selectedProxyList contains one and only one element,
+ * and the element equals proxy.
+ */
+ private void assertProxyEquals(List selectedProxyList, Proxy proxy) {
+ assertNotNull(selectedProxyList);
+ assertEquals(1, selectedProxyList.size());
+ assertEquals((Proxy) selectedProxyList.get(0), proxy);
+ }
+
+ /*
+ * asserts whether selectedProxyList contains one and only one element,
+ * and the element equals proxy which is represented by arguments "type",
+ * "host","port".
+ */
+ private void assertProxyEquals(List selectedProxyList, Proxy.Type type,
+ String host, int port) {
+ SocketAddress sa = InetSocketAddress.createUnresolved(host, port);
+ Proxy proxy = new Proxy(type, sa);
+ assertProxyEquals(selectedProxyList, proxy);
+ }
+
+ /*
+ * Mock selector for setDefault test
+ */
+ static class MockProxySelector extends ProxySelector {
+
+ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+
+ }
+
+ public List<Proxy> select(URI uri) {
+ return null;
+ }
+ }
+
+ /*
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ // save original system properties
+ originalSystemProperties = (Properties) System.getProperties().clone();
+ }
+
+ /*
+ * @see junit.framework.TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ // restore original system properties
+ System.setProperties(originalSystemProperties);
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProxyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProxyTest.java
new file mode 100644
index 0000000..0487537
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ProxyTest.java
@@ -0,0 +1,238 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.net;
+
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.SocketAddress;
+
+import junit.framework.TestCase;
+
+public class ProxyTest extends TestCase {
+
+ private SocketAddress address = new InetSocketAddress("127.0.0.1", 1234);
+
+ /**
+ * java.net.Proxy#Proxy(java.net.Proxy.Type, SocketAddress)
+ */
+ public void test_ConstructorLjava_net_ProxyLjava_net_SocketAddress_Normal() {
+ // test HTTP type proxy
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
+ assertEquals(Proxy.Type.HTTP, proxy.type());
+ assertEquals(address, proxy.address());
+
+ // test SOCKS type proxy
+ proxy = new Proxy(Proxy.Type.SOCKS, address);
+ assertEquals(Proxy.Type.SOCKS, proxy.type());
+ assertEquals(address, proxy.address());
+
+ // test DIRECT type proxy
+ proxy = Proxy.NO_PROXY;
+ assertEquals(Proxy.Type.DIRECT, proxy.type());
+ assertNull(proxy.address());
+ }
+
+ /**
+ * java.net.Proxy#Proxy(java.net.Proxy.Type, SocketAddress)
+ */
+ public void test_ConstructorLjava_net_ProxyLjava_net_SocketAddress_IllegalAddress() {
+ Proxy proxy = null;
+ // test HTTP type proxy
+ try {
+ proxy = new Proxy(Proxy.Type.HTTP, null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ // test SOCKS type proxy
+ try {
+ proxy = new Proxy(Proxy.Type.SOCKS, null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ // test DIRECT type proxy
+ try {
+ proxy = new Proxy(Proxy.Type.DIRECT, null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ // test DIRECT type proxy, any address is illegal
+ try {
+ proxy = new Proxy(Proxy.Type.DIRECT, address);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * java.net.Proxy#hashCode()
+ * @see also see test_equalsLjava_lang_Object_Equals
+ */
+ public void test_hashCode() {
+ // This method has been tested in test_equalsLjava_lang_Object_Equals.
+ }
+
+ /**
+ * java.net.Proxy#type()
+ */
+ public void test_type() {
+ // This method has been tested in test_ConstructorLjava_net_ProxyLjava_net_SocketAddress_Normal.
+ }
+
+ /**
+ * java.net.Proxy#address() This method has been tested in
+ * Constructor test case.
+ */
+ public void test_address() {
+ // This method has been tested in test_ConstructorLjava_net_ProxyLjava_net_SocketAddress_Normal.
+ }
+
+ /**
+ * java.net.Proxy#toString()
+ */
+ public void test_toString() {
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
+ // include type String
+ assertTrue(proxy.toString().indexOf(proxy.type().toString()) != -1);
+ // include address String
+ assertTrue(proxy.toString().indexOf(proxy.address().toString()) != -1);
+
+ proxy = new Proxy(Proxy.Type.SOCKS, address);
+ // include type String
+ assertTrue(proxy.toString().indexOf(proxy.type().toString()) != -1);
+ // include address String
+ assertTrue(proxy.toString().indexOf(proxy.address().toString()) != -1);
+
+ proxy = Proxy.NO_PROXY;
+ // include type String
+ assertTrue(proxy.toString().indexOf(proxy.type().toString()) != -1);
+
+ proxy = new Proxy(null, address);
+ // ensure no NPE is thrown
+ proxy.toString();
+
+ // Regression test for Java 6 spec change
+ proxy = new Proxy(Proxy.Type.HTTP, address);
+ assertTrue(proxy.toString().contains("@"));
+ proxy = new Proxy(Proxy.Type.SOCKS, address);
+ assertTrue(proxy.toString().contains(address.toString()));
+ }
+
+ /**
+ * java.net.Proxy#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object_Equals() {
+ SocketAddress address1 = new InetSocketAddress("127.0.0.1", 1234);
+ SocketAddress address2 = new InetSocketAddress("127.0.0.1", 1234);
+ // HTTP type
+ Proxy proxy1 = new Proxy(Proxy.Type.HTTP, address1);
+ Proxy proxy2 = new Proxy(Proxy.Type.HTTP, address2);
+ assertTrue(proxy1.equals(proxy2));
+ // assert hashCode
+ assertTrue(proxy1.hashCode() == proxy2.hashCode());
+
+ // SOCKS type
+ Proxy proxy3 = new Proxy(Proxy.Type.SOCKS, address1);
+ Proxy proxy4 = new Proxy(Proxy.Type.SOCKS, address2);
+ assertTrue(proxy3.equals(proxy4));
+ // assert hashCode
+ assertTrue(proxy3.hashCode() == proxy4.hashCode());
+
+ // null type
+ Proxy proxy5 = new Proxy(null, address1);
+ Proxy proxy6 = new Proxy(null, address2);
+ assertTrue(proxy5.equals(proxy6));
+ }
+
+ /**
+ * java.net.Proxy#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object_NotEquals() {
+ SocketAddress address1 = new InetSocketAddress("127.0.0.1", 1234);
+ SocketAddress address2 = new InetSocketAddress("127.0.0.1", 1235);
+ Proxy proxy[] = { new Proxy(Proxy.Type.HTTP, address1),
+ new Proxy(Proxy.Type.HTTP, address2),
+ new Proxy(Proxy.Type.SOCKS, address1),
+ new Proxy(Proxy.Type.SOCKS, address2), Proxy.NO_PROXY,
+ new Proxy(null, address1), new Proxy(null, address2) };
+ // All of them are not equals
+ for (int i = 0; i < proxy.length; i++) {
+ for (int j = i + 1; j < proxy.length; j++) {
+ assertFalse(proxy[i].equals(proxy[j]));
+ }
+ }
+ // Not equals to an Object type instance. Ensure no exception is thrown.
+ assertFalse(proxy[0].equals(new Object()));
+ }
+
+ /**
+ * java.net.Proxy.Type#valueOf(String)
+ */
+ public void test_Type_valueOfLjava_lang_String_Normal() {
+ assertEquals(Proxy.Type.DIRECT, Proxy.Type.valueOf("DIRECT"));
+ assertEquals(Proxy.Type.HTTP, Proxy.Type.valueOf("HTTP"));
+ assertEquals(Proxy.Type.SOCKS, Proxy.Type.valueOf("SOCKS"));
+ }
+
+ /**
+ * java.net.Proxy.Type#valueOf(String)
+ */
+ public void test_Type_valueOfLjava_lang_String_IllegalName() {
+ String[] illegalName = { "Direct", "direct", "http", "socks",
+ "illegalName", "" };
+ for (int i = 0; i < illegalName.length; i++) {
+ try {
+ Proxy.Type.valueOf(illegalName[i]);
+ fail("should throw IllegalArgumentException, illegalName:"
+ + illegalName);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+ }
+
+ /**
+ * java.net.Proxy.Type#valueOf(String)
+ */
+ public void test_Type_valueOfLjava_lang_String_NullPointerException() {
+ // Some old RIs,which throw IllegalArgumentException.
+ // Latest RIs throw NullPointerException.
+ try {
+ Proxy.Type.valueOf(null);
+ fail("should throw an exception.");
+ } catch (NullPointerException e) {
+ // May be caused by some compilers' code
+ } catch (IllegalArgumentException e) {
+ // other compilers will throw this
+ }
+ }
+
+ /**
+ * java.net.Proxy.Type#values()
+ */
+ public void test_Type_values() {
+ Proxy.Type types[] = Proxy.Type.values();
+ assertEquals(3, types.length);
+ assertEquals(Proxy.Type.DIRECT, types[0]);
+ assertEquals(Proxy.Type.HTTP, types[1]);
+ assertEquals(Proxy.Type.SOCKS, types[2]);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ResponseCacheTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ResponseCacheTest.java
new file mode 100644
index 0000000..4e79e4a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ResponseCacheTest.java
@@ -0,0 +1,70 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.NetPermission;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.net.URLConnection;
+import java.security.Permission;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class ResponseCacheTest extends TestCase {
+
+ /**
+ * java.net.ResponseCache#getDefault()
+ */
+ public void test_GetDefault() throws Exception {
+ assertNull(ResponseCache.getDefault());
+ }
+
+ /**
+ * java.net.ResponseCache#setDefault(ResponseCache)
+ */
+ public void test_SetDefaultLjava_net_ResponseCache_Normal()
+ throws Exception {
+ ResponseCache rc1 = new MockResponseCache();
+ ResponseCache rc2 = new MockResponseCache();
+ ResponseCache.setDefault(rc1);
+ assertSame(ResponseCache.getDefault(), rc1);
+ ResponseCache.setDefault(rc2);
+ assertSame(ResponseCache.getDefault(), rc2);
+ ResponseCache.setDefault(null);
+ assertNull(ResponseCache.getDefault());
+ }
+
+ /*
+ * MockResponseCache for testSetDefault(ResponseCache)
+ */
+ class MockResponseCache extends ResponseCache {
+
+ public CacheResponse get(URI arg0, String arg1, Map arg2)
+ throws IOException {
+ return null;
+ }
+
+ public CacheRequest put(URI arg0, URLConnection arg1)
+ throws IOException {
+ return null;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SecureCacheResponseTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SecureCacheResponseTest.java
new file mode 100644
index 0000000..ab78d65
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SecureCacheResponseTest.java
@@ -0,0 +1,85 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.SecureCacheResponse;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+
+import junit.framework.TestCase;
+
+public class SecureCacheResponseTest extends TestCase {
+
+ public void testSecureCacheResponse() {
+ // test constructor
+ SecureCacheResponse sc = new MockCacheResponse();
+ // nothing happened
+ assertNull(sc.getCipherSuite());
+ }
+
+ class MockCacheResponse extends SecureCacheResponse {
+
+ @Override
+ public String getCipherSuite() {
+ // do nothing
+ return null;
+ }
+
+ @Override
+ public List<Certificate> getLocalCertificateChain() {
+ // do nothing
+ return null;
+ }
+
+ @Override
+ public Principal getLocalPrincipal() {
+ // do nothing
+ return null;
+ }
+
+ @Override
+ public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+ // do nothing
+ return null;
+ }
+
+ @Override
+ public List<Certificate> getServerCertificateChain() throws SSLPeerUnverifiedException {
+ // do nothing
+ return null;
+ }
+
+ @Override
+ public InputStream getBody() throws IOException {
+ // do nothing
+ return null;
+ }
+
+ @Override
+ public Map<String, List<String>> getHeaders() throws IOException {
+ // do nothing
+ return null;
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java
new file mode 100644
index 0000000..d7ef745
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java
@@ -0,0 +1,950 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import tests.support.Support_Configuration;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.BindException;
+import java.net.ConnectException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.PlainServerSocketImpl;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketImplFactory;
+import java.net.UnknownHostException;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Properties;
+
+public class ServerSocketTest extends junit.framework.TestCase {
+
+ boolean interrupted;
+
+ ServerSocket s;
+
+ Socket sconn;
+
+ Thread t;
+
+ static class SSClient implements Runnable {
+ Socket cs;
+
+ int port;
+
+ public SSClient(int prt) {
+ port = prt;
+ }
+
+ public void run() {
+ try {
+ // Go to sleep so the server can setup and wait for connection
+ Thread.sleep(1000);
+ cs = new Socket(InetAddress.getLocalHost().getHostName(), port);
+ // Sleep again to allow server side processing. Thread is
+ // stopped by server.
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ return;
+ } catch (Throwable e) {
+ System.out
+ .println("Error establishing client: " + e.toString());
+ } finally {
+ try {
+ if (cs != null)
+ cs.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#ServerSocket()
+ */
+ public void test_Constructor() {
+ // Test for method java.net.ServerSocket(int)
+ assertTrue("Used during tests", true);
+ }
+
+ /**
+ * java.net.ServerSocket#ServerSocket(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.net.ServerSocket(int)
+ assertTrue("Used during tests", true);
+ }
+
+ /**
+ * java.net.ServerSocket#ServerSocket(int)
+ */
+ public void test_ConstructorI_SocksSet() throws IOException {
+ // Harmony-623 regression test
+ ServerSocket ss = null;
+ Properties props = (Properties) System.getProperties().clone();
+ try {
+ System.setProperty("socksProxyHost", "127.0.0.1");
+ System.setProperty("socksProxyPort", "12345");
+ ss = new ServerSocket(0);
+ } finally {
+ System.setProperties(props);
+ if (null != ss) {
+ ss.close();
+ }
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#ServerSocket(int, int)
+ */
+ public void test_ConstructorII() throws IOException {
+ try {
+ s = new ServerSocket(0, 10);
+ s.setSoTimeout(2000);
+ startClient(s.getLocalPort());
+ sconn = s.accept();
+ } catch (InterruptedIOException e) {
+ return;
+ }
+
+ ServerSocket s1 = new ServerSocket(0);
+ try {
+ try {
+ ServerSocket s2 = new ServerSocket(s1.getLocalPort());
+ s2.close();
+ fail("Was able to create two serversockets on same port");
+ } catch (BindException e) {
+ // Expected
+ }
+ } finally {
+ s1.close();
+ }
+
+ s1 = new ServerSocket(0);
+ int allocatedPort = s1.getLocalPort();
+ s1.close();
+ s1 = new ServerSocket(allocatedPort);
+ s1.close();
+ }
+
+ /**
+ * java.net.ServerSocket#ServerSocket(int, int, java.net.InetAddress)
+ */
+ public void test_ConstructorIILjava_net_InetAddress()
+ throws UnknownHostException, IOException {
+ s = new ServerSocket(0, 10, InetAddress.getLocalHost());
+ try {
+ s.setSoTimeout(5000);
+ startClient(s.getLocalPort());
+ sconn = s.accept();
+ assertNotNull("Was unable to accept connection", sconn);
+ sconn.close();
+ } finally {
+ s.close();
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#accept()
+ */
+ public void test_accept() throws IOException {
+ s = new ServerSocket(0);
+ try {
+ s.setSoTimeout(5000);
+ startClient(s.getLocalPort());
+ sconn = s.accept();
+ int localPort1 = s.getLocalPort();
+ int localPort2 = sconn.getLocalPort();
+ sconn.close();
+ assertEquals("Bad local port value", localPort1, localPort2);
+ } finally {
+ s.close();
+ }
+
+ try {
+ interrupted = false;
+ final ServerSocket ss = new ServerSocket(0);
+ ss.setSoTimeout(12000);
+ Runnable runnable = new Runnable() {
+ public void run() {
+ try {
+ ss.accept();
+ } catch (InterruptedIOException e) {
+ interrupted = true;
+ } catch (IOException e) {
+ }
+ }
+ };
+ Thread thread = new Thread(runnable, "ServerSocket.accept");
+ thread.start();
+ try {
+ do {
+ Thread.sleep(500);
+ } while (!thread.isAlive());
+ } catch (InterruptedException e) {
+ }
+ ss.close();
+ int c = 0;
+ do {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+ if (interrupted) {
+ fail("accept interrupted");
+ }
+ if (++c > 4) {
+ fail("accept call did not exit");
+ }
+ } while (thread.isAlive());
+
+ interrupted = false;
+ ServerSocket ss2 = new ServerSocket(0);
+ ss2.setSoTimeout(500);
+ Date start = new Date();
+ try {
+ ss2.accept();
+ } catch (InterruptedIOException e) {
+ interrupted = true;
+ }
+ assertTrue("accept not interrupted", interrupted);
+ Date finish = new Date();
+ int delay = (int) (finish.getTime() - start.getTime());
+ assertTrue("timeout too soon: " + delay + " " + start.getTime()
+ + " " + finish.getTime(), delay >= 490);
+ ss2.close();
+ } catch (IOException e) {
+ fail("Unexpected IOException : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#close()
+ */
+ public void test_close() throws IOException {
+ try {
+ s = new ServerSocket(0);
+ try {
+ s.close();
+ s.accept();
+ fail("Close test failed");
+ } catch (SocketException e) {
+ // expected;
+ }
+ } finally {
+ s.close();
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#getInetAddress()
+ */
+ public void test_getInetAddress() throws IOException {
+ InetAddress addr = InetAddress.getLocalHost();
+ s = new ServerSocket(0, 10, addr);
+ try {
+ assertEquals("Returned incorrect InetAdrees", addr, s
+ .getInetAddress());
+ } finally {
+ s.close();
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#getLocalPort()
+ */
+ public void test_getLocalPort() throws IOException {
+ // Try a specific port number, but don't complain if we don't get it
+ int portNumber = 63024; // I made this up
+ try {
+ try {
+ s = new ServerSocket(portNumber);
+ } catch (BindException e) {
+ // we could not get the port, give up
+ return;
+ }
+ assertEquals("Returned incorrect port", portNumber, s
+ .getLocalPort());
+ } finally {
+ s.close();
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#getSoTimeout()
+ */
+ public void test_getSoTimeout() throws IOException {
+ s = new ServerSocket(0);
+ try {
+ s.setSoTimeout(100);
+ assertEquals("Returned incorrect sotimeout", 100, s.getSoTimeout());
+ } finally {
+ s.close();
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
+ */
+ public void test_setSocketFactoryLjava_net_SocketImplFactory()
+ throws IOException {
+ SocketImplFactory factory = new MockSocketImplFactory();
+ // Should not throw SocketException when set DatagramSocketImplFactory
+ // for the first time.
+ ServerSocket.setSocketFactory(factory);
+
+ try {
+ ServerSocket.setSocketFactory(null);
+ fail("Should throw SocketException");
+ } catch (SocketException e) {
+ // Expected
+ }
+
+ try {
+ ServerSocket.setSocketFactory(factory);
+ fail("Should throw SocketException");
+ } catch (SocketException e) {
+ // Expected
+ }
+ }
+
+ private static class MockSocketImplFactory implements SocketImplFactory {
+ public SocketImpl createSocketImpl() {
+ return new PlainServerSocketImpl();
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#setSoTimeout(int)
+ */
+ public void test_setSoTimeoutI() throws IOException {
+ // Timeout should trigger and throw InterruptedIOException
+ try {
+ s = new ServerSocket(0);
+ s.setSoTimeout(100);
+ s.accept();
+ } catch (InterruptedIOException e) {
+ assertEquals("Set incorrect sotimeout", 100, s.getSoTimeout());
+ return;
+ }
+
+ // Timeout should not trigger in this case
+ s = new ServerSocket(0);
+ startClient(s.getLocalPort());
+ s.setSoTimeout(10000);
+ sconn = s.accept();
+ }
+
+ /**
+ * java.net.ServerSocket#toString()
+ */
+ public void test_toString() throws Exception {
+ s = new ServerSocket(0);
+ try {
+ int portNumber = s.getLocalPort();
+ // In IPv6, the all-zeros-address is written as "::"
+ assertEquals("ServerSocket[addr=::/::,port=0,localport="
+ + portNumber + "]", s.toString());
+ } finally {
+ s.close();
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#bind(java.net.SocketAddress)
+ */
+ public void test_bindLjava_net_SocketAddress() throws IOException {
+ class mySocketAddress extends SocketAddress {
+ public mySocketAddress() {
+ }
+ }
+ // create servers socket, bind it and then validate basic state
+ ServerSocket theSocket = new ServerSocket();
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 0);
+ theSocket.bind(theAddress);
+ int portNumber = theSocket.getLocalPort();
+ assertTrue(
+ "Returned incorrect InetSocketAddress(2):"
+ + theSocket.getLocalSocketAddress().toString()
+ + "Expected: "
+ + (new InetSocketAddress(InetAddress.getLocalHost(),
+ portNumber)).toString(), theSocket
+ .getLocalSocketAddress().equals(
+ new InetSocketAddress(InetAddress
+ .getLocalHost(), portNumber)));
+ assertTrue("Server socket not bound when it should be:", theSocket
+ .isBound());
+
+ // now make sure that it is actually bound and listening on the
+ // address we provided
+ Socket clientSocket = new Socket();
+ InetSocketAddress clAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), portNumber);
+ clientSocket.connect(clAddress);
+ Socket servSock = theSocket.accept();
+
+ assertEquals(clAddress, clientSocket.getRemoteSocketAddress());
+ theSocket.close();
+ servSock.close();
+ clientSocket.close();
+
+ // validate we can specify null for the address in the bind and all
+ // goes ok
+ theSocket = new ServerSocket();
+ theSocket.bind(null);
+ theSocket.close();
+
+ // Address that we have already bound to
+ theSocket = new ServerSocket();
+ ServerSocket theSocket2 = new ServerSocket();
+ try {
+ theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ theSocket.bind(theAddress);
+ SocketAddress localAddress = theSocket.getLocalSocketAddress();
+ theSocket2.bind(localAddress);
+ fail("No exception binding to address that is not available");
+ } catch (IOException ex) {
+ }
+ theSocket.close();
+ theSocket2.close();
+
+ // validate we get io address when we try to bind to address we
+ // cannot bind to
+ theSocket = new ServerSocket();
+ try {
+ theSocket.bind(new InetSocketAddress(InetAddress
+ .getByAddress(Support_Configuration.nonLocalAddressBytes),
+ 0));
+ fail("No exception was thrown when binding to bad address");
+ } catch (IOException ex) {
+ }
+ theSocket.close();
+
+ // now validate case where we pass in an unsupported subclass of
+ // SocketAddress
+ theSocket = new ServerSocket();
+ try {
+ theSocket.bind(new mySocketAddress());
+ fail("No exception when binding using unsupported SocketAddress subclass");
+ } catch (IllegalArgumentException ex) {
+ }
+ theSocket.close();
+ }
+
+ /**
+ * java.net.ServerSocket#bind(java.net.SocketAddress, int)
+ */
+ public void test_bindLjava_net_SocketAddressI() throws IOException {
+ class mySocketAddress extends SocketAddress {
+
+ public mySocketAddress() {
+ }
+ }
+
+ // create servers socket, bind it and then validate basic state
+ ServerSocket theSocket = new ServerSocket();
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 0);
+ theSocket.bind(theAddress, 5);
+ int portNumber = theSocket.getLocalPort();
+ assertTrue(
+ "Returned incorrect InetSocketAddress(2):"
+ + theSocket.getLocalSocketAddress().toString()
+ + "Expected: "
+ + (new InetSocketAddress(InetAddress.getLocalHost(),
+ portNumber)).toString(), theSocket
+ .getLocalSocketAddress().equals(
+ new InetSocketAddress(InetAddress
+ .getLocalHost(), portNumber)));
+ assertTrue("Server socket not bound when it should be:", theSocket
+ .isBound());
+
+ // now make sure that it is actually bound and listening on the
+ // address we provided
+ SocketAddress localAddress = theSocket.getLocalSocketAddress();
+ Socket clientSocket = new Socket();
+ clientSocket.connect(localAddress);
+ Socket servSock = theSocket.accept();
+
+ assertTrue(clientSocket.getRemoteSocketAddress().equals(localAddress));
+ theSocket.close();
+ servSock.close();
+ clientSocket.close();
+
+ // validate we can specify null for the address in the bind and all
+ // goes ok
+ theSocket = new ServerSocket();
+ theSocket.bind(null, 5);
+ theSocket.close();
+
+ // Address that we have already bound to
+ theSocket = new ServerSocket();
+ ServerSocket theSocket2 = new ServerSocket();
+ try {
+ theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ theSocket.bind(theAddress, 5);
+ SocketAddress inuseAddress = theSocket.getLocalSocketAddress();
+ theSocket2.bind(inuseAddress, 5);
+ fail("No exception binding to address that is not available");
+ } catch (IOException ex) {
+ // expected
+ }
+ theSocket.close();
+ theSocket2.close();
+
+ // validate we get ioException when we try to bind to address we
+ // cannot bind to
+ theSocket = new ServerSocket();
+ try {
+ theSocket.bind(new InetSocketAddress(InetAddress
+ .getByAddress(Support_Configuration.nonLocalAddressBytes),
+ 0), 5);
+ fail("No exception was thrown when binding to bad address");
+ } catch (IOException ex) {
+ }
+ theSocket.close();
+
+ // now validate case where we pass in an unsupported subclass of
+ // SocketAddress
+ theSocket = new ServerSocket();
+ try {
+ theSocket.bind(new mySocketAddress(), 5);
+ fail("Binding using unsupported SocketAddress subclass should have thrown exception");
+ } catch (IllegalArgumentException ex) {
+ }
+ theSocket.close();
+
+ // now validate that backlog is respected. We have to do a test that
+ // checks if it is a least a certain number as some platforms make
+ // it higher than we request. Unfortunately non-server versions of
+ // windows artificially limit the backlog to 5 and 5 is the
+ // historical default so it is not a great test.
+ theSocket = new ServerSocket();
+ theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ theSocket.bind(theAddress, 4);
+ localAddress = theSocket.getLocalSocketAddress();
+ Socket theSockets[] = new Socket[4];
+ int i = 0;
+ try {
+ for (i = 0; i < 4; i++) {
+ theSockets[i] = new Socket();
+ theSockets[i].connect(localAddress);
+ }
+ } catch (ConnectException ex) {
+ fail("Backlog does not seem to be respected in bind:" + i + ":"
+ + ex.toString());
+ }
+
+ for (i = 0; i < 4; i++) {
+ theSockets[i].close();
+ }
+
+ theSocket.close();
+ servSock.close();
+ }
+
+ /**
+ * java.net.ServerSocket#getLocalSocketAddress()
+ */
+ public void test_getLocalSocketAddress() throws Exception {
+ // set up server connect and then validate that we get the right
+ // response for the local address
+ ServerSocket theSocket = new ServerSocket(0, 5, InetAddress
+ .getLocalHost());
+ int portNumber = theSocket.getLocalPort();
+ assertTrue("Returned incorrect InetSocketAddress(1):"
+ + theSocket.getLocalSocketAddress().toString()
+ + "Expected: "
+ + (new InetSocketAddress(InetAddress.getLocalHost(),
+ portNumber)).toString(), theSocket
+ .getLocalSocketAddress().equals(
+ new InetSocketAddress(InetAddress.getLocalHost(),
+ portNumber)));
+ theSocket.close();
+
+ // now create a socket that is not bound and validate we get the
+ // right answer
+ theSocket = new ServerSocket();
+ assertNull(
+ "Returned incorrect InetSocketAddress -unbound socket- Expected null",
+ theSocket.getLocalSocketAddress());
+
+ // now bind the socket and make sure we get the right answer
+ theSocket
+ .bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ int localPort = theSocket.getLocalPort();
+ assertEquals("Returned incorrect InetSocketAddress(2):", theSocket
+ .getLocalSocketAddress(), new InetSocketAddress(InetAddress
+ .getLocalHost(), localPort));
+ theSocket.close();
+ }
+
+ /**
+ * java.net.ServerSocket#isBound()
+ */
+ public void test_isBound() throws IOException {
+ InetAddress addr = InetAddress.getLocalHost();
+ ServerSocket serverSocket = new ServerSocket();
+ assertFalse("Socket indicated bound when it should be (1)",
+ serverSocket.isBound());
+
+ // now bind and validate bound ok
+ serverSocket.bind(new InetSocketAddress(addr, 0));
+ assertTrue("Socket indicated not bound when it should be (1)",
+ serverSocket.isBound());
+ serverSocket.close();
+
+ // now do with some of the other constructors
+ serverSocket = new ServerSocket(0);
+ assertTrue("Socket indicated not bound when it should be (2)",
+ serverSocket.isBound());
+ serverSocket.close();
+
+ serverSocket = new ServerSocket(0, 5, addr);
+ assertTrue("Socket indicated not bound when it should be (3)",
+ serverSocket.isBound());
+ serverSocket.close();
+
+ serverSocket = new ServerSocket(0, 5);
+ assertTrue("Socket indicated not bound when it should be (4)",
+ serverSocket.isBound());
+ serverSocket.close();
+ }
+
+ /**
+ * java.net.ServerSocket#isClosed()
+ */
+ public void test_isClosed() throws IOException {
+ InetAddress addr = InetAddress.getLocalHost();
+ ServerSocket serverSocket = new ServerSocket(0, 5, addr);
+
+ // validate isClosed returns expected values
+ assertFalse("Socket should indicate it is not closed(1):", serverSocket
+ .isClosed());
+ serverSocket.close();
+ assertTrue("Socket should indicate it is closed(1):", serverSocket
+ .isClosed());
+
+ // now do with some of the other constructors
+ serverSocket = new ServerSocket(0);
+ assertFalse("Socket should indicate it is not closed(1):", serverSocket
+ .isClosed());
+ serverSocket.close();
+ assertTrue("Socket should indicate it is closed(1):", serverSocket
+ .isClosed());
+
+ serverSocket = new ServerSocket(0, 5, addr);
+ assertFalse("Socket should indicate it is not closed(1):", serverSocket
+ .isClosed());
+ serverSocket.close();
+ assertTrue("Socket should indicate it is closed(1):", serverSocket
+ .isClosed());
+
+ serverSocket = new ServerSocket(0, 5);
+ assertFalse("Socket should indicate it is not closed(1):", serverSocket
+ .isClosed());
+ serverSocket.close();
+ assertTrue("Socket should indicate it is closed(1):", serverSocket
+ .isClosed());
+ }
+
+ /*
+ * Regression HARMONY-6090
+ */
+ public void test_defaultValueReuseAddress() throws Exception {
+ String platform = System.getProperty("os.name").toLowerCase(Locale.US);
+ if (!platform.startsWith("windows")) {
+ // on Unix
+ assertTrue(new ServerSocket().getReuseAddress());
+ assertTrue(new ServerSocket(0).getReuseAddress());
+ assertTrue(new ServerSocket(0, 50).getReuseAddress());
+ assertTrue(new ServerSocket(0, 50, InetAddress.getLocalHost()).getReuseAddress());
+ } else {
+ // on Windows
+ assertFalse(new ServerSocket().getReuseAddress());
+ assertFalse(new ServerSocket(0).getReuseAddress());
+ assertFalse(new ServerSocket(0, 50).getReuseAddress());
+ assertFalse(new ServerSocket(0, 50, InetAddress.getLocalHost()).getReuseAddress());
+ }
+ }
+
+ public void test_setReuseAddressZ() throws Exception {
+ // set up server and connect
+ InetSocketAddress anyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.setReuseAddress(false);
+ serverSocket.bind(anyAddress);
+ SocketAddress theAddress = serverSocket.getLocalSocketAddress();
+
+ // make a connection to the server, then close the server
+ Socket theSocket = new Socket();
+ theSocket.connect(theAddress);
+ Socket stillActiveSocket = serverSocket.accept();
+ serverSocket.close();
+
+ // now try to rebind the server which should fail with
+ // setReuseAddress to false. On windows platforms the bind is
+ // allowed even then reUseAddress is false so our test uses
+ // the platform to determine what the expected result is.
+ String platform = System.getProperty("os.name");
+ try {
+ serverSocket = new ServerSocket();
+ serverSocket.setReuseAddress(false);
+ serverSocket.bind(theAddress);
+ fail("No exception when setReuseAddress is false and we bind:" + theAddress.toString());
+ } catch (IOException expected) {
+ }
+ stillActiveSocket.close();
+ theSocket.close();
+
+ // now test case were we set it to true
+ anyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ serverSocket = new ServerSocket();
+ serverSocket.setReuseAddress(true);
+ serverSocket.bind(anyAddress);
+ theAddress = serverSocket.getLocalSocketAddress();
+
+ // make a connection to the server, then close the server
+ theSocket = new Socket();
+ theSocket.connect(theAddress);
+ stillActiveSocket = serverSocket.accept();
+ serverSocket.close();
+
+ // now try to rebind the server which should pass with
+ // setReuseAddress to true
+ try {
+ serverSocket = new ServerSocket();
+ serverSocket.setReuseAddress(true);
+ serverSocket.bind(theAddress);
+ } catch (IOException ex) {
+ fail("Unexpected exception when setReuseAddress is true and we bind:"
+ + theAddress.toString() + ":" + ex.toString());
+ }
+ stillActiveSocket.close();
+ theSocket.close();
+
+ // now test default case were we expect this to work regardless of
+ // the value set
+ anyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ serverSocket = new ServerSocket();
+ serverSocket.bind(anyAddress);
+ theAddress = serverSocket.getLocalSocketAddress();
+
+ // make a connection to the server, then close the server
+ theSocket = new Socket();
+ theSocket.connect(theAddress);
+ stillActiveSocket = serverSocket.accept();
+ serverSocket.close();
+
+ // now try to rebind the server which should pass
+ try {
+ serverSocket = new ServerSocket();
+ serverSocket.bind(theAddress);
+ } catch (IOException ex) {
+ fail("Unexpected exception when setReuseAddress is the default case and we bind:"
+ + theAddress.toString() + ":" + ex.toString());
+ }
+ stillActiveSocket.close();
+ theSocket.close();
+ }
+
+ public void test_getReuseAddress() throws Exception {
+ ServerSocket theSocket = new ServerSocket();
+ theSocket.setReuseAddress(true);
+ assertTrue("getReuseAddress false when it should be true", theSocket.getReuseAddress());
+ theSocket.setReuseAddress(false);
+ assertFalse("getReuseAddress true when it should be False", theSocket.getReuseAddress());
+ }
+
+ public void test_setReceiveBufferSizeI() throws Exception {
+ // now validate case where we try to set to 0
+ ServerSocket theSocket = new ServerSocket();
+ try {
+ theSocket.setReceiveBufferSize(0);
+ fail("No exception when receive buffer size set to 0");
+ } catch (IllegalArgumentException ex) {
+ }
+ theSocket.close();
+
+ // now validate case where we try to set to a negative value
+ theSocket = new ServerSocket();
+ try {
+ theSocket.setReceiveBufferSize(-1000);
+ fail("No exception when receive buffer size set to -1000");
+ } catch (IllegalArgumentException ex) {
+ }
+ theSocket.close();
+
+ // now just try to set a good value to make sure it is set and there
+ // are not exceptions
+ theSocket = new ServerSocket();
+ theSocket.setReceiveBufferSize(1000);
+ theSocket.close();
+ }
+
+ public void test_getReceiveBufferSize() throws Exception {
+ ServerSocket theSocket = new ServerSocket();
+
+ // since the value returned is not necessary what we set we are
+ // limited in what we can test
+ // just validate that it is not 0 or negative
+ assertFalse("get Buffer size returns 0:", 0 == theSocket.getReceiveBufferSize());
+ assertFalse("get Buffer size returns a negative value:", 0 > theSocket.getReceiveBufferSize());
+ }
+
+ public void test_getChannel() throws Exception {
+ assertNull(new ServerSocket().getChannel());
+ }
+
+ public void test_setPerformancePreference_Int_Int_Int() throws Exception {
+ ServerSocket theSocket = new ServerSocket();
+ theSocket.setPerformancePreferences(1, 1, 1);
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+
+ try {
+ if (s != null)
+ s.close();
+ if (sconn != null)
+ sconn.close();
+ if (t != null)
+ t.interrupt();
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void startClient(int port) {
+ t = new Thread(new SSClient(port), "SSClient");
+ t.start();
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ System.out.println("Exception during startClinet()" + e.toString());
+ }
+ }
+
+ /**
+ * java.net.ServerSocket#implAccept
+ */
+ public void test_implAcceptLjava_net_Socket() throws Exception {
+ // regression test for Harmony-1235
+ try {
+ new MockServerSocket().mockImplAccept(new MockSocket(
+ new MockSocketImpl()));
+ } catch (SocketException e) {
+ // expected
+ }
+ }
+
+ static class MockSocketImpl extends SocketImpl {
+ protected void create(boolean arg0) throws IOException {
+ // empty
+ }
+
+ protected void connect(String arg0, int arg1) throws IOException {
+ // empty
+ }
+
+ protected void connect(InetAddress arg0, int arg1) throws IOException {
+ // empty
+ }
+
+ protected void connect(SocketAddress arg0, int arg1) throws IOException {
+ // empty
+ }
+
+ protected void bind(InetAddress arg0, int arg1) throws IOException {
+ // empty
+ }
+
+ protected void listen(int arg0) throws IOException {
+ // empty
+ }
+
+ protected void accept(SocketImpl arg0) throws IOException {
+ // empty
+ }
+
+ protected InputStream getInputStream() throws IOException {
+ return null;
+ }
+
+ protected OutputStream getOutputStream() throws IOException {
+ return null;
+ }
+
+ protected int available() throws IOException {
+ return 0;
+ }
+
+ protected void close() throws IOException {
+ // empty
+ }
+
+ protected void sendUrgentData(int arg0) throws IOException {
+ // empty
+ }
+
+ public void setOption(int arg0, Object arg1) throws SocketException {
+ // empty
+ }
+
+ public Object getOption(int arg0) throws SocketException {
+ return null;
+ }
+ }
+
+ static class MockSocket extends Socket {
+ public MockSocket(SocketImpl impl) throws SocketException {
+ super(impl);
+ }
+ }
+
+ static class MockServerSocket extends ServerSocket {
+ public MockServerSocket() throws Exception {
+ super();
+ }
+
+ public void mockImplAccept(Socket s) throws Exception {
+ super.implAccept(s);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketExceptionTest.java
new file mode 100644
index 0000000..32c9eb8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketExceptionTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.SocketException;
+
+public class SocketExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.SocketException#SocketException()
+ */
+ public void test_Constructor() {
+ try {
+ if (true) {
+ throw new SocketException();
+ }
+ fail("Failed to generate expected exception");
+ } catch (SocketException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.SocketException#SocketException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ try {
+ if (true) {
+ throw new SocketException("Some error message");
+ }
+ fail("Failed to generate expected exception");
+ } catch (SocketException e) {
+ // Expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketImplTest.java
new file mode 100644
index 0000000..f6122e5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketImplTest.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+
+public class SocketImplTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.SocketImpl#SocketImpl()
+ */
+ public void test_Constructor_fd() {
+ // Regression test for HARMONY-1117
+ MockSocketImpl mockSocketImpl = new MockSocketImpl();
+ assertNull(mockSocketImpl.getFileDescriptor());
+ }
+
+ /**
+ * java.net.SocketImpl#setPerformancePreference()
+ */
+ public void test_setPerformancePreference_Int_Int_Int() {
+ MockSocketImpl theSocket = new MockSocketImpl();
+ theSocket.setPerformancePreference(1, 1, 1);
+ }
+
+ /**
+ * java.net.SocketImpl#shutdownOutput()
+ */
+ public void test_shutdownOutput() {
+ MockSocketImpl s = new MockSocketImpl();
+ try {
+ s.shutdownOutput();
+ fail("This method is still not implemented yet,It should throw IOException.");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.net.SocketImpl#shutdownInput()
+ */
+ public void test_shutdownInput() {
+ MockSocketImpl s = new MockSocketImpl();
+ try {
+ s.shutdownInput();
+ fail("This method is still not implemented yet,It should throw IOException.");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.SocketImpl#supportsUrgentData()
+ */
+ public void test_supportsUrgentData() {
+ MockSocketImpl s = new MockSocketImpl();
+ assertFalse(s.testSupportsUrgentData());
+ }
+
+ // the mock class for test, leave all methods empty
+ class MockSocketImpl extends SocketImpl {
+
+ protected void accept(SocketImpl newSocket) throws IOException {
+ }
+
+ protected int available() throws IOException {
+ return 0;
+ }
+
+ protected void bind(InetAddress address, int port) throws IOException {
+ }
+
+ protected void close() throws IOException {
+ }
+
+ protected void connect(String host, int port) throws IOException {
+ }
+
+ protected void connect(InetAddress address, int port)
+ throws IOException {
+ }
+
+ protected void create(boolean isStreaming) throws IOException {
+ }
+
+ protected InputStream getInputStream() throws IOException {
+ return null;
+ }
+
+ public Object getOption(int optID) throws SocketException {
+ return null;
+ }
+
+ protected OutputStream getOutputStream() throws IOException {
+ return null;
+ }
+
+ protected void listen(int backlog) throws IOException {
+ }
+
+ public void setOption(int optID, Object val) throws SocketException {
+ }
+
+ protected void connect(SocketAddress remoteAddr, int timeout)
+ throws IOException {
+ }
+
+ protected void sendUrgentData(int value) throws IOException {
+ }
+
+ public void setPerformancePreference(int connectionTime, int latency,
+ int bandwidth) {
+ super.setPerformancePreferences(connectionTime, latency, bandwidth);
+ }
+
+ public FileDescriptor getFileDescriptor() {
+ return super.getFileDescriptor();
+ }
+
+ public void shutdownOutput() throws IOException {
+ super.shutdownOutput();
+ }
+
+ public void shutdownInput() throws IOException {
+ super.shutdownInput();
+ }
+
+ public boolean testSupportsUrgentData() {
+ return super.supportsUrgentData();
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTest.java
new file mode 100644
index 0000000..4df92e2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTest.java
@@ -0,0 +1,1634 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ConnectException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketImplFactory;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.Locale;
+
+import tests.support.Support_Configuration;
+
+public class SocketTest extends junit.framework.TestCase {
+ private class ClientThread implements Runnable {
+
+ public void run() {
+ try {
+ Socket socket = new Socket();
+ InetSocketAddress addr = new InetSocketAddress(host, port);
+ socket.connect(addr);
+
+ socket.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private class ServerThread implements Runnable {
+ private static final int FIRST_TIME = 1;
+
+ private static final int SECOND_TIME = 2;
+
+ private int backlog = 10;
+
+ public boolean ready = false;
+
+ private int serverSocketConstructor = 0;
+
+ public void run() {
+ try {
+
+ ServerSocket socket;
+ switch (serverSocketConstructor) {
+ case FIRST_TIME:
+ socket = new ServerSocket(port, backlog,
+ new InetSocketAddress(host, port).getAddress());
+ port = socket.getLocalPort();
+ break;
+ case SECOND_TIME:
+ socket = new ServerSocket(port, backlog);
+ host = socket.getInetAddress().getHostName();
+ port = socket.getLocalPort();
+ break;
+ default:
+ socket = new ServerSocket();
+ break;
+ }
+
+ synchronized (this) {
+ ready = true;
+ this.notifyAll();
+ }
+
+ socket.setSoTimeout(5000);
+ Socket client = socket.accept();
+ client.close();
+ socket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ public synchronized void waitCreated() throws Exception {
+ while (!ready) {
+ this.wait();
+ }
+ }
+ }
+
+ boolean interrupted;
+
+ String host = "localhost";
+ int port;
+
+ Thread t;
+
+ private void connectTestImpl(int ssConsType) throws Exception {
+ ServerThread server = new ServerThread();
+ server.serverSocketConstructor = ssConsType;
+ Thread serverThread = new Thread(server);
+ serverThread.start();
+ server.waitCreated();
+
+ ClientThread client = new ClientThread();
+ Thread clientThread = new Thread(client);
+ clientThread.start();
+ try {
+ serverThread.join();
+ clientThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void tearDown() {
+ try {
+ if (t != null) {
+ t.interrupt();
+ }
+ } catch (Exception e) {
+ }
+ this.t = null;
+ this.interrupted = false;
+ }
+
+ /**
+ * java.net.Socket#bind(java.net.SocketAddress)
+ */
+ public void test_bindLjava_net_SocketAddress() throws IOException {
+
+ @SuppressWarnings("serial")
+ class UnsupportedSocketAddress extends SocketAddress {
+ public UnsupportedSocketAddress() {
+ }
+ }
+
+ // Address we cannot bind to
+ Socket theSocket = new Socket();
+ InetSocketAddress bogusAddress = new InetSocketAddress(InetAddress
+ .getByAddress(Support_Configuration.nonLocalAddressBytes), 42);
+ try {
+ theSocket.bind(bogusAddress);
+ fail("No exception when binding to bad address");
+ } catch (IOException ex) {
+ // Expected
+ }
+ theSocket.close();
+
+ // Now create a socket that is not bound and then bind it
+ theSocket = new Socket();
+ theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ int portNumber = theSocket.getLocalPort();
+
+ // Validate that the localSocketAddress reflects the address we
+ // bound to
+ assertEquals("Local address not correct after bind",
+ new InetSocketAddress(InetAddress.getLocalHost(), portNumber),
+ theSocket.getLocalSocketAddress());
+
+ // Make sure we can now connect and that connections appear to come
+ // from the address we bound to.
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 0);
+ ServerSocket server = new ServerSocket();
+ server.bind(theAddress);
+ int sport = server.getLocalPort();
+ InetSocketAddress boundAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), sport);
+
+ theSocket.connect(boundAddress);
+ Socket worker = server.accept();
+ assertEquals(
+ "Returned Remote address from server connected to does not match expected local address",
+ new InetSocketAddress(InetAddress.getLocalHost(), portNumber),
+ worker.getRemoteSocketAddress());
+ theSocket.close();
+ worker.close();
+ server.close();
+
+ // Validate if we pass in null that it picks an address for us and
+ // all is ok
+ theSocket = new Socket();
+ theSocket.bind(null);
+ assertNotNull("Bind with null did not work", theSocket
+ .getLocalSocketAddress());
+ theSocket.close();
+
+ // now check the error conditions
+
+ // Address that we have already bound to
+ theSocket = new Socket();
+ theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ theSocket.bind(theAddress);
+
+ Socket theSocket2 = new Socket();
+ try {
+ theSocket2.bind(theSocket.getLocalSocketAddress());
+ fail("No exception binding to address that is not available");
+ } catch (IOException ex) {
+ // Expected
+ }
+ theSocket.close();
+ theSocket2.close();
+
+ // Unsupported SocketAddress subclass
+ theSocket = new Socket();
+ try {
+ theSocket.bind(new UnsupportedSocketAddress());
+ fail("No exception when binding using unsupported SocketAddress subclass");
+ } catch (IllegalArgumentException ex) {
+ // Expected
+ }
+ theSocket.close();
+ }
+
+ /**
+ * java.net.Socket#bind(java.net.SocketAddress)
+ */
+ public void test_bindLjava_net_SocketAddress_Proxy() throws IOException {
+ // The Proxy will not impact on the bind operation. It can be assigned
+ // with any address.
+ Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(
+ "127.0.0.1", 0));
+ Socket socket = new Socket(proxy);
+
+ InetAddress address = InetAddress.getByName("localhost");
+ socket.bind(new InetSocketAddress(address, 0));
+
+ assertEquals(address, socket.getLocalAddress());
+ assertTrue(0 != socket.getLocalPort());
+
+ socket.close();
+ }
+
+ public void test_close() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+ client.setSoLinger(false, 100);
+
+ client.close();
+ try {
+ client.getOutputStream();
+ fail("Failed to close socket");
+ } catch (IOException expected) {
+ }
+
+ server.close();
+ }
+
+ public void test_connect_unknownhost() throws Exception {
+ Socket socket = new Socket();
+ try {
+ socket.connect(new InetSocketAddress("1.2.3.4hello", 12345));
+ fail();
+ } catch (UnknownHostException expected) {
+ }
+ }
+
+ public void test_connect_unresolved() throws IOException {
+ Socket socket = new Socket();
+ InetSocketAddress unresolved = InetSocketAddress.createUnresolved("www.apache.org", 80);
+ try {
+ socket.connect(unresolved);
+ fail();
+ } catch (UnknownHostException expected) {
+ }
+ try {
+ socket.connect(unresolved, 123);
+ fail();
+ } catch (UnknownHostException expected) {
+ }
+ }
+
+ public void test_connectLjava_net_SocketAddress() throws Exception {
+
+ @SuppressWarnings("serial")
+ class UnsupportedSocketAddress extends SocketAddress {
+ public UnsupportedSocketAddress() {
+ }
+ }
+
+ Socket theSocket = new Socket();
+ try {
+ theSocket.connect(null);
+ fail("No exception for null arg");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ theSocket.connect(new UnsupportedSocketAddress());
+ fail("No exception for invalid socket address");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ theSocket.connect(new InetSocketAddress(InetAddress
+ .getByAddress(new byte[] { 0, 0, 0, 0 }), 42));
+ fail("No exception with non-connectable address");
+ } catch (ConnectException e) {
+ // Expected
+ }
+
+ // now validate that we get a connect exception if we try to connect to
+ // an address on which nobody is listening
+ theSocket = new Socket();
+ try {
+ theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
+ 0));
+ fail("No exception when connecting to address nobody listening on");
+ } catch (ConnectException e) {
+ // Expected
+ }
+
+ // Now validate that we can actually connect when somebody is listening
+ ServerSocket server = new ServerSocket(0);
+ InetSocketAddress boundAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), server.getLocalPort());
+ Socket client = new Socket();
+ client.connect(boundAddress);
+
+ // validate that when a socket is connected that it answers
+ // correctly to related queries
+ assertTrue("Wrong connected status", client.isConnected());
+ assertFalse("Wrong closed status", client.isClosed());
+ assertTrue("Wrong bound status", client.isBound());
+ assertFalse("Wrong input shutdown status", client.isInputShutdown());
+ assertFalse("Wrong output shutdown status", client.isOutputShutdown());
+ assertTrue("Local port was 0", client.getLocalPort() != 0);
+
+ client.close();
+ server.close();
+
+ // Now validate that we get the right exception if we connect when we
+ // are already connected
+ server = new ServerSocket(0);
+ boundAddress = new InetSocketAddress(InetAddress.getLocalHost(), server
+ .getLocalPort());
+ client = new Socket();
+ client.connect(boundAddress);
+
+ try {
+ client.connect(boundAddress);
+ fail("No exception when we try to connect on a connected socket: ");
+ } catch (SocketException e) {
+ // Expected
+ }
+ client.close();
+ server.close();
+ }
+
+ /**
+ * Regression for Harmony-2503
+ */
+ public void test_connectLjava_net_SocketAddress_AnyAddress()
+ throws Exception {
+ connectTestImpl(ServerThread.FIRST_TIME);
+ connectTestImpl(ServerThread.SECOND_TIME);
+ }
+
+ /**
+ * java.net.Socket#connect(java.net.SocketAddress, int)
+ */
+ public void test_connectLjava_net_SocketAddressI() throws Exception {
+
+ @SuppressWarnings("serial")
+ class UnsupportedSocketAddress extends SocketAddress {
+ public UnsupportedSocketAddress() {
+ }
+ }
+
+ // Start by validating the error checks
+ Socket theSocket = new Socket();
+ try {
+ theSocket.connect(new InetSocketAddress(0), -100);
+ fail("No exception for negative timeout");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ theSocket.connect(null, 0);
+ fail("No exception for null address");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ theSocket.connect(new UnsupportedSocketAddress(), 1000);
+ fail("No exception for invalid socket address type");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ SocketAddress nonConnectableAddress = new InetSocketAddress(InetAddress
+ .getByAddress(new byte[] { 0, 0, 0, 0 }), 0);
+ try {
+ theSocket.connect(nonConnectableAddress, 1000);
+ fail("No exception when non Connectable Address passed in: ");
+ } catch (SocketException e) {
+ // Expected
+ }
+
+ // Now validate that we get a connect exception if we try to connect to
+ // an address on which nobody is listening
+ theSocket = new Socket();
+ try {
+ theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
+ 0), 0);
+ fail("No exception when connecting to address nobody listening on");
+ } catch (ConnectException e) {
+ // Expected
+ }
+ theSocket.close();
+
+ // Now validate that we can actually connect when somebody is listening
+ ServerSocket server = new ServerSocket(0);
+ InetSocketAddress boundAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), server.getLocalPort());
+ Socket client = new Socket();
+ client.connect(boundAddress, 0);
+
+ // Validate that when a socket is connected that it answers
+ // correctly to related queries
+ assertTrue("Wrong connected status", client.isConnected());
+ assertFalse("Wrong closed status", client.isClosed());
+ assertTrue("Wrong bound status", client.isBound());
+ assertFalse("Wrong input shutdown status", client.isInputShutdown());
+ assertFalse("Wrong output shutdown status", client.isOutputShutdown());
+ assertTrue("Local port was 0", client.getLocalPort() != 0);
+
+ client.close();
+ server.close();
+
+ // Now validate that we get a connect exception if we try to connect to
+ // an address on which nobody is listening
+ theSocket = new Socket();
+ SocketAddress nonListeningAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 42);
+ try {
+ theSocket.connect(nonListeningAddress, 1000);
+ fail("No exception when connecting to address nobody listening on");
+ } catch (ConnectException e) {
+ // Expected
+ } catch (SocketTimeoutException e) {
+ // The other possibility is that the system timed us out.
+ }
+ theSocket.close();
+
+ // Now validate that we get the right exception if we connect when we
+ // are already connected
+ server = new ServerSocket(0);
+ boundAddress = new InetSocketAddress(InetAddress.getLocalHost(), server
+ .getLocalPort());
+ client = new Socket();
+ client.connect(boundAddress, 10000);
+
+ try {
+ client.connect(boundAddress, 10000);
+ fail("No exception when we try to connect on a connected socket: ");
+ } catch (SocketException e) {
+ // Expected
+ }
+ client.close();
+ server.close();
+ }
+
+ /**
+ * java.net.Socket#Socket()
+ */
+ public void test_Constructor() {
+ // create the socket and then validate some basic state
+ Socket s = new Socket();
+ assertFalse("new socket should not be connected", s.isConnected());
+ assertFalse("new socket should not be bound", s.isBound());
+ assertFalse("new socket should not be closed", s.isClosed());
+ assertFalse("new socket should not be in InputShutdown", s
+ .isInputShutdown());
+ assertFalse("new socket should not be in OutputShutdown", s
+ .isOutputShutdown());
+ }
+
+ /**
+ * java.net.Socket#Socket(java.lang.String, int)
+ */
+ public void test_ConstructorLjava_lang_StringI() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+
+ assertEquals("Failed to create socket", server.getLocalPort(), client
+ .getPort());
+
+ // Regression for HARMONY-946
+ ServerSocket ss = new ServerSocket(0);
+ Socket s = new Socket("0.0.0.0", ss.getLocalPort());
+ ss.close();
+ s.close();
+ }
+
+ /**
+ * java.net.Socket#Socket(java.lang.String, int,
+ *java.net.InetAddress, int)
+ */
+ public void test_ConstructorLjava_lang_StringILjava_net_InetAddressI()
+ throws IOException {
+
+ ServerSocket server = new ServerSocket(0);
+ int serverPort = server.getLocalPort();
+ Socket client = new Socket(InetAddress.getLocalHost().getHostName(),
+ serverPort, InetAddress.getLocalHost(), 0);
+ assertTrue("Failed to create socket", client.getPort() == serverPort);
+ client.close();
+
+ Socket theSocket;
+ try {
+ theSocket = new Socket("127.0.0.1", serverPort, InetAddress
+ .getLocalHost(), 0);
+ } catch (IOException e) {
+ // check here if InetAddress.getLocalHost() is returning the
+ // loopback address, if so that is likely the cause of the failure
+ assertFalse(
+ "Misconfiguration - local host is the loopback address",
+ InetAddress.getLocalHost().isLoopbackAddress());
+ throw e;
+ }
+
+ assertTrue(theSocket.isConnected());
+
+ try {
+ new Socket("127.0.0.1", serverPort, theSocket.getLocalAddress(),
+ theSocket.getLocalPort());
+ fail("Was able to create two sockets on same port");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ theSocket.close();
+ server.close();
+ }
+
+ @SuppressWarnings("deprecation")
+ public void test_ConstructorLjava_lang_StringIZ() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ int serverPort = server.getLocalPort();
+ Socket client = new Socket(InetAddress.getLocalHost().getHostAddress(),
+ serverPort, true);
+
+ assertEquals("Failed to create socket", serverPort, client.getPort());
+ client.close();
+
+ client = new Socket(InetAddress.getLocalHost().getHostName(),
+ serverPort, false);
+ client.close();
+ server.close();
+ }
+
+ /**
+ * java.net.Socket#Socket(java.net.InetAddress, int)
+ */
+ public void test_ConstructorLjava_net_InetAddressI() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+
+ assertEquals("Failed to create socket", server.getLocalPort(), client
+ .getPort());
+
+ client.close();
+ server.close();
+ }
+
+ /**
+ * java.net.Socket#Socket(java.net.InetAddress, int,
+ *java.net.InetAddress, int)
+ */
+ public void test_ConstructorLjava_net_InetAddressILjava_net_InetAddressI()
+ throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort(), InetAddress.getLocalHost(), 0);
+ assertNotSame("Failed to create socket", 0, client.getLocalPort());
+ }
+
+ /**
+ * java.net.Socket#Socket(java.net.InetAddress, int, boolean)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_ConstructorLjava_net_InetAddressIZ() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ int serverPort = server.getLocalPort();
+
+ Socket client = new Socket(InetAddress.getLocalHost(), serverPort, true);
+ assertEquals("Failed to create socket", serverPort, client.getPort());
+
+ client = new Socket(InetAddress.getLocalHost(), serverPort, false);
+ client.close();
+ }
+
+ /**
+ * java.net.Socket#Socket(Proxy)
+ */
+ public void test_ConstructorLjava_net_Proxy_Exception() {
+
+ SocketAddress addr1 = InetSocketAddress.createUnresolved("127.0.0.1", 80);
+
+ Proxy proxy1 = new Proxy(Proxy.Type.HTTP, addr1);
+ // IllegalArgumentException test
+ try {
+ new Socket(proxy1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ Proxy proxy2 = new Proxy(Proxy.Type.SOCKS, addr1);
+ // should not throw any exception
+ new Socket(proxy2);
+ new Socket(Proxy.NO_PROXY);
+ }
+
+ /**
+ * java.net.Socket#getChannel()
+ */
+ public void test_getChannel() {
+ assertNull(new Socket().getChannel());
+ }
+
+ /**
+ * java.net.Socket#getInetAddress()
+ */
+ public void test_getInetAddress() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+
+ assertTrue("Returned incorrect InetAdrees", client.getInetAddress()
+ .equals(InetAddress.getLocalHost()));
+
+ client.close();
+ server.close();
+ }
+
+ /**
+ * java.net.Socket#getInputStream()
+ */
+ public void test_getInputStream() throws IOException {
+ // Simple fetch test
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+ InputStream is = client.getInputStream();
+ assertNotNull("Failed to get stream", is);
+ is.close();
+ client.close();
+ server.close();
+ }
+
+ private boolean isUnix() {
+ String osName = System.getProperty("os.name");
+
+ // only comparing ASCII, so assume english locale
+ osName = (osName == null ? null : osName.toLowerCase(Locale.ENGLISH));
+
+ if (osName != null && osName.startsWith("windows")) { //$NON-NLS-1$
+ return false;
+ }
+ return true;
+ }
+
+ public void test_getKeepAlive() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort(), null, 0);
+
+ client.setKeepAlive(true);
+ assertTrue("getKeepAlive false when it should be true", client.getKeepAlive());
+
+ client.setKeepAlive(false);
+ assertFalse("getKeepAlive true when it should be False", client.getKeepAlive());
+ }
+
+ public void test_getLocalAddress() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+ assertTrue("Returned incorrect InetAddress", client.getLocalAddress()
+ .equals(InetAddress.getLocalHost()));
+
+ client = new Socket();
+ client.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0));
+ assertTrue(client.getLocalAddress().isAnyLocalAddress());
+
+ client.close();
+ server.close();
+ }
+
+ /**
+ * java.net.Socket#getLocalPort()
+ */
+ public void test_getLocalPort() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+
+ assertNotSame("Returned incorrect port", 0, client.getLocalPort());
+
+ client.close();
+ server.close();
+ }
+
+ public void test_getLocalSocketAddress() throws IOException {
+ // set up server connect and then validate that we get the right
+ // response for the local address
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+ int clientPort = client.getLocalPort();
+
+ assertEquals("Returned incorrect InetSocketAddress(1):",
+ new InetSocketAddress(InetAddress.getLocalHost(), clientPort),
+ client.getLocalSocketAddress());
+ client.close();
+ server.close();
+
+ // now create a socket that is not bound and validate we get the
+ // right answer
+ client = new Socket();
+ assertNull(
+ "Returned incorrect InetSocketAddress -unbound socket- Expected null",
+ client.getLocalSocketAddress());
+
+ // now bind the socket and make sure we get the right answer
+ client.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ clientPort = client.getLocalPort();
+ assertEquals("Returned incorrect InetSocketAddress(2):",
+ new InetSocketAddress(InetAddress.getLocalHost(), clientPort),
+ client.getLocalSocketAddress());
+ client.close();
+
+ // now validate the behaviour when the any address is returned
+ client = new Socket();
+ client.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0));
+ assertTrue(((InetSocketAddress) client.getLocalSocketAddress()).getAddress().isAnyLocalAddress());
+ client.close();
+
+ // now validate the same for getLocalAddress
+ client = new Socket();
+ client.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0));
+ assertTrue(client.getLocalAddress().isAnyLocalAddress());
+ client.close();
+ }
+
+ public void test_getOOBInline() throws Exception {
+ Socket theSocket = new Socket();
+
+ theSocket.setOOBInline(true);
+ assertTrue("expected OOBIline to be true", theSocket.getOOBInline());
+
+ theSocket.setOOBInline(false);
+ assertFalse("expected OOBIline to be false", theSocket.getOOBInline());
+
+ theSocket.setOOBInline(false);
+ assertFalse("expected OOBIline to be false", theSocket.getOOBInline());
+ }
+
+ /**
+ * java.net.Socket#getOutputStream()
+ */
+ @SuppressWarnings("deprecation")
+ public void test_getOutputStream() throws IOException {
+ // Simple fetch test
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+ OutputStream os = client.getOutputStream();
+ assertNotNull("Failed to get stream", os);
+ os.close();
+ client.close();
+ server.close();
+
+ // Simple read/write test over the IO streams
+ final ServerSocket sinkServer = new ServerSocket(0);
+ Runnable runnable = new Runnable() {
+ public void run() {
+ try {
+ Socket worker = sinkServer.accept();
+ sinkServer.close();
+ InputStream in = worker.getInputStream();
+ in.read();
+ in.close();
+ worker.close();
+ } catch (IOException e) {
+ fail();
+ }
+ }
+ };
+ Thread thread = new Thread(runnable, "Socket.getOutputStream");
+ thread.start();
+
+ Socket pingClient = new Socket(InetAddress.getLocalHost(), sinkServer
+ .getLocalPort());
+
+ // Busy wait until the client is connected.
+ int c = 0;
+ while (!pingClient.isConnected()) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ }
+ if (++c > 4) {
+ fail("thread is not alive");
+ }
+ }
+
+ // Write some data to the server
+ OutputStream out = pingClient.getOutputStream();
+ out.write(new byte[256]);
+
+ // Wait for the server to finish
+ Thread.yield();
+ c = 0;
+ while (thread.isAlive()) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ }
+ if (++c > 4) {
+ fail("read call did not exit");
+ }
+ }
+
+ // Subsequent writes should throw an exception
+ try {
+ // The output buffer may remain valid until the close completes
+ for (int i = 0; i < 400; i++) {
+ out.write(new byte[256]);
+ }
+ fail("write to closed socket did not cause exception");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ out.close();
+ pingClient.close();
+ sinkServer.close();
+
+ // Regression test for HARMONY-873
+ ServerSocket ss2 = new ServerSocket(0);
+ Socket s = new Socket("127.0.0.1", ss2.getLocalPort());
+ ss2.accept();
+ s.shutdownOutput();
+ try {
+ s.getOutputStream();
+ fail("should throw SocketException");
+ } catch (SocketException e) {
+ // expected
+ }
+ }
+
+ public void test_getPort() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ int serverPort = server.getLocalPort();
+ Socket client = new Socket(InetAddress.getLocalHost(), serverPort);
+
+ assertEquals("Returned incorrect port", serverPort, client.getPort());
+
+ client.close();
+ server.close();
+ }
+
+ public void test_getReceiveBufferSize() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ client.setReceiveBufferSize(130);
+
+ assertTrue("Incorrect buffer size", client.getReceiveBufferSize() >= 130);
+
+ client.close();
+ server.close();
+ }
+
+ /**
+ * java.net.Socket#getRemoteSocketAddress()
+ */
+ public void test_getRemoteSocketAddress() throws IOException {
+ // set up server connect and then validate that we get the right
+ // response for the remote address
+ ServerSocket server = new ServerSocket(0);
+ int serverPort = server.getLocalPort();
+ Socket client = new Socket(InetAddress.getLocalHost(), serverPort);
+
+ assertEquals("Returned incorrect InetSocketAddress(1):",
+ new InetSocketAddress(InetAddress.getLocalHost(), serverPort),
+ client.getRemoteSocketAddress());
+ client.close();
+
+ // now create one that is not connected and validate that we get the
+ // right answer
+ Socket theSocket = new Socket();
+ theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ assertNull("Returned incorrect InetSocketAddress -unconnected socket:",
+ theSocket.getRemoteSocketAddress());
+
+ // now connect and validate we get the right answer
+ theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
+ serverPort));
+ assertEquals("Returned incorrect InetSocketAddress(2):",
+ new InetSocketAddress(InetAddress.getLocalHost(), serverPort),
+ theSocket.getRemoteSocketAddress());
+ theSocket.close();
+
+ server.close();
+ }
+
+ public void test_getReuseAddress() throws Exception {
+ Socket theSocket = new Socket();
+ theSocket.setReuseAddress(true);
+ assertTrue("getReuseAddress false when it should be true", theSocket.getReuseAddress());
+ theSocket.setReuseAddress(false);
+ assertFalse("getReuseAddress true when it should be False", theSocket.getReuseAddress());
+ }
+
+ public void test_getSendBufferSize() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ client.setSendBufferSize(134);
+ assertTrue("Incorrect buffer size", client.getSendBufferSize() >= 134);
+ client.close();
+ server.close();
+ }
+
+ public void test_getSoLinger() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ client.setSoLinger(true, 200);
+ assertEquals("Returned incorrect linger", 200, client.getSoLinger());
+ client.setSoLinger(false, 0);
+ client.close();
+ server.close();
+ }
+
+ public void test_getSoTimeout() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ client.setSoTimeout(100);
+ assertEquals("Returned incorrect sotimeout", 100, client.getSoTimeout());
+ client.close();
+ server.close();
+ }
+
+ public void test_getTcpNoDelay() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+ boolean bool = !client.getTcpNoDelay();
+ client.setTcpNoDelay(bool);
+ assertTrue("Failed to get no delay setting: " + client.getTcpNoDelay(), client.getTcpNoDelay() == bool);
+
+ client.close();
+ server.close();
+ }
+
+ public void test_getTrafficClass() throws Exception {
+ /*
+ * We cannot actually check that the values are set as if a platform
+ * does not support the option then it may come back unset even
+ * though we set it so just get the value to make sure we can get it
+ */
+ int trafficClass = new Socket().getTrafficClass();
+ assertTrue(0 <= trafficClass);
+ assertTrue(trafficClass <= 255);
+ }
+
+ /**
+ * java.net.Socket#isBound()
+ */
+ public void test_isBound() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+ Socket worker = server.accept();
+
+ assertTrue("Socket indicated not bound when it should be (1)", client
+ .isBound());
+ worker.close();
+ client.close();
+ server.close();
+
+ client = new Socket();
+ assertFalse("Socket indicated bound when it was not (2)", client
+ .isBound());
+
+ server = new ServerSocket();
+ server.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ InetSocketAddress boundAddress = new InetSocketAddress(server
+ .getInetAddress(), server.getLocalPort());
+ client.connect(boundAddress);
+ worker = server.accept();
+ assertTrue("Socket indicated not bound when it should be (2)", client
+ .isBound());
+ worker.close();
+ client.close();
+ server.close();
+
+ // now test when we bind explicitly
+ InetSocketAddress theLocalAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 0);
+ client = new Socket();
+ assertFalse("Socket indicated bound when it was not (3)", client
+ .isBound());
+ client.bind(theLocalAddress);
+ assertTrue("Socket indicated not bound when it should be (3a)", client
+ .isBound());
+ client.close();
+ assertTrue("Socket indicated not bound when it should be (3b)", client
+ .isBound());
+ }
+
+ /**
+ * java.net.Socket#isClosed()
+ */
+ public void test_isClosed() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+ Socket worker = server.accept();
+
+ // validate isClosed returns expected values
+ assertFalse("Socket should indicate it is not closed(1):", client
+ .isClosed());
+ client.close();
+ assertTrue("Socket should indicate it is closed(1):", client.isClosed());
+
+ // validate that isClosed works ok for sockets returned from
+ // ServerSocket.accept()
+ assertFalse("Accepted Socket should indicate it is not closed:", worker
+ .isClosed());
+ worker.close();
+ assertTrue("Accepted Socket should indicate it is closed:", worker
+ .isClosed());
+
+ // and finally for the server socket
+ assertFalse("Server Socket should indicate it is not closed:", server
+ .isClosed());
+ server.close();
+ assertTrue("Server Socket should indicate it is closed:", server
+ .isClosed());
+ }
+
+ /**
+ * java.net.Socket#isConnected()
+ */
+ public void test_isConnected() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+ Socket worker = server.accept();
+
+ assertTrue("Socket indicated not connected when it should be", client
+ .isConnected());
+ client.close();
+ worker.close();
+ server.close();
+
+ // now do it with the new constructors and revalidate
+ InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+ .getLocalHost(), 0);
+ client = new Socket();
+ assertFalse("Socket indicated connected when it was not", client
+ .isConnected());
+
+ server = new ServerSocket();
+ server.bind(theAddress);
+ InetSocketAddress boundAddress = new InetSocketAddress(server
+ .getInetAddress(), server.getLocalPort());
+ client.connect(boundAddress);
+ worker = server.accept();
+ assertTrue("Socket indicated not connected when it should be", client
+ .isConnected());
+ client.close();
+ worker.close();
+ server.close();
+ }
+
+ /**
+ * java.net.Socket#isInputShutdown()
+ */
+ public void test_isInputShutdown() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+
+ Socket worker = server.accept();
+ InputStream theInput = client.getInputStream();
+ OutputStream theOutput = worker.getOutputStream();
+
+ // make sure we get the right answer with newly connected socket
+ assertFalse("Socket indicated input shutdown when it should not have",
+ client.isInputShutdown());
+
+ // shutdown the output
+ client.shutdownInput();
+
+ // make sure we get the right answer once it is shut down
+ assertTrue(
+ "Socket indicated input was NOT shutdown when it should have been",
+ client.isInputShutdown());
+
+ client.close();
+ worker.close();
+ server.close();
+
+ // make sure we get the right answer for closed sockets
+ assertFalse(
+ "Socket indicated input was shutdown when socket was closed",
+ worker.isInputShutdown());
+
+ theInput.close();
+ theOutput.close();
+ }
+
+ /**
+ * java.net.Socket#isOutputShutdown()
+ */
+ public void test_isOutputShutdown() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server
+ .getLocalPort());
+
+ Socket worker = server.accept();
+ InputStream theInput = client.getInputStream();
+ OutputStream theOutput = worker.getOutputStream();
+
+ // make sure we get the right answer with newly connected socket
+ assertFalse("Socket indicated output shutdown when it should not have",
+ worker.isOutputShutdown());
+
+ // shutdown the output
+ worker.shutdownOutput();
+
+ // make sure we get the right answer once it is shut down
+ assertTrue(
+ "Socket indicated output was NOT shutdown when it should have been",
+ worker.isOutputShutdown());
+
+ client.close();
+ worker.close();
+ server.close();
+
+ // make sure we get the right answer for closed sockets
+ assertFalse(
+ "Socket indicated output was output shutdown when the socket was closed",
+ client.isOutputShutdown());
+
+ theInput.close();
+ theOutput.close();
+ }
+
+ /**
+ * java.net.Socket#sendUrgentData(int)
+ */
+ public void test_sendUrgentDataI() throws Exception {
+ /*
+ * Some platforms may not support urgent data in this case we will not
+ * run these tests. For now run on all platforms until we find those
+ * that do not support urgent data
+ */
+ String platform = System.getProperty("os.name");
+ if (platform.equals("Dummy")) {
+ return;
+ }
+
+ /*
+ * Test 1: Validate that when OOBInline is false that any urgent data is
+ * silently ignored
+ */
+ InetAddress localHost = InetAddress.getLocalHost();
+ ServerSocket server = new ServerSocket(0, 5, localHost);
+ SocketAddress serverAddress = new InetSocketAddress(localHost, server
+ .getLocalPort());
+
+ Socket client = new Socket();
+ client.setOOBInline(false);
+
+ client.connect(serverAddress);
+ Socket worker = server.accept();
+ worker.setTcpNoDelay(true);
+ OutputStream theOutput = worker.getOutputStream();
+
+ // Send the regular data
+ byte[] sendBytes = "Test".getBytes();
+ theOutput.write(sendBytes);
+ theOutput.flush();
+
+ // Send the urgent data byte which should not be received
+ worker.sendUrgentData("UrgentData".getBytes()[0]);
+ theOutput.write(sendBytes);
+ worker.shutdownOutput();
+ worker.close();
+
+ // Try to read the bytes back
+ int totalBytesRead = 0;
+ byte[] myBytes = new byte[100];
+ InputStream theInput = client.getInputStream();
+ while (true) {
+ int bytesRead = theInput.read(myBytes, totalBytesRead,
+ myBytes.length - totalBytesRead);
+ if (bytesRead == -1) {
+ break;
+ }
+ totalBytesRead = totalBytesRead + bytesRead;
+ }
+
+ client.close();
+ server.close();
+
+ byte[] expectBytes = new byte[2 * sendBytes.length];
+ System.arraycopy(sendBytes, 0, expectBytes, 0, sendBytes.length);
+ System.arraycopy(sendBytes, 0, expectBytes, sendBytes.length,
+ sendBytes.length);
+
+ byte[] resultBytes = new byte[totalBytesRead];
+ System.arraycopy(myBytes, 0, resultBytes, 0, totalBytesRead);
+
+ assertTrue("Urgent data was received", Arrays.equals(expectBytes,
+ resultBytes));
+
+ /*
+ * Test 2: Now validate that urgent data is received as expected. Expect
+ * that it should be between the two writes.
+ */
+ server = new ServerSocket(0, 5, localHost);
+ serverAddress = new InetSocketAddress(localHost, server.getLocalPort());
+
+ client = new Socket();
+ client.setOOBInline(true);
+
+ client.connect(serverAddress);
+ worker = server.accept();
+ worker.setTcpNoDelay(true);
+ theOutput = worker.getOutputStream();
+
+ // Send the regular data
+ sendBytes = "Test - Urgent Data".getBytes();
+ theOutput.write(sendBytes);
+
+ // Send the urgent data (one byte) which should be received
+ client.setOOBInline(true);
+ byte urgentByte = "UrgentData".getBytes()[0];
+ worker.sendUrgentData(urgentByte);
+
+ // Send more data, the urgent byte must stay in position
+ theOutput.write(sendBytes);
+ worker.shutdownOutput();
+ worker.close();
+
+ // Try to read the bytes back
+ totalBytesRead = 0;
+ myBytes = new byte[100];
+ theInput = client.getInputStream();
+ while (true) {
+ int bytesRead = theInput.read(myBytes, totalBytesRead,
+ myBytes.length - totalBytesRead);
+ if (bytesRead == -1) {
+ break;
+ }
+ totalBytesRead = totalBytesRead + bytesRead;
+ }
+
+ client.close();
+ server.close();
+
+ expectBytes = new byte[2 * sendBytes.length + 1];
+ System.arraycopy(sendBytes, 0, expectBytes, 0, sendBytes.length);
+ expectBytes[sendBytes.length] = urgentByte;
+ System.arraycopy(sendBytes, 0, expectBytes, sendBytes.length + 1,
+ sendBytes.length);
+
+ resultBytes = new byte[totalBytesRead];
+ System.arraycopy(myBytes, 0, resultBytes, 0, totalBytesRead);
+
+ assertTrue("Urgent data was not received with one urgent byte", Arrays
+ .equals(expectBytes, resultBytes));
+
+ /*
+ * Test 3: Now validate that urgent data is received as expected. Expect
+ * that it should be between the two writes.
+ */
+ server = new ServerSocket(0, 5, localHost);
+ serverAddress = new InetSocketAddress(localHost, server.getLocalPort());
+
+ client = new Socket();
+ client.setOOBInline(true);
+
+ client.connect(serverAddress);
+ worker = server.accept();
+ worker.setTcpNoDelay(true);
+ theOutput = worker.getOutputStream();
+
+ // Send the regular data
+ sendBytes = "Test - Urgent Data".getBytes();
+ theOutput.write(sendBytes);
+
+ // Send the urgent data (one byte) which should be received
+ client.setOOBInline(true);
+ byte urgentByte1 = "UrgentData".getBytes()[0];
+ byte urgentByte2 = "UrgentData".getBytes()[1];
+ worker.sendUrgentData(urgentByte1);
+ worker.sendUrgentData(urgentByte2);
+
+ // Send more data, the urgent byte must stay in position
+ theOutput.write(sendBytes);
+ worker.shutdownOutput();
+ worker.close();
+
+ // Try to read the bytes back
+ totalBytesRead = 0;
+ myBytes = new byte[100];
+ theInput = client.getInputStream();
+ while (true) {
+ int bytesRead = theInput.read(myBytes, totalBytesRead,
+ myBytes.length - totalBytesRead);
+ if (bytesRead == -1) {
+ break;
+ }
+ totalBytesRead = totalBytesRead + bytesRead;
+ }
+
+ client.close();
+ server.close();
+
+ expectBytes = new byte[2 * sendBytes.length + 2];
+ System.arraycopy(sendBytes, 0, expectBytes, 0, sendBytes.length);
+ expectBytes[sendBytes.length] = urgentByte1;
+ expectBytes[sendBytes.length + 1] = urgentByte2;
+ System.arraycopy(sendBytes, 0, expectBytes, sendBytes.length + 2,
+ sendBytes.length);
+
+ resultBytes = new byte[totalBytesRead];
+ System.arraycopy(myBytes, 0, resultBytes, 0, totalBytesRead);
+
+ assertTrue("Urgent data was not received with two urgent bytes", Arrays
+ .equals(expectBytes, resultBytes));
+
+ /*
+ * Test 4: Now test the case where there is only urgent data.
+ */
+ server = new ServerSocket(0, 5, localHost);
+ serverAddress = new InetSocketAddress(localHost, server.getLocalPort());
+
+ client = new Socket();
+ client.setOOBInline(true);
+
+ client.connect(serverAddress);
+ worker = server.accept();
+ worker.setTcpNoDelay(true);
+
+ // Send the urgent data (one byte) which should be received
+ client.setOOBInline(true);
+ urgentByte = "UrgentData".getBytes()[0];
+ worker.sendUrgentData(urgentByte);
+ worker.close();
+
+ // Try to read the bytes back
+ theInput = client.getInputStream();
+ int byteRead = theInput.read();
+
+ client.close();
+ server.close();
+
+ assertEquals("Sole urgent data was not received",
+ (int) (urgentByte & 0xff), byteRead);
+ }
+
+ /**
+ * java.net.Socket#setKeepAlive(boolean)
+ */
+ public void test_setKeepAliveZ() throws IOException {
+
+ class TestSocket extends Socket {
+ public TestSocket(SocketImpl impl) throws SocketException {
+ super(impl);
+ }
+ }
+
+ // There is not really a good test for this as it is there to detect
+ // crashed machines. Just make sure we can set it
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+ client.setKeepAlive(true);
+ client.setKeepAlive(false);
+ client.close();
+ server.close();
+
+ // Regression test for HARMONY-1136
+ new TestSocket(null).setKeepAlive(true);
+ }
+
+ public void test_setOOBInlineZ() throws Exception {
+ Socket theSocket = new Socket();
+ theSocket.setOOBInline(true);
+ assertTrue("expected OOBIline to be true", theSocket.getOOBInline());
+ }
+
+ public void test_setPerformancePreference_Int_Int_Int() throws IOException {
+ Socket theSocket = new Socket();
+ theSocket.setPerformancePreferences(1, 1, 1);
+ }
+
+ public void test_setReceiveBufferSizeI() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+ client.setReceiveBufferSize(130);
+ assertTrue("Incorrect buffer size", client.getReceiveBufferSize() >= 130);
+
+ client.close();
+ server.close();
+ }
+
+ public void test_setReuseAddressZ() throws Exception {
+ Socket theSocket = new Socket();
+ theSocket.setReuseAddress(false);
+ // Bind to any available port on the given address
+ theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ InetSocketAddress localAddress1 = new InetSocketAddress(theSocket.getLocalAddress(), theSocket.getLocalPort());
+
+ Socket theSocket2 = new Socket();
+ theSocket2.setReuseAddress(false);
+
+ /*
+ * Try to invoke a bind while the port is busy (TIME_WAIT). Note
+ * that we may not succeed, which will cause the test to pass
+ * without testing the reuseaddr behavior.
+ */
+ theSocket.close();
+ theSocket2.bind(localAddress1);
+
+ theSocket2.close();
+ }
+
+ public void test_setSendBufferSizeI() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ client.setSendBufferSize(134);
+ assertTrue("Incorrect buffer size", client.getSendBufferSize() >= 134);
+ client.close();
+ server.close();
+ }
+
+ public void test_setSocketImplFactoryLjava_net_SocketImplFactory() {
+ // Cannot test as setting will cause the factory to be changed for
+ // all subsequent sockets
+ }
+
+ public void test_setSoLingerZI() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ client.setSoLinger(true, 500);
+ assertEquals("Set incorrect linger", 500, client.getSoLinger());
+ client.setSoLinger(false, 0);
+ client.close();
+ server.close();
+ }
+
+ public void test_setSoTimeoutI() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ client.setSoTimeout(100);
+ assertEquals("Set incorrect sotimeout", 100, client.getSoTimeout());
+ client.close();
+ server.close();
+ }
+
+ public void test_setTcpNoDelayZ() throws Exception {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+ boolean bool;
+ client.setTcpNoDelay(bool = !client.getTcpNoDelay());
+ assertTrue("Failed to set no delay setting: " + client.getTcpNoDelay(), client.getTcpNoDelay() == bool);
+
+ client.close();
+ server.close();
+ }
+
+ public void test_setTrafficClassI() throws Exception {
+ int IPTOS_LOWCOST = 0x2;
+ int IPTOS_RELIABILTY = 0x4;
+ int IPTOS_THROUGHPUT = 0x8;
+ int IPTOS_LOWDELAY = 0x10;
+
+ Socket theSocket = new Socket();
+
+ // validate that value set must be between 0 and 255
+ try {
+ theSocket.setTrafficClass(256);
+ fail("No exception was thrown when traffic class set to 256");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ theSocket.setTrafficClass(-1);
+ fail("No exception was thrown when traffic class set to -1");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // now validate that we can set it to some good values
+ theSocket.setTrafficClass(IPTOS_LOWCOST);
+ theSocket.setTrafficClass(IPTOS_RELIABILTY);
+ theSocket.setTrafficClass(IPTOS_THROUGHPUT);
+ theSocket.setTrafficClass(IPTOS_LOWDELAY);
+ }
+
+ @SuppressWarnings("deprecation")
+ public void test_shutdownInput() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ int port = server.getLocalPort();
+ Socket client = new Socket(InetAddress.getLocalHost(), port);
+
+ Socket worker = server.accept();
+ worker.setTcpNoDelay(true);
+
+ InputStream theInput = client.getInputStream();
+ OutputStream theOutput = worker.getOutputStream();
+
+ // shutdown the input
+ client.shutdownInput();
+
+ // send the regular data
+ String sendString = "Test";
+ theOutput.write(sendString.getBytes());
+ theOutput.flush();
+
+ // RI fails here. It is a RI bug not to return 0 to indicate EOF
+ assertEquals(0, theInput.available());
+
+ client.close();
+ server.close();
+
+ // Regression test for HARMONY-2944
+ // Port 0 is not allowed to be used in connect() on some platforms,
+ // Since server has been closed here, so the port is free now
+ Socket s = new Socket("0.0.0.0", port, false);
+ s.shutdownInput();
+ try {
+ s.shutdownInput();
+ fail("should throw SocketException");
+ } catch (SocketException se) {
+ // Expected
+ }
+ s.close();
+ }
+
+ /**
+ * java.net.Socket#shutdownOutput()
+ */
+ @SuppressWarnings("deprecation")
+ public void test_shutdownOutput() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ int port = server.getLocalPort();
+ Socket client = new Socket(InetAddress.getLocalHost(), port);
+
+ Socket worker = server.accept();
+ OutputStream theOutput = worker.getOutputStream();
+
+ // shutdown the output
+ worker.shutdownOutput();
+
+ // send the regular data
+ String sendString = "Test";
+ try {
+ theOutput.write(sendString.getBytes());
+ theOutput.flush();
+ fail("No exception when writing on socket with output shutdown");
+ } catch (IOException e) {
+ // Expected
+ }
+
+ client.close();
+ server.close();
+
+ // Regression test for HARMONY-2944
+ // Port 0 is not allowed to be used in connect() on some platforms,
+ // Since server has been closed here, so the port is free now
+ Socket s = new Socket("0.0.0.0", port, false);
+ s.shutdownOutput();
+ try {
+ s.shutdownOutput();
+ fail("should throw SocketException");
+ } catch (SocketException se) {
+ // Expected
+ }
+ s.close();
+ }
+
+ public void test_toString() throws IOException {
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ // RI has "addr" and "localport" instead of "address" and "localPort".
+ String expected = "Socket[address=" + InetAddress.getLocalHost()
+ + ",port=" + client.getPort() + ",localPort="
+ + client.getLocalPort() + "]";
+ assertEquals(expected, client.toString());
+ client.close();
+ server.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTimeoutExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTimeoutExceptionTest.java
new file mode 100644
index 0000000..14b813c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTimeoutExceptionTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.SocketTimeoutException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class SocketTimeoutExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * {@link java.net.SocketTimeoutException#SocketTimeoutException()}
+ */
+ public void test_Constructor() {
+ SocketTimeoutException e = new SocketTimeoutException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * {@link java.net.SocketTimeoutException#SocketTimeoutException(String)}
+ */
+ public void test_ConstructorLjava_lang_String() {
+ SocketTimeoutException e = new SocketTimeoutException("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(new SocketTimeoutException());
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ SerializationTest.verifyGolden(this, new SocketTimeoutException());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/TestServerSocketInit.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/TestServerSocketInit.java
new file mode 100644
index 0000000..31aa5b6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/TestServerSocketInit.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+
+public class TestServerSocketInit {
+
+ public static void main(String[] args) throws IOException {
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.setReuseAddress(true);
+ serverSocket.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URISyntaxExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URISyntaxExceptionTest.java
new file mode 100644
index 0000000..ff8ac40
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URISyntaxExceptionTest.java
@@ -0,0 +1,115 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.URISyntaxException;
+import java.util.Locale;
+
+public class URISyntaxExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.net.URISyntaxException#URISyntaxException(java.lang.String,
+ *java.lang.String, int)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringI() {
+ try {
+ new URISyntaxException(null, "problem", 2);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException npe) {
+ // Expected
+ }
+
+ try {
+ new URISyntaxException("str", null, 2);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException npe) {
+ // Expected
+ }
+
+ try {
+ new URISyntaxException("str", "problem", -2);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException iae) {
+ // Expected
+ }
+
+ URISyntaxException e = new URISyntaxException("str", "problem", 2);
+ assertEquals("returned incorrect reason", "problem", e.getReason());
+ assertEquals("returned incorrect input", "str", e.getInput());
+ assertEquals("returned incorrect index", 2, e.getIndex());
+ }
+
+ /**
+ * java.net.URISyntaxException#URISyntaxException(java.lang.String,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+ try {
+ new URISyntaxException(null, "problem");
+ fail("Expected NullPointerException");
+ } catch (NullPointerException npe) {
+ // Expected
+ }
+
+ try {
+ new URISyntaxException("str", null);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException npe) {
+ // Expected
+ }
+
+ URISyntaxException e = new URISyntaxException("str", "problem");
+ assertEquals("returned incorrect reason", "problem", e.getReason());
+ assertEquals("returned incorrect input", "str", e.getInput());
+ assertEquals("returned incorrect index", -1, e.getIndex());
+ }
+
+ /**
+ * java.net.URISyntaxException#getIndex()
+ */
+ public void test_getIndex() {
+ // see constructor tests
+ }
+
+ /**
+ * java.net.URISyntaxException#getReason()
+ */
+ public void test_getReason() {
+ // see constructor tests
+ }
+
+ /**
+ * java.net.URISyntaxException#getInput()
+ */
+ public void test_getInput() {
+ // see constructor tests
+ }
+
+ /**
+ * java.net.URISyntaxException#getMessage()
+ */
+ public void test_getMessage() {
+ Locale.setDefault(Locale.US);
+ URISyntaxException e = new URISyntaxException("str", "problem", 3);
+ assertEquals("Returned incorrect message", "problem at index 3: str", e
+ .getMessage());
+
+ e = new URISyntaxException("str", "problem");
+ assertEquals("Returned incorrect message", "problem: str", e
+ .getMessage());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URITest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URITest.java
new file mode 100644
index 0000000..f81c975
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URITest.java
@@ -0,0 +1,1841 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class URITest extends TestCase {
+
+ private URI[] uris;
+
+ private URI[] getUris() throws URISyntaxException {
+ if (uris != null) {
+ return uris;
+ }
+
+ uris = new URI[] {
+ // single arg constructor
+ new URI(
+ "http://user%60%20info@host/a%20path?qu%60%20ery#fr%5E%20ag"),
+ // escaped octets for illegal chars
+ new URI(
+ "http://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g"),
+ // escaped octets for unicode chars
+ new URI(
+ "ascheme://user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery#fr\u00E4\u00E8g"),
+ // unicode chars equivalent to = new
+ // URI("ascheme://user\u00df\u00a3info@host:0/a\u0080path?qu\u00a9\u00aeery#fr\u00e4\u00e8g"),
+
+ // multiple arg constructors
+ new URI("http", "user%60%20info", "host", 80, "/a%20path", //$NON-NLS-4$
+ "qu%60%20ery", "fr%5E%20ag"),
+ // escaped octets for illegal
+ new URI("http", "user%C3%9F%C2%A3info", "host", -1,
+ "/a%E2%82%ACpath", "qu%C2%A9%C2%AEery",
+ "fr%C3%A4%C3%A8g"),
+ // escaped octets for unicode
+ new URI("ascheme", "user\u00DF\u00A3info", "host", 80,
+ "/a\u20ACpath", "qu\u00A9\u00AEery", "fr\u00E4\u00E8g"),
+ // unicode chars equivalent to = new
+ // URI("ascheme", "user\u00df\u00a3info", "host", 80,
+ // "/a\u0080path", "qu\u00a9\u00aeery", "fr\u00e4\u00e8g"),
+ new URI("http", "user` info", "host", 81, "/a path", "qu` ery",
+ "fr^ ag"), // illegal chars
+ new URI("http", "user%info", "host", 0, "/a%path", "que%ry",
+ "f%rag"),
+ // % as illegal char, not escaped octet
+
+ // urls with undefined components
+ new URI("mailto", "user@domain.com", null),
+ // no host, path, query or fragment
+ new URI("../adirectory/file.html#"),
+ // relative path with empty fragment;
+ new URI("news", "comp.infosystems.www.servers.unix", null), //
+ new URI(null, null, null, "fragment"), // only fragment
+ new URI("telnet://server.org"), // only host
+ new URI("http://reg:istry?query"),
+ // malformed hostname, therefore registry-based,
+ // with query
+ new URI("file:///c:/temp/calculate.pl?"),
+ // empty authority, non empty path, empty query
+ };
+ return uris;
+ }
+
+ /**
+ * java.net.URI#URI(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws URISyntaxException {
+ // tests for public URI(String uri) throws URISyntaxException
+
+ String[] constructorTests = new String[] {
+ "http://user@www.google.com:45/search?q=helpinfo#somefragment",
+ // http with authority, query and fragment
+ "ftp://ftp.is.co.za/rfc/rfc1808.txt", // ftp
+ "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles", // gopher
+ "mailto:mduerst@ifi.unizh.ch", // mailto
+ "news:comp.infosystems.www.servers.unix", // news
+ "telnet://melvyl.ucop.edu/", // telnet
+ "http://123.24.17.98/test", // IPv4 authority
+ "http://www.google.com:80/test",// domain name authority
+ "http://joe@[3ffe:2a00:100:7031::1]:80/test",
+ // IPv6 authority, with userinfo and port
+ "/relative", // relative starting with /
+ "//relative", // relative starting with //
+ "relative", // relative with no /
+ "#fragment",// relative just with fragment
+ "http://user@host:80", // UI, host,port
+ "http://user@host", // ui, host
+ "http://host", // host
+ "http://host:80", // host,port
+ "http://joe@:80", // ui, port (becomes registry-based)
+ "file:///foo/bar", // empty authority, non empty path
+ "ht?tp://hoe@host:80", // miscellaneous tests
+ "mai/lto:hey?joe#man", "http://host/a%20path#frag",
+ // path with an escaped octet for space char
+ "http://host/a%E2%82%ACpath#frag",
+ // path with escaped octet for unicode char, not USASCII
+ "http://host/a\u20ACpath#frag",
+ // path with unicode char, not USASCII equivalent to
+ // = "http://host/a\u0080path#frag",
+ "http://host%20name/", // escaped octets in host (becomes
+ // registry based)
+ "http://host\u00DFname/", // unicodechar in host (becomes
+ // registry based)
+ // equivalent to = "http://host\u00dfname/",
+ "ht123-+tp://www.google.com:80/test", // legal chars in scheme
+ };
+
+ for (int i = 0; i < constructorTests.length; i++) {
+ try {
+ new URI(constructorTests[i]);
+ } catch (URISyntaxException e) {
+ fail("Failed to construct URI for: " + constructorTests[i]
+ + " : " + e);
+ }
+ }
+
+ String[] constructorTestsInvalid = new String[] {
+ "http:///a path#frag", // space char in path, not in escaped
+ // octet form, with no host
+ "http://host/a[path#frag", // an illegal char, not in escaped
+ // octet form, should throw an
+ // exception
+ "http://host/a%path#frag", // invalid escape sequence in path
+ "http://host/a%#frag", // incomplete escape sequence in path
+
+ "http://host#a frag", // space char in fragment, not in
+ // escaped octet form, no path
+ "http://host/a#fr#ag", // illegal char in fragment
+ "http:///path#fr%ag", // invalid escape sequence in fragment,
+ // with no host
+ "http://host/path#frag%", // incomplete escape sequence in
+ // fragment
+
+ "http://host/path?a query#frag", // space char in query, not
+ // in escaped octet form
+ "http://host?query%ag", // invalid escape sequence in query, no
+ // path
+ "http:///path?query%", // incomplete escape sequence in query,
+ // with no host
+
+ "mailto:user^name@fklkf.com" // invalid char in scheme
+ // specific part
+ };
+
+ int[] constructorTestsInvalidIndices = new int[] { 9, 13, 13, 13, 13,
+ 16, 15, 21, 18, 17, 18, 11 };
+
+ for (int i = 0; i < constructorTestsInvalid.length; i++) {
+ try {
+ new URI(constructorTestsInvalid[i]);
+ fail("Failed to throw URISyntaxException for: "
+ + constructorTestsInvalid[i]);
+ } catch (URISyntaxException e) {
+ assertTrue("Wrong index in URISytaxException for: "
+ + constructorTestsInvalid[i] + " expected: "
+ + constructorTestsInvalidIndices[i] + ", received: "
+ + e.getIndex(),
+ e.getIndex() == constructorTestsInvalidIndices[i]);
+ }
+ }
+
+ String invalid2[] = {
+ // authority validation
+ "http://user@[3ffe:2x00:100:7031::1]:80/test", // malformed
+ // IPv6 authority
+ "http://[ipv6address]/apath#frag", // malformed ipv6 address
+ "http://[ipv6address/apath#frag", // malformed ipv6 address
+ "http://ipv6address]/apath#frag", // illegal char in host name
+ "http://ipv6[address/apath#frag",
+ "http://ipv6addr]ess/apath#frag",
+ "http://ipv6address[]/apath#frag",
+ // illegal char in username...
+ "http://us[]er@host/path?query#frag", "http://host name/path", // illegal
+ // char
+ // in
+ // authority
+ "http://host^name#fragment", // illegal char in authority
+ "telnet://us er@hostname/", // illegal char in authority
+ // missing components
+ "//", // Authority expected
+ "ascheme://", // Authority expected
+ "ascheme:", // Scheme-specific part expected
+ // scheme validation
+ "a scheme://reg/", // illegal char
+ "1scheme://reg/", // non alpha char as 1st char
+ "asche\u00dfme:ssp", // unicode char , not USASCII
+ "asc%20heme:ssp" // escape octets
+ };
+
+ for (int i = 0; i < invalid2.length; i++) {
+ try {
+ new URI(invalid2[i]);
+ fail("Failed to throw URISyntaxException for: " + invalid2[i]);
+ } catch (URISyntaxException e) {
+ }
+ }
+
+ // Regression test for HARMONY-23
+ try {
+ new URI("%3");
+ fail("Assert 0: URI constructor failed to throw exception on invalid input.");
+ } catch (URISyntaxException e) {
+ // Expected
+ assertEquals("Assert 1: Wrong index in URISyntaxException.", 0, e
+ .getIndex());
+ }
+
+ // Regression test for HARMONY-25
+ // if port value is negative, the authority should be considered
+ // registry-based.
+ URI uri = new URI("http://host:-8096/path/index.html");
+ assertEquals("Assert 2: returned wrong port value,", -1, uri.getPort());
+ assertNull("Assert 3: returned wrong host value,", uri.getHost());
+ try {
+ uri.parseServerAuthority();
+ fail("Assert 4: Expected URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ uri = new URI("http", "//myhost:-8096", null);
+ assertEquals("Assert 5: returned wrong port value,", -1, uri.getPort());
+ assertNull("Assert 6: returned wrong host value,", uri.getHost());
+ try {
+ uri.parseServerAuthority();
+ fail("Assert 7: Expected URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.URI#URI(java.lang.String)
+ */
+ public void test_URI_String() {
+ try {
+ URI myUri = new URI(":abc@mymail.com");
+ fail("TestA, URISyntaxException expected, but not received.");
+ } catch (URISyntaxException e) {
+ assertEquals("TestA, Wrong URISyntaxException index, ", 0, e
+ .getIndex());
+ }
+
+ try {
+ URI uri = new URI("path[one");
+ fail("TestB, URISyntaxException expected, but not received.");
+ } catch (URISyntaxException e1) {
+ assertEquals("TestB, Wrong URISyntaxException index, ", 4, e1
+ .getIndex());
+ }
+
+ try {
+ URI uri = new URI(" ");
+ fail("TestC, URISyntaxException expected, but not received.");
+ } catch (URISyntaxException e2) {
+ assertEquals("TestC, Wrong URISyntaxException index, ", 0, e2
+ .getIndex());
+ }
+ }
+
+ /**
+ * java.net.URI#URI(java.lang.String, java.lang.String,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String()
+ throws URISyntaxException {
+ URI uri = new URI("mailto", "mduerst@ifi.unizh.ch", null);
+ assertNull("wrong userinfo", uri.getUserInfo());
+ assertNull("wrong hostname", uri.getHost());
+ assertNull("wrong authority", uri.getAuthority());
+ assertEquals("wrong port number", -1, uri.getPort());
+ assertNull("wrong path", uri.getPath());
+ assertNull("wrong query", uri.getQuery());
+ assertNull("wrong fragment", uri.getFragment());
+ assertEquals("wrong SchemeSpecificPart", "mduerst@ifi.unizh.ch", uri
+ .getSchemeSpecificPart());
+
+ // scheme specific part can not be null
+ try {
+ uri = new URI("mailto", null, null);
+ fail("Expected URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ // scheme needs to start with an alpha char
+ try {
+ uri = new URI("3scheme", "//authority/path", "fragment");
+ fail("Expected URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ // scheme can not be empty string
+ try {
+ uri = new URI("", "//authority/path", "fragment");
+ fail("Expected URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.URI#URI(java.lang.String, java.lang.String,
+ *java.lang.String, int, java.lang.String, java.lang.String,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_StringILjava_lang_StringLjava_lang_StringLjava_lang_String() {
+ // check for URISyntaxException for invalid Server Authority
+ construct1("http", "user", "host\u00DFname", -1, "/file", "query",
+ "fragment"); // unicode chars in host name
+ // equivalent to construct1("http", "user", "host\u00dfname", -1,
+ // "/file", "query", "fragment");
+ construct1("http", "user", "host%20name", -1, "/file", "query",
+ "fragment"); // escaped octets in host name
+ construct1("http", "user", "host name", -1, "/file", "query",
+ "fragment"); // illegal char in host name
+ construct1("http", "user", "host]name", -1, "/file", "query",
+ "fragment"); // illegal char in host name
+
+ // missing host name
+ construct1("http", "user", "", 80, "/file", "query", "fragment");
+
+ // missing host name
+ construct1("http", "user", "", -1, "/file", "query", "fragment");
+
+ // malformed ipv4 address
+ construct1("telnet", null, "256.197.221.200", -1, null, null, null);
+
+ // malformed ipv4 address
+ construct1("ftp", null, "198.256.221.200", -1, null, null, null);
+
+ // These tests fail on other implementations...
+ // construct1("http", "user", null, 80, "/file", "query", "fragment");
+ // //missing host name
+ // construct1("http", "user", null, -1, "/file", "query", "fragment");
+ // //missing host name
+
+ // check for URISyntaxException for invalid scheme
+ construct1("ht\u00DFtp", "user", "hostname", -1, "/file", "query",
+ "fragment"); // unicode chars in scheme
+ // equivalent to construct1("ht\u00dftp", "user", "hostname", -1,
+ // "/file",
+ // "query", "fragment");
+
+ construct1("ht%20tp", "user", "hostname", -1, "/file", "query",
+ "fragment"); // escaped octets in scheme
+ construct1("ht tp", "user", "hostname", -1, "/file", "query",
+ "fragment"); // illegal char in scheme
+ construct1("ht]tp", "user", "hostname", -1, "/file", "query",
+ "fragment"); // illegal char in scheme
+
+ // relative path with scheme
+ construct1("http", "user", "hostname", -1, "relative", "query",
+ "fragment"); // unicode chars in scheme
+
+ // functional test
+ URI uri;
+ try {
+ uri = new URI("http", "us:e@r", "hostname", 85, "/file/dir#/qu?e/",
+ "qu?er#y", "frag#me?nt");
+ assertEquals("wrong userinfo", "us:e@r", uri.getUserInfo());
+ assertEquals("wrong hostname", "hostname", uri.getHost());
+ assertEquals("wrong port number", 85, uri.getPort());
+ assertEquals("wrong path", "/file/dir#/qu?e/", uri.getPath());
+ assertEquals("wrong query", "qu?er#y", uri.getQuery());
+ assertEquals("wrong fragment", "frag#me?nt", uri.getFragment());
+ assertEquals("wrong SchemeSpecificPart",
+ "//us:e@r@hostname:85/file/dir#/qu?e/?qu?er#y", uri
+ .getSchemeSpecificPart());
+ } catch (URISyntaxException e) {
+ fail("Unexpected Exception: " + e);
+ }
+ }
+
+ /*
+ * helper method checking if the 7 arg constructor throws URISyntaxException
+ * for a given set of parameters
+ */
+ private void construct1(String scheme, String userinfo, String host,
+ int port, String path, String query, String fragment) {
+ try {
+ URI uri = new URI(scheme, userinfo, host, port, path, query,
+ fragment);
+ fail("Expected URISyntaxException not thrown for URI: "
+ + uri.toString());
+ } catch (URISyntaxException e) {
+ // this constructor throws URISyntaxException for malformed server
+ // based authorities
+ }
+ }
+
+ /**
+ * @throws URISyntaxException
+ * java.net.URI#URI(java.lang.String, java.lang.String,
+ *java.lang.String, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_StringLjava_lang_String()
+ throws URISyntaxException {
+ // relative path
+ try {
+ URI myUri = new URI("http", "www.joe.com", "relative", "jimmy");
+ fail("URISyntaxException expected but not received.");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ // valid parameters for this constructor
+ URI uri;
+
+ uri = new URI("http", "www.joe.com", "/path", "jimmy");
+
+ // illegal char in path
+ uri = new URI("http", "www.host.com", "/path?q", "somefragment");
+
+ // empty fragment
+ uri = new URI("ftp", "ftp.is.co.za", "/rfc/rfc1808.txt", "");
+
+ // path with escaped octet for unicode char, not USASCII
+ uri = new URI("http", "host", "/a%E2%82%ACpath", "frag");
+
+ // frag with unicode char, not USASCII
+ // equivalent to = uri = new URI("http", "host", "/apath",
+ // "\u0080frag");
+ uri = new URI("http", "host", "/apath", "\u20ACfrag");
+
+ // Regression test for Harmony-1693
+ new URI(null, null, null, null);
+
+ // regression for Harmony-1346
+ try {
+ uri = new URI("http", ":2:3:4:5:6:7:8", "/apath", "\u20ACfrag");
+ fail("Should throw URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * @throws URISyntaxException
+ * java.net.URI#URI(java.lang.String, java.lang.String,
+ *java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_StringLjava_lang_StringLjava_lang_String()
+ throws URISyntaxException {
+ // URISyntaxException on relative path
+ try {
+ URI myUri = new URI("http", "www.joe.com", "relative", "query",
+ "jimmy");
+ fail("URISyntaxException expected but not received.");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ // test if empty authority is parsed into undefined host, userinfo and
+ // port and if unicode chars and escaped octets in components are
+ // preserved, illegal chars are quoted
+ URI uri = new URI("ht12-3+tp", "", "/p#a%E2%82%ACth", "q^u%25ery",
+ "f/r\u00DFag");
+
+ assertEquals("wrong scheme", "ht12-3+tp", uri.getScheme());
+ assertNull("wrong authority", uri.getUserInfo());
+ assertNull("wrong userinfo", uri.getUserInfo());
+ assertNull("wrong hostname", uri.getHost());
+ assertEquals("wrong port number", -1, uri.getPort());
+ assertEquals("wrong path", "/p#a%E2%82%ACth", uri.getPath());
+ assertEquals("wrong query", "q^u%25ery", uri.getQuery());
+ assertEquals("wrong fragment", "f/r\u00DFag", uri.getFragment());
+ // equivalent to = assertTrue("wrong fragment",
+ // uri.getFragment().equals("f/r\u00dfag"));
+ assertEquals("wrong SchemeSpecificPart", "///p#a%E2%82%ACth?q^u%25ery",
+ uri.getSchemeSpecificPart());
+ assertEquals("wrong RawSchemeSpecificPart",
+ "///p%23a%25E2%2582%25ACth?q%5Eu%2525ery", uri
+ .getRawSchemeSpecificPart());
+ assertEquals(
+ "incorrect toString()",
+ "ht12-3+tp:///p%23a%25E2%2582%25ACth?q%5Eu%2525ery#f/r\u00dfag",
+ uri.toString());
+ assertEquals("incorrect toASCIIString()",
+
+ "ht12-3+tp:///p%23a%25E2%2582%25ACth?q%5Eu%2525ery#f/r%C3%9Fag", uri
+ .toASCIIString());
+ }
+
+ /**
+ * @throws URISyntaxException
+ * java.net.URI#URI(java.lang.String, java.lang.String,
+ *java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void test_fiveArgConstructor() throws URISyntaxException {
+ // accept [] as part of valid ipv6 host name
+ URI uri = new URI("ftp", "[0001:1234::0001]", "/dir1/dir2", "query",
+ "frag");
+ assertEquals("Returned incorrect host", "[0001:1234::0001]", uri
+ .getHost());
+
+ // do not accept [] as part of invalid ipv6 address
+ try {
+ uri = new URI("ftp", "[www.abc.com]", "/dir1/dir2", "query", "frag");
+ fail("Expected URISyntaxException for invalid ipv6 address");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ // do not accept [] as part of user info
+ try {
+ uri = new URI("ftp", "[user]@host", "/dir1/dir2", "query", "frag");
+ fail("Expected URISyntaxException invalid user info");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.URI#compareTo(java.lang.Object)
+ */
+ public void test_compareToLjava_lang_Object() throws Exception {
+ // compareTo tests
+
+ String[][] compareToData = new String[][] {
+ // scheme tests
+ { "http:test", "" }, // scheme null, scheme not null
+ { "", "http:test" }, // reverse
+ { "http:test", "ftp:test" }, // schemes different
+ { "/test", "/test" }, // schemes null
+ { "http://joe", "http://joe" }, // schemes same
+ { "http://joe", "hTTp://joe" }, // schemes same ignoring case
+
+ // opacity : one opaque, the other not
+ { "http:opaque", "http://nonopaque" },
+ { "http://nonopaque", "http:opaque" },
+ { "mailto:abc", "mailto:abc" }, // same ssp
+ { "mailto:abC", "mailto:Abc" }, // different, by case
+ { "mailto:abc", "mailto:def" }, // different by letter
+ { "mailto:abc#ABC", "mailto:abc#DEF" },
+ { "mailto:abc#ABC", "mailto:abc#ABC" },
+ { "mailto:abc#DEF", "mailto:abc#ABC" },
+
+ // hierarchical tests..
+
+ // different authorities
+ { "//www.test.com/test", "//www.test2.com/test" },
+
+ { "/nullauth", "//nonnullauth/test" }, // one null authority
+ { "//nonnull", "/null" },
+ { "/hello", "/hello" }, // both authorities null
+ // different userinfo
+ { "http://joe@test.com:80", "http://test.com" },
+ { "http://jim@test.com", "http://james@test.com" },
+ // different hostnames
+ { "http://test.com", "http://toast.com" },
+ { "http://test.com:80", "test.com:87" }, // different ports
+ { "http://test.com", "http://test.com:80" },
+ // different paths
+ { "http://test.com:91/dir1", "http://test.com:91/dir2" },
+ // one null host
+ { "http:/hostless", "http://hostfilled.com/hostless" },
+
+ // queries
+ { "http://test.com/dir?query", "http://test.com/dir?koory" },
+ { "/test?query", "/test" },
+ { "/test", "/test?query" },
+ { "/test", "/test" },
+
+ // fragments
+ { "ftp://test.com/path?query#frag", "ftp://test.com/path?query" },
+ { "ftp://test.com/path?query", "ftp://test.com/path?query#frag" },
+ { "#frag", "#frag" }, { "p", "" },
+
+ { "http://www.google.com", "#test" } // miscellaneous
+ };
+
+ int[] compareToResults = { 1, -1, 2, 0, 0, 0, 1, -1, 0, 32, -3, -3, 0,
+ 3, -4, -1, 1, 0, 1, 8, -10, -12, -81, -1, -1, 6, 1, -1, 0, 1,
+ -1, 0, 1, 1, };
+
+ // test compareTo functionality
+ for (int i = 0; i < compareToResults.length; i++) {
+ URI b = new URI(compareToData[i][0]);
+ URI r = new URI(compareToData[i][1]);
+ if (b.compareTo(r) != compareToResults[i]) {
+ fail("Test " + i + ": " + compareToData[i][0] + " compared to "
+ + compareToData[i][1] + " -> " + b.compareTo(r)
+ + " rather than " + compareToResults[i]);
+ }
+ }
+ }
+
+ /**
+ * @throws URISyntaxException
+ * java.net.URI#compareTo(java.lang.Object)
+ */
+ public void test_compareTo2() throws URISyntaxException {
+ URI uri, uri2;
+
+ // test URIs with host names with different casing
+ uri = new URI("http://AbC.cOm/root/news");
+ uri2 = new URI("http://aBc.CoM/root/news");
+ assertEquals("TestA", 0, uri.compareTo(uri2));
+ assertEquals("TestB", 0, uri.compareTo(uri2));
+
+ // test URIs with one undefined component
+ uri = new URI("http://abc.com:80/root/news");
+ uri2 = new URI("http://abc.com/root/news");
+ assertTrue("TestC", uri.compareTo(uri2) > 0);
+ assertTrue("TestD", uri2.compareTo(uri) < 0);
+
+ // test URIs with one undefined component
+ uri = new URI("http://user@abc.com/root/news");
+ uri2 = new URI("http://abc.com/root/news");
+ assertTrue("TestE", uri.compareTo(uri2) > 0);
+ assertTrue("TestF", uri2.compareTo(uri) < 0);
+ }
+
+ /**
+ * java.net.URI#create(java.lang.String)
+ */
+ public void test_createLjava_lang_String() {
+ try {
+ URI myUri = URI.create("a scheme://reg/");
+ fail("IllegalArgumentException expected but not received.");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.URI#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() throws Exception {
+ String[][] equalsData = new String[][] {
+ { "", "" }, // null frags
+ { "/path", "/path#frag" },
+ { "#frag", "#frag2" },
+ { "#frag", "#FRag" },
+
+ // case insensitive on hex escapes
+ { "#fr%4F", "#fr%4f" },
+
+ { "scheme:test", "scheme2:test" }, // scheme stuff
+ { "test", "http:test" },
+ { "http:test", "test" },
+ { "SCheme:test", "schEMe:test" },
+
+ // hierarchical/opaque mismatch
+ { "mailto:jim", "mailto://jim" },
+ { "mailto://test", "mailto:test" },
+
+ // opaque
+ { "mailto:name", "mailto:name" },
+ { "mailtO:john", "mailto:jim" },
+
+ // test hex case insensitivity on ssp
+ { "mailto:te%4Fst", "mailto:te%4fst" },
+
+ { "mailto:john#frag", "mailto:john#frag2" },
+
+ // hierarchical
+ { "/test", "/test" }, // paths
+ { "/te%F4st", "/te%f4st" },
+ { "/TEst", "/teSt" },
+ { "", "/test" },
+
+ // registry based because they don't resolve properly to
+ // server-based add more tests here
+ { "//host.com:80err", "//host.com:80e" },
+ { "//host.com:81e%Abrr", "//host.com:81e%abrr" },
+
+ { "/test", "//auth.com/test" },
+ { "//test.com", "/test" },
+
+ { "//test.com", "//test.com" }, // hosts
+
+ // case insensitivity for hosts
+ { "//HoSt.coM/", "//hOsT.cOm/" },
+ { "//te%ae.com", "//te%aE.com" },
+ { "//test.com:80", "//test.com:81" },
+ { "//joe@test.com:80", "//test.com:80" },
+ { "//jo%3E@test.com:82", "//jo%3E@test.com:82" },
+ { "//test@test.com:85", "//test@test.com" }, };
+
+ boolean[] equalsResults = new boolean[] { true, false, false, false,
+ true, false, false, false, true, false, false, true, false,
+ true, false, true, true, false, false, false, true, false,
+ false, true, true, true, false, false, true, false, };
+
+ // test equals functionality
+ for (int i = 0; i < equalsResults.length; i++) {
+ URI b = new URI(equalsData[i][0]);
+ URI r = new URI(equalsData[i][1]);
+ if (b.equals(r) != equalsResults[i]) {
+ fail("Error: " + equalsData[i][0] + " == " + equalsData[i][1]
+ + "? -> " + b.equals(r) + " expected "
+ + equalsResults[i]);
+ }
+ }
+
+ }
+
+ /**
+ * @throws URISyntaxException
+ * java.net.URI#equals(java.lang.Object)
+ */
+ public void test_equals2() throws URISyntaxException {
+ // test URIs with empty string authority
+ URI uri = new URI("http:///~/dictionary");
+ URI uri2 = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(),
+ uri.getQuery(), uri.getFragment());
+ assertTrue(uri2.equals(uri));
+
+ // test URIs with port number
+ uri = new URI("http://abc.com%E2%82%AC:88/root/news");
+ uri2 = new URI("http://abc.com%E2%82%AC/root/news");
+ assertFalse(uri.equals(uri2));
+ assertFalse(uri2.equals(uri));
+
+ // test URIs with host names with different casing
+ uri = new URI("http://AbC.cOm/root/news");
+ uri2 = new URI("http://aBc.CoM/root/news");
+ assertTrue(uri.equals(uri2));
+ assertTrue(uri2.equals(uri));
+ }
+
+ /**
+ * java.net.URI#getAuthority()
+ */
+ public void test_getAuthority() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getAuthorityResults = {
+ "user` info@host",
+ "user\u00DF\u00A3info@host:80", // =
+ // "user\u00df\u00a3info@host:80",
+ "user\u00DF\u00A3info@host:0", // =
+ // "user\u00df\u00a3info@host:0",
+ "user%60%20info@host:80",
+ "user%C3%9F%C2%A3info@host",
+ "user\u00DF\u00A3info@host:80", // =
+ // "user\u00df\u00a3info@host:80",
+ "user` info@host:81", "user%info@host:0", null, null, null,
+ null, "server.org", "reg:istry", null, };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getAuthority();
+ if (getAuthorityResults[i] != result
+ && !getAuthorityResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getAuthority() returned: " + result
+ + ", expected: " + getAuthorityResults[i]);
+ }
+ }
+ // regression test for HARMONY-1119
+ assertNull(new URI(null, null, null, 127, null, null, null)
+ .getAuthority());
+ }
+
+ /**
+ * java.net.URI#getAuthority()
+ */
+ public void test_getAuthority2() throws Exception {
+ // tests for URIs with empty string authority component
+
+ URI uri = new URI("file:///tmp/");
+ assertNull("Authority not null for URI: " + uri, uri.getAuthority());
+ assertNull("Host not null for URI " + uri, uri.getHost());
+ assertEquals("testA, toString() returned incorrect value",
+ "file:///tmp/", uri.toString());
+
+ uri = new URI("file", "", "/tmp", "frag");
+ assertNull("Authority not null for URI: " + uri, uri.getAuthority());
+ assertNull("Host not null for URI " + uri, uri.getHost());
+ assertEquals("testB, toString() returned incorrect value",
+ "file:///tmp#frag", uri.toString());
+
+ uri = new URI("file", "", "/tmp", "query", "frag");
+ assertNull("Authority not null for URI: " + uri, uri.getAuthority());
+ assertNull("Host not null for URI " + uri, uri.getHost());
+ assertEquals("test C, toString() returned incorrect value",
+ "file:///tmp?query#frag", uri.toString());
+
+ // after normalization the host string info may be lost since the
+ // uri string is reconstructed
+ uri = new URI("file", "", "/tmp/a/../b/c", "query", "frag");
+ URI uri2 = uri.normalize();
+ assertNull("Authority not null for URI: " + uri2, uri.getAuthority());
+ assertNull("Host not null for URI " + uri2, uri.getHost());
+ assertEquals("test D, toString() returned incorrect value",
+ "file:///tmp/a/../b/c?query#frag", uri.toString());
+ assertEquals("test E, toString() returned incorrect value",
+ "file:/tmp/b/c?query#frag", uri2.toString());
+
+ // the empty string host will give URISyntaxException
+ // for the 7 arg constructor
+ try {
+ uri = new URI("file", "user", "", 80, "/path", "query", "frag");
+ fail("Expected URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.URI#getFragment()
+ */
+ public void test_getFragment() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getFragmentResults = { "fr^ ag", "fr\u00E4\u00E8g", // =
+ // "fr\u00e4\u00e8g",
+ "fr\u00E4\u00E8g", // = "fr\u00e4\u00e8g",
+ "fr%5E%20ag", "fr%C3%A4%C3%A8g", "fr\u00E4\u00E8g", // =
+ // "fr\u00e4\u00e8g",
+ "fr^ ag", "f%rag", null, "", null, "fragment", null, null, null };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getFragment();
+ if (getFragmentResults[i] != result
+ && !getFragmentResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getFragment() returned: " + result
+ + ", expected: " + getFragmentResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getHost()
+ */
+ public void test_getHost() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getHostResults = { "host", "host", "host", "host", "host",
+ "host", "host", "host", null, null, null, null, "server.org",
+ null, null };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getHost();
+ if (getHostResults[i] != result
+ && !getHostResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getHost() returned: " + result + ", expected: "
+ + getHostResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getPath()
+ */
+ public void test_getPath() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getPathResults = { "/a path",
+ "/a\u20ACpath", // = "/a\u0080path",
+ "/a\u20ACpath", // = "/a\u0080path",
+ "/a%20path", "/a%E2%82%ACpath",
+ "/a\u20ACpath", // = "/a\u0080path",
+ "/a path", "/a%path", null, "../adirectory/file.html", null,
+ "", "", "", "/c:/temp/calculate.pl" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getPath();
+ if (getPathResults[i] != result
+ && !getPathResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getPath() returned: " + result + ", expected: "
+ + getPathResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getPort()
+ */
+ public void test_getPort() throws Exception {
+ URI[] uris = getUris();
+
+ int[] getPortResults = { -1, 80, 0, 80, -1, 80, 81, 0, -1, -1, -1, -1,
+ -1, -1, -1 };
+
+ for (int i = 0; i < uris.length; i++) {
+ int result = uris[i].getPort();
+ assertTrue("Error: For URI \"" + uris[i].toString()
+ + "\", getPort() returned: " + result + ", expected: "
+ + getPortResults[i], result == getPortResults[i]);
+ }
+ }
+
+ /**
+ * java.net.URI#getPort()
+ */
+ public void test_getPort2() throws Exception {
+ // if port value is negative, the authority should be
+ // consider registry based.
+
+ URI uri = new URI("http://myhost:-8096/site/index.html");
+ assertEquals("TestA, returned wrong port value,", -1, uri.getPort());
+ assertNull("TestA, returned wrong host value,", uri.getHost());
+ try {
+ uri.parseServerAuthority();
+ fail("TestA, Expected URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ uri = new URI("http", "//myhost:-8096", null);
+ assertEquals("TestB returned wrong port value,", -1, uri.getPort());
+ assertNull("TestB returned wrong host value,", uri.getHost());
+ try {
+ uri.parseServerAuthority();
+ fail("TestB, Expected URISyntaxException");
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.URI#getQuery()
+ */
+ public void test_getQuery() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getQueryResults = { "qu` ery", "qu\u00A9\u00AEery", // =
+ // "qu\u00a9\u00aeery",
+ "qu\u00A9\u00AEery", // = "qu\u00a9\u00aeery",
+ "qu%60%20ery", "qu%C2%A9%C2%AEery", "qu\u00A9\u00AEery", // =
+ // "qu\u00a9\u00aeery",
+ "qu` ery", "que%ry", null, null, null, null, null, "query", "" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getQuery();
+ if (getQueryResults[i] != result
+ && !getQueryResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getQuery() returned: " + result + ", expected: "
+ + getQueryResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getRawAuthority()
+ */
+ public void test_getRawAuthority() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getRawAuthorityResults = {
+ "user%60%20info@host",
+ "user%C3%9F%C2%A3info@host:80",
+ "user\u00DF\u00A3info@host:0", // =
+ // "user\u00df\u00a3info@host:0",
+ "user%2560%2520info@host:80",
+ "user%25C3%259F%25C2%25A3info@host",
+ "user\u00DF\u00A3info@host:80", // =
+ // "user\u00df\u00a3info@host:80",
+ "user%60%20info@host:81", "user%25info@host:0", null, null,
+ null, null, "server.org", "reg:istry", null };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getRawAuthority();
+ if (getRawAuthorityResults[i] != result
+ && !getRawAuthorityResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getRawAuthority() returned: " + result
+ + ", expected: " + getRawAuthorityResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getRawFragment()
+ */
+ public void test_getRawFragment() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getRawFragmentResults = { "fr%5E%20ag",
+ "fr%C3%A4%C3%A8g",
+ "fr\u00E4\u00E8g", // = "fr\u00e4\u00e8g",
+ "fr%255E%2520ag", "fr%25C3%25A4%25C3%25A8g",
+ "fr\u00E4\u00E8g", // =
+ // "fr\u00e4\u00e8g",
+ "fr%5E%20ag", "f%25rag", null, "", null, "fragment", null,
+ null, null };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getRawFragment();
+ if (getRawFragmentResults[i] != result
+ && !getRawFragmentResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getRawFragment() returned: " + result
+ + ", expected: " + getRawFragmentResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getRawPath()
+ */
+ public void test_getRawPath() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getRawPathResults = { "/a%20path",
+ "/a%E2%82%ACpath",
+ "/a\u20ACpath", // = "/a\u0080path",
+ "/a%2520path", "/a%25E2%2582%25ACpath",
+ "/a\u20ACpath", // =
+ // "/a\u0080path",
+ "/a%20path", "/a%25path", null, "../adirectory/file.html",
+ null, "", "", "", "/c:/temp/calculate.pl" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getRawPath();
+ if (getRawPathResults[i] != result
+ && !getRawPathResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getRawPath() returned: " + result
+ + ", expected: " + getRawPathResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getRawQuery()
+ */
+ public void test_getRawQuery() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getRawQueryResults = {
+ "qu%60%20ery",
+ "qu%C2%A9%C2%AEery",
+ "qu\u00A9\u00AEery", // = "qu\u00a9\u00aeery",
+ "qu%2560%2520ery",
+ "qu%25C2%25A9%25C2%25AEery",
+ "qu\u00A9\u00AEery", // = "qu\u00a9\u00aeery",
+ "qu%60%20ery", "que%25ry", null, null, null, null, null,
+ "query", "" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getRawQuery();
+ if (getRawQueryResults[i] != result
+ && !getRawQueryResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getRawQuery() returned: " + result
+ + ", expected: " + getRawQueryResults[i]);
+ }
+ }
+
+ }
+
+ /**
+ * java.net.URI#getRawSchemeSpecificPart()
+ */
+ public void test_getRawSchemeSpecificPart() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getRawSspResults = {
+ "//user%60%20info@host/a%20path?qu%60%20ery",
+ "//user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery",
+ "//user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery", // =
+ // "//user\u00df\u00a3info@host:0/a\u0080path?qu\u00a9\u00aeery"
+ "//user%2560%2520info@host:80/a%2520path?qu%2560%2520ery",
+ "//user%25C3%259F%25C2%25A3info@host/a%25E2%2582%25ACpath?qu%25C2%25A9%25C2%25AEery",
+ "//user\u00DF\u00A3info@host:80/a\u20ACpath?qu\u00A9\u00AEery", // =
+ // "//user\u00df\u00a3info@host:80/a\u0080path?qu\u00a9\u00aeery"
+ "//user%60%20info@host:81/a%20path?qu%60%20ery",
+ "//user%25info@host:0/a%25path?que%25ry", "user@domain.com",
+ "../adirectory/file.html", "comp.infosystems.www.servers.unix",
+ "", "//server.org", "//reg:istry?query",
+ "///c:/temp/calculate.pl?" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getRawSchemeSpecificPart();
+ if (!getRawSspResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getRawSchemeSpecificPart() returned: " + result
+ + ", expected: " + getRawSspResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getRawUserInfo()
+ */
+ public void test_getRawUserInfo() throws URISyntaxException {
+ URI[] uris = getUris();
+
+ String[] getRawUserInfoResults = {
+ "user%60%20info",
+ "user%C3%9F%C2%A3info",
+ "user\u00DF\u00A3info", // = "user\u00df\u00a3info",
+ "user%2560%2520info",
+ "user%25C3%259F%25C2%25A3info",
+ "user\u00DF\u00A3info", // = "user\u00df\u00a3info",
+ "user%60%20info", "user%25info", null, null, null, null, null,
+ null, null };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getRawUserInfo();
+ if (getRawUserInfoResults[i] != result
+ && !getRawUserInfoResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getRawUserInfo() returned: " + result
+ + ", expected: " + getRawUserInfoResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getScheme()
+ */
+ public void test_getScheme() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getSchemeResults = { "http", "http", "ascheme", "http",
+ "http", "ascheme", "http", "http", "mailto", null, "news",
+ null, "telnet", "http", "file" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getScheme();
+ if (getSchemeResults[i] != result
+ && !getSchemeResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getScheme() returned: " + result
+ + ", expected: " + getSchemeResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#getSchemeSpecificPart()
+ */
+ public void test_getSchemeSpecificPart() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getSspResults = {
+ "//user` info@host/a path?qu` ery",
+ "//user\u00DF\u00A3info@host:80/a\u20ACpath?qu\u00A9\u00AEery", // =
+ // "//user\u00df\u00a3info@host:80/a\u0080path?qu\u00a9\u00aeery",
+ "//user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery", // =
+ // "//user\u00df\u00a3info@host:0/a\u0080path?qu\u00a9\u00aeery",
+ "//user%60%20info@host:80/a%20path?qu%60%20ery",
+ "//user%C3%9F%C2%A3info@host/a%E2%82%ACpath?qu%C2%A9%C2%AEery",
+ "//user\u00DF\u00A3info@host:80/a\u20ACpath?qu\u00A9\u00AEery", // =
+ // "//user\u00df\u00a3info@host:80/a\u0080path?qu\u00a9\u00aeery",
+ "//user` info@host:81/a path?qu` ery",
+ "//user%info@host:0/a%path?que%ry", "user@domain.com",
+ "../adirectory/file.html", "comp.infosystems.www.servers.unix",
+ "", "//server.org", "//reg:istry?query",
+ "///c:/temp/calculate.pl?" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getSchemeSpecificPart();
+ if (!getSspResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getSchemeSpecificPart() returned: " + result
+ + ", expected: " + getSspResults[i]);
+ }
+ }
+
+ }
+
+ /**
+ * java.net.URI#getUserInfo()
+ */
+ public void test_getUserInfo() throws Exception {
+ URI[] uris = getUris();
+
+ String[] getUserInfoResults = {
+ "user` info",
+ "user\u00DF\u00A3info", // =
+ // "user\u00df\u00a3info",
+ "user\u00DF\u00A3info", // = "user\u00df\u00a3info",
+ "user%60%20info",
+ "user%C3%9F%C2%A3info",
+ "user\u00DF\u00A3info", // = "user\u00df\u00a3info",
+ "user` info", "user%info", null, null, null, null, null, null,
+ null };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].getUserInfo();
+ if (getUserInfoResults[i] != result
+ && !getUserInfoResults[i].equals(result)) {
+ fail("Error: For URI \"" + uris[i].toString()
+ + "\", getUserInfo() returned: " + result
+ + ", expected: " + getUserInfoResults[i]);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#hashCode()
+ */
+ public void test_hashCode() throws Exception {
+ String[][] hashCodeData = new String[][] {
+ { "", "" }, // null frags
+ { "/path", "/path#frag" },
+ { "#frag", "#frag2" },
+ { "#frag", "#FRag" },
+
+ { "#fr%4F", "#fr%4F" }, // case insensitive on hex escapes
+
+ { "scheme:test", "scheme2:test" }, // scheme
+ { "test", "http:test" },
+ { "http:test", "test" },
+
+ // case insensitivity for scheme
+ { "SCheme:test", "schEMe:test" },
+
+ // hierarchical/opaque mismatch
+ { "mailto:jim", "mailto://jim" },
+ { "mailto://test", "mailto:test" },
+
+ // opaque
+ { "mailto:name", "mailto:name" },
+ { "mailtO:john", "mailto:jim" },
+ { "mailto:te%4Fst", "mailto:te%4Fst" },
+ { "mailto:john#frag", "mailto:john#frag2" },
+
+ // hierarchical
+ { "/test/", "/test/" }, // paths
+ { "/te%F4st", "/te%F4st" },
+ { "/TEst", "/teSt" },
+ { "", "/test" },
+
+ // registry based because they don't resolve properly to
+ // server-based
+ // add more tests here
+ { "//host.com:80err", "//host.com:80e" },
+ { "//host.com:81e%Abrr", "//host.com:81e%Abrr" },
+ { "//Host.com:80e", "//hoSt.com:80e" },
+
+ { "/test", "//auth.com/test" },
+ { "//test.com", "/test" },
+
+ { "//test.com", "//test.com" }, // server based
+
+ // case insensitivity for host
+ { "//HoSt.coM/", "//hOsT.cOm/" },
+ { "//te%aE.com", "//te%aE.com" },
+ { "//test.com:80", "//test.com:81" },
+ { "//joe@test.com:80", "//test.com:80" },
+ { "//jo%3E@test.com:82", "//jo%3E@test.com:82" },
+ { "//test@test.com:85", "//test@test.com" }, };
+
+ boolean[] hashCodeResults = new boolean[] { true, false, false, false,
+ true, false, false, false, true, false, false, true, false,
+ true, false, true, true, false, false, false, true, false,
+ false, false, true, true, true, false, false, true, false, };
+
+ for (int i = 0; i < hashCodeResults.length; i++) {
+ URI b = new URI(hashCodeData[i][0]);
+ URI r = new URI(hashCodeData[i][1]);
+ assertEquals("Error in hashcode equals results for" + b.toString()
+ + " " + r.toString(), hashCodeResults[i], b.hashCode() == r
+ .hashCode());
+ }
+
+ }
+
+ /**
+ * java.net.URI#isAbsolute()
+ */
+ public void test_isAbsolute() throws URISyntaxException {
+ String[] isAbsoluteData = new String[] { "mailto:user@ca.ibm.com",
+ "urn:isbn:123498989h", "news:software.ibm.com",
+ "http://www.amazon.ca", "file:///d:/temp/results.txt",
+ "scheme:ssp", "calculate.pl?isbn=123498989h",
+ "?isbn=123498989h", "//www.amazon.ca", "a.html", "#top",
+ "//pc1/", "//user@host/path/file" };
+
+ boolean results[] = new boolean[] { true, true, true, true, true, true,
+ false, false, false, false, false, false, false };
+
+ for (int i = 0; i < isAbsoluteData.length; i++) {
+ boolean result = new URI(isAbsoluteData[i]).isAbsolute();
+ assertEquals("new URI(" + isAbsoluteData[i] + ").isAbsolute()",
+ results[i], result);
+ }
+ }
+
+ /**
+ * java.net.URI#isOpaque()
+ */
+ public void test_isOpaque() throws URISyntaxException {
+ String[] isOpaqueData = new String[] { "mailto:user@ca.ibm.com",
+ "urn:isbn:123498989h", "news:software.ibm.com",
+ "http://www.amazon.ca", "file:///d:/temp/results.txt",
+ "scheme:ssp", "calculate.pl?isbn=123498989h",
+ "?isbn=123498989h", "//www.amazon.ca", "a.html", "#top",
+ "//pc1/", "//user@host/path/file" };
+
+ boolean results[] = new boolean[] { true, true, true, false, false,
+ true, false, false, false, false, false, false, false };
+
+ for (int i = 0; i < isOpaqueData.length; i++) {
+ boolean result = new URI(isOpaqueData[i]).isOpaque();
+ assertEquals("new URI(" + isOpaqueData[i] + ").isOpaque()",
+ results[i], result);
+ }
+ }
+
+ /**
+ * java.net.URI#normalize()
+ */
+ public void test_normalize() throws Exception {
+ // normal
+ testNormalize("/", "/");
+ testNormalize("/a", "/a");
+ testNormalize("/a/b", "/a/b");
+ testNormalize("/a/b/c", "/a/b/c");
+ // single, '.'
+ testNormalize("/.", "/");
+ testNormalize("/./", "/");
+ testNormalize("/./.", "/");
+ testNormalize("/././", "/");
+ testNormalize("/./a", "/a");
+ testNormalize("/./a/", "/a/");
+ testNormalize("/././a", "/a");
+ testNormalize("/././a/", "/a/");
+ testNormalize("/a/.", "/a/");
+ testNormalize("/a/./", "/a/");
+ testNormalize("/a/./.", "/a/");
+ testNormalize("/a/./b", "/a/b");
+ // double, '..'
+ testNormalize("/a/..", "/");
+ testNormalize("/a/../", "/");
+ testNormalize("/a/../b", "/b");
+ testNormalize("/a/../b/..", "/");
+ testNormalize("/a/../b/../", "/");
+ testNormalize("/a/../b/../c", "/c");
+ testNormalize("/..", "/..");
+ testNormalize("/../", "/../");
+ testNormalize("/../..", "/../..");
+ testNormalize("/../../", "/../../");
+ testNormalize("/../a", "/../a");
+ testNormalize("/../a/", "/../a/");
+ testNormalize("/../../a", "/../../a");
+ testNormalize("/../../a/", "/../../a/");
+ testNormalize("/a/b/../../c", "/c");
+ testNormalize("/a/b/../..", "/");
+ testNormalize("/a/b/../../", "/");
+ testNormalize("/a/b/../../c", "/c");
+ testNormalize("/a/b/c/../../../d", "/d");
+ testNormalize("/a/b/..", "/a/");
+ testNormalize("/a/b/../", "/a/");
+ testNormalize("/a/b/../c", "/a/c");
+ // miscellaneous
+ testNormalize("/a/b/.././../../c/./d/../e", "/../c/e");
+ testNormalize("/a/../../.c././../././c/d/../g/..", "/../c/");
+ // '.' in the middle of segments
+ testNormalize("/a./b", "/a./b");
+ testNormalize("/.a/b", "/.a/b");
+ testNormalize("/a.b/c", "/a.b/c");
+ testNormalize("/a/b../c", "/a/b../c");
+ testNormalize("/a/..b/c", "/a/..b/c");
+ testNormalize("/a/b..c/d", "/a/b..c/d");
+ // no leading slash, miscellaneous
+ testNormalize("", "");
+ testNormalize("a", "a");
+ testNormalize("a/b", "a/b");
+ testNormalize("a/b/c", "a/b/c");
+ testNormalize("../", "../");
+ testNormalize(".", "");
+ testNormalize("..", "..");
+ testNormalize("../g", "../g");
+ testNormalize("g/a/../../b/c/./g", "b/c/g");
+ testNormalize("a/b/.././../../c/./d/../e", "../c/e");
+ testNormalize("a/../../.c././../././c/d/../g/..", "../c/");
+ }
+
+ private void testNormalize(String original, String expected) throws URISyntaxException {
+ assertEquals(expected, new URI(original).normalize().toString());
+ }
+
+ /**
+ * java.net.URI#normalize()
+ */
+ public void test_normalize2() throws URISyntaxException {
+ URI uri1 = null, uri2 = null;
+ uri1 = new URI("file:/D:/one/two/../../three");
+ uri2 = uri1.normalize();
+
+ assertEquals("Normalized to incorrect URI", "file:/D:/three", uri2
+ .toString());
+ assertTrue("Resolved URI is not absolute", uri2.isAbsolute());
+ assertFalse("Resolved URI is opaque", uri2.isOpaque());
+ assertEquals("Resolved URI has incorrect scheme specific part",
+ "/D:/three", uri2.getRawSchemeSpecificPart());
+ }
+
+ /**
+ * java.net.URI#normalize()
+ */
+ public void test_normalize3() throws URISyntaxException {
+ // return same URI if it has a normalized path already
+ URI uri1 = null, uri2 = null;
+ uri1 = new URI("http://host/D:/one/two/three");
+ uri2 = uri1.normalize();
+ assertSame("Failed to return same URI after normalization", uri1, uri2);
+
+ // try with empty path
+ uri1 = new URI("http", "host", null, "fragment");
+ uri2 = uri1.normalize();
+ assertSame("Failed to return same URI after normalization", uri1, uri2);
+ }
+
+ /**
+ * java.net.URI#parseServerAuthority()
+ */
+ public void test_parseServerAuthority() throws URISyntaxException {
+ // registry based uris
+ URI[] uris = null;
+ uris = new URI[] {
+ // port number not digits
+ new URI("http://foo:bar/file#fragment"),
+ new URI("http", "//foo:bar/file", "fragment"),
+
+ // unicode char in the hostname = new
+ // URI("http://host\u00dfname/")
+ new URI("http://host\u00DFname/"),
+
+ new URI("http", "//host\u00DFname/", null),
+ // = new URI("http://host\u00dfname/", null),
+
+ // escaped octets in host name
+ new URI("http://host%20name/"),
+ new URI("http", "//host%20name/", null),
+
+ // missing host name, port number
+ new URI("http://joe@:80"),
+
+ // missing host name, no port number
+ new URI("http://user@/file?query#fragment"),
+
+ new URI("//host.com:80err"), // malformed port number
+ new URI("//host.com:81e%Abrr"),
+
+ // malformed ipv4 address
+ new URI("telnet", "//256.197.221.200", null),
+
+ new URI("telnet://198.256.221.200"),
+ new URI("//te%ae.com"), // misc ..
+ new URI("//:port"), new URI("//:80"),
+
+ // last label has to start with alpha char
+ new URI("//fgj234fkgj.jhj.123."),
+
+ new URI("//fgj234fkgj.jhj.123"),
+
+ // '-' cannot be first or last character in a label
+ new URI("//-domain.name"), new URI("//domain.name-"),
+ new URI("//domain-"),
+
+ // illegal char in host name
+ new URI("//doma*in"),
+
+ // host expected
+ new URI("http://:80/"), new URI("http://user@/"),
+
+ // ipv6 address not enclosed in "[]"
+ new URI("http://3ffe:2a00:100:7031:22:1:80:89/"),
+
+ // expected ipv6 addresses to be enclosed in "[]"
+ new URI("http", "34::56:78", "/path", "query", "fragment"),
+
+ // expected host
+ new URI("http", "user@", "/path", "query", "fragment") };
+ // these URIs do not have valid server based authorities,
+ // but single arg, 3 and 5 arg constructors
+ // parse them as valid registry based authorities
+
+ // exception should occur when parseServerAuthority is
+ // requested on these uris
+ for (int i = 0; i < uris.length; i++) {
+ try {
+ URI uri = uris[i].parseServerAuthority();
+ fail("URISyntaxException expected but not received for URI: "
+ + uris[i].toString());
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+ }
+
+ // valid Server based authorities
+ new URI("http", "3ffe:2a00:100:7031:2e:1:80:80", "/path", "fragment")
+ .parseServerAuthority();
+ new URI("http", "host:80", "/path", "query", "fragment")
+ .parseServerAuthority();
+ new URI("http://[::3abc:4abc]:80/").parseServerAuthority();
+ new URI("http", "34::56:78", "/path", "fragment")
+ .parseServerAuthority();
+ new URI("http", "[34:56::78]:80", "/path", "fragment")
+ .parseServerAuthority();
+
+ // invalid authorities (neither server nor registry)
+ try {
+ URI uri = new URI("http://us[er@host:80/");
+ fail("Expected URISyntaxException for URI " + uri.toString());
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ try {
+ URI uri = new URI("http://[ddd::hgghh]/");
+ fail("Expected URISyntaxException for URI " + uri.toString());
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ try {
+ URI uri = new URI("http", "[3ffe:2a00:100:7031:2e:1:80:80]a:80",
+ "/path", "fragment");
+ fail("Expected URISyntaxException for URI " + uri.toString());
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ try {
+ URI uri = new URI("http", "host:80", "/path", "fragment");
+ fail("Expected URISyntaxException for URI " + uri.toString());
+ } catch (URISyntaxException e) {
+ // Expected
+ }
+
+ // regression test for HARMONY-1126
+ assertNotNull(URI.create("file://C:/1.txt").parseServerAuthority());
+ }
+
+ /**
+ * java.net.URI#relativize(java.net.URI)
+ */
+ public void test_relativizeLjava_net_URI() throws URISyntaxException {
+ // rel = opaque
+ testRelativize("http://www.google.com/dir1/dir2", "mailto:test", "mailto:test");
+ // base = opaque
+ testRelativize("mailto:test", "http://www.google.com", "http://www.google.com");
+ // different authority
+ testRelativize("http://www.eclipse.org/dir1", "http://www.google.com/dir1/dir2",
+ "http://www.google.com/dir1/dir2");
+ // different scheme
+ testRelativize("http://www.google.com", "ftp://www.google.com", "ftp://www.google.com");
+ testRelativize("http://www.google.com/dir1/dir2/",
+ "http://www.google.com/dir3/dir4/file.txt",
+ "http://www.google.com/dir3/dir4/file.txt");
+ testRelativize("http://www.google.com/dir1/", "http://www.google.com/dir1/dir2/file.txt",
+ "dir2/file.txt");
+ testRelativize("./dir1/", "./dir1/hi", "hi");
+ testRelativize("/dir1/./dir2", "/dir1/./dir2/hi", "dir2/hi");
+ testRelativize("/dir1/dir2/..", "/dir1/dir2/../hi", "hi");
+ testRelativize("/dir1/dir2/..", "/dir1/dir2/hi", "dir2/hi");
+ testRelativize("/dir1/dir2/", "/dir1/dir3/../dir2/text", "text");
+ testRelativize("//www.google.com", "//www.google.com/dir1/file", "/dir1/file");
+ testRelativize("/dir1", "/dir1/hi", "dir1/hi");
+ testRelativize("/dir1/", "/dir1/hi", "hi");
+
+ URI a = new URI("http://host/dir");
+ URI b = new URI("http://host/dir/file?query");
+ assertEquals("Assert 0: URI relativized incorrectly,",
+ new URI("dir/file?query"), a.relativize(b));
+
+ // One URI with empty host
+ a = new URI("file:///~/first");
+ b = new URI("file://tools/~/first");
+ assertEquals("Assert 1: URI relativized incorrectly,", new URI(
+ "file://tools/~/first"), a.relativize(b));
+ assertEquals("Assert 2: URI relativized incorrectly,", new URI(
+ "file:///~/first"), b.relativize(a));
+
+ // Both URIs with empty hosts
+ b = new URI("file:///~/second");
+ assertEquals("Assert 3: URI relativized incorrectly,", new URI("second"), a.relativize(b));
+ assertEquals("Assert 4: URI relativized incorrectly,", new URI("first"), b.relativize(a));
+ }
+
+ private void testRelativize(String base, String target, String expected)
+ throws URISyntaxException {
+ assertEquals(expected, new URI(base).relativize(new URI(target)).toString());
+ }
+
+ // Regression test for HARMONY-6075
+ public void test_relativize3() throws Exception {
+ URI uri = new URI("file", null, "/test/location", null);
+
+ URI base = new URI("file", null, "/test", null);
+
+ URI relative = base.relativize(uri);
+ assertEquals("test/location", relative.getSchemeSpecificPart());
+ assertNull(relative.getScheme());
+ }
+
+ /**
+ * java.net.URI#relativize(java.net.URI)
+ */
+ public void test_relativize2() throws URISyntaxException {
+ URI a = new URI("http://host/dir");
+ URI b = new URI("http://host/dir/file?query");
+ assertEquals("relativized incorrectly,", new URI("dir/file?query"), a.relativize(b));
+
+ // one URI with empty host
+ a = new URI("file:///~/dictionary");
+ b = new URI("file://tools/~/dictionary");
+ assertEquals("relativized incorrectly,", new URI(
+ "file://tools/~/dictionary"), a.relativize(b));
+ assertEquals("relativized incorrectly,",
+ new URI("file:///~/dictionary"), b.relativize(a));
+
+ // two URIs with empty hosts
+ b = new URI("file:///~/thesaurus");
+ assertEquals("relativized incorrectly,", new URI("thesaurus"), a.relativize(b));
+ assertEquals("relativized incorrectly,", new URI("dictionary"), b.relativize(a));
+
+ URI one = new URI("file:/C:/test/ws");
+ URI two = new URI("file:/C:/test/ws");
+
+ URI empty = new URI("");
+ assertEquals(empty, one.relativize(two));
+
+ one = new URI("file:/C:/test/ws");
+ two = new URI("file:/C:/test/ws/p1");
+ assertEquals(new URI("ws/p1"), one.relativize(two));
+
+ one = new URI("file:/C:/test/ws/");
+ assertEquals(new URI("p1"), one.relativize(two));
+ }
+
+ /**
+ * java.net.URI#resolve(java.net.URI)
+ */
+ public void test_resolve() throws URISyntaxException {
+ URI uri1 = null, uri2 = null;
+ uri1 = new URI("file:/D:/one/two/three");
+ uri2 = uri1.resolve(new URI(".."));
+
+ assertEquals("Resolved to incorrect URI", "file:/D:/one/", uri2
+ .toString());
+ assertTrue("Resolved URI is not absolute", uri2.isAbsolute());
+ assertFalse("Resolved URI is opaque", uri2.isOpaque());
+ assertEquals("Resolved URI has incorrect scheme specific part",
+ "/D:/one/", uri2.getRawSchemeSpecificPart());
+ }
+
+ /**
+ * java.net.URI#resolve(java.net.URI)
+ */
+ public void test_resolveLjava_net_URI() {
+ // resolution tests
+ String[][] resolveData = new String[][] {
+ // authority in given URI
+ { "http://www.test.com/dir",
+ "//www.test.com/hello?query#fragment" },
+ // no authority, absolute path
+ { "http://www.test.com/dir", "/abspath/file.txt" },
+ // no authority, relative paths
+ { "/", "dir1/file.txt" }, { "/dir1", "dir2/file.txt" },
+ { "/dir1/", "dir2/file.txt" }, { "", "dir1/file.txt" },
+ { "dir1", "dir2/file.txt" }, { "dir1/", "dir2/file.txt" },
+ // normalization required
+ { "/dir1/dir2/../dir3/./", "dir4/./file.txt" },
+ // allow a standalone fragment to be resolved
+ { "http://www.google.com/hey/joe?query#fragment", "#frag2" },
+ // return given when base is opaque
+ { "mailto:idontexist@uk.ibm.com", "dir1/dir2" },
+ // return given when given is absolute
+ { "http://www.google.com/hi/joe", "http://www.oogle.com" }, };
+
+ // expected results
+ String[] resolveResults = new String[] {
+ "http://www.test.com/hello?query#fragment",
+ "http://www.test.com/abspath/file.txt", "/dir1/file.txt",
+ "/dir2/file.txt", "/dir1/dir2/file.txt", "dir1/file.txt",
+ "dir2/file.txt", "dir1/dir2/file.txt",
+ "/dir1/dir3/dir4/file.txt",
+ "http://www.google.com/hey/joe?query#frag2", "dir1/dir2",
+ "http://www.oogle.com", };
+
+ for (int i = 0; i < resolveResults.length; i++) {
+ try {
+ URI b = new URI(resolveData[i][0]);
+ URI r = new URI(resolveData[i][1]);
+ URI result = b.resolve(r);
+ if (!result.toString().equals(resolveResults[i])) {
+ fail("Error: resolve, " + resolveData[i][0] + ", "
+ + resolveData[i][1] + " returned: " + b.resolve(r)
+ + ", expected:" + resolveResults[i]);
+ }
+ if (!b.isOpaque()) {
+ assertEquals(b + " and " + result
+ + " incorrectly differ in absoluteness", b
+ .isAbsolute(), result.isAbsolute());
+ }
+ } catch (URISyntaxException e) {
+ fail("Exception on resolve test on data " + resolveData[i][0]
+ + ", " + resolveData[i][1] + ": " + e);
+ }
+ }
+ }
+
+ /**
+ * java.net.URI#toASCIIString()
+ */
+ public void test_toASCIIString() throws Exception {
+ URI[] uris = getUris();
+
+ String[] toASCIIStringResults0 = new String[] {
+ "http://user%60%20info@host/a%20path?qu%60%20ery#fr%5E%20ag",
+ "http://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g",
+ "ascheme://user%C3%9F%C2%A3info@host:0/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g",
+ "http://user%2560%2520info@host:80/a%2520path?qu%2560%2520ery#fr%255E%2520ag",
+ "http://user%25C3%259F%25C2%25A3info@host/a%25E2%2582%25ACpath?qu%25C2%25A9%25C2%25AEery#fr%25C3%25A4%25C3%25A8g",
+ "ascheme://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g",
+ "http://user%60%20info@host:81/a%20path?qu%60%20ery#fr%5E%20ag",
+ "http://user%25info@host:0/a%25path?que%25ry#f%25rag",
+ "mailto:user@domain.com", "../adirectory/file.html#",
+ "news:comp.infosystems.www.servers.unix", "#fragment",
+ "telnet://server.org", "http://reg:istry?query",
+ "file:///c:/temp/calculate.pl?" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].toASCIIString();
+ assertTrue("Error: For URI \"" + uris[i].toString()
+ + "\", toASCIIString() returned: " + result
+ + ", expected: " + toASCIIStringResults0[i], result
+ .equals(toASCIIStringResults0[i]));
+ }
+
+ String[] toASCIIStringData = new String[] {
+ "http://www.test.com/\u00DF/dir/",
+ "http://www.test.com/\u20AC/dir", "http://www.\u20AC.com/dir",
+ "http://www.test.com/\u20AC/dir/file#fragment",
+ "mailto://user@domain.com", "mailto://user\u00DF@domain.com", };
+
+ String[] toASCIIStringResults = new String[] {
+ "http://www.test.com/%C3%9F/dir/",
+ "http://www.test.com/%E2%82%AC/dir",
+ "http://www.%E2%82%AC.com/dir",
+ "http://www.test.com/%E2%82%AC/dir/file#fragment",
+ "mailto://user@domain.com", "mailto://user%C3%9F@domain.com", };
+
+ for (int i = 0; i < toASCIIStringData.length; i++) {
+ URI test = new URI(toASCIIStringData[i]);
+ String result = test.toASCIIString();
+ assertTrue("Error: new URI(\"" + toASCIIStringData[i]
+ + "\").toASCIIString() returned: " + result
+ + ", expected: " + toASCIIStringResults[i], result
+ .equals(toASCIIStringResults[i]));
+ }
+ }
+
+ /**
+ * java.net.URI#toString()
+ */
+ public void test_toString() throws Exception {
+ URI[] uris = getUris();
+
+ String[] toStringResults = {
+ "http://user%60%20info@host/a%20path?qu%60%20ery#fr%5E%20ag",
+ "http://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g",
+ "ascheme://user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery#fr\u00E4\u00E8g",
+ // =
+ // "ascheme://user\u00df\u00a3info@host:0/a\u0080path?qu\u00a9\u00aeery#fr\u00e4\u00e8g",
+ "http://user%2560%2520info@host:80/a%2520path?qu%2560%2520ery#fr%255E%2520ag",
+ "http://user%25C3%259F%25C2%25A3info@host/a%25E2%2582%25ACpath?qu%25C2%25A9%25C2%25AEery#fr%25C3%25A4%25C3%25A8g",
+ "ascheme://user\u00DF\u00A3info@host:80/a\u20ACpath?qu\u00A9\u00AEery#fr\u00E4\u00E8g",
+ // =
+ // "ascheme://user\u00df\u00a3info@host:80/a\u0080path?qu\u00a9\u00aeery#fr\u00e4\u00e8g",
+ "http://user%60%20info@host:81/a%20path?qu%60%20ery#fr%5E%20ag",
+ "http://user%25info@host:0/a%25path?que%25ry#f%25rag",
+ "mailto:user@domain.com", "../adirectory/file.html#",
+ "news:comp.infosystems.www.servers.unix", "#fragment",
+ "telnet://server.org", "http://reg:istry?query",
+ "file:///c:/temp/calculate.pl?" };
+
+ for (int i = 0; i < uris.length; i++) {
+ String result = uris[i].toString();
+ assertTrue("Error: For URI \"" + uris[i].toString()
+ + "\", toString() returned: " + result + ", expected: "
+ + toStringResults[i], result.equals(toStringResults[i]));
+ }
+ }
+
+ /**
+ * java.net.URI#toURL()
+ */
+ public void test_toURL() throws Exception {
+ String absoluteuris[] = new String[] { "mailto:noreply@apache.org",
+ "urn:isbn:123498989h", "news:software.ibm.com",
+ "http://www.apache.org", "file:///d:/temp/results.txt",
+ "scheme:ssp", };
+
+ String relativeuris[] = new String[] { "calculate.pl?isbn=123498989h",
+ "?isbn=123498989h", "//www.apache.org", "a.html", "#top",
+ "//pc1/", "//user@host/path/file" };
+
+ for (int i = 0; i < absoluteuris.length; i++) {
+ try {
+ new URI(absoluteuris[i]).toURL();
+ } catch (MalformedURLException e) {
+ // not all the URIs can be translated into valid URLs
+ }
+ }
+
+ for (int i = 0; i < relativeuris.length; i++) {
+ try {
+ new URI(relativeuris[i]).toURL();
+ fail("Expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+ URI uri = new URI("http://harmony.apache.org/");
+
+ SerializationTest.verifySelf(uri);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URLDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URLDecoderTest.java
new file mode 100644
index 0000000..f0a8a6d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URLDecoderTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+import junit.framework.TestCase;
+import tests.support.Support_Configuration;
+
+public class URLDecoderTest extends TestCase {
+
+ /**
+ * java.net.URLDecoder#URLDecoder()
+ */
+ public void test_Constructor() throws Exception {
+ URLDecoder ud = new URLDecoder();
+ assertNotNull("Constructor failed.", ud);
+ }
+
+ /**
+ * java.net.URLDecoder#decode(java.lang.String)
+ */
+ public void test_decodeLjava_lang_String() throws Exception {
+ final String URL = "http://" + Support_Configuration.HomeAddress;
+ final String URL2 = "telnet://justWantToHaveFun.com:400";
+ final String URL3 = "file://myServer.org/a file with spaces.jpg";
+ assertTrue("1. Incorrect encoding/decoding", URLDecoder.decode(
+ URLEncoder.encode(URL)).equals(URL));
+ assertTrue("2. Incorrect encoding/decoding", URLDecoder.decode(
+ URLEncoder.encode(URL2)).equals(URL2));
+ assertTrue("3. Incorrect encoding/decoding", URLDecoder.decode(
+ URLEncoder.encode(URL3)).equals(URL3));
+ }
+
+ /**
+ * java.net.URLDecoder#decode(java.lang.String, java.lang.String)
+ */
+ public void test_decodeLjava_lang_String_Ljava_lang_String() {
+ // Regression for HARMONY-467
+ try {
+ URLDecoder.decode("", "");
+ fail("UnsupportedEncodingException expected");
+ } catch (UnsupportedEncodingException e) {
+ // Expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URLTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URLTest.java
new file mode 100644
index 0000000..3502e72
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/URLTest.java
@@ -0,0 +1,1155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.util.ArrayList;
+import java.util.List;
+
+public class URLTest extends TestCase {
+
+ public static class MyHandler extends URLStreamHandler {
+ protected URLConnection openConnection(URL u)
+ throws IOException {
+ return null;
+ }
+ }
+
+ URL u;
+
+ URL u1;
+
+ URL u2;
+
+ URL u3;
+
+ URL u4;
+
+ URL u5;
+
+ URL u6;
+
+ boolean caught = false;
+
+ static boolean isSelectCalled;
+
+ /**
+ * java.net.URL#URL(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws IOException {
+ // Tests for multiple URL instantiation basic parsing test
+ u = new URL(
+ "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1");
+ assertEquals("u returns a wrong protocol", "http", u.getProtocol());
+ assertEquals("u returns a wrong host", "www.yahoo1.com", u.getHost());
+ assertEquals("u returns a wrong port", 8080, u.getPort());
+ assertEquals("u returns a wrong file",
+ "/dir1/dir2/test.cgi?point1.html", u.getFile());
+ assertEquals("u returns a wrong anchor", "anchor1", u.getRef());
+
+ // test for no file
+ u1 = new URL("http://www.yahoo2.com:9999");
+ assertEquals("u1 returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("u1 returns a wrong host", "www.yahoo2.com", u1.getHost());
+ assertEquals("u1 returns a wrong port", 9999, u1.getPort());
+ assertTrue("u1 returns a wrong file", u1.getFile().equals(""));
+ assertNull("u1 returns a wrong anchor", u1.getRef());
+
+ // test for no port
+ u2 = new URL(
+ "http://www.yahoo3.com/dir1/dir2/test.cgi?point1.html#anchor1");
+ assertEquals("u2 returns a wrong protocol", "http", u2.getProtocol());
+ assertEquals("u2 returns a wrong host", "www.yahoo3.com", u2.getHost());
+ assertEquals("u2 returns a wrong port", -1, u2.getPort());
+ assertEquals("u2 returns a wrong file",
+ "/dir1/dir2/test.cgi?point1.html", u2.getFile());
+ assertEquals("u2 returns a wrong anchor", "anchor1", u2.getRef());
+
+ // test for no port
+ URL u2a = new URL("file://www.yahoo3.com/dir1/dir2/test.cgi#anchor1");
+ assertEquals("u2a returns a wrong protocol", "file", u2a.getProtocol());
+ assertEquals("u2a returns a wrong host", "www.yahoo3.com", u2a
+ .getHost());
+ assertEquals("u2a returns a wrong port", -1, u2a.getPort());
+ assertEquals("u2a returns a wrong file", "/dir1/dir2/test.cgi", u2a
+ .getFile());
+ assertEquals("u2a returns a wrong anchor", "anchor1", u2a.getRef());
+
+ // test for no file, no port
+ u3 = new URL("http://www.yahoo4.com/");
+ assertEquals("u3 returns a wrong protocol", "http", u3.getProtocol());
+ assertEquals("u3 returns a wrong host", "www.yahoo4.com", u3.getHost());
+ assertEquals("u3 returns a wrong port", -1, u3.getPort());
+ assertEquals("u3 returns a wrong file", "/", u3.getFile());
+ assertNull("u3 returns a wrong anchor", u3.getRef());
+
+ // test for no file, no port
+ URL u3a = new URL("file://www.yahoo4.com/");
+ assertEquals("u3a returns a wrong protocol", "file", u3a.getProtocol());
+ assertEquals("u3a returns a wrong host", "www.yahoo4.com", u3a
+ .getHost());
+ assertEquals("u3a returns a wrong port", -1, u3a.getPort());
+ assertEquals("u3a returns a wrong file", "/", u3a.getFile());
+ assertNull("u3a returns a wrong anchor", u3a.getRef());
+
+ // test for no file, no port
+ URL u3b = new URL("file://www.yahoo4.com");
+ assertEquals("u3b returns a wrong protocol", "file", u3b.getProtocol());
+ assertEquals("u3b returns a wrong host", "www.yahoo4.com", u3b
+ .getHost());
+ assertEquals("u3b returns a wrong port", -1, u3b.getPort());
+ assertTrue("u3b returns a wrong file", u3b.getFile().equals(""));
+ assertNull("u3b returns a wrong anchor", u3b.getRef());
+
+ // test for non-port ":" and wierd characters occurrences
+ u4 = new URL(
+ "http://www.yahoo5.com/di!@$%^&*()_+r1/di:::r2/test.cgi?point1.html#anchor1");
+ assertEquals("u4 returns a wrong protocol", "http", u4.getProtocol());
+ assertEquals("u4 returns a wrong host", "www.yahoo5.com", u4.getHost());
+ assertEquals("u4 returns a wrong port", -1, u4.getPort());
+ assertEquals("u4 returns a wrong file",
+ "/di!@$%^&*()_+r1/di:::r2/test.cgi?point1.html", u4.getFile());
+ assertEquals("u4 returns a wrong anchor", "anchor1", u4.getRef());
+
+ u5 = new URL("file:/testing.tst");
+ assertEquals("u5 returns a wrong protocol", "file", u5.getProtocol());
+ assertTrue("u5 returns a wrong host", u5.getHost().equals(""));
+ assertEquals("u5 returns a wrong port", -1, u5.getPort());
+ assertEquals("u5 returns a wrong file", "/testing.tst", u5.getFile());
+ assertNull("u5 returns a wrong anchor", u5.getRef());
+
+ URL u5a = new URL("file:testing.tst");
+ assertEquals("u5a returns a wrong protocol", "file", u5a.getProtocol());
+ assertTrue("u5a returns a wrong host", u5a.getHost().equals(""));
+ assertEquals("u5a returns a wrong port", -1, u5a.getPort());
+ assertEquals("u5a returns a wrong file", "testing.tst", u5a.getFile());
+ assertNull("u5a returns a wrong anchor", u5a.getRef());
+
+ URL u6 = new URL("http://host:/file");
+ assertEquals("u6 return a wrong port", -1, u6.getPort());
+
+ URL u7 = new URL("file:../../file.txt");
+ assertTrue("u7 returns a wrong file: " + u7.getFile(), u7.getFile()
+ .equals("../../file.txt"));
+
+ URL u8 = new URL("http://[fec0::1:20d:60ff:fe24:7410]:35/file.txt");
+ assertTrue("u8 returns a wrong protocol " + u8.getProtocol(), u8
+ .getProtocol().equals("http"));
+ assertTrue("u8 returns a wrong host " + u8.getHost(), u8.getHost()
+ .equals("[fec0::1:20d:60ff:fe24:7410]"));
+ assertTrue("u8 returns a wrong port " + u8.getPort(),
+ u8.getPort() == 35);
+ assertTrue("u8 returns a wrong file " + u8.getFile(), u8.getFile()
+ .equals("/file.txt"));
+ assertNull("u8 returns a wrong anchor " + u8.getRef(), u8.getRef());
+
+ URL u9 = new URL("file://[fec0::1:20d:60ff:fe24:7410]/file.txt#sogood");
+ assertTrue("u9 returns a wrong protocol " + u9.getProtocol(), u9
+ .getProtocol().equals("file"));
+ assertTrue("u9 returns a wrong host " + u9.getHost(), u9.getHost()
+ .equals("[fec0::1:20d:60ff:fe24:7410]"));
+ assertTrue("u9 returns a wrong port " + u9.getPort(),
+ u9.getPort() == -1);
+ assertTrue("u9 returns a wrong file " + u9.getFile(), u9.getFile()
+ .equals("/file.txt"));
+ assertTrue("u9 returns a wrong anchor " + u9.getRef(), u9.getRef()
+ .equals("sogood"));
+
+ URL u10 = new URL("file://[fec0::1:20d:60ff:fe24:7410]");
+ assertTrue("u10 returns a wrong protocol " + u10.getProtocol(), u10
+ .getProtocol().equals("file"));
+ assertTrue("u10 returns a wrong host " + u10.getHost(), u10.getHost()
+ .equals("[fec0::1:20d:60ff:fe24:7410]"));
+ assertTrue("u10 returns a wrong port " + u10.getPort(),
+ u10.getPort() == -1);
+
+ URL u11 = new URL("file:////file.txt");
+ // Harmony returned null here
+ assertEquals("u11 returns a wrong authority", "", u11.getAuthority());
+ assertEquals("u11 returns a wrong file " + u11.getFile(), "//file.txt",
+ u11.getFile());
+
+ URL u12 = new URL("file:///file.txt");
+ assertTrue("u12 returns a wrong authority", u12.getAuthority().equals(
+ ""));
+ assertTrue("u12 returns a wrong file " + u12.getFile(), u12.getFile()
+ .equals("/file.txt"));
+
+
+ // test for error catching
+
+ // Bad HTTP format - no "//"
+ u = new URL(
+ "http:www.yahoo5.com::22/dir1/di:::r2/test.cgi?point1.html#anchor1");
+
+ caught = false;
+ try {
+ u = new URL(
+ "http://www.yahoo5.com::22/dir1/di:::r2/test.cgi?point1.html#anchor1");
+ } catch (MalformedURLException e) {
+ caught = true;
+ }
+ assertTrue("Should have throw MalformedURLException", caught);
+
+ // unknown protocol
+ try {
+ u = new URL("myProtocol://www.yahoo.com:22");
+ } catch (MalformedURLException e) {
+ caught = true;
+ }
+ assertTrue("3 Failed to throw MalformedURLException", caught);
+
+ caught = false;
+ // no protocol
+ try {
+ u = new URL("www.yahoo.com");
+ } catch (MalformedURLException e) {
+ caught = true;
+ }
+ assertTrue("4 Failed to throw MalformedURLException", caught);
+
+ caught = false;
+
+ URL u1 = null;
+ try {
+ // No leading or trailing spaces.
+ u1 = new URL("file:/some/path");
+ assertEquals("5 got wrong file length1", 10, u1.getFile().length());
+
+ // Leading spaces.
+ u1 = new URL(" file:/some/path");
+ assertEquals("5 got wrong file length2", 10, u1.getFile().length());
+
+ // Trailing spaces.
+ u1 = new URL("file:/some/path ");
+ assertEquals("5 got wrong file length3", 10, u1.getFile().length());
+
+ // Leading and trailing.
+ u1 = new URL(" file:/some/path ");
+ assertEquals("5 got wrong file length4", 10, u1.getFile().length());
+
+ // in-place spaces.
+ u1 = new URL(" file: /some/path ");
+ assertEquals("5 got wrong file length5", 12, u1.getFile().length());
+
+ } catch (MalformedURLException e) {
+ fail("5 Did not expect the exception " + e);
+ }
+
+ // testing jar protocol with relative path
+ // to make sure it's not canonicalized
+ try {
+ String file = "file:/a!/b/../d";
+
+ u = new URL("jar:" + file);
+ assertEquals("Wrong file (jar protocol, relative path)", file, u
+ .getFile());
+ } catch (MalformedURLException e) {
+ fail("Unexpected exception (jar protocol, relative path)" + e);
+ }
+ }
+
+ /**
+ * java.net.URL#URL(java.net.URL, java.lang.String)
+ */
+ public void test_ConstructorLjava_net_URLLjava_lang_String()
+ throws Exception {
+ // Test for method java.net.URL(java.net.URL, java.lang.String)
+ u = new URL("http://www.yahoo.com");
+ URL uf = new URL("file://www.yahoo.com");
+ // basic ones
+ u1 = new URL(u, "file.java");
+ assertEquals("1 returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("1 returns a wrong host", "www.yahoo.com", u1.getHost());
+ assertEquals("1 returns a wrong port", -1, u1.getPort());
+ assertEquals("1 returns a wrong file", "/file.java", u1.getFile());
+ assertNull("1 returns a wrong anchor", u1.getRef());
+
+ URL u1f = new URL(uf, "file.java");
+ assertEquals("1f returns a wrong protocol", "file", u1f.getProtocol());
+ assertEquals("1f returns a wrong host", "www.yahoo.com", u1f.getHost());
+ assertEquals("1f returns a wrong port", -1, u1f.getPort());
+ assertEquals("1f returns a wrong file", "/file.java", u1f.getFile());
+ assertNull("1f returns a wrong anchor", u1f.getRef());
+
+ u1 = new URL(u, "dir1/dir2/../file.java");
+ assertEquals("3 returns a wrong protocol", "http", u1.getProtocol());
+ assertTrue("3 returns a wrong host: " + u1.getHost(), u1.getHost()
+ .equals("www.yahoo.com"));
+ assertEquals("3 returns a wrong port", -1, u1.getPort());
+ assertEquals("3 returns a wrong file", "/dir1/file.java", u1
+ .getFile());
+ assertNull("3 returns a wrong anchor", u1.getRef());
+
+ u1 = new URL(u, "http:dir1/dir2/../file.java");
+ assertEquals("3a returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("3a returns a wrong host: " + u1.getHost(), "www.yahoo.com", u1.getHost());
+ assertEquals("3a returns a wrong port", -1, u1.getPort());
+ assertEquals("3a returns a wrong file", "/dir1/file.java", u1
+ .getFile());
+ assertNull("3a returns a wrong anchor", u1.getRef());
+
+ u = new URL("http://www.apache.org/testing/");
+ u1 = new URL(u, "file.java");
+ assertEquals("4 returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("4 returns a wrong host", "www.apache.org", u1.getHost());
+ assertEquals("4 returns a wrong port", -1, u1.getPort());
+ assertEquals("4 returns a wrong file", "/testing/file.java", u1
+ .getFile());
+ assertNull("4 returns a wrong anchor", u1.getRef());
+
+ uf = new URL("file://www.apache.org/testing/");
+ u1f = new URL(uf, "file.java");
+ assertEquals("4f returns a wrong protocol", "file", u1f.getProtocol());
+ assertEquals("4f returns a wrong host", "www.apache.org", u1f.getHost());
+ assertEquals("4f returns a wrong port", -1, u1f.getPort());
+ assertEquals("4f returns a wrong file", "/testing/file.java", u1f
+ .getFile());
+ assertNull("4f returns a wrong anchor", u1f.getRef());
+
+ uf = new URL("file:/testing/");
+ u1f = new URL(uf, "file.java");
+ assertEquals("4fa returns a wrong protocol", "file", u1f.getProtocol());
+ assertTrue("4fa returns a wrong host", u1f.getHost().equals(""));
+ assertEquals("4fa returns a wrong port", -1, u1f.getPort());
+ assertEquals("4fa returns a wrong file", "/testing/file.java", u1f
+ .getFile());
+ assertNull("4fa returns a wrong anchor", u1f.getRef());
+
+ uf = new URL("file:testing/");
+ u1f = new URL(uf, "file.java");
+ assertEquals("4fb returns a wrong protocol", "file", u1f.getProtocol());
+ assertTrue("4fb returns a wrong host", u1f.getHost().equals(""));
+ assertEquals("4fb returns a wrong port", -1, u1f.getPort());
+ assertEquals("4fb returns a wrong file", "testing/file.java", u1f
+ .getFile());
+ assertNull("4fb returns a wrong anchor", u1f.getRef());
+
+ u1f = new URL(uf, "file:file.java");
+ assertEquals("4fc returns a wrong protocol", "file", u1f.getProtocol());
+ assertTrue("4fc returns a wrong host", u1f.getHost().equals(""));
+ assertEquals("4fc returns a wrong port", -1, u1f.getPort());
+ assertEquals("4fc returns a wrong file", "testing/file.java", u1f.getFile());
+ assertNull("4fc returns a wrong anchor", u1f.getRef());
+
+ u1f = new URL(uf, "file:");
+ assertEquals("4fd returns a wrong protocol", "file", u1f.getProtocol());
+ assertTrue("4fd returns a wrong host", u1f.getHost().equals(""));
+ assertEquals("4fd returns a wrong port", -1, u1f.getPort());
+ assertEquals("4fd returns a wrong file", "testing/", u1f.getFile());
+ assertNull("4fd returns a wrong anchor", u1f.getRef());
+
+ u = new URL("http://www.apache.org/testing");
+ u1 = new URL(u, "file.java");
+ assertEquals("5 returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("5 returns a wrong host", "www.apache.org", u1.getHost());
+ assertEquals("5 returns a wrong port", -1, u1.getPort());
+ assertEquals("5 returns a wrong file", "/file.java", u1.getFile());
+ assertNull("5 returns a wrong anchor", u1.getRef());
+
+ uf = new URL("file://www.apache.org/testing");
+ u1f = new URL(uf, "file.java");
+ assertEquals("5f returns a wrong protocol", "file", u1f.getProtocol());
+ assertEquals("5f returns a wrong host", "www.apache.org", u1f.getHost());
+ assertEquals("5f returns a wrong port", -1, u1f.getPort());
+ assertEquals("5f returns a wrong file", "/file.java", u1f.getFile());
+ assertNull("5f returns a wrong anchor", u1f.getRef());
+
+ uf = new URL("file:/testing");
+ u1f = new URL(uf, "file.java");
+ assertEquals("5fa returns a wrong protocol", "file", u1f.getProtocol());
+ assertTrue("5fa returns a wrong host", u1f.getHost().equals(""));
+ assertEquals("5fa returns a wrong port", -1, u1f.getPort());
+ assertEquals("5fa returns a wrong file", "/file.java", u1f.getFile());
+ assertNull("5fa returns a wrong anchor", u1f.getRef());
+
+ uf = new URL("file:testing");
+ u1f = new URL(uf, "file.java");
+ assertEquals("5fb returns a wrong protocol", "file", u1f.getProtocol());
+ assertTrue("5fb returns a wrong host", u1f.getHost().equals(""));
+ assertEquals("5fb returns a wrong port", -1, u1f.getPort());
+ assertEquals("5fb returns a wrong file", "file.java", u1f.getFile());
+ assertNull("5fb returns a wrong anchor", u1f.getRef());
+
+ u = new URL("http://www.apache.org/testing/foobaz");
+ u1 = new URL(u, "/file.java");
+ assertEquals("6 returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("6 returns a wrong host", "www.apache.org", u1.getHost());
+ assertEquals("6 returns a wrong port", -1, u1.getPort());
+ assertEquals("6 returns a wrong file", "/file.java", u1.getFile());
+ assertNull("6 returns a wrong anchor", u1.getRef());
+
+ uf = new URL("file://www.apache.org/testing/foobaz");
+ u1f = new URL(uf, "/file.java");
+ assertEquals("6f returns a wrong protocol", "file", u1f.getProtocol());
+ assertEquals("6f returns a wrong host", "www.apache.org", u1f.getHost());
+ assertEquals("6f returns a wrong port", -1, u1f.getPort());
+ assertEquals("6f returns a wrong file", "/file.java", u1f.getFile());
+ assertNull("6f returns a wrong anchor", u1f.getRef());
+
+ u = new URL("http://www.apache.org:8000/testing/foobaz");
+ u1 = new URL(u, "/file.java");
+ assertEquals("7 returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("7 returns a wrong host", "www.apache.org", u1.getHost());
+ assertEquals("7 returns a wrong port", 8000, u1.getPort());
+ assertEquals("7 returns a wrong file", "/file.java", u1.getFile());
+ assertNull("7 returns a wrong anchor", u1.getRef());
+
+ u = new URL("http://www.apache.org/index.html");
+ u1 = new URL(u, "#bar");
+ assertEquals("8 returns a wrong host", "www.apache.org", u1.getHost());
+ assertEquals("8 returns a wrong file", "/index.html", u1.getFile());
+ assertEquals("8 returns a wrong anchor", "bar", u1.getRef());
+
+ u = new URL("http://www.apache.org/index.html#foo");
+ u1 = new URL(u, "http:#bar");
+ assertEquals("9 returns a wrong host", "www.apache.org", u1.getHost());
+ assertEquals("9 returns a wrong file", "/index.html", u1.getFile());
+ assertEquals("9 returns a wrong anchor", "bar", u1.getRef());
+
+ u = new URL("http://www.apache.org/index.html");
+ u1 = new URL(u, "");
+ assertEquals("10 returns a wrong host", "www.apache.org", u1.getHost());
+ assertEquals("10 returns a wrong file", "/index.html", u1.getFile());
+ assertNull("10 returns a wrong anchor", u1.getRef());
+
+ uf = new URL("file://www.apache.org/index.html");
+ u1f = new URL(uf, "");
+ assertEquals("10f returns a wrong host", "www.apache.org", u1.getHost());
+ assertEquals("10f returns a wrong file", "/index.html", u1.getFile());
+ assertNull("10f returns a wrong anchor", u1.getRef());
+
+ u = new URL("http://www.apache.org/index.html");
+ u1 = new URL(u, "http://www.apache.org");
+ assertEquals("11 returns a wrong host", "www.apache.org", u1.getHost());
+ assertTrue("11 returns a wrong file", u1.getFile().equals(""));
+ assertNull("11 returns a wrong anchor", u1.getRef());
+
+ // test for question mark processing
+ u = new URL("http://www.foo.com/d0/d1/d2/cgi-bin?foo=bar/baz");
+
+ // test for relative file and out of bound "/../" processing
+ u1 = new URL(u, "../dir1/./dir2/../file.java");
+ assertTrue("A) returns a wrong file: " + u1.getFile(), u1.getFile()
+ .equals("/d0/d1/dir1/file.java"));
+
+ // test for absolute and relative file processing
+ u1 = new URL(u, "/../dir1/./dir2/../file.java");
+ assertEquals("B) returns a wrong file", "/dir1/file.java",
+ u1.getFile());
+
+ try {
+ // u should raise a MalFormedURLException because u, the context is
+ // null
+ u = null;
+ u1 = new URL(u, "file.java");
+ fail("didn't throw the expected MalFormedURLException");
+ } catch (MalformedURLException e) {
+ // valid
+ }
+
+ // Regression test for HARMONY-3258
+ // testing jar context url with relative file
+ try {
+ // check that relative path with null context is not canonicalized
+ String spec = "jar:file:/a!/b/../d";
+ URL ctx = null;
+ u = new URL(ctx, spec);
+ assertEquals("1 Wrong file (jar protocol, relative path)", spec, u
+ .toString());
+
+ spec = "../d";
+ ctx = new URL("jar:file:/a!/b");
+ u = new URL(ctx, spec);
+ assertEquals("2 Wrong file (jar protocol, relative path)",
+ "file:/a!/d", u.getFile());
+
+ spec = "../d";
+ ctx = new URL("jar:file:/a!/b/c");
+ u = new URL(ctx, spec);
+ assertEquals("3 Wrong file (jar protocol, relative path)",
+ "file:/a!/d", u.getFile());
+
+ spec = "../d";
+ ctx = new URL("jar:file:/a!/b/c/d");
+ u = new URL(ctx, spec);
+ assertEquals("4 Wrong file (jar protocol, relative path)",
+ "file:/a!/b/d", u.getFile());
+
+ // added the real example
+ spec = "../pdf/PDF.settings";
+ ctx = new URL(
+ "jar:file:/C:/Program%20Files/Netbeans-5.5/ide7/modules/org-netbeans-modules-utilities.jar!/org/netbeans/modules/utilities/Layer.xml");
+ u = new URL(ctx, spec);
+ assertEquals(
+ "5 Wrong file (jar protocol, relative path)",
+ "file:/C:/Program%20Files/Netbeans-5.5/ide7/modules/org-netbeans-modules-utilities.jar!/org/netbeans/modules/pdf/PDF.settings",
+ u.getFile());
+ } catch (MalformedURLException e) {
+ fail("Testing jar protocol, relative path failed: " + e);
+ }
+ }
+
+ /**
+ * java.net.URL#URL(java.net.URL, java.lang.String,
+ *java.net.URLStreamHandler)
+ */
+ public void test_ConstructorLjava_net_URLLjava_lang_StringLjava_net_URLStreamHandler()
+ throws Exception {
+ // Test for method java.net.URL(java.net.URL, java.lang.String,
+ // java.net.URLStreamHandler)
+ u = new URL("http://www.yahoo.com");
+ // basic ones
+ u1 = new URL(u, "file.java", new MyHandler());
+ assertEquals("1 returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("1 returns a wrong host", "www.yahoo.com", u1.getHost());
+ assertEquals("1 returns a wrong port", -1, u1.getPort());
+ assertEquals("1 returns a wrong file", "/file.java", u1.getFile());
+ assertNull("1 returns a wrong anchor", u1.getRef());
+
+ u1 = new URL(u, "systemresource:/+/FILE0/test.java", new MyHandler());
+ assertEquals("2 returns a wrong protocol", "systemresource", u1
+ .getProtocol());
+ assertTrue("2 returns a wrong host", u1.getHost().equals(""));
+ assertEquals("2 returns a wrong port", -1, u1.getPort());
+ assertEquals("2 returns a wrong file", "/+/FILE0/test.java", u1
+ .getFile());
+ assertNull("2 returns a wrong anchor", u1.getRef());
+
+ u1 = new URL(u, "dir1/dir2/../file.java", null);
+ assertEquals("3 returns a wrong protocol", "http", u1.getProtocol());
+ assertEquals("3 returns a wrong host", "www.yahoo.com", u1.getHost());
+ assertEquals("3 returns a wrong port", -1, u1.getPort());
+ assertEquals("3 returns a wrong file", "/dir1/file.java", u1
+ .getFile());
+ assertNull("3 returns a wrong anchor", u1.getRef());
+
+ // test for question mark processing
+ u = new URL("http://www.foo.com/d0/d1/d2/cgi-bin?foo=bar/baz");
+
+ // test for relative file and out of bound "/../" processing
+ u1 = new URL(u, "../dir1/dir2/../file.java", new MyHandler());
+ assertTrue("A) returns a wrong file: " + u1.getFile(), u1.getFile()
+ .equals("/d0/d1/dir1/file.java"));
+
+ // test for absolute and relative file processing
+ u1 = new URL(u, "/../dir1/dir2/../file.java", null);
+ assertEquals("B) returns a wrong file", "/dir1/file.java",
+ u1.getFile());
+
+ URL one;
+ try {
+ one = new URL("http://www.ibm.com");
+ } catch (MalformedURLException ex) {
+ // Should not happen.
+ throw new RuntimeException(ex.getMessage());
+ }
+ try {
+ new URL(one, (String) null);
+ fail("Specifying null spec on URL constructor should throw MalformedURLException");
+ } catch (MalformedURLException e) {
+ // expected
+ }
+
+ try {
+ // u should raise a MalFormedURLException because u, the context is
+ // null
+ u = null;
+ u1 = new URL(u, "file.java", new MyHandler());
+ } catch (MalformedURLException e) {
+ return;
+ }
+ fail("didn't throw expected MalFormedURLException");
+ }
+
+ /**
+ * java.net.URL#URL(java.lang.String, java.lang.String,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String()
+ throws MalformedURLException {
+
+ u = new URL("http", "www.yahoo.com", "test.html#foo");
+ assertEquals("http", u.getProtocol());
+ assertEquals("www.yahoo.com", u.getHost());
+ assertEquals(-1, u.getPort());
+ assertEquals("/test.html", u.getFile());
+ assertEquals("foo", u.getRef());
+
+ // Strange behavior in reference, the hostname contains a ':' so it gets
+ // wrapped in '[', ']'
+ URL testURL = new URL("http", "www.apache.org:8080", "test.html#anch");
+ assertEquals("wrong protocol", "http", testURL.getProtocol());
+ assertEquals("wrong host", "[www.apache.org:8080]", testURL.getHost());
+ assertEquals("wrong port", -1, testURL.getPort());
+ assertEquals("wrong file", "/test.html", testURL.getFile());
+ assertEquals("wrong anchor", "anch", testURL.getRef());
+ }
+
+ /**
+ * java.net.URL#URL(java.lang.String, java.lang.String, int,
+ *java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringILjava_lang_String()
+ throws MalformedURLException {
+ u = new URL("http", "www.yahoo.com", 8080, "test.html#foo");
+ assertEquals("SSIS returns a wrong protocol", "http", u.getProtocol());
+ assertEquals("SSIS returns a wrong host", "www.yahoo.com", u.getHost());
+ assertEquals("SSIS returns a wrong port", 8080, u.getPort());
+ // Libcore adds a leading "/"
+ assertEquals("SSIS returns a wrong file", "/test.html", u.getFile());
+ assertTrue("SSIS returns a wrong anchor: " + u.getRef(), u.getRef()
+ .equals("foo"));
+
+ // Regression for HARMONY-83
+ new URL("http", "apache.org", 123456789, "file");
+ try {
+ new URL("http", "apache.org", -123, "file");
+ fail("Assert 0: Negative port should throw exception");
+ } catch (MalformedURLException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * java.net.URL#URL(java.lang.String, java.lang.String, int,
+ *java.lang.String, java.net.URLStreamHandler)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringILjava_lang_StringLjava_net_URLStreamHandler()
+ throws Exception {
+ // Test for method java.net.URL(java.lang.String, java.lang.String, int,
+ // java.lang.String, java.net.URLStreamHandler)
+ u = new URL("http", "www.yahoo.com", 8080, "test.html#foo", null);
+ assertEquals("SSISH1 returns a wrong protocol", "http", u.getProtocol());
+ assertEquals("SSISH1 returns a wrong host", "www.yahoo.com", u
+ .getHost());
+ assertEquals("SSISH1 returns a wrong port", 8080, u.getPort());
+ assertEquals("SSISH1 returns a wrong file", "/test.html", u.getFile());
+ assertTrue("SSISH1 returns a wrong anchor: " + u.getRef(), u.getRef()
+ .equals("foo"));
+
+ u = new URL("http", "www.yahoo.com", 8080, "test.html#foo",
+ new MyHandler());
+ assertEquals("SSISH2 returns a wrong protocol", "http", u.getProtocol());
+ assertEquals("SSISH2 returns a wrong host", "www.yahoo.com", u
+ .getHost());
+ assertEquals("SSISH2 returns a wrong port", 8080, u.getPort());
+ assertEquals("SSISH2 returns a wrong file", "/test.html", u.getFile());
+ assertTrue("SSISH2 returns a wrong anchor: " + u.getRef(), u.getRef()
+ .equals("foo"));
+ }
+
+ /**
+ * java.net.URL#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() throws MalformedURLException {
+ u = new URL("http://www.apache.org:8080/dir::23??????????test.html");
+ u1 = new URL("http://www.apache.org:8080/dir::23??????????test.html");
+ assertTrue("A) equals returns false for two identical URLs", u
+ .equals(u1));
+ assertTrue("return true for null comparison", !u1.equals(null));
+ u = new URL("ftp://www.apache.org:8080/dir::23??????????test.html");
+ assertTrue("Returned true for non-equal URLs", !u.equals(u1));
+
+ // Regression for HARMONY-6556
+ u = new URL("file", null, 0, "/test.txt");
+ u1 = new URL("file", null, 0, "/test.txt");
+ assertEquals(u, u1);
+
+ u = new URL("file", "first.invalid", 0, "/test.txt");
+ u1 = new URL("file", "second.invalid", 0, "/test.txt");
+ assertFalse(u.equals(u1));
+
+ u = new URL("file", "harmony.apache.org", 0, "/test.txt");
+ u1 = new URL("file", "www.apache.org", 0, "/test.txt");
+ assertFalse(u.equals(u1));
+ }
+
+ /**
+ * java.net.URL#sameFile(java.net.URL)
+ */
+ public void test_sameFileLjava_net_URL() throws Exception {
+ // Test for method boolean java.net.URL.sameFile(java.net.URL)
+ u = new URL("http://www.yahoo.com");
+ u1 = new URL("http", "www.yahoo.com", "");
+ assertTrue("Should be the same1", u.sameFile(u1));
+ u = new URL("http://www.yahoo.com/dir1/dir2/test.html#anchor1");
+ u1 = new URL("http://www.yahoo.com/dir1/dir2/test.html#anchor2");
+ assertTrue("Should be the same ", u.sameFile(u1));
+
+ // regression test for Harmony-1040
+ u = new URL("file", null, -1, "/d:/somedir/");
+ u1 = new URL("file:/d:/somedir/");
+ assertFalse(u.sameFile(u1));
+
+ // regression test for Harmony-2136
+ URL url1 = new URL("file:///anyfile");
+ URL url2 = new URL("file://localhost/anyfile");
+ assertTrue(url1.sameFile(url2));
+
+ url1 = new URL("http:///anyfile");
+ url2 = new URL("http://localhost/anyfile");
+ assertFalse(url1.sameFile(url2));
+
+ url1 = new URL("ftp:///anyfile");
+ url2 = new URL("ftp://localhost/anyfile");
+ assertFalse(url1.sameFile(url2));
+
+ url1 = new URL("jar:file:///anyfile.jar!/");
+ url2 = new URL("jar:file://localhost/anyfile.jar!/");
+ assertFalse(url1.sameFile(url2));
+ }
+
+ /**
+ * java.net.URL#getContent()
+ */
+ public void test_getContent() {
+ // Test for method java.lang.Object java.net.URL.getContent()
+ byte[] ba;
+ InputStream is;
+ String s;
+ File resources = Support_Resources.createTempFolder();
+ try {
+ Support_Resources.copyFile(resources, null, "hyts_htmltest.html");
+ u = new URL("file", "", resources.getAbsolutePath()
+ + "/hyts_htmltest.html");
+ u.openConnection();
+ is = (InputStream) u.getContent();
+ is.read(ba = new byte[4096]);
+ s = new String(ba);
+ assertTrue(
+ "Incorrect content "
+ + u
+ + " does not contain: \" A Seemingly Non Important String \"",
+ s.indexOf("A Seemingly Non Important String") >= 0);
+ } catch (IOException e) {
+ fail("IOException thrown : " + e.getMessage());
+ } finally {
+ // Support_Resources.deleteTempFolder(resources);
+ }
+ }
+
+ /**
+ * java.net.URL#getContent(class[])
+ */
+ public void test_getContent_LJavaLangClass() throws Exception {
+ byte[] ba;
+ InputStream is;
+ String s;
+
+ File resources = Support_Resources.createTempFolder();
+
+ Support_Resources.copyFile(resources, null, "hyts_htmltest.html");
+ u = new URL("file", "", resources.getAbsolutePath()
+ + "/hyts_htmltest.html");
+ u.openConnection();
+
+ is = (InputStream) u.getContent(new Class[] { Object.class });
+ is.read(ba = new byte[4096]);
+ s = new String(ba);
+ assertTrue("Incorrect content " + u
+ + " does not contain: \" A Seemingly Non Important String \"",
+ s.indexOf("A Seemingly Non Important String") >= 0);
+
+ }
+
+ /**
+ * java.net.URL#openConnection()
+ */
+ public void test_openConnection() {
+ // Test for method java.net.URLConnection java.net.URL.openConnection()
+ try {
+ u = new URL("systemresource:/FILE4/+/types.properties");
+ URLConnection uConn = u.openConnection();
+ assertNotNull("u.openConnection() returns null", uConn);
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * java.net.URL#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.net.URL.toString()
+ try {
+ u1 = new URL("http://www.yahoo2.com:9999");
+ u = new URL(
+ "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1");
+ assertEquals(
+ "a) Does not return the right url string",
+
+ "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1",
+ u.toString());
+ assertEquals("b) Does not return the right url string",
+ "http://www.yahoo2.com:9999", u1.toString());
+ assertTrue("c) Does not return the right url string", u
+ .equals(new URL(u.toString())));
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * java.net.URL#toExternalForm()
+ */
+ public void test_toExternalForm() {
+ // Test for method java.lang.String java.net.URL.toExternalForm()
+ try {
+ u1 = new URL("http://www.yahoo2.com:9999");
+ u = new URL(
+ "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1");
+ assertEquals(
+ "a) Does not return the right url string",
+
+ "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1",
+ u.toString());
+ assertEquals("b) Does not return the right url string",
+ "http://www.yahoo2.com:9999", u1.toString());
+ assertTrue("c) Does not return the right url string", u
+ .equals(new URL(u.toString())));
+
+ u = new URL("http:index");
+ assertEquals("2 wrong external form", "http:index", u
+ .toExternalForm());
+
+ u = new URL("http", null, "index");
+ assertEquals("2 wrong external form", "http:index", u
+ .toExternalForm());
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * java.net.URL#getFile()
+ */
+ public void test_getFile() throws Exception {
+ // Test for method java.lang.String java.net.URL.getFile()
+ u = new URL("http", "www.yahoo.com:8080", 1233,
+ "test/!@$%^&*/test.html#foo");
+ assertEquals("returns a wrong file", "/test/!@$%^&*/test.html", u
+ .getFile());
+ u = new URL("http", "www.yahoo.com:8080", 1233, "");
+ assertTrue("returns a wrong file", u.getFile().equals(""));
+ }
+
+ /**
+ * java.net.URL#getHost()
+ */
+ public void test_getHost() throws MalformedURLException {
+ // Regression for HARMONY-60
+ String ipv6Host = "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210";
+ URL url = new URL("http", ipv6Host, -1, "myfile");
+ assertEquals(("[" + ipv6Host + "]"), url.getHost());
+ }
+
+ /**
+ * java.net.URL#getPort()
+ */
+ public void test_getPort() throws Exception {
+ // Test for method int java.net.URL.getPort()
+ u = new URL("http://member12.c++.com:9999");
+ assertTrue("return wrong port number " + u.getPort(),
+ u.getPort() == 9999);
+ u = new URL("http://member12.c++.com:9999/");
+ assertEquals("return wrong port number", 9999, u.getPort());
+ }
+
+ /**
+ * @throws MalformedURLException
+ * java.net.URL#getDefaultPort()
+ */
+ public void test_getDefaultPort() throws MalformedURLException {
+ u = new URL("http://member12.c++.com:9999");
+ assertEquals(80, u.getDefaultPort());
+ u = new URL("ftp://member12.c++.com:9999/");
+ assertEquals(21, u.getDefaultPort());
+ }
+
+ /**
+ * java.net.URL#getProtocol()
+ */
+ public void test_getProtocol() throws Exception {
+ // Test for method java.lang.String java.net.URL.getProtocol()
+ u = new URL("http://www.yahoo2.com:9999");
+ assertTrue("u returns a wrong protocol: " + u.getProtocol(), u
+ .getProtocol().equals("http"));
+ }
+
+ /**
+ * java.net.URL#getRef()
+ */
+ public void test_getRef() {
+ // Test for method java.lang.String java.net.URL.getRef()
+ try {
+ u1 = new URL("http://www.yahoo2.com:9999");
+ u = new URL(
+ "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1");
+ assertEquals("returns a wrong anchor1", "anchor1", u.getRef());
+ assertNull("returns a wrong anchor2", u1.getRef());
+ u1 = new URL("http://www.yahoo2.com#ref");
+ assertEquals("returns a wrong anchor3", "ref", u1.getRef());
+ u1 = new URL("http://www.yahoo2.com/file#ref1#ref2");
+ assertEquals("returns a wrong anchor4", "ref1#ref2", u1.getRef());
+ } catch (MalformedURLException e) {
+ fail("Incorrect URL format : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.net.URL#getAuthority()
+ */
+ public void test_getAuthority() throws MalformedURLException {
+ URL testURL = new URL("http", "hostname", 80, "/java?q1#ref");
+ assertEquals("hostname:80", testURL.getAuthority());
+ assertEquals("hostname", testURL.getHost());
+ assertNull(testURL.getUserInfo());
+ assertEquals("/java?q1", testURL.getFile());
+ assertEquals("/java", testURL.getPath());
+ assertEquals("q1", testURL.getQuery());
+ assertEquals("ref", testURL.getRef());
+
+ testURL = new URL("http", "u:p@home", 80, "/java?q1#ref");
+ assertEquals("[u:p@home]:80", testURL.getAuthority());
+ assertEquals("[u:p@home]", testURL.getHost());
+ assertNull(testURL.getUserInfo());
+ assertEquals("/java?q1", testURL.getFile());
+ assertEquals("/java", testURL.getPath());
+ assertEquals("q1", testURL.getQuery());
+ assertEquals("ref", testURL.getRef());
+
+ testURL = new URL("http", "home", -1, "/java");
+ assertEquals("wrong authority2", "home", testURL.getAuthority());
+ assertNull("wrong userInfo2", testURL.getUserInfo());
+ assertEquals("wrong host2", "home", testURL.getHost());
+ assertEquals("wrong file2", "/java", testURL.getFile());
+ assertEquals("wrong path2", "/java", testURL.getPath());
+ assertNull("wrong query2", testURL.getQuery());
+ assertNull("wrong ref2", testURL.getRef());
+ }
+
+ /**
+ * java.net.URL#toURL()
+ */
+ public void test_toURI() throws Exception {
+ u = new URL("http://www.apache.org");
+ URI uri = u.toURI();
+ assertTrue(u.equals(uri.toURL()));
+ }
+
+ /**
+ * java.net.URL#openConnection()
+ */
+ public void test_openConnection_FileProtocal() throws Exception {
+ // Regression test for Harmony-5779
+ String basedir = new File("temp.java").getAbsolutePath();
+ String fileUrlString = "file://localhost/" + basedir;
+ URLConnection conn = new URL(fileUrlString).openConnection();
+ assertEquals("file", conn.getURL().getProtocol());
+ assertEquals(new File(basedir), new File(conn.getURL().getFile()));
+
+ String nonLocalUrlString = "file://anything/" + basedir;
+ conn = new URL(nonLocalUrlString).openConnection();
+ assertEquals("ftp", conn.getURL().getProtocol());
+ assertEquals(new File(basedir), new File(conn.getURL().getFile()));
+ }
+
+ /**
+ * URLStreamHandler implementation class necessary for tests.
+ */
+ private class TestURLStreamHandler extends URLStreamHandler {
+ public URLConnection openConnection(URL arg0) throws IOException {
+ try {
+ return arg0.openConnection();
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ public URLConnection openConnection(URL arg0, Proxy proxy)
+ throws IOException {
+ return super.openConnection(u, proxy);
+ }
+ }
+
+ /**
+ * Check NPE throwing in constructor when protocol argument is null and
+ * URLStreamHandler argument is initialized.
+ */
+ public void test_ConstructorLnullLjava_lang_StringILjava_lang_StringLjava_net_URLStreamHandler()
+ throws Exception {
+ // Regression for HARMONY-1131
+ TestURLStreamHandler lh = new TestURLStreamHandler();
+
+ try {
+ new URL(null, "1", 0, "file", lh);
+ fail("NullPointerException expected, but nothing was thrown!");
+ } catch (NullPointerException e) {
+ // Expected NullPointerException
+ }
+
+ }
+
+ /**
+ * Check NPE throwing in constructor when protocol argument is null and
+ * URLStreamHandler argument is null.
+ */
+ public void test_ConstructorLnullLjava_lang_StringILjava_lang_StringLnull()
+ throws Exception {
+ // Regression for HARMONY-1131
+ try {
+ new URL(null, "1", 0, "file", null);
+ fail("NullPointerException expected, but nothing was thrown!");
+ } catch (NullPointerException e) {
+ // Expected NullPointerException
+ }
+ }
+
+ /**
+ * Check NPE throwing in constructor with 4 params when protocol argument is
+ * null.
+ */
+ public void test_ConstructorLnullLjava_lang_StringILjava_lang_String()
+ throws Exception {
+ // Regression for HARMONY-1131
+ try {
+ new URL(null, "1", 0, "file");
+ fail("NullPointerException expected, but nothing was thrown!");
+ } catch (NullPointerException e) {
+ // Expected NullPointerException
+ }
+ }
+
+ /**
+ * Check NPE throwing in constructor with 3 params when protocol argument is
+ * null.
+ */
+ public void test_ConstructorLnullLjava_lang_StringLjava_lang_String()
+ throws Exception {
+ // Regression for HARMONY-1131
+ try {
+ new URL(null, "1", "file");
+ fail("NullPointerException expected, but nothing was thrown!");
+ } catch (NullPointerException e) {
+ // Expected NullPointerException
+ }
+ }
+
+ public void test_toExternalForm_Absolute() throws MalformedURLException {
+ String strURL = "http://localhost?name=value";
+ URL url = new URL(strURL);
+ assertEquals(strURL, url.toExternalForm());
+
+ strURL = "http://localhost?name=value/age=12";
+ url = new URL(strURL);
+ assertEquals(strURL, url.toExternalForm());
+ }
+
+ public void test_toExternalForm_Relative() throws MalformedURLException {
+ String strURL = "http://a/b/c/d;p?q";
+ String ref = "?y";
+ URL url = new URL(new URL(strURL), ref);
+ assertEquals("http://a/b/c/d;p?y", url.toExternalForm());
+ }
+
+ // Regression test for HARMONY-6254
+
+ // Bogus handler forces file part of URL to be null
+ static class MyHandler2 extends URLStreamHandler {
+
+ @Override
+ protected URLConnection openConnection(URL arg0) throws IOException {
+ return null;
+ }
+
+ @Override
+ protected void setURL(URL u, String protocol, String host, int port,
+ String authority, String userInfo, String file, String query,
+ String ref) {
+ super.setURL(u, protocol, host, port, authority, userInfo,
+ (String) null, query, ref);
+ }
+ }
+
+ // Test special case of external form with null file part (HARMONY-6254)
+ public void test_toExternalForm_Null() throws IOException {
+ URLStreamHandler myHandler = new MyHandler2();
+ URL url = new URL(null, "foobar://example.com/foobar", myHandler);
+ String s = url.toExternalForm();
+ assertEquals("Got wrong URL external form", "foobar://example.com", s);
+ }
+
+ static class MockProxySelector extends ProxySelector {
+
+ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+ System.out.println("connection failed");
+ }
+
+ public List<Proxy> select(URI uri) {
+ isSelectCalled = true;
+ ArrayList<Proxy> proxyList = new ArrayList<Proxy>(1);
+ proxyList.add(Proxy.NO_PROXY);
+ return proxyList;
+ }
+ }
+
+ static class MyURLStreamHandler extends URLStreamHandler {
+
+ @Override
+ protected URLConnection openConnection(URL arg0) throws IOException {
+ return null;
+ }
+
+ public void parse(URL url, String spec, int start, int end) {
+ parseURL(url, spec, start, end);
+ }
+ }
+
+ /**
+ * java.net.URL#URL(String, String, String)
+ */
+ public void test_java_protocol_handler_pkgs_prop()
+ throws MalformedURLException {
+ // Regression test for Harmony-3094
+ final String HANDLER_PKGS = "java.protocol.handler.pkgs";
+ String pkgs = System.getProperty(HANDLER_PKGS);
+ System.setProperty(HANDLER_PKGS,
+ "fake|org.apache.harmony.luni.tests.java.net");
+
+ try {
+ new URL("test_protocol", "", "fake.jar");
+ } finally {
+ if (pkgs == null) {
+ System.clearProperty(HANDLER_PKGS);
+ } else {
+ System.setProperty(HANDLER_PKGS, pkgs);
+ }
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/UnknownHostExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/UnknownHostExceptionTest.java
new file mode 100644
index 0000000..6d881e7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/UnknownHostExceptionTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.UnknownHostException;
+
+import junit.framework.TestCase;
+
+public class UnknownHostExceptionTest extends TestCase {
+
+ /**
+ * java.net.UnknownHostException#UnknownHostException()
+ */
+ public void test_Constructor() {
+ try {
+ if (true) {
+ throw new UnknownHostException();
+ }
+ fail("Failed to generate Exception");
+ } catch (UnknownHostException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.UnknownHostException#UnknownHostException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ try {
+ if (true) {
+ throw new UnknownHostException("test");
+ }
+ fail("Failed to generate Exception");
+ } catch (UnknownHostException e) {
+ assertEquals("Threw exception with incorrect message", "test", e
+ .getMessage());
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/UnknownServiceExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/UnknownServiceExceptionTest.java
new file mode 100644
index 0000000..e141e88
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/UnknownServiceExceptionTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.net;
+
+import java.net.UnknownServiceException;
+
+import junit.framework.TestCase;
+
+public class UnknownServiceExceptionTest extends TestCase {
+
+ /**
+ * java.net.UnknownServiceException#UnknownServiceException()
+ */
+ public void test_Constructor() {
+ try {
+ if (true) {
+ throw new UnknownServiceException();
+ }
+ fail("Exception not thrown");
+ } catch (UnknownServiceException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.net.UnknownServiceException#UnknownServiceException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ try {
+ if (true) {
+ throw new UnknownServiceException("test");
+ }
+ fail("Constructor failed");
+ } catch (UnknownServiceException e) {
+ assertEquals("Wrong exception message", "test", e.getMessage());
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/AbstractBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/AbstractBufferTest.java
new file mode 100644
index 0000000..4da5f8c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/AbstractBufferTest.java
@@ -0,0 +1,306 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.InvalidMarkException;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests a java.nio.Buffer instance.
+ */
+public class AbstractBufferTest extends TestCase {
+
+ protected Buffer baseBuf;
+
+ protected void setUp() throws Exception{
+ super.setUp();
+ baseBuf = ByteBuffer.allocate(10);
+ }
+
+ protected void tearDown() throws Exception{
+ super.tearDown();
+ }
+
+ public void testCapacity() {
+ assertTrue(0 <= baseBuf.position() && baseBuf.position() <= baseBuf.limit()
+ && baseBuf.limit() <= baseBuf.capacity());
+ }
+
+ public void testClear() {
+ // save state
+ int oldPosition = baseBuf.position();
+ int oldLimit = baseBuf.limit();
+
+ Buffer ret = baseBuf.clear();
+ assertSame(ret, baseBuf);
+ assertEquals(baseBuf.position(), 0);
+ assertEquals(baseBuf.limit(), baseBuf.capacity());
+ try {
+ baseBuf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$S
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // restore state
+ baseBuf.limit(oldLimit);
+ baseBuf.position(oldPosition);
+ }
+
+ public void testFlip() {
+ // save state
+ int oldPosition = baseBuf.position();
+ int oldLimit = baseBuf.limit();
+
+ Buffer ret = baseBuf.flip();
+ assertSame(ret, baseBuf);
+ assertEquals(baseBuf.position(), 0);
+ assertEquals(baseBuf.limit(), oldPosition);
+ try {
+ baseBuf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // restore state
+ baseBuf.limit(oldLimit);
+ baseBuf.position(oldPosition);
+ }
+
+ public void testHasRemaining() {
+ // save state
+ int oldPosition = baseBuf.position();
+ int oldLimit = baseBuf.limit();
+
+ assertEquals(baseBuf.hasRemaining(), baseBuf.position() < baseBuf.limit());
+ baseBuf.position(baseBuf.limit());
+ assertFalse(baseBuf.hasRemaining());
+
+ // restore state
+ baseBuf.limit(oldLimit);
+ baseBuf.position(oldPosition);
+ }
+
+ public void testIsReadOnly() {
+ baseBuf.isReadOnly();
+ }
+
+ /*
+ * Class under test for int limit()
+ */
+ public void testLimit() {
+ assertTrue(0 <= baseBuf.position() && baseBuf.position() <= baseBuf.limit()
+ && baseBuf.limit() <= baseBuf.capacity());
+ }
+
+ /*
+ * Class under test for Buffer limit(int)
+ */
+ public void testLimitint() {
+ // save state
+ int oldPosition = baseBuf.position();
+ int oldLimit = baseBuf.limit();
+
+ Buffer ret = baseBuf.limit(baseBuf.limit());
+ assertSame(ret, baseBuf);
+
+ baseBuf.mark();
+ baseBuf.limit(baseBuf.capacity());
+ assertEquals(baseBuf.limit(), baseBuf.capacity());
+ // position should not change
+ assertEquals(baseBuf.position(), oldPosition);
+ // mark should be valid
+ baseBuf.reset();
+
+ if (baseBuf.capacity() > 0) {
+ baseBuf.limit(baseBuf.capacity());
+ baseBuf.position(baseBuf.capacity());
+ baseBuf.mark();
+ baseBuf.limit(baseBuf.capacity() - 1);
+ // position should be the new limit
+ assertEquals(baseBuf.position(), baseBuf.limit());
+ // mark should be invalid
+ try {
+ baseBuf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ try {
+ baseBuf.limit(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ baseBuf.limit(baseBuf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ // restore state
+ baseBuf.limit(oldLimit);
+ baseBuf.position(oldPosition);
+ }
+
+ public void testMark() {
+ // save state
+ int oldPosition = baseBuf.position();
+ int oldLimit = baseBuf.limit();
+
+ Buffer ret = baseBuf.mark();
+ assertSame(ret, baseBuf);
+
+ baseBuf.mark();
+ baseBuf.position(baseBuf.limit());
+ baseBuf.reset();
+ assertEquals(baseBuf.position(), oldPosition);
+
+ baseBuf.mark();
+ baseBuf.position(baseBuf.limit());
+ baseBuf.reset();
+ assertEquals(baseBuf.position(), oldPosition);
+
+ // restore state
+ baseBuf.limit(oldLimit);
+ baseBuf.position(oldPosition);
+ }
+
+ /*
+ * Class under test for int position()
+ */
+ public void testPosition() {
+ assertTrue(0 <= baseBuf.position() && baseBuf.position() <= baseBuf.limit()
+ && baseBuf.limit() <= baseBuf.capacity());
+ }
+
+ /*
+ * Class under test for Buffer position(int)
+ */
+ public void testPositionint() {
+ // save state
+ int oldPosition = baseBuf.position();
+ int oldLimit = baseBuf.limit();
+
+ try {
+ baseBuf.position(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ baseBuf.position(baseBuf.limit() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ baseBuf.mark();
+ baseBuf.position(baseBuf.position());
+ baseBuf.reset();
+ assertEquals(baseBuf.position(), oldPosition);
+
+ baseBuf.position(0);
+ assertEquals(baseBuf.position(), 0);
+ baseBuf.position(baseBuf.limit());
+ assertEquals(baseBuf.position(), baseBuf.limit());
+
+ if (baseBuf.capacity() > 0) {
+ baseBuf.limit(baseBuf.capacity());
+ baseBuf.position(baseBuf.limit());
+ baseBuf.mark();
+ baseBuf.position(baseBuf.limit() - 1);
+ assertEquals(baseBuf.position(), baseBuf.limit() - 1);
+ // mark should be invalid
+ try {
+ baseBuf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ Buffer ret = baseBuf.position(0);
+ assertSame(ret, baseBuf);
+
+ // restore state
+ baseBuf.limit(oldLimit);
+ baseBuf.position(oldPosition);
+ }
+
+ public void testRemaining() {
+ assertEquals(baseBuf.remaining(), baseBuf.limit() - baseBuf.position());
+ }
+
+ public void testReset() {
+ // save state
+ int oldPosition = baseBuf.position();
+ int oldLimit = baseBuf.limit();
+
+ baseBuf.mark();
+ baseBuf.position(baseBuf.limit());
+ baseBuf.reset();
+ assertEquals(baseBuf.position(), oldPosition);
+
+ baseBuf.mark();
+ baseBuf.position(baseBuf.limit());
+ baseBuf.reset();
+ assertEquals(baseBuf.position(), oldPosition);
+
+ Buffer ret = baseBuf.reset();
+ assertSame(ret, baseBuf);
+
+ baseBuf.clear();
+ try {
+ baseBuf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // restore state
+ baseBuf.limit(oldLimit);
+ baseBuf.position(oldPosition);
+ }
+
+ public void testRewind() {
+ // save state
+ int oldPosition = baseBuf.position();
+ int oldLimit = baseBuf.limit();
+
+ Buffer ret = baseBuf.rewind();
+ assertEquals(baseBuf.position(), 0);
+ assertSame(ret, baseBuf);
+ try {
+ baseBuf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // restore state
+ baseBuf.limit(oldLimit);
+ baseBuf.position(oldPosition);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/BufferOverflowExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/BufferOverflowExceptionTest.java
new file mode 100644
index 0000000..234e2e9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/BufferOverflowExceptionTest.java
@@ -0,0 +1,52 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferOverflowException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class BufferOverflowExceptionTest extends TestCase {
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new BufferOverflowException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new BufferOverflowException());
+ }
+
+ /**
+ *@tests {@link java.nio.BufferOverflowException#BufferOverflowException()}
+ */
+ public void test_Constructor() {
+ BufferOverflowException exception = new BufferOverflowException();
+ assertNull(exception.getMessage());
+ assertNull(exception.getLocalizedMessage());
+ assertNull(exception.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/BufferUnderflowExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/BufferUnderflowExceptionTest.java
new file mode 100644
index 0000000..eca02e4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/BufferUnderflowExceptionTest.java
@@ -0,0 +1,55 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferUnderflowException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for BufferUnderflowException
+ */
+public class BufferUnderflowExceptionTest extends TestCase {
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new BufferUnderflowException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new BufferUnderflowException());
+ }
+
+ /**
+ *@tests {@link java.nio.BufferUnderflowException#BufferUnderflowException()}
+ */
+ public void test_Constructor() {
+ BufferUnderflowException exception = new BufferUnderflowException();
+ assertNull(exception.getMessage());
+ assertNull(exception.getLocalizedMessage());
+ assertNull(exception.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java
new file mode 100644
index 0000000..aea177a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java
@@ -0,0 +1,2177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.InvalidMarkException;
+import java.nio.LongBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.nio.ShortBuffer;
+import java.util.Arrays;
+
+/**
+ * Tests java.nio.ByteBuffer
+ *
+ */
+public class ByteBufferTest extends AbstractBufferTest {
+ protected static final int SMALL_TEST_LENGTH = 5;
+ protected static final int BUFFER_LENGTH = 250;
+
+ protected ByteBuffer buf;
+
+ protected void setUp() throws Exception {
+ buf = ByteBuffer.allocate(10);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testArray() {
+ if (buf.hasArray()) {
+ byte array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ } else {
+ if (buf.isReadOnly()) {
+ try {
+ buf.array();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ // expected
+ // Note:can not tell when to throw
+ // UnsupportedOperationException
+ // or ReadOnlyBufferException, so catch all.
+ }
+ } else {
+ try {
+ buf.array();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+ }
+ }
+
+ public void testArrayOffset() {
+ if (buf.hasArray()) {
+ byte array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ } else {
+ if (buf.isReadOnly()) {
+ try {
+ buf.arrayOffset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ // expected
+ // Note:can not tell when to throw
+ // UnsupportedOperationException
+ // or ReadOnlyBufferException, so catch all.
+ }
+ } else {
+ try {
+ buf.arrayOffset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+ }
+ }
+
+ public void testAsReadOnlyBuffer() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // readonly's contents should be the same as buf
+ ByteBuffer readonly = buf.asReadOnlyBuffer();
+ assertNotSame(buf, readonly);
+ assertTrue(readonly.isReadOnly());
+ assertEquals(buf.position(), readonly.position());
+ assertEquals(buf.limit(), readonly.limit());
+ assertEquals(buf.isDirect(), readonly.isDirect());
+ assertEquals(buf.order(), readonly.order());
+ assertContentEquals(buf, readonly);
+
+ // readonly's position, mark, and limit should be independent to buf
+ readonly.reset();
+ assertEquals(readonly.position(), 0);
+ readonly.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+ }
+
+ public void testCompact() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.compact();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ // case: buffer is full
+ buf.clear();
+ buf.mark();
+ loadTestData1(buf);
+ ByteBuffer ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), buf.capacity());
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (byte) 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: buffer is empty
+ buf.position(0);
+ buf.limit(0);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 0);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (byte) 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: normal
+ assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
+ buf.position(1);
+ buf.limit(SMALL_TEST_LENGTH);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 4);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (byte) 1, 4);
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ public void testCompareTo() {
+ // compare to self
+ assertEquals(0, buf.compareTo(buf));
+
+ // normal cases
+ if (!buf.isReadOnly()) {
+ assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
+ buf.clear();
+ ByteBuffer other = ByteBuffer.allocate(buf.capacity());
+ loadTestData1(buf);
+ loadTestData1(other);
+ assertEquals(0, buf.compareTo(other));
+ assertEquals(0, other.compareTo(buf));
+ buf.position(1);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ other.position(2);
+ assertTrue(buf.compareTo(other) < 0);
+ assertTrue(other.compareTo(buf) > 0);
+ buf.position(2);
+ other.limit(SMALL_TEST_LENGTH);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ }
+
+ assertTrue(ByteBuffer.wrap(new byte[21]).compareTo(ByteBuffer.allocateDirect(21)) == 0);
+ }
+
+ public void testDuplicate() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // duplicate's contents should be the same as buf
+ ByteBuffer duplicate = buf.duplicate();
+ assertNotSame(buf, duplicate);
+ assertEquals(buf.position(), duplicate.position());
+ assertEquals(buf.limit(), duplicate.limit());
+ assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
+ assertEquals(buf.isDirect(), duplicate.isDirect());
+ assertEquals(buf.order(), duplicate.order());
+ assertContentEquals(buf, duplicate);
+
+ // duplicate's position, mark, and limit should be independent to buf
+ duplicate.reset();
+ assertEquals(duplicate.position(), 0);
+ duplicate.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+
+ // duplicate share the same content with buf
+ if (!duplicate.isReadOnly()) {
+ loadTestData1(buf);
+ assertContentEquals(buf, duplicate);
+ loadTestData2(duplicate);
+ assertContentEquals(buf, duplicate);
+ }
+ }
+
+ public void testEquals() {
+ // equal to self
+ assertTrue(buf.equals(buf));
+ ByteBuffer readonly = buf.asReadOnlyBuffer();
+ assertTrue(buf.equals(readonly));
+ ByteBuffer duplicate = buf.duplicate();
+ assertTrue(buf.equals(duplicate));
+
+ // always false, if type mismatch
+ assertFalse(buf.equals(Boolean.TRUE));
+
+ assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
+
+ buf.limit(buf.capacity()).position(0);
+ readonly.limit(readonly.capacity()).position(1);
+ assertFalse(buf.equals(readonly));
+
+ buf.limit(buf.capacity() - 1).position(0);
+ duplicate.limit(duplicate.capacity()).position(0);
+ assertFalse(buf.equals(duplicate));
+ }
+
+ /*
+ * Class under test for byte get()
+ */
+ public void testGet() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.ByteBuffer get(byte[])
+ */
+ public void testGetbyteArray() {
+ byte array[] = new byte[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ ByteBuffer ret = buf.get(array);
+ assertEquals(array[0], buf.get(i));
+ assertSame(ret, buf);
+ }
+ try {
+ buf.get(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ try {
+ buf.get((byte[])null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.ByteBuffer get(byte[], int, int)
+ */
+ public void testGetbyteArrayintint() {
+ buf.clear();
+ byte array[] = new byte[buf.capacity()];
+
+ try {
+ buf.get(new byte[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.get(array, array.length, 0);
+ try {
+ buf.get(array, array.length + 1, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get((byte[])null, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+
+ buf.clear();
+ ByteBuffer ret = buf.get(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for byte get(int)
+ */
+ public void testGetint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(buf.limit());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testHasArray() {
+ if (buf.hasArray()) {
+ assertNotNull(buf.array());
+ } else {
+ if (buf.isReadOnly()) {
+ try {
+ buf.array();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ // expected
+ // Note:can not tell when to throw
+ // UnsupportedOperationException
+ // or ReadOnlyBufferException, so catch all.
+ }
+ } else {
+ try {
+ buf.array();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+ }
+ }
+
+ public void testHashCode() {
+ buf.clear();
+ loadTestData1(buf);
+ ByteBuffer readonly = buf.asReadOnlyBuffer();
+ ByteBuffer duplicate = buf.duplicate();
+ assertTrue(buf.hashCode() == readonly.hashCode());
+ assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
+ duplicate.position(buf.capacity()/2);
+ assertTrue(buf.hashCode()!= duplicate.hashCode());
+ }
+
+ //for the testHashCode() method of readonly subclasses
+ protected void readOnlyHashCode() {
+ //create a new buffer initiated with some data
+ ByteBuffer buf = ByteBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ buf.clear();
+ ByteBuffer readonly = buf.asReadOnlyBuffer();
+ ByteBuffer duplicate = buf.duplicate();
+ assertEquals(buf.hashCode(),readonly.hashCode());
+ duplicate.position(buf.capacity()/2);
+ assertTrue(buf.hashCode()!= duplicate.hashCode());
+ }
+
+ public void testIsDirect() {
+ buf.isDirect();
+ }
+
+ public void testOrder() {
+ // BIG_ENDIAN is the default byte order
+ assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
+
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ assertEquals(ByteOrder.LITTLE_ENDIAN, buf.order());
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
+
+ // Regression test for HARMONY-798
+ buf.order((ByteOrder)null);
+ assertEquals(ByteOrder.LITTLE_ENDIAN, buf.order());
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ /*
+ * Class under test for java.nio.ByteBuffer put(byte)
+ */
+ public void testPutbyte() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.clear();
+ buf.put((byte) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ ByteBuffer ret = buf.put((byte) i);
+ assertEquals(buf.get(i), (byte) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put((byte) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.ByteBuffer put(byte[])
+ */
+ public void testPutbyteArray() {
+ byte array[] = new byte[1];
+ if (buf.isReadOnly()) {
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ array[0] = (byte) i;
+ ByteBuffer ret = buf.put(array);
+ assertEquals(buf.get(i), (byte) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.put((byte[])null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.ByteBuffer put(byte[], int, int)
+ */
+ public void testPutbyteArrayintint() {
+ buf.clear();
+ byte array[] = new byte[buf.capacity()];
+ if (buf.isReadOnly()) {
+ try {
+ buf.put(array, 0, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ try {
+ buf.put(new byte[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, array.length + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.put(array, array.length, 0);
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ buf.put(array, 2, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put((byte[])null, 2, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ assertEquals(buf.position(), 0);
+
+ loadTestData2(array, 0, array.length);
+ ByteBuffer ret = buf.put(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.ByteBuffer put(java.nio.ByteBuffer)
+ */
+ public void testPutByteBuffer() {
+ ByteBuffer other = ByteBuffer.allocate(buf.capacity());
+ if (buf.isReadOnly()) {
+ try {
+ buf.clear();
+ buf.put(other);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.clear();
+ buf.put((ByteBuffer)null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ try {
+ buf.put(buf);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ buf.put(ByteBuffer.allocate(buf.capacity() + 1));
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+
+ try {
+ buf.put((ByteBuffer)null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ loadTestData2(other);
+ other.clear();
+ buf.clear();
+ ByteBuffer ret = buf.put(other);
+ assertEquals(other.position(), other.capacity());
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(other, buf);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.ByteBuffer put(int, byte)
+ */
+ public void testPutintbyte() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.put(0, (byte) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), 0);
+ ByteBuffer ret = buf.put(i, (byte) i);
+ assertEquals(buf.get(i), (byte) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(-1, (byte) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(buf.limit(), (byte) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testSlice() {
+ assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
+ buf.position(1);
+ buf.limit(buf.capacity() - 1);
+
+ ByteBuffer slice = buf.slice();
+ assertEquals(buf.isReadOnly(), slice.isReadOnly());
+ assertEquals(buf.isDirect(), slice.isDirect());
+ assertEquals(buf.order(), slice.order());
+ assertEquals(slice.position(), 0);
+ assertEquals(slice.limit(), buf.remaining());
+ assertEquals(slice.capacity(), buf.remaining());
+ try {
+ slice.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // slice share the same content with buf
+ if (!slice.isReadOnly()) {
+ loadTestData1(slice);
+ assertContentLikeTestData1(buf, 1, (byte) 0, slice.capacity());
+ buf.put(2, (byte) 100);
+ assertEquals(slice.get(1), 100);
+ }
+ }
+
+ public void testToString() {
+ String str = buf.toString();
+ assertTrue(str.indexOf("Byte") >= 0 || str.indexOf("byte") >= 0);
+ assertTrue(str.indexOf("" + buf.position()) >= 0);
+ assertTrue(str.indexOf("" + buf.limit()) >= 0);
+ assertTrue(str.indexOf("" + buf.capacity()) >= 0);
+ }
+
+ public void testAsCharBuffer() {
+ CharBuffer charBuffer;
+ byte bytes[] = new byte[2];
+ char value;
+
+ // test BIG_ENDIAN char buffer, read
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ charBuffer = buf.asCharBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, charBuffer.order());
+ while (charBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = charBuffer.get();
+ assertEquals(bytes2char(bytes, buf.order()), value);
+ }
+
+ // test LITTLE_ENDIAN char buffer, read
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ charBuffer = buf.asCharBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, charBuffer.order());
+ while (charBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = charBuffer.get();
+ assertEquals(bytes2char(bytes, buf.order()), value);
+ }
+
+ if (!buf.isReadOnly()) {
+ // test BIG_ENDIAN char buffer, write
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ charBuffer = buf.asCharBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, charBuffer.order());
+ while (charBuffer.remaining() > 0) {
+ value = (char) charBuffer.remaining();
+ charBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, char2bytes(value, buf.order())));
+ }
+
+ // test LITTLE_ENDIAN char buffer, write
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ charBuffer = buf.asCharBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, charBuffer.order());
+ while (charBuffer.remaining() > 0) {
+ value = (char) charBuffer.remaining();
+ charBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, char2bytes(value, buf.order())));
+ }
+ }
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testAsDoubleBuffer() {
+ DoubleBuffer doubleBuffer;
+ byte bytes[] = new byte[8];
+ double value;
+
+ // test BIG_ENDIAN double buffer, read
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ doubleBuffer = buf.asDoubleBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, doubleBuffer.order());
+ while (doubleBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = doubleBuffer.get();
+ if (!(Double.isNaN(bytes2double(bytes, buf.order())) && Double
+ .isNaN(value))) {
+ assertEquals(bytes2double(bytes, buf.order()), value, 0.00);
+ }
+ }
+
+ // test LITTLE_ENDIAN double buffer, read
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ doubleBuffer = buf.asDoubleBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, doubleBuffer.order());
+ while (doubleBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = doubleBuffer.get();
+ if (!(Double.isNaN(bytes2double(bytes, buf.order())) && Double
+ .isNaN(value))) {
+ assertEquals(bytes2double(bytes, buf.order()), value, 0.00);
+ }
+ }
+
+ if (!buf.isReadOnly()) {
+ // test BIG_ENDIAN double buffer, write
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ doubleBuffer = buf.asDoubleBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, doubleBuffer.order());
+ while (doubleBuffer.remaining() > 0) {
+ value = (double) doubleBuffer.remaining();
+ doubleBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, double2bytes(value, buf.order())));
+ }
+
+ // test LITTLE_ENDIAN double buffer, write
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ doubleBuffer = buf.asDoubleBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, doubleBuffer.order());
+ while (doubleBuffer.remaining() > 0) {
+ value = (double) doubleBuffer.remaining();
+ doubleBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, double2bytes(value, buf.order())));
+ }
+ }
+
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testAsFloatBuffer() {
+ FloatBuffer floatBuffer;
+ byte bytes[] = new byte[4];
+ float value;
+
+ // test BIG_ENDIAN float buffer, read
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ floatBuffer = buf.asFloatBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, floatBuffer.order());
+ while (floatBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = floatBuffer.get();
+ if (!(Float.isNaN(bytes2float(bytes, buf.order())) && Float
+ .isNaN(value))) {
+ assertEquals(bytes2float(bytes, buf.order()), value, 0.00);
+ }
+ }
+
+ // test LITTLE_ENDIAN float buffer, read
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ floatBuffer = buf.asFloatBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, floatBuffer.order());
+ while (floatBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = floatBuffer.get();
+ if (!(Float.isNaN(bytes2float(bytes, buf.order())) && Float
+ .isNaN(value))) {
+ assertEquals(bytes2float(bytes, buf.order()), value, 0.00);
+ }
+ }
+
+ if (!buf.isReadOnly()) {
+ // test BIG_ENDIAN float buffer, write
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ floatBuffer = buf.asFloatBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, floatBuffer.order());
+ while (floatBuffer.remaining() > 0) {
+ value = (float) floatBuffer.remaining();
+ floatBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, float2bytes(value, buf.order())));
+ }
+
+ // test LITTLE_ENDIAN float buffer, write
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ floatBuffer = buf.asFloatBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, floatBuffer.order());
+ while (floatBuffer.remaining() > 0) {
+ value = (float) floatBuffer.remaining();
+ floatBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, float2bytes(value, buf.order())));
+ }
+ }
+
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testAsIntBuffer() {
+ IntBuffer intBuffer;
+ byte bytes[] = new byte[4];
+ int value;
+
+ // test BIG_ENDIAN int buffer, read
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ intBuffer = buf.asIntBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, intBuffer.order());
+ while (intBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = intBuffer.get();
+ assertEquals(bytes2int(bytes, buf.order()), value);
+ }
+
+ // test LITTLE_ENDIAN int buffer, read
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ intBuffer = buf.asIntBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, intBuffer.order());
+ while (intBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = intBuffer.get();
+ assertEquals(bytes2int(bytes, buf.order()), value);
+ }
+
+ if (!buf.isReadOnly()) {
+ // test BIG_ENDIAN int buffer, write
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ intBuffer = buf.asIntBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, intBuffer.order());
+ while (intBuffer.remaining() > 0) {
+ value = (int) intBuffer.remaining();
+ intBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, int2bytes(value, buf.order())));
+ }
+
+ // test LITTLE_ENDIAN int buffer, write
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ intBuffer = buf.asIntBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, intBuffer.order());
+ while (intBuffer.remaining() > 0) {
+ value = (int) intBuffer.remaining();
+ intBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, int2bytes(value, buf.order())));
+ }
+ }
+
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testAsLongBuffer() {
+ LongBuffer longBuffer;
+ byte bytes[] = new byte[8];
+ long value;
+
+ // test BIG_ENDIAN long buffer, read
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ longBuffer = buf.asLongBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, longBuffer.order());
+ while (longBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = longBuffer.get();
+ assertEquals(bytes2long(bytes, buf.order()), value);
+ }
+
+ // test LITTLE_ENDIAN long buffer, read
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ longBuffer = buf.asLongBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, longBuffer.order());
+ while (longBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = longBuffer.get();
+ assertEquals(bytes2long(bytes, buf.order()), value);
+ }
+
+ if (!buf.isReadOnly()) {
+ // test BIG_ENDIAN long buffer, write
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ longBuffer = buf.asLongBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, longBuffer.order());
+ while (longBuffer.remaining() > 0) {
+ value = (long) longBuffer.remaining();
+ longBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, long2bytes(value, buf.order())));
+ }
+
+ // test LITTLE_ENDIAN long buffer, write
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ longBuffer = buf.asLongBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, longBuffer.order());
+ while (longBuffer.remaining() > 0) {
+ value = (long) longBuffer.remaining();
+ longBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, long2bytes(value, buf.order())));
+ }
+ }
+
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testAsShortBuffer() {
+ ShortBuffer shortBuffer;
+ byte bytes[] = new byte[2];
+ short value;
+
+ // test BIG_ENDIAN short buffer, read
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ shortBuffer = buf.asShortBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, shortBuffer.order());
+ while (shortBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = shortBuffer.get();
+ assertEquals(bytes2short(bytes, buf.order()), value);
+ }
+
+ // test LITTLE_ENDIAN short buffer, read
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ shortBuffer = buf.asShortBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, shortBuffer.order());
+ while (shortBuffer.remaining() > 0) {
+ buf.get(bytes);
+ value = shortBuffer.get();
+ assertEquals(bytes2short(bytes, buf.order()), value);
+ }
+
+ if (!buf.isReadOnly()) {
+ // test BIG_ENDIAN short buffer, write
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ shortBuffer = buf.asShortBuffer();
+ assertSame(ByteOrder.BIG_ENDIAN, shortBuffer.order());
+ while (shortBuffer.remaining() > 0) {
+ value = (short) shortBuffer.remaining();
+ shortBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, short2bytes(value, buf.order())));
+ }
+
+ // test LITTLE_ENDIAN short buffer, write
+ buf.clear();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ shortBuffer = buf.asShortBuffer();
+ assertSame(ByteOrder.LITTLE_ENDIAN, shortBuffer.order());
+ while (shortBuffer.remaining() > 0) {
+ value = (short) shortBuffer.remaining();
+ shortBuffer.put(value);
+ buf.get(bytes);
+ assertTrue(Arrays.equals(bytes, short2bytes(value, buf.order())));
+ }
+ }
+
+ buf.clear();
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetChar() {
+ int nbytes = 2;
+ byte bytes[] = new byte[nbytes];
+ char value;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ assertEquals(i * nbytes, buf.position());
+ buf.mark();
+ buf.get(bytes);
+ buf.reset();
+ value = buf.getChar();
+ assertEquals(bytes2char(bytes, buf.order()), value);
+ }
+
+ try {
+ buf.getChar();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetCharint() {
+ int nbytes = 2;
+ byte bytes[] = new byte[nbytes];
+ char value;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ buf.position(i);
+ value = buf.getChar(i);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertEquals(bytes2char(bytes, buf.order()), value);
+ }
+
+ try {
+ buf.getChar(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.getChar(buf.limit() - nbytes + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutChar() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.clear();
+ buf.putChar((char) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 2;
+ byte bytes[] = new byte[nbytes];
+ char value = 0;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (char) i;
+ buf.mark();
+ buf.putChar(value);
+ assertEquals((i + 1) * nbytes, buf.position());
+ buf.reset();
+ buf.get(bytes);
+ assertTrue(Arrays.equals(char2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putChar(value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutCharint() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.putChar(0, (char) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 2;
+ byte bytes[] = new byte[nbytes];
+ char value = 0;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (char) i;
+ buf.position(i);
+ buf.putChar(i, value);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertTrue(Arrays.equals(char2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putChar(-1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.putChar(buf.limit() - nbytes + 1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+
+ try {
+ ByteBuffer.allocateDirect(16).putChar(Integer.MAX_VALUE, 'h');
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ public void testGetDouble() {
+ int nbytes = 8;
+ byte bytes[] = new byte[nbytes];
+ double value;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ assertEquals(i * nbytes, buf.position());
+ buf.mark();
+ buf.get(bytes);
+ buf.reset();
+ value = buf.getDouble();
+ if (!(Double.isNaN(bytes2double(bytes, buf.order())) && Double
+ .isNaN(value))) {
+ assertEquals(bytes2double(bytes, buf.order()), value, 0.00);
+ }
+ }
+
+ try {
+ buf.getDouble();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetDoubleint() {
+ int nbytes = 8;
+ byte bytes[] = new byte[nbytes];
+ double value;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ buf.position(i);
+ value = buf.getDouble(i);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ if (!(Double.isNaN(bytes2double(bytes, buf.order())) && Double
+ .isNaN(value))) {
+ assertEquals(bytes2double(bytes, buf.order()), value, 0.00);
+ }
+ }
+
+ try {
+ buf.getDouble(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.getDouble(buf.limit() - nbytes + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+
+ try {
+ ByteBuffer.allocateDirect(16).getDouble(Integer.MAX_VALUE);
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ public void testPutDouble() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.clear();
+ buf.putDouble((double) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 8;
+ byte bytes[] = new byte[nbytes];
+ double value = 0;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (double) i;
+ buf.mark();
+ buf.putDouble(value);
+ assertEquals((i + 1) * nbytes, buf.position());
+ buf.reset();
+ buf.get(bytes);
+ assertTrue(Arrays.equals(double2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putDouble(value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutDoubleint() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.putDouble(0, (double) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 8;
+ byte bytes[] = new byte[nbytes];
+ double value = 0;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (double) i;
+ buf.position(i);
+ buf.putDouble(i, value);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertTrue(Arrays.equals(double2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putDouble(-1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.putDouble(buf.limit() - nbytes + 1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetFloat() {
+ int nbytes = 4;
+ byte bytes[] = new byte[nbytes];
+ float value;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ assertEquals(i * nbytes, buf.position());
+ buf.mark();
+ buf.get(bytes);
+ buf.reset();
+ value = buf.getFloat();
+ if (!(Float.isNaN(bytes2float(bytes, buf.order())) && Float
+ .isNaN(value))) {
+ assertEquals(bytes2float(bytes, buf.order()), value, 0.00);
+ }
+ }
+
+ try {
+ buf.getFloat();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetFloatint() {
+ int nbytes = 4;
+ byte bytes[] = new byte[nbytes];
+ float value;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ buf.position(i);
+ value = buf.getFloat(i);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ if (!(Float.isNaN(bytes2float(bytes, buf.order())) && Float
+ .isNaN(value))) {
+ assertEquals(bytes2float(bytes, buf.order()), value, 0.00);
+ }
+ }
+
+ try {
+ buf.getFloat(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.getFloat(buf.limit() - nbytes + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutFloat() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.clear();
+ buf.putFloat((float) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 4;
+ byte bytes[] = new byte[nbytes];
+ float value = 0;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (float) i;
+ buf.mark();
+ buf.putFloat(value);
+ assertEquals((i + 1) * nbytes, buf.position());
+ buf.reset();
+ buf.get(bytes);
+ assertTrue(Arrays.equals(float2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putFloat(value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutFloatint() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.putFloat(0, (float) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 4;
+ byte bytes[] = new byte[nbytes];
+ float value = 0;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (float) i;
+ buf.position(i);
+ buf.putFloat(i, value);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertTrue(Arrays.equals(float2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putFloat(-1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.putFloat(buf.limit() - nbytes + 1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetInt() {
+ int nbytes = 4;
+ byte bytes[] = new byte[nbytes];
+ int value;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ assertEquals(i * nbytes, buf.position());
+ buf.mark();
+ buf.get(bytes);
+ buf.reset();
+ value = buf.getInt();
+ assertEquals(bytes2int(bytes, buf.order()), value);
+ }
+
+ try {
+ buf.getInt();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetIntint() {
+ int nbytes = 4;
+ byte bytes[] = new byte[nbytes];
+ int value;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ buf.position(i);
+ value = buf.getInt(i);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertEquals(bytes2int(bytes, buf.order()), value);
+ }
+
+ try {
+ buf.getInt(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.getInt(buf.limit() - nbytes + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ try {
+ ByteBuffer.allocateDirect(16).getInt(Integer.MAX_VALUE);
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ public void testPutInt() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.clear();
+ buf.putInt((int) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 4;
+ byte bytes[] = new byte[nbytes];
+ int value = 0;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (int) i;
+ buf.mark();
+ buf.putInt(value);
+ assertEquals((i + 1) * nbytes, buf.position());
+ buf.reset();
+ buf.get(bytes);
+ assertTrue(Arrays.equals(int2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putInt(value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutIntint() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.putInt(0, (int) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 4;
+ byte bytes[] = new byte[nbytes];
+ int value = 0;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (int) i;
+ buf.position(i);
+ buf.putInt(i, value);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertTrue(Arrays.equals(int2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putInt(-1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.putInt(buf.limit() - nbytes + 1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetLong() {
+ int nbytes = 8;
+ byte bytes[] = new byte[nbytes];
+ long value;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ assertEquals(i * nbytes, buf.position());
+ buf.mark();
+ buf.get(bytes);
+ buf.reset();
+ value = buf.getLong();
+ assertEquals(bytes2long(bytes, buf.order()), value);
+ }
+
+ try {
+ buf.getLong();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetLongint() {
+ int nbytes = 8;
+ byte bytes[] = new byte[nbytes];
+ long value;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ buf.position(i);
+ value = buf.getLong(i);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertEquals(bytes2long(bytes, buf.order()), value);
+ }
+
+ try {
+ buf.getLong(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.getLong(buf.limit() - nbytes + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutLong() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.clear();
+ buf.putLong((long) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 8;
+ byte bytes[] = new byte[nbytes];
+ long value = 0;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (long) i;
+ buf.mark();
+ buf.putLong(value);
+ assertEquals((i + 1) * nbytes, buf.position());
+ buf.reset();
+ buf.get(bytes);
+ assertTrue(Arrays.equals(long2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putLong(value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutLongint() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.putLong(0, (long) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 8;
+ byte bytes[] = new byte[nbytes];
+ long value = 0;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (long) i;
+ buf.position(i);
+ buf.putLong(i, value);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertTrue(Arrays.equals(long2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putLong(-1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.putLong(buf.limit() - nbytes + 1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetShort() {
+ int nbytes = 2;
+ byte bytes[] = new byte[nbytes];
+ short value;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ assertEquals(i * nbytes, buf.position());
+ buf.mark();
+ buf.get(bytes);
+ buf.reset();
+ value = buf.getShort();
+ assertEquals(bytes2short(bytes, buf.order()), value);
+ }
+
+ try {
+ buf.getShort();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testGetShortint() {
+ int nbytes = 2;
+ byte bytes[] = new byte[nbytes];
+ short value;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ buf.position(i);
+ value = buf.getShort(i);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertEquals(bytes2short(bytes, buf.order()), value);
+ }
+
+ try {
+ buf.getShort(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.getShort(buf.limit() - nbytes + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutShort() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.clear();
+ buf.putShort((short) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 2;
+ byte bytes[] = new byte[nbytes];
+ short value = 0;
+ buf.clear();
+ for (int i = 0; buf.remaining() >= nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (short) i;
+ buf.mark();
+ buf.putShort(value);
+ assertEquals((i + 1) * nbytes, buf.position());
+ buf.reset();
+ buf.get(bytes);
+ assertTrue(Arrays.equals(short2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putShort(value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public void testPutShortint() {
+ if (buf.isReadOnly()) {
+ try {
+ buf.putShort(0, (short) 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ return;
+ }
+
+ int nbytes = 2;
+ byte bytes[] = new byte[nbytes];
+ short value = 0;
+ buf.clear();
+ for (int i = 0; i <= buf.limit() - nbytes; i++) {
+ buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN);
+ value = (short) i;
+ buf.position(i);
+ buf.putShort(i, value);
+ assertEquals(i, buf.position());
+ buf.get(bytes);
+ assertTrue(Arrays.equals(short2bytes(value, buf.order()), bytes));
+ }
+
+ try {
+ buf.putShort(-1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.putShort(buf.limit() - nbytes + 1, value);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ buf.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ /**
+ * @tests java.nio.ByteBuffer.wrap(byte[],int,int)
+ */
+ public void testWrappedByteBuffer_null_array() {
+ // Regression for HARMONY-264
+ byte array[] = null;
+ try {
+ ByteBuffer.wrap(array, -1, 0);
+ fail("Should throw NPE"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ }
+ try {
+ ByteBuffer.wrap(new byte[10], Integer.MAX_VALUE, 2);
+ fail("Should throw IndexOutOfBoundsException"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ private void loadTestData1(byte array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (byte) i;
+ }
+ }
+
+ private void loadTestData2(byte array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (byte) (length - i);
+ }
+ }
+
+ private void loadTestData1(ByteBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (byte) i);
+ }
+ }
+
+ private void loadTestData2(ByteBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (byte) (buf.capacity() - i));
+ }
+ }
+
+ private void assertContentEquals(ByteBuffer buf, byte array[],
+ int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(i), array[offset + i]);
+ }
+ }
+
+ private void assertContentEquals(ByteBuffer buf, ByteBuffer other) {
+ assertEquals(buf.capacity(), other.capacity());
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.get(i), other.get(i));
+ }
+ }
+
+ private void assertContentLikeTestData1(ByteBuffer buf,
+ int startIndex, byte startValue, int length) {
+ byte value = startValue;
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(startIndex + i), value);
+ value = (byte) (value + 1);
+ }
+ }
+
+ private int bytes2int(byte bytes[], ByteOrder order) {
+ int nbytes = 4, bigHead, step;
+ if (order == ByteOrder.BIG_ENDIAN) {
+ bigHead = 0;
+ step = 1;
+ } else {
+ bigHead = nbytes - 1;
+ step = -1;
+ }
+ int result = 0;
+ int p = bigHead;
+ for (int i = 0; i < nbytes; i++) {
+ result = result << 8;
+ result = result | (bytes[p] & 0xff);
+ p += step;
+ }
+ return result;
+ }
+
+ private long bytes2long(byte bytes[], ByteOrder order) {
+ int nbytes = 8, bigHead, step;
+ if (order == ByteOrder.BIG_ENDIAN) {
+ bigHead = 0;
+ step = 1;
+ } else {
+ bigHead = nbytes - 1;
+ step = -1;
+ }
+ long result = 0;
+ int p = bigHead;
+ for (int i = 0; i < nbytes; i++) {
+ result = result << 8;
+ result = result | (bytes[p] & 0xff);
+ p += step;
+ }
+ return result;
+ }
+
+ private short bytes2short(byte bytes[], ByteOrder order) {
+ int nbytes = 2, bigHead, step;
+ if (order == ByteOrder.BIG_ENDIAN) {
+ bigHead = 0;
+ step = 1;
+ } else {
+ bigHead = nbytes - 1;
+ step = -1;
+ }
+ short result = 0;
+ int p = bigHead;
+ for (int i = 0; i < nbytes; i++) {
+ result = (short) (result << 8);
+ result = (short) (result | (bytes[p] & 0xff));
+ p += step;
+ }
+ return result;
+ }
+
+ private char bytes2char(byte bytes[], ByteOrder order) {
+ return (char) bytes2short(bytes, order);
+ }
+
+ private float bytes2float(byte bytes[], ByteOrder order) {
+ return Float.intBitsToFloat(bytes2int(bytes, order));
+ }
+
+ private double bytes2double(byte bytes[], ByteOrder order) {
+ return Double.longBitsToDouble(bytes2long(bytes, order));
+ }
+
+ private byte[] int2bytes(int value, ByteOrder order) {
+ int nbytes = 4, smallHead, step;
+ if (order == ByteOrder.BIG_ENDIAN) {
+ smallHead = nbytes - 1;
+ step = -1;
+ } else {
+ smallHead = 0;
+ step = 1;
+ }
+ byte bytes[] = new byte[nbytes];
+ int p = smallHead;
+ for (int i = 0; i < nbytes; i++) {
+ bytes[p] = (byte) (value & 0xff);
+ value = value >> 8;
+ p += step;
+ }
+ return bytes;
+ }
+
+ private byte[] long2bytes(long value, ByteOrder order) {
+ int nbytes = 8, smallHead, step;
+ if (order == ByteOrder.BIG_ENDIAN) {
+ smallHead = nbytes - 1;
+ step = -1;
+ } else {
+ smallHead = 0;
+ step = 1;
+ }
+ byte bytes[] = new byte[nbytes];
+ int p = smallHead;
+ for (int i = 0; i < nbytes; i++) {
+ bytes[p] = (byte) (value & 0xff);
+ value = value >> 8;
+ p += step;
+ }
+ return bytes;
+ }
+
+ private byte[] short2bytes(short value, ByteOrder order) {
+ int nbytes = 2, smallHead, step;
+ if (order == ByteOrder.BIG_ENDIAN) {
+ smallHead = nbytes - 1;
+ step = -1;
+ } else {
+ smallHead = 0;
+ step = 1;
+ }
+ byte bytes[] = new byte[nbytes];
+ int p = smallHead;
+ for (int i = 0; i < nbytes; i++) {
+ bytes[p] = (byte) (value & 0xff);
+ value = (short) (value >> 8);
+ p += step;
+ }
+ return bytes;
+ }
+
+ private byte[] char2bytes(char value, ByteOrder order) {
+ return short2bytes((short) value, order);
+ }
+
+ private byte[] float2bytes(float value, ByteOrder order) {
+ return int2bytes(Float.floatToRawIntBits(value), order);
+ }
+
+ private byte[] double2bytes(double value, ByteOrder order) {
+ return long2bytes(Double.doubleToRawLongBits(value), order);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteOrderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteOrderTest.java
new file mode 100644
index 0000000..82b5d7a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteOrderTest.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteOrder;
+
+import junit.framework.TestCase;
+
+/**
+ * Test java.nio.ByteOrder
+ *
+ */
+public class ByteOrderTest extends TestCase {
+
+ public void testToString() {
+ assertEquals(ByteOrder.BIG_ENDIAN.toString(), "BIG_ENDIAN");
+ assertEquals(ByteOrder.LITTLE_ENDIAN.toString(), "LITTLE_ENDIAN");
+ }
+
+ public void testNativeOrder() {
+ ByteOrder o = ByteOrder.nativeOrder();
+ assertTrue(o == ByteOrder.BIG_ENDIAN || o == ByteOrder.LITTLE_ENDIAN);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/CharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/CharBufferTest.java
new file mode 100644
index 0000000..b9f2bc0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/CharBufferTest.java
@@ -0,0 +1,1081 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.io.IOException;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.InvalidMarkException;
+import java.nio.ReadOnlyBufferException;
+
+/**
+ * Tests java.nio.CharBuffer
+ *
+ */
+public class CharBufferTest extends AbstractBufferTest {
+ protected static final int SMALL_TEST_LENGTH = 5;
+
+ protected static final int BUFFER_LENGTH = 20;
+
+ protected CharBuffer buf;
+
+ private static char[] chars = "123456789a".toCharArray();
+
+ protected void setUp() throws Exception{
+ char[] charscopy = new char[chars.length];
+ System.arraycopy(chars, 0, charscopy, 0, chars.length);
+ buf = CharBuffer.wrap(charscopy);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception{
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testArray() {
+ char array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testArrayOffset() {
+ char array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testAsReadOnlyBuffer() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // readonly's contents should be the same as buf
+ CharBuffer readonly = buf.asReadOnlyBuffer();
+ assertNotSame(buf, readonly);
+ assertTrue(readonly.isReadOnly());
+ assertEquals(buf.position(), readonly.position());
+ assertEquals(buf.limit(), readonly.limit());
+ assertEquals(buf.isDirect(), readonly.isDirect());
+ assertEquals(buf.order(), readonly.order());
+ assertEquals(buf.capacity(), readonly.capacity());
+ assertContentEquals(buf, readonly);
+
+ // readonly's position, mark, and limit should be independent to buf
+ readonly.reset();
+ assertEquals(readonly.position(), 0);
+ readonly.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+
+ buf.clear();
+ int originalPosition = (buf.position() + buf.limit()) / 2;
+ buf.position(originalPosition);
+ buf.mark();
+ buf.position(buf.limit());
+
+ // readonly's contents should be the same as buf
+ readonly = buf.asReadOnlyBuffer();
+ assertNotSame(buf, readonly);
+ assertTrue(readonly.isReadOnly());
+ assertEquals(buf.position(), readonly.position());
+ assertEquals(buf.limit(), readonly.limit());
+ assertEquals(buf.isDirect(), readonly.isDirect());
+ assertEquals(buf.order(), readonly.order());
+ assertEquals(buf.capacity(), readonly.capacity());
+ assertContentEquals(buf, readonly);
+
+ // readonly's position, mark, and limit should be independent to buf
+ readonly.reset();
+ assertEquals(readonly.position(), originalPosition);
+ readonly.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), originalPosition);
+ }
+
+ public void testCompact() {
+ // case: buffer is full
+ buf.clear();
+ buf.mark();
+ loadTestData1(buf);
+ CharBuffer ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), buf.capacity());
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (char) 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: buffer is empty
+ buf.position(0);
+ buf.limit(0);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 0);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (char) 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: normal
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(5);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 4);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (char) 1, 4);
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ public void testCompareTo() {
+ // compare to self
+ assertEquals(0, buf.compareTo(buf));
+
+ assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
+ buf.clear();
+ CharBuffer other = CharBuffer.allocate(buf.capacity());
+ other.put(buf);
+ other.clear();
+ buf.clear();
+ assertEquals(0, buf.compareTo(other));
+ assertEquals(0, other.compareTo(buf));
+ buf.position(1);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ other.position(2);
+ assertTrue(buf.compareTo(other) < 0);
+ assertTrue(other.compareTo(buf) > 0);
+ buf.position(2);
+ assertTrue(buf.compareTo(other) == 0);
+ assertTrue(other.compareTo(buf) == 0);
+ other.limit(SMALL_TEST_LENGTH);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ }
+
+ public void testDuplicate() {
+ // mark the position 0
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // duplicate's contents should be the same as buf
+ CharBuffer duplicate = buf.duplicate();
+ assertNotSame(buf, duplicate);
+ assertEquals(buf.position(), duplicate.position());
+ assertEquals(buf.limit(), duplicate.limit());
+ assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
+ assertEquals(buf.isDirect(), duplicate.isDirect());
+ assertEquals(buf.order(), duplicate.order());
+ assertEquals(buf.capacity(), duplicate.capacity());
+ assertContentEquals(buf, duplicate);
+
+ // duplicate's position, mark, and limit should be independent to
+ // buf
+ duplicate.reset();
+ assertEquals(duplicate.position(), 0);
+ duplicate.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+
+ // mark another position
+ buf.clear();
+ int originalPosition = (buf.position() + buf.limit()) / 2;
+ buf.position(originalPosition);
+ buf.mark();
+ buf.position(buf.limit());
+
+ // duplicate's contents should be the same as buf
+ duplicate = buf.duplicate();
+ assertNotSame(buf, duplicate);
+ assertEquals(buf.position(), duplicate.position());
+ assertEquals(buf.limit(), duplicate.limit());
+ assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
+ assertEquals(buf.isDirect(), duplicate.isDirect());
+ assertEquals(buf.order(), duplicate.order());
+ assertEquals(buf.capacity(), duplicate.capacity());
+ assertContentEquals(buf, duplicate);
+
+ // duplicate's position, mark, and limit should be independent to
+ // buf
+ duplicate.reset();
+ assertEquals(duplicate.position(), originalPosition);
+ duplicate.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), originalPosition);
+
+ // duplicate share the same content with buf
+ if (!duplicate.isReadOnly()) {
+ loadTestData1(buf);
+ assertContentEquals(buf, duplicate);
+ loadTestData2(duplicate);
+ assertContentEquals(buf, duplicate);
+ }
+ }
+
+ public void testEquals() {
+ // equal to self
+ assertTrue(buf.equals(buf));
+ CharBuffer readonly = buf.asReadOnlyBuffer();
+ assertTrue(buf.equals(readonly));
+ CharBuffer duplicate = buf.duplicate();
+ assertTrue(buf.equals(duplicate));
+
+ // always false, if type mismatch
+ assertFalse(buf.equals(Boolean.TRUE));
+
+ assertTrue(buf.capacity() > 5);
+
+ buf.limit(buf.capacity()).position(0);
+ readonly.limit(readonly.capacity()).position(1);
+ assertFalse(buf.equals(readonly));
+
+ buf.limit(buf.capacity() - 1).position(0);
+ duplicate.limit(duplicate.capacity()).position(0);
+ assertFalse(buf.equals(duplicate));
+ }
+
+ /*
+ * Class under test for char get()
+ */
+ public void testGet() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.CharBuffer get(char[])
+ */
+ public void testGetcharArray() {
+ char array[] = new char[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ CharBuffer ret = buf.get(array);
+ assertEquals(array[0], buf.get(i));
+ assertSame(ret, buf);
+ }
+ try {
+ buf.get(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.CharBuffer get(char[], int, int)
+ */
+ public void testGetcharArrayintint() {
+ buf.clear();
+ char array[] = new char[buf.capacity()];
+
+ try {
+ buf.get(new char[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.get(array, array.length, 0);
+ try {
+ buf.get(array, array.length + 1, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get((char[])null, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ buf.get(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+
+ buf.clear();
+ CharBuffer ret = buf.get(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for char get(int)
+ */
+ public void testGetint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(buf.limit());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testHashCode() {
+ buf.clear();
+ loadTestData1(buf);
+ CharBuffer readonly = buf.asReadOnlyBuffer();
+ CharBuffer duplicate = buf.duplicate();
+ assertTrue(buf.hashCode() == readonly.hashCode());
+ assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
+ duplicate.position(buf.capacity() / 2);
+ assertTrue(buf.hashCode() != duplicate.hashCode());
+ }
+
+ /*
+ * Class under test for java.nio.CharBuffer put(char)
+ */
+ public void testPutchar() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ CharBuffer ret = buf.put((char) i);
+ assertEquals(buf.get(i), (char) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put((char) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.CharBuffer put(char[])
+ */
+ public void testPutcharArray() {
+ char array[] = new char[1];
+
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ array[0] = (char) i;
+ CharBuffer ret = buf.put(array);
+ assertEquals(buf.get(i), (char) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.put((char[]) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.CharBuffer put(char[], int, int)
+ */
+ public void testPutcharArrayintint() {
+ buf.clear();
+ char array[] = new char[buf.capacity()];
+ try {
+ buf.put((char[]) null, 0, 1);
+ fail("Should throw NullPointerException"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.put(new char[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, array.length + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.put(array, array.length, 0);
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put((char[])null, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ assertEquals(buf.position(), 0);
+
+ loadTestData2(array, 0, array.length);
+ CharBuffer ret = buf.put(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.CharBuffer put(java.nio.CharBuffer)
+ */
+ public void testPutCharBuffer() {
+ CharBuffer other = CharBuffer.allocate(buf.capacity());
+
+ try {
+ buf.put((CharBuffer) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.put(buf);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ buf.put(CharBuffer.allocate(buf.capacity() + 1));
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.flip();
+ buf.put((CharBuffer)null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ loadTestData2(other);
+ other.clear();
+ buf.clear();
+ CharBuffer ret = buf.put(other);
+ assertEquals(other.position(), other.capacity());
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(other, buf);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.CharBuffer put(int, char)
+ */
+ public void testPutintchar() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), 0);
+ CharBuffer ret = buf.put(i, (char) i);
+ assertEquals(buf.get(i), (char) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(-1, (char) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(buf.limit(), (char) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testSlice() {
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(buf.capacity() - 1);
+
+ CharBuffer slice = buf.slice();
+ assertEquals(buf.isReadOnly(), slice.isReadOnly());
+ assertEquals(buf.isDirect(), slice.isDirect());
+ assertEquals(buf.order(), slice.order());
+ assertEquals(slice.position(), 0);
+ assertEquals(slice.limit(), buf.remaining());
+ assertEquals(slice.capacity(), buf.remaining());
+ try {
+ slice.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // slice share the same content with buf
+ if (!slice.isReadOnly()) {
+ loadTestData1(slice);
+ assertContentLikeTestData1(buf, 1, (char) 0, slice.capacity());
+ buf.put(2, (char) 500);
+ assertEquals(slice.get(1), 500);
+ }
+ }
+
+ public void testToString() {
+ String expected = "";
+ for (int i = buf.position(); i < buf.limit(); i++) {
+ expected += buf.get(i);
+ }
+ String str = buf.toString();
+ assertEquals(expected, str);
+ }
+
+ public void testCharAt() {
+ for (int i = 0; i < buf.remaining(); i++) {
+ assertEquals(buf.get(buf.position() + i), buf.charAt(i));
+ }
+ try {
+ buf.charAt(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.charAt(buf.remaining());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testLength() {
+ assertEquals(buf.length(), buf.remaining());
+ }
+
+ public void testSubSequence() {
+ try {
+ buf.subSequence(-1, buf.length());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.subSequence(buf.length() + 1, buf.length() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.subSequence(buf.length(), buf.length()).length(), 0);
+ try {
+ buf.subSequence(1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.subSequence(1, buf.length() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ assertEquals(buf.subSequence(0, buf.length()).toString(), buf
+ .toString());
+
+ if (buf.length() >= 2) {
+ assertEquals(buf.subSequence(1, buf.length() - 1).toString(), buf
+ .toString().substring(1, buf.length() - 1));
+ }
+ }
+
+ public void testPutString() {
+ String str = " ";
+
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ str = "" + (char) i;
+ CharBuffer ret = buf.put(str);
+ assertEquals(buf.get(i), (char) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(str);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.put((String) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPutStringintint() {
+ buf.clear();
+ String str = String.valueOf(new char[buf.capacity()]);
+
+ // Throw a BufferOverflowException and no character is transfered to
+ // CharBuffer
+ try {
+ buf.put(String.valueOf(new char[buf.capacity() + 1]), 0, buf
+ .capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.put((String) null, 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ assertEquals(0, buf.position());
+
+ buf.clear();
+ try {
+ buf.put(str, -1, str.length());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(str, str.length() + 1, str.length() + 2);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put((String) null, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ buf.put(str, str.length(), str.length());
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(str, 2, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(str, 2, str.length() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+
+ char array[] = new char[buf.capacity()];
+ loadTestData2(array, 0, array.length);
+ str = String.valueOf(array);
+
+ CharBuffer ret = buf.put(str, 0, str.length());
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, str.toCharArray(), 0, str.length());
+ assertSame(ret, buf);
+ }
+
+ void loadTestData1(char array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (char) i;
+ }
+ }
+
+ void loadTestData2(char array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (char) (length - i);
+ }
+ }
+
+ void loadTestData1(CharBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (char) i);
+ }
+ }
+
+ void loadTestData2(CharBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (char) (buf.capacity() - i));
+ }
+ }
+
+ private void assertContentEquals(CharBuffer buf, char array[], int offset,
+ int length) {
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(i), array[offset + i]);
+ }
+ }
+
+ private void assertContentEquals(CharBuffer buf, CharBuffer other) {
+ assertEquals(buf.capacity(), other.capacity());
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.get(i), other.get(i));
+ }
+ }
+
+ private void assertContentLikeTestData1(CharBuffer buf, int startIndex,
+ char startValue, int length) {
+ char value = startValue;
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(startIndex + i), value);
+ value = (char) (value + 1);
+ }
+ }
+
+ public void testAppendSelf() throws Exception {
+ CharBuffer cb = CharBuffer.allocate(10);
+ CharBuffer cb2 = cb.duplicate();
+ cb.append(cb);
+ assertEquals(10, cb.position());
+ cb.clear();
+ assertEquals(cb2, cb);
+
+ cb.put("abc");
+ cb2 = cb.duplicate();
+ cb.append(cb);
+ assertEquals(10, cb.position());
+ cb.clear();
+ cb2.clear();
+ assertEquals(cb2, cb);
+
+ cb.put("edfg");
+ cb.clear();
+ cb2 = cb.duplicate();
+ cb.append(cb);
+ assertEquals(10, cb.position());
+ cb.clear();
+ cb2.clear();
+ assertEquals(cb, cb2);
+ }
+
+ public void testAppendOverFlow() throws IOException {
+ CharBuffer cb = CharBuffer.allocate(1);
+ CharSequence cs = "String";
+ cb.put('A');
+ try {
+ cb.append('C');
+ fail("should throw BufferOverflowException.");
+ } catch (BufferOverflowException ex) {
+ // expected;
+ }
+ try {
+ cb.append(cs);
+ fail("should throw BufferOverflowException.");
+ } catch (BufferOverflowException ex) {
+ // expected;
+ }
+ try {
+ cb.append(cs, 1, 2);
+ fail("should throw BufferOverflowException.");
+ } catch (BufferOverflowException ex) {
+ // expected;
+ }
+ }
+
+ public void testReadOnlyMap() throws IOException {
+ CharBuffer cb = CharBuffer.wrap("ABCDE").asReadOnlyBuffer();
+ CharSequence cs = "String";
+ try {
+ cb.append('A');
+ fail("should throw ReadOnlyBufferException.");
+ } catch (ReadOnlyBufferException ex) {
+ // expected;
+ }
+ try {
+ cb.append(cs);
+ fail("should throw ReadOnlyBufferException.");
+ } catch (ReadOnlyBufferException ex) {
+ // expected;
+ }
+ try {
+ cb.append(cs, 1, 2);
+ fail("should throw ReadOnlyBufferException.");
+ } catch (ReadOnlyBufferException ex) {
+ // expected;
+ }
+ cb.append(cs, 1, 1);
+ }
+
+ public void testAppendCNormal() throws IOException {
+ CharBuffer cb = CharBuffer.allocate(2);
+ cb.put('A');
+ assertSame(cb, cb.append('B'));
+ assertEquals('B', cb.get(1));
+ }
+
+ public void testAppendCharSequenceNormal() throws IOException {
+ CharBuffer cb = CharBuffer.allocate(10);
+ cb.put('A');
+ assertSame(cb, cb.append("String"));
+ assertEquals("AString", cb.flip().toString());
+ cb.append(null);
+ assertEquals("null", cb.flip().toString());
+ }
+
+ public void testAppendCharSequenceIINormal() throws IOException {
+ CharBuffer cb = CharBuffer.allocate(10);
+ cb.put('A');
+ assertSame(cb, cb.append("String", 1, 3));
+ assertEquals("Atr", cb.flip().toString());
+
+ cb.append(null, 0, 1);
+ assertEquals("n", cb.flip().toString());
+ }
+
+ public void testAppendCharSequenceII_IllegalArgument() throws IOException {
+ CharBuffer cb = CharBuffer.allocate(10);
+ cb.append("String", 0, 0);
+ cb.append("String", 2, 2);
+ try {
+ cb.append("String", -1, 1);
+ fail("should throw IndexOutOfBoundsException.");
+ } catch (IndexOutOfBoundsException ex) {
+ // expected;
+ }
+ try {
+ cb.append("String", -1, -1);
+ fail("should throw IndexOutOfBoundsException.");
+ } catch (IndexOutOfBoundsException ex) {
+ // expected;
+ }
+ try {
+ cb.append("String", 3, 2);
+ fail("should throw IndexOutOfBoundsException.");
+ } catch (IndexOutOfBoundsException ex) {
+ // expected;
+ }
+ try {
+ cb.append("String", 3, 0);
+ fail("should throw IndexOutOfBoundsException.");
+ } catch (IndexOutOfBoundsException ex) {
+ // expected;
+ }
+ try {
+ cb.append("String", 3, 110);
+ fail("should throw IndexOutOfBoundsException.");
+ } catch (IndexOutOfBoundsException ex) {
+ // expected;
+ }
+ }
+
+ public void testReadCharBuffer() throws IOException {
+ CharBuffer source = CharBuffer.wrap("String");
+ CharBuffer target = CharBuffer.allocate(10);
+ assertEquals(6, source.read(target));
+ assertEquals("String", target.flip().toString());
+ // return -1 when nothing to read
+ assertEquals(-1, source.read(target));
+ // NullPointerException
+ try {
+ assertEquals(-1, source.read(null));
+ fail("should throw NullPointerException.");
+ } catch (NullPointerException ex) {
+ // expected;
+ }
+
+ }
+
+ public void testReadReadOnly() throws IOException {
+ CharBuffer source = CharBuffer.wrap("String");
+ CharBuffer target = CharBuffer.allocate(10).asReadOnlyBuffer();
+ try {
+ source.read(target);
+ fail("should throw ReadOnlyBufferException.");
+ } catch (ReadOnlyBufferException ex) {
+ // expected;
+ }
+ // if target has no remaining, needn't to check the isReadOnly
+ target.flip();
+ assertEquals(0, source.read(target));
+ }
+
+ public void testReadOverflow() throws IOException {
+ CharBuffer source = CharBuffer.wrap("String");
+ CharBuffer target = CharBuffer.allocate(1);
+ assertEquals(1, source.read(target));
+ assertEquals("S", target.flip().toString());
+ assertEquals(1, source.position());
+ }
+
+ public void testReadSelf() throws Exception {
+ CharBuffer source = CharBuffer.wrap("abuffer");
+ try {
+ source.read(source);
+ fail("should throw IAE.");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ public void testRead_scenario1() throws Exception {
+ char[] charArray = new char[] { 'a', 'b' };
+ CharBuffer charBuffer = CharBuffer.wrap(charArray);
+ try {
+ charBuffer.read(charBuffer);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ charBuffer.put(charArray);
+ assertEquals(-1, charBuffer.read(charBuffer));
+ }
+
+ public void testRead_scenario2() throws Exception {
+ CharBuffer charBufferA = CharBuffer.allocate(0);
+ CharBuffer allocateBuffer = CharBuffer.allocate(1);
+ CharBuffer charBufferB = CharBuffer.wrap(allocateBuffer);
+ assertEquals(-1, charBufferA.read(charBufferB));
+
+ allocateBuffer.append(allocateBuffer);
+ charBufferB = CharBuffer.wrap(allocateBuffer);
+ assertEquals(-1, charBufferA.read(charBufferB));
+ }
+
+ public void testIsDirect() {
+ assertFalse(buf.isDirect());
+ }
+
+ public void testHasArray() {
+ assertTrue(buf.hasArray());
+ }
+
+ public void testOrder() {
+ assertEquals(ByteOrder.nativeOrder(), buf.order());
+ }
+
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java
new file mode 100644
index 0000000..ffdfb2c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java
@@ -0,0 +1,60 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+
+public class DirectByteBufferTest extends ByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = ByteBuffer.allocateDirect(BUFFER_LENGTH);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ /**
+ * @tests java.nio.ByteBuffer#allocateDirect(int)
+ *
+ */
+ public void testAllocatedByteBuffer_IllegalArg() {
+ try {
+ ByteBuffer.allocateDirect(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testIsDirect() {
+ assertTrue(buf.isDirect());
+ }
+
+ public void testHasArray() {
+ // Android direct byte buffers have backing arrays.
+ assertTrue(buf.hasArray());
+ // assertFalse(buf.hasArray());
+ }
+
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectCharBufferTest.java
new file mode 100644
index 0000000..71957c1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectCharBufferTest.java
@@ -0,0 +1,61 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class DirectCharBufferTest extends CharBufferTest {
+
+ public void setUp(){
+ buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*2).asCharBuffer();
+ super.loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ public void tearDown(){
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testIsDirect() {
+ assertTrue(buf.isDirect());
+ }
+
+ public void testOrder() {
+ assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectDoubleBufferTest.java
new file mode 100644
index 0000000..0a14a44
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectDoubleBufferTest.java
@@ -0,0 +1,60 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class DirectDoubleBufferTest extends DoubleBufferTest {
+ public void setUp(){
+ buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*8).asDoubleBuffer();
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ public void tearDown(){
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testIsDirect() {
+ assertTrue(buf.isDirect());
+ }
+
+ public void testOrder() {
+ assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectFloatBufferTest.java
new file mode 100644
index 0000000..e74eb47
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectFloatBufferTest.java
@@ -0,0 +1,61 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class DirectFloatBufferTest extends FloatBufferTest {
+ public void setUp(){
+ buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*4).asFloatBuffer();
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ public void tearDown(){
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void testIsDirect() {
+ assertTrue(buf.isDirect());
+ }
+
+ public void testOrder() {
+ assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectIntBufferTest.java
new file mode 100644
index 0000000..e556a31
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectIntBufferTest.java
@@ -0,0 +1,61 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class DirectIntBufferTest extends IntBufferTest {
+ public void setUp(){
+ buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*4).asIntBuffer();
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ public void tearDown(){
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void testIsDirect() {
+ assertTrue(buf.isDirect());
+ }
+
+ public void testOrder() {
+ assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectLongBufferTest.java
new file mode 100644
index 0000000..df1ade5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectLongBufferTest.java
@@ -0,0 +1,62 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+
+public class DirectLongBufferTest extends LongBufferTest {
+ public void setUp(){
+ buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*8).asLongBuffer();
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ public void tearDown(){
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void testIsDirect() {
+ assertTrue(buf.isDirect());
+ }
+
+ public void testOrder() {
+ assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectShortBufferTest.java
new file mode 100644
index 0000000..c5ba915
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectShortBufferTest.java
@@ -0,0 +1,61 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class DirectShortBufferTest extends ShortBufferTest {
+ public void setUp(){
+ buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*2).asShortBuffer();
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ public void tearDown(){
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void testIsDirect() {
+ assertTrue(buf.isDirect());
+ }
+
+ public void testOrder() {
+ assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java
new file mode 100644
index 0000000..50e0b82
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java
@@ -0,0 +1,664 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.DoubleBuffer;
+import java.nio.InvalidMarkException;
+
+/**
+ * Tests java.nio.DoubleBuffer
+ */
+public class DoubleBufferTest extends AbstractBufferTest {
+
+ protected static final int SMALL_TEST_LENGTH = 5;
+
+ protected static final int BUFFER_LENGTH = 20;
+
+ protected DoubleBuffer buf;
+
+ protected void setUp() throws Exception {
+ buf = DoubleBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ buf = null;
+ baseBuf = null;
+ }
+
+ /*
+ * Test with bit sequences that represent the IEEE754 doubles Positive
+ * infinity, negative infinity, and NaN.
+ */
+ public void testNaNs() {
+ long[] nans = new long[] { 0x7ff0000000000000L, 0xfff0000000000000L,
+ 0x7ff8000000000000L };
+ for (int i = 0; i < nans.length; i++) {
+ long longBitsIn = nans[i];
+ double dbl = Double.longBitsToDouble(longBitsIn);
+ long longBitsOut = Double.doubleToRawLongBits(dbl);
+ // Sanity check
+ assertTrue(longBitsIn == longBitsOut);
+
+ // Store the double and retrieve it
+ ByteBuffer buffer = ByteBuffer.allocate(8);
+ buffer.putDouble(dbl);
+ double bufDoubleOut = buffer.getDouble(0);
+
+ // Check the bits sequence was not normalized
+ long bufLongOut = Double.doubleToRawLongBits(bufDoubleOut);
+ assertTrue(longBitsIn == bufLongOut);
+ }
+ }
+
+ public void testArray() {
+ double array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testArrayOffset() {
+ double array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testAsReadOnlyBuffer() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // readonly's contents should be the same as buf
+ DoubleBuffer readonly = buf.asReadOnlyBuffer();
+ assertNotSame(buf, readonly);
+ assertTrue(readonly.isReadOnly());
+ assertEquals(buf.position(), readonly.position());
+ assertEquals(buf.limit(), readonly.limit());
+ assertEquals(buf.isDirect(), readonly.isDirect());
+ assertEquals(buf.order(), readonly.order());
+ assertContentEquals(buf, readonly);
+
+ // readonly's position, mark, and limit should be independent to buf
+ readonly.reset();
+ assertEquals(readonly.position(), 0);
+ readonly.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+ }
+
+ public void testCompact() {
+ // case: buffer is full
+ buf.clear();
+ buf.mark();
+ loadTestData1(buf);
+ DoubleBuffer ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), buf.capacity());
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 0.0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: buffer is empty
+ buf.position(0);
+ buf.limit(0);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 0);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 0.0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: normal
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(5);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 4);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 1.0, 4);
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ public void testCompareTo() {
+ DoubleBuffer other = DoubleBuffer.allocate(buf.capacity());
+ loadTestData1(other);
+ assertEquals(0, buf.compareTo(other));
+ assertEquals(0, other.compareTo(buf));
+ buf.position(1);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ other.position(2);
+ assertTrue(buf.compareTo(other) < 0);
+ assertTrue(other.compareTo(buf) > 0);
+ buf.position(2);
+ other.limit(5);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+
+ DoubleBuffer dbuffer1 = DoubleBuffer.wrap(new double[] { Double.NaN });
+ DoubleBuffer dbuffer2 = DoubleBuffer.wrap(new double[] { Double.NaN });
+ DoubleBuffer dbuffer3 = DoubleBuffer.wrap(new double[] { 42d });
+
+ assertEquals("Failed equal comparison with NaN entry", 0, dbuffer1
+ .compareTo(dbuffer2));
+ assertEquals("Failed greater than comparison with NaN entry", 1, dbuffer3
+ .compareTo(dbuffer1));
+ assertEquals("Failed greater than comparison with NaN entry", 1, dbuffer1
+ .compareTo(dbuffer3));
+ }
+
+ public void testDuplicate() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // duplicate's contents should be the same as buf
+ DoubleBuffer duplicate = buf.duplicate();
+ assertNotSame(buf, duplicate);
+ assertEquals(buf.position(), duplicate.position());
+ assertEquals(buf.limit(), duplicate.limit());
+ assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
+ assertEquals(buf.isDirect(), duplicate.isDirect());
+ assertEquals(buf.order(), duplicate.order());
+ assertContentEquals(buf, duplicate);
+
+ // duplicate's position, mark, and limit should be independent to buf
+ duplicate.reset();
+ assertEquals(duplicate.position(), 0);
+ duplicate.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+
+ // duplicate share the same content with buf
+ // FIXME
+ if (!duplicate.isReadOnly()) {
+ loadTestData1(buf);
+ assertContentEquals(buf, duplicate);
+ loadTestData2(duplicate);
+ assertContentEquals(buf, duplicate);
+ }
+ }
+
+ public void testEquals() {
+ // equal to self
+ assertTrue(buf.equals(buf));
+ DoubleBuffer readonly = buf.asReadOnlyBuffer();
+ assertTrue(buf.equals(readonly));
+ DoubleBuffer duplicate = buf.duplicate();
+ assertTrue(buf.equals(duplicate));
+
+ // always false, if type mismatch
+ assertFalse(buf.equals(Boolean.TRUE));
+
+ assertTrue(buf.capacity() > 5);
+
+ buf.limit(buf.capacity()).position(0);
+ readonly.limit(readonly.capacity()).position(1);
+ assertFalse(buf.equals(readonly));
+
+ buf.limit(buf.capacity() - 1).position(0);
+ duplicate.limit(duplicate.capacity()).position(0);
+ assertFalse(buf.equals(duplicate));
+ }
+
+ /*
+ * Class under test for double get()
+ */
+ public void testGet() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i), 0.01);
+ }
+ try {
+ buf.get();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.DoubleBuffer get(double[])
+ */
+ public void testGetdoubleArray() {
+ double array[] = new double[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ DoubleBuffer ret = buf.get(array);
+ assertEquals(array[0], buf.get(i), 0.01);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.get(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.DoubleBuffer get(double[], int, int)
+ */
+ public void testGetdoubleArrayintint() {
+ buf.clear();
+ double array[] = new double[buf.capacity()];
+
+ try {
+ buf.get(new double[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.get(array, array.length, 0);
+ try {
+ buf.get(array, array.length + 1, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get((double[])null, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ buf.get(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+
+ buf.clear();
+ DoubleBuffer ret = buf.get(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for double get(int)
+ */
+ public void testGetint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i), 0.01);
+ }
+ try {
+ buf.get(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(buf.limit());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testHasArray() {
+ assertTrue(buf.hasArray());
+ }
+
+ public void testHashCode() {
+ buf.clear();
+ DoubleBuffer readonly = buf.asReadOnlyBuffer();
+ DoubleBuffer duplicate = buf.duplicate();
+ assertTrue(buf.hashCode() == readonly.hashCode());
+
+ assertTrue(buf.capacity() > 5);
+ duplicate.position(buf.capacity() / 2);
+ assertTrue(buf.hashCode() != duplicate.hashCode());
+ }
+
+ public void testIsDirect() {
+ assertFalse(buf.isDirect());
+ }
+
+ public void testOrder() {
+ assertEquals(ByteOrder.nativeOrder(), buf.order());
+ }
+
+ /*
+ * Class under test for java.nio.DoubleBuffer put(double)
+ */
+ public void testPutdouble() {
+
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ DoubleBuffer ret = buf.put((double) i);
+ assertEquals(buf.get(i), (double) i, 0.0);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.DoubleBuffer put(double[])
+ */
+ public void testPutdoubleArray() {
+ double array[] = new double[1];
+
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ array[0] = (double) i;
+ DoubleBuffer ret = buf.put(array);
+ assertEquals(buf.get(i), (double) i, 0.0);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.DoubleBuffer put(double[], int, int)
+ */
+ public void testPutdoubleArrayintint() {
+ buf.clear();
+ double array[] = new double[buf.capacity()];
+
+ try {
+ buf.put(new double[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, array.length + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.put(array, array.length, 0);
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put((double[])null, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ assertEquals(buf.position(), 0);
+
+ loadTestData2(array, 0, array.length);
+ DoubleBuffer ret = buf.put(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.DoubleBuffer put(java.nio.DoubleBuffer)
+ */
+ public void testPutDoubleBuffer() {
+ DoubleBuffer other = DoubleBuffer.allocate(buf.capacity());
+
+ try {
+ buf.put(buf);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ buf.put(DoubleBuffer.allocate(buf.capacity() + 1));
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+
+ loadTestData2(other);
+ other.clear();
+ buf.clear();
+ DoubleBuffer ret = buf.put(other);
+ assertEquals(other.position(), other.capacity());
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(other, buf);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.DoubleBuffer put(int, double)
+ */
+ public void testPutintdouble() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), 0);
+ DoubleBuffer ret = buf.put(i, (double) i);
+ assertEquals(buf.get(i), (double) i, 0.0);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(-1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(buf.limit(), 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testSlice() {
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(buf.capacity() - 1);
+
+ DoubleBuffer slice = buf.slice();
+ assertEquals(buf.isReadOnly(), slice.isReadOnly());
+ assertEquals(buf.isDirect(), slice.isDirect());
+ assertEquals(buf.order(), slice.order());
+ assertEquals(slice.position(), 0);
+ assertEquals(slice.limit(), buf.remaining());
+ assertEquals(slice.capacity(), buf.remaining());
+ try {
+ slice.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // slice share the same content with buf
+ // FIXME:
+ if (!slice.isReadOnly()) {
+ loadTestData1(slice);
+ assertContentLikeTestData1(buf, 1, 0, slice.capacity());
+ buf.put(2, 500);
+ assertEquals(slice.get(1), 500, 0.0);
+ }
+ }
+
+ public void testToString() {
+ String str = buf.toString();
+ assertTrue(str.indexOf("Double") >= 0 || str.indexOf("double") >= 0);
+ assertTrue(str.indexOf("" + buf.position()) >= 0);
+ assertTrue(str.indexOf("" + buf.limit()) >= 0);
+ assertTrue(str.indexOf("" + buf.capacity()) >= 0);
+ }
+
+ void loadTestData1(double array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (double) i;
+ }
+ }
+
+ void loadTestData2(double array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (double) length - i;
+ }
+ }
+
+ void loadTestData1(DoubleBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (double) i);
+ }
+ }
+
+ void loadTestData2(DoubleBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (double) buf.capacity() - i);
+ }
+ }
+
+ private void assertContentEquals(DoubleBuffer buf, double array[],
+ int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(i), array[offset + i], 0.01);
+ }
+ }
+
+ private void assertContentEquals(DoubleBuffer buf, DoubleBuffer other) {
+ assertEquals(buf.capacity(), other.capacity());
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.get(i), other.get(i), 0.01);
+ }
+ }
+
+ private void assertContentLikeTestData1(DoubleBuffer buf, int startIndex,
+ double startValue, int length) {
+ double value = startValue;
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(startIndex + i), value, 0.01);
+ value = value + 1.0;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateDirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateDirectByteBufferTest.java
new file mode 100644
index 0000000..58ac4c3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateDirectByteBufferTest.java
@@ -0,0 +1,31 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class DuplicateDirectByteBufferTest extends DirectByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.duplicate();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateHeapByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateHeapByteBufferTest.java
new file mode 100644
index 0000000..452f7cb
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateHeapByteBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class DuplicateHeapByteBufferTest extends HeapByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.duplicate();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateWrappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateWrappedByteBufferTest.java
new file mode 100644
index 0000000..8d9c833
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DuplicateWrappedByteBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class DuplicateWrappedByteBufferTest extends WrappedByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.duplicate();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/FloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/FloatBufferTest.java
new file mode 100644
index 0000000..49903bf
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/FloatBufferTest.java
@@ -0,0 +1,674 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteOrder;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.InvalidMarkException;
+
+/**
+ * Tests java.nio.FloatBuffer
+ *
+ */
+public class FloatBufferTest extends AbstractBufferTest {
+
+ protected static final int SMALL_TEST_LENGTH = 5;
+
+ protected static final int BUFFER_LENGTH = 20;
+
+ protected FloatBuffer buf;
+
+ protected void setUp() throws Exception {
+ buf = FloatBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testArray() {
+ float array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testArrayOffset() {
+ float array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testAsReadOnlyBuffer() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // readonly's contents should be the same as buf
+ FloatBuffer readonly = buf.asReadOnlyBuffer();
+ assertNotSame(buf, readonly);
+ assertTrue(readonly.isReadOnly());
+ assertEquals(buf.position(), readonly.position());
+ assertEquals(buf.limit(), readonly.limit());
+ assertEquals(buf.isDirect(), readonly.isDirect());
+ assertEquals(buf.order(), readonly.order());
+ assertContentEquals(buf, readonly);
+
+ // readonly's position, mark, and limit should be independent to buf
+ readonly.reset();
+ assertEquals(readonly.position(), 0);
+ readonly.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+ }
+
+ public void testCompact() {
+
+ // case: buffer is full
+ buf.clear();
+ buf.mark();
+ loadTestData1(buf);
+ FloatBuffer ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), buf.capacity());
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 0.0f, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: buffer is empty
+ buf.position(0);
+ buf.limit(0);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 0);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 0.0f, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: normal
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(5);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 4);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 1.0f, 4);
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ public void testCompareTo() {
+ try {
+ buf.compareTo(null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // compare to self
+ assertEquals(0, buf.compareTo(buf));
+
+ // normal cases
+ assertTrue(buf.capacity() > 5);
+ buf.clear();
+ FloatBuffer other = FloatBuffer.allocate(buf.capacity());
+ loadTestData1(other);
+ assertEquals(0, buf.compareTo(other));
+ assertEquals(0, other.compareTo(buf));
+ buf.position(1);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ other.position(2);
+ assertTrue(buf.compareTo(other) < 0);
+ assertTrue(other.compareTo(buf) > 0);
+ buf.position(2);
+ other.limit(5);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+
+ FloatBuffer fbuffer1 = FloatBuffer.wrap(new float[] { Float.NaN });
+ FloatBuffer fbuffer2 = FloatBuffer.wrap(new float[] { Float.NaN });
+ FloatBuffer fbuffer3 = FloatBuffer.wrap(new float[] { 42f });
+
+ assertEquals("Failed equal comparison with NaN entry", 0, fbuffer1
+ .compareTo(fbuffer2));
+ assertEquals("Failed greater than comparison with NaN entry", 1, fbuffer3
+ .compareTo(fbuffer1));
+ assertEquals("Failed greater than comparison with NaN entry", 1, fbuffer1
+ .compareTo(fbuffer3));
+
+ }
+
+ public void testDuplicate() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // duplicate's contents should be the same as buf
+ FloatBuffer duplicate = buf.duplicate();
+ assertNotSame(buf, duplicate);
+ assertEquals(buf.position(), duplicate.position());
+ assertEquals(buf.limit(), duplicate.limit());
+ assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
+ assertEquals(buf.isDirect(), duplicate.isDirect());
+ assertEquals(buf.order(), duplicate.order());
+ assertContentEquals(buf, duplicate);
+
+ // duplicate's position, mark, and limit should be independent to buf
+ duplicate.reset();
+ assertEquals(duplicate.position(), 0);
+ duplicate.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+
+ // duplicate share the same content with buf
+ if (!duplicate.isReadOnly()) {
+ loadTestData1(buf);
+ assertContentEquals(buf, duplicate);
+ loadTestData2(duplicate);
+ assertContentEquals(buf, duplicate);
+ }
+ }
+
+ public void testEquals() {
+ // equal to self
+ assertTrue(buf.equals(buf));
+ FloatBuffer readonly = buf.asReadOnlyBuffer();
+ assertTrue(buf.equals(readonly));
+ FloatBuffer duplicate = buf.duplicate();
+ assertTrue(buf.equals(duplicate));
+
+ // always false, if type mismatch
+ assertFalse(buf.equals(Boolean.TRUE));
+
+ assertTrue(buf.capacity() > 5);
+
+ buf.limit(buf.capacity()).position(0);
+ readonly.limit(readonly.capacity()).position(1);
+ assertFalse(buf.equals(readonly));
+
+ buf.limit(buf.capacity() - 1).position(0);
+ duplicate.limit(duplicate.capacity()).position(0);
+ assertFalse(buf.equals(duplicate));
+ }
+
+ /*
+ * Class under test for float get()
+ */
+ public void testGet() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i), 0.01);
+ }
+ try {
+ buf.get();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.FloatBuffer get(float[])
+ */
+ public void testGetfloatArray() {
+ float array[] = new float[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ FloatBuffer ret = buf.get(array);
+ assertEquals(array[0], buf.get(i), 0.01);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.get(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ try {
+ buf.position(buf.limit());
+ buf.get((float[])null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ buf.get(new float[0]);
+ }
+
+ /*
+ * Class under test for java.nio.FloatBuffer get(float[], int, int)
+ */
+ public void testGetfloatArrayintint() {
+ buf.clear();
+ float array[] = new float[buf.capacity()];
+
+ try {
+ buf.get(new float[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.get(array, array.length, 0);
+ try {
+ buf.get(array, array.length + 1, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get((float[])null, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ buf.get(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+
+ buf.clear();
+ FloatBuffer ret = buf.get(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for float get(int)
+ */
+ public void testGetint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i), 0.01);
+ }
+ try {
+ buf.get(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(buf.limit());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testHasArray() {
+ assertNotNull(buf.array());
+ }
+
+ public void testHashCode() {
+ buf.clear();
+ FloatBuffer readonly = buf.asReadOnlyBuffer();
+ FloatBuffer duplicate = buf.duplicate();
+ assertTrue(buf.hashCode() == readonly.hashCode());
+
+ assertTrue(buf.capacity() > 5);
+ duplicate.position(buf.capacity() / 2);
+ assertTrue(buf.hashCode() != duplicate.hashCode());
+ }
+
+ public void testIsDirect() {
+ assertFalse(buf.isDirect());
+ }
+
+ public void testOrder() {
+ buf.order();
+ if (buf.hasArray()) {
+ assertEquals(ByteOrder.nativeOrder(), buf.order());
+ }
+ }
+
+ /*
+ * Class under test for java.nio.FloatBuffer put(float)
+ */
+ public void testPutfloat() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ FloatBuffer ret = buf.put((float) i);
+ assertEquals(buf.get(i), (float) i, 0.0);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.FloatBuffer put(float[])
+ */
+ public void testPutfloatArray() {
+ float array[] = new float[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ array[0] = (float) i;
+ FloatBuffer ret = buf.put(array);
+ assertEquals(buf.get(i), (float) i, 0.0);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.position(buf.limit());
+ buf.put((float[])null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.FloatBuffer put(float[], int, int)
+ */
+ public void testPutfloatArrayintint() {
+ buf.clear();
+ float array[] = new float[buf.capacity()];
+ try {
+ buf.put(new float[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, array.length + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.put(array, array.length, 0);
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put((float[])null, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ assertEquals(buf.position(), 0);
+
+ loadTestData2(array, 0, array.length);
+ FloatBuffer ret = buf.put(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.FloatBuffer put(java.nio.FloatBuffer)
+ */
+ public void testPutFloatBuffer() {
+ FloatBuffer other = FloatBuffer.allocate(buf.capacity());
+ try {
+ buf.put(buf);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ buf.put(FloatBuffer.allocate(buf.capacity() + 1));
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.flip();
+ buf.put((FloatBuffer)null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ buf.clear();
+ loadTestData2(other);
+ other.clear();
+ buf.clear();
+ FloatBuffer ret = buf.put(other);
+ assertEquals(other.position(), other.capacity());
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(other, buf);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.FloatBuffer put(int, float)
+ */
+ public void testPutintfloat() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), 0);
+ FloatBuffer ret = buf.put(i, (float) i);
+ assertEquals(buf.get(i), (float) i, 0.0);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(-1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(buf.limit(), 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testSlice() {
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(buf.capacity() - 1);
+
+ FloatBuffer slice = buf.slice();
+ assertEquals(buf.isReadOnly(), slice.isReadOnly());
+ assertEquals(buf.isDirect(), slice.isDirect());
+ assertEquals(buf.order(), slice.order());
+ assertEquals(slice.position(), 0);
+ assertEquals(slice.limit(), buf.remaining());
+ assertEquals(slice.capacity(), buf.remaining());
+ try {
+ slice.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // slice share the same content with buf
+ if (!slice.isReadOnly()) {
+ loadTestData1(slice);
+ assertContentLikeTestData1(buf, 1, 0, slice.capacity());
+ buf.put(2, 500);
+ assertEquals(slice.get(1), 500, 0.0);
+ }
+ }
+
+ public void testToString() {
+ String str = buf.toString();
+ assertTrue(str.indexOf("Float") >= 0 || str.indexOf("float") >= 0);
+ assertTrue(str.indexOf("" + buf.position()) >= 0);
+ assertTrue(str.indexOf("" + buf.limit()) >= 0);
+ assertTrue(str.indexOf("" + buf.capacity()) >= 0);
+ }
+
+ void loadTestData1(float array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (float) i;
+ }
+ }
+
+ void loadTestData2(float array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (float) length - i;
+ }
+ }
+
+ void loadTestData1(FloatBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (float) i);
+ }
+ }
+
+ void loadTestData2(FloatBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (float) buf.capacity() - i);
+ }
+ }
+
+ void assertContentEquals(FloatBuffer buf, float array[],
+ int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(i), array[offset + i], 0.01);
+ }
+ }
+
+ void assertContentEquals(FloatBuffer buf, FloatBuffer other) {
+ assertEquals(buf.capacity(), other.capacity());
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.get(i), other.get(i), 0.01);
+ }
+ }
+
+ void assertContentLikeTestData1(FloatBuffer buf,
+ int startIndex, float startValue, int length) {
+ float value = startValue;
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(startIndex + i), value, 0.01);
+ value = value + 1.0f;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapByteBufferTest.java
new file mode 100644
index 0000000..1ce3c6b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapByteBufferTest.java
@@ -0,0 +1,60 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+
+
+public class HeapByteBufferTest extends ByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = ByteBuffer.allocate(BUFFER_LENGTH);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ /**
+ * @tests java.nio.ByteBuffer#allocate(int)
+ *
+ */
+ public void testAllocatedByteBuffer_IllegalArg() {
+ try {
+ ByteBuffer.allocate(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testIsDirect() {
+ assertFalse(buf.isDirect());
+ }
+
+ public void testHasArray() {
+ assertTrue(buf.hasArray());
+ }
+
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapCharBufferTest.java
new file mode 100644
index 0000000..1ef25c8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapCharBufferTest.java
@@ -0,0 +1,44 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.CharBuffer;
+
+
+public class HeapCharBufferTest extends CharBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = CharBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testAllocatedCharBuffer_IllegalArg() {
+ try {
+ CharBuffer.allocate(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapDoubleBufferTest.java
new file mode 100644
index 0000000..059adf6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapDoubleBufferTest.java
@@ -0,0 +1,42 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.DoubleBuffer;
+
+public class HeapDoubleBufferTest extends DoubleBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = DoubleBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testAllocatedDoubleBuffer_IllegalArg() {
+ try {
+ DoubleBuffer.allocate(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapFloatBufferTest.java
new file mode 100644
index 0000000..e946857
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapFloatBufferTest.java
@@ -0,0 +1,42 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.FloatBuffer;
+
+public class HeapFloatBufferTest extends FloatBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = FloatBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testAllocatedFloatBuffer_IllegalArg() {
+ try {
+ FloatBuffer.allocate(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapIntBufferTest.java
new file mode 100644
index 0000000..1f8e106
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapIntBufferTest.java
@@ -0,0 +1,42 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.IntBuffer;
+
+public class HeapIntBufferTest extends IntBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = IntBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testAllocatedIntBuffer_IllegalArg() {
+ try {
+ IntBuffer.allocate(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapLongBufferTest.java
new file mode 100644
index 0000000..a368ab6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapLongBufferTest.java
@@ -0,0 +1,42 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.LongBuffer;
+
+public class HeapLongBufferTest extends LongBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = LongBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testAllocatedLongBuffer_IllegalArg() {
+ try {
+ LongBuffer.allocate(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapShortBufferTest.java
new file mode 100644
index 0000000..aefbcf4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/HeapShortBufferTest.java
@@ -0,0 +1,42 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ShortBuffer;
+
+public class HeapShortBufferTest extends ShortBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = ShortBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testAllocatedShortBuffer_IllegalArg() {
+ try {
+ ShortBuffer.allocate(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/IntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/IntBufferTest.java
new file mode 100644
index 0000000..7b5f976
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/IntBufferTest.java
@@ -0,0 +1,650 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.nio.InvalidMarkException;
+
+/**
+ * Tests java.nio.IntBuffer
+ *
+ */
+public class IntBufferTest extends AbstractBufferTest {
+
+
+ protected static final int SMALL_TEST_LENGTH = 5;
+
+ protected static final int BUFFER_LENGTH = 20;
+
+ protected IntBuffer buf;
+
+ protected void setUp() throws Exception {
+ buf = IntBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testArray() {
+ int array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testArrayOffset() {
+ int array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testAsReadOnlyBuffer() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // readonly's contents should be the same as buf
+ IntBuffer readonly = buf.asReadOnlyBuffer();
+ assertNotSame(buf, readonly);
+ assertTrue(readonly.isReadOnly());
+ assertEquals(buf.position(), readonly.position());
+ assertEquals(buf.limit(), readonly.limit());
+ assertEquals(buf.isDirect(), readonly.isDirect());
+ assertEquals(buf.order(), readonly.order());
+ assertContentEquals(buf, readonly);
+
+ // readonly's position, mark, and limit should be independent to buf
+ readonly.reset();
+ assertEquals(readonly.position(), 0);
+ readonly.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+ }
+
+ public void testCompact() {
+ // case: buffer is full
+ buf.clear();
+ buf.mark();
+ loadTestData1(buf);
+ IntBuffer ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), buf.capacity());
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: buffer is empty
+ buf.position(0);
+ buf.limit(0);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 0);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: normal
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(5);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 4);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 1, 4);
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ public void testCompareTo() {
+ // compare to self
+ assertEquals(0, buf.compareTo(buf));
+
+ // normal cases
+ assertTrue(buf.capacity() > 5);
+ buf.clear();
+ IntBuffer other = IntBuffer.allocate(buf.capacity());
+ loadTestData1(other);
+ assertEquals(0, buf.compareTo(other));
+ assertEquals(0, other.compareTo(buf));
+ buf.position(1);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ other.position(2);
+ assertTrue(buf.compareTo(other) < 0);
+ assertTrue(other.compareTo(buf) > 0);
+ buf.position(2);
+ other.limit(5);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ }
+
+ public void testDuplicate() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // duplicate's contents should be the same as buf
+ IntBuffer duplicate = buf.duplicate();
+ assertNotSame(buf, duplicate);
+ assertEquals(buf.position(), duplicate.position());
+ assertEquals(buf.limit(), duplicate.limit());
+ assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
+ assertEquals(buf.isDirect(), duplicate.isDirect());
+ assertEquals(buf.order(), duplicate.order());
+ assertContentEquals(buf, duplicate);
+
+ // duplicate's position, mark, and limit should be independent to buf
+ duplicate.reset();
+ assertEquals(duplicate.position(), 0);
+ duplicate.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+
+ // duplicate share the same content with buf
+ if (!duplicate.isReadOnly()) {
+ loadTestData1(buf);
+ assertContentEquals(buf, duplicate);
+ loadTestData2(duplicate);
+ assertContentEquals(buf, duplicate);
+ }
+ }
+
+ public void testEquals() {
+ // equal to self
+ assertTrue(buf.equals(buf));
+ IntBuffer readonly = buf.asReadOnlyBuffer();
+ assertTrue(buf.equals(readonly));
+ IntBuffer duplicate = buf.duplicate();
+ assertTrue(buf.equals(duplicate));
+
+ // always false, if type mismatch
+ assertFalse(buf.equals(Boolean.TRUE));
+
+ assertTrue(buf.capacity() > 5);
+
+ buf.limit(buf.capacity()).position(0);
+ readonly.limit(readonly.capacity()).position(1);
+ assertFalse(buf.equals(readonly));
+
+ buf.limit(buf.capacity() - 1).position(0);
+ duplicate.limit(duplicate.capacity()).position(0);
+ assertFalse(buf.equals(duplicate));
+ }
+
+ /*
+ * Class under test for int get()
+ */
+ public void testGet() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.IntBuffer get(int[])
+ */
+ public void testGetintArray() {
+ int array[] = new int[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ IntBuffer ret = buf.get(array);
+ assertEquals(array[0], buf.get(i));
+ assertSame(ret, buf);
+ }
+ try {
+ buf.get(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ try {
+ buf.get((int[])null);
+ fail("Should throw NPE"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.IntBuffer get(int[], int, int)
+ */
+ public void testGetintArrayintint() {
+ buf.clear();
+ int array[] = new int[buf.capacity()];
+
+ try {
+ buf.get(new int[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.get(array, array.length, 0);
+ try {
+ buf.get(array, array.length + 1, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get((int[])null, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ buf.get(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+
+ buf.clear();
+ IntBuffer ret = buf.get(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for int get(int)
+ */
+ public void testGetint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(buf.limit());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testHasArray() {
+ assertNotNull(buf.array());
+ }
+
+ public void testHashCode() {
+ buf.clear();
+ IntBuffer readonly = buf.asReadOnlyBuffer();
+ IntBuffer duplicate = buf.duplicate();
+ assertTrue(buf.hashCode() == readonly.hashCode());
+
+ assertTrue(buf.capacity() > 5);
+ duplicate.position(buf.capacity() / 2);
+ assertTrue(buf.hashCode() != duplicate.hashCode());
+ }
+
+ public void testIsDirect() {
+ assertFalse(buf.isDirect());
+ }
+
+ public void testOrder() {
+ buf.order();
+ assertEquals(ByteOrder.nativeOrder(), buf.order());
+ }
+
+ /*
+ * Class under test for java.nio.IntBuffer put(int)
+ */
+ public void testPutint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ IntBuffer ret = buf.put((int) i);
+ assertEquals(buf.get(i), (int) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.IntBuffer put(int[])
+ */
+ public void testPutintArray() {
+ int array[] = new int[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ array[0] = (int) i;
+ IntBuffer ret = buf.put(array);
+ assertEquals(buf.get(i), (int) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.position(buf.limit());
+ buf.put((int[])null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.IntBuffer put(int[], int, int)
+ */
+ public void testPutintArrayintint() {
+ buf.clear();
+ int array[] = new int[buf.capacity()];
+ try {
+ buf.put(new int[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, array.length + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.put(array, array.length, 0);
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put((int[])null, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ assertEquals(buf.position(), 0);
+
+ loadTestData2(array, 0, array.length);
+ IntBuffer ret = buf.put(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.IntBuffer put(java.nio.IntBuffer)
+ */
+ public void testPutIntBuffer() {
+ IntBuffer other = IntBuffer.allocate(buf.capacity());
+ try {
+ buf.put(buf);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ buf.put(IntBuffer.allocate(buf.capacity() + 1));
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.flip();
+ buf.put((IntBuffer)null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ loadTestData2(other);
+ other.clear();
+ buf.clear();
+ IntBuffer ret = buf.put(other);
+ assertEquals(other.position(), other.capacity());
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(other, buf);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.IntBuffer put(int, int)
+ */
+ public void testPutintint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), 0);
+ IntBuffer ret = buf.put(i, (int) i);
+ assertEquals(buf.get(i), (int) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(-1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(buf.limit(), 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testSlice() {
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(buf.capacity() - 1);
+
+ IntBuffer slice = buf.slice();
+ assertEquals(buf.isReadOnly(), slice.isReadOnly());
+ assertEquals(buf.isDirect(), slice.isDirect());
+ assertEquals(buf.order(), slice.order());
+ assertEquals(slice.position(), 0);
+ assertEquals(slice.limit(), buf.remaining());
+ assertEquals(slice.capacity(), buf.remaining());
+ try {
+ slice.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // slice share the same content with buf
+ if (!slice.isReadOnly()) {
+ loadTestData1(slice);
+ assertContentLikeTestData1(buf, 1, 0, slice.capacity());
+ buf.put(2, 500);
+ assertEquals(slice.get(1), 500);
+ }
+ }
+
+ public void testToString() {
+ String str = buf.toString();
+ assertTrue(str.indexOf("Int") >= 0 || str.indexOf("int") >= 0);
+ assertTrue(str.indexOf("" + buf.position()) >= 0);
+ assertTrue(str.indexOf("" + buf.limit()) >= 0);
+ assertTrue(str.indexOf("" + buf.capacity()) >= 0);
+ }
+
+ void loadTestData1(int array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (int) i;
+ }
+ }
+
+ void loadTestData2(int array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (int) length - i;
+ }
+ }
+
+ void loadTestData1(IntBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (int) i);
+ }
+ }
+
+ void loadTestData2(IntBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (int) buf.capacity() - i);
+ }
+ }
+
+ void assertContentEquals(IntBuffer buf, int array[],
+ int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(i), array[offset + i]);
+ }
+ }
+
+ void assertContentEquals(IntBuffer buf, IntBuffer other) {
+ assertEquals(buf.capacity(), other.capacity());
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.get(i), other.get(i));
+ }
+ }
+
+ void assertContentLikeTestData1(IntBuffer buf,
+ int startIndex, int startValue, int length) {
+ int value = startValue;
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(startIndex + i), value);
+ value = value + 1;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/InvalidMarkExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/InvalidMarkExceptionTest.java
new file mode 100644
index 0000000..be8b1bd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/InvalidMarkExceptionTest.java
@@ -0,0 +1,51 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.InvalidMarkException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class InvalidMarkExceptionTest extends TestCase {
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new InvalidMarkException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new InvalidMarkException());
+ }
+
+ /**
+ *@tests {@link java.nio.InvalidMarkException#InvalidMarkException()}
+ */
+ public void test_Constructor() {
+ InvalidMarkException exception = new InvalidMarkException();
+ assertNull(exception.getMessage());
+ assertNull(exception.getLocalizedMessage());
+ assertNull(exception.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/LongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/LongBufferTest.java
new file mode 100644
index 0000000..e390db8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/LongBufferTest.java
@@ -0,0 +1,657 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteOrder;
+import java.nio.InvalidMarkException;
+import java.nio.LongBuffer;
+
+/**
+ * Tests java.nio.LongBuffer
+ *
+ */
+public class LongBufferTest extends AbstractBufferTest {
+
+
+ protected static final int SMALL_TEST_LENGTH = 5;
+
+ protected static final int BUFFER_LENGTH = 20;
+
+ protected LongBuffer buf;
+
+ protected void setUp() throws Exception {
+ buf = LongBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testArray() {
+ long array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testArrayOffset() {
+ long array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testAsReadOnlyBuffer() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // readonly's contents should be the same as buf
+ LongBuffer readonly = buf.asReadOnlyBuffer();
+ assertNotSame(buf, readonly);
+ assertTrue(readonly.isReadOnly());
+ assertEquals(buf.position(), readonly.position());
+ assertEquals(buf.limit(), readonly.limit());
+ assertEquals(buf.isDirect(), readonly.isDirect());
+ assertEquals(buf.order(), readonly.order());
+ assertContentEquals(buf, readonly);
+
+ // readonly's position, mark, and limit should be independent to buf
+ readonly.reset();
+ assertEquals(readonly.position(), 0);
+ readonly.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+ }
+
+ public void testCompact() {
+ // case: buffer is full
+ buf.clear();
+ buf.mark();
+ loadTestData1(buf);
+ LongBuffer ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), buf.capacity());
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: buffer is empty
+ buf.position(0);
+ buf.limit(0);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 0);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: normal
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(5);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 4);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, 1, 4);
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ public void testCompareTo() {
+ // compare to self
+ assertEquals(0, buf.compareTo(buf));
+
+ // normal cases
+ assertTrue(buf.capacity() > 5);
+ buf.clear();
+ LongBuffer other = LongBuffer.allocate(buf.capacity());
+ loadTestData1(other);
+ assertEquals(0, buf.compareTo(other));
+ assertEquals(0, other.compareTo(buf));
+ buf.position(1);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ other.position(2);
+ assertTrue(buf.compareTo(other) < 0);
+ assertTrue(other.compareTo(buf) > 0);
+ buf.position(2);
+ other.limit(5);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ }
+
+ public void testDuplicate() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // duplicate's contents should be the same as buf
+ LongBuffer duplicate = buf.duplicate();
+ assertNotSame(buf, duplicate);
+ assertEquals(buf.position(), duplicate.position());
+ assertEquals(buf.limit(), duplicate.limit());
+ assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
+ assertEquals(buf.isDirect(), duplicate.isDirect());
+ assertEquals(buf.order(), duplicate.order());
+ assertContentEquals(buf, duplicate);
+
+ // duplicate's position, mark, and limit should be independent to buf
+ duplicate.reset();
+ assertEquals(duplicate.position(), 0);
+ duplicate.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+
+ // duplicate share the same content with buf
+ if (!duplicate.isReadOnly()) {
+ loadTestData1(buf);
+ assertContentEquals(buf, duplicate);
+ loadTestData2(duplicate);
+ assertContentEquals(buf, duplicate);
+ }
+ }
+
+ public void testEquals() {
+ // equal to self
+ assertTrue(buf.equals(buf));
+ LongBuffer readonly = buf.asReadOnlyBuffer();
+ assertTrue(buf.equals(readonly));
+ LongBuffer duplicate = buf.duplicate();
+ assertTrue(buf.equals(duplicate));
+
+ // always false, if type mismatch
+ assertFalse(buf.equals(Boolean.TRUE));
+
+ assertTrue(buf.capacity() > 5);
+
+ buf.limit(buf.capacity()).position(0);
+ readonly.limit(readonly.capacity()).position(1);
+ assertFalse(buf.equals(readonly));
+
+ buf.limit(buf.capacity() - 1).position(0);
+ duplicate.limit(duplicate.capacity()).position(0);
+ assertFalse(buf.equals(duplicate));
+ }
+
+ /*
+ * Class under test for long get()
+ */
+ public void testGet() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.LongBuffer get(long[])
+ */
+ public void testGetlongArray() {
+ long array[] = new long[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ LongBuffer ret = buf.get(array);
+ assertEquals(array[0], buf.get(i));
+ assertSame(ret, buf);
+ }
+ try {
+ buf.get(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ try {
+ buf.position(buf.limit());
+ buf.get((long[])null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.LongBuffer get(long[], int, int)
+ */
+ public void testGetlongArrayintint() {
+ buf.clear();
+ long array[] = new long[buf.capacity()];
+
+ try {
+ buf.get(new long[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.get(array, array.length, 0);
+ try {
+ buf.get(array, array.length + 1, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get((long[])null, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ buf.get(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+
+ buf.clear();
+ LongBuffer ret = buf.get(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for long get(int)
+ */
+ public void testGetint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(buf.limit());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testHasArray() {
+ assertNotNull(buf.array());
+ }
+
+ public void testHashCode() {
+ buf.clear();
+ LongBuffer readonly = buf.asReadOnlyBuffer();
+ LongBuffer duplicate = buf.duplicate();
+ assertTrue(buf.hashCode() == readonly.hashCode());
+
+ assertTrue(buf.capacity() > 5);
+ duplicate.position(buf.capacity() / 2);
+ assertTrue(buf.hashCode() != duplicate.hashCode());
+ }
+
+ public void testIsDirect() {
+ assertFalse(buf.isDirect());
+ }
+
+ public void testOrder() {
+ buf.order();
+ assertEquals(ByteOrder.nativeOrder(), buf.order());
+ }
+
+ /*
+ * Class under test for java.nio.LongBuffer put(long)
+ */
+ public void testPutlong() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ LongBuffer ret = buf.put((long) i);
+ assertEquals(buf.get(i), (long) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.LongBuffer put(long[])
+ */
+ public void testPutlongArray() {
+ long array[] = new long[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ array[0] = (long) i;
+ LongBuffer ret = buf.put(array);
+ assertEquals(buf.get(i), (long) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.position(buf.limit());
+ buf.put((long[])null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.LongBuffer put(long[], int, int)
+ */
+ public void testPutlongArrayintint() {
+ buf.clear();
+ long array[] = new long[buf.capacity()];
+ try {
+ buf.put(new long[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, array.length + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.put(array, array.length, 0);
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put((long[])null, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ assertEquals(buf.position(), 0);
+
+ loadTestData2(array, 0, array.length);
+ LongBuffer ret = buf.put(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.LongBuffer put(java.nio.LongBuffer)
+ */
+ public void testPutLongBuffer() {
+ LongBuffer other = LongBuffer.allocate(buf.capacity());
+ try {
+ buf.put(buf);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ buf.put(LongBuffer.allocate(buf.capacity() + 1));
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.flip();
+ buf.put((LongBuffer)null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ loadTestData2(other);
+ other.clear();
+ buf.clear();
+ LongBuffer ret = buf.put(other);
+ assertEquals(other.position(), other.capacity());
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(other, buf);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.LongBuffer put(int, long)
+ */
+ public void testPutintlong() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), 0);
+ LongBuffer ret = buf.put(i, (long) i);
+ assertEquals(buf.get(i), (long) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(-1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(buf.limit(), 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testSlice() {
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(buf.capacity() - 1);
+
+ LongBuffer slice = buf.slice();
+ assertEquals(buf.isReadOnly(), slice.isReadOnly());
+ assertEquals(buf.isDirect(), slice.isDirect());
+ assertEquals(buf.order(), slice.order());
+ assertEquals(slice.position(), 0);
+ assertEquals(slice.limit(), buf.remaining());
+ assertEquals(slice.capacity(), buf.remaining());
+ try {
+ slice.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // slice share the same content with buf
+ if (!slice.isReadOnly()) {
+ loadTestData1(slice);
+ assertContentLikeTestData1(buf, 1, 0, slice.capacity());
+ buf.put(2, 500);
+ assertEquals(slice.get(1), 500);
+ }
+ }
+
+ public void testToString() {
+ String str = buf.toString();
+ assertTrue(str.indexOf("Long") >= 0 || str.indexOf("long") >= 0);
+ assertTrue(str.indexOf("" + buf.position()) >= 0);
+ assertTrue(str.indexOf("" + buf.limit()) >= 0);
+ assertTrue(str.indexOf("" + buf.capacity()) >= 0);
+ }
+
+ void loadTestData1(long array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (long) i;
+ }
+ }
+
+ void loadTestData2(long array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (long) length - i;
+ }
+ }
+
+ void loadTestData1(LongBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (long) i);
+ }
+ }
+
+ void loadTestData2(LongBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (long) buf.capacity() - i);
+ }
+ }
+
+ void assertContentEquals(LongBuffer buf, long array[],
+ int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(i), array[offset + i]);
+ }
+ }
+
+ void assertContentEquals(LongBuffer buf, LongBuffer other) {
+ assertEquals(buf.capacity(), other.capacity());
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.get(i), other.get(i));
+ }
+ }
+
+ void assertContentLikeTestData1(LongBuffer buf,
+ int startIndex, long startValue, int length) {
+ long value = startValue;
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(startIndex + i), value);
+ value = value + 1;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/MappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/MappedByteBufferTest.java
new file mode 100644
index 0000000..0fe6f35
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/MappedByteBufferTest.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.NonWritableChannelException;
+import java.nio.channels.FileChannel.MapMode;
+
+import junit.framework.TestCase;
+
+public class MappedByteBufferTest extends TestCase {
+
+ File tmpFile, emptyFile;
+
+ /**
+ * A regression test for failing to correctly set capacity of underlying
+ * wrapped buffer from a mapped byte buffer.
+ */
+ public void testasIntBuffer() throws IOException {
+ // Map file
+ FileInputStream fis = new FileInputStream(tmpFile);
+ FileChannel fc = fis.getChannel();
+ MappedByteBuffer mmb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc
+ .size());
+ int len = mmb.capacity();
+ assertEquals("Got wrong number of bytes", 46, len); //$NON-NLS-1$
+
+ // Read in our 26 bytes
+ for (int i = 0; i < 26; i++) {
+ byte b = mmb.get();
+ assertEquals("Got wrong byte value", (byte) 'A' + i, b); //$NON-NLS-1$
+ }
+
+ // Now convert to an IntBuffer to read our ints
+ IntBuffer ibuffer = mmb.asIntBuffer();
+ for (int i = 0; i < 5; i++) {
+ int val = ibuffer.get();
+ assertEquals("Got wrong int value", i + 1, val); //$NON-NLS-1$
+ }
+ fc.close();
+ }
+
+ /**
+ * Regression for HARMONY-6315 - FileChannel.map throws IOException
+ * when called with size 0
+ *
+ * @throws IOException
+ */
+ public void testEmptyBuffer() throws IOException {
+ // Map empty file
+ FileInputStream fis = new FileInputStream(emptyFile);
+ FileChannel fc = fis.getChannel();
+ MappedByteBuffer mmb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+
+ // check non-null
+ assertNotNull("MappedByteBuffer created from empty file should not be null",
+ mmb);
+
+ // check capacity is 0
+ int len = mmb.capacity();
+ assertEquals("MappedByteBuffer created from empty file should have 0 capacity",
+ 0, len);
+
+ assertFalse("MappedByteBuffer from empty file shouldn't be backed by an array ",
+ mmb.hasArray());
+
+ try
+ {
+ byte b = mmb.get();
+ fail("Calling MappedByteBuffer.get() on empty buffer should throw a BufferUnderflowException");
+ }
+ catch (BufferUnderflowException e)
+ {
+ // expected behaviour
+ }
+
+ // test expected exceptions thrown
+ try
+ {
+ mmb = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());
+ fail("Expected NonWritableChannelException to be thrown");
+ }
+ catch (NonWritableChannelException e)
+ {
+ // expected behaviour
+ }
+ try
+ {
+ mmb = fc.map(FileChannel.MapMode.PRIVATE, 0, fc.size());
+ fail("Expected NonWritableChannelException to be thrown");
+ }
+ catch (NonWritableChannelException e)
+ {
+ // expected behaviour
+ }
+ fc.close();
+ }
+
+ /**
+ * @tests {@link java.nio.MappedByteBuffer#force()}
+ */
+ public void test_force() throws IOException {
+ // buffer was not mapped in read/write mode
+ FileInputStream fileInputStream = new FileInputStream(tmpFile);
+ FileChannel fileChannelRead = fileInputStream.getChannel();
+ MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0,
+ fileChannelRead.size());
+
+ mmbRead.force();
+
+ FileInputStream inputStream = new FileInputStream(tmpFile);
+ FileChannel fileChannelR = inputStream.getChannel();
+ MappedByteBuffer resultRead = fileChannelR.map(MapMode.READ_ONLY, 0,
+ fileChannelR.size());
+
+ //If this buffer was not mapped in read/write mode, then invoking this method has no effect.
+ assertEquals(
+ "Invoking force() should have no effect when this buffer was not mapped in read/write mode",
+ mmbRead, resultRead);
+
+ // Buffer was mapped in read/write mode
+ RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw");
+ FileChannel fileChannelReadWrite = randomFile.getChannel();
+ MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map(
+ FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size());
+
+ mmbReadWrite.put((byte) 'o');
+ mmbReadWrite.force();
+
+ RandomAccessFile random = new RandomAccessFile(tmpFile, "rw");
+ FileChannel fileChannelRW = random.getChannel();
+ MappedByteBuffer resultReadWrite = fileChannelRW.map(
+ FileChannel.MapMode.READ_WRITE, 0, fileChannelRW.size());
+
+ // Invoking force() will change the buffer
+ assertFalse(mmbReadWrite.equals(resultReadWrite));
+
+ fileChannelRead.close();
+ fileChannelR.close();
+ fileChannelReadWrite.close();
+ fileChannelRW.close();
+ }
+
+ /**
+ * @tests {@link java.nio.MappedByteBuffer#load()}
+ */
+ public void test_load() throws IOException {
+ FileInputStream fileInputStream = new FileInputStream(tmpFile);
+ FileChannel fileChannelRead = fileInputStream.getChannel();
+ MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0,
+ fileChannelRead.size());
+
+ assertEquals(mmbRead, mmbRead.load());
+
+ RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw");
+ FileChannel fileChannelReadWrite = randomFile.getChannel();
+ MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map(
+ FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size());
+
+ assertEquals(mmbReadWrite, mmbReadWrite.load());
+
+ fileChannelRead.close();
+ fileChannelReadWrite.close();
+ }
+
+ protected void setUp() throws IOException {
+ // Create temp file with 26 bytes and 5 ints
+ tmpFile = File.createTempFile("harmony", "test"); //$NON-NLS-1$//$NON-NLS-2$
+ tmpFile.deleteOnExit();
+ FileOutputStream fileOutputStream = new FileOutputStream(tmpFile);
+ FileChannel fileChannel = fileOutputStream.getChannel();
+ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(26 + 20);
+ for (int i = 0; i < 26; i++) {
+ byteBuffer.put((byte) ('A' + i));
+ }
+ for (int i = 0; i < 5; i++) {
+ byteBuffer.putInt(i + 1);
+ }
+ byteBuffer.rewind();
+ fileChannel.write(byteBuffer);
+ fileChannel.close();
+ fileOutputStream.close();
+
+ emptyFile = File.createTempFile("harmony", "test"); //$NON-NLS-1$//$NON-NLS-2$
+ emptyFile.deleteOnExit();
+ }
+
+ public void test_position() throws IOException {
+ File tmp = File.createTempFile("hmy", "tmp");
+ tmp.deleteOnExit();
+ RandomAccessFile f = new RandomAccessFile(tmp, "rw");
+ FileChannel ch = f.getChannel();
+ MappedByteBuffer mbb = ch.map(MapMode.READ_WRITE, 0L, 100L);
+ ch.close();
+
+ mbb.putInt(1, 1);
+ mbb.position(50);
+ mbb.putInt(50);
+
+ mbb.flip();
+ mbb.get();
+ assertEquals(1, mbb.getInt());
+
+ mbb.position(50);
+ assertEquals(50, mbb.getInt());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyBufferExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyBufferExceptionTest.java
new file mode 100644
index 0000000..d6b553a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyBufferExceptionTest.java
@@ -0,0 +1,51 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ReadOnlyBufferException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class ReadOnlyBufferExceptionTest extends TestCase {
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new ReadOnlyBufferException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new ReadOnlyBufferException());
+ }
+
+ /**
+ *@tests {@link java.nio.ReadOnlyBufferException#ReadOnlyBufferException()}
+ */
+ public void test_Constructor() {
+ ReadOnlyBufferException exception = new ReadOnlyBufferException();
+ assertNull(exception.getMessage());
+ assertNull(exception.getLocalizedMessage());
+ assertNull(exception.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyCharBufferTest.java
new file mode 100644
index 0000000..f2669f2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyCharBufferTest.java
@@ -0,0 +1,209 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.CharBuffer;
+import java.nio.ReadOnlyBufferException;
+
+public class ReadOnlyCharBufferTest extends CharBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ buf = null;
+ baseBuf = null;
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ }
+ }
+
+ public void testHashCode() {
+ CharBuffer duplicate = buf.duplicate();
+ assertEquals(buf.hashCode(), duplicate.hashCode());
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testCompact() {
+ try {
+ buf.compact();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutchar() {
+ try {
+ buf.put((char) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutcharArray() {
+ char array[] = new char[1];
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((char[]) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPutcharArrayintint() {
+ char array[] = new char[1];
+ try {
+ buf.put(array, 0, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((char[]) null, 0, 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(new char[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutCharBuffer() {
+ CharBuffer other = CharBuffer.allocate(1);
+ try {
+ buf.put(other);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((CharBuffer) null);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(buf);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutintchar() {
+ try {
+ buf.put(0, (char) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(-1, (char) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutStringintint() {
+ buf.clear();
+ String str = String.valueOf(new char[buf.capacity()]);
+ try {
+ buf.put(str, 0, str.length());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((String) null, 0, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException expected) {
+ } catch (NullPointerException expected) {
+ }
+ try {
+ buf.put(str, -1, str.length());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException expected) {
+ } catch (NullPointerException expected) {
+ }
+ String longStr = String.valueOf(new char[buf.capacity()+1]);
+ try {
+ buf.put(longStr, 0, longStr.length());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutString() {
+ String str = " ";
+ try {
+ buf.put(str);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((String)null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyDirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyDirectByteBufferTest.java
new file mode 100644
index 0000000..dd7d31a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyDirectByteBufferTest.java
@@ -0,0 +1,44 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class ReadOnlyDirectByteBufferTest extends DirectByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testHashCode() {
+ super.readOnlyHashCode();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyDoubleBufferTest.java
new file mode 100644
index 0000000..f2f1ea4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyDoubleBufferTest.java
@@ -0,0 +1,160 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.DoubleBuffer;
+import java.nio.ReadOnlyBufferException;
+
+public class ReadOnlyDoubleBufferTest extends DoubleBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ }
+ }
+
+ public void testHashCode() {
+ DoubleBuffer duplicate = buf.duplicate();
+ assertEquals(buf.hashCode(), duplicate.hashCode());
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testCompact() {
+ try {
+ buf.compact();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutdouble() {
+ try {
+ buf.put(0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutdoubleArray() {
+ double array[] = new double[1];
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((double[]) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPutdoubleArrayintint() {
+ double array[] = new double[1];
+ try {
+ buf.put(array, 0, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((double[]) null, 0, 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(new double[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutDoubleBuffer() {
+ DoubleBuffer other = DoubleBuffer.allocate(1);
+ try {
+ buf.put(other);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((DoubleBuffer) null);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(buf);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutintdouble() {
+ try {
+ buf.put(0, (double) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(-1, (double) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyFloatBufferTest.java
new file mode 100644
index 0000000..56a14ba
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyFloatBufferTest.java
@@ -0,0 +1,161 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.FloatBuffer;
+import java.nio.ReadOnlyBufferException;
+
+public class ReadOnlyFloatBufferTest extends FloatBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ //expected
+ }
+ }
+
+ public void testHashCode() {
+ FloatBuffer duplicate = buf.duplicate();
+ assertEquals(buf.hashCode(), duplicate.hashCode());
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void testCompact() {
+ try {
+ buf.compact();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutfloat() {
+ try {
+ buf.put(0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutfloatArray() {
+ float array[] = new float[1];
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((float[]) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPutfloatArrayintint() {
+ float array[] = new float[1];
+ try {
+ buf.put(array, 0, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((float[]) null, 0, 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(new float[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutFloatBuffer() {
+ FloatBuffer other = FloatBuffer.allocate(1);
+ try {
+ buf.put(other);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((FloatBuffer) null);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(buf);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutintfloat() {
+ try {
+ buf.put(0, (float) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(-1, (float) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapByteBufferTest.java
new file mode 100644
index 0000000..025eca6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapByteBufferTest.java
@@ -0,0 +1,43 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class ReadOnlyHeapByteBufferTest extends HeapByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testHashCode() {
+ super.readOnlyHashCode();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapCharBufferTest.java
new file mode 100644
index 0000000..45ba320
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapCharBufferTest.java
@@ -0,0 +1,35 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.CharBuffer;
+
+
+public class ReadOnlyHeapCharBufferTest extends ReadOnlyCharBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = CharBuffer.allocate(BUFFER_LENGTH);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapDoubleBufferTest.java
new file mode 100644
index 0000000..b978f57
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapDoubleBufferTest.java
@@ -0,0 +1,34 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.DoubleBuffer;
+
+public class ReadOnlyHeapDoubleBufferTest extends ReadOnlyDoubleBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = DoubleBuffer.allocate(BUFFER_LENGTH);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapFloatBufferTest.java
new file mode 100644
index 0000000..9b81e3e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapFloatBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.FloatBuffer;
+
+public class ReadOnlyHeapFloatBufferTest extends ReadOnlyFloatBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = FloatBuffer.allocate(BUFFER_LENGTH);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapIntBufferTest.java
new file mode 100644
index 0000000..8db2ce9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapIntBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.IntBuffer;
+
+public class ReadOnlyHeapIntBufferTest extends ReadOnlyIntBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = IntBuffer.allocate(BUFFER_LENGTH);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapLongBufferTest.java
new file mode 100644
index 0000000..3c27dda
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapLongBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.LongBuffer;
+
+public class ReadOnlyHeapLongBufferTest extends ReadOnlyLongBufferTest{
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = LongBuffer.allocate(BUFFER_LENGTH);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapShortBufferTest.java
new file mode 100644
index 0000000..34ab778
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyHeapShortBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ShortBuffer;
+
+public class ReadOnlyHeapShortBufferTest extends ReadOnlyShortBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = ShortBuffer.allocate(BUFFER_LENGTH);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyIntBufferTest.java
new file mode 100644
index 0000000..e618783
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyIntBufferTest.java
@@ -0,0 +1,161 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.IntBuffer;
+import java.nio.ReadOnlyBufferException;
+
+public class ReadOnlyIntBufferTest extends IntBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ //expected
+ }
+ }
+
+ public void testHashCode() {
+ IntBuffer duplicate = buf.duplicate();
+ assertEquals(buf.hashCode(), duplicate.hashCode());
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void testCompact() {
+ try {
+ buf.compact();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutint() {
+ try {
+ buf.put(0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutintArray() {
+ int array[] = new int[1];
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((int[]) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPutintArrayintint() {
+ int array[] = new int[1];
+ try {
+ buf.put(array, 0, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((int[]) null, -1, 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(new int[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutIntBuffer() {
+ IntBuffer other = IntBuffer.allocate(1);
+ try {
+ buf.put(other);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((IntBuffer) null);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(buf);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutintint() {
+ try {
+ buf.put(0, (int) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(-1, (int) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyLongBufferTest.java
new file mode 100644
index 0000000..fd6438e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyLongBufferTest.java
@@ -0,0 +1,161 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.LongBuffer;
+import java.nio.ReadOnlyBufferException;
+
+public class ReadOnlyLongBufferTest extends LongBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ //expected
+ }
+ }
+
+ public void testHashCode() {
+ LongBuffer duplicate = buf.duplicate();
+ assertEquals(buf.hashCode(), duplicate.hashCode());
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void testCompact() {
+ try {
+ buf.compact();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutlong() {
+ try {
+ buf.put(0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutlongArray() {
+ long array[] = new long[1];
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((long[]) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPutlongArrayintint() {
+ long array[] = new long[1];
+ try {
+ buf.put(array, 0, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((long[]) null, 0, 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(new long[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutLongBuffer() {
+ LongBuffer other = LongBuffer.allocate(1);
+ try {
+ buf.put(other);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((LongBuffer) null);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(buf);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutintlong() {
+ try {
+ buf.put(0, (long) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(-1, (long) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyShortBufferTest.java
new file mode 100644
index 0000000..aab913e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyShortBufferTest.java
@@ -0,0 +1,161 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ReadOnlyBufferException;
+import java.nio.ShortBuffer;
+
+public class ReadOnlyShortBufferTest extends ShortBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ //expected
+ }
+ }
+
+ public void testHashCode() {
+ ShortBuffer duplicate = buf.duplicate();
+ assertEquals(buf.hashCode(), duplicate.hashCode());
+ }
+
+ public void testArrayOffset() {
+ try {
+ buf.arrayOffset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void testCompact() {
+ try {
+ buf.compact();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutshort() {
+ try {
+ buf.put((short)0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutshortArray() {
+ short array[] = new short[1];
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((short[]) null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPutshortArrayintint() {
+ short array[] = new short[1];
+ try {
+ buf.put(array, 0, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((short[]) null, 0, 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(new short[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutShortBuffer() {
+ ShortBuffer other = ShortBuffer.allocate(1);
+ try {
+ buf.put(other);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((ShortBuffer) null);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(buf);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+
+ public void testPutintshort() {
+ try {
+ buf.put(0, (short) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put(-1, (short) 0);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedByteBufferTest.java
new file mode 100644
index 0000000..21a39ea
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedByteBufferTest.java
@@ -0,0 +1,45 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class ReadOnlyWrappedByteBufferTest extends WrappedByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testIsReadOnly() {
+ assertTrue(buf.isReadOnly());
+ }
+
+ public void testHasArray() {
+ assertFalse(buf.hasArray());
+ }
+
+ public void testHashCode() {
+ super.readOnlyHashCode();
+ }
+
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java
new file mode 100644
index 0000000..bfa2033
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java
@@ -0,0 +1,34 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.CharBuffer;
+
+public class ReadOnlyWrappedCharBufferTest1 extends ReadOnlyCharBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = CharBuffer.wrap(new char[BUFFER_LENGTH]);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java
new file mode 100644
index 0000000..83c53ba
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.DoubleBuffer;
+
+public class ReadOnlyWrappedDoubleBufferTest extends ReadOnlyDoubleBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = DoubleBuffer.wrap(new double[BUFFER_LENGTH]);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java
new file mode 100644
index 0000000..645c8a7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.FloatBuffer;
+
+public class ReadOnlyWrappedFloatBufferTest extends ReadOnlyFloatBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = FloatBuffer.wrap(new float[BUFFER_LENGTH]);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedIntBufferTest.java
new file mode 100644
index 0000000..9941137
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedIntBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.IntBuffer;
+
+public class ReadOnlyWrappedIntBufferTest extends ReadOnlyIntBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = IntBuffer.wrap(new int[BUFFER_LENGTH]);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedLongBufferTest.java
new file mode 100644
index 0000000..80f3f88
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedLongBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.LongBuffer;
+
+public class ReadOnlyWrappedLongBufferTest extends ReadOnlyLongBufferTest{
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = LongBuffer.wrap(new long[BUFFER_LENGTH]);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedShortBufferTest.java
new file mode 100644
index 0000000..e10a8c0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ReadOnlyWrappedShortBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ShortBuffer;
+
+public class ReadOnlyWrappedShortBufferTest extends ReadOnlyShortBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = ShortBuffer.wrap(new short[BUFFER_LENGTH]);
+ super.loadTestData1(buf);
+ buf = buf.asReadOnlyBuffer();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ShortBufferTest.java
new file mode 100644
index 0000000..c1c43d7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ShortBufferTest.java
@@ -0,0 +1,637 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteOrder;
+import java.nio.InvalidMarkException;
+import java.nio.ShortBuffer;
+
+/**
+ * Tests java.nio.ShortBuffer
+ *
+ */
+public class ShortBufferTest extends AbstractBufferTest {
+
+ protected static final int SMALL_TEST_LENGTH = 5;
+
+ protected static final int BUFFER_LENGTH = 20;
+
+ protected ShortBuffer buf;
+
+ protected void setUp() throws Exception {
+ buf = ShortBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ buf = null;
+ baseBuf = null;
+ }
+
+ public void testArray() {
+ short array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testArrayOffset() {
+ short array[] = buf.array();
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(array, buf.arrayOffset(), buf.capacity());
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData1(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+
+ loadTestData2(buf);
+ assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
+ }
+
+ public void testAsReadOnlyBuffer() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // readonly's contents should be the same as buf
+ ShortBuffer readonly = buf.asReadOnlyBuffer();
+ assertNotSame(buf, readonly);
+ assertTrue(readonly.isReadOnly());
+ assertEquals(buf.position(), readonly.position());
+ assertEquals(buf.limit(), readonly.limit());
+ assertEquals(buf.isDirect(), readonly.isDirect());
+ assertEquals(buf.order(), readonly.order());
+ assertContentEquals(buf, readonly);
+
+ // readonly's position, mark, and limit should be independent to buf
+ readonly.reset();
+ assertEquals(readonly.position(), 0);
+ readonly.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+ }
+
+ public void testCompact() {
+ // case: buffer is full
+ buf.clear();
+ buf.mark();
+ loadTestData1(buf);
+ ShortBuffer ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), buf.capacity());
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (short) 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: buffer is empty
+ buf.position(0);
+ buf.limit(0);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 0);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (short) 0, buf.capacity());
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // case: normal
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(5);
+ buf.mark();
+ ret = buf.compact();
+ assertSame(ret, buf);
+ assertEquals(buf.position(), 4);
+ assertEquals(buf.limit(), buf.capacity());
+ assertContentLikeTestData1(buf, 0, (short) 1, 4);
+ try {
+ buf.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+ }
+
+ public void testCompareTo() {
+ // compare to self
+ assertEquals(0, buf.compareTo(buf));
+
+ // normal cases
+ assertTrue(buf.capacity() > 5);
+ buf.clear();
+ ShortBuffer other = ShortBuffer.allocate(buf.capacity());
+ loadTestData1(other);
+ assertEquals(0, buf.compareTo(other));
+ assertEquals(0, other.compareTo(buf));
+ buf.position(1);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ other.position(2);
+ assertTrue(buf.compareTo(other) < 0);
+ assertTrue(other.compareTo(buf) > 0);
+ buf.position(2);
+ other.limit(5);
+ assertTrue(buf.compareTo(other) > 0);
+ assertTrue(other.compareTo(buf) < 0);
+ }
+
+ public void testDuplicate() {
+ buf.clear();
+ buf.mark();
+ buf.position(buf.limit());
+
+ // duplicate's contents should be the same as buf
+ ShortBuffer duplicate = buf.duplicate();
+ assertNotSame(buf, duplicate);
+ assertEquals(buf.position(), duplicate.position());
+ assertEquals(buf.limit(), duplicate.limit());
+ assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
+ assertEquals(buf.isDirect(), duplicate.isDirect());
+ assertEquals(buf.order(), duplicate.order());
+ assertContentEquals(buf, duplicate);
+
+ // duplicate's position, mark, and limit should be independent to buf
+ duplicate.reset();
+ assertEquals(duplicate.position(), 0);
+ duplicate.clear();
+ assertEquals(buf.position(), buf.limit());
+ buf.reset();
+ assertEquals(buf.position(), 0);
+
+ // duplicate share the same content with buf
+ if (!duplicate.isReadOnly()) {
+ loadTestData1(buf);
+ assertContentEquals(buf, duplicate);
+ loadTestData2(duplicate);
+ assertContentEquals(buf, duplicate);
+ }
+ }
+
+ public void testEquals() {
+ // equal to self
+ assertTrue(buf.equals(buf));
+ ShortBuffer readonly = buf.asReadOnlyBuffer();
+ assertTrue(buf.equals(readonly));
+ ShortBuffer duplicate = buf.duplicate();
+ assertTrue(buf.equals(duplicate));
+
+ // always false, if type mismatch
+ assertFalse(buf.equals(Boolean.TRUE));
+
+ assertTrue(buf.capacity() > 5);
+
+ buf.limit(buf.capacity()).position(0);
+ readonly.limit(readonly.capacity()).position(1);
+ assertFalse(buf.equals(readonly));
+
+ buf.limit(buf.capacity() - 1).position(0);
+ duplicate.limit(duplicate.capacity()).position(0);
+ assertFalse(buf.equals(duplicate));
+ }
+
+ /*
+ * Class under test for short get()
+ */
+ public void testGet() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.ShortBuffer get(short[])
+ */
+ public void testGetshortArray() {
+ short array[] = new short[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ ShortBuffer ret = buf.get(array);
+ assertEquals(array[0], buf.get(i));
+ assertSame(ret, buf);
+ }
+ try {
+ buf.get(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.ShortBuffer get(short[], int, int)
+ */
+ public void testGetshortArrayintint() {
+ buf.clear();
+ short array[] = new short[buf.capacity()];
+
+ try {
+ buf.get(new short[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.get(array, array.length, 0);
+ try {
+ buf.get(array, array.length + 1, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.get((short[])null, 2, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferUnderflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ buf.get(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+
+ buf.clear();
+ ShortBuffer ret = buf.get(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for short get(int)
+ */
+ public void testGetint() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ assertEquals(buf.get(), buf.get(i));
+ }
+ try {
+ buf.get(-1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.get(buf.limit());
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testHasArray() {
+ assertNotNull(buf.array());
+ }
+
+ public void testHashCode() {
+ buf.clear();
+ ShortBuffer readonly = buf.asReadOnlyBuffer();
+ ShortBuffer duplicate = buf.duplicate();
+ assertTrue(buf.hashCode() == readonly.hashCode());
+
+ assertTrue(buf.capacity() > 5);
+ duplicate.position(buf.capacity() / 2);
+ assertTrue(buf.hashCode() != duplicate.hashCode());
+ }
+
+ public void testIsDirect() {
+ assertFalse(buf.isDirect());
+ }
+
+ public void testOrder() {
+ buf.order();
+ assertEquals(ByteOrder.nativeOrder(), buf.order());
+ }
+
+ /*
+ * Class under test for java.nio.ShortBuffer put(short)
+ */
+ public void testPutshort() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ ShortBuffer ret = buf.put((short) i);
+ assertEquals(buf.get(i), (short) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put((short) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.ShortBuffer put(short[])
+ */
+ public void testPutshortArray() {
+ short array[] = new short[1];
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), i);
+ array[0] = (short) i;
+ ShortBuffer ret = buf.put(array);
+ assertEquals(buf.get(i), (short) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(array);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.position(buf.limit());
+ buf.put((short[])null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Class under test for java.nio.ShortBuffer put(short[], int, int)
+ */
+ public void testPutshortArrayintint() {
+ buf.clear();
+ short array[] = new short[buf.capacity()];
+ try {
+ buf.put(new short[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, array.length + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ buf.put(array, array.length, 0);
+ assertEquals(buf.position(), 0);
+ try {
+ buf.put(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put((short[])null, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 2, array.length);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ assertEquals(buf.position(), 0);
+
+ loadTestData2(array, 0, array.length);
+ ShortBuffer ret = buf.put(array, 0, array.length);
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(buf, array, 0, array.length);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.ShortBuffer put(java.nio.ShortBuffer)
+ */
+ public void testPutShortBuffer() {
+ ShortBuffer other = ShortBuffer.allocate(buf.capacity());
+ try {
+ buf.put(buf);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ buf.put(ShortBuffer.allocate(buf.capacity() + 1));
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (BufferOverflowException e) {
+ // expected
+ }
+ try {
+ buf.flip();
+ buf.put((ShortBuffer)null);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ loadTestData2(other);
+ other.clear();
+ buf.clear();
+ ShortBuffer ret = buf.put(other);
+ assertEquals(other.position(), other.capacity());
+ assertEquals(buf.position(), buf.capacity());
+ assertContentEquals(other, buf);
+ assertSame(ret, buf);
+ }
+
+ /*
+ * Class under test for java.nio.ShortBuffer put(int, short)
+ */
+ public void testPutintshort() {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.position(), 0);
+ ShortBuffer ret = buf.put(i, (short) i);
+ assertEquals(buf.get(i), (short) i);
+ assertSame(ret, buf);
+ }
+ try {
+ buf.put(-1, (short) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ buf.put(buf.limit(), (short) 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void testSlice() {
+ assertTrue(buf.capacity() > 5);
+ buf.position(1);
+ buf.limit(buf.capacity() - 1);
+
+ ShortBuffer slice = buf.slice();
+ assertEquals(buf.isReadOnly(), slice.isReadOnly());
+ assertEquals(buf.isDirect(), slice.isDirect());
+ assertEquals(buf.order(), slice.order());
+ assertEquals(slice.position(), 0);
+ assertEquals(slice.limit(), buf.remaining());
+ assertEquals(slice.capacity(), buf.remaining());
+ try {
+ slice.reset();
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (InvalidMarkException e) {
+ // expected
+ }
+
+ // slice share the same content with buf
+ if (!slice.isReadOnly()) {
+ loadTestData1(slice);
+ assertContentLikeTestData1(buf, 1, (short) 0, slice.capacity());
+ buf.put(2, (short) 500);
+ assertEquals(slice.get(1), 500);
+ }
+ }
+
+ public void testToString() {
+ String str = buf.toString();
+ assertTrue(str.indexOf("Short") >= 0 || str.indexOf("short") >= 0);
+ assertTrue(str.indexOf("" + buf.position()) >= 0);
+ assertTrue(str.indexOf("" + buf.limit()) >= 0);
+ assertTrue(str.indexOf("" + buf.capacity()) >= 0);
+ }
+
+ void loadTestData1(short array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (short) i;
+ }
+ }
+
+ void loadTestData2(short array[], int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ array[offset + i] = (short) (length - i);
+ }
+ }
+
+ void loadTestData1(ShortBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (short) i);
+ }
+ }
+
+ void loadTestData2(ShortBuffer buf) {
+ buf.clear();
+ for (int i = 0; i < buf.capacity(); i++) {
+ buf.put(i, (short) (buf.capacity() - i));
+ }
+ }
+
+ void assertContentEquals(ShortBuffer buf, short array[],
+ int offset, int length) {
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(i), array[offset + i]);
+ }
+ }
+
+ void assertContentEquals(ShortBuffer buf, ShortBuffer other) {
+ assertEquals(buf.capacity(), other.capacity());
+ for (int i = 0; i < buf.capacity(); i++) {
+ assertEquals(buf.get(i), other.get(i));
+ }
+ }
+
+ void assertContentLikeTestData1(ShortBuffer buf,
+ int startIndex, short startValue, int length) {
+ short value = startValue;
+ for (int i = 0; i < length; i++) {
+ assertEquals(buf.get(startIndex + i), value);
+ value = (short) (value + 1);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceDirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceDirectByteBufferTest.java
new file mode 100644
index 0000000..c00694a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceDirectByteBufferTest.java
@@ -0,0 +1,32 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class SliceDirectByteBufferTest extends DirectByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf.position(1).limit(BUFFER_LENGTH-1);
+ buf = buf.slice();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceHeapByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceHeapByteBufferTest.java
new file mode 100644
index 0000000..949c9a0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceHeapByteBufferTest.java
@@ -0,0 +1,33 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class SliceHeapByteBufferTest extends HeapByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf.position(1).limit(BUFFER_LENGTH-1);
+ buf = buf.slice();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceWrappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceWrappedByteBufferTest.java
new file mode 100644
index 0000000..7fabd8d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/SliceWrappedByteBufferTest.java
@@ -0,0 +1,33 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+
+public class SliceWrappedByteBufferTest extends WrappedByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf.position(1).limit(BUFFER_LENGTH-1);
+ buf = buf.slice();
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedByteBufferTest.java
new file mode 100644
index 0000000..9475e7b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedByteBufferTest.java
@@ -0,0 +1,97 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ByteBuffer;
+
+public class WrappedByteBufferTest extends ByteBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = ByteBuffer.wrap(new byte[BUFFER_LENGTH]);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ buf = null;
+ baseBuf = null;
+ }
+
+ /**
+ * @tests java.nio.ByteBuffer#allocate(byte[],int,int)
+ *
+ */
+ public void testWrappedByteBuffer_IllegalArg() {
+ byte array[] = new byte[BUFFER_LENGTH];
+ try {
+ ByteBuffer.wrap(array, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ByteBuffer.wrap(array, BUFFER_LENGTH + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ByteBuffer.wrap(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ByteBuffer.wrap(array, 0, BUFFER_LENGTH + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ByteBuffer.wrap(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ByteBuffer.wrap(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ByteBuffer.wrap((byte[])null, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testIsDirect() {
+ assertFalse(buf.isDirect());
+ }
+
+ public void testHasArray() {
+ assertTrue(buf.hasArray());
+ }
+
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedCharBufferTest1.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedCharBufferTest1.java
new file mode 100644
index 0000000..a9a04e8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedCharBufferTest1.java
@@ -0,0 +1,84 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.CharBuffer;
+
+public class WrappedCharBufferTest1 extends CharBufferTest {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = CharBuffer.wrap(new char[BUFFER_LENGTH]);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ baseBuf = null;
+ buf = null;
+ }
+
+ /**
+ * @tests java.nio.CharBuffer#allocate(char[],int,int)
+ *
+ */
+ public void testWrappedCharBuffer_IllegalArg() {
+ char array[] = new char[BUFFER_LENGTH];
+ try {
+ CharBuffer.wrap(array, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap(array, BUFFER_LENGTH + 1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap(array, 0, BUFFER_LENGTH + 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap((char[])null, -1, 0);
+ fail("Should throw NPE"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedCharBufferTest2.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedCharBufferTest2.java
new file mode 100644
index 0000000..a5c222c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedCharBufferTest2.java
@@ -0,0 +1,128 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.BufferOverflowException;
+import java.nio.CharBuffer;
+import java.nio.ReadOnlyBufferException;
+
+public class WrappedCharBufferTest2 extends ReadOnlyCharBufferTest {
+ protected static final String TEST_STRING = "123456789abcdef12345";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = CharBuffer.wrap(TEST_STRING);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ baseBuf = null;
+ buf = null;
+ }
+
+ public void testWrappedCharSequence_IllegalArg() {
+ String str = TEST_STRING;
+ try {
+ CharBuffer.wrap(str, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap(str, 21, 21);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap(str, 2, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap(str, 0, 21);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ CharBuffer.wrap((String)null, -1, 21);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testArray() {
+ try {
+ buf.array();
+ fail("Should throw UnsupportedOperationException"); //$NON-NLS-1$
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ public void testPutcharArrayintint() {
+ char array[] = new char[1];
+ try {
+ buf.put(array, 0, array.length);
+ fail("Should throw ReadOnlyBufferException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException e) {
+ // expected
+ }
+ try {
+ buf.put((char[]) null, 0, 1);
+ fail("Should throw NullPointerException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException expected) {
+ } catch (NullPointerException expected) {
+ }
+ try {
+ buf.put(new char[buf.capacity() + 1], 0, buf.capacity() + 1);
+ fail("Should throw BufferOverflowException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException expected) {
+ } catch (BufferOverflowException expected) {
+ }
+ try {
+ buf.put(array, -1, array.length);
+ fail("Should throw IndexOutOfBoundsException"); //$NON-NLS-1$
+ } catch (ReadOnlyBufferException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void testPutCharBuffer() {
+ CharBuffer other = CharBuffer.allocate(1);
+ try {
+ buf.put(other);
+ fail();
+ } catch (ReadOnlyBufferException expected) {
+ }
+ try {
+ buf.put((CharBuffer) null);
+ fail();
+ } catch (ReadOnlyBufferException expected) {
+ } catch (NullPointerException expected) {
+ }
+ try {
+ buf.put(buf);
+ fail();
+ } catch (ReadOnlyBufferException expected) {
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedDoubleBufferTest.java
new file mode 100644
index 0000000..c371afa
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedDoubleBufferTest.java
@@ -0,0 +1,87 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.DoubleBuffer;
+
+public class WrappedDoubleBufferTest extends DoubleBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = DoubleBuffer.wrap(new double[BUFFER_LENGTH]);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ baseBuf = null;
+ buf = null;
+ }
+
+ /**
+ * @tests java.nio.CharBuffer#allocate(char[],int,int)
+ *
+ */
+ public void testWrappedDoubleuffer_IllegalArg() {
+ double array[] = new double[20];
+ try {
+ DoubleBuffer.wrap(array, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ DoubleBuffer.wrap(array, 21, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ DoubleBuffer.wrap(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ DoubleBuffer.wrap(array, 0, 21);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ DoubleBuffer.wrap(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ DoubleBuffer.wrap(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ DoubleBuffer.wrap((double[])null, -1, 0);
+ fail("Should throw NPE"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ }
+
+ DoubleBuffer buf = DoubleBuffer.wrap(array, 2, 16);
+ assertEquals(buf.position(), 2);
+ assertEquals(buf.limit(), 18);
+ assertEquals(buf.capacity(), 20);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedFloatBufferTest.java
new file mode 100644
index 0000000..e68d9bc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedFloatBufferTest.java
@@ -0,0 +1,87 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.FloatBuffer;
+
+public class WrappedFloatBufferTest extends FloatBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = FloatBuffer.wrap(new float[BUFFER_LENGTH]);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ baseBuf = null;
+ buf = null;
+ }
+
+ /**
+ * @tests java.nio.CharBuffer#allocate(char[],int,int)
+ *
+ */
+ public void testWrappedFloatBuffer_IllegalArg() {
+ float array[] = new float[20];
+ try {
+ FloatBuffer.wrap(array, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ FloatBuffer.wrap(array, 21, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ FloatBuffer.wrap(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ FloatBuffer.wrap(array, 0, 21);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ FloatBuffer.wrap(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ FloatBuffer.wrap(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ FloatBuffer.wrap((float[])null, -1, 0);
+ fail("Should throw NPE"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ }
+
+ FloatBuffer buf = FloatBuffer.wrap(array, 2, 16);
+ assertEquals(buf.position(), 2);
+ assertEquals(buf.limit(), 18);
+ assertEquals(buf.capacity(), 20);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedIntBufferTest.java
new file mode 100644
index 0000000..b1d2bf9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedIntBufferTest.java
@@ -0,0 +1,87 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.IntBuffer;
+
+public class WrappedIntBufferTest extends IntBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = IntBuffer.wrap(new int[BUFFER_LENGTH]);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ baseBuf = null;
+ buf = null;
+ }
+
+ /**
+ * @tests java.nio.CharBuffer#allocate(char[],int,int)
+ *
+ */
+ public void testWrappedIntBuffer_IllegalArg() {
+ int array[] = new int[20];
+ try {
+ IntBuffer.wrap(array, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ IntBuffer.wrap(array, 21, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ IntBuffer.wrap(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ IntBuffer.wrap(array, 0, 21);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ IntBuffer.wrap(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ IntBuffer.wrap(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ IntBuffer.wrap((int[])null, -1, 0);
+ fail("Should throw NPE"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ }
+
+ IntBuffer buf = IntBuffer.wrap(array, 2, 16);
+ assertEquals(buf.position(), 2);
+ assertEquals(buf.limit(), 18);
+ assertEquals(buf.capacity(), 20);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedLongBufferTest.java
new file mode 100644
index 0000000..9bc14c8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedLongBufferTest.java
@@ -0,0 +1,87 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.LongBuffer;
+
+public class WrappedLongBufferTest extends LongBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = LongBuffer.wrap(new long[BUFFER_LENGTH]);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ baseBuf = null;
+ buf = null;
+ }
+
+ /**
+ * @tests java.nio.CharBuffer#allocate(char[],int,int)
+ *
+ */
+ public void testWrappedLongBuffer_IllegalArg() {
+ long array[] = new long[20];
+ try {
+ LongBuffer.wrap(array, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ LongBuffer.wrap(array, 21, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ LongBuffer.wrap(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ LongBuffer.wrap(array, 0, 21);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ LongBuffer.wrap(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ LongBuffer.wrap(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ LongBuffer.wrap((long[])null, -1, 0);
+ fail("Should throw NPE"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ }
+
+ LongBuffer buf = LongBuffer.wrap(array, 2, 16);
+ assertEquals(buf.position(), 2);
+ assertEquals(buf.limit(), 18);
+ assertEquals(buf.capacity(), 20);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedShortBufferTest.java
new file mode 100644
index 0000000..4c797b5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/WrappedShortBufferTest.java
@@ -0,0 +1,87 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio;
+
+import java.nio.ShortBuffer;
+
+public class WrappedShortBufferTest extends ShortBufferTest {
+ protected void setUp() throws Exception {
+ super.setUp();
+ buf = ShortBuffer.wrap(new short[BUFFER_LENGTH]);
+ loadTestData1(buf);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ baseBuf = null;
+ buf = null;
+ }
+
+ /**
+ * @tests java.nio.CharBuffer#allocate(char[],int,int)
+ *
+ */
+ public void testWrappedShortBuffer_IllegalArg() {
+ short array[] = new short[20];
+ try {
+ ShortBuffer.wrap(array, -1, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ShortBuffer.wrap(array, 21, 0);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ShortBuffer.wrap(array, 0, -1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ShortBuffer.wrap(array, 0, 21);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ShortBuffer.wrap(array, Integer.MAX_VALUE, 1);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ShortBuffer.wrap(array, 1, Integer.MAX_VALUE);
+ fail("Should throw Exception"); //$NON-NLS-1$
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ShortBuffer.wrap((short[])null, -1, 0);
+ fail("Should throw NPE"); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ }
+
+ ShortBuffer buf = ShortBuffer.wrap(array, 2, 16);
+ assertEquals(buf.position(), 2);
+ assertEquals(buf.limit(), 18);
+ assertEquals(buf.capacity(), 20);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/AlreadyConnectedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/AlreadyConnectedExceptionTest.java
new file mode 100644
index 0000000..8e2a0e6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/AlreadyConnectedExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.AlreadyConnectedException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for AlreadyConnectedException
+ */
+public class AlreadyConnectedExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.AlreadyConnectedException#AlreadyConnectedException()}
+ */
+ public void test_Constructor() {
+ AlreadyConnectedException e = new AlreadyConnectedException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new AlreadyConnectedException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new AlreadyConnectedException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/AsynchronousCloseExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/AsynchronousCloseExceptionTest.java
new file mode 100644
index 0000000..95eb9fb
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/AsynchronousCloseExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.AsynchronousCloseException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for AsynchronousCloseException
+ */
+public class AsynchronousCloseExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.AsynchronousCloseException#AsynchronousCloseException()}
+ */
+ public void test_Constructor() {
+ AsynchronousCloseException e = new AsynchronousCloseException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new AsynchronousCloseException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new AsynchronousCloseException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/CancelledKeyExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/CancelledKeyExceptionTest.java
new file mode 100644
index 0000000..25ee801
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/CancelledKeyExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.CancelledKeyException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for CancelledKeyException
+ */
+public class CancelledKeyExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.CancelledKeyException#CancelledKeyException()}
+ */
+ public void test_Constructor() {
+ CancelledKeyException e = new CancelledKeyException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new CancelledKeyException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new CancelledKeyException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ChannelsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ChannelsTest.java
new file mode 100644
index 0000000..561d661
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ChannelsTest.java
@@ -0,0 +1,616 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.WritableByteChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import junit.framework.TestCase;
+
+/**
+ * Note: the test case uses a temp text file named "test" which contains 31
+ * characters : "P@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]"
+ *
+ */
+
+public class ChannelsTest extends TestCase {
+ private static final String CODE_SET = "GB2312"; //$NON-NLS-1$
+
+ private static final String BAD_CODE_SET = "GB2313"; //$NON-NLS-1$
+
+ private FileInputStream fins;
+
+ private FileOutputStream fouts;
+
+ private final int writebufSize = 60;
+
+ private final int testNum = 10;
+
+ private final int fileSize = 31;// the file size
+
+ private File tmpFile;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ // Make the test file same in every test
+ tmpFile = File.createTempFile("test","tmp");
+ tmpFile.deleteOnExit();
+ this.writeFileSame();
+ }
+
+ protected void tearDown() throws Exception {
+ if (null != this.fins) {
+ this.fins.close();
+ this.fins = null;
+ }
+ if (null != this.fouts) {
+ this.fouts.close();
+ this.fouts = null;
+ }
+
+ tmpFile.delete();
+ super.tearDown();
+
+ }
+
+ private void writeFileSame() throws IOException {
+ this.fouts = new FileOutputStream(tmpFile);
+ byte[] bit = new byte[1];
+ bit[0] = 80;
+ this.fouts.write(bit);
+ this.fouts.flush();
+ String writebuf = ""; //$NON-NLS-1$
+ for (int val = 0; val < this.writebufSize / 2; val++) {
+ writebuf = writebuf + ((char) (val + 64));
+ }
+ this.fouts.write(writebuf.getBytes());
+ }
+
+ /*
+ * This private method is to assert if the file size is the same as the
+ * compare Number in the test
+ */
+ private void assertFileSizeSame(File fileToTest, int compareNumber)
+ throws IOException {
+ FileInputStream file = new FileInputStream(fileToTest);
+ assertEquals(file.available(), compareNumber);
+ file.close();
+ }
+
+ // test if new Channel to input is null
+ public void testNewChannelInputStream_InputNull() throws IOException {
+ ByteBuffer byteBuf = ByteBuffer.allocate(this.testNum);
+ this.fins = null;
+ int readres = this.testNum;
+ try {
+ ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
+ assertNotNull(rbChannel);
+ readres = rbChannel.read(byteBuf);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ assertEquals(this.testNum, readres);
+ }
+
+ // test if buffer to read is null
+ public void testNewChannelInputStream_BufferNull() throws IOException {
+ ByteBuffer byteBuf = ByteBuffer.allocate(this.testNum);
+ int readres = this.testNum;
+ this.fins = new FileInputStream(tmpFile);
+ ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
+ assertNotNull(rbChannel);
+ try {
+ readres = rbChannel.read(null);
+ fail();
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertEquals(this.testNum, readres);
+ readres = 0;
+ try {
+ readres = rbChannel.read(byteBuf);
+ } catch (NullPointerException e) {
+ fail();
+ }
+ assertEquals(this.testNum, readres);
+ }
+
+ /*
+ * Test method for 'java.nio.channels.Channels.NewChannel'
+ */
+ public void testNewChannelInputStream() throws IOException {
+ int bufSize = 10;
+ int readres = 0;
+ byte[] byteArray = new byte[bufSize];
+ ByteBuffer byteBuf = ByteBuffer.allocate(bufSize);
+ this.fins = new FileInputStream(tmpFile);
+ readres = this.fins.read(byteArray);
+
+ assertEquals(bufSize, readres);
+ assertFalse(0 == this.fins.available());
+
+ ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
+ // fins still reads.
+ assertFalse(0 == this.fins.available());
+ readres = this.fins.read(byteArray);
+ assertEquals(bufSize, readres);
+
+ // rbChannel also reads.
+ assertNotNull(rbChannel);
+ readres = rbChannel.read(byteBuf);
+
+ assertEquals(bufSize, readres);
+ InputStream ins = Channels.newInputStream(rbChannel);
+ assertNotNull(ins);
+ assertEquals(0, ins.available());
+ }
+
+ // test if fout to change is null
+ public void testNewChannelOutputStream_inputNull() throws IOException {
+ int writeres = this.testNum;
+ ByteBuffer writebuf = ByteBuffer.allocate(this.writebufSize);
+ for (int val = 0; val < this.writebufSize / 2; val++) {
+ writebuf.putChar((char) (val + 64));
+ }
+ this.fouts = null;
+ try {
+ WritableByteChannel rbChannel = Channels.newChannel(this.fouts);
+ writeres = rbChannel.write(writebuf);
+ assertEquals(0, writeres);
+
+ writebuf.flip();
+ writeres = rbChannel.write(writebuf);
+ fail("Should throw NPE.");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ // test if write buf is null
+ public void testNewChannelOutputStream_BufNull() throws IOException {
+ int writeres = this.testNum;
+ ByteBuffer writebuf = null;
+ try {
+ this.fouts = new FileOutputStream(tmpFile);
+ } catch (FileNotFoundException e) {
+ fail();
+ }
+
+ WritableByteChannel rbChannel = Channels.newChannel(this.fouts);
+ try {
+ writeres = rbChannel.write(writebuf);
+ fail();
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertEquals(this.testNum, writeres);
+ }
+
+ /*
+ * Test method for 'java.nio.channels.Channels.NewChannel(OutputStream)'
+ */
+ public void testNewChannelOutputStream() throws IOException {
+ int writeNum = 0;
+ ByteBuffer writebuf = ByteBuffer.allocateDirect(this.writebufSize);
+ for (int val = 0; val < this.writebufSize / 2; val++) {
+ writebuf.putChar((char) (val + 64));
+ }
+ this.fouts = new FileOutputStream(tmpFile);
+ WritableByteChannel testChannel = this.fouts.getChannel();
+ WritableByteChannel rbChannel = Channels.newChannel(this.fouts);
+
+ assertTrue(testChannel.isOpen());
+ assertTrue(rbChannel.isOpen());
+
+ byte[] bit = new byte[1];
+ bit[0] = 80;
+ this.fouts.write(bit);
+ this.fouts.flush();
+ this.fins = new FileInputStream(tmpFile);
+ assertEquals(this.fins.available(), 1);
+ this.fins.close();
+
+ writeNum = rbChannel.write(writebuf);
+ // write success ,but output null
+ assertEquals(0, writeNum);
+ // close of fouts does not affect on channel
+ this.fouts.close();
+ writeNum = rbChannel.write(writebuf);
+ assertEquals(0, writeNum);
+ try {
+ writeNum = testChannel.write(writebuf);
+ fail();
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ assertEquals(0, writeNum);
+ // close of rbchannel does affect on testchannel(same channel)
+ rbChannel.close();
+ try {
+ writeNum = testChannel.write(writebuf);
+ fail();
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testNewInputStreamReadableByteChannel_InputNull()
+ throws Exception {
+ byte[] readbuf = new byte[this.testNum];
+ this.fins = new FileInputStream(tmpFile);
+ ReadableByteChannel readbc = this.fins.getChannel();
+ assertEquals(this.fileSize, this.fins.available());
+ assertTrue(readbc.isOpen());
+
+ try {
+ InputStream testins = Channels.newInputStream(null);
+ assertNotNull(testins);
+ testins.read(readbuf);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testNewInputStreamReadableByteChannel() throws Exception {
+ ByteBuffer readbcbuf = ByteBuffer.allocateDirect(this.testNum);
+ byte[] readbuf = new byte[this.testNum];
+ this.fins = new FileInputStream(tmpFile);
+ ReadableByteChannel readbc = this.fins.getChannel();
+ assertEquals(this.fileSize, this.fins.available());
+ assertTrue(readbc.isOpen());
+ InputStream testins = Channels.newInputStream(readbc);
+ // read in testins and fins use the same pointer
+ testins.read(readbuf);
+ assertEquals(this.fins.available(), this.fileSize - this.testNum);
+ int readNum = readbc.read(readbcbuf);
+ assertEquals(readNum, this.testNum);
+ assertEquals(this.fins.available(), this.fileSize - this.testNum * 2);
+ testins.read(readbuf);
+ assertEquals(this.fins.available(), this.fileSize - this.testNum * 3);
+ // readbc.close() affect testins
+ readbc.close();
+ assertFalse(readbc.isOpen());
+ try {
+ testins.read(readbuf);
+ fail();
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testNewOutputStreamWritableByteChannel_InputNull()
+ throws Exception {
+ byte[] writebuf = new byte[this.testNum];
+ try {
+ OutputStream testouts = Channels.newOutputStream(null);
+ assertNotNull(testouts);
+ testouts.write(writebuf);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ WritableByteChannel writebc = Channels.newChannel((OutputStream) null);
+ assertTrue(writebc.isOpen());
+ OutputStream testoutputS = Channels.newOutputStream(writebc);
+ testoutputS.write(writebuf);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testNewOutputStreamWritableByteChannel() throws Exception {
+ byte[] writebuf = new byte[this.testNum];
+ ByteBuffer writebcbuf = ByteBuffer.allocateDirect(this.testNum);
+ this.fouts = new FileOutputStream(tmpFile);
+ WritableByteChannel writebc = this.fouts.getChannel();
+
+ assertTrue(writebc.isOpen());
+ OutputStream testouts = Channels.newOutputStream(writebc);
+
+ // read in testins and fins use the same pointer
+ testouts.write(writebuf);
+ this.assertFileSizeSame(tmpFile, this.testNum);
+ writebc.write(writebcbuf);
+ this.assertFileSizeSame(tmpFile, this.testNum * 2);
+ testouts.write(writebuf);
+ this.assertFileSizeSame(tmpFile, this.testNum * 3);
+ // readbc.close() affect testins
+ writebc.close();
+ assertFalse(writebc.isOpen());
+ try {
+ testouts.write(writebuf);
+ fail();
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testnewReaderCharsetError() throws Exception {
+ this.fins = new FileInputStream(tmpFile);
+
+ ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
+ try {
+ Channels.newReader(rbChannel, Charset.forName(BAD_CODE_SET)
+ .newDecoder(), //$NON-NLS-1$
+ -1);
+ fail();
+ } catch (UnsupportedCharsetException e) {
+ // correct
+ }
+ }
+
+ public void testnewWriterCharsetError() throws Exception {
+ this.fouts = new FileOutputStream(tmpFile);
+ WritableByteChannel wbChannel = Channels.newChannel(this.fouts);
+ try {
+ Channels.newWriter(wbChannel, Charset.forName(BAD_CODE_SET)
+ .newEncoder(), -1);
+ fail();
+ } catch (UnsupportedCharsetException e) {
+ // correct
+ }
+ }
+
+ /*
+ * Test method for
+ * 'java.nio.channels.Channels.newReader(ReadableByteChannel, String)'
+ */
+ public void testNewReaderReadableByteChannelString_InputNull()
+ throws IOException {
+ int bufSize = this.testNum;
+ int readres = 0;
+ CharBuffer charBuf = CharBuffer.allocate(bufSize);
+ this.fins = new FileInputStream(tmpFile);
+ // channel null
+ Reader testReader;
+ try {
+ testReader = Channels.newReader(null, Charset.forName(CODE_SET).newDecoder(), -1);
+ assertNotNull(testReader);
+ assertFalse(testReader.ready());
+ readres = testReader.read((CharBuffer) null);
+ fail();
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertEquals(0, readres);
+
+ this.fins = null;
+ // channel with null inputs
+ try {
+ ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
+ testReader = Channels.newReader(rbChannel, Charset.forName(CODE_SET).newDecoder(), -1);
+ assertNotNull(testReader);
+ assertFalse(testReader.ready());
+ readres = testReader.read(charBuf);
+ fail();
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ /*
+ * Test method for
+ * 'java.nio.channels.Channels.newReader(ReadableByteChannel, String)'
+ */
+ public void testNewReaderReadableByteChannelString_internalBufferZero()
+ throws IOException {
+ int bufSize = this.testNum;
+ int readres = 0;
+ CharBuffer charBuf = CharBuffer.allocate(bufSize);
+ this.fins = new FileInputStream(tmpFile);
+ // channel null
+ Reader testReader;
+ try {
+ testReader = Channels.newReader(null, Charset.forName(CODE_SET).newDecoder(), 0);
+ assertNotNull(testReader);
+ assertFalse(testReader.ready());
+ readres = testReader.read((CharBuffer) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ assertEquals(0, readres);
+
+ this.fins = null;
+ // channel with null inputs
+ try {
+ ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
+ testReader = Channels.newReader(rbChannel, Charset.forName(CODE_SET).newDecoder(), -1);
+ assertNotNull(testReader);
+ assertFalse(testReader.ready());
+ readres = testReader.read(charBuf);
+ fail();
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ /*
+ * Test method for
+ * 'java.nio.channels.Channels.newReader(ReadableByteChannel, String)'
+ */
+ public void testNewReaderReadableByteChannelString() throws IOException {
+ int bufSize = this.testNum;
+ int readres = 0;
+ CharBuffer charBuf = CharBuffer.allocate(bufSize);
+ this.fins = new FileInputStream(tmpFile);
+ ReadableByteChannel rbChannel = Channels.newChannel(this.fins);
+ Reader testReader = Channels.newReader(rbChannel, Charset.forName(
+ CODE_SET).newDecoder(), //$NON-NLS-1$
+ -1);
+ Reader testReader_s = Channels.newReader(rbChannel, CODE_SET); //$NON-NLS-1$
+
+ assertEquals(this.fileSize, this.fins.available());
+ // not ready...
+ assertFalse(testReader.ready());
+ assertFalse(testReader_s.ready());
+ // still reads
+ readres = testReader.read(charBuf);
+ assertEquals(bufSize, readres);
+ assertEquals(0, this.fins.available());
+
+ try {
+ readres = testReader.read((CharBuffer) null);
+ fail();
+ } catch (NullPointerException e) {
+ // correct
+ }
+
+ readres = testReader_s.read(charBuf);
+ assertEquals(0, readres);
+ assertTrue(testReader.ready());
+ assertFalse(testReader_s.ready());
+ }
+
+ /*
+ * Zero-Buffer
+ */
+ public void testNewWriterWritableByteChannelString_internalBufZero()
+ throws IOException {
+
+ String writebuf = ""; //$NON-NLS-1$
+ for (int val = 0; val < this.writebufSize / 2; val++) {
+ writebuf = writebuf + ((char) (val + 64));
+ }
+ // null channel
+ try {
+ Writer testWriter = Channels.newWriter(null, Charset.forName(CODE_SET).newEncoder(), -1);
+ } catch (NullPointerException expected) {
+ }
+
+ // channel with null input
+ this.fouts = null;
+ try {
+ WritableByteChannel wbChannel = Channels.newChannel(this.fouts);
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /*
+ * this test cannot be passed when buffer set to 0!
+ */
+ public void testNewWriterWritableByteChannelString_InputNull()
+ throws IOException {
+ this.fouts = new FileOutputStream(tmpFile);
+ WritableByteChannel wbChannel = Channels.newChannel(this.fouts);
+ Writer testWriter = Channels.newWriter(wbChannel, Charset.forName(
+ CODE_SET).newEncoder(), //$NON-NLS-1$
+ 1);
+
+ String writebuf = ""; //$NON-NLS-1$
+ for (int val = 0; val < this.writebufSize / 2; val++) {
+ writebuf = writebuf + ((char) (val + 64));
+ }
+ // can write to buffer
+ testWriter.write(writebuf);
+ testWriter.flush();
+ testWriter.close();
+
+ }
+
+ /*
+ * Test method for
+ * 'java.nio.channels.Channels.newWriter(WritableByteChannel, String)'
+ */
+ public void testNewWriterWritableByteChannelString() throws IOException {
+ this.fouts = new FileOutputStream(tmpFile);
+ WritableByteChannel wbChannel = Channels.newChannel(this.fouts);
+ Writer testWriter = Channels.newWriter(wbChannel, CODE_SET); //$NON-NLS-1$
+ Writer testWriter_s = Channels.newWriter(wbChannel, Charset.forName(
+ CODE_SET).newEncoder(), //$NON-NLS-1$
+ -1);
+
+ String writebuf = ""; //$NON-NLS-1$
+ for (int val = 0; val < this.writebufSize / 2; val++) {
+ writebuf = writebuf + ((char) (val + 64));
+ }
+ byte[] bit = new byte[1];
+ bit[0] = 80;
+ this.fouts.write(bit);
+ this.assertFileSizeSame(tmpFile, 1);
+
+ // writer continues to write after '1',what the fouts write
+ testWriter.write(writebuf);
+ testWriter.flush();
+ this.assertFileSizeSame(tmpFile, this.writebufSize / 2 + 1);
+ // testwriter_s does not know if testwrite writes
+ testWriter_s.write(writebuf);
+ testWriter.flush();
+ this.assertFileSizeSame(tmpFile, this.writebufSize / 2 + 1);
+ // testwriter_s even does not know if himself writes?
+ testWriter_s.write(writebuf);
+ testWriter.flush();
+ this.assertFileSizeSame(tmpFile, this.writebufSize / 2 + 1);
+
+ // close the fouts, no longer writable for testWriter
+ for (int val = 0; val < this.writebufSize; val++) {
+ writebuf = writebuf + ((char) (val + 64));
+ }
+ this.fouts.close();
+ testWriter_s.write(writebuf);
+ testWriter.flush();
+ this.assertFileSizeSame(tmpFile, this.writebufSize / 2 + 1);
+ }
+
+ /**
+ * @tests java.nio.channels.Channels#newReader(ReadableByteChannel channel,
+ * String charsetName)
+ */
+ public void test_newReader_LReadableByteChannel_LString()
+ throws IOException {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(ssc.socket().getLocalSocketAddress());
+ sc.configureBlocking(false);
+ assertFalse(sc.isBlocking());
+
+ ssc.accept().close();
+ ssc.close();
+ assertFalse(sc.isBlocking());
+
+ Reader reader = Channels.newReader(sc, "UTF16");
+ try {
+ int i = reader.read();
+ fail("should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException expected) {
+ }
+
+ try {
+ Channels.newInputStream(sc).read();
+ fail("should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException expected) {
+ }
+
+ sc.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedByInterruptExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedByInterruptExceptionTest.java
new file mode 100644
index 0000000..30a486c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedByInterruptExceptionTest.java
@@ -0,0 +1,53 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.ClosedByInterruptException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for ClosedByInterruptException
+ */
+public class ClosedByInterruptExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.ClosedByInterruptException#ClosedByInterruptException()}
+ */
+ public void test_Constructor() {
+ ClosedByInterruptException e = new ClosedByInterruptException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new ClosedByInterruptException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new ClosedByInterruptException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedChannelExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedChannelExceptionTest.java
new file mode 100644
index 0000000..da1a68e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedChannelExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.ClosedChannelException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for ClosedChannelException
+ */
+public class ClosedChannelExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.ClosedChannelException#ClosedChannelException()}
+ */
+ public void test_Constructor() {
+ ClosedChannelException e = new ClosedChannelException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new ClosedChannelException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new ClosedChannelException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedSelectorExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedSelectorExceptionTest.java
new file mode 100644
index 0000000..8969f02
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ClosedSelectorExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.ClosedSelectorException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for ClosedSelectorException
+ */
+public class ClosedSelectorExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.ClosedSelectorException#ClosedSelectorException()}
+ */
+ public void test_Constructor() {
+ ClosedSelectorException e = new ClosedSelectorException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new ClosedSelectorException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new ClosedSelectorException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ConnectionPendingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ConnectionPendingExceptionTest.java
new file mode 100644
index 0000000..bce227d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ConnectionPendingExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.ConnectionPendingException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for ConnectionPendingException
+ */
+public class ConnectionPendingExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.ConnectionPendingException#ConnectionPendingException()}
+ */
+ public void test_Constructor() {
+ ConnectionPendingException e = new ConnectionPendingException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new ConnectionPendingException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new ConnectionPendingException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java
new file mode 100644
index 0000000..4469e01
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java
@@ -0,0 +1,2523 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.Inet6Address;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousCloseException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.NotYetConnectedException;
+import java.nio.channels.UnresolvedAddressException;
+import java.nio.channels.UnsupportedAddressTypeException;
+import java.nio.channels.spi.SelectorProvider;
+import junit.framework.TestCase;
+import libcore.io.IoUtils;
+
+/**
+ * Test for DatagramChannel
+ */
+public class DatagramChannelTest extends TestCase {
+
+ private static final int CAPACITY_NORMAL = 200;
+
+ private static final int CAPACITY_1KB = 1024;
+
+ private static final int CAPACITY_64KB = 65536;
+
+ private static final int CAPACITY_ZERO = 0;
+
+ private static final int CAPACITY_ONE = 1;
+
+ private static final int TIME_UNIT = 500;
+
+ private InetSocketAddress datagramSocket1Address;
+ private InetSocketAddress datagramSocket2Address;
+
+ private InetSocketAddress channel1Address;
+ private InetSocketAddress channel2Address;
+
+ private DatagramChannel channel1;
+ private DatagramChannel channel2;
+
+ private DatagramSocket datagramSocket1;
+ private DatagramSocket datagramSocket2;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ channel1 = DatagramChannel.open();
+ channel2 = DatagramChannel.open();
+
+ channel1.socket().bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
+ channel2.socket().bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
+
+ channel1Address = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
+ channel2Address = (InetSocketAddress) channel2.socket().getLocalSocketAddress();
+
+ this.datagramSocket1 = new DatagramSocket(0, Inet6Address.LOOPBACK);
+ this.datagramSocket2 = new DatagramSocket(0, Inet6Address.LOOPBACK);
+
+ datagramSocket1Address = (InetSocketAddress) datagramSocket1.getLocalSocketAddress();
+ datagramSocket2Address = (InetSocketAddress) datagramSocket2.getLocalSocketAddress();
+ }
+
+ protected void tearDown() throws Exception {
+ IoUtils.closeQuietly(channel1);
+ IoUtils.closeQuietly(channel2);
+ IoUtils.closeQuietly(datagramSocket1);
+ IoUtils.closeQuietly(datagramSocket2);
+
+ datagramSocket1Address = null;
+ datagramSocket2Address = null;
+ super.tearDown();
+ }
+
+ // -------------------------------------------------------------------
+ // Test for methods in abstract class.
+ // -------------------------------------------------------------------
+ /*
+ * Test method for 'java.nio.channels.DatagramChannel.validOps()'
+ */
+ public void testValidOps() {
+ MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
+ .provider());
+ MockDatagramChannel testMocknull = new MockDatagramChannel(null);
+ int val = this.channel1.validOps();
+ assertEquals(5, val);
+ assertEquals(val, testMock.validOps());
+ assertEquals(val, testMocknull.validOps());
+ }
+
+ /*
+ * Test method for 'java.nio.channels.DatagramChannel.open()'
+ */
+ public void testOpen() {
+ MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
+ .provider());
+ MockDatagramChannel testMocknull = new MockDatagramChannel(null);
+ assertNull(testMocknull.provider());
+ assertNotNull(testMock.provider());
+ assertEquals(this.channel1.provider(), testMock.provider());
+ assertEquals(5, testMock.validOps());
+ }
+
+ /*
+ * Test method for 'java.nio.channels.DatagramChannel.read(ByteBuffer)'
+ */
+ public void testReadByteBufferArray() throws IOException {
+ final int testNum = 0;
+ MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
+ .provider());
+ MockDatagramChannel testMocknull = new MockDatagramChannel(null);
+ int bufSize = 10;
+ ByteBuffer[] readBuf = null;
+ try {
+ this.channel1.read(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+
+ long readres;
+ try {
+ readres = testMock.read(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ readBuf = new ByteBuffer[bufSize];
+ try {
+ readres = this.channel1.read(readBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException expected) {
+ }
+
+ readres = testMock.read(readBuf);
+ assertEquals(testNum, readres);
+ readres = testMocknull.read(readBuf);
+ assertEquals(testNum, readres);
+ }
+
+ /*
+ * Test method for 'java.nio.channels.DatagramChannel.read(ByteBuffer)'
+ */
+ public void testReadByteBufferArray_BufNull() throws IOException {
+ MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
+ .provider());
+ MockDatagramChannel testMocknull = new MockDatagramChannel(null);
+
+ ByteBuffer[] readBuf = null;
+ try {
+ this.channel1.read(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ testMock.read(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ testMocknull.read(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /*
+ * Test method for 'java.nio.channels.DatagramChannel.write(ByteBuffer)'
+ */
+ public void testWriteByteBuffer() throws IOException {
+ MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
+ .provider());
+ MockDatagramChannel testMocknull = new MockDatagramChannel(null);
+ int bufSize = 10;
+ ByteBuffer[] readBuf = null;
+ try {
+ this.channel1.write(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ testMock.write(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ readBuf = new ByteBuffer[bufSize];
+ try {
+ this.channel1.write(readBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ long writeres = 0;
+ writeres = testMock.write(readBuf);
+
+ assertEquals(0, writeres);
+ writeres = testMocknull.write(readBuf);
+ assertEquals(0, writeres);
+ }
+
+ /*
+ * Test method for 'java.nio.channels.DatagramChannel.write(ByteBuffer)'
+ */
+ public void testWriteByteBuffer_Bufnull() throws IOException {
+ MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
+ .provider());
+ MockDatagramChannel testMocknull = new MockDatagramChannel(null);
+ ByteBuffer[] readBuf = null;
+ try {
+ this.channel1.write(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ testMock.write(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ testMocknull.write(readBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Test for socket()
+ // -------------------------------------------------------------------
+
+ /**
+ * Test method for 'DatagramChannelImpl.socket()'
+ */
+ public void testSocket_BasicStatusBeforeConnect() throws Exception {
+ final DatagramChannel dc = DatagramChannel.open();
+
+ assertFalse(dc.isConnected());// not connected
+ DatagramSocket s1 = dc.socket();
+
+ assertFalse(s1.isBound());
+ assertFalse(s1.isClosed());
+ assertFalse(s1.isConnected());
+ assertFalse(s1.getBroadcast());
+ assertFalse(s1.getReuseAddress());
+ assertNull(s1.getInetAddress());
+ assertTrue(s1.getLocalAddress().isAnyLocalAddress());
+ assertEquals(s1.getLocalPort(), 0);
+ assertNull(s1.getLocalSocketAddress());
+ assertEquals(s1.getPort(), -1);
+ assertTrue(s1.getReceiveBufferSize() >= 8192);
+ assertNull(s1.getRemoteSocketAddress());
+ assertFalse(s1.getReuseAddress());
+ assertTrue(s1.getSendBufferSize() >= 8192);
+ assertEquals(s1.getSoTimeout(), 0);
+ assertEquals(s1.getTrafficClass(), 0);
+
+ DatagramSocket s2 = dc.socket();
+ // same
+ assertSame(s1, s2);
+
+ dc.close();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.socket()'
+ */
+ public void testSocket_Block_BasicStatusAfterConnect() throws IOException {
+ final DatagramChannel dc = DatagramChannel.open();
+
+ dc.connect(datagramSocket1Address);
+ DatagramSocket s1 = dc.socket();
+ assertSocketAfterConnect(s1);
+ DatagramSocket s2 = dc.socket();
+ // same
+ assertSame(s1, s2);
+
+ dc.close();
+ }
+
+ public void testSocket_NonBlock_BasicStatusAfterConnect() throws IOException {
+ final DatagramChannel dc = DatagramChannel.open();
+ dc.connect(datagramSocket1Address);
+ dc.configureBlocking(false);
+
+ DatagramSocket s1 = dc.socket();
+ assertSocketAfterConnect(s1);
+ DatagramSocket s2 = dc.socket();
+ // same
+ assertSame(s1, s2);
+
+ dc.close();
+ }
+
+ private void assertSocketAfterConnect(DatagramSocket s) throws SocketException {
+ assertTrue(s.isBound());
+ assertFalse(s.isClosed());
+ assertTrue(s.isConnected());
+ assertFalse(s.getBroadcast());
+ assertFalse(s.getReuseAddress());
+ assertNotNull(s.getLocalSocketAddress());
+ assertEquals(s.getPort(), datagramSocket1Address.getPort());
+ assertTrue(s.getReceiveBufferSize() >= 8192);
+ // not same , but equals
+ assertNotSame(s.getRemoteSocketAddress(), datagramSocket1Address);
+ assertEquals(s.getRemoteSocketAddress(), datagramSocket1Address);
+ assertFalse(s.getReuseAddress());
+ assertTrue(s.getSendBufferSize() >= 8192);
+ assertEquals(s.getSoTimeout(), 0);
+ assertEquals(s.getTrafficClass(), 0);
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.socket()'
+ */
+ public void testSocket_ActionsBeforeConnect() throws IOException {
+ assertFalse(channel1.isConnected());// not connected
+ assertTrue(channel1.isBlocking());
+ DatagramSocket s = channel1.socket();
+
+ s.connect(datagramSocket2Address);
+ assertTrue(channel1.isConnected());
+ assertTrue(s.isConnected());
+
+ s.disconnect();
+ assertFalse(channel1.isConnected());
+ assertFalse(s.isConnected());
+
+ s.close();
+ assertTrue(s.isClosed());
+ assertFalse(channel1.isOpen());
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.socket()'
+ */
+ public void testSocket_Block_ActionsAfterConnect() throws IOException {
+ assertFalse(this.channel1.isConnected());// not connected
+ this.channel1.connect(datagramSocket1Address);
+ DatagramSocket s = this.channel1.socket();
+ assertSocketActionAfterConnect(s);
+ }
+
+ public void testSocket_NonBlock_ActionsAfterConnect() throws IOException {
+ this.channel1.connect(datagramSocket1Address);
+ this.channel1.configureBlocking(false);
+ DatagramSocket s = this.channel1.socket();
+ assertSocketActionAfterConnect(s);
+ }
+
+ private void assertSocketActionAfterConnect(DatagramSocket s) throws IOException {
+ assertEquals(s.getPort(), datagramSocket1Address.getPort());
+ try {
+ s.connect(datagramSocket2Address);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ assertTrue(this.channel1.isConnected());
+ assertTrue(s.isConnected());
+ // not changed
+ assertEquals(s.getPort(), datagramSocket1Address.getPort());
+
+ s.disconnect();
+ assertFalse(this.channel1.isConnected());
+ assertFalse(s.isConnected());
+
+ s.close();
+ assertTrue(s.isClosed());
+ assertFalse(this.channel1.isOpen());
+ }
+
+ // -------------------------------------------------------------------
+ // Test for isConnected()
+ // -------------------------------------------------------------------
+
+ /**
+ * Test method for 'DatagramChannelImpl.isConnected()'
+ */
+ public void testIsConnected_WithServer() throws IOException {
+ connectLocalServer();
+ disconnectAfterConnected();
+ this.datagramSocket1.close();
+ this.channel1.close();
+ assertFalse(this.channel1.isConnected());
+ }
+
+ // -------------------------------------------------------------------
+ // Test for connect()
+ // -------------------------------------------------------------------
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_BlockWithServer() throws IOException {
+ // blocking mode
+ assertTrue(this.channel1.isBlocking());
+ connectLocalServer();
+ datagramSocket1.close();
+ disconnectAfterConnected();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_BlockNoServer() throws IOException {
+ connectWithoutServer();
+ disconnectAfterConnected();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_NonBlockWithServer() throws IOException {
+ // Non blocking mode
+ this.channel1.configureBlocking(false);
+ connectLocalServer();
+ datagramSocket1.close();
+ disconnectAfterConnected();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_Null() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ try {
+ this.channel1.connect(null);
+ fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_UnsupportedType() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ class SubSocketAddress extends SocketAddress {
+ private static final long serialVersionUID = 1L;
+
+ public SubSocketAddress() {
+ super();
+ }
+ }
+ SocketAddress newTypeAddress = new SubSocketAddress();
+ try {
+ this.channel1.connect(newTypeAddress);
+ fail("Should throw an UnsupportedAddressTypeException here.");
+ } catch (UnsupportedAddressTypeException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_Unresolved() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ InetSocketAddress unresolved = new InetSocketAddress(
+ "unresolved address", 1080);
+ try {
+ this.channel1.connect(unresolved);
+ fail("Should throw an UnresolvedAddressException here."); //$NON-NLS-1$
+ } catch (UnresolvedAddressException e) {
+ // OK.
+ }
+ }
+
+ public void testConnect_EmptyHost() throws Exception {
+ assertFalse(this.channel1.isConnected());
+
+ assertEquals(this.channel1, this.channel1
+ .connect(new InetSocketAddress("", 1081))); //$NON-NLS-1$
+
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_ClosedChannelException() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ try {
+ this.channel1.connect(datagramSocket1Address);
+ fail("Should throw ClosedChannelException."); //$NON-NLS-1$
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_IllegalStateException() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ this.channel1.connect(datagramSocket1Address);
+ assertTrue(this.channel1.isConnected());
+ // connect after connected.
+ try {
+ this.channel1.connect(datagramSocket1Address);
+ fail("Should throw IllegalStateException."); //$NON-NLS-1$
+ } catch (IllegalStateException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
+ */
+ public void testConnect_CheckOpenBeforeStatus() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ this.channel1.connect(datagramSocket1Address);
+ assertTrue(this.channel1.isConnected());
+ // connect after connected.
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ // checking open is before checking status.
+ try {
+ this.channel1.connect(datagramSocket1Address);
+ fail("Should throw ClosedChannelException."); //$NON-NLS-1$
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ }
+
+ private void disconnectAfterConnected() throws IOException {
+ assertTrue(this.channel1.isConnected());
+ this.channel1.disconnect();
+ assertFalse(this.channel1.isConnected());
+ }
+
+ private void disconnectAfterClosed() throws IOException {
+ assertFalse(this.channel1.isOpen());
+ assertFalse(this.channel1.isConnected());
+ this.channel1.disconnect();
+ assertFalse(this.channel1.isConnected());
+ }
+
+ private void connectLocalServer() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ assertTrue(this.datagramSocket1.isBound());
+ assertSame(this.channel1, this.channel1.connect(datagramSocket1Address));
+ assertTrue(this.channel1.isConnected());
+ }
+
+ private void connectWithoutServer() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ this.datagramSocket1.close();
+ assertTrue(this.datagramSocket1.isClosed());
+ assertSame(this.channel1, this.channel1.connect(datagramSocket1Address));
+ assertTrue(this.channel1.isConnected());
+ }
+
+ // -------------------------------------------------------------------
+ // Test for disconnect()
+ // -------------------------------------------------------------------
+
+ /**
+ * Test method for 'DatagramChannelImpl.disconnect()'
+ */
+ public void testDisconnect_BeforeConnect() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ assertEquals(this.channel1, this.channel1.disconnect());
+ assertFalse(this.channel1.isConnected());
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.disconnect()'
+ */
+ public void testDisconnect_UnconnectedClosed() throws IOException {
+ assertFalse(this.channel1.isConnected());
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ assertEquals(this.channel1, this.channel1.disconnect());
+ assertFalse(this.channel1.isConnected());
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.disconnect()'
+ */
+ public void testDisconnect_BlockWithServerChannelClosed()
+ throws IOException {
+ assertTrue(this.channel1.isBlocking());
+ connectLocalServer();
+ // disconnect after channel close
+ this.channel1.close();
+ disconnectAfterClosed();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.disconnect()'
+ */
+ public void testDisconnect_NonBlockWithServerChannelClosed()
+ throws IOException {
+ this.channel1.configureBlocking(false);
+ connectLocalServer();
+ // disconnect after channel close
+ this.channel1.close();
+ disconnectAfterClosed();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.disconnect()'
+ */
+ public void testDisconnect_BlockWithServerServerClosed() throws IOException {
+ assertTrue(this.channel1.isBlocking());
+ connectLocalServer();
+ // disconnect after server close
+ this.datagramSocket1.close();
+ assertTrue(this.channel1.isOpen());
+ assertTrue(this.channel1.isConnected());
+ disconnectAfterConnected();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.disconnect()'
+ */
+ public void testDisconnect_NonBlockWithServerServerClosed()
+ throws IOException {
+ this.channel1.configureBlocking(false);
+ assertFalse(this.channel1.isBlocking());
+ connectLocalServer();
+ // disconnect after server close
+ this.datagramSocket1.close();
+ assertTrue(this.channel1.isOpen());
+ assertTrue(this.channel1.isConnected());
+ disconnectAfterConnected();
+ }
+
+ // -------------------------------------------------------------------
+ // Test for receive(): Behavior Without Server.
+ // -------------------------------------------------------------------
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_UnconnectedNull() throws Exception {
+ assertFalse(this.channel1.isConnected());
+ try {
+ this.channel1.receive(null);
+ fail("Should throw a NPE here."); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_UnconnectedReadonly() throws Exception {
+ assertFalse(this.channel1.isConnected());
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
+ .asReadOnlyBuffer();
+ assertTrue(dst.isReadOnly());
+ try {
+ this.channel1.receive(dst);
+ fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_UnconnectedBufEmpty() throws Exception {
+ this.channel1.configureBlocking(false);
+ assertFalse(this.channel1.isConnected());
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ assertNull(this.channel1.receive(dst));
+ }
+
+ public void testReceive_UnboundBufZero() throws Exception {
+ DatagramChannel dc = DatagramChannel.open();
+
+ assertFalse(dc.isConnected());
+ assertFalse(dc.socket().isBound());
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ZERO);
+ assertNull(dc.receive(dst));
+
+ dc.close();
+ }
+
+ public void testReceive_UnboundBufNotEmpty() throws Exception {
+ DatagramChannel dc = DatagramChannel.open();
+ assertFalse(dc.isConnected());
+ assertFalse(dc.socket().isBound());
+
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ // buf is not empty
+ dst.put((byte) 88);
+ assertEquals(dst.position() + CAPACITY_NORMAL - 1, dst.limit());
+ assertNull(dc.receive(dst));
+
+ dc.close();
+ }
+
+ public void testReceive_UnboundBufFull() throws Exception {
+ DatagramChannel dc = DatagramChannel.open();
+
+ assertFalse(dc.isConnected());
+ assertFalse(dc.socket().isBound());
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ONE);
+
+ // buf is full
+ dst.put((byte) 88);
+ assertEquals(dst.position(), dst.limit());
+ assertNull(dc.receive(dst));
+
+ dc.close();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_UnconnectedClose() throws Exception {
+ assertFalse(this.channel1.isConnected());
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ try {
+ assertNull(this.channel1.receive(dst));
+ fail("Should throw a ClosedChannelException here."); //$NON-NLS-1$
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_UnconnectedCloseNull() throws Exception {
+ assertFalse(this.channel1.isConnected());
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ // checking buffer before checking open
+ try {
+ this.channel1.receive(null);
+ fail("Should throw a NPE here."); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_UnconnectedCloseReadonly() throws Exception {
+ assertFalse(this.channel1.isConnected());
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
+ .asReadOnlyBuffer();
+ assertTrue(dst.isReadOnly());
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ try {
+ this.channel1.receive(dst);
+ fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerBufEmpty() throws Exception {
+ this.channel1.configureBlocking(false);
+ receiveNonBlockNoServer(CAPACITY_NORMAL);
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_BlockNoServerNull() throws Exception {
+ assertTrue(this.channel1.isBlocking());
+ receiveNoServerNull();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerNull() throws Exception {
+ this.channel1.configureBlocking(false);
+ receiveNoServerNull();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_BlockNoServerReadonly() throws Exception {
+ assertTrue(this.channel1.isBlocking());
+ receiveNoServerReadonly();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerReadonly() throws Exception {
+ this.channel1.configureBlocking(false);
+ receiveNoServerReadonly();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerBufZero() throws Exception {
+ this.channel1.configureBlocking(false);
+ receiveNonBlockNoServer(CAPACITY_ZERO);
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerBufNotEmpty() throws Exception {
+ this.channel1.configureBlocking(false);
+ connectWithoutServer();
+ ByteBuffer dst = allocateNonEmptyBuf();
+ assertNull(this.channel1.receive(dst));
+ }
+
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerBufFull() throws Exception {
+ this.channel1.configureBlocking(false);
+ connectWithoutServer();
+ ByteBuffer dst = allocateFullBuf();
+ assertNull(this.channel1.receive(dst));
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_BlockNoServerChannelClose() throws Exception {
+ assertTrue(this.channel1.isBlocking());
+ receiveNoServerChannelClose();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerChannelClose() throws Exception {
+ this.channel1.configureBlocking(false);
+ receiveNoServerChannelClose();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_BlockNoServerCloseNull() throws Exception {
+ assertTrue(this.channel1.isBlocking());
+ receiveNoServerChannelCloseNull();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerCloseNull() throws Exception {
+ this.channel1.configureBlocking(false);
+ receiveNoServerChannelCloseNull();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_NonBlockNoServerCloseReadonly() throws Exception {
+ this.channel1.configureBlocking(false);
+ receiveNoServerChannelCloseReadonly();
+ }
+
+ /**
+ * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
+ */
+ public void testReceive_BlockNoServerCloseReadonly() throws Exception {
+ assertTrue(this.channel1.isBlocking());
+ receiveNoServerChannelCloseReadonly();
+ }
+
+ private void receiveNoServerNull() throws IOException {
+ connectWithoutServer();
+ try {
+ this.channel1.receive(null);
+ fail("Should throw a NPE here."); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // OK.
+ }
+ }
+
+ private void receiveNoServerReadonly() throws IOException {
+ connectWithoutServer();
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
+ .asReadOnlyBuffer();
+ assertTrue(dst.isReadOnly());
+ try {
+ this.channel1.receive(dst);
+ fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // OK.
+ }
+ }
+
+ private void receiveNonBlockNoServer(int size) throws IOException {
+ connectWithoutServer();
+ ByteBuffer dst = ByteBuffer.allocateDirect(size);
+ assertNull(this.channel1.receive(dst));
+ }
+
+ private void receiveNoServerChannelClose() throws IOException {
+ connectWithoutServer();
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ try {
+ assertNull(this.channel1.receive(dst));
+ fail("Should throw a ClosedChannelException here."); //$NON-NLS-1$
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ }
+
+ private void receiveNoServerChannelCloseNull() throws IOException {
+ connectWithoutServer();
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ try {
+ this.channel1.receive(null);
+ fail("Should throw a NPE here."); //$NON-NLS-1$
+ } catch (NullPointerException e) {
+ // OK.
+ }
+ }
+
+ private void receiveNoServerChannelCloseReadonly() throws IOException {
+ connectWithoutServer();
+ this.channel1.close();
+ assertFalse(this.channel1.isOpen());
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
+ .asReadOnlyBuffer();
+ assertTrue(dst.isReadOnly());
+ try {
+ this.channel1.receive(dst);
+ fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // OK.
+ }
+ }
+
+ private ByteBuffer allocateFullBuf() {
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ONE);
+ // buf is full
+ dst.put((byte) 88);
+ assertEquals(dst.position(), dst.limit());
+ return dst;
+ }
+
+ private ByteBuffer allocateNonEmptyBuf() {
+ ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ // buf is not empty
+ dst.put((byte) 88);
+ dst.put((byte) 99);
+ assertEquals(dst.position() + CAPACITY_NORMAL - 2, dst.limit());
+ return dst;
+ }
+
+ // -------------------------------------------------------------------
+ // Test for send(): Behavior without server.
+ // -------------------------------------------------------------------
+
+ private void sendDataBlocking(InetSocketAddress addr, ByteBuffer writeBuf)
+ throws IOException {
+ InetSocketAddress ipAddr = addr;
+ assertEquals(CAPACITY_NORMAL, this.channel1.send(writeBuf, ipAddr));
+ assertTrue(this.channel1.isOpen());
+ assertTrue(this.channel1.isBlocking());
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ }
+
+ private void sendDataNonBlocking(InetSocketAddress addr, ByteBuffer writeBuf)
+ throws IOException {
+ InetSocketAddress ipAddr = addr;
+ this.channel1.configureBlocking(false);
+ assertEquals(CAPACITY_NORMAL, this.channel1.send(writeBuf, ipAddr));
+ assertTrue(this.channel1.isOpen());
+ assertFalse(this.channel1.isBlocking());
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ }
+
+ /*
+ * Test method for 'DatagramChannelImpl.send(ByteBuffer, SocketAddress)'
+ */
+ public void testSend_NoServerBlockingCommon() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ sendDataBlocking(datagramSocket1Address, writeBuf);
+ }
+
+ public void testSend_NoServerNonblockingCommon() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ sendDataNonBlocking(datagramSocket1Address, writeBuf);
+ }
+
+ public void testSend_NoServerTwice() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ sendDataBlocking(datagramSocket1Address, writeBuf);
+ // can not buffer twice!
+ assertEquals(0, this.channel1.send(writeBuf, datagramSocket1Address));
+ try {
+ channel1.send(writeBuf, datagramSocket2Address);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // correct
+ }
+ }
+
+ public void testSend_NoServerNonBlockingTwice() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ sendDataNonBlocking(datagramSocket1Address, writeBuf);
+ // can not buffer twice!
+ assertEquals(0, this.channel1.send(writeBuf, datagramSocket1Address));
+ try {
+ channel1.send(writeBuf, datagramSocket2Address);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // correct
+ }
+ }
+
+ public void testSend_NoServerBufNull() throws IOException {
+ try {
+ sendDataBlocking(datagramSocket1Address, null);
+ fail("Should throw a NPE here.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ public void testSend_NoServerBufNullTwice() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ try {
+ sendDataBlocking(datagramSocket1Address, null);
+ fail("Should throw a NPE here.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ sendDataBlocking(datagramSocket1Address, writeBuf);
+ try {
+ channel1.send(null, datagramSocket2Address);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ public void testSend_NoServerAddrNull() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ try {
+ sendDataBlocking(null, writeBuf);
+ fail("Should throw a NPE here.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ public void testSend_NoServerAddrNullTwice() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ try {
+ sendDataBlocking(null, writeBuf);
+ fail("Should throw a NPE here.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ sendDataBlocking(datagramSocket1Address, writeBuf);
+ try {
+ channel1.send(writeBuf, null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Test for receive()and send(): Send and Receive with Real Data
+ // -------------------------------------------------------------------
+
+ public void testReceiveSend_Block_Normal() throws Exception {
+ sendOnChannel2("some normal string in testReceiveSend_Normal",
+ channel1Address);
+ receiveOnChannel1AndClose(CAPACITY_NORMAL, channel2Address,
+ "some normal string in testReceiveSend_Normal");
+ }
+
+ public void testReceiveSend_NonBlock_NotBound() throws Exception {
+ // not bound
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+ sendOnChannel2("some normal string in testReceiveSend_Normal",
+ datagramSocket2Address);
+ ByteBuffer buf = ByteBuffer.wrap(new byte[CAPACITY_NORMAL]);
+ assertNull(this.channel1.receive(buf));
+ }
+
+ public void testReceiveSend_Block_Normal_S2C() throws Exception {
+ sendOnDatagramSocket1(
+ "some normal string in testReceiveSend_Normal_S2C", channel1Address);
+ receiveOnChannel1AndClose(CAPACITY_NORMAL, datagramSocket1Address,
+ "some normal string in testReceiveSend_Normal_S2C");
+ }
+
+ public void testReceiveSend_Block_Normal_C2S() throws Exception {
+ String str1 = "some normal string in testReceiveSend_Normal_C2S";
+ sendOnChannel2(str1, datagramSocket1Address);
+ receiveOnDatagramSocket1(CAPACITY_NORMAL, str1);
+ }
+
+ public void testReceiveSend_NonBlock_Normal_C2S() throws Exception {
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+ String str1 = "some normal string in testReceiveSend_Normal_C2S";
+ sendOnChannel2(str1, datagramSocket1Address);
+ receiveOnDatagramSocket1(CAPACITY_NORMAL, str1);
+ }
+
+ public void testReceiveSend_Normal_S2S() throws Exception {
+ String msg = "normal string in testReceiveSend_Normal_S2S";
+ DatagramPacket rdp = new DatagramPacket(msg.getBytes(), msg.length(),
+ datagramSocket2Address);
+ this.datagramSocket1.send(rdp);
+ byte[] buf = new byte[CAPACITY_NORMAL];
+ this.datagramSocket2.setSoTimeout(TIME_UNIT);
+ rdp = new DatagramPacket(buf, buf.length);
+ this.datagramSocket2.receive(rdp);
+ assertEquals(new String(buf, 0, CAPACITY_NORMAL).trim(), msg);
+ }
+
+ public void testReceiveSend_Block_Empty() throws Exception {
+ sendOnChannel2("", channel1Address);
+ receiveOnChannel1AndClose(CAPACITY_NORMAL, channel2Address, "");
+ }
+
+ public void testReceiveSend_NonBlock_Empty() throws Exception {
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+ sendOnChannel2("", channel1Address);
+ receiveOnChannel1AndClose(CAPACITY_NORMAL, channel2Address, "");
+ }
+
+ public void testReceiveSend_Block_Empty_S2C() throws Exception {
+ sendOnDatagramSocket1("", channel1Address);
+ receiveOnChannel1AndClose(CAPACITY_NORMAL, datagramSocket1Address, "");
+ }
+
+ public void testReceiveSend_NonBlock_Empty_S2C() throws Exception {
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+ sendOnDatagramSocket1("", channel1Address);
+ receiveOnChannel1AndClose(CAPACITY_NORMAL, datagramSocket1Address, "");
+ }
+
+ public void testReceiveSend_Block_Empty_C2S() throws Exception {
+ sendOnChannel2("", datagramSocket1Address);
+ receiveOnDatagramSocket1(CAPACITY_NORMAL, "");
+ }
+
+ public void testReceiveSend_NonBlock_Empty_C2S() throws Exception {
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+ sendOnChannel2("", datagramSocket1Address);
+ receiveOnDatagramSocket1(CAPACITY_NORMAL, "");
+ }
+
+ public void testReceiveSend_Empty_S2S() throws Exception {
+ String msg = "";
+ DatagramPacket rdp = new DatagramPacket(msg.getBytes(), msg.length(),
+ datagramSocket2Address);
+ this.datagramSocket1.send(rdp);
+ byte[] buf = new byte[CAPACITY_NORMAL];
+ this.datagramSocket2.setSoTimeout(TIME_UNIT);
+ rdp = new DatagramPacket(buf, buf.length);
+ this.datagramSocket2.receive(rdp);
+ assertEquals(new String(buf, 0, CAPACITY_NORMAL).trim(), msg);
+ }
+
+ public void testReceiveSend_Block_Oversize() throws Exception {
+ sendOnChannel2("0123456789", channel1Address);
+ receiveOnChannel1AndClose(5, channel2Address, "01234");
+ }
+
+ public void testReceiveSend_Block_Oversize_C2S() throws Exception {
+ sendOnChannel2("0123456789", datagramSocket1Address);
+ receiveOnDatagramSocket1(5, "01234");
+ }
+
+ public void testReceiveSend_NonBlock_Oversize_C2S() throws Exception {
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+ sendOnChannel2("0123456789", datagramSocket1Address);
+ receiveOnDatagramSocket1(5, "01234");
+ }
+
+ public void testReceiveSend_Block_Oversize_S2C() throws Exception {
+ sendOnDatagramSocket1("0123456789", channel1Address);
+ receiveOnChannel1AndClose(5, datagramSocket1Address, "01234");
+ }
+
+ public void testReceiveSend_8K() throws Exception {
+ StringBuffer str8k = new StringBuffer();
+ for (int i = 0; i < 8 * CAPACITY_1KB; i++) {
+ str8k.append('a');
+ }
+ String str = str8k.toString();
+
+ sendOnChannel2(str, channel1Address);
+ receiveOnChannel1AndClose(8 * CAPACITY_1KB, channel2Address, str);
+ }
+
+ public void testReceiveSend_64K() throws Exception {
+ StringBuffer str64k = new StringBuffer();
+ for (int i = 0; i < CAPACITY_64KB; i++) {
+ str64k.append('a');
+ }
+ String str = str64k.toString();
+ try {
+ Thread.sleep(TIME_UNIT);
+ channel2.send(ByteBuffer.wrap(str.getBytes()), datagramSocket1Address);
+ fail("Should throw SocketException!");
+ } catch (SocketException expected) {
+ }
+ }
+
+ private void sendOnChannel2(String data, SocketAddress address)
+ throws IOException {
+ assertEquals(data.length(), channel2.send(ByteBuffer.wrap(data.getBytes()), address));
+ }
+
+ private void sendOnDatagramSocket1(String data, InetSocketAddress address)
+ throws Exception {
+ DatagramPacket rdp = new DatagramPacket(data.getBytes(), data.length(), address);
+ this.datagramSocket1.send(rdp);
+ }
+
+ private void receiveOnChannel1AndClose(int bufSize,
+ InetSocketAddress expectedAddress, String expectedString) throws IOException {
+ try {
+ ByteBuffer buf = ByteBuffer.wrap(new byte[bufSize]);
+ InetSocketAddress senderAddr;
+ long startTime = System.currentTimeMillis();
+ do {
+ senderAddr = (InetSocketAddress) this.channel1.receive(buf);
+ // continue loop when channel1 is non-blocking and no data was
+ // received.
+ if (channel1.isBlocking() || senderAddr != null) {
+ break;
+ }
+ // avoid dead loop
+ assertTimeout(startTime, 10000);
+ } while (true);
+
+ assertEquals(senderAddr.getAddress(), Inet6Address.LOOPBACK);
+ assertEquals(expectedAddress.getPort(), senderAddr.getPort());
+ assertEquals(new String(buf.array(), 0, buf.position()), expectedString);
+ } finally {
+ this.channel1.close();
+ }
+ }
+
+ /*
+ * Fails if the difference between current time and start time is greater
+ * than timeout.
+ */
+ private void assertTimeout(long startTime, long timeout) {
+ long currentTime = System.currentTimeMillis();
+ if ((currentTime - startTime) > timeout) {
+ fail("Timeout");
+ }
+ }
+
+ private void receiveOnDatagramSocket1(int bufSize, String expectedString)
+ throws IOException {
+ byte[] buf = new byte[bufSize];
+ this.datagramSocket1.setSoTimeout(6000);
+ DatagramPacket rdp = new DatagramPacket(buf, buf.length);
+ this.datagramSocket1.receive(rdp);
+ assertEquals(new String(buf, 0, bufSize).trim(), expectedString);
+ }
+
+ public void testRead_fromSend() throws Exception {
+ ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
+ String strHello = "hello";
+
+ this.channel1.connect(channel2Address);
+ this.channel2.send(ByteBuffer.wrap(strHello.getBytes()), channel1Address);
+
+ assertEquals(strHello.length(), this.channel1.read(buf));
+ assertAscii(buf, strHello);
+ }
+
+ public void testReceive_Peek_NoSecurity_Nonblocking() throws Exception {
+ String strHello = "hello";
+
+ sendOnChannel2(strHello, channel1Address);
+ this.channel1.configureBlocking(false);
+ // for accepted addr, no problem.
+ ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
+
+ InetSocketAddress source = (InetSocketAddress) this.channel1.receive(buf);
+ assertEquals(channel2Address, source);
+ assertAscii(buf, strHello);
+ }
+
+ private static void assertAscii(ByteBuffer b, String s) {
+ assertEquals(s.length(), b.position());
+ for (int i = 0; i < s.length(); ++i) {
+ assertEquals(s.charAt(i), b.get(i));
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Test for write()
+ // -------------------------------------------------------------------
+
+ private void connectWriteBuf(InetSocketAddress ipAddr, ByteBuffer buf)
+ throws IOException {
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(buf));
+ assertEquals(0, this.channel1.write(buf));
+ }
+
+ private void noconnectWrite(ByteBuffer buf) throws IOException {
+ try {
+ this.channel1.write(buf);
+ fail("should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ }
+
+ /*
+ * Test method for 'DatagramChannelImpl.write(ByteBuffer)'
+ */
+ public void testWriteByteBuffer_Block() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ connectWriteBuf(datagramSocket1Address, writeBuf);
+ }
+
+ public void testWriteByteBuffer_NonBlock() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ this.channel1.configureBlocking(false);
+ connectWriteBuf(datagramSocket1Address, writeBuf);
+ }
+
+ public void testWriteByteBuffer_Block_closed() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ noconnectWrite(writeBuf);
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ this.channel1.close();
+ try {
+ channel1.write(writeBuf);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBuffer_NonBlock_closed() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ // non block mode
+ this.channel1.configureBlocking(false);
+ noconnectWrite(writeBuf);
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ this.channel1.close();
+ try {
+ channel1.write(writeBuf);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBuffer_Block_BufNull() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(0);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ try {
+ this.channel1.write((ByteBuffer) null);
+ fail("Should throw NPE.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ try {
+ this.channel1.write((ByteBuffer) null);
+ fail("Should throw NPE.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertEquals(0, this.channel1.write(writeBuf));
+ datagramSocket1.close();
+ try {
+ this.channel1.write((ByteBuffer) null);
+ fail("Should throw NPE.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBuffer_NonBlock_BufNull() throws IOException {
+ ByteBuffer writeBuf = ByteBuffer.allocateDirect(0);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+
+ // non block mode
+ this.channel1.configureBlocking(false);
+
+ try {
+ this.channel1.write((ByteBuffer) null);
+ fail("Should throw NPE.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ try {
+ this.channel1.write((ByteBuffer) null);
+ fail("Should throw NPE.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertEquals(0, this.channel1.write(writeBuf));
+ datagramSocket1.close();
+ try {
+ this.channel1.write((ByteBuffer) null);
+ fail("Should throw NPE.");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ /*
+ * Test method for 'DatagramChannelImpl.write(ByteBuffer[], int, int)'
+ */
+ public void testWriteByteBufferArrayIntInt_Block() throws IOException {
+ ByteBuffer[] writeBuf = new ByteBuffer[2];
+ writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ try {
+ this.channel1.write(writeBuf, 0, 2);
+ fail("Should throw NotYetConnectedException.");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
+ // cannot be buffered again!
+ assertEquals(0, this.channel1.write(writeBuf, 0, 1));
+
+ }
+
+ public void testWriteByteBufferArrayIntInt_NonBlock() throws IOException {
+ ByteBuffer[] writeBuf = new ByteBuffer[2];
+ writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ // non-block mode
+ this.channel1.configureBlocking(false);
+ try {
+ this.channel1.write(writeBuf, 0, 2);
+ fail("Should throw NotYetConnectedException.");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
+ // cannot be buffered again!
+ assertEquals(0, this.channel1.write(writeBuf, 0, 1));
+
+ }
+
+ public void testWriteByteBufferArrayIntInt_NoConnectIndexBad()
+ throws IOException {
+ ByteBuffer[] writeBuf = new ByteBuffer[2];
+ writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ try {
+ this.channel1.write(writeBuf, -1, 2);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // correct
+ }
+ try {
+ this.channel1.write(writeBuf, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // correct
+ }
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
+ // cannot be buffered again!
+ assertEquals(0, this.channel1.write(writeBuf, 0, 1));
+ }
+
+ public void testWriteByteBufferArrayIntInt_ConnectedIndexBad()
+ throws IOException {
+ ByteBuffer[] writeBuf = new ByteBuffer[2];
+ writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ try {
+ this.channel1.write(writeBuf, -1, 2);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // correct
+ }
+ try {
+ this.channel1.write(writeBuf, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBufferArrayIntInt_BufNullNoConnect()
+ throws IOException {
+ ByteBuffer[] writeBuf = new ByteBuffer[2];
+ writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ try {
+ this.channel1.write(null, 0, 2);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ this.channel1.write(writeBuf, -1, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.write(writeBuf, 0, 3);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void testWriteByteBufferArrayIntInt_BufNullConnect()
+ throws IOException {
+ ByteBuffer[] writeBuf = new ByteBuffer[2];
+ writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ try {
+ this.channel1.write(null, 0, 2);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ this.channel1.write(writeBuf, 0, 3);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // correct
+ }
+ datagramSocket1.close();
+ try {
+ this.channel1.write(null, 0, 2);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Test for read()
+ // -------------------------------------------------------------------
+
+ /*
+ * Test method for 'DatagramChannelImpl.read(ByteBuffer)'
+ */
+ public void testReadByteBuffer() throws IOException {
+ ByteBuffer readBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ try {
+ this.channel1.read(readBuf);
+ fail("should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(datagramSocket1Address);
+ assertTrue(this.channel1.isConnected());
+ this.channel1.configureBlocking(false);
+ // note : blocking-mode will make the read process endless!
+ assertEquals(0, this.channel1.read(readBuf));
+ this.channel1.close();
+ try {
+ this.channel1.read(readBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ }
+
+ public void testReadByteBuffer_bufNull() throws IOException {
+ ByteBuffer readBuf = ByteBuffer.allocateDirect(0);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ try {
+ this.channel1.read(readBuf);
+ fail("should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ try {
+ channel1.read((ByteBuffer) null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ this.channel1.configureBlocking(false);
+ // note : blocking-mode will make the read process endless!
+ assertEquals(0, this.channel1.read(readBuf));
+ datagramSocket1.close();
+ }
+
+ /*
+ * Test method for 'DatagramChannelImpl.read(ByteBuffer[], int, int)'
+ */
+ public void testReadByteBufferArrayIntInt() throws IOException {
+ ByteBuffer[] readBuf = new ByteBuffer[2];
+ readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ try {
+ this.channel1.read(readBuf, 0, 2);
+ fail("should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ this.channel1.configureBlocking(false);
+ // note : blocking-mode will make the read process endless!
+ assertEquals(0, this.channel1.read(readBuf, 0, 1));
+ assertEquals(0, this.channel1.read(readBuf, 0, 2));
+ datagramSocket1.close();
+ }
+
+ public void testReadByteBufferArrayIntInt_exceptions() throws IOException {
+ //regression test for HARMONY-932
+ try {
+ DatagramChannel.open().read(new ByteBuffer[] {}, 2, Integer.MAX_VALUE);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ DatagramChannel.open().read(new ByteBuffer[] {}, -1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ DatagramChannel.open().read((ByteBuffer[]) null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testReadByteBufferArrayIntInt_BufNull() throws IOException {
+ ByteBuffer[] readBuf = new ByteBuffer[2];
+ readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ InetSocketAddress ipAddr = datagramSocket1Address;
+ try {
+ this.channel1.read(null, 0, 0);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ this.channel1.connect(ipAddr);
+ assertTrue(this.channel1.isConnected());
+ this.channel1.configureBlocking(false);
+ // note : blocking-mode will make the read process endless!
+ try {
+ this.channel1.read(null, 0, 0);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertEquals(0, this.channel1.read(readBuf, 0, 1));
+ try {
+ this.channel1.read(readBuf, 0, 2);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ this.channel1.read(readBuf, 0, 3);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // correct
+ }
+ datagramSocket1.close();
+ }
+
+ // -------------------------------------------------------------------
+ // test read and write
+ // -------------------------------------------------------------------
+
+ public static class A {
+ protected int z;
+ }
+
+ public static class B extends A {
+ protected int z;
+
+ void foo() {
+ super.z+=1;
+ }
+ }
+
+
+ public void testReadWrite_asyncClose() throws Exception {
+ byte[] targetArray = new byte[2];
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+
+ channel2.connect(channel1Address);
+ channel1.connect(channel2Address);
+
+ new Thread() {
+ public void run() {
+ try {
+ Thread.sleep(TIME_UNIT);
+ channel1.close();
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+ }.start();
+
+ try {
+ this.channel1.read(targetBuf);
+ fail("should throw AsynchronousCloseException");
+ } catch (AsynchronousCloseException e) {
+ // ok
+ }
+ }
+
+ public void testReadWrite_Block_Zero() throws Exception {
+ byte[] sourceArray = new byte[0];
+ byte[] targetArray = new byte[0];
+
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(0, this.channel1.write(sourceBuf));
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ int readCount = this.channel2.read(targetBuf);
+
+ assertEquals(0, readCount);
+ }
+
+ public void testReadWrite_Block_Normal() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ readWriteReadData(this.channel1, sourceArray, this.channel2,
+ targetArray, CAPACITY_NORMAL, "testReadWrite_Block_Normal");
+ }
+
+ public void testReadWrite_Block_Empty() throws Exception {
+ // empty buf
+ byte[] sourceArray = "".getBytes();
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(0, this.channel1.write(sourceBuf));
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ // empty message let the reader blocked
+ closeBlockedReaderChannel2(targetBuf);
+ }
+
+ public void testReadWrite_changeBlock_Empty() throws Exception {
+ // empty buf
+ byte[] sourceArray = "".getBytes();
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(0, this.channel1.write(sourceBuf));
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ // empty message let the reader blocked
+ new Thread() {
+ public void run() {
+ try {
+ Thread.sleep(TIME_UNIT);
+ channel2.configureBlocking(false);
+ Thread.sleep(TIME_UNIT * 5);
+ channel2.close();
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }.start();
+ try {
+ assertTrue(this.channel2.isBlocking());
+ this.channel2.read(targetBuf);
+ fail("Should throw AsynchronousCloseException");
+ } catch (AsynchronousCloseException e) {
+ assertFalse(this.channel2.isBlocking());
+ // OK.
+ }
+ }
+
+ public void testReadWrite_Block_8KB() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_1KB * 8];
+ byte[] targetArray = new byte[CAPACITY_1KB * 8];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ readWriteReadData(this.channel1, sourceArray, this.channel2,
+ targetArray, 8 * CAPACITY_1KB, "testReadWrite_Block_8KB");
+ }
+
+ /*
+ * sender write the sourceArray whose size is dataSize, and receiver read
+ * the data into targetArray
+ */
+ private void readWriteReadData(DatagramChannel sender, byte[] sourceArray,
+ DatagramChannel receiver, byte[] targetArray, int dataSize,
+ String methodName) throws IOException {
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(dataSize, sender.write(sourceBuf));
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+
+ int count = 0;
+ int total = 0;
+ long beginTime = System.currentTimeMillis();
+ while (total < dataSize && (count = receiver.read(targetBuf)) != -1) {
+ total = total + count;
+ // 3s timeout to avoid dead loop
+ if (System.currentTimeMillis() - beginTime > 3000){
+ break;
+ }
+ }
+
+ assertEquals(dataSize, total);
+ assertEquals(targetBuf.position(), total);
+ targetBuf.flip();
+ targetArray = targetBuf.array();
+ for (int i = 0; i < targetArray.length; i++) {
+ assertEquals(targetArray[i], (byte) i);
+ }
+ }
+
+ public void testReadWrite_Block_64K() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_64KB];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ channel1.connect(channel2Address);
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ try {
+ channel1.write(sourceBuf);
+ fail("Should throw IOException");
+ } catch (IOException expected) {
+ // too big
+ }
+ }
+
+ public void testReadWrite_Block_DifferentAddr() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ this.channel1.connect(channel1.socket().getLocalSocketAddress());
+ this.channel2.connect(datagramSocket1Address); // the different addr
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ // the wrong connected addr will make the read blocked.
+ // we close the blocked channel
+ closeBlockedReaderChannel2(targetBuf);
+ }
+
+ public void testReadWrite_Block_WriterNotBound() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ DatagramChannel dc = DatagramChannel.open();
+ // The writer isn't bound, but is connected.
+ dc.connect(channel1Address);
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(CAPACITY_NORMAL, dc.write(sourceBuf));
+
+ // Connect channel2 after data has been written.
+ channel2.connect(dc.socket().getLocalSocketAddress());
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ closeBlockedReaderChannel2(targetBuf);
+
+ dc.close();
+ }
+
+ // NOTE: The original harmony test tested that things still work
+ // if there's no socket bound at the the address we're connecting to.
+ //
+ // It isn't really feasible to implement that in a non-racy way.
+ public void testReadWrite_Block_WriterConnectLater() throws Exception {
+
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+
+ // The reader is bound & connected to channel1.
+ channel2.connect(channel1Address);
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ new Thread() {
+ public void run() {
+ try {
+ Thread.sleep(TIME_UNIT);
+ // bind later
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ channel1.connect(channel2Address);
+ // write later
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(CAPACITY_NORMAL, channel1.write(sourceBuf));
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }.start();
+
+ int count = 0;
+ int total = 0;
+ long beginTime = System.currentTimeMillis();
+
+ while (total < CAPACITY_NORMAL && (count = channel2.read(targetBuf)) != -1) {
+ total = total + count;
+ // 3s timeout to avoid dead loop
+ if (System.currentTimeMillis() - beginTime > 3000){
+ break;
+ }
+ }
+
+ assertEquals(CAPACITY_NORMAL, total);
+ assertEquals(targetBuf.position(), total);
+ targetBuf.flip();
+ targetArray = targetBuf.array();
+ for (int i = 0; i < targetArray.length; i++) {
+ assertEquals(targetArray[i], (byte) i);
+ }
+ }
+
+ // NOTE: The original harmony test tested that things still work
+ // if there's no socket bound at the the address we're connecting to.
+ //
+ // It isn't really feasible to implement that in a non-racy way.
+ public void testReadWrite_Block_ReaderNotConnected() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ // reader channel2 is not connected.
+ this.channel1.connect(channel2Address);
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ try {
+ this.channel2.read(targetBuf);
+ fail();
+ } catch (NotYetConnectedException expected) {
+ }
+ }
+
+ private void closeBlockedReaderChannel2(ByteBuffer targetBuf)
+ throws IOException {
+ assertTrue(this.channel2.isBlocking());
+
+ new Thread() {
+ public void run() {
+ try {
+ Thread.sleep(TIME_UNIT);
+ } catch (InterruptedException ie) {
+ fail();
+ }
+ IoUtils.closeQuietly(channel2);
+ }
+ }.start();
+
+ try {
+ this.channel2.read(targetBuf);
+ fail("Should throw AsynchronousCloseException");
+ } catch (AsynchronousCloseException e) {
+ // OK.
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Test read and write in non-block mode.
+ // -------------------------------------------------------------------
+ public void testReadWrite_NonBlock_Normal() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ readWriteReadData(this.channel1, sourceArray, this.channel2,
+ targetArray, CAPACITY_NORMAL, "testReadWrite_NonBlock_Normal");
+ }
+
+ public void testReadWrite_NonBlock_8KB() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_1KB * 8];
+ byte[] targetArray = new byte[CAPACITY_1KB * 8];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+
+ // bind and connect
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ readWriteReadData(this.channel1, sourceArray, this.channel2,
+ targetArray, 8 * CAPACITY_1KB, "testReadWrite_NonBlock_8KB");
+ }
+
+ public void testReadWrite_NonBlock_DifferentAddr() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+
+ channel1.connect(channel2Address);
+ channel2.connect(datagramSocket1Address);// the different addr
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ assertEquals(0, this.channel2.read(targetBuf));
+ }
+
+
+ public void testReadWrite_NonBlock_WriterNotBound() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ DatagramChannel dc = DatagramChannel.open();
+ // The writer isn't bound, but is connected.
+ dc.connect(channel1Address);
+ dc.configureBlocking(false);
+ channel2.configureBlocking(false);
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(CAPACITY_NORMAL, dc.write(sourceBuf));
+
+ // Connect channel2 after data has been written.
+ channel2.connect(dc.socket().getLocalSocketAddress());
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+ assertEquals(0, this.channel2.read(targetBuf));
+
+ dc.close();
+ }
+
+ // NOTE: The original harmony test tested that things still work
+ // if there's no socket bound at the the address we're connecting to.
+ //
+ // It isn't really feasible to implement that in a non-racy way.
+ public void testReadWrite_NonBlock_ReaderNotConnected() throws Exception {
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ byte[] targetArray = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < sourceArray.length; i++) {
+ sourceArray[i] = (byte) i;
+ }
+
+ this.channel1.configureBlocking(false);
+ this.channel2.configureBlocking(false);
+
+ channel1.connect(channel2Address);
+
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
+
+ // read
+ ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
+
+ try {
+ assertEquals(0, this.channel2.read(targetBuf));
+ fail();
+ } catch (NotYetConnectedException expected) {
+ }
+ }
+
+ public void test_write_LBuffer_positioned() throws Exception {
+ // Regression test for Harmony-683
+ int position = 16;
+ DatagramChannel dc = DatagramChannel.open();
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ dc.connect(datagramSocket1Address);
+ // write
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ sourceBuf.position(position);
+ assertEquals(CAPACITY_NORMAL - position, dc.write(sourceBuf));
+ }
+
+ public void test_send_LBuffer_LSocketAddress_PositionNotZero()
+ throws Exception {
+ // regression test for Harmony-701
+ int CAPACITY_NORMAL = 256;
+ int position = 16;
+ DatagramChannel dc = DatagramChannel.open();
+ byte[] sourceArray = new byte[CAPACITY_NORMAL];
+ // send ByteBuffer whose position is not zero
+ ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
+ sourceBuf.position(position);
+ int ret = dc.send(sourceBuf, datagramSocket1Address);
+ // assert send (256 - 16) bytes
+ assertEquals(CAPACITY_NORMAL - position, ret);
+ // assert the position of ByteBuffer has been set
+ assertEquals(CAPACITY_NORMAL, sourceBuf.position());
+ }
+
+ /**
+ * @tests DatagramChannel#read(ByteBuffer[])
+ */
+ public void test_read_$LByteBuffer() throws Exception {
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ // regression test for Harmony-754
+ channel2.write(ByteBuffer.allocate(CAPACITY_NORMAL));
+
+ ByteBuffer[] readBuf = new ByteBuffer[2];
+ readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+
+ channel1.configureBlocking(true);
+ assertEquals(CAPACITY_NORMAL, channel1.read(readBuf));
+ }
+
+ /**
+ * @tests DatagramChannel#read(ByteBuffer[],int,int)
+ */
+ public void test_read_$LByteBufferII() throws Exception {
+ channel1.connect(channel2Address);
+ channel2.connect(channel1Address);
+
+ // regression test for Harmony-754
+ channel2.write(ByteBuffer.allocate(CAPACITY_NORMAL));
+
+ ByteBuffer[] readBuf = new ByteBuffer[2];
+ readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+
+ channel1.configureBlocking(true);
+ assertEquals(CAPACITY_NORMAL, channel1.read(readBuf, 0, 2));
+ }
+
+ /**
+ * @tests DatagramChannel#read(ByteBuffer)
+ */
+ public void test_read_LByteBuffer_closed_nullBuf() throws Exception {
+ // regression test for Harmony-754
+ ByteBuffer c = null;
+ DatagramChannel channel = DatagramChannel.open();
+ channel.close();
+ try{
+ channel.read(c);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e){
+ // expected
+ }
+ }
+
+ /**
+ * @tests DatagramChannel#read(ByteBuffer)
+ */
+ public void test_read_LByteBuffer_NotConnected_nullBuf() throws Exception {
+ // regression test for Harmony-754
+ ByteBuffer c = null;
+ DatagramChannel channel = DatagramChannel.open();
+ try{
+ channel.read(c);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e){
+ // expected
+ }
+ }
+
+ /**
+ * @tests DatagramChannel#read(ByteBuffer)
+ */
+ public void test_read_LByteBuffer_readOnlyBuf() throws Exception {
+ // regression test for Harmony-754
+ ByteBuffer c = ByteBuffer.allocate(1);
+ DatagramChannel channel = DatagramChannel.open();
+ try{
+ channel.read(c.asReadOnlyBuffer());
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e){
+ } catch (IllegalArgumentException e){
+ // expected
+ }
+ channel.connect(datagramSocket1Address);
+ try{
+ channel.read(c.asReadOnlyBuffer());
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e){
+ // expected
+ }
+ }
+
+ /**
+ * @tests DatagramChannel#send(ByteBuffer, SocketAddress)
+ */
+ public void test_send_LByteBuffer_LSocketAddress_closed() throws IOException{
+ // regression test for Harmony-913
+ channel1.close();
+ ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
+ try {
+ channel1.send(buf, datagramSocket1Address);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ //pass
+ }
+ try {
+ channel1.send(null, datagramSocket1Address);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ //pass
+ }
+ try {
+ channel1.send(buf, null);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ //pass
+ }
+ try {
+ channel1.send(null, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ //pass
+ }
+ }
+
+ /**
+ * @tests DatagramChannel#socket()
+ */
+ public void test_socket_IllegalBlockingModeException() throws Exception {
+ // regression test for Harmony-1036
+ DatagramChannel channel = DatagramChannel.open();
+ channel.configureBlocking(false);
+ DatagramSocket socket = channel.socket();
+ try {
+ socket.send(null);
+ fail("should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e) {
+ // expected
+ }
+ try {
+ socket.receive(null);
+ fail("should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e) {
+ // expected
+ }
+
+ channel.close();
+ }
+
+ public void test_bounded_harmony6493() throws IOException {
+ DatagramChannel server = DatagramChannel.open();
+ InetSocketAddress addr = new InetSocketAddress("localhost", 0);
+ server.socket().bind(addr);
+ SocketAddress boundedAddress = server.socket().getLocalSocketAddress();
+
+ DatagramChannel client = DatagramChannel.open();
+ ByteBuffer sent = ByteBuffer.allocate(1024);
+ sent.put("test".getBytes());
+ sent.flip();
+ client.send(sent, boundedAddress);
+ assertTrue(client.socket().isBound());
+
+ server.close();
+ client.close();
+ }
+
+ public void test_bind_null() throws Exception {
+ DatagramChannel dc = DatagramChannel.open();
+ try {
+ assertNull(dc.socket().getLocalSocketAddress());
+
+ dc.socket().bind(null);
+
+ InetSocketAddress localAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
+ assertTrue(localAddress.getAddress().isAnyLocalAddress());
+ assertTrue(localAddress.getPort() > 0);
+ } finally {
+ dc.close();
+ }
+ }
+
+ public void test_bind_failure() throws Exception {
+ DatagramChannel dc = DatagramChannel.open();
+ try {
+ // Bind to a local address that is in use
+ dc.socket().bind(channel1Address);
+ fail();
+ } catch (IOException expected) {
+ } finally {
+ dc.close();
+ }
+ }
+
+ public void test_bind_closed() throws Exception {
+ DatagramChannel dc = DatagramChannel.open();
+ dc.close();
+
+ try {
+ dc.socket().bind(null);
+ fail();
+ } catch (IOException expected) {
+ } finally {
+ dc.close();
+ }
+ }
+
+ public void test_bind_explicitPort() throws Exception {
+ InetSocketAddress address = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
+ assertTrue(address.getPort() > 0);
+
+ DatagramChannel dc = DatagramChannel.open();
+ // Allow the socket to bind to a port we know is already in use.
+ dc.socket().setReuseAddress(true);
+ InetSocketAddress bindAddress = new InetSocketAddress("localhost", address.getPort());
+ dc.socket().bind(bindAddress);
+
+ InetSocketAddress boundAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
+ assertEquals(bindAddress.getHostName(), boundAddress.getHostName());
+ assertEquals(bindAddress.getPort(), boundAddress.getPort());
+
+ dc.close();
+ channel1.close();
+ }
+
+ /** Checks that the SocketChannel and associated Socket agree on the socket state. */
+ public void test_bind_socketSync() throws IOException {
+ DatagramChannel dc = DatagramChannel.open();
+ assertNull(dc.socket().getLocalSocketAddress());
+
+ DatagramSocket socket = dc.socket();
+ assertNull(socket.getLocalSocketAddress());
+ assertFalse(socket.isBound());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ dc.socket().bind(bindAddr);
+
+ InetSocketAddress actualAddr = (InetSocketAddress) dc.socket().getLocalSocketAddress();
+ assertEquals(actualAddr, socket.getLocalSocketAddress());
+ assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
+ assertTrue(socket.isBound());
+ assertFalse(socket.isConnected());
+ assertFalse(socket.isClosed());
+
+ dc.close();
+
+ assertFalse(dc.isOpen());
+ assertTrue(socket.isClosed());
+ }
+
+ /**
+ * Checks that the SocketChannel and associated Socket agree on the socket state, even if
+ * the Socket object is requested/created after bind().
+ */
+ public void test_bind_socketSyncAfterBind() throws IOException {
+ DatagramChannel dc = DatagramChannel.open();
+ assertNull(dc.socket().getLocalSocketAddress());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ dc.socket().bind(bindAddr);
+
+ // Socket creation after bind().
+ DatagramSocket socket = dc.socket();
+ InetSocketAddress actualAddr = (InetSocketAddress) dc.socket().getLocalSocketAddress();
+ assertEquals(actualAddr, socket.getLocalSocketAddress());
+ assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
+ assertTrue(socket.isBound());
+ assertFalse(socket.isConnected());
+ assertFalse(socket.isClosed());
+
+ dc.close();
+
+ assertFalse(dc.isOpen());
+ assertTrue(socket.isClosed());
+ }
+
+ public void test_getLocalSocketAddress_afterClose() throws IOException {
+ DatagramChannel dc = DatagramChannel.open();
+ assertNull(dc.socket().getLocalSocketAddress());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ dc.socket().bind(bindAddr);
+
+ assertNotNull(dc.socket().getLocalSocketAddress());
+
+ dc.close();
+
+ assertFalse(dc.isOpen());
+
+ dc.socket().getLocalSocketAddress();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelLockingTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelLockingTest.java
new file mode 100644
index 0000000..40daa20
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelLockingTest.java
@@ -0,0 +1,208 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.NonReadableChannelException;
+import java.nio.channels.NonWritableChannelException;
+import java.nio.channels.OverlappingFileLockException;
+
+import junit.framework.TestCase;
+
+/**
+ * API tests for the NIO FileChannel locking APIs
+ */
+public class FileChannelLockingTest extends TestCase {
+
+ private FileChannel readOnlyChannel;
+
+ private FileChannel writeOnlyChannel;
+
+ private FileChannel readWriteChannel;
+
+ private final String CONTENT = "The best things in life are nearest: Breath in your nostrils, light in your eyes, "
+ + "flowers at your feet, duties at your hand, the path of right just before you. Then do not grasp at the stars, "
+ + "but do life's plain, common work as it comes, certain that daily duties and daily bread are the sweetest "
+ + " things in life.--Robert Louis Stevenson";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Create a three temporary files with content.
+ File[] tempFiles = new File[3];
+ for (int i = 0; i < tempFiles.length; i++) {
+ tempFiles[i] = File.createTempFile("testing", "tmp");
+ tempFiles[i].deleteOnExit();
+ FileWriter writer = new FileWriter(tempFiles[i]);
+ writer.write(CONTENT);
+ writer.close();
+ }
+
+ // Open read, write, and read/write channels on the temp files.
+ FileInputStream fileInputStream = new FileInputStream(tempFiles[0]);
+ readOnlyChannel = fileInputStream.getChannel();
+
+ FileOutputStream fileOutputStream = new FileOutputStream(tempFiles[1]);
+ writeOnlyChannel = fileOutputStream.getChannel();
+
+ RandomAccessFile randomAccessFile = new RandomAccessFile(tempFiles[2],
+ "rw");
+ readWriteChannel = randomAccessFile.getChannel();
+ }
+
+ protected void tearDown() throws IOException {
+ if (readOnlyChannel != null) {
+ readOnlyChannel.close();
+ }
+ if (writeOnlyChannel != null) {
+ writeOnlyChannel.close();
+ }
+ if (readWriteChannel != null) {
+ readWriteChannel.close();
+ }
+ }
+
+ public void test_illegalLocks() throws IOException {
+ // Cannot acquire an exclusive lock on a read-only file channel
+ try {
+ readOnlyChannel.lock();
+ fail("Acquiring a full exclusive lock on a read only channel should fail.");
+ } catch (NonWritableChannelException ex) {
+ // Expected.
+ }
+
+ // Cannot get a shared lock on a write-only file channel.
+ try {
+ writeOnlyChannel.lock(1, 10, true);
+ fail("Acquiring a shared lock on a write-only channel should fail.");
+ } catch (NonReadableChannelException ex) {
+ // expected
+ }
+ }
+
+ public void test_lockReadWrite() throws IOException {
+ // Acquire an exclusive lock across the entire file.
+ FileLock flock = readWriteChannel.lock();
+ if (flock != null) {
+ flock.release();
+ }
+ }
+
+ public void test_illegalLockParameters() throws IOException {
+ // Cannot lock negative positions
+ try {
+ readOnlyChannel.lock(-1, 10, true);
+ fail("Passing illegal args to lock should fail.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ writeOnlyChannel.lock(-1, 10, false);
+ fail("Passing illegal args to lock should fail.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ readWriteChannel.lock(-1, 10, false);
+ fail("Passing illegal args to lock should fail.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ // Lock a range at the front, shared.
+ FileLock flock1 = readWriteChannel.lock(22, 110, true);
+
+ // Try to acquire an overlapping lock.
+ try {
+ readWriteChannel.lock(75, 210, true);
+ } catch (OverlappingFileLockException exception) {
+ // expected
+ flock1.release();
+ }
+ }
+
+ public void test_lockLLZ() throws IOException {
+ // Lock a range at the front, non-shared.
+ FileLock flock1 = readWriteChannel.lock(0, 10, false);
+
+ // Lock a shared range further in the same file.
+ FileLock flock2 = readWriteChannel.lock(22, 100, true);
+
+ // The spec allows the impl to refuse shared locks
+ flock1.release();
+ flock2.release();
+ }
+
+ public void test_tryLock() throws IOException {
+ try {
+ readOnlyChannel.tryLock();
+ fail("Acquiring a full exclusive lock on a read channel should have thrown an exception.");
+ } catch (NonWritableChannelException ex) {
+ // Expected.
+ }
+ }
+
+ public void test_tryLockLLZ() throws IOException {
+ // It is illegal to request an exclusive lock on a read-only channel
+ try {
+ readOnlyChannel.tryLock(0, 99, false);
+ fail("Acquiring exclusive lock on read-only channel should fail");
+ } catch (NonWritableChannelException ex) {
+ // Expected
+ }
+
+ // It is invalid to request a lock starting before the file start
+ try {
+ readOnlyChannel.tryLock(-99, 0, true);
+ fail("Acquiring an illegal lock value should fail.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ // Acquire a valid lock
+ FileLock tmpLock = readOnlyChannel.tryLock(0, 10, true);
+ assertTrue(tmpLock.isValid());
+ tmpLock.release();
+
+ // Acquire another valid lock -- and don't release it yet
+ FileLock lock = readOnlyChannel.tryLock(10, 788, true);
+ assertTrue(lock.isValid());
+
+ // Overlapping locks are illegal
+ try {
+ readOnlyChannel.tryLock(1, 23, true);
+ fail("Acquiring an overlapping lock should fail.");
+ } catch (OverlappingFileLockException ex) {
+ // Expected
+ }
+
+ // Adjacent locks are legal
+ FileLock adjacentLock = readOnlyChannel.tryLock(1, 3, true);
+ assertTrue(adjacentLock.isValid());
+ adjacentLock.release();
+
+ // Release longer lived lock
+ lock.release();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java
new file mode 100644
index 0000000..990badc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java
@@ -0,0 +1,3121 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.NonReadableChannelException;
+import java.nio.channels.NonWritableChannelException;
+import java.nio.channels.OverlappingFileLockException;
+import java.nio.channels.Pipe;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.WritableByteChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+public class FileChannelTest extends TestCase {
+
+ private static final int CAPACITY = 100;
+
+ private static final int LIMITED_CAPACITY = 2;
+
+ private static final int TIME_OUT = 10000;
+
+ private static final String CONTENT = "MYTESTSTRING needs to be a little long";
+
+ private static final byte[] TEST_BYTES;
+
+ private static final byte[] CONTENT_AS_BYTES;
+
+ private static final int CONTENT_AS_BYTES_LENGTH;
+
+ static {
+ try {
+ TEST_BYTES = "test".getBytes("iso8859-1");
+ CONTENT_AS_BYTES = CONTENT.getBytes("iso8859-1");
+ CONTENT_AS_BYTES_LENGTH = CONTENT_AS_BYTES.length;
+ } catch (UnsupportedEncodingException e) {
+ throw new Error(e);
+ }
+ }
+
+ private static final int CONTENT_LENGTH = CONTENT.length();
+
+ private FileChannel readOnlyFileChannel;
+
+ private FileChannel writeOnlyFileChannel;
+
+ private FileChannel readWriteFileChannel;
+
+ private File fileOfReadOnlyFileChannel;
+
+ private File fileOfWriteOnlyFileChannel;
+
+ private File fileOfReadWriteFileChannel;
+
+ private ReadableByteChannel readByteChannel;
+
+ private WritableByteChannel writableByteChannel;
+
+ private DatagramChannel datagramChannelSender;
+
+ private DatagramChannel datagramChannelReceiver;
+
+ private ServerSocketChannel serverSocketChannel;
+
+ private SocketChannel socketChannelSender;
+
+ private SocketChannel socketChannelReceiver;
+
+ private Pipe pipe;
+
+ // to read content from FileChannel
+ private FileInputStream fis;
+
+ private FileLock fileLock;
+
+ protected void setUp() throws Exception {
+ fileOfReadOnlyFileChannel = File.createTempFile(
+ "File_of_readOnlyFileChannel", "tmp");
+ fileOfReadOnlyFileChannel.deleteOnExit();
+ fileOfWriteOnlyFileChannel = File.createTempFile(
+ "File_of_writeOnlyFileChannel", "tmp");
+ fileOfWriteOnlyFileChannel.deleteOnExit();
+ fileOfReadWriteFileChannel = File.createTempFile(
+ "File_of_readWriteFileChannel", "tmp");
+ fileOfReadWriteFileChannel.deleteOnExit();
+ fis = null;
+ fileLock = null;
+ readOnlyFileChannel = new FileInputStream(fileOfReadOnlyFileChannel)
+ .getChannel();
+ writeOnlyFileChannel = new FileOutputStream(fileOfWriteOnlyFileChannel)
+ .getChannel();
+ readWriteFileChannel = new RandomAccessFile(fileOfReadWriteFileChannel,
+ "rw").getChannel();
+ }
+
+ protected void tearDown() {
+ if (null != readOnlyFileChannel) {
+ try {
+ readOnlyFileChannel.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != writeOnlyFileChannel) {
+ try {
+ writeOnlyFileChannel.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != readWriteFileChannel) {
+ try {
+ readWriteFileChannel.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != fis) {
+ try {
+ fis.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+
+ if (null != fileLock) {
+ try {
+ fileLock.release();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+
+ if (null != fileOfReadOnlyFileChannel) {
+ fileOfReadOnlyFileChannel.delete();
+ }
+ if (null != fileOfWriteOnlyFileChannel) {
+ fileOfWriteOnlyFileChannel.delete();
+ }
+ if (null != fileOfReadWriteFileChannel) {
+ fileOfReadWriteFileChannel.delete();
+ }
+ if (null != datagramChannelSender) {
+ try {
+ datagramChannelSender.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != datagramChannelReceiver) {
+ try {
+ datagramChannelReceiver.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != serverSocketChannel) {
+ try {
+ serverSocketChannel.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != socketChannelSender) {
+ try {
+ socketChannelSender.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != socketChannelReceiver) {
+ try {
+ socketChannelReceiver.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != pipe) {
+ if (null != pipe.source()) {
+ try {
+ pipe.source().close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (null != pipe.sink()) {
+ try {
+ pipe.sink().close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#force(boolean)
+ */
+ public void test_forceJ() throws Exception {
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ writeOnlyFileChannel.write(writeBuffer);
+ writeOnlyFileChannel.force(true);
+
+ byte[] readBuffer = new byte[CONTENT_AS_BYTES_LENGTH];
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ fis.read(readBuffer);
+ assertTrue(Arrays.equals(CONTENT_AS_BYTES, readBuffer));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#force(boolean)
+ */
+ public void test_forceJ_closed() throws Exception {
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.force(true);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ try {
+ writeOnlyFileChannel.force(false);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#force(boolean)
+ */
+ public void test_forceJ_ReadOnlyChannel() throws Exception {
+ // force on a read only file channel has no effect.
+ readOnlyFileChannel.force(true);
+ readOnlyFileChannel.force(false);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position()
+ */
+ public void test_position_Init() throws Exception {
+ assertEquals(0, readOnlyFileChannel.position());
+ assertEquals(0, writeOnlyFileChannel.position());
+ assertEquals(0, readWriteFileChannel.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position()
+ */
+ public void test_position_ReadOnly() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+
+ assertEquals(0, readOnlyFileChannel.position());
+ ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
+ readOnlyFileChannel.read(readBuffer);
+ assertEquals(CONTENT_LENGTH, readOnlyFileChannel.position());
+ }
+
+ /**
+ * Initializes test file.
+ *
+ * @param file
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ private void writeDataToFile(File file) throws FileNotFoundException,
+ IOException {
+ FileOutputStream fos = new FileOutputStream(file);
+ try {
+ fos.write(CONTENT_AS_BYTES);
+ } finally {
+ fos.close();
+ }
+ }
+
+ /**
+ * Initializes large test file.
+ *
+ * @param file the file to be written
+ * @param size the content size to be written
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ private void writeLargeDataToFile(File file, int size) throws FileNotFoundException,
+ IOException {
+ FileOutputStream fos = new FileOutputStream(file);
+ byte[] buf = new byte[size];
+
+ try {
+ // we don't care about content - just need a particular file size
+ fos.write(buf);
+ } finally {
+ fos.close();
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position()
+ */
+ public void test_position_WriteOnly() throws Exception {
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ writeOnlyFileChannel.write(writeBuffer);
+ assertEquals(CONTENT_LENGTH, writeOnlyFileChannel.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position()
+ */
+ public void test_position_ReadWrite() throws Exception {
+ writeDataToFile(fileOfReadWriteFileChannel);
+
+ assertEquals(0, readWriteFileChannel.position());
+ ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
+ readWriteFileChannel.read(readBuffer);
+ assertEquals(CONTENT_LENGTH, readWriteFileChannel.position());
+
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ readWriteFileChannel.write(writeBuffer);
+ assertEquals(CONTENT_LENGTH * 2, readWriteFileChannel.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position()
+ */
+ public void test_position_Closed() throws Exception {
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.position();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.position();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.position();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position(long)
+ */
+ public void test_positionJ_Closed() throws Exception {
+ final long POSITION = 100;
+
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.position(POSITION);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.position(POSITION);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.position(POSITION);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position(long)
+ */
+ public void test_positionJ_Negative() throws Exception {
+ final long NEGATIVE_POSITION = -1;
+ try {
+ readOnlyFileChannel.position(NEGATIVE_POSITION);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ writeOnlyFileChannel.position(NEGATIVE_POSITION);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.position(NEGATIVE_POSITION);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position(long)
+ */
+ public void test_positionJ_ReadOnly() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+
+ // set the position of the read only file channel to POSITION
+ final int POSITION = 4;
+ readOnlyFileChannel.position(POSITION);
+
+ // reads the content left to readBuffer through read only file channel
+ ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
+ int count = readOnlyFileChannel.read(readBuffer);
+ assertEquals(CONTENT_LENGTH - POSITION, count);
+
+ // asserts the content read is the part which stays beyond the POSITION
+ readBuffer.flip();
+ int i = POSITION;
+ while (readBuffer.hasRemaining()) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
+ i++;
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position(long)
+ */
+ public void test_positionJ_WriteOnly() throws Exception {
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ // init data to write
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+
+ // set the position of the write only file channel to POSITION
+ final int POSITION = 4;
+ writeOnlyFileChannel.position(POSITION);
+
+ // writes to the write only file channel
+ writeOnlyFileChannel.write(writeBuffer);
+ // force to write out.
+ writeOnlyFileChannel.close();
+
+ // gets the result of the write only file channel
+ byte[] result = new byte[POSITION + CONTENT_LENGTH];
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ fis.read(result);
+
+ // constructs the expected result which has content[0... POSITION] plus
+ // content[0...length()]
+ byte[] expectedResult = new byte[POSITION + CONTENT_LENGTH];
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, 0, POSITION);
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, POSITION,
+ CONTENT_LENGTH);
+
+ // asserts result of the write only file channel same as expected
+ assertTrue(Arrays.equals(expectedResult, result));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#size()
+ */
+ public void test_size_Init() throws Exception {
+ assertEquals(0, readOnlyFileChannel.size());
+ assertEquals(0, writeOnlyFileChannel.size());
+ assertEquals(0, readWriteFileChannel.size());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#size()
+ */
+ public void test_size() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ assertEquals(fileOfReadOnlyFileChannel.length(), readOnlyFileChannel
+ .size());
+
+
+ // REGRESSION test for read(ByteBuffer[], int, int) on special files
+ try {
+ FileChannel specialFile =
+ new FileInputStream("/dev/zero").getChannel();
+ assertEquals(0, specialFile.size());
+ ByteBuffer buf = ByteBuffer.allocate(8);
+ assertEquals(8, specialFile.read(buf));
+ ByteBuffer[] bufs = { ByteBuffer.allocate(8) };
+ assertEquals(8, specialFile.read(bufs, 0, 1));
+ specialFile.close();
+ } catch (FileNotFoundException e) {
+ // skip test if special file doesn't exist
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#size()
+ */
+ public void test_size_Closed() throws Exception {
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.size();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.size();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.size();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#truncate(long)
+ */
+ public void test_truncateJ_Closed() throws Exception {
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.truncate(0);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.truncate(0);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.truncate(-1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#truncate(long)
+ */
+ public void test_truncateJ_IllegalArgument() throws Exception {
+ // regression test for Harmony-941
+ try {
+ readOnlyFileChannel.truncate(-1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ writeOnlyFileChannel.truncate(-1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.truncate(-1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#truncate(long)
+ */
+ public void test_truncateJ_ReadOnly() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ try {
+ readOnlyFileChannel.truncate(readOnlyFileChannel.size());
+ fail("should throw NonWritableChannelException.");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+
+ try {
+ readOnlyFileChannel.truncate(0);
+ fail("should throw NonWritableChannelException.");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#truncate(long)
+ */
+ public void test_truncateJ() throws Exception {
+ writeDataToFile(fileOfReadWriteFileChannel);
+
+ int truncateLength = CONTENT_LENGTH + 2;
+ assertEquals(readWriteFileChannel, readWriteFileChannel
+ .truncate(truncateLength));
+ assertEquals(CONTENT_LENGTH, fileOfReadWriteFileChannel.length());
+
+ truncateLength = CONTENT_LENGTH;
+ assertEquals(readWriteFileChannel, readWriteFileChannel
+ .truncate(truncateLength));
+ assertEquals(CONTENT_LENGTH, fileOfReadWriteFileChannel.length());
+
+ truncateLength = CONTENT_LENGTH / 2;
+ assertEquals(readWriteFileChannel, readWriteFileChannel
+ .truncate(truncateLength));
+ assertEquals(truncateLength, fileOfReadWriteFileChannel.length());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock()
+ */
+ public void test_lock() throws Exception {
+ MockFileChannel mockFileChannel = new MockFileChannel();
+ // Verify that calling lock() leads to the method
+ // lock(long, long, boolean) being called with a 0 for the
+ // first parameter, Long.MAX_VALUE as the second parameter and false
+ // as the third parameter.
+ mockFileChannel.lock();
+ assertTrue(mockFileChannel.isLockCalled);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_Closed() throws Exception {
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.lock(0, 10, false);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.lock(0, 10, false);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.lock(0, 10, false);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // throws ClosedChannelException before IllegalArgumentException
+ try {
+ readWriteFileChannel.lock(-1, 0, false);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_IllegalArgument() throws Exception {
+ try {
+ writeOnlyFileChannel.lock(0, -1, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ writeOnlyFileChannel.lock(-1, 0, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.lock(-1, -1, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.lock(Long.MAX_VALUE, 1, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_NonWritable() throws Exception {
+ try {
+ readOnlyFileChannel.lock(0, 10, false);
+ fail("should throw NonWritableChannelException");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+
+ // throws NonWritableChannelException before IllegalArgumentException
+ try {
+ readOnlyFileChannel.lock(-1, 0, false);
+ fail("should throw NonWritableChannelException");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_NonReadable() throws Exception {
+ try {
+ writeOnlyFileChannel.lock(0, 10, true);
+ fail("should throw NonReadableChannelException");
+ } catch (NonReadableChannelException e) {
+ // expected
+ }
+
+ // throws NonReadableChannelException before IllegalArgumentException
+ try {
+ writeOnlyFileChannel.lock(-1, 0, true);
+ fail("should throw NonReadableChannelException");
+ } catch (NonReadableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_Shared() throws Exception {
+ final long POSITION = 100;
+ final long SIZE = 200;
+ fileLock = readOnlyFileChannel.lock(POSITION, SIZE, true);
+ assertTrue(fileLock.isValid());
+ // fileLock.isShared depends on whether the underlying platform support
+ // shared lock, but it works on Windows & Linux.
+ assertTrue(fileLock.isShared());
+ assertSame(readOnlyFileChannel, fileLock.channel());
+ assertEquals(POSITION, fileLock.position());
+ assertEquals(SIZE, fileLock.size());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_NotShared() throws Exception {
+ final long POSITION = 100;
+ final long SIZE = 200;
+ fileLock = writeOnlyFileChannel.lock(POSITION, SIZE, false);
+ assertTrue(fileLock.isValid());
+ assertFalse(fileLock.isShared());
+ assertSame(writeOnlyFileChannel, fileLock.channel());
+ assertEquals(POSITION, fileLock.position());
+ assertEquals(SIZE, fileLock.size());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_Long_MAX_VALUE() throws Exception {
+ final long POSITION = 0;
+ final long SIZE = Long.MAX_VALUE;
+ fileLock = readOnlyFileChannel.lock(POSITION, SIZE, true);
+ assertTrue(fileLock.isValid());
+ assertTrue(fileLock.isShared());
+ assertEquals(POSITION, fileLock.position());
+ assertEquals(SIZE, fileLock.size());
+ assertSame(readOnlyFileChannel, fileLock.channel());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_Overlapping() throws Exception {
+ final long POSITION = 100;
+ final long SIZE = 200;
+ fileLock = writeOnlyFileChannel.lock(POSITION, SIZE, false);
+ assertTrue(fileLock.isValid());
+
+ try {
+ writeOnlyFileChannel.lock(POSITION + 1, SIZE, false);
+ fail("should throw OverlappingFileLockException");
+ } catch (OverlappingFileLockException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long, long, boolean)
+ */
+ public void test_lockJJZ_NotOverlapping() throws Exception {
+ final long POSITION = 100;
+ final long SIZE = 200;
+ FileLock fileLock1 = writeOnlyFileChannel.lock(POSITION, SIZE, false);
+ assertTrue(fileLock1.isValid());
+ FileLock fileLock2 = writeOnlyFileChannel.lock(POSITION + SIZE, SIZE,
+ false);
+ assertTrue(fileLock2.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock(long,long,boolean)
+ */
+ public void test_lockJJZ_After_Release() throws Exception {
+ fileLock = writeOnlyFileChannel.lock(0, 10, false);
+ fileLock.release();
+ // after release file lock can be obtained again.
+ fileLock = writeOnlyFileChannel.lock(0, 10, false);
+ assertTrue(fileLock.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock()
+ */
+ public void test_tryLock() throws Exception {
+ MockFileChannel mockFileChannel = new MockFileChannel();
+ // Verify that calling tryLock() leads to the method
+ // tryLock(long, long, boolean) being called with a 0 for the
+ // first parameter, Long.MAX_VALUE as the second parameter and false
+ // as the third parameter.
+ mockFileChannel.tryLock();
+ assertTrue(mockFileChannel.isTryLockCalled);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_Closed() throws Exception {
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.tryLock(0, 10, false);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.tryLock(0, 10, false);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.tryLock(0, 10, false);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // throws ClosedChannelException before IllegalArgumentException
+ try {
+ readWriteFileChannel.tryLock(-1, 0, false);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_IllegalArgument() throws Exception {
+ try {
+ writeOnlyFileChannel.tryLock(0, -1, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ writeOnlyFileChannel.tryLock(-1, 0, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.tryLock(-1, -1, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.tryLock(Long.MAX_VALUE, 1, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_NonWritable() throws Exception {
+ try {
+ readOnlyFileChannel.tryLock(0, 10, false);
+ fail("should throw NonWritableChannelException");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+
+ // throws NonWritableChannelException before IllegalArgumentException
+ try {
+ readOnlyFileChannel.tryLock(-1, 0, false);
+ fail("should throw NonWritableChannelException");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_NonReadable() throws Exception {
+ try {
+ writeOnlyFileChannel.tryLock(0, 10, true);
+ fail("should throw NonReadableChannelException");
+ } catch (NonReadableChannelException e) {
+ // expected
+ }
+
+ // throws NonReadableChannelException before IllegalArgumentException
+ try {
+ writeOnlyFileChannel.tryLock(-1, 0, true);
+ fail("should throw NonReadableChannelException");
+ } catch (NonReadableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_Shared() throws Exception {
+ final long POSITION = 100;
+ final long SIZE = 200;
+ fileLock = readOnlyFileChannel.tryLock(POSITION, SIZE, true);
+ assertTrue(fileLock.isValid());
+ // fileLock.isShared depends on whether the underlying platform support
+ // shared lock, but it works on Windows & Linux.
+ assertTrue(fileLock.isShared());
+ assertSame(readOnlyFileChannel, fileLock.channel());
+ assertEquals(POSITION, fileLock.position());
+ assertEquals(SIZE, fileLock.size());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_NotShared() throws Exception {
+ final long POSITION = 100;
+ final long SIZE = 200;
+ fileLock = writeOnlyFileChannel.tryLock(POSITION, SIZE, false);
+ assertTrue(fileLock.isValid());
+ assertFalse(fileLock.isShared());
+ assertSame(writeOnlyFileChannel, fileLock.channel());
+ assertEquals(POSITION, fileLock.position());
+ assertEquals(SIZE, fileLock.size());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_Long_MAX_VALUE() throws Exception {
+ final long POSITION = 0;
+ final long SIZE = Long.MAX_VALUE;
+ fileLock = readOnlyFileChannel.tryLock(POSITION, SIZE, true);
+ assertTrue(fileLock.isValid());
+ assertTrue(fileLock.isShared());
+ assertEquals(POSITION, fileLock.position());
+ assertEquals(SIZE, fileLock.size());
+ assertSame(readOnlyFileChannel, fileLock.channel());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_Overlapping() throws Exception {
+ final long POSITION = 100;
+ final long SIZE = 200;
+ fileLock = writeOnlyFileChannel.lock(POSITION, SIZE, false);
+ assertTrue(fileLock.isValid());
+
+ try {
+ writeOnlyFileChannel.lock(POSITION + 1, SIZE, false);
+ fail("should throw OverlappingFileLockException");
+ } catch (OverlappingFileLockException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long, long, boolean)
+ */
+ public void test_tryLockJJZ_NotOverlapping() throws Exception {
+ final long POSITION = 100;
+ final long SIZE = 200;
+ FileLock fileLock1 = writeOnlyFileChannel
+ .tryLock(POSITION, SIZE, false);
+ assertTrue(fileLock1.isValid());
+
+ FileLock fileLock2 = writeOnlyFileChannel.tryLock(POSITION + SIZE,
+ SIZE, false);
+ assertTrue(fileLock2.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock(long,long,boolean)
+ */
+ public void test_tryLockJJZ_After_Release() throws Exception {
+ fileLock = writeOnlyFileChannel.tryLock(0, 10, false);
+ fileLock.release();
+
+ // after release file lock can be obtained again.
+ fileLock = writeOnlyFileChannel.tryLock(0, 10, false);
+ assertTrue(fileLock.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer)
+ */
+ public void test_readLByteBuffer_Null() throws Exception {
+ ByteBuffer readBuffer = null;
+
+ try {
+ readOnlyFileChannel.read(readBuffer);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.read(readBuffer);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer)
+ */
+ public void test_readLByteBuffer_Closed() throws Exception {
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.read(readBuffer);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.read(readBuffer);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.read(readBuffer);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // should throw ClosedChannelException first
+ readBuffer = null;
+ try {
+ readWriteFileChannel.read(readBuffer);
+ fail();
+ } catch (ClosedChannelException expected) {
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_readLByteBuffer_WriteOnly() throws Exception {
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+
+ try {
+ writeOnlyFileChannel.read(readBuffer);
+ fail();
+ } catch (NonReadableChannelException expected) {
+ }
+
+ readBuffer = null;
+ try {
+ writeOnlyFileChannel.read(readBuffer);
+ fail();
+ } catch (NonReadableChannelException expected) {
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_readLByteBuffer_EmptyFile() throws Exception {
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+ int result = readOnlyFileChannel.read(readBuffer);
+ assertEquals(-1, result);
+ assertEquals(0, readBuffer.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer)
+ */
+ public void test_readLByteBuffer_LimitedCapacity() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+
+ ByteBuffer readBuffer = ByteBuffer.allocate(LIMITED_CAPACITY);
+ int result = readOnlyFileChannel.read(readBuffer);
+ assertEquals(LIMITED_CAPACITY, result);
+ assertEquals(LIMITED_CAPACITY, readBuffer.position());
+ readBuffer.flip();
+ for (int i = 0; i < LIMITED_CAPACITY; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
+ }
+ }
+
+ public void test_readLByteBuffer() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+
+ ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_AS_BYTES_LENGTH);
+ int result = readOnlyFileChannel.read(readBuffer);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, result);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, readBuffer.position());
+ readBuffer.flip();
+ for (int i = 0; i < CONTENT_AS_BYTES_LENGTH; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
+ }
+ }
+
+ public void test_readLByteBufferJ_Null() throws Exception {
+ try {
+ readOnlyFileChannel.read(null, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ readWriteFileChannel.read(null, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_readLByteBufferJ_Closed() throws Exception {
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.read(readBuffer, 0);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.read(readBuffer, 0);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ public void test_readLByteBufferJ_IllegalArgument() throws Exception {
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+
+ try {
+ readOnlyFileChannel.read(readBuffer, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ writeOnlyFileChannel.read(readBuffer, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ readWriteFileChannel.read(readBuffer, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_readLByteBufferJ_WriteOnly() throws Exception {
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+
+ try {
+ writeOnlyFileChannel.read(readBuffer, 0);
+ fail();
+ } catch (NonReadableChannelException expected) {
+ }
+ }
+
+ public void test_readLByteBufferJ_Emptyfile() throws Exception {
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+ int result = readOnlyFileChannel.read(readBuffer, 0);
+ assertEquals(-1, result);
+ assertEquals(0, readBuffer.position());
+ }
+
+ public void test_readLByteBufferJ_Position_BeyondFileLimit() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+ int result = readOnlyFileChannel.read(readBuffer,
+ CONTENT_AS_BYTES.length);
+ assertEquals(-1, result);
+ assertEquals(0, readBuffer.position());
+ }
+
+ public void test_readLByteBufferJ_Position_As_Long() throws Exception {
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+ try {
+ readOnlyFileChannel.read(readBuffer, Long.MAX_VALUE);
+ } catch (IOException expected) {
+ }
+ }
+
+ public void test_readLByteBufferJ() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ ByteBuffer readBuffer = ByteBuffer.allocate(CAPACITY);
+
+ final int BUFFER_POSITION = 1;
+ readBuffer.position(BUFFER_POSITION);
+
+ final int POSITION = 2;
+ int result = readOnlyFileChannel.read(readBuffer, POSITION);
+ assertEquals(CONTENT_AS_BYTES_LENGTH - POSITION, result);
+ assertEquals(BUFFER_POSITION + result, readBuffer.position());
+
+ readBuffer.flip();
+ readBuffer.position(BUFFER_POSITION);
+ for (int i = POSITION; i < CONTENT_AS_BYTES_LENGTH; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[])
+ */
+ public void test_read$LByteBuffer() throws Exception {
+ // regression test for Harmony-849
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ readBuffers[0] = ByteBuffer.allocate(CAPACITY);
+ readBuffers[1] = ByteBuffer.allocate(CAPACITY);
+
+ long readCount = readOnlyFileChannel.read(readBuffers);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, readCount);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, readBuffers[0].position());
+ assertEquals(0, readBuffers[1].position());
+ readBuffers[0].flip();
+ for (int i = 0; i < CONTENT_AS_BYTES_LENGTH; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffers[0].get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[])
+ */
+ public void test_read$LByteBuffer_mock() throws Exception {
+ FileChannel mockChannel = new MockFileChannel();
+ ByteBuffer[] buffers = new ByteBuffer[2];
+ mockChannel.read(buffers);
+ // Verify that calling read(ByteBuffer[] dsts) leads to the method
+ // read(dsts, 0, dsts.length)
+ assertTrue(((MockFileChannel)mockChannel).isReadCalled);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_Null() throws Exception {
+ ByteBuffer[] readBuffers = null;
+
+ try {
+ readOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ readOnlyFileChannel.read(readBuffers, 1, 11);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ writeOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.read(readBuffers, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // first throws NullPointerException
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_Closed() throws Exception {
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ readBuffers[0] = ByteBuffer.allocate(CAPACITY);
+
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.read(readBuffers, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // regression test for Harmony-902
+ readBuffers[0] = null;
+ try {
+ readOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ try {
+ writeOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ try {
+ readWriteFileChannel.read(readBuffers, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_WriteOnly() throws Exception {
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ readBuffers[0] = ByteBuffer.allocate(CAPACITY);
+
+ try {
+ writeOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw NonReadableChannelException");
+ } catch (NonReadableChannelException e) {
+ // expected
+ }
+
+ // first throws NonReadableChannelException.
+ readBuffers[0] = null;
+ try {
+ writeOnlyFileChannel.read(readBuffers, 0, 1);
+ fail("should throw NonReadableChannelException");
+ } catch (NonReadableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_IndexOutOfBound() throws Exception {
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ readBuffers[0] = ByteBuffer.allocate(CAPACITY);
+ readBuffers[1] = ByteBuffer.allocate(CAPACITY);
+
+ try {
+ readOnlyFileChannel.read(readBuffers, 2, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ readWriteFileChannel.read(null, -1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ writeOnlyFileChannel.read(readBuffers, 0, 3);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ readWriteFileChannel.read(readBuffers, -1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.read(readBuffers, 0, 3);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_EmptyFile() throws Exception {
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ readBuffers[0] = ByteBuffer.allocate(CAPACITY);
+ readBuffers[1] = ByteBuffer.allocate(CAPACITY);
+ long result = readOnlyFileChannel.read(readBuffers, 0, 2);
+ assertEquals(-1, result);
+ assertEquals(0, readBuffers[0].position());
+ assertEquals(0, readBuffers[1].position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_EmptyBuffers() throws Exception {
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ try {
+ readOnlyFileChannel.read(readBuffers, 0, 2);
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ readBuffers[0] = ByteBuffer.allocate(CAPACITY);
+ try {
+ readOnlyFileChannel.read(readBuffers, 0, 2);
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ long result = readOnlyFileChannel.read(readBuffers, 0, 1);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, result);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_EmptyFile_EmptyBuffers()
+ throws Exception {
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ // will not throw NullPointerException
+ long result = readOnlyFileChannel.read(readBuffers, 0, 0);
+ assertEquals(0, result);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_Length_Zero() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ readBuffers[0] = ByteBuffer.allocate(LIMITED_CAPACITY);
+ readBuffers[1] = ByteBuffer.allocate(LIMITED_CAPACITY);
+ long result = readOnlyFileChannel.read(readBuffers, 1, 0);
+ assertEquals(0, result);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII_LimitedCapacity() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ readBuffers[0] = ByteBuffer.allocate(LIMITED_CAPACITY);
+ readBuffers[1] = ByteBuffer.allocate(LIMITED_CAPACITY);
+
+ // reads to the second buffer
+ long result = readOnlyFileChannel.read(readBuffers, 1, 1);
+ assertEquals(LIMITED_CAPACITY, result);
+ assertEquals(0, readBuffers[0].position());
+ assertEquals(LIMITED_CAPACITY, readBuffers[1].position());
+
+ readBuffers[1].flip();
+ for (int i = 0; i < LIMITED_CAPACITY; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffers[1].get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read$LByteBufferII() throws Exception {
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ ByteBuffer[] readBuffers = new ByteBuffer[2];
+ readBuffers[0] = ByteBuffer.allocate(CAPACITY);
+ readBuffers[1] = ByteBuffer.allocate(CAPACITY);
+
+ // writes to the second buffer
+ assertEquals(CONTENT_AS_BYTES_LENGTH, readOnlyFileChannel.read(
+ readBuffers, 1, 1));
+ assertEquals(0, readBuffers[0].position());
+ assertEquals(CONTENT_AS_BYTES_LENGTH, readBuffers[1].position());
+
+ readBuffers[1].flip();
+ for (int i = 0; i < CONTENT_AS_BYTES_LENGTH; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffers[1].get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#isOpen()
+ */
+ public void test_isOpen() throws Exception {
+ // Regression for HARMONY-40
+ File logFile = File.createTempFile("out", "tmp");
+ logFile.deleteOnExit();
+ FileOutputStream out = new FileOutputStream(logFile, true);
+ FileChannel channel = out.getChannel();
+ out.write(1);
+ out.close();
+ assertFalse("Assert 0: Channel is still open", channel.isOpen());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#position()
+ */
+ public void test_position_append() throws Exception {
+ // Regression test for Harmony-508
+ File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+ tmpfile.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmpfile);
+ byte[] b = new byte[10];
+ for (int i = 0; i < b.length; i++) {
+ b[i] = (byte) i;
+ }
+ fos.write(b);
+ fos.flush();
+ fos.close();
+ FileOutputStream f = new FileOutputStream(tmpfile, true);
+ // Harmony expected 10, but the RI and Android report 0.
+ assertEquals(0, f.getChannel().position());
+ }
+
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_AbnormalMode() throws IOException {
+ try {
+ writeOnlyFileChannel.map(MapMode.READ_ONLY, 0, CONTENT_LENGTH);
+ fail("should throw NonReadableChannelException.");
+ } catch (NonReadableChannelException ex) {
+ // expected;
+ }
+ try {
+ writeOnlyFileChannel.map(MapMode.READ_WRITE, 0, CONTENT_LENGTH);
+ fail("should throw NonReadableChannelException.");
+ } catch (NonReadableChannelException ex) {
+ // expected;
+ }
+ try {
+ writeOnlyFileChannel.map(MapMode.PRIVATE, 0, CONTENT_LENGTH);
+ fail("should throw NonReadableChannelException.");
+ } catch (NonReadableChannelException ex) {
+ // expected;
+ }
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.map(MapMode.READ_WRITE, 0, -1);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException ex) {
+ // expected;
+ }
+
+ try {
+ readOnlyFileChannel.map(MapMode.READ_WRITE, 0, CONTENT_LENGTH);
+ fail("should throw NonWritableChannelException .");
+ } catch (NonWritableChannelException ex) {
+ // expected;
+ }
+ try {
+ readOnlyFileChannel.map(MapMode.PRIVATE, 0, CONTENT_LENGTH);
+ fail("should throw NonWritableChannelException .");
+ } catch (NonWritableChannelException ex) {
+ // expected;
+ }
+ try {
+ readOnlyFileChannel.map(MapMode.READ_WRITE, -1, CONTENT_LENGTH);
+ fail("should throw IAE.");
+ } catch (IllegalArgumentException ex) {
+ // expected;
+ }
+ try {
+ readOnlyFileChannel.map(MapMode.READ_WRITE, 0, -1);
+ fail("should throw IAE.");
+ } catch (IllegalArgumentException ex) {
+ // expected;
+ }
+
+ try {
+ readOnlyFileChannel.map(MapMode.READ_ONLY, 0, CONTENT_LENGTH + 1);
+ fail();
+ } catch (NonWritableChannelException expected) {
+ } catch (IOException expected) {
+ }
+ try {
+ readOnlyFileChannel.map(MapMode.READ_ONLY, 2, CONTENT_LENGTH - 1);
+ fail();
+ } catch (NonWritableChannelException expected) {
+ } catch (IOException expected) {
+ }
+
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.map(MapMode.READ_WRITE, 0, -1);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException ex) {
+ // expected;
+ }
+ try {
+ readOnlyFileChannel.map(MapMode.READ_ONLY, 2, CONTENT_LENGTH - 1);
+ fail("should throw IOException.");
+ } catch (IOException ex) {
+ // expected;
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.map(MapMode.READ_WRITE, 0, -1);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException ex) {
+ // expected;
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_ReadOnly_CloseChannel() throws IOException {
+ // close channel has no effect on map if mapped
+ assertEquals(0, readWriteFileChannel.size());
+ MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.READ_ONLY,
+ 0, CONTENT_LENGTH);
+ assertEquals(CONTENT_LENGTH, readWriteFileChannel.size());
+ readOnlyFileChannel.close();
+ assertEquals(CONTENT_LENGTH, mapped.limit());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_Private_CloseChannel() throws IOException {
+ MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.PRIVATE, 0,
+ CONTENT_LENGTH);
+ readWriteFileChannel.close();
+ mapped.put(TEST_BYTES);
+ assertEquals(CONTENT_LENGTH, mapped.limit());
+ assertEquals("test".length(), mapped.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_ReadOnly() throws IOException {
+ MappedByteBuffer mapped = null;
+ // try put something to readonly map
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ mapped = readOnlyFileChannel.map(MapMode.READ_ONLY, 0, CONTENT_LENGTH);
+ try {
+ mapped.put(TEST_BYTES);
+ fail("should throw ReadOnlyBufferException.");
+ } catch (ReadOnlyBufferException ex) {
+ // expected;
+ }
+ assertEquals(CONTENT_LENGTH, mapped.limit());
+ assertEquals(CONTENT_LENGTH, mapped.capacity());
+ assertEquals(0, mapped.position());
+
+ // try to get a readonly map from read/write channel
+ writeDataToFile(fileOfReadWriteFileChannel);
+ mapped = readWriteFileChannel.map(MapMode.READ_ONLY, 0, CONTENT
+ .length());
+ assertEquals(CONTENT_LENGTH, mapped.limit());
+ assertEquals(CONTENT_LENGTH, mapped.capacity());
+ assertEquals(0, mapped.position());
+
+ // map not change channel's position
+ assertEquals(0, readOnlyFileChannel.position());
+ assertEquals(0, readWriteFileChannel.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_ReadOnly_NonZeroPosition() throws IOException {
+ this.writeDataToFile(fileOfReadOnlyFileChannel);
+ MappedByteBuffer mapped = readOnlyFileChannel.map(MapMode.READ_ONLY,
+ 10, CONTENT_LENGTH - 10);
+ assertEquals(CONTENT_LENGTH - 10, mapped.limit());
+ assertEquals(CONTENT_LENGTH - 10, mapped.capacity());
+ assertEquals(0, mapped.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_Private() throws IOException {
+ this.writeDataToFile(fileOfReadWriteFileChannel);
+ MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.PRIVATE, 0,
+ CONTENT_LENGTH);
+ assertEquals(CONTENT_LENGTH, mapped.limit());
+ // test copy on write if private
+ ByteBuffer returnByPut = mapped.put(TEST_BYTES);
+ assertSame(returnByPut, mapped);
+ ByteBuffer checkBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
+ mapped.force();
+ readWriteFileChannel.read(checkBuffer);
+ assertEquals(CONTENT, new String(checkBuffer.array(), "iso8859-1"));
+
+ // test overflow
+ try {
+ mapped.put(("test" + CONTENT).getBytes("iso8859-1"));
+ fail("should throw BufferOverflowException.");
+ } catch (BufferOverflowException ex) {
+ // expected;
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_Private_NonZeroPosition() throws IOException {
+ MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.PRIVATE, 10,
+ CONTENT_LENGTH - 10);
+ assertEquals(CONTENT_LENGTH - 10, mapped.limit());
+ assertEquals(CONTENT_LENGTH - 10, mapped.capacity());
+ assertEquals(0, mapped.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_ReadWrite() throws IOException {
+ MappedByteBuffer mapped = null;
+ writeDataToFile(fileOfReadWriteFileChannel);
+ mapped = readWriteFileChannel.map(MapMode.READ_WRITE, 0, CONTENT
+ .length());
+
+ // put something will change its channel
+ ByteBuffer returnByPut = mapped.put(TEST_BYTES);
+ assertSame(returnByPut, mapped);
+ String checkString = "test" + CONTENT.substring(4);
+ ByteBuffer checkBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
+ mapped.force();
+ readWriteFileChannel.position(0);
+ readWriteFileChannel.read(checkBuffer);
+ assertEquals(checkString, new String(checkBuffer.array(), "iso8859-1"));
+
+ try {
+ mapped.put(("test" + CONTENT).getBytes("iso8859-1"));
+ fail("should throw BufferOverflowException.");
+ } catch (BufferOverflowException ex) {
+ // expected;
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_ReadWrite_NonZeroPosition() throws IOException {
+ // test position non-zero
+ writeDataToFile(fileOfReadWriteFileChannel);
+ MappedByteBuffer mapped = readWriteFileChannel.map(MapMode.READ_WRITE,
+ 10, CONTENT_LENGTH - 10);
+ assertEquals(CONTENT_LENGTH - 10, mapped.limit());
+ assertEquals(CONTENT.length() - 10, mapped.capacity());
+ assertEquals(0, mapped.position());
+ mapped.put(TEST_BYTES);
+ ByteBuffer checkBuffer = ByteBuffer.allocate(CONTENT_LENGTH);
+ readWriteFileChannel.read(checkBuffer);
+ String expected = CONTENT.substring(0, 10) + "test"
+ + CONTENT.substring(10 + "test".length());
+ assertEquals(expected, new String(checkBuffer.array(), "iso8859-1"));
+ }
+
+ /**
+ * Tests map() method for the value of positions exceeding memory
+ * page size and allocation granularity size.
+ *
+ * @tests java.nio.channels.FileChannel#map(MapMode,long,long)
+ */
+ public void test_map_LargePosition() throws IOException {
+ // Regression test for HARMONY-3085
+ int[] sizes = {
+ 4096, // 4K size (normal page size for Linux & Windows)
+ 65536, // 64K size (alocation granularity size for Windows)
+ };
+ final int CONTENT_LEN = 10;
+
+ for (int i = 0; i < sizes.length; ++i) {
+ // reset the file and the channel for the iterations
+ // (for the first iteration it was done by setUp()
+ if (i > 0 ) {
+ fileOfReadOnlyFileChannel = File.createTempFile(
+ "File_of_readOnlyFileChannel", "tmp");
+ fileOfReadOnlyFileChannel.deleteOnExit();
+ readOnlyFileChannel = new FileInputStream(fileOfReadOnlyFileChannel)
+ .getChannel();
+ }
+
+ writeLargeDataToFile(fileOfReadOnlyFileChannel, sizes[i] + 2 * CONTENT_LEN);
+ MappedByteBuffer mapped = readOnlyFileChannel.map(MapMode.READ_ONLY,
+ sizes[i], CONTENT_LEN);
+ assertEquals("Incorrectly mapped file channel for " + sizes[i]
+ + " position (capacity)", CONTENT_LEN, mapped.capacity());
+ assertEquals("Incorrectly mapped file channel for " + sizes[i]
+ + " position (limit)", CONTENT_LEN, mapped.limit());
+ assertEquals("Incorrectly mapped file channel for " + sizes[i]
+ + " position (position)", 0, mapped.position());
+
+ // map not change channel's position
+ assertEquals(0, readOnlyFileChannel.position());
+
+ // Close the file and the channel before the next iteration
+ readOnlyFileChannel.close();
+ fileOfReadOnlyFileChannel.delete();
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer)
+ */
+ public void test_writeLByteBuffer_Null() throws Exception {
+ ByteBuffer writeBuffer = null;
+
+ try {
+ writeOnlyFileChannel.write(writeBuffer);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.write(writeBuffer);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer)
+ */
+ public void test_writeLByteBuffer_Closed() throws Exception {
+ ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
+
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.write(writeBuffer);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.write(writeBuffer);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.write(writeBuffer);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ writeBuffer = null;
+ try {
+ readWriteFileChannel.read(writeBuffer);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer)
+ */
+ public void test_writeLByteBuffer_ReadOnly() throws Exception {
+ ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
+
+ try {
+ readOnlyFileChannel.write(writeBuffer);
+ fail("should throw NonWritableChannelException");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+
+ // first throws NonWriteableChannelException
+ writeBuffer = null;
+ try {
+ readOnlyFileChannel.write(writeBuffer);
+ fail("should throw NonWritableChannelException");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer)
+ */
+ public void test_writeLByteBuffer() throws Exception {
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+
+ int result = writeOnlyFileChannel.write(writeBuffer);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, result);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffer.position());
+ writeOnlyFileChannel.close();
+
+ assertEquals(CONTENT_AS_BYTES_LENGTH, fileOfWriteOnlyFileChannel
+ .length());
+
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ byte[] inputBuffer = new byte[CONTENT_AS_BYTES_LENGTH];
+ fis.read(inputBuffer);
+ assertTrue(Arrays.equals(CONTENT_AS_BYTES, inputBuffer));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer)
+ */
+ public void test_writeLByteBuffer_positioned() throws Exception {
+ final int pos = 5;
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ writeBuffer.position(pos);
+ int result = writeOnlyFileChannel.write(writeBuffer);
+ assertEquals(CONTENT_AS_BYTES_LENGTH - pos, result);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffer.position());
+ writeOnlyFileChannel.close();
+
+ assertEquals(CONTENT_AS_BYTES_LENGTH - pos, fileOfWriteOnlyFileChannel
+ .length());
+
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ byte[] inputBuffer = new byte[CONTENT_AS_BYTES_LENGTH - pos];
+ fis.read(inputBuffer);
+ String test = CONTENT.substring(pos);
+ assertTrue(Arrays.equals(test.getBytes("iso8859-1"), inputBuffer));
+ }
+
+ public void test_writeLByteBufferJ_Null() throws Exception {
+ try {
+ readWriteFileChannel.write(null, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (NonWritableChannelException expected) {
+ }
+
+ try {
+ writeOnlyFileChannel.write(null, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ readWriteFileChannel.write(null, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_writeLByteBufferJ_Closed() throws Exception {
+ ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.write(writeBuffer, 0);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.write(writeBuffer, 0);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ public void test_writeLByteBufferJ_ReadOnly() throws Exception {
+ ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
+ try {
+ readOnlyFileChannel.write(writeBuffer, 10);
+ fail();
+ } catch (NonWritableChannelException expected) {
+ }
+ }
+
+ public void test_writeLByteBufferJ_IllegalArgument() throws Exception {
+ ByteBuffer writeBuffer = ByteBuffer.allocate(CAPACITY);
+
+ try {
+ readOnlyFileChannel.write(writeBuffer, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ writeOnlyFileChannel.write(writeBuffer, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ readWriteFileChannel.write(writeBuffer, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer,long)
+ */
+ public void test_writeLByteBufferJ() throws Exception {
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ final int POSITION = 4;
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ int result = writeOnlyFileChannel.write(writeBuffer, POSITION);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, result);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffer.position());
+ writeOnlyFileChannel.close();
+
+ assertEquals(POSITION + CONTENT_AS_BYTES_LENGTH,
+ fileOfWriteOnlyFileChannel.length());
+
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ byte[] inputBuffer = new byte[POSITION + CONTENT_AS_BYTES_LENGTH];
+ fis.read(inputBuffer);
+ byte[] expectedResult = new byte[POSITION + CONTENT_AS_BYTES_LENGTH];
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, 0, POSITION);
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, POSITION,
+ CONTENT_AS_BYTES_LENGTH);
+ assertTrue(Arrays.equals(expectedResult, inputBuffer));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer[])
+ */
+ public void test_write$LByteBuffer() throws Exception {
+ ByteBuffer[] writeBuffers = new ByteBuffer[2];
+ MockFileChannel mockFileChannel = new MockFileChannel();
+ mockFileChannel.write(writeBuffers);
+ // verify that calling write(ByteBuffer[] srcs) leads to the method
+ // write(srcs, 0, srcs.length)
+ assertTrue(mockFileChannel.isWriteCalled);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
+ */
+ public void test_write$LByteBufferII_Null() throws Exception {
+ ByteBuffer[] writeBuffers = null;
+
+ try {
+ readOnlyFileChannel.write(writeBuffers, 1, 2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ writeOnlyFileChannel.write(writeBuffers, 1, 2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.write(writeBuffers, 1, 2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // first throws NullPointerException
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.write(writeBuffers, 0, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
+ */
+ public void test_write$LByteBufferII_Closed() throws Exception {
+ ByteBuffer[] writeBuffers = new ByteBuffer[2];
+ writeBuffers[0] = ByteBuffer.allocate(CAPACITY);
+ writeBuffers[1] = ByteBuffer.allocate(CAPACITY);
+
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.write(writeBuffers, 0, 2);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.write(writeBuffers, 0, 2);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.write(writeBuffers, 0, 2);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // throws ClosedChannelException first
+ writeBuffers[0] = null;
+ try {
+ readWriteFileChannel.write(writeBuffers, 0, 2);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
+ */
+ public void test_write$LByteBufferII_ReadOnly() throws Exception {
+ ByteBuffer[] writeBuffers = new ByteBuffer[2];
+ writeBuffers[0] = ByteBuffer.allocate(CAPACITY);
+ writeBuffers[1] = ByteBuffer.allocate(CAPACITY);
+
+ try {
+ readOnlyFileChannel.write(writeBuffers, 0, 2);
+ fail();
+ } catch (NonWritableChannelException e) {
+ }
+
+ try {
+ readOnlyFileChannel.write(writeBuffers, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ writeBuffers = null;
+ try {
+ readOnlyFileChannel.write(writeBuffers, 0, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ readOnlyFileChannel.close();
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
+ */
+ public void test_write$LByteBufferII_EmptyBuffers() throws Exception {
+ ByteBuffer[] writeBuffers = new ByteBuffer[2];
+ try {
+ writeOnlyFileChannel.write(writeBuffers, 0, 2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.write(writeBuffers, 0, 2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#write(ByteBuffer[],int,int)
+ */
+ public void test_write$LByteBufferII() throws Exception {
+ ByteBuffer[] writeBuffers = new ByteBuffer[2];
+ writeBuffers[0] = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ writeBuffers[1] = ByteBuffer.wrap(CONTENT_AS_BYTES);
+
+ long result = writeOnlyFileChannel.write(writeBuffers, 0, 2);
+ assertEquals(CONTENT_AS_BYTES_LENGTH * 2, result);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffers[0].position());
+ assertEquals(CONTENT_AS_BYTES_LENGTH, writeBuffers[1].position());
+ writeOnlyFileChannel.close();
+
+ assertEquals(CONTENT_AS_BYTES_LENGTH * 2, fileOfWriteOnlyFileChannel
+ .length());
+
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ byte[] inputBuffer = new byte[CONTENT_AS_BYTES_LENGTH];
+ fis.read(inputBuffer);
+ byte[] expectedResult = new byte[CONTENT_AS_BYTES_LENGTH * 2];
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult, 0,
+ CONTENT_AS_BYTES_LENGTH);
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedResult,
+ CONTENT_AS_BYTES_LENGTH, CONTENT_AS_BYTES_LENGTH);
+ assertTrue(Arrays.equals(CONTENT_AS_BYTES, inputBuffer));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_Closed()
+ throws Exception {
+ readByteChannel = DatagramChannel.open();
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.transferFrom(readByteChannel, 0, 0);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.transferFrom(readByteChannel, 0, 10);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.transferFrom(readByteChannel, 0, 0);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // should throw ClosedChannelException first.
+ try {
+ readWriteFileChannel.transferFrom(readByteChannel, 0, -1);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_SourceClosed()
+ throws Exception {
+ readByteChannel = DatagramChannel.open();
+ readByteChannel.close();
+
+ try {
+ readOnlyFileChannel.transferFrom(readByteChannel, 0, 10);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ try {
+ writeOnlyFileChannel.transferFrom(readByteChannel, 0, 10);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.transferFrom(readByteChannel, 0, 10);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // should throw ClosedChannelException first.
+ try {
+ readWriteFileChannel.transferFrom(readByteChannel, 0, -1);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_IllegalArgument()
+ throws Exception {
+ readByteChannel = DatagramChannel.open();
+ try {
+ writeOnlyFileChannel.transferFrom(readByteChannel, 10, -1);
+ fail("should throw IllegalArgumentException.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.transferFrom(readByteChannel, -1, -10);
+ fail("should throw IllegalArgumentException.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_NonWritable()
+ throws Exception {
+ readByteChannel = DatagramChannel.open();
+ try {
+ readOnlyFileChannel.transferFrom(readByteChannel, 0, 0);
+ fail("should throw NonWritableChannelException.");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_SourceNonReadable()
+ throws Exception {
+ try {
+ readWriteFileChannel.transferFrom(writeOnlyFileChannel, 0, 0);
+ fail("should throw NonReadableChannelException.");
+ } catch (NonReadableChannelException e) {
+ // expected
+ }
+
+ // not throws NonReadableChannelException first if position beyond file
+ // size.
+ readWriteFileChannel.transferFrom(writeOnlyFileChannel, 10, 10);
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_PositionBeyondSize()
+ throws Exception {
+ // init data to file.
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ final int READONLYFILECHANNELPOSITION = 2;
+ readOnlyFileChannel.position(READONLYFILECHANNELPOSITION);
+
+ final int POSITION = CONTENT_AS_BYTES_LENGTH * 2;
+ final int LENGTH = 5;
+ long result = writeOnlyFileChannel.transferFrom(readOnlyFileChannel,
+ POSITION, LENGTH);
+ assertEquals(0, result);
+ assertEquals(0, writeOnlyFileChannel.position());
+ assertEquals(READONLYFILECHANNELPOSITION, readOnlyFileChannel
+ .position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_FileChannel()
+ throws Exception {
+ // init data to file.
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ final int READONLYFILECHANNELPOSITION = 2;
+ final int WRITEONLYFILECHANNELPOSITION = 4;
+ readOnlyFileChannel.position(READONLYFILECHANNELPOSITION);
+ writeOnlyFileChannel.position(WRITEONLYFILECHANNELPOSITION);
+
+ final int POSITION = 3;
+ final int LENGTH = 5;
+ long result = writeOnlyFileChannel.transferFrom(readOnlyFileChannel,
+ POSITION, LENGTH);
+ assertEquals(LENGTH, result);
+ assertEquals(WRITEONLYFILECHANNELPOSITION, writeOnlyFileChannel
+ .position());
+ assertEquals(READONLYFILECHANNELPOSITION + LENGTH, readOnlyFileChannel
+ .position());
+ writeOnlyFileChannel.close();
+
+ final int EXPECTED_LENGTH = POSITION + LENGTH;
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ byte[] resultContent = new byte[EXPECTED_LENGTH];
+ fis.read(resultContent);
+
+ byte[] expectedContent = new byte[EXPECTED_LENGTH];
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedContent, 0, POSITION);
+ System.arraycopy(CONTENT_AS_BYTES, READONLYFILECHANNELPOSITION,
+ expectedContent, POSITION, LENGTH);
+ assertTrue(Arrays.equals(expectedContent, resultContent));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_DatagramChannel()
+ throws Exception {
+ // connects two datagramChannels.
+ datagramChannelReceiver = DatagramChannel.open();
+ datagramChannelReceiver.socket().bind(
+ new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ datagramChannelSender = DatagramChannel.open();
+ datagramChannelSender.socket().bind(
+ new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ datagramChannelReceiver.socket().setSoTimeout(TIME_OUT);
+ datagramChannelReceiver.connect(datagramChannelSender.socket()
+ .getLocalSocketAddress());
+ datagramChannelSender.socket().setSoTimeout(TIME_OUT);
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ datagramChannelSender.socket().setSoTimeout(TIME_OUT);
+ // sends data from datagramChannelSender to datagramChannelReceiver.
+ datagramChannelSender.send(writeBuffer, datagramChannelReceiver
+ .socket().getLocalSocketAddress());
+ datagramChannelReceiver.socket().setSoTimeout(TIME_OUT);
+
+ // transfers data from datagramChannelReceiver to fileChannel.
+ long result = writeOnlyFileChannel.transferFrom(
+ datagramChannelReceiver, 0, CONTENT_AS_BYTES_LENGTH);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, result);
+ assertEquals(0, writeOnlyFileChannel.position());
+ writeOnlyFileChannel.close();
+
+ // gets content from file.
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, fileOfWriteOnlyFileChannel
+ .length());
+ byte[] resultContent = new byte[CONTENT_AS_BYTES_LENGTH];
+ fis.read(resultContent);
+
+ // compares contents.
+ assertTrue(Arrays.equals(CONTENT_AS_BYTES, resultContent));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_SocketChannel()
+ throws Exception {
+ // connects two socketChannels.
+ socketChannelReceiver = SocketChannel.open();
+ serverSocketChannel = ServerSocketChannel.open();
+ serverSocketChannel.socket().bind(
+ new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ socketChannelReceiver.socket().setSoTimeout(TIME_OUT);
+ socketChannelReceiver.connect(serverSocketChannel.socket()
+ .getLocalSocketAddress());
+ serverSocketChannel.socket().setSoTimeout(TIME_OUT);
+ socketChannelSender = serverSocketChannel.accept();
+ socketChannelSender.socket().setSoTimeout(TIME_OUT);
+
+ // sends data from socketChannelSender to socketChannelReceiver.
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ socketChannelSender.write(writeBuffer);
+
+ // transfers data from socketChannelReceiver to fileChannel.
+ long result = readWriteFileChannel.transferFrom(socketChannelReceiver,
+ 0, CONTENT_AS_BYTES_LENGTH);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, result);
+ assertEquals(0, readWriteFileChannel.position());
+ readWriteFileChannel.close();
+
+ // gets content from file.
+ fis = new FileInputStream(fileOfReadWriteFileChannel);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, fileOfReadWriteFileChannel
+ .length());
+ byte[] resultContent = new byte[CONTENT_AS_BYTES_LENGTH];
+ fis.read(resultContent);
+
+ // compares content.
+ assertTrue(Arrays.equals(CONTENT_AS_BYTES, resultContent));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferFrom(ReadableByteChannel,long,long)
+ */
+ public void test_transferFromLReadableByteChannelJJ_Pipe() throws Exception {
+ // inits data in file.
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ // inits pipe.
+ pipe = Pipe.open();
+
+ // writes content to pipe.
+ ByteBuffer writeBuffer = ByteBuffer.wrap(CONTENT_AS_BYTES);
+ pipe.sink().write(writeBuffer);
+
+ // transfers data from pipe to fileChannel.
+ final int OFFSET = 2;
+ final int LENGTH = 4;
+ long result = writeOnlyFileChannel.transferFrom(pipe.source(), OFFSET,
+ LENGTH);
+ assertEquals(LENGTH, result);
+ writeOnlyFileChannel.close();
+
+ // gets content from file.
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ byte[] resultBytes = new byte[OFFSET + LENGTH];
+ fis.read(resultBytes);
+
+ // compares content.
+ byte[] expectedBytes = new byte[OFFSET + LENGTH];
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedBytes, 0, OFFSET);
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedBytes, OFFSET, LENGTH);
+
+ assertTrue(Arrays.equals(expectedBytes, resultBytes));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_Null() throws Exception {
+ writableByteChannel = null;
+ try {
+ readOnlyFileChannel.transferTo(0, 10, writableByteChannel);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ writeOnlyFileChannel.transferTo(0, 10, writableByteChannel);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (NonReadableChannelException expected) {
+ }
+
+ try {
+ readWriteFileChannel.transferTo(0, 10, writableByteChannel);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ readOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.transferTo(-1, 0, writableByteChannel);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (NonReadableChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_Closed() throws Exception {
+ writableByteChannel = DatagramChannel.open();
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.transferTo(0, 10, writableByteChannel);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.transferTo(0, 10, writableByteChannel);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.transferTo(0, 10, writableByteChannel);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // should throw ClosedChannelException first.
+ try {
+ readWriteFileChannel.transferTo(0, -1, writableByteChannel);
+ fail("should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ public void test_transferToJJLWritableByteChannel_SourceClosed() throws Exception {
+ writableByteChannel = DatagramChannel.open();
+ writableByteChannel.close();
+
+ try {
+ readOnlyFileChannel.transferTo(0, 10, writableByteChannel);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ try {
+ writeOnlyFileChannel.transferTo(0, 10, writableByteChannel);
+ fail();
+ } catch (ClosedChannelException expected) {
+ } catch (NonReadableChannelException expected) {
+ }
+
+ try {
+ readWriteFileChannel.transferTo(0, 10, writableByteChannel);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ try {
+ readWriteFileChannel.transferTo(0, -1, writableByteChannel);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_IllegalArgument()
+ throws Exception {
+ writableByteChannel = DatagramChannel.open();
+ try {
+ readOnlyFileChannel.transferTo(10, -1, writableByteChannel);
+ fail("should throw IllegalArgumentException.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.transferTo(-1, -10, writableByteChannel);
+ fail("should throw IllegalArgumentException.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void test_transferToJJLWritableByteChannel_NonReadable() throws Exception {
+ writableByteChannel = DatagramChannel.open();
+ try {
+ writeOnlyFileChannel.transferTo(0, 10, writableByteChannel);
+ fail();
+ } catch (NonReadableChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_TargetNonWritable()
+ throws Exception {
+ try {
+ readWriteFileChannel.transferTo(0, 0, readOnlyFileChannel);
+ fail("should throw NonWritableChannelException.");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+
+ // first throws NonWritableChannelException even position out of file
+ // size.
+ try {
+ readWriteFileChannel.transferTo(10, 10, readOnlyFileChannel);
+ fail("should throw NonWritableChannelException.");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+
+ // regression test for Harmony-941
+ // first throws NonWritableChannelException even arguments are illegal.
+ try {
+ readWriteFileChannel.transferTo(-1, 10, readOnlyFileChannel);
+ fail("should throw NonWritableChannelException.");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+
+ try {
+ readWriteFileChannel.transferTo(0, -1, readOnlyFileChannel);
+ fail("should throw NonWritableChannelException.");
+ } catch (NonWritableChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_PositionBeyondSize()
+ throws Exception {
+ // init data to file.
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ final int WRITEONLYFILECHANNELPOSITION = 2;
+ writeOnlyFileChannel.position(WRITEONLYFILECHANNELPOSITION);
+
+ final int POSITION = CONTENT_AS_BYTES_LENGTH * 2;
+ final int LENGTH = 5;
+ long result = readOnlyFileChannel.transferTo(POSITION, LENGTH,
+ writeOnlyFileChannel);
+ assertEquals(0, result);
+ assertEquals(0, readOnlyFileChannel.position());
+ assertEquals(WRITEONLYFILECHANNELPOSITION, writeOnlyFileChannel
+ .position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_FileChannel()
+ throws Exception {
+ // init data to file.
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ final int READONLYFILECHANNELPOSITION = 2;
+ final int WRITEONLYFILECHANNELPOSITION = 4;
+ readOnlyFileChannel.position(READONLYFILECHANNELPOSITION);
+ writeOnlyFileChannel.position(WRITEONLYFILECHANNELPOSITION);
+
+ final int POSITION = 3;
+ final int LENGTH = 5;
+ long result = readOnlyFileChannel.transferTo(POSITION, LENGTH,
+ writeOnlyFileChannel);
+ assertEquals(LENGTH, result);
+ assertEquals(READONLYFILECHANNELPOSITION, readOnlyFileChannel
+ .position());
+ assertEquals(WRITEONLYFILECHANNELPOSITION + LENGTH,
+ writeOnlyFileChannel.position());
+ writeOnlyFileChannel.close();
+
+ final int EXPECTED_LENGTH = WRITEONLYFILECHANNELPOSITION + LENGTH;
+ fis = new FileInputStream(fileOfWriteOnlyFileChannel);
+ byte[] resultContent = new byte[EXPECTED_LENGTH];
+ fis.read(resultContent);
+
+ byte[] expectedContent = new byte[EXPECTED_LENGTH];
+ System.arraycopy(CONTENT_AS_BYTES, 0, expectedContent, 0,
+ WRITEONLYFILECHANNELPOSITION);
+ System.arraycopy(CONTENT_AS_BYTES, POSITION, expectedContent,
+ WRITEONLYFILECHANNELPOSITION, LENGTH);
+ assertTrue(Arrays.equals(expectedContent, resultContent));
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_SocketChannel()
+ throws Exception {
+ // inits data into file.
+ writeDataToFile(fileOfReadOnlyFileChannel);
+
+ // connects two socketChannels.
+ socketChannelReceiver = SocketChannel.open();
+ socketChannelReceiver.socket().bind(
+ new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ serverSocketChannel = ServerSocketChannel.open();
+ serverSocketChannel.socket().bind(
+ new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ socketChannelReceiver.socket().setSoTimeout(TIME_OUT);
+ socketChannelReceiver.connect(serverSocketChannel.socket()
+ .getLocalSocketAddress());
+ serverSocketChannel.socket().setSoTimeout(TIME_OUT);
+ socketChannelSender = serverSocketChannel.accept();
+ socketChannelSender.socket().setSoTimeout(TIME_OUT);
+
+ // position here should have no effect on transferTo since it uses
+ // offset from file_begin
+ final int POSITION = 10;
+ readOnlyFileChannel.position(POSITION);
+
+ // transfers data from file to socketChannelSender.
+ final int OFFSET = 2;
+ long result = readOnlyFileChannel.transferTo(OFFSET,
+ CONTENT_AS_BYTES_LENGTH * 2, socketChannelSender);
+ final int LENGTH = CONTENT_AS_BYTES_LENGTH - OFFSET;
+ assertEquals(LENGTH, result);
+ assertEquals(POSITION, readOnlyFileChannel.position());
+ readOnlyFileChannel.close();
+ socketChannelSender.close();
+
+ // gets contents from socketChannelReceiver.
+ ByteBuffer readBuffer = ByteBuffer.allocate(LENGTH + 1);
+ int totalRead = 0;
+ int countRead = 0;
+ long beginTime = System.currentTimeMillis();
+ while ((countRead = socketChannelReceiver.read(readBuffer)) != -1) {
+ totalRead += countRead;
+ // TIMEOUT
+ if (System.currentTimeMillis() - beginTime > TIME_OUT) {
+ break;
+ }
+ }
+ assertEquals(LENGTH, totalRead);
+
+ // compares contents.
+ readBuffer.flip();
+ for (int i = OFFSET; i < CONTENT_AS_BYTES_LENGTH; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_DatagramChannel()
+ throws Exception {
+ // inits data to file.
+ writeDataToFile(fileOfReadOnlyFileChannel);
+
+ // connects two datagramChannel
+ datagramChannelReceiver = DatagramChannel.open();
+ datagramChannelReceiver.socket().bind(
+ new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ datagramChannelSender = DatagramChannel.open();
+ datagramChannelSender.socket().bind(
+ new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ datagramChannelSender.socket().setSoTimeout(TIME_OUT);
+ datagramChannelSender.connect(datagramChannelReceiver.socket()
+ .getLocalSocketAddress());
+ datagramChannelReceiver.socket().setSoTimeout(TIME_OUT);
+ datagramChannelReceiver.connect(datagramChannelSender.socket()
+ .getLocalSocketAddress());
+
+ // transfers data from fileChannel to datagramChannelSender
+ long result = readOnlyFileChannel.transferTo(0,
+ CONTENT_AS_BYTES_LENGTH, datagramChannelSender);
+ assertEquals(CONTENT_AS_BYTES_LENGTH, result);
+ assertEquals(0, readOnlyFileChannel.position());
+ readOnlyFileChannel.close();
+ datagramChannelSender.close();
+
+ // gets contents from datagramChannelReceiver
+ ByteBuffer readBuffer = ByteBuffer.allocate(CONTENT_AS_BYTES_LENGTH);
+ long beginTime = System.currentTimeMillis();
+ int totalRead = 0;
+ while (totalRead < CONTENT_AS_BYTES_LENGTH) {
+ totalRead += datagramChannelReceiver.read(readBuffer);
+ if (System.currentTimeMillis() - beginTime > TIME_OUT) {
+ break;
+ }
+ }
+ assertEquals(CONTENT_AS_BYTES_LENGTH, totalRead);
+
+ // compares contents.
+ readBuffer.flip();
+ for (int i = 0; i < CONTENT_AS_BYTES_LENGTH; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#transferTo(long,long,WritableByteChannel)
+ */
+ public void test_transferToJJLWritableByteChannel_Pipe() throws Exception {
+ // inits data in file.
+ writeDataToFile(fileOfReadOnlyFileChannel);
+
+ // inits pipe.
+ pipe = Pipe.open();
+
+ // transfers data from fileChannel to pipe.
+ final int OFFSET = 2;
+ final int LENGTH = 4;
+ long result = readOnlyFileChannel.transferTo(OFFSET, LENGTH, pipe
+ .sink());
+ assertEquals(LENGTH, result);
+ assertEquals(0, readOnlyFileChannel.position());
+ readOnlyFileChannel.close();
+
+ // gets content from pipe.
+ ByteBuffer readBuffer = ByteBuffer.allocate(LENGTH);
+ result = pipe.source().read(readBuffer);
+ assertEquals(LENGTH, result);
+
+ // compares content.
+ readBuffer.flip();
+ for (int i = OFFSET; i < OFFSET + LENGTH; i++) {
+ assertEquals(CONTENT_AS_BYTES[i], readBuffer.get());
+ }
+ }
+
+ /**
+ * Regression test for Harmony-3324
+ * Make sure we could delete the file after we called transferTo() method.
+ */
+ public void test_transferTo_couldDelete() throws Exception {
+ // init data in files
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ // call transferTo() method
+ readOnlyFileChannel.transferTo(0 , 2, writeOnlyFileChannel);
+
+ // delete both files
+ readOnlyFileChannel.close();
+ writeOnlyFileChannel.close();
+ boolean rDel = fileOfReadOnlyFileChannel.delete();
+ boolean wDel = fileOfWriteOnlyFileChannel.delete();
+
+ // make sure both files were deleted
+ assertTrue("File " + readOnlyFileChannel + " exists", rDel);
+ assertTrue("File " + writeOnlyFileChannel + " exists", wDel);
+ }
+
+ /**
+ * Regression test for Harmony-3324
+ * Make sure we could delete the file after we called transferFrom() method.
+ */
+ public void test_transferFrom_couldDelete() throws Exception {
+ // init data in files
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ // call transferTo() method
+ writeOnlyFileChannel.transferFrom(readOnlyFileChannel, 0 , 2);
+
+ // delete both files
+ readOnlyFileChannel.close();
+ writeOnlyFileChannel.close();
+ boolean rDel = fileOfReadOnlyFileChannel.delete();
+ boolean wDel = fileOfWriteOnlyFileChannel.delete();
+
+ // make sure both files were deleted
+ assertTrue("File " + readOnlyFileChannel + " exists", rDel);
+ assertTrue("File " + writeOnlyFileChannel + " exists", wDel);
+ }
+
+ private class MockFileChannel extends FileChannel {
+
+ private boolean isLockCalled = false;
+
+ private boolean isTryLockCalled = false;
+
+ private boolean isReadCalled = false;
+
+ private boolean isWriteCalled = false;
+
+ public void force(boolean arg0) throws IOException {
+ // do nothing
+ }
+
+ public FileLock lock(long position, long size, boolean shared)
+ throws IOException {
+ // verify that calling lock() leads to the method
+ // lock(0, Long.MAX_VALUE, false).
+ if (0 == position && Long.MAX_VALUE == size && false == shared) {
+ isLockCalled = true;
+ }
+ return null;
+ }
+
+ public MappedByteBuffer map(MapMode arg0, long arg1, long arg2)
+ throws IOException {
+ return null;
+ }
+
+ public long position() throws IOException {
+ return 0;
+ }
+
+ public FileChannel position(long arg0) throws IOException {
+ return null;
+ }
+
+ public int read(ByteBuffer arg0) throws IOException {
+ return 0;
+ }
+
+ public int read(ByteBuffer arg0, long arg1) throws IOException {
+ return 0;
+ }
+
+ public long read(ByteBuffer[] srcs, int offset, int length)
+ throws IOException {
+ // verify that calling read(ByteBuffer[] srcs) leads to the method
+ // read(srcs, 0, srcs.length)
+ if (0 == offset && length == srcs.length) {
+ isReadCalled = true;
+ }
+ return 0;
+ }
+
+ public long size() throws IOException {
+ return 0;
+ }
+
+ public long transferFrom(ReadableByteChannel arg0, long arg1, long arg2)
+ throws IOException {
+ return 0;
+ }
+
+ public long transferTo(long arg0, long arg1, WritableByteChannel arg2)
+ throws IOException {
+ return 0;
+ }
+
+ public FileChannel truncate(long arg0) throws IOException {
+ return null;
+ }
+
+ public FileLock tryLock(long position, long size, boolean shared)
+ throws IOException {
+ // verify that calling tryLock() leads to the method
+ // tryLock(0, Long.MAX_VALUE, false).
+ if (0 == position && Long.MAX_VALUE == size && false == shared) {
+ isTryLockCalled = true;
+ }
+ return null;
+ }
+
+ public int write(ByteBuffer arg0) throws IOException {
+ return 0;
+ }
+
+ public int write(ByteBuffer arg0, long arg1) throws IOException {
+ return 0;
+ }
+
+ public long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException {
+ // verify that calling write(ByteBuffer[] srcs) leads to the method
+ // write(srcs, 0, srcs.length)
+ if(0 == offset && length == srcs.length){
+ isWriteCalled = true;
+ }
+ return 0;
+ }
+
+ protected void implCloseChannel() throws IOException {
+
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockInterruptionExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockInterruptionExceptionTest.java
new file mode 100644
index 0000000..08a7421
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockInterruptionExceptionTest.java
@@ -0,0 +1,55 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.FileLockInterruptionException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for FileLockInterruptionException
+ */
+public class FileLockInterruptionExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.FileLockInterruptionException#FileLockInterruptionException()}
+ */
+ public void test_Constructor() {
+ FileLockInterruptionException e = new FileLockInterruptionException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new FileLockInterruptionException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new FileLockInterruptionException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockTest.java
new file mode 100644
index 0000000..7e3b671
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockTest.java
@@ -0,0 +1,199 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests class FileLock.
+ */
+public class FileLockTest extends TestCase {
+
+ private FileChannel readWriteChannel;
+
+ private MockFileLock mockLock;
+
+ class MockFileLock extends FileLock {
+
+ boolean isValid = true;
+
+ protected MockFileLock(FileChannel channel, long position, long size,
+ boolean shared) {
+ super(channel, position, size, shared);
+ }
+
+ public boolean isValid() {
+ return isValid;
+ }
+
+ public void release() throws IOException {
+ isValid = false;
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ File tempFile = File.createTempFile("testing", "tmp");
+ tempFile.deleteOnExit();
+ RandomAccessFile randomAccessFile = new RandomAccessFile(tempFile, "rw");
+ readWriteChannel = randomAccessFile.getChannel();
+ mockLock = new MockFileLock(readWriteChannel, 10, 100, false);
+ }
+
+ protected void tearDown() throws IOException {
+ if (readWriteChannel != null) {
+ readWriteChannel.close();
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileLock#FileLock(FileChannel, long, long,
+ * boolean)
+ */
+ public void test_Constructor_Ljava_nio_channels_FileChannelJJZ() {
+ FileLock fileLock1 = new MockFileLock(null, 0, 0, false);
+ assertNull(fileLock1.channel());
+
+ try {
+ new MockFileLock(readWriteChannel, -1, 0, false);
+ fail("should throw IllegalArgumentException.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ new MockFileLock(readWriteChannel, 0, -1, false);
+ fail("should throw IllegalArgumentException.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ // Harmony-682 regression test
+ try {
+ new MockFileLock(readWriteChannel, Long.MAX_VALUE, 1, false);
+ fail("should throw IllegalArgumentException.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.FileLock#channel()
+ */
+ public void test_channel() {
+ assertSame(readWriteChannel, mockLock.channel());
+ FileLock lock = new MockFileLock(null, 0, 10, true);
+ assertNull(lock.channel());
+ }
+
+ /**
+ * @tests java.nio.channels.FileLock#position()
+ */
+ public void test_position() {
+ FileLock fileLock1 = new MockFileLock(readWriteChannel, 20, 100, true);
+ assertEquals(20, fileLock1.position());
+
+ final long position = ((long) Integer.MAX_VALUE + 1);
+ FileLock fileLock2 = new MockFileLock(readWriteChannel, position, 100,
+ true);
+ assertEquals(position, fileLock2.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileLock#size()
+ */
+ public void test_size() {
+ FileLock fileLock1 = new MockFileLock(readWriteChannel, 20, 100, true);
+ assertEquals(100, fileLock1.size());
+
+ final long position = 0x0FFFFFFFFFFFFFFFL;
+ final long size = ((long) Integer.MAX_VALUE + 1);
+ FileLock fileLock2 = new MockFileLock(readWriteChannel, position, size,
+ true);
+ assertEquals(size, fileLock2.size());
+ }
+
+ /**
+ * @tests java.nio.channels.FileLock#isShared()
+ */
+ public void test_isShared() {
+ assertFalse(mockLock.isShared());
+ FileLock lock = new MockFileLock(null, 0, 10, true);
+ assertTrue(lock.isShared());
+ }
+
+ /**
+ * @tests java.nio.channels.FileLock#overlaps(long, long)
+ */
+ public void test_overlaps_JJ() {
+ assertTrue(mockLock.overlaps(0, 11));
+ assertFalse(mockLock.overlaps(0, 10));
+ assertTrue(mockLock.overlaps(100, 110));
+ assertTrue(mockLock.overlaps(99, 110));
+ assertFalse(mockLock.overlaps(-1, 10));
+ //Harmony-671 regression test
+ assertTrue(mockLock.overlaps(1, 120));
+ assertTrue(mockLock.overlaps(20, 50));
+ }
+
+ /**
+ * @tests java.nio.channels.FileLock#isValid()
+ */
+ public void test_isValid() throws IOException {
+ FileLock fileLock = readWriteChannel.lock();
+ assertTrue(fileLock.isValid());
+ fileLock.release();
+ assertFalse(fileLock.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.FileLock#release()
+ */
+ public void test_release() throws Exception {
+ File file = File.createTempFile("test", "tmp");
+ file.deleteOnExit();
+ FileOutputStream fout = new FileOutputStream(file);
+ FileChannel fileChannel = fout.getChannel();
+ FileLock fileLock = fileChannel.lock();
+ fileChannel.close();
+ try {
+ fileLock.release();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ // release after release
+ fout = new FileOutputStream(file);
+ fileChannel = fout.getChannel();
+ fileLock = fileChannel.lock();
+ fileLock.release();
+ fileChannel.close();
+ try {
+ fileLock.release();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ //expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java
new file mode 100644
index 0000000..3384ee5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java
@@ -0,0 +1,55 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.IllegalBlockingModeException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for IllegalBlockingModeException
+ */
+public class IllegalBlockingModeExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.IllegalBlockingModeException#IllegalBlockingModeException()}
+ */
+ public void test_Constructor() {
+ IllegalBlockingModeException e = new IllegalBlockingModeException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new IllegalBlockingModeException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest
+ .verifyGolden(this, new IllegalBlockingModeException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/IllegalSelectorExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/IllegalSelectorExceptionTest.java
new file mode 100644
index 0000000..dabb95f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/IllegalSelectorExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.IllegalSelectorException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for IllegalSelectorException
+ */
+public class IllegalSelectorExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.IllegalSelectorException#IllegalSelectorException()}
+ */
+ public void test_Constructor() {
+ IllegalSelectorException e = new IllegalSelectorException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new IllegalSelectorException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new IllegalSelectorException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MapModeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MapModeTest.java
new file mode 100644
index 0000000..13fe11b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MapModeTest.java
@@ -0,0 +1,52 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.FileChannel;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for FileChannel.MapMode
+ */
+public class MapModeTest extends TestCase {
+
+ /**
+ * java.nio.channels.FileChannel.MapMode#PRIVATE,READONLY,READWRITE
+ */
+ public void test_PRIVATE_READONLY_READWRITE() {
+ assertNotNull(FileChannel.MapMode.PRIVATE);
+ assertNotNull(FileChannel.MapMode.READ_ONLY);
+ assertNotNull(FileChannel.MapMode.READ_WRITE);
+
+ assertFalse(FileChannel.MapMode.PRIVATE
+ .equals(FileChannel.MapMode.READ_ONLY));
+ assertFalse(FileChannel.MapMode.PRIVATE
+ .equals(FileChannel.MapMode.READ_WRITE));
+ assertFalse(FileChannel.MapMode.READ_ONLY
+ .equals(FileChannel.MapMode.READ_WRITE));
+ }
+
+ /**
+ * java.nio.channels.FileChannel.MapMode#toString()
+ */
+ public void test_toString() {
+ assertNotNull(FileChannel.MapMode.PRIVATE.toString());
+ assertNotNull(FileChannel.MapMode.READ_ONLY.toString());
+ assertNotNull(FileChannel.MapMode.READ_WRITE.toString());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockDatagramChannel.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockDatagramChannel.java
new file mode 100644
index 0000000..41388ec
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockDatagramChannel.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+class MockDatagramChannel extends DatagramChannel {
+
+ public MockDatagramChannel(SelectorProvider arg0) {
+ super(arg0);
+ }
+
+ @Override
+ public DatagramSocket socket() {
+ return null;
+ }
+
+ @Override
+ public boolean isConnected() {
+ return false;
+ }
+
+ @Override
+ public DatagramChannel connect(SocketAddress arg0) throws IOException {
+ return null;
+ }
+
+ @Override
+ public DatagramChannel disconnect() throws IOException {
+ return null;
+ }
+
+ @Override
+ public SocketAddress receive(ByteBuffer arg0) throws IOException {
+ return null;
+ }
+
+ @Override
+ public int send(ByteBuffer arg0, SocketAddress arg1) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public int read(ByteBuffer arg0) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public long read(ByteBuffer[] arg0, int arg1, int arg2) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public int write(ByteBuffer arg0) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public long write(ByteBuffer[] arg0, int arg1, int arg2) throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected void implCloseSelectableChannel() throws IOException {
+ // empty
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean arg0) throws IOException {
+ // empty
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockServerSocketChannel.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockServerSocketChannel.java
new file mode 100644
index 0000000..783d2ce
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockServerSocketChannel.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+class MockServerSocketChannel extends ServerSocketChannel {
+
+ protected MockServerSocketChannel(SelectorProvider arg0) {
+ super(arg0);
+ }
+
+ @Override
+ public ServerSocket socket() {
+ return null;
+ }
+
+ @Override
+ public SocketChannel accept() throws IOException {
+ return null;
+ }
+
+ @Override
+ protected void implCloseSelectableChannel() throws IOException {
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean arg0) throws IOException {
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockSocketChannel.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockSocketChannel.java
new file mode 100644
index 0000000..47dad9d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/MockSocketChannel.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+class MockSocketChannel extends SocketChannel {
+
+ protected MockSocketChannel(SelectorProvider arg0) {
+ super(arg0);
+ }
+
+ @Override
+ public Socket socket() {
+ return null;
+ }
+
+ @Override
+ public boolean isConnected() {
+ return false;
+ }
+
+ @Override
+ public boolean isConnectionPending() {
+ return false;
+ }
+
+ @Override
+ public boolean connect(SocketAddress arg0) throws IOException {
+ return false;
+ }
+
+ @Override
+ public boolean finishConnect() throws IOException {
+ return false;
+ }
+
+ @Override
+ public int read(ByteBuffer arg0) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public long read(ByteBuffer[] arg0, int arg1, int arg2) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public int write(ByteBuffer arg0) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public long write(ByteBuffer[] arg0, int arg1, int arg2) throws IOException {
+ return 0;
+ }
+
+ @Override
+ protected void implCloseSelectableChannel() throws IOException {
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean arg0) throws IOException {
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NoConnectionPendingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NoConnectionPendingExceptionTest.java
new file mode 100644
index 0000000..7a99a77
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NoConnectionPendingExceptionTest.java
@@ -0,0 +1,55 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.NoConnectionPendingException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for NoConnectionPendingException
+ */
+public class NoConnectionPendingExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NoConnectionPendingException#NoConnectionPendingException()}
+ */
+ public void test_Constructor() {
+ NoConnectionPendingException e = new NoConnectionPendingException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new NoConnectionPendingException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest
+ .verifyGolden(this, new NoConnectionPendingException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NonReadableChannelExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NonReadableChannelExceptionTest.java
new file mode 100644
index 0000000..0f59d92
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NonReadableChannelExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.NonReadableChannelException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for NonReadableChannelException
+ */
+public class NonReadableChannelExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NonReadableChannelException#NonReadableChannelException()}
+ */
+ public void test_Constructor() {
+ NonReadableChannelException e = new NonReadableChannelException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new NonReadableChannelException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new NonReadableChannelException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NonWritableChannelExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NonWritableChannelExceptionTest.java
new file mode 100644
index 0000000..ffafb38
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NonWritableChannelExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.NonWritableChannelException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for NonWritableChannelException
+ */
+public class NonWritableChannelExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NonWritableChannelException#NonWritableChannelException()}
+ */
+ public void test_Constructor() {
+ NonWritableChannelException e = new NonWritableChannelException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new NonWritableChannelException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new NonWritableChannelException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NotYetBoundExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NotYetBoundExceptionTest.java
new file mode 100644
index 0000000..eef3185
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NotYetBoundExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.NotYetBoundException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for NotYetBoundException
+ */
+public class NotYetBoundExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NotYetBoundException#NotYetBoundException()}
+ */
+ public void test_Constructor() {
+ NotYetBoundException e = new NotYetBoundException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new NotYetBoundException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new NotYetBoundException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NotYetConnectedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NotYetConnectedExceptionTest.java
new file mode 100644
index 0000000..00284bd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/NotYetConnectedExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.NotYetConnectedException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for NotYetConnectedException
+ */
+public class NotYetConnectedExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NotYetConnectedException#NotYetConnectedException()}
+ */
+ public void test_Constructor() {
+ NotYetConnectedException e = new NotYetConnectedException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new NotYetConnectedException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new NotYetConnectedException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/OverlappingFileLockExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/OverlappingFileLockExceptionTest.java
new file mode 100644
index 0000000..fd11abf
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/OverlappingFileLockExceptionTest.java
@@ -0,0 +1,55 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.OverlappingFileLockException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for OverlappingFileLockException
+ */
+public class OverlappingFileLockExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.OverlappingFileLockException#OverlappingFileLockException()}
+ */
+ public void test_Constructor() {
+ OverlappingFileLockException e = new OverlappingFileLockException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new OverlappingFileLockException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest
+ .verifyGolden(this, new OverlappingFileLockException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/PipeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/PipeTest.java
new file mode 100644
index 0000000..e1de1f5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/PipeTest.java
@@ -0,0 +1,59 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.net.NetPermission;
+import java.nio.channels.Pipe;
+import java.nio.channels.Pipe.SinkChannel;
+import java.nio.channels.Pipe.SourceChannel;
+import java.security.Permission;
+
+import junit.framework.TestCase;
+
+/*
+ * Tests for Pipe and its default implementation
+ */
+public class PipeTest extends TestCase {
+
+ /**
+ * @tests java.nio.channels.Pipe#open()
+ */
+ public void test_open() throws IOException{
+ Pipe pipe = Pipe.open();
+ assertNotNull(pipe);
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe#sink()
+ */
+ public void test_sink() throws IOException {
+ Pipe pipe = Pipe.open();
+ SinkChannel sink = pipe.sink();
+ assertTrue(sink.isBlocking());
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe#source()
+ */
+ public void test_source() throws IOException {
+ Pipe pipe = Pipe.open();
+ SourceChannel source = pipe.source();
+ assertTrue(source.isBlocking());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectableChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectableChannelTest.java
new file mode 100644
index 0000000..a4698bd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectableChannelTest.java
@@ -0,0 +1,89 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.SelectorProvider;
+import junit.framework.TestCase;
+
+/*
+ * Tests for SelectableChannel
+ */
+public class SelectableChannelTest extends TestCase {
+
+ /**
+ * @tests SelectableChannel#register(Selector, int)
+ */
+ public void test_register_LSelectorI() throws IOException {
+ MockSelectableChannel msc = new MockSelectableChannel();
+ // Verify that calling register(Selector, int) leads to the method
+ // register(Selector, int, Object) being called with a null value
+ // for the third argument.
+ msc.register(Selector.open(), SelectionKey.OP_ACCEPT);
+ assertTrue(msc.isCalled);
+ }
+
+ private class MockSelectableChannel extends SelectableChannel {
+
+ private boolean isCalled = false;
+
+ public Object blockingLock() {
+ return null;
+ }
+
+ public SelectableChannel configureBlocking(boolean block)
+ throws IOException {
+ return null;
+ }
+
+ public boolean isBlocking() {
+ return false;
+ }
+
+ public boolean isRegistered() {
+ return false;
+ }
+
+ public SelectionKey keyFor(Selector sel) {
+ return null;
+ }
+
+ public SelectorProvider provider() {
+ return null;
+ }
+
+ public SelectionKey register(Selector sel, int ops, Object att)
+ throws ClosedChannelException {
+ if (null == att) {
+ isCalled = true;
+ }
+ return null;
+ }
+
+ public int validOps() {
+ return 0;
+ }
+
+ protected void implCloseChannel() throws IOException {
+ // empty
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectionKeyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectionKeyTest.java
new file mode 100644
index 0000000..150d11c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectionKeyTest.java
@@ -0,0 +1,318 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.nio.channels.CancelledKeyException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import junit.framework.TestCase;
+
+/*
+ * Tests for SelectionKey and its default implementation
+ */
+public class SelectionKeyTest extends TestCase {
+
+ Selector selector;
+
+ SocketChannel sc;
+
+ SelectionKey selectionKey;
+
+ private static String LOCAL_ADDR = "127.0.0.1";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ selector = Selector.open();
+ sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ selectionKey = sc.register(selector, SelectionKey.OP_CONNECT);
+ }
+
+ protected void tearDown() throws Exception {
+ selectionKey.cancel();
+ selectionKey = null;
+ selector.close();
+ selector = null;
+ super.tearDown();
+ }
+
+ static class MockSelectionKey extends SelectionKey {
+ private int interestOps;
+
+ MockSelectionKey(int ops) {
+ interestOps = ops;
+ }
+
+ public void cancel() {
+ // do nothing
+ }
+
+ public SelectableChannel channel() {
+ return null;
+ }
+
+ public int interestOps() {
+ return 0;
+ }
+
+ public SelectionKey interestOps(int operations) {
+ return null;
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+
+ public int readyOps() {
+ return interestOps;
+ }
+
+ public Selector selector() {
+ return null;
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#attach(Object)
+ */
+ public void test_attach() {
+ MockSelectionKey mockSelectionKey = new MockSelectionKey(SelectionKey.OP_ACCEPT);
+ // no previous, return null
+ Object o = new Object();
+ Object check = mockSelectionKey.attach(o);
+ assertNull(check);
+
+ // null parameter is ok
+ check = mockSelectionKey.attach(null);
+ assertSame(o, check);
+
+ check = mockSelectionKey.attach(o);
+ assertNull(check);
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#attachment()
+ */
+ public void test_attachment() {
+ MockSelectionKey mockSelectionKey = new MockSelectionKey(SelectionKey.OP_ACCEPT);
+ assertNull(mockSelectionKey.attachment());
+ Object o = new Object();
+ mockSelectionKey.attach(o);
+ assertSame(o, mockSelectionKey.attachment());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#channel()
+ */
+ public void test_channel() {
+ assertSame(sc, selectionKey.channel());
+ // can be invoked even canceled
+ selectionKey.cancel();
+ assertSame(sc, selectionKey.channel());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#interestOps()
+ */
+ public void test_interestOps() {
+ assertEquals(SelectionKey.OP_CONNECT, selectionKey.interestOps());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#interestOps(int)
+ */
+ public void test_interestOpsI() {
+ selectionKey.interestOps(SelectionKey.OP_WRITE);
+ assertEquals(SelectionKey.OP_WRITE, selectionKey.interestOps());
+
+ try {
+ selectionKey.interestOps(SelectionKey.OP_ACCEPT);
+ fail("should throw IAE.");
+ } catch (IllegalArgumentException ex) {
+ // expected;
+ }
+
+ try {
+ selectionKey.interestOps(~sc.validOps());
+ fail("should throw IAE.");
+ } catch (IllegalArgumentException ex) {
+ // expected;
+ }
+ try {
+ selectionKey.interestOps(-1);
+ fail("should throw IAE.");
+ } catch (IllegalArgumentException ex) {
+ // expected;
+ }
+
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#isValid()
+ */
+ public void test_isValid() {
+ assertTrue(selectionKey.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#isValid()
+ */
+ public void test_isValid_KeyCancelled() {
+ selectionKey.cancel();
+ assertFalse(selectionKey.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#isValid()
+ */
+ public void test_isValid_ChannelColsed() throws IOException {
+ sc.close();
+ assertFalse(selectionKey.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#isValid()
+ */
+ public void test_isValid_SelectorClosed() throws IOException {
+ selector.close();
+ assertFalse(selectionKey.isValid());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#isAcceptable()
+ */
+ public void test_isAcceptable() throws IOException {
+ MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
+ assertTrue(mockSelectionKey1.isAcceptable());
+ MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_CONNECT);
+ assertFalse(mockSelectionKey2.isAcceptable());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#isConnectable()
+ */
+ public void test_isConnectable() {
+ MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_CONNECT);
+ assertTrue(mockSelectionKey1.isConnectable());
+ MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
+ assertFalse(mockSelectionKey2.isConnectable());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#isReadable()
+ */
+ public void test_isReadable() {
+ MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_READ);
+ assertTrue(mockSelectionKey1.isReadable());
+ MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
+ assertFalse(mockSelectionKey2.isReadable());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#isWritable()
+ */
+ public void test_isWritable() {
+ MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_WRITE);
+ assertTrue(mockSelectionKey1.isWritable());
+ MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
+ assertFalse(mockSelectionKey2.isWritable());
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#cancel()
+ */
+ public void test_cancel() {
+ selectionKey.cancel();
+ try {
+ selectionKey.isAcceptable();
+ fail("should throw CancelledKeyException.");
+ } catch (CancelledKeyException ex) {
+ // expected
+ }
+ try {
+ selectionKey.isConnectable();
+ fail("should throw CancelledKeyException.");
+ } catch (CancelledKeyException ex) {
+ // expected
+ }
+ try {
+ selectionKey.isReadable();
+ fail("should throw CancelledKeyException.");
+ } catch (CancelledKeyException ex) {
+ // expected
+ }
+ try {
+ selectionKey.isWritable();
+ fail("should throw CancelledKeyException.");
+ } catch (CancelledKeyException ex) {
+ // expected
+ }
+
+ try {
+ selectionKey.readyOps();
+ fail("should throw CancelledKeyException.");
+ } catch (CancelledKeyException ex) {
+ // expected
+ }
+
+ try {
+ selectionKey.interestOps(SelectionKey.OP_CONNECT);
+ fail("should throw CancelledKeyException.");
+ } catch (CancelledKeyException ex) {
+ // expected
+ }
+
+ try {
+ selectionKey.interestOps();
+ fail("should throw CancelledKeyException.");
+ } catch (CancelledKeyException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#readyOps()
+ */
+ public void test_readyOps() throws IOException {
+ ServerSocket ss = new ServerSocket(0);
+ try {
+ sc.connect(new InetSocketAddress(LOCAL_ADDR, ss.getLocalPort()));
+ assertEquals(0, selectionKey.readyOps());
+ assertFalse(selectionKey.isConnectable());
+ selector.select();
+ assertEquals(SelectionKey.OP_CONNECT, selectionKey.readyOps());
+ } finally {
+ ss.close();
+ ss = null;
+ }
+
+ }
+
+ /**
+ * @tests java.nio.channels.SelectionKey#selector()
+ */
+ public void test_selector() {
+ assertSame(selector, selectionKey.selector());
+ selectionKey.cancel();
+ assertSame(selector, selectionKey.selector());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectorTest.java
new file mode 100644
index 0000000..0eb51b6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SelectorTest.java
@@ -0,0 +1,676 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.Pipe;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.Set;
+import junit.framework.TestCase;
+
+/*
+ * Tests for Selector and its default implementation
+ */
+public class SelectorTest extends TestCase {
+ private static final int WAIT_TIME = 100;
+
+ private SocketAddress localAddress;
+
+ private Selector selector;
+
+ private ServerSocketChannel ssc;
+
+ private enum SelectType {
+ NULL, TIMEOUT, NOW
+ };
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ ssc = ServerSocketChannel.open();
+ ssc.configureBlocking(false);
+ ServerSocket ss = ssc.socket();
+ ss.bind(null);
+ localAddress = ss.getLocalSocketAddress();
+ selector = Selector.open();
+ }
+
+ protected void tearDown() throws Exception {
+ try {
+ ssc.close();
+ } catch (Exception e) {
+ // do nothing
+ }
+ try {
+ selector.close();
+ } catch (Exception e) {
+ // do nothing
+ }
+ super.tearDown();
+ }
+
+ /**
+ * @tests java.nio.channels.Selector#open()
+ */
+ public void test_open() throws IOException {
+ assertNotNull(selector);
+ }
+
+ /**
+ * @tests Selector#isOpen()
+ */
+ public void test_isOpen() throws IOException {
+ assertTrue(selector.isOpen());
+ selector.close();
+ assertFalse(selector.isOpen());
+ }
+
+ /**
+ * @tests java.nio.channels.Selector#provider()
+ */
+ public void test_provider() throws IOException {
+ // should be system default provider
+ assertNotNull(selector.provider());
+ assertSame(SelectorProvider.provider(), selector.provider());
+ }
+
+ /**
+ * @tests java.nio.channels.Selector#keys()
+ */
+ public void test_keys() throws IOException {
+ SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT);
+
+ Set<SelectionKey> keySet = selector.keys();
+ Set<SelectionKey> keySet2 = selector.keys();
+
+ assertSame(keySet, keySet2);
+ assertEquals(1,keySet.size());
+ SelectionKey key2 = keySet.iterator().next();
+ assertEquals(key,key2);
+
+ // Any attempt to modify keys will cause UnsupportedOperationException
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ SelectionKey key3 = sc.register(selector, SelectionKey.OP_READ);
+ try {
+ keySet2.add(key3);
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ keySet2.remove(key3);
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ keySet2.clear();
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ selector.close();
+ try {
+ selector.keys();
+ fail("should throw ClosedSelectorException");
+ } catch (ClosedSelectorException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Selector#keys()
+ */
+ public void test_selectedKeys() throws IOException {
+ SocketChannel sc = SocketChannel.open();
+ ssc.register(selector, SelectionKey.OP_ACCEPT);
+ try {
+ int count = 0;
+ sc.connect(localAddress);
+ count = blockingSelect(SelectType.NULL, 0);
+ assertEquals(1, count);
+ Set<SelectionKey> selectedKeys = selector.selectedKeys();
+ Set<SelectionKey> selectedKeys2 = selector.selectedKeys();
+ assertSame(selectedKeys, selectedKeys2);
+
+ assertEquals(1, selectedKeys.size());
+ assertEquals(ssc.keyFor(selector), selectedKeys.iterator().next());
+ // add one key into selectedKeys
+ try {
+ selectedKeys.add(ssc.keyFor(selector));
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ // no exception should be thrown
+ selectedKeys.clear();
+
+ Set<SelectionKey> selectedKeys3 = selector.selectedKeys();
+ assertSame(selectedKeys, selectedKeys3);
+
+ ssc.keyFor(selector).cancel();
+ assertEquals(0, selectedKeys.size());
+ selector.close();
+ try {
+ selector.selectedKeys();
+ fail("should throw ClosedSelectorException");
+ } catch (ClosedSelectorException e) {
+ // expected
+ }
+ } finally {
+ sc.close();
+ }
+ }
+
+ /**
+ * @tests java.nio.channel.Selector#selectNow()
+ */
+ public void test_selectNow() throws IOException {
+ assert_select_OP_ACCEPT(SelectType.NOW, 0);
+ assert_select_OP_CONNECT(SelectType.NOW, 0);
+ assert_select_OP_READ(SelectType.NOW, 0);
+ assert_select_OP_WRITE(SelectType.NOW, 0);
+ }
+
+ /**
+ * @tests java.nio.channel.Selector#selectNow()
+ */
+ public void test_selectNow_SelectorClosed() throws IOException {
+ assert_select_SelectorClosed(SelectType.NOW, 0);
+ }
+
+ public void test_selectNow_Timeout() throws IOException {
+ // make sure selectNow doesn't block
+ selector.selectNow();
+ }
+
+ /**
+ * @tests java.nio.channel.Selector#select()
+ */
+ public void test_select() throws IOException {
+ assert_select_OP_ACCEPT(SelectType.NULL, 0);
+ assert_select_OP_CONNECT(SelectType.NULL, 0);
+ assert_select_OP_READ(SelectType.NULL, 0);
+ assert_select_OP_WRITE(SelectType.NULL, 0);
+ }
+
+ /**
+ * @tests java.nio.channel.Selector#select()
+ */
+ public void test_select_SelectorClosed() throws IOException {
+ assert_select_SelectorClosed(SelectType.NULL, 0);
+ }
+
+ /**
+ * @tests java.nio.channel.Selector#select(long)
+ */
+ public void test_selectJ() throws IOException {
+ assert_select_OP_ACCEPT(SelectType.TIMEOUT, 0);
+ assert_select_OP_CONNECT(SelectType.TIMEOUT, 0);
+ assert_select_OP_READ(SelectType.TIMEOUT, 0);
+ assert_select_OP_WRITE(SelectType.TIMEOUT, 0);
+
+ assert_select_OP_ACCEPT(SelectType.TIMEOUT, WAIT_TIME);
+ assert_select_OP_CONNECT(SelectType.TIMEOUT, WAIT_TIME);
+ assert_select_OP_READ(SelectType.TIMEOUT, WAIT_TIME);
+ assert_select_OP_WRITE(SelectType.TIMEOUT, WAIT_TIME);
+ }
+
+ /**
+ * @tests java.nio.channel.Selector#select(long)
+ */
+ public void test_selectJ_SelectorClosed() throws IOException {
+ assert_select_SelectorClosed(SelectType.TIMEOUT, 0);
+ selector = Selector.open();
+ assert_select_SelectorClosed(SelectType.TIMEOUT, WAIT_TIME);
+ }
+
+ /**
+ * @tests java.nio.channel.Selector#select(long)
+ */
+ public void test_selectJ_Exception() throws IOException {
+ try {
+ selector.select(-1);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void test_selectJ_Timeout() throws IOException {
+ // make sure select(timeout) doesn't block
+ selector.select(WAIT_TIME);
+ }
+
+ public void test_selectJ_Empty_Keys() throws IOException {
+ // regression test, see HARMONY-3888.
+ // make sure select(long) does wait for specified amount of
+ // time if keys.size() == 0 (initial state of selector).
+
+ final long SELECT_TIMEOUT_MS = 2000;
+
+ long t0 = System.nanoTime();
+ selector.select(SELECT_TIMEOUT_MS);
+ long t1 = System.nanoTime();
+
+ long waitMs = (t1 - t0) / 1000L / 1000L;
+ assertTrue(waitMs >= SELECT_TIMEOUT_MS);
+ assertTrue(waitMs < 5*SELECT_TIMEOUT_MS);
+ }
+
+ /**
+ * @tests java.nio.channels.Selector#wakeup()
+ */
+ public void test_wakeup() throws IOException {
+ /*
+ * make sure the test does not block on select
+ */
+ selector.wakeup();
+ selectOnce(SelectType.NULL, 0);
+ selector.wakeup();
+ selectOnce(SelectType.TIMEOUT, 0);
+
+ // try to wakeup select. The invocation sequence of wakeup and select
+ // doesn't affect test result.
+ new Thread() {
+ public void run() {
+
+ try {
+ Thread.sleep(WAIT_TIME);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ selector.wakeup();
+ }
+ }.start();
+ selectOnce(SelectType.NULL, 0);
+
+ // try to wakeup select. The invocation sequence of wakeup and select
+ // doesn't affect test result.
+ new Thread() {
+ public void run() {
+
+ try {
+ Thread.sleep(WAIT_TIME);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ selector.wakeup();
+ }
+ }.start();
+ selectOnce(SelectType.TIMEOUT, 0);
+ }
+
+ public void test_keySetViewsModifications() throws IOException {
+ Set<SelectionKey> keys = selector.keys();
+
+ SelectionKey key1 = ssc.register(selector, SelectionKey.OP_ACCEPT);
+
+ assertTrue(keys.contains(key1));
+
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ SelectionKey key2 = sc.register(selector, SelectionKey.OP_READ);
+
+ assertTrue(keys.contains(key1));
+ assertTrue(keys.contains(key2));
+
+ key1.cancel();
+ assertTrue(keys.contains(key1));
+
+ selector.selectNow();
+ assertFalse(keys.contains(key1));
+ assertTrue(keys.contains(key2));
+ }
+
+ /**
+ * This test cancels a key while selecting to verify that the cancelled
+ * key set is processed both before and after the call to the underlying
+ * operating system.
+ */
+ public void test_cancelledKeys() throws Exception {
+ final AtomicReference<Throwable> failure = new AtomicReference<Throwable>();
+ final AtomicBoolean complete = new AtomicBoolean();
+
+ final Pipe pipe = Pipe.open();
+ pipe.source().configureBlocking(false);
+ final SelectionKey key = pipe.source().register(selector, SelectionKey.OP_READ);
+
+ Thread thread = new Thread() {
+ public void run() {
+ try {
+ // make sure to call key.cancel() while the main thread is selecting
+ Thread.sleep(500);
+ key.cancel();
+ assertFalse(key.isValid());
+ pipe.sink().write(ByteBuffer.allocate(4)); // unblock select()
+ } catch (Throwable e) {
+ failure.set(e);
+ } finally {
+ complete.set(true);
+ }
+ }
+ };
+ assertTrue(key.isValid());
+
+ thread.start();
+ do {
+ assertEquals(0, selector.select(5000)); // blocks
+ assertEquals(0, selector.selectedKeys().size());
+ } while (!complete.get()); // avoid spurious interrupts
+ assertFalse(key.isValid());
+
+ thread.join();
+ assertNull(failure.get());
+ }
+
+ public void testOpChange() throws Exception {
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ sc.register(selector, SelectionKey.OP_CONNECT);
+ try {
+ sc.connect(localAddress);
+ int count = blockingSelect(SelectType.TIMEOUT, 100);
+ assertEquals(1, count);
+ Set<SelectionKey> selectedKeys = selector.selectedKeys();
+ assertEquals(1, selectedKeys.size());
+ SelectionKey key = selectedKeys.iterator().next();
+ assertEquals(sc.keyFor(selector), key);
+ assertEquals(SelectionKey.OP_CONNECT, key.readyOps());
+ // select again, it should return 0
+ count = selectOnce(SelectType.TIMEOUT, 100);
+ assertEquals(0, count);
+ // but selectedKeys remains the same as previous
+ assertSame(selectedKeys, selector.selectedKeys());
+ sc.finishConnect();
+
+ // same selector, but op is changed
+ SelectionKey key1 = sc.register(selector, SelectionKey.OP_WRITE);
+ assertEquals(key, key1);
+ count = blockingSelect(SelectType.TIMEOUT, 100);
+ assertEquals(1, count);
+ selectedKeys = selector.selectedKeys();
+ assertEquals(1, selectedKeys.size());
+ key = selectedKeys.iterator().next();
+ assertEquals(key, key1);
+ assertEquals(SelectionKey.OP_WRITE, key.readyOps());
+
+ selectedKeys.clear();
+ } finally {
+ try {
+ ssc.accept().close();
+ } catch (Exception e) {
+ // do nothing
+ }
+ try {
+ sc.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+
+ public void test_nonBlockingConnect() throws IOException {
+ SocketChannel channel = null;
+ try {
+ channel = SocketChannel.open();
+ channel.configureBlocking(false);
+ Selector selector = Selector.open();
+ channel.register(selector, SelectionKey.OP_CONNECT);
+ channel.connect(localAddress);
+ channel.finishConnect();
+ selector.select();
+ assertEquals(0, selector.selectedKeys().size());
+ } finally {
+ channel.close();
+ }
+ }
+
+ private void assert_select_SelectorClosed(SelectType type, int timeout)
+ throws IOException {
+ // selector is closed
+ selector.close();
+ try {
+ selectOnce(type, timeout);
+ fail("should throw ClosedSelectorException");
+ } catch (ClosedSelectorException e) {
+ // expected
+ }
+ }
+
+ private void assert_select_OP_ACCEPT(SelectType type, int timeout)
+ throws IOException, ClosedChannelException {
+ SocketChannel sc = SocketChannel.open();
+ SocketChannel client = null;
+ try {
+ ssc.register(selector, SelectionKey.OP_ACCEPT);
+ sc.connect(localAddress);
+ int count = blockingSelect(type, timeout);
+ assertEquals(1, count);
+ Set<SelectionKey> selectedKeys = selector.selectedKeys();
+ assertEquals(1, selectedKeys.size());
+ SelectionKey key = selectedKeys.iterator().next();
+ assertEquals(ssc.keyFor(selector), key);
+ assertEquals(SelectionKey.OP_ACCEPT, key.readyOps());
+ // select again, it should return 0
+ count = selectOnce(type, timeout);
+ assertEquals(0,count);
+ // but selectedKeys remains the same as previous
+ assertSame(selectedKeys, selector.selectedKeys());
+ client = ssc.accept();
+ selectedKeys.clear();
+ } finally {
+ try {
+ sc.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ if (null != client) {
+ client.close();
+ }
+ }
+ ssc.keyFor(selector).cancel();
+ }
+
+ private void assert_select_OP_CONNECT(SelectType type, int timeout)
+ throws IOException, ClosedChannelException {
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ sc.register(selector, SelectionKey.OP_CONNECT);
+ try {
+ sc.connect(localAddress);
+ int count = blockingSelect(type, timeout);
+ assertEquals(1, count);
+ Set<SelectionKey> selectedKeys = selector.selectedKeys();
+ assertEquals(1, selectedKeys.size());
+ SelectionKey key = selectedKeys.iterator().next();
+ assertEquals(sc.keyFor(selector), key);
+ assertEquals(SelectionKey.OP_CONNECT, key.readyOps());
+ // select again, it should return 0
+ count = selectOnce(type, timeout);
+ assertEquals(0, count);
+ // but selectedKeys remains the same as previous
+ assertSame(selectedKeys, selector.selectedKeys());
+ sc.finishConnect();
+ selectedKeys.clear();
+ } finally {
+ try {
+ ssc.accept().close();
+ } catch (Exception e) {
+ // do nothing
+ }
+
+ try {
+ sc.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+
+ private void assert_select_OP_READ(SelectType type, int timeout)
+ throws IOException {
+ SocketChannel sc = SocketChannel.open();
+ SocketChannel client = null;
+ SocketChannel sc2 = SocketChannel.open();
+ SocketChannel client2 = null;
+ try {
+ ssc.configureBlocking(true);
+ sc.connect(localAddress);
+ client = ssc.accept();
+ sc.configureBlocking(false);
+ sc.register(selector, SelectionKey.OP_READ);
+ client.configureBlocking(true);
+
+ sc2.connect(localAddress);
+ client2 = ssc.accept();
+ sc2.configureBlocking(false);
+ sc2.register(selector, SelectionKey.OP_READ);
+ client2.configureBlocking(true);
+
+ client.write(ByteBuffer.wrap("a".getBytes()));
+ int count = blockingSelect(type, timeout);
+ assertEquals(1, count);
+ Set<SelectionKey> selectedKeys = selector.selectedKeys();
+ assertEquals(1, selectedKeys.size());
+ SelectionKey key = selectedKeys.iterator().next();
+ assertEquals(sc.keyFor(selector), key);
+ assertEquals(SelectionKey.OP_READ, key.readyOps());
+ // select again, it should return 0
+ count = selectOnce(type, timeout);
+ assertEquals(0, count);
+ // but selectedKeys remains the same as previous
+ assertSame(selectedKeys, selector.selectedKeys());
+
+ sc.read(ByteBuffer.allocate(8));
+
+ // the second SocketChannel should be selected this time
+ client2.write(ByteBuffer.wrap("a".getBytes()));
+ count = blockingSelect(type, timeout);
+ assertEquals(1, count);
+ // selectedKeys still includes the key of sc, because the key of sc
+ // is not removed last time.
+ selectedKeys = selector.selectedKeys();
+ assertEquals(2, selectedKeys.size());
+ } finally {
+ if (null != client) {
+ try {
+ client.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ if (null != client2) {
+ try {
+ client2.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ try {
+ sc.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ try {
+ sc2.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ ssc.configureBlocking(false);
+ }
+ }
+
+ private void assert_select_OP_WRITE(SelectType type, int timeout)
+ throws IOException {
+ SocketChannel sc = SocketChannel.open();
+ SocketChannel client = null;
+ try {
+ sc.connect(localAddress);
+ ssc.configureBlocking(true);
+ client = ssc.accept();
+ sc.configureBlocking(false);
+ sc.register(selector, SelectionKey.OP_WRITE);
+ int count = blockingSelect(type, timeout);
+ assertEquals(1, count);
+ Set<SelectionKey> selectedKeys = selector.selectedKeys();
+ assertEquals(1, selectedKeys.size());
+ SelectionKey key = selectedKeys.iterator().next();
+ assertEquals(sc.keyFor(selector), key);
+ assertEquals(SelectionKey.OP_WRITE, key.readyOps());
+ // select again, it should return 0
+ count = selectOnce(type, timeout);
+ assertEquals(0, count);
+ // but selectedKeys remains the same as previous
+ assertSame(selectedKeys, selector.selectedKeys());
+ } finally {
+ if (null != client) {
+ client.close();
+ }
+ try {
+ sc.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ ssc.configureBlocking(false);
+ }
+ }
+
+ private int blockingSelect(SelectType type, int timeout) throws IOException {
+ int ret = 0;
+ do {
+ ret = selectOnce(type, timeout);
+ if (ret > 0) {
+ return ret;
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ } while (true);
+ }
+
+ private int selectOnce(SelectType type, int timeout) throws IOException {
+ int ret = 0;
+ switch (type) {
+ case NULL:
+ ret = selector.select();
+ break;
+ case TIMEOUT:
+ ret = selector.select(timeout);
+ break;
+ case NOW:
+ ret = selector.selectNow();
+ break;
+ }
+ return ret;
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java
new file mode 100644
index 0000000..be40d0b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java
@@ -0,0 +1,811 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousCloseException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.NotYetBoundException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.SelectorProvider;
+import junit.framework.TestCase;
+
+/*
+ * test for ServerSocketChannel
+ */
+public class ServerSocketChannelTest extends TestCase {
+
+ private static final int CAPACITY_NORMAL = 200;
+
+ private static final int CAPACITY_64KB = 65536;
+
+ private static final int TIME_UNIT = 200;
+
+ private ServerSocketChannel serverChannel;
+
+ private SocketChannel clientChannel;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.serverChannel = ServerSocketChannel.open();
+ this.clientChannel = SocketChannel.open();
+ }
+
+ protected void tearDown() throws Exception {
+ if (null != this.serverChannel) {
+ try {
+ this.serverChannel.close();
+ } catch (Exception e) {
+ //ignore
+ }
+
+ }
+ if (null != this.clientChannel) {
+ try {
+ this.clientChannel.close();
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+ super.tearDown();
+ }
+
+ // -------------------------------------------------------------------
+ // Test for methods in abstract class.
+ // -------------------------------------------------------------------
+
+ /*
+ * Test method for 'java.nio.channels.ServerSocketChannel.validOps()'
+ */
+ public void testValidOps() {
+ MockServerSocketChannel testMSChnlnull = new MockServerSocketChannel(
+ null);
+ MockServerSocketChannel testMSChnl = new MockServerSocketChannel(
+ SelectorProvider.provider());
+ assertEquals(SelectionKey.OP_ACCEPT, this.serverChannel.validOps());
+ assertEquals(SelectionKey.OP_ACCEPT, testMSChnl.validOps());
+ assertEquals(SelectionKey.OP_ACCEPT, testMSChnlnull.validOps());
+
+ }
+
+ /*
+ * Test method for 'java.nio.channels.ServerSocketChannel.open()'
+ */
+ public void testOpen() {
+ MockServerSocketChannel testMSChnl = new MockServerSocketChannel(null);
+ MockServerSocketChannel testMSChnlnotnull = new MockServerSocketChannel(
+ SelectorProvider.provider());
+ assertEquals(SelectionKey.OP_ACCEPT, testMSChnlnotnull.validOps());
+ assertNull(testMSChnl.provider());
+ assertNotNull(testMSChnlnotnull.provider());
+ assertNotNull(this.serverChannel.provider());
+ assertEquals(testMSChnlnotnull.provider(), this.serverChannel
+ .provider());
+ }
+
+ // -------------------------------------------------------------------
+ // Tests for bind()
+ // -------------------------------------------------------------------
+
+ public void test_bind_null() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ try {
+ assertNull(ssc.socket().getLocalSocketAddress());
+
+ ssc.socket().bind(null);
+
+ InetSocketAddress localAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
+ assertTrue(localAddress.getAddress().isAnyLocalAddress());
+ assertTrue(localAddress.getPort() > 0);
+ } finally {
+ ssc.close();
+ }
+ }
+
+ public void test_bind_failure() throws Exception {
+ ServerSocketChannel portHog = ServerSocketChannel.open();
+ portHog.socket().bind(null);
+
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ try {
+ // Bind to a local address that is in use
+ ssc.socket().bind(portHog.socket().getLocalSocketAddress());
+ fail();
+ } catch (IOException expected) {
+ } finally {
+ ssc.close();
+ portHog.close();
+ }
+ }
+
+ public void test_bind_closed() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.close();
+
+ try {
+ ssc.socket().bind(null);
+ fail();
+ } catch (IOException expected) {
+ } finally {
+ ssc.close();
+ }
+ }
+
+ public void test_bind_explicitPort() throws Exception {
+ ServerSocketChannel portPickingChannel = ServerSocketChannel.open();
+ // Have the OS find a free port.
+ portPickingChannel.socket().bind(null);
+
+ InetSocketAddress address = (InetSocketAddress) portPickingChannel.socket().getLocalSocketAddress();
+ assertTrue(address.getPort() > 0);
+ portPickingChannel.close();
+
+ // There is a risk of flakiness here if the port is allocated to something else between
+ // close() and bind().
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ InetSocketAddress bindAddress = new InetSocketAddress("localhost", address.getPort());
+ ssc.socket().bind(bindAddress);
+
+ InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
+ assertEquals(bindAddress.getHostName(), boundAddress.getHostName());
+ assertEquals(bindAddress.getPort(), boundAddress.getPort());
+
+ ssc.close();
+ }
+
+ public void test_bind_socketSync() throws IOException {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ assertNull(ssc.socket().getLocalSocketAddress());
+
+ ServerSocket socket = ssc.socket();
+ assertNull(socket.getLocalSocketAddress());
+ assertFalse(socket.isBound());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ ssc.socket().bind(bindAddr);
+
+ InetSocketAddress actualAddr = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
+ assertEquals(actualAddr, socket.getLocalSocketAddress());
+ assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
+ assertTrue(socket.isBound());
+ assertFalse(socket.isClosed());
+
+ ssc.close();
+
+ assertFalse(ssc.isOpen());
+ assertTrue(socket.isClosed());
+ }
+
+ public void test_bind_socketSyncAfterBind() throws IOException {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ assertNull(ssc.socket().getLocalSocketAddress());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ ssc.socket().bind(bindAddr);
+
+ // Socket creation after bind().
+ ServerSocket socket = ssc.socket();
+ InetSocketAddress actualAddr = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
+ assertEquals(actualAddr, socket.getLocalSocketAddress());
+ assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
+ assertTrue(socket.isBound());
+ assertFalse(socket.isClosed());
+
+ ssc.close();
+
+ assertFalse(ssc.isOpen());
+ assertTrue(socket.isClosed());
+ }
+
+ // -------------------------------------------------------------------
+ // Test for getLocalSocketAddress()
+ // -------------------------------------------------------------------
+
+ public void test_getLocalSocketAddress_afterClose() throws IOException {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ assertNull(ssc.socket().getLocalSocketAddress());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ ssc.socket().bind(bindAddr);
+
+ assertNotNull(ssc.socket().getLocalSocketAddress());
+
+ ssc.close();
+
+ assertFalse(ssc.isOpen());
+
+ ssc.socket().getLocalSocketAddress();
+ }
+
+ // -------------------------------------------------------------------
+ // Test for socket()
+ // -------------------------------------------------------------------
+
+ /*
+ * Test method for 'java.nio.channels.ServerSocketChannel.socket()'
+ */
+ public void testSocket_Block_BeforeClose() throws Exception {
+ assertTrue(this.serverChannel.isOpen());
+ assertTrue(this.serverChannel.isBlocking());
+ ServerSocket s1 = this.serverChannel.socket();
+ assertFalse(s1.isClosed());
+ assertSocketNotAccepted(s1);
+ ServerSocket s2 = this.serverChannel.socket();
+ // same
+ assertSame(s1, s2);
+
+ // socket close makes the channel close
+ s1.close();
+ assertFalse(this.serverChannel.isOpen());
+
+ }
+
+ public void testSocket_NonBlock_BeforeClose() throws Exception {
+ assertTrue(this.serverChannel.isOpen());
+ this.serverChannel.configureBlocking(false);
+ ServerSocket s1 = this.serverChannel.socket();
+ assertFalse(s1.isClosed());
+ assertSocketNotAccepted(s1);
+ ServerSocket s2 = this.serverChannel.socket();
+ // same
+ assertSame(s1, s2);
+
+ // socket close makes the channel close
+ s1.close();
+ assertFalse(this.serverChannel.isOpen());
+
+ }
+
+ public void testSocket_Block_Closed() throws Exception {
+ this.serverChannel.close();
+ assertFalse(this.serverChannel.isOpen());
+ assertTrue(this.serverChannel.isBlocking());
+ ServerSocket s1 = this.serverChannel.socket();
+ assertTrue(s1.isClosed());
+ assertSocketNotAccepted(s1);
+ ServerSocket s2 = this.serverChannel.socket();
+ // same
+ assertSame(s1, s2);
+ }
+
+ public void testSocket_NonBlock_Closed() throws Exception {
+ this.serverChannel.configureBlocking(false);
+ this.serverChannel.close();
+ assertFalse(this.serverChannel.isBlocking());
+ assertFalse(this.serverChannel.isOpen());
+ ServerSocket s1 = this.serverChannel.socket();
+ assertTrue(s1.isClosed());
+ assertSocketNotAccepted(s1);
+ ServerSocket s2 = this.serverChannel.socket();
+ // same
+ assertSame(s1, s2);
+ }
+
+ private void assertSocketNotAccepted(ServerSocket s) throws IOException {
+ assertFalse(s.isBound());
+ assertNull(s.getInetAddress());
+ assertEquals(-1, s.getLocalPort());
+ assertNull(s.getLocalSocketAddress());
+ try {
+ assertEquals(0, s.getSoTimeout());
+ } catch (IOException expected) {
+ // Android doesn't cache the timeout, so the getsockopt(2) fails and throws.
+ }
+ }
+
+ public void testChannelBasicStatus() {
+ ServerSocket gotSocket = this.serverChannel.socket();
+ assertFalse(gotSocket.isClosed());
+ assertTrue(this.serverChannel.isBlocking());
+ assertFalse(this.serverChannel.isRegistered());
+ assertEquals(SelectionKey.OP_ACCEPT, this.serverChannel.validOps());
+ assertEquals(SelectorProvider.provider(), this.serverChannel.provider());
+ }
+
+ // -------------------------------------------------------------------
+ // Test for accept()
+ // -------------------------------------------------------------------
+
+ /*
+ * Test method for 'java.nio.channels.ServerSocketChannel.accept()'
+ */
+
+ public void testAccept_Block_NotYetBound() throws IOException {
+ assertTrue(this.serverChannel.isOpen());
+ assertTrue(this.serverChannel.isBlocking());
+ try {
+ this.serverChannel.accept();
+ fail("Should throw NotYetBoundException");
+ } catch (NotYetBoundException e) {
+ // correct
+ }
+ }
+
+ public void testAccept_NonBlock_NotYetBound() throws IOException {
+ assertTrue(this.serverChannel.isOpen());
+ this.serverChannel.configureBlocking(false);
+ try {
+ this.serverChannel.accept();
+ fail("Should throw NotYetBoundException");
+ } catch (NotYetBoundException e) {
+ // correct
+ }
+ }
+
+ public void testAccept_ClosedChannel() throws Exception {
+ this.serverChannel.close();
+ assertFalse(this.serverChannel.isOpen());
+ try {
+ this.serverChannel.accept();
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ }
+
+ public void testAccept_Block_NoConnect() throws IOException {
+ assertTrue(this.serverChannel.isBlocking());
+ serverChannel.socket().bind(null);
+ // blocking mode , will block and wait for ever...
+ // so must close the server channel with another thread.
+ new Thread() {
+ public void run() {
+ try {
+ Thread.sleep(TIME_UNIT);
+ ServerSocketChannelTest.this.serverChannel.close();
+ } catch (Exception e) {
+ fail("Fail to close the server channel because of"
+ + e.getClass().getName());
+ }
+ }
+ }.start();
+ try {
+ this.serverChannel.accept();
+ fail("Should throw a AsynchronousCloseException");
+ } catch (AsynchronousCloseException e) {
+ // OK.
+ }
+ }
+
+ public void testAccept_NonBlock_NoConnect() throws IOException {
+ this.serverChannel.socket().bind(null);
+ this.serverChannel.configureBlocking(false);
+ // non-blocking mode , will immediately return
+ assertNull(this.serverChannel.accept());
+ }
+
+ /**
+ * @tests ServerSocketChannel#accept().socket()
+ */
+ public void test_read_Blocking_RealData() throws IOException {
+ serverChannel.socket().bind(null);
+ ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
+
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ buf.put((byte) i);
+ }
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ Socket serverSocket = serverChannel.accept().socket();
+ InputStream in = serverSocket.getInputStream();
+ buf.flip();
+ clientChannel.write(buf);
+ clientChannel.close();
+ assertReadResult(in,CAPACITY_NORMAL);
+ }
+
+ /**
+ * Asserts read content. The read content should contain <code>size</code>
+ * bytes, and the value should be a sequence from 0 to size-1
+ * ([0,1,...size-1]). Otherwise, the method throws Exception.
+ *
+ */
+ private void assertReadResult(InputStream in, int size) throws IOException{
+ byte[] readContent = new byte[size + 1];
+ int count = 0;
+ int total = 0;
+ while ((count = in.read(readContent, total, size + 1 - total)) != -1) {
+ total = total + count;
+ }
+ assertEquals(size, total);
+ for (int i = 0; i < size; i++) {
+ assertEquals((byte) i, readContent[i]);
+ }
+ }
+
+ /**
+ * @tests ServerSocketChannel#accept().socket()
+ */
+ public void test_read_NonBlocking_RealData() throws Exception {
+ serverChannel.configureBlocking(false);
+ serverChannel.socket().bind(null);
+ ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ buf.put((byte) i);
+ }
+ buf.flip();
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ Socket serverSocket = serverChannel.accept().socket();
+ InputStream in = serverSocket.getInputStream();
+ clientChannel.write(buf);
+ clientChannel.close();
+ assertReadResult(in,CAPACITY_NORMAL);
+ }
+
+ /**
+ * @tests ServerSocketChannel#accept().socket()
+ */
+ public void test_write_Blocking_RealData() throws IOException {
+ assertTrue(serverChannel.isBlocking());
+ serverChannel.socket().bind(null);
+
+ byte[] writeContent = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < writeContent.length; i++) {
+ writeContent[i] = (byte) i;
+ }
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ Socket socket = serverChannel.accept().socket();
+ OutputStream out = socket.getOutputStream();
+ out.write(writeContent);
+ out.flush();
+ socket.close();
+ assertWriteResult(CAPACITY_NORMAL);
+ }
+
+
+ /**
+ * @tests ServerSocketChannel#accept().socket()
+ */
+ public void test_write_NonBlocking_RealData() throws Exception {
+ serverChannel.configureBlocking(false);
+ serverChannel.socket().bind(null);
+
+ byte[] writeContent = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ writeContent[i] = (byte) i;
+ }
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ Socket clientSocket = serverChannel.accept().socket();
+ OutputStream out = clientSocket.getOutputStream();
+ out.write(writeContent);
+ clientSocket.close();
+ assertWriteResult(CAPACITY_NORMAL);
+ }
+
+ /**
+ * @throws InterruptedException
+ * @tests ServerSocketChannel#accept().socket()
+ */
+ public void test_read_LByteBuffer_Blocking_ReadWriteRealLargeData()
+ throws IOException, InterruptedException {
+ serverChannel.socket().bind(null);
+ ByteBuffer buf = ByteBuffer.allocate(CAPACITY_64KB);
+ for (int i = 0; i < CAPACITY_64KB; i++) {
+ buf.put((byte) i);
+ }
+ buf.flip();
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ WriteChannelThread writeThread = new WriteChannelThread(clientChannel, buf);
+ writeThread.start();
+ Socket socket = serverChannel.accept().socket();
+ InputStream in = socket.getInputStream();
+ assertReadResult(in,CAPACITY_64KB);
+ writeThread.join();
+ // check if the thread threw any exceptions
+ if (writeThread.exception != null) {
+ throw writeThread.exception;
+ }
+ }
+
+ class WriteChannelThread extends Thread {
+ SocketChannel channel;
+ ByteBuffer buffer;
+ IOException exception;
+
+ public WriteChannelThread(SocketChannel channel, ByteBuffer buffer) {
+ this.channel = channel;
+ this.buffer = buffer;
+ }
+
+ public void run() {
+ try {
+ channel.write(buffer);
+ channel.close();
+ } catch (IOException e) {
+ exception = e;
+ }
+ }
+ }
+
+ /**
+ * @tests ServerSocketChannel#accept().socket()
+ */
+ public void test_read_LByteBuffer_NonBlocking_ReadWriteRealLargeData()
+ throws Exception {
+ serverChannel.configureBlocking(false);
+ serverChannel.socket().bind(null);
+ ByteBuffer buf = ByteBuffer.allocate(CAPACITY_64KB);
+ for (int i = 0; i < CAPACITY_64KB; i++) {
+ buf.put((byte) i);
+ }
+ buf.flip();
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ WriteChannelThread writeThread = new WriteChannelThread(clientChannel, buf);
+ writeThread.start();
+ Socket socket = serverChannel.accept().socket();
+ InputStream in = socket.getInputStream();
+ assertReadResult(in,CAPACITY_64KB);
+ writeThread.join();
+ // check if the thread threw any exceptions
+ if (writeThread.exception != null) {
+ throw writeThread.exception;
+ }
+ }
+
+ /**
+ * @tests ServerSocketChannel#accept().socket()
+ */
+ public void test_write_LByteBuffer_NonBlocking_ReadWriteRealLargeData()
+ throws Exception {
+ serverChannel.configureBlocking(false);
+ serverChannel.socket().bind(null);
+ byte[] writeContent = new byte[CAPACITY_64KB];
+ for (int i = 0; i < writeContent.length; i++) {
+ writeContent[i] = (byte) i;
+ }
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ Socket socket = serverChannel.accept().socket();
+ WriteSocketThread writeThread = new WriteSocketThread(socket, writeContent);
+ writeThread.start();
+ assertWriteResult(CAPACITY_64KB);
+ writeThread.join();
+ // check if the thread threw any exceptions
+ if (writeThread.exception != null) {
+ throw writeThread.exception;
+ }
+ }
+
+ class WriteSocketThread extends Thread {
+ Socket socket;
+ byte[] buffer;
+ IOException exception;
+
+ public WriteSocketThread(Socket socket, byte[] buffer) {
+ this.socket = socket;
+ this.buffer = buffer;
+ }
+
+ public void run() {
+ try {
+ OutputStream out = socket.getOutputStream();
+ out.write(buffer);
+ socket.close();
+ } catch (IOException e) {
+ exception = e;
+ }
+ }
+ }
+
+ /**
+ * @tests ServerSocketChannel#accept().socket()
+ */
+ public void test_write_LByteBuffer_Blocking_ReadWriteRealLargeData()
+ throws Exception {
+ serverChannel.socket().bind(null);
+ byte[] writeContent = new byte[CAPACITY_64KB];
+ for (int i = 0; i < writeContent.length; i++) {
+ writeContent[i] = (byte) i;
+ }
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ Socket socket = serverChannel.accept().socket();
+ WriteSocketThread writeThread = new WriteSocketThread(socket, writeContent);
+ writeThread.start();
+ assertWriteResult(CAPACITY_64KB);
+ writeThread.join();
+ // check if the thread threw any exceptions
+ if (writeThread.exception != null) {
+ throw writeThread.exception;
+ }
+ }
+
+ /**
+ * Uses SocketChannel.read(ByteBuffer) to verify write result.
+ */
+ private void assertWriteResult(int size) throws IOException{
+ ByteBuffer buf = ByteBuffer.allocate(size + 1);
+ int count = 0;
+ int total = 0;
+ long beginTime = System.currentTimeMillis();
+ while ((count = clientChannel.read(buf)) != -1) {
+ total = total + count;
+ // 10s timeout to avoid dead loop
+ if (System.currentTimeMillis() - beginTime > 10000){
+ break;
+ }
+ }
+ assertEquals(total, size);
+ buf.flip();
+ for (int i = 0; i < count; i++) {
+ assertEquals((byte) i, buf.get(i));
+ }
+ }
+
+ /**
+ * @tests ServerSocketChannel#socket().getSoTimeout()
+ */
+ public void test_accept_SOTIMEOUT() throws IOException {
+ // Regression test for Harmony-707
+ // The timeout actually used may be different from the one set due to
+ // rounding by the Linux Kernel (see sock_set_timeout() in net/core/sock.c).
+ // getSoTimeout() can return a different value from the one set with
+ // setSoTimeout(). Consequently we do not check for equality with what was
+ // set.
+
+ ServerSocketChannel sc = ServerSocketChannel.open();
+ try {
+ sc.socket().bind(null);
+
+ // Non blocking mode, accept() will return NULL since there are no pending connections.
+ sc.configureBlocking(false);
+
+ ServerSocket ss = sc.socket();
+
+ int defaultTimeout = ss.getSoTimeout();
+ assertEquals(0, defaultTimeout);
+ // The timeout value is unimportant, providing it is large enough to be accepted
+ // by the Kernel as distinct from the default.
+ final int SO_TIMEOUT = 200;
+ ss.setSoTimeout(SO_TIMEOUT);
+ int nonDefaultTimeout = ss.getSoTimeout();
+ assertTrue(nonDefaultTimeout != defaultTimeout);
+
+ SocketChannel client = sc.accept();
+ assertNull(client);
+ // Confirm the timeout was unchanged.
+ assertEquals(nonDefaultTimeout, ss.getSoTimeout());
+ } finally {
+ sc.close();
+ }
+ }
+
+ /**
+ * @tests ServerSocket#socket().accept()
+ */
+ public void test_socket_accept_Blocking_NotBound() throws IOException {
+ // regression test for Harmony-748
+ ServerSocket gotSocket = serverChannel.socket();
+ serverChannel.configureBlocking(true);
+ try {
+ gotSocket.accept();
+ fail("Should throw an IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException expected) {
+ }
+ serverChannel.close();
+ try {
+ gotSocket.accept();
+ fail("Should throw an IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException expected) {
+ }
+ }
+
+ /**
+ * @tests ServerSocket#socket().accept()
+ */
+ public void test_socket_accept_Nonblocking_NotBound() throws IOException {
+ // regression test for Harmony-748
+ ServerSocket gotSocket = serverChannel.socket();
+ serverChannel.configureBlocking(false);
+ try {
+ gotSocket.accept();
+ fail("Should throw an IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException expected) {
+ }
+ serverChannel.close();
+ try {
+ gotSocket.accept();
+ fail("Should throw an IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException expected) {
+ }
+ }
+
+ /**
+ * @tests ServerSocket#socket().accept()
+ */
+ public void test_socket_accept_Nonblocking_Bound() throws IOException {
+ // regression test for Harmony-748
+ serverChannel.configureBlocking(false);
+ serverChannel.socket().bind(null);
+ ServerSocket gotSocket = serverChannel.socket();
+ try {
+ gotSocket.accept();
+ fail("Should throw an IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException expected) {
+ }
+ serverChannel.close();
+ try {
+ gotSocket.accept();
+ fail("Should throw a ClosedChannelException");
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests ServerSocket#socket().accept()
+ */
+ public void test_socket_accept_Blocking_Bound() throws IOException {
+ // regression test for Harmony-748
+ serverChannel.configureBlocking(true);
+ serverChannel.socket().bind(null);
+ serverChannel.close();
+ try {
+ serverChannel.socket().accept();
+ fail("Should throw a ClosedChannelException");
+ } catch (ClosedChannelException expected) {
+ }
+ }
+ /**
+ * Regression test for HARMONY-4961
+ */
+ public void test_socket_getLocalPort() throws IOException {
+ serverChannel.socket().bind(null);
+ clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
+ SocketChannel myChannel = serverChannel.accept();
+ int port = myChannel.socket().getLocalPort();
+ assertEquals(serverChannel.socket().getLocalPort(), port);
+ myChannel.close();
+ clientChannel.close();
+ serverChannel.close();
+ }
+
+ /**
+ * Regression test for HARMONY-6375
+ */
+ public void test_accept_configureBlocking() throws Exception {
+ InetSocketAddress localAddr = new InetSocketAddress("localhost", 0);
+ serverChannel.socket().bind(localAddr);
+
+ // configure the channel non-blocking
+ // when it is accepting in main thread
+ new Thread() {
+ public void run() {
+ try {
+ Thread.sleep(TIME_UNIT);
+ serverChannel.configureBlocking(false);
+ serverChannel.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }.start();
+
+ try {
+ serverChannel.accept();
+ fail("should throw AsynchronousCloseException");
+ } catch (AsynchronousCloseException expected) {
+ }
+ serverChannel.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SinkChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SinkChannelTest.java
new file mode 100644
index 0000000..32f59c5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SinkChannelTest.java
@@ -0,0 +1,505 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.Pipe;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for Pipe.SinkChannel class
+ */
+public class SinkChannelTest extends TestCase {
+
+ private static final int BUFFER_SIZE = 5;
+
+ private static final String ISO8859_1 = "ISO8859-1";
+
+ private Pipe pipe;
+
+ private Pipe.SinkChannel sink;
+
+ private Pipe.SourceChannel source;
+
+ private ByteBuffer buffer;
+
+ private ByteBuffer positionedBuffer;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ pipe = Pipe.open();
+ sink = pipe.sink();
+ source = pipe.source();
+ buffer = ByteBuffer.wrap("bytes".getBytes(ISO8859_1));
+ positionedBuffer = ByteBuffer.wrap("12345bytes".getBytes(ISO8859_1));
+ positionedBuffer.position(BUFFER_SIZE);
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SinkChannel#validOps()
+ */
+ public void test_validOps() {
+ assertEquals(SelectionKey.OP_WRITE, sink.validOps());
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
+ */
+ public void test_write_LByteBuffer() throws IOException {
+ ByteBuffer[] bufArray = { buffer, positionedBuffer };
+ boolean[] sinkBlockingMode = { true, true, false, false };
+ boolean[] sourceBlockingMode = { true, false, true, false };
+ int oldPosition;
+ int currentPosition;
+ for (int i = 0; i < sinkBlockingMode.length; ++i) {
+ sink.configureBlocking(sinkBlockingMode[i]);
+ source.configureBlocking(sourceBlockingMode[i]);
+ // if sink and source both are blocking mode, source only needs read
+ // once to get what sink write.
+ boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i];
+ for (ByteBuffer buf : bufArray) {
+ buf.mark();
+ oldPosition = buf.position();
+ sink.write(buf);
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ int totalCount = 0;
+ do {
+ int count = source.read(readBuf);
+ if (count > 0) {
+ totalCount += count;
+ }
+ } while (totalCount != BUFFER_SIZE && !isBlocking);
+ currentPosition = buf.position();
+ assertEquals(BUFFER_SIZE, currentPosition - oldPosition);
+ assertEquals("bytes", new String(readBuf.array(), ISO8859_1));
+ buf.reset();
+ }
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
+ */
+ public void test_write_LByteBuffer_mutliThread() throws IOException,
+ InterruptedException {
+ final int THREAD_NUM = 20;
+ final byte[] strbytes = "bytes".getBytes(ISO8859_1);
+ Thread[] thread = new Thread[THREAD_NUM];
+ for (int i = 0; i < THREAD_NUM; i++) {
+ thread[i] = new Thread() {
+ public void run() {
+ try {
+ sink.write(ByteBuffer.wrap(strbytes));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+ for (int i = 0; i < THREAD_NUM; i++) {
+ thread[i].start();
+ }
+ for (int i = 0; i < THREAD_NUM; i++) {
+ thread[i].join();
+ }
+ ByteBuffer readBuf = ByteBuffer.allocate(THREAD_NUM * BUFFER_SIZE);
+
+ long totalCount = 0;
+ do {
+ long count = source.read(readBuf);
+ if (count < 0) {
+ break;
+ }
+ totalCount += count;
+ } while (totalCount != (THREAD_NUM * BUFFER_SIZE));
+
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < THREAD_NUM; i++) {
+ buf.append("bytes");
+ }
+ String readString = buf.toString();
+ assertEquals(readString, new String(readBuf.array(), ISO8859_1));
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer)
+ */
+ public void test_write_LByteBuffer_Exception() throws IOException {
+ // write null ByteBuffer
+ ByteBuffer nullBuf = null;
+ try {
+ sink.write(nullBuf);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void test_write_LByteBuffer_SourceClosed() throws IOException {
+ source.close();
+ try {
+ int written = sink.write(buffer);
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ public void test_write_LByteBuffer_SinkClosed() throws IOException {
+ sink.close();
+ try {
+ sink.write(buffer);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
+ */
+ public void test_write_$LByteBuffer() throws IOException {
+ ByteBuffer[] bufArray = { buffer, positionedBuffer };
+ boolean[] sinkBlockingMode = { true, true, false, false };
+ boolean[] sourceBlockingMode = { true, false, true, false };
+ for (int i = 0; i < sinkBlockingMode.length; ++i) {
+ sink.configureBlocking(sinkBlockingMode[i]);
+ source.configureBlocking(sourceBlockingMode[i]);
+ buffer.position(0);
+ positionedBuffer.position(BUFFER_SIZE);
+ sink.write(bufArray);
+ // if sink and source both are blocking mode, source only needs read
+ // once to get what sink write.
+ boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i];
+ for (int j = 0; j < bufArray.length; ++j) {
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ int totalCount = 0;
+ do {
+ int count = source.read(readBuf);
+ if (count < 0) {
+ break;
+ }
+ totalCount += count;
+ } while (totalCount != BUFFER_SIZE && !isBlocking);
+ assertEquals("bytes", new String(readBuf.array(), ISO8859_1));
+ }
+ assertEquals(BUFFER_SIZE, buffer.position());
+ assertEquals(10, positionedBuffer.position());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
+ */
+ public void test_write_$LByteBuffer_Exception() throws IOException {
+ // write null ByteBuffer[]
+ ByteBuffer[] nullBufArrayRef = null;
+ try {
+ sink.write(nullBufArrayRef);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // write ByteBuffer[] contains null element
+ ByteBuffer nullBuf = null;
+ ByteBuffer[] nullBufArray = { buffer, nullBuf };
+ try {
+ sink.write(nullBufArray);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void test_write_$LByteBuffer_SourceClosed() throws IOException {
+ ByteBuffer[] bufArray = { buffer };
+ source.close();
+ try {
+ long written = sink.write(bufArray);
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[])
+ */
+ public void test_write_$LByteBuffer_SinkClosed() throws IOException {
+ ByteBuffer[] bufArray = { buffer };
+ sink.close();
+ try {
+ sink.write(bufArray);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ ByteBuffer[] nullBufArrayRef = null;
+ try {
+ sink.write(nullBufArrayRef);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ ByteBuffer nullBuf = null;
+ ByteBuffer[] nullBufArray = { nullBuf };
+ // write ByteBuffer[] contains null element
+ try {
+ sink.write(nullBufArray);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[], int, int)
+ */
+ public void test_write_$LByteBufferII() throws IOException {
+ ByteBuffer[] bufArray = { buffer, positionedBuffer };
+ boolean[] sinkBlockingMode = { true, true, false, false };
+ boolean[] sourceBlockingMode = { true, false, true, false };
+ for (int i = 0; i < sinkBlockingMode.length; ++i) {
+ sink.configureBlocking(sinkBlockingMode[i]);
+ source.configureBlocking(sourceBlockingMode[i]);
+ positionedBuffer.position(BUFFER_SIZE);
+ sink.write(bufArray, 1, 1);
+ // if sink and source both are blocking mode, source only needs read
+ // once to get what sink write.
+ boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i];
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ int totalCount = 0;
+ do {
+ int count = source.read(readBuf);
+ if (count < 0) {
+ break;
+ }
+ totalCount += count;
+ } while (totalCount != BUFFER_SIZE && !isBlocking);
+ assertEquals("bytes", new String(readBuf.array(), ISO8859_1));
+ assertEquals(10, positionedBuffer.position());
+ }
+ }
+
+ public void test_write_$LByteBufferII_Exception() throws IOException {
+ try {
+ sink.write(null, 0, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ sink.write(new ByteBuffer[2], 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // write ByteBuffer[] contains null element
+ ByteBuffer nullBuf = null;
+ ByteBuffer[] nullBufArray = { nullBuf };
+ try {
+ sink.write(nullBufArray, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ sink.write(nullBufArray, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ ByteBuffer[] bufArray = { buffer, nullBuf };
+ try {
+ sink.write(bufArray, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ sink.write(bufArray, -1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ sink.write(bufArray, -1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ sink.write(bufArray, 0, 3);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ sink.write(bufArray, 0, 2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void test_write_$LByteBufferII_SourceClosed() throws IOException {
+ ByteBuffer[] bufArray = { buffer };
+ source.close();
+
+ try {
+ long written = sink.write(bufArray, 0, 1);
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ public void test_write_$LByteBufferII_SinkClosed() throws IOException {
+ ByteBuffer[] bufArray = { buffer };
+ sink.close();
+ try {
+ sink.write(bufArray, 0, 1);
+ fail();
+ } catch (ClosedChannelException expected) {
+ }
+
+ try {
+ sink.write(null, 0, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ sink.write(new ByteBuffer[2], 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // write ByteBuffer[] contains null element
+ ByteBuffer nullBuf = null;
+ ByteBuffer[] nullBufArray = { nullBuf };
+ try {
+ sink.write(nullBufArray, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ // illegal array index
+ try {
+ sink.write(nullBufArray, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ ByteBuffer[] bufArray2 = { buffer, nullBuf };
+ // illegal array index
+ try {
+ sink.write(bufArray2, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ sink.write(bufArray2, -1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ sink.write(bufArray2, -1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ sink.write(bufArray2, 0, 3);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ sink.write(bufArray2, 0, 2);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ public void test_close() throws IOException {
+ sink.close();
+ assertFalse(sink.isOpen());
+ }
+
+ public void test_socketChannel_read_close() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999));
+ SocketChannel sc = SocketChannel.open();
+ ByteBuffer buf = null;
+ try{
+ sc.write(buf);
+ fail("should throw NPE");
+ }catch (NullPointerException e){
+ // expected
+ }
+ sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999));
+ SocketChannel sock = ssc.accept();
+ ssc.close();
+ sc.close();
+ try{
+ sc.write(buf);
+ fail("should throw NPE");
+ }catch (NullPointerException e){
+ // expected
+ }
+ sock.close();
+ }
+
+ public void test_socketChannel_read_write() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999));
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999));
+ SocketChannel sock = ssc.accept();
+ ByteBuffer[] buf = {ByteBuffer.allocate(10),null};
+ try {
+ sc.write(buf,0,2);
+ fail("should throw NPE");
+ } catch (NullPointerException expected) {
+ }
+ ssc.close();
+ sc.close();
+ ByteBuffer target = ByteBuffer.allocate(10);
+ assertEquals(-1, sock.read(target));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java
new file mode 100644
index 0000000..51a8cff
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java
@@ -0,0 +1,3812 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.BindException;
+import java.net.ConnectException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.channels.AlreadyConnectedException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.ConnectionPendingException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.NoConnectionPendingException;
+import java.nio.channels.NotYetConnectedException;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.UnresolvedAddressException;
+import java.nio.channels.UnsupportedAddressTypeException;
+import java.nio.channels.spi.SelectorProvider;
+import junit.framework.TestCase;
+
+/**
+ * Tests for SocketChannel and its default implementation.
+ */
+public class SocketChannelTest extends TestCase {
+
+ private static final int CAPACITY_NORMAL = 200;
+
+ private InetSocketAddress localAddr1;
+ private InetSocketAddress localAddr2;
+
+ private SocketChannel channel1;
+
+ private SocketChannel channel2;
+
+ private ServerSocket server1;
+
+ private ServerSocket server2;
+
+ private final static int TIMEOUT = 60000;
+
+ private final static int EOF = -1;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.channel1 = SocketChannel.open();
+ this.channel2 = SocketChannel.open();
+ this.server1 = new ServerSocket(0);
+ this.localAddr1 = new InetSocketAddress("127.0.0.1", server1.getLocalPort());
+
+ this.server2 = new ServerSocket(0);
+ this.localAddr2 = new InetSocketAddress("127.0.0.1", server2.getLocalPort());
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (null != this.channel1) {
+ try {
+ this.channel1.close();
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+ if (null != this.channel2) {
+ try {
+ this.channel2.close();
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+ if (null != this.server1) {
+ try {
+ this.server1.close();
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+ if (null != this.server2) {
+ try {
+ this.server2.close();
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // Test for methods in abstract class.
+ // -------------------------------------------------------------------
+ /*
+ * Test method for 'java.nio.channels.SocketChannel.validOps()'
+ */
+ public void testValidOps() {
+ MockSocketChannel testMSChannel = new MockSocketChannel(null);
+ assertEquals(13, this.channel1.validOps());
+ assertEquals(13, testMSChannel.validOps());
+ }
+
+ /*
+ * Test method for 'java.nio.channels.SocketChannel.open()'
+ */
+ public void testOpen() throws IOException {
+ java.nio.ByteBuffer[] buf = new java.nio.ByteBuffer[1];
+ buf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ MockSocketChannel testMSChannel = new MockSocketChannel(null);
+ MockSocketChannel testMSChannelnotnull = new MockSocketChannel(
+ SelectorProvider.provider());
+ assertNull(testMSChannel.provider());
+ assertNotNull(testMSChannelnotnull.provider());
+ assertNotNull(this.channel1);
+ assertEquals(this.channel1.provider(), testMSChannelnotnull.provider());
+ try {
+ this.channel1.write(buf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ }
+
+ /*
+ * Test method for 'java.nio.channels.SocketChannel.open(SocketAddress)'
+ */
+ public void testOpenSocketAddress_Null() throws IOException {
+ try {
+ SocketChannel.open(null);
+ fail("Should throw an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // correct
+ }
+ }
+
+ public void testBind_Null() throws Exception {
+ assertNull(channel1.socket().getLocalSocketAddress());
+
+ channel1.socket().bind(null);
+
+ InetSocketAddress localAddress = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
+ assertTrue(localAddress.getAddress().isAnyLocalAddress());
+ assertTrue(localAddress.getPort() > 0);
+ }
+
+ public void testBind_Failure() throws Exception {
+ assertNull(channel1.socket().getLocalSocketAddress());
+
+ try {
+ // Bind to a local address that is in use
+ channel1.socket().bind(localAddr1);
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ public void testBind_Closed() throws Exception {
+ channel1.close();
+
+ try {
+ channel1.socket().bind(null);
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ public void testBind_explicitPort() throws Exception {
+ ServerSocketChannel portPickingChannel = ServerSocketChannel.open();
+ // Have the OS find a free port.
+ portPickingChannel.socket().bind(null);
+ InetSocketAddress address = (InetSocketAddress) portPickingChannel.socket().getLocalSocketAddress();
+ assertTrue(address.getPort() > 0);
+ portPickingChannel.close();
+
+ // There is a risk of flakiness here if the port is allocated to something else between
+ // close() and bind().
+ InetSocketAddress bindAddress = new InetSocketAddress("localhost", address.getPort());
+ // Allow the socket to bind to a port we know is already in use.
+ channel1.socket().setReuseAddress(true);
+ channel1.socket().bind(bindAddress);
+
+ InetSocketAddress boundAddress = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
+ assertEquals(bindAddress.getHostName(), boundAddress.getHostName());
+ assertEquals(bindAddress.getPort(), boundAddress.getPort());
+ }
+
+ public void test_getLocalSocketAddress_afterClose() throws IOException {
+ SocketChannel sc = SocketChannel.open();
+ assertNull(sc.socket().getLocalSocketAddress());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ sc.socket().bind(bindAddr);
+
+ assertNotNull(sc.socket().getLocalSocketAddress());
+
+ sc.close();
+
+ assertFalse(sc.isOpen());
+
+ sc.socket().getLocalSocketAddress();
+ }
+
+ /*
+ * Test method for 'java.nio.channels.SocketChannel.read(ByteBuffer[])'
+ */
+ public void testReadByteBufferArray() throws IOException {
+ java.nio.ByteBuffer[] byteBuf = null;
+ MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
+ MockSocketChannel testMSChannel = new MockSocketChannel(
+ SelectorProvider.provider());
+ ServerSocket testServer = new ServerSocket(0);
+ try {
+ try {
+ this.channel1.read(byteBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ byteBuf = new java.nio.ByteBuffer[CAPACITY_NORMAL];
+ try {
+ this.channel1.read(byteBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ long readNum = testMSChannel.read(byteBuf);
+ assertEquals(0, readNum);
+ readNum = CAPACITY_NORMAL;
+ readNum = testMSChannelnull.read(byteBuf);
+ assertEquals(0, readNum);
+ } finally {
+ testServer.close();
+ }
+ }
+
+ /*
+ * Test method for 'java.nio.channels.SocketChannel.read(ByteBuffer[])'
+ */
+ public void testReadByteBufferArray_BufNull() throws IOException {
+ java.nio.ByteBuffer[] byteBuf = null;
+ MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
+ MockSocketChannel testMSChannel = new MockSocketChannel(
+ SelectorProvider.provider());
+ try {
+ this.channel1.read(byteBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ testMSChannel.read(byteBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ testMSChannelnull.read(byteBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ /*
+ * Test method for 'java.nio.channels.SocketChannel.write(ByteBuffer[])'
+ */
+ public void testWriteByteBufferArray() throws IOException {
+ java.nio.ByteBuffer[] byteBuf = null;
+ MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
+ MockSocketChannel testMSChannel = new MockSocketChannel(
+ SelectorProvider.provider());
+ try {
+ this.channel1.write(byteBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ byteBuf = new java.nio.ByteBuffer[CAPACITY_NORMAL];
+ try {
+ this.channel1.write(byteBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ testMSChannel.write(byteBuf);
+ testMSChannelnull.write(byteBuf);
+ }
+
+ /*
+ * Test method for 'java.nio.channels.SocketChannel.write(ByteBuffer[])'
+ */
+ public void testWriteByteBufferArray_BufNull() throws IOException {
+ java.nio.ByteBuffer[] byteBuf = null;
+ MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
+ MockSocketChannel testMSChannel = new MockSocketChannel(
+ SelectorProvider.provider());
+ try {
+ this.channel1.write(byteBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ testMSChannel.write(byteBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ testMSChannelnull.write(byteBuf);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ public void testSocket_BasicStatusBeforeConnect() throws IOException {
+ assertFalse(this.channel1.isConnected());// not connected
+ Socket s1 = this.channel1.socket();
+ assertSocketBeforeBind(s1);
+ assertSocketBeforeConnect(s1);
+ Socket s2 = this.channel1.socket();
+ // same
+ assertSame(s1, s2);
+ }
+
+ public void testSocket_Block_BasicStatusAfterConnect() throws IOException {
+ assertFalse(this.channel1.isConnected());// not connected
+ assertTrue(this.channel1.connect(localAddr1));
+
+ assertTrue(this.channel1.isConnected());
+ Socket s1 = this.channel1.socket();
+
+ assertSocketAfterConnect(s1, localAddr1);
+ Socket s2 = this.channel1.socket();
+ // same
+ assertSame(s1, s2);
+ }
+
+ public void testSocket_NonBlock_BasicStatusAfterConnect() throws Exception {
+ assertFalse(this.channel1.isConnected());// not connected
+ this.channel1.configureBlocking(false);
+ boolean connected = channel1.connect(localAddr1);
+ Socket s1;
+ Socket s2;
+ if (!connected) {
+ assertFalse(this.channel1.isConnected());
+ assertTrue(this.channel1.isConnectionPending());
+ s1 = this.channel1.socket();
+ // A connect() causes an implicit bind()
+ assertSocketAfterImplicitBind(s1);
+
+ // status of not connected
+ assertSocketBeforeConnect(s1);
+ s2 = this.channel1.socket();
+ // same
+ assertSame(s1, s2);
+ }
+
+ if (tryFinish()) {
+ assertTrue(this.channel1.isConnected());
+ s1 = this.channel1.socket();
+ assertSocketAfterConnect(s1, localAddr1);
+ s2 = this.channel1.socket();
+ // same
+ assertSame(s1, s2);
+ }
+ }
+
+ public void testSocket_Block_ActionsBeforeConnect() throws IOException {
+ assertFalse(this.channel1.isConnected());// not connected
+ Socket s = this.channel1.socket();
+ assertSocketAction_Block_BeforeConnect(s);
+ }
+
+ public void testSocket_Block_ActionsAfterConnect() throws IOException {
+ assertFalse(this.channel1.isConnected());// not connected
+ assertTrue(this.channel1.connect(localAddr1));
+ assertTrue(this.channel1.isConnected());
+ Socket s = this.channel1.socket();
+ assertSocketAction_Block_AfterConnect(s);
+
+ }
+
+ public void testSocket_NonBlock_ActionsAfterConnectBeforeFinish()
+ throws IOException {
+ assertFalse(this.channel1.isConnected());// not connected
+ this.channel1.configureBlocking(false);
+ boolean connected = channel1.connect(localAddr1);
+ if (!connected) {
+ assertFalse(this.channel1.isConnected());
+ assertTrue(this.channel1.isConnectionPending());
+ Socket s1 = this.channel1.socket();
+ // Action of not connected
+ assertSocketAction_NonBlock_BeforeConnect(s1);
+ Socket s2 = this.channel1.socket();
+ // same
+ assertSame(s1, s2);
+ }
+ }
+
+ public void testSocket_NonBlock_ActionsAfterConnectAfterFinish()
+ throws Exception {
+ assertFalse(this.channel1.isConnected());// not connected
+ this.channel1.configureBlocking(false);
+ channel1.connect(localAddr1);
+ if (tryFinish()) {
+ Socket s1 = this.channel1.socket();
+ assertSocketAction_NonBlock_AfterConnect(s1);
+ Socket s2 = this.channel1.socket();
+ // same
+ assertSame(s1, s2);
+ }
+ }
+
+ public void testSocket_getInetAddress() throws Exception {
+ Socket socket = channel1.socket();
+ assertNull(socket.getInetAddress());
+
+ channel1.connect(localAddr1);
+
+ assertNotNull(socket.getInetAddress());
+ assertEquals(localAddr1.getAddress(), socket.getInetAddress());
+ }
+
+ public void testSocket_getRemoteSocketAddress() throws Exception {
+ Socket socket = channel1.socket();
+ assertNull(socket.getRemoteSocketAddress());
+
+ channel1.connect(localAddr1);
+
+ assertNotNull(socket.getRemoteSocketAddress());
+ assertEquals(localAddr1, socket.getRemoteSocketAddress());
+ }
+
+ public void testSocket_getPort() throws Exception {
+ Socket socket = channel1.socket();
+ assertEquals(0, socket.getPort());
+
+ channel1.connect(localAddr1);
+
+ assertEquals(localAddr1.getPort(), socket.getPort());
+ }
+
+ public void testSocket_getLocalAddress() throws Exception {
+ Socket socket = channel1.socket();
+
+ channel1.connect(localAddr1);
+
+ assertNotNull(socket.getLocalSocketAddress());
+ }
+
+ public void testSocket_getLocalSocketAddress() throws Exception {
+ Socket socket = channel1.socket();
+ assertNull(socket.getLocalSocketAddress());
+
+ channel1.connect(localAddr1);
+
+ assertNotNull(socket.getLocalSocketAddress());
+ }
+
+ public void testSocket_getLocalPort() throws Exception {
+ Socket socket = channel1.socket();
+ assertEquals(-1, socket.getLocalPort());
+
+ channel1.connect(localAddr1);
+
+ assertTrue(-1 != socket.getLocalPort());
+ assertTrue(0 != socket.getLocalPort());
+ }
+
+ public void testSocket_bind() throws Exception {
+ Socket socket = channel1.socket();
+ socket.bind(new InetSocketAddress("127.0.0.1", 0));
+ assertEquals("127.0.0.1", socket.getLocalAddress().getHostAddress());
+ assertTrue(socket.getLocalPort() != -1);
+ }
+
+ private void assertSocketBeforeBind(Socket s) {
+ assertFalse(s.isBound());
+ assertTrue(s.getLocalAddress().isAnyLocalAddress());
+ // RI fails here. RI returns 0 while spec says unbound socket should
+ // return -1.
+ assertEquals(-1, s.getLocalPort());
+ assertNull(s.getLocalSocketAddress());
+ }
+
+ private void assertSocketAfterImplicitBind(Socket s) throws IOException {
+ assertTrue(s.isBound());
+ assertTrue(s.getLocalAddress().isLoopbackAddress());
+ assertTrue(s.getLocalPort() > 0);
+
+ InetSocketAddress localSocketAddress = (InetSocketAddress) s.getLocalSocketAddress();
+ assertTrue(localSocketAddress.getAddress().isLoopbackAddress());
+ assertEquals(s.getLocalPort(), localSocketAddress.getPort());
+ }
+
+ private void assertSocketBeforeConnect(Socket s) throws IOException {
+ assertFalse(s.isClosed());
+ assertFalse(s.isConnected());
+ assertFalse(s.getKeepAlive());
+ try {
+ s.getInputStream();
+ fail("Should throw SocketException.");
+ } catch (SocketException e) {
+ // OK.
+ }
+ assertFalse(s.getOOBInline());
+ try {
+ s.getOutputStream();
+ fail("Should throw SocketException.");
+ } catch (SocketException e) {
+ // OK.
+ }
+ assertEquals(-1, s.getSoLinger());
+ assertFalse(s.getTcpNoDelay());
+
+ assertFalse(s.isInputShutdown());
+ assertFalse(s.isOutputShutdown());
+
+ assertNull(s.getInetAddress());
+ assertFalse(s.getReuseAddress());
+
+ // not connected
+ assertEquals(0, s.getPort());
+ assertTrue(s.getReceiveBufferSize() >= 8192);
+ assertNull(s.getRemoteSocketAddress());
+ assertTrue(s.getSendBufferSize() >= 8192);
+ assertEquals(0, s.getSoTimeout());
+ assertEquals(0, s.getTrafficClass());
+
+ }
+
+ private void assertSocketAfterConnect(Socket s, InetSocketAddress address)
+ throws IOException {
+ assertTrue(s.isBound());
+ assertFalse(s.isClosed());
+ assertTrue(s.isConnected());
+ assertFalse(s.getKeepAlive());
+
+ assertNotNull(s.getInputStream());
+ assertNotNull(s.getOutputStream());
+
+ assertFalse(s.getOOBInline());
+ assertEquals(-1, s.getSoLinger());
+ assertFalse(s.getTcpNoDelay());
+
+ assertFalse(s.isInputShutdown());
+ assertFalse(s.isOutputShutdown());
+
+ assertSame(s.getInetAddress(), address.getAddress());
+
+ assertEquals(s.getLocalAddress(), this.localAddr1.getAddress());
+ assertEquals(s.getPort(), address.getPort());
+ assertNotNull(s.getLocalSocketAddress());
+ assertTrue(s.getReceiveBufferSize() >= 8192);
+ assertEquals(s.getRemoteSocketAddress(), (SocketAddress) address);
+ // assertFalse(s.getReuseAddress());
+ assertTrue(s.getSendBufferSize() >= 8192);
+ assertEquals(0, s.getSoTimeout());
+ assertEquals(0, s.getTrafficClass());
+ }
+
+ private void assertSocketAction_Block_BeforeConnect(Socket s)
+ throws IOException {
+ assertFalse(this.channel1.isConnected());
+ s.connect(localAddr2);
+ assertTrue(this.channel1.isConnected());
+ assertTrue(s.isConnected());
+
+ assertSocketAfterConnect(s, localAddr2);
+
+ try {
+ s.bind(localAddr2);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+
+ s.close();
+ assertTrue(s.isClosed());
+ assertFalse(this.channel1.isOpen());
+ }
+
+ private void assertSocketAction_NonBlock_BeforeConnect(Socket s)
+ throws IOException {
+ assertFalse(this.channel1.isConnected());
+ try {
+ s.connect(localAddr2);
+ fail("Should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e1) {
+ // OK.
+ }
+
+ if (this.channel1.isConnectionPending()) {
+ try {
+ s.bind(localAddr2);
+ fail("Should throw ConnectionPendingException");
+ } catch (ConnectionPendingException e1) {
+ // OK.
+ }
+ } else {
+ try {
+ s.bind(localAddr2);
+ fail("Should throw BindException");
+ } catch (BindException e1) {
+ // OK.
+ }
+ }
+
+ assertFalse(this.channel1.isConnected());
+ assertFalse(s.isConnected());
+
+ s.close();
+ assertTrue(s.isClosed());
+ assertFalse(this.channel1.isOpen());
+ }
+
+ private void assertSocketAction_Block_AfterConnect(Socket s)
+ throws IOException {
+ assertEquals(s.getPort(), localAddr1.getPort());
+ assertTrue(this.channel1.isConnected());
+ assertTrue(s.isConnected());
+ try {
+ s.connect(localAddr2);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+
+ try {
+ s.bind(localAddr2);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+
+ s.close();
+ assertTrue(s.isClosed());
+ assertFalse(this.channel1.isOpen());
+ }
+
+ private void assertSocketAction_NonBlock_AfterConnect(Socket s)
+ throws IOException {
+ assertEquals(s.getPort(), localAddr1.getPort());
+ assertTrue(this.channel1.isConnected());
+ assertTrue(s.isConnected());
+
+ if (this.channel1.isConnectionPending()) {
+ try {
+ s.connect(localAddr2);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ } else {
+ try {
+ s.connect(localAddr2);
+ fail("Should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e) {
+ // OK.
+ }
+ }
+
+ try {
+ s.bind(localAddr2);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+
+ s.close();
+ assertTrue(s.isClosed());
+ assertFalse(this.channel1.isOpen());
+ }
+
+ // -------------------------------------------------------------------
+ // Tests for connect(), finishConnect(),isConnected(),isConnectionPending()
+ // These methods are very close, so we test them together, call them "CFII".
+ // -------------------------------------------------------------------
+ /**
+ * connect-->finish-->close
+ */
+ public void testCFII_Norml_NoServer_Block() throws Exception {
+ // ensure
+ ensureServerClosed();
+ assertTrue(this.channel1.isBlocking());
+ statusNotConnected_NotPending();
+ // connect
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectException here.");
+ } catch (ConnectException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw a ClosedChannelException here.");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * connect-->finish-->close
+ */
+ public void testCFII_Norml_NoServer_NonBlock() throws Exception {
+ connectNoServerNonBlock();
+
+ this.channel1.close();
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->finish-->close
+ */
+ public void testCFII_Norml_Server_Block() throws Exception {
+ connectServerBlock();
+
+ this.channel1.close();
+ statusChannelClosed();
+
+ }
+
+ /**
+ * connect-->finish-->close
+ */
+ public void testCFII_Norml_Server_NonBlock() throws Exception {
+ connectServerNonBlock();
+
+ this.channel1.close();
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->server closed-->finish-->close
+ */
+ public void testCFII_ServerClosed_Block() throws Exception {
+ // ensure
+ ensureServerOpen();
+ assertTrue(this.channel1.isBlocking());
+ statusNotConnected_NotPending();
+ // connect
+ assertTrue(this.channel1.connect(localAddr1));
+ statusConnected_NotPending();
+
+ ensureServerClosed();
+
+ tryFinish();
+
+ this.channel1.close();
+ statusChannelClosed();
+
+ }
+
+ /**
+ * connect-->server closed-->finish-->close
+ */
+ public void testCFII_ServerClosed_NonBlock() throws Exception {
+ // ensure
+ ensureServerOpen();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // connect
+ boolean connected = channel1.connect(localAddr1);
+ if (!connected) {
+ statusNotConnected_Pending();
+ }
+ ensureServerClosed();
+
+ tryFinish();
+
+ this.channel1.close();
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->finish-->server closed-->close
+ */
+ public void testCFII_ServerClosedAfterFinish_Block() throws Exception {
+ connectServerBlock();
+
+ ensureServerClosed();
+ assertTrue(this.channel1.isOpen());
+ this.channel1.close();
+ statusChannelClosed();
+
+ }
+
+ /**
+ * connect-->finish-->server closed-->close
+ */
+ public void testCFII_ServerClosedAfterFinish_NonBlock() throws Exception {
+ connectServerNonBlock();
+
+ ensureServerClosed();
+ assertTrue(this.channel1.isOpen());
+ this.channel1.close();
+ statusChannelClosed();
+ }
+
+ /**
+ * no server-->connect-->server open-->finish-->close
+ */
+ public void testCFII_ServerStartLater_Block() throws Exception {
+ // ensure
+ ensureServerClosed();
+ assertTrue(this.channel1.isBlocking());
+ statusNotConnected_NotPending();
+ // connect
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectException here.");
+ } catch (ConnectException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ ensureServerOpen();
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw a ClosedChannelException here.");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ }
+
+ /**
+ * no server-->connect-->server open-->finish-->close
+ */
+ public void testCFII_ServerStartLater_NonBlock() throws Exception {
+ // ensure
+ ensureServerClosed();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // connect
+ assertFalse(this.channel1.connect(localAddr1));
+ statusNotConnected_Pending();
+
+ ensureServerOpen();
+
+ try {
+ assertFalse(this.channel1.finishConnect());
+ statusNotConnected_Pending();
+ this.channel1.close();
+ } catch (ConnectException e) {
+ // FIXME: assertEquals(e.getMessage(), "Connection refused");
+ }
+ }
+
+ /**
+ * connect-->finish-->finish-->close
+ */
+ public void testCFII_FinishTwice_NoServer_NonBlock() throws Exception {
+ // ensure
+ ensureServerClosed();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // connect
+ assertFalse(this.channel1.connect(localAddr1));
+ statusNotConnected_Pending();
+ try {
+ assertFalse(this.channel1.finishConnect());
+ statusNotConnected_Pending();
+ assertFalse(this.channel1.finishConnect());
+ statusNotConnected_Pending();
+ this.channel1.close();
+ } catch (ConnectException e) {
+ // FIXME: assertEquals(e.getMessage(), "Connection refused");
+ }
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->finish-->finish-->close
+ */
+ public void testCFII_FinishTwice_Server_Block() throws Exception {
+ connectServerBlock();
+ tryFinish();
+ this.channel1.close();
+ statusChannelClosed();
+
+ }
+
+ /**
+ * connect-->finish-->finish-->close
+ */
+ public void testCFII_FinishTwice_Server_NonBlock() throws Exception {
+ connectServerNonBlock();
+ tryFinish();
+ this.channel1.close();
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->finish-->connect-->close
+ */
+ public void testCFII_ConnectAfterFinish_NoServer_Block() throws Exception {
+ // ensure
+ ensureServerClosed();
+ assertTrue(this.channel1.isBlocking());
+ statusNotConnected_NotPending();
+ // connect
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectException here.");
+ } catch (ConnectException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw a ClosedChannelException here.");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ClosedChannelException here.");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->finish-->connect-->close
+ */
+ public void testCFII_ConnectAfterFinish_NoServer_NonBlock()
+ throws Exception {
+ // ensure
+ ensureServerClosed();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // connect
+ assertFalse(this.channel1.connect(localAddr1));
+ statusNotConnected_Pending();
+ try {
+ assertFalse(this.channel1.finishConnect());
+ statusNotConnected_Pending();
+ } catch (ConnectException e) {
+ // FIXME: assertEquals(e.getMessage(), "Connection refused");
+ }
+
+ if (this.channel1.isOpen()) {
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+
+ // connect another addr
+ try {
+ this.channel1.connect(localAddr2);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+
+ // connect if server closed
+ ensureServerClosed();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+
+ this.channel1.close();
+ }
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->finish-->connect-->close
+ */
+ public void testCFII_ConnectAfterFinish_Server_Block() throws Exception {
+ connectServerBlock();
+
+ if (!this.channel1.isConnected()) {
+ System.err
+ .println("Connection fail, testCFII_ConnectAfterFinish_Server_Block is not finished.");
+ return;
+ }
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw an AlreadyConnectedException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ statusConnected_NotPending();
+
+ // connect another addr
+ try {
+ this.channel1.connect(localAddr2);
+ fail("Should throw an AlreadyConnectedException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ statusConnected_NotPending();
+
+ // connect if server closed
+ ensureServerClosed();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw an AlreadyConnectedException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ statusConnected_NotPending();
+
+ this.channel1.close();
+ statusChannelClosed();
+
+ }
+
+ /**
+ * connect-->finish-->connect-->close
+ */
+ public void testCFII_ConnectAfterFinish_Server_NonBlock() throws Exception {
+ connectServerNonBlock();
+
+ if (!this.channel1.isConnected()) {
+ System.err
+ .println("Connection fail, testCFII_ConnectAfterFinish_Server_Block is not finished.");
+ return;
+ }
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw an AlreadyConnectedException or a ConnectionPendingException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+
+ statusConnected_NotPending();
+
+ // connect another addr
+ try {
+ this.channel1.connect(localAddr2);
+ fail("Should throw an AlreadyConnectedException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ statusConnected_NotPending();
+
+ // connect if server closed
+ ensureServerClosed();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw an AlreadyConnectedException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ statusConnected_NotPending();
+
+ this.channel1.close();
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->connect-->finish-->close
+ */
+ public void testCFII_ConnectTwice_NoServer_NonBlock() throws Exception {
+ // ensure
+ ensureServerClosed();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // connect
+ assertFalse(this.channel1.connect(localAddr1));
+ statusNotConnected_Pending();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+
+ // connect another addr
+ try {
+ this.channel1.connect(localAddr2);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+
+ // connect if server closed
+ ensureServerClosed();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+
+ try {
+ assertFalse(this.channel1.finishConnect());
+ statusNotConnected_Pending();
+ this.channel1.close();
+ } catch (ConnectException e) {
+ // FIXME: assertEquals(e.getMessage(), "Connection refused");
+ }
+
+ statusChannelClosed();
+ }
+
+ /**
+ * connect-->connect-->finish-->close
+ */
+ public void testCFII_ConnectTwice_Server_Block() throws Exception {
+ // ensure
+ ensureServerOpen();
+ assertTrue(this.channel1.isBlocking());
+ statusNotConnected_NotPending();
+ // connect
+ assertTrue(this.channel1.connect(localAddr1));
+ statusConnected_NotPending();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw an AlreadyConnectedException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ statusConnected_NotPending();
+
+ // connect another addr
+ try {
+ this.channel1.connect(localAddr2);
+ fail("Should throw an AlreadyConnectedException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ statusConnected_NotPending();
+
+ // connect if server closed
+ ensureServerClosed();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw an AlreadyConnectedException here.");
+ } catch (AlreadyConnectedException e) {
+ // OK.
+ }
+ statusConnected_NotPending();
+
+ tryFinish();
+
+ this.channel1.close();
+ statusChannelClosed();
+
+ }
+
+ /**
+ * connect-->connect-->finish-->close
+ */
+ public void testCFII_ConnectTwice_Server_NonBlock() throws Exception {
+ // ensure
+ ensureServerOpen();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // connect
+ boolean connected = channel1.connect(localAddr1);
+ if (!connected) {
+ statusNotConnected_Pending();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+
+ // connect another addr
+ try {
+ this.channel1.connect(localAddr2);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+
+ // connect if server closed
+ ensureServerClosed();
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectionPendingException here.");
+ } catch (ConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_Pending();
+ }
+ tryFinish();
+
+ this.channel1.close();
+ statusChannelClosed();
+ }
+
+ /**
+ * finish-->connect-->finish-->close
+ */
+ public void testCFII_FinishFirst_NoServer_Block() throws Exception {
+ // ensure
+ ensureServerClosed();
+ assertTrue(this.channel1.isBlocking());
+ statusNotConnected_NotPending();
+ // finish
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw NoConnectionPendingException");
+ } catch (NoConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_NotPending();
+ // connect
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw a ConnectException here.");
+ } catch (ConnectException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw a ClosedChannelException here.");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ }
+
+ /**
+ * finish-->connect-->finish-->close
+ */
+ public void testCFII_FinishFirst_NoServer_NonBlock() throws Exception {
+ // ensure
+ ensureServerClosed();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // finish
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw NoConnectionPendingException");
+ } catch (NoConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_NotPending();
+ // connect
+ assertFalse(this.channel1.connect(localAddr1));
+ statusNotConnected_Pending();
+
+ try {
+ assertFalse(this.channel1.finishConnect());
+ statusNotConnected_Pending();
+ this.channel1.close();
+ } catch (ConnectException e) {
+ // FIXME: assertEquals(e.getMessage(), "Connection refused");
+ }
+
+ statusChannelClosed();
+ }
+
+ /**
+ * finish-->connect-->finish-->close
+ */
+ public void testCFII_FinishFirst_Server_Block() throws Exception {
+ // ensure
+ ensureServerOpen();
+ assertTrue(this.channel1.isBlocking());
+ statusNotConnected_NotPending();
+ // finish
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw NoConnectionPendingException");
+ } catch (NoConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_NotPending();
+ // connect
+ assertTrue(this.channel1.connect(localAddr1));
+ statusConnected_NotPending();
+
+ tryFinish();
+
+ this.channel1.close();
+ statusChannelClosed();
+
+ }
+
+ /**
+ * finish-->connect-->finish-->close
+ */
+ public void testCFII_FinishFirst_Server_NonBlock() throws Exception {
+ // ensure
+ ensureServerOpen();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // finish
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw NoConnectionPendingException");
+ } catch (NoConnectionPendingException e) {
+ // OK.
+ }
+ statusNotConnected_NotPending();
+ // connect
+ boolean connected = channel1.connect(localAddr1);
+ if (!connected) {
+ statusNotConnected_Pending();
+ }
+ tryFinish();
+
+ this.channel1.close();
+ statusChannelClosed();
+ }
+
+ public void testCFII_Null() throws Exception {
+ statusNotConnected_NotPending();
+ try {
+ this.channel1.connect(null);
+ fail("Should throw an IllegalArgumentException here.");
+ } catch (IllegalArgumentException e) {
+ // OK.
+ }
+ }
+
+ public void testCFII_UnsupportedType() throws Exception {
+ class SubSocketAddress extends SocketAddress {
+ private static final long serialVersionUID = 1L;
+
+ //empty
+ public SubSocketAddress() {
+ super();
+ }
+ }
+ statusNotConnected_NotPending();
+ SocketAddress newTypeAddress = new SubSocketAddress();
+ try {
+ this.channel1.connect(newTypeAddress);
+ fail("Should throw an UnsupportedAddressTypeException here.");
+ } catch (UnsupportedAddressTypeException e) {
+ // OK.
+ }
+ }
+
+ public void testCFII_Unresolved() throws IOException {
+ statusNotConnected_NotPending();
+ InetSocketAddress unresolved = new InetSocketAddress(
+ "unresolved address", 1080);
+ try {
+ this.channel1.connect(unresolved);
+ fail("Should throw an UnresolvedAddressException here.");
+ } catch (UnresolvedAddressException e) {
+ // OK.
+ }
+ }
+
+ public void testCFII_EmptyHost() throws Exception {
+ statusNotConnected_NotPending();
+ ServerSocket server = new ServerSocket(0);
+ int port = server.getLocalPort();
+ server.close();
+ try {
+ this.channel1.connect(new InetSocketAddress("", port));
+ fail("Should throw ConnectException");
+ } catch (ConnectException e) {
+ // correct
+ }
+ }
+
+ public void testCFII_CloseFirst() throws Exception {
+ this.channel1.close();
+ statusChannelClosed();
+ ensureServerOpen();
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ try {
+ this.channel1.configureBlocking(false);
+ fail("Should throw ClosedChannelException.");
+ } catch (ClosedChannelException e) {
+ // OK.
+ }
+ statusChannelClosed();
+ }
+
+ public void testCFII_StatusAfterFinish() throws Exception {
+ // 1. close server, finish must return false, check the status
+ ensureServerClosed();
+
+ // 1.1 block mode
+ assertTrue(this.channel1.isBlocking());
+ try {
+ channel1.connect(localAddr1);
+ fail("Should throw ConnectException");
+ } catch (ConnectException e) {
+ // OK.
+ }
+ assertFalse(this.channel1.isOpen());
+
+ assertFalse(this.channel1.isOpen());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnectionPending());
+
+ // 1.2 non block mode
+ this.channel1 = SocketChannel.open();
+ this.channel1.configureBlocking(false);
+ assertFalse(this.channel1.connect(localAddr1));
+ try {
+ assertFalse(this.channel1.finishConnect());
+ statusNotConnected_Pending();
+ this.channel1.close();
+ } catch (ConnectException e) {
+ System.out.println(e.getMessage());
+ }
+
+ // 2. start server, finish usually return true, check the status
+ ensureServerOpen();
+
+ // 2.1 block mode
+ this.channel1 = SocketChannel.open();
+ assertTrue(this.channel1.isBlocking());
+ assertTrue(this.channel1.connect(localAddr1));
+ assertTrue(this.channel1.finishConnect());
+ statusConnected_NotPending();
+ this.channel1.close();
+
+ // 2.2 non block mode
+ this.channel1 = SocketChannel.open();
+ this.channel1.configureBlocking(false);
+ assertFalse(this.channel1.connect(localAddr1));
+ tryFinish();
+ this.channel1.close();
+ }
+
+ private void ensureServerClosed() throws IOException {
+ if (null != this.server1) {
+ this.server1.close();
+ assertTrue(this.server1.isClosed());
+ }
+ if (null != this.server2) {
+ this.server2.close();
+ assertTrue(this.server2.isClosed());
+ }
+ }
+
+ private void ensureServerOpen() throws IOException {
+ ensureServerClosed();
+ this.server1 = new ServerSocket(0);
+ this.localAddr1 = new InetSocketAddress("127.0.0.1", server1.getLocalPort());
+ this.server2 = new ServerSocket(0);
+ this.localAddr2 = new InetSocketAddress("127.0.0.1", server2.getLocalPort());
+ assertTrue(this.server1.isBound());
+ assertTrue(this.server2.isBound());
+ }
+
+ private void connectNoServerNonBlock() throws Exception {
+ // ensure
+ ensureServerClosed();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // connect
+ assertFalse(this.channel1.connect(localAddr1));
+ statusNotConnected_Pending();
+ try {
+ assertFalse(this.channel1.finishConnect());
+ statusNotConnected_Pending();
+ } catch (ConnectException e) {
+ // FIXME: assertEquals(e.getMessage(), "Connection refused");
+ }
+ }
+
+ private void connectServerNonBlock() throws Exception {
+ // ensure
+ ensureServerOpen();
+ this.channel1.configureBlocking(false);
+ statusNotConnected_NotPending();
+ // connect
+ boolean connected = channel1.connect(localAddr1);
+ if (!connected) {
+ statusNotConnected_Pending();
+ }
+ tryFinish();
+ }
+
+ private void connectServerBlock() throws Exception {
+ // ensure
+ ensureServerOpen();
+ assertTrue(this.channel1.isBlocking());
+ statusNotConnected_NotPending();
+ // connect
+ assertTrue(this.channel1.connect(localAddr1));
+ statusConnected_NotPending();
+ tryFinish();
+ }
+
+ private void statusChannelClosed() {
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertFalse(this.channel1.isOpen());
+ }
+
+ private void statusNotConnected_NotPending() {
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ }
+
+ private void statusNotConnected_Pending() {
+ assertFalse(this.channel1.isConnected());
+ assertTrue(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ }
+
+ private void statusConnected_NotPending() {
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ }
+
+ private boolean tryFinish() throws IOException {
+ /*
+ * the result of finish will be asserted in multi-thread tests.
+ */
+ boolean connected = false;
+ assertTrue(this.channel1.isOpen());
+ try {
+ connected = this.channel1.finishConnect();
+ } catch (SocketException e) {
+ // Finish connection failed, probably due to reset by peer error.
+ }
+ if (connected) {
+ statusConnected_NotPending();
+ }
+ return connected;
+ }
+
+ // -------------------------------------------------------------------
+ // Original tests. Test method for CFII with real data.
+ // -------------------------------------------------------------------
+
+ /**
+ *
+ * 'SocketChannelImpl.connect(SocketAddress)'
+ */
+ public void testCFII_Data_ConnectWithServer() throws Exception {
+ ensureServerOpen();
+ java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
+ .allocate(CAPACITY_NORMAL);
+ java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
+ writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+
+ this.channel1.connect(localAddr1);
+
+ assertTrue(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1));
+
+ this.channel1.configureBlocking(false);
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // correct
+ }
+
+ assertFalse(this.channel1.isRegistered());
+ tryFinish();
+ }
+
+ /*
+ * Test method for 'SocketChannelImpl.connect(SocketAddress)'
+ */
+ public void testCFII_Data_ConnectWithServer_nonBlocking() throws Exception {
+ ensureServerOpen();
+ java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
+ .allocate(CAPACITY_NORMAL);
+ java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
+ writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ this.channel1.configureBlocking(false);
+ this.channel1.connect(localAddr1);
+
+ assertFalse(this.channel1.isBlocking());
+ boolean connected = channel1.isConnected();
+ if (!connected) {
+ assertTrue(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ }
+ if (tryFinish()) {
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1));
+
+ this.channel1.configureBlocking(false);
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // correct
+ }
+ }
+
+ assertFalse(this.channel1.isRegistered());
+ tryFinish();
+ }
+
+ /*
+ * Test method for 'SocketChannelImpl.finishConnect()'
+ */
+ public void testCFII_Data_FinishConnect_nonBlocking() throws IOException {
+ ensureServerOpen();
+
+ java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
+ .allocate(CAPACITY_NORMAL);
+ java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
+ writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+
+ this.channel1.configureBlocking(false);
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw NoConnectionPendingException");
+ } catch (NoConnectionPendingException e) {
+ // correct
+ }
+ boolean connected = channel1.connect(localAddr1);
+ if (!connected) {
+ assertFalse(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertTrue(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ }
+ this.server1.accept();
+ if (tryFinish()) {
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1));
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // correct
+ }
+ }
+ assertFalse(this.channel1.isRegistered());
+ tryFinish();
+ }
+
+ public void testCFII_Data_FinishConnect_AddrSetServerStartLater()
+ throws IOException, InterruptedException {
+ ensureServerClosed();
+ this.channel1.configureBlocking(false);
+ try {
+ SocketChannel.open(localAddr1);
+ fail("Should throw ConnectException");
+ } catch (ConnectException e) {
+ // correct
+ }
+ assertTrue(this.channel1.isOpen());
+ assertFalse(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnectionPending());
+ this.channel1.configureBlocking(true);
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw NoConnectionPendingException");
+ } catch (NoConnectionPendingException e) {
+ // correct
+ }
+ try {
+ this.channel1.connect(localAddr2);
+ fail("Should throw ConnectException");
+ } catch (ConnectException e) {
+ // correct
+ }
+
+ assertTrue(this.channel1.isBlocking());
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ assertFalse(this.channel1.isConnected());
+ // finish after finish OK
+ assertFalse(this.channel1.isConnectionPending());
+ this.channel1 = SocketChannel.open();
+ this.channel1.configureBlocking(false);
+ this.channel1.connect(localAddr1);
+ assertFalse(this.channel1.isConnected());
+ ensureServerOpen();
+ // cannot connect?
+ try {
+ assertFalse(this.channel1.finishConnect());
+ assertFalse(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertTrue(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw ConnectionPendingException");
+ } catch (ConnectionPendingException e) {
+ // correct
+ }
+ this.channel1.configureBlocking(true);
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw ConnectionPendingException");
+ } catch (ConnectionPendingException e) {
+ // correct
+ }
+ tryFinish();
+ } catch (ConnectException e) {
+ // FIXME: assertEquals(e.getMessage(), "Connection refused");
+ }
+ }
+
+ public void testCFII_Data_FinishConnect_ServerStartLater()
+ throws IOException {
+ ensureServerClosed();
+ this.channel1.configureBlocking(true);
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw NoConnectionPendingException");
+ } catch (NoConnectionPendingException e) {
+ // correct
+ }
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw ConnectException");
+ } catch (ConnectException e) {
+ // correct
+ }
+
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ assertFalse(this.channel1.isConnected());
+ // finish after finish OK
+ assertFalse(this.channel1.isConnectionPending());
+ this.channel1 = SocketChannel.open();
+ this.channel1.configureBlocking(false);
+ this.channel1.connect(localAddr1);
+ assertFalse(this.channel1.isConnected());
+ ensureServerOpen();
+ // cannot connect?
+ try {
+ assertFalse(this.channel1.finishConnect());
+ assertFalse(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertTrue(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw ConnectionPendingException");
+ } catch (ConnectionPendingException e) {
+ // correct
+ }
+ this.channel1.configureBlocking(true);
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw ConnectionPendingException");
+ } catch (ConnectionPendingException e) {
+ // correct
+ }
+ tryFinish();
+ } catch (ConnectException e) {
+ // FIXME: assertEquals(e.getMessage(), "Connection refused");
+ }
+ }
+
+ public void testCFII_Data_FinishConnect_Blocking() throws IOException {
+ ensureServerOpen();
+ java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
+ .allocate(CAPACITY_NORMAL);
+ java.nio.ByteBuffer[] writeBufArr = new java.nio.ByteBuffer[1];
+ writeBufArr[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+ this.channel1.configureBlocking(true);
+ try {
+ this.channel1.finishConnect();
+ fail("Should throw NoConnectionPendingException");
+ } catch (NoConnectionPendingException e) {
+ // correct
+ }
+
+ this.channel1.connect(localAddr1);
+
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ if (tryFinish()) {
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBufArr, 0, 1));
+
+ try {
+ this.channel1.connect(localAddr1);
+ fail("Should throw AlreadyConnectedException");
+ } catch (AlreadyConnectedException e) {
+ // correct
+ }
+ }
+ assertFalse(this.channel1.isRegistered());
+ tryFinish();
+ }
+
+ /**
+ * Regression test for Harmony-1947.
+ */
+ public void test_finishConnect() throws Exception {
+ SocketAddress address = new InetSocketAddress("localhost", 0);
+
+ ServerSocketChannel theServerChannel = ServerSocketChannel.open();
+ ServerSocket serversocket = theServerChannel.socket();
+ serversocket.setReuseAddress(true);
+ // Bind the socket
+ theServerChannel.socket().bind(address);
+
+ boolean doneNonBlockingConnect = false;
+ // Loop so that we make sure we're definitely testing finishConnect()
+ while (!doneNonBlockingConnect) {
+ channel1 = SocketChannel.open();
+
+ // Set the SocketChannel to non-blocking so that connect(..) does
+ // not block
+ channel1.configureBlocking(false);
+ boolean connected = channel1.connect(new InetSocketAddress("localhost",serversocket.getLocalPort()));
+ if (!connected) {
+ // Now set the SocketChannel back to blocking so that
+ // finishConnect() blocks.
+ channel1.configureBlocking(true);
+ doneNonBlockingConnect = channel1.finishConnect();
+ }
+ if (doneNonBlockingConnect) {
+ tryFinish();
+ }
+ channel1.close();
+ }
+ if (!serversocket.isClosed()) {
+ serversocket.close();
+ }
+ }
+
+ // -------------------------------------------------------------------
+ // End of original tests. Test method for CFII with real data.
+ // -------------------------------------------------------------------
+
+ /**
+ * @tests java.nio.channels.SocketChannel#read(ByteBuffer)
+ */
+ public void test_readLjava_nio_ByteBuffer_Blocking() throws IOException {
+ // initialize write content
+ byte[] writeContent = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < writeContent.length; i++) {
+ writeContent[i] = (byte) i;
+ }
+ // establish connection
+ channel1.connect(localAddr1);
+ Socket acceptedSocket = server1.accept();
+
+ // use OutputStream.write to send CAPACITY_NORMAL bytes data
+ OutputStream out = acceptedSocket.getOutputStream();
+ out.write(writeContent);
+ // use close to guarantee all data is sent
+ acceptedSocket.close();
+
+ ByteBuffer readContent = ByteBuffer.allocate(CAPACITY_NORMAL + 1);
+ int totalCount = 0;
+ int count;
+ long startTime = System.currentTimeMillis();
+ // use SocketChannel.read to read data
+ while (totalCount <= CAPACITY_NORMAL) {
+ count = channel1.read(readContent);
+ if (EOF == count) {
+ break;
+ }
+ totalCount += count;
+ // if the channel could not finish reading in TIMEOUT ms, the
+ // test fails. It is used to guarantee the test never hangs even
+ // if there are bugs of SocketChannel implementation. For
+ // blocking read, it possibly returns 0 in some cases.
+ assertTimeout(startTime, TIMEOUT);
+ }
+ assertEquals(CAPACITY_NORMAL, totalCount);
+ readContent.flip();
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ assertEquals(writeContent[i], readContent.get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#read(ByteBuffer)
+ */
+ public void test_readLjava_nio_ByteBuffer_Nonblocking() throws IOException {
+ // initialize write content
+ byte[] writeContent = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < writeContent.length; i++) {
+ writeContent[i] = (byte) i;
+ }
+
+ // establish connection
+ channel1.connect(localAddr1);
+ Socket acceptedSocket = server1.accept();
+ // use OutputStream.write to write CAPACITY_NORMAL bytes data.
+ OutputStream out = acceptedSocket.getOutputStream();
+ out.write(writeContent);
+ // use close to guarantee all data is sent
+ acceptedSocket.close();
+
+ channel1.configureBlocking(false);
+ ByteBuffer readContent = ByteBuffer.allocate(CAPACITY_NORMAL + 1);
+ int totalCount = 0;
+ int count;
+ long startTime = System.currentTimeMillis();
+ // use SocketChannel.read to read data
+ while (totalCount <= CAPACITY_NORMAL) {
+ count = channel1.read(readContent);
+ if (EOF == count) {
+ break;
+ }
+ totalCount += count;
+ // if the channel could not finish reading in TIMEOUT ms, the
+ // test fails. It is used to guarantee the test never hangs even
+ // if there are bugs of SocketChannel implementation.
+ assertTimeout(startTime, TIMEOUT);
+ }
+
+ // assert read content
+ assertEquals(CAPACITY_NORMAL, totalCount);
+ assertEquals(CAPACITY_NORMAL, readContent.position());
+ readContent.flip();
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ assertEquals(writeContent[i], readContent.get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer)
+ */
+ public void test_writeLjava_nio_ByteBuffer_Blocking() throws IOException {
+ // initialize write content
+ ByteBuffer writeContent = ByteBuffer.allocate(CAPACITY_NORMAL);
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ writeContent.put((byte) i);
+ }
+ writeContent.flip();
+ // establish connection
+ channel1.connect(localAddr1);
+ Socket acceptedSocket = server1.accept();
+
+ // use SocketChannel.write(ByteBuffer) to write CAPACITY_NORMAL bytes
+ // data
+ int writtenCount = channel1.write(writeContent);
+ // assert written count and ByteBuffer position
+ assertEquals(CAPACITY_NORMAL, writtenCount);
+ assertEquals(CAPACITY_NORMAL, writeContent.position());
+ // use close to guarantee all data is sent
+ channel1.close();
+
+ InputStream in = acceptedSocket.getInputStream();
+ int totalCount = 0;
+ int count = 0;
+ byte[] readContent = new byte[CAPACITY_NORMAL + 1];
+ // if the channel could not finish reading in TIMEOUT ms, the test
+ // fails. It is used to guarantee the test never hangs even if there
+ // are bugs of SocketChannel implementation.
+ acceptedSocket.setSoTimeout(TIMEOUT);
+
+ // use InputStream.read to read data.
+ while (totalCount <= CAPACITY_NORMAL) {
+ count = in.read(readContent, totalCount, readContent.length
+ - totalCount);
+ if (EOF == count) {
+ break;
+ }
+ totalCount += count;
+ }
+
+ // assert read content
+ assertEquals(CAPACITY_NORMAL, totalCount);
+ writeContent.flip();
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ assertEquals(writeContent.get(), readContent[i]);
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer)
+ */
+ public void test_writeLjava_nio_ByteBuffer_NonBlocking() throws Exception {
+ // initialize write content
+ ByteBuffer writeContent = ByteBuffer.allocate(CAPACITY_NORMAL);
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ writeContent.put((byte) i);
+ }
+ writeContent.flip();
+
+ // establish connection
+ channel1.connect(localAddr1);
+ Socket acceptedSocket = server1.accept();
+
+ channel1.configureBlocking(false);
+ int writtenTotalCount = 0;
+ int writtenCount = 0;
+ long startTime = System.currentTimeMillis();
+ // use SocketChannel.write(ByteBuffer) to write CAPACITY_NORMAL bytes
+ while (writtenTotalCount < CAPACITY_NORMAL) {
+ writtenCount = channel1.write(writeContent);
+ writtenTotalCount += writtenCount;
+ // if the channel could not finish writing in TIMEOUT ms, the
+ // test fails. It is used to guarantee the test never hangs even
+ // if there are bugs of SocketChannel implementation.
+ assertTimeout(startTime, TIMEOUT);
+ }
+ // assert written count and ByteBuffer position
+ assertEquals(CAPACITY_NORMAL, writtenTotalCount);
+ assertEquals(CAPACITY_NORMAL, writeContent.position());
+ // use close to guarantee all data is sent
+ channel1.close();
+
+ InputStream in = acceptedSocket.getInputStream();
+ byte[] readContent = new byte[CAPACITY_NORMAL + 1];
+ int totalCount = 0;
+ int count = 0;
+ // if the channel could not finish reading in TIMEOUT ms, the test
+ // fails. It is used to guarantee the test never hangs even if there
+ // are bugs of SocketChannel implementation.
+ acceptedSocket.setSoTimeout(TIMEOUT);
+ // use InputStream.read to read data.
+ while (totalCount <= CAPACITY_NORMAL) {
+ count = in.read(readContent, totalCount, readContent.length
+ - totalCount);
+ if (EOF == count) {
+ break;
+ }
+ totalCount += count;
+ }
+ // assert read content
+ assertEquals(CAPACITY_NORMAL, totalCount);
+ writeContent.flip();
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ assertEquals(writeContent.get(), readContent[i]);
+ }
+ }
+
+ /*
+ * Fails if the difference between current time and start time is greater
+ * than timeout.
+ */
+ private void assertTimeout(long startTime, long timeout) {
+ long currentTime = System.currentTimeMillis();
+ if ((currentTime - startTime) > timeout) {
+ fail("Timeout");
+ }
+ }
+
+ // -------------------------------------------------
+ // Test for read/write but no real data expressed
+ // -------------------------------------------------
+
+ public void testReadByteBuffer() throws Exception {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer readBuf = java.nio.ByteBuffer
+ .allocate(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ // note: blocking-mode will make the read process endless!
+ this.channel1.configureBlocking(false);
+ try {
+ channel1.read(readBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ boolean connected = this.channel1.connect(localAddr1);
+ if (!connected) {
+ assertFalse(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnectionPending());
+ assertFalse(this.channel1.isConnected());
+ }
+ if (tryFinish()) {
+ assertEquals(0, this.channel1.read(readBuf));
+ }
+
+ this.channel1.close();
+ try {
+ channel1.read(readBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testReadByteBuffer_Direct() throws Exception {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer readBuf = java.nio.ByteBuffer
+ .allocateDirect(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ // note: blocking-mode will make the read process endless!
+ this.channel1.configureBlocking(false);
+ try {
+ channel1.read(readBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ boolean connected = this.channel1.connect(localAddr1);
+ if (!connected) {
+ assertFalse(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnectionPending());
+ assertFalse(this.channel1.isConnected());
+ }
+ if (tryFinish()) {
+ assertEquals(0, this.channel1.read(readBuf));
+ }
+
+ this.channel1.close();
+ try {
+ channel1.read(readBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testReadByteBuffer_Direct2() throws IOException {
+ byte[] request = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ ByteBuffer buffer = ByteBuffer.allocateDirect(128);
+
+ ServerSocketChannel server = ServerSocketChannel.open();
+ server.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), 0), 5);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.socket()
+ .getLocalPort());
+ client.setTcpNoDelay(false);
+ Socket worker = server.socket().accept();
+ SocketChannel workerChannel = worker.getChannel();
+
+ OutputStream out = client.getOutputStream();
+ out.write(request);
+ out.close();
+
+ buffer.limit(5);
+ int bytesRead = workerChannel.read(buffer);
+ assertEquals(5, bytesRead);
+ assertEquals(5, buffer.position());
+
+ buffer.limit(request.length);
+ bytesRead = workerChannel.read(buffer);
+ assertEquals(6, bytesRead);
+
+ buffer.flip();
+ assertEquals(request.length, buffer.limit());
+
+ assertEquals(ByteBuffer.wrap(request), buffer);
+
+ client.close();
+ worker.close();
+ server.close();
+ }
+
+ public void testReadByteBuffer_BufNull() throws Exception {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer readBuf = java.nio.ByteBuffer.allocate(0);
+ // note: blocking-mode will make the read process endless!
+ this.channel1.configureBlocking(false);
+ try {
+ channel1.read((java.nio.ByteBuffer) null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ if (tryFinish()) {
+ try {
+ this.channel1.read((java.nio.ByteBuffer) null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertEquals(0, this.channel1.read(readBuf));
+ }
+ this.server1.close();
+ try {
+ channel1.read((java.nio.ByteBuffer) null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ /*
+ * SocketChannelImpl.read(ByteBuffer[], int, int)'
+ */
+ public void testReadByteBufferArrayIntInt() throws Exception {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer[] readBuf = new java.nio.ByteBuffer[2];
+ readBuf[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+ readBuf[1] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ // note: blocking-mode will make the read process endless!
+ this.channel1.configureBlocking(false);
+ try {
+ channel1.read(readBuf, 0, 1);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ boolean connected = this.channel1.connect(localAddr1);
+ if (!connected) {
+ assertFalse(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnectionPending());
+ assertFalse(this.channel1.isConnected());
+ }
+ if (tryFinish()) {
+ assertEquals(0, this.channel1.read(readBuf, 0, 1));
+ assertEquals(0, this.channel1.read(readBuf, 0, 2));
+ }
+
+ this.channel1.close();
+ try {
+ channel1.read(readBuf, 0, 1);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ /*
+ * SocketChannelImpl.read(ByteBuffer[], int, int)'
+ */
+ public void testReadByteBufferArrayIntInt_Direct() throws Exception {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer[] readBuf = new java.nio.ByteBuffer[2];
+ readBuf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ readBuf[1] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ // note: blocking-mode will make the read process endless!
+ this.channel1.configureBlocking(false);
+ try {
+ channel1.read(readBuf, 0, 1);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ boolean connected = this.channel1.connect(localAddr1);
+ if (!connected) {
+ assertFalse(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnectionPending());
+ assertFalse(this.channel1.isConnected());
+ }
+ if (tryFinish()) {
+ assertEquals(0, this.channel1.read(readBuf, 0, 1));
+ assertEquals(0, this.channel1.read(readBuf, 0, 2));
+ }
+
+ this.channel1.close();
+ try {
+ channel1.read(readBuf, 0, 1);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testReadByteBufferArrayIntInt_BufNull() throws Exception {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer[] readBuf = new java.nio.ByteBuffer[2];
+ readBuf[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ // note: blocking-mode will make the read process endless!
+ this.channel1.configureBlocking(false);
+ try {
+ channel1.read(null, 0, 1);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ if (tryFinish()) {
+
+ try {
+ channel1.read(null, 0, 1);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ channel1.read(readBuf, 0, 2);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+
+ assertEquals(0, this.channel1.read(readBuf, 0, 1));
+ }
+ this.channel1.close();
+ try {
+ channel1.read(null, 0, 1);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBuffer() throws IOException {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
+ .allocate(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ assertTrue(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
+
+ this.channel1.close();
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBuffer_Direct() throws IOException {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
+ .allocateDirect(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ assertTrue(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
+
+ this.channel1.close();
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBuffer_BufNull() throws IOException {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer.allocate(0);
+ this.channel1.connect(localAddr1);
+ assertEquals(this.channel1.write(writeBuf), 0);
+ try {
+ this.channel1.write((java.nio.ByteBuffer) null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ /*
+ * SocketChannelImpl.write(ByteBuffer[], int, int)'
+ */
+ public void testWriteByteBufferArrayIntInt() throws IOException {
+ java.nio.ByteBuffer[] writeBuf = new java.nio.ByteBuffer[2];
+ writeBuf[0] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+ writeBuf[1] = java.nio.ByteBuffer.allocate(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ try {
+ channel1.write(writeBuf, 0, 1);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ assertTrue(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 1));
+ // still writes the same size as above
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 2));
+ writeBuf[0].flip();
+ writeBuf[1].flip();
+ assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
+ this.channel1.close();
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ /*
+ * SocketChannelImpl.write(ByteBuffer[], int, int)'
+ */
+ public void testWriteByteBufferArrayIntInt_Direct() throws IOException {
+ java.nio.ByteBuffer[] writeBuf = new java.nio.ByteBuffer[2];
+ writeBuf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ writeBuf[1] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ try {
+ channel1.write(writeBuf, 0, 1);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ assertTrue(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 1));
+ // still writes the same size as above
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 2));
+ writeBuf[0].flip();
+ writeBuf[1].flip();
+ assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
+ this.channel1.close();
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBufferArrayIntInt_BufNull() throws IOException {
+ java.nio.ByteBuffer[] writeBuf = new java.nio.ByteBuffer[0];
+
+ this.channel1.connect(localAddr1);
+ try {
+ this.channel1.write(null, 0, 1);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ assertEquals(0, this.channel1.write(writeBuf, 0, 0));
+ try {
+ this.channel1.write(writeBuf, 0, 1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // correct
+ }
+ writeBuf = new java.nio.ByteBuffer[1];
+ try {
+ this.channel1.write(writeBuf, 0, 1);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ try {
+ this.channel1.write(writeBuf, 0, 2);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // correct
+ }
+ this.server1.close();
+ try {
+ channel1.read(null, 0, 1);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // correct
+ }
+ }
+
+ public void testWriteByteBufferArrayIntInt_SizeError() throws IOException {
+ java.nio.ByteBuffer[] buf = new java.nio.ByteBuffer[1];
+ this.channel1.connect(localAddr1);
+ assertEquals(0, this.channel1.write(buf, 0, 0));
+ try {
+ this.channel1.write(buf, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.write(buf, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.write(buf, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.write(buf, 2, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.write(null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ this.server1.close();
+ }
+
+ public void testReadByteBufferArrayIntInt_SizeError() throws IOException {
+ java.nio.ByteBuffer[] buf = new java.nio.ByteBuffer[1];
+ this.channel1.connect(localAddr1);
+ assertEquals(0, this.channel1.read(buf, 0, 0));
+ try {
+ this.channel1.read(buf, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.read(buf, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.read(buf, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.read(buf, 2, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ this.channel1.read(null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ this.server1.close();
+ }
+
+ /*
+ * ==========================================================================
+ * Tests for read/write real data
+ * ==========================================================================
+ */
+
+
+ /**
+ * @tests java.nio.channels.SocketChannel#read(ByteBuffer[])
+ */
+ public void test_read$LByteBuffer() throws IOException {
+ MockSocketChannel sc = new MockSocketChannel(null);
+ ByteBuffer [] byteBufferArray = { ByteBuffer.allocate(1), ByteBuffer.allocate(1)};
+ // Verify that calling read(ByteBuffer[]) leads to the method
+ // read(ByteBuffer[], int, int) being called with a 0 for the
+ // second parameter and targets.length as the third parameter.
+ sc.read(byteBufferArray);
+ assertTrue(sc.isReadCalled);
+ }
+ /**
+ * @tests java.nio.channels.SocketChannel#read(ByteBuffer[],int,int)
+ */
+ public void test_read$LByteBufferII_blocking() throws Exception {
+ assert_read$LByteBuffer(true);
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#read(ByteBuffer[],int,int)
+ */
+ public void test_read$LByteBufferII_nonblocking() throws Exception {
+ assert_read$LByteBuffer(false);
+ }
+
+ private void assert_read$LByteBuffer(boolean isBlocking) throws IOException {
+ // initialize write content
+ byte[] writeContent = new byte[CAPACITY_NORMAL * 2];
+ for (int i = 0; i < CAPACITY_NORMAL * 2; i++) {
+ writeContent[i] = (byte) i;
+ }
+ ByteBuffer[] readContents = new ByteBuffer[2];
+ readContents[0] = ByteBuffer.allocate(CAPACITY_NORMAL);
+ readContents[1] = ByteBuffer.allocate(CAPACITY_NORMAL + 1);
+ // establish connection
+ channel1.connect(localAddr1);
+ Socket acceptedSocket = server1.accept();
+ // use OutputStream.write to send CAPACITY_NORMAL * 2 bytes data
+ OutputStream out = acceptedSocket.getOutputStream();
+ out.write(writeContent);
+ // use close to guarantee all data is sent
+ acceptedSocket.close();
+ // configure block/nonblock mode
+ channel1.configureBlocking(isBlocking);
+ long startTime = System.currentTimeMillis();
+ long totalRead = 0;
+ long countRead;
+
+ while (totalRead <= CAPACITY_NORMAL * 2) {
+ countRead = channel1.read(readContents, 0, 2);
+ if (0 == countRead && !readContents[1].hasRemaining()) {
+ // read returns 0 because readContents is full
+ break;
+ }
+ if (EOF == countRead) {
+ break;
+ }
+ totalRead += countRead;
+ // if the channel could not finish reading in TIMEOUT ms, the
+ // test fails. It is used to guarantee the test never hangs even
+ // if there are bugs of SocketChannel implementation. For
+ // blocking read, it possibly returns 0 in some cases.
+ assertTimeout(startTime, TIMEOUT);
+ }
+
+ // assert total bytes read and the position of ByteBuffers
+ assertEquals(CAPACITY_NORMAL * 2, totalRead);
+ assertEquals(CAPACITY_NORMAL, readContents[0].position());
+ assertEquals(CAPACITY_NORMAL, readContents[1].position());
+ // assert read content
+ readContents[0].flip();
+ readContents[1].flip();
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ assertEquals(writeContent[i], readContents[0].get());
+ }
+ for (int i = CAPACITY_NORMAL; i < CAPACITY_NORMAL * 2; i++) {
+ assertEquals(writeContent[i], readContents[1].get());
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[],int,int)
+ */
+ public void test_write$LByteBufferII_blocking() throws Exception {
+ assert_write$LByteBuffer(true);
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[],int,int)
+ */
+ public void test_write$LByteBufferII_nonblocking()
+ throws Exception {
+ assert_write$LByteBuffer(false);
+ }
+
+ private void assert_write$LByteBuffer(boolean isBlocking)
+ throws IOException {
+ // initialize write contents
+ ByteBuffer writeContents[] = new ByteBuffer[2];
+ writeContents[0] = ByteBuffer.allocate(CAPACITY_NORMAL);
+ writeContents[1] = ByteBuffer.allocate(CAPACITY_NORMAL);
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ writeContents[0].put((byte) i);
+ }
+ for (int i = CAPACITY_NORMAL; i < CAPACITY_NORMAL * 2; i++) {
+ writeContents[1].put((byte) i);
+ }
+ writeContents[0].flip();
+ writeContents[1].flip();
+ // establish connection
+ channel1.connect(localAddr1);
+ Socket acceptedSocket = server1.accept();
+ // set blocking/nonblocking mode
+ channel1.configureBlocking(isBlocking);
+
+ assertEquals(CAPACITY_NORMAL, channel1.write(writeContents, 0, 1));
+ assertEquals(CAPACITY_NORMAL, channel1.write(writeContents, 1, 1));
+
+ // assert written count and ByteBuffer position
+ assertEquals(CAPACITY_NORMAL, writeContents[0].position());
+ assertEquals(CAPACITY_NORMAL, writeContents[1].position());
+ // use close to guarantee all data is sent
+ channel1.close();
+ InputStream in = acceptedSocket.getInputStream();
+ byte[] readContent = new byte[CAPACITY_NORMAL * 2 + 1];
+ int totalCount = 0;
+ int count;
+ // if the channel could not finish reading in TIMEOUT ms, the test
+ // fails. It is used to guarantee the test never hangs even if there
+ // are bugs of SocketChannel implementation.
+ acceptedSocket.setSoTimeout(TIMEOUT);
+ // use InputStream.read to read data.
+ while (totalCount <= CAPACITY_NORMAL) {
+ count = in.read(readContent, totalCount, readContent.length
+ - totalCount);
+ if (EOF == count) {
+ break;
+ }
+ totalCount += count;
+ }
+ // assert read content
+ assertEquals(CAPACITY_NORMAL * 2, totalCount);
+ writeContents[0].flip();
+ writeContents[1].flip();
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ assertEquals(writeContents[0].get(), readContent[i]);
+ }
+ for (int i = CAPACITY_NORMAL; i < CAPACITY_NORMAL * 2; i++) {
+ assertEquals(writeContents[1].get(), readContent[i]);
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ */
+ public void test_write$LByteBuffer() throws IOException {
+ MockSocketChannel sc = new MockSocketChannel(null);
+ ByteBuffer [] byteBufferArray = { ByteBuffer.allocate(1), ByteBuffer.allocate(1)};
+ // Verify that calling write(ByteBuffer[]) leads to the method
+ // write(ByteBuffer[], int, int) being called with a 0 for the
+ // second parameter and sources.length as the third parameter.
+ sc.write(byteBufferArray);
+ assertTrue(sc.isWriteCalled);
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ */
+ public void test_writev() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(ssc.socket().getLocalSocketAddress());
+ SocketChannel sock = ssc.accept();
+ ByteBuffer[] buf = { ByteBuffer.allocate(10), ByteBuffer.allocateDirect(20) };
+
+ while (buf[0].remaining() != 0 && buf[1].remaining() !=0) {
+ assertTrue(sc.write(buf, 0, 2) >= 0);
+ }
+
+ ByteBuffer target = ByteBuffer.allocate(30);
+
+ while (target.remaining() != 0) {
+ assertTrue(sock.read(target) >=0);
+ }
+
+ ssc.close();
+ sc.close();
+ sock.close();
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ */
+ public void test_writev2() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.configureBlocking(false);
+ ssc.socket().bind(null);
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ boolean connected = sc.connect(ssc.socket().getLocalSocketAddress());
+ SocketChannel sock = ssc.accept();
+ if (!connected) {
+ sc.finishConnect();
+ }
+
+ ByteBuffer buf1 = ByteBuffer.allocate(10);
+ sc.socket().setSendBufferSize(512);
+ int bufSize = sc.socket().getSendBufferSize();
+ ByteBuffer buf2 = ByteBuffer.allocate(bufSize * 10);
+
+ ByteBuffer[] sent = new ByteBuffer[2];
+ sent[0] = buf1;
+ sent[1] = buf2;
+
+ long whole = buf1.remaining() + buf2.remaining();
+
+ long write = sc.write(sent);
+ ssc.close();
+ sc.close();
+ sock.close();
+
+ assertTrue(whole == (write + buf1.remaining() + buf2.remaining()));
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ *
+ * In non-blocking mode, the native system call will return EAGAIN/EWOULDBLOCK error
+ * code on Linux/Unix and return WSATRY_AGAIN/WSAEWOULDBLOCK error code on Windows.
+ * These error code means try again but not fatal error, so we should not throw exception.
+ */
+ public void test_write$NonBlockingException() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.configureBlocking(false);
+ ssc.socket().bind(null);
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ boolean connected = sc.connect(ssc.socket().getLocalSocketAddress());
+ SocketChannel sock = ssc.accept();
+ if (!connected) {
+ sc.finishConnect();
+ }
+
+ try {
+ for (int i = 0; i < 100; i++) {
+ ByteBuffer buf1 = ByteBuffer.allocate(10);
+ sc.socket().setSendBufferSize(512);
+ int bufSize = sc.socket().getSendBufferSize();
+ ByteBuffer buf2 = ByteBuffer.allocate(bufSize * 10);
+
+ ByteBuffer[] sent = new ByteBuffer[2];
+ sent[0] = buf1;
+ sent[1] = buf2;
+
+ sc.write(sent);
+ }
+ } finally {
+ ssc.close();
+ sc.close();
+ sock.close();
+ }
+
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ */
+ public void test_write$LByteBuffer2() throws IOException {
+ // Set-up
+ ServerSocketChannel server = ServerSocketChannel.open();
+ server.socket().bind(null);
+ SocketChannel client = SocketChannel.open();
+ client.connect(server.socket().getLocalSocketAddress());
+ SocketChannel worker = server.accept();
+
+ // Test overlapping buffers
+ byte[] data = "Hello world!".getBytes("UTF-8");
+ ByteBuffer[] buffers = new ByteBuffer[3];
+ buffers[0] = ByteBuffer.wrap(data, 0, 6);
+ buffers[1] = ByteBuffer.wrap(data, 6, data.length - 6);
+ buffers[2] = ByteBuffer.wrap(data);
+
+ // Write them out, read what we wrote and check it
+ client.write(buffers);
+ client.close();
+ ByteBuffer readBuffer = ByteBuffer.allocate(1024);
+ while (EOF != worker.read(readBuffer)) {}
+ readBuffer.flip();
+ Buffer expected = ByteBuffer.allocate(1024).put(data).put(data).flip();
+ assertEquals(expected, readBuffer);
+
+ // Tidy-up
+ worker.close();
+ server.close();
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ */
+ public void test_write$LByteBuffer_buffers() throws IOException {
+ // Set-up
+ ServerSocketChannel server = ServerSocketChannel.open();
+ server.socket().bind(null);
+ SocketChannel client = SocketChannel.open();
+ client.connect(server.socket().getLocalSocketAddress());
+ SocketChannel worker = server.accept();
+
+ // A variety of buffer types to write
+ byte[] data = "Hello world!".getBytes("UTF-8");
+ ByteBuffer[] buffers = new ByteBuffer[3];
+ buffers[0] = ByteBuffer.wrap(data, 0, 2);
+ assertFalse(buffers[0].isDirect());
+ assertTrue(buffers[0].hasArray());
+
+ buffers[1] = ByteBuffer.wrap(data, 2, 4).asReadOnlyBuffer();
+ assertFalse(buffers[1].isDirect());
+ assertFalse(buffers[1].hasArray());
+
+ buffers[2] = ByteBuffer.allocateDirect(42);
+ buffers[2].put(data, 6, data.length - 6);
+ buffers[2].flip();
+ assertTrue(buffers[2].isDirect());
+ // Android's direct buffers do have a backing array.
+ assertTrue(buffers[2].hasArray());
+
+ // Write them out, read what we wrote and check it
+ client.write(buffers);
+ client.close();
+ ByteBuffer readBuffer = ByteBuffer.allocate(1024);
+ while (EOF != worker.read(readBuffer)) {}
+ readBuffer.flip();
+ assertEquals(ByteBuffer.wrap(data), readBuffer);
+
+ // Tidy-up
+ worker.close();
+ server.close();
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ */
+ public void test_write$LByteBuffer_writes() throws IOException {
+ // Set-up
+ ServerSocketChannel server = ServerSocketChannel.open();
+ server.socket().bind(null);
+ SocketChannel client = SocketChannel.open();
+ client.connect(server.socket().getLocalSocketAddress());
+ SocketChannel worker = server.accept();
+
+ // Data to write
+ byte[] data = "Hello world!".getBytes("UTF-8");
+ ByteBuffer[] buffers = new ByteBuffer[3];
+ buffers[0] = ByteBuffer.wrap(data, 0, 6);
+ buffers[1] = ByteBuffer.wrap("world!".getBytes("UTF-8"));
+ buffers[2] = buffers[0];
+ assertTrue(buffers[0].hasArray());
+
+ // Test a sequence of write calls
+ client.write(buffers, 0, 0); // write nothing
+ client.write(buffers, 1, 0); // write nothing
+ client.write(buffers, 0, 1); // write "Hello "
+ assertEquals("Failed to drain buffer 0", 0, buffers[0].remaining());
+ assertEquals("Shouldn't touch buffer 1", buffers[1].limit(), buffers[1]
+ .remaining());
+ client.write(buffers, 0, 2); // writes "world!"
+ assertEquals("Failed to drain buffer 1", 0, buffers[1].remaining());
+ client.write(buffers, 0, 3); // write nothing
+ client.close();
+
+ // Read what we wrote and check it
+ ByteBuffer readBuffer = ByteBuffer.allocate(1024);
+ while (EOF != worker.read(readBuffer)) {}
+ readBuffer.flip();
+ assertEquals(ByteBuffer.wrap(data), readBuffer);
+
+ // Tidy-up
+ worker.close();
+ server.close();
+ }
+
+ /**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ */
+ public void test_write$LByteBuffer_invalid() throws IOException {
+ // Set-up
+ ServerSocketChannel server = ServerSocketChannel.open();
+ server.socket().bind(null);
+
+ SocketChannel client = SocketChannel.open();
+ client.connect(server.socket().getLocalSocketAddress());
+
+ SocketChannel worker = server.accept();
+
+ // Do some stuff
+ try {
+ client.write((ByteBuffer[]) null);
+ fail("Should throw a NPE");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ client.write((ByteBuffer[]) null, 0, 0);
+ fail("Should throw a NPE");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ client.write((ByteBuffer[]) null, 1, 0);
+ fail("Should throw a NPE");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ client.write((ByteBuffer[]) null, 0, 1);
+ fail("Should throw a NPE");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ client.write((ByteBuffer[]) null, 1, 1);
+ fail("Should throw a NPE");
+ } catch (NullPointerException expected) {
+ }
+
+ ByteBuffer[] buffers = new ByteBuffer[1];
+ buffers[0] = ByteBuffer.wrap("Hello ".getBytes("UTF-8"));
+
+ try {
+ client.write(buffers, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ client.write(buffers, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ client.write(buffers, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ client.write(buffers, 2, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ client.write(null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // Tidy-up
+ worker.close();
+ client.close();
+ server.close();
+ }
+
+ public void testSocket_configureblocking() throws IOException {
+ byte[] serverWBuf = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < serverWBuf.length; i++) {
+ serverWBuf[i] = (byte) i;
+ }
+ java.nio.ByteBuffer buf = java.nio.ByteBuffer
+ .allocate(CAPACITY_NORMAL + 1);
+ channel1.connect(localAddr1);
+ server1.accept();
+ Socket sock = this.channel1.socket();
+ channel1.configureBlocking(false);
+ assertFalse(channel1.isBlocking());
+ OutputStream channelSocketOut = sock.getOutputStream();
+ try {
+ // write operation is not allowed in non-blocking mode
+ channelSocketOut.write(buf.array());
+ fail("Non-Blocking mode should cause IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e) {
+ // correct
+ }
+ channel1.configureBlocking(true);
+ assertTrue(channel1.isBlocking());
+ // write operation is allowed in blocking mode
+ channelSocketOut.write(buf.array());
+ }
+
+ /**
+ * @tests SocketChannel#read(ByteBuffer[], int, int) when remote server
+ * closed
+ */
+ public void test_socketChannel_read_ByteBufferII_remoteClosed()
+ throws Exception {
+ // regression 1 for HARMONY-549
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(ssc.socket().getLocalSocketAddress());
+ ssc.accept().close();
+ ByteBuffer[] buf = { ByteBuffer.allocate(10) };
+ assertEquals(-1, sc.read(buf, 0, 1));
+ ssc.close();
+ sc.close();
+ }
+
+ /**
+ * @tests SocketChannel#write(ByteBuffer[], int, int)
+ */
+ public void test_socketChannel_write_ByteBufferII() throws Exception {
+ // regression 2 for HARMONY-549
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(ssc.socket().getLocalSocketAddress());
+ SocketChannel sock = ssc.accept();
+ ByteBuffer[] buf = { ByteBuffer.allocate(10), null };
+ try {
+ sc.write(buf, 0, 2);
+ fail("should throw NPE");
+ } catch (NullPointerException expected) {
+ }
+ ssc.close();
+ sc.close();
+ ByteBuffer target = ByteBuffer.allocate(10);
+ assertEquals(-1, sock.read(target));
+ }
+
+ /**
+ * @tests SocketChannel#read(ByteBuffer[], int, int) with a null ByteBuffer
+ */
+ public void test_socketChannel_read_ByteBufferII_bufNULL() throws Exception {
+ // regression 3 for HARMONY-549
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(ssc.socket().getLocalSocketAddress());
+ ssc.accept();
+ ByteBuffer[] buf = new ByteBuffer[2];
+ buf[0] = ByteBuffer.allocate(1);
+ // let buf[1] be null
+ try {
+ sc.read(buf, 0, 2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ ssc.close();
+ sc.close();
+ }
+
+ /**
+ * @tests SocketChannel#write(ByteBuffer) after close
+ */
+ public void test_socketChannel_write_close() throws Exception {
+ // regression 4 for HARMONY-549
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(ssc.socket().getLocalSocketAddress());
+ SocketChannel sock = ssc.accept();
+ ByteBuffer buf = null;
+ ssc.close();
+ sc.close();
+ try {
+ sc.write(buf);
+ fail("should throw NPE");
+ } catch (NullPointerException expected) {
+ }
+ sock.close();
+ }
+
+ /**
+ * @tests SocketChannel#write(ByteBuffer) if position is not zero
+ */
+ public void test_socketChannel_write_ByteBuffer_posNotZero()
+ throws Exception {
+ // regression 5 for HARMONY-549
+ final String testStr = "Hello World";
+ ByteBuffer readBuf = ByteBuffer.allocate(11);
+ ByteBuffer buf = ByteBuffer.wrap(testStr.getBytes());
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(ssc.socket().getLocalSocketAddress());
+ buf.position(2);
+ ssc.accept().write(buf);
+ assertEquals(9, sc.read(readBuf));
+ buf.flip();
+ readBuf.flip();
+ byte[] read = new byte[9];
+ byte[] write = new byte[11];
+ buf.get(write);
+ readBuf.get(read);
+ for (int i = 0; i < 9; i++) {
+ assertEquals(read[i], write[i + 2]);
+ }
+ }
+
+ /**
+ * @tests SocketChannelImpl#read(ByteBuffer[])
+ */
+ public void test_read_$ByteBuffer_Blocking() throws IOException {
+ // regression test for Harmony-728
+ byte[] data = new byte[CAPACITY_NORMAL];
+ for (int i = 0; i < CAPACITY_NORMAL; i++) {
+ data[i] = (byte) i;
+ }
+ ByteBuffer[] buf = new ByteBuffer[2];
+ buf[0] = ByteBuffer.allocate(CAPACITY_NORMAL);
+ buf[1] = ByteBuffer.allocate(CAPACITY_NORMAL);
+ channel1.connect(localAddr1);
+ Socket socket = null;
+ try {
+ socket = server1.accept();
+ OutputStream out = socket.getOutputStream();
+ out.write(data);
+ // should not block here
+ channel1.read(buf);
+ } finally {
+ if (null != socket) {
+ socket.close();
+ }
+ }
+ }
+
+ public void test_socket_getOutputStream_nonBlocking_read_Exception() throws IOException {
+ byte[] buf = new byte[1];
+ channel1.connect(this.localAddr1);
+ InputStream is = channel1.socket().getInputStream();
+ channel1.configureBlocking(false);
+ try {
+ is.read();
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ }
+
+ try {
+ is.read(null);
+ fail();
+ } catch (NullPointerException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(buf, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(buf, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(buf, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(buf, 2, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ is.close();
+
+ try {
+ is.read();
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IOException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(null);
+ fail();
+ } catch (NullPointerException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IOException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(buf, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IOException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(buf, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IOException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(buf, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IOException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(buf, 2, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IOException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ is.read(null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ // Any of these exceptions are possible.
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IOException expected) {
+ // Any of these exceptions are possible.
+ }
+ }
+
+ public void test_socket_getOutputStream_blocking_read_Exception() throws IOException {
+ byte[] buf = new byte[1];
+ channel1.connect(this.localAddr1);
+ InputStream is = channel1.socket().getInputStream();
+ try {
+ is.read(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ is.read(buf, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ is.read(buf, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ is.read(buf, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ is.read(buf, 2, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ is.read(null, 0, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ is.close();
+
+ try {
+ is.read(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ is.read(buf, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ is.read(buf, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ is.read(buf, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ is.read(buf, 2, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ is.read(null, 0, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_socket_getOutputStream_nonBlocking_write_Exception() throws IOException {
+ byte[] buf = new byte[1];
+ channel1.connect(this.localAddr1);
+ OutputStream os = channel1.socket().getOutputStream();
+ channel1.configureBlocking(false);
+
+ try {
+ os.write(1);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ }
+ try {
+ os.write(null);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (NullPointerException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(buf, -1, 1);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(buf, 0, -1);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(buf, 0, 2);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(buf, 2, 1);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(null, 0, 1);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (NullPointerException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ os.close();
+
+ try {
+ os.write(1);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ }
+
+ try {
+ os.write(null);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (NullPointerException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(buf, -1, 1);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(buf, 0, -1);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(buf, 0, 2);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(buf, 2, 0);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (IndexOutOfBoundsException expected) {
+ // Any of these exceptions are possible.
+ }
+
+ try {
+ os.write(null, 0, 0);
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ // Any of these exceptions are possible.
+ } catch (NullPointerException expected) {
+ // Any of these exceptions are possible.
+ }
+ }
+
+ public void test_socket_getOutputStream_blocking_write_Exception() throws IOException {
+ byte[] buf = new byte[1];
+ channel1.connect(this.localAddr1);
+ OutputStream os = channel1.socket().getOutputStream();
+ try {
+ os.write(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ os.write(buf, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ os.write(buf, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ os.write(buf, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ os.write(buf, 2, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ os.write(null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ os.close();
+
+ try {
+ os.write(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ os.write(buf, -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ os.write(buf, 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ os.write(buf, 0, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ os.write(buf, 2, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ os.write(null, 0, 0);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * @tests SocketChannelImpl#socket().getOutputStream().write(int)
+ */
+ public void test_socket_getOutputStream_write_oneByte()
+ throws IOException {
+
+ // Regression test for Harmony-3475
+
+ int MAGIC = 123;
+
+ channel1.connect(this.localAddr1);
+
+ OutputStream os = channel1.socket().getOutputStream();
+
+ Socket acceptedSocket = server1.accept();
+
+ InputStream in = acceptedSocket.getInputStream();
+
+ os.write(MAGIC);
+ channel1.close();
+
+ int lastByte = in.read();
+ if (lastByte == -1) {
+ fail("Server received nothing. Expected 1 byte.");
+ } else if (lastByte != MAGIC) {
+ fail("Server received wrong single byte: " + lastByte +
+ ", expected: " + MAGIC);
+ }
+
+ lastByte = in.read();
+ if (lastByte != -1) {
+ fail("Server received too long sequence. Expected 1 byte.");
+ }
+ }
+
+ public void testSocket_setOptions() throws IOException {
+ channel1.connect(localAddr1);
+ Socket socket = channel1.socket();
+
+ ByteBuffer buffer = ByteBuffer.wrap(new byte[] {1, 2, 3});
+ socket.setKeepAlive(true);
+ channel1.write(buffer);
+
+ socket.setOOBInline(true);
+ channel1.write(buffer);
+
+ socket.setReceiveBufferSize(100);
+ channel1.write(buffer);
+
+ socket.setReuseAddress(true);
+ channel1.write(buffer);
+
+ socket.setSendBufferSize(100);
+ channel1.write(buffer);
+
+ socket.setSoLinger(true, 100);
+ channel1.write(buffer);
+
+ socket.setSoTimeout(1000);
+ channel1.write(buffer);
+
+ socket.setTcpNoDelay(true);
+ channel1.write(buffer);
+
+ socket.setTrafficClass(10);
+ channel1.write(buffer);
+ }
+
+ class MockSocketChannel extends SocketChannel {
+
+ private boolean isWriteCalled = false;
+
+ private boolean isReadCalled = false;
+
+ public MockSocketChannel(SelectorProvider provider) {
+ super(provider);
+ }
+
+ @Override
+ public Socket socket() {
+ return null;
+ }
+
+ @Override
+ public boolean isConnected() {
+ return false;
+ }
+
+ @Override
+ public boolean isConnectionPending() {
+ return false;
+ }
+
+ @Override
+ public boolean connect(SocketAddress address) throws IOException {
+ return false;
+ }
+
+ @Override
+ public boolean finishConnect() throws IOException {
+ return false;
+ }
+
+ @Override
+ public int read(ByteBuffer target) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public long read(ByteBuffer[] targets, int offset, int length) throws IOException {
+ // Verify that calling read(ByteBuffer[]) leads to the method
+ // read(ByteBuffer[], int, int) being called with a 0 for the
+ // second parameter and targets.length as the third parameter.
+ if(0 == offset && length == targets.length){
+ isReadCalled = true;
+ }
+ return 0;
+ }
+
+ @Override
+ public int write(ByteBuffer source) throws IOException {
+ return 0;
+ }
+
+ @Override
+ public long write(ByteBuffer[] sources, int offset, int length) throws IOException {
+ // Verify that calling write(ByteBuffer[]) leads to the method
+ // write(ByteBuffer[], int, int) being called with a 0 for the
+ // second parameter and sources.length as the third parameter.
+ if(0 == offset && length == sources.length){
+ isWriteCalled = true;
+ }
+ return 0;
+ }
+
+ @Override
+ protected void implCloseSelectableChannel() throws IOException {
+ // empty
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean blockingMode) throws IOException {
+ // empty
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SourceChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SourceChannelTest.java
new file mode 100644
index 0000000..2d45e61
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SourceChannelTest.java
@@ -0,0 +1,554 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.Pipe;
+import java.nio.channels.SelectionKey;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for java.nio.channels.Pipe.SourceChannel
+ */
+public class SourceChannelTest extends TestCase {
+
+ private static final int BUFFER_SIZE = 5;
+
+ private static final String ISO8859_1 = "ISO8859-1";
+
+ private Pipe pipe;
+
+ private Pipe.SinkChannel sink;
+
+ private Pipe.SourceChannel source;
+
+ private ByteBuffer buffer;
+
+ private ByteBuffer positionedBuffer;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ pipe = Pipe.open();
+ sink = pipe.sink();
+ source = pipe.source();
+ buffer = ByteBuffer.wrap("bytes".getBytes(ISO8859_1));
+ positionedBuffer = ByteBuffer.wrap("12345bytes".getBytes(ISO8859_1));
+ positionedBuffer.position(BUFFER_SIZE);
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#validOps()
+ */
+ public void test_validOps() {
+ assertEquals(SelectionKey.OP_READ, source.validOps());
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_LByteBuffer_DataAvailable() throws IOException {
+ // if anything can read, read method will not block
+ sink.write(ByteBuffer.allocate(1));
+ int count = source.read(ByteBuffer.allocate(10));
+ assertEquals(1, count);
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_LByteBuffer_Exception() throws IOException {
+ ByteBuffer nullBuf = null;
+ try {
+ source.read(nullBuf);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_LByteBuffer_SinkClosed() throws IOException {
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ sink.write(buffer);
+ sink.close();
+ long count = source.read(readBuf);
+ assertEquals(BUFFER_SIZE, count);
+ // readBuf is full, read 0 byte expected
+ count = source.read(readBuf);
+ assertEquals(0, count);
+ // readBuf is not null, -1 is expected
+ readBuf.position(0);
+ count = source.read(readBuf);
+ assertEquals(-1, count);
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_LByteBuffer_SourceClosed() throws IOException {
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ source.close();
+ try {
+ source.read(readBuf);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ readBuf.position(BUFFER_SIZE);
+ try {
+ // readBuf is full
+ source.read(readBuf);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ ByteBuffer nullBuf = null;
+ try {
+ source.read(nullBuf);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ ByteBuffer[] bufArray = null;
+ try {
+ source.read(bufArray);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ ByteBuffer[] nullBufArray = {nullBuf};
+ try {
+ source.read(nullBufArray);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer[])
+ */
+ public void test_read_$LByteBuffer() throws IOException {
+ ByteBuffer[] bufArray = { buffer, positionedBuffer };
+ boolean[] sinkBlockingMode = { true, true, false, false };
+ boolean[] sourceBlockingMode = { true, false, true, false };
+ for (int i = 0; i < sinkBlockingMode.length; ++i) {
+ // open new pipe everytime, will be closed in finally block
+ pipe = Pipe.open();
+ sink = pipe.sink();
+ source = pipe.source();
+ sink.configureBlocking(sinkBlockingMode[i]);
+ source.configureBlocking(sourceBlockingMode[i]);
+ buffer.position(0);
+ positionedBuffer.position(BUFFER_SIZE);
+ try {
+ long writeCount = sink.write(bufArray);
+ assertEquals(10, writeCount);
+ // invoke close to ensure all data will be sent out
+ sink.close();
+ // read until EOF is meet or readBufArray is full.
+ ByteBuffer[] readBufArray = { ByteBuffer.allocate(BUFFER_SIZE),
+ ByteBuffer.allocate(BUFFER_SIZE) };
+ long totalCount = 0;
+ do {
+ long count = source.read(readBufArray);
+ if (count < 0) {
+ break;
+ }
+ if (0 == count && BUFFER_SIZE == readBufArray[1].position()) {
+ // source.read returns 0 because readBufArray is full
+ break;
+ }
+ totalCount += count;
+ } while (totalCount <= 10);
+ // assert read result
+ for (ByteBuffer readBuf : readBufArray) {
+ // RI may fail because of its bug implementation
+ assertEquals(BUFFER_SIZE, readBuf.position());
+ assertEquals("bytes",
+ new String(readBuf.array(), ISO8859_1));
+ }
+ } finally {
+ // close pipe everytime
+ sink.close();
+ source.close();
+ }
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_$LByteBuffer_Exception() throws IOException {
+ ByteBuffer[] nullBufArrayRef = null;
+ try {
+ source.read(nullBufArrayRef);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // ByteBuffer array contains null element
+ ByteBuffer nullBuf = null;
+ ByteBuffer[] nullBufArray1 = { nullBuf };
+ try {
+ source.read(nullBufArray1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
+ try {
+ source.read(nullBufArray2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_$LByteBuffer_SinkClosed() throws IOException {
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ ByteBuffer[] readBufArray = { readBuf };
+ sink.write(buffer);
+ sink.close();
+ long count = source.read(readBufArray);
+ assertEquals(BUFFER_SIZE, count);
+ // readBuf is full, read 0 byte expected
+ count = source.read(readBufArray);
+ assertEquals(0, count);
+ // readBuf is not null, -1 is expected
+ readBuf.position(0);
+ assertTrue(readBuf.hasRemaining());
+ count = source.read(readBufArray);
+ assertEquals(-1, count);
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_$LByteBuffer_SourceClosed() throws IOException {
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ ByteBuffer[] readBufArray = { readBuf };
+ source.close();
+ try {
+ source.read(readBufArray);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ readBuf.position(BUFFER_SIZE);
+ try {
+ // readBuf is full
+ source.read(readBufArray);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ ByteBuffer[] nullBufArrayRef = null;
+ try {
+ source.read(nullBufArrayRef);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // ByteBuffer array contains null element
+ ByteBuffer nullBuf = null;
+ ByteBuffer[] nullBufArray1 = { nullBuf };
+ try {
+ source.read(nullBufArray1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer[], int, int)
+ */
+ public void test_read_$LByteBufferII() throws IOException {
+ ByteBuffer[] bufArray = { buffer, positionedBuffer };
+ boolean[] sinkBlockingMode = { true, true, false, false };
+ boolean[] sourceBlockingMode = { true, false, true, false };
+ for (int i = 0; i < sinkBlockingMode.length; ++i) {
+ Pipe pipe = Pipe.open();
+ sink = pipe.sink();
+ source = pipe.source();
+
+ sink.configureBlocking(sinkBlockingMode[i]);
+ source.configureBlocking(sourceBlockingMode[i]);
+
+ buffer.position(0);
+ positionedBuffer.position(BUFFER_SIZE);
+ try {
+ sink.write(bufArray);
+ // invoke close to ensure all data will be sent out
+ sink.close();
+ // read until EOF is meet or readBufArray is full.
+ ByteBuffer[] readBufArray = { ByteBuffer.allocate(BUFFER_SIZE),
+ ByteBuffer.allocate(BUFFER_SIZE) };
+ long totalCount = 0;
+ do {
+ long count = source.read(readBufArray, 0, 2);
+ if (count < 0) {
+ break;
+ }
+ if (0 == count && BUFFER_SIZE == readBufArray[1].position()) {
+ // source.read returns 0 because readBufArray is full
+ break;
+ }
+ totalCount += count;
+ } while (totalCount != 10);
+
+ // assert read result
+ for (ByteBuffer readBuf : readBufArray) {
+ // RI may fail because of its bug implementation
+ assertEquals(BUFFER_SIZE, readBuf.position());
+ assertEquals("bytes",
+ new String(readBuf.array(), ISO8859_1));
+ }
+ } finally {
+ sink.close();
+ source.close();
+ }
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_$LByteBufferII_Exception() throws IOException {
+
+ ByteBuffer[] nullBufArrayRef = null;
+ try {
+ source.read(nullBufArrayRef, 0, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ source.read(nullBufArrayRef, 0, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ source.read(new ByteBuffer[0], 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ source.read(new ByteBuffer[0], -1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // ByteBuffer array contains null element
+ ByteBuffer nullBuf = null;
+ ByteBuffer[] nullBufArray1 = { nullBuf };
+ try {
+ source.read(nullBufArray1, 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ source.read(nullBufArray1, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ source.read(nullBufArray1, -1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ source.read(nullBufArray1, -1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
+
+ try {
+ source.read(nullBufArray1, 1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ source.read(nullBufArray2, 0, 3);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ source.read(nullBufArray2, 0, 2);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_$LByteBufferII_SinkClosed() throws IOException {
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ ByteBuffer[] readBufArray = { readBuf };
+ sink.write(buffer);
+ sink.close();
+ long count = source.read(readBufArray, 0, 1);
+ assertEquals(BUFFER_SIZE, count);
+ // readBuf is full, read 0 byte expected
+ count = source.read(readBufArray);
+ assertEquals(0, count);
+ // readBuf is not null, -1 is expected
+ readBuf.position(0);
+ count = source.read(readBufArray, 0, 1);
+ assertEquals(-1, count);
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#read(ByteBuffer)
+ */
+ public void test_read_$LByteBufferII_SourceClosed() throws IOException {
+ ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE);
+ ByteBuffer[] readBufArray = { readBuf };
+ source.close();
+ try {
+ source.read(readBufArray, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ readBuf.position(BUFFER_SIZE);
+ try {
+ // readBuf is full
+ source.read(readBufArray, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ ByteBuffer[] nullBufArrayRef = null;
+ try {
+ source.read(nullBufArrayRef, 0, 1);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ source.read(nullBufArrayRef, 0, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ source.read(new ByteBuffer[0], 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ source.read(new ByteBuffer[0], -1, 1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // ByteBuffer array contains null element
+ ByteBuffer nullBuf = null;
+ ByteBuffer[] nullBufArray1 = { nullBuf };
+ try {
+ source.read(nullBufArray1, 0, 1);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ try {
+ source.read(nullBufArray1, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ source.read(nullBufArray1, -1, 0);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ source.read(nullBufArray1, -1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ ByteBuffer[] nullBufArray2 = { buffer, nullBuf };
+
+ try {
+ source.read(nullBufArray1, 1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ source.read(nullBufArray2, 0, 3);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ source.read(nullBufArray2, 0, 2);
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.channels.Pipe.SourceChannel#close()
+ */
+ public void test_close() throws IOException {
+ sink.close();
+ assertFalse(sink.isOpen());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnixSelectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnixSelectorTest.java
new file mode 100644
index 0000000..59d8ed8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnixSelectorTest.java
@@ -0,0 +1,116 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+import junit.framework.TestCase;
+
+public class UnixSelectorTest extends TestCase {
+ static class Server {
+ ServerSocketChannel serverChannel = ServerSocketChannel.open();
+ ServerSocket socket = null;
+
+ Server() throws Exception {
+ serverChannel.configureBlocking(false);
+ }
+
+ public void initialize() throws Exception {
+ this.socket = serverChannel.socket();
+ socket.bind(null);
+ }
+
+ public void accept() {
+ Thread serverThread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ while (serverChannel.accept() == null) {
+ Thread.sleep(1000);
+ }
+ } catch (Exception e) {}
+ }
+ });
+ serverThread.start();
+ }
+
+ public void close() throws Exception{
+ serverChannel.close();
+ }
+ }
+
+ public void testSelectorAcceptAndRead() throws Exception {
+ Selector sel0 = Selector.open();
+ Selector sel1 = Selector.open();
+ Server server = new Server();
+ SelectionKey mkey0 = server.serverChannel.register(sel0, SelectionKey.OP_ACCEPT);
+ server.serverChannel.register(sel1, SelectionKey.OP_ACCEPT);
+
+ // HUP is treating as acceptable
+ assertEquals(1, sel0.select(100));
+ assertEquals(true, sel0.selectedKeys().contains(mkey0));
+ server.initialize();
+ // after bind can not accept
+ assertEquals(0, sel1.select(100));
+ server.accept();
+ Thread.sleep(1000);
+ SocketChannel socketChannel = SocketChannel.open();
+ socketChannel.configureBlocking(false);
+ Selector sel2 = Selector.open();
+ socketChannel.register(sel2, SelectionKey.OP_WRITE);
+ boolean isConnected = socketChannel.connect(server.socket.getLocalSocketAddress());
+ if (!isConnected) {
+ socketChannel.finishConnect();
+ }
+
+ assertEquals(true, socketChannel.isConnected());
+ server.close();
+ Thread.sleep(3000);
+ assertEquals(true, socketChannel.isConnected());
+ assertEquals(1, sel2.select(100));
+ }
+
+ public void testSelectUnConnectedChannel() throws Exception {
+ SocketChannel socketChannel2 = SocketChannel.open();
+ socketChannel2.configureBlocking(false);
+ Selector sel3 = Selector.open();
+ SelectionKey mkey3 = socketChannel2.register(sel3, SelectionKey.OP_WRITE);
+ // HUP is also treating as writable
+ assertEquals(1, sel3.select(100));
+ assertEquals(false, mkey3.isConnectable());
+ // even the channel is not connected, the selector could be writable
+ assertEquals(false, socketChannel2.isConnected());
+ assertEquals(true, mkey3.isWritable());
+
+ Selector sel4 = Selector.open();
+ SelectionKey mkey4 = socketChannel2.register(sel4, SelectionKey.OP_CONNECT);
+ assertEquals(1, sel4.select(100));
+ assertEquals(false, mkey4.isWritable());
+ assertEquals(true, mkey4.isConnectable());
+
+ Selector sel5 = Selector.open();
+ SelectionKey mkey5 = socketChannel2.register(sel5, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE);
+ assertEquals(1, sel5.select(100));
+ assertEquals(true, mkey5.isWritable());
+ assertEquals(true, mkey5.isConnectable());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnresolvedAddressExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnresolvedAddressExceptionTest.java
new file mode 100644
index 0000000..cb89964
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnresolvedAddressExceptionTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.UnresolvedAddressException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for UnresolvedAddressException
+ */
+public class UnresolvedAddressExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.UnresolvedAddressException#UnresolvedAddressException()}
+ */
+ public void test_Constructor() {
+ UnresolvedAddressException e = new UnresolvedAddressException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new UnresolvedAddressException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new UnresolvedAddressException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java
new file mode 100644
index 0000000..3b47cd4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java
@@ -0,0 +1,55 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.channels;
+
+import java.nio.channels.UnsupportedAddressTypeException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for UnsupportedAddressTypeException
+ */
+public class UnsupportedAddressTypeExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.UnsupportedAddressTypeException#UnsupportedAddressTypeException()}
+ */
+ public void test_Constructor() {
+ UnsupportedAddressTypeException e = new UnsupportedAddressTypeException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new UnsupportedAddressTypeException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new UnsupportedAddressTypeException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractInterruptibleChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractInterruptibleChannelTest.java
new file mode 100644
index 0000000..d6eb228
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractInterruptibleChannelTest.java
@@ -0,0 +1,135 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels.spi;
+
+import java.io.IOException;
+import java.nio.channels.AsynchronousCloseException;
+import java.nio.channels.spi.AbstractInterruptibleChannel;
+
+import junit.framework.TestCase;
+
+public class AbstractInterruptibleChannelTest extends TestCase {
+
+ /**
+ * @tests AbstractInterruptibleChannel#close()
+ */
+ public void test_close() throws IOException {
+ MockInterruptibleChannel testMiChannel = new MockInterruptibleChannel();
+ assertTrue(testMiChannel.isOpen());
+ testMiChannel.isImplCloseCalled = false;
+ testMiChannel.close();
+ assertTrue(testMiChannel.isImplCloseCalled);
+ assertFalse(testMiChannel.isOpen());
+ }
+
+ /**
+ * @tests AbstractInterruptibleChannel#begin/end()
+ */
+ public void test_begin_end() throws IOException {
+ boolean complete = false;
+ MockInterruptibleChannel testChannel = new MockInterruptibleChannel();
+ try {
+ testChannel.superBegin();
+ complete = true;
+ } finally {
+ testChannel.superEnd(complete);
+ }
+
+ try {
+ testChannel.superBegin();
+ complete = false;
+ } finally {
+ testChannel.superEnd(complete);
+ }
+
+ try {
+ testChannel.superBegin();
+ complete = true;
+ } finally {
+ testChannel.superEnd(complete);
+ }
+
+ testChannel.superBegin();
+ try {
+ testChannel.superBegin();
+ complete = true;
+ } finally {
+ testChannel.superEnd(complete);
+ }
+ assertTrue(testChannel.isOpen());
+ testChannel.close();
+ }
+
+ /**
+ * @tests AbstractInterruptibleChannel#close/begin/end()
+ */
+ public void test_close_begin_end() throws IOException {
+ boolean complete = false;
+ MockInterruptibleChannel testChannel = new MockInterruptibleChannel();
+ assertTrue(testChannel.isOpen());
+ try {
+ testChannel.superBegin();
+ complete = true;
+ } finally {
+ testChannel.superEnd(complete);
+ }
+ assertTrue(testChannel.isOpen());
+ testChannel.close();
+ try {
+ testChannel.superBegin();
+ complete = false;
+ } finally {
+ try {
+ testChannel.superEnd(complete);
+ fail("should throw AsynchronousCloseException");
+ } catch (AsynchronousCloseException e) {
+ // expected
+ }
+ }
+ assertFalse(testChannel.isOpen());
+ try {
+ testChannel.superBegin();
+ complete = true;
+ } finally {
+ testChannel.superEnd(complete);
+ }
+ assertFalse(testChannel.isOpen());
+ }
+
+ private class MockInterruptibleChannel extends AbstractInterruptibleChannel {
+
+ private boolean isImplCloseCalled = false;
+
+ public MockInterruptibleChannel() {
+ super();
+ }
+
+ protected void implCloseChannel() throws IOException {
+ isImplCloseCalled = true;
+ }
+
+ // call super.begin() for test
+ void superBegin() {
+ super.begin();
+ }
+
+ // call super.end() for test
+ void superEnd(boolean completed) throws AsynchronousCloseException {
+ super.end(completed);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java
new file mode 100644
index 0000000..31124ce
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java
@@ -0,0 +1,313 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels.spi;
+
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.IllegalSelectorException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for AbstractSelectableChannel
+ */
+public class AbstractSelectableChannelTest extends TestCase {
+
+ private MockSelectableChannel testChannel;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ testChannel = new MockSelectableChannel(SelectorProvider.provider());
+ }
+
+ protected void tearDown() throws Exception {
+ if (testChannel.isOpen()) {
+ testChannel.close();
+ }
+ }
+
+ /**
+ * @tests AbstractSelectableChannel#implCloseChannel()
+ */
+ public void test_implClose() throws IOException {
+ testChannel.isImplCloseSelectableChannelCalled = false;
+ testChannel.implCloseSelectableChannelCount = 0;
+ testChannel.close();
+ assertFalse(testChannel.isOpen());
+ assertTrue(testChannel.isImplCloseSelectableChannelCalled);
+ assertEquals(1, testChannel.implCloseSelectableChannelCount);
+
+ testChannel = new MockSelectableChannel(SelectorProvider.provider());
+ testChannel.isImplCloseSelectableChannelCalled = false;
+ testChannel.implCloseSelectableChannelCount = 0;
+ // close twice.
+ // make sure implCloseSelectableChannelCount is called only once.
+ testChannel.close();
+ testChannel.close();
+ assertFalse(testChannel.isOpen());
+ assertTrue(testChannel.isImplCloseSelectableChannelCalled);
+ assertEquals(1, testChannel.implCloseSelectableChannelCount);
+ }
+
+ /**
+ * @tests AbstractSelectableChannel#provider()
+ */
+ public void test_provider() {
+ SelectorProvider provider = testChannel.provider();
+ assertSame(SelectorProvider.provider(), provider);
+ testChannel = new MockSelectableChannel(null);
+ provider = testChannel.provider();
+ assertNull(provider);
+ }
+
+ /**
+ * @tests AbstractSelectableChannel#isBlocking()
+ */
+ public void test_isBlocking() throws IOException {
+ assertTrue(testChannel.isBlocking());
+ testChannel.configureBlocking(false);
+ assertFalse(testChannel.isBlocking());
+ testChannel.configureBlocking(true);
+ assertTrue(testChannel.isBlocking());
+ }
+
+ /**
+ *
+ * @tests AbstractSelectableChannel#blockingLock()
+ */
+ public void test_blockingLock() {
+ Object gotObj = testChannel.blockingLock();
+ assertNotNull(gotObj);
+ }
+
+ /**
+ * @tests AbstractSelectableChannel#register(Selector, int, Object)
+ */
+ public void test_register_LSelectorILObject() throws IOException {
+ assertFalse(testChannel.isRegistered());
+ Selector acceptSelector1 = SelectorProvider.provider().openSelector();
+ Selector acceptSelector2 = new MockAbstractSelector(SelectorProvider
+ .provider());
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ SelectionKey acceptKey = sc.register(acceptSelector1,
+ SelectionKey.OP_READ, null);
+ assertNotNull(acceptKey);
+ assertTrue(acceptKey.isValid());
+ assertSame(sc, acceptKey.channel());
+
+ //test that sc.register invokes Selector.register()
+ acceptKey = sc.register(acceptSelector2, SelectionKey.OP_READ, null);
+ assertNull(acceptKey);
+
+ // Regression test to ensure acceptance of a selector with empty
+ // interest set.
+ SocketChannel channel = SocketChannel.open();
+ channel.configureBlocking(false);
+ Selector selector = Selector.open();
+ channel.register(selector, 0);
+ selector.close();
+ channel.close();
+ }
+
+ /**
+ * @tests AbstractSelectableChannel#register(Selector, int, Object)
+ */
+ public void test_register_LSelectorILObject_IllegalArgument()
+ throws IOException {
+ Selector acceptSelector = SelectorProvider.provider().openSelector();
+ assertTrue(acceptSelector.isOpen());
+ MockSelectableChannel msc = new MockSelectableChannel(SelectorProvider
+ .provider());
+ msc.configureBlocking(false);
+ // in nonblocking mode
+ try {
+ //different SelectionKey with validOps
+ msc.register(acceptSelector, SelectionKey.OP_READ, null);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ msc.register(null, 0, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ // in nonblocking mode, if selector closed
+ acceptSelector.close();
+ try {
+ msc.register(acceptSelector, SelectionKey.OP_READ, null);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ msc.register(null, 0, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ msc.register(acceptSelector, 0, null);
+ fail("Should throw IllegalSelectorException");
+ } catch (IllegalSelectorException e) {
+ // expected
+ }
+
+ acceptSelector = SelectorProvider.provider().openSelector();
+ // test in blocking mode
+ msc.configureBlocking(true);
+ try {
+ msc.register(acceptSelector, SelectionKey.OP_READ, null);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ msc.register(null, 0, null);
+ fail("Should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e) {
+ // expected
+ }
+ acceptSelector.close();
+ // in blocking mode, if selector closed
+ try {
+ msc.register(acceptSelector, SelectionKey.OP_READ, null);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ msc.register(null, 0, null);
+ fail("Should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e) {
+ // expected
+ }
+
+ // register with an object
+ Object argObj = new Object();
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ try {
+ sc.register(null, SelectionKey.OP_READ, argObj);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // if channel closed
+ msc.close();
+ try {
+ msc.register(acceptSelector, SelectionKey.OP_READ, null);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * @tests AbstractSelectableChannel#keyFor(Selector)
+ */
+ public void test_keyfor_LSelector() throws Exception {
+ SocketChannel sc = SocketChannel.open();
+ Object argObj = new Object();
+ sc.configureBlocking(false);
+ Selector acceptSelector = SelectorProvider.provider().openSelector();
+ Selector acceptSelectorOther = SelectorProvider.provider()
+ .openSelector();
+ SelectionKey acceptKey = sc.register(acceptSelector,
+ SelectionKey.OP_READ, argObj);
+ assertEquals(sc.keyFor(acceptSelector), acceptKey);
+ SelectionKey acceptKeyObjNull = sc.register(acceptSelector,
+ SelectionKey.OP_READ, null);
+ assertSame(sc.keyFor(acceptSelector), acceptKeyObjNull);
+ assertSame(acceptKeyObjNull, acceptKey);
+ SelectionKey acceptKeyOther = sc.register(acceptSelectorOther,
+ SelectionKey.OP_READ, null);
+ assertSame(sc.keyFor(acceptSelectorOther), acceptKeyOther);
+ }
+
+ /**
+ * @tests AbstractSelectableChannel#configureBlocking(boolean)
+ */
+ public void test_configureBlocking_Z_IllegalBlockingMode() throws Exception {
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ Selector acceptSelector = SelectorProvider.provider().openSelector();
+ SelectionKey acceptKey = sc.register(acceptSelector,
+ SelectionKey.OP_READ, null);
+ assertEquals(sc.keyFor(acceptSelector), acceptKey);
+ SelectableChannel getChannel = sc.configureBlocking(false);
+ assertEquals(getChannel, sc);
+ try {
+ sc.configureBlocking(true);
+ fail("Should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests AbstractSelectableChannel#configureBlocking(boolean)
+ */
+ public void test_configureBlocking_Z() throws Exception {
+ MockSelectableChannel mock = new MockSelectableChannel(SelectorProvider
+ .provider());
+ //default blocking mode is true
+ //the implConfigureBlocking is only invoked if the given mode is different with current one
+ mock.configureBlocking(true);
+ assertFalse(mock.implConfigureBlockingCalled);
+ mock.configureBlocking(false);
+ assertTrue(mock.implConfigureBlockingCalled);
+ }
+
+ private class MockSelectableChannel extends AbstractSelectableChannel {
+
+ private boolean isImplCloseSelectableChannelCalled = false;
+
+ private int implCloseSelectableChannelCount = 0;
+
+ private boolean implConfigureBlockingCalled = false;
+
+ public MockSelectableChannel(SelectorProvider arg0) {
+ super(arg0);
+ }
+
+ protected void implCloseSelectableChannel() throws IOException {
+ isImplCloseSelectableChannelCalled = true;
+ ++implCloseSelectableChannelCount;
+ }
+
+ protected void implConfigureBlocking(boolean arg0) throws IOException {
+ implConfigureBlockingCalled = true;
+ }
+
+ public int validOps() {
+ return SelectionKey.OP_ACCEPT;
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectionKeyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectionKeyTest.java
new file mode 100644
index 0000000..e0abf8b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectionKeyTest.java
@@ -0,0 +1,76 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels.spi;
+
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectionKey;
+
+import junit.framework.TestCase;
+
+public class AbstractSelectionKeyTest extends TestCase {
+
+ /**
+ * @tests AbstractSelectionKey#isValid() without selector
+ */
+ public void test_isValid() throws Exception {
+ MockSelectionKey testKey = new MockSelectionKey();
+ assertTrue(testKey.isValid());
+ }
+
+ /**
+ * @tests AbstractSelectionKey#cancel
+ */
+ public void test_cancel() throws Exception {
+ MockSelectionKey testKey = new MockSelectionKey();
+ try {
+ testKey.cancel();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected: no selector available
+ }
+ assertFalse(testKey.isValid());
+ }
+
+ private class MockSelectionKey extends AbstractSelectionKey {
+
+ MockSelectionKey() {
+ super();
+ }
+
+ public SelectableChannel channel() {
+ return null;
+ }
+
+ public Selector selector() {
+ return null;
+ }
+
+ public int interestOps() {
+ return 0;
+ }
+
+ public SelectionKey interestOps(int arg0) {
+ return null;
+ }
+
+ public int readyOps() {
+ return 0;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectorTest.java
new file mode 100644
index 0000000..6f10b11
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/AbstractSelectorTest.java
@@ -0,0 +1,160 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels.spi;
+
+import java.io.IOException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for AbstractSelector and register of its default implementation
+ */
+public class AbstractSelectorTest extends TestCase {
+
+ /**
+ * @tests AbstractSelector#provider()
+ */
+ public void test_provider() throws IOException {
+ Selector mockSelector = new MockAbstractSelector(SelectorProvider
+ .provider());
+ assertTrue(mockSelector.isOpen());
+ assertSame(SelectorProvider.provider(), mockSelector.provider());
+ mockSelector = new MockAbstractSelector(null);
+ assertNull(mockSelector.provider());
+ }
+
+ /**
+ * @tests AbstractSelector#close()
+ */
+ public void test_close() throws IOException {
+ MockAbstractSelector mockSelector = new MockAbstractSelector(
+ SelectorProvider.provider());
+ mockSelector.close();
+ assertTrue(mockSelector.isImplCloseSelectorCalled);
+ }
+
+ /**
+ *
+ * @tests AbstractSelector#begin/end()
+ */
+ public void test_begin_end() throws IOException {
+ MockAbstractSelector mockSelector = new MockAbstractSelector(
+ SelectorProvider.provider());
+ try {
+ mockSelector.superBegin();
+ } finally {
+ mockSelector.superEnd();
+ }
+
+ mockSelector = new MockAbstractSelector(SelectorProvider.provider());
+ try {
+ mockSelector.superBegin();
+ mockSelector.close();
+ } finally {
+ mockSelector.superEnd();
+ }
+
+ try {
+ // begin twice
+ mockSelector.superBegin();
+ mockSelector.superBegin();
+ } finally {
+ mockSelector.superEnd();
+ }
+
+ try {
+ mockSelector.superBegin();
+ } finally {
+ // end twice
+ mockSelector.superEnd();
+ mockSelector.superEnd();
+ }
+
+ mockSelector.close();
+ try {
+ mockSelector.superBegin();
+ } finally {
+ mockSelector.superEnd();
+ }
+ }
+
+ /**
+ * @tests AbstractSelector#isOpen()
+ */
+ public void test_isOpen() throws Exception {
+ Selector acceptSelector = SelectorProvider.provider().openSelector();
+ assertTrue(acceptSelector.isOpen());
+ acceptSelector.close();
+ assertFalse(acceptSelector.isOpen());
+ }
+
+ /**
+ * @tests AbstractSelector#register(Selector,int)
+ */
+ public void test_register_LSelectorI() throws Exception {
+ Selector acceptSelector = SelectorProvider.provider().openSelector();
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.configureBlocking(false);
+
+ assertFalse(ssc.isRegistered());
+ SelectionKey acceptKey = ssc.register(acceptSelector,
+ SelectionKey.OP_ACCEPT);
+ assertTrue(ssc.isRegistered());
+ assertNotNull(acceptKey);
+ assertTrue(acceptSelector.keys().contains(acceptKey));
+ }
+
+ /**
+ * @tests AbstractSelector#register(Selector,int)
+ */
+ public void test_register_LSelectorI_error() throws IOException {
+ Selector acceptSelector = SelectorProvider.provider().openSelector();
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.configureBlocking(false);
+ acceptSelector.close();
+
+ assertFalse(acceptSelector.isOpen());
+ try {
+ ssc.register(acceptSelector, SelectionKey.OP_ACCEPT);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ assertFalse(ssc.isRegistered());
+
+ acceptSelector = Selector.open();
+ ssc.configureBlocking(true);
+ try {
+ ssc.register(acceptSelector, SelectionKey.OP_ACCEPT);
+ fail("should throw IllegalBlockingModeException");
+ } catch (IllegalBlockingModeException e) {
+ // expected
+ }
+ assertFalse(ssc.isRegistered());
+ ssc.configureBlocking(false);
+ SelectionKey acceptKey = ssc.register(acceptSelector,
+ SelectionKey.OP_ACCEPT);
+ assertNotNull(acceptKey);
+ assertTrue(acceptSelector.keys().contains(acceptKey));
+ assertTrue(ssc.isRegistered());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/MockAbstractSelector.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/MockAbstractSelector.java
new file mode 100644
index 0000000..aa173d8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/spi/MockAbstractSelector.java
@@ -0,0 +1,89 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.channels.spi;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.AbstractSelectionKey;
+import java.nio.channels.spi.AbstractSelector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Set;
+
+public class MockAbstractSelector extends AbstractSelector {
+
+ public boolean isImplCloseSelectorCalled = false;
+
+ public MockAbstractSelector(SelectorProvider arg0) {
+ super(arg0);
+ }
+
+ public static MockAbstractSelector openSelector() {
+ return new MockAbstractSelector(SelectorProvider.provider());
+ }
+
+ public Set getCancelledKeys() {
+ return super.cancelledKeys();
+ }
+
+ protected void implCloseSelector() throws IOException {
+ isImplCloseSelectorCalled = true;
+ }
+
+ protected SelectionKey register(AbstractSelectableChannel arg0, int arg1,
+ Object arg2) {
+ return null;
+ }
+
+ public void superBegin() {
+ super.begin();
+ }
+
+ public void superEnd() {
+ super.end();
+ }
+
+ protected void mockDeregister(AbstractSelectionKey key) {
+ super.deregister(key);
+ }
+
+ public Set<SelectionKey> keys() {
+ return null;
+ }
+
+ public Set<SelectionKey> selectedKeys() {
+ return null;
+ }
+
+ public int selectNow() throws IOException {
+ return 0;
+ }
+
+ public int select(long arg0) throws IOException {
+ return 0;
+ }
+
+ public int select() throws IOException {
+ return 0;
+ }
+
+ public Selector wakeup() {
+ return null;
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCCharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCCharsetDecoderTest.java
new file mode 100644
index 0000000..989443a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCCharsetDecoderTest.java
@@ -0,0 +1,72 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+public class ASCCharsetDecoderTest extends CharsetDecoderTest {
+
+ protected void setUp() throws Exception {
+ cs = Charset.forName("ascii");
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetDecoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // FIXME: give up this tests
+ // public void testDefaultCharsPerByte(){
+ // // assertEquals(1, decoder.averageCharsPerByte());
+ // // assertEquals(1, decoder.maxCharsPerByte());
+ // assertEquals(decoder.averageCharsPerByte(), 1, 0.001);
+ // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
+ // }
+
+ ByteBuffer getUnmappedByteBuffer() {
+ // FIXME: different here
+ return null;
+ // ByteBuffer buffer = ByteBuffer.allocate(8);
+ // buffer.put((byte)-1);
+ // buffer.put(unibytes);
+ // buffer.flip();
+ // return buffer;
+
+ }
+
+ ByteBuffer getMalformedByteBuffer() {
+ // FIXME: different here
+ ByteBuffer buffer = ByteBuffer.allocate(8);
+ buffer.put((byte) -1);
+ buffer.put(getByteBuffer());
+ buffer.flip();
+ return buffer;
+
+ // TODO: how malform?
+ // return null;
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ return null;
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCCharsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCCharsetTest.java
new file mode 100644
index 0000000..afd95ee
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCCharsetTest.java
@@ -0,0 +1,59 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+/**
+ * Test charset US-ASCII.
+ */
+public class ASCCharsetTest extends AbstractCharsetTestCase {
+
+ /**
+ * Constructor.
+ *
+ */
+ public ASCCharsetTest(String arg0) {
+ super(arg0, "US-ASCII", new String[] { "ISO646-US", "ASCII", "cp367",
+ "ascii7", "ANSI_X3.4-1986", "iso-ir-6", "us", "646",
+ "iso_646.irv:1983", "csASCII", "ANSI_X3.4-1968",
+ "ISO_646.irv:1991" }, true, true); // "ibm-367"
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
+ */
+ public void testEncode_Normal() {
+ String input = "ab\u5D14\u654F";
+ byte[] output = new byte[] { 97, 98,
+ this.testingCharset.newEncoder().replacement()[0],
+ this.testingCharset.newEncoder().replacement()[0] };
+ internalTestEncode(input, output);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
+ */
+ public void testDecode_Normal() {
+ byte[] input = new byte[] { 97, 98, 63, 63 };
+ char[] output = "ab??".toCharArray();
+ internalTestDecode(input, output);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCIICharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCIICharsetEncoderTest.java
new file mode 100644
index 0000000..ccaee57
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ASCIICharsetEncoderTest.java
@@ -0,0 +1,455 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import junit.framework.TestCase;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+
+public class ASCIICharsetEncoderTest extends TestCase {
+
+ // charset for ascii
+ private final Charset cs = Charset.forName("ascii");
+ private final CharsetEncoder encoder = cs.newEncoder();
+ private static final int MAXCODEPOINT = 0x7F;
+
+ /*
+ * @see CharsetEncoderTest#setUp()
+ */
+ protected void setUp() throws Exception {
+ }
+
+ /*
+ * @see CharsetEncoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ }
+
+ public void testCanEncodeCharSequence() {
+ // normal case for ascCS
+ assertTrue(encoder.canEncode("\u0077"));
+ assertFalse(encoder.canEncode("\uc2a3"));
+ assertFalse(encoder.canEncode("\ud800\udc00"));
+ try {
+ encoder.canEncode(null);
+ } catch (NullPointerException e) {
+ }
+ assertTrue(encoder.canEncode(""));
+ }
+
+ public void testCanEncodeSurrogate() {
+ assertFalse(encoder.canEncode('\ud800'));
+ assertFalse(encoder.canEncode("\udc00"));
+ }
+
+ public void testCanEncodechar() throws CharacterCodingException {
+ assertTrue(encoder.canEncode('\u0077'));
+ assertFalse(encoder.canEncode('\uc2a3'));
+ }
+
+ public void testSpecificDefaultValue() {
+ assertEquals(1.0, encoder.averageBytesPerChar(), 0.0);
+ assertEquals(1.0, encoder.maxBytesPerChar(), 0.0);
+ }
+
+ public void testMultiStepEncode() throws CharacterCodingException {
+ encoder.onMalformedInput(CodingErrorAction.REPORT);
+ encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ try {
+ encoder.encode(CharBuffer.wrap("\ud800\udc00"));
+ fail("should unmappable");
+ } catch (UnmappableCharacterException e) {
+ }
+ encoder.reset();
+ ByteBuffer out = ByteBuffer.allocate(10);
+ assertEquals(CoderResult.UNDERFLOW,
+ encoder.encode(CharBuffer.wrap("\ud800"), out, true));
+ assertTrue(encoder.flush(out).isMalformed());
+ encoder.reset();
+
+ out = ByteBuffer.allocate(10);
+ CharBuffer buffer1 = CharBuffer.wrap("\ud800");
+ CharBuffer buffer2 = CharBuffer.wrap("\udc00");
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(buffer1, out, false));
+ // We consume the entire input buffer because we're in an underflow
+ // state. We can't make a decision on whether the char in this buffer
+ // is unmappable or malformed without looking at the next input buffer.
+ assertEquals(1, buffer1.position());
+ assertTrue(encoder.encode(buffer2, out, true).isUnmappable());
+ assertEquals(0, buffer2.position());
+ }
+
+ public void testEncodeMapping() throws CharacterCodingException {
+ encoder.reset();
+
+ for (int i = 0; i <= MAXCODEPOINT; i++) {
+ char[] chars = Character.toChars(i);
+ CharBuffer cb = CharBuffer.wrap(chars);
+ ByteBuffer bb = encoder.encode(cb);
+ assertEquals(i, bb.get(0));
+ }
+
+ CharBuffer cb = CharBuffer.wrap("\u0080");
+ try {
+ encoder.encode(cb);
+ } catch (UnmappableCharacterException e) {
+ //expected
+ }
+
+ cb = CharBuffer.wrap("\ud800");
+ try {
+ encoder.encode(cb);
+ } catch (MalformedInputException e) {
+ //expected
+ }
+
+ ByteBuffer bb = ByteBuffer.allocate(0x10);
+ cb = CharBuffer.wrap("A");
+ encoder.reset();
+ encoder.encode(cb, bb, false);
+ try {
+ encoder.encode(cb);
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+
+ public void testInternalState() {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+
+ //normal encoding process
+ encoder.reset();
+ encoder.encode(in, out, false);
+ in = CharBuffer.wrap("B");
+ encoder.encode(in, out, true);
+ encoder.flush(out);
+ }
+
+ //reset could be called at any time
+ public void testInternalState_Reset() {
+ CharsetEncoder newEncoder = cs.newEncoder();
+ //Init - > reset
+ newEncoder.reset();
+
+ //reset - > reset
+ newEncoder.reset();
+
+ //encoding - >reset
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, false);
+ newEncoder.reset();
+ }
+
+ //encoding end -> reset
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ newEncoder.reset();
+ }
+ //flused -> reset
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ newEncoder.flush(out);
+ newEncoder.reset();
+ }
+ }
+
+ public void testInternalState_Encoding() {
+ CharsetEncoder newEncoder = cs.newEncoder();
+ //Init - > encoding
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, false);
+ }
+
+ //reset - > encoding
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.reset();
+ newEncoder.encode(in, out, false);
+ }
+ //reset - > encoding - > encoding
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, false);
+ in = CharBuffer.wrap("BC");
+ newEncoder.encode(in, out, false);
+ }
+
+ //encoding_end - > encoding
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ in = CharBuffer.wrap("BC");
+ try {
+ newEncoder.encode(in, out, false);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+ //flushed - > encoding
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ newEncoder.flush(out);
+ in = CharBuffer.wrap("BC");
+ try {
+ newEncoder.encode(in, out, false);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+ }
+
+ public void testInternalState_Encoding_END() {
+ CharsetEncoder newEncoder = cs.newEncoder();
+
+ //Init - >encoding_end
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ }
+
+ //Reset -> encoding_end
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.reset();
+ newEncoder.encode(in, out, true);
+ }
+
+ //encoding -> encoding_end
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, false);
+ in = CharBuffer.wrap("BC");
+ newEncoder.encode(in, out, true);
+ }
+
+ //Reset -> encoding_end
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ in = CharBuffer.wrap("BC");
+ newEncoder.encode(in, out, true);
+ }
+
+ //Flushed -> encoding_end
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ newEncoder.flush(out);
+ in = CharBuffer.wrap("BC");
+ try {
+ newEncoder.encode(in, out, true);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+ }
+
+ public void testInternalState_Flushed() {
+ CharsetEncoder newEncoder = cs.newEncoder();
+
+ // init -> flushed
+ {
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ try {
+ newEncoder.flush(out);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ }
+
+ // reset - > flushed
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ newEncoder.reset();
+ try {
+ newEncoder.flush(out);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+
+ //encoding - > flushed
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, false);
+ try {
+
+ newEncoder.flush(out);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ //encoding_end -> flushed
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ newEncoder.flush(out);
+ }
+
+ //flushd - > flushed
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ newEncoder.flush(out);
+ newEncoder.flush(out);
+ }
+ }
+
+ public void testInternalState_Encode() throws CharacterCodingException {
+ CharsetEncoder newEncoder = cs.newEncoder();
+ //Init - > encode
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ newEncoder.encode(in);
+ }
+
+ //Reset - > encode
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ newEncoder.encode(in);
+ }
+
+ //Encoding -> encode
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, false);
+ in = CharBuffer.wrap("BC");
+ newEncoder.encode(in);
+ }
+
+ //Encoding_end -> encode
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ in = CharBuffer.wrap("BC");
+ newEncoder.encode(in);
+ }
+
+ //Flushed -> reset
+ {
+ newEncoder.reset();
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.encode(in, out, true);
+ in = CharBuffer.wrap("BC");
+ newEncoder.flush(out);
+ out = newEncoder.encode(in);
+ }
+ }
+
+ public void testInternalState_from_Encode() throws CharacterCodingException {
+ CharsetEncoder newEncoder = cs.newEncoder();
+
+ //Encode -> Reset
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ newEncoder.encode(in);
+ newEncoder.reset();
+ }
+
+ // Encode -> encoding
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ newEncoder.encode(in);
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ try {
+ newEncoder.encode(in, out, false);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ //Encode -> Encoding_end
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = ByteBuffer.allocate(0x10);
+ newEncoder.reset();
+ newEncoder.encode(in, out, false);
+ newEncoder.encode(in, out, true);
+ }
+
+ //Encode -> Flushed
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ ByteBuffer out = newEncoder.encode(in);
+ newEncoder.flush(out);
+ }
+
+ //Encode - > encode
+ {
+ CharBuffer in = CharBuffer.wrap("A");
+ newEncoder.encode(in);
+ in = CharBuffer.wrap("BC");
+ newEncoder.encode(in);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/AbstractCharsetTestCase.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/AbstractCharsetTestCase.java
new file mode 100644
index 0000000..536cbce
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/AbstractCharsetTestCase.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+
+import junit.framework.TestCase;
+
+/**
+ * Super class for concrete charset test suites.
+ */
+public abstract class AbstractCharsetTestCase extends TestCase {
+
+ // the canonical name of this charset
+ protected final String canonicalName;
+
+ // the aliases set
+ protected final String[] aliases;
+
+ // canEncode
+ protected final boolean canEncode;
+
+ // isRegistered
+ protected final boolean isRegistered;
+
+ // charset instance
+ protected Charset testingCharset;
+
+ /*
+ * Initialize the field "testingCharset" here.
+ *
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.testingCharset = Charset.forName(this.canonicalName);
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * Constructor for ConcreteCharsetTest.
+ *
+ */
+ public AbstractCharsetTestCase(String arg0, String canonicalName,
+ String[] aliases, boolean canEncode, boolean isRegistered) {
+ super(arg0);
+ this.canonicalName = canonicalName;
+ this.canEncode = canEncode;
+ this.isRegistered = isRegistered;
+ this.aliases = aliases;
+ }
+
+ /*
+ * Test canEncode.
+ */
+ public void testCanEncode() {
+ assertEquals(this.canEncode, this.testingCharset.canEncode());
+ }
+
+ /*
+ * Test isRegistered.
+ */
+ public void testIsRegistered() {
+ assertEquals(this.isRegistered, this.testingCharset.isRegistered());
+ }
+
+ /*
+ * Test name.
+ */
+ public void testName() {
+ assertEquals(this.canonicalName, this.testingCharset.name());
+ // assertEquals(this.canonicalName, this.testingCharset.displayName());
+ // assertEquals(this.canonicalName,
+ // this.testingCharset.displayName(null));
+ }
+
+ /*
+ * Test aliases.
+ */
+ public void testAliases() {
+ for (int i = 0; i < this.aliases.length; i++) {
+ Charset c = Charset.forName(this.aliases[i]);
+ assertEquals(this.canonicalName, c.name());
+ // TODO
+ // assertTrue(this.testingCharset.aliases().contains(this.aliases[i]));
+ }
+ }
+
+ /*
+ * Test the method encode(String) with null.
+ */
+ public void testEncode_String_Null() {
+ try {
+ this.testingCharset.encode((String) null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Test the method encode(CharBuffer) with null.
+ */
+ public void testEncode_CharBuffer_Null() {
+ try {
+ this.testingCharset.encode((CharBuffer) null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Test encoding.
+ */
+ protected void internalTestEncode(String input, byte[] output) {
+ ByteBuffer bb = this.testingCharset.encode(input);
+ int i = 0;
+ bb.rewind();
+ while (bb.hasRemaining() && i < output.length) {
+ assertEquals(output[i], bb.get());
+ i++;
+ }
+ assertFalse(bb.hasRemaining());
+ assertEquals(output.length, i);
+ }
+
+ /*
+ * Test encoding.
+ */
+ public abstract void testEncode_Normal();
+
+ /*
+ * Test decoding.
+ */
+ protected void internalTestDecode(byte[] input, char[] output) {
+ CharBuffer chb = this.testingCharset.decode(ByteBuffer.wrap(input));
+ int i = 0;
+ chb.rewind();
+ while (chb.hasRemaining() && i < output.length) {
+ assertEquals(output[i], chb.get());
+ i++;
+ }
+ assertFalse(chb.hasRemaining());
+ assertEquals(output.length, i);
+ }
+
+ /*
+ * Test decoding.
+ */
+ public abstract void testDecode_Normal();
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharacterCodingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharacterCodingExceptionTest.java
new file mode 100644
index 0000000..aa69959
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharacterCodingExceptionTest.java
@@ -0,0 +1,53 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.IOException;
+import java.nio.charset.CharacterCodingException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Test CharacterCodingException
+ */
+public class CharacterCodingExceptionTest extends TestCase {
+
+ public void testConstructor() {
+ CharacterCodingException ex = new CharacterCodingException();
+ assertTrue(ex instanceof IOException);
+ assertNull(ex.getCause());
+ assertNull(ex.getMessage());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new CharacterCodingException());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ SerializationTest.verifyGolden(this, new CharacterCodingException());
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetDecoder2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetDecoder2Test.java
new file mode 100644
index 0000000..1fd61df
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetDecoder2Test.java
@@ -0,0 +1,279 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.IOException;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderMalfunctionError;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+public class CharsetDecoder2Test extends TestCase {
+
+ /**
+ * @tests java.nio.charset.CharsetDecoder.CharsetDecoder(Charset, float,
+ * float)
+ */
+ public void test_ConstructorLjava_nio_charset_CharsetFF() {
+ // Regression for HARMONY-142
+ try {
+ Charset cs = Charset.forName("UTF-8"); //$NON-NLS-1$
+ new MockCharsetDecoderForHarmony142(cs, 1.1f, 1);
+ fail("Assert 0: Should throw IllegalArgumentException."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /*
+ * MockCharsetDecoderForHarmony142: for constructor test
+ */
+ static class MockCharsetDecoderForHarmony142 extends CharsetDecoder {
+ protected MockCharsetDecoderForHarmony142(Charset cs,
+ float averageBytesPerChar, float maxBytesPerChar) {
+ super(cs, averageBytesPerChar, maxBytesPerChar);
+ }
+
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+ return null;
+ }
+ }
+
+ /**
+ * @tests java.nio.charset.CharsetDecoder#decode(java.nio.ByteBuffer)
+ */
+ public void test_decode() throws CharacterCodingException {
+ // Regression for HARMONY-33
+// ByteBuffer bb = ByteBuffer.allocate(1);
+// bb.put(0, (byte) 77);
+// CharsetDecoder decoder = Charset.forName("UTF-16").newDecoder();
+// decoder.onMalformedInput(CodingErrorAction.REPLACE);
+// decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+// decoder.decode(bb);
+
+ // Regression for HARMONY-67
+// byte[] b = new byte[] { (byte) 1 };
+// ByteBuffer buf = ByteBuffer.wrap(b);
+// CharBuffer charbuf = Charset.forName("UTF-16").decode(buf);
+// assertEquals("Assert 0: charset UTF-16", 1, charbuf.length());
+//
+// charbuf = Charset.forName("UTF-16BE").decode(buf);
+// assertEquals("Assert 1: charset UTF-16BE", 0, charbuf.length());
+//
+// charbuf = Charset.forName("UTF-16LE").decode(buf);
+// assertEquals("Assert 2: charset UTF16LE", 0, charbuf.length());
+
+ // Regression for HARMONY-99
+ CharsetDecoder decoder2 = Charset.forName("UTF-16").newDecoder();
+ decoder2.onMalformedInput(CodingErrorAction.REPORT);
+ decoder2.onUnmappableCharacter(CodingErrorAction.REPORT);
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 109, 97, 109 });
+ try {
+ decoder2.decode(in);
+ fail("Assert 3: MalformedInputException should have thrown");
+ } catch (MalformedInputException e) {
+ //expected
+ }
+ }
+
+ /*
+ * Test malfunction decode(ByteBuffer)
+ */
+ public void test_decodeLjava_nio_ByteBuffer() throws Exception {
+ MockMalfunctionCharset cs1 = new MockMalfunctionCharset(
+ "Harmony-124-1", null); //$NON-NLS-1$
+ try {
+ cs1.newDecoder().onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE).decode(
+ ByteBuffer.wrap(new byte[] { 0x00, 0x11 }));
+ fail("Assert 0: should throw CoderMalfunctionError"); // NON-NLS-1$
+ } catch (CoderMalfunctionError e) {
+ // expected
+ }
+
+ MockMalfunctionCharset cs2 = new MockMalfunctionCharset(
+ "Harmony-124-2", null); //$NON-NLS-1$
+ try {
+ cs2.decode(ByteBuffer.wrap(new byte[] { 0x00, 0x11 }));
+ fail("Assert 1: Charset.decode should throw CoderMalfunctionError"); // NON-NLS-1
+ } catch (CoderMalfunctionError e) {
+ // expected
+ }
+ }
+
+ /*
+ * Mock charset class with malfunction decode & encode.
+ */
+ static final class MockMalfunctionCharset extends Charset {
+
+ public MockMalfunctionCharset(String canonicalName, String[] aliases) {
+ super(canonicalName, aliases);
+ }
+
+ public boolean contains(Charset cs) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new MockMalfunctionDecoder(this);
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new MockMalfunctionEncoder(this);
+ }
+ }
+
+ /*
+ * Mock decoder. decodeLoop always throws unexpected exception.
+ */
+ static class MockMalfunctionDecoder extends java.nio.charset.CharsetDecoder {
+
+ public MockMalfunctionDecoder(Charset cs) {
+ super(cs, 1, 10);
+ }
+
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+ throw new BufferOverflowException();
+ }
+ }
+
+ /*
+ * Mock encoder. encodeLoop always throws unexpected exception.
+ */
+ static class MockMalfunctionEncoder extends java.nio.charset.CharsetEncoder {
+
+ public MockMalfunctionEncoder(Charset cs) {
+ super(cs, 1, 3, new byte[] { (byte) '?' });
+ }
+
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+ throw new BufferOverflowException();
+ }
+ }
+
+ /*
+ * Test the method decode(ByteBuffer) .
+ */
+ public void testDecodeLjava_nio_ByteBuffer_ReplaceOverflow()
+ throws Exception {
+ String replaceString = "a";
+ Charset cs = Charset.forName("UTF-8");
+ MockMalformedDecoder decoder = new MockMalformedDecoder(cs);
+ decoder.onMalformedInput(CodingErrorAction.REPLACE);
+ decoder.replaceWith(replaceString);
+ CharBuffer out = CharBuffer.allocate(1);
+ // MockMalformedDecoder treats the second byte '0x38' as malformed,
+ // but "out" doesn't have enough space for replace string.
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 0x45, 0x38, 0x45, 0x45 });
+ CoderResult result = decoder.decode(in, out, false);
+ assertTrue(result.isOverflow());
+
+ // allocate enough space for "out"
+ out = CharBuffer.allocate(10);
+ // replace string should be put into "out" firstly,
+ // and then decode "in".
+ result = decoder.decode(in, out, true);
+ out.flip();
+ assertTrue(result.isUnderflow());
+ assertEquals("bb", out.toString());
+ }
+
+ /*
+ * Mock decoder. It treats byte whose value is less than "0x40" as
+ * malformed.
+ */
+ static class MockMalformedDecoder extends java.nio.charset.CharsetDecoder {
+
+ public MockMalformedDecoder(Charset cs) {
+ super(cs, 1, 10);
+ }
+
+ /*
+ * It treats byte whose value is less than "0x40" as malformed.
+ * Otherwise, it's decoded as 'b'.
+ */
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+ while (in.hasRemaining()) {
+ byte b = in.get();
+ if (b < 0x40) {
+ return CoderResult.malformedForLength(1);
+ }
+ if (!out.hasRemaining()) {
+ return CoderResult.OVERFLOW;
+ }
+ out.put((char) 'b');
+ }
+ return CoderResult.UNDERFLOW;
+ }
+ }
+
+
+ public void testInvalidDecoding() throws IOException {
+
+ byte[][] invalidSequences = new byte[][] {
+ // overlong NULL
+ { (byte) 0xC0, (byte) 0x80 },
+ // overlong ascii 'A'
+ { (byte) 0xC0, (byte) 0xC1 },
+ // overlong "/../"
+ { (byte) 0x2F, (byte) 0xC0, (byte) 0xAE, (byte) 0x2E, (byte) 0x2F },
+ // Invalid encoding 2r11111000 (sequence too long)
+ { (byte) 0xF8 },
+ // Invalid encoding 2r10000000 (sequence too short)
+ { (byte) 0x80 }
+ };
+
+ CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+
+ /*
+ * When bytebuffer has a backing array...
+ */
+ for (byte[] bytes : invalidSequences) {
+ try {
+ CharBuffer cb = decoder.decode(ByteBuffer.wrap(bytes));
+ fail("No exception thrown on " + Arrays.toString(bytes) + " '" + cb + "'");
+ } catch (MalformedInputException expected) {
+ }
+ }
+
+ /*
+ * When bytebuffer has _not_ got a backing array...
+ */
+ for (byte[] bytes : invalidSequences) {
+ try {
+ ByteBuffer bb = ByteBuffer.allocateDirect(8);
+ bb.put(bytes).flip();
+ CharBuffer cb = decoder.decode(bb);
+ fail("No exception thrown on " + Arrays.toString(bytes) + " '" + cb + "'");
+ } catch (MalformedInputException expected) {
+ }
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetDecoderTest.java
new file mode 100644
index 0000000..e64b2b9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetDecoderTest.java
@@ -0,0 +1,875 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+
+import junit.framework.TestCase;
+
+/**
+ * API unit test for java.nio.CharsetDecoder
+ */
+public class CharsetDecoderTest extends TestCase {
+
+ protected static final int MAX_BYTES = 3;
+
+ protected static final double AVER_BYTES = 0.5;
+
+ // default charset
+ private static final Charset MOCKCS = new CharsetEncoderTest.MockCharset(
+ "mock", new String[0]);
+
+ Charset cs = MOCKCS;
+
+ // default decoder
+ protected static CharsetDecoder decoder;
+
+ String bom = "";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ decoder = cs.newDecoder();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // FIXME: give up this tests
+ // /*
+ // * test default value
+ // */
+ // public void testDefaultCharsPerByte() {
+ // assertTrue(decoder.averageCharsPerByte() == AVER_BYTES);
+ // assertTrue(decoder.maxCharsPerByte() == MAX_BYTES);
+ // }
+
+ public void testDefaultValues() {
+ assertSame(cs, decoder.charset());
+ try {
+ decoder.detectedCharset();
+ fail("should unsupported");
+ } catch (UnsupportedOperationException e) {
+ }
+ try {
+ assertTrue(decoder.isCharsetDetected());
+ fail("should unsupported");
+ } catch (UnsupportedOperationException e) {
+ }
+ assertFalse(decoder.isAutoDetecting());
+ assertSame(CodingErrorAction.REPORT, decoder.malformedInputAction());
+ assertSame(CodingErrorAction.REPORT, decoder
+ .unmappableCharacterAction());
+ assertEquals(decoder.replacement(), "\ufffd");
+ }
+
+ /*
+ * test constructor
+ */
+ public void testCharsetDecoder() {
+ // default value
+ decoder = new MockCharsetDecoder(cs, (float) AVER_BYTES, MAX_BYTES);
+
+ // normal case
+ CharsetDecoder ec = new MockCharsetDecoder(cs, 1, MAX_BYTES);
+ assertSame(ec.charset(), cs);
+ assertEquals(1.0, ec.averageCharsPerByte(), 0.0);
+ assertTrue(ec.maxCharsPerByte() == MAX_BYTES);
+
+ /*
+ * ------------------------ Exceptional cases -------------------------
+ */
+ // Normal case: null charset
+ ec = new MockCharsetDecoder(null, 1, MAX_BYTES);
+ assertNull(ec.charset());
+ assertEquals(1.0, ec.averageCharsPerByte(), 0.0);
+ assertTrue(ec.maxCharsPerByte() == MAX_BYTES);
+
+ ec = new MockCharsetDecoder(new CharsetEncoderTest.MockCharset("mock",
+ new String[0]), 1, MAX_BYTES);
+
+ // Commented out since the comment is wrong since MAX_BYTES > 1
+ // // OK: average length less than max length
+ // ec = new MockCharsetDecoder(cs, MAX_BYTES, 1);
+ // assertTrue(ec.averageCharsPerByte() == MAX_BYTES);
+ // assertTrue(ec.maxCharsPerByte() == 1);
+
+ // Illegal Argument: zero length
+ try {
+ ec = new MockCharsetDecoder(cs, 0, MAX_BYTES);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ec = new MockCharsetDecoder(cs, 1, 0);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // Illegal Argument: negative length
+ try {
+ ec = new MockCharsetDecoder(cs, -1, MAX_BYTES);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ec = new MockCharsetDecoder(cs, 1, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /*
+ * test onMalformedInput
+ */
+ public void testOnMalformedInput() {
+ assertSame(CodingErrorAction.REPORT, decoder.malformedInputAction());
+ try {
+ decoder.onMalformedInput(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ decoder.onMalformedInput(CodingErrorAction.IGNORE);
+ assertSame(CodingErrorAction.IGNORE, decoder.malformedInputAction());
+ }
+
+ /*
+ * test unmappableCharacter
+ */
+ public void testOnUnmappableCharacter() {
+ assertSame(CodingErrorAction.REPORT, decoder
+ .unmappableCharacterAction());
+ try {
+ decoder.onUnmappableCharacter(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ assertSame(CodingErrorAction.IGNORE, decoder
+ .unmappableCharacterAction());
+ }
+
+ /*
+ * test replaceWith
+ */
+ public void testReplaceWith() {
+ try {
+ decoder.replaceWith(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ decoder.replaceWith("");
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ decoder.replaceWith("testReplaceWith");
+ fail("should throw illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+
+ decoder.replaceWith("a");
+ assertSame("a", decoder.replacement());
+ }
+
+ /*
+ * Class under test for CharBuffer decode(ByteBuffer)
+ */
+ public void testDecodeByteBuffer() throws CharacterCodingException {
+ implTestDecodeByteBuffer();
+ }
+
+ void implTestDecodeByteBuffer() throws CharacterCodingException {
+ // Null pointer
+ try {
+ decoder.decode(null);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+
+ // empty input buffer
+ CharBuffer out = decoder.decode(ByteBuffer.allocate(0));
+ assertCharBufferValue("", out);
+
+ // normal case
+ ByteBuffer in = getByteBuffer();
+ out = decoder.decode(in);
+ assertEquals(0, out.position());
+ assertEquals(getString().length(), out.limit());
+ assertEquals(getString().length(), out.remaining());
+ assertCharBufferValue(getString(), out);
+
+ // normal read only case
+ in = getByteBuffer().asReadOnlyBuffer();
+ out = decoder.decode(in);
+ assertEquals(out.position(), 0);
+ assertEquals(out.limit(), getString().length());
+ assertEquals(out.remaining(), getString().length());
+ assertCharBufferValue(getString(), out);
+ }
+
+ public void testDecodeByteBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ CharBuffer out;
+ ByteBuffer in;
+ String replaceStr = decoder.replacement() + getString();
+
+ // MalformedException:
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ in = getMalformedByteBuffer();
+ if (in != null) {
+ try {
+ CharBuffer buffer = decoder.decode(in);
+ assertTrue(buffer.remaining() > 0);
+ fail("should throw MalformedInputException");
+ } catch (MalformedInputException e) {
+ }
+
+ decoder.reset();
+ in.rewind();
+ decoder.onMalformedInput(CodingErrorAction.IGNORE);
+ out = decoder.decode(in);
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ in.rewind();
+ decoder.onMalformedInput(CodingErrorAction.REPLACE);
+ out = decoder.decode(in);
+ assertCharBufferValue(replaceStr, out);
+ }
+
+ // Unmapped Exception:
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ in = getUnmappedByteBuffer();
+ if (in != null) {
+ try {
+ decoder.decode(in);
+ fail("should throw UnmappableCharacterException");
+ } catch (UnmappableCharacterException e) {
+ }
+
+ decoder.reset();
+ in.rewind();
+ decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ out = decoder.decode(in);
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ in.rewind();
+ decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ out = decoder.decode(in);
+ assertCharBufferValue(replaceStr, out);
+ }
+
+ // RuntimeException
+ try {
+ decoder.decode(getExceptionByteArray());
+ fail("should throw runtime exception");
+ } catch (RuntimeException e) {
+ }
+ }
+
+ /*
+ * Class under test for CoderResult decode(ByteBuffer, CharBuffer, boolean)
+ */
+ public void testDecodeByteBufferCharBuffer() {
+ implTestDecodeByteBufferCharBuffer(getByteBuffer());
+ }
+
+ public void testDecodeByteBufferCharBufferReadOnly() {
+ implTestDecodeByteBufferCharBuffer(getByteBuffer());
+ }
+
+ void implTestDecodeByteBufferCharBuffer(ByteBuffer in) {
+ CharBuffer out = CharBuffer.allocate(100);
+
+ // Null pointer
+ decoder.reset();
+ try {
+ decoder.decode(null, out, true);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ }
+ try {
+ decoder.decode(in, null, true);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ }
+
+ // normal case, one complete operation
+ decoder.reset();
+ in.rewind();
+ out.rewind();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
+ assertEquals(out.limit(), 100);
+ assertEquals(out.position(), getString().length());
+ assertEquals(out.remaining(), 100 - getString().length());
+ assertEquals(out.capacity(), 100);
+ assertCharBufferValue(getString(), out);
+ decoder.flush(out);
+
+ // normal case, one complete operation, but call twice, first time set
+ // endOfInput to false
+ decoder.reset();
+ in.rewind();
+ out.clear();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
+ assertEquals(out.limit(), 100);
+ assertEquals(out.position(), getString().length());
+ assertEquals(out.remaining(), 100 - getString().length());
+ assertEquals(out.capacity(), 100);
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ in.rewind();
+ out.clear();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
+ in = getHeadlessByteBuffer();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
+ in.rewind();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
+ assertEquals(out.limit(), 100);
+ assertTrue(out.position() > 0);
+ assertEquals(out.remaining(), out.capacity() - out.position());
+ assertEquals(out.capacity(), 100);
+ assertCharBufferValue(getString() + getString() + getString(), out);
+
+ // overflow
+ out = CharBuffer.allocate(4);
+ decoder.reset();
+ in = getByteBuffer();
+ out.rewind();
+ assertSame(CoderResult.OVERFLOW, decoder.decode(in, out, false));
+
+ assertCharBufferValue(getString().substring(0, 4), out);
+ out = CharBuffer.allocate(100);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
+ assertCharBufferValue(getString().substring(4), out);
+ in.rewind();
+ out = CharBuffer.allocate(100);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
+ assertCharBufferValue(bom + getString(), out);
+ }
+
+ public void testDecodeCharBufferByteBufferUnmappedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferUnmappedException(
+ getUnmappedByteBuffer(), true);
+ }
+
+ public void testDecodeCharBufferByteIncompleteBufferUnmappedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferUnmappedException(
+ getUnmappedByteBuffer(), false);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyBufferUnmappedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferUnmappedException(
+ readOnly(getUnmappedByteBuffer()), true);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyIncompleteBufferUnmappedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferUnmappedException(
+ readOnly(getUnmappedByteBuffer()), false);
+ }
+
+ void implTestDecodeCharBufferByteBufferUnmappedException(ByteBuffer in,
+ boolean endOfInput) throws CharacterCodingException,
+ UnsupportedEncodingException {
+ if (null == in) {
+ return;
+ }
+ CharBuffer out = CharBuffer.allocate(50);
+
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ decoder.reset();
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ CoderResult result = decoder.decode(in, out, endOfInput);
+ assertTrue(result.isUnmappable());
+
+ decoder.reset();
+ out.clear();
+ in.rewind();
+ decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ out.clear();
+ in.rewind();
+ decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
+ assertCharBufferValue(decoder.replacement() + getString(), out);
+ }
+
+ public void testDecodeCharBufferByteBufferMalformedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferMalformedException(
+ getMalformedByteBuffer(), true);
+ }
+
+ public void testDecodeCharBufferByteIncompleteBufferMalformedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+
+ implTestDecodeCharBufferByteBufferMalformedException(
+ getMalformedByteBuffer(), false);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyBufferMalformedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferMalformedException(
+ readOnly(getMalformedByteBuffer()), true);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyIncompleteBufferMalformedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferMalformedException(
+ readOnly(getMalformedByteBuffer()), false);
+ }
+
+ void implTestDecodeCharBufferByteBufferMalformedException(ByteBuffer in,
+ boolean endOfInput) throws CharacterCodingException,
+ UnsupportedEncodingException {
+ if (null == in) {
+ return;
+ }
+ CharBuffer out = CharBuffer.allocate(getString().length() * 3);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ decoder.reset();
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ CoderResult result = decoder.decode(in, out, endOfInput);
+ assertTrue(result.isMalformed());
+
+ decoder.reset();
+ out.clear();
+ in.rewind();
+ decoder.onMalformedInput(CodingErrorAction.IGNORE);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ out.clear();
+ in.rewind();
+ decoder.onMalformedInput(CodingErrorAction.REPLACE);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
+ assertCharBufferValue(decoder.replacement() + getString(), out);
+ }
+
+ public void testDecodeCharBufferByteBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferException(getExceptionByteArray(),
+ true);
+ }
+
+ public void testDecodeCharBufferByteIncompleteBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferException(getExceptionByteArray(),
+ false);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferException(
+ readOnly(getExceptionByteArray()), true);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyIncompleteBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferException(
+ readOnly(getExceptionByteArray()), false);
+ }
+
+ void implTestDecodeCharBufferByteBufferException(ByteBuffer in,
+ boolean endOfInput) throws CharacterCodingException,
+ UnsupportedEncodingException {
+ CharBuffer out = CharBuffer.allocate(50);
+ decoder.reset();
+ try {
+ decoder.decode(in, out, endOfInput);
+ fail("should throw runtime exception");
+ } catch (RuntimeException e) {
+ }
+ }
+
+ private ByteBuffer readOnly(ByteBuffer b) {
+ if (null == b) {
+ return null;
+ }
+ return b.asReadOnlyBuffer();
+ }
+
+ protected String getString() {
+ return " buffer";
+ }
+
+ protected ByteBuffer getByteBuffer() {
+ return ByteBuffer.wrap(new byte[] { 32, 98, 117, 102, 102, 101, 114 });
+ }
+
+ protected ByteBuffer getHeadlessByteBuffer() {
+ return getByteBuffer();
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ // "runtime"
+ return ByteBuffer
+ .wrap(new byte[] { 114, 117, 110, 116, 105, 109, 101 });
+ }
+
+ ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
+ // "unmap buffer"
+ byte[] ba = new byte[] { 117, 110, 109, 97, 112, 32, 98, 117, 102, 102,
+ 101, 114 };
+ return ByteBuffer.wrap(ba);
+ }
+
+ ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
+ // "malform buffer"
+ byte[] ba = new byte[] { 109, 97, 108, 102, 111, 114, 109, 32, 98, 117,
+ 102, 102, 101, 114 };
+ return ByteBuffer.wrap(ba);
+ }
+
+ private void assertCharBufferValue(String expected, CharBuffer out) {
+ if (out.position() != 0) {
+ out.flip();
+ }
+ assertEquals(expected, new String(out.array(), out.arrayOffset(), out
+ .arrayOffset() + out.limit()));
+ }
+
+ /*
+ * test flush
+ */
+ public void testFlush() throws CharacterCodingException {
+ CharBuffer out = CharBuffer.allocate(10);
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 12, 12 });
+ decoder.decode(in, out, true);
+ assertSame(CoderResult.UNDERFLOW, decoder.flush(out));
+
+ decoder.reset();
+ decoder.decode((ByteBuffer) in.rewind(), (CharBuffer) out.rewind(),
+ true);
+ assertSame(CoderResult.UNDERFLOW, decoder
+ .flush(CharBuffer.allocate(10)));
+ }
+
+ /*
+ * ---------------------------------- methods to test illegal state
+ * -----------------------------------
+ */
+ // Normal case: just after reset, and it also means reset can be done
+ // anywhere
+ public void testResetIllegalState() throws CharacterCodingException {
+ decoder.reset();
+ decoder.decode(getByteBuffer());
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(3), false);
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(3), true);
+ decoder.reset();
+ }
+
+ public void testFlushIllegalState() throws CharacterCodingException {
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
+ CharBuffer out = CharBuffer.allocate(5);
+
+ // Illegal state: after reset.
+ decoder.reset();
+ try {
+ decoder.flush(out);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ // Normal case: after decode with endOfInput is true
+ decoder.reset();
+ decoder.decode(in, out, true);
+ out.rewind();
+ CoderResult result = decoder.flush(out);
+ assertSame(result, CoderResult.UNDERFLOW);
+
+ // Good state: flush twice
+ decoder.flush(out);
+
+ // Illegal state: flush after decode with endOfInput is false
+ decoder.reset();
+ decoder.decode(in, out, false);
+ try {
+ decoder.flush(out);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ // test illegal states for decode facade
+ public void testDecodeFacadeIllegalState() throws CharacterCodingException {
+ // decode facade can be execute in anywhere
+ ByteBuffer in = getByteBuffer();
+
+ // Normal case: just created
+ decoder.decode(in);
+ in.rewind();
+
+ // Normal case: just after decode facade
+ decoder.decode(in);
+ in.rewind();
+
+ // Normal case: just after decode with that endOfInput is true
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(30), true);
+ decoder.decode(in);
+ in.rewind();
+
+ // Normal case:just after decode with that endOfInput is false
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(30), false);
+ decoder.decode(in);
+ in.rewind();
+
+ // Normal case: just after flush
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(30), true);
+ decoder.flush(CharBuffer.allocate(10));
+ decoder.decode(in);
+ in.rewind();
+ }
+
+ // test illegal states for two decode method with endOfInput is true
+ public void testDecodeTrueIllegalState() throws CharacterCodingException {
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
+ CharBuffer out = CharBuffer.allocate(100);
+ // Normal case: just created
+ decoder.decode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ // Normal case: just after decode with that endOfInput is true
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), true);
+ in.rewind();
+ decoder.decode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ // Normal case:just after decode with that endOfInput is false
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), false);
+ in.rewind();
+ decoder.decode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after flush
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), true);
+ decoder.flush(CharBuffer.allocate(10));
+ in.rewind();
+ try {
+ decoder.decode(in, out, true);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+ in.rewind();
+ out.rewind();
+
+ }
+
+ // test illegal states for two decode method with endOfInput is false
+ public void testDecodeFalseIllegalState() throws CharacterCodingException {
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
+ CharBuffer out = CharBuffer.allocate(5);
+ // Normal case: just created
+ decoder.decode(in, out, false);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after decode facade
+ decoder.reset();
+ decoder.decode(in);
+ in.rewind();
+ try {
+ decoder.decode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after decode with that endOfInput is true
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), true);
+ in.rewind();
+ try {
+ decoder.decode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+ in.rewind();
+ out.rewind();
+
+ // Normal case:just after decode with that endOfInput is false
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), false);
+ in.rewind();
+ decoder.decode(in, out, false);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after flush
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), true);
+ in.rewind();
+ decoder.flush(CharBuffer.allocate(10));
+ try {
+ decoder.decode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+ }
+
+ /*
+ * --------------------------------- illegal state test end
+ * ---------------------------------
+ */
+
+ public void testImplFlush() {
+ decoder = new MockCharsetDecoder(cs, 1, 3);
+ assertEquals(CoderResult.UNDERFLOW, ((MockCharsetDecoder) decoder)
+ .pubImplFlush(null));
+ }
+
+ public void testImplOnMalformedInput() {
+ decoder = new MockCharsetDecoder(cs, 1, 3);
+ assertEquals(CoderResult.UNDERFLOW, ((MockCharsetDecoder) decoder)
+ .pubImplFlush(null));
+
+ }
+
+ public void testImplOnUnmappableCharacter() {
+ decoder = new MockCharsetDecoder(cs, 1, 3);
+ ((MockCharsetDecoder) decoder).pubImplOnUnmappableCharacter(null);
+ }
+
+ public void testImplReplaceWith() {
+ decoder = new MockCharsetDecoder(cs, 1, 3);
+ ((MockCharsetDecoder) decoder).pubImplReplaceWith(null);
+ }
+
+ public void testImplReset() {
+ decoder = new MockCharsetDecoder(cs, 1, 3);
+ ((MockCharsetDecoder) decoder).pubImplReset();
+ }
+
+ /*
+ * mock decoder
+ */
+ public static class MockCharsetDecoder extends CharsetDecoder {
+ public MockCharsetDecoder(Charset cs, float ave, float max) {
+ super(cs, ave, max);
+ }
+
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+ int inPosition = in.position();
+ byte[] input = new byte[in.remaining()];
+ in.get(input);
+ String result;
+ try {
+ result = new String(input, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError(e);
+ }
+ if (result.startsWith("malform")) {
+ // reset the cursor to the error position
+ in.position(inPosition);
+ // set the error length
+ return CoderResult.malformedForLength("malform".length());
+ } else if (result.startsWith("unmap")) {
+ // reset the cursor to the error position
+ in.position(inPosition);
+ // set the error length
+ return CoderResult.unmappableForLength("unmap".length());
+ } else if (result.startsWith("runtime")) {
+ // reset the cursor to the error position
+ in.position(0);
+ // set the error length
+ throw new RuntimeException("runtime");
+ }
+ int inLeft = input.length;
+ int outLeft = out.remaining();
+ CoderResult r = CoderResult.UNDERFLOW;
+ int length = inLeft;
+ if (outLeft < inLeft) {
+ r = CoderResult.OVERFLOW;
+ length = outLeft;
+ in.position(inPosition + outLeft);
+ }
+ for (int i = 0; i < length; i++) {
+ out.put((char) input[i]);
+ }
+ return r;
+ }
+
+ protected CoderResult implFlush(CharBuffer out) {
+ CoderResult result = super.implFlush(out);
+ if (out.remaining() >= 5) {
+ // TODO
+ // out.put("flush");
+ result = CoderResult.UNDERFLOW;
+ } else {
+ // out.put("flush", 0, out.remaining());
+ result = CoderResult.OVERFLOW;
+ }
+ return result;
+ }
+
+ public CoderResult pubImplFlush(CharBuffer out) {
+ return super.implFlush(out);
+ }
+
+ public void pubImplOnMalformedInput(CodingErrorAction newAction) {
+ super.implOnMalformedInput(newAction);
+ }
+
+ public void pubImplOnUnmappableCharacter(CodingErrorAction newAction) {
+ super.implOnUnmappableCharacter(newAction);
+ }
+
+ public void pubImplReplaceWith(String newReplacement) {
+ super.implReplaceWith(newReplacement);
+ }
+
+ public void pubImplReset() {
+ super.implReset();
+ }
+
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetEncoder2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetEncoder2Test.java
new file mode 100644
index 0000000..9884625
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetEncoder2Test.java
@@ -0,0 +1,212 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.IOException;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderMalfunctionError;
+import java.nio.charset.CoderResult;
+
+import junit.framework.TestCase;
+
+public class CharsetEncoder2Test extends TestCase {
+
+ /**
+ * @tests java.nio.charset.CharsetEncoder.CharsetEncoder(
+ * java.nio.charset.Charset, float, float)
+ */
+ public void test_ConstructorLjava_nio_charset_CharsetFF() {
+ // Regression for HARMONY-141
+ try {
+ Charset cs = Charset.forName("UTF-8"); //$NON-NLS-1$
+ new MockCharsetEncoderForHarmony141(cs, 1.1f, 1);
+ fail("Assert 0: Should throw IllegalArgumentException."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ Charset cs = Charset.forName("ISO8859-1"); //$NON-NLS-1$
+ new MockCharsetEncoderForHarmony141(cs, 1.1f, 1,
+ new byte[] { 0x1a });
+ fail("Assert 1: Should throw IllegalArgumentException."); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.nio.charset.CharsetEncoder.CharsetEncoder(
+ * java.nio.charset.Charset, float, float)
+ */
+ public void test_ConstructorLjava_nio_charset_CharsetNull() {
+ // Regression for HARMONY-491
+ CharsetEncoder ech = new MockCharsetEncoderForHarmony491(null, 1, 1);
+ assertNull(ech.charset());
+ }
+
+ /**
+ * Helper for constructor tests
+ */
+
+ public static class MockCharsetEncoderForHarmony141 extends CharsetEncoder {
+
+ protected MockCharsetEncoderForHarmony141(Charset cs,
+ float averageBytesPerChar, float maxBytesPerChar) {
+ super(cs, averageBytesPerChar, maxBytesPerChar);
+ }
+
+ public MockCharsetEncoderForHarmony141(Charset cs,
+ float averageBytesPerChar, float maxBytesPerChar,
+ byte[] replacement) {
+ super(cs, averageBytesPerChar, maxBytesPerChar, replacement);
+ }
+
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+ return null;
+ }
+ }
+
+ public static class MockCharsetEncoderForHarmony491 extends CharsetEncoder {
+
+ public MockCharsetEncoderForHarmony491(Charset arg0, float arg1,
+ float arg2) {
+ super(arg0, arg1, arg2);
+ }
+
+ protected CoderResult encodeLoop(CharBuffer arg0, ByteBuffer arg1) {
+ return null;
+ }
+
+ public boolean isLegalReplacement(byte[] arg0) {
+ return true;
+ }
+ }
+
+ /*
+ * Test malfunction encode(CharBuffer)
+ */
+ public void test_EncodeLjava_nio_CharBuffer() throws Exception {
+ MockMalfunctionCharset cs = new MockMalfunctionCharset("mock", null);
+ try {
+ cs.encode(CharBuffer.wrap("AB"));
+ fail("should throw CoderMalfunctionError");// NON-NLS-1$
+ } catch (CoderMalfunctionError e) {
+ // expected
+ }
+ }
+
+ /*
+ * Mock charset class with malfunction decode & encode.
+ */
+ static final class MockMalfunctionCharset extends Charset {
+
+ public MockMalfunctionCharset(String canonicalName, String[] aliases) {
+ super(canonicalName, aliases);
+ }
+
+ public boolean contains(Charset cs) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return Charset.forName("UTF-8").newDecoder();
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new MockMalfunctionEncoder(this);
+ }
+ }
+
+ /*
+ * Mock encoder. encodeLoop always throws unexpected exception.
+ */
+ static class MockMalfunctionEncoder extends java.nio.charset.CharsetEncoder {
+
+ public MockMalfunctionEncoder(Charset cs) {
+ super(cs, 1, 3, new byte[] { (byte) '?' });
+ }
+
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+ throw new BufferOverflowException();
+ }
+ }
+
+ /*
+ * Test reserve bytes encode(CharBuffer,ByteBuffer,boolean)
+ */
+ public void test_EncodeLjava_nio_CharBufferLjava_nio_ByteBufferB() throws Exception {
+ Charset utf8 = Charset.forName("utf-8");
+ CharsetEncoder encoder = utf8.newEncoder();
+ CharBuffer char1 = CharBuffer.wrap("\ud800");
+ CharBuffer char2 = CharBuffer.wrap("\udc00");
+ ByteBuffer bytes = ByteBuffer.allocate(4);
+ encoder.reset();
+
+ // If we supply just the high surrogate...
+ CoderResult result = encoder.encode(char1, bytes, false);
+ // ...we're not done...
+ assertTrue(result.isUnderflow());
+ assertEquals(4, bytes.remaining());
+ // ...but if we then supply the low surrogate...
+ result = encoder.encode(char2, bytes, true);
+ assertTrue(result.isUnderflow());
+ // ...we're done. Note that the RI loses its state in
+ // between the two characters, so it can't do this.
+ assertEquals(0, bytes.remaining());
+
+ // Did we get the UTF-8 for U+10000?
+ assertEquals(4, bytes.limit());
+ assertEquals((byte) 0xf0, bytes.get(0));
+ assertEquals((byte) 0x90, bytes.get(1));
+ assertEquals((byte) 0x80, bytes.get(2));
+ assertEquals((byte) 0x80, bytes.get(3));
+
+ // See what we got in the output buffer by decoding and checking that we
+ // get back the same surrogate pair.
+ bytes.flip();
+ CharBuffer chars = utf8.newDecoder().decode(bytes);
+ assertEquals(0, bytes.remaining());
+ assertEquals(2, chars.limit());
+ assertEquals(0xd800, chars.get(0));
+ assertEquals(0xdc00, chars.get(1));
+ }
+
+ /**
+ * @tests {@link java.nio.charset.Charset#encode(java.nio.CharBuffer)
+ */
+ public void testUtf8Encoding() throws IOException {
+ byte[] orig = new byte[] { (byte) 0xed, (byte) 0xa0,
+ (byte) 0x80 };
+ String s = new String(orig, "UTF-8");
+ assertEquals(1, s.length());
+ assertEquals(55296, s.charAt(0));
+ Charset.forName("UTF-8").encode(CharBuffer.wrap(s));
+// ByteBuffer buf = <result>
+// for (byte o : orig) {
+// byte b = 0;
+// buf.get(b);
+// assertEquals(o, b);
+// }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetEncoderTest.java
new file mode 100644
index 0000000..5226ed6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetEncoderTest.java
@@ -0,0 +1,1129 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+/**
+ * API unit test for java.nio.charset.CharsetEncoder
+ */
+public class CharsetEncoderTest extends TestCase {
+
+ static final int MAX_BYTES = 3;
+
+ static final float AVER_BYTES = 0.5f;
+
+ // charset for mock class
+ private static final Charset MOCKCS = new MockCharset("CharsetEncoderTest_mock", new String[0]);
+
+ Charset cs = MOCKCS;
+
+ // default encoder
+ CharsetEncoder encoder;
+
+ // default for Charset abstract class
+ byte[] defaultReplacement = new byte[] { 63 };
+
+ // specific for Charset implementation subclass
+ byte[] specifiedReplacement = new byte[] { 63 };
+
+ static final String unistr = " buffer";// \u8000\u8001\u00a5\u3000\r\n";
+
+ byte[] unibytes = new byte[] { 32, 98, 117, 102, 102, 101, 114 };
+
+ byte[] unibytesWithRep = null;
+
+ byte[] surrogate = new byte[0];
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ encoder = cs.newEncoder();
+ if (null == unibytesWithRep) {
+ byte[] replacement = encoder.replacement();
+ unibytesWithRep = new byte[replacement.length + unibytes.length];
+ System.arraycopy(replacement, 0, unibytesWithRep, 0,
+ replacement.length);
+ System.arraycopy(unibytes, 0, unibytesWithRep, replacement.length,
+ unibytes.length);
+ }
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testSpecificDefaultValue() {
+ assertTrue(encoder.averageBytesPerChar() == AVER_BYTES);
+ assertTrue(encoder.maxBytesPerChar() == MAX_BYTES);
+ }
+
+ public void testDefaultValue() {
+ assertEquals(CodingErrorAction.REPORT, encoder.malformedInputAction());
+ assertEquals(CodingErrorAction.REPORT, encoder.unmappableCharacterAction());
+ assertSame(encoder, encoder.onMalformedInput(CodingErrorAction.IGNORE));
+ assertSame(encoder, encoder.onUnmappableCharacter(CodingErrorAction.IGNORE));
+ if (encoder instanceof MockCharsetEncoder) {
+ assertTrue(Arrays.equals(encoder.replacement(), defaultReplacement));
+ } else {
+ assertTrue(Arrays.equals(encoder.replacement(), specifiedReplacement));
+ }
+
+ }
+
+ /*
+ * Class under test for constructor CharsetEncoder(Charset, float, float)
+ */
+ public void testCharsetEncoderCharsetfloatfloat() {
+ // default value
+ encoder = new MockCharsetEncoder(cs, (float) AVER_BYTES, MAX_BYTES);
+ assertSame(encoder.charset(), cs);
+ assertTrue(encoder.averageBytesPerChar() == AVER_BYTES);
+ assertTrue(encoder.maxBytesPerChar() == MAX_BYTES);
+ assertEquals(CodingErrorAction.REPORT, encoder.malformedInputAction());
+ assertEquals(CodingErrorAction.REPORT, encoder
+ .unmappableCharacterAction());
+ assertEquals(new String(encoder.replacement()), new String(
+ defaultReplacement));
+ assertSame(encoder, encoder.onMalformedInput(CodingErrorAction.IGNORE));
+ assertSame(encoder, encoder
+ .onUnmappableCharacter(CodingErrorAction.IGNORE));
+
+ // normal case
+ CharsetEncoder ec = new MockCharsetEncoder(cs, 1, MAX_BYTES);
+ assertSame(ec.charset(), cs);
+ assertEquals(1.0, ec.averageBytesPerChar(), 0);
+ assertTrue(ec.maxBytesPerChar() == MAX_BYTES);
+
+ /*
+ * ------------------------ Exceptional cases -------------------------
+ */
+ // NullPointerException: null charset
+ try {
+ ec = new MockCharsetEncoder(null, 1, MAX_BYTES);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+
+ ec = new MockCharsetEncoder(new MockCharset("mock", new String[0]), 1,
+ MAX_BYTES);
+
+ // Commented out since the comment is wrong since MAX_BYTES > 1
+ // // OK: average length less than max length
+ // ec = new MockCharsetEncoder(cs, MAX_BYTES, 1);
+ // assertTrue(ec.averageBytesPerChar() == MAX_BYTES);
+ // assertTrue(ec.maxBytesPerChar() == 1);
+
+ // Illegal Argument: zero length
+ try {
+ ec = new MockCharsetEncoder(cs, 0, MAX_BYTES);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ec = new MockCharsetEncoder(cs, 1, 0);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // Illegal Argument: negative length
+ try {
+ ec = new MockCharsetEncoder(cs, -1, MAX_BYTES);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ec = new MockCharsetEncoder(cs, 1, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /*
+ * Class under test for constructor CharsetEncoder(Charset, float, float,
+ * byte[])
+ */
+ public void testCharsetEncoderCharsetfloatfloatbyteArray() {
+ byte[] ba = getLegalByteArray();
+ // normal case
+ CharsetEncoder ec = new MockCharsetEncoder(cs, 1, MAX_BYTES, ba);
+ assertSame(ec.charset(), cs);
+ assertEquals(1.0, ec.averageBytesPerChar(), 0.0);
+ assertTrue(ec.maxBytesPerChar() == MAX_BYTES);
+ assertSame(ba, ec.replacement());
+
+ /*
+ * ------------------------ Exceptional cases -------------------------
+ */
+ // NullPointerException: null charset
+ try {
+ ec = new MockCharsetEncoder(null, 1, MAX_BYTES, ba);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+
+ // Illegal Argument: null byte array
+ try {
+ ec = new MockCharsetEncoder(cs, 1, MAX_BYTES, null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ // Illegal Argument: empty byte array
+ try {
+ ec = new MockCharsetEncoder(cs, 1, MAX_BYTES, new byte[0]);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ // Illegal Argument: byte array is longer than max length
+ try {
+ ec = new MockCharsetEncoder(cs, 1, MAX_BYTES, new byte[] { 1, 2,
+ MAX_BYTES, 4 });
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // Commented out since the comment is wrong since MAX_BYTES > 1
+ // This test throws IllegalArgumentException on Harmony and RI
+ // // OK: average length less than max length
+ // ec = new MockCharsetEncoder(cs, MAX_BYTES, ba.length, ba);
+ // assertTrue(ec.averageBytesPerChar() == MAX_BYTES);
+ // assertTrue(ec.maxBytesPerChar() == ba.length);
+
+ // Illegal Argument: zero length
+ try {
+ ec = new MockCharsetEncoder(cs, 0, MAX_BYTES, ba);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ec = new MockCharsetEncoder(cs, 1, 0, ba);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // Illegal Argument: negative length
+ try {
+ ec = new MockCharsetEncoder(cs, -1, MAX_BYTES, ba);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ec = new MockCharsetEncoder(cs, 1, -1, ba);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /*
+ * Class under test for boolean canEncode(char)
+ */
+ public void testCanEncodechar() throws CharacterCodingException {
+ // for non-mapped char
+ assertTrue(encoder.canEncode('\uc2c0'));
+ // surrogate char for unicode
+ // 1st byte: d800-dbff
+ // 2nd byte: dc00-dfff
+ assertTrue(encoder.canEncode('\ud800'));
+ // valid surrogate pair
+ assertTrue(encoder.canEncode('\udc00'));
+ }
+
+ /*-----------------------------------------
+ * Class under test for illegal state case
+ * methods which can change internal states are two encode, flush, two canEncode, reset
+ * -----------------------------------------
+ */
+
+ // Normal case: just after reset, and it also means reset can be done
+ // anywhere
+ public void testResetIllegalState() throws CharacterCodingException {
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode('\ud901');
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode("\ud901\udc00");
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("aaa"));
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("aaa"), ByteBuffer.allocate(3), false);
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("aaa"), ByteBuffer.allocate(3), true);
+ assertSame(encoder, encoder.reset());
+ }
+
+ public void testFlushIllegalState() throws CharacterCodingException {
+ CharBuffer in = CharBuffer.wrap("aaa");
+ ByteBuffer out = ByteBuffer.allocate(5);
+
+ // Illegal state: after reset.
+ encoder.reset();
+ try {
+ encoder.flush(out);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ // Normal case: after encode with endOfInput is true
+ assertSame(encoder, encoder.reset());
+ encoder.encode(in, out, true);
+ out.rewind();
+ CoderResult result = encoder.flush(out);
+
+ // Good state: flush twice
+ encoder.flush(out);
+
+ // Illegal state: flush after encode with endOfInput is false
+ assertSame(encoder, encoder.reset());
+ encoder.encode(in, out, false);
+ try {
+ encoder.flush(out);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ public void testFlushAfterConstructing() {
+ ByteBuffer out = ByteBuffer.allocate(5);
+
+ //Illegal state: flush after instance created
+ try {
+ encoder.flush(out);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+
+ }
+
+ // test illegal states for encode facade
+ public void testEncodeFacadeIllegalState() throws CharacterCodingException {
+ // encode facade can be execute in anywhere
+ CharBuffer in = CharBuffer.wrap("aaa");
+ // Normal case: just created
+ encoder.encode(in);
+ in.rewind();
+
+ // Normal case: just after encode facade
+ encoder.encode(in);
+ in.rewind();
+
+ // Normal case: just after canEncode
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode("\ud902\udc00");
+ encoder.encode(in);
+ in.rewind();
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode('\ud902');
+ encoder.encode(in);
+ in.rewind();
+
+ // Normal case: just after encode with that endOfInput is true
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState2"),
+ ByteBuffer.allocate(30), true);
+ encoder.encode(in);
+ in.rewind();
+
+ // Normal case:just after encode with that endOfInput is false
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState3"),
+ ByteBuffer.allocate(30), false);
+ encoder.encode(in);
+ in.rewind();
+
+ // Normal case: just after flush
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState4"),
+ ByteBuffer.allocate(30), true);
+ encoder.flush(ByteBuffer.allocate(10));
+ encoder.encode(in);
+ in.rewind();
+ }
+
+ // test illegal states for two encode method with endOfInput is true
+ public void testEncodeTrueIllegalState() throws CharacterCodingException {
+ CharBuffer in = CharBuffer.wrap("aaa");
+ ByteBuffer out = ByteBuffer.allocate(5);
+ // Normal case: just created
+ encoder.encode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ in.rewind();
+ out.rewind();
+
+ // Normal case: just after encode with that endOfInput is true
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState2"),
+ ByteBuffer.allocate(30), true);
+ encoder.encode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ // Normal case:just after encode with that endOfInput is false
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState3"),
+ ByteBuffer.allocate(30), false);
+ encoder.encode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after flush
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState4"),
+ ByteBuffer.allocate(30), true);
+ encoder.flush(ByteBuffer.allocate(10));
+ try {
+ encoder.encode(in, out, true);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+
+ // Normal case: after canEncode
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode("\ud906\udc00");
+ encoder.encode(in, out, true);
+ in.rewind();
+ out.rewind();
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode('\ud905');
+ encoder.encode(in, out, true);
+ }
+
+ // test illegal states for two encode method with endOfInput is false
+ public void testEncodeFalseIllegalState() throws CharacterCodingException {
+ CharBuffer in = CharBuffer.wrap("aaa");
+ ByteBuffer out = ByteBuffer.allocate(5);
+ // Normal case: just created
+ encoder.encode(in, out, false);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after encode facade
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState1"));
+ try {
+ encoder.encode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+
+ // Illegal state: just after encode with that endOfInput is true
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState2"),
+ ByteBuffer.allocate(30), true);
+ try {
+ encoder.encode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+
+ // Normal case:just after encode with that endOfInput is false
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState3"),
+ ByteBuffer.allocate(30), false);
+ encoder.encode(in, out, false);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after flush
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState4"),
+ ByteBuffer.allocate(30), true);
+ encoder.flush(ByteBuffer.allocate(10));
+ try {
+ encoder.encode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+
+ // Normal case: after canEncode
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode("\ud906\udc00");
+ encoder.encode(in, out, false);
+ in.rewind();
+ out.rewind();
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode('\ud905');
+ encoder.encode(in, out, false);
+ }
+
+ // test illegal states for two canEncode methods
+ public void testCanEncodeIllegalState() throws CharacterCodingException {
+ // Normal case: just created
+ encoder.canEncode("\ud900\udc00");
+ encoder.canEncode('\ud900');
+
+ // Illegal state: just after encode with that endOfInput is true
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState2"),
+ ByteBuffer.allocate(30), true);
+ try {
+ encoder.canEncode("\ud903\udc00");
+ fail("should throw illegal state exception");
+ } catch (IllegalStateException e) {
+ }
+
+ // Illegal state:just after encode with that endOfInput is false
+ assertSame(encoder, encoder.reset());
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState3"),
+ ByteBuffer.allocate(30), false);
+ try {
+ encoder.canEncode("\ud904\udc00");
+ fail("should throw illegal state exception");
+ } catch (IllegalStateException e) {
+ }
+
+ // Normal case: just after flush
+ encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState4"),
+ ByteBuffer.allocate(30), true);
+ encoder.flush(ByteBuffer.allocate(10));
+ encoder.canEncode("\ud905\udc00");
+ encoder.canEncode('\ud906');
+
+ // Normal case: after reset again
+ assertSame(encoder, encoder.reset());
+ encoder.canEncode("\ud906\udc00");
+ encoder.canEncode('\ud905');
+ }
+
+ /*
+ * --------------------------------- illegal state test end
+ * ---------------------------------
+ */
+
+ /*
+ * Class under test for boolean canEncode(CharSequence)
+ */
+ public void testCanEncodeCharSequence() {
+ // for non-mapped char
+ assertTrue(encoder.canEncode("\uc2c0"));
+ // surrogate char for unicode
+ // 1st byte: d800-dbff
+ // 2nd byte: dc00-dfff
+ // valid surrogate pair
+ assertTrue(encoder.canEncode("\ud800\udc00"));
+ // invalid surrogate pair
+ assertTrue(encoder.canEncode("\ud800\udb00"));
+ }
+
+ public void test_canEncode_empty() throws Exception {
+ assertTrue(encoder.canEncode(""));
+ }
+
+ public void test_canEncode_null() throws Exception {
+ try {
+ encoder.canEncode(null);
+ fail();
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Class under test for Charset charset()
+ */
+ public void testCharset() {
+ try {
+ encoder = new MockCharsetEncoder(Charset.forName("gbk"), 1,
+ MAX_BYTES);
+ // assertSame(encoder.charset(), Charset.forName("gbk"));
+ } catch (UnsupportedCharsetException e) {
+ System.err
+ .println("Don't support GBK encoding, ignore current test");
+ }
+ }
+
+ /*
+ * Class under test for ByteBuffer encode(CharBuffer)
+ */
+ public void testEncodeCharBuffer() throws CharacterCodingException {
+ // Null pointer
+ try {
+ encoder.encode(null);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+
+ // empty input buffer
+ ByteBuffer out = encoder.encode(CharBuffer.wrap(""));
+ assertEquals(out.position(), 0);
+ assertByteArray(out, new byte[0]);
+ // assertByteArray(out, surrogate);
+
+ // normal case
+ out = encoder.encode(CharBuffer.wrap(unistr));
+ assertEquals(out.position(), 0);
+ assertByteArray(out, addSurrogate(unibytes));
+
+ // Regression test for harmony-3378
+ Charset cs = Charset.forName("UTF-8");
+ CharsetEncoder encoder = cs.newEncoder();
+ encoder.onMalformedInput(CodingErrorAction.REPLACE);
+ encoder = encoder.replaceWith(new byte[] { (byte) 0xef, (byte) 0xbf,
+ (byte) 0xbd, });
+ CharBuffer in = CharBuffer.wrap("\ud800");
+ out = encoder.encode(in);
+ assertNotNull(out);
+ }
+
+ private byte[] addSurrogate(byte[] expected) {
+ if (surrogate.length > 0) {
+ byte[] temp = new byte[surrogate.length + expected.length];
+ System.arraycopy(surrogate, 0, temp, 0, surrogate.length);
+ System.arraycopy(expected, 0, temp, surrogate.length,
+ expected.length);
+ expected = temp;
+ }
+ return expected;
+ }
+
+ /**
+ * @return
+ */
+ protected byte[] getEmptyByteArray() {
+ return new byte[0];
+ }
+
+ CharBuffer getMalformedCharBuffer() {
+ return CharBuffer.wrap("malform buffer");
+ }
+
+ CharBuffer getUnmapCharBuffer() {
+ return CharBuffer.wrap("unmap buffer");
+ }
+
+ CharBuffer getExceptionCharBuffer() {
+ return CharBuffer.wrap("runtime buffer");
+ }
+
+ public void testEncodeCharBufferException() throws CharacterCodingException {
+ ByteBuffer out;
+ CharBuffer in;
+ // MalformedException:
+ in = getMalformedCharBuffer();
+ encoder.onMalformedInput(CodingErrorAction.REPORT);
+ encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ if (in != null) {
+ try {
+ // regression test for Harmony-1379
+ encoder.encode(in);
+ fail("should throw MalformedInputException");
+ } catch (MalformedInputException e) {
+ }
+
+ encoder.reset();
+ in.rewind();
+ encoder.onMalformedInput(CodingErrorAction.IGNORE);
+ out = encoder.encode(in);
+ assertByteArray(out, addSurrogate(unibytes));
+
+ encoder.reset();
+ in.rewind();
+ encoder.onMalformedInput(CodingErrorAction.REPLACE);
+ out = encoder.encode(in);
+ assertByteArray(out, addSurrogate(unibytesWithRep));
+ }
+
+ // Unmapped Exception:
+ in = getUnmapCharBuffer();
+ encoder.onMalformedInput(CodingErrorAction.REPORT);
+ encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ if (in != null) {
+ encoder.reset();
+ try {
+ encoder.encode(in);
+ fail("should throw UnmappableCharacterException");
+ } catch (UnmappableCharacterException e) {
+ }
+
+ encoder.reset();
+ in.rewind();
+ encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ out = encoder.encode(in);
+ assertByteArray(out, unibytes);
+
+ encoder.reset();
+ in.rewind();
+ encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ out = encoder.encode(in);
+ assertByteArray(out, unibytesWithRep);
+ }
+
+ // RuntimeException
+ try {
+ encoder.encode(getExceptionCharBuffer());
+ fail("should throw runtime exception");
+ } catch (RuntimeException e) {
+ }
+ }
+
+ /*
+ * utility method, extract given bytebuffer to a string and compare with
+ * give string
+ */
+ void assertByteArray(ByteBuffer out, byte[] expected) {
+ out = out.duplicate();
+ if (out.position() != 0) {
+ out.flip();
+ }
+ byte[] ba = new byte[out.limit() - out.position()];
+ out.get(ba);
+ // byte[] ba = out.array();
+ assertTrue(Arrays.equals(ba, expected));
+ }
+
+ /*
+ * Class under test for CoderResult encode(CharBuffer, ByteBuffer, boolean)
+ */
+ public void testEncodeCharBufferByteBufferboolean()
+ throws CharacterCodingException {
+ ByteBuffer out = ByteBuffer.allocate(200);
+ CharBuffer in = CharBuffer.wrap(unistr);
+ // Null pointer
+ try {
+ encoder.encode(null, out, true);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+ try {
+ encoder.encode(in, null, true);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+
+ // normal case, one complete operation
+ assertSame(encoder, encoder.reset());
+ in.rewind();
+ out.rewind();
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, true));
+ assertEquals(out.limit(), 200);
+ assertTrue(out.position() > 0);
+ assertTrue(out.remaining() > 0);
+ assertEquals(out.capacity(), 200);
+ assertByteArray(out, addSurrogate(unibytes));
+ in.rewind();
+
+ encoder.flush(out);
+
+ // normal case, one complete operation, but call twice, first time set
+ // endOfInput to false
+ assertSame(encoder, encoder.reset());
+ in.rewind();
+ out = ByteBuffer.allocate(200);
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, false));
+ assertEquals(out.limit(), 200);
+ assertTrue(out.position() > 0);
+ assertTrue(out.remaining() > 0);
+ assertEquals(out.capacity(), 200);
+ assertByteArray(out, addSurrogate(unibytes));
+
+ in.rewind();
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, false));
+ in.rewind();
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, true));
+ assertEquals(out.limit(), 200);
+ assertTrue(out.position() > 0);
+ assertTrue(out.remaining() > 0);
+ assertEquals(out.capacity(), 200);
+
+ assertByteArray(out, addSurrogate(duplicateByteArray(unibytes, 3)));
+
+ // overflow
+ out = ByteBuffer.allocate(4);
+ assertSame(encoder, encoder.reset());
+ in.rewind();
+ out.rewind();
+ assertSame(CoderResult.OVERFLOW, encoder.encode(in, out, true));
+ assertEquals(out.limit(), 4);
+ assertEquals(out.position(), 4);
+ assertEquals(out.remaining(), 0);
+ assertEquals(out.capacity(), 4);
+ ByteBuffer temp = ByteBuffer.allocate(200);
+ out.flip();
+ temp.put(out);
+ out = temp;
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, true));
+ assertEquals(out.limit(), 200);
+ assertTrue(out.position() > 0);
+ assertTrue(out.remaining() > 0);
+ assertEquals(out.capacity(), 200);
+ assertByteArray(out, addSurrogate(unibytes));
+
+ assertSame(encoder, encoder.reset());
+ in.rewind();
+ out = ByteBuffer.allocate(4);
+ assertSame(CoderResult.OVERFLOW, encoder.encode(in, out, false));
+ assertEquals(out.limit(), 4);
+ assertEquals(out.position(), 4);
+ assertEquals(out.remaining(), 0);
+ assertEquals(out.capacity(), 4);
+ temp = ByteBuffer.allocate(200);
+ out.flip();
+ temp.put(out);
+ out = temp;
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, false));
+ assertEquals(out.limit(), 200);
+ assertTrue(out.position() > 0);
+ assertTrue(out.remaining() > 0);
+ assertEquals(out.capacity(), 200);
+ assertByteArray(out, addSurrogate(unibytes));
+ }
+
+ void printByteBuffer(ByteBuffer buffer) {
+ System.out.println("print buffer");
+ if (buffer.position() != 0) {
+ buffer.flip();
+ }
+ byte[] ba = buffer.array();
+ for (int i = 0; i < ba.length; i++) {
+ System.out.println(Integer.toHexString(ba[i]));
+ }
+ }
+
+ public void testEncodeCharBufferByteBufferbooleanExceptionFalse()
+ throws CharacterCodingException {
+ implTestEncodeCharBufferByteBufferbooleanException(false);
+ }
+
+ public void testEncodeCharBufferByteBufferbooleanExceptionTrue()
+ throws CharacterCodingException {
+ implTestEncodeCharBufferByteBufferbooleanException(true);
+ }
+
+ private byte[] duplicateByteArray(byte[] ba, int times) {
+ byte[] result = new byte[ba.length * times];
+ for (int i = 0; i < times; i++) {
+ System.arraycopy(ba, 0, result, i * ba.length, ba.length);
+ }
+ return result;
+ }
+
+ protected void implTestEncodeCharBufferByteBufferbooleanException(
+ boolean endOfInput) throws CharacterCodingException {
+ ByteBuffer out = ByteBuffer.allocate(100);
+
+ // MalformedException:
+ CharBuffer in = getMalformedCharBuffer();
+ encoder.onMalformedInput(CodingErrorAction.REPORT);
+ encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ if (in != null) {
+ encoder.reset();
+ CoderResult r = encoder.encode(in, out, endOfInput);
+ assertTrue(r.isMalformed());
+
+ encoder.reset();
+ out.clear();
+ in.rewind();
+ encoder.onMalformedInput(CodingErrorAction.IGNORE);
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
+ endOfInput));
+ assertCodingErrorAction(endOfInput, out, in, unibytes);
+
+ encoder.reset();
+ out.clear();
+ in.rewind();
+ encoder.onMalformedInput(CodingErrorAction.REPLACE);
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
+ endOfInput));
+ assertCodingErrorAction(endOfInput, out, in, unibytesWithRep);
+ } else {
+ System.out.println("Cannot find malformed char buffer for "
+ + cs.name());
+ }
+
+ // Unmapped Exception:
+ in = getUnmapCharBuffer();
+ encoder.onMalformedInput(CodingErrorAction.REPORT);
+ encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ if (in != null) {
+ encoder.reset();
+ out.clear();
+ assertTrue(encoder.encode(in, out, endOfInput).isUnmappable());
+
+ encoder.reset();
+ out.clear();
+ in.rewind();
+ encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
+ endOfInput));
+ assertCodingErrorAction(endOfInput, out, in, unibytes);
+
+ encoder.reset();
+ out.clear();
+ in.rewind();
+ encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
+ endOfInput));
+ assertCodingErrorAction(endOfInput, out, in, unibytesWithRep);
+ } else {
+ System.out.println("Cannot find unmapped char buffer for "
+ + cs.name());
+ }
+
+ // RuntimeException
+ try {
+ encoder.encode(getExceptionCharBuffer());
+ fail("should throw runtime exception");
+ } catch (RuntimeException e) {
+ }
+ }
+
+ private void assertCodingErrorAction(boolean endOfInput, ByteBuffer out,
+ CharBuffer in, byte[] expect) {
+ if (endOfInput) {
+ assertByteArray(out, addSurrogate(expect));
+ } else {
+ in.rewind();
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
+ endOfInput));
+ in.rewind();
+ assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, true));
+ assertByteArray(out, addSurrogate(duplicateByteArray(expect, 3)));
+ }
+ }
+
+ /*
+ * Class under test for CoderResult flush(ByteBuffer)
+ */
+ public void testFlush() throws CharacterCodingException {
+ ByteBuffer out = ByteBuffer.allocate(6);
+ CharBuffer in = CharBuffer.wrap("aaa");
+ assertEquals(in.remaining(), 3);
+
+ // by encode facade, so that internal state will be wrong
+ encoder.encode(CharBuffer.wrap("testFlush"), ByteBuffer.allocate(20),
+ true);
+ assertSame(CoderResult.UNDERFLOW, encoder
+ .flush(ByteBuffer.allocate(50)));
+ }
+
+ /*
+ * test isLegalReplacement(byte[])
+ */
+ public void test_isLegalReplacement_null() {
+ try {
+ encoder.isLegalReplacement(null);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_isLegalReplacement_good() {
+ assertTrue(encoder.isLegalReplacement(specifiedReplacement));
+ }
+
+ public void test_isLegalReplacement_bad() {
+ assertTrue(encoder.isLegalReplacement(new byte[200]));
+ byte[] ba = getIllegalByteArray();
+ if (ba != null) {
+ assertFalse(encoder.isLegalReplacement(ba));
+ }
+ }
+
+ public void test_isLegalReplacement_empty_array() {
+ // ISO, ASC, GB, UTF8 encoder will throw exception in RI
+ // others will pass
+ assertTrue(encoder.isLegalReplacement(new byte[0]));
+ }
+
+ public void testOnMalformedInput() {
+ assertSame(CodingErrorAction.REPORT, encoder.malformedInputAction());
+ try {
+ encoder.onMalformedInput(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ encoder.onMalformedInput(CodingErrorAction.IGNORE);
+ assertSame(CodingErrorAction.IGNORE, encoder.malformedInputAction());
+ }
+
+ public void testOnUnmappableCharacter() {
+ assertSame(CodingErrorAction.REPORT, encoder
+ .unmappableCharacterAction());
+ try {
+ encoder.onUnmappableCharacter(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ assertSame(CodingErrorAction.IGNORE, encoder
+ .unmappableCharacterAction());
+ }
+
+ public void testReplacement() {
+ try {
+ encoder.replaceWith(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ encoder.replaceWith(new byte[0]);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ encoder.replaceWith(new byte[100]);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+
+ byte[] nr = getLegalByteArray();
+ assertSame(encoder, encoder.replaceWith(nr));
+ assertSame(nr, encoder.replacement());
+
+ nr = getIllegalByteArray();
+ try {
+ encoder.replaceWith(new byte[100]);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ protected byte[] getLegalByteArray() {
+ return new byte[] { 'a' };
+ }
+
+ protected byte[] getIllegalByteArray() {
+ return new byte[155];
+ }
+
+ /*
+ * Mock subclass of CharsetEncoder For protected method test
+ */
+ public static class MockCharsetEncoder extends CharsetEncoder {
+
+ boolean flushed = false;
+
+ public boolean isFlushed() {
+ boolean result = flushed;
+ flushed = false;
+ return result;
+ }
+
+ public boolean isLegalReplacement(byte[] ba) {
+ if (ba.length == 155) {// specified magic number, return false
+ return false;
+ }
+ return super.isLegalReplacement(ba);
+ }
+
+ public MockCharsetEncoder(Charset cs, float aver, float max) {
+ super(cs, aver, max);
+ }
+
+ public MockCharsetEncoder(Charset cs, float aver, float max,
+ byte[] replacement) {
+ super(cs, aver, max, replacement);
+ }
+
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+ int inPosition = in.position();
+ char[] input = new char[in.remaining()];
+ in.get(input);
+ String result = new String(input);
+ if (result.startsWith("malform")) {
+ // reset the cursor to the error position
+ in.position(inPosition);
+ // in.position(0);
+ // set the error length
+ return CoderResult.malformedForLength("malform".length());
+ } else if (result.startsWith("unmap")) {
+ // reset the cursor to the error position
+ in.position(inPosition);
+ // in.position(0);
+ // set the error length
+ return CoderResult.unmappableForLength("unmap".length());
+ } else if (result.startsWith("runtime")) {
+ // reset the cursor to the error position
+ in.position(0);
+ // set the error length
+ throw new RuntimeException("runtime");
+ }
+ int inLeft = input.length;
+ int outLeft = out.remaining();
+ CoderResult r = CoderResult.UNDERFLOW;
+ int length = inLeft;
+ if (outLeft < inLeft) {
+ r = CoderResult.OVERFLOW;
+ length = outLeft;
+ in.position(inPosition + outLeft);
+ }
+ for (int i = 0; i < length; i++) {
+ out.put((byte) input[i]);
+ }
+ return r;
+ }
+
+ protected CoderResult implFlush(ByteBuffer out) {
+ CoderResult result = super.implFlush(out);
+ int length = 0;
+ if (out.remaining() >= 5) {
+ length = 5;
+ result = CoderResult.UNDERFLOW;
+ flushed = true;
+ // for (int i = 0; i < length; i++) {
+ // out.put((byte)'f');
+ // }
+ } else {
+ length = out.remaining();
+ result = CoderResult.OVERFLOW;
+ }
+ return result;
+ }
+
+ protected void implReplaceWith(byte[] ba) {
+ assertSame(ba, replacement());
+ }
+
+ }
+
+ /*
+ * mock charset for test encoder initialization
+ */
+ public static class MockCharset extends Charset {
+ protected MockCharset(String arg0, String[] arg1) {
+ super(arg0, arg1);
+ }
+
+ public boolean contains(Charset arg0) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new CharsetDecoderTest.MockCharsetDecoder(this,
+ (float) AVER_BYTES, MAX_BYTES);
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new MockCharsetEncoder(this, (float) AVER_BYTES, MAX_BYTES);
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java
new file mode 100644
index 0000000..01cf40e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java
@@ -0,0 +1,906 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.spi.CharsetProvider;
+import java.nio.charset.UnsupportedCharsetException;
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class java.nio.Charset.
+ */
+public class CharsetTest extends TestCase {
+
+ public void test_allAvailableCharsets() throws Exception {
+ // Check that we can instantiate every Charset, CharsetDecoder, and CharsetEncoder.
+ for (String charsetName : Charset.availableCharsets().keySet()) {
+ if (charsetName.equals("UTF-32")) {
+ // Our UTF-32 is broken. http://b/2702411
+ // TODO: remove this hack when UTF-32 is fixed.
+ continue;
+ }
+
+ Charset cs = Charset.forName(charsetName);
+ assertNotNull(cs.newDecoder());
+ if (cs.canEncode()) {
+ CharsetEncoder enc = cs.newEncoder();
+ assertNotNull(enc);
+ assertNotNull(enc.replacement());
+ }
+ }
+ }
+
+ public void test_defaultCharset() {
+ assertEquals("UTF-8", Charset.defaultCharset().name());
+ }
+
+ public void test_isRegistered() {
+ // Regression for HARMONY-45
+
+ // Will contain names of charsets registered with IANA
+ Set<String> knownRegisteredCharsets = new HashSet<String>();
+
+ // Will contain names of charsets not known to be registered with IANA
+ Set<String> unknownRegisteredCharsets = new HashSet<String>();
+
+ Set<String> names = Charset.availableCharsets().keySet();
+ for (Iterator nameItr = names.iterator(); nameItr.hasNext();) {
+ String name = (String) nameItr.next();
+ if (name.toLowerCase(Locale.ROOT).startsWith("x-")) {
+ unknownRegisteredCharsets.add(name);
+ } else {
+ knownRegisteredCharsets.add(name);
+ }
+ }
+
+ for (Iterator nameItr = knownRegisteredCharsets.iterator(); nameItr.hasNext();) {
+ String name = (String) nameItr.next();
+ Charset cs = Charset.forName(name);
+ if (!cs.isRegistered()) {
+ System.err.println("isRegistered was false for " + name + " " + cs.name() + " " + cs.aliases());
+ }
+ assertTrue("isRegistered was false for " + name + " " + cs.name() + " " + cs.aliases(), cs.isRegistered());
+ }
+ for (Iterator nameItr = unknownRegisteredCharsets.iterator(); nameItr.hasNext();) {
+ String name = (String) nameItr.next();
+ Charset cs = Charset.forName(name);
+ assertFalse("isRegistered was true for " + name + " " + cs.name() + " " + cs.aliases(), cs.isRegistered());
+ }
+ }
+
+ public void test_guaranteedCharsetsAvailable() throws Exception {
+ // All Java implementations must support these charsets.
+ assertNotNull(Charset.forName("ISO-8859-1"));
+ assertNotNull(Charset.forName("US-ASCII"));
+ assertNotNull(Charset.forName("UTF-16"));
+ assertNotNull(Charset.forName("UTF-16BE"));
+ assertNotNull(Charset.forName("UTF-16LE"));
+ assertNotNull(Charset.forName("UTF-8"));
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=42769
+ public void test_42769() throws Exception {
+ ArrayList<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < 10; ++i) {
+ Thread t = new Thread(new Runnable() {
+ public void run() {
+ for (int i = 0; i < 50; ++i) {
+ Charset.availableCharsets();
+ }
+ }
+ });
+ threads.add(t);
+ }
+
+ for (Thread t : threads) {
+ t.start();
+ }
+ for (Thread t : threads) {
+ t.join();
+ }
+ }
+
+ public void test_have_canonical_EUC_JP() throws Exception {
+ assertEquals("EUC-JP", Charset.forName("EUC-JP").name());
+ }
+
+ public void test_EUC_JP_replacement_character() throws Exception {
+ // We have text either side of the replacement character, because all kinds of errors
+ // could lead to a replacement character being returned.
+ assertEncodes(Charset.forName("EUC-JP"), " \ufffd ", ' ', 0xf4, 0xfe, ' ');
+ assertDecodes(Charset.forName("EUC-JP"), " \ufffd ", ' ', 0xf4, 0xfe, ' ');
+ }
+
+ public void test_SCSU_replacement_character() throws Exception {
+ // We have text either side of the replacement character, because all kinds of errors
+ // could lead to a replacement character being returned.
+ assertEncodes(Charset.forName("SCSU"), " \ufffd ", ' ', 14, 0xff, 0xfd, ' ');
+ assertDecodes(Charset.forName("SCSU"), " \ufffd ", ' ', 14, 0xff, 0xfd, ' ');
+ }
+
+ public void test_Shift_JIS_replacement_character() throws Exception {
+ // We have text either side of the replacement character, because all kinds of errors
+ // could lead to a replacement character being returned.
+ assertEncodes(Charset.forName("Shift_JIS"), " \ufffd ", ' ', 0xfc, 0xfc, ' ');
+ assertDecodes(Charset.forName("Shift_JIS"), " \ufffd ", ' ', 0xfc, 0xfc, ' ');
+ }
+
+ public void test_UTF_16() throws Exception {
+ Charset cs = Charset.forName("UTF-16");
+ // Writes big-endian, with a big-endian BOM.
+ assertEncodes(cs, "a\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
+ // Reads whatever the BOM tells it to read...
+ assertDecodes(cs, "a\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
+ assertDecodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
+ // ...and defaults to reading big-endian if there's no BOM.
+ assertDecodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
+ }
+
+ public void test_UTF_16BE() throws Exception {
+ Charset cs = Charset.forName("UTF-16BE");
+ // Writes big-endian, with no BOM.
+ assertEncodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
+ // Treats a little-endian BOM as an error and continues to read big-endian.
+ // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
+ assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 'a', 0x06, 0x66);
+ // Accepts a big-endian BOM and includes U+FEFF in the decoded output.
+ assertDecodes(cs, "\ufeffa\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
+ // Defaults to reading big-endian.
+ assertDecodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
+ }
+
+ public void test_UTF_16LE() throws Exception {
+ Charset cs = Charset.forName("UTF-16LE");
+ // Writes little-endian, with no BOM.
+ assertEncodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
+ // Accepts a little-endian BOM and includes U+FEFF in the decoded output.
+ assertDecodes(cs, "\ufeffa\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
+ // Treats a big-endian BOM as an error and continues to read little-endian.
+ // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
+ assertDecodes(cs, "\ufffda\u0666", 0xfe, 0xff, 'a', 0, 0x66, 0x06);
+ // Defaults to reading little-endian.
+ assertDecodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
+ }
+
+ public void test_x_UTF_16LE_BOM() throws Exception {
+ Charset cs = Charset.forName("x-UTF-16LE-BOM");
+ // Writes little-endian, with a BOM.
+ assertEncodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
+ // Accepts a little-endian BOM and swallows the BOM.
+ assertDecodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
+ // Swallows a big-endian BOM, but continues to read little-endian!
+ assertDecodes(cs, "\u6100\u6606", 0xfe, 0xff, 'a', 0, 0x66, 0x06);
+ // Defaults to reading little-endian.
+ assertDecodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
+ }
+
+ public void test_UTF_32() throws Exception {
+ Charset cs = Charset.forName("UTF-32");
+ // Writes big-endian, with no BOM.
+ assertEncodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ // Reads whatever the BOM tells it to read...
+ assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ // ...and defaults to reading big-endian if there's no BOM.
+ assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ }
+
+ public void test_UTF_32BE() throws Exception {
+ Charset cs = Charset.forName("UTF-32BE");
+ // Writes big-endian, with no BOM.
+ assertEncodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ // Treats a little-endian BOM as an error and continues to read big-endian.
+ // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
+ assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 0, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ // Accepts a big-endian BOM and swallows the BOM.
+ assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ // Defaults to reading big-endian.
+ assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ }
+
+ public void test_UTF_32LE() throws Exception {
+ Charset cs = Charset.forName("UTF-32LE");
+ // Writes little-endian, with no BOM.
+ assertEncodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ // Accepts a little-endian BOM and swallows the BOM.
+ assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ // Treats a big-endian BOM as an error and continues to read little-endian.
+ // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
+ assertDecodes(cs, "\ufffda\u0666", 0, 0, 0xfe, 0xff, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ // Defaults to reading little-endian.
+ assertDecodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ }
+
+ public void test_X_UTF_32BE_BOM() throws Exception {
+ Charset cs = Charset.forName("X-UTF-32BE-BOM");
+ // Writes big-endian, with a big-endian BOM.
+ assertEncodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ // Treats a little-endian BOM as an error and continues to read big-endian.
+ // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
+ assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 0, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ // Swallows a big-endian BOM, and continues to read big-endian.
+ assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ // Defaults to reading big-endian.
+ assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
+ }
+
+ public void test_X_UTF_32LE_BOM() throws Exception {
+ Charset cs = Charset.forName("X-UTF-32LE-BOM");
+ // Writes little-endian, with a little-endian BOM.
+ assertEncodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ // Accepts a little-endian BOM and swallows the BOM.
+ assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ // Treats a big-endian BOM as an error and continues to read little-endian.
+ // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
+ assertDecodes(cs, "\ufffda\u0666", 0, 0, 0xfe, 0xff, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ // Defaults to reading little-endian.
+ assertDecodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
+ }
+
+ private byte[] toByteArray(int[] ints) {
+ byte[] result = new byte[ints.length];
+ for (int i = 0; i < ints.length; ++i) {
+ result[i] = (byte) ints[i];
+ }
+ return result;
+ }
+
+ private void assertEncodes(Charset cs, String s, int... expectedByteInts) throws Exception {
+ ByteBuffer out = cs.encode(s);
+ byte[] bytes = new byte[out.remaining()];
+ out.get(bytes);
+ assertEquals(Arrays.toString(toByteArray(expectedByteInts)), Arrays.toString(bytes));
+ }
+
+ private void assertDecodes(Charset cs, String s, int... byteInts) throws Exception {
+ ByteBuffer in = ByteBuffer.wrap(toByteArray(byteInts));
+ CharBuffer out = cs.decode(in);
+ assertEquals(s, out.toString());
+ }
+
+ public void test_forNameLjava_lang_String() {
+ // Invoke forName two times with the same canonical name.
+ // It should return the same reference.
+ Charset cs1 = Charset.forName("UTF-8");
+ Charset cs2 = Charset.forName("UTF-8");
+ assertSame(cs1, cs2);
+
+ // test forName: invoke forName two times for the same Charset using
+ // canonical name and alias, it should return the same reference.
+ Charset cs3 = Charset.forName("ASCII");
+ Charset cs4 = Charset.forName("US-ASCII");
+ assertSame(cs3, cs4);
+ }
+
+ static MockCharset charset1 = new MockCharset("mockCharset00",
+ new String[] { "mockCharset01", "mockCharset02" });
+
+ static MockCharset charset2 = new MockCharset("mockCharset10",
+ new String[] { "mockCharset11", "mockCharset12" });
+
+ // Test the required 6 charsets are supported.
+ public void testRequiredCharsetSupported() {
+ assertTrue(Charset.isSupported("US-ASCII"));
+ assertTrue(Charset.isSupported("ASCII"));
+ assertTrue(Charset.isSupported("ISO-8859-1"));
+ assertTrue(Charset.isSupported("ISO8859_1"));
+ assertTrue(Charset.isSupported("UTF-8"));
+ assertTrue(Charset.isSupported("UTF8"));
+ assertTrue(Charset.isSupported("UTF-16"));
+ assertTrue(Charset.isSupported("UTF-16BE"));
+ assertTrue(Charset.isSupported("UTF-16LE"));
+
+ Charset c1 = Charset.forName("US-ASCII");
+ assertEquals("US-ASCII", Charset.forName("US-ASCII").name());
+ assertEquals("US-ASCII", Charset.forName("ASCII").name());
+ assertEquals("ISO-8859-1", Charset.forName("ISO-8859-1").name());
+ assertEquals("ISO-8859-1", Charset.forName("ISO8859_1").name());
+ assertEquals("UTF-8", Charset.forName("UTF-8").name());
+ assertEquals("UTF-8", Charset.forName("UTF8").name());
+ assertEquals("UTF-16", Charset.forName("UTF-16").name());
+ assertEquals("UTF-16BE", Charset.forName("UTF-16BE").name());
+ assertEquals("UTF-16LE", Charset.forName("UTF-16LE").name());
+
+ assertNotSame(Charset.availableCharsets(), Charset.availableCharsets());
+ // assertSame(Charset.forName("US-ASCII"), Charset.availableCharsets().get("US-ASCII"));
+ // assertSame(Charset.forName("US-ASCII"), c1);
+ assertTrue(Charset.availableCharsets().containsKey("US-ASCII"));
+ assertTrue(Charset.availableCharsets().containsKey("ISO-8859-1"));
+ assertTrue(Charset.availableCharsets().containsKey("UTF-8"));
+ assertTrue(Charset.availableCharsets().containsKey("UTF-16"));
+ assertTrue(Charset.availableCharsets().containsKey("UTF-16BE"));
+ assertTrue(Charset.availableCharsets().containsKey("UTF-16LE"));
+ }
+
+ public void testIsSupported_Null() {
+ try {
+ Charset.isSupported(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIsSupported_EmptyString() {
+ try {
+ Charset.isSupported("");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIsSupported_InvalidInitialCharacter() {
+ try {
+ Charset.isSupported(".char");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIsSupported_IllegalName() {
+ try {
+ Charset.isSupported(" ///#$$");
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ }
+
+ public void testIsSupported_NotSupported() {
+ assertFalse(Charset.isSupported("well-formed-name-of-a-charset-that-does-not-exist"));
+ }
+
+ public void testForName_Null() {
+ try {
+ Charset.forName(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testForName_EmptyString() {
+ try {
+ Charset.forName("");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testForName_InvalidInitialCharacter() {
+ try {
+ Charset.forName(".char");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testForName_IllegalName() {
+ try {
+ Charset.forName(" ///#$$");
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ }
+
+ public void testForName_NotSupported() {
+ try {
+ Charset.forName("impossible");
+ fail();
+ } catch (UnsupportedCharsetException expected) {
+ }
+ }
+
+ public void testConstructor_Normal() {
+ final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
+ MockCharset c = new MockCharset(mockName, new String[] { "mock" });
+ assertEquals(mockName, c.name());
+ assertEquals(mockName, c.displayName());
+ assertEquals(mockName, c.displayName(Locale.getDefault()));
+ assertEquals("mock", c.aliases().toArray()[0]);
+ assertEquals(1, c.aliases().toArray().length);
+ }
+
+ public void testConstructor_EmptyCanonicalName() {
+ try {
+ new MockCharset("", new String[0]);
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ }
+
+ public void testConstructor_IllegalCanonicalName_Initial() {
+ try {
+ new MockCharset("-123", new String[] { "mock" });
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ }
+
+ public void testConstructor_IllegalCanonicalName_Middle() {
+ try {
+ new MockCharset("1%%23", new String[] { "mock" });
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ try {
+ new MockCharset("1//23", new String[] { "mock" });
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ }
+
+ public void testConstructor_NullCanonicalName() {
+ try {
+ MockCharset c = new MockCharset(null, new String[] { "mock" });
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testConstructor_NullAliases() {
+ MockCharset c = new MockCharset("mockChar", null);
+ assertEquals("mockChar", c.name());
+ assertEquals("mockChar", c.displayName());
+ assertEquals("mockChar", c.displayName(Locale.getDefault()));
+ assertEquals(0, c.aliases().toArray().length);
+ }
+
+ public void testConstructor_NullAliase() {
+ try {
+ new MockCharset("mockChar", new String[] { "mock", null });
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testConstructor_NoAliases() {
+ MockCharset c = new MockCharset("mockChar", new String[0]);
+ assertEquals("mockChar", c.name());
+ assertEquals("mockChar", c.displayName());
+ assertEquals("mockChar", c.displayName(Locale.getDefault()));
+ assertEquals(0, c.aliases().toArray().length);
+ }
+
+ public void testConstructor_EmptyAliases() {
+ try {
+ new MockCharset("mockChar", new String[] { "" });
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ }
+
+ // Test the constructor with illegal aliases: starting with neither a digit nor a letter.
+ public void testConstructor_IllegalAliases_Initial() {
+ try {
+ new MockCharset("mockChar", new String[] { "mock", "-123" });
+ fail();
+ } catch (IllegalCharsetNameException e) {
+ }
+ }
+
+ public void testConstructor_IllegalAliases_Middle() {
+ try {
+ new MockCharset("mockChar", new String[] { "mock", "22##ab" });
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ try {
+ new MockCharset("mockChar", new String[] { "mock", "22%%ab" });
+ fail();
+ } catch (IllegalCharsetNameException expected) {
+ }
+ }
+
+ public void testAliases_Multiple() {
+ final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
+ MockCharset c = new MockCharset("mockChar", new String[] { "mock", mockName, "mock2" });
+ assertEquals("mockChar", c.name());
+ assertEquals(3, c.aliases().size());
+ assertTrue(c.aliases().contains("mock"));
+ assertTrue(c.aliases().contains(mockName));
+ assertTrue(c.aliases().contains("mock2"));
+
+ try {
+ c.aliases().clear();
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ public void testAliases_Duplicate() {
+ final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
+ MockCharset c = new MockCharset("mockChar", new String[] { "mockChar",
+ "mock", mockName, "mock", "mockChar", "mock", "mock2" });
+ assertEquals("mockChar", c.name());
+ assertEquals(4, c.aliases().size());
+ assertTrue(c.aliases().contains("mockChar"));
+ assertTrue(c.aliases().contains("mock"));
+ assertTrue(c.aliases().contains(mockName));
+ assertTrue(c.aliases().contains("mock2"));
+ }
+
+ public void testCanEncode() {
+ MockCharset c = new MockCharset("mock", null);
+ assertTrue(c.canEncode());
+ }
+
+ public void testIsRegistered() {
+ MockCharset c = new MockCharset("mock", null);
+ assertTrue(c.isRegistered());
+ }
+
+ public void testDisplayName_Locale_Null() {
+ MockCharset c = new MockCharset("mock", null);
+ assertEquals("mock", c.displayName(null));
+ }
+
+ public void testCompareTo_Normal() {
+ MockCharset c1 = new MockCharset("mock", null);
+ assertEquals(0, c1.compareTo(c1));
+
+ MockCharset c2 = new MockCharset("Mock", null);
+ assertEquals(0, c1.compareTo(c2));
+
+ c2 = new MockCharset("mock2", null);
+ assertTrue(c1.compareTo(c2) < 0);
+ assertTrue(c2.compareTo(c1) > 0);
+
+ c2 = new MockCharset("mack", null);
+ assertTrue(c1.compareTo(c2) > 0);
+ assertTrue(c2.compareTo(c1) < 0);
+
+ c2 = new MockCharset("m.", null);
+ assertTrue(c1.compareTo(c2) > 0);
+ assertTrue(c2.compareTo(c1) < 0);
+
+ c2 = new MockCharset("m:", null);
+ assertEquals("mock".compareToIgnoreCase("m:"), c1.compareTo(c2));
+ assertEquals("m:".compareToIgnoreCase("mock"), c2.compareTo(c1));
+
+ c2 = new MockCharset("m-", null);
+ assertTrue(c1.compareTo(c2) > 0);
+ assertTrue(c2.compareTo(c1) < 0);
+
+ c2 = new MockCharset("m_", null);
+ assertTrue(c1.compareTo(c2) > 0);
+ assertTrue(c2.compareTo(c1) < 0);
+ }
+
+ public void testCompareTo_Null() {
+ MockCharset c1 = new MockCharset("mock", null);
+ try {
+ c1.compareTo(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testCompareTo_DiffCharsetClass() {
+ MockCharset c1 = new MockCharset("mock", null);
+ MockCharset2 c2 = new MockCharset2("Mock", new String[] { "myname" });
+ assertEquals(0, c1.compareTo(c2));
+ assertEquals(0, c2.compareTo(c1));
+ }
+
+ public void testEquals_Normal() {
+ MockCharset c1 = new MockCharset("mock", null);
+ MockCharset2 c2 = new MockCharset2("mock", null);
+ assertTrue(c1.equals(c2));
+ assertTrue(c2.equals(c1));
+
+ c2 = new MockCharset2("Mock", null);
+ assertFalse(c1.equals(c2));
+ assertFalse(c2.equals(c1));
+ }
+
+ public void testEquals_Null() {
+ MockCharset c1 = new MockCharset("mock", null);
+ assertFalse(c1.equals(null));
+ }
+
+ public void testEquals_NonCharsetObject() {
+ MockCharset c1 = new MockCharset("mock", null);
+ assertFalse(c1.equals("test"));
+ }
+
+ public void testEquals_DiffCharsetClass() {
+ MockCharset c1 = new MockCharset("mock", null);
+ MockCharset2 c2 = new MockCharset2("mock", null);
+ assertTrue(c1.equals(c2));
+ assertTrue(c2.equals(c1));
+ }
+
+ public void testHashCode_DiffCharsetClass() {
+ MockCharset c1 = new MockCharset("mock", null);
+ assertEquals(c1.hashCode(), "mock".hashCode());
+
+ final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
+ c1 = new MockCharset(mockName, new String[] { "mockChar", "mock",
+ mockName, "mock", "mockChar", "mock", "mock2" });
+ assertEquals(mockName.hashCode(), c1.hashCode());
+ }
+
+ public void testEncode_CharBuffer_Normal() throws Exception {
+ MockCharset c1 = new MockCharset("testEncode_CharBuffer_Normal_mock", null);
+ ByteBuffer bb = c1.encode(CharBuffer.wrap("abcdefg"));
+ assertEquals("abcdefg", new String(bb.array(), "iso8859-1"));
+ bb = c1.encode(CharBuffer.wrap(""));
+ assertEquals("", new String(bb.array(), "iso8859-1"));
+ }
+
+ public void testEncode_CharBuffer_Unmappable() throws Exception {
+ Charset c1 = Charset.forName("iso8859-1");
+ ByteBuffer bb = c1.encode(CharBuffer.wrap("abcd\u5D14efg"));
+ assertEquals(new String(bb.array(), "iso8859-1"),
+ "abcd" + new String(c1.newEncoder().replacement(), "iso8859-1") + "efg");
+ }
+
+ public void testEncode_CharBuffer_NullCharBuffer() {
+ MockCharset c = new MockCharset("mock", null);
+ try {
+ c.encode((CharBuffer) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testEncode_CharBuffer_NullEncoder() {
+ MockCharset2 c = new MockCharset2("mock2", null);
+ try {
+ c.encode(CharBuffer.wrap("hehe"));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testEncode_String_Normal() throws Exception {
+ MockCharset c1 = new MockCharset("testEncode_String_Normal_mock", null);
+ ByteBuffer bb = c1.encode("abcdefg");
+ assertEquals("abcdefg", new String(bb.array(), "iso8859-1"));
+ bb = c1.encode("");
+ assertEquals("", new String(bb.array(), "iso8859-1"));
+ }
+
+ public void testEncode_String_Unmappable() throws Exception {
+ Charset c1 = Charset.forName("iso8859-1");
+ ByteBuffer bb = c1.encode("abcd\u5D14efg");
+ assertEquals(new String(bb.array(), "iso8859-1"),
+ "abcd" + new String(c1.newEncoder().replacement(), "iso8859-1") + "efg");
+ }
+
+ public void testEncode_String_NullString() {
+ MockCharset c = new MockCharset("mock", null);
+ try {
+ c.encode((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testEncode_String_NullEncoder() {
+ MockCharset2 c = new MockCharset2("mock2", null);
+ try {
+ c.encode("hehe");
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testDecode_Normal() throws Exception {
+ MockCharset c1 = new MockCharset("mock", null);
+ CharBuffer cb = c1.decode(ByteBuffer.wrap("abcdefg".getBytes("iso8859-1")));
+ assertEquals("abcdefg", new String(cb.array()));
+ cb = c1.decode(ByteBuffer.wrap("".getBytes("iso8859-1")));
+ assertEquals("", new String(cb.array()));
+ }
+
+ public void testDecode_Malformed() throws Exception {
+ Charset c1 = Charset.forName("iso8859-1");
+ CharBuffer cb = c1.decode(ByteBuffer.wrap("abcd\u5D14efg".getBytes("iso8859-1")));
+ byte[] replacement = c1.newEncoder().replacement();
+ assertEquals(new String(cb.array()).trim(), "abcd" + new String(replacement, "iso8859-1") + "efg");
+ }
+
+ public void testDecode_NullByteBuffer() {
+ MockCharset c = new MockCharset("mock", null);
+ try {
+ c.decode(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testDecode_NullDecoder() {
+ MockCharset2 c = new MockCharset2("mock2", null);
+ try {
+ c.decode(ByteBuffer.wrap("hehe".getBytes()));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testToString() {
+ MockCharset c1 = new MockCharset("mock", null);
+ assertTrue(-1 != c1.toString().indexOf("mock"));
+ }
+
+ static final class MockCharset extends Charset {
+ public MockCharset(String canonicalName, String[] aliases) {
+ super(canonicalName, aliases);
+ }
+
+ public boolean contains(Charset cs) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new MockDecoder(this);
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new MockEncoder(this);
+ }
+ }
+
+ static class MockCharset2 extends Charset {
+ public MockCharset2(String canonicalName, String[] aliases) {
+ super(canonicalName, aliases);
+ }
+
+ public boolean contains(Charset cs) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return null;
+ }
+
+ public CharsetEncoder newEncoder() {
+ return null;
+ }
+ }
+
+ static class MockEncoder extends java.nio.charset.CharsetEncoder {
+ public MockEncoder(Charset cs) {
+ super(cs, 1, 3, new byte[] { (byte) '?' });
+ }
+
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+ while (in.remaining() > 0) {
+ out.put((byte) in.get());
+ // out.put((byte) '!');
+ }
+ return CoderResult.UNDERFLOW;
+ }
+ }
+
+ static class MockDecoder extends java.nio.charset.CharsetDecoder {
+ public MockDecoder(Charset cs) {
+ super(cs, 1, 10);
+ }
+
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+ while (in.remaining() > 0) {
+ out.put((char) in.get());
+ }
+ return CoderResult.UNDERFLOW;
+ }
+ }
+
+
+ // Test the method isSupported(String) with charset supported by multiple providers.
+ public void testIsSupported_And_ForName_NormalProvider() throws Exception {
+ assertTrue(Charset.isSupported("mockCharset10"));
+ // ignore case problem in mock, intended
+ assertTrue(Charset.isSupported("MockCharset11"));
+ assertTrue(Charset.isSupported("MockCharset12"));
+ assertTrue(Charset.isSupported("MOCKCharset10"));
+ // intended case problem in mock
+ assertTrue(Charset.isSupported("MOCKCharset11"));
+ assertTrue(Charset.isSupported("MOCKCharset12"));
+
+ assertTrue(Charset.forName("mockCharset10") instanceof MockCharset);
+ assertTrue(Charset.forName("mockCharset11") instanceof MockCharset);
+ assertTrue(Charset.forName("mockCharset12") instanceof MockCharset);
+
+ assertTrue(Charset.forName("mockCharset10") == charset2);
+ // intended case problem in mock
+ Charset.forName("mockCharset11");
+ assertTrue(Charset.forName("mockCharset12") == charset2);
+ }
+
+ // Test the method availableCharsets() with charset supported by multiple providers.
+ public void testAvailableCharsets_NormalProvider() throws Exception {
+ assertTrue(Charset.availableCharsets().containsKey("mockCharset00"));
+ assertTrue(Charset.availableCharsets().containsKey("MOCKCharset00"));
+ assertTrue(Charset.availableCharsets().get("mockCharset00") instanceof MockCharset);
+ assertTrue(Charset.availableCharsets().get("MOCKCharset00") instanceof MockCharset);
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset01"));
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset02"));
+
+ assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
+ assertTrue(Charset.availableCharsets().get("MOCKCharset10") == charset2);
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
+
+ assertTrue(Charset.availableCharsets().containsKey("mockCharset10"));
+ assertTrue(Charset.availableCharsets().containsKey("MOCKCharset10"));
+ assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
+ }
+
+ // Test the method forName(String) when the charset provider supports a
+ // built-in charset.
+ public void testForName_DuplicateWithBuiltInCharset() throws Exception {
+ assertFalse(Charset.forName("us-ascii") instanceof MockCharset);
+ assertFalse(Charset.availableCharsets().get("us-ascii") instanceof MockCharset);
+ }
+
+ public static class MockCharsetProvider extends CharsetProvider {
+ public Charset charsetForName(String charsetName) {
+ if ("MockCharset00".equalsIgnoreCase(charsetName) ||
+ "MockCharset01".equalsIgnoreCase(charsetName) ||
+ "MockCharset02".equalsIgnoreCase(charsetName)) {
+ return charset1;
+ } else if ("MockCharset10".equalsIgnoreCase(charsetName) ||
+ "MockCharset11".equalsIgnoreCase(charsetName) ||
+ "MockCharset12".equalsIgnoreCase(charsetName)) {
+ return charset2;
+ }
+ return null;
+ }
+
+ public Iterator charsets() {
+ Vector v = new Vector();
+ v.add(charset1);
+ v.add(charset2);
+ return v.iterator();
+ }
+ }
+
+ // Another mock charset provider attempting to provide the built-in charset "ascii" again.
+ public static class MockCharsetProviderASCII extends CharsetProvider {
+ public Charset charsetForName(String charsetName) {
+ if ("US-ASCII".equalsIgnoreCase(charsetName) || "ASCII".equalsIgnoreCase(charsetName)) {
+ return new MockCharset("US-ASCII", new String[] { "ASCII" });
+ }
+ return null;
+ }
+
+ public Iterator charsets() {
+ Vector v = new Vector();
+ v.add(new MockCharset("US-ASCII", new String[] { "ASCII" }));
+ return v.iterator();
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CoderMalfunctionErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CoderMalfunctionErrorTest.java
new file mode 100644
index 0000000..1b343ad
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CoderMalfunctionErrorTest.java
@@ -0,0 +1,62 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.charset.CoderMalfunctionError;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Test java.nio.CoderMalfunctionError.
+ */
+public class CoderMalfunctionErrorTest extends TestCase {
+
+ /*
+ * Test constructor with normal param.
+ */
+ public void testConstructor_Normal() {
+ Exception ex = new Exception();
+ CoderMalfunctionError e = new CoderMalfunctionError(ex);
+ assertSame(ex, e.getCause());
+ }
+
+ /*
+ * Test constructor with null param.
+ */
+ public void testConstructor_Null() {
+ CoderMalfunctionError e = new CoderMalfunctionError(null);
+ assertNull(e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new CoderMalfunctionError(null));
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ SerializationTest.verifyGolden(this, new CoderMalfunctionError(null));
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CoderResultTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CoderResultTest.java
new file mode 100644
index 0000000..dafd21d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CoderResultTest.java
@@ -0,0 +1,265 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.charset.CoderResult;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class java.nio.charset.CoderResult.
+ */
+public class CoderResultTest extends TestCase {
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /*
+ * Test the constant OVERFLOW and UNDERFLOW.
+ */
+ public void testConstants() throws Exception {
+ assertNotSame(CoderResult.OVERFLOW, CoderResult.UNDERFLOW);
+
+ assertNotNull(CoderResult.OVERFLOW);
+ assertFalse(CoderResult.OVERFLOW.isError());
+ assertFalse(CoderResult.OVERFLOW.isMalformed());
+ assertFalse(CoderResult.OVERFLOW.isUnderflow());
+ assertFalse(CoderResult.OVERFLOW.isUnmappable());
+ assertTrue(CoderResult.OVERFLOW.isOverflow());
+ assertTrue(CoderResult.OVERFLOW.toString().indexOf("OVERFLOW") != -1);
+ try {
+ CoderResult.OVERFLOW.throwException();
+ fail("Should throw BufferOverflowException");
+ } catch (BufferOverflowException ex) {
+ // expected
+ }
+ try {
+ CoderResult.OVERFLOW.length();
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException ex) {
+ // expected
+ }
+
+ assertNotNull(CoderResult.UNDERFLOW);
+ assertFalse(CoderResult.UNDERFLOW.isError());
+ assertFalse(CoderResult.UNDERFLOW.isMalformed());
+ assertTrue(CoderResult.UNDERFLOW.isUnderflow());
+ assertFalse(CoderResult.UNDERFLOW.isUnmappable());
+ assertFalse(CoderResult.UNDERFLOW.isOverflow());
+ assertTrue(CoderResult.UNDERFLOW.toString().indexOf("UNDERFLOW") != -1);
+ try {
+ CoderResult.UNDERFLOW.throwException();
+ fail("Should throw BufferOverflowException");
+ } catch (BufferUnderflowException ex) {
+ // expected
+ }
+ try {
+ CoderResult.UNDERFLOW.length();
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * Test method isError().
+ *
+ */
+ public void testIsError() {
+ assertFalse(CoderResult.UNDERFLOW.isError());
+ assertFalse(CoderResult.OVERFLOW.isError());
+ assertTrue(CoderResult.malformedForLength(1).isError());
+ assertTrue(CoderResult.unmappableForLength(1).isError());
+ }
+
+ /**
+ * Test method isMalformed().
+ *
+ */
+ public void testIsMalformed() {
+ assertFalse(CoderResult.UNDERFLOW.isMalformed());
+ assertFalse(CoderResult.OVERFLOW.isMalformed());
+ assertTrue(CoderResult.malformedForLength(1).isMalformed());
+ assertFalse(CoderResult.unmappableForLength(1).isMalformed());
+ }
+
+ /**
+ * Test method isMalformed().
+ *
+ */
+ public void testIsUnmappable() {
+ assertFalse(CoderResult.UNDERFLOW.isUnmappable());
+ assertFalse(CoderResult.OVERFLOW.isUnmappable());
+ assertFalse(CoderResult.malformedForLength(1).isUnmappable());
+ assertTrue(CoderResult.unmappableForLength(1).isUnmappable());
+ }
+
+ /**
+ * Test method isOverflow().
+ *
+ */
+ public void testIsOverflow() {
+ assertFalse(CoderResult.UNDERFLOW.isOverflow());
+ assertTrue(CoderResult.OVERFLOW.isOverflow());
+ assertFalse(CoderResult.malformedForLength(1).isOverflow());
+ assertFalse(CoderResult.unmappableForLength(1).isOverflow());
+ }
+
+ /**
+ * Test method isUnderflow().
+ *
+ */
+ public void testIsUnderflow() {
+ assertTrue(CoderResult.UNDERFLOW.isUnderflow());
+ assertFalse(CoderResult.OVERFLOW.isUnderflow());
+ assertFalse(CoderResult.malformedForLength(1).isUnderflow());
+ assertFalse(CoderResult.unmappableForLength(1).isUnderflow());
+ }
+
+ /**
+ * Test method length().
+ *
+ */
+ public void testLength() {
+ try {
+ CoderResult.UNDERFLOW.length();
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException ex) {
+ // expected
+ }
+ try {
+ CoderResult.OVERFLOW.length();
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException ex) {
+ // expected
+ }
+
+ assertEquals(CoderResult.malformedForLength(1).length(), 1);
+ assertEquals(CoderResult.unmappableForLength(1).length(), 1);
+ }
+
+ /**
+ * Test method malformedForLength(int).
+ *
+ */
+ public void testMalformedForLength() {
+ assertNotNull(CoderResult.malformedForLength(Integer.MAX_VALUE));
+ assertNotNull(CoderResult.malformedForLength(1));
+ assertSame(CoderResult.malformedForLength(1), CoderResult
+ .malformedForLength(1));
+ assertNotSame(CoderResult.malformedForLength(1), CoderResult
+ .unmappableForLength(1));
+ assertNotSame(CoderResult.malformedForLength(2), CoderResult
+ .malformedForLength(1));
+ try {
+ CoderResult.malformedForLength(-1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ CoderResult.malformedForLength(0);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * Test method unmappableForLength(int).
+ *
+ */
+ public void testUnmappableForLength() {
+ assertNotNull(CoderResult.unmappableForLength(Integer.MAX_VALUE));
+ assertNotNull(CoderResult.unmappableForLength(1));
+ assertSame(CoderResult.unmappableForLength(1), CoderResult
+ .unmappableForLength(1));
+ assertNotSame(CoderResult.unmappableForLength(2), CoderResult
+ .unmappableForLength(1));
+ try {
+ CoderResult.unmappableForLength(-1);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ CoderResult.unmappableForLength(0);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * Test method throwException().
+ *
+ */
+ public void testThrowException() throws Exception {
+ try {
+ CoderResult.OVERFLOW.throwException();
+ fail("Should throw BufferOverflowException");
+ } catch (BufferOverflowException ex) {
+ // expected
+ }
+ try {
+ CoderResult.UNDERFLOW.throwException();
+ fail("Should throw BufferOverflowException");
+ } catch (BufferUnderflowException ex) {
+ // expected
+ }
+ try {
+ CoderResult.malformedForLength(1).throwException();
+ fail("Should throw MalformedInputException");
+ } catch (MalformedInputException ex) {
+ assertEquals(ex.getInputLength(), 1);
+ }
+ try {
+ CoderResult.unmappableForLength(1).throwException();
+ fail("Should throw UnmappableCharacterException");
+ } catch (UnmappableCharacterException ex) {
+ assertEquals(ex.getInputLength(), 1);
+ }
+ }
+
+ /**
+ * Test method toString().
+ *
+ */
+ public void testToString() throws Exception {
+ assertTrue(CoderResult.OVERFLOW.toString().indexOf("OVERFLOW") != -1);
+ assertTrue(CoderResult.UNDERFLOW.toString().indexOf("UNDERFLOW") != -1);
+ assertTrue(CoderResult.malformedForLength(666).toString()
+ .indexOf("666") != -1);
+ assertTrue(CoderResult.unmappableForLength(666).toString().indexOf(
+ "666") != -1);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CodingErrorActionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CodingErrorActionTest.java
new file mode 100644
index 0000000..7e408de
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CodingErrorActionTest.java
@@ -0,0 +1,62 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.charset.CodingErrorAction;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class java.nio.charset.CodingErrorAction
+ */
+public class CodingErrorActionTest extends TestCase {
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /*
+ * Test the constants.
+ */
+ public void testIGNORE() {
+ assertNotNull(CodingErrorAction.IGNORE);
+ assertNotNull(CodingErrorAction.REPLACE);
+ assertNotNull(CodingErrorAction.REPORT);
+ assertNotSame(CodingErrorAction.IGNORE, CodingErrorAction.REPLACE);
+ assertNotSame(CodingErrorAction.IGNORE, CodingErrorAction.REPORT);
+ assertNotSame(CodingErrorAction.REPLACE, CodingErrorAction.REPORT);
+ }
+
+ /*
+ * Test the method toString().
+ */
+ public void testToString() {
+ assertTrue(CodingErrorAction.IGNORE.toString().indexOf("IGNORE") != -1);
+ assertTrue(CodingErrorAction.REPLACE.toString().indexOf("REPLACE") != -1);
+ assertTrue(CodingErrorAction.REPORT.toString().indexOf("REPORT") != -1);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/GBCharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/GBCharsetDecoderTest.java
new file mode 100644
index 0000000..3f19877
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/GBCharsetDecoderTest.java
@@ -0,0 +1,64 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * test gb18030 decoder
+ */
+public class GBCharsetDecoderTest extends CharsetDecoderTest {
+
+ protected void setUp() throws Exception {
+ cs = Charset.forName("gb18030");
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetDecoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // // FIXME: give up this tests
+ // public void testDefaultCharsPerByte(){
+ // //assertEquals(1, decoder.averageCharsPerByte());
+ // //assertEquals(1, decoder.maxCharsPerByte());
+ // assertEquals(decoder.averageCharsPerByte(), 0.25, 0.001);
+ // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
+ // }
+
+ ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
+ return null;
+ }
+
+ ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
+ ByteBuffer buffer = ByteBuffer.allocate(20);
+ buffer.put(new byte[] { (byte) 0xd8 });
+ buffer.put(getByteBuffer());
+ buffer.flip();
+ return buffer;
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ return null;
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/GBCharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/GBCharsetEncoderTest.java
new file mode 100644
index 0000000..02b9062
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/GBCharsetEncoderTest.java
@@ -0,0 +1,89 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+
+/**
+ * test case specific activity of gb18030 charset encoder
+ */
+public class GBCharsetEncoderTest extends CharsetEncoderTest {
+
+ // charset for gb180303
+ private static final Charset CS = Charset.forName("gb18030");
+
+ /*
+ * @see CharsetEncoderTest#setUp()
+ */
+ protected void setUp() throws Exception {
+ cs = CS;
+ specifiedReplacement = new byte[] { 0x1a };
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetEncoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testCanEncodechar() {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode('\u0077'));
+ assertTrue(encoder.canEncode('\uc2a3'));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode('\uc2c0'));
+ }
+
+ /*
+ * Class under test for boolean canEncode(CharSequence)
+ */
+ public void testCanEncodeCharSequence() {
+ // surrogate char
+
+ // valid surrogate pair
+ assertTrue(encoder.canEncode("\ud800\udc00"));
+ // invalid surrogate pair
+ assertFalse(encoder.canEncode("\ud800\udb00"));
+ }
+
+ public void testSpecificDefaultValue() {
+ assertEquals(4.0, encoder.maxBytesPerChar(), 0.0);
+ assertEquals(2.5, encoder.averageBytesPerChar(), 0.0);
+ }
+
+ CharBuffer getMalformedCharBuffer() {
+ return CharBuffer.wrap("\ud800 buffer");
+ }
+
+ CharBuffer getUnmapCharBuffer() {
+ return null;
+ }
+
+ CharBuffer getExceptionCharBuffer() {
+ return null;
+ }
+
+ protected byte[] getIllegalByteArray() {
+ return new byte[] { (byte) 0xd8, (byte) 0x00 };
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetDecoderTest.java
new file mode 100644
index 0000000..3c8bad4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetDecoderTest.java
@@ -0,0 +1,61 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * test ISO-8859-1 decoder
+ */
+public class ISOCharsetDecoderTest extends CharsetDecoderTest {
+
+ protected void setUp() throws Exception {
+ cs = Charset.forName("iso-8859-1");
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetDecoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // FIXME: give up this tests
+ // public void testDefaultCharsPerByte(){
+ // assertEquals(1, decoder.averageCharsPerByte());
+ // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
+ // }
+
+ ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
+ // TODO how on map?
+ return null;
+
+ }
+
+ ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
+ // TODO how malform
+ return null;
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ return null;
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetEncoderTest.java
new file mode 100644
index 0000000..1c0bb48
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetEncoderTest.java
@@ -0,0 +1,93 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+
+/**
+ * test case specific activity of iso-8859-1 charset encoder
+ */
+public class ISOCharsetEncoderTest extends CharsetEncoderTest {
+
+ // charset for iso-8859-1
+ private static final Charset CS = Charset.forName("iso-8859-1");
+
+ /*
+ * @see CharsetEncoderTest#setUp()
+ */
+ protected void setUp() throws Exception {
+ cs = CS;
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetEncoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Override public void testCanEncodeCharSequence() {
+ // normal case for isoCS
+ assertTrue(encoder.canEncode("\u0077"));
+ assertFalse(encoder.canEncode("\uc2a3"));
+ assertFalse(encoder.canEncode("\ud800\udc00"));
+ }
+
+ @Override public void testCanEncodechar() throws CharacterCodingException {
+ assertTrue(encoder.canEncode('\u0077'));
+ assertFalse(encoder.canEncode('\uc2a3'));
+ }
+
+ @Override public void testSpecificDefaultValue() {
+ assertEquals(1, encoder.averageBytesPerChar(), 0.001);
+ assertEquals(1, encoder.maxBytesPerChar(), 0.001);
+ }
+
+ CharBuffer getMalformedCharBuffer() {
+ return CharBuffer.wrap("\ud800 buffer");
+ }
+
+ CharBuffer getUnmapCharBuffer() {
+ return CharBuffer.wrap("\ud800\udc00 buffer");
+ }
+
+ CharBuffer getExceptionCharBuffer() {
+ return null;
+ }
+
+ protected byte[] getIllegalByteArray() {
+ return null;
+ }
+
+ public void testMultiStepEncode() throws CharacterCodingException {
+ encoder.onMalformedInput(CodingErrorAction.REPORT);
+ encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ try {
+ encoder.encode(CharBuffer.wrap("\ud800\udc00"));
+ fail("should unmappable");
+ } catch (UnmappableCharacterException e) {
+ }
+ encoder.reset();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetTest.java
new file mode 100644
index 0000000..73f6ffd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/ISOCharsetTest.java
@@ -0,0 +1,58 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+/**
+ * Test ISO-8859-1.
+ */
+public class ISOCharsetTest extends AbstractCharsetTestCase {
+
+ /**
+ * Constructor.
+ */
+ public ISOCharsetTest(String arg0) {
+ super(arg0, "ISO-8859-1", new String[] { "iso-ir-100", "8859_1",
+ "ISO_8859-1", "ISO8859_1", "819", "csISOLatin1", "IBM-819",
+ "ISO_8859-1:1987", "latin1", "cp819", "ISO8859-1", "IBM819",
+ "ISO_8859_1", "l1" }, true, true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
+ */
+ public void testEncode_Normal() {
+ String input = "ab\u5D14\u654F";
+ byte[] output = new byte[] { 97, 98,
+ this.testingCharset.newEncoder().replacement()[0],
+ this.testingCharset.newEncoder().replacement()[0] };
+ internalTestEncode(input, output);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
+ */
+ public void testDecode_Normal() {
+ byte[] input = new byte[] { 97, 98, 63, 63 };
+ char[] output = "ab??".toCharArray();
+ internalTestDecode(input, output);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/IllegalCharsetNameExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/IllegalCharsetNameExceptionTest.java
new file mode 100644
index 0000000..f5ba3d1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/IllegalCharsetNameExceptionTest.java
@@ -0,0 +1,94 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.Serializable;
+import java.nio.charset.IllegalCharsetNameException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+/**
+ * Test class IllegalCharsetNameException.
+ */
+public class IllegalCharsetNameExceptionTest extends TestCase {
+
+ public void testConstructor() {
+ IllegalCharsetNameException ex = new IllegalCharsetNameException(
+ "impossible");
+ assertTrue(ex instanceof IllegalArgumentException);
+ assertNull(ex.getCause());
+ assertEquals(ex.getCharsetName(), "impossible");
+ assertTrue(ex.getMessage().indexOf("impossible") != -1);
+
+ ex = new IllegalCharsetNameException("ascii");
+ assertNull(ex.getCause());
+ assertEquals(ex.getCharsetName(), "ascii");
+ assertTrue(ex.getMessage().indexOf("ascii") != -1);
+
+ ex = new IllegalCharsetNameException("");
+ assertNull(ex.getCause());
+ assertEquals(ex.getCharsetName(), "");
+ ex.getMessage();
+
+ ex = new IllegalCharsetNameException(null);
+ assertNull(ex.getCause());
+ assertNull(ex.getCharsetName());
+ assertTrue(ex.getMessage().indexOf("null") != -1);
+
+ }
+
+ // comparator for IllegalCharsetNameException objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ // FIXME?: getMessage() returns more helpful string but
+ // this leads to incompatible message in serial form
+ //
+ // do common checks for all throwable objects
+ // SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ // deserialized);
+
+ IllegalCharsetNameException initEx = (IllegalCharsetNameException) initial;
+ IllegalCharsetNameException desrEx = (IllegalCharsetNameException) deserialized;
+
+ assertEquals("CharsetName", initEx.getCharsetName(), desrEx
+ .getCharsetName());
+ }
+ };
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new IllegalCharsetNameException(
+ "charsetName"), COMPARATOR);
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new IllegalCharsetNameException(
+ "charsetName"), COMPARATOR);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/MalformedInputExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/MalformedInputExceptionTest.java
new file mode 100644
index 0000000..d288a4a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/MalformedInputExceptionTest.java
@@ -0,0 +1,85 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.Serializable;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.MalformedInputException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+/**
+ * Test class MalformedInputException.
+ */
+public class MalformedInputExceptionTest extends TestCase {
+
+ public void testConstructor() {
+ MalformedInputException ex = new MalformedInputException(3);
+ assertTrue(ex instanceof CharacterCodingException);
+ assertNull(ex.getCause());
+ assertEquals(ex.getInputLength(), 3);
+ assertTrue(ex.getMessage().indexOf("3") != -1);
+
+ ex = new MalformedInputException(-3);
+ assertNull(ex.getCause());
+ assertEquals(ex.getInputLength(), -3);
+ assertTrue(ex.getMessage().indexOf("-3") != -1);
+
+ ex = new MalformedInputException(0);
+ assertNull(ex.getCause());
+ assertEquals(ex.getInputLength(), 0);
+ assertTrue(ex.getMessage().indexOf("0") != -1);
+ }
+
+ // comparator for MalformedInputException objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ // do common checks for all throwable objects
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ MalformedInputException initEx = (MalformedInputException) initial;
+ MalformedInputException desrEx = (MalformedInputException) deserialized;
+
+ assertEquals("InputLength", initEx.getInputLength(), desrEx
+ .getInputLength());
+ }
+ };
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new MalformedInputException(11),
+ COMPARATOR);
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new MalformedInputException(11),
+ COMPARATOR);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetDecoderTest.java
new file mode 100644
index 0000000..800353d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetDecoderTest.java
@@ -0,0 +1,72 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ *
+ */
+public class UTF16BECharsetDecoderTest extends CharsetDecoderTest {
+
+ protected void setUp() throws Exception {
+ cs = Charset.forName("utf-16be");
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetDecoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // FIXME: give up this tests
+ // public void testDefaultCharsPerByte() {
+ // // assertEquals(1, decoder.averageCharsPerByte());
+ // // assertEquals(1, decoder.maxCharsPerByte());
+ // assertEquals(decoder.averageCharsPerByte(), 0.5, 0.001);
+ // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
+ // }
+
+ ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
+ // no unmap byte buffer
+ return null;
+ }
+
+ ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
+ // FIXME: different here, RI can parse 0xd8d8
+ // ByteBuffer buffer = ByteBuffer.allocate(100);
+ // buffer.put((byte)0xd8);
+ // buffer.put((byte)0xd8);
+ // buffer.put(unibytes);
+ // buffer.flip();
+ // return buffer;
+ return null;
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ return null;
+ }
+
+ protected ByteBuffer getByteBuffer() {
+ return ByteBuffer.wrap(new byte[] { 0, 32, 0, 98, 0, 117, 0, 102, 0,
+ 102, 0, 101, 0, 114 });
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetEncoderTest.java
new file mode 100644
index 0000000..66970de
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetEncoderTest.java
@@ -0,0 +1,108 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+
+/**
+ * TODO type def
+ */
+public class UTF16BECharsetEncoderTest extends CharsetEncoderTest {
+
+ // charset for utf-16be
+ private static final Charset CS = Charset.forName("utf-16be");
+
+ /*
+ * @see CharsetEncoderTest#setUp()
+ */
+ protected void setUp() throws Exception {
+ cs = CS;
+ specifiedReplacement = new byte[] { -1, -3 };
+ unibytes = new byte[] { 0, 32, 0, 98, 0, 117, 0, 102, 0, 102, 0, 101,
+ 0, 114 };
+
+ // unibytesWithRep = new byte[] {(byte)0xff, (byte)0xfd,0, 32, 0, 98, 0,
+ // 117, 0, 102, 0, 102, 0, 101, 0, 114};
+
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetEncoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testCharsetEncoderCharsetfloatfloat() {
+ // this constructor is invalid for UTF16LE CharsetEncoder
+ }
+
+ public void testCanEncodechar() throws CharacterCodingException {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode('\u0077'));
+ assertTrue(encoder.canEncode('\uc2a3'));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode('\uc2c0'));
+
+ }
+
+ public void testCanEncodeCharSequence() {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode("\u0077"));
+ assertTrue(encoder.canEncode("\uc2a3"));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode("\uc2c0"));
+
+ // surrogate char for unicode
+ // 1st byte: d800-dbff
+ // 2nd byte: dc00-dfff
+ // valid surrogate pair
+ assertTrue(encoder.canEncode("\ud800\udc00"));
+ // invalid surrogate pair
+ assertFalse(encoder.canEncode("\ud800\udb00"));
+ }
+
+ public void testSpecificDefaultValue() {
+ assertEquals(2, encoder.averageBytesPerChar(), 0.001);
+ assertEquals(2, encoder.maxBytesPerChar(), 0.001);
+ }
+
+ CharBuffer getMalformedCharBuffer() {
+ return CharBuffer.wrap("\ud800 buffer");
+ }
+
+ CharBuffer getUnmapCharBuffer() {
+ return null;
+ }
+
+ CharBuffer getExceptionCharBuffer() {
+ return null;
+ }
+
+ protected byte[] getIllegalByteArray() {
+ return new byte[] { (byte)0xd8, (byte)0x00, (byte)0xdb, (byte)0x00 };
+ }
+
+ protected byte[] getLegalByteArray() {
+ return new byte[] { (byte) 0x00, (byte) 0xd8 };
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetTest.java
new file mode 100644
index 0000000..e951943
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16BECharsetTest.java
@@ -0,0 +1,53 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+/**
+ * Test UTF-16BE.
+ */
+public class UTF16BECharsetTest extends AbstractCharsetTestCase {
+
+ /**
+ * Constructor.
+ */
+ public UTF16BECharsetTest(String arg0) {
+ super(arg0, "UTF-16BE", new String[] { "X-UTF-16BE", "UTF_16BE" },
+ true, true); // "ISO-10646-UCS-2"
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
+ */
+ public void testEncode_Normal() {
+ String input = "ab\u5D14\u654F";
+ byte[] output = new byte[] { 0, 97, 0, 98, 93, 20, 101, 79 };
+ internalTestEncode(input, output);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
+ */
+ public void testDecode_Normal() {
+ byte[] input = new byte[] { 0, 97, 0, 98, 93, 20, 101, 79 };
+ char[] output = "ab\u5D14\u654F".toCharArray();
+ internalTestDecode(input, output);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetDecoderTest.java
new file mode 100644
index 0000000..d47a5c9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetDecoderTest.java
@@ -0,0 +1,118 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ *
+ */
+public class UTF16CharsetDecoderTest extends CharsetDecoderTest {
+
+ boolean bigEndian = true;
+
+ protected void setUp() throws Exception {
+ cs = Charset.forName("utf-16");
+ bom = "\ufeff";
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetDecoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ protected ByteBuffer getByteBuffer() {
+ // FIXME: different here
+ // if don't specified BOM
+ // ICU default is LE
+ // JDK default is BE
+
+ // maybe start with 0xFEFF, which means big endian
+ // 0xFFFE, which means little endian
+ byte[] b = (bigEndian) ? new byte[] { -1, -2, 32, 0, 98, 0, 117, 0,
+ 102, 0, 102, 0, 101, 0, 114, 0 } : new byte[] { -2, -1, 0, 32,
+ 0, 98, 0, 117, 0, 102, 0, 102, 0, 101, 0, 114 };
+ return ByteBuffer.wrap(b);
+ }
+
+ protected ByteBuffer getHeadlessByteBuffer() {
+ ByteBuffer b = getByteBuffer();
+ b.position(2);
+ byte[] bytes = new byte[b.remaining()];
+ b.get(bytes);
+ return ByteBuffer.wrap(bytes);
+ }
+
+ public void testLittleEndianByteBufferCharBuffer()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ bigEndian = false;
+ implTestDecodeByteBufferCharBuffer(getByteBuffer());
+ bigEndian = true;
+ }
+
+ public void testLittleEndianReadOnlyByteBufferCharBuffer()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ bigEndian = false;
+ implTestDecodeByteBufferCharBuffer(getByteBuffer().asReadOnlyBuffer());
+ bigEndian = true;
+ }
+
+ public void testLittleEndian() throws CharacterCodingException,
+ UnsupportedEncodingException {
+ bigEndian = false;
+ implTestDecodeByteBuffer();
+ bigEndian = true;
+ }
+
+ // FIXME: give up this tests
+ // public void testDefaultCharsPerByte() {
+ // // assertEquals(1, decoder.averageCharsPerByte());
+ // // assertEquals(1, decoder.maxCharsPerByte());
+ // assertEquals(decoder.averageCharsPerByte(), 0.5, 0.001);
+ // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
+ // }
+
+ ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
+ return null;
+ }
+
+ ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
+ return null;
+ // FIXME: different here, RI can parse 0xd8d8
+ // ByteBuffer buffer = ByteBuffer.allocate(100);
+ // buffer.put((byte) -1);
+ // buffer.put((byte) -2);
+ // buffer.put((byte) 0xdc);
+ // buffer.put((byte) 0xdc);
+ // buffer.put(unibytes);
+ // buffer.flip();
+ // return buffer;
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ return null;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetEncoderTest.java
new file mode 100644
index 0000000..a0f2ac3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetEncoderTest.java
@@ -0,0 +1,128 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+
+/**
+ * TODO type def
+ */
+public class UTF16CharsetEncoderTest extends CharsetEncoderTest {
+
+ // charset for utf-16
+ // charset for utf-16be
+ private static final Charset CS = Charset.forName("utf-16");
+
+ private static final CharsetDecoder decoder = CS.newDecoder();
+
+ /*
+ * @see CharsetEncoderTest#setUp()
+ */
+ protected void setUp() throws Exception {
+ cs = CS;
+ specifiedReplacement = new byte[] { -3, -1 };
+ surrogate = new byte[] { -1, -2 };
+ unibytes = new byte[] { 32, 0, 98, 0, 117, 0, 102, 0, 102, 0, 101, 0,
+ 114, 0 };
+ unibytesWithRep = new byte[] { -3, -1, 32, 0, 98, 0, 117, 0, 102, 0,
+ 102, 0, 101, 0, 114, 0 };
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetEncoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testCharsetEncoderCharsetfloatfloat() {
+ // this constructor is invalid for UTF16LE CharsetEncoder
+ }
+
+ public void testCanEncodechar() throws CharacterCodingException {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode('\u0077'));
+ assertTrue(encoder.canEncode('\uc2a3'));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode('\uc2c0'));
+ }
+
+ public void testCanEncodeCharSequence() {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode("\u0077"));
+ assertTrue(encoder.canEncode("\uc2a3"));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode("\uc2c0"));
+
+ // surrogate char for unicode
+ // 1st byte: d800-dbff
+ // 2nd byte: dc00-dfff
+ // valid surrogate pair
+ assertTrue(encoder.canEncode("\ud800\udc00"));
+ // invalid surrogate pair
+ assertFalse(encoder.canEncode("\ud800\udb00"));
+ }
+
+ public void testSpecificDefaultValue() {
+ assertEquals(encoder.averageBytesPerChar(), 2, 0.001);
+ // assertEquals(4, encoder.maxBytesPerChar());
+ // FIXME: different here!
+ assertEquals(encoder.maxBytesPerChar(), 2, 0.001);
+ }
+
+ CharBuffer getMalformedCharBuffer() {
+ return CharBuffer.wrap("\ud800 buffer");
+ }
+
+ CharBuffer getUnmapCharBuffer() {
+ return null;
+ }
+
+ CharBuffer getExceptionCharBuffer() {
+ return null;
+ }
+
+ protected byte[] getIllegalByteArray() {
+ return new byte[] { (byte)0xd8, (byte)0x00, (byte)0xdb, (byte)0x00 };
+ }
+
+ protected byte[] getLegalByteArray() {
+ // FIXME: Different Here!
+ // return new byte[]{(byte)0xd8, 0x00};
+ return new byte[] { (byte) 0x00, (byte) 0xd8 };
+ }
+
+ void assertByteArray(ByteBuffer out, byte[] expected) {
+ out = out.duplicate();
+ if (out.position() > 0) {
+ out.flip();
+ }
+ try {
+ assertEquals(decoder.decode(out), decoder.decode(ByteBuffer
+ .wrap(expected)));
+ } catch (CharacterCodingException e) {
+ fail(e.toString());
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetTest.java
new file mode 100644
index 0000000..7ec7d62
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16CharsetTest.java
@@ -0,0 +1,51 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+/**
+ * Test UTF-16.
+ */
+public class UTF16CharsetTest extends AbstractCharsetTestCase {
+
+ /**
+ * Constructor.
+ */
+ public UTF16CharsetTest(String arg0) {
+ super(arg0, "UTF-16", new String[] { "UTF_16" }, true, true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
+ */
+ public void testEncode_Normal() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
+ */
+ public void testDecode_Normal() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetDecoderTest.java
new file mode 100644
index 0000000..5caacae
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetDecoderTest.java
@@ -0,0 +1,72 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * TODO typedef
+ */
+public class UTF16LECharsetDecoderTest extends CharsetDecoderTest {
+
+ protected void setUp() throws Exception {
+ cs = Charset.forName("utf-16le");
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetDecoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // // FIXME: give up this tests
+ // public void testDefaultCharsPerByte(){
+ // // assertEquals(1, decoder.averageCharsPerByte());
+ // // assertEquals(1, decoder.maxCharsPerByte());
+ // assertEquals(decoder.averageCharsPerByte(), 0.5, 0.001);
+ // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
+ // }
+
+ ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
+ // no unmap byte buffer
+ return null;
+ }
+
+ ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
+ // FIXME: different here, JDK can parse 0xd8d8
+ // ByteBuffer buffer = ByteBuffer.allocate(100);
+ // buffer.put((byte)0xd8);
+ // buffer.put((byte)0xd8);
+ // buffer.put(unibytes);
+ // buffer.flip();
+ // return buffer;
+ return null;
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ return null;
+ }
+
+ protected ByteBuffer getByteBuffer() {
+ return ByteBuffer.wrap(new byte[] { 32, 0, 98, 0, 117, 0, 102, 0, 102,
+ 0, 101, 0, 114, 0 });
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetEncoderTest.java
new file mode 100644
index 0000000..425dc13
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetEncoderTest.java
@@ -0,0 +1,109 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+
+/**
+ * TODO type def
+ */
+public class UTF16LECharsetEncoderTest extends CharsetEncoderTest {
+
+ // charset for utf-16le
+ private static final Charset CS = Charset.forName("utf-16le");
+
+ /*
+ * @see CharsetEncoderTest#setUp()
+ */
+ protected void setUp() throws Exception {
+ cs = CS;
+ specifiedReplacement = new byte[] { -3, -1 };
+
+ unibytes = new byte[] { 32, 0, 98, 0, 117, 0, 102, 0, 102, 0, 101, 0,
+ 114, 0 };
+
+ // unibytesWithRep = new byte[] {(byte)0xfd, (byte)0xff, 32, 0, 98, 0,
+ // 117, 0, 102, 0, 102, 0, 101, 0, 114 ,0};
+
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetEncoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testCharsetEncoderCharsetfloatfloat() {
+ // this constructor is invalid for UTF16LE CharsetEncoder
+ }
+
+ public void testCanEncodechar() throws CharacterCodingException {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode('\u0077'));
+ assertTrue(encoder.canEncode('\uc2a3'));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode('\uc2c0'));
+ }
+
+ public void testCanEncodeCharSequence() {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode("\u0077"));
+ assertTrue(encoder.canEncode("\uc2a3"));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode("\uc2c0"));
+
+ // surrogate char for unicode
+ // 1st byte: d800-dbff
+ // 2nd byte: dc00-dfff
+ // valid surrogate pair
+ assertTrue(encoder.canEncode("\ud800\udc00"));
+ // invalid surrogate pair
+ assertFalse(encoder.canEncode("\ud800\udb00"));
+ }
+
+ public void testSpecificDefaultValue() {
+ assertEquals(2, encoder.averageBytesPerChar(), 0.001);
+ assertEquals(2, encoder.maxBytesPerChar(), 0.001);
+ }
+
+ CharBuffer getMalformedCharBuffer() {
+ return CharBuffer.wrap("\ud800 buffer");
+ }
+
+ CharBuffer getUnmapCharBuffer() {
+ return null;
+ }
+
+ CharBuffer getExceptionCharBuffer() {
+ return null;
+ }
+
+ protected byte[] getIllegalByteArray() {
+ return new byte[] { (byte)0x00, (byte)0xd8, (byte)0x00, (byte)0xdb };
+ }
+
+ protected byte[] getLegalByteArray() {
+ return new byte[] { (byte) 0xd8, 0x00 };
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetTest.java
new file mode 100644
index 0000000..a173d06
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF16LECharsetTest.java
@@ -0,0 +1,54 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+/**
+ * Test UTF-16LE.
+ */
+public class UTF16LECharsetTest extends AbstractCharsetTestCase {
+
+ /**
+ * Constructor.
+ */
+ public UTF16LECharsetTest(String arg0) {
+ super(arg0, "UTF-16LE", new String[] { "UTF_16LE", "X-UTF-16LE" },
+ true, true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
+ */
+ public void testEncode_Normal() {
+ String input = "ab\u5D14\u654F";
+ byte[] output = new byte[] { 97, 0, 98, 0, 20, 93, 79, 101 };
+ internalTestEncode(input, output);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
+ */
+ public void testDecode_Normal() {
+ byte[] input = new byte[] { 97, 0, 98, 0, 20, 93, 79, 101 };
+ char[] output = "ab\u5D14\u654F".toCharArray();
+ internalTestDecode(input, output);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF8CharsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF8CharsetTest.java
new file mode 100644
index 0000000..e6e328e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTF8CharsetTest.java
@@ -0,0 +1,62 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Test UTF-8 charset.
+ */
+public class UTF8CharsetTest extends AbstractCharsetTestCase {
+
+ /**
+ * Constructor for UTF8CharsetTest.
+ *
+ */
+ public UTF8CharsetTest(String arg0) {
+ super(arg0, "UTF-8", new String[] { "UTF8" }, true, true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
+ */
+ public void testDecode_Normal() {
+ byte[] input = new byte[] { 97, 98, -27, -76, -108, -26, -107, -113 };
+ char[] output = "ab\u5D14\u654F".toCharArray();
+ internalTestDecode(input, output);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
+ */
+ public void testEncode_Normal() {
+ String input = "ab\u5D14\u654F";
+ byte[] output = new byte[] { 97, 98, -27, -76, -108, -26, -107, -113 };
+ internalTestEncode(input, output);
+ }
+
+ public void test_surrogate() throws UnsupportedEncodingException {
+ // U+1D11E: MUSICAL SYMBOL G CLEF
+ String s = new StringBuilder().appendCodePoint(0x1D11E).toString();
+ byte utf8[] = s.getBytes("UTF-8");
+ assertEquals(s, new String(utf8, 0, utf8.length, "UTF-8"));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTFCharsetDecoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTFCharsetDecoderTest.java
new file mode 100644
index 0000000..80c9dfc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTFCharsetDecoderTest.java
@@ -0,0 +1,76 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * test utf-8 decoder
+ */
+public class UTFCharsetDecoderTest extends CharsetDecoderTest {
+
+ protected void setUp() throws Exception {
+ cs = Charset.forName("utf-8");
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetDecoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // FIXME: give up this tests
+ // public void testDefaultCharsPerByte(){
+ // assertEquals(decoder.averageCharsPerByte(), 0.333, 0.001);
+ // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
+ // // assertEquals(1, decoder.averageCharsPerByte());
+ // // assertEquals(1, decoder.maxCharsPerByte());
+ // }
+
+ ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
+ return null;
+ }
+
+ ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
+ ByteBuffer buffer = ByteBuffer.allocate(getByteBuffer().remaining() + 1);
+ buffer.put((byte) 0xd8);
+ buffer.put(getByteBuffer());
+ buffer.flip();
+ return buffer;
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ return null;
+ }
+
+ protected String getString() {
+ return " buffer \u041c\u0430\u0441\u044e\u043b\u044f \u611b";
+ }
+
+ protected ByteBuffer getByteBuffer() {
+ return ByteBuffer.wrap(new byte[] { 32, 98, 117, 102, 102, 101, 114,
+ 32, (byte) 0xd0, (byte) 0x9c, (byte) 0xd0, (byte) 0xb0,
+ (byte) 0xd1, (byte) 0x81, (byte) 0xd1, (byte) 0x8e,
+ (byte) 0xd0, (byte) 0xbb, (byte) 0xd1, (byte) 0x8f, 32,
+ (byte) 0xe6, (byte) 0x84, (byte) 0x9b });
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTFCharsetEncoderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTFCharsetEncoderTest.java
new file mode 100644
index 0000000..1662ae3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UTFCharsetEncoderTest.java
@@ -0,0 +1,96 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+
+/**
+ * test case specific activity of utf-8 charset encoder
+ */
+public class UTFCharsetEncoderTest extends CharsetEncoderTest {
+
+ // charset for UTF-8
+ private static final Charset CS = Charset.forName("utf-8");
+
+ /*
+ * @see CharsetEncoderTest#setUp()
+ */
+ protected void setUp() throws Exception {
+ cs = CS;
+ specifiedReplacement = new byte[] { 63 };
+ super.setUp();
+ }
+
+ /*
+ * @see CharsetEncoderTest#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testCanEncodechar() throws CharacterCodingException {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode('\u0077'));
+ assertTrue(encoder.canEncode('\uc2a3'));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode('\uc2c0'));
+ }
+
+ public void testCanEncodeCharSequence() {
+ // normal case for utfCS
+ assertTrue(encoder.canEncode("\u0077"));
+ assertTrue(encoder.canEncode("\uc2a3"));
+
+ // for non-mapped char
+ assertTrue(encoder.canEncode("\uc2c0"));
+
+ // surrogate char for unicode
+ // 1st byte: d800-dbff
+ // 2nd byte: dc00-dfff
+ // valid surrogate pair
+ assertTrue(encoder.canEncode("\ud800\udc00"));
+ // invalid surrogate pair
+ assertFalse(encoder.canEncode("\ud800\udb00"));
+ }
+
+ public void testSpecificDefaultValue() {
+ assertEquals(2, encoder.averageBytesPerChar(), 0);
+ assertEquals(3, encoder.maxBytesPerChar(), 0);
+ }
+
+ CharBuffer getMalformedCharBuffer() {
+ return CharBuffer.wrap("\ud800 buffer");
+ }
+
+ CharBuffer getUnmapCharBuffer() {
+ return null;
+ }
+
+ CharBuffer getExceptionCharBuffer() {
+ return null;
+ }
+
+ protected byte[] getIllegalByteArray() {
+ return new byte[] { (byte) 0xd8, (byte) 0x00 };
+ }
+
+ protected void assertFlushed() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UnmappableCharacterExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UnmappableCharacterExceptionTest.java
new file mode 100644
index 0000000..d9de0d4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UnmappableCharacterExceptionTest.java
@@ -0,0 +1,86 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.Serializable;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.UnmappableCharacterException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+/**
+ * Test class UnmappableCharacterException.
+ */
+public class UnmappableCharacterExceptionTest extends TestCase {
+
+ public void testConstructor() {
+ UnmappableCharacterException ex = new UnmappableCharacterException(3);
+ assertTrue(ex instanceof CharacterCodingException);
+ assertNull(ex.getCause());
+ assertEquals(ex.getInputLength(), 3);
+ assertTrue(ex.getMessage().indexOf("3") != -1);
+
+ ex = new UnmappableCharacterException(-3);
+ assertNull(ex.getCause());
+ assertEquals(ex.getInputLength(), -3);
+ assertTrue(ex.getMessage().indexOf("-3") != -1);
+
+ ex = new UnmappableCharacterException(0);
+ assertNull(ex.getCause());
+ assertEquals(ex.getInputLength(), 0);
+ assertTrue(ex.getMessage().indexOf("0") != -1);
+
+ }
+
+ // comparator for UnmappableCharacterException objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ // do common checks for all throwable objects
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ UnmappableCharacterException initEx = (UnmappableCharacterException) initial;
+ UnmappableCharacterException desrEx = (UnmappableCharacterException) deserialized;
+
+ assertEquals("InputLength", initEx.getInputLength(), desrEx
+ .getInputLength());
+ }
+ };
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new UnmappableCharacterException(11),
+ COMPARATOR);
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new UnmappableCharacterException(
+ 11), COMPARATOR);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UnsupportedCharsetExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UnsupportedCharsetExceptionTest.java
new file mode 100644
index 0000000..be52a84
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/UnsupportedCharsetExceptionTest.java
@@ -0,0 +1,93 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.nio.charset;
+
+import java.io.Serializable;
+import java.nio.charset.UnsupportedCharsetException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+/**
+ * Test class UnsupportedCharsetException.
+ */
+public class UnsupportedCharsetExceptionTest extends TestCase {
+
+ public void testConstructor() {
+ UnsupportedCharsetException ex = new UnsupportedCharsetException(
+ "impossible");
+ assertTrue(ex instanceof IllegalArgumentException);
+ assertNull(ex.getCause());
+ assertEquals(ex.getCharsetName(), "impossible");
+ assertTrue(ex.getMessage().indexOf("impossible") != -1);
+
+ ex = new UnsupportedCharsetException("ascii");
+ assertNull(ex.getCause());
+ assertEquals(ex.getCharsetName(), "ascii");
+ assertTrue(ex.getMessage().indexOf("ascii") != -1);
+
+ ex = new UnsupportedCharsetException("");
+ assertNull(ex.getCause());
+ assertEquals(ex.getCharsetName(), "");
+ ex.getMessage();
+
+ ex = new UnsupportedCharsetException(null);
+ assertNull(ex.getCause());
+ assertNull(ex.getCharsetName());
+ assertTrue(ex.getMessage().indexOf("null") != -1);
+ }
+
+ // comparator for UnsupportedCharsetException objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ // FIXME?: getMessage() returns more helpful string but
+ // this leads to incompatible message in serial form
+ //
+ // do common checks for all throwable objects
+ // SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ // deserialized);
+
+ UnsupportedCharsetException initEx = (UnsupportedCharsetException) initial;
+ UnsupportedCharsetException desrEx = (UnsupportedCharsetException) deserialized;
+
+ assertEquals("CharsetName", initEx.getCharsetName(), desrEx
+ .getCharsetName());
+ }
+ };
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new UnsupportedCharsetException(
+ "charsetName"), COMPARATOR);
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new UnsupportedCharsetException(
+ "charsetName"), COMPARATOR);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AnnotationTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AnnotationTest.java
new file mode 100644
index 0000000..61b1c17
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AnnotationTest.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.Annotation;
+
+import junit.framework.TestCase;
+
+public class AnnotationTest extends TestCase {
+
+ public void testAnnotation() {
+ assertNotNull(new Annotation(null));
+ assertNotNull(new Annotation("value"));
+ }
+
+ public void testGetValue() {
+ Annotation a = new Annotation(null);
+ assertNull(a.getValue());
+ a = new Annotation("value");
+ assertEquals("value", a.getValue());
+ }
+
+ public void testToString() {
+ Annotation ant = new Annotation("HelloWorld");
+ assertEquals("toString error.",
+ "java.text.Annotation[value=HelloWorld]",ant.toString());
+ assertNotNull(new Annotation(null).toString());
+ assertNotNull(new Annotation("value").toString());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedCharacterIteratorAttributeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedCharacterIteratorAttributeTest.java
new file mode 100644
index 0000000..0cc224a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedCharacterIteratorAttributeTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.NotSerializableException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Locale;
+import java.text.Annotation;
+
+public class AttributedCharacterIteratorAttributeTest extends junit.framework.TestCase {
+
+ /**
+ * @tests java.text.AttributedCharacterIterator$Attribute()
+ */
+ public void test_constructor() {
+ MyAttribute attribute = new MyAttribute("attribute");
+
+ assertEquals("Attribute has wrong name", "attribute", attribute.getExposedName());
+
+ attribute = new MyAttribute(null);
+ assertEquals("Attribute has wrong name", null, attribute.getExposedName());
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator.Attribute#equals(Object)
+ */
+ public void test_equals() {
+
+ assertTrue(Attribute.LANGUAGE.equals(Attribute.LANGUAGE));
+
+ assertFalse(Attribute.LANGUAGE.equals(Attribute.READING));
+
+ MyAttribute attribute = new MyAttribute("test");
+
+ assertTrue(attribute.equals(attribute));
+
+ /* this implementation of equals should only return true
+ * if the same objects */
+ assertFalse(attribute.equals(new MyAttribute("test")));
+
+ attribute = new MyAttribute(null);
+ assertFalse(attribute.equals(new MyAttribute(null)));
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator$Attribute#readResolve()
+ */
+ public void test_readResolve() {
+ // test for method java.lang.Object readResolve()
+
+ ObjectOutputStream out = null;
+ ObjectInputStream in = null;
+ try {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(bytes);
+
+ AttributedCharacterIterator.Attribute dattribute, dattribute2;
+ MyAttribute attribute;
+
+ // a regular instance of DateFormat.Field
+ dattribute = AttributedCharacterIterator.Attribute.LANGUAGE;
+
+ // a subclass instance with null name
+ attribute = new MyAttribute(null);
+
+ out.writeObject(dattribute);
+ try {
+ out.writeObject(attribute);
+ } catch (NotSerializableException e) {
+ }
+
+ in = new ObjectInputStream(new ByteArrayInputStream(bytes
+ .toByteArray()));
+
+ try {
+ dattribute2 = (AttributedCharacterIterator.Attribute) in.readObject();
+ assertSame("resolved incorrectly", dattribute, dattribute2);
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException: " + e);
+ }
+
+ } catch (IOException e) {
+ fail("unexpected IOException" + e);
+ } catch (ClassNotFoundException e) {
+ fail("unexpected ClassNotFoundException" + e);
+ } finally {
+ try {
+ if (out != null)
+ out.close();
+ if (in != null)
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator$Attribute#LANGUAGE
+ * java.text.AttributedCharacterIterator$Attribute#READING
+ * java.text.AttributedCharacterIterator$Attribute#INPUT_METHOD_SEGMENT
+ */
+ public void test_fields() {
+
+ // Just check that the fields are accessible as all
+ // methods are protected
+ Attribute language = Attribute.LANGUAGE;
+ Attribute reading = Attribute.READING;
+ Attribute inputMethodSegment = Attribute.INPUT_METHOD_SEGMENT;
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+
+ class MyAttribute extends AttributedCharacterIterator.Attribute {
+ protected MyAttribute(String name) {
+ super(name);
+ }
+
+ public Object getExposedName() {
+ return this.getName();
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedCharacterIteratorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedCharacterIteratorTest.java
new file mode 100644
index 0000000..12164bc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedCharacterIteratorTest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.text.CharacterIterator;
+
+public class AttributedCharacterIteratorTest extends junit.framework.TestCase {
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#current()
+ */
+ public void test_current() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator();
+ assertEquals("Wrong first", 'T', it.current());
+ it.next();
+ assertEquals("Wrong second", 'e', it.current());
+ for (int i = 0; i < 9; i++)
+ it.next();
+ assertEquals("Wrong last", 'g', it.current());
+ it.next();
+ assertTrue("Wrong final", it.current() == CharacterIterator.DONE);
+
+ it = attrString.getIterator(null, 2, 8);
+ assertEquals("Wrong first2", 's', it.current());
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#first()
+ */
+ public void test_first() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator();
+ assertEquals("Wrong first1", 'T', it.first());
+ it = attrString.getIterator(null, 0, 3);
+ assertEquals("Wrong first2", 'T', it.first());
+ it = attrString.getIterator(null, 2, 8);
+ assertEquals("Wrong first3", 's', it.first());
+ it = attrString.getIterator(null, 11, 11);
+ assertTrue("Wrong first4", it.first() == CharacterIterator.DONE);
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#getBeginIndex()
+ */
+ public void test_getBeginIndex() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator(null, 2, 6);
+ assertEquals("Wrong begin index", 2, it.getBeginIndex());
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#getEndIndex()
+ */
+ public void test_getEndIndex() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator(null, 2, 6);
+ assertEquals("Wrong begin index", 6, it.getEndIndex());
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#getIndex()
+ */
+ public void test_getIndex() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator();
+ assertEquals("Wrong first", 0, it.getIndex());
+ it.next();
+ assertEquals("Wrong second", 1, it.getIndex());
+ for (int i = 0; i < 9; i++)
+ it.next();
+ assertEquals("Wrong last", 10, it.getIndex());
+ it.next();
+ assertEquals("Wrong final", 11, it.getIndex());
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#last()
+ */
+ public void test_last() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator();
+ assertEquals("Wrong last1", 'g', it.last());
+ it = attrString.getIterator(null, 0, 3);
+ assertEquals("Wrong last2", 's', it.last());
+ it = attrString.getIterator(null, 2, 8);
+ assertEquals("Wrong last3", 'r', it.last());
+ it = attrString.getIterator(null, 0, 0);
+ assertTrue("Wrong last4", it.last() == CharacterIterator.DONE);
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#next()
+ */
+ public void test_next() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator();
+ assertEquals("Wrong first", 'e', it.next());
+ for (int i = 0; i < 8; i++)
+ it.next();
+ assertEquals("Wrong last", 'g', it.next());
+ assertTrue("Wrong final", it.next() == CharacterIterator.DONE);
+
+ it = attrString.getIterator(null, 2, 8);
+ assertEquals("Wrong first2", 't', it.next());
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#previous()
+ */
+ public void test_previous() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator();
+ it.setIndex(11);
+ assertEquals("Wrong first", 'g', it.previous());
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#setIndex(int)
+ */
+ public void test_setIndexI() {
+ String test = "Test 23ring";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator();
+ it.setIndex(5);
+ assertEquals("Wrong first", '2', it.current());
+ }
+
+ /**
+ * @tests java.text.AttributedCharacterIterator#getRunLimit(java.text.AttributedCharacterIterator$Attribute)
+ */
+ public void test_getRunLimitLjava_text_AttributedCharacterIterator$Attribute() {
+ AttributedString as = new AttributedString("test");
+ as.addAttribute(AttributedCharacterIterator.Attribute.LANGUAGE, "a", 2,
+ 3);
+ AttributedCharacterIterator it = as.getIterator();
+ assertEquals("non-null value limit",
+ 2, it.getRunLimit(AttributedCharacterIterator.Attribute.LANGUAGE));
+
+ as = new AttributedString("test");
+ as.addAttribute(AttributedCharacterIterator.Attribute.LANGUAGE, null,
+ 2, 3);
+ it = as.getIterator();
+ assertEquals("null value limit",
+ 4, it.getRunLimit(AttributedCharacterIterator.Attribute.LANGUAGE));
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedStringTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedStringTest.java
new file mode 100644
index 0000000..a0a4e16
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/AttributedStringTest.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.text.CharacterIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.WeakHashMap;
+
+public class AttributedStringTest extends junit.framework.TestCase {
+
+ /**
+ * @tests java.text.AttributedString#AttributedString(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ String test = "Test string";
+ AttributedString attrString = new AttributedString(test);
+ AttributedCharacterIterator it = attrString.getIterator();
+ StringBuffer buf = new StringBuffer();
+ buf.append(it.first());
+ char ch;
+ while ((ch = it.next()) != CharacterIterator.DONE)
+ buf.append(ch);
+ assertTrue("Wrong string: " + buf, buf.toString().equals(test));
+ }
+
+ /**
+ * @tests java.text.AttributedString#AttributedString(AttributedCharacterIterator)
+ */
+ public void test_ConstructorLAttributedCharacterIterator() {
+ //Regression for HARMONY-1354
+ assertNotNull(new AttributedString(new testAttributedCharacterIterator()));
+ }
+ /**
+ * @tests java.text.AttributedString#AttributedString(AttributedCharacterIterator, int, int)
+ */
+ public void test_ConstructorLAttributedCharacterIteratorII() {
+ //Regression for HARMONY-1355
+ assertNotNull(new AttributedString(new testAttributedCharacterIterator(), 0, 0));
+ }
+
+ private class testAttributedCharacterIterator implements AttributedCharacterIterator {
+ public Set getAllAttributeKeys() {
+ return null;
+ }
+ public Object getAttribute(AttributedCharacterIterator.Attribute p) {
+ return null;
+ }
+ public Map getAttributes() {
+ return null;
+ }
+ public int getRunLimit(Set p) {
+ return 0;
+ }
+ public int getRunLimit(AttributedCharacterIterator.Attribute p) {
+ return 0;
+ }
+ public int getRunLimit() {
+ return 0;
+ }
+ public int getRunStart(Set p) {
+ return 0;
+ }
+ public int getRunStart(AttributedCharacterIterator.Attribute p) {
+ return 0;
+ }
+ public int getRunStart() {
+ return 0;
+ }
+ public Object clone() {
+ return null;
+ }
+ public int getIndex() {
+ return 0;
+ }
+ public int getEndIndex() {
+ return 0;
+ }
+ public int getBeginIndex() {
+ return 0;
+ }
+ public char setIndex(int p) {
+ return 'a';
+ }
+ public char previous() {
+ return 'a';
+ }
+ public char next() {
+ return 'a';
+ }
+ public char current() {
+ return 'a';
+ }
+ public char last() {
+ return 'a';
+ }
+ public char first() {
+ return 'a';
+ }
+ }
+
+ public void test_addAttributeLjava_text_AttributedCharacterIterator$AttributeLjava_lang_ObjectII() {
+ AttributedString as = new AttributedString("test");
+ as.addAttribute(AttributedCharacterIterator.Attribute.LANGUAGE, "a", 2,
+ 3);
+ AttributedCharacterIterator it = as.getIterator();
+ assertEquals("non-null value limit", 2, it
+ .getRunLimit(AttributedCharacterIterator.Attribute.LANGUAGE));
+
+ as = new AttributedString("test");
+ as.addAttribute(AttributedCharacterIterator.Attribute.LANGUAGE, null,
+ 2, 3);
+ it = as.getIterator();
+ assertEquals("null value limit", 4, it
+ .getRunLimit(AttributedCharacterIterator.Attribute.LANGUAGE));
+
+ try {
+ as = new AttributedString("test");
+ as.addAttribute(AttributedCharacterIterator.Attribute.LANGUAGE,
+ null, -1, 3);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // regression for Harmony-1244
+ as = new AttributedString("123", new WeakHashMap());
+ try {
+ as.addAttribute(null, new TreeSet(), 0, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ as.addAttribute(null, new TreeSet(), -1, 1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.text.AttributedString.addAttribute(AttributedCharacterIterator, Object)
+ */
+ public void test_addAttributeLjava_text_AttributedCharacterIterator$AttributeLjava_lang_Object() {
+ //regression for Harmony-1244
+ AttributedString as = new AttributedString("123", new WeakHashMap());
+ try {
+ as.addAttribute(null, new TreeSet());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ as.addAttribute(null, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/BidiTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/BidiTest.java
new file mode 100644
index 0000000..52a29a2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/BidiTest.java
@@ -0,0 +1,964 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.AttributedString;
+import java.text.Bidi;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+public class BidiTest extends TestCase {
+
+ Bidi bd;
+
+ public static void assertRunArrayEquals(int[][] expected, Bidi bidi) {
+ assertEquals("different length", expected.length, bidi.getRunCount());
+
+ FORRUN: for (int i = 0; i < bidi.getRunCount(); i++) {
+ int[] butWas = new int[] { bidi.getRunStart(i),
+ bidi.getRunLimit(i), bidi.getRunLevel(i) };
+
+ for (int j = 0; j < expected.length; j++) {
+ if (expected[j][0] == butWas[0] && expected[j][1] == butWas[1]
+ && expected[j][2] == butWas[2]) {
+ continue FORRUN;
+ }
+ }
+ fail("expected [" + i + "] " + " start: " + butWas[0] + " limit: "
+ + butWas[1] + " level: " + butWas[2]);
+ }
+ }
+
+ public void testNullPointerConstructor() {
+ try {
+ bd = new Bidi(null, Bidi.DIRECTION_RIGHT_TO_LEFT);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi(null, 0, new byte[] { 0 }, 0, 0,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi(null);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ }
+
+ bd = new Bidi("a".toCharArray(), 0, null, 0, 1,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ }
+
+ public void testBadLength() {
+ try {
+ bd = new Bidi("1".toCharArray(), 0, new byte[] { 0 }, 0, 20,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi("1234567".toCharArray(), 0, new byte[] { 0 }, 0, 4,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi("1234567".toCharArray(), 4, new byte[] { 0, 1, 2, 3,
+ 4 }, 0, 5, Bidi.DIRECTION_RIGHT_TO_LEFT);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi("1234567".toCharArray(), 0, new byte[] { 0, 1, 2, 3,
+ 4 }, 4, 5, Bidi.DIRECTION_RIGHT_TO_LEFT);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ //regression for HARMONY-1031
+ try {
+ bd = new Bidi(new char[] { 't','t','t'}, -1, new byte[] { 2, 2 }, 1, 1, 1);
+ fail("should be IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi(new char[] { 't','t','t'}, 1, new byte[] { 2, 2 }, -1, 1, 1);
+ fail("should be IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi(new char[] { 't','t','t'}, 1, new byte[] { 2, 2 }, 1, -1, 1);
+ fail("should be IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi(new char[] {}, 5, new byte[] { 2, 2, 2, 2, 2, 2 }, 8, Integer.MAX_VALUE, 5);
+ fail("should be IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ bd = new Bidi(null, 5, null, 8, Integer.MAX_VALUE, 5);
+ fail("should be IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ bd = new Bidi(new char[] {'o'}, 0, new byte[] { 2, 2}, 2, 0, 2 );
+ }
+
+ public void testEmptyParagraph() {
+ bd = new Bidi("", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(0, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 0, 0 } }, bd);
+ assertTrue(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(0, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 0, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertTrue(bd.isRightToLeft());
+
+ bd = new Bidi("", Bidi.DIRECTION_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(0, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 0, 0 }, }, bd);
+ assertTrue(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("", Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(0, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 0, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertTrue(bd.isRightToLeft());
+ }
+
+ public void testSpaceParagraph() {
+ bd = new Bidi(" ", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
+ assertTrue(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi(" ", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertTrue(bd.isRightToLeft());
+
+ bd = new Bidi(" ", Bidi.DIRECTION_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
+ assertTrue(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi(" ", Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertTrue(bd.isRightToLeft());
+ }
+
+ public void testSimpleParagraph() {
+ bd = new Bidi("t", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
+ assertTrue(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("t", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
+ assertTrue(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("t", Bidi.DIRECTION_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
+ assertTrue(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testBadFlags() {
+ bd = new Bidi("", 173);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(0, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 0, 0 }, }, bd);
+ assertTrue(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testBadEmbeddings() {
+ try {
+ bd = new Bidi("".toCharArray(), 0, new byte[] {}, 0, 1,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testOverrideEmbeddings() {
+ bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -7,
+ (byte) -2, (byte) -3 }, 0, 3,
+ Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(7, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(3, bd.getLevelAt(2));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(3, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 7 }, { 1, 2, 2 },
+ { 2, 3, 3 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -1,
+ (byte) -2, (byte) -3 }, 0, 3,
+ Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(3, bd.getLevelAt(2));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(3, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
+ { 2, 3, 3 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -1,
+ (byte) -2, (byte) -3 }, 0, 3, Bidi.DIRECTION_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(3, bd.getLevelAt(2));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(3, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
+ { 2, 3, 3 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -1,
+ (byte) -2, (byte) -3 }, 0, 3, Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(3, bd.getLevelAt(2));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(3, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
+ { 2, 3, 3 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testDefaultEmbeddings() {
+ bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) 0,
+ (byte) 0, (byte) 0 }, 0, 3, Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(2, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(2, bd.getLevelAt(2));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 3, 2 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testRelativeEmbeddings() {
+ bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) 1,
+ (byte) 2, (byte) 3 }, 0, 3, Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(2, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(4, bd.getLevelAt(2));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 2, 2 }, { 2, 3, 4 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testSimpleHebrewParagraph() {
+ bd = new Bidi("\u05D0", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertTrue(bd.isRightToLeft());
+
+ bd = new Bidi("\u05D0", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertTrue(bd.isRightToLeft());
+
+ bd = new Bidi("\u05D0", Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertFalse(bd.isMixed());
+ assertTrue(bd.isRightToLeft());
+ }
+
+ public void testSimpleBidiParagraph_1() {
+ bd = new Bidi("\u05D0a", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(2, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("\u05D0a", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(2, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("\u05D0a", Bidi.DIRECTION_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(2, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 0 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("\u05D0a", Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(2, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testSimpleBidiParagraph_2() {
+ bd = new Bidi("a\u05D0", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(2, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 0 }, { 1, 2, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("a\u05D0", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(2, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 0 }, { 1, 2, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("a\u05D0", Bidi.DIRECTION_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(2, bd.getLength());
+ assertEquals(0, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 0 }, { 1, 2, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi("a\u05D0", Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(2, bd.getLength());
+ assertEquals(2, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(2, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 2 }, { 1, 2, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ /*
+ * spec reads: public static final int DIRECTION_RIGHT_TO_LEFT Constant
+ * indicating base direction is right-to-left. according to that, the method
+ * baseIsLeftToRight() here should return false. however, RI doesn't act so.
+ */
+ public void testRIBug_1() {
+ bd = new Bidi("t", Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ // the base level it the essential cause
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(2, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 2 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ // this is essentially the same bug as Bug_1
+ public void testRIBug_2() {
+ bd = new Bidi("\u05D0", Bidi.DIRECTION_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(1, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(1, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testComplicatedBidi() {
+ bd = new Bidi("a\u05D0a\"a\u05D0\"\u05D0a",
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(9, bd.getLength());
+ assertEquals(2, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1));
+ assertEquals(2, bd.getLevelAt(2));
+ assertEquals(2, bd.getLevelAt(3));
+ assertEquals(2, bd.getLevelAt(4));
+ assertEquals(1, bd.getLevelAt(5));
+ assertEquals(1, bd.getLevelAt(6));
+ assertEquals(1, bd.getLevelAt(7));
+ assertEquals(2, bd.getLevelAt(8));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(5, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 2 }, { 1, 2, 1 },
+ { 2, 5, 2 }, { 5, 8, 1 }, { 8, 9, 2 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testComplicatedOverrideBidi() {
+ bd = new Bidi("a\u05D0a\"a\u05D0\"\u05D0a".toCharArray(), 0,
+ new byte[] { 0, 0, 0, -3, -3, 2, 2, 0, 3 }, 0, 9,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(9, bd.getLength());
+ assertEquals(2, bd.getLevelAt(0));
+ assertEquals(1, bd.getLevelAt(1));
+ assertEquals(2, bd.getLevelAt(2));
+ assertEquals(3, bd.getLevelAt(3));
+ assertEquals(3, bd.getLevelAt(4));
+ assertEquals(3, bd.getLevelAt(5));
+ assertEquals(2, bd.getLevelAt(6));
+ assertEquals(1, bd.getLevelAt(7));
+ assertEquals(4, bd.getLevelAt(8));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(7, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 2 }, { 1, 2, 1 },
+ { 2, 3, 2 }, { 3, 6, 3 }, { 6, 7, 2 }, { 7, 8, 1 },
+ { 8, 9, 4 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testRequiresBidi() {
+ try{
+ Bidi.requiresBidi(null, 0, 0);
+ fail("should throw NullPointerException");
+ }catch (NullPointerException e){
+ // expected
+ }
+
+ try {
+ assertFalse(Bidi.requiresBidi(null, 0, 1));
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ assertFalse(Bidi.requiresBidi("".toCharArray(), 0, 1));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ assertFalse(Bidi.requiresBidi("aaa".toCharArray(), -1, 1));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 1, -1));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ assertFalse(Bidi.requiresBidi("\u05D0".toCharArray(), 1, -1));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 1, 0));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 7, 7));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 1, Integer.MAX_VALUE));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ assertFalse(Bidi.requiresBidi("aaa".toCharArray(), Integer.MAX_VALUE, 1));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertFalse(Bidi.requiresBidi("".toCharArray(), 0, 0));
+ assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 1, 1));
+ assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 0, 2));
+ assertFalse(Bidi.requiresBidi("\u05D0".toCharArray(), 1, 1));
+ assertTrue(Bidi.requiresBidi("\u05D0".toCharArray(), 0, 1));
+ assertFalse(Bidi.requiresBidi("aa\u05D0a".toCharArray(), 0, 2));
+ assertTrue(Bidi.requiresBidi("aa\u05D0a".toCharArray(), 1, 3));
+ }
+
+ public void testHebrewOverrideEmbeddings() {
+ bd = new Bidi(new char[] { '\u05D0', '\u05D0', '\u05D0' }, 0,
+ new byte[] { (byte) -1, (byte) -2, (byte) -3 }, 0, 3,
+ Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(3, bd.getLevelAt(2));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(3, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
+ { 2, 3, 3 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi(new char[] { '\u05D0', '\u05D0', '\u05D0' }, 0,
+ new byte[] { (byte) -1, (byte) -2, (byte) -3 }, 0, 3,
+ Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(3, bd.getLevelAt(2));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(3, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
+ { 2, 3, 3 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi(new char[] { '\u05D0', '\u05D0', '\u05D0' }, 0,
+ new byte[] { (byte) -1, (byte) -2, (byte) -3 }, 0, 3,
+ Bidi.DIRECTION_LEFT_TO_RIGHT);
+ assertTrue(bd.baseIsLeftToRight());
+ assertEquals(0, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(3, bd.getLevelAt(2));
+ assertEquals(0, bd.getLevelAt(1000));
+ assertEquals(3, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
+ { 2, 3, 3 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+
+ bd = new Bidi(new char[] { '\u05D0', '\u05D0', '\u05D0' }, 0,
+ new byte[] { (byte) -1, (byte) -2, (byte) -3 }, 0, 3,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ assertFalse(bd.baseIsLeftToRight());
+ assertEquals(1, bd.getBaseLevel());
+ assertEquals(3, bd.getLength());
+ assertEquals(1, bd.getLevelAt(0));
+ assertEquals(2, bd.getLevelAt(1));
+ assertEquals(3, bd.getLevelAt(2));
+ assertEquals(1, bd.getLevelAt(1000));
+ assertEquals(3, bd.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
+ { 2, 3, 3 }, }, bd);
+ assertFalse(bd.isLeftToRight());
+ assertTrue(bd.isMixed());
+ assertFalse(bd.isRightToLeft());
+ }
+
+ public void testCreateLineBidi() {
+ bd = new Bidi("a\u05D0a\u05D0a\u05D0\"\u05D0a".toCharArray(), 0,
+ new byte[] { 0, 0, 0, -3, -3, 2, 2, 0, 3 }, 0, 9,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ Bidi line = bd.createLineBidi(2, 7);
+ assertFalse(line.baseIsLeftToRight());
+ assertEquals(1, line.getBaseLevel());
+ assertEquals(5, line.getLength());
+ assertEquals(2, line.getLevelAt(0));
+ assertEquals(3, line.getLevelAt(1));
+ assertEquals(3, line.getLevelAt(2));
+ assertEquals(3, line.getLevelAt(3));
+ assertEquals(2, line.getLevelAt(4));
+ assertEquals(1, line.getLevelAt(1000));
+ assertEquals(3, line.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 1, 2 }, { 1, 4, 3 },
+ { 4, 5, 2 }, }, line);
+ assertFalse(line.isLeftToRight());
+ assertTrue(line.isMixed());
+ assertFalse(line.isRightToLeft());
+ }
+
+ public void testCreateLineBidiInvalid() {
+ //regression for HARMONY-1050
+ Bidi bidi = new Bidi("str", 1);
+ try {
+ bidi.createLineBidi(-1, 1);
+ fail("Expected IAE");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ bidi.createLineBidi(1, -1);
+ fail("Expected IAE");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ bidi.createLineBidi(-1, -1);
+ fail("Expected IAE");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ bidi.createLineBidi(2, 1);
+ fail("Expected IAE");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ bidi.createLineBidi(2, 2);
+ }catch (IllegalArgumentException e){
+ // Expected
+ }
+
+ try {
+ bidi.createLineBidi(2, 4);
+ fail("Expected IAE");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void testIncompatibleLineAlgorithm() {
+ // ICU treat a new line as in the same run, however RI does not
+ bd = new Bidi("aaaaa".toCharArray(), 0,
+ new byte[] { -2, -1, -3, -3, -2 }, 0, 5,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ Bidi line = bd.createLineBidi(1, 4);
+ assertFalse(line.baseIsLeftToRight());
+ assertEquals(1, line.getBaseLevel());
+ assertEquals(3, line.getLength());
+ assertEquals(1, line.getLevelAt(0));
+ assertEquals(1, line.getLevelAt(1));
+ assertEquals(1, line.getLevelAt(2));
+ assertEquals(1, line.getLevelAt(1000));
+ assertEquals(1, line.getRunCount());
+ assertRunArrayEquals(new int[][] { { 0, 3, 1 }, }, line);
+ assertFalse(line.isLeftToRight());
+ assertFalse(line.isMixed());
+ assertTrue(line.isRightToLeft());
+ }
+
+ public void testReorderVisually() {
+ String[] init = new String[] { "a", "b", "c", "d" };
+ String[] s = new String[4];
+
+ System.arraycopy(init, 0, s, 0, s.length);
+ Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 0, s, 0, 4);
+ assertEquals("[c, b, a, d]", Arrays.asList(s).toString());
+
+ System.arraycopy(init, 0, s, 0, s.length);
+ Bidi.reorderVisually(new byte[] { 1, 3 }, 0, s, 1, 2);
+ assertEquals("[a, c, b, d]", Arrays.asList(s).toString());
+
+ System.arraycopy(init, 0, s, 0, s.length);
+ Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 1, s, 1, 2);
+ assertEquals("[a, c, b, d]", Arrays.asList(s).toString());
+
+ System.arraycopy(init, 0, s, 0, s.length);
+ Bidi.reorderVisually(new byte[] { 2, 1, 2, 1 }, 1, s, 0, 3);
+ assertEquals("[c, b, a, d]", Arrays.asList(s).toString());
+
+ System.arraycopy(init, 0, s, 0, s.length);
+ Bidi.reorderVisually(new byte[] { 2, 1, 0, 1 }, 1, s, 0, 3);
+ assertEquals("[a, b, c, d]", Arrays.asList(s).toString());
+ }
+
+ public void testBadReorderVisually() {
+ String[] s = new String[] { "a", "b", "c", "d" };
+
+ try {
+ Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 0, s, 0, 5);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 0, s, -1, 1);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, -1, s, 0, 1);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ Bidi.reorderVisually(null, 0, s, 0, 1);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 0, null, 0, 1);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 1, s, 0, -1);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ }
+
+ public void testGetRuns() {
+ //Regression test for Harmony-1028
+
+ String LTR = "\u0061\u0062";
+ String RTL = "\u05DC\u05DD";
+ String newLine = "\n";
+ String defText = LTR + newLine + RTL + LTR + RTL;
+
+ int[][] expectedRuns = {
+ {0, 3},
+ {3, 5},
+ {5, 7},
+ {7, 9},
+ };
+
+ Bidi bi = new Bidi(defText, 0);
+ final int count = bi.getRunCount();
+ for (int i = 0; i < count; i++) {
+ assertEquals(expectedRuns[i][0], bi.getRunStart(i));
+ assertEquals(expectedRuns[i][1], bi.getRunLimit(i));
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/BreakIteratorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/BreakIteratorTest.java
new file mode 100644
index 0000000..d12f9ac
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/BreakIteratorTest.java
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+public class BreakIteratorTest extends TestCase {
+
+ private static final String TEXT = "a\u0308abc def, gh-12i?jkl.mno?";
+
+ BreakIterator iterator;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ iterator = BreakIterator.getCharacterInstance(Locale.US);
+ }
+
+ public void testConsts() {
+ assertEquals(-1, BreakIterator.DONE);
+ }
+
+ public void testCache() {
+ BreakIterator newOne = BreakIterator.getCharacterInstance(Locale.US);
+ assertNotSame(newOne, iterator);
+ assertEquals(newOne, iterator);
+
+ newOne = BreakIterator.getCharacterInstance();
+ assertEquals(newOne, iterator);
+
+ newOne = BreakIterator.getCharacterInstance(Locale.CHINA);
+ assertEquals(newOne, iterator);
+
+ BreakIterator wordIterator = BreakIterator.getWordInstance();
+ assertFalse(wordIterator.equals(iterator));
+
+ BreakIterator lineIterator = BreakIterator.getLineInstance();
+ assertFalse(lineIterator.equals(iterator));
+
+ BreakIterator senteIterator = BreakIterator.getSentenceInstance();
+ assertFalse(senteIterator.equals(iterator));
+ }
+
+ public void testClone() {
+ BreakIterator cloned = (BreakIterator) iterator.clone();
+ assertNotSame(cloned, iterator);
+ assertEquals(cloned, iterator);
+ }
+
+ public void testCurrent() {
+ assertEquals(0, iterator.current());
+ iterator.setText(TEXT);
+ assertEquals(iterator.first(), iterator.current());
+ }
+
+ public void testFirst() {
+ assertEquals(0, iterator.first());
+ iterator.setText(TEXT);
+ assertEquals(0, iterator.first());
+ }
+
+ public void testFollowing() {
+ try {
+ iterator.following(1);
+ fail("should throw illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+ iterator.setText(TEXT);
+ assertEquals(2, iterator.following(1));
+ try {
+ assertEquals(0, iterator.following(-1));
+ fail("should throw illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+ assertEquals(BreakIterator.DONE, iterator.following(TEXT.length()));
+ }
+
+ public void testIsBoundary() {
+ try {
+ iterator.isBoundary(2);
+ fail("should throw illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+ iterator.setText(TEXT);
+ assertTrue(iterator.isBoundary(2));
+ assertFalse(iterator.isBoundary(1));
+ assertTrue(iterator.isBoundary(0));
+ try {
+ iterator.isBoundary(-1);
+ fail("should throw illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+ assertTrue(iterator.isBoundary(TEXT.length()));
+ }
+
+ public void testLast() {
+ assertEquals(0, iterator.last());
+ iterator.setText(TEXT);
+ assertEquals(TEXT.length(), iterator.last());
+ }
+
+ /*
+ * Class under test for int next(int)
+ */
+ public void testNextint() {
+ assertEquals(BreakIterator.DONE, iterator.next(3));
+ iterator.setText(TEXT);
+ assertEquals(4, iterator.next(3));
+ assertEquals(24, iterator.next(20));
+ assertEquals(23, iterator.next(-1));
+ assertEquals(-1, iterator.next(TEXT.length()));
+ }
+
+ public void testPreceding() {
+ try {
+ iterator.preceding(2);
+ fail("should throw illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+ iterator.setText(TEXT);
+ assertEquals(0, iterator.preceding(2));
+ assertEquals(2, iterator.preceding(3));
+ assertEquals(16, iterator.preceding(17));
+ assertEquals(17, iterator.preceding(18));
+ assertEquals(18, iterator.preceding(19));
+ try {
+ iterator.preceding(-1);
+ fail("should throw illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+ assertEquals(TEXT.length() - 1, iterator.preceding(TEXT.length()));
+ assertEquals(BreakIterator.DONE, iterator.preceding(0));
+ }
+
+ public void testPrevious() {
+ assertEquals(-1, iterator.previous());
+ iterator.setText(TEXT);
+ assertEquals(-1, iterator.previous());
+ iterator.last();
+ assertEquals(TEXT.length() - 1, iterator.previous());
+ }
+
+ public void testGetAvailableLocales() {
+ Locale[] locales = BreakIterator.getAvailableLocales();
+ assertTrue(locales.length > 0);
+ }
+
+ /*
+ * Class under test for BreakIterator getCharacterInstance()
+ */
+ public void testGetCharacterInstance() {
+ BreakIterator.getCharacterInstance();
+ }
+
+ /*
+ * Class under test for BreakIterator getCharacterInstance(Locale)
+ */
+ public void testGetCharacterInstanceLocale() {
+ BreakIterator it = BreakIterator.getCharacterInstance(Locale.US);
+ BreakIterator it2 = BreakIterator.getCharacterInstance(Locale.CHINA);
+ assertEquals(it, it2);
+ }
+
+ /*
+ * Class under test for BreakIterator getLineInstance()
+ */
+ public void testGetLineInstance() {
+ BreakIterator it = BreakIterator.getLineInstance();
+ assertNotNull(it);
+ }
+
+ /*
+ * Class under test for BreakIterator getLineInstance(Locale)
+ */
+ public void testGetLineInstanceLocale() {
+ BreakIterator it = BreakIterator.getLineInstance(Locale.US);
+ assertNotNull(it);
+ BreakIterator.getLineInstance(new Locale("bad locale"));
+ }
+
+ /*
+ * Class under test for BreakIterator getSentenceInstance()
+ */
+ public void testGetSentenceInstance() {
+ BreakIterator it = BreakIterator.getSentenceInstance();
+ assertNotNull(it);
+ }
+
+ /*
+ * Class under test for BreakIterator getSentenceInstance(Locale)
+ */
+ public void testGetSentenceInstanceLocale() {
+ BreakIterator it = BreakIterator.getSentenceInstance(Locale.US);
+ assertNotNull(it);
+ }
+
+ public void testGetText() {
+ assertEquals(new StringCharacterIterator(""), iterator.getText());
+ iterator.setText(TEXT);
+ assertEquals(new StringCharacterIterator(TEXT), iterator.getText());
+ }
+
+ /*
+ * Class under test for BreakIterator getWordInstance()
+ */
+ public void testGetWordInstance() {
+ BreakIterator it = BreakIterator.getWordInstance();
+ assertNotNull(it);
+ }
+
+ /*
+ * Class under test for BreakIterator getWordInstance(Locale)
+ */
+ public void testGetWordInstanceLocale() {
+ BreakIterator it = BreakIterator.getWordInstance(Locale.US);
+ assertNotNull(it);
+ }
+
+ /*
+ * Class under test for void setText(CharacterIterator)
+ */
+ public void testSetTextCharacterIterator() {
+ try {
+ iterator.setText((CharacterIterator) null);
+ fail();
+ } catch (NullPointerException e) {
+ }
+ CharacterIterator it = new StringCharacterIterator("abc");
+ iterator.setText(it);
+ assertSame(it, iterator.getText());
+ }
+
+ /*
+ * Class under test for void setText(String)
+ */
+ public void testSetTextString() {
+ try {
+ iterator.setText((String) null);
+ fail();
+ } catch (NullPointerException e) {
+ }
+ iterator.setText("abc");
+ CharacterIterator it = new StringCharacterIterator("abc");
+ assertEquals(it, iterator.getText());
+ }
+
+ public void test_next() {
+ // Regression test for HARMONY-30
+ BreakIterator bi = BreakIterator.getWordInstance(Locale.US);
+ bi.setText("This is the test, WordInstance");
+ int n = bi.first();
+ n = bi.next();
+ assertEquals("Assert 0: next() returns incorrect value ", 4, n);
+
+ assertEquals(BreakIterator.DONE, iterator.next());
+ iterator.setText(TEXT);
+ assertEquals(2, iterator.next());
+ }
+
+ /**
+ * @tests java.text.BreakIterator#getCharacterInstance(Locale)
+ */
+ public void testGetCharacterInstanceLocale_NPE() {
+ // Regression for HARMONY-265
+ try {
+ BreakIterator.getCharacterInstance(null);
+ fail("BreakIterator.getCharacterInstance(null); should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void testGetLineInstanceLocale_NPE() {
+ try {
+ BreakIterator.getLineInstance(null);
+ fail("BreakIterator.getLineInstance(null); should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void testGetSentenceInstanceLocale_NPE() {
+ try {
+ BreakIterator.getSentenceInstance(null);
+ fail("BreakIterator.getSentenceInstance(null); should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void testGetWordInstanceLocale_NPE() {
+ try {
+ BreakIterator.getWordInstance(null);
+ fail("BreakIterator.getWordInstance(null); should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ChoiceFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ChoiceFormatTest.java
new file mode 100644
index 0000000..e4d6bd8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ChoiceFormatTest.java
@@ -0,0 +1,469 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.ChoiceFormat;
+import java.text.FieldPosition;
+import java.text.MessageFormat;
+import java.text.ParsePosition;
+
+import junit.framework.TestCase;
+
+public class ChoiceFormatTest extends TestCase {
+
+ double[] limits = new double[] { 0, 1, ChoiceFormat.nextDouble(1),
+ ChoiceFormat.nextDouble(2) };
+
+ String[] formats = new String[] { "Less than one", "one",
+ "Between one and two", "Greater than two" };
+
+ ChoiceFormat f1 = new ChoiceFormat(limits, formats);
+
+ /**
+ * @tests java.text.ChoiceFormat#ChoiceFormat(double[], java.lang.String[])
+ */
+ public void test_Constructor$D$Ljava_lang_String() {
+ // Test for method java.text.ChoiceFormat(double [], java.lang.String
+ // [])
+ String formattedString;
+ double[] appleLimits = { 1, 2, 3, 4, 5 };
+ String[] appleFormats = { "Tiny Apple", "Small Apple", "Medium Apple",
+ "Large Apple", "Huge Apple" };
+ ChoiceFormat cf = new ChoiceFormat(appleLimits, appleFormats);
+
+ formattedString = cf.format(Double.NEGATIVE_INFINITY);
+ assertTrue("a) Incorrect format returned: " + formattedString,
+ formattedString.equals("Tiny Apple"));
+ formattedString = cf.format(0.5d);
+ assertTrue("b) Incorrect format returned: " + formattedString,
+ formattedString.equals("Tiny Apple"));
+ formattedString = cf.format(1d);
+ assertTrue("c) Incorrect format returned: " + formattedString,
+ formattedString.equals("Tiny Apple"));
+ formattedString = cf.format(1.5d);
+ assertTrue("d) Incorrect format returned: " + formattedString,
+ formattedString.equals("Tiny Apple"));
+ formattedString = cf.format(2d);
+ assertTrue("e) Incorrect format returned: " + formattedString,
+ formattedString.equals("Small Apple"));
+ formattedString = cf.format(2.5d);
+ assertTrue("f) Incorrect format returned: " + formattedString,
+ formattedString.equals("Small Apple"));
+ formattedString = cf.format(3d);
+ assertTrue("g) Incorrect format returned: " + formattedString,
+ formattedString.equals("Medium Apple"));
+ formattedString = cf.format(4d);
+ assertTrue("h) Incorrect format returned: " + formattedString,
+ formattedString.equals("Large Apple"));
+ formattedString = cf.format(5d);
+ assertTrue("i) Incorrect format returned: " + formattedString,
+ formattedString.equals("Huge Apple"));
+ formattedString = cf.format(5.5d);
+ assertTrue("j) Incorrect format returned: " + formattedString,
+ formattedString.equals("Huge Apple"));
+ formattedString = cf.format(6.0d);
+ assertTrue("k) Incorrect format returned: " + formattedString,
+ formattedString.equals("Huge Apple"));
+ formattedString = cf.format(Double.POSITIVE_INFINITY);
+ assertTrue("l) Incorrect format returned: " + formattedString,
+ formattedString.equals("Huge Apple"));
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#ChoiceFormat(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.text.ChoiceFormat(java.lang.String)
+ String formattedString;
+ String patternString = "-2#Inverted Orange| 0#No Orange| 0<Almost No Orange| 1#Normal Orange| 2#Expensive Orange";
+ ChoiceFormat cf = new ChoiceFormat(patternString);
+
+ formattedString = cf.format(Double.NEGATIVE_INFINITY);
+ assertTrue("a) Incorrect format returned: " + formattedString,
+ formattedString.equals("Inverted Orange"));
+ formattedString = cf.format(-3);
+ assertTrue("b) Incorrect format returned: " + formattedString,
+ formattedString.equals("Inverted Orange"));
+ formattedString = cf.format(-2);
+ assertTrue("c) Incorrect format returned: " + formattedString,
+ formattedString.equals("Inverted Orange"));
+ formattedString = cf.format(-1);
+ assertTrue("d) Incorrect format returned: " + formattedString,
+ formattedString.equals("Inverted Orange"));
+ formattedString = cf.format(-0);
+ assertTrue("e) Incorrect format returned: " + formattedString,
+ formattedString.equals("No Orange"));
+ formattedString = cf.format(0);
+ assertTrue("f) Incorrect format returned: " + formattedString,
+ formattedString.equals("No Orange"));
+ formattedString = cf.format(0.1);
+ assertTrue("g) Incorrect format returned: " + formattedString,
+ formattedString.equals("Almost No Orange"));
+ formattedString = cf.format(1);
+ assertTrue("h) Incorrect format returned: " + formattedString,
+ formattedString.equals("Normal Orange"));
+ formattedString = cf.format(1.5);
+ assertTrue("i) Incorrect format returned: " + formattedString,
+ formattedString.equals("Normal Orange"));
+ formattedString = cf.format(2);
+ assertTrue("j) Incorrect format returned: " + formattedString,
+ formattedString.equals("Expensive Orange"));
+ formattedString = cf.format(3);
+ assertTrue("k) Incorrect format returned: " + formattedString,
+ formattedString.equals("Expensive Orange"));
+ formattedString = cf.format(Double.POSITIVE_INFINITY);
+ assertTrue("l) Incorrect format returned: " + formattedString,
+ formattedString.equals("Expensive Orange"));
+
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#applyPattern(java.lang.String)
+ */
+ public void test_applyPatternLjava_lang_String() {
+ // Test for method void
+ // java.text.ChoiceFormat.applyPattern(java.lang.String)
+ ChoiceFormat f = (ChoiceFormat) f1.clone();
+ f.applyPattern("0#0|1#1");
+ assertTrue("Incorrect limits", java.util.Arrays.equals(f.getLimits(),
+ new double[] { 0, 1 }));
+ assertTrue("Incorrect formats", java.util.Arrays.equals(f.getFormats(),
+ new String[] { "0", "1" }));
+
+ //Regression for Harmony 540
+ double[] choiceLimits = { -1, 0, 1, ChoiceFormat.nextDouble(1) };
+ String[] choiceFormats = { "is negative", "is zero or fraction",
+ "is one", "is more than 1" };
+
+ f = new ChoiceFormat("");
+ f.applyPattern("-1#is negative|0#is zero or fraction|1#is one|1<is more than 1");
+ assertTrue("Incorrect limits", java.util.Arrays.equals(f.getLimits(),
+ choiceLimits));
+ assertTrue("Incorrect formats", java.util.Arrays.equals(f.getFormats(),
+ choiceFormats));
+
+ f = new ChoiceFormat("");
+ try {
+ f.applyPattern("-1#is negative|0#is zero or fraction|-1#is one|1<is more than 1");
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ f = new ChoiceFormat("");
+ try {
+ f.applyPattern("-1is negative|0#is zero or fraction|1#is one|1<is more than 1");
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ f = new ChoiceFormat("");
+ f.applyPattern("-1<is negative|0#is zero or fraction|1#is one|1<is more than 1");
+ choiceLimits[0] = ChoiceFormat.nextDouble(-1);
+ assertTrue("Incorrect limits", java.util.Arrays.equals(f.getLimits(),
+ choiceLimits));
+ assertTrue("Incorrect formats", java.util.Arrays.equals(f.getFormats(),
+ choiceFormats));
+
+ f = new ChoiceFormat("");
+ f.applyPattern("-1#is negative|0#is zero or fraction|1#is one|1<is more than 1");
+ String str = "org.apache.harmony.tests.java.text.ChoiceFormat";
+ f.applyPattern(str);
+ String ptrn = f.toPattern();
+ assertEquals("Return value should be empty string for invalid pattern",
+ 0, ptrn.length());
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.text.ChoiceFormat.clone()
+ ChoiceFormat f = (ChoiceFormat) f1.clone();
+ assertTrue("Not equal", f.equals(f1));
+ f.setChoices(new double[] { 0, 1, 2 }, new String[] { "0", "1", "2" });
+ assertTrue("Equal", !f.equals(f1));
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.text.ChoiceFormat.equals(java.lang.Object)
+
+ String patternString = "-2#Inverted Orange| 0#No Orange| 0<Almost No Orange| 1#Normal Orange| 2#Expensive Orange";
+ double[] appleLimits = { 1, 2, 3, 4, 5 };
+ String[] appleFormats = { "Tiny Apple", "Small Apple", "Medium Apple",
+ "Large Apple", "Huge Apple" };
+ double[] orangeLimits = { -2, 0, ChoiceFormat.nextDouble(0), 1, 2 };
+ String[] orangeFormats = { "Inverted Orange", "No Orange",
+ "Almost No Orange", "Normal Orange", "Expensive Orange" };
+
+ ChoiceFormat appleChoiceFormat = new ChoiceFormat(appleLimits,
+ appleFormats);
+ ChoiceFormat orangeChoiceFormat = new ChoiceFormat(orangeLimits,
+ orangeFormats);
+ ChoiceFormat orangeChoiceFormat2 = new ChoiceFormat(patternString);
+ ChoiceFormat hybridChoiceFormat = new ChoiceFormat(appleLimits,
+ orangeFormats);
+
+ assertTrue("Apples should not equal oranges", !appleChoiceFormat
+ .equals(orangeChoiceFormat));
+ assertTrue("Different limit list--should not appear as equal",
+ !orangeChoiceFormat.equals(hybridChoiceFormat));
+ assertTrue("Different format list--should not appear as equal",
+ !appleChoiceFormat.equals(hybridChoiceFormat));
+ assertTrue("Should be equal--identical format", appleChoiceFormat
+ .equals(appleChoiceFormat));
+ assertTrue("Should be equals--same limits, same formats",
+ orangeChoiceFormat.equals(orangeChoiceFormat2));
+
+ ChoiceFormat f2 = new ChoiceFormat(
+ "0#Less than one|1#one|1<Between one and two|2<Greater than two");
+ assertTrue("Not equal", f1.equals(f2));
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#format(double, java.lang.StringBuffer,
+ * java.text.FieldPosition)
+ */
+ public void test_formatDLjava_lang_StringBufferLjava_text_FieldPosition() {
+ // Test for method java.lang.StringBuffer
+ // java.text.ChoiceFormat.format(double, java.lang.StringBuffer,
+ // java.text.FieldPosition)
+ FieldPosition field = new FieldPosition(0);
+ StringBuffer buf = new StringBuffer();
+ String r = f1.format(-1, buf, field).toString();
+ assertEquals("Wrong choice for -1", "Less than one", r);
+ buf.setLength(0);
+ r = f1.format(0, buf, field).toString();
+ assertEquals("Wrong choice for 0", "Less than one", r);
+ buf.setLength(0);
+ r = f1.format(1, buf, field).toString();
+ assertEquals("Wrong choice for 1", "one", r);
+ buf.setLength(0);
+ r = f1.format(2, buf, field).toString();
+ assertEquals("Wrong choice for 2", "Between one and two", r);
+ buf.setLength(0);
+ r = f1.format(3, buf, field).toString();
+ assertEquals("Wrong choice for 3", "Greater than two", r);
+
+ // Regression test for HARMONY-1081
+ assertEquals(0, new ChoiceFormat("|").format(Double.NaN, new StringBuffer(), new FieldPosition(6)).length());
+ assertEquals(0, new ChoiceFormat("|").format(1, new StringBuffer(), new FieldPosition(6)).length());
+ assertEquals("Less than one", f1.format(Double.NaN, new StringBuffer(), field).toString());
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#format(long, java.lang.StringBuffer,
+ * java.text.FieldPosition)
+ */
+ public void test_formatJLjava_lang_StringBufferLjava_text_FieldPosition() {
+ // Test for method java.lang.StringBuffer
+ // java.text.ChoiceFormat.format(long, java.lang.StringBuffer,
+ // java.text.FieldPosition)
+ FieldPosition field = new FieldPosition(0);
+ StringBuffer buf = new StringBuffer();
+ String r = f1.format(0.5, buf, field).toString();
+ assertEquals("Wrong choice for 0.5", "Less than one", r);
+ buf.setLength(0);
+ r = f1.format(1.5, buf, field).toString();
+ assertEquals("Wrong choice for 1.5", "Between one and two", r);
+ buf.setLength(0);
+ r = f1.format(2.5, buf, field).toString();
+ assertEquals("Wrong choice for 2.5", "Greater than two", r);
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#getFormats()
+ */
+ public void test_getFormats() {
+ // Test for method java.lang.Object []
+ // java.text.ChoiceFormat.getFormats()
+ String[] orgFormats = (String[]) formats.clone();
+ String[] f = (String[]) f1.getFormats();
+ assertTrue("Wrong formats", f.equals(formats));
+ f[0] = "Modified";
+ assertTrue("Formats copied", !f.equals(orgFormats));
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#getLimits()
+ */
+ public void test_getLimits() {
+ // Test for method double [] java.text.ChoiceFormat.getLimits()
+ double[] orgLimits = (double[]) limits.clone();
+ double[] l = f1.getLimits();
+ assertTrue("Wrong limits", l.equals(limits));
+ l[0] = 3.14527;
+ assertTrue("Limits copied", !l.equals(orgLimits));
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.text.ChoiceFormat.hashCode()
+ ChoiceFormat f2 = new ChoiceFormat(
+ "0#Less than one|1#one|1<Between one and two|2<Greater than two");
+ assertTrue("Different hash", f1.hashCode() == f2.hashCode());
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#nextDouble(double)
+ */
+ public void test_nextDoubleD() {
+ // Test for method double java.text.ChoiceFormat.nextDouble(double)
+ assertTrue("Not greater 5", ChoiceFormat.nextDouble(5) > 5);
+ assertTrue("Not greater 0", ChoiceFormat.nextDouble(0) > 0);
+ assertTrue("Not greater -5", ChoiceFormat.nextDouble(-5) > -5);
+ assertTrue("Not NaN", Double.isNaN(ChoiceFormat.nextDouble(Double.NaN)));
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#nextDouble(double, boolean)
+ */
+ public void test_nextDoubleDZ() {
+ // Test for method double java.text.ChoiceFormat.nextDouble(double,
+ // boolean)
+ assertTrue("Not greater 0", ChoiceFormat.nextDouble(0, true) > 0);
+ assertTrue("Not less 0", ChoiceFormat.nextDouble(0, false) < 0);
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#parse(java.lang.String,
+ * java.text.ParsePosition)
+ */
+ public void test_parseLjava_lang_StringLjava_text_ParsePosition() {
+ // Test for method java.lang.Number
+ // java.text.ChoiceFormat.parse(java.lang.String,
+ // java.text.ParsePosition)
+ ChoiceFormat format = new ChoiceFormat("1#one|2#two|3#three");
+ assertEquals("Case insensitive", 0, format
+ .parse("One", new ParsePosition(0)).intValue());
+
+ ParsePosition pos = new ParsePosition(0);
+ Number result = f1.parse("Greater than two", pos);
+ assertTrue("Not a Double1", result instanceof Double);
+ assertTrue("Wrong value ~>2", result.doubleValue() == ChoiceFormat
+ .nextDouble(2));
+ assertEquals("Wrong position ~16", 16, pos.getIndex());
+ pos = new ParsePosition(0);
+ assertTrue("Incorrect result", Double.isNaN(f1.parse("12one", pos)
+ .doubleValue()));
+ assertEquals("Wrong position ~0", 0, pos.getIndex());
+ pos = new ParsePosition(2);
+ result = f1.parse("12one and two", pos);
+ assertTrue("Not a Double2", result instanceof Double);
+ assertEquals("Ignored parse position", 1.0D, result.doubleValue(), 0.0D);
+ assertEquals("Wrong position ~5", 5, pos.getIndex());
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#previousDouble(double)
+ */
+ public void test_previousDoubleD() {
+ // Test for method double java.text.ChoiceFormat.previousDouble(double)
+ assertTrue("Not less 5", ChoiceFormat.previousDouble(5) < 5);
+ assertTrue("Not less 0", ChoiceFormat.previousDouble(0) < 0);
+ assertTrue("Not less -5", ChoiceFormat.previousDouble(-5) < -5);
+ assertTrue("Not NaN", Double.isNaN(ChoiceFormat
+ .previousDouble(Double.NaN)));
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#setChoices(double[], java.lang.String[])
+ */
+ public void test_setChoices$D$Ljava_lang_String() {
+ // Test for method void java.text.ChoiceFormat.setChoices(double [],
+ // java.lang.String [])
+ ChoiceFormat f = (ChoiceFormat) f1.clone();
+ double[] l = new double[] { 0, 1 };
+ String[] fs = new String[] { "0", "1" };
+ f.setChoices(l, fs);
+ assertTrue("Limits copied", f.getLimits() == l);
+ assertTrue("Formats copied", f.getFormats() == fs);
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#toPattern()
+ */
+ public void test_toPattern() {
+ // Regression for HARMONY-59
+ ChoiceFormat cf = new ChoiceFormat("");
+ assertEquals("", cf.toPattern());
+
+ cf = new ChoiceFormat("-1#NEGATIVE_ONE|0#ZERO|1#ONE|1<GREATER_THAN_ONE");
+ assertEquals("-1.0#NEGATIVE_ONE|0.0#ZERO|1.0#ONE|1.0<GREATER_THAN_ONE",
+ cf.toPattern());
+
+ MessageFormat mf = new MessageFormat("CHOICE {1,choice}");
+ String ptrn = mf.toPattern();
+ assertEquals("Unused message format returning incorrect pattern", "CHOICE {1,choice,}", ptrn
+ );
+
+ String pattern = f1.toPattern();
+ assertTrue(
+ "Wrong pattern: " + pattern,
+ pattern
+ .equals("0.0#Less than one|1.0#one|1.0<Between one and two|2.0<Greater than two"));
+
+ cf = new ChoiceFormat(
+ "-1#is negative| 0#is zero or fraction | 1#is one |1.0<is 1+|2#is two |2<is more than 2.");
+ String str = "org.apache.harmony.tests.java.lang.share.MyResources2";
+ cf.applyPattern(str);
+ ptrn = cf.toPattern();
+ assertEquals("Return value should be empty string for invalid pattern",
+ 0, ptrn.length());
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#format(long)
+ */
+ public void test_formatL() {
+ ChoiceFormat fmt = new ChoiceFormat(
+ "-1#NEGATIVE_ONE|0#ZERO|1#ONE|1<GREATER_THAN_ONE");
+
+ assertEquals("NEGATIVE_ONE", fmt.format(Long.MIN_VALUE));
+ assertEquals("NEGATIVE_ONE", fmt.format(-1));
+ assertEquals("ZERO", fmt.format(0));
+ assertEquals("ONE", fmt.format(1));
+ assertEquals("GREATER_THAN_ONE", fmt.format(Long.MAX_VALUE));
+ }
+
+ /**
+ * @tests java.text.ChoiceFormat#format(double)
+ */
+ public void test_formatD() {
+ ChoiceFormat fmt = new ChoiceFormat(
+ "-1#NEGATIVE_ONE|0#ZERO|1#ONE|1<GREATER_THAN_ONE");
+ assertEquals("NEGATIVE_ONE", fmt.format(Double.NEGATIVE_INFINITY));
+ assertEquals("NEGATIVE_ONE", fmt.format(-999999999D));
+ assertEquals("NEGATIVE_ONE", fmt.format(-1.1));
+ assertEquals("NEGATIVE_ONE", fmt.format(-1.0));
+ assertEquals("NEGATIVE_ONE", fmt.format(-0.9));
+ assertEquals("ZERO", fmt.format(0.0));
+ assertEquals("ZERO", fmt.format(0.9));
+ assertEquals("ONE", fmt.format(1.0));
+ assertEquals("GREATER_THAN_ONE", fmt.format(1.1));
+ assertEquals("GREATER_THAN_ONE", fmt.format(999999999D));
+ assertEquals("GREATER_THAN_ONE", fmt.format(Double.POSITIVE_INFINITY));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollationElementIteratorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollationElementIteratorTest.java
new file mode 100644
index 0000000..081b446
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollationElementIteratorTest.java
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.CollationElementIterator;
+import java.text.Collator;
+import java.text.RuleBasedCollator;
+import java.text.StringCharacterIterator;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+/**
+ * Test CollationElementIterator
+ *
+ * Only test normal condition.
+ *
+ */
+public class CollationElementIteratorTest extends TestCase {
+
+ private RuleBasedCollator coll;
+
+ protected void setUp() {
+ coll = (RuleBasedCollator) Collator.getInstance(Locale.US);
+ }
+
+ public void testGetOffset() {
+ String text = "abc";
+ CollationElementIterator iterator = coll.getCollationElementIterator(text);
+ int[] offsets = { 0, 1, 2, 3 };
+ int offset = iterator.getOffset();
+ int i = 0;
+ assertEquals(offsets[i++], offset);
+ while (offset != text.length()) {
+ iterator.next();
+ offset = iterator.getOffset();
+ assertEquals(offsets[i++], offset);
+ }
+ }
+
+ public void testNext() {
+ String text = "abc";
+ CollationElementIterator iterator = coll.getCollationElementIterator(text);
+ int[] orders = new int[text.length()];
+ int order = iterator.next();
+ int i = 0;
+ while (order != CollationElementIterator.NULLORDER) {
+ orders[i++] = order;
+ order = iterator.next();
+ }
+
+ int offset = iterator.getOffset();
+ assertEquals(text.length(), offset);
+
+ iterator.reset();
+ order = iterator.previous();
+
+ while (order != CollationElementIterator.NULLORDER) {
+ assertEquals(orders[--i], order);
+ order = iterator.previous();
+ }
+
+ assertEquals(0, iterator.getOffset());
+ }
+
+ public void testPrevious() {
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(Locale.US);
+ String text = "abc";
+ CollationElementIterator iterator = coll
+ .getCollationElementIterator(text);
+ int[] orders = new int[text.length()];
+ int order = iterator.next();
+ int i = 0;
+ while (order != CollationElementIterator.NULLORDER) {
+ orders[i++] = order;
+ order = iterator.next();
+ }
+
+ int offset = iterator.getOffset();
+ assertEquals(text.length(), offset);
+
+ iterator.reset();
+ order = iterator.previous();
+
+ while (order != CollationElementIterator.NULLORDER) {
+ assertEquals(orders[--i], order);
+ order = iterator.previous();
+ }
+
+ assertEquals(0, iterator.getOffset());
+ }
+
+ public void testReset() {
+ String text = "abc";
+ CollationElementIterator iterator = coll.getCollationElementIterator(text);
+ int[] orders = new int[text.length()];
+ int order = iterator.next();
+ int i = 0;
+ while (order != CollationElementIterator.NULLORDER) {
+ orders[i++] = order;
+ order = iterator.next();
+ }
+
+ int offset = iterator.getOffset();
+ assertEquals(text.length(), offset);
+
+ iterator.reset();
+ assertEquals(0, iterator.getOffset());
+ }
+
+ public void testGetMaxExpansion() {
+ String text = "cha";
+ RuleBasedCollator rbColl = (RuleBasedCollator) Collator.getInstance(
+ Locale.forLanguageTag("es-u-co-trad"));
+ CollationElementIterator iterator = rbColl.getCollationElementIterator(text);
+ int order = iterator.next();
+ while (order != CollationElementIterator.NULLORDER) {
+ assertEquals(1, iterator.getMaxExpansion(order));
+ order = iterator.next();
+ }
+ }
+
+ public void testPrimaryOrder() {
+ RuleBasedCollator rbColl = (RuleBasedCollator) Collator.getInstance(new Locale("de", "DE"));
+ String text = "\u00e6";
+ CollationElementIterator iterator = rbColl.getCollationElementIterator(text);
+ int order = iterator.next();
+ int pOrder = CollationElementIterator.primaryOrder(order);
+ CollationElementIterator iterator2 = rbColl.getCollationElementIterator("ae");
+ int order2 = iterator2.next();
+ int pOrder2 = CollationElementIterator.primaryOrder(order2);
+ assertEquals(pOrder, pOrder2);
+ }
+
+ public void testSecondaryOrder() {
+ RuleBasedCollator rbColl = (RuleBasedCollator) Collator.getInstance(new Locale("fr", "FR"));
+ String text = "a\u00e0";
+ CollationElementIterator iterator = rbColl.getCollationElementIterator(text);
+ int order = iterator.next();
+ int sOrder1 = CollationElementIterator.secondaryOrder(order);
+
+ order = iterator.next();
+ int sOrder2 = CollationElementIterator.secondaryOrder(order);
+
+ assertEquals(sOrder1, sOrder2);
+ }
+
+ public void testTertiaryOrder() {
+ RuleBasedCollator rbColl = (RuleBasedCollator) Collator.getInstance(new Locale("fr", "FR"));
+ String text = "abAB";
+ CollationElementIterator iterator = rbColl.getCollationElementIterator(text);
+ int order = iterator.next();
+ int tOrder1 = CollationElementIterator.tertiaryOrder(order);
+ order = iterator.next();
+ int tOrder2 = CollationElementIterator.tertiaryOrder(order);
+ assertEquals(tOrder1, tOrder2);
+
+ order = iterator.next();
+ tOrder1 = CollationElementIterator.tertiaryOrder(order);
+ order = iterator.next();
+ tOrder2 = CollationElementIterator.tertiaryOrder(order);
+ assertEquals(tOrder1, tOrder2);
+ }
+
+ public void testSetOffset() {
+ RuleBasedCollator rbColl = (RuleBasedCollator) Collator.getInstance(
+ Locale.forLanguageTag("es-u-co-trad"));
+ String text = "cha";
+ CollationElementIterator iterator = rbColl.getCollationElementIterator(text);
+ iterator.setOffset(0);
+ assertEquals(0, iterator.getOffset());
+ iterator.setOffset(1);
+ assertEquals(0, iterator.getOffset());
+ iterator.setOffset(2);
+ assertEquals(2, iterator.getOffset());
+ }
+
+ public void testSetTextString() {
+ RuleBasedCollator rbColl = (RuleBasedCollator) Collator.getInstance(
+ Locale.forLanguageTag("es-u-co-trad"));
+ String text = "caa";
+ CollationElementIterator iterator = rbColl.getCollationElementIterator(text);
+ iterator.setOffset(0);
+ assertEquals(0, iterator.getOffset());
+ iterator.setOffset(1);
+ assertEquals(1, iterator.getOffset());
+ iterator.setOffset(2);
+ assertEquals(2, iterator.getOffset());
+ iterator.setText("cha");
+ iterator.setOffset(0);
+ assertEquals(0, iterator.getOffset());
+ iterator.setOffset(1);
+ assertEquals(0, iterator.getOffset());
+ iterator.setOffset(2);
+ assertEquals(2, iterator.getOffset());
+ }
+
+ public void testSetTextCharacterIterator() {
+ RuleBasedCollator rbColl = (RuleBasedCollator) Collator.getInstance(
+ Locale.forLanguageTag("es-u-co-trad"));
+ String text = "caa";
+ CollationElementIterator iterator = rbColl.getCollationElementIterator(text);
+ iterator.setOffset(1);
+ assertEquals(1, iterator.getOffset());
+ iterator.setText(new StringCharacterIterator("cha"));
+ iterator.setOffset(1);
+ assertEquals(1, iterator.getOffset());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollationKeyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollationKeyTest.java
new file mode 100644
index 0000000..345c25d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollationKeyTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.text.CollationKey;
+import java.text.Collator;
+import java.text.ParseException;
+import java.text.RuleBasedCollator;
+import java.util.Arrays;
+
+public class CollationKeyTest extends junit.framework.TestCase {
+
+ /**
+ * @tests java.text.CollationKey#compareTo(java.text.CollationKey)
+ */
+ public void test_compareToLjava_text_CollationKey() {
+ Collator collator = Collator.getInstance();
+ collator.setStrength(Collator.PRIMARY);
+ CollationKey key1 = collator.getCollationKey("abc");
+ CollationKey key2 = collator.getCollationKey("ABC");
+ assertEquals("Should be equal", 0, key1.compareTo(key2));
+ }
+
+ /**
+ * @tests java.text.CollationKey#compareTo(java.lang.Object)
+ */
+ public void test_compareToLjava_lang_Object() {
+ // Test for method int
+ // java.text.CollationKey.compareTo(java.lang.Object)
+ Collator collator = Collator.getInstance();
+ collator.setStrength(Collator.PRIMARY);
+ CollationKey key1 = collator.getCollationKey("abc");
+ CollationKey key2 = collator.getCollationKey("ABC");
+ assertEquals("Should be equal", 0, key1.compareTo(key2));
+ }
+
+ /**
+ * @tests java.text.CollationKey#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ Collator collator = Collator.getInstance();
+ collator.setStrength(Collator.PRIMARY);
+ CollationKey key1 = collator.getCollationKey("abc");
+ CollationKey key2 = collator.getCollationKey("ABC");
+ assertTrue("Should be equal", key1.equals(key2));
+ }
+
+ /**
+ * @tests java.text.CollationKey#getSourceString()
+ */
+ public void test_getSourceString() {
+ Collator collator = Collator.getInstance();
+ collator.setStrength(Collator.PRIMARY);
+ assertTrue("Wrong source string1", collator.getCollationKey("abc")
+ .getSourceString() == "abc");
+ assertTrue("Wrong source string2", collator.getCollationKey("ABC")
+ .getSourceString() == "ABC");
+ }
+
+ /**
+ * @tests java.text.CollationKey#hashCode()
+ */
+ public void test_hashCode() {
+ Collator collator = Collator.getInstance();
+ collator.setStrength(Collator.PRIMARY);
+ CollationKey key1 = collator.getCollationKey("abc");
+ CollationKey key2 = collator.getCollationKey("ABC");
+ assertTrue("Should be equal", key1.hashCode() == key2.hashCode());
+ }
+
+ /**
+ * @tests java.text.CollationKey#toByteArray()
+ */
+ //FIXME This test fails on Harmony ClassLibrary
+ public void failing_test_toByteArray() {
+ // Test for method byte [] java.text.CollationKey.toByteArray()
+ Collator collator = Collator.getInstance();
+ collator.setStrength(Collator.PRIMARY);
+ CollationKey key1 = collator.getCollationKey("abc");
+ byte[] bytes = key1.toByteArray();
+ assertTrue("Not enough bytes", bytes.length >= 3);
+
+ try {
+ collator = new RuleBasedCollator("= 1 , 2 ; 3 , 4 < 5 ; 6 , 7");
+ } catch (ParseException e) {
+ fail("ParseException");
+ return;
+ }
+ bytes = collator.getCollationKey("1234567").toByteArray();
+ /*
+ * CollationElementIterator it =
+ * ((RuleBasedCollator)collator).getCollationElementIterator("1234567");
+ * int order; while ((order = it.next()) !=
+ * CollationElementIterator.NULLORDER) {
+ * System.out.println(Integer.toHexString(order)); } for (int i=0; i<bytes.length;
+ * i+=2) { System.out.print(Integer.toHexString(bytes[i]) +
+ * Integer.toHexString(bytes[i+1]) + " "); } System.out.println();
+ */
+ byte[] result = new byte[] { 0, 2, 0, 2, 0, 2, 0, 0, 0, 3, 0, 3, 0, 1,
+ 0, 2, 0, 2, 0, 0, 0, 4, 0, 4, 0, 1, 0, 1, 0, 2 };
+ assertTrue("Wrong bytes", Arrays.equals(bytes, result));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollatorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollatorTest.java
new file mode 100644
index 0000000..9f5d141
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/CollatorTest.java
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.text.Collator;
+import java.text.ParseException;
+import java.text.RuleBasedCollator;
+import java.util.Locale;
+
+public class CollatorTest extends junit.framework.TestCase {
+
+ public void test_clone() {
+ Collator c = Collator.getInstance(Locale.GERMAN);
+ Collator c2 = (Collator) c.clone();
+ assertTrue("Clones answered false to equals", c.equals(c2));
+ assertTrue("Clones were equivalent", c != c2);
+ }
+
+ public void test_compareLjava_lang_ObjectLjava_lang_Object() {
+ Collator c = Collator.getInstance(Locale.FRENCH);
+ Object o, o2;
+
+ c.setStrength(Collator.IDENTICAL);
+ o = "E";
+ o2 = "F";
+ assertTrue("a) Failed on primary difference", c.compare(o, o2) < 0);
+ o = "e";
+ o2 = "\u00e9";
+ assertTrue("a) Failed on secondary difference", c.compare(o, o2) < 0);
+ o = "e";
+ o2 = "E";
+ assertTrue("a) Failed on tertiary difference", c.compare(o, o2) < 0);
+ o = "\u0001";
+ o2 = "\u0002";
+ assertTrue("a) Failed on identical", c.compare(o, o2) < 0);
+ o = "e";
+ o2 = "e";
+ assertEquals("a) Failed on equivalence", 0, c.compare(o, o2));
+ assertTrue("a) Failed on primary expansion",
+ c.compare("\u01db", "v") < 0);
+
+ c.setStrength(Collator.TERTIARY);
+ o = "E";
+ o2 = "F";
+ assertTrue("b) Failed on primary difference", c.compare(o, o2) < 0);
+ o = "e";
+ o2 = "\u00e9";
+ assertTrue("b) Failed on secondary difference", c.compare(o, o2) < 0);
+ o = "e";
+ o2 = "E";
+ assertTrue("b) Failed on tertiary difference", c.compare(o, o2) < 0);
+ o = "\u0001";
+ o2 = "\u0002";
+ assertEquals("b) Failed on identical", 0, c.compare(o, o2));
+ o = "e";
+ o2 = "e";
+ assertEquals("b) Failed on equivalence", 0, c.compare(o, o2));
+
+ c.setStrength(Collator.SECONDARY);
+ o = "E";
+ o2 = "F";
+ assertTrue("c) Failed on primary difference", c.compare(o, o2) < 0);
+ o = "e";
+ o2 = "\u00e9";
+ assertTrue("c) Failed on secondary difference", c.compare(o, o2) < 0);
+ o = "e";
+ o2 = "E";
+ assertEquals("c) Failed on tertiary difference", 0, c.compare(o, o2));
+ o = "\u0001";
+ o2 = "\u0002";
+ assertEquals("c) Failed on identical", 0, c.compare(o, o2));
+ o = "e";
+ o2 = "e";
+ assertEquals("c) Failed on equivalence", 0, c.compare(o, o2));
+
+ c.setStrength(Collator.PRIMARY);
+ o = "E";
+ o2 = "F";
+ assertTrue("d) Failed on primary difference", c.compare(o, o2) < 0);
+ o = "e";
+ o2 = "\u00e9";
+ assertEquals("d) Failed on secondary difference", 0, c.compare(o, o2));
+ o = "e";
+ o2 = "E";
+ assertEquals("d) Failed on tertiary difference", 0, c.compare(o, o2));
+ o = "\u0001";
+ o2 = "\u0002";
+ assertEquals("d) Failed on identical", 0, c.compare(o, o2));
+ o = "e";
+ o2 = "e";
+ assertEquals("d) Failed on equivalence", 0, c.compare(o, o2));
+
+ try {
+ c.compare("e", new StringBuffer("Blah"));
+ } catch (ClassCastException e) {
+ // correct
+ return;
+ }
+ fail("Failed to throw ClassCastException");
+ }
+
+ public void test_equalsLjava_lang_Object() {
+ Collator c = Collator.getInstance(Locale.ENGLISH);
+ Collator c2 = (Collator) c.clone();
+ assertTrue("Cloned collators not equal", c.equals(c2));
+ c2.setStrength(Collator.SECONDARY);
+ assertTrue("Collators with different strengths equal", !c.equals(c2));
+ }
+
+ public void test_equalsLjava_lang_StringLjava_lang_String() {
+ Collator c = Collator.getInstance(Locale.FRENCH);
+
+ c.setStrength(Collator.IDENTICAL);
+ assertTrue("a) Failed on primary difference", !c.equals("E", "F"));
+ assertTrue("a) Failed on secondary difference", !c
+ .equals("e", "\u00e9"));
+ assertTrue("a) Failed on tertiary difference", !c.equals("e", "E"));
+ assertTrue("a) Failed on identical", !c.equals("\u0001", "\u0002"));
+ assertTrue("a) Failed on equivalence", c.equals("e", "e"));
+
+ c.setStrength(Collator.TERTIARY);
+ assertTrue("b) Failed on primary difference", !c.equals("E", "F"));
+ assertTrue("b) Failed on secondary difference", !c
+ .equals("e", "\u00e9"));
+ assertTrue("b) Failed on tertiary difference", !c.equals("e", "E"));
+ assertTrue("b) Failed on identical", c.equals("\u0001", "\u0002"));
+ assertTrue("b) Failed on equivalence", c.equals("e", "e"));
+
+ c.setStrength(Collator.SECONDARY);
+ assertTrue("c) Failed on primary difference", !c.equals("E", "F"));
+ assertTrue("c) Failed on secondary difference", !c
+ .equals("e", "\u00e9"));
+ assertTrue("c) Failed on tertiary difference", c.equals("e", "E"));
+ assertTrue("c) Failed on identical", c.equals("\u0001", "\u0002"));
+ assertTrue("c) Failed on equivalence", c.equals("e", "e"));
+
+ c.setStrength(Collator.PRIMARY);
+ assertTrue("d) Failed on primary difference", !c.equals("E", "F"));
+ assertTrue("d) Failed on secondary difference", c.equals("e", "\u00e9"));
+ assertTrue("d) Failed on tertiary difference", c.equals("e", "E"));
+ assertTrue("d) Failed on identical", c.equals("\u0001", "\u0002"));
+ assertTrue("d) Failed on equivalence", c.equals("e", "e"));
+ }
+
+ public void failing_test_getAvailableLocales() {
+ Locale[] locales = Collator.getAvailableLocales();
+ assertTrue("No locales", locales.length > 0);
+ boolean english = false, german = false;
+ for (int i = locales.length; --i >= 0;) {
+ if (locales[i].equals(Locale.ENGLISH))
+ english = true;
+ if (locales[i].equals(Locale.GERMAN))
+ german = true;
+ // Output the working locale to help diagnose a hang
+ Collator c1 = Collator.getInstance(locales[i]);
+ assertTrue("Doesn't work", c1.compare("a", "b") < 0);
+ assertTrue("Wrong decomposition",
+ c1.getDecomposition() == Collator.NO_DECOMPOSITION);
+ assertTrue("Wrong strength", c1.getStrength() == Collator.TERTIARY);
+ if (c1 instanceof RuleBasedCollator) {
+ try {
+ new RuleBasedCollator(((RuleBasedCollator) c1).getRules());
+ } catch (ParseException e) {
+ fail("ParseException");
+ }
+ // assertTrue("Can't recreate: " + locales[i], temp.equals(c1));
+ }
+ }
+ assertTrue("Missing locales", english && german);
+ }
+
+ public void failing_test_getDecomposition() {
+ RuleBasedCollator collator;
+ try {
+ collator = new RuleBasedCollator("; \u0300 < a, A < b < c < d");
+ } catch (ParseException e) {
+ fail("ParseException");
+ return;
+ }
+ assertTrue("Wrong default",
+ collator.getDecomposition() == Collator.CANONICAL_DECOMPOSITION);
+ }
+
+ public void test_getInstance() {
+ Collator c1 = Collator.getInstance();
+ Collator c2 = Collator.getInstance(Locale.getDefault());
+ assertTrue("Wrong locale", c1.equals(c2));
+ }
+
+ public void test_getInstanceLjava_util_Locale() {
+ assertTrue("Used to test", true);
+ }
+
+ public void test_getStrength() throws ParseException {
+ RuleBasedCollator collator = new RuleBasedCollator("&9 ; \u0300 < a, A < b < c < d");
+ assertTrue("Wrong default", collator.getStrength() == Collator.TERTIARY);
+ }
+
+ public void failing_test_setDecompositionI() {
+ Collator c = Collator.getInstance(Locale.FRENCH);
+ c.setStrength(Collator.IDENTICAL);
+ c.setDecomposition(Collator.NO_DECOMPOSITION);
+ assertTrue("Collator should not be using decomposition", !c.equals(
+ "\u212B", "\u00C5")); // "ANGSTROM SIGN" and "LATIN CAPITAL
+ // LETTER A WITH RING ABOVE"
+ c.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+ assertTrue("Collator should be using decomposition", c.equals("\u212B",
+ "\u00C5")); // "ANGSTROM SIGN" and "LATIN CAPITAL LETTER A WITH
+ // RING ABOVE"
+ assertTrue("Should not be equal under canonical decomposition", !c
+ .equals("\u2163", "IV")); // roman number "IV"
+ c.setDecomposition(Collator.FULL_DECOMPOSITION);
+ assertTrue("Should be equal under full decomposition", c.equals(
+ "\u2163", "IV")); // roman number "IV"
+ }
+
+ public void test_setStrengthI() {
+ assertTrue("Used to test", true);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DataFormatFieldTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DataFormatFieldTest.java
new file mode 100644
index 0000000..390dff8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DataFormatFieldTest.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InvalidObjectException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import java.text.DateFormat;
+import java.text.DateFormat.Field;
+import java.util.Calendar;
+
+import junit.framework.TestCase;
+
+public class DataFormatFieldTest extends TestCase{
+
+ public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+ // Regression for HARMONY-178
+ MyField field = new MyField("day of month", Calendar.ERA);
+
+ assertEquals("field has wrong name", "day of month", field.getName());
+ assertEquals("field has wrong Calendar field number", Calendar.ERA,
+ field.getCalendarField());
+
+ DateFormat.Field realField = DateFormat.Field
+ .ofCalendarField(Calendar.ERA);
+ assertSame("Modified calendar field with the same field number",
+ DateFormat.Field.ERA, realField);
+
+ DateFormat.Field realField2 = DateFormat.Field
+ .ofCalendarField(Calendar.DAY_OF_MONTH);
+ assertSame("Modified calendar field with the same field number",
+ DateFormat.Field.DAY_OF_MONTH, realField2);
+ }
+
+ static class MyField extends DateFormat.Field {
+ private static final long serialVersionUID = 1L;
+
+ protected MyField(String fieldName, int calendarField) {
+ super(fieldName, calendarField);
+ }
+
+ protected String getName() {
+ return super.getName();
+ }
+ }
+
+ /**
+ * @tests java.text.DateFormat$Field#Field(java.lang.String, int)
+ */
+ public void test_ConstructorLjava_lang_StringI() {
+ MyField field = new MyField("a field", Calendar.DAY_OF_WEEK);
+
+ assertEquals("field has wrong name", "a field", field.getName());
+ assertEquals("field has wrong Calendar field number",
+ Calendar.DAY_OF_WEEK, field.getCalendarField());
+
+ DateFormat.Field realField = DateFormat.Field
+ .ofCalendarField(Calendar.DAY_OF_WEEK);
+ assertSame("Modified calendar field with the same field number",
+ DateFormat.Field.DAY_OF_WEEK, realField);
+ }
+
+ /**
+ * @tests java.text.DateFormat$Field#Field(java.lang.String, int)
+ */
+ public void test_Constructor2() {
+ MyField field = new MyField("day of month", Calendar.ERA);
+
+ assertEquals("field has wrong name", "day of month", field.getName());
+ assertEquals("field has wrong Calendar field number", Calendar.ERA,
+ field.getCalendarField());
+
+ DateFormat.Field realField = DateFormat.Field
+ .ofCalendarField(Calendar.ERA);
+ assertSame("Modified calendar field with the same field number",
+ DateFormat.Field.ERA, realField);
+
+ DateFormat.Field realField2 = DateFormat.Field
+ .ofCalendarField(Calendar.DAY_OF_MONTH);
+ assertSame("Modified calendar field with the same field number",
+ DateFormat.Field.DAY_OF_MONTH, realField2);
+ }
+
+ /**
+ * @tests java.text.DateFormat$Field#getCalendarField()
+ */
+ public void test_getCalendarField() {
+ // Test for method int getCalendarField()
+ assertEquals("Field.AM_PM.getCalendarField() returned the wrong value",
+ Calendar.AM_PM, Field.AM_PM.getCalendarField());
+
+ // test special cases
+ assertEquals(
+ "Field.TIME_ZONE.getCalendarField() returned the wrong value",
+ -1, Field.TIME_ZONE.getCalendarField());
+ assertEquals("Field.HOUR0.getCalendarField() returned the wrong value",
+ Calendar.HOUR, Field.HOUR0.getCalendarField());
+ assertEquals("Field.HOUR1.getCalendarField() returned the wrong value",
+ -1, Field.HOUR1.getCalendarField());
+ assertEquals(
+ "Field.HOUR_OF_DAY0.getCalendarField() returned the wrong value",
+ Calendar.HOUR_OF_DAY, Field.HOUR_OF_DAY0.getCalendarField());
+ assertEquals(
+ "Field.HOUR_OF_DAY1.getCalendarField() returned the wrong value",
+ -1, Field.HOUR_OF_DAY1.getCalendarField());
+ }
+
+ /**
+ * @tests java.text.DateFormat$Field#ofCalendarField(int)
+ */
+ public void test_ofCalendarFieldI() {
+ // Test for method static java.text.DateFormat.Field
+ // ofCalendarField(int)
+ assertSame("ofCalendarField(Calendar.AM_PM) returned the wrong value",
+ Field.AM_PM, Field.ofCalendarField(Calendar.AM_PM));
+
+ // test special cases
+ assertSame("ofCalendarField(Calendar.HOUR) returned the wrong value",
+ Field.HOUR0, Field.ofCalendarField(Calendar.HOUR));
+ assertSame(
+ "ofCalendarField(Calendar.HOUR_OF_DAY) returned the wrong value",
+ Field.HOUR_OF_DAY0, Field.ofCalendarField(Calendar.HOUR_OF_DAY));
+
+ // test illegal args
+ try {
+ DateFormat.Field.ofCalendarField(-1);
+ fail("Expected IllegalArgumentException for ofCalendarField(-1)");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ DateFormat.Field.ofCalendarField(Calendar.FIELD_COUNT);
+ fail("Expected IllegalArgumentException for ofCalendarField(Calendar.FIELD_COUNT)");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // test Calendar fields that do not have corresponding DateFormat Fields
+ assertNull(
+ "ofCalendarField(Calendar.DST_OFFSET) returned the wrong value",
+ DateFormat.Field.ofCalendarField(Calendar.DST_OFFSET));
+ assertNull(
+ "ofCalendarField(Calendar.ZONE_OFFSET) returned the wrong value",
+ DateFormat.Field.ofCalendarField(Calendar.ZONE_OFFSET));
+ }
+
+ /**
+ * @tests java.text.DateFormat$Field#readResolve()
+ */
+ public void test_readResolve() {
+ // test for method java.lang.Object readResolve()
+
+ // see serialization stress tests:
+ // implemented in
+ // SerializationStressTest4.test_writeObject_NumberFormat_Field()
+
+ ObjectOutputStream out = null;
+ ObjectInputStream in = null;
+ try {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(bytes);
+
+ DateFormat.Field dfield, dfield2;
+ MyField field;
+
+ // a regular instance of DateFormat.Field
+ dfield = DateFormat.Field.MILLISECOND;
+
+ // a subclass instance with null name
+ field = new MyField(null, Calendar.AM_PM);
+
+ out.writeObject(dfield);
+ out.writeObject(field);
+
+ in = new ObjectInputStream(new ByteArrayInputStream(bytes
+ .toByteArray()));
+
+ try {
+ dfield2 = (Field) in.readObject();
+ assertSame("resolved incorrectly", dfield, dfield2);
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException: " + e);
+ }
+
+ try {
+ in.readObject();
+ fail("Expected InvalidObjectException for subclass instance with null name");
+ } catch (InvalidObjectException e) {
+ }
+
+ } catch (IOException e) {
+ fail("unexpected IOException" + e);
+ } catch (ClassNotFoundException e) {
+ fail("unexpected ClassNotFoundException" + e);
+ } finally {
+ try {
+ if (out != null)
+ out.close();
+ if (in != null)
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java
new file mode 100644
index 0000000..1a6a25e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.text.DateFormatSymbols;
+import java.util.Arrays;
+import java.util.Locale;
+
+public class DateFormatSymbolsTest extends junit.framework.TestCase {
+
+ private DateFormatSymbols dfs;
+
+ /**
+ * @tests java.text.DateFormatSymbols#DateFormatSymbols()
+ */
+ public void test_Constructor() {
+ // Test for method java.text.DateFormatSymbols()
+ // Used in tests
+ new DateFormatSymbols();
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#DateFormatSymbols(java.util.Locale)
+ */
+ public void test_ConstructorLjava_util_Locale() {
+ // Test for method java.text.DateFormatSymbols(java.util.Locale)
+ new DateFormatSymbols(new Locale("en", "us"));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getAvailableLocales()
+ */
+ public void test_getAvailableLocales_no_provider() throws Exception {
+ Locale[] locales = DateFormatSymbols.getAvailableLocales();
+ assertNotNull(locales);
+ // must contain Locale.US
+ boolean flag = false;
+ for (Locale locale : locales) {
+ if (locale.equals(Locale.US)) {
+ flag = true;
+ break;
+ }
+ }
+ assertTrue(flag);
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getInstance()
+ */
+ public void test_getInstance() {
+ DateFormatSymbols.getInstance();
+ assertEquals(new DateFormatSymbols(), DateFormatSymbols.getInstance());
+ assertEquals(new DateFormatSymbols(Locale.getDefault()),
+ DateFormatSymbols.getInstance());
+
+ assertNotSame(DateFormatSymbols.getInstance(), DateFormatSymbols.getInstance());
+ }
+
+ public void test_getInstanceLjava_util_Locale() {
+ try {
+ DateFormatSymbols.getInstance(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ assertEquals(new DateFormatSymbols(Locale.GERMANY), DateFormatSymbols.getInstance(Locale.GERMANY));
+
+ Locale locale = new Locale("not exist language", "not exist country");
+ DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale);
+ assertEquals(DateFormatSymbols.getInstance(Locale.ROOT), symbols);
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.text.DateFormatSymbols.clone()
+ DateFormatSymbols symbols = new DateFormatSymbols();
+ DateFormatSymbols clone = (DateFormatSymbols) symbols.clone();
+ assertTrue("Not equal", symbols.equals(clone));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.text.DateFormatSymbols.equals(java.lang.Object)
+ assertTrue("Equal object returned true", dfs.equals(dfs.clone()));
+ dfs.setLocalPatternChars("KKKKKKKKK");
+ assertTrue("Un-Equal objects returned false", !dfs
+ .equals(new DateFormatSymbols()));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getAmPmStrings()
+ */
+ public void test_getAmPmStrings() {
+ // Test for method java.lang.String []
+ // java.text.DateFormatSymbols.getAmPmStrings()
+ String[] retVal = dfs.getAmPmStrings();
+ String[] val = { "AM", "PM" };
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Array values do not match", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getEras()
+ */
+ public void test_getEras() {
+ // Test for method java.lang.String []
+ // java.text.DateFormatSymbols.getEras()
+ String[] retVal = dfs.getEras();
+ String[] val = { "BC", "AD" };
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Array values do not match", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getMonths()
+ */
+ public void test_getMonths() {
+ // Test for method java.lang.String []
+ // java.text.DateFormatSymbols.getMonths()
+ String[] retVal = dfs.getMonths();
+ String[] val = { "January", "February", "March", "April", "May",
+ "June", "July", "August", "September", "October", "November",
+ "December"};
+ assertEquals("Returned wrong array: ", val.length, retVal.length);
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Array values do not match", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getShortMonths()
+ */
+ public void test_getShortMonths() {
+ // Test for method java.lang.String []
+ // java.text.DateFormatSymbols.getShortMonths()
+ String[] retVal = dfs.getShortMonths();
+ String[] val = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
+ "Aug", "Sep", "Oct", "Nov", "Dec"};
+ assertEquals("Returned wrong array: ", val.length, retVal.length);
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Array values do not match", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getShortWeekdays()
+ */
+ public void test_getShortWeekdays() {
+ // Test for method java.lang.String []
+ // java.text.DateFormatSymbols.getShortWeekdays()
+ String[] retVal = dfs.getShortWeekdays();
+ String[] val = { "", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Array values do not match", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getWeekdays()
+ */
+ public void test_getWeekdays() {
+ // Test for method java.lang.String []
+ // java.text.DateFormatSymbols.getWeekdays()
+ String[] retVal = dfs.getWeekdays();
+ String[] val = { "", "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday" };
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Array values do not match", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#getZoneStrings()
+ */
+ public void test_getZoneStrings() {
+ // Test for method java.lang.String [][]
+ // java.text.DateFormatSymbols.getZoneStrings()
+ String[][] val = { { "XX", "XX", "XX", "XX", "XX" },
+ { "YY", "YY", "YY", "YY", "YY" } };
+ dfs.setZoneStrings(val);
+ String[][] retVal = dfs.getZoneStrings();
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Failed to set strings", Arrays
+ .equals(retVal[i], val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.text.DateFormatSymbols.hashCode()
+ int hc1 = dfs.hashCode();
+ int hc2 = dfs.hashCode();
+ assertTrue("hashCode() returned inconsistent number : " + hc1 + " - " + hc2, hc1 == hc2);
+
+ assertTrue("hashCode() returns different values for equal() objects",
+ dfs.hashCode() == dfs.clone().hashCode());
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#setAmPmStrings(java.lang.String[])
+ */
+ public void test_setAmPmStrings$Ljava_lang_String() {
+ // Test for method void
+ // java.text.DateFormatSymbols.setAmPmStrings(java.lang.String [])
+ String[] val = { "XX", "YY" };
+ dfs.setAmPmStrings(val);
+ String[] retVal = dfs.getAmPmStrings();
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Failed to set strings", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#setEras(java.lang.String[])
+ */
+ public void test_setEras$Ljava_lang_String() {
+ // Test for method void
+ // java.text.DateFormatSymbols.setEras(java.lang.String [])
+ String[] val = { "XX", "YY" };
+ dfs.setEras(val);
+ String[] retVal = dfs.getEras();
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Failed to set strings", retVal[i].equals(val[i]));
+ }
+
+ public void test_setLocalPatternCharsLjava_lang_String() {
+ String patternChars = "GyMZZkHmsSEHHFwWahKz";
+ dfs.setLocalPatternChars(patternChars);
+ assertEquals(patternChars, dfs.getLocalPatternChars());
+
+ try {
+ // Regression for HARMONY-466
+ new DateFormatSymbols().setLocalPatternChars(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#setMonths(java.lang.String[])
+ */
+ public void test_setMonths$Ljava_lang_String() {
+ // Test for method void
+ // java.text.DateFormatSymbols.setMonths(java.lang.String [])
+ String[] val = { "XX", "YY" };
+ dfs.setMonths(val);
+ String[] retVal = dfs.getMonths();
+ assertTrue("Return is identical", retVal != dfs.getMonths());
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Failed to set strings", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#setShortMonths(java.lang.String[])
+ */
+ public void test_setShortMonths$Ljava_lang_String() {
+ // Test for method void
+ // java.text.DateFormatSymbols.setShortMonths(java.lang.String [])
+ String[] val = { "XX", "YY" };
+ dfs.setShortMonths(val);
+ String[] retVal = dfs.getShortMonths();
+ assertTrue("Return is identical", retVal != dfs.getShortMonths());
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Failed to set strings", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#setShortWeekdays(java.lang.String[])
+ */
+ public void test_setShortWeekdays$Ljava_lang_String() {
+ // Test for method void
+ // java.text.DateFormatSymbols.setShortWeekdays(java.lang.String [])
+ String[] val = { "XX", "YY" };
+ dfs.setShortWeekdays(val);
+ String[] retVal = dfs.getShortWeekdays();
+ assertTrue("Return is identical", retVal != dfs.getShortWeekdays());
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Failed to set strings", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#setWeekdays(java.lang.String[])
+ */
+ public void test_setWeekdays$Ljava_lang_String() {
+ // Test for method void
+ // java.text.DateFormatSymbols.setWeekdays(java.lang.String [])
+ String[] val = { "XX", "YY" };
+ dfs.setWeekdays(val);
+ String[] retVal = dfs.getWeekdays();
+ assertTrue("Return is identical", retVal != dfs.getWeekdays());
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Failed to set strings", retVal[i].equals(val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#setZoneStrings(java.lang.String[][])
+ */
+ public void test_setZoneStrings$$Ljava_lang_String() {
+ // Test for method void
+ // java.text.DateFormatSymbols.setZoneStrings(java.lang.String [][])
+ String[][] val = { { "XX", "XX", "XX", "XX", "XX" },
+ { "YY", "YY", "YY", "YY", "YY" } };
+ dfs.setZoneStrings(val);
+ String[][] retVal = dfs.getZoneStrings();
+ assertTrue("get returns identical", retVal != dfs.getZoneStrings());
+ assertTrue("get[0] returns identical", retVal[0] != dfs
+ .getZoneStrings()[0]);
+ assertTrue("get returned identical", retVal != val);
+ assertEquals("Returned wrong array", val.length, retVal.length);
+ for (int i = 0; i < val.length; i++)
+ assertTrue("Failed to set strings: " + retVal[i], Arrays.equals(
+ retVal[i], val[i]));
+ }
+
+ /**
+ * @tests java.text.DateFormatSymbols#setZoneStrings(java.lang.String[][])
+ *
+ * Tests setting zone strings to invalid values
+ * Regression for HARMONY-6337
+ */
+ public void test_setZoneStrings_invalid() {
+ // failing cases
+ String[][] val1 = null;
+ try {
+ dfs.setZoneStrings(val1);
+ fail("Attempt to set zone strings a null array should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ String[][] val2 = { { "XX", "XX" }, { "YY", "YY" } };
+ try {
+ dfs.setZoneStrings(val2);
+ fail("Attempt to set zone strings to a 2D array that contains one or more "
+ + "rows of length less than 5 should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected because each subarray has length < 5
+ }
+
+ String[][] val3 = { { "a", "b", "c", "d", "e" },
+ { "a", "b", "c", "d", "e" },
+ { "a", "b", "c", "d" },
+ { "a", "b", "c", "d", "e" } };
+ try {
+ dfs.setZoneStrings(val3);
+ fail("Attempt to set zone strings to a 2D array that contains one or more "
+ + "rows of length less than 5 should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected because each subarray has length < 5
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ dfs = new DateFormatSymbols(new Locale("en", "us"));
+ }
+
+ // Test serialization mechanism of DateFormatSymbols
+ public void test_serialization() throws Exception {
+ DateFormatSymbols symbols = new DateFormatSymbols(Locale.FRANCE);
+ String[][] zoneStrings = symbols.getZoneStrings();
+ assertNotNull(zoneStrings);
+
+ // serialize
+ ByteArrayOutputStream byteOStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOStream = new ObjectOutputStream(byteOStream);
+ objectOStream.writeObject(symbols);
+
+ // and deserialize
+ ObjectInputStream objectIStream = new ObjectInputStream(
+ new ByteArrayInputStream(byteOStream.toByteArray()));
+ DateFormatSymbols symbolsD = (DateFormatSymbols) objectIStream
+ .readObject();
+
+ String[][] zoneStringsD = symbolsD.getZoneStrings();
+ assertNotNull(zoneStringsD);
+ assertEquals(symbols, symbolsD);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatTest.java
new file mode 100644
index 0000000..072d133
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatTest.java
@@ -0,0 +1,475 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+public class DateFormatTest extends junit.framework.TestCase {
+
+ /**
+ * @tests java.text.DateFormat#clone()
+ */
+ public void test_clone() {
+ DateFormat format = DateFormat.getInstance();
+ DateFormat clone = (DateFormat) format.clone();
+ assertTrue("Clone not equal", format.equals(clone));
+ clone.getNumberFormat().setMinimumFractionDigits(123);
+ assertTrue("Clone shares NumberFormat", !format.equals(clone));
+ }
+
+ /**
+ * @tests java.text.DateFormat#getAvailableLocales()
+ */
+ public void test_getAvailableLocales() {
+ Locale[] locales = DateFormat.getAvailableLocales();
+ assertTrue("No locales", locales.length > 0);
+ boolean english = false, german = false;
+ for (int i = locales.length; --i >= 0;) {
+ if (locales[i].equals(Locale.ENGLISH))
+ english = true;
+ if (locales[i].equals(Locale.GERMAN))
+ german = true;
+ DateFormat f1 = DateFormat.getDateTimeInstance(DateFormat.SHORT,
+ DateFormat.SHORT, locales[i]);
+ assertTrue("Doesn't work",
+ f1.format(new Date()).getClass() == String.class);
+ }
+ assertTrue("Missing locales", english && german);
+ }
+
+ /**
+ * @tests java.text.DateFormat#getCalendar()
+ */
+ public void test_getCalendar() {
+ DateFormat format = DateFormat.getInstance();
+ Calendar cal1 = format.getCalendar();
+ Calendar cal2 = format.getCalendar();
+ assertTrue("Calendars not identical", cal1 == cal2);
+ }
+
+ /**
+ * @tests java.text.DateFormat#getDateInstance()
+ */
+ public void test_getDateInstance() {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat.getDateInstance();
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default", f2.equals(DateFormat.getDateInstance(
+ DateFormat.DEFAULT, Locale.getDefault())));
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+ }
+
+ /**
+ * @tests java.text.DateFormat#getDateInstance(int)
+ */
+ public void test_getDateInstanceI() {
+ assertTrue("Default not medium",
+ DateFormat.DEFAULT == DateFormat.MEDIUM);
+
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat
+ .getDateInstance(DateFormat.SHORT);
+ assertTrue("Wrong class1", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default1", f2.equals(DateFormat.getDateInstance(
+ DateFormat.SHORT, Locale.getDefault())));
+ assertTrue("Wrong symbols1", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work1",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.MEDIUM);
+ assertTrue("Wrong class2", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default2", f2.equals(DateFormat.getDateInstance(
+ DateFormat.MEDIUM, Locale.getDefault())));
+ assertTrue("Wrong symbols2", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work2",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.LONG);
+ assertTrue("Wrong class3", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default3", f2.equals(DateFormat.getDateInstance(
+ DateFormat.LONG, Locale.getDefault())));
+ assertTrue("Wrong symbols3", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work3",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.FULL);
+ assertTrue("Wrong class4", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default4", f2.equals(DateFormat.getDateInstance(
+ DateFormat.FULL, Locale.getDefault())));
+ assertTrue("Wrong symbols4", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work4",
+ f2.format(new Date()).getClass() == String.class);
+
+ // regression test for HARMONY-940
+ try {
+ DateFormat.getDateInstance(77);
+ fail("Should throw IAE");
+ } catch (IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests java.text.DateFormat#getDateInstance(int, java.util.Locale)
+ */
+ public void test_getDateInstanceILjava_util_Locale() {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat.getDateInstance(
+ DateFormat.SHORT, Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.MEDIUM,
+ Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.LONG,
+ Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.FULL,
+ Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+
+ // regression test for HARMONY-940
+ try {
+ DateFormat.getDateInstance(77, Locale.GERMAN);
+ fail("Should throw IAE");
+ } catch (IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests java.text.DateFormat#getDateTimeInstance()
+ */
+ public void test_getDateTimeInstance() {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat
+ .getDateTimeInstance();
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default", f2.equals(DateFormat.getDateTimeInstance(
+ DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.getDefault())));
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+ }
+
+ private void testDateTime(int dStyle, int tStyle) {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat
+ .getDateTimeInstance(dStyle, tStyle);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ SimpleDateFormat date = (SimpleDateFormat) DateFormat.getDateInstance(
+ dStyle, Locale.getDefault());
+ SimpleDateFormat time = (SimpleDateFormat) DateFormat.getTimeInstance(
+ tStyle, Locale.getDefault());
+ assertTrue("Wrong default", f2.toPattern().equals(
+ date.toPattern() + " " + time.toPattern()));
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+ }
+
+ /**
+ * @tests java.text.DateFormat#getDateTimeInstance(int, int)
+ */
+ public void test_getDateTimeInstanceII() {
+ testDateTime(DateFormat.SHORT, DateFormat.SHORT);
+ testDateTime(DateFormat.SHORT, DateFormat.MEDIUM);
+ testDateTime(DateFormat.SHORT, DateFormat.LONG);
+ testDateTime(DateFormat.SHORT, DateFormat.FULL);
+
+ testDateTime(DateFormat.MEDIUM, DateFormat.SHORT);
+ testDateTime(DateFormat.MEDIUM, DateFormat.MEDIUM);
+ testDateTime(DateFormat.MEDIUM, DateFormat.LONG);
+ testDateTime(DateFormat.MEDIUM, DateFormat.FULL);
+
+ testDateTime(DateFormat.LONG, DateFormat.SHORT);
+ testDateTime(DateFormat.LONG, DateFormat.MEDIUM);
+ testDateTime(DateFormat.LONG, DateFormat.LONG);
+ testDateTime(DateFormat.LONG, DateFormat.FULL);
+
+ testDateTime(DateFormat.FULL, DateFormat.SHORT);
+ testDateTime(DateFormat.FULL, DateFormat.MEDIUM);
+ testDateTime(DateFormat.FULL, DateFormat.LONG);
+ testDateTime(DateFormat.FULL, DateFormat.FULL);
+
+ // regression test for HARMONY-940
+ try {
+ DateFormat.getDateTimeInstance(77, 66);
+ fail("Should throw IAE");
+ } catch (IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ private void testDateTimeLocale(int dStyle, int tStyle) {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat
+ .getDateTimeInstance(dStyle, tStyle, Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ SimpleDateFormat date = (SimpleDateFormat) DateFormat.getDateInstance(
+ dStyle, Locale.GERMAN);
+ SimpleDateFormat time = (SimpleDateFormat) DateFormat.getTimeInstance(
+ tStyle, Locale.GERMAN);
+ assertTrue("Wrong default", f2.toPattern().equals(
+ date.toPattern() + " " + time.toPattern()));
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+ }
+
+ /**
+ * @tests java.text.DateFormat#getDateTimeInstance(int, int,
+ * java.util.Locale)
+ */
+ public void test_getDateTimeInstanceIILjava_util_Locale() {
+ testDateTimeLocale(DateFormat.SHORT, DateFormat.SHORT);
+ testDateTimeLocale(DateFormat.SHORT, DateFormat.MEDIUM);
+ testDateTimeLocale(DateFormat.SHORT, DateFormat.LONG);
+ testDateTimeLocale(DateFormat.SHORT, DateFormat.FULL);
+
+ testDateTimeLocale(DateFormat.MEDIUM, DateFormat.SHORT);
+ testDateTimeLocale(DateFormat.MEDIUM, DateFormat.MEDIUM);
+ testDateTimeLocale(DateFormat.MEDIUM, DateFormat.LONG);
+ testDateTimeLocale(DateFormat.MEDIUM, DateFormat.FULL);
+
+ testDateTimeLocale(DateFormat.LONG, DateFormat.SHORT);
+ testDateTimeLocale(DateFormat.LONG, DateFormat.MEDIUM);
+ testDateTimeLocale(DateFormat.LONG, DateFormat.LONG);
+ testDateTimeLocale(DateFormat.LONG, DateFormat.FULL);
+
+ testDateTimeLocale(DateFormat.FULL, DateFormat.SHORT);
+ testDateTimeLocale(DateFormat.FULL, DateFormat.MEDIUM);
+ testDateTimeLocale(DateFormat.FULL, DateFormat.LONG);
+ testDateTimeLocale(DateFormat.FULL, DateFormat.FULL);
+
+ // regression test for HARMONY-940
+ try {
+ DateFormat.getDateTimeInstance(77, 66, Locale.GERMAN);
+ fail("Should throw IAE");
+ } catch (IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests java.text.DateFormat#getInstance()
+ */
+ public void test_getInstance() {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat.getInstance();
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default", f2.equals(DateFormat.getDateTimeInstance(
+ DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault())));
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+ }
+
+ /**
+ * @tests java.text.DateFormat#getNumberFormat()
+ */
+ public void test_getNumberFormat() {
+ DateFormat format = DateFormat.getInstance();
+ NumberFormat nf1 = format.getNumberFormat();
+ NumberFormat nf2 = format.getNumberFormat();
+ assertTrue("NumberFormats not identical", nf1 == nf2);
+ }
+
+ /**
+ * @tests java.text.DateFormat#getTimeInstance()
+ */
+ public void test_getTimeInstance() {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat.getTimeInstance();
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default", f2.equals(DateFormat.getTimeInstance(
+ DateFormat.DEFAULT, Locale.getDefault())));
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+ }
+
+ /**
+ * @tests java.text.DateFormat#getTimeInstance(int)
+ */
+ public void test_getTimeInstanceI() {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat
+ .getTimeInstance(DateFormat.SHORT);
+ assertTrue("Wrong class1", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default1", f2.equals(DateFormat.getTimeInstance(
+ DateFormat.SHORT, Locale.getDefault())));
+ assertTrue("Wrong symbols1", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work1",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.MEDIUM);
+ assertTrue("Wrong class2", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default2", f2.equals(DateFormat.getTimeInstance(
+ DateFormat.MEDIUM, Locale.getDefault())));
+ assertTrue("Wrong symbols2", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work2",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.LONG);
+ assertTrue("Wrong class3", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default3", f2.equals(DateFormat.getTimeInstance(
+ DateFormat.LONG, Locale.getDefault())));
+ assertTrue("Wrong symbols3", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work3",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.FULL);
+ assertTrue("Wrong class4", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default4", f2.equals(DateFormat.getTimeInstance(
+ DateFormat.FULL, Locale.getDefault())));
+ assertTrue("Wrong symbols4", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols()));
+ assertTrue("Doesn't work4",
+ f2.format(new Date()).getClass() == String.class);
+
+ // regression test for HARMONY-940
+ try {
+ DateFormat.getTimeInstance(77);
+ fail("Should throw IAE");
+ } catch (IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests java.text.DateFormat#getTimeInstance(int, java.util.Locale)
+ */
+ public void test_getTimeInstanceILjava_util_Locale() {
+ SimpleDateFormat f2 = (SimpleDateFormat) DateFormat.getTimeInstance(
+ DateFormat.SHORT, Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.MEDIUM,
+ Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.LONG,
+ Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+
+ f2 = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.FULL,
+ Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work",
+ f2.format(new Date()).getClass() == String.class);
+
+ // regression test for HARMONY-940
+ try {
+ DateFormat.getTimeInstance(77, Locale.GERMAN);
+ fail("Should throw IAE");
+ } catch (IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests java.text.DateFormat#setCalendar(java.util.Calendar)
+ */
+ public void test_setCalendarLjava_util_Calendar() {
+ DateFormat format = DateFormat.getInstance();
+ Calendar cal = Calendar.getInstance();
+ format.setCalendar(cal);
+ assertTrue("Not identical Calendar", cal == format.getCalendar());
+ }
+
+ /**
+ * @tests java.text.DateFormat#setNumberFormat(java.text.NumberFormat)
+ */
+ public void test_setNumberFormatLjava_text_NumberFormat() {
+ DateFormat format = DateFormat.getInstance();
+ NumberFormat f1 = NumberFormat.getInstance();
+ format.setNumberFormat(f1);
+ assertTrue("Not identical NumberFormat", f1 == format.getNumberFormat());
+ }
+
+ /**
+ * @tests java.text.DateFormat#parse(String)
+ */
+ public void test_parse_LString() {
+ DateFormat format = DateFormat.getInstance();
+ try {
+ format.parse("not a Date");
+ fail("should throw ParseException first");
+ } catch (ParseException e) {
+ assertNotNull(e.getMessage());
+ }
+ }
+
+ /**
+ * @tests java.text.DateFormat#setLenient(boolean)
+ */
+ public void test_setLenient() {
+ Date d = null;
+ DateFormat output = new SimpleDateFormat("MM/dd/yy");
+ output.setLenient(false);
+ try {
+ d = output.parse("01/01/-1");
+ fail("Should throw ParseException here.");
+ } catch (ParseException e) {}
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatSymbolsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatSymbolsTest.java
new file mode 100644
index 0000000..c6eace0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatSymbolsTest.java
@@ -0,0 +1,552 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Currency;
+import java.util.Locale;
+import java.util.ServiceConfigurationError;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class DecimalFormatSymbolsTest extends TestCase {
+
+ DecimalFormatSymbols dfs;
+
+ DecimalFormatSymbols dfsUS;
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#DecimalFormatSymbols()
+ */
+ public void test_Constructor() {
+ // Test for method java.text.DecimalFormatSymbols()
+ // Used in tests
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#DecimalFormatSymbols(java.util.Locale)
+ */
+ public void test_ConstructorLjava_util_Locale() {
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols(new Locale("en",
+ "us"));
+ assertEquals("Returned incorrect symbols", '%', dfs.getPercent());
+ }
+
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getAvailableLocales()
+ */
+ public void test_getAvailableLocales_no_provider() throws Exception {
+ Locale[] locales = DecimalFormatSymbols.getAvailableLocales();
+ assertNotNull(locales);
+ // must contain Locale.US
+ boolean flag = false;
+ for (Locale locale : locales) {
+ if (locale.equals(Locale.US)) {
+ flag = true;
+ break;
+ }
+ }
+ assertTrue(flag);
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getInstance()
+ */
+ public void test_getInstance() {
+ assertEquals(new DecimalFormatSymbols(), DecimalFormatSymbols.getInstance());
+ assertEquals(new DecimalFormatSymbols(Locale.getDefault()),
+ DecimalFormatSymbols.getInstance());
+
+ assertNotSame(DecimalFormatSymbols.getInstance(), DecimalFormatSymbols.getInstance());
+ }
+
+ public void test_getInstanceLjava_util_Locale() {
+ try {
+ DecimalFormatSymbols.getInstance(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ assertEquals(new DecimalFormatSymbols(Locale.GERMANY), DecimalFormatSymbols.getInstance(Locale.GERMANY));
+
+ Locale locale = new Locale("not exist language", "not exist country");
+ DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
+ assertNotNull(symbols);
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ assertTrue("Equal objects returned false", dfs.equals(dfs.clone()));
+ dfs.setDigit('B');
+ assertTrue("Un-Equal objects returned true", !dfs
+ .equals(new DecimalFormatSymbols()));
+
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getCurrency()
+ */
+ public void test_getCurrency() {
+ Currency currency = Currency.getInstance("USD");
+ assertEquals("Returned incorrect currency",
+ dfsUS.getCurrency(), currency);
+
+ Currency currK = Currency.getInstance("KRW");
+ Currency currX = Currency.getInstance("XXX");
+ Currency currE = Currency.getInstance("EUR");
+ // Currency currF = Currency.getInstance("FRF");
+
+ DecimalFormatSymbols dfs1 = new DecimalFormatSymbols(new Locale("ko",
+ "KR"));
+ assertTrue("Test1: Returned incorrect currency",
+ dfs1.getCurrency() == currK);
+ assertEquals("Test1: Returned incorrect currencySymbol", "\u20a9", dfs1
+ .getCurrencySymbol());
+ assertEquals("Test1: Returned incorrect intlCurrencySymbol", "KRW",
+ dfs1.getInternationalCurrencySymbol());
+
+ dfs1 = new DecimalFormatSymbols(new Locale("", "KR"));
+ assertTrue("Test2: Returned incorrect currency",
+ dfs1.getCurrency() == currK);
+ assertEquals("Test2: Returned incorrect currencySymbol", "\u20a9", dfs1
+ .getCurrencySymbol());
+ assertEquals("Test2: Returned incorrect intlCurrencySymbol", "KRW",
+ dfs1.getInternationalCurrencySymbol());
+
+ dfs1 = new DecimalFormatSymbols(new Locale("ko", ""));
+ assertTrue("Test3: Returned incorrect currency",
+ dfs1.getCurrency() == currX);
+ assertEquals("Test3: Returned incorrect currencySymbol", "\u00a4", dfs1
+ .getCurrencySymbol());
+ assertEquals("Test3: Returned incorrect intlCurrencySymbol", "XXX",
+ dfs1.getInternationalCurrencySymbol());
+
+ dfs1 = new DecimalFormatSymbols(new Locale("fr", "FR"));
+ assertTrue("Test4: Returned incorrect currency",
+ dfs1.getCurrency() == currE);
+ assertEquals("Test4: Returned incorrect currencySymbol", "\u20ac", dfs1
+ .getCurrencySymbol());
+ assertEquals("Test4: Returned incorrect intlCurrencySymbol", "EUR",
+ dfs1.getInternationalCurrencySymbol());
+
+ // RI fails these tests since it doesn't have the PREEURO variant
+ // dfs1 = new DecimalFormatSymbols(new Locale("fr", "FR","PREEURO"));
+ // assertTrue("Test5: Returned incorrect currency", dfs1.getCurrency()
+ // == currF);
+ // assertTrue("Test5: Returned incorrect currencySymbol",
+ // dfs1.getCurrencySymbol().equals("F"));
+ // assertTrue("Test5: Returned incorrect intlCurrencySymbol",
+ // dfs1.getInternationalCurrencySymbol().equals("FRF"));
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getCurrencySymbol()
+ */
+ public void test_getCurrencySymbol() {
+ assertEquals("Returned incorrect currencySymbol", "$", dfsUS
+ .getCurrencySymbol());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getDecimalSeparator()
+ */
+ public void test_getDecimalSeparator() {
+ dfs.setDecimalSeparator('*');
+ assertEquals("Returned incorrect DecimalSeparator symbol", '*', dfs
+ .getDecimalSeparator());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getDigit()
+ */
+ public void test_getDigit() {
+ dfs.setDigit('*');
+ assertEquals("Returned incorrect Digit symbol", '*', dfs.getDigit());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getExponentSeparator()
+ */
+ public void test_getExponentSeparator() {
+ dfs.setExponentSeparator("EE");
+ assertEquals("Returned incorrect Exponent Separator symbol", "EE", dfs
+ .getExponentSeparator());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getGroupingSeparator()
+ */
+ public void test_getGroupingSeparator() {
+ dfs.setGroupingSeparator('*');
+ assertEquals("Returned incorrect GroupingSeparator symbol", '*', dfs
+ .getGroupingSeparator());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getInfinity()
+ */
+ public void test_getInfinity() {
+ dfs.setInfinity("&");
+ assertTrue("Returned incorrect Infinity symbol",
+ dfs.getInfinity() == "&");
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getInternationalCurrencySymbol()
+ */
+ public void test_getInternationalCurrencySymbol() {
+ assertEquals("Returned incorrect InternationalCurrencySymbol", "USD",
+ dfsUS.getInternationalCurrencySymbol());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getMinusSign()
+ */
+ public void test_getMinusSign() {
+ dfs.setMinusSign('&');
+ assertEquals("Returned incorrect MinusSign symbol", '&', dfs
+ .getMinusSign());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getNaN()
+ */
+ public void test_getNaN() {
+ dfs.setNaN("NAN!!");
+ assertEquals("Returned incorrect nan symbol", "NAN!!", dfs.getNaN());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getPatternSeparator()
+ */
+ public void test_getPatternSeparator() {
+ dfs.setPatternSeparator('X');
+ assertEquals("Returned incorrect PatternSeparator symbol", 'X', dfs
+ .getPatternSeparator());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getPercent()
+ */
+ public void test_getPercent() {
+ dfs.setPercent('*');
+ assertEquals("Returned incorrect Percent symbol", '*', dfs.getPercent());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getPerMill()
+ */
+ public void test_getPerMill() {
+ dfs.setPerMill('#');
+ assertEquals("Returned incorrect PerMill symbol", '#', dfs.getPerMill());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#getZeroDigit()
+ */
+ public void test_getZeroDigit() {
+ dfs.setZeroDigit('*');
+ assertEquals("Returned incorrect ZeroDigit symbol", '*', dfs
+ .getZeroDigit());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setCurrency(java.util.Currency)
+ */
+ public void test_setCurrencyLjava_util_Currency() {
+ Locale locale = Locale.CANADA;
+ DecimalFormatSymbols dfs = ((DecimalFormat) NumberFormat
+ .getCurrencyInstance(locale)).getDecimalFormatSymbols();
+
+ try {
+ dfs.setCurrency(null);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ }
+
+ Currency currency = Currency.getInstance("JPY");
+ dfs.setCurrency(currency);
+
+ assertTrue("Returned incorrect currency", currency == dfs.getCurrency());
+ assertEquals("Returned incorrect currency symbol", currency.getSymbol(
+ locale), dfs.getCurrencySymbol());
+ assertTrue("Returned incorrect international currency symbol", currency
+ .getCurrencyCode().equals(dfs.getInternationalCurrencySymbol()));
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setDecimalSeparator(char)
+ */
+ public void test_setDecimalSeparatorC() {
+ dfs.setDecimalSeparator('*');
+ assertEquals("Returned incorrect DecimalSeparator symbol", '*', dfs
+ .getDecimalSeparator());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setDigit(char)
+ */
+ public void test_setDigitC() {
+ dfs.setDigit('*');
+ assertEquals("Returned incorrect Digit symbol", '*', dfs.getDigit());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setExponentSeparator(String)
+ */
+ public void test_setExponentSeparator() {
+ try {
+ dfs.setExponentSeparator(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ dfs.setExponentSeparator("");
+ assertEquals("Returned incorrect Exponent Separator symbol", "", dfs
+ .getExponentSeparator());
+
+ dfs.setExponentSeparator("what ever you want");
+ assertEquals("Returned incorrect Exponent Separator symbol",
+ "what ever you want", dfs.getExponentSeparator());
+
+ dfs.setExponentSeparator(" E ");
+ assertEquals("Returned incorrect Exponent Separator symbol", " E ", dfs
+ .getExponentSeparator());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setGroupingSeparator(char)
+ */
+ public void test_setGroupingSeparatorC() {
+ dfs.setGroupingSeparator('*');
+ assertEquals("Returned incorrect GroupingSeparator symbol", '*', dfs
+ .getGroupingSeparator());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setInfinity(java.lang.String)
+ */
+ public void test_setInfinityLjava_lang_String() {
+ dfs.setInfinity("&");
+ assertTrue("Returned incorrect Infinity symbol",
+ dfs.getInfinity() == "&");
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setInternationalCurrencySymbol(java.lang.String)
+ */
+ public void test_setInternationalCurrencySymbolLjava_lang_String() {
+ Locale locale = Locale.CANADA;
+ DecimalFormatSymbols dfs = ((DecimalFormat) NumberFormat
+ .getCurrencyInstance(locale)).getDecimalFormatSymbols();
+ Currency currency = Currency.getInstance("JPY");
+ dfs.setInternationalCurrencySymbol(currency.getCurrencyCode());
+
+ assertTrue("Test1: Returned incorrect currency", currency == dfs
+ .getCurrency());
+ assertEquals("Test1: Returned incorrect currency symbol", currency
+ .getSymbol(locale), dfs.getCurrencySymbol());
+ assertTrue("Test1: Returned incorrect international currency symbol",
+ currency.getCurrencyCode().equals(
+ dfs.getInternationalCurrencySymbol()));
+
+ dfs.setInternationalCurrencySymbol("bogus");
+ // RI support this legacy country code
+ // assertNotNull("Test2: Returned incorrect currency", dfs.getCurrency());
+ assertEquals("Test2: Returned incorrect international currency symbol",
+ "bogus", dfs.getInternationalCurrencySymbol());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setMinusSign(char)
+ */
+ public void test_setMinusSignC() {
+ dfs.setMinusSign('&');
+ assertEquals("Returned incorrect MinusSign symbol", '&', dfs
+ .getMinusSign());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setNaN(java.lang.String)
+ */
+ public void test_setNaNLjava_lang_String() {
+ dfs.setNaN("NAN!!");
+ assertEquals("Returned incorrect nan symbol", "NAN!!", dfs.getNaN());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setPatternSeparator(char)
+ */
+ public void test_setPatternSeparatorC() {
+ dfs.setPatternSeparator('X');
+ assertEquals("Returned incorrect PatternSeparator symbol", 'X', dfs
+ .getPatternSeparator());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setPercent(char)
+ */
+ public void test_setPercentC() {
+ dfs.setPercent('*');
+ assertEquals("Returned incorrect Percent symbol", '*', dfs.getPercent());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setPerMill(char)
+ */
+ public void test_setPerMillC() {
+ dfs.setPerMill('#');
+ assertEquals("Returned incorrect PerMill symbol", '#', dfs.getPerMill());
+ }
+
+ /**
+ * @tests java.text.DecimalFormatSymbols#setZeroDigit(char)
+ */
+ public void test_setZeroDigitC() {
+ dfs.setZeroDigit('*');
+ assertEquals("Set incorrect ZeroDigit symbol", '*', dfs.getZeroDigit());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ dfs = new DecimalFormatSymbols();
+ dfsUS = new DecimalFormatSymbols(new Locale("en", "us"));
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+
+ // Test serialization mechanism of DecimalFormatSymbols
+ public void test_serialization() throws Exception {
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.FRANCE);
+ Currency currency = symbols.getCurrency();
+ assertNotNull(currency);
+
+ // serialize
+ ByteArrayOutputStream byteOStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOStream = new ObjectOutputStream(byteOStream);
+ objectOStream.writeObject(symbols);
+
+ // and deserialize
+ ObjectInputStream objectIStream = new ObjectInputStream(
+ new ByteArrayInputStream(byteOStream.toByteArray()));
+ DecimalFormatSymbols symbolsD = (DecimalFormatSymbols) objectIStream
+ .readObject();
+
+ // The associated currency will not persist
+ currency = symbolsD.getCurrency();
+ assertNotNull(currency);
+ }
+
+ /**
+ * Assert that Harmony can correct read an instance that was created by
+ * the Java 1.5 RI. The actual values may differ on Harmony and other JREs,
+ * so we only assert the values that are known to be in the serialized data.
+ */
+ public void test_RIHarmony_compatible() throws Exception {
+ DecimalFormatSymbols dfs;
+ ObjectInputStream i = null;
+ try {
+ i = new ObjectInputStream(getClass().getClassLoader().getResourceAsStream(
+ "serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbols.ser"));
+ dfs = (DecimalFormatSymbols) i.readObject();
+ } finally {
+ try {
+ if (i != null) {
+ i.close();
+ }
+ } catch (Exception e) {
+ }
+ }
+ assertDecimalFormatSymbolsRIFrance(dfs);
+ }
+
+ static void assertDecimalFormatSymbolsRIFrance(DecimalFormatSymbols dfs) {
+ // Values based on Java 1.5 RI DecimalFormatSymbols for Locale.FRANCE
+ /*
+ * currency = [EUR]
+ * currencySymbol = [€][U+20ac]
+ * decimalSeparator = [,][U+002c]
+ * digit = [#][U+0023]
+ * groupingSeparator = [ ][U+00a0]
+ * infinity = [∞][U+221e]
+ * internationalCurrencySymbol = [EUR]
+ * minusSign = [-][U+002d]
+ * monetaryDecimalSeparator = [,][U+002c]
+ * naN = [�][U+fffd]
+ * patternSeparator = [;][U+003b]
+ * perMill = [‰][U+2030]
+ * percent = [%][U+0025]
+ * zeroDigit = [0][U+0030]
+ */
+ assertEquals("EUR", dfs.getCurrency().getCurrencyCode());
+ assertEquals("\u20AC", dfs.getCurrencySymbol());
+ assertEquals(',', dfs.getDecimalSeparator());
+ assertEquals('#', dfs.getDigit());
+ assertEquals('\u00a0', dfs.getGroupingSeparator());
+ assertEquals("\u221e", dfs.getInfinity());
+ assertEquals("EUR", dfs.getInternationalCurrencySymbol());
+ assertEquals('-', dfs.getMinusSign());
+ assertEquals(',', dfs.getMonetaryDecimalSeparator());
+ // RI's default NaN is U+FFFD, Harmony's is based on ICU
+ assertEquals("\uFFFD", dfs.getNaN());
+ assertEquals('\u003b', dfs.getPatternSeparator());
+ assertEquals('\u2030', dfs.getPerMill());
+ assertEquals('%', dfs.getPercent());
+ assertEquals('0', dfs.getZeroDigit());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI6.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
+ symbols.setExponentSeparator("EE");
+ symbols.setNaN("NaN");
+ SerializationTest.verifyGolden(this, symbols);
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ public void testSerializationSelf() throws Exception {
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.ITALIAN);
+ SerializationTest.verifySelf(symbols);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java
new file mode 100644
index 0000000..e0e04e8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java
@@ -0,0 +1,2594 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.io.ObjectInputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.AttributedCharacterIterator;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.ArrayList;
+import java.util.Currency;
+import java.util.List;
+import java.util.Locale;
+
+import junit.framework.Assert;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+
+public class DecimalFormatTest extends TestCase {
+
+ // https://code.google.com/p/android/issues/detail?id=59600
+ public void test_setNan_emptyString() throws Exception {
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols();
+ dfs.setNaN("");
+ DecimalFormat df = new DecimalFormat();
+ df.setDecimalFormatSymbols(dfs);
+ df.format(Double.NaN);
+ }
+
+ public void testAttributedCharacterIterator() throws Exception {
+ // Regression for http://issues.apache.org/jira/browse/HARMONY-333
+ AttributedCharacterIterator iterator = new DecimalFormat().formatToCharacterIterator(
+ new Integer(1));
+ assertNotNull(iterator);
+ assertFalse("attributes should exist", iterator.getAttributes().isEmpty());
+ }
+
+ public void test_parse_bigDecimal() throws Exception {
+ // parseBigDecimal default to false
+ DecimalFormat form = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+ assertFalse(form.isParseBigDecimal());
+ form.setParseBigDecimal(true);
+ assertTrue(form.isParseBigDecimal());
+
+ Number result = form.parse("123.123");
+ assertEquals(new BigDecimal("123.123"), result);
+
+ form.setParseBigDecimal(false);
+ assertFalse(form.isParseBigDecimal());
+
+ result = form.parse("123.123");
+ assertFalse(result instanceof BigDecimal);
+ }
+
+ public void test_parse_integerOnly() throws Exception {
+ DecimalFormat format = new DecimalFormat();
+ assertFalse("Default value of isParseIntegerOnly is true", format.isParseIntegerOnly());
+
+ format.setParseIntegerOnly(true);
+ assertTrue(format.isParseIntegerOnly());
+ Number result = format.parse("123.123");
+ assertEquals(new Long("123"), result);
+
+ format.setParseIntegerOnly(false);
+ assertFalse(format.isParseIntegerOnly());
+ result = format.parse("123.123");
+ assertEquals(new Double("123.123"), result);
+ }
+
+ // Test the type of the returned object
+ public void test_parse_returnType() {
+ DecimalFormat form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ Number number = form.parse("23.1", new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ // Test parsed object of type double when
+ // parseBigDecimal is set to true
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ number = form.parse("23.1", new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ form.setParseBigDecimal(true);
+ number = form.parse("23.1", new ParsePosition(0));
+
+ assertTrue(number instanceof BigDecimal);
+ assertEquals(new BigDecimal("23.1"), number);
+
+ // When parseIntegerOnly set to true, all numbers will be parsed
+ // into Long unless the value is out of the bound of Long or
+ // some special values such as NaN or Infinity.
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ form.setParseIntegerOnly(true);
+ number = form.parse("23.1f", new ParsePosition(0));
+
+ assertTrue(number instanceof Long);
+
+ number = form.parse("23.0", new ParsePosition(0));
+ assertTrue(number instanceof Long);
+
+ number = form.parse("-0.0", new ParsePosition(0));
+ assertTrue(number instanceof Long);
+ assertTrue(new Long(0).equals(number));
+
+ // The last integers representable by long.
+ number = form.parse("9223372036854775807.00", new ParsePosition(0));
+ assertEquals(Long.class, number.getClass());
+ number = form.parse("9223372036854775808.00", new ParsePosition(0));
+ assertEquals(Double.class, number.getClass());
+ // The first integers that need to be represented by double.
+ number = form.parse("-9223372036854775808.00", new ParsePosition(0));
+ assertEquals(Long.class, number.getClass());
+ number = form.parse("-9223372036854775809.00", new ParsePosition(0));
+ assertEquals(Double.class, number.getClass());
+
+ // Even if parseIntegerOnly is set to true, NaN will be parsed to Double
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ form.setParseIntegerOnly(true);
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+ number = form.parse(symbols.getNaN(), new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ // Even if parseIntegerOnly is set to true, Infinity will still be
+ // parsed to Double
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ form.setParseIntegerOnly(true);
+ symbols = new DecimalFormatSymbols();
+ number = form.parse(symbols.getInfinity(), new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ // ParseBigDecimal take precedence of parseBigInteger
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ form.setParseIntegerOnly(true);
+ form.setParseBigDecimal(true);
+
+ number = form.parse("23.1f", new ParsePosition(0));
+
+ assertTrue(number instanceof BigDecimal);
+
+ number = form.parse("23.0", new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+
+ number = form.parse("-92,233,720,368,547,758,080.00", new ParsePosition(0));
+ assertFalse(number instanceof BigInteger);
+ assertTrue(number instanceof BigDecimal);
+
+ // Test whether the parsed object is of type float. (To be specific,
+ // they are of type Double)
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ number = form.parse("23.1f", new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ form.setParseBigDecimal(true);
+ number = form.parse("23.1f", new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+ assertEquals(new BigDecimal("23.1"), number);
+
+ // Integer will be parsed to Long, unless parseBigDecimal is set to true
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ number = form.parse("123", new ParsePosition(0));
+ assertTrue(number instanceof Long);
+
+ form.setParseBigDecimal(true);
+ number = form.parse("123", new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+ assertEquals(new BigDecimal("123"), number);
+
+ // NaN will be parsed to Double, no matter parseBigDecimal set or not.
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ symbols = new DecimalFormatSymbols();
+ number = form.parse(symbols.getNaN() + "", new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ form.setParseBigDecimal(true);
+ number = form.parse(symbols.getNaN() + "", new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ // Infinity will be parsed to Double, no matter parseBigDecimal set or
+ // not.
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ symbols = new DecimalFormatSymbols();
+
+ number = form.parse(symbols.getInfinity(), new ParsePosition(0));
+
+ assertTrue(number instanceof Double);
+ assertEquals("Infinity", number.toString());
+ // When set bigDecimal to true, the result of parsing infinity
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ symbols = new DecimalFormatSymbols();
+ form.setParseBigDecimal(true);
+
+ number = form.parse(symbols.getInfinity(), new ParsePosition(0));
+ assertTrue(number instanceof Double);
+ assertEquals("Infinity", number.toString());
+
+ // Negative infinity will be parsed to double no matter parseBigDecimal
+ // set or not
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ symbols = new DecimalFormatSymbols();
+
+ number = form.parse("-" + symbols.getInfinity(), new ParsePosition(0));
+
+ assertTrue(number instanceof Double);
+ assertEquals("-Infinity", number.toString());
+
+ // When set bigDecimal to true, the result of parsing minus infinity
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ symbols = new DecimalFormatSymbols();
+ form.setParseBigDecimal(true);
+
+ number = form.parse("-" + symbols.getInfinity(), new ParsePosition(0));
+
+ assertTrue(number instanceof Double);
+ assertEquals("-Infinity", number.toString());
+
+ // -0.0 will be parsed to different type according to the combination of
+ // parseBigDecimal and parseIntegerOnly
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ // parseBigDecimal == true;
+ // parseIntegerOnly == false;
+ form.setParseBigDecimal(true);
+ number = form.parse("-0", new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+
+ number = form.parse("-0.0", new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+
+ // parseBigDecimal == false;
+ // parseIntegerOnly == true;
+ form.setParseBigDecimal(false);
+ form.setParseIntegerOnly(true);
+ number = form.parse("-0", new ParsePosition(0));
+
+ assertTrue(number instanceof Long);
+
+ number = form.parse("-0.0", new ParsePosition(0));
+ assertTrue(number instanceof Long);
+
+ // parseBigDecimal == false;
+ // parseIntegerOnly == false;
+ form.setParseBigDecimal(false);
+ form.setParseIntegerOnly(false);
+ number = form.parse("-0", new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ number = form.parse("-0.0", new ParsePosition(0));
+ assertTrue(number instanceof Double);
+
+ // parseBigDecimal == true;
+ // parseIntegerOnly == true;
+ // parseBigDecimal take precedence of parseBigInteger
+ form.setParseBigDecimal(true);
+ form.setParseIntegerOnly(true);
+ number = form.parse("-0", new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+
+ number = form.parse("-0.0", new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+
+ number = form.parse("12.4", new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+
+ // When parseBigDecimal is set to false, no matter how massive the
+ // mantissa part of a number is, the number will be parsed into Double
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ number = form.parse("9,223,372,036,854,775,808.00",
+ new ParsePosition(0));
+
+ assertTrue(number instanceof Double);
+ assertEquals("9.223372036854776E18", number.toString());
+
+ number = form.parse("-92,233,720,368,547,758,080.00",
+ new ParsePosition(0));
+ assertTrue(number instanceof Double);
+ assertEquals("-9.223372036854776E19", number.toString());
+
+ // When parseBigDecimal is set to true, if mantissa part of number
+ // exceeds Long.MAX_VALUE, the number will be parsed into BigDecimal
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ form.setParseBigDecimal(true);
+ number = form.parse("9,223,372,036,854,775,808.00",
+ new ParsePosition(0));
+
+ assertTrue(number instanceof BigDecimal);
+
+ assertEquals(9.223372036854776E18, number.doubleValue(), 0);
+
+ number = form.parse("-92,233,720,368,547,758,080.00", new ParsePosition(0));
+
+ assertTrue(number instanceof BigDecimal);
+ assertEquals(-9.223372036854776E19, number.doubleValue(), 0);
+
+ // The minimum value of Long will be parsed to Long when parseBigDecimal
+ // is not set
+
+ ParsePosition pos = new ParsePosition(0);
+ DecimalFormat df = new DecimalFormat();
+ pos = new ParsePosition(0);
+ Number nb = df.parse("" + Long.MIN_VALUE, pos);
+ assertTrue(nb instanceof Long);
+
+ // The maximum value of Long will be parsed to Long when parseBigDecimal
+ // is set
+ pos = new ParsePosition(0);
+ df = new DecimalFormat();
+ pos = new ParsePosition(0);
+ nb = df.parse("" + Long.MAX_VALUE, pos);
+ assertTrue(nb instanceof Long);
+
+ // When parsing invalid string( which is neither consist of digits nor
+ // NaN/Infinity), a null will be returned.
+
+ pos = new ParsePosition(0);
+ df = new DecimalFormat();
+ try {
+ nb = df.parse("invalid", pos);
+ assertNull(nb);
+ } catch (NullPointerException e) {
+ fail("Should not throw NPE");
+ }
+ }
+
+ public void test_parse_largeBigDecimal() {
+ DecimalFormat form = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+ form.setParseIntegerOnly(true);
+ form.setParseBigDecimal(true);
+
+ final String doubleMax2 = "359,538,626,972,463,141,629,054,847,463,408,"
+ + "713,596,141,135,051,689,993,197,834,953,606,314,521,560,057,077,"
+ + "521,179,117,265,533,756,343,080,917,907,028,764,928,468,642,653,"
+ + "778,928,365,536,935,093,407,075,033,972,099,821,153,102,564,152,"
+ + "490,980,180,778,657,888,151,737,016,910,267,884,609,166,473,806,"
+ + "445,896,331,617,118,664,246,696,549,595,652,408,289,446,337,476,"
+ + "354,361,838,599,762,500,808,052,368,249,716,736";
+ Number number = form.parse(doubleMax2, new ParsePosition(0));
+ assertTrue(number instanceof BigDecimal);
+ BigDecimal result = (BigDecimal) number;
+ assertEquals(new BigDecimal(Double.MAX_VALUE).add(new BigDecimal(Double.MAX_VALUE)),
+ result);
+ }
+
+ public void testMaximumFractionDigits_getAndSet() {
+ DecimalFormat form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ // getMaximumFractionDigits of DecimalFormat defaults to 3
+ assertEquals(3, form.getMaximumFractionDigits());
+
+ form.setMaximumFractionDigits(310);
+ assertEquals(310, form.getMaximumFractionDigits());
+
+ // Deliberately > 340. The API docs mention 340 and suggest that you can set the value
+ // higher but it will use 340 as a ceiling.
+ form.setMaximumFractionDigits(500);
+ assertEquals(500, form.getMaximumFractionDigits());
+
+ form.setMaximumFractionDigits(500);
+ assertEquals(500, form.getMaximumFractionDigits());
+ form.format(12.3);
+ assertEquals(500, form.getMaximumFractionDigits());
+
+ form.setMaximumFractionDigits(-2);
+ assertEquals(0, form.getMaximumFractionDigits());
+ }
+
+ public void testMinimumFractionDigits_getAndSet() {
+ DecimalFormat form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ // getMinimumFractionDigits from NumberFormat (default to 0)
+ // getMinimumFractionDigits from DecimalFormat (default to 0)
+ assertEquals(0, form.getMinimumFractionDigits());
+
+ form.setMinimumFractionDigits(310);
+ assertEquals(310, form.getMinimumFractionDigits());
+
+ // Deliberately > 340. The API docs mention 340 and suggest that you can set the value
+ // higher but it will use 340 as a ceiling.
+ form.setMinimumFractionDigits(500);
+ assertEquals(500, form.getMinimumFractionDigits());
+
+ form.setMaximumFractionDigits(400);
+ assertEquals(400, form.getMinimumFractionDigits());
+
+ form.setMinimumFractionDigits(-3);
+ assertEquals(0, form.getMinimumFractionDigits());
+ }
+
+ public void testMaximumIntegerDigits_getAndSet() {
+ // When use default locale, in this case zh_CN
+ // the returned instance of NumberFormat is a DecimalFormat
+ DecimalFormat form = new DecimalFormat("00.###E0");
+ assertEquals(2, form.getMaximumIntegerDigits());
+
+ form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ form.setMaximumIntegerDigits(300);
+ assertEquals(300, form.getMaximumIntegerDigits());
+
+ // Deliberately > 309. The API docs mention 309 and suggest that you can set the value
+ // higher but it will use 309 as a ceiling.
+ form.setMaximumIntegerDigits(500);
+ assertEquals(500, form.getMaximumIntegerDigits());
+
+ form = new DecimalFormat("00.###E0");
+ assertEquals(2, form.getMaximumIntegerDigits());
+
+ form.setMaximumIntegerDigits(500);
+ assertEquals(500, form.getMaximumIntegerDigits());
+ form.format(12.3);
+ assertEquals(500, form.getMaximumIntegerDigits());
+
+ form.setMaximumIntegerDigits(-3);
+ assertEquals(0, form.getMaximumIntegerDigits());
+
+ // regression test for HARMONY-878
+ assertTrue(new DecimalFormat("0\t'0'").getMaximumIntegerDigits() > 0);
+ }
+
+ public void testMinimumIntegerDigits_getAndSet() {
+ final int minIntDigit = 1;
+ DecimalFormat form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ // getMaximumIntegerDigits from DecimalFormat (default to 1)
+ assertEquals(minIntDigit, form.getMinimumIntegerDigits());
+
+ form.setMinimumIntegerDigits(300);
+ assertEquals(300, form.getMinimumIntegerDigits());
+
+ // Deliberately > 309. The API docs mention 309 and suggest that you can set the value
+ // higher but it will use 309 as a ceiling.
+ form.setMinimumIntegerDigits(500);
+ assertEquals(500, form.getMinimumIntegerDigits());
+
+ form.setMaximumIntegerDigits(400);
+ assertEquals(400, form.getMinimumIntegerDigits());
+
+ form.setMinimumIntegerDigits(-3);
+ assertEquals(0, form.getMinimumIntegerDigits());
+ }
+
+ // When MaxFractionDigits is set first and less than MinFractionDigits, max
+ // will be changed to min value
+ public void testMinimumFactionDigits_minChangesMax() {
+ DecimalFormat form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ form.setMaximumFractionDigits(100);
+ form.setMinimumFractionDigits(200);
+
+ assertEquals(200, form.getMaximumFractionDigits());
+ assertEquals(200, form.getMinimumFractionDigits());
+
+ form.setMaximumIntegerDigits(100);
+ form.setMinimumIntegerDigits(200);
+
+ assertEquals(200, form.getMaximumIntegerDigits());
+ assertEquals(200, form.getMinimumIntegerDigits());
+ }
+
+ // When MinFractionDigits is set first and less than MaxFractionDigits, min
+ // will be changed to max value
+ public void testMaximumFactionDigits_maxChangesMin() {
+ DecimalFormat form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ form.setMinimumFractionDigits(200);
+ form.setMaximumFractionDigits(100);
+
+ assertEquals(100, form.getMaximumFractionDigits());
+ assertEquals(100, form.getMinimumFractionDigits());
+
+ form.setMinimumIntegerDigits(200);
+ form.setMaximumIntegerDigits(100);
+
+ assertEquals(100, form.getMaximumIntegerDigits());
+ assertEquals(100, form.getMinimumIntegerDigits());
+ }
+
+ public void test_formatObject_errorCases() {
+ DecimalFormat form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ // If Object(including null) is not of type Number,
+ // IllegalArgumentException will be thrown out
+ try {
+ form.format(new Object(), new StringBuffer(), new FieldPosition(0));
+ fail("Should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ form.format(null, new StringBuffer(), new FieldPosition(0));
+ fail("Should throw IAE");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ // When StringBuffer == null || FieldPosition == null
+ // NullPointerException will be thrown out.
+ try {
+ form.format(new Double(1.9), null, new FieldPosition(0));
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ form.format(new Double(1.3), new StringBuffer(), null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ form.format(new Object(), new StringBuffer(), new FieldPosition(0));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_formatObject() {
+ DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+
+ // format maxLong
+ FieldPosition pos = new FieldPosition(0);
+ StringBuffer out = format.format(new Long(Long.MAX_VALUE), new StringBuffer(), pos);
+ assertTrue("Wrong result L1: " + out, out.toString().equals("9,223,372,036,854,775,807"));
+
+ // format minLong
+ pos = new FieldPosition(0);
+ out = format.format(new Long(Long.MIN_VALUE), new StringBuffer(), pos);
+ assertTrue("Wrong result L2: " + out, out.toString().equals("-9,223,372,036,854,775,808"));
+
+ // format maxLong of type BigInteger
+ pos = new FieldPosition(0);
+ out = format.format(new java.math.BigInteger(String.valueOf(Long.MAX_VALUE)),
+ new StringBuffer(), pos);
+ assertTrue("Wrong result BI1: " + out, out.toString().equals("9,223,372,036,854,775,807"));
+
+ // format minLong of type BigInteger
+ pos = new FieldPosition(0);
+ out = format.format(new java.math.BigInteger(String.valueOf(Long.MIN_VALUE)),
+ new StringBuffer(), pos);
+ assertTrue("Wrong result BI2: " + out, out.toString().equals("-9,223,372,036,854,775,808"));
+
+ // format maxLong + 1
+ java.math.BigInteger big;
+ pos = new FieldPosition(0);
+ big = new java.math.BigInteger(String.valueOf(Long.MAX_VALUE))
+ .add(new java.math.BigInteger("1"));
+ out = format.format(big, new StringBuffer(), pos);
+ assertTrue("Wrong result BI3: " + out, out.toString().equals("9,223,372,036,854,775,808"));
+
+ // format minLong - 1
+ pos = new FieldPosition(0);
+ big = new java.math.BigInteger(String.valueOf(Long.MIN_VALUE))
+ .add(new java.math.BigInteger("-1"));
+ out = format.format(big, new StringBuffer(), pos);
+ assertTrue("Wrong result BI4: " + out, out.toString().equals("-9,223,372,036,854,775,809"));
+
+ // format big decimal
+ pos = new FieldPosition(0);
+ out = format.format(new java.math.BigDecimal("51.348"), new StringBuffer(), pos);
+ assertTrue("Wrong result BD1: " + out, out.toString().equals("51.348"));
+
+ // format big decimal
+ pos = new FieldPosition(0);
+ out = format.format(new java.math.BigDecimal("51"), new StringBuffer(), pos);
+ assertTrue("Wrong result BD2: " + out, out.toString().equals("51"));
+
+ // format big decimal Double.MAX_VALUE * 2
+ java.math.BigDecimal bigDecimal;
+ pos = new FieldPosition(0);
+ final String doubleMax2 = "359,538,626,972,463,141,629,054,847,463,408,"
+ + "713,596,141,135,051,689,993,197,834,953,606,314,521,560,057,077,"
+ + "521,179,117,265,533,756,343,080,917,907,028,764,928,468,642,653,"
+ + "778,928,365,536,935,093,407,075,033,972,099,821,153,102,564,152,"
+ + "490,980,180,778,657,888,151,737,016,910,267,884,609,166,473,806,"
+ + "445,896,331,617,118,664,246,696,549,595,652,408,289,446,337,476,"
+ + "354,361,838,599,762,500,808,052,368,249,716,736";
+ bigDecimal = new BigDecimal(Double.MAX_VALUE).add(new BigDecimal(Double.MAX_VALUE));
+ out = format.format(bigDecimal, new StringBuffer(), pos);
+ assertTrue("Wrong result BDmax2: " + out, out.toString().equals(doubleMax2));
+
+ // format big decimal Double.MIN_VALUE + Double.MIN_VALUE
+ // and Double.MIN_VALUE - Double.MIN_VALUE
+ pos = new FieldPosition(0);
+
+ bigDecimal = new BigDecimal(Double.MIN_VALUE).add(new BigDecimal(Double.MIN_VALUE));
+ out = format.format(bigDecimal, new StringBuffer(), pos);
+
+ bigDecimal = new BigDecimal(Float.MAX_VALUE).add(new BigDecimal(Float.MAX_VALUE));
+ out = format.format(bigDecimal, new StringBuffer(), pos);
+ final String BDFloatMax2 = "680,564,693,277,057,719,623,408,366,969,033,850,880";
+ assertTrue("Wrong result BDFloatMax2: " + out, out.toString().equals(BDFloatMax2));
+ // format big decimal Float.MIN_VALUE + Float.MIN_VALUE
+ // and Float.MIN_VALUE - Float.MIN_VALUE
+ bigDecimal = new BigDecimal(Float.MIN_VALUE).add(new BigDecimal(Float.MIN_VALUE));
+ out = format.format(bigDecimal, new StringBuffer(), pos);
+ final String BDFloatMin2 = "0";
+
+ bigDecimal = new BigDecimal(Float.MIN_VALUE).subtract(new BigDecimal(Float.MIN_VALUE));
+ out = format.format(bigDecimal, new StringBuffer(), pos);
+
+ assertTrue("Wrong result BDFloatMax2: " + out, out.toString().equals(BDFloatMin2));
+ }
+
+ public void test_equals() {
+ DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ DecimalFormat cloned = (DecimalFormat) format.clone();
+ cloned.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
+ assertEquals(format, cloned);
+
+ Currency c = Currency.getInstance(Locale.US);
+ cloned.setCurrency(c);
+
+ assertEquals(format, cloned);
+ }
+
+ public void test_getNegativePrefix() {
+ DecimalFormat df = new DecimalFormat();
+ df.setNegativePrefix("--");
+ assertTrue("Incorrect negative prefix", df.getNegativePrefix().equals("--"));
+ }
+
+ public void test_getNegativeSuffix() {
+ DecimalFormat df = new DecimalFormat();
+ df.setNegativeSuffix("&");
+ assertTrue("Incorrect negative suffix", df.getNegativeSuffix().equals("&"));
+ }
+
+ public void test_getPositivePrefix() {
+ DecimalFormat df = new DecimalFormat();
+ df.setPositivePrefix("++");
+ assertTrue("Incorrect positive prefix", df.getPositivePrefix().equals("++"));
+ }
+
+ public void test_getPositiveSuffix() {
+ DecimalFormat df = new DecimalFormat();
+ df.setPositiveSuffix("%");
+ assertTrue("Incorrect positive prefix", df.getPositiveSuffix().equals("%"));
+ }
+
+ public void test_setPositivePrefix() throws Exception {
+ DecimalFormat format = new DecimalFormat();
+ assertEquals("", format.getPositivePrefix());
+
+ format.setPositivePrefix("PosPrf");
+ assertEquals("PosPrf", format.getPositivePrefix());
+ assertTrue(format.parse("PosPrf123.45").doubleValue() == 123.45);
+
+ format.setPositivePrefix("");
+ assertEquals("", format.getPositivePrefix());
+
+ format.setPositivePrefix(null);
+ assertNull(format.getPositivePrefix());
+ }
+
+ public void test_setPositiveSuffix() throws Exception {
+ DecimalFormat format = new DecimalFormat();
+ assertEquals("", format.getPositiveSuffix());
+
+ format.setPositiveSuffix("PosSfx");
+ assertEquals("PosSfx", format.getPositiveSuffix());
+ assertTrue(format.parse("123.45PosSfx").doubleValue() == 123.45);
+
+ format.setPositiveSuffix("");
+ assertEquals("", format.getPositiveSuffix());
+
+ format.setPositiveSuffix(null);
+ assertNull(format.getPositiveSuffix());
+ }
+
+ public void test_setNegativePrefix() throws Exception {
+ DecimalFormat format = new DecimalFormat();
+ assertEquals("-", format.getNegativePrefix());
+
+ format.setNegativePrefix("NegPrf");
+ assertEquals("NegPrf", format.getNegativePrefix());
+ assertTrue(format.parse("NegPrf123.45").doubleValue() == -123.45);
+ format.setNegativePrefix("");
+ assertEquals("", format.getNegativePrefix());
+
+ format.setNegativePrefix(null);
+ assertNull(format.getNegativePrefix());
+ }
+
+ public void test_setNegativeSuffix() throws Exception {
+ DecimalFormat format = new DecimalFormat();
+ assertEquals("", format.getNegativeSuffix());
+
+ format.setNegativeSuffix("NegSfx");
+ assertEquals("NegSfx", format.getNegativeSuffix());
+ assertTrue(format.parse("123.45NegPfx").doubleValue() == 123.45);
+
+ format.setNegativeSuffix("");
+ assertEquals("", format.getNegativeSuffix());
+
+ format.setNegativeSuffix(null);
+ assertNull(format.getNegativeSuffix());
+ }
+
+ public void test_setGroupingUsed() {
+ DecimalFormat format = new DecimalFormat();
+
+ StringBuffer buf = new StringBuffer();
+ format.setGroupingUsed(false);
+ format.format(new Long(1970), buf, new FieldPosition(0));
+ assertEquals("1970", buf.toString());
+ assertFalse(format.isGroupingUsed());
+ format.format(new Long(1970), buf, new FieldPosition(0));
+ assertEquals("19701970", buf.toString());
+ assertFalse(format.isGroupingUsed());
+
+ format.setGroupingUsed(true);
+ format.format(new Long(1970), buf, new FieldPosition(0));
+ assertEquals("197019701,970", buf.toString());
+ assertTrue(format.isGroupingUsed());
+ }
+
+ public void test_isGroupingUsed() {
+ assertFalse(new DecimalFormat("####.##").isGroupingUsed());
+ assertFalse(new DecimalFormat("######.######").isGroupingUsed());
+ assertFalse(new DecimalFormat("000000.000000").isGroupingUsed());
+ assertFalse(new DecimalFormat("######.000000").isGroupingUsed());
+ assertFalse(new DecimalFormat("000000.######").isGroupingUsed());
+ assertFalse(new DecimalFormat(" ###.###").isGroupingUsed());
+ assertFalse(new DecimalFormat("$#####.######").isGroupingUsed());
+ assertFalse(new DecimalFormat("$$####.######").isGroupingUsed());
+
+ assertTrue(new DecimalFormat("###,####").isGroupingUsed());
+ }
+
+ public void testConstructor_noArg() {
+ // Test for method java.text.DecimalFormat()
+ // the constructor form that specifies a pattern is equal to the form
+ // constructed with no pattern and applying that pattern using the
+ // applyPattern call
+ DecimalFormat format1 = new DecimalFormat();
+ format1.applyPattern("'$'1000.0000");
+ DecimalFormat format2 = new DecimalFormat();
+ format2.applyPattern("'$'1000.0000");
+ assertTrue("Constructed format did not match applied format object",
+ format2.equals(format1));
+ DecimalFormat format3 = new DecimalFormat("'$'1000.0000");
+ assertTrue("Constructed format did not match applied format object",
+ format3.equals(format1));
+ DecimalFormat format4 = new DecimalFormat("'$'8000.0000");
+ assertTrue("Constructed format did not match applied format object",
+ !format4.equals(format1));
+ }
+
+ public void testConstructor_string() {
+ // Test for method java.text.DecimalFormat(java.lang.String)
+ // the constructor form that specifies a pattern is equal to the form
+ // constructed with no pattern and applying that pattern using the
+ // applyPattern call
+ DecimalFormat format = new DecimalFormat("'$'0000.0000");
+ DecimalFormat format1 = new DecimalFormat();
+ format1.applyPattern("'$'0000.0000");
+ assertTrue("Constructed format did not match applied format object",
+ format.equals(format1));
+
+ new DecimalFormat("####.##");
+ new DecimalFormat("######.######");
+ new DecimalFormat("000000.000000");
+ new DecimalFormat("######.000000");
+ new DecimalFormat("000000.######");
+ new DecimalFormat(" ###.###");
+ new DecimalFormat("$#####.######");
+ new DecimalFormat("$$####.######");
+ new DecimalFormat("%#,##,###,####");
+ new DecimalFormat("#,##0.00;(#,##0.00)");
+
+ try {
+ new DecimalFormat(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ new DecimalFormat("%#,##,###,####'");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ new DecimalFormat("#.##0.00");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testConstructor_stringAndSymbols() {
+ // case 1: Try to construct object using correct pattern and format
+ // symbols.
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.CANADA);
+ DecimalFormat format1 = new DecimalFormat("'$'1000.0000", dfs);
+ DecimalFormat format2 = new DecimalFormat();
+ format2.applyPattern("'$'1000.0000");
+ format2.setDecimalFormatSymbols(dfs);
+ assertTrue("Constructed format did not match applied format object",
+ format2.equals(format1));
+ assertTrue("Constructed format did not match applied format object",
+ !format1.equals(
+ new DecimalFormat("'$'1000.0000", new DecimalFormatSymbols(Locale.CHINA))));
+
+ // case 2: Try to construct object using null arguments.
+ try {
+ new DecimalFormat("'$'1000.0000", (DecimalFormatSymbols) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ new DecimalFormat(null, new DecimalFormatSymbols());
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ new DecimalFormat(null, (DecimalFormatSymbols) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // case 3: Try to construct object using incorrect pattern.
+ try {
+ new DecimalFormat("$'", new DecimalFormatSymbols());
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_applyPattern() {
+ DecimalFormat format = new DecimalFormat("#.#");
+ assertEquals("Wrong pattern 1", "#0.#", format.toPattern());
+ format = new DecimalFormat("#.");
+ assertEquals("Wrong pattern 2", "#0.", format.toPattern());
+ format = new DecimalFormat("#");
+ assertEquals("Wrong pattern 3", "#", format.toPattern());
+ format = new DecimalFormat(".#");
+ assertEquals("Wrong pattern 4", "#.0", format.toPattern());
+
+ // Regression for HARMONY-6485
+ format = new DecimalFormat();
+ format.setMinimumIntegerDigits(0);
+ format.setMinimumFractionDigits(0);
+ format.setMaximumFractionDigits(0);
+ format.applyPattern("00.0#");
+ assertEquals("Minimum integer digits not set", 2, format.getMinimumIntegerDigits());
+ assertEquals("Minimum fraction digits not set", 1, format.getMinimumFractionDigits());
+ assertEquals("Maximum fraction digits not set", 2, format.getMaximumFractionDigits());
+
+ try {
+ format.applyPattern(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ format.applyPattern("%#,##,###,####'");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ format.applyPattern("#.##0.00");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ // AndroidOnly: icu supports 2 grouping sizes
+ public void test_applyPattern_icu2GroupingSizes() {
+ DecimalFormat decFormat = new DecimalFormat("#.#");
+ String[] patterns = {
+ "####.##", "######.######", "000000.000000",
+ "######.000000", "000000.######", " ###.###", "$#####.######",
+ "$$####.######", "%#,##,###,####", "#,##0.00;(#,##0.00)",
+ "##.##-E"
+ };
+
+ String[] expResult = {
+ "#0.##", "#0.######", "#000000.000000",
+ "#.000000", "#000000.######", " #0.###", "$#0.######",
+ "$$#0.######",
+ "%#,###,####", // icu only. icu supports two grouping sizes
+ "#,##0.00;(#,##0.00)",
+ "#0.##-'E'"
+ // icu only. E in the suffix does not need to be quoted. This is done automatically.
+ };
+
+ for (int i = 0; i < patterns.length; i++) {
+ decFormat.applyPattern(patterns[i]);
+ String result = decFormat.toPattern();
+ assertEquals("Failed to apply following pattern: " + patterns[i] +
+ "\n expected: " + expResult[i] +
+ "\n returned: " + result, expResult[i], result);
+ }
+ }
+
+ public void test_applyLocalizedPattern() throws Exception {
+ DecimalFormat format = new DecimalFormat();
+
+ // case 1: Try to apply correct variants of pattern.
+ format.applyLocalizedPattern("#.#");
+ assertEquals("Wrong pattern 1", "#0.#", format.toLocalizedPattern());
+ format.applyLocalizedPattern("#.");
+ assertEquals("Wrong pattern 2", "#0.", format.toLocalizedPattern());
+ format.applyLocalizedPattern("#");
+ assertEquals("Wrong pattern 3", "#", format.toLocalizedPattern());
+ format.applyLocalizedPattern(".#");
+ assertEquals("Wrong pattern 4", "#.0", format.toLocalizedPattern());
+
+ // case 2: Try to apply malformed patten.
+ try {
+ format.applyLocalizedPattern("'#,#:#0.0#;(#)");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // case 3: Try to apply null pattern.
+ try {
+ format.applyLocalizedPattern((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_toPattern() {
+ DecimalFormat format = new DecimalFormat();
+ format.applyPattern("#.#");
+ assertEquals("Wrong pattern 1", "#0.#", format.toPattern());
+ format.applyPattern("#.");
+ assertEquals("Wrong pattern 2", "#0.", format.toPattern());
+ format.applyPattern("#");
+ assertEquals("Wrong pattern 3", "#", format.toPattern());
+ format.applyPattern(".#");
+ assertEquals("Wrong pattern 4", "#.0", format.toPattern());
+ }
+
+ public void test_toLocalizedPattern() {
+ DecimalFormat format = new DecimalFormat();
+ format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
+ format.applyLocalizedPattern("#.#");
+ assertEquals("Wrong pattern 1", "#0.#", format.toLocalizedPattern());
+ format.applyLocalizedPattern("#.");
+ assertEquals("Wrong pattern 2", "#0.", format.toLocalizedPattern());
+ format.applyLocalizedPattern("#");
+ assertEquals("Wrong pattern 3", "#", format.toLocalizedPattern());
+ format.applyLocalizedPattern(".#");
+ assertEquals("Wrong pattern 4", "#.0", format.toLocalizedPattern());
+ }
+
+ public void test_hashCode() {
+ DecimalFormat df1 = new DecimalFormat();
+ DecimalFormat df2 = (DecimalFormat) df1.clone();
+ assertTrue("Hash codes of equals object are not equal", df2.hashCode() == df1.hashCode());
+ }
+
+ public void test_clone() {
+ DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ DecimalFormat cloned = (DecimalFormat) format.clone();
+ assertEquals(cloned.getDecimalFormatSymbols(), format.getDecimalFormatSymbols());
+
+ format = new DecimalFormat("'$'0000.0000");
+ DecimalFormat format1 = (DecimalFormat) (format.clone());
+ // make sure the objects are equal
+ assertTrue("Object's clone isn't equal!", format.equals(format1));
+ // change the content of the clone and make sure it's not equal anymore
+ // verifies that it's data is now distinct from the original
+ format1.applyPattern("'$'0000.####");
+ assertTrue("Object's changed clone should not be equal!", !format.equals(format1));
+ }
+
+ public void test_formatDouble_maximumFractionDigits() {
+ DecimalFormat df = new DecimalFormat("###0.##", new DecimalFormatSymbols(Locale.US));
+ df.setMaximumFractionDigits(3);
+ assertEquals(3, df.getMaximumFractionDigits());
+ assertEquals("1.235", df.format(1.23456));
+ df.setMinimumFractionDigits(4);
+ assertEquals(4, df.getMaximumFractionDigits());
+ assertEquals("456.0000", df.format(456));
+
+ df = new DecimalFormat("##0.#");
+ df.setMaximumFractionDigits(30);
+ assertEquals("0", df.format(0.0));
+ assertEquals("-0", df.format(-0.0));
+ assertEquals("1", df.format(1.0));
+ assertEquals("-1", df.format(-1.0));
+ }
+
+ public void test_formatDouble_minimumFractionDigits() {
+ DecimalFormat df = new DecimalFormat("###0.##", new DecimalFormatSymbols(Locale.US));
+ df.setMinimumFractionDigits(4);
+ assertEquals(4, df.getMinimumFractionDigits());
+ assertEquals("1.2300", df.format(1.23));
+ df.setMaximumFractionDigits(2);
+ assertEquals(2, df.getMinimumFractionDigits());
+ assertEquals("456.00", df.format(456));
+
+ df = new DecimalFormat("##0.#", new DecimalFormatSymbols(Locale.US));
+ df.setMinimumFractionDigits(30);
+ assertEquals("0.000000000000000000000000000000", df.format(0.0));
+ assertEquals("-0.000000000000000000000000000000", df.format(-0.0));
+ assertEquals("1.000000000000000000000000000000", df.format(1.0));
+ assertEquals("-1.000000000000000000000000000000", df.format(-1.0));
+ }
+
+ public void test_formatDouble_withFieldPosition() {
+ new Support_DecimalFormat(
+ "test_formatDLjava_lang_StringBufferLjava_text_FieldPosition")
+ .t_format_with_FieldPosition();
+ }
+
+ // This test serves as a regression test for Android's behavior.
+ // There are many patterns that produce different output from the RI but are sometimes the
+ // consequence of Android following the ICU DecimalFormat rules.
+ public void test_formatDouble_scientificNotation() {
+ FormatTester formatTester = new FormatTester();
+ final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+
+ DecimalFormat df = new DecimalFormat("00.0#E0", dfs);
+ // ["00.0#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=2,
+ // maxFractionDigits=2,minIntegerDigits=2,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (2) + "max fractional digits (2) == 4
+ formatTester.format(df, "00.0E0", 0.0);
+ formatTester.format(df, "10.0E-1", 1.0);
+ formatTester.format(df, "12.0E0", 12.0);
+ formatTester.format(df, "12.3E1", 123.0);
+ formatTester.format(df, "12.34E2", 1234.0);
+ formatTester.format(df, "12.35E3", 12346.0);
+ formatTester.format(df, "10.0E4", 99999.0);
+ formatTester.format(df, "12.0E-1", 1.2);
+ formatTester.format(df, "12.3E0", 12.3);
+ formatTester.format(df, "12.34E1", 123.4);
+ formatTester.format(df, "12.35E2", 1234.6);
+ formatTester.format(df, "10.0E3", 9999.9);
+ formatTester.format(df, "10.0E-2", 0.1);
+ formatTester.format(df, "12.0E-2", 0.12);
+ formatTester.format(df, "12.3E-2", 0.123);
+ formatTester.format(df, "12.34E-2", 0.1234);
+ formatTester.format(df, "12.35E-2", 0.12346);
+ formatTester.format(df, "10.0E-1", 0.99999);
+ formatTester.format(df, "-10.0E-1", -1.0);
+ formatTester.format(df, "-12.0E0", -12.0);
+ formatTester.format(df, "-12.3E1", -123.0);
+ formatTester.format(df, "-12.34E2", -1234.0);
+ formatTester.format(df, "-12.35E3", -12346.0);
+ formatTester.format(df, "-10.0E4", -99999.0);
+
+ df = new DecimalFormat("#00.0##E0", dfs);
+ // ["#00.0##E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=3,
+ // maxFractionDigits=3,minIntegerDigits=2,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (3).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (2) + "max fractional digits (3) == 5
+ formatTester.format(df, "100E-3", 0.1);
+ formatTester.format(df, "120E-3", 0.12);
+ formatTester.format(df, "123E-3", 0.123);
+ formatTester.format(df, "123.4E-3", 0.1234);
+ formatTester.format(df, "123.46E-3", 0.1234567);
+ formatTester.format(df, "10E-3", 0.01);
+ formatTester.format(df, "12E-3", 0.012);
+ formatTester.format(df, "12.3E-3", 0.0123);
+ formatTester.format(df, "12.34E-3", 0.01234);
+ formatTester.format(df, "12.346E-3", 0.01234567);
+ formatTester.format(df, "1.0E-3", 0.001);
+ formatTester.format(df, "1.2E-3", 0.0012);
+ formatTester.format(df, "1.23E-3", 0.00123);
+ formatTester.format(df, "1.234E-3", 0.001234);
+ formatTester.format(df, "1.2346E-3", 0.001234567);
+ formatTester.format(df, "100E-6", 0.0001);
+ formatTester.format(df, "120E-6", 0.00012);
+ formatTester.format(df, "123E-6", 0.000123);
+ formatTester.format(df, "123.4E-6", 0.0001234);
+ formatTester.format(df, "123.46E-6", 0.0001234567);
+ formatTester.format(df, "0.0E0", 0.0);
+ formatTester.format(df, "1.0E0", 1.0);
+ formatTester.format(df, "12E0", 12.0);
+ formatTester.format(df, "123E0", 123.0);
+ formatTester.format(df, "1.234E3", 1234.0);
+ formatTester.format(df, "12.345E3", 12345.0);
+ formatTester.format(df, "123.46E3", 123456.0);
+ formatTester.format(df, "1.2346E6", 1234567.0);
+ formatTester.format(df, "12.346E6", 12345678.0);
+ formatTester.format(df, "100E6", 99999999.0);
+
+ df = new DecimalFormat("#.0E0", dfs);
+ // ["#.0E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=1,
+ // maxFractionDigits=1,minIntegerDigits=0,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (1).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (0) + "max fractional digits (1) == 1
+ formatTester.format(df, "0.0E0", 0.0);
+ formatTester.format(df, "1.0E0", 1.0);
+ formatTester.format(df, "1.0E1", 12.0);
+ formatTester.format(df, "1.0E2", 123.0);
+ formatTester.format(df, "1.0E3", 1234.0);
+ formatTester.format(df, "1.0E4", 9999.0);
+
+ df = new DecimalFormat("0.E0", dfs);
+ // ["0.E0",isDecimalSeparatorAlwaysShown=true,groupingSize=0,multiplier=1,negativePrefix=-,
+ // negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=1,maxFractionDigits=0,
+ // minIntegerDigits=1,minFractionDigits=0,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (0) == 1
+ formatTester.format(df, "0E0", 0.0);
+ formatTester.format(df, "1E0", 1.0);
+ formatTester.format(df, "1E1", 12.0);
+ formatTester.format(df, "1E2", 123.0);
+ formatTester.format(df, "1E3", 1234.0);
+ formatTester.format(df, "1E4", 9999.0);
+
+ df = new DecimalFormat("##0.00#E0", dfs);
+ // ["##0.00#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=3,
+ // maxFractionDigits=3,minIntegerDigits=1,minFractionDigits=2,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (3).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (3) == 4
+ formatTester.format(df, "100E-3", 0.1);
+ formatTester.format(df, "123.5E-3", 0.1234567);
+ formatTester.format(df, "1.00E0", 0.9999999);
+ formatTester.format(df, "10.0E-3", 0.01);
+ formatTester.format(df, "12.35E-3", 0.01234567);
+ formatTester.format(df, "100E-3", 0.09999999);
+ formatTester.format(df, "1.00E-3", 0.001);
+ formatTester.format(df, "1.235E-3", 0.001234567);
+ formatTester.format(df, "10.0E-3", 0.009999999);
+ formatTester.format(df, "100E-6", 0.0001);
+ formatTester.format(df, "123.5E-6", 0.0001234567);
+ formatTester.format(df, "1.00E-3", 0.0009999999);
+
+ df = new DecimalFormat("###0.00#E0", dfs);
+ // ["###0.00#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=4,
+ // maxFractionDigits=3,minIntegerDigits=1,minFractionDigits=2,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (4).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (3) == 4
+ formatTester.format(df, "1000E-4", 0.1);
+ formatTester.format(df, "1235E-4", 0.12345678);
+ formatTester.format(df, "1.00E0", 0.99999999);
+ formatTester.format(df, "100E-4", 0.01);
+ formatTester.format(df, "123.5E-4", 0.012345678);
+ formatTester.format(df, "1000E-4", 0.099999999);
+ formatTester.format(df, "10.0E-4", 0.001);
+ formatTester.format(df, "12.35E-4", 0.0012345678);
+ formatTester.format(df, "100E-4", 0.0099999999);
+ formatTester.format(df, "1.00E-4", 0.0001);
+ formatTester.format(df, "1.235E-4", 0.00012345678);
+ formatTester.format(df, "10.0E-4", 0.00099999999);
+ formatTester.format(df, "1000E-8", 0.00001);
+ formatTester.format(df, "1235E-8", 0.000012345678);
+ formatTester.format(df, "1.00E-4", 0.000099999999);
+
+ df = new DecimalFormat("###0.0#E0", dfs);
+ // ["###0.0#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=4,
+ // maxFractionDigits=2,minIntegerDigits=1,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (4).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (2) == 3
+ formatTester.format(df, "1000E-4", 0.1);
+ formatTester.format(df, "1230E-4", 0.1234567);
+ formatTester.format(df, "1.0E0", 0.9999999);
+ formatTester.format(df, "100E-4", 0.01);
+ formatTester.format(df, "123E-4", 0.01234567);
+ formatTester.format(df, "1000E-4", 0.09999999);
+ formatTester.format(df, "10E-4", 0.001);
+ formatTester.format(df, "12.3E-4", 0.001234567);
+ formatTester.format(df, "100E-4", 0.009999999);
+ formatTester.format(df, "1.0E-4", 0.0001);
+ formatTester.format(df, "1.23E-4", 0.0001234567);
+ formatTester.format(df, "10E-4", 0.0009999999);
+ formatTester.format(df, "1000E-8", 0.00001);
+ formatTester.format(df, "1230E-8", 0.00001234567);
+ formatTester.format(df, "1.0E-4", 0.00009999999);
+
+ df = new DecimalFormat("##0.0E0", dfs);
+ // ["##0.0E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=3,
+ // maxFractionDigits=1,minIntegerDigits=1,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (3).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (1) == 2
+ formatTester.format(df, "0.0E0", 0.0);
+ formatTester.format(df, "1.0E0", 1.0);
+ formatTester.format(df, "12E0", 12.0);
+ formatTester.format(df, "120E0", 123.0);
+ formatTester.format(df, "1.2E3", 1234.0);
+ formatTester.format(df, "12E3", 12346.0);
+ formatTester.format(df, "100E3", 99999.0);
+ formatTester.format(df, "1.0E6", 999999.0);
+
+ df = new DecimalFormat("0.#E0", dfs);
+ // ["0.#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=1,
+ // maxFractionDigits=1,minIntegerDigits=1,minFractionDigits=0,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (1) == 2
+ formatTester.format(df, "0E0", 0.0);
+ formatTester.format(df, "1E0", 1.0);
+ formatTester.format(df, "1.2E1", 12.0);
+ formatTester.format(df, "1.2E2", 123.0);
+ formatTester.format(df, "1.2E3", 1234.0);
+ formatTester.format(df, "1E4", 9999.0);
+
+ df = new DecimalFormat(".0E0", dfs);
+ // [".0E0",isDecimalSeparatorAlwaysShown=true,groupingSize=0,multiplier=1,negativePrefix=-,
+ // negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=0,maxFractionDigits=1,
+ // minIntegerDigits=0,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (0) + "max fractional digits (1) == 2
+ formatTester.format(df, ".0E0", 0.0);
+ formatTester.format(df, ".1E1", 1.0);
+ formatTester.format(df, ".1E2", 12.0);
+ formatTester.format(df, ".1E3", 123.0);
+ formatTester.format(df, ".1E4", 1234.0);
+ formatTester.format(df, ".1E5", 9999.0);
+
+ formatTester.throwFailures();
+ }
+
+ public void test_formatDouble_scientificNotationMinusZero() throws Exception {
+ FormatTester formatTester = new FormatTester();
+ final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+
+ DecimalFormat df = new DecimalFormat("00.0#E0", dfs);
+ // ["00.0#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=2,
+ // maxFractionDigits=2,minIntegerDigits=2,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (2) + "max fractional digits (2) == 4
+ formatTester.format(df, "-00.0E0", -0.0);
+
+ df = new DecimalFormat("##0.0E0", dfs);
+ // ["##0.0E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=3,
+ // maxFractionDigits=1,minIntegerDigits=1,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (3).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (1) == 2
+ formatTester.format(df, "-0.0E0", -0.0);
+
+ df = new DecimalFormat("#.0E0", dfs);
+ // ["#.0E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=1,
+ // maxFractionDigits=1,minIntegerDigits=0,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (1).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (0) + "max fractional digits (1) == 2
+ formatTester.format(df, "-0.0E0", -0.0);
+
+ df = new DecimalFormat("0.#E0", dfs);
+ // ["0.#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=1,
+ // maxFractionDigits=1,minIntegerDigits=1,minFractionDigits=0,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (1) == 2
+ formatTester.format(df, "-0E0", -0.0);
+
+ df = new DecimalFormat(".0E0", dfs);
+ // [".0E0",isDecimalSeparatorAlwaysShown=true,groupingSize=0,multiplier=1,negativePrefix=-,
+ // negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=0,maxFractionDigits=1,
+ // minIntegerDigits=0,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (0) + "max fractional digits (1) == 1
+ formatTester.format(df, "-.0E0", -0.0);
+
+ formatTester.throwFailures();
+ }
+
+ public void test_formatLong_maximumIntegerDigits() {
+ DecimalFormat df = new DecimalFormat("###0.##");
+ df.setMaximumIntegerDigits(2);
+ assertEquals(2, df.getMaximumIntegerDigits());
+ assertEquals("34", df.format(1234));
+ df.setMinimumIntegerDigits(4);
+ assertEquals(4, df.getMaximumIntegerDigits());
+ assertEquals("0026", df.format(26));
+ }
+
+ public void test_formatLong_minimumIntegerDigits() {
+ DecimalFormat df = new DecimalFormat("###0.##", new DecimalFormatSymbols(Locale.US));
+ df.setMinimumIntegerDigits(3);
+ assertEquals(3, df.getMinimumIntegerDigits());
+ assertEquals("012", df.format(12));
+ df.setMaximumIntegerDigits(2);
+ assertEquals(2, df.getMinimumIntegerDigits());
+ assertEquals("00.7", df.format(0.7));
+ }
+
+ // See also the _formatDouble tests. This tests a subset of patterns / values.
+ public void test_formatLong_scientificNotation() {
+ FormatTester formatTester = new FormatTester();
+ final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+
+ DecimalFormat df = new DecimalFormat("00.0#E0", dfs);
+ // ["00.0#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=2,
+ // maxFractionDigits=2,minIntegerDigits=2,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (2) + "max fractional digits (2) == 4
+ formatTester.format(df, "00.0E0", 0);
+ formatTester.format(df, "10.0E-1", 1);
+ formatTester.format(df, "12.0E0", 12);
+ formatTester.format(df, "12.3E1", 123);
+ formatTester.format(df, "12.34E2", 1234);
+ formatTester.format(df, "12.35E3", 12346);
+ formatTester.format(df, "10.0E4", 99999);
+ formatTester.format(df, "-10.0E-1", -1);
+ formatTester.format(df, "-12.0E0", -12);
+ formatTester.format(df, "-12.3E1", -123);
+ formatTester.format(df, "-12.34E2", -1234);
+ formatTester.format(df, "-12.35E3", -12346);
+ formatTester.format(df, "-10.0E4", -99999);
+
+ df = new DecimalFormat("##0.0E0", dfs);
+ // ["##0.0E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=3,
+ // maxFractionDigits=1,minIntegerDigits=1,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (3).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (1) == 2
+ formatTester.format(df, "0.0E0", 0);
+ formatTester.format(df, "1.0E0", 1);
+ formatTester.format(df, "12E0", 12);
+ formatTester.format(df, "120E0", 123);
+ formatTester.format(df, "1.2E3", 1234);
+ formatTester.format(df, "12E3", 12346);
+ formatTester.format(df, "100E3", 99999);
+ formatTester.format(df, "1.0E6", 999999);
+
+ df = new DecimalFormat("#00.0##E0", dfs);
+ // ["##0.0E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=3,
+ // maxFractionDigits=1,minIntegerDigits=1,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (3).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (2) + "max fractional digits (3) == 5
+ formatTester.format(df, "0.0E0", 0);
+ formatTester.format(df, "1.0E0", 1);
+ formatTester.format(df, "12E0", 12);
+ formatTester.format(df, "123E0", 123);
+ formatTester.format(df, "1.234E3", 1234);
+ formatTester.format(df, "12.345E3", 12345);
+ formatTester.format(df, "123.46E3", 123456);
+ formatTester.format(df, "1.2346E6", 1234567);
+ formatTester.format(df, "12.346E6", 12345678);
+ formatTester.format(df, "100E6", 99999999);
+
+ df = new DecimalFormat("#.0E0", dfs);
+ // ["#.0E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=1,
+ // maxFractionDigits=1,minIntegerDigits=0,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit count is set: The exponent must be a multiple of it (1).
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (0) + "max fractional digits (1) == 1
+ formatTester.format(df, "0.0E0", 0);
+ formatTester.format(df, "1.0E0", 1);
+ formatTester.format(df, "1.0E1", 12);
+ formatTester.format(df, "1.0E2", 123);
+ formatTester.format(df, "1.0E3", 1234);
+ formatTester.format(df, "1.0E4", 9999);
+
+ df = new DecimalFormat("0.#E0", dfs);
+ // ["0.#E0",isDecimalSeparatorAlwaysShown=false,groupingSize=0,multiplier=1,
+ // negativePrefix=-,negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=1,
+ // maxFractionDigits=1,minIntegerDigits=1,minFractionDigits=0,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (1) + "max fractional digits (1) == 2
+ formatTester.format(df, "0E0", 0);
+ formatTester.format(df, "1E0", 1);
+ formatTester.format(df, "1.2E1", 12);
+ formatTester.format(df, "1.2E2", 123);
+ formatTester.format(df, "1.2E3", 1234);
+ formatTester.format(df, "1E4", 9999);
+
+ df = new DecimalFormat(".0E0", dfs);
+ // [".0E0",isDecimalSeparatorAlwaysShown=true,groupingSize=0,multiplier=1,negativePrefix=-,
+ // negativeSuffix=,positivePrefix=,positiveSuffix=,maxIntegerDigits=0,maxFractionDigits=1,
+ // minIntegerDigits=0,minFractionDigits=1,grouping=false]
+ // Because maximum integer digit was not explicitly set: The exponent can be any integer.
+ // Scientific notation => use significant digit logic
+ // '@' not present: Significant digits: Min: 1,
+ // Max: "min integer digits" (0) + "max fractional digits (1) == 1
+ formatTester.format(df, ".0E0", 0);
+ formatTester.format(df, ".1E1", 1);
+ formatTester.format(df, ".1E2", 12);
+ formatTester.format(df, ".1E3", 123);
+ formatTester.format(df, ".1E4", 1234);
+ formatTester.format(df, ".1E5", 9999);
+
+ formatTester.throwFailures();
+ }
+
+ // Demonstrates that fraction digit rounding occurs as expected with 1, 10 and 14 fraction
+ // digits, using numbers that are well within the precision of IEEE 754.
+ public void test_formatDouble_maxFractionDigits() {
+ final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+ DecimalFormat format = new DecimalFormat("#0.#", dfs);
+ format.setGroupingUsed(false);
+ format.setMaximumIntegerDigits(400);
+ format.setMaximumFractionDigits(1);
+
+ assertEquals("1", format.format(0.99));
+ assertEquals("1", format.format(0.95));
+ assertEquals("0.9", format.format(0.94));
+ assertEquals("0.9", format.format(0.90));
+
+ assertEquals("0.2", format.format(0.19));
+ assertEquals("0.2", format.format(0.15));
+ assertEquals("0.1", format.format(0.14));
+ assertEquals("0.1", format.format(0.10));
+
+ format.setMaximumFractionDigits(10);
+ assertEquals("1", format.format(0.99999999999));
+ assertEquals("1", format.format(0.99999999995));
+ assertEquals("0.9999999999", format.format(0.99999999994));
+ assertEquals("0.9999999999", format.format(0.99999999990));
+
+ assertEquals("0.1111111112", format.format(0.11111111119));
+ assertEquals("0.1111111112", format.format(0.11111111115));
+ assertEquals("0.1111111111", format.format(0.11111111114));
+ assertEquals("0.1111111111", format.format(0.11111111110));
+
+ format.setMaximumFractionDigits(14);
+ assertEquals("1", format.format(0.999999999999999));
+ assertEquals("1", format.format(0.999999999999995));
+ assertEquals("0.99999999999999", format.format(0.999999999999994));
+ assertEquals("0.99999999999999", format.format(0.999999999999990));
+
+ assertEquals("0.11111111111112", format.format(0.111111111111119));
+ assertEquals("0.11111111111112", format.format(0.111111111111115));
+ assertEquals("0.11111111111111", format.format(0.111111111111114));
+ assertEquals("0.11111111111111", format.format(0.111111111111110));
+ }
+
+ // This demonstrates rounding at the 15th decimal digit. By setting the maximum fraction digits
+ // we force rounding at a point just below the full IEEE 754 precision. IEEE 754 should be
+ // precise to just above 15 decimal digits.
+ // df.format() with no limits always emits up to 16 decimal digits, slightly above what IEEE 754
+ // can store precisely.
+ public void test_formatDouble_roundingTo15Digits() throws Exception {
+ final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+ DecimalFormat df = new DecimalFormat("#.#", dfs);
+ df.setMaximumIntegerDigits(400);
+ df.setGroupingUsed(false);
+
+ df.setMaximumFractionDigits(0);
+ assertEquals("1000000000000000", df.format(999999999999999.9));
+ df.setMaximumFractionDigits(1);
+ assertEquals("100000000000000", df.format(99999999999999.99));
+ df.setMaximumFractionDigits(2);
+ assertEquals("10000000000000", df.format(9999999999999.999));
+ df.setMaximumFractionDigits(3);
+ assertEquals("1000000000000", df.format(999999999999.9999));
+ df.setMaximumFractionDigits(4);
+ assertEquals("100000000000", df.format(99999999999.99999));
+ df.setMaximumFractionDigits(5);
+ assertEquals("10000000000", df.format(9999999999.999999));
+ df.setMaximumFractionDigits(6);
+ assertEquals("1000000000", df.format(999999999.9999999));
+ df.setMaximumFractionDigits(7);
+ assertEquals("100000000", df.format(99999999.99999999));
+ df.setMaximumFractionDigits(8);
+ assertEquals("10000000", df.format(9999999.999999999));
+ df.setMaximumFractionDigits(9);
+ assertEquals("1000000", df.format(999999.9999999999));
+ df.setMaximumFractionDigits(10);
+ assertEquals("100000", df.format(99999.99999999999));
+ df.setMaximumFractionDigits(11);
+ assertEquals("10000", df.format(9999.999999999999));
+ df.setMaximumFractionDigits(12);
+ assertEquals("1000", df.format(999.9999999999999));
+ df.setMaximumFractionDigits(13);
+ assertEquals("100", df.format(99.99999999999999));
+ df.setMaximumFractionDigits(14);
+ assertEquals("10", df.format(9.999999999999999));
+ df.setMaximumFractionDigits(15);
+ assertEquals("1", df.format(0.9999999999999999));
+ }
+
+ // This checks formatting over most of the representable IEEE 754 range using a formatter that
+ // should be performing no lossy rounding.
+ // It checks that the formatted double can be parsed to get the original double.
+ // IEEE 754 can represent values from (decimal) ~2.22507E−308 to ~1.79769E308 to full precision.
+ // Close to zero it can go down to 4.94066E-324 with a loss of precision.
+ // At the extremes of the double range this test will not be testing doubles that exactly
+ // represent powers of 10. The test is only interested in whether the doubles closest
+ // to powers of 10 that can be represented can each be turned into a string and read back again
+ // to arrive at the original double.
+ public void test_formatDouble_wideRange() throws Exception {
+ for (int i = -324; i < 309; i++) {
+ // Generate a decimal number we are interested in: 1 * 10^i
+ String stringForm = "1e" + i;
+ BigDecimal bigDecimal = new BigDecimal(stringForm);
+
+ // Obtain the nearest double representation of the decimal number.
+ // This is lossy because going from BigDecimal -> double is inexact, but we should
+ // arrive at a number that is as close as possible to the decimal value. We assume that
+ // BigDecimal is capable of this, but it is not critical to this test if it gets it a
+ // little wrong, though it may mean we are testing a double value different from the one
+ // we thought we were.
+ double d = bigDecimal.doubleValue();
+
+ assertDecimalFormatIsLossless(d);
+ }
+ }
+
+ // This test is a regression test for http://b/17656132.
+ // It checks hand-picked values can be formatted and parsed to get the original double.
+ // The formatter as configured should perform no rounding.
+ public void test_formatDouble_roundingProblemCases() throws Exception {
+ // Most of the double literals below are not exactly representable in IEEE 754 but
+ // it should not matter to this test.
+ assertDecimalFormatIsLossless(999999999999999.9);
+ assertDecimalFormatIsLossless(99999999999999.99);
+ assertDecimalFormatIsLossless(9999999999999.999);
+ assertDecimalFormatIsLossless(999999999999.9999);
+ assertDecimalFormatIsLossless(99999999999.99999);
+ assertDecimalFormatIsLossless(9999999999.999999);
+ assertDecimalFormatIsLossless(999999999.9999999);
+ assertDecimalFormatIsLossless(99999999.99999999);
+ assertDecimalFormatIsLossless(9999999.999999999);
+ assertDecimalFormatIsLossless(999999.9999999999);
+ assertDecimalFormatIsLossless(99999.99999999999);
+ assertDecimalFormatIsLossless(9999.999999999999);
+ assertDecimalFormatIsLossless(999.9999999999999);
+ assertDecimalFormatIsLossless(99.99999999999999);
+ assertDecimalFormatIsLossless(9.999999999999999);
+ assertDecimalFormatIsLossless(0.9999999999999999);
+ }
+
+ // This test checks hand-picked values can be formatted and parsed to get the original double.
+ // The formatter as configured should perform no rounding.
+ // These numbers are not affected by http://b/17656132.
+ public void test_formatDouble_varyingScale() throws Exception {
+ // Most of the double literals below are not exactly representable in IEEE 754 but
+ // it should not matter to this test.
+
+ assertDecimalFormatIsLossless(999999999999999.);
+
+ assertDecimalFormatIsLossless(123456789012345.);
+ assertDecimalFormatIsLossless(12345678901234.5);
+ assertDecimalFormatIsLossless(1234567890123.25);
+ assertDecimalFormatIsLossless(999999999999.375);
+ assertDecimalFormatIsLossless(99999999999.0625);
+ assertDecimalFormatIsLossless(9999999999.03125);
+ assertDecimalFormatIsLossless(999999999.015625);
+ assertDecimalFormatIsLossless(99999999.0078125);
+ assertDecimalFormatIsLossless(9999999.00390625);
+ assertDecimalFormatIsLossless(999999.001953125);
+ assertDecimalFormatIsLossless(9999.00048828125);
+ assertDecimalFormatIsLossless(999.000244140625);
+ assertDecimalFormatIsLossless(99.0001220703125);
+ assertDecimalFormatIsLossless(9.00006103515625);
+ assertDecimalFormatIsLossless(0.000030517578125);
+ }
+
+ private static void assertDecimalFormatIsLossless(double d) throws Exception {
+ final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+ DecimalFormat format = new DecimalFormat("#0.#", dfs);
+ format.setGroupingUsed(false);
+ format.setMaximumIntegerDigits(400);
+ format.setMaximumFractionDigits(400);
+
+ // Every floating point binary can be represented exactly in decimal if you have enough
+ // digits. This shows the value actually being tested.
+ String testId = "decimalValue: " + new BigDecimal(d);
+
+ // As a sanity check we try out parseDouble() with the string generated by
+ // Double.toString(). Strictly speaking Double.toString() is probably not guaranteed to be
+ // lossless, but in reality it probably is, or at least is close enough.
+ assertDoubleEqual(
+ testId + " failed parseDouble(toString()) sanity check",
+ d, Double.parseDouble(Double.toString(d)));
+
+ // Format the number: If this is lossy it is a problem. We are trying to check that it
+ // doesn't lose any unnecessary precision.
+ String result = format.format(d);
+
+ // Here we use Double.parseDouble() which should able to parse a number we know was
+ // representable as a double into the original double. If parseDouble() is not implemented
+ // correctly the test is invalid.
+ double doubleParsed = Double.parseDouble(result);
+ assertDoubleEqual(testId + " (format() produced " + result + ")",
+ d, doubleParsed);
+
+ // For completeness we try to parse using the formatter too. If this fails but the format
+ // above didn't it may be a problem with parse(), or with format() that we didn't spot.
+ assertDoubleEqual(testId + " failed parse(format()) check",
+ d, format.parse(result).doubleValue());
+ }
+
+ private static void assertDoubleEqual(String message, double d, double doubleParsed) {
+ assertEquals(message,
+ createPrintableDouble(d),createPrintableDouble(doubleParsed));
+ }
+
+ private static String createPrintableDouble(double d) {
+ return Double.toString(d) + "(" + Long.toHexString(Double.doubleToRawLongBits(d)) + ")";
+ }
+
+ // Concise demonstration of http://b/17656132 using hard-coded expected values.
+ public void test_formatDouble_bug17656132() {
+ final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+ DecimalFormat df = new DecimalFormat("#0.#", dfs);
+ df.setGroupingUsed(false);
+ df.setMaximumIntegerDigits(400);
+ df.setMaximumFractionDigits(400);
+
+ // The expected values below come from the RI and are correct 16 decimal digit
+ // representations of the formatted value. Android does something different.
+ // The decimal value given in each comment is the actual double value as represented by
+ // IEEE 754. See new BigDecimal(double).
+
+ // double: 999999999999999.9 is decimal 999999999999999.875
+ assertEquals("999999999999999.9", df.format(999999999999999.9));
+ // double: 99999999999999.98 is decimal 99999999999999.984375
+ assertEquals("99999999999999.98", df.format(99999999999999.98));
+ // double 9999999999999.998 is decimal 9999999999999.998046875
+ assertEquals("9999999999999.998", df.format(9999999999999.998));
+ // double 999999999999.9999 is decimal 999999999999.9998779296875
+ assertEquals("999999999999.9999", df.format(999999999999.9999));
+ // double 99999999999.99998 is decimal 99999999999.9999847412109375
+ assertEquals("99999999999.99998", df.format(99999999999.99998));
+ // double 9999999999.999998 is decimal 9999999999.9999980926513671875
+ assertEquals("9999999999.999998", df.format(9999999999.999998));
+ // double 1E23 is decimal 99999999999999991611392
+ assertEquals("9999999999999999", df.format(1E23));
+ }
+
+ public void test_getDecimalFormatSymbols() {
+ DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
+ DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
+ assertNotSame(dfs, df.getDecimalFormatSymbols());
+ }
+
+ public void test_getCurrency() {
+ Currency currK = Currency.getInstance("KRW");
+ Currency currX = Currency.getInstance("XXX");
+ Currency currE = Currency.getInstance("EUR");
+
+ DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("ko", "KR"));
+ assertTrue("Test1: Returned incorrect currency", df.getCurrency() == currK);
+
+ df = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("", "KR"));
+ assertTrue("Test2: Returned incorrect currency", df.getCurrency() == currK);
+
+ df = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("ko", ""));
+ assertTrue("Test3: Returned incorrect currency", df.getCurrency() == currX);
+
+ df = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("fr", "FR"));
+ assertTrue("Test4: Returned incorrect currency", df.getCurrency() == currE);
+
+ // Regression for HARMONY-1351
+ df = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("QWERTY"));
+ assertTrue("Test5: Returned incorrect currency", df.getCurrency() == currX);
+
+ // JDK fails these tests since it doesn't have the PREEURO variant
+ // df = (DecimalFormat)NumberFormat.getCurrencyInstance(new Locale("fr",
+ // "FR","PREEURO"));
+ // assertTrue("Test5: Returned incorrect currency", df.getCurrency() ==
+ // currF);
+ }
+
+ public void test_getGroupingSize() {
+ DecimalFormat df = new DecimalFormat("###0.##");
+ assertEquals("Wrong unset size", 0, df.getGroupingSize());
+ df = new DecimalFormat("#,##0.##");
+ assertEquals("Wrong set size", 3, df.getGroupingSize());
+ df = new DecimalFormat("#,###,###0.##");
+ assertEquals("Wrong multiple set size", 4, df.getGroupingSize());
+ }
+
+ public void test_getMultiplier() {
+ final int defaultMultiplier = 1;
+ DecimalFormat form = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ assertEquals(defaultMultiplier, form.getMultiplier());
+
+ DecimalFormat df = new DecimalFormat("###0.##");
+ assertEquals("Wrong unset multiplier", 1, df.getMultiplier());
+ df = new DecimalFormat("###0.##%");
+ assertEquals("Wrong percent multiplier", 100, df.getMultiplier());
+ df = new DecimalFormat("###0.##\u2030");
+ assertEquals("Wrong mille multiplier", 1000, df.getMultiplier());
+ }
+
+ public void test_isDecimalSeparatorAlwaysShown() {
+ DecimalFormat df = new DecimalFormat("###0.##");
+ assertTrue("Wrong unset value", !df.isDecimalSeparatorAlwaysShown());
+ df = new DecimalFormat("###0.00");
+ assertTrue("Wrong unset2 value", !df.isDecimalSeparatorAlwaysShown());
+ df = new DecimalFormat("###0.");
+ assertTrue("Wrong set value", df.isDecimalSeparatorAlwaysShown());
+ }
+
+ public void test_parse_withParsePosition() {
+ DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH);
+ ParsePosition pos = new ParsePosition(0);
+ Number result = format.parse("9223372036854775807", pos);
+ assertTrue("Wrong result type for Long.MAX_VALUE", result.getClass() == Long.class);
+ assertTrue("Wrong result Long.MAX_VALUE", result.longValue() == Long.MAX_VALUE);
+ pos = new ParsePosition(0);
+ result = format.parse("-9223372036854775808", pos);
+ assertTrue("Wrong result type for Long.MIN_VALUE", result.getClass() == Long.class);
+ assertTrue("Wrong result Long.MIN_VALUE: " + result.longValue(),
+ result.longValue() == Long.MIN_VALUE);
+ pos = new ParsePosition(0);
+ result = format.parse("9223372036854775808", pos);
+ assertTrue("Wrong result type for Long.MAX_VALUE+1", result.getClass() == Double.class);
+ assertTrue("Wrong result Long.MAX_VALUE + 1",
+ result.doubleValue() == (double) Long.MAX_VALUE + 1);
+ pos = new ParsePosition(0);
+ result = format.parse("-9223372036854775809", pos);
+ assertTrue("Wrong result type for Long.MIN_VALUE+1", result.getClass() == Double.class);
+ assertTrue("Wrong result Long.MIN_VALUE - 1",
+ result.doubleValue() == (double) Long.MIN_VALUE - 1);
+
+ pos = new ParsePosition(0);
+ result = format.parse("18446744073709551629", pos);
+ assertTrue("Wrong result type for overflow", result.getClass() == Double.class);
+ assertTrue("Wrong result for overflow", result.doubleValue() == 18446744073709551629d);
+
+ pos = new ParsePosition(0);
+ result = format.parse("42325917317067571199", pos);
+ assertTrue("Wrong result type for overflow a: " + result,
+ result.getClass() == Double.class);
+ assertTrue("Wrong result for overflow a: " + result,
+ result.doubleValue() == 42325917317067571199d);
+ pos = new ParsePosition(0);
+ result = format.parse("4232591731706757119E1", pos);
+ assertTrue("Wrong result type for overflow b: " + result,
+ result.getClass() == Double.class);
+ assertTrue("Wrong result for overflow b: " + result,
+ result.doubleValue() == 42325917317067571190d);
+ pos = new ParsePosition(0);
+ result = format.parse(".42325917317067571199E20", pos);
+ assertTrue("Wrong result type for overflow c: " + result,
+ result.getClass() == Double.class);
+ assertTrue("Wrong result for overflow c: " + result,
+ result.doubleValue() == 42325917317067571199d);
+ pos = new ParsePosition(0);
+ result = format.parse("922337203685477580.9E1", pos);
+ assertTrue("Wrong result type for overflow d: " + result,
+ result.getClass() == Double.class);
+ assertTrue("Wrong result for overflow d: " + result,
+ result.doubleValue() == 9223372036854775809d);
+ pos = new ParsePosition(0);
+ result = format.parse("9.223372036854775809E18", pos);
+ assertTrue("Wrong result type for overflow e: " + result,
+ result.getClass() == Double.class);
+ assertTrue("Wrong result for overflow e: " + result,
+ result.doubleValue() == 9223372036854775809d);
+ }
+
+ public void test_parse_withMultiplier() {
+ DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH);
+ Number result;
+
+ format.setMultiplier(100);
+ result = format.parse("9223372036854775807", new ParsePosition(0));
+ assertEquals("Wrong result type multiplier 100: " + result, Double.class,
+ result.getClass());
+ assertEquals("Wrong result for multiplier 100: " + result,
+ 92233720368547758.07d, result.doubleValue());
+
+ format.setMultiplier(1000);
+ result = format.parse("9223372036854775807", new ParsePosition(0));
+ assertEquals("Wrong result type multiplier 1000: " + result, Double.class,
+ result.getClass());
+ assertEquals("Wrong result for multiplier 1000: " + result,
+ 9223372036854775.807d, result.doubleValue());
+
+ format.setMultiplier(10000);
+ result = format.parse("9223372036854775807", new ParsePosition(0));
+ assertEquals("Wrong result type multiplier 10000: " + result,
+ Double.class, result.getClass());
+ assertEquals("Wrong result for multiplier 10000: " + result,
+ 922337203685477.5807d, result.doubleValue());
+ }
+
+ public void test_setDecimalFormatSymbols() {
+ DecimalFormat df = new DecimalFormat("###0.##");
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols();
+ dfs.setDecimalSeparator('@');
+ df.setDecimalFormatSymbols(dfs);
+ assertTrue("Not set", df.getDecimalFormatSymbols().equals(dfs));
+ assertEquals("Symbols not used", "1@2", df.format(1.2));
+
+ // The returned symbols may be cloned in two spots
+ // 1. When set
+ // 2. When returned
+ DecimalFormat format = new DecimalFormat();
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+ format.setDecimalFormatSymbols(symbols);
+ DecimalFormatSymbols symbolsOut = format.getDecimalFormatSymbols();
+ assertNotSame(symbols, symbolsOut);
+ }
+
+ public void test_setDecimalSeparatorAlwaysShown() {
+ DecimalFormat df = new DecimalFormat("###0.##", new DecimalFormatSymbols(Locale.US));
+ assertEquals("Wrong default result", "5", df.format(5));
+ df.setDecimalSeparatorAlwaysShown(true);
+ assertTrue("Not set", df.isDecimalSeparatorAlwaysShown());
+ assertEquals("Wrong set result", "7.", df.format(7));
+ }
+
+ public void test_setCurrency() {
+ Locale locale = Locale.CANADA;
+ DecimalFormat df = ((DecimalFormat) NumberFormat.getCurrencyInstance(locale));
+
+ try {
+ df.setCurrency(null);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ }
+
+ Currency currency = Currency.getInstance("AED");
+ df.setCurrency(currency);
+ assertTrue("Returned incorrect currency", currency == df.getCurrency());
+ assertEquals("Returned incorrect currency symbol", currency.getSymbol(locale),
+ df.getDecimalFormatSymbols().getCurrencySymbol());
+ assertEquals("Returned incorrect international currency symbol", currency.getCurrencyCode(),
+ df.getDecimalFormatSymbols().getInternationalCurrencySymbol());
+ }
+
+ public void test_setGroupingSize() {
+ DecimalFormat df = new DecimalFormat("###0.##", new DecimalFormatSymbols(Locale.ENGLISH));
+ df.setGroupingUsed(true);
+ df.setGroupingSize(2);
+ assertEquals("Value not set", 2, df.getGroupingSize());
+ String result = df.format(123);
+ assertTrue("Invalid format:" + result, result.equals("1,23"));
+ }
+
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(new DecimalFormat());
+ }
+
+ public void testSerializationHarmonyRICompatible() throws Exception {
+ NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
+
+ DecimalFormat df = null;
+ if (!(nf instanceof DecimalFormat)) {
+ throw new Error("This NumberFormat is not a DecimalFormat");
+
+ }
+ df = (DecimalFormat) nf;
+
+ ObjectInputStream oinput = null;
+
+ DecimalFormat deserializedDF = null;
+
+ try {
+ oinput = new ObjectInputStream(getClass().getResource(
+ "/serialization/org/apache/harmony/tests/java/text/DecimalFormat.ser")
+ .openStream());
+ deserializedDF = (DecimalFormat) oinput.readObject();
+ } finally {
+ try {
+ if (null != oinput) {
+ oinput.close();
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ assertEquals(df.getNegativePrefix(), deserializedDF.getNegativePrefix());
+ assertEquals(df.getNegativeSuffix(), deserializedDF.getNegativeSuffix());
+ assertEquals(df.getPositivePrefix(), deserializedDF.getPositivePrefix());
+ assertEquals(df.getPositiveSuffix(), deserializedDF.getPositiveSuffix());
+ assertEquals(df.getCurrency(), deserializedDF.getCurrency());
+
+ DecimalFormatSymbolsTest.assertDecimalFormatSymbolsRIFrance(
+ deserializedDF.getDecimalFormatSymbols());
+
+ assertEquals(df.getGroupingSize(), df.getGroupingSize());
+ assertEquals(df.getMaximumFractionDigits(), deserializedDF
+ .getMaximumFractionDigits());
+
+ assertEquals(df.getMaximumIntegerDigits(), deserializedDF
+ .getMaximumIntegerDigits());
+
+ assertEquals(df.getMinimumFractionDigits(), deserializedDF
+ .getMinimumFractionDigits());
+ assertEquals(df.getMinimumIntegerDigits(), deserializedDF
+ .getMinimumIntegerDigits());
+ assertEquals(df.getMultiplier(), deserializedDF.getMultiplier());
+
+ // Deliberately omitted this assertion. Since different data resource
+ // will cause the assertion fail.
+ // assertEquals(df, deserializedDF);
+
+ }
+
+ public void test_parse_infinityBigDecimalFalse() {
+ // Regression test for HARMONY-106
+ DecimalFormat format = (DecimalFormat) NumberFormat.getInstance();
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+ Number number = format.parse(symbols.getInfinity(),
+ new ParsePosition(0));
+ assertTrue(number instanceof Double);
+ assertTrue(Double.isInfinite(number.doubleValue()));
+ }
+
+ public void test_parse_minusInfinityBigDecimalFalse() {
+ // Regression test for HARMONY-106
+ DecimalFormat format = (DecimalFormat) NumberFormat.getInstance();
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+ Number number = format.parse("-" + symbols.getInfinity(),
+ new ParsePosition(0));
+ assertTrue(number instanceof Double);
+ assertTrue(Double.isInfinite(number.doubleValue()));
+ }
+
+ public void test_setDecimalFormatSymbolsAsNull() {
+ // Regression for HARMONY-1070
+ DecimalFormat format = (DecimalFormat) NumberFormat.getInstance();
+ format.setDecimalFormatSymbols(null);
+ }
+
+ public void test_formatToCharacterIterator_null() {
+ try {
+ // Regression for HARMONY-466
+ new DecimalFormat().formatToCharacterIterator(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void test_formatToCharacterIterator_original() {
+ new Support_DecimalFormat(
+ "test_formatToCharacterIteratorLjava_lang_Object")
+ .t_formatToCharacterIterator();
+ }
+
+ public void test_formatToCharacterIterator() throws Exception {
+ AttributedCharacterIterator iterator;
+ int[] runStarts;
+ int[] runLimits;
+ String result;
+ char current;
+
+ // BigInteger.
+ iterator = new DecimalFormat().formatToCharacterIterator(new BigInteger("123456789"));
+ runStarts = new int[] { 0, 0, 0, 3, 4, 4, 4, 7, 8, 8, 8 };
+ runLimits = new int[] { 3, 3, 3, 4, 7, 7, 7, 8, 11, 11, 11 };
+ result = "123,456,789";
+ current = iterator.current();
+ for (int i = 0; i < runStarts.length; i++) {
+ assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
+ assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+ assertEquals(0, iterator.getBeginIndex());
+ assertEquals(11, iterator.getEndIndex());
+
+ // For BigDecimal with multiplier test.
+ DecimalFormat df = new DecimalFormat();
+ df.setMultiplier(10);
+ iterator = df.formatToCharacterIterator(new BigDecimal("12345678901234567890"));
+ result = "123,456,789,012,345,678,900";
+ current = iterator.current();
+ for (int i = 0; i < result.length(); i++) {
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+
+ // For BigDecimal with multiplier test.
+ df = new DecimalFormat();
+ df.setMultiplier(-1);
+ df.setMaximumFractionDigits(20);
+ iterator = df.formatToCharacterIterator(new BigDecimal("1.23456789012345678901"));
+ result = "-1.23456789012345678901";
+ current = iterator.current();
+ for (int i = 0; i < result.length(); i++) {
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+
+ iterator = new DecimalFormat().formatToCharacterIterator(new BigDecimal("1.23456789E301"));
+ runStarts = new int[] { 0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14 };
+ runLimits = new int[] { 2, 2, 3, 6, 6, 6, 7, 10, 10, 10, 11, 14, 14, 14, 15 };
+ result = "12,345,678,900,"; // 000,000,000,000....
+ current = iterator.current();
+ for (int i = 0; i < runStarts.length; i++) {
+ assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
+ assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+ assertEquals(0, iterator.getBeginIndex());
+ assertEquals(402, iterator.getEndIndex());
+
+ iterator = new DecimalFormat().formatToCharacterIterator(new BigDecimal("1.2345678E4"));
+ runStarts = new int[] { 0, 0, 2, 3, 3, 3, 6, 7, 7, 7 };
+ runLimits = new int[] { 2, 2, 3, 6, 6, 6, 7, 10, 10, 10 };
+ result = "12,345.678";
+ current = iterator.current();
+ for (int i = 0; i < runStarts.length; i++) {
+ assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
+ assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+ assertEquals(0, iterator.getBeginIndex());
+ assertEquals(10, iterator.getEndIndex());
+ }
+
+ public void test_formatToCharacterIterator_veryLarge() throws Exception {
+ AttributedCharacterIterator iterator;
+ int[] runStarts;
+ int[] runLimits;
+ String result;
+ char current;
+
+ Number number = new BigDecimal("1.23456789E1234");
+ assertEquals("1.23456789E+1234", number.toString());
+ iterator = new DecimalFormat().formatToCharacterIterator(number);
+ runStarts = new int[] { 0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14 };
+ runLimits = new int[] { 2, 2, 3, 6, 6, 6, 7, 10, 10, 10, 11, 14, 14, 14, 15 };
+ result = "12,345,678,900,"; // 000,000,000,000....
+ current = iterator.current();
+ for (int i = 0; i < runStarts.length; i++) {
+ assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
+ assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+ assertEquals(0, iterator.getBeginIndex());
+ assertEquals(1646, iterator.getEndIndex());
+ }
+
+ public void test_formatToCharacterIterator_roundingUnnecessaryArithmeticException() {
+ DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+ decimalFormat.setMaximumFractionDigits(0);
+ try {
+ // when rounding is needed, but RoundingMode is set to RoundingMode.UNNECESSARY,
+ // throw ArithmeticException
+ decimalFormat.formatToCharacterIterator(new Double(1.5));
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ // expected
+ }
+ }
+
+ public void test_formatDouble_roundingUnnecessaryArithmeticException() {
+ DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+ decimalFormat.setMaximumFractionDigits(0);
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+
+ try {
+ // when rounding is needed, but RoundingMode is set to RoundingMode.UNNECESSARY,
+ // throw ArithmeticException
+ decimalFormat.format(11.5, new StringBuffer(), new FieldPosition(0));
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ // expected
+ }
+ }
+
+ public void test_format_roundingUnnecessaryArithmeticException() {
+ final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+ DecimalFormat decimalFormat = new DecimalFormat("00.0#E0", dfs);
+
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+ try {
+ // when rounding is needed, but RoundingMode is set to RoundingMode.UNNECESSARY,
+ // throw ArithmeticException
+ decimalFormat.format(99999, new StringBuffer(), new FieldPosition(0));
+ fail("ArithmeticException expected");
+ } catch (ArithmeticException e) {
+ // expected
+ }
+ }
+
+ public void test_getRoundingMode() {
+ // get the default RoundingMode of this DecimalFormat
+ DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+
+ // the default RoundingMode is HALF_EVEN
+ assertEquals("Incorrect default RoundingMode",
+ decimalFormat.getRoundingMode(), RoundingMode.HALF_EVEN);
+
+ // set RoundingMode.HALF_DOWN of this DecimalFormat
+ decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+ assertEquals("Returned incorrect RoundingMode",
+ decimalFormat.getRoundingMode(), RoundingMode.HALF_DOWN);
+
+ }
+
+ public void test_setRoundingMode_null() {
+ DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+ try {
+ // when the given RoundingMode is null, throw NullPointerException
+ decimalFormat.setRoundingMode(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void test_format_withRoundingMode() {
+ DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+ // ignore the fraction part of a given value
+ decimalFormat.setMaximumFractionDigits(0);
+
+ // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+ String result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+
+ result = decimalFormat.format(11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+
+ result = decimalFormat.format(11.6);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "12", result);
+
+ // set RoundingMode.CEILING of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.CEILING);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "12", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11", result);
+
+ // set RoundingMode.DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.DOWN);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+
+ // set RoundingMode.FLOOR of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-12", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+
+ // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "0", result);
+
+ // set RoundingMode.HALF_UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "0", result);
+
+ result = decimalFormat.format(-0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-0", result);
+
+ // set RoundingMode.UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UP);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "1", result);
+
+ result = decimalFormat.format(-0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-1", result);
+
+ // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+
+ try {
+ // when rounding is needed but RoundingMode is set to RoundingMode.UNNECESSARY,
+ // throw ArithmeticException
+ result = decimalFormat.format(5.5);
+ fail("ArithmeticException expected: RoundingMode.UNNECESSARY");
+ } catch (ArithmeticException e) {
+ // expected
+ }
+
+ result = decimalFormat.format(1.0);
+ assertEquals(
+ "Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "1", result);
+
+ result = decimalFormat.format(-1.0);
+ assertEquals(
+ "Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-1", result);
+
+ // set MaxFractionDigits to 3, test different DecimalFormat format
+ // function with differnt RoundingMode
+ decimalFormat.setMaximumFractionDigits(3);
+
+ // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.565", result);
+
+ result = decimalFormat.format(11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.565", result);
+
+ result = decimalFormat.format(11.5656);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.566", result);
+
+ // set RoundingMode.CEILING of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.CEILING);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "11.566", result);
+
+ result = decimalFormat.format(-11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11.565", result);
+
+ // set RoundingMode.DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.DOWN);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11.565", result);
+
+ result = decimalFormat.format(-11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11.565", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+
+ // set RoundingMode.FLOOR of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11.565", result);
+
+ result = decimalFormat.format(-11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-11.566", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+
+ // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "11.565", result);
+
+ result = decimalFormat.format(-11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-11.566", result);
+
+ result = decimalFormat.format(11.5656);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "11.566", result);
+
+ // set RoundingMode.HALF_UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "11.565", result);
+
+ result = decimalFormat.format(-11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-11.566", result);
+
+ result = decimalFormat.format(11.5656);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "11.566", result);
+
+ // set RoundingMode.UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UP);
+ result = decimalFormat.format(11.5653);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "11.566", result);
+
+ result = decimalFormat.format(-11.5655);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-11.566", result);
+
+ // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+ result = decimalFormat.format(-11.565);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY",
+ "-11.565", result);
+
+ result = decimalFormat.format(11.565);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY",
+ "11.565", result);
+
+ // when setting MaxFractionDigits to negative value -2, default it as
+ // zero, test different DecimalFormat format
+ // function with differnt RoundingMode
+ decimalFormat.setMaximumFractionDigits(-2);
+
+ // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+
+ result = decimalFormat.format(11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+
+ result = decimalFormat.format(11.6);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "12", result);
+
+ // set RoundingMode.CEILING of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.CEILING);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "12", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11", result);
+
+ // set RoundingMode.DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.DOWN);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+
+ // set RoundingMode.FLOOR of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+ result = decimalFormat.format(11.3);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11", result);
+
+ result = decimalFormat.format(-11.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-12", result);
+
+ result = decimalFormat.format(0);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+
+ // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "0", result);
+
+ // set RoundingMode.HALF_UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "0", result);
+
+ result = decimalFormat.format(-0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-0", result);
+
+ // set RoundingMode.UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UP);
+ result = decimalFormat.format(5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "6", result);
+
+ result = decimalFormat.format(-5.5);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-6", result);
+
+ result = decimalFormat.format(0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "1", result);
+
+ result = decimalFormat.format(-0.2);
+ assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-1", result);
+
+ // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+
+ result = decimalFormat.format(1.0);
+ assertEquals(
+ "Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "1", result);
+
+ result = decimalFormat.format(-1.0);
+ assertEquals(
+ "Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-1", result);
+
+ // Regression for HARMONY-6485
+ // Test with applyPattern call after setRoundingMode
+
+ // set RoundingMode.HALF_UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+ decimalFormat.applyPattern(".##");
+ result = decimalFormat.format(0.125);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".13", result);
+ result = decimalFormat.format(0.255);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".26", result);
+ result = decimalFormat.format(0.732);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".73", result);
+ result = decimalFormat.format(0.467);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".47", result);
+
+ // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+ decimalFormat.applyPattern(".##");
+ result = decimalFormat.format(0.125);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".12", result);
+ result = decimalFormat.format(0.255);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".25", result);
+ result = decimalFormat.format(0.732);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".73", result);
+ result = decimalFormat.format(0.467);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".47", result);
+
+ // set RoundingMode.UP of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.UP);
+ decimalFormat.applyPattern(".##");
+ result = decimalFormat.format(0.125);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".13", result);
+ result = decimalFormat.format(0.255);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".26", result);
+ result = decimalFormat.format(0.732);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".74", result);
+ result = decimalFormat.format(0.467);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".47", result);
+
+ // set RoundingMode.DOWN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.DOWN);
+ decimalFormat.applyPattern(".##");
+ result = decimalFormat.format(0.125);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".12", result);
+ result = decimalFormat.format(0.255);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".25", result);
+ result = decimalFormat.format(0.732);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".73", result);
+ result = decimalFormat.format(0.467);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".46", result);
+
+ // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+ // behavior
+ decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+ decimalFormat.applyPattern(".##");
+ result = decimalFormat.format(0.125);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".12", result);
+ result = decimalFormat.format(0.255);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".26", result);
+ result = decimalFormat.format(0.732);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".73", result);
+ result = decimalFormat.format(0.467);
+ assertEquals("Incorrect RoundingMode behavior after applyPattern", ".47", result);
+ }
+
+ private static class FormatTester {
+ private List<AssertionFailedError> failures = new ArrayList<AssertionFailedError>();
+
+ public void format(DecimalFormat format, String expected, double value) {
+ try {
+ Assert.assertEquals(format.toPattern() + ": " + value, expected,
+ format.format(value));
+ } catch (AssertionFailedError e) {
+ failures.add(e);
+ }
+ }
+
+ public void format(DecimalFormat format, String expected, int value) {
+ try {
+ Assert.assertEquals(format.toPattern() + ": " + value, expected,
+ format.format(value));
+ } catch (AssertionFailedError e) {
+ failures.add(e);
+ }
+ }
+
+ public void throwFailures() throws AssertionFailedError {
+ if (failures.isEmpty()) {
+ return;
+ }
+ if (failures.size() == 1) {
+ throw failures.get(0);
+ }
+ AssertionFailedError combined = new AssertionFailedError("Multiple format failures");
+ for (AssertionFailedError failure : failures) {
+ combined.addSuppressed(failure);
+ }
+ throw combined;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/FieldPositionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/FieldPositionTest.java
new file mode 100644
index 0000000..8fdc334
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/FieldPositionTest.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+
+public class FieldPositionTest extends junit.framework.TestCase {
+
+ /**
+ * @tests java.text.FieldPosition#FieldPosition(int)
+ */
+ public void test_ConstructorI() {
+ // Test for constructor java.text.FieldPosition(int)
+ FieldPosition fpos = new FieldPosition(DateFormat.MONTH_FIELD);
+ assertEquals("Test1: Constructor failed to set field identifier!",
+ DateFormat.MONTH_FIELD, fpos.getField());
+ assertNull("Constructor failed to set field attribute!", fpos
+ .getFieldAttribute());
+ }
+
+ /**
+ * @tests java.text.FieldPosition#FieldPosition(java.text.Format$Field)
+ */
+ public void test_ConstructorLjava_text_Format$Field() {
+ // Test for constructor java.text.FieldPosition(Format.Field)
+ FieldPosition fpos = new FieldPosition(DateFormat.Field.MONTH);
+ assertSame("Constructor failed to set field attribute!",
+ DateFormat.Field.MONTH, fpos.getFieldAttribute());
+ assertEquals("Test1: Constructor failed to set field identifier!", -1,
+ fpos.getField());
+ }
+
+ /**
+ * @tests java.text.FieldPosition#FieldPosition(java.text.Format$Field, int)
+ */
+ public void test_ConstructorLjava_text_Format$FieldI() {
+ // Test for constructor java.text.FieldPosition(Format.Field, int)
+ FieldPosition fpos = new FieldPosition(DateFormat.Field.MONTH,
+ DateFormat.MONTH_FIELD);
+ assertSame("Constructor failed to set field attribute!",
+ DateFormat.Field.MONTH, fpos.getFieldAttribute());
+ assertEquals("Test1: Constructor failed to set field identifier!",
+ DateFormat.MONTH_FIELD, fpos.getField());
+
+ // test special cases
+ FieldPosition fpos2 = new FieldPosition(DateFormat.Field.HOUR1,
+ DateFormat.HOUR1_FIELD);
+ assertSame("Constructor failed to set field attribute!",
+ DateFormat.Field.HOUR1, fpos2.getFieldAttribute());
+ assertEquals("Test2: Constructor failed to set field identifier!",
+ DateFormat.HOUR1_FIELD, fpos2.getField());
+
+ FieldPosition fpos3 = new FieldPosition(DateFormat.Field.TIME_ZONE,
+ DateFormat.MONTH_FIELD);
+ assertSame("Constructor failed to set field attribute!",
+ DateFormat.Field.TIME_ZONE, fpos3.getFieldAttribute());
+ assertEquals("Test3: Constructor failed to set field identifier!",
+ DateFormat.MONTH_FIELD, fpos3.getField());
+ }
+
+ /**
+ * @tests java.text.FieldPosition#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.text.FieldPosition.equals(java.lang.Object)
+ FieldPosition fpos = new FieldPosition(1);
+ FieldPosition fpos1 = new FieldPosition(1);
+ assertTrue("Identical objects were not equal!", fpos.equals(fpos1));
+
+ FieldPosition fpos2 = new FieldPosition(2);
+ assertTrue("Objects with a different ID should not be equal!", !fpos
+ .equals(fpos2));
+
+ fpos.setBeginIndex(1);
+ fpos1.setBeginIndex(2);
+ assertTrue("Objects with a different beginIndex were still equal!",
+ !fpos.equals(fpos1));
+ fpos1.setBeginIndex(1);
+ fpos1.setEndIndex(2);
+ assertTrue("Objects with a different endIndex were still equal!", !fpos
+ .equals(fpos1));
+
+ FieldPosition fpos3 = new FieldPosition(DateFormat.Field.ERA, 1);
+ assertTrue("Objects with a different attribute should not be equal!",
+ !fpos.equals(fpos3));
+ FieldPosition fpos4 = new FieldPosition(DateFormat.Field.AM_PM, 1);
+ assertTrue("Objects with a different attribute should not be equal!",
+ !fpos3.equals(fpos4));
+ }
+
+ /**
+ * @tests java.text.FieldPosition#getBeginIndex()
+ */
+ public void test_getBeginIndex() {
+ // Test for method int java.text.FieldPosition.getBeginIndex()
+ FieldPosition fpos = new FieldPosition(1);
+ fpos.setEndIndex(3);
+ fpos.setBeginIndex(2);
+ assertEquals("getBeginIndex should have returned 2",
+ 2, fpos.getBeginIndex());
+ }
+
+ /**
+ * @tests java.text.FieldPosition#getEndIndex()
+ */
+ public void test_getEndIndex() {
+ // Test for method int java.text.FieldPosition.getEndIndex()
+ FieldPosition fpos = new FieldPosition(1);
+ fpos.setBeginIndex(2);
+ fpos.setEndIndex(3);
+ assertEquals("getEndIndex should have returned 3",
+ 3, fpos.getEndIndex());
+ }
+
+ /**
+ * @tests java.text.FieldPosition#getField()
+ */
+ public void test_getField() {
+ // Test for method int java.text.FieldPosition.getField()
+ FieldPosition fpos = new FieldPosition(65);
+ assertEquals("FieldPosition(65) should have caused getField to return 65",
+ 65, fpos.getField());
+ FieldPosition fpos2 = new FieldPosition(DateFormat.Field.MINUTE);
+ assertEquals("FieldPosition(DateFormat.Field.MINUTE) should have caused getField to return -1",
+ -1, fpos2.getField());
+ }
+
+ /**
+ * @tests java.text.FieldPosition#getFieldAttribute()
+ */
+ public void test_getFieldAttribute() {
+ // Test for method int java.text.FieldPosition.getFieldAttribute()
+ FieldPosition fpos = new FieldPosition(DateFormat.Field.TIME_ZONE);
+ assertTrue(
+ "FieldPosition(DateFormat.Field.TIME_ZONE) should have caused getFieldAttribute to return DateFormat.Field.TIME_ZONE",
+ fpos.getFieldAttribute() == DateFormat.Field.TIME_ZONE);
+
+ FieldPosition fpos2 = new FieldPosition(DateFormat.TIMEZONE_FIELD);
+ assertNull(
+ "FieldPosition(DateFormat.TIMEZONE_FIELD) should have caused getFieldAttribute to return null",
+ fpos2.getFieldAttribute());
+ }
+
+ public void test_hashCode() {
+ // Test for method int java.text.FieldPosition.hashCode()
+ FieldPosition fpos1 = new FieldPosition(1);
+ FieldPosition fpos2 = new FieldPosition(1);
+ assertTrue("test 1: hash codes are not equal for equal objects.",
+ fpos1.hashCode() == fpos2.hashCode());
+ fpos1.setBeginIndex(5);
+ fpos1.setEndIndex(110);
+ assertTrue("test 2: hash codes are equal for non equal objects.",
+ fpos1.hashCode() != fpos2.hashCode());
+ fpos2.setBeginIndex(5);
+ fpos2.setEndIndex(110);
+ assertTrue("test 3: hash codes are not equal for equal objects.",
+ fpos1.hashCode() == fpos2.hashCode());
+
+ FieldPosition fpos3 = new FieldPosition(
+ DateFormat.Field.DAY_OF_WEEK_IN_MONTH);
+
+ assertTrue("test 4: hash codes are equal for non equal objects.",
+ fpos2.hashCode() != fpos3.hashCode());
+ }
+
+ public void test_setBeginIndexI() {
+ FieldPosition fpos = new FieldPosition(1);
+ fpos.setBeginIndex(2);
+ fpos.setEndIndex(3);
+ assertEquals("beginIndex should have been set to 2", 2, fpos
+ .getBeginIndex());
+
+ fpos.setBeginIndex(Integer.MAX_VALUE);
+ assertEquals("beginIndex should have been set to Integer.MAX_VALUE",
+ Integer.MAX_VALUE, fpos.getBeginIndex());
+
+ fpos.setBeginIndex(-1);
+ assertEquals("beginIndex should have been set to -1",
+ -1, fpos.getBeginIndex());
+ }
+
+ public void test_setEndIndexI() {
+ FieldPosition fpos = new FieldPosition(1);
+ fpos.setEndIndex(3);
+ fpos.setBeginIndex(2);
+ assertEquals("EndIndex should have been set to 3", 3, fpos
+ .getEndIndex());
+
+ fpos.setEndIndex(Integer.MAX_VALUE);
+ assertEquals("endIndex should have been set to Integer.MAX_VALUE",
+ Integer.MAX_VALUE, fpos.getEndIndex());
+
+ fpos.setEndIndex(-1);
+ assertEquals("endIndex should have been set to -1",
+ -1, fpos.getEndIndex());
+ }
+
+ /**
+ * @tests java.text.FieldPosition#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.text.FieldPosition.toString()
+ FieldPosition fpos = new FieldPosition(1);
+ fpos.setBeginIndex(2);
+ fpos.setEndIndex(3);
+ assertEquals(
+ "ToString returned the wrong value:",
+ "java.text.FieldPosition[attribute=null,field=1,beginIndex=2,endIndex=3]",
+ fpos.toString());
+
+ FieldPosition fpos2 = new FieldPosition(DateFormat.Field.ERA);
+ fpos2.setBeginIndex(4);
+ fpos2.setEndIndex(5);
+ assertEquals("ToString returned the wrong value:",
+ "java.text.FieldPosition[attribute=" + DateFormat.Field.ERA
+ + ",field=-1,beginIndex=4,endIndex=5]", fpos2
+ .toString());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/LoadLocaleProviderTestHelper.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/LoadLocaleProviderTestHelper.java
new file mode 100644
index 0000000..b898061
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/LoadLocaleProviderTestHelper.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public abstract class LoadLocaleProviderTestHelper implements Runnable {
+ private Throwable throwable;
+
+ public LoadLocaleProviderTestHelper(URL[] classpathes)
+ throws InterruptedException {
+ URLClassLoader loader = new URLClassLoader(classpathes);
+ Thread thread = new Thread(this);
+ thread.setContextClassLoader(loader);
+ thread.start();
+ thread.join();
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ public void run() {
+ try {
+ test();
+ } catch (Throwable t) {
+ throwable = t;
+ }
+ }
+
+ public abstract void test();
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/MessageFormatFieldTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/MessageFormatFieldTest.java
new file mode 100644
index 0000000..91eb9e3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/MessageFormatFieldTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+public class MessageFormatFieldTest extends junit.framework.TestCase {
+ /**
+ * @tests java.text.MessageFormat$Field#Field(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // protected constructor
+ }
+
+ /**
+ * @tests java.text.MessageFormat$Field#readResolve()
+ */
+ public void test_readResolve() {
+ // test for method java.lang.Object readResolve()
+
+ // see serialization stress tests:
+ // implemented in
+ // SerializationStressTest4.test_writeObject_MessageFormat_Field()
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+
+ protected void doneSuite() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/MessageFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/MessageFormatTest.java
new file mode 100644
index 0000000..171f247
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/MessageFormatTest.java
@@ -0,0 +1,953 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.text.ChoiceFormat;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.MessageFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import junit.framework.TestCase;
+
+public class MessageFormatTest extends TestCase {
+
+ private MessageFormat format1, format2, format3;
+
+ private Locale defaultLocale;
+
+ private void checkSerialization(MessageFormat format) {
+ try {
+ ByteArrayOutputStream ba = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(ba);
+ out.writeObject(format);
+ out.close();
+ ObjectInputStream in = new ObjectInputStream(
+ new ByteArrayInputStream(ba.toByteArray()));
+ MessageFormat read = (MessageFormat) in.readObject();
+ assertTrue("Not equal: " + format.toPattern(), format.equals(read));
+ } catch (IOException e) {
+ fail("Format: " + format.toPattern()
+ + " caused IOException: " + e);
+ } catch (ClassNotFoundException e) {
+ fail("Format: " + format.toPattern()
+ + " caused ClassNotFoundException: " + e);
+ }
+ }
+
+ public void test_formatToCharacterIteratorLjava_lang_Object() {
+ new Support_MessageFormat("test_formatToCharacterIteratorLjava_lang_Object").t_formatToCharacterIterator();
+
+ try {
+ new MessageFormat("{1, number}").formatToCharacterIterator(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ new MessageFormat("{0, time}").formatToCharacterIterator(new Object[]{""});
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+
+ public void test_getLocale() throws Exception {
+ Locale[] l = {
+ Locale.FRANCE,
+ Locale.KOREA,
+ new Locale("FR", "fr"), // Deliberately backwards.
+ new Locale("mk"),
+ new Locale("mk", "MK"),
+ Locale.US,
+ new Locale("#ru", "@31230") // Deliberately nonsense.
+ };
+
+ String pattern = "getLocale test {0,number,#,####}";
+
+ for (int i = 0; i < 0; i++) {
+ MessageFormat mf = new MessageFormat(pattern, l[i]);
+ Locale result = mf.getLocale();
+ assertEquals(l[i], result);
+ assertEquals(l[i].getLanguage(), result.getLanguage());
+ assertEquals(l[i].getCountry(), result.getCountry());
+ }
+
+ MessageFormat mf = new MessageFormat(pattern);
+ mf.setLocale(null);
+ Locale result = mf.getLocale();
+ assertEquals(null, result);
+ }
+
+ public void test_setFormatILjava_text_Format() throws Exception {
+ // case 1: Compare getFormats() results after calls to setFormat()
+ MessageFormat f1 = (MessageFormat) format1.clone();
+ f1.setFormat(0, DateFormat.getTimeInstance());
+ f1.setFormat(1, DateFormat.getTimeInstance());
+ f1.setFormat(2, NumberFormat.getInstance());
+ f1.setFormat(3, new ChoiceFormat("0#off|1#on"));
+ f1.setFormat(4, new ChoiceFormat("1#few|2#ok|3#a lot"));
+ f1.setFormat(5, DateFormat.getTimeInstance());
+
+ Format[] formats = f1.getFormats();
+ formats = f1.getFormats();
+
+ Format[] correctFormats = new Format[] {
+ DateFormat.getTimeInstance(),
+ DateFormat.getTimeInstance(),
+ NumberFormat.getInstance(),
+ new ChoiceFormat("0#off|1#on"),
+ new ChoiceFormat("1#few|2#ok|3#a lot"),
+ DateFormat.getTimeInstance()
+ };
+
+ assertEquals(correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test1B:wrong format for pattern index " + i + ":", correctFormats[i], formats[i]);
+ }
+
+ // case 2: Try to setFormat using incorrect index
+ try {
+ f1.setFormat(-1, DateFormat.getDateInstance());
+ fail();
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ try {
+ f1.setFormat(f1.getFormats().length, DateFormat.getDateInstance());
+ fail();
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_parseObjectLjava_lang_StringLjavajava_text_ParsePosition() throws Exception {
+ MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
+ // case 1: Try to parse correct data string.
+ Object[] objs = { new Double(3.1415) };
+ String result = mf.format(objs);
+ // result now equals "3.14, 3.1"
+ Object[] res = null;
+ ParsePosition pp = new ParsePosition(0);
+ int parseIndex = pp.getIndex();
+ res = (Object[]) mf.parseObject(result, pp);
+ assertTrue("Parse operation return null", res != null);
+ assertTrue("parse operation return array with incorrect length", 1 == res.length);
+ assertTrue("ParseIndex is incorrect", pp.getIndex() != parseIndex);
+ assertTrue("Result object is incorrect", new Double(3.1).equals(res[0]));
+
+ // case 2: Try to parse partially correct data string.
+ pp.setIndex(0);
+ char[] cur = result.toCharArray();
+ cur[cur.length / 2] = 'Z';
+ String partialCorrect = new String(cur);
+ res = (Object[]) mf.parseObject(partialCorrect, pp);
+ assertTrue("Parse operation return null", res == null);
+ assertTrue("ParseIndex is incorrect", pp.getIndex() == 0);
+ assertTrue("ParseErrorIndex is incorrect", pp.getErrorIndex() == cur.length / 2);
+
+ // case 3: Try to use argument ParsePosition as null.
+ try {
+ mf.parseObject(result, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_parseLjava_lang_String() throws ParseException {
+ String pattern = "A {3, number, currency} B {2, time} C {0, number, percent} D {4} E {1,choice,0#off|1#on} F {0, date}";
+ MessageFormat mf = new MessageFormat(pattern);
+ String sToParse = "A $12,345.00 B 9:56:07 AM C 3,200% D 1/15/70 9:56 AM E on F Jan 1, 1970";
+ Object[] result = mf.parse(sToParse);
+
+ assertTrue("No result: " + result.length, result.length == 5);
+ assertTrue("Object 0 is not date", result[0] instanceof Date);
+ assertEquals("Object 1 is not stringr", result[1].toString(), "1.0");
+ assertTrue("Object 2 is not date", result[2] instanceof Date);
+ assertEquals("Object 3 is not number", result[3].toString(), "12345");
+ assertEquals("Object 4 is not string", result[4].toString(), "1/15/70 9:56 AM");
+
+ sToParse = "xxdate is Feb 28, 1999";
+ try {
+ result = format1.parse(sToParse);
+ fail();
+ } catch (java.text.ParseException expected) {
+ }
+
+ sToParse = "vm=Test, @3 4 6, 3 ";
+ mf = new MessageFormat("vm={0},{1},{2}");
+ result = mf.parse(sToParse);
+ assertTrue("No result: " + result.length, result.length == 3);
+ assertEquals("Object 0 is not string", result[0].toString(), "Test");
+ assertEquals("Object 1 is not string", result[1].toString(), " @3 4 6");
+ assertEquals("Object 2 is not string", result[2].toString(), " 3 ");
+
+ try {
+ result = mf.parse(null);
+ fail();
+ } catch (java.text.ParseException expected) {
+ }
+ }
+
+ public void test_setFormats$Ljava_text_Format() throws Exception {
+ MessageFormat f1 = (MessageFormat) format1.clone();
+
+ // case 1: Test with repeating formats and max argument index < max
+ // offset
+ // compare getFormats() results after calls to setFormats(Format[])
+ Format[] correctFormats = new Format[] {
+ DateFormat.getTimeInstance(),
+ new ChoiceFormat("0#off|1#on"),
+ DateFormat.getTimeInstance(),
+ NumberFormat.getCurrencyInstance(),
+ new ChoiceFormat("1#few|2#ok|3#a lot")
+ };
+
+ f1.setFormats(correctFormats);
+ Format[] formats = f1.getFormats();
+
+ assertTrue("Test1A:Returned wrong number of formats:", correctFormats.length <= formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test1B:wrong format for argument index " + i + ":", correctFormats[i], formats[i]);
+ }
+
+ // case 2: Try to pass null argument to setFormats().
+ try {
+ f1.setFormats(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_formatLjava_lang_StringLjava_lang_Object() {
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+ int iCurrency = 123;
+ int iInteger = Integer.MIN_VALUE;
+
+ Date date = new Date(12345678);
+ Object[] args = { date, iCurrency, iInteger };
+ String resStr = "Date: Jan 1, 1970 Currency: $" + iCurrency + ".00 Integer: -2,147,483,648";
+ String pattern = "Date: {0,date} Currency: {1, number, currency} Integer: {2, number, integer}";
+ String sFormat = MessageFormat.format(pattern, (Object[]) args);
+ assertEquals(
+ "format(String, Object[]) with valid parameters returns incorrect string: case 1",
+ sFormat, resStr);
+
+ pattern = "abc {4, number, integer} def {3,date} ghi {2,number} jkl {1,choice,0#low|1#high} mnop {0}";
+ resStr = "abc -2,147,483,648 def Jan 1, 1970 ghi -2,147,483,648 jkl high mnop -2,147,483,648";
+ Object[] args_ = { iInteger, 1, iInteger, date, iInteger };
+ sFormat = MessageFormat.format(pattern, args_);
+ assertEquals(
+ "format(String, Object[]) with valid parameters returns incorrect string: case 1",
+ sFormat, resStr);
+
+ try {
+ args = null;
+ MessageFormat.format(null, args);
+ fail();
+ } catch (Exception expected) {
+ }
+
+ try {
+ MessageFormat.format("Invalid {1,foobar} format descriptor!", new Object[] {iInteger} );
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ MessageFormat.format("Invalid {1,date,invalid-spec} format descriptor!", new Object[]{""});
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ MessageFormat.format("{0,number,integer", new Object[] {iInteger});
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ MessageFormat.format("Valid {1, date} format {0, number} descriptor!", new Object[]{ "" } );
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_ConstructorLjava_lang_StringLjava_util_Locale() {
+ Locale mk = new Locale("mk", "MK");
+ MessageFormat format = new MessageFormat("Date: {0,date} Currency: {1, number, currency} Integer: {2, number, integer}", mk);
+ assertEquals(format.getLocale(), mk);
+ assertEquals(format.getFormats()[0], DateFormat.getDateInstance(DateFormat.DEFAULT, mk));
+ assertEquals(format.getFormats()[1], NumberFormat.getCurrencyInstance(mk));
+ assertEquals(format.getFormats()[2], NumberFormat.getIntegerInstance(mk));
+ }
+
+ public void test_ConstructorLjava_lang_String() {
+ MessageFormat format = new MessageFormat(
+ "abc {4,time} def {3,date} ghi {2,number} jkl {1,choice,0#low|1#high} mnop {0}");
+ assertTrue("Not a MessageFormat",
+ format.getClass() == MessageFormat.class);
+ Format[] formats = format.getFormats();
+ assertNotNull("null formats", formats);
+ assertTrue("Wrong format count: " + formats.length, formats.length >= 5);
+ assertTrue("Wrong time format", formats[0].equals(DateFormat
+ .getTimeInstance()));
+ assertTrue("Wrong date format", formats[1].equals(DateFormat
+ .getDateInstance()));
+ assertTrue("Wrong number format", formats[2].equals(NumberFormat
+ .getInstance()));
+ assertTrue("Wrong choice format", formats[3].equals(new ChoiceFormat(
+ "0.0#low|1.0#high")));
+ assertNull("Wrong string format", formats[4]);
+
+ Date date = new Date();
+ FieldPosition pos = new FieldPosition(-1);
+ StringBuffer buffer = new StringBuffer();
+ format.format(new Object[] { "123", new Double(1.6), new Double(7.2),
+ date, date }, buffer, pos);
+ String result = buffer.toString();
+ buffer.setLength(0);
+ buffer.append("abc ");
+ buffer.append(DateFormat.getTimeInstance().format(date));
+ buffer.append(" def ");
+ buffer.append(DateFormat.getDateInstance().format(date));
+ buffer.append(" ghi ");
+ buffer.append(NumberFormat.getInstance().format(new Double(7.2)));
+ buffer.append(" jkl high mnop 123");
+ assertTrue("Wrong answer:\n" + result + "\n" + buffer, result
+ .equals(buffer.toString()));
+
+ assertEquals("Simple string", "Test message", new MessageFormat("Test message").format(
+ new Object[0]));
+
+ result = new MessageFormat("Don't").format(new Object[0]);
+ assertTrue("Should not throw IllegalArgumentException: " + result,
+ "Dont".equals(result));
+
+ try {
+ new MessageFormat("Invalid {1,foobar} format descriptor!");
+ fail("Expected test_ConstructorLjava_lang_String to throw IAE.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ try {
+ new MessageFormat(
+ "Invalid {1,date,invalid-spec} format descriptor!");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ checkSerialization(new MessageFormat(""));
+ checkSerialization(new MessageFormat("noargs"));
+ checkSerialization(new MessageFormat("{0}"));
+ checkSerialization(new MessageFormat("a{0}"));
+ checkSerialization(new MessageFormat("{0}b"));
+ checkSerialization(new MessageFormat("a{0}b"));
+
+ // Regression for HARMONY-65
+ try {
+ new MessageFormat("{0,number,integer");
+ fail("Assert 0: Failed to detect unmatched brackets.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void test_applyPatternLjava_lang_String() {
+ MessageFormat format = new MessageFormat("test");
+ format.applyPattern("xx {0}");
+ assertEquals("Invalid number", "xx 46", format.format(
+ new Object[] { new Integer(46) }));
+ Date date = new Date();
+ String result = format.format(new Object[] { date });
+ String expected = "xx " + DateFormat.getInstance().format(date);
+ assertTrue("Invalid date:\n" + result + "\n" + expected, result
+ .equals(expected));
+ format = new MessageFormat("{0,date}{1,time}{2,number,integer}");
+ format.applyPattern("nothing");
+ assertEquals("Found formats", "nothing", format.toPattern());
+
+ format.applyPattern("{0}");
+ assertNull("Wrong format", format.getFormats()[0]);
+ assertEquals("Wrong pattern", "{0}", format.toPattern());
+
+ format.applyPattern("{0, \t\u001ftime }");
+ assertTrue("Wrong time format", format.getFormats()[0]
+ .equals(DateFormat.getTimeInstance()));
+ assertEquals("Wrong time pattern", "{0,time}", format.toPattern());
+ format.applyPattern("{0,Time, Short\n}");
+ assertTrue("Wrong short time format", format.getFormats()[0]
+ .equals(DateFormat.getTimeInstance(DateFormat.SHORT)));
+ assertEquals("Wrong short time pattern",
+ "{0,time,short}", format.toPattern());
+ format.applyPattern("{0,TIME,\nmedium }");
+ assertTrue("Wrong medium time format", format.getFormats()[0]
+ .equals(DateFormat.getTimeInstance(DateFormat.MEDIUM)));
+ assertEquals("Wrong medium time pattern",
+ "{0,time}", format.toPattern());
+ format.applyPattern("{0,time,LONG}");
+ assertTrue("Wrong long time format", format.getFormats()[0]
+ .equals(DateFormat.getTimeInstance(DateFormat.LONG)));
+ assertEquals("Wrong long time pattern",
+ "{0,time,long}", format.toPattern());
+ format.setLocale(Locale.FRENCH); // use French since English has the
+ // same LONG and FULL time patterns
+ format.applyPattern("{0,time, Full}");
+ assertTrue("Wrong full time format", format.getFormats()[0]
+ .equals(DateFormat.getTimeInstance(DateFormat.FULL,
+ Locale.FRENCH)));
+ assertEquals("Wrong full time pattern",
+ "{0,time,full}", format.toPattern());
+ format.setLocale(Locale.getDefault());
+
+ format.applyPattern("{0, date}");
+ assertTrue("Wrong date format", format.getFormats()[0]
+ .equals(DateFormat.getDateInstance()));
+ assertEquals("Wrong date pattern", "{0,date}", format.toPattern());
+ format.applyPattern("{0, date, short}");
+ assertTrue("Wrong short date format", format.getFormats()[0]
+ .equals(DateFormat.getDateInstance(DateFormat.SHORT)));
+ assertEquals("Wrong short date pattern",
+ "{0,date,short}", format.toPattern());
+ format.applyPattern("{0, date, medium}");
+ assertTrue("Wrong medium date format", format.getFormats()[0]
+ .equals(DateFormat.getDateInstance(DateFormat.MEDIUM)));
+ assertEquals("Wrong medium date pattern",
+ "{0,date}", format.toPattern());
+ format.applyPattern("{0, date, long}");
+ assertTrue("Wrong long date format", format.getFormats()[0]
+ .equals(DateFormat.getDateInstance(DateFormat.LONG)));
+ assertEquals("Wrong long date pattern",
+ "{0,date,long}", format.toPattern());
+ format.applyPattern("{0, date, full}");
+ assertTrue("Wrong full date format", format.getFormats()[0]
+ .equals(DateFormat.getDateInstance(DateFormat.FULL)));
+ assertEquals("Wrong full date pattern",
+ "{0,date,full}", format.toPattern());
+
+ format.applyPattern("{0, date, MMM d {hh:mm:ss}}");
+ assertEquals("Wrong time/date format", " MMM d {hh:mm:ss}", ((SimpleDateFormat) (format
+ .getFormats()[0])).toPattern());
+ assertEquals("Wrong time/date pattern",
+ "{0,date, MMM d {hh:mm:ss}}", format.toPattern());
+
+ format.applyPattern("{0, number}");
+ assertTrue("Wrong number format", format.getFormats()[0]
+ .equals(NumberFormat.getNumberInstance()));
+ assertEquals("Wrong number pattern",
+ "{0,number}", format.toPattern());
+ format.applyPattern("{0, number, currency}");
+ assertTrue("Wrong currency number format", format.getFormats()[0]
+ .equals(NumberFormat.getCurrencyInstance()));
+ assertEquals("Wrong currency number pattern",
+ "{0,number,currency}", format.toPattern());
+ format.applyPattern("{0, number, percent}");
+ assertTrue("Wrong percent number format", format.getFormats()[0]
+ .equals(NumberFormat.getPercentInstance()));
+ assertEquals("Wrong percent number pattern",
+ "{0,number,percent}", format.toPattern());
+ format.applyPattern("{0, number, integer}");
+
+ DecimalFormat expectedNumberFormat = (DecimalFormat) NumberFormat.getIntegerInstance();
+ DecimalFormat actualNumberFormat = (DecimalFormat) format.getFormats()[0];
+ assertEquals(expectedNumberFormat.getDecimalFormatSymbols(), actualNumberFormat.getDecimalFormatSymbols());
+ assertEquals(expectedNumberFormat.isParseIntegerOnly(), actualNumberFormat.isParseIntegerOnly());
+ assertEquals("Wrong integer number pattern", "{0,number,integer}", format.toPattern());
+ assertEquals(expectedNumberFormat, format.getFormats()[0]);
+
+ format.applyPattern("{0, number, {'#'}##0.0E0}");
+
+ /*
+ * TODO validate these assertions
+ * String actual = ((DecimalFormat)(format.getFormats()[0])).toPattern();
+ * assertEquals("Wrong pattern number format", "' {#}'##0.0E0", actual);
+ * assertEquals("Wrong pattern number pattern", "{0,number,' {#}'##0.0E0}", format.toPattern());
+ *
+ */
+
+ format.applyPattern("{0, choice,0#no|1#one|2#{1,number}}");
+ assertEquals("Wrong choice format",
+
+ "0.0#no|1.0#one|2.0#{1,number}", ((ChoiceFormat) format.getFormats()[0]).toPattern());
+ assertEquals("Wrong choice pattern",
+ "{0,choice,0.0#no|1.0#one|2.0#{1,number}}", format.toPattern());
+ assertEquals("Wrong formatted choice", "3.6", format.format(
+ new Object[] { new Integer(2), new Float(3.6) }));
+
+ try {
+ format.applyPattern("WRONG MESSAGE FORMAT {0,number,{}");
+ fail("Expected IllegalArgumentException for invalid pattern");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // Regression for HARMONY-65
+ MessageFormat mf = new MessageFormat("{0,number,integer}");
+ String badpattern = "{0,number,#";
+ try {
+ mf.applyPattern(badpattern);
+ fail("Assert 0: Failed to detect unmatched brackets.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void test_clone() {
+ MessageFormat format = new MessageFormat("'{'choice'}'{0}");
+ MessageFormat clone = (MessageFormat) format.clone();
+ assertTrue("Clone not equal", format.equals(clone));
+ assertEquals("Wrong answer",
+ "{choice}{0}", format.format(new Object[] {}));
+ clone.setFormat(0, DateFormat.getInstance());
+ assertTrue("Clone shares format data", !format.equals(clone));
+ format = (MessageFormat) clone.clone();
+ Format[] formats = clone.getFormats();
+ ((SimpleDateFormat) formats[0]).applyPattern("adk123");
+ assertTrue("Clone shares format data", !format.equals(clone));
+ }
+
+ public void test_equalsLjava_lang_Object() {
+ MessageFormat format1 = new MessageFormat("{0}");
+ MessageFormat format2 = new MessageFormat("{1}");
+ assertTrue("Should not be equal", !format1.equals(format2));
+ format2.applyPattern("{0}");
+ assertTrue("Should be equal", format1.equals(format2));
+ SimpleDateFormat date = (SimpleDateFormat) DateFormat.getTimeInstance();
+ format1.setFormat(0, DateFormat.getTimeInstance());
+ format2.setFormat(0, new SimpleDateFormat(date.toPattern()));
+ assertTrue("Should be equal2", format1.equals(format2));
+ }
+
+ public void test_hashCode() {
+ assertEquals("Should be equal", 3648, new MessageFormat("rr", null).hashCode());
+ }
+
+ public void test_format$Ljava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
+ MessageFormat format = new MessageFormat("{1,number,integer}");
+ StringBuffer buffer = new StringBuffer();
+ format.format(new Object[] { "0", new Double(53.863) }, buffer,
+ new FieldPosition(0));
+ assertEquals("Wrong result", "54", buffer.toString());
+
+ format.format(new Object[] { "0", new Double(53.863) }, buffer,
+ new FieldPosition(MessageFormat.Field.ARGUMENT));
+ assertEquals("Wrong result", "5454", buffer.toString());
+
+ buffer = new StringBuffer();
+ format.applyPattern("{0,choice,0#zero|1#one '{1,choice,2#two {2,time}}'}");
+ Date date = new Date();
+ String expectedText = "one two " + DateFormat.getTimeInstance().format(date);
+ format.format(new Object[] { new Double(1.6), new Integer(3), date }, buffer, new FieldPosition(MessageFormat.Field.ARGUMENT));
+ assertEquals("Choice not recursive:\n" + expectedText + "\n" + buffer, expectedText, buffer.toString());
+
+ StringBuffer str = format.format(new Object[] { new Double(0.6),
+ new Integer(3)}, buffer, null);
+ assertEquals(expectedText + "zero", str.toString());
+ assertEquals(expectedText + "zero", buffer.toString());
+
+ try {
+ format.format(new Object[] { "0", new Double(1), "" }, buffer,
+ new FieldPosition(MessageFormat.Field.ARGUMENT));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ format.format(new Object[] { "", new Integer(3)}, buffer,
+ new FieldPosition(MessageFormat.Field.ARGUMENT));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
+ new Support_MessageFormat(
+ "test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition")
+ .t_format_with_FieldPosition();
+
+ String pattern = "On {4,date} at {3,time}, he ate {2,number, integer} hamburger{2,choice,1#|1<s}.";
+ MessageFormat format = new MessageFormat(pattern, Locale.US);
+ Object[] objects = new Object[] { "", new Integer(3), 8, ""};
+ try {
+ format.format(objects, new StringBuffer(), new FieldPosition(DateFormat.Field.AM_PM));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_getFormats() {
+ // test with repeating formats and max argument index < max offset
+ Format[] formats = format1.getFormats();
+ Format[] correctFormats = new Format[] {
+ NumberFormat.getCurrencyInstance(),
+ DateFormat.getTimeInstance(),
+ NumberFormat.getPercentInstance(), null,
+ new ChoiceFormat("0#off|1#on"), DateFormat.getDateInstance(), };
+
+ assertEquals("Test1:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test1:wrong format for pattern index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // test with max argument index > max offset
+ formats = format2.getFormats();
+ correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
+ DateFormat.getTimeInstance(),
+ NumberFormat.getPercentInstance(), null,
+ new ChoiceFormat("0#off|1#on"), DateFormat.getDateInstance() };
+
+ assertEquals("Test2:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test2:wrong format for pattern index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // test with argument number being zero
+ formats = format3.getFormats();
+ assertEquals("Test3: Returned wrong number of formats:", 0,
+ formats.length);
+ }
+
+ public void test_getFormatsByArgumentIndex() {
+ // test with repeating formats and max argument index < max offset
+ Format[] formats = format1.getFormatsByArgumentIndex();
+ Format[] correctFormats = new Format[] { DateFormat.getDateInstance(),
+ new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
+ NumberFormat.getCurrencyInstance(), null };
+
+ assertEquals("Test1:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test1:wrong format for argument index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // test with max argument index > max offset
+ formats = format2.getFormatsByArgumentIndex();
+ correctFormats = new Format[] { DateFormat.getDateInstance(),
+ new ChoiceFormat("0#off|1#on"), null,
+ NumberFormat.getCurrencyInstance(), null, null, null, null,
+ DateFormat.getTimeInstance() };
+
+ assertEquals("Test2:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test2:wrong format for argument index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // test with argument number being zero
+ formats = format3.getFormatsByArgumentIndex();
+ assertEquals("Test3: Returned wrong number of formats:", 0,
+ formats.length);
+ }
+
+ public void test_setFormatByArgumentIndexILjava_text_Format() {
+ // test for method setFormatByArgumentIndex(int, Format)
+ MessageFormat f1 = (MessageFormat) format1.clone();
+ f1.setFormatByArgumentIndex(0, DateFormat.getTimeInstance());
+ f1.setFormatByArgumentIndex(4, new ChoiceFormat("1#few|2#ok|3#a lot"));
+
+ // test with repeating formats and max argument index < max offset
+ // compare getFormatsByArgumentIndex() results after calls to
+ // setFormatByArgumentIndex()
+ Format[] formats = f1.getFormatsByArgumentIndex();
+
+ Format[] correctFormats = new Format[] { DateFormat.getTimeInstance(),
+ new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
+ NumberFormat.getCurrencyInstance(),
+ new ChoiceFormat("1#few|2#ok|3#a lot") };
+
+ assertEquals("Test1A:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test1B:wrong format for argument index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // compare getFormats() results after calls to
+ // setFormatByArgumentIndex()
+ formats = f1.getFormats();
+
+ correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
+ DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
+ new ChoiceFormat("1#few|2#ok|3#a lot"),
+ new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(), };
+
+ assertEquals("Test1C:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test1D:wrong format for pattern index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // test setting argumentIndexes that are not used
+ MessageFormat f2 = (MessageFormat) format2.clone();
+ f2.setFormatByArgumentIndex(2, NumberFormat.getPercentInstance());
+ f2.setFormatByArgumentIndex(4, DateFormat.getTimeInstance());
+
+ formats = f2.getFormatsByArgumentIndex();
+ correctFormats = format2.getFormatsByArgumentIndex();
+
+ assertEquals("Test2A:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test2B:wrong format for argument index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ formats = f2.getFormats();
+ correctFormats = format2.getFormats();
+
+ assertEquals("Test2C:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test2D:wrong format for pattern index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // test exceeding the argumentIndex number
+ MessageFormat f3 = (MessageFormat) format3.clone();
+ f3.setFormatByArgumentIndex(1, NumberFormat.getCurrencyInstance());
+
+ formats = f3.getFormatsByArgumentIndex();
+ assertEquals("Test3A:Returned wrong number of formats:", 0,
+ formats.length);
+
+ formats = f3.getFormats();
+ assertEquals("Test3B:Returned wrong number of formats:", 0,
+ formats.length);
+ }
+
+ public void test_setFormatsByArgumentIndex$Ljava_text_Format() {
+ MessageFormat f1 = (MessageFormat) format1.clone();
+
+ // test with repeating formats and max argument index < max offset
+ // compare getFormatsByArgumentIndex() results after calls to
+ // setFormatsByArgumentIndex(Format[])
+ Format[] correctFormats = new Format[] { DateFormat.getTimeInstance(),
+ new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(),
+ NumberFormat.getCurrencyInstance(),
+ new ChoiceFormat("1#few|2#ok|3#a lot") };
+
+ f1.setFormatsByArgumentIndex(correctFormats);
+ Format[] formats = f1.getFormatsByArgumentIndex();
+
+ assertEquals("Test1A:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test1B:wrong format for argument index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // compare getFormats() results after calls to
+ // setFormatByArgumentIndex()
+ formats = f1.getFormats();
+ correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
+ DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
+ new ChoiceFormat("1#few|2#ok|3#a lot"),
+ new ChoiceFormat("0#off|1#on"), DateFormat.getTimeInstance(), };
+
+ assertEquals("Test1C:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test1D:wrong format for pattern index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // test setting argumentIndexes that are not used
+ MessageFormat f2 = (MessageFormat) format2.clone();
+ Format[] inputFormats = new Format[] { DateFormat.getDateInstance(),
+ new ChoiceFormat("0#off|1#on"),
+ NumberFormat.getPercentInstance(),
+ NumberFormat.getCurrencyInstance(),
+ DateFormat.getTimeInstance(), null, null, null,
+ DateFormat.getTimeInstance() };
+ f2.setFormatsByArgumentIndex(inputFormats);
+
+ formats = f2.getFormatsByArgumentIndex();
+ correctFormats = format2.getFormatsByArgumentIndex();
+
+ assertEquals("Test2A:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test2B:wrong format for argument index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ formats = f2.getFormats();
+ correctFormats = new Format[] { NumberFormat.getCurrencyInstance(),
+ DateFormat.getTimeInstance(), DateFormat.getDateInstance(),
+ null, new ChoiceFormat("0#off|1#on"),
+ DateFormat.getDateInstance() };
+
+ assertEquals("Test2C:Returned wrong number of formats:",
+ correctFormats.length, formats.length);
+ for (int i = 0; i < correctFormats.length; i++) {
+ assertEquals("Test2D:wrong format for pattern index " + i + ":",
+ correctFormats[i], formats[i]);
+ }
+
+ // test exceeding the argumentIndex number
+ MessageFormat f3 = (MessageFormat) format3.clone();
+ f3.setFormatsByArgumentIndex(inputFormats);
+
+ formats = f3.getFormatsByArgumentIndex();
+ assertEquals("Test3A:Returned wrong number of formats:", 0,
+ formats.length);
+
+ formats = f3.getFormats();
+ assertEquals("Test3B:Returned wrong number of formats:", 0,
+ formats.length);
+
+ }
+
+ public void test_parseLjava_lang_StringLjava_text_ParsePosition() {
+ MessageFormat format = new MessageFormat("date is {0,date,MMM d, yyyy}");
+ ParsePosition pos = new ParsePosition(2);
+ Object[] result = (Object[]) format
+ .parse("xxdate is Feb 28, 1999", pos);
+ assertTrue("No result: " + result.length, result.length >= 1);
+ assertTrue("Wrong answer", ((Date) result[0])
+ .equals(new GregorianCalendar(1999, Calendar.FEBRUARY, 28)
+ .getTime()));
+
+ MessageFormat mf = new MessageFormat("vm={0},{1},{2}");
+ result = mf.parse("vm=win,foo,bar", new ParsePosition(0));
+ assertTrue("Invalid parse", result[0].equals("win")
+ && result[1].equals("foo") && result[2].equals("bar"));
+
+ mf = new MessageFormat("{0}; {0}; {0}");
+ String parse = "a; b; c";
+ result = mf.parse(parse, new ParsePosition(0));
+ assertEquals("Wrong variable result", "c", result[0]);
+
+ mf = new MessageFormat("before {0}, after {1,number}");
+ parse = "before you, after 42";
+ pos.setIndex(0);
+ pos.setErrorIndex(8);
+ result = mf.parse(parse, pos);
+ assertEquals(2, result.length);
+
+ try {
+ mf.parse(parse, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // This should _not_ throw.
+ mf.parse(null, pos);
+ }
+
+ public void test_setLocaleLjava_util_Locale() {
+ MessageFormat format = new MessageFormat("date {0,date}");
+ format.setLocale(Locale.CHINA);
+ assertEquals("Wrong locale1", Locale.CHINA, format.getLocale());
+ format.applyPattern("{1,date}");
+ assertEquals("Wrong locale3", DateFormat.getDateInstance(DateFormat.DEFAULT,
+ Locale.CHINA), format.getFormats()[0]);
+ }
+
+ public void test_toPattern() {
+ String pattern = "[{0}]";
+ MessageFormat mf = new MessageFormat(pattern);
+ assertTrue("Wrong pattern", mf.toPattern().equals(pattern));
+
+ // Regression for HARMONY-59
+ new MessageFormat("CHOICE {1,choice}").toPattern();
+ }
+
+ protected void setUp() {
+ defaultLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+
+ // test with repeating formats and max argument index < max offset
+ String pattern = "A {3, number, currency} B {2, time} C {0, number, percent} D {4} E {1,choice,0#off|1#on} F {0, date}";
+ format1 = new MessageFormat(pattern);
+
+ // test with max argument index > max offset
+ pattern = "A {3, number, currency} B {8, time} C {0, number, percent} D {6} E {1,choice,0#off|1#on} F {0, date}";
+ format2 = new MessageFormat(pattern);
+
+ // test with argument number being zero
+ pattern = "A B C D E F";
+ format3 = new MessageFormat(pattern);
+ }
+
+ protected void tearDown() {
+ Locale.setDefault(defaultLocale);
+ }
+
+ public void test_ConstructorLjava_util_Locale() {
+ // Regression for HARMONY-65
+ try {
+ new MessageFormat("{0,number,integer", Locale.US);
+ fail("Assert 0: Failed to detect unmatched brackets.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void test_parse() throws ParseException {
+ // Regression for HARMONY-63
+ MessageFormat mf = new MessageFormat("{0,number,#,##}", Locale.US);
+ Object[] res = mf.parse("1,00,00");
+ assertEquals("Assert 0: incorrect size of parsed data ", 1, res.length);
+ assertEquals("Assert 1: parsed value incorrectly", new Long(10000), (Long)res[0]);
+ }
+
+ public void test_format_Object() {
+ // Regression for HARMONY-1875
+ Locale.setDefault(Locale.CANADA);
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+ String pat="text here {0, date, yyyyyyyyy } and here";
+ String etalon="text here 000002007 and here";
+ MessageFormat obj = new MessageFormat(pat);
+ assertEquals(etalon, obj.format(new Object[]{new Date(1198141737640L)}));
+
+ assertEquals("{0}", MessageFormat.format("{0}", (Object[]) null));
+ assertEquals("nullABC", MessageFormat.format("{0}{1}", (Object[]) new String[]{null, "ABC"}));
+ }
+
+ public void testHARMONY5323() {
+ Object[] messageArgs = new Object[11];
+ for (int i = 0; i < messageArgs.length; i++) {
+ messageArgs[i] = "example" + i;
+ }
+
+ String res = MessageFormat.format("bgcolor=\"{10}\"", messageArgs);
+ assertEquals(res, "bgcolor=\"example10\"");
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NormalizerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NormalizerTest.java
new file mode 100644
index 0000000..50aa096
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NormalizerTest.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.Normalizer;
+import java.text.Normalizer.Form;
+
+import junit.framework.TestCase;
+
+public class NormalizerTest extends TestCase {
+ /**
+ * @tests java.text.Normalizer.Form#values()
+ */
+ public void test_form_values() throws Exception {
+ Form[] forms = Form.values();
+ assertEquals(4, forms.length);
+ assertEquals(Form.NFD, forms[0]);
+ assertEquals(Form.NFC, forms[1]);
+ assertEquals(Form.NFKD, forms[2]);
+ assertEquals(Form.NFKC, forms[3]);
+ }
+
+ /**
+ * @tests java.text.Normalizer.Form#valueOf(String)
+ */
+ public void test_form_valueOfLjava_lang_String() {
+ try {
+ Form.valueOf(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ assertEquals(Form.NFC, Form.valueOf("NFC"));
+ assertEquals(Form.NFD, Form.valueOf("NFD"));
+ assertEquals(Form.NFKC, Form.valueOf("NFKC"));
+ assertEquals(Form.NFKD, Form.valueOf("NFKD"));
+
+ try {
+ Form.valueOf("not exist");
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ Form.valueOf("nfc");
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ Form.valueOf("NFC ");
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.text.Normalizer#isNormalized(CharSequence, Form)
+ */
+ public void test_isNormalized() throws Exception {
+ String src = "\u00c1";
+ assertTrue(Normalizer.isNormalized(src, Form.NFC));
+ assertFalse(Normalizer.isNormalized(src, Form.NFD));
+ assertTrue(Normalizer.isNormalized(src, Form.NFKC));
+ assertFalse(Normalizer.isNormalized(src, Form.NFKD));
+
+ src = "\u0041\u0301";
+ assertFalse(Normalizer.isNormalized(src, Form.NFC));
+ assertTrue(Normalizer.isNormalized(src, Form.NFD));
+ assertFalse(Normalizer.isNormalized(src, Form.NFKC));
+ assertTrue(Normalizer.isNormalized(src, Form.NFKD));
+
+ src = "\ufb03";
+ assertTrue(Normalizer.isNormalized(src, Form.NFC));
+ assertTrue(Normalizer.isNormalized(src, Form.NFD));
+ assertFalse(Normalizer.isNormalized(src, Form.NFKC));
+ assertFalse(Normalizer.isNormalized(src, Form.NFKD));
+
+ src = "\u0066\u0066\u0069";
+ assertTrue(Normalizer.isNormalized(src, Form.NFC));
+ assertTrue(Normalizer.isNormalized(src, Form.NFD));
+ assertTrue(Normalizer.isNormalized(src, Form.NFKC));
+ assertTrue(Normalizer.isNormalized(src, Form.NFKD));
+
+ src = "";
+ assertTrue(Normalizer.isNormalized(src, Form.NFC));
+ assertTrue(Normalizer.isNormalized(src, Form.NFD));
+ assertTrue(Normalizer.isNormalized(src, Form.NFKC));
+ assertTrue(Normalizer.isNormalized(src, Form.NFKD));
+ }
+
+ /**
+ * @tests java.text.Normalizer#isNormalized(CharSequence, Form)
+ */
+ public void test_isNormalized_exception() throws Exception {
+ try {
+ Normalizer.isNormalized(null, Form.NFC);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ Normalizer.isNormalized("chars", null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.text.Normalizer#normalize(CharSequence, Form)
+ */
+ public void test_normalize() throws Exception {
+ String src = "\u00c1";
+ assertEquals("\u00c1", Normalizer.normalize(src, Form.NFC));
+ assertEquals("\u0041\u0301", Normalizer.normalize(src, Form.NFD));
+ assertEquals("\u00c1", Normalizer.normalize(src, Form.NFKC));
+ assertEquals("\u0041\u0301", Normalizer.normalize(src, Form.NFKD));
+
+ src = "\u0041\u0301";
+ assertEquals("\u00c1", Normalizer.normalize(src, Form.NFC));
+ assertEquals("\u0041\u0301", Normalizer.normalize(src, Form.NFD));
+ assertEquals("\u00c1", Normalizer.normalize(src, Form.NFKC));
+ assertEquals("\u0041\u0301", Normalizer.normalize(src, Form.NFKD));
+
+ src = "\ufb03";
+ assertEquals("\ufb03", Normalizer.normalize(src, Form.NFC));
+ assertEquals("\ufb03", Normalizer.normalize(src, Form.NFD));
+ assertEquals("\u0066\u0066\u0069", Normalizer.normalize(src, Form.NFKC));
+ assertEquals("\u0066\u0066\u0069", Normalizer.normalize(src, Form.NFKD));
+
+ src = "\u0066\u0066\u0069";
+ assertEquals("\u0066\u0066\u0069", Normalizer.normalize(src, Form.NFC));
+ assertEquals("\u0066\u0066\u0069", Normalizer.normalize(src, Form.NFD));
+ assertEquals("\u0066\u0066\u0069", Normalizer.normalize(src, Form.NFKC));
+ assertEquals("\u0066\u0066\u0069", Normalizer.normalize(src, Form.NFKD));
+
+ src = "";
+ assertEquals("", Normalizer.normalize(src, Form.NFC));
+ assertEquals("", Normalizer.normalize(src, Form.NFD));
+ assertEquals("", Normalizer.normalize(src, Form.NFKC));
+ assertEquals("", Normalizer.normalize(src, Form.NFKD));
+ }
+
+ /**
+ * @tests java.text.Normalizer#normalize(CharSequence, Form)
+ */
+ public void test_normalize_exception() throws Exception {
+ try {
+ Normalizer.normalize(null, Form.NFC);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ Normalizer.normalize("chars", null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NumberFormatFieldTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NumberFormatFieldTest.java
new file mode 100644
index 0000000..8d64d8a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NumberFormatFieldTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+public class NumberFormatFieldTest extends junit.framework.TestCase {
+ /**
+ * @tests java.text.NumberFormat$Field#Field(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // protected constructor
+ }
+
+ /**
+ * @tests java.text.NumberFormat$Field#readResolve()
+ */
+ public void test_readResolve() {
+ // test for method java.lang.Object readResolve()
+
+ // see serialization stress tests:
+ // implemented in
+ // SerializationStressTest4.test_writeObject_NumberFormat_Field()
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+
+ protected void doneSuite() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NumberFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NumberFormatTest.java
new file mode 100644
index 0000000..49e3d9e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/NumberFormatTest.java
@@ -0,0 +1,295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.math.RoundingMode;
+import java.text.ChoiceFormat;
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.util.Currency;
+import java.util.Locale;
+
+public class NumberFormatTest extends junit.framework.TestCase {
+
+ /**
+ * @tests java.text.NumberFormat#format(java.lang.Object,
+ * java.lang.StringBuffer, java.text.FieldPosition)
+ */
+ public void test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
+ FieldPosition pos;
+ StringBuffer out;
+ DecimalFormat format = (DecimalFormat) NumberFormat
+ .getInstance(Locale.US);
+
+ pos = new FieldPosition(0);
+ out = format.format(new Long(Long.MAX_VALUE), new StringBuffer(), pos);
+ assertEquals("Wrong result L1: " + out, "9,223,372,036,854,775,807",
+ out.toString());
+
+ pos = new FieldPosition(0);
+ out = format.format(new Long(Long.MIN_VALUE), new StringBuffer(), pos);
+ assertEquals("Wrong result L2: " + out, "-9,223,372,036,854,775,808",
+ out.toString());
+
+ pos = new FieldPosition(0);
+ out = format.format(new java.math.BigInteger(String
+ .valueOf(Long.MAX_VALUE)), new StringBuffer(), pos);
+ assertEquals("Wrong result BI1: " + out, "9,223,372,036,854,775,807",
+ out.toString());
+
+ pos = new FieldPosition(0);
+ out = format.format(new java.math.BigInteger(String
+ .valueOf(Long.MIN_VALUE)), new StringBuffer(), pos);
+ assertEquals("Wrong result BI2: " + out, "-9,223,372,036,854,775,808",
+ out.toString());
+
+ java.math.BigInteger big;
+ pos = new FieldPosition(0);
+ big = new java.math.BigInteger(String.valueOf(Long.MAX_VALUE))
+ .add(new java.math.BigInteger("1"));
+ out = format.format(big, new StringBuffer(), pos);
+ assertEquals("Wrong result BI3: " + out, "9,223,372,036,854,775,808",
+ out.toString());
+
+ pos = new FieldPosition(0);
+ big = new java.math.BigInteger(String.valueOf(Long.MIN_VALUE))
+ .add(new java.math.BigInteger("-1"));
+ out = format.format(big, new StringBuffer(), pos);
+ assertEquals("Wrong result BI4: " + out, "-9,223,372,036,854,775,809",
+ out.toString());
+
+ pos = new FieldPosition(0);
+ out = format.format(new java.math.BigDecimal("51.348"),
+ new StringBuffer(), pos);
+ assertEquals("Wrong result BD1: " + out, "51.348", out.toString());
+
+ pos = new FieldPosition(0);
+ out = format.format(new java.math.BigDecimal("51"), new StringBuffer(),
+ pos);
+ assertEquals("Wrong result BD2: " + out, "51", out.toString());
+
+ try {
+ format.format(this, new StringBuffer(), pos);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ format.format(null, new StringBuffer(), pos);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ format.format(new Long(0), null, pos);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ format.format(new Long(0), new StringBuffer(), null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * @tests java.text.NumberFormat#getIntegerInstance()
+ */
+ public void test_getIntegerInstance() throws ParseException {
+ // Test for method java.text.NumberFormat getIntegerInstance()
+ Locale origLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+
+ DecimalFormat format = (DecimalFormat) NumberFormat
+ .getIntegerInstance();
+
+ assertEquals(
+ "Test1: NumberFormat.getIntegerInstance().toPattern() returned wrong pattern",
+ "#,##0", format.toPattern());
+ assertEquals(
+ "Test2: NumberFormat.getIntegerInstance().format(35.76) returned wrong value",
+ "36", format.format(35.76));
+ assertEquals(
+ "Test3: NumberFormat.getIntegerInstance().parse(\"35.76\") returned wrong number",
+ new Long(35), format.parse("35.76"));
+ assertEquals(
+ "Test4: NumberFormat.getIntegerInstance().parseObject(\"35.76\") returned wrong number",
+ new Long(35), format.parseObject("35.76"));
+ Locale.setDefault(origLocale);
+ }
+
+ /**
+ * @tests java.text.NumberFormat#getIntegerInstance(java.util.Locale)
+ */
+ public void test_getIntegerInstanceLjava_util_Locale()
+ throws ParseException {
+ // Test for method java.text.NumberFormat
+ // getIntegerInstance(java.util.Locale)
+ Locale usLocale = Locale.US;
+ Locale arLocale = new Locale("ar", "AE");
+
+ DecimalFormat format = (DecimalFormat) NumberFormat
+ .getIntegerInstance(usLocale);
+ assertEquals(
+ "Test1: NumberFormat.getIntegerInstance().toPattern() returned wrong pattern",
+ "#,##0", format.toPattern());
+ assertEquals(
+ "Test2: NumberFormat.getIntegerInstance().format(-35.76) returned wrong value",
+ "-36", format.format(-35.76));
+ assertEquals(
+ "Test3: NumberFormat.getIntegerInstance().parse(\"-36\") returned wrong number",
+ new Long(-36), format.parse("-36"));
+ assertEquals(
+ "Test4: NumberFormat.getIntegerInstance().parseObject(\"-36\") returned wrong number",
+ new Long(-36), format.parseObject("-36"));
+ assertEquals(
+ "Test5: NumberFormat.getIntegerInstance().getMaximumFractionDigits() returned wrong value",
+ 0, format.getMaximumFractionDigits());
+ assertTrue("Test6: NumberFormat.getIntegerInstance().isParseIntegerOnly() returned wrong value",
+ format.isParseIntegerOnly());
+
+ // try with a locale that has a different integer pattern
+ format = (DecimalFormat) NumberFormat.getIntegerInstance(arLocale);
+ assertEquals(
+ "Test7: NumberFormat.getIntegerInstance(new Locale(\"ar\", \"AE\")).toPattern() returned wrong pattern",
+ "#,##0", format.toPattern());
+ assertEquals(
+ "Test8: NumberFormat.getIntegerInstance(new Locale(\"ar\", \"AE\")).format(-35.76) returned wrong value",
+ "\u200f-\u0666", format.format(-6));
+ assertEquals(
+ "Test9: NumberFormat.getIntegerInstance(new Locale(\"ar\", \"AE\")).parse(\"-36-\") returned wrong number",
+ new Long(36), format.parse("36-"));
+ assertEquals(
+ "Test10: NumberFormat.getIntegerInstance(new Locale(\"ar\", \"AE\")).parseObject(\"36-\") returned wrong number",
+ new Long(36), format.parseObject("36-"));
+
+ assertEquals(
+ "Test11: NumberFormat.getIntegerInstance(new Locale(\"ar\", \"AE\")).getMaximumFractionDigits() returned wrong value",
+ 0, format.getMaximumFractionDigits());
+ assertTrue(
+ "Test12: NumberFormat.getIntegerInstance(new Locale(\"ar\", \"AE\")).isParseIntegerOnly() returned wrong value",
+ format.isParseIntegerOnly());
+ }
+
+ /**
+ * @tests java.text.NumberFormat#getCurrency()
+ */
+ public void test_getCurrency() {
+ // Test for method java.util.Currency getCurrency()
+
+ // a subclass that supports currency formatting
+ Currency currH = Currency.getInstance("HUF");
+ NumberFormat format = NumberFormat.getInstance(new Locale("hu", "HU"));
+ assertSame("Returned incorrect currency", currH, format.getCurrency());
+
+ // a subclass that doesn't support currency formatting
+ ChoiceFormat cformat = new ChoiceFormat(
+ "0#Less than one|1#one|1<Between one and two|2<Greater than two");
+ try {
+ ((NumberFormat) cformat).getCurrency();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ /**
+ * @tests java.text.NumberFormat#getMaximumIntegerDigits()
+ */
+ public void test_getMaximumIntegerDigits() {
+ NumberFormat format = NumberFormat.getInstance();
+ format.setMaximumIntegerDigits(2);
+ assertEquals("Wrong result", "23", format.format(123));
+ }
+
+ /**
+ * @tests java.text.NumberFormat#setCurrency(java.util.Currency)
+ */
+ public void test_setCurrencyLjava_util_Currency() {
+ // Test for method void setCurrency(java.util.Currency)
+ // a subclass that supports currency formatting
+ Currency currA = Currency.getInstance("ARS");
+ NumberFormat format = NumberFormat.getInstance(new Locale("hu", "HU"));
+ format.setCurrency(currA);
+ assertSame("Returned incorrect currency", currA, format.getCurrency());
+
+ // a subclass that doesn't support currency formatting
+ ChoiceFormat cformat = new ChoiceFormat(
+ "0#Less than one|1#one|1<Between one and two|2<Greater than two");
+ try {
+ ((NumberFormat) cformat).setCurrency(currA);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+ /**
+ * @tests java.text.NumberFormat#parseObject(java.lang.String, java.text.ParsePosition)
+ */
+ public void test_parseObjectLjava_lang_StringLjava_text_ParsePosition() {
+ // regression test for HARMONY-1003
+ assertNull(NumberFormat.getInstance().parseObject("0", new ParsePosition(-1)));
+
+ // Regression for HARMONY-1685
+ try {
+ NumberFormat.getInstance().parseObject("test", null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+
+ public void test_setRoundingMode_NullRoundingMode() {
+ try {
+ // Create a subclass ChoiceFormat which doesn't support
+ // RoundingMode
+ ChoiceFormat choiceFormat = new ChoiceFormat(
+ "0#Less than one|1#one|1<Between one and two|2<Greater than two");
+ ((NumberFormat) choiceFormat).setRoundingMode(null);
+ // Follow the behavior of RI
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void test_setRoundingMode_Normal() {
+ try {
+ // Create a subclass ChoiceFormat which doesn't support
+ // RoundingMode
+ ChoiceFormat choiceFormat = new ChoiceFormat(
+ "0#Less than one|1#one|1<Between one and two|2<Greater than two");
+ ((NumberFormat) choiceFormat).setRoundingMode(RoundingMode.CEILING);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ParseExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ParseExceptionTest.java
new file mode 100644
index 0000000..c73d8e3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ParseExceptionTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+
+@SuppressWarnings("nls")
+public class ParseExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * @tests java.text.ParseException#ParseException(java.lang.String, int)
+ */
+ public void test_ConstructorLjava_lang_StringI() {
+ try {
+ DateFormat df = DateFormat.getInstance();
+ df.parse("HelloWorld");
+ fail("ParseException not created/thrown.");
+ } catch (ParseException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.text.ParseException#getErrorOffset()
+ */
+ public void test_getErrorOffset() {
+ try {
+ DateFormat df = DateFormat.getInstance();
+ df.parse("1999HelloWorld");
+ } catch (ParseException e) {
+ assertEquals("getErrorOffsetFailed.", 4, e.getErrorOffset());
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ParsePositionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ParsePositionTest.java
new file mode 100644
index 0000000..994a8d3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/ParsePositionTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.text.ParsePosition;
+
+public class ParsePositionTest extends junit.framework.TestCase {
+
+ ParsePosition pp;
+
+ /**
+ * @tests java.text.ParsePosition#ParsePosition(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.text.ParsePosition(int)
+ ParsePosition pp1 = new ParsePosition(Integer.MIN_VALUE);
+ assertTrue("Initialization failed.", pp1.getIndex() == Integer.MIN_VALUE);
+ assertEquals("Initialization failed.", -1, pp1.getErrorIndex());
+ }
+
+ /**
+ * @tests java.text.ParsePosition#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.text.ParsePosition.equals(java.lang.Object)
+ ParsePosition pp2 = new ParsePosition(43);
+ pp2.setErrorIndex(56);
+ assertTrue("equals failed.", !pp.equals(pp2));
+ pp.setErrorIndex(56);
+ pp.setIndex(43);
+ assertTrue("equals failed.", pp.equals(pp2));
+ }
+
+ /**
+ * @tests java.text.ParsePosition#getErrorIndex()
+ */
+ public void test_getErrorIndex() {
+ // Test for method int java.text.ParsePosition.getErrorIndex()
+ pp.setErrorIndex(56);
+ assertEquals("getErrorIndex failed.", 56, pp.getErrorIndex());
+ }
+
+ /**
+ * @tests java.text.ParsePosition#getIndex()
+ */
+ public void test_getIndex() {
+ // Test for method int java.text.ParsePosition.getIndex()
+ assertTrue("getIndex failed.", pp.getIndex() == Integer.MAX_VALUE);
+ }
+
+ /**
+ * @tests java.text.ParsePosition#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.text.ParsePosition.hashCode()
+ assertTrue("Wrong hashCode returned", (pp.hashCode() == pp.getIndex()
+ + pp.getErrorIndex()));
+ }
+
+ /**
+ * @tests java.text.ParsePosition#setErrorIndex(int)
+ */
+ public void test_setErrorIndexI() {
+ // Test for method void java.text.ParsePosition.setErrorIndex(int)
+ pp.setErrorIndex(4564);
+ assertEquals("setErrorIndex failed.", 4564, pp.getErrorIndex());
+ }
+
+ /**
+ * @tests java.text.ParsePosition#setIndex(int)
+ */
+ public void test_setIndexI() {
+ // Test for method void java.text.ParsePosition.setIndex(int)
+ pp.setIndex(4564);
+ assertEquals("setErrorIndex failed.", 4564, pp.getIndex());
+ }
+
+ /**
+ * @tests java.text.ParsePosition#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.text.ParsePosition.toString()
+ assertEquals("toString failed.",
+ "java.text.ParsePosition[index=2147483647, errorIndex=-1]", pp.toString());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+
+ pp = new ParsePosition(Integer.MAX_VALUE);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/RuleBasedCollatorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/RuleBasedCollatorTest.java
new file mode 100644
index 0000000..906857b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/RuleBasedCollatorTest.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.CharacterIterator;
+import java.text.CollationElementIterator;
+import java.text.CollationKey;
+import java.text.Collator;
+import java.text.ParseException;
+import java.text.RuleBasedCollator;
+import java.text.StringCharacterIterator;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+public class RuleBasedCollatorTest extends TestCase {
+
+ public void test_getCollationKeyLjava_lang_String() throws Exception {
+ // Regression test for HARMONY-28
+ String source = null;
+ String Simple = "&9 < a< b< c< d";
+ RuleBasedCollator rbc = new RuleBasedCollator(Simple);
+ CollationKey ck = rbc.getCollationKey(source);
+ assertNull("Assert 1: getCollationKey (null) does not return null", ck);
+ }
+
+ public void testHashCode() throws ParseException {
+ {
+ String rule = "&9 < a < b < c < d";
+ RuleBasedCollator coll = new RuleBasedCollator(rule);
+ assertEquals(rule.hashCode(), coll.hashCode());
+ }
+
+ {
+ String rule = "&9 < a < b < c < d < e";
+ RuleBasedCollator coll = new RuleBasedCollator(rule);
+ assertEquals(rule.hashCode(), coll.hashCode());
+ }
+ }
+
+ public void testClone() throws ParseException {
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(Locale.US);
+ RuleBasedCollator clone = (RuleBasedCollator) coll.clone();
+ assertNotSame(coll, clone);
+ assertEquals(coll.getRules(), clone.getRules());
+ assertEquals(coll.getDecomposition(), clone.getDecomposition());
+ assertEquals(coll.getStrength(), clone.getStrength());
+ }
+
+ public void testEqualsObject() throws ParseException {
+ String rule = "&9 < a < b < c < d < e";
+ RuleBasedCollator coll = new RuleBasedCollator(rule);
+
+ assertEquals(Collator.TERTIARY, coll.getStrength());
+ assertEquals(Collator.NO_DECOMPOSITION, coll.getDecomposition());
+ RuleBasedCollator other = new RuleBasedCollator(rule);
+ assertTrue(coll.equals(other));
+
+ coll.setStrength(Collator.PRIMARY);
+ assertFalse(coll.equals(other));
+
+ coll.setStrength(Collator.TERTIARY);
+ coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+ assertFalse(coll.equals(other));
+ }
+
+ public void testCompareStringString() throws ParseException {
+ String rule = "&9 < c < b < a";
+ RuleBasedCollator coll = new RuleBasedCollator(rule);
+ assertEquals(-1, coll.compare("c", "a"));
+ }
+
+ public void testGetCollationKey() {
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(Locale.GERMAN);
+ String source = "abc";
+ CollationKey key1 = coll.getCollationKey(source);
+ assertEquals(source, key1.getSourceString());
+ String source2 = "abb";
+ CollationKey key2 = coll.getCollationKey(source2);
+ assertEquals(source2, key2.getSourceString());
+ assertTrue(key1.compareTo(key2) > 0);
+ assertTrue(coll.compare(source, source2) > 0);
+ }
+
+ public void testGetRules() throws ParseException {
+ String rule = "&9 < a = b < c";
+ RuleBasedCollator coll = new RuleBasedCollator(rule);
+ assertEquals(rule, coll.getRules());
+ }
+
+ public void testGetCollationElementIteratorString() throws Exception {
+ {
+ Locale locale = Locale.forLanguageTag("es-u-co-trad");
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(locale);
+ String source = "cha";
+ CollationElementIterator iterator = coll.getCollationElementIterator(source);
+ int[] e_offset = { 0, 2, 3 };
+ int offset = iterator.getOffset();
+ int i = 0;
+ assertEquals(e_offset[i++], offset);
+ while (offset != source.length()) {
+ iterator.next();
+ offset = iterator.getOffset();
+ assertEquals(e_offset[i++], offset);
+ }
+ assertEquals(CollationElementIterator.NULLORDER, iterator.next());
+ }
+
+ {
+ Locale locale = new Locale("de", "DE");
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(locale);
+ String source = "\u00fcb";
+ CollationElementIterator iterator = coll.getCollationElementIterator(source);
+ int[] e_offset = { 0, 1, 1, 2 };
+ int offset = iterator.getOffset();
+ int i = 0;
+ assertEquals(e_offset[i++], offset);
+ while (offset != source.length()) {
+ iterator.next();
+ offset = iterator.getOffset();
+ assertEquals(e_offset[i++], offset);
+ }
+ assertEquals(CollationElementIterator.NULLORDER, iterator.next());
+ }
+ //Regression for HARMONY-1352
+ try {
+ new RuleBasedCollator("&9 < a< b< c< d").getCollationElementIterator((String)null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testGetCollationElementIteratorCharacterIterator() throws Exception {
+ {
+ Locale locale = Locale.forLanguageTag("es-u-co-trad");
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(locale);
+ String text = "cha";
+ StringCharacterIterator source = new StringCharacterIterator(text);
+ CollationElementIterator iterator = coll.getCollationElementIterator(source);
+ int[] e_offset = { 0, 2, 3 };
+ int offset = iterator.getOffset();
+ int i = 0;
+ assertEquals(e_offset[i++], offset);
+ while (offset != text.length()) {
+ iterator.next();
+ offset = iterator.getOffset();
+ // System.out.println(offset);
+ assertEquals(e_offset[i++], offset);
+ }
+ assertEquals(CollationElementIterator.NULLORDER, iterator.next());
+ }
+
+ {
+ Locale locale = new Locale("de", "DE");
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(locale);
+ String text = "\u00fcb";
+ StringCharacterIterator source = new StringCharacterIterator(text);
+ CollationElementIterator iterator = coll.getCollationElementIterator(source);
+ int[] e_offset = { 0, 1, 1, 2 };
+ int offset = iterator.getOffset();
+ int i = 0;
+ assertEquals(e_offset[i++], offset);
+ while (offset != text.length()) {
+ iterator.next();
+ offset = iterator.getOffset();
+ assertEquals(e_offset[i++], offset);
+ }
+ assertEquals(CollationElementIterator.NULLORDER, iterator.next());
+ }
+ //Regression for HARMONY-1352
+ try {
+ new RuleBasedCollator("&9 < a< b< c< d").getCollationElementIterator((CharacterIterator)null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testStrength() {
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(Locale.US);
+ for (int i = 0; i < 4; i++) {
+ coll.setStrength(i);
+ assertEquals(i, coll.getStrength());
+ }
+ }
+
+ public void testDecomposition() {
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(Locale.US);
+ for (int i = 0; i < 2; i++) {
+ coll.setDecomposition(i);
+ assertEquals(i, coll.getDecomposition());
+ }
+ }
+
+ public void testCollator_GetInstance() {
+ Collator coll = Collator.getInstance();
+ Object obj1 = "a";
+ Object obj2 = "b";
+ assertEquals(-1, coll.compare(obj1, obj2));
+
+ Collator.getInstance();
+ assertFalse(coll.equals("A", "\uFF21"));
+ }
+
+ public void testGetAvailableLocales() {
+ assertTrue(Collator.getAvailableLocales().length > 0);
+ }
+
+ // Test CollationKey
+ public void testCollationKey() {
+ Collator coll = Collator.getInstance(Locale.US);
+ String text = "abc";
+ CollationKey key = coll.getCollationKey(text);
+ key.hashCode();
+
+ CollationKey key2 = coll.getCollationKey("abc");
+
+ assertEquals(0, key.compareTo(key2));
+ }
+
+ public void testNullPointerException() throws Exception {
+ //Regression for HARMONY-241
+ try {
+ new RuleBasedCollator(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testCompareNull() throws Exception {
+ //Regression for HARMONY-836
+ try {
+ new RuleBasedCollator("&9 < a").compare(null, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testEmptyRules() throws Exception {
+ new RuleBasedCollator("");
+ new RuleBasedCollator(" ");
+ new RuleBasedCollator("# This is a comment.");
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java
new file mode 100644
index 0000000..9a484ae
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java
@@ -0,0 +1,835 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.text;
+
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.FieldPosition;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+
+public class SimpleDateFormatTest extends junit.framework.TestCase {
+
+ private SimpleDateFormat format;
+
+ private SimpleDateFormat pFormat;
+
+ private TimeZone previousDefaultTimeZone;
+
+ @Override public void setUp() {
+ previousDefaultTimeZone = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+ format = new SimpleDateFormat("", Locale.ENGLISH);
+ pFormat = new SimpleDateFormat("", Locale.ENGLISH);
+ }
+
+ @Override public void tearDown() {
+ TimeZone.setDefault(previousDefaultTimeZone);
+ }
+
+ public void test_Constructor() {
+ // Test for method java.text.SimpleDateFormat()
+ SimpleDateFormat f2 = new SimpleDateFormat();
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertTrue("Wrong default", f2.equals(DateFormat.getDateTimeInstance(
+ DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault())));
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(new DateFormatSymbols()));
+ assertTrue("Doesn't work", f2.format(new Date()).getClass() == String.class);
+ }
+
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.text.SimpleDateFormat(java.lang.String)
+ SimpleDateFormat f2 = new SimpleDateFormat("yyyy");
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertEquals("Wrong pattern", "yyyy", f2.toPattern());
+ assertTrue("Wrong locale", f2.equals(new SimpleDateFormat("yyyy", Locale.getDefault())));
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(new DateFormatSymbols()));
+ assertTrue("Doesn't work", f2.format(new Date()).getClass() == String.class);
+
+ // Invalid constructor value.
+ try {
+ new SimpleDateFormat("this is an invalid simple date format");
+ fail("Expected test_ConstructorLjava_lang_String to throw IAE.");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ // Null string value
+ try {
+ new SimpleDateFormat(null);
+ fail("Expected test_ConstructorLjava_lang_String to throw NPE.");
+ } catch (NullPointerException ex) {
+ // expected
+ }
+ }
+
+ public void test_ConstructorLjava_lang_StringLjava_text_DateFormatSymbols() {
+ // Test for method java.text.SimpleDateFormat(java.lang.String,
+ // java.text.DateFormatSymbols)
+ DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH);
+ symbols.setEras(new String[] { "Before", "After" });
+ SimpleDateFormat f2 = new SimpleDateFormat("y'y'yy", symbols);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertEquals("Wrong pattern", "y'y'yy", f2.toPattern());
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(symbols));
+ assertTrue("Doesn't work", f2.format(new Date()).getClass() == String.class);
+
+ try {
+ new SimpleDateFormat(null, symbols);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ new SimpleDateFormat("eee", symbols);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_ConstructorLjava_lang_StringLjava_util_Locale() {
+ // Test for method java.text.SimpleDateFormat(java.lang.String,
+ // java.util.Locale)
+ SimpleDateFormat f2 = new SimpleDateFormat("'yyyy' MM yy", Locale.GERMAN);
+ assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
+ assertEquals("Wrong pattern", "'yyyy' MM yy", f2.toPattern());
+ assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
+ new DateFormatSymbols(Locale.GERMAN)));
+ assertTrue("Doesn't work", f2.format(new Date()).getClass() == String.class);
+
+ try {
+ new SimpleDateFormat(null, Locale.GERMAN);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ new SimpleDateFormat("eee", Locale.GERMAN);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_applyLocalizedPatternLjava_lang_String() {
+ SimpleDateFormat f2 = new SimpleDateFormat("y", new Locale("de", "CH"));
+ String pattern = "GyMdkHmsSEDFwWahKzZLc";
+ f2.applyLocalizedPattern(pattern);
+ assertEquals(pattern, f2.toPattern());
+ assertEquals(pattern, f2.toLocalizedPattern());
+
+ // test invalid patterns
+ try {
+ f2.applyLocalizedPattern("b");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ f2.applyLocalizedPattern("a '"); // Unterminated quote.
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ f2.applyLocalizedPattern(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_applyPatternLjava_lang_String() {
+ // Test for method void
+ // java.text.SimpleDateFormat.applyPattern(java.lang.String)
+ SimpleDateFormat f2 = new SimpleDateFormat("y", new Locale("de", "CH"));
+ f2.applyPattern("GyMdkHmsSEDFwWahKz");
+ assertEquals("Wrong pattern", "GyMdkHmsSEDFwWahKz", f2.toPattern());
+
+ // test invalid patterns
+ try {
+ f2.applyPattern("b");
+ fail("Expected IllegalArgumentException for pattern with invalid patter letter: b");
+ } catch (IllegalArgumentException e) {
+ }
+
+// try {
+// f2.applyPattern("u");
+// fail("Expected IllegalArgumentException for pattern with invalid patter letter: u");
+// } catch (IllegalArgumentException e) {
+// }
+
+ try {
+ f2.applyPattern("a '");
+ fail("Expected IllegalArgumentException for pattern with unterminated quote: a '");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ f2.applyPattern(null);
+ fail("Expected NullPointerException for null pattern");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_clone() {
+ // Test for method java.lang.Object java.text.SimpleDateFormat.clone()
+ SimpleDateFormat f2 = new SimpleDateFormat();
+ SimpleDateFormat clone = (SimpleDateFormat) f2.clone();
+ assertTrue("Invalid clone", f2.equals(clone));
+ clone.applyPattern("y");
+ assertTrue("Format modified", !f2.equals(clone));
+ clone = (SimpleDateFormat) f2.clone();
+ // Date date = clone.get2DigitYearStart();
+ // date.setTime(0);
+ // assertTrue("Equal after date change: " +
+ // f2.get2DigitYearStart().getTime() + " " +
+ // clone.get2DigitYearStart().getTime(), !f2.equals(clone));
+ }
+
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.text.SimpleDateFormat.equals(java.lang.Object)
+ SimpleDateFormat format = (SimpleDateFormat) DateFormat.getInstance();
+ SimpleDateFormat clone = (SimpleDateFormat) format.clone();
+ assertTrue("clone not equal", format.equals(clone));
+ format.format(new Date());
+ assertTrue("not equal after format", format.equals(clone));
+ }
+
+ public void test_equals_afterFormat() {
+ // Regression test for HARMONY-209
+ SimpleDateFormat df = new SimpleDateFormat();
+ df.format(new Date());
+ assertEquals(df, new SimpleDateFormat());
+ }
+
+ public void test_hashCode() {
+ SimpleDateFormat format = (SimpleDateFormat) DateFormat.getInstance();
+ SimpleDateFormat clone = (SimpleDateFormat) format.clone();
+ assertTrue("clone has not equal hash code", clone.hashCode() == format.hashCode());
+ format.format(new Date());
+ assertTrue("clone has not equal hash code after format",
+ clone.hashCode() == format.hashCode());
+ DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH);
+ symbols.setEras(new String[] { "Before", "After" });
+ SimpleDateFormat format2 = new SimpleDateFormat("y'y'yy", symbols);
+ assertFalse("objects has equal hash code", format2.hashCode() == format.hashCode());
+ }
+
+ public void test_formatToCharacterIteratorLjava_lang_Object() {
+ try {
+ // Regression for HARMONY-466
+ new SimpleDateFormat().formatToCharacterIterator(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // Test for method formatToCharacterIterator(java.lang.Object)
+ new Support_SimpleDateFormat(
+ "test_formatToCharacterIteratorLjava_lang_Object")
+ .t_formatToCharacterIterator();
+ }
+
+ public void test_formatLjava_util_DateLjava_lang_StringBufferLjava_text_FieldPosition() {
+ // Test for method java.lang.StringBuffer
+ // java.text.SimpleDateFormat.format(java.util.Date,
+ // java.lang.StringBuffer, java.text.FieldPosition)
+
+ new Support_SimpleDateFormat(
+ "test_formatLjava_util_DateLjava_lang_StringBufferLjava_text_FieldPosition")
+ .t_format_with_FieldPosition();
+
+ Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6);
+ assertFormat(" G", cal, " AD", DateFormat.ERA_FIELD);
+ assertFormat(" GG", cal, " AD", DateFormat.ERA_FIELD);
+ assertFormat(" GGG", cal, " AD", DateFormat.ERA_FIELD);
+ assertFormat(" G", new GregorianCalendar(-1999, Calendar.JUNE, 2), " BC",
+ DateFormat.ERA_FIELD);
+
+ // This assumes Unicode behavior where 'y' and 'yyy' don't truncate,
+ // which means that it will fail on the RI.
+ assertFormat(" y", cal, " 1999", DateFormat.YEAR_FIELD);
+ assertFormat(" yy", cal, " 99", DateFormat.YEAR_FIELD);
+ assertFormat(" yy", new GregorianCalendar(2001, Calendar.JUNE, 2), " 01",
+ DateFormat.YEAR_FIELD);
+ assertFormat(" yy", new GregorianCalendar(2000, Calendar.JUNE, 2), " 00",
+ DateFormat.YEAR_FIELD);
+ assertFormat(" yyy", new GregorianCalendar(2000, Calendar.JUNE, 2), " 2000",
+ DateFormat.YEAR_FIELD);
+ assertFormat(" yyy", cal, " 1999", DateFormat.YEAR_FIELD);
+ assertFormat(" yyyy", cal, " 1999", DateFormat.YEAR_FIELD);
+ assertFormat(" yyyyy", cal, " 01999", DateFormat.YEAR_FIELD);
+
+ assertFormat(" M", cal, " 6", DateFormat.MONTH_FIELD);
+ assertFormat(" M", new GregorianCalendar(1999, Calendar.NOVEMBER, 2), " 11",
+ DateFormat.MONTH_FIELD);
+ assertFormat(" MM", cal, " 06", DateFormat.MONTH_FIELD);
+ assertFormat(" MMM", cal, " Jun", DateFormat.MONTH_FIELD);
+ assertFormat(" MMMM", cal, " June", DateFormat.MONTH_FIELD);
+ assertFormat(" MMMMM", cal, " J", DateFormat.MONTH_FIELD);
+
+ assertFormat(" d", cal, " 2", DateFormat.DATE_FIELD);
+ assertFormat(" d", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 12",
+ DateFormat.DATE_FIELD);
+ assertFormat(" dd", cal, " 02", DateFormat.DATE_FIELD);
+ assertFormat(" dddd", cal, " 0002", DateFormat.DATE_FIELD);
+
+ assertFormat(" h", cal, " 3", DateFormat.HOUR1_FIELD);
+ assertFormat(" h", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 12",
+ DateFormat.HOUR1_FIELD);
+ assertFormat(" hh", cal, " 03", DateFormat.HOUR1_FIELD);
+ assertFormat(" hhhh", cal, " 0003", DateFormat.HOUR1_FIELD);
+
+ assertFormat(" H", cal, " 15", DateFormat.HOUR_OF_DAY0_FIELD);
+ assertFormat(" H", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 0), " 4",
+ DateFormat.HOUR_OF_DAY0_FIELD);
+ assertFormat(" H", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 12, 0), " 12",
+ DateFormat.HOUR_OF_DAY0_FIELD);
+ assertFormat(" H", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 0",
+ DateFormat.HOUR_OF_DAY0_FIELD);
+ assertFormat(" HH", cal, " 15", DateFormat.HOUR_OF_DAY0_FIELD);
+ assertFormat(" HHHH", cal, " 0015", DateFormat.HOUR_OF_DAY0_FIELD);
+
+ assertFormat(" m", cal, " 3", DateFormat.MINUTE_FIELD);
+ assertFormat(" m", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 47), " 47",
+ DateFormat.MINUTE_FIELD);
+ assertFormat(" mm", cal, " 03", DateFormat.MINUTE_FIELD);
+ assertFormat(" mmmm", cal, " 0003", DateFormat.MINUTE_FIELD);
+
+ assertFormat(" s", cal, " 6", DateFormat.SECOND_FIELD);
+ assertFormat(" s", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 47, 13), " 13",
+ DateFormat.SECOND_FIELD);
+ assertFormat(" ss", cal, " 06", DateFormat.SECOND_FIELD);
+ assertFormat(" ssss", cal, " 0006", DateFormat.SECOND_FIELD);
+
+ assertFormat(" S", cal, " 0", DateFormat.MILLISECOND_FIELD);
+ Calendar temp = new GregorianCalendar();
+ temp.set(Calendar.MILLISECOND, 961);
+
+ assertFormat(" SS", temp, " 96", DateFormat.MILLISECOND_FIELD);
+ assertFormat(" SSSS", cal, " 0000", DateFormat.MILLISECOND_FIELD);
+
+ assertFormat(" SS", cal, " 00", DateFormat.MILLISECOND_FIELD);
+
+ assertFormat(" E", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
+ assertFormat(" EE", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
+ assertFormat(" EEE", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
+ assertFormat(" EEEE", cal, " Wednesday", DateFormat.DAY_OF_WEEK_FIELD);
+ assertFormat(" EEEEE", cal, " W", DateFormat.DAY_OF_WEEK_FIELD);
+
+ assertFormat(" D", cal, " 153", DateFormat.DAY_OF_YEAR_FIELD);
+ assertFormat(" DD", cal, " 153", DateFormat.DAY_OF_YEAR_FIELD);
+ assertFormat(" DDDD", cal, " 0153", DateFormat.DAY_OF_YEAR_FIELD);
+
+ assertFormat(" F", cal, " 1", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
+ assertFormat(" F", new GregorianCalendar(1999, Calendar.NOVEMBER, 14), " 2",
+ DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
+ assertFormat(" FF", cal, " 01", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
+ assertFormat(" FFFF", cal, " 0001", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
+
+ cal.setMinimalDaysInFirstWeek(1);
+ cal.setFirstDayOfWeek(1);
+
+ assertFormat(" w", cal, " 23", DateFormat.WEEK_OF_YEAR_FIELD);
+ assertFormat(" ww", cal, " 23", DateFormat.WEEK_OF_YEAR_FIELD);
+ assertFormat(" wwww", cal, " 0023", DateFormat.WEEK_OF_YEAR_FIELD);
+
+ assertFormat(" W", cal, " 1", DateFormat.WEEK_OF_MONTH_FIELD);
+ assertFormat(" WW", cal, " 01", DateFormat.WEEK_OF_MONTH_FIELD);
+ assertFormat(" WWWW", cal, " 0001", DateFormat.WEEK_OF_MONTH_FIELD);
+
+ assertFormat(" a", cal, " PM", DateFormat.AM_PM_FIELD);
+ assertFormat(" a", new GregorianCalendar(1999, Calendar.NOVEMBER, 14), " AM",
+ DateFormat.AM_PM_FIELD);
+ assertFormat(" a", new GregorianCalendar(1999, Calendar.NOVEMBER, 14, 12, 0), " PM",
+ DateFormat.AM_PM_FIELD);
+ assertFormat(" aa", cal, " PM", DateFormat.AM_PM_FIELD);
+ assertFormat(" aaa", cal, " PM", DateFormat.AM_PM_FIELD);
+ assertFormat(" aaaa", cal, " PM", DateFormat.AM_PM_FIELD);
+ assertFormat(" aaaaa", cal, " PM", DateFormat.AM_PM_FIELD);
+
+ assertFormat(" k", cal, " 15", DateFormat.HOUR_OF_DAY1_FIELD);
+ assertFormat(" k", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 0), " 4",
+ DateFormat.HOUR_OF_DAY1_FIELD);
+ assertFormat(" k", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 12, 0), " 12",
+ DateFormat.HOUR_OF_DAY1_FIELD);
+ assertFormat(" k", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 24",
+ DateFormat.HOUR_OF_DAY1_FIELD);
+ assertFormat(" kk", cal, " 15", DateFormat.HOUR_OF_DAY1_FIELD);
+ assertFormat(" kkkk", cal, " 0015", DateFormat.HOUR_OF_DAY1_FIELD);
+
+ assertFormat(" K", cal, " 3", DateFormat.HOUR0_FIELD);
+ assertFormat(" K", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 0",
+ DateFormat.HOUR0_FIELD);
+ assertFormat(" KK", cal, " 03", DateFormat.HOUR0_FIELD);
+ assertFormat(" KKKK", cal, " 0003", DateFormat.HOUR0_FIELD);
+
+ format.applyPattern("'Mkz''':.@5");
+ assertEquals("Wrong output", "Mkz':.@5", format.format(new Date()));
+
+ // Test invalid args to format.
+ SimpleDateFormat dateFormat = new SimpleDateFormat();
+ try {
+ dateFormat.format(null, new StringBuffer(), new FieldPosition(1));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ private void assertFormat(String pattern, Calendar cal, String expected, int field) {
+ StringBuffer buffer = new StringBuffer();
+ FieldPosition position = new FieldPosition(field);
+ format.applyPattern(pattern);
+ format.format(cal.getTime(), buffer, position);
+ String result = buffer.toString();
+ assertTrue("Wrong format: \"" + pattern + "\" expected: " + expected + " result: " + result,
+ result.equals(expected));
+ assertEquals("Wrong begin position: " + pattern + "\n" + "expected: " + expected + "\n" +
+ "field: " + field, 1, position.getBeginIndex());
+ assertTrue("Wrong end position: " + pattern + " expected: " + expected + " field: " + field,
+ position.getEndIndex() == result.length());
+ }
+
+ public void test_format_time_zones() throws Exception {
+ Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6);
+
+ format.setTimeZone(TimeZone.getTimeZone("EST"));
+ assertFormat(" z", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
+ Calendar temp2 = new GregorianCalendar(1999, Calendar.JANUARY, 12);
+ assertFormat(" z", temp2, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zz", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzz", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzzz", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzzz", temp2, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzzzz", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
+
+ format.setTimeZone(TimeZone.getTimeZone("America/New_York"));
+ assertFormat(" z", cal, " EDT", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" z", temp2, " EST", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzzz", cal, " Eastern Daylight Time", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzzz", temp2, " Eastern Standard Time", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzzzz", cal, " Eastern Daylight Time", DateFormat.TIMEZONE_FIELD);
+
+ TimeZone tz0001 = new SimpleTimeZone(60000, "ONE MINUTE");
+ TimeZone tz0130 = new SimpleTimeZone(5400000, "ONE HOUR, THIRTY");
+ TimeZone tzMinus0130 = new SimpleTimeZone(-5400000, "NEG ONE HOUR, THIRTY");
+
+ format.setTimeZone(tz0001);
+// test(" Z", cal, " +0001", DateFormat.TIMEZONE_FIELD);
+// test(" ZZZZ", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
+// test(" ZZZZZ", cal, " +00:01", DateFormat.TIMEZONE_FIELD);
+ format.setTimeZone(tz0130);
+// test(" Z", cal, " +0130", DateFormat.TIMEZONE_FIELD);
+ format.setTimeZone(tzMinus0130);
+// test(" Z", cal, " -0130", DateFormat.TIMEZONE_FIELD);
+
+ format.setTimeZone(tz0001);
+ assertFormat(" z", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
+ assertFormat(" zzzz", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
+ format.setTimeZone(tz0130);
+ assertFormat(" z", cal, " GMT+01:30", DateFormat.TIMEZONE_FIELD);
+ format.setTimeZone(tzMinus0130);
+ assertFormat(" z", cal, " GMT-01:30", DateFormat.TIMEZONE_FIELD);
+ }
+
+ public void test_timeZoneFormatting() {
+ // tests specific to formatting of timezones
+ Date summerDate = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6).getTime();
+ Date winterDate = new GregorianCalendar(1999, Calendar.JANUARY, 12).getTime();
+
+ verifyFormatTimezone(
+ "America/Los_Angeles", "PDT, Pacific Daylight Time", "-0700, GMT-07:00",
+ summerDate);
+ verifyFormatTimezone(
+ "America/Los_Angeles", "PST, Pacific Standard Time", "-0800, GMT-08:00",
+ winterDate);
+
+ verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, GMT-07:00", summerDate);
+ verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, GMT-07:00", winterDate);
+
+ verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", summerDate);
+ verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", winterDate);
+
+ // this fails on the RI!
+ verifyFormatTimezone("America/Detroit", "EDT, Eastern Daylight Time", "-0400, GMT-04:00",
+ summerDate);
+ verifyFormatTimezone("America/Detroit", "EST, Eastern Standard Time", "-0500, GMT-05:00",
+ winterDate);
+
+ // Pacific/Kiritimati is one of the timezones supported only in mJava
+ verifyFormatTimezone(
+ "Pacific/Kiritimati", "GMT+14:00, Line Islands Time", "+1400, GMT+14:00",
+ summerDate);
+ verifyFormatTimezone(
+ "Pacific/Kiritimati", "GMT+14:00, Line Islands Time", "+1400, GMT+14:00",
+ winterDate);
+
+ verifyFormatTimezone("EST", "GMT-05:00, GMT-05:00", "-0500, GMT-05:00", summerDate);
+ verifyFormatTimezone("EST", "GMT-05:00, GMT-05:00", "-0500, GMT-05:00", winterDate);
+
+ verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", summerDate);
+ verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", winterDate);
+ }
+
+ private void verifyFormatTimezone(String timeZoneId, String expected1, String expected2,
+ Date date) {
+ format.setTimeZone(SimpleTimeZone.getTimeZone(timeZoneId));
+ format.applyPattern("z, zzzz");
+ assertEquals("Test z for TimeZone : " + timeZoneId, expected1, format.format(date));
+
+ format.applyPattern("Z, ZZZZ");
+ assertEquals("Test Z for TimeZone : " + timeZoneId, expected2, format.format(date));
+ }
+
+ public void test_get2DigitYearStart() {
+ // Test for method java.util.Date
+ // java.text.SimpleDateFormat.get2DigitYearStart()
+ SimpleDateFormat f1 = new SimpleDateFormat("y");
+ Date date = f1.get2DigitYearStart();
+ Calendar cal = new GregorianCalendar();
+ int year = cal.get(Calendar.YEAR);
+ cal.setTime(date);
+ assertTrue("Wrong default year start", cal.get(Calendar.YEAR) == (year - 80));
+ }
+
+ public void test_getDateFormatSymbols() {
+ // Test for method java.text.DateFormatSymbols
+ // java.text.SimpleDateFormat.getDateFormatSymbols()
+ SimpleDateFormat df = (SimpleDateFormat) DateFormat.getInstance();
+ DateFormatSymbols dfs = df.getDateFormatSymbols();
+ assertTrue("Symbols identical", dfs != df.getDateFormatSymbols());
+ }
+
+ public void test_parseLjava_lang_StringLjava_text_ParsePosition() throws Exception {
+ // Test for method java.util.Date
+ // java.text.SimpleDateFormat.parse(java.lang.String,
+ // java.text.ParsePosition)
+ Calendar cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
+ Date time = cal.getTime();
+ assertParse("h", " 12", time, 1, 3);
+ assertParse("H", " 0", time, 1, 2);
+ assertParse("k", " 24", time, 1, 3);
+ assertParse("K", " 0", time, 1, 2);
+
+ cal = new GregorianCalendar(1970, Calendar.JANUARY, 1, 1, 0);
+ time = cal.getTime();
+ assertParse("h", "1", time, 0, 1);
+ assertParse("H", "1 ", time, 0, 1);
+ assertParse("k", "1", time, 0, 1);
+ assertParse("K", "1", time, 0, 1);
+
+ cal = new GregorianCalendar(1970, Calendar.JANUARY, 1, 11, 0);
+ time = cal.getTime();
+ assertParse("h", "0011 ", time, 0, 4);
+ assertParse("K", "11", time, 0, 2);
+ cal = new GregorianCalendar(1970, Calendar.JANUARY, 1, 23, 0);
+ time = cal.getTime();
+ assertParse("H", "23", time, 0, 2);
+ assertParse("k", "23", time, 0, 2);
+
+ assertParse("h a", " 3 AM", new GregorianCalendar(1970,
+ Calendar.JANUARY, 1, 3, 0).getTime(), 1, 5);
+ assertParse("K a", " 3 pm ", new GregorianCalendar(1970,
+ Calendar.JANUARY, 1, 15, 0).getTime(), 1, 5);
+ assertParse("m:s", "0:59 ", new GregorianCalendar(1970,
+ Calendar.JANUARY, 1, 0, 0, 59).getTime(), 0, 4);
+ assertParse("m:s", "59:0", new GregorianCalendar(1970, Calendar.JANUARY,
+ 1, 0, 59, 0).getTime(), 0, 4);
+ assertParse("ms", "059", new GregorianCalendar(1970, Calendar.JANUARY,
+ 1, 0, 0, 59).getTime(), 0, 3);
+
+ cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
+ assertParse("S", "0", cal.getTime(), 0, 1);
+ cal.setTimeZone(TimeZone.getTimeZone("HST"));
+ cal.set(Calendar.MILLISECOND, 999);
+ assertParse("S z", "999 HST", cal.getTime(), 0, 7);
+
+ cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
+ cal.set(Calendar.ERA, GregorianCalendar.BC);
+ assertParse("G", "Bc ", cal.getTime(), 0, 2);
+
+ assertParse("y", "00", new GregorianCalendar(2000, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("y", "99", new GregorianCalendar(1999, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("y", "1", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 1);
+ assertParse("y", "-1", new GregorianCalendar(-1, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("y", "001", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 3);
+ assertParse("y", "2005", new GregorianCalendar(2005, Calendar.JANUARY, 1).getTime(), 0, 4);
+ assertParse("yy", "00", new GregorianCalendar(2000, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("yy", "99", new GregorianCalendar(1999, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("yy", "1", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 1);
+ assertParse("yy", "-1", new GregorianCalendar(-1, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("yy", "001", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 3);
+ assertParse("yy", "2005", new GregorianCalendar(2005, Calendar.JANUARY, 1).getTime(), 0, 4);
+ assertParse("yyy", "99", new GregorianCalendar(99, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("yyy", "1", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 1);
+ assertParse("yyy", "-1", new GregorianCalendar(-1, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("yyy", "001", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 3);
+ assertParse("yyy", "2005", new GregorianCalendar(2005, Calendar.JANUARY, 1).getTime(),
+ 0, 4);
+ assertParse("yyyy", "99", new GregorianCalendar(99, Calendar.JANUARY, 1).getTime(), 0, 2);
+ assertParse("yyyy", " 1999", new GregorianCalendar(1999, Calendar.JANUARY, 1).getTime(),
+ 2, 6);
+ assertParse("MM'M'", "4M", new GregorianCalendar(1970, Calendar.APRIL, 1).getTime(), 0, 2);
+ assertParse("MMM", "Feb", new GregorianCalendar(1970, Calendar.FEBRUARY, 1).getTime(),
+ 0, 3);
+ assertParse("MMMM d", "April 14 ",
+ new GregorianCalendar(1970, Calendar.APRIL, 14).getTime(), 0, 8);
+ assertParse("MMMMd", "April14 ", new GregorianCalendar(1970, Calendar.APRIL, 14).getTime(),
+ 0, 7);
+ assertParse("E w", "Mon 12", new GregorianCalendar(1970, Calendar.MARCH, 16).getTime(),
+ 0, 6);
+ assertParse("Ew", "Mon12", new GregorianCalendar(1970, Calendar.MARCH, 16).getTime(), 0, 5);
+ assertParse("M EE ''W", "5 Tue '2", new GregorianCalendar(1970, Calendar.MAY, 5).getTime(),
+ 0, 8);
+ assertParse("MEE''W", "5Tue'2", new GregorianCalendar(1970, Calendar.MAY, 5).getTime(),
+ 0, 6);
+ assertParse("MMM EEE F", " JUL Sunday 3",
+ new GregorianCalendar(1970, Calendar.JULY, 19).getTime(), 1, 13);
+ assertParse("MMMEEEF", " JULSunday3",
+ new GregorianCalendar(1970, Calendar.JULY, 19).getTime(), 1, 11);
+
+ cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
+ cal.setTimeZone(TimeZone.getTimeZone("GMT+0:1"));
+ cal.set(Calendar.DAY_OF_YEAR, 243);
+ assertParse("D z", "243 GMT+0:0", cal.getTime(), 0, 11);
+ cal.setTimeZone(TimeZone.getTimeZone("EST"));
+ cal.set(1970, Calendar.JANUARY, 1, 4, 30);
+ assertParse("h:m z", "4:30 GMT-5 ", cal.getTime(), 0, 10);
+ assertParse("h z", "14 GMT-24 ", new Date(51840000), 0, 9);
+ assertParse("h z", "14 GMT-23 ", new Date(133200000), 0, 9);
+ assertParse("h z", "14 GMT-0001 ", new Date(54000000), 0, 11);
+ assertParse("h z", "14 GMT+24 ", new Date(48960000), 0, 9);
+ assertParse("h z", "14 GMT+23 ", new Date(-32400000), 0, 9);
+ assertParse("h z", "14 GMT+0001 ", new Date(46800000), 0, 11);
+ assertParse("h z", "14 +0001 ", new Date(46800000), 0, 8);
+ assertParse("h z", "14 -0001 ", new Date(54000000), 0, 8);
+
+ assertParse("yyyyMMddHHmmss", "19990913171901",
+ new GregorianCalendar(1999, Calendar.SEPTEMBER, 13, 17, 19, 1).getTime(), 0, 14);
+
+ Date d = new Date(1015822800000L);
+ SimpleDateFormat df = new SimpleDateFormat("", new Locale("en", "US"));
+ df.setTimeZone(TimeZone.getTimeZone("EST"));
+
+ df.applyPattern("dd MMMM yyyy EEEE");
+ String output = df.format(d);
+ Date date = df.parse(output);
+ assertTrue("Invalid result 1: " + date, d.equals(date));
+
+ df.applyPattern("dd MMMM yyyy F");
+ output = df.format(d);
+ date = df.parse(output);
+ assertTrue("Invalid result 2: " + date, d.equals(date));
+
+ df.applyPattern("dd MMMM yyyy w");
+ output = df.format(d);
+ date = df.parse(output);
+ assertTrue("Invalid result 3: " + date, d.equals(date));
+
+ df.applyPattern("dd MMMM yyyy W");
+ output = df.format(d);
+ date = df.parse(output);
+ assertTrue("Invalid result 4: " + date, d.equals(date));
+
+ df.applyPattern("dd MMMM yyyy D");
+ date = df.parse("5 January 2002 70");
+ assertTrue("Invalid result 5: " + date, d.equals(date));
+
+ df.applyPattern("W w dd MMMM yyyy EEEE");
+ output = df.format(d);
+ date = df.parse("3 12 5 March 2002 Monday");
+ assertTrue("Invalid result 6: " + date, d.equals(date));
+
+ df.applyPattern("w W dd MMMM yyyy EEEE");
+ output = df.format(d);
+ date = df.parse("12 3 5 March 2002 Monday");
+ assertTrue("Invalid result 6a: " + date, d.equals(date));
+
+ df.applyPattern("F dd MMMM yyyy EEEE");
+ output = df.format(d);
+ date = df.parse("2 5 March 2002 Monday");
+ assertTrue("Invalid result 7: " + date, d.equals(date));
+
+ df.applyPattern("w dd MMMM yyyy EEEE");
+ output = df.format(d);
+ date = df.parse("11 5 January 2002 Monday");
+ assertTrue("Invalid result 8: " + date, d.equals(date));
+
+ df.applyPattern("w dd yyyy EEEE MMMM");
+ output = df.format(d);
+ date = df.parse("11 5 2002 Monday January");
+ assertTrue("Invalid result 9: " + date, d.equals(date));
+
+ df.applyPattern("w yyyy EEEE MMMM dd");
+ output = df.format(d);
+ date = df.parse("17 2002 Monday March 11");
+ assertTrue("Invalid result 10: " + date, d.equals(date));
+
+ df.applyPattern("dd D yyyy MMMM");
+ output = df.format(d);
+ date = df.parse("5 70 2002 January");
+ assertTrue("Invalid result 11: " + date, d.equals(date));
+
+ df.applyPattern("D dd yyyy MMMM");
+ output = df.format(d);
+ date = df.parse("240 11 2002 March");
+ assertTrue("Invalid result 12: " + date, d.equals(date));
+
+ try {
+ format.parse("240 11 2002 March", null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ format.parse(null, new ParsePosition(0));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ private void assertParse(String pattern, String input, Date expected, int start, int end) {
+ pFormat.applyPattern(pattern);
+ ParsePosition position = new ParsePosition(start);
+ Date result = pFormat.parse(input, position);
+ assertTrue("Wrong result: " + pattern + " input: " + input + " expected: " + expected +
+ " result: " + result, expected.equals(result));
+ assertTrue("Wrong end position: " + pattern + " input: " + input,
+ position.getIndex() == end);
+ }
+
+ public void test_set2DigitYearStartLjava_util_Date() {
+ // Test for method void
+ // java.text.SimpleDateFormat.set2DigitYearStart(java.util.Date)
+ SimpleDateFormat f1 = new SimpleDateFormat("yy");
+ f1.set2DigitYearStart(new GregorianCalendar(1950, Calendar.JANUARY, 1).getTime());
+ Calendar cal = new GregorianCalendar();
+ try {
+ cal.setTime(f1.parse("49"));
+ assertEquals("Incorrect year 2049", 2049, cal.get(Calendar.YEAR));
+ cal.setTime(f1.parse("50"));
+ int year = cal.get(Calendar.YEAR);
+ assertTrue("Incorrect year 1950: " + year, year == 1950);
+ f1.applyPattern("y");
+ cal.setTime(f1.parse("00"));
+ assertEquals("Incorrect year 2000", 2000, cal.get(Calendar.YEAR));
+ f1.applyPattern("yyy");
+ cal.setTime(f1.parse("50"));
+ assertEquals("Incorrect year 50", 50, cal.get(Calendar.YEAR));
+ } catch (ParseException e) {
+ fail("ParseException");
+ }
+ }
+
+ public void test_setDateFormatSymbolsLjava_text_DateFormatSymbols() {
+ // Test for method void
+ // java.text.SimpleDateFormat.setDateFormatSymbols(java.text.DateFormatSymbols)
+ SimpleDateFormat f1 = new SimpleDateFormat("a");
+ DateFormatSymbols symbols = new DateFormatSymbols();
+ symbols.setAmPmStrings(new String[] { "morning", "night" });
+ f1.setDateFormatSymbols(symbols);
+ DateFormatSymbols newSym = f1.getDateFormatSymbols();
+ assertTrue("Set incorrectly", newSym.equals(symbols));
+ assertTrue("Not a clone", f1.getDateFormatSymbols() != symbols);
+ String result = f1.format(new GregorianCalendar(1999, Calendar.JUNE, 12, 3, 0).getTime());
+ assertEquals("Incorrect symbols used", "morning", result);
+ symbols.setEras(new String[] { "before", "after" });
+ assertTrue("Identical symbols", !f1.getDateFormatSymbols().equals(symbols));
+
+ try {
+ f1.setDateFormatSymbols(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_toPattern() {
+ String pattern = "yyyy mm dd";
+ SimpleDateFormat f = new SimpleDateFormat(pattern);
+ assertEquals("Wrong pattern: " + pattern, pattern, f.toPattern());
+
+ pattern = "GyMdkHmsSEDFwWahKz";
+ f = new SimpleDateFormat("GyMdkHmsSEDFwWahKz", new Locale("de", "CH"));
+ assertTrue("Wrong pattern: " + pattern, f.toPattern().equals(pattern));
+
+ pattern = "G y M d Z";
+ f = new SimpleDateFormat(pattern, new Locale("de", "CH"));
+ pattern = f.toPattern();
+ assertTrue("Wrong pattern: " + pattern, f.toPattern().equals(pattern));
+ }
+
+ public void test_toLocalizedPattern() {
+ SimpleDateFormat f2 = new SimpleDateFormat("GyMdkHmsSEDFwWahKzZLc", new Locale("de", "CH"));
+ assertEquals(f2.toPattern(), f2.toLocalizedPattern());
+ }
+
+ public void test_parse_with_spaces() {
+ // Regression for HARMONY-502
+ SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
+ df.setLenient(false);
+
+ char allowed_chars[] = { 0x9, 0x20 };
+ String allowed_char_names[] = { "tab", "space" };
+ for (int i = 0; i < allowed_chars.length; i++) {
+ Date expected = new GregorianCalendar(1970, Calendar.JANUARY, 1, 9, 7, 6).getTime();
+ ParsePosition pp = new ParsePosition(0);
+ Date d = df.parse(allowed_chars[i] + "9:07:06", pp);
+ assertNotNull("hour may be prefixed by " + allowed_char_names[i], d);
+ assertEquals(expected, d);
+
+ pp = new ParsePosition(0);
+ d = df.parse("09:" + allowed_chars[i] + "7:06", pp);
+ assertNotNull("minute may be prefixed by " + allowed_char_names[i], d);
+ assertEquals(expected, d);
+
+ pp = new ParsePosition(0);
+ d = df.parse("09:07:" + allowed_chars[i] + "6", pp);
+ assertNotNull("second may be prefixed by " + allowed_char_names[i], d);
+ assertEquals(expected, d);
+ }
+
+ char not_allowed_chars[] = {
+ // whitespace
+ 0x1c, 0x1d, 0x1e, 0x1f, 0xa, 0xb, 0xc, 0xd, 0x2001, 0x2002,
+ 0x2003, 0x2004, 0x2005, 0x2006, 0x2008, 0x2009, 0x200a, 0x200b,
+ 0x2028, 0x2029, 0x3000,
+ // non-breaking space
+ 0xA0, 0x2007, 0x202F };
+
+ for (int i = 0; i < not_allowed_chars.length; i++) {
+ ParsePosition pp = new ParsePosition(0);
+ Date d = df.parse(not_allowed_chars[i] + "9:07", pp);
+ assertNull(d);
+
+ pp = new ParsePosition(0);
+ d = df.parse("09:" + not_allowed_chars[i] + "7", pp);
+ assertNull(d);
+
+ pp = new ParsePosition(0);
+ d = df.parse("09:07:" + not_allowed_chars[i] + "6", pp);
+ assertNull(d);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/StringCharacterIteratorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/StringCharacterIteratorTest.java
new file mode 100644
index 0000000..0108089
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/StringCharacterIteratorTest.java
@@ -0,0 +1,521 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+
+import junit.framework.TestCase;
+
+public class StringCharacterIteratorTest extends TestCase {
+
+ /**
+ * @tests java.text.StringCharacterIterator.StringCharacterIterator(String,
+ * int)
+ */
+ public void test_ConstructorI() {
+ assertNotNull(new StringCharacterIterator("value", 0));
+ assertNotNull(new StringCharacterIterator("value", "value".length()));
+ assertNotNull(new StringCharacterIterator("", 0));
+ try {
+ new StringCharacterIterator(null, 0);
+ fail("Assert 0: no null pointer");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new StringCharacterIterator("value", -1);
+ fail("Assert 1: no illegal argument");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ new StringCharacterIterator("value", "value".length() + 1);
+ fail("Assert 2: no illegal argument");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator(String, int, int, int)
+ */
+ public void test_ConstructorIII() {
+ assertNotNull(new StringCharacterIterator("value", 0, "value".length(),
+ 0));
+ assertNotNull(new StringCharacterIterator("value", 0, "value".length(),
+ 1));
+ assertNotNull(new StringCharacterIterator("", 0, 0, 0));
+
+ try {
+ new StringCharacterIterator(null, 0, 0, 0);
+ fail("no null pointer");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ new StringCharacterIterator("value", -1, "value".length(), 0);
+ fail("no illegal argument: invalid begin");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ new StringCharacterIterator("value", 0, "value".length() + 1, 0);
+ fail("no illegal argument: invalid end");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ new StringCharacterIterator("value", 2, 1, 0);
+ fail("no illegal argument: start greater than end");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ new StringCharacterIterator("value", 2, 1, 2);
+ fail("no illegal argument: start greater than end");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ new StringCharacterIterator("value", 2, 4, 1);
+ fail("no illegal argument: location greater than start");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ new StringCharacterIterator("value", 0, 2, 3);
+ fail("no illegal argument: location greater than start");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.equals(Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ StringCharacterIterator sci0 = new StringCharacterIterator("fixture");
+ assertEquals(sci0, sci0);
+ assertFalse(sci0.equals(null));
+ assertFalse(sci0.equals("fixture"));
+
+ StringCharacterIterator sci1 = new StringCharacterIterator("fixture");
+ assertEquals(sci0, sci1);
+
+ sci1.next();
+ assertFalse(sci0.equals(sci1));
+ sci0.next();
+ assertEquals(sci0, sci1);
+
+ StringCharacterIterator it1 = new StringCharacterIterator("testing", 2,
+ 6, 4);
+ StringCharacterIterator it2 = new StringCharacterIterator("xxstinx", 2,
+ 6, 4);
+ assertTrue("Range is equal", !it1.equals(it2));
+ StringCharacterIterator it3 = new StringCharacterIterator("testing", 2,
+ 6, 2);
+ it3.setIndex(4);
+ assertTrue("Not equal", it1.equals(it3));
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.clone()
+ */
+ public void test_clone() {
+ StringCharacterIterator sci0 = new StringCharacterIterator("fixture");
+ assertSame(sci0, sci0);
+ StringCharacterIterator sci1 = (StringCharacterIterator) sci0.clone();
+ assertNotSame(sci0, sci1);
+ assertEquals(sci0, sci1);
+
+ StringCharacterIterator it = new StringCharacterIterator("testing", 2,
+ 6, 4);
+ StringCharacterIterator clone = (StringCharacterIterator) it.clone();
+ assertTrue("Clone not equal", it.equals(clone));
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.current()
+ */
+ public void test_current() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ assertEquals('f', fixture.current());
+ fixture.next();
+ assertEquals('i', fixture.current());
+
+ StringCharacterIterator it =
+ new StringCharacterIterator("testing", 2, 6, 4);
+ assertEquals("Wrong current char", 'i', it.current());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.first()
+ */
+ public void test_first() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ assertEquals('f', fixture.first());
+ fixture.next();
+ assertEquals('f', fixture.first());
+ fixture = new StringCharacterIterator("fixture", 1);
+ assertEquals('f', fixture.first());
+ fixture = new StringCharacterIterator("fixture", 1, "fixture".length(),
+ 2);
+ assertEquals('i', fixture.first());
+
+ StringCharacterIterator it1 =
+ new StringCharacterIterator("testing", 2, 6, 4);
+ assertEquals("Wrong first char", 's', it1.first());
+ assertEquals("Wrong next char", 't', it1.next());
+ it1 = new StringCharacterIterator("testing", 2, 2, 2);
+ assertTrue("Not DONE", it1.first() == CharacterIterator.DONE);
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.getBeginIndex()
+ */
+ public void test_getBeginIndex() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ assertEquals(0, fixture.getBeginIndex());
+ fixture = new StringCharacterIterator("fixture", 1);
+ assertEquals(0, fixture.getBeginIndex());
+ fixture = new StringCharacterIterator("fixture", 1, "fixture".length(),
+ 2);
+ assertEquals(1, fixture.getBeginIndex());
+
+ StringCharacterIterator it1 =
+ new StringCharacterIterator("testing", 2, 6, 4);
+ assertEquals("Wrong begin index 2", 2, it1.getBeginIndex());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.getEndIndex()
+ */
+ public void test_getEndIndex() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ assertEquals("fixture".length(), fixture.getEndIndex());
+ fixture = new StringCharacterIterator("fixture", 1);
+ assertEquals("fixture".length(), fixture.getEndIndex());
+ fixture = new StringCharacterIterator("fixture", 1, "fixture".length(),
+ 2);
+ assertEquals("fixture".length(), fixture.getEndIndex());
+ fixture = new StringCharacterIterator("fixture", 1, 4, 2);
+ assertEquals(4, fixture.getEndIndex());
+
+ StringCharacterIterator it1 =
+ new StringCharacterIterator("testing", 2, 6, 4);
+ assertEquals("Wrong end index 6", 6, it1.getEndIndex());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.getIndex()
+ */
+ public void testGetIndex() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ assertEquals(0, fixture.getIndex());
+ fixture = new StringCharacterIterator("fixture", 1);
+ assertEquals(1, fixture.getIndex());
+ fixture = new StringCharacterIterator("fixture", 1, "fixture".length(),
+ 2);
+ assertEquals(2, fixture.getIndex());
+ fixture = new StringCharacterIterator("fixture", 1, 4, 2);
+ assertEquals(2, fixture.getIndex());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.last()
+ */
+ public void testLast() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ assertEquals('e', fixture.last());
+ fixture.next();
+ assertEquals('e', fixture.last());
+ fixture = new StringCharacterIterator("fixture", 1);
+ assertEquals('e', fixture.last());
+ fixture = new StringCharacterIterator("fixture", 1, "fixture".length(),
+ 2);
+ assertEquals('e', fixture.last());
+ fixture = new StringCharacterIterator("fixture", 1, 4, 2);
+ assertEquals('t', fixture.last());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.next()
+ */
+ public void test_next() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ assertEquals(0, fixture.getIndex());
+ assertEquals('i', fixture.next());
+ assertEquals(1, fixture.getIndex());
+ assertEquals('x', fixture.next());
+ assertEquals(2, fixture.getIndex());
+ assertEquals('t', fixture.next());
+ assertEquals(3, fixture.getIndex());
+ assertEquals('u', fixture.next());
+ assertEquals(4, fixture.getIndex());
+ assertEquals('r', fixture.next());
+ assertEquals(5, fixture.getIndex());
+ assertEquals('e', fixture.next());
+ assertEquals(6, fixture.getIndex());
+ assertEquals(CharacterIterator.DONE, fixture.next());
+ assertEquals(7, fixture.getIndex());
+ assertEquals(CharacterIterator.DONE, fixture.next());
+ assertEquals(7, fixture.getIndex());
+ assertEquals(CharacterIterator.DONE, fixture.next());
+ assertEquals(7, fixture.getIndex());
+
+ StringCharacterIterator it1 = new StringCharacterIterator("testing", 2,
+ 6, 3);
+ char result = it1.next();
+ assertEquals("Wrong next char1", 'i', result);
+ assertEquals("Wrong next char2", 'n', it1.next());
+ assertTrue("Wrong next char3", it1.next() == CharacterIterator.DONE);
+ assertTrue("Wrong next char4", it1.next() == CharacterIterator.DONE);
+ int index = it1.getIndex();
+ assertEquals("Wrong index", 6, index);
+ assertTrue("Wrong current char",
+ it1.current() == CharacterIterator.DONE);
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.previous()
+ */
+ public void test_previous() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ assertEquals(CharacterIterator.DONE, fixture.previous());
+ assertEquals('i', fixture.next());
+ assertEquals('x', fixture.next());
+ assertEquals('t', fixture.next());
+ assertEquals('u', fixture.next());
+ assertEquals('r', fixture.next());
+ assertEquals('e', fixture.next());
+ assertEquals(CharacterIterator.DONE, fixture.next());
+ assertEquals(CharacterIterator.DONE, fixture.next());
+ assertEquals(CharacterIterator.DONE, fixture.next());
+ assertEquals(7, fixture.getIndex());
+ assertEquals('e', fixture.previous());
+ assertEquals(6, fixture.getIndex());
+ assertEquals('r', fixture.previous());
+ assertEquals(5, fixture.getIndex());
+ assertEquals('u', fixture.previous());
+ assertEquals(4, fixture.getIndex());
+ assertEquals('t', fixture.previous());
+ assertEquals(3, fixture.getIndex());
+ assertEquals('x', fixture.previous());
+ assertEquals(2, fixture.getIndex());
+ assertEquals('i', fixture.previous());
+ assertEquals(1, fixture.getIndex());
+ assertEquals('f', fixture.previous());
+ assertEquals(0, fixture.getIndex());
+ assertEquals(CharacterIterator.DONE, fixture.previous());
+ assertEquals(0, fixture.getIndex());
+
+ StringCharacterIterator it1 =
+ new StringCharacterIterator("testing", 2, 6, 4);
+ assertEquals("Wrong previous char1", 't', it1.previous());
+ assertEquals("Wrong previous char2", 's', it1.previous());
+ assertTrue("Wrong previous char3",
+ it1.previous() == CharacterIterator.DONE);
+ assertTrue("Wrong previous char4",
+ it1.previous() == CharacterIterator.DONE);
+ assertEquals("Wrong index", 2, it1.getIndex());
+ assertEquals("Wrong current char", 's', it1.current());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.setIndex(int)
+ */
+ public void test_setIndex() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ while (fixture.next() != CharacterIterator.DONE) {
+ // empty
+ }
+ assertEquals("fixture".length(), fixture.getIndex());
+ fixture.setIndex(0);
+ assertEquals(0, fixture.getIndex());
+ assertEquals('f', fixture.current());
+ fixture.setIndex("fixture".length() - 1);
+ assertEquals('e', fixture.current());
+ try {
+ fixture.setIndex(-1);
+ fail("no illegal argument");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ fixture.setIndex("fixture".length() + 1);
+ fail("no illegal argument");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator.setText(String)
+ */
+ public void test_setText() {
+ StringCharacterIterator fixture = new StringCharacterIterator("fixture");
+ fixture.setText("fix");
+ assertEquals('f', fixture.current());
+ assertEquals('x', fixture.last());
+
+ try {
+ fixture.setText(null);
+ fail("no null pointer");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator#StringCharacterIterator(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ assertNotNull(new StringCharacterIterator("value"));
+ assertNotNull(new StringCharacterIterator(""));
+ try {
+ new StringCharacterIterator(null);
+ fail("Assert 0: no null pointer");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ StringCharacterIterator it = new StringCharacterIterator("testing");
+ assertEquals("Wrong begin index", 0, it.getBeginIndex());
+ assertEquals("Wrong end index", 7, it.getEndIndex());
+ assertEquals("Wrong current index", 0, it.getIndex());
+ assertEquals("Wrong current char", 't', it.current());
+ assertEquals("Wrong next char", 'e', it.next());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator#StringCharacterIterator(java.lang.String,
+ * int)
+ */
+ public void test_ConstructorLjava_lang_StringI() {
+ StringCharacterIterator it = new StringCharacterIterator("testing", 3);
+ assertEquals("Wrong begin index", 0, it.getBeginIndex());
+ assertEquals("Wrong end index", 7, it.getEndIndex());
+ assertEquals("Wrong current index", 3, it.getIndex());
+ assertEquals("Wrong current char", 't', it.current());
+ assertEquals("Wrong next char", 'i', it.next());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator#StringCharacterIterator(java.lang.String,
+ * int, int, int)
+ */
+ public void test_ConstructorLjava_lang_StringIII() {
+ StringCharacterIterator it = new StringCharacterIterator("testing", 2,
+ 6, 4);
+ assertEquals("Wrong begin index", 2, it.getBeginIndex());
+ assertEquals("Wrong end index", 6, it.getEndIndex());
+ assertEquals("Wrong current index", 4, it.getIndex());
+ assertEquals("Wrong current char", 'i', it.current());
+ assertEquals("Wrong next char", 'n', it.next());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator#getIndex()
+ */
+ public void test_getIndex() {
+ StringCharacterIterator it1 = new StringCharacterIterator("testing", 2,
+ 6, 4);
+ assertEquals("Wrong index 4", 4, it1.getIndex());
+ it1.next();
+ assertEquals("Wrong index 5", 5, it1.getIndex());
+ it1.last();
+ assertEquals("Wrong index 4/2", 5, it1.getIndex());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator#hashCode()
+ */
+ public void test_hashCode() {
+ StringCharacterIterator it1 = new StringCharacterIterator("testing", 2,
+ 6, 4);
+ StringCharacterIterator it2 = new StringCharacterIterator("xxstinx", 2,
+ 6, 4);
+ assertTrue("Hash is equal", it1.hashCode() != it2.hashCode());
+ StringCharacterIterator it3 = new StringCharacterIterator("testing", 2,
+ 6, 2);
+ assertTrue("Hash equal1", it1.hashCode() != it3.hashCode());
+ it3 = new StringCharacterIterator("testing", 0, 6, 4);
+ assertTrue("Hash equal2", it1.hashCode() != it3.hashCode());
+ it3 = new StringCharacterIterator("testing", 2, 5, 4);
+ assertTrue("Hash equal3", it1.hashCode() != it3.hashCode());
+ it3 = new StringCharacterIterator("froging", 2, 6, 4);
+ assertTrue("Hash equal4", it1.hashCode() != it3.hashCode());
+
+ StringCharacterIterator sci0 = new StringCharacterIterator("fixture");
+ assertEquals(sci0.hashCode(), sci0.hashCode());
+
+ StringCharacterIterator sci1 = new StringCharacterIterator("fixture");
+ assertEquals(sci0.hashCode(), sci1.hashCode());
+
+ sci1.next();
+ sci0.next();
+ assertEquals(sci0.hashCode(), sci1.hashCode());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator#last()
+ */
+ public void test_last() {
+ StringCharacterIterator it1 = new StringCharacterIterator("testing", 2,
+ 6, 3);
+ assertEquals("Wrong last char", 'n', it1.last());
+ assertEquals("Wrong previous char", 'i', it1.previous());
+ it1 = new StringCharacterIterator("testing", 2, 2, 2);
+ assertTrue("Not DONE", it1.last() == CharacterIterator.DONE);
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator#setIndex(int)
+ */
+ public void test_setIndexI() {
+ StringCharacterIterator it1 = new StringCharacterIterator("testing", 2,
+ 6, 4);
+ assertEquals("Wrong result1", 's', it1.setIndex(2));
+ char result = it1.next();
+ assertTrue("Wrong next char: " + result, result == 't');
+ assertTrue("Wrong result2", it1.setIndex(6) == CharacterIterator.DONE);
+ assertEquals("Wrong previous char", 'n', it1.previous());
+ }
+
+ /**
+ * @tests java.text.StringCharacterIterator#setText(java.lang.String)
+ */
+ public void test_setTextLjava_lang_String() {
+ StringCharacterIterator it1 = new StringCharacterIterator("testing", 2,
+ 6, 4);
+ it1.setText("frog");
+ assertEquals("Wrong begin index", 0, it1.getBeginIndex());
+ assertEquals("Wrong end index", 4, it1.getEndIndex());
+ assertEquals("Wrong current index", 0, it1.getIndex());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_DecimalFormat.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_DecimalFormat.java
new file mode 100644
index 0000000..0c6a824
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_DecimalFormat.java
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Locale;
+import java.util.Vector;
+
+public class Support_DecimalFormat extends Support_Format {
+
+ public Support_DecimalFormat(String p1) {
+ super(p1);
+ }
+
+ @Override public void runTest() {
+ t_formatToCharacterIterator();
+ t_format_with_FieldPosition();
+ }
+
+ public static void main(String[] args) {
+ new Support_DecimalFormat("").runTest();
+ }
+
+ public void t_format_with_FieldPosition() {
+ DecimalFormat format = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.US);
+ Number number = new Double(10000000.76);
+ String text = "$10,000,000.76";
+
+ t_FormatWithField(0, format, number, text, NumberFormat.Field.CURRENCY, 0, 1);
+ t_FormatWithField(1, format, number, text, NumberFormat.Field.INTEGER, 1, 11);
+ t_FormatWithField(2, format, number, text, NumberFormat.Field.GROUPING_SEPARATOR, 3, 4);
+ t_FormatWithField(3, format, number, text, NumberFormat.Field.DECIMAL_SEPARATOR, 11, 12);
+ t_FormatWithField(4, format, number, text, NumberFormat.Field.FRACTION, 12, 14);
+
+ // test fields that are not included in the formatted text
+ t_FormatWithField(5, format, number, text, NumberFormat.Field.SIGN, 0, 0);
+ t_FormatWithField(6, format, number, text, NumberFormat.Field.EXPONENT, 0, 0);
+ t_FormatWithField(7, format, number, text, NumberFormat.Field.EXPONENT_SIGN, 0, 0);
+ t_FormatWithField(8, format, number, text, NumberFormat.Field.EXPONENT_SYMBOL, 0, 0);
+ t_FormatWithField(9, format, number, text, NumberFormat.Field.PERCENT, 0, 0);
+ t_FormatWithField(10, format, number, text, NumberFormat.Field.PERMILLE, 0, 0);
+
+ // test Exponential
+ format = new DecimalFormat("000000000.0#E0");
+ text = "100000007.6E-1";
+ t_FormatWithField(11, format, number, text, NumberFormat.Field.INTEGER, 0, 9);
+ t_FormatWithField(12, format, number, text, NumberFormat.Field.DECIMAL_SEPARATOR, 9, 10);
+ t_FormatWithField(13, format, number, text, NumberFormat.Field.FRACTION, 10, 11);
+ t_FormatWithField(14, format, number, text, NumberFormat.Field.EXPONENT_SYMBOL, 11, 12);
+ t_FormatWithField(15, format, number, text, NumberFormat.Field.EXPONENT_SIGN, 12, 13);
+ t_FormatWithField(16, format, number, text, NumberFormat.Field.EXPONENT, 13, 14);
+
+ // test fields that are not included in the formatted text
+ t_FormatWithField(17, format, number, text, NumberFormat.Field.GROUPING_SEPARATOR, 0, 0);
+ t_FormatWithField(18, format, number, text, NumberFormat.Field.SIGN, 0, 0);
+ t_FormatWithField(19, format, number, text, NumberFormat.Field.CURRENCY, 0, 0);
+ t_FormatWithField(20, format, number, text, NumberFormat.Field.PERCENT, 0, 0);
+ t_FormatWithField(21, format, number, text, NumberFormat.Field.PERMILLE, 0, 0);
+
+ // test currency instance with TR Locale
+ number = new Double(350.76);
+ format = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("tr", "TR"));
+ // Turkey either uses "123,45 TL" or "₺123,45"; google3 uses the former because most
+ // platforms' fonts don't include U+20BA TURKISH LIRA SIGN. http://b/16727554.
+ text = "₺350,76";
+ t_FormatWithField(23, format, number, text, NumberFormat.Field.CURRENCY, 0, 1);
+ t_FormatWithField(22, format, number, text, NumberFormat.Field.INTEGER, 1, 4);
+ t_FormatWithField(22, format, number, text, NumberFormat.Field.DECIMAL_SEPARATOR, 4, 5);
+ t_FormatWithField(22, format, number, text, NumberFormat.Field.FRACTION, 5, 7);
+
+ // test fields that are not included in the formatted text
+ t_FormatWithField(25, format, number, text, NumberFormat.Field.GROUPING_SEPARATOR, 0, 0);
+ t_FormatWithField(27, format, number, text, NumberFormat.Field.SIGN, 0, 0);
+ t_FormatWithField(28, format, number, text, NumberFormat.Field.EXPONENT, 0, 0);
+ t_FormatWithField(29, format, number, text, NumberFormat.Field.EXPONENT_SIGN, 0, 0);
+ t_FormatWithField(30, format, number, text, NumberFormat.Field.EXPONENT_SYMBOL, 0, 0);
+ t_FormatWithField(31, format, number, text, NumberFormat.Field.PERCENT, 0, 0);
+ t_FormatWithField(32, format, number, text, NumberFormat.Field.PERMILLE, 0, 0);
+ }
+
+ public void t_formatToCharacterIterator() {
+ Number number = new Double(350.76);
+ Number negativeNumber = new Double(-350.76);
+
+ Locale us = Locale.US;
+ Locale tr = new Locale("tr", "TR");
+
+ // test number instance
+ t_Format(1, number, NumberFormat.getNumberInstance(us), getNumberVectorUS());
+
+ // test integer instance
+ // testFormat(2, number, NumberFormat.getIntegerInstance(us),
+ // getPercentVectorUS());
+
+ // test percent instance
+ t_Format(3, number, NumberFormat.getPercentInstance(us), getPercentVectorUS());
+
+ // test permille pattern
+ DecimalFormat format = new DecimalFormat("###0.##\u2030");
+ t_Format(4, number, format, getPermilleVector());
+
+ // test exponential pattern with positive exponent
+ format = new DecimalFormat("00.0#E0");
+ t_Format(5, number, format, getPositiveExponentVector());
+
+ // test exponential pattern with negative exponent
+ format = new DecimalFormat("0000.0#E0");
+ t_Format(6, number, format, getNegativeExponentVector());
+
+ // test currency instance with US Locale
+ t_Format(7, number, NumberFormat.getCurrencyInstance(us), getPositiveCurrencyVectorUS());
+
+ // test negative currency instance with US Locale
+ t_Format(8, negativeNumber, NumberFormat.getCurrencyInstance(us), getNegativeCurrencyVectorUS());
+
+ // test currency instance with TR Locale
+ t_Format(9, number, NumberFormat.getCurrencyInstance(tr), getPositiveCurrencyVectorTR());
+
+ // test negative currency instance with TR Locale
+ t_Format(10, negativeNumber, NumberFormat.getCurrencyInstance(tr), getNegativeCurrencyVectorTR());
+
+ // test multiple grouping separators
+ number = new Long(100300400);
+ t_Format(11, number, NumberFormat.getNumberInstance(us), getNumberVector2US());
+
+ // test 0
+ number = new Long(0);
+ t_Format(12, number, NumberFormat.getNumberInstance(us), getZeroVector());
+ }
+
+ private static Vector<FieldContainer> getNumberVectorUS() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 3, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(3, 4, NumberFormat.Field.DECIMAL_SEPARATOR));
+ v.add(new FieldContainer(4, 6, NumberFormat.Field.FRACTION));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getPositiveCurrencyVectorTR() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 1, NumberFormat.Field.CURRENCY));
+ v.add(new FieldContainer(1, 4, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(4, 5, NumberFormat.Field.DECIMAL_SEPARATOR));
+ v.add(new FieldContainer(5, 7, NumberFormat.Field.FRACTION));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getNegativeCurrencyVectorTR() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 1, NumberFormat.Field.SIGN));
+ v.add(new FieldContainer(1, 2, NumberFormat.Field.CURRENCY));
+ v.add(new FieldContainer(2, 5, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(5, 6, NumberFormat.Field.DECIMAL_SEPARATOR));
+ v.add(new FieldContainer(6, 8, NumberFormat.Field.FRACTION));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getPositiveCurrencyVectorUS() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 1, NumberFormat.Field.CURRENCY));
+ v.add(new FieldContainer(1, 4, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(4, 5, NumberFormat.Field.DECIMAL_SEPARATOR));
+ v.add(new FieldContainer(5, 7, NumberFormat.Field.FRACTION));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getNegativeCurrencyVectorUS() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 1, NumberFormat.Field.SIGN));
+ v.add(new FieldContainer(1, 2, NumberFormat.Field.CURRENCY));
+ v.add(new FieldContainer(2, 5, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(5, 6, NumberFormat.Field.DECIMAL_SEPARATOR));
+ v.add(new FieldContainer(6, 8, NumberFormat.Field.FRACTION));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getPercentVectorUS() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 2, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(2, 3, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(2, 3, NumberFormat.Field.GROUPING_SEPARATOR));
+ v.add(new FieldContainer(3, 6, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(6, 7, NumberFormat.Field.PERCENT));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getPermilleVector() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 6, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(6, 7, NumberFormat.Field.PERMILLE));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getNegativeExponentVector() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 4, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(4, 5, NumberFormat.Field.DECIMAL_SEPARATOR));
+ v.add(new FieldContainer(5, 6, NumberFormat.Field.FRACTION));
+ v.add(new FieldContainer(6, 7, NumberFormat.Field.EXPONENT_SYMBOL));
+ v.add(new FieldContainer(7, 8, NumberFormat.Field.EXPONENT_SIGN));
+ v.add(new FieldContainer(8, 9, NumberFormat.Field.EXPONENT));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getPositiveExponentVector() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 2, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(2, 3, NumberFormat.Field.DECIMAL_SEPARATOR));
+ v.add(new FieldContainer(3, 5, NumberFormat.Field.FRACTION));
+ v.add(new FieldContainer(5, 6, NumberFormat.Field.EXPONENT_SYMBOL));
+ v.add(new FieldContainer(6, 7, NumberFormat.Field.EXPONENT));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getNumberVector2US() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 3, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(3, 4, NumberFormat.Field.GROUPING_SEPARATOR));
+ v.add(new FieldContainer(3, 4, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(4, 7, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(7, 8, NumberFormat.Field.GROUPING_SEPARATOR));
+ v.add(new FieldContainer(7, 8, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(8, 11, NumberFormat.Field.INTEGER));
+ return v;
+ }
+
+ private static Vector<FieldContainer> getZeroVector() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 1, NumberFormat.Field.INTEGER));
+ return v;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_Format.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_Format.java
new file mode 100644
index 0000000..493e27e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_Format.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.AttributedCharacterIterator;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Vector;
+import junit.framework.TestCase;
+
+public class Support_Format extends TestCase {
+
+ protected String text;
+
+ public Support_Format(String p1) {
+ super(p1);
+ }
+
+ protected void t_FormatWithField(int count, Format format, Object object,
+ String text, Format.Field field, int begin, int end) {
+ StringBuffer buffer = new StringBuffer();
+ FieldPosition pos = new FieldPosition(field);
+ format.format(object, buffer, pos);
+
+ // System.out.println(buffer);
+ // System.out.println(pos);
+
+ if (text == null) {
+ assertEquals("Test " + count + ": incorrect formatted text", this.text, buffer.toString());
+ } else {
+ assertEquals(text, buffer.toString());
+ }
+
+ if (begin != pos.getBeginIndex() || end != pos.getEndIndex()) {
+ assertEquals(field + " " + begin + ".." + end,
+ pos.getFieldAttribute() + " " + pos.getBeginIndex() + ".." + pos.getEndIndex());
+ }
+ }
+
+ protected void t_Format(int count, Object object, Format format, Vector<FieldContainer> expectedResults) {
+ Vector<FieldContainer> results = findFields(format.formatToCharacterIterator(object));
+ assertEquals("size mismatch\n" +
+ format.format(object) + "\n" +
+ "expectedResults=" + expectedResults + "\n" +
+ " results=" + results, expectedResults.size(), results.size());
+ for (int i = 0; i < results.size(); ++i) {
+ if (!results.contains(expectedResults.get(i))) {
+ fail("didn't find expected result " + expectedResults.get(i) + "\n" +
+ "expectedResults=" + expectedResults + "\n" +
+ " results=" + results);
+ }
+ }
+ }
+
+ /**
+ * finds attributes with regards to char index in this
+ * AttributedCharacterIterator, and puts them in a vector
+ *
+ * @param iterator
+ * @return a vector, each entry in this vector are of type FieldContainer,
+ * which stores start and end indexes and an attribute this range has
+ */
+ protected static Vector<FieldContainer> findFields(AttributedCharacterIterator iterator) {
+ Vector<FieldContainer> result = new Vector<FieldContainer>();
+ while (iterator.getIndex() != iterator.getEndIndex()) {
+ int start = iterator.getRunStart();
+ int end = iterator.getRunLimit();
+
+ Iterator<Attribute> it = iterator.getAttributes().keySet().iterator();
+ while (it.hasNext()) {
+ AttributedCharacterIterator.Attribute attribute = it.next();
+ Object value = iterator.getAttribute(attribute);
+ result.add(new FieldContainer(start, end, attribute, value));
+ // System.out.println(start + " " + end + ": " + attribute + ",
+ // " + value );
+ // System.out.println("v.add(new FieldContainer(" + start +"," +
+ // end +"," + attribute+ "," + value+ "));");
+ }
+ iterator.setIndex(end);
+ }
+ return result;
+ }
+
+ static class FieldContainer {
+ final int start;
+ final int end;
+ final Attribute attribute;
+ final Object value;
+
+ // called from Support_DecimalFormat and Support_SimpleDateFormat tests
+ public FieldContainer(int start, int end, Attribute attribute) {
+ this(start, end, attribute, attribute);
+ }
+
+ // called from Support_MessageFormat tests
+ public FieldContainer(int start, int end, Attribute attribute, int value) {
+ this(start, end, attribute, new Integer(value));
+ }
+
+ // called from Support_MessageFormat tests
+ public FieldContainer(int start, int end, Attribute attribute, Object value) {
+ this.start = start;
+ this.end = end;
+ this.attribute = attribute;
+ this.value = value;
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (!(obj instanceof FieldContainer)) {
+ return false;
+ }
+
+ FieldContainer fc = (FieldContainer) obj;
+ return (start == fc.start && end == fc.end && attribute == fc.attribute && value.equals(fc.value));
+ }
+
+ @Override public String toString() {
+ return "FC[" + start + ".." + end + ",attribute=" + attribute + ",value=" + value + "]";
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_MessageFormat.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_MessageFormat.java
new file mode 100644
index 0000000..8003b88
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_MessageFormat.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.NumberFormat;
+import java.text.MessageFormat.Field;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.Vector;
+
+
+public class Support_MessageFormat extends Support_Format {
+
+ public Support_MessageFormat(String p1) {
+ super(p1);
+ }
+
+ @Override
+ public void runTest() {
+ t_formatToCharacterIterator();
+ t_format_with_FieldPosition();
+ }
+
+ public static void main(String[] args) {
+ new Support_MessageFormat("").runTest();
+ }
+
+ public void t_format_with_FieldPosition() {
+
+ String pattern = "On {4,date} at {3,time}, he ate {2,number, integer} hamburger{2,choice,1#|1<s} and drank {1, number} liters of coke. That was {0,choice,1#just enough|1<more than enough} food!";
+ MessageFormat format = new MessageFormat(pattern, Locale.US);
+
+ Date date = new GregorianCalendar(2005, 1, 28, 14, 20, 16).getTime();
+ Integer hamburgers = new Integer(8);
+ Object[] objects = new Object[] { hamburgers, new Double(3.5),
+ hamburgers, date, date };
+
+ super.text = "On Feb 28, 2005 at 2:20:16 PM, he ate 8 hamburgers and drank 3.5 liters of coke. That was more than enough food!";
+
+ // test with MessageFormat.Field.ARGUMENT
+ t_FormatWithField(1, format, objects, null, Field.ARGUMENT, 3, 15);
+
+ // test other format fields that are included in the formatted text
+ t_FormatWithField(2, format, objects, null, DateFormat.Field.AM_PM, 0,
+ 0);
+ t_FormatWithField(3, format, objects, null,
+ NumberFormat.Field.FRACTION, 0, 0);
+
+ // test fields that are not included in the formatted text
+ t_FormatWithField(4, format, objects, null, DateFormat.Field.ERA, 0, 0);
+ t_FormatWithField(5, format, objects, null,
+ NumberFormat.Field.EXPONENT_SIGN, 0, 0);
+ }
+
+ public void t_formatToCharacterIterator() {
+ String pattern = "On {4,date} at {3,time}, he ate {2,number, integer} hamburger{2,choice,1#|1<s} and drank {1, number} liters of coke. That was {0,choice,1#just enough|1<more than enough} food!";
+ MessageFormat format = new MessageFormat(pattern, Locale.US);
+
+ Date date = new GregorianCalendar(2005, 1, 28, 14, 20, 16).getTime();
+ Integer hamburgers = new Integer(8);
+ Object[] objects = new Object[] { hamburgers, new Double(3.5), hamburgers, date, date };
+
+ t_Format(1, objects, format, getMessageVector1());
+ }
+
+ private Vector<FieldContainer> getMessageVector1() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(3, 6, DateFormat.Field.MONTH));
+ v.add(new FieldContainer(3, 6, Field.ARGUMENT, 4));
+ v.add(new FieldContainer(6, 7, Field.ARGUMENT, 4));
+ v.add(new FieldContainer(7, 9, DateFormat.Field.DAY_OF_MONTH));
+ v.add(new FieldContainer(7, 9, Field.ARGUMENT, 4));
+ v.add(new FieldContainer(9, 11, Field.ARGUMENT, 4));
+ v.add(new FieldContainer(11, 15, DateFormat.Field.YEAR));
+ v.add(new FieldContainer(11, 15, Field.ARGUMENT, 4));
+ v.add(new FieldContainer(19, 20, DateFormat.Field.HOUR1));
+ v.add(new FieldContainer(19, 20, Field.ARGUMENT, 3));
+ v.add(new FieldContainer(20, 21, Field.ARGUMENT, 3));
+ v.add(new FieldContainer(21, 23, DateFormat.Field.MINUTE));
+ v.add(new FieldContainer(21, 23, Field.ARGUMENT, 3));
+ v.add(new FieldContainer(23, 24, Field.ARGUMENT, 3));
+ v.add(new FieldContainer(24, 26, DateFormat.Field.SECOND));
+ v.add(new FieldContainer(24, 26, Field.ARGUMENT, 3));
+ v.add(new FieldContainer(26, 27, Field.ARGUMENT, 3));
+ v.add(new FieldContainer(27, 29, DateFormat.Field.AM_PM));
+ v.add(new FieldContainer(27, 29, Field.ARGUMENT, 3));
+ v.add(new FieldContainer(38, 39, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(38, 39, Field.ARGUMENT, 2));
+ v.add(new FieldContainer(49, 50, Field.ARGUMENT, 2));
+ v.add(new FieldContainer(61, 62, NumberFormat.Field.INTEGER));
+ v.add(new FieldContainer(61, 62, Field.ARGUMENT, 1));
+ v.add(new FieldContainer(62, 63, NumberFormat.Field.DECIMAL_SEPARATOR));
+ v.add(new FieldContainer(62, 63, Field.ARGUMENT, 1));
+ v.add(new FieldContainer(63, 64, NumberFormat.Field.FRACTION));
+ v.add(new FieldContainer(63, 64, Field.ARGUMENT, 1));
+ v.add(new FieldContainer(90, 106, Field.ARGUMENT, 0));
+ return v;
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_SimpleDateFormat.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_SimpleDateFormat.java
new file mode 100644
index 0000000..d050e83
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/Support_SimpleDateFormat.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.text;
+
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.text.DateFormat.Field;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.Vector;
+
+import org.apache.harmony.tests.java.text.Support_Format.FieldContainer;
+
+public class Support_SimpleDateFormat extends Support_Format {
+
+ public Support_SimpleDateFormat(String p1) {
+ super(p1);
+ }
+
+ @Override public void runTest() {
+ t_formatToCharacterIterator();
+ t_format_with_FieldPosition();
+ }
+
+ public static void main(String[] args) {
+ new Support_SimpleDateFormat("").runTest();
+ }
+
+ public void t_format_with_FieldPosition() {
+ TimeZone tz = TimeZone.getTimeZone("EST");
+ Calendar cal = new GregorianCalendar(tz);
+ cal.set(1999, Calendar.SEPTEMBER, 13, 17, 19, 01);
+ cal.set(Calendar.MILLISECOND, 0);
+ Date date = cal.getTime();
+ SimpleDateFormat format = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US);
+ format.setTimeZone(tz);
+
+ // test with all pattern chars, and multiple occurences
+ format.applyPattern("G GGGG y yy yyyy M MM MMM MMMM d dd ddd " +
+ "k kk kkk H HH HHH h hh hhh m mmm s ss sss S SS SSS EE EEEE " +
+ "D DD DDD F FF w www W WWW " +
+ "a aaa K KKK z zzzz Z ZZZZ");
+
+ StringBuffer textBuffer = new StringBuffer();
+ // Really, GGGG should be "Anno Domini", but the RI doesn't support that and no one cares.
+ textBuffer.append("AD AD 1999 99 1999 9 09 Sep September 13 13 013 ");
+ textBuffer.append("17 17 017 17 17 017 5 05 005 19 019 1 01 001 0 00 000 Mon Monday ");
+ textBuffer.append("256 256 256 2 02 38 038 3 003 ");
+ textBuffer.append("PM PM 5 005 GMT-05:00 GMT-05:00 -0500 GMT-05:00");
+
+ // to avoid passing the huge StringBuffer each time.
+ super.text = textBuffer.toString();
+
+ // test if field positions are set correctly for these fields occurring
+ // multiple times.
+ t_FormatWithField(0, format, date, null, Field.ERA, 0, 2);
+ t_FormatWithField(1, format, date, null, Field.YEAR, 6, 10);
+ t_FormatWithField(2, format, date, null, Field.MONTH, 19, 20);
+ t_FormatWithField(3, format, date, null, Field.DAY_OF_MONTH, 38, 40);
+ t_FormatWithField(4, format, date, null, Field.HOUR_OF_DAY1, 48, 50);
+ t_FormatWithField(5, format, date, null, Field.HOUR_OF_DAY0, 58, 60);
+ t_FormatWithField(6, format, date, null, Field.HOUR1, 68, 69);
+ t_FormatWithField(7, format, date, null, Field.MINUTE, 77, 79);
+ t_FormatWithField(8, format, date, null, Field.SECOND, 84, 85);
+ t_FormatWithField(9, format, date, null, Field.MILLISECOND, 93, 94);
+ t_FormatWithField(10, format, date, null, Field.DAY_OF_WEEK, 102, 105);
+ t_FormatWithField(11, format, date, null, Field.DAY_OF_YEAR, 113, 116);
+ t_FormatWithField(12, format, date, null, Field.DAY_OF_WEEK_IN_MONTH, 125, 126);
+ t_FormatWithField(13, format, date, null, Field.WEEK_OF_YEAR, 130, 132);
+ t_FormatWithField(14, format, date, null, Field.WEEK_OF_MONTH, 137, 138);
+ t_FormatWithField(15, format, date, null, Field.AM_PM, 143, 145);
+ t_FormatWithField(16, format, date, null, Field.HOUR0, 151, 152);
+ t_FormatWithField(17, format, date, null, Field.TIME_ZONE, 157, 166);
+
+ // test fields that are not included in the formatted text
+ t_FormatWithField(18, format, date, null, NumberFormat.Field.EXPONENT_SIGN, 0, 0);
+
+ // test with simple example
+ format.applyPattern("h:m z");
+
+ super.text = "5:19 GMT-05:00";
+ t_FormatWithField(21, format, date, null, Field.HOUR1, 0, 1);
+ t_FormatWithField(22, format, date, null, Field.MINUTE, 2, 4);
+ t_FormatWithField(23, format, date, null, Field.TIME_ZONE, 5, 14);
+
+ // test fields that are not included in the formatted text
+ t_FormatWithField(24, format, date, null, Field.ERA, 0, 0);
+ t_FormatWithField(25, format, date, null, Field.YEAR, 0, 0);
+ t_FormatWithField(26, format, date, null, Field.MONTH, 0, 0);
+ t_FormatWithField(27, format, date, null, Field.DAY_OF_MONTH, 0, 0);
+ t_FormatWithField(28, format, date, null, Field.HOUR_OF_DAY1, 0, 0);
+ t_FormatWithField(29, format, date, null, Field.HOUR_OF_DAY0, 0, 0);
+ t_FormatWithField(30, format, date, null, Field.SECOND, 0, 0);
+ t_FormatWithField(31, format, date, null, Field.MILLISECOND, 0, 0);
+ t_FormatWithField(32, format, date, null, Field.DAY_OF_WEEK, 0, 0);
+ t_FormatWithField(33, format, date, null, Field.DAY_OF_YEAR, 0, 0);
+ t_FormatWithField(34, format, date, null, Field.DAY_OF_WEEK_IN_MONTH, 0, 0);
+ t_FormatWithField(35, format, date, null, Field.WEEK_OF_YEAR, 0, 0);
+ t_FormatWithField(36, format, date, null, Field.WEEK_OF_MONTH, 0, 0);
+ t_FormatWithField(37, format, date, null, Field.AM_PM, 0, 0);
+ t_FormatWithField(38, format, date, null, Field.HOUR0, 0, 0);
+
+ t_FormatWithField(39, format, date, null, NumberFormat.Field.EXPONENT, 0, 0);
+
+ // test with simple example with pattern char Z
+ format.applyPattern("h:m Z z");
+ super.text = "5:19 -0500 GMT-05:00";
+ t_FormatWithField(40, format, date, null, Field.HOUR1, 0, 1);
+ t_FormatWithField(41, format, date, null, Field.MINUTE, 2, 4);
+ t_FormatWithField(42, format, date, null, Field.TIME_ZONE, 5, 10);
+ }
+
+ public void t_formatToCharacterIterator() {
+ TimeZone tz = TimeZone.getTimeZone("EST");
+ Calendar cal = new GregorianCalendar(tz);
+ cal.set(1999, Calendar.SEPTEMBER, 13, 17, 19, 01);
+ cal.set(Calendar.MILLISECOND, 0);
+ Date date = cal.getTime();
+ SimpleDateFormat format = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US);
+ format.setTimeZone(tz);
+
+ format.applyPattern("yyyyMMddHHmmss");
+ t_Format(1, date, format, getDateVector1());
+
+ format.applyPattern("w W dd MMMM yyyy EEEE");
+ t_Format(2, date, format, getDateVector2());
+
+ format.applyPattern("h:m z");
+ t_Format(3, date, format, getDateVector3());
+
+ format.applyPattern("h:m Z");
+ t_Format(5, date, format, getDateVector5());
+
+ // with all pattern chars, and multiple occurences
+ format.applyPattern("G GGGG y yy yyyy M MM MMM MMMM d dd ddd k kk kkk H HH HHH h hh hhh m mmm s ss sss S SS SSS EE EEEE D DD DDD F FF w www W WWW a aaa K KKK z zzzz Z ZZZZ");
+ t_Format(4, date, format, getDateVector4());
+ }
+
+ private Vector<FieldContainer> getDateVector1() {
+ // "19990913171901"
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 4, Field.YEAR));
+ v.add(new FieldContainer(4, 6, Field.MONTH));
+ v.add(new FieldContainer(6, 8, Field.DAY_OF_MONTH));
+ v.add(new FieldContainer(8, 10, Field.HOUR_OF_DAY0));
+ v.add(new FieldContainer(10, 12, Field.MINUTE));
+ v.add(new FieldContainer(12, 14, Field.SECOND));
+ return v;
+ }
+
+ private Vector<FieldContainer> getDateVector2() {
+ // "12 3 5 March 2002 Monday"
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 2, Field.WEEK_OF_YEAR));
+ v.add(new FieldContainer(3, 4, Field.WEEK_OF_MONTH));
+ v.add(new FieldContainer(5, 7, Field.DAY_OF_MONTH));
+ v.add(new FieldContainer(8, 17, Field.MONTH));
+ v.add(new FieldContainer(18, 22, Field.YEAR));
+ v.add(new FieldContainer(23, 29, Field.DAY_OF_WEEK));
+ return v;
+ }
+
+ private Vector<FieldContainer> getDateVector3() {
+ // "5:19 EDT"
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 1, Field.HOUR1));
+ v.add(new FieldContainer(2, 4, Field.MINUTE));
+ v.add(new FieldContainer(5, 14, Field.TIME_ZONE));
+ return v;
+ }
+
+ private Vector<FieldContainer> getDateVector5() {
+ // "5:19 -0400"
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+ v.add(new FieldContainer(0, 1, Field.HOUR1));
+ v.add(new FieldContainer(2, 4, Field.MINUTE));
+ v.add(new FieldContainer(5, 10, Field.TIME_ZONE));
+ return v;
+ }
+
+ private Vector<FieldContainer> getDateVector4() {
+ Vector<FieldContainer> v = new Vector<FieldContainer>();
+
+ // "AD AD 1999 99 1999 9 09 Sep September 13 13 013 17 17 017 17 17 017 5
+ // 05
+ // 005 19 019 1 01 001 0 00 000 Mon Monday 256 256 256 2 02 38 038 3 003
+ // PM
+ // PM 5 005 EDT Eastern Daylight Time -0400 -0400"
+ v.add(new FieldContainer(0, 2, Field.ERA));
+ v.add(new FieldContainer(3, 5, Field.ERA));
+ v.add(new FieldContainer(6, 10, Field.YEAR));
+ v.add(new FieldContainer(11, 13, Field.YEAR));
+ v.add(new FieldContainer(14, 18, Field.YEAR));
+ v.add(new FieldContainer(19, 20, Field.MONTH));
+ v.add(new FieldContainer(21, 23, Field.MONTH));
+ v.add(new FieldContainer(24, 27, Field.MONTH));
+ v.add(new FieldContainer(28, 37, Field.MONTH));
+ v.add(new FieldContainer(38, 40, Field.DAY_OF_MONTH));
+ v.add(new FieldContainer(41, 43, Field.DAY_OF_MONTH));
+ v.add(new FieldContainer(44, 47, Field.DAY_OF_MONTH));
+ v.add(new FieldContainer(48, 50, Field.HOUR_OF_DAY1));
+ v.add(new FieldContainer(51, 53, Field.HOUR_OF_DAY1));
+ v.add(new FieldContainer(54, 57, Field.HOUR_OF_DAY1));
+ v.add(new FieldContainer(58, 60, Field.HOUR_OF_DAY0));
+ v.add(new FieldContainer(61, 63, Field.HOUR_OF_DAY0));
+ v.add(new FieldContainer(64, 67, Field.HOUR_OF_DAY0));
+ v.add(new FieldContainer(68, 69, Field.HOUR1));
+ v.add(new FieldContainer(70, 72, Field.HOUR1));
+ v.add(new FieldContainer(73, 76, Field.HOUR1));
+ v.add(new FieldContainer(77, 79, Field.MINUTE));
+ v.add(new FieldContainer(80, 83, Field.MINUTE));
+ v.add(new FieldContainer(84, 85, Field.SECOND));
+ v.add(new FieldContainer(86, 88, Field.SECOND));
+ v.add(new FieldContainer(89, 92, Field.SECOND));
+ v.add(new FieldContainer(93, 94, Field.MILLISECOND));
+ v.add(new FieldContainer(95, 97, Field.MILLISECOND));
+ v.add(new FieldContainer(98, 101, Field.MILLISECOND));
+ v.add(new FieldContainer(102, 105, Field.DAY_OF_WEEK));
+ v.add(new FieldContainer(106, 112, Field.DAY_OF_WEEK));
+ v.add(new FieldContainer(113, 116, Field.DAY_OF_YEAR));
+ v.add(new FieldContainer(117, 120, Field.DAY_OF_YEAR));
+ v.add(new FieldContainer(121, 124, Field.DAY_OF_YEAR));
+ v.add(new FieldContainer(125, 126, Field.DAY_OF_WEEK_IN_MONTH));
+ v.add(new FieldContainer(127, 129, Field.DAY_OF_WEEK_IN_MONTH));
+ v.add(new FieldContainer(130, 132, Field.WEEK_OF_YEAR));
+ v.add(new FieldContainer(133, 136, Field.WEEK_OF_YEAR));
+ v.add(new FieldContainer(137, 138, Field.WEEK_OF_MONTH));
+ v.add(new FieldContainer(139, 142, Field.WEEK_OF_MONTH));
+ v.add(new FieldContainer(143, 145, Field.AM_PM));
+ v.add(new FieldContainer(147, 149, Field.AM_PM));
+ v.add(new FieldContainer(151, 152, Field.HOUR0));
+ v.add(new FieldContainer(153, 156, Field.HOUR0));
+ v.add(new FieldContainer(157, 166, Field.TIME_ZONE));
+ v.add(new FieldContainer(167, 176, Field.TIME_ZONE));
+ v.add(new FieldContainer(177, 182, Field.TIME_ZONE));
+ v.add(new FieldContainer(183, 192, Field.TIME_ZONE));
+ return v;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractCollectionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractCollectionTest.java
new file mode 100644
index 0000000..9ea6efc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractCollectionTest.java
@@ -0,0 +1,345 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.AbstractCollection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+
+public class AbstractCollectionTest extends TestCase {
+
+ /**
+ * java.util.AbstractCollection#add(java.lang.Object)
+ */
+ public void test_addLjava_lang_Object() {
+ AbstractCollection<Object> ac = new AbstractCollection<Object>() {
+
+ @Override
+ public Iterator<Object> iterator() {
+ fail("iterator should not get called");
+ return null;
+ }
+
+ @Override
+ public int size() {
+ fail("size should not get called");
+ return 0;
+ }
+
+ };
+ try {
+ ac.add(null);
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ /**
+ * java.util.AbstractCollection#addAll(java.util.Collection)
+ */
+ public void test_addAllLjava_util_Collection() {
+ final Collection<String> fixtures = Arrays.asList("0", "1", "2");
+ AbstractCollection<String> ac = new AbstractCollection<String>() {
+
+ @Override
+ public boolean add(String object) {
+ assertTrue(fixtures.contains(object));
+ return true;
+ }
+
+ @Override
+ public Iterator<String> iterator() {
+ fail("iterator should not get called");
+ return null;
+ }
+
+ @Override
+ public int size() {
+ fail("size should not get called");
+ return 0;
+ }
+
+ };
+ assertTrue(ac.addAll(fixtures));
+ }
+
+ /**
+ * java.util.AbstractCollection#containsAll(java.util.Collection)
+ */
+ public void test_containsAllLjava_util_Collection() {
+ final Collection<String> fixtures = Arrays.asList("0", "1", "2");
+ AbstractCollection<String> ac = new AbstractCollection<String>() {
+
+ @Override
+ public boolean contains(Object object) {
+ assertTrue(fixtures.contains(object));
+ return true;
+ }
+
+ @Override
+ public Iterator<String> iterator() {
+ fail("iterator should not get called");
+ return null;
+ }
+
+ @Override
+ public int size() {
+ fail("size should not get called");
+ return 0;
+ }
+
+ };
+ assertTrue(ac.containsAll(fixtures));
+ }
+
+ /**
+ * java.util.AbstractCollection#isEmpty()
+ */
+ public void test_isEmpty() {
+ final boolean[] sizeCalled = new boolean[1];
+ AbstractCollection<Object> ac = new AbstractCollection<Object>() {
+ @Override
+ public Iterator<Object> iterator() {
+ fail("iterator should not get called");
+ return null;
+ }
+
+ @Override
+ public int size() {
+ sizeCalled[0] = true;
+ return 0;
+ }
+ };
+ assertTrue(ac.isEmpty());
+ assertTrue(sizeCalled[0]);
+ }
+
+ /**
+ * java.util.AbstractCollection#removeAll(java.util.Collection)
+ */
+ public void test_removeAllLjava_util_Collection() {
+ final String[] removed = new String[3];
+ AbstractCollection<String> ac = new AbstractCollection<String>() {
+
+ @Override
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ String[] values = new String[] { "0", "1", "2" };
+ int index;
+
+ public boolean hasNext() {
+ return index < values.length;
+ }
+
+ public String next() {
+ return values[index++];
+ }
+
+ public void remove() {
+ removed[index - 1] = values[index - 1];
+ }
+
+ };
+ }
+
+ @Override
+ public int size() {
+ fail("size should not get called");
+ return 0;
+ }
+
+ };
+ assertTrue(ac.removeAll(Arrays.asList("0", "1", "2")));
+ for (String r : removed) {
+ if (!"0".equals(r) && !"1".equals(r) && !"2".equals(r)) {
+ fail("an unexpected element was removed");
+ }
+ }
+ }
+
+ /**
+ * java.util.AbstractCollection#retainAll(java.util.Collection)
+ */
+ public void test_retainAllLjava_util_Collection() {
+ final String[] removed = new String[1];
+ AbstractCollection<String> ac = new AbstractCollection<String>() {
+
+ @Override
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ String[] values = new String[] { "0", "1", "2" };
+ int index;
+
+ public boolean hasNext() {
+ return index < values.length;
+ }
+
+ public String next() {
+ return values[index++];
+ }
+
+ public void remove() {
+ removed[index - 1] = values[index - 1];
+ }
+
+ };
+ }
+
+ @Override
+ public int size() {
+ fail("size should not get called");
+ return 0;
+ }
+
+ };
+ assertTrue(ac.retainAll(Arrays.asList("1", "2")));
+ assertEquals("0", removed[0]);
+ }
+
+ /**
+ * java.util.AbstractCollection#toArray()
+ */
+ public void test_toArray() {
+ AbstractCollection<String> ac = new AbstractCollection<String>() {
+ @Override
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ String[] values = new String[] { "0", "1", "2" };
+ int index;
+
+ public boolean hasNext() {
+ return index < values.length;
+ }
+
+ public String next() {
+ return values[index++];
+ }
+
+ public void remove() {
+ fail("remove should not get called");
+ }
+
+ };
+ }
+
+ @Override
+ public int size() {
+ return 3;
+ }
+ };
+
+ Object[] array = ac.toArray();
+ assertEquals(3, array.length);
+ for (Object o : array) {
+ if (!"0".equals(o) && !"1".equals(o) && !"2".equals(o)) {
+ fail("an unexpected element was removed");
+ }
+ }
+ }
+
+ /**
+ * java.util.AbstractCollection#toArray(java.lang.Object[])
+ */
+ public void test_toArray$Ljava_lang_Object() {
+ AbstractCollection<String> ac = new AbstractCollection<String>() {
+ @Override
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ String[] values = new String[] { "0", "1", "2" };
+ int index;
+
+ public boolean hasNext() {
+ return index < values.length;
+ }
+
+ public String next() {
+ return values[index++];
+ }
+
+ public void remove() {
+ fail("remove should not get called");
+ }
+
+ };
+ }
+
+ @Override
+ public int size() {
+ return 3;
+ }
+ };
+ try {
+ ac.toArray(null);
+ fail("No expected NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ ac.toArray(new StringBuffer[ac.size()]);
+ fail("No expected ArrayStoreException");
+ } catch (ArrayStoreException e) {
+ // expected
+ }
+
+ String[] a = new String[3];
+ assertSame(a, ac.toArray(a));
+
+ a = new String[0];
+ assertNotSame(a, ac.toArray(a));
+ a = ac.toArray(a);
+ assertEquals(3, a.length);
+
+ CharSequence[] csa = new CharSequence[3];
+ ac.toArray(csa);
+ assertEquals(3, csa.length);
+ assertEquals("0", csa[0]);
+ assertEquals("1", csa[1]);
+ assertEquals("2", csa[2]);
+ }
+
+ /**
+ * java.util.AbstractCollection#toString()
+ */
+ public void test_toString() {
+ // see HARMONY-1522
+ // collection that returns null iterator(this is against the spec.)
+ AbstractCollection<?> c = new AbstractCollection<Object>() {
+ @Override
+ public int size() {
+ // return non-zero value to pass 'isEmpty' check
+ return 1;
+ }
+
+ @Override
+ public Iterator<Object> iterator() {
+ // this violates the spec.
+ return null;
+ }
+ };
+
+ try {
+ // AbstractCollection.toString() doesn't verify
+ // whether iterator() returns null value or not
+ c.toString();
+ fail("No expected NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractListTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractListTest.java
new file mode 100644
index 0000000..efc196f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractListTest.java
@@ -0,0 +1,576 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.RandomAccess;
+
+public class AbstractListTest extends junit.framework.TestCase {
+
+ static class SimpleList extends AbstractList {
+ ArrayList arrayList;
+
+ SimpleList() {
+ this.arrayList = new ArrayList();
+ }
+
+ public Object get(int index) {
+ return this.arrayList.get(index);
+ }
+
+ public void add(int i, Object o) {
+ this.arrayList.add(i, o);
+ }
+
+ public Object remove(int i) {
+ return this.arrayList.remove(i);
+ }
+
+ public int size() {
+ return this.arrayList.size();
+ }
+ }
+
+ /**
+ * java.util.AbstractList#hashCode()
+ */
+ public void test_hashCode() {
+ List list = new ArrayList();
+ list.add(new Integer(3));
+ list.add(new Integer(15));
+ list.add(new Integer(5));
+ list.add(new Integer(1));
+ list.add(new Integer(7));
+ int hashCode = 1;
+ Iterator i = list.iterator();
+ while (i.hasNext()) {
+ Object obj = i.next();
+ hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
+ }
+ assertTrue("Incorrect hashCode returned. Wanted: " + hashCode
+ + " got: " + list.hashCode(), hashCode == list.hashCode());
+ }
+
+ /**
+ * java.util.AbstractList#iterator()
+ */
+ public void test_iterator() {
+ SimpleList list = new SimpleList();
+ list.add(new Object());
+ list.add(new Object());
+ Iterator it = list.iterator();
+ it.next();
+ it.remove();
+ it.next();
+ }
+
+ /**
+ * java.util.AbstractList#listIterator()
+ */
+ public void test_listIterator() {
+ Integer tempValue;
+ List list = new ArrayList();
+ list.add(new Integer(3));
+ list.add(new Integer(15));
+ list.add(new Integer(5));
+ list.add(new Integer(1));
+ list.add(new Integer(7));
+ ListIterator lit = list.listIterator();
+ assertTrue("Should not have previous", !lit.hasPrevious());
+ assertTrue("Should have next", lit.hasNext());
+ tempValue = (Integer) lit.next();
+ assertTrue("next returned wrong value. Wanted 3, got: " + tempValue,
+ tempValue.intValue() == 3);
+ tempValue = (Integer) lit.previous();
+
+ SimpleList list2 = new SimpleList();
+ list2.add(new Object());
+ ListIterator lit2 = list2.listIterator();
+ lit2.add(new Object());
+ lit2.next();
+
+ //Regression test for Harmony-5808
+ list = new MockArrayList();
+ ListIterator it = list.listIterator();
+ it.add("one");
+ it.add("two");
+ assertEquals(2, list.size());
+ }
+
+ /**
+ * java.util.AbstractList#subList(int, int)
+ */
+ public void test_subListII() {
+ // Test each of the SubList operations to ensure a
+ // ConcurrentModificationException does not occur on an AbstractList
+ // which does not update modCount
+ SimpleList mList = new SimpleList();
+ mList.add(new Object());
+ mList.add(new Object());
+ List sList = mList.subList(0, 2);
+ sList.add(new Object()); // calls add(int, Object)
+ sList.get(0);
+
+ sList.add(0, new Object());
+ sList.get(0);
+
+ sList.addAll(Arrays.asList(new String[] { "1", "2" }));
+ sList.get(0);
+
+ sList.addAll(0, Arrays.asList(new String[] { "3", "4" }));
+ sList.get(0);
+
+ sList.remove(0);
+ sList.get(0);
+
+ ListIterator lit = sList.listIterator();
+ lit.add(new Object());
+ lit.next();
+ lit.remove();
+ lit.next();
+
+ sList.clear(); // calls removeRange()
+ sList.add(new Object());
+
+ // test the type of sublist that is returned
+ List al = new ArrayList();
+ for (int i = 0; i < 10; i++) {
+ al.add(new Integer(i));
+ }
+ assertTrue(
+ "Sublist returned should have implemented Random Access interface",
+ al.subList(3, 7) instanceof RandomAccess);
+
+ List ll = new LinkedList();
+ for (int i = 0; i < 10; i++) {
+ ll.add(new Integer(i));
+ }
+ assertTrue(
+ "Sublist returned should not have implemented Random Access interface",
+ !(ll.subList(3, 7) instanceof RandomAccess));
+
+ }
+
+ /**
+ * java.util.AbstractList#subList(int, int)
+ */
+ public void test_subList_empty() {
+ // Regression for HARMONY-389
+ List al = new ArrayList();
+ al.add("one");
+ List emptySubList = al.subList(0, 0);
+
+ try {
+ emptySubList.get(0);
+ fail("emptySubList.get(0) should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ emptySubList.set(0, "one");
+ fail("emptySubList.set(0,Object) should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ emptySubList.remove(0);
+ fail("emptySubList.remove(0) should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ class MockArrayList<E> extends AbstractList<E> {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ ArrayList<E> list = new ArrayList<E>();
+
+ public E remove(int idx) {
+ modCount++;
+ return list.remove(idx);
+ }
+
+ @Override
+ public E get(int index) {
+ return list.get(index);
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ public void add(int idx, E o) {
+ modCount += 10;
+ list.add(idx, o);
+ }
+ }
+
+ /*
+ * Regression test for HY-4398
+ */
+ public void test_iterator_next() {
+ MockArrayList<String> t = new MockArrayList<String>();
+ t.list.add("a");
+ t.list.add("b");
+
+ Iterator it = t.iterator();
+
+ while (it.hasNext()) {
+ it.next();
+ }
+ try {
+ it.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException cme) {
+ // expected
+ }
+
+ t.add("c");
+ try {
+ it.remove();
+ fail("Should throw NoSuchElementException");
+ } catch (ConcurrentModificationException cme) {
+ // expected
+ }
+
+ it = t.iterator();
+ try {
+ it.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException ise) {
+ // expected
+ }
+
+ Object value = it.next();
+ assertEquals("a", value);
+ }
+
+ /**
+ * java.util.AbstractList#subList(int, int)
+ */
+ public void test_subList_addAll() {
+ // Regression for HARMONY-390
+ List mainList = new ArrayList();
+ Object[] mainObjects = { "a", "b", "c" };
+ mainList.addAll(Arrays.asList(mainObjects));
+ List subList = mainList.subList(1, 2);
+ assertFalse("subList should not contain \"a\"", subList.contains("a"));
+ assertFalse("subList should not contain \"c\"", subList.contains("c"));
+ assertTrue("subList should contain \"b\"", subList.contains("b"));
+
+ Object[] subObjects = { "one", "two", "three" };
+ subList.addAll(Arrays.asList(subObjects));
+ assertFalse("subList should not contain \"a\"", subList.contains("a"));
+ assertFalse("subList should not contain \"c\"", subList.contains("c"));
+
+ Object[] expected = { "b", "one", "two", "three" };
+ ListIterator iter = subList.listIterator();
+ for (int i = 0; i < expected.length; i++) {
+ assertTrue("subList should contain " + expected[i], subList
+ .contains(expected[i]));
+ assertTrue("should be more elements", iter.hasNext());
+ assertEquals("element in incorrect position", expected[i], iter
+ .next());
+ }
+ }
+
+ public void test_indexOfLjava_lang_Object() {
+ AbstractList al = new ArrayList();
+ al.add(0);
+ al.add(1);
+ al.add(2);
+ al.add(3);
+ al.add(4);
+
+ assertEquals(-1, al.indexOf(5));
+ assertEquals(2, al.indexOf(2));
+ }
+
+ public void test_lastIndexOfLjava_lang_Object() {
+ AbstractList al = new ArrayList();
+ al.add(0);
+ al.add(1);
+ al.add(2);
+ al.add(2);
+ al.add(2);
+ al.add(2);
+ al.add(2);
+ al.add(3);
+ al.add(4);
+
+ assertEquals(-1, al.lastIndexOf(5));
+ assertEquals(6, al.lastIndexOf(2));
+ }
+
+ public void test_listIteratorI() {
+ AbstractList al1 = new ArrayList();
+ AbstractList al2 = new ArrayList();
+ al1.add(0);
+ al1.add(1);
+ al1.add(2);
+ al1.add(3);
+ al1.add(4);
+ al2.add(2);
+ al2.add(3);
+ al2.add(4);
+
+ Iterator li1 = al1.listIterator(2);
+ Iterator li2 = al2.listIterator();
+
+ while(li1.hasNext()&&li2.hasNext()) {
+ assertEquals(li1.next(), li2.next());
+ }
+ assertSame(li1.hasNext(),li2.hasNext());
+
+ try {
+ al1.listIterator(-1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ try {
+ al1.listIterator(al1.size() + 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+ }
+
+ protected void doneSuite() {
+ }
+
+ class MockRemoveFailureArrayList<E> extends AbstractList<E> {
+
+ @Override
+ public E get(int location) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int size() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public E remove(int idx) {
+ modCount += 2;
+ return null;
+ }
+
+ public int getModCount() {
+ return modCount;
+ }
+ }
+
+ //test remove for failure by inconsistency of modCount and expectedModCount
+ public void test_remove() {
+ MockRemoveFailureArrayList<String> mrfal = new MockRemoveFailureArrayList<String>();
+ Iterator<String> imrfal = mrfal.iterator();
+ imrfal.next();
+ imrfal.remove();
+ try {
+ imrfal.remove();
+ } catch (ConcurrentModificationException e) {
+ fail("Excepted to catch IllegalStateException not ConcurrentModificationException");
+ } catch (IllegalStateException e) {
+ //Excepted to catch IllegalStateException here
+ }
+ }
+
+ public void test_subListII2() {
+ List<Integer> holder = new ArrayList<Integer>(16);
+ for (int i = 0; i < 10; i++) {
+ holder.add(i);
+ }
+
+ // parent change should cause sublist concurrentmodification fail
+ List<Integer> sub = holder.subList(0, holder.size());
+ holder.add(11);
+ try {
+ sub.size();
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.add(12);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.add(0, 11);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.clear();
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.contains(11);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.get(9);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.indexOf(10);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.isEmpty();
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.iterator();
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.lastIndexOf(10);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.listIterator();
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.listIterator(0);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.remove(0);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.remove(9);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.set(0, 0);
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.size();
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.toArray();
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+ try {
+ sub.toString();
+ fail("Should throw ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ }
+
+ holder.clear();
+ }
+
+ public void test_indexOf_Ljava_lang_Object() {
+ AbstractList<Integer> list = new MockArrayList<Integer>();
+ Integer[] array = { 1, 2, 3, 4, 5 };
+ list.addAll(Arrays.asList(array));
+
+ assertEquals("find 0 in the list do not contain 0", -1, list
+ .indexOf(new Integer(0)));
+ assertEquals("did not return the right location of element 3", 2, list
+ .indexOf(new Integer(3)));
+ assertEquals("find null in the list do not contain null element", -1,
+ list.indexOf(null));
+ list.add(null);
+ assertEquals("did not return the right location of element null", 5,
+ list.indexOf(null));
+ }
+
+ public void test_lastIndexOf_Ljava_lang_Object() {
+ AbstractList<Integer> list = new MockArrayList<Integer>();
+ Integer[] array = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
+ list.addAll(Arrays.asList(array));
+
+ assertEquals("find 6 in the list do not contain 6", -1, list
+ .lastIndexOf(new Integer(6)));
+ assertEquals("did not return the right location of element 4", 6, list
+ .lastIndexOf(new Integer(4)));
+ assertEquals("find null in the list do not contain null element", -1,
+ list.lastIndexOf(null));
+ list.add(null);
+ assertEquals("did not return the right location of element null", 10,
+ list.lastIndexOf(null));
+ }
+
+ public void test_remove_I() {
+ class MockList<E> extends AbstractList<E> {
+ private ArrayList<E> list;
+
+ @Override
+ public E get(int location) {
+ return list.get(location);
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ }
+ AbstractList<Integer> list = new MockList<Integer>();
+ try {
+ list.remove(0);
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+
+ try {
+ list.set(0, null);
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractMapTest.java
new file mode 100644
index 0000000..cd06680
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractMapTest.java
@@ -0,0 +1,415 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Vector;
+import java.util.WeakHashMap;
+
+public class AbstractMapTest extends junit.framework.TestCase {
+
+ static final String specialKey = "specialKey".intern();
+
+ static final String specialValue = "specialValue".intern();
+
+ // The impl of MyMap is not realistic, but serves to create a type
+ // that uses the default remove behavior.
+ class MyMap extends AbstractMap {
+ final Set mySet = new HashSet(1);
+
+ MyMap() {
+ mySet.add(new Map.Entry() {
+ public Object getKey() {
+ return specialKey;
+ }
+
+ public Object getValue() {
+ return specialValue;
+ }
+
+ public Object setValue(Object object) {
+ return null;
+ }
+ });
+ }
+
+ public Object put(Object key, Object value) {
+ return null;
+ }
+
+ public Set entrySet() {
+ return mySet;
+ }
+ }
+
+ /**
+ * java.util.AbstractMap#keySet()
+ */
+ public void test_keySet() {
+ AbstractMap map1 = new HashMap(0);
+ assertSame("HashMap(0)", map1.keySet(), map1.keySet());
+
+ AbstractMap map2 = new HashMap(10);
+ assertSame("HashMap(10)", map2.keySet(), map2.keySet());
+
+ Map map3 = Collections.EMPTY_MAP;
+ assertSame("EMPTY_MAP", map3.keySet(), map3.keySet());
+
+ AbstractMap map4 = new IdentityHashMap(1);
+ assertSame("IdentityHashMap", map4.keySet(), map4.keySet());
+
+ AbstractMap map5 = new LinkedHashMap(122);
+ assertSame("LinkedHashMap", map5.keySet(), map5.keySet());
+
+ AbstractMap map6 = new TreeMap();
+ assertSame("TreeMap", map6.keySet(), map6.keySet());
+
+ AbstractMap map7 = new WeakHashMap();
+ assertSame("WeakHashMap", map7.keySet(), map7.keySet());
+ }
+
+ /**
+ * java.util.AbstractMap#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ Object key = new Object();
+ Object value = new Object();
+
+ AbstractMap map1 = new HashMap(0);
+ map1.put("key", value);
+ assertSame("HashMap(0)", map1.remove("key"), value);
+
+ AbstractMap map4 = new IdentityHashMap(1);
+ map4.put(key, value);
+ assertSame("IdentityHashMap", map4.remove(key), value);
+
+ AbstractMap map5 = new LinkedHashMap(122);
+ map5.put(key, value);
+ assertSame("LinkedHashMap", map5.remove(key), value);
+
+ AbstractMap map6 = new TreeMap(new Comparator() {
+ // Bogus comparator
+ public int compare(Object object1, Object object2) {
+ return 0;
+ }
+ });
+ map6.put(key, value);
+ assertSame("TreeMap", map6.remove(key), value);
+
+ AbstractMap map7 = new WeakHashMap();
+ map7.put(key, value);
+ assertSame("WeakHashMap", map7.remove(key), value);
+
+ AbstractMap aSpecialMap = new MyMap();
+ aSpecialMap.put(specialKey, specialValue);
+ Object valueOut = aSpecialMap.remove(specialKey);
+ assertSame("MyMap", valueOut, specialValue);
+ }
+
+ /**
+ * java.util.AbstractMap#clear()
+ */
+ public void test_clear() {
+ // normal clear()
+ AbstractMap map = new HashMap();
+ map.put(1, 1);
+ map.clear();
+ assertTrue(map.isEmpty());
+
+ // Special entrySet return a Set with no clear method.
+ AbstractMap myMap = new MocAbstractMap();
+ try {
+ myMap.clear();
+ fail("Should throw UnsupportedOprationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ class MocAbstractMap<K, V> extends AbstractMap {
+
+ public Set entrySet() {
+ Set set = new MySet();
+ return set;
+ }
+
+ class MySet extends HashSet {
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ /**
+ * java.util.AbstractMap#containsKey(Object)
+ */
+ public void test_containsKey() {
+ AbstractMap map = new AMT();
+
+ assertFalse(map.containsKey("k"));
+ assertFalse(map.containsKey(null));
+
+ map.put("k", "v");
+ map.put("key", null);
+ map.put(null, "value");
+ map.put(null, null);
+
+ assertTrue(map.containsKey("k"));
+ assertTrue(map.containsKey("key"));
+ assertTrue(map.containsKey(null));
+ }
+
+ /**
+ * java.util.AbstractMap#containsValue(Object)
+ */
+ public void test_containValue() {
+ AbstractMap map = new AMT();
+
+ assertFalse(map.containsValue("v"));
+ assertFalse(map.containsValue(null));
+
+ map.put("k", "v");
+ map.put("key", null);
+ map.put(null, "value");
+
+ assertTrue(map.containsValue("v"));
+ assertTrue(map.containsValue("value"));
+ assertTrue(map.containsValue(null));
+ }
+
+ /**
+ * java.util.AbstractMap#get(Object)
+ */
+ public void test_get() {
+ AbstractMap map = new AMT();
+ assertNull(map.get("key"));
+ assertNull(map.get(null));
+
+ map.put("k", "v");
+ map.put("key", null);
+ map.put(null, "value");
+
+ assertEquals("v", map.get("k"));
+ assertNull(map.get("key"));
+ assertEquals("value", map.get(null));
+ }
+
+ /**
+ * java.util.AbstractMap#values()
+ */
+ public void test_values() {
+ AbstractMap map1 = new HashMap(0);
+ assertSame("HashMap(0)", map1.values(), map1.values());
+
+ AbstractMap map2 = new HashMap(10);
+ assertSame("HashMap(10)", map2.values(), map2.values());
+
+ Map map3 = Collections.EMPTY_MAP;
+ assertSame("EMPTY_MAP", map3.values(), map3.values());
+
+ AbstractMap map4 = new IdentityHashMap(1);
+ assertSame("IdentityHashMap", map4.values(), map4.values());
+
+ AbstractMap map5 = new LinkedHashMap(122);
+ assertSame("IdentityHashMap", map5.values(), map5.values());
+
+ AbstractMap map6 = new TreeMap();
+ assertSame("TreeMap", map6.values(), map6.values());
+
+ AbstractMap map7 = new WeakHashMap();
+ assertSame("WeakHashMap", map7.values(), map7.values());
+ }
+
+ /**
+ * java.util.AbstractMap#clone()
+ */
+ public void test_clone() {
+ class MyMap extends AbstractMap implements Cloneable {
+ private Map map = new HashMap();
+
+ public Set entrySet() {
+ return map.entrySet();
+ }
+
+ public Object put(Object key, Object value) {
+ return map.put(key, value);
+ }
+
+ public Map getMap() {
+ return map;
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ fail("Clone must be supported");
+ return null;
+ }
+ }
+ }
+ MyMap map = new MyMap();
+ map.put("one", "1");
+ Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
+ assertTrue("entry not added", entry.getKey() == "one"
+ && entry.getValue() == "1");
+ MyMap mapClone = (MyMap) map.clone();
+ assertTrue("clone not shallow", map.getMap() == mapClone.getMap());
+ }
+
+ public class AMT extends AbstractMap {
+
+ // Very crude AbstractMap implementation
+ Vector values = new Vector();
+ Vector keys = new Vector();
+
+ public Set entrySet() {
+ return new AbstractSet() {
+ public Iterator iterator() {
+ return new Iterator() {
+ int index = 0;
+
+ public boolean hasNext() {
+ return index < values.size();
+ }
+
+ public Object next() {
+ if (index < values.size()) {
+ Map.Entry me = new Map.Entry() {
+ Object v = values.elementAt(index);
+
+ Object k = keys.elementAt(index);
+
+ public Object getKey() {
+ return k;
+ }
+
+ public Object getValue() {
+ return v;
+ }
+
+ public Object setValue(Object value) {
+ return null;
+ }
+ };
+ index++;
+ return me;
+ }
+ return null;
+ }
+
+ public void remove() {
+ }
+ };
+ }
+
+ public int size() {
+ return values.size();
+ }
+ };
+ }
+
+ public Object put(Object k, Object v) {
+ keys.add(k);
+ values.add(v);
+ return v;
+ }
+ }
+
+ /**
+ * {@link java.util.AbstractMap#putAll(Map)}
+ */
+ public void test_putAllLMap() {
+ Hashtable ht = new Hashtable();
+ AMT amt = new AMT();
+ ht.put("this", "that");
+ amt.putAll(ht);
+
+ assertEquals("Should be equal", amt, ht);
+ }
+
+ public void testEqualsWithNullValues() {
+ Map<String, String> a = new HashMap<String, String>();
+ a.put("a", null);
+ a.put("b", null);
+
+ Map<String, String> b = new HashMap<String, String>();
+ a.put("c", "cat");
+ a.put("d", "dog");
+
+ assertFalse(a.equals(b));
+ assertFalse(b.equals(a));
+ }
+
+ public void testNullsOnViews() {
+ Map<String, String> nullHostile = new Hashtable<String, String>();
+
+ nullHostile.put("a", "apple");
+ testNullsOnView(nullHostile.entrySet());
+
+ nullHostile.put("a", "apple");
+ testNullsOnView(nullHostile.keySet());
+
+ nullHostile.put("a", "apple");
+ testNullsOnView(nullHostile.values());
+ }
+
+ private void testNullsOnView(Collection<?> view) {
+ try {
+ assertFalse(view.contains(null));
+ } catch (NullPointerException optional) {
+ }
+
+ try {
+ assertFalse(view.remove(null));
+ } catch (NullPointerException optional) {
+ }
+
+ Set<Object> setOfNull = Collections.singleton(null);
+ assertFalse(view.equals(setOfNull));
+
+ try {
+ assertFalse(view.removeAll(setOfNull));
+ } catch (NullPointerException optional) {
+ }
+
+ try {
+ assertTrue(view.retainAll(setOfNull)); // destructive
+ } catch (NullPointerException optional) {
+ }
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractQueueTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractQueueTest.java
new file mode 100644
index 0000000..f123bcf
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractQueueTest.java
@@ -0,0 +1,323 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.util.AbstractQueue;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+public class AbstractQueueTest extends TestCase {
+
+ private MockAbstractQueue<Object> queue;
+
+ private class MockAbstractQueue<E> extends AbstractQueue<E> {
+
+ static final int CAPACITY = 10;
+
+ private int size = 0;
+
+ private Object[] elements = new Object[CAPACITY];
+
+ public Iterator<E> iterator() {
+ return new Iterator<E>() {
+
+ private int currentIndex = -1;
+
+ public boolean hasNext() {
+ return size > 0 && currentIndex < size;
+ }
+
+ public E next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ currentIndex++;
+ return (E) elements[currentIndex];
+ }
+
+ public void remove() {
+ if (-1 == currentIndex) {
+ throw new IllegalStateException();
+ }
+ for (int i = currentIndex; i < size - 1; i++) {
+ elements[i] = elements[i + 1];
+ }
+ size--;
+ }
+ };
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public boolean offer(E o) {
+ if (null == o) {
+ throw new NullPointerException();
+ }
+
+ if (size >= CAPACITY) {
+ return false;
+ }
+
+ elements[size++] = o;
+ return true;
+ }
+
+ public E poll() {
+ if (isEmpty()) {
+ return null;
+ }
+ E e = (E) elements[0];
+ for (int i = 0; i < size - 1; i++) {
+ elements[i] = elements[i + 1];
+ }
+ size--;
+ return e;
+ }
+
+ public E peek() {
+ if (isEmpty()) {
+ return null;
+ }
+ return (E) elements[0];
+ }
+
+ }
+
+ /**
+ * java.util.AbstractQueue.add(E)
+ */
+ public void test_addLE_null() {
+ try {
+ queue.add(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.AbstractQueue.add(E)
+ */
+ public void test_addLE_Full() {
+ Object o = new Object();
+
+ for(int i = 0; i < MockAbstractQueue.CAPACITY; i++ ) {
+ queue.add(o);
+ }
+
+ try {
+ queue.add(o);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.AbstractQueue#add(E)
+ */
+ public void test_addLE() {
+ Object o = new Object();
+ final int LAST_INDEX = 4;
+ for (int i = 0; i < LAST_INDEX; i++) {
+ queue.add(o);
+ }
+ Integer I = new Integer(123456);
+ queue.add(I);
+ assertTrue(queue.contains(I));
+ Iterator iter = queue.iterator();
+ for (int i = 0; i < LAST_INDEX; i++) {
+ iter.next();
+ }
+ assertTrue(I == iter.next());
+ }
+
+ /**
+ * java.util.AbstractQueue#addAll(E)
+ */
+ public void test_addAllLE_null() {
+ try {
+ queue.addAll(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.AbstractQueue#addAll(E)
+ */
+ public void test_addAllLE_with_null() {
+ List list = Arrays.asList("MYTESTSTRING", null, new Float(123.456));
+ try {
+ queue.addAll(list);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.AbstractQueue#addAll(E)
+ */
+ public void test_addAllLE_full() {
+ List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+ try {
+ queue.addAll(list);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.AbstractQueue#addAll(E)
+ */
+ public void test_addAllLE_empty() {
+ // Regression test for HARMONY-1178
+ List list = new ArrayList<Object>(0);
+ assertFalse("Non modification to queue should return false", queue.addAll(list));
+ }
+
+ /**
+ * java.util.AbstractQueue#addAll(E)
+ */
+ public void test_addAllLE_this() {
+ try {
+ queue.addAll(queue);
+ fail("should throw IllegalArgumentException ");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void test_addAllLjava_lang_Object() {
+ Collection c = new Vector();
+
+ c.add(0);
+ c.add(1);
+ c.add(2);
+ c.add(3);
+ c.add(4);
+ c.add(5);
+
+ assertTrue(queue.addAll(c));
+ assertEquals(6, queue.size());
+ }
+
+ /**
+ * java.util.AbstractQueue#clear()
+ */
+ public void test_clear_empty() {
+ queue.clear();
+ assertTrue(queue.isEmpty());
+ assertNull(queue.peek());
+ }
+
+ /**
+ * java.util.AbstractQueue#clear()
+ */
+ public void test_clear() {
+ List list = Arrays.asList(123.456, "MYTESTSTRING", new Object(), 'c');
+ queue.addAll(list);
+ queue.clear();
+ assertTrue(queue.isEmpty());
+ assertNull(queue.peek());
+ }
+
+ /**
+ * java.util.AbstractQueue#AbstractQueue()
+ */
+ public void test_Constructor() {
+ MockAbstractQueue queue = new MockAbstractQueue();
+ assertNotNull(queue);
+ }
+
+ /**
+ * java.util.AbstractQueue#remove()
+ */
+ public void test_remove_null() {
+ try {
+ queue.remove();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * java.util.AbstractQueue#remove()
+ */
+ public void test_remove() {
+ char c = 'a';
+ queue.add(c);
+ c = 'b';
+ queue.add(c);
+ assertEquals('a', queue.remove());
+ assertEquals('b', queue.remove());
+ try {
+ queue.remove();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.AbstractQueue#element()
+ */
+ public void test_element_empty() {
+ try {
+ queue.element();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.AbstractQueue#element()
+ */
+ public void test_element() {
+ String s = "MYTESTSTRING_ONE";
+ queue.add(s);
+ s = "MYTESTSTRING_TWO";
+ queue.add(s);
+ assertEquals("MYTESTSTRING_ONE", queue.element());
+ // still the first element
+ assertEquals("MYTESTSTRING_ONE", queue.element());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ queue = new MockAbstractQueue<Object>();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ queue = null;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractSequentialListTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractSequentialListTest.java
new file mode 100644
index 0000000..80ca4fd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/AbstractSequentialListTest.java
@@ -0,0 +1,603 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.util.AbstractSequentialList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+public class AbstractSequentialListTest extends TestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ class ASLT<E> extends AbstractSequentialList<E> {
+
+ LinkedList<E> l = new LinkedList<E>();
+
+ @Override
+ public ListIterator<E> listIterator(int index) {
+ return l.listIterator(index);
+ }
+
+ @Override
+ public int size() {
+ return l.size();
+ }
+ }
+
+ /**
+ * {@link java.util.AbstractSequentialList#addAll(int, java.util.Collection)}
+ */
+ public void test_addAll_ILCollection() {
+ AbstractSequentialList<String> al = new ASLT<String>();
+ String[] someList = { "Aardvark" ,
+ "Bear" ,
+ "Chimpanzee",
+ "Duck" };
+ Collection<String> c = Arrays.asList(someList);
+ al.addAll(c);
+ assertTrue("Should return true", al.addAll(2, c));
+ }
+
+ class Mock_unsupportedListIterator implements ListIterator {
+ public void add(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasNext() {
+ return true;
+ }
+
+ public boolean hasPrevious() {
+ return false;
+ }
+
+ public Object next() {
+ return null;
+ }
+
+ public int nextIndex() {
+ return 0;
+ }
+
+ public Object previous() {
+ return null;
+ }
+
+ public int previousIndex() {
+ return 0;
+ }
+
+ public void remove() {
+ }
+
+ public void set(Object o) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ class Mock_ListIterator<E> implements ListIterator<E> {
+ final String wrongElement = "String";
+ public void add(E o) {
+ if (o.equals(wrongElement)) throw new IllegalArgumentException();
+ if (o == null) throw new NullPointerException();
+ }
+
+ public boolean hasNext() {
+ return false;
+ }
+
+ public boolean hasPrevious() {
+ return false;
+ }
+
+ public E next() {
+ return null;
+ }
+
+ public int nextIndex() {
+ return 0;
+ }
+
+ public E previous() {
+ return null;
+ }
+
+ public int previousIndex() {
+ return 0;
+ }
+
+ public void remove() {
+ }
+
+ public void set(E o) {
+ }
+ }
+
+ public void test_addAllILjava_util_Collection() {
+ AbstractSequentialList asl = new AbstractSequentialList() {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return new Mock_unsupportedListIterator();
+ }
+ };
+ Collection strV = new Vector<String>();
+
+ strV.add("String");
+ strV.add("1");
+ strV.add("3.14");
+
+ try {
+ asl.addAll(0, strV);
+ fail("UnsupportedOperationException expected.");
+ } catch (UnsupportedOperationException ee) {
+ //expected
+ }
+ try {
+ asl.addAll(0, null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ //ClassCastException can not be checked for this method.
+
+ asl = new AbstractSequentialList() {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return new Mock_ListIterator();
+ }
+ };
+
+ try {
+ asl.addAll(0, strV);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ strV.remove("String");
+ strV.add(null);
+
+ try {
+ asl.addAll(0, strV);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ strV.remove(null);
+ asl.addAll(0, strV);
+
+ asl = new LinkedList();
+
+ try {
+ asl.addAll(-10, strV);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ asl.addAll(1, strV);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ public void test_addILjava_lang_Object() {
+ AbstractSequentialList asl = new AbstractSequentialList() {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return new Mock_unsupportedListIterator();
+ }
+ };
+
+ try {
+ asl.add(0, 1);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+
+ asl = new AbstractSequentialList() {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return new Mock_ListIterator();
+ }
+ };
+
+ try {
+ asl.add(0, "String");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ee) {
+ //expected
+ }
+
+ try {
+ asl.add(0, null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ //ClassCastException can not be checked for this method.
+
+ asl.add(0, 1);
+
+ asl = new LinkedList();
+
+ try {
+ asl.add(-1, 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ asl.add(0, 1);
+
+ try {
+ asl.add(2, 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+ }
+
+ public void test_getI() {
+ final String buff[] = {"0", "1", "2", "3", "4", "5"};
+ AbstractSequentialList asl = new AbstractSequentialList() {
+ int currPos = 0;
+
+ @Override
+ public int size() {
+ return buff.length;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ currPos = index;
+ return new ListIterator() {
+ public void add(Object o) {
+ }
+
+ public boolean hasNext() {
+ return true;
+ }
+
+ public boolean hasPrevious() {
+ return false;
+ }
+
+ public Object next() {
+ return buff[currPos];
+ }
+
+ public int nextIndex() {
+ return 0;
+ }
+
+ public Object previous() {
+ return null;
+ }
+
+ public int previousIndex() {
+ return 0;
+ }
+
+ public void remove() {
+ }
+
+ public void set(Object o) {
+ }
+ };
+ }
+ };
+
+ for (int i = 0; i < buff.length; i++) {
+ assertEquals(buff[i], asl.get(i));
+ }
+
+ try {
+ asl.get(asl.size() + 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ asl.get(-1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ public void test_iterrator() {
+ AbstractSequentialList asl = new AbstractSequentialList() {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return new Mock_unsupportedListIterator();
+ }
+ };
+
+ assertTrue(asl.iterator().getClass().toString().contains("Mock_unsupportedListIterator"));
+
+ asl = new AbstractSequentialList() {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return new Mock_ListIterator();
+ }
+ };
+
+ assertTrue(asl.iterator().getClass().toString().contains("Mock_ListIterator"));
+
+ asl = new AbstractSequentialList() {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return null;
+ }
+ };
+ assertNull(asl.iterator());
+ }
+
+ public void test_removeI() {
+ AbstractSequentialList asl = new AbstractSequentialList() {
+ String buff[] = {"0", "1", "2", "3", "4", "5"};
+ int currPos = 0;
+
+ @Override
+ public int size() {
+ return buff.length;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ currPos = index;
+ return new ListIterator() {
+ public void add(Object o) {
+ }
+
+ public boolean hasNext() {
+ return true;
+ }
+
+ public boolean hasPrevious() {
+ return false;
+ }
+
+ public Object next() {
+ return buff[currPos];
+ }
+
+ public int nextIndex() {
+ return 0;
+ }
+
+ public Object previous() {
+ return null;
+ }
+
+ public int previousIndex() {
+ return 0;
+ }
+
+ public void remove() {
+ buff[currPos] = "removed element";
+ }
+
+ public void set(Object o) {
+ }
+ };
+ }
+ };
+
+ try {
+ asl.remove(asl.size() + 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ asl.remove(-1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ for(int i = 0; i < asl.size(); i++) {
+ assertFalse(asl.get(i).toString().contains("removed element"));
+ asl.remove(i);
+ assertTrue(asl.get(i).toString().contains("removed element"));
+ }
+ }
+
+ public void test_setILjava_lang_Object() {
+ AbstractSequentialList asl = new AbstractSequentialList() {
+ String buff[] = {"0", "1", "2", "3", "4", "5"};
+ final String illegalStr = "Illegal element";
+ int currPos = 0;
+
+ @Override
+ public int size() {
+ return buff.length;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ currPos = index;
+ return new ListIterator() {
+ public void add(Object o) {
+ }
+
+ public boolean hasNext() {
+ return true;
+ }
+
+ public boolean hasPrevious() {
+ return false;
+ }
+
+ public Object next() {
+ return buff[currPos];
+ }
+
+ public int nextIndex() {
+ return 0;
+ }
+
+ public Object previous() {
+ return null;
+ }
+
+ public int previousIndex() {
+ return 0;
+ }
+
+ public void remove() {
+ buff[currPos] = "removed element";
+ }
+
+ public void set(Object o) {
+ if (o == null) throw new NullPointerException();
+ if (o.equals(illegalStr)) throw new IllegalArgumentException();
+ buff[currPos] = (String) o;
+ }
+ };
+ }
+ };
+
+ try {
+ asl.set(asl.size() + 1, "new element");
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ asl.set(-1, "new element");
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ for(int i = 0; i < asl.size(); i++) {
+ assertFalse(asl.get(i).toString().contains("new element"));
+ asl.set(i, "new element");
+ assertTrue(asl.get(i).toString().contains("new element"));
+ }
+
+ try {
+ asl.set(1, new Double(1));
+ fail("ClassCastException expected");
+ } catch (ClassCastException e) {
+ //
+ }
+
+ try {
+ asl.set(1, "Illegal element");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ee) {
+ //expected
+ }
+
+ try {
+ asl.set(1, null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ asl = new AbstractSequentialList() {
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return new Mock_unsupportedListIterator();
+ }
+ };
+
+ try {
+ asl.set(0, "New element");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayDequeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayDequeTest.java
new file mode 100644
index 0000000..11e6cfc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayDequeTest.java
@@ -0,0 +1,932 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class ArrayDequeTest extends TestCase {
+
+ private Object testObjOne;
+
+ private Object testObjTwo;
+
+ private Object testObjThree;
+
+ private Object testObjFour;
+
+ private Object testObjLast;
+
+ private ArrayDeque<Object> testQue;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ testObjOne = new Object();
+ testObjTwo = new Object();
+ testObjThree = new Object();
+ testObjFour = new Object();
+ testObjLast = new Object();
+ testQue = new ArrayDeque<Object>();
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#ArrayDeque()}
+ */
+ public void test_Constructor() throws Exception {
+ assertEquals(0, new ArrayDeque<Object>().size());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#ArrayDeque(java.util.Collection)}
+ */
+ public void test_Constructor_LCollection() throws Exception {
+ assertEquals(0, new ArrayDeque<Object>(new ArrayList<Object>()).size());
+ try {
+ new ArrayDeque<Object>(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#ArrayDeque(int)}
+ */
+ public void test_Constructor_Int() throws Exception {
+ assertEquals(0, new ArrayDeque<Object>(8).size());
+ ArrayDeque<Object> zeroCapQue = new ArrayDeque<Object>(0);
+ assertEquals(0, zeroCapQue.size());
+ zeroCapQue.add(testObjOne);
+ assertEquals(1, zeroCapQue.size());
+ assertEquals(0, new ArrayDeque<Object>(0).size());
+ ArrayDeque<Object> negCapQue = new ArrayDeque<Object>(-1);
+ assertEquals(0, negCapQue.size());
+ negCapQue.add(testObjOne);
+ assertEquals(1, negCapQue.size());
+ ArrayDeque<Object> oneCapQue = new ArrayDeque<Object>(1);
+ assertEquals(0, oneCapQue.size());
+ oneCapQue.add(testObjOne);
+ assertEquals(1, oneCapQue.size());
+ oneCapQue.add(testObjOne);
+ assertEquals(2, oneCapQue.size());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#addFirst(Object)}
+ */
+ public void test_addFirst() throws Exception {
+ testQue.addFirst(testObjOne);
+ assertEquals(1, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ testQue.addFirst(testObjOne);
+ assertEquals(2, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ testQue.addFirst(testObjTwo);
+ assertEquals(3, testQue.size());
+ assertEquals(testObjTwo, testQue.peek());
+ assertEquals(testObjOne, testQue.getLast());
+ try {
+ testQue.addFirst(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#addLast(Object)}
+ */
+ public void test_addLast() throws Exception {
+ testQue.addLast(testObjOne);
+ assertEquals(1, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ testQue.addLast(testObjOne);
+ assertEquals(2, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ testQue.addLast(testObjTwo);
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ assertEquals(testObjTwo, testQue.getLast());
+ try {
+ testQue.addLast(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#offerFirst(Object)}
+ */
+ public void test_offerFirst() throws Exception {
+ assertTrue(testQue.offerFirst(testObjOne));
+ assertEquals(1, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ assertTrue(testQue.offerFirst(testObjOne));
+ assertEquals(2, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ assertTrue(testQue.offerFirst(testObjTwo));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjTwo, testQue.peek());
+ assertEquals(testObjOne, testQue.getLast());
+ try {
+ testQue.offerFirst(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#offerLast(Object)}
+ */
+ public void test_offerLast() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertEquals(1, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ assertTrue(testQue.offerLast(testObjOne));
+ assertEquals(2, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ assertEquals(testObjTwo, testQue.getLast());
+ try {
+ testQue.offerLast(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#removeFirst()}
+ */
+ public void test_removeFirst() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.removeFirst());
+ assertEquals(2, testQue.size());
+ assertEquals(testObjTwo, testQue.removeFirst());
+ assertEquals(testObjThree, testQue.removeFirst());
+ assertEquals(0, testQue.size());
+ try {
+ testQue.removeFirst();
+ fail("should throw NoSuchElementException ");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#removeLast()}
+ */
+ public void test_removeLast() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjThree, testQue.removeLast());
+ assertEquals(2, testQue.size());
+ assertEquals(testObjTwo, testQue.removeLast());
+ assertEquals(testObjOne, testQue.removeLast());
+ assertEquals(0, testQue.size());
+ try {
+ testQue.removeLast();
+ fail("should throw NoSuchElementException ");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#pollFirst()}
+ */
+ public void test_pollFirst() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.pollFirst());
+ assertEquals(2, testQue.size());
+ assertEquals(testObjTwo, testQue.pollFirst());
+ assertEquals(testObjThree, testQue.pollFirst());
+ assertEquals(0, testQue.size());
+ assertNull(testQue.pollFirst());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#peekLast()}
+ */
+ public void test_pollLast() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjThree, testQue.pollLast());
+ assertEquals(2, testQue.size());
+ assertEquals(testObjTwo, testQue.pollLast());
+ assertEquals(testObjOne, testQue.pollLast());
+ assertEquals(0, testQue.size());
+ assertNull(testQue.pollFirst());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#getFirst()}
+ */
+ public void test_getFirst() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.getFirst());
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.pollFirst());
+ assertEquals(testObjTwo, testQue.getFirst());
+ assertEquals(testObjTwo, testQue.pollFirst());
+ assertEquals(testObjThree, testQue.pollFirst());
+ assertEquals(0, testQue.size());
+ try {
+ testQue.getFirst();
+ fail("should throw NoSuchElementException ");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#getLast()}
+ */
+ public void test_getLast() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjThree, testQue.getLast());
+ assertEquals(3, testQue.size());
+ assertEquals(testObjThree, testQue.pollLast());
+ assertEquals(testObjTwo, testQue.getLast());
+ assertEquals(testObjTwo, testQue.pollLast());
+ assertEquals(testObjOne, testQue.pollLast());
+ assertEquals(0, testQue.size());
+ try {
+ testQue.getLast();
+ fail("should throw NoSuchElementException ");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#peekFirst()}
+ */
+ public void test_peekFirst() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.peekFirst());
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.pollFirst());
+ assertEquals(testObjTwo, testQue.peekFirst());
+ assertEquals(testObjTwo, testQue.pollFirst());
+ assertEquals(testObjThree, testQue.pollFirst());
+ assertEquals(0, testQue.size());
+ assertEquals(null, testQue.peekFirst());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#peekLast()}
+ */
+ public void test_peekLast() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjThree, testQue.peekLast());
+ assertEquals(3, testQue.size());
+ assertEquals(testObjThree, testQue.pollLast());
+ assertEquals(testObjTwo, testQue.peekLast());
+ assertEquals(testObjTwo, testQue.pollLast());
+ assertEquals(testObjOne, testQue.pollLast());
+ assertEquals(0, testQue.size());
+ assertNull(testQue.peekLast());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#removeFirstOccurrence(Object)}
+ */
+ public void test_removeFirstOccurrence() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertTrue(testQue.offerLast(testObjOne));
+ assertEquals(5, testQue.size());
+ assertTrue(testQue.removeFirstOccurrence(testObjOne));
+ assertFalse(testQue.removeFirstOccurrence(testObjFour));
+ assertEquals(testObjTwo, testQue.peekFirst());
+ assertEquals(testObjOne, testQue.peekLast());
+ assertEquals(4, testQue.size());
+ assertTrue(testQue.removeFirstOccurrence(testObjOne));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.peekLast());
+ assertTrue(testQue.removeFirstOccurrence(testObjOne));
+ assertEquals(2, testQue.size());
+ assertEquals(testObjThree, testQue.peekLast());
+ assertFalse(testQue.removeFirstOccurrence(testObjOne));
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#removeLastOccurrence(Object)}
+ */
+ public void test_removeLastOccurrence() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertTrue(testQue.offerLast(testObjOne));
+ assertEquals(5, testQue.size());
+ assertTrue(testQue.removeLastOccurrence(testObjOne));
+ assertFalse(testQue.removeLastOccurrence(testObjFour));
+ assertEquals(testObjOne, testQue.peekFirst());
+ assertEquals(testObjThree, testQue.peekLast());
+ assertEquals(4, testQue.size());
+ assertTrue(testQue.removeLastOccurrence(testObjOne));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.peekFirst());
+ assertEquals(testObjThree, testQue.peekLast());
+ assertTrue(testQue.removeLastOccurrence(testObjOne));
+ assertEquals(2, testQue.size());
+ assertEquals(testObjThree, testQue.peekLast());
+ assertFalse(testQue.removeLastOccurrence(testObjOne));
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#add(Object)}
+ */
+ public void test_add() throws Exception {
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertEquals(testObjOne, testQue.peekFirst());
+ assertEquals(testObjThree, testQue.peekLast());
+ try {
+ testQue.add(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#offer(Object)}
+ */
+ public void test_offer() throws Exception {
+ assertTrue(testQue.offer(testObjOne));
+ assertTrue(testQue.offer(testObjTwo));
+ assertTrue(testQue.offer(testObjOne));
+ assertTrue(testQue.offer(testObjThree));
+ assertEquals(testObjOne, testQue.peekFirst());
+ assertEquals(testObjThree, testQue.peekLast());
+ try {
+ testQue.offer(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#remove()}
+ */
+ public void test_remove() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.remove());
+ assertEquals(2, testQue.size());
+ assertEquals(testObjTwo, testQue.remove());
+ assertEquals(testObjThree, testQue.remove());
+ assertEquals(0, testQue.size());
+ try {
+ testQue.remove();
+ fail("should throw NoSuchElementException ");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#poll()}
+ */
+ public void test_poll() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.poll());
+ assertEquals(2, testQue.size());
+ assertEquals(testObjTwo, testQue.poll());
+ assertEquals(testObjThree, testQue.poll());
+ assertEquals(0, testQue.size());
+ assertNull(testQue.poll());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#element()}
+ */
+ public void test_element() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.element());
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.pollFirst());
+ assertEquals(testObjTwo, testQue.element());
+ assertEquals(testObjTwo, testQue.pollFirst());
+ assertEquals(testObjThree, testQue.element());
+ assertEquals(testObjThree, testQue.pollFirst());
+ assertEquals(0, testQue.size());
+ try {
+ testQue.element();
+ fail("should throw NoSuchElementException ");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#peek()}
+ */
+ public void test_peek() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.pollFirst());
+ assertEquals(testObjTwo, testQue.peek());
+ assertEquals(testObjTwo, testQue.pollFirst());
+ assertEquals(testObjThree, testQue.pollFirst());
+ assertEquals(0, testQue.size());
+ assertEquals(null, testQue.peek());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#push(Object)}
+ */
+ public void test_push() throws Exception {
+ testQue.push(testObjOne);
+ assertEquals(1, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ testQue.push(testObjOne);
+ assertEquals(2, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ testQue.push(testObjTwo);
+ assertEquals(3, testQue.size());
+ assertEquals(testObjTwo, testQue.peek());
+ assertEquals(testObjOne, testQue.getLast());
+ try {
+ testQue.push(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#pop()}
+ */
+ public void test_pop() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.pop());
+ assertEquals(2, testQue.size());
+ assertEquals(testObjTwo, testQue.pop());
+ assertEquals(testObjThree, testQue.pop());
+ assertEquals(0, testQue.size());
+ try {
+ testQue.pop();
+ fail("should throw NoSuchElementException ");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#addFirst(Object)}
+ */
+ public void test_size() throws Exception {
+ assertEquals(0, testQue.size());
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertEquals(2, testQue.size());
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertEquals(4, testQue.size());
+ testQue.remove();
+ testQue.remove();
+ assertEquals(2, testQue.size());
+ testQue.clear();
+ assertEquals(0, testQue.size());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#isEmpty()}
+ */
+ public void test_isEmpty() throws Exception {
+ assertTrue(testQue.isEmpty());
+ assertTrue(testQue.add(testObjOne));
+ assertFalse(testQue.isEmpty());
+ assertTrue(testQue.add(testObjTwo));
+ assertFalse(testQue.isEmpty());
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertFalse(testQue.isEmpty());
+ testQue.remove();
+ testQue.remove();
+ assertFalse(testQue.isEmpty());
+ testQue.clear();
+ assertTrue(testQue.isEmpty());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#iterator()}
+ */
+ public void test_iterator() throws Exception {
+ assertFalse(testQue.iterator().hasNext());
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertTrue(testQue.add(testObjLast));
+ Iterator result = testQue.iterator();
+ assertEquals(5, testQue.size());
+ try {
+ result.remove();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ assertTrue(testQue.add(testObjThree));
+ try {
+ result.next();
+ fail("should throw ConcurrentModificationException");
+ } catch (ConcurrentModificationException e) {
+ // expected
+ }
+ result = testQue.iterator();
+ assertEquals(testObjOne, result.next());
+ assertEquals(testObjTwo, result.next());
+ assertEquals(testObjOne, result.next());
+ assertEquals(testObjThree, result.next());
+ assertEquals(testObjLast, result.next());
+ assertTrue(result.hasNext());
+ result.remove();
+ assertEquals(testObjThree, result.next());
+ assertFalse(result.hasNext());
+ try {
+ result.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ // test a full array
+ ArrayDeque<Object> ad = new ArrayDeque<Object>();
+ // fill the array
+ for (int i = 0; i < 16; ++i) {
+ ad.addLast(new Object());
+ }
+ assertTrue(ad.iterator().hasNext());
+ Iterator<Object> iter = ad.iterator();
+ for (int i = 0; i < 16; ++i) {
+ assertTrue(iter.hasNext());
+ iter.next();
+ }
+ iter.remove();
+ // test un-full array
+ ad = new ArrayDeque<Object>();
+ // fill the array
+ for (int i = 0; i < 5; ++i) {
+ ad.addLast(new Object());
+ }
+ iter = ad.iterator();
+ for (int i = 0; i < 5; ++i) {
+ assertTrue(iter.hasNext());
+ iter.next();
+ }
+ iter.remove();
+
+ ad = new ArrayDeque<Object>();
+ // fill the array
+ for (int i = 0; i < 16; ++i) {
+ ad.addLast(new Object());
+ }
+ iter = ad.iterator();
+ assertTrue(iter.hasNext());
+ for (int i = 0; i < ad.size(); ++i) {
+ iter.next();
+ }
+ assertFalse(iter.hasNext());
+ iter.remove();
+ ad.add(new Object());
+ assertFalse(iter.hasNext());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#descendingIterator()}
+ */
+ public void test_descendingIterator() throws Exception {
+ assertFalse(testQue.descendingIterator().hasNext());
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertTrue(testQue.add(testObjLast));
+ Iterator result = testQue.descendingIterator();
+ assertEquals(5, testQue.size());
+ try {
+ result.remove();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ assertTrue(testQue.add(testObjFour));
+
+ // a strange behavior here, RI's descendingIterator() and iterator() is
+ // properly different. Notice spec: "The iterators returned by this
+ // class's iterator method are fail-fast". RI shows descendingIterator()
+ // is not an iterator method.
+ assertEquals(testObjLast, result.next());
+
+ result = testQue.descendingIterator();
+ assertEquals(testObjFour, result.next());
+ assertEquals(testObjLast, result.next());
+ assertEquals(testObjThree, result.next());
+ assertEquals(testObjOne, result.next());
+ assertEquals(testObjTwo, result.next());
+ assertTrue(result.hasNext());
+ result.remove();
+ assertEquals(testObjOne, result.next());
+ assertFalse(result.hasNext());
+ try {
+ result.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ // test a full array
+ ArrayDeque<Object> ad = new ArrayDeque<Object>();
+ // fill the array
+ for (int i = 0; i < 16; ++i) {
+ ad.addLast(new Object());
+ }
+ assertTrue(ad.descendingIterator().hasNext());
+ Iterator<Object> iter = ad.descendingIterator();
+ for (int i = 0; i < 16; ++i) {
+ assertTrue(iter.hasNext());
+ iter.next();
+ }
+ iter.remove();
+ // test un-full array
+ ad = new ArrayDeque<Object>();
+ // fill the array
+ for (int i = 0; i < 5; ++i) {
+ ad.addLast(new Object());
+ }
+ iter = ad.descendingIterator();
+ for (int i = 0; i < 5; ++i) {
+ assertTrue(iter.hasNext());
+ iter.next();
+ }
+ iter.remove();
+
+ ad = new ArrayDeque<Object>();
+ // fill the array
+ for (int i = 0; i < 16; ++i) {
+ ad.addLast(new Object());
+ }
+ iter = ad.descendingIterator();
+ assertTrue(iter.hasNext());
+ for (int i = 0; i < ad.size(); ++i) {
+ iter.next();
+ }
+ assertFalse(iter.hasNext());
+ iter.remove();
+ ad.add(new Object());
+ assertFalse(iter.hasNext());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#contains(Object)}
+ */
+ public void test_contains() throws Exception {
+ assertFalse(testQue.contains(testObjFour));
+ assertFalse(testQue.contains(null));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertTrue(testQue.add(testObjLast));
+
+ assertTrue(testQue.contains(testObjOne));
+ assertTrue(testQue.contains(testObjTwo));
+ assertTrue(testQue.contains(testObjThree));
+ assertTrue(testQue.contains(testObjLast));
+ assertFalse(testQue.contains(null));
+ testQue.clear();
+ assertFalse(testQue.contains(testObjOne));
+ assertFalse(testQue.contains(testObjTwo));
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#remove(Object)}
+ */
+ public void test_remove_LObject() throws Exception {
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjTwo));
+ assertTrue(testQue.offerLast(testObjOne));
+ assertTrue(testQue.offerLast(testObjThree));
+ assertTrue(testQue.offerLast(testObjOne));
+ assertEquals(5, testQue.size());
+ assertTrue(testQue.remove(testObjOne));
+ assertFalse(testQue.remove(testObjFour));
+ assertEquals(testObjTwo, testQue.peekFirst());
+ assertEquals(testObjOne, testQue.peekLast());
+ assertEquals(4, testQue.size());
+ assertTrue(testQue.remove(testObjOne));
+ assertEquals(3, testQue.size());
+ assertEquals(testObjOne, testQue.peekLast());
+ assertTrue(testQue.remove(testObjOne));
+ assertEquals(2, testQue.size());
+ assertEquals(testObjThree, testQue.peekLast());
+ assertFalse(testQue.remove(testObjOne));
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#clear()}
+ */
+ public void test_clear() throws Exception {
+ assertTrue(testQue.isEmpty());
+ testQue.clear();
+ assertTrue(testQue.isEmpty());
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ testQue.clear();
+ assertTrue(testQue.isEmpty());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#toArray()}
+ */
+ public void test_toArray() throws Exception {
+ assertEquals(0, testQue.toArray().length);
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertTrue(testQue.add(testObjLast));
+ Object[] result = testQue.toArray();
+ assertEquals(5, testQue.size());
+ assertEquals(testObjOne, result[0]);
+ assertEquals(testObjTwo, result[1]);
+ assertEquals(testObjOne, result[2]);
+ assertEquals(testObjThree, result[3]);
+ assertEquals(testObjLast, result[4]);
+ // change in array do not affect ArrayDeque
+ result[0] = null;
+ assertEquals(5, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#toArray(Object[])}
+ */
+ public void test_toArray_$LObject() throws Exception {
+ Object[] array = new Object[0];
+ Object[] result = testQue.toArray(array);
+ assertEquals(0, result.length);
+ assertEquals(array, result);
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertTrue(testQue.add(testObjLast));
+ result = testQue.toArray(array);
+ assertEquals(5, testQue.size());
+ assertEquals(5, result.length);
+ assertEquals(0, array.length);
+ assertFalse(array == result);
+ assertEquals(testObjOne, result[0]);
+ assertEquals(testObjTwo, result[1]);
+ assertEquals(testObjOne, result[2]);
+ assertEquals(testObjThree, result[3]);
+ assertEquals(testObjLast, result[4]);
+ // change in array do not affect ArrayDeque
+ result[0] = null;
+ assertEquals(5, testQue.size());
+ assertEquals(testObjOne, testQue.peek());
+ try {
+ testQue.toArray(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * {@link java.util.ArrayDeque#clone()}
+ */
+ public void test_clone() throws Exception {
+ ArrayDeque<Object> cloned = testQue.clone();
+ assertEquals(0, cloned.size());
+ assertFalse(cloned == testQue);
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjTwo));
+ assertTrue(testQue.add(testObjOne));
+ assertTrue(testQue.add(testObjThree));
+ assertTrue(testQue.add(testObjLast));
+ assertTrue(testQue.add(testQue));
+ cloned = testQue.clone();
+ assertEquals(6, cloned.size());
+ while (0 != testQue.size()) {
+ assertEquals(testQue.remove(), cloned.remove());
+ }
+ }
+
+ /**
+ * java.util.ArrayDeque#Serialization()
+ */
+ public void test_serialization() throws Exception {
+ assertTrue(testQue.add(new Integer(1)));
+ assertTrue(testQue.add(new Integer(2)));
+ assertTrue(testQue.add(new Integer(3)));
+ assertTrue(testQue.add(new Integer(4)));
+ assertTrue(testQue.add(new Integer(5)));
+ SerializationTest.verifySelf(testQue, new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+ ArrayDeque<Object> formerQue = (ArrayDeque) initial;
+ ArrayDeque<Object> deserializedQue = (ArrayDeque) deserialized;
+ assertEquals(formerQue.remove(), deserializedQue.remove());
+ }
+ });
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationCompatibility() throws Exception {
+ assertTrue(testQue.add(new Integer(1)));
+ assertTrue(testQue.add(new Integer(2)));
+ assertTrue(testQue.add(new Integer(3)));
+ assertTrue(testQue.add(new Integer(4)));
+ assertTrue(testQue.add(new Integer(5)));
+ SerializationTest.verifyGolden(this, testQue, new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+ ArrayDeque<Object> formerQue = (ArrayDeque) initial;
+ ArrayDeque<Object> deserializedQue = (ArrayDeque) deserialized;
+ assertEquals(formerQue.remove(), deserializedQue.remove());
+ }
+ });
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayListTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayListTest.java
new file mode 100644
index 0000000..f2546e0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayListTest.java
@@ -0,0 +1,1071 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import tests.support.Support_ListTest;
+
+public class ArrayListTest extends junit.framework.TestCase {
+
+ List alist;
+
+ Object[] objArray;
+
+ /**
+ * java.util.ArrayList#ArrayList()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.ArrayList()
+ new Support_ListTest("", alist).runTest();
+
+ ArrayList subList = new ArrayList();
+ for (int i = -50; i < 150; i++)
+ subList.add(new Integer(i));
+ new Support_ListTest("", subList.subList(50, 150)).runTest();
+ }
+
+ /**
+ * java.util.ArrayList#ArrayList(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.ArrayList(int)
+ ArrayList al = new ArrayList(5);
+ assertEquals("Incorrect arrayList created", 0, al.size());
+
+ al = new ArrayList(0);
+ assertEquals("Incorrect arrayList created", 0, al.size());
+
+ try {
+ new ArrayList(-1);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * java.util.ArrayList#ArrayList(java.util.Collection)
+ */
+ public void test_ConstructorLjava_util_Collection() {
+ // Test for method java.util.ArrayList(java.util.Collection)
+ ArrayList al = new ArrayList(Arrays.asList(objArray));
+ assertTrue("arrayList created from collection has incorrect size", al
+ .size() == objArray.length);
+ for (int counter = 0; counter < objArray.length; counter++)
+ assertTrue(
+ "arrayList created from collection has incorrect elements",
+ al.get(counter) == objArray[counter]);
+ try {
+ new ArrayList(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ }
+
+ public void testConstructorWithConcurrentCollection() {
+ Collection<String> collection = shrinksOnSize("A", "B", "C", "D");
+ ArrayList<String> list = new ArrayList<String>(collection);
+ assertFalse(list.contains(null));
+ }
+
+ /**
+ * java.util.ArrayList#add(int, java.lang.Object)
+ */
+ public void test_addILjava_lang_Object() {
+ // Test for method void java.util.ArrayList.add(int, java.lang.Object)
+ Object o;
+ alist.add(50, o = new Object());
+ assertTrue("Failed to add Object", alist.get(50) == o);
+ assertTrue("Failed to fix up list after insert",
+ alist.get(51) == objArray[50]
+ && (alist.get(52) == objArray[51]));
+ Object oldItem = alist.get(25);
+ alist.add(25, null);
+ assertNull("Should have returned null", alist.get(25));
+ assertTrue("Should have returned the old item from slot 25", alist
+ .get(26) == oldItem);
+
+ alist.add(0, o = new Object());
+ assertEquals("Failed to add Object", alist.get(0), o);
+ assertEquals(alist.get(1), objArray[0]);
+ assertEquals(alist.get(2), objArray[1]);
+
+ oldItem = alist.get(0);
+ alist.add(0, null);
+ assertNull("Should have returned null", alist.get(0));
+ assertEquals("Should have returned the old item from slot 0", alist
+ .get(1), oldItem);
+
+ try {
+ alist.add(-1, new Object());
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ alist.add(-1, null);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ alist.add(alist.size() + 1, new Object());
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ alist.add(alist.size() + 1, null);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+ }
+
+ /**
+ * java.util.ArrayList#add(int, java.lang.Object)
+ */
+ public void test_addILjava_lang_Object_2() {
+ Object o = new Object();
+ int size = alist.size();
+ alist.add(size, o);
+ assertEquals("Failed to add Object", alist.get(size), o);
+ assertEquals(alist.get(size - 2), objArray[size - 2]);
+ assertEquals(alist.get(size - 1), objArray[size - 1]);
+
+ alist.remove(size);
+
+ size = alist.size();
+ alist.add(size, null);
+ assertNull("Should have returned null", alist.get(size));
+ assertEquals(alist.get(size - 2), objArray[size - 2]);
+ assertEquals(alist.get(size - 1), objArray[size - 1]);
+ }
+
+ /**
+ * java.util.ArrayList#add(java.lang.Object)
+ */
+ public void test_addLjava_lang_Object() {
+ // Test for method boolean java.util.ArrayList.add(java.lang.Object)
+ Object o = new Object();
+ alist.add(o);
+ assertTrue("Failed to add Object", alist.get(alist.size() - 1) == o);
+ alist.add(null);
+ assertNull("Failed to add null", alist.get(alist.size() - 1));
+ }
+
+ /**
+ * java.util.ArrayList#addAll(int, java.util.Collection)
+ */
+ public void test_addAllILjava_util_Collection() {
+ // Test for method boolean java.util.ArrayList.addAll(int,
+ // java.util.Collection)
+ alist.addAll(50, alist);
+ assertEquals("Returned incorrect size after adding to existing list",
+ 200, alist.size());
+ for (int i = 0; i < 50; i++)
+ assertTrue("Manipulated elements < index",
+ alist.get(i) == objArray[i]);
+ for (int i = 0; i >= 50 && (i < 150); i++)
+ assertTrue("Failed to ad elements properly",
+ alist.get(i) == objArray[i - 50]);
+ for (int i = 0; i >= 150 && (i < 200); i++)
+ assertTrue("Failed to ad elements properly",
+ alist.get(i) == objArray[i - 100]);
+ ArrayList listWithNulls = new ArrayList();
+ listWithNulls.add(null);
+ listWithNulls.add(null);
+ listWithNulls.add("yoink");
+ listWithNulls.add("kazoo");
+ listWithNulls.add(null);
+ alist.addAll(100, listWithNulls);
+ assertTrue("Incorrect size: " + alist.size(), alist.size() == 205);
+ assertNull("Item at slot 100 should be null", alist.get(100));
+ assertNull("Item at slot 101 should be null", alist.get(101));
+ assertEquals("Item at slot 102 should be 'yoink'", "yoink", alist
+ .get(102));
+ assertEquals("Item at slot 103 should be 'kazoo'", "kazoo", alist
+ .get(103));
+ assertNull("Item at slot 104 should be null", alist.get(104));
+ alist.addAll(205, listWithNulls);
+ assertTrue("Incorrect size2: " + alist.size(), alist.size() == 210);
+ }
+
+ /**
+ * java.util.ArrayList#addAll(int, java.util.Collection)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_addAllILjava_util_Collection_2() {
+ // Regression for HARMONY-467
+ ArrayList obj = new ArrayList();
+ try {
+ obj.addAll((int) -1, (Collection) null);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ // Regression for HARMONY-5705
+ String[] data = new String[] { "1", "2", "3", "4", "5", "6", "7", "8" };
+ ArrayList list1 = new ArrayList();
+ ArrayList list2 = new ArrayList();
+ for (String d : data) {
+ list1.add(d);
+ list2.add(d);
+ list2.add(d);
+ }
+ while (list1.size() > 0)
+ list1.remove(0);
+ list1.addAll(list2);
+ assertTrue("The object list is not the same as original list", list1
+ .containsAll(list2)
+ && list2.containsAll(list1));
+
+ obj = new ArrayList();
+ for (int i = 0; i < 100; i++) {
+ if (list1.size() > 0) {
+ obj.removeAll(list1);
+ obj.addAll(list1);
+ }
+ }
+ assertTrue("The object list is not the same as original list", obj
+ .containsAll(list1)
+ && list1.containsAll(obj));
+
+ // Regression for Harmony-5799
+ list1 = new ArrayList();
+ list2 = new ArrayList();
+ int location = 2;
+
+ String[] strings = { "0", "1", "2", "3", "4", "5", "6" };
+ int[] integers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ for (int i = 0; i < 7; i++) {
+ list1.add(strings[i]);
+ }
+ for (int i = 0; i < 10; i++) {
+ list2.add(integers[i]);
+ }
+ list1.remove(location);
+ list1.addAll(location, list2);
+
+ // Inserted elements should be equal to integers array
+ for (int i = 0; i < integers.length; i++) {
+ assertEquals(integers[i], list1.get(location + i));
+ }
+ // Elements after inserted location should
+ // be equals to related elements in strings array
+ for (int i = location + 1; i < strings.length; i++) {
+ assertEquals(strings[i], list1.get(i + integers.length - 1));
+ }
+ }
+
+ /**
+ * java.util.ArrayList#addAll(int, java.util.Collection)
+ */
+ public void test_addAllILjava_util_Collection_3() {
+ ArrayList obj = new ArrayList();
+ obj.addAll(0, obj);
+ obj.addAll(obj.size(), obj);
+ try {
+ obj.addAll(-1, obj);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ obj.addAll(obj.size() + 1, obj);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ obj.addAll(0, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Excepted
+ }
+
+ try {
+ obj.addAll(obj.size() + 1, null);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ obj.addAll((int) -1, (Collection) null);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+ }
+
+// BEGIN android-removed
+// The spec does not mandate that IndexOutOfBoundsException be thrown in
+// preference to NullPointerException when the caller desserves both.
+//
+// /**
+// * java.util.ArrayList#addAll(int, java.util.Collection)
+// */
+// public void test_addAllILjava_util_Collection_2() {
+// // Regression for HARMONY-467
+// ArrayList obj = new ArrayList();
+// try {
+// obj.addAll((int) -1, (Collection) null);
+// fail("IndexOutOfBoundsException expected");
+// } catch (IndexOutOfBoundsException e) {
+// }
+// }
+// END android-removed
+
+ /**
+ * java.util.ArrayList#addAll(java.util.Collection)
+ */
+ public void test_addAllLjava_util_Collection() {
+ // Test for method boolean
+ // java.util.ArrayList.addAll(java.util.Collection)
+ List l = new ArrayList();
+ l.addAll(alist);
+ for (int i = 0; i < alist.size(); i++)
+ assertTrue("Failed to add elements properly", l.get(i).equals(
+ alist.get(i)));
+ alist.addAll(alist);
+ assertEquals("Returned incorrect size after adding to existing list",
+ 200, alist.size());
+ for (int i = 0; i < 100; i++) {
+ assertTrue("Added to list in incorrect order", alist.get(i).equals(
+ l.get(i)));
+ assertTrue("Failed to add to existing list", alist.get(i + 100)
+ .equals(l.get(i)));
+ }
+ Set setWithNulls = new HashSet();
+ setWithNulls.add(null);
+ setWithNulls.add(null);
+ setWithNulls.add("yoink");
+ setWithNulls.add("kazoo");
+ setWithNulls.add(null);
+ alist.addAll(100, setWithNulls);
+ Iterator i = setWithNulls.iterator();
+ assertTrue("Item at slot 100 is wrong: " + alist.get(100), alist
+ .get(100) == i.next());
+ assertTrue("Item at slot 101 is wrong: " + alist.get(101), alist
+ .get(101) == i.next());
+ assertTrue("Item at slot 103 is wrong: " + alist.get(102), alist
+ .get(102) == i.next());
+
+ try {
+ alist.addAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Excepted
+ }
+
+ // Regression test for Harmony-3481
+ ArrayList<Integer> originalList = new ArrayList<Integer>(12);
+ for (int j = 0; j < 12; j++) {
+ originalList.add(j);
+ }
+
+ originalList.remove(0);
+ originalList.remove(0);
+
+ ArrayList<Integer> additionalList = new ArrayList<Integer>(11);
+ for (int j = 0; j < 11; j++) {
+ additionalList.add(j);
+ }
+ assertTrue(originalList.addAll(additionalList));
+ assertEquals(21, originalList.size());
+
+ }
+
+ public void test_ArrayList_addAll_scenario1() {
+ ArrayList arrayListA = new ArrayList();
+ arrayListA.add(1);
+ ArrayList arrayListB = new ArrayList();
+ arrayListB.add(1);
+ arrayListA.addAll(1, arrayListB);
+ int size = arrayListA.size();
+ assertEquals(2, size);
+ for (int index = 0; index < size; index++) {
+ assertEquals(1, arrayListA.get(index));
+ }
+ }
+
+ public void test_ArrayList_addAll_scenario2() {
+ ArrayList arrayList = new ArrayList();
+ arrayList.add(1);
+ arrayList.addAll(1, arrayList);
+ int size = arrayList.size();
+ assertEquals(2, size);
+ for (int index = 0; index < size; index++) {
+ assertEquals(1, arrayList.get(index));
+ }
+ }
+
+ // Regression test for HARMONY-5839
+ public void testaddAllHarmony5839() {
+ Collection coll = Arrays.asList(new String[] { "1", "2" });
+ List list = new ArrayList();
+ list.add("a");
+ list.add(0, "b");
+ list.add(0, "c");
+ list.add(0, "d");
+ list.add(0, "e");
+ list.add(0, "f");
+ list.add(0, "g");
+ list.add(0, "h");
+ list.add(0, "i");
+
+ list.addAll(6, coll);
+
+ assertEquals(11, list.size());
+ assertFalse(list.contains(null));
+ }
+
+ /**
+ * java.util.ArrayList#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.ArrayList.clear()
+ alist.clear();
+ assertEquals("List did not clear", 0, alist.size());
+ alist.add(null);
+ alist.add(null);
+ alist.add(null);
+ alist.add("bam");
+ alist.clear();
+ assertEquals("List with nulls did not clear", 0, alist.size());
+ /*
+ * for (int i = 0; i < alist.size(); i++) assertNull("Failed to clear
+ * list", alist.get(i));
+ */
+
+ }
+
+ /**
+ * java.util.ArrayList#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.ArrayList.clone()
+ ArrayList x = (ArrayList) (((ArrayList) (alist)).clone());
+ assertTrue("Cloned list was inequal to original", x.equals(alist));
+ for (int i = 0; i < alist.size(); i++)
+ assertTrue("Cloned list contains incorrect elements",
+ alist.get(i) == x.get(i));
+
+ alist.add(null);
+ alist.add(25, null);
+ x = (ArrayList) (((ArrayList) (alist)).clone());
+ assertTrue("nulls test - Cloned list was inequal to original", x
+ .equals(alist));
+ for (int i = 0; i < alist.size(); i++)
+ assertTrue("nulls test - Cloned list contains incorrect elements",
+ alist.get(i) == x.get(i));
+
+ }
+
+ /**
+ * java.util.ArrayList#contains(java.lang.Object)
+ */
+ public void test_containsLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.ArrayList.contains(java.lang.Object)
+ assertTrue("Returned false for valid element", alist
+ .contains(objArray[99]));
+ assertTrue("Returned false for equal element", alist
+ .contains(new Integer(8)));
+ assertTrue("Returned true for invalid element", !alist
+ .contains(new Object()));
+ assertTrue("Returned true for null but should have returned false",
+ !alist.contains(null));
+ alist.add(null);
+ assertTrue("Returned false for null but should have returned true",
+ alist.contains(null));
+ }
+
+ /**
+ * java.util.ArrayList#ensureCapacity(int)
+ */
+ public void test_ensureCapacityI() throws Exception {
+ // Test for method void java.util.ArrayList.ensureCapacity(int)
+ // TODO : There is no good way to test this as it only really impacts on
+ // the private implementation.
+
+ Object testObject = new Object();
+ int capacity = 20;
+ ArrayList al = new ArrayList(capacity);
+ int i;
+ for (i = 0; i < capacity / 2; i++) {
+ al.add(i, new Object());
+ }
+ al.add(i, testObject);
+ int location = al.indexOf(testObject);
+ al.ensureCapacity(capacity);
+ assertTrue("EnsureCapacity moved objects around in array1.",
+ location == al.indexOf(testObject));
+ al.remove(0);
+ al.ensureCapacity(capacity);
+ assertTrue("EnsureCapacity moved objects around in array2.",
+ --location == al.indexOf(testObject));
+ al.ensureCapacity(capacity + 2);
+ assertTrue("EnsureCapacity did not change location.", location == al
+ .indexOf(testObject));
+
+ ArrayList<String> list = new ArrayList<String>(1);
+ list.add("hello");
+ list.ensureCapacity(Integer.MIN_VALUE);
+ }
+
+ /**
+ * java.util.ArrayList#get(int)
+ */
+ public void test_getI() {
+ // Test for method java.lang.Object java.util.ArrayList.get(int)
+ assertTrue("Returned incorrect element", alist.get(22) == objArray[22]);
+ try {
+ alist.get(8765);
+ fail("Failed to throw expected exception for index > size");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+ }
+
+ /**
+ * java.util.ArrayList#indexOf(java.lang.Object)
+ */
+ public void test_indexOfLjava_lang_Object() {
+ // Test for method int java.util.ArrayList.indexOf(java.lang.Object)
+ assertEquals("Returned incorrect index", 87, alist
+ .indexOf(objArray[87]));
+ assertEquals("Returned index for invalid Object", -1, alist
+ .indexOf(new Object()));
+ alist.add(25, null);
+ alist.add(50, null);
+ assertTrue("Wrong indexOf for null. Wanted 25 got: "
+ + alist.indexOf(null), alist.indexOf(null) == 25);
+ }
+
+ /**
+ * java.util.ArrayList#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.ArrayList.isEmpty()
+ assertTrue("isEmpty returned false for new list", new ArrayList()
+ .isEmpty());
+ assertTrue("Returned true for existing list with elements", !alist
+ .isEmpty());
+ }
+
+ /**
+ * java.util.ArrayList#lastIndexOf(java.lang.Object)
+ */
+ public void test_lastIndexOfLjava_lang_Object() {
+ // Test for method int java.util.ArrayList.lastIndexOf(java.lang.Object)
+ alist.add(new Integer(99));
+ assertEquals("Returned incorrect index", 100, alist
+ .lastIndexOf(objArray[99]));
+ assertEquals("Returned index for invalid Object", -1, alist
+ .lastIndexOf(new Object()));
+ alist.add(25, null);
+ alist.add(50, null);
+ assertTrue("Wrong lastIndexOf for null. Wanted 50 got: "
+ + alist.lastIndexOf(null), alist.lastIndexOf(null) == 50);
+ }
+
+ /**
+ * {@link java.util.ArrayList#removeRange(int, int)}
+ */
+ public void test_removeRange() {
+ MockArrayList mylist = new MockArrayList();
+ mylist.removeRange(0, 0);
+
+ try {
+ mylist.removeRange(0, 1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ int[] data = { 1, 2, 3 };
+ for (int i = 0; i < data.length; i++) {
+ mylist.add(i, data[i]);
+ }
+
+ mylist.removeRange(0, 1);
+ assertEquals(data[1], mylist.get(0));
+ assertEquals(data[2], mylist.get(1));
+
+ try {
+ mylist.removeRange(-1, 1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ mylist.removeRange(0, -1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ mylist.removeRange(1, 0);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ mylist.removeRange(2, 1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+ }
+
+ /**
+ * java.util.ArrayList#remove(int)
+ */
+ public void test_removeI() {
+ // Test for method java.lang.Object java.util.ArrayList.remove(int)
+ alist.remove(10);
+ assertEquals("Failed to remove element", -1, alist
+ .indexOf(objArray[10]));
+ try {
+ alist.remove(999);
+ fail("Failed to throw exception when index out of range");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ ArrayList myList = (ArrayList) (((ArrayList) (alist)).clone());
+ alist.add(25, null);
+ alist.add(50, null);
+ alist.remove(50);
+ alist.remove(25);
+ assertTrue("Removing nulls did not work", alist.equals(myList));
+
+ List list = new ArrayList(Arrays.asList(new String[] { "a", "b", "c",
+ "d", "e", "f", "g" }));
+ assertTrue("Removed wrong element 1", list.remove(0) == "a");
+ assertTrue("Removed wrong element 2", list.remove(4) == "f");
+ String[] result = new String[5];
+ list.toArray(result);
+ assertTrue("Removed wrong element 3", Arrays.equals(result,
+ new String[] { "b", "c", "d", "e", "g" }));
+
+ List l = new ArrayList(0);
+ l.add(new Object());
+ l.add(new Object());
+ l.remove(0);
+ l.remove(0);
+ try {
+ l.remove(-1);
+ fail("-1 should cause exception");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+ try {
+ l.remove(0);
+ fail("0 should case exception");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+ }
+
+ /**
+ * java.util.ArrayList#set(int, java.lang.Object)
+ */
+ public void test_setILjava_lang_Object() {
+ // Test for method java.lang.Object java.util.ArrayList.set(int,
+ // java.lang.Object)
+ Object obj;
+ alist.set(65, obj = new Object());
+ assertTrue("Failed to set object", alist.get(65) == obj);
+ alist.set(50, null);
+ assertNull("Setting to null did not work", alist.get(50));
+ assertTrue("Setting increased the list's size to: " + alist.size(),
+ alist.size() == 100);
+
+ obj = new Object();
+ alist.set(0, obj);
+ assertTrue("Failed to set object", alist.get(0) == obj);
+
+ try {
+ alist.set(-1, obj);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ alist.set(alist.size(), obj);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ alist.set(-1, null);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+
+ try {
+ alist.set(alist.size(), null);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertNotNull(e.getMessage());
+ }
+ }
+
+ /**
+ * java.util.ArrayList#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.ArrayList.size()
+ assertEquals("Returned incorrect size for exiting list", 100, alist
+ .size());
+ assertEquals("Returned incorrect size for new list", 0, new ArrayList()
+ .size());
+ }
+
+ /**
+ * java.util.AbstractCollection#toString()
+ */
+ public void test_toString() {
+ ArrayList l = new ArrayList(1);
+ l.add(l);
+ String result = l.toString();
+ assertTrue("should contain self ref", result.indexOf("(this") > -1);
+ }
+
+ /**
+ * java.util.ArrayList#toArray()
+ */
+ public void test_toArray() {
+ // Test for method java.lang.Object [] java.util.ArrayList.toArray()
+ alist.set(25, null);
+ alist.set(75, null);
+ Object[] obj = alist.toArray();
+ assertEquals("Returned array of incorrect size", objArray.length,
+ obj.length);
+
+ for (int i = 0; i < obj.length; i++) {
+ if ((i == 25) || (i == 75))
+ assertNull("Should be null at: " + i + " but instead got: "
+ + obj[i], obj[i]);
+ else
+ assertTrue("Returned incorrect array: " + i,
+ obj[i] == objArray[i]);
+ }
+
+ }
+
+ /**
+ * java.util.ArrayList#toArray(java.lang.Object[])
+ */
+ public void test_toArray$Ljava_lang_Object() {
+ // Test for method java.lang.Object []
+ // java.util.ArrayList.toArray(java.lang.Object [])
+ alist.set(25, null);
+ alist.set(75, null);
+ Integer[] argArray = new Integer[100];
+ Object[] retArray;
+ retArray = alist.toArray(argArray);
+ assertTrue("Returned different array than passed", retArray == argArray);
+ argArray = new Integer[1000];
+ retArray = alist.toArray(argArray);
+ assertNull("Failed to set first extra element to null", argArray[alist
+ .size()]);
+ for (int i = 0; i < 100; i++) {
+ if ((i == 25) || (i == 75))
+ assertNull("Should be null: " + i, retArray[i]);
+ else
+ assertTrue("Returned incorrect array: " + i,
+ retArray[i] == objArray[i]);
+ }
+
+ String[] strArray = new String[100];
+ try {
+ alist.toArray(strArray);
+ fail("ArrayStoreException expected");
+ } catch (ArrayStoreException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.ArrayList#trimToSize()
+ */
+ public void test_trimToSize() {
+ // Test for method void java.util.ArrayList.trimToSize()
+ for (int i = 99; i > 24; i--)
+ alist.remove(i);
+ ((ArrayList) alist).trimToSize();
+ assertEquals("Returned incorrect size after trim", 25, alist.size());
+ for (int i = 0; i < alist.size(); i++)
+ assertTrue("Trimmed list contained incorrect elements", alist
+ .get(i) == objArray[i]);
+ Vector v = new Vector();
+ v.add("a");
+ ArrayList al = new ArrayList(v);
+ al.add("b");
+ Iterator it = al.iterator();
+ al.trimToSize();
+ try {
+ it.next();
+ fail("should throw a ConcurrentModificationException");
+ } catch (ConcurrentModificationException ioobe) {
+ // expected
+ }
+ }
+
+ public void test_trimToSize_02() {
+ ArrayList list = new ArrayList(Arrays.asList(new String[] { "a", "b", "c",
+ "d", "e", "f", "g" }));
+ list.remove("a");
+ list.remove("f");
+ list.trimToSize();
+ }
+
+ public void test_addAll() {
+ ArrayList list = new ArrayList();
+ list.add("one");
+ list.add("two");
+ assertEquals(2, list.size());
+
+ list.remove(0);
+ assertEquals(1, list.size());
+
+ ArrayList collection = new ArrayList();
+ collection.add("1");
+ collection.add("2");
+ collection.add("3");
+ assertEquals(3, collection.size());
+
+ list.addAll(0, collection);
+ assertEquals(4, list.size());
+
+ list.remove(0);
+ list.remove(0);
+ assertEquals(2, list.size());
+
+ collection.add("4");
+ collection.add("5");
+ collection.add("6");
+ collection.add("7");
+ collection.add("8");
+ collection.add("9");
+ collection.add("10");
+ collection.add("11");
+ collection.add("12");
+
+ assertEquals(12, collection.size());
+
+ list.addAll(0, collection);
+ assertEquals(14, list.size());
+ }
+
+ public void test_removeLjava_lang_Object() {
+ List list = new ArrayList(Arrays.asList(new String[] { "a", "b", "c",
+ "d", "e", "f", "g" }));
+ assertTrue("Removed wrong element 1", list.remove("a"));
+ assertTrue("Removed wrong element 2", list.remove("f"));
+ String[] result = new String[5];
+ list.toArray(result);
+ assertTrue("Removed wrong element 3", Arrays.equals(result,
+ new String[] { "b", "c", "d", "e", "g" }));
+ }
+
+ public void testAddAllWithConcurrentCollection() {
+ ArrayList<String> list = new ArrayList<String>();
+ list.addAll(shrinksOnSize("A", "B", "C", "D"));
+ assertFalse(list.contains(null));
+ }
+
+ public void testAddAllAtPositionWithConcurrentCollection() {
+ ArrayList<String> list = new ArrayList<String>(
+ Arrays.asList("A", "B", "C", "D"));
+
+ list.addAll(3, shrinksOnSize("E", "F", "G", "H"));
+ assertFalse(list.contains(null));
+ }
+
+ public void test_override_size() throws Exception {
+ ArrayList testlist = new MockArrayList();
+ // though size is overriden, it should passed without exception
+ testlist.add("test_0");
+ testlist.add("test_1");
+ testlist.add("test_2");
+ testlist.add(1, "test_3");
+ testlist.get(1);
+ testlist.remove(2);
+ testlist.set(1, "test_4");
+ }
+
+ public class MockArrayList extends ArrayList {
+ public int size() {
+ return 0;
+ }
+
+ public void removeRange(int begin, int end) {
+ super.removeRange(begin, end);
+ }
+ }
+
+ public void test_removeRangeII() {
+ MockArrayList mal = new MockArrayList();
+ mal.add("a");
+ mal.add("b");
+ mal.add("c");
+ mal.add("d");
+ mal.add("e");
+ mal.add("f");
+ mal.add("g");
+ mal.add("h");
+
+ mal.removeRange(2, 4);
+
+ String[] result = new String[6];
+ mal.toArray(result);
+ assertTrue("Removed wrong element 3", Arrays.equals(result,
+ new String[] { "a", "b", "e", "f", "g", "h"}));
+ }
+
+ public static class ArrayListExtend extends ArrayList {
+
+ private int size = 0;
+
+ public ArrayListExtend() {
+ super(10);
+ }
+
+ public boolean add(Object o) {
+ size++;
+ return super.add(o);
+ }
+
+ public int size() {
+ return size;
+ }
+ }
+
+ public void test_subclassing() {
+ ArrayListExtend a = new ArrayListExtend();
+ /*
+ * Regression test for subclasses that override size() (which used to
+ * cause an exception when growing 'a').
+ */
+ for (int i = 0; i < 100; i++) {
+ a.add(new Object());
+ }
+ }
+
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ objArray = new Object[100];
+ for (int i = 0; i < objArray.length; i++) {
+ objArray[i] = new Integer(i);
+ }
+
+ alist = new ArrayList();
+ for (int i = 0; i < objArray.length; i++) {
+ alist.add(objArray[i]);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ objArray = null;
+ alist = null;
+
+ super.tearDown();
+ }
+
+ /**
+ * Returns a collection that emulates another thread calling remove() each
+ * time the current thread calls size().
+ */
+ private <T> Collection<T> shrinksOnSize(T... elements) {
+ return new HashSet<T>(Arrays.asList(elements)) {
+ boolean shrink = true;
+
+ @Override
+ public int size() {
+ int result = super.size();
+ if (shrink) {
+ Iterator<T> i = iterator();
+ i.next();
+ i.remove();
+ }
+ return result;
+ }
+
+ @Override
+ public Object[] toArray() {
+ shrink = false;
+ return super.toArray();
+ }
+ };
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/Arrays2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/Arrays2Test.java
new file mode 100644
index 0000000..d6adbb5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/Arrays2Test.java
@@ -0,0 +1,472 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.RandomAccess;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class Arrays2Test extends TestCase {
+
+ /**
+ * java.util.Arrays#binarySearch(double[], double)
+ */
+ public void test_binarySearch$DD() {
+ double[] specials = new double[] { Double.NEGATIVE_INFINITY,
+ -Double.MAX_VALUE, -2d, -Double.MIN_VALUE, -0d, 0d,
+ Double.MIN_VALUE, 2d, Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY, Double.NaN };
+
+ for (int i = 0; i < specials.length; i++) {
+ int result = Arrays.binarySearch(specials, specials[i]);
+ assertTrue("Assert 0: " + specials[i] + " invalid: " + result,
+ result == i);
+ }
+ assertEquals("Assert 1: Invalid search index for -1d",
+ -4, Arrays.binarySearch(specials, -1d));
+ assertEquals("Assert 2: Invalid search index for 1d",
+ -8, Arrays.binarySearch(specials, 1d));
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(float[], float)
+ */
+ public void test_binarySearch$FF() {
+ float[] specials = new float[] { Float.NEGATIVE_INFINITY,
+ -Float.MAX_VALUE, -2f, -Float.MIN_VALUE, -0f, 0f,
+ Float.MIN_VALUE, 2f, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
+ Float.NaN };
+
+ for (int i = 0; i < specials.length; i++) {
+ int result = Arrays.binarySearch(specials, specials[i]);
+ assertTrue("Assert 0: " + specials[i] + " invalid: " + result,
+ result == i);
+ }
+ assertEquals("Assert 1: Invalid search index for -1f",
+ -4, Arrays.binarySearch(specials, -1f));
+ assertEquals("Assert 2: Invalid search index for 1f",
+ -8, Arrays.binarySearch(specials, 1f));
+ }
+
+ /**
+ * java.util.Arrays#equals(double[], double[])
+ */
+ public void test_equals$D$D() {
+ double d[] = new double[100];
+ double x[] = new double[100];
+ Arrays.fill(d, Double.MAX_VALUE);
+ Arrays.fill(x, Double.MIN_VALUE);
+
+ assertTrue("Assert 0: Inequal arrays returned true", !Arrays.equals(d, x));
+
+ Arrays.fill(x, Double.MAX_VALUE);
+ assertTrue("Assert 1: equal arrays returned false", Arrays.equals(d, x));
+
+ assertTrue("Assert 2: should be false",
+ !Arrays.equals(new double[] { 1.0 }, new double[] { 2.0 }));
+
+ assertTrue("Assert 3: NaN not equals",
+ Arrays.equals(new double[] { Double.NaN }, new double[] { Double.NaN }));
+ assertTrue("Assert 4: 0d equals -0d",
+ !Arrays.equals(new double[] { 0d }, new double[] { -0d }));
+ }
+
+ /**
+ * java.util.Arrays#equals(float[], float[])
+ */
+ public void test_equals$F$F() {
+ float d[] = new float[100];
+ float x[] = new float[100];
+ Arrays.fill(d, Float.MAX_VALUE);
+ Arrays.fill(x, Float.MIN_VALUE);
+
+ assertTrue("Assert 0: Inequal arrays returned true", !Arrays.equals(d, x));
+
+ Arrays.fill(x, Float.MAX_VALUE);
+ assertTrue("Assert 1: equal arrays returned false", Arrays.equals(d, x));
+
+ assertTrue("Assert 2: NaN not equals",
+ Arrays.equals(new float[] { Float.NaN }, new float[] { Float.NaN }));
+ assertTrue("Assert 3: 0f equals -0f",
+ !Arrays.equals(new float[] { 0f }, new float[] { -0f }));
+ }
+
+ /**
+ * java.util.Arrays#sort(double[])
+ */
+ public void test_sort$D() {
+ // Test a basic sort
+ double[] reversedArray = new double[100];
+ for (int counter = 0; counter < reversedArray.length; counter++) {
+ reversedArray[counter] = (reversedArray.length - counter - 1);
+ }
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < reversedArray.length; counter++) {
+ assertTrue("Assert 0: Resulting array not sorted",
+ reversedArray[counter] == counter);
+ }
+
+ // These have to sort as per the Double compare ordering
+ double[] specials1 = new double[] { Double.NaN, Double.MAX_VALUE, Double.MIN_VALUE, 0d, -0d, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY };
+ double[] specials2 = new double[] { 0d, Double.POSITIVE_INFINITY, -0d, Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Double.NaN, Double.MAX_VALUE };
+ double[] answer = new double[] { Double.NEGATIVE_INFINITY, -0d, 0d, Double.MIN_VALUE, Double.MAX_VALUE, Double.POSITIVE_INFINITY, Double.NaN };
+
+ Arrays.sort(specials1);
+ Object[] print1 = new Object[specials1.length];
+ for (int i = 0; i < specials1.length; i++) {
+ print1[i] = new Double(specials1[i]);
+ }
+ assertTrue("Assert 1: specials sort incorrectly" + Arrays.asList(print1),
+ Arrays.equals(specials1, answer));
+
+ Arrays.sort(specials2);
+ Object[] print2 = new Object[specials2.length];
+ for (int i = 0; i < specials2.length; i++) {
+ print2[i] = new Double(specials2[i]);
+ }
+ assertTrue("Assert 2: specials sort incorrectly " + Arrays.asList(print2),
+ Arrays.equals(specials2, answer));
+ }
+
+ /**
+ * java.util.Arrays#sort(float[])
+ */
+ public void test_sort$F() {
+ // Test a basic sort
+ float[] reversedArray = new float[100];
+ for (int counter = 0; counter < reversedArray.length; counter++) {
+ reversedArray[counter] = (reversedArray.length - counter - 1);
+ }
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < reversedArray.length; counter++) {
+ assertTrue("Assert 0: Resulting array not sorted",
+ reversedArray[counter] == counter);
+ }
+
+ float[] specials1 = new float[] { Float.NaN, Float.MAX_VALUE, Float.MIN_VALUE, 0f, -0f, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY };
+ float[] specials2 = new float[] { 0f, Float.POSITIVE_INFINITY, -0f, Float.NEGATIVE_INFINITY, Float.MIN_VALUE, Float.NaN, Float.MAX_VALUE };
+ float[] answer = new float[] { Float.NEGATIVE_INFINITY, -0f, 0f, Float.MIN_VALUE, Float.MAX_VALUE, Float.POSITIVE_INFINITY, Float.NaN };
+
+ Arrays.sort(specials1);
+ Object[] print1 = new Object[specials1.length];
+ for (int i = 0; i < specials1.length; i++) {
+ print1[i] = new Float(specials1[i]);
+ }
+ assertTrue("Assert 1: specials sort incorrectly" + Arrays.asList(print1),
+ Arrays.equals(specials1, answer));
+
+ Arrays.sort(specials2);
+ Object[] print2 = new Object[specials2.length];
+ for (int i = 0; i < specials2.length; i++) {
+ print2[i] = new Float(specials2[i]);
+ }
+ assertTrue("Assert 2: specials sort incorrectly" + Arrays.asList(print2),
+ Arrays.equals(specials2, answer));
+ }
+
+ /**
+ * java.util.Arrays#toString(boolean[])
+ */
+ public void test_toString$Z() {
+ assertEquals("null", Arrays.toString((boolean[]) null));
+ assertEquals("[]", Arrays.toString(new boolean[] { }));
+ assertEquals("[true]", Arrays.toString(new boolean[] { true }));
+ assertEquals("[true, false]", Arrays.toString(new boolean[] { true, false }));
+ assertEquals("[true, false, true]", Arrays.toString(new boolean[] { true, false, true }));
+ }
+
+ /**
+ * java.util.Arrays#toString(byte[])
+ */
+ public void test_toString$B() {
+ assertEquals("null", Arrays.toString((byte[]) null));
+ assertEquals("[]", Arrays.toString(new byte[] { }));
+ assertEquals("[0]", Arrays.toString(new byte[] { 0 }));
+ assertEquals("[-1, 0]", Arrays.toString(new byte[] { -1, 0 }));
+ assertEquals("[-1, 0, 1]", Arrays.toString(new byte[] { -1, 0, 1 }));
+ }
+
+ /**
+ * java.util.Arrays#toString(char[])
+ */
+ public void test_toString$C() {
+ assertEquals("null", Arrays.toString((char[]) null));
+ assertEquals("[]", Arrays.toString(new char[] { }));
+ assertEquals("[a]", Arrays.toString(new char[] { 'a' }));
+ assertEquals("[a, b]", Arrays.toString(new char[] { 'a', 'b' }));
+ assertEquals("[a, b, c]", Arrays.toString(new char[] { 'a', 'b', 'c' }));
+ }
+
+ /**
+ * java.util.Arrays#toString(double[])
+ */
+ public void test_toString$D() {
+ assertEquals("null", Arrays.toString((double[]) null));
+ assertEquals("[]", Arrays.toString(new double[] { }));
+ assertEquals("[0.0]", Arrays.toString(new double[] { 0.0D }));
+ assertEquals("[-1.0, 0.0]", Arrays.toString(new double[] { -1.0D, 0.0D }));
+ assertEquals("[-1.0, 0.0, 1.0]", Arrays.toString(new double[] { -1.0D, 0.0D, 1.0D }));
+ }
+
+ /**
+ * java.util.Arrays#toString(float[])
+ */
+ public void test_toString$F() {
+ assertEquals("null", Arrays.toString((float[]) null));
+ assertEquals("[]", Arrays.toString(new float[] { }));
+ assertEquals("[0.0]", Arrays.toString(new float[] { 0.0F }));
+ assertEquals("[-1.0, 0.0]", Arrays.toString(new float[] { -1.0F, 0.0F }));
+ assertEquals("[-1.0, 0.0, 1.0]", Arrays.toString(new float[] { -1.0F, 0.0F, 1.0F }));
+ }
+
+ /**
+ * java.util.Arrays#toString(int[])
+ */
+ public void test_toString$I() {
+ assertEquals("null", Arrays.toString((int[]) null));
+ assertEquals("[]", Arrays.toString(new int[] { }));
+ assertEquals("[0]", Arrays.toString(new int[] { 0 }));
+ assertEquals("[-1, 0]", Arrays.toString(new int[] { -1, 0 }));
+ assertEquals("[-1, 0, 1]", Arrays.toString(new int[] { -1, 0, 1 }));
+ }
+
+ /**
+ * java.util.Arrays#toString(long[])
+ */
+ public void test_toString$J() {
+ assertEquals("null", Arrays.toString((long[]) null));
+ assertEquals("[]", Arrays.toString(new long[] { }));
+ assertEquals("[0]", Arrays.toString(new long[] { 0 }));
+ assertEquals("[-1, 0]", Arrays.toString(new long[] { -1, 0 }));
+ assertEquals("[-1, 0, 1]", Arrays.toString(new long[] { -1, 0, 1 }));
+ }
+
+ /**
+ * java.util.Arrays#toString(short[])
+ */
+ public void test_toString$S() {
+ assertEquals("null", Arrays.toString((short[]) null));
+ assertEquals("[]", Arrays.toString(new short[] { }));
+ assertEquals("[0]", Arrays.toString(new short[] { 0 }));
+ assertEquals("[-1, 0]", Arrays.toString(new short[] { -1, 0 }));
+ assertEquals("[-1, 0, 1]", Arrays.toString(new short[] { -1, 0, 1 }));
+ }
+
+ /**
+ * java.util.Arrays#toString(Object[])
+ */
+ public void test_toString$Ljava_lang_Object() {
+ assertEquals("null", Arrays.toString((Object[]) null));
+ assertEquals("[]", Arrays.toString(new Object[] { }));
+ assertEquals("[fixture]", Arrays.toString(new Object[] { "fixture" }));
+ assertEquals("[fixture, null]", Arrays.toString(new Object[] { "fixture", null }));
+ assertEquals("[fixture, null, fixture]", Arrays.toString(new Object[] { "fixture", null, "fixture" }));
+ }
+
+ /**
+ * java.util.Arrays#deepToString(Object[])
+ */
+ public void test_deepToString$java_lang_Object() {
+ assertEquals("null", Arrays.deepToString((Object[]) null));
+ assertEquals("[]", Arrays.deepToString(new Object[] { }));
+ assertEquals("[fixture]", Arrays.deepToString(new Object[] { "fixture" }));
+ assertEquals("[fixture, null]", Arrays.deepToString(new Object[] { "fixture", null }));
+ assertEquals("[fixture, null, fixture]", Arrays.deepToString(new Object[] { "fixture", null, "fixture" }));
+
+ Object[] fixture = new Object[1];
+ fixture[0] = fixture;
+ assertEquals("[[...]]", Arrays.deepToString(fixture));
+
+ fixture = new Object[2];
+ fixture[0] = "fixture";
+ fixture[1] = fixture;
+ assertEquals("[fixture, [...]]", Arrays.deepToString(fixture));
+
+ fixture = new Object[10];
+ fixture[0] = new boolean[] { true, false };
+ fixture[1] = new byte[] { 0, 1 };
+ fixture[2] = new char[] { 'a', 'b' };
+ fixture[3] = new double[] { 0.0D, 1.0D };
+ fixture[4] = new float[] { 0.0F, 1.0F };
+ fixture[5] = new int[] { 0, 1 };
+ fixture[6] = new long[] { 0L, 1L };
+ fixture[7] = new short[] { 0, 1 };
+ fixture[8] = fixture[0];
+ fixture[9] = new Object[9];
+ ((Object[]) fixture[9])[0] = fixture;
+ ((Object[]) fixture[9])[1] = fixture[1];
+ ((Object[]) fixture[9])[2] = fixture[2];
+ ((Object[]) fixture[9])[3] = fixture[3];
+ ((Object[]) fixture[9])[4] = fixture[4];
+ ((Object[]) fixture[9])[5] = fixture[5];
+ ((Object[]) fixture[9])[6] = fixture[6];
+ ((Object[]) fixture[9])[7] = fixture[7];
+ Object[] innerFixture = new Object[4];
+ innerFixture[0] = "innerFixture0";
+ innerFixture[1] = innerFixture;
+ innerFixture[2] = fixture;
+ innerFixture[3] = "innerFixture3";
+ ((Object[]) fixture[9])[8] = innerFixture;
+
+ String expected = "[[true, false], [0, 1], [a, b], [0.0, 1.0], [0.0, 1.0], [0, 1], [0, 1], [0, 1], [true, false], [[...], [0, 1], [a, b], [0.0, 1.0], [0.0, 1.0], [0, 1], [0, 1], [0, 1], [innerFixture0, [...], [...], innerFixture3]]]";
+
+ assertEquals(expected, Arrays.deepToString(fixture));
+ }
+
+ public void test_asListTvararg() throws Exception {
+ List<String> stringsList = Arrays.asList("0", "1");
+ assertEquals(2, stringsList.size());
+ assertEquals("0", stringsList.get(0));
+ assertEquals("1", stringsList.get(1));
+ assertTrue(stringsList instanceof RandomAccess);
+ assertTrue(stringsList instanceof Serializable);
+
+ assertEquals(stringsList, SerializationTest
+ .copySerializable((Serializable) stringsList));
+
+ //test from javadoc
+ List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
+ assertEquals(3, stooges.size());
+ assertEquals("Larry", stooges.get(0));
+ assertEquals("Moe", stooges.get(1));
+ assertEquals("Curly", stooges.get(2));
+
+ stringsList = Arrays.asList((String) null);
+ assertEquals(1, stringsList.size());
+ assertEquals((String) null, stringsList.get(0));
+
+ try {
+ Arrays.asList((Object[]) null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_binarySearch$TTLjava_util_ComparatorsuperT() {
+ String[] strings = new String[] { "a", "B", "c", "D" };
+ Arrays.sort(strings, String.CASE_INSENSITIVE_ORDER);
+ assertEquals(0, Arrays.binarySearch(strings, "a",
+ String.CASE_INSENSITIVE_ORDER));
+ assertEquals(0, Arrays.binarySearch(strings, "A",
+ String.CASE_INSENSITIVE_ORDER));
+ assertEquals(1, Arrays.binarySearch(strings, "b",
+ String.CASE_INSENSITIVE_ORDER));
+ assertEquals(1, Arrays.binarySearch(strings, "B",
+ String.CASE_INSENSITIVE_ORDER));
+ assertEquals(2, Arrays.binarySearch(strings, "c",
+ String.CASE_INSENSITIVE_ORDER));
+ assertEquals(2, Arrays.binarySearch(strings, "C",
+ String.CASE_INSENSITIVE_ORDER));
+ assertEquals(3, Arrays.binarySearch(strings, "d",
+ String.CASE_INSENSITIVE_ORDER));
+ assertEquals(3, Arrays.binarySearch(strings, "D",
+ String.CASE_INSENSITIVE_ORDER));
+
+
+ assertTrue(Arrays.binarySearch(strings, "e",
+ String.CASE_INSENSITIVE_ORDER) < 0);
+ assertTrue(Arrays.binarySearch(strings, "" + ('A' - 1),
+ String.CASE_INSENSITIVE_ORDER) < 0);
+
+ //test with null comparator, which switches back to Comparable
+ Arrays.sort(strings, null);
+ //B, D, a, c
+ assertEquals(2, Arrays.binarySearch(strings, "a", (Comparator<String>) null));
+ assertEquals(-1, Arrays.binarySearch(strings, "A", (Comparator<String>) null));
+ assertEquals(-4, Arrays.binarySearch(strings, "b", (Comparator<String>) null));
+ assertEquals(0, Arrays.binarySearch(strings, "B", (Comparator<String>) null));
+ assertEquals(3, Arrays.binarySearch(strings, "c", (Comparator<String>) null));
+ assertEquals(-2, Arrays.binarySearch(strings, "C", (Comparator<String>) null));
+ assertEquals(-5, Arrays.binarySearch(strings, "d", (Comparator<String>) null));
+ assertEquals(1, Arrays.binarySearch(strings, "D", (Comparator<String>) null));
+
+ assertTrue(Arrays.binarySearch(strings, "e", null) < 0);
+ assertTrue(Arrays.binarySearch(strings, "" + ('A' - 1), null) < 0);
+
+ try {
+ Arrays.binarySearch((String[]) null, "A", String.CASE_INSENSITIVE_ORDER);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Arrays.binarySearch(strings, (String) null, String.CASE_INSENSITIVE_ORDER);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Arrays.binarySearch(strings, (String) null, (Comparator<String>) null);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+
+ }
+
+ public void test_sort$TLjava_lang_ComparatorsuperT() {
+ String[] strings = new String[] { "a", "B", "c", "D" };
+ Arrays.sort(strings, String.CASE_INSENSITIVE_ORDER);
+ assertEquals("a", strings[0]);
+ assertEquals("B", strings[1]);
+ assertEquals("c", strings[2]);
+ assertEquals("D", strings[3]);
+
+ //test with null comparator, which switches back to Comparable
+ Arrays.sort(strings, null);
+ //B, D, a, c
+ assertEquals("B", strings[0]);
+ assertEquals("D", strings[1]);
+ assertEquals("a", strings[2]);
+ assertEquals("c", strings[3]);
+
+ try {
+ Arrays.sort((String[]) null, String.CASE_INSENSITIVE_ORDER);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_sort$TIILjava_lang_ComparatorsuperT() {
+ String[] strings = new String[] { "a", "B", "c", "D" };
+ Arrays.sort(strings, 0, strings.length, String.CASE_INSENSITIVE_ORDER);
+ assertEquals("a", strings[0]);
+ assertEquals("B", strings[1]);
+ assertEquals("c", strings[2]);
+ assertEquals("D", strings[3]);
+
+ //test with null comparator, which switches back to Comparable
+ Arrays.sort(strings, 0, strings.length, null);
+ //B, D, a, c
+ assertEquals("B", strings[0]);
+ assertEquals("D", strings[1]);
+ assertEquals("a", strings[2]);
+ assertEquals("c", strings[3]);
+
+ try {
+ Arrays.sort((String[]) null, String.CASE_INSENSITIVE_ORDER);
+ fail("No NPE");
+ } catch (NullPointerException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArraysTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArraysTest.java
new file mode 100644
index 0000000..277abce
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArraysTest.java
@@ -0,0 +1,4209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import tests.support.Support_UnmodifiableCollectionTest;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+public class ArraysTest extends junit.framework.TestCase {
+
+ public static class ReversedIntegerComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ return -(((Integer) o1).compareTo((Integer) o2));
+ }
+
+ public boolean equals(Object o1, Object o2) {
+ return ((Integer) o1).compareTo((Integer) o2) == 0;
+ }
+ }
+
+ static class MockComparable implements Comparable {
+ public int compareTo(Object o) {
+ return 0;
+ }
+ }
+
+ final static int arraySize = 100;
+
+ Object[] objArray;
+
+ boolean[] booleanArray;
+
+ byte[] byteArray;
+
+ char[] charArray;
+
+ double[] doubleArray;
+
+ float[] floatArray;
+
+ int[] intArray;
+
+ long[] longArray;
+
+ Object[] objectArray;
+
+ short[] shortArray;
+
+ /**
+ * java.util.Arrays#asList(java.lang.Object[])
+ */
+ public void test_asList$Ljava_lang_Object() {
+ // Test for method java.util.List
+ // java.util.Arrays.asList(java.lang.Object [])
+ List convertedList = Arrays.asList(objectArray);
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Array and List converted from array do not contain identical elements",
+ convertedList.get(counter) == objectArray[counter]);
+ }
+ convertedList.set(50, new Integer(1000));
+ assertTrue("set/get did not work on coverted list", convertedList.get(
+ 50).equals(new Integer(1000)));
+ convertedList.set(50, new Integer(50));
+ new Support_UnmodifiableCollectionTest("", convertedList).runTest();
+
+ Object[] myArray = (Object[]) (objectArray.clone());
+ myArray[30] = null;
+ myArray[60] = null;
+ convertedList = Arrays.asList(myArray);
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Array and List converted from array do not contain identical elements",
+ convertedList.get(counter) == myArray[counter]);
+ }
+
+ try {
+ Arrays.asList((Object[]) null);
+ fail("asList with null arg didn't throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(byte[], byte)
+ */
+ public void test_binarySearch$BB() {
+ // Test for method int java.util.Arrays.binarySearch(byte [], byte)
+ for (byte counter = 0; counter < arraySize; counter++)
+ assertTrue("Binary search on byte[] answered incorrect position",
+ Arrays.binarySearch(byteArray, counter) == counter);
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(intArray, (byte) -1));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(intArray, (byte) arraySize) == -(arraySize + 1));
+ for (byte counter = 0; counter < arraySize; counter++)
+ byteArray[counter] -= 50;
+ for (byte counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on byte[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(byteArray, (byte) (counter - 50)) == counter);
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(char[], char)
+ */
+ public void test_binarySearch$CC() {
+ // Test for method int java.util.Arrays.binarySearch(char [], char)
+ for (char counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on char[] answered incorrect position",
+ Arrays.binarySearch(charArray, (char) (counter + 1)) == counter);
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(charArray, '\u0000'));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(charArray, (char) (arraySize + 1)) == -(arraySize + 1));
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(double[], double)
+ */
+ public void test_binarySearch$DD() {
+ // Test for method int java.util.Arrays.binarySearch(double [], double)
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on double[] answered incorrect position",
+ Arrays.binarySearch(doubleArray, (double) counter) == (double) counter);
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(doubleArray, (double) -1));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(doubleArray, (double) arraySize) == -(arraySize + 1));
+ for (int counter = 0; counter < arraySize; counter++)
+ doubleArray[counter] -= (double) 50;
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on double[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(doubleArray, (double) (counter - 50)) == (double) counter);
+
+ double[] specials = new double[] { Double.NEGATIVE_INFINITY,
+ -Double.MAX_VALUE, -2d, -Double.MIN_VALUE, -0d, 0d,
+ Double.MIN_VALUE, 2d, Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY, Double.NaN };
+ for (int i = 0; i < specials.length; i++) {
+ int result = Arrays.binarySearch(specials, specials[i]);
+ assertTrue(specials[i] + " invalid: " + result, result == i);
+ }
+ assertEquals("-1d", -4, Arrays.binarySearch(specials, -1d));
+ assertEquals("1d", -8, Arrays.binarySearch(specials, 1d));
+
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(float[], float)
+ */
+ public void test_binarySearch$FF() {
+ // Test for method int java.util.Arrays.binarySearch(float [], float)
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on float[] answered incorrect position",
+ Arrays.binarySearch(floatArray, (float) counter) == (float) counter);
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(floatArray, (float) -1));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(floatArray, (float) arraySize) == -(arraySize + 1));
+ for (int counter = 0; counter < arraySize; counter++)
+ floatArray[counter] -= (float) 50;
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on float[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(floatArray, (float) counter - 50) == (float) counter);
+
+ float[] specials = new float[] { Float.NEGATIVE_INFINITY,
+ -Float.MAX_VALUE, -2f, -Float.MIN_VALUE, -0f, 0f,
+ Float.MIN_VALUE, 2f, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
+ Float.NaN };
+ for (int i = 0; i < specials.length; i++) {
+ int result = Arrays.binarySearch(specials, specials[i]);
+ assertTrue(specials[i] + " invalid: " + result, result == i);
+ }
+ assertEquals("-1f", -4, Arrays.binarySearch(specials, -1f));
+ assertEquals("1f", -8, Arrays.binarySearch(specials, 1f));
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(int[], int)
+ */
+ public void test_binarySearch$II() {
+ // Test for method int java.util.Arrays.binarySearch(int [], int)
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Binary search on int[] answered incorrect position",
+ Arrays.binarySearch(intArray, counter) == counter);
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(intArray, -1));
+ assertTrue("Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(intArray, arraySize) == -(arraySize + 1));
+ for (int counter = 0; counter < arraySize; counter++)
+ intArray[counter] -= 50;
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on int[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(intArray, counter - 50) == counter);
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(long[], long)
+ */
+ public void test_binarySearch$JJ() {
+ // Test for method int java.util.Arrays.binarySearch(long [], long)
+ for (long counter = 0; counter < arraySize; counter++)
+ assertTrue("Binary search on long[] answered incorrect position",
+ Arrays.binarySearch(longArray, counter) == counter);
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(longArray, (long) -1));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(longArray, (long) arraySize) == -(arraySize + 1));
+ for (long counter = 0; counter < arraySize; counter++)
+ longArray[(int) counter] -= (long) 50;
+ for (long counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on long[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(longArray, counter - (long) 50) == counter);
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(java.lang.Object[],
+ * java.lang.Object)
+ */
+ public void test_binarySearch$Ljava_lang_ObjectLjava_lang_Object() {
+ // Test for method int java.util.Arrays.binarySearch(java.lang.Object
+ // [], java.lang.Object)
+ assertEquals(
+ "Binary search succeeded for non-comparable value in empty array",
+ -1, Arrays.binarySearch(new Object[] {}, new Object()));
+ assertEquals(
+ "Binary search succeeded for comparable value in empty array",
+ -1, Arrays.binarySearch(new Object[] {}, new Integer(-1)));
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on Object[] answered incorrect position",
+ Arrays.binarySearch(objectArray, objArray[counter]) == counter);
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(objectArray, new Integer(-1)));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(objectArray, new Integer(arraySize)) == -(arraySize + 1));
+
+ Object object = new Object();
+ Object[] objects = new MockComparable[] { new MockComparable() };
+ assertEquals("Should always return 0", 0, Arrays.binarySearch(objects, object));
+
+ Object[] string_objects = new String[] { "one" };
+ try {
+ Arrays.binarySearch(string_objects, object);
+ fail("No expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(java.lang.Object[],
+ * java.lang.Object, java.util.Comparator)
+ */
+ public void test_binarySearch$Ljava_lang_ObjectLjava_lang_ObjectLjava_util_Comparator() {
+ // Test for method int java.util.Arrays.binarySearch(java.lang.Object
+ // [], java.lang.Object, java.util.Comparator)
+ Comparator comp = new ReversedIntegerComparator();
+ for (int counter = 0; counter < arraySize; counter++)
+ objectArray[counter] = objArray[arraySize - counter - 1];
+ assertTrue(
+ "Binary search succeeded for value not present in array 1",
+ Arrays.binarySearch(objectArray, new Integer(-1), comp) == -(arraySize + 1));
+ assertEquals("Binary search succeeded for value not present in array 2",
+ -1, Arrays.binarySearch(objectArray, new Integer(arraySize), comp));
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on Object[] with custom comparator answered incorrect position",
+ Arrays.binarySearch(objectArray, objArray[counter], comp) == arraySize
+ - counter - 1);
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(short[], short)
+ */
+ public void test_binarySearch$SS() {
+ // Test for method int java.util.Arrays.binarySearch(short [], short)
+ for (short counter = 0; counter < arraySize; counter++)
+ assertTrue("Binary search on short[] answered incorrect position",
+ Arrays.binarySearch(shortArray, counter) == counter);
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(intArray, (short) -1));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(intArray, (short) arraySize) == -(arraySize + 1));
+ for (short counter = 0; counter < arraySize; counter++)
+ shortArray[counter] -= 50;
+ for (short counter = 0; counter < arraySize; counter++)
+ assertTrue(
+ "Binary search on short[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(shortArray, (short) (counter - 50)) == counter);
+ }
+
+ public void test_Arrays_binaraySearch_byte() {
+ assertEquals(-1, Arrays.binarySearch(new byte[] { '0' }, 0, 0,
+ (byte) '1'));
+ assertEquals(-2, Arrays.binarySearch(new byte[] { '0' }, 1, 1,
+ (byte) '1'));
+ assertEquals(-2, Arrays.binarySearch(new byte[] { '0', '1' }, 1, 1,
+ (byte) '2'));
+ assertEquals(-3, Arrays.binarySearch(new byte[] { '0', '1' }, 2, 2,
+ (byte) '2'));
+ }
+
+ public void test_Arrays_binaraySearch_char() {
+ assertEquals(-1, Arrays.binarySearch(new char[] { '0' }, 0, 0, '1'));
+ assertEquals(-2, Arrays.binarySearch(new char[] { '0' }, 1, 1, '1'));
+ assertEquals(-2, Arrays
+ .binarySearch(new char[] { '0', '1' }, 1, 1, '2'));
+ assertEquals(-3, Arrays
+ .binarySearch(new char[] { '0', '1' }, 2, 2, '2'));
+ }
+
+ public void test_Arrays_binaraySearch_float() {
+ assertEquals(-1, Arrays.binarySearch(new float[] { -1.0f }, 0, 0, 0.0f));
+ assertEquals(-2, Arrays.binarySearch(new float[] { -1.0f }, 1, 1, 0.0f));
+ assertEquals(-2, Arrays.binarySearch(new float[] { -1.0f, 0f }, 1, 1,
+ 1f));
+ assertEquals(-3, Arrays.binarySearch(new float[] { -1.0f, 0f }, 2, 2,
+ 1f));
+ }
+
+ public void test_Arrays_binaraySearch_double() {
+ assertEquals(-1, Arrays.binarySearch(new double[] { -1.0 }, 0, 0, 0.0));
+ assertEquals(-2, Arrays.binarySearch(new double[] { -1.0 }, 1, 1, 0.0));
+ assertEquals(-2, Arrays.binarySearch(new double[] { -1.0, 0 }, 1, 1, 1));
+ assertEquals(-3, Arrays.binarySearch(new double[] { -1.0, 0 }, 2, 2, 1));
+ }
+
+ public void test_Arrays_binaraySearch_int() {
+ assertEquals(-1, Arrays.binarySearch(new int[] { -1 }, 0, 0, 0));
+ assertEquals(-2, Arrays.binarySearch(new int[] { -1 }, 1, 1, 0));
+ assertEquals(-2, Arrays.binarySearch(new int[] { -1, 0 }, 1, 1, 1));
+ assertEquals(-3, Arrays.binarySearch(new int[] { -1, 0 }, 2, 2, 1));
+ }
+
+ public void test_Arrays_binaraySearch_long() {
+ assertEquals(-1, Arrays.binarySearch(new long[] { -1l }, 0, 0, 0l));
+ assertEquals(-2, Arrays.binarySearch(new long[] { -1l }, 1, 1, 0l));
+ assertEquals(-2, Arrays.binarySearch(new long[] { -1l, 0l }, 1, 1, 1l));
+ assertEquals(-3, Arrays.binarySearch(new long[] { -1l, 0l }, 2, 2, 1l));
+ }
+
+ public void test_Arrays_binaraySearch_short() {
+ assertEquals(-1, Arrays.binarySearch(new short[] { (short) -1 }, 0, 0,
+ (short) 0));
+ assertEquals(-2, Arrays.binarySearch(new short[] { (short) -1 }, 1, 1,
+ (short) 0));
+ assertEquals(-2, Arrays.binarySearch(new short[] { (short) -1,
+ (short) 0 }, 1, 1, (short) 1));
+ assertEquals(-3, Arrays.binarySearch(new short[] { (short) -1,
+ (short) 0 }, 2, 2, (short) 1));
+ }
+
+ public void test_Arrays_binaraySearch_Object() {
+ assertEquals(-1, Arrays.binarySearch(new Object[] { new Integer(-1) },
+ 0, 0, new Integer(0)));
+ assertEquals(-2, Arrays.binarySearch(new Object[] { new Integer(-1) },
+ 1, 1, new Integer(0)));
+ assertEquals(-2, Arrays.binarySearch(new Object[] { new Integer(-1),
+ new Integer(0) }, 1, 1, new Integer(1)));
+ assertEquals(-3, Arrays.binarySearch(new Object[] { new Integer(-1),
+ new Integer(0) }, 2, 2, new Integer(1)));
+ }
+
+ public void test_Arrays_binaraySearch_T() {
+ ReversedIntegerComparator reversedComparator = new ReversedIntegerComparator();
+ assertEquals(-1, Arrays.binarySearch(new Integer[] { new Integer(-1) },
+ 0, 0, new Integer(0), reversedComparator));
+ assertEquals(-2, Arrays.binarySearch(new Integer[] { new Integer(-1) },
+ 1, 1, new Integer(0), reversedComparator));
+ assertEquals(-2, Arrays.binarySearch(new Integer[] { new Integer(-1),
+ new Integer(0) }, 1, 1, new Integer(1), reversedComparator));
+ assertEquals(-3, Arrays.binarySearch(new Integer[] { new Integer(-1),
+ new Integer(0) }, 2, 2, new Integer(1), reversedComparator));
+ }
+
+ /**
+ * java.util.Arrays#fill(byte[], byte)
+ */
+ public void test_fill$BB() {
+ // Test for method void java.util.Arrays.fill(byte [], byte)
+
+ byte d[] = new byte[1000];
+ Arrays.fill(d, Byte.MAX_VALUE);
+ for (int i = 0; i < d.length; i++)
+ assertTrue("Failed to fill byte array correctly",
+ d[i] == Byte.MAX_VALUE);
+ }
+
+ /**
+ * java.util.Arrays#fill(byte[], int, int, byte)
+ */
+ public void test_fill$BIIB() {
+ // Test for method void java.util.Arrays.fill(byte [], int, int, byte)
+ byte val = Byte.MAX_VALUE;
+ byte d[] = new byte[1000];
+ Arrays.fill(d, 400, d.length, val);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == val));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill byte array correctly", d[i] == val);
+
+ int result;
+ try {
+ Arrays.fill(new byte[2], 2, 1, (byte) 27);
+ result = 0;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ result = 1;
+ } catch (IllegalArgumentException e) {
+ result = 2;
+ }
+ assertEquals("Wrong exception1", 2, result);
+ try {
+ Arrays.fill(new byte[2], -1, 1, (byte) 27);
+ result = 0;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ result = 1;
+ } catch (IllegalArgumentException e) {
+ result = 2;
+ }
+ assertEquals("Wrong exception2", 1, result);
+ try {
+ Arrays.fill(new byte[2], 1, 4, (byte) 27);
+ result = 0;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ result = 1;
+ } catch (IllegalArgumentException e) {
+ result = 2;
+ }
+ assertEquals("Wrong exception", 1, result);
+ }
+
+ /**
+ * java.util.Arrays#fill(short[], short)
+ */
+ public void test_fill$SS() {
+ // Test for method void java.util.Arrays.fill(short [], short)
+
+ short d[] = new short[1000];
+ Arrays.fill(d, Short.MAX_VALUE);
+ for (int i = 0; i < d.length; i++)
+ assertTrue("Failed to fill short array correctly",
+ d[i] == Short.MAX_VALUE);
+ }
+
+ /**
+ * java.util.Arrays#fill(short[], int, int, short)
+ */
+ public void test_fill$SIIS() {
+ // Test for method void java.util.Arrays.fill(short [], int, int, short)
+ short val = Short.MAX_VALUE;
+ short d[] = new short[1000];
+ Arrays.fill(d, 400, d.length, val);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == val));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill short array correctly", d[i] == val);
+
+ try {
+ Arrays.fill(d, 10, 0, val);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, -10, 0, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, 10, d.length+1, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#fill(char[], char)
+ */
+ public void test_fill$CC() {
+ // Test for method void java.util.Arrays.fill(char [], char)
+
+ char d[] = new char[1000];
+ Arrays.fill(d, 'V');
+ for (int i = 0; i < d.length; i++)
+ assertEquals("Failed to fill char array correctly", 'V', d[i]);
+ }
+
+ /**
+ * java.util.Arrays#fill(char[], int, int, char)
+ */
+ public void test_fill$CIIC() {
+ // Test for method void java.util.Arrays.fill(char [], int, int, char)
+ char val = 'T';
+ char d[] = new char[1000];
+ Arrays.fill(d, 400, d.length, val);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == val));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill char array correctly", d[i] == val);
+
+ try {
+ Arrays.fill(d, 10, 0, val);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, -10, 0, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, 10, d.length+1, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#fill(int[], int)
+ */
+ public void test_fill$II() {
+ // Test for method void java.util.Arrays.fill(int [], int)
+
+ int d[] = new int[1000];
+ Arrays.fill(d, Integer.MAX_VALUE);
+ for (int i = 0; i < d.length; i++)
+ assertTrue("Failed to fill int array correctly",
+ d[i] == Integer.MAX_VALUE);
+ }
+
+ /**
+ * java.util.Arrays#fill(int[], int, int, int)
+ */
+ public void test_fill$IIII() {
+ // Test for method void java.util.Arrays.fill(int [], int, int, int)
+ int val = Integer.MAX_VALUE;
+ int d[] = new int[1000];
+ Arrays.fill(d, 400, d.length, val);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == val));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill int array correctly", d[i] == val);
+
+ try {
+ Arrays.fill(d, 10, 0, val);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, -10, 0, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, 10, d.length+1, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#fill(long[], long)
+ */
+ public void test_fill$JJ() {
+ // Test for method void java.util.Arrays.fill(long [], long)
+
+ long d[] = new long[1000];
+ Arrays.fill(d, Long.MAX_VALUE);
+ for (int i = 0; i < d.length; i++)
+ assertTrue("Failed to fill long array correctly",
+ d[i] == Long.MAX_VALUE);
+ }
+
+ /**
+ * java.util.Arrays#fill(long[], int, int, long)
+ */
+ public void test_fill$JIIJ() {
+ // Test for method void java.util.Arrays.fill(long [], int, int, long)
+ long d[] = new long[1000];
+ Arrays.fill(d, 400, d.length, Long.MAX_VALUE);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == Long.MAX_VALUE));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill long array correctly",
+ d[i] == Long.MAX_VALUE);
+
+ try {
+ Arrays.fill(d, 10, 0, Long.MIN_VALUE);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, -10, 0, Long.MAX_VALUE);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, 10, d.length+1, Long.MAX_VALUE);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#fill(float[], float)
+ */
+ public void test_fill$FF() {
+ // Test for method void java.util.Arrays.fill(float [], float)
+ float d[] = new float[1000];
+ Arrays.fill(d, Float.MAX_VALUE);
+ for (int i = 0; i < d.length; i++)
+ assertTrue("Failed to fill float array correctly",
+ d[i] == Float.MAX_VALUE);
+ }
+
+ /**
+ * java.util.Arrays#fill(float[], int, int, float)
+ */
+ public void test_fill$FIIF() {
+ // Test for method void java.util.Arrays.fill(float [], int, int, float)
+ float val = Float.MAX_VALUE;
+ float d[] = new float[1000];
+ Arrays.fill(d, 400, d.length, val);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == val));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill float array correctly", d[i] == val);
+
+ try {
+ Arrays.fill(d, 10, 0, val);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, -10, 0, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, 10, d.length+1, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#fill(double[], double)
+ */
+ public void test_fill$DD() {
+ // Test for method void java.util.Arrays.fill(double [], double)
+
+ double d[] = new double[1000];
+ Arrays.fill(d, Double.MAX_VALUE);
+ for (int i = 0; i < d.length; i++)
+ assertTrue("Failed to fill double array correctly",
+ d[i] == Double.MAX_VALUE);
+ }
+
+ /**
+ * java.util.Arrays#fill(double[], int, int, double)
+ */
+ public void test_fill$DIID() {
+ // Test for method void java.util.Arrays.fill(double [], int, int,
+ // double)
+ double val = Double.MAX_VALUE;
+ double d[] = new double[1000];
+ Arrays.fill(d, 400, d.length, val);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == val));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill double array correctly", d[i] == val);
+
+ try {
+ Arrays.fill(d, 10, 0, val);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, -10, 0, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, 10, d.length+1, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#fill(boolean[], boolean)
+ */
+ public void test_fill$ZZ() {
+ // Test for method void java.util.Arrays.fill(boolean [], boolean)
+
+ boolean d[] = new boolean[1000];
+ Arrays.fill(d, true);
+ for (int i = 0; i < d.length; i++)
+ assertTrue("Failed to fill boolean array correctly", d[i]);
+ }
+
+ /**
+ * java.util.Arrays#fill(boolean[], int, int, boolean)
+ */
+ public void test_fill$ZIIZ() {
+ // Test for method void java.util.Arrays.fill(boolean [], int, int,
+ // boolean)
+ boolean val = true;
+ boolean d[] = new boolean[1000];
+ Arrays.fill(d, 400, d.length, val);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == val));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill boolean array correctly", d[i] == val);
+
+ try {
+ Arrays.fill(d, 10, 0, val);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, -10, 0, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, 10, d.length+1, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#fill(java.lang.Object[], java.lang.Object)
+ */
+ public void test_fill$Ljava_lang_ObjectLjava_lang_Object() {
+ // Test for method void java.util.Arrays.fill(java.lang.Object [],
+ // java.lang.Object)
+ Object val = new Object();
+ Object d[] = new Object[1000];
+ Arrays.fill(d, 0, d.length, val);
+ for (int i = 0; i < d.length; i++)
+ assertTrue("Failed to fill Object array correctly", d[i] == val);
+ }
+
+ /**
+ * java.util.Arrays#fill(java.lang.Object[], int, int,
+ * java.lang.Object)
+ */
+ public void test_fill$Ljava_lang_ObjectIILjava_lang_Object() {
+ // Test for method void java.util.Arrays.fill(java.lang.Object [], int,
+ // int, java.lang.Object)
+ Object val = new Object();
+ Object d[] = new Object[1000];
+ Arrays.fill(d, 400, d.length, val);
+ for (int i = 0; i < 400; i++)
+ assertTrue("Filled elements not in range", !(d[i] == val));
+ for (int i = 400; i < d.length; i++)
+ assertTrue("Failed to fill Object array correctly", d[i] == val);
+
+ Arrays.fill(d, 400, d.length, null);
+ for (int i = 400; i < d.length; i++)
+ assertNull("Failed to fill Object array correctly with nulls",
+ d[i]);
+
+ try {
+ Arrays.fill(d, 10, 0, val);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, -10, 0, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.fill(d, 10, d.length+1, val);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#equals(byte[], byte[])
+ */
+ public void test_equals$B$B() {
+ // Test for method boolean java.util.Arrays.equals(byte [], byte [])
+ byte d[] = new byte[1000];
+ byte x[] = new byte[1000];
+ Arrays.fill(d, Byte.MAX_VALUE);
+ Arrays.fill(x, Byte.MIN_VALUE);
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, Byte.MAX_VALUE);
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+ }
+
+ /**
+ * java.util.Arrays#equals(short[], short[])
+ */
+ public void test_equals$S$S() {
+ // Test for method boolean java.util.Arrays.equals(short [], short [])
+ short d[] = new short[1000];
+ short x[] = new short[1000];
+ Arrays.fill(d, Short.MAX_VALUE);
+ Arrays.fill(x, Short.MIN_VALUE);
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, Short.MAX_VALUE);
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+ }
+
+ /**
+ * java.util.Arrays#equals(char[], char[])
+ */
+ public void test_equals$C$C() {
+ // Test for method boolean java.util.Arrays.equals(char [], char [])
+ char d[] = new char[1000];
+ char x[] = new char[1000];
+ char c = 'T';
+ Arrays.fill(d, c);
+ Arrays.fill(x, 'L');
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, c);
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+ }
+
+ /**
+ * java.util.Arrays#equals(int[], int[])
+ */
+ public void test_equals$I$I() {
+ // Test for method boolean java.util.Arrays.equals(int [], int [])
+ int d[] = new int[1000];
+ int x[] = new int[1000];
+ Arrays.fill(d, Integer.MAX_VALUE);
+ Arrays.fill(x, Integer.MIN_VALUE);
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, Integer.MAX_VALUE);
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+
+ assertTrue("wrong result for null array1", !Arrays.equals(new int[2],
+ null));
+ assertTrue("wrong result for null array2", !Arrays.equals(null,
+ new int[2]));
+ }
+
+ /**
+ * java.util.Arrays#equals(long[], long[])
+ */
+ public void test_equals$J$J() {
+ // Test for method boolean java.util.Arrays.equals(long [], long [])
+ long d[] = new long[1000];
+ long x[] = new long[1000];
+ Arrays.fill(d, Long.MAX_VALUE);
+ Arrays.fill(x, Long.MIN_VALUE);
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, Long.MAX_VALUE);
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+
+ assertTrue("should be false", !Arrays.equals(
+ new long[] { 0x100000000L }, new long[] { 0x200000000L }));
+
+ }
+
+ /**
+ * java.util.Arrays#equals(float[], float[])
+ */
+ public void test_equals$F$F() {
+ // Test for method boolean java.util.Arrays.equals(float [], float [])
+ float d[] = new float[1000];
+ float x[] = new float[1000];
+ Arrays.fill(d, Float.MAX_VALUE);
+ Arrays.fill(x, Float.MIN_VALUE);
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, Float.MAX_VALUE);
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+
+ assertTrue("NaN not equals", Arrays.equals(new float[] { Float.NaN },
+ new float[] { Float.NaN }));
+ assertTrue("0f equals -0f", !Arrays.equals(new float[] { 0f },
+ new float[] { -0f }));
+ }
+
+ /**
+ * java.util.Arrays#equals(double[], double[])
+ */
+ public void test_equals$D$D() {
+ // Test for method boolean java.util.Arrays.equals(double [], double [])
+ double d[] = new double[1000];
+ double x[] = new double[1000];
+ Arrays.fill(d, Double.MAX_VALUE);
+ Arrays.fill(x, Double.MIN_VALUE);
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, Double.MAX_VALUE);
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+
+ assertTrue("should be false", !Arrays.equals(new double[] { 1.0 },
+ new double[] { 2.0 }));
+
+ assertTrue("NaN not equals", Arrays.equals(new double[] { Double.NaN },
+ new double[] { Double.NaN }));
+ assertTrue("0d equals -0d", !Arrays.equals(new double[] { 0d },
+ new double[] { -0d }));
+ }
+
+ /**
+ * java.util.Arrays#equals(boolean[], boolean[])
+ */
+ public void test_equals$Z$Z() {
+ // Test for method boolean java.util.Arrays.equals(boolean [], boolean
+ // [])
+ boolean d[] = new boolean[1000];
+ boolean x[] = new boolean[1000];
+ Arrays.fill(d, true);
+ Arrays.fill(x, false);
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, true);
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+ }
+
+ /**
+ * java.util.Arrays#equals(java.lang.Object[], java.lang.Object[])
+ */
+ public void test_equals$Ljava_lang_Object$Ljava_lang_Object() {
+ // Test for method boolean java.util.Arrays.equals(java.lang.Object [],
+ // java.lang.Object [])
+ Object d[] = new Object[1000];
+ Object x[] = new Object[1000];
+ Object o = new Object();
+ Arrays.fill(d, o);
+ Arrays.fill(x, new Object());
+ assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+ Arrays.fill(x, o);
+ d[50] = null;
+ x[50] = null;
+ assertTrue("equal arrays returned false", Arrays.equals(d, x));
+ }
+
+ /**
+ * java.util.Arrays#sort(byte[])
+ */
+ public void test_sort$B() {
+ // Test for method void java.util.Arrays.sort(byte [])
+ byte[] reversedArray = new byte[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ reversedArray[counter] = (byte) (arraySize - counter - 1);
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Resulting array not sorted",
+ reversedArray[counter] == (byte) counter);
+ }
+
+ /**
+ * java.util.Arrays#sort(byte[], int, int)
+ */
+ public void test_sort$BII() {
+ // Test for method void java.util.Arrays.sort(byte [], int, int)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ byte[] reversedArray = new byte[arraySize];
+ byte[] originalReversedArray = new byte[arraySize];
+ for (int counter = 0; counter < arraySize; counter++) {
+ reversedArray[counter] = (byte) (arraySize - counter - 1);
+ originalReversedArray[counter] = reversedArray[counter];
+ }
+ Arrays.sort(reversedArray, startIndex, endIndex);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds",
+ reversedArray[counter] <= reversedArray[counter + 1]);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+
+ //exception testing
+ try {
+ Arrays.sort(reversedArray, startIndex + 1, startIndex);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, -1, startIndex);
+ fail("ArrayIndexOutOfBoundsException expected (1)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+ fail("ArrayIndexOutOfBoundsException expected (2)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(char[])
+ */
+ public void test_sort$C() {
+ // Test for method void java.util.Arrays.sort(char [])
+ char[] reversedArray = new char[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ reversedArray[counter] = (char) (arraySize - counter - 1);
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Resulting array not sorted",
+ reversedArray[counter] == (char) counter);
+
+ }
+
+ /**
+ * java.util.Arrays#sort(char[], int, int)
+ */
+ public void test_sort$CII() {
+ // Test for method void java.util.Arrays.sort(char [], int, int)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ char[] reversedArray = new char[arraySize];
+ char[] originalReversedArray = new char[arraySize];
+ for (int counter = 0; counter < arraySize; counter++) {
+ reversedArray[counter] = (char) (arraySize - counter - 1);
+ originalReversedArray[counter] = reversedArray[counter];
+ }
+ Arrays.sort(reversedArray, startIndex, endIndex);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds",
+ reversedArray[counter] <= reversedArray[counter + 1]);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+
+ //exception testing
+ try {
+ Arrays.sort(reversedArray, startIndex + 1, startIndex);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, -1, startIndex);
+ fail("ArrayIndexOutOfBoundsException expected (1)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+ fail("ArrayIndexOutOfBoundsException expected (2)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(double[])
+ */
+ public void test_sort$D() {
+ // Test for method void java.util.Arrays.sort(double [])
+ double[] reversedArray = new double[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ reversedArray[counter] = (double) (arraySize - counter - 1);
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Resulting array not sorted",
+ reversedArray[counter] == (double) counter);
+
+ double[] specials1 = new double[] { Double.NaN, Double.MAX_VALUE,
+ Double.MIN_VALUE, 0d, -0d, Double.POSITIVE_INFINITY,
+ Double.NEGATIVE_INFINITY };
+ double[] specials2 = new double[] { 0d, Double.POSITIVE_INFINITY, -0d,
+ Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Double.NaN,
+ Double.MAX_VALUE };
+ double[] specials3 = new double[] { 0.0, Double.NaN, 1.0, 2.0, Double.NaN,
+ Double.NaN, 1.0, 3.0, -0.0 };
+ double[] answer = new double[] { Double.NEGATIVE_INFINITY, -0d, 0d,
+ Double.MIN_VALUE, Double.MAX_VALUE, Double.POSITIVE_INFINITY,
+ Double.NaN };
+ double[] answer3 = new double[] { -0.0, 0.0, 1.0, 1.0, 2.0, 3.0, Double.NaN,
+ Double.NaN, Double.NaN };
+
+ Arrays.sort(specials1);
+ Object[] print1 = new Object[specials1.length];
+ for (int i = 0; i < specials1.length; i++)
+ print1[i] = new Double(specials1[i]);
+ assertTrue("specials sort incorrectly 1: " + Arrays.asList(print1),
+ Arrays.equals(specials1, answer));
+
+ Arrays.sort(specials2);
+ Object[] print2 = new Object[specials2.length];
+ for (int i = 0; i < specials2.length; i++)
+ print2[i] = new Double(specials2[i]);
+ assertTrue("specials sort incorrectly 2: " + Arrays.asList(print2),
+ Arrays.equals(specials2, answer));
+
+ Arrays.sort(specials3);
+ Object[] print3 = new Object[specials3.length];
+ for (int i = 0; i < specials3.length; i++)
+ print3[i] = new Double(specials3[i]);
+ assertTrue("specials sort incorrectly 3: " + Arrays.asList(print3),
+ Arrays.equals(specials3, answer3));
+ }
+
+ /**
+ * java.util.Arrays#sort(double[], int, int)
+ */
+ public void test_sort$DII() {
+ // Test for method void java.util.Arrays.sort(double [], int, int)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ double[] reversedArray = new double[arraySize];
+ double[] originalReversedArray = new double[arraySize];
+ for (int counter = 0; counter < arraySize; counter++) {
+ reversedArray[counter] = (double) (arraySize - counter - 1);
+ originalReversedArray[counter] = reversedArray[counter];
+ }
+ Arrays.sort(reversedArray, startIndex, endIndex);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds",
+ reversedArray[counter] <= reversedArray[counter + 1]);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+
+ //exception testing
+ try {
+ Arrays.sort(reversedArray, startIndex + 1, startIndex);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, -1, startIndex);
+ fail("ArrayIndexOutOfBoundsException expected (1)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+ fail("ArrayIndexOutOfBoundsException expected (2)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(float[])
+ */
+ public void test_sort$F() {
+ // Test for method void java.util.Arrays.sort(float [])
+ float[] reversedArray = new float[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ reversedArray[counter] = (float) (arraySize - counter - 1);
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Resulting array not sorted",
+ reversedArray[counter] == (float) counter);
+
+ float[] specials1 = new float[] { Float.NaN, Float.MAX_VALUE,
+ Float.MIN_VALUE, 0f, -0f, Float.POSITIVE_INFINITY,
+ Float.NEGATIVE_INFINITY };
+ float[] specials2 = new float[] { 0f, Float.POSITIVE_INFINITY, -0f,
+ Float.NEGATIVE_INFINITY, Float.MIN_VALUE, Float.NaN,
+ Float.MAX_VALUE };
+ float[] answer = new float[] { Float.NEGATIVE_INFINITY, -0f, 0f,
+ Float.MIN_VALUE, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
+ Float.NaN };
+
+ Arrays.sort(specials1);
+ Object[] print1 = new Object[specials1.length];
+ for (int i = 0; i < specials1.length; i++)
+ print1[i] = new Float(specials1[i]);
+ assertTrue("specials sort incorrectly 1: " + Arrays.asList(print1),
+ Arrays.equals(specials1, answer));
+
+ Arrays.sort(specials2);
+ Object[] print2 = new Object[specials2.length];
+ for (int i = 0; i < specials2.length; i++)
+ print2[i] = new Float(specials2[i]);
+ assertTrue("specials sort incorrectly 2: " + Arrays.asList(print2),
+ Arrays.equals(specials2, answer));
+ }
+
+ /**
+ * java.util.Arrays#sort(float[], int, int)
+ */
+ public void test_sort$FII() {
+ // Test for method void java.util.Arrays.sort(float [], int, int)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ float[] reversedArray = new float[arraySize];
+ float[] originalReversedArray = new float[arraySize];
+ for (int counter = 0; counter < arraySize; counter++) {
+ reversedArray[counter] = (float) (arraySize - counter - 1);
+ originalReversedArray[counter] = reversedArray[counter];
+ }
+ Arrays.sort(reversedArray, startIndex, endIndex);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds",
+ reversedArray[counter] <= reversedArray[counter + 1]);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+
+ //exception testing
+ try {
+ Arrays.sort(reversedArray, startIndex + 1, startIndex);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, -1, startIndex);
+ fail("ArrayIndexOutOfBoundsException expected (1)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+ fail("ArrayIndexOutOfBoundsException expected (2)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(int[])
+ */
+ public void test_sort$I() {
+ // Test for method void java.util.Arrays.sort(int [])
+ int[] reversedArray = new int[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ reversedArray[counter] = arraySize - counter - 1;
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Resulting array not sorted",
+ reversedArray[counter] == counter);
+ }
+
+ /**
+ * java.util.Arrays#sort(int[], int, int)
+ */
+ public void test_sort$III() {
+ // Test for method void java.util.Arrays.sort(int [], int, int)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ int[] reversedArray = new int[arraySize];
+ int[] originalReversedArray = new int[arraySize];
+ for (int counter = 0; counter < arraySize; counter++) {
+ reversedArray[counter] = arraySize - counter - 1;
+ originalReversedArray[counter] = reversedArray[counter];
+ }
+ Arrays.sort(reversedArray, startIndex, endIndex);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds",
+ reversedArray[counter] <= reversedArray[counter + 1]);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+
+ //exception testing
+ try {
+ Arrays.sort(reversedArray, startIndex + 1, startIndex);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, -1, startIndex);
+ fail("ArrayIndexOutOfBoundsException expected (1)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+ fail("ArrayIndexOutOfBoundsException expected (2)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(long[])
+ */
+ public void test_sort$J() {
+ // Test for method void java.util.Arrays.sort(long [])
+ long[] reversedArray = new long[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ reversedArray[counter] = (long) (arraySize - counter - 1);
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Resulting array not sorted",
+ reversedArray[counter] == (long) counter);
+
+ }
+
+ /**
+ * java.util.Arrays#sort(long[], int, int)
+ */
+ public void test_sort$JII() {
+ // Test for method void java.util.Arrays.sort(long [], int, int)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ long[] reversedArray = new long[arraySize];
+ long[] originalReversedArray = new long[arraySize];
+ for (int counter = 0; counter < arraySize; counter++) {
+ reversedArray[counter] = (long) (arraySize - counter - 1);
+ originalReversedArray[counter] = reversedArray[counter];
+ }
+ Arrays.sort(reversedArray, startIndex, endIndex);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds",
+ reversedArray[counter] <= reversedArray[counter + 1]);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+
+ //exception testing
+ try {
+ Arrays.sort(reversedArray, startIndex + 1, startIndex);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, -1, startIndex);
+ fail("ArrayIndexOutOfBoundsException expected (1)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+ fail("ArrayIndexOutOfBoundsException expected (2)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(java.lang.Object[])
+ */
+ public void test_sort$Ljava_lang_Object() {
+ // Test for method void java.util.Arrays.sort(java.lang.Object [])
+ Object[] reversedArray = new Object[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ reversedArray[counter] = objectArray[arraySize - counter - 1];
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Resulting array not sorted",
+ reversedArray[counter] == objectArray[counter]);
+
+ Arrays.fill(reversedArray, 0, reversedArray.length/2, "String");
+ Arrays.fill(reversedArray, reversedArray.length/2, reversedArray.length, new Integer(1));
+
+ try {
+ Arrays.sort(reversedArray);
+ fail("ClassCastException expected");
+ } catch (ClassCastException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(java.lang.Object[], int, int)
+ */
+ public void test_sort$Ljava_lang_ObjectII() {
+ // Test for method void java.util.Arrays.sort(java.lang.Object [], int,
+ // int)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ Object[] reversedArray = new Object[arraySize];
+ Object[] originalReversedArray = new Object[arraySize];
+ for (int counter = 0; counter < arraySize; counter++) {
+ reversedArray[counter] = objectArray[arraySize - counter - 1];
+ originalReversedArray[counter] = reversedArray[counter];
+ }
+ Arrays.sort(reversedArray, startIndex, endIndex);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds",
+ ((Comparable) reversedArray[counter])
+ .compareTo(reversedArray[counter + 1]) <= 0);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+
+ //exception testing
+ try {
+ Arrays.sort(reversedArray, startIndex + 1, startIndex);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, -1, startIndex);
+ fail("ArrayIndexOutOfBoundsException expected (1)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+ fail("ArrayIndexOutOfBoundsException expected (2)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ Arrays.fill(reversedArray, 0, reversedArray.length/2, "String");
+ Arrays.fill(reversedArray, reversedArray.length/2, reversedArray.length, new Integer(1));
+
+ try {
+ Arrays.sort(reversedArray, reversedArray.length/4, 3*reversedArray.length/4);
+ fail("ClassCastException expected");
+ } catch (ClassCastException e) {
+ //expected
+ }
+
+ Arrays.sort(reversedArray, 0, reversedArray.length/4);
+ Arrays.sort(reversedArray, 3*reversedArray.length/4, reversedArray.length);
+ }
+
+ /**
+ * java.util.Arrays#sort(java.lang.Object[], int, int,
+ * java.util.Comparator)
+ */
+ public void test_sort$Ljava_lang_ObjectIILjava_util_Comparator() {
+ // Test for method void java.util.Arrays.sort(java.lang.Object [], int,
+ // int, java.util.Comparator)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ ReversedIntegerComparator comp = new ReversedIntegerComparator();
+ Object[] originalArray = new Object[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ originalArray[counter] = objectArray[counter];
+ Arrays.sort(objectArray, startIndex, endIndex, comp);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ objectArray[counter] == originalArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds", comp.compare(
+ objectArray[counter], objectArray[counter + 1]) <= 0);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ objectArray[counter] == originalArray[counter]);
+
+ Arrays.fill(originalArray, 0, originalArray.length/2, "String");
+ Arrays.fill(originalArray, originalArray.length/2, originalArray.length, new Integer(1));
+
+ try {
+ Arrays.sort(originalArray, startIndex, endIndex, comp);
+ fail("ClassCastException expected");
+ } catch (ClassCastException e) {
+ //expected
+ }
+
+ Arrays.sort(originalArray, endIndex, originalArray.length, comp);
+
+ try {
+ Arrays.sort(originalArray, endIndex, originalArray.length + 1, comp);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.sort(originalArray, -1, startIndex, comp);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ Arrays.sort(originalArray, originalArray.length, endIndex, comp);
+ fail("IllegalArgumentException expected");
+ } catch(IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(java.lang.Object[], java.util.Comparator)
+ */
+ public void test_sort$Ljava_lang_ObjectLjava_util_Comparator() {
+ // Test for method void java.util.Arrays.sort(java.lang.Object [],
+ // java.util.Comparator)
+ ReversedIntegerComparator comp = new ReversedIntegerComparator();
+ Arrays.sort(objectArray, comp);
+ for (int counter = 0; counter < arraySize - 1; counter++)
+ assertTrue("Array not sorted correctly with custom comparator",
+ comp
+ .compare(objectArray[counter],
+ objectArray[counter + 1]) <= 0);
+
+ Arrays.fill(objectArray, 0, objectArray.length/2, "String");
+ Arrays.fill(objectArray, objectArray.length/2, objectArray.length, new Integer(1));
+
+ try {
+ Arrays.sort(objectArray, comp);
+ fail("ClassCastException expected");
+ } catch (ClassCastException e) {
+ //expected
+ }
+ }
+
+ // Regression HARMONY-6076
+ public void test_sort$Ljava_lang_ObjectLjava_util_Comparator_stable() {
+ Element[] array = new Element[11];
+ array[0] = new Element(122);
+ array[1] = new Element(146);
+ array[2] = new Element(178);
+ array[3] = new Element(208);
+ array[4] = new Element(117);
+ array[5] = new Element(146);
+ array[6] = new Element(173);
+ array[7] = new Element(203);
+ array[8] = new Element(56);
+ array[9] = new Element(208);
+ array[10] = new Element(96);
+
+ Comparator<Element> comparator = new Comparator<Element>() {
+ public int compare(Element object1, Element object2) {
+ return object1.value - object2.value;
+ }
+ };
+
+ Arrays.sort(array, comparator);
+
+ for (int i = 1; i < array.length; i++) {
+ assertTrue(comparator.compare(array[i - 1], array[i]) <= 0);
+ if (comparator.compare(array[i - 1], array[i]) == 0) {
+ assertTrue(array[i - 1].index < array[i].index);
+ }
+ }
+ }
+
+ public static class Element {
+ public int value;
+
+ public int index;
+
+ private static int count = 0;
+
+ public Element(int value) {
+ this.value = value;
+ index = count++;
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(short[])
+ */
+ public void test_sort$S() {
+ // Test for method void java.util.Arrays.sort(short [])
+ short[] reversedArray = new short[arraySize];
+ for (int counter = 0; counter < arraySize; counter++)
+ reversedArray[counter] = (short) (arraySize - counter - 1);
+ Arrays.sort(reversedArray);
+ for (int counter = 0; counter < arraySize; counter++)
+ assertTrue("Resulting array not sorted",
+ reversedArray[counter] == (short) counter);
+ }
+
+ /**
+ * java.util.Arrays#sort(short[], int, int)
+ */
+ public void test_sort$SII() {
+ // Test for method void java.util.Arrays.sort(short [], int, int)
+ int startIndex = arraySize / 4;
+ int endIndex = 3 * arraySize / 4;
+ short[] reversedArray = new short[arraySize];
+ short[] originalReversedArray = new short[arraySize];
+ for (int counter = 0; counter < arraySize; counter++) {
+ reversedArray[counter] = (short) (arraySize - counter - 1);
+ originalReversedArray[counter] = reversedArray[counter];
+ }
+ Arrays.sort(reversedArray, startIndex, endIndex);
+ for (int counter = 0; counter < startIndex; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+ for (int counter = startIndex; counter < endIndex - 1; counter++)
+ assertTrue("Array not sorted within bounds",
+ reversedArray[counter] <= reversedArray[counter + 1]);
+ for (int counter = endIndex; counter < arraySize; counter++)
+ assertTrue("Array modified outside of bounds",
+ reversedArray[counter] == originalReversedArray[counter]);
+
+ //exception testing
+ try {
+ Arrays.sort(reversedArray, startIndex + 1, startIndex);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, -1, startIndex);
+ fail("ArrayIndexOutOfBoundsException expected (1)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+
+ try {
+ Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+ fail("ArrayIndexOutOfBoundsException expected (2)");
+ } catch (ArrayIndexOutOfBoundsException ignore) {
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(byte[], int, int)
+ */
+ public void test_java_util_Arrays_sort_byte_array_NPE() {
+ byte[] byte_array_null = null;
+ try {
+ java.util.Arrays.sort(byte_array_null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(byte_array_null, (int) -1, (int) 1);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(char[], int, int)
+ */
+ public void test_java_util_Arrays_sort_char_array_NPE() {
+ char[] char_array_null = null;
+ try {
+ java.util.Arrays.sort(char_array_null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(char_array_null, (int) -1, (int) 1);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(double[], int, int)
+ */
+ public void test_java_util_Arrays_sort_double_array_NPE() {
+ double[] double_array_null = null;
+ try {
+ java.util.Arrays.sort(double_array_null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(double_array_null, (int) -1, (int) 1);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(float[], int, int)
+ */
+ public void test_java_util_Arrays_sort_float_array_NPE() {
+ float[] float_array_null = null;
+ try {
+ java.util.Arrays.sort(float_array_null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(float_array_null, (int) -1, (int) 1);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(int[], int, int)
+ */
+ public void test_java_util_Arrays_sort_int_array_NPE() {
+ int[] int_array_null = null;
+ try {
+ java.util.Arrays.sort(int_array_null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(int_array_null, (int) -1, (int) 1);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(Object[], int, int)
+ */
+ public void test_java_util_Arrays_sort_object_array_NPE() {
+ Object[] object_array_null = null;
+ try {
+ java.util.Arrays.sort(object_array_null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(object_array_null, (int) -1, (int) 1);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(object_array_null, (int) -1, (int) 1, null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(long[], int, int)
+ */
+ public void test_java_util_Arrays_sort_long_array_NPE() {
+ long[] long_array_null = null;
+ try {
+ java.util.Arrays.sort(long_array_null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(long_array_null, (int) -1, (int) 1);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#sort(short[], int, int)
+ */
+ public void test_java_util_Arrays_sort_short_array_NPE() {
+ short[] short_array_null = null;
+ try {
+ java.util.Arrays.sort(short_array_null);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ // Regression for HARMONY-378
+ java.util.Arrays.sort(short_array_null, (int) -1, (int) 1);
+ fail("Should throw java.lang.NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ // Lenghts of arrays to test in test_sort;
+ private static final int[] LENGTHS = { 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 100, 1000, 10000 };
+
+ /**
+ * java.util.Arrays#sort()
+ */
+ public void test_sort() {
+ for (int len : LENGTHS) {
+ PrimitiveTypeArrayBuilder.reset();
+ int[] golden = new int[len];
+ for (int m = 1; m < 2 * len; m *= 2) {
+ for (PrimitiveTypeArrayBuilder builder : PrimitiveTypeArrayBuilder.values()) {
+ builder.build(golden, m);
+ int[] test = golden.clone();
+
+ for (PrimitiveTypeConverter converter : PrimitiveTypeConverter.values()) {
+ Object convertedGolden = converter.convert(golden);
+ Object convertedTest = converter.convert(test);
+ sort(convertedTest);
+ checkSorted(convertedTest);
+ assertEquals(checkSum(convertedGolden), checkSum(convertedTest));
+ }
+ }
+ }
+ }
+ }
+
+ private void sort(Object array) {
+ if (array instanceof int[]) {
+ Arrays.sort((int[]) array);
+ }
+ else if (array instanceof long[]) {
+ Arrays.sort((long[]) array);
+ } else if (array instanceof short[]) {
+ Arrays.sort((short[]) array);
+ } else if (array instanceof byte[]) {
+ Arrays.sort((byte[]) array);
+ } else if (array instanceof char[]) {
+ Arrays.sort((char[]) array);
+ } else if (array instanceof float[]) {
+ Arrays.sort((float[]) array);
+ } else if (array instanceof double[]) {
+ Arrays.sort((double[]) array);
+ } else {
+ fail("Unknow type of array: " + array.getClass());
+ }
+ }
+
+ private void checkSorted(Object array) {
+ if (array instanceof int[]) {
+ checkSorted((int[]) array);
+ } else if (array instanceof long[]) {
+ checkSorted((long[]) array);
+ } else if (array instanceof short[]) {
+ checkSorted((short[]) array);
+ } else if (array instanceof byte[]) {
+ checkSorted((byte[]) array);
+ } else if (array instanceof char[]) {
+ checkSorted((char[]) array);
+ } else if (array instanceof float[]) {
+ checkSorted((float[]) array);
+ } else if (array instanceof double[]) {
+ checkSorted((double[]) array);
+ } else {
+ fail("Unknow type of array: " + array.getClass());
+ }
+ }
+
+ private void checkSorted(int[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ orderFail(i, "" + a[i], "" + a[i + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(long[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ orderFail(i, "" + a[i], "" + a[i + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(short[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ orderFail(i, "" + a[i], "" + a[i + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(byte[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ orderFail(i, "" + a[i], "" + a[i + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(char[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ orderFail(i, "" + a[i], "" + a[i + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(float[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ orderFail(i, "" + a[i], "" + a[i + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(double[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ orderFail(i, "" + a[i], "" + a[i + 1]);
+ }
+ }
+ }
+
+
+ private void orderFail(int index, String value1, String value2) {
+ fail("Array is not sorted at " + index + "-th position: " + value1 + " and " + value2);
+ }
+
+ private int checkSum(Object array) {
+ if (array instanceof int[]) {
+ return checkSum((int[]) array);
+ } else if (array instanceof long[]) {
+ return checkSum((long[]) array);
+ } else if (array instanceof short[]) {
+ return checkSum((short[]) array);
+ } else if (array instanceof byte[]) {
+ return checkSum((byte[]) array);
+ } else if (array instanceof char[]) {
+ return checkSum((char[]) array);
+ } else if (array instanceof float[]) {
+ return checkSum((float[]) array);
+ } else if (array instanceof double[]) {
+ return checkSum((double[]) array);
+ } else {
+ fail("Unknow type of array: " + array.getClass());
+ }
+ throw new AssertionError(); // Needed to shut up compiler
+ }
+
+ private int checkSum(int[] a) {
+ int checkSum = 0;
+
+ for (int e : a) {
+ checkSum ^= e; // xor
+ }
+ return checkSum;
+ }
+
+ private int checkSum(long[] a) {
+ long checkSum = 0;
+
+ for (long e : a) {
+ checkSum ^= e; // xor
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSum(short[] a) {
+ short checkSum = 0;
+
+ for (short e : a) {
+ checkSum ^= e; // xor
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSum(byte[] a) {
+ byte checkSum = 0;
+
+ for (byte e : a) {
+ checkSum ^= e; // xor
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSum(char[] a) {
+ char checkSum = 0;
+
+ for (char e : a) {
+ checkSum ^= e; // xor
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSum(float[] a) {
+ int checkSum = 0;
+
+ for (float e : a) {
+ checkSum ^= (int) e; // xor
+ }
+ return checkSum;
+ }
+
+ private int checkSum(double[] a) {
+ int checkSum = 0;
+
+ for (double e : a) {
+ checkSum ^= (int) e; // xor
+ }
+ return checkSum;
+ }
+
+ private enum PrimitiveTypeArrayBuilder {
+
+ RANDOM {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = ourRandom.nextInt();
+ }
+ }
+ },
+
+ ASCENDING {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = m + i;
+ }
+ }
+ },
+
+ DESCENDING {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = a.length - m - i;
+ }
+ }
+ },
+
+ ALL_EQUAL {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = m;
+ }
+ }
+ },
+
+ SAW {
+ void build(int[] a, int m) {
+ int incCount = 1;
+ int decCount = a.length;
+ int i = 0;
+ int period = m;
+ m--;
+
+ while (true) {
+ for (int k = 1; k <= period; k++) {
+ if (i >= a.length) {
+ return;
+ }
+ a[i++] = incCount++;
+ }
+ period += m;
+
+ for (int k = 1; k <= period; k++) {
+ if (i >= a.length) {
+ return;
+ }
+ a[i++] = decCount--;
+ }
+ period += m;
+ }
+ }
+ },
+
+ REPEATED {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = i % m;
+ }
+ }
+ },
+
+ DUPLICATED {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = ourRandom.nextInt(m);
+ }
+ }
+ },
+
+ ORGAN_PIPES {
+ void build(int[] a, int m) {
+ int middle = a.length / (m + 1);
+
+ for (int i = 0; i < middle; i++) {
+ a[i] = i;
+ }
+ for (int i = middle; i < a.length ; i++) {
+ a[i] = a.length - i - 1;
+ }
+ }
+ },
+
+ STAGGER {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = (i * m + i) % a.length;
+ }
+ }
+ },
+
+ PLATEAU {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = Math.min(i, m);
+ }
+ }
+ },
+
+ SHUFFLE {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = ourRandom.nextBoolean() ? (ourFirst += 2) : (ourSecond += 2);
+ }
+ }
+ };
+
+ abstract void build(int[] a, int m);
+
+ static void reset() {
+ ourRandom = new Random(666);
+ ourFirst = 0;
+ ourSecond = 0;
+ }
+
+ @Override
+ public String toString() {
+ String name = name();
+
+ for (int i = name.length(); i < 12; i++) {
+ name += " " ;
+ }
+ return name;
+ }
+
+ private static int ourFirst;
+ private static int ourSecond;
+ private static Random ourRandom = new Random(666);
+ }
+
+ private enum PrimitiveTypeConverter {
+
+ INT {
+ Object convert(int[] a) {
+ return a;
+ }
+ },
+
+ LONG {
+ Object convert(int[] a) {
+ long[] b = new long[a.length];
+
+ for (int i = 0; i < a.length; i++) {
+ b[i] = (int) a[i];
+ }
+ return b;
+ }
+ },
+
+ BYTE {
+ Object convert(int[] a) {
+ byte[] b = new byte[a.length];
+
+ for (int i = 0; i < a.length; i++) {
+ b[i] = (byte) a[i];
+ }
+ return b;
+ }
+ },
+
+ SHORT {
+ Object convert(int[] a) {
+ short[] b = new short[a.length];
+
+ for (int i = 0; i < a.length; i++) {
+ b[i] = (short) a[i];
+ }
+ return b;
+ }
+ },
+
+ CHAR {
+ Object convert(int[] a) {
+ char[] b = new char[a.length];
+
+ for (int i = 0; i < a.length; i++) {
+ b[i] = (char) a[i];
+ }
+ return b;
+ }
+ },
+
+ FLOAT {
+ Object convert(int[] a) {
+ float[] b = new float[a.length];
+
+ for (int i = 0; i < a.length; i++) {
+ b[i] = (float) a[i];
+ }
+ return b;
+ }
+ },
+
+ DOUBLE {
+ Object convert(int[] a) {
+ double[] b = new double[a.length];
+
+ for (int i = 0; i < a.length; i++) {
+ b[i] = (double) a[i];
+ }
+ return b;
+ }
+ };
+
+ abstract Object convert(int[] a);
+
+ public String toString() {
+ String name = name();
+
+ for (int i = name.length(); i < 9; i++) {
+ name += " " ;
+ }
+ return name;
+ }
+ }
+
+
+ /**
+ * java.util.Arrays#deepEquals(Object[], Object[])
+ */
+ public void test_deepEquals$Ljava_lang_ObjectLjava_lang_Object() {
+ int[] a1 = { 1, 2, 3 };
+ short[] a2 = { 0, 1 };
+ Object[] a3 = { new Integer(1), a2 };
+ int[] a4 = { 6, 5, 4 };
+
+ int[] b1 = { 1, 2, 3 };
+ short[] b2 = { 0, 1 };
+ Object[] b3 = { new Integer(1), b2 };
+
+ Object a[] = { a1, a2, a3 };
+ Object b[] = { b1, b2, b3 };
+
+ assertFalse(Arrays.equals(a, b));
+ assertTrue(Arrays.deepEquals(a, b));
+
+ a[2] = a4;
+
+ assertFalse(Arrays.deepEquals(a, b));
+ }
+
+ /**
+ * java.util.Arrays#deepHashCode(Object[])
+ */
+ public void test_deepHashCode$Ljava_lang_Object() {
+ int[] a1 = { 1, 2, 3 };
+ short[] a2 = { 0, 1 };
+ Object[] a3 = { new Integer(1), a2 };
+
+ int[] b1 = { 1, 2, 3 };
+ short[] b2 = { 0, 1 };
+ Object[] b3 = { new Integer(1), b2 };
+
+ Object a[] = { a1, a2, a3 };
+ Object b[] = { b1, b2, b3 };
+
+ int deep_hash_a = Arrays.deepHashCode(a);
+ int deep_hash_b = Arrays.deepHashCode(b);
+
+ assertEquals(deep_hash_a, deep_hash_b);
+ }
+
+ /**
+ * java.util.Arrays#hashCode(boolean[] a)
+ */
+ public void test_hashCode$LZ() {
+ int listHashCode;
+ int arrayHashCode;
+
+ boolean[] boolArr = { true, false, false, true, false };
+ List listOfBoolean = new LinkedList();
+ for (int i = 0; i < boolArr.length; i++) {
+ listOfBoolean.add(new Boolean(boolArr[i]));
+ }
+ listHashCode = listOfBoolean.hashCode();
+ arrayHashCode = Arrays.hashCode(boolArr);
+ assertEquals(listHashCode, arrayHashCode);
+ }
+
+ /**
+ * java.util.Arrays#hashCode(int[] a)
+ */
+ public void test_hashCode$LI() {
+ int listHashCode;
+ int arrayHashCode;
+
+ int[] intArr = { 10, 5, 134, 7, 19 };
+ List listOfInteger = new LinkedList();
+
+ for (int i = 0; i < intArr.length; i++) {
+ listOfInteger.add(new Integer(intArr[i]));
+ }
+ listHashCode = listOfInteger.hashCode();
+ arrayHashCode = Arrays.hashCode(intArr);
+ assertEquals(listHashCode, arrayHashCode);
+
+ int[] intArr2 = { 10, 5, 134, 7, 19 };
+ assertEquals(Arrays.hashCode(intArr2), Arrays.hashCode(intArr));
+ }
+
+ /**
+ * java.util.Arrays#hashCode(char[] a)
+ */
+ public void test_hashCode$LC() {
+ int listHashCode;
+ int arrayHashCode;
+
+ char[] charArr = { 'a', 'g', 'x', 'c', 'm' };
+ List listOfCharacter = new LinkedList();
+ for (int i = 0; i < charArr.length; i++) {
+ listOfCharacter.add(new Character(charArr[i]));
+ }
+ listHashCode = listOfCharacter.hashCode();
+ arrayHashCode = Arrays.hashCode(charArr);
+ assertEquals(listHashCode, arrayHashCode);
+ }
+
+ /**
+ * java.util.Arrays#hashCode(byte[] a)
+ */
+ public void test_hashCode$LB() {
+ int listHashCode;
+ int arrayHashCode;
+
+ byte[] byteArr = { 5, 9, 7, 6, 17 };
+ List listOfByte = new LinkedList();
+ for (int i = 0; i < byteArr.length; i++) {
+ listOfByte.add(new Byte(byteArr[i]));
+ }
+ listHashCode = listOfByte.hashCode();
+ arrayHashCode = Arrays.hashCode(byteArr);
+ assertEquals(listHashCode, arrayHashCode);
+ }
+
+ /**
+ * java.util.Arrays#hashCode(long[] a)
+ */
+ public void test_hashCode$LJ() {
+ int listHashCode;
+ int arrayHashCode;
+
+ long[] longArr = { 67890234512l, 97587236923425l, 257421912912l,
+ 6754268100l, 5 };
+ List listOfLong = new LinkedList();
+ for (int i = 0; i < longArr.length; i++) {
+ listOfLong.add(new Long(longArr[i]));
+ }
+ listHashCode = listOfLong.hashCode();
+ arrayHashCode = Arrays.hashCode(longArr);
+ assertEquals(listHashCode, arrayHashCode);
+ }
+
+ /**
+ * java.util.Arrays#hashCode(float[] a)
+ */
+ public void test_hashCode$LF() {
+ int listHashCode;
+ int arrayHashCode;
+
+ float[] floatArr = { 0.13497f, 0.268934f, 12e-5f, -3e+2f, 10e-4f };
+ List listOfFloat = new LinkedList();
+ for (int i = 0; i < floatArr.length; i++) {
+ listOfFloat.add(new Float(floatArr[i]));
+ }
+ listHashCode = listOfFloat.hashCode();
+ arrayHashCode = Arrays.hashCode(floatArr);
+ assertEquals(listHashCode, arrayHashCode);
+
+ float[] floatArr2 = { 0.13497f, 0.268934f, 12e-5f, -3e+2f, 10e-4f };
+ assertEquals(Arrays.hashCode(floatArr2), Arrays.hashCode(floatArr));
+ }
+
+ /**
+ * java.util.Arrays#hashCode(double[] a)
+ */
+ public void test_hashCode$LD() {
+ int listHashCode;
+ int arrayHashCode;
+
+ double[] doubleArr = { 0.134945657, 0.0038754, 11e-150, -30e-300, 10e-4 };
+ List listOfDouble = new LinkedList();
+ for (int i = 0; i < doubleArr.length; i++) {
+ listOfDouble.add(new Double(doubleArr[i]));
+ }
+ listHashCode = listOfDouble.hashCode();
+ arrayHashCode = Arrays.hashCode(doubleArr);
+ assertEquals(listHashCode, arrayHashCode);
+ }
+
+ /**
+ * java.util.Arrays#hashCode(short[] a)
+ */
+ public void test_hashCode$LS() {
+ int listHashCode;
+ int arrayHashCode;
+
+ short[] shortArr = { 35, 13, 45, 2, 91 };
+ List listOfShort = new LinkedList();
+ for (int i = 0; i < shortArr.length; i++) {
+ listOfShort.add(new Short(shortArr[i]));
+ }
+ listHashCode = listOfShort.hashCode();
+ arrayHashCode = Arrays.hashCode(shortArr);
+ assertEquals(listHashCode, arrayHashCode);
+ }
+
+ /**
+ * java.util.Arrays#hashCode(Object[] a)
+ */
+ public void test_hashCode$Ljava_lang_Object() {
+ int listHashCode;
+ int arrayHashCode;
+
+ Object[] objectArr = { new Integer(1), new Float(10e-12f), null };
+ List listOfObject = new LinkedList();
+ for (int i = 0; i < objectArr.length; i++) {
+ listOfObject.add(objectArr[i]);
+ }
+ listHashCode = listOfObject.hashCode();
+ arrayHashCode = Arrays.hashCode(objectArr);
+ assertEquals(listHashCode, arrayHashCode);
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ objArray = new Object[arraySize];
+ for (int i = 0; i < objArray.length; i++)
+ objArray[i] = new Integer(i);
+
+ booleanArray = new boolean[arraySize];
+ byteArray = new byte[arraySize];
+ charArray = new char[arraySize];
+ doubleArray = new double[arraySize];
+ floatArray = new float[arraySize];
+ intArray = new int[arraySize];
+ longArray = new long[arraySize];
+ objectArray = new Object[arraySize];
+ shortArray = new short[arraySize];
+
+ for (int counter = 0; counter < arraySize; counter++) {
+ byteArray[counter] = (byte) counter;
+ charArray[counter] = (char) (counter + 1);
+ doubleArray[counter] = counter;
+ floatArray[counter] = counter;
+ intArray[counter] = counter;
+ longArray[counter] = counter;
+ objectArray[counter] = objArray[counter];
+ shortArray[counter] = (short) counter;
+ }
+ for (int counter = 0; counter < arraySize; counter += 2) {
+ booleanArray[counter] = false;
+ booleanArray[counter + 1] = true;
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(byte[], int, int, byte)
+ */
+ public void test_binarySearch$BIIB() {
+ for (byte counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on byte[] answered incorrect position",
+ Arrays.binarySearch(byteArray, counter, arraySize, counter) == counter);
+ }
+ assertEquals(
+ "Binary search succeeded for value not present in array 1", -1,
+ Arrays.binarySearch(byteArray, 0, arraySize, (byte) -1));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(byteArray, (byte) arraySize) == -(arraySize + 1));
+ for (byte counter = 0; counter < arraySize; counter++) {
+ byteArray[counter] -= 50;
+ }
+ for (byte counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on byte[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(byteArray, counter, arraySize,
+ (byte) (counter - 50)) == counter);
+ }
+ try {
+ Arrays.binarySearch((byte[]) null, 2, 1, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((byte[]) null, -1, 0, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((byte[]) null, -1, -2, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(byteArray, 2, 1, (byte) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays.binarySearch(byteArray, 0, 0, (byte) arraySize));
+ try {
+ Arrays.binarySearch(byteArray, -1, -2, (byte) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(byteArray, arraySize + 2, arraySize + 1,
+ (byte) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(byteArray, -1, 0, (byte) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(byteArray, 0, arraySize + 1, (byte) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(char[], char)
+ */
+ public void test_binarySearch$CIIC() {
+ for (char counter = 0; counter < arraySize; counter++) {
+ assertTrue("Binary search on char[] answered incorrect position",
+ Arrays.binarySearch(charArray, counter, arraySize,
+ (char) (counter + 1)) == counter);
+ }
+ assertEquals(
+ "Binary search succeeded for value not present in array 1", -1,
+ Arrays.binarySearch(charArray, 0, arraySize, '\u0000'));
+ assertTrue("Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(charArray, 0, arraySize,
+ (char) (arraySize + 1)) == -(arraySize + 1));
+ try {
+ Arrays.binarySearch(charArray, 2, 1, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((char[]) null, 2, 1, (char) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((char[]) null, -1, 0, (char) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((char[]) null, -1, -2, (char) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays.binarySearch(charArray, 0, 0, (char) arraySize));
+ try {
+ Arrays.binarySearch(charArray, -1, -2, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(charArray, arraySize + 2, arraySize + 1,
+ (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(charArray, -1, 0, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(charArray, 0, arraySize + 1, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(double[], double)
+ */
+ public void test_binarySearch$DIID() {
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue("Binary search on double[] answered incorrect position",
+ Arrays.binarySearch(doubleArray, counter, arraySize,
+ (double) counter) == (double) counter);
+ }
+ assertEquals(
+ "Binary search succeeded for value not present in array 1", -1,
+ Arrays.binarySearch(doubleArray, 0, arraySize, (double) -1));
+ assertTrue("Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(doubleArray, 0, arraySize,
+ (double) arraySize) == -(arraySize + 1));
+ for (int counter = 0; counter < arraySize; counter++) {
+ doubleArray[counter] -= (double) 50;
+ }
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on double[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(doubleArray, counter, arraySize, (double) (counter - 50)) == (double) counter);
+ }
+ double[] specials = new double[] { Double.NEGATIVE_INFINITY,
+ -Double.MAX_VALUE, -2d, -Double.MIN_VALUE, -0d, 0d,
+ Double.MIN_VALUE, 2d, Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY, Double.NaN };
+ for (int i = 0; i < specials.length; i++) {
+ int result = Arrays.binarySearch(specials, i, specials.length, specials[i]);
+ assertTrue(specials[i] + " invalid: " + result, result == i);
+ }
+ assertEquals("-1d", -4, Arrays.binarySearch(specials, 0, specials.length, -1d));
+ assertEquals("1d", -8, Arrays.binarySearch(specials, 0, specials.length, 1d));
+ try {
+ Arrays.binarySearch((double[]) null, 2, 1, (double) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((double[]) null, -1, 0, (double) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((double[]) null, -1, -2, (double) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(doubleArray, 2, 1, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays.binarySearch(doubleArray, 0, 0, (char) arraySize));
+ try {
+ Arrays.binarySearch(doubleArray, -1, -2, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(doubleArray, arraySize + 2, arraySize + 1,
+ (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(doubleArray, -1, 0, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(doubleArray, 0, arraySize + 1, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(float[], float)
+ */
+ public void test_binarySearch$FIIF() {
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue("Binary search on float[] answered incorrect position",
+ Arrays.binarySearch(floatArray, counter, arraySize,
+ (float) counter) == (float) counter);
+ }
+ assertEquals(
+ "Binary search succeeded for value not present in array 1", -1,
+ Arrays.binarySearch(floatArray, 0, arraySize, (float) -1));
+ assertTrue("Binary search succeeded for value not present in array 2",
+ Arrays
+ .binarySearch(floatArray, 0, arraySize,
+ (float) arraySize) == -(arraySize + 1));
+ for (int counter = 0; counter < arraySize; counter++) {
+ floatArray[counter] -= (float) 50;
+ }
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on float[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(floatArray, 0, arraySize,
+ (float) counter - 50) == (float) counter);
+ }
+ float[] specials = new float[] { Float.NEGATIVE_INFINITY,
+ -Float.MAX_VALUE, -2f, -Float.MIN_VALUE, -0f, 0f,
+ Float.MIN_VALUE, 2f, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
+ Float.NaN };
+ for (int i = 0; i < specials.length; i++) {
+ int result = Arrays.binarySearch(specials, i, specials.length, specials[i]);
+ assertTrue(specials[i] + " invalid: " + result, result == i);
+ }
+ assertEquals("-1f", -4, Arrays.binarySearch(specials, 0, specials.length, -1f));
+ assertEquals("1f", -8, Arrays.binarySearch(specials, 0, specials.length, 1f));
+ try {
+ Arrays.binarySearch((float[]) null, 2, 1, (float) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((float[]) null, -1, 0, (float) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((float[]) null, -1, -2, (float) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(floatArray, 2, 1, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays.binarySearch(floatArray, 0, 0,
+ (char) arraySize));
+ try {
+ Arrays.binarySearch(floatArray, -1, -2, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(floatArray, arraySize + 2, arraySize + 1,
+ (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(floatArray, -1, 0, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays
+ .binarySearch(floatArray, 0, arraySize + 1,
+ (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(int[], int)
+ */
+ public void test_binarySearch$IIII() {
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on int[] answered incorrect position",
+ Arrays.binarySearch(intArray, counter, arraySize, counter) == counter);
+ }
+ assertEquals(
+ "Binary search succeeded for value not present in array 1", -1,
+ Arrays.binarySearch(intArray, 0, arraySize, -1));
+ assertTrue("Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(intArray, 0, arraySize, arraySize) == -(arraySize + 1));
+ for (int counter = 0; counter < arraySize; counter++) {
+ intArray[counter] -= 50;
+ }
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on int[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(intArray, 0, arraySize, counter - 50) == counter);
+ }
+ try {
+ Arrays.binarySearch((int[]) null, 2, 1, (int) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((int[]) null, -1, 0, (int) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((int[]) null, -1, -2, (int) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(intArray, 2, 1, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays
+ .binarySearch(intArray, 0, 0, (char) arraySize));
+ try {
+ Arrays.binarySearch(intArray, -1, -2, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(intArray, arraySize + 2, arraySize + 1,
+ (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(intArray, -1, 0, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(intArray, 0, arraySize + 1, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(long[], long)
+ */
+ public void test_binarySearch$JIIJ() {
+ for (long counter = 0; counter < arraySize; counter++) {
+ assertTrue("Binary search on long[] answered incorrect position",
+ Arrays.binarySearch(longArray, 0, arraySize, counter) == counter);
+ }
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(longArray, 0, arraySize, (long) -1));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(longArray, 0, arraySize, (long) arraySize) == -(arraySize + 1));
+ for (long counter = 0; counter < arraySize; counter++) {
+ longArray[(int) counter] -= (long) 50;
+ }
+ for (long counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on long[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(longArray, 0, arraySize, counter - (long) 50) == counter);
+ }
+ try {
+ Arrays.binarySearch((long[]) null, 2, 1, (long) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((long[]) null, -1, 0, (long) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((long[]) null, -1, -2, (long) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(longArray, 2, 1, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays
+ .binarySearch(longArray, 0, 0, (char) arraySize));
+ try {
+ Arrays.binarySearch(longArray, -1, -2, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(longArray, arraySize + 2, arraySize + 1,
+ (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(longArray, -1, 0, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(longArray, 0, arraySize + 1, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(java.lang.Object[],
+ *java.lang.Object)
+ */
+ public void test_binarySearch$Ljava_lang_ObjectIILjava_lang_Object() {
+ assertEquals(
+ "Binary search succeeded for non-comparable value in empty array",
+ -1, Arrays.binarySearch(new Object[] { }, 0, 0, new Object()));
+ assertEquals(
+ "Binary search succeeded for comparable value in empty array",
+ -1, Arrays.binarySearch(new Object[] { }, 0, 0, new Integer(-1)));
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on Object[] answered incorrect position",
+ Arrays.binarySearch(objectArray, counter, arraySize, objArray[counter]) == counter);
+ }
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(objectArray, 0, arraySize, new Integer(-1)));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(objectArray, 0, arraySize, new Integer(arraySize)) == -(arraySize + 1));
+ try {
+ Arrays.binarySearch((Object[]) null, 2, 1, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((Object[]) null, -1, 0, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((Object[]) null, -1, -2, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, 2, 1, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays
+ .binarySearch(objectArray, 0, 0, (char) arraySize));
+ try {
+ Arrays.binarySearch(objectArray, -1, -2, (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, arraySize + 2, arraySize + 1,
+ (char) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, -1, 0, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, 0, arraySize + 1, (char) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(java.lang.Object[],
+ *java.lang.Object, java.util.Comparator)
+ */
+ public void test_binarySearch$Ljava_lang_ObjectIILjava_lang_ObjectLjava_util_Comparator() {
+ Comparator comp = new ReversedIntegerComparator();
+ for (int counter = 0; counter < arraySize; counter++) {
+ objectArray[counter] = objArray[arraySize - counter - 1];
+ }
+ assertTrue("Binary search succeeded for value not present in array 1",
+ Arrays.binarySearch(objectArray, 0, arraySize, new Integer(-1),
+ comp) == -(arraySize + 1));
+ assertEquals(
+ "Binary search succeeded for value not present in array 2", -1,
+ Arrays.binarySearch(objectArray, 0, arraySize, new Integer(
+ arraySize), comp));
+ for (int counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on Object[] with custom comparator answered incorrect position",
+ Arrays.binarySearch(objectArray, objArray[counter], comp) == arraySize
+ - counter - 1);
+ }
+ try {
+ Arrays.binarySearch((Object[]) null, 2, 1, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((Object[]) null, -1, 0, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((Object[]) null, -1, -2, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, 2, 1, (char) arraySize, comp);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays.binarySearch(objectArray, 0, 0,
+ (char) arraySize, comp));
+ try {
+ Arrays.binarySearch(objectArray, -1, -2, (char) arraySize, comp);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, arraySize + 2, arraySize + 1,
+ (char) arraySize, comp);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, -1, 0, (char) arraySize, comp);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, 0, arraySize + 1,
+ (char) arraySize, comp);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(objectArray, 0, arraySize,
+ new LinkedList(), comp);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Arrays#binarySearch(short[], short)
+ */
+ public void test_binarySearch$SIIS() {
+ for (short counter = 0; counter < arraySize; counter++) {
+ assertTrue("Binary search on short[] answered incorrect position",
+ Arrays.binarySearch(shortArray, counter, arraySize, counter) == counter);
+ }
+ assertEquals("Binary search succeeded for value not present in array 1",
+ -1, Arrays.binarySearch(shortArray, 0, arraySize, (short) -1));
+ assertTrue(
+ "Binary search succeeded for value not present in array 2",
+ Arrays.binarySearch(shortArray, 0, arraySize, (short) arraySize) == -(arraySize + 1));
+ for (short counter = 0; counter < arraySize; counter++) {
+ shortArray[counter] -= 50;
+ }
+ for (short counter = 0; counter < arraySize; counter++) {
+ assertTrue(
+ "Binary search on short[] involving negative numbers answered incorrect position",
+ Arrays.binarySearch(shortArray, counter, arraySize, (short) (counter - 50)) == counter);
+ }
+ try {
+ Arrays.binarySearch((String[]) null, 2, 1, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((String[]) null, -1, 0, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch((String[]) null, -1, -2, (byte) arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(shortArray, 2, 1, (short) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(-1, Arrays
+ .binarySearch(shortArray, 0, 0, (short) arraySize));
+ try {
+ Arrays.binarySearch(shortArray, -1, -2, (short) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(shortArray, arraySize + 2, arraySize + 1,
+ (short) arraySize);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(shortArray, -1, 0, (short) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.binarySearch(shortArray, 0, arraySize + 1, (short) arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ String[] array = { "a", "b", "c" };
+ assertEquals(-2, Arrays.binarySearch(array, 1, 2, "a", null));
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(byte[], int)
+ */
+ public void test_copyOf_$BI() throws Exception {
+ byte[] result = Arrays.copyOf(byteArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOf(byteArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i, result[i]);
+ }
+ try {
+ Arrays.copyOf((byte[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(byteArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((byte[]) null, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(short[], int)
+ */
+ public void test_copyOf_$SI() throws Exception {
+ short[] result = Arrays.copyOf(shortArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOf(shortArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i, result[i]);
+ }
+ try {
+ Arrays.copyOf((short[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(shortArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((short[]) null, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(int[], int)
+ */
+ public void test_copyOf_$II() throws Exception {
+ int[] result = Arrays.copyOf(intArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOf(intArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i, result[i]);
+ }
+ try {
+ Arrays.copyOf((int[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(intArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((int[]) null, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(boolean[], int)
+ */
+ public void test_copyOf_$ZI() throws Exception {
+ boolean[] result = Arrays.copyOf(booleanArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(booleanArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(false, result[i]);
+ }
+ result = Arrays.copyOf(booleanArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(booleanArray[i], result[i]);
+ }
+ try {
+ Arrays.copyOf((boolean[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(booleanArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((boolean[]) null, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(char[], int)
+ */
+ public void test_copyOf_$CI() throws Exception {
+ char[] result = Arrays.copyOf(charArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i + 1, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOf(charArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i + 1, result[i]);
+ }
+ try {
+ Arrays.copyOf((char[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(charArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((char[]) null, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(float[], int)
+ */
+ public void test_copyOf_$FI() throws Exception {
+ float[] result = Arrays.copyOf(floatArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(floatArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0.0f, result[i]);
+ }
+ result = Arrays.copyOf(floatArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(floatArray[i], result[i]);
+ }
+ try {
+ Arrays.copyOf((float[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(floatArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((float[]) null, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(double[], int)
+ */
+ public void test_copyOf_$DI() throws Exception {
+ double[] result = Arrays.copyOf(doubleArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(doubleArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0.0, result[i]);
+ }
+ result = Arrays.copyOf(doubleArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(doubleArray[i], result[i]);
+ }
+ try {
+ Arrays.copyOf((double[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(doubleArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((double[]) null, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(long[], int)
+ */
+ public void test_copyOf_$JI() throws Exception {
+ long[] result = Arrays.copyOf(longArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(longArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOf(longArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(longArray[i], result[i]);
+ }
+ try {
+ Arrays.copyOf((long[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(longArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((long[]) null, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(T[], int)
+ */
+ public void test_copyOf_$TI() throws Exception {
+ Object[] result = Arrays.copyOf(objArray, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertNull(result[i]);
+ }
+ result = Arrays.copyOf(objArray, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ try {
+ Arrays.copyOf((String[]) null, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(objArray, -1);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((String[]) null, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ Date[] component = new Date[0];
+ Object object[] = new Date[0];
+
+ object = Arrays.copyOf(component, 2);
+ assertNotNull(object);
+ component = Arrays.copyOf(component, 2);
+ assertNotNull(component);
+ assertEquals(2, component.length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOf(T[], int, Class<? extends Object[]>))
+ */
+ public void test_copyOf_$TILClass() throws Exception {
+ Object[] result = Arrays.copyOf(objArray, arraySize * 2, Object[].class);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertNull(result[i]);
+ }
+ result = Arrays.copyOf(objArray, arraySize / 2, Object[].class);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ result = Arrays.copyOf(objArray, arraySize / 2, Integer[].class);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ try {
+ Arrays.copyOf((Object[]) null, arraySize, LinkedList[].class);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(objArray, arraySize, LinkedList[].class);
+ fail("should throw ArrayStoreException ");
+ } catch (ArrayStoreException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((Object[]) null, arraySize, Object[].class);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf(objArray, -1, Object[].class);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((Object[]) null, -1, Object[].class);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((Object[]) null, -1, LinkedList[].class);
+ fail("should throw NegativeArraySizeException");
+ } catch (NegativeArraySizeException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOf((Object[]) null, 0, LinkedList[].class);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ assertEquals(0, Arrays.copyOf(objArray, 0, LinkedList[].class).length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOfRange(byte[], int, int)
+ */
+ public void test_copyOfRange_$BII() throws Exception {
+ byte[] result = Arrays.copyOfRange(byteArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOfRange(byteArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i, result[i]);
+ }
+ result = Arrays.copyOfRange(byteArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((byte[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((byte[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((byte[]) null, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(byteArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(byteArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(byteArray.length + 1, Arrays.copyOfRange(byteArray, 0,
+ byteArray.length + 1).length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOfRange(short[], int, int)
+ */
+ public void test_copyOfRange_$SII() throws Exception {
+ short[] result = Arrays.copyOfRange(shortArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOfRange(shortArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i, result[i]);
+ }
+ result = Arrays.copyOfRange(shortArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((short[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((short[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((short[]) null, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(shortArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(shortArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(shortArray.length + 1, Arrays.copyOfRange(shortArray, 0,
+ shortArray.length + 1).length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOfRange(int[], int, int)
+ */
+ public void test_copyOfRange_$III() throws Exception {
+ int[] result = Arrays.copyOfRange(intArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOfRange(intArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i, result[i]);
+ }
+ result = Arrays.copyOfRange(intArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((int[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((int[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((int[]) null, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(intArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(intArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(intArray.length + 1, Arrays.copyOfRange(intArray, 0,
+ intArray.length + 1).length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOfRange(long[], int, int)
+ */
+ public void test_copyOfRange_$JII() throws Exception {
+ long[] result = Arrays.copyOfRange(longArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOfRange(longArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i, result[i]);
+ }
+ result = Arrays.copyOfRange(longArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((long[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((long[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((long[]) null, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(longArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(longArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(longArray.length + 1, Arrays.copyOfRange(longArray, 0,
+ longArray.length + 1).length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOfRange(char[], int, int)
+ */
+ public void test_copyOfRange_$CII() throws Exception {
+ char[] result = Arrays.copyOfRange(charArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(i + 1, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0, result[i]);
+ }
+ result = Arrays.copyOfRange(charArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(i + 1, result[i]);
+ }
+ result = Arrays.copyOfRange(charArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((char[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((char[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((char[]) null, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(charArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(charArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(charArray.length + 1, Arrays.copyOfRange(charArray, 0,
+ charArray.length + 1).length);
+ }
+
+ public void test_copyOfRange_$FII() throws Exception {
+ float[] result = Arrays.copyOfRange(floatArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals((float) i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0.0f, result[i]);
+ }
+ result = Arrays.copyOfRange(floatArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals((float) i, result[i]);
+ }
+ result = Arrays.copyOfRange(floatArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((float[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((float[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((float[]) null, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(floatArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(floatArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(floatArray.length + 1, Arrays.copyOfRange(floatArray, 0,
+ floatArray.length + 1).length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOfRange(double[], int, int)
+ */
+ public void test_copyOfRange_$DII() throws Exception {
+ double[] result = Arrays.copyOfRange(doubleArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals((double) i, result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(0.0, result[i]);
+ }
+ result = Arrays.copyOfRange(doubleArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals((double) i, result[i]);
+ }
+ result = Arrays.copyOfRange(doubleArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((double[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((double[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((double[]) null, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(doubleArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(doubleArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(doubleArray.length + 1, Arrays.copyOfRange(doubleArray, 0,
+ doubleArray.length + 1).length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOfRange(boolean[], int, int)
+ */
+ public void test_copyOfRange_$ZII() throws Exception {
+ boolean[] result = Arrays.copyOfRange(booleanArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(booleanArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(false, result[i]);
+ }
+ result = Arrays.copyOfRange(booleanArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(booleanArray[i], result[i]);
+ }
+ result = Arrays.copyOfRange(booleanArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((boolean[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((boolean[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((boolean[]) null, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(booleanArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(booleanArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(booleanArray.length + 1, Arrays.copyOfRange(booleanArray, 0,
+ booleanArray.length + 1).length);
+ }
+
+ /**
+ * {@link java.util.Arrays#copyOfRange(Object[], int, int)
+ */
+ public void test_copyOfRange_$TII() throws Exception {
+ Object[] result = Arrays.copyOfRange(objArray, 0, arraySize * 2);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(null, result[i]);
+ }
+ result = Arrays.copyOfRange(objArray, 0, arraySize / 2);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ result = Arrays.copyOfRange(objArray, 0, 0);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange((Object[]) null, 0, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((Object[]) null, -1, arraySize);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((Object[]) null, 0, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((Object[]) objArray, -1, arraySize);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange((Object[]) objArray, 0, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(objArray.length + 1, Arrays.copyOfRange(objArray, 0,
+ objArray.length + 1).length);
+ }
+
+ public void test_copyOfRange_$TIILClass() throws Exception {
+ Object[] result = Arrays.copyOfRange(objArray, 0, arraySize * 2, Integer[].class);
+ int i = 0;
+ for (; i < arraySize; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ for (; i < result.length; i++) {
+ assertEquals(null, result[i]);
+ }
+ result = Arrays.copyOfRange(objArray, 0, arraySize / 2, Integer[].class);
+ i = 0;
+ for (; i < result.length; i++) {
+ assertEquals(objArray[i], result[i]);
+ }
+ result = Arrays.copyOfRange(objArray, 0, 0, Integer[].class);
+ assertEquals(0, result.length);
+ try {
+ Arrays.copyOfRange(null, 0, arraySize, Integer[].class);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(null, -1, arraySize, Integer[].class);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(null, 0, -1, Integer[].class);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(objArray, -1, arraySize, Integer[].class);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(objArray, 0, -1, Integer[].class);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(objArray, 0, -1, LinkedList[].class);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(objArray, 0, 1, LinkedList[].class);
+ fail("should throw ArrayStoreException");
+ } catch (ArrayStoreException e) {
+ // expected
+ }
+ try {
+ Arrays.copyOfRange(null, 0, 1, LinkedList[].class);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ assertEquals(objArray.length + 1, Arrays.copyOfRange(objArray, 0,
+ objArray.length + 1, LinkedList[].class).length);
+ fail("should throw ArrayStoreException");
+ } catch (ArrayStoreException e) {
+ // expected
+ }
+ assertEquals(0,
+ Arrays.copyOfRange(objArray, 0, 0, LinkedList[].class).length);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ objArray = null;
+ booleanArray = null;
+ byteArray = null;
+ charArray = null;
+ doubleArray = null;
+ floatArray = null;
+ intArray = null;
+ longArray = null;
+ objectArray = null;
+ shortArray = null;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/BitSetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/BitSetTest.java
new file mode 100644
index 0000000..96ffccc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/BitSetTest.java
@@ -0,0 +1,1361 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.BitSet;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class BitSetTest extends junit.framework.TestCase {
+
+ BitSet eightbs;
+
+ public void test_Constructor() {
+ BitSet bs = new BitSet();
+ // Default size for a BitSet should be 64 elements;
+ assertEquals("Created BitSet of incorrect size", 64, bs.size());
+ assertEquals("New BitSet had invalid string representation", "{}", bs
+ .toString());
+ }
+
+ public void test_ConstructorI() {
+ BitSet bs = new BitSet(128);
+ // Default size for a BitSet should be 64 elements;
+
+ assertEquals("Created BitSet of incorrect size", 128, bs.size());
+ assertEquals("New BitSet had invalid string representation: "
+ + bs.toString(), "{}", bs.toString());
+
+ // All BitSets are created with elements of multiples of 64
+
+ bs = new BitSet(89);
+ assertEquals("Failed to round BitSet element size", 128, bs.size());
+
+ try {
+ bs = new BitSet(-9);
+ fail();
+ } catch (NegativeArraySizeException expected) {
+ }
+ }
+
+ public void test_clone() {
+ BitSet bs = (BitSet) eightbs.clone();
+ assertTrue("Clone failed to return equal BitSet", eightbs.equals(bs));
+ }
+
+ public void test_equalsLjava_lang_Object() {
+ BitSet bs;
+
+ bs = (BitSet) eightbs.clone();
+ assertEquals("Same BitSet returned false", eightbs, eightbs);
+ assertEquals("Identical BitSet returned false", bs, eightbs);
+ bs.clear(6);
+ assertFalse("Different BitSets returned true", eightbs.equals(bs));
+ // Grow the BitSet
+ bs = (BitSet) eightbs.clone();
+ bs.set(128);
+ assertFalse("Different sized BitSet with higher bit set returned true",
+ eightbs.equals(bs));
+ bs.clear(128);
+ assertTrue(
+ "Different sized BitSet with higher bits not set returned false",
+ eightbs.equals(bs));
+ }
+
+ public void test_hashCode() {
+ BitSet bs = (BitSet) eightbs.clone();
+ bs.clear(2);
+ bs.clear(6);
+ assertEquals("BitSet returns wrong hash value", 1129, bs.hashCode());
+ bs.set(10);
+ bs.clear(3);
+ assertEquals("BitSet returns wrong hash value", 97, bs.hashCode());
+ }
+
+ public void test_clear() {
+ eightbs.clear();
+ for (int i = 0; i < 8; i++) {
+ assertTrue("Clear didn't clear bit " + i, !eightbs.get(i));
+ }
+ assertEquals("Test1: Wrong length", 0, eightbs.length());
+
+ BitSet bs = new BitSet(3400);
+ bs.set(0, bs.size() - 1); // ensure all bits are 1's
+ bs.set(bs.size() - 1);
+ bs.clear();
+ assertEquals("Test2: Wrong length", 0, bs.length());
+ assertTrue("Test2: isEmpty() returned incorrect value", bs.isEmpty());
+ assertEquals("Test2: cardinality() returned incorrect value", 0, bs
+ .cardinality());
+ }
+
+ public void test_clearI() {
+ eightbs.clear(7);
+ assertFalse("Failed to clear bit", eightbs.get(7));
+
+ // Check to see all other bits are still set
+ for (int i = 0; i < 7; i++) {
+ assertTrue("Clear cleared incorrect bits", eightbs.get(i));
+ }
+
+ eightbs.clear(165);
+ assertFalse("Failed to clear bit", eightbs.get(165));
+ // Try out of range
+ try {
+ eightbs.clear(-1);
+ fail("Failed to throw expected out of bounds exception");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ BitSet bs = new BitSet(0);
+ assertEquals("Test1: Wrong length,", 0, bs.length());
+ assertEquals("Test1: Wrong size,", 0, bs.size());
+
+ bs.clear(0);
+ assertEquals("Test2: Wrong length,", 0, bs.length());
+ assertEquals("Test2: Wrong size,", 0, bs.size());
+
+ bs.clear(60);
+ assertEquals("Test3: Wrong length,", 0, bs.length());
+ assertEquals("Test3: Wrong size,", 0, bs.size());
+
+ bs.clear(120);
+ assertEquals("Test4: Wrong size,", 0, bs.size());
+ assertEquals("Test4: Wrong length,", 0, bs.length());
+
+ bs.set(25);
+ assertEquals("Test5: Wrong size,", 64, bs.size());
+ assertEquals("Test5: Wrong length,", 26, bs.length());
+
+ bs.clear(80);
+ assertEquals("Test6: Wrong size,", 64, bs.size());
+ assertEquals("Test6: Wrong length,", 26, bs.length());
+
+ bs.clear(25);
+ assertEquals("Test7: Wrong size,", 64, bs.size());
+ assertEquals("Test7: Wrong length,", 0, bs.length());
+
+ bs = new BitSet();
+ try {
+ bs.clear(-1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void test_clearII() throws IndexOutOfBoundsException {
+ // Regression for HARMONY-98
+ BitSet bitset = new BitSet();
+ for (int i = 0; i < 20; i++) {
+ bitset.set(i);
+ }
+ bitset.clear(10, 10);
+
+ // pos1 and pos2 are in the same bitset element
+ BitSet bs = new BitSet(16);
+ int initialSize = bs.size();
+ assertEquals(64, initialSize);
+ bs.set(0, initialSize);
+ bs.clear(5);
+ bs.clear(15);
+ bs.clear(7, 11);
+ for (int i = 0; i < 7; i++) {
+ if (i == 5) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ } else {
+ assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+ }
+ }
+ for (int i = 7; i < 11; i++) {
+ assertFalse("Failed to clear bit " + i, bs.get(i));
+ }
+
+ for (int i = 11; i < initialSize; i++) {
+ if (i == 15) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ } else {
+ assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+ }
+ }
+
+ for (int i = initialSize; i < bs.size(); i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+
+ // pos1 and pos2 is in the same bitset element, boundary testing
+ bs = new BitSet(16);
+ initialSize = bs.size();
+ bs.set(0, initialSize);
+ bs.clear(7, 64);
+ assertEquals("Failed to grow BitSet", 64, bs.size());
+ for (int i = 0; i < 7; i++) {
+ assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+ }
+ for (int i = 7; i < 64; i++) {
+ assertFalse("Failed to clear bit " + i, bs.get(i));
+ }
+ for (int i = 64; i < bs.size(); i++) {
+ assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+ }
+ // more boundary testing
+ bs = new BitSet(32);
+ initialSize = bs.size();
+ bs.set(0, initialSize);
+ bs.clear(0, 64);
+ for (int i = 0; i < 64; i++) {
+ assertFalse("Failed to clear bit " + i, bs.get(i));
+ }
+ for (int i = 64; i < bs.size(); i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+
+ bs = new BitSet(32);
+ initialSize = bs.size();
+ bs.set(0, initialSize);
+ bs.clear(0, 65);
+ for (int i = 0; i < 65; i++) {
+ assertFalse("Failed to clear bit " + i, bs.get(i));
+ }
+ for (int i = 65; i < bs.size(); i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+
+ // pos1 and pos2 are in two sequential bitset elements
+ bs = new BitSet(128);
+ initialSize = bs.size();
+ bs.set(0, initialSize);
+ bs.clear(7);
+ bs.clear(110);
+ bs.clear(9, 74);
+ for (int i = 0; i < 9; i++) {
+ if (i == 7) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ } else {
+ assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+ }
+ }
+ for (int i = 9; i < 74; i++) {
+ assertFalse("Failed to clear bit " + i, bs.get(i));
+ }
+ for (int i = 74; i < initialSize; i++) {
+ if (i == 110) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ } else {
+ assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+ }
+ }
+ for (int i = initialSize; i < bs.size(); i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+
+ // pos1 and pos2 are in two non-sequential bitset elements
+ bs = new BitSet(256);
+ bs.set(0, 256);
+ bs.clear(7);
+ bs.clear(255);
+ bs.clear(9, 219);
+ for (int i = 0; i < 9; i++) {
+ if (i == 7) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ } else {
+ assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+ }
+ }
+
+ for (int i = 9; i < 219; i++) {
+ assertFalse("failed to clear bit " + i, bs.get(i));
+ }
+
+ for (int i = 219; i < 255; i++) {
+ assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+ }
+
+ for (int i = 255; i < bs.size(); i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+
+ // test illegal args
+ bs = new BitSet(10);
+ try {
+ bs.clear(-1, 3);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ bs.clear(2, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ bs.set(2, 4);
+ bs.clear(2, 2);
+ assertTrue("Bit got cleared incorrectly ", bs.get(2));
+
+ try {
+ bs.clear(4, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ bs = new BitSet(0);
+ assertEquals("Test1: Wrong length,", 0, bs.length());
+ assertEquals("Test1: Wrong size,", 0, bs.size());
+
+ bs.clear(0, 2);
+ assertEquals("Test2: Wrong length,", 0, bs.length());
+ assertEquals("Test2: Wrong size,", 0, bs.size());
+
+ bs.clear(60, 64);
+ assertEquals("Test3: Wrong length,", 0, bs.length());
+ assertEquals("Test3: Wrong size,", 0, bs.size());
+
+ bs.clear(64, 120);
+ assertEquals("Test4: Wrong length,", 0, bs.length());
+ assertEquals("Test4: Wrong size,", 0, bs.size());
+
+ bs.set(25);
+ assertEquals("Test5: Wrong length,", 26, bs.length());
+ assertEquals("Test5: Wrong size,", 64, bs.size());
+
+ bs.clear(60, 64);
+ assertEquals("Test6: Wrong length,", 26, bs.length());
+ assertEquals("Test6: Wrong size,", 64, bs.size());
+
+ bs.clear(64, 120);
+ assertEquals("Test7: Wrong size,", 64, bs.size());
+ assertEquals("Test7: Wrong length,", 26, bs.length());
+
+ bs.clear(80);
+ assertEquals("Test8: Wrong size,", 64, bs.size());
+ assertEquals("Test8: Wrong length,", 26, bs.length());
+
+ bs.clear(25);
+ assertEquals("Test9: Wrong size,", 64, bs.size());
+ assertEquals("Test9: Wrong length,", 0, bs.length());
+ }
+
+ public void test_getI() {
+ BitSet bs = new BitSet();
+ bs.set(8);
+ assertFalse("Get returned true for index out of range", eightbs.get(99));
+ assertTrue("Get returned false for set value", eightbs.get(3));
+ assertFalse("Get returned true for a non set value", bs.get(0));
+
+ try {
+ bs.get(-1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ bs = new BitSet(1);
+ assertFalse("Access greater than size", bs.get(64));
+
+ bs = new BitSet();
+ bs.set(63);
+ assertTrue("Test highest bit", bs.get(63));
+
+ bs = new BitSet(0);
+ assertEquals("Test1: Wrong length,", 0, bs.length());
+ assertEquals("Test1: Wrong size,", 0, bs.size());
+
+ bs.get(2);
+ assertEquals("Test2: Wrong length,", 0, bs.length());
+ assertEquals("Test2: Wrong size,", 0, bs.size());
+
+ bs.get(70);
+ assertEquals("Test3: Wrong length,", 0, bs.length());
+ assertEquals("Test3: Wrong size,", 0, bs.size());
+
+ bs = new BitSet();
+ try {
+ bs.get(Integer.MIN_VALUE);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ public void test_getII() {
+ BitSet bitset = new BitSet(30);
+ bitset.get(3, 3);
+
+ BitSet bs, resultbs, correctbs;
+ bs = new BitSet(512);
+ bs.set(3, 9);
+ bs.set(10, 20);
+ bs.set(60, 75);
+ bs.set(121);
+ bs.set(130, 140);
+
+ // pos1 and pos2 are in the same bitset element, at index0
+ resultbs = bs.get(3, 6);
+ correctbs = new BitSet(3);
+ correctbs.set(0, 3);
+ assertEquals("Test1: Returned incorrect BitSet", correctbs, resultbs);
+
+ // pos1 and pos2 are in the same bitset element, at index 1
+ resultbs = bs.get(100, 125);
+ correctbs = new BitSet(25);
+ correctbs.set(21);
+ assertEquals("Test2: Returned incorrect BitSet", correctbs, resultbs);
+
+ // pos1 in bitset element at index 0, and pos2 in bitset element at
+ // index 1
+ resultbs = bs.get(15, 125);
+ correctbs = new BitSet(25);
+ correctbs.set(0, 5);
+ correctbs.set(45, 60);
+ correctbs.set(121 - 15);
+ assertEquals("Test3: Returned incorrect BitSet", correctbs, resultbs);
+
+ // pos1 in bitset element at index 1, and pos2 in bitset element at
+ // index 2
+ resultbs = bs.get(70, 145);
+ correctbs = new BitSet(75);
+ correctbs.set(0, 5);
+ correctbs.set(51);
+ correctbs.set(60, 70);
+ assertEquals("Test4: Returned incorrect BitSet", correctbs, resultbs);
+
+ // pos1 in bitset element at index 0, and pos2 in bitset element at
+ // index 2
+ resultbs = bs.get(5, 145);
+ correctbs = new BitSet(140);
+ correctbs.set(0, 4);
+ correctbs.set(5, 15);
+ correctbs.set(55, 70);
+ correctbs.set(116);
+ correctbs.set(125, 135);
+ assertEquals("Test5: Returned incorrect BitSet", correctbs, resultbs);
+
+ // pos1 in bitset element at index 0, and pos2 in bitset element at
+ // index 3
+ resultbs = bs.get(5, 250);
+ correctbs = new BitSet(200);
+ correctbs.set(0, 4);
+ correctbs.set(5, 15);
+ correctbs.set(55, 70);
+ correctbs.set(116);
+ correctbs.set(125, 135);
+ assertEquals("Test6: Returned incorrect BitSet", correctbs, resultbs);
+
+ assertEquals("equality principle 1 ", bs.get(0, bs.size()), bs);
+
+ // more tests
+ BitSet bs2 = new BitSet(129);
+ bs2.set(0, 20);
+ bs2.set(62, 65);
+ bs2.set(121, 123);
+ resultbs = bs2.get(1, 124);
+ correctbs = new BitSet(129);
+ correctbs.set(0, 19);
+ correctbs.set(61, 64);
+ correctbs.set(120, 122);
+ assertEquals("Test7: Returned incorrect BitSet", correctbs, resultbs);
+
+ // equality principle with some boundary conditions
+ bs2 = new BitSet(128);
+ bs2.set(2, 20);
+ bs2.set(62);
+ bs2.set(121, 123);
+ bs2.set(127);
+ resultbs = bs2.get(0, bs2.size());
+ assertEquals("equality principle 2 ", resultbs, bs2);
+
+ bs2 = new BitSet(128);
+ bs2.set(2, 20);
+ bs2.set(62);
+ bs2.set(121, 123);
+ bs2.set(127);
+ bs2.flip(0, 128);
+ resultbs = bs2.get(0, bs.size());
+ assertEquals("equality principle 3 ", resultbs, bs2);
+
+ bs = new BitSet(0);
+ assertEquals("Test1: Wrong length,", 0, bs.length());
+ assertEquals("Test1: Wrong size,", 0, bs.size());
+
+ bs.get(0, 2);
+ assertEquals("Test2: Wrong length,", 0, bs.length());
+ assertEquals("Test2: Wrong size,", 0, bs.size());
+
+ bs.get(60, 64);
+ assertEquals("Test3: Wrong length,", 0, bs.length());
+ assertEquals("Test3: Wrong size,", 0, bs.size());
+
+ bs.get(64, 120);
+ assertEquals("Test4: Wrong length,", 0, bs.length());
+ assertEquals("Test4: Wrong size,", 0, bs.size());
+
+ bs.set(25);
+ assertEquals("Test5: Wrong length,", 26, bs.length());
+ assertEquals("Test5: Wrong size,", 64, bs.size());
+
+ bs.get(60, 64);
+ assertEquals("Test6: Wrong length,", 26, bs.length());
+ assertEquals("Test6: Wrong size,", 64, bs.size());
+
+ bs.get(64, 120);
+ assertEquals("Test7: Wrong size,", 64, bs.size());
+ assertEquals("Test7: Wrong length,", 26, bs.length());
+
+ bs.get(80);
+ assertEquals("Test8: Wrong size,", 64, bs.size());
+ assertEquals("Test8: Wrong length,", 26, bs.length());
+
+ bs.get(25);
+ assertEquals("Test9: Wrong size,", 64, bs.size());
+ assertEquals("Test9: Wrong length,", 26, bs.length());
+
+ try {
+ bs2.get(-1, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ bs2.get(bs2.size()/2, 0);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ bs2.get(bs2.size()/2, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_setI() {
+ BitSet bs = new BitSet();
+ bs.set(8);
+ assertTrue("Failed to set bit", bs.get(8));
+
+ try {
+ bs.set(-1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // Try setting a bit on a 64 boundary
+ bs.set(128);
+ assertEquals("Failed to grow BitSet", 192, bs.size());
+ assertTrue("Failed to set bit", bs.get(128));
+
+ bs = new BitSet(64);
+ for (int i = bs.size(); --i >= 0;) {
+ bs.set(i);
+ assertTrue("Incorrectly set", bs.get(i));
+ assertEquals("Incorrect length", i + 1, bs.length());
+ for (int j = bs.size(); --j > i; )
+ assertFalse("Incorrectly set bit " + j, bs.get(j));
+ for (int j = i; --j >= 0; )
+ assertFalse("Incorrectly set bit " + j, bs.get(j));
+ bs.clear(i);
+ }
+
+ bs = new BitSet(0);
+ assertEquals("Test1: Wrong length", 0, bs.length());
+ bs.set(0);
+ assertEquals("Test2: Wrong length", 1, bs.length());
+ }
+
+ public void test_setIZ() {
+ // Test for method void java.util.BitSet.set(int, boolean)
+ eightbs.set(5, false);
+ assertFalse("Should have set bit 5 to true", eightbs.get(5));
+
+ eightbs.set(5, true);
+ assertTrue("Should have set bit 5 to false", eightbs.get(5));
+
+ try {
+ eightbs.set(-5, false);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_setII() throws IndexOutOfBoundsException {
+ BitSet bitset = new BitSet(30);
+ bitset.set(29, 29);
+
+ // Test for method void java.util.BitSet.set(int, int)
+ // pos1 and pos2 are in the same bitset element
+ BitSet bs = new BitSet(16);
+ bs.set(5);
+ bs.set(15);
+ bs.set(7, 11);
+ assertEquals("{5, 7, 8, 9, 10, 15}", bs.toString());
+ for (int i = 16; i < bs.size(); i++) {
+ assertFalse("Shouldn't have set bit " + i, bs.get(i));
+ }
+
+ // pos1 and pos2 is in the same bitset element, boundary testing
+ bs = new BitSet(16);
+ bs.set(7, 64);
+ assertEquals("Failed to grow BitSet", 64, bs.size());
+ for (int i = 0; i < 7; i++) {
+ assertFalse("Shouldn't have set bit " + i, bs.get(i));
+ }
+ for (int i = 7; i < 64; i++) {
+ assertTrue("Failed to set bit " + i, bs.get(i));
+ }
+ assertFalse("Shouldn't have set bit 64", bs.get(64));
+
+ // more boundary testing
+ bs = new BitSet(32);
+ bs.set(0, 64);
+ for (int i = 0; i < 64; i++) {
+ assertTrue("Failed to set bit " + i, bs.get(i));
+ }
+ assertTrue("Shouldn't have set bit 64", !bs.get(64));
+
+ bs = new BitSet(32);
+ bs.set(0, 65);
+ for (int i = 0; i < 65; i++) {
+ assertTrue("Failed to set bit " + i, bs.get(i));
+ }
+ assertTrue("Shouldn't have set bit 65", !bs.get(65));
+
+ // pos1 and pos2 are in two sequential bitset elements
+ bs = new BitSet(128);
+ bs.set(7);
+ bs.set(110);
+ bs.set(9, 74);
+ for (int i = 0; i < 9; i++) {
+ if (i == 7) {
+ assertTrue("Shouldn't have flipped bit " + i, bs.get(i));
+ } else {
+ assertFalse("Shouldn't have set bit " + i, bs.get(i));
+ }
+ }
+ for (int i = 9; i < 74; i++) {
+ assertTrue("Failed to set bit " + i, bs.get(i));
+ }
+ for (int i = 74; i < bs.size(); i++) {
+ if (i == 110) {
+ assertTrue("Shouldn't have flipped bit " + i, bs.get(i));
+ } else {
+ assertFalse("Shouldn't have set bit " + i, bs.get(i));
+ }
+ }
+
+ // pos1 and pos2 are in two non-sequential bitset elements
+ bs = new BitSet(256);
+ bs.set(7);
+ bs.set(255);
+ bs.set(9, 219);
+ for (int i = 0; i < 9; i++) {
+ if (i == 7) {
+ assertTrue("Shouldn't have set flipped " + i, bs.get(i));
+ } else {
+ assertFalse("Shouldn't have set bit " + i, bs.get(i));
+ }
+ }
+
+ for (int i = 9; i < 219; i++) {
+ assertTrue("failed to set bit " + i, bs.get(i));
+ }
+
+ for (int i = 219; i < 255; i++) {
+ assertTrue("Shouldn't have set bit " + i, !bs.get(i));
+ }
+
+ assertTrue("Shouldn't have flipped bit 255", bs.get(255));
+
+ // test illegal args
+ bs = new BitSet(10);
+ try {
+ bs.set(-1, 3);
+ fail("Test1: Attempt to flip with negative index failed to generate exception");
+ } catch (IndexOutOfBoundsException e) {
+ // Correct behavior
+ }
+
+ try {
+ bs.set(2, -1);
+ fail("Test2: Attempt to flip with negative index failed to generate exception");
+ } catch (IndexOutOfBoundsException e) {
+ // Correct behavior
+ }
+
+ bs.set(2, 2);
+ assertFalse("Bit got set incorrectly ", bs.get(2));
+
+ try {
+ bs.set(4, 2);
+ fail("Test4: Attempt to flip with illegal args failed to generate exception");
+ } catch (IndexOutOfBoundsException e) {
+ // Correct behavior
+ }
+ }
+
+ public void test_setIIZ() {
+ // Test for method void java.util.BitSet.set(int, int, boolean)
+ eightbs.set(3, 6, false);
+ assertTrue("Should have set bits 3, 4, and 5 to false", !eightbs.get(3)
+ && !eightbs.get(4) && !eightbs.get(5));
+
+ eightbs.set(3, 6, true);
+ assertTrue("Should have set bits 3, 4, and 5 to true", eightbs.get(3)
+ && eightbs.get(4) && eightbs.get(5));
+
+ try {
+ eightbs.set(-3, 6, false);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ eightbs.set(3, -6, false);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ eightbs.set(6, 3, false);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+
+ public void test_flipI() {
+ BitSet bs = new BitSet();
+ bs.clear(8);
+ bs.clear(9);
+ bs.set(10);
+ bs.flip(9);
+ assertFalse("Failed to flip bit", bs.get(8));
+ assertTrue("Failed to flip bit", bs.get(9));
+ assertTrue("Failed to flip bit", bs.get(10));
+
+ bs.set(8);
+ bs.set(9);
+ bs.clear(10);
+ bs.flip(9);
+ assertTrue("Failed to flip bit", bs.get(8));
+ assertFalse("Failed to flip bit", bs.get(9));
+ assertFalse("Failed to flip bit", bs.get(10));
+
+ try {
+ bs.flip(-1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // Try setting a bit on a 64 boundary
+ bs.flip(128);
+ assertEquals("Failed to grow BitSet", 192, bs.size());
+ assertTrue("Failed to flip bit", bs.get(128));
+
+ bs = new BitSet(64);
+ for (int i = bs.size(); --i >= 0;) {
+ bs.flip(i);
+ assertTrue("Test1: Incorrectly flipped bit" + i, bs.get(i));
+ assertEquals("Incorrect length", i + 1, bs.length());
+ for (int j = bs.size(); --j > i; ) {
+ assertTrue("Test2: Incorrectly flipped bit" + j, !bs.get(j));
+ }
+ for (int j = i; --j >= 0; ) {
+ assertTrue("Test3: Incorrectly flipped bit" + j, !bs.get(j));
+ }
+ bs.flip(i);
+ }
+
+ BitSet bs0 = new BitSet(0);
+ assertEquals("Test1: Wrong size", 0, bs0.size());
+ assertEquals("Test1: Wrong length", 0, bs0.length());
+
+ bs0.flip(0);
+ assertEquals("Test2: Wrong size", 64, bs0.size());
+ assertEquals("Test2: Wrong length", 1, bs0.length());
+
+ bs0.flip(63);
+ assertEquals("Test3: Wrong size", 64, bs0.size());
+ assertEquals("Test3: Wrong length", 64, bs0.length());
+
+ eightbs.flip(7);
+ assertTrue("Failed to flip bit 7", !eightbs.get(7));
+
+ // Check to see all other bits are still set
+ for (int i = 0; i < 7; i++) {
+ assertTrue("Flip flipped incorrect bits", eightbs.get(i));
+ }
+
+ eightbs.flip(127);
+ assertTrue("Failed to flip bit 127", eightbs.get(127));
+
+ eightbs.flip(127);
+ assertTrue("Failed to flip bit 127", !eightbs.get(127));
+ }
+
+ public void test_flipII() {
+ BitSet bitset = new BitSet();
+ for (int i = 0; i < 20; i++) {
+ bitset.set(i);
+ }
+ bitset.flip(10, 10);
+
+ // pos1 and pos2 are in the same bitset element
+ BitSet bs = new BitSet(16);
+ bs.set(7);
+ bs.set(10);
+ bs.flip(7, 11);
+ for (int i = 0; i < 7; i++) {
+ assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+ }
+ assertFalse("Failed to flip bit 7", bs.get(7));
+ assertTrue("Failed to flip bit 8", bs.get(8));
+ assertTrue("Failed to flip bit 9", bs.get(9));
+ assertFalse("Failed to flip bit 10", bs.get(10));
+ for (int i = 11; i < bs.size(); i++) {
+ assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+ }
+
+ // pos1 and pos2 is in the same bitset element, boundry testing
+ bs = new BitSet(16);
+ bs.set(7);
+ bs.set(10);
+ bs.flip(7, 64);
+ assertEquals("Failed to grow BitSet", 64, bs.size());
+ for (int i = 0; i < 7; i++) {
+ assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+ }
+ assertFalse("Failed to flip bit 7", bs.get(7));
+ assertTrue("Failed to flip bit 8", bs.get(8));
+ assertTrue("Failed to flip bit 9", bs.get(9));
+ assertFalse("Failed to flip bit 10", bs.get(10));
+ for (int i = 11; i < 64; i++) {
+ assertTrue("failed to flip bit " + i, bs.get(i));
+ }
+ assertFalse("Shouldn't have flipped bit 64", bs.get(64));
+
+ // more boundary testing
+ bs = new BitSet(32);
+ bs.flip(0, 64);
+ for (int i = 0; i < 64; i++) {
+ assertTrue("Failed to flip bit " + i, bs.get(i));
+ }
+ assertFalse("Shouldn't have flipped bit 64", bs.get(64));
+
+ bs = new BitSet(32);
+ bs.flip(0, 65);
+ for (int i = 0; i < 65; i++) {
+ assertTrue("Failed to flip bit " + i, bs.get(i));
+ }
+ assertFalse("Shouldn't have flipped bit 65", bs.get(65));
+
+ // pos1 and pos2 are in two sequential bitset elements
+ bs = new BitSet(128);
+ bs.set(7);
+ bs.set(10);
+ bs.set(72);
+ bs.set(110);
+ bs.flip(9, 74);
+ for (int i = 0; i < 7; i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+ assertTrue("Shouldn't have flipped bit 7", bs.get(7));
+ assertFalse("Shouldn't have flipped bit 8", bs.get(8));
+ assertTrue("Failed to flip bit 9", bs.get(9));
+ assertFalse("Failed to flip bit 10", bs.get(10));
+ for (int i = 11; i < 72; i++) {
+ assertTrue("failed to flip bit " + i, bs.get(i));
+ }
+ assertFalse("Failed to flip bit 72", bs.get(72));
+ assertTrue("Failed to flip bit 73", bs.get(73));
+ for (int i = 74; i < 110; i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+ assertTrue("Shouldn't have flipped bit 110", bs.get(110));
+ for (int i = 111; i < bs.size(); i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+
+ // pos1 and pos2 are in two non-sequential bitset elements
+ bs = new BitSet(256);
+ bs.set(7);
+ bs.set(10);
+ bs.set(72);
+ bs.set(110);
+ bs.set(181);
+ bs.set(220);
+ bs.flip(9, 219);
+ for (int i = 0; i < 7; i++) {
+ assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+ }
+ assertTrue("Shouldn't have flipped bit 7", bs.get(7));
+ assertFalse("Shouldn't have flipped bit 8", bs.get(8));
+ assertTrue("Failed to flip bit 9", bs.get(9));
+ assertFalse("Failed to flip bit 10", bs.get(10));
+ for (int i = 11; i < 72; i++) {
+ assertTrue("failed to flip bit " + i, bs.get(i));
+ }
+ assertFalse("Failed to flip bit 72", bs.get(72));
+ for (int i = 73; i < 110; i++) {
+ assertTrue("failed to flip bit " + i, bs.get(i));
+ }
+ assertFalse("Failed to flip bit 110", bs.get(110));
+ for (int i = 111; i < 181; i++) {
+ assertTrue("failed to flip bit " + i, bs.get(i));
+ }
+ assertFalse("Failed to flip bit 181", bs.get(181));
+ for (int i = 182; i < 219; i++) {
+ assertTrue("failed to flip bit " + i, bs.get(i));
+ }
+ assertFalse("Shouldn't have flipped bit 219", bs.get(219));
+ assertTrue("Shouldn't have flipped bit 220", bs.get(220));
+ for (int i = 221; i < bs.size(); i++) {
+ assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+ }
+
+ // test illegal args
+ bs = new BitSet(10);
+ try {
+ bs.flip(-1, 3);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ bs.flip(2, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ bs.flip(4, 2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_111478() throws Exception {
+ // BitSet shouldn't be modified by any of the operations below,
+ // since the affected bits for these methods are defined as inclusive of
+ // pos1, exclusive of pos2.
+ eightbs.flip(0, 0);
+ assertTrue("Bit got flipped incorrectly ", eightbs.get(0));
+
+ BitSet bsnew = eightbs.get(2, 2);
+ assertEquals(0, bsnew.cardinality());
+
+ eightbs.set(10, 10);
+ assertTrue("Bit got set incorrectly ", !eightbs.get(10));
+
+ eightbs.clear(3, 3);
+ assertTrue("Bit cleared incorrectly ", eightbs.get(3));
+ }
+
+ public void test_intersectsLjava_util_BitSet() {
+ BitSet bs = new BitSet(500);
+ bs.set(5);
+ bs.set(63);
+ bs.set(64);
+ bs.set(71, 110);
+ bs.set(127, 130);
+ bs.set(192);
+ bs.set(450);
+
+ BitSet bs2 = new BitSet(8);
+ assertFalse("Test1: intersects() returned incorrect value", bs.intersects(bs2));
+ assertFalse("Test1: intersects() returned incorrect value", bs2.intersects(bs));
+
+ bs2.set(4);
+ assertFalse("Test2: intersects() returned incorrect value", bs.intersects(bs2));
+ assertFalse("Test2: intersects() returned incorrect value", bs2.intersects(bs));
+
+ bs2.clear();
+ bs2.set(5);
+ assertTrue("Test3: intersects() returned incorrect value", bs.intersects(bs2));
+ assertTrue("Test3: intersects() returned incorrect value", bs2.intersects(bs));
+
+ bs2.clear();
+ bs2.set(63);
+ assertTrue("Test4: intersects() returned incorrect value", bs.intersects(bs2));
+ assertTrue("Test4: intersects() returned incorrect value", bs2.intersects(bs));
+
+ bs2.clear();
+ bs2.set(80);
+ assertTrue("Test5: intersects() returned incorrect value", bs.intersects(bs2));
+ assertTrue("Test5: intersects() returned incorrect value", bs2.intersects(bs));
+
+ bs2.clear();
+ bs2.set(127);
+ assertTrue("Test6: intersects() returned incorrect value", bs.intersects(bs2));
+ assertTrue("Test6: intersects() returned incorrect value", bs2.intersects(bs));
+
+ bs2.clear();
+ bs2.set(192);
+ assertTrue("Test7: intersects() returned incorrect value", bs.intersects(bs2));
+ assertTrue("Test7: intersects() returned incorrect value", bs2.intersects(bs));
+
+ bs2.clear();
+ bs2.set(450);
+ assertTrue("Test8: intersects() returned incorrect value", bs.intersects(bs2));
+ assertTrue("Test8: intersects() returned incorrect value", bs2.intersects(bs));
+
+ bs2.clear();
+ bs2.set(500);
+ assertFalse("Test9: intersects() returned incorrect value", bs.intersects(bs2));
+ assertFalse("Test9: intersects() returned incorrect value", bs2.intersects(bs));
+ }
+
+ public void test_andLjava_util_BitSet() {
+ BitSet bs = new BitSet(128);
+ // Initialize the bottom half of the BitSet
+ for (int i = 64; i < 128; i++) {
+ bs.set(i);
+ }
+ eightbs.and(bs);
+ assertFalse("AND failed to clear bits", eightbs.equals(bs));
+ eightbs.set(3);
+ bs.set(3);
+ eightbs.and(bs);
+ assertTrue("AND failed to maintain set bits", bs.get(3));
+ bs.and(eightbs);
+ for (int i = 64; i < 128; i++) {
+ assertFalse("Failed to clear extra bits in the receiver BitSet", bs.get(i));
+ }
+
+ bs = new BitSet(64);
+ try {
+ bs.and(null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void test_andNotLjava_util_BitSet() {
+ BitSet bs = (BitSet) eightbs.clone();
+ bs.clear(5);
+ BitSet bs2 = new BitSet();
+ bs2.set(2);
+ bs2.set(3);
+ bs.andNot(bs2);
+ assertEquals("Incorrect bitset after andNot",
+ "{0, 1, 4, 6, 7}", bs.toString());
+
+ bs = new BitSet(0);
+ bs.andNot(bs2);
+ assertEquals("Incorrect size", 0, bs.size());
+
+ bs = new BitSet(64);
+ try {
+ bs.andNot(null);
+ fail("Should throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // Regression test for HARMONY-4213
+ bs = new BitSet(256);
+ bs2 = new BitSet(256);
+ bs.set(97);
+ bs2.set(37);
+ bs.andNot(bs2);
+ assertTrue("Incorrect value at 97 pos", bs.get(97));
+ }
+
+ public void test_orLjava_util_BitSet() {
+ BitSet bs = new BitSet(128);
+ bs.or(eightbs);
+ for (int i = 0; i < 8; i++) {
+ assertTrue("OR failed to set bits", bs.get(i));
+ }
+ bs = new BitSet(0);
+ bs.or(eightbs);
+ for (int i = 0; i < 8; i++) {
+ assertTrue("OR(0) failed to set bits", bs.get(i));
+ }
+ eightbs.clear(5);
+ bs = new BitSet(128);
+ bs.or(eightbs);
+ assertTrue("OR set a bit which should be off", !bs.get(5));
+ }
+
+ public void test_xorLjava_util_BitSet() {
+ BitSet bs = (BitSet) eightbs.clone();
+ bs.xor(eightbs);
+ for (int i = 0; i < 8; i++) {
+ assertTrue("XOR failed to clear bit " + i + bs, !bs.get(i));
+ }
+ bs.xor(eightbs);
+ for (int i = 0; i < 8; i++) {
+ assertTrue("XOR failed to set bit " + i + bs, bs.get(i));
+ }
+ bs = new BitSet(0);
+ bs.xor(eightbs);
+ for (int i = 0; i < 8; i++) {
+ assertTrue("XOR(0) failed to set bit " + i + bs, bs.get(i));
+ }
+ bs = new BitSet();
+ bs.set(63);
+ assertEquals("{63}", bs.toString());
+ }
+
+ public void test_size() {
+ assertEquals("Returned incorrect size", 64, eightbs.size());
+ eightbs.set(129);
+ assertTrue("Returned incorrect size", eightbs.size() >= 129);
+
+ }
+
+ public void test_toString() {
+ assertEquals("Returned incorrect string representation", "{0, 1, 2, 3, 4, 5, 6, 7}", eightbs.toString());
+ eightbs.clear(2);
+ assertEquals("Returned incorrect string representation", "{0, 1, 3, 4, 5, 6, 7}", eightbs.toString());
+ }
+
+ public void test_length() {
+ BitSet bs = new BitSet();
+ assertEquals(bs.toString(), 0, bs.length());
+ bs.set(5);
+ assertEquals(bs.toString(), 6, bs.length());
+ bs.set(10);
+ assertEquals(bs.toString(), 11, bs.length());
+ bs.set(432);
+ assertEquals(bs.toString(), 433, bs.length());
+ bs.set(300);
+ assertEquals(bs.toString(), 433, bs.length());
+ }
+
+ public void test_nextSetBitI() {
+ BitSet bs = new BitSet(500);
+ bs.set(5);
+ bs.set(32);
+ bs.set(63);
+ bs.set(64);
+ bs.set(71, 110);
+ bs.set(127, 130);
+ bs.set(193);
+ bs.set(450);
+ try {
+ bs.nextSetBit(-1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ assertEquals(5, bs.nextSetBit(0));
+ assertEquals(5, bs.nextSetBit(5));
+ assertEquals(32, bs.nextSetBit(6));
+ assertEquals(32, bs.nextSetBit(32));
+ assertEquals(63, bs.nextSetBit(33));
+
+ // boundary tests
+ assertEquals(63, bs.nextSetBit(63));
+ assertEquals(64, bs.nextSetBit(64));
+
+ // at bitset element 1
+ assertEquals(71, bs.nextSetBit(65));
+ assertEquals(71, bs.nextSetBit(71));
+ assertEquals(72, bs.nextSetBit(72));
+ assertEquals(127, bs.nextSetBit(110));
+
+ // boundary tests
+ assertEquals(127, bs.nextSetBit(127));
+ assertEquals(128, bs.nextSetBit(128));
+
+ // at bitset element 2
+ assertEquals(193, bs.nextSetBit(130));
+
+ assertEquals(193, bs.nextSetBit(191));
+ assertEquals(193, bs.nextSetBit(192));
+ assertEquals(193, bs.nextSetBit(193));
+ assertEquals(450, bs.nextSetBit(194));
+ assertEquals(450, bs.nextSetBit(255));
+ assertEquals(450, bs.nextSetBit(256));
+ assertEquals(450, bs.nextSetBit(450));
+
+ assertEquals(-1, bs.nextSetBit(451));
+ assertEquals(-1, bs.nextSetBit(511));
+ assertEquals(-1, bs.nextSetBit(512));
+ assertEquals(-1, bs.nextSetBit(800));
+ }
+
+ public void test_nextClearBitI() {
+ BitSet bs = new BitSet(500);
+ // ensure all the bits from 0 to bs.size() - 1 are set to true
+ bs.set(0, bs.size() - 1);
+ bs.set(bs.size() - 1);
+ bs.clear(5);
+ bs.clear(32);
+ bs.clear(63);
+ bs.clear(64);
+ bs.clear(71, 110);
+ bs.clear(127, 130);
+ bs.clear(193);
+ bs.clear(450);
+ try {
+ bs.nextClearBit(-1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ assertEquals(5, bs.nextClearBit(0));
+ assertEquals(5, bs.nextClearBit(5));
+ assertEquals(32, bs.nextClearBit(6));
+ assertEquals(32, bs.nextClearBit(32));
+ assertEquals(63, bs.nextClearBit(33));
+
+ // boundary tests
+ assertEquals(63, bs.nextClearBit(63));
+ assertEquals(64, bs.nextClearBit(64));
+
+ // at bitset element 1
+ assertEquals(71, bs.nextClearBit(65));
+ assertEquals(71, bs.nextClearBit(71));
+ assertEquals(72, bs.nextClearBit(72));
+ assertEquals(127, bs.nextClearBit(110));
+
+ // boundary tests
+ assertEquals(127, bs.nextClearBit(127));
+ assertEquals(128, bs.nextClearBit(128));
+
+ // at bitset element 2
+ assertEquals(193, bs.nextClearBit(130));
+ assertEquals(193, bs.nextClearBit(191));
+
+ assertEquals(193, bs.nextClearBit(192));
+ assertEquals(193, bs.nextClearBit(193));
+ assertEquals(450, bs.nextClearBit(194));
+ assertEquals(450, bs.nextClearBit(255));
+ assertEquals(450, bs.nextClearBit(256));
+ assertEquals(450, bs.nextClearBit(450));
+
+ // bitset has 1 still the end of bs.size() -1, but calling nextClearBit
+ // with any index value after the last true bit should return bs.size()
+ assertEquals(512, bs.nextClearBit(451));
+ assertEquals(512, bs.nextClearBit(511));
+ assertEquals(512, bs.nextClearBit(512));
+
+ // if the index is larger than bs.size(), nextClearBit should return index
+ assertEquals(513, bs.nextClearBit(513));
+ assertEquals(800, bs.nextClearBit(800));
+
+ bs.clear();
+ assertEquals(0, bs.nextClearBit(0));
+ assertEquals(3, bs.nextClearBit(3));
+ assertEquals(64, bs.nextClearBit(64));
+ assertEquals(128, bs.nextClearBit(128));
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=31036
+ public void test_31036_clear() {
+ BitSet bs = new BitSet(500);
+ for (int i = 0; i < 500; ++i) {
+ int nextClear = bs.nextClearBit(0);
+ assertEquals(i, nextClear);
+ bs.set(i);
+ }
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=31036
+ public void test_31036_set() {
+ BitSet bs = new BitSet(500);
+ bs.set(0, 511);
+ for (int i = 0; i < 500; ++i) {
+ int nextSet = bs.nextSetBit(0);
+ assertEquals(i, nextSet);
+ bs.clear(i);
+ }
+ }
+
+ public void test_isEmpty() {
+ BitSet bs = new BitSet(500);
+ assertTrue("Test: isEmpty() returned wrong value", bs.isEmpty());
+
+ // at bitset element 0
+ bs.set(3);
+ assertFalse("Test0: isEmpty() returned wrong value", bs.isEmpty());
+
+ // at bitset element 1
+ bs.clear();
+ bs.set(12);
+ assertFalse("Test1: isEmpty() returned wrong value", bs.isEmpty());
+
+ // at bitset element 2
+ bs.clear();
+ bs.set(128);
+ assertFalse("Test2: isEmpty() returned wrong value", bs.isEmpty());
+
+ // boundary testing
+ bs.clear();
+ bs.set(459);
+ assertFalse("Test3: isEmpty() returned wrong value", bs.isEmpty());
+
+ bs.clear();
+ bs.set(511);
+ assertFalse("Test4: isEmpty() returned wrong value", bs.isEmpty());
+ }
+
+ public void test_cardinality() {
+ BitSet bs = new BitSet(500);
+ bs.set(5);
+ bs.set(32);
+ bs.set(63);
+ bs.set(64);
+ assertEquals(bs.toString(), 4, bs.cardinality());
+ bs.set(71, 110);
+ bs.set(127, 130);
+ bs.set(193);
+ bs.set(450);
+ assertEquals(bs.toString(), 48, bs.cardinality());
+
+ bs.flip(0, 500);
+ assertEquals("cardinality() returned wrong value", 452, bs
+ .cardinality());
+
+ bs.clear();
+ assertEquals("cardinality() returned wrong value", 0, bs.cardinality());
+
+ bs.set(0, 500);
+ assertEquals("cardinality() returned wrong value", 500, bs
+ .cardinality());
+
+ bs.clear();
+ bs.set(0, 64);
+ assertEquals("cardinality() returned wrong value", 64, bs.cardinality());
+ }
+
+ public void test_serialization() throws Exception {
+ BitSet bs = new BitSet(500);
+ bs.set(5);
+ bs.set(32);
+ bs.set(63);
+ bs.set(64);
+ bs.set(71, 110);
+ bs.set(127, 130);
+ bs.set(193);
+ bs.set(450);
+ SerializationTest.verifySelf(bs);
+ }
+
+
+ protected void setUp() {
+ eightbs = new BitSet();
+ for (int i = 0; i < 8; i++) {
+ eightbs.set(i);
+ }
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CalendarTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CalendarTest.java
new file mode 100644
index 0000000..06a37c8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CalendarTest.java
@@ -0,0 +1,1099 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.text.DateFormatSymbols;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class CalendarTest extends junit.framework.TestCase {
+
+ Locale defaultLocale;
+
+ /**
+ * java.util.Calendar#set(int, int)
+ */
+ public void test_setII() {
+ // Test for correct result defined by the last set field
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ assertTrue("Incorrect result 0: " + cal.getTime().getTime(), cal
+ .getTime().getTime() == 1009861200000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ assertTrue("Incorrect result 0a: " + cal.getTime(), cal.getTime()
+ .getTime() == 1014958800000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DATE, 24);
+ assertTrue("Incorrect result 0b: " + cal.getTime(), cal.getTime()
+ .getTime() == 1011848400000L);
+
+ cal.set(Calendar.MONTH, Calendar.OCTOBER);
+ cal.set(Calendar.DATE, 31);
+ cal.set(Calendar.MONTH, Calendar.NOVEMBER);
+ cal.set(Calendar.DATE, 26);
+ assertTrue("Incorrect month: " + cal.get(Calendar.MONTH), cal
+ .get(Calendar.MONTH) == Calendar.NOVEMBER);
+
+ int dow = cal.get(Calendar.DAY_OF_WEEK);
+ cal.set(Calendar.DATE, 27);
+ assertTrue("Incorrect DAY_OF_WEEK: " + cal.get(Calendar.DAY_OF_WEEK)
+ + " expected: " + dow, cal.get(Calendar.DAY_OF_WEEK) != dow);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ assertTrue("Incorrect result 0c1: " + cal.getTime().getTime(), cal
+ .getTime().getTime() == 1010379600000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ assertTrue("Incorrect result 0c2: " + cal.getTime().getTime(), cal
+ .getTime().getTime() == 1009861200000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
+ assertTrue("Incorrect result 0c3: " + cal.getTime(), cal.getTime()
+ .getTime() == 1010034000000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_MONTH, 2);
+ assertTrue("Incorrect result 0d: " + cal.getTime(), cal.getTime()
+ .getTime() == 1010293200000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2);
+ assertTrue("Incorrect result 0e: " + cal.getTime(), cal.getTime()
+ .getTime() == 1010898000000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 11);
+ assertTrue("Incorrect result 0f: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015736400000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DATE, 24);
+ cal.set(Calendar.WEEK_OF_YEAR, 11);
+ assertTrue("Incorrect result 0g: " + cal.getTime(), cal.getTime()
+ .getTime() == 1011848400000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.get(Calendar.WEEK_OF_YEAR); // Force fields to compute
+ cal.set(Calendar.WEEK_OF_YEAR, 11);
+ assertTrue("Incorrect result 0h: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015909200000L);
+
+ // WEEK_OF_YEAR has priority over MONTH/DATE
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_YEAR, 170);
+ cal.set(Calendar.WEEK_OF_YEAR, 11);
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ cal.set(Calendar.DATE, 5);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ assertTrue("Incorrect result 1: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // WEEK_OF_YEAR has priority over MONTH/DATE
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 11);
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ cal.set(Calendar.DATE, 5);
+ cal.set(Calendar.DAY_OF_YEAR, 170);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ assertTrue("Incorrect result 1a: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // DAY_OF_WEEK has no effect when other fields not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.DATE, 11);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ assertTrue("Incorrect result 1b: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+ // Regression for HARMONY-4384
+ // Set DAY_OF_WEEK without DATE
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ assertEquals("Incorrect result 1b: " + cal.getTime(), 1015304400000L, cal.getTime()
+ .getTime());
+
+
+ // WEEK_OF_MONTH has priority
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 12);
+ cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+ cal.set(Calendar.WEEK_OF_MONTH, 3);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.DATE, 5);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ assertTrue("Incorrect result 2: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // DAY_OF_WEEK_IN_MONTH has priority over WEEK_OF_YEAR
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 12);
+ cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.DATE, 5);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ assertTrue("Incorrect result 3: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // WEEK_OF_MONTH has priority, MONTH not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 12);
+ cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+ cal.set(Calendar.WEEK_OF_MONTH, 3);
+ cal.set(Calendar.DATE, 25);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ assertTrue("Incorrect result 4: " + cal.getTime(), cal.getTime()
+ .getTime() == 1010984400000L);
+
+ // WEEK_OF_YEAR has priority when MONTH set last and DAY_OF_WEEK set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 11);
+ cal.set(Calendar.DATE, 25);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ assertTrue("Incorrect result 5: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // Use MONTH/DATE when WEEK_OF_YEAR set but not DAY_OF_WEEK
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 12);
+ cal.set(Calendar.DATE, 11);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ assertTrue("Incorrect result 5a: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // Use MONTH/DATE when DAY_OF_WEEK is not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 12);
+ cal.set(Calendar.DATE, 11);
+ cal.set(Calendar.WEEK_OF_MONTH, 1);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ assertTrue("Incorrect result 5b: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // WEEK_OF_MONTH has priority
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 12);
+ cal.set(Calendar.DATE, 5);
+ cal.set(Calendar.WEEK_OF_MONTH, 3);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ assertTrue("Incorrect result 5c: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // DATE has priority when set last
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 12);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.DATE, 11);
+ assertTrue("Incorrect result 6: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // DATE has priority when set last, MONTH not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 12);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ cal.set(Calendar.DATE, 14);
+ assertTrue("Incorrect result 7: " + cal.getTime(), cal.getTime()
+ .getTime() == 1010984400000L);
+
+ // DAY_OF_YEAR has priority when MONTH set last and DATE not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_YEAR, 70);
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ assertTrue("Incorrect result 8: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // DAY/MONTH has priority when DATE set after DAY_OF_YEAR
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_YEAR, 170);
+ cal.set(Calendar.DATE, 11);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ assertTrue("Incorrect result 8a: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // DAY_OF_YEAR has priority when set after DATE
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DATE, 15);
+ cal.set(Calendar.DAY_OF_YEAR, 70);
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ assertTrue("Incorrect result 8b: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // DATE has priority when set last
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_YEAR, 70);
+ cal.set(Calendar.DATE, 14);
+ assertTrue("Incorrect result 9: " + cal.getTime(), cal.getTime()
+ .getTime() == 1010984400000L);
+
+ // DATE has priority when set last
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_YEAR, 15);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
+ cal.set(Calendar.DATE, 14);
+ assertTrue("Incorrect result 9a: " + cal.getTime(), cal.getTime()
+ .getTime() == 1010984400000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ cal.set(Calendar.DATE, 14);
+ cal.set(Calendar.WEEK_OF_YEAR, 11);
+ assertTrue("Incorrect result 9b: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DATE, 14);
+ cal.set(Calendar.WEEK_OF_YEAR, 11);
+ assertTrue("Incorrect result 9c: " + cal.getTime(), cal.getTime()
+ .getTime() == 1010984400000L);
+
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.WEEK_OF_MONTH, 1);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.DATE, 11);
+ assertTrue("Incorrect result 9d: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // DAY_OF_YEAR has priority when DAY_OF_MONTH set last and other fields
+ // not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_YEAR, 70);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ assertTrue("Incorrect result 10: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // MONTH/DATE has priority when DAY_OF_WEEK_IN_MONTH set last but
+ // DAY_OF_WEEK not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DATE, 11);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+ assertTrue("Incorrect result 11: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // MONTH/DATE has priority when WEEK_OF_YEAR set last but DAY_OF_WEEK
+ // not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DATE, 11);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.WEEK_OF_YEAR, 15);
+ assertTrue("Incorrect result 12: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // MONTH/DATE has priority when WEEK_OF_MONTH set last but DAY_OF_WEEK
+ // not set
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DATE, 11);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.WEEK_OF_MONTH, 1);
+ assertTrue("Incorrect result 13: " + cal.getTime(), cal.getTime()
+ .getTime() == 1015822800000L);
+
+ // Ensure last date field set is reset after computing
+ cal.clear();
+ cal.set(Calendar.YEAR, 2002);
+ cal.set(Calendar.DAY_OF_YEAR, 111);
+ cal.get(Calendar.YEAR);
+ cal.set(Calendar.MONTH, Calendar.MARCH);
+ cal.set(Calendar.AM_PM, Calendar.AM);
+ assertTrue("Incorrect result 14: " + cal.getTime(), cal.getTime()
+ .getTime() == 1016686800000L);
+
+ int hour = cal.get(Calendar.HOUR);
+ cal.set(Calendar.HOUR, hour);
+ cal.set(Calendar.AM_PM, Calendar.PM);
+ assertEquals("AM_PM not changed", Calendar.PM, cal.get(Calendar.AM_PM));
+ // setting AM_PM without HOUR should not have any affect
+ cal.set(Calendar.AM_PM, Calendar.AM);
+ assertEquals("AM_PM was changed 1",
+ Calendar.AM, cal.get(Calendar.AM_PM));
+ int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
+ hour = cal.get(Calendar.HOUR);
+ cal.set(Calendar.AM_PM, Calendar.PM);
+ assertEquals("AM_PM was changed 2",
+ Calendar.PM, cal.get(Calendar.AM_PM));
+ assertEquals(hour, cal.get(Calendar.HOUR));
+ assertEquals(hourOfDay + 12, cal.get(Calendar.HOUR_OF_DAY));
+
+ // regression test for Harmony-2122
+ cal = Calendar.getInstance();
+ int oldValue = cal.get(Calendar.AM_PM);
+ int newValue = (oldValue == Calendar.AM) ? Calendar.PM : Calendar.AM;
+ cal.set(Calendar.AM_PM, newValue);
+ newValue = cal.get(Calendar.AM_PM);
+ assertTrue(newValue != oldValue);
+ }
+
+ /**
+ * java.util.Calendar#setTime(java.util.Date)
+ */
+ public void test_setTimeLjava_util_Date() {
+ Calendar cal = Calendar.getInstance();
+ // Use millisecond time for testing in Core
+ cal.setTime(new Date(884581200000L)); // (98, Calendar.JANUARY, 12)
+ assertEquals("incorrect millis", 884581200000L, cal.getTime().getTime());
+ cal.setTimeZone(TimeZone.getTimeZone("EST"));
+ cal.setTime(new Date(943506000000L)); // (99, Calendar.NOVEMBER, 25)
+ assertTrue("incorrect fields", cal.get(Calendar.YEAR) == 1999
+ && cal.get(Calendar.MONTH) == Calendar.NOVEMBER
+ && cal.get(Calendar.DATE) == 25);
+ }
+
+ /**
+ * java.util.Calendar#compareTo(Calendar)
+ */
+ public void test_compareToLjava_util_Calendar_null() {
+ Calendar cal = Calendar.getInstance();
+ try {
+ cal.compareTo(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Calendar#compareTo(Calendar)
+ */
+ public void test_compareToLjava_util_Calendar() {
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(1997, 12, 13, 23, 57);
+
+ Calendar anotherCal = Calendar.getInstance();
+ anotherCal.clear();
+ anotherCal.set(1997, 12, 13, 23, 57);
+ assertEquals(0, cal.compareTo(anotherCal));
+
+ anotherCal = Calendar.getInstance();
+ anotherCal.clear();
+ anotherCal.set(1997, 11, 13, 24, 57);
+ assertEquals(1, cal.compareTo(anotherCal));
+
+ anotherCal = Calendar.getInstance();
+ anotherCal.clear();
+ anotherCal.set(1997, 12, 13, 23, 58);
+ assertEquals(-1, cal.compareTo(anotherCal));
+ }
+
+ /**
+ * java.util.Calendar#clone()
+ */
+ public void test_clone() {
+ // Regression for HARMONY-475
+ Calendar cal = Calendar.getInstance();
+ cal.set(2006, 5, 6, 11, 35);
+ Calendar anotherCal = (Calendar) cal.clone();
+ // should be deep clone
+ assertNotSame("getTimeZone", cal.getTimeZone(), anotherCal
+ .getTimeZone());
+ }
+
+ /**
+ * java.util.Calendar#getTimeInMillis()
+ */
+ public void test_getTimeInMillis() {
+ Calendar cal = Calendar.getInstance();
+
+ int year = Integer.MIN_VALUE + 71;
+ cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+ cal.set(Calendar.YEAR, year + 1900);
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ cal.set(Calendar.DATE, 1);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+
+ assertEquals(6017546357372606464L, cal.getTimeInMillis());
+ }
+
+ private static final Locale[] locales = new Locale[] { Locale.getDefault(),
+ Locale.US, Locale.UK, Locale.TAIWAN, Locale.PRC, Locale.KOREA,
+ Locale.JAPAN, Locale.ITALIAN, Locale.GERMAN, Locale.ENGLISH,
+ Locale.CHINA, Locale.CANADA, Locale.FRANCE };
+
+ /**
+ * java.util.Calendar#before(Object)
+ * java.util.Calendar#after(Object)
+ */
+ public void test_before_after() {
+ Calendar early = Calendar.getInstance();
+ Calendar late = Calendar.getInstance();
+ // test by second
+ early.set(2008, 3, 20, 17, 28, 12);
+ late.set(2008, 3, 20, 17, 28, 22);
+ // test before()
+ assertTrue(early.before(late));
+ assertFalse(early.before(early));
+ assertFalse(late.before(early));
+ // test after();
+ assertTrue(late.after(early));
+ assertFalse(late.after(late));
+ assertFalse(early.after(late));
+
+ // test by minute
+ early.set(2008, 3, 20, 17, 18, 12);
+ late.set(2008, 3, 20, 17, 28, 12);
+ // test before()
+ assertTrue(early.before(late));
+ assertFalse(early.before(early));
+ assertFalse(late.before(early));
+ // test after();
+ assertTrue(late.after(early));
+ assertFalse(late.after(late));
+ assertFalse(early.after(late));
+
+ // test by hour
+ early.set(2008, 3, 20, 17, 28, 12);
+ late.set(2008, 3, 20, 27, 28, 12);
+ // test before()
+ assertTrue(early.before(late));
+ assertFalse(early.before(early));
+ assertFalse(late.before(early));
+ // test after();
+ assertTrue(late.after(early));
+ assertFalse(late.after(late));
+ assertFalse(early.after(late));
+
+ // test by day
+ early.set(2008, 3, 10, 17, 28, 12);
+ late.set(2008, 3, 20, 17, 28, 12);
+ // test before()
+ assertTrue(early.before(late));
+ assertFalse(early.before(early));
+ assertFalse(late.before(early));
+ // test after();
+ assertTrue(late.after(early));
+ assertFalse(late.after(late));
+ assertFalse(early.after(late));
+
+ // test by month
+ early.set(2008, 2, 20, 17, 28, 12);
+ late.set(2008, 3, 20, 17, 28, 12);
+ // test before()
+ assertTrue(early.before(late));
+ assertFalse(early.before(early));
+ assertFalse(late.before(early));
+ // test after();
+ assertTrue(late.after(early));
+ assertFalse(late.after(late));
+ assertFalse(early.after(late));
+
+ // test by year
+ early.set(2007, 3, 20, 17, 28, 12);
+ late.set(2008, 3, 20, 17, 28, 12);
+ // test before()
+ assertTrue(early.before(late));
+ assertFalse(early.before(early));
+ assertFalse(late.before(early));
+ // test after();
+ assertTrue(late.after(early));
+ assertFalse(late.after(late));
+ assertFalse(early.after(late));
+ }
+
+ /**
+ * java.util.Calendar#clear()
+ * java.util.Calendar#clear(int)
+ */
+ public void test_clear() {
+ Calendar calendar = Calendar.getInstance();
+
+ int count = 6;
+ int[] fields = new int[count];
+ int[] defaults = new int[count];
+
+ fields[0] = Calendar.YEAR;
+ fields[1] = Calendar.MONTH;
+ fields[2] = Calendar.DATE;
+ fields[3] = Calendar.HOUR_OF_DAY;
+ fields[4] = Calendar.MINUTE;
+ fields[5] = Calendar.SECOND;
+
+ defaults[0] = 1970;
+ defaults[1] = 0;
+ defaults[2] = 1;
+ defaults[3] = 0;
+ defaults[4] = 0;
+ defaults[5] = 0;
+
+ calendar.set(2008, 3, 20, 17, 28, 12);
+
+ // test clear(int)
+ for (int i = 0; i < fields.length; i++) {
+ int index = fields[i];
+ calendar.clear(index);
+ if (5 == index) {
+ // RI also doesn't change the value of DATE
+ assertEquals("Field " + index + " Should equal to 20.", 20,
+ calendar.get(index));
+ } else if (11 == index) {
+ // RI also doesn't change the value of HOUR
+ assertEquals("Field " + index + " Should equal to 17.", 17,
+ calendar.get(index));
+ } else {
+ // Other have been set to default values
+ assertEquals("Field " + index + " Should equal to "
+ + defaults[i] + ".", defaults[i], calendar.get(index));
+ }
+ }
+
+ // test clear()
+ calendar.set(2008, 3, 20, 17, 28, 12);
+
+ calendar.clear();
+
+ for (int i = 0; i < fields.length; i++) {
+ int index = fields[i];
+ assertEquals("Field " + index + " Should equal to "
+ + defaults[i] + ".", defaults[i], calendar.get(index));
+ }
+ }
+
+ /**
+ * java.util.Calendar#isSet(int)
+ */
+ public void test_isSet() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.clear();
+ for (int i = 0; i < Calendar.FIELD_COUNT; i++) {
+ assertFalse(calendar.isSet(i));
+ }
+ }
+
+ /**
+ * java.util.Calendar#getAvailableLocales()
+ */
+ public void test_getAvailableLocales() {
+ Locale[] locales = Calendar.getAvailableLocales();
+ boolean exist = false;
+ for (int i = 0; i < locales.length; i++) {
+ Locale l = locales[i];
+ if (Locale.US.equals(l)) {
+ exist = true;
+ break;
+ }
+ }
+ assertTrue(exist);
+ }
+
+ /**
+ * java.util.Calendar#getInstance(Locale)
+ * java.util.Calendar#getInstance(TimeZone, Locale)
+ */
+ public void test_getInstance() {
+ // test getInstance(Locale)
+ Calendar us_calendar = Calendar.getInstance(Locale.US);
+ Calendar de_calendar = Calendar.getInstance(Locale.GERMAN);
+ assertEquals(Calendar.SUNDAY, us_calendar
+ .getFirstDayOfWeek());
+ assertEquals(Calendar.MONDAY, de_calendar
+ .getFirstDayOfWeek());
+
+ // test getInstance(Locale, TimeZone)
+ Calendar gmt_calendar = Calendar.getInstance(TimeZone
+ .getTimeZone("GMT"), Locale.US);
+ assertEquals(TimeZone.getTimeZone("GMT"),
+ gmt_calendar.getTimeZone());
+ Calendar est_calendar = Calendar.getInstance(TimeZone
+ .getTimeZone("EST"), Locale.US);
+ assertEquals(TimeZone.getTimeZone("EST")
+ .getID(), est_calendar.getTimeZone().getID());
+ }
+
+ /**
+ * java.util.Calendar#internalGet(int)
+ */
+ public void test_internalGet() {
+ MockGregorianCalendar c = new MockGregorianCalendar();
+ c.clear(Calendar.YEAR);
+ assertEquals(0, c.internal_get(Calendar.YEAR));
+ }
+
+ /**
+ * java.util.Calendar#hashCode()
+ */
+ public void test_hashcode() {
+ Calendar calendar = Calendar.getInstance(Locale.JAPAN);
+ assertTrue(calendar.hashCode() == calendar.hashCode());
+ }
+
+ /**
+ * java.util.Calendar#roll(int, int)
+ */
+ public void test_roll() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(2008, 3, 20, 17, 28, 12);
+
+ // roll up
+ calendar.roll(Calendar.DATE, 5);
+ assertEquals(25, calendar.get(Calendar.DATE));
+
+ // roll down
+ calendar.roll(Calendar.DATE, -5);
+ assertEquals(20, calendar.get(Calendar.DATE));
+
+ // roll 0
+ calendar.roll(Calendar.DATE, 0);
+ assertEquals(20, calendar.get(Calendar.DATE));
+
+ // roll overweight
+ calendar.set(2008, 1, 31, 17, 28, 12);
+ calendar.roll(Calendar.MONTH, 1);
+ assertEquals(2, calendar.get(Calendar.DATE));
+
+ }
+
+ /**
+ * java.util.Calendar#toString()
+ */
+ public void test_toString() {
+ Calendar calendar = Calendar.getInstance();
+ //Should be the current time with no interrogation in the string.
+ assertTrue(calendar.toString() instanceof String);
+ assertEquals(-1, calendar.toString().indexOf("?"));
+ calendar.clear();
+ assertTrue(calendar.toString() instanceof String);
+ assertTrue(0 <= calendar.toString().indexOf("?"));
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(2008, 3, 20, 17, 28, 12);
+
+ SerializationTest.verifySelf(calendar);
+ }
+
+
+ private class MockGregorianCalendar extends GregorianCalendar {
+ public int internal_get(int field) {
+ return super.internalGet(field);
+ }
+ }
+
+ private class MockCalendar extends Calendar {
+
+ public MockCalendar() {
+ super();
+ }
+
+ @Override
+ public void add(int field, int value) {
+ }
+
+ @Override
+ protected void computeFields() {
+ }
+
+ @Override
+ protected void computeTime() {
+ }
+
+ @Override
+ public int getGreatestMinimum(int field) {
+ return 0;
+ }
+
+ @Override
+ public int getLeastMaximum(int field) {
+ return 0;
+ }
+
+ @Override
+ public int getMaximum(int field) {
+ return 0;
+ }
+
+ @Override
+ public int getMinimum(int field) {
+ return 0;
+ }
+
+ @Override
+ public void roll(int field, boolean increment) {
+ }
+ }
+
+ /**
+ * {@link java.util.Calendar#getDisplayName(int, int, Locale)}
+ * @since 1.6
+ */
+ public void test_getDisplayNameIILjava_util_Locale() {
+ Calendar cal = Calendar.getInstance();
+ for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+ for (Locale locale : locales) {
+ DateFormatSymbols symbols = new DateFormatSymbols(locale);
+ String value = null;
+ switch (field) {
+ case Calendar.AM_PM:
+ cal.set(Calendar.AM_PM, Calendar.AM);
+ value = symbols.getAmPmStrings()[0];
+ assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+ locale), value);
+ assertEquals(cal.getDisplayName(field, Calendar.LONG,
+ locale), value);
+ cal.set(Calendar.AM_PM, Calendar.PM);
+ value = symbols.getAmPmStrings()[1];
+ assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+ locale), value);
+ assertEquals(cal.getDisplayName(field, Calendar.LONG,
+ locale), value);
+ break;
+ case Calendar.ERA:
+ cal.set(Calendar.ERA, GregorianCalendar.BC);
+ value = symbols.getEras()[0];
+ assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+ locale), value);
+ assertEquals(cal.getDisplayName(field, Calendar.LONG,
+ locale), value);
+ cal.set(Calendar.ERA, GregorianCalendar.AD);
+ value = symbols.getEras()[1];
+ assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+ locale), value);
+ assertEquals(cal.getDisplayName(field, Calendar.LONG,
+ locale), value);
+ break;
+ case Calendar.MONTH:
+ cal.set(Calendar.DAY_OF_MONTH, 1);
+ for (int month = 0; month <= 11; month++) {
+ cal.set(Calendar.MONTH, month);
+ value = symbols.getShortMonths()[month];
+ assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+ locale), value);
+ value = symbols.getMonths()[month];
+ assertEquals(cal.getDisplayName(field, Calendar.LONG,
+ locale), value);
+ }
+ break;
+ case Calendar.DAY_OF_WEEK:
+ for (int day = 1; day <= 7; day++) {
+ cal.set(Calendar.DAY_OF_WEEK, day);
+ value = symbols.getShortWeekdays()[day];
+ assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+ locale), value);
+ value = symbols.getWeekdays()[day];
+ assertEquals(cal.getDisplayName(field, Calendar.LONG,
+ locale), value);
+ }
+ break;
+ default:
+ assertNull(cal
+ .getDisplayName(field, Calendar.SHORT, locale));
+ assertNull(cal.getDisplayName(field, Calendar.LONG, locale));
+ }
+ }
+ }
+
+ cal.setLenient(true);
+
+ try {
+ cal.getDisplayName(-1, Calendar.SHORT, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayName(Calendar.FIELD_COUNT, Calendar.LONG, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayName(Calendar.MONTH, -1, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayName(Calendar.MONTH, 3, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayName(-1, Calendar.SHORT, null);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayName(Calendar.MONTH, -1, null);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ // in lenient mode, following cases pass
+ cal.set(Calendar.SECOND, 999);
+ cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US);
+ // test for ALL_STYLES, it is equal to use SHORT
+ for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+ for (Locale locale : locales) {
+ String result = cal.getDisplayName(field, Calendar.ALL_STYLES,
+ locale);
+ if (field == Calendar.AM_PM || field == Calendar.ERA
+ || field == Calendar.MONTH
+ || field == Calendar.DAY_OF_WEEK) {
+ assertEquals(result, cal.getDisplayName(field,
+ Calendar.SHORT, locale));
+ } else {
+ assertNull(result);
+ }
+ }
+ }
+
+ // invalid value for an un-related field when the calendar is not
+ // lenient
+ cal.setLenient(false);
+ assertNotNull(cal.getDisplayName(Calendar.MONTH, Calendar.SHORT,
+ Locale.US));
+ cal.set(Calendar.SECOND, 999);
+ try {
+ cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayName(Calendar.MONTH, Calendar.ALL_STYLES, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Calendar#getDisplayNames(int, int, Locale)}
+ * @since 1.6
+ */
+ public void test_getDisplayNamesIILjava_util_Locale() {
+ assertEquals(0, Calendar.ALL_STYLES);
+ assertEquals(1, Calendar.SHORT);
+ assertEquals(2, Calendar.LONG);
+
+ Calendar cal = Calendar.getInstance(Locale.US);
+
+ for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+ for (Locale locale : locales) {
+ Map<String, Integer> shortResult = cal.getDisplayNames(field,
+ Calendar.SHORT, locale);
+ Map<String, Integer> longResult = cal.getDisplayNames(field,
+ Calendar.LONG, locale);
+ Map<String, Integer> allResult = cal.getDisplayNames(field,
+ Calendar.ALL_STYLES, locale);
+ DateFormatSymbols symbols = new DateFormatSymbols(locale);
+ String[] values = null;
+ switch (field) {
+ case Calendar.AM_PM:
+ case Calendar.ERA:
+ values = (field == Calendar.AM_PM) ? symbols
+ .getAmPmStrings() : symbols.getEras();
+ assertDisplayNameMap(values, shortResult, 0);
+ assertDisplayNameMap(values, longResult, 0);
+ assertDisplayNameMap(values, allResult, 0);
+ break;
+ case Calendar.MONTH:
+ values = symbols.getShortMonths();
+ assertDisplayNameMap(values, shortResult, 0);
+ values = symbols.getMonths();
+ assertDisplayNameMap(values, longResult, 0);
+ assertTrue(allResult.size() >= shortResult.size());
+ assertTrue(allResult.size() >= longResult.size());
+ assertTrue(allResult.size() <= shortResult.size()
+ + longResult.size());
+ break;
+ case Calendar.DAY_OF_WEEK:
+ values = symbols.getShortWeekdays();
+ assertDisplayNameMap(values, shortResult, 1);
+ values = symbols.getWeekdays();
+ assertDisplayNameMap(values, longResult, 1);
+ assertTrue(allResult.size() >= shortResult.size());
+ assertTrue(allResult.size() >= longResult.size());
+ assertTrue(allResult.size() <= shortResult.size()
+ + longResult.size());
+ break;
+ default:
+ assertNull(shortResult);
+ assertNull(longResult);
+ assertNull(allResult);
+ }
+ }
+ }
+
+ cal.setLenient(true);
+
+ try {
+ cal.getDisplayNames(-1, Calendar.SHORT, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayNames(Calendar.FIELD_COUNT, Calendar.LONG, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayNames(Calendar.MONTH, -1, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayNames(Calendar.MONTH, 3, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayNames(-1, Calendar.SHORT, null);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ cal.getDisplayNames(Calendar.MONTH, -1, null);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ cal.set(Calendar.SECOND, 999);
+ cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.US);
+
+ // RI fails here
+ // invalid value for an un-related field when the calendar is not
+ // lenient
+ cal.setLenient(false);
+ cal.set(Calendar.SECOND, 999);
+ try {
+ cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.US);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ private void assertDisplayNameMap(String[] values,
+ Map<String, Integer> result, int shift) {
+ List<String> trimValue = new ArrayList<String>();
+ for (String value : values) {
+ if (value.trim().length() > 0) {
+ trimValue.add(value);
+ }
+ }
+ assertEquals(trimValue.size(), result.size());
+ for (int i = 0; i < trimValue.size(); i++) {
+ assertEquals(i + shift, result.get(trimValue.get(i)).intValue());
+ }
+ }
+
+ /**
+ * {@link java.util.Calendar#getActualMaximum(int)}
+ */
+ public void test_getActualMaximum_I() {
+ Calendar c = new MockCalendar();
+ assertEquals("should be equal to 0", 0, c.getActualMaximum(0));
+ }
+
+ /**
+ * {@link java.util.Calendar#getActualMinimum(int)}
+ */
+ public void test_getActualMinimum_I() {
+ Calendar c = new MockCalendar();
+ assertEquals("should be equal to 0", 0, c.getActualMinimum(0));
+ }
+
+ protected void setUp() {
+ defaultLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ }
+
+ protected void tearDown() {
+ Locale.setDefault(defaultLocale);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/Collections2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/Collections2Test.java
new file mode 100644
index 0000000..899cd18
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/Collections2Test.java
@@ -0,0 +1,495 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+import tests.util.SerializationTester;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.RandomAccess;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+
+public class Collections2Test extends TestCase {
+
+ private static final SerializableAssert comparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable reference, Serializable test) {
+ assertSame(reference, test);
+ }
+ };
+
+ /**
+ * java.util.Collections#binarySearch(java.util.List,
+ *java.lang.Object, java.util.Comparator)
+ */
+ public void test_binarySearchLjava_util_ListLjava_lang_ObjectLjava_util_Comparator() {
+ // Regression for HARMONY-94
+ LinkedList<Integer> lst = new LinkedList<Integer>();
+ lst.add(new Integer(30));
+ Collections.sort(lst, null);
+ int index = Collections.binarySearch(lst, new Integer(2), null);
+ assertEquals(-1, index);
+ }
+
+ /**
+ * java.util.Collections#binarySearch(java.util.List,
+ *java.lang.Object)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_binarySearchLjava_util_ListLjava_lang_Object() {
+ // regression for Harmony-1367
+ List localList = new LinkedList();
+ assertEquals(-1, Collections.binarySearch(localList, new Object()));
+ localList.add(new Object());
+ try {
+ Collections.binarySearch(localList, new Integer(1));
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#rotate(java.util.List, int)
+ */
+ public void test_rotateLjava_util_ListI() {
+ // Regression for HARMONY-19 Rotate an *empty* list
+ Collections.rotate(new ArrayList<Object>(), 25);
+
+ // Regression for HARMONY-20
+ List<String> list = new ArrayList<String>();
+ list.add(0, "zero");
+ list.add(1, "one");
+ list.add(2, "two");
+ list.add(3, "three");
+ list.add(4, "four");
+
+ Collections.rotate(list, Integer.MIN_VALUE);
+ assertEquals("Rotated incorrectly at position 0, ", "three",
+ list.get(0));
+ assertEquals("Rotated incorrectly at position 1, ", "four",
+ list.get(1));
+ assertEquals("Rotated incorrectly at position 2, ", "zero",
+ list.get(2));
+ assertEquals("Rotated incorrectly at position 3, ", "one",
+ list.get(3));
+ assertEquals("Rotated incorrectly at position 4, ", "two",
+ list.get(4));
+ }
+
+ /**
+ * java.util.Collections#synchronizedCollection(java.util.Collection)
+ */
+ public void test_synchronizedCollectionLjava_util_Collection() {
+ try {
+ // Regression for HARMONY-93
+ Collections.synchronizedCollection(null);
+ fail("Assert 0: synchronizedCollection(null) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#synchronizedSortedMap(java.util.SortedMap)
+ */
+ public void test_synchronizedSortedMapLjava_util_SortedMap() {
+ try {
+ // Regression for HARMONY-93
+ Collections.synchronizedSortedMap(null);
+ fail("Assert 0: synchronizedSortedMap(null) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#synchronizedMap(java.util.Map)
+ */
+ public void test_synchronizedMapLjava_util_Map() {
+ try {
+ // Regression for HARMONY-93
+ Collections.synchronizedMap(null);
+ fail("Assert 0: synchronizedMap(map) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#synchronizedSet(java.util.Set)
+ */
+ public void test_synchronizedSetLjava_util_Set() {
+ try {
+ // Regression for HARMONY-93
+ Collections.synchronizedSet(null);
+ fail("Assert 0: synchronizedSet(set) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#synchronizedSortedSet(java.util.SortedSet)
+ */
+ public void test_synchronizedSortedSetLjava_util_SortedSet() {
+ try {
+ // Regression for HARMONY-93
+ Collections.synchronizedSortedSet(null);
+ fail("Assert 0: synchronizedSortedSet(null) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#unmodifiableCollection(java.util.Collection)
+ */
+ public void test_unmodifiableCollectionLjava_util_Collection() {
+ try {
+ // Regression for HARMONY-93
+ Collections.unmodifiableCollection(null);
+ fail("Assert 0: unmodifiableCollection(null) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#unmodifiableMap(java.util.Map)
+ */
+ public void test_unmodifiableMapLjava_util_Map() {
+ try {
+ // Regression for HARMONY-93
+ Collections.unmodifiableMap(null);
+ fail("Assert 0: unmodifiableMap(null) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#unmodifiableSet(java.util.Set)
+ */
+ public void test_unmodifiableSetLjava_util_Set() {
+ try {
+ // Regression for HARMONY-93
+ Collections.unmodifiableSet(null);
+ fail("Assert 0: unmodifiableSet(null) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#unmodifiableSortedMap(java.util.SortedMap)
+ */
+ public void test_unmodifiableSortedMapLjava_util_SortedMap() {
+ try {
+ // Regression for HARMONY-93
+ Collections.unmodifiableSortedMap(null);
+ fail("Assert 0: unmodifiableSortedMap(null) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#unmodifiableSortedSet(java.util.SortedSet)
+ */
+ public void test_unmodifiableSortedSetLjava_util_SortedSet() {
+ try {
+ // Regression for HARMONY-93
+ Collections.unmodifiableSortedSet(null);
+ fail("Assert 0: unmodifiableSortedSet(null) must throw NPE");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Collections#frequency(java.util.Collection, Object)
+ */
+ public void test_frequencyLjava_util_CollectionLint() {
+ try {
+ Collections.frequency(null, null);
+ fail("Assert 0: frequency(null,<any>) must throw NPE");
+ } catch (NullPointerException e) {
+ }
+
+ List<String> strings = Arrays.asList(new String[] { "1", "2", "3", "1", "1" });
+
+ assertEquals("Assert 1: did not find three \"1\" strings", 3,
+ Collections.frequency(strings, "1"));
+
+ assertEquals("Assert 2: did not find one \"2\" strings", 1, Collections
+ .frequency(strings, "2"));
+
+ assertEquals("Assert 3: did not find three \"3\" strings", 1,
+ Collections.frequency(strings, "3"));
+
+ assertEquals("Assert 4: matched on null when there are none", 0,
+ Collections.frequency(strings, null));
+
+ List<Object> objects = Arrays.asList(new Object[] { new Integer(1), null, null,
+ new Long(1) });
+
+ assertEquals("Assert 5: did not find one Integer(1)", 1, Collections
+ .frequency(objects, new Integer(1)));
+
+ assertEquals("Assert 6: did not find one Long(1)", 1, Collections
+ .frequency(objects, new Long(1)));
+
+ assertEquals("Assert 7: did not find two null references", 2,
+ Collections.frequency(objects, null));
+ }
+
+ /**
+ * java.util.Collections#reverseOrder()
+ */
+ public void test_reverseOrder() {
+ Comparator<String> roc = Collections.reverseOrder();
+ assertNotNull("Assert 0: comparator must not be null", roc);
+
+ assertTrue("Assert 1: comparator must implement Serializable",
+ roc instanceof Serializable);
+
+ String[] fixtureDesc = new String[] { "2", "1", "0" };
+ String[] numbers = new String[] { "0", "1", "2" };
+ Arrays.sort(numbers, roc);
+ assertTrue("Assert 2: the arrays are not equal, the sort failed",
+ Arrays.equals(fixtureDesc, numbers));
+ }
+
+ /**
+ * java.util.Collections#reverseOrder(java.util.Comparator)
+ */
+ public void test_reverseOrderLjava_util_Comparator() {
+ Comparator<String> roc = Collections
+ .reverseOrder(String.CASE_INSENSITIVE_ORDER);
+ assertNotNull("Assert 0: comparator must not be null", roc);
+
+ assertTrue("Assert 1: comparator must implement Serializable",
+ roc instanceof Serializable);
+
+ String[] fixtureDesc = new String[] { "2", "1", "0" };
+ String[] numbers = new String[] { "0", "1", "2" };
+ Arrays.sort(numbers, roc);
+ assertTrue("Assert 2: the arrays are not equal, the sort failed",
+ Arrays.equals(fixtureDesc, numbers));
+
+ roc = Collections.reverseOrder(null);
+ assertNotNull("Assert 3: comparator must not be null", roc);
+
+ assertTrue("Assert 4: comparator must implement Serializable",
+ roc instanceof Serializable);
+
+ numbers = new String[] { "0", "1", "2" };
+ Arrays.sort(numbers, roc);
+ assertTrue("Assert 5: the arrays are not equal, the sort failed",
+ Arrays.equals(fixtureDesc, numbers));
+ }
+
+ public void test_AddAll() {
+ List<Object> l = new ArrayList<Object>();
+ assertFalse(Collections.addAll(l, new Object[] { }));
+ assertTrue(l.isEmpty());
+ assertTrue(Collections.addAll(l, new Object[] { new Integer(1),
+ new Integer(2), new Integer(3) }));
+ assertFalse(l.isEmpty());
+ assertTrue(l.equals(Arrays.asList(new Object[] { new Integer(1),
+ new Integer(2), new Integer(3) })));
+ }
+
+ public void test_Disjoint() {
+ Object[] arr1 = new Object[10];
+ for (int i = 0; i < arr1.length; i++) {
+ arr1[i] = new Integer(i);
+ }
+ Object[] arr2 = new Object[20];
+ for (int i = 0; i < arr2.length; i++) {
+ arr2[i] = new Integer(100 + i);
+ }
+ Collection<Object> c1 = new ArrayList<Object>();
+ Collection<Object> c2 = new ArrayList<Object>();
+ Collections.addAll(c1, arr1);
+ Collections.addAll(c2, arr2);
+ assertTrue(Collections.disjoint(c1, c2));
+ c1.add(arr2[10]);
+ assertFalse(Collections.disjoint(c1, c2));
+
+ c1 = new LinkedList<Object>();
+ c2 = new LinkedList<Object>();
+ Collections.addAll(c1, arr1);
+ Collections.addAll(c2, arr2);
+ assertTrue(Collections.disjoint(c1, c2));
+ c1.add(arr2[10]);
+ assertFalse(Collections.disjoint(c1, c2));
+
+ c1 = new TreeSet<Object>();
+ c2 = new TreeSet<Object>();
+ Collections.addAll(c1, arr1);
+ Collections.addAll(c2, arr2);
+ assertTrue(Collections.disjoint(c1, c2));
+ c1.add(arr2[10]);
+ assertFalse(Collections.disjoint(c1, c2));
+
+ c1 = new HashSet<Object>();
+ c2 = new HashSet<Object>();
+ Collections.addAll(c1, arr1);
+ Collections.addAll(c2, arr2);
+ assertTrue(Collections.disjoint(c1, c2));
+ c1.add(arr2[10]);
+ assertFalse(Collections.disjoint(c1, c2));
+
+ c1 = new LinkedList<Object>();
+ c2 = new TreeSet<Object>();
+ Collections.addAll(c1, arr1);
+ Collections.addAll(c2, arr2);
+ assertTrue(Collections.disjoint(c1, c2));
+ c1.add(arr2[10]);
+ assertFalse(Collections.disjoint(c1, c2));
+
+ c1 = new Vector<Object>();
+ c2 = new HashSet<Object>();
+ Collections.addAll(c1, arr1);
+ Collections.addAll(c2, arr2);
+ assertTrue(Collections.disjoint(c1, c2));
+ c1.add(arr2[10]);
+ assertFalse(Collections.disjoint(c1, c2));
+
+ }
+
+ /**
+ * java.util.Collections.EmptyList#readResolve()
+ */
+ public void test_EmptyList_readResolve() throws Exception {
+ SerializationTest.verifySelf(Collections.EMPTY_LIST, comparator);
+ }
+
+ /**
+ * java.util.Collections.EmptyMap#readResolve()
+ */
+ public void test_EmptyMap_readResolve() throws Exception {
+ SerializationTest.verifySelf(Collections.EMPTY_MAP, comparator);
+ }
+
+ /**
+ * java.util.Collections.EmptySet#readResolve()
+ */
+ public void test_EmptySet_readResolve() throws Exception {
+ SerializationTest.verifySelf(Collections.EMPTY_SET, comparator);
+ }
+
+ public void test_checkedCollectionSerializationCompatability() throws Exception {
+ Collection<String> c = Collections.emptySet();
+ c = Collections.checkedCollection(c, String.class);
+ SerializationTester.assertCompabilityEquals(c, "serialization/org/apache/harmony/tests/java/util/Collections_CheckedCollection.golden.ser");
+ }
+
+ public void test_checkedListRandomAccessSerializationCompatability() throws Exception {
+ List<String> c = new ArrayList<String>();
+ assertTrue(c instanceof RandomAccess);
+ c = Collections.checkedList(c, String.class);
+ SerializationTester.assertCompabilityEquals(c, "serialization/org/apache/harmony/tests/java/util/Collections_CheckedListRandomAccess.golden.ser");
+ }
+
+ public void test_checkedListSerializationCompatability() throws Exception {
+ List<String> c = new LinkedList<String>();
+ assertFalse(c instanceof RandomAccess);
+ c = Collections.checkedList(c, String.class);
+ SerializationTester.assertCompabilityEquals(c, "serialization/org/apache/harmony/tests/java/util/Collections_CheckedList.golden.ser");
+ }
+
+ public void test_checkedSetSerializationCompatability() throws Exception {
+ Set<String> c = new HashSet<String>();
+ assertFalse(c instanceof SortedSet);
+ c = Collections.checkedSet(c, String.class);
+ SerializationTester.assertCompabilityEquals(c, "serialization/org/apache/harmony/tests/java/util/Collections_CheckedSet.golden.ser");
+ }
+
+ public void test_checkedMapSerializationCompatability() throws Exception {
+ Map<String, String> c = new HashMap<String, String>();
+ assertFalse(c instanceof SortedMap);
+ c = Collections.checkedMap(c, String.class, String.class);
+ SerializationTester.assertCompabilityEquals(c, "serialization/org/apache/harmony/tests/java/util/Collections_CheckedMap.golden.ser");
+ }
+
+ public void test_checkedSortedSetSerializationCompatability() throws Exception {
+ SortedSet<String> c = new TreeSet<String>();
+ c = Collections.checkedSortedSet(c, String.class);
+ SerializationTester.assertCompabilityEquals(c, "serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedSet.golden.ser");
+ }
+
+ public void test_checkedSortedMapSerializationCompatability() throws Exception {
+ SortedMap<String, String> c = new TreeMap<String, String>();
+ c = Collections.checkedSortedMap(c, String.class, String.class);
+ SerializationTester.assertCompabilityEquals(c, "serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedMap.golden.ser");
+ }
+
+ public void test_emptyList() {
+ List<Object> emptyList = Collections.emptyList();
+ assertEquals(0, emptyList.size());
+ assertTrue(emptyList instanceof RandomAccess);
+ }
+
+ // Regression test for http://issues.apache.org/jira/browse/HARMONY-6122
+ public void test_Collections_swap_IndexOutOfBoundsException() {
+ try {
+ Collections.swap(new ArrayList<Object>(), -1, 3);
+ fail("IOOBE expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ List<Object> list = new ArrayList<Object>();
+ list.add("0");
+ try {
+ Collections.swap(list, 0, -1);
+ fail("IOOBE expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Collections.swap(list, 0, 3);
+ fail("IOOBE expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ Collections.swap(new ArrayList<Object>(), 3, 3);
+ fail("IOOBE expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CollectionsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CollectionsTest.java
new file mode 100644
index 0000000..a1629d2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CollectionsTest.java
@@ -0,0 +1,2385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+import tests.support.Support_CollectionTest;
+import tests.support.Support_ListTest;
+import tests.support.Support_SetTest;
+import tests.support.Support_UnmodifiableCollectionTest;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Random;
+import java.util.RandomAccess;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+public class CollectionsTest extends junit.framework.TestCase {
+
+ private LinkedList ll;
+
+ private LinkedList myll;
+
+ private LinkedList reversedLinkedList;
+
+ private LinkedList myReversedLinkedList;
+
+ private Set s;
+
+ private Set mys;
+
+ private HashMap hm;
+
+ private Integer[] objArray;
+
+ private Object[] myobjArray;
+
+ public static class ReversedMyIntComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ return -((MyInt) o1).compareTo((MyInt) o2);
+ }
+
+ public int equals(Object o1, Object o2) {
+ return ((MyInt) o1).compareTo((MyInt) o2);
+ }
+ }
+
+ public static class SynchCollectionChecker implements Runnable {
+ Collection col;
+
+ int colSize;
+
+ int totalToRun;
+
+ boolean offset;
+
+ volatile int numberOfChecks = 0;
+
+ boolean result = true;
+
+ ArrayList normalCountingList;
+
+ ArrayList offsetCountingList;
+
+ public void run() {
+ // ensure the list either contains the numbers from 0 to size-1 or
+ // the numbers from size to 2*size -1
+ while (numberOfChecks < totalToRun) {
+ synchronized (col) {
+ if (!(col.isEmpty() || col.containsAll(normalCountingList) || col
+ .containsAll(offsetCountingList)))
+ result = false;
+ col.clear();
+ }
+ if (offset)
+ col.addAll(offsetCountingList);
+ else
+ col.addAll(normalCountingList);
+ numberOfChecks++;
+ }
+ }
+
+ public SynchCollectionChecker(Collection c, boolean offset,
+ int totalChecks) {
+ // The collection to test, whether to offset the filler values by
+ // size or not, and the min number of iterations to run
+ totalToRun = totalChecks;
+ col = c;
+ colSize = c.size();
+ normalCountingList = new ArrayList(colSize);
+ offsetCountingList = new ArrayList(colSize);
+ for (int i = 0; i < colSize; i++)
+ normalCountingList.add(new Integer(i));
+ for (int i = 0; i < colSize; i++)
+ offsetCountingList.add(new Integer(i + colSize));
+ col.clear();
+ if (offset)
+ col.addAll(offsetCountingList);
+ else
+ col.addAll(normalCountingList);
+ }
+
+ public boolean offset() {
+ // answer true iff the list is filled with a counting sequence
+ // starting at the value size to 2*size - 1
+ // else the list with be filled starting at 0 to size - 1
+ return offset;
+ }
+
+ public boolean getResult() {
+ // answer true iff no corruption has been found in the collection
+ return result;
+ }
+
+ public int getNumberOfChecks() {
+ // answer the number of checks that have been performed on the list
+ return numberOfChecks;
+ }
+ }
+
+ public static class SynchMapChecker implements Runnable {
+ Map map;
+
+ int mapSize;
+
+ int totalToRun;
+
+ boolean offset;
+
+ volatile int numberOfChecks = 0;
+
+ boolean result = true;
+
+ Map normalCountingMap;
+
+ Map offsetCountingMap;
+
+ public void run() {
+ Object firstNormalValue = normalCountingMap.get(new Integer(0));
+ Object lastNormalValue = normalCountingMap.get(new Integer(
+ mapSize - 1));
+ Object firstOffsetValue = offsetCountingMap
+ .get(new Integer(mapSize));
+ Object lastOffsetValue = offsetCountingMap.get(new Integer(
+ 2 * mapSize - 1));
+ // ensure the list either contains the numbers from 0 to size-1 or
+ // the numbers from size to 2*size -1
+ while (numberOfChecks < totalToRun) {
+ synchronized (map) {
+ if (!(map.isEmpty()
+ || (map.containsValue(firstNormalValue) && map
+ .containsValue(lastNormalValue)) || (map
+ .containsValue(firstOffsetValue) && map
+ .containsValue(lastOffsetValue))))
+ result = false;
+ map.clear();
+ }
+ if (offset)
+ map.putAll(offsetCountingMap);
+ else
+ map.putAll(normalCountingMap);
+ numberOfChecks++;
+ }
+ }
+
+ public SynchMapChecker(Map m, boolean offset, int totalChecks) {
+ // The collection to test, whether to offset the filler values by
+ // size or not, and the min number of iterations to run
+ Integer myInt;
+ totalToRun = totalChecks;
+ map = m;
+ mapSize = m.size();
+ normalCountingMap = new HashMap(mapSize);
+ offsetCountingMap = new HashMap(mapSize);
+ for (int i = 0; i < mapSize; i++) {
+ myInt = new Integer(i);
+ normalCountingMap.put(myInt, myInt);
+ }
+ for (int i = 0; i < mapSize; i++) {
+ myInt = new Integer(i + mapSize);
+ offsetCountingMap.put(myInt, myInt);
+ }
+ map.clear();
+ if (offset)
+ map.putAll(offsetCountingMap);
+ else
+ map.putAll(normalCountingMap);
+ }
+
+ public boolean offset() {
+ // answer true iff the list is filled with a counting sequence
+ // starting at the value size to 2*size - 1
+ // else the list with be filled starting at 0 to size - 1
+ return offset;
+ }
+
+ public boolean getResult() {
+ // answer true iff no corruption has been found in the collection
+ return result;
+ }
+
+ public int getNumberOfChecks() {
+ // answer the number of checks that have been performed on the list
+ return numberOfChecks;
+ }
+ }
+
+ static class MyInt {
+ int data;
+
+ public MyInt(int value) {
+ data = value;
+ }
+
+ public int compareTo(MyInt object) {
+ return data > object.data ? 1 : (data < object.data ? -1 : 0);
+ }
+ }
+
+ public void test_binarySearchLjava_util_ListLjava_lang_Object() {
+ // Test for method int
+ // java.util.Collections.binarySearch(java.util.List, java.lang.Object)
+ // assumes ll is sorted and has no duplicate keys
+ final int llSize = ll.size();
+ // Ensure a NPE is thrown if the list is NULL
+ try {
+ Collections.binarySearch(null, new Object());
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ for (int i = 0; i < llSize; i++) {
+ assertEquals("Returned incorrect binary search item position", ll
+ .get(i), ll.get(Collections.binarySearch(ll, ll
+ .get(i))));
+ }
+ }
+
+ public void test_binarySearchLjava_util_ListLjava_lang_ObjectLjava_util_Comparator() {
+ // Test for method int
+ // java.util.Collections.binarySearch(java.util.List, java.lang.Object,
+ // java.util.Comparator)
+ // assumes reversedLinkedList is sorted in reversed order and has no
+ // duplicate keys
+ final int rSize = myReversedLinkedList.size();
+ ReversedMyIntComparator comp = new ReversedMyIntComparator();
+ // Ensure a NPE is thrown if the list is NULL
+ try {
+ Collections.binarySearch(null, new Object(), comp);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ for (int i = 0; i < rSize; i++) {
+ assertEquals(
+ "Returned incorrect binary search item position using custom comparator",
+ myReversedLinkedList.get(i), myReversedLinkedList
+ .get(Collections.binarySearch(myReversedLinkedList,
+ myReversedLinkedList.get(i), comp)));
+ }
+ }
+
+ class Mock_ArrayList extends ArrayList {
+ @Override
+ public
+ Object set (int index, Object o){
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public void test_copyLjava_util_ListLjava_util_List() {
+ // Test for method void java.util.Collections.copy(java.util.List,
+ // java.util.List)
+ // Ensure a NPE is thrown if the list is NULL
+ try {
+ Collections.copy(null, ll);
+ fail("Expected NullPointerException for null list first parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ try {
+ Collections.copy(ll, null);
+ fail("Expected NullPointerException for null list second parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ final int llSize = ll.size();
+ ll.set(25, null);
+ ArrayList al = new ArrayList();
+ Integer extraElement = new Integer(1);
+ Integer extraElement2 = new Integer(2);
+ al.addAll(myReversedLinkedList);
+ al.add(extraElement);
+ al.add(extraElement2);
+ Collections.copy(al, ll);
+ for (int i = 0; i < llSize; i++) {
+ assertEquals("Elements do not match after copying collection", ll
+ .get(i), al.get(i));
+ }
+ assertTrue("Elements after copied elements affected by copy",
+ extraElement == al.get(llSize)
+ && extraElement2 == al.get(llSize + 1));
+
+ ArrayList ar1 = new ArrayList();
+ ArrayList ar2 = new ArrayList();
+
+ int i;
+
+ for(i = 0; i < 5; i ++) {
+ ar2.add(new Integer(i));
+ }
+
+ for(i = 0; i < 10; i ++) {
+ ar1.add(new Integer(i));
+ }
+
+ try {
+ Collections.copy(ar2, ar1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ Mock_ArrayList mal1 = new Mock_ArrayList();
+ Mock_ArrayList mal2 = new Mock_ArrayList();
+
+ for(i = 0; i < 10; i ++) {
+ mal1.add(new Integer(i));
+ mal2.add(new Integer(10 - i));
+ }
+
+ try {
+ Collections.copy(mal1, mal2);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void test_copy_check_index() {
+ ArrayList a1 = new ArrayList();
+ a1.add("one");
+ a1.add("two");
+
+ ArrayList a2 = new ArrayList();
+ a2.add("aa");
+
+ try {
+ Collections.copy(a2, a1);
+ fail("Expected IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ //Expected
+ }
+
+ assertEquals("aa", a2.get(0));
+ }
+
+ public void test_enumerationLjava_util_Collection() {
+ // Test for method java.util.Enumeration
+ // java.util.Collections.enumeration(java.util.Collection)
+ TreeSet ts = new TreeSet();
+ ts.addAll(s);
+ Enumeration e = Collections.enumeration(ts);
+ int count = 0;
+ while (e.hasMoreElements()) {
+ assertEquals("Returned incorrect enumeration", e.nextElement(),
+ objArray[count++]);
+ }
+ assertEquals("Enumeration missing elements: " + count, objArray.length,
+ count);
+ }
+
+ public void test_fillLjava_util_ListLjava_lang_Object() {
+ // Test for method void java.util.Collections.fill(java.util.List,
+ // java.lang.Object)
+ try {
+ Collections.fill(null, new Object());
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ final int size = ll.size();
+ Collections.fill(ll, "k");
+ assertEquals("Fill modified list size", size, ll.size());
+ Iterator i = ll.iterator();
+ while (i.hasNext())
+ assertEquals("Failed to fill elements", "k", i.next());
+
+ Collections.fill(ll, null);
+ assertEquals("Fill with nulls modified list size", size, ll.size());
+ i = ll.iterator();
+ while (i.hasNext())
+ assertNull("Failed to fill with nulls", i.next());
+
+ Mock_ArrayList mal = new Mock_ArrayList();
+
+ mal.add("one");
+ mal.add("two");
+
+ try {
+ Collections.fill(mal, "value");
+ fail("UnsupportedOperationException ecpected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void test_maxLjava_util_Collection() {
+ // Test for method java.lang.Object
+ // java.util.Collections.max(java.util.Collection)
+ // assumes s, objArray are sorted
+ assertEquals("Returned incorrect max element", Collections.max(s),
+ objArray[objArray.length - 1]);
+
+ ArrayList al = new ArrayList();
+
+ try {
+ Collections.max(al);
+ fail("NoSuchElementException expected");
+ } catch (NoSuchElementException e) {
+ //expected
+ }
+
+ al.add("String");
+ al.add(new Integer(1));
+ al.add(new Double(3.14));
+
+ try {
+ Collections.max(al);
+ fail("ClassCastException expected");
+ } catch (ClassCastException e) {
+ //expected
+ }
+ }
+
+ public void test_maxLjava_util_CollectionLjava_util_Comparator() {
+ // Test for method java.lang.Object
+ // java.util.Collections.max(java.util.Collection, java.util.Comparator)
+ // assumes s, objArray are sorted
+
+ // With this custom (backwards) comparator the 'max' element should be
+ // the smallest in the list
+ assertEquals("Returned incorrect max element using custom comparator",
+ Collections.max(mys, new ReversedMyIntComparator()),
+ myobjArray[0]);
+ }
+
+ public void test_minLjava_util_Collection() {
+ // Test for method java.lang.Object
+ // java.util.Collections.min(java.util.Collection)
+ // assumes s, objArray are sorted
+ assertEquals("Returned incorrect min element", Collections.min(s),
+ objArray[0]);
+ }
+
+ public void test_minLjava_util_CollectionLjava_util_Comparator() {
+ // Test for method java.lang.Object
+ // java.util.Collections.min(java.util.Collection, java.util.Comparator)
+ // assumes s, objArray are sorted
+
+ // With this custom (backwards) comparator the 'min' element should be
+ // the largest in the list
+ assertEquals("Returned incorrect min element using custom comparator",
+ Collections.min(mys, new ReversedMyIntComparator()),
+ myobjArray[objArray.length - 1]);
+ }
+
+ public void test_nCopiesILjava_lang_Object() {
+ // Test for method java.util.List java.util.Collections.nCopies(int,
+ // java.lang.Object)
+ Object o = new Object();
+ List l = Collections.nCopies(100, o);
+ Iterator iterator = l.iterator();
+ Object first = iterator.next();
+ assertEquals("Returned list consists of copies not refs", first, o);
+ assertEquals("Returned list of incorrect size", 100, l.size());
+ assertTrue("Contains", l.contains(o));
+ assertFalse("Contains null", l.contains(null));
+ assertFalse("null nCopies contains", Collections.nCopies(2, null)
+ .contains(o));
+ assertTrue("null nCopies contains null", Collections.nCopies(2, null)
+ .contains(null));
+ l = Collections.nCopies(20, null);
+ iterator = l.iterator();
+ for (int i = 0; iterator.hasNext(); i++) {
+ assertTrue("List is too large", i < 20);
+ assertNull("Element should be null: " + i, iterator.next());
+ }
+ try {
+ l.add(o);
+ fail("Returned list is not immutable");
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+ try {
+ Collections.nCopies(-2, new HashSet());
+ fail("nCopies with negative arg didn't throw IAE");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void test_reverseLjava_util_List() {
+ // Test for method void java.util.Collections.reverse(java.util.List)
+ try {
+ Collections.reverse(null);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ Collections.reverse(ll);
+ Iterator i = ll.iterator();
+ int count = objArray.length - 1;
+ while (i.hasNext()) {
+ assertEquals("Failed to reverse collection", objArray[count], i
+ .next());
+ --count;
+ }
+ ArrayList myList = new ArrayList();
+ myList.add(null);
+ myList.add(new Integer(20));
+ Collections.reverse(myList);
+ assertEquals("Did not reverse correctly--first element is: "
+ + myList.get(0), new Integer(20), myList.get(0));
+ assertNull("Did not reverse correctly--second element is: "
+ + myList.get(1), myList.get(1));
+ }
+
+ public void test_reverseOrder() {
+ // Test for method java.util.Comparator
+ // java.util.Collections.reverseOrder()
+ // assumes no duplicates in ll
+ Comparator comp = Collections.reverseOrder();
+ LinkedList list2 = new LinkedList(ll);
+ Collections.sort(list2, comp);
+ final int llSize = ll.size();
+ for (int i = 0; i < llSize; i++)
+ assertEquals("New comparator does not reverse sorting order", list2
+ .get(llSize - i - 1), ll.get(i));
+ }
+
+ public void test_shuffleLjava_util_List() {
+ // Test for method void java.util.Collections.shuffle(java.util.List)
+ // Assumes ll is sorted and has no duplicate keys and is large ( > 20
+ // elements)
+
+ // test shuffling a Sequential Access List
+ try {
+ Collections.shuffle(null);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ ArrayList al = new ArrayList();
+ al.addAll(ll);
+ testShuffle(al, "Sequential Access", false);
+
+ // test shuffling a Random Access List
+ LinkedList ll2 = new LinkedList();
+ ll2.addAll(ll);
+ testShuffle(ll2, "Random Access", false);
+ }
+
+ public void testShuffleRandomAccessWithSeededRandom() {
+ List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F", "G");
+ Collections.shuffle(list, new Random(0));
+ assertEquals(Arrays.asList("B", "A", "D", "C", "G", "E", "F"), list);
+ }
+
+ public void testShuffleWithSeededRandom() {
+ List<String> list = new LinkedList<String>(Arrays.asList(
+ "A", "B", "C", "D", "E", "F", "G"));
+ Collections.shuffle(list, new Random(0));
+ assertEquals(Arrays.asList("B", "A", "D", "C", "G", "E", "F"), list);
+ }
+
+ private void testShuffle(List list, String type, boolean random) {
+ boolean sorted = true;
+ boolean allMatch = true;
+ int index = 0;
+ final int size = list.size();
+
+ if (random)
+ Collections.shuffle(list);
+ else
+ Collections.shuffle(list, new Random(200));
+
+ for (int i = 0; i < size - 1; i++) {
+ if (((Integer) list.get(i)).compareTo((Integer) list.get(i + 1)) > 0) {
+ sorted = false;
+ }
+ }
+ assertFalse("Shuffling sorted " + type
+ + " list resulted in sorted list (should be unlikely)", sorted);
+ for (int i = 0; i < 20; i++) {
+ index = 30031 * i % (size + 1); // 30031 is a large prime
+ if (list.get(index) != ll.get(index))
+ allMatch = false;
+ }
+ assertFalse("Too many element positions match in shuffled " + type
+ + " list", allMatch);
+ }
+
+ public void test_shuffleLjava_util_ListLjava_util_Random() {
+ // Test for method void java.util.Collections.shuffle(java.util.List,
+ // java.util.Random)
+ // Assumes ll is sorted and has no duplicate keys and is large ( > 20
+ // elements)
+
+ // test shuffling a Sequential Access List
+ try {
+ Collections.shuffle(null, new Random(200));
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Excepted
+ }
+ ArrayList al = new ArrayList();
+ al.addAll(ll);
+ testShuffle(al, "Sequential Access", true);
+
+ // test shuffling a Random Access List
+ LinkedList ll2 = new LinkedList();
+ ll2.addAll(ll);
+ testShuffle(ll2, "Random Access", true);
+
+ List l = new ArrayList();
+ l.add('a');
+ l.add('b');
+ l.add('c');
+ Collections.shuffle(l, new Random(12345678921L));
+ assertEquals("acb", l.get(0).toString() + l.get(1) + l.get(2));
+ }
+
+ public void test_singletonLjava_lang_Object() {
+ // Test for method java.util.Set
+ // java.util.Collections.singleton(java.lang.Object)
+ Object o = new Object();
+ Set single = Collections.singleton(o);
+ assertEquals("Wrong size", 1, single.size());
+ assertTrue("Contains", single.contains(o));
+ assertFalse("Contains null", single.contains(null));
+ assertFalse("null nCopies contains", Collections.singleton(null)
+ .contains(o));
+ assertTrue("null nCopies contains null", Collections.singleton(null)
+ .contains(null));
+ try {
+ single.add("l");
+ fail("Allowed modification of singleton");
+ } catch (UnsupportedOperationException e) {
+ // Excepted
+ }
+ }
+
+ public void test_sortLjava_util_List() {
+ // Test for method void java.util.Collections.sort(java.util.List)
+ // assumes no duplicate keys in ll
+ final int llSize = ll.size();
+ final int rllSize = reversedLinkedList.size();
+ try {
+ Collections.sort((List) null);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ Collections.shuffle(ll);
+ Collections.sort(ll);
+ Collections.sort(reversedLinkedList);
+ for (int i = 0; i < llSize - 1; i++) {
+ assertTrue(
+ "Sorting shuffled list resulted in unsorted list",
+ ((Integer) ll.get(i)).compareTo((Integer) ll.get(i + 1)) < 0);
+ }
+
+ for (int i = 0; i < rllSize - 1; i++) {
+ assertTrue("Sorting reversed list resulted in unsorted list",
+ ((Integer) reversedLinkedList.get(i))
+ .compareTo((Integer) reversedLinkedList.get(i + 1)) < 0);
+ }
+ }
+
+ public void test_sortLjava_util_ListLjava_util_Comparator() {
+ // Test for method void java.util.Collections.sort(java.util.List,
+ // java.util.Comparator)
+ Comparator comp = new ReversedMyIntComparator();
+ try {
+ Collections.sort(null, comp);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ Collections.shuffle(myll);
+ Collections.sort(myll, comp);
+ final int llSize = myll.size();
+
+ for (int i = 0; i < llSize - 1; i++) {
+ assertTrue(
+ "Sorting shuffled list with custom comparator resulted in unsorted list",
+ ((MyInt) myll.get(i)).compareTo((MyInt) myll
+ .get(i + 1)) >= 0);
+ }
+
+ ArrayList al = new ArrayList();
+
+ al.add("String");
+ al.add(new Integer(1));
+ al.add(new Double(3.14));
+
+ try {
+ Collections.sort(al, comp);
+ fail("ClassCastException expected");
+ } catch (ClassCastException e) {
+ //expected
+ }
+
+ Mock_ArrayList mal = new Mock_ArrayList();
+
+ mal.add(new MyInt(1));
+ mal.add(new MyInt(2));
+
+ try {
+ Collections.sort(mal, comp);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void test_swapLjava_util_ListII() {
+ // Test for method swap(java.util.List, int, int)
+
+ LinkedList smallList = new LinkedList();
+ for (int i = 0; i < 10; i++) {
+ smallList.add(objArray[i]);
+ }
+
+ // test exception cases
+ try {
+ Collections.swap(smallList, -1, 6);
+ fail("Expected IndexOutOfBoundsException for -1");
+ } catch (IndexOutOfBoundsException e) {
+ //Expected
+ }
+
+ try {
+ Collections.swap(smallList, 6, -1);
+ fail("Expected IndexOutOfBoundsException for -1");
+ } catch (IndexOutOfBoundsException e) {
+ //Expected
+ }
+
+ try {
+ Collections.swap(smallList, 6, 11);
+ fail("Expected IndexOutOfBoundsException for 11");
+ } catch (IndexOutOfBoundsException e) {
+ //Expected
+ }
+
+ try {
+ Collections.swap(smallList, 11, 6);
+ fail("Expected IndexOutOfBoundsException for 11");
+ } catch (IndexOutOfBoundsException e) {
+ //Expected
+ }
+
+ // Ensure a NPE is thrown if the list is NULL
+ try {
+ Collections.swap(null, 1, 1);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+
+ // test with valid parameters
+ Collections.swap(smallList, 4, 7);
+ assertEquals("Didn't Swap the element at position 4 ", new Integer(7),
+ smallList.get(4));
+ assertEquals("Didn't Swap the element at position 7 ", new Integer(4),
+ smallList.get(7));
+
+ // make sure other elements didn't get swapped by mistake
+ for (int i = 0; i < 10; i++) {
+ if (i != 4 && i != 7)
+ assertEquals("shouldn't have swapped the element at position "
+ + i, new Integer(i), smallList.get(i));
+ }
+ }
+
+ public void test_replaceAllLjava_util_ListLjava_lang_ObjectLjava_lang_Object() {
+ // Test for method replaceAll(java.util.List, java.lang.Object,
+ // java.lang.Object)
+
+ String string1 = "A-B-C-D-E-S-JF-SUB-G-H-I-J-SUBL-K-L-LIST-M-N--S-S-O-SUBLIS-P-Q-R-SUBLIST-S-T-U-V-W-X-Y-Z";
+ char[] chars = string1.toCharArray();
+ List list = new ArrayList();
+ for (int i = 0; i < chars.length; i++) {
+ list.add(new Character(chars[i]));
+ }
+
+ try {
+ Collections.replaceAll(null, new Object(), new Object());
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+
+ // test replace for an element that is not in the list
+ boolean result = Collections.replaceAll(list, new Character('1'),
+ new Character('Z'));
+ assertFalse("Test1: Collections.replaceAll() returned wrong result",
+ result);
+ assertEquals("Test2 : ReplaceAll modified the list incorrectly",
+ string1, getString(list));
+
+ // test replace for an element that is in the list
+ result = Collections.replaceAll(list, new Character('S'),
+ new Character('K'));
+ assertTrue("Test3: Collections.replaceAll() returned wrong result",
+ result);
+ assertEquals("Test4: ReplaceAll modified the list incorrectly",
+ (string1 = string1.replace('S', 'K')), getString(list));
+
+ // test replace for the last element in the list
+ result = Collections.replaceAll(list, new Character('Z'),
+ new Character('N'));
+ assertTrue("Test5: Collections.replaceAll() returned wrong result",
+ result);
+ assertEquals("Test6: ReplaceAll modified the list incorrectly",
+ (string1 = string1.replace('Z', 'N')), getString(list));
+
+ // test replace for the first element in the list
+ result = Collections.replaceAll(list, new Character('A'),
+ new Character('B'));
+ assertTrue("Test7: Collections.replaceAll() returned wrong result",
+ result);
+ assertEquals("Test8: ReplaceAll modified the list incorrectly",
+ (string1 = string1.replace('A', 'B')), getString(list));
+
+ // test replacing elements with null
+ LinkedList smallList = new LinkedList();
+ for (int i = 0; i < 10; i++) {
+ smallList.add(objArray[i]);
+ }
+ smallList.set(4, new Integer(5));
+ result = Collections.replaceAll(smallList, new Integer(5), null);
+ assertTrue("Test9: Collections.replaceAll() returned wrong result",
+ result);
+ for (int i = 0; i < smallList.size(); i++) {
+ if (i == 4 || i == 5)
+ assertSame("Test9: ReplaceAll didn't replace element at " + i,
+ null, smallList.get(i));
+ else
+ assertEquals(
+ "Test9: ReplaceAll shouldn't have replaced element at "
+ + i, new Integer(i), smallList.get(i));
+ }
+
+ // test replacing null elements with another value
+ result = Collections.replaceAll(smallList, null, new Integer(99));
+ assertTrue("Test10: Collections.replaceAll() returned wrong result",
+ result);
+
+ for (int i = 0; i < smallList.size(); i++) {
+ if (i == 4 || i == 5)
+ assertEquals("Test10: ReplaceAll didn't replace element at "
+ + i, new Integer(99), smallList.get(i));
+ else
+ assertEquals(
+ "Test10: ReplaceAll shouldn't have replaced element at "
+ + i, new Integer(i), smallList.get(i));
+ }
+
+ Mock_ArrayList mal = new Mock_ArrayList();
+
+ mal.add("First");
+ mal.add("Second");
+
+ try {
+ Collections.replaceAll(mal, "Second", null);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void test_rotateLjava_util_ListI() {
+ // Test for method rotate(java.util.List, int)
+
+ try {
+ Collections.rotate(null, 0);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+
+ // Test rotating a Sequential Access List
+ LinkedList list1 = new LinkedList();
+ for (int i = 0; i < 10; i++) {
+ list1.add(objArray[i]);
+ }
+ testRotate(list1, "Sequential Access");
+
+ // Test rotating a Random Access List
+ ArrayList list2 = new ArrayList();
+ for (int i = 0; i < 10; i++) {
+ list2.add(objArray[i]);
+ }
+ testRotate(list2, "Random Access");
+ }
+
+ private void testRotate(List list, String type) {
+ // rotate with positive distance
+ Collections.rotate(list, 7);
+ assertEquals("Test1: rotate modified the " + type
+ + " list incorrectly,", "3456789012", getString(list));
+
+ // rotate with negative distance
+ Collections.rotate(list, -2);
+ assertEquals("Test2: rotate modified the " + type
+ + " list incorrectly,", "5678901234", getString(list));
+
+ // rotate sublist with negative distance
+ List subList = list.subList(1, 5);
+ Collections.rotate(subList, -1);
+ assertEquals("Test3: rotate modified the " + type
+ + " list incorrectly,", "5789601234", getString(list));
+
+ // rotate sublist with positive distance
+ Collections.rotate(subList, 2);
+ assertEquals("Test4: rotate modified the " + type
+ + " list incorrectly,", "5967801234", getString(list));
+
+ // rotate with positive distance that is larger than list size
+ Collections.rotate(list, 23);
+ assertEquals("Test5: rotate modified the " + type
+ + " list incorrectly,", "2345967801", getString(list));
+
+ // rotate with negative distance that is larger than list size
+ Collections.rotate(list, -23);
+ assertEquals("Test6: rotate modified the " + type
+ + " list incorrectly,", "5967801234", getString(list));
+
+ // rotate with 0 and equivalent distances, this should make no
+ // modifications to the list
+ Collections.rotate(list, 0);
+ assertEquals("Test7: rotate modified the " + type
+ + " list incorrectly,", "5967801234", getString(list));
+
+ Collections.rotate(list, -30);
+ assertEquals("Test8: rotate modified the " + type
+ + " list incorrectly,", "5967801234", getString(list));
+
+ Collections.rotate(list, 30);
+ assertEquals("Test9: rotate modified the " + type
+ + " list incorrectly,", "5967801234", getString(list));
+ }
+
+ private String getString(List list) {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < list.size(); i++) {
+ buffer.append(list.get(i));
+ }
+ return buffer.toString();
+ }
+
+ public void test_rotate2() {
+ List list = new ArrayList();
+ try {
+ Collections.rotate(list, 5);
+ } catch (UnsupportedOperationException e) {
+ fail("Unexpected UnsupportedOperationException for empty list, "
+ + e);
+ }
+
+ list.add(0, "zero");
+ list.add(1, "one");
+ list.add(2, "two");
+ list.add(3, "three");
+ list.add(4, "four");
+
+ Collections.rotate(list, Integer.MIN_VALUE);
+ assertEquals("Rotated incorrectly at position 0, ", "three",
+ (String) list.get(0));
+ assertEquals("Rotated incorrectly at position 1, ", "four",
+ (String) list.get(1));
+ assertEquals("Rotated incorrectly at position 2, ", "zero",
+ (String) list.get(2));
+ assertEquals("Rotated incorrectly at position 3, ", "one",
+ (String) list.get(3));
+ assertEquals("Rotated incorrectly at position 4, ", "two",
+ (String) list.get(4));
+ }
+
+ public void test_indexOfSubListLjava_util_ListLjava_util_List() {
+ // Test for method int indexOfSubList(java.util.List, java.util.List)
+ List list = new ArrayList();
+ try {
+ Collections.indexOfSubList(null, list);
+ fail("Expected NullPointerException for null list first parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ try {
+ Collections.indexOfSubList(list, null);
+ fail("Expected NullPointerException for null list second parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+
+ String string1 = "A-B-C-D-E-S-JF-SUB-G-H-I-J-SUBL-K-L-LIST-M-N--S-S-O-SUBLIS-P-Q-R-SUBLIST-S-T-U-V-W-X-Y-Z";
+
+ testwithCharList(1, string1, "B", true);
+ testwithCharList(2, string1, "LIST", true);
+ testwithCharList(3, string1, "SUBLIST", true);
+ testwithCharList(4, string1, "NONE", true);
+ testwithCharList(5, string1, "END", true);
+
+ // test boundary conditions:
+ testwithCharList(6, "", "", true);
+ testwithCharList(7, "LIST", "", true);
+ testwithCharList(8, "", "SUBLIST", true);
+ }
+
+ public void test_indexOfSubList2() {
+ ArrayList sub = new ArrayList();
+ sub.add(new Integer(1));
+ sub.add(new Integer(2));
+ sub.add(new Integer(3));
+
+ ArrayList sub2 = new ArrayList();
+ sub2.add(new Integer(7));
+ sub2.add(new Integer(8));
+
+ ArrayList src = new ArrayList();
+ src.addAll(sub);
+ src.addAll(sub);
+ src.addAll(sub);
+ src.add(new Integer(5));
+ src.add(new Integer(6));
+
+ // so src becomes a list like this:
+ // [1, 2, 3, 1, 2, 3, 1, 2, 3, 5, 6]
+
+ sub = new ArrayList(src.subList(3, 11));
+ // [1, 2, 3, 1, 2, 3, 5, 6]
+ assertEquals("TestA : Returned wrong indexOfSubList, ", 3, Collections
+ .indexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(6, 11));
+ // [1, 2, 3, 5, 6]
+ assertEquals("TestB : Returned wrong indexOfSubList, ", 6, Collections
+ .indexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(0, 3));
+ // [1, 2, 3]
+ assertEquals("TestCC : Returned wrong indexOfSubList, ", 0, Collections
+ .indexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(9, 11));
+ // [5, 6]
+ assertEquals("TestD : Returned wrong indexOfSubList, ", 9, Collections
+ .indexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(10, 11));
+ // [6]
+ assertEquals("TestE : Returned wrong indexOfSubList, ", 10, Collections
+ .indexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(0, 11));
+ // the whole list
+ assertEquals("TestH : Returned wrong indexIndexOfSubList, ", 0,
+ Collections.indexOfSubList(src, sub));
+
+ // a non-matching list
+ assertEquals("TestI : Returned wrong indexOfSubList, ", -1, Collections
+ .indexOfSubList(src, sub2));
+ }
+
+ private void testwithCharList(int count, String string1, String string2,
+ boolean first) {
+ char[] chars = string1.toCharArray();
+ List list = new ArrayList();
+ for (int i = 0; i < chars.length; i++) {
+ list.add(new Character(chars[i]));
+ }
+ chars = string2.toCharArray();
+ List sublist = new ArrayList();
+ for (int i = 0; i < chars.length; i++) {
+ sublist.add(new Character(chars[i]));
+ }
+
+ if (first)
+ assertEquals("Test " + count + ": Returned wrong index:", string1
+ .indexOf(string2), Collections
+ .indexOfSubList(list, sublist));
+ else
+ assertEquals("Test " + count + ": Returned wrong index:", string1
+ .lastIndexOf(string2), Collections.lastIndexOfSubList(list,
+ sublist));
+ }
+
+ public void test_lastIndexOfSubListLjava_util_ListLjava_util_List() {
+ // Test for method int lastIndexOfSubList(java.util.List,
+ // java.util.List)
+ String string1 = "A-B-C-D-E-S-JF-SUB-G-H-I-J-SUBL-K-L-LIST-M-N--S-S-O-SUBLIS-P-Q-R-SUBLIST-S-T-U-V-W-X-Y-Z-END";
+
+ List list = new ArrayList();
+ try {
+ Collections.lastIndexOfSubList(null, list);
+ fail("Expected NullPointerException for null list first parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+ try {
+ Collections.lastIndexOfSubList(list, null);
+ fail("Expected NullPointerException for null list second parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+
+ testwithCharList(1, string1, "B", false);
+ testwithCharList(2, string1, "LIST", false);
+ testwithCharList(3, string1, "SUBLIST", false);
+ testwithCharList(4, string1, "END", false);
+ testwithCharList(5, string1, "NONE", false);
+
+ // test boundary conditions
+ testwithCharList(6, "", "", false);
+ testwithCharList(7, "LIST", "", false);
+ testwithCharList(8, "", "SUBLIST", false);
+ }
+
+ public void test_lastIndexOfSubList2() {
+ ArrayList sub = new ArrayList();
+ sub.add(new Integer(1));
+ sub.add(new Integer(2));
+ sub.add(new Integer(3));
+
+ ArrayList sub2 = new ArrayList();
+ sub2.add(new Integer(7));
+ sub2.add(new Integer(8));
+
+ ArrayList src = new ArrayList();
+ src.addAll(sub);
+ src.addAll(sub);
+ src.addAll(sub);
+ src.add(new Integer(5));
+ src.add(new Integer(6));
+
+ // so src is a list like this:
+ // [1, 2, 3, 1, 2, 3, 1, 2, 3, 5, 6]
+
+ Collections.reverse(src);
+ // it becomes like this :
+ // [6, 5, 3, 2, 1, 3, 2, 1, 3, 2, 1]
+
+ sub = new ArrayList(src.subList(0, 8));
+ // [6, 5, 3, 2, 1, 3, 2, 1]
+ assertEquals("TestA : Returned wrong lastIndexOfSubList, ", 0,
+ Collections.lastIndexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(0, 5));
+ // [6, 5, 3, 2, 1]
+ assertEquals("TestB : Returned wrong lastIndexOfSubList, ", 0,
+ Collections.lastIndexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(2, 5));
+ // [3, 2, 1]
+ assertEquals("TestC : Returned wrong lastIndexOfSubList, ", 8,
+ Collections.lastIndexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(9, 11));
+ // [2, 1]
+ assertEquals("TestD : Returned wrong lastIndexOfSubList, ", 9,
+ Collections.lastIndexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(10, 11));
+ // [1]
+ assertEquals("TestE : Returned wrong lastIndexOfSubList, ", 10,
+ Collections.lastIndexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(0, 2));
+ // [6, 5]
+ assertEquals("TestF : Returned wrong lastIndexOfSubList, ", 0,
+ Collections.lastIndexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(0, 1));
+ // [6]
+ assertEquals("TestG : Returned wrong lastIndexOfSubList, ", 0,
+ Collections.lastIndexOfSubList(src, sub));
+
+ sub = new ArrayList(src.subList(0, 11));
+ // the whole list
+ assertEquals("TestH : Returned wrong lastIndexOfSubList, ", 0,
+ Collections.lastIndexOfSubList(src, sub));
+
+ // a non-matching list
+ assertEquals("TestI : Returned wrong lastIndexOfSubList, ", -1,
+ Collections.lastIndexOfSubList(src, sub2));
+ }
+
+ public void test_listLjava_util_Enumeration() {
+ // Test for method java.util.ArrayList list(java.util.Enumeration)
+
+ Enumeration e = Collections.enumeration(ll);
+ ArrayList al = Collections.list(e);
+
+ int size = al.size();
+ assertEquals("Wrong size", ll.size(), size);
+
+ for (int i = 0; i < size; i++) {
+ assertEquals("wrong element at position " + i + ",", ll.get(i), al
+ .get(i));
+ }
+ }
+
+ public void test_synchronizedCollectionLjava_util_Collection() {
+ // Test for method java.util.Collection
+ // java.util.Collections.synchronizedCollection(java.util.Collection)
+
+ LinkedList smallList = new LinkedList();
+ for (int i = 0; i < 50; i++) {
+ smallList.add(objArray[i]);
+ }
+
+ final int numberOfLoops = 200;
+ Collection synchCol = Collections.synchronizedCollection(smallList);
+ // Replacing the previous line with the line below *should* cause the
+ // test to fail--the collecion below isn't synchronized
+ // Collection synchCol = smallList;
+
+ SynchCollectionChecker normalSynchChecker = new SynchCollectionChecker(
+ synchCol, false, numberOfLoops);
+ SynchCollectionChecker offsetSynchChecker = new SynchCollectionChecker(
+ synchCol, true, numberOfLoops);
+ Thread normalThread = new Thread(normalSynchChecker);
+ Thread offsetThread = new Thread(offsetSynchChecker);
+ normalThread.start();
+ offsetThread.start();
+ while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
+ || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ assertTrue("Returned collection corrupted by multiple thread access",
+ normalSynchChecker.getResult()
+ && offsetSynchChecker.getResult());
+ try {
+ normalThread.join(5000);
+ offsetThread.join(5000);
+ } catch (InterruptedException e) {
+ fail("join() interrupted");
+ }
+
+ synchCol.add(null);
+ assertTrue("Trying to use nulls in collection failed", synchCol
+ .contains(null));
+
+ smallList = new LinkedList();
+ for (int i = 0; i < 100; i++) {
+ smallList.add(objArray[i]);
+ }
+ new Support_CollectionTest("", Collections
+ .synchronizedCollection(smallList)).runTest();
+
+ //Test self reference
+ synchCol = Collections.synchronizedCollection(smallList);
+ synchCol.add(smallList);
+ assertTrue("should contain self ref", synchCol.toString().indexOf("(this") > -1);
+ }
+
+ public void test_synchronizedListLjava_util_List() {
+ try {
+ Collections.synchronizedList(null);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ //Expected
+ }
+
+ // test with a Sequential Access List
+ List smallList = new LinkedList();
+ testSynchronizedList(smallList, "Sequential Access");
+
+ smallList = new LinkedList();
+ List myList;
+ for (int i = 0; i < 100; i++) {
+ smallList.add(objArray[i]);
+ }
+ myList = Collections.synchronizedList(smallList);
+ new Support_ListTest("", myList).runTest();
+
+ // test with a Random Access List
+ smallList = new ArrayList();
+ testSynchronizedList(smallList, "Random Access");
+
+ smallList = new ArrayList();
+ for (int i = 0; i < 100; i++) {
+ smallList.add(objArray[i]);
+ }
+ myList = Collections.synchronizedList(smallList);
+ new Support_ListTest("", myList).runTest();
+
+ //Test self reference
+ myList = Collections.synchronizedList(smallList);
+ myList.add(smallList);
+ assertTrue("should contain self ref", myList.toString().indexOf("(this") > -1);
+ }
+
+ private void testSynchronizedList(List smallList, String type) {
+ for (int i = 0; i < 50; i++) {
+ smallList.add(objArray[i]);
+ }
+ final int numberOfLoops = 200;
+ List synchList = Collections.synchronizedList(smallList);
+ if (type.equals("Random Access"))
+ assertTrue(
+ "Returned synchronized list should implement the Random Access interface",
+ synchList instanceof RandomAccess);
+ else
+ assertTrue(
+ "Returned synchronized list should not implement the Random Access interface",
+ !(synchList instanceof RandomAccess));
+
+ // Replacing the previous line with the line below *should* cause the
+ // test to fail--the list below isn't synchronized
+ // List synchList = smallList;
+ SynchCollectionChecker normalSynchChecker = new SynchCollectionChecker(
+ synchList, false, numberOfLoops);
+ SynchCollectionChecker offsetSynchChecker = new SynchCollectionChecker(
+ synchList, true, numberOfLoops);
+ Thread normalThread = new Thread(normalSynchChecker);
+ Thread offsetThread = new Thread(offsetSynchChecker);
+ normalThread.start();
+ offsetThread.start();
+ while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
+ || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ //Expected
+ }
+ }
+ assertTrue(
+ type
+ + " list tests: Returned list corrupted by multiple thread access",
+ normalSynchChecker.getResult()
+ && offsetSynchChecker.getResult());
+ try {
+ normalThread.join(5000);
+ offsetThread.join(5000);
+ } catch (InterruptedException e) {
+ fail(type + " list tests: join() interrupted");
+ }
+ synchList.set(25, null);
+ assertNull(type + " list tests: Trying to use nulls in list failed",
+ synchList.get(25));
+ }
+
+ public void test_synchronizedMapLjava_util_Map() {
+ // Test for method java.util.Map
+ // java.util.Collections.synchronizedMap(java.util.Map)
+ HashMap smallMap = new HashMap();
+ for (int i = 0; i < 50; i++) {
+ smallMap.put(objArray[i], objArray[i]);
+ }
+
+ final int numberOfLoops = 200;
+ Map synchMap = Collections.synchronizedMap(smallMap);
+ // Replacing the previous line with the line below should cause the test
+ // to fail--the list below isn't synchronized
+ // Map synchMap = smallMap;
+
+ SynchMapChecker normalSynchChecker = new SynchMapChecker(synchMap,
+ false, numberOfLoops);
+ SynchMapChecker offsetSynchChecker = new SynchMapChecker(synchMap,
+ true, numberOfLoops);
+ Thread normalThread = new Thread(normalSynchChecker);
+ Thread offsetThread = new Thread(offsetSynchChecker);
+ normalThread.start();
+ offsetThread.start();
+ while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
+ || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ //Expected
+ }
+ }
+ assertTrue("Returned map corrupted by multiple thread access",
+ normalSynchChecker.getResult()
+ && offsetSynchChecker.getResult());
+ try {
+ normalThread.join(5000);
+ offsetThread.join(5000);
+ } catch (InterruptedException e) {
+ fail("join() interrupted");
+ }
+
+ // synchronized map does not have to permit null keys or values
+ synchMap.put(new Long(25), null);
+ synchMap.put(null, new Long(30));
+ assertNull("Trying to use a null value in map failed", synchMap
+ .get(new Long(25)));
+ assertTrue("Trying to use a null key in map failed", synchMap.get(null)
+ .equals(new Long(30)));
+
+ smallMap = new HashMap();
+ for (int i = 0; i < 100; i++) {
+ smallMap.put(objArray[i].toString(), objArray[i]);
+ }
+ synchMap = Collections.synchronizedMap(smallMap);
+ new MapTestSupport(synchMap).runTest();
+ synchMap.keySet().remove(objArray[50].toString());
+ assertNull(
+ "Removing a key from the keySet of the synchronized map did not remove it from the synchronized map: ",
+ synchMap.get(objArray[50].toString()));
+ assertNull(
+ "Removing a key from the keySet of the synchronized map did not remove it from the original map",
+ smallMap.get(objArray[50].toString()));
+ }
+
+ public void test_unmodifiableMap_LinkedHashMap() {
+ // LinkedHashMap has a well defined iteration order and shows ordering issues with
+ // entrySet() / keySet() methods: iterator(), toArray(T[]) and toArray(). See bug 72073.
+ LinkedHashMap<String, Integer> smallMap = new LinkedHashMap<String, Integer>();
+ for (int i = 0; i < 100; i++) {
+ Integer object = objArray[i];
+ smallMap.put(object.toString(), object);
+ }
+ new MapTestSupport(smallMap).runTest();
+ }
+
+ public void test_synchronizedSetLjava_util_Set() {
+ // Test for method java.util.Set
+ // java.util.Collections.synchronizedSet(java.util.Set)
+ HashSet smallSet = new HashSet();
+ for (int i = 0; i < 50; i++) {
+ smallSet.add(objArray[i]);
+ }
+
+ final int numberOfLoops = 200;
+ Set synchSet = Collections.synchronizedSet(smallSet);
+ // Replacing the previous line with the line below should cause the test
+ // to fail--the set below isn't synchronized
+ // Set synchSet = smallSet;
+
+ SynchCollectionChecker normalSynchChecker = new SynchCollectionChecker(
+ synchSet, false, numberOfLoops);
+ SynchCollectionChecker offsetSynchChecker = new SynchCollectionChecker(
+ synchSet, true, numberOfLoops);
+ Thread normalThread = new Thread(normalSynchChecker);
+ Thread offsetThread = new Thread(offsetSynchChecker);
+ normalThread.start();
+ offsetThread.start();
+ while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
+ || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ //Expected
+ }
+ }
+ assertTrue("Returned set corrupted by multiple thread access",
+ normalSynchChecker.getResult()
+ && offsetSynchChecker.getResult());
+ try {
+ normalThread.join(5000);
+ offsetThread.join(5000);
+ } catch (InterruptedException e) {
+ fail("join() interrupted");
+ }
+
+ Set mySet = Collections.synchronizedSet(smallSet);
+ mySet.add(null);
+ assertTrue("Trying to use nulls in list failed", mySet.contains(null));
+
+ smallSet = new HashSet();
+ for (int i = 0; i < 100; i++) {
+ smallSet.add(objArray[i]);
+ }
+ new Support_SetTest("", Collections.synchronizedSet(smallSet))
+ .runTest();
+
+ //Test self reference
+ mySet = Collections.synchronizedSet(smallSet);
+ mySet.add(smallSet);
+ assertTrue("should contain self ref", mySet.toString().indexOf("(this") > -1);
+ }
+
+ public void test_synchronizedSortedMapLjava_util_SortedMap() {
+ // Test for method java.util.SortedMap
+ // java.util.Collections.synchronizedSortedMap(java.util.SortedMap)
+ TreeMap smallMap = new TreeMap();
+ for (int i = 0; i < 50; i++) {
+ smallMap.put(objArray[i], objArray[i]);
+ }
+
+ final int numberOfLoops = 200;
+ Map synchMap = Collections.synchronizedMap(smallMap);
+ // Replacing the previous line with the line below should cause the test
+ // to fail--the list below isn't synchronized
+ // Map synchMap = smallMap;
+
+ SynchMapChecker normalSynchChecker = new SynchMapChecker(synchMap,
+ false, numberOfLoops);
+ SynchMapChecker offsetSynchChecker = new SynchMapChecker(synchMap,
+ true, numberOfLoops);
+ Thread normalThread = new Thread(normalSynchChecker);
+ Thread offsetThread = new Thread(offsetSynchChecker);
+ normalThread.start();
+ offsetThread.start();
+ while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
+ || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ //Expected
+ }
+ }
+ assertTrue("Returned map corrupted by multiple thread access",
+ normalSynchChecker.getResult()
+ && offsetSynchChecker.getResult());
+ try {
+ normalThread.join(5000);
+ offsetThread.join(5000);
+ } catch (InterruptedException e) {
+ fail("join() interrupted");
+ }
+
+ smallMap = new TreeMap();
+ for (int i = 0; i < 100; i++) {
+ smallMap.put(objArray[i].toString(), objArray[i]);
+ }
+ synchMap = Collections.synchronizedSortedMap(smallMap);
+ new MapTestSupport(synchMap).runTest();
+ synchMap.keySet().remove(objArray[50].toString());
+ assertNull(
+ "Removing a key from the keySet of the synchronized map did not remove it from the synchronized map",
+ synchMap.get(objArray[50].toString()));
+ assertNull(
+ "Removing a key from the keySet of the synchronized map did not remove it from the original map",
+ smallMap.get(objArray[50].toString()));
+ }
+
+ public void test_synchronizedSortedSetLjava_util_SortedSet() {
+ // Test for method java.util.SortedSet
+ // java.util.Collections.synchronizedSortedSet(java.util.SortedSet)
+ TreeSet smallSet = new TreeSet();
+ for (int i = 0; i < 50; i++) {
+ smallSet.add(objArray[i]);
+ }
+
+ final int numberOfLoops = 200;
+ Set synchSet = Collections.synchronizedSet(smallSet);
+ // Replacing the previous line with the line below should cause the test
+ // to fail--the list below isn't synchronized
+ // Set synchSet = smallSet;
+
+ SynchCollectionChecker normalSynchChecker = new SynchCollectionChecker(
+ synchSet, false, numberOfLoops);
+ SynchCollectionChecker offsetSynchChecker = new SynchCollectionChecker(
+ synchSet, true, numberOfLoops);
+ Thread normalThread = new Thread(normalSynchChecker);
+ Thread offsetThread = new Thread(offsetSynchChecker);
+ normalThread.start();
+ offsetThread.start();
+ while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
+ || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ //Expected
+ }
+ }
+ assertTrue("Returned set corrupted by multiple thread access",
+ normalSynchChecker.getResult()
+ && offsetSynchChecker.getResult());
+ try {
+ normalThread.join(5000);
+ offsetThread.join(5000);
+ } catch (InterruptedException e) {
+ fail("join() interrupted");
+ }
+ }
+
+ public void test_unmodifiableCollectionLjava_util_Collection() {
+ // Test for method java.util.Collection
+ // java.util.Collections.unmodifiableCollection(java.util.Collection)
+ boolean exception = false;
+ Collection c = Collections.unmodifiableCollection(ll);
+ assertTrue("Returned collection is of incorrect size", c.size() == ll
+ .size());
+ Iterator iterator = ll.iterator();
+ while (iterator.hasNext())
+ assertTrue("Returned list missing elements", c.contains(iterator.next()));
+ try {
+ c.add(new Object());
+ } catch (UnsupportedOperationException e) {
+ exception = true;
+ // Correct
+ }
+ if (!exception) {
+ fail("Allowed modification of collection");
+ }
+
+ try {
+ c.remove(new Object());
+ fail("Allowed modification of collection");
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ }
+
+ Collection myCollection = new ArrayList();
+ myCollection.add(new Integer(20));
+ myCollection.add(null);
+ c = Collections.unmodifiableCollection(myCollection);
+ assertTrue("Collection should contain null", c.contains(null));
+ assertTrue("Collection should contain Integer(20)", c
+ .contains(new Integer(20)));
+
+ myCollection = new ArrayList();
+ for (int i = 0; i < 100; i++) {
+ myCollection.add(objArray[i]);
+ }
+ new Support_UnmodifiableCollectionTest("", Collections
+ .unmodifiableCollection(myCollection)).runTest();
+ }
+
+ public void test_unmodifiableListLjava_util_List() {
+ // Test for method java.util.List
+ // java.util.Collections.unmodifiableList(java.util.List)
+
+ // test with a Sequential Access List
+ boolean exception = false;
+ List c = Collections.unmodifiableList(ll);
+ // Ensure a NPE is thrown if the list is NULL
+ try {
+ Collections.unmodifiableList(null);
+ fail("Expected NullPointerException for null list parameter");
+ } catch (NullPointerException e) {
+ }
+
+ assertTrue("Returned list is of incorrect size", c.size() == ll.size());
+ assertTrue(
+ "Returned List should not implement Random Access interface",
+ !(c instanceof RandomAccess));
+
+ Iterator iterator = ll.iterator();
+ while (iterator.hasNext())
+ assertTrue("Returned list missing elements", c.contains(iterator.next()));
+ try {
+ c.add(new Object());
+ } catch (UnsupportedOperationException e) {
+ exception = true;
+ // Correct
+ }
+ if (!exception) {
+ fail("Allowed modification of list");
+ }
+
+ try {
+ c.remove(new Object());
+ fail("Allowed modification of list");
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ }
+
+ // test with a Random Access List
+ List smallList = new ArrayList();
+ smallList.add(null);
+ smallList.add("yoink");
+ c = Collections.unmodifiableList(smallList);
+ assertNull("First element should be null", c.get(0));
+ assertTrue("List should contain null", c.contains(null));
+ assertTrue(
+ "T1. Returned List should implement Random Access interface",
+ c instanceof RandomAccess);
+
+ smallList = new ArrayList();
+ for (int i = 0; i < 100; i++) {
+ smallList.add(objArray[i]);
+ }
+ List myList = Collections.unmodifiableList(smallList);
+ assertTrue("List should not contain null", !myList.contains(null));
+ assertTrue(
+ "T2. Returned List should implement Random Access interface",
+ myList instanceof RandomAccess);
+
+ assertTrue("get failed on unmodifiable list", myList.get(50).equals(
+ new Integer(50)));
+ ListIterator listIterator = myList.listIterator();
+ for (int i = 0; listIterator.hasNext(); i++) {
+ assertTrue("List has wrong elements", ((Integer) listIterator
+ .next()).intValue() == i);
+ }
+ new Support_UnmodifiableCollectionTest("", smallList).runTest();
+ }
+
+ public void test_unmodifiableMapLjava_util_Map() {
+ // Test for method java.util.Map
+ // java.util.Collections.unmodifiableMap(java.util.Map)
+ boolean exception = false;
+ Map c = Collections.unmodifiableMap(hm);
+ assertTrue("Returned map is of incorrect size", c.size() == hm.size());
+ Iterator iterator = hm.keySet().iterator();
+ while (iterator.hasNext()) {
+ Object x = iterator.next();
+ assertTrue("Returned map missing elements", c.get(x).equals(
+ hm.get(x)));
+ }
+ try {
+ c.put(new Object(), "");
+ } catch (UnsupportedOperationException e) {
+ exception = true;
+ // Correct
+ }
+ assertTrue("Allowed modification of map", exception);
+
+ exception = false;
+ try {
+ c.remove(new Object());
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Allowed modification of map", exception);
+
+ exception = false;
+ Iterator entrySetIterator = c.entrySet().iterator();
+ Map.Entry entry = (Map.Entry) entrySetIterator.next();
+ try {
+ entry.setValue("modified");
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Allowed modification of entry", exception);
+
+ exception = false;
+ Object[] array = c.entrySet().toArray();
+ try {
+ ((Map.Entry) array[0]).setValue("modified");
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Allowed modification of array entry", exception);
+
+ exception = false;
+ Map.Entry[] array2 = (Map.Entry[]) c.entrySet().toArray(
+ new Map.Entry[0]);
+ try {
+ array2[0].setValue("modified");
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ exception = true;
+ }
+ assertTrue("Allowed modification of array entry2", exception);
+
+ HashMap smallMap = new HashMap();
+ smallMap.put(null, new Long(30));
+ smallMap.put(new Long(25), null);
+ Map unmodMap = Collections.unmodifiableMap(smallMap);
+
+ assertNull("Trying to use a null value in map failed", unmodMap
+ .get(new Long(25)));
+ assertTrue("Trying to use a null key in map failed", unmodMap.get(null)
+ .equals(new Long(30)));
+
+ smallMap = new HashMap();
+ for (int i = 0; i < 100; i++) {
+ smallMap.put(objArray[i].toString(), objArray[i]);
+ }
+ new MapTestSupport(smallMap).runTest();
+ }
+
+ public void test_unmodifiableSetLjava_util_Set() {
+ // Test for method java.util.Set
+ // java.util.Collections.unmodifiableSet(java.util.Set)
+ boolean exception = false;
+ Set c = Collections.unmodifiableSet(s);
+ assertTrue("Returned set is of incorrect size", c.size() == s.size());
+ Iterator iterator = ll.iterator();
+ while (iterator.hasNext())
+ assertTrue("Returned set missing elements", c.contains(iterator.next()));
+ try {
+ c.add(new Object());
+ } catch (UnsupportedOperationException e) {
+ exception = true;
+ // Correct
+ }
+ if (!exception) {
+ fail("Allowed modification of set");
+ }
+ try {
+ c.remove(new Object());
+ fail("Allowed modification of set");
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ }
+
+ Set mySet = Collections.unmodifiableSet(new HashSet());
+ assertTrue("Should not contain null", !mySet.contains(null));
+ mySet = Collections.unmodifiableSet(Collections.singleton(null));
+ assertTrue("Should contain null", mySet.contains(null));
+
+ mySet = new TreeSet();
+ for (int i = 0; i < 100; i++) {
+ mySet.add(objArray[i]);
+ }
+ new Support_UnmodifiableCollectionTest("", Collections
+ .unmodifiableSet(mySet)).runTest();
+ }
+
+ public void test_unmodifiableSortedMapLjava_util_SortedMap() {
+ // Test for method java.util.SortedMap
+ // java.util.Collections.unmodifiableSortedMap(java.util.SortedMap)
+ boolean exception = false;
+ TreeMap tm = new TreeMap();
+ tm.putAll(hm);
+ Map c = Collections.unmodifiableSortedMap(tm);
+ assertTrue("Returned map is of incorrect size", c.size() == tm.size());
+ Iterator i = hm.keySet().iterator();
+ while (i.hasNext()) {
+ Object x = i.next();
+ assertTrue("Returned map missing elements", c.get(x).equals(
+ tm.get(x)));
+ }
+ try {
+ c.put(new Object(), "");
+ } catch (UnsupportedOperationException e) {
+ exception = true;
+ // Correct
+ }
+
+ if (!exception) {
+ fail("Allowed modification of map");
+ }
+ try {
+ c.remove(new Object());
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ return;
+ }
+ fail("Allowed modification of map");
+ }
+
+ public void test_unmodifiableSortedSetLjava_util_SortedSet() {
+ // Test for method java.util.SortedSet
+ // java.util.Collections.unmodifiableSortedSet(java.util.SortedSet)
+ boolean exception = false;
+ SortedSet ss = new TreeSet();
+ ss.addAll(s);
+ SortedSet c = Collections.unmodifiableSortedSet(ss);
+ assertTrue("Returned set is of incorrect size", c.size() == ss.size());
+ Iterator i = ll.iterator();
+ while (i.hasNext())
+ assertTrue("Returned set missing elements", c.contains(i.next()));
+ try {
+ c.add(new Object());
+ } catch (UnsupportedOperationException e) {
+ exception = true;
+ // Correct
+ }
+ if (!exception) {
+ fail("Allowed modification of set");
+ }
+ try {
+ c.remove(new Object());
+ } catch (UnsupportedOperationException e) {
+ // Correct
+ return;
+ }
+ fail("Allowed modification of set");
+ }
+
+ /**
+ * Test unmodifiable objects toString methods
+ */
+ public void test_unmodifiable_toString_methods() {
+ // Regression for HARMONY-552
+ ArrayList al = new ArrayList();
+ al.add("a");
+ al.add("b");
+ Collection uc = Collections.unmodifiableCollection(al);
+ assertEquals("[a, b]", uc.toString());
+ HashMap m = new HashMap();
+ m.put("one", "1");
+ m.put("two", "2");
+ Map um = Collections.unmodifiableMap(m);
+ assertTrue("{one=1, two=2}".equals(um.toString()) ||
+ "{two=2, one=1}".equals(um.toString()));
+ }
+
+
+ public void test_singletonListLjava_lang_Object() {
+ // Test for method java.util.Set
+ // java.util.Collections.singleton(java.lang.Object)
+ String str = "Singleton";
+
+ List single = Collections.singletonList(str);
+ assertEquals(1, single.size());
+ assertTrue(single.contains(str));
+ assertFalse(single.contains(null));
+ assertFalse(Collections.singletonList(null).contains(str));
+ assertTrue(Collections.singletonList(null).contains(null));
+
+ try {
+ single.add("New element");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void test_singletonMapLjava_lang_Object() {
+ // Test for method java.util.Set
+ // java.util.Collections.singleton(java.lang.Object)
+ Double key = new Double (3.14);
+ String value = "Fundamental constant";
+
+ Map single = Collections.singletonMap(key, value);
+ assertEquals(1, single.size());
+ assertTrue(single.containsKey(key));
+ assertTrue(single.containsValue(value));
+ assertFalse(single.containsKey(null));
+ assertFalse(single.containsValue(null));
+ assertFalse(Collections.singletonMap(null, null).containsKey(key));
+ assertFalse(Collections.singletonMap(null, null).containsValue(value));
+ assertTrue(Collections.singletonMap(null, null).containsKey(null));
+ assertTrue(Collections.singletonMap(null, null).containsValue(null));
+
+ try {
+ single.clear();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+
+ try {
+ single.put(new Double(1), "one wrong value");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void test_checkType_Ljava_lang_Object_Ljava_lang_Class() throws Exception {
+ Method m = Collections.class.getDeclaredMethod("checkType", Object.class, Class.class);
+ m.setAccessible(true);
+ m.invoke(null, new Object(), Object.class);
+
+ try {
+ m.invoke(null, new Object(), int.class);
+ fail();
+ } catch (InvocationTargetException expected) {
+ }
+ }
+
+ public void test_binarySearch_asymmetry_with_comparator() throws Exception {
+ List list = new ArrayList();
+ String s1 = new String("a");
+ String s2 = new String("aa");
+ String s3 = new String("aaa");
+ list.add(s1);
+ list.add(s2);
+ list.add(s3);
+ Collections.sort(list);
+ Object o = Collections.binarySearch(list, 1, new StringComparator());
+ assertSame(0, o);
+ }
+
+ public void test_binarySearch_asymmetry() throws Exception {
+ List list = new LinkedList();
+ String s1 = new String("a");
+ String s2 = new String("aa");
+ String s3 = new String("aaa");
+ list.add(new MyComparable(s1));
+ list.add(new MyComparable(s2));
+ list.add(new MyComparable(s3));
+ Collections.sort(list);
+ Object o = Collections.binarySearch(list, 1);
+ assertSame(0, o);
+ }
+
+
+ private class MyComparable implements Comparable {
+
+ public String s;
+
+ public MyComparable(String s) {
+ this.s = s;
+
+ }
+
+ public int compareTo(Object another) {
+ int length = 0;
+ if (another instanceof MyComparable) {
+ length = (((MyComparable) another).s).length();
+ } else {
+ length = (Integer) another;
+ }
+ return s.length() - length;
+ }
+
+ }
+
+ private class StringComparator implements Comparator {
+
+ public int compare(Object object1, Object object2) {
+ String s = (String) object1;
+ int length;
+ if (object2 instanceof String) {
+ length = ((String) object2).length();
+ } else {
+ length = (Integer) object2;
+ }
+ return s.length() - length;
+ }
+ }
+
+
+ public void test_newSetFromMap_LMap() throws Exception {
+ Integer testInt[] = new Integer[100];
+ for (int i = 0; i < testInt.length; i++) {
+ testInt[i] = new Integer(i);
+ }
+ Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
+ Set<Integer> set = Collections.newSetFromMap(map);
+ for (int i = 0; i < testInt.length; i++) {
+ map.put(testInt[i], true);
+ }
+ // operater on map successed
+ map.put(testInt[1], false);
+ assertTrue(map.containsKey(testInt[1]));
+ assertEquals(100, map.size());
+ assertFalse(map.get(testInt[1]));
+ assertEquals(100, set.size());
+ assertTrue(set.contains(testInt[16]));
+ Iterator setIter = set.iterator();
+ Iterator mapIter = map.keySet().iterator();
+ int i = 0;
+ // in the same order
+ while (setIter.hasNext()) {
+ assertEquals(mapIter.next(), setIter.next());
+ }
+
+ // operator on set successed
+ Integer testInt101 = new Integer(101);
+ Integer testInt102 = new Integer(102);
+ set.add(testInt101);
+ assertTrue(set.contains(testInt101));
+ assertTrue(map.get(testInt101));
+
+ // operator on map still passes
+ map.put(testInt102, false);
+ assertTrue(set.contains(testInt102));
+ assertFalse(map.get(testInt102));
+
+ // exception thrown
+ try {
+ Collections.newSetFromMap(map);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationSelf_newSetFromMap() throws Exception {
+ Integer testInt[] = new Integer[100];
+ for (int i = 0; i < testInt.length; i++) {
+ testInt[i] = new Integer(i);
+ }
+ Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
+ Set<Integer> set = Collections.newSetFromMap(map);
+ for (int i = 0; i < testInt.length; i++) {
+ map.put(testInt[i], true);
+ }
+ SerializationTest.verifySelf(set);
+ }
+
+ public void test_asLifoQueue() throws Exception {
+ Integer testInt[] = new Integer[100];
+ Integer test101 = new Integer(101);
+ for (int i = 0; i < testInt.length; i++) {
+ testInt[i] = new Integer(i);
+ }
+ Deque deque = new ArrayDeque<Integer>();
+ Queue<Integer> que = Collections.asLifoQueue(deque);
+ for (int i = 0; i < testInt.length; i++) {
+ que.add(testInt[i]);
+ }
+ assertEquals(100, deque.size());
+ assertEquals(100, que.size());
+ for (int i = testInt.length - 1; i >= 0; i--) {
+ assertEquals(testInt[i], deque.pop());
+ }
+ assertEquals(0, deque.size());
+ assertEquals(0, que.size());
+ for (int i = 0; i < testInt.length; i++) {
+ deque.push(testInt[i]);
+ }
+ assertEquals(100, deque.size());
+ assertEquals(100, que.size());
+ Collection col = new LinkedList<Integer>();
+ col.add(test101);
+ que.addAll(col);
+ assertEquals(test101, que.remove());
+ for (int i = testInt.length - 1; i >= 0; i--) {
+ assertEquals(testInt[i], que.remove());
+ }
+ assertEquals(0, deque.size());
+ assertEquals(0, que.size());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationSelf_asLifoQueue() throws Exception {
+ Integer testInt[] = new Integer[100];
+ for (int i = 0; i < testInt.length; i++) {
+ testInt[i] = new Integer(i);
+ }
+ Deque deque = new ArrayDeque<Integer>();
+ Queue<Integer> que = Collections.asLifoQueue(deque);
+ for (int i = 0; i < testInt.length; i++) {
+ que.add(testInt[i]);
+ }
+ SerializationTest.verifySelf(que, new SerializableAssert() {
+ public void assertDeserialized(Serializable initial, Serializable deserialized) {
+ Queue<Integer> initque = (Queue) initial;
+ Queue<Integer> deserque = (Queue) deserialized;
+ while (!initque.isEmpty()) {
+ assertEquals(initque.remove(), deserque.remove());
+ }
+ }
+ });
+ }
+
+ public void test_emptyList() {
+ List<String> list = Collections.emptyList();
+ assertTrue("should be true", list.isEmpty());
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ objArray = new Integer[1000];
+ myobjArray = new Object[1000];
+ for (int i = 0; i < objArray.length; i++) {
+ objArray[i] = i;
+ myobjArray[i] = new MyInt(i);
+ }
+
+ ll = new LinkedList();
+ myll = new LinkedList();
+ s = new HashSet();
+ mys = new HashSet();
+ reversedLinkedList = new LinkedList(); // to be sorted in reverse order
+ myReversedLinkedList = new LinkedList(); // to be sorted in reverse
+ // order
+ hm = new HashMap();
+ for (int i = 0; i < objArray.length; i++) {
+ ll.add(objArray[i]);
+ myll.add(myobjArray[i]);
+ s.add(objArray[i]);
+ mys.add(myobjArray[i]);
+ reversedLinkedList.add(objArray[objArray.length - i - 1]);
+ myReversedLinkedList.add(myobjArray[myobjArray.length - i - 1]);
+ hm.put(objArray[i].toString(), objArray[i]);
+ }
+ }
+
+ /**
+ * A class shared by various Map-related tests that checks the properties and contents of a
+ * supplied Map and compares the some methods to the same map when wrapped with
+ * {@link Collections#unmodifiableMap(java.util.Map)}.
+ */
+ static class MapTestSupport {
+
+ // must be a map containing the string keys "0"-"99" paired with the Integer
+ // values Integer(0) to Integer(99)
+ private final Map<String, Integer> modifiableMap;
+ private final Map<String, Integer> unmodifiableMap;
+
+ public MapTestSupport(Map<String, Integer> modifiableMap) {
+ this.modifiableMap = modifiableMap;
+ unmodifiableMap = Collections.unmodifiableMap(modifiableMap);
+ }
+
+ public void runTest() {
+ testContents(modifiableMap);
+ testContents(unmodifiableMap);
+
+ // values()
+ new Support_UnmodifiableCollectionTest("values() from map test", modifiableMap.values())
+ .runTest();
+ new Support_UnmodifiableCollectionTest("values() from unmodifiable map test",
+ unmodifiableMap.values()).runTest();
+
+ // entrySet()
+ testEntrySet(modifiableMap.entrySet(), unmodifiableMap.entrySet());
+
+ // keySet()
+ testKeySet(modifiableMap.keySet(), unmodifiableMap.keySet());
+ }
+
+ private static void testContents(Map<String, Integer> map) {
+ // size
+ assertTrue("Size should return 100, returned: " + map.size(), map.size() == 100);
+
+ // containsKey
+ assertTrue("Should contain the key \"0\"", map.containsKey("0"));
+ assertTrue("Should contain the key \"50\"", map.containsKey("50"));
+ assertTrue("Should not contain the key \"100\"", !map.containsKey("100"));
+
+ // containsValue
+ assertTrue("Should contain the value 0", map.containsValue(0));
+ assertTrue("Should contain the value 50", map.containsValue(50));
+ assertTrue("Should not contain value 100", !map.containsValue(100));
+
+ // get
+ assertTrue("getting \"0\" didn't return 0", map.get("0") == 0);
+ assertTrue("getting \"50\" didn't return 50", map.get("50") == 50);
+ assertNull("getting \"100\" didn't return null", map.get("100"));
+
+ // isEmpty
+ assertTrue("should have returned false to isEmpty", !map.isEmpty());
+ }
+
+ private static void testEntrySet(
+ Set<Map.Entry<String, Integer>> referenceEntrySet,
+ Set<Map.Entry<String, Integer>> entrySet) {
+ // entrySet should be a set of mappings {"0", 0}, {"1",1}... {"99", 99}
+ assertEquals(100, referenceEntrySet.size());
+ assertEquals(100, entrySet.size());
+
+ // The ordering may be undefined for a map implementation but the ordering must be the
+ // same across iterator(), toArray() and toArray(T[]) for a given map *and* the same for the
+ // modifiable and unmodifiable map.
+ crossCheckOrdering(referenceEntrySet, entrySet, Map.Entry.class);
+ }
+
+ private static void testKeySet(Set<String> referenceKeySet, Set<String> keySet) {
+ // keySet should be a set of the strings "0" to "99"
+ testKeySetContents(referenceKeySet);
+ testKeySetContents(keySet);
+
+ // The ordering may be undefined for a map implementation but the ordering must be the
+ // same across iterator(), toArray() and toArray(T[]) for a given map *and* the same for the
+ // modifiable and unmodifiable map.
+ crossCheckOrdering(referenceKeySet, keySet, String.class);
+ }
+
+ private static void testKeySetContents(Set<String> keySet) {
+ // contains
+ assertTrue("should contain \"0\"", keySet.contains("0"));
+ assertTrue("should contain \"50\"", keySet.contains("50"));
+ assertTrue("should not contain \"100\"", !keySet.contains("100"));
+
+ // containsAll
+ HashSet<String> hs = new HashSet<String>();
+ hs.add("0");
+ hs.add("25");
+ hs.add("99");
+ assertTrue("Should contain set of \"0\", \"25\", and \"99\"", keySet.containsAll(hs));
+ hs.add("100");
+ assertTrue("Should not contain set of \"0\", \"25\", \"99\" and \"100\"",
+ !keySet.containsAll(hs));
+
+ // isEmpty
+ assertTrue("Should not be empty", !keySet.isEmpty());
+
+ // size
+ assertEquals("Returned wrong size.", 100, keySet.size());
+ }
+
+ private static <T> void crossCheckOrdering(Set<T> set1, Set<T> set2, Class<?> elementType) {
+ Iterator<T> set1Iterator = set1.iterator();
+ Iterator<T> set2Iterator = set2.iterator();
+
+ T[] zeroLengthArray = createArray(elementType, 0);
+ T[] set1TypedArray1 = set1.toArray(zeroLengthArray);
+ assertEquals(set1.size(), set1TypedArray1.length);
+
+ // Compare set1.iterator(), set2.iterator() and set1.toArray(new T[0])
+ int entryCount = 0;
+ while (set1Iterator.hasNext()) {
+ T set1Entry = set1Iterator.next();
+ T set2Entry = set2Iterator.next();
+
+ // Compare set1 with set2
+ assertEquals(set1Entry, set2Entry);
+
+ // Compare the iterator with the array. The arrays will be checked against each other.
+ assertEquals(set1Entry, set1TypedArray1[entryCount]);
+
+ entryCount++;
+ }
+ assertFalse(set2Iterator.hasNext());
+ assertEquals(set1.size(), entryCount);
+
+ // Compare the various arrays with each other.
+
+ // set1.toArray(new T[size])
+ T[] parameterArray1 = createArray(elementType, set1.size());
+ T[] set1TypedArray2 = set1.toArray(parameterArray1);
+ assertSame(set1TypedArray2, parameterArray1);
+ assertArrayEquals(set1TypedArray1, set1TypedArray2);
+
+ // set1.toArray()
+ Object[] set1UntypedArray = set1.toArray();
+ assertEquals(set1.size(), set1UntypedArray.length);
+ assertArrayEquals(set1TypedArray1, set1UntypedArray);
+
+ // set2.toArray(new T[0])
+ T[] set2TypedArray1 = set2.toArray(zeroLengthArray);
+ assertEquals(set1.size(), set2TypedArray1.length);
+ assertArrayEquals(set1TypedArray1, set2TypedArray1);
+
+ // set2.toArray(new T[size])
+ T[] parameterArray2 = createArray(elementType, set2.size());
+ T[] set2TypedArray2 = set1.toArray(parameterArray2);
+ assertSame(set2TypedArray2, parameterArray2);
+ assertArrayEquals(set1TypedArray1, set1TypedArray2);
+
+ // set2.toArray()
+ Object[] set2UntypedArray = set2.toArray();
+ assertArrayEquals(set1TypedArray1, set2UntypedArray);
+ }
+
+ private static <T> void assertArrayEquals(T[] array1, T[] array2) {
+ assertTrue(Arrays.equals(array1, array2));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> T[] createArray(Class<?> elementType, int size) {
+ return (T[]) Array.newInstance(elementType, size);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModTest.java
new file mode 100644
index 0000000..2e2553d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModTest.java
@@ -0,0 +1,667 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.List;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+public class ConcurrentModTest extends TestCase {
+
+ /*
+ * Test method for 'java.util.AbstractList.subList(int, int)'
+ */
+ public void testGet() {
+ AbstractList al = new ArrayList();
+ Double one = new Double(1.0);
+ Double two = new Double(2.0);
+ Double three = new Double(3.0);
+ Double four = new Double(4.0);
+ al.add(one);
+ al.add(two);
+ al.add(three);
+ al.add(four);
+ List sub = al.subList(1, 3);
+ assertEquals(2, sub.size());
+ // the sub.get(1) is 3.0
+ assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
+ assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
+
+ al.remove(1); // remove the 2.0
+
+ try {
+ // illegal call the subList's method get(int).
+ sub.get(1);
+ fail("It should throws ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ return;
+ }
+
+ try {
+ al.get(-1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ try {
+ al.get(al.size()+1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+ }
+
+ /*
+ * Test method for 'java.util.AbstractList.subList(int, int)'
+ */
+ public void testSet() {
+ AbstractList al = new ArrayList();
+ Double one = new Double(1.0);
+ Double two = new Double(2.0);
+ Double three = new Double(3.0);
+ Double four = new Double(4.0);
+ al.add(one);
+ al.add(two);
+ al.add(three);
+ al.add(four);
+ List sub = al.subList(1, 3);
+ assertEquals(2, sub.size());
+ // the sub.get(1) is 3.0
+ assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
+ assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
+
+ al.remove(1); // remove the 2.0
+
+ try {
+ // illegal call the subList's method set(int,Object).
+ sub.set(1, two);
+ fail("It should throws ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ return;
+ }
+ }
+
+ /*
+ * Test method for 'java.util.AbstractList.subList(int, int)'
+ */
+ public void testAdd() {
+ AbstractList al = new ArrayList();
+ Double one = new Double(1.0);
+ Double two = new Double(2.0);
+ Double three = new Double(3.0);
+ Double four = new Double(4.0);
+ al.add(one);
+ al.add(two);
+ al.add(three);
+ al.add(four);
+ List sub = al.subList(1, 3);
+ assertEquals(2, sub.size());
+ // the sub.get(1) is 3.0
+ assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
+ assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
+
+ al.remove(1); // remove the 2.0
+
+ try {
+ // illegal call the subList's method Add(int,Object).
+ sub.add(1, two);
+ fail("It should throws ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ return;
+ }
+ }
+
+ /*
+ * Test method for 'java.util.AbstractList.subList(int, int)'
+ */
+ public void testRemove() {
+ AbstractList al = new ArrayList();
+ Double one = new Double(1.0);
+ Double two = new Double(2.0);
+ Double three = new Double(3.0);
+ Double four = new Double(4.0);
+ al.add(one);
+ al.add(two);
+ al.add(three);
+ al.add(four);
+ List sub = al.subList(1, 3);
+ assertEquals(2, sub.size());
+ // the sub.get(1) is 3.0
+ assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
+ assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
+
+ al.remove(1); // remove the 2.0
+
+ try {
+ // illegal call the subList's method remove(int).
+ sub.remove(1);
+ fail("It should throws ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ return;
+ }
+
+ try {
+ sub.remove(-1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ try {
+ sub.remove(sub.size() + 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ al = new AbstractList() {
+
+ @Override
+ public Object get(int index) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int size() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+ };
+
+ try {
+ al.remove(1);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException ee) {
+ //expected
+ }
+ }
+
+ /*
+ * Test method for 'java.util.AbstractList.subList(int, int)'
+ */
+ public void testAddAll() {
+ AbstractList al = new ArrayList();
+ Double one = new Double(1.0);
+ Double two = new Double(2.0);
+ Double three = new Double(3.0);
+ Double four = new Double(4.0);
+ al.add(one);
+ al.add(two);
+ al.add(three);
+ al.add(four);
+ List sub = al.subList(1, 3);
+ assertEquals(2, sub.size());
+ // the sub.get(1) is 3.0
+ assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
+ assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
+
+ al.remove(1); // remove the 2.0
+
+ try {
+ // illegal call the subList's method addAll(int,Collection).
+ Collection c = new Vector();
+ Double five = new Double(5.0);
+ c.add(five);
+ sub.addAll(1, c);
+ fail("It should throws ConcurrentModificationException.");
+ } catch (ConcurrentModificationException e) {
+ return;
+ }
+ }
+
+ public void test_addLjava_lang_Object() {
+ AbstractList abstr = new AbstractList() {
+
+ @Override
+ public Object get(int arg0) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ };
+
+ try {
+ abstr.add(null);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //ecpected
+ }
+ abstr = new AbstractList<Double>() {
+ @Override
+ public boolean add(Double value) {
+ return true;
+ }
+
+ @Override
+ public Double get(int index) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+
+ try {
+ abstr.add(1);
+ fail("ClassCastException expected");
+ } catch (ClassCastException ee) {
+ //expected
+ }
+
+ abstr = new AbstractList<Integer>() {
+ final int forbiddenValue = 33;
+ @Override
+ public boolean add(Integer value) {
+ if (value == forbiddenValue) {
+ throw new IllegalArgumentException();
+ }
+ return true;
+ }
+
+ @Override
+ public Integer get(int index) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+
+ abstr.add(1);
+ try {
+ abstr.add(33);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ee) {
+ //expected
+ }
+ }
+
+ public void test_addILjava_lang_Object() {
+ AbstractList abstr = new AbstractList() {
+
+ @Override
+ public Object get(int arg0) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ };
+
+ try {
+ abstr.add(1, null);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //ecpected
+ }
+ abstr = new AbstractList<Double>() {
+ @Override
+ public void add(int index, Double value) {
+ }
+
+ @Override
+ public Double get(int index) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+
+ try {
+ abstr.add(1, 1);
+ fail("ClassCastException expected");
+ } catch (ClassCastException ee) {
+ //expected
+ }
+
+ abstr = new AbstractList<Integer>() {
+ final int forbiddenValue = 33;
+ @Override
+ public void add(int index, Integer value) {
+ if (value == forbiddenValue) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public Integer get(int index) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+
+ abstr.add(1, 1);
+ try {
+ abstr.add(1, 33);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ee) {
+ //expected
+ }
+
+ abstr = new ArrayList();
+
+ abstr.add(0, "element");
+ abstr.add(1, null);
+ abstr.add(2, 1);
+ abstr.add(3, new Double(33));
+
+ try {
+ abstr.add(-3, new Double(33));
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ try {
+ abstr.add(abstr.size() + 1, new Double(33));
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+ }
+
+ public void test_addAllILjava_util_Collection() {
+ Collection c = new Vector();
+ c.add(new Double(33));
+ c.add(10);
+ c.add("String");
+
+ AbstractList abstr = new AbstractList() {
+ @Override
+ public Object get(int arg0) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+
+ try {
+ abstr.addAll(0, null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ try {
+ abstr.addAll(0, c);
+ fail("UnsuportedOperationException expected");
+ } catch (UnsupportedOperationException ee) {
+ //expected
+ }
+
+ abstr = new AbstractList<Double>() {
+ @Override
+ public void add(int index, Double value) {
+ }
+
+ @Override
+ public Double get(int arg0) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+
+ try {
+ abstr.addAll(0, c);
+ fail("ClassCastException expected");
+ } catch (ClassCastException ee) {
+ //expectd
+ }
+
+ abstr = new AbstractList<Integer>() {
+ final int forbiddenValue = 33;
+ @Override
+ public void add(int index, Integer value) {
+ if (value == forbiddenValue) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public Integer get(int arg0) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+ c.clear();
+ c.add(new Integer(1));
+ c.add(new Integer(2));
+ c.add(new Integer(3));
+ c.add(new Integer(4));
+ c.add(new Integer(5));
+
+ abstr.addAll(0, c);
+
+ c.add(new Integer(33));
+
+ try {
+ abstr.addAll(0, c);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ee) {
+ //expected
+ }
+ abstr = new ArrayList();
+ abstr.addAll(0, c);
+
+ try {
+ abstr.addAll(-1, c);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ try {
+ abstr.addAll(abstr.size() + 1, c);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+ }
+
+ public void test_clear() {
+ AbstractList abstr = new ArrayList();
+
+ assertEquals(0, abstr.size());
+ abstr.add("String");
+ abstr.add("1");
+ abstr.add(2);
+ abstr.add(new Double(3));
+ assertEquals(4, abstr.size());
+ abstr.clear();
+ assertEquals(0, abstr.size());
+ }
+
+ public void test_equalsLjava_lang_Object() {
+ Collection c = new Vector();
+ c.add(new Double(33));
+ c.add(10);
+ c.add("String");
+
+ AbstractList abstr = new ArrayList();
+ AbstractList abstr1 = new ArrayList();
+
+ assertFalse(abstr.equals(this));
+ abstr.add(new Double(33));
+ abstr.add(10);
+ abstr.add("String");
+ assertTrue(abstr.equals(c));
+ abstr1.addAll(c);
+ assertTrue(abstr.equals(abstr1));
+ }
+
+ public void test_setILjava_lang_Object() {
+ Collection c = new Vector();
+ c.add(new Double(33));
+ c.add(10);
+ c.add("String");
+
+ AbstractList abstr1 = new ArrayList();
+ AbstractList abstr2 = new ArrayList();
+
+ abstr1.addAll(c);
+ abstr2.addAll(c);
+ assertTrue(abstr1.equals(abstr2));
+ abstr1.set(1, 1);
+ assertFalse(abstr1.equals(abstr2));
+
+ try {
+ abstr1.set(abstr1.size() + 1, 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ try {
+ abstr1.set(-1, 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException ee) {
+ //expected
+ }
+
+ AbstractList abstr = new AbstractList() {
+
+ @Override
+ public Object get(int index) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ };
+
+ try {
+ abstr.set(0, null);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException ee) {
+ //expected
+ }
+
+ abstr = new AbstractList<Double>() {
+ @Override
+ public Double set(int index, Double value) {
+ return value;
+ }
+
+ @Override
+ public Double get(int index) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+
+ try {
+ abstr.set(0, 1);
+ fail("ClassCastException expected");
+ } catch (ClassCastException ee) {
+ //expected
+ }
+
+ abstr = new AbstractList<Integer>() {
+ final int forbiddenValue = 33;
+ @Override
+ public Integer set(int index, Integer value) {
+ if (value == forbiddenValue) {
+ throw new IllegalArgumentException();
+ }
+ return value;
+ }
+
+ @Override
+ public Integer get(int index) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ };
+
+ try {
+ abstr.set(0, 33);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ee) {
+ //expected
+ }
+ }
+ class Mock_ArrayList extends ArrayList {
+ @Override
+ public void removeRange(int fromIndex, int toIndex) {
+ super.removeRange(fromIndex, toIndex);
+ }
+ }
+
+ public void test_removeRangeII() {
+ Mock_ArrayList al1 = new Mock_ArrayList();
+ al1.add(1);
+ al1.add(2);
+ al1.add(3);
+ al1.add(4);
+ al1.add(5);
+ Mock_ArrayList al2 = new Mock_ArrayList();
+
+ al2.add(1);
+ al2.add(5);
+ assertNotSame(al1,al2);
+ al1.removeRange(1, 4);
+ assertEquals(al1,al2);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModificationExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModificationExceptionTest.java
new file mode 100644
index 0000000..2bbcd1e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModificationExceptionTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+public class ConcurrentModificationExceptionTest extends
+ junit.framework.TestCase {
+
+ static public class CollectionModifier implements Runnable {
+ Collection col;
+
+ boolean keepGoing = true;
+
+ public CollectionModifier(Collection c) {
+ col = c;
+ }
+
+ public void stopNow() {
+ keepGoing = false;
+ }
+
+ public void run() {
+ Object someItem = new Integer(-1);
+ while (keepGoing) {
+ col.add(someItem);
+ col.remove(someItem);
+ }
+ }
+ }
+
+ /**
+ * java.util.ConcurrentModificationException#ConcurrentModificationException()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.ConcurrentModificationException()
+ Collection myCollection = new LinkedList();
+ Iterator myIterator = myCollection.iterator();
+ for (int counter = 0; counter < 50; counter++)
+ myCollection.add(new Integer(counter));
+ CollectionModifier cm = new CollectionModifier(myCollection);
+ Thread collectionSlapper = new Thread(cm);
+ try {
+ collectionSlapper.start();
+ while (myIterator.hasNext())
+ myIterator.next();
+ } catch (ConcurrentModificationException e) {
+ cm.stopNow();
+ return;
+ }
+ cm.stopNow();
+ // The exception should have been thrown--if the code flow makes it here
+ // the test has failed
+ fail("Failed to throw expected ConcurrentModificationException");
+ }
+
+ /**
+ * java.util.ConcurrentModificationException#ConcurrentModificationException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method
+ // java.util.ConcurrentModificationException(java.lang.String)
+ String errorMessage = "This is an error message";
+ try {
+ // This is here to stop "unreachable code" unresolved problem
+ if (true)
+ throw new ConcurrentModificationException(errorMessage);
+ } catch (ConcurrentModificationException e) {
+ assertTrue("Exception thrown without error message", e.getMessage()
+ .equals(errorMessage));
+ return;
+ }
+ fail("Failed to throw expected ConcurrentModificationException");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ControlTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ControlTest.java
new file mode 100644
index 0000000..d0b236d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ControlTest.java
@@ -0,0 +1,682 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.ResourceBundle.Control;
+import java.util.Scanner;
+import static java.util.ResourceBundle.Control.*;
+
+/**
+ * Test cases for java.util.ResourceBundle.Control
+ *
+ * @since 1.6
+ */
+public class ControlTest extends TestCase {
+
+ /**
+ * Control with format:FORMAT_PROPERTIES
+ */
+ private Control controlP;
+
+ /**
+ * Control with format:FORMAT_CLASS
+ */
+ private Control controlC;
+
+ /**
+ * Control with format:FORMAT_DEFAULT
+ */
+ private Control control;
+
+ /**
+ * {@link java.util.ResourceBundle.Control#Control()}.
+ */
+ @SuppressWarnings("nls")
+ public void test_Constructor() {
+
+ class SubControl extends Control {
+ SubControl() {
+ super();
+ }
+ }
+ Control subControl = new SubControl();
+ assertEquals(FORMAT_DEFAULT, subControl.getFormats(""));
+ assertFalse(control.equals(subControl));
+ }
+
+ /**
+ * Test for all the public constants.
+ *
+ * {@link java.util.ResourceBundle.Control#FORMAT_CLASS}
+ * {@link java.util.ResourceBundle.Control#FORMAT_DEFAULT}
+ * {@link java.util.ResourceBundle.Control#FORMAT_PROPERTIES}
+ * {@link java.util.ResourceBundle.Control#TTL_DONT_CACHE}
+ * {@link java.util.ResourceBundle.Control#TTL_NO_EXPIRATION_CONTROL}
+ */
+ @SuppressWarnings("nls")
+ public void test_Constants() {
+ List<String> list = FORMAT_CLASS;
+ assertEquals(1, list.size());
+ assertEquals("java.class", list.get(0));
+ list = FORMAT_PROPERTIES;
+ assertEquals(1, list.size());
+ assertEquals("java.properties", list.get(0));
+ list = FORMAT_DEFAULT;
+ assertEquals(2, list.size());
+ assertEquals("java.class", list.get(0));
+ assertEquals("java.properties", list.get(1));
+ try {
+ FORMAT_CLASS.add("");
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ FORMAT_DEFAULT.add("");
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ FORMAT_PROPERTIES.add("");
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ Class<?> unmodifiableListClass = Collections.unmodifiableList(
+ new ArrayList<String>()).getClass();
+ assertEquals(FORMAT_CLASS.getClass(), unmodifiableListClass);
+ assertEquals(FORMAT_DEFAULT.getClass(), unmodifiableListClass);
+ assertEquals(FORMAT_PROPERTIES.getClass(), unmodifiableListClass);
+ assertEquals(-1L, TTL_DONT_CACHE);
+ assertEquals(-2L, TTL_NO_EXPIRATION_CONTROL);
+ }
+
+ /**
+ * {@link java.util.ResourceBundle.Control#getControl(java.util.List)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_getControl_LList() {
+ // singleton
+ assertSame(control, Control.getControl(FORMAT_DEFAULT));
+ assertSame(controlC, Control.getControl(FORMAT_CLASS));
+ assertSame(controlP, Control.getControl(FORMAT_PROPERTIES));
+
+ // class
+ assertTrue(control.getClass() == Control.class);
+ assertTrue(controlC.getClass() != Control.class);
+ assertTrue(controlP.getClass() != Control.class);
+
+ // formats: need not same, just need equal
+ List<String> list = new ArrayList<String>(FORMAT_CLASS);
+ assertSame(controlC, Control.getControl(list));
+ // can add
+ list.add(FORMAT_PROPERTIES.get(0));
+ assertSame(control, Control.getControl(list));
+
+ // exceptions
+ try {
+ Control.getControl(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ list = new ArrayList<String>();
+ try {
+ Control.getControl(list);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ list = new ArrayList<String>(FORMAT_CLASS);
+ // java.class -> JAVA.CLASS
+ list.set(0, list.get(0).toUpperCase());
+ try {
+ Control.getControl(list);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ list = new ArrayList<String>(FORMAT_CLASS);
+ list.add("");
+ try {
+ Control.getControl(list);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ResourceBundle.Control#getNoFallbackControl(java.util.List)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_getNoFallbackControl_LList() {
+ assertNotSame(control, Control.getNoFallbackControl(FORMAT_DEFAULT));
+ assertNotSame(controlC, Control.getNoFallbackControl(FORMAT_CLASS));
+ assertNotSame(controlP, Control.getNoFallbackControl(FORMAT_PROPERTIES));
+ controlP = Control.getNoFallbackControl(FORMAT_PROPERTIES);
+ controlC = Control.getNoFallbackControl(FORMAT_CLASS);
+ control = Control.getNoFallbackControl(FORMAT_DEFAULT);
+ // singleton
+ assertSame(control, Control.getNoFallbackControl(FORMAT_DEFAULT));
+ assertSame(controlC, Control.getNoFallbackControl(FORMAT_CLASS));
+ assertSame(controlP, Control.getNoFallbackControl(FORMAT_PROPERTIES));
+
+ // class
+ assertTrue(control.getClass() != Control.class);
+ assertTrue(controlC.getClass() != Control.class);
+ assertTrue(controlP.getClass() != Control.class);
+
+ // format
+ assertEquals(FORMAT_CLASS, controlC.getFormats(""));
+ assertEquals(FORMAT_DEFAULT, control.getFormats(""));
+ assertEquals(FORMAT_PROPERTIES, controlP.getFormats(""));
+
+ // no fall back locale
+ Locale defaultLocale = Locale.getDefault();
+ Locale.setDefault(new Locale("TestLanguage", "TestCountry", "Var"));
+ assertNull(control.getFallbackLocale("message", Locale.US));
+ try {
+ control.getFallbackLocale("message", null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ control.getFallbackLocale(null, Locale.US);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ Locale.setDefault(defaultLocale);
+
+ // formats: need not same, just need equal
+ List<String> list = new ArrayList<String>(FORMAT_CLASS);
+ assertSame(controlC, Control.getNoFallbackControl(list));
+ // can add
+ list.add(FORMAT_PROPERTIES.get(0));
+ assertSame(control, Control.getNoFallbackControl(list));
+
+ // exceptions
+ try {
+ Control.getNoFallbackControl(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ list = new ArrayList<String>();
+ try {
+ Control.getNoFallbackControl(list);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ list = new ArrayList<String>(FORMAT_CLASS);
+ // java.class -> JAVA.CLASS
+ list.set(0, list.get(0).toUpperCase());
+ try {
+ Control.getNoFallbackControl(list);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ list = new ArrayList<String>(FORMAT_CLASS);
+ list.add("");
+ try {
+ Control.getNoFallbackControl(list);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ResourceBundle.Control#getFormats(java.lang.String)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_getFormats_LString() {
+ assertEquals(FORMAT_DEFAULT, control.getFormats(""));
+ assertEquals(FORMAT_PROPERTIES, controlP.getFormats(""));
+ assertEquals(FORMAT_CLASS, controlC.getFormats(""));
+ try {
+ controlC.getFormats(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ResourceBundle.Control#getCandidateLocales(java.lang.String, java.util.Locale)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_getCandidateLocales_LStringLLocale() {
+ // the ResourceBundle for this baseName and Locale does not exists
+ List<Locale> result = control.getCandidateLocales("baseName",
+ new Locale("one", "two", "three"));
+ assertEquals(4, result.size());
+ Locale locale = result.get(0);
+ assertEquals("one", locale.getLanguage());
+ assertEquals("TWO", locale.getCountry());
+ assertEquals("three", locale.getVariant());
+ assertEquals(new Locale("one", "TWO"), result.get(1));
+ assertEquals(new Locale("one"), result.get(2));
+ assertSame(Locale.ROOT, result.get(3));
+ // ArrayList is not immutable
+ assertTrue(ArrayList.class == result.getClass());
+
+ result = control.getCandidateLocales("baseName", new Locale("one",
+ "two", ""));
+ assertEquals(new Locale("one", "TWO"), result.get(0));
+ assertEquals(new Locale("one"), result.get(1));
+ assertSame(Locale.ROOT, result.get(2));
+
+ result = control.getCandidateLocales("baseName", new Locale("one", "",
+ "three"));
+ assertEquals(new Locale("one", "", "three"), result.get(0));
+ assertEquals(new Locale("one"), result.get(1));
+ assertSame(Locale.ROOT, result.get(2));
+
+ result = control.getCandidateLocales("baseName", new Locale("", "two",
+ "three"));
+ assertEquals(new Locale("", "TWO", "three"), result.get(0));
+ assertEquals(new Locale("", "TWO"), result.get(1));
+ assertSame(Locale.ROOT, result.get(2));
+
+ result = control.getCandidateLocales("baseName", new Locale("", "",
+ "three"));
+ assertEquals(new Locale("", "", "three"), result.get(0));
+ assertSame(Locale.ROOT, result.get(1));
+
+ result = control.getCandidateLocales("baseName", new Locale("", "two",
+ ""));
+ assertEquals(new Locale("", "TWO"), result.get(0));
+ assertSame(Locale.ROOT, result.get(1));
+
+ result = control.getCandidateLocales("baseName", Locale.ROOT);
+ assertSame(Locale.ROOT, result.get(0));
+
+ try {
+ control.getCandidateLocales(null, Locale.US);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ control.getCandidateLocales("baseName", null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ResourceBundle.Control#getFallbackLocale(java.lang.String, java.util.Locale)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_getFallbackLocale_LStringLLocale() {
+ Locale defaultLocale = Locale.getDefault();
+ Locale testLocale = new Locale("TestLanguage", "TestCountry", "Var");
+ Locale.setDefault(testLocale);
+ assertSame(testLocale, control.getFallbackLocale("baseName",
+ Locale.ROOT));
+ assertSame(testLocale, control.getFallbackLocale("baseName", Locale.US));
+ assertSame(null, control.getFallbackLocale("baseName", testLocale));
+ try {
+ control.getFallbackLocale(null, Locale.US);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ control.getFallbackLocale("baseName", null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ // restore
+ Locale.setDefault(defaultLocale);
+ }
+
+ @SuppressWarnings("nls")
+ static File copyFile(final URL src) throws IOException {
+ String tail = src.getFile().split("hyts_resource")[1];
+ String tmpdir = System.getProperty("java.io.tmpdir");
+ if (null == tmpdir) {
+ return null;
+ }
+ String copyName = tmpdir + File.separator + "hyts_resource_copy" + tail;
+ File copy = new File(copyName);
+ if (copy.exists()) {
+ copy.delete();
+ }
+ copy.createNewFile();
+ copy.deleteOnExit();
+
+ Reader in = new InputStreamReader(src.openStream());
+ Writer out = new FileWriter(copy);
+ int c;
+ while ((c = in.read()) != -1) {
+ out.write(c);
+ }
+ in.close();
+ out.close();
+ return copy;
+ }
+
+ static class SubRBStaticPrivate extends ListResourceBundle {
+ private SubRBStaticPrivate() {
+ super();
+ }
+
+ @Override
+ protected Object[][] getContents() {
+ return null;
+ }
+ }
+
+ /*
+ * change the value in the .properties file
+ */
+ @SuppressWarnings("nls")
+ static void changeProperties(File file) throws FileNotFoundException {
+ String newValue = "property=changedValue";
+ PrintWriter writer = new PrintWriter(file);
+ writer.write(newValue);
+ writer.flush();
+ writer.close();
+ Scanner scanner = new Scanner(file);
+ assertEquals(newValue, scanner.nextLine());
+ scanner.close();
+ }
+
+ /**
+ * {@link java.util.ResourceBundle.Control#getTimeToLive(java.lang.String, java.util.Locale)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_getTimeToLive_LStringLLocale() {
+ assertEquals(TTL_NO_EXPIRATION_CONTROL, control.getTimeToLive(
+ "baseName", Locale.US));
+ try {
+ control.getTimeToLive(null, Locale.US);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ control.getTimeToLive("baseName", null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @throws Exception
+ * {@link java.util.ResourceBundle.Control#needsReload(java.lang.String, java.util.Locale, java.lang.String, java.lang.ClassLoader, java.util.ResourceBundle, long)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_needsReload_LStringLLocaleLStringLClassLoaderResourceBundleJ()
+ throws Exception {
+ String className = "tests.support.Support_TestResource";
+ String propertiesName = Support_Resources.RESOURCE_PACKAGE_NAME
+ + ".hyts_resource";
+ String propertiesNameCopy = "hyts_resource_copy";
+ String CLASS = "java.class";
+ String PROPERTIES = "java.properties";
+ Locale frFR = new Locale("fr", "FR");
+ ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
+ ClassLoader URLLoader = systemLoader;
+ ResourceBundle bundle = null;
+ long time = 0L;
+ final URL srcFile = URLLoader.getResource(control.toResourceName(
+ control.toBundleName(propertiesName, frFR), "properties"));
+ assertNotNull(srcFile);
+ final File copyFile = copyFile(srcFile);
+
+ // 1. format = "java.properties"
+ if (null != URLLoader.getResourceAsStream(copyFile.toURL().toString())) {
+ Thread.sleep(1000);
+ bundle = control.newBundle(propertiesNameCopy, frFR, PROPERTIES,
+ URLLoader, false);
+ time = System.currentTimeMillis();
+ assertTrue(bundle.getClass() == PropertyResourceBundle.class);
+ assertEquals("fr_FR_resource", bundle.getString("property"));
+ assertFalse(control.needsReload(propertiesNameCopy, frFR,
+ PROPERTIES, URLLoader, bundle, time));
+ // change the file
+ Thread.sleep(2000);
+ changeProperties(copyFile);
+ assertTrue(control.needsReload(propertiesNameCopy, frFR,
+ PROPERTIES, URLLoader, bundle, time));
+ // detect again
+ assertTrue(control.needsReload(propertiesNameCopy, frFR,
+ PROPERTIES, URLLoader, bundle, time));
+ // long long ago
+ assertTrue(control.needsReload(propertiesNameCopy, frFR,
+ PROPERTIES, URLLoader, bundle, 2006L));
+ // other loader
+ assertFalse(control.needsReload(propertiesNameCopy, frFR,
+ PROPERTIES, systemLoader, bundle, time));
+ // other bundle
+ ResourceBundle otherBundle = control.newBundle(propertiesName,
+ Locale.ROOT, PROPERTIES, systemLoader, false);
+ assertEquals("parent", otherBundle.getString("property"));
+ assertTrue(control.needsReload(propertiesNameCopy, frFR,
+ PROPERTIES, URLLoader, otherBundle, time));
+ otherBundle = control.newBundle(propertiesName, Locale.ROOT,
+ PROPERTIES, URLLoader, false);
+ assertEquals("resource", otherBundle.getString("property"));
+ assertTrue(control.needsReload(propertiesNameCopy, frFR,
+ PROPERTIES, URLLoader, otherBundle, time));
+ // other time
+ assertFalse(control.needsReload(propertiesNameCopy, frFR,
+ PROPERTIES, URLLoader, bundle, System.currentTimeMillis()));
+ } else {
+ System.err
+ .println("Can not find the test file, some code of this test 'test_needsReload_LStringLLocaleLStringLClassLoaderResourceBundleJ' did not run.");
+
+ }
+
+ // 2. format = "java.class"
+ bundle = control.newBundle(className, frFR, CLASS, systemLoader, false);
+ time = System.currentTimeMillis();
+ assertEquals("frFRValue3", bundle.getString("parent3"));
+ assertFalse(control.needsReload(className, frFR, CLASS, systemLoader,
+ bundle, time));
+ // exceptions
+ control.needsReload(propertiesName, frFR, PROPERTIES, URLLoader,
+ bundle, time);
+ try {
+ control
+ .needsReload(null, frFR, PROPERTIES, URLLoader, bundle,
+ time);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ control.needsReload(propertiesName, null, PROPERTIES, URLLoader,
+ bundle, time);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ control.needsReload(propertiesName, frFR, null, URLLoader, bundle,
+ time);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ control.needsReload(propertiesName, frFR, PROPERTIES, null, bundle,
+ time);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ control.needsReload(propertiesName, frFR, PROPERTIES, URLLoader,
+ null, time);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ResourceBundle.Control#toBundleName(java.lang.String, java.util.Locale)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_toBundleName_LStringLLocale() {
+ assertEquals("baseName_one_TWO_three", control.toBundleName("baseName",
+ new Locale("one", "two", "three")));
+ assertEquals("baseName_one_TWO", control.toBundleName("baseName",
+ new Locale("one", "two")));
+ assertEquals("baseName_one__three", control.toBundleName("baseName",
+ new Locale("one", "", "three")));
+ assertEquals("baseName__TWO_three", control.toBundleName("baseName",
+ new Locale("", "two", "three")));
+ assertEquals("baseName_one", control.toBundleName("baseName",
+ new Locale("one", "", "")));
+ assertEquals("baseName___three", control.toBundleName("baseName",
+ new Locale("", "", "three")));
+ assertEquals("baseName__TWO", control.toBundleName("baseName",
+ new Locale("", "two", "")));
+ assertEquals("baseName", control.toBundleName("baseName", new Locale(
+ "", "", "")));
+ assertEquals("baseName", control.toBundleName("baseName", Locale.ROOT));
+ assertEquals("_one_TWO_three", control.toBundleName("", new Locale(
+ "one", "two", "three")));
+ assertEquals("", control.toBundleName("", Locale.ROOT));
+
+ assertEquals("does.not.exists_one_TWO_three", control.toBundleName(
+ "does.not.exists", new Locale("one", "two", "three")));
+ assertEquals("does/not/exists_one_TWO_three", control.toBundleName(
+ "does/not/exists", new Locale("one", "two", "three")));
+ assertEquals("does_not_exists__one_TWO_three", control.toBundleName(
+ "does_not_exists_", new Locale("one", "two", "three")));
+
+ assertEquals("...", control.toBundleName("...", Locale.ROOT));
+ assertEquals("s/./\\//g", control
+ .toBundleName("s/./\\//g", Locale.ROOT));
+ assertEquals("123_one", control.toBundleName("123", new Locale("one")));
+
+ try {
+ control.toBundleName(null, Locale.US);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ control.toBundleName("baseName", null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.ResourceBundle.Control#toResourceName(java.lang.String, java.lang.String)}.
+ */
+ @SuppressWarnings("nls")
+ public void test_toResourceNameLStringLString() {
+ assertEquals("does/not/exists_language_country.someSuffix", control
+ .toResourceName("does.not.exists_language_country",
+ "someSuffix"));
+ assertEquals("does/not/exists_language_country.someSuffix", control
+ .toResourceName("does/not/exists_language_country",
+ "someSuffix"));
+ assertEquals("does///not//exists_language/country.someSuffix", control
+ .toResourceName("does...not..exists_language.country",
+ "someSuffix"));
+ assertEquals("does\\not\\exists_language_country.someSuffix", control
+ .toResourceName("does\\not\\exists_language_country",
+ "someSuffix"));
+ assertEquals("does/not/exists_language_country/.someSuffix", control
+ .toResourceName("does.not.exists_language_country.",
+ "someSuffix"));
+ assertEquals("does/not/exists_language_country../someSuffix", control
+ .toResourceName("does.not.exists_language_country",
+ "./someSuffix"));
+
+ assertEquals("///.//", control.toResourceName("...", "//"));
+ assertEquals("///...", control.toResourceName("///", ".."));
+ assertEquals("123...", control.toResourceName("123", ".."));
+ assertEquals("base.", control.toResourceName("base", ""));
+ assertEquals(".suffix", control.toResourceName("", "suffix"));
+ assertEquals(".", control.toResourceName("", ""));
+
+ try {
+ control.toResourceName(null, "suffix");
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ control.toResourceName("bundleName", null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ controlP = Control.getControl(FORMAT_PROPERTIES);
+ controlC = Control.getControl(FORMAT_CLASS);
+ control = Control.getControl(FORMAT_DEFAULT);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java
new file mode 100644
index 0000000..07256e4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java
@@ -0,0 +1,405 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Currency;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+
+public class CurrencyTest extends junit.framework.TestCase {
+
+ private Locale originalLocale;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ originalLocale = Locale.getDefault();
+ }
+
+ @Override
+ protected void tearDown() {
+ Locale.setDefault(originalLocale);
+ }
+
+ /**
+ * java.util.Currency#getInstance(java.lang.String)
+ */
+ public void test_getInstanceLjava_lang_String() {
+ // see test_getInstanceLjava_util_Locale() tests
+ }
+
+ /**
+ * java.util.Currency#getInstance(java.util.Locale)
+ */
+ public void test_getInstanceLjava_util_Locale() {
+ /*
+ * the behaviour in all these three cases should be the same since this
+ * method ignores language and variant component of the locale.
+ */
+ Currency c0 = Currency.getInstance("CAD");
+ Currency c1 = Currency.getInstance(new Locale("en", "CA"));
+ assertTrue(
+ "Currency.getInstance(new Locale(\"en\",\"CA\")) isn't equal to Currency.getInstance(\"CAD\")",
+ c1 == c0);
+ Currency c2 = Currency.getInstance(new Locale("fr", "CA"));
+ assertTrue(
+ "Currency.getInstance(new Locale(\"fr\",\"CA\")) isn't equal to Currency.getInstance(\"CAD\")",
+ c2 == c0);
+ Currency c3 = Currency.getInstance(new Locale("", "CA"));
+ assertTrue(
+ "Currency.getInstance(new Locale(\"\",\"CA\")) isn't equal to Currency.getInstance(\"CAD\")",
+ c3 == c0);
+
+ c0 = Currency.getInstance("JPY");
+ c1 = Currency.getInstance(new Locale("ja", "JP"));
+ assertTrue(
+ "Currency.getInstance(new Locale(\"ja\",\"JP\")) isn't equal to Currency.getInstance(\"JPY\")",
+ c1 == c0);
+ c2 = Currency.getInstance(new Locale("", "JP"));
+ assertTrue(
+ "Currency.getInstance(new Locale(\"\",\"JP\")) isn't equal to Currency.getInstance(\"JPY\")",
+ c2 == c0);
+ c3 = Currency.getInstance(new Locale("bogus", "JP"));
+ assertTrue(
+ "Currency.getInstance(new Locale(\"bogus\",\"JP\")) isn't equal to Currency.getInstance(\"JPY\")",
+ c3 == c0);
+
+ Locale localeGu = new Locale("gu", "IN");
+ Currency cGu = Currency.getInstance(localeGu);
+ Locale localeKn = new Locale("kn", "IN");
+ Currency cKn = Currency.getInstance(localeKn);
+ assertTrue("Currency.getInstance(Locale_" + localeGu.toString() + "))"
+ + "isn't equal to " + "Currency.getInstance(Locale_"
+ + localeKn.toString() + "))", cGu == cKn);
+
+ // some teritories do not have currencies, like Antarctica
+ Locale loc = new Locale("", "AQ");
+ try {
+ Currency curr = Currency.getInstance(loc);
+ assertNull(
+ "Currency.getInstance(new Locale(\"\", \"AQ\")) did not return null",
+ curr);
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException " + e);
+ }
+
+ // unsupported/legacy iso3 countries
+ loc = new Locale("", "ZR");
+ try {
+ Currency curr = Currency.getInstance(loc);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ loc = new Locale("", "ZAR");
+ try {
+ Currency curr = Currency.getInstance(loc);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ loc = new Locale("", "FX");
+ try {
+ Currency curr = Currency.getInstance(loc);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ loc = new Locale("", "FXX");
+ try {
+ Currency curr = Currency.getInstance(loc);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * java.util.Currency#getSymbol()
+ */
+ public void test_getSymbol() {
+ Currency currK = Currency.getInstance("KRW");
+ Currency currI = Currency.getInstance("IEP");
+ Currency currUS = Currency.getInstance("USD");
+
+ Locale.setDefault(Locale.US);
+ // BEGIN android-changed
+ // KRW currency symbol is \u20a9 since CLDR1.7 release.
+ assertEquals("currK.getSymbol()", "\u20a9", currK.getSymbol());
+ // IEP currency symbol is IEP since CLDR2.0 release.
+ assertEquals("currI.getSymbol()", "IEP", currI.getSymbol());
+ // END android-changed
+ assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
+
+ Locale.setDefault(new Locale("en", "IE"));
+ // BEGIN android-changed
+ assertEquals("currK.getSymbol()", "\u20a9", currK.getSymbol());
+ assertEquals("currI.getSymbol()", "IEP", currI.getSymbol());
+ assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
+ // END android-changed
+
+ // Test what happens if the default is an invalid locale, one with the country Korea (KR)
+ // but a currently unsupported language. "kr" == Kanuri (Korean is actually "ko").
+ // All these values are those defined in the "root" locale or the currency code if one isn't
+ // defined.
+ Locale.setDefault(new Locale("kr", "KR"));
+ // BEGIN android-changed
+ assertEquals("currK.getSymbol()", "\u20a9", currK.getSymbol());
+ assertEquals("currI.getSymbol()", "IEP", currI.getSymbol());
+ assertEquals("currUS.getSymbol()", "US$", currUS.getSymbol());
+ // END android-changed
+ }
+
+ /**
+ * java.util.Currency#getSymbol(java.util.Locale)
+ */
+ public void test_getSymbolLjava_util_Locale() {
+ //Tests was simplified because java specification not
+ // includes strong requirements for returning symbol.
+ // on android platform used wrong character for yen
+ // sign: \u00a5 instead of \uffe5
+ Locale[] desiredLocales = new Locale[]{
+ Locale.JAPAN, Locale.JAPANESE,
+ Locale.FRANCE, Locale.FRENCH,
+ Locale.US, Locale.UK,
+ Locale.CANADA, Locale.CANADA_FRENCH,
+ Locale.ENGLISH,
+ new Locale("ja", "JP"), new Locale("", "JP"),
+
+ new Locale("fr", "FR"), new Locale("", "FR"),
+
+ new Locale("en", "US"), new Locale("", "US"),
+ new Locale("es", "US"), new Locale("ar", "US"),
+ new Locale("ja", "US"),
+
+ new Locale("en", "CA"), new Locale("fr", "CA"),
+ new Locale("", "CA"), new Locale("ar", "CA"),
+
+ new Locale("ja", "JP"), new Locale("", "JP"),
+ new Locale("ar", "JP"),
+
+ new Locale("ja", "AE"), new Locale("en", "AE"),
+ new Locale("ar", "AE"),
+
+ new Locale("da", "DK"), new Locale("", "DK"),
+
+ new Locale("da", ""), new Locale("ja", ""),
+ new Locale("en", "")};
+
+ Set<Locale> availableLocales = new HashSet<Locale>(Arrays.asList(Locale.getAvailableLocales()));
+
+ ArrayList<Locale> locales = new ArrayList<Locale>();
+ for (Locale desiredLocale : desiredLocales) {
+ if (availableLocales.contains(desiredLocale)) {
+ locales.add(desiredLocale);
+ }
+ }
+
+ Locale[] loc1 = locales.toArray(new Locale[locales.size()]);
+
+ String[] euro = new String[] {"EUR", "\u20ac"};
+ // \u00a5 and \uffe5 are actually the same symbol, just different code points.
+ // But the RI returns the \uffe5 and Android returns those with \u00a5
+ String[] yen = new String[] {"JPY", "\u00a5", "\u00a5JP", "JP\u00a5", "\uffe5", "\uffe5JP", "JP\uffe5"};
+ String[] dollar = new String[] {"USD", "$", "US$", "$US"};
+ // BEGIN android-changed
+ // Starting CLDR 1.7 release, currency symbol for CAD changed to CA$ in some locales such as ja.
+ String[] cDollar = new String[] {"CA$", "CAD", "$", "Can$", "$CA"};
+ // END android-changed
+
+ Currency currE = Currency.getInstance("EUR");
+ Currency currJ = Currency.getInstance("JPY");
+ Currency currUS = Currency.getInstance("USD");
+ Currency currCA = Currency.getInstance("CAD");
+
+ int i, j, k;
+ boolean flag;
+
+ for(k = 0; k < loc1.length; k++) {
+ Locale.setDefault(loc1[k]);
+
+ for (i = 0; i < loc1.length; i++) {
+ flag = false;
+ for (j = 0; j < euro.length; j++) {
+ if (currE.getSymbol(loc1[i]).equals(euro[j])) {
+ flag = true;
+ break;
+ }
+ }
+ assertTrue("Default Locale is: " + Locale.getDefault()
+ + ". For locale " + loc1[i]
+ + " the Euro currency returned "
+ + currE.getSymbol(loc1[i])
+ + ". Expected was one of these: "
+ + Arrays.toString(euro), flag);
+ }
+
+ for (i = 0; i < loc1.length; i++) {
+ flag = false;
+ for (j = 0; j < yen.length; j++) {
+ if (currJ.getSymbol(loc1[i]).equals(yen[j])) {
+ flag = true;
+ break;
+ }
+ }
+ assertTrue("Default Locale is: " + Locale.getDefault()
+ + ". For locale " + loc1[i]
+ + " the Yen currency returned "
+ + currJ.getSymbol(loc1[i])
+ + ". Expected was one of these: "
+ + Arrays.toString(yen), flag);
+ }
+
+ for (i = 0; i < loc1.length; i++) {
+ flag = false;
+ for (j = 0; j < dollar.length; j++) {
+ if (currUS.getSymbol(loc1[i]).equals(dollar[j])) {
+ flag = true;
+ break;
+ }
+ }
+ assertTrue("Default Locale is: " + Locale.getDefault()
+ + ". For locale " + loc1[i]
+ + " the Dollar currency returned "
+ + currUS.getSymbol(loc1[i])
+ + ". Expected was one of these: "
+ + Arrays.toString(dollar), flag);
+ }
+
+ for (i = 0; i < loc1.length; i++) {
+ flag = false;
+ for (j = 0; j < cDollar.length; j++) {
+ if (currCA.getSymbol(loc1[i]).equals(cDollar[j])) {
+ flag = true;
+ break;
+ }
+ }
+ assertTrue("Default Locale is: " + Locale.getDefault()
+ + ". For locale " + loc1[i]
+ + " the Canadian Dollar currency returned "
+ + currCA.getSymbol(loc1[i])
+ + ". Expected was one of these: "
+ + Arrays.toString(cDollar), flag);
+ }
+ }
+ }
+
+ /**
+ * java.util.Currency#getDefaultFractionDigits()
+ */
+ public void test_getDefaultFractionDigits() {
+
+ Currency c1 = Currency.getInstance("TND");
+ c1.getDefaultFractionDigits();
+ assertEquals(" Currency.getInstance(\"" + c1
+ + "\") returned incorrect number of digits. ", 3, c1
+ .getDefaultFractionDigits());
+
+ Currency c2 = Currency.getInstance("EUR");
+ c2.getDefaultFractionDigits();
+ assertEquals(" Currency.getInstance(\"" + c2
+ + "\") returned incorrect number of digits. ", 2, c2
+ .getDefaultFractionDigits());
+
+ Currency c3 = Currency.getInstance("JPY");
+ c3.getDefaultFractionDigits();
+ assertEquals(" Currency.getInstance(\"" + c3
+ + "\") returned incorrect number of digits. ", 0, c3
+ .getDefaultFractionDigits());
+
+ Currency c4 = Currency.getInstance("XXX");
+ c4.getDefaultFractionDigits();
+ assertEquals(" Currency.getInstance(\"" + c4
+ + "\") returned incorrect number of digits. ", -1, c4
+ .getDefaultFractionDigits());
+ }
+
+ /**
+ * java.util.Currency#getCurrencyCode() Note: lines under remarks
+ * (Locale.CHINESE, Locale.ENGLISH, Locale.FRENCH, Locale.GERMAN,
+ * Locale.ITALIAN, Locale.JAPANESE, Locale.KOREAN) raises exception
+ * on SUN VM
+ */
+ public void test_getCurrencyCode() {
+ final Collection<Locale> locVal = Arrays.asList(
+ Locale.CANADA,
+ Locale.CANADA_FRENCH,
+ Locale.CHINA,
+ // Locale.CHINESE,
+ // Locale.ENGLISH,
+ Locale.FRANCE,
+ // Locale.FRENCH,
+ // Locale.GERMAN,
+ Locale.GERMANY,
+ // Locale.ITALIAN,
+ Locale.ITALY, Locale.JAPAN,
+ // Locale.JAPANESE,
+ Locale.KOREA,
+ // Locale.KOREAN,
+ Locale.PRC, Locale.SIMPLIFIED_CHINESE, Locale.TAIWAN, Locale.TRADITIONAL_CHINESE,
+ Locale.UK, Locale.US);
+ final Collection<String> locDat = Arrays.asList("CAD", "CAD", "CNY", "EUR", "EUR", "EUR",
+ "JPY", "KRW", "CNY", "CNY", "TWD", "TWD", "GBP", "USD");
+
+ Iterator<String> dat = locDat.iterator();
+ for (Locale l : locVal) {
+ String d = dat.next().trim();
+ assertEquals("For locale " + l + " currency code wrong", Currency.getInstance(l)
+ .getCurrencyCode(), d);
+ }
+ }
+
+ /**
+ * java.util.Currency#toString() Note: lines under remarks
+ * (Locale.CHINESE, Locale.ENGLISH, Locale.FRENCH, Locale.GERMAN,
+ * Locale.ITALIAN, Locale.JAPANESE, Locale.KOREAN) raises exception
+ * on SUN VM
+ */
+ public void test_toString() {
+ final Collection<Locale> locVal = Arrays.asList(
+ Locale.CANADA,
+ Locale.CANADA_FRENCH,
+ Locale.CHINA,
+ // Locale.CHINESE,
+ // Locale.ENGLISH,
+ Locale.FRANCE,
+ // Locale.FRENCH,
+ // Locale.GERMAN,
+ Locale.GERMANY,
+ // Locale.ITALIAN,
+ Locale.ITALY, Locale.JAPAN,
+ // Locale.JAPANESE,
+ Locale.KOREA,
+ // Locale.KOREAN,
+ Locale.PRC, Locale.SIMPLIFIED_CHINESE, Locale.TAIWAN, Locale.TRADITIONAL_CHINESE,
+ Locale.UK, Locale.US);
+ final Collection<String> locDat = Arrays.asList("CAD", "CAD", "CNY", "EUR", "EUR", "EUR",
+ "JPY", "KRW", "CNY", "CNY", "TWD", "TWD", "GBP", "USD");
+
+ Iterator<String> dat = locDat.iterator();
+ for (Locale l : locVal) {
+ String d = dat.next().trim();
+ assertEquals("For locale " + l + " Currency.toString method returns wrong value",
+ Currency.getInstance(l).toString(), d);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/DateTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/DateTest.java
new file mode 100644
index 0000000..0ce971d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/DateTest.java
@@ -0,0 +1,520 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class DateTest extends junit.framework.TestCase {
+
+ /**
+ * java.util.Date#Date()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.Date()
+ GregorianCalendar gc = new GregorianCalendar(1998, Calendar.OCTOBER,
+ 13, 19, 9);
+ long oldTime = gc.getTime().getTime();
+ long now = new Date().getTime();
+ assertTrue("Created incorrect date: " + oldTime + " now: " + now,
+ oldTime < now);
+ }
+
+ /**
+ * java.util.Date#Date(int, int, int)
+ */
+ public void test_ConstructorIII() {
+ // Test for method java.util.Date(int, int, int)
+ Date d1 = new Date(70, 0, 1); // the epoch + local time
+
+ // the epoch + local time
+ Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000);
+
+ assertTrue("Created incorrect date", d1.equals(d2));
+
+ Date date = new Date(99, 5, 22);
+ Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 22);
+ assertTrue("Wrong time zone", date.equals(cal.getTime()));
+ }
+
+ /**
+ * java.util.Date#Date(int, int, int, int, int)
+ */
+ public void test_ConstructorIIIII() {
+ // Test for method java.util.Date(int, int, int, int, int)
+
+ // the epoch + local time + (1 hour and 1 minute)
+ Date d1 = new Date(70, 0, 1, 1, 1);
+
+ // the epoch + local time + (1 hour and 1 minute)
+ Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000 + 60 * 60
+ * 1000 + 60 * 1000);
+
+ assertTrue("Created incorrect date", d1.equals(d2));
+ }
+
+ /**
+ * java.util.Date#Date(int, int, int, int, int, int)
+ */
+ public void test_ConstructorIIIIII() {
+ // Test for method java.util.Date(int, int, int, int, int, int)
+
+ // the epoch + local time + (1 hour and 1 minute + 1 second)
+ Date d1 = new Date(70, 0, 1, 1, 1, 1);
+
+ // the epoch + local time + (1 hour and 1 minute + 1 second)
+ Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000 + 60 * 60
+ * 1000 + 60 * 1000 + 1000);
+
+ assertTrue("Created incorrect date", d1.equals(d2));
+ }
+
+ /**
+ * java.util.Date#Date(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.util.Date(java.lang.String)
+ Date d1 = new Date("January 1, 1970, 00:00:00 GMT"); // the epoch
+ Date d2 = new Date(0); // the epoch
+ assertTrue("Created incorrect date", d1.equals(d2));
+
+ try {
+ // Regression for HARMONY-238
+ new Date(null);
+ fail("Constructor Date((String)null) should "
+ + "throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Date#after(java.util.Date)
+ */
+ public void test_afterLjava_util_Date() {
+ // Test for method boolean java.util.Date.after(java.util.Date)
+ Date d1 = new Date(0);
+ Date d2 = new Date(1900000);
+ assertTrue("Older was returned as newer", d2.after(d1));
+ assertTrue("Newer was returned as older", !d1.after(d2));
+
+ try {
+ d1.after(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Date#before(java.util.Date)
+ */
+ public void test_beforeLjava_util_Date() {
+ // Test for method boolean java.util.Date.before(java.util.Date)
+ Date d1 = new Date(0);
+ Date d2 = new Date(1900000);
+ assertTrue("Older was returned as newer", !d2.before(d1));
+ assertTrue("Newer was returned as older", d1.before(d2));
+
+ try {
+ d1.before(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Date#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.Date.clone()
+ Date d1 = new Date(100000);
+ Date d2 = (Date) d1.clone();
+ assertTrue(
+ "Cloning date results in same reference--new date is equivalent",
+ d1 != d2);
+ assertTrue("Cloning date results unequal date", d1.equals(d2));
+ }
+
+ /**
+ * java.util.Date#compareTo(java.util.Date)
+ */
+ public void test_compareToLjava_util_Date() {
+ // Test for method int java.util.Date.compareTo(java.util.Date)
+ final int someNumber = 10000;
+ Date d1 = new Date(someNumber);
+ Date d2 = new Date(someNumber);
+ Date d3 = new Date(someNumber + 1);
+ Date d4 = new Date(someNumber - 1);
+ assertEquals("Comparing a date to itself did not answer zero", 0, d1
+ .compareTo(d1));
+ assertEquals("Comparing equal dates did not answer zero", 0, d1
+ .compareTo(d2));
+ assertEquals("date1.compareTo(date2), where date1 > date2, did not result in 1",
+ 1, d1.compareTo(d4));
+ assertEquals("date1.compareTo(date2), where date1 < date2, did not result in -1",
+ -1, d1.compareTo(d3));
+
+ try {
+ d1.compareTo(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Date#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean java.util.Date.equals(java.lang.Object)
+ Date d1 = new Date(0);
+ Date d2 = new Date(1900000);
+ Date d3 = new Date(1900000);
+ assertTrue("Equality test failed", d2.equals(d3));
+ assertTrue("Equality test failed", !d1.equals(d2));
+ }
+
+ /**
+ * java.util.Date#getDate()
+ */
+ public void test_getDate() {
+ // Test for method int java.util.Date.getDate()
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ assertEquals("Returned incorrect date", 13, d.getDate());
+ }
+
+ /**
+ * java.util.Date#getDay()
+ */
+ public void test_getDay() {
+ // Test for method int java.util.Date.getDay()
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ assertEquals("Returned incorrect day", 2, d.getDay());
+ }
+
+ /**
+ * java.util.Date#getHours()
+ */
+ public void test_getHours() {
+ // Test for method int java.util.Date.getHours()
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ assertEquals("Returned incorrect hours", 19, d.getHours());
+ }
+
+ /**
+ * java.util.Date#getMinutes()
+ */
+ public void test_getMinutes() {
+ // Test for method int java.util.Date.getMinutes()
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ assertEquals("Returned incorrect minutes", 9, d.getMinutes());
+ }
+
+ /**
+ * java.util.Date#getMonth()
+ */
+ public void test_getMonth() {
+ // Test for method int java.util.Date.getMonth()
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ assertEquals("Returned incorrect month", 9, d.getMonth());
+ }
+
+ /**
+ * java.util.Date#getSeconds()
+ */
+ public void test_getSeconds() {
+ // Test for method int java.util.Date.getSeconds()
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ assertEquals("Returned incorrect seconds", 0, d.getSeconds());
+ }
+
+ /**
+ * java.util.Date#getTime()
+ */
+ public void test_getTime() {
+ // Test for method long java.util.Date.getTime()
+ Date d1 = new Date(0);
+ Date d2 = new Date(1900000);
+ assertEquals("Returned incorrect time", 1900000, d2.getTime());
+ assertEquals("Returned incorrect time", 0, d1.getTime());
+ }
+
+ /**
+ * java.util.Date#getTimezoneOffset()
+ */
+ public void test_getTimezoneOffset() {
+ // Test for method int java.util.Date.getTimezoneOffset()
+ assertTrue("Used to test", true);
+ }
+
+ /**
+ * java.util.Date#getYear()
+ */
+ public void test_getYear() {
+ // Test for method int java.util.Date.getYear()
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ assertEquals("Returned incorrect year", 98, d.getYear());
+ }
+
+ /**
+ * java.util.Date#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.util.Date.hashCode()
+ Date d1 = new Date(0);
+ Date d2 = new Date(1900000);
+ assertEquals("Returned incorrect hash", 1900000, d2.hashCode());
+ assertEquals("Returned incorrect hash", 0, d1.hashCode());
+ }
+
+ /**
+ * java.util.Date#parse(java.lang.String)
+ */
+ public void test_parseLjava_lang_String() {
+ // Test for method long java.util.Date.parse(java.lang.String)
+ Date d = new Date(Date.parse("13 October 1998"));
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setTime(d);
+ assertEquals("Parsed incorrect month", 9, cal.get(Calendar.MONTH));
+ assertEquals("Parsed incorrect year", 1998, cal.get(Calendar.YEAR));
+ assertEquals("Parsed incorrect date", 13, cal.get(Calendar.DATE));
+
+ d = new Date(Date.parse("Jan-12 1999"));
+ assertTrue("Wrong parsed date 1", d.equals(new GregorianCalendar(1999,
+ 0, 12).getTime()));
+ d = new Date(Date.parse("Jan12-1999"));
+ assertTrue("Wrong parsed date 2", d.equals(new GregorianCalendar(1999,
+ 0, 12).getTime()));
+ d = new Date(Date.parse("Jan12 69-1"));
+ cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+ cal.clear();
+ cal.set(1969, Calendar.JANUARY, 12, 1, 0);
+ assertTrue("Wrong parsed date 3", d.equals(cal.getTime()));
+ d = new Date(Date.parse("6:45:13 3/2/1200 MST"));
+ cal.setTimeZone(TimeZone.getTimeZone("MST"));
+ cal.clear();
+ cal.set(1200, 2, 2, 6, 45, 13);
+ assertTrue("Wrong parsed date 4", d.equals(cal.getTime()));
+ d = new Date(Date.parse("Mon, 22 Nov 1999 12:52:06 GMT"));
+ cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+ cal.clear();
+ cal.set(1999, Calendar.NOVEMBER, 22, 12, 52, 06);
+ assertTrue("Wrong parsed date 5", d.equals(cal.getTime()));
+
+ try {
+ // Regression for HARMONY-259
+ Date.parse(null);
+ fail("Date.parse(null) should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ // Regression for HARMONY-102
+ assertEquals("Assert 0: parse failure",
+ -5400000, Date.parse("Sat, 1 Jan 1970 +0130 00:00:00"));
+ assertEquals("Assert 1: parse failure",
+ 858600000, Date.parse("00:00:00 GMT +0130 Sat, 11 Jan 1970"));
+ }
+
+ /**
+ * java.util.Date#setDate(int)
+ */
+ public void test_setDateI() {
+ // Test for method void java.util.Date.setDate(int)
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ d.setDate(23);
+ assertEquals("Set incorrect date", 23, d.getDate());
+ }
+
+ /**
+ * java.util.Date#setHours(int)
+ */
+ public void test_setHoursI() {
+ // Test for method void java.util.Date.setHours(int)
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ d.setHours(23);
+ assertEquals("Set incorrect hours", 23, d.getHours());
+ }
+
+ /**
+ * java.util.Date#setMinutes(int)
+ */
+ public void test_setMinutesI() {
+ // Test for method void java.util.Date.setMinutes(int)
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ d.setMinutes(45);
+ assertEquals("Set incorrect mins", 45, d.getMinutes());
+ }
+
+ /**
+ * java.util.Date#setMonth(int)
+ */
+ public void test_setMonthI() {
+ // Test for method void java.util.Date.setMonth(int)
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ d.setMonth(0);
+ assertEquals("Set incorrect month", 0, d.getMonth());
+ }
+
+ /**
+ * java.util.Date#setSeconds(int)
+ */
+ public void test_setSecondsI() {
+ // Test for method void java.util.Date.setSeconds(int)
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ d.setSeconds(13);
+ assertEquals("Set incorrect seconds", 13, d.getSeconds());
+ }
+
+ /**
+ * java.util.Date#setTime(long)
+ */
+ public void test_setTimeJ() {
+ // Test for method void java.util.Date.setTime(long)
+ Date d1 = new Date(0);
+ Date d2 = new Date(1900000);
+ d1.setTime(900);
+ d2.setTime(890000);
+ assertEquals("Returned incorrect time", 890000, d2.getTime());
+ assertEquals("Returned incorrect time", 900, d1.getTime());
+ }
+
+ /**
+ * java.util.Date#setYear(int)
+ */
+ public void test_setYearI() {
+ // Test for method void java.util.Date.setYear(int)
+ Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+ .getTime();
+ d.setYear(8);
+ assertEquals("Set incorrect year", 8, d.getYear());
+ }
+
+ /**
+ * java.util.Date#toGMTString()
+ */
+ public void test_toGMTString() {
+ // Test for method java.lang.String java.util.Date.toGMTString()
+ assertEquals("Did not convert epoch to GMT string correctly", "1 Jan 1970 00:00:00 GMT", new Date(0)
+ .toGMTString());
+ assertEquals("Did not convert epoch + 1yr to GMT string correctly",
+ "1 Jan 1971 00:00:00 GMT", new Date((long) 365 * 24 * 60 * 60 * 1000).toGMTString()
+ );
+ }
+
+ /**
+ * java.util.Date#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.util.Date.toString()
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.DATE, 1);
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ cal.set(Calendar.YEAR, 1970);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ Date d = cal.getTime();
+ String result = d.toString();
+ assertTrue("Incorrect result: " + d, result
+ .startsWith("Thu Jan 01 00:00:00")
+ && result.endsWith("1970"));
+
+ TimeZone tz = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT-5"));
+ try {
+ Date d1 = new Date(0);
+ assertTrue("Returned incorrect string: " + d1, d1.toString()
+ .equals("Wed Dec 31 19:00:00 GMT-05:00 1969"));
+ } finally {
+ TimeZone.setDefault(tz);
+ }
+
+ // Test for HARMONY-5468
+ TimeZone.setDefault(TimeZone.getTimeZone("MST"));
+ Date d2 = new Date(108, 7, 27);
+ assertTrue("Returned incorrect string: " + d2, d2.toString()
+ .startsWith("Wed Aug 27 00:00:00")
+ && d2.toString().endsWith("2008"));
+ }
+
+ /**
+ * java.util.Date#UTC(int, int, int, int, int, int)
+ */
+ public void test_UTCIIIIII() {
+ // Test for method long java.util.Date.UTC(int, int, int, int, int, int)
+ assertTrue("Returned incorrect UTC value for epoch", Date.UTC(70, 0, 1,
+ 0, 0, 0) == (long) 0);
+ assertTrue("Returned incorrect UTC value for epoch +1yr", Date.UTC(71,
+ 0, 1, 0, 0, 0) == (long) 365 * 24 * 60 * 60 * 1000);
+ }
+ /**
+ * java.util.Date#toLocaleString() Test for method java.lang.String
+ * java.util.Date.toGMTString()
+ */
+ public void test_toLocaleString() {
+ Locale loc = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ TimeZone tz = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ try {
+ assertEquals("Did not convert epoch to GMT string correctly", "Jan 1, 1970 12:00:00 AM",
+ new Date(0).toLocaleString());
+ assertEquals("Did not convert epoch + 1yr to GMT string correctly",
+ "Jan 1, 1971 12:00:00 AM", new Date((long)365 * 24 * 60 * 60 * 1000)
+ .toLocaleString());
+ } finally {
+ Locale.setDefault(loc);
+ TimeZone.setDefault(tz);
+ }
+ }
+
+ static TimeZone defaultTimeZone = TimeZone.getDefault();
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ TimeZone.setDefault(defaultTimeZone);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/DuplicateFormatFlagsExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/DuplicateFormatFlagsExceptionTest.java
new file mode 100644
index 0000000..d59decb
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/DuplicateFormatFlagsExceptionTest.java
@@ -0,0 +1,94 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.DuplicateFormatFlagsException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class DuplicateFormatFlagsExceptionTest extends TestCase {
+
+ /**
+ * java.util.DuplicateFormatFlagsException#DuplicateFormatFlagsException(String)
+ */
+ public void test_duplicateFormatFlagsException() {
+ try {
+ new DuplicateFormatFlagsException(null);
+ fail("should throw NullPointerException.");
+ } catch (NullPointerException e) {
+ // desired
+ }
+ }
+
+ /**
+ * java.util.DuplicateFormatFlagsException#getFlags()
+ */
+ public void test_getFlags() {
+ String strFlags = "MYTESTFLAGS";
+ DuplicateFormatFlagsException duplicateFormatException = new DuplicateFormatFlagsException(
+ strFlags);
+ assertEquals(strFlags, duplicateFormatException.getFlags());
+ }
+
+ /**
+ * java.util.DuplicateFormatFlagsException#getMessage()
+ */
+ public void test_getMessage() {
+ String strFlags = "MYTESTFLAGS";
+ DuplicateFormatFlagsException duplicateFormatException = new DuplicateFormatFlagsException(
+ strFlags);
+ assertTrue(null != duplicateFormatException.getFlags());
+
+ }
+
+ // comparator for DuplicateFormatFlagsException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ DuplicateFormatFlagsException initEx = (DuplicateFormatFlagsException) initial;
+ DuplicateFormatFlagsException desrEx = (DuplicateFormatFlagsException) deserialized;
+
+ assertEquals("Flags", initEx.getFlags(), desrEx.getFlags());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new DuplicateFormatFlagsException(
+ "TESTDESC"), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new DuplicateFormatFlagsException(
+ "TESTDESC"), exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EmptyStackExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EmptyStackExceptionTest.java
new file mode 100644
index 0000000..fdba5bf
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EmptyStackExceptionTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.EmptyStackException;
+import java.util.Stack;
+
+public class EmptyStackExceptionTest extends junit.framework.TestCase {
+
+ Object[] objArray = new Object[10];
+ Stack s;
+
+ /**
+ * java.util.EmptyStackException#EmptyStackException()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.EmptyStackException()
+ try {
+ for (int counter = 0; counter < objArray.length + 1; counter++)
+ s.pop();
+ } catch (EmptyStackException e) {
+ return;
+ }
+ fail("Expected EmptyStackException not thrown");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ for (int counter = 0; counter < objArray.length; counter++) {
+ objArray[counter] = new Integer(counter);
+ }
+
+ s = new Stack();
+ for (int counter = 0; counter < objArray.length; counter++) {
+ s.push(objArray[counter]);
+ }
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ objArray = null;
+ s = null;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumMapTest.java
new file mode 100644
index 0000000..2a37a18
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumMapTest.java
@@ -0,0 +1,1175 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import dalvik.annotation.AndroidOnly;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import junit.framework.TestCase;
+
+public class EnumMapTest extends TestCase {
+ enum Size {
+ Small, Middle, Big {};
+ }
+
+ enum Color {
+ Red, Green, Blue {};
+ }
+
+ enum Empty {
+ //Empty
+ }
+
+ private static class MockEntry<K, V> implements Map.Entry<K, V> {
+ private K key;
+
+ private V value;
+
+ public MockEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ return (key == null ? 0 : key.hashCode())
+ ^ (value == null ? 0 : value.hashCode());
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ public V setValue(V object) {
+ V oldValue = value;
+ value = object;
+ return oldValue;
+ }
+ }
+
+ /**
+ * java.util.EnumMap#EnumMap(Class)
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_ConstructorLjava_lang_Class() {
+ try {
+ new EnumMap((Class) null);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+
+ try {
+ new EnumMap(Size.Big.getClass());
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ new EnumMap(Integer.class);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ assertNull("Return non-null for non mapped key", enumColorMap.put(
+ Color.Green, 2));
+ assertEquals("Get returned incorrect value for given key", 2,
+ enumColorMap.get(Color.Green));
+
+ EnumMap enumEmptyMap = new EnumMap<Empty, Double>(Empty.class);
+ try {
+ enumEmptyMap.put(Color.Red, 2);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ assertNull("Return non-null for non mapped key", enumSizeMap.put(
+ Size.Big, 2));
+ assertEquals("Get returned incorrect value for given key", 2,
+ enumSizeMap.get(Size.Big));
+ try {
+ enumSizeMap.put(Color.Red, 2);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+
+ enumSizeMap = new EnumMap(Size.Middle.getClass());
+ assertNull("Return non-null for non mapped key", enumSizeMap.put(
+ Size.Small, 1));
+ assertEquals("Get returned incorrect value for given key", 1,
+ enumSizeMap.get(Size.Small));
+ try {
+ enumSizeMap.put(Color.Red, 2);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.EnumMap#EnumMap(EnumMap)
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_ConstructorLjava_util_EnumMap() {
+ EnumMap enumMap;
+ EnumMap enumColorMap = null;
+ try {
+ enumMap = new EnumMap(enumColorMap);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ enumColorMap = new EnumMap<Color, Double>(Color.class);
+ Double double1 = new Double(1);
+ enumColorMap.put(Color.Green, 2);
+ enumColorMap.put(Color.Blue, double1);
+
+ enumMap = new EnumMap(enumColorMap);
+ assertEquals("Constructor fails", 2, enumMap.get(Color.Green));
+ assertSame("Constructor fails", double1, enumMap.get(Color.Blue));
+ assertNull("Constructor fails", enumMap.get(Color.Red));
+ enumMap.put(Color.Red, 1);
+ assertEquals("Wrong value", 1, enumMap.get(Color.Red));
+
+ try {
+ enumMap.put(Size.Middle, 2);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.EnumMap#EnumMap(Map)
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_ConstructorLjava_util_Map() {
+ EnumMap enumMap;
+ Map enumColorMap = null;
+ try {
+ enumMap = new EnumMap(enumColorMap);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ enumColorMap = new EnumMap<Color, Double>(Color.class);
+ enumMap = new EnumMap(enumColorMap);
+ enumColorMap.put(Color.Blue, 3);
+ enumMap = new EnumMap(enumColorMap);
+
+ HashMap hashColorMap = null;
+ try {
+ enumMap = new EnumMap(hashColorMap);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ hashColorMap = new HashMap();
+ try {
+ enumMap = new EnumMap(hashColorMap);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ hashColorMap.put(Color.Green, 2);
+ enumMap = new EnumMap(hashColorMap);
+ assertEquals("Constructor fails", 2, enumMap.get(Color.Green));
+ assertNull("Constructor fails", enumMap.get(Color.Red));
+ enumMap.put(Color.Red, 1);
+ assertEquals("Wrong value", 1, enumMap.get(Color.Red));
+ hashColorMap.put(Size.Big, 3);
+ try {
+ enumMap = new EnumMap(hashColorMap);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+
+ hashColorMap = new HashMap();
+ hashColorMap.put(new Integer(1), 1);
+ try {
+ enumMap = new EnumMap(hashColorMap);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.EnumMap#clear()
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_clear() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Small, 1);
+ enumSizeMap.clear();
+ assertNull("Failed to clear all elements", enumSizeMap.get(Size.Small));
+ }
+
+ /**
+ * java.util.EnumMap#containsKey(Object)
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void test_containsKeyLjava_lang_Object() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ assertFalse("Returned true for uncontained key", enumSizeMap
+ .containsKey(Size.Small));
+ enumSizeMap.put(Size.Small, 1);
+ assertTrue("Returned false for contained key", enumSizeMap
+ .containsKey(Size.Small));
+
+ enumSizeMap.put(Size.Big, null);
+ assertTrue("Returned false for contained key", enumSizeMap
+ .containsKey(Size.Big));
+
+ assertFalse("Returned true for uncontained key", enumSizeMap
+ .containsKey(Color.Red));
+ assertFalse("Returned true for uncontained key", enumSizeMap
+ .containsKey(new Integer("3")));
+ assertFalse("Returned true for uncontained key", enumSizeMap
+ .containsKey(null));
+ }
+
+ /**
+ * java.util.EnumMap#clone()
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void test_clone() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ Integer integer = new Integer("3");
+ enumSizeMap.put(Size.Small, integer);
+ EnumMap enumSizeMapClone = enumSizeMap.clone();
+ assertNotSame("Should not be same", enumSizeMap, enumSizeMapClone);
+ assertEquals("Clone answered unequal EnumMap", enumSizeMap,
+ enumSizeMapClone);
+
+ assertSame("Should be same", enumSizeMap.get(Size.Small),
+ enumSizeMapClone.get(Size.Small));
+ assertSame("Clone is not shallow clone", integer, enumSizeMapClone
+ .get(Size.Small));
+ enumSizeMap.remove(Size.Small);
+ assertSame("Clone is not shallow clone", integer, enumSizeMapClone
+ .get(Size.Small));
+ }
+
+ /**
+ * java.util.EnumMap#containsValue(Object)
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void test_containsValueLjava_lang_Object() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ Double double1 = new Double(3);
+ Double double2 = new Double(3);
+
+ assertFalse("Returned true for uncontained value", enumSizeMap
+ .containsValue(double1));
+ enumSizeMap.put(Size.Middle, 2);
+ enumSizeMap.put(Size.Small, double1);
+ assertTrue("Returned false for contained value", enumSizeMap
+ .containsValue(double1));
+ assertTrue("Returned false for contained value", enumSizeMap
+ .containsValue(double2));
+ assertTrue("Returned false for contained value", enumSizeMap
+ .containsValue(2));
+ assertFalse("Returned true for uncontained value", enumSizeMap
+ .containsValue(1));
+
+ assertFalse("Returned true for uncontained value", enumSizeMap
+ .containsValue(null));
+ enumSizeMap.put(Size.Big, null);
+ assertTrue("Returned false for contained value", enumSizeMap
+ .containsValue(null));
+ }
+
+ /**
+ * java.util.EnumMap#entrySet()
+ */
+ @AndroidOnly("Map.Entry is indirectly modified on RI when Iterator.next() is invoked")
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_entrySet() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ MockEntry mockEntry = new MockEntry(Size.Middle, 1);
+ Set set = enumSizeMap.entrySet();
+
+ Set set1 = enumSizeMap.entrySet();
+ assertSame("Should be same", set1, set);
+ try {
+ set.add(mockEntry);
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+
+ assertTrue("Returned false for contained object", set
+ .contains(mockEntry));
+ mockEntry = new MockEntry(Size.Middle, null);
+ assertFalse("Returned true for uncontained object", set
+ .contains(mockEntry));
+ assertFalse("Returned true for uncontained object", set
+ .contains(Size.Small));
+ mockEntry = new MockEntry(new Integer(1), 1);
+ assertFalse("Returned true for uncontained object", set
+ .contains(mockEntry));
+ assertFalse("Returned true for uncontained object", set
+ .contains(new Integer(1)));
+
+ mockEntry = new MockEntry(Size.Big, null);
+ assertTrue("Returned false for contained object", set
+ .contains(mockEntry));
+ assertTrue("Returned false when the object can be removed", set
+ .remove(mockEntry));
+ assertFalse("Returned true for uncontained object", set
+ .contains(mockEntry));
+ assertFalse("Returned true when the object can not be removed", set
+ .remove(mockEntry));
+ mockEntry = new MockEntry(new Integer(1), 1);
+ assertFalse("Returned true when the object can not be removed", set
+ .remove(mockEntry));
+ assertFalse("Returned true when the object can not be removed", set
+ .remove(new Integer(1)));
+
+ // The set is backed by the map so changes to one are reflected by the
+ // other.
+ enumSizeMap.put(Size.Big, 3);
+ mockEntry = new MockEntry(Size.Big, 3);
+ assertTrue("Returned false for contained object", set
+ .contains(mockEntry));
+ enumSizeMap.remove(Size.Big);
+ assertFalse("Returned true for uncontained object", set
+ .contains(mockEntry));
+
+ assertEquals("Wrong size", 1, set.size());
+ set.clear();
+ assertEquals("Wrong size", 0, set.size());
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ Collection c = new ArrayList();
+ c.add(new MockEntry(Size.Middle, 1));
+ assertTrue("Return wrong value", set.containsAll(c));
+ assertTrue("Remove does not success", set.removeAll(c));
+
+ enumSizeMap.put(Size.Middle, 1);
+ c.add(new MockEntry(Size.Big, 3));
+ assertTrue("Remove does not success", set.removeAll(c));
+ assertFalse("Should return false", set.removeAll(c));
+ assertEquals("Wrong size", 1, set.size());
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ c = new ArrayList();
+ c.add(new MockEntry(Size.Middle, 1));
+ c.add(new MockEntry(Size.Big, 3));
+
+ assertTrue("Retain does not success", set.retainAll(c));
+ assertEquals("Wrong size", 1, set.size());
+ assertFalse("Should return false", set.retainAll(c));
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+
+ set = enumSizeMap.entrySet();
+ Object[] array = set.toArray();
+ assertEquals("Wrong length", 2, array.length);
+ Map.Entry entry = (Map.Entry) array[0];
+ assertEquals("Wrong key", Size.Middle, entry.getKey());
+ assertEquals("Wrong value", 1, entry.getValue());
+
+ Object[] array1 = new Object[10];
+ array1 = set.toArray();
+ assertEquals("Wrong length", 2, array1.length);
+ entry = (Map.Entry) array[0];
+ assertEquals("Wrong key", Size.Middle, entry.getKey());
+ assertEquals("Wrong value", 1, entry.getValue());
+
+ array1 = new Object[10];
+ array1 = set.toArray(array1);
+ assertEquals("Wrong length", 10, array1.length);
+ entry = (Map.Entry) array[1];
+ assertEquals("Wrong key", Size.Big, entry.getKey());
+ assertNull("Should be null", array1[2]);
+
+ set = enumSizeMap.entrySet();
+ Integer integer = new Integer("1");
+ assertFalse("Returned true when the object can not be removed", set
+ .remove(integer));
+ assertTrue("Returned false when the object can be removed", set
+ .remove(entry));
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ Iterator iter = set.iterator();
+ entry = (Map.Entry) iter.next();
+ assertTrue("Returned false for contained object", set.contains(entry));
+ mockEntry = new MockEntry(Size.Middle, 2);
+ assertFalse("Returned true for uncontained object", set
+ .contains(mockEntry));
+ mockEntry = new MockEntry(new Integer(2), 2);
+ assertFalse("Returned true for uncontained object", set
+ .contains(mockEntry));
+ entry = (Map.Entry) iter.next();
+ assertTrue("Returned false for contained object", set.contains(entry));
+
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.remove(Size.Big);
+ mockEntry = new MockEntry(Size.Big, null);
+ assertEquals("Wrong size", 1, set.size());
+ assertFalse("Returned true for uncontained object", set.contains(mockEntry));
+ enumSizeMap.put(Size.Big, 2);
+ mockEntry = new MockEntry(Size.Big, 2);
+ assertTrue("Returned false for contained object", set
+ .contains(mockEntry));
+
+ iter.remove();
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ try {
+ entry.setValue(2);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ try {
+ set.contains(entry);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ iter = set.iterator();
+ entry = (Map.Entry) iter.next();
+ assertEquals("Wrong key", Size.Middle, entry.getKey());
+
+ assertTrue("Returned false for contained object", set.contains(entry));
+ enumSizeMap.put(Size.Middle, 3);
+ assertTrue("Returned false for contained object", set.contains(entry));
+ entry.setValue(2);
+ assertTrue("Returned false for contained object", set.contains(entry));
+ assertFalse("Returned true for uncontained object", set
+ .remove(new Integer(1)));
+
+ iter.next();
+ assertEquals("Wrong key", Size.Middle, entry.getKey());
+ set.clear();
+ assertEquals("Wrong size", 0, set.size());
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.entrySet();
+ iter = set.iterator();
+ mockEntry = new MockEntry(Size.Middle, 1);
+
+ assertFalse("Wrong result", entry.equals(mockEntry));
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ entry = (Map.Entry) iter.next();
+ assertEquals("Wrong key", Size.Middle, entry.getKey());
+ assertTrue("Should return true", entry.equals(mockEntry));
+ assertEquals("Should be equal", mockEntry.hashCode(), entry.hashCode());
+ mockEntry = new MockEntry(Size.Big, 1);
+ assertFalse("Wrong result", entry.equals(mockEntry));
+
+ entry = (Map.Entry) iter.next();
+ assertFalse("Wrong result", entry.equals(mockEntry));
+ assertEquals("Wrong key", Size.Big, entry.getKey());
+ iter.remove();
+ assertFalse("Wrong result", entry.equals(mockEntry));
+ assertEquals("Wrong size", 1, set.size());
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ try {
+ iter.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.EnumMap#equals(Object)
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void test_equalsLjava_lang_Object() {
+ EnumMap enumMap = new EnumMap(Size.class);
+ enumMap.put(Size.Small, 1);
+
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ assertFalse("Returned true for unequal EnumMap", enumSizeMap
+ .equals(enumMap));
+ enumSizeMap.put(Size.Small, 1);
+ assertTrue("Returned false for equal EnumMap", enumSizeMap
+ .equals(enumMap));
+ enumSizeMap.put(Size.Big, null);
+ assertFalse("Returned true for unequal EnumMap", enumSizeMap
+ .equals(enumMap));
+
+ enumMap.put(Size.Middle, null);
+ assertFalse("Returned true for unequal EnumMap", enumSizeMap
+ .equals(enumMap));
+ enumMap.remove(Size.Middle);
+ enumMap.put(Size.Big, 3);
+ assertFalse("Returned true for unequal EnumMap", enumSizeMap
+ .equals(enumMap));
+ enumMap.put(Size.Big, null);
+ assertTrue("Returned false for equal EnumMap", enumSizeMap
+ .equals(enumMap));
+
+ HashMap hashMap = new HashMap();
+ hashMap.put(Size.Small, 1);
+ assertFalse("Returned true for unequal EnumMap", hashMap
+ .equals(enumMap));
+ hashMap.put(Size.Big, null);
+ assertTrue("Returned false for equal EnumMap", enumMap.equals(hashMap));
+
+ assertFalse("Should return false", enumSizeMap
+ .equals(new Integer(1)));
+ }
+
+ /**
+ * java.util.EnumMap#keySet()
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void test_keySet() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 2);
+ enumSizeMap.put(Size.Big, null);
+ Set set = enumSizeMap.keySet();
+
+ Set set1 = enumSizeMap.keySet();
+ assertSame("Should be same", set1, set);
+ try {
+ set.add(Size.Big);
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+
+ assertTrue("Returned false for contained object", set
+ .contains(Size.Middle));
+ assertTrue("Returned false for contained object", set
+ .contains(Size.Big));
+ assertFalse("Returned true for uncontained object", set
+ .contains(Size.Small));
+ assertFalse("Returned true for uncontained object", set
+ .contains(new Integer(1)));
+ assertTrue("Returned false when the object can be removed", set
+ .remove(Size.Big));
+ assertFalse("Returned true for uncontained object", set
+ .contains(Size.Big));
+ assertFalse("Returned true when the object can not be removed", set
+ .remove(Size.Big));
+ assertFalse("Returned true when the object can not be removed", set
+ .remove(new Integer(1)));
+
+ // The set is backed by the map so changes to one are reflected by the
+ // other.
+ enumSizeMap.put(Size.Big, 3);
+ assertTrue("Returned false for contained object", set
+ .contains(Size.Big));
+ enumSizeMap.remove(Size.Big);
+ assertFalse("Returned true for uncontained object", set
+ .contains(Size.Big));
+
+ assertEquals("Wrong size", 1, set.size());
+ set.clear();
+ assertEquals("Wrong size", 0, set.size());
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.keySet();
+ Collection c = new ArrayList();
+ c.add(Size.Big);
+ assertTrue("Should return true", set.containsAll(c));
+ c.add(Size.Small);
+ assertFalse("Should return false", set.containsAll(c));
+ assertTrue("Should return true", set.removeAll(c));
+ assertEquals("Wrong size", 1, set.size());
+ assertFalse("Should return false", set.removeAll(c));
+ assertEquals("Wrong size", 1, set.size());
+ try {
+ set.addAll(c);
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+
+ enumSizeMap.put(Size.Big, null);
+ assertEquals("Wrong size", 2, set.size());
+ assertTrue("Should return true", set.retainAll(c));
+ assertEquals("Wrong size", 1, set.size());
+ assertFalse("Should return false", set.retainAll(c));
+ assertEquals(1, set.size());
+ Object[] array = set.toArray();
+ assertEquals("Wrong length", 1, array.length);
+ assertEquals("Wrong key", Size.Big, array[0]);
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.keySet();
+ c = new ArrayList();
+ c.add(Color.Blue);
+ assertFalse("Should return false", set.remove(c));
+ assertEquals("Wrong size", 2, set.size());
+ assertTrue("Should return true", set.retainAll(c));
+ assertEquals("Wrong size", 0, set.size());
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.keySet();
+
+ Iterator iter = set.iterator();
+ Enum enumKey = (Enum) iter.next();
+ assertTrue("Returned false for contained object", set.contains(enumKey));
+ enumKey = (Enum) iter.next();
+ assertTrue("Returned false for contained object", set.contains(enumKey));
+
+ enumSizeMap.remove(Size.Big);
+ assertFalse("Returned true for uncontained object", set
+ .contains(enumKey));
+ iter.remove();
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ assertFalse("Returned true for uncontained object", set
+ .contains(enumKey));
+
+ iter = set.iterator();
+ enumKey = (Enum) iter.next();
+ assertTrue("Returned false for contained object", set.contains(enumKey));
+ enumSizeMap.put(Size.Middle, 3);
+ assertTrue("Returned false for contained object", set.contains(enumKey));
+
+ enumSizeMap = new EnumMap(Size.class);
+ enumSizeMap.put(Size.Middle, 1);
+ enumSizeMap.put(Size.Big, null);
+ set = enumSizeMap.keySet();
+ iter = set.iterator();
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ enumKey = (Enum) iter.next();
+ assertEquals("Wrong key", Size.Middle, enumKey);
+ assertSame("Wrong key", Size.Middle, enumKey);
+ assertFalse("Returned true for unequal object", iter.equals(enumKey));
+ iter.remove();
+ assertFalse("Returned true for uncontained object", set
+ .contains(enumKey));
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+
+ assertEquals("Wrong size", 1, set.size());
+ enumKey = (Enum) iter.next();
+ assertEquals("Wrong key", Size.Big, enumKey);
+ iter.remove();
+ try {
+ iter.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.EnumMap#get(Object)
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_getLjava_lang_Object() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ assertNull("Get returned non-null for non mapped key", enumSizeMap
+ .get(Size.Big));
+ enumSizeMap.put(Size.Big, 1);
+ assertEquals("Get returned incorrect value for given key", 1,
+ enumSizeMap.get(Size.Big));
+
+ assertNull("Get returned non-null for non mapped key", enumSizeMap
+ .get(Size.Small));
+ assertNull("Get returned non-null for non existent key", enumSizeMap
+ .get(Color.Red));
+ assertNull("Get returned non-null for non existent key", enumSizeMap
+ .get(new Integer(1)));
+ assertNull("Get returned non-null for non existent key", enumSizeMap
+ .get(null));
+
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ assertNull("Get returned non-null for non mapped key", enumColorMap
+ .get(Color.Green));
+ enumColorMap.put(Color.Green, 2);
+ assertEquals("Get returned incorrect value for given key", 2,
+ enumColorMap.get(Color.Green));
+ assertNull("Get returned non-null for non mapped key", enumColorMap
+ .get(Color.Blue));
+
+ enumColorMap.put(Color.Green, new Double(4));
+ assertEquals("Get returned incorrect value for given key",
+ new Double(4), enumColorMap.get(Color.Green));
+ enumColorMap.put(Color.Green, new Integer("3"));
+ assertEquals("Get returned incorrect value for given key", new Integer(
+ "3"), enumColorMap.get(Color.Green));
+ enumColorMap.put(Color.Green, null);
+ assertNull("Can not handle null value", enumColorMap.get(Color.Green));
+ Float f = new Float("3.4");
+ enumColorMap.put(Color.Green, f);
+ assertSame("Get returned incorrect value for given key", f,
+ enumColorMap.get(Color.Green));
+ }
+
+ /**
+ * java.util.EnumMap#put(Object,Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ try {
+ enumSizeMap.put(Color.Red, 2);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ assertNull("Return non-null for non mapped key", enumSizeMap.put(
+ Size.Small, 1));
+
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ try {
+ enumColorMap.put(Size.Big, 2);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ try {
+ enumColorMap.put(null, 2);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ assertNull("Return non-null for non mapped key", enumColorMap.put(
+ Color.Green, 2));
+ assertEquals("Return wrong value", 2, enumColorMap.put(Color.Green,
+ new Double(4)));
+ assertEquals("Return wrong value", new Double(4), enumColorMap.put(
+ Color.Green, new Integer("3")));
+ assertEquals("Return wrong value", new Integer("3"), enumColorMap.put(
+ Color.Green, null));
+ Float f = new Float("3.4");
+ assertNull("Return non-null for non mapped key", enumColorMap.put(
+ Color.Green, f));
+ assertNull("Return non-null for non mapped key", enumColorMap.put(
+ Color.Blue, 2));
+ assertEquals("Return wrong value", 2, enumColorMap.put(Color.Blue,
+ new Double(4)));
+ }
+
+ /**
+ * java.util.EnumMap#putAll(Map)
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_putAllLjava_util_Map() {
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ enumColorMap.put(Color.Green, 2);
+
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ enumColorMap.putAll(enumSizeMap);
+
+ enumSizeMap.put(Size.Big, 1);
+ try {
+ enumColorMap.putAll(enumSizeMap);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+
+ EnumMap enumColorMap1 = new EnumMap<Color, Double>(Color.class);
+ enumColorMap1.put(Color.Blue, 3);
+ enumColorMap.putAll(enumColorMap1);
+ assertEquals("Get returned incorrect value for given key", 3,
+ enumColorMap.get(Color.Blue));
+ assertEquals("Wrong Size", 2, enumColorMap.size());
+
+ enumColorMap = new EnumMap<Color, Double>(Color.class);
+
+ HashMap hashColorMap = null;
+ try {
+ enumColorMap.putAll(hashColorMap);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ hashColorMap = new HashMap();
+ enumColorMap.putAll(hashColorMap);
+
+ hashColorMap.put(Color.Green, 2);
+ enumColorMap.putAll(hashColorMap);
+ assertEquals("Get returned incorrect value for given key", 2,
+ enumColorMap.get(Color.Green));
+ assertNull("Get returned non-null for non mapped key", enumColorMap
+ .get(Color.Red));
+ hashColorMap.put(Color.Red, new Integer(1));
+ enumColorMap.putAll(hashColorMap);
+ assertEquals("Get returned incorrect value for given key", new Integer(
+ 2), enumColorMap.get(Color.Green));
+ hashColorMap.put(Size.Big, 3);
+ try {
+ enumColorMap.putAll(hashColorMap);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+
+ hashColorMap = new HashMap();
+ hashColorMap.put(new Integer(1), 1);
+ try {
+ enumColorMap.putAll(hashColorMap);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.EnumMap#remove(Object)
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_removeLjava_lang_Object() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ assertNull("Remove of non-mapped key returned non-null", enumSizeMap
+ .remove(Size.Big));
+ enumSizeMap.put(Size.Big, 3);
+ enumSizeMap.put(Size.Middle, 2);
+
+ assertNull("Get returned non-null for non mapped key", enumSizeMap
+ .get(Size.Small));
+ assertEquals("Remove returned incorrect value", 3, enumSizeMap
+ .remove(Size.Big));
+ assertNull("Get returned non-null for non mapped key", enumSizeMap
+ .get(Size.Big));
+ assertNull("Remove of non-mapped key returned non-null", enumSizeMap
+ .remove(Size.Big));
+ assertNull("Remove of non-existent key returned non-null", enumSizeMap
+ .remove(Color.Red));
+ assertNull("Remove of non-existent key returned non-null", enumSizeMap
+ .remove(new Double(4)));
+ assertNull("Remove of non-existent key returned non-null", enumSizeMap
+ .remove(null));
+
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ assertNull("Get returned non-null for non mapped key", enumColorMap
+ .get(Color.Green));
+ enumColorMap.put(Color.Green, new Double(4));
+ assertEquals("Remove returned incorrect value", new Double(4),
+ enumColorMap.remove(Color.Green));
+ assertNull("Get returned non-null for non mapped key", enumColorMap
+ .get(Color.Green));
+ enumColorMap.put(Color.Green, null);
+ assertNull("Can not handle null value", enumColorMap
+ .remove(Color.Green));
+ assertNull("Get returned non-null for non mapped key", enumColorMap
+ .get(Color.Green));
+ }
+
+ /**
+ * java.util.EnumMap#size()
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void test_size() {
+ EnumMap enumSizeMap = new EnumMap(Size.class);
+ assertEquals("Wrong size", 0, enumSizeMap.size());
+ enumSizeMap.put(Size.Small, 1);
+ assertEquals("Wrong size", 1, enumSizeMap.size());
+ enumSizeMap.put(Size.Small, 0);
+ assertEquals("Wrong size", 1, enumSizeMap.size());
+ try {
+ enumSizeMap.put(Color.Red, 2);
+ fail("Expected ClassCastException");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ assertEquals("Wrong size", 1, enumSizeMap.size());
+
+ enumSizeMap.put(Size.Middle, null);
+ assertEquals("Wrong size", 2, enumSizeMap.size());
+ enumSizeMap.remove(Size.Big);
+ assertEquals("Wrong size", 2, enumSizeMap.size());
+ enumSizeMap.remove(Size.Middle);
+ assertEquals("Wrong size", 1, enumSizeMap.size());
+ enumSizeMap.remove(Color.Green);
+ assertEquals("Wrong size", 1, enumSizeMap.size());
+
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ enumColorMap.put(Color.Green, 2);
+ assertEquals("Wrong size", 1, enumColorMap.size());
+ enumColorMap.remove(Color.Green);
+ assertEquals("Wrong size", 0, enumColorMap.size());
+
+ EnumMap enumEmptyMap = new EnumMap<Empty, Double>(Empty.class);
+ assertEquals("Wrong size", 0, enumEmptyMap.size());
+ }
+
+ /**
+ * java.util.EnumMap#values()
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void test_values() {
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ enumColorMap.put(Color.Red, 1);
+ enumColorMap.put(Color.Blue, null);
+ Collection collection = enumColorMap.values();
+
+ Collection collection1 = enumColorMap.values();
+ assertSame("Should be same", collection1, collection);
+ try {
+ collection.add(new Integer(1));
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+
+ assertTrue("Returned false for contained object", collection
+ .contains(1));
+ assertTrue("Returned false for contained object", collection
+ .contains(null));
+ assertFalse("Returned true for uncontained object", collection
+ .contains(2));
+
+ assertTrue("Returned false when the object can be removed", collection
+ .remove(null));
+ assertFalse("Returned true for uncontained object", collection
+ .contains(null));
+ assertFalse("Returned true when the object can not be removed",
+ collection.remove(null));
+
+ // The set is backed by the map so changes to one are reflected by the
+ // other.
+ enumColorMap.put(Color.Blue, 3);
+ assertTrue("Returned false for contained object", collection
+ .contains(3));
+ enumColorMap.remove(Color.Blue);
+ assertFalse("Returned true for uncontained object", collection
+ .contains(3));
+
+ assertEquals("Wrong size", 1, collection.size());
+ collection.clear();
+ assertEquals("Wrong size", 0, collection.size());
+
+ enumColorMap = new EnumMap<Color, Double>(Color.class);
+ enumColorMap.put(Color.Red, 1);
+ enumColorMap.put(Color.Blue, null);
+ collection = enumColorMap.values();
+ Collection c = new ArrayList();
+ c.add(new Integer(1));
+ assertTrue("Should return true", collection.containsAll(c));
+ c.add(new Double(3.4));
+ assertFalse("Should return false", collection.containsAll(c));
+ assertTrue("Should return true", collection.removeAll(c));
+ assertEquals("Wrong size", 1, collection.size());
+ assertFalse("Should return false", collection.removeAll(c));
+ assertEquals("Wrong size", 1, collection.size());
+ try {
+ collection.addAll(c);
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+
+ enumColorMap.put(Color.Red, 1);
+ assertEquals("Wrong size", 2, collection.size());
+ assertTrue("Should return true", collection.retainAll(c));
+ assertEquals("Wrong size", 1, collection.size());
+ assertFalse("Should return false", collection.retainAll(c));
+ assertEquals(1, collection.size());
+ Object[] array = collection.toArray();
+ assertEquals("Wrong length", 1, array.length);
+ assertEquals("Wrong key", 1, array[0]);
+
+ enumColorMap = new EnumMap<Color, Double>(Color.class);
+ enumColorMap.put(Color.Red, 1);
+ enumColorMap.put(Color.Blue, null);
+ collection = enumColorMap.values();
+
+ assertEquals("Wrong size", 2, collection.size());
+ assertFalse("Returned true when the object can not be removed",
+ collection.remove(new Integer("10")));
+
+ Iterator iter = enumColorMap.values().iterator();
+ Object value = iter.next();
+ assertTrue("Returned false for contained object", collection
+ .contains(value));
+ value = iter.next();
+ assertTrue("Returned false for contained object", collection
+ .contains(value));
+
+ enumColorMap.put(Color.Green, 1);
+ enumColorMap.remove(Color.Blue);
+ assertFalse("Returned true for uncontained object", collection
+ .contains(value));
+ iter.remove();
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ assertFalse("Returned true for uncontained object", collection
+ .contains(value));
+
+ iter = enumColorMap.values().iterator();
+ value = iter.next();
+ assertTrue("Returned false for contained object", collection
+ .contains(value));
+ enumColorMap.put(Color.Green, 3);
+ assertTrue("Returned false for contained object", collection
+ .contains(value));
+ assertTrue("Returned false for contained object", collection
+ .remove(new Integer("1")));
+ assertEquals("Wrong size", 1, collection.size());
+ collection.clear();
+ assertEquals("Wrong size", 0, collection.size());
+
+ enumColorMap = new EnumMap<Color, Double>(Color.class);
+ Integer integer1 = new Integer(1);
+ enumColorMap.put(Color.Green, integer1);
+ enumColorMap.put(Color.Blue, null);
+ collection = enumColorMap.values();
+ iter = enumColorMap.values().iterator();
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ value = iter.next();
+ assertEquals("Wrong value", integer1, value);
+ assertSame("Wrong value", integer1, value);
+ assertFalse("Returned true for unequal object", iter.equals(value));
+ iter.remove();
+ assertFalse("Returned true for unequal object", iter.equals(value));
+ try {
+ iter.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ assertEquals("Wrong size", 1, collection.size());
+ value = iter.next();
+ assertFalse("Returned true for unequal object", iter.equals(value));
+ iter.remove();
+ try {
+ iter.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationSelf() throws Exception {
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ enumColorMap.put(Color.Blue, 3);
+ SerializationTest.verifySelf(enumColorMap);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationCompatibility() throws Exception {
+ EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
+ enumColorMap.put(Color.Red, 1);
+ enumColorMap.put(Color.Blue, 3);
+ SerializationTest.verifyGolden(this, enumColorMap);
+ }
+
+ /**
+ * Sets up the fixture.
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ /**
+ * Tears down the fixture.
+ */
+ @Override
+ protected void tearDown() throws Exception{
+ super.tearDown();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumSetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumSetTest.java
new file mode 100644
index 0000000..612c9f1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumSetTest.java
@@ -0,0 +1,2003 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class EnumSetTest extends TestCase {
+ static final boolean disableRIBugs = true;
+
+ static enum EnumWithInnerClass {
+ a, b, c, d, e, f {
+ },
+ }
+
+ enum EnumWithAllInnerClass {
+ a {},
+ b {},
+ }
+
+ static enum EnumFoo {
+ a, b,c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, aa, bb, cc, dd, ee, ff, gg, hh, ii, jj, kk, ll,
+ }
+
+ static enum EmptyEnum {
+ // expected
+ }
+
+ static enum HugeEnumWithInnerClass {
+ a{}, b{}, c{}, d{}, e{}, f{}, g{}, h{}, i{}, j{}, k{}, l{}, m{}, n{}, o{}, p{}, q{}, r{}, s{}, t{}, u{}, v{}, w{}, x{}, y{}, z{}, A{}, B{}, C{}, D{}, E{}, F{}, G{}, H{}, I{}, J{}, K{}, L{}, M{}, N{}, O{}, P{}, Q{}, R{}, S{}, T{}, U{}, V{}, W{}, X{}, Y{}, Z{}, aa{}, bb{}, cc{}, dd{}, ee{}, ff{}, gg{}, hh{}, ii{}, jj{}, kk{}, ll{}, mm{},
+ }
+
+ static enum HugeEnum {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, aa, bb, cc, dd, ee, ff, gg, hh, ii, jj, kk, ll, mm,
+ }
+
+ static enum HugeEnumCount {
+ NO1, NO2, NO3, NO4, NO5, NO6, NO7, NO8, NO9, NO10, NO11, NO12, NO13, NO14, NO15, NO16, NO17, NO18, NO19, NO20,
+ NO21, NO22, NO23, NO24, NO25, NO26, NO27, NO28, NO29, NO30, NO31, NO32, NO33, NO34, NO35, NO36, NO37, NO38, NO39, NO40,
+ NO41, NO42, NO43, NO44, NO45, NO46, NO47, NO48, NO49, NO50, NO51, NO52, NO53, NO54, NO55, NO56, NO57, NO58, NO59, NO60,
+ NO61, NO62, NO63, NO64, NO65, NO66, NO67, NO68, NO69, NO70, NO71, NO72, NO73, NO74, NO75, NO76, NO77, NO78, NO79, NO80,
+ NO81, NO82, NO83, NO84, NO85, NO86, NO87, NO88, NO89, NO90, NO91, NO92, NO93, NO94, NO95, NO96, NO97, NO98, NO99, NO100,
+ NO101, NO102, NO103, NO104, NO105, NO106, NO107, NO108, NO109, NO110, NO111, NO112, NO113, NO114, NO115, NO116, NO117, NO118, NO119, NO120,
+ NO121, NO122, NO123, NO124, NO125, NO126, NO127, NO128, NO129, NO130,
+ }
+
+ /**
+ * java.util.EnumSet#noneOf(java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_NoneOf_LClass() {
+ try {
+ EnumSet.noneOf((Class) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ EnumSet.noneOf(Enum.class);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException cce) {
+ // expected
+ }
+
+ Class<EnumWithAllInnerClass> c = (Class<EnumWithAllInnerClass>) EnumWithAllInnerClass.a
+ .getClass();
+ try {
+ EnumSet.noneOf(c);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ EnumSet<EnumWithAllInnerClass> setWithInnerClass = EnumSet
+ .noneOf(EnumWithAllInnerClass.class);
+ assertNotNull(setWithInnerClass);
+
+ // test enum type with more than 64 elements
+ Class<HugeEnumWithInnerClass> hc = (Class<HugeEnumWithInnerClass>) HugeEnumWithInnerClass.a
+ .getClass();
+ try {
+ EnumSet.noneOf(hc);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ EnumSet<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
+ .noneOf(HugeEnumWithInnerClass.class);
+ assertNotNull(hugeSetWithInnerClass);
+ }
+
+ /**
+ * java.util.HugeEnumSet#iterator()
+ */
+ public void test_iterator_HugeEnumSet() {
+ EnumSet<HugeEnumCount> set;
+ Object[] array;
+
+ // Test HugeEnumSet with 65 elements
+ // which is more than the bits of Long
+ set = EnumSet.range(HugeEnumCount.NO1, HugeEnumCount.NO65);
+ array = set.toArray();
+ for (HugeEnumCount count : set) {
+ assertEquals(count, (HugeEnumCount) array[count.ordinal()]);
+ }
+
+ // Test HugeEnumSet with 130 elements
+ // which is more than twice of the bits of Long
+ set = EnumSet.range(HugeEnumCount.NO1, HugeEnumCount.NO130);
+ array = set.toArray();
+ for (HugeEnumCount count : set) {
+ assertEquals(count, (HugeEnumCount) array[count.ordinal()]);
+ }
+ }
+
+ public void testRemoveIteratorRemoveFromHugeEnumSet() {
+ EnumSet<HugeEnumCount> set = EnumSet.noneOf(HugeEnumCount.class);
+ set.add(HugeEnumCount.NO64);
+ set.add(HugeEnumCount.NO65);
+ set.add(HugeEnumCount.NO128);
+ Iterator<HugeEnumCount> iterator = set.iterator();
+ assertTrue(iterator.hasNext());
+ assertEquals(HugeEnumCount.NO64, iterator.next());
+ assertTrue(iterator.hasNext());
+ iterator.remove();
+ assertEquals(HugeEnumCount.NO65, iterator.next());
+ assertTrue(iterator.hasNext());
+ assertEquals(HugeEnumCount.NO128, iterator.next());
+ assertFalse(iterator.hasNext());
+ assertEquals(EnumSet.of(HugeEnumCount.NO65, HugeEnumCount.NO128), set);
+ iterator.remove();
+ assertEquals(EnumSet.of(HugeEnumCount.NO65), set);
+ }
+
+ /**
+ * java.util.EnumSet#allOf(java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_AllOf_LClass() {
+ try {
+ EnumSet.allOf((Class) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ EnumSet.allOf(Enum.class);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException cce) {
+ // expected
+ }
+
+ EnumSet<EnumFoo> enumSet = EnumSet.allOf(EnumFoo.class);
+ assertEquals("Size of enumSet should be 64", 64, enumSet.size());
+
+ assertFalse(
+ "enumSet should not contain null value", enumSet.contains(null));
+ assertTrue(
+ "enumSet should contain EnumFoo.a", enumSet.contains(EnumFoo.a));
+ assertTrue(
+ "enumSet should contain EnumFoo.b", enumSet.contains(EnumFoo.b));
+
+ enumSet.add(EnumFoo.a);
+ assertEquals("Should be equal", 64, enumSet.size());
+
+ EnumSet<EnumFoo> anotherSet = EnumSet.allOf(EnumFoo.class);
+ assertEquals("Should be equal", enumSet, anotherSet);
+ assertNotSame("Should not be identical", enumSet, anotherSet);
+
+ // test enum with more than 64 elements
+ EnumSet<HugeEnum> hugeEnumSet = EnumSet.allOf(HugeEnum.class);
+ assertEquals(65, hugeEnumSet.size());
+
+ assertFalse(hugeEnumSet.contains(null));
+ assertTrue(hugeEnumSet.contains(HugeEnum.a));
+ assertTrue(hugeEnumSet.contains(HugeEnum.b));
+
+ hugeEnumSet.add(HugeEnum.a);
+ assertEquals(65, hugeEnumSet.size());
+
+ EnumSet<HugeEnum> anotherHugeSet = EnumSet.allOf(HugeEnum.class);
+ assertEquals(hugeEnumSet, anotherHugeSet);
+ assertNotSame(hugeEnumSet, anotherHugeSet);
+
+ }
+
+ /**
+ * java.util.EnumSet#add(E)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_add_E() {
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ set.add(EnumFoo.a);
+ set.add(EnumFoo.b);
+
+ try {
+ set.add(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ // test enum type with more than 64 elements
+ Set rawSet = set;
+ try {
+ rawSet.add(HugeEnumWithInnerClass.b);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ set.clear();
+ try {
+ set.add(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ boolean result = set.add(EnumFoo.a);
+ assertEquals("Size should be 1:", 1, set.size());
+ assertTrue("Return value should be true", result);
+
+ result = set.add(EnumFoo.a);
+ assertEquals("Size should be 1:", 1, set.size());
+ assertFalse("Return value should be false", result);
+
+ set.add(EnumFoo.b);
+ assertEquals("Size should be 2:", 2, set.size());
+
+ rawSet = set;
+ try {
+ rawSet.add(EnumWithAllInnerClass.a);
+ fail("Should throw ClassCastException");
+ } catch(ClassCastException e) {
+ // expected
+ }
+
+ try {
+ rawSet.add(EnumWithInnerClass.a);
+ fail("Should throw ClassCastException");
+ } catch(ClassCastException e) {
+ // expected
+ }
+
+ try {
+ rawSet.add(new Object());
+ fail("Should throw ClassCastException");
+ } catch(ClassCastException e) {
+ // expected
+ }
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
+ result = hugeSet.add(HugeEnum.a);
+ assertTrue(result);
+
+ result = hugeSet.add(HugeEnum.a);
+ assertFalse(result);
+
+ try {
+ hugeSet.add(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ rawSet = hugeSet;
+ try {
+ rawSet.add(HugeEnumWithInnerClass.b);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ try {
+ rawSet.add(new Object());
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ result = hugeSet.add(HugeEnum.mm);
+ assertTrue(result);
+ result = hugeSet.add(HugeEnum.mm);
+ assertFalse(result);
+ assertEquals(2, hugeSet.size());
+
+ }
+
+ /**
+ * java.util.EnumSet#addAll(Collection)
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void test_addAll_LCollection() {
+
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ assertEquals("Size should be 0:", 0, set.size());
+
+ try {
+ set.addAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ Set emptySet = EnumSet.noneOf(EmptyEnum.class);
+ Enum[] elements = EmptyEnum.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ emptySet.add(elements[i]);
+ }
+ boolean result = set.addAll(emptySet);
+ assertFalse(result);
+
+ Collection<EnumFoo> collection = new ArrayList<EnumFoo>();
+ collection.add(EnumFoo.a);
+ collection.add(EnumFoo.b);
+ result = set.addAll(collection);
+ assertTrue("addAll should be successful", result);
+ assertEquals("Size should be 2:", 2, set.size());
+
+ set = EnumSet.noneOf(EnumFoo.class);
+
+ Collection rawCollection = new ArrayList<Integer>();
+ result = set.addAll(rawCollection);
+ assertFalse(result);
+ rawCollection.add(1);
+ try {
+ set.addAll(rawCollection);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ Set<EnumFoo> fullSet = EnumSet.noneOf(EnumFoo.class);
+ fullSet.add(EnumFoo.a);
+ fullSet.add(EnumFoo.b);
+ result = set.addAll(fullSet);
+ assertTrue("addAll should be successful", result);
+ assertEquals("Size of set should be 2", 2, set.size());
+
+ try {
+ fullSet.addAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ Set fullSetWithSubclass = EnumSet.noneOf(EnumWithInnerClass.class);
+ elements = EnumWithInnerClass.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ fullSetWithSubclass.add(elements[i]);
+ }
+ try {
+ set.addAll(fullSetWithSubclass);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ Set<EnumWithInnerClass> setWithSubclass = fullSetWithSubclass;
+ result = setWithSubclass.addAll(setWithSubclass);
+ assertFalse("Should return false", result);
+
+ Set<EnumWithInnerClass> anotherSetWithSubclass = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ elements = EnumWithInnerClass.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ anotherSetWithSubclass.add((EnumWithInnerClass) elements[i]);
+ }
+ result = setWithSubclass.addAll(anotherSetWithSubclass);
+ assertFalse("Should return false", result);
+
+ anotherSetWithSubclass.remove(EnumWithInnerClass.a);
+ result = setWithSubclass.addAll(anotherSetWithSubclass);
+ assertFalse("Should return false", result);
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
+ assertEquals(0, hugeSet.size());
+
+ try {
+ hugeSet.addAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ hugeSet = EnumSet.allOf(HugeEnum.class);
+ result = hugeSet.addAll(hugeSet);
+ assertFalse(result);
+
+ hugeSet = EnumSet.noneOf(HugeEnum.class);
+ Collection<HugeEnum> hugeCollection = new ArrayList<HugeEnum>();
+ hugeCollection.add(HugeEnum.a);
+ hugeCollection.add(HugeEnum.b);
+ result = hugeSet.addAll(hugeCollection);
+ assertTrue(result);
+ assertEquals(2, set.size());
+
+ hugeSet = EnumSet.noneOf(HugeEnum.class);
+
+ rawCollection = new ArrayList<Integer>();
+ result = hugeSet.addAll(rawCollection);
+ assertFalse(result);
+ rawCollection.add(1);
+ try {
+ hugeSet.addAll(rawCollection);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ EnumSet<HugeEnum> aHugeSet = EnumSet.noneOf(HugeEnum.class);
+ aHugeSet.add(HugeEnum.a);
+ aHugeSet.add(HugeEnum.b);
+ result = hugeSet.addAll(aHugeSet);
+ assertTrue(result);
+ assertEquals(2, hugeSet.size());
+
+ try {
+ aHugeSet.addAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ Set hugeSetWithSubclass = EnumSet.allOf(HugeEnumWithInnerClass.class);
+ try {
+ hugeSet.addAll(hugeSetWithSubclass);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ Set<HugeEnumWithInnerClass> hugeSetWithInnerSubclass = hugeSetWithSubclass;
+ result = hugeSetWithInnerSubclass.addAll(hugeSetWithInnerSubclass);
+ assertFalse(result);
+
+ Set<HugeEnumWithInnerClass> anotherHugeSetWithSubclass = EnumSet
+ .allOf(HugeEnumWithInnerClass.class);
+ result = hugeSetWithSubclass.addAll(anotherHugeSetWithSubclass);
+ assertFalse(result);
+
+ anotherHugeSetWithSubclass.remove(HugeEnumWithInnerClass.a);
+ result = setWithSubclass.addAll(anotherSetWithSubclass);
+ assertFalse(result);
+
+ }
+
+ /**
+ * java.util.EnumSet#remove(Object)
+ */
+ public void test_remove_LOject() {
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ Enum[] elements = EnumFoo.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ set.add((EnumFoo) elements[i]);
+ }
+
+ boolean result = set.remove(null);
+ assertFalse("'set' does not contain null", result);
+
+ result = set.remove(EnumFoo.a);
+ assertTrue("Should return true", result);
+ result = set.remove(EnumFoo.a);
+ assertFalse("Should return false", result);
+
+ assertEquals("Size of set should be 63:", 63, set.size());
+
+ result = set.remove(EnumWithInnerClass.a);
+ assertFalse("Should return false", result);
+ result = set.remove(EnumWithInnerClass.f);
+ assertFalse("Should return false", result);
+
+ // test enum with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
+
+ result = hugeSet.remove(null);
+ assertFalse("'set' does not contain null", result);
+
+ result = hugeSet.remove(HugeEnum.a);
+ assertTrue("Should return true", result);
+ result = hugeSet.remove(HugeEnum.a);
+ assertFalse("Should return false", result);
+
+ assertEquals("Size of set should be 64:", 64, hugeSet.size());
+
+ result = hugeSet.remove(HugeEnumWithInnerClass.a);
+ assertFalse("Should return false", result);
+ result = hugeSet.remove(HugeEnumWithInnerClass.f);
+ assertFalse("Should return false", result);
+ }
+
+ /**
+ * java.util.EnumSet#equals(Object)
+ */
+ public void test_equals_LObject() {
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ Enum[] elements = EnumFoo.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ set.add((EnumFoo) elements[i]);
+ }
+
+ assertFalse("Should return false", set.equals(null));
+ assertFalse(
+ "Should return false", set.equals(new Object()));
+
+ Set<EnumFoo> anotherSet = EnumSet.noneOf(EnumFoo.class);
+ elements = EnumFoo.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ anotherSet.add((EnumFoo) elements[i]);
+ }
+ assertTrue("Should return true", set.equals(anotherSet));
+
+ anotherSet.remove(EnumFoo.a);
+ assertFalse(
+ "Should return false", set.equals(anotherSet));
+
+ Set<EnumWithInnerClass> setWithInnerClass = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ elements = EnumWithInnerClass.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ setWithInnerClass.add((EnumWithInnerClass) elements[i]);
+ }
+
+ assertFalse(
+ "Should return false", set.equals(setWithInnerClass));
+
+ setWithInnerClass.clear();
+ set.clear();
+ assertTrue("Should be equal", set.equals(setWithInnerClass));
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
+ assertTrue(hugeSet.equals(set));
+
+ hugeSet = EnumSet.allOf(HugeEnum.class);
+ assertFalse(hugeSet.equals(null));
+ assertFalse(hugeSet.equals(new Object()));
+
+ Set<HugeEnum> anotherHugeSet = EnumSet.allOf(HugeEnum.class);
+ anotherHugeSet.remove(HugeEnum.a);
+ assertFalse(hugeSet.equals(anotherHugeSet));
+
+ Set<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
+ .allOf(HugeEnumWithInnerClass.class);
+ assertFalse(hugeSet.equals(hugeSetWithInnerClass));
+ hugeSetWithInnerClass.clear();
+ hugeSet.clear();
+ assertTrue(hugeSet.equals(hugeSetWithInnerClass));
+ }
+
+ /**
+ * java.util.EnumSet#clear()
+ */
+ public void test_clear() {
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ set.add(EnumFoo.a);
+ set.add(EnumFoo.b);
+ assertEquals("Size should be 2", 2, set.size());
+
+ set.clear();
+
+ assertEquals("Size should be 0", 0, set.size());
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
+ assertEquals(65, hugeSet.size());
+
+ boolean result = hugeSet.contains(HugeEnum.aa);
+ assertTrue(result);
+
+ hugeSet.clear();
+ assertEquals(0, hugeSet.size());
+ result = hugeSet.contains(HugeEnum.aa);
+ assertFalse(result);
+ }
+
+ /**
+ * java.util.EnumSet#size()
+ */
+ public void test_size() {
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ set.add(EnumFoo.a);
+ set.add(EnumFoo.b);
+ assertEquals("Size should be 2", 2, set.size());
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
+ hugeSet.add(HugeEnum.a);
+ hugeSet.add(HugeEnum.bb);
+ assertEquals("Size should be 2", 2, hugeSet.size());
+ }
+
+ /**
+ * java.util.EnumSet#complementOf(java.util.EnumSet)
+ */
+ public void test_ComplementOf_LEnumSet() {
+
+ try {
+ EnumSet.complementOf((EnumSet<EnumFoo>) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ EnumSet<EnumWithInnerClass> set = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ set.add(EnumWithInnerClass.d);
+ set.add(EnumWithInnerClass.e);
+ set.add(EnumWithInnerClass.f);
+
+ assertEquals("Size should be 3:", 3, set.size());
+
+ EnumSet<EnumWithInnerClass> complementOfE = EnumSet.complementOf(set);
+ assertTrue(set.contains(EnumWithInnerClass.d));
+ assertEquals(
+ "complementOfE should have size 3", 3, complementOfE.size());
+ assertTrue("complementOfE should contain EnumWithSubclass.a:",
+ complementOfE.contains(EnumWithInnerClass.a));
+ assertTrue("complementOfE should contain EnumWithSubclass.b:",
+ complementOfE.contains(EnumWithInnerClass.b));
+ assertTrue("complementOfE should contain EnumWithSubclass.c:",
+ complementOfE.contains(EnumWithInnerClass.c));
+
+ // test enum type with more than 64 elements
+ EnumSet<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
+ assertEquals(0, hugeSet.size());
+ Set<HugeEnum> complementHugeSet = EnumSet.complementOf(hugeSet);
+ assertEquals(65, complementHugeSet.size());
+
+ hugeSet.add(HugeEnum.A);
+ hugeSet.add(HugeEnum.mm);
+ complementHugeSet = EnumSet.complementOf(hugeSet);
+ assertEquals(63, complementHugeSet.size());
+
+ try {
+ EnumSet.complementOf((EnumSet<HugeEnum>) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.EnumSet#contains(Object)
+ */
+ public void test_contains_LObject() {
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ Enum[] elements = EnumFoo.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ set.add((EnumFoo)elements[i]);
+ }
+ boolean result = set.contains(null);
+ assertFalse("Should not contain null:", result);
+
+ result = set.contains(EnumFoo.a);
+ assertTrue("Should contain EnumFoo.a", result);
+ result = set.contains(EnumFoo.ll);
+ assertTrue("Should contain EnumFoo.ll", result);
+
+ result = set.contains(EnumFoo.b);
+ assertTrue("Should contain EnumFoo.b", result);
+
+ result = set.contains(new Object());
+ assertFalse("Should not contain Object instance", result);
+
+ result = set.contains(EnumWithInnerClass.a);
+ assertFalse("Should not contain EnumWithSubclass.a", result);
+
+ set = EnumSet.noneOf(EnumFoo.class);
+ set.add(EnumFoo.aa);
+ set.add(EnumFoo.bb);
+ set.add(EnumFoo.cc);
+
+ assertEquals("Size of set should be 3", 3, set.size());
+ assertTrue("set should contain EnumFoo.aa", set.contains(EnumFoo.aa));
+
+ Set<EnumWithInnerClass> setWithSubclass = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ setWithSubclass.add(EnumWithInnerClass.a);
+ setWithSubclass.add(EnumWithInnerClass.b);
+ setWithSubclass.add(EnumWithInnerClass.c);
+ setWithSubclass.add(EnumWithInnerClass.d);
+ setWithSubclass.add(EnumWithInnerClass.e);
+ setWithSubclass.add(EnumWithInnerClass.f);
+ result = setWithSubclass.contains(EnumWithInnerClass.f);
+ assertTrue("Should contain EnumWithSubclass.f", result);
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
+ hugeSet.add(HugeEnum.a);
+ result = hugeSet.contains(HugeEnum.a);
+ assertTrue(result);
+
+ result = hugeSet.contains(HugeEnum.b);
+ assertTrue(result);
+
+ result = hugeSet.contains(null);
+ assertFalse(result);
+
+ result = hugeSet.contains(HugeEnum.a);
+ assertTrue(result);
+
+ result = hugeSet.contains(HugeEnum.ll);
+ assertTrue(result);
+
+ result = hugeSet.contains(new Object());
+ assertFalse(result);
+
+ result = hugeSet.contains(Enum.class);
+ assertFalse(result);
+
+ }
+
+ /**
+ * java.util.EnumSet#containsAll(Collection)
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void test_containsAll_LCollection() {
+ EnumSet<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ Enum[] elements = EnumFoo.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ set.add((EnumFoo)elements[i]);
+ }
+ try {
+ set.containsAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ EnumSet<EmptyEnum> emptySet = EnumSet.noneOf(EmptyEnum.class);
+ elements = EmptyEnum.class.getEnumConstants();
+ for(int i = 0; i < elements.length; i++) {
+ emptySet.add((EmptyEnum)elements[i]);
+ }
+ boolean result = set.containsAll(emptySet);
+ assertTrue("Should return true", result);
+
+ Collection rawCollection = new ArrayList();
+ result = set.containsAll(rawCollection);
+ assertTrue("Should contain empty collection:", result);
+
+ rawCollection.add(1);
+ result = set.containsAll(rawCollection);
+ assertFalse("Should return false", result);
+
+ rawCollection.add(EnumWithInnerClass.a);
+ result = set.containsAll(rawCollection);
+ assertFalse("Should return false", result);
+
+ EnumSet rawSet = EnumSet.noneOf(EnumFoo.class);
+ result = set.containsAll(rawSet);
+ assertTrue("Should contain empty set", result);
+
+ emptySet = EnumSet.noneOf(EmptyEnum.class);
+ result = set.containsAll(emptySet);
+ assertTrue("No class cast should be performed on empty set", result);
+
+ Collection<EnumFoo> collection = new ArrayList<EnumFoo>();
+ collection.add(EnumFoo.a);
+ result = set.containsAll(collection);
+ assertTrue("Should contain all elements in collection", result);
+
+ EnumSet<EnumFoo> fooSet = EnumSet.noneOf(EnumFoo.class);
+ fooSet.add(EnumFoo.a);
+ result = set.containsAll(fooSet);
+ assertTrue("Should return true", result);
+
+ set.clear();
+ try {
+ set.containsAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ Collection<EnumWithInnerClass> collectionWithSubclass = new ArrayList<EnumWithInnerClass>();
+ collectionWithSubclass.add(EnumWithInnerClass.a);
+ result = set.containsAll(collectionWithSubclass);
+ assertFalse("Should return false", result);
+
+ EnumSet<EnumWithInnerClass> setWithSubclass = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ setWithSubclass.add(EnumWithInnerClass.a);
+ result = set.containsAll(setWithSubclass);
+ assertFalse("Should return false", result);
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
+ hugeSet.add(HugeEnum.a);
+ hugeSet.add(HugeEnum.b);
+ hugeSet.add(HugeEnum.aa);
+ hugeSet.add(HugeEnum.bb);
+ hugeSet.add(HugeEnum.cc);
+ hugeSet.add(HugeEnum.dd);
+
+ Set<HugeEnum> anotherHugeSet = EnumSet.noneOf(HugeEnum.class);
+ hugeSet.add(HugeEnum.b);
+ hugeSet.add(HugeEnum.cc);
+ result = hugeSet.containsAll(anotherHugeSet);
+ assertTrue(result);
+
+ try {
+ hugeSet.containsAll(null);
+ fail("Should throw NullPointerException");
+ } catch(NullPointerException e) {
+ // expected
+ }
+
+ Set<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
+ .noneOf(HugeEnumWithInnerClass.class);
+ hugeSetWithInnerClass.add(HugeEnumWithInnerClass.a);
+ hugeSetWithInnerClass.add(HugeEnumWithInnerClass.b);
+ result = hugeSetWithInnerClass.containsAll(hugeSetWithInnerClass);
+ assertTrue(result);
+ result = hugeSet.containsAll(hugeSetWithInnerClass);
+ assertFalse(result);
+
+ rawCollection = new ArrayList();
+ result = hugeSet.containsAll(rawCollection);
+ assertTrue("Should contain empty collection:", result);
+
+ rawCollection.add(1);
+ result = hugeSet.containsAll(rawCollection);
+ assertFalse("Should return false", result);
+
+ rawCollection.add(EnumWithInnerClass.a);
+ result = set.containsAll(rawCollection);
+ assertFalse("Should return false", result);
+
+ rawSet = EnumSet.noneOf(HugeEnum.class);
+ result = hugeSet.containsAll(rawSet);
+ assertTrue("Should contain empty set", result);
+
+ EnumSet<HugeEnumWithInnerClass> emptyHugeSet
+ = EnumSet.noneOf(HugeEnumWithInnerClass.class);
+ result = hugeSet.containsAll(emptyHugeSet);
+ assertTrue("No class cast should be performed on empty set", result);
+
+ Collection<HugeEnum> hugeCollection = new ArrayList<HugeEnum>();
+ hugeCollection.add(HugeEnum.a);
+ result = hugeSet.containsAll(hugeCollection);
+ assertTrue("Should contain all elements in collection", result);
+
+ hugeSet.clear();
+ try {
+ hugeSet.containsAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ Collection<HugeEnumWithInnerClass> hugeCollectionWithSubclass = new ArrayList<HugeEnumWithInnerClass>();
+ hugeCollectionWithSubclass.add(HugeEnumWithInnerClass.a);
+ result = hugeSet.containsAll(hugeCollectionWithSubclass);
+ assertFalse("Should return false", result);
+
+ EnumSet<HugeEnumWithInnerClass> hugeSetWithSubclass = EnumSet
+ .noneOf(HugeEnumWithInnerClass.class);
+ hugeSetWithSubclass.add(HugeEnumWithInnerClass.a);
+ result = hugeSet.containsAll(hugeSetWithSubclass);
+ assertFalse("Should return false", result);
+ }
+
+ /**
+ * java.util.EnumSet#copyOf(java.util.Collection)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_CopyOf_LCollection() {
+ try {
+ EnumSet.copyOf((Collection) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ Collection collection = new ArrayList();
+ try {
+ EnumSet.copyOf(collection);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ collection.add(new Object());
+ try {
+ EnumSet.copyOf(collection);
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ Collection<EnumFoo> enumCollection = new ArrayList<EnumFoo>();
+ enumCollection.add(EnumFoo.b);
+
+ EnumSet<EnumFoo> copyOfEnumCollection = EnumSet.copyOf(enumCollection);
+ assertEquals("Size of copyOfEnumCollection should be 1:",
+ 1, copyOfEnumCollection.size());
+ assertTrue("copyOfEnumCollection should contain EnumFoo.b:",
+ copyOfEnumCollection.contains(EnumFoo.b));
+
+ enumCollection.add(null);
+ assertEquals("Size of enumCollection should be 2:",
+ 2, enumCollection.size());
+
+ try {
+ copyOfEnumCollection = EnumSet.copyOf(enumCollection);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ Collection rawEnumCollection = new ArrayList();
+ rawEnumCollection.add(EnumFoo.a);
+ rawEnumCollection.add(EnumWithInnerClass.a);
+ try {
+ EnumSet.copyOf(rawEnumCollection);
+ fail("Should throw ClassCastException");
+ } catch(ClassCastException e) {
+ // expected
+ }
+
+ // test enum type with more than 64 elements
+ Collection<HugeEnum> hugeEnumCollection = new ArrayList<HugeEnum>();
+ hugeEnumCollection.add(HugeEnum.b);
+
+ EnumSet<HugeEnum> copyOfHugeEnumCollection = EnumSet.copyOf(hugeEnumCollection);
+ assertEquals(1, copyOfHugeEnumCollection.size());
+ assertTrue(copyOfHugeEnumCollection.contains(HugeEnum.b));
+
+ hugeEnumCollection.add(null);
+ assertEquals(2, hugeEnumCollection.size());
+
+ try {
+ copyOfHugeEnumCollection = EnumSet.copyOf(hugeEnumCollection);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ rawEnumCollection = new ArrayList();
+ rawEnumCollection.add(HugeEnum.a);
+ rawEnumCollection.add(HugeEnumWithInnerClass.a);
+ try {
+ EnumSet.copyOf(rawEnumCollection);
+ fail("Should throw ClassCastException");
+ } catch(ClassCastException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.EnumSet#copyOf(java.util.EnumSet)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_CopyOf_LEnumSet() {
+ EnumSet<EnumWithInnerClass> enumSet = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ enumSet.add(EnumWithInnerClass.a);
+ enumSet.add(EnumWithInnerClass.f);
+ EnumSet<EnumWithInnerClass> copyOfE = EnumSet.copyOf(enumSet);
+ assertEquals("Size of enumSet and copyOfE should be equal",
+ enumSet.size(), copyOfE.size());
+
+ assertTrue("EnumWithSubclass.a should be contained in copyOfE",
+ copyOfE.contains(EnumWithInnerClass.a));
+ assertTrue("EnumWithSubclass.f should be contained in copyOfE",
+ copyOfE.contains(EnumWithInnerClass.f));
+
+ Object[] enumValue = copyOfE.toArray();
+ assertSame("enumValue[0] should be identical with EnumWithSubclass.a",
+ enumValue[0], EnumWithInnerClass.a);
+ assertSame("enumValue[1] should be identical with EnumWithSubclass.f",
+ enumValue[1], EnumWithInnerClass.f);
+
+ try {
+ EnumSet.copyOf((EnumSet) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ // test enum type with more than 64 elements
+ EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet
+ .noneOf(HugeEnumWithInnerClass.class);
+ hugeEnumSet.add(HugeEnumWithInnerClass.a);
+ hugeEnumSet.add(HugeEnumWithInnerClass.f);
+ EnumSet<HugeEnumWithInnerClass> copyOfHugeEnum = EnumSet.copyOf(hugeEnumSet);
+ assertEquals(enumSet.size(), copyOfE.size());
+
+ assertTrue(copyOfHugeEnum.contains(HugeEnumWithInnerClass.a));
+ assertTrue(copyOfHugeEnum.contains(HugeEnumWithInnerClass.f));
+
+ Object[] hugeEnumValue = copyOfHugeEnum.toArray();
+ assertSame(hugeEnumValue[0], HugeEnumWithInnerClass.a);
+ assertSame(hugeEnumValue[1], HugeEnumWithInnerClass.f);
+ }
+
+ /**
+ * java.util.EnumSet#removeAll(Collection)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_removeAll_LCollection() {
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ try {
+ set.removeAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ set = EnumSet.allOf(EnumFoo.class);
+ assertEquals("Size of set should be 64:", 64, set.size());
+
+ try {
+ set.removeAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ Collection<EnumFoo> collection = new ArrayList<EnumFoo>();
+ collection.add(EnumFoo.a);
+
+ boolean result = set.removeAll(collection);
+ assertTrue("Should return true", result);
+ assertEquals("Size of set should be 63", 63, set.size());
+
+ collection = new ArrayList();
+ result = set.removeAll(collection);
+ assertFalse("Should return false", result);
+
+ Set<EmptyEnum> emptySet = EnumSet.noneOf(EmptyEnum.class);
+ result = set.removeAll(emptySet);
+ assertFalse("Should return false", result);
+
+ EnumSet<EnumFoo> emptyFooSet = EnumSet.noneOf(EnumFoo.class);
+ result = set.removeAll(emptyFooSet);
+ assertFalse("Should return false", result);
+
+ emptyFooSet.add(EnumFoo.a);
+ result = set.removeAll(emptyFooSet);
+ assertFalse("Should return false", result);
+
+ Set<EnumWithInnerClass> setWithSubclass = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ result = set.removeAll(setWithSubclass);
+ assertFalse("Should return false", result);
+
+ setWithSubclass.add(EnumWithInnerClass.a);
+ result = set.removeAll(setWithSubclass);
+ assertFalse("Should return false", result);
+
+ Set<EnumFoo> anotherSet = EnumSet.noneOf(EnumFoo.class);
+ anotherSet.add(EnumFoo.a);
+
+ set = EnumSet.allOf(EnumFoo.class);
+ result = set.removeAll(anotherSet);
+ assertTrue("Should return true", result);
+ assertEquals("Size of set should be 63:", 63, set.size());
+
+ Set<EnumWithInnerClass> setWithInnerClass = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ setWithInnerClass.add(EnumWithInnerClass.a);
+ setWithInnerClass.add(EnumWithInnerClass.b);
+
+ Set<EnumWithInnerClass> anotherSetWithInnerClass = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ anotherSetWithInnerClass.add(EnumWithInnerClass.c);
+ anotherSetWithInnerClass.add(EnumWithInnerClass.d);
+ result = anotherSetWithInnerClass.removeAll(setWithInnerClass);
+ assertFalse("Should return false", result);
+
+ anotherSetWithInnerClass.add(EnumWithInnerClass.a);
+ result = anotherSetWithInnerClass.removeAll(setWithInnerClass);
+ assertTrue("Should return true", result);
+ assertEquals("Size of anotherSetWithInnerClass should remain 2",
+ 2, anotherSetWithInnerClass.size());
+
+ anotherSetWithInnerClass.remove(EnumWithInnerClass.c);
+ anotherSetWithInnerClass.remove(EnumWithInnerClass.d);
+ result = anotherSetWithInnerClass.remove(setWithInnerClass);
+ assertFalse("Should return false", result);
+
+ Set rawSet = EnumSet.allOf(EnumWithAllInnerClass.class);
+ result = rawSet.removeAll(EnumSet.allOf(EnumFoo.class));
+ assertFalse("Should return false", result);
+
+ setWithInnerClass = EnumSet.allOf(EnumWithInnerClass.class);
+ anotherSetWithInnerClass = EnumSet.allOf(EnumWithInnerClass.class);
+ setWithInnerClass.remove(EnumWithInnerClass.a);
+ anotherSetWithInnerClass.remove(EnumWithInnerClass.f);
+ result = setWithInnerClass.removeAll(anotherSetWithInnerClass);
+ assertTrue("Should return true", result);
+ assertEquals("Size of setWithInnerClass should be 1", 1, setWithInnerClass.size());
+
+ result = setWithInnerClass.contains(EnumWithInnerClass.f);
+ assertTrue("Should return true", result);
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
+
+ Collection<HugeEnum> hugeCollection = new ArrayList<HugeEnum>();
+ hugeCollection.add(HugeEnum.a);
+
+ result = hugeSet.removeAll(hugeCollection);
+ assertTrue(result);
+ assertEquals(64, hugeSet.size());
+
+ collection = new ArrayList();
+ result = hugeSet.removeAll(collection);
+ assertFalse(result);
+
+ Set<HugeEnum> emptyHugeSet = EnumSet.noneOf(HugeEnum.class);
+ result = hugeSet.removeAll(emptyHugeSet);
+ assertFalse(result);
+
+ Set<HugeEnumWithInnerClass> hugeSetWithSubclass = EnumSet
+ .noneOf(HugeEnumWithInnerClass.class);
+ result = hugeSet.removeAll(hugeSetWithSubclass);
+ assertFalse(result);
+
+ hugeSetWithSubclass.add(HugeEnumWithInnerClass.a);
+ result = hugeSet.removeAll(hugeSetWithSubclass);
+ assertFalse(result);
+
+ Set<HugeEnum> anotherHugeSet = EnumSet.noneOf(HugeEnum.class);
+ anotherHugeSet.add(HugeEnum.a);
+
+ hugeSet = EnumSet.allOf(HugeEnum.class);
+ result = hugeSet.removeAll(anotherHugeSet);
+ assertTrue(result);
+ assertEquals(63, set.size());
+
+ Set<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
+ .noneOf(HugeEnumWithInnerClass.class);
+ hugeSetWithInnerClass.add(HugeEnumWithInnerClass.a);
+ hugeSetWithInnerClass.add(HugeEnumWithInnerClass.b);
+
+ Set<HugeEnumWithInnerClass> anotherHugeSetWithInnerClass = EnumSet
+ .noneOf(HugeEnumWithInnerClass.class);
+ anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.c);
+ anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.d);
+ result = anotherHugeSetWithInnerClass.removeAll(setWithInnerClass);
+ assertFalse("Should return false", result);
+
+ anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.a);
+ result = anotherHugeSetWithInnerClass.removeAll(hugeSetWithInnerClass);
+ assertTrue(result);
+ assertEquals(2, anotherHugeSetWithInnerClass.size());
+
+ anotherHugeSetWithInnerClass.remove(HugeEnumWithInnerClass.c);
+ anotherHugeSetWithInnerClass.remove(HugeEnumWithInnerClass.d);
+ result = anotherHugeSetWithInnerClass.remove(hugeSetWithInnerClass);
+ assertFalse(result);
+
+ rawSet = EnumSet.allOf(HugeEnumWithInnerClass.class);
+ result = rawSet.removeAll(EnumSet.allOf(HugeEnum.class));
+ assertFalse(result);
+
+ hugeSetWithInnerClass = EnumSet.allOf(HugeEnumWithInnerClass.class);
+ anotherHugeSetWithInnerClass = EnumSet.allOf(HugeEnumWithInnerClass.class);
+ hugeSetWithInnerClass.remove(HugeEnumWithInnerClass.a);
+ anotherHugeSetWithInnerClass.remove(HugeEnumWithInnerClass.f);
+ result = hugeSetWithInnerClass.removeAll(anotherHugeSetWithInnerClass);
+ assertTrue(result);
+ assertEquals(1, hugeSetWithInnerClass.size());
+
+ result = hugeSetWithInnerClass.contains(HugeEnumWithInnerClass.f);
+ assertTrue(result);
+ }
+
+ /**
+ * java.util.EnumSet#retainAll(Collection)
+ */
+ @SuppressWarnings("unchecked")
+ public void test_retainAll_LCollection() {
+ Set<EnumFoo> set = EnumSet.allOf(EnumFoo.class);
+
+ try {
+ set.retainAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ set.clear();
+ boolean result = set.retainAll(null);
+ assertFalse("Should return false", result);
+
+ Collection rawCollection = new ArrayList();
+ result = set.retainAll(rawCollection);
+ assertFalse("Should return false", result);
+
+ rawCollection.add(EnumFoo.a);
+ result = set.retainAll(rawCollection);
+ assertFalse("Should return false", result);
+
+ rawCollection.add(EnumWithInnerClass.a);
+ result = set.retainAll(rawCollection);
+ assertFalse("Should return false", result);
+ assertEquals("Size of set should be 0:", 0, set.size());
+
+ rawCollection.remove(EnumFoo.a);
+ result = set.retainAll(rawCollection);
+ assertFalse("Should return false", result);
+
+ Set<EnumFoo> anotherSet = EnumSet.allOf(EnumFoo.class);
+ result = set.retainAll(anotherSet);
+ assertFalse("Should return false", result);
+ assertEquals("Size of set should be 0", 0, set.size());
+
+ Set<EnumWithInnerClass> setWithInnerClass = EnumSet
+ .allOf(EnumWithInnerClass.class);
+ result = set.retainAll(setWithInnerClass);
+ assertFalse("Should return false", result);
+ assertEquals("Size of set should be 0", 0, set.size());
+
+ setWithInnerClass = EnumSet.noneOf(EnumWithInnerClass.class);
+ result = set.retainAll(setWithInnerClass);
+ assertFalse("Should return false", result);
+
+ Set<EmptyEnum> emptySet = EnumSet.allOf(EmptyEnum.class);
+ result = set.retainAll(emptySet);
+ assertFalse("Should return false", result);
+
+ Set<EnumWithAllInnerClass> setWithAllInnerClass = EnumSet
+ .allOf(EnumWithAllInnerClass.class);
+ result = set.retainAll(setWithAllInnerClass);
+ assertFalse("Should return false", result);
+
+ set.add(EnumFoo.a);
+ result = set.retainAll(setWithInnerClass);
+ assertTrue("Should return true", result);
+ assertEquals("Size of set should be 0", 0, set.size());
+
+ setWithInnerClass = EnumSet.allOf(EnumWithInnerClass.class);
+ setWithInnerClass.remove(EnumWithInnerClass.f);
+ Set<EnumWithInnerClass> anotherSetWithInnerClass = EnumSet
+ .noneOf(EnumWithInnerClass.class);
+ anotherSetWithInnerClass.add(EnumWithInnerClass.e);
+ anotherSetWithInnerClass.add(EnumWithInnerClass.f);
+
+ result = setWithInnerClass.retainAll(anotherSetWithInnerClass);
+ assertTrue("Should return true", result);
+ result = setWithInnerClass.contains(EnumWithInnerClass.e);
+ assertTrue("Should contain EnumWithInnerClass.e", result);
+ result = setWithInnerClass.contains(EnumWithInnerClass.b);
+ assertFalse("Should not contain EnumWithInnerClass.b", result);
+ assertEquals("Size of set should be 1:", 1, setWithInnerClass.size());
+
+ anotherSetWithInnerClass = EnumSet.allOf(EnumWithInnerClass.class);
+ result = setWithInnerClass.retainAll(anotherSetWithInnerClass);
+
+ assertFalse("Return value should be false", result);
+
+ rawCollection = new ArrayList();
+ rawCollection.add(EnumWithInnerClass.e);
+ rawCollection.add(EnumWithInnerClass.f);
+ result = setWithInnerClass.retainAll(rawCollection);
+ assertFalse("Should return false", result);
+
+ set = EnumSet.allOf(EnumFoo.class);
+ set.remove(EnumFoo.a);
+ anotherSet = EnumSet.noneOf(EnumFoo.class);
+ anotherSet.add(EnumFoo.a);
+ result = set.retainAll(anotherSet);
+ assertTrue("Should return true", result);
+ assertEquals("size should be 0", 0, set.size());
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
+
+ try {
+ hugeSet.retainAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ hugeSet.clear();
+ result = hugeSet.retainAll(null);
+ assertFalse(result);
+
+ rawCollection = new ArrayList();
+ result = hugeSet.retainAll(rawCollection);
+ assertFalse(result);
+
+ rawCollection.add(HugeEnum.a);
+ result = hugeSet.retainAll(rawCollection);
+ assertFalse(result);
+
+ rawCollection.add(HugeEnumWithInnerClass.a);
+ result = hugeSet.retainAll(rawCollection);
+ assertFalse(result);
+ assertEquals(0, set.size());
+
+ rawCollection.remove(HugeEnum.a);
+ result = set.retainAll(rawCollection);
+ assertFalse(result);
+
+ Set<HugeEnum> anotherHugeSet = EnumSet.allOf(HugeEnum.class);
+ result = hugeSet.retainAll(anotherHugeSet);
+ assertFalse(result);
+ assertEquals(0, hugeSet.size());
+
+ Set<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
+ .allOf(HugeEnumWithInnerClass.class);
+ result = hugeSet.retainAll(hugeSetWithInnerClass);
+ assertFalse(result);
+ assertEquals(0, hugeSet.size());
+
+ hugeSetWithInnerClass = EnumSet.noneOf(HugeEnumWithInnerClass.class);
+ result = hugeSet.retainAll(hugeSetWithInnerClass);
+ assertFalse(result);
+
+ Set<HugeEnumWithInnerClass> hugeSetWithAllInnerClass = EnumSet
+ .allOf(HugeEnumWithInnerClass.class);
+ result = hugeSet.retainAll(hugeSetWithAllInnerClass);
+ assertFalse(result);
+
+ hugeSet.add(HugeEnum.a);
+ result = hugeSet.retainAll(hugeSetWithInnerClass);
+ assertTrue(result);
+ assertEquals(0, hugeSet.size());
+
+ hugeSetWithInnerClass = EnumSet.allOf(HugeEnumWithInnerClass.class);
+ hugeSetWithInnerClass.remove(HugeEnumWithInnerClass.f);
+ Set<HugeEnumWithInnerClass> anotherHugeSetWithInnerClass = EnumSet
+ .noneOf(HugeEnumWithInnerClass.class);
+ anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.e);
+ anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.f);
+
+ result = hugeSetWithInnerClass.retainAll(anotherHugeSetWithInnerClass);
+ assertTrue(result);
+ result = hugeSetWithInnerClass.contains(HugeEnumWithInnerClass.e);
+ assertTrue("Should contain HugeEnumWithInnerClass.e", result);
+ result = hugeSetWithInnerClass.contains(HugeEnumWithInnerClass.b);
+ assertFalse("Should not contain HugeEnumWithInnerClass.b", result);
+ assertEquals("Size of hugeSet should be 1:", 1, hugeSetWithInnerClass.size());
+
+ anotherHugeSetWithInnerClass = EnumSet.allOf(HugeEnumWithInnerClass.class);
+ result = hugeSetWithInnerClass.retainAll(anotherHugeSetWithInnerClass);
+
+ assertFalse("Return value should be false", result);
+
+ rawCollection = new ArrayList();
+ rawCollection.add(HugeEnumWithInnerClass.e);
+ rawCollection.add(HugeEnumWithInnerClass.f);
+ result = hugeSetWithInnerClass.retainAll(rawCollection);
+ assertFalse(result);
+
+ hugeSet = EnumSet.allOf(HugeEnum.class);
+ hugeSet.remove(HugeEnum.a);
+ anotherHugeSet = EnumSet.noneOf(HugeEnum.class);
+ anotherHugeSet.add(HugeEnum.a);
+ result = hugeSet.retainAll(anotherHugeSet);
+ assertTrue(result);
+ assertEquals(0, hugeSet.size());
+ }
+
+ /**
+ * java.util.EnumSet#iterator()
+ */
+ public void test_iterator() {
+ Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+ set.add(EnumFoo.a);
+ set.add(EnumFoo.b);
+
+ Iterator<EnumFoo> iterator = set.iterator();
+ Iterator<EnumFoo> anotherIterator = set.iterator();
+ assertNotSame("Should not be same", iterator, anotherIterator);
+ try {
+ iterator.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expectedd
+ }
+
+ assertTrue("Should has next element:", iterator.hasNext());
+ assertSame("Should be identical", EnumFoo.a, iterator.next());
+ iterator.remove();
+ assertTrue("Should has next element:", iterator.hasNext());
+ assertSame("Should be identical", EnumFoo.b, iterator.next());
+ assertFalse("Should not has next element:", iterator.hasNext());
+ assertFalse("Should not has next element:", iterator.hasNext());
+
+ assertEquals("Size should be 1:", 1, set.size());
+
+ try {
+ iterator.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ set = EnumSet.noneOf(EnumFoo.class);
+ set.add(EnumFoo.a);
+ iterator = set.iterator();
+ assertEquals("Should be equal", EnumFoo.a, iterator.next());
+ iterator.remove();
+ try {
+ iterator.remove();
+ fail("Should throw IllegalStateException");
+ } catch(IllegalStateException e) {
+ // expected
+ }
+
+ Set<EmptyEnum> emptySet = EnumSet.allOf(EmptyEnum.class);
+ Iterator<EmptyEnum> emptyIterator = emptySet.iterator();
+ try {
+ emptyIterator.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ Set<EnumWithInnerClass> setWithSubclass = EnumSet
+ .allOf(EnumWithInnerClass.class);
+ setWithSubclass.remove(EnumWithInnerClass.e);
+ Iterator<EnumWithInnerClass> iteratorWithSubclass = setWithSubclass
+ .iterator();
+ assertSame("Should be same", EnumWithInnerClass.a, iteratorWithSubclass.next());
+
+ assertTrue("Should return true", iteratorWithSubclass.hasNext());
+ assertSame("Should be same", EnumWithInnerClass.b, iteratorWithSubclass.next());
+
+ setWithSubclass.remove(EnumWithInnerClass.c);
+ assertTrue("Should return true", iteratorWithSubclass.hasNext());
+ assertSame("Should be same", EnumWithInnerClass.c, iteratorWithSubclass.next());
+
+ assertTrue("Should return true", iteratorWithSubclass.hasNext());
+ assertSame("Should be same", EnumWithInnerClass.d, iteratorWithSubclass.next());
+
+ setWithSubclass.add(EnumWithInnerClass.e);
+ assertTrue("Should return true", iteratorWithSubclass.hasNext());
+ assertSame("Should be same", EnumWithInnerClass.f, iteratorWithSubclass.next());
+
+ set = EnumSet.noneOf(EnumFoo.class);
+ iterator = set.iterator();
+ try {
+ iterator.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ set.add(EnumFoo.a);
+ iterator = set.iterator();
+ assertEquals("Should return EnumFoo.a", EnumFoo.a, iterator.next());
+ assertEquals("Size of set should be 1", 1, set.size());
+ iterator.remove();
+ assertEquals("Size of set should be 0", 0, set.size());
+ assertFalse("Should return false", set.contains(EnumFoo.a));
+
+ set.add(EnumFoo.a);
+ set.add(EnumFoo.b);
+ iterator = set.iterator();
+ assertEquals("Should be equals", EnumFoo.a, iterator.next());
+ iterator.remove();
+ try {
+ iterator.remove();
+ fail("Should throw IllegalStateException");
+ } catch(IllegalStateException e) {
+ // expected
+ }
+
+ assertTrue("Should have next element", iterator.hasNext());
+ try {
+ iterator.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ assertEquals("Size of set should be 1", 1, set.size());
+ assertTrue("Should have next element", iterator.hasNext());
+ assertEquals("Should return EnumFoo.b", EnumFoo.b, iterator.next());
+ set.remove(EnumFoo.b);
+ assertEquals("Size of set should be 0", 0, set.size());
+ iterator.remove();
+ assertFalse("Should return false", set.contains(EnumFoo.a));
+
+ // RI's bug, EnumFoo.b should not exist at the moment.
+ if (!disableRIBugs) {
+ assertFalse("Should return false", set.contains(EnumFoo.b));
+ }
+
+ // test enum type with more than 64 elements
+ Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
+ hugeSet.add(HugeEnum.a);
+ hugeSet.add(HugeEnum.b);
+
+ Iterator<HugeEnum> hIterator = hugeSet.iterator();
+ Iterator<HugeEnum> anotherHugeIterator = hugeSet.iterator();
+ assertNotSame(hIterator, anotherHugeIterator);
+ try {
+ hIterator.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expectedd
+ }
+
+ assertTrue(hIterator.hasNext());
+ assertSame(HugeEnum.a, hIterator.next());
+ hIterator.remove();
+ assertTrue(hIterator.hasNext());
+ assertSame(HugeEnum.b, hIterator.next());
+ assertFalse(hIterator.hasNext());
+ assertFalse(hIterator.hasNext());
+
+ assertEquals(1, hugeSet.size());
+
+ try {
+ hIterator.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ Set<HugeEnumWithInnerClass> hugeSetWithSubclass = EnumSet
+ .allOf(HugeEnumWithInnerClass.class);
+ hugeSetWithSubclass.remove(HugeEnumWithInnerClass.e);
+ Iterator<HugeEnumWithInnerClass> hugeIteratorWithSubclass = hugeSetWithSubclass
+ .iterator();
+ assertSame(HugeEnumWithInnerClass.a, hugeIteratorWithSubclass.next());
+
+ assertTrue(hugeIteratorWithSubclass.hasNext());
+ assertSame(HugeEnumWithInnerClass.b, hugeIteratorWithSubclass.next());
+
+ setWithSubclass.remove(HugeEnumWithInnerClass.c);
+ assertTrue(hugeIteratorWithSubclass.hasNext());
+ assertSame(HugeEnumWithInnerClass.c, hugeIteratorWithSubclass.next());
+
+ assertTrue(hugeIteratorWithSubclass.hasNext());
+ assertSame(HugeEnumWithInnerClass.d, hugeIteratorWithSubclass.next());
+
+ hugeSetWithSubclass.add(HugeEnumWithInnerClass.e);
+ assertTrue(hugeIteratorWithSubclass.hasNext());
+ assertSame(HugeEnumWithInnerClass.f, hugeIteratorWithSubclass.next());
+
+ hugeSet = EnumSet.noneOf(HugeEnum.class);
+ hIterator = hugeSet.iterator();
+ try {
+ hIterator.next();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ hugeSet.add(HugeEnum.a);
+ hIterator = hugeSet.iterator();
+ assertEquals(HugeEnum.a, hIterator.next());
+ assertEquals(1, hugeSet.size());
+ hIterator.remove();
+ assertEquals(0, hugeSet.size());
+ assertFalse(hugeSet.contains(HugeEnum.a));
+
+ hugeSet.add(HugeEnum.a);
+ hugeSet.add(HugeEnum.b);
+ hIterator = hugeSet.iterator();
+ hIterator.next();
+ hIterator.remove();
+
+ assertTrue(hIterator.hasNext());
+ try {
+ hIterator.remove();
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ assertEquals(1, hugeSet.size());
+ assertTrue(hIterator.hasNext());
+ assertEquals(HugeEnum.b, hIterator.next());
+ hugeSet.remove(HugeEnum.b);
+ assertEquals(0, hugeSet.size());
+ hIterator.remove();
+ assertFalse(hugeSet.contains(HugeEnum.a));
+ // RI's bug, EnumFoo.b should not exist at the moment.
+ if(!disableRIBugs) {
+ assertFalse("Should return false", set.contains(EnumFoo.b));
+ }
+ }
+
+ /**
+ * java.util.EnumSet#of(E)
+ */
+ public void test_Of_E() {
+ EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a);
+ assertEquals("enumSet should have length 1:", 1, enumSet.size());
+
+ assertTrue("enumSet should contain EnumWithSubclass.a:",
+ enumSet.contains(EnumWithInnerClass.a));
+
+ try {
+ EnumSet.of((EnumWithInnerClass) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ // test enum type with more than 64 elements
+ EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a);
+ assertEquals(1, hugeEnumSet.size());
+
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
+ }
+
+ /**
+ * java.util.EnumSet#of(E, E)
+ */
+ public void test_Of_EE() {
+ EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
+ EnumWithInnerClass.b);
+ assertEquals("enumSet should have length 2:", 2, enumSet.size());
+
+ assertTrue("enumSet should contain EnumWithSubclass.a:",
+ enumSet.contains(EnumWithInnerClass.a));
+ assertTrue("enumSet should contain EnumWithSubclass.b:",
+ enumSet.contains(EnumWithInnerClass.b));
+
+ try {
+ EnumSet.of((EnumWithInnerClass) null, EnumWithInnerClass.a);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ try {
+ EnumSet.of( EnumWithInnerClass.a, (EnumWithInnerClass) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ try {
+ EnumSet.of( (EnumWithInnerClass) null, (EnumWithInnerClass) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ enumSet = EnumSet.of(EnumWithInnerClass.a, EnumWithInnerClass.a);
+ assertEquals("Size of enumSet should be 1",
+ 1, enumSet.size());
+
+ // test enum type with more than 64 elements
+ EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
+ HugeEnumWithInnerClass.b);
+ assertEquals(2, hugeEnumSet.size());
+
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.b));
+
+ try {
+ EnumSet.of((HugeEnumWithInnerClass) null, HugeEnumWithInnerClass.a);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ try {
+ EnumSet.of( HugeEnumWithInnerClass.a, (HugeEnumWithInnerClass) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ try {
+ EnumSet.of( (HugeEnumWithInnerClass) null, (HugeEnumWithInnerClass) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.a);
+ assertEquals(1, hugeEnumSet.size());
+ }
+
+ /**
+ * java.util.EnumSet#of(E, E, E)
+ */
+ public void test_Of_EEE() {
+ EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
+ EnumWithInnerClass.b, EnumWithInnerClass.c);
+ assertEquals("Size of enumSet should be 3:", 3, enumSet.size());
+
+ assertTrue(
+ "enumSet should contain EnumWithSubclass.a:", enumSet.contains(EnumWithInnerClass.a));
+ assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.c));
+
+ try {
+ EnumSet.of((EnumWithInnerClass) null, null, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ enumSet = EnumSet.of(EnumWithInnerClass.a, EnumWithInnerClass.b,
+ EnumWithInnerClass.b);
+ assertEquals("enumSet should contain 2 elements:", 2, enumSet.size());
+
+ // test enum type with more than 64 elements
+ EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
+ HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.c);
+ assertEquals(3, hugeEnumSet.size());
+
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.c));
+
+ try {
+ EnumSet.of((HugeEnumWithInnerClass) null, null, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.b,
+ HugeEnumWithInnerClass.b);
+ assertEquals(2, hugeEnumSet.size());
+ }
+
+ /**
+ * java.util.EnumSet#of(E, E, E, E)
+ */
+ public void test_Of_EEEE() {
+ EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
+ EnumWithInnerClass.b, EnumWithInnerClass.c,
+ EnumWithInnerClass.d);
+ assertEquals("Size of enumSet should be 4", 4, enumSet.size());
+
+ assertTrue(
+ "enumSet should contain EnumWithSubclass.a:", enumSet.contains(EnumWithInnerClass.a));
+ assertTrue("enumSet should contain EnumWithSubclass.d:", enumSet
+ .contains(EnumWithInnerClass.d));
+
+ try {
+ EnumSet.of((EnumWithInnerClass) null, null, null, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ // test enum type with more than 64 elements
+ EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
+ HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.c,
+ HugeEnumWithInnerClass.d);
+ assertEquals(4, hugeEnumSet.size());
+
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.d));
+
+ try {
+ EnumSet.of((HugeEnumWithInnerClass) null, null, null, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.EnumSet#of(E, E, E, E, E)
+ */
+ public void test_Of_EEEEE() {
+ EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
+ EnumWithInnerClass.b, EnumWithInnerClass.c,
+ EnumWithInnerClass.d, EnumWithInnerClass.e);
+ assertEquals("Size of enumSet should be 5:", 5, enumSet.size());
+
+ assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.a));
+ assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.e));
+
+ try {
+ EnumSet.of((EnumWithInnerClass) null, null, null, null, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ // test enum with more than 64 elements
+ EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
+ HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.c,
+ HugeEnumWithInnerClass.d, HugeEnumWithInnerClass.e);
+ assertEquals(5, hugeEnumSet.size());
+
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.e));
+
+ try {
+ EnumSet.of((HugeEnumWithInnerClass) null, null, null, null, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.EnumSet#of(E, E...)
+ */
+ public void test_Of_EEArray() {
+ EnumWithInnerClass[] enumArray = new EnumWithInnerClass[] {
+ EnumWithInnerClass.b, EnumWithInnerClass.c };
+ EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
+ enumArray);
+ assertEquals("Should be equal", 3, enumSet.size());
+
+ assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.a));
+ assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.c));
+
+ try {
+ EnumSet.of(EnumWithInnerClass.a, (EnumWithInnerClass[])null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ EnumFoo[] foos = {EnumFoo.a, EnumFoo.c, EnumFoo.d};
+ EnumSet<EnumFoo> set = EnumSet.of(EnumFoo.c, foos);
+ assertEquals("size of set should be 1", 3, set.size());
+ assertTrue("Should contain EnumFoo.a", set.contains(EnumFoo.a));
+ assertTrue("Should contain EnumFoo.c", set.contains(EnumFoo.c));
+ assertTrue("Should contain EnumFoo.d", set.contains(EnumFoo.d));
+
+ // test enum type with more than 64 elements
+ HugeEnumWithInnerClass[] hugeEnumArray = new HugeEnumWithInnerClass[] {
+ HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.c };
+ EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
+ hugeEnumArray);
+ assertEquals(3, hugeEnumSet.size());
+
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
+ assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.c));
+
+ try {
+ EnumSet.of(HugeEnumWithInnerClass.a, (HugeEnumWithInnerClass[])null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ HugeEnumWithInnerClass[] huges = {HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.c, HugeEnumWithInnerClass.d};
+ EnumSet<HugeEnumWithInnerClass> hugeSet = EnumSet.of(HugeEnumWithInnerClass.c, huges);
+ assertEquals(3, hugeSet.size());
+ assertTrue(hugeSet.contains(HugeEnumWithInnerClass.a));
+ assertTrue(hugeSet.contains(HugeEnumWithInnerClass.c));
+ assertTrue(hugeSet.contains(HugeEnumWithInnerClass.d));
+ }
+
+ /**
+ * java.util.EnumSet#range(E, E)
+ */
+ public void test_Range_EE() {
+ try {
+ EnumSet.range(EnumWithInnerClass.c, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ EnumSet.range(null, EnumWithInnerClass.c);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ EnumSet.range(null, (EnumWithInnerClass) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ EnumSet.range(EnumWithInnerClass.b, EnumWithInnerClass.a);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ EnumSet<EnumWithInnerClass> enumSet = EnumSet.range(
+ EnumWithInnerClass.a, EnumWithInnerClass.a);
+ assertEquals("Size of enumSet should be 1", 1, enumSet.size());
+
+ enumSet = EnumSet.range(
+ EnumWithInnerClass.a, EnumWithInnerClass.c);
+ assertEquals("Size of enumSet should be 3", 3, enumSet.size());
+
+ // test enum with more than 64 elements
+ try {
+ EnumSet.range(HugeEnumWithInnerClass.c, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ EnumSet.range(null, HugeEnumWithInnerClass.c);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ EnumSet.range(null, (HugeEnumWithInnerClass) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ EnumSet.range(HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.a);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.range(
+ HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.a);
+ assertEquals(1, hugeEnumSet.size());
+
+ hugeEnumSet = EnumSet.range(
+ HugeEnumWithInnerClass.c, HugeEnumWithInnerClass.aa);
+ assertEquals(51, hugeEnumSet.size());
+
+ hugeEnumSet = EnumSet.range(
+ HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.mm);
+ assertEquals(65, hugeEnumSet.size());
+
+ hugeEnumSet = EnumSet.range(
+ HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.mm);
+ assertEquals(64, hugeEnumSet.size());
+ }
+
+ /**
+ * java.util.EnumSet#clone()
+ */
+ public void test_Clone() {
+ EnumSet<EnumFoo> enumSet = EnumSet.allOf(EnumFoo.class);
+ EnumSet<EnumFoo> clonedEnumSet = enumSet.clone();
+ assertEquals(enumSet, clonedEnumSet);
+ assertNotSame(enumSet, clonedEnumSet);
+ assertTrue(clonedEnumSet.contains(EnumFoo.a));
+ assertTrue(clonedEnumSet.contains(EnumFoo.b));
+ assertEquals(64, clonedEnumSet.size());
+
+ // test enum type with more than 64 elements
+ EnumSet<HugeEnum> hugeEnumSet = EnumSet.allOf(HugeEnum.class);
+ EnumSet<HugeEnum> hugeClonedEnumSet = hugeEnumSet.clone();
+ assertEquals(hugeEnumSet, hugeClonedEnumSet);
+ assertNotSame(hugeEnumSet, hugeClonedEnumSet);
+ assertTrue(hugeClonedEnumSet.contains(HugeEnum.a));
+ assertTrue(hugeClonedEnumSet.contains(HugeEnum.b));
+ assertEquals(65, hugeClonedEnumSet.size());
+
+ hugeClonedEnumSet.remove(HugeEnum.a);
+ assertEquals(64, hugeClonedEnumSet.size());
+ assertFalse(hugeClonedEnumSet.contains(HugeEnum.a));
+ assertEquals(65, hugeEnumSet.size());
+ assertTrue(hugeEnumSet.contains(HugeEnum.a));
+ }
+
+ /**
+ * java.util.EnumSet#Serialization()
+ */
+ public void test_serialization() throws Exception {
+ EnumSet<EnumFoo> set = EnumSet.allOf(EnumFoo.class);
+ SerializationTest.verifySelf(set);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ @SuppressWarnings( { "unchecked", "boxing" })
+ public void testSerializationCompatibility() throws Exception {
+ EnumSet<EnumFoo> set = EnumSet.allOf(EnumFoo.class);
+ SerializationTest.verifyGolden(this, set);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EventObjectTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EventObjectTest.java
new file mode 100644
index 0000000..bea2a44
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EventObjectTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.EventObject;
+
+public class EventObjectTest extends junit.framework.TestCase {
+
+ Object myObject;
+
+ EventObject myEventObject;
+
+ /**
+ * java.util.EventObject#EventObject(java.lang.Object)
+ */
+ public void test_ConstructorLjava_lang_Object() {
+ // Test for method java.util.EventObject(java.lang.Object)
+ assertTrue("Used to test", true);
+ }
+
+ /**
+ * java.util.EventObject#getSource()
+ */
+ public void test_getSource() {
+ // Test for method java.lang.Object java.util.EventObject.getSource()
+ assertTrue("Wrong source returned",
+ myEventObject.getSource() == myObject);
+ }
+
+ /**
+ * java.util.EventObject#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.util.EventObject.toString()
+ assertTrue("Incorrect toString returned: " + myEventObject.toString(),
+ myEventObject.toString().indexOf(
+ "java.util.EventObject[source=java.lang.Object@") == 0);
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ myObject = new Object();
+ myEventObject = new EventObject(myObject);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatFlagsConversionMismatchExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatFlagsConversionMismatchExceptionTest.java
new file mode 100644
index 0000000..bc9c480
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatFlagsConversionMismatchExceptionTest.java
@@ -0,0 +1,115 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.FormatFlagsConversionMismatchException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class FormatFlagsConversionMismatchExceptionTest extends TestCase {
+
+ /**
+ * java.util.FormatFlagsConversionMismatchException#FormatFlagsConversionMismatchException(String,
+ *char)
+ */
+ public void test_formatFlagsConversionMismatchException() {
+ try {
+ new FormatFlagsConversionMismatchException(null, ' ');
+ fail("should throw NullPointerException.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * java.util.FormatFlagsConversionMismatchException#getFlags()
+ */
+ public void test_getFlags() {
+ String flags = "MYTESTFLAGS";
+ char conversion = 'T';
+ FormatFlagsConversionMismatchException formatFlagsConversionMismatchException = new FormatFlagsConversionMismatchException(
+ flags, conversion);
+ assertEquals(flags, formatFlagsConversionMismatchException.getFlags());
+ }
+
+ /**
+ * java.util.FormatFlagsConversionMismatchException#getConversion()
+ */
+ public void test_getConversion() {
+ String flags = "MYTESTFLAGS";
+ char conversion = 'T';
+ FormatFlagsConversionMismatchException formatFlagsConversionMismatchException = new FormatFlagsConversionMismatchException(
+ flags, conversion);
+ assertEquals(conversion, formatFlagsConversionMismatchException
+ .getConversion());
+
+ }
+
+ /**
+ * java.util.FormatFlagsConversionMismatchException#getMessage()
+ */
+ public void test_getMessage() {
+ String flags = "MYTESTFLAGS";
+ char conversion = 'T';
+ FormatFlagsConversionMismatchException formatFlagsConversionMismatchException = new FormatFlagsConversionMismatchException(
+ flags, conversion);
+ assertTrue(null != formatFlagsConversionMismatchException.getMessage());
+
+ }
+
+ // comparator for FormatFlagsConversionMismatchException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ FormatFlagsConversionMismatchException initEx = (FormatFlagsConversionMismatchException) initial;
+ FormatFlagsConversionMismatchException desrEx = (FormatFlagsConversionMismatchException) deserialized;
+
+ assertEquals("Flags", initEx.getFlags(), desrEx.getFlags());
+ assertEquals("Conversion", initEx.getConversion(), desrEx
+ .getConversion());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(
+ new FormatFlagsConversionMismatchException("MYTESTFLAGS", 'T'),
+ exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new FormatFlagsConversionMismatchException("MYTESTFLAGS", 'T'),
+ exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormattableFlagsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormattableFlagsTest.java
new file mode 100644
index 0000000..dc51e86
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormattableFlagsTest.java
@@ -0,0 +1,27 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.util.FormattableFlags;
+import junit.framework.TestCase;
+
+public class FormattableFlagsTest extends TestCase {
+ public void test_ConstantFieldValues() {
+ assertEquals(1, FormattableFlags.LEFT_JUSTIFY);
+ assertEquals(2, FormattableFlags.UPPERCASE);
+ assertEquals(4, FormattableFlags.ALTERNATE);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterClosedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterClosedExceptionTest.java
new file mode 100644
index 0000000..e89576a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterClosedExceptionTest.java
@@ -0,0 +1,42 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.FormatterClosedException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class FormatterClosedExceptionTest extends TestCase {
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new FormatterClosedException());
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new FormatterClosedException());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java
new file mode 100644
index 0000000..c0e814e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java
@@ -0,0 +1,4244 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.BufferedOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilePermission;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.nio.charset.Charset;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.DuplicateFormatFlagsException;
+import java.util.FormatFlagsConversionMismatchException;
+import java.util.Formattable;
+import java.util.FormattableFlags;
+import java.util.Formatter;
+import java.util.FormatterClosedException;
+import java.util.IllegalFormatCodePointException;
+import java.util.IllegalFormatConversionException;
+import java.util.IllegalFormatException;
+import java.util.IllegalFormatFlagsException;
+import java.util.IllegalFormatPrecisionException;
+import java.util.IllegalFormatWidthException;
+import java.util.Locale;
+import java.util.MissingFormatArgumentException;
+import java.util.MissingFormatWidthException;
+import java.util.TimeZone;
+import java.util.UnknownFormatConversionException;
+import java.util.Formatter.BigDecimalLayoutForm;
+
+import junit.framework.TestCase;
+
+public class FormatterTest extends TestCase {
+ private boolean root;
+
+ class MockAppendable implements Appendable {
+ public Appendable append(CharSequence arg0) throws IOException {
+ return null;
+ }
+
+ public Appendable append(char arg0) throws IOException {
+ return null;
+ }
+
+ public Appendable append(CharSequence arg0, int arg1, int arg2)
+ throws IOException {
+ return null;
+ }
+ }
+
+ class MockFormattable implements Formattable {
+ public void formatTo(Formatter formatter, int flags, int width,
+ int precision) throws IllegalFormatException {
+ if ((flags & FormattableFlags.UPPERCASE) != 0) {
+ formatter.format("CUSTOMIZED FORMAT FUNCTION" + " WIDTH: "
+ + width + " PRECISION: " + precision);
+ } else {
+ formatter.format("customized format function" + " width: "
+ + width + " precision: " + precision);
+ }
+ }
+
+ public String toString() {
+ return "formattable object";
+ }
+
+ public int hashCode() {
+ return 0xf;
+ }
+ }
+
+ class MockDestination implements Appendable, Flushable {
+
+ private StringBuilder data = new StringBuilder();
+
+ private boolean enabled = false;
+
+ public Appendable append(char c) throws IOException {
+ if (enabled) {
+ data.append(c);
+ enabled = true; // enable it after the first append
+ } else {
+ throw new IOException();
+ }
+ return this;
+ }
+
+ public Appendable append(CharSequence csq) throws IOException {
+ if (enabled) {
+ data.append(csq);
+ enabled = true; // enable it after the first append
+ } else {
+ throw new IOException();
+ }
+ return this;
+ }
+
+ public Appendable append(CharSequence csq, int start, int end)
+ throws IOException {
+ if (enabled) {
+ data.append(csq, start, end);
+ enabled = true; // enable it after the first append
+ } else {
+ throw new IOException();
+ }
+ return this;
+ }
+
+ public void flush() throws IOException {
+ throw new IOException("Always throw IOException");
+ }
+
+ public String toString() {
+ return data.toString();
+ }
+ }
+
+ private File notExist;
+
+ private File fileWithContent;
+
+ private File readOnly;
+
+ private File secret;
+
+ private TimeZone defaultTimeZone;
+
+ /**
+ * java.util.Formatter#Formatter()
+ */
+ public void test_Constructor() {
+ Formatter f = new Formatter();
+ assertNotNull(f);
+ assertTrue(f.out() instanceof StringBuilder);
+ assertEquals(f.locale(), Locale.getDefault());
+ assertNotNull(f.toString());
+ }
+
+ /**
+ * java.util.Formatter#Formatter(Appendable)
+ */
+ public void test_ConstructorLjava_lang_Appendable() {
+ MockAppendable ma = new MockAppendable();
+ Formatter f1 = new Formatter(ma);
+ assertEquals(ma, f1.out());
+ assertEquals(f1.locale(), Locale.getDefault());
+ assertNotNull(f1.toString());
+
+ Formatter f2 = new Formatter((Appendable) null);
+ /*
+ * If a(the input param) is null then a StringBuilder will be created
+ * and the output can be attained by invoking the out() method. But RI
+ * raises an error of FormatterClosedException when invoking out() or
+ * toString().
+ */
+ Appendable sb = f2.out();
+ assertTrue(sb instanceof StringBuilder);
+ assertNotNull(f2.toString());
+ }
+
+ /**
+ * java.util.Formatter#Formatter(Locale)
+ */
+ public void test_ConstructorLjava_util_Locale() {
+ Formatter f1 = new Formatter(Locale.FRANCE);
+ assertTrue(f1.out() instanceof StringBuilder);
+ assertEquals(f1.locale(), Locale.FRANCE);
+ assertNotNull(f1.toString());
+
+ Formatter f2 = new Formatter((Locale) null);
+ assertNull(f2.locale());
+ assertTrue(f2.out() instanceof StringBuilder);
+ assertNotNull(f2.toString());
+ }
+
+ /**
+ * java.util.Formatter#Formatter(Appendable, Locale)
+ */
+ public void test_ConstructorLjava_lang_AppendableLjava_util_Locale() {
+ MockAppendable ma = new MockAppendable();
+ Formatter f1 = new Formatter(ma, Locale.CANADA);
+ assertEquals(ma, f1.out());
+ assertEquals(f1.locale(), Locale.CANADA);
+
+ Formatter f2 = new Formatter(ma, null);
+ assertNull(f2.locale());
+ assertEquals(ma, f1.out());
+
+ Formatter f3 = new Formatter(null, Locale.GERMAN);
+ assertEquals(f3.locale(), Locale.GERMAN);
+ assertTrue(f3.out() instanceof StringBuilder);
+ }
+
+ /**
+ * java.util.Formatter#Formatter(String)
+ */
+ public void test_ConstructorLjava_lang_String() throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((String) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ f = new Formatter(notExist.getPath());
+ assertEquals(f.locale(), Locale.getDefault());
+ f.close();
+
+ f = new Formatter(fileWithContent.getPath());
+ assertEquals(0, fileWithContent.length());
+ f.close();
+
+ if (!root) {
+ try {
+ f = new Formatter(readOnly.getPath());
+ fail("should throw FileNotFoundException");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ }
+ }
+
+ /**
+ * java.util.Formatter#Formatter(String, String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_String()
+ throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((String) null, Charset.defaultCharset().name());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ try {
+ f = new Formatter(notExist.getPath(), null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e2) {
+ // expected
+ }
+
+ f = new Formatter(notExist.getPath(), Charset.defaultCharset().name());
+ assertEquals(f.locale(), Locale.getDefault());
+ f.close();
+
+ try {
+ f = new Formatter(notExist.getPath(), "ISO 1111-1");
+ fail("should throw UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e1) {
+ // expected
+ }
+
+ f = new Formatter(fileWithContent.getPath(), "UTF-16BE");
+ assertEquals(0, fileWithContent.length());
+ f.close();
+
+ if (!root) {
+ try {
+ f = new Formatter(readOnly.getPath(), "UTF-16BE");
+ fail("should throw FileNotFoundException");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ }
+ }
+
+ /**
+ * java.util.Formatter#Formatter(String, String, Locale)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_util_Locale()
+ throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((String) null, Charset.defaultCharset().name(),
+ Locale.KOREA);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ try {
+ f = new Formatter(notExist.getPath(), null, Locale.KOREA);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e2) {
+ // expected
+ }
+
+ f = new Formatter(notExist.getPath(), Charset.defaultCharset().name(),
+ null);
+ assertNotNull(f);
+ f.close();
+
+ f = new Formatter(notExist.getPath(), Charset.defaultCharset().name(),
+ Locale.KOREA);
+ assertEquals(f.locale(), Locale.KOREA);
+ f.close();
+
+ try {
+ f = new Formatter(notExist.getPath(), "ISO 1111-1", Locale.CHINA);
+ fail("should throw UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e1) {
+ // expected
+ }
+
+ f = new Formatter(fileWithContent.getPath(), "UTF-16BE",
+ Locale.CANADA_FRENCH);
+ assertEquals(0, fileWithContent.length());
+ f.close();
+
+ if (!root) {
+ try {
+ f = new Formatter(readOnly.getPath(), Charset.defaultCharset()
+ .name(), Locale.ITALY);
+ fail("should throw FileNotFoundException");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ }
+ }
+
+ /**
+ * java.util.Formatter#Formatter(File)
+ */
+ public void test_ConstructorLjava_io_File() throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((File) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ f = new Formatter(notExist);
+ assertEquals(f.locale(), Locale.getDefault());
+ f.close();
+
+ f = new Formatter(fileWithContent);
+ assertEquals(0, fileWithContent.length());
+ f.close();
+
+ if (!root) {
+ try {
+ f = new Formatter(readOnly);
+ fail("should throw FileNotFoundException");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ }
+ }
+
+ /**
+ * java.util.Formatter#Formatter(File, String)
+ */
+ public void test_ConstructorLjava_io_FileLjava_lang_String()
+ throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((File) null, Charset.defaultCharset().name());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ f = new Formatter(notExist, Charset.defaultCharset().name());
+ assertEquals(f.locale(), Locale.getDefault());
+ f.close();
+
+ f = new Formatter(fileWithContent, "UTF-16BE");
+ assertEquals(0, fileWithContent.length());
+ f.close();
+
+ if (!root) {
+ try {
+ f = new Formatter(readOnly, Charset.defaultCharset().name());
+ fail("should throw FileNotFoundException");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ }
+
+ try {
+ f = new Formatter(notExist, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e2) {
+ // expected
+ } finally {
+ if (notExist.exists()) {
+ // Fail on RI on Windows, because output stream is created and
+ // not closed when exception thrown
+ assertTrue(notExist.delete());
+ }
+ }
+
+ try {
+ f = new Formatter(notExist, "ISO 1111-1");
+ fail("should throw UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e1) {
+ // expected
+ } finally {
+ if (notExist.exists()) {
+ // Fail on RI on Windows, because output stream is created and
+ // not closed when exception thrown
+ assertTrue(notExist.delete());
+ }
+ }
+ }
+
+ /**
+ * java.util.Formatter#Formatter(File, String, Locale)
+ */
+ public void test_ConstructorLjava_io_FileLjava_lang_StringLjava_util_Locale()
+ throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((File) null, Charset.defaultCharset().name(),
+ Locale.KOREA);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ try {
+ f = new Formatter(notExist, null, Locale.KOREA);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e2) {
+ // expected
+ }
+
+ f = new Formatter(notExist, Charset.defaultCharset().name(), null);
+ assertNotNull(f);
+ f.close();
+
+ f = new Formatter(notExist, Charset.defaultCharset().name(),
+ Locale.KOREA);
+ assertEquals(f.locale(), Locale.KOREA);
+ f.close();
+
+ try {
+ f = new Formatter(notExist, "ISO 1111-1", Locale.CHINA);
+ fail("should throw UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e1) {
+ // expected
+ }
+ f = new Formatter(fileWithContent.getPath(), "UTF-16BE",
+ Locale.CANADA_FRENCH);
+ assertEquals(0, fileWithContent.length());
+ f.close();
+
+ if (!root) {
+ try {
+ f = new Formatter(readOnly.getPath(), Charset.defaultCharset()
+ .name(), Locale.ITALY);
+ fail("should throw FileNotFoundException");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ }
+ }
+
+ /**
+ * java.util.Formatter#Formatter(PrintStream)
+ */
+ public void test_ConstructorLjava_io_PrintStream() throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((PrintStream) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ PrintStream ps = new PrintStream(notExist, "UTF-16BE");
+ f = new Formatter(ps);
+ assertEquals(Locale.getDefault(), f.locale());
+ f.close();
+ }
+
+ /**
+ * java.util.Formatter#Formatter(OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((OutputStream) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ OutputStream os = new FileOutputStream(notExist);
+ f = new Formatter(os);
+ assertEquals(Locale.getDefault(), f.locale());
+ f.close();
+ }
+
+ /**
+ * java.util.Formatter#Formatter(OutputStream, String)
+ */
+ public void test_ConstructorLjava_io_OutputStreamLjava_lang_String()
+ throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((OutputStream) null, Charset.defaultCharset()
+ .name());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ OutputStream os = null;
+ try {
+ os = new FileOutputStream(notExist);
+ f = new Formatter(os, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e2) {
+ // expected
+ } finally {
+ os.close();
+ }
+
+ try {
+ os = new PipedOutputStream();
+ f = new Formatter(os, "TMP-1111");
+ fail("should throw UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e1) {
+ // expected
+ } finally {
+ os.close();
+ }
+
+ os = new FileOutputStream(fileWithContent);
+ f = new Formatter(os, "UTF-16BE");
+ assertEquals(Locale.getDefault(), f.locale());
+ f.close();
+ }
+
+ /**
+ * Test method for 'java.util.Formatter.Formatter(OutputStream, String,
+ * Locale)
+ */
+ public void test_ConstructorLjava_io_OutputStreamLjava_lang_StringLjava_util_Locale()
+ throws IOException {
+ Formatter f = null;
+ try {
+ f = new Formatter((OutputStream) null, Charset.defaultCharset()
+ .name(), Locale.getDefault());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ OutputStream os = null;
+ try {
+ os = new FileOutputStream(notExist);
+ f = new Formatter(os, null, Locale.getDefault());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e2) {
+ // expected
+ } finally {
+ os.close();
+ }
+
+ os = new FileOutputStream(notExist);
+ f = new Formatter(os, Charset.defaultCharset().name(), null);
+ f.close();
+
+ try {
+ os = new PipedOutputStream();
+ f = new Formatter(os, "TMP-1111", Locale.getDefault());
+ fail("should throw UnsupportedEncodingException");
+ } catch (UnsupportedEncodingException e1) {
+ // expected
+ }
+
+ os = new FileOutputStream(fileWithContent);
+ f = new Formatter(os, "UTF-16BE", Locale.ENGLISH);
+ assertEquals(Locale.ENGLISH, f.locale());
+ f.close();
+ }
+
+ /**
+ * java.util.Formatter#locale()
+ */
+ public void test_locale() {
+ Formatter f = null;
+ f = new Formatter((Locale) null);
+ assertNull(f.locale());
+
+ f.close();
+ try {
+ f.locale();
+ fail("should throw FormatterClosedException");
+ } catch (FormatterClosedException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Formatter#out()
+ */
+ public void test_out() {
+ Formatter f = null;
+ f = new Formatter();
+ assertNotNull(f.out());
+ assertTrue(f.out() instanceof StringBuilder);
+ f.close();
+ try {
+ f.out();
+ fail("should throw FormatterClosedException");
+ } catch (FormatterClosedException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * java.util.Formatter#flush()
+ */
+ public void test_flush() throws IOException {
+ Formatter f = null;
+ f = new Formatter(notExist);
+ assertTrue(f instanceof Flushable);
+ f.close();
+ try {
+ f.flush();
+ fail("should throw FormatterClosedException");
+ } catch (FormatterClosedException e) {
+ // expected
+ }
+
+ f = new Formatter();
+ // For destination that does not implement Flushable
+ // No exception should be thrown
+ f.flush();
+ }
+
+ /**
+ * java.util.Formatter#close()
+ */
+ public void test_close() throws IOException {
+ Formatter f = new Formatter(notExist);
+ assertTrue(f instanceof Closeable);
+ f.close();
+ // close next time will not throw exception
+ f.close();
+ assertNull(f.ioException());
+ }
+
+ /**
+ * java.util.Formatter#toString()
+ */
+ public void test_toString() {
+ Formatter f = new Formatter();
+ assertNotNull(f.toString());
+ assertEquals(f.out().toString(), f.toString());
+ f.close();
+ try {
+ f.toString();
+ fail("should throw FormatterClosedException");
+ } catch (FormatterClosedException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Formatter#ioException()
+ */
+ public void test_ioException() throws IOException {
+ Formatter f = null;
+ f = new Formatter(new MockDestination());
+ assertNull(f.ioException());
+ f.flush();
+ assertNotNull(f.ioException());
+ f.close();
+
+ MockDestination md = new MockDestination();
+ f = new Formatter(md);
+ f.format("%s%s", "1", "2");
+ // format stop working after IOException
+ assertNotNull(f.ioException());
+ assertEquals("", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for null parameter
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_null() {
+ Formatter f = new Formatter();
+ try {
+ f.format((String) null, "parameter");
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ f = new Formatter();
+ f.format("hello", (Object[]) null);
+ assertEquals("hello", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for argument index
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_ArgIndex() {
+ Formatter formatter = new Formatter(Locale.US);
+ formatter.format("%1$s%2$s%3$s%4$s%5$s%6$s%7$s%8$s%9$s%11$s%10$s", "1",
+ "2", "3", "4", "5", "6", "7", "8", "9", "10", "11");
+ assertEquals("1234567891110", formatter.toString());
+
+ formatter = new Formatter(Locale.JAPAN);
+ formatter.format("%0$s", "hello");
+ assertEquals("hello", formatter.toString());
+
+ try {
+ formatter = new Formatter(Locale.US);
+ formatter.format("%-1$s", "1", "2");
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+
+ try {
+ formatter = new Formatter(Locale.US);
+ formatter.format("%$s", "hello", "2");
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+
+ try {
+ Formatter f = new Formatter(Locale.US);
+ f.format("%", "string");
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+
+ formatter = new Formatter(Locale.FRANCE);
+ formatter.format("%1$s%2$s%3$s%4$s%5$s%6$s%7$s%8$s%<s%s%s%<s", "1",
+ "2", "3", "4", "5", "6", "7", "8", "9", "10", "11");
+ assertEquals("123456788122", formatter.toString());
+
+ formatter = new Formatter(Locale.FRANCE);
+ formatter.format(
+ "xx%1$s22%2$s%s%<s%5$s%<s&%7$h%2$s%8$s%<s%s%s%<ssuffix", "1",
+ "2", "3", "4", "5", "6", 7, "8", "9", "10", "11");
+ assertEquals("xx12221155&7288233suffix", formatter.toString());
+
+ try {
+ formatter.format("%<s", "hello");
+ fail("should throw MissingFormatArgumentException");
+ } catch (MissingFormatArgumentException e) {
+ // expected
+ }
+
+ formatter = new Formatter(Locale.US);
+ try {
+ formatter.format("%123$s", "hello");
+ fail("should throw MissingFormatArgumentException");
+ } catch (MissingFormatArgumentException e) {
+ // expected
+ }
+
+ formatter = new Formatter(Locale.US);
+ try {
+ // 2147483648 is the value of Integer.MAX_VALUE + 1
+ formatter.format("%2147483648$s", "hello");
+ fail("should throw MissingFormatArgumentException");
+ } catch (MissingFormatArgumentException e) {
+ // expected
+ }
+
+ try {
+ // 2147483647 is the value of Integer.MAX_VALUE
+ formatter.format("%2147483647$s", "hello");
+ fail("should throw MissingFormatArgumentException");
+ } catch (MissingFormatArgumentException e) {
+ // expected
+ }
+
+ formatter = new Formatter(Locale.US);
+ try {
+ formatter.format("%s%s", "hello");
+ fail("should throw MissingFormatArgumentException");
+ } catch (MissingFormatArgumentException e) {
+ // expected
+ }
+
+ formatter = new Formatter(Locale.US);
+ formatter.format("$100", 100);
+ assertEquals("$100", formatter.toString());
+
+ formatter = new Formatter(Locale.UK);
+ formatter.format("%01$s", "string");
+ assertEquals("string", formatter.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for width
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_Width() {
+ Formatter f = new Formatter(Locale.US);
+ f.format("%1$8s", "1");
+ assertEquals(" 1", f.toString());
+
+ f = new Formatter(Locale.US);
+ f.format("%1$-1%", "string");
+ assertEquals("%", f.toString());
+
+ f = new Formatter(Locale.ITALY);
+ // 2147483648 is the value of Integer.MAX_VALUE + 1
+ f.format("%2147483648s", "string");
+ assertEquals("string", f.toString());
+
+ // the value of Integer.MAX_VALUE will allocate about 4G bytes of
+ // memory.
+ // It may cause OutOfMemoryError, so this value is not tested
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for precision
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_Precision() {
+ Formatter f = new Formatter(Locale.US);
+ f.format("%.5s", "123456");
+ assertEquals("12345", f.toString());
+
+ f = new Formatter(Locale.US);
+ // 2147483648 is the value of Integer.MAX_VALUE + 1
+ f.format("%.2147483648s", "...");
+ assertEquals("...", f.toString());
+
+ // the value of Integer.MAX_VALUE will allocate about 4G bytes of
+ // memory.
+ // It may cause OutOfMemoryError, so this value is not tested
+
+ f = new Formatter(Locale.US);
+ f.format("%10.0b", Boolean.TRUE);
+ assertEquals(" ", f.toString());
+
+ f = new Formatter(Locale.US);
+ f.format("%10.01s", "hello");
+ assertEquals(" h", f.toString());
+
+ try {
+ f = new Formatter(Locale.US);
+ f.format("%.s", "hello", "2");
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+
+ try {
+ f = new Formatter(Locale.US);
+ f.format("%.-5s", "123456");
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+
+ try {
+ f = new Formatter(Locale.US);
+ f.format("%1.s", "hello", "2");
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ f.format("%5.1s", "hello");
+ assertEquals(" h", f.toString());
+
+ f = new Formatter(Locale.FRANCE);
+ f.format("%.0s", "hello", "2");
+ assertEquals("", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for line sperator
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_LineSeparator() {
+ Formatter f = null;
+
+ String oldSeparator = System.getProperty("line.separator");
+ try {
+ System.setProperty("line.separator", "!\n");
+
+ f = new Formatter(Locale.US);
+ f.format("%1$n", 1);
+ assertEquals("!\n", f.toString());
+
+ f = new Formatter(Locale.KOREAN);
+ f.format("head%1$n%2$n", 1, new Date());
+ assertEquals("head!\n!\n", f.toString());
+
+ f = new Formatter(Locale.US);
+ f.format("%n%s", "hello");
+ assertEquals("!\nhello", f.toString());
+ } finally {
+ System.setProperty("line.separator", oldSeparator);
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%-n");
+ fail("should throw IllegalFormatFlagsException: %-n");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+ try {
+ f.format("%+n");
+ fail("should throw IllegalFormatFlagsException: %+n");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+ try {
+ f.format("%#n");
+ fail("should throw IllegalFormatFlagsException: %#n");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+ try {
+ f.format("% n");
+ fail("should throw IllegalFormatFlagsException: % n");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+ try {
+ f.format("%0n");
+ fail("should throw IllegalFormatFlagsException: %0n");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+ try {
+ f.format("%,n");
+ fail("should throw IllegalFormatFlagsException: %,n");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+ try {
+ f.format("%(n");
+ fail("should throw IllegalFormatFlagsException: %(n");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%4n");
+ fail("should throw IllegalFormatWidthException");
+ } catch (IllegalFormatWidthException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%-4n");
+ fail("should throw IllegalFormatWidthException");
+ } catch (IllegalFormatWidthException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%.9n");
+ fail("should throw IllegalFormatPrecisionException");
+ } catch (IllegalFormatPrecisionException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%5.9n");
+ fail("should throw IllegalFormatPrecisionException");
+ } catch (IllegalFormatPrecisionException e) {
+ // expected
+ }
+
+ System.setProperty("line.separator", oldSeparator);
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for percent
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_Percent() {
+ Formatter f = null;
+
+ f = new Formatter(Locale.ENGLISH);
+ f.format("%1$%", 100);
+ assertEquals("%", f.toString());
+
+ f = new Formatter(Locale.CHINA);
+ f.format("%1$%%%", "hello", new Object());
+ assertEquals("%%", f.toString());
+
+ f = new Formatter(Locale.CHINA);
+ f.format("%%%s", "hello");
+ assertEquals("%hello", f.toString());
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%.9%");
+ fail("should throw IllegalFormatPrecisionException");
+ } catch (IllegalFormatPrecisionException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%5.9%");
+ fail("should throw IllegalFormatPrecisionException");
+ } catch (IllegalFormatPrecisionException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ assertFormatFlagsConversionMismatchException(f, "%+%");
+ assertFormatFlagsConversionMismatchException(f, "%#%");
+ assertFormatFlagsConversionMismatchException(f, "% %");
+ assertFormatFlagsConversionMismatchException(f, "%0%");
+ assertFormatFlagsConversionMismatchException(f, "%,%");
+ assertFormatFlagsConversionMismatchException(f, "%(%");
+
+
+ f = new Formatter(Locale.KOREAN);
+ f.format("%4%", 1);
+ /*
+ * fail on RI the output string should be right justified by appending
+ * spaces till the whole string is 4 chars width.
+ */
+ assertEquals(" %", f.toString());
+
+ f = new Formatter(Locale.US);
+ f.format("%-4%", 100);
+ /*
+ * fail on RI, throw UnknownFormatConversionException the output string
+ * should be left justified by appending spaces till the whole string is
+ * 4 chars width.
+ */
+ assertEquals("% ", f.toString());
+ }
+
+ private void assertFormatFlagsConversionMismatchException(Formatter f, String str) {
+ try {
+ f.format(str);
+ fail("should throw FormatFlagsConversionMismatchException: "
+ + str);
+ /*
+ * error on RI, throw IllegalFormatFlagsException specification
+ * says FormatFlagsConversionMismatchException should be thrown
+ */
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for flag
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_Flag() {
+ Formatter f = new Formatter(Locale.US);
+ try {
+ f.format("%1$-#-8s", "something");
+ fail("should throw DuplicateFormatFlagsException");
+ } catch (DuplicateFormatFlagsException e) {
+ // expected
+ }
+
+ final char[] chars = { '-', '#', '+', ' ', '0', ',', '(', '%', '<' };
+ Arrays.sort(chars);
+ f = new Formatter(Locale.US);
+ for (char i = 0; i <= 256; i++) {
+ // test 8 bit character
+ if (Arrays.binarySearch(chars, i) >= 0 || Character.isDigit(i)
+ || Character.isLetter(i)) {
+ // Do not test 0-9, a-z, A-Z and characters in the chars array.
+ // They are characters used as flags, width or conversions
+ continue;
+ }
+ try {
+ f.format("%" + i + "s", 1);
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for general
+ * conversion b/B
+ */
+ public void test_format_LString$LObject_GeneralConversionB() {
+ final Object[][] triple = {
+ { Boolean.FALSE, "%3.2b", " fa", },
+ { Boolean.FALSE, "%-4.6b", "false", },
+ { Boolean.FALSE, "%.2b", "fa", },
+ { Boolean.TRUE, "%3.2b", " tr", },
+ { Boolean.TRUE, "%-4.6b", "true", },
+ { Boolean.TRUE, "%.2b", "tr", },
+ { new Character('c'), "%3.2b", " tr", },
+ { new Character('c'), "%-4.6b", "true", },
+ { new Character('c'), "%.2b", "tr", },
+ { new Byte((byte) 0x01), "%3.2b", " tr", },
+ { new Byte((byte) 0x01), "%-4.6b", "true", },
+ { new Byte((byte) 0x01), "%.2b", "tr", },
+ { new Short((short) 0x0001), "%3.2b", " tr", },
+ { new Short((short) 0x0001), "%-4.6b", "true", },
+ { new Short((short) 0x0001), "%.2b", "tr", },
+ { new Integer(1), "%3.2b", " tr", },
+ { new Integer(1), "%-4.6b", "true", },
+ { new Integer(1), "%.2b", "tr", },
+ { new Float(1.1f), "%3.2b", " tr", },
+ { new Float(1.1f), "%-4.6b", "true", },
+ { new Float(1.1f), "%.2b", "tr", },
+ { new Double(1.1d), "%3.2b", " tr", },
+ { new Double(1.1d), "%-4.6b", "true", },
+ { new Double(1.1d), "%.2b", "tr", },
+ { "", "%3.2b", " tr", },
+ { "", "%-4.6b", "true", },
+ { "", "%.2b", "tr", },
+ { "string content", "%3.2b", " tr", },
+ { "string content", "%-4.6b", "true", },
+ { "string content", "%.2b", "tr", },
+ { new MockFormattable(), "%3.2b", " tr", },
+ { new MockFormattable(), "%-4.6b", "true", },
+ { new MockFormattable(), "%.2b", "tr", },
+ { (Object) null, "%3.2b", " fa", },
+ { (Object) null, "%-4.6b", "false", },
+ { (Object) null, "%.2b", "fa", },
+ };
+
+
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ Formatter f = null;
+ for (int i = 0; i < triple.length; i++) {
+ f = new Formatter(Locale.FRANCE);
+ f.format((String) triple[i][pattern], triple[i][input]);
+ assertEquals("triple[" + i + "]:" + triple[i][input]
+ + ",pattern[" + i + "]:" + triple[i][pattern], triple[i][output], f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format(((String) triple[i][pattern]).toUpperCase(Locale.US), triple[i][input]);
+ assertEquals("triple[" + i + "]:" + triple[i][input]
+ + ",pattern[" + i + "]:" + triple[i][pattern], ((String) triple[i][output])
+ .toUpperCase(Locale.US), f.toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for general
+ * conversion type 's' and 'S'
+ */
+ public void test_format_LString$LObject_GeneralConversionS() {
+
+ final Object[][] triple = {
+ { Boolean.FALSE, "%2.3s", "fal", },
+ { Boolean.FALSE, "%-6.4s", "fals ", },
+ { Boolean.FALSE, "%.5s", "false", },
+ { Boolean.TRUE, "%2.3s", "tru", },
+ { Boolean.TRUE, "%-6.4s", "true ", },
+ { Boolean.TRUE, "%.5s", "true", },
+ { new Character('c'), "%2.3s", " c", },
+ { new Character('c'), "%-6.4s", "c ", },
+ { new Character('c'), "%.5s", "c", },
+ { new Byte((byte) 0x01), "%2.3s", " 1", },
+ { new Byte((byte) 0x01), "%-6.4s", "1 ", },
+ { new Byte((byte) 0x01), "%.5s", "1", },
+ { new Short((short) 0x0001), "%2.3s", " 1", },
+ { new Short((short) 0x0001), "%-6.4s", "1 ", },
+ { new Short((short) 0x0001), "%.5s", "1", },
+ { new Integer(1), "%2.3s", " 1", },
+ { new Integer(1), "%-6.4s", "1 ", },
+ { new Integer(1), "%.5s", "1", },
+ { new Float(1.1f), "%2.3s", "1.1", },
+ { new Float(1.1f), "%-6.4s", "1.1 ", },
+ { new Float(1.1f), "%.5s", "1.1", },
+ { new Double(1.1d), "%2.3s", "1.1", },
+ { new Double(1.1d), "%-6.4s", "1.1 ", },
+ { new Double(1.1d), "%.5s", "1.1", },
+ { "", "%2.3s", " ", },
+ { "", "%-6.4s", " ", },
+ { "", "%.5s", "", },
+ { "string content", "%2.3s", "str", },
+ { "string content", "%-6.4s", "stri ", },
+ { "string content", "%.5s", "strin", },
+ { new MockFormattable(), "%2.3s", "customized format function width: 2 precision: 3", },
+ { new MockFormattable(), "%-6.4s", "customized format function width: 6 precision: 4", },
+ { new MockFormattable(), "%.5s", "customized format function width: -1 precision: 5", },
+ { (Object) null, "%2.3s", "nul", },
+ { (Object) null, "%-6.4s", "null ", },
+ { (Object) null, "%.5s", "null", },
+ };
+
+
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ Formatter f = null;
+ for (int i = 0; i < triple.length; i++) {
+ f = new Formatter(Locale.FRANCE);
+ f.format((String) triple[i][pattern], triple[i][input]);
+ assertEquals("triple[" + i + "]:" + triple[i][input]
+ + ",pattern[" + i + "]:" + triple[i][pattern], triple[i][output], f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format(((String) triple[i][pattern]).toUpperCase(Locale.US), triple[i][input]);
+ assertEquals("triple[" + i + "]:" + triple[i][input]
+ + ",pattern[" + i + "]:" + triple[i][pattern], ((String) triple[i][output])
+ .toUpperCase(Locale.US), f.toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for general
+ * conversion type 'h' and 'H'
+ */
+ public void test_format_LString$LObject_GeneralConversionH() {
+
+ final Object[] input = {
+ Boolean.FALSE,
+ Boolean.TRUE,
+ new Character('c'),
+ new Byte((byte) 0x01),
+ new Short((short) 0x0001),
+ new Integer(1),
+ new Float(1.1f),
+ new Double(1.1d),
+ "",
+ "string content",
+ new MockFormattable(),
+ (Object) null,
+ };
+
+ Formatter f = null;
+ for (int i = 0; i < input.length - 1; i++) {
+ f = new Formatter(Locale.FRANCE);
+ f.format("%h", input[i]);
+ assertEquals("triple[" + i + "]:" + input[i],
+ Integer.toHexString(input[i].hashCode()), f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%H", input[i]);
+ assertEquals("triple[" + i + "]:" + input[i],
+ Integer.toHexString(input[i].hashCode()).toUpperCase(Locale.US), f.toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for general
+ * conversion other cases
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionOther() {
+ /*
+ * In Turkish locale, the upper case of '\u0069' is '\u0130'. The
+ * following test indicate that '\u0069' is coverted to upper case
+ * without using the turkish locale.
+ */
+ Formatter f = new Formatter(new Locale("tr"));
+ f.format("%S", "\u0069");
+ assertEquals("\u0049", f.toString());
+
+ final Object[] input = {
+ Boolean.FALSE,
+ Boolean.TRUE,
+ new Character('c'),
+ new Byte((byte) 0x01),
+ new Short((short) 0x0001),
+ new Integer(1),
+ new Float(1.1f),
+ new Double(1.1d),
+ "",
+ "string content",
+ new MockFormattable(),
+ (Object) null,
+ };
+ f = new Formatter(Locale.GERMAN);
+ for (int i = 0; i < input.length; i++) {
+ if (!(input[i] instanceof Formattable)) {
+ try {
+ f.format("%#s", input[i]);
+ /*
+ * fail on RI, spec says if the '#' flag is present and the
+ * argument is not a Formattable , then a
+ * FormatFlagsConversionMismatchException will be thrown.
+ */
+ fail("should throw FormatFlagsConversionMismatchException");
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+ } else {
+ f.format("%#s%<-#8s", input[i]);
+ assertEquals(
+ "customized format function width: -1 precision: -1customized format function width: 8 precision: -1",
+ f.toString());
+ }
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for general
+ * conversion exception
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionException() {
+ final String[] flagMismatch = { "%#b", "%+b", "% b", "%0b", "%,b",
+ "%(b", "%#B", "%+B", "% B", "%0B", "%,B", "%(B", "%#h", "%+h",
+ "% h", "%0h", "%,h", "%(h", "%#H", "%+H", "% H", "%0H", "%,H",
+ "%(H", "%+s", "% s", "%0s", "%,s", "%(s", "%+S", "% S", "%0S",
+ "%,S", "%(S" };
+
+ Formatter f = new Formatter(Locale.US);
+
+ for (int i = 0; i < flagMismatch.length; i++) {
+ try {
+ f.format(flagMismatch[i], "something");
+ fail("should throw FormatFlagsConversionMismatchException");
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+ }
+
+ final String[] missingWidth = { "%-b", "%-B", "%-h", "%-H", "%-s",
+ "%-S", };
+ for (int i = 0; i < missingWidth.length; i++) {
+ try {
+ f.format(missingWidth[i], "something");
+ fail("should throw MissingFormatWidthException");
+ } catch (MissingFormatWidthException e) {
+ // expected
+ }
+ }
+
+ // Regression test
+ f = new Formatter();
+ try {
+ f.format("%c", (byte) -0x0001);
+ fail("Should throw IllegalFormatCodePointException");
+ } catch (IllegalFormatCodePointException e) {
+ // expected
+ }
+
+ f = new Formatter();
+ try {
+ f.format("%c", (short) -0x0001);
+ fail("Should throw IllegalFormatCodePointException");
+ } catch (IllegalFormatCodePointException e) {
+ // expected
+ }
+
+ f = new Formatter();
+ try {
+ f.format("%c", -0x0001);
+ fail("Should throw IllegalFormatCodePointException");
+ } catch (IllegalFormatCodePointException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for Character
+ * conversion
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_CharacterConversion() {
+ Formatter f = new Formatter(Locale.US);
+ final Object[] illArgs = { Boolean.TRUE, new Float(1.1f),
+ new Double(1.1d), "string content", new Float(1.1f), new Date() };
+ for (int i = 0; i < illArgs.length; i++) {
+ try {
+ f.format("%c", illArgs[i]);
+ fail("should throw IllegalFormatConversionException");
+ } catch (IllegalFormatConversionException e) {
+ // expected
+ }
+ }
+
+ try {
+ f.format("%c", Integer.MAX_VALUE);
+ fail("should throw IllegalFormatCodePointException");
+ } catch (IllegalFormatCodePointException e) {
+ // expected
+ }
+
+ try {
+ f.format("%#c", 'c');
+ fail("should throw FormatFlagsConversionMismatchException");
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+
+ final Object[][] triple = {
+ { 'c', "%c", "c" },
+ { 'c', "%-2c", "c " },
+ { '\u0123', "%c", "\u0123" },
+ { '\u0123', "%-2c", "\u0123 " },
+ { (byte) 0x11, "%c", "\u0011" },
+ { (byte) 0x11, "%-2c", "\u0011 " },
+ { (short) 0x1111, "%c", "\u1111" },
+ { (short) 0x1111, "%-2c", "\u1111 " },
+ { 0x11, "%c", "\u0011" },
+ { 0x11, "%-2c", "\u0011 " },
+ };
+
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ for (int i = 0; i < triple.length; i++) {
+ f = new Formatter(Locale.US);
+ f.format((String) triple[i][pattern], triple[i][input]);
+ assertEquals(triple[i][output], f.toString());
+ }
+
+ f = new Formatter(Locale.US);
+ f.format("%c", 0x10000);
+ assertEquals(0x10000, f.toString().codePointAt(0));
+
+ try {
+ f.format("%2.2c", 'c');
+ fail("should throw IllegalFormatPrecisionException");
+ } catch (IllegalFormatPrecisionException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ f.format("%C", 'w');
+ // error on RI, throw UnknownFormatConversionException
+ // RI do not support converter 'C'
+ assertEquals("W", f.toString());
+
+ f = new Formatter(Locale.JAPAN);
+ f.format("%Ced", 0x1111);
+ // error on RI, throw UnknownFormatConversionException
+ // RI do not support converter 'C'
+ assertEquals("\u1111ed", f.toString());
+ }
+
+
+ /**
+ * java.util.Formatter#format(String, Object...) for legal
+ * Byte/Short/Integer/Long conversion type 'd'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionD() {
+ final Object[][] triple = {
+ { 0, "%d", "0" },
+ { 0, "%10d", " 0" },
+ { 0, "%-1d", "0" },
+ { 0, "%+d", "+0" },
+ { 0, "% d", " 0" },
+ { 0, "%,d", "0" },
+ { 0, "%(d", "0" },
+ { 0, "%08d", "00000000" },
+ { 0, "%-+,(11d", "+0 " },
+ { 0, "%0 ,(11d", " 0000000000" },
+
+ { (byte) 0xff, "%d", "-1" },
+ { (byte) 0xff, "%10d", " -1" },
+ { (byte) 0xff, "%-1d", "-1" },
+ { (byte) 0xff, "%+d", "-1" },
+ { (byte) 0xff, "% d", "-1" },
+ { (byte) 0xff, "%,d", "-1" },
+ { (byte) 0xff, "%(d", "(1)" },
+ { (byte) 0xff, "%08d", "-0000001" },
+ { (byte) 0xff, "%-+,(11d", "(1) " },
+ { (byte) 0xff, "%0 ,(11d", "(000000001)" },
+
+ { (short) 0xf123, "%d", "-3805" },
+ { (short) 0xf123, "%10d", " -3805" },
+ { (short) 0xf123, "%-1d", "-3805" },
+ { (short) 0xf123, "%+d", "-3805" },
+ { (short) 0xf123, "% d", "-3805" },
+ { (short) 0xf123, "%,d", "-3.805" },
+ { (short) 0xf123, "%(d", "(3805)" },
+ { (short) 0xf123, "%08d", "-0003805" },
+ { (short) 0xf123, "%-+,(11d", "(3.805) " },
+ { (short) 0xf123, "%0 ,(11d", "(00003.805)" },
+
+ { 0x123456, "%d", "1193046" },
+ { 0x123456, "%10d", " 1193046" },
+ { 0x123456, "%-1d", "1193046" },
+ { 0x123456, "%+d", "+1193046" },
+ { 0x123456, "% d", " 1193046" },
+ { 0x123456, "%,d", "1.193.046" },
+ { 0x123456, "%(d", "1193046" },
+ { 0x123456, "%08d", "01193046" },
+ { 0x123456, "%-+,(11d", "+1.193.046 " },
+ { 0x123456, "%0 ,(11d", " 01.193.046" },
+
+ { -3, "%d", "-3" },
+ { -3, "%10d", " -3" },
+ { -3, "%-1d", "-3" },
+ { -3, "%+d", "-3" },
+ { -3, "% d", "-3" },
+ { -3, "%,d", "-3" },
+ { -3, "%(d", "(3)" },
+ { -3, "%08d", "-0000003" },
+ { -3, "%-+,(11d", "(3) " },
+ { -3, "%0 ,(11d", "(000000003)" },
+
+ { 0x7654321L, "%d", "124076833" },
+ { 0x7654321L, "%10d", " 124076833" },
+ { 0x7654321L, "%-1d", "124076833" },
+ { 0x7654321L, "%+d", "+124076833" },
+ { 0x7654321L, "% d", " 124076833" },
+ { 0x7654321L, "%,d", "124.076.833" },
+ { 0x7654321L, "%(d", "124076833" },
+ { 0x7654321L, "%08d", "124076833" },
+ { 0x7654321L, "%-+,(11d", "+124.076.833" },
+ { 0x7654321L, "%0 ,(11d", " 124.076.833" },
+
+ { -1L, "%d", "-1" },
+ { -1L, "%10d", " -1" },
+ { -1L, "%-1d", "-1" },
+ { -1L, "%+d", "-1" },
+ { -1L, "% d", "-1" },
+ { -1L, "%,d", "-1" },
+ { -1L, "%(d", "(1)" },
+ { -1L, "%08d", "-0000001" },
+ { -1L, "%-+,(11d", "(1) " },
+ { -1L, "%0 ,(11d", "(000000001)" },
+ };
+
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ Formatter f;
+ for (int i = 0; i < triple.length; i++) {
+ f = new Formatter(Locale.GERMAN);
+ f.format((String) triple[i][pattern],
+ triple[i][input]);
+ assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
+ + i + "]:" + triple[i][pattern], triple[i][output], f
+ .toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for legal
+ * Byte/Short/Integer/Long conversion type 'o'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionO() {
+ final Object[][] triple = {
+ { 0, "%o", "0" },
+ { 0, "%-6o", "0 " },
+ { 0, "%08o", "00000000" },
+ { 0, "%#o", "00" },
+ { 0, "%0#11o", "00000000000" },
+ { 0, "%-#9o", "00 " },
+
+ { (byte) 0xff, "%o", "377" },
+ { (byte) 0xff, "%-6o", "377 " },
+ { (byte) 0xff, "%08o", "00000377" },
+ { (byte) 0xff, "%#o", "0377" },
+ { (byte) 0xff, "%0#11o", "00000000377" },
+ { (byte) 0xff, "%-#9o", "0377 " },
+
+ { (short) 0xf123, "%o", "170443" },
+ { (short) 0xf123, "%-6o", "170443" },
+ { (short) 0xf123, "%08o", "00170443" },
+ { (short) 0xf123, "%#o", "0170443" },
+ { (short) 0xf123, "%0#11o", "00000170443" },
+ { (short) 0xf123, "%-#9o", "0170443 " },
+
+ { 0x123456, "%o", "4432126" },
+ { 0x123456, "%-6o", "4432126" },
+ { 0x123456, "%08o", "04432126" },
+ { 0x123456, "%#o", "04432126" },
+ { 0x123456, "%0#11o", "00004432126" },
+ { 0x123456, "%-#9o", "04432126 " },
+
+ { -3, "%o", "37777777775" },
+ { -3, "%-6o", "37777777775" },
+ { -3, "%08o", "37777777775" },
+ { -3, "%#o", "037777777775" },
+ { -3, "%0#11o", "037777777775" },
+ { -3, "%-#9o", "037777777775" },
+
+ { 0x7654321L, "%o", "731241441" },
+ { 0x7654321L, "%-6o", "731241441" },
+ { 0x7654321L, "%08o", "731241441" },
+ { 0x7654321L, "%#o", "0731241441" },
+ { 0x7654321L, "%0#11o", "00731241441" },
+ { 0x7654321L, "%-#9o", "0731241441" },
+
+ { -1L, "%o", "1777777777777777777777" },
+ { -1L, "%-6o", "1777777777777777777777" },
+ { -1L, "%08o", "1777777777777777777777" },
+ { -1L, "%#o", "01777777777777777777777" },
+ { -1L, "%0#11o", "01777777777777777777777" },
+ { -1L, "%-#9o", "01777777777777777777777" },
+ };
+
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ Formatter f;
+ for (int i = 0; i < triple.length; i++) {
+ f = new Formatter(Locale.ITALY);
+ f.format((String) triple[i][pattern],
+ triple[i][input]);
+ assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
+ + i + "]:" + triple[i][pattern], triple[i][output], f
+ .toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for legal
+ * Byte/Short/Integer/Long conversion type 'x' and 'X'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionX() {
+ final Object[][] triple = {
+ { 0, "%x", "0" },
+ { 0, "%-8x", "0 " },
+ { 0, "%06x", "000000" },
+ { 0, "%#x", "0x0" },
+ { 0, "%0#12x", "0x0000000000" },
+ { 0, "%-#9x", "0x0 " },
+
+ { (byte) 0xff, "%x", "ff" },
+ { (byte) 0xff, "%-8x", "ff " },
+ { (byte) 0xff, "%06x", "0000ff" },
+ { (byte) 0xff, "%#x", "0xff" },
+ { (byte) 0xff, "%0#12x", "0x00000000ff" },
+ { (byte) 0xff, "%-#9x", "0xff " },
+
+ { (short) 0xf123, "%x", "f123" },
+ { (short) 0xf123, "%-8x", "f123 " },
+ { (short) 0xf123, "%06x", "00f123" },
+ { (short) 0xf123, "%#x", "0xf123" },
+ { (short) 0xf123, "%0#12x", "0x000000f123" },
+ { (short) 0xf123, "%-#9x", "0xf123 " },
+
+ { 0x123456, "%x", "123456" },
+ { 0x123456, "%-8x", "123456 " },
+ { 0x123456, "%06x", "123456" },
+ { 0x123456, "%#x", "0x123456" },
+ { 0x123456, "%0#12x", "0x0000123456" },
+ { 0x123456, "%-#9x", "0x123456 " },
+
+ { -3, "%x", "fffffffd" },
+ { -3, "%-8x", "fffffffd" },
+ { -3, "%06x", "fffffffd" },
+ { -3, "%#x", "0xfffffffd" },
+ { -3, "%0#12x", "0x00fffffffd" },
+ { -3, "%-#9x", "0xfffffffd" },
+
+ { 0x7654321L, "%x", "7654321" },
+ { 0x7654321L, "%-8x", "7654321 " },
+ { 0x7654321L, "%06x", "7654321" },
+ { 0x7654321L, "%#x", "0x7654321" },
+ { 0x7654321L, "%0#12x", "0x0007654321" },
+ { 0x7654321L, "%-#9x", "0x7654321" },
+
+ { -1L, "%x", "ffffffffffffffff" },
+ { -1L, "%-8x", "ffffffffffffffff" },
+ { -1L, "%06x", "ffffffffffffffff" },
+ { -1L, "%#x", "0xffffffffffffffff" },
+ { -1L, "%0#12x", "0xffffffffffffffff" },
+ { -1L, "%-#9x", "0xffffffffffffffff" },
+ };
+
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ Formatter f;
+ for (int i = 0; i < triple.length; i++) {
+ f = new Formatter(Locale.FRANCE);
+ f.format((String) triple[i][pattern],
+ triple[i][input]);
+ assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
+ + i + "]:" + triple[i][pattern], triple[i][output], f
+ .toString());
+
+ f = new Formatter(Locale.FRANCE);
+ f.format((String) triple[i][pattern],
+ triple[i][input]);
+ assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
+ + i + "]:" + triple[i][pattern], triple[i][output], f
+ .toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for Date/Time
+ * conversion
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion() {
+ Formatter f = null;
+ Date now = new Date(1147327147578L);
+
+ Calendar paris = Calendar.getInstance(TimeZone
+ .getTimeZone("Europe/Paris"), Locale.FRANCE);
+ paris.set(2006, 4, 8, 12, 0, 0);
+ paris.set(Calendar.MILLISECOND, 453);
+ Calendar china = Calendar.getInstance(
+ TimeZone.getTimeZone("GMT-08:00"), Locale.CHINA);
+ china.set(2006, 4, 8, 12, 0, 0);
+ china.set(Calendar.MILLISECOND, 609);
+
+ final Object[][] lowerCaseGermanTriple = {
+ { 0L, 'a', "Do." }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'a', "So." }, //$NON-NLS-2$
+ { -1000L, 'a', "Do." }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'a', "Do." }, //$NON-NLS-2$
+ { paris, 'a', "Mo." }, //$NON-NLS-2$
+ { china, 'a', "Mo." }, //$NON-NLS-2$
+ { 0L, 'b', "Jan" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'b', "Aug" }, //$NON-NLS-2$
+ { -1000L, 'b', "Jan" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'b', "Mai" }, //$NON-NLS-2$
+ { paris, 'b', "Mai" }, //$NON-NLS-2$
+ { china, 'b', "Mai" }, //$NON-NLS-2$
+ { 0L, 'c', "Do. Jan 01 08:00:00 GMT+08:00 1970" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'c', "So. Aug 17 15:18:47 GMT+08:00 292278994" }, //$NON-NLS-2$
+ { -1000L, 'c', "Do. Jan 01 07:59:59 GMT+08:00 1970" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'c', "Do. Mai 11 13:59:07 GMT+08:00 2006" }, //$NON-NLS-2$
+ { paris, 'c', "Mo. Mai 08 12:00:00 MESZ 2006" }, //$NON-NLS-2$
+ { china, 'c', "Mo. Mai 08 12:00:00 GMT-08:00 2006" }, //$NON-NLS-2$
+ { 0L, 'd', "01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'd', "17" }, //$NON-NLS-2$
+ { -1000L, 'd', "01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'd', "11" }, //$NON-NLS-2$
+ { paris, 'd', "08" }, //$NON-NLS-2$
+ { china, 'd', "08" }, //$NON-NLS-2$
+ { 0L, 'e', "1" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'e', "17" }, //$NON-NLS-2$
+ { -1000L, 'e', "1" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'e', "11" }, //$NON-NLS-2$
+ { paris, 'e', "8" }, //$NON-NLS-2$
+ { china, 'e', "8" }, //$NON-NLS-2$
+ { 0L, 'h', "Jan" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'h', "Aug" }, //$NON-NLS-2$
+ { -1000L, 'h', "Jan" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'h', "Mai" }, //$NON-NLS-2$
+ { paris, 'h', "Mai" }, //$NON-NLS-2$
+ { china, 'h', "Mai" }, //$NON-NLS-2$
+ { 0L, 'j', "001" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'j', "229" }, //$NON-NLS-2$
+ { -1000L, 'j', "001" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'j', "131" }, //$NON-NLS-2$
+ { paris, 'j', "128" }, //$NON-NLS-2$
+ { china, 'j', "128" }, //$NON-NLS-2$
+ { 0L, 'k', "8" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'k', "15" }, //$NON-NLS-2$
+ { -1000L, 'k', "7" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'k', "13" }, //$NON-NLS-2$
+ { paris, 'k', "12" }, //$NON-NLS-2$
+ { china, 'k', "12" }, //$NON-NLS-2$
+ { 0L, 'l', "8" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'l', "3" }, //$NON-NLS-2$
+ { -1000L, 'l', "7" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'l', "1" }, //$NON-NLS-2$
+ { paris, 'l', "12" }, //$NON-NLS-2$
+ { china, 'l', "12" }, //$NON-NLS-2$
+ { 0L, 'm', "01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'm', "08" }, //$NON-NLS-2$
+ { -1000L, 'm', "01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'm', "05" }, //$NON-NLS-2$
+ { paris, 'm', "05" }, //$NON-NLS-2$
+ { china, 'm', "05" }, //$NON-NLS-2$
+ { 0L, 'p', "vorm." }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'p', "nachm." }, //$NON-NLS-2$
+ { -1000L, 'p', "vorm." }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'p', "nachm." }, //$NON-NLS-2$
+ { paris, 'p', "nachm." }, //$NON-NLS-2$
+ { china, 'p', "nachm." }, //$NON-NLS-2$
+ { 0L, 'r', "08:00:00 vorm." }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'r', "03:18:47 nachm." }, //$NON-NLS-2$
+ { -1000L, 'r', "07:59:59 vorm." }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'r', "01:59:07 nachm." }, //$NON-NLS-2$
+ { paris, 'r', "12:00:00 nachm." }, //$NON-NLS-2$
+ { china, 'r', "12:00:00 nachm." }, //$NON-NLS-2$
+ { 0L, 's', "0" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 's', "9223372036854775" }, //$NON-NLS-2$
+ { -1000L, 's', "-1" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 's', "1147327147" }, //$NON-NLS-2$
+ { paris, 's', "1147082400" }, //$NON-NLS-2$
+ { china, 's', "1147118400" }, //$NON-NLS-2$
+ { 0L, 'y', "70" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'y', "94" }, //$NON-NLS-2$
+ { -1000L, 'y', "70" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'y', "06" }, //$NON-NLS-2$
+ { paris, 'y', "06" }, //$NON-NLS-2$
+ { china, 'y', "06" }, //$NON-NLS-2$
+ { 0L, 'z', "+0800" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'z', "+0800" }, //$NON-NLS-2$
+ { -1000L, 'z', "+0800" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'z', "+0800" }, //$NON-NLS-2$
+ { paris, 'z', "+0100" }, //$NON-NLS-2$
+ { china, 'z', "-0800" }, //$NON-NLS-2$
+
+ };
+
+ final Object[][] lowerCaseFranceTriple = {
+ { 0L, 'a', "jeu." }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'a', "dim." }, //$NON-NLS-2$
+ { -1000L, 'a', "jeu." }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'a', "jeu." }, //$NON-NLS-2$
+ { paris, 'a', "lun." }, //$NON-NLS-2$
+ { china, 'a', "lun." }, //$NON-NLS-2$
+ { 0L, 'b', "janv." }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'b', "ao\u00fbt" }, //$NON-NLS-2$
+ { -1000L, 'b', "janv." }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'b', "mai" }, //$NON-NLS-2$
+ { paris, 'b', "mai" }, //$NON-NLS-2$
+ { china, 'b', "mai" }, //$NON-NLS-2$
+ { 0L, 'c', "jeu. janv. 01 08:00:00 UTC+08:00 1970" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'c', "dim. ao\u00fbt 17 15:18:47 UTC+08:00 292278994" }, //$NON-NLS-2$
+ { -1000L, 'c', "jeu. janv. 01 07:59:59 UTC+08:00 1970" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'c', "jeu. mai 11 13:59:07 UTC+08:00 2006" }, //$NON-NLS-2$
+ { paris, 'c', "lun. mai 08 12:00:00 HAEC 2006" }, //$NON-NLS-2$
+ { china, 'c', "lun. mai 08 12:00:00 UTC-08:00 2006" }, //$NON-NLS-2$
+ { 0L, 'd', "01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'd', "17" }, //$NON-NLS-2$
+ { -1000L, 'd', "01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'd', "11" }, //$NON-NLS-2$
+ { paris, 'd', "08" }, //$NON-NLS-2$
+ { china, 'd', "08" }, //$NON-NLS-2$
+ { 0L, 'e', "1" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'e', "17" }, //$NON-NLS-2$
+ { -1000L, 'e', "1" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'e', "11" }, //$NON-NLS-2$
+ { paris, 'e', "8" }, //$NON-NLS-2$
+ { china, 'e', "8" }, //$NON-NLS-2$
+ { 0L, 'h', "janv." }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'h', "ao\u00fbt" }, //$NON-NLS-2$
+ { -1000L, 'h', "janv." }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'h', "mai" }, //$NON-NLS-2$
+ { paris, 'h', "mai" }, //$NON-NLS-2$
+ { china, 'h', "mai" }, //$NON-NLS-2$
+ { 0L, 'j', "001" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'j', "229" }, //$NON-NLS-2$
+ { -1000L, 'j', "001" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'j', "131" }, //$NON-NLS-2$
+ { paris, 'j', "128" }, //$NON-NLS-2$
+ { china, 'j', "128" }, //$NON-NLS-2$
+ { 0L, 'k', "8" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'k', "15" }, //$NON-NLS-2$
+ { -1000L, 'k', "7" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'k', "13" }, //$NON-NLS-2$
+ { paris, 'k', "12" }, //$NON-NLS-2$
+ { china, 'k', "12" }, //$NON-NLS-2$
+ { 0L, 'l', "8" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'l', "3" }, //$NON-NLS-2$
+ { -1000L, 'l', "7" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'l', "1" }, //$NON-NLS-2$
+ { paris, 'l', "12" }, //$NON-NLS-2$
+ { china, 'l', "12" }, //$NON-NLS-2$
+ { 0L, 'm', "01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'm', "08" }, //$NON-NLS-2$
+ { -1000L, 'm', "01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'm', "05" }, //$NON-NLS-2$
+ { paris, 'm', "05" }, //$NON-NLS-2$
+ { china, 'm', "05" }, //$NON-NLS-2$
+ { 0L, 'p', "am" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'p', "pm" }, //$NON-NLS-2$
+ { -1000L, 'p', "am" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'p', "pm" }, //$NON-NLS-2$
+ { paris, 'p', "pm" }, //$NON-NLS-2$
+ { china, 'p', "pm" }, //$NON-NLS-2$
+ { 0L, 'r', "08:00:00 AM" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'r', "03:18:47 PM" }, //$NON-NLS-2$
+ { -1000L, 'r', "07:59:59 AM" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'r', "01:59:07 PM" }, //$NON-NLS-2$
+ { paris, 'r', "12:00:00 PM" }, //$NON-NLS-2$
+ { china, 'r', "12:00:00 PM" }, //$NON-NLS-2$
+ { 0L, 's', "0" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 's', "9223372036854775" }, //$NON-NLS-2$
+ { -1000L, 's', "-1" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 's', "1147327147" }, //$NON-NLS-2$
+ { paris, 's', "1147082400" }, //$NON-NLS-2$
+ { china, 's', "1147118400" }, //$NON-NLS-2$
+ { 0L, 'y', "70" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'y', "94" }, //$NON-NLS-2$
+ { -1000L, 'y', "70" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'y', "06" }, //$NON-NLS-2$
+ { paris, 'y', "06" }, //$NON-NLS-2$
+ { china, 'y', "06" }, //$NON-NLS-2$
+ { 0L, 'z', "+0800" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'z', "+0800" }, //$NON-NLS-2$
+ { -1000L, 'z', "+0800" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'z', "+0800" }, //$NON-NLS-2$
+ { paris, 'z', "+0100" }, //$NON-NLS-2$
+ { china, 'z', "-0800" }, //$NON-NLS-2$
+
+ };
+
+ final Object[][] lowerCaseJapanTriple = {
+ { 0L, 'a', "\u6728" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'a', "\u65e5" }, //$NON-NLS-2$
+ { -1000L, 'a', "\u6728" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'a', "\u6728" }, //$NON-NLS-2$
+ { paris, 'a', "\u6708" }, //$NON-NLS-2$
+ { china, 'a', "\u6708" }, //$NON-NLS-2$
+ { 0L, 'b', "1\u6708" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'b', "8\u6708" }, //$NON-NLS-2$
+ { -1000L, 'b', "1\u6708" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'b', "5\u6708" }, //$NON-NLS-2$
+ { paris, 'b', "5\u6708" }, //$NON-NLS-2$
+ { china, 'b', "5\u6708" }, //$NON-NLS-2$
+ { 0L, 'c', "\u6728 1\u6708 01 08:00:00 GMT+08:00 1970" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'c', "\u65e5 8\u6708 17 15:18:47 GMT+08:00 292278994" }, //$NON-NLS-2$
+ { -1000L, 'c', "\u6728 1\u6708 01 07:59:59 GMT+08:00 1970" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'c', "\u6728 5\u6708 11 13:59:07 GMT+08:00 2006" }, //$NON-NLS-2$
+ { paris, 'c', "\u6708 5\u6708 08 12:00:00 GMT+02:00 2006" }, //$NON-NLS-2$
+ { china, 'c', "\u6708 5\u6708 08 12:00:00 GMT-08:00 2006" }, //$NON-NLS-2$
+ { 0L, 'd', "01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'd', "17" }, //$NON-NLS-2$
+ { -1000L, 'd', "01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'd', "11" }, //$NON-NLS-2$
+ { paris, 'd', "08" }, //$NON-NLS-2$
+ { china, 'd', "08" }, //$NON-NLS-2$
+ { 0L, 'e', "1" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'e', "17" }, //$NON-NLS-2$
+ { -1000L, 'e', "1" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'e', "11" }, //$NON-NLS-2$
+ { paris, 'e', "8" }, //$NON-NLS-2$
+ { china, 'e', "8" }, //$NON-NLS-2$
+ { 0L, 'h', "1\u6708" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'h', "8\u6708" }, //$NON-NLS-2$
+ { -1000L, 'h', "1\u6708" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'h', "5\u6708" }, //$NON-NLS-2$
+ { paris, 'h', "5\u6708" }, //$NON-NLS-2$
+ { china, 'h', "5\u6708" }, //$NON-NLS-2$
+ { 0L, 'j', "001" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'j', "229" }, //$NON-NLS-2$
+ { -1000L, 'j', "001" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'j', "131" }, //$NON-NLS-2$
+ { paris, 'j', "128" }, //$NON-NLS-2$
+ { china, 'j', "128" }, //$NON-NLS-2$
+ { 0L, 'k', "8" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'k', "15" }, //$NON-NLS-2$
+ { -1000L, 'k', "7" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'k', "13" }, //$NON-NLS-2$
+ { paris, 'k', "12" }, //$NON-NLS-2$
+ { china, 'k', "12" }, //$NON-NLS-2$
+ { 0L, 'l', "8" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'l', "3" }, //$NON-NLS-2$
+ { -1000L, 'l', "7" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'l', "1" }, //$NON-NLS-2$
+ { paris, 'l', "12" }, //$NON-NLS-2$
+ { china, 'l', "12" }, //$NON-NLS-2$
+ { 0L, 'm', "01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'm', "08" }, //$NON-NLS-2$
+ { -1000L, 'm', "01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'm', "05" }, //$NON-NLS-2$
+ { paris, 'm', "05" }, //$NON-NLS-2$
+ { china, 'm', "05" }, //$NON-NLS-2$
+ { 0L, 'p', "\u5348\u524d" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'p', "\u5348\u5f8c" }, //$NON-NLS-2$
+ { -1000L, 'p', "\u5348\u524d" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'p', "\u5348\u5f8c" }, //$NON-NLS-2$
+ { paris, 'p', "\u5348\u5f8c" }, //$NON-NLS-2$
+ { china, 'p', "\u5348\u5f8c" }, //$NON-NLS-2$
+ { 0L, 'r', "08:00:00 \u5348\u524d" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'r', "03:18:47 \u5348\u5f8c" }, //$NON-NLS-2$
+ { -1000L, 'r', "07:59:59 \u5348\u524d" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'r', "01:59:07 \u5348\u5f8c" }, //$NON-NLS-2$
+ { paris, 'r', "12:00:00 \u5348\u5f8c" }, //$NON-NLS-2$
+ { china, 'r', "12:00:00 \u5348\u5f8c" }, //$NON-NLS-2$
+ { 0L, 's', "0" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 's', "9223372036854775" }, //$NON-NLS-2$
+ { -1000L, 's', "-1" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 's', "1147327147" }, //$NON-NLS-2$
+ { paris, 's', "1147082400" }, //$NON-NLS-2$
+ { china, 's', "1147118400" }, //$NON-NLS-2$
+ { 0L, 'y', "70" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'y', "94" }, //$NON-NLS-2$
+ { -1000L, 'y', "70" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'y', "06" }, //$NON-NLS-2$
+ { paris, 'y', "06" }, //$NON-NLS-2$
+ { china, 'y', "06" }, //$NON-NLS-2$
+ { 0L, 'z', "+0800" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'z', "+0800" }, //$NON-NLS-2$
+ { -1000L, 'z', "+0800" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'z', "+0800" }, //$NON-NLS-2$
+ { paris, 'z', "+0100" }, //$NON-NLS-2$
+ { china, 'z', "-0800" }, //$NON-NLS-2$
+ };
+
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ for (int i = 0; i < 90; i++) {
+ // go through legal conversion
+ String formatSpecifier = "%t" + lowerCaseGermanTriple[i][pattern]; //$NON-NLS-2$
+ String formatSpecifierUpper = "%T" + lowerCaseGermanTriple[i][pattern]; //$NON-NLS-2$
+ // test '%t'
+ f = new Formatter(Locale.GERMAN);
+ f.format(formatSpecifier, lowerCaseGermanTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+ + " Argument: " + lowerCaseGermanTriple[i][input], //$NON-NLS-2$
+ lowerCaseGermanTriple[i][output], f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format(Locale.FRANCE, formatSpecifier, lowerCaseFranceTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+ + " Argument: " + lowerCaseFranceTriple[i][input], //$NON-NLS-2$
+ lowerCaseFranceTriple[i][output], f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format(Locale.JAPAN, formatSpecifier, lowerCaseJapanTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+ + " Argument: " + lowerCaseJapanTriple[i][input], //$NON-NLS-2$
+ lowerCaseJapanTriple[i][output], f.toString());
+
+ // test '%T'
+ f = new Formatter(Locale.GERMAN);
+ f.format(formatSpecifierUpper, lowerCaseGermanTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+ + " Argument: " + lowerCaseGermanTriple[i][input], //$NON-NLS-2$
+ ((String) lowerCaseGermanTriple[i][output])
+ .toUpperCase(Locale.US), f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format(Locale.FRANCE, formatSpecifierUpper, lowerCaseFranceTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+ + " Argument: " + lowerCaseFranceTriple[i][input], //$NON-NLS-2$
+ ((String) lowerCaseFranceTriple[i][output])
+ .toUpperCase(Locale.US), f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format(Locale.JAPAN, formatSpecifierUpper, lowerCaseJapanTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+ + " Argument: " + lowerCaseJapanTriple[i][input], //$NON-NLS-2$
+ ((String) lowerCaseJapanTriple[i][output])
+ .toUpperCase(Locale.US), f.toString());
+ }
+
+ final Object[][] upperCaseGermanTriple = {
+ { 0L, 'A', "Donnerstag" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'A', "Sonntag" }, //$NON-NLS-2$
+ { -1000L, 'A', "Donnerstag" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'A', "Donnerstag" }, //$NON-NLS-2$
+ { paris, 'A', "Montag" }, //$NON-NLS-2$
+ { china, 'A', "Montag" }, //$NON-NLS-2$
+ { 0L, 'B', "Januar" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'B', "August" }, //$NON-NLS-2$
+ { -1000L, 'B', "Januar" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'B', "Mai" }, //$NON-NLS-2$
+ { paris, 'B', "Mai" }, //$NON-NLS-2$
+ { china, 'B', "Mai" }, //$NON-NLS-2$
+ { 0L, 'C', "19" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'C', "2922789" }, //$NON-NLS-2$
+ { -1000L, 'C', "19" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'C', "20" }, //$NON-NLS-2$
+ { paris, 'C', "20" }, //$NON-NLS-2$
+ { china, 'C', "20" }, //$NON-NLS-2$
+ { 0L, 'D', "01/01/70" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'D', "08/17/94" }, //$NON-NLS-2$
+ { -1000L, 'D', "01/01/70" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'D', "05/11/06" }, //$NON-NLS-2$
+ { paris, 'D', "05/08/06" }, //$NON-NLS-2$
+ { china, 'D', "05/08/06" }, //$NON-NLS-2$
+ { 0L, 'F', "1970-01-01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'F', "292278994-08-17" }, //$NON-NLS-2$
+ { -1000L, 'F', "1970-01-01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'F', "2006-05-11" }, //$NON-NLS-2$
+ { paris, 'F', "2006-05-08" }, //$NON-NLS-2$
+ { china, 'F', "2006-05-08" }, //$NON-NLS-2$
+ { 0L, 'H', "08" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'H', "15" }, //$NON-NLS-2$
+ { -1000L, 'H', "07" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'H', "13" }, //$NON-NLS-2$
+ { paris, 'H', "12" }, //$NON-NLS-2$
+ { china, 'H', "12" }, //$NON-NLS-2$
+ { 0L, 'I', "08" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'I', "03" }, //$NON-NLS-2$
+ { -1000L, 'I', "07" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'I', "01" }, //$NON-NLS-2$
+ { paris, 'I', "12" }, //$NON-NLS-2$
+ { china, 'I', "12" }, //$NON-NLS-2$
+ { 0L, 'L', "000" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'L', "807" }, //$NON-NLS-2$
+ { -1000L, 'L', "000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'L', "578" }, //$NON-NLS-2$
+ { paris, 'L', "453" }, //$NON-NLS-2$
+ { china, 'L', "609" }, //$NON-NLS-2$
+ { 0L, 'M', "00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'M', "18" }, //$NON-NLS-2$
+ { -1000L, 'M', "59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'M', "59" }, //$NON-NLS-2$
+ { paris, 'M', "00" }, //$NON-NLS-2$
+ { china, 'M', "00" }, //$NON-NLS-2$
+ { 0L, 'N', "000000000" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'N', "807000000" }, //$NON-NLS-2$
+ { -1000L, 'N', "000000000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'N', "578000000" }, //$NON-NLS-2$
+ { paris, 'N', "609000000" }, //$NON-NLS-2$
+ { china, 'N', "609000000" }, //$NON-NLS-2$
+ { 0L, 'Q', "0" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Q', "9223372036854775807" }, //$NON-NLS-2$
+ { -1000L, 'Q', "-1000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Q', "1147327147578" }, //$NON-NLS-2$
+ { paris, 'Q', "1147082400453" }, //$NON-NLS-2$
+ { china, 'Q', "1147118400609" }, //$NON-NLS-2$
+ { 0L, 'R', "08:00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'R', "15:18" }, //$NON-NLS-2$
+ { -1000L, 'R', "07:59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'R', "13:59" }, //$NON-NLS-2$
+ { paris, 'R', "12:00" }, //$NON-NLS-2$
+ { china, 'R', "12:00" }, //$NON-NLS-2$
+ { 0L, 'S', "00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'S', "47" }, //$NON-NLS-2$
+ { -1000L, 'S', "59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'S', "07" }, //$NON-NLS-2$
+ { paris, 'S', "00" }, //$NON-NLS-2$
+ { china, 'S', "00" }, //$NON-NLS-2$
+ { 0L, 'T', "08:00:00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'T', "15:18:47" }, //$NON-NLS-2$
+ { -1000L, 'T', "07:59:59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'T', "13:59:07" }, //$NON-NLS-2$
+ { paris, 'T', "12:00:00" }, //$NON-NLS-2$
+ { china, 'T', "12:00:00" }, //$NON-NLS-2$
+ { 0L, 'Y', "1970" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Y', "292278994" }, //$NON-NLS-2$
+ { -1000L, 'Y', "1970" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Y', "2006" }, //$NON-NLS-2$
+ { paris, 'Y', "2006" }, //$NON-NLS-2$
+ { china, 'Y', "2006" }, //$NON-NLS-2$
+ { 0L, 'Z', "CST" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Z', "CST" }, //$NON-NLS-2$
+ { -1000L, 'Z', "CST" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Z', "CST" }, //$NON-NLS-2$
+ { paris, 'Z', "CEST" }, //$NON-NLS-2$
+ { china, 'Z', "GMT-08:00" }, //$NON-NLS-2$
+
+ };
+
+ final Object[][] upperCaseFranceTriple = {
+ { 0L, 'A', "jeudi" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'A', "dimanche" }, //$NON-NLS-2$
+ { -1000L, 'A', "jeudi" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'A', "jeudi" }, //$NON-NLS-2$
+ { paris, 'A', "lundi" }, //$NON-NLS-2$
+ { china, 'A', "lundi" }, //$NON-NLS-2$
+ { 0L, 'B', "janvier" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'B', "ao\u00fbt" }, //$NON-NLS-2$
+ { -1000L, 'B', "janvier" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'B', "mai" }, //$NON-NLS-2$
+ { paris, 'B', "mai" }, //$NON-NLS-2$
+ { china, 'B', "mai" }, //$NON-NLS-2$
+ { 0L, 'C', "19" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'C', "2922789" }, //$NON-NLS-2$
+ { -1000L, 'C', "19" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'C', "20" }, //$NON-NLS-2$
+ { paris, 'C', "20" }, //$NON-NLS-2$
+ { china, 'C', "20" }, //$NON-NLS-2$
+ { 0L, 'D', "01/01/70" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'D', "08/17/94" }, //$NON-NLS-2$
+ { -1000L, 'D', "01/01/70" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'D', "05/11/06" }, //$NON-NLS-2$
+ { paris, 'D', "05/08/06" }, //$NON-NLS-2$
+ { china, 'D', "05/08/06" }, //$NON-NLS-2$
+ { 0L, 'F', "1970-01-01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'F', "292278994-08-17" }, //$NON-NLS-2$
+ { -1000L, 'F', "1970-01-01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'F', "2006-05-11" }, //$NON-NLS-2$
+ { paris, 'F', "2006-05-08" }, //$NON-NLS-2$
+ { china, 'F', "2006-05-08" }, //$NON-NLS-2$
+ { 0L, 'H', "08" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'H', "15" }, //$NON-NLS-2$
+ { -1000L, 'H', "07" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'H', "13" }, //$NON-NLS-2$
+ { paris, 'H', "12" }, //$NON-NLS-2$
+ { china, 'H', "12" }, //$NON-NLS-2$
+ { 0L, 'I', "08" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'I', "03" }, //$NON-NLS-2$
+ { -1000L, 'I', "07" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'I', "01" }, //$NON-NLS-2$
+ { paris, 'I', "12" }, //$NON-NLS-2$
+ { china, 'I', "12" }, //$NON-NLS-2$
+ { 0L, 'L', "000" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'L', "807" }, //$NON-NLS-2$
+ { -1000L, 'L', "000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'L', "578" }, //$NON-NLS-2$
+ { paris, 'L', "453" }, //$NON-NLS-2$
+ { china, 'L', "609" }, //$NON-NLS-2$
+ { 0L, 'M', "00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'M', "18" }, //$NON-NLS-2$
+ { -1000L, 'M', "59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'M', "59" }, //$NON-NLS-2$
+ { paris, 'M', "00" }, //$NON-NLS-2$
+ { china, 'M', "00" }, //$NON-NLS-2$
+ { 0L, 'N', "000000000" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'N', "807000000" }, //$NON-NLS-2$
+ { -1000L, 'N', "000000000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'N', "578000000" }, //$NON-NLS-2$
+ { paris, 'N', "453000000" }, //$NON-NLS-2$
+ { china, 'N', "468000000" }, //$NON-NLS-2$
+ { 0L, 'Q', "0" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Q', "9223372036854775807" }, //$NON-NLS-2$
+ { -1000L, 'Q', "-1000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Q', "1147327147578" }, //$NON-NLS-2$
+ { paris, 'Q', "1147082400453" }, //$NON-NLS-2$
+ { china, 'Q', "1147118400609" }, //$NON-NLS-2$
+ { 0L, 'R', "08:00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'R', "15:18" }, //$NON-NLS-2$
+ { -1000L, 'R', "07:59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'R', "13:59" }, //$NON-NLS-2$
+ { paris, 'R', "12:00" }, //$NON-NLS-2$
+ { china, 'R', "12:00" }, //$NON-NLS-2$
+ { 0L, 'S', "00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'S', "47" }, //$NON-NLS-2$
+ { -1000L, 'S', "59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'S', "07" }, //$NON-NLS-2$
+ { paris, 'S', "00" }, //$NON-NLS-2$
+ { china, 'S', "00" }, //$NON-NLS-2$
+ { 0L, 'T', "08:00:00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'T', "15:18:47" }, //$NON-NLS-2$
+ { -1000L, 'T', "07:59:59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'T', "13:59:07" }, //$NON-NLS-2$
+ { paris, 'T', "12:00:00" }, //$NON-NLS-2$
+ { china, 'T', "12:00:00" }, //$NON-NLS-2$
+ { 0L, 'Y', "1970" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Y', "292278994" }, //$NON-NLS-2$
+ { -1000L, 'Y', "1970" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Y', "2006" }, //$NON-NLS-2$
+ { paris, 'Y', "2006" }, //$NON-NLS-2$
+ { china, 'Y', "2006" }, //$NON-NLS-2$
+ { 0L, 'Z', "CST" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Z', "CST" }, //$NON-NLS-2$
+ { -1000L, 'Z', "CST" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Z', "CST" }, //$NON-NLS-2$
+ { paris, 'Z', "CEST" }, //$NON-NLS-2$
+ { china, 'Z', "GMT-08:00" }, //$NON-NLS-2$
+
+ };
+
+ final Object[][] upperCaseJapanTriple = {
+ { 0L, 'A', "\u6728\u66dc\u65e5" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'A', "\u65e5\u66dc\u65e5" }, //$NON-NLS-2$
+ { -1000L, 'A', "\u6728\u66dc\u65e5" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'A', "\u6728\u66dc\u65e5" }, //$NON-NLS-2$
+ { paris, 'A', "\u6708\u66dc\u65e5" }, //$NON-NLS-2$
+ { china, 'A', "\u6708\u66dc\u65e5" }, //$NON-NLS-2$
+ { 0L, 'B', "1\u6708" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'B', "8\u6708" }, //$NON-NLS-2$
+ { -1000L, 'B', "1\u6708" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'B', "5\u6708" }, //$NON-NLS-2$
+ { paris, 'B', "5\u6708" }, //$NON-NLS-2$
+ { china, 'B', "5\u6708" }, //$NON-NLS-2$
+ { 0L, 'C', "19" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'C', "2922789" }, //$NON-NLS-2$
+ { -1000L, 'C', "19" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'C', "20" }, //$NON-NLS-2$
+ { paris, 'C', "20" }, //$NON-NLS-2$
+ { china, 'C', "20" }, //$NON-NLS-2$
+ { 0L, 'D', "01/01/70" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'D', "08/17/94" }, //$NON-NLS-2$
+ { -1000L, 'D', "01/01/70" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'D', "05/11/06" }, //$NON-NLS-2$
+ { paris, 'D', "05/08/06" }, //$NON-NLS-2$
+ { china, 'D', "05/08/06" }, //$NON-NLS-2$
+ { 0L, 'F', "1970-01-01" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'F', "292278994-08-17" }, //$NON-NLS-2$
+ { -1000L, 'F', "1970-01-01" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'F', "2006-05-11" }, //$NON-NLS-2$
+ { paris, 'F', "2006-05-08" }, //$NON-NLS-2$
+ { china, 'F', "2006-05-08" }, //$NON-NLS-2$
+ { 0L, 'H', "08" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'H', "15" }, //$NON-NLS-2$
+ { -1000L, 'H', "07" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'H', "13" }, //$NON-NLS-2$
+ { paris, 'H', "12" }, //$NON-NLS-2$
+ { china, 'H', "12" }, //$NON-NLS-2$
+ { 0L, 'I', "08" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'I', "03" }, //$NON-NLS-2$
+ { -1000L, 'I', "07" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'I', "01" }, //$NON-NLS-2$
+ { paris, 'I', "12" }, //$NON-NLS-2$
+ { china, 'I', "12" }, //$NON-NLS-2$
+ { 0L, 'L', "000" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'L', "807" }, //$NON-NLS-2$
+ { -1000L, 'L', "000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'L', "578" }, //$NON-NLS-2$
+ { paris, 'L', "453" }, //$NON-NLS-2$
+ { china, 'L', "609" }, //$NON-NLS-2$
+ { 0L, 'M', "00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'M', "18" }, //$NON-NLS-2$
+ { -1000L, 'M', "59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'M', "59" }, //$NON-NLS-2$
+ { paris, 'M', "00" }, //$NON-NLS-2$
+ { china, 'M', "00" }, //$NON-NLS-2$
+ { 0L, 'N', "000000000" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'N', "807000000" }, //$NON-NLS-2$
+ { -1000L, 'N', "000000000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'N', "578000000" }, //$NON-NLS-2$
+ { paris, 'N', "453000000" }, //$NON-NLS-2$
+ { china, 'N', "468000000" }, //$NON-NLS-2$
+ { 0L, 'Q', "0" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Q', "9223372036854775807" }, //$NON-NLS-2$
+ { -1000L, 'Q', "-1000" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Q', "1147327147578" }, //$NON-NLS-2$
+ { paris, 'Q', "1147082400453" }, //$NON-NLS-2$
+ { china, 'Q', "1147118400609" }, //$NON-NLS-2$
+ { 0L, 'R', "08:00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'R', "15:18" }, //$NON-NLS-2$
+ { -1000L, 'R', "07:59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'R', "13:59" }, //$NON-NLS-2$
+ { paris, 'R', "12:00" }, //$NON-NLS-2$
+ { china, 'R', "12:00" }, //$NON-NLS-2$
+ { 0L, 'S', "00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'S', "47" }, //$NON-NLS-2$
+ { -1000L, 'S', "59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'S', "07" }, //$NON-NLS-2$
+ { paris, 'S', "00" }, //$NON-NLS-2$
+ { china, 'S', "00" }, //$NON-NLS-2$
+ { 0L, 'T', "08:00:00" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'T', "15:18:47" }, //$NON-NLS-2$
+ { -1000L, 'T', "07:59:59" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'T', "13:59:07" }, //$NON-NLS-2$
+ { paris, 'T', "12:00:00" }, //$NON-NLS-2$
+ { china, 'T', "12:00:00" }, //$NON-NLS-2$
+ { 0L, 'Y', "1970" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Y', "292278994" }, //$NON-NLS-2$
+ { -1000L, 'Y', "1970" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Y', "2006" }, //$NON-NLS-2$
+ { paris, 'Y', "2006" }, //$NON-NLS-2$
+ { china, 'Y', "2006" }, //$NON-NLS-2$
+ { 0L, 'Z', "CST" }, //$NON-NLS-2$
+ { Long.MAX_VALUE, 'Z', "CST" }, //$NON-NLS-2$
+ { -1000L, 'Z', "CST" }, //$NON-NLS-2$
+ { new Date(1147327147578L), 'Z', "CST" }, //$NON-NLS-2$
+ { paris, 'Z', "CEST" }, //$NON-NLS-2$
+ { china, 'Z', "GMT-08:00" }, //$NON-NLS-2$
+ };
+
+
+ for (int i = 0; i < 90; i++) {
+ String formatSpecifier = "%t" + upperCaseGermanTriple[i][pattern]; //$NON-NLS-2$
+ String formatSpecifierUpper = "%T" + upperCaseGermanTriple[i][pattern]; //$NON-NLS-2$
+ if ((Character) upperCaseGermanTriple[i][pattern] == 'N') {
+ // result can't be predicted on RI, so skip this test
+ continue;
+ }
+ // test '%t'
+ f = new Formatter(Locale.JAPAN);
+ f.format(formatSpecifier, upperCaseJapanTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+ + " Argument: " + upperCaseJapanTriple[i][input], //$NON-NLS-2$
+ upperCaseJapanTriple[i][output], f.toString());
+
+ f = new Formatter(Locale.JAPAN);
+ f.format(Locale.GERMAN, formatSpecifier, upperCaseGermanTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+ + " Argument: " + upperCaseGermanTriple[i][input], //$NON-NLS-2$
+ upperCaseGermanTriple[i][output], f.toString());
+
+ f = new Formatter(Locale.JAPAN);
+ f.format(Locale.FRANCE, formatSpecifier, upperCaseFranceTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+ + " Argument: " + upperCaseFranceTriple[i][input], //$NON-NLS-2$
+ upperCaseFranceTriple[i][output], f.toString());
+
+ // test '%T'
+ f = new Formatter(Locale.GERMAN);
+ f.format(formatSpecifierUpper, upperCaseGermanTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+ + " Argument: " + upperCaseGermanTriple[i][input], //$NON-NLS-2$
+ ((String) upperCaseGermanTriple[i][output])
+ .toUpperCase(Locale.US), f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format(Locale.JAPAN, formatSpecifierUpper, upperCaseJapanTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+ + " Argument: " + upperCaseJapanTriple[i][input], //$NON-NLS-2$
+ ((String) upperCaseJapanTriple[i][output])
+ .toUpperCase(Locale.US), f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format(Locale.FRANCE, formatSpecifierUpper, upperCaseFranceTriple[i][input]);
+ assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+ + " Argument: " + upperCaseFranceTriple[i][input], //$NON-NLS-2$
+ ((String) upperCaseFranceTriple[i][output])
+ .toUpperCase(Locale.US), f.toString());
+ }
+
+ f = new Formatter(Locale.US);
+ f.format("%-10ta", now); //$NON-NLS-2$
+ assertEquals("Thu ", f.toString()); //$NON-NLS-2$
+
+ f = new Formatter(Locale.US);
+ f.format("%10000000000000000000000000000000001ta", now); //$NON-NLS-2$
+ assertEquals("Thu", f.toString().trim()); //$NON-NLS-2$
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for null argment for
+ * Byte/Short/Integer/Long/BigInteger conversion
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongNullConversion() {
+
+ Formatter f = new Formatter(Locale.FRANCE);
+ f.format("%d%<o%<x%<5X", (Integer) null);
+ assertEquals("nullnullnull NULL", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%d%<#03o %<0#4x%<6X", (Long) null);
+ assertEquals("nullnull null NULL", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%(+,07d%<o %<x%<6X", (Byte) null);
+ assertEquals(" nullnull null NULL", f.toString());
+
+ f = new Formatter(Locale.ITALY);
+ f.format("%(+,07d%<o %<x%<0#6X", (Short) null);
+ assertEquals(" nullnull null NULL", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%(+,-7d%<( o%<+(x %<( 06X", (BigInteger) null);
+ assertEquals("null nullnull NULL", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for legal
+ * BigInteger conversion type 'd'
+ */
+ public void test_formatLjava_lang_String$LBigInteger() {
+ final Object[][] tripleD = {
+ { new BigInteger("123456789012345678901234567890"), "%d", "123456789012345678901234567890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%10d", "123456789012345678901234567890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%-1d", "123456789012345678901234567890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%+d", "+123456789012345678901234567890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "% d", " 123456789012345678901234567890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%,d", "123.456.789.012.345.678.901.234.567.890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%(d", "123456789012345678901234567890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%08d", "123456789012345678901234567890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%-+,(11d", "+123.456.789.012.345.678.901.234.567.890" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%0 ,(11d", " 123.456.789.012.345.678.901.234.567.890" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%10d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%-1d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%+d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "% d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%,d", "-9.876.543.210.987.654.321.098.765.432.100.000" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%(d", "(9876543210987654321098765432100000)" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%08d", "-9876543210987654321098765432100000" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%-+,(11d", "(9.876.543.210.987.654.321.098.765.432.100.000)" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%0 ,(11d", "(9.876.543.210.987.654.321.098.765.432.100.000)" }, //$NON-NLS-2$
+ };
+
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ Formatter f;
+ for (int i = 0; i < tripleD.length; i++) {
+ f = new Formatter(Locale.GERMAN);
+ f.format((String) tripleD[i][pattern],
+ tripleD[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleD[i][input] + ",pattern["
+ + i + "]:" + tripleD[i][pattern], tripleD[i][output], f
+ .toString());
+
+ }
+
+ final Object[][] tripleO = {
+ { new BigInteger("123456789012345678901234567890"), "%o", "143564417755415637016711617605322" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%-6o", "143564417755415637016711617605322" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%08o", "143564417755415637016711617605322" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%#o", "0143564417755415637016711617605322" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%0#11o", "0143564417755415637016711617605322" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%-#9o", "0143564417755415637016711617605322" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%o", "-36336340043453651353467270113157312240" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%-6o", "-36336340043453651353467270113157312240" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%08o", "-36336340043453651353467270113157312240" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%#o", "-036336340043453651353467270113157312240" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%0#11o", "-036336340043453651353467270113157312240" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%-#9o", "-036336340043453651353467270113157312240" }, //$NON-NLS-2$
+ };
+ for (int i = 0; i < tripleO.length; i++) {
+ f = new Formatter(Locale.ITALY);
+ f.format((String) tripleO[i][pattern],
+ tripleO[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleO[i][input] + ",pattern["
+ + i + "]:" + tripleO[i][pattern], tripleO[i][output], f
+ .toString());
+
+ }
+
+ final Object[][] tripleX = {
+ { new BigInteger("123456789012345678901234567890"), "%x", "18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%-8x", "18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%06x", "18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%#x", "0x18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%0#12x", "0x18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
+ { new BigInteger("123456789012345678901234567890"), "%-#9x", "0x18ee90ff6c373e0ee4e3f0ad2" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%x", "-1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%-8x", "-1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%06x", "-1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%#x", "-0x1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%0#12x", "-0x1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
+ { new BigInteger("-9876543210987654321098765432100000"), "%-#9x", "-0x1e6f380472bd4bae6eb8259bd94a0" }, //$NON-NLS-2$
+ };
+
+ for (int i = 0; i < tripleX.length; i++) {
+ f = new Formatter(Locale.FRANCE);
+ f.format((String) tripleX[i][pattern],
+ tripleX[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleX[i][input] + ",pattern["
+ + i + "]:" + tripleX[i][pattern], tripleX[i][output], f
+ .toString());
+
+ }
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%(+,-7d%<( o%<+(x %<( 06X", (BigInteger) null);
+ assertEquals("null nullnull NULL", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for padding of
+ * BigInteger conversion
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerPaddingConversion() {
+ Formatter f = null;
+
+ BigInteger bigInt = new BigInteger("123456789012345678901234567890");
+ f = new Formatter(Locale.GERMAN);
+ f.format("%32d", bigInt);
+ assertEquals(" 123456789012345678901234567890", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%+32x", bigInt);
+ assertEquals(" +18ee90ff6c373e0ee4e3f0ad2", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("% 32o", bigInt);
+ assertEquals(" 143564417755415637016711617605322", f.toString());
+
+ BigInteger negBigInt = new BigInteger(
+ "-1234567890123456789012345678901234567890");
+ f = new Formatter(Locale.GERMAN);
+ f.format("%( 040X", negBigInt);
+ assertEquals("(000003A0C92075C0DBF3B8ACBC5F96CE3F0AD2)", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%+(045d", negBigInt);
+ assertEquals("(0001234567890123456789012345678901234567890)", f
+ .toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%+,-(60d", negBigInt);
+ assertEquals(
+ "(1.234.567.890.123.456.789.012.345.678.901.234.567.890) ",
+ f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for BigInteger
+ * conversion exception
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerConversionException() {
+ Formatter f = null;
+
+ final String[] flagsConversionMismatches = { "%#d", "%,o", "%,x", "%,X" };
+ for (int i = 0; i < flagsConversionMismatches.length; i++) {
+ try {
+ f = new Formatter(Locale.CHINA);
+ f.format(flagsConversionMismatches[i], new BigInteger("1"));
+ fail("should throw FormatFlagsConversionMismatchException");
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+ }
+
+ final String[] missingFormatWidths = { "%-0d", "%0d", "%-d", "%-0o",
+ "%0o", "%-o", "%-0x", "%0x", "%-x", "%-0X", "%0X", "%-X" };
+ for (int i = 0; i < missingFormatWidths.length; i++) {
+ try {
+ f = new Formatter(Locale.KOREA);
+ f.format(missingFormatWidths[i], new BigInteger("1"));
+ fail("should throw MissingFormatWidthException");
+ } catch (MissingFormatWidthException e) {
+ // expected
+ }
+ }
+
+ final String[] illFlags = { "%+ d", "%-08d", "%+ o", "%-08o", "%+ x",
+ "%-08x", "%+ X", "%-08X" };
+ for (int i = 0; i < illFlags.length; i++) {
+ try {
+ f = new Formatter(Locale.CANADA);
+ f.format(illFlags[i], new BigInteger("1"));
+ fail("should throw IllegalFormatFlagsException");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+ }
+
+ final String[] precisionExceptions = { "%.4d", "%2.5o", "%8.6x",
+ "%11.17X" };
+ for (int i = 0; i < precisionExceptions.length; i++) {
+ try {
+ f = new Formatter(Locale.US);
+ f.format(precisionExceptions[i], new BigInteger("1"));
+ fail("should throw IllegalFormatPrecisionException");
+ } catch (IllegalFormatPrecisionException e) {
+ // expected
+ }
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%D", new BigInteger("1"));
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%O", new BigInteger("1"));
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+
+ try {
+ f = new Formatter();
+ f.format("%010000000000000000000000000000000001d", new BigInteger(
+ "1"));
+ fail("should throw MissingFormatWidthException");
+ } catch (MissingFormatWidthException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for BigInteger
+ * exception throwing order
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerExceptionOrder() {
+ Formatter f = null;
+ BigInteger big = new BigInteger("100");
+
+ /*
+ * Order summary: UnknownFormatConversionException >
+ * MissingFormatWidthException > IllegalFormatFlagsException >
+ * IllegalFormatPrecisionException > IllegalFormatConversionException >
+ * FormatFlagsConversionMismatchException
+ *
+ */
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%(o", false);
+ fail();
+ } catch (FormatFlagsConversionMismatchException expected) {
+ } catch (IllegalFormatConversionException expected) {
+ }
+
+ try {
+ f.format("%.4o", false);
+ fail();
+ } catch (IllegalFormatPrecisionException expected) {
+ } catch (IllegalFormatConversionException expected) {
+ }
+
+ try {
+ f.format("%+ .4o", big);
+ fail();
+ } catch (IllegalFormatPrecisionException expected) {
+ } catch (IllegalFormatFlagsException expected) {
+ }
+
+ try {
+ f.format("%+ -o", big);
+ fail();
+ } catch (MissingFormatWidthException expected) {
+ } catch (IllegalFormatFlagsException expected) {
+ }
+
+ try {
+ f.format("%-O", big);
+ fail();
+ } catch (MissingFormatWidthException expected) {
+ } catch (UnknownFormatConversionException expected) {
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for Float/Double
+ * conversion type 'e' and 'E'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionE() {
+ Formatter f = null;
+ final Object[][] tripleE = {
+ { 0f, "%e", "0.000000e+00" },
+ { 0f, "%#.0e", "0.e+00" },
+ { 0f, "%#- (9.8e", " 0.00000000e+00" },
+ { 0f, "%#+0(8.4e", "+0.0000e+00" },
+ { 0f, "%-+(1.6e", "+0.000000e+00" },
+ { 0f, "% 0(12e", " 0.000000e+00" },
+
+ { 101f, "%e", "1.010000e+02" },
+ { 101f, "%#.0e", "1.e+02" },
+ { 101f, "%#- (9.8e", " 1.01000000e+02" },
+ { 101f, "%#+0(8.4e", "+1.0100e+02" },
+ { 101f, "%-+(1.6e", "+1.010000e+02" },
+ { 101f, "% 0(12e", " 1.010000e+02" },
+
+ { 1.f, "%e", "1.000000e+00" },
+ { 1.f, "%#.0e", "1.e+00" },
+ { 1.f, "%#- (9.8e", " 1.00000000e+00" },
+ { 1.f, "%#+0(8.4e", "+1.0000e+00" },
+ { 1.f, "%-+(1.6e", "+1.000000e+00" },
+ { 1.f, "% 0(12e", " 1.000000e+00" },
+
+ { -98f, "%e", "-9.800000e+01" },
+ { -98f, "%#.0e", "-1.e+02" },
+ { -98f, "%#- (9.8e", "(9.80000000e+01)" },
+ { -98f, "%#+0(8.4e", "(9.8000e+01)" },
+ { -98f, "%-+(1.6e", "(9.800000e+01)" },
+ { -98f, "% 0(12e", "(9.800000e+01)" },
+
+ { 1.23f, "%e", "1.230000e+00" },
+ { 1.23f, "%#.0e", "1.e+00" },
+ { 1.23f, "%#- (9.8e", " 1.23000002e+00" },
+ { 1.23f, "%#+0(8.4e", "+1.2300e+00" },
+ { 1.23f, "%-+(1.6e", "+1.230000e+00" },
+ { 1.23f, "% 0(12e", " 1.230000e+00" },
+
+ { 34.1234567f, "%e", "3.412346e+01" },
+ { 34.1234567f, "%#.0e", "3.e+01" },
+ { 34.1234567f, "%#- (9.8e", " 3.41234550e+01" },
+ { 34.1234567f, "%#+0(8.4e", "+3.4123e+01" },
+ { 34.1234567f, "%-+(1.6e", "+3.412346e+01" },
+ { 34.1234567f, "% 0(12e", " 3.412346e+01" },
+
+ { -.12345f, "%e", "-1.234500e-01" },
+ { -.12345f, "%#.0e", "-1.e-01" },
+ { -.12345f, "%#- (9.8e", "(1.23450004e-01)" },
+ { -.12345f, "%#+0(8.4e", "(1.2345e-01)" },
+ { -.12345f, "%-+(1.6e", "(1.234500e-01)" },
+ { -.12345f, "% 0(12e", "(1.234500e-01)" },
+
+ { -9876.1234567f, "%e", "-9.876123e+03" },
+ { -9876.1234567f, "%#.0e", "-1.e+04" },
+ { -9876.1234567f, "%#- (9.8e", "(9.87612305e+03)" },
+ { -9876.1234567f, "%#+0(8.4e", "(9.8761e+03)" },
+ { -9876.1234567f, "%-+(1.6e", "(9.876123e+03)" },
+ { -9876.1234567f, "% 0(12e", "(9.876123e+03)" },
+
+ { Float.MAX_VALUE, "%e", "3.402823e+38" },
+ { Float.MAX_VALUE, "%#.0e", "3.e+38" },
+ { Float.MAX_VALUE, "%#- (9.8e", " 3.40282347e+38" },
+ { Float.MAX_VALUE, "%#+0(8.4e", "+3.4028e+38" },
+ { Float.MAX_VALUE, "%-+(1.6e", "+3.402823e+38" },
+ { Float.MAX_VALUE, "% 0(12e", " 3.402823e+38" },
+
+ { Float.MIN_VALUE, "%e", "1.401298e-45" },
+ { Float.MIN_VALUE, "%#.0e", "1.e-45" },
+ { Float.MIN_VALUE, "%#- (9.8e", " 1.40129846e-45" },
+ { Float.MIN_VALUE, "%#+0(8.4e", "+1.4013e-45" },
+ { Float.MIN_VALUE, "%-+(1.6e", "+1.401298e-45" },
+ { Float.MIN_VALUE, "% 0(12e", " 1.401298e-45" },
+
+ { Float.NaN, "%e", "NaN" },
+ { Float.NaN, "%#.0e", "NaN" },
+ { Float.NaN, "%#- (9.8e", "NaN " },
+ { Float.NaN, "%#+0(8.4e", " NaN" },
+ { Float.NaN, "%-+(1.6e", "NaN" },
+ { Float.NaN, "% 0(12e", " NaN" },
+
+
+ { Float.NEGATIVE_INFINITY, "%e", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%#.0e", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%#- (9.8e", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "%#+0(8.4e", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "%-+(1.6e", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "% 0(12e", " (Infinity)" },
+
+ { Float.NEGATIVE_INFINITY, "%e", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%#.0e", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%#- (9.8e", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "%#+0(8.4e", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "%-+(1.6e", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "% 0(12e", " (Infinity)" },
+
+ { 0d, "%e", "0.000000e+00" },
+ { 0d, "%#.0e", "0.e+00" },
+ { 0d, "%#- (9.8e", " 0.00000000e+00" },
+ { 0d, "%#+0(8.4e", "+0.0000e+00" },
+ { 0d, "%-+(1.6e", "+0.000000e+00" },
+ { 0d, "% 0(12e", " 0.000000e+00" },
+
+ { 1d, "%e", "1.000000e+00" },
+ { 1d, "%#.0e", "1.e+00" },
+ { 1d, "%#- (9.8e", " 1.00000000e+00" },
+ { 1d, "%#+0(8.4e", "+1.0000e+00" },
+ { 1d, "%-+(1.6e", "+1.000000e+00" },
+ { 1d, "% 0(12e", " 1.000000e+00" },
+
+ { -1d, "%e", "-1.000000e+00" },
+ { -1d, "%#.0e", "-1.e+00" },
+ { -1d, "%#- (9.8e", "(1.00000000e+00)" },
+ { -1d, "%#+0(8.4e", "(1.0000e+00)" },
+ { -1d, "%-+(1.6e", "(1.000000e+00)" },
+ { -1d, "% 0(12e", "(1.000000e+00)" },
+
+
+ { .00000001d, "%e", "1.000000e-08" },
+ { .00000001d, "%#.0e", "1.e-08" },
+ { .00000001d, "%#- (9.8e", " 1.00000000e-08" },
+ { .00000001d, "%#+0(8.4e", "+1.0000e-08" },
+ { .00000001d, "%-+(1.6e", "+1.000000e-08" },
+ { .00000001d, "% 0(12e", " 1.000000e-08" },
+
+ { 9122.10d, "%e", "9.122100e+03" },
+ { 9122.10d, "%#.0e", "9.e+03" },
+ { 9122.10d, "%#- (9.8e", " 9.12210000e+03" },
+ { 9122.10d, "%#+0(8.4e", "+9.1221e+03" },
+ { 9122.10d, "%-+(1.6e", "+9.122100e+03" },
+ { 9122.10d, "% 0(12e", " 9.122100e+03" },
+
+ { 0.1d, "%e", "1.000000e-01" },
+ { 0.1d, "%#.0e", "1.e-01" },
+ { 0.1d, "%#- (9.8e", " 1.00000000e-01" },
+ { 0.1d, "%#+0(8.4e", "+1.0000e-01" },
+ { 0.1d, "%-+(1.6e", "+1.000000e-01" },
+ { 0.1d, "% 0(12e", " 1.000000e-01" },
+
+ { -2.d, "%e", "-2.000000e+00" },
+ { -2.d, "%#.0e", "-2.e+00" },
+ { -2.d, "%#- (9.8e", "(2.00000000e+00)" },
+ { -2.d, "%#+0(8.4e", "(2.0000e+00)" },
+ { -2.d, "%-+(1.6e", "(2.000000e+00)" },
+ { -2.d, "% 0(12e", "(2.000000e+00)" },
+
+ { -.39d, "%e", "-3.900000e-01" },
+ { -.39d, "%#.0e", "-4.e-01" },
+ { -.39d, "%#- (9.8e", "(3.90000000e-01)" },
+ { -.39d, "%#+0(8.4e", "(3.9000e-01)" },
+ { -.39d, "%-+(1.6e", "(3.900000e-01)" },
+ { -.39d, "% 0(12e", "(3.900000e-01)" },
+
+ { -1234567890.012345678d, "%e", "-1.234568e+09" },
+ { -1234567890.012345678d, "%#.0e", "-1.e+09" },
+ { -1234567890.012345678d, "%#- (9.8e", "(1.23456789e+09)" },
+ { -1234567890.012345678d, "%#+0(8.4e", "(1.2346e+09)" },
+ { -1234567890.012345678d, "%-+(1.6e", "(1.234568e+09)" },
+ { -1234567890.012345678d, "% 0(12e", "(1.234568e+09)" },
+
+ { Double.MAX_VALUE, "%e", "1.797693e+308" },
+ { Double.MAX_VALUE, "%#.0e", "2.e+308" },
+ { Double.MAX_VALUE, "%#- (9.8e", " 1.79769313e+308" },
+ { Double.MAX_VALUE, "%#+0(8.4e", "+1.7977e+308" },
+ { Double.MAX_VALUE, "%-+(1.6e", "+1.797693e+308" },
+ { Double.MAX_VALUE, "% 0(12e", " 1.797693e+308" },
+
+ { Double.MIN_VALUE, "%e", "4.900000e-324" },
+ { Double.MIN_VALUE, "%#.0e", "5.e-324" },
+ { Double.MIN_VALUE, "%#- (9.8e", " 4.90000000e-324" },
+ { Double.MIN_VALUE, "%#+0(8.4e", "+4.9000e-324" },
+ { Double.MIN_VALUE, "%-+(1.6e", "+4.900000e-324" },
+ { Double.MIN_VALUE, "% 0(12e", " 4.900000e-324" },
+
+ { Double.NaN, "%e", "NaN" },
+ { Double.NaN, "%#.0e", "NaN" },
+ { Double.NaN, "%#- (9.8e", "NaN " },
+ { Double.NaN, "%#+0(8.4e", " NaN" },
+ { Double.NaN, "%-+(1.6e", "NaN" },
+ { Double.NaN, "% 0(12e", " NaN" },
+
+ { Double.NEGATIVE_INFINITY, "%e", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%#.0e", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%#- (9.8e", "(Infinity)" },
+ { Double.NEGATIVE_INFINITY, "%#+0(8.4e", "(Infinity)" },
+ { Double.NEGATIVE_INFINITY, "%-+(1.6e", "(Infinity)" },
+ { Double.NEGATIVE_INFINITY, "% 0(12e", " (Infinity)" },
+
+ { Double.POSITIVE_INFINITY, "%e", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%#.0e", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%#- (9.8e", " Infinity" },
+ { Double.POSITIVE_INFINITY, "%#+0(8.4e", "+Infinity" },
+ { Double.POSITIVE_INFINITY, "%-+(1.6e", "+Infinity" },
+ { Double.POSITIVE_INFINITY, "% 0(12e", " Infinity" },
+ };
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ for (int i = 0; i < tripleE.length; i++) {
+ f = new Formatter(Locale.US);
+ f.format((String) tripleE[i][pattern], tripleE[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
+ + i + "]:" + tripleE[i][pattern],
+ tripleE[i][output], f.toString());
+
+ // test for conversion type 'E'
+ f = new Formatter(Locale.US);
+ f.format(((String) tripleE[i][pattern]).toUpperCase(), tripleE[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
+ + i + "]:" + tripleE[i][pattern], ((String) tripleE[i][output])
+ .toUpperCase(Locale.UK), f.toString());
+ }
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%e", 1001f);
+ /*
+ * fail on RI, spec says 'e' requires the output to be formatted in
+ * general scientific notation and the localization algorithm is
+ * applied. But RI format this case to 1.001000e+03, which does not
+ * conform to the German Locale
+ */
+ assertEquals("1,001000e+03", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for Float/Double
+ * conversion type 'g' and 'G'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionG() {
+ Formatter f = null;
+ final Object[][] tripleG = {
+ { 1001f, "%g", "1001.00" },
+ { 1001f, "%- (,9.8g", " 1,001.0000" },
+ { 1001f, "%+0(,8.4g", "+001,001" },
+ { 1001f, "%-+(,1.6g", "+1,001.00" },
+ { 1001f, "% 0(,12.0g", " 0000001e+03" },
+
+ { 1.f, "%g", "1.00000" },
+ { 1.f, "%- (,9.8g", " 1.0000000" },
+ { 1.f, "%+0(,8.4g", "+001.000" },
+ { 1.f, "%-+(,1.6g", "+1.00000" },
+ { 1.f, "% 0(,12.0g", " 00000000001" },
+
+ { -98f, "%g", "-98.0000" },
+ { -98f, "%- (,9.8g", "(98.000000)" },
+ { -98f, "%+0(,8.4g", "(098.00)" },
+ { -98f, "%-+(,1.6g", "(98.0000)" },
+ { -98f, "% 0(,12.0g", "(000001e+02)" },
+
+ { 0.000001f, "%g", "1.00000e-06" },
+ { 0.000001f, "%- (,9.8g", " 1.0000000e-06" },
+ { 0.000001f, "%+0(,8.4g", "+1.000e-06" },
+ { 0.000001f, "%-+(,1.6g", "+1.00000e-06" },
+ { 0.000001f, "% 0(,12.0g", " 0000001e-06" },
+
+ { 345.1234567f, "%g", "345.123" },
+ { 345.1234567f, "%- (,9.8g", " 345.12344" },
+ { 345.1234567f, "%+0(,8.4g", "+00345.1" },
+ { 345.1234567f, "%-+(,1.6g", "+345.123" },
+ { 345.1234567f, "% 0(,12.0g", " 0000003e+02" },
+
+ { -.00000012345f, "%g", "-1.23450e-07" },
+ { -.00000012345f, "%- (,9.8g", "(1.2344999e-07)" },
+ { -.00000012345f, "%+0(,8.4g", "(1.234e-07)" },
+ { -.00000012345f, "%-+(,1.6g", "(1.23450e-07)" },
+ { -.00000012345f, "% 0(,12.0g", "(000001e-07)" },
+
+ { -987.1234567f, "%g", "-987.123" },
+ { -987.1234567f, "%- (,9.8g", "(987.12347)" },
+ { -987.1234567f, "%+0(,8.4g", "(0987.1)" },
+ { -987.1234567f, "%-+(,1.6g", "(987.123)" },
+ { -987.1234567f, "% 0(,12.0g", "(000001e+03)" },
+
+ { Float.MAX_VALUE, "%g", "3.40282e+38" },
+ { Float.MAX_VALUE, "%- (,9.8g", " 3.4028235e+38" },
+ { Float.MAX_VALUE, "%+0(,8.4g", "+3.403e+38" },
+ { Float.MAX_VALUE, "%-+(,1.6g", "+3.40282e+38" },
+ { Float.MAX_VALUE, "% 0(,12.0g", " 0000003e+38" },
+
+ { Float.MIN_VALUE, "%g", "1.40130e-45" },
+ { Float.MIN_VALUE, "%- (,9.8g", " 1.4012985e-45" },
+ { Float.MIN_VALUE, "%+0(,8.4g", "+1.401e-45" },
+ { Float.MIN_VALUE, "%-+(,1.6g", "+1.40130e-45" },
+ { Float.MIN_VALUE, "% 0(,12.0g", " 0000001e-45" },
+
+ { Float.NaN, "%g", "NaN" },
+ { Float.NaN, "%- (,9.8g", "NaN " },
+ { Float.NaN, "%+0(,8.4g", " NaN" },
+ { Float.NaN, "%-+(,1.6g", "NaN" },
+ { Float.NaN, "% 0(,12.0g", " NaN" },
+
+ { Float.NEGATIVE_INFINITY, "%g", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%- (,9.8g", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "%+0(,8.4g", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "%-+(,1.6g", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "% 0(,12.0g", " (Infinity)" },
+
+ { Float.POSITIVE_INFINITY, "%g", "Infinity" },
+ { Float.POSITIVE_INFINITY, "%- (,9.8g", " Infinity" },
+ { Float.POSITIVE_INFINITY, "%+0(,8.4g", "+Infinity" },
+ { Float.POSITIVE_INFINITY, "%-+(,1.6g", "+Infinity" },
+ { Float.POSITIVE_INFINITY, "% 0(,12.0g", " Infinity" },
+
+ { 1d, "%g", "1.00000" },
+ { 1d, "%- (,9.8g", " 1.0000000" },
+ { 1d, "%+0(,8.4g", "+001.000" },
+ { 1d, "%-+(,1.6g", "+1.00000" },
+ { 1d, "% 0(,12.0g", " 00000000001" },
+
+ { -1d, "%g", "-1.00000" },
+ { -1d, "%- (,9.8g", "(1.0000000)" },
+ { -1d, "%+0(,8.4g", "(01.000)" },
+ { -1d, "%-+(,1.6g", "(1.00000)" },
+ { -1d, "% 0(,12.0g", "(0000000001)" },
+
+ { .00000001d, "%g", "1.00000e-08" },
+ { .00000001d, "%- (,9.8g", " 1.0000000e-08" },
+ { .00000001d, "%+0(,8.4g", "+1.000e-08" },
+ { .00000001d, "%-+(,1.6g", "+1.00000e-08" },
+ { .00000001d, "% 0(,12.0g", " 0000001e-08" },
+
+ { 1912.10d, "%g", "1912.10" },
+ { 1912.10d, "%- (,9.8g", " 1,912.1000" },
+ { 1912.10d, "%+0(,8.4g", "+001,912" },
+ { 1912.10d, "%-+(,1.6g", "+1,912.10" },
+ { 1912.10d, "% 0(,12.0g", " 0000002e+03" },
+
+ { 0.1d, "%g", "0.100000" },
+ { 0.1d, "%- (,9.8g", " 0.10000000" },
+ { 0.1d, "%+0(,8.4g", "+00.1000" },
+ { 0.1d, "%-+(,1.6g", "+0.100000" },
+ { 0.1d, "% 0(,12.0g", " 000000000.1" },
+
+ { -2.d, "%g", "-2.00000" },
+ { -2.d, "%- (,9.8g", "(2.0000000)" },
+ { -2.d, "%+0(,8.4g", "(02.000)" },
+ { -2.d, "%-+(,1.6g", "(2.00000)" },
+ { -2.d, "% 0(,12.0g", "(0000000002)" },
+
+ { -.00039d, "%g", "-0.000390000" },
+ { -.00039d, "%- (,9.8g", "(0.00039000000)" },
+ { -.00039d, "%+0(,8.4g", "(0.0003900)" },
+ { -.00039d, "%-+(,1.6g", "(0.000390000)" },
+ { -.00039d, "% 0(,12.0g", "(00000.0004)" },
+
+ { -1234567890.012345678d, "%g", "-1.23457e+09" },
+ { -1234567890.012345678d, "%- (,9.8g", "(1.2345679e+09)" },
+ { -1234567890.012345678d, "%+0(,8.4g", "(1.235e+09)" },
+ { -1234567890.012345678d, "%-+(,1.6g", "(1.23457e+09)" },
+ { -1234567890.012345678d, "% 0(,12.0g", "(000001e+09)" },
+
+ { Double.MAX_VALUE, "%g", "1.79769e+308" },
+ { Double.MAX_VALUE, "%- (,9.8g", " 1.7976931e+308" },
+ { Double.MAX_VALUE, "%+0(,8.4g", "+1.798e+308" },
+ { Double.MAX_VALUE, "%-+(,1.6g", "+1.79769e+308" },
+ { Double.MAX_VALUE, "% 0(,12.0g", " 000002e+308" },
+
+ { Double.MIN_VALUE, "%g", "4.90000e-324" },
+ { Double.MIN_VALUE, "%- (,9.8g", " 4.9000000e-324" },
+ { Double.MIN_VALUE, "%+0(,8.4g", "+4.900e-324" },
+ { Double.MIN_VALUE, "%-+(,1.6g", "+4.90000e-324" },
+ { Double.MIN_VALUE, "% 0(,12.0g", " 000005e-324" },
+
+ { Double.NaN, "%g", "NaN" },
+ { Double.NaN, "%- (,9.8g", "NaN " },
+ { Double.NaN, "%+0(,8.4g", " NaN" },
+ { Double.NaN, "%-+(,1.6g", "NaN" },
+ { Double.NaN, "% 0(,12.0g", " NaN" },
+
+ { Double.NEGATIVE_INFINITY, "%g", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%- (,9.8g", "(Infinity)" },
+ { Double.NEGATIVE_INFINITY, "%+0(,8.4g", "(Infinity)" },
+ { Double.NEGATIVE_INFINITY, "%-+(,1.6g", "(Infinity)" },
+ { Double.NEGATIVE_INFINITY, "% 0(,12.0g", " (Infinity)" },
+
+ { Double.POSITIVE_INFINITY, "%g", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%- (,9.8g", " Infinity" },
+ { Double.POSITIVE_INFINITY, "%+0(,8.4g", "+Infinity" },
+ { Double.POSITIVE_INFINITY, "%-+(,1.6g", "+Infinity" },
+ { Double.POSITIVE_INFINITY, "% 0(,12.0g", " Infinity" },
+
+ };
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ for (int i = 0; i < tripleG.length; i++) {
+
+ f = new Formatter(Locale.US);
+ f.format((String) tripleG[i][pattern], tripleG[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
+ + i + "]:" + tripleG[i][pattern],
+ tripleG[i][output], f.toString());
+
+ // test for conversion type 'G'
+ f = new Formatter(Locale.US);
+ f.format(((String) tripleG[i][pattern]).toUpperCase(), tripleG[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
+ + i + "]:" + tripleG[i][pattern], ((String) tripleG[i][output])
+ .toUpperCase(Locale.UK), f.toString());
+ }
+
+ f = new Formatter(Locale.US);
+ f.format("%.5g", 0f);
+ assertEquals("0.0000", f.toString());
+
+ f = new Formatter(Locale.US);
+ f.format("%.0g", 0f);
+ /*
+ * fail on RI, spec says if the precision is 0, then it is taken to be
+ * 1. but RI throws ArrayIndexOutOfBoundsException.
+ */
+ assertEquals("0", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%g", 1001f);
+ /*
+ * fail on RI, spec says 'g' requires the output to be formatted in
+ * general scientific notation and the localization algorithm is
+ * applied. But RI format this case to 1001.00, which does not conform
+ * to the German Locale
+ */
+ assertEquals("1001,00", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for Float/Double
+ * conversion type 'g' and 'G' overflow
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionG_Overflow() {
+ Formatter f = new Formatter();
+ f.format("%g", 999999.5);
+ assertEquals("1.00000e+06", f.toString());
+
+ f = new Formatter();
+ f.format("%g", 99999.5);
+ assertEquals("99999.5", f.toString());
+
+ f = new Formatter();
+ f.format("%.4g", 99.95);
+ assertEquals("99.95", f.toString());
+
+ f = new Formatter();
+ f.format("%g", 99.95);
+ assertEquals("99.9500", f.toString());
+
+ f = new Formatter();
+ f.format("%g", 0.9);
+ assertEquals("0.900000", f.toString());
+
+ f = new Formatter();
+ f.format("%.0g", 0.000095);
+ assertEquals("0.0001", f.toString());
+
+ f = new Formatter();
+ f.format("%g", 0.0999999);
+ assertEquals("0.0999999", f.toString());
+
+ f = new Formatter();
+ f.format("%g", 0.00009);
+ assertEquals("9.00000e-05", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for Float/Double
+ * conversion type 'f'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionF() {
+ Formatter f = null;
+
+ final Object[][] tripleF = {
+ { 0f, "%f", "0,000000" },
+ { 0f, "%#.3f", "0,000" },
+ { 0f, "%,5f", "0,000000" },
+ { 0f, "%- (12.0f", " 0 " },
+ { 0f, "%#+0(1.6f", "+0,000000" },
+ { 0f, "%-+(8.4f", "+0,0000 " },
+ { 0f, "% 0#(9.8f", " 0,00000000" },
+
+ { 1234f, "%f", "1234,000000" },
+ { 1234f, "%#.3f", "1234,000" },
+ { 1234f, "%,5f", "1.234,000000" },
+ { 1234f, "%- (12.0f", " 1234 " },
+ { 1234f, "%#+0(1.6f", "+1234,000000" },
+ { 1234f, "%-+(8.4f", "+1234,0000" },
+ { 1234f, "% 0#(9.8f", " 1234,00000000" },
+
+ { 1.f, "%f", "1,000000" },
+ { 1.f, "%#.3f", "1,000" },
+ { 1.f, "%,5f", "1,000000" },
+ { 1.f, "%- (12.0f", " 1 " },
+ { 1.f, "%#+0(1.6f", "+1,000000" },
+ { 1.f, "%-+(8.4f", "+1,0000 " },
+ { 1.f, "% 0#(9.8f", " 1,00000000" },
+
+ { -98f, "%f", "-98,000000" },
+ { -98f, "%#.3f", "-98,000" },
+ { -98f, "%,5f", "-98,000000" },
+ { -98f, "%- (12.0f", "(98) " },
+ { -98f, "%#+0(1.6f", "(98,000000)" },
+ { -98f, "%-+(8.4f", "(98,0000)" },
+ { -98f, "% 0#(9.8f", "(98,00000000)" },
+
+ { 0.000001f, "%f", "0,000001" },
+ { 0.000001f, "%#.3f", "0,000" },
+ { 0.000001f, "%,5f", "0,000001" },
+ { 0.000001f, "%- (12.0f", " 0 " },
+ { 0.000001f, "%#+0(1.6f", "+0,000001" },
+ { 0.000001f, "%-+(8.4f", "+0,0000 " },
+ { 0.000001f, "% 0#(9.8f", " 0,00000100" },
+
+ { 345.1234567f, "%f", "345,123444" },
+ { 345.1234567f, "%#.3f", "345,123" },
+ { 345.1234567f, "%,5f", "345,123444" },
+ { 345.1234567f, "%- (12.0f", " 345 " },
+ { 345.1234567f, "%#+0(1.6f", "+345,123444" },
+ { 345.1234567f, "%-+(8.4f", "+345,1234" },
+ { 345.1234567f, "% 0#(9.8f", " 345,12344360" },
+
+ { -.00000012345f, "%f", "-0,000000" },
+ { -.00000012345f, "%#.3f", "-0,000" },
+ { -.00000012345f, "%,5f", "-0,000000" },
+ { -.00000012345f, "%- (12.0f", "(0) " },
+ { -.00000012345f, "%#+0(1.6f", "(0,000000)" },
+ { -.00000012345f, "%-+(8.4f", "(0,0000)" },
+ { -.00000012345f, "% 0#(9.8f", "(0,00000012)" },
+
+ { -987654321.1234567f, "%f", "-987654336,000000" },
+ { -987654321.1234567f, "%#.3f", "-987654336,000" },
+ { -987654321.1234567f, "%,5f", "-987.654.336,000000" },
+ { -987654321.1234567f, "%- (12.0f", "(987654336) " },
+ { -987654321.1234567f, "%#+0(1.6f", "(987654336,000000)" },
+ { -987654321.1234567f, "%-+(8.4f", "(987654336,0000)" },
+ { -987654321.1234567f, "% 0#(9.8f", "(987654336,00000000)" },
+
+ { Float.MAX_VALUE, "%f", "340282346638528860000000000000000000000,000000" },
+ { Float.MAX_VALUE, "%#.3f", "340282346638528860000000000000000000000,000" },
+ { Float.MAX_VALUE, "%,5f", "340.282.346.638.528.860.000.000.000.000.000.000.000,000000" },
+ { Float.MAX_VALUE, "%- (12.0f", " 340282346638528860000000000000000000000" },
+ { Float.MAX_VALUE, "%#+0(1.6f", "+340282346638528860000000000000000000000,000000" },
+ { Float.MAX_VALUE, "%-+(8.4f", "+340282346638528860000000000000000000000,0000" },
+ { Float.MAX_VALUE, "% 0#(9.8f", " 340282346638528860000000000000000000000,00000000" },
+
+ { Float.MIN_VALUE, "%f", "0,000000" },
+ { Float.MIN_VALUE, "%#.3f", "0,000" },
+ { Float.MIN_VALUE, "%,5f", "0,000000" },
+ { Float.MIN_VALUE, "%- (12.0f", " 0 " },
+ { Float.MIN_VALUE, "%#+0(1.6f", "+0,000000" },
+ { Float.MIN_VALUE, "%-+(8.4f", "+0,0000 " },
+ { Float.MIN_VALUE, "% 0#(9.8f", " 0,00000000" },
+
+ { Float.NaN, "%f", "NaN" },
+ { Float.NaN, "%#.3f", "NaN" },
+ { Float.NaN, "%,5f", " NaN" },
+ { Float.NaN, "%- (12.0f", "NaN " },
+ { Float.NaN, "%#+0(1.6f", "NaN" },
+ { Float.NaN, "%-+(8.4f", "NaN " },
+ { Float.NaN, "% 0#(9.8f", " NaN" },
+
+ { Float.NEGATIVE_INFINITY, "%f", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%#.3f", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%,5f", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%- (12.0f", "(Infinity) " },
+ { Float.NEGATIVE_INFINITY, "%#+0(1.6f", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "%-+(8.4f", "(Infinity)" },
+ { Float.NEGATIVE_INFINITY, "% 0#(9.8f", "(Infinity)" },
+
+ { Float.POSITIVE_INFINITY, "%f", "Infinity" },
+ { Float.POSITIVE_INFINITY, "%#.3f", "Infinity" },
+ { Float.POSITIVE_INFINITY, "%,5f", "Infinity" },
+ { Float.POSITIVE_INFINITY, "%- (12.0f", " Infinity " },
+ { Float.POSITIVE_INFINITY, "%#+0(1.6f", "+Infinity" },
+ { Float.POSITIVE_INFINITY, "%-+(8.4f", "+Infinity" },
+ { Float.POSITIVE_INFINITY, "% 0#(9.8f", " Infinity" },
+
+
+ { 0d, "%f", "0,000000" },
+ { 0d, "%#.3f", "0,000" },
+ { 0d, "%,5f", "0,000000" },
+ { 0d, "%- (12.0f", " 0 " },
+ { 0d, "%#+0(1.6f", "+0,000000" },
+ { 0d, "%-+(8.4f", "+0,0000 " },
+ { 0d, "% 0#(9.8f", " 0,00000000" },
+
+ { 1d, "%f", "1,000000" },
+ { 1d, "%#.3f", "1,000" },
+ { 1d, "%,5f", "1,000000" },
+ { 1d, "%- (12.0f", " 1 " },
+ { 1d, "%#+0(1.6f", "+1,000000" },
+ { 1d, "%-+(8.4f", "+1,0000 " },
+ { 1d, "% 0#(9.8f", " 1,00000000" },
+
+ { -1d, "%f", "-1,000000" },
+ { -1d, "%#.3f", "-1,000" },
+ { -1d, "%,5f", "-1,000000" },
+ { -1d, "%- (12.0f", "(1) " },
+ { -1d, "%#+0(1.6f", "(1,000000)" },
+ { -1d, "%-+(8.4f", "(1,0000)" },
+ { -1d, "% 0#(9.8f", "(1,00000000)" },
+
+ { .00000001d, "%f", "0,000000" },
+ { .00000001d, "%#.3f", "0,000" },
+ { .00000001d, "%,5f", "0,000000" },
+ { .00000001d, "%- (12.0f", " 0 " },
+ { .00000001d, "%#+0(1.6f", "+0,000000" },
+ { .00000001d, "%-+(8.4f", "+0,0000 " },
+ { .00000001d, "% 0#(9.8f", " 0,00000001" },
+
+ { 1000.10d, "%f", "1000,100000" },
+ { 1000.10d, "%#.3f", "1000,100" },
+ { 1000.10d, "%,5f", "1.000,100000" },
+ { 1000.10d, "%- (12.0f", " 1000 " },
+ { 1000.10d, "%#+0(1.6f", "+1000,100000" },
+ { 1000.10d, "%-+(8.4f", "+1000,1000" },
+ { 1000.10d, "% 0#(9.8f", " 1000,10000000" },
+
+ { 0.1d, "%f", "0,100000" },
+ { 0.1d, "%#.3f", "0,100" },
+ { 0.1d, "%,5f", "0,100000" },
+ { 0.1d, "%- (12.0f", " 0 " },
+ { 0.1d, "%#+0(1.6f", "+0,100000" },
+ { 0.1d, "%-+(8.4f", "+0,1000 " },
+ { 0.1d, "% 0#(9.8f", " 0,10000000" },
+
+ { -2.d, "%f", "-2,000000" },
+ { -2.d, "%#.3f", "-2,000" },
+ { -2.d, "%,5f", "-2,000000" },
+ { -2.d, "%- (12.0f", "(2) " },
+ { -2.d, "%#+0(1.6f", "(2,000000)" },
+ { -2.d, "%-+(8.4f", "(2,0000)" },
+ { -2.d, "% 0#(9.8f", "(2,00000000)" },
+
+ { -.00009d, "%f", "-0,000090" },
+ { -.00009d, "%#.3f", "-0,000" },
+ { -.00009d, "%,5f", "-0,000090" },
+ { -.00009d, "%- (12.0f", "(0) " },
+ { -.00009d, "%#+0(1.6f", "(0,000090)" },
+ { -.00009d, "%-+(8.4f", "(0,0001)" },
+ { -.00009d, "% 0#(9.8f", "(0,00009000)" },
+
+ { -1234567890.012345678d, "%f", "-1234567890,012346" },
+ { -1234567890.012345678d, "%#.3f", "-1234567890,012" },
+ { -1234567890.012345678d, "%,5f", "-1.234.567.890,012346" },
+ { -1234567890.012345678d, "%- (12.0f", "(1234567890)" },
+ { -1234567890.012345678d, "%#+0(1.6f", "(1234567890,012346)" },
+ { -1234567890.012345678d, "%-+(8.4f", "(1234567890,0123)" },
+ { -1234567890.012345678d, "% 0#(9.8f", "(1234567890,01234580)" },
+
+ { Double.MAX_VALUE, "%f", "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000000" },
+ { Double.MAX_VALUE, "%#.3f", "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000" },
+ { Double.MAX_VALUE, "%,5f", "179.769.313.486.231.570.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,000000" },
+ { Double.MAX_VALUE, "%- (12.0f", " 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" },
+ { Double.MAX_VALUE, "%#+0(1.6f", "+179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000000" },
+ { Double.MAX_VALUE, "%-+(8.4f", "+179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0000" },
+ { Double.MAX_VALUE, "% 0#(9.8f", " 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,00000000" },
+
+ { Double.MIN_VALUE, "%f", "0,000000" },
+ { Double.MIN_VALUE, "%#.3f", "0,000" },
+ { Double.MIN_VALUE, "%,5f", "0,000000" },
+ { Double.MIN_VALUE, "%- (12.0f", " 0 " },
+ { Double.MIN_VALUE, "%#+0(1.6f", "+0,000000" },
+ { Double.MIN_VALUE, "%-+(8.4f", "+0,0000 " },
+ { Double.MIN_VALUE, "% 0#(9.8f", " 0,00000000" },
+
+ { Double.NaN, "%f", "NaN" },
+ { Double.NaN, "%#.3f", "NaN" },
+ { Double.NaN, "%,5f", " NaN" },
+ { Double.NaN, "%- (12.0f", "NaN " },
+ { Double.NaN, "%#+0(1.6f", "NaN" },
+ { Double.NaN, "%-+(8.4f", "NaN " },
+ { Double.NaN, "% 0#(9.8f", " NaN" },
+
+ { Double.POSITIVE_INFINITY, "%f", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%#.3f", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%,5f", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%- (12.0f", " Infinity " },
+ { Double.POSITIVE_INFINITY, "%#+0(1.6f", "+Infinity" },
+ { Double.POSITIVE_INFINITY, "%-+(8.4f", "+Infinity" },
+ { Double.POSITIVE_INFINITY, "% 0#(9.8f", " Infinity" },
+
+ { Double.NEGATIVE_INFINITY, "%f", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%#.3f", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%,5f", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%- (12.0f", "(Infinity) " },
+ { Double.NEGATIVE_INFINITY, "%#+0(1.6f", "(Infinity)" },
+ { Double.NEGATIVE_INFINITY, "%-+(8.4f", "(Infinity)" },
+ { Double.NEGATIVE_INFINITY, "% 0#(9.8f", "(Infinity)" },
+ };
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ for (int i = 0; i < tripleF.length; i++) {
+ f = new Formatter(Locale.GERMAN);
+ f.format((String) tripleF[i][pattern], tripleF[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleF[i][input] + ",pattern["
+ + i + "]:" + tripleF[i][pattern],
+ tripleF[i][output], f.toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for Float/Double
+ * conversion type 'a' and 'A'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionA() {
+ Formatter f = null;
+ final Object[][] tripleA = {
+ { -0f, "%a", "-0x0.0p0" },
+ { -0f, "%#.3a", "-0x0.000p0" },
+ { -0f, "%5a", "-0x0.0p0" },
+ { -0f, "%- 12.0a", "-0x0.0p0 " },
+ { -0f, "%#+01.6a", "-0x0.000000p0" },
+ { -0f, "%-+8.4a", "-0x0.0000p0" },
+
+ { 0f, "%a", "0x0.0p0" },
+ { 0f, "%#.3a", "0x0.000p0" },
+ { 0f, "%5a", "0x0.0p0" },
+ { 0f, "%- 12.0a", " 0x0.0p0 " },
+ { 0f, "%#+01.6a", "+0x0.000000p0" },
+ { 0f, "%-+8.4a", "+0x0.0000p0" },
+
+ { 1234f, "%a", "0x1.348p10" },
+ { 1234f, "%#.3a", "0x1.348p10" },
+ { 1234f, "%5a", "0x1.348p10" },
+ { 1234f, "%- 12.0a", " 0x1.3p10 " },
+ { 1234f, "%#+01.6a", "+0x1.348000p10" },
+ { 1234f, "%-+8.4a", "+0x1.3480p10" },
+
+ { 1.f, "%a", "0x1.0p0" },
+ { 1.f, "%#.3a", "0x1.000p0" },
+ { 1.f, "%5a", "0x1.0p0" },
+ { 1.f, "%- 12.0a", " 0x1.0p0 " },
+ { 1.f, "%#+01.6a", "+0x1.000000p0" },
+ { 1.f, "%-+8.4a", "+0x1.0000p0" },
+
+ { -98f, "%a", "-0x1.88p6" },
+ { -98f, "%#.3a", "-0x1.880p6" },
+ { -98f, "%5a", "-0x1.88p6" },
+ { -98f, "%- 12.0a", "-0x1.8p6 " },
+ { -98f, "%#+01.6a", "-0x1.880000p6" },
+ { -98f, "%-+8.4a", "-0x1.8800p6" },
+
+ { 345.1234567f, "%a", "0x1.591f9ap8" },
+ { 345.1234567f, "%5a", "0x1.591f9ap8" },
+ { 345.1234567f, "%#+01.6a", "+0x1.591f9ap8" },
+
+ { -987654321.1234567f, "%a", "-0x1.d6f346p29" },
+ { -987654321.1234567f, "%#.3a", "-0x1.d6fp29" },
+ { -987654321.1234567f, "%5a", "-0x1.d6f346p29" },
+ { -987654321.1234567f, "%- 12.0a", "-0x1.dp29 " },
+ { -987654321.1234567f, "%#+01.6a", "-0x1.d6f346p29" },
+ { -987654321.1234567f, "%-+8.4a", "-0x1.d6f3p29" },
+
+ { Float.MAX_VALUE, "%a", "0x1.fffffep127" },
+ { Float.MAX_VALUE, "%5a", "0x1.fffffep127" },
+ { Float.MAX_VALUE, "%#+01.6a", "+0x1.fffffep127" },
+
+ { Float.NaN, "%a", "NaN" },
+ { Float.NaN, "%#.3a", "NaN" },
+ { Float.NaN, "%5a", " NaN" },
+ { Float.NaN, "%- 12.0a", "NaN " },
+ { Float.NaN, "%#+01.6a", "NaN" },
+ { Float.NaN, "%-+8.4a", "NaN " },
+
+ { Float.NEGATIVE_INFINITY, "%a", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%#.3a", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%5a", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%- 12.0a", "-Infinity " },
+ { Float.NEGATIVE_INFINITY, "%#+01.6a", "-Infinity" },
+ { Float.NEGATIVE_INFINITY, "%-+8.4a", "-Infinity" },
+
+ { Float.POSITIVE_INFINITY, "%a", "Infinity" },
+ { Float.POSITIVE_INFINITY, "%#.3a", "Infinity" },
+ { Float.POSITIVE_INFINITY, "%5a", "Infinity" },
+ { Float.POSITIVE_INFINITY, "%- 12.0a", " Infinity " },
+ { Float.POSITIVE_INFINITY, "%#+01.6a", "+Infinity" },
+ { Float.POSITIVE_INFINITY, "%-+8.4a", "+Infinity" },
+
+ { -0d, "%a", "-0x0.0p0" },
+ { -0d, "%#.3a", "-0x0.000p0" },
+ { -0d, "%5a", "-0x0.0p0" },
+ { -0d, "%- 12.0a", "-0x0.0p0 " },
+ { -0d, "%#+01.6a", "-0x0.000000p0" },
+ { -0d, "%-+8.4a", "-0x0.0000p0" },
+
+ { 0d, "%a", "0x0.0p0" },
+ { 0d, "%#.3a", "0x0.000p0" },
+ { 0d, "%5a", "0x0.0p0" },
+ { 0d, "%- 12.0a", " 0x0.0p0 " },
+ { 0d, "%#+01.6a", "+0x0.000000p0" },
+ { 0d, "%-+8.4a", "+0x0.0000p0" },
+
+ { 1d, "%a", "0x1.0p0" },
+ { 1d, "%#.3a", "0x1.000p0" },
+ { 1d, "%5a", "0x1.0p0" },
+ { 1d, "%- 12.0a", " 0x1.0p0 " },
+ { 1d, "%#+01.6a", "+0x1.000000p0" },
+ { 1d, "%-+8.4a", "+0x1.0000p0" },
+
+ { -1d, "%a", "-0x1.0p0" },
+ { -1d, "%#.3a", "-0x1.000p0" },
+ { -1d, "%5a", "-0x1.0p0" },
+ { -1d, "%- 12.0a", "-0x1.0p0 " },
+ { -1d, "%#+01.6a", "-0x1.000000p0" },
+ { -1d, "%-+8.4a", "-0x1.0000p0" },
+
+ { .00000001d, "%a", "0x1.5798ee2308c3ap-27" },
+ { .00000001d, "%5a", "0x1.5798ee2308c3ap-27" },
+ { .00000001d, "%- 12.0a", " 0x1.5p-27 " },
+ { .00000001d, "%#+01.6a", "+0x1.5798eep-27" },
+
+ { 1000.10d, "%a", "0x1.f40cccccccccdp9" },
+ { 1000.10d, "%5a", "0x1.f40cccccccccdp9" },
+ { 1000.10d, "%- 12.0a", " 0x1.fp9 " },
+
+ { 0.1d, "%a", "0x1.999999999999ap-4" },
+ { 0.1d, "%5a", "0x1.999999999999ap-4" },
+
+ { -2.d, "%a", "-0x1.0p1" },
+ { -2.d, "%#.3a", "-0x1.000p1" },
+ { -2.d, "%5a", "-0x1.0p1" },
+ { -2.d, "%- 12.0a", "-0x1.0p1 " },
+ { -2.d, "%#+01.6a", "-0x1.000000p1" },
+ { -2.d, "%-+8.4a", "-0x1.0000p1" },
+
+ { -.00009d, "%a", "-0x1.797cc39ffd60fp-14" },
+ { -.00009d, "%5a", "-0x1.797cc39ffd60fp-14" },
+
+ { -1234567890.012345678d, "%a", "-0x1.26580b480ca46p30" },
+ { -1234567890.012345678d, "%5a", "-0x1.26580b480ca46p30" },
+ { -1234567890.012345678d, "%- 12.0a", "-0x1.2p30 " },
+ { -1234567890.012345678d, "%#+01.6a", "-0x1.26580bp30" },
+ { -1234567890.012345678d, "%-+8.4a", "-0x1.2658p30" },
+
+ { Double.MAX_VALUE, "%a", "0x1.fffffffffffffp1023" },
+ { Double.MAX_VALUE, "%5a", "0x1.fffffffffffffp1023" },
+
+ { Double.MIN_VALUE, "%a", "0x0.0000000000001p-1022" },
+ { Double.MIN_VALUE, "%5a", "0x0.0000000000001p-1022" },
+
+ { Double.NaN, "%a", "NaN" },
+ { Double.NaN, "%#.3a", "NaN" },
+ { Double.NaN, "%5a", " NaN" },
+ { Double.NaN, "%- 12.0a", "NaN " },
+ { Double.NaN, "%#+01.6a", "NaN" },
+ { Double.NaN, "%-+8.4a", "NaN " },
+
+ { Double.NEGATIVE_INFINITY, "%a", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%#.3a", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%5a", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%- 12.0a", "-Infinity " },
+ { Double.NEGATIVE_INFINITY, "%#+01.6a", "-Infinity" },
+ { Double.NEGATIVE_INFINITY, "%-+8.4a", "-Infinity" },
+
+ { Double.POSITIVE_INFINITY, "%a", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%#.3a", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%5a", "Infinity" },
+ { Double.POSITIVE_INFINITY, "%- 12.0a", " Infinity " },
+ { Double.POSITIVE_INFINITY, "%#+01.6a", "+Infinity" },
+ { Double.POSITIVE_INFINITY, "%-+8.4a", "+Infinity" },
+
+ };
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ for (int i = 0; i < tripleA.length; i++) {
+ f = new Formatter(Locale.UK);
+ f.format((String) tripleA[i][pattern], tripleA[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleA[i][input] + ",pattern["
+ + i + "]:" + tripleA[i][pattern],
+ tripleA[i][output], f.toString());
+
+ // test for conversion type 'A'
+ f = new Formatter(Locale.UK);
+ f.format(((String) tripleA[i][pattern]).toUpperCase(), tripleA[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleA[i][input] + ",pattern["
+ + i + "]:" + tripleA[i][pattern], ((String) tripleA[i][output])
+ .toUpperCase(Locale.UK), f.toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for BigDecimal
+ * conversion type 'e' and 'E'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionE() {
+ Formatter f = null;
+ final Object[][] tripleE = {
+ { BigDecimal.ZERO, "%e", "0.000000e+00" },
+ { BigDecimal.ZERO, "%#.0e", "0.e+00" },
+ { BigDecimal.ZERO, "%# 9.8e", " 0.00000000e+00" },
+ { BigDecimal.ZERO, "%#+0(8.4e", "+0.0000e+00" },
+ { BigDecimal.ZERO, "%-+17.6e", "+0.000000e+00 " },
+ { BigDecimal.ZERO, "% 0(20e", " 00000000.000000e+00" },
+
+ { BigDecimal.ONE, "%e", "1.000000e+00" },
+ { BigDecimal.ONE, "%#.0e", "1.e+00" },
+ { BigDecimal.ONE, "%# 9.8e", " 1.00000000e+00" },
+ { BigDecimal.ONE, "%#+0(8.4e", "+1.0000e+00" },
+ { BigDecimal.ONE, "%-+17.6e", "+1.000000e+00 " },
+ { BigDecimal.ONE, "% 0(20e", " 00000001.000000e+00" },
+
+ { BigDecimal.TEN, "%e", "1.000000e+01" },
+ { BigDecimal.TEN, "%#.0e", "1.e+01" },
+ { BigDecimal.TEN, "%# 9.8e", " 1.00000000e+01" },
+ { BigDecimal.TEN, "%#+0(8.4e", "+1.0000e+01" },
+ { BigDecimal.TEN, "%-+17.6e", "+1.000000e+01 " },
+ { BigDecimal.TEN, "% 0(20e", " 00000001.000000e+01" },
+
+ { new BigDecimal(-1), "%e", "-1.000000e+00" },
+ { new BigDecimal(-1), "%#.0e", "-1.e+00" },
+ { new BigDecimal(-1), "%# 9.8e", "-1.00000000e+00" },
+ { new BigDecimal(-1), "%#+0(8.4e", "(1.0000e+00)" },
+ { new BigDecimal(-1), "%-+17.6e", "-1.000000e+00 " },
+ { new BigDecimal(-1), "% 0(20e", "(0000001.000000e+00)" },
+
+ { new BigDecimal("5.000E999"), "%e", "5.000000e+999" },
+ { new BigDecimal("5.000E999"), "%#.0e", "5.e+999" },
+ { new BigDecimal("5.000E999"), "%# 9.8e", " 5.00000000e+999" },
+ { new BigDecimal("5.000E999"), "%#+0(8.4e", "+5.0000e+999" },
+ { new BigDecimal("5.000E999"), "%-+17.6e", "+5.000000e+999 " },
+ { new BigDecimal("5.000E999"), "% 0(20e", " 0000005.000000e+999" },
+
+ { new BigDecimal("-5.000E999"), "%e", "-5.000000e+999" },
+ { new BigDecimal("-5.000E999"), "%#.0e", "-5.e+999" },
+ { new BigDecimal("-5.000E999"), "%# 9.8e", "-5.00000000e+999" },
+ { new BigDecimal("-5.000E999"), "%#+0(8.4e", "(5.0000e+999)" },
+ { new BigDecimal("-5.000E999"), "%-+17.6e", "-5.000000e+999 " },
+ { new BigDecimal("-5.000E999"), "% 0(20e", "(000005.000000e+999)" },
+ };
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ for (int i = 0; i < tripleE.length; i++) {
+ f = new Formatter(Locale.US);
+ f.format((String) tripleE[i][pattern], tripleE[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
+ + i + "]:" + tripleE[i][pattern],
+ tripleE[i][output], f.toString());
+
+ // test for conversion type 'E'
+ f = new Formatter(Locale.US);
+ f.format(((String) tripleE[i][pattern]).toUpperCase(), tripleE[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
+ + i + "]:" + tripleE[i][pattern], ((String) tripleE[i][output])
+ .toUpperCase(Locale.US), f.toString());
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for BigDecimal
+ * conversion type 'g' and 'G'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionG() {
+ Formatter f = null;
+ final Object[][] tripleG = {
+ { BigDecimal.ZERO, "%g", "0.00000" },
+ { BigDecimal.ZERO, "%.5g", "0.0000" },
+ { BigDecimal.ZERO, "%- (,9.8g", " 0.0000000" },
+ { BigDecimal.ZERO, "%+0(,8.4g", "+000.000" },
+ { BigDecimal.ZERO, "%-+10.6g", "+0.00000 " },
+ { BigDecimal.ZERO, "% 0(,12.0g", " 00000000000" },
+ { BigDecimal.ONE, "%g", "1.00000" },
+ { BigDecimal.ONE, "%.5g", "1.0000" },
+ { BigDecimal.ONE, "%- (,9.8g", " 1.0000000" },
+ { BigDecimal.ONE, "%+0(,8.4g", "+001.000" },
+ { BigDecimal.ONE, "%-+10.6g", "+1.00000 " },
+ { BigDecimal.ONE, "% 0(,12.0g", " 00000000001" },
+
+ { new BigDecimal(-1), "%g", "-1.00000" },
+ { new BigDecimal(-1), "%.5g", "-1.0000" },
+ { new BigDecimal(-1), "%- (,9.8g", "(1.0000000)" },
+ { new BigDecimal(-1), "%+0(,8.4g", "(01.000)" },
+ { new BigDecimal(-1), "%-+10.6g", "-1.00000 " },
+ { new BigDecimal(-1), "% 0(,12.0g", "(0000000001)" },
+
+ { new BigDecimal(-0.000001), "%g", "-1.00000e-06" },
+ { new BigDecimal(-0.000001), "%.5g", "-1.0000e-06" },
+ { new BigDecimal(-0.000001), "%- (,9.8g", "(1.0000000e-06)" },
+ { new BigDecimal(-0.000001), "%+0(,8.4g", "(1.000e-06)" },
+ { new BigDecimal(-0.000001), "%-+10.6g", "-1.00000e-06" },
+ { new BigDecimal(-0.000001), "% 0(,12.0g", "(000001e-06)" },
+
+ { new BigDecimal(0.0002), "%g", "0.000200000" },
+ { new BigDecimal(0.0002), "%.5g", "0.00020000" },
+ { new BigDecimal(0.0002), "%- (,9.8g", " 0.00020000000" },
+ { new BigDecimal(0.0002), "%+0(,8.4g", "+0.0002000" },
+ { new BigDecimal(0.0002), "%-+10.6g", "+0.000200000" },
+ { new BigDecimal(0.0002), "% 0(,12.0g", " 000000.0002" },
+
+ { new BigDecimal(-0.003), "%g", "-0.00300000" },
+ { new BigDecimal(-0.003), "%.5g", "-0.0030000" },
+ { new BigDecimal(-0.003), "%- (,9.8g", "(0.0030000000)" },
+ { new BigDecimal(-0.003), "%+0(,8.4g", "(0.003000)" },
+ { new BigDecimal(-0.003), "%-+10.6g", "-0.00300000" },
+ { new BigDecimal(-0.003), "% 0(,12.0g", "(000000.003)" },
+
+ { new BigDecimal("5.000E999"), "%g", "5.00000e+999" },
+ { new BigDecimal("5.000E999"), "%.5g", "5.0000e+999" },
+ { new BigDecimal("5.000E999"), "%- (,9.8g", " 5.0000000e+999" },
+ { new BigDecimal("5.000E999"), "%+0(,8.4g", "+5.000e+999" },
+ { new BigDecimal("5.000E999"), "%-+10.6g", "+5.00000e+999" },
+ { new BigDecimal("5.000E999"), "% 0(,12.0g", " 000005e+999" },
+
+ { new BigDecimal("-5.000E999"), "%g", "-5.00000e+999" },
+ { new BigDecimal("-5.000E999"), "%.5g", "-5.0000e+999" },
+ { new BigDecimal("-5.000E999"), "%- (,9.8g", "(5.0000000e+999)" },
+ { new BigDecimal("-5.000E999"), "%+0(,8.4g", "(5.000e+999)" },
+ { new BigDecimal("-5.000E999"), "%-+10.6g", "-5.00000e+999" },
+ { new BigDecimal("-5.000E999"), "% 0(,12.0g", "(00005e+999)" },
+ };
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ for (int i = 0; i < tripleG.length; i++) {
+ f = new Formatter(Locale.US);
+ f.format((String) tripleG[i][pattern], tripleG[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
+ + i + "]:" + tripleG[i][pattern],
+ tripleG[i][output], f.toString());
+
+ // test for conversion type 'G'
+ f = new Formatter(Locale.US);
+ f.format(((String) tripleG[i][pattern]).toUpperCase(), tripleG[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
+ + i + "]:" + tripleG[i][pattern], ((String) tripleG[i][output])
+ .toUpperCase(Locale.US), f.toString());
+ }
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%- (,9.6g", new BigDecimal("4E6"));
+ /*
+ * fail on RI, spec says 'g' requires the output to be formatted in
+ * general scientific notation and the localization algorithm is
+ * applied. But RI format this case to 4.00000e+06, which does not
+ * conform to the German Locale
+ */
+ assertEquals(" 4,00000e+06", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for BigDecimal
+ * conversion type 'f'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionF() {
+
+ Formatter f = null;
+ final int input = 0;
+ final int pattern = 1;
+ final int output = 2;
+ final Object[][] tripleF = {
+ { BigDecimal.ZERO, "%f", "0.000000" },
+ { BigDecimal.ZERO, "%#.3f", "0.000" },
+ { BigDecimal.ZERO, "%#,5f", "0.000000" },
+ { BigDecimal.ZERO, "%- #(12.0f", " 0. " },
+ { BigDecimal.ZERO, "%#+0(1.6f", "+0.000000" },
+ { BigDecimal.ZERO, "%-+(8.4f", "+0.0000 " },
+ { BigDecimal.ZERO, "% 0#(9.8f", " 0.00000000" },
+ { BigDecimal.ONE, "%f", "1.000000" },
+ { BigDecimal.ONE, "%#.3f", "1.000" },
+ { BigDecimal.ONE, "%#,5f", "1.000000" },
+ { BigDecimal.ONE, "%- #(12.0f", " 1. " },
+ { BigDecimal.ONE, "%#+0(1.6f", "+1.000000" },
+ { BigDecimal.ONE, "%-+(8.4f", "+1.0000 " },
+ { BigDecimal.ONE, "% 0#(9.8f", " 1.00000000" },
+ { BigDecimal.TEN, "%f", "10.000000" },
+ { BigDecimal.TEN, "%#.3f", "10.000" },
+ { BigDecimal.TEN, "%#,5f", "10.000000" },
+ { BigDecimal.TEN, "%- #(12.0f", " 10. " },
+ { BigDecimal.TEN, "%#+0(1.6f", "+10.000000" },
+ { BigDecimal.TEN, "%-+(8.4f", "+10.0000" },
+ { BigDecimal.TEN, "% 0#(9.8f", " 10.00000000" },
+ { new BigDecimal(-1), "%f", "-1.000000" },
+ { new BigDecimal(-1), "%#.3f", "-1.000" },
+ { new BigDecimal(-1), "%#,5f", "-1.000000" },
+ { new BigDecimal(-1), "%- #(12.0f", "(1.) " },
+ { new BigDecimal(-1), "%#+0(1.6f", "(1.000000)" },
+ { new BigDecimal(-1), "%-+(8.4f", "(1.0000)" },
+ { new BigDecimal(-1), "% 0#(9.8f", "(1.00000000)" },
+ { new BigDecimal("9999999999999999999999999999999999999999999"), "%f", "9999999999999999999999999999999999999999999.000000" },
+ { new BigDecimal("9999999999999999999999999999999999999999999"), "%#.3f", "9999999999999999999999999999999999999999999.000" },
+ { new BigDecimal("9999999999999999999999999999999999999999999"), "%#,5f", "9,999,999,999,999,999,999,999,999,999,999,999,999,999,999.000000" },
+ { new BigDecimal("9999999999999999999999999999999999999999999"), "%- #(12.0f", " 9999999999999999999999999999999999999999999." },
+ { new BigDecimal("9999999999999999999999999999999999999999999"), "%#+0(1.6f", "+9999999999999999999999999999999999999999999.000000" },
+ { new BigDecimal("9999999999999999999999999999999999999999999"), "%-+(8.4f", "+9999999999999999999999999999999999999999999.0000" },
+ { new BigDecimal("9999999999999999999999999999999999999999999"), "% 0#(9.8f", " 9999999999999999999999999999999999999999999.00000000" },
+ { new BigDecimal("-9999999999999999999999999999999999999999999"), "%f", "-9999999999999999999999999999999999999999999.000000" },
+ { new BigDecimal("-9999999999999999999999999999999999999999999"), "%#.3f", "-9999999999999999999999999999999999999999999.000" },
+ { new BigDecimal("-9999999999999999999999999999999999999999999"), "%#,5f", "-9,999,999,999,999,999,999,999,999,999,999,999,999,999,999.000000" },
+ { new BigDecimal("-9999999999999999999999999999999999999999999"), "%- #(12.0f", "(9999999999999999999999999999999999999999999.)" },
+ { new BigDecimal("-9999999999999999999999999999999999999999999"), "%#+0(1.6f", "(9999999999999999999999999999999999999999999.000000)" },
+ { new BigDecimal("-9999999999999999999999999999999999999999999"), "%-+(8.4f", "(9999999999999999999999999999999999999999999.0000)" },
+ { new BigDecimal("-9999999999999999999999999999999999999999999"), "% 0#(9.8f", "(9999999999999999999999999999999999999999999.00000000)" },
+ };
+ for (int i = 0; i < tripleF.length; i++) {
+ f = new Formatter(Locale.US);
+ f.format((String) tripleF[i][pattern], tripleF[i][input]);
+ assertEquals("triple[" + i + "]:" + tripleF[i][input] + ",pattern["
+ + i + "]:" + tripleF[i][pattern], tripleF[i][output], f.toString());
+ }
+
+ f = new Formatter(Locale.US);
+ f.format("%f", new BigDecimal("5.0E9"));
+ // error on RI
+ // RI throw ArrayIndexOutOfBoundsException
+ assertEquals("5000000000.000000", f.toString());
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for exceptions in
+ * Float/Double/BigDecimal conversion type 'e', 'E', 'g', 'G', 'f', 'a', 'A'
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalConversionException() {
+ Formatter f = null;
+
+ final char[] conversions = { 'e', 'E', 'g', 'G', 'f', 'a', 'A' };
+ final Object[] illArgs = { false, (byte) 1, (short) 2, 3, (long) 4,
+ new BigInteger("5"), new Character('c'), new Object(),
+ new Date() };
+ for (int i = 0; i < illArgs.length; i++) {
+ for (int j = 0; j < conversions.length; j++) {
+ try {
+ f = new Formatter(Locale.UK);
+ f.format("%" + conversions[j], illArgs[i]);
+ fail("should throw IllegalFormatConversionException");
+ } catch (IllegalFormatConversionException e) {
+ // expected
+ }
+ }
+ }
+
+ try {
+ f = new Formatter(Locale.UK);
+ f.format("%a", new BigDecimal(1));
+ fail("should throw IllegalFormatConversionException");
+ } catch (IllegalFormatConversionException e) {
+ // expected
+ }
+
+ try {
+ f = new Formatter(Locale.UK);
+ f.format("%A", new BigDecimal(1));
+ fail("should throw IllegalFormatConversionException");
+ } catch (IllegalFormatConversionException e) {
+ // expected
+ }
+
+ final String[] flagsConversionMismatches = { "%,e", "%,E", "%#g",
+ "%#G", "%,a", "%,A", "%(a", "%(A" };
+ for (int i = 0; i < flagsConversionMismatches.length; i++) {
+ try {
+ f = new Formatter(Locale.CHINA);
+ f.format(flagsConversionMismatches[i], new BigDecimal(1));
+ fail("should throw FormatFlagsConversionMismatchException");
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+ try {
+ f = new Formatter(Locale.JAPAN);
+ f.format(flagsConversionMismatches[i], (BigDecimal) null);
+ fail("should throw FormatFlagsConversionMismatchException");
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+ }
+
+ final String[] missingFormatWidths = { "%-0e", "%0e", "%-e", "%-0E",
+ "%0E", "%-E", "%-0g", "%0g", "%-g", "%-0G", "%0G", "%-G",
+ "%-0f", "%0f", "%-f", "%-0a", "%0a", "%-a", "%-0A", "%0A",
+ "%-A" };
+ for (int i = 0; i < missingFormatWidths.length; i++) {
+ try {
+ f = new Formatter(Locale.KOREA);
+ f.format(missingFormatWidths[i], 1f);
+ fail("should throw MissingFormatWidthException");
+ } catch (MissingFormatWidthException e) {
+ // expected
+ }
+
+ try {
+ f = new Formatter(Locale.KOREA);
+ f.format(missingFormatWidths[i], (Float) null);
+ fail("should throw MissingFormatWidthException");
+ } catch (MissingFormatWidthException e) {
+ // expected
+ }
+ }
+
+ final String[] illFlags = { "%+ e", "%+ E", "%+ g", "%+ G", "%+ f",
+ "%+ a", "%+ A", "%-03e", "%-03E", "%-03g", "%-03G", "%-03f",
+ "%-03a", "%-03A" };
+ for (int i = 0; i < illFlags.length; i++) {
+ try {
+ f = new Formatter(Locale.CANADA);
+ f.format(illFlags[i], 1.23d);
+ fail("should throw IllegalFormatFlagsException");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+
+ try {
+ f = new Formatter(Locale.CANADA);
+ f.format(illFlags[i], (Double) null);
+ fail("should throw IllegalFormatFlagsException");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+ }
+
+ f = new Formatter(Locale.US);
+ try {
+ f.format("%F", 1);
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for
+ * Float/Double/BigDecimal exception throwing order
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalExceptionOrder() {
+ Formatter f = null;
+
+ /*
+ * Summary: UnknownFormatConversionException >
+ * MissingFormatWidthException > IllegalFormatFlagsException >
+ * FormatFlagsConversionMismatchException >
+ * IllegalFormatConversionException
+ *
+ */
+ try {
+ // compare FormatFlagsConversionMismatchException and
+ // IllegalFormatConversionException
+ f = new Formatter(Locale.US);
+ f.format("%,e", (byte) 1);
+ fail("should throw FormatFlagsConversionMismatchException");
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+
+ try {
+ // compare IllegalFormatFlagsException and
+ // FormatFlagsConversionMismatchException
+ f = new Formatter(Locale.US);
+ f.format("%+ ,e", 1f);
+ fail("should throw IllegalFormatFlagsException");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+
+ try {
+ // compare MissingFormatWidthException and
+ // IllegalFormatFlagsException
+ f = new Formatter(Locale.US);
+ f.format("%+ -e", 1f);
+ fail("should throw MissingFormatWidthException");
+ } catch (MissingFormatWidthException e) {
+ // expected
+ }
+
+ try {
+ // compare UnknownFormatConversionException and
+ // MissingFormatWidthException
+ f = new Formatter(Locale.US);
+ f.format("%-F", 1f);
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for BigDecimal
+ * exception throwing order
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalExceptionOrder() {
+ Formatter f = null;
+ BigDecimal bd = new BigDecimal("1.0");
+
+ /*
+ * Summary: UnknownFormatConversionException >
+ * MissingFormatWidthException > IllegalFormatFlagsException >
+ * FormatFlagsConversionMismatchException >
+ * IllegalFormatConversionException
+ *
+ */
+ try {
+ // compare FormatFlagsConversionMismatchException and
+ // IllegalFormatConversionException
+ f = new Formatter(Locale.US);
+ f.format("%,e", (byte) 1);
+ fail("should throw FormatFlagsConversionMismatchException");
+ } catch (FormatFlagsConversionMismatchException e) {
+ // expected
+ }
+
+ try {
+ // compare IllegalFormatFlagsException and
+ // FormatFlagsConversionMismatchException
+ f = new Formatter(Locale.US);
+ f.format("%+ ,e", bd);
+ fail("should throw IllegalFormatFlagsException");
+ } catch (IllegalFormatFlagsException e) {
+ // expected
+ }
+
+ try {
+ // compare MissingFormatWidthException and
+ // IllegalFormatFlagsException
+ f = new Formatter(Locale.US);
+ f.format("%+ -e", bd);
+ fail("should throw MissingFormatWidthException");
+ } catch (MissingFormatWidthException e) {
+ // expected
+ }
+
+ // compare UnknownFormatConversionException and
+ // MissingFormatWidthException
+ try {
+ f = new Formatter(Locale.US);
+ f.format("%-F", bd);
+ fail("should throw UnknownFormatConversionException");
+ } catch (UnknownFormatConversionException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Formatter#format(String, Object...) for null argment for
+ * Float/Double/BigDecimal conversion
+ */
+ public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalNullConversion() {
+ Formatter f = null;
+
+ // test (Float)null
+ f = new Formatter(Locale.FRANCE);
+ f.format("%#- (9.0e", (Float) null);
+ assertEquals(" ", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%-+(1.6E", (Float) null);
+ assertEquals("NULL", f.toString());
+
+ f = new Formatter(Locale.UK);
+ f.format("%+0(,8.4g", (Float) null);
+ assertEquals(" null", f.toString());
+
+ f = new Formatter(Locale.FRANCE);
+ f.format("%- (9.8G", (Float) null);
+ assertEquals("NULL ", f.toString());
+
+ f = new Formatter(Locale.FRANCE);
+ f.format("%- (12.1f", (Float) null);
+ assertEquals("n ", f.toString());
+
+ f = new Formatter(Locale.FRANCE);
+ f.format("% .4a", (Float) null);
+ assertEquals("null", f.toString());
+
+ f = new Formatter(Locale.FRANCE);
+ f.format("%06A", (Float) null);
+ assertEquals(" NULL", f.toString());
+
+ // test (Double)null
+ f = new Formatter(Locale.GERMAN);
+ f.format("%- (9e", (Double) null);
+ assertEquals("null ", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%#-+(1.6E", (Double) null);
+ assertEquals("NULL", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%+0(6.4g", (Double) null);
+ assertEquals(" null", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%- (,5.8G", (Double) null);
+ assertEquals("NULL ", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("% (.4f", (Double) null);
+ assertEquals("null", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("%#.6a", (Double) null);
+ assertEquals("null", f.toString());
+
+ f = new Formatter(Locale.GERMAN);
+ f.format("% 2.5A", (Double) null);
+ assertEquals("NULL", f.toString());
+
+ // test (BigDecimal)null
+ f = new Formatter(Locale.UK);
+ f.format("%#- (6.2e", (BigDecimal) null);
+ assertEquals("nu ", f.toString());
+
+ f = new Formatter(Locale.UK);
+ f.format("%-+(1.6E", (BigDecimal) null);
+ assertEquals("NULL", f.toString());
+
+ f = new Formatter(Locale.UK);
+ f.format("%+-(,5.3g", (BigDecimal) null);
+ assertEquals("nul ", f.toString());
+
+ f = new Formatter(Locale.UK);
+ f.format("%0 3G", (BigDecimal) null);
+ assertEquals("NULL", f.toString());
+
+ f = new Formatter(Locale.UK);
+ f.format("%0 (9.0G", (BigDecimal) null);
+ assertEquals(" ", f.toString());
+
+ f = new Formatter(Locale.UK);
+ f.format("% (.5f", (BigDecimal) null);
+ assertEquals("null", f.toString());
+
+ f = new Formatter(Locale.UK);
+ f.format("%06a", (BigDecimal) null);
+ assertEquals(" null", f.toString());
+
+ f = new Formatter(Locale.UK);
+ f.format("% .5A", (BigDecimal) null);
+ assertEquals("NULL", f.toString());
+ }
+
+ /**
+ * java.util.Formatter.BigDecimalLayoutForm#values()
+ */
+ public void test_values() {
+ BigDecimalLayoutForm[] vals = BigDecimalLayoutForm.values();
+ assertEquals("Invalid length of enum values", 2, vals.length);
+ assertEquals("Wrong scientific value in enum", BigDecimalLayoutForm.SCIENTIFIC, vals[0]);
+ assertEquals("Wrong dec float value in enum", BigDecimalLayoutForm.DECIMAL_FLOAT, vals[1]);
+ }
+
+ /**
+ * java.util.Formatter.BigDecimalLayoutForm#valueOf(String)
+ */
+ public void test_valueOfLjava_lang_String() {
+ BigDecimalLayoutForm sci = BigDecimalLayoutForm.valueOf("SCIENTIFIC");
+ assertEquals("Wrong scientific value in enum", BigDecimalLayoutForm.SCIENTIFIC, sci);
+
+ BigDecimalLayoutForm decFloat = BigDecimalLayoutForm.valueOf("DECIMAL_FLOAT");
+ assertEquals("Wrong dec float value from valueOf ", BigDecimalLayoutForm.DECIMAL_FLOAT, decFloat);
+ }
+
+ /*
+ * Regression test for Harmony-5845
+ * test the short name for timezone whether uses DaylightTime or not
+ */
+ public void test_DaylightTime() {
+ Calendar c1 = new GregorianCalendar(2007, 0, 1);
+ Calendar c2 = new GregorianCalendar(2007, 7, 1);
+
+ for (String tz : TimeZone.getAvailableIDs()) {
+ if (tz.equals("America/Los_Angeles")) {
+ c1.setTimeZone(TimeZone.getTimeZone(tz));
+ c2.setTimeZone(TimeZone.getTimeZone(tz));
+ assertTrue(String.format("%1$tZ%2$tZ", c1, c2).equals("PSTPDT"));
+ }
+ if (tz.equals("America/Panama")) {
+ c1.setTimeZone(TimeZone.getTimeZone(tz));
+ c2.setTimeZone(TimeZone.getTimeZone(tz));
+ assertTrue(String.format("%1$tZ%2$tZ", c1, c2).equals("ESTEST"));
+ }
+ }
+ }
+
+ /*
+ * Regression test for Harmony-5845
+ * test scientific notation to follow RI's behavior
+ */
+ public void test_ScientificNotation() {
+ Formatter f = new Formatter();
+ MathContext mc = new MathContext(30);
+ BigDecimal value = new BigDecimal(0.1, mc);
+ f.format("%.30G", value);
+
+ String result = f.toString();
+ String expected = "0.100000000000000005551115123126";
+ assertEquals(expected, result);
+ }
+
+
+ /**
+ * Setup resource files for testing
+ */
+ protected void setUp() throws IOException {
+ root = System.getProperty("user.name").equalsIgnoreCase("root");
+ notExist = File.createTempFile("notexist", null);
+ notExist.delete();
+
+ fileWithContent = File.createTempFile("filewithcontent", null);
+ BufferedOutputStream bw = new BufferedOutputStream(
+ new FileOutputStream(fileWithContent));
+ bw.write(1);// write something into the file
+ bw.close();
+
+ readOnly = File.createTempFile("readonly", null);
+ readOnly.setReadOnly();
+
+ secret = File.createTempFile("secret", null);
+
+ defaultTimeZone = TimeZone.getDefault();
+ TimeZone cst = TimeZone.getTimeZone("Asia/Shanghai");
+ TimeZone.setDefault(cst);
+ }
+
+ /**
+ * Delete the resource files if they exist
+ */
+ protected void tearDown() {
+ if (notExist.exists()) {
+ notExist.delete();
+ }
+
+ if (fileWithContent.exists()) {
+ fileWithContent.delete();
+ }
+ if (readOnly.exists()) {
+ readOnly.delete();
+ }
+ if (secret.exists()) {
+ secret.delete();
+ }
+
+ TimeZone.setDefault(defaultTimeZone);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/GregorianCalendarTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/GregorianCalendarTest.java
new file mode 100644
index 0000000..f35be4b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/GregorianCalendarTest.java
@@ -0,0 +1,753 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.BitSet;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+import java.util.Vector;
+
+public class GregorianCalendarTest extends junit.framework.TestCase {
+
+ private static final TimeZone AMERICA_CHICAGO = TimeZone.getTimeZone("America/Chicago");
+ private static final TimeZone AMERICA_NEW_YORK = TimeZone.getTimeZone("America/New_York");
+
+ /**
+ * java.util.GregorianCalendar#GregorianCalendar()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.GregorianCalendar()
+ assertTrue("Constructed incorrect calendar", (new GregorianCalendar()
+ .isLenient()));
+ }
+
+ /**
+ * java.util.GregorianCalendar#GregorianCalendar(int, int, int)
+ */
+ public void test_ConstructorIII() {
+ // Test for method java.util.GregorianCalendar(int, int, int)
+ GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER, 13);
+ assertEquals("Incorrect calendar constructed 1",
+ 1972, gc.get(Calendar.YEAR));
+ assertTrue("Incorrect calendar constructed 2",
+ gc.get(Calendar.MONTH) == Calendar.OCTOBER);
+ assertEquals("Incorrect calendar constructed 3", 13, gc
+ .get(Calendar.DAY_OF_MONTH));
+ assertTrue("Incorrect calendar constructed 4", gc.getTimeZone().equals(
+ TimeZone.getDefault()));
+ }
+
+ /**
+ * java.util.GregorianCalendar#GregorianCalendar(int, int, int, int,
+ *int)
+ */
+ public void test_ConstructorIIIII() {
+ // Test for method java.util.GregorianCalendar(int, int, int, int, int)
+ GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER,
+ 13, 19, 9);
+ assertEquals("Incorrect calendar constructed",
+ 1972, gc.get(Calendar.YEAR));
+ assertTrue("Incorrect calendar constructed",
+ gc.get(Calendar.MONTH) == Calendar.OCTOBER);
+ assertEquals("Incorrect calendar constructed", 13, gc
+ .get(Calendar.DAY_OF_MONTH));
+ assertEquals("Incorrect calendar constructed", 7, gc.get(Calendar.HOUR));
+ assertEquals("Incorrect calendar constructed",
+ 1, gc.get(Calendar.AM_PM));
+ assertEquals("Incorrect calendar constructed",
+ 9, gc.get(Calendar.MINUTE));
+ assertTrue("Incorrect calendar constructed", gc.getTimeZone().equals(
+ TimeZone.getDefault()));
+
+ //Regression for HARMONY-998
+ gc = new GregorianCalendar(1900, 0, 0, 0, Integer.MAX_VALUE);
+ assertEquals("Incorrect calendar constructed",
+ 5983, gc.get(Calendar.YEAR));
+ }
+
+ /**
+ * java.util.GregorianCalendar#GregorianCalendar(int, int, int, int,
+ *int, int)
+ */
+ public void test_ConstructorIIIIII() {
+ // Test for method java.util.GregorianCalendar(int, int, int, int, int,
+ // int)
+ GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER,
+ 13, 19, 9, 59);
+ assertEquals("Incorrect calendar constructed",
+ 1972, gc.get(Calendar.YEAR));
+ assertTrue("Incorrect calendar constructed",
+ gc.get(Calendar.MONTH) == Calendar.OCTOBER);
+ assertEquals("Incorrect calendar constructed", 13, gc
+ .get(Calendar.DAY_OF_MONTH));
+ assertEquals("Incorrect calendar constructed", 7, gc.get(Calendar.HOUR));
+ assertEquals("Incorrect calendar constructed",
+ 1, gc.get(Calendar.AM_PM));
+ assertEquals("Incorrect calendar constructed",
+ 9, gc.get(Calendar.MINUTE));
+ assertEquals("Incorrect calendar constructed",
+ 59, gc.get(Calendar.SECOND));
+ assertTrue("Incorrect calendar constructed", gc.getTimeZone().equals(
+ TimeZone.getDefault()));
+ }
+
+ /**
+ * java.util.GregorianCalendar#GregorianCalendar(java.util.Locale)
+ */
+ public void test_ConstructorLjava_util_Locale() {
+ // Test for method java.util.GregorianCalendar(java.util.Locale)
+ Date date = new Date();
+ GregorianCalendar gcJapan = new GregorianCalendar(Locale.JAPAN);
+ gcJapan.setTime(date);
+ GregorianCalendar gcJapan2 = new GregorianCalendar(Locale.JAPAN);
+ gcJapan2.setTime(date);
+ GregorianCalendar gcItaly = new GregorianCalendar(Locale.ITALY);
+ gcItaly.setTime(date);
+ assertTrue("Locales not created correctly", gcJapan.equals(gcJapan2)
+ && !gcJapan.equals(gcItaly));
+ }
+
+ /**
+ * java.util.GregorianCalendar#GregorianCalendar(java.util.TimeZone)
+ */
+ public void test_ConstructorLjava_util_TimeZone() {
+ // Test for method java.util.GregorianCalendar(java.util.TimeZone)
+ Date date = new Date(2008, 1, 1);
+ TimeZone.getDefault();
+ GregorianCalendar gc1 = new GregorianCalendar(AMERICA_NEW_YORK);
+ gc1.setTime(date);
+ GregorianCalendar gc2 = new GregorianCalendar(AMERICA_CHICAGO);
+ gc2.setTime(date);
+ // Chicago is 1 hour before New York, add 1 to the Chicago time and convert to 0-12 value
+ assertEquals("Incorrect calendar returned",
+ gc1.get(Calendar.HOUR), ((gc2.get(Calendar.HOUR) + 1) % 12));
+
+ // Regression test for HARMONY-2961
+ SimpleTimeZone timezone = new SimpleTimeZone(-3600 * 24 * 1000 * 2,
+ "GMT");
+ GregorianCalendar gc = new GregorianCalendar(timezone);
+
+ // Regression test for HARMONY-5195
+ Calendar c1 = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+ c1.set(Calendar.YEAR, 1999);
+ c1.set(Calendar.MONTH, Calendar.JUNE);
+ c1.set(Calendar.DAY_OF_MONTH, 2);
+ c1.set(Calendar.HOUR, 15);
+ c1.set(Calendar.MINUTE, 34);
+ c1.set(Calendar.SECOND, 16);
+ assertEquals(34, c1.get(Calendar.MINUTE));
+ c1.setTimeZone(new SimpleTimeZone(60000, "ONE MINUTE"));
+ assertEquals(35, c1.get(Calendar.MINUTE));
+ }
+
+ /**
+ * java.util.GregorianCalendar#GregorianCalendar(java.util.TimeZone,
+ *java.util.Locale)
+ */
+ public void test_ConstructorLjava_util_TimeZoneLjava_util_Locale() {
+ // Test for method java.util.GregorianCalendar(java.util.TimeZone,
+ // java.util.Locale)
+ Date date = new Date(2008, 1, 1);
+ TimeZone.getDefault();
+ GregorianCalendar gc1 = new GregorianCalendar(AMERICA_NEW_YORK, Locale.JAPAN);
+ gc1.setTime(date);
+ GregorianCalendar gc2 = new GregorianCalendar(AMERICA_NEW_YORK, Locale.JAPAN);
+ gc2.setTime(date);
+ GregorianCalendar gc3 = new GregorianCalendar(AMERICA_CHICAGO, Locale.ITALY);
+ gc3.setTime(date);
+ // Chicago is 1 hour before New York, add 1 to the Chicago time and convert to 0-12 value
+ assertEquals("Incorrect calendar returned",
+ gc1.get(Calendar.HOUR), ((gc3.get(Calendar.HOUR) + 1) % 12));
+ assertTrue("Locales not created correctly", gc1.equals(gc2)
+ && !gc1.equals(gc3));
+ }
+
+ /**
+ * java.util.GregorianCalendar#add(int, int)
+ */
+ public void test_addII() {
+ // Test for method void java.util.GregorianCalendar.add(int, int)
+ GregorianCalendar gc1 = new GregorianCalendar(1998, 11, 6);
+ gc1.add(GregorianCalendar.YEAR, 1);
+ assertEquals("Add failed to Increment",
+ 1999, gc1.get(GregorianCalendar.YEAR));
+
+ gc1 = new GregorianCalendar(1999, Calendar.JULY, 31);
+ gc1.add(Calendar.MONTH, 7);
+ assertEquals("Wrong result year 1", 2000, gc1.get(Calendar.YEAR));
+ assertTrue("Wrong result month 1",
+ gc1.get(Calendar.MONTH) == Calendar.FEBRUARY);
+ assertEquals("Wrong result date 1", 29, gc1.get(Calendar.DATE));
+
+ gc1.add(Calendar.YEAR, -1);
+ assertEquals("Wrong result year 2", 1999, gc1.get(Calendar.YEAR));
+ assertTrue("Wrong result month 2",
+ gc1.get(Calendar.MONTH) == Calendar.FEBRUARY);
+ assertEquals("Wrong result date 2", 28, gc1.get(Calendar.DATE));
+
+ gc1 = new GregorianCalendar(AMERICA_NEW_YORK);
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.MILLISECOND, 24 * 60 * 60 * 1000);
+ assertEquals("Wrong time after MILLISECOND change", 17, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.SECOND, 24 * 60 * 60);
+ assertEquals("Wrong time after SECOND change", 17, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.MINUTE, 24 * 60);
+ assertEquals("Wrong time after MINUTE change", 17, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.HOUR, 24);
+ assertEquals("Wrong time after HOUR change", 17, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.HOUR_OF_DAY, 24);
+ assertEquals("Wrong time after HOUR_OF_DAY change", 17, gc1
+ .get(Calendar.HOUR_OF_DAY));
+
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.AM_PM, 2);
+ assertEquals("Wrong time after AM_PM change", 16, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.DATE, 1);
+ assertEquals("Wrong time after DATE change", 16, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.DAY_OF_YEAR, 1);
+ assertEquals("Wrong time after DAY_OF_YEAR change", 16, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.DAY_OF_WEEK, 1);
+ assertEquals("Wrong time after DAY_OF_WEEK change", 16, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.WEEK_OF_YEAR, 1);
+ assertEquals("Wrong time after WEEK_OF_YEAR change", 16, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.WEEK_OF_MONTH, 1);
+ assertEquals("Wrong time after WEEK_OF_MONTH change", 16, gc1
+ .get(Calendar.HOUR_OF_DAY));
+ gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+ gc1.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+ assertEquals("Wrong time after DAY_OF_WEEK_IN_MONTH change", 16, gc1
+ .get(Calendar.HOUR_OF_DAY));
+
+ gc1.clear();
+ gc1.set(2000, Calendar.APRIL, 1, 23, 0);
+ gc1.add(Calendar.DATE, 1);
+ assertTrue("Wrong time after DATE change near DST boundary", gc1
+ .get(Calendar.MONTH) == Calendar.APRIL
+ && gc1.get(Calendar.DATE) == 2
+ && gc1.get(Calendar.HOUR_OF_DAY) == 23);
+ }
+
+ /**
+ * java.util.GregorianCalendar#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.GregorianCalendar.equals(java.lang.Object)
+ GregorianCalendar gc1 = new GregorianCalendar(1998, 11, 6);
+ GregorianCalendar gc2 = new GregorianCalendar(2000, 11, 6);
+ GregorianCalendar gc3 = new GregorianCalendar(1998, 11, 6);
+ assertTrue("Equality check failed", gc1.equals(gc3));
+ assertTrue("Equality check failed", !gc1.equals(gc2));
+ gc3.setGregorianChange(new Date());
+ assertTrue("Different gregorian change", !gc1.equals(gc3));
+ }
+
+ /**
+ * java.util.GregorianCalendar#getActualMaximum(int)
+ */
+ public void test_getActualMaximumI() {
+ // Test for method int java.util.GregorianCalendar.getActualMaximum(int)
+ GregorianCalendar gc1 = new GregorianCalendar(1900, 1, 1);
+ GregorianCalendar gc2 = new GregorianCalendar(1996, 1, 1);
+ GregorianCalendar gc3 = new GregorianCalendar(1997, 1, 1);
+ GregorianCalendar gc4 = new GregorianCalendar(2000, 1, 1);
+ GregorianCalendar gc5 = new GregorianCalendar(2000, 9, 9);
+ GregorianCalendar gc6 = new GregorianCalendar(2000, 3, 3);
+ assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Feb 1900",
+ 28, gc1.getActualMaximum(Calendar.DAY_OF_MONTH));
+ assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Feb 1996",
+ 29, gc2.getActualMaximum(Calendar.DAY_OF_MONTH));
+ assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Feb 1998",
+ 28, gc3.getActualMaximum(Calendar.DAY_OF_MONTH));
+ assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Feb 2000",
+ 29, gc4.getActualMaximum(Calendar.DAY_OF_MONTH));
+ assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Oct 2000",
+ 31, gc5.getActualMaximum(Calendar.DAY_OF_MONTH));
+ assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Apr 2000",
+ 30, gc6.getActualMaximum(Calendar.DAY_OF_MONTH));
+ assertTrue("Wrong actual maximum value for MONTH", gc1
+ .getActualMaximum(Calendar.MONTH) == Calendar.DECEMBER);
+ assertEquals("Wrong actual maximum value for HOUR_OF_DAY", 23, gc1
+ .getActualMaximum(Calendar.HOUR_OF_DAY));
+ assertEquals("Wrong actual maximum value for HOUR", 11, gc1
+ .getActualMaximum(Calendar.HOUR));
+ assertEquals("Wrong actual maximum value for DAY_OF_WEEK_IN_MONTH", 4, gc6
+ .getActualMaximum(Calendar.DAY_OF_WEEK_IN_MONTH));
+
+
+ // Regression test for harmony 2954
+ Date date = new Date(Date.parse("Jan 15 00:00:01 GMT 2000"));
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.setTimeInMillis(Date.parse("Dec 15 00:00:01 GMT 1582"));
+ assertEquals(355, gc.getActualMaximum(Calendar.DAY_OF_YEAR));
+ gc.setGregorianChange(date);
+ gc.setTimeInMillis(Date.parse("Jan 16 00:00:01 GMT 2000"));
+ assertEquals(353, gc.getActualMaximum(Calendar.DAY_OF_YEAR));
+
+ //Regression test for HARMONY-3004
+ gc = new GregorianCalendar(1900, 7, 1);
+ String[] ids = TimeZone.getAvailableIDs();
+ for (int i = 0; i < ids.length; i++) {
+ TimeZone tz = TimeZone.getTimeZone(ids[i]);
+ gc.setTimeZone(tz);
+ for (int j = 1900; j < 2000; j++) {
+ gc.set(Calendar.YEAR, j);
+ assertEquals(7200000, gc.getActualMaximum(Calendar.DST_OFFSET));
+ }
+ }
+ }
+
+ /**
+ * java.util.GregorianCalendar#getActualMinimum(int)
+ */
+ public void test_getActualMinimumI() {
+ // Test for method int java.util.GregorianCalendar.getActualMinimum(int)
+ GregorianCalendar gc1 = new GregorianCalendar(1900, 1, 1);
+ new GregorianCalendar(1996, 1, 1);
+ new GregorianCalendar(1997, 1, 1);
+ new GregorianCalendar(2000, 1, 1);
+ new GregorianCalendar(2000, 9, 9);
+ GregorianCalendar gc6 = new GregorianCalendar(2000, 3, 3);
+ assertEquals("Wrong actual minimum value for DAY_OF_MONTH for Feb 1900",
+ 1, gc1.getActualMinimum(Calendar.DAY_OF_MONTH));
+ assertTrue("Wrong actual minimum value for MONTH", gc1
+ .getActualMinimum(Calendar.MONTH) == Calendar.JANUARY);
+ assertEquals("Wrong actual minimum value for HOUR_OF_DAY", 0, gc1
+ .getActualMinimum(Calendar.HOUR_OF_DAY));
+ assertEquals("Wrong actual minimum value for HOUR", 0, gc1
+ .getActualMinimum(Calendar.HOUR));
+ assertEquals("Wrong actual minimum value for DAY_OF_WEEK_IN_MONTH", 1, gc6
+ .getActualMinimum(Calendar.DAY_OF_WEEK_IN_MONTH));
+ }
+
+ /**
+ * java.util.GregorianCalendar#getGreatestMinimum(int)
+ */
+ public void test_getGreatestMinimumI() {
+ // Test for method int
+ // java.util.GregorianCalendar.getGreatestMinimum(int)
+ GregorianCalendar gc = new GregorianCalendar();
+ assertEquals("Wrong greatest minimum value for DAY_OF_MONTH", 1, gc
+ .getGreatestMinimum(Calendar.DAY_OF_MONTH));
+ assertTrue("Wrong greatest minimum value for MONTH", gc
+ .getGreatestMinimum(Calendar.MONTH) == Calendar.JANUARY);
+ assertEquals("Wrong greatest minimum value for HOUR_OF_DAY", 0, gc
+ .getGreatestMinimum(Calendar.HOUR_OF_DAY));
+ assertEquals("Wrong greatest minimum value for HOUR", 0, gc
+ .getGreatestMinimum(Calendar.HOUR));
+
+ BitSet result = new BitSet();
+ int[] min = { 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, -46800000,
+ 0 };
+ for (int i = 0; i < min.length; i++) {
+ if (gc.getGreatestMinimum(i) != min[i])
+ result.set(i);
+ }
+ assertTrue("Wrong greatest min for " + result, result.length() == 0);
+ }
+
+ /**
+ * java.util.GregorianCalendar#getGregorianChange()
+ */
+ public void test_getGregorianChange() {
+ // Test for method java.util.Date
+ // java.util.GregorianCalendar.getGregorianChange()
+ GregorianCalendar gc = new GregorianCalendar();
+ GregorianCalendar returnedChange = new GregorianCalendar(AMERICA_NEW_YORK);
+ returnedChange.setTime(gc.getGregorianChange());
+ assertEquals("Returned incorrect year",
+ 1582, returnedChange.get(Calendar.YEAR));
+ assertTrue("Returned incorrect month", returnedChange
+ .get(Calendar.MONTH) == Calendar.OCTOBER);
+ assertEquals("Returned incorrect day of month", 4, returnedChange
+ .get(Calendar.DAY_OF_MONTH));
+ }
+
+ /**
+ * java.util.GregorianCalendar#getLeastMaximum(int)
+ */
+ public void test_getLeastMaximumI() {
+ // Test for method int java.util.GregorianCalendar.getLeastMaximum(int)
+ GregorianCalendar gc = new GregorianCalendar();
+ assertEquals("Wrong least maximum value for DAY_OF_MONTH", 28, gc
+ .getLeastMaximum(Calendar.DAY_OF_MONTH));
+ assertTrue("Wrong least maximum value for MONTH", gc
+ .getLeastMaximum(Calendar.MONTH) == Calendar.DECEMBER);
+ assertEquals("Wrong least maximum value for HOUR_OF_DAY", 23, gc
+ .getLeastMaximum(Calendar.HOUR_OF_DAY));
+ assertEquals("Wrong least maximum value for HOUR", 11, gc
+ .getLeastMaximum(Calendar.HOUR));
+
+ BitSet result = new BitSet();
+ Vector values = new Vector();
+ int[] max = { 1, 292269054, 11, 50, 3, 28, 355, 7, 3, 1, 11, 23, 59,
+ 59, 999, 50400000, 1200000 };
+ for (int i = 0; i < max.length; i++) {
+ if (gc.getLeastMaximum(i) != max[i]) {
+ result.set(i);
+ values.add(new Integer(gc.getLeastMaximum(i)));
+ }
+ }
+ assertTrue("Wrong least max for " + result + " = " + values, result
+ .length() == 0);
+
+ // Regression test for harmony-2947
+ Date date = new Date(Date.parse("Jan 1 00:00:01 GMT 2000"));
+ gc = new GregorianCalendar();
+ gc.setGregorianChange(date);
+ gc.setTime(date);
+ assertEquals(gc.getActualMaximum(Calendar.WEEK_OF_YEAR), gc
+ .getLeastMaximum(Calendar.WEEK_OF_YEAR));
+ }
+
+ /**
+ * java.util.GregorianCalendar#getMaximum(int)
+ */
+ public void test_getMaximumI() {
+ // Test for method int java.util.GregorianCalendar.getMaximum(int)
+ GregorianCalendar gc = new GregorianCalendar();
+ assertEquals("Wrong maximum value for DAY_OF_MONTH", 31, gc
+ .getMaximum(Calendar.DAY_OF_MONTH));
+ assertTrue("Wrong maximum value for MONTH", gc
+ .getMaximum(Calendar.MONTH) == Calendar.DECEMBER);
+ assertEquals("Wrong maximum value for HOUR_OF_DAY", 23, gc
+ .getMaximum(Calendar.HOUR_OF_DAY));
+ assertEquals("Wrong maximum value for HOUR",
+ 11, gc.getMaximum(Calendar.HOUR));
+
+ BitSet result = new BitSet();
+ Vector values = new Vector();
+ int[] max = { 1, 292278994, 11, 53, 6, 31, 366, 7, 6, 1, 11, 23, 59,
+ 59, 999, 50400000, 7200000 };
+ for (int i = 0; i < max.length; i++) {
+ if (gc.getMaximum(i) != max[i]) {
+ result.set(i);
+ values.add(new Integer(gc.getMaximum(i)));
+ }
+ }
+ assertTrue("Wrong max for " + result + " = " + values,
+ result.length() == 0);
+ }
+
+ /**
+ * java.util.GregorianCalendar#getMinimum(int)
+ */
+ public void test_getMinimumI() {
+ // Test for method int java.util.GregorianCalendar.getMinimum(int)
+ GregorianCalendar gc = new GregorianCalendar();
+ assertEquals("Wrong minimum value for DAY_OF_MONTH", 1, gc
+ .getMinimum(Calendar.DAY_OF_MONTH));
+ assertTrue("Wrong minimum value for MONTH", gc
+ .getMinimum(Calendar.MONTH) == Calendar.JANUARY);
+ assertEquals("Wrong minimum value for HOUR_OF_DAY", 0, gc
+ .getMinimum(Calendar.HOUR_OF_DAY));
+ assertEquals("Wrong minimum value for HOUR",
+ 0, gc.getMinimum(Calendar.HOUR));
+
+ BitSet result = new BitSet();
+ int[] min = { 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, -46800000,
+ 0 };
+ for (int i = 0; i < min.length; i++) {
+ if (gc.getMinimum(i) != min[i])
+ result.set(i);
+ }
+ assertTrue("Wrong min for " + result, result.length() == 0);
+ }
+
+ /**
+ * java.util.GregorianCalendar#isLeapYear(int)
+ */
+ public void test_isLeapYearI() {
+ // Test for method boolean java.util.GregorianCalendar.isLeapYear(int)
+ GregorianCalendar gc = new GregorianCalendar(1998, 11, 6);
+ assertTrue("Returned incorrect value for leap year", !gc
+ .isLeapYear(1998));
+ assertTrue("Returned incorrect value for leap year", gc
+ .isLeapYear(2000));
+
+ }
+
+ /**
+ * java.util.GregorianCalendar#roll(int, int)
+ */
+ public void test_rollII() {
+ // Test for method void java.util.GregorianCalendar.roll(int, int)
+ GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER, 8,
+ 2, 5, 0);
+ gc.roll(Calendar.DAY_OF_MONTH, -1);
+ assertTrue("Failed to roll DAY_OF_MONTH down by 1", gc
+ .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 7, 2, 5,
+ 0)));
+ gc = new GregorianCalendar(1972, Calendar.OCTOBER, 8, 2, 5, 0);
+ gc.roll(Calendar.DAY_OF_MONTH, 25);
+ assertTrue("Failed to roll DAY_OF_MONTH up by 25", gc
+ .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 2, 2, 5,
+ 0)));
+ gc = new GregorianCalendar(1972, Calendar.OCTOBER, 8, 2, 5, 0);
+ gc.roll(Calendar.DAY_OF_MONTH, -10);
+ assertTrue("Failed to roll DAY_OF_MONTH down by 10", gc
+ .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 29, 2, 5,
+ 0)));
+ }
+
+ /**
+ * java.util.GregorianCalendar#roll(int, boolean)
+ */
+ public void test_rollIZ() {
+ // Test for method void java.util.GregorianCalendar.roll(int, boolean)
+ GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER,
+ 13, 19, 9, 59);
+ gc.roll(Calendar.DAY_OF_MONTH, false);
+ assertTrue("Failed to roll day_of_month down", gc
+ .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 12, 19,
+ 9, 59)));
+ gc = new GregorianCalendar(1972, Calendar.OCTOBER, 13, 19, 9, 59);
+ gc.roll(Calendar.DAY_OF_MONTH, true);
+ assertTrue("Failed to roll day_of_month up", gc
+ .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 14, 19,
+ 9, 59)));
+ gc = new GregorianCalendar(1972, Calendar.OCTOBER, 31, 19, 9, 59);
+ gc.roll(Calendar.DAY_OF_MONTH, true);
+ assertTrue("Failed to roll day_of_month up", gc
+ .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 1, 19, 9,
+ 59)));
+
+ GregorianCalendar cal = new GregorianCalendar();
+ int result;
+ try {
+ cal.roll(Calendar.ZONE_OFFSET, true);
+ result = 0;
+ } catch (IllegalArgumentException e) {
+ result = 1;
+ }
+ assertEquals("ZONE_OFFSET roll", 1, result);
+ try {
+ cal.roll(Calendar.DST_OFFSET, true);
+ result = 0;
+ } catch (IllegalArgumentException e) {
+ result = 1;
+ }
+ assertEquals("ZONE_OFFSET roll", 1, result);
+
+ cal.set(2004, Calendar.DECEMBER, 31, 5, 0, 0);
+ cal.roll(Calendar.WEEK_OF_YEAR, true);
+ assertEquals("Wrong year: " + cal.getTime(), 2004, cal
+ .get(Calendar.YEAR));
+ assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+ .get(Calendar.MONTH));
+ assertEquals("Wrong date: " + cal.getTime(), 9, cal.get(Calendar.DATE));
+
+ // Regression for HARMONY-4372
+ cal.set(1994, 11, 30, 5, 0, 0);
+ cal.setMinimalDaysInFirstWeek(4);
+ cal.roll(Calendar.WEEK_OF_YEAR, true);
+ assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+ .get(Calendar.YEAR));
+ assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+ .get(Calendar.MONTH));
+ assertEquals("Wrong date: " + cal.getTime(), 7, cal.get(Calendar.DATE));
+
+ cal.roll(Calendar.WEEK_OF_YEAR, true);
+ assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+ .get(Calendar.YEAR));
+ assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+ .get(Calendar.MONTH));
+ assertEquals("Wrong date: " + cal.getTime(), 14, cal.get(Calendar.DATE));
+
+ cal.roll(Calendar.WEEK_OF_YEAR, false);
+ assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+ .get(Calendar.YEAR));
+ assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+ .get(Calendar.MONTH));
+ assertEquals("Wrong date: " + cal.getTime(), 7, cal.get(Calendar.DATE));
+
+ cal.roll(Calendar.WEEK_OF_YEAR, false);
+ assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+ .get(Calendar.YEAR));
+ assertEquals("Wrong month: " + cal.getTime(), Calendar.DECEMBER, cal
+ .get(Calendar.MONTH));
+ assertEquals("Wrong date: " + cal.getTime(), 30, cal.get(Calendar.DATE));
+
+ cal.roll(Calendar.WEEK_OF_YEAR, false);
+ assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+ .get(Calendar.YEAR));
+ assertEquals("Wrong month: " + cal.getTime(), Calendar.DECEMBER, cal
+ .get(Calendar.MONTH));
+ assertEquals("Wrong date: " + cal.getTime(), 23, cal.get(Calendar.DATE));
+
+ // Regression for HARMONY-4510
+ cal.set(1999, Calendar.DECEMBER, 31, 23, 59, 59);
+ cal.roll(GregorianCalendar.WEEK_OF_YEAR, true);
+ assertEquals("Wrong year: " + cal.getTime(), 1999, cal
+ .get(Calendar.YEAR));
+ assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+ .get(Calendar.MONTH));
+ assertEquals("Wrong date: " + cal.getTime(), 8, cal.get(Calendar.DATE));
+ cal.roll(GregorianCalendar.WEEK_OF_YEAR, false);
+ assertEquals("Wrong year: " + cal.getTime(), 1999, cal
+ .get(Calendar.YEAR));
+ assertEquals("Wrong month: " + cal.getTime(), Calendar.DECEMBER, cal
+ .get(Calendar.MONTH));
+ assertEquals("Wrong date: " + cal.getTime(), 31, cal.get(Calendar.DATE));
+ }
+
+ /**
+ * java.util.GregorianCalendar#setGregorianChange(java.util.Date)
+ */
+ public void test_setGregorianChangeLjava_util_Date() {
+ // Test for method void
+ // java.util.GregorianCalendar.setGregorianChange(java.util.Date)
+ GregorianCalendar gc1 = new GregorianCalendar(1582, Calendar.OCTOBER,
+ 4, 0, 0);
+ GregorianCalendar gc2 = new GregorianCalendar(1972, Calendar.OCTOBER,
+ 13, 0, 0);
+ gc1.setGregorianChange(gc2.getTime());
+ assertTrue("Returned incorrect value", gc2.getTime().equals(
+ gc1.getGregorianChange()));
+ }
+
+ /**
+ * java.util.GregorianCalendar#clone()
+ */
+ public void test_clone() {
+
+ // Regression for HARMONY-498
+ GregorianCalendar gCalend = new GregorianCalendar();
+
+ gCalend.set(Calendar.MILLISECOND, 0);
+ int dayOfMonth = gCalend.get(Calendar.DAY_OF_MONTH);
+
+ // create clone object and change date
+ GregorianCalendar gCalendClone = (GregorianCalendar) gCalend.clone();
+ gCalendClone.add(Calendar.DATE, 1);
+
+ assertEquals("Before", dayOfMonth, gCalend.get(Calendar.DAY_OF_MONTH));
+ gCalend.set(Calendar.MILLISECOND, 0);//changes nothing
+ assertEquals("After", dayOfMonth, gCalend.get(Calendar.DAY_OF_MONTH));
+ }
+
+ /**
+ * java.util.GregorianCalendar#getMinimalDaysInFirstWeek()
+ */
+ public void test_getMinimalDaysInFirstWeek() {
+ // Regression for Harmony-1037
+ // Some non-bug differences below because of different CLDR data of Harmony
+ GregorianCalendar g = new GregorianCalendar(TimeZone
+ .getTimeZone("Europe/London"), new Locale("en", "GB"));
+ int minimalDaysInFirstWeek = g.getMinimalDaysInFirstWeek();
+ assertEquals(4, minimalDaysInFirstWeek);
+
+ g = new GregorianCalendar(TimeZone.getTimeZone("Europe/London"),
+ new Locale("fr"));
+ minimalDaysInFirstWeek = g.getMinimalDaysInFirstWeek();
+ assertEquals(4, minimalDaysInFirstWeek);
+
+ g = new GregorianCalendar(TimeZone.getTimeZone("Europe/London"),
+ new Locale("fr", "CA"));
+ minimalDaysInFirstWeek = g.getMinimalDaysInFirstWeek();
+ assertEquals(1, minimalDaysInFirstWeek);
+
+ }
+
+ /**
+ * java.util.GregorianCalendar#computeTime()
+ */
+ public void test_computeTime() {
+ // Regression for Harmony-493
+ GregorianCalendar g = new GregorianCalendar(
+ TimeZone.getTimeZone("Europe/London"),
+ new Locale("en", "GB")
+ );
+ g.clear();
+ g.set(2006, Calendar.MARCH, 26, 01, 50, 00);
+ assertEquals(1143337800000L, g.getTimeInMillis());
+
+ GregorianCalendar g1 = new GregorianCalendar(
+ TimeZone.getTimeZone("Europe/Moscow"));
+ g1.clear();
+ g1.set(2006, Calendar.MARCH, 26, 02, 20, 00);
+ assertEquals(1143328800000L, g1.getTimeInMillis());
+ assertEquals(3, g1.get(Calendar.HOUR_OF_DAY));
+ assertEquals(20, g1.get(Calendar.MINUTE));
+
+ g1.clear();
+ g1.set(2006, Calendar.OCTOBER, 29, 02, 50, 00);
+ assertEquals(1162079400000L, g1.getTimeInMillis());
+ assertEquals(2, g1.get(Calendar.HOUR_OF_DAY));
+ assertEquals(50, g1.get(Calendar.MINUTE));
+ // End of regression test
+ }
+
+ /**
+ * java.util.GregorianCalendar#get(int)
+ */
+ @SuppressWarnings("deprecation")
+ public void test_getI() {
+ // Regression test for HARMONY-2959
+ Date date = new Date(Date.parse("Jan 15 00:00:01 GMT 2000"));
+ GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+ gc.setGregorianChange(date);
+ gc.setTimeInMillis(Date.parse("Dec 24 00:00:01 GMT 2000"));
+ assertEquals(346, gc.get(Calendar.DAY_OF_YEAR));
+
+ // Regression test for HARMONY-3003
+ date = new Date(Date.parse("Feb 28 00:00:01 GMT 2000"));
+ gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+ gc.setGregorianChange(date);
+ gc.setTimeInMillis(Date.parse("Dec 1 00:00:01 GMT 2000"));
+ assertEquals(1, gc.get(Calendar.DAY_OF_MONTH));
+ assertEquals(11, gc.get(Calendar.MONTH));
+
+ // Regression test for HARMONY-4513
+ gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+ gc.set(1582, Calendar.OCTOBER, 15, 0, 0, 0);
+ // reset millisecond to zero in order to be the same time as cutover
+ gc.set(Calendar.MILLISECOND, 0);
+ assertEquals(0, gc.get(Calendar.MILLISECOND));
+ assertEquals(1582, gc.get(Calendar.YEAR));
+ assertEquals(Calendar.OCTOBER, gc.get(Calendar.MONTH));
+ assertEquals(15, gc.get(Calendar.DAY_OF_MONTH));
+ assertEquals(0, gc.get(Calendar.HOUR_OF_DAY));
+ assertEquals(0, gc.get(Calendar.MINUTE));
+ assertEquals(0, gc.get(Calendar.SECOND));
+ gc.set(1582, Calendar.OCTOBER, 14, 0, 0, 0);
+ assertEquals(24, gc.get(Calendar.DAY_OF_MONTH));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashMapTest.java
new file mode 100644
index 0000000..26d0a8e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashMapTest.java
@@ -0,0 +1,755 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.support.Support_MapTest2;
+import tests.support.Support_UnmodifiableCollectionTest;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeMap;
+
+public class HashMapTest extends junit.framework.TestCase {
+ class MockMap extends AbstractMap {
+ public Set entrySet() {
+ return Collections.EMPTY_SET;
+ }
+
+ public int size() {
+ return 0;
+ }
+ }
+
+ private static class MockMapNull extends AbstractMap {
+ public Set entrySet() {
+ return null;
+ }
+
+ public int size() {
+ return 10;
+ }
+ }
+
+ interface MockInterface {
+ public String mockMethod();
+ }
+
+ class MockClass implements MockInterface {
+ public String mockMethod() {
+ return "This is a MockClass";
+ }
+ }
+
+ class MockHandler implements InvocationHandler {
+
+ Object obj;
+
+ public MockHandler(Object o) {
+ obj = o;
+ }
+
+ public Object invoke(Object proxy, Method m, Object[] args)
+ throws Throwable {
+ Object result = null;
+
+ try {
+ result = m.invoke(obj, args);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+ }
+
+
+ HashMap hm;
+
+ final static int hmSize = 1000;
+
+ Object[] objArray;
+
+ Object[] objArray2;
+
+ /**
+ * java.util.HashMap#HashMap()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.HashMap()
+ new Support_MapTest2(new HashMap()).runTest();
+
+ HashMap hm2 = new HashMap();
+ assertEquals("Created incorrect HashMap", 0, hm2.size());
+ }
+
+ /**
+ * java.util.HashMap#HashMap(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.HashMap(int)
+ HashMap hm2 = new HashMap(5);
+ assertEquals("Created incorrect HashMap", 0, hm2.size());
+ try {
+ new HashMap(-1);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ HashMap empty = new HashMap(0);
+ assertNull("Empty hashmap access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+ }
+
+ /**
+ * java.util.HashMap#HashMap(int, float)
+ */
+ public void test_ConstructorIF() {
+ // Test for method java.util.HashMap(int, float)
+ HashMap hm2 = new HashMap(5, (float) 0.5);
+ assertEquals("Created incorrect HashMap", 0, hm2.size());
+ try {
+ new HashMap(0, 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ HashMap empty = new HashMap(0, 0.75f);
+ assertNull("Empty hashtable access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+ }
+
+ /**
+ * java.util.HashMap#HashMap(java.util.Map)
+ */
+ public void test_ConstructorLjava_util_Map() {
+ // Test for method java.util.HashMap(java.util.Map)
+ Map myMap = new TreeMap();
+ for (int counter = 0; counter < hmSize; counter++)
+ myMap.put(objArray2[counter], objArray[counter]);
+ HashMap hm2 = new HashMap(myMap);
+ for (int counter = 0; counter < hmSize; counter++)
+ assertTrue("Failed to construct correct HashMap", hm
+ .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+ Map mockMap = new MockMap();
+ hm = new HashMap(mockMap);
+ assertEquals(hm, mockMap);
+ }
+
+ /**
+ * java.util.HashMap#clear()
+ */
+ public void test_clear() {
+ hm.clear();
+ assertEquals("Clear failed to reset size", 0, hm.size());
+ for (int i = 0; i < hmSize; i++)
+ assertNull("Failed to clear all elements",
+ hm.get(objArray2[i]));
+
+ // Check clear on a large loaded map of Integer keys
+ HashMap<Integer, String> map = new HashMap<Integer, String>();
+ for (int i = -32767; i < 32768; i++) {
+ map.put(i, "foobar");
+ }
+ map.clear();
+ assertEquals("Failed to reset size on large integer map", 0, hm.size());
+ for (int i = -32767; i < 32768; i++) {
+ assertNull("Failed to clear integer map values", map.get(i));
+ }
+ }
+
+ /**
+ * java.util.HashMap#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.HashMap.clone()
+ HashMap hm2 = (HashMap) hm.clone();
+ assertTrue("Clone answered equivalent HashMap", hm2 != hm);
+ for (int counter = 0; counter < hmSize; counter++)
+ assertTrue("Clone answered unequal HashMap", hm
+ .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+ HashMap map = new HashMap();
+ map.put("key", "value");
+ // get the keySet() and values() on the original Map
+ Set keys = map.keySet();
+ Collection values = map.values();
+ assertEquals("values() does not work",
+ "value", values.iterator().next());
+ assertEquals("keySet() does not work",
+ "key", keys.iterator().next());
+ AbstractMap map2 = (AbstractMap) map.clone();
+ map2.put("key", "value2");
+ Collection values2 = map2.values();
+ assertTrue("values() is identical", values2 != values);
+ // values() and keySet() on the cloned() map should be different
+ assertEquals("values() was not cloned",
+ "value2", values2.iterator().next());
+ map2.clear();
+ map2.put("key2", "value3");
+ Set key2 = map2.keySet();
+ assertTrue("keySet() is identical", key2 != keys);
+ assertEquals("keySet() was not cloned",
+ "key2", key2.iterator().next());
+
+ // regresion test for HARMONY-4603
+ HashMap hashmap = new HashMap();
+ MockClonable mock = new MockClonable(1);
+ hashmap.put(1, mock);
+ assertEquals(1, ((MockClonable) hashmap.get(1)).i);
+ HashMap hm3 = (HashMap) hashmap.clone();
+ assertEquals(1, ((MockClonable) hm3.get(1)).i);
+ mock.i = 0;
+ assertEquals(0, ((MockClonable) hashmap.get(1)).i);
+ assertEquals(0, ((MockClonable) hm3.get(1)).i);
+ }
+
+ /**
+ * java.util.HashMap#containsKey(java.lang.Object)
+ */
+ public void test_containsKeyLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.HashMap.containsKey(java.lang.Object)
+ assertTrue("Returned false for valid key", hm.containsKey(new Integer(
+ 876).toString()));
+ assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
+
+ HashMap m = new HashMap();
+ m.put(null, "test");
+ assertTrue("Failed with null key", m.containsKey(null));
+ assertTrue("Failed with missing key matching null hash", !m
+ .containsKey(new Integer(0)));
+ }
+
+ /**
+ * java.util.HashMap#containsValue(java.lang.Object)
+ */
+ public void test_containsValueLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.HashMap.containsValue(java.lang.Object)
+ assertTrue("Returned false for valid value", hm
+ .containsValue(new Integer(875)));
+ assertTrue("Returned true for invalid valie", !hm
+ .containsValue(new Integer(-9)));
+ }
+
+ /**
+ * java.util.HashMap#entrySet()
+ */
+ public void test_entrySet() {
+ // Test for method java.util.Set java.util.HashMap.entrySet()
+ Set s = hm.entrySet();
+ Iterator i = s.iterator();
+ assertTrue("Returned set of incorrect size", hm.size() == s.size());
+ while (i.hasNext()) {
+ Map.Entry m = (Map.Entry) i.next();
+ assertTrue("Returned incorrect entry set", hm.containsKey(m
+ .getKey())
+ && hm.containsValue(m.getValue()));
+ }
+
+ Iterator iter = s.iterator();
+ s.remove(iter.next());
+ assertEquals(1001, s.size());
+ }
+
+ /**
+ * java.util.HashMap#entrySet()
+ */
+ public void test_entrySetEquals() {
+ Set s1 = hm.entrySet();
+ Set s2 = new HashMap(hm).entrySet();
+ assertEquals(s1, s2);
+ }
+
+ /**
+ * java.util.HashMap#entrySet()
+ */
+ public void test_removeFromViews() {
+ hm.put("A", null);
+ hm.put("B", null);
+ assertTrue(hm.keySet().remove("A"));
+
+ Map<String, String> m2 = new HashMap<String, String>();
+ m2.put("B", null);
+ assertTrue(hm.entrySet().remove(m2.entrySet().iterator().next()));
+ }
+
+
+ /**
+ * java.util.HashMap#get(java.lang.Object)
+ */
+ public void test_getLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.HashMap.get(java.lang.Object)
+ assertNull("Get returned non-null for non existent key",
+ hm.get("T"));
+ hm.put("T", "HELLO");
+ assertEquals("Get returned incorrect value for existing key", "HELLO", hm.get("T")
+ );
+
+ HashMap m = new HashMap();
+ m.put(null, "test");
+ assertEquals("Failed with null key", "test", m.get(null));
+ assertNull("Failed with missing key matching null hash", m
+ .get(new Integer(0)));
+
+ // Regression for HARMONY-206
+ ReusableKey k = new ReusableKey();
+ HashMap map = new HashMap();
+ k.setKey(1);
+ map.put(k, "value1");
+
+ k.setKey(18);
+ assertNull(map.get(k));
+
+ k.setKey(17);
+ assertNull(map.get(k));
+ }
+
+ /**
+ * java.util.HashMap#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.HashMap.isEmpty()
+ assertTrue("Returned false for new map", new HashMap().isEmpty());
+ assertTrue("Returned true for non-empty", !hm.isEmpty());
+ }
+
+ /**
+ * java.util.HashMap#keySet()
+ */
+ public void test_keySet() {
+ // Test for method java.util.Set java.util.HashMap.keySet()
+ Set s = hm.keySet();
+ assertTrue("Returned set of incorrect size()", s.size() == hm.size());
+ for (int i = 0; i < objArray.length; i++)
+ assertTrue("Returned set does not contain all keys", s
+ .contains(objArray[i].toString()));
+
+ HashMap m = new HashMap();
+ m.put(null, "test");
+ assertTrue("Failed with null key", m.keySet().contains(null));
+ assertNull("Failed with null key", m.keySet().iterator().next());
+
+ Map map = new HashMap(101);
+ map.put(new Integer(1), "1");
+ map.put(new Integer(102), "102");
+ map.put(new Integer(203), "203");
+ Iterator it = map.keySet().iterator();
+ Integer remove1 = (Integer) it.next();
+ it.hasNext();
+ it.remove();
+ Integer remove2 = (Integer) it.next();
+ it.remove();
+ ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
+ new Integer(1), new Integer(102), new Integer(203) }));
+ list.remove(remove1);
+ list.remove(remove2);
+ assertTrue("Wrong result", it.next().equals(list.get(0)));
+ assertEquals("Wrong size", 1, map.size());
+ assertTrue("Wrong contents", map.keySet().iterator().next().equals(
+ list.get(0)));
+
+ Map map2 = new HashMap(101);
+ map2.put(new Integer(1), "1");
+ map2.put(new Integer(4), "4");
+ Iterator it2 = map2.keySet().iterator();
+ Integer remove3 = (Integer) it2.next();
+ Integer next;
+ if (remove3.intValue() == 1)
+ next = new Integer(4);
+ else
+ next = new Integer(1);
+ it2.hasNext();
+ it2.remove();
+ assertTrue("Wrong result 2", it2.next().equals(next));
+ assertEquals("Wrong size 2", 1, map2.size());
+ assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
+ next));
+ }
+
+ /**
+ * java.util.HashMap#put(java.lang.Object, java.lang.Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object() {
+ hm.put("KEY", "VALUE");
+ assertEquals("Failed to install key/value pair", "VALUE", hm.get("KEY"));
+
+ HashMap<Object, Object> m = new HashMap<Object, Object>();
+ m.put(new Short((short) 0), "short");
+ m.put(null, "test");
+ m.put(new Integer(0), "int");
+ assertEquals("Failed adding to bucket containing null", "short", m
+ .get(new Short((short) 0)));
+ assertEquals("Failed adding to bucket containing null2", "int", m
+ .get(new Integer(0)));
+
+ // Check my actual key instance is returned
+ HashMap<Integer, String> map = new HashMap<Integer, String>();
+ for (int i = -32767; i < 32768; i++) {
+ map.put(i, "foobar");
+ }
+ Integer myKey = new Integer(0);
+ // Put a new value at the old key position
+ map.put(myKey, "myValue");
+ assertTrue(map.containsKey(myKey));
+ assertEquals("myValue", map.get(myKey));
+ boolean found = false;
+ for (Iterator<Integer> itr = map.keySet().iterator(); itr.hasNext(); ) {
+ Integer key = itr.next();
+ if (found = key == myKey) {
+ break;
+ }
+ }
+ assertFalse("Should not find new key instance in hashmap", found);
+
+ // Add a new key instance and check it is returned
+ assertNotNull(map.remove(myKey));
+ map.put(myKey, "myValue");
+ assertTrue(map.containsKey(myKey));
+ assertEquals("myValue", map.get(myKey));
+ for (Iterator<Integer> itr = map.keySet().iterator(); itr.hasNext(); ) {
+ Integer key = itr.next();
+ if (found = key == myKey) {
+ break;
+ }
+ }
+ assertTrue("Did not find new key instance in hashmap", found);
+
+ // Ensure keys with identical hashcode are stored separately
+ HashMap<Object, Object> objmap = new HashMap<Object, Object>();
+ for (int i = 0; i < 32768; i++) {
+ objmap.put(i, "foobar");
+ }
+ // Put non-equal object with same hashcode
+ MyKey aKey = new MyKey();
+ assertNull(objmap.put(aKey, "value"));
+ assertNull(objmap.remove(new MyKey()));
+ assertEquals("foobar", objmap.get(0));
+ assertEquals("value", objmap.get(aKey));
+ }
+
+ static class MyKey {
+ public MyKey() {
+ super();
+ }
+
+ public int hashCode() {
+ return 0;
+ }
+ }
+
+ /**
+ * java.util.HashMap#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map() {
+ // Test for method void java.util.HashMap.putAll(java.util.Map)
+ HashMap hm2 = new HashMap();
+ hm2.putAll(hm);
+ for (int i = 0; i < 1000; i++)
+ assertTrue("Failed to clear all elements", hm2.get(
+ new Integer(i).toString()).equals((new Integer(i))));
+
+ Map mockMap = new MockMap();
+ hm2 = new HashMap();
+ hm2.putAll(mockMap);
+ assertEquals("Size should be 0", 0, hm2.size());
+ }
+
+ /**
+ * java.util.HashMap#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map_Null() {
+ HashMap hashMap = new HashMap();
+ try {
+ hashMap.putAll(new MockMapNull());
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ hashMap = new HashMap(new MockMapNull());
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected.
+ }
+ }
+
+ public void test_putAllLjava_util_Map_Resize() {
+ Random rnd = new Random(666);
+
+ Map<Integer,Integer> m1 = new HashMap<Integer, Integer>();
+ int MID = 10000;
+ for (int i = 0; i < MID; i++) {
+ Integer j = rnd.nextInt();
+ m1.put(j, j);
+ }
+
+ Map<Integer,Integer> m2 = new HashMap<Integer, Integer>();
+ int HI = 30000;
+ for (int i = MID; i < HI; i++) {
+ Integer j = rnd.nextInt();
+ m2.put(j, j);
+ }
+
+ m1.putAll(m2);
+
+ rnd = new Random(666);
+ for (int i = 0; i < HI; i++) {
+ Integer j = rnd.nextInt();
+ assertEquals(j, m1.get(j));
+ }
+ }
+
+ /**
+ * java.util.HashMap#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ int size = hm.size();
+ Integer y = new Integer(9);
+ Integer x = ((Integer) hm.remove(y.toString()));
+ assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
+ assertNull("Failed to remove given key", hm.get(new Integer(9)));
+ assertTrue("Failed to decrement size", hm.size() == (size - 1));
+ assertNull("Remove of non-existent key returned non-null", hm
+ .remove("LCLCLC"));
+
+ HashMap m = new HashMap();
+ m.put(null, "test");
+ assertNull("Failed with same hash as null",
+ m.remove(new Integer(0)));
+ assertEquals("Failed with null key", "test", m.remove(null));
+
+ HashMap<Integer, Object> map = new HashMap<Integer, Object>();
+ for (int i = 0; i < 32768; i++) {
+ map.put(i, "const");
+ }
+ Object[] values = new Object[32768];
+ for (int i = 0; i < 32768; i++) {
+ values[i] = new Object();
+ map.put(i, values[i]);
+ }
+ for (int i = 32767; i >= 0; i--) {
+ assertEquals("Failed to remove same value", values[i], map.remove(i));
+ }
+
+ // Ensure keys with identical hashcode are removed properly
+ map = new HashMap<Integer, Object>();
+ for (int i = -32767; i < 32768; i++) {
+ map.put(i, "foobar");
+ }
+ // Remove non equal object with same hashcode
+ assertNull(map.remove(new MyKey()));
+ assertEquals("foobar", map.get(0));
+ map.remove(0);
+ assertNull(map.get(0));
+ }
+
+ /**
+ * java.util.HashMap#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.HashMap.size()
+ assertTrue("Returned incorrect size",
+ hm.size() == (objArray.length + 2));
+ }
+
+ /**
+ * java.util.HashMap#values()
+ */
+ public void test_values() {
+ // Test for method java.util.Collection java.util.HashMap.values()
+ Collection c = hm.values();
+ assertTrue("Returned collection of incorrect size()", c.size() == hm
+ .size());
+ for (int i = 0; i < objArray.length; i++)
+ assertTrue("Returned collection does not contain all keys", c
+ .contains(objArray[i]));
+
+ HashMap myHashMap = new HashMap();
+ for (int i = 0; i < 100; i++)
+ myHashMap.put(objArray2[i], objArray[i]);
+ Collection values = myHashMap.values();
+ new Support_UnmodifiableCollectionTest(
+ "Test Returned Collection From HashMap.values()", values)
+ .runTest();
+ values.remove(new Integer(0));
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myHashMap.containsValue(new Integer(0)));
+
+ }
+
+ /**
+ * java.util.AbstractMap#toString()
+ */
+ public void test_toString() {
+
+ HashMap m = new HashMap();
+ m.put(m, m);
+ String result = m.toString();
+ assertTrue("should contain self ref", result.indexOf("(this") > -1);
+ }
+
+ static class ReusableKey {
+ private int key = 0;
+
+ public void setKey(int key) {
+ this.key = key;
+ }
+
+ public int hashCode() {
+ return key;
+ }
+
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof ReusableKey)) {
+ return false;
+ }
+ return key == ((ReusableKey) o).key;
+ }
+ }
+
+ public void test_Map_Entry_hashCode() {
+ //Related to HARMONY-403
+ HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(10);
+ Integer key = new Integer(1);
+ Integer val = new Integer(2);
+ map.put(key, val);
+ int expected = key.hashCode() ^ val.hashCode();
+ assertEquals(expected, map.hashCode());
+ key = new Integer(4);
+ val = new Integer(8);
+ map.put(key, val);
+ expected += key.hashCode() ^ val.hashCode();
+ assertEquals(expected, map.hashCode());
+ }
+
+ class MockClonable implements Cloneable {
+ public int i;
+
+ public MockClonable(int i) {
+ this.i = i;
+ }
+
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ return new MockClonable(i);
+ }
+ }
+
+ /*
+ * Regression test for HY-4750
+ */
+ public void test_EntrySet() {
+ HashMap map = new HashMap();
+ map.put(new Integer(1), "ONE");
+
+ Set entrySet = map.entrySet();
+ Iterator e = entrySet.iterator();
+ Object real = e.next();
+ Map.Entry copyEntry = new MockEntry();
+ assertEquals(real, copyEntry);
+ assertTrue(entrySet.contains(copyEntry));
+
+ entrySet.remove(copyEntry);
+ assertFalse(entrySet.contains(copyEntry));
+ }
+
+ private static class MockEntry implements Map.Entry {
+
+ public Object getKey() {
+ return new Integer(1);
+ }
+
+ public Object getValue() {
+ return "ONE";
+ }
+
+ public Object setValue(Object object) {
+ return null;
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ objArray = new Object[hmSize];
+ objArray2 = new Object[hmSize];
+ for (int i = 0; i < objArray.length; i++) {
+ objArray[i] = new Integer(i);
+ objArray2[i] = objArray[i].toString();
+ }
+
+ hm = new HashMap();
+ for (int i = 0; i < objArray.length; i++)
+ hm.put(objArray2[i], objArray[i]);
+ hm.put("test", null);
+ hm.put(null, "test");
+ }
+
+ protected void tearDown() {
+ hm = null;
+ objArray = null;
+ objArray2 = null;
+ }
+
+ class SubMap<K, V> extends HashMap<K, V> {
+ public SubMap(Map<? extends K, ? extends V> m) {
+ super(m);
+ }
+
+ public V put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+ HashMap<String, String> hm = new HashMap<String, String>();
+ hm.put("key", "value");
+
+ SerializationTest.verifySelf(hm);
+
+ // regression for HARMONY-1583
+ hm.put(null, "null");
+ SerializationTest.verifySelf(hm);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashSetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashSetTest.java
new file mode 100644
index 0000000..ed9c596
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashSetTest.java
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class HashSetTest extends junit.framework.TestCase {
+
+ HashSet hs;
+
+ Object[] objArray;
+
+ /**
+ * java.util.HashSet#HashSet()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.HashSet()
+ HashSet hs2 = new HashSet();
+ assertEquals("Created incorrect HashSet", 0, hs2.size());
+ }
+
+ /**
+ * java.util.HashSet#HashSet(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.HashSet(int)
+ HashSet hs2 = new HashSet(5);
+ assertEquals("Created incorrect HashSet", 0, hs2.size());
+ try {
+ new HashSet(-1);
+ } catch (IllegalArgumentException e) {
+ return;
+ }
+ fail(
+ "Failed to throw IllegalArgumentException for capacity < 0");
+ }
+
+ /**
+ * java.util.HashSet#HashSet(int, float)
+ */
+ public void test_ConstructorIF() {
+ // Test for method java.util.HashSet(int, float)
+ HashSet hs2 = new HashSet(5, (float) 0.5);
+ assertEquals("Created incorrect HashSet", 0, hs2.size());
+ try {
+ new HashSet(0, 0);
+ } catch (IllegalArgumentException e) {
+ return;
+ }
+ fail(
+ "Failed to throw IllegalArgumentException for initial load factor <= 0");
+ }
+
+ /**
+ * java.util.HashSet#HashSet(java.util.Collection)
+ */
+ public void test_ConstructorLjava_util_Collection() {
+ // Test for method java.util.HashSet(java.util.Collection)
+ HashSet hs2 = new HashSet(Arrays.asList(objArray));
+ for (int counter = 0; counter < objArray.length; counter++)
+ assertTrue("HashSet does not contain correct elements", hs
+ .contains(objArray[counter]));
+ assertTrue("HashSet created from collection incorrect size",
+ hs2.size() == objArray.length);
+
+ try {
+ new HashSet(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.HashSet#add(java.lang.Object)
+ */
+ public void test_addLjava_lang_Object() {
+ // Test for method boolean java.util.HashSet.add(java.lang.Object)
+ int size = hs.size();
+ hs.add(new Integer(8));
+ assertTrue("Added element already contained by set", hs.size() == size);
+ hs.add(new Integer(-9));
+ assertTrue("Failed to increment set size after add",
+ hs.size() == size + 1);
+ assertTrue("Failed to add element to set", hs.contains(new Integer(-9)));
+ }
+
+ /**
+ * java.util.HashSet#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.HashSet.clear()
+ Set orgSet = (Set) hs.clone();
+ hs.clear();
+ Iterator i = orgSet.iterator();
+ assertEquals("Returned non-zero size after clear", 0, hs.size());
+ while (i.hasNext())
+ assertTrue("Failed to clear set", !hs.contains(i.next()));
+ }
+
+ /**
+ * java.util.HashSet#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.HashSet.clone()
+ HashSet hs2 = (HashSet) hs.clone();
+ assertTrue("clone returned an equivalent HashSet", hs != hs2);
+ assertTrue("clone did not return an equal HashSet", hs.equals(hs2));
+ }
+
+ /**
+ * java.util.HashSet#contains(java.lang.Object)
+ */
+ public void test_containsLjava_lang_Object() {
+ // Test for method boolean java.util.HashSet.contains(java.lang.Object)
+ assertTrue("Returned false for valid object", hs.contains(objArray[90]));
+ assertTrue("Returned true for invalid Object", !hs
+ .contains(new Object()));
+
+ HashSet s = new HashSet();
+ s.add(null);
+ assertTrue("Cannot handle null", s.contains(null));
+ }
+
+ /**
+ * java.util.HashSet#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.HashSet.isEmpty()
+ assertTrue("Empty set returned false", new HashSet().isEmpty());
+ assertTrue("Non-empty set returned true", !hs.isEmpty());
+ }
+
+ /**
+ * java.util.HashSet#iterator()
+ */
+ public void test_iterator() {
+ // Test for method java.util.Iterator java.util.HashSet.iterator()
+ Iterator i = hs.iterator();
+ int x = 0;
+ while (i.hasNext()) {
+ assertTrue("Failed to iterate over all elements", hs.contains(i
+ .next()));
+ ++x;
+ }
+ assertTrue("Returned iteration of incorrect size", hs.size() == x);
+
+ HashSet s = new HashSet();
+ s.add(null);
+ assertNull("Cannot handle null", s.iterator().next());
+ }
+
+ /**
+ * java.util.HashSet#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method boolean java.util.HashSet.remove(java.lang.Object)
+ int size = hs.size();
+ hs.remove(new Integer(98));
+ assertTrue("Failed to remove element", !hs.contains(new Integer(98)));
+ assertTrue("Failed to decrement set size", hs.size() == size - 1);
+
+ HashSet s = new HashSet();
+ s.add(null);
+ assertTrue("Cannot handle null", s.remove(null));
+ assertFalse(hs.remove(new Integer(-98)));
+ }
+
+ /**
+ * java.util.HashSet#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.HashSet.size()
+ assertTrue("Returned incorrect size", hs.size() == (objArray.length + 1));
+ hs.clear();
+ assertEquals("Cleared set returned non-zero size", 0, hs.size());
+ }
+
+ /**
+ * java.util.HashSet#SerializationTest
+ */
+ public void test_Serialization() throws Exception{
+ HashSet<String> hs = new HashSet<String>();
+ hs.add("hello");
+ hs.add("world");
+ SerializationTest.verifySelf(hs, comparator);
+ SerializationTest.verifyGolden(this, hs, comparator);
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ objArray = new Object[1000];
+ for (int i = 0; i < objArray.length; i++) {
+ objArray[i] = new Integer(i);
+ }
+
+ hs = new HashSet();
+ for (int i = 0; i < objArray.length; i++) {
+ hs.add(objArray[i]);
+ }
+
+ hs.add(null);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ hs = null;
+ objArray = null;
+ }
+
+ private static final SerializationTest.SerializableAssert comparator = new
+ SerializationTest.SerializableAssert() {
+ public void assertDeserialized(Serializable initial, Serializable deserialized) {
+ HashSet<String> initialHs = (HashSet<String>) initial;
+ HashSet<String> deseriaHs = (HashSet<String>) deserialized;
+ assertEquals("should be equal", initialHs.size(), deseriaHs.size());
+ assertEquals("should be equal", initialHs, deseriaHs);
+ }
+
+ };
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashtableTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashtableTest.java
new file mode 100644
index 0000000..2c81f65
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/HashtableTest.java
@@ -0,0 +1,935 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import tests.support.Support_MapTest2;
+import tests.support.Support_UnmodifiableCollectionTest;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Vector;
+
+public class HashtableTest extends junit.framework.TestCase {
+
+ private Hashtable ht10;
+
+ private Hashtable ht100;
+
+ private Hashtable htfull;
+
+ private Vector keyVector;
+
+ private Vector elmVector;
+
+ private String h10sVal;
+
+ /**
+ * java.util.Hashtable#Hashtable()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.Hashtable()
+ new Support_MapTest2(new Hashtable()).runTest();
+
+ Hashtable h = new Hashtable();
+
+ assertEquals("Created incorrect hashtable", 0, h.size());
+ }
+
+ /**
+ * java.util.Hashtable#Hashtable(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.Hashtable(int)
+ Hashtable h = new Hashtable(9);
+
+ assertEquals("Created incorrect hashtable", 0, h.size());
+
+ Hashtable empty = new Hashtable(0);
+ assertNull("Empty hashtable access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+ }
+
+ /**
+ * java.util.Hashtable#Hashtable(int, float)
+ */
+ public void test_ConstructorIF() {
+ // Test for method java.util.Hashtable(int, float)
+ Hashtable h = new java.util.Hashtable(10, 0.5f);
+ assertEquals("Created incorrect hashtable", 0, h.size());
+
+ Hashtable empty = new Hashtable(0, 0.75f);
+ assertNull("Empty hashtable access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+
+ try {
+ new Hashtable(-1, 0.75f);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new Hashtable(0, -0.75f);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Hashtable#Hashtable(java.util.Map)
+ */
+ public void test_ConstructorLjava_util_Map() {
+ // Test for method java.util.Hashtable(java.util.Map)
+ Map map = new TreeMap();
+ Object firstVal = "Gabba";
+ Object secondVal = new Integer(5);
+ map.put("Gah", firstVal);
+ map.put("Ooga", secondVal);
+ Hashtable ht = new Hashtable(map);
+ assertTrue("a) Incorrect Hashtable constructed",
+ ht.get("Gah") == firstVal);
+ assertTrue("b) Incorrect Hashtable constructed",
+ ht.get("Ooga") == secondVal);
+
+ try {
+ new Hashtable(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ public void test_HashTable_Constructor() {
+ Hashtable hashTable = new Hashtable();
+ hashTable.put(hashTable, hashTable.keySet());
+ new Hashtable(hashTable);
+ }
+
+ /**
+ * java.util.Hashtable#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.Hashtable.clear()
+ Hashtable h = hashtableClone(htfull);
+ h.clear();
+ assertEquals("Hashtable was not cleared", 0, h.size());
+ Enumeration el = h.elements();
+ Enumeration keys = h.keys();
+ assertTrue("Hashtable improperly cleared", !el.hasMoreElements()
+ && !(keys.hasMoreElements()));
+ }
+
+ /**
+ * java.util.Hashtable#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.Hashtable.clone()
+
+ Hashtable h = (Hashtable) htfull.clone();
+ assertTrue("Clone different size than original", h.size() == htfull
+ .size());
+
+ Enumeration org = htfull.keys();
+ Enumeration cpy = h.keys();
+
+ String okey, ckey;
+ while (org.hasMoreElements()) {
+ assertTrue("Key comparison failed", (okey = (String) org
+ .nextElement()).equals(ckey = (String) cpy.nextElement()));
+ assertTrue("Value comparison failed", ((String) htfull.get(okey))
+ .equals((String) h.get(ckey)));
+ }
+ assertTrue("Copy has more keys than original", !cpy.hasMoreElements());
+ }
+
+ /**
+ * java.util.Hashtable#contains(java.lang.Object)
+ */
+ public void test_containsLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.Hashtable.contains(java.lang.Object)
+ assertTrue("Element not found", ht10.contains("Val 7"));
+ assertTrue("Invalid element found", !ht10.contains("ZZZZZZZZZZZZZZZZ"));
+
+ try {
+ ht10.contains(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Hashtable#containsKey(java.lang.Object)
+ */
+ public void test_containsKeyLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.Hashtable.containsKey(java.lang.Object)
+
+ assertTrue("Failed to find key", htfull.containsKey("FKey 4"));
+ assertTrue("Failed to find key", !htfull.containsKey("FKey 99"));
+
+ try {
+ htfull.containsKey(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Hashtable#containsValue(java.lang.Object)
+ */
+ public void test_containsValueLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.Hashtable.containsValue(java.lang.Object)
+ Enumeration e = elmVector.elements();
+ while (e.hasMoreElements())
+ assertTrue("Returned false for valid value", ht10.containsValue(e
+ .nextElement()));
+ assertTrue("Returned true for invalid value", !ht10
+ .containsValue(new Object()));
+
+ try {
+ ht10.containsValue(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Hashtable#elements()
+ */
+ public void test_elements() {
+ // Test for method java.util.Enumeration java.util.Hashtable.elements()
+ Enumeration elms = ht10.elements();
+ int i = 0;
+ while (elms.hasMoreElements()) {
+ String s = (String) elms.nextElement();
+ assertTrue("Missing key from enumeration", elmVector.contains(s));
+ ++i;
+ }
+
+ assertEquals("All keys not retrieved", 10, ht10.size());
+
+ assertFalse(elms.hasMoreElements());
+ try {
+ elms.nextElement();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+// BEGIN android-removed
+// implementation dependent
+// /**
+// * java.util.Hashtable#elements()
+// */
+// public void test_elements_subtest0() {
+// // this is the reference implementation behavior
+// final Hashtable ht = new Hashtable(7);
+// ht.put("1", "a");
+// // these three elements hash to the same bucket in a 7 element Hashtable
+// ht.put("2", "b");
+// ht.put("9", "c");
+// ht.put("12", "d");
+// // Hashtable looks like:
+// // 0: "1"
+// // 1: "12" -> "9" -> "2"
+// Enumeration en = ht.elements();
+// // cache the first entry
+// en.hasMoreElements();
+// ht.remove("12");
+// ht.remove("9");
+// boolean exception = false;
+// try {
+// // cached "12"
+// Object result = en.nextElement();
+// assertNull("unexpected: " + result, result);
+// // next is removed "9"
+// result = en.nextElement();
+// assertNull("unexpected: " + result, result);
+// result = en.nextElement();
+// assertTrue("unexpected: " + result, "b".equals(result));
+// } catch (NoSuchElementException e) {
+// exception = true;
+// }
+// assertTrue("unexpected NoSuchElementException", !exception);
+// }
+// END android-removed
+
+ /**
+ * java.util.Hashtable#entrySet()
+ */
+ public void test_entrySet() {
+ // Test for method java.util.Set java.util.Hashtable.entrySet()
+ Set s = ht10.entrySet();
+ Set s2 = new HashSet();
+ Iterator i = s.iterator();
+ while (i.hasNext())
+ s2.add(((Map.Entry) i.next()).getValue());
+ Enumeration e = elmVector.elements();
+ while (e.hasMoreElements())
+ assertTrue("Returned incorrect entry set", s2.contains(e
+ .nextElement()));
+// BEGIN android-removed
+// implementation dependent
+// assertEquals("Not synchronized",
+// "java.util.Collections$SynchronizedSet", s.getClass().getName());
+// END android-removed
+
+ boolean exception = false;
+ try {
+ ((Map.Entry) ht10.entrySet().iterator().next()).setValue(null);
+ } catch (NullPointerException e1) {
+ exception = true;
+ }
+ assertTrue(
+ "Should not be able to assign null to a Hashtable entrySet() Map.Entry",
+ exception);
+ }
+
+ /**
+ * java.util.Hashtable#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean java.util.Hashtable.equals(java.lang.Object)
+ Hashtable h = hashtableClone(ht10);
+ assertTrue("Returned false for equal tables", ht10.equals(h));
+ assertTrue("Returned true for unequal tables", !ht10.equals(htfull));
+ }
+
+ /**
+ * java.util.Hashtable#get(java.lang.Object)
+ */
+ public void test_getLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.Hashtable.get(java.lang.Object)
+ Hashtable h = hashtableClone(htfull);
+ assertEquals("Could not retrieve element", "FVal 2", ((String) h.get("FKey 2"))
+ );
+
+// BEGIN android-removed
+// implementation dependent
+// // Regression for HARMONY-262
+// ReusableKey k = new ReusableKey();
+// Hashtable h2 = new Hashtable();
+// k.setKey(1);
+// h2.put(k, "value1");
+//
+// k.setKey(13);
+// assertNull(h2.get(k));
+//
+// k.setKey(12);
+// assertNull(h2.get(k));
+//
+// try {
+// h2.get(null);
+// fail("NullPointerException expected");
+// } catch (NullPointerException e) {
+// //expected
+// }
+// END android-removed
+ }
+
+ /**
+ * java.util.Hashtable#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.util.Hashtable.hashCode()
+ Set entrySet = ht10.entrySet();
+ Iterator iterator = entrySet.iterator();
+ int expectedHash;
+ for (expectedHash = 0; iterator.hasNext(); expectedHash += iterator
+ .next().hashCode())
+ ;
+ assertTrue("Incorrect hashCode returned. Wanted: " + expectedHash
+ + " got: " + ht10.hashCode(), expectedHash == ht10.hashCode());
+ }
+
+ /**
+ * java.util.Hashtable#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.Hashtable.isEmpty()
+
+ assertTrue("isEmpty returned incorrect value", !ht10.isEmpty());
+ assertTrue("isEmpty returned incorrect value",
+ new java.util.Hashtable().isEmpty());
+
+ final Hashtable ht = new Hashtable();
+ ht.put("0", "");
+ Thread t1 = new Thread() {
+ public void run() {
+ while (!ht.isEmpty())
+ ;
+ ht.put("final", "");
+ }
+ };
+ t1.start();
+ for (int i = 1; i < 10000; i++) {
+ synchronized (ht) {
+ ht.remove(String.valueOf(i - 1));
+ ht.put(String.valueOf(i), "");
+ }
+ int size;
+ if ((size = ht.size()) != 1) {
+ String result = "Size is not 1: " + size + " " + ht;
+ // terminate the thread
+ ht.clear();
+ fail(result);
+ }
+ }
+ // terminate the thread
+ ht.clear();
+ }
+
+ /**
+ * java.util.Hashtable#keys()
+ */
+ public void test_keys() {
+ // Test for method java.util.Enumeration java.util.Hashtable.keys()
+
+ Enumeration keys = ht10.keys();
+ int i = 0;
+ while (keys.hasMoreElements()) {
+ String s = (String) keys.nextElement();
+ assertTrue("Missing key from enumeration", keyVector.contains(s));
+ ++i;
+ }
+
+ assertEquals("All keys not retrieved", 10, ht10.size());
+
+ assertFalse(keys.hasMoreElements());
+ try {
+ keys.nextElement();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.Hashtable#keys()
+ */
+ public void test_keys_subtest0() {
+ // this is the reference implementation behavior
+ final Hashtable ht = new Hashtable(3);
+ ht.put("initial", "");
+ Enumeration en = ht.keys();
+ en.hasMoreElements();
+ ht.remove("initial");
+ boolean exception = false;
+ try {
+ Object result = en.nextElement();
+ assertTrue("unexpected: " + result, "initial".equals(result));
+ } catch (NoSuchElementException e) {
+ exception = true;
+ }
+ assertTrue("unexpected NoSuchElementException", !exception);
+ }
+
+ /**
+ * java.util.Hashtable#keySet()
+ */
+ public void test_keySet() {
+ // Test for method java.util.Set java.util.Hashtable.keySet()
+ Set s = ht10.keySet();
+ Enumeration e = keyVector.elements();
+ while (e.hasMoreElements())
+ assertTrue("Returned incorrect key set", s
+ .contains(e.nextElement()));
+
+// BEGIN android-removed
+// implementation dependent
+// assertEquals("Not synchronized",
+// "java.util.Collections$SynchronizedSet", s.getClass().getName());
+// END android-removed
+
+ Map map = new Hashtable(101);
+ map.put(new Integer(1), "1");
+ map.put(new Integer(102), "102");
+ map.put(new Integer(203), "203");
+ Iterator it = map.keySet().iterator();
+ Integer remove1 = (Integer) it.next();
+ it.remove();
+ Integer remove2 = (Integer) it.next();
+ it.remove();
+ ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
+ new Integer(1), new Integer(102), new Integer(203) }));
+ list.remove(remove1);
+ list.remove(remove2);
+ assertTrue("Wrong result", it.next().equals(list.get(0)));
+ assertEquals("Wrong size", 1, map.size());
+ assertTrue("Wrong contents", map.keySet().iterator().next().equals(
+ list.get(0)));
+
+ Map map2 = new Hashtable(101);
+ map2.put(new Integer(1), "1");
+ map2.put(new Integer(4), "4");
+ Iterator it2 = map2.keySet().iterator();
+ Integer remove3 = (Integer) it2.next();
+ Integer next;
+ if (remove3.intValue() == 1)
+ next = new Integer(4);
+ else
+ next = new Integer(1);
+ it2.hasNext();
+ it2.remove();
+ assertTrue("Wrong result 2", it2.next().equals(next));
+ assertEquals("Wrong size 2", 1, map2.size());
+ assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
+ next));
+ }
+
+ /**
+ * java.util.Hashtable#keySet()
+ */
+ public void test_keySet_subtest0() {
+ Set s1 = ht10.keySet();
+ assertTrue("should contain key", s1.remove("Key 0"));
+ assertTrue("should not contain key", !s1.remove("Key 0"));
+
+ final int iterations = 10000;
+ final Hashtable ht = new Hashtable();
+ Thread t1 = new Thread() {
+ public void run() {
+ for (int i = 0; i < iterations; i++) {
+ ht.put(String.valueOf(i), "");
+ ht.remove(String.valueOf(i));
+ }
+ }
+ };
+ t1.start();
+ Set set = ht.keySet();
+ for (int i = 0; i < iterations; i++) {
+ Iterator it = set.iterator();
+ try {
+ it.next();
+ it.remove();
+ int size;
+ // ensure removing with the iterator doesn't corrupt the
+ // Hashtable
+ if ((size = ht.size()) < 0) {
+ fail("invalid size: " + size);
+ }
+ } catch (NoSuchElementException e) {
+ } catch (ConcurrentModificationException e) {
+ }
+ }
+ }
+
+// BEGIN android-removed
+// implementation dependent
+// /**
+// * java.util.Hashtable#keySet()
+// */
+// public void test_keySet_subtest1() {
+// // this is the reference implementation behavior
+// final Hashtable ht = new Hashtable(7);
+// ht.put("1", "a");
+// // these three elements hash to the same bucket in a 7 element Hashtable
+// ht.put("2", "b");
+// ht.put("9", "c");
+// ht.put("12", "d");
+// // Hashtable looks like:
+// // 0: "1"
+// // 1: "12" -> "9" -> "2"
+// Enumeration en = ht.elements();
+// // cache the first entry
+// en.hasMoreElements();
+// Iterator it = ht.keySet().iterator();
+// // this is mostly a copy of the test in test_elements_subtest0()
+// // test removing with the iterator does not null the values
+// while (it.hasNext()) {
+// String key = (String) it.next();
+// if ("12".equals(key) || "9".equals(key)) {
+// it.remove();
+// }
+// }
+// it.remove();
+// boolean exception = false;
+// try {
+// // cached "12"
+// Object result = en.nextElement();
+// assertTrue("unexpected: " + result, "d".equals(result));
+// // next is removed "9"
+// result = en.nextElement();
+// assertTrue("unexpected: " + result, "c".equals(result));
+// result = en.nextElement();
+// assertTrue("unexpected: " + result, "b".equals(result));
+// } catch (NoSuchElementException e) {
+// exception = true;
+// }
+// assertTrue("unexpected NoSuchElementException", !exception);
+// }
+// END android-removed
+
+ /**
+ * java.util.Hashtable#put(java.lang.Object, java.lang.Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.Hashtable.put(java.lang.Object, java.lang.Object)
+ Hashtable h = hashtableClone(ht100);
+ Integer key = new Integer(100);
+ h.put("Value 100", key);
+ assertTrue("Key/Value not inserted", h.size() == 1 && (h.contains(key)));
+
+ // Put into "full" table
+ h = hashtableClone(htfull);
+ h.put("Value 100", key);
+ assertTrue("Key/Value not inserted into full table", h.size() == 8
+ && (h.contains(key)));
+
+ try {
+ h.put(null, key);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ try {
+ h.put("Value 100", null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Hashtable#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map() {
+ // Test for method void java.util.Hashtable.putAll(java.util.Map)
+ Hashtable h = new Hashtable();
+ h.putAll(ht10);
+ Enumeration e = keyVector.elements();
+ while (e.hasMoreElements()) {
+ Object x = e.nextElement();
+ assertTrue("Failed to put all elements", h.get(x).equals(
+ ht10.get(x)));
+ }
+
+ try {
+ h.putAll(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Hashtable#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.Hashtable.remove(java.lang.Object)
+ Hashtable h = hashtableClone(htfull);
+ Object k = h.remove("FKey 0");
+ assertTrue("Remove failed", !h.containsKey("FKey 0") || k == null);
+ assertNull(h.remove("FKey 0"));
+
+ try {
+ h.remove(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ public void test_HashTable_remove_scenario1() {
+ Hashtable hashTable = new Hashtable();
+ Set keySet = hashTable.keySet();
+ hashTable.put(hashTable, keySet);
+ hashTable.remove(hashTable);
+ }
+
+ public void test_HashTable_remove_scenario2() {
+ Hashtable hashTable = new Hashtable();
+ Set keySet = hashTable.keySet();
+ hashTable.put(hashTable, hashTable);
+ hashTable.remove(hashTable);
+ }
+
+ public void test_HashTable_remove_scenario3() {
+ Hashtable hashTable = new Hashtable();
+ Hashtable keyHashTable = new Hashtable();
+ keyHashTable.put(hashTable, keyHashTable);
+ hashTable.put(keyHashTable, hashTable);
+ hashTable.remove(keyHashTable);
+ }
+
+ /**
+ * java.util.Hashtable#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.Hashtable.size()
+ assertTrue("Returned invalid size", ht10.size() == 10
+ && (ht100.size() == 0));
+
+ final Hashtable ht = new Hashtable();
+ ht.put("0", "");
+ Thread t1 = new Thread() {
+ public void run() {
+ while (ht.size() > 0)
+ ;
+ ht.put("final", "");
+ }
+ };
+ t1.start();
+ for (int i = 1; i < 10000; i++) {
+ synchronized (ht) {
+ ht.remove(String.valueOf(i - 1));
+ ht.put(String.valueOf(i), "");
+ }
+ int size;
+ if ((size = ht.size()) != 1) {
+ String result = "Size is not 1: " + size + " " + ht;
+ // terminate the thread
+ ht.clear();
+ fail(result);
+ }
+ }
+ // terminate the thread
+ ht.clear();
+ }
+
+ /**
+ * java.util.Hashtable#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.util.Hashtable.toString()
+ Hashtable h = new Hashtable();
+ assertEquals("Incorrect toString for Empty table",
+ "{}", h.toString());
+
+ h.put("one", "1");
+ h.put("two", h);
+ h.put(h, "3");
+ h.put(h, h);
+ String result = h.toString();
+ assertTrue("should contain self ref", result.indexOf("(this") > -1);
+ }
+
+ /**
+ * java.util.Hashtable#values()
+ */
+ public void test_values() {
+ // Test for method java.util.Collection java.util.Hashtable.values()
+ Collection c = ht10.values();
+ Enumeration e = elmVector.elements();
+ while (e.hasMoreElements())
+ assertTrue("Returned incorrect values", c.contains(e.nextElement()));
+
+// BEGIN android-removed
+// implementation dependent
+// assertEquals("Not synchronized",
+// "java.util.Collections$SynchronizedCollection", c.getClass().getName());
+// END android-removed
+
+ Hashtable myHashtable = new Hashtable();
+ for (int i = 0; i < 100; i++)
+ myHashtable.put(new Integer(i), new Integer(i));
+ Collection values = myHashtable.values();
+ new Support_UnmodifiableCollectionTest(
+ "Test Returned Collection From Hashtable.values()", values)
+ .runTest();
+ values.remove(new Integer(0));
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myHashtable.containsValue(new Integer(0)));
+ }
+
+ /**
+ * Regression Test for JIRA 2181
+ */
+ public void test_entrySet_remove() {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put("my.nonexistent.prop", "AAA");
+ hashtable.put("parse.error", "BBB");
+ Iterator<Map.Entry<String, String>> iterator =
+ hashtable.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = iterator.next();
+ final Object value = entry.getValue();
+ if (value.equals("AAA")) {
+ iterator.remove();
+ }
+ }
+ assertFalse(hashtable.containsKey("my.nonexistent.prop"));
+ }
+
+ class Mock_Hashtable extends Hashtable {
+ boolean flag = false;
+
+ public Mock_Hashtable(int i) {
+ super(i);
+ }
+
+ @Override
+ protected void rehash() {
+ flag = true;
+ super.rehash();
+ }
+
+ public boolean isRehashed() {
+ return flag;
+ }
+ }
+
+ public void test_rehash() {
+ Mock_Hashtable mht = new Mock_Hashtable(5);
+
+ assertFalse(mht.isRehashed());
+ for(int i = 0; i < 10; i++) {
+ mht.put(i, "New value");
+ }
+ assertTrue(mht.isRehashed());
+ }
+
+ /**
+ * java.util.Hashtable#elements()
+ * java.util.Hashtable#keys()
+ * java.util.Hashtable#keySet()
+ */
+ public void test_keys_elements_keySet_Exceptions() {
+ Hashtable hashTable = new Hashtable();
+ String key = "key";
+ String value = "value";
+ hashTable.put(key, value);
+
+ Enumeration enumeration = hashTable.keys();
+ assertTrue(enumeration.hasMoreElements());
+ enumeration.nextElement();
+ assertFalse(enumeration.hasMoreElements());
+
+ enumeration = hashTable.elements();
+ assertTrue(enumeration.hasMoreElements());
+ enumeration.nextElement();
+ assertFalse(enumeration.hasMoreElements());
+
+ Iterator iterator = hashTable.keySet().iterator();
+ assertTrue(iterator.hasNext());
+ try {
+ iterator.remove();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // Expected
+ }
+ iterator.next();
+ iterator.remove();
+ assertFalse(iterator.hasNext());
+
+ hashTable.clear();
+ for (int i = 0; i < 10; i++) {
+ hashTable.put(key + i, value + i);
+ }
+
+ enumeration = hashTable.keys();
+ assertTrue(enumeration.hasMoreElements());
+ for (int i = 0; i < 10; i++) {
+ enumeration.nextElement();
+ }
+ assertFalse(enumeration.hasMoreElements());
+ try {
+ enumeration.nextElement();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ enumeration = hashTable.elements();
+ assertTrue(enumeration.hasMoreElements());
+ for (int i = 0; i < 10; i++) {
+ enumeration.nextElement();
+ }
+ assertFalse(enumeration.hasMoreElements());
+ try {
+ enumeration.nextElement();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ iterator = hashTable.keySet().iterator();
+ assertTrue(iterator.hasNext());
+ for (int i = 0; i < 10; i++) {
+ iterator.next();
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ protected Hashtable hashtableClone(Hashtable s) {
+ return (Hashtable) s.clone();
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+
+ ht10 = new Hashtable(10);
+ ht100 = new Hashtable(100);
+ htfull = new Hashtable(10);
+ keyVector = new Vector(10);
+ elmVector = new Vector(10);
+
+ for (int i = 0; i < 10; i++) {
+ ht10.put("Key " + i, "Val " + i);
+ keyVector.addElement("Key " + i);
+ elmVector.addElement("Val " + i);
+ }
+
+ for (int i = 0; i < 7; i++)
+ htfull.put("FKey " + i, "FVal " + i);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ ht10 = null;
+ ht100 = null;
+ htfull = null;
+ keyVector = null;
+ elmVector = null;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IdentityHashMap2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IdentityHashMap2Test.java
new file mode 100644
index 0000000..7882077
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IdentityHashMap2Test.java
@@ -0,0 +1,467 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.support.Support_MapTest2;
+import java.io.Serializable;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+public class IdentityHashMap2Test extends junit.framework.TestCase {
+ private static final String ID = "hello";
+
+ class MockMap extends AbstractMap {
+ public Set entrySet() {
+ return null;
+ }
+
+ public int size() {
+ return 0;
+ }
+ }
+ private IdentityHashMap hm;
+
+ private final static int hmSize = 20;
+
+ private Object[] objArray;
+
+ private Object[] objArray2;
+
+ /**
+ * java.util.IdentityHashMap#IdentityHashMap()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.IdentityHashMap()
+ new Support_MapTest2(new IdentityHashMap()).runTest();
+
+ IdentityHashMap hm2 = new IdentityHashMap();
+ assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
+ }
+
+ /**
+ * java.util.IdentityHashMap#IdentityHashMap(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.IdentityHashMap(int)
+ IdentityHashMap hm2 = new IdentityHashMap(5);
+ assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
+ try {
+ new IdentityHashMap(-1);
+ } catch (IllegalArgumentException e) {
+ return;
+ }
+ fail(
+ "Failed to throw IllegalArgumentException for initial capacity < 0");
+
+ IdentityHashMap empty = new IdentityHashMap(0);
+ assertNull("Empty IdentityHashMap access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+ }
+
+ /**
+ * java.util.IdentityHashMap#IdentityHashMap(java.util.Map)
+ */
+ public void test_ConstructorLjava_util_Map() {
+ // Test for method java.util.IdentityHashMap(java.util.Map)
+ Map myMap = new TreeMap();
+ for (int counter = 0; counter < hmSize; counter++)
+ myMap.put(objArray2[counter], objArray[counter]);
+ IdentityHashMap hm2 = new IdentityHashMap(myMap);
+ for (int counter = 0; counter < hmSize; counter++)
+ assertTrue("Failed to construct correct IdentityHashMap", hm
+ .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+ Map mockMap = new MockMap();
+ hm2 = new IdentityHashMap(mockMap);
+ assertEquals("Size should be 0", 0, hm2.size());
+ }
+
+ public void test_IdentityHashMap_Constructor_BigSize() {
+ try {
+ new IdentityHashMap(Integer.MAX_VALUE);
+ fail("should throw OutOfMemoryError");
+ } catch (OutOfMemoryError e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.IdentityHashMap#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.IdentityHashMap.clear()
+ hm.clear();
+ assertEquals("Clear failed to reset size", 0, hm.size());
+ for (int i = 0; i < hmSize; i++)
+ assertNull("Failed to clear all elements",
+ hm.get(objArray2[i]));
+
+ }
+
+ /**
+ * java.util.IdentityHashMap#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.IdentityHashMap.clone()
+ IdentityHashMap hm2 = (IdentityHashMap) hm.clone();
+ assertTrue("Clone answered equivalent IdentityHashMap", hm2 != hm);
+ for (int counter = 0; counter < hmSize; counter++)
+ assertTrue("Clone answered unequal IdentityHashMap", hm
+ .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+ IdentityHashMap map = new IdentityHashMap();
+ map.put("key", "value");
+ // get the keySet() and values() on the original Map
+ Set keys = map.keySet();
+ Collection values = map.values();
+ assertSame("values() does not work",
+ "value", values.iterator().next());
+ assertSame("keySet() does not work",
+ "key", keys.iterator().next());
+ AbstractMap map2 = (AbstractMap) map.clone();
+ map2.put("key", "value2");
+ Collection values2 = map2.values();
+ assertTrue("values() is identical", values2 != values);
+ // values() and keySet() on the cloned() map should be different
+ assertEquals("values() was not cloned",
+ "value2", values2.iterator().next());
+ map2.clear();
+ map2.put("key2", "value3");
+ Set key2 = map2.keySet();
+ assertTrue("keySet() is identical", key2 != keys);
+ assertSame("keySet() was not cloned",
+ "key2", key2.iterator().next());
+ }
+
+ /**
+ * java.util.IdentityHashMap#containsKey(java.lang.Object)
+ */
+ public void test_containsKeyLjava_lang_Object() {
+ IdentityHashMap m = new IdentityHashMap();
+ m.put(null, "test");
+ assertTrue("Failed with null key", m.containsKey(null));
+ assertFalse("Failed with missing key matching null hash", m.containsKey(new Integer(0)));
+ }
+
+ public static class TestKey implements Cloneable {
+ private final String foo;
+
+ TestKey(String foo) {
+ this.foo = foo;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof TestKey && foo.equals(((TestKey) o).foo);
+ }
+
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+ }
+
+ public void test_containsKey_copies() throws Exception {
+ TestKey a = new TestKey("a");
+ hm.put(a, new Object());
+ assertTrue(hm.containsKey(a));
+ assertFalse(hm.containsKey(a.clone()));
+ }
+
+ /**
+ * java.util.IdentityHashMap#containsValue(java.lang.Object)
+ */
+ public void test_containsValueLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.IdentityHashMap.containsValue(java.lang.Object)
+ assertTrue("Returned false for valid value", hm
+ .containsValue(objArray[19]));
+ assertTrue("Returned true for invalid valie", !hm
+ .containsValue(new Integer(-9)));
+ }
+
+ /**
+ * java.util.IdentityHashMap#entrySet()
+ */
+ public void test_entrySet() {
+ // Test for method java.util.Set java.util.IdentityHashMap.entrySet()
+ Set s = hm.entrySet();
+ Iterator i = s.iterator();
+ assertTrue("Returned set of incorrect size", hm.size() == s.size());
+ while (i.hasNext()) {
+ Map.Entry m = (Map.Entry) i.next();
+ assertTrue("Returned incorrect entry set", hm.containsKey(m
+ .getKey())
+ && hm.containsValue(m.getValue()));
+ }
+ }
+
+ /**
+ * java.util.IdentityHashMap#get(java.lang.Object)
+ */
+ public void test_getLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.IdentityHashMap.get(java.lang.Object)
+ assertNull("Get returned non-null for non existent key",
+ hm.get("T"));
+ hm.put("T", "HELLO");
+ assertEquals("Get returned incorecct value for existing key", "HELLO", hm.get("T"));
+
+ IdentityHashMap m = new IdentityHashMap();
+ m.put(null, "test");
+ assertEquals("Failed with null key", "test", m.get(null));
+ assertNull("Failed with missing key matching null hash", m
+ .get(new Integer(0)));
+ }
+
+ /**
+ * java.util.IdentityHashMap#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.IdentityHashMap.isEmpty()
+ assertTrue("Returned false for new map", new IdentityHashMap()
+ .isEmpty());
+ assertTrue("Returned true for non-empty", !hm.isEmpty());
+ }
+
+ /**
+ * java.util.IdentityHashMap#keySet()
+ */
+ public void test_keySet() {
+ // Test for method java.util.Set java.util.IdentityHashMap.keySet()
+ Set s = hm.keySet();
+ assertTrue("Returned set of incorrect size()", s.size() == hm.size());
+ for (int i = 0; i < objArray.length; i++) {
+ assertTrue("Returned set does not contain all keys", s
+ .contains(objArray2[i]));
+ }
+
+ IdentityHashMap m = new IdentityHashMap();
+ m.put(null, "test");
+ assertTrue("Failed with null key", m.keySet().contains(null));
+ assertNull("Failed with null key", m.keySet().iterator().next());
+
+ Map map = new IdentityHashMap(101);
+ map.put(new Integer(1), "1");
+ map.put(new Integer(102), "102");
+ map.put(new Integer(203), "203");
+ Iterator it = map.keySet().iterator();
+ Integer remove1 = (Integer) it.next();
+ it.hasNext();
+ it.remove();
+ Integer remove2 = (Integer) it.next();
+ it.remove();
+ ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
+ new Integer(1), new Integer(102), new Integer(203) }));
+ list.remove(remove1);
+ list.remove(remove2);
+ assertTrue("Wrong result", it.next().equals(list.get(0)));
+ assertEquals("Wrong size", 1, map.size());
+ assertTrue("Wrong contents", map.keySet().iterator().next().equals(
+ list.get(0)));
+
+ Map map2 = new IdentityHashMap(101);
+ map2.put(new Integer(1), "1");
+ map2.put(new Integer(4), "4");
+ Iterator it2 = map2.keySet().iterator();
+ Integer remove3 = (Integer) it2.next();
+ Integer next;
+ if (remove3.intValue() == 1)
+ next = new Integer(4);
+ else
+ next = new Integer(1);
+ it2.hasNext();
+ it2.remove();
+ assertTrue("Wrong result 2", it2.next().equals(next));
+ assertEquals("Wrong size 2", 1, map2.size());
+ assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
+ next));
+ }
+
+ /**
+ * java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.IdentityHashMap.put(java.lang.Object, java.lang.Object)
+ hm.put("KEY", "VALUE");
+ assertEquals("Failed to install key/value pair",
+ "VALUE", hm.get("KEY"));
+
+ IdentityHashMap m = new IdentityHashMap();
+ Short s0 = new Short((short) 0);
+ m.put(s0, "short");
+ m.put(null, "test");
+ Integer i0 = new Integer(0);
+ m.put(i0, "int");
+ assertEquals("Failed adding to bucket containing null",
+ "short", m.get(s0));
+ assertEquals("Failed adding to bucket containing null2", "int", m.get(i0)
+ );
+ }
+
+ /**
+ * java.util.IdentityHashMap#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map() {
+ // Test for method void java.util.IdentityHashMap.putAll(java.util.Map)
+ IdentityHashMap hm2 = new IdentityHashMap();
+ hm2.putAll(hm);
+ for (int i = 0; i < hmSize; i++) {
+ assertTrue("Failed to clear all elements", hm2.get(objArray2[i])
+ .equals((new Integer(i))));
+ }
+
+ hm2 = new IdentityHashMap();
+ Map mockMap = new MockMap();
+ hm2.putAll(mockMap);
+ assertEquals("Size should be 0", 0, hm2.size());
+ }
+
+ /**
+ * java.util.IdentityHashMap#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.IdentityHashMap.remove(java.lang.Object)
+ int size = hm.size();
+ Integer x = ((Integer) hm.remove(objArray2[9]));
+ assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
+ assertNull("Failed to remove given key", hm.get(objArray2[9]));
+ assertTrue("Failed to decrement size", hm.size() == (size - 1));
+ assertNull("Remove of non-existent key returned non-null", hm
+ .remove("LCLCLC"));
+
+ IdentityHashMap m = new IdentityHashMap();
+ m.put(null, "test");
+ assertNull("Failed with same hash as null",
+ m.remove(objArray[0]));
+ assertEquals("Failed with null key", "test", m.remove(null));
+ }
+
+ /**
+ * java.util.IdentityHashMap#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.IdentityHashMap.size()
+ assertEquals("Returned incorrect size, ", (objArray.length), hm.size());
+ }
+
+ /**
+ * java.util.IdentityHashMap#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ IdentityHashMap mapOne = new IdentityHashMap();
+ IdentityHashMap mapTwo = new IdentityHashMap();
+ IdentityHashMap mapThree = new IdentityHashMap();
+ IdentityHashMap mapFour = new IdentityHashMap();
+
+ String one = "one";
+ String alsoOne = new String(one); // use the new operator to ensure a
+ // new reference is constructed
+ String two = "two";
+ String alsoTwo = new String(two); // use the new operator to ensure a
+ // new reference is constructed
+
+ mapOne.put(one, two);
+ mapFour.put(one, two);
+
+ // these two are not equal to the above two
+ mapTwo.put(alsoOne, two);
+ mapThree.put(one, alsoTwo);
+
+ assertEquals("failure of equality of IdentityHashMaps", mapOne, mapFour);
+ assertTrue("failure of non-equality of IdentityHashMaps one and two",
+ !mapOne.equals(mapTwo));
+ assertTrue("failure of non-equality of IdentityHashMaps one and three",
+ !mapOne.equals(mapThree));
+ assertTrue("failure of non-equality of IdentityHashMaps two and three",
+ !mapTwo.equals(mapThree));
+
+ HashMap hashMapTwo = new HashMap();
+ HashMap hashMapThree = new HashMap();
+ hashMapTwo.put(alsoOne, two);
+ hashMapThree.put(one, alsoTwo);
+
+ assertTrue(
+ "failure of non-equality of IdentityHashMaps one and Hashmap two",
+ !mapOne.equals(hashMapTwo));
+ assertTrue(
+ "failure of non-equality of IdentityHashMaps one and Hashmap three",
+ !mapOne.equals(hashMapThree));
+ }
+
+ /**
+ * java.util.IdentityHashMap#values()
+ */
+ public void test_values() {
+ // Test for method java.util.Collection
+ // java.util.IdentityHashMap.values()
+ Collection c = hm.values();
+ assertTrue("Returned collection of incorrect size()", c.size() == hm
+ .size());
+ for (int i = 0; i < objArray.length; i++)
+ assertTrue("Returned collection does not contain all keys", c
+ .contains(objArray[i]));
+
+ IdentityHashMap myIdentityHashMap = new IdentityHashMap();
+ for (int i = 0; i < hmSize; i++)
+ myIdentityHashMap.put(objArray2[i], objArray[i]);
+ Collection values = myIdentityHashMap.values();
+ values.remove(objArray[0]);
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myIdentityHashMap.containsValue(objArray2[0]));
+
+ }
+
+ protected void setUp() {
+ objArray = new Object[hmSize];
+ objArray2 = new Object[hmSize];
+ for (int i = 0; i < objArray.length; i++) {
+ objArray[i] = new Integer(i);
+ objArray2[i] = objArray[i].toString();
+ }
+
+ hm = new IdentityHashMap();
+ for (int i = 0; i < objArray.length; i++) {
+ hm.put(objArray2[i], objArray[i]);
+ }
+ }
+
+
+ private static final SerializationTest.SerializableAssert comparator = new
+ SerializationTest.SerializableAssert() {
+
+ public void assertDeserialized(Serializable initial, Serializable deserialized) {
+ IdentityHashMap<String, String> initialMap = (IdentityHashMap<String, String>) initial;
+ IdentityHashMap<String, String> deseriaMap = (IdentityHashMap<String, String>) deserialized;
+ assertEquals("should be equal", initialMap.size(), deseriaMap.size());
+ }
+
+ };
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IdentityHashMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IdentityHashMapTest.java
new file mode 100644
index 0000000..4ddaf65
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IdentityHashMapTest.java
@@ -0,0 +1,871 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+import tests.support.Support_MapTest2;
+import java.io.Serializable;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+public class IdentityHashMapTest extends junit.framework.TestCase {
+ private static final String ID = "hello";
+
+ class MockMap extends AbstractMap {
+ public Set entrySet() {
+ return null;
+ }
+ public int size(){
+ return 0;
+ }
+ }
+ /*
+ * TODO: change all the statements testing the keys and values with equals()
+ * method to check for reference equality instead
+ */
+
+ IdentityHashMap hm;
+
+ final static int hmSize = 1000;
+
+ Object[] objArray;
+
+ Object[] objArray2;
+
+ /**
+ * java.util.IdentityHashMap#IdentityHashMap()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.IdentityHashMap()
+ new Support_MapTest2(new IdentityHashMap()).runTest();
+
+ IdentityHashMap hm2 = new IdentityHashMap();
+ assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
+ }
+
+ /**
+ * java.util.IdentityHashMap#IdentityHashMap(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.IdentityHashMap(int)
+ IdentityHashMap hm2 = new IdentityHashMap(5);
+ assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
+ try {
+ new IdentityHashMap(-1);
+ fail("Failed to throw IllegalArgumentException for initial capacity < 0");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ IdentityHashMap empty = new IdentityHashMap(0);
+ assertNull("Empty IdentityHashMap access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+ }
+
+ /**
+ * java.util.IdentityHashMap#IdentityHashMap(java.util.Map)
+ */
+ public void test_ConstructorLjava_util_Map() {
+ // Test for method java.util.IdentityHashMap(java.util.Map)
+ Map myMap = new TreeMap();
+ for (int counter = 0; counter < hmSize; counter++)
+ myMap.put(objArray2[counter], objArray[counter]);
+ IdentityHashMap hm2 = new IdentityHashMap(myMap);
+ for (int counter = 0; counter < hmSize; counter++)
+ assertTrue("Failed to construct correct IdentityHashMap", hm
+ .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+ Map mockMap = new MockMap();
+ hm2 = new IdentityHashMap(mockMap);
+ assertEquals("Size should be 0", 0, hm2.size());
+
+ try {
+ new IdentityHashMap(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.IdentityHashMap#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.IdentityHashMap.clear()
+ hm.clear();
+ assertEquals("Clear failed to reset size", 0, hm.size());
+ for (int i = 0; i < hmSize; i++)
+ assertNull("Failed to clear all elements",
+ hm.get(objArray2[i]));
+
+ }
+
+ /**
+ * java.util.IdentityHashMap#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.IdentityHashMap.clone()
+ IdentityHashMap hm2 = (IdentityHashMap) hm.clone();
+ assertTrue("Clone answered equivalent IdentityHashMap", hm2 != hm);
+ for (int counter = 0; counter < hmSize; counter++)
+ assertTrue("Clone answered unequal IdentityHashMap", hm
+ .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+ IdentityHashMap map = new IdentityHashMap();
+ map.put("key", "value");
+ // get the keySet() and values() on the original Map
+ Set keys = map.keySet();
+ Collection values = map.values();
+ assertEquals("values() does not work",
+ "value", values.iterator().next());
+ assertEquals("keySet() does not work",
+ "key", keys.iterator().next());
+ AbstractMap map2 = (AbstractMap) map.clone();
+ map2.put("key", "value2");
+ Collection values2 = map2.values();
+ assertTrue("values() is identical", values2 != values);
+ // values() and keySet() on the cloned() map should be different
+ assertEquals("values() was not cloned",
+ "value2", values2.iterator().next());
+ map2.clear();
+ map2.put("key2", "value3");
+ Set key2 = map2.keySet();
+ assertTrue("keySet() is identical", key2 != keys);
+ assertEquals("keySet() was not cloned",
+ "key2", key2.iterator().next());
+ }
+
+ /**
+ * java.util.IdentityHashMap#containsKey(java.lang.Object)
+ */
+ public void test_containsKeyLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.IdentityHashMap.containsKey(java.lang.Object)
+ assertTrue("Returned false for valid key", hm
+ .containsKey(objArray2[23]));
+ assertTrue("Returned true for copy of valid key", !hm
+ .containsKey(new Integer(23).toString()));
+ assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
+
+ IdentityHashMap m = new IdentityHashMap();
+ m.put(null, "test");
+ assertTrue("Failed with null key", m.containsKey(null));
+ assertTrue("Failed with missing key matching null hash", !m
+ .containsKey(new Integer(0)));
+ }
+
+ /**
+ * java.util.IdentityHashMap#containsValue(java.lang.Object)
+ */
+ public void test_containsValueLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.IdentityHashMap.containsValue(java.lang.Object)
+ assertTrue("Returned false for valid value", hm
+ .containsValue(objArray[19]));
+ assertTrue("Returned true for invalid valie", !hm
+ .containsValue(new Integer(-9)));
+ }
+
+ /**
+ * java.util.IdentityHashMap#entrySet()
+ */
+ public void test_entrySet() {
+ // Test for method java.util.Set java.util.IdentityHashMap.entrySet()
+ Set s = hm.entrySet();
+ Iterator i = s.iterator();
+ assertTrue("Returned set of incorrect size", hm.size() == s.size());
+ while (i.hasNext()) {
+ Map.Entry m = (Map.Entry) i.next();
+ assertTrue("Returned incorrect entry set", hm.containsKey(m
+ .getKey())
+ && hm.containsValue(m.getValue()));
+ }
+ }
+
+ /**
+ * java.util.IdentityHashMap#get(java.lang.Object)
+ */
+ public void test_getLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.IdentityHashMap.get(java.lang.Object)
+ assertNull("Get returned non-null for non existent key",
+ hm.get("T"));
+ hm.put("T", "HELLO");
+ assertEquals("Get returned incorecct value for existing key", "HELLO", hm.get("T")
+ );
+
+ IdentityHashMap m = new IdentityHashMap();
+ m.put(null, "test");
+ assertEquals("Failed with null key", "test", m.get(null));
+ assertNull("Failed with missing key matching null hash", m
+ .get(new Integer(0)));
+ }
+
+ /**
+ * java.util.IdentityHashMap#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.IdentityHashMap.isEmpty()
+ assertTrue("Returned false for new map", new IdentityHashMap()
+ .isEmpty());
+ assertTrue("Returned true for non-empty", !hm.isEmpty());
+ }
+
+ /**
+ * java.util.IdentityHashMap#keySet()
+ */
+ public void test_keySet() {
+ // Test for method java.util.Set java.util.IdentityHashMap.keySet()
+ Set s = hm.keySet();
+ assertTrue("Returned set of incorrect size()", s.size() == hm.size());
+ for (int i = 0; i < objArray.length; i++) {
+ assertTrue("Returned set does not contain all keys", s
+ .contains(objArray2[i]));
+ }
+
+ IdentityHashMap m = new IdentityHashMap();
+ m.put(null, "test");
+ assertTrue("Failed with null key", m.keySet().contains(null));
+ assertNull("Failed with null key", m.keySet().iterator().next());
+
+ Map map = new IdentityHashMap(101);
+ map.put(new Integer(1), "1");
+ map.put(new Integer(102), "102");
+ map.put(new Integer(203), "203");
+ Iterator it = map.keySet().iterator();
+ Integer remove1 = (Integer) it.next();
+ it.hasNext();
+ it.remove();
+ Integer remove2 = (Integer) it.next();
+ it.remove();
+ ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
+ new Integer(1), new Integer(102), new Integer(203) }));
+ list.remove(remove1);
+ list.remove(remove2);
+ assertTrue("Wrong result", it.next().equals(list.get(0)));
+ assertEquals("Wrong size", 1, map.size());
+ assertTrue("Wrong contents", map.keySet().iterator().next().equals(
+ list.get(0)));
+
+ Map map2 = new IdentityHashMap(101);
+ map2.put(new Integer(1), "1");
+ map2.put(new Integer(4), "4");
+ Iterator it2 = map2.keySet().iterator();
+ Integer remove3 = (Integer) it2.next();
+ Integer next;
+ if (remove3.intValue() == 1)
+ next = new Integer(4);
+ else
+ next = new Integer(1);
+ it2.hasNext();
+ it2.remove();
+ assertTrue("Wrong result 2", it2.next().equals(next));
+ assertEquals("Wrong size 2", 1, map2.size());
+ assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
+ next));
+ }
+
+ /**
+ * java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.IdentityHashMap.put(java.lang.Object, java.lang.Object)
+ hm.put("KEY", "VALUE");
+ assertEquals("Failed to install key/value pair",
+ "VALUE", hm.get("KEY"));
+
+ IdentityHashMap m = new IdentityHashMap();
+ Short s0 = new Short((short) 0);
+ m.put(s0, "short");
+ m.put(null, "test");
+ Integer i0 = new Integer(0);
+ m.put(i0, "int");
+ assertEquals("Failed adding to bucket containing null",
+ "short", m.get(s0));
+ assertEquals("Failed adding to bucket containing null2", "int", m.get(i0)
+ );
+
+ IdentityHashMap<Object, Object> map = new IdentityHashMap<Object, Object>();
+
+ // Test null as a key.
+ Object value = "Some value";
+ map.put(null, value);
+ assertSame("Assert 0: Failure getting null key", value, map.get(null));
+
+ // Test null as a value
+ Object key = "Some key";
+ map.put(key, null);
+ assertNull("Assert 1: Failure getting null value", map.get(key));
+ }
+
+ /**
+ * java.util.IdentityHashMap#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map() {
+ // Test for method void java.util.IdentityHashMap.putAll(java.util.Map)
+ IdentityHashMap hm2 = new IdentityHashMap();
+ hm2.putAll(hm);
+ for (int i = 0; i < 1000; i++)
+ assertTrue("Failed to clear all elements", hm2.get(objArray2[i])
+ .equals((new Integer(i))));
+
+ hm2 = new IdentityHashMap();
+ Map mockMap = new MockMap();
+ hm2.putAll(mockMap);
+ assertEquals("Size should be 0", 0, hm2.size());
+
+ try {
+ hm2.putAll(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.IdentityHashMap#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.IdentityHashMap.remove(java.lang.Object)
+ int size = hm.size();
+ Integer x = ((Integer) hm.remove(objArray2[9]));
+ assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
+ assertNull("Failed to remove given key", hm.get(objArray2[9]));
+ assertTrue("Failed to decrement size", hm.size() == (size - 1));
+ assertNull("Remove of non-existent key returned non-null", hm
+ .remove("LCLCLC"));
+
+ IdentityHashMap m = new IdentityHashMap();
+ m.put(null, "test");
+ assertNull("Failed with same hash as null",
+ m.remove(objArray[0]));
+ assertEquals("Failed with null key", "test", m.remove(null));
+
+ // Regression for HARMONY-37
+ IdentityHashMap<String, String> hashMap = new IdentityHashMap<String, String>();
+ hashMap.remove("absent");
+ assertEquals("Assert 0: Size is incorrect", 0, hashMap.size());
+
+ hashMap.put("key", "value");
+ hashMap.remove("key");
+ assertEquals("Assert 1: After removing non-null element size is incorrect", 0, hashMap.size());
+
+ hashMap.put(null, null);
+ assertEquals("Assert 2: adding literal null failed", 1, hashMap.size());
+ hashMap.remove(null);
+ assertEquals("Assert 3: After removing null element size is incorrect", 0, hashMap.size());
+ }
+
+ /**
+ * java.util.IdentityHashMap#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.IdentityHashMap.size()
+ assertEquals("Returned incorrect size, ", (objArray.length + 2), hm
+ .size());
+ }
+
+ /**
+ * java.util.IdentityHashMap#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ IdentityHashMap mapOne = new IdentityHashMap();
+ IdentityHashMap mapTwo = new IdentityHashMap();
+ IdentityHashMap mapThree = new IdentityHashMap();
+ IdentityHashMap mapFour = new IdentityHashMap();
+
+ String one = "one";
+ String alsoOne = new String(one); // use the new operator to ensure a
+ // new reference is constructed
+ String two = "two";
+ String alsoTwo = new String(two); // use the new operator to ensure a
+ // new reference is constructed
+
+ mapOne.put(one, two);
+ mapFour.put(one, two);
+
+ // these two are not equal to the above two
+ mapTwo.put(alsoOne, two);
+ mapThree.put(one, alsoTwo);
+
+ assertEquals("failure of equality of IdentityHashMaps", mapOne, mapFour);
+ assertTrue("failure of non-equality of IdentityHashMaps one and two",
+ !mapOne.equals(mapTwo));
+ assertTrue("failure of non-equality of IdentityHashMaps one and three",
+ !mapOne.equals(mapThree));
+ assertTrue("failure of non-equality of IdentityHashMaps two and three",
+ !mapTwo.equals(mapThree));
+
+ HashMap hashMapTwo = new HashMap();
+ HashMap hashMapThree = new HashMap();
+ hashMapTwo.put(alsoOne, two);
+ hashMapThree.put(one, alsoTwo);
+
+ assertTrue(
+ "failure of non-equality of IdentityHashMaps one and Hashmap two",
+ !mapOne.equals(hashMapTwo));
+ assertTrue(
+ "failure of non-equality of IdentityHashMaps one and Hashmap three",
+ !mapOne.equals(hashMapThree));
+ }
+
+ /**
+ * java.util.IdentityHashMap#Serialization()
+ */
+ public void test_Serialization() throws Exception {
+ IdentityHashMap<String, String> map = new IdentityHashMap<String, String>();
+ map.put(ID, "world");
+ // BEGIN android-added
+ // Regression test for null key in serialized IdentityHashMap (1178549)
+ // Together with this change the IdentityHashMap.golden.ser resource
+ // was replaced by a version that contains a map with a null key.
+ map.put(null, "null");
+ // END android-added
+ SerializationTest.verifySelf(map, comparator);
+ SerializationTest.verifyGolden(this, map, comparator);
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ objArray = new Object[hmSize];
+ objArray2 = new Object[hmSize];
+ for (int i = 0; i < objArray.length; i++) {
+ objArray[i] = new Integer(i);
+ // android-changed: the containsKey test requires unique strings.
+ objArray2[i] = new String(objArray[i].toString());
+ }
+
+ hm = new IdentityHashMap();
+ for (int i = 0; i < objArray.length; i++)
+ hm.put(objArray2[i], objArray[i]);
+ hm.put("test", null);
+ hm.put(null, "test");
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ objArray = null;
+ objArray2 = null;
+ hm = null;
+ }
+
+ private static final SerializationTest.SerializableAssert comparator = new
+ SerializationTest.SerializableAssert() {
+
+ public void assertDeserialized(Serializable initial, Serializable deserialized) {
+ IdentityHashMap<String, String> initialMap = (IdentityHashMap<String, String>) initial;
+ IdentityHashMap<String, String> deseriaMap = (IdentityHashMap<String, String>) deserialized;
+ assertEquals("should be equal", initialMap.size(), deseriaMap.size());
+ }
+
+ };
+
+ /**
+ * java.util.IdentityHashMap#containsKey(java.lang.Object)
+ * java.util.IdentityHashMap#containsValue(java.lang.Object)
+ * java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
+ * java.util.IdentityHashMap#get(java.lang.Object)
+ */
+ public void test_null_Keys_and_Values() {
+ // tests with null keys and values
+ IdentityHashMap map = new IdentityHashMap();
+ Object result;
+
+ // null key and null value
+ result = map.put(null, null);
+ assertTrue("testA can not find null key", map.containsKey(null));
+ assertTrue("testA can not find null value", map.containsValue(null));
+ assertNull("testA can not get null value for null key",
+ map.get(null));
+ assertNull("testA put returned wrong value", result);
+
+ // null value
+ String value = "a value";
+ result = map.put(null, value);
+ assertTrue("testB can not find null key", map.containsKey(null));
+ assertTrue("testB can not find a value with null key", map
+ .containsValue(value));
+ assertTrue("testB can not get value for null key",
+ map.get(null) == value);
+ assertNull("testB put returned wrong value", result);
+
+ // a null key
+ String key = "a key";
+ result = map.put(key, null);
+ assertTrue("testC can not find a key with null value", map
+ .containsKey(key));
+ assertTrue("testC can not find null value", map.containsValue(null));
+ assertNull("testC can not get null value for key", map.get(key));
+ assertNull("testC put returned wrong value", result);
+
+ // another null key
+ String anothervalue = "another value";
+ result = map.put(null, anothervalue);
+ assertTrue("testD can not find null key", map.containsKey(null));
+ assertTrue("testD can not find a value with null key", map
+ .containsValue(anothervalue));
+ assertTrue("testD can not get value for null key",
+ map.get(null) == anothervalue);
+ assertTrue("testD put returned wrong value", result == value);
+
+ // remove a null key
+ result = map.remove(null);
+ assertTrue("testE remove returned wrong value", result == anothervalue);
+ assertTrue("testE should not find null key", !map.containsKey(null));
+ assertTrue("testE should not find a value with null key", !map
+ .containsValue(anothervalue));
+ assertNull("testE should not get value for null key",
+ map.get(null));
+ }
+
+ /**
+ * java.util.IdentityHashMap#remove(java.lang.Object)
+ * java.util.IdentityHashMap#keySet()
+ */
+ public void test_remove() {
+ IdentityHashMap map = new IdentityHashMap();
+ map.put(null, null);
+ map.put("key1", "value1");
+ map.put("key2", "value2");
+ map.remove("key1");
+
+ assertTrue("Did not remove key1", !map.containsKey("key1"));
+ assertTrue("Did not remove the value for key1", !map
+ .containsValue("value1"));
+
+ assertTrue("Modified key2", map.get("key2") != null
+ && map.get("key2") == "value2");
+ assertNull("Modified null entry", map.get(null));
+ }
+
+ /**
+ * java.util.IdentityHashMap#entrySet()
+ * java.util.IdentityHashMap#keySet()
+ * java.util.IdentityHashMap#values()
+ */
+ public void test_sets() {
+ // tests with null keys and values
+ IdentityHashMap map = new IdentityHashMap();
+
+ // null key and null value
+ map.put("key", "value");
+ map.put(null, null);
+ map.put("a key", null);
+ map.put("another key", null);
+
+ Set keyset = map.keySet();
+ Collection valueset = map.values();
+ Set entries = map.entrySet();
+ Iterator it = entries.iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+ assertTrue("EntrySetIterator can not find entry ", entries
+ .contains(entry));
+
+ assertTrue("entry key not found in map", map.containsKey(entry
+ .getKey()));
+ assertTrue("entry value not found in map", map.containsValue(entry
+ .getValue()));
+
+ assertTrue("entry key not found in the keyset", keyset
+ .contains(entry.getKey()));
+ assertTrue("entry value not found in the valueset", valueset
+ .contains(entry.getValue()));
+ }
+ }
+
+ /**
+ * java.util.IdentityHashMap#entrySet()
+ * java.util.IdentityHashMap#remove(java.lang.Object)
+ */
+ public void test_entrySet_removeAll() {
+ IdentityHashMap map = new IdentityHashMap();
+ for (int i = 0; i < 1000; i++) {
+ map.put(new Integer(i), new Integer(i));
+ }
+ Set set = map.entrySet();
+
+ set.removeAll(set);
+ assertEquals("did not remove all elements in the map", 0, map.size());
+ assertTrue("did not remove all elements in the entryset", set.isEmpty());
+
+ Iterator it = set.iterator();
+ assertTrue("entrySet iterator still has elements", !it.hasNext());
+ }
+
+ /**
+ * java.util.IdentityHashMap#keySet()
+ * java.util.IdentityHashMap#clear()
+ */
+ public void test_keySet_clear() {
+ IdentityHashMap map = new IdentityHashMap();
+ for (int i = 0; i < 1000; i++) {
+ map.put(new Integer(i), new Integer(i));
+ }
+ Set set = map.keySet();
+ set.clear();
+
+ assertEquals("did not remove all elements in the map", 0, map.size());
+ assertTrue("did not remove all elements in the keyset", set.isEmpty());
+
+ Iterator it = set.iterator();
+ assertTrue("keySet iterator still has elements", !it.hasNext());
+ }
+
+ /**
+ * java.util.IdentityHashMap#values()
+ */
+ public void test_values() {
+
+ IdentityHashMap map = new IdentityHashMap();
+ for (int i = 0; i < 10; i++) {
+ map.put(new Integer(i), new Integer(i));
+ }
+
+ Integer key = new Integer(20);
+ Integer value = new Integer(40);
+ map.put(key, value);
+
+ Collection vals = map.values();
+ boolean result = vals.remove(key);
+ assertTrue("removed entries incorrectly", map.size() == 11 && !result);
+ assertTrue("removed key incorrectly", map.containsKey(key));
+ assertTrue("removed value incorrectly", map.containsValue(value));
+
+ result = vals.remove(value);
+ assertTrue("Did not remove entry as expected", map.size() == 10
+ && result);
+ assertTrue("Did not remove key as expected", !map.containsKey(key));
+ assertTrue("Did not remove value as expected", !map
+ .containsValue(value));
+
+ // put an equivalent key to a value
+ key = new Integer(1);
+ value = new Integer(100);
+ map.put(key, value);
+
+ result = vals.remove(key);
+ assertTrue("TestB. removed entries incorrectly", map.size() == 11
+ && !result);
+ assertTrue("TestB. removed key incorrectly", map.containsKey(key));
+ assertTrue("TestB. removed value incorrectly", map.containsValue(value));
+
+ result = vals.remove(value);
+ assertTrue("TestB. Did not remove entry as expected", map.size() == 10
+ && result);
+ assertTrue("TestB. Did not remove key as expected", !map
+ .containsKey(key));
+ assertTrue("TestB. Did not remove value as expected", !map
+ .containsValue(value));
+
+ vals.clear();
+ assertEquals("Did not remove all entries as expected", 0, map.size());
+ }
+
+ /**
+ * java.util.IdentityHashMap#keySet()
+ * java.util.IdentityHashMap#remove(java.lang.Object)
+ */
+ public void test_keySet_removeAll() {
+ IdentityHashMap map = new IdentityHashMap();
+ for (int i = 0; i < 1000; i++) {
+ map.put(new Integer(i), new Integer(i));
+ }
+ Set set = map.keySet();
+ set.removeAll(set);
+
+ assertEquals("did not remove all elements in the map", 0, map.size());
+ assertTrue("did not remove all elements in the keyset", set.isEmpty());
+
+ Iterator it = set.iterator();
+ assertTrue("keySet iterator still has elements", !it.hasNext());
+ }
+
+ /**
+ * java.util.IdentityHashMap#keySet()
+ */
+ public void test_keySet_retainAll() {
+ IdentityHashMap map = new IdentityHashMap();
+ for (int i = 0; i < 1000; i++) {
+ map.put(new Integer(i), new Integer(i));
+ }
+ Set set = map.keySet();
+
+ // retain all the elements
+ boolean result = set.retainAll(set);
+ assertTrue("retain all should return false", !result);
+ assertEquals("did not retain all", 1000, set.size());
+
+ // send empty set to retainAll
+ result = set.retainAll(new TreeSet());
+ assertTrue("retain all should return true", result);
+ assertEquals("did not remove all elements in the map", 0, map.size());
+ assertTrue("did not remove all elements in the keyset", set.isEmpty());
+
+ Iterator it = set.iterator();
+ assertTrue("keySet iterator still has elements", !it.hasNext());
+ }
+
+ /**
+ * java.util.IdentityHashMap#keySet()
+ * java.util.IdentityHashMap#remove(java.lang.Object)
+ */
+ public void test_keyset_remove() {
+ IdentityHashMap map = new IdentityHashMap();
+
+ Integer key = new Integer(21);
+
+ map.put(new Integer(1), null);
+ map.put(new Integer(11), null);
+ map.put(key, null);
+ map.put(new Integer(31), null);
+ map.put(new Integer(41), null);
+ map.put(new Integer(51), null);
+ map.put(new Integer(61), null);
+ map.put(new Integer(71), null);
+ map.put(new Integer(81), null);
+ map.put(new Integer(91), null);
+
+ Set set = map.keySet();
+
+ Set newset = new HashSet();
+ Iterator it = set.iterator();
+ while (it.hasNext()) {
+ Object element = it.next();
+ if (element == key) {
+ it.remove();
+ } else
+ newset.add(element);
+ }
+ int size = newset.size();
+ assertTrue("keyset and newset don't have same size",
+ newset.size() == size);
+ assertTrue("element is in newset ", !newset.contains(key));
+ assertTrue("element not removed from keyset", !set.contains(key));
+ assertTrue("element not removed from map", !map.containsKey(key));
+
+ assertTrue("newset and keyset do not have same elements 1", newset
+ .equals(set));
+ assertTrue("newset and keyset do not have same elements 2", set
+ .equals(newset));
+ }
+
+ public void test_clone_scenario1() {
+ IdentityHashMap hashMap = new IdentityHashMap();
+ assertEquals(0, hashMap.hashCode());
+ Object cloneHashMap = hashMap.clone();
+ ((IdentityHashMap) cloneHashMap).put("key", "value");
+ assertEquals(0, hashMap.hashCode());
+ assertTrue(0 != cloneHashMap.hashCode());
+ }
+
+ public void test_clone_scenario2() {
+ IdentityHashMap hashMap = new IdentityHashMap();
+ assertEquals(0, hashMap.hashCode());
+ Object cloneHashMap = hashMap.clone();
+ hashMap.put("key", "value");
+ assertEquals(1, hashMap.size());
+ assertEquals(0, ((IdentityHashMap) cloneHashMap).size());
+ assertEquals("value", hashMap.get("key"));
+ assertNull(((IdentityHashMap) cloneHashMap).get("key"));
+ assertTrue(0 != hashMap.hashCode());
+ assertEquals(0, cloneHashMap.hashCode());
+ }
+
+ public void test_clone_scenario3() {
+ IdentityHashMap hashMap = new IdentityHashMap();
+ assertEquals(0, hashMap.hashCode());
+ hashMap.put("key", "value");
+ Object cloneHashMap = hashMap.clone();
+ assertEquals(1, hashMap.size());
+ assertEquals(1, ((IdentityHashMap) cloneHashMap).size());
+ assertEquals("value", hashMap.get("key"));
+ assertEquals("value", ((IdentityHashMap) cloneHashMap).get("key"));
+ assertEquals(hashMap.hashCode(), cloneHashMap.hashCode());
+ }
+
+ public void test_clone_scenario4() {
+ IdentityHashMap hashMap = new IdentityHashMap();
+ Object cloneHashMap = hashMap.clone();
+ assertNull(((IdentityHashMap) cloneHashMap).get((Object) null));
+ hashMap.put((Object) null, cloneHashMap);
+ assertNull(((IdentityHashMap) cloneHashMap).get((Object) null));
+ assertEquals(cloneHashMap, hashMap.get((Object) null));
+ }
+
+ public void test_clone_scenario5() throws Exception {
+ IdentityHashMap hashMap = new IdentityHashMap();
+ Object cloneHashMap = hashMap.clone();
+ assertNull(hashMap.remove((Object) null));
+ ((IdentityHashMap) cloneHashMap).put((Object) null, cloneHashMap);
+ assertNull(hashMap.remove((Object) null));
+ assertEquals(cloneHashMap, ((IdentityHashMap) cloneHashMap)
+ .get((Object) null));
+ }
+
+ /*
+ * Regression test for HARMONY-6419
+ */
+ public void test_underlyingMap() {
+ IdentityHashMap<String, String> ihm = new IdentityHashMap<String, String>();
+ String key = "key";
+ String value = "value";
+ ihm.put(key, value);
+
+ Set<Map.Entry<String, String>> set = ihm.entrySet();
+ assertEquals(1, set.size());
+
+ Map.Entry<String, String> entry = set.iterator().next();
+
+ String newValue = "newvalue";
+ entry.setValue(newValue);
+ assertSame(newValue, ihm.get(key));
+ }
+
+ // comparator for IdentityHashMap objects
+ private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ IdentityHashMap init = (IdentityHashMap) initial;
+ IdentityHashMap desr = (IdentityHashMap) deserialized;
+
+ assertEquals("Size", init.size(), desr.size());
+ }
+ };
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatCodePointExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatCodePointExceptionTest.java
new file mode 100644
index 0000000..ac67e81
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatCodePointExceptionTest.java
@@ -0,0 +1,91 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.IllegalFormatCodePointException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class IllegalFormatCodePointExceptionTest extends TestCase {
+
+ /**
+ * java.util.IllegalFormatCodePointException.IllegalFormatCodePointException(int)
+ */
+ public void test_illegalFormatCodePointException() {
+ IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
+ -1);
+ assertTrue(null != illegalFormatCodePointException);
+ }
+
+ /**
+ * java.util.IllegalFormatCodePointException.getCodePoint()
+ */
+ public void test_getCodePoint() {
+ int codePoint = 12345;
+ IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
+ codePoint);
+ assertEquals(codePoint, illegalFormatCodePointException.getCodePoint());
+ }
+
+ /**
+ * java.util.IllegalFormatCodePointException.getMessage()
+ */
+ public void test_getMessage() {
+ int codePoint = 12345;
+ IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
+ codePoint);
+ assertTrue(null != illegalFormatCodePointException.getMessage());
+ }
+
+ // comparator for IllegalFormatCodePointException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ IllegalFormatCodePointException initEx = (IllegalFormatCodePointException) initial;
+ IllegalFormatCodePointException desrEx = (IllegalFormatCodePointException) deserialized;
+
+ assertEquals("CodePoint", initEx.getCodePoint(), desrEx
+ .getCodePoint());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(
+ new IllegalFormatCodePointException(12345), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new IllegalFormatCodePointException(12345), exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatConversionExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatConversionExceptionTest.java
new file mode 100644
index 0000000..2277825
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatConversionExceptionTest.java
@@ -0,0 +1,115 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.IllegalFormatConversionException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class IllegalFormatConversionExceptionTest extends TestCase {
+
+ /**
+ * java.util.IllegalFormatConversionException#IllegalFormatConversionException(char,
+ *Class)
+ */
+ public void test_illegalFormatConversionException() {
+ try {
+ new IllegalFormatConversionException(' ', null);
+ fail("should throw NullPointerExcetpion.");
+ } catch (NullPointerException e) {
+ // desired
+ }
+ }
+
+ /**
+ * java.util.IllegalFormatConversionException#getArgumentClass()
+ */
+ public void test_getArgumentClass() {
+ char c = '*';
+ Class<String> argClass = String.class;
+ IllegalFormatConversionException illegalFormatConversionException = new IllegalFormatConversionException(
+ c, argClass);
+ assertEquals(argClass, illegalFormatConversionException
+ .getArgumentClass());
+
+ }
+
+ /**
+ * java.util.IllegalFormatConversionException#getConversion()
+ */
+ public void test_getConversion() {
+ char c = '*';
+ Class<String> argClass = String.class;
+ IllegalFormatConversionException illegalFormatConversionException = new IllegalFormatConversionException(
+ c, argClass);
+ assertEquals(c, illegalFormatConversionException.getConversion());
+
+ }
+
+ /**
+ * java.util.IllegalFormatConversionException#getMessage()
+ */
+ public void test_getMessage() {
+ char c = '*';
+ Class<String> argClass = String.class;
+ IllegalFormatConversionException illegalFormatConversionException = new IllegalFormatConversionException(
+ c, argClass);
+ assertTrue(null != illegalFormatConversionException.getMessage());
+
+ }
+
+ // comparator for IllegalFormatConversionException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ IllegalFormatConversionException initEx = (IllegalFormatConversionException) initial;
+ IllegalFormatConversionException desrEx = (IllegalFormatConversionException) deserialized;
+
+ assertEquals("ArgumentClass", initEx.getArgumentClass(), desrEx
+ .getArgumentClass());
+ assertEquals("Conversion", initEx.getConversion(), desrEx
+ .getConversion());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new IllegalFormatConversionException('*',
+ String.class), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new IllegalFormatConversionException('*', String.class),
+ exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatFlagsExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatFlagsExceptionTest.java
new file mode 100644
index 0000000..1611028
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatFlagsExceptionTest.java
@@ -0,0 +1,94 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.IllegalFormatFlagsException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class IllegalFormatFlagsExceptionTest extends TestCase {
+
+ /**
+ * java.util.IllegalFormatFlagsException#IllegalFormatFlagsException(String)
+ */
+ public void test_illegalFormatFlagsException() {
+ try {
+ new IllegalFormatFlagsException(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.IllegalFormatFlagsException.getFlags()
+ */
+ public void test_getFlags() {
+ String flags = "TESTFLAGS";
+ IllegalFormatFlagsException illegalFormatFlagsException = new IllegalFormatFlagsException(
+ flags);
+ assertEquals(flags, illegalFormatFlagsException.getFlags());
+ }
+
+ /**
+ * java.util.IllegalFormatFlagsException.getMessage()
+ */
+ public void test_getMessage() {
+ String flags = "TESTFLAGS";
+ IllegalFormatFlagsException illegalFormatFlagsException = new IllegalFormatFlagsException(
+ flags);
+ assertTrue(null != illegalFormatFlagsException.getMessage());
+
+ }
+
+ // comparator for IllegalFormatFlagsException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ IllegalFormatFlagsException initEx = (IllegalFormatFlagsException) initial;
+ IllegalFormatFlagsException desrEx = (IllegalFormatFlagsException) deserialized;
+
+ assertEquals("Flags", initEx.getFlags(), desrEx.getFlags());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new IllegalFormatFlagsException(
+ "TESTFLAGS"), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new IllegalFormatFlagsException(
+ "TESTFLAGS"), exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatPrecisionExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatPrecisionExceptionTest.java
new file mode 100644
index 0000000..b290b48
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatPrecisionExceptionTest.java
@@ -0,0 +1,92 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.IllegalFormatPrecisionException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class IllegalFormatPrecisionExceptionTest extends TestCase {
+
+ /**
+ * java.util.IllegalFormatPrecisionException#IllegalFormatPrecisionException(int)
+ */
+ public void test_illegalFormatPrecisionException() {
+ IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
+ Integer.MIN_VALUE);
+ assertEquals(Integer.MIN_VALUE, illegalFormatPrecisionException
+ .getPrecision());
+ }
+
+ /**
+ * java.util.IllegalFormatPrecisionException#getPrecision()
+ */
+ public void test_getPrecision() {
+ int precision = 12345;
+ IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
+ precision);
+ assertEquals(precision, illegalFormatPrecisionException.getPrecision());
+ }
+
+ /**
+ * method for 'java.util.IllegalFormatPrecisionException#getMessage()
+ */
+ public void test_getMessage() {
+ int precision = 12345;
+ IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
+ precision);
+ assertTrue(null != illegalFormatPrecisionException.getMessage());
+
+ }
+
+ // comparator for IllegalFormatPrecisionException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ IllegalFormatPrecisionException initEx = (IllegalFormatPrecisionException) initial;
+ IllegalFormatPrecisionException desrEx = (IllegalFormatPrecisionException) deserialized;
+
+ assertEquals("Precision", initEx.getPrecision(), desrEx
+ .getPrecision());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(
+ new IllegalFormatPrecisionException(12345), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new IllegalFormatPrecisionException(12345), exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatWidthExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatWidthExceptionTest.java
new file mode 100644
index 0000000..8d5ed0e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/IllegalFormatWidthExceptionTest.java
@@ -0,0 +1,93 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.IllegalFormatWidthException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class IllegalFormatWidthExceptionTest extends TestCase {
+
+ /**
+ * java.util.IllegalFormatWidthException#IllegalFormatWidthException(int)
+ */
+ public void test_illegalFormatWidthException() {
+ int width = Integer.MAX_VALUE;
+ IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
+ width);
+ assertEquals(width, illegalFormatWidthException.getWidth());
+
+ }
+
+ /**
+ * java.util.IllegalFormatWidthException#getWidth()
+ */
+ public void test_getWidth() {
+ int width = 12345;
+ IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
+ width);
+ assertEquals(width, illegalFormatWidthException.getWidth());
+
+ }
+
+ /**
+ * java.util.IllegalFormatWidthException#getMessage()
+ */
+ public void test_getMessage() {
+ int width = 12345;
+ IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
+ width);
+ assertTrue(null != illegalFormatWidthException.getMessage());
+
+ }
+
+ // comparator for IllegalFormatWidthException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ IllegalFormatWidthException initEx = (IllegalFormatWidthException) initial;
+ IllegalFormatWidthException desrEx = (IllegalFormatWidthException) deserialized;
+
+ assertEquals("Width", initEx.getWidth(), desrEx.getWidth());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new IllegalFormatWidthException(12345),
+ exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new IllegalFormatWidthException(
+ 12345), exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/InputMismatchExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/InputMismatchExceptionTest.java
new file mode 100644
index 0000000..30291b3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/InputMismatchExceptionTest.java
@@ -0,0 +1,67 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.InputMismatchException;
+import java.util.NoSuchElementException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class InputMismatchExceptionTest extends TestCase {
+
+ private static final String ERROR_MESSAGE = "for serialization test"; //$NON-NLS-1$
+
+ /**
+ * java.util.InputMismatchException#InputMismatchException()
+ */
+ @SuppressWarnings("cast")
+ public void test_Constructor() {
+ InputMismatchException exception = new InputMismatchException();
+ assertNotNull(exception);
+ assertTrue(exception instanceof NoSuchElementException);
+ assertTrue(exception instanceof Serializable);
+ }
+
+ /**
+ * java.util.InputMismatchException#InputMismatchException(String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ InputMismatchException exception = new InputMismatchException(
+ ERROR_MESSAGE);
+ assertNotNull(exception);
+ assertEquals(ERROR_MESSAGE, exception.getMessage());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new InputMismatchException(ERROR_MESSAGE));
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new InputMismatchException(
+ ERROR_MESSAGE));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/InvalidPropertiesFormatExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/InvalidPropertiesFormatExceptionTest.java
new file mode 100644
index 0000000..10bb50e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/InvalidPropertiesFormatExceptionTest.java
@@ -0,0 +1,50 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.NotSerializableException;
+import java.util.InvalidPropertiesFormatException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class InvalidPropertiesFormatExceptionTest extends
+ junit.framework.TestCase {
+
+ /**
+ * java.util.InvalidPropertiesFormatException#SerializationTest()
+ */
+ public void test_Serialization() throws Exception {
+ InvalidPropertiesFormatException ipfe = new InvalidPropertiesFormatException(
+ "Hey, this is InvalidPropertiesFormatException");
+ try {
+ SerializationTest.verifySelf(ipfe);
+ } catch (NotSerializableException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.InvalidPropertiesFormatException#InvalidPropertiesFormatException(Throwable)}
+ */
+ public void test_Constructor_Ljava_lang_Throwable() {
+ Throwable throwable = new Throwable();
+ InvalidPropertiesFormatException exception = new InvalidPropertiesFormatException(
+ throwable);
+ assertEquals("the casue did not equals argument passed in constructor",
+ throwable, exception.getCause());
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedHashMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedHashMapTest.java
new file mode 100644
index 0000000..8565b8e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedHashMapTest.java
@@ -0,0 +1,736 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import tests.support.Support_MapTest2;
+import tests.support.Support_UnmodifiableCollectionTest;
+
+/**
+ * java.util.LinkedHashMap
+ */
+public class LinkedHashMapTest extends junit.framework.TestCase {
+
+ LinkedHashMap hm;
+
+ final static int hmSize = 1000;
+
+ Object[] objArray;
+
+ Object[] objArray2;
+
+ static final class CacheMap extends LinkedHashMap {
+ protected boolean removeEldestEntry(Map.Entry e) {
+ return size() > 5;
+ }
+ }
+
+ private static class MockMapNull extends AbstractMap {
+ @Override
+ public Set entrySet() {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 10;
+ }
+ }
+
+ /**
+ * java.util.LinkedHashMap#LinkedHashMap()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.LinkedHashMap()
+ new Support_MapTest2(new LinkedHashMap()).runTest();
+
+ LinkedHashMap hm2 = new LinkedHashMap();
+ assertEquals("Created incorrect LinkedHashMap", 0, hm2.size());
+ }
+
+ /**
+ * java.util.LinkedHashMap#LinkedHashMap(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.LinkedHashMap(int)
+ LinkedHashMap hm2 = new LinkedHashMap(5);
+ assertEquals("Created incorrect LinkedHashMap", 0, hm2.size());
+ try {
+ new LinkedHashMap(-1);
+ fail("Failed to throw IllegalArgumentException for initial " +
+ "capacity < 0");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ LinkedHashMap empty = new LinkedHashMap(0);
+ assertNull("Empty LinkedHashMap access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+ }
+
+ /**
+ * java.util.LinkedHashMap#LinkedHashMap(int, float)
+ */
+ public void test_ConstructorIF() {
+ // Test for method java.util.LinkedHashMap(int, float)
+ LinkedHashMap hm2 = new LinkedHashMap(5, (float) 0.5);
+ assertEquals("Created incorrect LinkedHashMap", 0, hm2.size());
+ try {
+ new LinkedHashMap(0, 0);
+ fail("Failed to throw IllegalArgumentException for initial " +
+ "load factor <= 0");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ LinkedHashMap empty = new LinkedHashMap(0, 0.75f);
+ assertNull("Empty hashtable access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+ }
+
+ /**
+ * java.util.LinkedHashMap#LinkedHashMap(java.util.Map)
+ */
+ public void test_ConstructorLjava_util_Map() {
+ // Test for method java.util.LinkedHashMap(java.util.Map)
+ Map myMap = new TreeMap();
+ for (int counter = 0; counter < hmSize; counter++)
+ myMap.put(objArray2[counter], objArray[counter]);
+ LinkedHashMap hm2 = new LinkedHashMap(myMap);
+ for (int counter = 0; counter < hmSize; counter++)
+ assertTrue("Failed to construct correct LinkedHashMap", hm
+ .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+ }
+
+ /**
+ * java.util.LinkedHashMap#get(java.lang.Object)
+ */
+ public void test_getLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.LinkedHashMap.get(java.lang.Object)
+ assertNull("Get returned non-null for non existent key",
+ hm.get("T"));
+ hm.put("T", "HELLO");
+ assertEquals("Get returned incorecct value for existing key", "HELLO", hm.get("T")
+ );
+
+ LinkedHashMap m = new LinkedHashMap();
+ m.put(null, "test");
+ assertEquals("Failed with null key", "test", m.get(null));
+ assertNull("Failed with missing key matching null hash", m
+ .get(new Integer(0)));
+ }
+
+ /**
+ * java.util.LinkedHashMap#put(java.lang.Object, java.lang.Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.LinkedHashMap.put(java.lang.Object, java.lang.Object)
+ hm.put("KEY", "VALUE");
+ assertEquals("Failed to install key/value pair",
+ "VALUE", hm.get("KEY"));
+
+ LinkedHashMap m = new LinkedHashMap();
+ m.put(new Short((short) 0), "short");
+ m.put(null, "test");
+ m.put(new Integer(0), "int");
+ assertEquals("Failed adding to bucket containing null", "short", m.get(
+ new Short((short) 0)));
+ assertEquals("Failed adding to bucket containing null2", "int", m.get(
+ new Integer(0)));
+ }
+
+
+ public void test_putPresent() {
+ Map<String, String> m = new LinkedHashMap<String, String>(8, .75f, true);
+ m.put("KEY", "VALUE");
+ m.put("WOMBAT", "COMBAT");
+ m.put("KEY", "VALUE");
+ Map.Entry newest = null;
+ for (Map.Entry<String, String> e : m.entrySet()) {
+ newest = e;
+ }
+ assertEquals("KEY", newest.getKey());
+ assertEquals("VALUE", newest.getValue());
+ }
+
+ /**
+ * java.util.LinkedHashMap#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map() {
+ // Test for method void java.util.LinkedHashMap.putAll(java.util.Map)
+ LinkedHashMap hm2 = new LinkedHashMap();
+ hm2.putAll(hm);
+ for (int i = 0; i < 1000; i++)
+ assertTrue("Failed to clear all elements", hm2.get(
+ new Integer(i).toString()).equals((new Integer(i))));
+ }
+
+ /**
+ * java.util.LinkedHashMap#putAll(java.util.Map)
+ */
+ public void test_putAll_Ljava_util_Map_Null() {
+ LinkedHashMap linkedHashMap = new LinkedHashMap();
+ try {
+ linkedHashMap.putAll(new MockMapNull());
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ linkedHashMap = new LinkedHashMap(new MockMapNull());
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected.
+ }
+ }
+
+ /**
+ * java.util.LinkedHashMap#entrySet()
+ */
+ public void test_entrySet() {
+ // Test for method java.util.Set java.util.LinkedHashMap.entrySet()
+ Set s = hm.entrySet();
+ Iterator i = s.iterator();
+ assertTrue("Returned set of incorrect size", hm.size() == s.size());
+ while (i.hasNext()) {
+ Map.Entry m = (Map.Entry) i.next();
+ assertTrue("Returned incorrect entry set", hm.containsKey(m
+ .getKey())
+ && hm.containsValue(m.getValue()));
+ }
+ }
+
+ public void test_entrySetRemove() {
+ entrySetRemoveHelper("military", "intelligence");
+ entrySetRemoveHelper(null, "hypothesis");
+ }
+ private void entrySetRemoveHelper(String key, String value) {
+ Map<String, String> m1 = new LinkedHashMap<String, String>();
+ m1.put(key, value);
+ m1.put("jumbo", "shrimp");
+ LinkedHashMap<String, String> m2 = new LinkedHashMap<String, String>(m1);
+ Set<Map.Entry<String, String>> s1 = m1.entrySet();
+ s1.remove(m2.entrySet().iterator().next());
+ assertEquals("jumbo", s1.iterator().next().getKey());
+ }
+
+ /**
+ * java.util.LinkedHashMap#keySet()
+ */
+ public void test_keySet() {
+ // Test for method java.util.Set java.util.LinkedHashMap.keySet()
+ Set s = hm.keySet();
+ assertTrue("Returned set of incorrect size()", s.size() == hm.size());
+ for (int i = 0; i < objArray.length; i++)
+ assertTrue("Returned set does not contain all keys", s
+ .contains(objArray[i].toString()));
+
+ LinkedHashMap m = new LinkedHashMap();
+ m.put(null, "test");
+ assertTrue("Failed with null key", m.keySet().contains(null));
+ assertNull("Failed with null key", m.keySet().iterator().next());
+
+ Map map = new LinkedHashMap(101);
+ map.put(new Integer(1), "1");
+ map.put(new Integer(102), "102");
+ map.put(new Integer(203), "203");
+ Iterator it = map.keySet().iterator();
+ Integer remove1 = (Integer) it.next();
+ it.hasNext();
+ it.remove();
+ Integer remove2 = (Integer) it.next();
+ it.remove();
+ ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
+ new Integer(1), new Integer(102), new Integer(203) }));
+ list.remove(remove1);
+ list.remove(remove2);
+ assertTrue("Wrong result", it.next().equals(list.get(0)));
+ assertEquals("Wrong size", 1, map.size());
+ assertTrue("Wrong contents", map.keySet().iterator().next().equals(
+ list.get(0)));
+
+ Map map2 = new LinkedHashMap(101);
+ map2.put(new Integer(1), "1");
+ map2.put(new Integer(4), "4");
+ Iterator it2 = map2.keySet().iterator();
+ Integer remove3 = (Integer) it2.next();
+ Integer next;
+ if (remove3.intValue() == 1)
+ next = new Integer(4);
+ else
+ next = new Integer(1);
+ it2.hasNext();
+ it2.remove();
+ assertTrue("Wrong result 2", it2.next().equals(next));
+ assertEquals("Wrong size 2", 1, map2.size());
+ assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
+ next));
+ }
+
+ /**
+ * java.util.LinkedHashMap#values()
+ */
+ public void test_values() {
+ // Test for method java.util.Collection java.util.LinkedHashMap.values()
+ Collection c = hm.values();
+ assertTrue("Returned collection of incorrect size()", c.size() == hm
+ .size());
+ for (int i = 0; i < objArray.length; i++)
+ assertTrue("Returned collection does not contain all keys", c
+ .contains(objArray[i]));
+
+ LinkedHashMap myLinkedHashMap = new LinkedHashMap();
+ for (int i = 0; i < 100; i++)
+ myLinkedHashMap.put(objArray2[i], objArray[i]);
+ Collection values = myLinkedHashMap.values();
+ new Support_UnmodifiableCollectionTest(
+ "Test Returned Collection From LinkedHashMap.values()", values)
+ .runTest();
+ values.remove(new Integer(0));
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myLinkedHashMap.containsValue(new Integer(0)));
+
+ }
+
+ /**
+ * java.util.LinkedHashMap#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.LinkedHashMap.remove(java.lang.Object)
+ int size = hm.size();
+ Integer y = new Integer(9);
+ Integer x = ((Integer) hm.remove(y.toString()));
+ assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
+ assertNull("Failed to remove given key", hm.get(new Integer(9)));
+ assertTrue("Failed to decrement size", hm.size() == (size - 1));
+ assertNull("Remove of non-existent key returned non-null", hm
+ .remove("LCLCLC"));
+
+ LinkedHashMap m = new LinkedHashMap();
+ m.put(null, "test");
+ assertNull("Failed with same hash as null",
+ m.remove(new Integer(0)));
+ assertEquals("Failed with null key", "test", m.remove(null));
+ }
+
+ /**
+ * java.util.LinkedHashMap#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.LinkedHashMap.clear()
+ hm.clear();
+ assertEquals("Clear failed to reset size", 0, hm.size());
+ for (int i = 0; i < hmSize; i++)
+ assertNull("Failed to clear all elements",
+ hm.get(objArray2[i]));
+
+ }
+
+ /**
+ * java.util.LinkedHashMap#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.LinkedHashMap.clone()
+ LinkedHashMap hm2 = (LinkedHashMap) hm.clone();
+ assertTrue("Clone answered equivalent LinkedHashMap", hm2 != hm);
+ for (int counter = 0; counter < hmSize; counter++)
+ assertTrue("Clone answered unequal LinkedHashMap", hm
+ .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+ LinkedHashMap map = new LinkedHashMap();
+ map.put("key", "value");
+ // get the keySet() and values() on the original Map
+ Set keys = map.keySet();
+ Collection values = map.values();
+ assertEquals("values() does not work",
+ "value", values.iterator().next());
+ assertEquals("keySet() does not work",
+ "key", keys.iterator().next());
+ AbstractMap map2 = (AbstractMap) map.clone();
+ map2.put("key", "value2");
+ Collection values2 = map2.values();
+ assertTrue("values() is identical", values2 != values);
+
+ // values() and keySet() on the cloned() map should be different
+ assertEquals("values() was not cloned",
+ "value2", values2.iterator().next());
+ map2.clear();
+ map2.put("key2", "value3");
+ Set key2 = map2.keySet();
+ assertTrue("keySet() is identical", key2 != keys);
+ assertEquals("keySet() was not cloned",
+ "key2", key2.iterator().next());
+ }
+
+ /**
+ * java.util.LinkedHashMap#clone()
+ */
+ public void test_clone_ordered() {
+ // Test for method java.lang.Object java.util.LinkedHashMap.clone()
+ LinkedHashMap<String, String> hm1 = new LinkedHashMap<String, String>(10, 0.75f, true);
+ hm1.put("a", "a");
+ hm1.put("b", "b");
+ hm1.put("c", "c");
+ LinkedHashMap<String, String> hm2 = (LinkedHashMap<String, String>) hm1.clone();
+ hm1.get("a");
+
+ Map.Entry<String, String>[] set = new Map.Entry[3];
+ Iterator<Map.Entry<String,String>> iterator = hm1.entrySet().iterator();
+
+ assertEquals("b", iterator.next().getKey());
+ assertEquals("c", iterator.next().getKey());
+ assertEquals("a", iterator.next().getKey());
+
+ iterator = hm2.entrySet().iterator();
+ assertEquals("a", iterator.next().getKey());
+ assertEquals("b", iterator.next().getKey());
+ assertEquals("c", iterator.next().getKey());
+ }
+
+ // regresion test for HARMONY-4603
+ public void test_clone_Mock() {
+ LinkedHashMap hashMap = new MockMap();
+ String value = "value a";
+ hashMap.put("key", value);
+ MockMap cloneMap = (MockMap) hashMap.clone();
+ assertEquals(value, cloneMap.get("key"));
+ assertEquals(hashMap, cloneMap);
+ assertEquals(1, cloneMap.num);
+
+ hashMap.put("key", "value b");
+ assertFalse(hashMap.equals(cloneMap));
+ }
+
+ class MockMap extends LinkedHashMap {
+ int num;
+
+ public Object put(Object k, Object v) {
+ num++;
+ return super.put(k, v);
+ }
+
+ protected boolean removeEldestEntry(Map.Entry e) {
+ return num > 1;
+ }
+ }
+
+ /**
+ * put/get interaction in access-order map where removeEldest
+ * returns true.
+ */
+ public void test_removeEldestFromSameBucketAsNewEntry() {
+ LinkedHashMap<String, String> map
+ = new LinkedHashMap<String, String>(6, 0.75F, true) {
+ @Override
+ protected boolean removeEldestEntry(Entry<String, String> e) {
+ return true;
+ }
+ };
+ map.put("N", "E");
+ map.put("F", "I");
+ assertEquals(null, map.get("N"));
+ }
+
+ /**
+ * java.util.LinkedHashMap#containsKey(java.lang.Object)
+ */
+ public void test_containsKeyLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.LinkedHashMap.containsKey(java.lang.Object)
+ assertTrue("Returned false for valid key", hm.containsKey(new Integer(
+ 876).toString()));
+ assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
+
+ LinkedHashMap m = new LinkedHashMap();
+ m.put(null, "test");
+ assertTrue("Failed with null key", m.containsKey(null));
+ assertTrue("Failed with missing key matching null hash", !m
+ .containsKey(new Integer(0)));
+ }
+
+ /**
+ * java.util.LinkedHashMap#containsValue(java.lang.Object)
+ */
+ public void test_containsValueLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.LinkedHashMap.containsValue(java.lang.Object)
+ assertTrue("Returned false for valid value", hm
+ .containsValue(new Integer(875)));
+ assertTrue("Returned true for invalid valie", !hm
+ .containsValue(new Integer(-9)));
+ }
+
+ /**
+ * java.util.LinkedHashMap#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.LinkedHashMap.isEmpty()
+ assertTrue("Returned false for new map", new LinkedHashMap().isEmpty());
+ assertTrue("Returned true for non-empty", !hm.isEmpty());
+ }
+
+ /**
+ * java.util.LinkedHashMap#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.LinkedHashMap.size()
+ assertTrue("Returned incorrect size",
+ hm.size() == (objArray.length + 2));
+ }
+
+ /**
+ * java.util.LinkedHashMap#entrySet()
+ */
+ public void test_ordered_entrySet() {
+ int i;
+ int sz = 100;
+ LinkedHashMap lhm = new LinkedHashMap();
+ for (i = 0; i < sz; i++) {
+ Integer ii = new Integer(i);
+ lhm.put(ii, ii.toString());
+ }
+
+ Set s1 = lhm.entrySet();
+ Iterator it1 = s1.iterator();
+ assertTrue("Returned set of incorrect size 1", lhm.size() == s1.size());
+ for (i = 0; it1.hasNext(); i++) {
+ Map.Entry m = (Map.Entry) it1.next();
+ Integer jj = (Integer) m.getKey();
+ assertTrue("Returned incorrect entry set 1", jj.intValue() == i);
+ }
+
+ LinkedHashMap lruhm = new LinkedHashMap(200, .75f, true);
+ for (i = 0; i < sz; i++) {
+ Integer ii = new Integer(i);
+ lruhm.put(ii, ii.toString());
+ }
+
+ Set s3 = lruhm.entrySet();
+ Iterator it3 = s3.iterator();
+ assertTrue("Returned set of incorrect size 2", lruhm.size() == s3
+ .size());
+ for (i = 0; i < sz && it3.hasNext(); i++) {
+ Map.Entry m = (Map.Entry) it3.next();
+ Integer jj = (Integer) m.getKey();
+ assertTrue("Returned incorrect entry set 2", jj.intValue() == i);
+ }
+
+ /* fetch the even numbered entries to affect traversal order */
+ int p = 0;
+ for (i = 0; i < sz; i += 2) {
+ String ii = (String) lruhm.get(new Integer(i));
+ p = p + Integer.parseInt(ii);
+ }
+ assertEquals("invalid sum of even numbers", 2450, p);
+
+ Set s2 = lruhm.entrySet();
+ Iterator it2 = s2.iterator();
+ assertTrue("Returned set of incorrect size 3", lruhm.size() == s2
+ .size());
+ for (i = 1; i < sz && it2.hasNext(); i += 2) {
+ Map.Entry m = (Map.Entry) it2.next();
+ Integer jj = (Integer) m.getKey();
+ assertTrue("Returned incorrect entry set 3", jj.intValue() == i);
+ }
+ for (i = 0; i < sz && it2.hasNext(); i += 2) {
+ Map.Entry m = (Map.Entry) it2.next();
+ Integer jj = (Integer) m.getKey();
+ assertTrue("Returned incorrect entry set 4", jj.intValue() == i);
+ }
+ assertTrue("Entries left to iterate on", !it2.hasNext());
+ }
+
+ /**
+ * java.util.LinkedHashMap#keySet()
+ */
+ public void test_ordered_keySet() {
+ int i;
+ int sz = 100;
+ LinkedHashMap lhm = new LinkedHashMap();
+ for (i = 0; i < sz; i++) {
+ Integer ii = new Integer(i);
+ lhm.put(ii, ii.toString());
+ }
+
+ Set s1 = lhm.keySet();
+ Iterator it1 = s1.iterator();
+ assertTrue("Returned set of incorrect size", lhm.size() == s1.size());
+ for (i = 0; it1.hasNext(); i++) {
+ Integer jj = (Integer) it1.next();
+ assertTrue("Returned incorrect entry set", jj.intValue() == i);
+ }
+
+ LinkedHashMap lruhm = new LinkedHashMap(200, .75f, true);
+ for (i = 0; i < sz; i++) {
+ Integer ii = new Integer(i);
+ lruhm.put(ii, ii.toString());
+ }
+
+ Set s3 = lruhm.keySet();
+ Iterator it3 = s3.iterator();
+ assertTrue("Returned set of incorrect size", lruhm.size() == s3.size());
+ for (i = 0; i < sz && it3.hasNext(); i++) {
+ Integer jj = (Integer) it3.next();
+ assertTrue("Returned incorrect entry set", jj.intValue() == i);
+ }
+
+ /* fetch the even numbered entries to affect traversal order */
+ int p = 0;
+ for (i = 0; i < sz; i += 2) {
+ String ii = (String) lruhm.get(new Integer(i));
+ p = p + Integer.parseInt(ii);
+ }
+ assertEquals("invalid sum of even numbers", 2450, p);
+
+ Set s2 = lruhm.keySet();
+ Iterator it2 = s2.iterator();
+ assertTrue("Returned set of incorrect size", lruhm.size() == s2.size());
+ for (i = 1; i < sz && it2.hasNext(); i += 2) {
+ Integer jj = (Integer) it2.next();
+ assertTrue("Returned incorrect entry set", jj.intValue() == i);
+ }
+ for (i = 0; i < sz && it2.hasNext(); i += 2) {
+ Integer jj = (Integer) it2.next();
+ assertTrue("Returned incorrect entry set", jj.intValue() == i);
+ }
+ assertTrue("Entries left to iterate on", !it2.hasNext());
+ }
+
+ /**
+ * java.util.LinkedHashMap#values()
+ */
+ public void test_ordered_values() {
+ int i;
+ int sz = 100;
+ LinkedHashMap lhm = new LinkedHashMap();
+ for (i = 0; i < sz; i++) {
+ Integer ii = new Integer(i);
+ lhm.put(ii, new Integer(i * 2));
+ }
+
+ Collection s1 = lhm.values();
+ Iterator it1 = s1.iterator();
+ assertTrue("Returned set of incorrect size 1", lhm.size() == s1.size());
+ for (i = 0; it1.hasNext(); i++) {
+ Integer jj = (Integer) it1.next();
+ assertTrue("Returned incorrect entry set 1", jj.intValue() == i * 2);
+ }
+
+ LinkedHashMap lruhm = new LinkedHashMap(200, .75f, true);
+ for (i = 0; i < sz; i++) {
+ Integer ii = new Integer(i);
+ lruhm.put(ii, new Integer(i * 2));
+ }
+
+ Collection s3 = lruhm.values();
+ Iterator it3 = s3.iterator();
+ assertTrue("Returned set of incorrect size", lruhm.size() == s3.size());
+ for (i = 0; i < sz && it3.hasNext(); i++) {
+ Integer jj = (Integer) it3.next();
+ assertTrue("Returned incorrect entry set", jj.intValue() == i * 2);
+ }
+
+ // fetch the even numbered entries to affect traversal order
+ int p = 0;
+ for (i = 0; i < sz; i += 2) {
+ Integer ii = (Integer) lruhm.get(new Integer(i));
+ p = p + ii.intValue();
+ }
+ assertTrue("invalid sum of even numbers", p == 2450 * 2);
+
+ Collection s2 = lruhm.values();
+ Iterator it2 = s2.iterator();
+ assertTrue("Returned set of incorrect size", lruhm.size() == s2.size());
+ for (i = 1; i < sz && it2.hasNext(); i += 2) {
+ Integer jj = (Integer) it2.next();
+ assertTrue("Returned incorrect entry set", jj.intValue() == i * 2);
+ }
+ for (i = 0; i < sz && it2.hasNext(); i += 2) {
+ Integer jj = (Integer) it2.next();
+ assertTrue("Returned incorrect entry set", jj.intValue() == i * 2);
+ }
+ assertTrue("Entries left to iterate on", !it2.hasNext());
+ }
+
+ /**
+ * java.util.LinkedHashMap#removeEldestEntry(java.util.Map$Entry)
+ */
+ public void test_remove_eldest() {
+ int i;
+ int sz = 10;
+ CacheMap lhm = new CacheMap();
+ for (i = 0; i < sz; i++) {
+ Integer ii = new Integer(i);
+ lhm.put(ii, new Integer(i * 2));
+ }
+
+ Collection s1 = lhm.values();
+ Iterator it1 = s1.iterator();
+ assertTrue("Returned set of incorrect size 1", lhm.size() == s1.size());
+ for (i = 5; it1.hasNext(); i++) {
+ Integer jj = (Integer) it1.next();
+ assertTrue("Returned incorrect entry set 1", jj.intValue() == i * 2);
+ }
+ assertTrue("Entries left in map", !it1.hasNext());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ objArray = new Object[hmSize];
+ objArray2 = new Object[hmSize];
+ for (int i = 0; i < objArray.length; i++) {
+ objArray[i] = new Integer(i);
+ objArray2[i] = objArray[i].toString();
+ }
+
+ hm = new LinkedHashMap();
+ for (int i = 0; i < objArray.length; i++)
+ hm.put(objArray2[i], objArray[i]);
+ hm.put("test", null);
+ hm.put(null, "test");
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ objArray = null;
+ objArray2 = null;
+ hm = null;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedHashSetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedHashSetTest.java
new file mode 100644
index 0000000..721a879
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedHashSetTest.java
@@ -0,0 +1,351 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * java.util.LinkedHashSet
+ */
+
+public class LinkedHashSetTest extends junit.framework.TestCase {
+
+ LinkedHashSet hs;
+
+ Object[] objArray;
+
+ /**
+ * java.util.LinkedHashSet#LinkedHashSet()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.LinkedHashSet()
+ LinkedHashSet hs2 = new LinkedHashSet();
+ assertEquals("Created incorrect LinkedHashSet", 0, hs2.size());
+ }
+
+ /**
+ * java.util.LinkedHashSet#LinkedHashSet(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.LinkedHashSet(int)
+ LinkedHashSet hs2 = new LinkedHashSet(5);
+ assertEquals("Created incorrect LinkedHashSet", 0, hs2.size());
+ try {
+ new LinkedHashSet(-1);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.LinkedHashSet#LinkedHashSet(int, float)
+ */
+ public void test_ConstructorIF() {
+ // Test for method java.util.LinkedHashSet(int, float)
+ LinkedHashSet hs2 = new LinkedHashSet(5, (float) 0.5);
+ assertEquals("Created incorrect LinkedHashSet", 0, hs2.size());
+
+ try {
+ new LinkedHashSet(-1, 0.5f);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new LinkedHashSet(1, -0.5f);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new LinkedHashSet(1, 0f);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.LinkedHashSet#LinkedHashSet(java.util.Collection)
+ */
+ public void test_ConstructorLjava_util_Collection() {
+ // Test for method java.util.LinkedHashSet(java.util.Collection)
+ LinkedHashSet hs2 = new LinkedHashSet(Arrays.asList(objArray));
+ for (int counter = 0; counter < objArray.length; counter++)
+ assertTrue("LinkedHashSet does not contain correct elements", hs
+ .contains(objArray[counter]));
+ assertTrue("LinkedHashSet created from collection incorrect size", hs2
+ .size() == objArray.length);
+
+ try {
+ new LinkedHashSet(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.LinkedHashSet#add(java.lang.Object)
+ */
+ public void test_addLjava_lang_Object() {
+ // Test for method boolean java.util.LinkedHashSet.add(java.lang.Object)
+ int size = hs.size();
+ hs.add(new Integer(8));
+ assertTrue("Added element already contained by set", hs.size() == size);
+ hs.add(new Integer(-9));
+ assertTrue("Failed to increment set size after add",
+ hs.size() == size + 1);
+ assertTrue("Failed to add element to set", hs.contains(new Integer(-9)));
+ }
+
+ /**
+ * java.util.LinkedHashSet#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.LinkedHashSet.clear()
+ Set orgSet = (Set) hs.clone();
+ hs.clear();
+ Iterator i = orgSet.iterator();
+ assertEquals("Returned non-zero size after clear", 0, hs.size());
+ while (i.hasNext())
+ assertTrue("Failed to clear set", !hs.contains(i.next()));
+ }
+
+ /**
+ * java.util.LinkedHashSet#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.LinkedHashSet.clone()
+ LinkedHashSet hs2 = (LinkedHashSet) hs.clone();
+ assertTrue("clone returned an equivalent LinkedHashSet", hs != hs2);
+ assertTrue("clone did not return an equal LinkedHashSet", hs
+ .equals(hs2));
+ }
+
+ /**
+ * java.util.LinkedHashSet#contains(java.lang.Object)
+ */
+ public void test_containsLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.LinkedHashSet.contains(java.lang.Object)
+ assertTrue("Returned false for valid object", hs.contains(objArray[90]));
+ assertTrue("Returned true for invalid Object", !hs
+ .contains(new Object()));
+
+ LinkedHashSet s = new LinkedHashSet();
+ s.add(null);
+ assertTrue("Cannot handle null", s.contains(null));
+ }
+
+ /**
+ * java.util.LinkedHashSet#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.LinkedHashSet.isEmpty()
+ assertTrue("Empty set returned false", new LinkedHashSet().isEmpty());
+ assertTrue("Non-empty set returned true", !hs.isEmpty());
+ }
+
+ /**
+ * java.util.LinkedHashSet#iterator()
+ */
+ public void test_iterator() {
+ // Test for method java.util.Iterator java.util.LinkedHashSet.iterator()
+ Iterator i = hs.iterator();
+ int x = 0;
+ int j;
+ for (j = 0; i.hasNext(); j++) {
+ Object oo = i.next();
+ if (oo != null) {
+ Integer ii = (Integer) oo;
+ assertTrue("Incorrect element found", ii.intValue() == j);
+ } else {
+ assertTrue("Cannot find null", hs.contains(oo));
+ }
+ ++x;
+ }
+ assertTrue("Returned iteration of incorrect size", hs.size() == x);
+
+ LinkedHashSet s = new LinkedHashSet();
+ s.add(null);
+ assertNull("Cannot handle null", s.iterator().next());
+ }
+
+ /**
+ * java.util.LinkedHashSet#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.LinkedHashSet.remove(java.lang.Object)
+ int size = hs.size();
+ hs.remove(new Integer(98));
+ assertTrue("Failed to remove element", !hs.contains(new Integer(98)));
+ assertTrue("Failed to decrement set size", hs.size() == size - 1);
+
+ LinkedHashSet s = new LinkedHashSet();
+ s.add(null);
+ assertTrue("Cannot handle null", s.remove(null));
+ }
+
+ /**
+ * java.util.LinkedHashSet#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.LinkedHashSet.size()
+ assertTrue("Returned incorrect size", hs.size() == (objArray.length + 1));
+ hs.clear();
+ assertEquals("Cleared set returned non-zero size", 0, hs.size());
+ }
+
+ class Mock_LinkedHashSet extends LinkedHashSet {
+ @Override
+ public boolean retainAll(Collection c) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public void test_retainAllLjava_util_Collection() {
+ LinkedHashSet<Integer> lhs = new LinkedHashSet<Integer>();
+ Vector v = new Vector<Float>();
+ v.add(new Float(3.14));
+ lhs.add(new Integer(1));
+ assertEquals(1, lhs.size());
+ lhs.retainAll(v);
+ assertEquals(0, lhs.size());
+ v = new Vector<Integer>();
+ v.add(new Integer(1));
+ v.add(new Integer(2));
+ v.add(new Integer(3));
+ v.add(new Integer(4));
+ v.add(new Integer(5));
+ v.add(new Integer(6));
+ lhs.add(new Integer(1));
+ lhs.add(new Integer(6));
+ lhs.add(new Integer(7));
+ lhs.add(new Integer(8));
+ lhs.add(new Integer(9));
+ lhs.add(new Integer(10));
+ lhs.add(new Integer(11));
+ lhs.add(new Integer(12));
+ lhs.add(new Integer(13));
+ assertEquals(9, lhs.size());
+ lhs.retainAll(v);
+ assertEquals(2, lhs.size());
+
+ try {
+ lhs.retainAll(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ lhs = new Mock_LinkedHashSet();
+
+ try {
+ lhs.retainAll(v);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException e) {
+ //expected
+ }
+ }
+
+ public void test_toArray() {
+ LinkedHashSet<Integer> lhs = new LinkedHashSet<Integer>();
+ lhs.add(new Integer(1));
+ lhs.add(new Integer(6));
+ lhs.add(new Integer(7));
+ lhs.add(new Integer(8));
+ lhs.add(new Integer(9));
+ lhs.add(new Integer(10));
+ lhs.add(new Integer(11));
+ lhs.add(new Integer(12));
+ lhs.add(new Integer(13));
+
+ Object[] o = lhs.toArray();
+ for (int i = 0; i < o.length; i++) {
+ assertTrue(lhs.contains(o[i]));
+ }
+ assertEquals(lhs.size(), o.length);
+ }
+
+ public void test_toArray$Ljava_lang_Object() {
+ LinkedHashSet<Integer> lhs = new LinkedHashSet<Integer>();
+ lhs.add(new Integer(1));
+ lhs.add(new Integer(6));
+ lhs.add(new Integer(7));
+ lhs.add(new Integer(8));
+ lhs.add(new Integer(9));
+ lhs.add(new Integer(10));
+ lhs.add(new Integer(11));
+ lhs.add(new Integer(12));
+ lhs.add(new Integer(13));
+
+ Object[] o1 = new Object[lhs.size()];
+ Object[] o2 = new Double[lhs.size()];
+ lhs.toArray(o1);
+ for (int i = 0; i < o1.length; i++) {
+ assertTrue(lhs.contains(o1[i]));
+ }
+
+ try {
+ lhs.toArray(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ try {
+ lhs.toArray(o2);
+ fail("ArrayStoreException expected");
+ } catch (ArrayStoreException e) {
+ //expected
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ objArray = new Object[1000];
+ for (int i = 0; i < objArray.length; i++)
+ objArray[i] = new Integer(i);
+
+ hs = new LinkedHashSet();
+ for (int i = 0; i < objArray.length; i++)
+ hs.add(objArray[i]);
+ hs.add(null);
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ objArray = null;
+ hs = null;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedListTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedListTest.java
new file mode 100644
index 0000000..79607f1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedListTest.java
@@ -0,0 +1,983 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+import tests.support.Support_ListTest;
+
+public class LinkedListTest extends junit.framework.TestCase {
+
+ LinkedList ll;
+
+ LinkedList<Object> testList;
+
+ private Object testObjOne;
+
+ private Object testObjTwo;
+
+ private Object testObjThree;
+
+ private Object testObjFour;
+
+ private Object testObjLast;
+
+ Object[] objArray;
+
+ /**
+ * java.util.LinkedList#LinkedList()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.LinkedList()
+ new Support_ListTest("", ll).runTest();
+
+ LinkedList subList = new LinkedList();
+ for (int i = -50; i < 150; i++)
+ subList.add(new Integer(i));
+ new Support_ListTest("", subList.subList(50, 150)).runTest();
+ }
+
+ /**
+ * java.util.LinkedList#LinkedList(java.util.Collection)
+ */
+ public void test_ConstructorLjava_util_Collection() {
+ // Test for method java.util.LinkedList(java.util.Collection)
+ assertTrue("Incorrect LinkedList constructed", new LinkedList(ll)
+ .equals(ll));
+
+ try {
+ new LinkedList(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.LinkedList#add(int, java.lang.Object)
+ */
+ public void test_addILjava_lang_Object() {
+ // Test for method void java.util.LinkedList.add(int, java.lang.Object)
+ Object o;
+ ll.add(50, o = "Test");
+ assertTrue("Failed to add Object>: " + ll.get(50).toString(), ll
+ .get(50) == o);
+ assertTrue("Failed to fix up list after insert",
+ ll.get(51) == objArray[50] && (ll.get(52) == objArray[51]));
+ ll.add(50, null);
+ assertNull("Did not add null correctly", ll.get(50));
+
+ try {
+ ll.add(-1, "Test");
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ ll.add(-1, null);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ ll.add(ll.size() + 1, "Test");
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ ll.add(ll.size() + 1, null);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.LinkedList#add(java.lang.Object)
+ */
+ public void test_addLjava_lang_Object() {
+ // Test for method boolean java.util.LinkedList.add(java.lang.Object)
+ Object o;
+ ll.add(o = new Object());
+ assertTrue("Failed to add Object", ll.getLast() == o);
+ ll.add(null);
+ assertNull("Did not add null correctly", ll.get(ll.size() - 1));
+ }
+
+ /**
+ * java.util.LinkedList#addAll(int, java.util.Collection)
+ */
+ public void test_addAllILjava_util_Collection() {
+ // Test for method boolean java.util.LinkedList.addAll(int,
+ // java.util.Collection)
+ ll.addAll(50, (Collection) ll.clone());
+ assertEquals("Returned incorrect size after adding to existing list", 200, ll
+ .size());
+ for (int i = 0; i < 50; i++)
+ assertTrue("Manipulated elements < index", ll.get(i) == objArray[i]);
+ for (int i = 0; i >= 50 && (i < 150); i++)
+ assertTrue("Failed to ad elements properly",
+ ll.get(i) == objArray[i - 50]);
+ for (int i = 0; i >= 150 && (i < 200); i++)
+ assertTrue("Failed to ad elements properly",
+ ll.get(i) == objArray[i - 100]);
+ List myList = new LinkedList();
+ myList.add(null);
+ myList.add("Blah");
+ myList.add(null);
+ myList.add("Booga");
+ myList.add(null);
+ ll.addAll(50, myList);
+ assertNull("a) List w/nulls not added correctly", ll.get(50));
+ assertEquals("b) List w/nulls not added correctly",
+ "Blah", ll.get(51));
+ assertNull("c) List w/nulls not added correctly", ll.get(52));
+ assertEquals("d) List w/nulls not added correctly",
+ "Booga", ll.get(53));
+ assertNull("e) List w/nulls not added correctly", ll.get(54));
+
+ try {
+ ll.addAll(-1, (Collection) null);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ ll.addAll(ll.size() + 1, (Collection) null);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ ll.addAll(0, null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.LinkedList#addAll(int, java.util.Collection)
+ */
+ public void test_addAllILjava_util_Collection_2() {
+ // Regression for HARMONY-467
+ LinkedList obj = new LinkedList();
+ try {
+ obj.addAll(-1, (Collection) null);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ /**
+ * java.util.LinkedList#addAll(java.util.Collection)
+ */
+ public void test_addAllLjava_util_Collection() {
+ // Test for method boolean
+ // java.util.LinkedList.addAll(java.util.Collection)
+ List l = new ArrayList();
+ l.addAll((Collection) ll.clone());
+ for (int i = 0; i < ll.size(); i++)
+ assertTrue("Failed to add elements properly", l.get(i).equals(
+ ll.get(i)));
+ ll.addAll((Collection) ll.clone());
+ assertEquals("Returned incorrect siZe after adding to existing list", 200, ll
+ .size());
+ for (int i = 0; i < 100; i++) {
+ assertTrue("Added to list in incorrect order", ll.get(i).equals(
+ l.get(i)));
+ assertTrue("Failed to add to existing list", ll.get(i + 100)
+ .equals(l.get(i)));
+ }
+ List myList = new LinkedList();
+ myList.add(null);
+ myList.add("Blah");
+ myList.add(null);
+ myList.add("Booga");
+ myList.add(null);
+ ll.addAll(myList);
+ assertNull("a) List w/nulls not added correctly", ll.get(200));
+ assertEquals("b) List w/nulls not added correctly",
+ "Blah", ll.get(201));
+ assertNull("c) List w/nulls not added correctly", ll.get(202));
+ assertEquals("d) List w/nulls not added correctly",
+ "Booga", ll.get(203));
+ assertNull("e) List w/nulls not added correctly", ll.get(204));
+
+ try {
+ ll.addAll(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Excepted
+ }
+ }
+
+ public void test_addAll_Self_Ljava_util_Collection() {
+ LinkedList linkedList = new LinkedList();
+ linkedList.addLast(1);
+ assertEquals(1, linkedList.size());
+ assertTrue(linkedList.addAll(linkedList));
+ assertEquals(2, linkedList.size());
+ }
+
+ public void test_addAll_Self_ILjava_util_Collection() {
+ LinkedList linkedList = new LinkedList();
+ linkedList.addLast(1);
+ assertEquals(1, linkedList.size());
+ assertTrue(linkedList.addAll(1, linkedList));
+ assertEquals(2, linkedList.size());
+ }
+
+ /**
+ * java.util.LinkedList#addFirst(java.lang.Object)
+ */
+ public void test_addFirstLjava_lang_Object() {
+ // Test for method void java.util.LinkedList.addFirst(java.lang.Object)
+ Object o;
+ ll.addFirst(o = new Object());
+ assertTrue("Failed to add Object", ll.getFirst() == o);
+ ll.addFirst(null);
+ assertNull("Failed to add null", ll.getFirst());
+ }
+
+ /**
+ * java.util.LinkedList#addLast(java.lang.Object)
+ */
+ public void test_addLastLjava_lang_Object() {
+ // Test for method void java.util.LinkedList.addLast(java.lang.Object)
+ Object o;
+ ll.addLast(o = new Object());
+ assertTrue("Failed to add Object", ll.getLast() == o);
+ ll.addLast(null);
+ assertNull("Failed to add null", ll.getLast());
+ }
+
+ /**
+ * java.util.LinkedList#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.LinkedList.clear()
+ ll.clear();
+ for (int i = 0; i < ll.size(); i++)
+ assertNull("Failed to clear list", ll.get(i));
+ }
+
+ /**
+ * java.util.LinkedList#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.LinkedList.clone()
+ Object x = ll.clone();
+ assertTrue("Cloned list was inequal to cloned", x.equals(ll));
+ for (int i = 0; i < ll.size(); i++)
+ assertTrue("Cloned list contains incorrect elements", ll.get(i)
+ .equals(((LinkedList) x).get(i)));
+ ll.addFirst(null);
+ x = ll.clone();
+ assertTrue("List with a null did not clone properly", ll.equals(x));
+ }
+
+ /**
+ * java.util.LinkedList#contains(java.lang.Object)
+ */
+ public void test_containsLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.LinkedList.contains(java.lang.Object)
+ assertTrue("Returned false for valid element", ll
+ .contains(objArray[99]));
+ assertTrue("Returned false for equal element", ll.contains(new Integer(
+ 8)));
+ assertTrue("Returned true for invalid element", !ll
+ .contains(new Object()));
+ assertTrue("Should not contain null", !ll.contains(null));
+ ll.add(25, null);
+ assertTrue("Should contain null", ll.contains(null));
+ }
+
+ /**
+ * java.util.LinkedList#get(int)
+ */
+ public void test_getI() {
+ // Test for method java.lang.Object java.util.LinkedList.get(int)
+ assertTrue("Returned incorrect element", ll.get(22) == objArray[22]);
+ try {
+ ll.get(8765);
+ fail("Failed to throw expected exception for index > size");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ /**
+ * {@link java.util.LinkedList#peek()}
+ */
+ public void test_peek() {
+ LinkedList list = new LinkedList();
+
+ assertNull("Should return null if this list is empty", list.peek());
+
+ assertEquals("Returned incorrect first element", ll.peek(), objArray[0]);
+ assertEquals("Peek remove the head (first element) of this list", ll.getFirst(), objArray[0]);
+ }
+
+ /**
+ * java.util.LinkedList#getFirst()
+ */
+ public void test_getFirst() {
+ // Test for method java.lang.Object java.util.LinkedList.getFirst()
+ assertTrue("Returned incorrect first element", ll.getFirst().equals(
+ objArray[0]));
+
+ LinkedList list = new LinkedList();
+ try {
+ list.getFirst();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.LinkedList#getLast()
+ */
+ public void test_getLast() {
+ // Test for method java.lang.Object java.util.LinkedList.getLast()
+ assertTrue("Returned incorrect first element", ll.getLast().equals(
+ objArray[objArray.length - 1]));
+
+ LinkedList list = new LinkedList();
+ try {
+ list.getLast();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.LinkedList#indexOf(java.lang.Object)
+ */
+ public void test_indexOfLjava_lang_Object() {
+ // Test for method int java.util.LinkedList.indexOf(java.lang.Object)
+ assertEquals("Returned incorrect index", 87, ll.indexOf(objArray[87]));
+ assertEquals("Returned index for invalid Object", -1, ll
+ .indexOf(new Object()));
+ ll.add(20, null);
+ ll.add(24, null);
+ assertTrue("Index of null should be 20, but got: " + ll.indexOf(null),
+ ll.indexOf(null) == 20);
+ }
+
+ /**
+ * java.util.LinkedList#lastIndexOf(java.lang.Object)
+ */
+ public void test_lastIndexOfLjava_lang_Object() {
+ // Test for method int
+ // java.util.LinkedList.lastIndexOf(java.lang.Object)
+ ll.add(new Integer(99));
+ assertEquals("Returned incorrect index",
+ 100, ll.lastIndexOf(objArray[99]));
+ assertEquals("Returned index for invalid Object", -1, ll
+ .lastIndexOf(new Object()));
+ ll.add(20, null);
+ ll.add(24, null);
+ assertTrue("Last index of null should be 20, but got: "
+ + ll.lastIndexOf(null), ll.lastIndexOf(null) == 24);
+ }
+
+ /**
+ * java.util.LinkedList#listIterator(int)
+ */
+ public void test_listIteratorI() {
+ // Test for method java.util.ListIterator
+ // java.util.LinkedList.listIterator(int)
+ ListIterator i1 = ll.listIterator();
+ ListIterator i2 = ll.listIterator(0);
+ Object elm;
+ int n = 0;
+ while (i2.hasNext()) {
+ if (n == 0 || n == objArray.length - 1) {
+ if (n == 0)
+ assertTrue("First element claimed to have a previous", !i2
+ .hasPrevious());
+ if (n == objArray.length)
+ assertTrue("Last element claimed to have next", !i2
+ .hasNext());
+ }
+ elm = i2.next();
+ assertTrue("Iterator returned elements in wrong order",
+ elm == objArray[n]);
+ if (n > 0 && n < objArray.length - 1) {
+ assertTrue("Next index returned incorrect value",
+ i2.nextIndex() == n + 1);
+ assertTrue("previousIndex returned incorrect value : "
+ + i2.previousIndex() + ", n val: " + n, i2
+ .previousIndex() == n);
+ }
+ elm = i1.next();
+ assertTrue("Iterator returned elements in wrong order",
+ elm == objArray[n]);
+ ++n;
+ }
+
+ i2 = ll.listIterator(ll.size()/2);
+ assertTrue((Integer)i2.next() == ll.size()/2);
+ List myList = new LinkedList();
+ myList.add(null);
+ myList.add("Blah");
+ myList.add(null);
+ myList.add("Booga");
+ myList.add(null);
+ ListIterator li = myList.listIterator();
+ assertTrue("li.hasPrevious() should be false", !li.hasPrevious());
+ assertNull("li.next() should be null", li.next());
+ assertTrue("li.hasPrevious() should be true", li.hasPrevious());
+ assertNull("li.prev() should be null", li.previous());
+ assertNull("li.next() should be null", li.next());
+ assertEquals("li.next() should be Blah", "Blah", li.next());
+ assertNull("li.next() should be null", li.next());
+ assertEquals("li.next() should be Booga", "Booga", li.next());
+ assertTrue("li.hasNext() should be true", li.hasNext());
+ assertNull("li.next() should be null", li.next());
+ assertTrue("li.hasNext() should be false", !li.hasNext());
+
+ try {
+ ll.listIterator(-1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ ll.listIterator(ll.size() + 1);
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.LinkedList#remove(int)
+ */
+ public void test_removeI() {
+ // Test for method java.lang.Object java.util.LinkedList.remove(int)
+ ll.remove(10);
+ assertEquals("Failed to remove element", -1, ll.indexOf(objArray[10]));
+ try {
+ ll.remove(999);
+ fail("Failed to throw expected exception when index out of range");
+ } catch (IndexOutOfBoundsException e) {
+ // Correct
+ }
+
+ ll.add(20, null);
+ ll.remove(20);
+ assertNotNull("Should have removed null", ll.get(20));
+ }
+
+ /**
+ * java.util.LinkedList#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method boolean java.util.LinkedList.remove(java.lang.Object)
+ assertTrue("Failed to remove valid Object", ll.remove(objArray[87]));
+ assertTrue("Removed invalid object", !ll.remove(new Object()));
+ assertEquals("Found Object after removal", -1, ll.indexOf(objArray[87]));
+ ll.add(null);
+ ll.remove(null);
+ assertTrue("Should not contain null afrer removal", !ll.contains(null));
+ }
+
+ /**
+ * java.util.LinkedList#removeFirst()
+ */
+ public void test_removeFirst() {
+ // Test for method java.lang.Object java.util.LinkedList.removeFirst()
+ ll.removeFirst();
+ assertTrue("Failed to remove first element",
+ ll.getFirst() != objArray[0]);
+
+ LinkedList list = new LinkedList();
+ try {
+ list.removeFirst();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.LinkedList#removeLast()
+ */
+ public void test_removeLast() {
+ // Test for method java.lang.Object java.util.LinkedList.removeLast()
+ ll.removeLast();
+ assertTrue("Failed to remove last element",
+ ll.getLast() != objArray[objArray.length - 1]);
+
+ LinkedList list = new LinkedList();
+ try {
+ list.removeLast();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.LinkedList#set(int, java.lang.Object)
+ */
+ public void test_setILjava_lang_Object() {
+ // Test for method java.lang.Object java.util.LinkedList.set(int,
+ // java.lang.Object)
+ Object obj;
+ ll.set(65, obj = new Object());
+ assertTrue("Failed to set object", ll.get(65) == obj);
+
+ try {
+ ll.set(-1, obj = new Object());
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ ll.set(ll.size() + 1, obj = new Object());
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.LinkedList#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.LinkedList.size()
+ assertTrue("Returned incorrect size", ll.size() == objArray.length);
+ ll.removeFirst();
+ assertTrue("Returned incorrect size", ll.size() == objArray.length - 1);
+ }
+
+ /**
+ * java.util.LinkedList#toArray()
+ */
+ public void test_toArray() {
+ // Test for method java.lang.Object [] java.util.LinkedList.toArray()
+ ll.add(null);
+ Object[] obj = ll.toArray();
+ assertEquals("Returned array of incorrect size", objArray.length + 1, obj.length);
+
+ for (int i = 0; i < obj.length - 1; i++)
+ assertTrue("Returned incorrect array: " + i, obj[i] == objArray[i]);
+ assertNull("Returned incorrect array--end isn't null",
+ obj[obj.length - 1]);
+ }
+
+ /**
+ * java.util.LinkedList#toArray(java.lang.Object[])
+ */
+ public void test_toArray$Ljava_lang_Object() {
+ // Test for method java.lang.Object []
+ // java.util.LinkedList.toArray(java.lang.Object [])
+ Integer[] argArray = new Integer[100];
+ Object[] retArray;
+ retArray = ll.toArray(argArray);
+ assertTrue("Returned different array than passed", retArray == argArray);
+ List retList = new LinkedList(Arrays.asList(retArray));
+ Iterator li = ll.iterator();
+ Iterator ri = retList.iterator();
+ while (li.hasNext())
+ assertTrue("Lists are not equal", li.next() == ri.next());
+ argArray = new Integer[1000];
+ retArray = ll.toArray(argArray);
+ assertNull("Failed to set first extra element to null", argArray[ll
+ .size()]);
+ for (int i = 0; i < ll.size(); i++)
+ assertTrue("Returned incorrect array: " + i,
+ retArray[i] == objArray[i]);
+ ll.add(50, null);
+ argArray = new Integer[101];
+ retArray = ll.toArray(argArray);
+ assertTrue("Returned different array than passed", retArray == argArray);
+ retArray = ll.toArray(argArray);
+ assertTrue("Returned different array than passed", retArray == argArray);
+ retList = new LinkedList(Arrays.asList(retArray));
+ li = ll.iterator();
+ ri = retList.iterator();
+ while (li.hasNext())
+ assertTrue("Lists are not equal", li.next() == ri.next());
+
+ try {
+ ll.toArray(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ LinkedList<String> lls = new LinkedList<String>();
+ lls.add("First");
+ lls.add("Second");
+
+ try {
+ lls.toArray(argArray);
+ fail("ArrayStoreException expected");
+ } catch (ArrayStoreException e) {
+ //expected
+ }
+ }
+
+ public void test_offer() {
+ int origSize = ll.size();
+ assertTrue("offer() should return true'", ll.offer(objArray[0]));
+ assertEquals("offer() should add an element as the last one", origSize, ll.lastIndexOf(objArray[0]));
+ }
+
+ public void test_poll() {
+ for (int i = 0; i < objArray.length; i++) {
+ assertEquals("should remove the head", objArray[i], ll.poll());
+ }
+ assertEquals("should be empty", 0, ll.size());
+ assertNull("should return 'null' if list is empty", ll.poll());
+ }
+
+ public void test_remove() {
+ for (int i = 0; i < objArray.length; i++) {
+ assertEquals("should remove the head", objArray[i], ll.remove());
+ }
+ assertEquals("should be empty", 0, ll.size());
+ try {
+ ll.remove();
+ fail("NoSuchElementException is expected when removing from the empty list");
+ } catch (NoSuchElementException e) {
+ //-- expected
+ }
+ }
+
+ public void test_element() {
+ assertEquals("should return the head", objArray[0], ll.element());
+ assertEquals("element() should remove nothing", objArray.length, ll.size());
+ try {
+ new LinkedList().remove();
+ fail("NoSuchElementException is expected when the list is empty");
+ } catch (NoSuchElementException e) {
+ //-- expected
+ }
+ }
+
+ /**
+ * {@link java.util.LinkedList#removeFirstOccurrence(Object)}
+ */
+ public void test_removeFirstOccurrence() throws Exception {
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjTwo));
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjThree));
+ assertTrue(testList.offerLast(testObjOne));
+ assertEquals(5, testList.size());
+ assertTrue(testList.removeFirstOccurrence(testObjOne));
+ assertFalse(testList.removeFirstOccurrence(testObjFour));
+ assertEquals(testObjTwo, testList.peekFirst());
+ assertEquals(testObjOne, testList.peekLast());
+ assertEquals(4, testList.size());
+ assertTrue(testList.removeFirstOccurrence(testObjOne));
+ assertEquals(3, testList.size());
+ assertEquals(testObjOne, testList.peekLast());
+ assertTrue(testList.removeFirstOccurrence(testObjOne));
+ assertEquals(2, testList.size());
+ assertEquals(testObjThree, testList.peekLast());
+ assertFalse(testList.removeFirstOccurrence(testObjOne));
+ }
+
+ /**
+ * {@link java.util.LinkedList#removeLastOccurrence(Object)}
+ */
+ public void test_removeLastOccurrence() throws Exception {
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjTwo));
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjThree));
+ assertTrue(testList.offerLast(testObjOne));
+ assertEquals(5, testList.size());
+ assertTrue(testList.removeLastOccurrence(testObjOne));
+ assertFalse(testList.removeLastOccurrence(testObjFour));
+ assertEquals(testObjOne, testList.peekFirst());
+ assertEquals(testObjThree, testList.peekLast());
+ assertEquals(4, testList.size());
+ assertTrue(testList.removeLastOccurrence(testObjOne));
+ assertEquals(3, testList.size());
+ assertEquals(testObjOne, testList.peekFirst());
+ assertEquals(testObjThree, testList.peekLast());
+ assertTrue(testList.removeLastOccurrence(testObjOne));
+ assertEquals(2, testList.size());
+ assertEquals(testObjThree, testList.peekLast());
+ assertFalse(testList.removeLastOccurrence(testObjOne));
+ }
+
+ /**
+ * {@link java.util.LinkedList#offerFirst(Object)}
+ */
+ public void test_offerFirst() throws Exception {
+ assertTrue(testList.offerFirst(testObjOne));
+ assertEquals(1, testList.size());
+ assertEquals(testObjOne, testList.peek());
+ assertTrue(testList.offerFirst(testObjOne));
+ assertEquals(2, testList.size());
+ assertEquals(testObjOne, testList.peek());
+ assertTrue(testList.offerFirst(testObjTwo));
+ assertEquals(3, testList.size());
+ assertEquals(testObjTwo, testList.peek());
+ assertEquals(testObjOne, testList.getLast());
+ assertTrue(testList.offerFirst(null));
+ assertEquals(4, testList.size());
+ }
+
+ /**
+ * {@link java.util.LinkedList#offerLast(Object)}
+ */
+ public void test_offerLast() throws Exception {
+ assertTrue(testList.offerLast(testObjOne));
+ assertEquals(1, testList.size());
+ assertEquals(testObjOne, testList.peek());
+ assertTrue(testList.offerLast(testObjOne));
+ assertEquals(2, testList.size());
+ assertEquals(testObjOne, testList.peek());
+ assertTrue(testList.offerLast(testObjTwo));
+ assertEquals(3, testList.size());
+ assertEquals(testObjOne, testList.peek());
+ assertEquals(testObjTwo, testList.getLast());
+ assertTrue(testList.offerLast(null));
+ assertEquals(4, testList.size());
+ }
+
+ /**
+ * {@link java.util.LinkedList#push(Object)}
+ */
+ public void test_push() throws Exception {
+ testList.push(testObjOne);
+ assertEquals(1, testList.size());
+ assertEquals(testObjOne, testList.peek());
+ testList.push(testObjOne);
+ assertEquals(2, testList.size());
+ assertEquals(testObjOne, testList.peek());
+ testList.push(testObjTwo);
+ assertEquals(3, testList.size());
+ assertEquals(testObjTwo, testList.peek());
+ assertEquals(testObjOne, testList.getLast());
+ testList.push(null);
+ assertEquals(4, testList.size());
+ }
+
+ /**
+ * {@link java.util.LinkedList#pop()}
+ */
+ public void test_pop() throws Exception {
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjTwo));
+ assertTrue(testList.offerLast(testObjThree));
+ assertEquals(3, testList.size());
+ assertEquals(testObjOne, testList.pop());
+ assertEquals(2, testList.size());
+ assertEquals(testObjTwo, testList.pop());
+ assertEquals(testObjThree, testList.pop());
+ assertEquals(0, testList.size());
+ testList.push(null);
+ assertEquals(1, testList.size());
+ assertNull(testList.pop());
+ try {
+ testList.pop();
+ fail("should throw NoSuchElementException ");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.LinkedList#descendingIterator()}
+ */
+ public void test_descendingIterator() throws Exception {
+ assertFalse(testList.descendingIterator().hasNext());
+ assertTrue(testList.add(testObjOne));
+ assertTrue(testList.add(testObjTwo));
+ assertTrue(testList.add(testObjOne));
+ assertTrue(testList.add(testObjThree));
+ assertTrue(testList.add(testObjLast));
+ Iterator result = testList.descendingIterator();
+ assertEquals(5, testList.size());
+ try {
+ result.remove();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ assertTrue(testList.add(testObjFour));
+
+ try {
+ assertEquals(testObjLast, result.next());
+ fail("should throw ConcurrentModificationException");
+ } catch (ConcurrentModificationException e) {
+ // expected
+ }
+
+ result = testList.descendingIterator();
+ assertEquals(testObjFour, result.next());
+ assertEquals(testObjLast, result.next());
+ assertEquals(testObjThree, result.next());
+ assertEquals(testObjOne, result.next());
+ assertEquals(testObjTwo, result.next());
+ assertTrue(result.hasNext());
+ result.remove();
+ assertEquals(testObjOne, result.next());
+ assertFalse(result.hasNext());
+ try {
+ result.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.LinkedList#pollFirst()}
+ */
+ public void test_pollFirst() throws Exception {
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjTwo));
+ assertTrue(testList.offerLast(testObjThree));
+ assertEquals(3, testList.size());
+ assertEquals(testObjOne, testList.pollFirst());
+ assertEquals(2, testList.size());
+ assertEquals(testObjTwo, testList.pollFirst());
+ assertEquals(testObjThree, testList.pollFirst());
+ assertEquals(0, testList.size());
+ assertNull(testList.pollFirst());
+ }
+
+ /**
+ * {@link java.util.LinkedList#pollLast()}
+ */
+ public void test_pollLast() throws Exception {
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjTwo));
+ assertTrue(testList.offerLast(testObjThree));
+ assertEquals(3, testList.size());
+ assertEquals(testObjThree, testList.pollLast());
+ assertEquals(2, testList.size());
+ assertEquals(testObjTwo, testList.pollLast());
+ assertEquals(testObjOne, testList.pollLast());
+ assertEquals(0, testList.size());
+ assertNull(testList.pollFirst());
+ }
+
+ /**
+ * {@link java.util.LinkedList#peekFirst()}
+ */
+ public void test_peekFirst() throws Exception {
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjTwo));
+ assertTrue(testList.offerLast(testObjThree));
+ assertEquals(3, testList.size());
+ assertEquals(testObjOne, testList.peekFirst());
+ assertEquals(3, testList.size());
+ assertEquals(testObjOne, testList.pollFirst());
+ assertEquals(testObjTwo, testList.peekFirst());
+ assertEquals(testObjTwo, testList.pollFirst());
+ assertEquals(testObjThree, testList.pollFirst());
+ assertEquals(0, testList.size());
+ assertEquals(null, testList.peekFirst());
+ }
+
+ /**
+ * {@link java.util.LinkedList#peek()}
+ */
+ public void test_peekLast() throws Exception {
+ assertTrue(testList.offerLast(testObjOne));
+ assertTrue(testList.offerLast(testObjTwo));
+ assertTrue(testList.offerLast(testObjThree));
+ assertEquals(3, testList.size());
+ assertEquals(testObjThree, testList.peekLast());
+ assertEquals(3, testList.size());
+ assertEquals(testObjThree, testList.pollLast());
+ assertEquals(testObjTwo, testList.peekLast());
+ assertEquals(testObjTwo, testList.pollLast());
+ assertEquals(testObjOne, testList.pollLast());
+ assertEquals(0, testList.size());
+ assertNull(testList.peekLast());
+ }
+
+ /**
+ * java.util.LinkedList#Serialization()
+ */
+ public void test_serialization() throws Exception {
+ assertTrue(ll.add(new Integer(1)));
+ assertTrue(ll.add(new Integer(2)));
+ assertTrue(ll.add(new Integer(3)));
+ assertTrue(ll.add(new Integer(4)));
+ assertTrue(ll.add(new Integer(5)));
+ SerializationTest.verifySelf(ll, new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+ LinkedList<Object> formerQue = (LinkedList) initial;
+ LinkedList<Object> deserializedQue = (LinkedList) deserialized;
+ assertEquals(formerQue.remove(), deserializedQue.remove());
+ }
+ });
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ objArray = new Object[100];
+ for (int i = 0; i < objArray.length; i++) {
+ objArray[i] = new Integer(i);
+ }
+
+ ll = new LinkedList();
+ for (int i = 0; i < objArray.length; i++) {
+ ll.add(objArray[i]);
+ }
+
+ testList = new LinkedList<Object>();
+ testObjOne = new Object();
+ testObjTwo = new Object();
+ testObjThree = new Object();
+ testObjFour = new Object();
+ testObjLast = new Object();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ListResourceBundleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ListResourceBundleTest.java
new file mode 100644
index 0000000..6a85161
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ListResourceBundleTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Enumeration;
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+public class ListResourceBundleTest extends junit.framework.TestCase {
+ /**
+ * java.util.ListResourceBundle#getKeys()
+ */
+ public void test_getKeys() {
+ ResourceBundle bundle;
+ String name = "tests.support.Support_TestResource";
+ Locale.setDefault(new Locale("en", "US"));
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
+ Enumeration<String> keys = bundle.getKeys();
+ Vector<String> result = new Vector<String>();
+ while (keys.hasMoreElements()) {
+ result.addElement(keys.nextElement());
+ }
+ assertTrue("Missing key parent1", result.contains("parent1"));
+ assertTrue("Missing key parent2", result.contains("parent2"));
+ assertTrue("Missing key parent3", result.contains("parent3"));
+ assertTrue("Missing key parent4", result.contains("parent4"));
+ assertTrue("Missing key child1", result.contains("child1"));
+ assertTrue("Missing key child2", result.contains("child2"));
+ assertTrue("Missing key child3", result.contains("child3"));
+ }
+
+ public void test_handleGetObjectLjava_lang_String() {
+ ListResourceBundle bundle;
+ String name = "tests.support.Support_TestResource";
+ Locale.setDefault(new Locale("en", "US"));
+ bundle = (ListResourceBundle) ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
+ Enumeration keys = bundle.getKeys();
+ String keyValue = null;
+ Vector result = new Vector();
+ while (keys.hasMoreElements()) {
+ result.addElement(bundle.handleGetObject((String)keys.nextElement()));
+ }
+ assertEquals(9, result.size());
+ assertTrue(result.contains(null));
+ assertTrue(result.contains("frFRVARValue4"));
+ assertTrue(result.contains("frFRVARChildValue1"));
+ assertTrue(result.contains("frFRVARChildValue2"));
+ assertTrue(result.contains("frFRVARChildValue3"));
+ assertTrue(result.remove(null));
+ assertTrue(result.remove(null));
+ assertTrue(result.remove(null));
+ }
+
+ protected void setUp() {
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java
new file mode 100644
index 0000000..dfb2d96
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java
@@ -0,0 +1,449 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+public class LocaleTest extends junit.framework.TestCase {
+
+ Locale testLocale;
+
+ Locale l;
+
+ Locale defaultLocale;
+
+ /**
+ * java.util.Locale#Locale(java.lang.String, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.util.Locale(java.lang.String)
+ Locale x = new Locale("xx");
+ assertTrue("Failed to create Locale", x.getVariant().equals(""));
+
+ try {
+ new Locale(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Locale#Locale(java.lang.String, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+ // Test for method java.util.Locale(java.lang.String, java.lang.String)
+ Locale x = new Locale("xx", "CV");
+ assertTrue("Failed to create Locale", x.getCountry().equals("CV")
+ && x.getVariant().equals(""));
+
+ try {
+ new Locale("xx", null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ try {
+ new Locale(null, "CV");
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Locale#Locale(java.lang.String, java.lang.String,
+ * java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String() {
+ // Test for method java.util.Locale(java.lang.String, java.lang.String,
+ // java.lang.String)
+ Locale x = new Locale("xx", "CV", "ZZ");
+ assertTrue("Failed to create Locale", x.getLanguage().equals("xx")
+ && (x.getCountry().equals("CV") && x.getVariant().equals("ZZ")));
+ try {
+ new Locale(null, "CV", "ZZ");
+ fail("expected NullPointerException with 1st parameter == null");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ new Locale("xx", null, "ZZ");
+ fail("expected NullPointerException with 2nd parameter == null");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ new Locale("xx", "CV", null);
+ fail("expected NullPointerException with 3rd parameter == null");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.util.Locale#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.Locale.clone()
+ assertTrue("Clone failed", l.clone().equals(l));
+ }
+
+ /**
+ * java.util.Locale#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean java.util.Locale.equals(java.lang.Object)
+ Locale l2 = new Locale("en", "CA", "WIN32");
+ assertTrue("Same object returned false", testLocale.equals(testLocale));
+ assertTrue("Same values returned false", testLocale.equals(l2));
+ assertTrue("Different locales returned true", !testLocale.equals(l));
+
+ }
+
+ /**
+ * java.util.Locale#getAvailableLocales()
+ */
+ public void test_getAvailableLocales() {
+// BEGIN android-changed
+ // Test for method java.util.Locale []
+ // java.util.Locale.getAvailableLocales()
+ // Assumes there will generally be about 10+ available locales...
+ // even in minimal configurations for android
+ try {
+ Locale[] locales = Locale.getAvailableLocales();
+ assertTrue("Wrong number of locales: " + locales.length, locales.length > 10);
+ // regression test for HARMONY-1514
+ // HashSet can filter duplicate locales
+ Set<Locale> localesSet = new HashSet<Locale>(Arrays.asList(locales));
+ assertEquals(localesSet.size(), locales.length);
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+// END android-changed
+ }
+
+ /**
+ * java.util.Locale#getCountry()
+ */
+ public void test_getCountry() {
+ // Test for method java.lang.String java.util.Locale.getCountry()
+ assertTrue("Returned incorrect country: " + testLocale.getCountry(),
+ testLocale.getCountry().equals("CA"));
+ }
+
+ /**
+ * java.util.Locale#getDefault()
+ */
+ public void test_getDefault() {
+ // Test for method java.util.Locale java.util.Locale.getDefault()
+ assertTrue("returns copy", Locale.getDefault() == Locale.getDefault());
+ Locale org = Locale.getDefault();
+ Locale.setDefault(l);
+ Locale x = Locale.getDefault();
+ Locale.setDefault(org);
+ assertEquals("Failed to get locale", "fr_CA_WIN32", x.toString());
+ }
+
+ /**
+ * java.util.Locale#getDisplayCountry()
+ */
+ public void test_getDisplayCountry() {
+ // Test for method java.lang.String java.util.Locale.getDisplayCountry()
+ assertTrue("Returned incorrect country: "
+ + testLocale.getDisplayCountry(), testLocale
+ .getDisplayCountry().equals("Canada"));
+
+ // Regression for Harmony-1146
+ Locale l_countryCD = new Locale("", "CD");
+ assertEquals("Congo (DRC)",
+ l_countryCD.getDisplayCountry());
+ }
+
+ public void test_getDisplayCountryLjava_util_Locale() {
+ assertEquals("Italie", Locale.ITALY.getDisplayCountry(new Locale("fr", "CA", "WIN32")));
+ }
+
+ /**
+ * java.util.Locale#getDisplayLanguage()
+ */
+ public void test_getDisplayLanguage() {
+ // Test for method java.lang.String
+ // java.util.Locale.getDisplayLanguage()
+ assertTrue("Returned incorrect language: "
+ + testLocale.getDisplayLanguage(), testLocale
+ .getDisplayLanguage().equals("English"));
+
+ // Regression for Harmony-1146
+ Locale l_languageAE = new Locale("ae", "");
+ assertEquals("Avestan", l_languageAE.getDisplayLanguage());
+
+ // Regression for HARMONY-4402
+ Locale defaultLocale = Locale.getDefault();
+ try {
+ Locale locale = new Locale("no", "NO");
+ Locale.setDefault(locale);
+ assertEquals("norsk", locale.getDisplayLanguage());
+ } finally {
+ Locale.setDefault(defaultLocale);
+ }
+ }
+
+ public void test_getDisplayLanguageLjava_util_Locale() {
+ assertEquals("anglais", new Locale("en", "CA", "WIN32").getDisplayLanguage(l));
+ }
+
+ public void test_getDisplayName() {
+ assertEquals("English (Canada,WIN32)", new Locale("en", "CA", "WIN32").getDisplayName());
+ }
+
+ public void test_getDisplayNameLjava_util_Locale() {
+ assertEquals("anglais (Canada,WIN32)", new Locale("en", "CA", "WIN32").getDisplayName(l));
+ }
+
+ /**
+ * java.util.Locale#getDisplayVariant()
+ */
+ public void test_getDisplayVariant() {
+ // Test for method java.lang.String java.util.Locale.getDisplayVariant()
+ assertTrue("Returned incorrect variant: "
+ + testLocale.getDisplayVariant(), testLocale
+ .getDisplayVariant().equals("WIN32"));
+ }
+
+ /**
+ * java.util.Locale#getDisplayVariant(java.util.Locale)
+ */
+ public void test_getDisplayVariantLjava_util_Locale() {
+ // Test for method java.lang.String
+ // java.util.Locale.getDisplayVariant(java.util.Locale)
+ assertTrue("Returned incorrect variant: "
+ + testLocale.getDisplayVariant(l), testLocale
+ .getDisplayVariant(l).equals("WIN32"));
+ }
+
+ /**
+ * java.util.Locale#getISO3Country()
+ */
+ public void test_getISO3Country() {
+ // Test for method java.lang.String java.util.Locale.getISO3Country()
+ assertTrue("Returned incorrect ISO3 country: "
+ + testLocale.getISO3Country(), testLocale.getISO3Country()
+ .equals("CAN"));
+
+ Locale l = new Locale("", "CD");
+ assertEquals("COD", l.getISO3Country());
+ }
+
+ /**
+ * java.util.Locale#getISO3Language()
+ */
+ public void test_getISO3Language() {
+ // Test for method java.lang.String java.util.Locale.getISO3Language()
+ assertTrue("Returned incorrect ISO3 language: "
+ + testLocale.getISO3Language(), testLocale.getISO3Language()
+ .equals("eng"));
+
+ Locale l = new Locale("ae");
+ assertEquals("ave", l.getISO3Language());
+
+ // Regression for Harmony-1146
+ Locale l_CountryCS = new Locale("", "CS");
+ assertEquals("SCG", l_CountryCS.getISO3Country());
+
+ // Regression for Harmony-1129
+ l = new Locale("ak", "");
+ assertEquals("aka", l.getISO3Language());
+ }
+
+ /**
+ * java.util.Locale#getISOCountries()
+ */
+ public void test_getISOCountries() {
+ // Test for method java.lang.String []
+ // java.util.Locale.getISOCountries()
+ // Assumes all countries are 2 digits, and that there will always be
+ // 230 countries on the list...
+ String[] isoCountries = Locale.getISOCountries();
+ int length = isoCountries.length;
+ int familiarCount = 0;
+ for (int i = 0; i < length; i++) {
+ if (isoCountries[i].length() != 2) {
+ fail("Wrong format for ISOCountries.");
+ }
+ if (isoCountries[i].equals("CA") || isoCountries[i].equals("BB")
+ || isoCountries[i].equals("US")
+ || isoCountries[i].equals("KR"))
+ familiarCount++;
+ }
+ assertTrue("ISOCountries missing.", familiarCount == 4 && length > 230);
+ }
+
+ /**
+ * java.util.Locale#getISOLanguages()
+ */
+ public void test_getISOLanguages() {
+ // Test for method java.lang.String []
+ // java.util.Locale.getISOLanguages()
+ // Assumes always at least 131 ISOlanguages...
+ String[] isoLang = Locale.getISOLanguages();
+ int length = isoLang.length;
+
+ // BEGIN android-changed
+ // Language codes are 2- and 3-letter, with preference given
+ // to 2-letter codes where possible. 3-letter codes are used
+ // when lack a 2-letter equivalent.
+ assertTrue("Random element in wrong format.",
+ (isoLang[length / 2].length() == 2 || isoLang[length / 2].length() == 3)
+ && isoLang[length / 2].toLowerCase().equals(isoLang[length / 2]));
+ // END android-changed
+
+ assertTrue("Wrong number of ISOLanguages.", length > 130);
+ }
+
+ /**
+ * java.util.Locale#getLanguage()
+ */
+ public void test_getLanguage() {
+ // Test for method java.lang.String java.util.Locale.getLanguage()
+ assertTrue("Returned incorrect language: " + testLocale.getLanguage(),
+ testLocale.getLanguage().equals("en"));
+ }
+
+ /**
+ * java.util.Locale#getVariant()
+ */
+ public void test_getVariant() {
+ // Test for method java.lang.String java.util.Locale.getVariant()
+ assertTrue("Returned incorrect variant: " + testLocale.getVariant(),
+ testLocale.getVariant().equals("WIN32"));
+ }
+
+ /**
+ * java.util.Locale#setDefault(java.util.Locale)
+ */
+ public void test_setDefaultLjava_util_Locale() {
+ // Test for method void java.util.Locale.setDefault(java.util.Locale)
+
+ Locale org = Locale.getDefault();
+ Locale.setDefault(l);
+ Locale x = Locale.getDefault();
+ Locale.setDefault(org);
+ assertEquals("Failed to set locale", "fr_CA_WIN32", x.toString());
+
+ Locale.setDefault(new Locale("tr", ""));
+ String res1 = "\u0069".toUpperCase();
+ String res2 = "\u0049".toLowerCase();
+ Locale.setDefault(org);
+ assertEquals("Wrong toUppercase conversion", "\u0130", res1);
+ assertEquals("Wrong toLowercase conversion", "\u0131", res2);
+
+ try {
+ Locale.setDefault(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Locale#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.util.Locale.toString()
+ assertEquals("en_CA_WIN32", new Locale("en", "CA", "WIN32").toString());
+
+ Locale l = new Locale("en", "");
+ assertEquals("Wrong representation 1", "en", l.toString());
+ l = new Locale("", "CA");
+ assertEquals("Wrong representation 2", "_CA", l.toString());
+
+ // Non-bug difference for HARMONY-5442
+ l = new Locale("", "CA", "var");
+ assertEquals("Wrong representation 2.5", "_CA_var", l.toString());
+ l = new Locale("en", "", "WIN");
+ assertEquals("Wrong representation 4", "en__WIN", l.toString());
+ l = new Locale("en", "CA");
+ assertEquals("Wrong representation 6", "en_CA", l.toString());
+ l = new Locale("en", "CA", "VAR");
+ assertEquals("Wrong representation 7", "en_CA_VAR", l.toString());
+
+ l = new Locale("", "", "var");
+ assertEquals("Wrong representation 8", "", l.toString());
+
+ }
+
+ public void test_hashCode() {
+ Locale l1 = new Locale("en", "US");
+ Locale l2 = new Locale("fr", "CA");
+
+ assertTrue(l1.hashCode() != l2.hashCode());
+ }
+
+ /**
+ * {@value java.util.Locale#ROOT}
+ * @since 1.6
+ */
+ public void test_constantROOT() {
+ Locale root = Locale.ROOT;
+ assertEquals("", root.getLanguage());
+ assertEquals("", root.getCountry());
+ assertEquals("", root.getVariant());
+ }
+
+// BEGIN android-removed
+// These locales are not part of the android reference impl
+// // Regression Test for HARMONY-2953
+// public void test_getISO() {
+// Locale locale = new Locale("an");
+// assertEquals("arg", locale.getISO3Language());
+//
+// locale = new Locale("PS");
+// assertEquals("pus", locale.getISO3Language());
+//
+// List<String> languages = Arrays.asList(Locale.getISOLanguages());
+// assertTrue(languages.contains("ak"));
+//
+// List<String> countries = Arrays.asList(Locale.getISOCountries());
+// assertTrue(countries.contains("CS"));
+// }
+// END android-removed
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ defaultLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ testLocale = new Locale("en", "CA", "WIN32");
+ l = new Locale("fr", "CA", "WIN32");
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ Locale.setDefault(defaultLocale);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingFormatArgumentExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingFormatArgumentExceptionTest.java
new file mode 100644
index 0000000..464960a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingFormatArgumentExceptionTest.java
@@ -0,0 +1,97 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.MissingFormatArgumentException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class MissingFormatArgumentExceptionTest extends TestCase {
+
+ /**
+ * java.util.MissingFormatArgumentException#MissingFormatArgumentException(String)
+ */
+ public void test_missingFormatArgumentException() {
+
+ try {
+ new MissingFormatArgumentException(null);
+ fail("should throw NullPointerExcepiton.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.MissingFormatArgumentException#getFormatSpecifier()
+ */
+ public void test_getFormatSpecifier() {
+ String s = "MYTESTSTRING";
+ MissingFormatArgumentException missingFormatArgumentException = new MissingFormatArgumentException(
+ s);
+ assertEquals(s, missingFormatArgumentException.getFormatSpecifier());
+ }
+
+ /**
+ * java.util.MissingFormatArgumentException#getMessage()
+ */
+ public void test_getMessage() {
+ String s = "MYTESTSTRING";
+ MissingFormatArgumentException missingFormatArgumentException = new MissingFormatArgumentException(
+ s);
+ assertTrue(null != missingFormatArgumentException.getMessage());
+
+ }
+
+ // comparator for comparing MissingFormatArgumentException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ MissingFormatArgumentException initEx = (MissingFormatArgumentException) initial;
+ MissingFormatArgumentException desrEx = (MissingFormatArgumentException) deserialized;
+
+ assertEquals("FormatSpecifier", initEx.getFormatSpecifier(), desrEx
+ .getFormatSpecifier());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new MissingFormatArgumentException(
+ "MYTESTSTRING"), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new MissingFormatArgumentException("MYTESTSTRING"),
+ exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingFormatWidthExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingFormatWidthExceptionTest.java
new file mode 100644
index 0000000..cf3d25f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingFormatWidthExceptionTest.java
@@ -0,0 +1,95 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.MissingFormatWidthException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class MissingFormatWidthExceptionTest extends TestCase {
+
+ /**
+ * java.util.MissingFormatWidthException#MissingFormatWidthException(String)
+ */
+ public void test_missingFormatWidthException() {
+ try {
+ new MissingFormatWidthException(null);
+ fail("should throw NullPointerExcepiton");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.MissingFormatWidthException#getFormatSpecifier()
+ */
+ public void test_getFormatSpecifier() {
+ String s = "MYTESTSTRING";
+ MissingFormatWidthException missingFormatWidthException = new MissingFormatWidthException(
+ s);
+ assertEquals(s, missingFormatWidthException.getFormatSpecifier());
+
+ }
+
+ /**
+ * java.util.MissingFormatWidthException#getMessage()
+ */
+ public void test_getMessage() {
+ String s = "MYTESTSTRING";
+ MissingFormatWidthException missingFormatWidthException = new MissingFormatWidthException(
+ s);
+ assertTrue(null != missingFormatWidthException.getMessage());
+
+ }
+
+ // comparator for comparing MissingFormatWidthException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ MissingFormatWidthException initEx = (MissingFormatWidthException) initial;
+ MissingFormatWidthException desrEx = (MissingFormatWidthException) deserialized;
+
+ assertEquals("FormatSpecifier", initEx.getFormatSpecifier(), desrEx
+ .getFormatSpecifier());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new MissingFormatWidthException(
+ "MYTESTSTRING"), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new MissingFormatWidthException(
+ "MYTESTSTRING"), exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingResourceExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingResourceExceptionTest.java
new file mode 100644
index 0000000..3eb9bac
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/MissingResourceExceptionTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class MissingResourceExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.util.MissingResourceException#MissingResourceException(java.lang.String,
+ * java.lang.String, java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String() {
+ // Test for method java.util.MissingResourceException(java.lang.String,
+ // java.lang.String, java.lang.String)
+ assertNotNull(new MissingResourceException("Detail string", "Class name string", "Key string"));
+ assertNotNull(new MissingResourceException(null, "Class name string", "Key string"));
+ assertNotNull(new MissingResourceException("Detail string", null, "Key string"));
+ assertNotNull(new MissingResourceException("Detail string", "Class name string", null));
+ try {
+ ResourceBundle.getBundle("Non-ExistentBundle");
+ } catch (MissingResourceException e) {
+ return;
+ }
+ fail("Failed to generate expected exception");
+ }
+
+ /**
+ * java.util.MissingResourceException#getClassName()
+ */
+ public void test_getClassName() {
+ // Test for method java.lang.String
+ // java.util.MissingResourceException.getClassName()
+ try {
+ ResourceBundle.getBundle("Non-ExistentBundle");
+ } catch (MissingResourceException e) {
+ assertEquals("Returned incorrect class name", "Non-ExistentBundle"
+ + '_' + Locale.getDefault(), e.getClassName());
+ }
+ }
+
+ /**
+ * java.util.MissingResourceException#getKey()
+ */
+ public void test_getKey() {
+ // Test for method java.lang.String
+ // java.util.MissingResourceException.getKey()
+ try {
+ ResourceBundle.getBundle("Non-ExistentBundle");
+ } catch (MissingResourceException e) {
+ assertTrue("Returned incorrect class name", e.getKey().equals(""));
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/NoSuchElementExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/NoSuchElementExceptionTest.java
new file mode 100644
index 0000000..7727f3f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/NoSuchElementExceptionTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+public class NoSuchElementExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.util.NoSuchElementException#NoSuchElementException()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.NoSuchElementException()
+
+ assertNotNull(new NoSuchElementException());
+
+ try {
+ Vector v = new Vector();
+ v.elements().nextElement();
+ fail("NoSuchElementException expected");
+ } catch (NoSuchElementException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.NoSuchElementException#NoSuchElementException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.util.NoSuchElementException(java.lang.String)
+
+ assertNotNull(new NoSuchElementException("String"));
+ assertNotNull(new NoSuchElementException(null));
+
+ try {
+ Vector v = new Vector();
+ v.firstElement();
+ fail("NoSuchElementException expected");
+ } catch (NoSuchElementException e) {
+ //expected
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ObservableTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ObservableTest.java
new file mode 100644
index 0000000..b13a876
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ObservableTest.java
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Vector;
+
+public class ObservableTest extends junit.framework.TestCase {
+
+ static class TestObserver implements Observer {
+ public Vector objv = new Vector();
+
+ int updateCount = 0;
+
+ public void update(Observable observed, Object arg) {
+ ++updateCount;
+ objv.add(arg);
+ }
+
+ public int updateCount() {
+ return updateCount;
+ }
+
+ }
+
+ static class DeleteTestObserver implements Observer {
+ int updateCount = 0;
+
+ boolean deleteAll = false;
+
+ public DeleteTestObserver(boolean all) {
+ deleteAll = all;
+ }
+
+ public void update(Observable observed, Object arg) {
+ ++updateCount;
+ if (deleteAll)
+ observed.deleteObservers();
+ else
+ observed.deleteObserver(this);
+ }
+
+ public int updateCount() {
+ return updateCount;
+ }
+
+ }
+
+ static class TestObservable extends Observable {
+ public void doChange() {
+ setChanged();
+ }
+
+ public void clearChange() {
+ clearChanged();
+ }
+ }
+
+ Observer observer;
+
+ TestObservable observable;
+
+ /**
+ * java.util.Observable#Observable()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.Observable()
+ try {
+ Observable ov = new Observable();
+ assertTrue("Wrong initial values.", !ov.hasChanged());
+ assertEquals("Wrong initial values.", 0, ov.countObservers());
+ } catch (Exception e) {
+ fail("Exception during test : " + e.getMessage());
+ }
+ }
+
+ /**
+ * java.util.Observable#addObserver(java.util.Observer)
+ */
+ public void test_addObserverLjava_util_Observer() {
+ // Test for method void
+ // java.util.Observable.addObserver(java.util.Observer)
+ TestObserver test = new TestObserver();
+ observable.addObserver(test);
+ assertEquals("Failed to add observer", 1, observable.countObservers());
+ observable.addObserver(test);
+ assertEquals("Duplicate observer", 1, observable.countObservers());
+
+ Observable o = new Observable();
+ try {
+ o.addObserver(null);
+ fail("Expected adding a null observer to throw a NPE.");
+ } catch (NullPointerException ex) {
+ // expected;
+ } catch (Throwable ex) {
+ fail("Did not expect adding a new observer to throw a "
+ + ex.getClass().getName());
+ }
+ }
+
+ /**
+ * java.util.Observable#countObservers()
+ */
+ public void test_countObservers() {
+ // Test for method int java.util.Observable.countObservers()
+ assertEquals("New observable had > 0 observers", 0, observable
+ .countObservers());
+ observable.addObserver(new TestObserver());
+ assertEquals("Observable with observer returned other than 1", 1, observable
+ .countObservers());
+ }
+
+ /**
+ * java.util.Observable#deleteObserver(java.util.Observer)
+ */
+ public void test_deleteObserverLjava_util_Observer() {
+ // Test for method void
+ // java.util.Observable.deleteObserver(java.util.Observer)
+ observable.addObserver(observer = new TestObserver());
+ observable.deleteObserver(observer);
+ assertEquals("Failed to delete observer",
+ 0, observable.countObservers());
+ observable.deleteObserver(observer);
+ observable.deleteObserver(null);
+ }
+
+ /**
+ * java.util.Observable#deleteObservers()
+ */
+ public void test_deleteObservers() {
+ // Test for method void java.util.Observable.deleteObservers()
+ observable.addObserver(new TestObserver());
+ observable.addObserver(new TestObserver());
+ observable.addObserver(new TestObserver());
+ observable.addObserver(new TestObserver());
+ observable.addObserver(new TestObserver());
+ observable.addObserver(new TestObserver());
+ observable.addObserver(new TestObserver());
+ observable.addObserver(new TestObserver());
+ observable.deleteObservers();
+ assertEquals("Failed to delete observers",
+ 0, observable.countObservers());
+ }
+
+ /**
+ * java.util.Observable#hasChanged()
+ */
+ public void test_hasChanged() {
+ assertFalse(observable.hasChanged());
+ observable.addObserver(observer = new TestObserver());
+ observable.doChange();
+ assertTrue(observable.hasChanged());
+ }
+
+ public void test_clearChanged() {
+ assertFalse(observable.hasChanged());
+ observable.addObserver(observer = new TestObserver());
+ observable.doChange();
+ assertTrue(observable.hasChanged());
+ observable.clearChange();
+ assertFalse(observable.hasChanged());
+ }
+
+ /**
+ * java.util.Observable#notifyObservers()
+ */
+ public void test_notifyObservers() {
+ // Test for method void java.util.Observable.notifyObservers()
+ observable.addObserver(observer = new TestObserver());
+ observable.notifyObservers();
+ assertEquals("Notified when unchnaged", 0, ((TestObserver) observer)
+ .updateCount());
+ ((TestObservable) observable).doChange();
+ observable.notifyObservers();
+ assertEquals("Failed to notify",
+ 1, ((TestObserver) observer).updateCount());
+
+ DeleteTestObserver observer1, observer2;
+ observable.deleteObservers();
+ observable.addObserver(observer1 = new DeleteTestObserver(false));
+ observable.addObserver(observer2 = new DeleteTestObserver(false));
+ observable.doChange();
+ observable.notifyObservers();
+ assertTrue("Failed to notify all", observer1.updateCount() == 1
+ && observer2.updateCount() == 1);
+ assertEquals("Failed to delete all", 0, observable.countObservers());
+
+ observable.addObserver(observer1 = new DeleteTestObserver(false));
+ observable.addObserver(observer2 = new DeleteTestObserver(false));
+ observable.doChange();
+ observable.notifyObservers();
+ assertTrue("Failed to notify all 2", observer1.updateCount() == 1
+ && observer2.updateCount() == 1);
+ assertEquals("Failed to delete all 2", 0, observable.countObservers());
+ }
+
+ /**
+ * java.util.Observable#notifyObservers(java.lang.Object)
+ */
+ public void test_notifyObserversLjava_lang_Object() {
+ // Test for method void
+ // java.util.Observable.notifyObservers(java.lang.Object)
+ Object obj;
+ observable.addObserver(observer = new TestObserver());
+ observable.notifyObservers();
+ assertEquals("Notified when unchanged", 0, ((TestObserver) observer)
+ .updateCount());
+ ((TestObservable) observable).doChange();
+ observable.notifyObservers(obj = new Object());
+ assertEquals("Failed to notify",
+ 1, ((TestObserver) observer).updateCount());
+ assertTrue("Failed to pass Object arg", ((TestObserver) observer).objv
+ .elementAt(0).equals(obj));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ observable = new TestObservable();
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PriorityQueueTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PriorityQueueTest.java
new file mode 100644
index 0000000..9c9d4fe
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PriorityQueueTest.java
@@ -0,0 +1,823 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import junit.framework.TestCase;
+import tests.util.SerializationTester;
+
+public class PriorityQueueTest extends TestCase {
+
+ private static final String SERIALIZATION_FILE_NAME = "serialization/org/apache/harmony/tests/java/util/PriorityQueue.golden.ser";
+
+ /**
+ * java.util.PriorityQueue#iterator()
+ */
+ public void test_iterator() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.offer(array[i]);
+ }
+ Iterator<Integer> iter = integerQueue.iterator();
+ assertNotNull(iter);
+ ArrayList<Integer> iterResult = new ArrayList<Integer>();
+ while (iter.hasNext()) {
+ iterResult.add(iter.next());
+ }
+ Object[] resultArray = iterResult.toArray();
+ Arrays.sort(array);
+ Arrays.sort(resultArray);
+ assertTrue(Arrays.equals(array, resultArray));
+ }
+
+ /**
+ * java.util.PriorityQueue#iterator()
+ */
+ public void test_iterator_empty() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ Iterator<Integer> iter = integerQueue.iterator();
+ try {
+ iter.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ iter = integerQueue.iterator();
+ try {
+ iter.remove();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#iterator()
+ */
+ public void test_iterator_outofbound() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ integerQueue.offer(0);
+ Iterator<Integer> iter = integerQueue.iterator();
+ iter.next();
+ try {
+ iter.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ iter = integerQueue.iterator();
+ iter.next();
+ iter.remove();
+ try {
+ iter.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#iterator()
+ */
+ public void test_iterator_remove() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.offer(array[i]);
+ }
+ Iterator<Integer> iter = integerQueue.iterator();
+ assertNotNull(iter);
+ for (int i = 0; i < array.length; i++) {
+ iter.next();
+ if (2 == i) {
+ iter.remove();
+ }
+ }
+ assertEquals(array.length - 1, integerQueue.size());
+
+ iter = integerQueue.iterator();
+ Integer[] newArray = new Integer[array.length - 1];
+ for (int i = 0; i < newArray.length; i++) {
+ newArray[i] = iter.next();
+ }
+
+ Arrays.sort(newArray);
+ for (int i = 0; i < integerQueue.size(); i++) {
+ assertEquals(newArray[i], integerQueue.poll());
+ }
+ }
+
+ public void test_iterator_removeEquals() {
+ PriorityQueue<String> integerQueue = new PriorityQueue<String>(10, new MockComparatorStringByLength());
+ String[] array = { "ONE", "TWO", "THREE", "FOUR", "FIVE" };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.offer(array[i]);
+ }
+ // Try removing an entry that the comparator says is equal
+ assertFalse(integerQueue.remove("123"));
+ assertFalse(integerQueue.remove("one"));
+ assertTrue(integerQueue.remove("THREE"));
+ }
+
+ /**
+ * java.util.PriorityQueue#iterator()
+ */
+ public void test_iterator_remove_illegalState() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.offer(array[i]);
+ }
+ Iterator<Integer> iter = integerQueue.iterator();
+ assertNotNull(iter);
+ try {
+ iter.remove();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ iter.next();
+ iter.remove();
+ try {
+ iter.remove();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+
+ }
+
+ /**
+ * java.util.PriorityQueue.size()
+ */
+ public void test_size() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ assertEquals(0, integerQueue.size());
+ int[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.offer(array[i]);
+ }
+ assertEquals(array.length, integerQueue.size());
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue()
+ */
+ public void test_Constructor() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ assertNotNull(queue);
+ assertEquals(0, queue.size());
+ assertNull(queue.comparator());
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(int)
+ */
+ public void test_ConstructorI() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>(100);
+ assertNotNull(queue);
+ assertEquals(0, queue.size());
+ assertNull(queue.comparator());
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(int, Comparator<? super E>)
+ */
+ public void test_ConstructorILjava_util_Comparator() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>(100,
+ (Comparator<Object>) null);
+ assertNotNull(queue);
+ assertEquals(0, queue.size());
+ assertNull(queue.comparator());
+
+ MockComparator<Object> comparator = new MockComparator<Object>();
+ queue = new PriorityQueue<Object>(100, comparator);
+ assertNotNull(queue);
+ assertEquals(0, queue.size());
+ assertEquals(comparator, queue.comparator());
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(int, Comparator<? super E>)
+ */
+ public void test_ConstructorILjava_util_Comparator_illegalCapacity() {
+ try {
+ new PriorityQueue<Object>(0, new MockComparator<Object>());
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ new PriorityQueue<Object>(-1, new MockComparator<Object>());
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(int, Comparator<? super E>)
+ */
+ public void test_ConstructorILjava_util_Comparator_cast() {
+ MockComparatorCast<Object> objectComparator = new MockComparatorCast<Object>();
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(100,
+ objectComparator);
+ assertNotNull(integerQueue);
+ assertEquals(0, integerQueue.size());
+ assertEquals(objectComparator, integerQueue.comparator());
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ List<Integer> list = Arrays.asList(array);
+ integerQueue.addAll(list);
+ assertEquals(list.size(), integerQueue.size());
+ // just test here no cast exception raises.
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(Collection)
+ */
+ public void test_ConstructorLjava_util_Colleciton() {
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ List<Integer> list = Arrays.asList(array);
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+ assertEquals(array.length, integerQueue.size());
+ assertNull(integerQueue.comparator());
+ Arrays.sort(array);
+ for (int i = 0; i < array.length; i++) {
+ assertEquals(array[i], integerQueue.poll());
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(Collection)
+ */
+ public void test_ConstructorLjava_util_Colleciton_null() {
+ ArrayList<Object> list = new ArrayList<Object>();
+ list.add(new Float(11));
+ list.add(null);
+ list.add(new Integer(10));
+ try {
+ new PriorityQueue<Object>(list);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(Collection)
+ */
+ public void test_ConstructorLjava_util_Colleciton_non_comparable() {
+ ArrayList<Object> list = new ArrayList<Object>();
+ list.add(new Float(11));
+ list.add(new Integer(10));
+ try {
+ new PriorityQueue<Object>(list);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(Collection)
+ */
+ public void test_ConstructorLjava_util_Colleciton_from_priorityqueue() {
+ String[] array = { "AAAAA", "AA", "AAAA", "AAAAAAAA" };
+ PriorityQueue<String> queue = new PriorityQueue<String>(4,
+ new MockComparatorStringByLength());
+ for (int i = 0; i < array.length; i++) {
+ queue.offer(array[i]);
+ }
+ Collection<String> c = queue;
+ PriorityQueue<String> constructedQueue = new PriorityQueue<String>(c);
+ assertEquals(queue.comparator(), constructedQueue.comparator());
+ while (queue.size() > 0) {
+ assertEquals(queue.poll(), constructedQueue.poll());
+ }
+ assertEquals(0, constructedQueue.size());
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(Collection)
+ */
+ public void test_ConstructorLjava_util_Colleciton_from_sortedset() {
+ int[] array = { 3, 5, 79, -17, 5 };
+ TreeSet<Integer> treeSet = new TreeSet<Integer>(new MockComparator<Integer>());
+ for (int i = 0; i < array.length; i++) {
+ treeSet.add(array[i]);
+ }
+ Collection<? extends Integer> c = treeSet;
+ PriorityQueue<Integer> queue = new PriorityQueue<Integer>(c);
+ assertEquals(treeSet.comparator(), queue.comparator());
+ Iterator<Integer> iter = treeSet.iterator();
+ while (iter.hasNext()) {
+ assertEquals(iter.next(), queue.poll());
+ }
+ assertEquals(0, queue.size());
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(PriorityQueue<? * extends
+ *E>)
+ */
+ public void test_ConstructorLjava_util_PriorityQueue() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ int[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.offer(array[i]);
+ }
+ PriorityQueue<Object> objectQueue = new PriorityQueue<Object>(
+ integerQueue);
+ assertEquals(integerQueue.size(), objectQueue.size());
+ assertEquals(integerQueue.comparator(), objectQueue.comparator());
+ Arrays.sort(array);
+ for (int i = 0; i < array.length; i++) {
+ assertEquals(array[i], objectQueue.poll());
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(PriorityQueue<? * extends
+ *E>)
+ */
+ public void test_ConstructorLjava_util_PriorityQueue_null() {
+ try {
+ new PriorityQueue<Object>((PriorityQueue<Integer>) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(SortedSet<? extends E>)
+ */
+ public void test_ConstructorLjava_util_SortedSet() {
+ int[] array = { 3, 5, 79, -17, 5 };
+ TreeSet<Integer> treeSet = new TreeSet<Integer>();
+ for (int i = 0; i < array.length; i++) {
+ treeSet.add(array[i]);
+ }
+ PriorityQueue<Integer> queue = new PriorityQueue<Integer>(treeSet);
+ Iterator<Integer> iter = treeSet.iterator();
+ while (iter.hasNext()) {
+ assertEquals(iter.next(), queue.poll());
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#PriorityQueue(SortedSet<? extends E>)
+ */
+ public void test_ConstructorLjava_util_SortedSet_null() {
+ try {
+ new PriorityQueue<Integer>((SortedSet<? extends Integer>) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#offer(Object)
+ */
+ public void test_offerLjava_lang_Object() {
+ PriorityQueue<String> queue = new PriorityQueue<String>(10,
+ new MockComparatorStringByLength());
+ String[] array = { "AAAAA", "AA", "AAAA", "AAAAAAAA" };
+ for (int i = 0; i < array.length; i++) {
+ queue.offer(array[i]);
+ }
+ String[] sortedArray = { "AA", "AAAA", "AAAAA", "AAAAAAAA" };
+ for (int i = 0; i < sortedArray.length; i++) {
+ assertEquals(sortedArray[i], queue.poll());
+ }
+ assertEquals(0, queue.size());
+ assertNull(queue.poll());
+ }
+
+ /**
+ * java.util.PriorityQueue#offer(Object)
+ */
+ public void test_offerLjava_lang_Object_null() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ try {
+ queue.offer(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#offer(Object)
+ */
+ public void test_offer_Ljava_lang_Object_non_Comparable() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ queue.offer(new Integer(10));
+ try {
+ queue.offer(new Float(1.3));
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ queue = new PriorityQueue<Object>();
+ queue.offer(new Integer(10));
+ try {
+ queue.offer(new Object());
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#poll()
+ */
+ public void test_poll() {
+ PriorityQueue<String> stringQueue = new PriorityQueue<String>();
+ String[] array = { "MYTESTSTRING", "AAAAA", "BCDEF", "ksTRD", "AAAAA" };
+ for (int i = 0; i < array.length; i++) {
+ stringQueue.offer(array[i]);
+ }
+ Arrays.sort(array);
+ for (int i = 0; i < array.length; i++) {
+ assertEquals(array[i], stringQueue.poll());
+ }
+ assertEquals(0, stringQueue.size());
+ assertNull(stringQueue.poll());
+ }
+
+ /**
+ * java.util.PriorityQueue#poll()
+ */
+ public void test_poll_empty() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ assertEquals(0, queue.size());
+ assertNull(queue.poll());
+ }
+
+ /**
+ * java.util.PriorityQueue#peek()
+ */
+ public void test_peek() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ int[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.add(array[i]);
+ }
+ Arrays.sort(array);
+ assertEquals(new Integer(array[0]), integerQueue.peek());
+ assertEquals(new Integer(array[0]), integerQueue.peek());
+ }
+
+ /**
+ * java.util.PriorityQueue#peek()
+ */
+ public void test_peek_empty() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ assertEquals(0, queue.size());
+ assertNull(queue.peek());
+ assertNull(queue.peek());
+ }
+
+ /**
+ * java.util.PriorityQueue#Clear()
+ */
+ public void test_clear() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ int[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.offer(array[i]);
+ }
+ integerQueue.clear();
+ assertTrue(integerQueue.isEmpty());
+ }
+
+ /**
+ * java.util.PriorityQueue#add(Object)
+ */
+ public void test_add_Ljava_lang_Object() {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.add(array[i]);
+ }
+ Arrays.sort(array);
+ assertEquals(array.length, integerQueue.size());
+ for (int i = 0; i < array.length; i++) {
+ assertEquals(array[i], integerQueue.poll());
+ }
+ assertEquals(0, integerQueue.size());
+ }
+
+ /**
+ * java.util.PriorityQueue#add(Object)
+ */
+ public void test_add_Ljava_lang_Object_null() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ try {
+ queue.add(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#add(Object)
+ */
+ public void test_add_Ljava_lang_Object_non_Comparable() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ queue.add(new Integer(10));
+ try {
+ queue.add(new Float(1.3));
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ queue = new PriorityQueue<Object>();
+ queue.add(new Integer(10));
+ try {
+ queue.add(new Object());
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PriorityQueue#remove(Object)
+ */
+ public void test_remove_Ljava_lang_Object() {
+ Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+ List<Integer> list = Arrays.asList(array);
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+ assertTrue(integerQueue.remove(16));
+ Integer[] newArray = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 39 };
+ Arrays.sort(newArray);
+ for (int i = 0; i < newArray.length; i++) {
+ assertEquals(newArray[i], integerQueue.poll());
+ }
+ assertEquals(0, integerQueue.size());
+ }
+
+ /**
+ * java.util.PriorityQueue#remove(Object)
+ */
+ public void test_remove_Ljava_lang_Object_using_comparator() {
+ PriorityQueue<String> queue = new PriorityQueue<String>(10,
+ new MockComparatorStringByLength());
+ String[] array = { "AAAAA", "AA", "AAAA", "AAAAAAAA" };
+ for (int i = 0; i < array.length; i++) {
+ queue.offer(array[i]);
+ }
+ assertFalse(queue.contains("BB"));
+ assertTrue(queue.remove("AA"));
+ }
+
+ /**
+ * java.util.PriorityQueue#remove(Object)
+ */
+ public void test_remove_Ljava_lang_Object_not_exists() {
+ Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+ List<Integer> list = Arrays.asList(array);
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+ assertFalse(integerQueue.remove(111));
+ assertFalse(integerQueue.remove(null));
+ assertFalse(integerQueue.remove(""));
+ }
+
+ /**
+ * java.util.PriorityQueue#remove(Object)
+ */
+ public void test_remove_Ljava_lang_Object_null() {
+ Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+ List<Integer> list = Arrays.asList(array);
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+ assertFalse(integerQueue.remove(null));
+ }
+
+ /**
+ * java.util.PriorityQueue#remove(Object)
+ */
+ public void test_remove_Ljava_lang_Object_not_Compatible() {
+ Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+ List<Integer> list = Arrays.asList(array);
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+ assertFalse(integerQueue.remove(new Float(1.3F)));
+
+ // although argument element type is not compatible with those in queue,
+ // but comparator supports it.
+ MockComparator<Object> comparator = new MockComparator<Object>();
+ PriorityQueue<Integer> integerQueue1 = new PriorityQueue<Integer>(100,
+ comparator);
+ integerQueue1.offer(1);
+ assertFalse(integerQueue1.remove(new Float(1.3F)));
+
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ Object o = new Object();
+ queue.offer(o);
+ assertTrue(queue.remove(o));
+ }
+
+ /**
+ * java.util.PriorityQueue#comparator()
+ */
+ public void test_comparator() {
+ PriorityQueue<Object> queue = new PriorityQueue<Object>();
+ assertNull(queue.comparator());
+
+ MockComparator<Object> comparator = new MockComparator<Object>();
+ queue = new PriorityQueue<Object>(100, comparator);
+ assertEquals(comparator, queue.comparator());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void test_Serialization() throws Exception {
+ Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+ List<Integer> list = Arrays.asList(array);
+ PriorityQueue<Integer> srcIntegerQueue = new PriorityQueue<Integer>(
+ list);
+ PriorityQueue<Integer> destIntegerQueue = (PriorityQueue<Integer>) SerializationTester
+ .getDeserilizedObject(srcIntegerQueue);
+ Arrays.sort(array);
+ for (int i = 0; i < array.length; i++) {
+ assertEquals(array[i], destIntegerQueue.poll());
+ }
+ assertEquals(0, destIntegerQueue.size());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ public void test_Serialization_casting() throws Exception {
+ Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+ List<Integer> list = Arrays.asList(array);
+ PriorityQueue<Integer> srcIntegerQueue = new PriorityQueue<Integer>(
+ list);
+ PriorityQueue<String> destStringQueue = (PriorityQueue<String>) SerializationTester
+ .getDeserilizedObject(srcIntegerQueue);
+ // will not incur class cast exception.
+ Object o = destStringQueue.peek();
+ Arrays.sort(array);
+ Integer I = (Integer) o;
+ assertEquals(array[0], I);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void test_SerializationCompatibility_cast() throws Exception {
+ Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+ List<Integer> list = Arrays.asList(array);
+ PriorityQueue<Integer> srcIntegerQueue = new PriorityQueue<Integer>(
+ list);
+ PriorityQueue<String> destStringQueue = (PriorityQueue<String>) SerializationTester
+ .readObject(srcIntegerQueue, SERIALIZATION_FILE_NAME);
+
+ // will not incur class cast exception.
+ Object o = destStringQueue.peek();
+ Arrays.sort(array);
+ Integer I = (Integer) o;
+ assertEquals(array[0], I);
+ }
+
+ /**
+ * {@link PriorityQueue#contains(Object)}
+ */
+ public void test_contains() throws Exception {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.add(array[i]);
+ }
+ for (int i = 0; i < array.length; i++) {
+ assertTrue(integerQueue.contains(array[i]));
+ }
+ assertFalse(integerQueue.contains(null));
+ }
+
+ /**
+ * {@link PriorityQueue#toArray()}
+ */
+ public void test_toArray() throws Exception {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.add(array[i]);
+ }
+ Object[] returnArray = integerQueue.toArray();
+ assertEquals(returnArray.length, integerQueue.size());
+ for (int i = 0; i < returnArray.length; i++) {
+ assertTrue(integerQueue.contains(returnArray[i]));
+ }
+ }
+
+ /**
+ * {@link PriorityQueue#toArray(T[])}
+ */
+ public void test_toArray_$T() throws Exception {
+ PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+ Integer[] array = { 2, 45, 7, -12, 9 };
+ for (int i = 0; i < array.length; i++) {
+ integerQueue.add(array[i]);
+ }
+ Object[] returnArray = integerQueue.toArray(new Integer[0]);
+ assertEquals(returnArray.length, integerQueue.size());
+ for (int i = 0; i < returnArray.length; i++) {
+ assertTrue(integerQueue.contains(returnArray[i]));
+ }
+ returnArray = integerQueue.toArray(new Integer[10]);
+ assertEquals(10, returnArray.length);
+ for (int i = 0; i < array.length; i++) {
+ assertTrue(integerQueue.contains(returnArray[i]));
+ }
+ for (int i = array.length; i < 10; i++) {
+ assertNull(returnArray[i]);
+ }
+ try {
+ integerQueue.toArray(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ integerQueue.toArray(new String[1]);
+ fail("should throw ArrayStoreException");
+ } catch (ArrayStoreException e) {
+ // expected
+ }
+ }
+
+ private static class MockComparator<E> implements Comparator<E> {
+
+ public int compare(E object1, E object2) {
+ int hashcode1 = object1.hashCode();
+ int hashcode2 = object2.hashCode();
+ if (hashcode1 > hashcode2) {
+ return 1;
+ } else if (hashcode1 == hashcode2) {
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ }
+
+ private static class MockComparatorStringByLength implements
+ Comparator<String> {
+
+ public int compare(String object1, String object2) {
+ int length1 = object1.length();
+ int length2 = object2.length();
+ if (length1 > length2) {
+ return 1;
+ } else if (length1 == length2) {
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+
+ }
+
+ private static class MockComparatorCast<E> implements Comparator<E> {
+
+ public int compare(E object1, E object2) {
+ return 0;
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PropertiesTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PropertiesTest.java
new file mode 100644
index 0000000..27cae4e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PropertiesTest.java
@@ -0,0 +1,1157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Scanner;
+import java.util.Set;
+import tests.support.resource.Support_Resources;
+
+public class PropertiesTest extends junit.framework.TestCase {
+
+ Properties tProps;
+
+ byte[] propsFile;
+
+ /**
+ * java.util.Properties#Properties()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.Properties()
+ Properties p = new Properties();
+ // do something to avoid getting a variable unused warning
+ p.clear();
+ assertTrue("Created incorrect Properties", true);
+ }
+
+ public void test_loadLjava_io_InputStream_NPE() throws Exception {
+ Properties p = new Properties();
+ try {
+ p.load((InputStream) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ public void test_loadsave() throws Exception {
+ Properties p = new Properties();
+ try {
+ p.load((InputStream) null);
+ fail("should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Properties#Properties(java.util.Properties)
+ */
+ public void test_ConstructorLjava_util_Properties() {
+ Properties systemProperties = System.getProperties();
+ Properties properties = new Properties(systemProperties);
+ Enumeration<?> propertyNames = systemProperties.propertyNames();
+ String propertyName = null;
+ while (propertyNames.hasMoreElements()) {
+ propertyName = (String) propertyNames.nextElement();
+ assertEquals("failed to construct correct properties",
+ systemProperties.getProperty(propertyName),
+ properties.getProperty(propertyName));
+ }
+ }
+
+ /**
+ * java.util.Properties#getProperty(java.lang.String)
+ */
+ public void test_getPropertyLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.util.Properties.getProperty(java.lang.String)
+ assertEquals("Did not retrieve property", "this is a test property",
+ ((String) tProps.getProperty("test.prop")));
+ }
+
+ /**
+ * java.util.Properties#getProperty(java.lang.String,
+ *java.lang.String)
+ */
+ public void test_getPropertyLjava_lang_StringLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.util.Properties.getProperty(java.lang.String, java.lang.String)
+ assertEquals("Did not retrieve property", "this is a test property",
+ ((String) tProps.getProperty("test.prop", "Blarg")));
+ assertEquals("Did not return default value", "Gabba", ((String) tProps
+ .getProperty("notInThere.prop", "Gabba")));
+ }
+
+ /**
+ * java.util.Properties#getProperty(java.lang.String)
+ */
+ public void test_getPropertyLjava_lang_String2() {
+ // regression test for HARMONY-3518
+ MyProperties props = new MyProperties();
+ assertNull(props.getProperty("key"));
+ }
+
+ /**
+ * java.util.Properties#getProperty(java.lang.String,
+ *java.lang.String)
+ */
+ public void test_getPropertyLjava_lang_StringLjava_lang_String2() {
+ // regression test for HARMONY-3518
+ MyProperties props = new MyProperties();
+ assertEquals("defaultValue", props.getProperty("key", "defaultValue"));
+ }
+
+ // regression testing for HARMONY-3518
+ static class MyProperties extends Properties {
+ public synchronized Object get(Object key) {
+ return getProperty((String) key); // assume String
+ }
+ }
+
+ /**
+ * java.util.Properties#list(java.io.PrintStream)
+ */
+ public void test_listLjava_io_PrintStream() {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ Properties myProps = new Properties();
+ myProps.setProperty("Abba", "Cadabra");
+ myProps.setProperty("Open", "Sesame");
+ myProps.setProperty("LongProperty",
+ "a long long long long long long long property");
+ myProps.list(ps);
+ ps.flush();
+ String propList = baos.toString();
+ assertTrue("Property list innacurate",
+ propList.indexOf("Abba=Cadabra") >= 0);
+ assertTrue("Property list innacurate",
+ propList.indexOf("Open=Sesame") >= 0);
+ assertTrue("property list do not conatins \"...\"", propList
+ .indexOf("...") != -1);
+
+ ps = null;
+ try {
+ myProps.list(ps);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Properties#list(java.io.PrintWriter)
+ */
+ public void test_listLjava_io_PrintWriter() {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(baos);
+ Properties myProps = new Properties();
+ myProps.setProperty("Abba", "Cadabra");
+ myProps.setProperty("Open", "Sesame");
+ myProps.setProperty("LongProperty",
+ "a long long long long long long long property");
+ myProps.list(pw);
+ pw.flush();
+ String propList = baos.toString();
+ assertTrue("Property list innacurate",
+ propList.indexOf("Abba=Cadabra") >= 0);
+ assertTrue("Property list innacurate",
+ propList.indexOf("Open=Sesame") >= 0);
+ pw = null;
+ try {
+ myProps.list(pw);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Properties#load(java.io.InputStream)
+ */
+ public void test_loadLjava_io_InputStream() {
+ // Test for method void java.util.Properties.load(java.io.InputStream)
+ Properties prop = null;
+ try {
+ InputStream is;
+ prop = new Properties();
+ prop.load(is = new ByteArrayInputStream(writeProperties()));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
+ assertEquals("Failed to load correct properties", "harmony.tests", prop
+ .getProperty("test.pkg"));
+ assertNull("Load failed to parse incorrectly", prop
+ .getProperty("commented.entry"));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream("=".getBytes()));
+ } catch (IOException e) {
+ // expected
+ }
+ assertTrue("Failed to add empty key", prop.get("").equals(""));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream(" = ".getBytes()));
+ } catch (IOException e) {
+ // expected
+ }
+ assertTrue("Failed to add empty key2", prop.get("").equals(""));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream(" a= b".getBytes()));
+ } catch (IOException e) {
+ // expected
+ }
+ assertEquals("Failed to ignore whitespace", "b", prop.get("a"));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream(" a b".getBytes()));
+ } catch (IOException e) {
+ // expected
+ }
+ assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream("#\u008d\u00d2\na=\u008d\u00d3"
+ .getBytes("ISO8859_1")));
+ } catch (IOException e) {
+ // expected
+ }
+ assertEquals("Failed to parse chars >= 0x80", "\u008d\u00d3", prop
+ .get("a"));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream(
+ "#properties file\r\nfred=1\r\n#last comment"
+ .getBytes("ISO8859_1")));
+ } catch (IOException e) {
+ // expected
+ } catch (IndexOutOfBoundsException e) {
+ fail("IndexOutOfBoundsException when last line is a comment with no line terminator");
+ }
+ assertEquals("Failed to load when last line contains a comment", "1",
+ prop.get("fred"));
+ }
+
+ /**
+ * java.util.Properties#load(java.io.InputStream)
+ */
+ public void test_loadLjava_io_InputStream_subtest0() {
+ try {
+ InputStream is = Support_Resources
+ .getStream("hyts_PropertiesTest.properties");
+ Properties props = new Properties();
+ props.load(is);
+ is.close();
+ assertEquals("1", "\n \t \f", props.getProperty(" \r"));
+ assertEquals("2", "a", props.getProperty("a"));
+ assertEquals("3", "bb as,dn ", props.getProperty("b"));
+ assertEquals("4", ":: cu", props.getProperty("c\r \t\nu"));
+ assertEquals("5", "bu", props.getProperty("bu"));
+ assertEquals("6", "d\r\ne=e", props.getProperty("d"));
+ assertEquals("7", "fff", props.getProperty("f"));
+ assertEquals("8", "g", props.getProperty("g"));
+ assertEquals("9", "", props.getProperty("h h"));
+ assertEquals("10", "i=i", props.getProperty(" "));
+ assertEquals("11", " j", props.getProperty("j"));
+ assertEquals("12", " c", props.getProperty("space"));
+ assertEquals("13", "\\", props.getProperty("dblbackslash"));
+ } catch (IOException e) {
+ fail("Unexpected: " + e);
+ }
+ }
+
+ /**
+ * @throws IOException
+ * java.util.Properties#load(java.io.Reader)
+ * @since 1.6
+ */
+ public void test_loadLjava_io_Reader() throws IOException {
+ Properties prop = null;
+ try {
+ InputStream is;
+ prop = new Properties();
+ is = new ByteArrayInputStream(writeProperties());
+ prop.load(new InputStreamReader(is));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
+ assertEquals("Failed to load correct properties", "harmony.tests", prop
+ .getProperty("test.pkg"));
+ assertNull("Load failed to parse incorrectly", prop
+ .getProperty("commented.entry"));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("=".getBytes()));
+ assertEquals("Failed to add empty key", "", prop.get(""));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream(" = ".getBytes()));
+ assertEquals("Failed to add empty key2", "", prop.get(""));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream(" a= b".getBytes()));
+ assertEquals("Failed to ignore whitespace", "b", prop.get("a"));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream(" a b".getBytes()));
+ assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("#comment\na=value"
+ .getBytes("UTF-8")));
+ assertEquals("value", prop.getProperty("a"));
+
+ prop = new Properties();
+ prop.load(new InputStreamReader(new ByteArrayInputStream(
+ "#\u008d\u00d2\na=\u008d\u00d3".getBytes("UTF-8"))));
+ try {
+ prop
+ .load(new InputStreamReader(new ByteArrayInputStream(
+ "#\u008d\u00d2\na=\\\\u008d\\\\\\uu00d3"
+ .getBytes("UTF-8"))));
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ prop = new Properties();
+ try {
+ prop.load(new InputStreamReader(new ByteArrayInputStream(
+ "#properties file\r\nfred=1\r\n#last comment"
+ .getBytes("ISO8859_1"))));
+ } catch (IndexOutOfBoundsException e) {
+ fail("IndexOutOfBoundsException when last line is a comment with no line terminator");
+ }
+ assertEquals("Failed to load when last line contains a comment", "1",
+ prop.get("fred"));
+
+ // Regression tests for HARMONY-5414
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("a=\\u1234z".getBytes()));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream("a=\\u123".getBytes()));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream("a=\\u123z".getBytes()));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // Expected
+ }
+
+ prop = new Properties();
+ Properties expected = new Properties();
+ expected.put("a", "\u0000");
+ prop.load(new ByteArrayInputStream("a=\\".getBytes()));
+ assertEquals("Failed to read trailing slash value", expected, prop);
+
+ prop = new Properties();
+ expected = new Properties();
+ expected.put("a", "\u1234\u0000");
+ prop.load(new ByteArrayInputStream("a=\\u1234\\".getBytes()));
+ assertEquals("Failed to read trailing slash value #2", expected, prop);
+
+ prop = new Properties();
+ expected = new Properties();
+ expected.put("a", "q");
+ prop.load(new ByteArrayInputStream("a=\\q".getBytes()));
+ assertEquals("Failed to read slash value #3", expected, prop);
+ }
+
+ /**
+ * java.util.Properties#load(java.io.InputStream)
+ */
+ public void test_loadLjava_io_InputStream_Special() throws IOException {
+ // Test for method void java.util.Properties.load(java.io.InputStream)
+ Properties prop = null;
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("=".getBytes()));
+ assertTrue("Failed to add empty key", prop.get("").equals(""));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("=\r\n".getBytes()));
+ assertTrue("Failed to add empty key", prop.get("").equals(""));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("=\n\r".getBytes()));
+ assertTrue("Failed to add empty key", prop.get("").equals(""));
+ }
+
+ /**
+ * @throws IOException
+ * java.util.Properties#load(java.io.Reader)
+ * @since 1.6
+ */
+ public void test_loadLjava_io_Reader_subtest0() throws IOException {
+ InputStream is = Support_Resources
+ .getStream("hyts_PropertiesTest.properties");
+ Properties props = new Properties();
+ props.load(new InputStreamReader(is));
+ is.close();
+ assertEquals("1", "\n \t \f", props.getProperty(" \r"));
+ assertEquals("2", "a", props.getProperty("a"));
+ assertEquals("3", "bb as,dn ", props.getProperty("b"));
+ assertEquals("4", ":: cu", props.getProperty("c\r \t\nu"));
+ assertEquals("5", "bu", props.getProperty("bu"));
+ assertEquals("6", "d\r\ne=e", props.getProperty("d"));
+ assertEquals("7", "fff", props.getProperty("f"));
+ assertEquals("8", "g", props.getProperty("g"));
+ assertEquals("9", "", props.getProperty("h h"));
+ assertEquals("10", "i=i", props.getProperty(" "));
+ assertEquals("11", " j", props.getProperty("j"));
+ assertEquals("12", " c", props.getProperty("space"));
+ assertEquals("13", "\\", props.getProperty("dblbackslash"));
+ }
+
+ /**
+ * {@link java.util.Properties#stringPropertyNames()}
+ * @since 1.6
+ */
+ public void test_stringPropertyNames() {
+ Set<String> set = tProps.stringPropertyNames();
+ assertEquals(2, set.size());
+ assertTrue(set.contains("test.prop"));
+ assertTrue(set.contains("bogus.prop"));
+ assertNotSame(set, tProps.stringPropertyNames());
+
+ set = new Properties().stringPropertyNames();
+ assertEquals(0, set.size());
+
+ set = new Properties(System.getProperties()).stringPropertyNames();
+ assertTrue(set.size() > 0);
+
+ tProps = new Properties(tProps);
+ tProps.put("test.prop", "anotherValue");
+ tProps.put("3rdKey", "3rdValue");
+ set = tProps.stringPropertyNames();
+ assertEquals(3, set.size());
+ assertTrue(set.contains("test.prop"));
+ assertTrue(set.contains("bogus.prop"));
+ assertTrue(set.contains("3rdKey"));
+
+ tProps.put(String.class, "valueOfNonStringKey");
+ set = tProps.stringPropertyNames();
+ assertEquals(3, set.size());
+ assertTrue(set.contains("test.prop"));
+ assertTrue(set.contains("bogus.prop"));
+ assertTrue(set.contains("3rdKey"));
+
+ tProps.put("4thKey", "4thValue");
+ assertEquals(4, tProps.size());
+ assertEquals(3, set.size());
+
+ try {
+ set.add("another");
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ /**
+ * {@link java.util.Properties#stringPropertyNames()}
+ * @since 1.6
+ */
+ public void test_stringPropertyNames_scenario1() {
+ String[] keys = new String[] { "key1", "key2", "key3" };
+ String[] values = new String[] { "value1", "value2", "value3" };
+ List<String> keyList = Arrays.asList(keys);
+
+ Properties properties = new Properties();
+ for (int index = 0; index < keys.length; index++) {
+ properties.setProperty(keys[index], values[index]);
+ }
+
+ properties = new Properties(properties);
+ Set<String> nameSet = properties.stringPropertyNames();
+ assertEquals(keys.length, nameSet.size());
+ Iterator<String> iterator = nameSet.iterator();
+ while (iterator.hasNext()) {
+ assertTrue(keyList.contains(iterator.next()));
+ }
+
+ Enumeration<?> nameEnum = properties.propertyNames();
+ int count = 0;
+ while (nameEnum.hasMoreElements()) {
+ count++;
+ assertTrue(keyList.contains(nameEnum.nextElement()));
+ }
+ assertEquals(keys.length, count);
+
+ properties = new Properties(properties);
+ nameSet = properties.stringPropertyNames();
+ assertEquals(keys.length, nameSet.size());
+ iterator = nameSet.iterator();
+ while (iterator.hasNext()) {
+ assertTrue(keyList.contains(iterator.next()));
+ }
+
+ nameEnum = properties.propertyNames();
+ count = 0;
+ while (nameEnum.hasMoreElements()) {
+ count++;
+ assertTrue(keyList.contains(nameEnum.nextElement()));
+ }
+ assertEquals(keys.length, count);
+ }
+
+ /**
+ * {@link java.util.Properties#stringPropertyNames()}
+ * @since 1.6
+ */
+ public void test_stringPropertyNames_scenario2() {
+ String[] defaultKeys = new String[] { "defaultKey1", "defaultKey2",
+ "defaultKey3", "defaultKey4", "defaultKey5", "defaultKey6" };
+ String[] defaultValues = new String[] { "defaultValue1",
+ "defaultValue2", "defaultValue3", "defaultValue4",
+ "defaultValue5", "defaultValue6" };
+ List<String> keyList = new ArrayList<String>();
+ Properties defaults = new Properties();
+ for (int index = 0; index < 3; index++) {
+ defaults.setProperty(defaultKeys[index], defaultValues[index]);
+ keyList.add(defaultKeys[index]);
+ }
+
+ String[] keys = new String[] { "key1", "key2", "key3" };
+ String[] values = new String[] { "value1", "value2", "value3" };
+ Properties properties = new Properties(defaults);
+ for (int index = 0; index < keys.length; index++) {
+ properties.setProperty(keys[index], values[index]);
+ keyList.add(keys[index]);
+ }
+
+ Set<String> nameSet = properties.stringPropertyNames();
+ assertEquals(keyList.size(), nameSet.size());
+ Iterator<String> iterator = nameSet.iterator();
+ while (iterator.hasNext()) {
+ assertTrue(keyList.contains(iterator.next()));
+ }
+
+ Enumeration<?> nameEnum = properties.propertyNames();
+ int count = 0;
+ while (nameEnum.hasMoreElements()) {
+ count++;
+ assertTrue(keyList.contains(nameEnum.nextElement()));
+ }
+ assertEquals(keyList.size(), count);
+
+ for (int index = 3; index < defaultKeys.length; index++) {
+ defaults.setProperty(defaultKeys[index], defaultValues[index]);
+ keyList.add(defaultKeys[index]);
+ }
+
+ nameSet = properties.stringPropertyNames();
+ assertEquals(keyList.size(), nameSet.size());
+ iterator = nameSet.iterator();
+ while (iterator.hasNext()) {
+ assertTrue(keyList.contains(iterator.next()));
+ }
+
+ nameEnum = properties.propertyNames();
+ count = 0;
+ while (nameEnum.hasMoreElements()) {
+ count++;
+ assertTrue(keyList.contains(nameEnum.nextElement()));
+ }
+ assertEquals(keyList.size(), count);
+ }
+
+ /**
+ * java.util.Properties#save(java.io.OutputStream, java.lang.String)
+ */
+ public void test_saveLjava_io_OutputStreamLjava_lang_String() {
+ // Test for method void java.util.Properties.save(java.io.OutputStream,
+ // java.lang.String)
+ Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+
+ myProps.setProperty("Property A", "aye");
+ myProps.setProperty("Property B", "bee");
+ myProps.setProperty("Property C", "see");
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ myProps.save(out, "A Header");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2.load(in);
+ in.close();
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
+ }
+
+ Enumeration e = myProps.propertyNames();
+ String nextKey;
+ while (e.hasMoreElements()) {
+ nextKey = (String) e.nextElement();
+ assertEquals("Stored property list not equal to original", myProps
+ .getProperty(nextKey), myProps2.getProperty(nextKey));
+ }
+ }
+
+ /**
+ * java.util.Properties#setProperty(java.lang.String,
+ *java.lang.String)
+ */
+ public void test_setPropertyLjava_lang_StringLjava_lang_String() {
+ // Test for method java.lang.Object
+ // java.util.Properties.setProperty(java.lang.String, java.lang.String)
+ Properties myProps = new Properties();
+ myProps.setProperty("Yoink", "Yabba");
+ assertEquals("Failed to set property", "Yabba", myProps
+ .getProperty("Yoink"));
+ myProps.setProperty("Yoink", "Gab");
+ assertEquals("Failed to reset property", "Gab", myProps
+ .getProperty("Yoink"));
+ }
+
+ /**
+ * java.util.Properties#store(java.io.OutputStream, java.lang.String)
+ */
+ public void test_storeLjava_io_OutputStreamLjava_lang_String() {
+ // Test for method void java.util.Properties.store(java.io.OutputStream,
+ // java.lang.String)
+ Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+ Enumeration e;
+ String nextKey;
+
+ myProps.put("Property A", " aye\\\f\t\n\r\b");
+ myProps.put("Property B", "b ee#!=:");
+ myProps.put("Property C", "see");
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ myProps.store(out, "A Header");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2.load(in);
+ in.close();
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
+ }
+
+ e = myProps.propertyNames();
+ while (e.hasMoreElements()) {
+ nextKey = (String) e.nextElement();
+ assertTrue("Stored property list not equal to original", myProps2
+ .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ }
+
+ }
+
+ /**
+ * @throws IOException
+ * java.util.Properties#store(java.io.Writer, java.lang.String)
+ * @since 1.6
+ */
+ public void test_storeLjava_io_WriterLjava_lang_String() throws IOException {
+ Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+
+ myProps.put("Property A", " aye\\\f\t\n\r\b");
+ myProps.put("Property B", "b ee#!=:");
+ myProps.put("Property C", "see");
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ myProps.store(new OutputStreamWriter(out), "A Header");
+ Scanner scanner = new Scanner(out.toString());
+ assertTrue(scanner.nextLine().startsWith("#A Header"));
+ assertTrue(scanner.nextLine().startsWith("#"));
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ myProps2.load(in);
+ in.close();
+
+ Enumeration e = myProps.propertyNames();
+ String nextKey;
+ while (e.hasMoreElements()) {
+ nextKey = (String) e.nextElement();
+ assertTrue("Stored property list not equal to original", myProps2
+ .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ }
+
+ try {
+ myProps.store((Writer) null, "some comments");
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
+ }
+
+ myProps.put(String.class, "wrong type");
+ try {
+ myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+ "some comments");
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e1) {
+ // expected
+ }
+ myProps.remove(String.class);
+ myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+ "some comments");
+ // it is OK
+ myProps.put("wrong type", String.class);
+ try {
+ myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+ "some comments");
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e1) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Properties#loadFromXML(java.io.InputStream)
+ */
+ public void test_loadFromXMLLjava_io_InputStream() throws Exception {
+ // Test for method void
+ // java.util.Properties.loadFromXML(java.io.InputStream)
+ Properties prop = null;
+ try {
+ InputStream is;
+ prop = new Properties();
+ prop.loadFromXML(is = new ByteArrayInputStream(
+ writePropertiesXMLUTF_8()));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
+ assertEquals("Failed to load correct properties", "value3", prop
+ .getProperty("key3"));
+ assertEquals("Failed to load correct properties", "value1", prop
+ .getProperty("key1"));
+
+ try {
+ InputStream is;
+ prop = new Properties();
+ prop.loadFromXML(is = new ByteArrayInputStream(
+ writePropertiesXMLISO_8859_1()));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
+ assertEquals("Failed to load correct properties", "value2", prop
+ .getProperty("key2"));
+ assertEquals("Failed to load correct properties", "value1", prop
+ .getProperty("key1"));
+
+ try {
+ prop.loadFromXML(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.Properties#storeToXML(java.io.OutputStream,
+ *java.lang.String, java.lang.String)
+ */
+ public void test_storeToXMLLjava_io_OutputStreamLjava_lang_StringLjava_lang_String()
+ throws Exception {
+ // Test for method void
+ // java.util.Properties.storeToXML(java.io.OutputStream,
+ // java.lang.String, java.lang.String)
+ Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+ Enumeration e;
+ String nextKey;
+
+ myProps.setProperty("key1", "value1");
+ myProps.setProperty("key2", "value2");
+ myProps.setProperty("key3", "value3");
+ myProps.setProperty("<a>key4</a>", "\"value4");
+ myProps.setProperty("key5 ", "<h>value5</h>");
+ myProps.setProperty("<a>key6</a>", " <h>value6</h> ");
+ myProps.setProperty("<comment>key7</comment>", "value7");
+ myProps.setProperty(" key8 ", "<comment>value8</comment>");
+ myProps.setProperty("&lt;key9&gt;", "\u0027value9");
+ myProps.setProperty("key10\"", "&lt;value10&gt;");
+ myProps.setProperty("&amp;key11&amp;", "value11");
+ myProps.setProperty("key12", "&amp;value12&amp;");
+ myProps.setProperty("<a>&amp;key13&lt;</a>",
+ "&amp;&value13<b>&amp;</b>");
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ // store in UTF-8 encoding
+ myProps.storeToXML(out, "comment");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2.loadFromXML(in);
+ in.close();
+ } catch (InvalidPropertiesFormatException ipfe) {
+ fail("InvalidPropertiesFormatException occurred reading file: "
+ + ipfe.getMessage());
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
+ }
+
+ e = myProps.propertyNames();
+ while (e.hasMoreElements()) {
+ nextKey = (String) e.nextElement();
+ assertTrue("Stored property list not equal to original", myProps2
+ .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ }
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ // store in ISO-8859-1 encoding
+ myProps.storeToXML(out, "comment", "ISO-8859-1");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2 = new Properties();
+ myProps2.loadFromXML(in);
+ in.close();
+ } catch (InvalidPropertiesFormatException ipfe) {
+ fail("InvalidPropertiesFormatException occurred reading file: "
+ + ipfe.getMessage());
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
+ }
+
+ e = myProps.propertyNames();
+ while (e.hasMoreElements()) {
+ nextKey = (String) e.nextElement();
+ assertTrue("Stored property list not equal to original", myProps2
+ .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ }
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ myProps.storeToXML(out, null, null);
+ fail("should throw nullPointerException");
+ } catch (NullPointerException ne) {
+ // expected
+ }
+ }
+
+ /**
+ * if loading from single line like "hello" without "\n\r" neither "=", it
+ * should be same as loading from "hello="
+ */
+ public void testLoadSingleLine() throws Exception {
+ Properties props = new Properties();
+ InputStream sr = new ByteArrayInputStream("hello".getBytes());
+ props.load(sr);
+ assertEquals(1, props.size());
+ }
+
+ public void test_propertyNames() {
+ Properties parent = new Properties();
+ parent.setProperty("parent.a.key", "parent.a.value");
+ parent.setProperty("parent.b.key", "parent.b.value");
+
+ Enumeration<?> names = parent.propertyNames();
+ assertPropertyEnumeration(names, "parent.a.key", "parent.b.key");
+
+ Properties current = new Properties(parent);
+ current.setProperty("current.a.key", "current.a.value");
+ current.setProperty("current.b.key", "current.b.value");
+
+ names = current.propertyNames();
+ assertPropertyEnumeration(names,
+ "parent.a.key",
+ "parent.b.key",
+ "current.a.key",
+ "current.b.key");
+
+ Properties child = new Properties(current);
+ child.setProperty("child.a.key", "child.a.value");
+ child.setProperty("child.b.key", "child.b.value");
+
+ names = child.propertyNames();
+ assertPropertyEnumeration(names,
+ "parent.a.key",
+ "parent.b.key",
+ "current.a.key",
+ "current.b.key",
+ "child.a.key",
+ "child.b.key");
+ }
+
+ public void assertPropertyEnumeration(Enumeration<?> propNames,
+ String... expected) {
+ Set<String> propsSet = new HashSet<String>();
+ while (propNames.hasMoreElements()) {
+ String next = (String) propNames.nextElement();
+ assertFalse(propsSet.contains(next));
+ propsSet.add(next);
+ }
+
+ assertEquals(expected.length, propsSet.size());
+ assertTrue(propsSet.containsAll(Arrays.asList(expected)));
+ }
+
+ private String comment1 = "comment1";
+
+ private String comment2 = "comment2";
+
+ private void validateOutput(String[] expectStrings, byte[] output)
+ throws IOException {
+ ByteArrayInputStream bais = new ByteArrayInputStream(output);
+ BufferedReader br = new BufferedReader(new InputStreamReader(bais,
+ "ISO8859_1"));
+ for (String expectString : expectStrings) {
+ assertEquals(expectString, br.readLine());
+ }
+ br.readLine();
+ assertNull(br.readLine());
+ br.close();
+ }
+
+ public void testStore_scenario0() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\r' + comment2);
+ validateOutput(new String[] { "#comment1", "#comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario1() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\n' + comment2);
+ validateOutput(new String[] { "#comment1", "#comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario2() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\r' + '\n' + comment2);
+ validateOutput(new String[] { "#comment1", "#comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario3() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\n' + '\r' + comment2);
+ validateOutput(new String[] { "#comment1", "#", "#comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario4() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\r' + '#' + comment2);
+ validateOutput(new String[] { "#comment1", "#comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario5() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\r' + '!' + comment2);
+ validateOutput(new String[] { "#comment1", "!comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario6() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\n' + '#' + comment2);
+ validateOutput(new String[] { "#comment1", "#comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario7() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\n' + '!' + comment2);
+ validateOutput(new String[] { "#comment1", "!comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario8() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\r' + '\n' + '#' + comment2);
+ validateOutput(new String[] { "#comment1", "#comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario9() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\n' + '\r' + '#' + comment2);
+ validateOutput(new String[] { "#comment1", "#", "#comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario10() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\r' + '\n' + '!' + comment2);
+ validateOutput(new String[] { "#comment1", "!comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testStore_scenario11() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Properties props = new Properties();
+ props.store(baos, comment1 + '\n' + '\r' + '!' + comment2);
+ validateOutput(new String[] { "#comment1", "#", "!comment2" },
+ baos.toByteArray());
+ baos.close();
+ }
+
+ public void testLoadReader() throws IOException {
+ InputStream inputStream = new ByteArrayInputStream(
+ "\u3000key=value".getBytes("UTF-8"));
+ Properties props = new Properties();
+ props.load(inputStream);
+ Enumeration<Object> keyEnum = props.keys();
+ assertFalse("\u3000key".equals(keyEnum.nextElement()));
+ assertFalse(keyEnum.hasMoreElements());
+ inputStream.close();
+
+ inputStream = new ByteArrayInputStream(
+ "\u3000key=value".getBytes("UTF-8"));
+ props = new Properties();
+ props.load(new InputStreamReader(inputStream, "UTF-8"));
+ keyEnum = props.keys();
+ assertEquals("key", keyEnum.nextElement());
+ assertFalse(keyEnum.hasMoreElements());
+ inputStream.close();
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+
+ tProps = new Properties();
+ tProps.put("test.prop", "this is a test property");
+ tProps.put("bogus.prop", "bogus");
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected byte[] writeProperties() throws IOException {
+ PrintStream ps = null;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ps = new PrintStream(bout);
+ ps.println("#commented.entry=Bogus");
+ ps.println("test.pkg=harmony.tests");
+ ps.println("test.proj=Automated Tests");
+ ps.close();
+ return bout.toByteArray();
+ }
+
+ protected byte[] writePropertiesXMLUTF_8() throws IOException {
+ PrintStream ps = null;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ps = new PrintStream(bout, true, "UTF-8");
+ ps.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ ps
+ .println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
+ ps.println("<properties>");
+ ps.println("<comment>comment</comment>");
+ ps.println("<entry key=\"key4\">value4</entry>");
+ ps.println("<entry key=\"key3\">value3</entry>");
+ ps.println("<entry key=\"key2\">value2</entry>");
+ ps.println("<entry key=\"key1\"><!-- xml comment -->value1</entry>");
+ ps.println("</properties>");
+ ps.close();
+ return bout.toByteArray();
+ }
+
+ protected byte[] writePropertiesXMLISO_8859_1() throws IOException {
+ PrintStream ps = null;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ps = new PrintStream(bout, true, "ISO-8859-1");
+ ps.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
+ ps
+ .println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
+ ps.println("<properties>");
+ ps.println("<comment>comment</comment>");
+ ps.println("<entry key=\"key4\">value4</entry>");
+ ps.println("<entry key=\"key3\">value3</entry>");
+ ps.println("<entry key=\"key2\">value2</entry>");
+ ps.println("<entry key=\"key1\"><!-- xml comment -->value1</entry>");
+ ps.println("</properties>");
+ ps.close();
+ return bout.toByteArray();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PropertyResourceBundleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PropertyResourceBundleTest.java
new file mode 100644
index 0000000..2306ec1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/PropertyResourceBundleTest.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.Enumeration;
+import java.util.MissingResourceException;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+public class PropertyResourceBundleTest extends junit.framework.TestCase {
+
+ static PropertyResourceBundle prb;
+
+ /**
+ * @throws IOException
+ * java.util.PropertyResourceBundle#PropertyResourceBundle(java.io.InputStream)
+ */
+ @SuppressWarnings("nls")
+ public void test_ConstructorLjava_io_InputStream() throws IOException {
+ InputStream propertiesStream = new ByteArrayInputStream(
+ "p1=one\ncharset=iso-8859-1".getBytes("ISO-8859-1"));
+ prb = new PropertyResourceBundle(propertiesStream);
+ assertEquals(2, prb.keySet().size());
+ assertEquals("one", prb.getString("p1"));
+ assertEquals("iso-8859-1", prb.getString("charset"));
+
+ propertiesStream = new ByteArrayInputStream("p1=one\ncharset=UTF-8"
+ .getBytes("UTF-8"));
+ prb = new PropertyResourceBundle(propertiesStream);
+ assertEquals(2, prb.keySet().size());
+ assertEquals("UTF-8", prb.getString("charset"));
+
+ try {
+ new PropertyResourceBundle((InputStream) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @throws IOException
+ * {@link java.util.PropertyResourceBundle#PropertyResourceBundle(java.io.Reader)}
+ * @since 1.6
+ */
+ @SuppressWarnings("nls")
+ public void test_ConstructorLjava_io_Reader() throws IOException {
+ Charset charset = Charset.forName("ISO-8859-1");
+ String content = "p1=one\nfeature=good_feature";
+ CharBuffer cbuffer = charset.decode(ByteBuffer.wrap(content
+ .getBytes("ISO-8859-1")));
+ char[] chars = new char[cbuffer.limit()];
+ cbuffer.get(chars);
+
+ prb = new PropertyResourceBundle(new CharArrayReader(chars));
+ assertEquals(2, prb.keySet().size());
+ assertEquals("one", prb.getString("p1"));
+ assertEquals("good_feature", prb.getString("feature"));
+
+ charset = Charset.forName("UTF-8");
+ cbuffer = charset.decode(ByteBuffer.wrap(content.getBytes("UTF-8")));
+ chars = new char[cbuffer.limit()];
+ cbuffer.get(chars);
+
+ prb = new PropertyResourceBundle(new CharArrayReader(chars));
+ assertEquals(2, prb.keySet().size());
+ assertEquals("one", prb.getString("p1"));
+ assertEquals("good_feature", prb.getString("feature"));
+
+ try {
+ new PropertyResourceBundle((Reader) null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.PropertyResourceBundle#getKeys()
+ */
+ public void test_getKeys() {
+ Enumeration keyEnum = prb.getKeys();
+ Vector<Object> test = new Vector<Object>();
+ int keyCount = 0;
+ while (keyEnum.hasMoreElements()) {
+ test.addElement(keyEnum.nextElement());
+ keyCount++;
+ }
+
+ assertEquals("Returned the wrong number of keys", 2, keyCount);
+ assertTrue("Returned the wrong keys", test.contains("p1")
+ && test.contains("p2"));
+ }
+
+ /**
+ * java.util.PropertyResourceBundle#handleGetObject(java.lang.String)
+ */
+ public void test_handleGetObjectLjava_lang_String() {
+ // Test for method java.lang.Object
+ // java.util.PropertyResourceBundle.handleGetObject(java.lang.String)
+ try {
+ assertTrue("Returned incorrect objects", prb.getObject("p1")
+ .equals("one")
+ && prb.getObject("p2").equals("two"));
+ } catch (MissingResourceException e) {
+ fail(
+ "Threw MisingResourceException for a key contained in the bundle");
+ }
+ try {
+ prb.getObject("Not in the bundle");
+ } catch (MissingResourceException e) {
+ return;
+ }
+ fail(
+ "Failed to throw MissingResourceException for object not in the bundle");
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ *
+ * @throws UnsupportedEncodingException
+ */
+ protected void setUp() throws UnsupportedEncodingException {
+ InputStream propertiesStream = new ByteArrayInputStream(
+ "p1=one\np2=two".getBytes("ISO-8859-1"));
+ try {
+ prb = new PropertyResourceBundle(propertiesStream);
+ } catch (java.io.IOException e) {
+ fail(
+ "Construction of PropertyResourceBundle threw IOException");
+ }
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+
+ /**
+ * {@link java.util.PropertyResourceBundle#Enumeration}
+ */
+ public void test_access$0_Enumeration() throws IOException {
+ class MockResourceBundle extends PropertyResourceBundle {
+ MockResourceBundle(java.io.InputStream stream) throws IOException {
+ super(stream);
+ }
+
+ @Override
+ protected void setParent(ResourceBundle bundle) {
+ super.setParent(bundle);
+ }
+ }
+
+ java.io.InputStream localStream = new java.io.ByteArrayInputStream(
+ "p3=three\np4=four".getBytes());
+ MockResourceBundle localPrb = new MockResourceBundle(localStream);
+ localPrb.setParent(prb);
+ Enumeration<String> keys = localPrb.getKeys();
+ Vector<String> contents = new Vector<String>();
+ while (keys.hasMoreElements()) {
+ contents.add(keys.nextElement());
+ }
+
+ assertEquals("did not get the right number of properties", 4, contents
+ .size());
+ assertTrue("did not get the parent property p1", contents
+ .contains("p1"));
+ assertTrue("did not get the parent property p2", contents
+ .contains("p2"));
+ assertTrue("did not get the local property p3", contents.contains("p3"));
+ assertTrue("did not get the local property p4", contents.contains("p4"));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RandomTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RandomTest.java
new file mode 100644
index 0000000..d51d8ab
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RandomTest.java
@@ -0,0 +1,320 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.Random;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class RandomTest extends junit.framework.TestCase {
+
+ Random r;
+
+ /**
+ * java.util.Random#Random()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.Random()
+ assertTrue("Used to test", true);
+ }
+
+ /**
+ * java.util.Random#Random(long)
+ */
+ public void test_ConstructorJ() {
+ Random r = new Random(8409238L);
+ Random r2 = new Random(8409238L);
+ for (int i = 0; i < 100; i++)
+ assertTrue("Values from randoms with same seed don't match", r
+ .nextInt() == r2.nextInt());
+ }
+
+ /**
+ * java.util.Random#nextBoolean()
+ */
+ public void test_nextBoolean() {
+ // Test for method boolean java.util.Random.nextBoolean()
+ boolean falseAppeared = false, trueAppeared = false;
+ for (int counter = 0; counter < 100; counter++)
+ if (r.nextBoolean())
+ trueAppeared = true;
+ else
+ falseAppeared = true;
+ assertTrue("Calling nextBoolean() 100 times resulted in all trues",
+ falseAppeared);
+ assertTrue("Calling nextBoolean() 100 times resulted in all falses",
+ trueAppeared);
+ }
+
+ /**
+ * java.util.Random#nextBytes(byte[])
+ */
+ public void test_nextBytes$B() {
+ // Test for method void java.util.Random.nextBytes(byte [])
+ boolean someDifferent = false;
+ byte[] randomBytes = new byte[100];
+ r.nextBytes(randomBytes);
+ byte firstByte = randomBytes[0];
+ for (int counter = 1; counter < randomBytes.length; counter++)
+ if (randomBytes[counter] != firstByte)
+ someDifferent = true;
+ assertTrue(
+ "nextBytes() returned an array of length 100 of the same byte",
+ someDifferent);
+ }
+
+ /**
+ * java.util.Random#nextDouble()
+ */
+ public void test_nextDouble() {
+ // Test for method double java.util.Random.nextDouble()
+ double lastNum = r.nextDouble();
+ double nextNum;
+ boolean someDifferent = false;
+ boolean inRange = true;
+ for (int counter = 0; counter < 100; counter++) {
+ nextNum = r.nextDouble();
+ if (nextNum != lastNum)
+ someDifferent = true;
+ if (!(0 <= nextNum && nextNum < 1.0))
+ inRange = false;
+ lastNum = nextNum;
+ }
+ assertTrue("Calling nextDouble 100 times resulted in same number",
+ someDifferent);
+ assertTrue(
+ "Calling nextDouble resulted in a number out of range [0,1)",
+ inRange);
+ }
+
+ /**
+ * java.util.Random#nextFloat()
+ */
+ public void test_nextFloat() {
+ // Test for method float java.util.Random.nextFloat()
+ float lastNum = r.nextFloat();
+ float nextNum;
+ boolean someDifferent = false;
+ boolean inRange = true;
+ for (int counter = 0; counter < 100; counter++) {
+ nextNum = r.nextFloat();
+ if (nextNum != lastNum)
+ someDifferent = true;
+ if (!(0 <= nextNum && nextNum < 1.0))
+ inRange = false;
+ lastNum = nextNum;
+ }
+ assertTrue("Calling nextFloat 100 times resulted in same number",
+ someDifferent);
+ assertTrue("Calling nextFloat resulted in a number out of range [0,1)",
+ inRange);
+ }
+
+ /**
+ * java.util.Random#nextGaussian()
+ */
+ public void test_nextGaussian() {
+ // Test for method double java.util.Random.nextGaussian()
+ double lastNum = r.nextGaussian();
+ double nextNum;
+ boolean someDifferent = false;
+ boolean someInsideStd = false;
+ for (int counter = 0; counter < 100; counter++) {
+ nextNum = r.nextGaussian();
+ if (nextNum != lastNum)
+ someDifferent = true;
+ if (-1.0 <= nextNum && nextNum <= 1.0)
+ someInsideStd = true;
+ lastNum = nextNum;
+ }
+ assertTrue("Calling nextGaussian 100 times resulted in same number",
+ someDifferent);
+ assertTrue(
+ "Calling nextGaussian 100 times resulted in no number within 1 std. deviation of mean",
+ someInsideStd);
+ }
+
+ /**
+ * java.util.Random#nextInt()
+ */
+ public void test_nextInt() {
+ // Test for method int java.util.Random.nextInt()
+ int lastNum = r.nextInt();
+ int nextNum;
+ boolean someDifferent = false;
+ for (int counter = 0; counter < 100; counter++) {
+ nextNum = r.nextInt();
+ if (nextNum != lastNum)
+ someDifferent = true;
+ lastNum = nextNum;
+ }
+ assertTrue("Calling nextInt 100 times resulted in same number",
+ someDifferent);
+ }
+
+ /**
+ * java.util.Random#nextInt(int)
+ */
+ public void test_nextIntI() {
+ // Test for method int java.util.Random.nextInt(int)
+ final int range = 10;
+ int lastNum = r.nextInt(range);
+ int nextNum;
+ boolean someDifferent = false;
+ boolean inRange = true;
+ for (int counter = 0; counter < 100; counter++) {
+ nextNum = r.nextInt(range);
+ if (nextNum != lastNum)
+ someDifferent = true;
+ if (!(0 <= nextNum && nextNum < range))
+ inRange = false;
+ lastNum = nextNum;
+ }
+ assertTrue("Calling nextInt (range) 100 times resulted in same number",
+ someDifferent);
+ assertTrue(
+ "Calling nextInt (range) resulted in a number outside of [0, range)",
+ inRange);
+
+ }
+
+ /**
+ * java.util.Random#nextLong()
+ */
+ public void test_nextLong() {
+ // Test for method long java.util.Random.nextLong()
+ long lastNum = r.nextLong();
+ long nextNum;
+ boolean someDifferent = false;
+ for (int counter = 0; counter < 100; counter++) {
+ nextNum = r.nextLong();
+ if (nextNum != lastNum)
+ someDifferent = true;
+ lastNum = nextNum;
+ }
+ assertTrue("Calling nextLong 100 times resulted in same number",
+ someDifferent);
+ }
+
+ /**
+ * java.util.Random#setSeed(long)
+ */
+ public void test_setSeedJ() {
+ // Test for method void java.util.Random.setSeed(long)
+ long[] randomArray = new long[100];
+ boolean someDifferent = false;
+ final long firstSeed = 1000;
+ long aLong, anotherLong, yetAnotherLong;
+ Random aRandom = new Random();
+ Random anotherRandom = new Random();
+ Random yetAnotherRandom = new Random();
+ aRandom.setSeed(firstSeed);
+ anotherRandom.setSeed(firstSeed);
+ for (int counter = 0; counter < randomArray.length; counter++) {
+ aLong = aRandom.nextLong();
+ anotherLong = anotherRandom.nextLong();
+ assertTrue(
+ "Two randoms with same seeds gave differing nextLong values",
+ aLong == anotherLong);
+ yetAnotherLong = yetAnotherRandom.nextLong();
+ randomArray[counter] = aLong;
+ if (aLong != yetAnotherLong)
+ someDifferent = true;
+ }
+ assertTrue(
+ "Two randoms with the different seeds gave the same chain of values",
+ someDifferent);
+ aRandom.setSeed(firstSeed);
+ for (int counter = 0; counter < randomArray.length; counter++)
+ assertTrue(
+ "Reseting a random to its old seed did not result in the same chain of values as it gave before",
+ aRandom.nextLong() == randomArray[counter]);
+ }
+
+ class Mock_Random extends Random {
+ boolean nextCalled = false;
+
+ public boolean getFlag () {
+ boolean retVal = nextCalled;
+ nextCalled = false;
+ return retVal;
+ }
+
+ @Override
+ protected int next(int bits) {
+ nextCalled = true;
+ return super.next(bits);
+ }
+ }
+
+ public void test_next() {
+ Mock_Random mr = new Mock_Random();
+ assertFalse(mr.getFlag());
+ mr.nextBoolean();
+ assertTrue(mr.getFlag());
+ mr.nextBytes(new byte[10]);
+ assertTrue(mr.getFlag());
+ mr.nextDouble();
+ assertTrue(mr.getFlag());
+ mr.nextFloat();
+ assertTrue(mr.getFlag());
+ mr.nextGaussian();
+ assertTrue(mr.getFlag());
+ mr.nextInt();
+ assertTrue(mr.getFlag());
+ mr.nextInt(10);
+ assertTrue(mr.getFlag());
+ mr.nextLong();
+ assertTrue(mr.getFlag());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ r = new Random();
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+
+ public void testSerializationCompatibility() throws Exception {
+ Random rand = new Random(0x8123aea6267e055dL);
+ rand.nextGaussian();
+ // SerializationTest.createGoldenFile("/tmp", this, rand);
+ SerializationTest.verifyGolden(this, rand, comparator);
+
+ rand = new Random(0x8123aea6267e055dL);
+ rand.nextGaussian();
+ SerializationTest.verifySelf(rand, comparator);
+ }
+
+ public static final SerializationTest.SerializableAssert comparator =
+ new SerializationTest.SerializableAssert() {
+ public void assertDeserialized(Serializable initial, Serializable deserialized) {
+ Random initialRand = (Random) initial;
+ Random deserializedRand = (Random) deserialized;
+ assertEquals("should be equal", initialRand.nextInt(), deserializedRand.nextInt());
+ }
+ };
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RefSortedMap.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RefSortedMap.java
new file mode 100644
index 0000000..4b829af
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RefSortedMap.java
@@ -0,0 +1,402 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+
+public class RefSortedMap<K, V> extends java.util.AbstractMap<K, V>
+ implements SortedMap<K, V>, Cloneable, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final class MapEntry<K, V> implements Map.Entry<K, V> {
+
+ final K key;
+ V value;
+
+ MapEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ public V setValue(V v) {
+ V res = value;
+ value = v;
+ return res;
+ }
+
+ public int hashCode() {
+ return (getKey() == null ? 0 : getKey().hashCode())
+ ^ (getValue() == null ? 0 : getValue().hashCode());
+ }
+
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (object instanceof Map.Entry) {
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
+ return (getKey() == null ? entry.getKey() == null : getKey().equals(entry
+ .getKey()))
+ && (getValue() == null ? entry.getValue() == null : getValue()
+ .equals(entry.getValue()));
+ }
+ return false;
+ }
+ }
+
+ transient ArrayList<MapEntry<K, V>> entries = new ArrayList<MapEntry<K, V>>();
+ transient int modCnt;
+
+ private final Comparator<? super K> comparator;
+
+ class SubMap extends java.util.AbstractMap<K, V>
+ implements SortedMap<K, V>, Cloneable {
+
+ final boolean hasStart, hasEnd;
+ final K start, end;
+
+ SubMap(boolean hasFirst, K first, boolean hasLast, K last) {
+ this.hasStart = hasFirst;
+ this.start = first;
+ this.hasEnd = hasLast;
+ this.end = last;
+ if (hasStart && hasEnd && compare(start, end) >= 0) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public Set<java.util.Map.Entry<K, V>> entrySet() {
+ return new AbstractSet<Entry<K, V>>() {
+
+ @Override
+ public Iterator<java.util.Map.Entry<K, V>> iterator() {
+ return new Iterator<Entry<K, V>>() {
+ int modCnt = RefSortedMap.this.modCnt;
+ int offset = SubMap.this.size() > 0 ?
+ bsearch(SubMap.this.firstKey()) - 1 :
+ entries.size();
+
+ public boolean hasNext() {
+ if (modCnt != RefSortedMap.this.modCnt) {
+ throw new ConcurrentModificationException();
+ }
+ return offset + 1 < entries.size()
+ && isInRange(entries.get(offset + 1).getKey());
+ }
+
+ public Map.Entry<K, V> next() {
+ if (modCnt != RefSortedMap.this.modCnt) {
+ throw new ConcurrentModificationException();
+ }
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ offset++;
+ return entries.get(offset);
+ }
+
+ public void remove() {
+ if (modCnt != RefSortedMap.this.modCnt) {
+ throw new ConcurrentModificationException();
+ }
+ modCnt++;
+ RefSortedMap.this.modCnt++;
+ RefSortedMap.this.entries.remove(offset);
+ offset--;
+ }
+
+ };
+ }
+
+ @Override
+ public int size() {
+ try {
+ int lastIdx = bsearch(SubMap.this.lastKey());
+ int firstIdx = bsearch(SubMap.this.firstKey());
+ return lastIdx - firstIdx + 1;
+ } catch (NoSuchElementException e) {
+ return 0;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return 0;
+ }
+ }
+
+ };
+ }
+
+ public Comparator<? super K> comparator() {
+ return RefSortedMap.this.comparator();
+ }
+
+ public K firstKey() {
+ if (!hasStart) {
+ K res = RefSortedMap.this.firstKey();
+ if (!isInRange(res)) {
+ throw new NoSuchElementException();
+ }
+ return res;
+ }
+ int idx = bsearch(start);
+ if (idx >= 0) {
+ return start;
+ }
+ if (-idx - 1 >= entries.size() || !isInRange(entries.get(-idx - 1).getKey())) {
+ throw new NoSuchElementException();
+ }
+ return entries.get(-idx - 1).getKey();
+ }
+
+ public SortedMap<K, V> headMap(K key) {
+ if (!isInRange(key)) {
+ throw new IllegalArgumentException();
+ }
+ return new SubMap(hasStart, start, true, key);
+ }
+
+ public K lastKey() {
+ if (!hasEnd) {
+ K res = RefSortedMap.this.lastKey();
+ if (!isInRange(res)) {
+ throw new NoSuchElementException();
+ }
+ return res;
+ }
+ int idx = bsearch(end);
+ idx = idx >= 0 ? idx - 1 : -idx - 2;
+ if (idx < 0 || !isInRange(entries.get(idx).getKey())) {
+ throw new NoSuchElementException();
+ }
+ return entries.get(idx).getKey();
+ }
+
+ public SortedMap<K, V> subMap(K startKey, K endKey) {
+ if (!isInRange(startKey)) {
+ throw new IllegalArgumentException();
+ }
+ if (!isInRange(endKey)) {
+ throw new IllegalArgumentException();
+ }
+ return new SubMap(true, startKey, true, endKey);
+ }
+
+ public SortedMap<K, V> tailMap(K key) {
+ if (!isInRange(key)) {
+ throw new IllegalArgumentException();
+ }
+ return new SubMap(true, key, hasEnd, end);
+ }
+
+ private boolean isInRange(K key) {
+ if (hasStart && compare(key, start) < 0) {
+ return false;
+ }
+ if (hasEnd && compare(key, end) >= 0) {
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ public RefSortedMap() {
+ this((Comparator<? super K>) null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public int compare(K start, K end) {
+ return comparator != null ? comparator.compare(start, end)
+ : ((Comparable<K>) start).compareTo(end);
+ }
+
+ @SuppressWarnings("unchecked")
+ public RefSortedMap(Comparator<? super K> comparator) {
+ this.comparator = comparator;
+ cmp = createCmp();
+ }
+
+ public RefSortedMap(Map<? extends K, ? extends V> map) {
+ this();
+ putAll(map);
+ }
+
+ public RefSortedMap(SortedMap<K, ? extends V> map) {
+ this(map.comparator());
+ putAll(map);
+ }
+
+ public Comparator<? super K> comparator() {
+ return comparator;
+ }
+
+ public Set<Map.Entry<K, V>> entrySet() {
+ return tailMap(firstKey()).entrySet();
+ }
+
+ public K firstKey() {
+ return entries.get(0).getKey();
+ }
+
+ public SortedMap<K, V> headMap(K key) {
+ return new SubMap(false, null, true, key);
+ }
+
+ public Set<K> keySet() {
+ return tailMap(firstKey()).keySet();
+ }
+
+ public K lastKey() {
+ return entries.get(entries.size() - 1).getKey();
+ }
+
+ public SortedMap<K, V> subMap(K startKey, K endKey) {
+ return new SubMap(true, startKey, true, endKey);
+ }
+
+ public SortedMap<K, V> tailMap(K key) {
+ return new SubMap(true, key, false, null);
+ }
+
+ public Collection<V> values() {
+ return tailMap(firstKey()).values();
+ }
+
+ public void clear() {
+ entries.clear();
+ }
+
+ public boolean containsKey(Object arg0) {
+ return bsearch(arg0) >= 0;
+ }
+
+ public boolean containsValue(Object arg0) {
+ for (V v : values()) {
+ if (arg0.equals(v)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ public V get(Object arg0) {
+ int idx = bsearch(arg0);
+ return idx >= 0 ? entries.get(idx).getValue() : null;
+ }
+
+ public boolean isEmpty() {
+ return entries.isEmpty();
+ }
+
+ public V put(K arg0, V arg1) {
+ modCnt++;
+ int idx = bsearch(arg0);
+ if (idx >= 0) {
+ return entries.get(idx).setValue(arg1);
+ }
+ entries.add(-idx - 1, new MapEntry<K, V>(arg0, arg1));
+ return null;
+ }
+
+ public void putAll(Map<? extends K, ? extends V> arg0) {
+ for (Map.Entry<? extends K, ? extends V> e : arg0.entrySet()) {
+ put(e.getKey(), e.getValue());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public V remove(Object arg0) {
+ modCnt++;
+ int idx = bsearch(arg0);
+ if (idx < 0) {
+ return null;
+ }
+ return entries.remove(idx).getValue();
+ }
+
+ transient private Comparator<MapEntry<K, V>> cmp = createCmp();
+
+ Comparator<MapEntry<K, V>> createCmp() {
+ return new Comparator<MapEntry<K, V>>() {
+
+ public int compare(MapEntry<K, V> arg0, MapEntry<K, V> arg1) {
+ return RefSortedMap.this.compare(arg0.getKey(), arg1.getKey());
+ }
+
+ };
+ }
+
+ @SuppressWarnings("unchecked")
+ private int bsearch(Object arg0) {
+ return Collections.binarySearch(entries, new MapEntry<K, V>((K) arg0, null), cmp);
+ }
+
+ public int size() {
+ return entries.size();
+ }
+
+ public RefSortedMap<K, V> clone() {
+ return new RefSortedMap<K, V>(this);
+ }
+
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeInt(size());
+ for (Map.Entry<K, V> e : entrySet()) {
+ stream.writeObject(e.getKey());
+ stream.writeObject(e.getValue());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void readObject(ObjectInputStream stream) throws IOException,
+ ClassNotFoundException {
+
+ cmp = createCmp();
+ stream.defaultReadObject();
+ int size = stream.readInt();
+ entries = new ArrayList<MapEntry<K, V>>(size);
+ for (int i = 0; i < size; i++) {
+ put((K) stream.readObject(), (V) stream.readObject());
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ResourceBundleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ResourceBundleTest.java
new file mode 100644
index 0000000..11be2fe
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ResourceBundleTest.java
@@ -0,0 +1,398 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import dalvik.annotation.KnownFailure;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import org.apache.harmony.tests.java.util.support.B;
+import tests.support.resource.Support_Resources;
+
+public class ResourceBundleTest extends junit.framework.TestCase {
+
+ public void test_getCandidateLocales() throws Exception {
+ ResourceBundle.Control c = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
+ assertEquals("[en_US, en, ]", c.getCandidateLocales("base", Locale.US).toString());
+ assertEquals("[de_CH, de, ]", c.getCandidateLocales("base", new Locale("de", "CH")).toString());
+ }
+
+ /**
+ * java.util.ResourceBundle#getBundle(java.lang.String,
+ * java.util.Locale)
+ */
+ public void test_getBundleLjava_lang_StringLjava_util_Locale() {
+ ResourceBundle bundle;
+ String name = "tests.support.Support_TestResource";
+ Locale defLocale = Locale.getDefault();
+
+ Locale.setDefault(new Locale("en", "US"));
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
+ assertEquals("Wrong bundle fr_FR_VAR", "frFRVARValue4", bundle.getString("parent4"));
+
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "v1"));
+ assertEquals("Wrong bundle fr_FR_v1", "frFRValue4", bundle.getString("parent4"));
+
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "US", "VAR"));
+ assertEquals("Wrong bundle fr_US_var", "frValue4", bundle.getString("parent4"));
+
+ bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "VAR"));
+ assertEquals("Wrong bundle de_FR_var", "enUSValue4", bundle.getString("parent4"));
+
+ Locale.setDefault(new Locale("fr", "FR", "VAR"));
+ bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "v1"));
+ assertEquals("Wrong bundle de_FR_var 2", "frFRVARValue4", bundle.getString("parent4"));
+
+ Locale.setDefault(new Locale("de", "US"));
+ bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "var"));
+ assertEquals("Wrong bundle de_FR_var 2", "parentValue4", bundle.getString("parent4")
+ );
+
+ try {
+ ResourceBundle.getBundle(null, Locale.US);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+ try {
+ ResourceBundle.getBundle("blah", (Locale) null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+
+ try {
+ ResourceBundle.getBundle("", new Locale("xx", "yy"));
+ fail("MissingResourceException expected");
+ } catch (MissingResourceException ee) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.ResourceBundle#getBundle(java.lang.String,
+ * java.util.Locale, java.lang.ClassLoader)
+ */
+ @KnownFailure("It's not allowed to pass null as parent class loader to"
+ + " a new ClassLoader anymore. Maybe we need to change"
+ + " URLClassLoader to allow this? It's not specified.")
+ public void test_getBundleLjava_lang_StringLjava_util_LocaleLjava_lang_ClassLoader() {
+ String classPath = System.getProperty("java.class.path");
+ StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator);
+ Vector<URL> urlVec = new Vector<URL>();
+ String resPackage = Support_Resources.RESOURCE_PACKAGE;
+ try {
+ while (tok.hasMoreTokens()) {
+ String path = tok.nextToken();
+ String url;
+ if (new File(path).isDirectory())
+ url = "file:" + path + resPackage + "subfolder/";
+ else
+ url = "jar:file:" + path + "!" + resPackage + "subfolder/";
+ urlVec.addElement(new URL(url));
+ }
+ } catch (MalformedURLException e) {
+ }
+ URL[] urls = new URL[urlVec.size()];
+ for (int i = 0; i < urlVec.size(); i++)
+ urls[i] = urlVec.elementAt(i);
+ URLClassLoader loader = new URLClassLoader(urls, null);
+
+ String name = Support_Resources.RESOURCE_PACKAGE_NAME
+ + ".hyts_resource";
+ ResourceBundle bundle = ResourceBundle.getBundle(name, Locale
+ .getDefault());
+ assertEquals("Wrong value read", "parent", bundle.getString("property"));
+ bundle = ResourceBundle.getBundle(name, Locale.getDefault(), loader);
+ assertEquals("Wrong cached value",
+ "resource", bundle.getString("property"));
+
+ try {
+ ResourceBundle.getBundle(null, Locale.getDefault(), loader);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ try {
+ ResourceBundle.getBundle(name, null, loader);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ try {
+ ResourceBundle.getBundle(name, Locale.getDefault(), (ClassLoader) null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ try {
+ ResourceBundle.getBundle("", Locale.getDefault(), loader);
+ fail("MissingResourceException expected");
+ } catch (MissingResourceException ee) {
+ //expected
+ }
+
+ // Regression test for Harmony-3823
+ B bb = new B();
+ String s = bb.find("nonexistent");
+ s = bb.find("name");
+ assertEquals("Wrong property got", "Name", s);
+ }
+
+ /**
+ * java.util.ResourceBundle#getString(java.lang.String)
+ */
+ public void test_getStringLjava_lang_String() {
+ ResourceBundle bundle;
+ String name = "tests.support.Support_TestResource";
+ Locale.setDefault(new Locale("en", "US"));
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
+ assertEquals("Wrong value parent4",
+ "frFRVARValue4", bundle.getString("parent4"));
+ assertEquals("Wrong value parent3",
+ "frFRValue3", bundle.getString("parent3"));
+ assertEquals("Wrong value parent2",
+ "frValue2", bundle.getString("parent2"));
+ assertEquals("Wrong value parent1",
+ "parentValue1", bundle.getString("parent1"));
+ assertEquals("Wrong value child3",
+ "frFRVARChildValue3", bundle.getString("child3"));
+ assertEquals("Wrong value child2",
+ "frFRVARChildValue2", bundle.getString("child2"));
+ assertEquals("Wrong value child1",
+ "frFRVARChildValue1", bundle.getString("child1"));
+
+ try {
+ bundle.getString(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ try {
+ bundle.getString("");
+ fail("MissingResourceException expected");
+ } catch (MissingResourceException ee) {
+ //expected
+ }
+
+ try {
+ bundle.getString("IntegerVal");
+ fail("ClassCastException expected");
+ } catch (ClassCastException ee) {
+ //expected
+ }
+ }
+ public void test_getBundle_getClassName() {
+ // Regression test for Harmony-1759
+ Locale locale = Locale.GERMAN;
+ String nonExistentBundle = "Non-ExistentBundle";
+ try {
+ ResourceBundle.getBundle(nonExistentBundle, locale, this.getClass()
+ .getClassLoader());
+ fail("MissingResourceException expected!");
+ } catch (MissingResourceException e) {
+ assertEquals(nonExistentBundle + "_" + locale, e.getClassName());
+ }
+
+ try {
+ ResourceBundle.getBundle(nonExistentBundle, locale);
+ fail("MissingResourceException expected!");
+ } catch (MissingResourceException e) {
+ assertEquals(nonExistentBundle + "_" + locale, e.getClassName());
+ }
+
+ locale = Locale.getDefault();
+ try {
+ ResourceBundle.getBundle(nonExistentBundle);
+ fail("MissingResourceException expected!");
+ } catch (MissingResourceException e) {
+ assertEquals(nonExistentBundle + "_" + locale, e.getClassName());
+ }
+ }
+
+ class Mock_ResourceBundle extends ResourceBundle {
+ @Override
+ public Enumeration<String> getKeys() {
+ return null;
+ }
+
+ @Override
+ protected Object handleGetObject(String key) {
+ return null;
+ }
+ }
+
+ public void test_constructor() {
+ assertNotNull(new Mock_ResourceBundle());
+ }
+
+ public void test_getLocale() {
+ ResourceBundle bundle;
+ String name = "tests.support.Support_TestResource";
+ Locale loc = Locale.getDefault();
+ Locale.setDefault(new Locale("en", "US"));
+
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
+ assertEquals("fr_FR_VAR", bundle.getLocale().toString());
+
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "v1"));
+ assertEquals("fr_FR", bundle.getLocale().toString());
+
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "US", "VAR"));
+ assertEquals("fr", bundle.getLocale().toString());
+
+ bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "VAR"));
+ assertEquals("en_US", bundle.getLocale().toString());
+
+ bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "v1"));
+ assertEquals("en_US", bundle.getLocale().toString());
+
+ bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "var"));
+ assertEquals("en_US", bundle.getLocale().toString());
+
+ Locale.setDefault(loc);
+ }
+
+ public void test_getObjectLjava_lang_String() {
+ ResourceBundle bundle;
+ String name = "tests.support.Support_TestResource";
+ Locale.setDefault(new Locale("en", "US"));
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
+ assertEquals("Wrong value parent4",
+ "frFRVARValue4", (String)bundle.getObject("parent4"));
+ assertEquals("Wrong value parent3",
+ "frFRValue3", (String)bundle.getObject("parent3"));
+ assertEquals("Wrong value parent2",
+ "frValue2", (String) bundle.getObject("parent2"));
+ assertEquals("Wrong value parent1",
+ "parentValue1", (String)bundle.getObject("parent1"));
+ assertEquals("Wrong value child3",
+ "frFRVARChildValue3", (String)bundle.getObject("child3"));
+ assertEquals("Wrong value child2",
+ "frFRVARChildValue2", (String) bundle.getObject("child2"));
+ assertEquals("Wrong value child1",
+ "frFRVARChildValue1", (String)bundle.getObject("child1"));
+ assertEquals("Wrong value IntegerVal",
+ 1, bundle.getObject("IntegerVal"));
+
+ try {
+ bundle.getObject(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ try {
+ bundle.getObject("");
+ fail("MissingResourceException expected");
+ } catch (MissingResourceException ee) {
+ //expected
+ }
+ }
+
+ public void test_getStringArrayLjava_lang_String() {
+ ResourceBundle bundle;
+ String name = "tests.support.Support_TestResource";
+ Locale.setDefault(new Locale("en", "US"));
+ bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
+
+ String[] array = bundle.getStringArray("StringArray");
+ for(int i = 0; i < array.length; i++) {
+ assertEquals("Str" + (i + 1), array[i]);
+ }
+
+ try {
+ bundle.getStringArray(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ try {
+ bundle.getStringArray("");
+ fail("MissingResourceException expected");
+ } catch (MissingResourceException ee) {
+ //expected
+ }
+
+ try {
+ bundle.getStringArray("IntegerVal");
+ fail("ClassCastException expected");
+ } catch (ClassCastException ee) {
+ //expected
+ }
+ }
+
+ public void test_getBundleLjava_lang_String() {
+ ResourceBundle bundle;
+ String name = "tests.support.Support_TestResource";
+ Locale defLocale = Locale.getDefault();
+
+ Locale.setDefault(new Locale("en", "US"));
+ bundle = ResourceBundle.getBundle(name);
+ assertEquals("enUSValue4", bundle.getString("parent4"));
+
+ Locale.setDefault(new Locale("fr", "FR", "v1"));
+ bundle = ResourceBundle.getBundle(name);
+ assertEquals("Wrong bundle fr_FR_v1", "frFRValue4", bundle.getString("parent4"));
+
+ Locale.setDefault(new Locale("fr", "US", "VAR"));
+ bundle = ResourceBundle.getBundle(name);
+ assertEquals("Wrong bundle fr_US_var", "frValue4", bundle.getString("parent4"));
+
+ Locale.setDefault(new Locale("de", "FR", "VAR"));
+ bundle = ResourceBundle.getBundle(name);
+ assertEquals("Wrong bundle de_FR_var", "parentValue4", bundle.getString("parent4"));
+
+ Locale.setDefault(new Locale("de", "FR", "v1"));
+ bundle = ResourceBundle.getBundle(name);
+ assertEquals("Wrong bundle de_FR_var 2", "parentValue4", bundle.getString("parent4"));
+
+ Locale.setDefault(new Locale("de", "FR", "var"));
+ bundle = ResourceBundle.getBundle(name);
+ assertEquals("Wrong bundle de_FR_var 2", "parentValue4", bundle.getString("parent4"));
+
+ try {
+ ResourceBundle.getBundle(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ //expected
+ }
+
+ try {
+ ResourceBundle.getBundle("");
+ fail("MissingResourceException expected");
+ } catch (MissingResourceException ee) {
+ //expected
+ }
+
+ Locale.setDefault(defLocale);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SampleBundleClass.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SampleBundleClass.java
new file mode 100644
index 0000000..394291b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SampleBundleClass.java
@@ -0,0 +1,43 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Part of the ResourceBundleTest
+ */
+public class SampleBundleClass {
+
+ private static SampleBundleClass singleton;
+ private static ResourceBundle bundle;
+
+ public SampleBundleClass() {
+ super();
+ if (singleton != null) {
+ throw new RuntimeException();
+ }
+ singleton = this;
+ try {
+ bundle = ResourceBundle.getBundle("tests.api.simple.SampleBundleClass");
+ } catch (MissingResourceException x) {
+ System.out.println("Missing resource");
+ bundle = null;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerParseLargeFileBenchmarkTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerParseLargeFileBenchmarkTest.java
new file mode 100644
index 0000000..c0f9e58
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerParseLargeFileBenchmarkTest.java
@@ -0,0 +1,73 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Scanner;
+
+import junit.framework.TestCase;
+
+public class ScannerParseLargeFileBenchmarkTest extends TestCase {
+
+ /**
+ * Check whether the Scanner will exhaust all heap memory when parsing a
+ * large file.
+ */
+ public void testParseLargeFile() throws Exception {
+ FakeLargeFile reader = new FakeLargeFile();
+ String delimiter = "\r?\n";
+ Scanner scanner = new Scanner(reader).useDelimiter(delimiter);
+
+ while (scanner.hasNext()) {
+ scanner.next();
+ }
+ scanner.close();
+ reader.close();
+ }
+
+ private static class FakeLargeFile extends Reader {
+ private static final char[] CONTENT = "large file!\n".toCharArray();
+ private static final int FILE_LENGTH = 192 * 1024 * 1024; // 192 MB
+
+ private int count = 0;
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public int read(char[] buffer, int offset, int length) {
+ if (count >= FILE_LENGTH) {
+ return -1;
+ }
+
+ final int charsToRead = Math.min(FILE_LENGTH - count, length);
+ int bufferIndex = offset;
+ int contentIndex = count % CONTENT.length;
+ int charsRead = 0;
+ while (charsRead < charsToRead) {
+ buffer[bufferIndex++] = CONTENT[contentIndex++];
+ if (contentIndex == CONTENT.length) {
+ contentIndex = 0;
+ }
+ charsRead++;
+ }
+ count += charsRead;
+ return charsToRead;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java
new file mode 100644
index 0000000..cc6a0f0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java
@@ -0,0 +1,5606 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.InputMismatchException;
+import java.util.List;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+import java.util.Scanner;
+import java.util.regex.MatchResult;
+import java.util.regex.Pattern;
+import junit.framework.TestCase;
+
+public class ScannerTest extends TestCase {
+
+ private Scanner s;
+
+ private ServerSocket server;
+
+ private SocketAddress address;
+
+ private SocketChannel client;
+
+ private Socket serverSocket;
+
+ private OutputStream os;
+
+ private static class MockCloseable implements Closeable, Readable {
+
+ public void close() throws IOException {
+ throw new IOException();
+ }
+
+ public int read(CharBuffer cb) throws IOException {
+ throw new EOFException();
+ }
+
+ }
+
+ /**
+ * @tests java.util.Scanner#Scanner(File)
+ */
+ public void test_ConstructorLjava_io_File() throws IOException {
+ File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
+ s = new Scanner(tmpFile);
+ assertNotNull(s);
+ s.close();
+ assertTrue(tmpFile.delete());
+
+ try {
+ s = new Scanner(tmpFile);
+ fail();
+ } catch (FileNotFoundException expected) {
+ }
+
+ tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
+ FileOutputStream fos = new FileOutputStream(tmpFile);
+ fos.write("test".getBytes());
+ fos.close();
+
+ s = new Scanner(tmpFile);
+ s.close();
+ tmpFile.delete();
+
+ // Scanner(File = null)
+ try {
+ s = new Scanner((File) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // TODO: test if the default charset is used.
+ }
+
+ /**
+ * @tests java.util.Scanner#Scanner(File, String)
+ */
+ public void test_ConstructorLjava_io_FileLjava_lang_String()
+ throws IOException {
+ File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
+ s = new Scanner(tmpFile, Charset.defaultCharset().name());
+ assertNotNull(s);
+ s.close();
+ assertTrue(tmpFile.delete());
+
+ try {
+ s = new Scanner(tmpFile, Charset.defaultCharset().name());
+ fail();
+ } catch (FileNotFoundException expected) {
+ }
+
+ try {
+ s = new Scanner(tmpFile, null);
+ fail();
+ } catch (FileNotFoundException expected) {
+ }
+
+ tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
+ try {
+ s = new Scanner(tmpFile, "invalid charset");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ //fail on RI. File is opened but not closed when exception is thrown on
+ // RI.
+ assertTrue(tmpFile.delete());
+
+ // Scanner(File = null, Charset = null)
+ try {
+ s = new Scanner((File) null, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // Scanner(File = null, Charset = UTF-8)
+ try {
+ s = new Scanner((File) null, "UTF-8");
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // Scanner(File = null, Charset = invalid)
+ try {
+ s = new Scanner((File) null, "invalid");
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // Scanner(File, Charset = null)
+ try {
+ File f = File.createTempFile("test", ".tmp");
+ s = new Scanner(f, null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // TODO: test if the specified charset is used.
+ }
+
+ /**
+ * @tests java.util.Scanner#Scanner(InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() {
+ s = new Scanner(new PipedInputStream());
+ assertNotNull(s);
+ s.close();
+
+ // Scanner(InputStream)
+ try {
+ s = new Scanner((InputStream) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // TODO: test if the default charset is used.
+ }
+
+ /**
+ * @tests java.util.Scanner#Scanner(InputStream, String)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_lang_String() {
+ s = new Scanner(new PipedInputStream(), Charset.defaultCharset().name());
+ assertNotNull(s);
+ s.close();
+
+ try {
+ s = new Scanner((PipedInputStream) null, "invalid charset");
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ s = new Scanner(new PipedInputStream(), null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ s = new Scanner(new PipedInputStream(), "invalid charset");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // TODO: test if the specified charset is used.
+ }
+
+ /**
+ * @tests java.util.Scanner#Scanner(Readable)
+ */
+ public void test_ConstructorLjava_lang_Readable() {
+ s = new Scanner(new StringReader("test string"));
+ assertNotNull(s);
+ s.close();
+
+ // Scanner(Readable)
+ try {
+ s = new Scanner((Readable) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * @tests java.util.Scanner#Scanner(ReadableByteChannel)
+ */
+ public void test_ConstructorLjava_nio_channels_ReadableByteChannel()
+ throws IOException {
+ File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
+ FileChannel fc = new FileOutputStream(tmpFile).getChannel();
+ s = new Scanner(fc);
+ assertNotNull(s);
+ s.close();
+ assertTrue(tmpFile.delete());
+
+ // Scanner(ReadableByteChannel)
+ try {
+ s = new Scanner((ReadableByteChannel) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // Test if the default charset is used.
+ String sampleData = "1 2 3 4 5 6 7 8 9 10";
+ File tempFile = File.createTempFile("harmony", "test");
+ tempFile.deleteOnExit();
+ FileOutputStream os = new FileOutputStream(tempFile);
+ os.write(sampleData.getBytes());
+ os.close();
+
+ FileInputStream is = new FileInputStream(tempFile);
+ FileChannel channel = is.getChannel();
+
+ Scanner s = new Scanner(channel);
+ int count = 0;
+ while (s.hasNextInt()) {
+ s.nextInt();
+ count++;
+ }
+ channel.close();
+ assertEquals(10, count);
+ }
+
+ /**
+ * @tests java.util.Scanner#Scanner(ReadableByteChannel, String)
+ */
+ public void test_ConstructorLjava_nio_channels_ReadableByteChannelLjava_lang_String()
+ throws IOException {
+ File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
+ FileChannel fc = new FileOutputStream(tmpFile).getChannel();
+ s = new Scanner(fc, Charset.defaultCharset().name());
+ assertNotNull(s);
+ s.close();
+
+ fc = new FileOutputStream(tmpFile).getChannel();
+ try {
+ s = new Scanner(fc, "invalid charset");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ fc.close();
+ assertTrue(tmpFile.delete());
+
+ // Scanner(ReadableByteChannel = null, Charset = null)
+ try {
+ s = new Scanner((ReadableByteChannel) null, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // Scanner(ReadableByteChannel = null, Charset = invalid)
+ try {
+ s = new Scanner((ReadableByteChannel) null, "invalid");
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // Scanner(ReadableByteChannel, Charset = null)
+ try {
+ s = new Scanner(fc, null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ // TODO: test if the specified charset is used.
+ }
+
+ public void test_Constructor_LReadableByteChannel() throws IOException {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+
+ SocketChannel sc = SocketChannel.open();
+ sc.connect(ssc.socket().getLocalSocketAddress());
+ sc.configureBlocking(false);
+ assertFalse(sc.isBlocking());
+
+ ssc.accept().close();
+ ssc.close();
+ assertFalse(sc.isBlocking());
+
+ Scanner s = new Scanner(sc);
+ try {
+ s.hasNextInt();
+ fail();
+ } catch (IllegalBlockingModeException expected) {
+ }
+
+ sc.close();
+ }
+
+ /**
+ * @tests java.util.Scanner#Scanner(String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ s = new Scanner("test string");
+ assertNotNull(s);
+ s.close();
+
+ // Scanner(String)
+ try {
+ s = new Scanner((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * @tests java.util.Scanner#close()
+ */
+ public void test_close() throws IOException {
+ File tmpFile = File.createTempFile("TestFileForScanner", ".tmp");
+ FileOutputStream fos = new FileOutputStream(tmpFile);
+ FileChannel fc = fos.getChannel();
+ s = new Scanner(fc);
+
+ // Write out a int before the scanner is closed, should be OK.
+ fos.write(12);
+
+ s.close();
+ assertFalse(fc.isOpen());
+
+ // Write out a int after the scanner is closed, IOException should be
+ // thrown out.
+ try {
+ fos.write(12);
+ fail();
+ } catch (IOException expected) {
+ }
+
+ s.close(); // no exception should be thrown
+ assertTrue(tmpFile.delete());
+ }
+
+ /**
+ * @tests java.util.Scanner#ioException()
+ */
+ public void test_ioException() throws IOException {
+ MockCloseable mc = new MockCloseable();
+ s = new Scanner(mc);
+ assertNull(s.ioException()); // No operation, no exception
+
+ s.close(); // IOException should be cached
+ assertNotNull(s.ioException());
+ assertTrue(s.ioException() instanceof IOException);
+ }
+
+ /**
+ * @tests java.util.Scanner#delimiter()
+ */
+ public void test_delimiter() {
+ s = new Scanner("test");
+ Pattern pattern = s.delimiter();
+ assertEquals("\\p{javaWhitespace}+", pattern.toString());
+ }
+
+ /**
+ * @tests java.util.Scanner#useDelimiter(Pattern)
+ */
+ public void test_useDelimiter_LPattern() {
+ s = new Scanner("test");
+ s.useDelimiter(Pattern.compile("\\w+"));
+ assertEquals("\\w+", s.delimiter().toString());
+
+ s = new Scanner("test");
+ s.useDelimiter((Pattern) null);
+ assertNull(s.delimiter());
+ }
+
+ /**
+ * @tests java.util.Scanner#useDelimiter(String)
+ */
+ public void test_useDelimiter_String() {
+ s = new Scanner("test");
+ try {
+ s.useDelimiter((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ s = new Scanner("test");
+ s.useDelimiter("\\w+");
+ assertEquals("\\w+", s.delimiter().toString());
+ }
+
+ /**
+ * @tests java.util.Scanner#locale()
+ */
+ public void test_locale() {
+ s = new Scanner("test");
+ assertEquals(Locale.getDefault(), s.locale());
+ }
+
+ /**
+ * @tests java.util.Scanner#useLocale(Locale)
+ */
+ public void test_useLocale_LLocale() {
+ s = new Scanner("test");
+ try {
+ s.useLocale(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ s.useLocale(new Locale("test", "test"));
+ assertEquals(new Locale("test", "test"), s.locale());
+ }
+
+ /**
+ * @tests java.util.Scanner#radix()
+ */
+ public void test_radix() {
+ s = new Scanner("test");
+ assertEquals(10, s.radix());
+ }
+
+ /**
+ * @tests java.util.Scanner#useRadix()
+ */
+ public void test_useRadix_I() {
+ s = new Scanner("test");
+ try {
+ s.useRadix(Character.MIN_RADIX - 1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ s.useRadix(Character.MAX_RADIX + 1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ s.useRadix(11);
+ assertEquals(11, s.radix());
+ }
+
+ /**
+ * @tests java.util.Scanner#remove()
+ */
+ public void test_remove() {
+ s = new Scanner("aab*b*").useDelimiter("\\*");
+ try {
+ s.remove();
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ /**
+ * @tests java.util.Scanner#match()
+ */
+ public void test_match() {
+ MatchResult result ;
+ s = new Scanner("1 2 ");
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ assertEquals("1", s.next());
+ assertEquals("2", s.next());
+ result = s.match();
+ assertEquals(2, result.start());
+ assertEquals(3, result.end());
+ assertEquals(2, result.start(0));
+ assertEquals(3, result.end(0));
+ assertEquals("2", result.group());
+ assertEquals("2", result.group(0));
+ assertEquals(0, result.groupCount());
+ try {
+ result.start(1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("True faLse");
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ assertTrue(s.nextBoolean());
+ result = s.match();
+ assertEquals(0, result.start());
+ assertEquals(4, result.end());
+ assertEquals(0, result.start(0));
+ assertEquals(4, result.end(0));
+ assertEquals("True", result.group());
+ assertEquals(0, result.groupCount());
+ assertFalse(s.nextBoolean());
+ try {
+ s.nextBoolean();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("True faLse");
+ assertTrue(s.nextBoolean());
+ result = s.match();
+ assertEquals(0, result.start());
+ assertEquals(4, result.end());
+ assertEquals(0, result.start(0));
+ assertEquals(4, result.end(0));
+ assertEquals("True", result.group());
+ assertEquals(0, result.groupCount());
+ s.close();
+ try {
+ s.nextBoolean();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ result = s.match();
+ assertEquals(0, result.start());
+ assertEquals(4, result.end());
+ assertEquals(0, result.start(0));
+ assertEquals(4, result.end(0));
+ assertEquals("True", result.group());
+ assertEquals(0, result.groupCount());
+
+ s = new Scanner("True fase");
+ assertTrue(s.nextBoolean());
+ assertEquals(0, result.groupCount());
+ try {
+ s.nextBoolean();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("True fase");
+ assertTrue(s.nextBoolean());
+ try {
+ s.next((Pattern)null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ result = s.match();
+ assertEquals(0, result.start());
+ assertEquals(4, result.end());
+ assertEquals(0, result.start(0));
+ assertEquals(4, result.end(0));
+ assertEquals("True", result.group());
+ assertEquals(0, result.groupCount());
+
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#next()
+ */
+ public void test_next() throws IOException {
+ // use special delimiter
+ s = new Scanner("1**2").useDelimiter("\\*");
+ assertEquals("1", s.next());
+ assertEquals("", s.next());
+ assertEquals("2", s.next());
+
+ s = new Scanner(" \t 1 \t 2").useDelimiter("\\s*");
+ assertEquals("1", s.next());
+ assertEquals("2", s.next());
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("a").useDelimiter("a?");
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("aa").useDelimiter("a?");
+ assertEquals("", s.next());
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+
+ s = new Scanner("word( )test( )").useDelimiter("\\( \\)");
+ assertEquals("word", s.next());
+ assertEquals("test", s.next());
+
+ s = new Scanner("? next ").useDelimiter("( )");
+ assertEquals("?", s.next());
+ assertEquals("next", s.next());
+ assertEquals("", s.next());
+
+ s = new Scanner("word1 word2 ");
+ assertEquals("word1", s.next());
+ assertEquals("word2", s.next());
+ // test boundary case
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // just delimiter exists in this scanner
+ s = new Scanner(" ");
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // nothing exists in this scanner
+ s = new Scanner("");
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // no delimiter exists in this scanner
+ s = new Scanner("test");
+ assertEquals("test", s.next());
+
+ // input resourse starts with delimiter
+ s = new Scanner(" test");
+ assertEquals("test", s.next());
+
+ // input resource ends with delimiter
+ s = new Scanner(" test ");
+ assertEquals("test", s.next());
+
+ // Harmony uses 1024 as default buffer size,
+ // What if a sentence can not be read in all in once.
+ StringBuilder longSentence = new StringBuilder(1025);
+ for (int i = 0; i < 11; i++) {
+ longSentence.append(" ");
+ }
+ for (int i = 11; i < 1026; i++) {
+ longSentence.append("a");
+ }
+ s = new Scanner(longSentence.toString());
+ assertEquals(longSentence.toString().trim(), s.next());
+
+ s = new Scanner(" test test");
+ assertEquals("test", s.next());
+ assertEquals("test", s.next());
+
+ // What if use a delimiter of length 0.
+ s = new Scanner("test\ntest").useDelimiter(Pattern.compile("^",
+ Pattern.MULTILINE));
+ assertEquals("test\n", s.next());
+ assertEquals("test", s.next());
+
+ s = new Scanner("").useDelimiter(Pattern.compile("^",
+ Pattern.MULTILINE));
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("").useDelimiter(Pattern.compile("^*",
+ Pattern.MULTILINE));
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("test\ntest").useDelimiter(Pattern.compile("^*",
+ Pattern.MULTILINE));
+ assertEquals("t", s.next());
+ assertEquals("e", s.next());
+
+ s = new Scanner("\ntest\ntest").useDelimiter(Pattern.compile("$",
+ Pattern.MULTILINE));
+ assertEquals("\ntest", s.next());
+ assertEquals("\ntest", s.next());
+
+ // test socket inputStream
+ // Harmony uses 1024 as default buffer size,
+ // what if the leading delimiter is larger than 1023
+ for (int i = 0; i < 1024; i++) {
+ os.write(" ".getBytes());
+ }
+ os.write(" 1 2 ".getBytes());
+ s = new Scanner(client);
+ assertEquals("1", s.next());
+ assertEquals("2", s.next());
+ os.write(" 1 2".getBytes());
+ serverSocket.close();
+ assertEquals("1", s.next());
+ assertEquals("2", s.next());
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#next(Pattern)
+ */
+ public void test_nextLPattern() throws IOException {
+ Pattern pattern;
+ s = new Scanner("aab*2*").useDelimiter("\\*");
+ pattern = Pattern.compile("a*b");
+ assertEquals("aab", s.next(pattern));
+ try {
+ s.next(pattern);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("word ? ");
+ pattern = Pattern.compile("\\w+");
+ assertEquals("word", s.next(pattern));
+ try {
+ s.next(pattern);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("word1 word2 ");
+ pattern = Pattern.compile("\\w+");
+ assertEquals("word1", s.next(pattern));
+ assertEquals("word2", s.next(pattern));
+ // test boundary case
+ try {
+ s.next(pattern);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // test socket inputStream
+
+ os.write("aab 2".getBytes());
+ serverSocket.close();
+
+ s = new Scanner(client);
+ pattern = Pattern.compile("a*b");
+ assertEquals("aab", s.next(pattern));
+ try {
+ s.next(pattern);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#next(String)
+ */
+ public void test_nextLString() throws IOException {
+ s = new Scanner("b*a*").useDelimiter("\\*");
+ assertEquals("b", s.next("a*b"));
+ try {
+ s.next("a*b");
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("word ? ");
+ assertEquals("word", s.next("\\w+"));
+ try {
+ s.next("\\w+");
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("word1 next ");
+ assertEquals("word1", s.next("\\w+"));
+ assertEquals("next", s.next("\\w+"));
+ // test boundary case
+ try {
+ s.next("\\w+");
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // test socket inputStream
+ os.write("aab 2".getBytes());
+ serverSocket.close();
+
+ s = new Scanner(client);
+ assertEquals("aab", s.next("a*b"));
+ try {
+ s.next("a*b");
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextBoolean()
+ */
+ public void test_nextBoolean() throws IOException {
+ // case insensitive
+ s = new Scanner("TRue");
+ assertTrue(s.nextBoolean());
+
+ s = new Scanner("tRue false");
+ assertTrue(s.nextBoolean());
+ assertFalse(s.nextBoolean());
+ try {
+ s.nextBoolean();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("true1");
+ try {
+ s.nextBoolean();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ try {
+ s = new Scanner("");
+ s.nextBoolean();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // test socket inputStream
+ os.write("true false".getBytes());
+ serverSocket.close();
+
+ s = new Scanner(client);
+ assertTrue(s.nextBoolean());
+ assertFalse(s.nextBoolean());
+
+ // ues '*' as delimiter
+ s = new Scanner("true**false").useDelimiter("\\*");
+ assertTrue(s.nextBoolean());
+ try {
+ s.nextBoolean();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("false( )").useDelimiter("\\( \\)");
+ assertFalse(s.nextBoolean());
+
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextInt(int)
+ */
+ public void test_nextIntI() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextInt(10));
+ assertEquals(456, s.nextInt(10));
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertEquals(38, s.nextInt(5));
+ try {
+ s.nextInt(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt(10));
+ assertEquals(23456, s.nextInt(10));
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt(10));
+ assertEquals(23456, s.nextInt(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextInt(10));
+ try {
+ s.nextInt(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertEquals(162, s.nextInt(10));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt(10));
+ assertEquals(23456, s.nextInt(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertEquals(3456, s.nextInt(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextInt(10));
+
+ s = new Scanner("E3456");
+ assertEquals(930902, s.nextInt(16));
+ // The following test case fails on RI, because RI does not support
+ // letter as leading digit
+ s = new Scanner("E3,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(930902, s.nextInt(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("-123 123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("-123 -123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("-123 123-");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextInt(10));
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+
+ // If the parameter radix is illegal, the following test cases fail on
+ // RI
+ try {
+ s.nextInt(Character.MIN_RADIX - 1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ s.nextInt(Character.MAX_RADIX + 1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextInt()
+ */
+ public void test_nextInt() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextInt());
+ assertEquals(456, s.nextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertEquals(38, s.nextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt());
+ assertEquals(23456, s.nextInt());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt());
+ assertEquals(23456, s.nextInt());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextInt());
+ s.useRadix(5);
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertEquals(162, s.nextInt());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextInt());
+ assertEquals(23456, s.nextInt());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertEquals(3456, s.nextInt());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextInt());
+
+ s = new Scanner("E3456");
+ s.useRadix(16);
+ assertEquals(930902, s.nextInt());
+
+ // The following test case fails on RI, because RI does not support
+ // letter as leading digit
+ s = new Scanner("E3,456");
+ s.useLocale(Locale.ENGLISH);
+ s.useRadix(16);
+ assertEquals(930902, s.nextInt());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("-123 123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("-123 -123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("-123 123-");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextByte(int)
+ */
+ public void test_nextByteI() throws IOException {
+ s = new Scanner("123 126");
+ assertEquals(123, s.nextByte(10));
+ assertEquals(126, s.nextByte(10));
+ try {
+ s.nextByte(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 126");
+ assertEquals(38, s.nextByte(5));
+ try {
+ s.nextByte(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("1234");
+ try {
+ s.nextByte(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 12\u0666");
+ assertEquals(102, s.nextByte(10));
+ try {
+ s.nextByte(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertEquals(126, s.nextByte(10));
+
+ s = new Scanner("012");
+ assertEquals(12, s.nextByte(10));
+
+ s = new Scanner("E");
+ assertEquals(14, s.nextByte(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("100");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(100, s.nextByte(10));
+
+ s = new Scanner("1\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(100, s.nextByte(10));
+
+ s = new Scanner("1\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(100, s.nextByte(10));
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextByte(10));
+
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextByte(10));
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextByte()
+ */
+ public void test_nextByte() throws IOException {
+ s = new Scanner("123 126");
+ assertEquals(123, s.nextByte());
+ assertEquals(126, s.nextByte());
+ try {
+ s.nextByte();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 126");
+ s.useRadix(5);
+ assertEquals(38, s.nextByte());
+ try {
+ s.nextByte();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("1234");
+ try {
+ s.nextByte();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 12\u0666");
+ assertEquals(102, s.nextByte());
+ s.useRadix(5);
+ try {
+ s.nextByte();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertEquals(126, s.nextByte());
+
+ s = new Scanner("012");
+ assertEquals(12, s.nextByte());
+
+ s = new Scanner("E");
+ s.useRadix(16);
+ assertEquals(14, s.nextByte());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("100");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(100, s.nextByte());
+
+ s = new Scanner("1\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(100, s.nextByte());
+
+ s = new Scanner("1\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(100, s.nextByte());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextByte());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextByte());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextFloat()
+ */
+ public void test_nextFloat() throws IOException {
+ s = new Scanner("123 45\u0666. 123.4 .123 ");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals((float)123.0, s.nextFloat());
+ assertEquals((float)456.0, s.nextFloat());
+ assertEquals((float)123.4, s.nextFloat());
+ assertEquals((float)0.123, s.nextFloat());
+ try {
+ s.nextFloat();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals((float)123.4, s.nextFloat());
+ assertEquals((float)-456.7, s.nextFloat());
+ assertEquals((float)123456.789, s.nextFloat());
+ try {
+ s.nextFloat();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // Scientific notation
+ s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals((float)1.234E12, s.nextFloat());
+ assertEquals((float)-4.567E14, s.nextFloat());
+ assertEquals((float)1.23456789E-5, s.nextFloat());
+
+ s = new Scanner("NaN Infinity -Infinity");
+ assertEquals(Float.NaN, s.nextFloat());
+ assertEquals(Float.POSITIVE_INFINITY, s.nextFloat());
+ assertEquals(Float.NEGATIVE_INFINITY, s.nextFloat());
+
+ String str=String.valueOf(Float.MAX_VALUE*2);
+ s=new Scanner(str);
+ assertEquals(Float.POSITIVE_INFINITY,s.nextFloat());
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals((float)23456.0, s.nextFloat());
+ s.useLocale(Locale.GERMANY);
+ assertEquals((float)23.456, s.nextFloat());
+
+ s = new Scanner("23.456 23.456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals((float)23.456, s.nextFloat());
+ s.useLocale(Locale.GERMANY);
+ assertEquals((float)23456.0, s.nextFloat());
+
+ s = new Scanner("23,456.7 23.456,7");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals((float)23456.7, s.nextFloat());
+ s.useLocale(Locale.GERMANY);
+ assertEquals((float)23456.7, s.nextFloat());
+
+ s = new Scanner("-123.4 123.4- -123.4-");
+ s.useLocale(new Locale("ar", "AE"));
+ // FIXME
+// assertEquals((float)-123.4, s.nextFloat());
+// //The following test case fails on RI
+// assertEquals((float)-123.4, s.nextFloat());
+ try {
+ s.nextFloat();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("123- -123");
+ s.useLocale(new Locale("mk", "MK"));
+ try {
+ s.nextFloat();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ assertEquals((float)-123.0, s.nextFloat());
+
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextBigInteger(int)
+ */
+ public void test_nextBigIntegerI() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(new BigInteger("123"), s.nextBigInteger(10));
+ assertEquals(new BigInteger("456"), s.nextBigInteger(10));
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertEquals(new BigInteger("38"), s.nextBigInteger(5));
+ try {
+ s.nextBigInteger(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(new BigInteger("102"), s.nextBigInteger(10));
+ try {
+ s.nextBigInteger(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertEquals(new BigInteger("162"), s.nextBigInteger(10));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertEquals(new BigInteger("3456"), s.nextBigInteger(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigInteger("3456"), s.nextBigInteger(10));
+
+ s = new Scanner("E34");
+ assertEquals(new BigInteger("3636"), s.nextBigInteger(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(new BigInteger("-123"), s.nextBigInteger(10));
+
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(new BigInteger("-123"), s.nextBigInteger(10));
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextBigInteger()
+ */
+ public void test_nextBigInteger() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(new BigInteger("123"), s.nextBigInteger());
+ assertEquals(new BigInteger("456"), s.nextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertEquals(new BigInteger("38"), s.nextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(new BigInteger("102"), s.nextBigInteger());
+ s.useRadix(5);
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertEquals(new BigInteger("162"), s.nextBigInteger());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertEquals(new BigInteger("3456"), s.nextBigInteger());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigInteger("3456"), s.nextBigInteger());
+
+ s = new Scanner("E34");
+ s.useRadix(16);
+ assertEquals(new BigInteger("3636"), s.nextBigInteger());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(new BigInteger("12300"), s.nextBigInteger());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(new BigInteger("12300"), s.nextBigInteger());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(new BigInteger("12300"), s.nextBigInteger());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(new BigInteger("-123"), s.nextBigInteger());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(new BigInteger("-123"), s.nextBigInteger());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextShort(int)
+ */
+ public void test_nextShortI() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextShort(10));
+ assertEquals(456, s.nextShort(10));
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertEquals(38, s.nextShort(5));
+ try {
+ s.nextShort(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789");
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextShort(10));
+ assertEquals(23456, s.nextShort(10));
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextShort(10));
+ assertEquals(23456, s.nextShort(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextShort(10));
+ try {
+ s.nextShort(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertEquals(162, s.nextShort(10));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextShort(10));
+ assertEquals(23456, s.nextShort(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertEquals(3456, s.nextShort(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextShort(10));
+
+ s = new Scanner("E34");
+ assertEquals(3636, s.nextShort(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextShort(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextShort(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextShort(10));
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextShort(10));
+
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextShort(10));
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextShort()
+ */
+ public void test_nextShort() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextShort());
+ assertEquals(456, s.nextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertEquals(38, s.nextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789");
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextShort());
+ assertEquals(23456, s.nextShort());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextShort());
+ assertEquals(23456, s.nextShort());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextShort());
+ s.useRadix(5);
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertEquals(162, s.nextShort());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextShort());
+ assertEquals(23456, s.nextShort());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertEquals(3456, s.nextShort());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextShort());
+
+ s = new Scanner("E34");
+ s.useRadix(16);
+ assertEquals(3636, s.nextShort());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextShort());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextShort());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextShort());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextShort());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextShort());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextLong(int)
+ */
+ public void test_nextLongI() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextLong(10));
+ assertEquals(456, s.nextLong(10));
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertEquals(38, s.nextLong(5));
+ try {
+ s.nextLong(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextLong(10));
+ assertEquals(23456, s.nextLong(10));
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextLong(10));
+ assertEquals(23456, s.nextLong(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextLong(10));
+ try {
+ s.nextLong(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertEquals(162, s.nextLong(10));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextLong(10));
+ assertEquals(23456, s.nextLong(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertEquals(3456, s.nextLong(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextLong(10));
+
+ s = new Scanner("E34");
+ assertEquals(3636, s.nextLong(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextLong(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextLong(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextLong(10));
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextLong(10));
+
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextLong(10));
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextLong()
+ */
+ public void test_nextLong() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextLong());
+ assertEquals(456, s.nextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertEquals(38, s.nextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextLong());
+ assertEquals(23456, s.nextLong());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextLong());
+ assertEquals(23456, s.nextLong());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextLong());
+ s.useRadix(5);
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertEquals(162, s.nextLong());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertEquals(23456, s.nextLong());
+ assertEquals(23456, s.nextLong());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertEquals(3456, s.nextLong());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextLong());
+
+ s = new Scanner("E34");
+ s.useRadix(16);
+ assertEquals(3636, s.nextLong());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextLong());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextLong());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertEquals(12300, s.nextLong());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextLong());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertEquals(-123, s.nextLong());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNext()
+ */
+ public void test_hasNext() throws IOException {
+ s = new Scanner("1##2").useDelimiter("\\#");
+ assertTrue(s.hasNext());
+ assertEquals("1", s.next());
+ assertEquals("", s.next());
+ assertEquals("2", s.next());
+ assertFalse(s.hasNext());
+ s.close();
+ try {
+ s.hasNext();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("1( )2( )").useDelimiter("\\( \\)");
+ assertTrue(s.hasNext());
+ assertTrue(s.hasNext());
+ assertEquals("1", s.next());
+ assertEquals("2", s.next());
+
+ s = new Scanner("1 2 ").useDelimiter("( )");
+ assertEquals("1", s.next());
+ assertEquals("2", s.next());
+ assertTrue(s.hasNext());
+ assertEquals("", s.next());
+
+ s = new Scanner("1\n2 ");
+ assertEquals("1", s.next());
+ assertTrue(s.hasNext());
+ assertEquals("2", s.next());
+ assertFalse(s.hasNext());
+ // test boundary case
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("1'\n'2 ");
+ assertEquals("1'", s.next());
+ assertTrue(s.hasNext());
+ assertEquals("'2", s.next());
+ assertFalse(s.hasNext());
+ // test boundary case
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner(" ");
+ assertFalse(s.hasNext());
+
+ // test socket inputStream
+
+ os.write("1 2".getBytes());
+ serverSocket.close();
+
+ s = new Scanner(client);
+ assertEquals("1", s.next());
+ assertTrue(s.hasNext());
+ assertEquals("2", s.next());
+ assertFalse(s.hasNext());
+ try {
+ s.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNext(Pattern)
+ */
+ public void test_hasNextLPattern() throws IOException {
+ Pattern pattern;
+ s = new Scanner("aab@2@abb@").useDelimiter("\\@");
+ pattern = Pattern.compile("a*b");
+ assertTrue(s.hasNext(pattern));
+ assertEquals("aab", s.next(pattern));
+ assertFalse(s.hasNext(pattern));
+ try {
+ s.next(pattern);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("word ? ");
+ pattern = Pattern.compile("\\w+");
+ assertTrue(s.hasNext(pattern));
+ assertEquals("word", s.next(pattern));
+ assertFalse(s.hasNext(pattern));
+ try {
+ s.next(pattern);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("word1 WorD2 ");
+ pattern = Pattern.compile("\\w+");
+ assertTrue(s.hasNext(pattern));
+ assertEquals("word1", s.next(pattern));
+ assertTrue(s.hasNext(pattern));
+ assertEquals("WorD2", s.next(pattern));
+ assertFalse(s.hasNext(pattern));
+ try {
+ s.next(pattern);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("word1 WorD2 ");
+ pattern = Pattern.compile("\\w+");
+ try {
+ s.hasNext((Pattern) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ s.close();
+ try {
+ s.hasNext(pattern);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ // test socket inputStream
+ os.write("aab b".getBytes());
+ serverSocket.close();
+
+ s = new Scanner(client);
+ pattern = Pattern.compile("a+b");
+ assertTrue(s.hasNext(pattern));
+ assertEquals("aab", s.next(pattern));
+ assertFalse(s.hasNext(pattern));
+ try {
+ s.next(pattern);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNext(String)
+ */
+ public void test_hasNextLString() throws IOException {
+ s = new Scanner("aab@2@abb@").useDelimiter("\\@");
+ try {
+ s.hasNext((String)null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ s = new Scanner("aab*b*").useDelimiter("\\*");
+ assertTrue(s.hasNext("a+b"));
+ assertEquals("aab", s.next("a+b"));
+ assertFalse(s.hasNext("a+b"));
+ try {
+ s.next("a+b");
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.close();
+ try {
+ s.hasNext("a+b");
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("WORD ? ");
+ assertTrue(s.hasNext("\\w+"));
+ assertEquals("WORD", s.next("\\w+"));
+ assertFalse(s.hasNext("\\w+"));
+ try {
+ s.next("\\w+");
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("word1 word2 ");
+ assertEquals("word1", s.next("\\w+"));
+ assertEquals("word2", s.next("\\w+"));
+ // test boundary case
+ try {
+ s.next("\\w+");
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // test socket inputStream
+
+ os.write("aab 2".getBytes());
+ serverSocket.close();
+
+ s = new Scanner(client);
+ assertTrue(s.hasNext("a*b"));
+ assertEquals("aab", s.next("a*b"));
+ assertFalse(s.hasNext("a*b"));
+ try {
+ s.next("a*b");
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextBoolean()
+ */
+ public void test_hasNextBoolean() throws IOException {
+
+ s = new Scanner("TRue");
+ assertTrue(s.hasNextBoolean());
+ assertTrue(s.nextBoolean());
+
+ s = new Scanner("tRue false");
+ assertTrue(s.hasNextBoolean());
+ assertTrue(s.nextBoolean());
+ assertTrue(s.hasNextBoolean());
+ assertFalse(s.nextBoolean());
+
+ s = new Scanner("");
+ assertFalse(s.hasNextBoolean());
+
+ // test socket inputStream
+
+ os.write("true false ".getBytes());
+ serverSocket.close();
+
+ s = new Scanner(client);
+ assertTrue(s.hasNextBoolean());
+ assertTrue(s.nextBoolean());
+
+ // ues '*' as delimiter
+ s = new Scanner("true**false").useDelimiter("\\*");
+ assertTrue(s.hasNextBoolean());
+ assertTrue(s.nextBoolean());
+ assertFalse(s.hasNextBoolean());
+ try {
+ s.nextBoolean();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("false( )").useDelimiter("\\( \\)");
+ assertTrue(s.hasNextBoolean());
+ assertFalse(s.nextBoolean());
+ assertFalse(s.hasNextBoolean());
+
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextByte(int)
+ */
+ public void test_hasNextByteI() throws IOException {
+ s = new Scanner("123 126");
+ assertTrue(s.hasNextByte(10));
+ assertEquals(123, s.nextByte(10));
+ assertTrue(s.hasNextByte(10));
+ assertEquals(126, s.nextByte(10));
+ assertFalse(s.hasNextByte(10));
+ try {
+ s.nextByte(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 126");
+ assertTrue(s.hasNextByte(5));
+ assertEquals(38, s.nextByte(5));
+ assertFalse(s.hasNextByte(5));
+ try {
+ s.nextByte(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("1234");
+ assertFalse(s.hasNextByte(10));
+ try {
+ s.nextByte(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 12\u0666");
+ assertTrue(s.hasNextByte(10));
+ assertEquals(102, s.nextByte(10));
+ assertFalse(s.hasNextByte(5));
+ try {
+ s.nextByte(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertTrue(s.hasNextByte(10));
+ assertEquals(126, s.nextByte(10));
+
+ s = new Scanner("012");
+ assertTrue(s.hasNextByte(10));
+ assertEquals(12, s.nextByte(10));
+
+ s = new Scanner("E");
+ assertTrue(s.hasNextByte(16));
+ assertEquals(14, s.nextByte(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("100");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextByte(10));
+ assertEquals(100, s.nextByte(10));
+
+ s = new Scanner("1\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextByte(10));
+ assertEquals(100, s.nextByte(10));
+
+ s = new Scanner("1\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextByte(10));
+ assertEquals(100, s.nextByte(10));
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextByte(10));
+ assertEquals(-123, s.nextByte(10));
+
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextByte(10));
+ assertEquals(-123, s.nextByte(10));
+ }
+
+ public void test_hasNextByteI_cache() throws IOException{
+ //regression for HARMONY-2063
+ s = new Scanner("123 45");
+ assertTrue(s.hasNextByte(8));
+ assertEquals(83, s.nextByte());
+ assertEquals(45, s.nextByte());
+
+ s = new Scanner("123 45");
+ assertTrue(s.hasNextByte(10));
+ assertTrue(s.hasNextByte(8));
+ assertEquals(83, s.nextByte());
+ assertEquals(45, s.nextByte());
+
+ s = new Scanner("-123 -45");
+ assertTrue(s.hasNextByte(8));
+ assertEquals(-123, s.nextInt());
+ assertEquals(-45, s.nextByte());
+
+ s = new Scanner("123 45");
+ assertTrue(s.hasNextByte());
+ s.close();
+ try {
+ s.nextByte();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ public void test_hasNextByte() throws IOException {
+ s = new Scanner("123 126");
+ assertTrue(s.hasNextByte());
+ assertEquals(123, s.nextByte());
+ assertTrue(s.hasNextByte());
+ assertEquals(126, s.nextByte());
+ assertFalse(s.hasNextByte());
+ try {
+ s.nextByte();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 126");
+ s.useRadix(5);
+ assertTrue(s.hasNextByte());
+ assertEquals(38, s.nextByte());
+ assertFalse(s.hasNextByte());
+ try {
+ s.nextByte();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("1234");
+ assertFalse(s.hasNextByte());
+ try {
+ s.nextByte();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 12\u0666");
+ assertTrue(s.hasNextByte());
+ assertEquals(102, s.nextByte());
+ s.useRadix(5);
+ assertFalse(s.hasNextByte());
+ try {
+ s.nextByte();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertTrue(s.hasNextByte());
+ assertEquals(126, s.nextByte());
+
+ s = new Scanner("012");
+ assertEquals(12, s.nextByte());
+
+ s = new Scanner("E");
+ s.useRadix(16);
+ assertTrue(s.hasNextByte());
+ assertEquals(14, s.nextByte());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("100");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextByte());
+ assertEquals(100, s.nextByte());
+
+ s = new Scanner("1\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextByte());
+ assertEquals(100, s.nextByte());
+
+ s = new Scanner("1\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextByte());
+ assertEquals(100, s.nextByte());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextByte());
+ assertEquals(-123, s.nextByte());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextByte());
+ assertEquals(-123, s.nextByte());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextBigInteger(int)
+ */
+ public void test_hasNextBigIntegerI() throws IOException {
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("123"), s.nextBigInteger(10));
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("456"), s.nextBigInteger(10));
+ assertFalse(s.hasNextBigInteger(10));
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextBigInteger(5));
+ assertEquals(new BigInteger("38"), s.nextBigInteger(5));
+ assertFalse(s.hasNextBigInteger(5));
+ try {
+ s.nextBigInteger(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextBigInteger(10));
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextBigInteger(10));
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("102"), s.nextBigInteger(10));
+ assertFalse(s.hasNextBigInteger(5));
+ try {
+ s.nextBigInteger(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("162"), s.nextBigInteger(10));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextBigInteger(10));
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("23456"), s.nextBigInteger(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextBigInteger(10));
+ try {
+ s.nextBigInteger(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("3456"), s.nextBigInteger(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("3456"), s.nextBigInteger(10));
+
+ s = new Scanner("E34");
+ assertTrue(s.hasNextBigInteger(16));
+ assertEquals(new BigInteger("3636"), s.nextBigInteger(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("12300"), s.nextBigInteger(10));
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("-123"), s.nextBigInteger(10));
+
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("-123"), s.nextBigInteger(10));
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextBigInteger(int)
+ */
+ public void test_hasNextBigIntegerI_cache() throws IOException {
+ //regression for HARMONY-2063
+ s = new Scanner("123 123456789123456789");
+ assertTrue(s.hasNextBigInteger(16));
+ assertEquals(new BigInteger("291"), s.nextBigInteger());
+ assertEquals(new BigInteger("123456789123456789"), s.nextBigInteger());
+
+ s = new Scanner("123456789123456789 456");
+ assertTrue(s.hasNextBigInteger(16));
+ assertTrue(s.hasNextBigInteger(10));
+ assertEquals(new BigInteger("123456789123456789"), s.nextBigInteger());
+ assertEquals(new BigInteger("456"), s.nextBigInteger());
+
+ s = new Scanner("-123 -123456789123456789");
+ assertTrue(s.hasNextBigInteger(8));
+ assertEquals(-123, s.nextShort());
+ assertEquals(new BigInteger("-123456789123456789"), s.nextBigInteger());
+
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextBigInteger());
+ s.close();
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextBigInteger()
+ */
+ public void test_hasNextBigInteger() throws IOException {
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("123"), s.nextBigInteger());
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("456"), s.nextBigInteger());
+ assertFalse(s.hasNextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("38"), s.nextBigInteger());
+ assertFalse(s.hasNextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(new BigInteger("102"), s.nextBigInteger());
+ s.useRadix(5);
+ assertFalse(s.hasNextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("162"), s.nextBigInteger());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("23456"), s.nextBigInteger());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextBigInteger());
+ try {
+ s.nextBigInteger();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("3456"), s.nextBigInteger());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("3456"), s.nextBigInteger());
+
+ s = new Scanner("E34");
+ s.useRadix(16);
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("3636"), s.nextBigInteger());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("12300"), s.nextBigInteger());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("12300"), s.nextBigInteger());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("12300"), s.nextBigInteger());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("-123"), s.nextBigInteger());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextBigInteger());
+ assertEquals(new BigInteger("-123"), s.nextBigInteger());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextInt(int)
+ */
+ public void test_hasNextIntI() throws IOException {
+ s = new Scanner("123 456");
+ assertEquals(123, s.nextInt(10));
+ assertTrue(s.hasNextInt(10));
+ assertEquals(456, s.nextInt(10));
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextInt(5));
+ assertEquals(38, s.nextInt(5));
+ assertFalse(s.hasNextInt(5));
+ try {
+ s.nextInt(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ assertFalse(s.hasNextInt(10));
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextInt(10));
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextInt(10));
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextInt(10));
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextInt(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06662");
+ assertTrue(s.hasNextInt(10));
+ assertFalse(s.hasNextInt(5));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextInt(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextInt(10));
+ assertEquals(3456, s.nextInt(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextInt(10));
+ assertEquals(3456, s.nextInt(10));
+
+ s = new Scanner("E3456");
+ assertTrue(s.hasNextInt(16));
+ assertEquals(930902, s.nextInt(16));
+ // The following test case fails on RI, because RI does not support
+ // letter as leading digit
+ s = new Scanner("E3,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextInt(16));
+ assertEquals(930902, s.nextInt(16));
+
+ // If parameter radix is illegal, the following test case fails on RI
+ try {
+ s.hasNextInt(Character.MIN_RADIX - 1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt(10));
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt(10));
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt(10));
+ assertEquals(12300, s.nextInt(10));
+
+ s = new Scanner("-123 123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextInt(10));
+ assertEquals(-123, s.nextInt(10));
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("-123 -123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertEquals(-123, s.nextInt(10));
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("-123 123-");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextInt(10));
+ assertEquals(-123, s.nextInt(10));
+ assertFalse(s.hasNextInt(10));
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextInt(int)
+ */
+ public void test_hasNextIntI_cache() throws IOException {
+ //regression for HARMONY-2063
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextInt(16));
+ assertEquals(291, s.nextInt(10));
+ assertEquals(456, s.nextInt());
+
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextInt(16));
+ assertTrue(s.hasNextInt(8));
+ assertEquals(83, s.nextInt());
+ assertEquals(456, s.nextInt());
+
+ s = new Scanner("-123 -456 -789");
+ assertTrue(s.hasNextInt(8));
+ assertEquals(-123, s.nextShort());
+ assertEquals(-456, s.nextInt());
+ assertTrue(s.hasNextShort(16));
+ assertEquals(-789, s.nextInt());
+
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextInt());
+ s.close();
+ try {
+ s.nextInt();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextInt()
+ */
+ public void test_hasNextInt() throws IOException {
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextInt());
+ assertEquals(123, s.nextInt());
+ assertEquals(456, s.nextInt());
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertTrue(s.hasNextInt());
+ assertEquals(38, s.nextInt());
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ assertFalse(s.hasNextInt());
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextInt());
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextInt());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextInt());
+ s.useLocale(new Locale("it", "CH"));
+ assertTrue(s.hasNextInt());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06662");
+ s.useRadix(5);
+ assertFalse(s.hasNextInt());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextInt());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextInt());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextInt());
+ assertEquals(3456, s.nextInt());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(3456, s.nextInt());
+
+ s = new Scanner("E3456");
+ s.useRadix(16);
+ assertTrue(s.hasNextInt());
+ assertEquals(930902, s.nextInt());
+
+ // The following test case fails on RI, because RI does not support
+ // letter as leading digit
+ s = new Scanner("E3,456");
+ s.useLocale(Locale.ENGLISH);
+ s.useRadix(16);
+ assertTrue(s.hasNextInt());
+ assertEquals(930902, s.nextInt());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt());
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt());
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextInt());
+ assertEquals(12300, s.nextInt());
+
+ s = new Scanner("-123 123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextInt());
+ assertEquals(-123, s.nextInt());
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("-123 -123-");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextInt());
+ assertEquals(-123, s.nextInt());
+ assertFalse(s.hasNextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("-123 123-");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextInt());
+ assertEquals(-123, s.nextInt());
+ try {
+ s.nextInt();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextFloat()
+ */
+ public void test_hasNextFloat() throws IOException {
+ s = new Scanner("123 45\u0666. 123.4 .123 ");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)123.0, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)456.0, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)123.4, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)0.123, s.nextFloat());
+ assertFalse(s.hasNextFloat());
+ try {
+ s.nextFloat();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)123.4, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)-456.7, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)123456.789, s.nextFloat());
+ assertFalse(s.hasNextFloat());
+ try {
+ s.nextFloat();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // Scientific notation
+ s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)1.234E12, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)-4.567E14, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)1.23456789E-5, s.nextFloat());
+
+ s = new Scanner("NaN Infinity -Infinity");
+ assertTrue(s.hasNextFloat());
+ assertEquals(Float.NaN, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals(Float.POSITIVE_INFINITY, s.nextFloat());
+ assertTrue(s.hasNextFloat());
+ assertEquals(Float.NEGATIVE_INFINITY, s.nextFloat());
+
+ String str=String.valueOf(Float.MAX_VALUE*2);
+ s=new Scanner(str);
+ assertTrue(s.hasNextFloat());
+ assertEquals(Float.POSITIVE_INFINITY,s.nextFloat());
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)23456.0, s.nextFloat());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)23.456, s.nextFloat());
+
+ s = new Scanner("23.456 23.456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)23.456, s.nextFloat());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)23456.0, s.nextFloat());
+
+ s = new Scanner("23,456.7 23.456,7");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)23456.7, s.nextFloat());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)23456.7, s.nextFloat());
+
+ //FIXME
+// s = new Scanner("-123.4 123.4- -123.4-");
+// s.useLocale(new Locale("ar", "AE"));
+// assertTrue(s.hasNextFloat());
+// assertEquals((float)-123.4, s.nextFloat());
+// //The following test case fails on RI
+// assertTrue(s.hasNextFloat());
+// assertEquals((float)-123.4, s.nextFloat());
+// try {
+// s.nextFloat();
+// fail();
+// } catch (InputMismatchException expected) {
+// }
+
+ s = new Scanner("123- -123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertFalse(s.hasNextFloat());
+ try {
+ s.nextFloat();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ // Skip the un-recognizable token 123-.
+ assertEquals("123-", s.next());
+ assertTrue(s.hasNextFloat());
+ assertEquals((float)-123.0, s.nextFloat());
+
+ s = new Scanner("+123.4 -456.7");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextFloat());
+ s.close();
+ try{
+ s.nextFloat();
+ fail();
+ }catch(IllegalStateException expected) {
+ }
+
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextShort(int)
+ */
+ public void test_hasNextShortI() throws IOException {
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextShort(10));
+ assertEquals(123, s.nextShort(10));
+ assertTrue(s.hasNextShort(10));
+ assertEquals(456, s.nextShort(10));
+ assertFalse(s.hasNextShort(10));
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextShort(5));
+ assertEquals(38, s.nextShort(5));
+ assertFalse(s.hasNextShort(5));
+ try {
+ s.nextShort(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789");
+ assertFalse(s.hasNextShort(10));
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextShort(10));
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextShort(10));
+ assertEquals(23456, s.nextInt(10));
+ assertTrue(s.hasNextShort(10));
+ assertEquals(23456, s.nextInt(10));
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextShort(10));
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextShort(10));
+ assertEquals(23456, s.nextShort(10));
+ assertTrue(s.hasNextShort(10));
+ assertEquals(23456, s.nextShort(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertTrue(s.hasNextShort(10));
+ assertEquals(102, s.nextShort(10));
+ assertFalse(s.hasNextShort(5));
+ try {
+ s.nextShort(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertTrue(s.hasNextShort(10));
+ assertEquals(162, s.nextShort(10));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextShort(10));
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextShort(10));
+ assertEquals(23456, s.nextShort(10));
+ assertTrue(s.hasNextShort(10));
+ assertEquals(23456, s.nextShort(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextShort(10));
+ try {
+ s.nextShort(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextShort(10));
+ assertEquals(3456, s.nextShort(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextShort(10));
+ assertEquals(3456, s.nextShort(10));
+
+ s = new Scanner("E34");
+ assertTrue(s.hasNextShort(16));
+ assertEquals(3636, s.nextShort(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextShort(10));
+ assertEquals(12300, s.nextShort(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextShort(10));
+ assertEquals(12300, s.nextShort(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextShort(10));
+ assertEquals(12300, s.nextShort(10));
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextShort(10));
+ assertEquals(-123, s.nextShort(10));
+
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextShort(10));
+ assertEquals(-123, s.nextShort(10));
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextShort()
+ */
+ public void test_hasNextShort() throws IOException {
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextShort());
+ assertEquals(123, s.nextShort());
+ assertTrue(s.hasNextShort());
+ assertEquals(456, s.nextShort());
+ assertFalse(s.hasNextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertTrue(s.hasNextShort());
+ assertEquals(38, s.nextShort());
+ assertFalse(s.hasNextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789");
+ assertFalse(s.hasNextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextShort());
+ assertEquals(23456, s.nextShort());
+ assertTrue(s.hasNextShort());
+ assertEquals(23456, s.nextShort());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextShort());
+ assertEquals(23456, s.nextShort());
+ assertTrue(s.hasNextShort());
+ assertEquals(23456, s.nextShort());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextShort());
+ s.useRadix(5);
+ assertFalse(s.hasNextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertTrue(s.hasNextShort());
+ assertEquals(162, s.nextShort());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextShort());
+ assertEquals(23456, s.nextShort());
+ assertTrue(s.hasNextShort());
+ assertEquals(23456, s.nextShort());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextShort());
+ try {
+ s.nextShort();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextShort());
+ assertEquals(3456, s.nextShort());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextShort());
+ assertEquals(3456, s.nextShort());
+
+ s = new Scanner("E34");
+ s.useRadix(16);
+ assertTrue(s.hasNextShort());
+ assertEquals(3636, s.nextShort());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextShort());
+ assertEquals(12300, s.nextShort());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextShort());
+ assertEquals(12300, s.nextShort());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextShort());
+ assertEquals(12300, s.nextShort());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextShort());
+ assertEquals(-123, s.nextShort());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextShort());
+ assertEquals(-123, s.nextShort());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextShort(int)
+ */
+ public void test_hasNextShortI_cache() throws IOException {
+ //regression for HARMONY-2063
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextShort(16));
+ assertEquals(291, s.nextShort());
+ assertEquals(456, s.nextShort());
+
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextShort(16));
+ assertTrue(s.hasNextShort(8));
+ assertEquals(83, s.nextShort());
+ assertEquals(456, s.nextShort());
+
+ s = new Scanner("-123 -456 -789");
+ assertTrue(s.hasNextShort(8));
+ assertEquals(-123, s.nextInt());
+ assertEquals(-456, s.nextShort());
+ assertTrue(s.hasNextInt(16));
+ assertEquals(-789, s.nextShort());
+
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextShort());
+ s.close();
+ try {
+ s.nextShort();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextLong(int)
+ */
+ public void test_hasNextLongI() throws IOException {
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextLong(10));
+ assertEquals(123, s.nextLong(10));
+ assertTrue(s.hasNextLong(10));
+ assertEquals(456, s.nextLong(10));
+ assertFalse(s.hasNextLong(10));
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextLong(5));
+ assertEquals(38, s.nextLong(5));
+ assertFalse(s.hasNextLong(5));
+ try {
+ s.nextLong(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ assertFalse(s.hasNextLong(10));
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextShort(10));
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextLong(10));
+ assertEquals(23456, s.nextLong(10));
+ assertTrue(s.hasNextLong(10));
+ assertEquals(23456, s.nextLong(10));
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextLong(10));
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextLong(10));
+ assertEquals(23456, s.nextLong(10));
+ assertTrue(s.hasNextLong(10));
+ assertEquals(23456, s.nextLong(10));
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertTrue(s.hasNextLong(10));
+ assertEquals(102, s.nextLong(10));
+ assertFalse(s.hasNextLong(5));
+ try {
+ s.nextLong(5);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ assertTrue(s.hasNextLong(10));
+ assertEquals(162, s.nextLong(10));
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextLong(10));
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextLong(10));
+ assertEquals(23456, s.nextLong(10));
+ assertTrue(s.hasNextLong(10));
+ assertEquals(23456, s.nextLong(10));
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextLong(10));
+ try {
+ s.nextLong(10);
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextLong(10));
+ assertEquals(3456, s.nextLong(10));
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextLong(10));
+ assertEquals(3456, s.nextLong(10));
+
+ s = new Scanner("E34");
+ assertTrue(s.hasNextLong(16));
+ assertEquals(3636, s.nextLong(16));
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextLong(10));
+ assertEquals(12300, s.nextLong(10));
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextLong(10));
+ assertEquals(12300, s.nextLong(10));
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextLong(10));
+ assertEquals(12300, s.nextLong(10));
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextLong(10));
+ assertEquals(-123, s.nextLong(10));
+
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextLong(10));
+ assertEquals(-123, s.nextLong(10));
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextLong(int)
+ */
+ public void test_hasNextLongI_cache() throws IOException {
+ //regression for HARMONY-2063
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextLong(16));
+ assertEquals(291, s.nextLong());
+ assertEquals(456, s.nextLong());
+
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextLong(16));
+ assertTrue(s.hasNextLong(8));
+ assertEquals(83, s.nextLong());
+ assertEquals(456, s.nextLong());
+
+ s = new Scanner("-123 -456 -789");
+ assertTrue(s.hasNextLong(8));
+ assertEquals(-123, s.nextInt());
+ assertEquals(-456, s.nextLong());
+ assertTrue(s.hasNextShort(16));
+ assertEquals(-789, s.nextLong());
+
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextLong());
+ s.close();
+ try {
+ s.nextLong();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextLong()
+ */
+ public void test_hasNextLong() throws IOException {
+ s = new Scanner("123 456");
+ assertTrue(s.hasNextLong());
+ assertEquals(123, s.nextLong());
+ assertTrue(s.hasNextLong());
+ assertEquals(456, s.nextLong());
+ assertFalse(s.hasNextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ // If the radix is different from 10
+ s = new Scanner("123 456");
+ s.useRadix(5);
+ assertTrue(s.hasNextLong());
+ assertEquals(38, s.nextLong());
+ assertFalse(s.hasNextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // If the number is out of range
+ s = new Scanner("123456789123456789123456789123456789");
+ assertFalse(s.hasNextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.ENGLISH);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextLong());
+ assertEquals(23456, s.nextLong());
+ assertTrue(s.hasNextLong());
+ assertEquals(23456, s.nextLong());
+
+ /*
+ * ''' is used in many locales as group separator.
+ */
+ s = new Scanner("23'456 23'456");
+ s.useLocale(Locale.GERMANY);
+ assertFalse(s.hasNextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(new Locale("it", "CH"));
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextLong());
+ assertEquals(23456, s.nextLong());
+ assertTrue(s.hasNextLong());
+ assertEquals(23456, s.nextLong());
+
+ /*
+ * The input string has Arabic-Indic digits.
+ */
+ s = new Scanner("1\u06602 1\u06662");
+ assertEquals(102, s.nextLong());
+ s.useRadix(5);
+ assertFalse(s.hasNextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useRadix(10);
+ assertTrue(s.hasNextLong());
+ assertEquals(162, s.nextLong());
+
+ /*
+ * '.' is used in many locales as group separator. The input string
+ * has Arabic-Indic digits .
+ */
+ s = new Scanner("23.45\u0666 23.456");
+ s.useLocale(Locale.CHINESE);
+ assertFalse(s.hasNextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+ s.useLocale(Locale.GERMANY);
+ // If exception is thrown out, input will not be advanced.
+ assertTrue(s.hasNextLong());
+ assertEquals(23456, s.nextLong());
+ assertTrue(s.hasNextLong());
+ assertEquals(23456, s.nextLong());
+
+ // The input string starts with zero
+ s = new Scanner("03,456");
+ s.useLocale(Locale.ENGLISH);
+ assertFalse(s.hasNextLong());
+ try {
+ s.nextLong();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ s = new Scanner("03456");
+ assertTrue(s.hasNextLong());
+ assertEquals(3456, s.nextLong());
+
+ s = new Scanner("\u06603,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextLong());
+ assertEquals(3456, s.nextLong());
+
+ s = new Scanner("E34");
+ s.useRadix(16);
+ assertTrue(s.hasNextLong());
+ assertEquals(3636, s.nextLong());
+
+ /*
+ * There are 3 types of zero digit in all locales, '0' '\u0966' '\u0e50'
+ * respectively, but they are not differentiated.
+ */
+ s = new Scanner("12300");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextLong());
+ assertEquals(12300, s.nextLong());
+
+ s = new Scanner("123\u0966\u0966");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextLong());
+ assertEquals(12300, s.nextLong());
+
+ s = new Scanner("123\u0e50\u0e50");
+ s.useLocale(Locale.CHINESE);
+ assertTrue(s.hasNextLong());
+ assertEquals(12300, s.nextLong());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("ar", "AE"));
+ assertTrue(s.hasNextLong());
+ assertEquals(-123, s.nextLong());
+
+ s = new Scanner("-123");
+ s.useLocale(new Locale("mk", "MK"));
+ assertTrue(s.hasNextLong());
+ assertEquals(-123, s.nextLong());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextDouble()
+ */
+ public void test_hasNextDouble() throws IOException {
+ s = new Scanner("123 45\u0666. 123.4 .123 ");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextDouble());
+ assertEquals(123.0, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(456.0, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(123.4, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(0.123, s.nextDouble());
+ assertFalse(s.hasNextDouble());
+ try {
+ s.nextDouble();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextDouble());
+ assertEquals(123.4, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(-456.7, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(123456.789, s.nextDouble());
+ assertFalse(s.hasNextDouble());
+ try {
+ s.nextDouble();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // Scientific notation
+ s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextDouble());
+ assertEquals(1.234E12, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(-4.567E14, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(1.23456789E-5, s.nextDouble());
+
+ s = new Scanner("NaN Infinity -Infinity");
+ assertTrue(s.hasNextDouble());
+ assertEquals(Double.NaN, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(Double.POSITIVE_INFINITY, s.nextDouble());
+ assertTrue(s.hasNextDouble());
+ assertEquals(Double.NEGATIVE_INFINITY, s.nextDouble());
+
+ String str=String.valueOf(Double.MAX_VALUE*2);
+ s=new Scanner(str);
+ assertTrue(s.hasNextDouble());
+ assertEquals(Double.POSITIVE_INFINITY,s.nextDouble());
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextDouble());
+ assertEquals(23456.0, s.nextDouble());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextDouble());
+ assertEquals(23.456, s.nextDouble());
+
+ s = new Scanner("23.456 23.456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextDouble());
+ assertEquals(23.456, s.nextDouble());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextDouble());
+ assertEquals(23456.0, s.nextDouble());
+
+ s = new Scanner("23,456.7 23.456,7");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextDouble());
+ assertEquals(23456.7, s.nextDouble());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextDouble());
+ assertEquals(23456.7, s.nextDouble());
+
+ s = new Scanner("-123.4");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextDouble());
+ assertEquals(-123.4, s.nextDouble());
+
+ s = new Scanner("+123.4 -456.7");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextDouble());
+ s.close();
+ try{
+ s.nextDouble();
+ fail();
+ }catch(IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#hasNextBigDecimal()
+ */
+ public void test_hasNextBigDecimal() throws IOException {
+ s = new Scanner("123 45\u0666. 123.4 .123 ");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("123"), s.nextBigDecimal());
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("456"), s.nextBigDecimal());
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("123.4"), s.nextBigDecimal());
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("0.123"), s.nextBigDecimal());
+ assertFalse(s.hasNextBigDecimal());
+ try {
+ s.nextBigDecimal();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("123.4"), s.nextBigDecimal());
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("-456.7"), s.nextBigDecimal());
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("123456.789"), s.nextBigDecimal());
+ assertFalse(s.hasNextBigDecimal());
+ try {
+ s.nextBigDecimal();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // Scientific notation
+ s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("1.234E12"), s.nextBigDecimal());
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("-4.567E14"), s.nextBigDecimal());
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("1.23456789E-5"), s.nextBigDecimal());
+
+ s = new Scanner("NaN");
+ assertFalse(s.hasNextBigDecimal());
+ try {
+ s.nextBigDecimal();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("23456"), s.nextBigDecimal());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("23.456"), s.nextBigDecimal());
+
+ s = new Scanner("23.456 23.456");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("23.456"), s.nextBigDecimal());
+ s.useLocale(Locale.GERMANY);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("23456"), s.nextBigDecimal());
+
+ s = new Scanner("23,456.7");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("23456.7"), s.nextBigDecimal());
+
+ s = new Scanner("-123.4");
+ s.useLocale(Locale.ENGLISH);
+ assertTrue(s.hasNextBigDecimal());
+ assertEquals(new BigDecimal("-123.4"), s.nextBigDecimal());
+ }
+
+ private static class MockStringReader extends StringReader {
+
+ public MockStringReader(String param) {
+ super(param);
+ }
+
+ public int read(CharBuffer target) throws IOException {
+ target.append('t');
+ target.append('e');
+ target.append('s');
+ target.append('t');
+ throw new IOException();
+ }
+
+ }
+
+ private static class MockStringReader2Read extends StringReader {
+ int timesRead = 0;
+
+ public MockStringReader2Read(String param) {
+ super(param);
+ }
+
+ public int read(CharBuffer target) throws IOException {
+ if (timesRead == 0) {
+ target.append('1');
+ target.append('2');
+ target.append('3');
+ timesRead++;
+ return 3;
+ } else if (timesRead == 1) {
+ target.append('t');
+ timesRead++;
+ return 1;
+ } else {
+ throw new IOException();
+ }
+ }
+
+ }
+
+ // https://code.google.com/p/android/issues/detail?id=40555
+ public void test_40555() throws Exception {
+ MockStringReader2Read reader = new MockStringReader2Read("MockStringReader");
+ s = new Scanner(reader);
+ // We should get a match straight away.
+ String result = s.findWithinHorizon("1", 0);
+ assertEquals("1", result);
+ // The stream should not be consumed as there's already a match after the first read.
+ assertEquals(1, reader.timesRead);
+ }
+
+ /**
+ * @tests java.util.Scanner#findWithinHorizon(Pattern, int)
+ */
+ public void test_findWithinHorizon_LPatternI() {
+
+ // This method searches through the input up to the specified search
+ // horizon(exclusive).
+ s = new Scanner("123test");
+ String result = s.findWithinHorizon(Pattern.compile("\\p{Lower}"), 5);
+ assertEquals("t", result);
+ MatchResult mresult = s.match();
+ assertEquals(3, mresult.start());
+ assertEquals(4, mresult.end());
+
+ s = new Scanner("12345test1234test next");
+ /*
+ * If the pattern is found the scanner advances past the input that
+ * matched and returns the string that matched the pattern.
+ */
+ result = s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), 2);
+ assertEquals("12", result);
+ mresult = s.match();
+ assertEquals(0, mresult.start());
+ assertEquals(2, mresult.end());
+ // Position is now pointing at the bar. "12|345test1234test next"
+
+ result = s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), 6);
+ assertEquals("345", result);
+
+ mresult = s.match();
+ assertEquals(2, mresult.start());
+ assertEquals(5, mresult.end());
+ // Position is now pointing at the bar. "12345|test1234test next"
+
+ // If no such pattern is detected then the null is returned and the
+ // scanner's position remains unchanged.
+ result = s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), 3);
+ assertNull(result);
+
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ assertEquals("345", mresult.group());
+ assertEquals(2, mresult.start());
+ assertEquals(5, mresult.end());
+ // Position is now still pointing at the bar. "12345|test1234test next"
+
+ // If horizon is 0, then the horizon is ignored and this method
+ // continues to search through the input looking for the specified
+ // pattern without bound.
+ result = s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), 0);
+ mresult = s.match();
+ assertEquals(9, mresult.start());
+ assertEquals(13, mresult.end());
+ // Position is now pointing at the bar. "12345test1234|test next"
+
+ assertEquals("test", s.next());
+ mresult = s.match();
+ assertEquals(13, mresult.start());
+ assertEquals(17, mresult.end());
+
+ assertEquals("next", s.next());
+ mresult = s.match();
+ assertEquals(18, mresult.start());
+ assertEquals(22, mresult.end());
+
+ try {
+ s.findWithinHorizon((Pattern) null, -1);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ s.findWithinHorizon(Pattern.compile("\\p{Digit}+"), -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ s.close();
+ try {
+ s.findWithinHorizon((Pattern) null, -1);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("test");
+ result = s.findWithinHorizon(Pattern.compile("\\w+"), 10);
+ assertEquals("test", result);
+
+ s = new Scanner("aa\n\rb");
+ result = s.findWithinHorizon(Pattern.compile("a"), 5);
+ assertEquals("a", result);
+ mresult = s.match();
+ assertEquals(0, mresult.start());
+ assertEquals(1, mresult.end());
+
+ result = s.findWithinHorizon(Pattern.compile("^(a)$", Pattern.MULTILINE), 5);
+ assertNull(result);
+
+ try {
+ mresult = s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("");
+ result = s.findWithinHorizon(Pattern.compile("^"), 0);
+ assertEquals("", result);
+ MatchResult matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(0, matchResult.end());
+
+ result = s.findWithinHorizon(Pattern.compile("$"), 0);
+ assertEquals("", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(0, matchResult.end());
+
+ s = new Scanner("1 fish 2 fish red fish blue fish");
+ result = s.findWithinHorizon(Pattern
+ .compile("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)"), 10);
+ assertNull(result);
+
+ try {
+ mresult = s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ assertEquals(0, mresult.groupCount());
+
+ result = s.findWithinHorizon(Pattern
+ .compile("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)"), 100);
+ assertEquals("1 fish 2 fish red fish blue", result);
+ mresult = s.match();
+ assertEquals(4, mresult.groupCount());
+ assertEquals("1", mresult.group(1));
+ assertEquals("2", mresult.group(2));
+ assertEquals("red", mresult.group(3));
+ assertEquals("blue", mresult.group(4));
+
+ s = new Scanner("test");
+ s.close();
+ try {
+ s.findWithinHorizon(Pattern.compile("test"), 1);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("word1 WorD2 ");
+ s.close();
+ try {
+ s.findWithinHorizon(Pattern.compile("\\d+"), 10);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("word1 WorD2 wOrd3 ");
+ Pattern pattern = Pattern.compile("\\d+");
+ assertEquals("1", s.findWithinHorizon(pattern, 10));
+ assertEquals("WorD2", s.next());
+ assertEquals("3", s.findWithinHorizon(pattern, 15));
+
+ // Regression test
+ s = new Scanner(new MockStringReader("MockStringReader"));
+ pattern = Pattern.compile("test");
+ result = s.findWithinHorizon(pattern, 10);
+ assertEquals("test", result);
+
+ // Test the situation when input length is longer than buffer size.
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < 1026; i++) {
+ stringBuilder.append('a');
+ }
+ s = new Scanner(stringBuilder.toString());
+ pattern = Pattern.compile("\\p{Lower}+");
+ result = s.findWithinHorizon(pattern, 1026);
+ assertEquals(stringBuilder.toString().length(), result.length());
+ assertEquals(stringBuilder.toString(), result);
+
+ // Test the situation when input length is longer than buffer size and
+ // set horizon to buffer size.
+ stringBuilder = new StringBuilder();
+ for (int i = 0; i < 1026; i++) {
+ stringBuilder.append('a');
+ }
+ s = new Scanner(stringBuilder.toString());
+ pattern = Pattern.compile("\\p{Lower}+");
+ result = s.findWithinHorizon(pattern, 1022);
+ assertEquals(1022, result.length());
+ assertEquals(stringBuilder.subSequence(0, 1022), result);
+
+ // Test the situation, under which pattern is clipped by buffer.
+ stringBuilder = new StringBuilder();
+ for (int i = 0; i < 1022; i++) {
+ stringBuilder.append(' ');
+ }
+ stringBuilder.append("bbc");
+ assertEquals(1025, stringBuilder.length());
+ s = new Scanner(stringBuilder.toString());
+ pattern = Pattern.compile("bbc");
+ result = s.findWithinHorizon(pattern, 1025);
+ assertEquals(3, result.length());
+ assertEquals(stringBuilder.subSequence(1022, 1025), result);
+
+ stringBuilder = new StringBuilder();
+ for (int i = 0; i < 1026; i++) {
+ stringBuilder.append('a');
+ }
+ s = new Scanner(stringBuilder.toString());
+ pattern = Pattern.compile("\\p{Lower}+");
+ result = s.findWithinHorizon(pattern, 0);
+ assertEquals(stringBuilder.toString(), result);
+
+ stringBuilder = new StringBuilder();
+ for (int i = 0; i < 10240; i++) {
+ stringBuilder.append('-');
+ }
+ stringBuilder.replace(0, 2, "aa");
+ s = new Scanner(stringBuilder.toString());
+ result = s.findWithinHorizon(Pattern.compile("aa"), 0);
+ assertEquals("aa", result);
+
+ s = new Scanner("aaaa");
+ result = s.findWithinHorizon(Pattern.compile("a*"), 0);
+ assertEquals("aaaa", result);
+ }
+
+ /**
+ * @tests java.util.Scanner#findInLine(Pattern)
+ */
+ public void test_findInLine_LPattern() {
+
+ Scanner s = new Scanner("");
+ try {
+ s.findInLine((Pattern) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ String result = s.findInLine(Pattern.compile("^"));
+ assertEquals("", result);
+ MatchResult matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(0, matchResult.end());
+
+ result = s.findInLine(Pattern.compile("$"));
+ assertEquals("", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(0, matchResult.end());
+
+ /*
+ * When we use the operation of findInLine(Pattern), the match region
+ * should not span the line separator.
+ */
+ s = new Scanner("aa\nb.b");
+ result = s.findInLine(Pattern.compile("a\nb*"));
+ assertNull(result);
+
+ s = new Scanner("aa\nbb.b");
+ result = s.findInLine(Pattern.compile("\\."));
+ assertNull(result);
+
+ s = new Scanner("abcd1234test\n");
+ result = s.findInLine(Pattern.compile("\\p{Lower}+"));
+ assertEquals("abcd", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(4, matchResult.end());
+
+ result = s.findInLine(Pattern.compile("\\p{Digit}{5}"));
+ assertNull(result);
+ try {
+ matchResult = s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ assertEquals(0, matchResult.start());
+ assertEquals(4, matchResult.end());
+
+ result = s.findInLine(Pattern.compile("\\p{Lower}+"));
+ assertEquals("test", result);
+ matchResult = s.match();
+ assertEquals(8, matchResult.start());
+ assertEquals(12, matchResult.end());
+
+ char[] chars = new char[2048];
+ Arrays.fill(chars, 'a');
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(chars);
+ stringBuilder.append("1234");
+ s = new Scanner(stringBuilder.toString());
+ result = s.findInLine(Pattern.compile("\\p{Digit}+"));
+ assertEquals("1234", result);
+ matchResult = s.match();
+ assertEquals(2048, matchResult.start());
+ assertEquals(2052, matchResult.end());
+
+ s = new Scanner("test");
+ s.close();
+ try {
+ s.findInLine((Pattern) null);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("test1234\n1234 test");
+ result = s.findInLine(Pattern.compile("test"));
+ assertEquals("test", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(4, matchResult.end());
+
+ int number = s.nextInt();
+ assertEquals(1234, number);
+ matchResult = s.match();
+ assertEquals(4, matchResult.start());
+ assertEquals(8, matchResult.end());
+
+ result = s.next();
+ assertEquals("1234", result);
+ matchResult = s.match();
+ assertEquals(9, matchResult.start());
+ assertEquals(13, matchResult.end());
+
+ result = s.findInLine(Pattern.compile("test"));
+ assertEquals("test", result);
+ matchResult = s.match();
+ assertEquals(14, matchResult.start());
+ assertEquals(18, matchResult.end());
+
+ s = new Scanner("test\u0085\ntest");
+ result = s.findInLine("est");
+ assertEquals("est", result);
+ result = s.findInLine("est");
+ assertEquals("est", result);
+
+ s = new Scanner("test\ntest");
+ result = s.findInLine("est");
+ assertEquals("est", result);
+ result = s.findInLine("est");
+ assertEquals("est", result);
+
+ s = new Scanner("test\n123\ntest");
+ result = s.findInLine("est");
+ assertEquals("est", result);
+ result = s.findInLine("est");
+ // RI fails. It is a RI's bug.
+ assertNull(result);
+
+ s = new Scanner( " *\n");
+ result = s.findInLine(Pattern.compile( "^\\s*(?:\\*(?=[^/]))"));
+ assertEquals(" *", result);
+ }
+
+ public void test_findInLine_LString_NPEs() {
+ s = new Scanner("test");
+ try {
+ s.findInLine((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ s.close();
+ try {
+ s.findInLine((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ s.findInLine("test");
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ public void test_findInLine_LString() {
+ Scanner s = new Scanner("");
+ String result = s.findInLine("^");
+ assertEquals("", result);
+ MatchResult matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(0, matchResult.end());
+
+ result = s.findInLine("$");
+ assertEquals("", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(0, matchResult.end());
+
+ // When we use the operation of findInLine(Pattern), the match region
+ // should not span the line separator.
+ s = new Scanner("aa\nb.b");
+ result = s.findInLine("a\nb*");
+ assertNull(result);
+
+ s = new Scanner("aa\nbb.b");
+ result = s.findInLine("\\.");
+ assertNull(result);
+
+ s = new Scanner("abcd1234test\n");
+ result = s.findInLine("\\p{Lower}+");
+ assertEquals("abcd", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(4, matchResult.end());
+
+ result = s.findInLine("\\p{Digit}{5}");
+ assertNull(result);
+ try {
+ matchResult = s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ assertEquals(0, matchResult.start());
+ assertEquals(4, matchResult.end());
+
+ result = s.findInLine("\\p{Lower}+");
+ assertEquals("test", result);
+ matchResult = s.match();
+ assertEquals(8, matchResult.start());
+ assertEquals(12, matchResult.end());
+
+ char[] chars = new char[2048];
+ Arrays.fill(chars, 'a');
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(chars);
+ stringBuilder.append("1234");
+ s = new Scanner(stringBuilder.toString());
+ result = s.findInLine("\\p{Digit}+");
+ assertEquals("1234", result);
+ matchResult = s.match();
+ assertEquals(2048, matchResult.start());
+ assertEquals(2052, matchResult.end());
+
+ s = new Scanner("test1234\n1234 test");
+ result = s.findInLine("test");
+ assertEquals("test", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(4, matchResult.end());
+
+ int number = s.nextInt();
+ assertEquals(1234, number);
+ matchResult = s.match();
+ assertEquals(4, matchResult.start());
+ assertEquals(8, matchResult.end());
+
+ result = s.next();
+ assertEquals("1234", result);
+ matchResult = s.match();
+ assertEquals(9, matchResult.start());
+ assertEquals(13, matchResult.end());
+
+ result = s.findInLine("test");
+ assertEquals("test", result);
+ matchResult = s.match();
+ assertEquals(14, matchResult.start());
+ assertEquals(18, matchResult.end());
+
+ s = new Scanner("test\u0085\ntest");
+ result = s.findInLine("est");
+ assertEquals("est", result);
+ result = s.findInLine("est");
+ assertEquals("est", result);
+
+ s = new Scanner("test\ntest");
+ result = s.findInLine("est");
+ assertEquals("est", result);
+ result = s.findInLine("est");
+ assertEquals("est", result);
+
+ s = new Scanner("test\n123\ntest");
+ result = s.findInLine("est");
+ assertEquals("est", result);
+ result = s.findInLine("est");
+ }
+
+ /**
+ * @tests java.util.Scanner#skip(Pattern)
+ */
+ public void test_skip_LPattern() {
+ s = new Scanner("test");
+ try {
+ s.skip((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // If pattern does not match, NoSuchElementException will be thrown out.
+ s = new Scanner("1234");
+ try {
+ s.skip(Pattern.compile("\\p{Lower}"));
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ // Then, no matchResult will be thrown out.
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s.skip(Pattern.compile("\\p{Digit}"));
+ MatchResult matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+
+ s.skip(Pattern.compile("\\p{Digit}+"));
+ matchResult = s.match();
+ assertEquals(1, matchResult.start());
+ assertEquals(4, matchResult.end());
+
+ s.close();
+ try {
+ s.skip(Pattern.compile("test"));
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ MockStringReader2Read reader = new MockStringReader2Read("test");
+ s = new Scanner(reader);
+ try {
+ s.skip(Pattern.compile("\\p{Digit}{4}"));
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ s.skip(Pattern.compile("\\p{Digit}{3}\\p{Lower}"));
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(4, matchResult.end());
+
+ s.close();
+ try {
+ s.skip((Pattern) null);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ char [] chars = new char[1024];
+ Arrays.fill(chars, 'a');
+ stringBuilder.append(chars);
+ stringBuilder.append('3');
+ s = new Scanner(stringBuilder.toString());
+ s.skip(Pattern.compile("\\p{Lower}+\\p{Digit}"));
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1025, matchResult.end());
+
+ // Large amount of input may be cached
+ chars = new char[102400];
+ Arrays.fill(chars, 'a');
+ stringBuilder = new StringBuilder();
+ stringBuilder.append(chars);
+ s = new Scanner(stringBuilder.toString());
+ s.skip(Pattern.compile(".*"));
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(102400, matchResult.end());
+
+ // skip something without risking a NoSuchElementException
+ s.skip(Pattern.compile("[ \t]*"));
+ matchResult = s.match();
+ assertEquals(102400, matchResult.start());
+ assertEquals(102400, matchResult.end());
+ }
+
+ /**
+ * @tests java.util.Scanner#skip(String)
+ */
+ public void test_skip_LString() {
+ s = new Scanner("test");
+ try {
+ s.skip((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextDouble()
+ */
+ public void test_nextDouble() throws IOException {
+ s = new Scanner("123 45\u0666. 123.4 .123 ");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(123.0, s.nextDouble());
+ assertEquals(456.0, s.nextDouble());
+ assertEquals(123.4, s.nextDouble());
+ assertEquals(0.123, s.nextDouble());
+ try {
+ s.nextDouble();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(123.4, s.nextDouble());
+ assertEquals(-456.7, s.nextDouble());
+ assertEquals(123456.789, s.nextDouble());
+ try {
+ s.nextDouble();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // Scientific notation
+ s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(1.234E12, s.nextDouble());
+ assertEquals(-4.567E14, s.nextDouble());
+ assertEquals(1.23456789E-5, s.nextDouble());
+
+ s = new Scanner("NaN Infinity -Infinity");
+ assertEquals(Double.NaN, s.nextDouble());
+ assertEquals(Double.POSITIVE_INFINITY, s.nextDouble());
+ assertEquals(Double.NEGATIVE_INFINITY, s.nextDouble());
+
+ //The following test case fails on RI
+ s=new Scanner("\u221e");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(Double.POSITIVE_INFINITY, s.nextDouble());
+
+ String str=String.valueOf(Double.MAX_VALUE*2);
+ s=new Scanner(str);
+ assertEquals(Double.POSITIVE_INFINITY,s.nextDouble());
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(23456.0, s.nextDouble());
+ s.useLocale(Locale.GERMANY);
+ assertEquals(23.456, s.nextDouble());
+
+ s = new Scanner("23.456 23.456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(23.456, s.nextDouble());
+ s.useLocale(Locale.GERMANY);
+ assertEquals(23456.0, s.nextDouble());
+
+ s = new Scanner("23,456.7 23.456,7");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(23456.7, s.nextDouble());
+ s.useLocale(Locale.GERMANY);
+ assertEquals(23456.7, s.nextDouble());
+
+ s = new Scanner("-123.4");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(-123.4, s.nextDouble());
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Scanner#nextBigDecimal()
+ */
+ public void test_nextBigDecimal() throws IOException {
+ s = new Scanner("123 45\u0666. 123.4 .123 ");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigDecimal("123"), s.nextBigDecimal());
+ assertEquals(new BigDecimal("456"), s.nextBigDecimal());
+ assertEquals(new BigDecimal("123.4"), s.nextBigDecimal());
+ assertEquals(new BigDecimal("0.123"), s.nextBigDecimal());
+ try {
+ s.nextBigDecimal();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+
+ s = new Scanner("+123.4 -456.7 123,456.789 0.1\u06623,4");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigDecimal("123.4"), s.nextBigDecimal());
+ assertEquals(new BigDecimal("-456.7"), s.nextBigDecimal());
+ assertEquals(new BigDecimal("123456.789"), s.nextBigDecimal());
+ try {
+ s.nextBigDecimal();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ // Scientific notation
+ s = new Scanner("+123.4E10 -456.7e+12 123,456.789E-10");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigDecimal("1.234E12"), s.nextBigDecimal());
+ assertEquals(new BigDecimal("-4.567E14"), s.nextBigDecimal());
+ assertEquals(new BigDecimal("1.23456789E-5"), s.nextBigDecimal());
+
+ s = new Scanner("NaN");
+ try {
+ s.nextBigDecimal();
+ fail();
+ } catch (InputMismatchException expected) {
+ }
+
+ /*
+ * Different locale can only recognize corresponding locale sensitive
+ * string. ',' is used in many locales as group separator.
+ */
+ s = new Scanner("23,456 23,456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigDecimal("23456"), s.nextBigDecimal());
+ s.useLocale(Locale.GERMANY);
+ assertEquals(new BigDecimal("23.456"), s.nextBigDecimal());
+
+ s = new Scanner("23.456 23.456");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigDecimal("23.456"), s.nextBigDecimal());
+ s.useLocale(Locale.GERMANY);
+ assertEquals(new BigDecimal("23456"), s.nextBigDecimal());
+
+ s = new Scanner("23,456.7");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigDecimal("23456.7"), s.nextBigDecimal());
+
+ s = new Scanner("-123.4");
+ s.useLocale(Locale.ENGLISH);
+ assertEquals(new BigDecimal("-123.4"), s.nextBigDecimal());
+ }
+
+ /**
+ * @tests java.util.Scanner#toString()
+ */
+ public void test_toString() {
+ s = new Scanner("test");
+ assertNotNull(s.toString());
+ }
+
+ /**
+ * @tests java.util.Scanner#nextLine()
+ */
+ public void test_nextLine() {
+ s = new Scanner("");
+ s.close();
+ try {
+ s.nextLine();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("test\r\ntest");
+ String result = s.nextLine();
+ assertEquals("test", result);
+ MatchResult matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(6, matchResult.end());
+
+ s = new Scanner("\u0085");
+ result = s.nextLine();
+ assertEquals("", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+
+ s = new Scanner("\u2028");
+ result = s.nextLine();
+ assertEquals("", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+
+ s = new Scanner("\u2029");
+ result = s.nextLine();
+ assertEquals("", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+
+ s = new Scanner("");
+ try {
+ result = s.nextLine();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ try {
+ s.match();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("Ttest");
+ result = s.nextLine();
+ assertEquals("Ttest", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(5, matchResult.end());
+
+ s = new Scanner("\r\n");
+ result = s.nextLine();
+ assertEquals("", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(2, matchResult.end());
+
+ char[] chars = new char[1024];
+ Arrays.fill(chars, 'a');
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(chars);
+ chars = new char[] { '+', '-' };
+ stringBuilder.append(chars);
+ stringBuilder.append("\u2028");
+ s = new Scanner(stringBuilder.toString());
+ result = s.nextLine();
+
+ assertEquals(stringBuilder.toString().substring(0, 1026), result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1027, matchResult.end());
+
+ chars = new char[1023];
+ Arrays.fill(chars, 'a');
+ stringBuilder = new StringBuilder();
+ stringBuilder.append(chars);
+ stringBuilder.append("\r\n");
+ s = new Scanner(stringBuilder.toString());
+ result = s.nextLine();
+
+ assertEquals(stringBuilder.toString().substring(0, 1023), result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1025, matchResult.end());
+
+ s = new Scanner(" ");
+ result = s.nextLine();
+ assertEquals(" ", result);
+
+ s = new Scanner("test\n\n\n");
+ result = s.nextLine();
+ assertEquals("test", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(5, matchResult.end());
+ result = s.nextLine();
+ matchResult = s.match();
+ assertEquals(5, matchResult.start());
+ assertEquals(6, matchResult.end());
+
+ s = new Scanner("\n\n\n");
+ result = s.nextLine();
+ assertEquals("", result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+ result = s.nextLine();
+ matchResult = s.match();
+ assertEquals(1, matchResult.start());
+ assertEquals(2, matchResult.end());
+
+ s = new Scanner("123 test\n ");
+ int value = s.nextInt();
+ assertEquals(123, value);
+
+ result = s.nextLine();
+ assertEquals(" test", result);
+
+ s = new Scanner("test\n ");
+ result = s.nextLine();
+ assertEquals("test", result);
+
+ // Regression test for Harmony-4774
+ class CountReadable implements Readable {
+ int counter = 0;
+ public int read(CharBuffer charBuffer) throws IOException {
+ counter++;
+ charBuffer.append("hello\n");
+ return 6;
+ }
+ }
+ CountReadable cr = new CountReadable();
+ s = new Scanner(cr);
+ result = s.nextLine();
+ // We expect read() to be called only once, otherwise we see the problem
+ // when reading from System.in described in Harmony-4774
+ assertEquals(1, cr.counter);
+ assertEquals("hello", result);
+ }
+
+ /**
+ * @tests java.util.Scanner#hasNextLine()
+ */
+ public void test_hasNextLine() {
+ s = new Scanner("");
+ s.close();
+ try {
+ s.hasNextLine();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ s = new Scanner("test\r\ntest");
+ boolean result = s.hasNextLine();
+ assertTrue(result);
+ MatchResult matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(6, matchResult.end());
+
+ s = new Scanner("\u0085");
+ result = s.hasNextLine();
+ assertTrue(result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+
+ s = new Scanner("\u2028");
+ result = s.hasNextLine();
+ assertTrue(result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+
+ s = new Scanner("\u2029");
+ result = s.hasNextLine();
+ assertTrue(result);
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+
+ s = new Scanner("test\n");
+ assertTrue(s.hasNextLine());
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(5, matchResult.end());
+
+ char[] chars = new char[2048];
+ Arrays.fill(chars, 'a');
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(chars);
+ s = new Scanner(stringBuilder.toString());
+ result = s.hasNextLine();
+ assertTrue(result);
+
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(2048, matchResult.end());
+
+ s = new Scanner("\n\n\n");
+ assertTrue(s.hasNextLine());
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+
+ // The scanner will not advance any input.
+ assertTrue(s.hasNextLine());
+ matchResult = s.match();
+ assertEquals(0, matchResult.start());
+ assertEquals(1, matchResult.end());
+ }
+
+ public void test_hasNextLine_sequence() throws IOException {
+ final PipedInputStream pis = new PipedInputStream();
+ final PipedOutputStream pos = new PipedOutputStream();
+ final Scanner scanner = new Scanner(pis);
+ pis.connect(pos);
+ final List<String> result = new ArrayList<String>();
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ result.add(line);
+ }
+ }
+ });
+ thread.start();
+ for (int index = 0; index < 5; index++) {
+ String line = "line" + index + "\n";
+ pos.write(line.getBytes());
+ pos.flush();
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignored) {
+ }
+ assertEquals(index + 1, result.size());
+ }
+ pis.close();
+ pos.close();
+ try {
+ thread.join(1000);
+ } catch (InterruptedException ignored) {
+ }
+ assertFalse(scanner.hasNextLine());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ server = new ServerSocket(0);
+ address = new InetSocketAddress("127.0.0.1", server.getLocalPort());
+
+ client = SocketChannel.open();
+ client.connect(address);
+ serverSocket = server.accept();
+
+ os = serverSocket.getOutputStream();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ try {
+ serverSocket.close();
+ } catch (Exception ignored) {
+ }
+ try {
+ client.close();
+ } catch (Exception ignored) {
+ }
+ try {
+ server.close();
+ } catch (Exception ignored) {
+ }
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=57050
+ public void testPerformance() throws Exception {
+ int count = 100000;
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ BufferedWriter out = new BufferedWriter(new OutputStreamWriter(baos));
+ for (int i = 0; i < count; ++i) {
+ out.write(Integer.toString(123) + " ");
+ }
+ out.close();
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ bais.mark(-1);
+
+ Scanner s = new Scanner(new BufferedReader(new InputStreamReader(bais)));
+ for (int i = 0; i < count; ++i) {
+ if (s.nextInt() != 123) {
+ fail();
+ }
+ }
+
+ bais.reset();
+ s = new Scanner(new BufferedReader(new InputStreamReader(bais)));
+ for (int i = 0; i < count; ++i) {
+ if (s.nextFloat() != 123.0) {
+ fail();
+ }
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ServiceConfigurationErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ServiceConfigurationErrorTest.java
new file mode 100644
index 0000000..870ef1e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ServiceConfigurationErrorTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.ServiceConfigurationError;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for java.util.ServiceConfigurationError
+ *
+ * @since 1.6
+ */
+public class ServiceConfigurationErrorTest extends TestCase {
+
+ /**
+ * {@link java.util.ServiceConfigurationError#ServiceConfigurationError(String)}
+ */
+ @SuppressWarnings("nls")
+ public void test_ConstructorLjava_lang_String() {
+ ServiceConfigurationError e = new ServiceConfigurationError("fixture");
+ assertEquals("fixture", e.getMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
+ * {@link java.util.ServiceConfigurationError#ServiceConfigurationError(String, Throwable)}
+ */
+ @SuppressWarnings("nls")
+ public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+ IllegalArgumentException iae = new IllegalArgumentException(
+ "info in the IAE");
+ ServiceConfigurationError e = new ServiceConfigurationError("fixture",
+ iae);
+ assertEquals("fixture", e.getMessage());
+ assertEquals(iae, e.getCause());
+ assertEquals("info in the IAE", e.getCause().getMessage());
+ }
+
+ /**
+ * @throws Exception
+ * serialization/deserialization.
+ */
+ @SuppressWarnings("nls")
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(new ServiceConfigurationError("fixture"));
+ SerializationTest.verifySelf(new ServiceConfigurationError("fixture",
+ new IllegalArgumentException("info in the IAE")));
+ }
+
+ /**
+ * @throws Exception
+ * serialization/deserialization compatibility with RI.
+ */
+ @SuppressWarnings("nls")
+ public void testSerializationCompatibility() throws Exception {
+ ServiceConfigurationError e = new ServiceConfigurationError("fixture",
+ new IllegalArgumentException("info in the IAE"));
+ SerializationTest.verifyGolden(this, e);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleEntryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleEntryTest.java
new file mode 100644
index 0000000..3f0847f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleEntryTest.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.util.SerializationTester;
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+public class SimpleEntryTest extends TestCase {
+ public void test_SimpleEntry_Constructor_K_V() throws Exception {
+ new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ new AbstractMap.SimpleEntry(null, null);
+ }
+
+ static class NullEntry implements Entry {
+
+ public Object getKey() {
+ return null;
+ }
+
+ public Object getValue() {
+ return null;
+ }
+
+ public Object setValue(Object object) {
+ return null;
+ }
+ }
+
+ public void test_SimpleEntry_Constructor_LEntry() throws Exception {
+ Map map = new TreeMap();
+ map.put(1, "test");
+ Entry entryToPut = (Entry) map.entrySet().iterator().next();
+ Entry testEntry = new AbstractMap.SimpleEntry(entryToPut);
+ assertEquals(1, testEntry.getKey());
+ assertEquals("test", testEntry.getValue());
+ map.clear();
+
+ testEntry = new AbstractMap.SimpleEntry(new NullEntry());
+ assertNull(testEntry.getKey());
+ assertNull(testEntry.getValue());
+ try {
+ new AbstractMap.SimpleEntry(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ }
+
+ public void test_SimpleEntry_getKey() throws Exception {
+ Entry entry = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ assertEquals(1, entry.getKey());
+ entry = new AbstractMap.SimpleEntry(null, null);
+ assertNull(entry.getKey());
+ }
+
+ public void test_SimpleEntry_getValue() throws Exception {
+ Entry entry = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ assertEquals("test", entry.getValue());
+ entry = new AbstractMap.SimpleEntry(null, null);
+ assertNull(entry.getValue());
+ }
+
+ public void test_SimpleEntry_setValue() throws Exception {
+ Entry entry = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ assertEquals("test", entry.getValue());
+ entry.setValue("Another String");
+ assertEquals("Another String", entry.getValue());
+ entry = new AbstractMap.SimpleEntry(null, null);
+ assertNull(entry.getKey());
+ }
+
+ public void test_SimpleEntry_equals() throws Exception {
+ Entry entry = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ Map map = new TreeMap();
+ map.put(1, "test");
+ Entry entryToPut = (Entry) map.entrySet().iterator().next();
+ Entry testEntry = new AbstractMap.SimpleEntry(entryToPut);
+ assertEquals(entry, testEntry);
+ Entry ent = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ assertEquals(entry, ent);
+ }
+
+ public void test_SimpleEntry_hashCode() throws Exception {
+ Entry e = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ assertEquals((e.getKey() == null ? 0 : e.getKey().hashCode())
+ ^ (e.getValue() == null ? 0 : e.getValue().hashCode()), e
+ .hashCode());
+ }
+
+ public void test_SimpleEntry_toString() throws Exception {
+ Entry e = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ assertEquals(e.getKey() + "=" + e.getValue(), e.toString());
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationSelf_SimpleEntry() throws Exception {
+ Entry e = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ SerializationTest.verifySelf(e);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationCompatibility_SimpleEntry() throws Exception {
+ SimpleEntry e = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+ SerializationTester.assertCompabilityEquals(e, "serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleEntry.golden.ser");
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleImmutableEntryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleImmutableEntryTest.java
new file mode 100644
index 0000000..b83468e
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleImmutableEntryTest.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.util.SerializationTester;
+import java.lang.reflect.Array;
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+public class SimpleImmutableEntryTest extends TestCase {
+ public void test_SimpleImmutableEntry_Constructor_K_V() throws Exception {
+ new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ new AbstractMap.SimpleImmutableEntry(null, null);
+ }
+
+ static class NullEntry implements Entry {
+
+ public Object getKey() {
+ return null;
+ }
+
+ public Object getValue() {
+ return null;
+ }
+
+ public Object setValue(Object object) {
+ return null;
+ }
+ }
+
+ public void test_SimpleImmutableEntry_Constructor_LEntry() throws Exception {
+ Map map = new TreeMap();
+ map.put(1, "test");
+ Entry entryToPut = (Entry) map.entrySet().iterator().next();
+ Entry testEntry = new AbstractMap.SimpleImmutableEntry(entryToPut);
+ assertEquals(1, testEntry.getKey());
+ assertEquals("test", testEntry.getValue());
+ map.clear();
+
+ testEntry = new AbstractMap.SimpleImmutableEntry(new NullEntry());
+ assertNull(testEntry.getKey());
+ assertNull(testEntry.getValue());
+ try {
+ new AbstractMap.SimpleImmutableEntry(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ }
+
+ public void test_SimpleImmutableEntry_getKey() throws Exception {
+ Entry entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ assertEquals(1, entry.getKey());
+ entry = new AbstractMap.SimpleImmutableEntry(null, null);
+ assertNull(entry.getKey());
+ }
+
+ public void test_SimpleImmutableEntry_getValue() throws Exception {
+ Entry entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ assertEquals("test", entry.getValue());
+ entry = new AbstractMap.SimpleImmutableEntry(null, null);
+ assertNull(entry.getValue());
+ }
+
+ public void test_SimpleImmutableEntry_setValue() throws Exception {
+ Entry entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ assertEquals("test", entry.getValue());
+ try {
+ entry.setValue("Another String");
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals("test", entry.getValue());
+ try {
+ entry.setValue(null);
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void test_SimpleImmutableEntry_equals() throws Exception {
+ Entry entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ Map map = new TreeMap();
+ map.put(1, "test");
+ Entry entryToPut = (Entry) map.entrySet().iterator().next();
+ Entry testEntry = new AbstractMap.SimpleImmutableEntry(entryToPut);
+ assertEquals(entry, testEntry);
+ }
+
+ public void test_SimpleImmutableEntry_hashCode() throws Exception {
+ Entry e = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ assertEquals((e.getKey() == null ? 0 : e.getKey().hashCode())
+ ^ (e.getValue() == null ? 0 : e.getValue().hashCode()), e
+ .hashCode());
+ }
+
+ public void test_SimpleImmutableEntry_toString() throws Exception {
+ Entry e = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ assertEquals(e.getKey() + "=" + e.getValue(), e.toString());
+ Object array = Array.newInstance((byte[].class).getComponentType(), 10);
+ assertEquals(10, ((byte[]) array).length);
+ }
+
+ /**
+ * serialization/deserialization.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationSelf_SimpleImmutableEntry() throws Exception {
+ Entry e = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ SerializationTest.verifySelf(e);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ @SuppressWarnings({ "unchecked", "boxing" })
+ public void testSerializationCompatibility_SimpleImmutableEntry() throws Exception {
+ SimpleImmutableEntry e = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+ if (!(SerializationTester.readObject(e, "serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleImmutableEntry.golden.ser") instanceof SimpleImmutableEntry)) {
+ fail("should be SimpleImmutableEntry");
+ }
+ SerializationTester.assertCompabilityEquals(e, "serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleImmutableEntry.golden.ser");
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleTimeZoneTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleTimeZoneTest.java
new file mode 100644
index 0000000..0fbe7ac
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SimpleTimeZoneTest.java
@@ -0,0 +1,838 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+public class SimpleTimeZoneTest extends junit.framework.TestCase {
+
+ SimpleTimeZone st1;
+
+ SimpleTimeZone st2;
+
+ /**
+ * java.util.SimpleTimeZone#SimpleTimeZone(int, java.lang.String)
+ */
+ public void test_ConstructorILjava_lang_String() {
+ // Test for method java.util.SimpleTimeZone(int, java.lang.String)
+
+ SimpleTimeZone st = new SimpleTimeZone(1000, "TEST");
+ assertEquals("Incorrect TZ constructed", "TEST", st.getID());
+ assertTrue("Incorrect TZ constructed: " + "returned wrong offset", st
+ .getRawOffset() == 1000);
+ assertTrue("Incorrect TZ constructed" + "using daylight savings", !st
+ .useDaylightTime());
+ }
+
+ /**
+ * java.util.SimpleTimeZone#SimpleTimeZone(int, java.lang.String,
+ * int, int, int, int, int, int, int, int)
+ */
+ public void test_ConstructorILjava_lang_StringIIIIIIII() {
+ // Test for method java.util.SimpleTimeZone(int, java.lang.String, int,
+ // int, int, int, int, int, int, int)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0);
+ assertTrue("Incorrect TZ constructed", st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.NOVEMBER,
+ 13).getTime()));
+ assertTrue("Incorrect TZ constructed", !(st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
+ 13).getTime())));
+ assertEquals("Incorrect TZ constructed", "TEST", st.getID());
+ assertEquals("Incorrect TZ constructed", 1000, st.getRawOffset());
+ assertTrue("Incorrect TZ constructed", st.useDaylightTime());
+
+ try {
+ new SimpleTimeZone(1000, "TEST", 12,
+ 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 10, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 1, 10, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.DECEMBER,
+ 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -10, Calendar.SUNDAY,
+ 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#SimpleTimeZone(int, java.lang.String,
+ * int, int, int, int, int, int, int, int, int)
+ */
+ public void test_ConstructorILjava_lang_StringIIIIIIIII() {
+ // Test for method java.util.SimpleTimeZone(int, java.lang.String, int,
+ // int, int, int, int, int, int, int, int)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0, 1000 * 60 * 60);
+ assertTrue("Incorrect TZ constructed", st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.NOVEMBER,
+ 13).getTime()));
+ assertTrue("Incorrect TZ constructed", !(st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
+ 13).getTime())));
+ assertEquals("Incorrect TZ constructed", "TEST", st.getID());
+ assertEquals("Incorrect TZ constructed", 1000, st.getRawOffset());
+ assertTrue("Incorrect TZ constructed", st.useDaylightTime());
+ assertTrue("Incorrect TZ constructed",
+ st.getDSTSavings() == 1000 * 60 * 60);
+
+ try {
+ new SimpleTimeZone(1000, "TEST", 12,
+ 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0, 1000 * 60 * 60);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 10, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0, 1000 * 60 * 60);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 1, 10, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0, 1000 * 60 * 60);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.DECEMBER,
+ 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -10, Calendar.SUNDAY,
+ 0, 1000 * 60 * 60);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#SimpleTimeZone(int, java.lang.String,
+ * int, int, int, int, int, int, int, int, int, int, int)
+ */
+ public void test_ConstructorILjava_lang_StringIIIIIIIIIII() {
+ // Test for method java.util.SimpleTimeZone(int, java.lang.String, int,
+ // int, int, int, int, int, int, int, int, int, int)
+ // TODO : Implement test
+ //Regression for HARMONY-1241
+ assertNotNull(new SimpleTimeZone(
+ TimeZone.LONG,
+ "Europe/Paris",
+ SimpleTimeZone.STANDARD_TIME,
+ SimpleTimeZone.STANDARD_TIME,
+ SimpleTimeZone.UTC_TIME,
+ SimpleTimeZone.WALL_TIME,
+ SimpleTimeZone.WALL_TIME,
+ TimeZone.SHORT,
+ SimpleTimeZone.STANDARD_TIME,
+ TimeZone.LONG,
+ SimpleTimeZone.UTC_TIME,
+ SimpleTimeZone.STANDARD_TIME,
+ TimeZone.LONG));
+ //seems RI doesn't check the startTimeMode and endTimeMode at all
+ //this behavior is contradicts with spec
+ assertNotNull(new SimpleTimeZone(
+ TimeZone.LONG,
+ "Europe/Paris",
+ SimpleTimeZone.STANDARD_TIME,
+ SimpleTimeZone.STANDARD_TIME,
+ SimpleTimeZone.UTC_TIME,
+ SimpleTimeZone.WALL_TIME,
+ Integer.MAX_VALUE,
+ TimeZone.SHORT,
+ SimpleTimeZone.STANDARD_TIME,
+ TimeZone.LONG,
+ SimpleTimeZone.UTC_TIME,
+ Integer.MIN_VALUE,
+ TimeZone.LONG));
+
+ try {
+ new SimpleTimeZone(1000, "TEST", 12,
+ 1, Calendar.SUNDAY, 0, Integer.MAX_VALUE, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0, Integer.MAX_VALUE, 1000 * 60 * 60);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 10, Calendar.SUNDAY, 0, Integer.MAX_VALUE, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0, Integer.MAX_VALUE, 1000 * 60 * 60);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 1, 10, 0, Calendar.NOVEMBER, Integer.MAX_VALUE, -1, Calendar.SUNDAY,
+ 0, Integer.MAX_VALUE, 1000 * 60 * 60);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new SimpleTimeZone(1000, "TEST", Calendar.DECEMBER,
+ 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, Integer.MAX_VALUE, -10, Calendar.SUNDAY,
+ 0, Integer.MAX_VALUE, 1000 * 60 * 60);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.SimpleTimeZone.clone()
+ SimpleTimeZone st1 = new SimpleTimeZone(1000, "TEST",
+ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER,
+ -1, Calendar.SUNDAY, 0);
+ SimpleTimeZone stA = new SimpleTimeZone(1, "Gah");
+ assertTrue("Clone resulted in same reference", st1.clone() != st1);
+ assertTrue("Clone resulted in unequal object", ((SimpleTimeZone) st1
+ .clone()).equals(st1));
+ assertTrue("Clone resulted in same reference", stA.clone() != stA);
+ assertTrue("Clone resulted in unequal object", ((SimpleTimeZone) stA
+ .clone()).equals(stA));
+ }
+
+ /**
+ * java.util.SimpleTimeZone#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.SimpleTimeZone.equals(java.lang.Object)
+ TimeZone tz = TimeZone.getTimeZone("EST");
+ st1 = new SimpleTimeZone(tz.getRawOffset(), "EST");
+ st2 = new SimpleTimeZone(0, "EST");
+ assertFalse(st1.equals(st2));
+ st1.setRawOffset(st2.getRawOffset());
+ assertTrue(st1.equals(st2));
+ }
+
+ /**
+ * java.util.SimpleTimeZone#getDSTSavings()
+ */
+ public void test_getDSTSavings() {
+ // Test for method int java.util.SimpleTimeZone.getDSTSavings()
+ st1 = new SimpleTimeZone(0, "TEST");
+
+ assertEquals("Non-zero default daylight savings",
+ 0, st1.getDSTSavings());
+ st1.setStartRule(0, 1, 1, 1);
+ st1.setEndRule(11, 1, 1, 1);
+
+ assertEquals("Incorrect default daylight savings",
+ 3600000, st1.getDSTSavings());
+ st1 = new SimpleTimeZone(-5 * 3600000, "EST", Calendar.APRIL, 1,
+ -Calendar.SUNDAY, 2 * 3600000, Calendar.OCTOBER, -1,
+ Calendar.SUNDAY, 2 * 3600000, 7200000);
+ assertEquals("Incorrect daylight savings from constructor", 7200000, st1
+ .getDSTSavings());
+
+ }
+
+ /**
+ * java.util.SimpleTimeZone#getOffset(int, int, int, int, int, int)
+ */
+ public void test_getOffsetIIIIII() {
+ // Test for method int java.util.SimpleTimeZone.getOffset(int, int, int,
+ // int, int, int)
+// TimeZone st1 = TimeZone.getTimeZone("EST");
+ st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
+ assertTrue("Incorrect offset returned", st1.getOffset(
+ GregorianCalendar.AD, 1998, Calendar.NOVEMBER, 11,
+ Calendar.WEDNESDAY, 0) == -(5 * 60 * 60 * 1000));
+
+ st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
+ assertEquals("Incorrect offset returned", -(5 * 60 * 60 * 1000), st1
+ .getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 11,
+ Calendar.THURSDAY, 0));
+
+ // Regression for HARMONY-5459
+ st1 = new SimpleTimeZone(TimeZone.getDefault().getRawOffset(), TimeZone.getDefault().getID());
+ int fourHours = 4*60*60*1000;
+ st1.setRawOffset(fourHours);
+ assertEquals(fourHours, st1.getOffset(1, 2099, 01, 1, 5, 0));
+
+ try {
+ st1.getOffset(-1, 2099, 01, 1, 5, 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ st1.getOffset(1, 2099, 15, 1, 5, 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ st1.getOffset(1, 2099, 01, 100, 5, 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ st1.getOffset(1, 2099, 01, 1, 50, 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ st1.getOffset(1, 2099, 01, 1, 5, -10);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#getRawOffset()
+ */
+ public void test_getRawOffset() {
+ // Test for method int java.util.SimpleTimeZone.getRawOffset()
+ st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
+ assertTrue("Incorrect offset returned",
+ st1.getRawOffset() == -(5 * 60 * 60 * 1000));
+
+ }
+
+ /**
+ * java.util.SimpleTimeZone#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.util.SimpleTimeZone.hashCode()
+ // For lack of a better test.
+ st1 = new SimpleTimeZone(-5 * 3600000, "EST", Calendar.APRIL, 1,
+ -Calendar.SUNDAY, 2 * 3600000, Calendar.OCTOBER, -1,
+ Calendar.SUNDAY, 2 * 3600000);
+ assertTrue(TimeZone.getTimeZone("EST").hashCode() != 0);
+ assertTrue(st1.hashCode() != 0);
+ }
+
+ /**
+ * java.util.SimpleTimeZone#hasSameRules(java.util.TimeZone)
+ */
+ public void test_hasSameRulesLjava_util_TimeZone() {
+ // Test for method boolean
+ // java.util.SimpleTimeZone.hasSameRules(java.util.TimeZone)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
+ 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
+ 0);
+ SimpleTimeZone sameAsSt = new SimpleTimeZone(1000, "REST",
+ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER,
+ -1, Calendar.SUNDAY, 0);
+ SimpleTimeZone notSameAsSt = new SimpleTimeZone(1000, "PEST",
+ Calendar.NOVEMBER, 2, Calendar.SUNDAY, 0, Calendar.NOVEMBER,
+ -1, Calendar.SUNDAY, 0);
+ assertTrue("Time zones have same rules but return false", st
+ .hasSameRules(sameAsSt));
+ assertTrue("Time zones have different rules but return true", !st
+ .hasSameRules(notSameAsSt));
+ }
+
+ /**
+ * java.util.SimpleTimeZone#inDaylightTime(java.util.Date)
+ */
+ public void test_inDaylightTimeLjava_util_Date() {
+ // Test for method boolean
+ // java.util.SimpleTimeZone.inDaylightTime(java.util.Date)
+ TimeZone tz = TimeZone.getTimeZone("EST");
+ SimpleTimeZone zone = new SimpleTimeZone(tz.getRawOffset(), "EST",
+ Calendar.APRIL, 1, -Calendar.SUNDAY, 7200000, Calendar.OCTOBER, -1, Calendar.SUNDAY, 7200000, 3600000);
+ GregorianCalendar gc = new GregorianCalendar(1998, Calendar.JUNE, 11);
+
+ assertTrue("Returned incorrect daylight value1", zone.inDaylightTime(gc
+ .getTime()));
+ gc = new GregorianCalendar(1998, Calendar.NOVEMBER, 11);
+ assertTrue("Returned incorrect daylight value2", !(zone
+ .inDaylightTime(gc.getTime())));
+ gc = new GregorianCalendar(zone);
+ gc.set(1999, Calendar.APRIL, 4, 1, 59, 59);
+ assertTrue("Returned incorrect daylight value3", !(zone
+ .inDaylightTime(gc.getTime())));
+ Date date = new Date(gc.getTime().getTime() + 1000);
+ assertTrue("Returned incorrect daylight value4", zone
+ .inDaylightTime(date));
+ gc.set(1999, Calendar.OCTOBER, 31, 1, 0, 0);
+ assertTrue("Returned incorrect daylight value5", !(zone
+ .inDaylightTime(gc.getTime())));
+ date = new Date(gc.getTime().getTime() - 1000);
+ assertTrue("Returned incorrect daylight value6", zone
+ .inDaylightTime(date));
+
+ assertTrue("Returned incorrect daylight value7", !zone
+ .inDaylightTime(new Date(891752400000L + 7200000 - 1)));
+ assertTrue("Returned incorrect daylight value8", zone
+ .inDaylightTime(new Date(891752400000L + 7200000)));
+ assertTrue("Returned incorrect daylight value9", zone
+ .inDaylightTime(new Date(909288000000L + 7200000 - 1)));
+ assertTrue("Returned incorrect daylight value10", !zone
+ .inDaylightTime(new Date(909288000000L + 7200000)));
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setDSTSavings(int)
+ */
+ public void test_setDSTSavingsI() {
+ // Test for method void java.util.SimpleTimeZone.setDSTSavings(int)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
+ st.setStartRule(0, 1, 1, 1);
+ st.setEndRule(11, 1, 1, 1);
+ st.setDSTSavings(1);
+ assertEquals(1, st.getDSTSavings());
+ try {
+ st.setDSTSavings(0);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ st.setDSTSavings(-1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setEndRule(int, int, int)
+ */
+ public void test_setEndRuleIII() {
+ SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
+ st.setStartRule(Calendar.NOVEMBER, 1, 0);
+ st.setEndRule(Calendar.NOVEMBER, 20, 0);
+ assertTrue("StartRule improperly set1", st.useDaylightTime());
+ assertTrue("StartRule improperly set2", st.inDaylightTime(
+ new GregorianCalendar(1998, Calendar.NOVEMBER,
+ 13).getTime()));
+ assertTrue("StartRule improperly set3", !(st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
+ 13).getTime())));
+
+ try {
+ st.setEndRule(13, 20, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setEndRule(1, 32, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setEndRule(1, 30, 10);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setEndRule(int, int, int, int)
+ */
+ public void test_setEndRuleIIII() {
+ // Test for method void java.util.SimpleTimeZone.setEndRule(int, int,
+ // int, int)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
+ // Spec indicates that both end and start must be set or result is
+ // undefined
+ st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0);
+ st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, 0);
+ assertTrue("StartRule improperly set1", st.useDaylightTime());
+ assertTrue("StartRule improperly set2", st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.NOVEMBER,
+ 13).getTime()));
+ assertTrue("StartRule improperly set3", !(st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
+ 13).getTime())));
+
+ try {
+ st.setEndRule(12, -1, Calendar.SUNDAY, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setEndRule(Calendar.NOVEMBER, 10, Calendar.SUNDAY, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setEndRule(Calendar.NOVEMBER, -1, 8, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, -10);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setEndRule(int, int, int, int, boolean)
+ */
+ public void test_setEndRuleIIIIZ() {
+ // Test for method void java.util.SimpleTimeZone.setEndRule(int, int,
+ // int, int, boolean)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
+ // Spec indicates that both end and start must be set or result is
+ // undefined
+ st.setStartRule(Calendar.NOVEMBER, 8, Calendar.SUNDAY, 1, false);
+ st.setEndRule(Calendar.NOVEMBER, 15, Calendar.SUNDAY, 1, true);
+ assertTrue("StartRule improperly set1", st.useDaylightTime());
+ assertTrue("StartRule improperly set2", st
+ .inDaylightTime((new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 7, 12, 0).getTime())));
+ assertTrue("StartRule improperly set3", st
+ .inDaylightTime((new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 20, 12, 0).getTime())));
+ assertTrue("StartRule improperly set4", !(st
+ .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 6, 12, 0).getTime())));
+ assertTrue("StartRule improperly set5", !(st
+ .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 21, 12, 0).getTime())));
+
+ try {
+ st.setEndRule(20, 15, Calendar.SUNDAY, 1, true);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setEndRule(Calendar.NOVEMBER, 35, Calendar.SUNDAY, 1, true);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setEndRule(Calendar.NOVEMBER, 15, 12, 1, true);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setEndRule(Calendar.NOVEMBER, 15, Calendar.SUNDAY, -1, true);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setRawOffset(int)
+ */
+ public void test_setRawOffsetI() {
+ // Test for method void java.util.SimpleTimeZone.setRawOffset(int)
+
+ st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
+ int off = st1.getRawOffset();
+ st1.setRawOffset(1000);
+ boolean val = st1.getRawOffset() == 1000;
+ st1.setRawOffset(off);
+ assertTrue("Incorrect offset set", val);
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setStartRule(int, int, int)
+ */
+ public void test_setStartRuleIII() {
+ // Test for method void java.util.SimpleTimeZone.setStartRule(int, int,
+ // int)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
+ // Spec indicates that both end and start must be set or result is
+ // undefined
+ st.setStartRule(Calendar.NOVEMBER, 1, 1);
+ st.setEndRule(Calendar.DECEMBER, 1, 1);
+ assertTrue("StartRule improperly set", st.useDaylightTime());
+ assertTrue("StartRule improperly set", st
+ .inDaylightTime((new GregorianCalendar(1998, Calendar.NOVEMBER,
+ 13).getTime())));
+ assertTrue("StartRule improperly set", !(st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
+ 13).getTime())));
+
+ try {
+ st.setStartRule(13, 20, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setStartRule(1, 32, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setStartRule(1, 30, 10);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setStartRule(int, int, int, int)
+ */
+ public void test_setStartRuleIIII() {
+ // Test for method void java.util.SimpleTimeZone.setStartRule(int, int,
+ // int, int)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
+ // Spec indicates that both end and start must be set or result is
+ // undefined
+ st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0);
+ st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, 0);
+ assertTrue("StartRule improperly set1", st.useDaylightTime());
+ assertTrue("StartRule improperly set2", st
+ .inDaylightTime((new GregorianCalendar(1998, Calendar.NOVEMBER,
+ 13).getTime())));
+ assertTrue("StartRule improperly set3", !(st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
+ 13).getTime())));
+
+ try {
+ st.setStartRule(12, -1, Calendar.SUNDAY, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setStartRule(Calendar.NOVEMBER, 10, Calendar.SUNDAY, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setStartRule(Calendar.NOVEMBER, -1, 8, 0);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setStartRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, -10);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setStartRule(int, int, int, int, boolean)
+ */
+ public void test_setStartRuleIIIIZ() {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ // Test for method void java.util.SimpleTimeZone.setStartRule(int, int,
+ // int, int, boolean)
+ SimpleTimeZone st = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
+ // Spec indicates that both end and start must be set or result is
+ // undefined
+ st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 1, true);
+ st.setEndRule(Calendar.NOVEMBER, 15, Calendar.SUNDAY, 1, false);
+ assertTrue("StartRule improperly set1", st.useDaylightTime());
+ assertTrue("StartRule improperly set2", st
+ .inDaylightTime((new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 7, 12, 0).getTime())));
+ assertTrue("StartRule improperly set3", st
+ .inDaylightTime((new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 13, 12, 0).getTime())));
+ assertTrue("StartRule improperly set4", !(st
+ .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 6, 12, 0).getTime())));
+ assertTrue("StartRule improperly set5", !(st
+ .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 14, 12, 0).getTime())));
+
+ try {
+ st.setStartRule(20, 15, Calendar.SUNDAY, 1, true);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setStartRule(Calendar.NOVEMBER, 35, Calendar.SUNDAY, 1, true);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setStartRule(Calendar.NOVEMBER, 15, 12, 1, true);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ st.setStartRule(Calendar.NOVEMBER, 15, Calendar.SUNDAY, -1, true);
+ fail("IllegalArgumentException is not thrown.");
+ } catch(IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.SimpleTimeZone#setStartYear(int)
+ */
+ public void test_setStartYearI() {
+ // Test for method void java.util.SimpleTimeZone.setStartYear(int)
+ SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
+ st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0);
+ st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, 0);
+ st.setStartYear(1999);
+ assertTrue("set year improperly set1", !(st
+ .inDaylightTime(new GregorianCalendar(1999, Calendar.JULY, 12)
+ .getTime())));
+ assertTrue("set year improperly set2", !(st
+ .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
+ 13).getTime())));
+ assertTrue("set year improperly set3", (st
+ .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
+ 13).getTime())));
+ }
+
+ /**
+ * java.util.SimpleTimeZone#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.util.SimpleTimeZone.toString()
+ String string = TimeZone.getTimeZone("EST").toString();
+ assertNotNull("toString() returned null", string);
+ assertTrue("toString() is empty", string.length() != 0);
+ }
+
+ /**
+ * java.util.SimpleTimeZone#useDaylightTime()
+ */
+ public void test_useDaylightTime() {
+ // Test for method boolean java.util.SimpleTimeZone.useDaylightTime()
+ SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
+ assertTrue("useDaylightTime returned incorrect value", !st
+ .useDaylightTime());
+ // Spec indicates that both end and start must be set or result is
+ // undefined
+ st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0);
+ st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, 0);
+ assertTrue("useDaylightTime returned incorrect value", st
+ .useDaylightTime());
+ }
+
+ public void test_getOffsetJ() {
+ Calendar cal = Calendar.getInstance();
+ cal.set(1998, Calendar.NOVEMBER, 11, 0, 0);
+ st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
+
+ assertTrue("Incorrect offset returned", st1.getOffset(cal.getTimeInMillis()) ==
+ -(5 * 60 * 60 * 1000));
+
+ st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
+ cal.set(1998, Calendar.JUNE, 11, 0, 0);
+ assertEquals("Incorrect offset returned", -(5 * 60 * 60 * 1000), st1
+ .getOffset(cal.getTimeInMillis()));
+
+ // Regression for HARMONY-5459
+ st1 = new SimpleTimeZone(TimeZone.getDefault().getRawOffset(), TimeZone.getDefault().getID());
+ int fourHours = 4*60*60*1000;
+ st1.setRawOffset(fourHours);
+ cal.set(2099, 01, 1, 0, 0);
+
+ assertEquals(fourHours, st1.getOffset(cal.getTimeInMillis()));
+
+ }
+
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SortedMapTestBase.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SortedMapTestBase.java
new file mode 100644
index 0000000..f1fb1e4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/SortedMapTestBase.java
@@ -0,0 +1,369 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import junit.framework.TestCase;
+
+public abstract class SortedMapTestBase extends TestCase {
+
+ final int N = 1000;
+ final int TRIES = 100;
+
+ SortedMap<Integer, Integer> map;
+ SortedMap<Integer, Integer> ref;
+
+ Random rnd;
+
+ protected void setUp() throws Exception {
+ rnd = new Random(-1);
+ for (int i = 0; i < N; i++) {
+ ref.put(rnd.nextInt(N) * 2, rnd.nextBoolean() ? null : rnd.nextInt(N) * 2);
+ }
+ }
+
+ public final void testClear() {
+ map.clear();
+ assertTrue(map.isEmpty());
+ }
+
+ public final void testContainsKey() {
+ for (int i = 0; i < TRIES; i++) {
+ int key = rnd.nextInt(N);
+ assertEquals(ref.containsKey(key), map.containsKey(key));
+ }
+ }
+
+
+ public final void testContainsValue() {
+ for (int i = 0; i < TRIES; i++) {
+ int value = rnd.nextInt(N);
+ assertEquals(ref.containsValue(value), map.containsValue(value));
+ }
+ }
+
+
+ public final void testEntrySet() {
+ Set<Map.Entry<Integer, Integer>> refSet = ref.entrySet();
+ Set<Map.Entry<Integer, Integer>> mapSet = map.entrySet();
+ for (Map.Entry<Integer, Integer> e : refSet) {
+ assertTrue(mapSet.contains(e));
+ }
+ for (Map.Entry<Integer, Integer> e : mapSet) {
+ assertTrue(refSet.contains(e));
+ }
+ assertEquals(ref.entrySet(), map.entrySet());
+ }
+
+
+ public final void testGet() {
+ for (int i = 0; i < TRIES; i++) {
+ int key = rnd.nextInt(N);
+ assertEquals(ref.get(key), map.get(key));
+ }
+ }
+
+
+ public final void testKeySet() {
+ assertEquals(ref.keySet(), map.keySet());
+ Iterator<Integer> i = ref.keySet().iterator();
+ Iterator<Integer> j = map.keySet().iterator();
+ while (i.hasNext()) {
+ assertEquals(i.next(), j.next());
+ if (rnd.nextBoolean()) {
+ j.remove();
+ i.remove();
+ }
+ }
+ }
+
+
+ public final void testPut() {
+ for (int i = 0; i < TRIES; i++) {
+ int key = rnd.nextInt(N);
+ int value = rnd.nextInt(N);
+ assertEquals(ref.put(key, value), map.put(key, value));
+ assertEquals(ref.get(key), map.get(key));
+ assertEquals(ref, map);
+ }
+ }
+
+ public final void testPut0() {
+ ref.clear();
+ map.clear();
+ for (int i = 0; i < N; i++) {
+ int key = rnd.nextInt(N);
+ int value = rnd.nextInt(N);
+ assertEquals(ref.put(key, value), map.put(key, value));
+ assertEquals(ref.get(key), map.get(key));
+ }
+ }
+
+ public final void testPutAll() {
+ Map<Integer, Integer> mixin = new HashMap<Integer, Integer>(TRIES);
+ for (int i = 0; i < TRIES; i++) {
+ mixin.put(rnd.nextInt(N), rnd.nextInt(N));
+ }
+ ref.putAll(mixin);
+ map.putAll(mixin);
+ assertEquals(ref, map);
+ }
+
+
+ public final void testRemove() {
+ for (int i = 0; i < N; i++) {
+ int key = rnd.nextInt(N);
+ assertEquals(ref.remove(key), map.remove(key));
+ if (i % (N / TRIES) == 0) {
+ assertEquals(ref, map);
+ }
+ }
+ }
+
+ public final void testRemove0() {
+ while (!ref.isEmpty()) {
+ int key = ref.tailMap((ref.firstKey() + ref.lastKey()) / 2)
+ .firstKey();
+ assertEquals(ref.remove(key), map.remove(key));
+ }
+ }
+
+ public final void testSize() {
+ assertEquals(ref.size(), map.size());
+ }
+
+
+ public final void testValues() {
+ assertEquals(ref.values().size(), map.values().size());
+ assertTrue(ref.values().containsAll(map.values()));
+ assertTrue(map.values().containsAll(ref.values()));
+
+ Iterator<Integer> i = ref.values().iterator();
+ Iterator<Integer> j = map.values().iterator();
+ while (i.hasNext()) {
+ assertEquals(i.next(), j.next());
+ if (rnd.nextBoolean()) {
+ j.remove();
+ i.remove();
+ }
+ }
+ }
+
+ public final void testComparator() {
+ assertEquals(ref.comparator(), map.comparator());
+ }
+
+
+ public final void testFirstKey() {
+ assertEquals(ref.firstKey(), map.firstKey());
+ }
+
+
+ public final void testHeadMap() {
+ for (int i = 0; i < TRIES; i++) {
+ int key = rnd.nextInt(N);
+ checkSubMap(ref.headMap(key), map.headMap(key));
+ }
+ checkSubMap(ref.headMap(-1), map.headMap(-1));
+ }
+
+ public final void testLastKey() {
+ assertEquals(ref.lastKey(), map.lastKey());
+ }
+
+ public final void testSubMap() {
+ for (int i = 0; i < TRIES; i++) {
+ int key0 = rnd.nextInt(N / 2);
+ int key1 = rnd.nextInt(N / 2) + N / 2;
+ if (ref.comparator() != null &&
+ ref.comparator().compare(key0, key1) > 0) {
+
+ int tmp = key0;
+ key0 = key1;
+ key1 = tmp;
+ }
+ checkSubMap(ref.subMap(key0, key1), map.subMap(key0, key1));
+ }
+ boolean caught = false;
+ try {
+ if (ref.comparator() != null && ref.comparator().compare(100, 0) < 0) {
+ map.subMap(0, 100);
+ } else {
+ map.subMap(100, 0);
+ }
+ } catch (IllegalArgumentException e) {
+ caught = true;
+ }
+ assertTrue(caught);
+
+ int firstKey = ref.firstKey();
+ Map.Entry<Integer, Integer> refE = ref.entrySet().iterator().next();
+ Map.Entry<Integer, Integer> mapE = map.entrySet().iterator().next();
+ mapE.setValue(-1);
+ refE.setValue(-1);
+ assertEquals(ref.get(firstKey), map.get(firstKey));
+ }
+
+
+ public final void testTailMap() {
+ for (int i = 0; i < TRIES; i++) {
+ int key = rnd.nextInt(2 * N);
+ checkSubMap(ref.tailMap(key), map.tailMap(key));
+ }
+ checkSubMap(ref.tailMap(2 * N + 1), map.tailMap(2 * N + 1));
+ }
+
+
+ public final void testHashCode() {
+ assertEquals(ref.hashCode(), map.hashCode());
+ }
+
+ public final void testEqualsObject() {
+ assertTrue(map.equals(ref));
+ map.put(N + 1, N + 1);
+ assertFalse(map.equals(ref));
+ }
+
+
+ public final void testIsEmpty() {
+ assertEquals(ref.isEmpty(), map.isEmpty());
+ }
+
+ public final void testIsEmpty2() {
+ TreeMap<String, String> map = new TreeMap<String, String>();
+ map.put("one", "1");
+ assertEquals("size should be one", 1, map.size());
+ map.clear();
+ assertEquals("size should be zero", 0, map.size());
+ assertTrue("Should not have entries", !map.entrySet().iterator()
+ .hasNext());
+
+ map.put("one", "1");
+ assertEquals("size should be one", 1, map.size());
+ map.remove("one");
+ assertEquals("size should be zero", 0, map.size());
+ assertTrue("Should not have entries", !map.entrySet().iterator()
+ .hasNext());
+
+ map.clear();
+ map.put("0", "1");
+ map.clear();
+ assertTrue(map.isEmpty());
+ assertFalse(map.entrySet().iterator().hasNext());
+ assertFalse(map.keySet().iterator().hasNext());
+ assertFalse(map.values().iterator().hasNext());
+ }
+
+ public final void testToString() {
+ assertEquals(ref.toString(), map.toString());
+ }
+
+ private void checkSubMap(SortedMap<Integer, Integer> ref,
+ SortedMap<Integer, Integer> map) {
+
+ assertEquals(ref.size(), map.size());
+ assertEquals(ref, map);
+ assertEquals(ref.isEmpty(), map.isEmpty());
+ if (!ref.isEmpty()) {
+ assertEquals(ref.firstKey(), map.firstKey());
+ assertEquals(ref.lastKey(), map.lastKey());
+
+ testViews(ref, map);
+ } else {
+ boolean caught = false;
+ try {
+ map.firstKey();
+ } catch (NoSuchElementException e) {
+ caught = true;
+ }
+ caught = false;
+ try {
+ map.lastKey();
+ } catch (NoSuchElementException e) {
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ }
+
+ public final void testViews() {
+ testViews(ref, map);
+ }
+
+ private void testViews(SortedMap<Integer, Integer> ref, SortedMap<Integer, Integer> map) {
+ assertEquals(ref.keySet().size(), map.keySet().size());
+ assertEquals(ref.keySet(), map.keySet());
+ compareIterators(ref.keySet(), map.keySet());
+
+ assertEquals(ref.values().size(), map.values().size());
+ compareIterators(ref.values(), map.values());
+
+ assertEquals(ref.entrySet(), map.entrySet());
+ compareIterators(ref.entrySet(), map.entrySet());
+ }
+
+ private void compareIterators(Collection ref, Collection map) {
+ Iterator i = ref.iterator();
+ Iterator j = map.iterator();
+ while (i.hasNext()) {
+ assertEquals(i.next(), j.next());
+ if (rnd.nextBoolean()) {
+ j.remove();
+ i.remove();
+ assertEquals(ref.size(), map.size());
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public final void testSerialization() throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(map);
+ oos.close();
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
+ Object read = ois.readObject();
+ assertEquals(ref, read);
+ }
+
+ public final void testClone() throws Exception {
+ Method refClone = ref.getClass().getMethod("clone", new Class[0]);
+ Method mapClone = map.getClass().getMethod("clone", new Class[0]);
+ SortedMap<Integer, Integer> map2 = (SortedMap<Integer, Integer>) mapClone.invoke(map, new Object[0]);
+ assertEquals(refClone.invoke(ref, new Object[0]), map2);
+ map2.remove(map2.lastKey());
+ assertFalse(ref.equals(map2));
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/StackTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/StackTest.java
new file mode 100644
index 0000000..7be5a56
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/StackTest.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.EmptyStackException;
+import java.util.Stack;
+
+public class StackTest extends junit.framework.TestCase {
+
+ Stack s;
+
+ /**
+ * java.util.Stack#Stack()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.Stack()
+ assertEquals("Stack creation failed", 0, s.size());
+ }
+
+ /**
+ * java.util.Stack#empty()
+ */
+ public void test_empty() {
+ // Test for method boolean java.util.Stack.empty()
+ assertTrue("New stack answers non-empty", s.empty());
+ s.push("blah");
+ assertTrue("Stack should not be empty but answers empty", !s.empty());
+ s.pop();
+ assertTrue("Stack should be empty but answers non-empty", s.empty());
+ s.push(null);
+ assertTrue("Stack with null should not be empty but answers empty", !s
+ .empty());
+ }
+
+ /**
+ * java.util.Stack#peek()
+ */
+ public void test_peek() {
+ // Test for method java.lang.Object java.util.Stack.peek()
+ String item1 = "Ichi";
+ String item2 = "Ni";
+ String item3 = "San";
+ s.push(item1);
+ assertTrue("Peek did not return top item when it was the only item", s
+ .peek() == item1);
+ s.push(item2);
+ s.push(item3);
+ assertTrue("Peek did not return top item amoung many other items", s
+ .peek() == item3);
+ s.pop();
+ assertTrue("Peek did not return top item after a pop", s.pop() == item2);
+ s.push(null);
+ assertNull("Peek did not return top item (wanted: null)",
+ s.peek());
+ s.pop();
+ s.pop();
+ try {
+ s.pop();
+ fail("EmptyStackException expected");
+ } catch (EmptyStackException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Stack#pop()
+ */
+ public void test_pop() {
+ // Test for method java.lang.Object java.util.Stack.pop()
+ String item1 = "Ichi";
+ String item2 = "Ni";
+ Object lastPopped;
+ s.push(item1);
+ s.push(item2);
+
+ try {
+ lastPopped = s.pop();
+ assertTrue("a) Pop did not return top item", lastPopped == item2);
+ } catch (EmptyStackException e) {
+ fail(
+ "a) Pop threw EmptyStackException when stack should not have been empty");
+ }
+
+ try {
+ lastPopped = s.pop();
+ assertTrue("b) Pop did not return top item", lastPopped == item1);
+ } catch (EmptyStackException e) {
+ fail(
+ "b) Pop threw EmptyStackException when stack should not have been empty");
+ }
+
+ s.push(null);
+ try {
+ lastPopped = s.pop();
+ assertNull("c) Pop did not return top item", lastPopped);
+ } catch (EmptyStackException e) {
+ fail(
+ "c) Pop threw EmptyStackException when stack should not have been empty");
+ }
+
+ try {
+ lastPopped = s.pop();
+ fail(
+ "d) Pop did not throw EmptyStackException when stack should have been empty");
+ } catch (EmptyStackException e) {
+ return;
+ }
+
+ }
+
+ /**
+ * java.util.Stack#push(java.lang.Object)
+ */
+ public void test_pushLjava_lang_Object() {
+ Object [] array = {new Integer(0), new Object(),
+ new Float(0), new String()};
+
+ Stack<Object> stack = new Stack<Object>();
+ for(int i = 0; i < array.length; i++) {
+ stack.push(array[i]);
+ }
+ for(int i = 0; i < array.length; i++) {
+ assertEquals(array.length - i, stack.search(array[i]));
+ }
+ }
+
+ /**
+ * java.util.Stack#search(java.lang.Object)
+ */
+ public void test_searchLjava_lang_Object() {
+ // Test for method int java.util.Stack.search(java.lang.Object)
+ String item1 = "Ichi";
+ String item2 = "Ni";
+ String item3 = "San";
+ s.push(item1);
+ s.push(item2);
+ s.push(item3);
+ assertEquals("Search returned incorrect value for equivalent object", 3, s
+ .search(item1));
+ assertEquals("Search returned incorrect value for equal object", 3, s
+ .search("Ichi"));
+ s.pop();
+ assertEquals("Search returned incorrect value for equivalent object at top of stack",
+ 1, s.search(item2));
+ assertEquals("Search returned incorrect value for equal object at top of stack",
+ 1, s.search("Ni"));
+ s.push(null);
+ assertEquals("Search returned incorrect value for search for null at top of stack",
+ 1, s.search(null));
+ s.push("Shi");
+ assertEquals("Search returned incorrect value for search for null", 2, s
+ .search(null));
+ s.pop();
+ s.pop();
+ assertEquals("Search returned incorrect value for search for null--wanted -1",
+ -1, s.search(null));
+ }
+
+ static class BugStack<E> extends Stack<E> {
+ public void setLength(int elementCount) {
+ this.elementCount = elementCount;
+ }
+
+ public int getLength() {
+ return elementCount;
+ }
+ }
+
+ //test for wrong exception threw by pop method
+ public void test_pop_modify_elementCount() {
+ BugStack<String> testStack = new BugStack<String>();
+ testStack.push("A");
+ testStack.push("B");
+ testStack.setLength(20);
+ try {
+ testStack.pop();
+ fail("Should throw ArrayIndexOutOfBoundsException here");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //Expected to throw ArrayIndexOutOfBoundsException here
+ } catch (EmptyStackException e) {
+ fail("Should throw ArrayIndexOutOfBoundsException here");
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ s = new Stack();
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/StringTokenizerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/StringTokenizerTest.java
new file mode 100644
index 0000000..eeed19f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/StringTokenizerTest.java
@@ -0,0 +1,311 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+public class StringTokenizerTest extends junit.framework.TestCase {
+
+ /**
+ * java.util.StringTokenizer#StringTokenizer(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.util.StringTokenizer(java.lang.String)
+ try {
+ new StringTokenizer(null);
+ fail("NullPointerException is not thrown.");
+ } catch(NullPointerException npe) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.StringTokenizer#StringTokenizer(java.lang.String,
+ * java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+ // Test for method java.util.StringTokenizer(java.lang.String,
+ // java.lang.String)
+ StringTokenizer st = new StringTokenizer("This:is:a:test:String", ":");
+ assertTrue("Created incorrect tokenizer", st.countTokens() == 5
+ && (st.nextElement().equals("This")));
+ st = new StringTokenizer("This:is:a:test:String", null);
+
+ try {
+ new StringTokenizer(null, ":");
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.StringTokenizer#StringTokenizer(java.lang.String,
+ * java.lang.String, boolean)
+ */
+ public void test_ConstructorLjava_lang_StringLjava_lang_StringZ() {
+ // Test for method java.util.StringTokenizer(java.lang.String,
+ // java.lang.String, boolean)
+ StringTokenizer st = new StringTokenizer("This:is:a:test:String", ":",
+ true);
+ st.nextElement();
+ assertTrue("Created incorrect tokenizer", st.countTokens() == 8
+ && (st.nextElement().equals(":")));
+ st = new StringTokenizer("This:is:a:test:String", null, true);
+ st = new StringTokenizer("This:is:a:test:String", null, false);
+
+ try {
+ new StringTokenizer(null, ":", true);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.StringTokenizer#countTokens()
+ */
+ public void test_countTokens() {
+ // Test for method int java.util.StringTokenizer.countTokens()
+ StringTokenizer st = new StringTokenizer("This is a test String");
+
+ assertEquals("Incorrect token count returned", 5, st.countTokens());
+ }
+
+ /**
+ * java.util.StringTokenizer#hasMoreElements()
+ */
+ public void test_hasMoreElements() {
+ // Test for method boolean java.util.StringTokenizer.hasMoreElements()
+
+ StringTokenizer st = new StringTokenizer("This is a test String");
+ st.nextElement();
+ assertTrue("hasMoreElements returned incorrect value", st
+ .hasMoreElements());
+ st.nextElement();
+ st.nextElement();
+ st.nextElement();
+ st.nextElement();
+ assertTrue("hasMoreElements returned incorrect value", !st
+ .hasMoreElements());
+ }
+
+ /**
+ * java.util.StringTokenizer#hasMoreTokens()
+ */
+ public void test_hasMoreTokens() {
+ // Test for method boolean java.util.StringTokenizer.hasMoreTokens()
+ StringTokenizer st = new StringTokenizer("This is a test String");
+ for (int counter = 0; counter < 5; counter++) {
+ assertTrue(
+ "StringTokenizer incorrectly reports it has no more tokens",
+ st.hasMoreTokens());
+ st.nextToken();
+ }
+ assertTrue("StringTokenizer incorrectly reports it has more tokens",
+ !st.hasMoreTokens());
+ }
+
+ /**
+ * java.util.StringTokenizer#nextElement()
+ */
+ public void test_nextElement() {
+ // Test for method java.lang.Object
+ // java.util.StringTokenizer.nextElement()
+ StringTokenizer st = new StringTokenizer("This is a test String");
+ assertEquals("nextElement returned incorrect value", "This", ((String) st
+ .nextElement()));
+ assertEquals("nextElement returned incorrect value", "is", ((String) st
+ .nextElement()));
+ assertEquals("nextElement returned incorrect value", "a", ((String) st
+ .nextElement()));
+ assertEquals("nextElement returned incorrect value", "test", ((String) st
+ .nextElement()));
+ assertEquals("nextElement returned incorrect value", "String", ((String) st
+ .nextElement()));
+ try {
+ st.nextElement();
+ fail(
+ "nextElement failed to throw a NoSuchElementException when it should have been out of elements");
+ } catch (NoSuchElementException e) {
+ return;
+ }
+ }
+
+ /**
+ * java.util.StringTokenizer#nextToken()
+ */
+ public void test_nextToken() {
+ // Test for method java.lang.String
+ // java.util.StringTokenizer.nextToken()
+ StringTokenizer st = new StringTokenizer("This is a test String");
+ assertEquals("nextToken returned incorrect value",
+ "This", st.nextToken());
+ assertEquals("nextToken returned incorrect value",
+ "is", st.nextToken());
+ assertEquals("nextToken returned incorrect value",
+ "a", st.nextToken());
+ assertEquals("nextToken returned incorrect value",
+ "test", st.nextToken());
+ assertEquals("nextToken returned incorrect value",
+ "String", st.nextToken());
+ try {
+ st.nextToken();
+ fail(
+ "nextToken failed to throw a NoSuchElementException when it should have been out of elements");
+ } catch (NoSuchElementException e) {
+ return;
+ }
+ }
+
+ /**
+ * java.util.StringTokenizer#nextToken(java.lang.String)
+ */
+ public void test_nextTokenLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.util.StringTokenizer.nextToken(java.lang.String)
+ StringTokenizer st = new StringTokenizer("This is a test String");
+ assertEquals("nextToken(String) returned incorrect value with normal token String",
+ "This", st.nextToken(" "));
+ assertEquals("nextToken(String) returned incorrect value with custom token String",
+ " is a ", st.nextToken("tr"));
+ assertEquals("calling nextToken() did not use the new default delimiter list",
+ "es", st.nextToken());
+ st = new StringTokenizer("This:is:a:test:String", " ");
+ assertTrue(st.nextToken(":").equals("This"));
+ assertTrue(st.nextToken(":").equals("is"));
+ assertTrue(st.nextToken(":").equals("a"));
+ assertTrue(st.nextToken(":").equals("test"));
+ assertTrue(st.nextToken(":").equals("String"));
+
+ try {
+ st.nextToken(":");
+ fail("NoSuchElementException expected");
+ } catch (NoSuchElementException e) {
+ //expected
+ }
+
+ try {
+ st.nextToken(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ public void test_hasMoreElements_NPE() {
+ StringTokenizer stringTokenizer = new StringTokenizer(new String(),
+ (String) null, true);
+ try {
+ stringTokenizer.hasMoreElements();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ stringTokenizer = new StringTokenizer(new String(), (String) null);
+ try {
+ stringTokenizer.hasMoreElements();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ public void test_hasMoreTokens_NPE() {
+ StringTokenizer stringTokenizer = new StringTokenizer(new String(),
+ (String) null, true);
+ try {
+ stringTokenizer.hasMoreTokens();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ stringTokenizer = new StringTokenizer(new String(), (String) null);
+ try {
+ stringTokenizer.hasMoreTokens();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ public void test_nextElement_NPE() {
+ StringTokenizer stringTokenizer = new StringTokenizer(new String(),
+ (String) null, true);
+ try {
+ stringTokenizer.nextElement();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ stringTokenizer = new StringTokenizer(new String(), (String) null);
+ try {
+ stringTokenizer.nextElement();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ public void test_nextToken_NPE() {
+ StringTokenizer stringTokenizer = new StringTokenizer(new String(),
+ (String) null, true);
+ try {
+ stringTokenizer.nextToken();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ stringTokenizer = new StringTokenizer(new String(), (String) null);
+ try {
+ stringTokenizer.nextToken();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ public void test_nextTokenLjava_lang_String_NPE() {
+ StringTokenizer stringTokenizer = new StringTokenizer(new String());
+ try {
+ stringTokenizer.nextToken(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimeZoneTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimeZoneTest.java
new file mode 100644
index 0000000..0d16786
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimeZoneTest.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import tests.support.Support_TimeZone;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+public class TimeZoneTest extends junit.framework.TestCase {
+
+ private static final int ONE_HOUR = 3600000;
+
+ private TimeZone processDefault;
+
+ /**
+ * java.util.TimeZone#getDefault()
+ */
+ public void test_getDefault() {
+ assertNotSame("returns identical",
+ TimeZone.getDefault(), TimeZone.getDefault());
+ }
+
+ /**
+ * java.util.TimeZone#getDSTSavings()
+ */
+ public void test_getDSTSavings() {
+ // Test for method int java.util.TimeZone.getDSTSavings()
+
+ // test on subclass SimpleTimeZone
+ TimeZone st1 = TimeZone.getTimeZone("America/New_York");
+ assertEquals("T1A. Incorrect daylight savings returned",
+ ONE_HOUR, st1.getDSTSavings());
+
+ // a SimpleTimeZone with daylight savings different then 1 hour
+ st1 = TimeZone.getTimeZone("Australia/Lord_Howe");
+ assertEquals("T1B. Incorrect daylight savings returned",
+ 1800000, st1.getDSTSavings());
+
+ // test on subclass Support_TimeZone, an instance with daylight savings
+ TimeZone tz1 = new Support_TimeZone(-5 * ONE_HOUR, true);
+ assertEquals("T2. Incorrect daylight savings returned",
+ ONE_HOUR, tz1.getDSTSavings());
+
+ // an instance without daylight savings
+ tz1 = new Support_TimeZone(3 * ONE_HOUR, false);
+ assertEquals("T3. Incorrect daylight savings returned, ",
+ 0, tz1.getDSTSavings());
+ }
+
+ /**
+ * java.util.TimeZone#getOffset(long)
+ */
+ public void test_getOffset_long() {
+ // Test for method int java.util.TimeZone.getOffset(long time)
+
+ // test on subclass SimpleTimeZone
+ TimeZone st1 = TimeZone.getTimeZone("EST");
+ long time1 = new GregorianCalendar(1998, Calendar.NOVEMBER, 11)
+ .getTimeInMillis();
+ assertEquals("T1. Incorrect offset returned",
+ -(5 * ONE_HOUR), st1.getOffset(time1));
+
+ long time2 = new GregorianCalendar(1998, Calendar.JUNE, 11)
+ .getTimeInMillis();
+ st1 = TimeZone.getTimeZone("EST");
+ assertEquals("T2. Incorrect offset returned",
+ -(5 * ONE_HOUR), st1.getOffset(time2));
+
+ // test on subclass Support_TimeZone, an instance with daylight savings
+ TimeZone tz1 = new Support_TimeZone(-5 * ONE_HOUR, true);
+ assertEquals("T3. Incorrect offset returned, ",
+ -(5 * ONE_HOUR), tz1.getOffset(time1));
+ assertEquals("T4. Incorrect offset returned, ",
+ -(4 * ONE_HOUR), tz1.getOffset(time2));
+
+ // an instance without daylight savings
+ tz1 = new Support_TimeZone(3 * ONE_HOUR, false);
+ assertEquals("T5. Incorrect offset returned, ",
+ (3 * ONE_HOUR), tz1.getOffset(time1));
+ assertEquals("T6. Incorrect offset returned, ",
+ (3 * ONE_HOUR), tz1.getOffset(time2));
+ }
+
+ /**
+ * java.util.TimeZone#getTimeZone(java.lang.String)
+ */
+ public void test_getTimeZoneLjava_lang_String() {
+ assertEquals("Must return GMT when given an invalid TimeZone id SMT-8.",
+ "GMT", TimeZone.getTimeZone("SMT-8").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+28:70.",
+ "GMT", TimeZone.getTimeZone("GMT+28:70").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+28:30.",
+ "GMT", TimeZone.getTimeZone("GMT+28:30").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+8:70.",
+ "GMT", TimeZone.getTimeZone("GMT+8:70").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+3:.",
+ "GMT", TimeZone.getTimeZone("GMT+3:").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+3:0.",
+ "GMT", TimeZone.getTimeZone("GMT+3:0").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+2360.",
+ "GMT", TimeZone.getTimeZone("GMT+2360").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+892.",
+ "GMT", TimeZone.getTimeZone("GMT+892").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+082.",
+ "GMT", TimeZone.getTimeZone("GMT+082").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+28.",
+ "GMT", TimeZone.getTimeZone("GMT+28").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT+30.",
+ "GMT", TimeZone.getTimeZone("GMT+30").getID());
+ assertEquals("Must return GMT when given TimeZone GMT.",
+ "GMT", TimeZone.getTimeZone("GMT").getID());
+ assertEquals("Must return GMT when given TimeZone GMT+.",
+ "GMT", TimeZone.getTimeZone("GMT+").getID());
+ assertEquals("Must return GMT when given TimeZone GMT-.",
+ "GMT", TimeZone.getTimeZone("GMT-").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT-8.45.",
+ "GMT", TimeZone.getTimeZone("GMT-8.45").getID());
+ assertEquals("Must return GMT when given an invalid TimeZone time GMT-123:23.",
+ "GMT", TimeZone.getTimeZone("GMT-123:23").getID());
+ assertEquals("Must return proper GMT formatted string for GMT+8:30 (eg. GMT+08:20).",
+ "GMT+08:30", TimeZone.getTimeZone("GMT+8:30").getID());
+ assertEquals("Must return proper GMT formatted string for GMT+3 (eg. GMT+08:20).",
+ "GMT+03:00", TimeZone.getTimeZone("GMT+3").getID());
+ assertEquals("Must return proper GMT formatted string for GMT+3:02 (eg. GMT+08:20).",
+ "GMT+03:02", TimeZone.getTimeZone("GMT+3:02").getID());
+ assertEquals("Must return proper GMT formatted string for GMT+2359 (eg. GMT+08:20).",
+ "GMT+23:59", TimeZone.getTimeZone("GMT+2359").getID());
+ assertEquals("Must return proper GMT formatted string for GMT+520 (eg. GMT+08:20).",
+ "GMT+05:20", TimeZone.getTimeZone("GMT+520").getID());
+ assertEquals("Must return proper GMT formatted string for GMT+052 (eg. GMT+08:20).",
+ "GMT+00:52", TimeZone.getTimeZone("GMT+052").getID());
+ // GMT-0 is an available ID in ICU, so replace it with GMT-00
+ assertEquals("Must return proper GMT formatted string for GMT-00 (eg. GMT+08:20).",
+ "GMT-00:00", TimeZone.getTimeZone("GMT-00").getID());
+ }
+
+ /**
+ * java.util.TimeZone#setDefault(java.util.TimeZone)
+ */
+ public void test_setDefaultLjava_util_TimeZone() {
+ // NOTE: Required to get tests passing under vogar. Vogar sets
+ // a hardcoded timezone before running every test, so we have to
+ // set it back to the "real" default before we run the test.
+ TimeZone.setDefault(null);
+
+ TimeZone oldDefault = TimeZone.getDefault();
+ TimeZone zone = new SimpleTimeZone(45, "TEST");
+ TimeZone.setDefault(zone);
+ assertEquals("timezone not set", zone, TimeZone.getDefault());
+ TimeZone.setDefault(null);
+ assertEquals("default not restored",
+ oldDefault, TimeZone.getDefault());
+ }
+
+ /**
+ * java.util.TimeZone#getDisplayName(java.util.Locale)
+ */
+ public void test_getDisplayNameLjava_util_Locale() {
+ TimeZone timezone = TimeZone.getTimeZone("Asia/Shanghai");
+ assertEquals("\u4e2d\u56fd\u6807\u51c6\u65f6\u95f4", timezone
+ .getDisplayName(Locale.CHINA));
+ }
+
+ /**
+ * java.util.TimeZone#getDisplayName(boolean, int, java.util.Locale)
+ */
+ public void test_getDisplayNameZILjava_util_Locale() {
+ TimeZone timezone = TimeZone.getTimeZone("Asia/Shanghai");
+ /* Time zone data was changed in ICU49.2. Many common short names were removed. */
+ assertEquals("中国标准时间",
+ timezone.getDisplayName(false, TimeZone.LONG, Locale.CHINA));
+ assertEquals("GMT+08:00",
+ timezone.getDisplayName(false, TimeZone.SHORT, Locale.CHINA));
+ try {
+ timezone.getDisplayName(false, 100, Locale.CHINA);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Regression for HARMONY-5860
+ */
+ public void test_GetTimezoneOffset() {
+ // America/Toronto is lazy initialized
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Toronto"));
+ Date date = new Date(07, 2, 24);
+ assertEquals(300, date.getTimezoneOffset());
+ date = new Date(99, 8, 1);
+ assertEquals(240, date.getTimezoneOffset());
+ }
+
+ protected void setUp() {
+ processDefault = TimeZone.getDefault();
+ }
+
+ protected void tearDown() {
+ TimeZone.setDefault(processDefault);
+ }
+
+ public void test_getAvailableIDs_I_16947622() {
+ TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+ int rawOffset = tz.getRawOffset();
+ assertEquals(-8 * 60 * 60 * 1000, rawOffset);
+ List<String> ids = Arrays.asList(TimeZone.getAvailableIDs(rawOffset));
+
+ // Obviously, for all time zones, the time zone whose raw offset we started with
+ // should be one of the available ids for that offset.
+ assertTrue(ids.toString(), ids.contains("America/Los_Angeles"));
+
+ // Any one of these might legitimately change its raw offset, though that's
+ // fairly unlikely, and the chances of more than one changing are very slim.
+ assertTrue(ids.toString(), ids.contains("America/Dawson"));
+ assertTrue(ids.toString(), ids.contains("America/Tijuana"));
+ assertTrue(ids.toString(), ids.contains("America/Vancouver"));
+ assertTrue(ids.toString(), ids.contains("Canada/Pacific"));
+ assertTrue(ids.toString(), ids.contains("Canada/Yukon"));
+ assertTrue(ids.toString(), ids.contains("Pacific/Pitcairn"));
+ }
+
+ public void test_getAvailableIDs_I() {
+ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+ int rawoffset = tz.getRawOffset();
+ String[] ids = TimeZone.getAvailableIDs(rawoffset);
+ List<String> idList = Arrays.asList(ids);
+ assertTrue(idList.toString(), idList.contains("Asia/Hong_Kong"));
+ }
+
+ /**
+ * @add test {@link java.util.TimeZone#getDisplayName()}
+ */
+ public void test_getDisplayName() {
+ TimeZone defaultZone = TimeZone.getDefault();
+ Locale defaulLocal = Locale.getDefault();
+ String defaultName = defaultZone.getDisplayName();
+ String expectedName = defaultZone.getDisplayName(defaulLocal);
+ assertEquals(
+ "getDispalyName() did not return the default Locale suitable name",
+ expectedName, defaultName);
+ }
+
+ /**
+ * @add test {@link java.util.TimeZone#getDisplayName(boolean, int)}
+ */
+ public void test_getDisplayName_ZI() {
+ TimeZone defaultZone = TimeZone.getDefault();
+ Locale defaultLocale = Locale.getDefault();
+ String actualName = defaultZone.getDisplayName(false, TimeZone.LONG);
+ String expectedName = defaultZone.getDisplayName(false, TimeZone.LONG,
+ defaultLocale);
+ assertEquals(
+ "getDisplayName(daylight,style) did not return the default locale suitable name",
+ expectedName, actualName);
+ }
+
+ /**
+ * @add test {@link java.util.TimeZone#hasSameRules(TimeZone)}
+ */
+ public void test_hasSameRules_Ljava_util_TimeZone() {
+ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+ int offset = tz.getRawOffset();
+
+ String[] ids = TimeZone.getAvailableIDs(offset);
+ int i = 0;
+ if (ids.length != 0) {
+ while (true) {
+ if (!(ids[i].equalsIgnoreCase(tz.getID()))) {
+ TimeZone sameZone = TimeZone.getTimeZone(ids[i]);
+ assertTrue(tz.hasSameRules(sameZone));
+ break;
+ } else {
+ i++;
+ }
+ }
+ }
+ assertFalse("should return false when parameter is null", tz
+ .hasSameRules(null));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTaskTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTaskTest.java
new file mode 100644
index 0000000..3e072e7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTaskTest.java
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class TimerTaskTest extends junit.framework.TestCase {
+ /**
+ * Warning: These tests have the possibility to leave a VM hanging if the
+ * Timer is not cancelled.
+ */
+ class TimerTestTask extends TimerTask {
+
+ private final Object sync = new Object();
+ private final Object start = new Object();
+
+ private int wasRun = 0;
+
+ // Set this to true to see normal tests fail (or hang possibly)
+ // The default is false and needs to be set by some tests
+ private boolean sleepInRun = false;
+
+ public void run() {
+ synchronized (this) {
+ wasRun++;
+ }
+ synchronized (start) {
+ start.notify();
+ }
+ if (sleepInRun) {
+
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ }
+ }
+ synchronized (sync) {
+ sync.notify();
+ }
+ }
+
+ public synchronized int wasRun() {
+ return wasRun;
+ }
+
+ public void sleepInRun(boolean value) {
+ sleepInRun = value;
+ }
+ }
+
+ /**
+ * java.util.TimerTask#TimerTask()
+ */
+ public void test_Constructor() {
+ // Ensure the constructor does not fail
+ new TimerTestTask();
+ }
+
+ /**
+ * java.util.TimerTask#cancel()
+ */
+ public void test_cancel() {
+ Timer t = null;
+ try {
+ // Ensure cancel returns false if never scheduled
+ TimerTestTask testTask = new TimerTestTask();
+ assertTrue("Unsheduled tasks should return false for cancel()",
+ !testTask.cancel());
+
+ // Ensure cancelled task never runs
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 500);
+ assertTrue("TimerTask should not have run yet", testTask.cancel());
+ t.cancel();
+
+ // Ensure cancelling a task which has already run returns true
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 50);
+ while (testTask.wasRun() == 0) {
+ try {
+ Thread.sleep(150);
+ } catch (InterruptedException e) {
+ }
+ }
+ assertFalse(
+ "TimerTask.cancel() should return false if task has run",
+ testTask.cancel());
+ assertFalse(
+ "TimerTask.cancel() should return false if called a second time",
+ testTask.cancel());
+ t.cancel();
+
+ // Ensure cancelling a repeated execution task which has never run
+ // returns true
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 500, 500); // should never run
+ assertTrue(
+ "TimerTask.cancel() should return true if sheduled for repeated execution even if not run",
+ testTask.cancel());
+ t.cancel();
+
+ // Ensure cancelling a repeated execution task which HAS run returns
+ // true
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 50, 50);
+ while (testTask.wasRun() == 0) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ assertTrue(
+ "TimerTask.cancel() should return true if sheduled for repeated execution and run",
+ testTask.cancel());
+ t.cancel();
+
+ // Ensure calling cancel a second returns false
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 5000); // Should never run
+ assertTrue(
+ "TimerTask.cancel() should return true if task has never run",
+ testTask.cancel());
+ assertFalse(
+ "TimerTask.cancel() should return false if called a second time",
+ testTask.cancel());
+ t.cancel();
+
+ // Ensure cancelling a task won't cause deadlock
+ t = new Timer();
+ testTask = new TimerTestTask();
+ testTask.sleepInRun(true);
+ synchronized (testTask.start) {
+ t.schedule(testTask, 0);
+ try {
+ testTask.start.wait();
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ }
+ }
+ assertFalse("TimerTask should have been cancelled", testTask
+ .cancel());
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+ }
+
+ /**
+ * java.util.TimerTask#scheduledExecutionTime()
+ */
+ public void test_scheduledExecutionTime() {
+ Timer t = null;
+ try {
+ // Ensure scheduledExecutionTime is roughly right
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ t.schedule(testTask, 100);
+ long time = System.currentTimeMillis() + 100;
+ synchronized (testTask.sync) {
+ try {
+ testTask.sync.wait(500);
+ } catch (InterruptedException e) {
+ }
+ }
+ long scheduledExecutionTime = testTask.scheduledExecutionTime();
+ assertTrue(scheduledExecutionTime <= time);
+ t.cancel();
+
+ // Ensure scheduledExecutionTime is the last scheduled time
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 100, 500);
+ long estNow = System.currentTimeMillis() + 100;
+ // Will wake in 100, and every 500 run again
+ // We want to try to get it after it's run at least once but not
+ // twice
+ synchronized (testTask.sync) {
+ try {
+ testTask.sync.wait(500);
+ } catch (InterruptedException e) {
+ }
+ }
+ scheduledExecutionTime = testTask.scheduledExecutionTime();
+ assertTrue(scheduledExecutionTime <= estNow);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+
+ }
+
+ /**
+ * java.util.TimerTask#run()
+ */
+ public void test_run() {
+ Timer t = null;
+ try {
+ // Ensure a new task is never run
+ TimerTestTask testTask = new TimerTestTask();
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ }
+ assertEquals("TimerTask.run() method should not have been called",
+ 0, testTask.wasRun());
+
+ // Ensure a task is run
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 200);
+ while(testTask.wasRun() < 1) {
+ try {
+ Thread.sleep(400);
+ } catch (InterruptedException e) {
+ }
+ }
+ assertFalse(testTask.cancel());
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTest.java
new file mode 100644
index 0000000..85e7c6a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTest.java
@@ -0,0 +1,986 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
+
+public class TimerTest extends TestCase {
+
+ int timerCounter = 0;
+
+ private final Object sync = new Object();
+
+ /**
+ * Warning: These tests have the possibility to leave a VM hanging if the
+ * Timer is not cancelled.
+ */
+ class TimerTestTask extends TimerTask {
+ int wasRun = 0;
+
+ // Should we sleep for 200 ms each run()?
+ boolean sleepInRun = false;
+
+ // Should we increment the timerCounter?
+ boolean incrementCount = false;
+
+ // Should we terminate the timer at a specific timerCounter?
+ int terminateCount = -1;
+
+ // The timer we belong to
+ Timer timer = null;
+
+ public TimerTestTask() {
+ }
+
+ public TimerTestTask(Timer t) {
+ timer = t;
+ }
+
+ public void run() {
+ synchronized (this) {
+ wasRun++;
+ }
+ if (incrementCount) {
+ timerCounter++;
+ }
+ if (terminateCount == timerCounter && timer != null) {
+ timer.cancel();
+ }
+ if (sleepInRun) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ synchronized (sync) {
+ sync.notify();
+ }
+ }
+
+ public synchronized int wasRun() {
+ return wasRun;
+ }
+
+ public void sleepInRun(boolean sleepInRun) {
+ this.sleepInRun = sleepInRun;
+ }
+
+ public void incrementCount(boolean incrementCount) {
+ this.incrementCount = incrementCount;
+ }
+
+ public void terminateCount(int terminateCount) {
+ this.terminateCount = terminateCount;
+ }
+ }
+
+ private void awaitRun(TimerTestTask task) throws Exception {
+ while (task.wasRun() == 0) {
+ Thread.sleep(150);
+ }
+ }
+
+ /**
+ * java.util.Timer#Timer(boolean)
+ */
+ public void test_ConstructorZ() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a task is run
+ t = new Timer(true);
+ TimerTestTask testTask = new TimerTestTask();
+ t.schedule(testTask, 200);
+ awaitRun(testTask);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+
+ }
+
+ /**
+ * java.util.Timer#Timer()
+ */
+ public void test_Constructor() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a task is run
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ t.schedule(testTask, 200);
+ awaitRun(testTask);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+
+ }
+
+ /**
+ * java.util.Timer#Timer(String, boolean)
+ */
+ public void test_ConstructorSZ() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a task is run
+ t = new Timer("test_ConstructorSZThread", true);
+ TimerTestTask testTask = new TimerTestTask();
+ t.schedule(testTask, 200);
+ awaitRun(testTask);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+
+ try {
+ new Timer(null, true);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ new Timer(null, false);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * java.util.Timer#Timer(String)
+ */
+ public void test_ConstructorS() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a task is run
+ t = new Timer("test_ConstructorSThread");
+ TimerTestTask testTask = new TimerTestTask();
+ t.schedule(testTask, 200);
+ awaitRun(testTask);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+
+ try {
+ new Timer(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /**
+ * java.util.Timer#cancel()
+ */
+ public void test_cancel() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a task throws an IllegalStateException after cancelled
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ t.cancel();
+ try {
+ t.schedule(testTask, 100, 200);
+ fail("Scheduling a task after Timer.cancel() should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+
+ // Ensure a task is run but not after cancel
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 100, 500);
+ awaitRun(testTask);
+ t.cancel();
+ synchronized (sync) {
+ sync.wait(500);
+ }
+ assertEquals("TimerTask.run() method should not have been called after cancel",
+ 1, testTask.wasRun());
+
+ // Ensure you can call cancel more than once
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 100, 500);
+ awaitRun(testTask);
+ t.cancel();
+ t.cancel();
+ t.cancel();
+ synchronized (sync) {
+ sync.wait(500);
+ }
+ assertEquals("TimerTask.run() method should not have been called after cancel",
+ 1, testTask.wasRun());
+
+ // Ensure that a call to cancel from within a timer ensures no more
+ // run
+ t = new Timer();
+ testTask = new TimerTestTask(t);
+ testTask.incrementCount(true);
+ testTask.terminateCount(5); // Terminate after 5 runs
+ t.schedule(testTask, 100, 100);
+ synchronized (sync) {
+ sync.wait(200);
+ assertEquals(1, testTask.wasRun());
+ sync.wait(200);
+ assertEquals(2, testTask.wasRun());
+ sync.wait(200);
+ assertEquals(3, testTask.wasRun());
+ sync.wait(200);
+ assertEquals(4, testTask.wasRun());
+ sync.wait(200);
+ assertEquals(5, testTask.wasRun());
+ sync.wait(200);
+ assertEquals(5, testTask.wasRun());
+ }
+ t.cancel();
+ Thread.sleep(200);
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+
+ }
+
+ /**
+ * java.util.Timer#purge()
+ */
+ public void test_purge() throws Exception {
+ Timer t = null;
+ try {
+ t = new Timer();
+ assertEquals(0, t.purge());
+
+ TimerTestTask[] tasks = new TimerTestTask[100];
+ int[] delayTime = { 50, 80, 20, 70, 40, 10, 90, 30, 60 };
+
+ int j = 0;
+ for (int i = 0; i < 100; i++) {
+ tasks[i] = new TimerTestTask();
+ t.schedule(tasks[i], delayTime[j++], 200);
+ if (j == 9) {
+ j = 0;
+ }
+ }
+
+ for (int i = 0; i < 50; i++) {
+ tasks[i].cancel();
+ }
+
+ assertTrue(t.purge() <= 50);
+ assertEquals(0, t.purge());
+ } finally {
+ if (t != null) {
+ t.cancel();
+ }
+ }
+ }
+
+ /**
+ * java.util.Timer#schedule(java.util.TimerTask, java.util.Date)
+ */
+ public void test_scheduleLjava_util_TimerTaskLjava_util_Date() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a Timer throws an IllegalStateException after cancelled
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ Date d = new Date(System.currentTimeMillis() + 100);
+ t.cancel();
+ try {
+ t.schedule(testTask, d);
+ fail("Scheduling a task after Timer.cancel() should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+
+ // Ensure a Timer throws an IllegalStateException if task already
+ // cancelled
+ t = new Timer();
+ testTask = new TimerTestTask();
+ d = new Date(System.currentTimeMillis() + 100);
+ testTask.cancel();
+ try {
+ t.schedule(testTask, d);
+ fail("Scheduling a task after cancelling it should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if delay is
+ // negative
+ t = new Timer();
+ testTask = new TimerTestTask();
+ d = new Date(-100);
+ try {
+ t.schedule(testTask, d);
+ fail("Scheduling a task with negative date should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws a NullPointerException if the task is null
+ t = new Timer();
+ d = new Date(System.currentTimeMillis() + 100);
+ try {
+ t.schedule(null, d);
+ fail("Scheduling a null task should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws a NullPointerException if the date is null
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.schedule(testTask, null);
+ fail("Scheduling a null date should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ t.cancel();
+
+ // Ensure proper sequence of exceptions
+ t = new Timer();
+ d = new Date(-100);
+ try {
+ t.schedule(null, d);
+ fail("Scheduling a null task with negative date should throw IllegalArgumentException first");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a task is run
+ t = new Timer();
+ testTask = new TimerTestTask();
+ d = new Date(System.currentTimeMillis() + 200);
+ t.schedule(testTask, d);
+ awaitRun(testTask);
+ t.cancel();
+
+ // Ensure multiple tasks are run
+ t = new Timer();
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ d = new Date(System.currentTimeMillis() + 100);
+ t.schedule(testTask, d);
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ d = new Date(System.currentTimeMillis() + 150);
+ t.schedule(testTask, d);
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ d = new Date(System.currentTimeMillis() + 70);
+ t.schedule(testTask, d);
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ d = new Date(System.currentTimeMillis() + 10);
+ t.schedule(testTask, d);
+ Thread.sleep(400);
+ assertTrue("Multiple tasks should have incremented counter 4 times not "
+ + timerCounter, timerCounter == 4);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+ }
+
+ /**
+ * java.util.Timer#schedule(java.util.TimerTask, long)
+ */
+ public void test_scheduleLjava_util_TimerTaskJ() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a Timer throws an IllegalStateException after cancelled
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ t.cancel();
+ try {
+ t.schedule(testTask, 100);
+ fail("Scheduling a task after Timer.cancel() should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+
+ // Ensure a Timer throws an IllegalStateException if task already
+ // cancelled
+ t = new Timer();
+ testTask = new TimerTestTask();
+ testTask.cancel();
+ try {
+ t.schedule(testTask, 100);
+ fail("Scheduling a task after cancelling it should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if delay is
+ // negative
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.schedule(testTask, -100);
+ fail("Scheduling a task with negative delay should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws a NullPointerException if the task is null
+ t = new Timer();
+ try {
+ t.schedule(null, 10);
+ fail("Scheduling a null task should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ t.cancel();
+
+ // Ensure proper sequence of exceptions
+ t = new Timer();
+ try {
+ t.schedule(null, -10);
+ fail("Scheduling a null task with negative delays should throw IllegalArgumentException first");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a task is run
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 200);
+ awaitRun(testTask);
+ t.cancel();
+
+ // Ensure multiple tasks are run
+ t = new Timer();
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ t.schedule(testTask, 100);
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ t.schedule(testTask, 150);
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ t.schedule(testTask, 70);
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ t.schedule(testTask, 10);
+ Thread.sleep(400);
+ assertTrue("Multiple tasks should have incremented counter 4 times not "
+ + timerCounter, timerCounter == 4);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+ }
+
+ /**
+ * java.util.Timer#schedule(java.util.TimerTask, long, long)
+ */
+ public void test_scheduleLjava_util_TimerTaskJJ() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a Timer throws an IllegalStateException after cancelled
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ t.cancel();
+ try {
+ t.schedule(testTask, 100, 100);
+ fail("Scheduling a task after Timer.cancel() should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+
+ // Ensure a Timer throws an IllegalStateException if task already
+ // cancelled
+ t = new Timer();
+ testTask = new TimerTestTask();
+ testTask.cancel();
+ try {
+ t.schedule(testTask, 100, 100);
+ fail("Scheduling a task after cancelling it should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if delay is
+ // negative
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.schedule(testTask, -100, 100);
+ fail("Scheduling a task with negative delay should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if period is
+ // negative
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.schedule(testTask, 100, -100);
+ fail("Scheduling a task with negative period should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if period is
+ // zero
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.schedule(testTask, 100, 0);
+ fail("Scheduling a task with 0 period should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws a NullPointerException if the task is null
+ t = new Timer();
+ try {
+ t.schedule(null, 10, 10);
+ fail("Scheduling a null task should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ t.cancel();
+
+ // Ensure proper sequence of exceptions
+ t = new Timer();
+ try {
+ t.schedule(null, -10, -10);
+ fail("Scheduling a null task with negative delays should throw IllegalArgumentException first");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a task is run at least twice
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.schedule(testTask, 100, 100);
+ Thread.sleep(400);
+ assertTrue("TimerTask.run() method should have been called at least twice ("
+ + testTask.wasRun() + ")", testTask.wasRun() >= 2);
+ t.cancel();
+
+ // Ensure multiple tasks are run
+ t = new Timer();
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ t.schedule(testTask, 100, 100); // at least 9 times
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ t.schedule(testTask, 200, 100); // at least 7 times
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ t.schedule(testTask, 300, 200); // at least 4 times
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ t.schedule(testTask, 100, 200); // at least 4 times
+ Thread.sleep(1200); // Allowed more room for error
+ assertTrue("Multiple tasks should have incremented counter 24 times not "
+ + timerCounter, timerCounter >= 24);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+ }
+
+ /**
+ * java.util.Timer#schedule(java.util.TimerTask, java.util.Date,
+ * long)
+ */
+ public void test_scheduleLjava_util_TimerTaskLjava_util_DateJ() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a Timer throws an IllegalStateException after cancelled
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ Date d = new Date(System.currentTimeMillis() + 100);
+ t.cancel();
+ try {
+ t.schedule(testTask, d, 100);
+ fail("Scheduling a task after Timer.cancel() should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+
+ // Ensure a Timer throws an IllegalStateException if task already
+ // cancelled
+ t = new Timer();
+ d = new Date(System.currentTimeMillis() + 100);
+ testTask = new TimerTestTask();
+ testTask.cancel();
+ try {
+ t.schedule(testTask, d, 100);
+ fail("Scheduling a task after cancelling it should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if delay is
+ // negative
+ t = new Timer();
+ d = new Date(-100);
+ testTask = new TimerTestTask();
+ try {
+ t.schedule(testTask, d, 100);
+ fail("Scheduling a task with negative delay should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if period is
+ // negative
+ t = new Timer();
+ d = new Date(System.currentTimeMillis() + 100);
+ testTask = new TimerTestTask();
+ try {
+ t.schedule(testTask, d, -100);
+ fail("Scheduling a task with negative period should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws a NullPointerException if the task is null
+ t = new Timer();
+ d = new Date(System.currentTimeMillis() + 100);
+ try {
+ t.schedule(null, d, 10);
+ fail("Scheduling a null task should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws a NullPointerException if the date is null
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.schedule(testTask, null, 10);
+ fail("Scheduling a null task should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ t.cancel();
+
+ // Ensure proper sequence of exceptions
+ t = new Timer();
+ d = new Date(-100);
+ try {
+ t.schedule(null, d, 10);
+ fail("Scheduling a null task with negative dates should throw IllegalArgumentException first");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a task is run at least twice
+ t = new Timer();
+ d = new Date(System.currentTimeMillis() + 100);
+ testTask = new TimerTestTask();
+ t.schedule(testTask, d, 100);
+ Thread.sleep(800);
+ assertTrue("TimerTask.run() method should have been called at least twice ("
+ + testTask.wasRun() + ")", testTask.wasRun() >= 2);
+ t.cancel();
+
+ // Ensure multiple tasks are run
+ t = new Timer();
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ d = new Date(System.currentTimeMillis() + 100);
+ t.schedule(testTask, d, 100); // at least 9 times
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ d = new Date(System.currentTimeMillis() + 200);
+ t.schedule(testTask, d, 100); // at least 7 times
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ d = new Date(System.currentTimeMillis() + 300);
+ t.schedule(testTask, d, 200); // at least 4 times
+ testTask = new TimerTestTask();
+ testTask.incrementCount(true);
+ d = new Date(System.currentTimeMillis() + 100);
+ t.schedule(testTask, d, 200); // at least 4 times
+ Thread.sleep(3000);
+ assertTrue("Multiple tasks should have incremented counter 24 times not "
+ + timerCounter, timerCounter >= 24);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+ }
+
+ /**
+ * java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long,
+ * long)
+ */
+ public void test_scheduleAtFixedRateLjava_util_TimerTaskJJ() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a Timer throws an IllegalStateException after cancelled
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ t.cancel();
+ try {
+ t.scheduleAtFixedRate(testTask, 100, 100);
+ fail("scheduleAtFixedRate after Timer.cancel() should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+
+ // Ensure a Timer throws an IllegalArgumentException if delay is
+ // negative
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.scheduleAtFixedRate(testTask, -100, 100);
+ fail("scheduleAtFixedRate with negative delay should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if period is
+ // negative
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.scheduleAtFixedRate(testTask, 100, -100);
+ fail("scheduleAtFixedRate with negative period should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a task is run at least twice
+ t = new Timer();
+ testTask = new TimerTestTask();
+ t.scheduleAtFixedRate(testTask, 100, 100);
+ Thread.sleep(400);
+ assertTrue("TimerTask.run() method should have been called at least twice ("
+ + testTask.wasRun() + ")", testTask.wasRun() >= 2);
+ t.cancel();
+
+ class SlowThenFastTask extends TimerTask {
+ int wasRun = 0;
+
+ long startedAt;
+
+ long lastDelta;
+
+ public void run() {
+ if (wasRun == 0)
+ startedAt = System.currentTimeMillis();
+ lastDelta = System.currentTimeMillis()
+ - (startedAt + (100 * wasRun));
+ wasRun++;
+ if (wasRun == 2) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public long lastDelta() {
+ return lastDelta;
+ }
+
+ public int wasRun() {
+ return wasRun;
+ }
+ }
+
+ // Ensure multiple tasks are run
+ t = new Timer();
+ SlowThenFastTask slowThenFastTask = new SlowThenFastTask();
+
+ // at least 9 times even when asleep
+ t.scheduleAtFixedRate(slowThenFastTask, 100, 100);
+ Thread.sleep(1000);
+ long lastDelta = slowThenFastTask.lastDelta();
+ assertTrue("Fixed Rate Schedule should catch up, but is off by "
+ + lastDelta + " ms", slowThenFastTask.lastDelta < 300);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+ }
+
+ /**
+ * java.util.Timer#scheduleAtFixedRate(java.util.TimerTask,
+ * java.util.Date, long)
+ */
+ public void test_scheduleAtFixedRateLjava_util_TimerTaskLjava_util_DateJ() throws Exception {
+ Timer t = null;
+ try {
+ // Ensure a Timer throws an IllegalStateException after cancelled
+ t = new Timer();
+ TimerTestTask testTask = new TimerTestTask();
+ t.cancel();
+ Date d = new Date(System.currentTimeMillis() + 100);
+ try {
+ t.scheduleAtFixedRate(testTask, d, 100);
+ fail("scheduleAtFixedRate after Timer.cancel() should throw exception");
+ } catch (IllegalStateException expected) {
+ }
+
+ // Ensure a Timer throws an IllegalArgumentException if delay is
+ // negative
+ t = new Timer();
+ testTask = new TimerTestTask();
+ d = new Date(-100);
+ try {
+ t.scheduleAtFixedRate(testTask, d, 100);
+ fail("scheduleAtFixedRate with negative Date should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an IllegalArgumentException if period is
+ // negative
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.scheduleAtFixedRate(testTask, d, -100);
+ fail("scheduleAtFixedRate with negative period should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a Timer throws an NullPointerException if date is Null
+ t = new Timer();
+ testTask = new TimerTestTask();
+ try {
+ t.scheduleAtFixedRate(testTask, null, 100);
+ fail("scheduleAtFixedRate with null date should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ t.cancel();
+
+ // Ensure proper sequence of exceptions
+ t = new Timer();
+ d = new Date(-100);
+ try {
+ t.scheduleAtFixedRate(null, d, 10);
+ fail("Scheduling a null task with negative date should throw IllegalArgumentException first");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure proper sequence of exceptions
+ t = new Timer();
+ try {
+ t.scheduleAtFixedRate(null, null, -10);
+ fail("Scheduling a null task & null date & negative period should throw IllegalArgumentException first");
+ } catch (IllegalArgumentException expected) {
+ }
+ t.cancel();
+
+ // Ensure a task is run at least twice
+ t = new Timer();
+ testTask = new TimerTestTask();
+ d = new Date(System.currentTimeMillis() + 100);
+ t.scheduleAtFixedRate(testTask, d, 100);
+ Thread.sleep(400);
+ assertTrue("TimerTask.run() method should have been called at least twice ("
+ + testTask.wasRun() + ")", testTask.wasRun() >= 2);
+ t.cancel();
+
+ class SlowThenFastTask extends TimerTask {
+ int wasRun = 0;
+
+ long startedAt;
+
+ long lastDelta;
+
+ public void run() {
+ if (wasRun == 0)
+ startedAt = System.currentTimeMillis();
+ lastDelta = System.currentTimeMillis()
+ - (startedAt + (100 * wasRun));
+ wasRun++;
+ if (wasRun == 2) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public long lastDelta() {
+ return lastDelta;
+ }
+
+ public int wasRun() {
+ return wasRun;
+ }
+ }
+
+ // Ensure multiple tasks are run
+ t = new Timer();
+ SlowThenFastTask slowThenFastTask = new SlowThenFastTask();
+ d = new Date(System.currentTimeMillis() + 100);
+
+ // at least 9 times even when asleep
+ t.scheduleAtFixedRate(slowThenFastTask, d, 100);
+ Thread.sleep(1000);
+ long lastDelta = slowThenFastTask.lastDelta();
+ assertTrue("Fixed Rate Schedule should catch up, but is off by "
+ + lastDelta + " ms", lastDelta < 300);
+ t.cancel();
+ } finally {
+ if (t != null)
+ t.cancel();
+ }
+ }
+
+ /**
+ * We used to swallow RuntimeExceptions thrown by tasks. Instead, we need to
+ * let those exceptions bubble up, where they will both notify the thread's
+ * uncaught exception handler and terminate the timer's thread.
+ */
+ public void testThrowingTaskKillsTimerThread() throws Exception {
+ final AtomicReference<Thread> threadRef = new AtomicReference<Thread>();
+ new Timer().schedule(new TimerTask() {
+ @Override public void run() {
+ Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
+ public void uncaughtException(Thread thread, Throwable ex) {}
+ });
+ threadRef.set(Thread.currentThread());
+ throw new RuntimeException("task failure!");
+ }
+ }, 1);
+
+ Thread.sleep(400);
+ Thread timerThread = threadRef.get();
+ assertFalse(timerThread.isAlive());
+ }
+
+ protected void setUp() {
+ timerCounter = 0;
+ }
+
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TooManyListenersExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TooManyListenersExceptionTest.java
new file mode 100644
index 0000000..6683e96
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TooManyListenersExceptionTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.TooManyListenersException;
+
+public class TooManyListenersExceptionTest extends junit.framework.TestCase {
+
+ /**
+ * java.util.TooManyListenersException#TooManyListenersException()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.TooManyListenersException()
+ try {
+ throw new TooManyListenersException();
+ } catch (TooManyListenersException e) {
+ assertNull(
+ "Message thrown with exception constructed with no message",
+ e.getMessage());
+ }
+ }
+
+ /**
+ * java.util.TooManyListenersException#TooManyListenersException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.util.TooManyListenersException(java.lang.String)
+ try {
+ throw new TooManyListenersException("Gah");
+ } catch (TooManyListenersException e) {
+ assertEquals("Incorrect message thrown with exception", "Gah", e
+ .getMessage());
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapExtendTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapExtendTest.java
new file mode 100644
index 0000000..5754468
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapExtendTest.java
@@ -0,0 +1,13581 @@
+package org.apache.harmony.tests.java.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import junit.framework.TestCase;
+import org.apache.harmony.tests.java.util.TreeMapTest.MockComparator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+
+//
+public class TreeMapExtendTest extends TestCase {
+
+ TreeMap tm;
+
+ TreeMap tm_comparator;
+
+ SortedMap subMap_default;
+
+ SortedMap subMap_startExcluded_endExcluded;
+
+ SortedMap subMap_startExcluded_endIncluded;
+
+ SortedMap subMap_startIncluded_endExcluded;
+
+ SortedMap subMap_startIncluded_endIncluded;
+
+ SortedMap subMap_default_beforeStart_100;
+
+ SortedMap subMap_default_afterEnd_109;
+
+ NavigableMap navigableMap_startExcluded_endExcluded;
+
+ NavigableMap navigableMap_startExcluded_endIncluded;
+
+ NavigableMap navigableMap_startIncluded_endExcluded;
+
+ NavigableMap navigableMap_startIncluded_endIncluded;
+
+ SortedMap subMap_default_comparator;
+
+ SortedMap subMap_startExcluded_endExcluded_comparator;
+
+ SortedMap subMap_startExcluded_endIncluded_comparator;
+
+ SortedMap subMap_startIncluded_endExcluded_comparator;
+
+ SortedMap subMap_startIncluded_endIncluded_comparator;
+
+ Object objArray[] = new Object[1000];
+
+ public void test_TreeMap_Constructor_Default() {
+ TreeMap treeMap = new TreeMap();
+ assertTrue(treeMap.isEmpty());
+ assertNull(treeMap.comparator());
+ assertEquals(0, treeMap.size());
+
+ try {
+ treeMap.firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ assertNull(treeMap.firstEntry());
+
+ try {
+ treeMap.lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ assertNull(treeMap.lastEntry());
+
+ try {
+ treeMap.ceilingKey(1);
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ assertNull(treeMap.ceilingEntry(1));
+
+ try {
+ treeMap.floorKey(1);
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ assertNull(treeMap.floorEntry(1));
+ assertNull(treeMap.lowerKey(1));
+ assertNull(treeMap.lowerEntry(1));
+ assertNull(treeMap.higherKey(1));
+ assertNull(treeMap.higherEntry(1));
+ assertFalse(treeMap.containsKey(1));
+ assertFalse(treeMap.containsValue(1));
+ assertNull(treeMap.get(1));
+
+ assertNull(treeMap.pollFirstEntry());
+ assertNull(treeMap.pollLastEntry());
+ assertEquals(0, treeMap.values().size());
+ }
+
+ public void test_TreeMap_Constructor_Comparator() {
+ MockComparator mockComparator = new MockComparator();
+ TreeMap treeMap = new TreeMap(mockComparator);
+
+ assertEquals(mockComparator, treeMap.comparator());
+ }
+
+ public void test_TreeMap_Constructor_Map() {
+ TreeMap treeMap = new TreeMap(tm);
+ assertEquals(tm.size(), treeMap.size());
+ assertEquals(tm.firstKey(), treeMap.firstKey());
+ assertEquals(tm.firstEntry(), treeMap.firstEntry());
+ assertEquals(tm.lastKey(), treeMap.lastKey());
+ assertEquals(tm.lastEntry(), treeMap.lastEntry());
+ assertEquals(tm.keySet(), treeMap.keySet());
+
+ String key = new Integer(100).toString();
+ assertEquals(tm.ceilingKey(key), treeMap.ceilingKey(key));
+ assertEquals(tm.ceilingEntry(key), treeMap.ceilingEntry(key));
+ assertEquals(tm.floorKey(key), treeMap.floorKey(key));
+ assertEquals(tm.floorEntry(key), treeMap.floorEntry(key));
+ assertEquals(tm.lowerKey(key), treeMap.lowerKey(key));
+ assertEquals(tm.lowerEntry(key), treeMap.lowerEntry(key));
+ assertEquals(tm.higherKey(key), treeMap.higherKey(key));
+ assertEquals(tm.higherEntry(key), treeMap.higherEntry(key));
+ assertEquals(tm.entrySet(), treeMap.entrySet());
+ }
+
+ public void test_TreeMap_Constructor_SortedMap() {
+ TreeMap treeMap = new TreeMap(subMap_default);
+ assertEquals(subMap_default.size(), treeMap.size());
+ assertEquals(subMap_default.firstKey(), treeMap.firstKey());
+ assertEquals(subMap_default.lastKey(), treeMap.lastKey());
+ assertEquals(subMap_default.keySet(), treeMap.keySet());
+ assertEquals(subMap_default.entrySet(), treeMap.entrySet());
+ }
+
+ public void test_TreeMap_clear() {
+ tm.clear();
+ assertEquals(0, tm.size());
+ }
+
+ public void test_TreeMap_clone() {
+ TreeMap cloneTreeMap = (TreeMap) tm.clone();
+ assertEquals(tm, cloneTreeMap);
+ }
+
+ public void test_SubMap_Constructor() {
+ }
+
+ public void test_SubMap_clear() {
+ subMap_default.clear();
+ assertEquals(0, subMap_default.size());
+ }
+
+ public void test_SubMap_comparator() {
+ assertEquals(tm.comparator(), subMap_default.comparator());
+ }
+
+ public void test_SubMap_containsKey() {
+ String key = null;
+ for (int counter = 101; counter < 109; counter++) {
+ key = objArray[counter].toString();
+ assertTrue("SubMap contains incorrect elements", subMap_default
+ .containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded.containsKey(key));
+ }
+
+ // Check boundary
+ key = objArray[100].toString();
+ assertTrue("SubMap contains incorrect elements", subMap_default
+ .containsKey(key));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded.containsKey(key));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded.containsKey(key));
+
+ key = objArray[109].toString();
+ assertFalse("SubMap contains incorrect elements", subMap_default
+ .containsKey(key));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded.containsKey(key));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded.containsKey(key));
+
+ // With Comparator
+ for (int counter = 101; counter < 109; counter++) {
+ key = objArray[counter].toString();
+ assertTrue("SubMap contains incorrect elements",
+ subMap_default_comparator.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded_comparator
+ .containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded_comparator
+ .containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded_comparator
+ .containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded_comparator
+ .containsKey(key));
+ }
+
+ // Check boundary
+ key = objArray[100].toString();
+ assertTrue("SubMap contains incorrect elements",
+ subMap_default_comparator.containsKey(key));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded_comparator.containsKey(key));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded_comparator.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded_comparator.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded_comparator.containsKey(key));
+
+ key = objArray[109].toString();
+ assertFalse("SubMap contains incorrect elements",
+ subMap_default_comparator.containsKey(key));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded_comparator.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded_comparator.containsKey(key));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded_comparator.containsKey(key));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded_comparator.containsKey(key));
+ }
+
+ public void test_SubMap_containsValue() {
+ Object value = null;
+ for (int counter = 101; counter < 109; counter++) {
+ value = objArray[counter];
+ assertTrue("SubMap contains incorrect elements", subMap_default
+ .containsValue(value));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded.containsValue(value));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded.containsValue(value));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded.containsValue(value));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded.containsValue(value));
+ }
+
+ // Check boundary
+ value = objArray[100];
+ assertTrue("SubMap contains incorrect elements", subMap_default
+ .containsValue(value));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded.containsValue(value));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded.containsValue(value));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded.containsValue(value));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded.containsValue(value));
+
+ value = objArray[109];
+ assertFalse("SubMap contains incorrect elements", subMap_default
+ .containsValue(value));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startExcluded_endExcluded.containsValue(value));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startExcluded_endIncluded.containsValue(value));
+ assertFalse("SubMap contains incorrect elements",
+ subMap_startIncluded_endExcluded.containsValue(value));
+ assertTrue("SubMap contains incorrect elements",
+ subMap_startIncluded_endIncluded.containsValue(value));
+
+ assertFalse(subMap_default.containsValue(null));
+
+ TreeMap tm_null = new TreeMap();
+ tm_null.put("0", 1);
+ tm_null.put("1", null);
+ tm_null.put("2", 2);
+ SortedMap subMap = tm_null.subMap("0", "2");
+ assertTrue(subMap.containsValue(null));
+
+ subMap.remove("1");
+ assertFalse(subMap.containsValue(null));
+ }
+
+ public void test_SubMap_entrySet() {
+ Set entrySet = subMap_default.entrySet();
+ assertFalse(entrySet.isEmpty());
+ assertEquals(9, entrySet.size());
+
+ entrySet = subMap_startExcluded_endExcluded.entrySet();
+ assertFalse(entrySet.isEmpty());
+ assertEquals(8, entrySet.size());
+
+ entrySet = subMap_startExcluded_endIncluded.entrySet();
+ assertFalse(entrySet.isEmpty());
+ assertEquals(9, entrySet.size());
+
+ entrySet = subMap_startIncluded_endExcluded.entrySet();
+ assertFalse(entrySet.isEmpty());
+ assertEquals(9, entrySet.size());
+
+ entrySet = subMap_startIncluded_endIncluded.entrySet();
+ assertFalse(entrySet.isEmpty());
+ assertEquals(10, entrySet.size());
+ }
+
+ public void test_SubMap_firstKey() {
+ String firstKey1 = new Integer(100).toString();
+ String firstKey2 = new Integer(101).toString();
+ assertEquals(firstKey1, subMap_default.firstKey());
+ assertEquals(firstKey2, subMap_startExcluded_endExcluded.firstKey());
+ assertEquals(firstKey2, subMap_startExcluded_endIncluded.firstKey());
+ assertEquals(firstKey1, subMap_startIncluded_endExcluded.firstKey());
+ assertEquals(firstKey1, subMap_startIncluded_endIncluded.firstKey());
+
+ try {
+ subMap_default.subMap(firstKey1, firstKey1).firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.subMap(firstKey2, firstKey2)
+ .firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded.subMap(firstKey2, firstKey2)
+ .firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded.subMap(firstKey1, firstKey1)
+ .firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded.subMap(firstKey1, firstKey1)
+ .firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ // With Comparator
+ assertEquals(firstKey1, subMap_default_comparator.firstKey());
+ assertEquals(firstKey2, subMap_startExcluded_endExcluded_comparator
+ .firstKey());
+ assertEquals(firstKey2, subMap_startExcluded_endIncluded_comparator
+ .firstKey());
+ assertEquals(firstKey1, subMap_startIncluded_endExcluded_comparator
+ .firstKey());
+ assertEquals(firstKey1, subMap_startIncluded_endIncluded_comparator
+ .firstKey());
+
+ try {
+ subMap_default_comparator.subMap(firstKey1, firstKey1).firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded_comparator.subMap(firstKey2,
+ firstKey2).firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded_comparator.subMap(firstKey2,
+ firstKey2).firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded_comparator.subMap(firstKey1,
+ firstKey1).firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded_comparator.subMap(firstKey1,
+ firstKey1).firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ }
+
+ public void test_SubMap_lastKey() {
+ String lastKey1 = new Integer(108).toString();
+ String lastKey2 = new Integer(109).toString();
+ assertEquals(lastKey1, subMap_default.lastKey());
+ assertEquals(lastKey1, subMap_startExcluded_endExcluded.lastKey());
+ assertEquals(lastKey2, subMap_startExcluded_endIncluded.lastKey());
+ assertEquals(lastKey1, subMap_startIncluded_endExcluded.lastKey());
+ assertEquals(lastKey2, subMap_startIncluded_endIncluded.lastKey());
+
+ try {
+ subMap_default.subMap(lastKey1, lastKey1).lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.subMap(lastKey1, lastKey1)
+ .lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded.subMap(lastKey2, lastKey2)
+ .lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded.subMap(lastKey1, lastKey1)
+ .lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded.subMap(lastKey2, lastKey2)
+ .lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ // With Comparator
+ assertEquals(lastKey1, subMap_default_comparator.lastKey());
+ assertEquals(lastKey1, subMap_startExcluded_endExcluded_comparator
+ .lastKey());
+ assertEquals(lastKey2, subMap_startExcluded_endIncluded_comparator
+ .lastKey());
+ assertEquals(lastKey1, subMap_startIncluded_endExcluded_comparator
+ .lastKey());
+ assertEquals(lastKey2, subMap_startIncluded_endIncluded_comparator
+ .lastKey());
+
+ try {
+ subMap_default_comparator.subMap(lastKey1, lastKey1).lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded_comparator.subMap(lastKey1,
+ lastKey1).lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded_comparator.subMap(lastKey2,
+ lastKey2).lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded_comparator.subMap(lastKey1,
+ lastKey1).lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded_comparator.subMap(lastKey2,
+ lastKey2).lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ public void test_SubMap_get() {
+ // left boundary
+ Integer value = new Integer(100);
+ assertEquals(value, subMap_default.get(value.toString()));
+ assertEquals(null, subMap_startExcluded_endExcluded.get(value
+ .toString()));
+ assertEquals(null, subMap_startExcluded_endIncluded.get(value
+ .toString()));
+ assertEquals(value, subMap_startIncluded_endExcluded.get(value
+ .toString()));
+ assertEquals(value, subMap_startIncluded_endIncluded.get(value
+ .toString()));
+
+ // normal value
+ value = new Integer(105);
+ assertEquals(value, subMap_default.get(value.toString()));
+ assertEquals(value, subMap_startExcluded_endExcluded.get(value
+ .toString()));
+ assertEquals(value, subMap_startExcluded_endIncluded.get(value
+ .toString()));
+ assertEquals(value, subMap_startIncluded_endExcluded.get(value
+ .toString()));
+ assertEquals(value, subMap_startIncluded_endIncluded.get(value
+ .toString()));
+
+ // right boundary
+ value = new Integer(109);
+ assertEquals(null, subMap_default.get(value.toString()));
+ assertEquals(null, subMap_startExcluded_endExcluded.get(value
+ .toString()));
+ assertEquals(value, subMap_startExcluded_endIncluded.get(value
+ .toString()));
+ assertEquals(null, subMap_startIncluded_endExcluded.get(value
+ .toString()));
+ assertEquals(value, subMap_startIncluded_endIncluded.get(value
+ .toString()));
+
+ // With Comparator to test inInRange
+ // left boundary
+ value = new Integer(100);
+ assertEquals(value, subMap_default_comparator.get(value.toString()));
+
+ // normal value
+ value = new Integer(105);
+ assertEquals(value, subMap_default_comparator.get(value.toString()));
+
+ // right boundary
+ value = new Integer(109);
+ assertEquals(null, subMap_default_comparator.get(value.toString()));
+ }
+
+ public void test_SubMap_headMap() {
+ String endKey = new Integer(99).toString();
+ try {
+ subMap_default.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ SortedMap headMap = null;
+ endKey = new Integer(100).toString();
+ headMap = subMap_default.headMap(endKey);
+ assertEquals(0, headMap.size());
+
+ try {
+ headMap = subMap_startExcluded_endExcluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ headMap = subMap_startExcluded_endIncluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ headMap = subMap_startIncluded_endExcluded.headMap(endKey);
+ assertEquals(0, headMap.size());
+
+ headMap = subMap_startIncluded_endIncluded.headMap(endKey);
+ assertEquals(0, headMap.size());
+
+ for (int i = 0, j = 101; i < 8; i++) {
+ endKey = new Integer(i + j).toString();
+ headMap = subMap_default.headMap(endKey);
+ assertEquals(i + 1, headMap.size());
+
+ headMap = subMap_startExcluded_endExcluded.headMap(endKey);
+ assertEquals(i, headMap.size());
+
+ headMap = subMap_startExcluded_endIncluded.headMap(endKey);
+ assertEquals(i, headMap.size());
+
+ headMap = subMap_startIncluded_endExcluded.headMap(endKey);
+ assertEquals(i + 1, headMap.size());
+
+ headMap = subMap_startIncluded_endIncluded.headMap(endKey);
+ assertEquals(i + 1, headMap.size());
+ }
+
+ endKey = new Integer(109).toString();
+ headMap = subMap_default.headMap(endKey);
+ assertEquals(9, headMap.size());
+
+ headMap = subMap_startExcluded_endExcluded.headMap(endKey);
+ assertEquals(8, headMap.size());
+
+ headMap = subMap_startExcluded_endIncluded.headMap(endKey);
+ assertEquals(8, headMap.size());
+
+ headMap = subMap_startIncluded_endExcluded.headMap(endKey);
+ assertEquals(9, headMap.size());
+
+ headMap = subMap_startIncluded_endIncluded.headMap(endKey);
+ assertEquals(9, headMap.size());
+
+ endKey = new Integer(110).toString();
+ try {
+ subMap_default.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // With Comparator
+ endKey = new Integer(99).toString();
+ try {
+ subMap_default_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ headMap = null;
+ endKey = new Integer(100).toString();
+ headMap = subMap_default_comparator.headMap(endKey);
+ assertEquals(0, headMap.size());
+
+ try {
+ headMap = subMap_startExcluded_endExcluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ headMap = subMap_startExcluded_endIncluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ headMap = subMap_startIncluded_endExcluded_comparator.headMap(endKey);
+ assertEquals(0, headMap.size());
+
+ headMap = subMap_startIncluded_endIncluded_comparator.headMap(endKey);
+ assertEquals(0, headMap.size());
+
+ for (int i = 0, j = 101; i < 8; i++) {
+ endKey = new Integer(i + j).toString();
+ headMap = subMap_default_comparator.headMap(endKey);
+ assertEquals(i + 1, headMap.size());
+
+ headMap = subMap_startExcluded_endExcluded_comparator
+ .headMap(endKey);
+ assertEquals(i, headMap.size());
+
+ headMap = subMap_startExcluded_endIncluded_comparator
+ .headMap(endKey);
+ assertEquals(i, headMap.size());
+
+ headMap = subMap_startIncluded_endExcluded_comparator
+ .headMap(endKey);
+ assertEquals(i + 1, headMap.size());
+
+ headMap = subMap_startIncluded_endIncluded_comparator
+ .headMap(endKey);
+ assertEquals(i + 1, headMap.size());
+ }
+
+ endKey = new Integer(108).toString();
+ headMap = subMap_default_comparator.headMap(endKey);
+ assertEquals(8, headMap.size());
+
+ headMap = subMap_startExcluded_endExcluded_comparator.headMap(endKey);
+ assertEquals(7, headMap.size());
+
+ headMap = subMap_startExcluded_endIncluded_comparator.headMap(endKey);
+ assertEquals(7, headMap.size());
+
+ headMap = subMap_startIncluded_endExcluded_comparator.headMap(endKey);
+ assertEquals(8, headMap.size());
+
+ headMap = subMap_startIncluded_endIncluded_comparator.headMap(endKey);
+ assertEquals(8, headMap.size());
+
+ endKey = new Integer(110).toString();
+ try {
+ subMap_default_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded_comparator.headMap(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void test_SubMap_isEmpty() {
+ assertFalse(subMap_default.isEmpty());
+ assertFalse(subMap_startExcluded_endExcluded.isEmpty());
+ assertFalse(subMap_startExcluded_endIncluded.isEmpty());
+ assertFalse(subMap_startIncluded_endExcluded.isEmpty());
+ assertFalse(subMap_startIncluded_endIncluded.isEmpty());
+
+ Object startKey = new Integer(100);
+ Object endKey = startKey;
+ SortedMap subMap = tm.subMap(startKey.toString(), endKey.toString());
+ assertTrue(subMap.isEmpty());
+ subMap = subMap_default.subMap(startKey.toString(), endKey.toString());
+ assertTrue(subMap.isEmpty());
+ subMap = subMap_startIncluded_endExcluded.subMap(startKey.toString(),
+ endKey.toString());
+ assertTrue(subMap.isEmpty());
+ subMap = subMap_startIncluded_endIncluded.subMap(startKey.toString(),
+ endKey.toString());
+ assertTrue(subMap.isEmpty());
+
+ for (int i = 0, j = 101; i < 8; i++) {
+ startKey = i + j;
+ endKey = startKey;
+
+ subMap = subMap_default.subMap(startKey.toString(), endKey
+ .toString());
+ assertTrue(subMap.isEmpty());
+
+ subMap = subMap_startExcluded_endExcluded.subMap(startKey
+ .toString(), endKey.toString());
+ assertTrue(subMap.isEmpty());
+
+ subMap = subMap_startExcluded_endIncluded.subMap(startKey
+ .toString(), endKey.toString());
+ assertTrue(subMap.isEmpty());
+
+ subMap = subMap_startIncluded_endExcluded.subMap(startKey
+ .toString(), endKey.toString());
+ assertTrue(subMap.isEmpty());
+
+ subMap = subMap_startIncluded_endIncluded.subMap(startKey
+ .toString(), endKey.toString());
+ assertTrue(subMap.isEmpty());
+ }
+
+ for (int i = 0, j = 101; i < 5; i++) {
+ startKey = i + j;
+ endKey = i + j + 4;
+
+ subMap = subMap_default.subMap(startKey.toString(), endKey
+ .toString());
+ assertFalse(subMap.isEmpty());
+
+ subMap = subMap_startExcluded_endExcluded.subMap(startKey
+ .toString(), endKey.toString());
+ assertFalse(subMap.isEmpty());
+
+ subMap = subMap_startExcluded_endIncluded.subMap(startKey
+ .toString(), endKey.toString());
+ assertFalse(subMap.isEmpty());
+
+ subMap = subMap_startIncluded_endExcluded.subMap(startKey
+ .toString(), endKey.toString());
+ assertFalse(subMap.isEmpty());
+
+ subMap = subMap_startIncluded_endIncluded.subMap(startKey
+ .toString(), endKey.toString());
+ assertFalse(subMap.isEmpty());
+ }
+
+ startKey = new Integer(109).toString();
+ endKey = startKey;
+ subMap = tm.subMap(startKey.toString(), endKey.toString());
+ assertTrue(subMap.isEmpty());
+ subMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey);
+ assertTrue(subMap.isEmpty());
+ subMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey);
+ assertTrue(subMap.isEmpty());
+
+ }
+
+ public void test_SubMap_keySet() {
+ Set keySet = subMap_default.keySet();
+ assertFalse(keySet.isEmpty());
+ assertEquals(9, keySet.size());
+
+ keySet = subMap_startExcluded_endExcluded.entrySet();
+ assertFalse(keySet.isEmpty());
+ assertEquals(8, keySet.size());
+
+ keySet = subMap_startExcluded_endIncluded.entrySet();
+ assertFalse(keySet.isEmpty());
+ assertEquals(9, keySet.size());
+
+ keySet = subMap_startIncluded_endExcluded.entrySet();
+ assertFalse(keySet.isEmpty());
+ assertEquals(9, keySet.size());
+
+ keySet = subMap_startIncluded_endIncluded.entrySet();
+ assertFalse(keySet.isEmpty());
+ assertEquals(10, keySet.size());
+ }
+
+ public void test_SubMap_put() {
+ Integer value = new Integer(100);
+ int addValue = 5;
+
+ subMap_default.put(value.toString(), value + addValue);
+ assertEquals(value + addValue, subMap_default.get(value.toString()));
+
+ try {
+ subMap_startExcluded_endExcluded.put(value.toString(), value
+ + addValue);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded.put(value.toString(), value
+ + addValue);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ subMap_startIncluded_endExcluded
+ .put(value.toString(), value + addValue);
+ assertEquals(value + addValue, subMap_startIncluded_endExcluded
+ .get(value.toString()));
+
+ subMap_startIncluded_endIncluded
+ .put(value.toString(), value + addValue);
+ assertEquals(value + addValue, subMap_startIncluded_endIncluded
+ .get(value.toString()));
+
+ value = new Integer(109);
+ try {
+ subMap_default.put(value.toString(), value + addValue);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.put(value.toString(), value
+ + addValue);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ subMap_startExcluded_endIncluded
+ .put(value.toString(), value + addValue);
+ assertEquals(value + addValue, subMap_startExcluded_endIncluded
+ .get(value.toString()));
+
+ try {
+ subMap_startIncluded_endExcluded.put(value.toString(), value
+ + addValue);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ subMap_startIncluded_endIncluded
+ .put(value.toString(), value + addValue);
+ assertEquals(value + addValue, subMap_startIncluded_endIncluded
+ .get(value.toString()));
+ }
+
+ public void test_SubMap_remove() {
+ Integer value = new Integer(100);
+
+ subMap_default.remove(value.toString());
+ assertNull(subMap_default.get(value.toString()));
+
+ subMap_startExcluded_endExcluded.remove(value.toString());
+ assertNull(subMap_startExcluded_endExcluded.get(value.toString()));
+
+ subMap_startExcluded_endIncluded.remove(value.toString());
+ assertNull(subMap_startExcluded_endIncluded.get(value.toString()));
+
+ subMap_startIncluded_endExcluded.remove(value.toString());
+ assertNull(subMap_startIncluded_endExcluded.get(value.toString()));
+
+ subMap_startIncluded_endIncluded.remove(value.toString());
+ assertNull(subMap_startIncluded_endIncluded.get(value.toString()));
+
+ value = new Integer(109);
+ subMap_default.remove(value.toString());
+ assertNull(subMap_default.get(value.toString()));
+
+ subMap_startExcluded_endExcluded.remove(value.toString());
+ assertNull(subMap_startExcluded_endExcluded.get(value.toString()));
+
+ subMap_startExcluded_endIncluded.remove(value.toString());
+ assertNull(subMap_startExcluded_endIncluded.get(value.toString()));
+
+ subMap_startIncluded_endExcluded.remove(value.toString());
+ assertNull(subMap_startIncluded_endExcluded.get(value.toString()));
+
+ subMap_startIncluded_endIncluded.remove(value.toString());
+ assertNull(subMap_startIncluded_endIncluded.get(value.toString()));
+ }
+
+ public void test_SubMap_subMap_NoComparator() {
+ String startKey = new Integer[100].toString();
+ String endKey = new Integer[100].toString();
+ try {
+ subMap_default.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ SortedMap subSubMap = null;
+ for (int i = 101; i < 109; i++) {
+ startKey = new Integer(i).toString();
+ endKey = startKey;
+
+ subSubMap = subMap_default.subMap(startKey, endKey);
+ assertEquals(0, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endExcluded.subMap(startKey,
+ endKey);
+ assertEquals(0, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endIncluded.subMap(startKey,
+ endKey);
+ assertEquals(0, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endExcluded.subMap(startKey,
+ endKey);
+ assertEquals(0, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endIncluded.subMap(startKey,
+ endKey);
+ assertEquals(0, subSubMap.size());
+ }
+
+ for (int i = 101, j = 5; i < 105; i++) {
+ startKey = new Integer(i).toString();
+ endKey = new Integer(i + j).toString();
+
+ subSubMap = subMap_default.subMap(startKey, endKey);
+ assertEquals(j, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endExcluded.subMap(startKey,
+ endKey);
+ assertEquals(j, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endIncluded.subMap(startKey,
+ endKey);
+ assertEquals(j, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endExcluded.subMap(startKey,
+ endKey);
+ assertEquals(j, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endIncluded.subMap(startKey,
+ endKey);
+ assertEquals(j, subSubMap.size());
+ }
+
+ startKey = new Integer(108).toString();
+ endKey = new Integer(109).toString();
+
+ subSubMap = subMap_default.subMap(startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endExcluded.subMap(startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endExcluded.subMap(startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ startKey = new Integer(109).toString();
+ endKey = new Integer(109).toString();
+
+ try {
+ subMap_default.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey);
+ assertEquals(0, subSubMap.size());
+
+ try {
+ subMap_startIncluded_endExcluded.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey);
+ assertEquals(0, subSubMap.size());
+ }
+
+ public void test_SubMap_subMap_Comparator() {
+ String startKey = new Integer[100].toString();
+ String endKey = new Integer[100].toString();
+ try {
+ subMap_default_comparator.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded_comparator
+ .subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded_comparator
+ .subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded_comparator
+ .subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded_comparator
+ .subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ SortedMap subSubMap = null;
+ for (int i = 101; i < 109; i++) {
+ startKey = new Integer(i).toString();
+ endKey = startKey;
+
+ subSubMap = subMap_default_comparator.subMap(startKey, endKey);
+ assertEquals(0, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endExcluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(0, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endIncluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(0, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endExcluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(0, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endIncluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(0, subSubMap.size());
+ }
+
+ for (int i = 101, j = 5; i < 105; i++) {
+ startKey = new Integer(i).toString();
+ endKey = new Integer(i + j).toString();
+
+ subSubMap = subMap_default_comparator.subMap(startKey, endKey);
+ assertEquals(j, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endExcluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(j, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endIncluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(j, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endExcluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(j, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endIncluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(j, subSubMap.size());
+ }
+
+ startKey = new Integer(108).toString();
+ endKey = new Integer(109).toString();
+
+ subSubMap = subMap_default_comparator.subMap(startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endExcluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ subSubMap = subMap_startExcluded_endIncluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endExcluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ subSubMap = subMap_startIncluded_endIncluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(1, subSubMap.size());
+
+ startKey = new Integer(109).toString();
+ endKey = new Integer(109).toString();
+
+ try {
+ subMap_default_comparator.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded_comparator
+ .subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ subSubMap = subMap_startExcluded_endIncluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(0, subSubMap.size());
+
+ try {
+ subMap_startIncluded_endExcluded_comparator
+ .subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ subSubMap = subMap_startIncluded_endIncluded_comparator.subMap(
+ startKey, endKey);
+ assertEquals(0, subSubMap.size());
+ }
+
+ public void test_SubMap_tailMap() {
+ String startKey = new Integer(99).toString();
+ try {
+ subMap_default.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endExcluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startIncluded_endIncluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ SortedMap tailMap = null;
+
+ startKey = new Integer(100).toString();
+ tailMap = subMap_default.tailMap(startKey);
+ assertEquals(9, tailMap.size());
+
+ try {
+ subMap_startExcluded_endExcluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endIncluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ tailMap = subMap_startIncluded_endExcluded.tailMap(startKey);
+ assertEquals(9, tailMap.size());
+
+ tailMap = subMap_startIncluded_endIncluded.tailMap(startKey);
+ assertEquals(10, tailMap.size());
+
+ for (int i = 0, j = 101, end = 8; i < end; i++) {
+ startKey = new Integer(i + j).toString();
+ tailMap = subMap_default.tailMap(startKey);
+ assertEquals(end - i, tailMap.size());
+
+ tailMap = subMap_startExcluded_endExcluded.tailMap(startKey);
+ assertEquals(end - i, tailMap.size());
+
+ tailMap = subMap_startExcluded_endIncluded.tailMap(startKey);
+ assertEquals(end - i + 1, tailMap.size());
+
+ tailMap = subMap_startIncluded_endExcluded.tailMap(startKey);
+ assertEquals(end - i, tailMap.size());
+
+ tailMap = subMap_startIncluded_endIncluded.tailMap(startKey);
+ assertEquals(end - i + 1, tailMap.size());
+ }
+
+ startKey = new Integer(109).toString();
+ try {
+ subMap_default.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ subMap_startExcluded_endExcluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ tailMap = subMap_startExcluded_endIncluded.tailMap(startKey);
+ assertEquals(1, tailMap.size());
+
+ try {
+ subMap_startIncluded_endExcluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ tailMap = subMap_startIncluded_endIncluded.tailMap(startKey);
+ assertEquals(1, tailMap.size());
+
+ startKey = new Integer(110).toString();
+ try {
+ subMap_default.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ subMap_startExcluded_endExcluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ subMap_startExcluded_endIncluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ subMap_startIncluded_endExcluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ subMap_startIncluded_endIncluded.tailMap(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void test_SubMap_values() {
+ Collection values = subMap_default.values();
+
+ assertFalse(values.isEmpty());
+ assertTrue(values.contains(100));
+ for (int i = 101; i < 109; i++) {
+ assertTrue(values.contains(i));
+ }
+ assertFalse(values.contains(109));
+
+ values = subMap_startExcluded_endExcluded.values();
+ assertFalse(values.isEmpty());
+ assertFalse(values.contains(100));
+ for (int i = 101; i < 109; i++) {
+ assertTrue(values.contains(i));
+ }
+ assertFalse(values.contains(109));
+
+ values = subMap_startExcluded_endIncluded.values();
+ assertFalse(values.isEmpty());
+ assertFalse(values.contains(100));
+ for (int i = 101; i < 109; i++) {
+ assertTrue(values.contains(i));
+ }
+ assertTrue(values.contains(109));
+
+ values = subMap_startIncluded_endExcluded.values();
+ assertFalse(values.isEmpty());
+ assertTrue(values.contains(100));
+ for (int i = 101; i < 109; i++) {
+ assertTrue(values.contains(i));
+ }
+ assertFalse(values.contains(109));
+
+ values = subMap_startIncluded_endIncluded.values();
+ assertFalse(values.isEmpty());
+ assertTrue(values.contains(100));
+ for (int i = 100; i < 109; i++) {
+ assertTrue(values.contains(i));
+ }
+ assertTrue(values.contains(109));
+ }
+
+ public void test_SubMap_size() {
+ assertEquals(9, subMap_default.size());
+ assertEquals(8, subMap_startExcluded_endExcluded.size());
+ assertEquals(9, subMap_startExcluded_endIncluded.size());
+ assertEquals(9, subMap_startIncluded_endExcluded.size());
+ assertEquals(10, subMap_startIncluded_endIncluded.size());
+
+ assertEquals(9, subMap_default_comparator.size());
+ assertEquals(8, subMap_startExcluded_endExcluded_comparator.size());
+ assertEquals(9, subMap_startExcluded_endIncluded_comparator.size());
+ assertEquals(9, subMap_startIncluded_endExcluded_comparator.size());
+ assertEquals(10, subMap_startIncluded_endIncluded_comparator.size());
+ }
+
+ public void test_SubMap_readObject() throws Exception {
+ // SerializationTest.verifySelf(subMap_default);
+ // SerializationTest.verifySelf(subMap_startExcluded_endExcluded);
+ // SerializationTest.verifySelf(subMap_startExcluded_endIncluded);
+ // SerializationTest.verifySelf(subMap_startIncluded_endExcluded);
+ // SerializationTest.verifySelf(subMap_startIncluded_endIncluded);
+ }
+
+ public void test_AscendingSubMap_ceilingEntry() {
+ String key = new Integer(99).toString();
+ assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key));
+ assertNull(navigableMap_startExcluded_endIncluded.ceilingEntry(key));
+ assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key));
+ assertNull(navigableMap_startIncluded_endIncluded.ceilingEntry(key));
+
+ key = new Integer(100).toString();
+ assertEquals(101, navigableMap_startExcluded_endExcluded.ceilingEntry(
+ key).getValue());
+ assertEquals(101, navigableMap_startExcluded_endIncluded.ceilingEntry(
+ key).getValue());
+ assertEquals(100, navigableMap_startIncluded_endExcluded.ceilingEntry(
+ key).getValue());
+ assertEquals(100, navigableMap_startIncluded_endIncluded.ceilingEntry(
+ key).getValue());
+
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, navigableMap_startExcluded_endExcluded
+ .ceilingEntry(key).getValue());
+ assertEquals(i, navigableMap_startExcluded_endIncluded
+ .ceilingEntry(key).getValue());
+ assertEquals(i, navigableMap_startIncluded_endExcluded
+ .ceilingEntry(key).getValue());
+ assertEquals(i, navigableMap_startIncluded_endIncluded
+ .ceilingEntry(key).getValue());
+
+ }
+
+ key = new Integer(109).toString();
+ assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key));
+ assertEquals(109, navigableMap_startExcluded_endIncluded.ceilingEntry(
+ key).getValue());
+ assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key));
+ assertEquals(109, navigableMap_startIncluded_endIncluded.ceilingEntry(
+ key).getValue());
+
+ key = new Integer(110).toString();
+ assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key));
+ assertNull(navigableMap_startExcluded_endIncluded.ceilingEntry(key));
+ assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key));
+ assertNull(navigableMap_startIncluded_endIncluded.ceilingEntry(key));
+ }
+
+ public void test_AscendingSubMap_descendingMap() {
+ NavigableMap descendingMap = navigableMap_startExcluded_endExcluded
+ .descendingMap();
+ assertEquals(navigableMap_startExcluded_endExcluded.size(),
+ descendingMap.size());
+ assertNotNull(descendingMap.comparator());
+
+ assertEquals(navigableMap_startExcluded_endExcluded.firstKey(),
+ descendingMap.lastKey());
+ assertEquals(navigableMap_startExcluded_endExcluded.firstEntry(),
+ descendingMap.lastEntry());
+
+ assertEquals(navigableMap_startExcluded_endExcluded.lastKey(),
+ descendingMap.firstKey());
+ assertEquals(navigableMap_startExcluded_endExcluded.lastEntry(),
+ descendingMap.firstEntry());
+
+ descendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ assertEquals(navigableMap_startExcluded_endIncluded.size(),
+ descendingMap.size());
+ assertNotNull(descendingMap.comparator());
+
+ assertEquals(navigableMap_startExcluded_endIncluded.firstKey(),
+ descendingMap.lastKey());
+ assertEquals(navigableMap_startExcluded_endIncluded.firstEntry(),
+ descendingMap.lastEntry());
+
+ assertEquals(navigableMap_startExcluded_endIncluded.lastKey(),
+ descendingMap.firstKey());
+ assertEquals(navigableMap_startExcluded_endIncluded.lastEntry(),
+ descendingMap.firstEntry());
+
+ descendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ assertEquals(navigableMap_startIncluded_endExcluded.size(),
+ descendingMap.size());
+ assertNotNull(descendingMap.comparator());
+
+ assertEquals(navigableMap_startIncluded_endExcluded.firstKey(),
+ descendingMap.lastKey());
+ assertEquals(navigableMap_startIncluded_endExcluded.firstEntry(),
+ descendingMap.lastEntry());
+
+ assertEquals(navigableMap_startIncluded_endExcluded.lastKey(),
+ descendingMap.firstKey());
+ assertEquals(navigableMap_startIncluded_endExcluded.lastEntry(),
+ descendingMap.firstEntry());
+
+ descendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ assertEquals(navigableMap_startIncluded_endIncluded.size(),
+ descendingMap.size());
+ assertNotNull(descendingMap.comparator());
+
+ assertEquals(navigableMap_startIncluded_endIncluded.firstKey(),
+ descendingMap.lastKey());
+ assertEquals(navigableMap_startIncluded_endIncluded.firstEntry(),
+ descendingMap.lastEntry());
+
+ assertEquals(navigableMap_startIncluded_endIncluded.lastKey(),
+ descendingMap.firstKey());
+ assertEquals(navigableMap_startIncluded_endIncluded.lastEntry(),
+ descendingMap.firstEntry());
+ }
+
+ public void test_AscendingSubMap_floorEntry() {
+ String key = new Integer(99).toString();
+ assertEquals(108, navigableMap_startExcluded_endExcluded
+ .floorEntry(key).getValue());
+ assertEquals(109, navigableMap_startExcluded_endIncluded
+ .floorEntry(key).getValue());
+ assertEquals(108, navigableMap_startIncluded_endExcluded
+ .floorEntry(key).getValue());
+ assertEquals(109, navigableMap_startIncluded_endIncluded
+ .floorEntry(key).getValue());
+
+ key = new Integer(100).toString();
+ assertNull(navigableMap_startExcluded_endExcluded.floorEntry(key));
+ assertNull(navigableMap_startExcluded_endIncluded.floorEntry(key));
+ assertEquals(100, navigableMap_startIncluded_endExcluded
+ .floorEntry(key).getValue());
+ assertEquals(100, navigableMap_startIncluded_endIncluded
+ .floorEntry(key).getValue());
+
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, navigableMap_startExcluded_endExcluded.floorEntry(
+ key).getValue());
+ assertEquals(i, navigableMap_startExcluded_endIncluded.floorEntry(
+ key).getValue());
+ assertEquals(i, navigableMap_startIncluded_endExcluded.floorEntry(
+ key).getValue());
+ assertEquals(i, navigableMap_startIncluded_endIncluded.floorEntry(
+ key).getValue());
+
+ }
+
+ key = new Integer(109).toString();
+ assertEquals(108, navigableMap_startExcluded_endExcluded
+ .floorEntry(key).getValue());
+ assertEquals(109, navigableMap_startExcluded_endIncluded
+ .floorEntry(key).getValue());
+ assertEquals(108, navigableMap_startIncluded_endExcluded
+ .floorEntry(key).getValue());
+ assertEquals(109, navigableMap_startIncluded_endIncluded
+ .floorEntry(key).getValue());
+
+ key = new Integer(110).toString();
+ assertEquals(108, navigableMap_startExcluded_endExcluded
+ .floorEntry(key).getValue());
+ assertEquals(109, navigableMap_startExcluded_endIncluded
+ .floorEntry(key).getValue());
+ assertEquals(108, navigableMap_startIncluded_endExcluded
+ .floorEntry(key).getValue());
+ assertEquals(109, navigableMap_startIncluded_endIncluded
+ .floorEntry(key).getValue());
+ }
+
+ public void test_AscendingSubMap_pollFirstEntry() {
+ assertEquals(101, navigableMap_startExcluded_endExcluded
+ .pollFirstEntry().getValue());
+ assertEquals(102, navigableMap_startExcluded_endIncluded
+ .pollFirstEntry().getValue());
+ assertEquals(100, navigableMap_startIncluded_endExcluded
+ .pollFirstEntry().getValue());
+ assertEquals(103, navigableMap_startIncluded_endIncluded
+ .pollFirstEntry().getValue());
+ }
+
+ public void test_AscendingSubMap_pollLastEntry() {
+ assertEquals(108, navigableMap_startExcluded_endExcluded
+ .pollLastEntry().getValue());
+ assertEquals(109, navigableMap_startExcluded_endIncluded
+ .pollLastEntry().getValue());
+ assertEquals(107, navigableMap_startIncluded_endExcluded
+ .pollLastEntry().getValue());
+ assertEquals(106, navigableMap_startIncluded_endIncluded
+ .pollLastEntry().getValue());
+ }
+
+ public void test_AscendingSubMap_entrySet() {
+ assertEquals(8, navigableMap_startExcluded_endExcluded.entrySet()
+ .size());
+ assertEquals(9, navigableMap_startExcluded_endIncluded.entrySet()
+ .size());
+ assertEquals(9, navigableMap_startIncluded_endExcluded.entrySet()
+ .size());
+ assertEquals(10, navigableMap_startIncluded_endIncluded.entrySet()
+ .size());
+ }
+
+ public void test_AscendingSubMap_subMap() {
+ Set entrySet;
+ Entry startEntry, endEntry;
+ int startIndex, endIndex;
+ SortedMap subMap;
+ Iterator subMapSetIterator;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ Iterator startIterator = entrySet.iterator();
+ while (startIterator.hasNext()) {
+ startEntry = (Entry) startIterator.next();
+ startIndex = (Integer) startEntry.getValue();
+ Iterator endIterator = entrySet.iterator();
+ while (endIterator.hasNext()) {
+ endEntry = (Entry) endIterator.next();
+ endIndex = (Integer) endEntry.getValue();
+
+ if (startIndex > endIndex) {
+ try {
+ navigableMap_startExcluded_endExcluded.subMap(
+ startEntry.getKey(), endEntry.getKey());
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ navigableMap_startExcluded_endExcluded.subMap(
+ startEntry.getKey(), false, endEntry.getKey(),
+ false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ navigableMap_startExcluded_endExcluded.subMap(
+ startEntry.getKey(), false, endEntry.getKey(),
+ true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ navigableMap_startExcluded_endExcluded.subMap(
+ startEntry.getKey(), true, endEntry.getKey(),
+ false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ navigableMap_startExcluded_endExcluded.subMap(
+ startEntry.getKey(), true, endEntry.getKey(),
+ true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } else {
+ subMap = navigableMap_startExcluded_endExcluded.subMap(
+ startEntry.getKey(), endEntry.getKey());
+ subMapSetIterator = subMap.entrySet().iterator();
+ for (int index = startIndex; index < endIndex; index++) {
+ assertEquals(index, ((Entry) subMapSetIterator.next())
+ .getValue());
+ }
+
+ subMap = navigableMap_startExcluded_endExcluded.subMap(
+ startEntry.getKey(), false, endEntry.getKey(),
+ false);
+ subMapSetIterator = subMap.entrySet().iterator();
+ for (int index = startIndex + 1; index < endIndex; index++) {
+ assertEquals(index, ((Entry) subMapSetIterator.next())
+ .getValue());
+ }
+
+ subMap = navigableMap_startExcluded_endExcluded
+ .subMap(startEntry.getKey(), false, endEntry
+ .getKey(), true);
+ subMapSetIterator = subMap.entrySet().iterator();
+ for (int index = startIndex + 1; index < endIndex; index++) {
+ assertEquals(index, ((Entry) subMapSetIterator.next())
+ .getValue());
+ }
+
+ subMap = navigableMap_startExcluded_endExcluded
+ .subMap(startEntry.getKey(), true, endEntry
+ .getKey(), false);
+ subMapSetIterator = subMap.entrySet().iterator();
+ for (int index = startIndex; index < endIndex; index++) {
+ assertEquals(index, ((Entry) subMapSetIterator.next())
+ .getValue());
+ }
+
+ subMap = navigableMap_startExcluded_endExcluded.subMap(
+ startEntry.getKey(), true, endEntry.getKey(), true);
+ subMapSetIterator = subMap.entrySet().iterator();
+ for (int index = startIndex; index <= endIndex; index++) {
+ assertEquals(index, ((Entry) subMapSetIterator.next())
+ .getValue());
+ }
+ }
+ }
+ }
+ }
+
+ public void test_DescendingSubMap_ceilingEntry() {
+ NavigableMap decendingMap = tm.descendingMap();
+ String key = new Integer(-1).toString();
+ assertNull(decendingMap.ceilingEntry(key));
+ for (int i = 0; i < objArray.length; i++) {
+ key = objArray[i].toString();
+ assertEquals(objArray[i], decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(1000).toString();
+ assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+ key = new Integer(1001).toString();
+ assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ key = new Integer(100).toString();
+ assertNull(decendingMap.ceilingEntry(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(108, decendingMap.ceilingEntry(key).getValue());
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ key = new Integer(100).toString();
+ assertNull(decendingMap.ceilingEntry(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(109, decendingMap.ceilingEntry(key).getValue());
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(108, decendingMap.ceilingEntry(key).getValue());
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(109, decendingMap.ceilingEntry(key).getValue());
+
+ // With Comparator
+ decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .descendingMap();
+ key = new Integer(100).toString();
+ assertNull(decendingMap.ceilingEntry(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(108, decendingMap.ceilingEntry(key).getValue());
+
+ decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .descendingMap();
+ key = new Integer(100).toString();
+ assertNull(decendingMap.ceilingEntry(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(109, decendingMap.ceilingEntry(key).getValue());
+
+ decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+ .descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(108, decendingMap.ceilingEntry(key).getValue());
+
+ decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+ .descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(109, decendingMap.ceilingEntry(key).getValue());
+ }
+
+ public void test_DescendingSubMap_descendingMap() {
+ NavigableMap decendingMap = tm.descendingMap();
+ NavigableMap decendingDecendingMap = decendingMap.descendingMap();
+ assertEquals(decendingMap, decendingDecendingMap);
+
+ NavigableMap decendingMapHeadMap = decendingMap.headMap(
+ new Integer(990).toString(), false);
+ NavigableMap decendingDecendingHeadMap = decendingMapHeadMap
+ .descendingMap();
+ assertNotNull(decendingMapHeadMap);
+ assertNotNull(decendingDecendingHeadMap);
+ assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+ NavigableMap decendingMapTailMap = decendingMap.tailMap(
+ new Integer(990).toString(), false);
+ NavigableMap decendingDecendingTailMap = decendingMapTailMap
+ .descendingMap();
+ assertNotNull(decendingMapTailMap);
+ assertNotNull(decendingDecendingTailMap);
+ // assertEquals(decendingMapTailMap,decendingDecendingTailMap);
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ decendingDecendingMap = decendingMap.descendingMap();
+ assertEquals(decendingMap, decendingDecendingMap);
+
+ decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(),
+ false);
+ decendingDecendingHeadMap = decendingMapHeadMap.descendingMap();
+ assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+ decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(),
+ false);
+ decendingDecendingTailMap = decendingMapTailMap.descendingMap();
+ assertEquals(decendingMapTailMap, decendingDecendingTailMap);
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ decendingDecendingMap = decendingMap.descendingMap();
+ assertEquals(decendingMap, decendingDecendingMap);
+
+ decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(),
+ false);
+ decendingDecendingHeadMap = decendingMapHeadMap.descendingMap();
+ assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+ decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(),
+ false);
+ decendingDecendingTailMap = decendingMapTailMap.descendingMap();
+ assertEquals(decendingMapTailMap, decendingDecendingTailMap);
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ decendingDecendingMap = decendingMap.descendingMap();
+ assertEquals(decendingMap, decendingDecendingMap);
+
+ decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(),
+ false);
+ decendingDecendingHeadMap = decendingMapHeadMap.descendingMap();
+ assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+ decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(),
+ false);
+ decendingDecendingTailMap = decendingMapTailMap.descendingMap();
+ assertEquals(decendingMapTailMap, decendingDecendingTailMap);
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ decendingDecendingMap = decendingMap.descendingMap();
+ assertEquals(decendingMap, decendingDecendingMap);
+
+ decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(),
+ false);
+ decendingDecendingHeadMap = decendingMapHeadMap.descendingMap();
+ assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+ decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(),
+ false);
+ decendingDecendingTailMap = decendingMapTailMap.descendingMap();
+ assertEquals(decendingMapTailMap, decendingDecendingTailMap);
+ }
+
+ public void test_DescendingSubMap_firstEntry() {
+ NavigableMap decendingMap = tm.descendingMap();
+ assertEquals(999, decendingMap.firstEntry().getValue());
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ assertEquals(108, decendingMap.firstEntry().getValue());
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ assertEquals(109, decendingMap.firstEntry().getValue());
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ assertEquals(108, decendingMap.firstEntry().getValue());
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ assertEquals(109, decendingMap.firstEntry().getValue());
+ }
+
+ public void test_DescendingSubMap_floorEntry() {
+ NavigableMap decendingMap = tm.descendingMap();
+ String key = new Integer(-1).toString();
+ assertEquals(0, decendingMap.floorEntry(key).getValue());
+ for (int i = 0; i < objArray.length; i++) {
+ key = objArray[i].toString();
+ assertEquals(objArray[i], decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(1000).toString();
+ assertEquals(101, decendingMap.floorEntry(key).getValue());
+ key = new Integer(1001).toString();
+ assertEquals(101, decendingMap.floorEntry(key).getValue());
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(101, decendingMap.floorEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertNull(decendingMap.floorEntry(key));
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(101, decendingMap.floorEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(109, decendingMap.floorEntry(key).getValue());
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(100, decendingMap.floorEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertNull(decendingMap.floorEntry(key));
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(100, decendingMap.floorEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(109, decendingMap.floorEntry(key).getValue());
+
+ // With Comparator
+ decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(101, decendingMap.floorEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertNull(decendingMap.floorEntry(key));
+
+ decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(101, decendingMap.floorEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(109, decendingMap.floorEntry(key).getValue());
+
+ decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+ .descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(100, decendingMap.floorEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertNull(decendingMap.floorEntry(key));
+
+ decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+ .descendingMap();
+ key = new Integer(100).toString();
+ assertEquals(100, decendingMap.floorEntry(key).getValue());
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertEquals(i, decendingMap.floorEntry(key).getValue());
+ }
+ key = new Integer(109).toString();
+ assertEquals(109, decendingMap.floorEntry(key).getValue());
+ }
+
+ public void test_DescendingSubMap_lastEntry() {
+ NavigableMap decendingMap = tm.descendingMap();
+ assertEquals(0, decendingMap.lastEntry().getValue());
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ assertEquals(101, decendingMap.lastEntry().getValue());
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ assertEquals(101, decendingMap.lastEntry().getValue());
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ assertEquals(100, decendingMap.lastEntry().getValue());
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ assertEquals(100, decendingMap.lastEntry().getValue());
+ }
+
+ public void test_DescendingSubMap_higherEntry() {
+ NavigableMap decendingMap;
+ NavigableMap decendingTailMap;
+ Integer value;
+ Entry entry;
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ value = new Integer(101);
+ assertNull(decendingMap.higherEntry(value.toString()));
+
+ for (int i = 108; i > 101; i--) {
+ value = new Integer(i);
+ entry = decendingMap.higherEntry(value.toString());
+ assertEquals(value - 1, entry.getValue());
+ }
+
+ value = new Integer(109);
+ entry = decendingMap.higherEntry(value.toString());
+ assertEquals(108, entry.getValue());
+
+ decendingTailMap = decendingMap.tailMap(new Integer(104).toString(),
+ false);
+ value = new Integer(109);
+ entry = decendingTailMap.higherEntry(value.toString());
+ assertEquals(103, entry.getValue());
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ value = new Integer(100);
+ assertNull(decendingMap.higherEntry(value.toString()));
+
+ for (int i = 108; i > 100; i--) {
+ value = new Integer(i);
+ entry = decendingMap.higherEntry(value.toString());
+ assertEquals(value - 1, entry.getValue());
+ }
+
+ value = new Integer(109);
+ entry = decendingMap.higherEntry(value.toString());
+ assertEquals(108, entry.getValue());
+
+ decendingTailMap = decendingMap.tailMap(new Integer(104).toString(),
+ false);
+ value = new Integer(109);
+ entry = decendingTailMap.higherEntry(value.toString());
+ assertEquals(103, entry.getValue());
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ value = new Integer(101);
+ assertNull(decendingMap.higherEntry(value.toString()));
+
+ for (int i = 109; i > 101; i--) {
+ value = new Integer(i);
+ entry = decendingMap.higherEntry(value.toString());
+ assertEquals(value - 1, entry.getValue());
+ }
+
+ value = new Integer(2);
+ entry = decendingMap.higherEntry(value.toString());
+ assertEquals(109, entry.getValue());
+
+ decendingTailMap = decendingMap.tailMap(new Integer(104).toString(),
+ false);
+ value = new Integer(109);
+ entry = decendingTailMap.higherEntry(value.toString());
+ assertEquals(103, entry.getValue());
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ value = new Integer(100);
+ assertNull(decendingMap.higherEntry(value.toString()));
+
+ for (int i = 109; i > 100; i--) {
+ value = new Integer(i);
+ entry = decendingMap.higherEntry(value.toString());
+ assertEquals(value - 1, entry.getValue());
+ }
+
+ value = new Integer(2);
+ entry = decendingMap.higherEntry(value.toString());
+ assertEquals(109, entry.getValue());
+
+ decendingTailMap = decendingMap.tailMap(new Integer(104).toString(),
+ false);
+ value = new Integer(109);
+ entry = decendingTailMap.higherEntry(value.toString());
+ assertEquals(103, entry.getValue());
+ }
+
+ public void test_DescendingSubMap_lowerEntry() {
+ NavigableMap decendingMap;
+ NavigableMap decendingHeadMap;
+ Integer value;
+ Entry entry;
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ value = new Integer(99);
+ assertNull(decendingMap.lowerEntry(value.toString()));
+ for (int i = 100; i < 108; i++) {
+ value = new Integer(i);
+ entry = decendingMap.lowerEntry(value.toString());
+ assertEquals(value + 1, entry.getValue());
+ }
+ value = new Integer(109);
+ assertNull(decendingMap.lowerEntry(value.toString()));
+
+ decendingHeadMap = decendingMap.headMap(new Integer(103).toString(),
+ false);
+ for (int i = 104; i < 106; i++) {
+ value = new Integer(i);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertEquals(value + 1, entry.getValue());
+ }
+ value = new Integer(102);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertEquals(104, entry.getValue());
+
+ value = new Integer(109);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertNull(entry);
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ value = new Integer(99);
+ assertNull(decendingMap.lowerEntry(value.toString()));
+ for (int i = 100; i < 109; i++) {
+ value = new Integer(i);
+ entry = decendingMap.lowerEntry(value.toString());
+ assertEquals(value + 1, entry.getValue());
+ }
+ value = new Integer(110);
+ assertNull(decendingMap.lowerEntry(value.toString()));
+
+ decendingHeadMap = decendingMap.headMap(new Integer(103).toString(),
+ false);
+ for (int i = 104; i < 109; i++) {
+ value = new Integer(i);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertEquals(value + 1, entry.getValue());
+ }
+ value = new Integer(102);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertEquals(104, entry.getValue());
+
+ value = new Integer(2);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertNull(entry);
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ value = new Integer(99);
+ assertNull(decendingMap.lowerEntry(value.toString()));
+ for (int i = 100; i < 108; i++) {
+ value = new Integer(i);
+ entry = decendingMap.lowerEntry(value.toString());
+ assertEquals(value + 1, entry.getValue());
+ }
+ value = new Integer(109);
+ assertNull(decendingMap.lowerEntry(value.toString()));
+
+ decendingHeadMap = decendingMap.headMap(new Integer(103).toString(),
+ false);
+ for (int i = 104; i < 107; i++) {
+ value = new Integer(i);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertEquals(value + 1, entry.getValue());
+ }
+ value = new Integer(102);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertEquals(104, entry.getValue());
+
+ value = new Integer(2);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertNull(entry);
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ value = new Integer(99);
+ assertNull(decendingMap.lowerEntry(value.toString()));
+ for (int i = 100; i < 109; i++) {
+ value = new Integer(i);
+ entry = decendingMap.lowerEntry(value.toString());
+ assertEquals(value + 1, entry.getValue());
+ }
+ value = new Integer(110);
+ assertNull(decendingMap.lowerEntry(value.toString()));
+
+ decendingHeadMap = decendingMap.headMap(new Integer(103).toString(),
+ false);
+ for (int i = 104; i < 109; i++) {
+ value = new Integer(i);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertEquals(value + 1, entry.getValue());
+ }
+ value = new Integer(102);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertEquals(104, entry.getValue());
+
+ value = new Integer(2);
+ entry = decendingHeadMap.lowerEntry(value.toString());
+ assertNull(entry);
+ }
+
+ public void test_DescendingSubMap_pollFirstEntry() {
+ NavigableMap decendingMap = tm.descendingMap();
+ assertEquals(999, decendingMap.pollFirstEntry().getValue());
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ assertEquals(108, decendingMap.pollFirstEntry().getValue());
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ assertEquals(109, decendingMap.pollFirstEntry().getValue());
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ assertEquals(107, decendingMap.pollFirstEntry().getValue());
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ assertEquals(106, decendingMap.pollFirstEntry().getValue());
+ }
+
+ public void test_DescendingSubMap_pollLastEntry() {
+ NavigableMap decendingMap = tm.descendingMap();
+ assertEquals(0, decendingMap.pollLastEntry().getValue());
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ assertEquals(101, decendingMap.pollLastEntry().getValue());
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ assertEquals(102, decendingMap.pollLastEntry().getValue());
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ assertEquals(100, decendingMap.pollLastEntry().getValue());
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ assertEquals(103, decendingMap.pollLastEntry().getValue());
+ }
+
+ public void test_DescendingSubMap_values() {
+ NavigableMap decendingMap = tm.descendingMap();
+ Collection values = decendingMap.values();
+ assertFalse(values.isEmpty());
+ assertFalse(values.contains(1000));
+ for (int i = 999; i > 0; i--) {
+ assertTrue(values.contains(i));
+ }
+ assertTrue(values.contains(0));
+
+ String endKey = new Integer(99).toString();
+ NavigableMap headMap = decendingMap.headMap(endKey, false);
+ values = headMap.values();
+ Iterator it = values.iterator();
+ for (int i = 999; i > 990; i--) {
+ assertTrue(values.contains(i));
+ assertEquals(i, it.next());
+ }
+
+ String startKey = new Integer(11).toString();
+ NavigableMap tailMap = decendingMap.tailMap(startKey, false);
+ values = tailMap.values();
+ it = values.iterator();
+ for (int i = 109; i > 100; i--) {
+ assertTrue(values.contains(i));
+ assertEquals(i, it.next());
+ }
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ values = decendingMap.values();
+ assertFalse(values.isEmpty());
+ assertFalse(values.contains(109));
+ for (int i = 108; i > 100; i--) {
+ assertTrue(values.contains(i));
+ }
+ assertFalse(values.contains(100));
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ values = decendingMap.values();
+ assertFalse(values.isEmpty());
+ assertFalse(values.contains(100));
+ for (int i = 108; i > 100; i--) {
+ assertTrue(values.contains(i));
+ }
+ assertTrue(values.contains(109));
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ values = decendingMap.values();
+ assertFalse(values.isEmpty());
+ assertTrue(values.contains(100));
+ for (int i = 108; i > 100; i--) {
+ assertTrue(values.contains(i));
+ }
+ assertFalse(values.contains(109));
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ values = decendingMap.values();
+ assertFalse(values.isEmpty());
+ assertTrue(values.contains(100));
+ for (int i = 108; i > 100; i--) {
+ assertTrue(values.contains(i));
+ }
+ assertTrue(values.contains(109));
+ }
+
+ public void test_DescendingSubMap_headMap() {
+ NavigableMap decendingMap = tm.descendingMap();
+ String endKey = new Integer(0).toString(), key;
+ SortedMap subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ SortedMap subDecendingMap_Excluded = decendingMap
+ .headMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 1; i < 1000; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(1000).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ endKey = new Integer(100).toString();
+ try {
+ decendingMap.headMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ for (int i = 102; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ endKey = new Integer(100).toString();
+ try {
+ decendingMap.headMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ for (int i = 102; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ endKey = new Integer(100).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ for (int i = 102; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ endKey = new Integer(100).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ for (int i = 102; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+ // With Comparator
+
+ decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .descendingMap();
+ endKey = new Integer(100).toString();
+ try {
+ decendingMap.headMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ for (int i = 102; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .descendingMap();
+ endKey = new Integer(100).toString();
+ try {
+ decendingMap.headMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ for (int i = 102; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+ decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+ .descendingMap();
+ endKey = new Integer(100).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ for (int i = 102; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+ .descendingMap();
+ endKey = new Integer(100).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.headMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ for (int i = 102; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+
+ public void test_DescendingSubMap_subMap() {
+ NavigableMap descendingMap = tm.descendingMap();
+ String startKey = new Integer(109).toString();
+ String endKey = new Integer(100).toString();
+ try {
+ descendingMap.subMap(endKey, false, startKey, false);
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ SortedMap subDescendingMap = descendingMap.subMap(startKey, false,
+ endKey, false);
+ String key = new Integer(100).toString();
+ assertFalse(subDescendingMap.containsKey(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDescendingMap.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(subDescendingMap.containsKey(key));
+
+ subDescendingMap = descendingMap.subMap(startKey, false, endKey, true);
+ key = new Integer(100).toString();
+ assertTrue(subDescendingMap.containsKey(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDescendingMap.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(subDescendingMap.containsKey(key));
+
+ subDescendingMap = descendingMap.subMap(startKey, true, endKey, false);
+ key = new Integer(100).toString();
+ assertFalse(subDescendingMap.containsKey(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDescendingMap.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertTrue(subDescendingMap.containsKey(key));
+
+ subDescendingMap = descendingMap.subMap(startKey, true, endKey, true);
+ key = new Integer(100).toString();
+ assertTrue(subDescendingMap.containsKey(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(subDescendingMap.containsKey(key));
+ }
+ key = new Integer(109).toString();
+ assertTrue(subDescendingMap.containsKey(key));
+
+ TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
+ for (int i = -10; i < 10; i++) {
+ treeMap.put(i, String.valueOf(i));
+ }
+ descendingMap = treeMap.descendingMap();
+ subDescendingMap = descendingMap.subMap(5, 0);
+ assertEquals(5, subDescendingMap.size());
+ }
+
+ public void test_DescendingSubMap_tailMap() {
+ // tm
+ NavigableMap decendingMap = tm.descendingMap();
+ String endKey = new Integer(1000).toString(), key;
+ SortedMap subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ SortedMap subDecendingMap_Excluded = decendingMap
+ .tailMap(endKey, false);
+
+ key = endKey;
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ key = new Integer(100).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+ key = new Integer(10).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+ key = new Integer(1).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+ key = new Integer(0).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(999).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 998; i > 0; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(0).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(0).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ assertEquals(1, subDecendingMap_Included.size());
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.isEmpty());
+
+ // navigableMap_startExcluded_endExcluded
+ decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+ endKey = new Integer(110).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(109).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(108).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 107; i > 100; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(100).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Included.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertEquals(1, subDecendingMap_Included.size());
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.isEmpty());
+
+ endKey = new Integer(100).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(99).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // navigableMap_startExcluded_endIncluded
+ decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+ endKey = new Integer(110).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(109).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(108).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 107; i > 100; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(100).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Included.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertEquals(1, subDecendingMap_Included.size());
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.isEmpty());
+
+ endKey = new Integer(100).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(99).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // navigableMap_startIncluded_endExcluded
+ decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+ endKey = new Integer(110).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(109).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(108).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 107; i > 100; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(100).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Included.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertEquals(2, subDecendingMap_Included.size());
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(100).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(99).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // navigableMap_startIncluded_endIncluded
+ decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+ endKey = new Integer(110).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(109).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(108).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 107; i > 100; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(100).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Included.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertEquals(2, subDecendingMap_Included.size());
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(100).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(99).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // With Comparator
+ decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .descendingMap();
+ endKey = new Integer(110).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(109).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(108).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 107; i > 100; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(100).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Included.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertEquals(1, subDecendingMap_Included.size());
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.isEmpty());
+
+ endKey = new Integer(100).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(99).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .descendingMap();
+ endKey = new Integer(110).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(109).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(108).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 107; i > 100; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(100).toString();
+ assertFalse(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Included.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertEquals(1, subDecendingMap_Included.size());
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.isEmpty());
+
+ endKey = new Integer(100).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(99).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // navigableMap_startIncluded_endExcluded
+ decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded)
+ .descendingMap();
+ endKey = new Integer(110).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(109).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(108).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 107; i > 100; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(100).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Included.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertEquals(2, subDecendingMap_Included.size());
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(100).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(99).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded)
+ .descendingMap();
+ endKey = new Integer(110).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(109).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(108).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+ for (int i = 107; i > 100; i--) {
+ key = new Integer(i).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Excluded.containsKey(key));
+ }
+ key = new Integer(100).toString();
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertTrue(subDecendingMap_Included.containsKey(key));
+
+ endKey = new Integer(101).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertEquals(2, subDecendingMap_Included.size());
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(100).toString();
+ subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+ subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+ key = endKey;
+ assertTrue(subDecendingMap_Included.containsKey(key));
+ assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+ endKey = new Integer(99).toString();
+ try {
+ decendingMap.tailMap(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ decendingMap.tailMap(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void test_Entry_setValue() {
+ TreeMap treeMap = new TreeMap();
+ Integer value = null;
+ for (int i = 0; i < 50; i++) {
+ value = new Integer(i);
+ treeMap.put(value, value);
+ }
+ Map checkedMap = Collections.checkedMap(treeMap, Integer.class,
+ Integer.class);
+ Set entrySet = checkedMap.entrySet();
+ Iterator iterator = entrySet.iterator();
+ Entry entry;
+ value = new Integer(0);
+ for (; iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.setValue(value + 1));
+ assertEquals(value + 1, entry.getValue());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_comparator() {
+ Set entrySet;
+ NavigableSet descendingSet;
+ Comparator comparator;
+ Entry[] entryArray;
+ Integer value1, value2;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ assertNull(((NavigableSet) entrySet).comparator());
+ comparator = descendingSet.comparator();
+ assertNotNull(comparator);
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 1; i < entryArray.length; i++) {
+ value1 = (Integer) entryArray[i - 1].getValue();
+ value2 = (Integer) entryArray[i].getValue();
+ assertTrue(value1 > value2);
+ assertTrue(comparator.compare(value1, value2) < 0);
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ assertNull(((NavigableSet) entrySet).comparator());
+ comparator = descendingSet.comparator();
+ assertNotNull(comparator);
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 1; i < entryArray.length; i++) {
+ value1 = (Integer) entryArray[i - 1].getValue();
+ value2 = (Integer) entryArray[i].getValue();
+ assertTrue(value1 > value2);
+ assertTrue(comparator.compare(value1, value2) < 0);
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ assertNull(((NavigableSet) entrySet).comparator());
+ comparator = descendingSet.comparator();
+ assertNotNull(comparator);
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 1; i < entryArray.length; i++) {
+ value1 = (Integer) entryArray[i - 1].getValue();
+ value2 = (Integer) entryArray[i].getValue();
+ assertTrue(value1 > value2);
+ assertTrue(comparator.compare(value1, value2) < 0);
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ assertNull(((NavigableSet) entrySet).comparator());
+ comparator = descendingSet.comparator();
+ assertNotNull(comparator);
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 1; i < entryArray.length; i++) {
+ value1 = (Integer) entryArray[i - 1].getValue();
+ value2 = (Integer) entryArray[i].getValue();
+ assertTrue(value1 > value2);
+ assertTrue(comparator.compare(value1, value2) < 0);
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ assertNotNull(descendingSet.comparator());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_descendingSet() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet, descendingSet, descendingDescedingSet;
+ Entry[] ascendingEntryArray, descendingDescendingArray;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ descendingDescedingSet = descendingSet.descendingSet();
+ ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet
+ .toArray(new Entry[ascendingSubMapEntrySet.size()]);
+
+ descendingDescendingArray = (Entry[]) descendingDescedingSet
+ .toArray(new Entry[descendingDescedingSet.size()]);
+
+ assertEquals(ascendingEntryArray.length,
+ descendingDescendingArray.length);
+ for (int i = 0; i < ascendingEntryArray.length; i++) {
+ assertEquals(ascendingEntryArray[i],
+ descendingDescendingArray[i]);
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ descendingDescedingSet = descendingSet.descendingSet();
+ ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet
+ .toArray(new Entry[ascendingSubMapEntrySet.size()]);
+
+ descendingDescendingArray = (Entry[]) descendingDescedingSet
+ .toArray(new Entry[descendingDescedingSet.size()]);
+
+ assertEquals(ascendingEntryArray.length,
+ descendingDescendingArray.length);
+ for (int i = 0; i < ascendingEntryArray.length; i++) {
+ assertEquals(ascendingEntryArray[i],
+ descendingDescendingArray[i]);
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ descendingDescedingSet = descendingSet.descendingSet();
+ ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet
+ .toArray(new Entry[ascendingSubMapEntrySet.size()]);
+
+ descendingDescendingArray = (Entry[]) descendingDescedingSet
+ .toArray(new Entry[descendingDescedingSet.size()]);
+
+ assertEquals(ascendingEntryArray.length,
+ descendingDescendingArray.length);
+ for (int i = 0; i < ascendingEntryArray.length; i++) {
+ assertEquals(ascendingEntryArray[i],
+ descendingDescendingArray[i]);
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ descendingDescedingSet = descendingSet.descendingSet();
+ ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet
+ .toArray(new Entry[ascendingSubMapEntrySet.size()]);
+
+ descendingDescendingArray = (Entry[]) descendingDescedingSet
+ .toArray(new Entry[descendingDescedingSet.size()]);
+
+ assertEquals(ascendingEntryArray.length,
+ descendingDescendingArray.length);
+ for (int i = 0; i < ascendingEntryArray.length; i++) {
+ assertEquals(ascendingEntryArray[i],
+ descendingDescendingArray[i]);
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();// 0...2
+ if (entrySet instanceof NavigableSet) {
+ // [2...0]
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ // [0...2]
+ descendingDescedingSet = descendingSet.descendingSet();
+ Iterator iterator = descendingDescedingSet.iterator();
+ assertEquals(0, ((Entry) iterator.next()).getValue());
+ }
+
+ String startKey = new Integer(2).toString();
+ entrySet = tm.tailMap(startKey, true).entrySet();// 2...
+ if (entrySet instanceof NavigableSet) {
+ // [2...0]
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ // [0...2]
+ descendingDescedingSet = descendingSet.descendingSet();
+ Iterator iterator = descendingDescedingSet.iterator();
+ assertEquals(2, ((Entry) iterator.next()).getValue());
+ }
+
+ }
+
+ public void test_DescendingSubMapEntrySet_first() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet, descendingSet;
+ Entry entry;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ entry = (Entry) descendingSet.first();
+ assertEquals(101, entry.getValue());
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ entry = (Entry) descendingSet.first();
+ assertEquals(101, entry.getValue());
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ entry = (Entry) descendingSet.first();
+ assertEquals(100, entry.getValue());
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ entry = (Entry) descendingSet.first();
+ assertEquals(100, entry.getValue());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_last() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet, descendingSet;
+ Entry entry;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ entry = (Entry) descendingSet.last();
+ assertEquals(108, entry.getValue());
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ entry = (Entry) descendingSet.last();
+ assertEquals(109, entry.getValue());
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ entry = (Entry) descendingSet.last();
+ assertEquals(108, entry.getValue());
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ entry = (Entry) descendingSet.last();
+ assertEquals(109, entry.getValue());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollFirst_startExcluded_endExcluded() {
+ Set entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ Entry entry;
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ assertEquals(8, descendingSubMapEntrySet.size());
+ for (int i = 101; i < 109; i++) {
+ entry = (Entry) descendingSubMapEntrySet.pollFirst();
+ assertEquals(i, entry.getValue());
+ }
+ assertNull(descendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollFirst_startExcluded_endIncluded() {
+ Set entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ Entry entry;
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ assertEquals(9, descendingSubMapEntrySet.size());
+ for (int i = 101; i < 110; i++) {
+ entry = (Entry) descendingSubMapEntrySet.pollFirst();
+ assertEquals(i, entry.getValue());
+ }
+ assertNull(descendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollFirst_startIncluded_endExcluded() {
+ Set entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ Entry entry;
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ assertEquals(9, descendingSubMapEntrySet.size());
+ for (int i = 100; i < 109; i++) {
+ entry = (Entry) descendingSubMapEntrySet.pollFirst();
+ assertEquals(i, entry.getValue());
+ }
+ assertNull(descendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollFirst_startIncluded_endIncluded() {
+ Set entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ Entry entry;
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ assertEquals(10, descendingSubMapEntrySet.size());
+ for (int i = 100; i < 110; i++) {
+ entry = (Entry) descendingSubMapEntrySet.pollFirst();
+ assertEquals(i, entry.getValue());
+ }
+ assertNull(descendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollFirst() {
+ String key = new Integer(2).toString();
+ Set entrySet = tm.headMap(key, true).entrySet();// [0...2]
+ NavigableSet descendingEntrySet;
+ Entry entry;
+
+ if (entrySet instanceof NavigableSet) {
+ // [2...0]
+ descendingEntrySet = ((NavigableSet) entrySet).descendingSet();
+ entry = (Entry) descendingEntrySet.pollFirst();
+ assertEquals(0, entry.getValue());
+ }
+
+ entrySet = tm.tailMap(key, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingEntrySet = ((NavigableSet) entrySet).descendingSet();
+ entry = (Entry) descendingEntrySet.pollFirst();
+ assertEquals(2, entry.getValue());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollLast_startExcluded_endExclued() {
+ Set entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ Entry entry;
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ assertEquals(8, descendingSubMapEntrySet.size());
+ for (int i = 108; i > 100; i--) {
+ entry = (Entry) descendingSubMapEntrySet.pollLast();
+ assertEquals(i, entry.getValue());
+ }
+ assertNull(descendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollLast_startExcluded_endInclued() {
+ Set entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ Entry entry;
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ assertEquals(9, descendingSubMapEntrySet.size());
+ for (int i = 109; i > 100; i--) {
+ entry = (Entry) descendingSubMapEntrySet.pollLast();
+ assertEquals(i, entry.getValue());
+ }
+ assertNull(descendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollLast_startIncluded_endExclued() {
+ Set entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ Entry entry;
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ assertEquals(9, descendingSubMapEntrySet.size());
+ for (int i = 108; i > 99; i--) {
+ entry = (Entry) descendingSubMapEntrySet.pollLast();
+ assertEquals(i, entry.getValue());
+ }
+ assertNull(descendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollLast_startIncluded_endInclued() {
+ Set entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ Entry entry;
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ assertEquals(10, descendingSubMapEntrySet.size());
+ for (int i = 109; i > 99; i--) {
+ entry = (Entry) descendingSubMapEntrySet.pollLast();
+ assertEquals(i, entry.getValue());
+ }
+ assertNull(descendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_pollLast() {
+ String key = new Integer(2).toString();
+ Set entrySet = tm.headMap(key, true).entrySet();// [0...2]
+ NavigableSet descendingEntrySet;
+ Entry entry;
+
+ if (entrySet instanceof NavigableSet) {
+ // [2...0]
+ descendingEntrySet = ((NavigableSet) entrySet).descendingSet();
+ entry = (Entry) descendingEntrySet.pollLast();
+ assertEquals(2, entry.getValue());
+ }
+
+ entrySet = tm.tailMap(key, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingEntrySet = ((NavigableSet) entrySet).descendingSet();
+ entry = (Entry) descendingEntrySet.pollLast();
+ assertEquals(999, entry.getValue());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_descendingIterator() {
+ Set entrySet;
+ NavigableSet descendingSet;
+ Iterator iterator;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ iterator = descendingSet.iterator();
+ for (int value = 108; value > 100; value--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(value, ((Entry) iterator.next()).getValue());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ iterator = descendingSet.iterator();
+ for (int value = 109; value > 100; value--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(value, ((Entry) iterator.next()).getValue());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ iterator = descendingSet.iterator();
+ for (int value = 108; value > 99; value--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(value, ((Entry) iterator.next()).getValue());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ iterator = descendingSet.iterator();
+ for (int value = 109; value > 99; value--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(value, ((Entry) iterator.next()).getValue());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();// 0...2
+ if (entrySet instanceof NavigableSet) {
+ // [2...0]
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ iterator = descendingSet.descendingIterator();
+ assertEquals(0, ((Entry) iterator.next()).getValue());// 0...2
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_headSet() {
+ Set entrySet, headSet;
+ NavigableSet descendingSubMapEntrySet;
+ Iterator iterator, headSetIterator;
+ Entry entry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ headSet = descendingSubMapEntrySet.headSet(entry);
+ headSetIterator = headSet.iterator();
+ for (value = 108; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = descendingSubMapEntrySet.headSet(entry, false);
+ headSetIterator = headSet.iterator();
+ for (value = 108; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = descendingSubMapEntrySet.headSet(entry, true);
+ headSetIterator = headSet.iterator();
+ for (value = 108; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ headSet = descendingSubMapEntrySet.headSet(entry);
+ headSetIterator = headSet.iterator();
+ for (value = 109; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = descendingSubMapEntrySet.headSet(entry, false);
+ headSetIterator = headSet.iterator();
+ for (value = 109; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = descendingSubMapEntrySet.headSet(entry, true);
+ headSetIterator = headSet.iterator();
+ for (value = 109; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ headSet = descendingSubMapEntrySet.headSet(entry);
+ headSetIterator = headSet.iterator();
+ for (value = 108; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = descendingSubMapEntrySet.headSet(entry, false);
+ headSetIterator = headSet.iterator();
+ for (value = 108; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = descendingSubMapEntrySet.headSet(entry, true);
+ headSetIterator = headSet.iterator();
+ for (value = 108; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ headSet = descendingSubMapEntrySet.headSet(entry);
+ headSetIterator = headSet.iterator();
+ for (value = 109; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = descendingSubMapEntrySet.headSet(entry, false);
+ headSetIterator = headSet.iterator();
+ for (value = 109; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = descendingSubMapEntrySet.headSet(entry, true);
+ headSetIterator = headSet.iterator();
+ for (value = 109; headSetIterator.hasNext(); value--) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();// 0...2
+ if (entrySet instanceof NavigableSet) {
+ // [2...0]
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ iterator.next();// 2
+ iterator.next();// 199
+ entry = (Entry) iterator.next();// 198
+ headSet = descendingSubMapEntrySet.headSet(entry);
+ assertEquals(2, headSet.size());// 2 199
+ headSetIterator = headSet.iterator();
+ assertEquals(2, ((Entry) headSetIterator.next()).getValue());
+ assertEquals(199, ((Entry) headSetIterator.next()).getValue());
+
+ headSet = descendingSubMapEntrySet.headSet(entry, true);
+ assertEquals(3, headSet.size());// 2 199
+ headSetIterator = headSet.iterator();
+ assertEquals(2, ((Entry) headSetIterator.next()).getValue());
+ assertEquals(199, ((Entry) headSetIterator.next()).getValue());
+ assertEquals(198, ((Entry) headSetIterator.next()).getValue());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_tailSet() {
+ Set entrySet, tailSet;
+ NavigableSet descendingSubMapEntrySet;
+ Iterator iterator, tailSetIterator;
+ Entry entry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ tailSet = descendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value - 1, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ tailSet = descendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value - 1, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ tailSet = descendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value - 1, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ tailSet = descendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value - 1, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value--) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();// 0...2
+ if (entrySet instanceof NavigableSet) {
+ // [2...0]
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ iterator.next();// 2
+ entry = (Entry) iterator.next();// 199
+ tailSet = descendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ assertEquals(199, ((Entry) tailSetIterator.next()).getValue());
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ assertEquals(198, ((Entry) tailSetIterator.next()).getValue());
+
+ tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ assertEquals(199, ((Entry) tailSetIterator.next()).getValue());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_subSet() {
+ Set entrySet, subSet;
+ NavigableSet descendingSubMapEntrySet;
+ Entry startEntry, endEntry;
+ Iterator subSetIterator;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ Iterator iteratorStart = descendingSubMapEntrySet.iterator();
+ while (iteratorStart.hasNext()) {
+ startEntry = (Entry) iteratorStart.next();
+ Iterator iteratorEnd = descendingSubMapEntrySet.iterator();
+ while (iteratorEnd.hasNext()) {
+ endEntry = (Entry) iteratorEnd.next();
+ int startIndex = (Integer) startEntry.getValue();
+ int endIndex = (Integer) endEntry.getValue();
+ if (startIndex < endIndex) {
+ try {
+ descendingSubMapEntrySet.subSet(startEntry,
+ endEntry);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingSubMapEntrySet.subSet(startEntry, true,
+ endEntry, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingSubMapEntrySet.subSet(startEntry, true,
+ endEntry, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } else {
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ endEntry);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ false, endEntry, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex - 1; subSetIterator
+ .hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ false, endEntry, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex - 1; subSetIterator
+ .hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ true, endEntry, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ true, endEntry, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+ }
+ }
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ // [2...0]
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ Iterator iterator = descendingSubMapEntrySet.iterator();
+ startEntry = (Entry) iterator.next();
+ iterator.next();
+ endEntry = (Entry) iterator.next();
+ subSet = descendingSubMapEntrySet.subSet(startEntry, endEntry);
+ assertEquals(2, subSet.size());
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, false);
+ assertEquals(1, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(199, ((Entry) subSetIterator.next()).getValue());
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, true);
+ assertEquals(2, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(199, ((Entry) subSetIterator.next()).getValue());
+ assertEquals(198, ((Entry) subSetIterator.next()).getValue());
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry, true,
+ endEntry, false);
+ assertEquals(2, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(2, ((Entry) subSetIterator.next()).getValue());
+ assertEquals(199, ((Entry) subSetIterator.next()).getValue());
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry, true,
+ endEntry, true);
+ assertEquals(3, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(2, ((Entry) subSetIterator.next()).getValue());
+ assertEquals(199, ((Entry) subSetIterator.next()).getValue());
+ assertEquals(198, ((Entry) subSetIterator.next()).getValue());
+ }
+
+ // With Comnparator
+ entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ Iterator iteratorStart = descendingSubMapEntrySet.iterator();
+ while (iteratorStart.hasNext()) {
+ startEntry = (Entry) iteratorStart.next();
+ Iterator iteratorEnd = descendingSubMapEntrySet.iterator();
+ while (iteratorEnd.hasNext()) {
+ endEntry = (Entry) iteratorEnd.next();
+ int startIndex = (Integer) startEntry.getValue();
+ int endIndex = (Integer) endEntry.getValue();
+ if (startIndex < endIndex) {
+ try {
+ descendingSubMapEntrySet.subSet(startEntry,
+ endEntry);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingSubMapEntrySet.subSet(startEntry, true,
+ endEntry, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingSubMapEntrySet.subSet(startEntry, true,
+ endEntry, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } else {
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ endEntry);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ false, endEntry, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex - 1; subSetIterator
+ .hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ false, endEntry, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex - 1; subSetIterator
+ .hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ true, endEntry, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = descendingSubMapEntrySet.subSet(startEntry,
+ true, endEntry, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_lower() {
+ Set entrySet, subSet;
+ NavigableSet descendingSubMapEntrySet;
+ Iterator iterator;
+ Entry entry, lowerEntry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value < 108) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+
+ // System.out.println(descendingSubMapEntrySet);
+ // System.out.println(tm);
+ Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+ .iterator().next();
+ // System.out.println("o:" + afterEnd);
+ Object x = descendingSubMapEntrySet.lower(afterEnd);
+ // System.out.println("x:" + x);
+ assertNull(x);
+ Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+ .iterator().next();
+ // System.out.println("before: " + beforeStart);
+ Object y = descendingSubMapEntrySet.lower(beforeStart);
+ // System.out.println("y: " + y);
+ assertNotNull(y);
+ assertEquals(101, (((Entry) y).getValue()));
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value < 109) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value < 108) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value < 109) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ iterator.next();// 2
+ iterator.next();// 199
+ entry = (Entry) iterator.next();// 198
+ lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+ assertEquals(199, lowerEntry.getValue());
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_higher() {
+ Set entrySet, subSet;
+ NavigableSet descendingSubMapEntrySet;
+ Iterator iterator;
+ Entry entry, higherEntry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value > 101) {
+ assertEquals(value - 1, higherEntry.getValue());
+ } else {
+ assertNull(higherEntry);
+ }
+ }
+
+ Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+ .iterator().next();
+ Object x = descendingSubMapEntrySet.higher(afterEnd);
+ assertNotNull(x);
+ assertEquals(108, ((Entry) x).getValue());
+ Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+ .iterator().next();
+ Object y = descendingSubMapEntrySet.higher(beforeStart);
+ assertNull(y);
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value > 101) {
+ assertEquals(value - 1, higherEntry.getValue());
+ } else {
+ assertNull(higherEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value > 100) {
+ assertEquals(value - 1, higherEntry.getValue());
+ } else {
+ assertNull(higherEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value > 100) {
+ assertEquals(value - 1, higherEntry.getValue());
+ } else {
+ assertNull(higherEntry);
+ }
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ iterator.next();// 2
+ iterator.next();// 199
+ entry = (Entry) iterator.next();// 198
+ higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+ assertEquals(197, higherEntry.getValue());
+ }
+
+ // With Comparator
+ entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSubMapEntrySet = ((NavigableSet) entrySet)
+ .descendingSet();
+ iterator = descendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value > 101) {
+ assertEquals(value - 1, higherEntry.getValue());
+ } else {
+ assertNull(higherEntry);
+ }
+ }
+
+ Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+ .iterator().next();
+ Object x = descendingSubMapEntrySet.higher(afterEnd);
+ assertNotNull(x);
+ assertEquals(108, ((Entry) x).getValue());
+ Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+ .iterator().next();
+ Object y = descendingSubMapEntrySet.higher(beforeStart);
+ assertNull(y);
+ }
+ }
+
+ public void test_DescendingSubMapEntrySet_ceiling() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet, descendingSet;
+ Entry entry;
+ Entry[] entryArray;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.ceiling(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 108; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.ceiling(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+
+ // System.out.println(descendingSet);
+ // System.out.println(tm);
+ Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+ .iterator().next();
+ // System.out.println("o:" + afterEnd);//110
+ Object x = descendingSet.ceiling(afterEnd);
+ assertNotNull(x);
+ // System.out.println("x:" + x);
+ assertEquals(108, ((Entry) x).getValue());
+ Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+ .iterator().next();
+ // System.out.println("before: " + beforeStart);//0
+ Object y = descendingSet.ceiling(beforeStart);
+ assertNull(y);
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.ceiling(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 109; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.ceiling(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.ceiling(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 108; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.ceiling(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ try {
+ descendingSet.ceiling(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 109; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.ceiling(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ try {
+ descendingSet.ceiling(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ Iterator iterator = descendingSet.iterator();
+ Entry ceilingEntry;
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ ceilingEntry = (Entry) descendingSet.ceiling(entry);
+ assertEquals(entry, ceilingEntry);
+ }
+ }
+
+ }
+
+ public void test_DescendingSubMapEntrySet_floor() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet, descendingSet;
+ Entry entry;
+ Entry[] entryArray;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 108; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.floor(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+
+ Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+ .iterator().next();
+ Object x = descendingSet.floor(afterEnd);
+ assertNull(x);
+
+ Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+ .iterator().next();
+ Object y = descendingSet.floor(beforeStart);
+ assertNotNull(y);
+ assertEquals(101, (((Entry) y).getValue()));
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 109; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.floor(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 108; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.floor(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ try {
+ descendingSet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 109; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.floor(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+
+ Iterator iterator = descendingSet.iterator();
+ Entry floorEntry;
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) descendingSet.floor(entry);
+ assertEquals(entry, floorEntry);
+ }
+ }
+
+ // With Comparator
+ entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 108; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.floor(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 109; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.floor(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ try {
+ descendingSet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 108; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.floor(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+
+ entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ descendingSet = ((NavigableSet) entrySet).descendingSet();
+ try {
+ descendingSet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ entryArray = (Entry[]) descendingSet
+ .toArray(new Entry[descendingSet.size()]);
+ for (int i = 0, j = 109; i < entryArray.length; i++) {
+ entry = (Entry) descendingSet.floor(entryArray[i]);
+ assertEquals(j - i, entry.getValue());
+ }
+ }
+ }
+
+ public void test_DescendingSubMapKeySet_comparator() {
+ NavigableSet keySet, descendingKeySet;
+ Comparator comparator;
+ String[] keyArray;
+ Integer value1, value2;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ assertNull(keySet.comparator());
+ descendingKeySet = keySet.descendingSet();
+ comparator = descendingKeySet.comparator();
+ assertNotNull(comparator);
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 1; i < keyArray.length; i++) {
+ value1 = Integer.valueOf(keyArray[i - 1]);
+ value2 = Integer.valueOf(keyArray[i]);
+ assertTrue(value1 > value2);
+ assertTrue(comparator.compare(value1, value2) < 0);
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ assertNull(keySet.comparator());
+ descendingKeySet = keySet.descendingSet();
+ comparator = descendingKeySet.comparator();
+ assertNotNull(comparator);
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 1; i < keyArray.length; i++) {
+ value1 = Integer.valueOf(keyArray[i - 1]);
+ value2 = Integer.valueOf(keyArray[i]);
+ assertTrue(value1 > value2);
+ assertTrue(comparator.compare(value1, value2) < 0);
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ assertNull(keySet.comparator());
+ descendingKeySet = keySet.descendingSet();
+ comparator = descendingKeySet.comparator();
+ assertNotNull(comparator);
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 1; i < keyArray.length; i++) {
+ value1 = Integer.valueOf(keyArray[i - 1]);
+ value2 = Integer.valueOf(keyArray[i]);
+ assertTrue(value1 > value2);
+ assertTrue(comparator.compare(value1, value2) < 0);
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ assertNull(keySet.comparator());
+ descendingKeySet = keySet.descendingSet();
+ comparator = descendingKeySet.comparator();
+ assertNotNull(comparator);
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 1; i < keyArray.length; i++) {
+ value1 = Integer.valueOf(keyArray[i - 1]);
+ value2 = Integer.valueOf(keyArray[i]);
+ assertTrue(value1 > value2);
+ assertTrue(comparator.compare(value1, value2) < 0);
+ }
+
+ String endKey = new Integer(2).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ assertNull(keySet.comparator());
+ descendingKeySet = keySet.descendingSet();
+ assertNotNull(descendingKeySet.comparator());
+ }
+
+ public void test_AscendingSubMapKeySet_first() {
+ NavigableSet keySet;
+ String firstKey1 = new Integer(100).toString();
+ String firstKey2 = new Integer(101).toString();
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ assertEquals(firstKey2, keySet.first());
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ assertEquals(firstKey2, keySet.first());
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ assertEquals(firstKey1, keySet.first());
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ assertEquals(firstKey1, keySet.first());
+ }
+
+ public void test_DescendingSubMapKeySet_pollFirst_startExcluded_endExcluded() {
+ NavigableSet keySet = navigableMap_startExcluded_endExcluded
+ .navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(8, keySet.size());
+ for (int value = 101; value < 109; value++) {
+ assertEquals(new Integer(value).toString(), keySet.pollFirst());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_pollFirst_startExcluded_endIncluded() {
+ NavigableSet keySet = navigableMap_startExcluded_endIncluded
+ .navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(9, keySet.size());
+ for (int value = 101; value < 110; value++) {
+ assertEquals(new Integer(value).toString(), keySet.pollFirst());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_pollFirst_startIncluded_endExcluded() {
+ NavigableSet keySet = navigableMap_startIncluded_endExcluded
+ .navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(9, keySet.size());
+ for (int value = 100; value < 109; value++) {
+ assertEquals(new Integer(value).toString(), keySet.pollFirst());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_pollFirst_startIncluded_endIncluded() {
+ NavigableSet keySet = navigableMap_startIncluded_endIncluded
+ .navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(10, keySet.size());
+ for (int value = 100; value < 110; value++) {
+ assertEquals(new Integer(value).toString(), keySet.pollFirst());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_pollFirst() {
+ String endKey = new Integer(2).toString();
+ NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ assertEquals(endKey, descendingKeySet.pollFirst());
+ }
+
+ public void test_DescendingSubMapKeySet_pollLast_startExcluded_endExcluded() {
+ NavigableSet keySet = navigableMap_startExcluded_endExcluded
+ .navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(8, keySet.size());
+ for (int value = 108; value > 100; value--) {
+ assertEquals(new Integer(value).toString(), keySet.pollLast());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_pollLast_startExcluded_endIncluded() {
+ NavigableSet keySet = navigableMap_startExcluded_endIncluded
+ .navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(9, keySet.size());
+ for (int value = 109; value > 100; value--) {
+ assertEquals(new Integer(value).toString(), keySet.pollLast());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_pollLast_startIncluded_endExcluded() {
+ NavigableSet keySet = navigableMap_startIncluded_endExcluded
+ .navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(9, keySet.size());
+ for (int value = 108; value > 99; value--) {
+ assertEquals(new Integer(value).toString(), keySet.pollLast());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_pollLast_startIncluded_endIncluded() {
+ NavigableSet keySet = navigableMap_startIncluded_endIncluded
+ .navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(10, keySet.size());
+ for (int value = 109; value > 99; value--) {
+ assertEquals(new Integer(value).toString(), keySet.pollLast());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_pollLast() {
+ String endKey = new Integer(2).toString();
+ NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet();
+ NavigableSet descendingKeySet = keySet.descendingSet();
+ assertEquals(new Integer(0).toString(), descendingKeySet.pollLast());
+ }
+
+ public void test_DescendingSubMapKeySet_headSet() {
+ NavigableSet keySet, descendingKeySet;
+ SortedSet headSet;
+ String endKey, key;
+ Iterator iterator;
+ int index;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ endKey = new Integer(99).toString();
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(101).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 108; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 108; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 108; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i - 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ try {
+ headSet = descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(110).toString();
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ endKey = new Integer(99).toString();
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(101).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 109; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 109; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 109; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i - 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(108, index);
+
+ endKey = new Integer(110).toString();
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ endKey = new Integer(99).toString();
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(99, index);
+
+ endKey = new Integer(101).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 108; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 108; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 108; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 108; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i - 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(110).toString();
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ endKey = new Integer(99).toString();
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(99, index);
+
+ endKey = new Integer(101).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 109; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 109; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 109; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i - 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = descendingKeySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(108, index);
+
+ endKey = new Integer(110).toString();
+ try {
+ descendingKeySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ iterator.next();
+ endKey = (String) iterator.next();
+
+ headSet = descendingKeySet.headSet(endKey);
+ assertEquals(1, headSet.size());
+
+ headSet = descendingKeySet.headSet(endKey, false);
+ assertEquals(1, headSet.size());
+
+ headSet = descendingKeySet.headSet(endKey, true);
+ assertEquals(2, headSet.size());
+
+ key = new Integer(2).toString();
+ keySet = tm.tailMap(key, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ iterator.next();
+ endKey = (String) iterator.next();
+ headSet = descendingKeySet.headSet(endKey);
+ assertEquals(1, headSet.size());
+ iterator = headSet.iterator();
+ assertEquals(999, Integer.parseInt((String) iterator.next()));
+ }
+
+ public void test_DescendingSubMapKeySet_tailSet() {
+ NavigableSet keySet, descendingKeySet;
+ SortedSet tailSet;
+ String startKey, key;
+ Iterator iterator;
+ int index;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ startKey = new Integer(99).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(101).toString();
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(100, j);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(100, j);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j - 1).toString(), key);
+ }
+ assertEquals(101, j);
+ }
+
+ startKey = new Integer(109).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index - 1).toString(), key);
+ }
+ assertEquals(101, index);
+
+ startKey = new Integer(110).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ startKey = new Integer(99).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(101).toString();
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(100, j);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(100, j);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j - 1).toString(), key);
+ }
+ assertEquals(101, j);
+ }
+
+ startKey = new Integer(109).toString();
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(100, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index - 1).toString(), key);
+ }
+ assertEquals(101, index);
+
+ startKey = new Integer(110).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ startKey = new Integer(99).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ tailSet = descendingKeySet.tailSet(startKey);
+ assertEquals(1, tailSet.size());
+ iterator = tailSet.iterator();
+ assertEquals(startKey, iterator.next());
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ assertEquals(1, tailSet.size());
+ iterator = tailSet.iterator();
+ assertEquals(startKey, iterator.next());
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ assertEquals(0, tailSet.size());
+
+ startKey = new Integer(101).toString();
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(99, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(99, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index - 1).toString(), key);
+ }
+ assertEquals(100, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(99, j);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(99, j);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j - 1).toString(), key);
+ }
+ assertEquals(100, j);
+ }
+
+ startKey = new Integer(109).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index - 1).toString(), key);
+ }
+ assertEquals(100, index);
+
+ startKey = new Integer(110).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ startKey = new Integer(99).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ tailSet = descendingKeySet.tailSet(startKey);
+ assertEquals(1, tailSet.size());
+ iterator = tailSet.iterator();
+ assertEquals(startKey, iterator.next());
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ assertEquals(1, tailSet.size());
+ iterator = tailSet.iterator();
+ assertEquals(startKey, iterator.next());
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ assertEquals(0, tailSet.size());
+
+ startKey = new Integer(101).toString();
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(99, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(99, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index - 1).toString(), key);
+ }
+ assertEquals(100, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(99, j);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(99, j);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j - 1).toString(), key);
+ }
+ assertEquals(100, j);
+ }
+
+ startKey = new Integer(109).toString();
+ tailSet = descendingKeySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(99, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(99, index);
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index--) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index - 1).toString(), key);
+ }
+ assertEquals(100, index);
+
+ startKey = new Integer(110).toString();
+ try {
+ descendingKeySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ descendingKeySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ iterator.next();
+ startKey = (String) iterator.next();
+
+ tailSet = descendingKeySet.tailSet(startKey);
+ assertEquals(112, tailSet.size());
+ Iterator tailIterator = tailSet.iterator();
+ assertEquals(new Integer(199).toString(), tailIterator.next());
+
+ tailSet = descendingKeySet.tailSet(startKey, true);
+ assertEquals(112, tailSet.size());
+ tailIterator = tailSet.iterator();
+ assertEquals(new Integer(199).toString(), tailIterator.next());
+
+ tailSet = descendingKeySet.tailSet(startKey, false);
+ assertEquals(111, tailSet.size());
+ tailIterator = tailSet.iterator();
+ assertEquals(new Integer(198).toString(), tailIterator.next());
+ }
+
+ public void test_DescendingSubMapKeySet_subSet() {
+ NavigableSet keySet, descendingKeySet;
+ SortedSet subSet;
+ String startKey, endKey, key;
+ Iterator startIterator, endIterator, subSetIterator;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ startIterator = descendingKeySet.iterator();
+ while (startIterator.hasNext()) {
+ startKey = (String) startIterator.next();
+ endIterator = descendingKeySet.iterator();
+ while (endIterator.hasNext()) {
+ endKey = (String) endIterator.next();
+ int startIndex = Integer.valueOf(startKey);
+ int endIndex = Integer.valueOf(endKey);
+ if (startIndex < endIndex) {
+ try {
+ descendingKeySet.subSet(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.subSet(startKey, false, endKey, false);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.subSet(startKey, false, endKey, true);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.subSet(startKey, true, endKey, false);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.subSet(startKey, true, endKey, true);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } else {
+ subSet = descendingKeySet.subSet(startKey, endKey);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = descendingKeySet.subSet(startKey, false, endKey,
+ false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex - 1; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = descendingKeySet.subSet(startKey, false, endKey,
+ true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex - 1; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = descendingKeySet.subSet(startKey, true, endKey,
+ false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = descendingKeySet.subSet(startKey, true, endKey,
+ true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+ }
+ }
+ }
+
+ endKey = new Integer(2).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+
+ startKey = (String) iterator.next();
+ iterator.next();
+ endKey = (String) iterator.next();
+
+ subSet = descendingKeySet.subSet(startKey, endKey);
+ assertEquals(2, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(startKey, subSetIterator.next());
+ subSetIterator.next();
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = descendingKeySet.subSet(startKey, false, endKey, false);
+ assertEquals(1, subSet.size());
+ subSetIterator = subSet.iterator();
+ subSetIterator.next();
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = descendingKeySet.subSet(startKey, false, endKey, true);
+ assertEquals(2, subSet.size());
+ subSetIterator = subSet.iterator();
+ subSetIterator.next();
+ assertEquals(endKey, subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = descendingKeySet.subSet(startKey, true, endKey, false);
+ assertEquals(2, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(startKey, subSetIterator.next());
+ subSetIterator.next();
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = descendingKeySet.subSet(startKey, true, endKey, true);
+ assertEquals(3, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(startKey, subSetIterator.next());
+ subSetIterator.next();
+ assertEquals(endKey, subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ // With Comparator
+ keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ startIterator = descendingKeySet.iterator();
+ while (startIterator.hasNext()) {
+ startKey = (String) startIterator.next();
+ endIterator = descendingKeySet.iterator();
+ while (endIterator.hasNext()) {
+ endKey = (String) endIterator.next();
+ int startIndex = Integer.valueOf(startKey);
+ int endIndex = Integer.valueOf(endKey);
+ if (startIndex < endIndex) {
+ try {
+ descendingKeySet.subSet(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.subSet(startKey, false, endKey, false);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.subSet(startKey, false, endKey, true);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.subSet(startKey, true, endKey, false);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ descendingKeySet.subSet(startKey, true, endKey, true);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } else {
+ subSet = descendingKeySet.subSet(startKey, endKey);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = descendingKeySet.subSet(startKey, false, endKey,
+ false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex - 1; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = descendingKeySet.subSet(startKey, false, endKey,
+ true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex - 1; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = descendingKeySet.subSet(startKey, true, endKey,
+ false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = descendingKeySet.subSet(startKey, true, endKey,
+ true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index--) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+ }
+ }
+ }
+ }
+
+ public void test_DescendingSubMapKeySet_descendingSet() {
+ NavigableSet keySet, descendingSet, descendingDescendingSet;
+ int value;
+ Iterator iterator;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingDescendingSet = descendingSet.descendingSet();
+ iterator = descendingDescendingSet.iterator();
+ assertTrue(iterator.hasNext());
+ for (value = 101; iterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertEquals(109, value);
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingDescendingSet = descendingSet.descendingSet();
+ iterator = descendingDescendingSet.iterator();
+ assertTrue(iterator.hasNext());
+ for (value = 101; iterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertEquals(110, value);
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingDescendingSet = descendingSet.descendingSet();
+ iterator = descendingDescendingSet.iterator();
+ assertTrue(iterator.hasNext());
+ for (value = 100; iterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertEquals(109, value);
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingDescendingSet = descendingSet.descendingSet();
+ iterator = descendingDescendingSet.iterator();
+ assertTrue(iterator.hasNext());
+ for (value = 100; iterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertEquals(110, value);
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ String endKey = new Integer(2).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingDescendingSet = descendingSet.descendingSet();
+ assertEquals(keySet, descendingDescendingSet);
+
+ String startKey = new Integer(2).toString();
+ keySet = tm.tailMap(startKey, true).navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingDescendingSet = descendingSet.descendingSet();
+ assertEquals(keySet, descendingDescendingSet);
+ }
+
+ public void test_DescendingSubMapKeySet_descendingIterator() {
+ NavigableSet keySet, descendingSet;
+ int value;
+ Iterator iterator, descendingIterator;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingIterator = descendingSet.descendingIterator();
+ assertTrue(descendingIterator.hasNext());
+ for (value = 101; descendingIterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), descendingIterator
+ .next());
+ }
+ assertEquals(109, value);
+ try {
+ descendingIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ descendingSet = descendingSet
+ .headSet(new Integer(105).toString(), true);
+ descendingIterator = descendingSet.descendingIterator();
+ for (value = 105; descendingIterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), descendingIterator
+ .next());
+ }
+
+ descendingSet = keySet.descendingSet();
+ descendingSet = descendingSet
+ .tailSet(new Integer(105).toString(), true);
+ descendingIterator = descendingSet.descendingIterator();
+ for (value = 101; descendingIterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), descendingIterator
+ .next());
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingIterator = descendingSet.descendingIterator();
+ assertTrue(descendingIterator.hasNext());
+ for (value = 101; descendingIterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), descendingIterator
+ .next());
+ }
+ assertEquals(110, value);
+ try {
+ descendingIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ descendingSet = descendingSet
+ .headSet(new Integer(105).toString(), true);
+ descendingIterator = descendingSet.descendingIterator();
+ for (value = 105; descendingIterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), descendingIterator
+ .next());
+ }
+
+ descendingSet = keySet.descendingSet();
+ descendingSet = descendingSet
+ .tailSet(new Integer(105).toString(), true);
+ descendingIterator = descendingSet.descendingIterator();
+ for (value = 101; descendingIterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), descendingIterator
+ .next());
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingIterator = descendingSet.descendingIterator();
+ assertTrue(descendingIterator.hasNext());
+ for (value = 100; descendingIterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), descendingIterator
+ .next());
+ }
+ assertEquals(109, value);
+ try {
+ descendingIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ descendingIterator = descendingSet.descendingIterator();
+ assertTrue(descendingIterator.hasNext());
+ for (value = 100; descendingIterator.hasNext(); value++) {
+ assertEquals(new Integer(value).toString(), descendingIterator
+ .next());
+ }
+ assertEquals(110, value);
+ try {
+ descendingIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ String endKey = new Integer(2).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ iterator = keySet.iterator();
+
+ descendingSet = keySet.descendingSet();
+ descendingIterator = descendingSet.descendingIterator();
+
+ while (iterator.hasNext()) {
+ assertEquals(iterator.next(), descendingIterator.next());
+ }
+
+ String startKey = new Integer(2).toString();
+ keySet = tm.tailMap(startKey, true).navigableKeySet();
+ iterator = keySet.iterator();
+ descendingSet = keySet.descendingSet();
+ descendingIterator = descendingSet.descendingIterator();
+
+ while (iterator.hasNext()) {
+ assertEquals(iterator.next(), descendingIterator.next());
+ }
+ }
+
+ public void test_DescendingSubMapKeySet_lower() {
+ NavigableSet keySet, descendingKeySet;
+ Iterator iterator;
+ String key, lowerKey;
+ int value, lowerValue;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) descendingKeySet.lower(key);
+ if (value < 108) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(0).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertEquals(101, Integer.parseInt(lowerKey));
+
+ key = new Integer(2).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertNull(lowerKey);
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) descendingKeySet.lower(key);
+ if (value < 109) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(0).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertEquals(101, Integer.parseInt(lowerKey));
+
+ key = new Integer(2).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertNull(lowerKey);
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) descendingKeySet.lower(key);
+ if (value < 108) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(0).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertEquals(100, Integer.parseInt(lowerKey));
+
+ key = new Integer(2).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertNull(lowerKey);
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) descendingKeySet.lower(key);
+ if (value < 109) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(0).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertEquals(100, Integer.parseInt(lowerKey));
+
+ key = new Integer(2).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertNull(lowerKey);
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ iterator.next();
+ iterator.next();
+ key = (String) iterator.next();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertEquals(new Integer(199).toString(), lowerKey);
+ try {
+ descendingKeySet.lower(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ String endKey = key;
+
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.lower(endKey));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.lower(endKey));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.lower(endKey));
+ assertEquals(new Integer(1).toString(), descendingKeySet.lower(key));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.lower(endKey));
+ assertEquals(new Integer(1).toString(), descendingKeySet.lower(key));
+
+ // With Comparator
+ keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) descendingKeySet.lower(key);
+ if (value < 108) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(0).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertEquals(101, Integer.parseInt(lowerKey));
+
+ key = new Integer(2).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertNull(lowerKey);
+
+ keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) descendingKeySet.lower(key);
+ if (value < 109) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(0).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertEquals(101, Integer.parseInt(lowerKey));
+
+ key = new Integer(2).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertNull(lowerKey);
+
+ keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) descendingKeySet.lower(key);
+ if (value < 108) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(0).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertEquals(100, Integer.parseInt(lowerKey));
+
+ key = new Integer(2).toString();
+ lowerKey = (String) descendingKeySet.lower(key);
+ assertNull(lowerKey);
+
+ keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) descendingKeySet.lower(key);
+ if (value < 109) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+ }
+
+ public void test_DescendingSubMapKeySet_higher() {
+ NavigableSet keySet, descendingKeySet;
+ Iterator iterator;
+ String key, higherKey;
+ int value, higherValue;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ higherKey = (String) descendingKeySet.higher(key);
+ if (value > 101) {
+ higherValue = Integer.valueOf(higherKey);
+ assertEquals(value - 1, higherValue);
+ } else {
+ assertNull(higherKey);
+ }
+ }
+
+ key = new Integer(99999).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals("108", higherKey);
+
+ key = new Integer(-1).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(100).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(0).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(2).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(108, Integer.parseInt(higherKey));
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ higherKey = (String) descendingKeySet.higher(key);
+ if (value > 101) {
+ higherValue = Integer.valueOf(higherKey);
+ assertEquals(value - 1, higherValue);
+ } else {
+ assertNull(higherKey);
+ }
+ }
+
+ key = new Integer(99999).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals("109", higherKey);
+
+ key = new Integer(-1).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(100).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(2).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(109, Integer.parseInt(higherKey));
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ higherKey = (String) descendingKeySet.higher(key);
+ if (value > 100) {
+ higherValue = Integer.valueOf(higherKey);
+ assertEquals(value - 1, higherValue);
+ } else {
+ assertNull(higherKey);
+ }
+ }
+
+ key = new Integer(99999).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals("108", higherKey);
+
+ key = new Integer(-1).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(100).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(2).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(108, Integer.parseInt(higherKey));
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ higherKey = (String) descendingKeySet.higher(key);
+ if (value > 100) {
+ higherValue = Integer.valueOf(higherKey);
+ assertEquals(value - 1, higherValue);
+ } else {
+ assertNull(higherKey);
+ }
+ }
+
+ key = new Integer(99999).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals("109", higherKey);
+
+ key = new Integer(-1).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(100).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(2).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(109, Integer.parseInt(higherKey));
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ key = (String) iterator.next();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(new Integer(199).toString(), higherKey);
+ try {
+ descendingKeySet.higher(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ String endKey = key;
+
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.higher(endKey));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.higher(endKey));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(new Integer(998).toString(), descendingKeySet
+ .higher(endKey));
+ assertNull(descendingKeySet.higher(key));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(new Integer(998).toString(), descendingKeySet
+ .higher(endKey));
+ assertNull(descendingKeySet.higher(key));
+
+ // With Comparator
+ keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ higherKey = (String) descendingKeySet.higher(key);
+ if (value > 101) {
+ higherValue = Integer.valueOf(higherKey);
+ assertEquals(value - 1, higherValue);
+ } else {
+ assertNull(higherKey);
+ }
+ }
+
+ key = new Integer(99999).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals("108", higherKey);
+
+ key = new Integer(-1).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(100).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(0).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(2).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(108, Integer.parseInt(higherKey));
+
+ keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ higherKey = (String) descendingKeySet.higher(key);
+ if (value > 101) {
+ higherValue = Integer.valueOf(higherKey);
+ assertEquals(value - 1, higherValue);
+ } else {
+ assertNull(higherKey);
+ }
+ }
+
+ key = new Integer(99999).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals("109", higherKey);
+
+ key = new Integer(-1).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(100).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(2).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(109, Integer.parseInt(higherKey));
+
+ keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ higherKey = (String) descendingKeySet.higher(key);
+ if (value > 100) {
+ higherValue = Integer.valueOf(higherKey);
+ assertEquals(value - 1, higherValue);
+ } else {
+ assertNull(higherKey);
+ }
+ }
+
+ key = new Integer(99999).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals("108", higherKey);
+
+ key = new Integer(-1).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(100).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(2).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(108, Integer.parseInt(higherKey));
+
+ keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ higherKey = (String) descendingKeySet.higher(key);
+ if (value > 100) {
+ higherValue = Integer.valueOf(higherKey);
+ assertEquals(value - 1, higherValue);
+ } else {
+ assertNull(higherKey);
+ }
+ }
+
+ key = new Integer(99999).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals("109", higherKey);
+
+ key = new Integer(-1).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(100).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertNull(higherKey);
+
+ key = new Integer(2).toString();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(109, Integer.parseInt(higherKey));
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ iterator = descendingKeySet.iterator();
+ key = (String) iterator.next();
+ higherKey = (String) descendingKeySet.higher(key);
+ assertEquals(new Integer(199).toString(), higherKey);
+ try {
+ descendingKeySet.higher(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ endKey = key;
+
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.higher(endKey));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.higher(endKey));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(new Integer(998).toString(), descendingKeySet
+ .higher(endKey));
+ assertNull(descendingKeySet.higher(key));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(new Integer(998).toString(), descendingKeySet
+ .higher(endKey));
+ assertNull(descendingKeySet.higher(key));
+ }
+
+ public void test_DescendingSubMapKeySet_ceiling() {
+ NavigableSet keySet, descendingKeySet;
+ String[] keyArray;
+ String key, ceilingKey;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 108; i < keyArray.length; i++) {
+ ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), ceilingKey);
+ }
+
+ key = new Integer(2).toString();
+ ceilingKey = (String) descendingKeySet.ceiling(key);
+ assertEquals(108, Integer.parseInt(ceilingKey));
+
+ key = new Integer(0).toString();
+ ceilingKey = (String) descendingKeySet.ceiling(key);
+ assertNull(ceilingKey);
+
+ key = new Integer(-1).toString();
+ ceilingKey = (String) descendingKeySet.ceiling(key);
+ assertNull(ceilingKey);
+
+ key = new Integer(99999).toString();
+ ceilingKey = (String) descendingKeySet.ceiling(key);
+ assertEquals(108, Integer.parseInt(ceilingKey));
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 109; i < keyArray.length; i++) {
+ ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), ceilingKey);
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 108; i < keyArray.length; i++) {
+ ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), ceilingKey);
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 109; i < keyArray.length; i++) {
+ ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), ceilingKey);
+ }
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(key, descendingKeySet.ceiling(iterator.next()));
+ try {
+ descendingKeySet.ceiling(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ String endKey = key;
+
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(key, descendingKeySet.ceiling(endKey));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.ceiling(endKey));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(new Integer(999).toString(), descendingKeySet
+ .ceiling(endKey));
+ assertEquals(key, descendingKeySet.ceiling(key));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(new Integer(998).toString(), descendingKeySet
+ .ceiling(endKey));
+ assertEquals(key, descendingKeySet.ceiling(key));
+
+ // With Comparator
+ keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 108; i < keyArray.length; i++) {
+ ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), ceilingKey);
+ }
+
+ key = new Integer(2).toString();
+ ceilingKey = (String) descendingKeySet.ceiling(key);
+ assertEquals(108, Integer.parseInt(ceilingKey));
+
+ key = new Integer(0).toString();
+ ceilingKey = (String) descendingKeySet.ceiling(key);
+ assertNull(ceilingKey);
+
+ keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 109; i < keyArray.length; i++) {
+ ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), ceilingKey);
+ }
+
+ keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 108; i < keyArray.length; i++) {
+ ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), ceilingKey);
+ }
+
+ keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 109; i < keyArray.length; i++) {
+ ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), ceilingKey);
+ }
+ }
+
+ public void test_DescendingSubMapKeySet_floor() {
+ NavigableSet keySet, descendingKeySet;
+ String[] keyArray;
+ String floorKey;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 108; i < keyArray.length; i++) {
+ floorKey = (String) descendingKeySet.floor(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), floorKey);
+ }
+
+ String key = new Integer(0).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertEquals(101, Integer.parseInt(floorKey));
+
+ key = new Integer(2).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertNull(floorKey);
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 109; i < keyArray.length; i++) {
+ floorKey = (String) descendingKeySet.floor(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), floorKey);
+ }
+
+ key = new Integer(0).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertEquals(101, Integer.parseInt(floorKey));
+
+ key = new Integer(2).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertNull(floorKey);
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 108; i < keyArray.length; i++) {
+ floorKey = (String) descendingKeySet.floor(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), floorKey);
+ }
+
+ key = new Integer(0).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertEquals(100, Integer.parseInt(floorKey));
+
+ key = new Integer(2).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertNull(floorKey);
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 109; i < keyArray.length; i++) {
+ floorKey = (String) descendingKeySet.floor(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), floorKey);
+ }
+
+ key = new Integer(0).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertEquals(100, Integer.parseInt(floorKey));
+
+ key = new Integer(2).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertNull(floorKey);
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ Iterator iterator = descendingKeySet.iterator();
+ assertEquals(key, descendingKeySet.floor(iterator.next()));
+ try {
+ descendingKeySet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ String endKey = key;
+
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(key, descendingKeySet.floor(endKey));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.floor(endKey));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertEquals(new Integer(999).toString(), descendingKeySet
+ .floor(endKey));
+ assertEquals(key, descendingKeySet.floor(key));
+
+ endKey = new Integer(999).toString();
+ keySet = tm.headMap(endKey, false).navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ assertNull(descendingKeySet.floor(endKey));
+ assertEquals(key, descendingKeySet.floor(key));
+
+ // With Comparator
+ keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 108; i < keyArray.length; i++) {
+ floorKey = (String) descendingKeySet.floor(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), floorKey);
+ }
+
+ key = new Integer(0).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertEquals(101, Integer.parseInt(floorKey));
+
+ key = new Integer(2).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertNull(floorKey);
+
+ keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 109; i < keyArray.length; i++) {
+ floorKey = (String) descendingKeySet.floor(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), floorKey);
+ }
+
+ key = new Integer(0).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertEquals(101, Integer.parseInt(floorKey));
+
+ key = new Integer(2).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertNull(floorKey);
+
+ keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 108; i < keyArray.length; i++) {
+ floorKey = (String) descendingKeySet.floor(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), floorKey);
+ }
+
+ key = new Integer(0).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertEquals(100, Integer.parseInt(floorKey));
+
+ key = new Integer(2).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertNull(floorKey);
+
+ keySet = ((NavigableMap) subMap_startIncluded_endIncluded)
+ .navigableKeySet();
+ descendingKeySet = keySet.descendingSet();
+ keyArray = (String[]) descendingKeySet
+ .toArray(new String[descendingKeySet.size()]);
+ for (int i = 0, j = 109; i < keyArray.length; i++) {
+ floorKey = (String) descendingKeySet.floor(keyArray[i]);
+ assertEquals(new Integer(j - i).toString(), floorKey);
+ }
+
+ key = new Integer(0).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertEquals(100, Integer.parseInt(floorKey));
+
+ key = new Integer(2).toString();
+ floorKey = (String) descendingKeySet.floor(key);
+ assertNull(floorKey);
+ }
+
+ public void test_AscendingSubMapKeySet_last() {
+ NavigableSet keySet;
+ String firstKey1 = new Integer(108).toString();
+ String firstKey2 = new Integer(109).toString();
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ assertEquals(firstKey1, keySet.last());
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ assertEquals(firstKey2, keySet.last());
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ assertEquals(firstKey1, keySet.last());
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ assertEquals(firstKey2, keySet.last());
+ }
+
+ public void test_AscendingSubMapKeySet_comparator() {
+ NavigableSet keySet;
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ assertNull(keySet.comparator());
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ assertNull(keySet.comparator());
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ assertNull(keySet.comparator());
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ assertNull(keySet.comparator());
+
+ String endKey = new Integer(2).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ assertNull(keySet.comparator());
+ }
+
+ public void test_AscendingSubMapKeySet_pollFirst_startExcluded_endExcluded() {
+ NavigableSet keySet = navigableMap_startExcluded_endExcluded
+ .navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ assertEquals(8, keySet.size());
+ for (int value = 101; value < 109; value++) {
+ assertEquals(new Integer(value).toString(), keySet.pollFirst());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollFirst());
+ }
+
+ public void test_AscendingSubMapKeySet_pollFirst_startExcluded_endIncluded() {
+ NavigableSet keySet = navigableMap_startExcluded_endIncluded
+ .navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ assertEquals(9, keySet.size());
+ for (int value = 101; value < 110; value++) {
+ assertEquals(new Integer(value).toString(), keySet.pollFirst());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollFirst());
+ }
+
+ public void test_AscendingSubMapKeySet_pollFirst_startIncluded_endExcluded() {
+ NavigableSet keySet = navigableMap_startIncluded_endExcluded
+ .navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ assertEquals(9, keySet.size());
+ for (int value = 100; value < 109; value++) {
+ assertEquals(new Integer(value).toString(), keySet.pollFirst());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollFirst());
+ }
+
+ public void test_AscendingSubMapKeySet_pollFirst_startIncluded_endIncluded() {
+ NavigableSet keySet = navigableMap_startIncluded_endIncluded
+ .navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ assertEquals(10, keySet.size());
+ for (int value = 100; value < 110; value++) {
+ assertEquals(new Integer(value).toString(), keySet.pollFirst());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollFirst());
+ }
+
+ public void test_AscendingSubMapKeySet_pollFirst() {
+ String endKey = new Integer(2).toString();
+ NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet();
+ assertEquals(new Integer(0).toString(), keySet.pollFirst());
+
+ keySet = tm.tailMap(endKey, true).navigableKeySet();
+ assertEquals(new Integer(2).toString(), keySet.pollFirst());
+ }
+
+ public void test_AscendingSubMapKeySet_pollLast_startExcluded_endExcluded() {
+ NavigableSet keySet = navigableMap_startExcluded_endExcluded
+ .navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ assertEquals(8, keySet.size());
+ for (int value = 108; value > 100; value--) {
+ assertEquals(new Integer(value).toString(), keySet.pollLast());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_AscendingSubMapKeySet_pollLast_startExcluded_endIncluded() {
+ NavigableSet keySet = navigableMap_startExcluded_endIncluded
+ .navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ assertEquals(9, keySet.size());
+ for (int value = 109; value > 100; value--) {
+ assertEquals(new Integer(value).toString(), keySet.pollLast());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_AscendingSubMapKeySet_pollLast_startIncluded_endExcluded() {
+ NavigableSet keySet = navigableMap_startIncluded_endExcluded
+ .navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ assertEquals(9, keySet.size());
+ for (int value = 108; value > 99; value--) {
+ assertEquals(new Integer(value).toString(), keySet.pollLast());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_AscendingSubMapKeySet_pollLast_startIncluded_endIncluded() {
+ NavigableSet keySet = navigableMap_startIncluded_endIncluded
+ .navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ assertEquals(10, keySet.size());
+ for (int value = 109; value > 99; value--) {
+ assertEquals(new Integer(value).toString(), keySet.pollLast());
+ }
+ assertEquals(0, keySet.size());
+ assertNull(keySet.pollLast());
+ }
+
+ public void test_AscendingSubMapKeySet_pollLast() {
+ String endKey = new Integer(2).toString();
+ NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet();
+ assertEquals(new Integer(2).toString(), keySet.pollLast());
+
+ keySet = tm.tailMap(endKey, true).navigableKeySet();
+ assertEquals(new Integer(999).toString(), keySet.pollLast());
+ }
+
+ public void test_AscendingSubMapKeySet_descendingIterator() {
+ NavigableSet keySet;
+ Iterator iterator;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ iterator = keySet.descendingIterator();
+ for (int value = 108; value > 100; value--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ iterator = keySet.descendingIterator();
+ for (int value = 109; value > 100; value--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ iterator = keySet.descendingIterator();
+ for (int value = 108; value > 99; value--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ iterator = keySet.descendingIterator();
+ for (int value = 109; value > 99; value--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ String endKey = new Integer(2).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ iterator = keySet.descendingIterator();
+ assertEquals(new Integer(2).toString(), iterator.next());
+ assertEquals(new Integer(199).toString(), iterator.next());
+ }
+
+ public void test_AscendingSubMapKeySet_descendingSet() {
+ NavigableSet keySet, descendingSet;
+ Iterator iterator;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet()
+ .descendingSet();
+ descendingSet = keySet.descendingSet();
+ iterator = descendingSet.iterator();
+ for (int value = 101; value < 109; value++) {
+ assertTrue(iterator.hasNext());
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet()
+ .descendingSet();
+ descendingSet = keySet.descendingSet();
+ iterator = descendingSet.iterator();
+ for (int value = 101; value < 110; value++) {
+ assertTrue(iterator.hasNext());
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet()
+ .descendingSet();
+ descendingSet = keySet.descendingSet();
+ iterator = descendingSet.iterator();
+ for (int value = 100; value < 109; value++) {
+ assertTrue(iterator.hasNext());
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet()
+ .descendingSet();
+ descendingSet = keySet.descendingSet();
+ iterator = descendingSet.iterator();
+ for (int value = 100; value < 110; value++) {
+ assertTrue(iterator.hasNext());
+ assertEquals(new Integer(value).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ String endKey = new Integer(1).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ descendingSet = keySet.descendingSet();
+ iterator = descendingSet.iterator();
+ assertEquals(new Integer(1).toString(), iterator.next());
+ assertEquals(new Integer(0).toString(), iterator.next());
+ }
+
+ public void test_AscendingSubMapKeySet_headSet() {
+ NavigableSet keySet;
+ SortedSet headSet;
+ String endKey, key;
+ Iterator iterator;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ endKey = new Integer(99).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(101).toString();
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(0, keySet.headSet(endKey, false).size());
+ assertEquals(1, keySet.headSet(endKey, true).size());
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i + 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int index;
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(110).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ endKey = new Integer(99).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(101).toString();
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(1, keySet.headSet(endKey, true).size());
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i + 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ endKey = new Integer(110).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ endKey = new Integer(99).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(0, keySet.headSet(endKey, false).size());
+ assertEquals(1, keySet.headSet(endKey, true).size());
+
+ endKey = new Integer(101).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(102, index);
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i + 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(110).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ endKey = new Integer(99).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(0, keySet.headSet(endKey, false).size());
+ assertEquals(1, keySet.headSet(endKey, true).size());
+
+ endKey = new Integer(101).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(102, index);
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i + 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ endKey = new Integer(110).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ key = new Integer(1).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ iterator = keySet.iterator();
+ iterator.next();
+ endKey = (String) iterator.next();
+ headSet = keySet.headSet(endKey, false);
+ assertEquals(1, headSet.size());
+ Iterator headSetIterator = headSet.iterator();
+ assertEquals(new Integer(0).toString(), headSetIterator.next());
+ assertFalse(headSetIterator.hasNext());
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ headSet = keySet.headSet(endKey, true);
+ assertEquals(2, headSet.size());
+ headSetIterator = headSet.iterator();
+ assertEquals(new Integer(0).toString(), headSetIterator.next());
+ assertEquals(new Integer(1).toString(), headSetIterator.next());
+ assertFalse(headSetIterator.hasNext());
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ // With Comparator
+ keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .navigableKeySet();
+ endKey = new Integer(99).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ try {
+ keySet.headSet(endKey).size();
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, false).size();
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, true).size();
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(101).toString();
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(0, keySet.headSet(endKey, false).size());
+ assertEquals(1, keySet.headSet(endKey, true).size());
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i + 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(110).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+ .navigableKeySet();
+ endKey = new Integer(99).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(101).toString();
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(1, keySet.headSet(endKey, true).size());
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 101; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i + 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ endKey = new Integer(110).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+ .navigableKeySet();
+ endKey = new Integer(99).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(0, keySet.headSet(endKey, false).size());
+ assertEquals(1, keySet.headSet(endKey, true).size());
+
+ endKey = new Integer(101).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(102, index);
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i + 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(110).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+ .navigableKeySet();
+ endKey = new Integer(99).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ endKey = new Integer(100).toString();
+ assertEquals(0, keySet.headSet(endKey).size());
+ assertEquals(0, keySet.headSet(endKey, false).size());
+ assertEquals(1, keySet.headSet(endKey, true).size());
+
+ endKey = new Integer(101).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(101, index);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(102, index);
+
+ for (int i = 102; i < 109; i++) {
+ endKey = new Integer(i).toString();
+
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ int j;
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i, j);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (j = 100; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(i + 1, j);
+ }
+
+ endKey = new Integer(109).toString();
+ headSet = keySet.headSet(endKey);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, false);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ headSet = keySet.headSet(endKey, true);
+ iterator = headSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ endKey = new Integer(110).toString();
+ try {
+ keySet.headSet(endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(endKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ key = new Integer(1).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ iterator = keySet.iterator();
+ iterator.next();
+ endKey = (String) iterator.next();
+ headSet = keySet.headSet(endKey, false);
+ assertEquals(1, headSet.size());
+ headSetIterator = headSet.iterator();
+ assertEquals(new Integer(0).toString(), headSetIterator.next());
+ assertFalse(headSetIterator.hasNext());
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ headSet = keySet.headSet(endKey, true);
+ assertEquals(2, headSet.size());
+ headSetIterator = headSet.iterator();
+ assertEquals(new Integer(0).toString(), headSetIterator.next());
+ assertEquals(new Integer(1).toString(), headSetIterator.next());
+ assertFalse(headSetIterator.hasNext());
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ try {
+ keySet.headSet(null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ }
+
+ public void test_AscendingSubMapKeySet_remove() {
+ TreeMap tm_rm = new TreeMap(tm);
+ SortedMap subMap_startExcluded_endExcluded_rm = tm_rm.subMap(
+ objArray[100].toString(), false, objArray[109].toString(),
+ false);
+ assertNull(subMap_startExcluded_endExcluded_rm.remove("0"));
+ try {
+ subMap_startExcluded_endExcluded_rm.remove(null);
+ fail("should throw NPE");
+ } catch (Exception e) {
+ // Expected
+ }
+ for (int i = 101; i < 108; i++) {
+ assertNotNull(subMap_startExcluded_endExcluded_rm
+ .remove(new Integer(i).toString()));
+ }
+ }
+
+ public void test_AscendingSubMapKeySet_tailSet() {
+ NavigableSet keySet;
+ SortedSet tailSet;
+ String startKey, key;
+ Iterator iterator;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ startKey = new Integer(99).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ int index;
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; index < 109; index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+
+ startKey = new Integer(101).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(108, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(109, j);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(109, j);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j + 1).toString(), key);
+ }
+ assertEquals(108, j);
+ }
+
+ startKey = new Integer(109).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(110).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ startKey = new Integer(99).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(109, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(110, j);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(110, j);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j + 1).toString(), key);
+ }
+ assertEquals(109, j);
+ }
+
+ startKey = new Integer(109).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(109, index);
+
+ startKey = new Integer(110).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ startKey = new Integer(99).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(108, index);
+
+ startKey = new Integer(101).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(108, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(109, j);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(109, j);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j + 1).toString(), key);
+ }
+ assertEquals(108, j);
+ }
+
+ startKey = new Integer(109).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(110).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ startKey = new Integer(99).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ startKey = new Integer(100).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(109, index);
+
+ startKey = new Integer(101).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(109, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(110, j);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(110, j);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j + 1).toString(), key);
+ }
+ assertEquals(109, j);
+ }
+
+ startKey = new Integer(109).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(109, index);
+
+ startKey = new Integer(110).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ String endKey = new Integer(1).toString();
+ keySet = tm.headMap(endKey, true).navigableKeySet();
+ iterator = keySet.iterator();
+ iterator.next();
+ startKey = (String) iterator.next();
+ tailSet = keySet.tailSet(startKey);
+ assertEquals(1, tailSet.size());
+ Iterator tailSetIterator = tailSet.iterator();
+ assertEquals(endKey, tailSetIterator.next());
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ tailSet = keySet.tailSet(startKey, true);
+ assertEquals(1, tailSet.size());
+ tailSetIterator = tailSet.iterator();
+ assertEquals(endKey, tailSetIterator.next());
+
+ tailSet = keySet.tailSet(startKey, false);
+ assertEquals(0, tailSet.size());
+ tailSetIterator = tailSet.iterator();
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ // With Comparator
+ keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .navigableKeySet();
+ startKey = new Integer(99).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; index < 109; index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+
+ startKey = new Integer(101).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(109, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 101; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(108, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(109, j);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(109, j);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j + 1).toString(), key);
+ }
+ assertEquals(108, j);
+ }
+
+ startKey = new Integer(109).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(110).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ startKey = new Integer(99).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ startKey = new Integer(100).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 100; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(109, index);
+
+ for (int i = 102; i < 109; i++) {
+ startKey = new Integer(i).toString();
+
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ int j;
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(110, j);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j).toString(), key);
+ }
+ assertEquals(110, j);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (j = i; iterator.hasNext(); j++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(j + 1).toString(), key);
+ }
+ assertEquals(109, j);
+ }
+
+ startKey = new Integer(109).toString();
+ tailSet = keySet.tailSet(startKey);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, true);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index).toString(), key);
+ }
+ assertEquals(110, index);
+
+ tailSet = keySet.tailSet(startKey, false);
+ iterator = tailSet.iterator();
+ for (index = 109; iterator.hasNext(); index++) {
+ key = (String) iterator.next();
+ assertEquals(new Integer(index + 1).toString(), key);
+ }
+ assertEquals(109, index);
+
+ startKey = new Integer(110).toString();
+ try {
+ keySet.tailSet(startKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ try {
+ keySet.tailSet(startKey, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void test_AscendingSubMapKeySet_subSet() {
+ NavigableSet keySet;
+ SortedSet subSet;
+ String startKey, endKey, key;
+ Iterator startIterator, endIterator, subSetIterator;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ startIterator = keySet.iterator();
+ while (startIterator.hasNext()) {
+ startKey = (String) startIterator.next();
+ endIterator = keySet.iterator();
+ while (endIterator.hasNext()) {
+ endKey = (String) endIterator.next();
+ int startIndex = Integer.valueOf(startKey);
+ int endIndex = Integer.valueOf(endKey);
+ if (startIndex > endIndex) {
+ try {
+ keySet.subSet(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, false, endKey, false);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, false, endKey, true);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, true, endKey, false);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, true, endKey, true);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } else {
+ subSet = keySet.subSet(startKey, endKey);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = keySet.subSet(startKey, false, endKey, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex + 1; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = keySet.subSet(startKey, false, endKey, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex + 1; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = keySet.subSet(startKey, true, endKey, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = keySet.subSet(startKey, true, endKey, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+ }
+ }
+ }
+
+ key = new Integer(1).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ startKey = (String) iterator.next();
+ endKey = (String) iterator.next();
+
+ subSet = keySet.subSet(startKey, endKey);
+ assertEquals(1, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(new Integer(0).toString(), subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = keySet.subSet(startKey, false, endKey, false);
+ assertEquals(0, subSet.size());
+
+ subSet = keySet.subSet(startKey, false, endKey, true);
+ assertEquals(1, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(new Integer(1).toString(), subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = keySet.subSet(startKey, true, endKey, false);
+ assertEquals(1, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(new Integer(0).toString(), subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = keySet.subSet(startKey, true, endKey, true);
+ assertEquals(2, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(new Integer(0).toString(), subSetIterator.next());
+ assertEquals(new Integer(1).toString(), subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, false, null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, false, null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, true, null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, true, null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, endKey);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, false, endKey, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, false, endKey, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, true, endKey, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, true, endKey, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, false, null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, false, null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, true, null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, true, null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ // With Comparator
+ keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+ .navigableKeySet();
+ startIterator = keySet.iterator();
+ while (startIterator.hasNext()) {
+ startKey = (String) startIterator.next();
+ endIterator = keySet.iterator();
+ while (endIterator.hasNext()) {
+ endKey = (String) endIterator.next();
+ int startIndex = Integer.valueOf(startKey);
+ int endIndex = Integer.valueOf(endKey);
+ if (startIndex > endIndex) {
+ try {
+ keySet.subSet(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, false, endKey, false);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, false, endKey, true);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, true, endKey, false);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, true, endKey, true);
+ fail("shoudl throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } else {
+ subSet = keySet.subSet(startKey, endKey);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = keySet.subSet(startKey, false, endKey, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex + 1; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = keySet.subSet(startKey, false, endKey, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex + 1; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = keySet.subSet(startKey, true, endKey, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+
+ subSet = keySet.subSet(startKey, true, endKey, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index++) {
+ assertEquals(new Integer(index).toString(),
+ subSetIterator.next());
+ }
+ }
+ }
+ }
+
+ key = new Integer(1).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ iterator = keySet.iterator();
+ startKey = (String) iterator.next();
+ endKey = (String) iterator.next();
+
+ subSet = keySet.subSet(startKey, endKey);
+ assertEquals(1, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(new Integer(0).toString(), subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = keySet.subSet(startKey, false, endKey, false);
+ assertEquals(0, subSet.size());
+
+ subSet = keySet.subSet(startKey, false, endKey, true);
+ assertEquals(1, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(new Integer(1).toString(), subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = keySet.subSet(startKey, true, endKey, false);
+ assertEquals(1, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(new Integer(0).toString(), subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ subSet = keySet.subSet(startKey, true, endKey, true);
+ assertEquals(2, subSet.size());
+ subSetIterator = subSet.iterator();
+ assertEquals(new Integer(0).toString(), subSetIterator.next());
+ assertEquals(new Integer(1).toString(), subSetIterator.next());
+ try {
+ subSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, false, null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, false, null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, true, null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, true, null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, endKey);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, false, endKey, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, false, endKey, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, true, endKey, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(null, true, endKey, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, false, null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, false, null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, true, null, false);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ keySet.subSet(startKey, true, null, true);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ }
+
+ public void test_AscendingSubMapKeySet_lower() {
+ NavigableSet keySet;
+ Iterator iterator;
+ String key, lowerKey;
+ int value, lowerValue;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ iterator = keySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) keySet.lower(key);
+ if (value > 101) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value - 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ iterator = keySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) keySet.lower(key);
+ if (value > 101) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value - 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ iterator = keySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) keySet.lower(key);
+ if (value > 100) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value - 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ iterator = keySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) keySet.lower(key);
+ if (value > 100) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value - 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ iterator = keySet.iterator();
+ iterator.next();// 0
+ String expectedLowerKey = (String) iterator.next();// 1
+ assertEquals(expectedLowerKey, keySet.lower(iterator.next()));
+
+ try {
+ keySet.lower(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ assertNull(keySet.lower(key));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(key, false).navigableKeySet();
+ assertNull(keySet.lower(key));
+
+ key = new Integer(999).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ assertNotNull(keySet.lower(key));
+
+ key = new Integer(999).toString();
+ keySet = tm.headMap(key, false).navigableKeySet();
+ assertNotNull(keySet.lower(key));
+ }
+
+ public void test_AscendingSubMapKeySet_higher() {
+ NavigableSet keySet;
+ Iterator iterator;
+ String key, lowerKey;
+ int value, lowerValue;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ iterator = keySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) keySet.higher(key);
+ if (value < 108) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ iterator = keySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) keySet.higher(key);
+ if (value < 109) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ iterator = keySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) keySet.higher(key);
+ if (value < 108) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ iterator = keySet.iterator();
+ while (iterator.hasNext()) {
+ key = (String) iterator.next();
+ value = Integer.valueOf(key);
+ lowerKey = (String) keySet.higher(key);
+ if (value < 109) {
+ lowerValue = Integer.valueOf(lowerKey);
+ assertEquals(value + 1, lowerValue);
+ } else {
+ assertNull(lowerKey);
+ }
+ }
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ iterator = keySet.iterator();
+ iterator.next();// 0
+ iterator.next();// 1
+ lowerKey = (String) keySet.higher(iterator.next());
+ String expectedLowerKey = (String) iterator.next();
+ assertEquals(expectedLowerKey, lowerKey);
+
+ try {
+ keySet.higher(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ assertNull(keySet.higher(key));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(key, false).navigableKeySet();
+ assertNull(keySet.higher(key));
+
+ key = new Integer(999).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ assertNull(keySet.higher(key));
+
+ key = new Integer(999).toString();
+ keySet = tm.headMap(key, false).navigableKeySet();
+ assertNull(keySet.higher(key));
+ }
+
+ public void test_AscendingSubMapKeySet_ceiling() {
+ NavigableSet keySet;
+ String key;
+ String[] keyArray;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+ for (int i = 0, j = 101; i < keyArray.length; i++) {
+ key = (String) keySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(i + j).toString(), key);
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+ for (int i = 0, j = 101; i < keyArray.length; i++) {
+ key = (String) keySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(i + j).toString(), key);
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+ for (int i = 0, j = 100; i < keyArray.length; i++) {
+ key = (String) keySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(i + j).toString(), key);
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+ for (int i = 0, j = 100; i < keyArray.length; i++) {
+ key = (String) keySet.ceiling(keyArray[i]);
+ assertEquals(new Integer(i + j).toString(), key);
+ }
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ iterator.next();
+ assertEquals(new Integer(1).toString(), keySet.ceiling(iterator.next()));
+
+ try {
+ keySet.ceiling(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ assertEquals(key, keySet.ceiling(key));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(key, false).navigableKeySet();
+ assertNull(keySet.higher(key));
+
+ key = new Integer(999).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ assertNull(keySet.higher(key));
+
+ key = new Integer(999).toString();
+ keySet = tm.headMap(key, false).navigableKeySet();
+ assertNull(keySet.higher(key));
+ }
+
+ public void test_AscendingSubMapKeySet_floor() {
+ NavigableSet keySet;
+ String key;
+ String[] keyArray;
+
+ keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+ keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+ for (int i = 0, j = 101; i < keyArray.length; i++) {
+ key = (String) keySet.floor(keyArray[i]);
+ assertEquals(new Integer(i + j).toString(), key);
+ }
+
+ keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+ keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+ for (int i = 0, j = 101; i < keyArray.length; i++) {
+ key = (String) keySet.floor(keyArray[i]);
+ assertEquals(new Integer(i + j).toString(), key);
+ }
+
+ keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+ keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+ for (int i = 0, j = 100; i < keyArray.length; i++) {
+ key = (String) keySet.floor(keyArray[i]);
+ assertEquals(new Integer(i + j).toString(), key);
+ }
+
+ keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+ keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+ for (int i = 0, j = 100; i < keyArray.length; i++) {
+ key = (String) keySet.floor(keyArray[i]);
+ assertEquals(new Integer(i + j).toString(), key);
+ }
+
+ key = new Integer(2).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ Iterator iterator = keySet.iterator();
+ iterator.next();
+ assertEquals(new Integer(1).toString(), keySet.floor(iterator.next()));
+
+ try {
+ keySet.floor(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ assertEquals(key, keySet.floor(key));
+
+ key = new Integer(0).toString();
+ keySet = tm.headMap(key, false).navigableKeySet();
+ assertNull(keySet.floor(key));
+
+ key = new Integer(999).toString();
+ keySet = tm.headMap(key, true).navigableKeySet();
+ assertEquals(key, keySet.floor(key));
+
+ key = new Integer(999).toString();
+ keySet = tm.headMap(key, false).navigableKeySet();
+ assertEquals(new Integer(998).toString(), keySet.floor(key));
+ }
+
+ public void test_BoundedEntryIterator_next() {
+ Iterator iterator = subMap_default.entrySet().iterator();
+ assertTrue(iterator.hasNext());
+ for (int i = 100; iterator.hasNext(); i++) {
+ assertEquals(i, ((Entry) iterator.next()).getValue());
+ }
+
+ try {
+ iterator.next();
+ fail("should throw java.util.NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ }
+
+ public void test_BoundedKeyIterator_next() {
+ Iterator iterator = subMap_default.keySet().iterator();
+ assertTrue(iterator.hasNext());
+ for (int i = 100; iterator.hasNext(); i++) {
+ assertEquals(new Integer(i).toString(), iterator.next());
+ }
+
+ try {
+ iterator.next();
+ fail("should throw java.util.NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ public void test_BoundedValueIterator_next() {
+ String startKey = new Integer(101).toString();
+ String endKey = new Integer(108).toString();
+
+ Collection values = tm.subMap(startKey, endKey).values();
+ Iterator iter = values.iterator();
+ for (int i = 101; i < 108; i++) {
+ assertEquals(i, iter.next());
+ }
+ try {
+ iter.next();
+ fail("should throw java.util.NoSuchElementException");
+ } catch (Exception e) {
+ // Expected
+ }
+ }
+
+ /*
+ * SubMapEntrySet
+ */
+ public void test_SubMapEntrySet_Constructor() {
+ }
+
+ public void test_SubMapEntrySet_contains() {
+ // covered in test_SubMapEntrySet_remove
+ }
+
+ public void test_SubMapEntrySet_iterator() {
+ Set entrySet = subMap_default.entrySet();
+ Iterator iterator;
+ Entry entry;
+ Integer value = new Integer(100);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(109, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ entrySet = subMap_startExcluded_endExcluded.entrySet();
+ value = new Integer(101);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(109, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ entrySet = subMap_startExcluded_endIncluded.entrySet();
+ value = new Integer(101);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(110, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ entrySet = subMap_startIncluded_endExcluded.entrySet();
+ value = new Integer(100);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(109, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ entrySet = subMap_startIncluded_endIncluded.entrySet();
+ value = new Integer(100);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(110, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ String startKey = new Integer(-1).toString();
+ String endKey = new Integer(0).toString();
+ SortedMap subMap = tm.subMap(startKey, endKey);
+ entrySet = subMap.entrySet();
+ iterator = entrySet.iterator();
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ endKey = new Integer(1).toString();
+ subMap = tm.subMap(startKey, endKey);
+ entrySet = subMap.entrySet();
+ iterator = entrySet.iterator();
+ assertEquals(0, ((Entry) iterator.next()).getValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ endKey = new Integer(2000).toString();
+ subMap = tm.subMap(startKey, endKey);
+ entrySet = subMap.entrySet();
+ iterator = entrySet.iterator();
+ for (int i = 0; i < subMap.size(); i++) {
+ iterator.next();
+ }
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ startKey = new Integer(9).toString();
+ endKey = new Integer(100).toString();
+ try {
+ tm.subMap(startKey, endKey);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // With Comparator
+ entrySet = subMap_default_comparator.entrySet();
+ value = new Integer(100);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(109, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+ value = new Integer(101);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(109, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+ value = new Integer(101);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(110, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+ value = new Integer(100);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(109, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+ value = new Integer(100);
+ for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+ entry = (Entry) iterator.next();
+ assertEquals(value.toString(), entry.getKey());
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(110, value.intValue());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ public void test_SubMapEntrySet_remove() {
+ Set entrySet = subMap_default.entrySet();
+ assertFalse(entrySet.remove(null));
+ int size = entrySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = entrySet.iterator();
+ assertTrue(entrySet.remove(iterator.next()));
+ }
+
+ entrySet = subMap_startExcluded_endExcluded.entrySet();
+ assertFalse(entrySet.remove(null));
+ size = entrySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = entrySet.iterator();
+ assertTrue(entrySet.remove(iterator.next()));
+ }
+
+ entrySet = subMap_startExcluded_endIncluded.entrySet();
+ assertFalse(entrySet.remove(null));
+ size = entrySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = entrySet.iterator();
+ assertTrue(entrySet.remove(iterator.next()));
+ }
+
+ entrySet = subMap_startIncluded_endExcluded.entrySet();
+ assertFalse(entrySet.remove(null));
+ size = entrySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = entrySet.iterator();
+ assertTrue(entrySet.remove(iterator.next()));
+ }
+
+ entrySet = subMap_startIncluded_endIncluded.entrySet();
+ assertFalse(entrySet.remove(null));
+ size = entrySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = entrySet.iterator();
+ assertTrue(entrySet.remove(iterator.next()));
+ }
+ }
+
+ public void test_SubMapEntrySet_isEmpty() {
+ assertFalse(subMap_default.entrySet().isEmpty());
+ assertFalse(subMap_startExcluded_endExcluded.entrySet().isEmpty());
+ assertFalse(subMap_startExcluded_endIncluded.entrySet().isEmpty());
+ assertFalse(subMap_startIncluded_endExcluded.entrySet().isEmpty());
+ assertFalse(subMap_startIncluded_endIncluded.entrySet().isEmpty());
+
+ String startKey = new Integer(0).toString();
+ String endKey = startKey;
+ SortedMap subMap = tm.subMap(startKey, endKey);
+ assertTrue(subMap.entrySet().isEmpty());
+
+ startKey = new Integer(-1).toString();
+ subMap = tm.subMap(startKey, endKey);
+ assertTrue(subMap.entrySet().isEmpty());
+
+ endKey = new Integer(1).toString();
+ subMap = tm.subMap(startKey, endKey);
+ assertFalse(subMap.entrySet().isEmpty());
+ }
+
+ public void test_SubMapEntrySet_size() {
+ assertEquals(9, subMap_default.entrySet().size());
+ assertEquals(8, subMap_startExcluded_endExcluded.entrySet().size());
+ assertEquals(9, subMap_startExcluded_endIncluded.entrySet().size());
+ assertEquals(9, subMap_startIncluded_endExcluded.entrySet().size());
+ assertEquals(10, subMap_startIncluded_endIncluded.entrySet().size());
+
+ String startKey = new Integer(0).toString();
+ String endKey = new Integer(2).toString();
+ SortedMap subMap = tm.subMap(startKey, endKey);
+ assertEquals(112, subMap.entrySet().size());
+
+ startKey = new Integer(0).toString();
+ endKey = startKey;
+ subMap = tm.subMap(startKey, endKey);
+ assertEquals(0, subMap.entrySet().size());
+
+ startKey = new Integer(-1).toString();
+ endKey = startKey;
+ subMap = tm.subMap(startKey, endKey);
+ assertEquals(0, subMap.entrySet().size());
+
+ endKey = new Integer(1).toString();
+ subMap = tm.subMap(startKey, endKey);
+ assertEquals(1, subMap.entrySet().size());
+
+ startKey = new Integer(999).toString();
+ endKey = startKey;
+ subMap = tm.subMap(startKey, endKey);
+ assertEquals(0, subMap.entrySet().size());
+ }
+
+ /*
+ * SubMapKeySet
+ */
+ public void test_SubMapKeySet_Constructor() {
+ // covered in other test
+ }
+
+ public void test_SubMapKeySet_iterator() {
+ Set keySet = subMap_default.keySet();
+ Iterator iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(100 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = subMap_startExcluded_endExcluded.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(101 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = subMap_startExcluded_endIncluded.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(101 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = subMap_startIncluded_endExcluded.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(100 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = subMap_startIncluded_endIncluded.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(100 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ // With Comparator
+ keySet = subMap_default_comparator.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(100 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = subMap_startExcluded_endExcluded_comparator.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(101 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = subMap_startExcluded_endIncluded_comparator.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(101 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = subMap_startIncluded_endExcluded_comparator.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(100 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ keySet = subMap_startIncluded_endIncluded_comparator.keySet();
+ iterator = keySet.iterator();
+ for (int i = 0; i < keySet.size(); i++) {
+ assertEquals(new Integer(100 + i).toString(), iterator.next());
+ }
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+
+ public void test_SubMapKeySet_isEmpty() {
+ assertFalse(subMap_default.keySet().isEmpty());
+ assertFalse(subMap_startExcluded_endExcluded.keySet().isEmpty());
+ assertFalse(subMap_startExcluded_endIncluded.keySet().isEmpty());
+ assertFalse(subMap_startIncluded_endExcluded.keySet().isEmpty());
+ assertFalse(subMap_startIncluded_endIncluded.keySet().isEmpty());
+
+ String startKey = new Integer(0).toString();
+ String endKey = startKey;
+ SortedMap subMap = tm.subMap(startKey, endKey);
+ assertTrue(subMap.keySet().isEmpty());
+
+ startKey = new Integer(999).toString();
+ endKey = startKey;
+ subMap = tm.subMap(startKey, endKey);
+ assertTrue(subMap.keySet().isEmpty());
+
+ startKey = new Integer(-1).toString();
+ endKey = new Integer(1).toString();
+ subMap = tm.subMap(startKey, endKey);
+ assertFalse(subMap.keySet().isEmpty());
+
+ endKey = new Integer(0).toString();
+ subMap = tm.subMap(startKey, endKey);
+ assertTrue(subMap.keySet().isEmpty());
+ }
+
+ public void test_SubMapKeySet_contains() {
+ Set keySet = subMap_default.keySet();
+ try {
+ keySet.contains(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ String key = new Integer(-1).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(99).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(100).toString();
+ assertTrue(keySet.contains(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(keySet.contains(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(110).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(1001).toString();
+ assertFalse(keySet.contains(key));
+
+ keySet = subMap_startExcluded_endExcluded.keySet();
+ try {
+ keySet.contains(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ key = new Integer(-1).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(99).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(100).toString();
+ assertFalse(keySet.contains(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(keySet.contains(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(110).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(1001).toString();
+ assertFalse(keySet.contains(key));
+
+ keySet = subMap_startExcluded_endIncluded.keySet();
+ try {
+ keySet.contains(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ key = new Integer(-1).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(99).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(100).toString();
+ assertFalse(keySet.contains(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(keySet.contains(key));
+ }
+ key = new Integer(109).toString();
+ assertTrue(keySet.contains(key));
+ key = new Integer(110).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(1001).toString();
+ assertFalse(keySet.contains(key));
+
+ keySet = subMap_startIncluded_endExcluded.keySet();
+ try {
+ keySet.contains(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ key = new Integer(-1).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(99).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(100).toString();
+ assertTrue(keySet.contains(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(keySet.contains(key));
+ }
+ key = new Integer(109).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(110).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(1001).toString();
+ assertFalse(keySet.contains(key));
+
+ keySet = subMap_startIncluded_endIncluded.keySet();
+ try {
+ keySet.contains(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ key = new Integer(-1).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(99).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(100).toString();
+ assertTrue(keySet.contains(key));
+ for (int i = 101; i < 109; i++) {
+ key = new Integer(i).toString();
+ assertTrue(keySet.contains(key));
+ }
+ key = new Integer(109).toString();
+ assertTrue(keySet.contains(key));
+ key = new Integer(110).toString();
+ assertFalse(keySet.contains(key));
+ key = new Integer(1001).toString();
+ assertFalse(keySet.contains(key));
+ }
+
+ public void test_SubMapKeySet_size() {
+ assertEquals(9, subMap_default.keySet().size());
+ assertEquals(8, subMap_startExcluded_endExcluded.keySet().size());
+ assertEquals(9, subMap_startExcluded_endIncluded.keySet().size());
+ assertEquals(9, subMap_startIncluded_endExcluded.keySet().size());
+ assertEquals(10, subMap_startIncluded_endIncluded.keySet().size());
+
+ String startKey = new Integer(0).toString();
+ String endKey = new Integer(2).toString();
+ SortedMap subMap = tm.subMap(startKey, endKey);
+ assertEquals(112, subMap.keySet().size());
+
+ startKey = new Integer(0).toString();
+ endKey = startKey;
+ subMap = tm.subMap(startKey, endKey);
+ assertEquals(0, subMap.keySet().size());
+
+ startKey = new Integer(-1).toString();
+ endKey = startKey;
+ subMap = tm.subMap(startKey, endKey);
+ assertEquals(0, subMap.keySet().size());
+
+ endKey = new Integer(1).toString();
+ subMap = tm.subMap(startKey, endKey);
+ assertEquals(1, subMap.keySet().size());
+
+ startKey = new Integer(999).toString();
+ endKey = startKey;
+ subMap = tm.subMap(startKey, endKey);
+ assertEquals(0, subMap.keySet().size());
+ }
+
+ public void test_SubMapKeySet_remove() {
+ Set keySet = subMap_default.keySet();
+ try {
+ keySet.remove(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ int size = keySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = keySet.iterator();
+ assertTrue(keySet.remove(iterator.next()));
+ }
+
+ keySet = subMap_startExcluded_endExcluded.keySet();
+ try {
+ keySet.remove(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ size = keySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = keySet.iterator();
+ assertTrue(keySet.remove(iterator.next()));
+ }
+
+ keySet = subMap_startExcluded_endIncluded.keySet();
+ try {
+ keySet.remove(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ size = keySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = keySet.iterator();
+ assertTrue(keySet.remove(iterator.next()));
+ }
+
+ keySet = subMap_startIncluded_endExcluded.keySet();
+ try {
+ keySet.remove(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ size = keySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = keySet.iterator();
+ assertTrue(keySet.remove(iterator.next()));
+ }
+
+ keySet = subMap_startIncluded_endIncluded.keySet();
+ try {
+ keySet.remove(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ size = keySet.size();
+ for (int i = 0; i < size; i++) {
+ Iterator iterator = keySet.iterator();
+ assertTrue(keySet.remove(iterator.next()));
+ }
+ }
+
+ /*
+ * AscendingSubMapEntrySet
+ */
+
+ public void test_AscendingSubMapEntrySet_comparator() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ assertNull(ascendingSubMapEntrySet.comparator());
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ assertNull(ascendingSubMapEntrySet.comparator());
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ assertNull(ascendingSubMapEntrySet.comparator());
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ assertNull(ascendingSubMapEntrySet.comparator());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_descendingSet() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet, descendingSet;
+ Entry entry;
+ int value;
+ Iterator iterator;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ iterator = descendingSet.iterator();
+ assertTrue(iterator.hasNext());
+ for (value = 108; iterator.hasNext(); value--) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(100, value);
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ iterator = descendingSet.iterator();
+ assertTrue(iterator.hasNext());
+ for (value = 109; iterator.hasNext(); value--) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(100, value);
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ iterator = descendingSet.iterator();
+ assertTrue(iterator.hasNext());
+ for (value = 108; iterator.hasNext(); value--) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(99, value);
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ descendingSet = ascendingSubMapEntrySet.descendingSet();
+ iterator = descendingSet.iterator();
+ assertTrue(iterator.hasNext());
+ for (value = 109; iterator.hasNext(); value--) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(99, value);
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_descendingIterator() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet;
+ Iterator iterator;
+ Entry entry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.descendingIterator();
+ assertTrue(iterator.hasNext());
+ for (value = 108; iterator.hasNext(); value--) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(100, value);
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.descendingIterator();
+ assertTrue(iterator.hasNext());
+ for (value = 109; iterator.hasNext(); value--) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(100, value);
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.descendingIterator();
+ assertTrue(iterator.hasNext());
+ for (value = 108; iterator.hasNext(); value--) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(99, value);
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.descendingIterator();
+ assertTrue(iterator.hasNext());
+ for (value = 109; iterator.hasNext(); value--) {
+ entry = (Entry) iterator.next();
+ assertEquals(value, entry.getValue());
+ }
+ assertEquals(99, value);
+ }
+
+ String startKey = new Integer(2).toString();
+ entrySet = tm.headMap(startKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.descendingIterator();
+ assertTrue(iterator.hasNext());
+ assertEquals(2, ((Entry) iterator.next()).getValue());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_pollFirst_startExcluded_endExcluded() {
+ Set entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ for (int value = 101; value < 109; value++) {
+ Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst();
+ assertEquals(value, entry.getValue());
+ }
+ assertTrue(ascendingSubMapEntrySet.isEmpty());
+ // should return null if the set is empty.
+ assertNull(ascendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_pollFirst_startExcluded_endIncluded() {
+ Set entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ for (int value = 101; value < 110; value++) {
+ Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst();
+ assertEquals(value, entry.getValue());
+ }
+ assertTrue(ascendingSubMapEntrySet.isEmpty());
+ // should return null if the set is empty.
+ assertNull(ascendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_pollFirst_startIncluded_endExcluded() {
+ Set entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ for (int value = 100; value < 109; value++) {
+ Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst();
+ assertEquals(value, entry.getValue());
+ }
+ assertTrue(ascendingSubMapEntrySet.isEmpty());
+ // should return null if the set is empty.
+ assertNull(ascendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_pollFirst_startIncluded_endIncluded() {
+ Set entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ for (int value = 100; value < 110; value++) {
+ Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst();
+ assertEquals(value, entry.getValue());
+ }
+ assertTrue(ascendingSubMapEntrySet.isEmpty());
+ // should return null if the set is empty.
+ assertNull(ascendingSubMapEntrySet.pollFirst());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_pollLast_startExcluded_endExcluded() {
+ Set entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ for (int value = 108; value > 100; value--) {
+ Entry entry = (Entry) ascendingSubMapEntrySet.pollLast();
+ assertEquals(value, entry.getValue());
+ }
+ assertTrue(ascendingSubMapEntrySet.isEmpty());
+ // should return null if the set is empty
+ assertNull(ascendingSubMapEntrySet.pollLast());
+ }
+
+ // NavigableMap ascendingSubMap = tm.headMap("2", true);
+ // Set entrySet = ascendingSubMap.entrySet();
+ // Object last;
+ // if (entrySet instanceof NavigableSet) {
+ // last = ((NavigableSet) entrySet).pollLast();
+ // assertEquals("2=2", last.toString());
+ // }
+ //
+ // ascendingSubMap = tm.tailMap("2", true);
+ // entrySet = ascendingSubMap.entrySet();
+ // if (entrySet instanceof NavigableSet) {
+ // last = ((NavigableSet) entrySet).pollLast();
+ // assertEquals("999=999", last.toString());
+ // }
+ }
+
+ public void test_AscendingSubMapEntrySet_pollLast_startExcluded_endIncluded() {
+ Set entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ for (int value = 109; value > 100; value--) {
+ Entry entry = (Entry) ascendingSubMapEntrySet.pollLast();
+ assertEquals(value, entry.getValue());
+ }
+ assertTrue(ascendingSubMapEntrySet.isEmpty());
+ // should return null if the set is empty
+ assertNull(ascendingSubMapEntrySet.pollLast());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_pollLast_startIncluded_endExcluded() {
+ Set entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ for (int value = 108; value > 99; value--) {
+ Entry entry = (Entry) ascendingSubMapEntrySet.pollLast();
+ assertEquals(value, entry.getValue());
+ }
+ assertTrue(ascendingSubMapEntrySet.isEmpty());
+ // should return null if the set is empty
+ assertNull(ascendingSubMapEntrySet.pollLast());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_pollLast_startIncluded_endIncluded() {
+ Set entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ for (int value = 109; value > 99; value--) {
+ Entry entry = (Entry) ascendingSubMapEntrySet.pollLast();
+ assertEquals(value, entry.getValue());
+ }
+ assertTrue(ascendingSubMapEntrySet.isEmpty());
+ // should return null if the set is empty
+ assertNull(ascendingSubMapEntrySet.pollLast());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_headSet() {
+ Set entrySet, headSet;
+ NavigableSet ascendingSubMapEntrySet;
+ Iterator iterator, headSetIterator;
+ Entry entry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ headSet = ascendingSubMapEntrySet.headSet(entry);
+ headSetIterator = headSet.iterator();
+ for (value = 101; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = ascendingSubMapEntrySet.headSet(entry, false);
+ headSetIterator = headSet.iterator();
+ for (value = 101; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = ascendingSubMapEntrySet.headSet(entry, true);
+ headSetIterator = headSet.iterator();
+ for (value = 101; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value - 1);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ headSet = ascendingSubMapEntrySet.headSet(entry);
+ headSetIterator = headSet.iterator();
+ for (value = 101; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = ascendingSubMapEntrySet.headSet(entry, false);
+ headSetIterator = headSet.iterator();
+ for (value = 101; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = ascendingSubMapEntrySet.headSet(entry, true);
+ headSetIterator = headSet.iterator();
+ for (value = 101; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value - 1);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ headSet = ascendingSubMapEntrySet.headSet(entry);
+ headSetIterator = headSet.iterator();
+ for (value = 100; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = ascendingSubMapEntrySet.headSet(entry, false);
+ headSetIterator = headSet.iterator();
+ for (value = 100; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = ascendingSubMapEntrySet.headSet(entry, true);
+ headSetIterator = headSet.iterator();
+ for (value = 100; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value - 1);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ headSet = ascendingSubMapEntrySet.headSet(entry);
+ headSetIterator = headSet.iterator();
+ for (value = 100; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = ascendingSubMapEntrySet.headSet(entry, false);
+ headSetIterator = headSet.iterator();
+ for (value = 100; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ headSet = ascendingSubMapEntrySet.headSet(entry, true);
+ headSetIterator = headSet.iterator();
+ for (value = 100; headSetIterator.hasNext(); value++) {
+ assertEquals(value, ((Entry) headSetIterator.next())
+ .getValue());
+ }
+ assertEquals(entry.getValue(), value - 1);
+ try {
+ headSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ // NavigableMap ascendingSubMap = tm.headMap("1", true);
+ // entrySet = ascendingSubMap.entrySet();
+ // if (entrySet instanceof SortedSet) {
+ // Iterator it = entrySet.iterator();
+ // it.next();
+ // Object end = it.next();// 1=1
+ // Set headSet = ((NavigableSet) entrySet).headSet(end);// inclusive
+ // // false
+ // assertEquals(1, headSet.size());
+ // }
+ }
+
+ public void test_AscendingSubMapEntrySet_tailSet() {
+ Set entrySet, tailSet;
+ NavigableSet ascendingSubMapEntrySet;
+ Iterator iterator, tailSetIterator;
+ Entry entry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = entrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ tailSet = ascendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue() + 1; tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(109, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = ascendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue() + 1; tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(109, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = ascendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(109, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = entrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ tailSet = ascendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue() + 1; tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(110, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = ascendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue() + 1; tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(110, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = ascendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(110, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = entrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ tailSet = ascendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue() + 1; tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(109, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = ascendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue() + 1; tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(109, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = ascendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(109, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = entrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ tailSet = ascendingSubMapEntrySet.tailSet(entry);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue() + 1; tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(110, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = ascendingSubMapEntrySet.tailSet(entry, false);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue() + 1; tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(110, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+
+ tailSet = ascendingSubMapEntrySet.tailSet(entry, true);
+ tailSetIterator = tailSet.iterator();
+ for (value = (Integer) entry.getValue(); tailSetIterator
+ .hasNext(); value++) {
+ assertEquals(value, ((Entry) tailSetIterator.next())
+ .getValue());
+ }
+ assertEquals(110, value);
+ try {
+ tailSetIterator.next();
+ fail("should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Expected
+ }
+ }
+ }
+
+ // NavigableMap ascendingSubMap = tm.headMap("1", true);
+ // Set entrySet = ascendingSubMap.entrySet();
+ // if (entrySet instanceof NavigableSet) {
+ // Iterator it = entrySet.iterator();
+ // Object start = it.next();// 0=0
+ // Set tailSet = ((NavigableSet) entrySet).tailSet(start);// default
+ // // inclusive
+ // // false
+ // assertEquals(1, tailSet.size());
+ // }
+ }
+
+ public void test_AscendingSubMapEntrySet_subSet() {
+ Set entrySet, subSet;
+ NavigableSet ascendingSubMapEntrySet;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ Iterator iteratorStart = ascendingSubMapEntrySet.iterator();
+ while (iteratorStart.hasNext()) {
+ Entry startEntry = (Entry) iteratorStart.next();
+ Iterator iteratorEnd = ascendingSubMapEntrySet.iterator();
+ while (iteratorEnd.hasNext()) {
+ Entry endEntry = (Entry) iteratorEnd.next();
+ int startIndex = (Integer) startEntry.getValue();
+ int endIndex = (Integer) endEntry.getValue();
+ if (startIndex > endIndex) {
+ try {
+ ascendingSubMapEntrySet
+ .subSet(startEntry, endEntry);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ ascendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ ascendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ ascendingSubMapEntrySet.subSet(startEntry, true,
+ endEntry, false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ ascendingSubMapEntrySet.subSet(startEntry, true,
+ endEntry, true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ } else {
+ subSet = ascendingSubMapEntrySet.subSet(startEntry,
+ endEntry);
+ Iterator subSetIterator = subSet.iterator();
+ for (int index = startIndex + 1; subSetIterator
+ .hasNext(); index++) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = ascendingSubMapEntrySet.subSet(startEntry,
+ false, endEntry, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex + 1; subSetIterator
+ .hasNext(); index++) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = ascendingSubMapEntrySet.subSet(startEntry,
+ false, endEntry, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex + 1; subSetIterator
+ .hasNext(); index++) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = ascendingSubMapEntrySet.subSet(startEntry,
+ true, endEntry, false);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index++) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+
+ subSet = ascendingSubMapEntrySet.subSet(startEntry,
+ true, endEntry, true);
+ subSetIterator = subSet.iterator();
+ for (int index = startIndex; subSetIterator.hasNext(); index++) {
+ assertEquals(index, ((Entry) subSetIterator.next())
+ .getValue());
+ }
+ }
+ }
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ Iterator iterator = entrySet.iterator();
+ Object startEntry = iterator.next();
+ iterator.next();
+ Object endEntry = iterator.next();
+ subSet = ascendingSubMapEntrySet.subSet(startEntry, endEntry);
+ assertEquals(1, subSet.size());
+
+ subSet = ascendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, false);
+ assertEquals(1, subSet.size());
+
+ subSet = ascendingSubMapEntrySet.subSet(startEntry, false,
+ endEntry, true);
+ assertEquals(2, subSet.size());
+
+ subSet = ascendingSubMapEntrySet.subSet(startEntry, true, endEntry,
+ false);
+ assertEquals(2, subSet.size());
+
+ subSet = ascendingSubMapEntrySet.subSet(startEntry, true, endEntry,
+ true);
+ assertEquals(3, subSet.size());
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_lower() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet;
+ Iterator iterator;
+ Entry entry, lowerEntry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value > 101) {
+ assertEquals(value - 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value > 101) {
+ assertEquals(value - 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value > 100) {
+ assertEquals(value - 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value > 100) {
+ assertEquals(value - 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = entrySet.iterator();
+ Entry expectedEntry = (Entry) iterator.next();
+ entry = (Entry) iterator.next();
+ assertEquals(expectedEntry, ascendingSubMapEntrySet.lower(entry));
+ }
+
+ // With Comparator
+
+ entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value > 101) {
+ assertEquals(value - 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value > 101) {
+ assertEquals(value - 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value > 100) {
+ assertEquals(value - 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+ value = (Integer) entry.getValue();
+ if (value > 100) {
+ assertEquals(value - 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_higher() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet;
+ Iterator iterator;
+ Entry entry, lowerEntry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value < 108) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value < 109) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value < 108) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value < 109) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ String endKey = new Integer(2).toString();
+ entrySet = tm.headMap(endKey, true).entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = entrySet.iterator();
+ entry = (Entry) iterator.next();
+ Entry expectedEntry = (Entry) iterator.next();
+ assertEquals(expectedEntry, ascendingSubMapEntrySet.higher(entry));
+ }
+
+ // With Comparator
+ entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value < 108) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value < 109) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value < 108) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+
+ entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+ value = (Integer) entry.getValue();
+ if (value < 109) {
+ assertEquals(value + 1, lowerEntry.getValue());
+ } else {
+ assertNull(lowerEntry);
+ }
+ }
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_ceiling() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet;
+ Iterator iterator;
+
+ Set entrySet_beyondBound;
+ Iterator iterator_beyondBound;
+ Entry beyondBoundEntry;
+
+ Entry entry, lowerEntry;
+ int value = 0;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.ceiling(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+ value = (Integer) entry.getValue();
+ assertEquals(value, lowerEntry.getValue());
+ }
+ assertEquals(108, value);
+
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.ceiling(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+ value = (Integer) entry.getValue();
+ assertEquals(value, lowerEntry.getValue());
+ }
+ assertEquals(109, value);
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.ceiling(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+ value = (Integer) entry.getValue();
+ assertEquals(value, lowerEntry.getValue());
+ }
+ assertEquals(108, value);
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.ceiling(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+ value = (Integer) entry.getValue();
+ assertEquals(value, lowerEntry.getValue());
+ }
+ assertEquals(109, value);
+ }
+
+ // With Comparator
+ entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.ceiling(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+ value = (Integer) entry.getValue();
+ assertEquals(value, lowerEntry.getValue());
+ }
+ assertEquals(109, value);
+ }
+
+ entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.ceiling(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+ value = (Integer) entry.getValue();
+ assertEquals(value, lowerEntry.getValue());
+ }
+ assertEquals(108, value);
+ }
+
+ entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.ceiling(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+ value = (Integer) entry.getValue();
+ assertEquals(value, lowerEntry.getValue());
+ }
+ assertEquals(109, value);
+ }
+
+ entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.ceiling(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ while (iterator.hasNext()) {
+ entry = (Entry) iterator.next();
+ lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+ value = (Integer) entry.getValue();
+ assertEquals(value, lowerEntry.getValue());
+ }
+ assertEquals(108, value);
+ }
+ }
+
+ public void test_AscendingSubMapEntrySet_floor() {
+ Set entrySet;
+ NavigableSet ascendingSubMapEntrySet;
+ Iterator iterator;
+ Entry entry, floorEntry;
+ int value;
+
+ entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.floor(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ for (int i = 101; i < 109; i++) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+ assertEquals(entry.getValue(), floorEntry.getValue());
+ }
+ assertFalse(iterator.hasNext());
+ }
+
+ entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.floor(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ for (int i = 101; i < 110; i++) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+ assertEquals(entry.getValue(), floorEntry.getValue());
+ }
+ assertFalse(iterator.hasNext());
+ }
+
+ entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.floor(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ for (int i = 100; i < 109; i++) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+ assertEquals(entry.getValue(), floorEntry.getValue());
+ }
+ assertFalse(iterator.hasNext());
+ }
+
+ entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.floor(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ for (int i = 100; i < 110; i++) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+ assertEquals(entry.getValue(), floorEntry.getValue());
+ }
+ assertFalse(iterator.hasNext());
+ }
+
+ // With Comparator
+ entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.floor(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ for (int i = 101; i < 109; i++) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+ assertEquals(entry.getValue(), floorEntry.getValue());
+ }
+ assertFalse(iterator.hasNext());
+ }
+
+ entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.floor(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ for (int i = 101; i < 110; i++) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+ assertEquals(entry.getValue(), floorEntry.getValue());
+ }
+ assertFalse(iterator.hasNext());
+ }
+
+ entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.floor(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ for (int i = 100; i < 109; i++) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+ assertEquals(entry.getValue(), floorEntry.getValue());
+ }
+ assertFalse(iterator.hasNext());
+ }
+
+ entrySet = subMap_startIncluded_endIncluded.entrySet();
+ if (entrySet instanceof NavigableSet) {
+ ascendingSubMapEntrySet = (NavigableSet) entrySet;
+ try {
+ ascendingSubMapEntrySet.floor(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ iterator = ascendingSubMapEntrySet.iterator();
+ for (int i = 100; i < 110; i++) {
+ entry = (Entry) iterator.next();
+ floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+ assertEquals(entry.getValue(), floorEntry.getValue());
+ }
+ assertFalse(iterator.hasNext());
+ }
+ }
+
+ @Override
+ protected void setUp() {
+ tm = new TreeMap();
+ tm_comparator = new TreeMap(new MockComparator());
+ for (int i = 0; i < objArray.length; i++) {
+ Object x = objArray[i] = new Integer(i);
+ tm.put(x.toString(), x);
+ tm_comparator.put(x.toString(), x);
+ }
+
+ subMap_default = tm.subMap(objArray[100].toString(), objArray[109]
+ .toString());
+ subMap_startExcluded_endExcluded = tm.subMap(objArray[100].toString(),
+ false, objArray[109].toString(), false);
+ subMap_startExcluded_endIncluded = tm.subMap(objArray[100].toString(),
+ false, objArray[109].toString(), true);
+ subMap_startIncluded_endExcluded = tm.subMap(objArray[100].toString(),
+ true, objArray[109].toString(), false);
+ subMap_startIncluded_endIncluded = tm.subMap(objArray[100].toString(),
+ true, objArray[109].toString(), true);
+
+ subMap_default_beforeStart_100 = tm.subMap(objArray[0].toString(),
+ objArray[1].toString());
+
+ subMap_default_afterEnd_109 = tm.subMap(objArray[110].toString(),
+ objArray[119].toString());
+
+ assertTrue(subMap_startExcluded_endExcluded instanceof NavigableMap);
+ assertTrue(subMap_startExcluded_endIncluded instanceof NavigableMap);
+ assertTrue(subMap_startIncluded_endExcluded instanceof NavigableMap);
+ assertTrue(subMap_startIncluded_endIncluded instanceof NavigableMap);
+
+ navigableMap_startExcluded_endExcluded = (NavigableMap) subMap_startExcluded_endExcluded;
+ navigableMap_startExcluded_endIncluded = (NavigableMap) subMap_startExcluded_endIncluded;
+ navigableMap_startIncluded_endExcluded = (NavigableMap) subMap_startIncluded_endExcluded;
+ navigableMap_startIncluded_endIncluded = (NavigableMap) subMap_startIncluded_endIncluded;
+
+ subMap_default_comparator = tm_comparator.subMap(objArray[100]
+ .toString(), objArray[109].toString());
+ subMap_startExcluded_endExcluded_comparator = tm_comparator.subMap(
+ objArray[100].toString(), false, objArray[109].toString(),
+ false);
+
+ subMap_startExcluded_endIncluded_comparator = tm_comparator
+ .subMap(objArray[100].toString(), false, objArray[109]
+ .toString(), true);
+ subMap_startIncluded_endExcluded_comparator = tm_comparator
+ .subMap(objArray[100].toString(), true, objArray[109]
+ .toString(), false);
+ subMap_startIncluded_endIncluded_comparator = tm_comparator.subMap(
+ objArray[100].toString(), true, objArray[109].toString(), true);
+ }
+
+ @Override
+ protected void tearDown() {
+ tm = null;
+ tm_comparator = null;
+
+ subMap_default = null;
+ subMap_startExcluded_endExcluded = null;
+ subMap_startExcluded_endIncluded = null;
+ subMap_startIncluded_endExcluded = null;
+ subMap_startIncluded_endIncluded = null;
+
+ subMap_default_beforeStart_100 = null;
+ subMap_default_afterEnd_109 = null;
+
+ subMap_default_comparator = null;
+ subMap_startExcluded_endExcluded_comparator = null;
+ subMap_startExcluded_endIncluded_comparator = null;
+ subMap_startIncluded_endExcluded_comparator = null;
+ subMap_startIncluded_endIncluded_comparator = null;
+ }
+
+ public void test_lower_null() throws Exception {
+ NavigableMap map = tm.subMap(objArray[100].toString(), true,
+ objArray[100].toString(), false);
+ assertNull(map.ceilingKey(objArray[100].toString()));
+ assertNull(map.floorKey(objArray[100].toString()));
+ assertNull(map.lowerKey(objArray[100].toString()));
+ assertNull(map.higherKey(objArray[100].toString()));
+ assertNull(map.ceilingKey(objArray[111].toString()));
+ assertNull(map.floorKey(objArray[111].toString()));
+ assertNull(map.lowerKey(objArray[111].toString()));
+ assertNull(map.higherKey(objArray[111].toString()));
+ assertNull(map.ceilingKey(objArray[1].toString()));
+ assertNull(map.floorKey(objArray[1].toString()));
+ assertNull(map.lowerKey(objArray[1].toString()));
+ assertNull(map.higherKey(objArray[1].toString()));
+ map = map.descendingMap();
+ assertNull(map.ceilingKey(objArray[100].toString()));
+ assertNull(map.floorKey(objArray[100].toString()));
+ assertNull(map.lowerKey(objArray[100].toString()));
+ assertNull(map.higherKey(objArray[100].toString()));
+ assertNull(map.ceilingKey(objArray[111].toString()));
+ assertNull(map.floorKey(objArray[111].toString()));
+ assertNull(map.lowerKey(objArray[111].toString()));
+ assertNull(map.higherKey(objArray[111].toString()));
+ assertNull(map.ceilingKey(objArray[1].toString()));
+ assertNull(map.floorKey(objArray[1].toString()));
+ assertNull(map.lowerKey(objArray[1].toString()));
+ assertNull(map.higherKey(objArray[1].toString()));
+ }
+
+ public void test_lower_tail() throws Exception {
+ NavigableMap map = tm.subMap(objArray[102].toString(), true,
+ objArray[103].toString(), false);
+ assertTrue(map.containsKey(objArray[102].toString()));
+ assertFalse(map.containsKey(objArray[101].toString()));
+ assertFalse(map.containsKey(objArray[103].toString()));
+ assertFalse(map.containsKey(objArray[104].toString()));
+ map = map.descendingMap();
+ assertTrue(map.containsKey(objArray[102].toString()));
+ assertFalse(map.containsKey(objArray[101].toString()));
+ assertFalse(map.containsKey(objArray[103].toString()));
+ assertFalse(map.containsKey(objArray[104].toString()));
+ map = tm.subMap(objArray[102].toString(), true, objArray[102]
+ .toString(), false);
+ assertFalse(map.containsKey(objArray[102].toString()));
+ assertFalse(map.containsKey(objArray[101].toString()));
+ assertFalse(map.containsKey(objArray[103].toString()));
+ assertFalse(map.containsKey(objArray[104].toString()));
+ map = map.descendingMap();
+ assertFalse(map.containsKey(objArray[102].toString()));
+ assertFalse(map.containsKey(objArray[101].toString()));
+ assertFalse(map.containsKey(objArray[103].toString()));
+ assertFalse(map.containsKey(objArray[104].toString()));
+ }
+
+ public void test_contains_null() throws Exception {
+ NavigableMap map = tm.subMap(objArray[100].toString(), true,
+ objArray[100].toString(), false);
+ assertFalse(map.containsKey(objArray[100].toString()));
+ assertFalse(map.containsKey(objArray[10].toString()));
+ assertFalse(map.containsKey(objArray[101].toString()));
+ assertFalse(map.containsKey(objArray[102].toString()));
+ assertFalse(map.containsKey(objArray[1].toString()));
+ map = map.descendingMap();
+ assertFalse(map.containsKey(objArray[100].toString()));
+ assertFalse(map.containsKey(objArray[10].toString()));
+ assertFalse(map.containsKey(objArray[101].toString()));
+ assertFalse(map.containsKey(objArray[102].toString()));
+ assertFalse(map.containsKey(objArray[1].toString()));
+ }
+
+ public void test_contains() throws Exception {
+ NavigableMap map = tm.subMap(objArray[102].toString(), true,
+ objArray[103].toString(), false);
+ assertFalse(map.containsKey(objArray[100].toString()));
+ assertFalse(map.containsKey(objArray[104].toString()));
+ assertFalse(map.containsKey(objArray[101].toString()));
+ assertTrue(map.containsKey(objArray[102].toString()));
+ map = map.descendingMap();
+ assertFalse(map.containsKey(objArray[100].toString()));
+ assertFalse(map.containsKey(objArray[104].toString()));
+ assertFalse(map.containsKey(objArray[101].toString()));
+ assertTrue(map.containsKey(objArray[102].toString()));
+ }
+
+ public void test_size() throws Exception {
+ NavigableMap map = tm.subMap(objArray[102].toString(), true,
+ objArray[103].toString(), false);
+ assertEquals(0, map.headMap(objArray[102].toString(), false).size());
+ assertEquals(1, map.headMap(objArray[102].toString(), true).size());
+ try {
+ assertEquals(1, map.headMap(objArray[103].toString(), true).size());
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ }
+ assertEquals(1, map.headMap(objArray[103].toString(), false).size());
+ assertEquals(1, map.tailMap(objArray[102].toString(), true).size());
+ assertEquals(0, map.tailMap(objArray[102].toString(), false).size());
+ assertTrue(map.headMap(objArray[103].toString(), false).containsKey(
+ objArray[102].toString()));
+ try {
+ assertTrue(map.headMap(objArray[103].toString(), true).containsKey(
+ objArray[102].toString()));
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ }
+ assertFalse(map.headMap(objArray[102].toString(), false).containsKey(
+ objArray[102].toString()));
+ assertTrue(map.headMap(objArray[102].toString(), true).containsKey(
+ objArray[102].toString()));
+ assertTrue(map.tailMap(objArray[102].toString(), true).containsKey(
+ objArray[102].toString()));
+ assertFalse(map.tailMap(objArray[102].toString(), true).containsKey(
+ objArray[103].toString()));
+ try {
+ assertEquals(0, map.tailMap(objArray[101].toString()).size());
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ }
+ map = map.descendingMap();
+ try {
+ map = map.subMap(objArray[103].toString(), true, objArray[102]
+ .toString(), true);
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ }
+ map = map.subMap(objArray[102].toString(), true, objArray[102]
+ .toString(), true);
+ assertEquals(1, map.headMap(objArray[102].toString(), true).size());
+ assertEquals(0, map.headMap(objArray[102].toString(), false).size());
+ try {
+ assertEquals(0, map.headMap(objArray[103].toString(), true).size());
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ }
+
+ assertEquals(1, map.tailMap(objArray[102].toString(), true).size());
+ try {
+ assertFalse(map.headMap(objArray[103].toString(), true)
+ .containsKey(objArray[102].toString()));
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ }
+ assertTrue(map.headMap(objArray[102].toString(), true).containsKey(
+ objArray[102].toString()));
+ assertFalse(map.headMap(objArray[102].toString(), false).containsKey(
+ objArray[102].toString()));
+ assertTrue(map.tailMap(objArray[102].toString(), true).containsKey(
+ objArray[102].toString()));
+ assertFalse(map.tailMap(objArray[102].toString(), true).containsKey(
+ objArray[103].toString()));
+ try {
+ assertEquals(0, map.tailMap(objArray[101].toString()).size());
+ fail("should throw IAE");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void test_lower() throws Exception {
+ NavigableMap map = tm.subMap(objArray[102].toString(), true,
+ objArray[103].toString(), false);
+ assertEquals(objArray[102].toString(), map.higherKey(objArray[101]
+ .toString()));
+ assertEquals(null, map.higherKey(objArray[102].toString()));
+ assertEquals(null, map.higherKey(objArray[103].toString()));
+ assertEquals(null, map.higherKey(objArray[104].toString()));
+ assertEquals(objArray[102].toString(), map.ceilingKey(objArray[101]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.ceilingKey(objArray[102]
+ .toString()));
+ assertEquals(null, map.ceilingKey(objArray[103].toString()));
+ assertEquals(null, map.ceilingKey(objArray[104].toString()));
+ assertEquals(null, map.lowerKey(objArray[101].toString()));
+ assertEquals(null, map.lowerKey(objArray[102].toString()));
+ assertEquals(objArray[102].toString(), map.lowerKey(objArray[103]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.lowerKey(objArray[104]
+ .toString()));
+ assertEquals(null, map.floorKey(objArray[101].toString()));
+ assertEquals(objArray[102].toString(), map.floorKey(objArray[102]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.floorKey(objArray[103]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.floorKey(objArray[104]
+ .toString()));
+ map = map.descendingMap();
+ assertEquals(null, map.higherKey(objArray[101].toString()));
+ assertEquals(null, map.higherKey(objArray[102].toString()));
+ assertEquals(objArray[102].toString(), map.higherKey(objArray[103]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.higherKey(objArray[104]
+ .toString()));
+ assertEquals(null, map.ceilingKey(objArray[101].toString()));
+ assertEquals(objArray[102].toString(), map.ceilingKey(objArray[102]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.ceilingKey(objArray[103]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.ceilingKey(objArray[104]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.lowerKey(objArray[101]
+ .toString()));
+ assertEquals(null, map.lowerKey(objArray[102].toString()));
+ assertEquals(null, map.lowerKey(objArray[103].toString()));
+ assertEquals(null, map.lowerKey(objArray[104].toString()));
+ assertEquals(objArray[102].toString(), map.floorKey(objArray[101]
+ .toString()));
+ assertEquals(objArray[102].toString(), map.floorKey(objArray[102]
+ .toString()));
+ assertEquals(null, map.floorKey(objArray[103].toString()));
+ assertEquals(null, map.floorKey(objArray[104].toString()));
+ }
+
+ public void test_lowerkey() throws Exception {
+ try {
+ tm.subMap(objArray[100].toString(), true, objArray[100].toString(),
+ false).descendingMap().firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (Exception e) {
+ // expected
+ }
+ try {
+ tm.subMap(objArray[100].toString(), true, objArray[100].toString(),
+ false).descendingMap().lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (Exception e) {
+ // expected
+ }
+ try {
+ tm.subMap(objArray[100].toString(), true, objArray[100].toString(),
+ false).firstKey();
+ fail("should throw NoSuchElementException");
+ } catch (Exception e) {
+ // expected
+ }
+ try {
+ tm.subMap(objArray[100].toString(), true, objArray[100].toString(),
+ false).lastKey();
+ fail("should throw NoSuchElementException");
+ } catch (Exception e) {
+ // expected
+ }
+
+ }
+
+ public void test_headMap() throws Exception {
+ TreeMap tree = new TreeMap();
+ tree.put(new Integer(0), null);
+ tree.put(new Integer(1), null);
+ Map submap = tree.subMap(tree.firstKey(), tree.lastKey());
+ tree.remove(tree.lastKey());
+ assertEquals(submap, tree);
+ }
+
+ public void testname() throws Exception {
+ TreeMap nullTree = new TreeMap(new Comparator() {
+ public int compare(Object o1, Object o2) {
+ if (o1 == null) {
+ return o2 == null ? 0 : -1;
+ }
+ return ((String) o1).compareTo((String) o2);
+ }
+ });
+ nullTree.put(new String("One"), 1);
+ nullTree.put(new String("Two"), 2);
+ nullTree.put(new String("Three"), 3);
+ nullTree.put(new String("Four"), 4);
+ nullTree.put(null, 0);
+ nullTree.subMap(null, "two").size();
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapRndTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapRndTest.java
new file mode 100644
index 0000000..bec75a4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapRndTest.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.TreeMap;
+
+public class TreeMapRndTest extends SortedMapTestBase {
+ protected void setUp() throws Exception {
+ ref = new RefSortedMap<Integer, Integer>();
+ super.setUp();
+ map = new TreeMap<Integer, Integer>(ref);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapTest.java
new file mode 100644
index 0000000..58ffaf6
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapTest.java
@@ -0,0 +1,1968 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.support.Support_MapTest2;
+import tests.support.Support_UnmodifiableCollectionTest;
+import java.io.Serializable;
+import java.text.CollationKey;
+import java.text.Collator;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+public class TreeMapTest extends junit.framework.TestCase {
+
+ public static class ReversedComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ return -(((Comparable) o1).compareTo(o2));
+ }
+
+ public boolean equals(Object o1, Object o2) {
+ return (((Comparable) o1).compareTo(o2)) == 0;
+ }
+ }
+
+ // Regression for Harmony-1026
+ public static class MockComparator<T extends Comparable<T>> implements
+ Comparator<T>, Serializable {
+
+ public int compare(T o1, T o2) {
+ if (o1 == o2) {
+ return 0;
+ }
+ if (null == o1 || null == o2) {
+ return -1;
+ }
+ T c1 = o1;
+ T c2 = o2;
+ return c1.compareTo(c2);
+ }
+ }
+
+ // Regression for Harmony-1161
+ class MockComparatorNullTolerable implements Comparator<String> {
+
+ public int compare(String o1, String o2) {
+ if (o1 == o2) {
+ return 0;
+ }
+ if (null == o1) {
+ return -1;
+ }
+ if (null == o2) { // comparator should be symmetric
+ return 1;
+ }
+ return o1.compareTo(o2);
+ }
+ }
+
+ TreeMap tm;
+
+ Object objArray[] = new Object[1000];
+
+ /**
+ * java.util.TreeMap#TreeMap()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.TreeMap()
+ new Support_MapTest2(new TreeMap()).runTest();
+
+ assertTrue("New treeMap non-empty", new TreeMap().isEmpty());
+ }
+
+ /**
+ * java.util.TreeMap#TreeMap(java.util.Comparator)
+ */
+ public void test_ConstructorLjava_util_Comparator() {
+ // Test for method java.util.TreeMap(java.util.Comparator)
+ Comparator comp = new ReversedComparator();
+ TreeMap reversedTreeMap = new TreeMap(comp);
+ assertTrue("TreeMap answered incorrect comparator", reversedTreeMap
+ .comparator() == comp);
+ reversedTreeMap.put(new Integer(1).toString(), new Integer(1));
+ reversedTreeMap.put(new Integer(2).toString(), new Integer(2));
+ assertTrue("TreeMap does not use comparator (firstKey was incorrect)",
+ reversedTreeMap.firstKey().equals(new Integer(2).toString()));
+ assertTrue("TreeMap does not use comparator (lastKey was incorrect)",
+ reversedTreeMap.lastKey().equals(new Integer(1).toString()));
+
+ }
+
+ /**
+ * java.util.TreeMap#TreeMap(java.util.Map)
+ */
+ public void test_ConstructorLjava_util_Map() {
+ // Test for method java.util.TreeMap(java.util.Map)
+ TreeMap myTreeMap = new TreeMap(new HashMap(tm));
+ assertTrue("Map is incorrect size", myTreeMap.size() == objArray.length);
+ for (Object element : objArray) {
+ assertTrue("Map has incorrect mappings", myTreeMap.get(
+ element.toString()).equals(element));
+ }
+ }
+
+ /**
+ * java.util.TreeMap#TreeMap(java.util.SortedMap)
+ */
+ public void test_ConstructorLjava_util_SortedMap() {
+ // Test for method java.util.TreeMap(java.util.SortedMap)
+ Comparator comp = new ReversedComparator();
+ TreeMap reversedTreeMap = new TreeMap(comp);
+ reversedTreeMap.put(new Integer(1).toString(), new Integer(1));
+ reversedTreeMap.put(new Integer(2).toString(), new Integer(2));
+ TreeMap anotherTreeMap = new TreeMap(reversedTreeMap);
+ assertTrue("New tree map does not answer correct comparator",
+ anotherTreeMap.comparator() == comp);
+ assertTrue("TreeMap does not use comparator (firstKey was incorrect)",
+ anotherTreeMap.firstKey().equals(new Integer(2).toString()));
+ assertTrue("TreeMap does not use comparator (lastKey was incorrect)",
+ anotherTreeMap.lastKey().equals(new Integer(1).toString()));
+
+ }
+
+ /**
+ * java.util.TreeMap#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.TreeMap.clear()
+ tm.clear();
+ assertEquals("Cleared map returned non-zero size", 0, tm.size());
+ }
+
+ /**
+ * java.util.TreeMap#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.TreeMap.clone()
+ TreeMap clonedMap = (TreeMap) tm.clone();
+ assertTrue("Cloned map does not equal the original map", clonedMap
+ .equals(tm));
+ assertTrue("Cloned map is the same reference as the original map",
+ clonedMap != tm);
+ for (Object element : objArray) {
+ assertTrue("Cloned map contains incorrect elements", clonedMap
+ .get(element.toString()) == tm.get(element.toString()));
+ }
+
+ TreeMap map = new TreeMap();
+ map.put("key", "value");
+ // get the keySet() and values() on the original Map
+ Set keys = map.keySet();
+ Collection values = map.values();
+ assertEquals("values() does not work", "value", values.iterator()
+ .next());
+ assertEquals("keySet() does not work", "key", keys.iterator().next());
+ AbstractMap map2 = (AbstractMap) map.clone();
+ map2.put("key", "value2");
+ Collection values2 = map2.values();
+ assertTrue("values() is identical", values2 != values);
+ // values() and keySet() on the cloned() map should be different
+ assertEquals("values() was not cloned", "value2", values2.iterator()
+ .next());
+ map2.clear();
+ map2.put("key2", "value3");
+ Set key2 = map2.keySet();
+ assertTrue("keySet() is identical", key2 != keys);
+ assertEquals("keySet() was not cloned", "key2", key2.iterator().next());
+ }
+
+ /**
+ * java.util.TreeMap#comparator()
+ */
+ public void test_comparator() {
+ // Test for method java.util.Comparator java.util.TreeMap.comparator()\
+ Comparator comp = new ReversedComparator();
+ TreeMap reversedTreeMap = new TreeMap(comp);
+ assertTrue("TreeMap answered incorrect comparator", reversedTreeMap
+ .comparator() == comp);
+ reversedTreeMap.put(new Integer(1).toString(), new Integer(1));
+ reversedTreeMap.put(new Integer(2).toString(), new Integer(2));
+ assertTrue("TreeMap does not use comparator (firstKey was incorrect)",
+ reversedTreeMap.firstKey().equals(new Integer(2).toString()));
+ assertTrue("TreeMap does not use comparator (lastKey was incorrect)",
+ reversedTreeMap.lastKey().equals(new Integer(1).toString()));
+ }
+
+ /**
+ * java.util.TreeMap#containsKey(java.lang.Object)
+ */
+ public void test_containsKeyLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.TreeMap.containsKey(java.lang.Object)
+ assertTrue("Returned false for valid key", tm.containsKey("95"));
+ assertTrue("Returned true for invalid key", !tm.containsKey("XXXXX"));
+ }
+
+ /**
+ * java.util.TreeMap#containsValue(java.lang.Object)
+ */
+ public void test_containsValueLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.TreeMap.containsValue(java.lang.Object)
+ assertTrue("Returned false for valid value", tm
+ .containsValue(objArray[986]));
+ assertTrue("Returned true for invalid value", !tm
+ .containsValue(new Object()));
+ }
+
+ /**
+ * java.util.TreeMap#entrySet()
+ */
+ public void test_entrySet() {
+ // Test for method java.util.Set java.util.TreeMap.entrySet()
+ Set anEntrySet = tm.entrySet();
+ Iterator entrySetIterator = anEntrySet.iterator();
+ assertTrue("EntrySet is incorrect size",
+ anEntrySet.size() == objArray.length);
+ Map.Entry entry;
+ while (entrySetIterator.hasNext()) {
+ entry = (Map.Entry) entrySetIterator.next();
+ assertTrue("EntrySet does not contain correct mappings", tm
+ .get(entry.getKey()) == entry.getValue());
+ }
+ }
+
+ /**
+ * java.util.TreeMap#firstKey()
+ */
+ public void test_firstKey() {
+ // Test for method java.lang.Object java.util.TreeMap.firstKey()
+ assertEquals("Returned incorrect first key", "0", tm.firstKey());
+ }
+
+ /**
+ * java.util.TreeMap#get(java.lang.Object)
+ */
+ public void test_getLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.TreeMap.get(java.lang.Object)
+ Object o = new Object();
+ tm.put("Hello", o);
+ assertTrue("Failed to get mapping", tm.get("Hello") == o);
+
+ // Test for the same key & same value
+ tm = new TreeMap();
+ Object o2 = new Object();
+ Integer key1 = 1;
+ Integer key2 = 2;
+ assertNull(tm.put(key1, o));
+ assertNull(tm.put(key2, o));
+ assertEquals(2, tm.values().size());
+ assertEquals(2, tm.keySet().size());
+ assertSame(tm.get(key1), tm.get(key2));
+ assertSame(o, tm.put(key1, o2));
+ assertSame(o2, tm.get(key1));
+ }
+
+ /**
+ * java.util.TreeMap#headMap(java.lang.Object)
+ */
+ public void test_headMapLjava_lang_Object() {
+ // Test for method java.util.SortedMap
+ // java.util.TreeMap.headMap(java.lang.Object)
+ Map head = tm.headMap("100");
+ assertEquals("Returned map of incorrect size", 3, head.size());
+ assertTrue("Returned incorrect elements", head.containsKey("0")
+ && head.containsValue(new Integer("1"))
+ && head.containsKey("10"));
+
+ // Regression for Harmony-1026
+ TreeMap<Integer, Double> map = new TreeMap<Integer, Double>(
+ new MockComparator());
+ map.put(1, 2.1);
+ map.put(2, 3.1);
+ map.put(3, 4.5);
+ map.put(7, 21.3);
+ map.put(null, null);
+
+ SortedMap<Integer, Double> smap = map.headMap(null);
+ assertEquals(0, smap.size());
+
+ Set<Integer> keySet = smap.keySet();
+ assertEquals(0, keySet.size());
+
+ Set<Map.Entry<Integer, Double>> entrySet = smap.entrySet();
+ assertEquals(0, entrySet.size());
+
+ Collection<Double> valueCollection = smap.values();
+ assertEquals(0, valueCollection.size());
+
+ // Regression for Harmony-1066
+ assertTrue(head instanceof Serializable);
+
+ // Regression for ill-behaved collator
+ Collator c = new Collator() {
+ @Override
+ public int compare(String o1, String o2) {
+ if (o1 == null) {
+ return 0;
+ }
+ return o1.compareTo(o2);
+ }
+
+ @Override
+ public CollationKey getCollationKey(String string) {
+ return null;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+ };
+
+ TreeMap<String, String> treemap = new TreeMap<String, String>(c);
+ assertEquals(0, treemap.headMap(null).size());
+
+ treemap = new TreeMap();
+ SortedMap<String, String> headMap = treemap.headMap("100");
+ headMap.headMap("100");
+
+ SortedMap<Integer, Integer> intMap, sub;
+ int size = 16;
+ intMap = new TreeMap<Integer, Integer>();
+ for (int i = 0; i < size; i++) {
+ intMap.put(i, i);
+ }
+ sub = intMap.headMap(-1);
+ assertEquals("size should be zero", sub.size(), 0);
+ assertTrue("submap should be empty", sub.isEmpty());
+ try {
+ sub.firstKey();
+ fail("java.util.NoSuchElementException should be thrown");
+ } catch (java.util.NoSuchElementException e) {
+ }
+
+ TreeMap t = new TreeMap();
+ try {
+ SortedMap th = t.headMap(null);
+ fail("Should throw a NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ try {
+ sub.lastKey();
+ fail("java.util.NoSuchElementException should be thrown");
+ } catch (java.util.NoSuchElementException e) {
+ }
+
+ size = 256;
+ intMap = new TreeMap<Integer, Integer>();
+ for (int i = 0; i < size; i++) {
+ intMap.put(i, i);
+ }
+ sub = intMap.headMap(-1);
+ assertEquals("size should be zero", sub.size(), 0);
+ assertTrue("submap should be empty", sub.isEmpty());
+ try {
+ sub.firstKey();
+ fail("java.util.NoSuchElementException should be thrown");
+ } catch (java.util.NoSuchElementException e) {
+ }
+
+ try {
+ sub.lastKey();
+ fail("java.util.NoSuchElementException should be thrown");
+ } catch (java.util.NoSuchElementException e) {
+ }
+
+ }
+
+ /**
+ * java.util.TreeMap#keySet()
+ */
+ public void test_keySet() {
+ // Test for method java.util.Set java.util.TreeMap.keySet()
+ Set ks = tm.keySet();
+ assertTrue("Returned set of incorrect size",
+ ks.size() == objArray.length);
+ for (int i = 0; i < tm.size(); i++) {
+ assertTrue("Returned set is missing keys", ks.contains(new Integer(
+ i).toString()));
+ }
+ }
+
+ /**
+ * java.util.TreeMap#lastKey()
+ */
+ public void test_lastKey() {
+ // Test for method java.lang.Object java.util.TreeMap.lastKey()
+ assertTrue("Returned incorrect last key", tm.lastKey().equals(
+ objArray[objArray.length - 1].toString()));
+ assertNotSame(objArray[objArray.length - 1].toString(), tm.lastKey());
+ assertEquals(objArray[objArray.length - 2].toString(), tm
+ .headMap("999").lastKey());
+ assertEquals(objArray[objArray.length - 1].toString(), tm
+ .tailMap("123").lastKey());
+ assertEquals(objArray[objArray.length - 2].toString(), tm.subMap("99",
+ "999").lastKey());
+ }
+
+ public void test_lastKey_after_subMap() {
+ TreeMap<String, String> tm = new TreeMap<String, String>();
+ tm.put("001", "VAL001");
+ tm.put("003", "VAL003");
+ tm.put("002", "VAL002");
+ SortedMap<String, String> sm = tm;
+ String firstKey = (String) sm.firstKey();
+ String lastKey = "";
+ for (int i = 1; i <= tm.size(); i++) {
+ try {
+ lastKey = (String) sm.lastKey();
+ } catch (NoSuchElementException excep) {
+ fail("NoSuchElementException thrown when there are elements in the map");
+ }
+ sm = sm.subMap(firstKey, lastKey);
+ }
+ }
+
+ /**
+ * java.util.TreeMap#put(java.lang.Object, java.lang.Object)
+ */
+ public void test_remove_throwsWhenNotComparable() {
+ // Test for method java.lang.Object
+ // java.util.TreeMap.put(java.lang.Object, java.lang.Object)
+ Object o = new Object();
+ tm = new TreeMap();
+ try {
+ tm.remove(o);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.TreeMap#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map() {
+ // Test for method void java.util.TreeMap.putAll(java.util.Map)
+ TreeMap x = new TreeMap();
+ x.putAll(tm);
+ assertTrue("Map incorrect size after put", x.size() == tm.size());
+ for (Object element : objArray) {
+ assertTrue("Failed to put all elements", x.get(element.toString())
+ .equals(element));
+ }
+ }
+
+ /**
+ * java.util.TreeMap#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.TreeMap.remove(java.lang.Object)
+ tm.remove("990");
+ assertTrue("Failed to remove mapping", !tm.containsKey("990"));
+
+ }
+
+ /**
+ * java.util.TreeMap#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.TreeMap.size()
+ assertEquals("Returned incorrect size", 1000, tm.size());
+ assertEquals("Returned incorrect size", 447, tm.headMap("500").size());
+ assertEquals("Returned incorrect size", 1000, tm.headMap("null").size());
+ assertEquals("Returned incorrect size", 0, tm.headMap("").size());
+ assertEquals("Returned incorrect size", 448, tm.headMap("500a").size());
+ assertEquals("Returned incorrect size", 553, tm.tailMap("500").size());
+ assertEquals("Returned incorrect size", 0, tm.tailMap("null").size());
+ assertEquals("Returned incorrect size", 1000, tm.tailMap("").size());
+ assertEquals("Returned incorrect size", 552, tm.tailMap("500a").size());
+ assertEquals("Returned incorrect size", 111, tm.subMap("500", "600")
+ .size());
+ try {
+ tm.subMap("null", "600");
+ fail("Should throw an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals("Returned incorrect size", 1000, tm.subMap("", "null")
+ .size());
+ }
+
+ /**
+ * java.util.TreeMap#subMap(java.lang.Object, java.lang.Object)
+ */
+ public void test_subMapLjava_lang_ObjectLjava_lang_Object() {
+ // Test for method java.util.SortedMap
+ // java.util.TreeMap.subMap(java.lang.Object, java.lang.Object)
+ SortedMap subMap = tm.subMap(objArray[100].toString(), objArray[109]
+ .toString());
+ assertEquals("subMap is of incorrect size", 9, subMap.size());
+ for (int counter = 100; counter < 109; counter++) {
+ assertTrue("SubMap contains incorrect elements", subMap.get(
+ objArray[counter].toString()).equals(objArray[counter]));
+ }
+
+ try {
+ tm.subMap(objArray[9].toString(), objArray[1].toString());
+ fail("end key less than start key should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // Regression for Harmony-1161
+ TreeMap<String, String> treeMapWithNull = new TreeMap<String, String>(
+ new MockComparatorNullTolerable());
+ treeMapWithNull.put("key1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+ treeMapWithNull.put(null, "value2"); //$NON-NLS-1$
+ SortedMap<String, String> subMapWithNull = treeMapWithNull.subMap(null,
+ "key1"); //$NON-NLS-1$
+ assertEquals("Size of subMap should be 1:", 1, subMapWithNull.size()); //$NON-NLS-1$
+
+ // Regression test for typo in lastKey method
+ SortedMap<String, String> map = new TreeMap<String, String>();
+ map.put("1", "one"); //$NON-NLS-1$ //$NON-NLS-2$
+ map.put("2", "two"); //$NON-NLS-1$ //$NON-NLS-2$
+ map.put("3", "three"); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals("3", map.lastKey());
+ SortedMap<String, String> sub = map.subMap("1", "3"); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals("2", sub.lastKey()); //$NON-NLS-1$
+
+ // NOTE: The contract of this method allows us to throw either
+ // an NPE or a class cast exception.
+ TreeMap t = new TreeMap();
+ try {
+ t.subMap(null, new Object());
+ fail("Should throw a ClassCastException");
+ } catch (ClassCastException npe) {
+ // expected
+ }
+ }
+
+
+ /**
+ * java.util.TreeMap#subMap(java.lang.Object, java.lang.Object)
+ */
+ public void test_subMap_Iterator() {
+ TreeMap<String, String> map = new TreeMap<String, String>();
+
+ String[] keys = { "1", "2", "3" };
+ String[] values = { "one", "two", "three" };
+ for (int i = 0; i < keys.length; i++) {
+ map.put(keys[i], values[i]);
+ }
+
+ assertEquals(3, map.size());
+
+ Map subMap = map.subMap("", "test");
+ assertEquals(3, subMap.size());
+
+ Set entrySet = subMap.entrySet();
+ Iterator iter = entrySet.iterator();
+ int size = 0;
+ while (iter.hasNext()) {
+ Map.Entry<String, String> entry = (Map.Entry<String, String>) iter
+ .next();
+ assertTrue(map.containsKey(entry.getKey()));
+ assertTrue(map.containsValue(entry.getValue()));
+ size++;
+ }
+ assertEquals(map.size(), size);
+
+ Set<String> keySet = subMap.keySet();
+ iter = keySet.iterator();
+ size = 0;
+ while (iter.hasNext()) {
+ String key = (String) iter.next();
+ assertTrue(map.containsKey(key));
+ size++;
+ }
+ assertEquals(map.size(), size);
+ }
+
+
+ /**
+ * java.util.TreeMap#tailMap(java.lang.Object)
+ */
+ public void test_tailMapLjava_lang_Object() {
+ // Test for method java.util.SortedMap
+ // java.util.TreeMap.tailMap(java.lang.Object)
+ Map tail = tm.tailMap(objArray[900].toString());
+ assertTrue("Returned map of incorrect size : " + tail.size(), tail
+ .size() == (objArray.length - 900) + 9);
+ for (int i = 900; i < objArray.length; i++) {
+ assertTrue("Map contains incorrect entries", tail
+ .containsValue(objArray[i]));
+ }
+
+ // Regression for Harmony-1066
+ assertTrue(tail instanceof Serializable);
+
+ SortedMap<Integer, Integer> intMap, sub;
+ int size = 16;
+ intMap = new TreeMap<Integer, Integer>();
+ for (int i = 0; i < size; i++) {
+ intMap.put(i, i);
+ }
+ sub = intMap.tailMap(size);
+ assertEquals("size should be zero", sub.size(), 0);
+ assertTrue("submap should be empty", sub.isEmpty());
+ try {
+ sub.firstKey();
+ fail("java.util.NoSuchElementException should be thrown");
+ } catch (java.util.NoSuchElementException e) {
+ }
+
+ TreeMap t = new TreeMap();
+ try {
+ SortedMap th = t.tailMap(null);
+ fail("Should throw a NullPointerException");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+
+ try {
+ sub.lastKey();
+ fail("java.util.NoSuchElementException should be thrown");
+ } catch (java.util.NoSuchElementException e) {
+ }
+
+ size = 256;
+ intMap = new TreeMap<Integer, Integer>();
+ for (int i = 0; i < size; i++) {
+ intMap.put(i, i);
+ }
+ sub = intMap.tailMap(size);
+ assertEquals("size should be zero", sub.size(), 0);
+ assertTrue("submap should be empty", sub.isEmpty());
+ try {
+ sub.firstKey();
+ fail("java.util.NoSuchElementException should be thrown");
+ } catch (java.util.NoSuchElementException e) {
+ }
+
+ try {
+ sub.lastKey();
+ fail("java.util.NoSuchElementException should be thrown");
+ } catch (java.util.NoSuchElementException e) {
+ }
+
+ }
+
+ /**
+ * java.util.TreeMap#values()
+ */
+ public void test_values() {
+ // Test for method java.util.Collection java.util.TreeMap.values()
+ Collection vals = tm.values();
+ vals.iterator();
+ assertTrue("Returned collection of incorrect size",
+ vals.size() == objArray.length);
+ for (Object element : objArray) {
+ assertTrue("Collection contains incorrect elements", vals
+ .contains(element));
+ }
+ assertEquals(1000, vals.size());
+ int j = 0;
+ for (Iterator iter = vals.iterator(); iter.hasNext(); ) {
+ Object element = (Object) iter.next();
+ j++;
+ }
+ assertEquals(1000, j);
+
+ vals = tm.descendingMap().values();
+ vals.iterator();
+ assertTrue("Returned collection of incorrect size",
+ vals.size() == objArray.length);
+ for (Object element : objArray) {
+ assertTrue("Collection contains incorrect elements", vals
+ .contains(element));
+ }
+ assertEquals(1000, vals.size());
+ j = 0;
+ for (Iterator iter = vals.iterator(); iter.hasNext(); ) {
+ Object element = (Object) iter.next();
+ j++;
+ }
+ assertEquals(1000, j);
+
+ TreeMap myTreeMap = new TreeMap();
+ for (int i = 0; i < 100; i++) {
+ myTreeMap.put(objArray[i], objArray[i]);
+ }
+ Collection values = myTreeMap.values();
+ new Support_UnmodifiableCollectionTest(
+ "Test Returned Collection From TreeMap.values()", values)
+ .runTest();
+ values.remove(new Integer(0));
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myTreeMap.containsValue(new Integer(0)));
+ assertEquals(99, values.size());
+ j = 0;
+ for (Iterator iter = values.iterator(); iter.hasNext(); ) {
+ Object element = (Object) iter.next();
+ j++;
+ }
+ assertEquals(99, j);
+
+ }
+
+ /**
+ * java.util.TreeMap the values() method in sub maps
+ */
+ public void test_subMap_values_size() {
+ TreeMap myTreeMap = new TreeMap();
+ for (int i = 0; i < 1000; i++) {
+ myTreeMap.put(i, objArray[i]);
+ }
+ // Test for method values() in subMaps
+ Collection vals = myTreeMap.subMap(200, 400).values();
+ assertTrue("Returned collection of incorrect size", vals.size() == 200);
+ for (int i = 200; i < 400; i++) {
+ assertTrue("Collection contains incorrect elements" + i, vals
+ .contains(objArray[i]));
+ }
+ assertEquals(200, vals.toArray().length);
+ vals.remove(objArray[300]);
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myTreeMap.containsValue(objArray[300]));
+ assertTrue("Returned collection of incorrect size", vals.size() == 199);
+ assertEquals(199, vals.toArray().length);
+
+ myTreeMap.put(300, objArray[300]);
+ // Test for method values() in subMaps
+ vals = myTreeMap.headMap(400).values();
+ assertEquals("Returned collection of incorrect size", vals.size(), 400);
+ for (int i = 0; i < 400; i++) {
+ assertTrue("Collection contains incorrect elements " + i, vals
+ .contains(objArray[i]));
+ }
+ assertEquals(400, vals.toArray().length);
+ vals.remove(objArray[300]);
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myTreeMap.containsValue(objArray[300]));
+ assertTrue("Returned collection of incorrect size", vals.size() == 399);
+ assertEquals(399, vals.toArray().length);
+
+ myTreeMap.put(300, objArray[300]);
+ // Test for method values() in subMaps
+ vals = myTreeMap.tailMap(400).values();
+ assertEquals("Returned collection of incorrect size", vals.size(), 600);
+ for (int i = 400; i < 1000; i++) {
+ assertTrue("Collection contains incorrect elements " + i, vals
+ .contains(objArray[i]));
+ }
+ assertEquals(600, vals.toArray().length);
+ vals.remove(objArray[600]);
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myTreeMap.containsValue(objArray[600]));
+ assertTrue("Returned collection of incorrect size", vals.size() == 599);
+ assertEquals(599, vals.toArray().length);
+
+
+ myTreeMap.put(600, objArray[600]);
+ // Test for method values() in subMaps
+ vals = myTreeMap.descendingMap().headMap(400).values();
+ assertEquals("Returned collection of incorrect size", vals.size(), 599);
+ for (int i = 401; i < 1000; i++) {
+ assertTrue("Collection contains incorrect elements " + i, vals
+ .contains(objArray[i]));
+ }
+ assertEquals(599, vals.toArray().length);
+ vals.remove(objArray[600]);
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myTreeMap.containsValue(objArray[600]));
+ assertTrue("Returned collection of incorrect size", vals.size() == 598);
+ assertEquals(598, vals.toArray().length);
+
+ myTreeMap.put(600, objArray[600]);
+ // Test for method values() in subMaps
+ vals = myTreeMap.descendingMap().tailMap(400).values();
+ assertEquals("Returned collection of incorrect size", vals.size(), 401);
+ for (int i = 0; i <= 400; i++) {
+ assertTrue("Collection contains incorrect elements " + i, vals
+ .contains(objArray[i]));
+ }
+ assertEquals(401, vals.toArray().length);
+ vals.remove(objArray[300]);
+ assertTrue(
+ "Removing from the values collection should remove from the original map",
+ !myTreeMap.containsValue(objArray[300]));
+ assertTrue("Returned collection of incorrect size", vals.size() == 400);
+ assertEquals(400, vals.toArray().length);
+
+ }
+
+ /**
+ * java.util.TreeMap#subMap()
+ */
+ public void test_subMap_Iterator2() {
+ TreeMap<String, String> map = new TreeMap<String, String>();
+
+ String[] keys = { "1", "2", "3" };
+ String[] values = { "one", "two", "three" };
+ for (int i = 0; i < keys.length; i++) {
+ map.put(keys[i], values[i]);
+ }
+
+ assertEquals(3, map.size());
+
+ Map subMap = map.subMap("", "test");
+ assertEquals(3, subMap.size());
+
+ Set entrySet = subMap.entrySet();
+ Iterator iter = entrySet.iterator();
+ int size = 0;
+ while (iter.hasNext()) {
+ Map.Entry<String, String> entry = (Map.Entry<String, String>) iter
+ .next();
+ assertTrue(map.containsKey(entry.getKey()));
+ assertTrue(map.containsValue(entry.getValue()));
+ size++;
+ }
+ assertEquals(map.size(), size);
+
+ Set<String> keySet = subMap.keySet();
+ iter = keySet.iterator();
+ size = 0;
+ while (iter.hasNext()) {
+ String key = (String) iter.next();
+ assertTrue(map.containsKey(key));
+ size++;
+ }
+ assertEquals(map.size(), size);
+ }
+
+ /**
+ * java.util.TreeMap#SerializationTest()
+ */
+ // Regression for Harmony-1066
+ public void test_SubMap_Serializable() throws Exception {
+ TreeMap<Integer, Double> map = new TreeMap<Integer, Double>();
+ map.put(1, 2.1);
+ map.put(2, 3.1);
+ map.put(3, 4.5);
+ map.put(7, 21.3);
+ SortedMap<Integer, Double> headMap = map.headMap(3);
+ assertTrue(headMap instanceof Serializable);
+ assertFalse(headMap instanceof TreeMap);
+ assertTrue(headMap instanceof SortedMap);
+
+ assertFalse(headMap.entrySet() instanceof Serializable);
+ assertFalse(headMap.keySet() instanceof Serializable);
+ assertFalse(headMap.values() instanceof Serializable);
+
+ // This assertion will fail on RI. This is a bug of RI.
+ SerializationTest.verifySelf(headMap);
+ }
+
+ /**
+ * {@link java.util.TreeMap#firstEntry()}
+ */
+ public void test_firstEntry() throws Exception {
+ Integer testint = new Integer(-1);
+ Integer testint10000 = new Integer(-10000);
+ Integer testint9999 = new Integer(-9999);
+ assertEquals(objArray[0].toString(), tm.firstEntry().getKey());
+ assertEquals(objArray[0], tm.firstEntry().getValue());
+ tm.put(testint.toString(), testint);
+ assertEquals(testint.toString(), tm.firstEntry().getKey());
+ assertEquals(testint, tm.firstEntry().getValue());
+ tm.put(testint10000.toString(), testint10000);
+ assertEquals(testint.toString(), tm.firstEntry().getKey());
+ assertEquals(testint, tm.firstEntry().getValue());
+ tm.put(testint9999.toString(), testint9999);
+ assertEquals(testint.toString(), tm.firstEntry().getKey());
+ Entry entry = tm.firstEntry();
+ assertEquals(testint, entry.getValue());
+ assertEntry(entry);
+ tm.clear();
+ assertNull(tm.firstEntry());
+ }
+
+ /**
+ * {@link java.util.TreeMap#lastEntry()
+ */
+ public void test_lastEntry() throws Exception {
+ Integer testint10000 = new Integer(10000);
+ Integer testint9999 = new Integer(9999);
+ assertEquals(objArray[999].toString(), tm.lastEntry().getKey());
+ assertEquals(objArray[999], tm.lastEntry().getValue());
+ tm.put(testint10000.toString(), testint10000);
+ assertEquals(objArray[999].toString(), tm.lastEntry().getKey());
+ assertEquals(objArray[999], tm.lastEntry().getValue());
+ tm.put(testint9999.toString(), testint9999);
+ assertEquals(testint9999.toString(), tm.lastEntry().getKey());
+ Entry entry = tm.lastEntry();
+ assertEquals(testint9999, entry.getValue());
+ assertEntry(entry);
+ tm.clear();
+ assertNull(tm.lastEntry());
+ }
+
+ /**
+ * {@link java.util.TreeMap#pollFirstEntry()
+ */
+ public void test_pollFirstEntry() throws Exception {
+ Integer testint = new Integer(-1);
+ Integer testint10000 = new Integer(-10000);
+ Integer testint9999 = new Integer(-9999);
+ assertEquals(objArray[0].toString(), tm.pollFirstEntry().getKey());
+ assertEquals(objArray[1], tm.pollFirstEntry().getValue());
+ assertEquals(objArray[10], tm.pollFirstEntry().getValue());
+ tm.put(testint.toString(), testint);
+ tm.put(testint10000.toString(), testint10000);
+ assertEquals(testint.toString(), tm.pollFirstEntry().getKey());
+ assertEquals(testint10000, tm.pollFirstEntry().getValue());
+ tm.put(testint9999.toString(), testint9999);
+ assertEquals(testint9999.toString(), tm.pollFirstEntry().getKey());
+ Entry entry = tm.pollFirstEntry();
+ assertEntry(entry);
+ assertEquals(objArray[100], entry.getValue());
+ tm.clear();
+ assertNull(tm.pollFirstEntry());
+ }
+
+ /**
+ * {@link java.util.TreeMap#pollLastEntry()
+ */
+ public void test_pollLastEntry() throws Exception {
+ Integer testint10000 = new Integer(10000);
+ Integer testint9999 = new Integer(9999);
+ assertEquals(objArray[999].toString(), tm.pollLastEntry().getKey());
+ assertEquals(objArray[998], tm.pollLastEntry().getValue());
+ assertEquals(objArray[997], tm.pollLastEntry().getValue());
+ tm.put(testint10000.toString(), testint10000);
+ assertEquals(objArray[996], tm.pollLastEntry().getValue());
+ tm.put(testint9999.toString(), testint9999);
+ assertEquals(testint9999.toString(), tm.pollLastEntry().getKey());
+ Entry entry = tm.pollLastEntry();
+ assertEquals(objArray[995], entry.getValue());
+ assertEntry(entry);
+ tm.clear();
+ assertNull(tm.pollLastEntry());
+ }
+
+ /**
+ * {@link java.util.TreeMap#lowerEntry(Object)
+ */
+ public void test_lowerEntry() throws Exception {
+ Integer testint10000 = new Integer(10000);
+ Integer testint9999 = new Integer(9999);
+ assertEquals(objArray[999], tm.lowerEntry(testint9999.toString())
+ .getValue());
+ assertEquals(objArray[100], tm.lowerEntry(testint10000.toString())
+ .getValue());
+ tm.put(testint10000.toString(), testint10000);
+ tm.put(testint9999.toString(), testint9999);
+ assertEquals(objArray[999], tm.lowerEntry(testint9999.toString())
+ .getValue());
+ Entry entry = tm.lowerEntry(testint10000.toString());
+ assertEquals(objArray[100], entry.getValue());
+ assertEntry(entry);
+ try {
+ tm.lowerEntry(testint10000);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.lowerEntry(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ tm.clear();
+ assertNull(tm.lowerEntry(testint9999.toString()));
+ }
+
+ /**
+ * {@link java.util.TreeMap#lowerKey(Object)
+ */
+ public void test_lowerKey() throws Exception {
+ Integer testint10000 = new Integer(10000);
+ Integer testint9999 = new Integer(9999);
+ assertEquals(objArray[999].toString(), tm.lowerKey(testint9999
+ .toString()));
+ assertEquals(objArray[100].toString(), tm.lowerKey(testint10000
+ .toString()));
+ tm.put(testint10000.toString(), testint10000);
+ tm.put(testint9999.toString(), testint9999);
+ assertEquals(objArray[999].toString(), tm.lowerKey(testint9999
+ .toString()));
+ assertEquals(objArray[100].toString(), tm.lowerKey(testint10000
+ .toString()));
+ try {
+ tm.lowerKey(testint10000);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.lowerKey(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ tm.clear();
+ assertNull(tm.lowerKey(testint9999.toString()));
+ }
+
+ /**
+ * {@link java.util.TreeMap#floorEntry(Object)
+ */
+ public void test_floorEntry() throws Exception {
+ Integer testint10000 = new Integer(10000);
+ Integer testint9999 = new Integer(9999);
+ assertEquals(objArray[999], tm.floorEntry(testint9999.toString())
+ .getValue());
+ assertEquals(objArray[100], tm.floorEntry(testint10000.toString())
+ .getValue());
+ tm.put(testint10000.toString(), testint10000);
+ tm.put(testint9999.toString(), testint9999);
+ assertEquals(testint9999, tm.floorEntry(testint9999.toString())
+ .getValue());
+ Entry entry = tm.floorEntry(testint10000.toString());
+ assertEquals(testint10000, entry.getValue());
+ assertEntry(entry);
+ try {
+ tm.floorEntry(testint10000);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.floorEntry(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ tm.clear();
+ assertNull(tm.floorEntry(testint9999.toString()));
+ }
+
+ /**
+ * {@link java.util.TreeMap#floorKey(Object)
+ */
+ public void test_floorKey() throws Exception {
+ Integer testint10000 = new Integer(10000);
+ Integer testint9999 = new Integer(9999);
+ assertEquals(objArray[999].toString(), tm.floorKey(testint9999
+ .toString()));
+ assertEquals(objArray[100].toString(), tm.floorKey(testint10000
+ .toString()));
+ tm.put(testint10000.toString(), testint10000);
+ tm.put(testint9999.toString(), testint9999);
+ assertEquals(testint9999.toString(), tm
+ .floorKey(testint9999.toString()));
+ assertEquals(testint10000.toString(), tm.floorKey(testint10000
+ .toString()));
+ try {
+ tm.floorKey(testint10000);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.floorKey(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ tm.clear();
+ assertNull(tm.floorKey(testint9999.toString()));
+ }
+
+ /**
+ * {@link java.util.TreeMap#ceilingEntry(Object)
+ */
+ public void test_ceilingEntry() throws Exception {
+ Integer testint100 = new Integer(100);
+ Integer testint = new Integer(-1);
+ assertEquals(objArray[0], tm.ceilingEntry(testint.toString())
+ .getValue());
+ assertEquals(objArray[100], tm.ceilingEntry(testint100.toString())
+ .getValue());
+ tm.put(testint.toString(), testint);
+ tm.put(testint100.toString(), testint);
+ assertEquals(testint, tm.ceilingEntry(testint.toString()).getValue());
+ Entry entry = tm.ceilingEntry(testint100.toString());
+ assertEquals(testint, entry.getValue());
+ assertEntry(entry);
+ try {
+ tm.ceilingEntry(testint100);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.ceilingEntry(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ tm.clear();
+ assertNull(tm.ceilingEntry(testint.toString()));
+ }
+
+ /**
+ * {@link java.util.TreeMap#ceilingKey(Object)
+ */
+ public void test_ceilingKey() throws Exception {
+ Integer testint100 = new Integer(100);
+ Integer testint = new Integer(-1);
+ assertEquals(objArray[0].toString(), tm.ceilingKey(testint.toString()));
+ assertEquals(objArray[100].toString(), tm.ceilingKey(testint100
+ .toString()));
+ tm.put(testint.toString(), testint);
+ tm.put(testint100.toString(), testint);
+ assertEquals(testint.toString(), tm.ceilingKey(testint.toString()));
+ assertEquals(testint100.toString(), tm
+ .ceilingKey(testint100.toString()));
+ try {
+ tm.ceilingKey(testint100);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.ceilingKey(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ tm.clear();
+ assertNull(tm.ceilingKey(testint.toString()));
+ }
+
+ /**
+ * {@link java.util.TreeMap#higherEntry(Object)
+ */
+ public void test_higherEntry() throws Exception {
+ Integer testint9999 = new Integer(9999);
+ Integer testint10000 = new Integer(10000);
+ Integer testint100 = new Integer(100);
+ Integer testint = new Integer(-1);
+ assertEquals(objArray[0], tm.higherEntry(testint.toString()).getValue());
+ assertEquals(objArray[101], tm.higherEntry(testint100.toString())
+ .getValue());
+ assertEquals(objArray[101], tm.higherEntry(testint10000.toString())
+ .getValue());
+ tm.put(testint9999.toString(), testint);
+ tm.put(testint100.toString(), testint);
+ tm.put(testint10000.toString(), testint);
+ assertEquals(objArray[0], tm.higherEntry(testint.toString()).getValue());
+ assertEquals(testint, tm.higherEntry(testint100.toString()).getValue());
+ Entry entry = tm.higherEntry(testint10000.toString());
+ assertEquals(objArray[101], entry.getValue());
+ assertEntry(entry);
+ assertNull(tm.higherEntry(testint9999.toString()));
+ try {
+ tm.higherEntry(testint100);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.higherEntry(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ tm.clear();
+ assertNull(tm.higherEntry(testint.toString()));
+ }
+
+ /**
+ * {@link java.util.TreeMap#higherKey(Object)
+ */
+ public void test_higherKey() throws Exception {
+ Integer testint9999 = new Integer(9999);
+ Integer testint10000 = new Integer(10000);
+ Integer testint100 = new Integer(100);
+ Integer testint = new Integer(-1);
+ assertEquals(objArray[0].toString(), tm.higherKey(testint.toString()));
+ assertEquals(objArray[101].toString(), tm.higherKey(testint100
+ .toString()));
+ assertEquals(objArray[101].toString(), tm.higherKey(testint10000
+ .toString()));
+ tm.put(testint9999.toString(), testint);
+ tm.put(testint100.toString(), testint);
+ tm.put(testint10000.toString(), testint);
+ assertEquals(objArray[0].toString(), tm.higherKey(testint.toString()));
+ assertEquals(testint10000.toString(), tm.higherKey(testint100
+ .toString()));
+ assertEquals(objArray[101].toString(), tm.higherKey(testint10000
+ .toString()));
+ assertNull(tm.higherKey(testint9999.toString()));
+ try {
+ tm.higherKey(testint100);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.higherKey(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ tm.clear();
+ assertNull(tm.higherKey(testint.toString()));
+ }
+
+ public void test_navigableKeySet() throws Exception {
+ Integer testint9999 = new Integer(9999);
+ Integer testint10000 = new Integer(10000);
+ Integer testint100 = new Integer(100);
+ Integer testint0 = new Integer(0);
+ NavigableSet set = tm.navigableKeySet();
+ assertFalse(set.contains(testint9999.toString()));
+ tm.put(testint9999.toString(), testint9999);
+ assertTrue(set.contains(testint9999.toString()));
+ tm.remove(testint9999.toString());
+ assertFalse(set.contains(testint9999.toString()));
+ try {
+ set.add(new Object());
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ set.add(null);
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ set.addAll(null);
+ fail("should throw UnsupportedOperationException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ Collection collection = new LinkedList();
+ set.addAll(collection);
+ try {
+ collection.add(new Object());
+ set.addAll(collection);
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ set.remove(testint100.toString());
+ assertFalse(tm.containsKey(testint100.toString()));
+ assertTrue(tm.containsKey(testint0.toString()));
+ Iterator iter = set.iterator();
+ iter.next();
+ iter.remove();
+ assertFalse(tm.containsKey(testint0.toString()));
+ collection.add(new Integer(200).toString());
+ set.retainAll(collection);
+ assertEquals(1, tm.size());
+ set.removeAll(collection);
+ assertEquals(0, tm.size());
+ tm.put(testint10000.toString(), testint10000);
+ assertEquals(1, tm.size());
+ set.clear();
+ assertEquals(0, tm.size());
+ }
+
+ private void assertEntry(Entry entry) {
+ try {
+ entry.setValue(new Object());
+ fail("should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals((entry.getKey() == null ? 0 : entry.getKey().hashCode())
+ ^ (entry.getValue() == null ? 0 : entry.getValue().hashCode()),
+ entry.hashCode());
+ assertEquals(entry.toString(), entry.getKey() + "=" + entry.getValue());
+ }
+
+ /**
+ * java.util.TreeMap#subMap(java.lang.Object, boolean,
+ *java.lang.Object, boolean)
+ */
+ public void test_subMapLjava_lang_ObjectZLjava_lang_ObjectZ() {
+ // normal case
+ SortedMap subMap = tm.subMap(objArray[100].toString(), true,
+ objArray[109].toString(), true);
+ assertEquals("subMap is of incorrect size", 10, subMap.size());
+ subMap = tm.subMap(objArray[100].toString(), true, objArray[109]
+ .toString(), false);
+ assertEquals("subMap is of incorrect size", 9, subMap.size());
+ for (int counter = 100; counter < 109; counter++) {
+ assertTrue("SubMap contains incorrect elements", subMap.get(
+ objArray[counter].toString()).equals(objArray[counter]));
+ }
+ subMap = tm.subMap(objArray[100].toString(), false, objArray[109]
+ .toString(), true);
+ assertEquals("subMap is of incorrect size", 9, subMap.size());
+ assertNull(subMap.get(objArray[100].toString()));
+
+ // Exceptions
+ try {
+ tm.subMap(objArray[9].toString(), true, objArray[1].toString(),
+ true);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ tm.subMap(objArray[9].toString(), false, objArray[1].toString(),
+ false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ tm.subMap(null, true, null, true);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ tm.subMap(null, false, objArray[100], true);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ tm.subMap(new LinkedList(), false, objArray[100], true);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ // use integer elements to test
+ TreeMap<Integer, String> treeMapInt = new TreeMap<Integer, String>();
+ assertEquals(0, treeMapInt.subMap(new Integer(-1), true,
+ new Integer(100), true).size());
+ for (int i = 0; i < 100; i++) {
+ treeMapInt.put(new Integer(i), new Integer(i).toString());
+ }
+ SortedMap<Integer, String> result = treeMapInt.subMap(new Integer(-1),
+ true, new Integer(100), true);
+ assertEquals(100, result.size());
+ result.put(new Integer(-1), new Integer(-1).toString());
+ assertEquals(101, result.size());
+ assertEquals(101, treeMapInt.size());
+ result = treeMapInt
+ .subMap(new Integer(50), true, new Integer(60), true);
+ assertEquals(11, result.size());
+ try {
+ result.put(new Integer(-2), new Integer(-2).toString());
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(11, result.size());
+ treeMapInt.remove(new Integer(50));
+ assertEquals(100, treeMapInt.size());
+ assertEquals(10, result.size());
+ result.remove(new Integer(60));
+ assertEquals(99, treeMapInt.size());
+ assertEquals(9, result.size());
+ SortedMap<Integer, String> result2 = null;
+ try {
+ result2 = result.subMap(new Integer(-2), new Integer(100));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ result2 = result.subMap(new Integer(50), new Integer(60));
+ assertEquals(9, result2.size());
+
+ // sub map of sub map
+ NavigableMap<Integer, Object> mapIntObj = new TreeMap<Integer, Object>();
+ for (int i = 0; i < 10; ++i) {
+ mapIntObj.put(i, new Object());
+ }
+ mapIntObj = mapIntObj.subMap(5, false, 9, true);
+ assertEquals(4, mapIntObj.size());
+ mapIntObj = mapIntObj.subMap(5, false, 9, true);
+ assertEquals(4, mapIntObj.size());
+ mapIntObj = mapIntObj.subMap(5, false, 6, false);
+ assertEquals(0, mapIntObj.size());
+
+ // a special comparator dealing with null key
+ tm = new TreeMap(new Comparator() {
+ public int compare(Object o1, Object o2) {
+ if (o1 == null) {
+ return -1;
+ }
+ if (o2 == null) {
+ return 1;
+ }
+ return ((String) o1).compareTo((String) o2);
+ }
+ });
+ tm.put(null, -1);
+ tm.put(new String("1st"), 1);
+ tm.put(new String("2nd"), 2);
+ tm.put(new String("3rd"), 3);
+ SortedMap s = tm.subMap(null, "3rd");
+ assertEquals(3, s.size());
+ assertTrue(s.containsValue(-1));
+ assertTrue(s.containsValue(1));
+ assertTrue(s.containsValue(2));
+ assertFalse(s.containsKey(null));
+
+ s = tm.descendingMap();
+ s = s.subMap("3rd", null);
+ assertFalse(s.containsKey(null));
+ assertTrue(s.containsKey("1st"));
+ assertTrue(s.containsKey("2nd"));
+ assertTrue(s.containsKey("3rd"));
+ }
+
+ public void test_subMap_NullTolerableComparator() {
+ // Null Tolerable Comparator
+ TreeMap<String, String> treeMapWithNull = new TreeMap<String, String>(
+ new MockComparatorNullTolerable());
+ treeMapWithNull.put("key1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+ treeMapWithNull.put(null, "value2"); //$NON-NLS-1$
+ SortedMap<String, String> subMapWithNull = treeMapWithNull.subMap(null,
+ true, "key1", true); //$NON-NLS-1$
+
+ // RI fails here
+ assertEquals("Size of subMap should be 2:", 2, subMapWithNull.size()); //$NON-NLS-1$
+ assertEquals("value1", subMapWithNull.get("key1"));
+ assertEquals("value2", subMapWithNull.get(null));
+ treeMapWithNull.put("key0", "value2");
+ treeMapWithNull.put("key3", "value3");
+ treeMapWithNull.put("key4", "value4");
+ treeMapWithNull.put("key5", "value5");
+ treeMapWithNull.put("key6", "value6");
+ assertEquals("Size of subMap should be 3:", 3, subMapWithNull.size()); //$NON-NLS-1$
+ subMapWithNull = treeMapWithNull.subMap(null, false, "key1", true); //$NON-NLS-1$
+ assertEquals("Size of subMap should be 2:", 2, subMapWithNull.size()); //$NON-NLS-1$
+ }
+
+
+ /**
+ * java.util.TreeMap#headMap(java.lang.Object, boolea)
+ */
+ public void test_headMapLjava_lang_ObjectZL() {
+ // normal case
+ SortedMap subMap = tm.headMap(objArray[100].toString(), true);
+ assertEquals("subMap is of incorrect size", 4, subMap.size());
+ subMap = tm.headMap(objArray[109].toString(), true);
+ assertEquals("subMap is of incorrect size", 13, subMap.size());
+ for (int counter = 100; counter < 109; counter++) {
+ assertTrue("SubMap contains incorrect elements", subMap.get(
+ objArray[counter].toString()).equals(objArray[counter]));
+ }
+ subMap = tm.headMap(objArray[100].toString(), false);
+ assertEquals("subMap is of incorrect size", 3, subMap.size());
+ assertNull(subMap.get(objArray[100].toString()));
+
+ // Exceptions
+ assertEquals(0, tm.headMap("", true).size());
+ assertEquals(0, tm.headMap("", false).size());
+
+ try {
+ tm.headMap(null, true);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ tm.headMap(null, false);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ tm.headMap(new Object(), true);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.headMap(new Object(), false);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ // use integer elements to test
+ TreeMap<Integer, String> treeMapInt = new TreeMap<Integer, String>();
+ assertEquals(0, treeMapInt.headMap(new Integer(-1), true).size());
+ for (int i = 0; i < 100; i++) {
+ treeMapInt.put(new Integer(i), new Integer(i).toString());
+ }
+ SortedMap<Integer, String> result = treeMapInt
+ .headMap(new Integer(101));
+ assertEquals(100, result.size());
+ try {
+ result.put(new Integer(101), new Integer(101).toString());
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(100, result.size());
+ assertEquals(100, treeMapInt.size());
+ result = treeMapInt.headMap(new Integer(50), true);
+ assertEquals(51, result.size());
+ result.put(new Integer(-1), new Integer(-1).toString());
+ assertEquals(52, result.size());
+
+ treeMapInt.remove(new Integer(40));
+ assertEquals(100, treeMapInt.size());
+ assertEquals(51, result.size());
+ result.remove(new Integer(30));
+ assertEquals(99, treeMapInt.size());
+ assertEquals(50, result.size());
+ SortedMap<Integer, String> result2 = null;
+ try {
+ result.subMap(new Integer(-2), new Integer(100));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ result.subMap(new Integer(1), new Integer(100));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ result2 = result.subMap(new Integer(-2), new Integer(48));
+ assertEquals(47, result2.size());
+
+ result2 = result.subMap(new Integer(40), new Integer(50));
+ assertEquals(9, result2.size());
+
+ // Null Tolerable Comparator
+ TreeMap<String, String> treeMapWithNull = new TreeMap<String, String>(
+ new MockComparatorNullTolerable());
+ treeMapWithNull.put("key1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+ treeMapWithNull.put(null, "value2"); //$NON-NLS-1$
+ SortedMap<String, String> subMapWithNull = treeMapWithNull.headMap(
+ null, true); //$NON-NLS-1$
+ assertEquals("Size of subMap should be 1:", 1, subMapWithNull.size()); //$NON-NLS-1$
+ assertEquals(null, subMapWithNull.get("key1"));
+ assertEquals("value2", subMapWithNull.get(null));
+ treeMapWithNull.put("key0", "value2");
+ treeMapWithNull.put("key3", "value3");
+ treeMapWithNull.put("key4", "value4");
+ treeMapWithNull.put("key5", "value5");
+ treeMapWithNull.put("key6", "value6");
+ assertEquals("Size of subMap should be 1:", 1, subMapWithNull.size()); //$NON-NLS-1$
+ subMapWithNull = treeMapWithNull.subMap(null, false, "key1", true); //$NON-NLS-1$
+ assertEquals("Size of subMap should be 2:", 2, subMapWithNull.size()); //$NON-NLS-1$
+
+ // head map of head map
+ NavigableMap<Integer, Object> original = new TreeMap<Integer, Object>();
+ for (int i = 0; i < 10; ++i) {
+ original.put(i, new Object());
+ }
+ NavigableMap<Integer, Object> mapIntObj = original.headMap(5, false);
+ assertEquals(5, mapIntObj.size());
+ mapIntObj = mapIntObj.headMap(5, false);
+ assertEquals(5, mapIntObj.size());
+ try {
+ mapIntObj = mapIntObj.tailMap(5, false);
+ fail("IllegalArgumentException expected: key falls outside restricted range");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ assertEquals(0, original.headMap(0, false).size());
+ }
+
+ /**
+ * java.util.TreeMap#tailMap(java.lang.Object, boolea)
+ */
+ public void test_tailMapLjava_lang_ObjectZL() {
+ // normal case
+ SortedMap subMap = tm.tailMap(objArray[100].toString(), true);
+ assertEquals("subMap is of incorrect size", 997, subMap.size());
+ subMap = tm.tailMap(objArray[109].toString(), true);
+ assertEquals("subMap is of incorrect size", 988, subMap.size());
+ for (int counter = 119; counter > 110; counter--) {
+ assertTrue("SubMap contains incorrect elements", subMap.get(
+ objArray[counter].toString()).equals(objArray[counter]));
+ }
+ subMap = tm.tailMap(objArray[100].toString(), false);
+ assertEquals("subMap is of incorrect size", 996, subMap.size());
+ assertNull(subMap.get(objArray[100].toString()));
+
+ // Exceptions
+ assertEquals(1000, tm.tailMap("", true).size());
+ assertEquals(1000, tm.tailMap("", false).size());
+
+ try {
+ tm.tailMap(null, true);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ tm.tailMap(null, false);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ tm.tailMap(new Object(), true);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ try {
+ tm.tailMap(new Object(), false);
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+
+ // use integer elements to test
+ TreeMap<Integer, String> treeMapInt = new TreeMap<Integer, String>();
+ assertEquals(0, treeMapInt.tailMap(new Integer(-1), true).size());
+ for (int i = 0; i < 100; i++) {
+ treeMapInt.put(new Integer(i), new Integer(i).toString());
+ }
+ SortedMap<Integer, String> result = treeMapInt.tailMap(new Integer(1));
+ assertEquals(99, result.size());
+ try {
+ result.put(new Integer(-1), new Integer(-1).toString());
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ assertEquals(99, result.size());
+ assertEquals(100, treeMapInt.size());
+ result = treeMapInt.tailMap(new Integer(50), true);
+ assertEquals(50, result.size());
+ result.put(new Integer(101), new Integer(101).toString());
+ assertEquals(51, result.size());
+
+ treeMapInt.remove(new Integer(60));
+ assertEquals(100, treeMapInt.size());
+ assertEquals(50, result.size());
+ result.remove(new Integer(70));
+ assertEquals(99, treeMapInt.size());
+ assertEquals(49, result.size());
+ SortedMap<Integer, String> result2 = null;
+ try {
+ result2 = result.subMap(new Integer(-2), new Integer(100));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ result2 = result.subMap(new Integer(60), new Integer(70));
+ assertEquals(9, result2.size());
+
+ // Null Tolerable Comparator
+ TreeMap<String, String> treeMapWithNull = new TreeMap<String, String>(
+ new MockComparatorNullTolerable());
+ treeMapWithNull.put("key1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+ treeMapWithNull.put(null, "value2"); //$NON-NLS-1$
+ SortedMap<String, String> subMapWithNull = treeMapWithNull.tailMap(
+ "key1", true); //$NON-NLS-1$
+ assertEquals("Size of subMap should be 1:", 1, subMapWithNull.size()); //$NON-NLS-1$
+ assertEquals("value1", subMapWithNull.get("key1"));
+ assertEquals(null, subMapWithNull.get(null));
+ treeMapWithNull.put("key0", "value2");
+ treeMapWithNull.put("key3", "value3");
+ treeMapWithNull.put("key4", "value4");
+ treeMapWithNull.put("key5", "value5");
+ treeMapWithNull.put("key6", "value6");
+ assertEquals("Size of subMap should be 5:", 5, subMapWithNull.size()); //$NON-NLS-1$
+ subMapWithNull = treeMapWithNull.subMap(null, false, "key1", true); //$NON-NLS-1$
+ assertEquals("Size of subMap should be 2:", 2, subMapWithNull.size()); //$NON-NLS-1$
+
+ // tail map of tail map
+ NavigableMap<Integer, Object> original = new TreeMap<Integer, Object>();
+ for (int i = 0; i < 10; ++i) {
+ original.put(i, new Object());
+ }
+ NavigableMap<Integer, Object> mapIntObj = original.tailMap(5, false);
+ assertEquals(4, mapIntObj.size());
+ mapIntObj = mapIntObj.tailMap(5, false);
+ assertEquals(4, mapIntObj.size());
+ try {
+ mapIntObj = mapIntObj.headMap(5, false);
+ fail("IllegalArgumentException expected: key falls outside restricted range");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ assertEquals(0, original.headMap(0, false).size());
+ }
+
+ public void test_descendingMap_subMap() throws Exception {
+ TreeMap<Integer, Object> tm = new TreeMap<Integer, Object>();
+ for (int i = 0; i < 10; ++i) {
+ tm.put(i, new Object());
+ }
+ NavigableMap<Integer, Object> descMap = tm.descendingMap();
+ assertEquals(7, descMap.subMap(8, true, 1, false).size());
+ assertEquals(4, descMap.headMap(6, true).size());
+ assertEquals(2, descMap.tailMap(2, false).size());
+
+ // sub map of sub map of descendingMap
+ NavigableMap<Integer, Object> mapIntObj = new TreeMap<Integer, Object>();
+ for (int i = 0; i < 10; ++i) {
+ mapIntObj.put(i, new Object());
+ }
+ mapIntObj = mapIntObj.descendingMap();
+ NavigableMap<Integer, Object> subMapIntObj = mapIntObj.subMap(9, true,
+ 5, false);
+ assertEquals(4, subMapIntObj.size());
+ subMapIntObj = subMapIntObj.subMap(9, true, 5, false);
+ assertEquals(4, subMapIntObj.size());
+ subMapIntObj = subMapIntObj.subMap(6, false, 5, false);
+ assertEquals(0, subMapIntObj.size());
+
+ subMapIntObj = mapIntObj.headMap(5, false);
+ assertEquals(4, subMapIntObj.size());
+ subMapIntObj = subMapIntObj.headMap(5, false);
+ assertEquals(4, subMapIntObj.size());
+ try {
+ subMapIntObj = subMapIntObj.tailMap(5, false);
+ fail("IllegalArgumentException expected: key falls outside restricted range");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ subMapIntObj = mapIntObj.tailMap(5, false);
+ assertEquals(5, subMapIntObj.size());
+ subMapIntObj = subMapIntObj.tailMap(5, false);
+ assertEquals(5, subMapIntObj.size());
+ try {
+ subMapIntObj = subMapIntObj.headMap(5, false);
+ fail("IllegalArgumentException expected: key falls outside restricted range");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ private void illegalFirstNullKeyMapTester(NavigableMap<String, String> map) {
+ try {
+ map.get(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ map.put("NormalKey", "value");
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ Set<String> keySet = map.keySet();
+ assertTrue(!keySet.isEmpty());
+ assertEquals(1, keySet.size());
+ for (String key : keySet) {
+ assertEquals(key, null);
+ try {
+ map.get(key);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // ignore
+ }
+ }
+ Set<Entry<String, String>> entrySet = map.entrySet();
+ assertTrue(!entrySet.isEmpty());
+ assertEquals(1, entrySet.size());
+ for (Entry<String, String> entry : entrySet) {
+ assertEquals(null, entry.getKey());
+ assertEquals("NullValue", entry.getValue());
+ }
+ Collection<String> values = map.values();
+ assertTrue(!values.isEmpty());
+ assertEquals(1, values.size());
+ for (String value : values) {
+ assertEquals("NullValue", value);
+ }
+
+ try {
+ map.headMap(null, true);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // ignore
+ }
+ try {
+ map.headMap(null, false);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // ignore
+ }
+
+ try {
+ map.subMap(null, false, null, false);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // ignore
+ }
+ try {
+ map.subMap(null, true, null, true);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // ignore
+ }
+ try {
+ map.tailMap(null, true);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // ignore
+ }
+ try {
+ map.tailMap(null, false);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // ignore
+ }
+ }
+
+ /**
+ * Tests equals() method.
+ * Tests that no ClassCastException will be thrown in all cases.
+ * Regression test for HARMONY-1639.
+ */
+ public void test_equals() throws Exception {
+ // comparing TreeMaps with different object types
+ Map m1 = new TreeMap();
+ Map m2 = new TreeMap();
+ m1.put("key1", "val1");
+ m1.put("key2", "val2");
+ m2.put(new Integer(1), "val1");
+ m2.put(new Integer(2), "val2");
+ assertFalse("Maps should not be equal 1", m1.equals(m2));
+ assertFalse("Maps should not be equal 2", m2.equals(m1));
+
+ // comparing TreeMap with HashMap
+ m1 = new TreeMap();
+ m2 = new HashMap();
+ m1.put("key", "val");
+ m2.put(new Object(), "val");
+ assertFalse("Maps should not be equal 3", m1.equals(m2));
+ assertFalse("Maps should not be equal 4", m2.equals(m1));
+ }
+
+ public void test_invalidKeys() throws Exception {
+ // comparing TreeMaps with not-comparable objects inside
+ TreeMap m1 = new TreeMap();
+ try {
+ m1.put(new Object(), "val1");
+ fail("ClassCastException expected");
+ } catch (ClassCastException expected) {
+
+ }
+ }
+
+ public void test_remove_from_iterator() throws Exception {
+ Set set = tm.keySet();
+ Iterator iter = set.iterator();
+ iter.next();
+ iter.remove();
+ try {
+ iter.remove();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Tests entrySet().contains() method behaviour with respect to entries
+ * with null values.
+ * Regression test for HARMONY-5788.
+ */
+ public void test_entrySet_contains() throws Exception {
+ TreeMap master = new TreeMap<String, String>();
+ TreeMap test_map = new TreeMap<String, String>();
+
+ master.put("null", null);
+ Object[] entry = master.entrySet().toArray();
+ assertFalse("Empty map should not contain the null-valued entry",
+ test_map.entrySet().contains(entry[0]));
+
+ Map<String, String> submap = test_map.subMap("a", "z");
+ entry = master.entrySet().toArray();
+ assertFalse("Empty submap should not contain the null-valued entry",
+ submap.entrySet().contains(entry[0]));
+
+ test_map.put("null", null);
+ assertTrue("entrySet().containsAll(...) should work with null values",
+ test_map.entrySet().containsAll(master.entrySet()));
+
+ master.clear();
+ master.put("null", '0');
+ entry = master.entrySet().toArray();
+ assertFalse("Null-valued entry should not equal non-null-valued entry",
+ test_map.entrySet().contains(entry[0]));
+ }
+
+ public void test_iterator_next_() {
+ Map m = tm.subMap("0", "1");
+ Iterator it = m.entrySet().iterator();
+ assertEquals("0=0", it.next().toString());
+ while (it.hasNext()) {
+ }
+ try {
+ it.next();
+ fail("should throw java.util.NoSuchElementException");
+ } catch (Exception e) {
+ assertTrue(e instanceof java.util.NoSuchElementException);
+ }
+ }
+
+ public void test_empty_subMap() throws Exception {
+ TreeMap<Float, List<Integer>> tm = new TreeMap<Float, List<Integer>>();
+ SortedMap<Float, List<Integer>> sm = tm.tailMap(1.1f);
+ assertTrue(sm.values().size() == 0);
+ }
+
+ public static TreeMap treeMap = new TreeMap();
+
+ public void test_values_1() {
+ treeMap.put("firstKey", "firstValue");
+ treeMap.put("secondKey", "secondValue");
+ treeMap.put("thirdKey", "thirdValue");
+ Object firstKey = treeMap.firstKey();
+ SortedMap subMap = ((SortedMap) treeMap).subMap(firstKey, firstKey);
+ Iterator iter = subMap.values().iterator();
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ @Override
+ protected void setUp() {
+ tm = new TreeMap();
+ for (int i = 0; i < objArray.length; i++) {
+ Object x = objArray[i] = new Integer(i);
+ tm.put(x.toString(), x);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeSetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeSetTest.java
new file mode 100644
index 0000000..43efa2d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeSetTest.java
@@ -0,0 +1,342 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+public class TreeSetTest extends junit.framework.TestCase {
+
+ public static class ReversedIntegerComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ return -(((Integer) o1).compareTo((Integer) o2));
+ }
+
+ public boolean equals(Object o1, Object o2) {
+ return ((Integer) o1).compareTo((Integer) o2) == 0;
+ }
+ }
+
+ TreeSet ts;
+
+ Object objArray[] = new Object[1000];
+
+ /**
+ * java.util.TreeSet#TreeSet()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.TreeSet()
+ assertTrue("Did not construct correct TreeSet", new TreeSet().isEmpty());
+ }
+
+ /**
+ * java.util.TreeSet#TreeSet(java.util.Collection)
+ */
+ public void test_ConstructorLjava_util_Collection() {
+ // Test for method java.util.TreeSet(java.util.Collection)
+ TreeSet myTreeSet = new TreeSet(Arrays.asList(objArray));
+ assertTrue("TreeSet incorrect size",
+ myTreeSet.size() == objArray.length);
+ for (int counter = 0; counter < objArray.length; counter++)
+ assertTrue("TreeSet does not contain correct elements", myTreeSet
+ .contains(objArray[counter]));
+ }
+
+ /**
+ * java.util.TreeSet#TreeSet(java.util.Comparator)
+ */
+ public void test_ConstructorLjava_util_Comparator() {
+ // Test for method java.util.TreeSet(java.util.Comparator)
+ TreeSet myTreeSet = new TreeSet(new ReversedIntegerComparator());
+ assertTrue("Did not construct correct TreeSet", myTreeSet.isEmpty());
+ myTreeSet.add(new Integer(1));
+ myTreeSet.add(new Integer(2));
+ assertTrue(
+ "Answered incorrect first element--did not use custom comparator ",
+ myTreeSet.first().equals(new Integer(2)));
+ assertTrue(
+ "Answered incorrect last element--did not use custom comparator ",
+ myTreeSet.last().equals(new Integer(1)));
+ }
+
+ /**
+ * java.util.TreeSet#TreeSet(java.util.SortedSet)
+ */
+ public void test_ConstructorLjava_util_SortedSet() {
+ // Test for method java.util.TreeSet(java.util.SortedSet)
+ ReversedIntegerComparator comp = new ReversedIntegerComparator();
+ TreeSet myTreeSet = new TreeSet(comp);
+ for (int i = 0; i < objArray.length; i++)
+ myTreeSet.add(objArray[i]);
+ TreeSet anotherTreeSet = new TreeSet(myTreeSet);
+ assertTrue("TreeSet is not correct size",
+ anotherTreeSet.size() == objArray.length);
+ for (int counter = 0; counter < objArray.length; counter++)
+ assertTrue("TreeSet does not contain correct elements",
+ anotherTreeSet.contains(objArray[counter]));
+ assertTrue("TreeSet does not answer correct comparator", anotherTreeSet
+ .comparator() == comp);
+ assertTrue("TreeSet does not use comparator",
+ anotherTreeSet.first() == objArray[objArray.length - 1]);
+ }
+
+ /**
+ * java.util.TreeSet#add(java.lang.Object)
+ */
+ public void test_addLjava_lang_Object() {
+ // Test for method boolean java.util.TreeSet.add(java.lang.Object)
+ ts.add(new Integer(-8));
+ assertTrue("Failed to add Object", ts.contains(new Integer(-8)));
+ ts.add(objArray[0]);
+ assertTrue("Added existing element", ts.size() == objArray.length + 1);
+
+ }
+
+ /**
+ * java.util.TreeSet#addAll(java.util.Collection)
+ */
+ public void test_addAllLjava_util_Collection() {
+ // Test for method boolean
+ // java.util.TreeSet.addAll(java.util.Collection)
+ TreeSet s = new TreeSet();
+ s.addAll(ts);
+ assertTrue("Incorrect size after add", s.size() == ts.size());
+ Iterator i = ts.iterator();
+ while (i.hasNext())
+ assertTrue("Returned incorrect set", s.contains(i.next()));
+
+ }
+
+ /**
+ * java.util.TreeSet#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.TreeSet.clear()
+ ts.clear();
+ assertEquals("Returned non-zero size after clear", 0, ts.size());
+ assertTrue("Found element in cleared set", !ts.contains(objArray[0]));
+ }
+
+ /**
+ * java.util.TreeSet#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.TreeSet.clone()
+ TreeSet s = (TreeSet) ts.clone();
+ Iterator i = ts.iterator();
+ while (i.hasNext())
+ assertTrue("Clone failed to copy all elements", s
+ .contains(i.next()));
+ }
+
+ /**
+ * java.util.TreeSet#comparator()
+ */
+ public void test_comparator() {
+ // Test for method java.util.Comparator java.util.TreeSet.comparator()
+ ReversedIntegerComparator comp = new ReversedIntegerComparator();
+ TreeSet myTreeSet = new TreeSet(comp);
+ assertTrue("Answered incorrect comparator",
+ myTreeSet.comparator() == comp);
+ }
+
+ /**
+ * java.util.TreeSet#contains(java.lang.Object)
+ */
+ public void test_containsLjava_lang_Object() {
+ // Test for method boolean java.util.TreeSet.contains(java.lang.Object)
+ assertTrue("Returned false for valid Object", ts
+ .contains(objArray[objArray.length / 2]));
+ assertTrue("Returned true for invalid Object", !ts
+ .contains(new Integer(-9)));
+ try {
+ ts.contains(new Object());
+ } catch (ClassCastException e) {
+ // Correct
+ return;
+ }
+ fail("Failed to throw exception when passed invalid element");
+
+ }
+
+ /**
+ * java.util.TreeSet#first()
+ */
+ public void test_first() {
+ // Test for method java.lang.Object java.util.TreeSet.first()
+ assertTrue("Returned incorrect first element",
+ ts.first() == objArray[0]);
+ }
+
+ /**
+ * java.util.TreeSet#headSet(java.lang.Object)
+ */
+ public void test_headSetLjava_lang_Object() {
+ // Test for method java.util.SortedSet
+ // java.util.TreeSet.headSet(java.lang.Object)
+ Set s = ts.headSet(new Integer(100));
+ assertEquals("Returned set of incorrect size", 100, s.size());
+ for (int i = 0; i < 100; i++)
+ assertTrue("Returned incorrect set", s.contains(objArray[i]));
+ }
+
+ /**
+ * java.util.TreeSet#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.TreeSet.isEmpty()
+ assertTrue("Empty set returned false", new TreeSet().isEmpty());
+ assertTrue("Non-Empty returned true", !ts.isEmpty());
+ }
+
+ /**
+ * java.util.TreeSet#iterator()
+ */
+ public void test_iterator() {
+ // Test for method java.util.Iterator java.util.TreeSet.iterator()
+ TreeSet s = new TreeSet();
+ s.addAll(ts);
+ Iterator i = ts.iterator();
+ Set as = new HashSet(Arrays.asList(objArray));
+ while (i.hasNext())
+ as.remove(i.next());
+ assertEquals("Returned incorrect iterator", 0, as.size());
+
+ }
+
+ /**
+ * java.util.TreeSet#last()
+ */
+ public void test_last() {
+ // Test for method java.lang.Object java.util.TreeSet.last()
+ assertTrue("Returned incorrect last element",
+ ts.last() == objArray[objArray.length - 1]);
+ }
+
+ /**
+ * java.util.TreeSet#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method boolean java.util.TreeSet.remove(java.lang.Object)
+ ts.remove(objArray[0]);
+ assertTrue("Failed to remove object", !ts.contains(objArray[0]));
+ assertTrue("Failed to change size after remove",
+ ts.size() == objArray.length - 1);
+ try {
+ ts.remove(new Object());
+ } catch (ClassCastException e) {
+ // Correct
+ return;
+ }
+ fail("Failed to throw exception when past uncomparable value");
+ }
+
+ /**
+ * java.util.TreeSet#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.TreeSet.size()
+ assertTrue("Returned incorrect size", ts.size() == objArray.length);
+ }
+
+ /**
+ * java.util.TreeSet#subSet(java.lang.Object, java.lang.Object)
+ */
+ public void test_subSetLjava_lang_ObjectLjava_lang_Object() {
+ // Test for method java.util.SortedSet
+ // java.util.TreeSet.subSet(java.lang.Object, java.lang.Object)
+ final int startPos = objArray.length / 4;
+ final int endPos = 3 * objArray.length / 4;
+ SortedSet aSubSet = ts.subSet(objArray[startPos], objArray[endPos]);
+ assertTrue("Subset has wrong number of elements",
+ aSubSet.size() == (endPos - startPos));
+ for (int counter = startPos; counter < endPos; counter++)
+ assertTrue("Subset does not contain all the elements it should",
+ aSubSet.contains(objArray[counter]));
+
+ int result;
+ try {
+ ts.subSet(objArray[3], objArray[0]);
+ result = 0;
+ } catch (IllegalArgumentException e) {
+ result = 1;
+ }
+ assertEquals("end less than start should throw", 1, result);
+ }
+
+ /**
+ * java.util.TreeSet#tailSet(java.lang.Object)
+ */
+ public void test_tailSetLjava_lang_Object() {
+ // Test for method java.util.SortedSet
+ // java.util.TreeSet.tailSet(java.lang.Object)
+ Set s = ts.tailSet(new Integer(900));
+ assertEquals("Returned set of incorrect size", 100, s.size());
+ for (int i = 900; i < objArray.length; i++)
+ assertTrue("Returned incorrect set", s.contains(objArray[i]));
+ }
+
+ /**
+ * Tests equals() method.
+ * Tests that no ClassCastException will be thrown in all cases.
+ * Regression test for HARMONY-1639.
+ */
+ public void test_equals() throws Exception {
+ // comparing TreeSets with different object types
+ Set s1 = new TreeSet();
+ Set s2 = new TreeSet();
+ s1.add("key1");
+ s1.add("key2");
+ s2.add(new Integer(1));
+ s2.add(new Integer(2));
+ assertFalse("Sets should not be equal 1", s1.equals(s2));
+ assertFalse("Sets should not be equal 2", s2.equals(s1));
+
+ // comparing TreeSet with HashSet
+ s1 = new TreeSet();
+ s2 = new HashSet();
+ s1.add("key");
+ s2.add(new Object());
+ assertFalse("Sets should not be equal 3", s1.equals(s2));
+ assertFalse("Sets should not be equal 4", s2.equals(s1));
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ ts = new TreeSet();
+ for (int i = 0; i < objArray.length; i++) {
+ Object x = objArray[i] = new Integer(i);
+ ts.add(x);
+ }
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UUIDTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UUIDTest.java
new file mode 100644
index 0000000..a56a2d4
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UUIDTest.java
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.UUID;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import junit.framework.TestCase;
+
+public class UUIDTest extends TestCase {
+
+ /**
+ * @see UUID#UUID(long, long)
+ */
+ public void test_ConstructorJJ() {
+ UUID uuid = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
+ assertEquals(2, uuid.variant());
+ assertEquals(1, uuid.version());
+ assertEquals(0x1d07decf81d4faeL, uuid.timestamp());
+ assertEquals(130742845922168750L, uuid.timestamp());
+ assertEquals(0x2765, uuid.clockSequence());
+ assertEquals(0xA0C91E6BF6L, uuid.node());
+ }
+
+ /**
+ * @see UUID#getLeastSignificantBits()
+ */
+ public void test_getLeastSignificantBits() {
+ UUID uuid = new UUID(0, 0);
+ assertEquals(0, uuid.getLeastSignificantBits());
+ uuid = new UUID(0, Long.MIN_VALUE);
+ assertEquals(Long.MIN_VALUE, uuid.getLeastSignificantBits());
+ uuid = new UUID(0, Long.MAX_VALUE);
+ assertEquals(Long.MAX_VALUE, uuid.getLeastSignificantBits());
+ }
+
+ /**
+ * @see UUID#getMostSignificantBits()
+ */
+ public void test_getMostSignificantBits() {
+ UUID uuid = new UUID(0, 0);
+ assertEquals(0, uuid.getMostSignificantBits());
+ uuid = new UUID(Long.MIN_VALUE, 0);
+ assertEquals(Long.MIN_VALUE, uuid.getMostSignificantBits());
+ uuid = new UUID(Long.MAX_VALUE, 0);
+ assertEquals(Long.MAX_VALUE, uuid.getMostSignificantBits());
+ }
+
+ /**
+ * @see UUID#version()
+ */
+ public void test_version() {
+ UUID uuid = new UUID(0, 0);
+ assertEquals(0, uuid.version());
+ uuid = new UUID(0x0000000000001000L, 0);
+ assertEquals(1, uuid.version());
+ uuid = new UUID(0x0000000000002000L, 0);
+ assertEquals(2, uuid.version());
+ uuid = new UUID(0x0000000000003000L, 0);
+ assertEquals(3, uuid.version());
+ uuid = new UUID(0x0000000000004000L, 0);
+ assertEquals(4, uuid.version());
+ uuid = new UUID(0x0000000000005000L, 0);
+ assertEquals(5, uuid.version());
+ }
+
+ /**
+ * @see UUID#variant()
+ */
+ public void test_variant() {
+ UUID uuid = new UUID(0, 0x0000000000000000L);
+ assertEquals(0, uuid.variant());
+ uuid = new UUID(0, 0x7000000000000000L);
+ assertEquals(0, uuid.variant());
+ uuid = new UUID(0, 0x3000000000000000L);
+ assertEquals(0, uuid.variant());
+ uuid = new UUID(0, 0x1000000000000000L);
+ assertEquals(0, uuid.variant());
+
+ uuid = new UUID(0, 0x8000000000000000L);
+ assertEquals(2, uuid.variant());
+ uuid = new UUID(0, 0xB000000000000000L);
+ assertEquals(2, uuid.variant());
+ uuid = new UUID(0, 0xA000000000000000L);
+ assertEquals(2, uuid.variant());
+ uuid = new UUID(0, 0x9000000000000000L);
+ assertEquals(2, uuid.variant());
+
+ uuid = new UUID(0, 0xC000000000000000L);
+ assertEquals(6, uuid.variant());
+ uuid = new UUID(0, 0xD000000000000000L);
+ assertEquals(6, uuid.variant());
+
+ uuid = new UUID(0, 0xE000000000000000L);
+ assertEquals(7, uuid.variant());
+ uuid = new UUID(0, 0xF000000000000000L);
+ assertEquals(7, uuid.variant());
+ }
+
+ /**
+ * @see UUID#timestamp()
+ */
+ public void test_timestamp() {
+ UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
+ assertEquals(0x0, uuid.timestamp());
+
+ uuid = new UUID(0x7777777755551333L, 0x8000000000000000L);
+ assertEquals(0x333555577777777L, uuid.timestamp());
+
+ uuid = new UUID(0x0000000000000000L, 0x8000000000000000L);
+ try {
+ uuid.timestamp();
+ fail("No UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {}
+
+ uuid = new UUID(0x0000000000002000L, 0x8000000000000000L);
+ try {
+ uuid.timestamp();
+ fail("No UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {}
+ }
+
+ /**
+ * @see UUID#clockSequence()
+ */
+ public void test_clockSequence() {
+ UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
+ assertEquals(0x0, uuid.clockSequence());
+
+ uuid = new UUID(0x0000000000001000L, 0x8FFF000000000000L);
+ assertEquals(0x0FFF, uuid.clockSequence());
+
+ uuid = new UUID(0x0000000000001000L, 0xBFFF000000000000L);
+ assertEquals(0x3FFF, uuid.clockSequence());
+
+ uuid = new UUID(0x0000000000000000L, 0x8000000000000000L);
+ try {
+ uuid.clockSequence();
+ fail("No UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {}
+
+ uuid = new UUID(0x0000000000002000L, 0x8000000000000000L);
+ try {
+ uuid.clockSequence();
+ fail("No UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {}
+ }
+
+ /**
+ * @see UUID#node()
+ */
+ public void test_node() {
+ UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
+ assertEquals(0x0, uuid.node());
+
+ uuid = new UUID(0x0000000000001000L, 0x8000FFFFFFFFFFFFL);
+ assertEquals(0xFFFFFFFFFFFFL, uuid.node());
+
+ uuid = new UUID(0x0000000000000000L, 0x8000000000000000L);
+ try {
+ uuid.node();
+ fail("No UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {}
+
+ uuid = new UUID(0x0000000000002000L, 0x8000000000000000L);
+ try {
+ uuid.node();
+ fail("No UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {}
+ }
+
+ /**
+ * @see UUID#compareTo(UUID)
+ */
+ public void test_compareTo() {
+ UUID uuid1 = new UUID(0, 0);
+ assertEquals(0, uuid1.compareTo(uuid1));
+ UUID uuid2 = new UUID(1, 0);
+ assertEquals(-1, uuid1.compareTo(uuid2));
+ assertEquals(1, uuid2.compareTo(uuid1));
+
+ uuid2 = new UUID(0, 1);
+ assertEquals(-1, uuid1.compareTo(uuid2));
+ assertEquals(1, uuid2.compareTo(uuid1));
+ }
+
+ /**
+ * @see UUID#hashCode()
+ */
+ public void test_hashCode() {
+ UUID uuid = new UUID(0, 0);
+ assertEquals(0, uuid.hashCode());
+ uuid = new UUID(123, 123);
+ UUID uuidClone = new UUID(123, 123);
+ assertEquals(uuid.hashCode(), uuidClone.hashCode());
+ }
+
+ /**
+ * @see UUID#equals(Object)
+ */
+ public void test_equalsObject() {
+ UUID uuid1 = new UUID(0, 0);
+ assertEquals(uuid1, uuid1);
+ assertFalse(uuid1.equals(null));
+ assertFalse(uuid1.equals("NOT A UUID"));
+ UUID uuid2 = new UUID(0, 0);
+ assertEquals(uuid1, uuid2);
+ assertEquals(uuid2, uuid1);
+
+ uuid1 = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
+ uuid2 = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
+ assertEquals(uuid1, uuid2);
+ assertEquals(uuid2, uuid1);
+
+ uuid2 = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf7L);
+ assertFalse(uuid1.equals(uuid2));
+ assertFalse(uuid2.equals(uuid1));
+ }
+
+ /**
+ * @see UUID#toString()
+ */
+ public void test_toString() {
+ UUID uuid = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
+ String actual = uuid.toString();
+ assertEquals("f81d4fae-7dec-11d0-a765-00a0c91e6bf6", actual);
+
+ uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
+ actual = uuid.toString();
+ assertEquals("00000000-0000-1000-8000-000000000000", actual);
+ }
+
+ /**
+ * @tests serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(new UUID(0xf81d4fae7dec11d0L,
+ 0xa76500a0c91e6bf6L));
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ SerializationTest.verifyGolden(this, new UUID(0xf81d4fae7dec11d0L,
+ 0xa76500a0c91e6bf6L));
+ }
+
+ /**
+ * @see UUID#randomUUID()
+ */
+ public void test_randomUUID() {
+ UUID uuid = UUID.randomUUID();
+ assertEquals(2, uuid.variant());
+ assertEquals(4, uuid.version());
+ }
+
+ /**
+ * @see UUID#nameUUIDFromBytes(byte[])
+ */
+ public void test_nameUUIDFromBytes() throws Exception {
+ byte[] name = { (byte) 0x6b, (byte) 0xa7, (byte) 0xb8, (byte) 0x11,
+ (byte) 0x9d, (byte) 0xad, (byte) 0x11, (byte) 0xd1,
+ (byte) 0x80, (byte) 0xb4, (byte) 0x00, (byte) 0xc0,
+ (byte) 0x4f, (byte) 0xd4, (byte) 0x30, (byte) 0xc8 };
+
+ UUID uuid = UUID.nameUUIDFromBytes(name);
+
+ assertEquals(2, uuid.variant());
+ assertEquals(3, uuid.version());
+
+ assertEquals(0xaff565bc2f771745L, uuid.getLeastSignificantBits());
+ assertEquals(0x14cdb9b4de013faaL, uuid.getMostSignificantBits());
+
+ uuid = UUID.nameUUIDFromBytes(new byte[0]);
+ assertEquals(2, uuid.variant());
+ assertEquals(3, uuid.version());
+
+ assertEquals(0xa9800998ecf8427eL, uuid.getLeastSignificantBits());
+ assertEquals(0xd41d8cd98f003204L, uuid.getMostSignificantBits());
+
+ try {
+ UUID.nameUUIDFromBytes(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {}
+ }
+
+ /**
+ * @see UUID#fromString(String)
+ */
+ public void test_fromString() {
+ UUID actual = UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
+ UUID expected = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
+ assertEquals(expected, actual);
+
+ assertEquals(2, actual.variant());
+ assertEquals(1, actual.version());
+ assertEquals(130742845922168750L, actual.timestamp());
+ assertEquals(10085, actual.clockSequence());
+ assertEquals(690568981494L, actual.node());
+
+ actual = UUID.fromString("00000000-0000-1000-8000-000000000000");
+ expected = new UUID(0x0000000000001000L, 0x8000000000000000L);
+ assertEquals(expected, actual);
+
+ assertEquals(2, actual.variant());
+ assertEquals(1, actual.version());
+ assertEquals(0L, actual.timestamp());
+ assertEquals(0, actual.clockSequence());
+ assertEquals(0L, actual.node());
+
+ try {
+ UUID.fromString(null);
+ fail("No NPE");
+ } catch (NullPointerException e) {}
+
+ try {
+ UUID.fromString("");
+ fail("No IAE");
+ } catch (IllegalArgumentException e) {}
+
+ try {
+ UUID.fromString("f81d4fae_7dec-11d0-a765-00a0c91e6bf6");
+ fail("No IAE");
+ } catch (IllegalArgumentException e) {}
+
+ try {
+ UUID.fromString("f81d4fae-7dec_11d0-a765-00a0c91e6bf6");
+ fail("No IAE");
+ } catch (IllegalArgumentException e) {}
+
+ try {
+ UUID.fromString("f81d4fae-7dec-11d0_a765-00a0c91e6bf6");
+ fail("No IAE");
+ } catch (IllegalArgumentException e) {}
+
+ try {
+ UUID.fromString("f81d4fae-7dec-11d0-a765_00a0c91e6bf6");
+ fail("No IAE");
+ } catch (IllegalArgumentException e) {}
+ }
+
+ /**
+ * @tests java.util.UUID#fromString(String)
+ */
+ public void test_fromString_LString_Exception() {
+
+ UUID uuid = UUID.fromString("0-0-0-0-0");
+
+ try {
+ uuid = UUID.fromString("0-0-0-0-");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ uuid = UUID.fromString("-0-0-0-0-0");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ uuid = UUID.fromString("-0-0-0-0");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ uuid = UUID.fromString("-0-0-0-");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ uuid = UUID.fromString("0--0-0-0");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ uuid = UUID.fromString("0-0-0-0-");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ uuid = UUID.fromString("-1-0-0-0-0");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ uuid = UUID.fromString("123456789-0-0-0-0");
+ assertEquals(0x2345678900000000L, uuid.getMostSignificantBits());
+ assertEquals(0x0L, uuid.getLeastSignificantBits());
+
+ uuid = UUID.fromString("111123456789-0-0-0-0");
+ assertEquals(0x2345678900000000L, uuid.getMostSignificantBits());
+ assertEquals(0x0L, uuid.getLeastSignificantBits());
+
+ uuid = UUID.fromString("7fffffffffffffff-0-0-0-0");
+ assertEquals(0xffffffff00000000L, uuid.getMostSignificantBits());
+ assertEquals(0x0L, uuid.getLeastSignificantBits());
+
+ try {
+ uuid = UUID.fromString("8000000000000000-0-0-0-0");
+ fail("should throw NumberFormatException");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ uuid = UUID
+ .fromString("7fffffffffffffff-7fffffffffffffff-7fffffffffffffff-0-0");
+ assertEquals(0xffffffffffffffffL, uuid.getMostSignificantBits());
+ assertEquals(0x0L, uuid.getLeastSignificantBits());
+
+ uuid = UUID.fromString("0-0-0-7fffffffffffffff-7fffffffffffffff");
+ assertEquals(0x0L, uuid.getMostSignificantBits());
+ assertEquals(0xffffffffffffffffL, uuid.getLeastSignificantBits());
+
+ try {
+ uuid = UUID.fromString("0-0-0-8000000000000000-0");
+ fail("should throw NumberFormatException");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+
+ try {
+ uuid = UUID.fromString("0-0-0-0-8000000000000000");
+ fail("should throw NumberFormatException");
+ } catch (NumberFormatException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UnknownFormatConversionExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UnknownFormatConversionExceptionTest.java
new file mode 100644
index 0000000..a265887
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UnknownFormatConversionExceptionTest.java
@@ -0,0 +1,96 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.UnknownFormatConversionException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class UnknownFormatConversionExceptionTest extends TestCase {
+
+ /**
+ * java.util.UnknownFormatConversionException#UnknownFormatConversionException(String)
+ */
+ public void test_unknownFormatConversionException() {
+
+ // RI 5.0 will not throw NullPointerException, it is the bug according
+ // to spec.
+ try {
+ new UnknownFormatConversionException(null);
+ fail("should throw NullPointerExcepiton");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.util.UnknownFormatConversionException#getConversion()
+ */
+ public void test_getConversion() {
+ String s = "MYTESTSTRING";
+ UnknownFormatConversionException UnknownFormatConversionException = new UnknownFormatConversionException(
+ s);
+ assertEquals(s, UnknownFormatConversionException.getConversion());
+ }
+
+ /**
+ * java.util.UnknownFormatConversionException#getMessage()
+ */
+ public void test_getMessage() {
+ String s = "MYTESTSTRING";
+ UnknownFormatConversionException UnknownFormatConversionException = new UnknownFormatConversionException(
+ s);
+ assertTrue(null != UnknownFormatConversionException.getMessage());
+ }
+
+ // comparator for comparing UnknownFormatConversionException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ UnknownFormatConversionException initEx = (UnknownFormatConversionException) initial;
+ UnknownFormatConversionException desrEx = (UnknownFormatConversionException) deserialized;
+
+ assertEquals("Conversion", initEx.getConversion(), desrEx
+ .getConversion());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new UnknownFormatConversionException(
+ "MYTESTSTRING"), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new UnknownFormatConversionException("MYTESTSTRING"),
+ exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UnknownFormatFlagsExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UnknownFormatFlagsExceptionTest.java
new file mode 100644
index 0000000..667ff98
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UnknownFormatFlagsExceptionTest.java
@@ -0,0 +1,94 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.io.Serializable;
+import java.util.UnknownFormatFlagsException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class UnknownFormatFlagsExceptionTest extends TestCase {
+
+ /**
+ * java.util.UnknownFormatFlagsException#UnknownFormatFlagsException(String)
+ */
+ public void test_unknownFormatFlagsException() {
+
+ try {
+ new UnknownFormatFlagsException(null);
+ fail("should throw NullPointerExcepiton");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.UnknownFormatFlagsException#getFlags()
+ */
+ public void test_getFlags() {
+ String s = "MYTESTSTRING";
+ UnknownFormatFlagsException UnknownFormatFlagsException = new UnknownFormatFlagsException(
+ s);
+ assertEquals(s, UnknownFormatFlagsException.getFlags());
+ }
+
+ /**
+ * java.util.UnknownFormatFlagsException#getMessage()
+ */
+ public void test_getMessage() {
+ String s = "MYTESTSTRING";
+ UnknownFormatFlagsException UnknownFormatFlagsException = new UnknownFormatFlagsException(
+ s);
+ assertNotNull(UnknownFormatFlagsException.getMessage());
+ }
+
+ // comparator for comparing UnknownFormatFlagsException objects
+ private static final SerializableAssert exComparator = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+ deserialized);
+
+ UnknownFormatFlagsException initEx = (UnknownFormatFlagsException) initial;
+ UnknownFormatFlagsException desrEx = (UnknownFormatFlagsException) deserialized;
+
+ assertEquals("Flags", initEx.getFlags(), desrEx.getFlags());
+ }
+ };
+
+ /**
+ * serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new UnknownFormatFlagsException(
+ "MYTESTSTRING"), exComparator);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new UnknownFormatFlagsException(
+ "MYTESTSTRING"), exComparator);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java
new file mode 100644
index 0000000..e32ca94
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java
@@ -0,0 +1,1406 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import tests.support.Support_ListTest;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+public class VectorTest extends junit.framework.TestCase {
+
+ private Vector tVector = new Vector();
+
+ Object[] objArray;
+
+ private String vString = "[Test 0, Test 1, Test 2, Test 3, Test 4, Test 5, Test 6, Test 7, Test 8, Test 9, Test 10, Test 11, Test 12, Test 13, Test 14, Test 15, Test 16, Test 17, Test 18, Test 19, Test 20, Test 21, Test 22, Test 23, Test 24, Test 25, Test 26, Test 27, Test 28, Test 29, Test 30, Test 31, Test 32, Test 33, Test 34, Test 35, Test 36, Test 37, Test 38, Test 39, Test 40, Test 41, Test 42, Test 43, Test 44, Test 45, Test 46, Test 47, Test 48, Test 49, Test 50, Test 51, Test 52, Test 53, Test 54, Test 55, Test 56, Test 57, Test 58, Test 59, Test 60, Test 61, Test 62, Test 63, Test 64, Test 65, Test 66, Test 67, Test 68, Test 69, Test 70, Test 71, Test 72, Test 73, Test 74, Test 75, Test 76, Test 77, Test 78, Test 79, Test 80, Test 81, Test 82, Test 83, Test 84, Test 85, Test 86, Test 87, Test 88, Test 89, Test 90, Test 91, Test 92, Test 93, Test 94, Test 95, Test 96, Test 97, Test 98, Test 99]";
+
+ /**
+ * java.util.Vector#Vector()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.Vector()
+
+ Vector tv = new Vector(100);
+ for (int i = 0; i < 100; i++)
+ tv.addElement(new Integer(i));
+ new Support_ListTest("", tv).runTest();
+
+ tv = new Vector(200);
+ for (int i = -50; i < 150; i++)
+ tv.addElement(new Integer(i));
+ new Support_ListTest("", tv.subList(50, 150)).runTest();
+
+ Vector v = new Vector();
+ assertEquals("Vector creation failed", 0, v.size());
+ assertEquals("Wrong capacity", 10, v.capacity());
+ }
+
+ /**
+ * java.util.Vector#Vector(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.Vector(int)
+
+ Vector v = new Vector(100);
+ assertEquals("Vector creation failed", 0, v.size());
+ assertEquals("Wrong capacity", 100, v.capacity());
+
+ try {
+ new Vector(-1);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#Vector(int, int)
+ */
+ public void test_ConstructorII() {
+ // Test for method java.util.Vector(int, int)
+
+ Vector v = new Vector(2, 10);
+ v.addElement(new Object());
+ v.addElement(new Object());
+ v.addElement(new Object());
+
+ assertEquals("Failed to inc capacity by proper amount",
+ 12, v.capacity());
+
+ Vector grow = new Vector(3, -1);
+ grow.addElement("one");
+ grow.addElement("two");
+ grow.addElement("three");
+ grow.addElement("four");
+ assertEquals("Wrong size", 4, grow.size());
+ assertEquals("Wrong capacity", 6, grow.capacity());
+
+ Vector emptyVector = new Vector(0, 0);
+ emptyVector.addElement("one");
+ assertEquals("Wrong size", 1, emptyVector.size());
+ emptyVector.addElement("two");
+ emptyVector.addElement("three");
+ assertEquals("Wrong size", 3, emptyVector.size());
+
+ try {
+ Vector negativeVector = new Vector(-1, 0);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#Vector(java.util.Collection)
+ */
+ public void test_ConstructorLjava_util_Collection() {
+ // Test for method java.util.Vector(java.util.Collection)
+ Collection l = new LinkedList();
+ for (int i = 0; i < 100; i++)
+ l.add("Test " + i);
+ Vector myVector = new Vector(l);
+ assertTrue("Vector is not correct size",
+ myVector.size() == objArray.length);
+ for (int counter = 0; counter < objArray.length; counter++)
+ assertTrue("Vector does not contain correct elements", myVector
+ .contains(((List) l).get(counter)));
+
+ try {
+ new Vector(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#add(int, java.lang.Object)
+ */
+ public void test_addILjava_lang_Object() {
+ // Test for method void java.util.Vector.add(int, java.lang.Object)
+ Object o = new Object();
+ Object prev = tVector.get(45);
+ tVector.add(45, o);
+ assertTrue("Failed to add Object", tVector.get(45) == o);
+ assertTrue("Failed to fix-up existing indices", tVector.get(46) == prev);
+ assertEquals("Wrong size after add", 101, tVector.size());
+
+ prev = tVector.get(50);
+ tVector.add(50, null);
+ assertNull("Failed to add null", tVector.get(50));
+ assertTrue("Failed to fix-up existing indices after adding null",
+ tVector.get(51) == prev);
+ assertEquals("Wrong size after add", 102, tVector.size());
+
+ try {
+ tVector.add(-5, null);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ tVector.add(tVector.size() + 1, null);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#add(java.lang.Object)
+ */
+ public void test_addLjava_lang_Object() {
+ // Test for method boolean java.util.Vector.add(java.lang.Object)
+ Object o = new Object();
+ tVector.add(o);
+ assertTrue("Failed to add Object", tVector.lastElement() == o);
+ assertEquals("Wrong size after add", 101, tVector.size());
+
+ tVector.add(null);
+ assertNull("Failed to add null", tVector.lastElement());
+ assertEquals("Wrong size after add", 102, tVector.size());
+ }
+
+ /**
+ * java.util.Vector#addAll(int, java.util.Collection)
+ */
+ public void test_addAllILjava_util_Collection() {
+ // Test for method boolean java.util.Vector.addAll(int,
+ // java.util.Collection)
+ Collection l = new LinkedList();
+ for (int i = 0; i < 100; i++)
+ l.add("Test " + i);
+ Vector v = new Vector();
+ tVector.addAll(50, l);
+ for (int i = 50; i < 100; i++)
+ assertTrue("Failed to add all elements",
+ tVector.get(i) == ((List) l).get(i - 50));
+ v = new Vector();
+ v.add("one");
+ int r = 0;
+ try {
+ v.addAll(3, Arrays.asList(new String[] { "two", "three" }));
+ } catch (ArrayIndexOutOfBoundsException e) {
+ r = 1;
+ } catch (IndexOutOfBoundsException e) {
+ r = 2;
+ }
+ assertTrue("Invalid add: " + r, r == 1);
+ l = new LinkedList();
+ l.add(null);
+ l.add("gah");
+ l.add(null);
+ tVector.addAll(50, l);
+ assertNull("Wrong element at position 50--wanted null",
+ tVector.get(50));
+ assertEquals("Wrong element at position 51--wanted 'gah'", "gah", tVector
+ .get(51));
+ assertNull("Wrong element at position 52--wanted null",
+ tVector.get(52));
+
+ try {
+ tVector.addAll(-5, Arrays.asList(new String[] { "two", "three" }));
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ tVector.addAll(tVector.size() + 1, Arrays.asList(new String[] { "two", "three" }));
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ tVector.addAll(tVector.size() / 2, null);
+ fail("NullPointerException expected");
+ } catch(NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#addAll(java.util.Collection)
+ */
+ public void test_addAllLjava_util_Collection() {
+ // Test for method boolean java.util.Vector.addAll(java.util.Collection)
+ Vector v = new Vector();
+ Collection l = new LinkedList();
+ for (int i = 0; i < 100; i++)
+ l.add("Test " + i);
+ v.addAll(l);
+ assertTrue("Failed to add all elements", tVector.equals(v));
+
+ v.addAll(l);
+ int vSize = tVector.size();
+ for (int counter = vSize - 1; counter >= 0; counter--)
+ assertTrue("Failed to add elements correctly", v.get(counter) == v
+ .get(counter + vSize));
+
+ l = new LinkedList();
+ l.add(null);
+ l.add("gah");
+ l.add(null);
+ tVector.addAll(l);
+ assertNull("Wrong element at 3rd last position--wanted null", tVector
+ .get(vSize));
+ assertEquals("Wrong element at 2nd last position--wanted 'gah'", "gah", tVector
+ .get(vSize + 1));
+ assertNull("Wrong element at last position--wanted null", tVector
+ .get(vSize + 2));
+
+ try {
+ tVector.addAll(tVector.size() / 2, null);
+ fail("NullPointerException expected");
+ } catch(NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#addElement(java.lang.Object)
+ */
+ public void test_addElementLjava_lang_Object() {
+ // Test for method void java.util.Vector.addElement(java.lang.Object)
+ Vector v = vectorClone(tVector);
+ v.addElement("Added Element");
+ assertTrue("Failed to add element", v.contains("Added Element"));
+ assertEquals("Added Element to wrong slot", "Added Element", ((String) v.elementAt(100))
+ );
+ v.addElement(null);
+ assertTrue("Failed to add null", v.contains(null));
+ assertNull("Added null to wrong slot", v.elementAt(101));
+ }
+
+ /**
+ * java.util.Vector#addElement(java.lang.Object)
+ */
+ public void test_addElementLjava_lang_Object_subtest0() {
+ // Test for method void java.util.Vector.addElement(java.lang.Object)
+ Vector v = vectorClone(tVector);
+ v.addElement("Added Element");
+ assertTrue("Failed to add element", v.contains("Added Element"));
+ assertEquals("Added Element to wrong slot", "Added Element", ((String) v.elementAt(100))
+ );
+ v.addElement(null);
+ assertTrue("Failed to add null", v.contains(null));
+ assertNull("Added null to wrong slot", v.elementAt(101));
+ }
+
+ /**
+ * java.util.Vector#capacity()
+ */
+ public void test_capacity() {
+ // Test for method int java.util.Vector.capacity()
+
+ Vector v = new Vector(9);
+ assertEquals("Incorrect capacity returned", 9, v.capacity());
+ }
+
+ /**
+ * java.util.Vector#clear()
+ */
+ public void test_clear() {
+ // Test for method void java.util.Vector.clear()
+ Vector orgVector = vectorClone(tVector);
+ tVector.clear();
+ assertEquals("a) Cleared Vector has non-zero size", 0, tVector.size());
+ Enumeration e = orgVector.elements();
+ while (e.hasMoreElements())
+ assertTrue("a) Cleared vector contained elements", !tVector
+ .contains(e.nextElement()));
+
+ tVector.add(null);
+ tVector.clear();
+ assertEquals("b) Cleared Vector has non-zero size", 0, tVector.size());
+ e = orgVector.elements();
+ while (e.hasMoreElements())
+ assertTrue("b) Cleared vector contained elements", !tVector
+ .contains(e.nextElement()));
+ }
+
+ /**
+ * java.util.Vector#clone()
+ */
+ public void test_clone() {
+ // Test for method java.lang.Object java.util.Vector.clone()
+ tVector.add(25, null);
+ tVector.add(75, null);
+ Vector v = (Vector) tVector.clone();
+ Enumeration orgNum = tVector.elements();
+ Enumeration cnum = v.elements();
+
+ while (orgNum.hasMoreElements()) {
+ assertTrue("Not enough elements copied", cnum.hasMoreElements());
+ assertTrue("Vector cloned improperly, elements do not match",
+ orgNum.nextElement() == cnum.nextElement());
+ }
+ assertTrue("Not enough elements copied", !cnum.hasMoreElements());
+
+ }
+
+ /**
+ * java.util.Vector#contains(java.lang.Object)
+ */
+ public void test_containsLjava_lang_Object() {
+ // Test for method boolean java.util.Vector.contains(java.lang.Object)
+ assertTrue("Did not find element", tVector.contains("Test 42"));
+ assertTrue("Found bogus element", !tVector.contains("Hello"));
+ assertTrue(
+ "Returned true looking for null in vector without null element",
+ !tVector.contains(null));
+ tVector.insertElementAt(null, 20);
+ assertTrue(
+ "Returned false looking for null in vector with null element",
+ tVector.contains(null));
+ }
+
+ /**
+ * java.util.Vector#containsAll(java.util.Collection)
+ */
+ public void test_containsAllLjava_util_Collection() {
+ // Test for method boolean
+ // java.util.Vector.containsAll(java.util.Collection)
+ Collection s = new HashSet();
+ for (int i = 0; i < 100; i++)
+ s.add("Test " + i);
+
+ assertTrue("Returned false for valid collection", tVector
+ .containsAll(s));
+ s.add(null);
+ assertTrue("Returned true for invlaid collection containing null",
+ !tVector.containsAll(s));
+ tVector.add(25, null);
+ assertTrue("Returned false for valid collection containing null",
+ tVector.containsAll(s));
+ s = new HashSet();
+ s.add(new Object());
+ assertTrue("Returned true for invalid collection", !tVector
+ .containsAll(s));
+
+ try {
+ tVector.containsAll(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#copyInto(java.lang.Object[])
+ */
+ public void test_copyInto$Ljava_lang_Object() {
+ // Test for method void java.util.Vector.copyInto(java.lang.Object [])
+
+ Object[] a = new Object[100];
+ tVector.setElementAt(null, 20);
+ tVector.copyInto(a);
+
+ for (int i = 0; i < 100; i++)
+ assertTrue("copyInto failed", a[i] == tVector.elementAt(i));
+
+ try {
+ tVector.copyInto(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#elementAt(int)
+ */
+ public void test_elementAtI() {
+ // Test for method java.lang.Object java.util.Vector.elementAt(int)
+ assertEquals("Incorrect element returned", "Test 18", ((String) tVector
+ .elementAt(18)));
+ tVector.setElementAt(null, 20);
+ assertNull("Incorrect element returned--wanted null", tVector
+ .elementAt(20));
+
+ try {
+ tVector.elementAt(-5);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ tVector.elementAt(tVector.size() + 1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#elements()
+ */
+ public void test_elements() {
+ // Test for method java.util.Enumeration java.util.Vector.elements()
+ tVector.insertElementAt(null, 20);
+ Enumeration e = tVector.elements();
+ int i = 0;
+ while (e.hasMoreElements()) {
+ assertTrue("Enumeration returned incorrect element at pos: " + i, e
+ .nextElement() == tVector.elementAt(i));
+ i++;
+ }
+ assertTrue("Invalid enumeration", i == tVector.size());
+ }
+
+ /**
+ * java.util.Vector#elements()
+ */
+ public void test_elements_subtest0() {
+ final int iterations = 10000;
+ final Vector v = new Vector();
+ Thread t1 = new Thread() {
+ public void run() {
+ for (int i = 0; i < iterations; i++) {
+ synchronized (v) {
+ v.addElement(String.valueOf(i));
+ v.removeElementAt(0);
+ }
+ }
+ }
+ };
+ t1.start();
+ for (int i = 0; i < iterations; i++) {
+ Enumeration en = v.elements();
+ try {
+ while (true) {
+ Object result = en.nextElement();
+ if (result == null) {
+ fail("Null result: " + i);
+ }
+ }
+ } catch (NoSuchElementException e) {
+ }
+ }
+ }
+
+ /**
+ * java.util.Vector#ensureCapacity(int)
+ */
+ public void test_ensureCapacityI() {
+ // Test for method void java.util.Vector.ensureCapacity(int)
+
+ Vector v = new Vector(9);
+ v.ensureCapacity(20);
+ assertEquals("ensureCapacity failed to set correct capacity", 20, v
+ .capacity());
+ v = new Vector(100);
+ assertEquals("ensureCapacity reduced capacity", 100, v.capacity());
+
+ v.ensureCapacity(150);
+ assertEquals(
+ "ensuieCapacity failed to set to be twice the old capacity",
+ 200, v.capacity());
+
+ v = new Vector(9, -1);
+ v.ensureCapacity(20);
+ assertEquals("ensureCapacity failed to set to be minCapacity", 20, v
+ .capacity());
+ v.ensureCapacity(15);
+ assertEquals("ensureCapacity reduced capacity", 20, v.capacity());
+ v.ensureCapacity(35);
+ assertEquals(
+ "ensuieCapacity failed to set to be twice the old capacity",
+ 40, v.capacity());
+
+ v = new Vector(9, 4);
+ v.ensureCapacity(11);
+ assertEquals("ensureCapacity failed to set correct capacity", 13, v
+ .capacity());
+ v.ensureCapacity(5);
+ assertEquals("ensureCapacity reduced capacity", 13, v.capacity());
+ v.ensureCapacity(20);
+ assertEquals(
+ "ensureCapacity failed to set to be twice the old capacity",
+ 20, v.capacity());
+ }
+
+ /**
+ * java.util.Vector#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ // Test for method boolean java.util.Vector.equals(java.lang.Object)
+ Vector v = new Vector();
+ for (int i = 0; i < 100; i++)
+ v.addElement("Test " + i);
+ assertTrue("a) Equal vectors returned false", tVector.equals(v));
+ v.addElement(null);
+ assertTrue("b) UnEqual vectors returned true", !tVector.equals(v));
+ tVector.addElement(null);
+ assertTrue("c) Equal vectors returned false", tVector.equals(v));
+ tVector.removeElementAt(22);
+ assertTrue("d) UnEqual vectors returned true", !tVector.equals(v));
+ assertTrue("e) Equal vectors returned false", tVector.equals(tVector));
+ assertFalse("f) UnEqual vectors returned true", tVector
+ .equals(new Object()));
+ assertFalse("g) Unequal vectors returned true", tVector.equals(null));
+ }
+
+ /**
+ * java.util.Vector#firstElement()
+ */
+ public void test_firstElement() {
+ // Test for method java.lang.Object java.util.Vector.firstElement()
+ assertEquals("Returned incorrect firstElement", "Test 0", tVector.firstElement()
+ );
+ tVector.insertElementAt(null, 0);
+ assertNull("Returned incorrect firstElement--wanted null", tVector
+ .firstElement());
+
+ Vector v = new Vector(10);
+ try {
+ v.firstElement();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#get(int)
+ */
+ public void test_getI() {
+ // Test for method java.lang.Object java.util.Vector.get(int)
+ assertEquals("Get returned incorrect object",
+ "Test 80", tVector.get(80));
+ tVector.add(25, null);
+ assertNull("Returned incorrect element--wanted null",
+ tVector.get(25));
+
+ try {
+ tVector.get(-5);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+
+ try {
+ tVector.get(tVector.size() + 1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#hashCode()
+ */
+ public void test_hashCode() {
+ // Test for method int java.util.Vector.hashCode()
+ int hashCode = 1; // one
+ tVector.insertElementAt(null, 20);
+ for (int i = 0; i < tVector.size(); i++) {
+ Object obj = tVector.elementAt(i);
+ hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
+ }
+ assertTrue("Incorrect hashCode returned. Wanted: " + hashCode
+ + " got: " + tVector.hashCode(), tVector.hashCode() == hashCode);
+ }
+
+ /**
+ * java.util.Vector#indexOf(java.lang.Object)
+ */
+ public void test_indexOfLjava_lang_Object() {
+ // Test for method int java.util.Vector.indexOf(java.lang.Object)
+ assertEquals("Incorrect index returned", 10, tVector.indexOf("Test 10"));
+ assertEquals("Index returned for invalid Object", -1, tVector
+ .indexOf("XXXXXXXXXXX"));
+ tVector.setElementAt(null, 20);
+ tVector.setElementAt(null, 40);
+ assertTrue("Incorrect indexOf returned for null: "
+ + tVector.indexOf(null), tVector.indexOf(null) == 20);
+ }
+
+ /**
+ * java.util.Vector#indexOf(java.lang.Object, int)
+ */
+ public void test_indexOfLjava_lang_ObjectI() {
+ // Test for method int java.util.Vector.indexOf(java.lang.Object, int)
+ assertEquals("Failed to find correct index", tVector.indexOf("Test 98",
+ 50), 98);
+ assertTrue("Found index of bogus element", (tVector.indexOf(
+ "Test 1001", 50) == -1));
+ tVector.setElementAt(null, 20);
+ tVector.setElementAt(null, 40);
+ tVector.setElementAt(null, 60);
+ assertTrue("a) Incorrect indexOf returned for null: "
+ + tVector.indexOf(null, 25), tVector.indexOf(null, 25) == 40);
+ assertTrue("b) Incorrect indexOf returned for null: "
+ + tVector.indexOf(null, 20), tVector.indexOf(null, 20) == 20);
+ try {
+ tVector.indexOf("Test 98", -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+
+ }
+ assertEquals(-1, tVector.indexOf("Test 98", 1000));
+ assertEquals(-1, tVector.indexOf("Test 98", Integer.MAX_VALUE));
+ assertEquals(-1, tVector.indexOf("Test 98", tVector.size()));
+ assertEquals(98, tVector.indexOf("Test 98", 0));
+ try {
+ tVector.indexOf("Test 98", Integer.MIN_VALUE);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+
+ }
+ }
+
+ /**
+ * java.util.Vector#insertElementAt(java.lang.Object, int)
+ */
+ public void test_insertElementAtLjava_lang_ObjectI() {
+ // Test for method void
+ // java.util.Vector.insertElementAt(java.lang.Object, int)
+ Vector v = vectorClone(tVector);
+ String prevElement = (String) v.elementAt(99);
+ v.insertElementAt("Inserted Element", 99);
+ assertEquals("Element not inserted", "Inserted Element", ((String) v.elementAt(99))
+ );
+ assertTrue("Elements shifted incorrectly", ((String) v.elementAt(100))
+ .equals(prevElement));
+ v.insertElementAt(null, 20);
+ assertNull("null not inserted", v.elementAt(20));
+
+ try {
+ tVector.insertElementAt("Inserted Element", -1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ tVector.insertElementAt(null, -1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ tVector.insertElementAt("Inserted Element", tVector.size() + 1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ tVector.insertElementAt(null, tVector.size() + 1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.Vector.isEmpty()Vector
+ Vector v = new java.util.Vector();
+ assertTrue("Empty vector returned false", v.isEmpty());
+ v.addElement(new Object());
+ assertTrue("non-Empty vector returned true", !v.isEmpty());
+ }
+
+ /**
+ * java.util.Vector#isEmpty()
+ */
+ public void test_isEmpty_subtest0() {
+ final Vector v = new Vector();
+ v.addElement("initial");
+ Thread t1 = new Thread() {
+ public void run() {
+ while (!v.isEmpty())
+ ;
+ v.addElement("final");
+ }
+ };
+ t1.start();
+ for (int i = 0; i < 10000; i++) {
+ synchronized (v) {
+ v.removeElementAt(0);
+ v.addElement(String.valueOf(i));
+ }
+ int size;
+ if ((size = v.size()) != 1) {
+ String result = "Size is not 1: " + size + " " + v;
+ // terminate the thread
+ v.removeAllElements();
+ fail(result);
+ }
+ }
+ // terminate the thread
+ v.removeElementAt(0);
+ }
+
+ /**
+ * java.util.Vector#lastElement()
+ */
+ public void test_lastElement() {
+ // Test for method java.lang.Object java.util.Vector.lastElement()
+ assertEquals("Incorrect last element returned", "Test 99", tVector.lastElement()
+ );
+ tVector.addElement(null);
+ assertNull("Incorrect last element returned--wanted null", tVector
+ .lastElement());
+
+ Vector vector = new Vector();
+ try {
+ vector.lastElement();
+ fail("Should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#lastIndexOf(java.lang.Object)
+ */
+ public void test_lastIndexOfLjava_lang_Object() {
+ // Test for method int java.util.Vector.lastIndexOf(java.lang.Object)
+ Vector v = new Vector(9);
+ for (int i = 0; i < 9; i++)
+ v.addElement("Test");
+ v.addElement("z");
+ assertEquals("Failed to return correct index", 8, v.lastIndexOf("Test"));
+ tVector.setElementAt(null, 20);
+ tVector.setElementAt(null, 40);
+ assertTrue("Incorrect lastIndexOf returned for null: "
+ + tVector.lastIndexOf(null), tVector.lastIndexOf(null) == 40);
+ }
+
+ /**
+ * java.util.Vector#lastIndexOf(java.lang.Object, int)
+ */
+ public void test_lastIndexOfLjava_lang_ObjectI() {
+ // Test for method int java.util.Vector.lastIndexOf(java.lang.Object,
+ // int)
+ assertEquals("Failed to find object",
+ 0, tVector.lastIndexOf("Test 0", 0));
+ assertTrue("Found Object outside of index", (tVector.lastIndexOf(
+ "Test 0", 10) > -1));
+ tVector.setElementAt(null, 20);
+ tVector.setElementAt(null, 40);
+ tVector.setElementAt(null, 60);
+ assertTrue("Incorrect lastIndexOf returned for null: "
+ + tVector.lastIndexOf(null, 15),
+ tVector.lastIndexOf(null, 15) == -1);
+ assertTrue("Incorrect lastIndexOf returned for null: "
+ + tVector.lastIndexOf(null, 45),
+ tVector.lastIndexOf(null, 45) == 40);
+
+ assertEquals(-1, tVector.lastIndexOf("Test 98", -1));
+ assertEquals(-1, tVector.lastIndexOf("Test 98", 0));
+ try {
+ assertEquals(-1, tVector.lastIndexOf("Test 98", 1000));
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ try {
+ assertEquals(-1, tVector.lastIndexOf("Test 98", Integer.MAX_VALUE));
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ try {
+ tVector.lastIndexOf("Test 98", tVector.size());
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ try {
+ tVector.indexOf("Test 98", Integer.MIN_VALUE);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ }
+
+ /**
+ * java.util.Vector#remove(int)
+ */
+ public void test_removeI() {
+ // Test for method java.lang.Object java.util.Vector.remove(int)
+ Object removeElement = tVector.get(36);
+ Object result = tVector.remove(36);
+ assertFalse("Contained element after remove", tVector
+ .contains("Test 36"));
+ assertEquals("Should return the element that was removed",
+ removeElement, result);
+ assertEquals("Failed to decrement size after remove",
+ 99, tVector.size());
+ tVector.add(20, null);
+ removeElement = tVector.get(19);
+ result = tVector.remove(19);
+ assertNull("Didn't move null element over", tVector.get(19));
+ assertEquals("Should return the element that was removed",
+ removeElement, result);
+ removeElement = tVector.get(19);
+ result = tVector.remove(19);
+ assertNotNull("Didn't remove null element", tVector.get(19));
+ assertEquals("Should return the element that was removed",
+ removeElement, result);
+ assertEquals("Failed to decrement size after removing null", 98, tVector
+ .size());
+
+ try {
+ tVector.remove(-1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ tVector.remove(tVector.size());
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method boolean java.util.Vector.remove(java.lang.Object)
+ tVector.remove("Test 0");
+ assertTrue("Contained element after remove", !tVector
+ .contains("Test 0"));
+ assertEquals("Failed to decrement size after remove",
+ 99, tVector.size());
+ tVector.add(null);
+ tVector.remove(null);
+ assertTrue("Contained null after remove", !tVector.contains(null));
+ assertEquals("Failed to decrement size after removing null", 99, tVector
+ .size());
+ }
+
+ /**
+ * java.util.Vector#removeAll(java.util.Collection)
+ */
+ public void test_removeAllLjava_util_Collection() {
+ // Test for method boolean
+ // java.util.Vector.removeAll(java.util.Collection)
+ Vector v = new Vector();
+ Collection l = new LinkedList();
+ for (int i = 0; i < 5; i++)
+ l.add("Test " + i);
+ v.addElement(l);
+
+ Collection s = new HashSet();
+ Object o;
+ s.add(o = v.firstElement());
+ v.removeAll(s);
+ assertTrue("Failed to remove items in collection", !v.contains(o));
+ v.removeAll(l);
+ assertTrue("Failed to remove all elements", v.isEmpty());
+
+ v.add(null);
+ v.add(null);
+ v.add("Boom");
+ v.removeAll(s);
+ assertEquals("Should not have removed any elements", 3, v.size());
+ l = new LinkedList();
+ l.add(null);
+ v.removeAll(l);
+ assertEquals("Should only have one element", 1, v.size());
+ assertEquals("Element should be 'Boom'", "Boom", v.firstElement());
+
+ try {
+ v.removeAll(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.Vector#removeAllElements()
+ */
+ public void test_removeAllElements() {
+ // Test for method void java.util.Vector.removeAllElements()
+ Vector v = vectorClone(tVector);
+ v.removeAllElements();
+ assertEquals("Failed to remove all elements", 0, v.size());
+ }
+
+ /**
+ * java.util.Vector#removeElement(java.lang.Object)
+ */
+ public void test_removeElementLjava_lang_Object() {
+ // Test for method boolean
+ // java.util.Vector.removeElement(java.lang.Object)
+ Vector v = vectorClone(tVector);
+ v.removeElement("Test 98");
+ assertEquals("Element not removed", "Test 99", ((String) v.elementAt(98))
+ );
+ assertTrue("Vector is wrong size after removal: " + v.size(),
+ v.size() == 99);
+ tVector.addElement(null);
+ v.removeElement(null);
+ assertTrue("Vector is wrong size after removing null: " + v.size(), v
+ .size() == 99);
+ }
+
+ /**
+ * java.util.Vector#removeElementAt(int)
+ */
+ public void test_removeElementAtI() {
+ // Test for method void java.util.Vector.removeElementAt(int)
+ Vector v = vectorClone(tVector);
+ int size = v.size();
+ v.removeElementAt(50);
+ assertEquals("Failed to remove element", -1, v.indexOf("Test 50", 0));
+ assertEquals("Test 51", v.get(50));
+ assertEquals(size - 1, v.size());
+
+ tVector.insertElementAt(null, 60);
+ assertNull(tVector.get(60));
+ size = tVector.size();
+ tVector.removeElementAt(60);
+ assertNotNull("Element at 60 should not be null after removal", tVector
+ .elementAt(60));
+ assertEquals(size - 1, tVector.size());
+
+ try {
+ tVector.removeElementAt(-1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ tVector.removeElementAt(tVector.size());
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * {@link java.util.Vector#removeRange(int, int)}
+ */
+ public void test_removeRange() {
+ MockVector myVector = new MockVector();
+ myVector.removeRange(0, 0);
+
+ try {
+ myVector.removeRange(0, 1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ int[] data = { 1, 2, 3, 4 };
+ for (int i = 0; i < data.length; i++) {
+ myVector.add(i, data[i]);
+ }
+
+ myVector.removeRange(0, 2);
+ assertEquals(data[2], myVector.get(0));
+ assertEquals(data[3], myVector.get(1));
+
+ try {
+ myVector.removeRange(-1, 1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ myVector.removeRange(0, -1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ myVector.removeRange(1, 0);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ myVector.removeRange(2, 1);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#retainAll(java.util.Collection)
+ */
+ public void test_retainAllLjava_util_Collection() {
+ // Test for method boolean
+ // java.util.Vector.retainAll(java.util.Collection)
+ Object o = tVector.firstElement();
+ tVector.add(null);
+ Collection s = new HashSet();
+ s.add(o);
+ s.add(null);
+ tVector.retainAll(s);
+ assertTrue("Retained items other than specified", tVector.size() == 2
+ && tVector.contains(o) && tVector.contains(null));
+ }
+
+ /**
+ * java.util.Vector#set(int, java.lang.Object)
+ */
+ public void test_setILjava_lang_Object() {
+ // Test for method java.lang.Object java.util.Vector.set(int,
+ // java.lang.Object)
+ Object o = new Object();
+ Object previous = tVector.get(23);
+ Object result = tVector.set(23, o);
+ assertEquals(
+ "Should return the element previously at the specified position",
+ previous, result);
+ assertTrue("Failed to set Object", tVector.get(23) == o);
+
+ previous = tVector.get(0);
+ result = tVector.set(0, null);
+ assertEquals(
+ "Should return the element previously at the specified position",
+ previous, result);
+ assertNull("Failed to set Object", tVector.get(0));
+
+ try {
+ tVector.set(-1, o);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ tVector.set(-1, null);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ tVector.set(tVector.size(), o);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ tVector.set(tVector.size(), null);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#setElementAt(java.lang.Object, int)
+ */
+ public void test_setElementAtLjava_lang_ObjectI() {
+ // Test for method void java.util.Vector.setElementAt(java.lang.Object,
+ // int)
+ Vector v = vectorClone(tVector);
+ v.setElementAt("Inserted Element", 99);
+ assertEquals("Element not set", "Inserted Element", ((String) v.elementAt(99))
+ );
+
+ v.setElementAt(null, 0);
+ assertNull("Null element not set", v.elementAt(0));
+
+ try {
+ v.setElementAt("Inserted Element", -1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ v.setElementAt(null, -1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ v.setElementAt("Inserted Element", v.size());
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+
+ try {
+ v.setElementAt(null, v.size());
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#setSize(int)
+ */
+ public void test_setSizeI() {
+ // Test for method void java.util.Vector.setSize(int)
+ Vector v = vectorClone(tVector);
+ int oldSize = v.size();
+ Object preElement = v.get(10);
+ v.setSize(10);
+ assertEquals("Failed to set size", 10, v.size());
+ assertEquals(
+ "All components at index newSize and greater should be discarded",
+ -1, v.indexOf(preElement));
+ try {
+ v.get(oldSize - 1);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted;
+ }
+
+ oldSize = v.size();
+ v.setSize(20);
+ assertEquals("Failed to set size", 20, v.size());
+ for (int i = oldSize; i < v.size(); i++) {
+ assertNull(v.get(i));
+ }
+
+ try {
+ v.setSize(-1);
+ fail("Should throw ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Excepted
+ }
+ }
+
+ /**
+ * java.util.Vector#size()
+ */
+ public void test_size() {
+ // Test for method int java.util.Vector.size()
+ assertEquals("Returned incorrect size", 100, tVector.size());
+
+ final Vector v = new Vector();
+ v.addElement("initial");
+ Thread t1 = new Thread() {
+ public void run() {
+ while (v.size() > 0)
+ ;
+ v.addElement("final");
+ }
+ };
+ t1.start();
+ for (int i = 0; i < 10000; i++) {
+ synchronized (v) {
+ v.removeElementAt(0);
+ v.addElement(String.valueOf(i));
+ }
+ int size;
+ if ((size = v.size()) != 1) {
+ String result = "Size is not 1: " + size + " " + v;
+ // terminate the thread
+ v.removeAllElements();
+ fail(result);
+ }
+ }
+ // terminate the thread
+ v.removeElementAt(0);
+ }
+
+ /**
+ * java.util.Vector#subList(int, int)
+ */
+ public void test_subListII() {
+ // Test for method java.util.List java.util.Vector.subList(int, int)
+ List sl = tVector.subList(10, 25);
+ assertEquals("Returned sublist of incorrect size", 15, sl.size());
+ for (int i = 10; i < 25; i++)
+ assertTrue("Returned incorrect sublist", sl
+ .contains(tVector.get(i)));
+
+ assertEquals("Not synchronized random access", "java.util.Collections$SynchronizedRandomAccessList", sl.getClass().getName()
+ );
+
+ }
+
+ /**
+ * java.util.Vector#toArray()
+ */
+ public void test_toArray() {
+ // Test for method java.lang.Object [] java.util.Vector.toArray()
+ assertTrue("Returned incorrect array", Arrays.equals(objArray, tVector
+ .toArray()));
+ }
+
+ /**
+ * java.util.Vector#toArray(java.lang.Object[])
+ */
+ public void test_toArray$Ljava_lang_Object() {
+ // Test for method java.lang.Object []
+ // java.util.Vector.toArray(java.lang.Object [])
+ Object[] o = new Object[1000];
+ Object f = new Object();
+ for (int i = 0; i < o.length; i++)
+ o[i] = f;
+ tVector.toArray(o);
+ assertNull("Failed to set slot to null", o[100]);
+ for (int i = 0; i < tVector.size(); i++)
+ assertTrue("Returned incorrect array", tVector.elementAt(i) == o[i]);
+ }
+
+
+ class SubVector<E> extends Vector<E> {
+
+ private static final long serialVersionUID = 1L;
+
+ public SubVector() {
+ super();
+ }
+
+ public synchronized boolean add(E obj) {
+ super.addElement(obj);
+ return true;
+ }
+
+ public synchronized void addElement(E obj) {
+ super.add(obj);
+ }
+
+ /**
+ * java.util.Vector#add(Object)
+ */
+ @SuppressWarnings("nls")
+ public void test_add() {
+ SubVector<String> subvector = new SubVector<String>();
+ subvector.add("foo");
+ subvector.addElement("bar");
+ assertEquals("Expected two elements in vector", 2, subvector.size());
+ }
+
+ }
+
+ /**
+ * java.util.Vector#toString()
+ */
+ public void test_toString() {
+ // Ensure toString works with self-referencing elements.
+ Vector<Object> vec = new Vector<Object>(3);
+ vec.add(null);
+ vec.add(new Object());
+ vec.add(vec);
+ assertNotNull(vec.toString());
+
+ // Test for method java.lang.String java.util.Vector.toString()
+ assertTrue("Incorrect String returned", tVector.toString().equals(
+ vString));
+
+ Vector v = new Vector();
+ v.addElement("one");
+ v.addElement(v);
+ v.addElement("3");
+ // test last element
+ v.addElement(v);
+ String result = v.toString();
+ assertTrue("should contain self ref", result.indexOf("(this") > -1);
+ }
+
+ public void test_override_size() throws Exception {
+ Vector v = new Vector();
+ Vector testv = new MockVector();
+ // though size is overriden, it should passed without exception
+ testv.add(1);
+ testv.add(2);
+ testv.clear();
+
+ testv.add(1);
+ testv.add(2);
+ v.add(1);
+ v.add(2);
+ // RI's bug here
+ assertTrue(testv.equals(v));
+ }
+
+ /**
+ * java.util.Vector#trimToSize()
+ */
+ public void test_trimToSize() {
+ // Test for method void java.util.Vector.trimToSize()
+ Vector v = new Vector(10);
+ v.addElement(new Object());
+ v.trimToSize();
+ assertEquals("Failed to trim capacity", 1, v.capacity());
+ }
+
+ public void test_removeRangeII() {
+ MockVector mv = new MockVector();
+ mv.add("First");
+ mv.add("Second");
+ mv.add("One more");
+ mv.add("Last");
+ mv.removeRange(1, 3);
+ assertTrue(mv.contains("First"));
+ assertFalse(mv.contains("Second"));
+ assertFalse(mv.contains("One more"));
+ assertTrue(mv.contains("Last"));
+ }
+
+ protected Vector vectorClone(Vector s) {
+ return (Vector) s.clone();
+ }
+
+ public class MockVector extends Vector {
+ @Override
+ public synchronized int size() {
+ return 0;
+ }
+
+ public void removeRange(int start, int end) {
+ super.removeRange(start, end);
+ }
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ for (int i = 0; i < 100; i++) {
+ tVector.addElement("Test " + i);
+ }
+ objArray = new Object[100];
+ for (int i = 0; i < 100; i++) {
+ objArray[i] = "Test " + i;
+ }
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/WeakHashMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/WeakHashMapTest.java
new file mode 100644
index 0000000..1d5294f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/WeakHashMapTest.java
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import libcore.java.lang.ref.FinalizationTester;
+
+import tests.support.Support_MapTest2;
+
+public class WeakHashMapTest extends junit.framework.TestCase {
+ class MockMap extends AbstractMap {
+ public Set entrySet() {
+ return null;
+ }
+
+ public int size() {
+ return 0;
+ }
+ }
+
+ Object[] keyArray = new Object[100];
+
+ Object[] valueArray = new Object[100];
+
+ WeakHashMap whm;
+
+ /**
+ * java.util.WeakHashMap#WeakHashMap()
+ */
+ public void test_Constructor() {
+ // Test for method java.util.WeakHashMap()
+ new Support_MapTest2(new WeakHashMap()).runTest();
+
+ whm = new WeakHashMap();
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+ for (int i = 0; i < 100; i++)
+ assertTrue("Incorrect value retrieved",
+ whm.get(keyArray[i]) == valueArray[i]);
+
+ }
+
+ /**
+ * java.util.WeakHashMap#WeakHashMap(int)
+ */
+ public void test_ConstructorI() {
+ // Test for method java.util.WeakHashMap(int)
+ whm = new WeakHashMap(50);
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+ for (int i = 0; i < 100; i++)
+ assertTrue("Incorrect value retrieved",
+ whm.get(keyArray[i]) == valueArray[i]);
+
+ WeakHashMap empty = new WeakHashMap(0);
+ assertNull("Empty weakhashmap access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+
+ try {
+ new WeakHashMap(-50);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.WeakHashMap#WeakHashMap(int, float)
+ */
+ public void test_ConstructorIF() {
+ // Test for method java.util.WeakHashMap(int, float)
+ whm = new WeakHashMap(50, 0.5f);
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+ for (int i = 0; i < 100; i++)
+ assertTrue("Incorrect value retrieved",
+ whm.get(keyArray[i]) == valueArray[i]);
+
+ WeakHashMap empty = new WeakHashMap(0, 0.75f);
+ assertNull("Empty hashtable access", empty.get("nothing"));
+ empty.put("something", "here");
+ assertTrue("cannot get element", empty.get("something") == "here");
+
+ try {
+ new WeakHashMap(50, -0.5f);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.WeakHashMap#WeakHashMap(java.util.Map)
+ */
+ public void test_ConstructorLjava_util_Map() {
+ Map mockMap = new MockMap();
+ WeakHashMap map = new WeakHashMap(mockMap);
+ assertEquals("Size should be 0", 0, map.size());
+
+ try {
+ new WeakHashMap(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.WeakHashMap#clear()
+ */
+ public void test_clear() {
+ // Test for method boolean java.util.WeakHashMap.clear()
+ whm = new WeakHashMap();
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+ whm.clear();
+ assertTrue("Cleared map should be empty", whm.isEmpty());
+ for (int i = 0; i < 100; i++)
+ assertNull("Cleared map should only return null", whm
+ .get(keyArray[i]));
+
+ }
+
+ /**
+ * java.util.WeakHashMap#containsKey(java.lang.Object)
+ */
+ public void test_containsKeyLjava_lang_Object() {
+ // Test for method boolean java.util.WeakHashMap.containsKey()
+ whm = new WeakHashMap();
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+ for (int i = 0; i < 100; i++)
+ assertTrue("Should contain referenced key", whm
+ .containsKey(keyArray[i]));
+ keyArray[25] = null;
+ keyArray[50] = null;
+ }
+
+ /**
+ * java.util.WeakHashMap#containsValue(java.lang.Object)
+ */
+ public void test_containsValueLjava_lang_Object() {
+ // Test for method boolean java.util.WeakHashMap.containsValue()
+ whm = new WeakHashMap();
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+ for (int i = 0; i < 100; i++)
+ assertTrue("Should contain referenced value", whm
+ .containsValue(valueArray[i]));
+ keyArray[25] = null;
+ keyArray[50] = null;
+ }
+
+ /**
+ * java.util.WeakHashMap#entrySet()
+ */
+ public void test_entrySet() {
+ // Test for method java.util.Set java.util.WeakHashMap.entrySet()
+ whm = new WeakHashMap();
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+ List keys = Arrays.asList(keyArray);
+ List values = Arrays.asList(valueArray);
+ Set entrySet = whm.entrySet();
+ assertTrue("Incorrect number of entries returned--wanted 100, got: "
+ + entrySet.size(), entrySet.size() == 100);
+ Iterator it = entrySet.iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+ assertTrue("Invalid map entry returned--bad key", keys
+ .contains(entry.getKey()));
+ assertTrue("Invalid map entry returned--bad key", values
+ .contains(entry.getValue()));
+ }
+ keys = null;
+ values = null;
+ keyArray[50] = null;
+
+ FinalizationTester.induceFinalization();
+ long startTime = System.currentTimeMillis();
+ // We use a busy wait loop here since we can not know when the ReferenceQueue
+ // daemon will enqueue the cleared references on their internal reference
+ // queues. The current timeout is 5 seconds.
+ do {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ } while (entrySet.size() != 99 &&
+ System.currentTimeMillis() - startTime < 5000);
+
+ assertTrue(
+ "Incorrect number of entries returned after gc--wanted 99, got: "
+ + entrySet.size(), entrySet.size() == 99);
+ }
+
+ /**
+ * java.util.WeakHashMap#isEmpty()
+ */
+ public void test_isEmpty() {
+ // Test for method boolean java.util.WeakHashMap.isEmpty()
+ whm = new WeakHashMap();
+ assertTrue("New map should be empty", whm.isEmpty());
+ Object myObject = new Object();
+ whm.put(myObject, myObject);
+ assertTrue("Map should not be empty", !whm.isEmpty());
+ whm.remove(myObject);
+ assertTrue("Map with elements removed should be empty", whm.isEmpty());
+ }
+
+ /**
+ * java.util.WeakHashMap#put(java.lang.Object, java.lang.Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.WeakHashMap.put(java.lang.Object, java.lang.Object)
+ WeakHashMap map = new WeakHashMap();
+ map.put(null, "value"); // add null key
+ System.gc();
+ System.gc();
+ FinalizationTester.induceFinalization();
+ map.remove("nothing"); // Cause objects in queue to be removed
+ assertEquals("null key was removed", 1, map.size());
+ }
+
+ /**
+ * java.util.WeakHashMap#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map() {
+ Map mockMap = new MockMap();
+ WeakHashMap map = new WeakHashMap();
+ map.putAll(mockMap);
+ assertEquals("Size should be 0", 0, map.size());
+
+ try {
+ map.putAll(null);
+ fail("NullPointerException exected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.WeakHashMap#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ // Test for method java.lang.Object
+ // java.util.WeakHashMap.remove(java.lang.Object)
+ whm = new WeakHashMap();
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+
+ assertTrue("Remove returned incorrect value",
+ whm.remove(keyArray[25]) == valueArray[25]);
+ assertNull("Remove returned incorrect value",
+ whm.remove(keyArray[25]));
+ assertEquals("Size should be 99 after remove", 99, whm.size());
+ }
+
+ /**
+ * java.util.WeakHashMap#size()
+ */
+ public void test_size() {
+ whm = new WeakHashMap();
+ assertEquals(0, whm.size());
+ }
+
+ /**
+ * java.util.WeakHashMap#keySet()
+ */
+ public void test_keySet() {
+ // Test for method java.util.Set java.util.WeakHashMap.keySet()
+ whm = new WeakHashMap();
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+
+ List keys = Arrays.asList(keyArray);
+ List values = Arrays.asList(valueArray);
+
+ Set keySet = whm.keySet();
+ assertEquals("Incorrect number of keys returned,", 100, keySet.size());
+ Iterator it = keySet.iterator();
+ while (it.hasNext()) {
+ Object key = it.next();
+ assertTrue("Invalid map entry returned--bad key", keys
+ .contains(key));
+ }
+ keys = null;
+ values = null;
+ keyArray[50] = null;
+
+ int count = 0;
+ do {
+ System.gc();
+ System.gc();
+ FinalizationTester.induceFinalization();
+ count++;
+ } while (count <= 5 && keySet.size() == 100);
+
+ assertEquals("Incorrect number of keys returned after gc,", 99, keySet
+ .size());
+ }
+
+ /**
+ * Regression test for HARMONY-3883
+ *
+ * java.util.WeakHashMap#keySet()
+ */
+ public void test_keySet_hasNext() {
+ WeakHashMap map = new WeakHashMap();
+ ConstantHashClass cl = new ConstantHashClass(2);
+ map.put(new ConstantHashClass(1), null);
+ map.put(cl, null);
+ map.put(new ConstantHashClass(3), null);
+ Iterator iter = map.keySet().iterator();
+ iter.next();
+ iter.next();
+ int count = 0;
+ do {
+ System.gc();
+ System.gc();
+ FinalizationTester.induceFinalization();
+ count++;
+ } while (count <= 5);
+ assertFalse("Wrong hasNext() value", iter.hasNext());
+ }
+
+ static class ConstantHashClass {
+ private int id = 0;
+
+ public ConstantHashClass(int id) {
+ this.id = id;
+ }
+
+ public int hashCode() {
+ return 0;
+ }
+
+ public String toString() {
+ return "ConstantHashClass[id=" + id + "]";
+ }
+ }
+
+
+ /**
+ * java.util.WeakHashMap#values()
+ */
+ public void test_values() {
+ // Test for method java.util.Set java.util.WeakHashMap.values()
+ whm = new WeakHashMap();
+ for (int i = 0; i < 100; i++)
+ whm.put(keyArray[i], valueArray[i]);
+
+ List keys = Arrays.asList(keyArray);
+ List values = Arrays.asList(valueArray);
+
+ Collection valuesCollection = whm.values();
+ assertEquals("Incorrect number of keys returned,", 100,
+ valuesCollection.size());
+ Iterator it = valuesCollection.iterator();
+ while (it.hasNext()) {
+ Object value = it.next();
+ assertTrue("Invalid map entry returned--bad value", values
+ .contains(value));
+ }
+ keys = null;
+ values = null;
+ keyArray[50] = null;
+
+ int count = 0;
+ do {
+ System.gc();
+ System.gc();
+ FinalizationTester.induceFinalization();
+ count++;
+ } while (count <= 5 && valuesCollection.size() == 100);
+
+ assertEquals("Incorrect number of keys returned after gc,", 99,
+ valuesCollection.size());
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
+ for (int i = 0; i < 100; i++) {
+ keyArray[i] = new Object();
+ valueArray[i] = new Object();
+ }
+
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/AttributesNameTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/AttributesNameTest.java
new file mode 100644
index 0000000..8eb7fe0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/AttributesNameTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.jar;
+
+import java.util.jar.Attributes;
+
+import junit.framework.TestCase;
+
+public class AttributesNameTest extends TestCase {
+
+ /**
+ * java.util.jar.Attributes.Name#Name(java.lang.String)
+ */
+ public void testAttributesNameConstructor() {
+ // Regression for HARMONY-85
+ try {
+ new Attributes.Name(
+ "01234567890123456789012345678901234567890123456789012345678901234567890");
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/AttributesTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/AttributesTest.java
new file mode 100644
index 0000000..15f6851
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/AttributesTest.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.jar;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Attributes;
+import junit.framework.TestCase;
+
+public class AttributesTest extends TestCase {
+ private Attributes a;
+
+ @Override
+ protected void setUp() {
+ a = new Attributes();
+ a.putValue("1", "one");
+ a.putValue("2", "two");
+ a.putValue("3", "three");
+ a.putValue("4", "four");
+ }
+
+ /**
+ * java.util.jar.Attributes#Attributes(java.util.jar.Attributes)
+ */
+ public void test_ConstructorLjava_util_jar_Attributes() {
+ Attributes a2 = new Attributes(a);
+ assertEquals(a, a2);
+ a.putValue("1", "one(1)");
+ assertTrue("equal", !a.equals(a2));
+ }
+
+ /**
+ * java.util.jar.Attributes#clear()
+ */
+ public void test_clear() {
+ a.clear();
+ assertNull("a) All entries should be null after clear", a.get("1"));
+ assertNull("b) All entries should be null after clear", a.get("2"));
+ assertNull("c) All entries should be null after clear", a.get("3"));
+ assertNull("d) All entries should be null after clear", a.get("4"));
+ assertTrue("Should not contain any keys", !a.containsKey("1"));
+ }
+
+ /**
+ * java.util.jar.Attributes#containsKey(java.lang.Object)
+ */
+ public void test_containsKeyLjava_lang_Object() {
+ assertTrue("a) Should have returned false", !a.containsKey(new Integer(1)));
+ assertTrue("b) Should have returned false", !a.containsKey("0"));
+ assertTrue("Should have returned true", a.containsKey(new Attributes.Name("1")));
+ }
+
+ /**
+ * java.util.jar.Attributes#containsValue(java.lang.Object)
+ */
+ public void test_containsValueLjava_lang_Object() {
+ assertTrue("Should have returned false", !a.containsValue("One"));
+ assertTrue("Should have returned true", a.containsValue("one"));
+ }
+
+ /**
+ * java.util.jar.Attributes#entrySet()
+ */
+ public void test_entrySet() {
+ Set<Map.Entry<Object, Object>> entrySet = a.entrySet();
+ Set<Object> keySet = new HashSet<Object>();
+ Set<Object> valueSet = new HashSet<Object>();
+ Iterator<?> i;
+ assertEquals(4, entrySet.size());
+ i = entrySet.iterator();
+ while (i.hasNext()) {
+ java.util.Map.Entry<?, ?> e;
+ e = (Map.Entry<?, ?>) i.next();
+ keySet.add(e.getKey());
+ valueSet.add(e.getValue());
+ }
+ assertTrue("a) Should contain entry", valueSet.contains("one"));
+ assertTrue("b) Should contain entry", valueSet.contains("two"));
+ assertTrue("c) Should contain entry", valueSet.contains("three"));
+ assertTrue("d) Should contain entry", valueSet.contains("four"));
+ assertTrue("a) Should contain key", keySet.contains(new Attributes.Name("1")));
+ assertTrue("b) Should contain key", keySet.contains(new Attributes.Name("2")));
+ assertTrue("c) Should contain key", keySet.contains(new Attributes.Name("3")));
+ assertTrue("d) Should contain key", keySet.contains(new Attributes.Name("4")));
+ }
+
+ /**
+ * java.util.jar.Attributes#get(java.lang.Object)
+ */
+ public void test_getLjava_lang_Object() {
+ assertEquals("a) Incorrect value returned", "one", a.getValue("1"));
+ assertNull("b) Incorrect value returned", a.getValue("0"));
+ }
+
+ /**
+ * java.util.jar.Attributes#isEmpty()
+ */
+ public void test_isEmpty() {
+ assertTrue("Should not be empty", !a.isEmpty());
+ a.clear();
+ assertTrue("a) Should be empty", a.isEmpty());
+ a = new Attributes();
+ assertTrue("b) Should be empty", a.isEmpty());
+ }
+
+ /**
+ * java.util.jar.Attributes#keySet()
+ */
+ public void test_keySet() {
+ Set<?> s = a.keySet();
+ assertEquals(4, s.size());
+ assertTrue("a) Should contain entry", s.contains(new Attributes.Name("1")));
+ assertTrue("b) Should contain entry", s.contains(new Attributes.Name("2")));
+ assertTrue("c) Should contain entry", s.contains(new Attributes.Name("3")));
+ assertTrue("d) Should contain entry", s.contains(new Attributes.Name("4")));
+ }
+
+ /**
+ * java.util.jar.Attributes#putAll(java.util.Map)
+ */
+ public void test_putAllLjava_util_Map() {
+ Attributes b = new Attributes();
+ b.putValue("3", "san");
+ b.putValue("4", "shi");
+ b.putValue("5", "go");
+ b.putValue("6", "roku");
+ a.putAll(b);
+ assertEquals("Should not have been replaced", "one", a.getValue("1"));
+ assertEquals("Should have been replaced", "san", a.getValue("3"));
+ assertEquals("Should have been added", "go", a.getValue("5"));
+ Attributes atts = new Attributes();
+ assertNull("Assert 0: ", atts.put(Attributes.Name.CLASS_PATH, "tools.jar"));
+ assertNull("Assert 1: ", atts.put(Attributes.Name.MANIFEST_VERSION, "1"));
+ Attributes atts2 = new Attributes();
+ atts2.putAll(atts);
+ assertEquals("Assert 2:", "tools.jar", atts2.get(Attributes.Name.CLASS_PATH));
+ assertEquals("Assert 3: ", "1", atts2.get(Attributes.Name.MANIFEST_VERSION));
+ try {
+ atts.putAll(Collections.EMPTY_MAP);
+ fail("Assert 4: no class cast from attrib parameter");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.jar.Attributes#remove(java.lang.Object)
+ */
+ public void test_removeLjava_lang_Object() {
+ a.remove(new Attributes.Name("1"));
+ a.remove(new Attributes.Name("3"));
+ assertNull("Should have been removed", a.getValue("1"));
+ assertEquals("Should not have been removed", "four", a.getValue("4"));
+ }
+
+ /**
+ * java.util.jar.Attributes#size()
+ */
+ public void test_size() {
+ assertEquals("Incorrect size returned", 4, a.size());
+ a.clear();
+ assertEquals(0, a.size());
+ }
+
+ /**
+ * java.util.jar.Attributes#values()
+ */
+ public void test_values() {
+ Collection<?> valueCollection = a.values();
+ assertTrue("a) Should contain entry", valueCollection.contains("one"));
+ assertTrue("b) Should contain entry", valueCollection.contains("two"));
+ assertTrue("c) Should contain entry", valueCollection.contains("three"));
+ assertTrue("d) Should contain entry", valueCollection.contains("four"));
+ }
+
+ /**
+ * java.util.jar.Attributes#clone()
+ */
+ public void test_clone() {
+ Attributes a2 = (Attributes) a.clone();
+ assertEquals(a, a2);
+ a.putValue("1", "one(1)");
+ assertTrue("equal", !a.equals(a2));
+ }
+
+ /**
+ * java.util.jar.Attributes#equals(java.lang.Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ Attributes.Name n1 = new Attributes.Name("name"), n2 = new Attributes.Name("Name");
+ assertEquals(n1, n2);
+ Attributes a1 = new Attributes();
+ a1.putValue("one", "1");
+ a1.putValue("two", "2");
+ Attributes a2 = new Attributes();
+ a2.putValue("One", "1");
+ a2.putValue("TWO", "2");
+ assertEquals(a1, a2);
+ assertEquals(a1, a1);
+ a2 = null;
+ assertFalse(a1.equals(a2));
+ }
+
+ /**
+ * java.util.jar.Attributes.put(java.lang.Object, java.lang.Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object() {
+ Attributes atts = new Attributes();
+ assertNull("Assert 0: ", atts.put(Attributes.Name.CLASS_PATH, "tools.jar"));
+ assertEquals("Assert 1: ", "tools.jar", atts.getValue(Attributes.Name.CLASS_PATH));
+ // Regression for HARMONY-79
+ try {
+ atts.put("not a name", "value");
+ fail("Assert 2: no class cast from key parameter");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ try {
+ atts.put(Attributes.Name.CLASS_PATH, Boolean.TRUE);
+ fail("Assert 3: no class cast from value parameter");
+ } catch (ClassCastException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.jar.Attributes.put(java.lang.Object, java.lang.Object)
+ */
+ public void test_putLjava_lang_ObjectLjava_lang_Object_Null() {
+
+ Attributes attribute = new Attributes();
+
+ assertFalse(attribute.containsKey(null));
+ assertFalse(attribute.containsValue(null));
+ attribute.put(null, null);
+ attribute.put(null, null);
+ assertEquals(1, attribute.size());
+ assertTrue(attribute.containsKey(null));
+ assertTrue(attribute.containsValue(null));
+ assertNull(attribute.get(null));
+
+ String value = "It's null";
+ attribute.put(null, value);
+ assertEquals(1, attribute.size());
+ assertEquals(value, attribute.get(null));
+
+ Attributes.Name name = new Attributes.Name("null");
+ attribute.put(name, null);
+ assertEquals(2, attribute.size());
+ assertNull(attribute.get(name));
+ }
+
+ /**
+ * java.util.jar.Attributes.hashCode()
+ */
+ public void test_hashCode() {
+ MockAttributes mockAttr = new MockAttributes();
+ mockAttr.putValue("1", "one");
+ assertEquals(mockAttr.getMap().hashCode(), mockAttr.hashCode());
+ }
+
+ private static class MockAttributes extends Attributes {
+ public Map<Object, Object> getMap() {
+ return map;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarEntryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarEntryTest.java
new file mode 100644
index 0000000..a48bd60
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarEntryTest.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.jar;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.CodeSigner;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
+public class JarEntryTest extends TestCase {
+ private ZipEntry zipEntry;
+
+ private JarEntry jarEntry;
+
+ private JarFile jarFile;
+
+ private final String jarName = "hyts_patch.jar";
+
+ private final String entryName = "foo/bar/A.class";
+
+ private final String entryName2 = "Blah.txt";
+
+ private final String attJarName = "hyts_att.jar";
+
+ private final String attEntryName = "HasAttributes.txt";
+
+ private final String attEntryName2 = "NoAttributes.txt";
+
+ private File resources;
+
+ @Override
+ protected void setUp() throws Exception {
+ resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, jarName);
+ jarFile = new JarFile(new File(resources, jarName));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (jarFile != null) {
+ jarFile.close();
+ }
+ }
+
+ /**
+ * @throws IOException
+ * java.util.jar.JarEntry#JarEntry(java.util.jar.JarEntry)
+ */
+ public void test_ConstructorLjava_util_jar_JarEntry() throws IOException {
+ JarEntry newJarEntry = new JarEntry(jarFile.getJarEntry(entryName));
+ assertNotNull(newJarEntry);
+
+ jarEntry = null;
+ try {
+ newJarEntry = new JarEntry(jarEntry);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.jar.JarEntry#JarEntry(java.util.zip.ZipEntry)
+ */
+ public void test_ConstructorLjava_util_zip_ZipEntry() {
+ assertNotNull("Jar file is null", jarFile);
+ zipEntry = jarFile.getEntry(entryName);
+ assertNotNull("Zip entry is null", zipEntry);
+ jarEntry = new JarEntry(zipEntry);
+ assertNotNull("Jar entry is null", jarEntry);
+ assertEquals("Wrong entry constructed--wrong name", entryName, jarEntry
+ .getName());
+ assertEquals("Wrong entry constructed--wrong size", 311, jarEntry
+ .getSize());
+ }
+
+ /**
+ * java.util.jar.JarEntry#getAttributes()
+ */
+ public void test_getAttributes() throws Exception {
+ JarFile attrJar = null;
+ File file = null;
+
+ Support_Resources.copyFile(resources, null, attJarName);
+ file = new File(resources, attJarName);
+ attrJar = new JarFile(file);
+
+ jarEntry = attrJar.getJarEntry(attEntryName);
+ assertNotNull("Should have Manifest attributes", jarEntry
+ .getAttributes());
+
+ jarEntry = attrJar.getJarEntry(attEntryName2);
+ assertNull("Shouldn't have any Manifest attributes", jarEntry
+ .getAttributes());
+ attrJar.close();
+ }
+
+ /**
+ * java.util.jar.JarEntry#getCertificates()
+ */
+ public void test_getCertificates() throws Exception {
+ zipEntry = jarFile.getEntry(entryName2);
+ jarEntry = new JarEntry(zipEntry);
+ assertNull(jarEntry.getCertificates());
+
+ // Regression Test for HARMONY-3424
+ String jarFileName = "TestCodeSigners.jar";
+ Support_Resources.copyFile(resources, null, jarFileName);
+ File file = new File(resources, jarFileName);
+ JarFile jarFile = new JarFile(file);
+ JarEntry jarEntry1 = jarFile.getJarEntry("Test.class");
+ JarEntry jarEntry2 = jarFile.getJarEntry("Test.class");
+ InputStream in = jarFile.getInputStream(jarEntry1);
+ byte[] buffer = new byte[1024];
+ while (in.available() > 0) {
+ assertNull("getCertificates() should be null until the entry is read",
+ jarEntry1.getCertificates());
+ assertNull(jarEntry2.getCertificates());
+ in.read(buffer);
+ }
+ assertEquals("the file is fully read", -1, in.read());
+ assertNotNull(jarEntry1.getCertificates());
+ assertNotNull(jarEntry2.getCertificates());
+ in.close();
+ }
+
+ /**
+ * java.util.jar.JarEntry#getCodeSigners()
+ */
+ public void test_getCodeSigners() throws IOException {
+ String jarFileName = "TestCodeSigners.jar";
+ Support_Resources.copyFile(resources, null, jarFileName);
+ File file = new File(resources, jarFileName);
+ JarFile jarFile = new JarFile(file);
+ JarEntry jarEntry = jarFile.getJarEntry("Test.class");
+ InputStream in = jarFile.getInputStream(jarEntry);
+ byte[] buffer = new byte[1024];
+ while (in.available() > 0) {
+ assertNull("getCodeSigners() should be null until the entry is read",
+ jarEntry.getCodeSigners());
+ in.read(buffer);
+ }
+ assertEquals("the file is fully read", -1, in.read());
+ CodeSigner[] codeSigners = jarEntry.getCodeSigners();
+ assertEquals(2, codeSigners.length);
+ List<?> certs_bob = codeSigners[0].getSignerCertPath()
+ .getCertificates();
+ List<?> certs_alice = codeSigners[1].getSignerCertPath()
+ .getCertificates();
+ if (1 == certs_bob.size()) {
+ List<?> temp = certs_bob;
+ certs_bob = certs_alice;
+ certs_alice = temp;
+ }
+ assertEquals(2, certs_bob.size());
+ assertEquals(1, certs_alice.size());
+ assertNull(
+ "getCodeSigners() should be null for a primitive JarEntry",
+ new JarEntry("aaa").getCodeSigners());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarExceptionTest.java
new file mode 100644
index 0000000..66ff400
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarExceptionTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.jar;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.jar.JarException;
+import java.util.jar.Manifest;
+import junit.framework.TestCase;
+
+public class JarExceptionTest extends TestCase {
+ /**
+ * java.util.jar.JarException#JarException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws Exception {
+ try {
+ new Manifest(new ByteArrayInputStream(
+ "jlkasj dl: dsklf jlks dslka : fdsfsd\n\n\n\ndsfas".getBytes()));
+ fail("Should have thrown exception");
+ } catch (IOException e) {
+ // correct
+ }
+ }
+
+ /**
+ * java.util.jar.JarException#JarException(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String1() throws Exception {
+ assertEquals("Jar Exception", new JarException("Jar Exception").getMessage());
+ }
+
+ /**
+ * java.util.jar.JarException#JarException()
+ */
+ public void test_Constructor_void() throws Exception {
+ new JarException();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
new file mode 100644
index 0000000..d5d8191
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
@@ -0,0 +1,1017 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.jar;
+
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.CodeSigner;
+import java.security.Permission;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
+
+public class JarFileTest extends TestCase {
+
+ // BEGIN android-added
+ public byte[] getAllBytesFromStream(InputStream is) throws IOException {
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ byte[] buf = new byte[666];
+ int iRead;
+ int off;
+ while (is.available() > 0) {
+ iRead = is.read(buf, 0, buf.length);
+ if (iRead > 0) bs.write(buf, 0, iRead);
+ }
+ return bs.toByteArray();
+ }
+
+ // END android-added
+
+ private final String jarName = "hyts_patch.jar"; // a 'normal' jar file
+
+ private final String jarName2 = "hyts_patch2.jar";
+
+ private final String jarName3 = "hyts_manifest1.jar";
+
+ private final String jarName4 = "hyts_signed.jar";
+
+ private final String jarName5 = "hyts_signed_inc.jar";
+
+ private final String jarName6 = "hyts_signed_sha256withrsa.jar";
+
+ private final String jarName7 = "hyts_signed_sha256digest_sha256withrsa.jar";
+
+ private final String jarName8 = "hyts_signed_sha512digest_sha512withecdsa.jar";
+
+ private final String jarName9 = "hyts_signed_sha256digest_sha256withecdsa.jar";
+
+ private final String authAttrsJar = "hyts_signed_authAttrs.jar";
+
+ private final String entryName = "foo/bar/A.class";
+
+ private final String entryName3 = "coucou/FileAccess.class";
+
+ private final String integrateJar = "Integrate.jar";
+
+ private final String integrateJarEntry = "Test.class";
+
+ private final String emptyEntryJar = "EmptyEntries_signed.jar";
+
+ private final String emptyEntry1 = "subfolder/internalSubset01.js";
+
+ private final String emptyEntry2 = "svgtest.js";
+
+ private final String emptyEntry3 = "svgunit.js";
+
+ private static final String VALID_CHAIN_JAR = "hyts_signed_validChain.jar";
+
+ private static final String INVALID_CHAIN_JAR = "hyts_signed_invalidChain.jar";
+
+ private static final String AMBIGUOUS_SIGNERS_JAR = "hyts_signed_ambiguousSignerArray.jar";
+
+ private File resources;
+
+ // custom security manager
+ SecurityManager sm = new SecurityManager() {
+ final String forbidenPermissionName = "user.dir";
+
+ public void checkPermission(Permission perm) {
+ if (perm.getName().equals(forbidenPermissionName)) {
+ throw new SecurityException();
+ }
+ }
+ };
+
+ @Override
+ protected void setUp() {
+ resources = Support_Resources.createTempFolder();
+ }
+
+ /**
+ * java.util.jar.JarFile#JarFile(java.io.File)
+ */
+ public void test_ConstructorLjava_io_File() {
+ try {
+ JarFile jarFile = new JarFile(new File("Wrong.file"));
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ } catch (IOException e) {
+ fail("Should not throw IOException");
+ }
+ }
+
+ /**
+ * java.util.jar.JarFile#JarFile(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ try {
+ JarFile jarFile = new JarFile("Wrong.file");
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ String fileName = (new File(resources, jarName)).getCanonicalPath();
+ JarFile jarFile = new JarFile(fileName);
+ } catch (IOException e) {
+ fail("Should not throw IOException");
+ }
+ }
+
+ /**
+ * java.util.jar.JarFile#JarFile(java.lang.String, boolean)
+ */
+ public void test_ConstructorLjava_lang_StringZ() {
+ try {
+ JarFile jarFile = new JarFile("Wrong.file", false);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ String fileName = (new File(resources, jarName)).getCanonicalPath();
+ JarFile jarFile = new JarFile(fileName, true);
+ } catch (IOException e) {
+ fail("Should not throw IOException");
+ }
+ }
+
+ /**
+ * java.util.jar.JarFile#JarFile(java.io.File, boolean)
+ */
+ public void test_ConstructorLjava_io_FileZ() {
+ try {
+ JarFile jarFile = new JarFile(new File("Wrong.file"), true);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName), false);
+ } catch (IOException e) {
+ fail("Should not throw IOException");
+ }
+ }
+
+ /**
+ * java.util.jar.JarFile#JarFile(java.io.File, boolean, int)
+ */
+ public void test_ConstructorLjava_io_FileZI() {
+ try {
+ JarFile jarFile = new JarFile(new File("Wrong.file"), true,
+ ZipFile.OPEN_READ);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName), false,
+ ZipFile.OPEN_READ);
+ } catch (IOException e) {
+ fail("Should not throw IOException");
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName), false,
+ ZipFile.OPEN_READ | ZipFile.OPEN_DELETE + 33);
+ fail("Should throw IllegalArgumentException");
+ } catch (IOException e) {
+ fail("Should not throw IOException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Constructs JarFile object.
+ *
+ * java.util.jar.JarFile#JarFile(java.io.File)
+ * java.util.jar.JarFile#JarFile(java.lang.String)
+ */
+ public void testConstructor_file() throws IOException {
+ File f = new File(resources, jarName);
+ Support_Resources.copyFile(resources, null, jarName);
+ assertTrue(new JarFile(f).getEntry(entryName).getName().equals(
+ entryName));
+ assertTrue(new JarFile(f.getPath()).getEntry(entryName).getName()
+ .equals(entryName));
+ }
+
+ /**
+ * java.util.jar.JarFile#entries()
+ */
+ public void test_entries() throws Exception {
+ /*
+ * Note only (and all of) the following should be contained in the file
+ * META-INF/ META-INF/MANIFEST.MF foo/ foo/bar/ foo/bar/A.class Blah.txt
+ */
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ Enumeration<JarEntry> e = jarFile.entries();
+ int i;
+ for (i = 0; e.hasMoreElements(); i++) {
+ e.nextElement();
+ }
+ assertEquals(jarFile.size(), i);
+ jarFile.close();
+ assertEquals(6, i);
+ }
+
+ public void test_entries2() throws Exception {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ Enumeration<JarEntry> enumeration = jarFile.entries();
+ jarFile.close();
+ try {
+ enumeration.hasMoreElements();
+ fail("hasMoreElements() did not detect a closed jar file");
+ } catch (IllegalStateException e) {
+ }
+ Support_Resources.copyFile(resources, null, jarName);
+ jarFile = new JarFile(new File(resources, jarName));
+ enumeration = jarFile.entries();
+ jarFile.close();
+ try {
+ enumeration.nextElement();
+ fail("nextElement() did not detect closed jar file");
+ } catch (IllegalStateException e) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * java.util.jar.JarFile#getJarEntry(java.lang.String)
+ */
+ public void test_getEntryLjava_lang_String() throws IOException {
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ assertEquals("Error in returned entry", 311, jarFile.getEntry(
+ entryName).getSize());
+ jarFile.close();
+ } catch (Exception e) {
+ fail("Exception during test: " + e.toString());
+ }
+
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ Enumeration<JarEntry> enumeration = jarFile.entries();
+ assertTrue(enumeration.hasMoreElements());
+ while (enumeration.hasMoreElements()) {
+ JarEntry je = enumeration.nextElement();
+ jarFile.getEntry(je.getName());
+ }
+
+ enumeration = jarFile.entries();
+ assertTrue(enumeration.hasMoreElements());
+ JarEntry je = enumeration.nextElement();
+ try {
+ jarFile.close();
+ jarFile.getEntry(je.getName());
+ // fail("IllegalStateException expected.");
+ } catch (IllegalStateException ee) { // Per documentation exception
+ // may be thrown.
+ // expected
+ }
+ }
+
+ /**
+ * @throws IOException
+ * java.util.jar.JarFile#getJarEntry(java.lang.String)
+ */
+ public void test_getJarEntryLjava_lang_String() throws IOException {
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ assertEquals("Error in returned entry", 311, jarFile.getJarEntry(
+ entryName).getSize());
+ jarFile.close();
+ } catch (Exception e) {
+ fail("Exception during test: " + e.toString());
+ }
+
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ Enumeration<JarEntry> enumeration = jarFile.entries();
+ assertTrue(enumeration.hasMoreElements());
+ while (enumeration.hasMoreElements()) {
+ JarEntry je = enumeration.nextElement();
+ jarFile.getJarEntry(je.getName());
+ }
+
+ enumeration = jarFile.entries();
+ assertTrue(enumeration.hasMoreElements());
+ JarEntry je = enumeration.nextElement();
+ try {
+ jarFile.close();
+ jarFile.getJarEntry(je.getName());
+ // fail("IllegalStateException expected.");
+ } catch (IllegalStateException ee) { // Per documentation exception
+ // may be thrown.
+ // expected
+ }
+ }
+
+
+ /**
+ * java.util.jar.JarFile#getJarEntry(java.lang.String)
+ */
+ public void testGetJarEntry() throws Exception {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ assertEquals("Error in returned entry", 311, jarFile.getEntry(
+ entryName).getSize());
+ jarFile.close();
+
+ // tests for signed jars
+ // test all signed jars in the /Testres/Internal/SignedJars directory
+ String jarDirUrl = Support_Resources
+ .getResourceURL("/../internalres/signedjars");
+ Vector<String> signedJars = new Vector<String>();
+ try {
+ InputStream is = new URL(jarDirUrl + "/jarlist.txt").openStream();
+ while (is.available() > 0) {
+ StringBuilder linebuff = new StringBuilder(80); // Typical line
+ // length
+ done: while (true) {
+ int nextByte = is.read();
+ switch (nextByte) {
+ case -1:
+ break done;
+ case (byte) '\r':
+ if (linebuff.length() == 0) {
+ // ignore
+ }
+ break done;
+ case (byte) '\n':
+ if (linebuff.length() == 0) {
+ // ignore
+ }
+ break done;
+ default:
+ linebuff.append((char) nextByte);
+ }
+ }
+ if (linebuff.length() == 0) {
+ break;
+ }
+ String line = linebuff.toString();
+ signedJars.add(line);
+ }
+ is.close();
+ } catch (IOException e) {
+ // no list of jars found
+ }
+
+ for (int i = 0; i < signedJars.size(); i++) {
+ String jarName = signedJars.get(i);
+ try {
+ File file = Support_Resources.getExternalLocalFile(jarDirUrl
+ + "/" + jarName);
+ jarFile = new JarFile(file, true);
+ boolean foundCerts = false;
+ Enumeration<JarEntry> e = jarFile.entries();
+ while (e.hasMoreElements()) {
+ JarEntry entry = e.nextElement();
+ InputStream is = jarFile.getInputStream(entry);
+ is.skip(100000);
+ is.close();
+ Certificate[] certs = entry.getCertificates();
+ if (certs != null && certs.length > 0) {
+ foundCerts = true;
+ break;
+ }
+ }
+ assertTrue(
+ "No certificates found during signed jar test for jar \""
+ + jarName + "\"", foundCerts);
+ } catch (IOException e) {
+ fail("Exception during signed jar test for jar \"" + jarName
+ + "\": " + e.toString());
+ }
+ }
+ }
+
+ /**
+ * java.util.jar.JarFile#getManifest()
+ */
+ public void test_getManifest() {
+ // Test for method java.util.jar.Manifest
+ // java.util.jar.JarFile.getManifest()
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ JarFile jarFile = new JarFile(new File(resources, jarName));
+ assertNotNull("Error--Manifest not returned", jarFile.getManifest());
+ jarFile.close();
+ } catch (Exception e) {
+ fail("Exception during 1st test: " + e.toString());
+ }
+ try {
+ Support_Resources.copyFile(resources, null, jarName2);
+ JarFile jarFile = new JarFile(new File(resources, jarName2));
+ assertNull("Error--should have returned null", jarFile
+ .getManifest());
+ jarFile.close();
+ } catch (Exception e) {
+ fail("Exception during 2nd test: " + e.toString());
+ }
+
+ try {
+ // jarName3 was created using the following test
+ Support_Resources.copyFile(resources, null, jarName3);
+ JarFile jarFile = new JarFile(new File(resources, jarName3));
+ assertNotNull("Should find manifest without verifying", jarFile
+ .getManifest());
+ jarFile.close();
+ } catch (Exception e) {
+ fail("Exception during 3rd test: " + e.toString());
+ }
+
+ try {
+ // this is used to create jarName3 used in the previous test
+ Manifest manifest = new Manifest();
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.put(new Attributes.Name("Manifest-Version"), "1.0");
+ ByteArrayOutputStream manOut = new ByteArrayOutputStream();
+ manifest.write(manOut);
+ byte[] manBytes = manOut.toByteArray();
+ File file = File.createTempFile("hyts_manifest1", ".jar");
+ JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(
+ file.getAbsolutePath()));
+ ZipEntry entry = new ZipEntry("META-INF/");
+ entry.setSize(0);
+ jarOut.putNextEntry(entry);
+ entry = new ZipEntry(JarFile.MANIFEST_NAME);
+ entry.setSize(manBytes.length);
+ jarOut.putNextEntry(entry);
+ jarOut.write(manBytes);
+ entry = new ZipEntry("myfile");
+ entry.setSize(1);
+ jarOut.putNextEntry(entry);
+ jarOut.write(65);
+ jarOut.close();
+ JarFile jar = new JarFile(file.getAbsolutePath(), false);
+ assertNotNull("Should find manifest without verifying", jar
+ .getManifest());
+ jar.close();
+ file.delete();
+ } catch (IOException e) {
+ fail("IOException 3");
+ }
+ try {
+ Support_Resources.copyFile(resources, null, jarName2);
+ JarFile jF = new JarFile(new File(resources, jarName2));
+ jF.close();
+ jF.getManifest();
+ fail("FAILED: expected IllegalStateException");
+ } catch (IllegalStateException ise) {
+ // expected;
+ } catch (Exception e) {
+ fail("Exception during 4th test: " + e.toString());
+ }
+
+ Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
+ JarFile jf;
+ try {
+ jf = new JarFile(new File(resources, "Broken_manifest.jar"));
+ jf.getManifest();
+ fail("IOException expected.");
+ } catch (IOException e) {
+ // expected.
+ }
+ }
+
+ /**
+ * java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
+ */
+ // This test doesn't pass on RI. If entry size is set up incorrectly,
+ // SecurityException is thrown. But SecurityException is thrown on RI only
+ // if jar file is signed incorrectly.
+ public void test_getInputStreamLjava_util_jar_JarEntry_subtest0() throws Exception {
+ File signedFile = null;
+ try {
+ Support_Resources.copyFile(resources, null, jarName4);
+ signedFile = new File(resources, jarName4);
+ } catch (Exception e) {
+ fail("Failed to create local file 2: " + e);
+ }
+
+ try {
+ JarFile jar = new JarFile(signedFile);
+ JarEntry entry = new JarEntry(entryName3);
+ InputStream in = jar.getInputStream(entry);
+ in.read();
+ } catch (Exception e) {
+ fail("Exception during test 3: " + e);
+ }
+
+ try {
+ JarFile jar = new JarFile(signedFile);
+ JarEntry entry = new JarEntry(entryName3);
+ InputStream in = jar.getInputStream(entry);
+ // BEGIN android-added
+ byte[] dummy = getAllBytesFromStream(in);
+ // END android-added
+ assertNull("found certificates", entry.getCertificates());
+ } catch (Exception e) {
+ fail("Exception during test 4: " + e);
+ }
+
+ try {
+ JarFile jar = new JarFile(signedFile);
+ JarEntry entry = new JarEntry(entryName3);
+ entry.setSize(1076);
+ InputStream in = jar.getInputStream(entry);
+ // BEGIN android-added
+ byte[] dummy = getAllBytesFromStream(in);
+ // END android-added
+ fail("SecurityException should be thrown.");
+ } catch (SecurityException e) {
+ // expected
+ } catch (Exception e) {
+ fail("Exception during test 5: " + e);
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName5);
+ signedFile = new File(resources, jarName5);
+ } catch (Exception e) {
+ fail("Failed to create local file 5: " + e);
+ }
+
+ try {
+ JarFile jar = new JarFile(signedFile);
+ JarEntry entry = new JarEntry(entryName3);
+ InputStream in = jar.getInputStream(entry);
+ fail("SecurityException should be thrown.");
+ } catch (SecurityException e) {
+ // expected
+ } catch (Exception e) {
+ fail("Exception during test 5: " + e);
+ }
+
+ // SHA1 digest, SHA256withRSA signed JAR
+ checkSignedJar(jarName6);
+
+ // SHA-256 digest, SHA256withRSA signed JAR
+ checkSignedJar(jarName7);
+
+ // SHA-512 digest, SHA512withECDSA signed JAR
+ checkSignedJar(jarName8);
+
+ // JAR with a signature that has PKCS#7 Authenticated Attributes
+ checkSignedJar(authAttrsJar);
+ }
+
+ /**
+ * This test uses a jar file signed with an algorithm that has its own OID
+ * that is valid as a signature type. SHA256withECDSA is an algorithm that
+ * isn't combined as DigestAlgorithm + "with" + DigestEncryptionAlgorithm
+ * like RSAEncryption needs to be.
+ */
+ public void testJarFile_Signed_Valid_DigestEncryptionAlgorithm() throws Exception {
+ checkSignedJar(jarName9);
+ }
+
+ private void checkSignedJar(String jarName) throws Exception {
+ Support_Resources.copyFile(resources, null, jarName);
+
+ File file = new File(resources, jarName);
+ boolean foundCerts = false;
+
+ JarFile jarFile = new JarFile(file, true);
+ try {
+
+ Enumeration<JarEntry> e = jarFile.entries();
+ while (e.hasMoreElements()) {
+ JarEntry entry = e.nextElement();
+ InputStream is = jarFile.getInputStream(entry);
+ is.skip(100000);
+ is.close();
+ Certificate[] certs = entry.getCertificates();
+ if (certs != null && certs.length > 0) {
+ foundCerts = true;
+ break;
+ }
+ }
+ } finally {
+ jarFile.close();
+ }
+
+ assertTrue(
+ "No certificates found during signed jar test for jar \""
+ + jarName + "\"", foundCerts);
+ }
+
+ private static class Results {
+ public Certificate[] certificates;
+ public CodeSigner[] signers;
+ }
+
+ private Results getSignedJarCerts(String jarName) throws Exception {
+ Support_Resources.copyFile(resources, null, jarName);
+
+ File file = new File(resources, jarName);
+ Results results = new Results();
+
+ JarFile jarFile = new JarFile(file, true, ZipFile.OPEN_READ);
+ try {
+
+ Enumeration<JarEntry> e = jarFile.entries();
+ while (e.hasMoreElements()) {
+ JarEntry entry = e.nextElement();
+ InputStream is = jarFile.getInputStream(entry);
+ // Skip bytes because we have to read the entire file for it to read signatures.
+ is.skip(entry.getSize());
+ is.close();
+ Certificate[] certs = entry.getCertificates();
+ CodeSigner[] signers = entry.getCodeSigners();
+ if (certs != null && certs.length > 0) {
+ results.certificates = certs;
+ results.signers = signers;
+ break;
+ }
+ }
+ } finally {
+ jarFile.close();
+ }
+
+ return results;
+ }
+
+ public void testJarFile_Signed_ValidChain() throws Exception {
+ Results result = getSignedJarCerts(VALID_CHAIN_JAR);
+ assertNotNull(result);
+ assertEquals(Arrays.deepToString(result.certificates), 3, result.certificates.length);
+ assertEquals(Arrays.deepToString(result.signers), 1, result.signers.length);
+ assertEquals(3, result.signers[0].getSignerCertPath().getCertificates().size());
+ assertEquals("CN=fake-chain", ((X509Certificate) result.certificates[0]).getSubjectDN().toString());
+ assertEquals("CN=intermediate1", ((X509Certificate) result.certificates[1]).getSubjectDN().toString());
+ assertEquals("CN=root1", ((X509Certificate) result.certificates[2]).getSubjectDN().toString());
+ }
+
+ public void testJarFile_Signed_InvalidChain() throws Exception {
+ Results result = getSignedJarCerts(INVALID_CHAIN_JAR);
+ assertNotNull(result);
+ assertEquals(Arrays.deepToString(result.certificates), 3, result.certificates.length);
+ assertEquals(Arrays.deepToString(result.signers), 1, result.signers.length);
+ assertEquals(3, result.signers[0].getSignerCertPath().getCertificates().size());
+ assertEquals("CN=fake-chain", ((X509Certificate) result.certificates[0]).getSubjectDN().toString());
+ assertEquals("CN=intermediate1", ((X509Certificate) result.certificates[1]).getSubjectDN().toString());
+ assertEquals("CN=root1", ((X509Certificate) result.certificates[2]).getSubjectDN().toString());
+ }
+
+ public void testJarFile_Signed_AmbiguousSigners() throws Exception {
+ Results result = getSignedJarCerts(AMBIGUOUS_SIGNERS_JAR);
+ assertNotNull(result);
+ assertEquals(Arrays.deepToString(result.certificates), 2, result.certificates.length);
+ assertEquals(Arrays.deepToString(result.signers), 2, result.signers.length);
+ assertEquals(1, result.signers[0].getSignerCertPath().getCertificates().size());
+ assertEquals(1, result.signers[1].getSignerCertPath().getCertificates().size());
+ }
+
+ /*
+ * The jar created by 1.4 which does not provide a
+ * algorithm-Digest-Manifest-Main-Attributes entry in .SF file.
+ */
+ public void test_Jar_created_before_java_5() throws IOException {
+ String modifiedJarName = "Created_by_1_4.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = entries.nextElement();
+ jarFile.getInputStream(zipEntry);
+ }
+ }
+
+ /* The jar is intact, then everything is all right. */
+ public void test_JarFile_Integrate_Jar() throws IOException {
+ String modifiedJarName = "Integrate.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = entries.nextElement();
+ jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
+ }
+ }
+
+ /**
+ * The jar is intact, but the entry object is modified.
+ */
+ public void testJarVerificationModifiedEntry() throws IOException {
+ Support_Resources.copyFile(resources, null, integrateJar);
+ File f = new File(resources, integrateJar);
+
+ JarFile jarFile = new JarFile(f);
+ ZipEntry zipEntry = jarFile.getJarEntry(integrateJarEntry);
+ zipEntry.setSize(zipEntry.getSize() + 1);
+ jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
+
+ jarFile = new JarFile(f);
+ zipEntry = jarFile.getJarEntry(integrateJarEntry);
+ zipEntry.setSize(zipEntry.getSize() - 1);
+ try {
+ //jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
+ jarFile.getInputStream(zipEntry).read(new byte[5000], 0, 5000);
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // desired
+ }
+ }
+
+ /*
+ * If another entry is inserted into Manifest, no security exception will be
+ * thrown out.
+ */
+ public void test_JarFile_InsertEntry_in_Manifest_Jar() throws IOException {
+ String modifiedJarName = "Inserted_Entry_Manifest.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ int count = 0;
+ while (entries.hasMoreElements()) {
+
+ ZipEntry zipEntry = entries.nextElement();
+ jarFile.getInputStream(zipEntry);
+ count++;
+ }
+ assertEquals(5, count);
+ }
+
+ /*
+ * If another entry is inserted into Manifest, no security exception will be
+ * thrown out.
+ */
+ public void test_Inserted_Entry_Manifest_with_DigestCode()
+ throws IOException {
+ String modifiedJarName = "Inserted_Entry_Manifest_with_DigestCode.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ int count = 0;
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = entries.nextElement();
+ jarFile.getInputStream(zipEntry);
+ count++;
+ }
+ assertEquals(5, count);
+ }
+
+ /*
+ * The content of Test.class is modified, jarFile.getInputStream will not
+ * throw security Exception, but it will anytime before the inputStream got
+ * from getInputStream method has been read to end.
+ */
+ public void test_JarFile_Modified_Class() throws IOException {
+ String modifiedJarName = "Modified_Class.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = entries.nextElement();
+ jarFile.getInputStream(zipEntry);
+ }
+ /* The content of Test.class has been tampered. */
+ ZipEntry zipEntry = jarFile.getEntry("Test.class");
+ InputStream in = jarFile.getInputStream(zipEntry);
+ byte[] buffer = new byte[1024];
+ try {
+ while (in.available() > 0) {
+ in.read(buffer);
+ }
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // desired
+ }
+ }
+
+ /*
+ * In the Modified.jar, the main attributes of META-INF/MANIFEST.MF is
+ * tampered manually. Hence the RI 5.0 JarFile.getInputStream of any
+ * JarEntry will throw security exception.
+ */
+ public void test_JarFile_Modified_Manifest_MainAttributes()
+ throws IOException {
+ String modifiedJarName = "Modified_Manifest_MainAttributes.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = entries.nextElement();
+ try {
+ jarFile.getInputStream(zipEntry);
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // desired
+ }
+ }
+ }
+
+ /*
+ * It is all right in our original JarFile. If the Entry Attributes, for
+ * example Test.class in our jar, the jarFile.getInputStream will throw
+ * Security Exception.
+ */
+ public void test_JarFile_Modified_Manifest_EntryAttributes()
+ throws IOException {
+ String modifiedJarName = "Modified_Manifest_EntryAttributes.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = entries.nextElement();
+ try {
+ jarFile.getInputStream(zipEntry);
+ fail("should throw Security Exception");
+ } catch (SecurityException e) {
+ // desired
+ }
+ }
+ }
+
+ /*
+ * If the content of the .SA file is modified, no matter what it resides,
+ * JarFile.getInputStream of any JarEntry will throw Security Exception.
+ */
+ public void test_JarFile_Modified_SF_EntryAttributes() throws IOException {
+ String modifiedJarName = "Modified_SF_EntryAttributes.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = entries.nextElement();
+ try {
+ jarFile.getInputStream(zipEntry);
+ fail("should throw Security Exception");
+ } catch (SecurityException e) {
+ // desired
+ }
+ }
+ }
+
+ public void test_close() throws IOException {
+ String modifiedJarName = "Modified_SF_EntryAttributes.jar";
+ Support_Resources.copyFile(resources, null, modifiedJarName);
+ JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
+ true);
+ Enumeration<JarEntry> entries = jarFile.entries();
+
+ jarFile.close();
+ jarFile.close();
+
+ // Can not check IOException
+ }
+
+ /**
+ * @throws IOException
+ * java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
+ */
+ public void test_getInputStreamLjava_util_jar_JarEntry() throws IOException {
+ File localFile = null;
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ localFile = new File(resources, jarName);
+ } catch (Exception e) {
+ fail("Failed to create local file: " + e);
+ }
+
+ byte[] b = new byte[1024];
+ try {
+ JarFile jf = new JarFile(localFile);
+ java.io.InputStream is = jf.getInputStream(jf.getEntry(entryName));
+ // BEGIN android-removed
+ // jf.close();
+ // END android-removed
+ assertTrue("Returned invalid stream", is.available() > 0);
+ int r = is.read(b, 0, 1024);
+ is.close();
+ StringBuffer sb = new StringBuffer(r);
+ for (int i = 0; i < r; i++) {
+ sb.append((char) (b[i] & 0xff));
+ }
+ String contents = sb.toString();
+ assertTrue("Incorrect stream read", contents.indexOf("bar") > 0);
+ // BEGIN android-added
+ jf.close();
+ // END android-added
+ } catch (Exception e) {
+ fail("Exception during test: " + e.toString());
+ }
+
+ try {
+ JarFile jf = new JarFile(localFile);
+ InputStream in = jf.getInputStream(new JarEntry("invalid"));
+ assertNull("Got stream for non-existent entry", in);
+ } catch (Exception e) {
+ fail("Exception during test 2: " + e);
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ File signedFile = new File(resources, jarName);
+ JarFile jf = new JarFile(signedFile);
+ JarEntry jre = new JarEntry("foo/bar/A.class");
+ jf.getInputStream(jre);
+ // InputStream returned in any way, exception can be thrown in case
+ // of reading from this stream only.
+ // fail("Should throw ZipException");
+ } catch (ZipException ee) {
+ // expected
+ }
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName);
+ File signedFile = new File(resources, jarName);
+ JarFile jf = new JarFile(signedFile);
+ JarEntry jre = new JarEntry("foo/bar/A.class");
+ jf.close();
+ jf.getInputStream(jre);
+ // InputStream returned in any way, exception can be thrown in case
+ // of reading from this stream only.
+ // The same for IOException
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException ee) {
+ // expected
+ }
+ }
+
+ /**
+ * The jar is intact, but the entry object is modified.
+ */
+ // Regression test for issue introduced by HARMONY-4569: signed archives containing files with size 0 could not get verified.
+ public void testJarVerificationEmptyEntry() throws IOException {
+ Support_Resources.copyFile(resources, null, emptyEntryJar);
+ File f = new File(resources, emptyEntryJar);
+
+ JarFile jarFile = new JarFile(f);
+
+ ZipEntry zipEntry = jarFile.getJarEntry(emptyEntry1);
+ int res = jarFile.getInputStream(zipEntry).read(new byte[100], 0, 100);
+ assertEquals("Wrong length of empty jar entry", -1, res);
+
+ zipEntry = jarFile.getJarEntry(emptyEntry2);
+ res = jarFile.getInputStream(zipEntry).read(new byte[100], 0, 100);
+ assertEquals("Wrong length of empty jar entry", -1, res);
+
+ zipEntry = jarFile.getJarEntry(emptyEntry3);
+ res = jarFile.getInputStream(zipEntry).read();
+ assertEquals("Wrong length of empty jar entry", -1, res);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarInputStreamTest.java
new file mode 100644
index 0000000..9d4224a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarInputStreamTest.java
@@ -0,0 +1,406 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.jar;
+
+import tests.support.resource.Support_Resources;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+
+public class JarInputStreamTest extends junit.framework.TestCase {
+
+ private static final int DSA_INDEX = 2;
+
+ private static final int TEST_CLASS_INDEX = 4;
+
+ private static final int TOTAL_ENTRIES = 4;
+
+ private static final String A_CLASS = "foo/bar/A.class";
+
+ // a 'normal' jar file
+ private String jarName;
+
+ // same as patch.jar but without a manifest file
+ private String jarName2;
+
+ @Override
+ protected void setUp() {
+ jarName = Support_Resources.getURL("morestuff/hyts_patch.jar");
+ jarName2 = Support_Resources.getURL("morestuff/hyts_patch2.jar");
+ }
+
+ public void test_ConstructorLjava_io_InputStream() throws Exception {
+ // Test for method java.util.jar.JarInputStream(java.io.InputStream)
+ InputStream is = new URL(jarName).openConnection().getInputStream();
+ boolean hasCorrectEntry = false;
+ JarInputStream jis = new JarInputStream(is);
+ assertNotNull("The jar input stream should have a manifest", jis.getManifest());
+
+ JarEntry je = jis.getNextJarEntry();
+ while (je != null) {
+ if (je.getName().equals(A_CLASS)) {
+ hasCorrectEntry = true;
+ }
+ je = jis.getNextJarEntry();
+ }
+ assertTrue("The jar input stream does not contain the correct entries", hasCorrectEntry);
+ }
+
+ public void test_closeAfterException() throws Exception {
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, "Broken_entry.jar");
+ InputStream is = Support_Resources.getStream("Broken_entry.jar");
+ JarInputStream jis = new JarInputStream(is, false);
+ jis.getNextEntry();
+ try {
+ jis.getNextEntry();
+ fail("ZipException expected");
+ } catch (ZipException ee) {
+ // expected
+ }
+ jis.close();
+ try {
+ jis.getNextEntry();
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+ }
+
+ public void test_getNextJarEntry_Ex() throws Exception {
+ final Set<String> desired = new HashSet<String>(Arrays
+ .asList("foo/", "foo/bar/", "foo/bar/A.class", "Blah.txt"));
+ Set<String> actual = new HashSet<String>();
+ InputStream is = new URL(jarName).openConnection().getInputStream();
+ JarInputStream jis = new JarInputStream(is);
+ JarEntry je = jis.getNextJarEntry();
+ while (je != null) {
+ actual.add(je.toString());
+ je = jis.getNextJarEntry();
+ }
+ assertEquals(actual, desired);
+ jis.close();
+
+ try {
+ jis.getNextJarEntry();
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, "Broken_entry.jar");
+ is = Support_Resources.getStream("Broken_entry.jar");
+ jis = new JarInputStream(is, false);
+ jis.getNextJarEntry();
+ try {
+ jis.getNextJarEntry();
+ fail("ZipException expected");
+ } catch (ZipException ee) {
+ // expected
+ }
+ }
+
+ public void test_getManifest() throws Exception {
+ // Test for method java.util.jar.Manifest
+ // java.util.jar.JarInputStream.getManifest()
+ Manifest m;
+ InputStream is = new URL(jarName2).openConnection().getInputStream();
+ JarInputStream jis = new JarInputStream(is);
+ m = jis.getManifest();
+ assertNull("The jar input stream should not have a manifest", m);
+
+ is = new URL(jarName).openConnection().getInputStream();
+ jis = new JarInputStream(is);
+ m = jis.getManifest();
+ assertNotNull("The jar input stream should have a manifest", m);
+ }
+
+ public void test_getNextJarEntry() throws Exception {
+ final Set<String> desired = new HashSet<String>(Arrays.asList(new String[] { "foo/",
+ "foo/bar/", A_CLASS, "Blah.txt" }));
+ Set<String> actual = new HashSet<String>();
+ InputStream is = new URL(jarName).openConnection().getInputStream();
+ JarInputStream jis = new JarInputStream(is);
+ JarEntry je = jis.getNextJarEntry();
+ while (je != null) {
+ actual.add(je.toString());
+ je = jis.getNextJarEntry();
+ }
+ assertEquals(actual, desired);
+ }
+
+ public void test_JarInputStream_Integrate_Jar_getNextEntry()
+ throws IOException {
+ String intJarName = Support_Resources.getURL("Integrate.jar");
+ InputStream is = new URL(intJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+ ZipEntry entry = null;
+ int count = 0;
+ while (count == 0 || entry != null) {
+ count++;
+ entry = jin.getNextEntry();
+ }
+ assertEquals(TOTAL_ENTRIES + 1, count);
+ jin.close();
+ }
+
+ public void test_JarInputStream_Modified_Class_getNextEntry()
+ throws IOException {
+ String modJarName = Support_Resources.getURL("Modified_Class.jar");
+ InputStream is = new URL(modJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+ ZipEntry zipEntry = null;
+
+ int count = 0;
+ while (count == 0 || zipEntry != null) {
+ count++;
+ try {
+ zipEntry = jin.getNextEntry();
+ if (count == TEST_CLASS_INDEX + 1) {
+ fail("Should throw Security Exception");
+ }
+ } catch (SecurityException e) {
+ if (count != TEST_CLASS_INDEX + 1) {
+ throw e;
+ }
+
+ }
+ }
+ assertEquals(TOTAL_ENTRIES + 2, count);
+ jin.close();
+ }
+
+ public void test_JarInputStream_Modified_Manifest_MainAttributes_getNextEntry()
+ throws IOException {
+ String modJarName = Support_Resources.getURL("Modified_Manifest_MainAttributes.jar");
+ InputStream is = new URL(modJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+
+ assertEquals("META-INF/TESTROOT.SF", jin.getNextEntry().getName());
+ assertEquals("META-INF/TESTROOT.DSA", jin.getNextEntry().getName());
+ try {
+ jin.getNextEntry();
+ fail();
+ } catch (SecurityException expected) {
+ }
+ assertEquals("META-INF/", jin.getNextEntry().getName());
+ assertEquals("Test.class", jin.getNextEntry().getName());
+ assertNull(jin.getNextEntry());
+ jin.close();
+ }
+
+ public void test_JarInputStream_Modified_Manifest_EntryAttributes_getNextEntry()
+ throws IOException {
+ String modJarName = Support_Resources
+ .getURL("Modified_Manifest_EntryAttributes.jar");
+ InputStream is = new URL(modJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+ ZipEntry zipEntry = null;
+
+ int count = 0;
+ while (count == 0 || zipEntry != null) {
+ count++;
+ try {
+ zipEntry = jin.getNextEntry();
+ if (count == DSA_INDEX + 1) {
+ fail("Should throw Security Exception");
+ }
+ } catch (SecurityException e) {
+ if (count != DSA_INDEX + 1) {
+ throw e;
+ }
+ }
+ }
+ assertEquals(TOTAL_ENTRIES + 2, count);
+ jin.close();
+ }
+
+ public void test_JarInputStream_Modified_SF_EntryAttributes_getNextEntry()
+ throws IOException {
+ String modJarName = Support_Resources
+ .getURL("Modified_SF_EntryAttributes.jar");
+ InputStream is = new URL(modJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+ ZipEntry zipEntry = null;
+
+ int count = 0;
+ while (count == 0 || zipEntry != null) {
+ count++;
+ try {
+ zipEntry = jin.getNextEntry();
+ if (count == DSA_INDEX + 1) {
+ fail("Should throw Security Exception");
+ }
+ } catch (SecurityException e) {
+ if (count != DSA_INDEX + 1) {
+ throw e;
+ }
+ }
+ }
+ assertEquals(TOTAL_ENTRIES + 2, count);
+ jin.close();
+ }
+
+ public void test_JarInputStream_Modified_Class_read() throws IOException {
+ String modJarName = Support_Resources.getURL("Modified_Class.jar");
+ InputStream is = new URL(modJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+ int count = 0;
+ ZipEntry zipEntry = null;
+ while (count == 0 || zipEntry != null) {
+ count++;
+ zipEntry = jin.getNextEntry();
+ byte[] buffer = new byte[1024];
+ try {
+ int length = 0;
+ while (length >= 0) {
+ length = jin.read(buffer);
+ }
+ if (count == TEST_CLASS_INDEX) {
+ fail("Should throw Security Exception");
+ }
+ } catch (SecurityException e) {
+ if (count < TEST_CLASS_INDEX) {
+ throw e;
+ }
+ }
+ }
+ assertEquals(TOTAL_ENTRIES + 1, count);
+ jin.close();
+ }
+
+ public void test_Integrate_Jar_read() throws IOException {
+ String intJarName = Support_Resources.getURL("Integrate.jar");
+ InputStream is = new URL(intJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+ int count = 0;
+ ZipEntry zipEntry = null;
+ while (count == 0 || zipEntry != null) {
+ count++;
+ zipEntry = jin.getNextEntry();
+ byte[] buffer = new byte[1024];
+ int length = 0;
+ while (length >= 0) {
+ length = jin.read(buffer);
+ }
+
+ }
+ assertEquals(TOTAL_ENTRIES + 1, count);
+ jin.close();
+ }
+
+ public void test_JarInputStream_Modified_Manifest_MainAttributes_read()
+ throws IOException {
+ String modJarName = Support_Resources
+ .getURL("Modified_Manifest_MainAttributes.jar");
+ InputStream is = new URL(modJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+ int count = 0;
+ ZipEntry zipEntry = null;
+ while (count == 0 || zipEntry != null) {
+ count++;
+ zipEntry = jin.getNextEntry();
+ byte[] buffer = new byte[1024];
+ try {
+ int length = 0;
+ while (length >= 0) {
+ length = jin.read(buffer);
+ }
+ if (count == DSA_INDEX) {
+ fail("Should throw Security Exception");
+ }
+ } catch (SecurityException e) {
+ if (count != DSA_INDEX) {
+ throw e;
+ }
+ }
+ }
+ assertEquals(TOTAL_ENTRIES + 1, count);
+ jin.close();
+ }
+
+ public void test_JarInputStream_Modified_SF_EntryAttributes_read()
+ throws IOException {
+ String modJarName = Support_Resources
+ .getURL("Modified_SF_EntryAttributes.jar");
+ InputStream is = new URL(modJarName).openConnection()
+ .getInputStream();
+ JarInputStream jin = new JarInputStream(is, true);
+ int count = 0;
+ ZipEntry zipEntry = null;
+ while (count == 0 || zipEntry != null) {
+ count++;
+ zipEntry = jin.getNextEntry();
+ byte[] buffer = new byte[1024];
+ try {
+ int length = 0;
+ while (length >= 0) {
+ length = jin.read(buffer);
+ }
+ if (count == DSA_INDEX) {
+ fail("Should throw Security Exception");
+ }
+ } catch (SecurityException e) {
+ if (count != DSA_INDEX) {
+ throw e;
+ }
+ }
+ }
+ assertEquals(TOTAL_ENTRIES + 1, count);
+ jin.close();
+ }
+
+ public void test_getNextEntry() throws Exception {
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, "Broken_entry.jar");
+ InputStream is = Support_Resources.getStream("Broken_entry.jar");
+ JarInputStream jis = new JarInputStream(is, false);
+ jis.getNextEntry();
+ try {
+ jis.getNextEntry();
+ fail("ZipException expected");
+ } catch (ZipException ee) {
+ // expected
+ }
+
+ try {
+ jis.close(); // Android throws exception here, already!
+ jis.getNextEntry(); // But RI here, only!
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarOutputStreamTest.java
new file mode 100644
index 0000000..37750db
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarOutputStreamTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.jar;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.jar.Attributes;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+public class JarOutputStreamTest extends junit.framework.TestCase {
+
+ /**
+ * java.util.jar.JarOutputStream#putNextEntry(java.util.zip.ZipEntry)
+ */
+ public void test_putNextEntryLjava_util_zip_ZipEntry() throws Exception {
+
+ }
+
+ public void test_JarOutputStreamLjava_io_OutputStreamLjava_util_jar_Manifest()
+ throws IOException {
+ File fooJar = File.createTempFile("hyts_", ".jar");
+ fooJar.deleteOnExit();
+ File barZip = File.createTempFile("hyts_", ".zip");
+ barZip.deleteOnExit();
+
+ FileOutputStream fos = new FileOutputStream(fooJar);
+
+ Manifest man = new Manifest();
+ Attributes att = man.getMainAttributes();
+ att.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo");
+ att.put(Attributes.Name.CLASS_PATH, barZip.getName());
+
+ fos.close();
+ try {
+ new JarOutputStream(fos, man);
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+
+ try {
+ new JarOutputStream(fos, null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException ee) {
+ // expected
+ }
+ }
+
+ public void test_JarOutputStreamLjava_io_OutputStream() throws IOException {
+ File fooJar = File.createTempFile("hyts_", ".jar");
+
+ FileOutputStream fos = new FileOutputStream(fooJar);
+ ZipEntry ze = new ZipEntry("Test");
+
+ try {
+ JarOutputStream joutFoo = new JarOutputStream(fos);
+ joutFoo.putNextEntry(ze);
+ joutFoo.write(33);
+ } catch (IOException ee) {
+ fail("IOException is not expected");
+ }
+
+ fos.close();
+ fooJar.delete();
+ try {
+ JarOutputStream joutFoo = new JarOutputStream(fos);
+ joutFoo.putNextEntry(ze);
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/ManifestTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/ManifestTest.java
new file mode 100644
index 0000000..c4d7735
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/ManifestTest.java
@@ -0,0 +1,456 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.jar;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import junit.framework.TestCase;
+
+import tests.support.resource.Support_Resources;
+
+public class ManifestTest extends TestCase {
+
+ private final String JAR_NAME = "hyts_patch.jar";
+
+ private final String ATT_JAR_NAME = "hyts_att.jar";
+
+ private final String ATT_ENTRY_NAME = "HasAttributes.txt";
+
+ private final String ATT_ATT_NAME = "MyAttribute";
+
+ private final String MANIFEST_NAME = "manifest/hyts_MANIFEST.MF";
+
+ private static final String MANIFEST_CONTENTS = "Manifest-Version: 1.0\nBundle-Name: ClientSupport\nBundle-Description: Provides SessionService, AuthenticationService. Extends RegistryService.\nBundle-Activator: com.ibm.ive.eccomm.client.support.ClientSupportActivator\nImport-Package: com.ibm.ive.eccomm.client.services.log,\n com.ibm.ive.eccomm.client.services.registry,\n com.ibm.ive.eccomm.service.registry; specification-version=1.0.0,\n com.ibm.ive.eccomm.service.session; specification-version=1.0.0,\n com.ibm.ive.eccomm.service.framework; specification-version=1.2.0,\n org.osgi.framework; specification-version=1.0.0,\n org.osgi.service.log; specification-version=1.0.0,\n com.ibm.ive.eccomm.flash; specification-version=1.2.0,\n com.ibm.ive.eccomm.client.xml,\n com.ibm.ive.eccomm.client.http.common,\n com.ibm.ive.eccomm.client.http.client\nImport-Service: org.osgi.service.log.LogReaderService\n org.osgi.service.log.LogService,\n com.ibm.ive.eccomm.service.registry.RegistryService\nExport-Package: com.ibm.ive.eccomm.client.services.authentication; specification-version=1.0.0,\n com.ibm.ive.eccomm.service.authentication; specification-version=1.0.0,\n com.ibm.ive.eccomm.common; specification-version=1.0.0,\n com.ibm.ive.eccomm.client.services.registry.store; specification-version=1.0.0\nExport-Service: com.ibm.ive.eccomm.service.authentication.AuthenticationService,\n com.ibm.ive.eccomm.service.session.SessionService\nBundle-Vendor: IBM\nBundle-Version: 1.2.0\n";
+
+ private static final String MANIFEST_CONTENTS_1 = "Manifest-Version: 2.0\nBundle-Name: ClientSupport\nBundle-Description: Provides SessionService, AuthenticationService. Extends RegistryService.\nBundle-Activator: com.ibm.ive.eccomm.client.support.ClientSupportActivator\nImport-Package: com.ibm.ive.eccomm.client.services.log,\n com.ibm.ive.eccomm.client.services.registry,\n com.ibm.ive.eccomm.service.registry; specification-version=2.0.0,\n com.ibm.ive.eccomm.service.session; specification-version=2.0.0,\n com.ibm.ive.eccomm.service.framework; specification-version=2.1.0,\n org.osgi.framework; specification-version=2.0.0,\n org.osgi.service.log; specification-version=2.0.0,\n com.ibm.ive.eccomm.flash; specification-version=2.2.0,\n com.ibm.ive.eccomm.client.xml,\n com.ibm.ive.eccomm.client.http.common,\n com.ibm.ive.eccomm.client.http.client\nImport-Service: org.osgi.service.log.LogReaderService\n org.osgi.service.log.LogService,\n com.ibm.ive.eccomm.service.registry.RegistryService\nExport-Package: com.ibm.ive.eccomm.client.services.authentication; specification-version=1.0.0,\n com.ibm.ive.eccomm.service.authentication; specification-version=1.0.0,\n com.ibm.ive.eccomm.common; specification-version=1.0.0,\n com.ibm.ive.eccomm.client.services.registry.store; specification-version=1.0.0\nExport-Service: com.ibm.ive.eccomm.service.authentication.AuthenticationService,\n com.ibm.ive.eccomm.service.session.SessionService\nBundle-Vendor: IBM\nBundle-Version: 1.2.0\n";
+
+ private static final String MANIFEST_CONTENTS_2 = "Manifest-Version: 1.0\nName: value\n \n"; // Note penultimate line is single space
+
+ private File resources;
+
+ @Override
+ protected void setUp() {
+ resources = Support_Resources.createTempFolder();
+ }
+
+ private Manifest getManifest(String fileName) {
+ try {
+ Support_Resources.copyFile(resources, null, fileName);
+ JarFile jarFile = new JarFile(new File(resources, fileName));
+ Manifest m = jarFile.getManifest();
+ jarFile.close();
+ return m;
+ } catch (Exception e) {
+ fail("Exception during setup: " + e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * java.util.jar.Manifest#Manifest()
+ */
+ public void testConstructor() {
+ // Test for method java.util.jar.Manifest()
+ Manifest emptyManifest = new Manifest();
+ assertTrue("Should have no entries", emptyManifest.getEntries()
+ .isEmpty());
+ assertTrue("Should have no main attributes", emptyManifest
+ .getMainAttributes().isEmpty());
+ }
+
+ /**
+ * java.util.jar.Manifest#Manifest(java.util.jar.Manifest)
+ */
+ public void testCopyingConstructor() throws IOException {
+ Manifest firstManifest = new Manifest(new ByteArrayInputStream(
+ MANIFEST_CONTENTS.getBytes("ISO-8859-1")));
+ Manifest secondManifest = new Manifest(firstManifest);
+ assertEquals(firstManifest, secondManifest);
+ }
+
+ private void assertAttribute(Attributes attr, String name, String value) {
+ assertEquals("Incorrect " + name, value, attr.getValue(name));
+ }
+
+ private void checkManifest(Manifest manifest) {
+ Attributes main = manifest.getMainAttributes();
+ assertAttribute(main, "Bundle-Name", "ClientSupport");
+ assertAttribute(main, "Bundle-Description",
+ "Provides SessionService, AuthenticationService. Extends RegistryService.");
+ assertAttribute(main, "Bundle-Activator",
+ "com.ibm.ive.eccomm.client.support.ClientSupportActivator");
+ assertAttribute(
+ main,
+ "Import-Package",
+ "com.ibm.ive.eccomm.client.services.log,com.ibm.ive.eccomm.client.services.registry,com.ibm.ive.eccomm.service.registry; specification-version=1.0.0,com.ibm.ive.eccomm.service.session; specification-version=1.0.0,com.ibm.ive.eccomm.service.framework; specification-version=1.2.0,org.osgi.framework; specification-version=1.0.0,org.osgi.service.log; specification-version=1.0.0,com.ibm.ive.eccomm.flash; specification-version=1.2.0,com.ibm.ive.eccomm.client.xml,com.ibm.ive.eccomm.client.http.common,com.ibm.ive.eccomm.client.http.client");
+ assertAttribute(
+ main,
+ "Import-Service",
+ "org.osgi.service.log.LogReaderServiceorg.osgi.service.log.LogService,com.ibm.ive.eccomm.service.registry.RegistryService");
+ assertAttribute(
+ main,
+ "Export-Package",
+ "com.ibm.ive.eccomm.client.services.authentication; specification-version=1.0.0,com.ibm.ive.eccomm.service.authentication; specification-version=1.0.0,com.ibm.ive.eccomm.common; specification-version=1.0.0,com.ibm.ive.eccomm.client.services.registry.store; specification-version=1.0.0");
+ assertAttribute(
+ main,
+ "Export-Service",
+ "com.ibm.ive.eccomm.service.authentication.AuthenticationService,com.ibm.ive.eccomm.service.session.SessionService");
+ assertAttribute(main, "Bundle-Vendor", "IBM");
+ assertAttribute(main, "Bundle-Version", "1.2.0");
+ }
+
+ /**
+ * java.util.jar.Manifest#Manifest(java.io.InputStream)
+ */
+ public void testStreamConstructor() throws IOException {
+ Manifest m = getManifest(ATT_JAR_NAME);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ m.write(baos);
+ InputStream is = new ByteArrayInputStream(baos.toByteArray());
+ Manifest mCopy = new Manifest(is);
+ assertEquals(m, mCopy);
+
+ Manifest manifest = new Manifest(new ByteArrayInputStream(
+ MANIFEST_CONTENTS.getBytes("ISO-8859-1")));
+ checkManifest(manifest);
+
+ // regression test for HARMONY-5424
+ String manifestContent = "Manifest-Version: 1.0\nCreated-By: Apache\nPackage: \nBuild-Jdk: 1.4.1_01\n\n"
+ + "Name: \nSpecification-Title: foo\nSpecification-Version: 1.0\nSpecification-Vendor: \n"
+ + "Implementation-Title: \nImplementation-Version: 1.0\nImplementation-Vendor: \n\n";
+ ByteArrayInputStream bis = new ByteArrayInputStream(manifestContent
+ .getBytes("ISO-8859-1"));
+
+
+ Manifest mf = new Manifest(bis);
+ assertEquals("Should be 4 main attributes", 4, mf.getMainAttributes()
+ .size());
+
+ Map<String, Attributes> entries = mf.getEntries();
+ assertEquals("Should be one named entry", 1, entries.size());
+
+ Attributes namedEntryAttributes = (Attributes) (entries.get(""));
+ assertEquals("Should be 6 named entry attributes", 6,
+ namedEntryAttributes.size());
+
+ // Regression test for HARMONY-6669
+ new Manifest(new ByteArrayInputStream(
+ MANIFEST_CONTENTS_2.getBytes("ISO-8859-1")));
+ }
+
+ /**
+ * java.util.jar.Manifest#clear()
+ */
+ public void testClear() {
+ Manifest m = getManifest(ATT_JAR_NAME);
+ m.clear();
+ assertTrue("Should have no entries", m.getEntries().isEmpty());
+ assertTrue("Should have no main attributes", m.getMainAttributes()
+ .isEmpty());
+ }
+
+ /**
+ * java.util.jar.Manifest#clone()
+ */
+ public void testClone() {
+ Manifest m = getManifest(JAR_NAME);
+ assertEquals(m, m.clone());
+ }
+
+ /**
+ * java.util.jar.Manifest#equals(java.lang.Object)
+ */
+ public void testEquals() throws IOException {
+ Manifest firstManifest = new Manifest(new ByteArrayInputStream(
+ MANIFEST_CONTENTS.getBytes("ISO-8859-1")));
+ Manifest secondManifest = new Manifest(new ByteArrayInputStream(
+ MANIFEST_CONTENTS.getBytes("ISO-8859-1")));
+
+ assertEquals(firstManifest, secondManifest);
+
+ Manifest thirdManifest = new Manifest(new ByteArrayInputStream(
+ MANIFEST_CONTENTS_1.getBytes("ISO-8859-1")));
+ assertNotSame(firstManifest, thirdManifest);
+
+ firstManifest = null;
+ assertFalse(secondManifest.equals(firstManifest));
+ assertFalse(secondManifest.equals(new String("abc"))); //non Manifest Object
+ }
+
+ /**
+ * java.util.jar.Manifest#hashCode()
+ */
+ public void testHashCode() {
+ Manifest m = getManifest(JAR_NAME);
+ assertEquals(m.hashCode(), m.clone().hashCode());
+ }
+
+ /**
+ * java.util.jar.Manifest#getAttributes(java.lang.String)
+ */
+ public void testGetAttributes() {
+ Manifest m = getManifest(ATT_JAR_NAME);
+ assertNull("Should not exist", m.getAttributes("Doesn't Exist"));
+ assertEquals("Should exist", "OK", m.getAttributes(ATT_ENTRY_NAME).get(
+ new Attributes.Name(ATT_ATT_NAME)));
+ }
+
+ /**
+ * java.util.jar.Manifest#getEntries()
+ */
+ public void testGetEntries() {
+ Manifest m = getManifest(ATT_JAR_NAME);
+ Map<String, Attributes> myMap = m.getEntries();
+ assertNull("Shouldn't exist", myMap.get("Doesn't exist"));
+ assertEquals("Should exist", "OK", myMap.get(ATT_ENTRY_NAME).get(
+ new Attributes.Name(ATT_ATT_NAME)));
+ }
+
+ /**
+ * java.util.jar.Manifest#getMainAttributes()
+ */
+ public void testGetMainAttributes() {
+ Manifest m = getManifest(JAR_NAME);
+ Attributes a = m.getMainAttributes();
+ assertEquals("Manifest_Version should return 1.0", "1.0", a
+ .get(Attributes.Name.MANIFEST_VERSION));
+ }
+
+ /**
+ * {@link java.util.jar.Manifest#write(java.io.OutputStream)
+ */
+ public void testWrite() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Manifest m = getManifest(JAR_NAME);
+ // maximum allowed length is 72 for a header, colon and a following
+ // space
+ StringBuffer headerName = new StringBuffer(71);
+ headerName.append("Manifest-");
+ while (headerName.length() < 70) {
+ headerName.append("0");
+ }
+ m.getMainAttributes().put(new Attributes.Name(headerName.toString()),
+ "Value");
+ m.write(baos); // ok
+ }
+
+ /**
+ * Ensures compatibility with manifests produced by gcc.
+ *
+ * @see <a
+ * href="http://issues.apache.org/jira/browse/HARMONY-5662">HARMONY-5662</a>
+ */
+ public void testNul() throws IOException {
+ String manifestContent =
+ "Manifest-Version: 1.0\nCreated-By: nasty gcc tool\n\n\0";
+
+ byte[] bytes = manifestContent.getBytes("ISO-8859-1");
+ new Manifest(new ByteArrayInputStream(bytes)); // the last NUL is ok
+
+ bytes[bytes.length - 1] = 26;
+ new Manifest(new ByteArrayInputStream(bytes)); // the last EOF is ok
+
+ bytes[bytes.length - 1] = 'A'; // the last line ignored
+ new Manifest(new ByteArrayInputStream(bytes));
+
+ bytes[2] = 0; // NUL char in Manifest
+ try {
+ new Manifest(new ByteArrayInputStream(bytes));
+ fail("IOException expected");
+ } catch (IOException e) {
+ // desired
+ }
+ }
+
+ public void testDecoding() throws IOException {
+ Manifest m = getManifest(ATT_JAR_NAME);
+ final byte[] bVendor = new byte[] { (byte) 0xd0, (byte) 0x9C,
+ (byte) 0xd0, (byte) 0xb8, (byte) 0xd0, (byte) 0xbb,
+ (byte) 0xd0, (byte) 0xb0, (byte) 0xd1, (byte) 0x8f, ' ',
+ (byte) 0xd0, (byte) 0xb4, (byte) 0xd0, (byte) 0xbe,
+ (byte) 0xd1, (byte) 0x87, (byte) 0xd1, (byte) 0x83,
+ (byte) 0xd0, (byte) 0xbd, (byte) 0xd1, (byte) 0x8C,
+ (byte) 0xd0, (byte) 0xba, (byte) 0xd0, (byte) 0xb0, ' ',
+ (byte) 0xd0, (byte) 0x9C, (byte) 0xd0, (byte) 0xb0,
+ (byte) 0xd1, (byte) 0x88, (byte) 0xd0, (byte) 0xb0 };
+
+ final byte[] bSpec = new byte[] { (byte) 0xe1, (byte) 0x88,
+ (byte) 0xb0, (byte) 0xe1, (byte) 0x88, (byte) 0x8b,
+ (byte) 0xe1, (byte) 0x88, (byte) 0x9d, ' ', (byte) 0xe1,
+ (byte) 0x9a, (byte) 0xa0, (byte) 0xe1, (byte) 0x9a,
+ (byte) 0xb1, (byte) 0xe1, (byte) 0x9b, (byte) 0x81,
+ (byte) 0xe1, (byte) 0x9a, (byte) 0xa6, ' ', (byte) 0xd8,
+ (byte) 0xb3, (byte) 0xd9, (byte) 0x84, (byte) 0xd8,
+ (byte) 0xa7, (byte) 0xd9, (byte) 0x85, ' ', (byte) 0xd8,
+ (byte) 0xb9, (byte) 0xd8, (byte) 0xb3, (byte) 0xd9,
+ (byte) 0x84, (byte) 0xd8, (byte) 0xa7, (byte) 0xd9,
+ (byte) 0x85, (byte) 0xd8, (byte) 0xa9, ' ', (byte) 0xdc,
+ (byte) 0xab, (byte) 0xdc, (byte) 0xa0, (byte) 0xdc,
+ (byte) 0xa1, (byte) 0xdc, (byte) 0x90, ' ', (byte) 0xe0,
+ (byte) 0xa6, (byte) 0xb6, (byte) 0xe0, (byte) 0xa6,
+ (byte) 0xbe, (byte) 0xe0, (byte) 0xa6, (byte) 0xa8,
+ (byte) 0xe0, (byte) 0xa7, (byte) 0x8d, (byte) 0xe0,
+ (byte) 0xa6, (byte) 0xa4, (byte) 0xe0, (byte) 0xa6,
+ (byte) 0xbf, ' ', (byte) 0xd0, (byte) 0xa0, (byte) 0xd0,
+ (byte) 0xb5, (byte) 0xd0, (byte) 0xba, (byte) 0xd1,
+ (byte) 0x8a, (byte) 0xd0, (byte) 0xb5, (byte) 0xd0,
+ (byte) 0xbb, ' ', (byte) 0xd0, (byte) 0x9c, (byte) 0xd0,
+ (byte) 0xb8, (byte) 0xd1, (byte) 0x80, ' ', (byte) 0xe0,
+ (byte) 0xa6, (byte) 0xb6, (byte) 0xe0, (byte) 0xa6,
+ (byte) 0xbe, (byte) 0xe0, (byte) 0xa6, (byte) 0xa8,
+ (byte) 0xe0, (byte) 0xa7, (byte) 0x8d, (byte) 0xe0,
+ (byte) 0xa6, (byte) 0xa4, (byte) 0xe0, (byte) 0xa6,
+ (byte) 0xbf, ' ', (byte) 0xe0, (byte) 0xbd, (byte) 0x9e,
+ (byte) 0xe0, (byte) 0xbd, (byte) 0xb2, (byte) 0xe0,
+ (byte) 0xbc, (byte) 0x8b, (byte) 0xe0, (byte) 0xbd,
+ (byte) 0x96, (byte) 0xe0, (byte) 0xbd, (byte) 0x91,
+ (byte) 0xe0, (byte) 0xbd, (byte) 0xba, ' ', (byte) 0xd0,
+ (byte) 0x9c, (byte) 0xd0, (byte) 0xb0, (byte) 0xd1,
+ (byte) 0x88, (byte) 0xd0, (byte) 0xb0, (byte) 0xd1,
+ (byte) 0x80, ' ', (byte) 0xe1, (byte) 0x8f, (byte) 0x99,
+ (byte) 0xe1, (byte) 0x8e, (byte) 0xaf, (byte) 0xe1,
+ (byte) 0x8f, (byte) 0xb1, ' ', (byte) 0xcf, (byte) 0xa8,
+ (byte) 0xce, (byte) 0xb9, (byte) 0xcf, (byte) 0x81,
+ (byte) 0xce, (byte) 0xb7, (byte) 0xce, (byte) 0xbd,
+ (byte) 0xce, (byte) 0xb7, ' ', (byte) 0xde, (byte) 0x90,
+ (byte) 0xde, (byte) 0xaa, (byte) 0xde, (byte) 0x85,
+ (byte) 0xde, (byte) 0xa6, ' ', (byte) 0xe0, (byte) 0xbd,
+ (byte) 0x82, (byte) 0xe0, (byte) 0xbd, (byte) 0x9e,
+ (byte) 0xe0, (byte) 0xbd, (byte) 0xb2, (byte) 0xe0,
+ (byte) 0xbc, (byte) 0x8b, (byte) 0xe0, (byte) 0xbd,
+ (byte) 0x96, (byte) 0xe0, (byte) 0xbd, (byte) 0x91,
+ (byte) 0xe0, (byte) 0xbd, (byte) 0xba, ' ', (byte) 0xce,
+ (byte) 0x95, (byte) 0xce, (byte) 0xb9, (byte) 0xcf,
+ (byte) 0x81, (byte) 0xce, (byte) 0xae, (byte) 0xce,
+ (byte) 0xbd, (byte) 0xce, (byte) 0xb7, ' ', (byte) 0xd8,
+ (byte) 0xb5, (byte) 0xd9, (byte) 0x84, (byte) 0xd8,
+ (byte) 0xad, ' ', (byte) 0xe0, (byte) 0xaa, (byte) 0xb6,
+ (byte) 0xe0, (byte) 0xaa, (byte) 0xbe, (byte) 0xe0,
+ (byte) 0xaa, (byte) 0x82, (byte) 0xe0, (byte) 0xaa,
+ (byte) 0xa4, (byte) 0xe0, (byte) 0xaa, (byte) 0xbf, ' ',
+ (byte) 0xe5, (byte) 0xb9, (byte) 0xb3, (byte) 0xe5,
+ (byte) 0x92, (byte) 0x8c, ' ', (byte) 0xd7, (byte) 0xa9,
+ (byte) 0xd7, (byte) 0x9c, (byte) 0xd7, (byte) 0x95,
+ (byte) 0xd7, (byte) 0x9d, ' ', (byte) 0xd7, (byte) 0xa4,
+ (byte) 0xd7, (byte) 0xa8, (byte) 0xd7, (byte) 0x99,
+ (byte) 0xd7, (byte) 0x93, (byte) 0xd7, (byte) 0x9f, ' ',
+ (byte) 0xe5, (byte) 0x92, (byte) 0x8c, (byte) 0xe5,
+ (byte) 0xb9, (byte) 0xb3, ' ', (byte) 0xe5, (byte) 0x92,
+ (byte) 0x8c, (byte) 0xe5, (byte) 0xb9, (byte) 0xb3, ' ',
+ (byte) 0xd8, (byte) 0xaa, (byte) 0xd9, (byte) 0x89,
+ (byte) 0xd9, (byte) 0x86, (byte) 0xda, (byte) 0x86,
+ (byte) 0xd9, (byte) 0x84, (byte) 0xd9, (byte) 0x89,
+ (byte) 0xd9, (byte) 0x82, ' ', (byte) 0xe0, (byte) 0xae,
+ (byte) 0x85, (byte) 0xe0, (byte) 0xae, (byte) 0xae,
+ (byte) 0xe0, (byte) 0xaf, (byte) 0x88, (byte) 0xe0,
+ (byte) 0xae, (byte) 0xa4, (byte) 0xe0, (byte) 0xae,
+ (byte) 0xbf, ' ', (byte) 0xe0, (byte) 0xb0, (byte) 0xb6,
+ (byte) 0xe0, (byte) 0xb0, (byte) 0xbe, (byte) 0xe0,
+ (byte) 0xb0, (byte) 0x82, (byte) 0xe0, (byte) 0xb0,
+ (byte) 0xa4, (byte) 0xe0, (byte) 0xb0, (byte) 0xbf, ' ',
+ (byte) 0xe0, (byte) 0xb8, (byte) 0xaa, (byte) 0xe0,
+ (byte) 0xb8, (byte) 0xb1, (byte) 0xe0, (byte) 0xb8,
+ (byte) 0x99, (byte) 0xe0, (byte) 0xb8, (byte) 0x95,
+ (byte) 0xe0, (byte) 0xb8, (byte) 0xb4, (byte) 0xe0,
+ (byte) 0xb8, (byte) 0xa0, (byte) 0xe0, (byte) 0xb8,
+ (byte) 0xb2, (byte) 0xe0, (byte) 0xb8, (byte) 0x9e, ' ',
+ (byte) 0xe1, (byte) 0x88, (byte) 0xb0, (byte) 0xe1,
+ (byte) 0x88, (byte) 0x8b, (byte) 0xe1, (byte) 0x88,
+ (byte) 0x9d, ' ', (byte) 0xe0, (byte) 0xb7, (byte) 0x83,
+ (byte) 0xe0, (byte) 0xb7, (byte) 0x8f, (byte) 0xe0,
+ (byte) 0xb6, (byte) 0xb8, (byte) 0xe0, (byte) 0xb6,
+ (byte) 0xba, ' ', (byte) 0xe0, (byte) 0xa4, (byte) 0xb6,
+ (byte) 0xe0, (byte) 0xa4, (byte) 0xbe, (byte) 0xe0,
+ (byte) 0xa4, (byte) 0xa8, (byte) 0xe0, (byte) 0xa5,
+ (byte) 0x8d, (byte) 0xe0, (byte) 0xa4, (byte) 0xa4,
+ (byte) 0xe0, (byte) 0xa4, (byte) 0xbf, (byte) 0xe0,
+ (byte) 0xa4, (byte) 0x83, ' ', (byte) 0xe1, (byte) 0x83,
+ (byte) 0x9b, (byte) 0xe1, (byte) 0x83, (byte) 0xa8,
+ (byte) 0xe1, (byte) 0x83, (byte) 0x95, (byte) 0xe1,
+ (byte) 0x83, (byte) 0x98, (byte) 0xe1, (byte) 0x83,
+ (byte) 0x93, (byte) 0xe1, (byte) 0x83, (byte) 0x9d,
+ (byte) 0xe1, (byte) 0x83, (byte) 0x91, (byte) 0xe1,
+ (byte) 0x83, (byte) 0x90 };
+ // TODO Cannot make the following word work, encoder changes needed
+ // (byte) 0xed, (byte) 0xa0, (byte) 0x80,
+ // (byte) 0xed, (byte) 0xbc, (byte) 0xb2, (byte) 0xed,
+ // (byte) 0xa0, (byte) 0x80, (byte) 0xed, (byte) 0xbc,
+ // (byte) 0xb0, (byte) 0xed, (byte) 0xa0, (byte) 0x80,
+ // (byte) 0xed, (byte) 0xbd, (byte) 0x85, (byte) 0xed,
+ // (byte) 0xa0, (byte) 0x80, (byte) 0xed, (byte) 0xbc,
+ // (byte) 0xb0, (byte) 0xed, (byte) 0xa0, (byte) 0x80,
+ // (byte) 0xed, (byte) 0xbc, (byte) 0xb9, (byte) 0xed,
+ // (byte) 0xa0, (byte) 0x80, (byte) 0xed, (byte) 0xbc,
+ // (byte) 0xb8, (byte) 0xed, (byte) 0xa0, (byte) 0x80,
+ // (byte) 0xed, (byte) 0xbc, (byte) 0xb9, ' '
+
+ final String vendor = new String(bVendor, "UTF-8");
+ final String spec = new String(bSpec, "UTF-8");
+ m.getMainAttributes()
+ .put(Attributes.Name.IMPLEMENTATION_VENDOR, vendor);
+ m.getAttributes(ATT_ENTRY_NAME).put(
+ Attributes.Name.IMPLEMENTATION_VENDOR, vendor);
+ m.getEntries().get(ATT_ENTRY_NAME).put(
+ Attributes.Name.SPECIFICATION_TITLE, spec);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ m.write(baos);
+ m = new Manifest(new ByteArrayInputStream(baos.toByteArray()));
+
+ assertEquals(vendor, m.getMainAttributes().get(
+ Attributes.Name.IMPLEMENTATION_VENDOR));
+ assertEquals(vendor, m.getEntries().get(ATT_ENTRY_NAME).get(
+ Attributes.Name.IMPLEMENTATION_VENDOR));
+ assertEquals(spec, m.getAttributes(ATT_ENTRY_NAME).get(
+ Attributes.Name.SPECIFICATION_TITLE));
+ }
+
+ /**
+ * {@link java.util.jar.Manifest#read(java.io.InputStream)
+ */
+ public void testRead() {
+ // Regression for HARMONY-89
+ InputStream is = new InputStreamImpl();
+ try {
+ new Manifest().read(is);
+ fail("IOException expected");
+ } catch (IOException e) {
+ // desired
+ }
+ }
+
+ // helper class
+ private class InputStreamImpl extends InputStream {
+ public InputStreamImpl() {
+ super();
+ }
+
+ @Override
+ public int read() {
+ return 0;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/AbstractPreferencesTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/AbstractPreferencesTest.java
new file mode 100644
index 0000000..98476f5
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/AbstractPreferencesTest.java
@@ -0,0 +1,1699 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.prefs.AbstractPreferences;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.FilePreferencesImpl;
+import java.util.prefs.NodeChangeEvent;
+import java.util.prefs.NodeChangeListener;
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import junit.framework.TestCase;
+import libcore.io.IoUtils;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+public class AbstractPreferencesTest extends TestCase {
+
+ public static final class TestPreferencesFactory implements PreferencesFactory {
+ private final Preferences userPrefs;
+ private final Preferences systemPrefs;
+
+ public TestPreferencesFactory(String root) {
+ userPrefs = new FilePreferencesImpl(root + "/user", true);
+ systemPrefs = new FilePreferencesImpl(root + "/system", false);
+ }
+
+ public Preferences userRoot() {
+ return userPrefs;
+ }
+
+ public Preferences systemRoot() {
+ return systemPrefs;
+ }
+ }
+
+ private AbstractPreferences pref;
+ private AbstractPreferences root;
+ private AbstractPreferences parent;
+ private PreferencesFactory defaultFactory;
+
+ private final static String LONG_KEY;
+ private final static String LONG_VALUE;
+ private final static String LONG_NAME;
+
+ static {
+ final byte[] chars = new byte[Preferences.MAX_VALUE_LENGTH];
+
+ LONG_VALUE = new String(chars, StandardCharsets.US_ASCII);
+ LONG_KEY = LONG_VALUE.substring(0, Preferences.MAX_KEY_LENGTH);
+ LONG_NAME = LONG_VALUE.substring(0, Preferences.MAX_NAME_LENGTH);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ File tmpDir = IoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
+ defaultFactory = Preferences.setPreferencesFactory(
+ new TestPreferencesFactory(tmpDir.getAbsolutePath()));
+ root = (AbstractPreferences) Preferences.userRoot();
+ parent = (AbstractPreferences) Preferences.userNodeForPackage(Preferences.class);
+
+ pref = (AbstractPreferences) parent.node("mock");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ Preferences.setPreferencesFactory(defaultFactory);
+ }
+
+ public void testConstructor() throws BackingStoreException {
+ try {
+ pref = new MockAbstractPreferences(
+ (AbstractPreferences) Preferences.userRoot(), "mo/ck");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ pref = new MockAbstractPreferences(null, "mock");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ new MockAbstractPreferences(null, " ");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ new MockAbstractPreferences(pref, "");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ new MockAbstractPreferences(pref, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ new MockAbstractPreferences(pref, " ");
+
+ Preferences p2 = new MockAbstractPreferences(null, "");
+ assertNotSame(p2, Preferences.systemRoot());
+ assertNotSame(p2, Preferences.userRoot());
+ assertFalse(p2.isUserNode());
+
+ p2 = new MockAbstractPreferences((AbstractPreferences) Preferences
+ .userRoot(), "mock");
+ assertNotSame(p2, pref);
+ p2.removeNode();
+ }
+
+ public void testProtectedFields() throws BackingStoreException {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = new MockAbstractPreferences(pref, "newNode");
+ assertFalse(p.getNewNode());
+ assertSame(p.getLock().getClass(), Object.class);
+
+ p = (MockAbstractPreferences) pref.node("child");
+ assertTrue(p.getNewNode());
+
+ p = (MockAbstractPreferences) ((MockAbstractPreferences) pref)
+ .publicChildSpi("child2");
+ assertTrue(p.getNewNode());
+ }
+
+ public void testToString() {
+ assertEquals("User Preference Node: " + pref.absolutePath(), pref
+ .toString());
+
+ pref = new MockAbstractPreferences((AbstractPreferences) Preferences
+ .systemRoot(), "mock");
+ assertEquals("System Preference Node: " + pref.absolutePath(), pref
+ .toString());
+ }
+
+ public void testAbsolutePath() {
+ assertEquals("/java/util/prefs/mock", pref.absolutePath());
+
+ pref = new MockAbstractPreferences(pref, " ");
+ assertEquals("/java/util/prefs/mock/ ", pref.absolutePath());
+ }
+
+ public void testChildrenNames() throws BackingStoreException {
+ assertEquals(0, pref.childrenNames().length);
+
+ // MockAbstractPreferences child1 = new MockAbstractPreferences(pref,
+ // "child1");
+ // MockAbstractPreferences child2 = new MockAbstractPreferences(pref,
+ // "child2");
+ // MockAbstractPreferences child3 = new MockAbstractPreferences(pref,
+ // "child3");
+ // MockAbstractPreferences subchild1 = new
+ // MockAbstractPreferences(child1,
+ // "subchild1");
+ Preferences child1 = pref.node("child1");
+
+ pref.node("child2");
+ pref.node("child3");
+ child1.node("subchild1");
+
+ assertSame(pref, child1.parent());
+ assertEquals(3, pref.childrenNames().length);
+ }
+
+ public void testClear() throws BackingStoreException {
+ pref.put("testClearKey", "testClearValue");
+ pref.put("testClearKey1", "testClearValue1");
+ assertEquals("testClearValue", pref.get("testClearKey", null));
+ assertEquals("testClearValue1", pref.get("testClearKey1", null));
+ pref.clear();
+ assertNull(pref.get("testClearKey", null));
+ assertNull(pref.get("testClearKey1", null));
+ }
+
+ public void testGet() throws BackingStoreException {
+ assertNull(pref.get("", null));
+ assertEquals("default", pref.get("key", "default"));
+ assertNull(pref.get("key", null));
+ pref.put("testGetkey", "value");
+ assertNull(pref.get("testGetKey", null));
+ assertEquals("value", pref.get("testGetkey", null));
+
+ try {
+ pref.get(null, "abc");
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.get("", "abc");
+ pref.get("key", null);
+ pref.get("key", "");
+ pref.putFloat("floatKey", 1.0f);
+ assertEquals("1.0", pref.get("floatKey", null));
+
+ pref.removeNode();
+ try {
+ pref.get("key", "abc");
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.get(null, "abc");
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testGetBoolean() {
+ try {
+ pref.getBoolean(null, false);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.put("testGetBooleanKey", "false");
+ pref.put("testGetBooleanKey2", "value");
+ assertFalse(pref.getBoolean("testGetBooleanKey", true));
+ assertTrue(pref.getBoolean("testGetBooleanKey2", true));
+ }
+
+ public void testPutByteArray() {
+ try {
+ pref.putByteArray(null, new byte[0]);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ pref.putByteArray("testPutByteArrayKey4", null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.putByteArray(LONG_KEY, new byte[0]);
+ try {
+ pref.putByteArray(LONG_KEY + "a", new byte[0]);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ byte[] longArray = new byte[(int) (Preferences.MAX_VALUE_LENGTH * 0.74)];
+ byte[] longerArray = new byte[(int) (Preferences.MAX_VALUE_LENGTH * 0.75) + 1];
+ pref.putByteArray(LONG_KEY, longArray);
+ try {
+ pref.putByteArray(LONG_KEY, longerArray);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ pref.putByteArray("testPutByteArrayKey", new byte[0]);
+ assertEquals("", pref.get("testPutByteArrayKey", null));
+ assertTrue(Arrays.equals(new byte[0], pref.getByteArray(
+ "testPutByteArrayKey", null)));
+
+ pref.putByteArray("testPutByteArrayKey3", new byte[] { 'a', 'b', 'c' });
+ assertEquals("YWJj", pref.get("testPutByteArrayKey3", null));
+ assertTrue(Arrays.equals(new byte[] { 'a', 'b', 'c' }, pref
+ .getByteArray("testPutByteArrayKey3", null)));
+ }
+
+ public void testGetByteArray() throws UnsupportedEncodingException {
+ try {
+ pref.getByteArray(null, new byte[0]);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ byte[] b64Array = new byte[] { 0x59, 0x57, 0x4a, 0x6a };// BASE64
+ // encoding for
+ // "abc"
+
+ pref.put("testGetByteArrayKey", "abc=");
+ pref.put("testGetByteArrayKey2", new String(b64Array, "UTF-8"));
+ pref.put("invalidKey", "<>?");
+ // assertTrue(Arrays.equals(new byte[0], p.getByteArray(
+ // "testGetByteArrayKey", new byte[0])));
+ assertTrue(Arrays.equals(new byte[] { 105, -73 }, pref.getByteArray(
+ "testGetByteArrayKey", new byte[0])));
+ assertTrue(Arrays.equals(new byte[] { 'a', 'b', 'c' }, pref
+ .getByteArray("testGetByteArrayKey2", new byte[0])));
+ assertTrue(Arrays.equals(new byte[0], pref.getByteArray("invalidKey",
+ new byte[0])));
+
+ pref.putByteArray("testGetByteArrayKey3", b64Array);
+ pref.putByteArray("testGetByteArrayKey4", "abc".getBytes());
+ assertTrue(Arrays.equals(b64Array, pref.getByteArray(
+ "testGetByteArrayKey3", new byte[0])));
+ assertTrue(Arrays.equals("abc".getBytes(), pref.getByteArray(
+ "testGetByteArrayKey4", new byte[0])));
+ }
+
+ public void testGetDouble() {
+ try {
+ pref.getDouble(null, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.put("testGetDoubleKey", "1");
+ pref.put("testGetDoubleKey2", "value");
+ pref.putDouble("testGetDoubleKey3", 1);
+ pref.putInt("testGetDoubleKey4", 1);
+ assertEquals(1.0, pref.getDouble("testGetDoubleKey", 0.0), 0);
+ assertEquals(0.0, pref.getDouble("testGetDoubleKey2", 0.0), 0);
+ assertEquals(1.0, pref.getDouble("testGetDoubleKey3", 0.0), 0);
+ assertEquals(1.0, pref.getDouble("testGetDoubleKey4", 0.0), 0);
+ }
+
+ public void testGetFloat() {
+ try {
+ pref.getFloat(null, 0f);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ pref.put("testGetFloatKey", "1");
+ pref.put("testGetFloatKey2", "value");
+ assertEquals(1f, pref.getFloat("testGetFloatKey", 0f), 0); //$NON-NLS-1$
+ assertEquals(0f, pref.getFloat("testGetFloatKey2", 0f), 0);
+ }
+
+ public void testGetInt() {
+ try {
+ pref.getInt(null, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.put("testGetIntKey", "1");
+ pref.put("testGetIntKey2", "value");
+ assertEquals(1, pref.getInt("testGetIntKey", 0));
+ assertEquals(0, pref.getInt("testGetIntKey2", 0));
+ }
+
+ public void testGetLong() {
+ try {
+ pref.getLong(null, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.put("testGetLongKey", "1");
+ pref.put("testGetLongKey2", "value");
+ assertEquals(1, pref.getInt("testGetLongKey", 0));
+ assertEquals(0, pref.getInt("testGetLongKey2", 0));
+ }
+
+ public void testIsUserNode() {
+ assertTrue(pref.isUserNode());
+
+ pref = new MockAbstractPreferences((AbstractPreferences) Preferences
+ .systemRoot(), "mock");
+ assertFalse(pref.isUserNode());
+ }
+
+ // TODO, how to test the "stored defaults"
+ // TODO, how to test the multi-thread
+ public void testKeys() throws BackingStoreException {
+ assertEquals(0, pref.keys().length);
+
+ pref.put("key0", "value");
+ pref.put("key1", "value1");
+ pref.put("key2", "value2");
+ pref.put("key3", "value3");
+
+ String[] keys = pref.keys();
+ assertEquals(4, keys.length);
+ for (int i = 0; i < keys.length; i++) {
+ assertEquals(0, keys[i].indexOf("key"));
+ assertEquals(4, keys[i].length());
+ }
+ }
+
+ public void testName() {
+ assertEquals("mock", pref.name());
+
+ pref = new MockAbstractPreferences(pref, " ");
+ assertEquals(" ", pref.name());
+ }
+
+ public void testCharCase() throws BackingStoreException {
+ assertSame(pref.node("samechild"), pref.node("samechild"));
+ assertNotSame(pref.node("sameChild"), pref.node("samechild"));
+ assertNotSame(pref.node("child"), pref.node("Child"));
+ assertNotSame(pref.node("child"), pref.node("Child"));
+ assertNotSame(pref.node("child"), pref.node(" child"));
+ String[] names = pref.childrenNames();
+ assertEquals(5, names.length);
+ for (int i = 0; i < names.length; i++) {
+ String name = names[i];
+ assertTrue("samechild".equals(name) || "sameChild".equals(name)
+ || "child".equals(name) || "Child".equals(name)
+ || " child".equals(name));
+ }
+
+ Preferences mock1 = pref.node("mock1");
+ mock1.put("key", "1value");
+ mock1.put("KEY", "2value");
+ mock1.put("/K/E/Y", "7value");
+ mock1.put("/K/E\\Y\\abc~@!#$%^&*(\\", "8value");
+
+ assertEquals("8value", mock1.get("/K/E\\Y\\abc~@!#$%^&*(\\", null));
+ assertNull(mock1.get("/k/e/y", null));
+ assertEquals("7value", mock1.get("/K/E/Y", null));
+ assertEquals("1value", mock1.get("key", null));
+
+ String[] keys = mock1.keys();
+ assertEquals(4, keys.length);
+ for (int i = 0; i < keys.length; i++) {
+ String key = keys[i];
+ assertTrue("key".equals(key) || "KEY".equals(key)
+ || "/K/E/Y".equals(key)
+ || "/K/E\\Y\\abc~@!#$%^&*(\\".equals(key));
+ }
+ }
+
+ public void testNode() throws BackingStoreException {
+ try {
+ pref.node(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ pref.node("/java/util/prefs/");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ pref.node("/java//util/prefs");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ pref.node(LONG_NAME + "a");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ assertNotNull(pref.node(LONG_NAME));
+
+ assertSame(root, pref.node("/"));
+
+ Preferences prefs = pref.node("/java/util/prefs");
+ assertSame(prefs, parent);
+
+ assertSame(pref, pref.node(""));
+
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences child = (MockAbstractPreferences) ((MockAbstractPreferences) pref)
+ .publicChildSpi("child");
+ assertSame(child, pref.node("child"));
+
+ Preferences child2 = pref.node("child2");
+ assertSame(child2, ((MockAbstractPreferences) pref)
+ .publicChildSpi("child2"));
+
+ Preferences grandchild = pref.node("child/grandchild");
+ assertSame(grandchild, child.childSpi("grandchild"));
+ assertSame(grandchild, child.cachedChildrenImpl()[0]);
+ grandchild.removeNode();
+ assertNotSame(grandchild, pref.node("child/grandchild"));
+
+ grandchild = pref.node("child3/grandchild");
+ AbstractPreferences[] childs = ((MockAbstractPreferences) pref)
+ .cachedChildrenImpl();
+ Preferences child3 = child;
+ for (int i = 0; i < childs.length; i++) {
+ if (childs[i].name().equals("child3")) {
+ child3 = childs[i];
+ break;
+ }
+ }
+ assertSame(child3, grandchild.parent());
+ }
+
+ public void testNodeExists() throws BackingStoreException {
+ try {
+ pref.nodeExists(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ pref.nodeExists("/java/util/prefs/");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ pref.nodeExists("/java//util/prefs");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ assertTrue(pref.nodeExists("/"));
+
+ assertTrue(pref.nodeExists("/java/util/prefs"));
+
+ assertTrue(pref.nodeExists(""));
+
+ assertFalse(pref.nodeExists("child"));
+ Preferences grandchild = pref.node("child/grandchild");
+ assertTrue(pref.nodeExists("child"));
+ assertTrue(pref.nodeExists("child/grandchild"));
+ grandchild.removeNode();
+ assertTrue(pref.nodeExists("child"));
+ assertFalse(pref.nodeExists("child/grandchild"));
+ assertFalse(grandchild.nodeExists(""));
+
+ assertFalse(pref.nodeExists("child2/grandchild"));
+ pref.node("child2/grandchild");
+ assertTrue(pref.nodeExists("child2/grandchild"));
+ }
+
+ public void test_nodeExists() throws BackingStoreException {
+ AbstractPreferences test = (AbstractPreferences) Preferences.userRoot()
+ .node("test");
+ try {
+ test.nodeExists(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ test.removeNode();
+ try {
+ test.nodeExists(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testParent() {
+ assertSame(parent, pref.parent());
+ AbstractPreferences child1 = new MockAbstractPreferences(pref, "child1");
+ assertSame(pref, child1.parent());
+ assertNull(root.parent());
+ }
+
+ public void testPut() throws BackingStoreException {
+ pref.put("", "emptyvalue");
+ assertEquals("emptyvalue", pref.get("", null));
+ pref.put("testPutkey", "value1");
+ assertEquals("value1", pref.get("testPutkey", null));
+ pref.put("testPutkey", "value2");
+ assertEquals("value2", pref.get("testPutkey", null));
+
+ pref.put("", "emptyvalue");
+ assertEquals("emptyvalue", pref.get("", null));
+
+ try {
+ pref.put(null, "value");
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ pref.put("key", null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.put(LONG_KEY, LONG_VALUE);
+ try {
+ pref.put(LONG_KEY + 1, LONG_VALUE);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ pref.put(LONG_KEY, LONG_VALUE + 1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ pref.removeNode();
+ try {
+ pref.put(LONG_KEY, LONG_VALUE + 1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ pref.put(LONG_KEY, LONG_VALUE);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ public void testPutBoolean() {
+ try {
+ pref.putBoolean(null, false);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.putBoolean(LONG_KEY, false);
+ try {
+ pref.putBoolean(LONG_KEY + "a", false);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ pref.putBoolean("testPutBooleanKey", false);
+ assertEquals("false", pref.get("testPutBooleanKey", null));
+ assertFalse(pref.getBoolean("testPutBooleanKey", true));
+ }
+
+ public void testPutDouble() {
+ try {
+ pref.putDouble(null, 3);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.putDouble(LONG_KEY, 3);
+ try {
+ pref.putDouble(LONG_KEY + "a", 3);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ pref.putDouble("testPutDoubleKey", 3);
+ assertEquals("3.0", pref.get("testPutDoubleKey", null));
+ assertEquals(3, pref.getDouble("testPutDoubleKey", 0), 0);
+ }
+
+ public void testPutFloat() {
+ try {
+ pref.putFloat(null, 3f);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.putFloat(LONG_KEY, 3f);
+ try {
+ pref.putFloat(LONG_KEY + "a", 3f);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ pref.putFloat("testPutFloatKey", 3f);
+ assertEquals("3.0", pref.get("testPutFloatKey", null));
+ assertEquals(3f, pref.getFloat("testPutFloatKey", 0), 0);
+ }
+
+ public void testPutInt() {
+ try {
+ pref.putInt(null, 3);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.putInt(LONG_KEY, 3);
+ try {
+ pref.putInt(LONG_KEY + "a", 3);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ pref.putInt("testPutIntKey", 3);
+ assertEquals("3", pref.get("testPutIntKey", null));
+ assertEquals(3, pref.getInt("testPutIntKey", 0));
+ }
+
+ public void testPutLong() {
+ try {
+ pref.putLong(null, 3L);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.putLong(LONG_KEY, 3L);
+ try {
+ pref.putLong(LONG_KEY + "a", 3L);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ pref.putLong("testPutLongKey", 3L);
+ assertEquals("3", pref.get("testPutLongKey", null));
+ assertEquals(3L, pref.getLong("testPutLongKey", 0));
+ }
+
+ public void testRemove() throws BackingStoreException {
+ pref.remove("key");
+
+ pref.put("key", "value");
+ assertEquals("value", pref.get("key", null));
+ pref.remove("key");
+ assertNull(pref.get("key", null));
+
+ pref.remove("key");
+
+ try {
+ pref.remove(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.removeNode();
+ try {
+ pref.remove("key");
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ public void testRemoveNode() throws BackingStoreException {
+ Preferences child = pref.node("child");
+ Preferences child1 = pref.node("child1");
+ Preferences grandchild = child.node("grandchild");
+
+ pref.removeNode();
+
+ assertFalse(child.nodeExists(""));
+ assertFalse(child1.nodeExists(""));
+ assertFalse(grandchild.nodeExists(""));
+ assertFalse(pref.nodeExists(""));
+ }
+
+ public void testRemoveNodeChangeListener() {
+ try {
+ pref.removeNodeChangeListener(null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ MockNodeChangeListener l1 = new MockNodeChangeListener();
+ MockNodeChangeListener l2 = new MockNodeChangeListener();
+ pref.addNodeChangeListener(l1);
+ pref.addNodeChangeListener(l1);
+
+ pref.removeNodeChangeListener(l1);
+ pref.removeNodeChangeListener(l1);
+ try {
+ pref.removeNodeChangeListener(l1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ pref.removeNodeChangeListener(l2);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testRemovePreferenceChangeListener() {
+ try {
+ pref.removePreferenceChangeListener(null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ MockPreferenceChangeListener l1 = new MockPreferenceChangeListener();
+ MockPreferenceChangeListener l2 = new MockPreferenceChangeListener();
+ pref.addPreferenceChangeListener(l1);
+ pref.addPreferenceChangeListener(l1);
+ try {
+ pref.removePreferenceChangeListener(l2);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ pref.removePreferenceChangeListener(l1);
+ pref.removePreferenceChangeListener(l1);
+ try {
+ pref.removePreferenceChangeListener(l1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testSync() throws BackingStoreException {
+ pref.sync();
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ p.resetSyncTimes();
+ p.sync();
+ assertEquals(1, p.getSyncTimes());
+
+ p.resetSyncTimes();
+ MockAbstractPreferences child = (MockAbstractPreferences) p
+ .node("child");
+ MockAbstractPreferences child2 = new MockAbstractPreferences(p,
+ "child2");
+ p.childs.put("child2", child2);
+ assertEquals(1, p.cachedChildrenImpl().length);
+ assertSame(child, p.cachedChildrenImpl()[0]);
+ p.sync();
+ assertEquals(1, p.getSyncTimes());
+ assertEquals(1, child.getSyncTimes());
+ assertEquals(0, child2.getSyncTimes());
+
+ p.resetSyncTimes();
+ child.resetSyncTimes();
+ child.sync();
+ assertEquals(0, p.getSyncTimes());
+ assertEquals(1, child.getSyncTimes());
+
+ p.resetSyncTimes();
+ child.resetSyncTimes();
+ MockAbstractPreferences grandson = (MockAbstractPreferences) child
+ .node("grandson");
+ child.sync();
+ assertEquals(0, p.getSyncTimes());
+ assertEquals(1, child.getSyncTimes());
+ assertEquals(1, grandson.getSyncTimes());
+ }
+
+ public void testFlush() throws BackingStoreException {
+ pref.flush();
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ p.resetFlushedTimes();
+ p.flush();
+ assertEquals(1, p.getFlushedTimes());
+
+ p.resetFlushedTimes();
+ MockAbstractPreferences child = (MockAbstractPreferences) p
+ .node("child");
+ MockAbstractPreferences child2 = new MockAbstractPreferences(p,
+ "child2");
+ p.childs.put("child2", child2);
+ assertEquals(1, p.cachedChildrenImpl().length);
+ assertSame(child, p.cachedChildrenImpl()[0]);
+ p.flush();
+ assertEquals(1, p.getFlushedTimes());
+ assertEquals(1, child.getFlushedTimes());
+ assertEquals(0, child2.getFlushedTimes());
+
+ p.resetFlushedTimes();
+ child.resetFlushedTimes();
+ child.flush();
+ assertEquals(0, p.getFlushedTimes());
+ assertEquals(1, child.getFlushedTimes());
+
+ p.resetFlushedTimes();
+ child.resetFlushedTimes();
+ MockAbstractPreferences grandson = (MockAbstractPreferences) child
+ .node("grandson");
+ child.flush();
+ assertEquals(0, p.getFlushedTimes());
+ assertEquals(1, child.getFlushedTimes());
+ assertEquals(1, grandson.getFlushedTimes());
+
+ p.resetFlushedTimes();
+ child.resetFlushedTimes();
+ grandson.resetFlushedTimes();
+ child.removeNode();
+ child.flush();
+ assertEquals(0, p.getFlushedTimes());
+ assertEquals(1, child.getFlushedTimes());
+ assertEquals(0, grandson.getFlushedTimes());
+ }
+
+ public void testGetChild() throws BackingStoreException {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ assertNull(p.getChildImpl("child"));
+ MockAbstractPreferences child = new MockAbstractPreferences(p, "child");
+ p.childs.put("child", child);
+ assertSame(child, p.getChildImpl("child"));
+ assertNull(p.getChildImpl("child "));
+
+ assertNull(p.getChildImpl("child/grandson"));
+ child.childs.put("grandson", new MockAbstractPreferences(child,
+ "grandson"));
+ assertNull(p.getChildImpl("child/grandson"));
+
+ assertNull(p.getChildImpl(null));
+ assertNull(p.getChildImpl(""));
+ assertNull(p.getChildImpl(" "));
+ assertNull(p.getChildImpl("abc//abc"));
+ assertNull(p.getChildImpl("child/"));
+ assertNull(p.getChildImpl(LONG_NAME + "a"));
+
+ child.removeNode();
+ assertNull(p.getChildImpl("child"));
+ }
+
+ public void testIsRemoved() throws BackingStoreException {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ assertFalse(p.isRemovedImpl());
+ p.removeNode();
+ assertTrue(p.isRemovedImpl());
+ }
+
+ public void testExportNode() throws Exception {
+ try {
+ pref.exportNode(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ pref.putBoolean("key", false);
+ Preferences child = pref.node("child<");
+ child.put("key2", "value2<");
+ Preferences grandson = child.node("grandson");
+ grandson.put("key3", "value3");
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ child.exportNode(out);
+
+ byte[] result = out.toByteArray();
+ ByteArrayInputStream in = new ByteArrayInputStream(result);
+
+ parseXmlStream(in, false);
+ }
+
+ private static Document parseXmlStream(InputStream input, boolean validating)
+ throws SAXException, IOException, ParserConfigurationException {
+ // Create a builder factory
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(validating);
+ // Create the builder and parse the file
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ return builder.parse(input);
+ }
+
+ public void testExportSubtree() throws Exception {
+ try {
+ pref.exportSubtree(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ pref.putBoolean("key", false);
+ Preferences child = pref.node("child");
+ child.put("key2", "value2");
+ Preferences grandson = child.node("grandson");
+ grandson.put("key3", "value3");
+ child.node("grandson2");
+ Preferences grandgrandson = grandson.node("grandgrandson");
+ grandgrandson.put("key4", "value4");
+ child.exportSubtree(out);
+
+ byte[] result = out.toByteArray();
+ ByteArrayInputStream in = new ByteArrayInputStream(result);
+
+ // We don't have an xpath API so all we can do is test that the
+ // generated XML parses correctly.
+ parseXmlStream(in, false);
+ }
+
+ public void testCachedChildren() throws Exception {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ assertEquals(0, p.cachedChildrenImpl().length);
+
+ MockAbstractPreferences child = (MockAbstractPreferences) p
+ .getChildImpl("child");
+ assertNull(child);
+
+ child = new MockAbstractPreferences(p, "child");
+ assertSame(child, p.getChildImpl("child"));
+
+ assertEquals(0, p.cachedChildrenImpl().length);
+
+ p.node("child");
+ assertSame(child, p.cachedChildrenImpl()[0]);
+
+ MockAbstractPreferences grandchild = new MockAbstractPreferences(child,
+ "grandchild");
+ assertSame(grandchild, child.getChildImpl("grandchild"));
+ assertNull(p.getChildImpl("grandchild"));
+
+ assertEquals(1, p.cachedChildrenImpl().length);
+ assertEquals(0, child.cachedChildrenImpl().length);
+
+ p.node("child/grandchild");
+ assertSame(child, p.cachedChildrenImpl()[0]);
+ assertSame(grandchild, child.cachedChildrenImpl()[0]);
+ assertEquals(1, p.cachedChildrenImpl().length);
+ assertEquals(1, child.cachedChildrenImpl().length);
+
+ p.childs.put("child2", new MockAbstractPreferences(p, "child2"));
+ p.nodeExists("child2/grandchild");
+ assertSame(child, p.cachedChildrenImpl()[0]);
+ assertSame(grandchild, child.cachedChildrenImpl()[0]);
+ assertEquals(1, p.cachedChildrenImpl().length);
+ assertEquals(1, child.cachedChildrenImpl().length);
+ }
+
+ public void testAbstractMethod() {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ ((MockAbstractPreferences) pref).protectedAbstractMethod();
+ }
+
+ public void testBackingStoreException() throws IOException,
+ BackingStoreException {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ p.setResult(MockAbstractPreferences.backingException);
+ try {
+ p.childrenNames();
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException e) {
+ }
+ p.put("exceptionkey", "value");
+ p.absolutePath();
+ p.toString();
+ assertEquals("exception default", p.get("key", "exception default"));
+ p.remove("key");
+ try {
+ p.clear();
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+
+ p.putInt("key", 3);
+ p.getInt("key", 3);
+ p.putLong("key", 3l);
+ p.getLong("key", 3l);
+ p.putDouble("key", 3);
+ p.getDouble("key", 3);
+ p.putBoolean("key", true);
+ p.getBoolean("key", true);
+ p.putFloat("key", 3f);
+ p.getFloat("key", 3f);
+ p.putByteArray("key", new byte[0]);
+ p.getByteArray("key", new byte[0]);
+ try {
+ p.keys();
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+
+ try {
+ p.keys();
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+ try {
+ p.childrenNames();
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+ p.parent();
+ p.node("");
+ p.nodeExists("");
+ try {
+ p.removeNode();
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+ p.name();
+ p.absolutePath();
+ p.isUserNode();
+ MockPreferenceChangeListener mockPreferenceChangeListener = new MockPreferenceChangeListener();
+ p.addPreferenceChangeListener(mockPreferenceChangeListener);
+ p.removePreferenceChangeListener(mockPreferenceChangeListener);
+ MockNodeChangeListener mockNodeChangeListener = new MockNodeChangeListener();
+ p.addNodeChangeListener(mockNodeChangeListener);
+ p.removeNodeChangeListener(mockNodeChangeListener);
+ p.toString();
+ try {
+ p.sync();
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+ try {
+ p.flush();
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+ try {
+ p.exportNode(new ByteArrayOutputStream());
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+ try {
+ p.exportSubtree(new ByteArrayOutputStream());
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+ p.isRemovedImpl();
+ try {
+ p.getChildImpl(null);
+ fail("should throw BackingStoreException");
+ } catch (BackingStoreException expected) {
+ }
+ p.cachedChildrenImpl();
+ }
+
+ public void testRuntimeException() throws IOException,
+ BackingStoreException {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ p.setResult(MockAbstractPreferences.runtimeException);
+ try {
+ p.childrenNames();
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ try {
+ p.put("exceptionkey", "value");
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.absolutePath();
+ p.toString();
+ assertEquals("exception default", p.get("key", "exception default"));
+ try {
+ p.remove("key");
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ try {
+ p.clear();
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ try {
+ p.putInt("key", 3);
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.getInt("key", 3);
+ try {
+ p.putLong("key", 3l);
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.getLong("key", 3l);
+ try {
+ p.putDouble("key", 3);
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.getDouble("key", 3);
+ try {
+ p.putBoolean("key", true);
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.getBoolean("key", true);
+ try {
+ p.putFloat("key", 3f);
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.getFloat("key", 3f);
+ try {
+ p.putByteArray("key", new byte[0]);
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.getByteArray("key", new byte[0]);
+ try {
+ p.keys();
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ try {
+ p.keys();
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ try {
+ p.childrenNames();
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.parent();
+ p.node("");
+ p.nodeExists("");
+ try {
+ p.removeNode();
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.name();
+ p.absolutePath();
+ p.isUserNode();
+ MockPreferenceChangeListener pcl = new MockPreferenceChangeListener();
+ p.addPreferenceChangeListener(pcl);
+ p.removePreferenceChangeListener(pcl);
+ MockNodeChangeListener ncl = new MockNodeChangeListener();
+ p.addNodeChangeListener(ncl);
+ p.removeNodeChangeListener(ncl);
+ p.toString();
+ try {
+ p.sync();
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ try {
+ p.flush();
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ try {
+ p.exportNode(new ByteArrayOutputStream());
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ try {
+ p.exportSubtree(new ByteArrayOutputStream());
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.isRemovedImpl();
+ try {
+ p.getChildImpl(null);
+ fail("should throw MockRuntimeException");
+ } catch (MockRuntimeException expected) {
+ }
+ p.cachedChildrenImpl();
+ }
+
+ public void testSPIReturnNull() throws IOException, BackingStoreException {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ p.setResult(MockAbstractPreferences.returnNull);
+ try {
+ p.childrenNames();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ p.absolutePath();
+ p.toString();
+ p.put("nullkey", "value");
+ assertEquals("null default", p.get("key", "null default"));
+ p.remove("key");
+ try {
+ p.clear();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ p.putInt("key", 3);
+ p.getInt("key", 3);
+ p.putLong("key", 3l);
+ p.getLong("key", 3l);
+ p.putDouble("key", 3);
+ p.getDouble("key", 3);
+ p.putBoolean("key", true);
+ p.getBoolean("key", true);
+ p.putFloat("key", 3f);
+ p.getFloat("key", 3f);
+ p.putByteArray("key", new byte[0]);
+ p.getByteArray("key", new byte[0]);
+ p.keys();
+ try {
+ p.childrenNames();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ p.parent();
+ p.node("");
+ p.nodeExists("");
+ try {
+ p.removeNode();
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ p.name();
+ p.absolutePath();
+ p.isUserNode();
+ MockPreferenceChangeListener mockPreferenceChangeListener = new MockPreferenceChangeListener();
+ p.addPreferenceChangeListener(mockPreferenceChangeListener);
+ p.removePreferenceChangeListener(mockPreferenceChangeListener);
+ MockNodeChangeListener mockNodeChangeListener = new MockNodeChangeListener();
+ p.addNodeChangeListener(mockNodeChangeListener);
+ p.removeNodeChangeListener(mockNodeChangeListener);
+ p.toString();
+ p.sync();
+ p.flush();
+ try {
+ p.exportNode(System.out);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.exportSubtree(System.out);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ p.isRemovedImpl();
+ try {
+ p.getChildImpl("");
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ p.cachedChildrenImpl();
+ }
+
+ public void testIllegalStateException() throws IOException,
+ BackingStoreException {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ pref.removeNode();
+ // after remove node, every methods, except name(), absolutePath(),
+ // isUserNode(), flush() or nodeExists(""),
+ // will throw illegal state exception
+ pref.nodeExists("");
+ pref.name();
+ pref.absolutePath();
+ pref.isUserNode();
+ pref.toString();
+ pref.flush();
+ try {
+ pref.nodeExists("child");
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.childrenNames();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.remove(null);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.clear();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.get("key", "null default");
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.put("nullkey", "value");
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.putInt("key", 3);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.getInt("key", 3);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.putLong("key", 3l);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.getLong("key", 3l);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.putDouble("key", 3);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.getDouble("key", 3);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.putBoolean("key", true);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.getBoolean("key", true);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.putFloat("key", 3f);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.getFloat("key", 3f);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.putByteArray("key", new byte[0]);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.getByteArray("key", new byte[0]);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.keys();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.keys();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.childrenNames();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.parent();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.node(null);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.removeNode();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref
+ .addPreferenceChangeListener(new MockPreferenceChangeListener());
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref
+ .removePreferenceChangeListener(new MockPreferenceChangeListener());
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.addNodeChangeListener(new MockNodeChangeListener());
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.removeNodeChangeListener(new MockNodeChangeListener());
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.sync();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.exportNode(null);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ pref.exportSubtree(null);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ p.isRemovedImpl();
+ p.cachedChildrenImpl();
+ try {
+ p.getChildImpl(null);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ public void testNullAndIllegalStateException() throws Exception {
+ if (!(pref instanceof MockAbstractPreferences)) {
+ return;
+ }
+ MockAbstractPreferences p = (MockAbstractPreferences) pref;
+ p.removeNode();
+ try {
+ p.get(null, "null default");
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.put(null, "value");
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.putInt(null, 3);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.getInt(null, 3);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.putLong(null, 3l);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.getLong(null, 3l);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.putDouble(null, 3);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.getDouble(null, 3);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.putBoolean(null, true);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.getBoolean(null, true);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.putFloat(null, 3f);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.getFloat(null, 3f);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.putByteArray(null, new byte[0]);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.getByteArray(null, new byte[0]);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.addPreferenceChangeListener(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.removePreferenceChangeListener(null);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ p.addNodeChangeListener(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ try {
+ p.removeNodeChangeListener(null);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * Regression for HARMONY-828
+ */
+ public void testLongPath() throws Exception {
+ assertFalse(pref.nodeExists("ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"));
+ }
+
+ public static class MockPreferenceChangeListener implements
+ PreferenceChangeListener {
+ private int changed = 0;
+
+ public void preferenceChange(PreferenceChangeEvent pce) {
+ changed++;
+ }
+
+ public int getChanged() {
+ int result = changed;
+ changed = 0;
+ return result;
+ }
+ }
+
+ public static class MockNodeChangeListener implements NodeChangeListener {
+ private boolean addDispatched = false;
+
+ private boolean removeDispatched = false;
+
+ private Object addLock = new Object();
+
+ private Object removeLock = new Object();
+
+ private int added = 0;
+
+ private int removed = 0;
+
+ public void childAdded(NodeChangeEvent e) {
+ synchronized (addLock) {
+ ++added;
+ addDispatched = true;
+ addLock.notifyAll();
+ }
+ }
+
+ public void childRemoved(NodeChangeEvent e) {
+ synchronized (removeLock) {
+ removed++;
+ removeDispatched = true;
+ removeLock.notifyAll();
+ }
+ }
+
+ public int getAdded() {
+ synchronized (addLock) {
+ if (!addDispatched) {
+ try {
+ // TODO: don't know why must add limitation
+ addLock.wait(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ addDispatched = false;
+ }
+ return added;
+ }
+
+ public int getRemoved() {
+ synchronized (removeLock) {
+ if (!removeDispatched) {
+ try {
+ removeLock.wait(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ removeDispatched = false;
+ }
+ return removed;
+
+ }
+
+ public void reset() {
+ added = 0;
+ removed = 0;
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/BackingStoreExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/BackingStoreExceptionTest.java
new file mode 100644
index 0000000..4d264e1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/BackingStoreExceptionTest.java
@@ -0,0 +1,62 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.util.prefs.BackingStoreException;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ *
+ *
+ */
+public class BackingStoreExceptionTest extends TestCase {
+
+ /*
+ * Class under test for void BackingStoreException(String)
+ */
+ public void testBackingStoreExceptionString() {
+ BackingStoreException e = new BackingStoreException("msg");
+ assertNull(e.getCause());
+ assertEquals("msg", e.getMessage());
+ }
+
+ /*
+ * Class under test for void BackingStoreException(Throwable)
+ */
+ public void testBackingStoreExceptionThrowable() {
+ Throwable t = new Throwable("msg");
+ BackingStoreException e = new BackingStoreException(t);
+ assertTrue(e.getMessage().indexOf(t.getClass().getName()) >= 0);
+ assertTrue(e.getMessage().indexOf("msg") >= 0);
+ assertEquals(t, e.getCause());
+ }
+
+ /**
+ * @tests serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(new BackingStoreException("msg"));
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ SerializationTest.verifyGolden(this, new BackingStoreException("msg"));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/FilePreferencesImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/FilePreferencesImplTest.java
new file mode 100644
index 0000000..352603c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/FilePreferencesImplTest.java
@@ -0,0 +1,120 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+import junit.framework.TestCase;
+import libcore.io.IoUtils;
+
+public class FilePreferencesImplTest extends TestCase {
+
+ private Preferences uroot;
+ private Preferences sroot;
+
+ @Override
+ protected void setUp() throws Exception {
+ File tmpDir = IoUtils.createTemporaryDirectory("FilePreferencesImplTest");
+ AbstractPreferencesTest.TestPreferencesFactory factory
+ = new AbstractPreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath());
+
+ uroot = factory.userRoot().node("harmony_test");
+ sroot = factory.systemRoot().node("harmony_test");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ uroot.removeNode();
+ sroot.removeNode();
+ uroot = null;
+ sroot = null;
+ }
+
+ public void testPutGet() throws IOException, BackingStoreException {
+ uroot.put("ukey1", "value1");
+ assertEquals("value1", uroot.get("ukey1", null));
+ String[] names = uroot.keys();
+ assertEquals(1, names.length);
+
+ uroot.put("ukey2", "value3");
+ assertEquals("value3", uroot.get("ukey2", null));
+ uroot.put("\u4e2d key1", "\u4e2d value1");
+ assertEquals("\u4e2d value1", uroot.get("\u4e2d key1", null));
+ names = uroot.keys();
+ assertEquals(3, names.length);
+
+ uroot.flush();
+ uroot.clear();
+ names = uroot.keys();
+ assertEquals(0, names.length);
+
+ sroot.put("skey1", "value1");
+ assertEquals("value1", sroot.get("skey1", null));
+ sroot.put("\u4e2d key1", "\u4e2d value1");
+ assertEquals("\u4e2d value1", sroot.get("\u4e2d key1", null));
+ }
+
+ public void testChildNodes() throws Exception {
+ Preferences child1 = uroot.node("child1");
+ Preferences child2 = uroot.node("\u4e2d child2");
+ Preferences grandchild = child1.node("grand");
+ assertNotNull(grandchild);
+
+ String[] childNames = uroot.childrenNames();
+ assertEquals(2, childNames.length);
+
+ childNames = child1.childrenNames();
+ assertEquals(1, childNames.length);
+
+ childNames = child2.childrenNames();
+ assertEquals(0, childNames.length);
+
+ child1.removeNode();
+ childNames = uroot.childrenNames();
+ assertEquals(1, childNames.length);
+
+ child2.removeNode();
+ childNames = uroot.childrenNames();
+ assertEquals(0, childNames.length);
+
+ child1 = sroot.node("child1");
+ child2 = sroot.node("child2");
+ childNames = sroot.childrenNames();
+
+ Preferences grandchild2 = child1.node("grand");
+ assertEquals(2, childNames.length);
+
+ childNames = child1.childrenNames();
+ assertEquals(1, childNames.length);
+
+ childNames = child2.childrenNames();
+ assertEquals(0, childNames.length);
+
+ child1.removeNode();
+ assertNotSame(child1, sroot.node("child1"));
+ assertSame(sroot.node("child1"), sroot.node("child1"));
+ sroot.node("child1").removeNode();
+ childNames = sroot.childrenNames();
+ assertEquals(1, childNames.length);
+ child2.removeNode();
+ childNames = sroot.childrenNames();
+ assertEquals(0, childNames.length);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/InvalidPreferencesFormatExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/InvalidPreferencesFormatExceptionTest.java
new file mode 100644
index 0000000..7c4891f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/InvalidPreferencesFormatExceptionTest.java
@@ -0,0 +1,81 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.util.prefs.InvalidPreferencesFormatException;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ *
+ */
+public class InvalidPreferencesFormatExceptionTest extends TestCase {
+
+ /*
+ * Class under test for void InvalidPreferencesFormatException(String)
+ */
+ public void testInvalidPreferencesFormatExceptionString() {
+ InvalidPreferencesFormatException e = new InvalidPreferencesFormatException(
+ "msg");
+ assertNull(e.getCause());
+ assertEquals("msg", e.getMessage());
+ }
+
+ /*
+ * Class under test for void InvalidPreferencesFormatException(String,
+ * Throwable)
+ */
+ public void testInvalidPreferencesFormatExceptionStringThrowable() {
+ Throwable t = new Throwable("root");
+ InvalidPreferencesFormatException e = new InvalidPreferencesFormatException(
+ "msg", t);
+ assertSame(t, e.getCause());
+ assertTrue(e.getMessage().indexOf("root") < 0);
+ assertTrue(e.getMessage().indexOf(t.getClass().getName()) < 0);
+ assertTrue(e.getMessage().indexOf("msg") >= 0);
+ }
+
+ /*
+ * Class under test for void InvalidPreferencesFormatException(Throwable)
+ */
+ public void testInvalidPreferencesFormatExceptionThrowable() {
+ Throwable t = new Throwable("root");
+ InvalidPreferencesFormatException e = new InvalidPreferencesFormatException(
+ t);
+ assertSame(t, e.getCause());
+ assertTrue(e.getMessage().indexOf("root") >= 0);
+ assertTrue(e.getMessage().indexOf(t.getClass().getName()) >= 0);
+ }
+
+ /**
+ * @tests serialization/deserialization.
+ */
+ public void testSerializationSelf() throws Exception {
+
+ SerializationTest.verifySelf(new InvalidPreferencesFormatException(
+ "msg"));
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new InvalidPreferencesFormatException("msg"));
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/MockAbstractPreferences.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/MockAbstractPreferences.java
new file mode 100644
index 0000000..88f184b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/MockAbstractPreferences.java
@@ -0,0 +1,263 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.prefs.AbstractPreferences;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+public class MockAbstractPreferences extends AbstractPreferences {
+ static final int NORMAL = 0;
+
+ static final int backingException = 1;
+
+ static final int runtimeException = 2;
+
+ static final int returnNull = 3;
+
+ int result = NORMAL;
+
+ Properties attr = new Properties();
+
+ Map<String, MockAbstractPreferences> childs = new HashMap<String, MockAbstractPreferences>();
+
+ private int flushedTimes;
+
+ private int syncTimes;
+
+ protected MockAbstractPreferences(AbstractPreferences parent, String name) {
+ this(parent, name, false);
+
+ }
+
+ protected MockAbstractPreferences(AbstractPreferences parent, String name,
+ boolean newNode) {
+ super(parent, name);
+ super.newNode = newNode;
+ if (parent instanceof MockAbstractPreferences) {
+ ((MockAbstractPreferences) parent).addChild(this);
+ }
+ }
+
+ public int getFlushedTimes() {
+ return flushedTimes;
+ }
+
+ public void resetFlushedTimes() {
+ flushedTimes = 0;
+ }
+
+ public int getSyncTimes() {
+ return syncTimes;
+ }
+
+ public void resetSyncTimes() {
+ syncTimes = 0;
+ }
+
+ private void addChild(MockAbstractPreferences c) {
+ childs.put(c.name(), c);
+ }
+
+ public void setResult(int r) {
+ result = r;
+ }
+
+ public Object lock() {
+ return lock;
+ }
+
+ @Override
+ protected String[] childrenNamesSpi() throws BackingStoreException {
+ checkException();
+ if (result == returnNull)
+ return null;
+ String[] r = new String[childs.size()];
+ childs.keySet().toArray(r);
+ return r;
+ }
+
+ private void checkException() throws BackingStoreException {
+ switch (result) {
+ case NORMAL:
+ return;
+ case backingException:
+ throw new BackingStoreException("test");
+ case runtimeException:
+ throw new MockRuntimeException("test");
+ }
+ }
+
+ public AbstractPreferences publicChildSpi(String name) {
+ return childSpi(name);
+ }
+
+ @Override
+ protected AbstractPreferences childSpi(String name) {
+ try {
+ checkException();
+ } catch (BackingStoreException e) {
+ }
+ if (result == returnNull)
+ return null;
+ AbstractPreferences r = childs.get(name);
+ if (r == null) {
+ r = new MockAbstractPreferences(this, name, true);
+
+ }
+ return r;
+ }
+
+ @Override
+ protected void flushSpi() throws BackingStoreException {
+ checkException();
+ flushedTimes++;
+ }
+
+ @Override
+ protected String getSpi(String key) {
+ try {
+ checkException();
+ } catch (BackingStoreException e) {
+ }
+ if (null == key) {
+ return null;
+ }
+ return result == returnNull ? null : attr.getProperty(key);
+ }
+
+ @Override
+ protected String[] keysSpi() throws BackingStoreException {
+ checkException();
+ Set<Object> keys = attr.keySet();
+ String[] results = new String[keys.size()];
+ keys.toArray(results);
+ return result == returnNull ? null : results;
+ }
+
+ @Override
+ protected void putSpi(String name, String value) {
+ try {
+ checkException();
+ } catch (BackingStoreException e) {
+ }
+ if (name == null || value == null) {
+ return;
+ }
+ attr.put(name, value);
+ }
+
+ @Override
+ protected void removeNodeSpi() throws BackingStoreException {
+ checkException();
+ Preferences p = parent();
+ if (p instanceof MockAbstractPreferences) {
+ ((MockAbstractPreferences) p).childs.remove(name());
+ } else {
+ String[] children = p.childrenNames();
+ for (String child : children) {
+ p.node(child).removeNode();
+ }
+ }
+ }
+
+ @Override
+ protected void removeSpi(String key) {
+ try {
+ checkException();
+ } catch (BackingStoreException e) {
+ }
+ if (null == key) {
+ return;
+ }
+ attr.remove(key);
+ }
+
+ @Override
+ protected void syncSpi() throws BackingStoreException {
+ checkException();
+ syncTimes++;
+ }
+
+ public boolean getNewNode() {
+ return newNode;
+ }
+
+ public Object getLock() {
+ return lock;
+ }
+
+ public void protectedAbstractMethod() {
+ try {
+ childrenNamesSpi();
+ } catch (BackingStoreException e) {
+ }
+ childSpi("mock");
+ try {
+ flushSpi();
+ } catch (BackingStoreException e1) {
+ }
+ getSpi(null);
+ isRemoved();
+ try {
+ keysSpi();
+ } catch (BackingStoreException e2) {
+ }
+ putSpi(null, null);
+ try {
+ removeNodeSpi();
+ } catch (BackingStoreException e3) {
+ }
+ removeSpi(null);
+ try {
+ syncSpi();
+ } catch (BackingStoreException e4) {
+ }
+ }
+
+ public boolean isRemovedImpl() {
+ return super.isRemoved();
+ }
+
+ public AbstractPreferences getChildImpl(String name)
+ throws BackingStoreException {
+ return super.getChild(name);
+ }
+
+ public AbstractPreferences[] cachedChildrenImpl() {
+ return super.cachedChildren();
+ }
+
+}
+
+class MockRuntimeException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public MockRuntimeException(String s) {
+ super(s);
+ }
+
+ public MockRuntimeException() {
+ super();
+ }
+}
+
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/MockPreferencesFactory.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/MockPreferencesFactory.java
new file mode 100644
index 0000000..8bbbed2
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/MockPreferencesFactory.java
@@ -0,0 +1,42 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+
+/**
+ *
+ */
+public class MockPreferencesFactory implements PreferencesFactory {
+ static MockAbstractPreferences userRoot = new MockAbstractPreferences(null,
+ "");
+
+ static MockAbstractPreferences systemRoot = new MockAbstractPreferences(
+ null, "");
+
+ public MockPreferencesFactory() {
+ }
+
+ public Preferences userRoot() {
+ return userRoot;
+ }
+
+ public Preferences systemRoot() {
+ return systemRoot;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/NodeChangeEventTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/NodeChangeEventTest.java
new file mode 100644
index 0000000..07fd887
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/NodeChangeEventTest.java
@@ -0,0 +1,63 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.io.NotSerializableException;
+import java.util.prefs.NodeChangeEvent;
+import java.util.prefs.Preferences;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ *
+ */
+public class NodeChangeEventTest extends TestCase {
+
+ NodeChangeEvent event;
+
+ public void testConstructor() {
+ event = new NodeChangeEvent(Preferences.systemRoot(), Preferences
+ .userRoot());
+ assertSame(Preferences.systemRoot(), event.getParent());
+ assertSame(Preferences.userRoot(), event.getChild());
+ assertSame(Preferences.systemRoot(), event.getSource());
+ }
+
+ public void testConstructorNullParam() {
+ try {
+ event = new NodeChangeEvent(null, Preferences.userRoot());
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+
+ event = new NodeChangeEvent(Preferences.systemRoot(), null);
+ assertSame(Preferences.systemRoot(), event.getParent());
+ assertNull(event.getChild());
+ assertSame(Preferences.systemRoot(), event.getSource());
+ }
+
+ public void testSerialization() throws Exception {
+
+ event = new NodeChangeEvent(Preferences.systemRoot(), null);
+
+ try {
+ SerializationTest.copySerializable(event);
+ fail("No expected NotSerializableException");
+ } catch (NotSerializableException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/NodeChangeListenerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/NodeChangeListenerTest.java
new file mode 100644
index 0000000..cda52ec
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/NodeChangeListenerTest.java
@@ -0,0 +1,68 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.util.prefs.NodeChangeEvent;
+import java.util.prefs.NodeChangeListener;
+import java.util.prefs.Preferences;
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+public class NodeChangeListenerTest extends TestCase {
+
+ NodeChangeListener l;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ l = new NodeChangeListenerImpl();
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testChildAdded() {
+ l.childAdded(new NodeChangeEvent(Preferences.userRoot(), Preferences
+ .userRoot()));
+ }
+
+ public void testChildRemoved() {
+ l.childRemoved(new NodeChangeEvent(Preferences.userRoot(), Preferences
+ .userRoot()));
+ }
+
+ public static class NodeChangeListenerImpl implements NodeChangeListener {
+
+ public void childAdded(NodeChangeEvent e) {
+ }
+
+ public void childRemoved(NodeChangeEvent e) {
+ }
+
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferenceChangeEventTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferenceChangeEventTest.java
new file mode 100644
index 0000000..7d403c7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferenceChangeEventTest.java
@@ -0,0 +1,84 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.io.NotSerializableException;
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.Preferences;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ *
+ */
+public class PreferenceChangeEventTest extends TestCase {
+
+ PreferenceChangeEvent event;
+
+ public void testPreferenceChangeEventException() {
+ try {
+ event = new PreferenceChangeEvent(null, "key", "value");
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testConstructorNullValue() {
+ event = new PreferenceChangeEvent(Preferences.userRoot(), "key", null);
+ assertEquals("key", event.getKey());
+ assertNull(event.getNewValue());
+ assertSame(Preferences.userRoot(), event.getNode());
+ assertSame(Preferences.userRoot(), event.getSource());
+
+ event = new PreferenceChangeEvent(Preferences.userRoot(), "", null);
+ assertEquals("", event.getKey());
+ assertNull(event.getNewValue());
+ assertSame(Preferences.userRoot(), event.getNode());
+ assertSame(Preferences.userRoot(), event.getSource());
+
+ event = new PreferenceChangeEvent(Preferences.userRoot(), null, "value");
+ assertNull(event.getKey());
+ assertEquals("value", event.getNewValue());
+ assertSame(Preferences.userRoot(), event.getNode());
+ assertSame(Preferences.userRoot(), event.getSource());
+
+ event = new PreferenceChangeEvent(Preferences.userRoot(), null, "");
+ assertNull(event.getKey());
+ assertEquals("", event.getNewValue());
+ assertSame(Preferences.userRoot(), event.getNode());
+ assertSame(Preferences.userRoot(), event.getSource());
+ }
+
+ public void testConstructor() {
+ event = new PreferenceChangeEvent(Preferences.userRoot(), "key",
+ "value");
+ assertEquals("key", event.getKey());
+ assertEquals("value", event.getNewValue());
+ assertSame(Preferences.userRoot(), event.getNode());
+ assertSame(Preferences.userRoot(), event.getSource());
+ }
+
+ public void testSerialization() throws Exception {
+ event = new PreferenceChangeEvent(Preferences.userRoot(), "key",
+ "value");
+ try {
+ SerializationTest.copySerializable(event);
+ fail("No expected NotSerializableException");
+ } catch (NotSerializableException e) {
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferenceChangeListenerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferenceChangeListenerTest.java
new file mode 100644
index 0000000..63170e7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferenceChangeListenerTest.java
@@ -0,0 +1,52 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+public class PreferenceChangeListenerTest extends TestCase {
+
+ PreferenceChangeListener l;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ l = new PreferenceChangeListenerImpl();
+ }
+
+ public void testPreferenceChange() {
+ l.preferenceChange(new PreferenceChangeEvent(Preferences.userRoot(),
+ "", ""));
+ }
+
+ public static class PreferenceChangeListenerImpl implements
+ PreferenceChangeListener {
+ public void preferenceChange(PreferenceChangeEvent pce) {
+ }
+
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesFactoryTest.java
new file mode 100644
index 0000000..e70fc5a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesFactoryTest.java
@@ -0,0 +1,59 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+public class PreferencesFactoryTest extends TestCase {
+
+ PreferencesFactory f;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ f = new PreferencesFactoryImpl();
+ }
+
+ public void testUserRoot() {
+ assertNull(f.userRoot());
+ }
+
+ public void testSystemRoot() {
+ assertNull(f.systemRoot());
+ }
+
+ public static class PreferencesFactoryImpl implements PreferencesFactory {
+
+ public Preferences userRoot() {
+ return null;
+ }
+
+ public Preferences systemRoot() {
+ return null;
+ }
+
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesTest.java
new file mode 100644
index 0000000..3d194da
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesTest.java
@@ -0,0 +1,420 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.prefs;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.nio.charset.StandardCharsets;
+import java.util.prefs.AbstractPreferences;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.InvalidPreferencesFormatException;
+import java.util.prefs.NodeChangeListener;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+import junit.framework.TestCase;
+import libcore.io.IoUtils;
+
+/**
+ *
+ */
+public class PreferencesTest extends TestCase {
+
+ private static final String PREFS =
+ "<!DOCTYPE preferences SYSTEM \"http://java.sun.com/dtd/preferences.dtd\">" +
+ "<preferences>" +
+ "<root type=\"user\">" +
+ "<map></map>" +
+ "</root>" +
+ "</preferences>";
+
+
+ private MockInputStream stream ;
+ private InputStream in;
+ private PreferencesFactory defaultFactory;
+
+ @Override
+ protected void setUp() throws Exception {
+ File tmpDir = IoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
+ defaultFactory = Preferences.setPreferencesFactory(
+ new AbstractPreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
+
+ in = new ByteArrayInputStream(PREFS.getBytes(StandardCharsets.US_ASCII));
+ stream = new MockInputStream(in);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ Preferences.setPreferencesFactory(defaultFactory);
+ stream.close();
+ }
+
+ public void testSystemNodeForPackage() throws Exception {
+ Preferences p = Preferences.systemNodeForPackage(Object.class);
+
+ assertEquals("/java/lang", p.absolutePath());
+ assertTrue(p instanceof AbstractPreferences);
+ Preferences root = Preferences.systemRoot();
+ Preferences parent = root.node("java");
+ assertSame(parent, p.parent());
+ assertFalse(p.isUserNode());
+ assertEquals("lang", p.name());
+ assertEquals("System Preference Node: " + p.absolutePath(), p
+ .toString());
+
+ assertEquals(0, p.childrenNames().length);
+ assertEquals(0, p.keys().length);
+ parent.removeNode();
+ try {
+ Preferences.userNodeForPackage(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ public void testSystemRoot() throws BackingStoreException {
+ Preferences p = Preferences.systemRoot();
+ assertTrue(p instanceof AbstractPreferences);
+ assertEquals("/", p.absolutePath());
+ assertSame(null, p.parent());
+ assertFalse(p.isUserNode());
+ assertEquals("", p.name());
+ assertEquals("System Preference Node: " + p.absolutePath(), p
+ .toString());
+ }
+
+ public void testConsts() {
+ assertEquals(80, Preferences.MAX_KEY_LENGTH);
+ assertEquals(80, Preferences.MAX_NAME_LENGTH);
+ assertEquals(8192, Preferences.MAX_VALUE_LENGTH);
+ }
+
+ public void testUserNodeForPackage() throws BackingStoreException {
+ Preferences p = Preferences.userNodeForPackage(Object.class);
+ assertEquals("/java/lang", p.absolutePath());
+ assertTrue(p instanceof AbstractPreferences);
+ Preferences root = Preferences.userRoot();
+ Preferences parent = root.node("java");
+ assertSame(parent, p.parent());
+ assertTrue(p.isUserNode());
+ assertEquals("lang", p.name());
+ assertEquals("User Preference Node: " + p.absolutePath(), p.toString());
+ assertEquals(0, p.childrenNames().length);
+ assertEquals(0, p.keys().length);
+
+ try {
+ Preferences.userNodeForPackage(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ public void testUserRoot() throws BackingStoreException {
+ Preferences p = Preferences.userRoot();
+ assertTrue(p instanceof AbstractPreferences);
+ assertEquals("/", p.absolutePath());
+ assertSame(null, p.parent());
+ assertTrue(p.isUserNode());
+ assertEquals("", p.name());
+ assertEquals("User Preference Node: " + p.absolutePath(), p.toString());
+ }
+
+ public void testImportPreferences() throws Exception {
+ Preferences prefs = null;
+ try {
+ prefs = Preferences.userNodeForPackage(PreferencesTest.class);
+
+ prefs.put("prefskey", "oldvalue");
+ prefs.put("prefskey2", "oldvalue2");
+ in = PreferencesTest.class
+ .getResourceAsStream("/resources/prefs/java/util/prefs/userprefs.xml");
+ Preferences.importPreferences(in);
+
+ prefs = Preferences.userNodeForPackage(PreferencesTest.class);
+ assertEquals(1, prefs.childrenNames().length);
+ assertTrue(prefs.nodeExists("mock/child/grandson"));
+ assertEquals("newvalue", prefs.get("prefskey", null));
+ assertEquals("oldvalue2", prefs.get("prefskey2", null));
+ assertEquals("newvalue3", prefs.get("prefskey3", null));
+
+ in = PreferencesTest.class.getResourceAsStream(
+ "/prefs/java/util/prefs/userprefs-badform.xml");
+ try {
+ Preferences.importPreferences(in);
+ fail("should throw InvalidPreferencesFormatException");
+ } catch (InvalidPreferencesFormatException expected) {
+ }
+ } finally {
+ try {
+ prefs = Preferences.userNodeForPackage(PreferencesTest.class);
+ prefs.removeNode();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ public void testImportPreferencesException() throws Exception {
+ try {
+ Preferences.importPreferences(null);
+ fail("should throw MalformedURLException");
+ } catch (MalformedURLException expected) {
+ }
+
+ byte[] source = new byte[0];
+ InputStream in = new ByteArrayInputStream(source);
+ try {
+ Preferences.importPreferences(in);
+ fail("should throw InvalidPreferencesFormatException");
+ } catch (InvalidPreferencesFormatException expected) {
+ }
+
+ stream.setResult(MockInputStream.exception);
+ try {
+ Preferences.importPreferences(stream);
+ fail("should throw IOException");
+ } catch (IOException expected) {
+ }
+
+ stream.setResult(MockInputStream.runtimeException);
+ try {
+ Preferences.importPreferences(stream);
+ fail("should throw RuntimeException");
+ } catch (RuntimeException expected) {
+ }
+ }
+
+ static class MockInputStream extends InputStream {
+
+ static final int normal = 0;
+
+ static final int exception = 1;
+
+ static final int runtimeException = 2;
+
+ int result = normal;
+
+ InputStream wrapper;
+
+ public void setResult(int i) {
+ result = i;
+ }
+
+ private void checkException() throws IOException {
+ switch (result) {
+ case normal:
+ return;
+ case exception:
+ throw new IOException("test");
+ case runtimeException:
+ throw new RuntimeException("test");
+ }
+ }
+
+ public MockInputStream(InputStream in) {
+ wrapper = in;
+ }
+
+ @Override
+ public int read() throws IOException {
+ checkException();
+ return wrapper.read();
+ }
+ }
+
+ static class MockPreferences extends Preferences {
+
+ public MockPreferences() {
+ super();
+ }
+
+ @Override
+ public String absolutePath() {
+ return null;
+ }
+
+ @Override
+ public String[] childrenNames() throws BackingStoreException {
+ return null;
+ }
+
+ @Override
+ public void clear() throws BackingStoreException {
+ }
+
+ @Override
+ public void exportNode(OutputStream ostream) throws IOException,
+ BackingStoreException {
+ }
+
+ @Override
+ public void exportSubtree(OutputStream ostream) throws IOException,
+ BackingStoreException {
+ }
+
+ @Override
+ public void flush() throws BackingStoreException {
+ }
+
+ @Override
+ public String get(String key, String deflt) {
+ return null;
+ }
+
+ @Override
+ public boolean getBoolean(String key, boolean deflt) {
+ return false;
+ }
+
+ @Override
+ public byte[] getByteArray(String key, byte[] deflt) {
+ return null;
+ }
+
+ @Override
+ public double getDouble(String key, double deflt) {
+ return 0;
+ }
+
+ @Override
+ public float getFloat(String key, float deflt) {
+ return 0;
+ }
+
+ @Override
+ public int getInt(String key, int deflt) {
+ return 0;
+ }
+
+ @Override
+ public long getLong(String key, long deflt) {
+ return 0;
+ }
+
+ @Override
+ public boolean isUserNode() {
+ return false;
+ }
+
+ @Override
+ public String[] keys() throws BackingStoreException {
+ return null;
+ }
+
+ @Override
+ public String name() {
+ return null;
+ }
+
+ @Override
+ public Preferences node(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean nodeExists(String name) throws BackingStoreException {
+ return false;
+ }
+
+ @Override
+ public Preferences parent() {
+ return null;
+ }
+
+ @Override
+ public void put(String key, String value) {
+
+ }
+
+ @Override
+ public void putBoolean(String key, boolean value) {
+
+ }
+
+ @Override
+ public void putByteArray(String key, byte[] value) {
+
+ }
+
+ @Override
+ public void putDouble(String key, double value) {
+
+ }
+
+ @Override
+ public void putFloat(String key, float value) {
+
+ }
+
+ @Override
+ public void putInt(String key, int value) {
+
+ }
+
+ @Override
+ public void putLong(String key, long value) {
+
+ }
+
+ @Override
+ public void remove(String key) {
+
+ }
+
+ @Override
+ public void removeNode() throws BackingStoreException {
+
+ }
+
+ @Override
+ public void addNodeChangeListener(NodeChangeListener ncl) {
+
+ }
+
+ @Override
+ public void addPreferenceChangeListener(PreferenceChangeListener pcl) {
+
+ }
+
+ @Override
+ public void removeNodeChangeListener(NodeChangeListener ncl) {
+
+ }
+
+ @Override
+ public void removePreferenceChangeListener(PreferenceChangeListener pcl) {
+
+ }
+
+ @Override
+ public void sync() throws BackingStoreException {
+
+ }
+
+ @Override
+ public String toString() {
+ return null;
+ }
+
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
index 98450a4..9f749c6 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
@@ -22,7 +22,6 @@ import java.util.regex.Pattern;
import junit.framework.TestCase;
-@SuppressWarnings("nls")
public class MatcherTest extends TestCase {
String[] testPatterns = {
"(a|b)*abb",
@@ -40,42 +39,42 @@ public class MatcherTest extends TestCase {
public MatcherTest(String name) {
super(name);
}
-
+
public void testRegionsIntInt() {
Pattern p = Pattern.compile("x*");
Matcher m = p.matcher("axxxxxa");
assertFalse(m.matches());
-
+
m.region(1, 6);
assertEquals(1, m.regionStart());
assertEquals(6, m.regionEnd());
assertTrue(m.matches());
-
+
try {
m.region(1, 0);
fail("expected an IOOBE");
} catch(IndexOutOfBoundsException e) {
}
-
+
try {
m.region(-1, 2);
fail("expected an IOOBE");
} catch(IndexOutOfBoundsException e) {
}
-
+
try {
m.region(10, 11);
fail("expected an IOOBE");
} catch(IndexOutOfBoundsException e) {
}
-
+
try {
m.region(1, 10);
fail("expected an IOOBE");
} catch(IndexOutOfBoundsException e) {
}
}
-
+
public void testAppendReplacement() {
Pattern pat = Pattern.compile("XX");
Matcher m = pat.matcher("Today is XX-XX-XX ...");
@@ -109,16 +108,13 @@ public class MatcherTest extends TestCase {
assertEquals("-foo-foo-foo-", mat.replaceAll("-"));
}
- /*
- * Class under test for Matcher reset(CharSequence)
- */
public void testResetCharSequence() {
Pattern p = Pattern.compile("abcd");
Matcher m = p.matcher("abcd");
assertTrue(m.matches());
m.reset("efgh");
assertFalse(m.matches());
-
+
try {
m.reset(null);
fail("expected a NPE");
@@ -159,15 +155,9 @@ public class MatcherTest extends TestCase {
}
}
- /*
- * Class under test for Matcher reset()
- */
public void testReset() {
}
- /*
- * Class under test for String group(int)
- */
public void testGroupint() {
String positiveTestString = "ababababbaaabb";
@@ -245,24 +235,6 @@ public class MatcherTest extends TestCase {
assertEquals("a", mat.group(1));
}
- /*
- * Class under test for boolean find(int)
- */
- public void testFindint() {
- }
-
- /*
- * Class under test for int start(int)
- */
- public void testStartint() {
- }
-
- /*
- * Class under test for int end(int)
- */
- public void testEndint() {
- }
-
public void testMatchesMisc() {
String[][] posSeq = {
{ "abb", "ababb", "abababbababb", "abababbababbabababbbbbabb" },
@@ -350,9 +322,6 @@ public class MatcherTest extends TestCase {
public void testLookingAt() {
}
- /*
- * Class under test for boolean find()
- */
public void testFind() {
String testPattern = "(abb)";
String testString = "cccabbabbabbabbabb";
@@ -389,12 +358,6 @@ public class MatcherTest extends TestCase {
assertTrue(mat.matches());
}
- /*
- * Class under test for int start()
- */
- public void testStart() {
- }
-
public void testGroupCount() {
for (int i = 0; i < groupPatterns.length; i++) {
Pattern test = Pattern.compile(groupPatterns[i]);
@@ -595,11 +558,9 @@ public class MatcherTest extends TestCase {
assertEquals("a", mat.group());
}
- /*
- * Verify if the Matcher can match the input when region is changed
- */
public void testMatchesRegionChanged() {
// Regression for HARMONY-610
+ // Verify if the Matcher can match the input when region is changed
String input = " word ";
Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher(input);
@@ -645,11 +606,9 @@ public class MatcherTest extends TestCase {
assertEquals(0x110000 / step, cnt);
}
- /*
- * Verify if the Matcher behaves correct when region is changed
- */
public void testFindRegionChanged() {
// Regression for HARMONY-625
+ // Verify if the Matcher behaves correct when region is changed.
Pattern pattern = Pattern.compile("(?s).*");
Matcher matcher = pattern.matcher("abcde");
matcher.find();
@@ -662,12 +621,9 @@ public class MatcherTest extends TestCase {
}
- /*
- * Verify if the Matcher behaves correct with pattern "c" when region is
- * changed
- */
public void testFindRegionChanged2() {
// Regression for HARMONY-713
+ // Verify if the Matcher behaves correct with pattern "c" when region is changed.
Pattern pattern = Pattern.compile("c");
String inputStr = "aabb.c";
@@ -677,18 +633,14 @@ public class MatcherTest extends TestCase {
assertFalse(matcher.find());
}
- /*
- * Regression test for HARMONY-674
- */
public void testPatternMatcher() throws Exception {
+ // Regression test for HARMONY-674
Pattern pattern = Pattern.compile("(?:\\d+)(?:pt)");
assertTrue(pattern.matcher("14pt").matches());
}
- /**
- * Inspired by HARMONY-3360
- */
public void test3360() {
+ // Inspired by HARMONY-3360
String str = "!\"#%&'(),-./";
Pattern p = Pattern.compile("\\s");
Matcher m = p.matcher(str);
@@ -696,12 +648,9 @@ public class MatcherTest extends TestCase {
assertFalse(m.find());
}
- /**
- * Regression test for HARMONY-3360
- */
public void testGeneralPunctuationCategory() {
- String[] s = { ",", "!", "\"", "#", "%", "&", "'", "(", ")", "-", ".",
- "/" };
+ // Regression test for HARMONY-3360
+ String[] s = { ",", "!", "\"", "#", "%", "&", "'", "(", ")", "-", ".", "/" };
String regexp = "\\p{P}";
for (int i = 0; i < s.length; i++) {
@@ -711,10 +660,8 @@ public class MatcherTest extends TestCase {
}
}
- /**
- * Regression test for HARMONY-4396
- */
public void testHitEndAfterFind() {
+ // Regression test for HARMONY-4396
hitEndTest(true, "#01.0", "r((ege)|(geg))x", "regexx", false);
hitEndTest(true, "#01.1", "r((ege)|(geg))x", "regex", false);
hitEndTest(true, "#01.2", "r((ege)|(geg))x", "rege", true);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/A.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/A.java
new file mode 100644
index 0000000..a03935a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/A.java
@@ -0,0 +1,13 @@
+package org.apache.harmony.tests.java.util.support;
+
+public class A implements I {
+ private static P pp = new P();
+
+ public A() {
+ pp.setClazz(getClass());
+ }
+
+ public String find(String key) {
+ return pp.findProp(key);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/B.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/B.java
new file mode 100644
index 0000000..03ebb15
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/B.java
@@ -0,0 +1,4 @@
+package org.apache.harmony.tests.java.util.support;
+
+public class B extends A {
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/I.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/I.java
new file mode 100644
index 0000000..4538945
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/I.java
@@ -0,0 +1,5 @@
+package org.apache.harmony.tests.java.util.support;
+
+public interface I {
+ String find(String key);
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/P.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/P.java
new file mode 100644
index 0000000..bba2537
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/support/P.java
@@ -0,0 +1,28 @@
+package org.apache.harmony.tests.java.util.support;
+
+import java.util.ResourceBundle;
+
+public class P {
+ private Class c;
+
+ public void setClazz(Class c) {
+ this.c = c;
+ }
+
+ public String findProp(String key) {
+ return findProp(this.c, key);
+ }
+
+ private String findProp(Class cls, String key) {
+ String ret = null;
+ try {
+ ResourceBundle b = ResourceBundle.getBundle(cls.getName());
+ ret = (String)b.getObject(key);
+ } catch (Exception e) {
+ }
+ if (ret == null && !cls.equals(Object.class) && !cls.isPrimitive()) {
+ ret = findProp(cls.getSuperclass(), key);
+ }
+ return ret;
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/Adler32Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/Adler32Test.java
new file mode 100644
index 0000000..7555896
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/Adler32Test.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.util.zip.Adler32;
+
+public class Adler32Test extends junit.framework.TestCase {
+
+ /**
+ * java.util.zip.Adler32#Adler32()
+ */
+ public void test_Constructor() {
+ // test method of java.util.zip.Adler32()
+ Adler32 adl = new Adler32();
+ assertEquals("Constructor of adl32 failed", 1, adl.getValue());
+ }
+
+ /**
+ * java.util.zip.Adler32#getValue()
+ */
+ public void test_getValue() {
+ // test methods of java.util.zip.getValue()
+ Adler32 adl = new Adler32();
+ assertEquals("GetValue should return a zero as a result of construction an object of Adler32",
+ 1, adl.getValue());
+
+ adl.reset();
+ adl.update(1);
+ // System.out.print("value of adl"+adl.getValue());
+ // The value of the adl should be 131074
+ assertEquals("update(int) failed to update the checksum to the correct value ",
+ 131074, adl.getValue());
+ adl.reset();
+ assertEquals("reset failed to reset the checksum value to zero", 1, adl
+ .getValue());
+
+ adl.reset();
+ adl.update(Integer.MIN_VALUE);
+ // System.out.print("value of adl " + adl.getValue());
+ // The value of the adl should be 65537
+ assertEquals("update(min) failed to update the checksum to the correct value ",
+ 65537L, adl.getValue());
+ }
+
+ /**
+ * java.util.zip.Adler32#reset()
+ */
+ public void test_reset() {
+ // test methods of java.util.zip.reset()
+ Adler32 adl = new Adler32();
+ adl.update(1);
+ // System.out.print("value of adl"+adl.getValue());
+ // The value of the adl should be 131074
+ assertEquals("update(int) failed to update the checksum to the correct value ",
+ 131074, adl.getValue());
+ adl.reset();
+ assertEquals("reset failed to reset the checksum value to zero", 1, adl
+ .getValue());
+ }
+
+ /**
+ * java.util.zip.Adler32#update(int)
+ */
+ public void test_updateI() {
+ // test methods of java.util.zip.update(int)
+ Adler32 adl = new Adler32();
+ adl.update(1);
+ // The value of the adl should be 131074
+ assertEquals("update(int) failed to update the checksum to the correct value ",
+ 131074, adl.getValue());
+
+ adl.reset();
+ adl.update(Integer.MAX_VALUE);
+ // System.out.print("value of adl " + adl.getValue());
+ // The value of the adl should be 16777472
+ assertEquals("update(max) failed to update the checksum to the correct value ",
+ 16777472L, adl.getValue());
+
+ adl.reset();
+ adl.update(Integer.MIN_VALUE);
+ // System.out.print("value of adl " + adl.getValue());
+ // The value of the adl should be 65537
+ assertEquals("update(min) failed to update the checksum to the correct value ",
+ 65537L, adl.getValue());
+
+ }
+
+ /**
+ * java.util.zip.Adler32#update(byte[])
+ */
+ public void test_update$B() {
+ // test method of java.util.zip.update(byte[])
+ byte byteArray[] = { 1, 2 };
+ Adler32 adl = new Adler32();
+ adl.update(byteArray);
+ // System.out.print("value of adl"+adl.getValue());
+ // The value of the adl should be 393220
+ assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+ 393220, adl.getValue());
+
+ adl.reset();
+ byte byteEmpty[] = new byte[10000];
+ adl.update(byteEmpty);
+ // System.out.print("value of adl"+adl.getValue());
+ // The value of the adl should be 655360001
+ assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+ 655360001L, adl.getValue());
+
+ }
+
+ /**
+ * java.util.zip.Adler32#update(byte[], int, int)
+ */
+ public void test_update$BII() {
+ // test methods of java.util.zip.update(byte[],int,int)
+ byte[] byteArray = { 1, 2, 3 };
+ Adler32 adl = new Adler32();
+ int off = 2;// accessing the 2nd element of byteArray
+ int len = 1;
+ int lenError = 3;
+ int offError = 4;
+ adl.update(byteArray, off, len);
+ // System.out.print("value of adl"+adl.getValue());
+ // The value of the adl should be 262148
+ assertEquals("update(byte[],int,int) failed to update the checksum to the correct value ",
+ 262148, adl.getValue());
+ int r = 0;
+
+ try {
+ adl.update(byteArray, off, lenError);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ r = 1;
+ }
+ assertEquals("update(byte[],int,int) failed b/c lenError>byte[].length-off",
+ 1, r);
+
+ try {
+ adl.update(byteArray, offError, len);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ r = 2;
+ }
+ assertEquals("update(byte[],int,int) failed b/c offError>byte[].length",
+ 2, r);
+
+ }
+
+ @Override
+ protected void setUp() {
+ }
+
+ @Override
+ protected void tearDown() {
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CRC32Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CRC32Test.java
new file mode 100644
index 0000000..30bdf9f
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CRC32Test.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.util.zip.CRC32;
+
+public class CRC32Test extends junit.framework.TestCase {
+
+ /**
+ * java.util.zip.CRC32#CRC32()
+ */
+ public void test_Constructor() {
+ // test methods of java.util.zip.CRC32()
+ CRC32 crc = new CRC32();
+ assertEquals("Constructor of CRC32 failed", 0, crc.getValue());
+ }
+
+ /**
+ * java.util.zip.CRC32#getValue()
+ */
+ public void test_getValue() {
+ // test methods of java.util.zip.crc32.getValue()
+ CRC32 crc = new CRC32();
+ assertEquals("getValue() should return a zero as a result of constructing a CRC32 instance",
+ 0, crc.getValue());
+
+ crc.reset();
+ crc.update(Integer.MAX_VALUE);
+ // System.out.print("value of crc " + crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 4278190080
+ assertEquals("update(max) failed to update the checksum to the correct value ",
+ 4278190080L, crc.getValue());
+
+ crc.reset();
+ byte byteEmpty[] = new byte[10000];
+ crc.update(byteEmpty);
+ // System.out.print("value of crc"+crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 1295764014
+ assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+ 1295764014L, crc.getValue());
+
+ crc.reset();
+ crc.update(1);
+ // System.out.print("value of crc"+crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 2768625435
+ // assertEquals("update(int) failed to update the checksum to the correct
+ // value ",2768625435L, crc.getValue());
+ crc.reset();
+ assertEquals("reset failed to reset the checksum value to zero", 0, crc
+ .getValue());
+ }
+
+ /**
+ * java.util.zip.CRC32#reset()
+ */
+ public void test_reset() {
+ // test methods of java.util.zip.crc32.reset()
+ CRC32 crc = new CRC32();
+ crc.update(1);
+ // System.out.print("value of crc"+crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 2768625435
+ assertEquals("update(int) failed to update the checksum to the correct value ",
+ 2768625435L, crc.getValue());
+ crc.reset();
+ assertEquals("reset failed to reset the checksum value to zero", 0, crc
+ .getValue());
+
+ }
+
+ /**
+ * java.util.zip.CRC32#update(int)
+ */
+ public void test_updateI() {
+ // test methods of java.util.zip.crc32.update(int)
+ CRC32 crc = new CRC32();
+ crc.update(1);
+ // System.out.print("value of crc"+crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 2768625435
+ assertEquals("update(1) failed to update the checksum to the correct value ",
+ 2768625435L, crc.getValue());
+
+ crc.reset();
+ crc.update(Integer.MAX_VALUE);
+ // System.out.print("value of crc " + crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 4278190080
+ assertEquals("update(max) failed to update the checksum to the correct value ",
+ 4278190080L, crc.getValue());
+
+ crc.reset();
+ crc.update(Integer.MIN_VALUE);
+ // System.out.print("value of crc " + crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 3523407757
+ assertEquals("update(min) failed to update the checksum to the correct value ",
+ 3523407757L, crc.getValue());
+ }
+
+ /**
+ * java.util.zip.CRC32#update(byte[])
+ */
+ public void test_update$B() {
+ // test methods of java.util.zip.crc32.update(byte[])
+ byte byteArray[] = { 1, 2 };
+ CRC32 crc = new CRC32();
+ crc.update(byteArray);
+ // System.out.print("value of crc"+crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 3066839698
+ assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+ 3066839698L, crc.getValue());
+
+ crc.reset();
+ byte byteEmpty[] = new byte[10000];
+ crc.update(byteEmpty);
+ // System.out.print("value of crc"+crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 1295764014
+ assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+ 1295764014L, crc.getValue());
+ }
+
+ /**
+ * java.util.zip.CRC32#update(byte[], int, int)
+ */
+ public void test_update$BII() {
+ // test methods of java.util.zip.update(byte[],int,int)
+ byte[] byteArray = { 1, 2, 3 };
+ CRC32 crc = new CRC32();
+ int off = 2;// accessing the 2nd element of byteArray
+ int len = 1;
+ int lenError = 3;
+ int offError = 4;
+ crc.update(byteArray, off, len);
+ // System.out.print("value of crc"+crc.getValue());
+ // Ran JDK and discovered that the value of the CRC should be
+ // 1259060791
+ assertEquals("update(byte[],int,int) failed to update the checksum to the correct value ",
+ 1259060791L, crc.getValue());
+ int r = 0;
+ try {
+ crc.update(byteArray, off, lenError);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ r = 1;
+ }
+ assertEquals("update(byte[],int,int) failed b/c lenError>byte[].length-off",
+ 1, r);
+
+ try {
+ crc.update(byteArray, offError, len);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ r = 2;
+ }
+ assertEquals("update(byte[],int,int) failed b/c offError>byte[].length",
+ 2, r);
+ }
+
+ @Override
+ protected void setUp() {
+
+ }
+
+ @Override
+ protected void tearDown() {
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CheckedInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CheckedInputStreamTest.java
new file mode 100644
index 0000000..903f60b
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CheckedInputStreamTest.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedInputStream;
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
+public class CheckedInputStreamTest extends TestCase {
+
+ /**
+ * java.util.zip.CheckedInputStream#CheckedInputStream(java.io.InputStream,
+ *java.util.zip.Checksum)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_util_zip_Checksum() throws Exception {
+ InputStream checkInput = Support_Resources.getStream("hyts_checkInput.txt");
+ CheckedInputStream checkIn = new CheckedInputStream(checkInput, new CRC32());
+ assertEquals("constructor of checkedInputStream has failed", 0, checkIn.getChecksum()
+ .getValue());
+ checkInput.close();
+ }
+
+ /**
+ * java.util.zip.CheckedInputStream#getChecksum()
+ */
+ public void test_getChecksum() throws Exception {
+ byte outBuf[] = new byte[100];
+ File f = File.createTempFile("CheckedInputStreamTest", ".txt");
+ InputStream inEmp = new FileInputStream(f);
+ CheckedInputStream checkEmpty = new CheckedInputStream(inEmp, new CRC32());
+ while (checkEmpty.read() >= 0) {
+ }
+ assertEquals("the checkSum value of an empty file is not zero", 0, checkEmpty
+ .getChecksum().getValue());
+ inEmp.close();
+
+ // testing getChecksum for the file checkInput
+ InputStream checkInput = Support_Resources.getStream("hyts_checkInput.txt");
+ CheckedInputStream checkIn = new CheckedInputStream(checkInput, new CRC32());
+ while (checkIn.read() >= 0) {
+ }
+ // ran JDK and found that the checkSum value of this is 2036203193
+ // System.out.print(" " + checkIn.getChecksum().getValue());
+ assertEquals("the checksum value is incorrect", 2036203193, checkIn.getChecksum()
+ .getValue());
+ checkInput.close();
+ // testing getChecksum for file checkInput
+ checkInput = Support_Resources.getStream("hyts_checkInput.txt");
+ CheckedInputStream checkIn2 = new CheckedInputStream(checkInput, new CRC32());
+ checkIn2.read(outBuf, 0, 10);
+ // ran JDK and found that the checkSum value of this is 2235765342
+ // System.out.print(" " + checkIn2.getChecksum().getValue());
+ assertEquals("the checksum value is incorrect", 2235765342L, checkIn2.getChecksum()
+ .getValue());
+ checkInput.close();
+ }
+
+ /**
+ * java.util.zip.CheckedInputStream#skip(long)
+ */
+ public void test_skipJ() throws Exception {
+ // testing that the return by skip is valid
+ InputStream checkInput = Support_Resources.getStream("hyts_checkInput.txt");
+ CheckedInputStream checkIn = new CheckedInputStream(checkInput, new CRC32());
+ long skipValue = 5;
+ assertEquals("the value returned by skip(n) is not the same as its parameter",
+ skipValue, checkIn.skip(skipValue));
+ checkIn.skip(skipValue);
+ // ran JDK and found the checkSum value is 2235765342
+ // System.out.print(checkIn.getChecksum().getValue());
+ assertEquals("checkSum value is not correct", 2235765342L, checkIn.getChecksum()
+ .getValue());
+ assertEquals(0, checkIn.skip(0));
+ checkInput.close();
+ }
+
+ public void test_read() throws Exception {
+ // testing that the return by skip is valid
+ InputStream checkInput = Support_Resources
+ .getStream("hyts_checkInput.txt");
+ CheckedInputStream checkIn = new CheckedInputStream(checkInput,
+ new CRC32());
+ checkIn.read();
+ checkIn.close();
+ try {
+ checkIn.read();
+ fail("IOException expected.");
+ } catch (IOException ee) {
+ // expected
+ }
+ checkInput.close();
+ }
+
+ public void test_read$byteII() throws Exception {
+ // testing that the return by skip is valid
+ InputStream checkInput = Support_Resources
+ .getStream("hyts_checkInput.txt");
+ CheckedInputStream checkIn = new CheckedInputStream(checkInput,
+ new CRC32());
+ byte buff[] = new byte[50];
+ checkIn.read(buff, 10, 5);
+ checkIn.close();
+ try {
+ checkIn.read(buff, 10, 5);
+ fail("IOException expected.");
+ } catch (IOException ee) {
+ // expected
+ }
+ checkInput.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CheckedOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CheckedOutputStreamTest.java
new file mode 100644
index 0000000..09d5756
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/CheckedOutputStreamTest.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.Adler32;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedOutputStream;
+
+public class CheckedOutputStreamTest extends junit.framework.TestCase {
+
+ /**
+ * java.util.zip.CheckedOutputStream#CheckedOutputStream(java.io.OutputStream,
+ *java.util.zip.Checksum)
+ */
+ public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_Checksum() {
+ // test method java.util.zip.checkedOutputStream.constructor
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("CheckedOutputStreamTest", ".txt"));
+ CheckedOutputStream chkOut = new CheckedOutputStream(outFile,
+ new CRC32());
+ assertEquals("the checkSum value of the constructor is not 0", 0, chkOut
+ .getChecksum().getValue());
+ outFile.close();
+ } catch (IOException e) {
+ fail("Unable to find file");
+ } catch (SecurityException e) {
+ fail(
+ "file cannot be opened for writing due to security reasons");
+ }
+ }
+
+ /**
+ * java.util.zip.CheckedOutputStream#getChecksum()
+ */
+ public void test_getChecksum() {
+ // test method java.util.zip.checkedOutputStream.getChecksum()
+ byte byteArray[] = { 1, 2, 3, 'e', 'r', 't', 'g', 3, 6 };
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("CheckedOutputStreamTest", ".txt"));
+ CheckedOutputStream chkOut = new CheckedOutputStream(outFile,
+ new Adler32());
+ chkOut.write(byteArray[4]);
+ // ran JDK and found that checkSum value is 7536755
+ // System.out.print(chkOut.getChecksum().getValue());
+
+ assertEquals("the checkSum value for writeI is incorrect", 7536755, chkOut
+ .getChecksum().getValue());
+ chkOut.getChecksum().reset();
+ chkOut.write(byteArray, 5, 4);
+ // ran JDK and found that checkSum value is 51708133
+ // System.out.print(" " +chkOut.getChecksum().getValue());
+
+ assertEquals("the checkSum value for writeBII is incorrect ", 51708133, chkOut
+ .getChecksum().getValue());
+ outFile.close();
+ } catch (IOException e) {
+ fail("Unable to find file");
+ } catch (SecurityException e) {
+ fail(
+ "file cannot be opened for writing due to security reasons");
+ }
+ }
+
+ /**
+ * java.util.zip.CheckedOutputStream#write(int)
+ */
+ public void test_writeI() {
+ // test method java.util.zip.checkedOutputStream.writeI()
+ byte byteArray[] = { 1, 2, 3, 'e', 'r', 't', 'g', 3, 6 };
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("CheckedOutputStreamTest", ".txt"));
+ CheckedOutputStream chkOut = new CheckedOutputStream(outFile,
+ new CRC32());
+ for (byte element : byteArray) {
+ chkOut.write(element);
+ }
+ assertTrue(
+ "the checkSum value is zero, no bytes are written to the output file",
+ chkOut.getChecksum().getValue() != 0);
+ outFile.close();
+ } catch (IOException e) {
+ fail("Unable to find file");
+ } catch (SecurityException e) {
+ fail("File cannot be opened for writing due to security reasons");
+ }
+ }
+
+ /**
+ * java.util.zip.CheckedOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() {
+ // test method java.util.zip.checkOutputStream.writeBII()
+ byte byteArray[] = { 1, 2, 3, 'e', 'r', 't', 'g', 3, 6 };
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("CheckedOutputStreamTest", ".txt"));
+ CheckedOutputStream chkOut = new CheckedOutputStream(outFile,
+ new CRC32());
+ chkOut.write(byteArray, 4, 5);
+ assertTrue(
+ "the checkSum value is zero, no bytes are written to the output file",
+ chkOut.getChecksum().getValue() != 0);
+ int r = 0;
+ try {
+ chkOut.write(byteArray, 4, 6);
+ } catch (IndexOutOfBoundsException e) {
+ r = 1;
+ }
+ assertEquals("boundary check is not performed", 1, r);
+ outFile.close();
+ } catch (IOException e) {
+ fail("Unable to find file");
+ } catch (SecurityException e) {
+ fail(
+ "file cannot be opened for writing due to security reasons");
+ } catch (IndexOutOfBoundsException e) {
+ fail("Index for write is out of bounds");
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterInputStreamTest.java
new file mode 100644
index 0000000..7ed5916
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterInputStreamTest.java
@@ -0,0 +1,426 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterInputStream;
+
+import junit.framework.TestCase;
+import libcore.io.Streams;
+
+public class DeflaterInputStreamTest extends TestCase {
+
+ private static final String TEST_STR = "Hi,this is a test";
+
+ private static final byte[] TEST_STRING_DEFLATED_BYTES = {
+ 120, -100, -13, -56, -44, 41, -55, -56, 44, 86,
+ 0, -94, 68, -123, -110, -44, -30, 18, 0, 52,
+ 34, 5, -13 };
+
+ private InputStream is;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8"));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ is.close();
+ super.tearDown();
+ }
+
+ /**
+ * DeflaterInputStream#available()
+ */
+ public void testAvailable() throws IOException {
+ byte[] buf = new byte[1024];
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ assertEquals(1, dis.available());
+ assertEquals(120, dis.read());
+ assertEquals(1, dis.available());
+ assertEquals(22, dis.read(buf, 0, 1024));
+ assertEquals(0, dis.available());
+ assertEquals(-1, dis.read());
+ assertEquals(0, dis.available());
+ dis.close();
+ try {
+ dis.available();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * DeflaterInputStream#close()
+ */
+ public void testClose() throws IOException {
+ byte[] buf = new byte[1024];
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ assertEquals(1, dis.available());
+ dis.close();
+ try {
+ dis.available();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ dis.read(buf, 0, 1024);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ // can close after close
+ dis.close();
+ }
+
+ /**
+ * DeflaterInputStream#mark()
+ */
+ public void testMark() throws IOException {
+ // mark do nothing
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ dis.mark(-1);
+ dis.mark(0);
+ dis.mark(1);
+ dis.close();
+ dis.mark(1);
+ }
+
+ /**
+ * DeflaterInputStream#markSupported()
+ */
+ public void testMarkSupported() throws IOException {
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ assertFalse(dis.markSupported());
+ dis.close();
+ assertFalse(dis.markSupported());
+ }
+
+ /**
+ * DeflaterInputStream#read()
+ */
+ public void testRead() throws IOException {
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ assertEquals(1, dis.available());
+ assertEquals(120, dis.read());
+ assertEquals(1, dis.available());
+ assertEquals(156, dis.read());
+ assertEquals(1, dis.available());
+ assertEquals(243, dis.read());
+ assertEquals(1, dis.available());
+ dis.close();
+ try {
+ dis.read();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ public void testRead_golden() throws Exception {
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ byte[] contents = Streams.readFully(dis);
+ assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, contents));
+
+ byte[] result = new byte[32];
+ dis = new DeflaterInputStream(new ByteArrayInputStream(TEST_STR.getBytes("UTF-8")));
+ int count = 0;
+ int bytesRead = 0;
+ while ((bytesRead = dis.read(result, count, 4)) != -1) {
+ count += bytesRead;
+ }
+ assertEquals(23, count);
+ byte[] splicedResult = new byte[23];
+ System.arraycopy(result, 0, splicedResult, 0, 23);
+ assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, splicedResult));
+ }
+
+ public void testRead_leavesBufUnmodified() throws Exception {
+ DeflaterInputStreamWithPublicBuffer dis = new DeflaterInputStreamWithPublicBuffer(is);
+ byte[] contents = Streams.readFully(dis);
+ assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, contents));
+
+ // protected field buf is a part of the public API of this class.
+ // we guarantee that it's only used as an input buffer, and not for
+ // anything else.
+ byte[] buf = dis.getBuffer();
+ byte[] expected = TEST_STR.getBytes("UTF-8");
+
+ byte[] splicedBuf = new byte[expected.length];
+ System.arraycopy(buf, 0, splicedBuf, 0, splicedBuf.length);
+ assertTrue(Arrays.equals(expected, splicedBuf));
+ }
+
+ /**
+ * DeflaterInputStream#read(byte[], int, int)
+ */
+ public void testReadByteArrayIntInt() throws IOException {
+ byte[] buf1 = new byte[256];
+ byte[] buf2 = new byte[256];
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ assertEquals(23, dis.read(buf1, 0, 256));
+ dis = new DeflaterInputStream(is);
+ assertEquals(8, dis.read(buf2, 0, 256));
+ is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8"));
+ dis = new DeflaterInputStream(is);
+ assertEquals(1, dis.available());
+ assertEquals(120, dis.read());
+ assertEquals(1, dis.available());
+ assertEquals(22, dis.read(buf2, 0, 256));
+ assertEquals(0, dis.available());
+ assertEquals(-1, dis.read());
+ assertEquals(0, dis.available());
+ try {
+ dis.read(buf1, 0, 512);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ dis.read(null, 0, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ dis.read(null, -1, 0);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ dis.read(null, -1, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ dis.read(buf1, -1, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ dis.read(buf1, 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ dis.close();
+ try {
+ dis.read(buf1, 0, 512);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ dis.read(buf1, 0, 1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ dis.read(null, 0, 0);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ dis.read(null, -1, 0);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ dis.read(null, -1, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ dis.read(buf1, -1, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ dis.read(buf1, 0, -1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * DeflaterInputStream#reset()
+ */
+ public void testReset() throws IOException {
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ try {
+ dis.reset();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ dis.close();
+ try {
+ dis.reset();
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * DeflaterInputStream#skip()
+ */
+ public void testSkip() throws IOException {
+ byte[] buf = new byte[1024];
+ DeflaterInputStream dis = new DeflaterInputStream(is);
+ assertEquals(1, dis.available());
+ dis.skip(1);
+ assertEquals(1, dis.available());
+ assertEquals(22, dis.read(buf, 0, 1024));
+ assertEquals(0, dis.available());
+ assertEquals(0, dis.available());
+ is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8"));
+ dis = new DeflaterInputStream(is);
+ assertEquals(1, dis.available());
+ dis.skip(56);
+ assertEquals(0, dis.available());
+ assertEquals(-1, dis.read(buf, 0, 1024));
+
+ assertEquals(0, dis.available());
+ // can still skip
+ dis.skip(1);
+ dis.close();
+ try {
+ dis.skip(1);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8"));
+ dis = new DeflaterInputStream(is);
+ assertEquals(23, dis.skip(Long.MAX_VALUE));
+ assertEquals(0, dis.available());
+ }
+
+ /**
+ * DeflaterInputStream#DeflaterInputStream(InputStream)
+ */
+ public void testDeflaterInputStreamInputStream() {
+ // ok
+ new DeflaterInputStream(is);
+ // fail
+ try {
+ new DeflaterInputStream(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * DataFormatException#DataFormatException()
+ */
+ public void testDataFormatException() {
+ new DataFormatException();
+ }
+
+ /**
+ * DeflaterInputStream#DeflaterInputStream(InputStream, Deflater)
+ */
+ public void testDeflaterInputStreamInputStreamDeflater() {
+ // ok
+ new DeflaterInputStream(is, new Deflater());
+ // fail
+ try {
+ new DeflaterInputStream(is, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new DeflaterInputStream(null, new Deflater());
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * DeflaterInputStream#DeflaterInputStream(InputStream, Deflater, int)
+ */
+ public void testDeflaterInputStreamInputStreamDeflaterInt() {
+ // ok
+ new DeflaterInputStream(is, new Deflater(), 1024);
+ // fail
+ try {
+ new DeflaterInputStream(is, null, 1024);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new DeflaterInputStream(null, new Deflater(), 1024);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new DeflaterInputStream(is, new Deflater(), -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ new DeflaterInputStream(null, new Deflater(), -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ new DeflaterInputStream(is, null, -1);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public static final class DeflaterInputStreamWithPublicBuffer extends DeflaterInputStream {
+
+ public DeflaterInputStreamWithPublicBuffer(InputStream in) {
+ super(in);
+ }
+
+ public byte[] getBuffer() {
+ return buf;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterOutputStreamTest.java
new file mode 100644
index 0000000..e4be198
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterOutputStreamTest.java
@@ -0,0 +1,402 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.InflaterInputStream;
+
+import junit.framework.TestCase;
+
+public class DeflaterOutputStreamTest extends TestCase {
+
+ private class MyDeflaterOutputStream extends DeflaterOutputStream {
+ boolean deflateFlag = false;
+
+ MyDeflaterOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ MyDeflaterOutputStream(OutputStream out, Deflater defl) {
+ super(out, defl);
+ }
+
+ MyDeflaterOutputStream(OutputStream out, Deflater defl, int size) {
+ super(out, defl, size);
+ }
+
+ byte[] getProtectedBuf() {
+ return buf;
+ }
+
+ protected void deflate() throws IOException {
+ deflateFlag = true;
+ super.deflate();
+ }
+
+ boolean getDaflateFlag() {
+ return deflateFlag;
+ }
+ }
+
+ private final byte outputBuf[] = new byte[500];
+
+ @Override
+ protected void setUp() {
+ // setting up a deflater to be used
+ byte byteArray[] = { 1, 3, 4, 7, 8 };
+ int x = 0;
+ Deflater deflate = new Deflater(1);
+ deflate.setInput(byteArray);
+ while (!(deflate.needsInput())) {
+ x += deflate.deflate(outputBuf, x, outputBuf.length - x);
+ }
+ deflate.finish();
+ while (!(deflate.finished())) {
+ x = x + deflate.deflate(outputBuf, x, outputBuf.length - x);
+ }
+ deflate.end();
+ }
+
+ /**
+ * java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream,
+ *java.util.zip.Deflater)
+ */
+ public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_Deflater() throws Exception {
+ byte byteArray[] = { 1, 3, 4, 7, 8 };
+ File f1 = File.createTempFile("hyts_ConstruOD", ".tst");
+ FileOutputStream fos = new FileOutputStream(f1);
+ Deflater defl = null;
+ MyDeflaterOutputStream dos;
+ // Test for a null Deflater.
+ try {
+ dos = new MyDeflaterOutputStream(fos, defl);
+ fail("NullPointerException Not Thrown");
+ } catch (NullPointerException e) {
+ }
+ defl = new Deflater();
+ dos = new MyDeflaterOutputStream(fos, defl);
+
+ // Test to see if DeflaterOutputStream was created with the correct
+ // buffer.
+ assertEquals("Incorrect Buffer Size", 512, dos.getProtectedBuf().length);
+
+ dos.write(byteArray);
+ dos.close();
+ f1.delete();
+ }
+
+ /**
+ * java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() throws Exception {
+ File f1 = File.createTempFile("hyts_ConstruO", ".tst");
+ FileOutputStream fos = new FileOutputStream(f1);
+ MyDeflaterOutputStream dos = new MyDeflaterOutputStream(fos);
+
+ // Test to see if DeflaterOutputStream was created with the correct
+ // buffer.
+ assertEquals("Incorrect Buffer Size", 512, dos.getProtectedBuf().length);
+
+ dos.write(outputBuf);
+ dos.close();
+ f1.delete();
+ }
+
+ /**
+ * java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream,
+ *java.util.zip.Deflater, int)
+ */
+ public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_DeflaterI()
+ throws Exception {
+ int buf = 5;
+ int negBuf = -5;
+ int zeroBuf = 0;
+ byte byteArray[] = { 1, 3, 4, 7, 8, 3, 6 };
+ File f1 = File.createTempFile("hyts_ConstruODI", ".tst");
+ FileOutputStream fos = new FileOutputStream(f1);
+ Deflater defl = null;
+ MyDeflaterOutputStream dos;
+
+ // Test for a null Deflater.
+ try {
+ dos = new MyDeflaterOutputStream(fos, defl, buf);
+ fail("NullPointerException Not Thrown");
+ } catch (NullPointerException e) {
+ }
+ defl = new Deflater();
+
+ // Test for a negative buf.
+ try {
+ dos = new MyDeflaterOutputStream(fos, defl, negBuf);
+ fail("IllegalArgumentException Not Thrown");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // Test for a zero buf.
+ try {
+ dos = new MyDeflaterOutputStream(fos, defl, zeroBuf);
+ fail("IllegalArgumentException Not Thrown");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // Test to see if DeflaterOutputStream was created with the correct
+ // buffer.
+ dos = new MyDeflaterOutputStream(fos, defl, buf);
+ assertEquals("Incorrect Buffer Size", 5, dos.getProtectedBuf().length);
+
+ dos.write(byteArray);
+ dos.close();
+ f1.delete();
+ }
+
+ /**
+ * java.util.zip.DeflaterOutputStream#close()
+ */
+ public void test_close() throws Exception {
+ File f1 = File.createTempFile("close", ".tst");
+
+ InflaterInputStream iis = new InflaterInputStream(new FileInputStream(f1));
+ try {
+ iis.read();
+ fail("EOFException Not Thrown");
+ } catch (EOFException e) {
+ }
+
+ FileOutputStream fos = new FileOutputStream(f1);
+ DeflaterOutputStream dos = new DeflaterOutputStream(fos);
+ byte byteArray[] = { 1, 3, 4, 6 };
+ dos.write(byteArray);
+ dos.close();
+
+ iis = new InflaterInputStream(new FileInputStream(f1));
+
+ // Test to see if the finish method wrote the bytes to the file.
+ assertEquals("Incorrect Byte Returned.", 1, iis.read());
+ assertEquals("Incorrect Byte Returned.", 3, iis.read());
+ assertEquals("Incorrect Byte Returned.", 4, iis.read());
+ assertEquals("Incorrect Byte Returned.", 6, iis.read());
+ assertEquals("Incorrect Byte Returned.", -1, iis.read());
+ assertEquals("Incorrect Byte Returned.", -1, iis.read());
+ iis.close();
+
+ // Not sure if this test will stay.
+ FileOutputStream fos2 = new FileOutputStream(f1);
+ DeflaterOutputStream dos2 = new DeflaterOutputStream(fos2);
+ fos2.close();
+ try {
+ dos2.close();
+ fail("IOException not thrown");
+ } catch (IOException e) {
+ }
+
+ // Test to write to a closed DeflaterOutputStream
+ try {
+ dos.write(5);
+ fail("DeflaterOutputStream Able To Write After Being Closed.");
+ } catch (IOException e) {
+ }
+
+ // Test to write to a FileOutputStream that should have been closed
+ // by
+ // the DeflaterOutputStream.
+ try {
+ fos.write(("testing").getBytes());
+ fail("FileOutputStream Able To Write After Being Closed.");
+ } catch (IOException e) {
+ }
+
+ f1.delete();
+ }
+
+ /**
+ * java.util.zip.DeflaterOutputStream#finish()
+ */
+ public void test_finish() throws Exception {
+ // Need test to see if method finish() actually finishes
+ // Only testing possible errors, not if it actually works
+
+ File f1 = File.createTempFile("finish", ".tst");
+ FileOutputStream fos1 = new FileOutputStream(f1);
+ DeflaterOutputStream dos = new DeflaterOutputStream(fos1);
+ byte byteArray[] = { 1, 3, 4, 6 };
+ dos.write(byteArray);
+ dos.finish();
+
+ // Test to see if the same FileOutputStream can be used with the
+ // DeflaterOutputStream after finish is called.
+ try {
+ dos.write(1);
+ fail("IOException not thrown");
+ } catch (IOException e) {
+ }
+
+ // Test for writing with a new FileOutputStream using the same
+ // DeflaterOutputStream.
+ FileOutputStream fos2 = new FileOutputStream(f1);
+ dos = new DeflaterOutputStream(fos2);
+ dos.write(1);
+
+ // Test for writing to FileOutputStream fos1, which should be open.
+ fos1.write(("testing").getBytes());
+
+ // Test for writing to FileOutputStream fos2, which should be open.
+ fos2.write(("testing").getBytes());
+
+ // Not sure if this test will stay.
+ FileOutputStream fos3 = new FileOutputStream(f1);
+ DeflaterOutputStream dos3 = new DeflaterOutputStream(fos3);
+ fos3.close();
+ try {
+ dos3.finish();
+ fail("IOException not thrown");
+ } catch (IOException e) {
+ }
+
+ // dos.close() won't close fos1 because it has been re-assigned to
+ // fos2
+ fos1.close();
+ dos.close();
+ f1.delete();
+ }
+
+ /**
+ * java.util.zip.DeflaterOutputStream#write(int)
+ */
+ public void test_writeI() throws Exception {
+ File f1 = File.createTempFile("writeIL", ".tst");
+ FileOutputStream fos = new FileOutputStream(f1);
+ DeflaterOutputStream dos = new DeflaterOutputStream(fos);
+ for (int i = 0; i < 3; i++) {
+ dos.write(i);
+ }
+ dos.close();
+ FileInputStream fis = new FileInputStream(f1);
+ InflaterInputStream iis = new InflaterInputStream(fis);
+ for (int i = 0; i < 3; i++) {
+ assertEquals("Incorrect Byte Returned.", i, iis.read());
+ }
+ assertEquals("Incorrect Byte Returned (EOF).", -1, iis.read());
+ assertEquals("Incorrect Byte Returned (EOF).", -1, iis.read());
+ iis.close();
+
+ // Not sure if this test is that important.
+ // Checks to see if you can write using the DeflaterOutputStream
+ // after
+ // the FileOutputStream has been closed.
+ FileOutputStream fos2 = new FileOutputStream(f1);
+ DeflaterOutputStream dos2 = new DeflaterOutputStream(fos2);
+ fos2.close();
+ try {
+ dos2.write(2);
+ fail("IOException not thrown");
+ } catch (IOException e) {
+ }
+
+ f1.delete();
+ }
+
+ /**
+ * java.util.zip.DeflaterOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() throws Exception {
+ byte byteArray[] = { 1, 3, 4, 7, 8, 3, 6 };
+
+ // Test to see if the correct bytes are saved.
+ File f1 = File.createTempFile("writeBII", ".tst");
+ FileOutputStream fos1 = new FileOutputStream(f1);
+ DeflaterOutputStream dos1 = new DeflaterOutputStream(fos1);
+ dos1.write(byteArray, 2, 3);
+ dos1.close();
+ FileInputStream fis = new FileInputStream(f1);
+ InflaterInputStream iis = new InflaterInputStream(fis);
+ assertEquals("Incorrect Byte Returned.", 4, iis.read());
+ assertEquals("Incorrect Byte Returned.", 7, iis.read());
+ assertEquals("Incorrect Byte Returned.", 8, iis.read());
+ assertEquals("Incorrect Byte Returned (EOF).", -1, iis.read());
+ assertEquals("Incorrect Byte Returned (EOF).", -1, iis.read());
+ iis.close();
+ f1.delete();
+
+ // Test for trying to write more bytes than available from the array
+ File f2 = File.createTempFile("writeBII2", ".tst");
+ FileOutputStream fos2 = new FileOutputStream(f2);
+ DeflaterOutputStream dos2 = new DeflaterOutputStream(fos2);
+ try {
+ dos2.write(byteArray, 2, 10);
+ fail("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ // Test for trying to write a negative number of bytes.
+ try {
+ dos2.write(byteArray, 2, Integer.MIN_VALUE);
+ fail("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ // Test for trying to start writing from a byte < 0 from the array.
+ try {
+ dos2.write(byteArray, Integer.MIN_VALUE, 2);
+ fail("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ // Test for trying to start writing from a byte > than the array
+ // size.
+ try {
+ dos2.write(byteArray, 10, 2);
+ fail("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ dos2.close();
+
+ // Not sure if this test is that important.
+ // Checks to see if you can write using the DeflaterOutputStream
+ // after
+ // the FileOutputStream has been closed.
+ FileOutputStream fos3 = new FileOutputStream(f2);
+ DeflaterOutputStream dos3 = new DeflaterOutputStream(fos3);
+ fos3.close();
+ try {
+ dos3.write(byteArray, 2, 3);
+ fail("IOException not thrown");
+ } catch (IOException e) {
+ }
+
+ f2.delete();
+ }
+
+ public void test_deflate() throws Exception {
+ File f1 = File.createTempFile("writeI1", ".tst");
+ FileOutputStream fos = new FileOutputStream(f1);
+ MyDeflaterOutputStream dos = new MyDeflaterOutputStream(fos);
+ assertFalse(dos.getDaflateFlag());
+ for (int i = 0; i < 3; i++) {
+ dos.write(i);
+ }
+ assertTrue(dos.getDaflateFlag());
+ dos.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterTest.java
new file mode 100644
index 0000000..75e4a64
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/DeflaterTest.java
@@ -0,0 +1,1129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.zip.Adler32;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
+public class DeflaterTest extends TestCase {
+
+ class MyDeflater extends Deflater {
+ MyDeflater() {
+ super();
+ }
+
+ MyDeflater(int lvl) {
+ super(lvl);
+ }
+
+ void myFinalize() {
+ finalize();
+ }
+
+ int getDefCompression() {
+ return DEFAULT_COMPRESSION;
+ }
+
+ int getDefStrategy() {
+ return DEFAULT_STRATEGY;
+ }
+
+ int getHuffman() {
+ return HUFFMAN_ONLY;
+ }
+
+ int getFiltered() {
+ return FILTERED;
+ }
+ }
+
+ /**
+ * java.util.zip.Deflater#deflate(byte[])
+ */
+ public void test_deflate$B() {
+ byte outPutBuf[] = new byte[50];
+ byte byteArray[] = { 1, 3, 4, 7, 8 };
+ byte outPutInf[] = new byte[50];
+ int x = 0;
+
+ Deflater defl = new Deflater();
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ x += defl.deflate(outPutBuf);
+ }
+ assertEquals("Deflater at end of stream, should return 0", 0, defl
+ .deflate(outPutBuf));
+ int totalOut = defl.getTotalOut();
+ int totalIn = defl.getTotalIn();
+ assertEquals(x, totalOut);
+ assertEquals(byteArray.length, totalIn);
+ defl.end();
+
+ Inflater infl = new Inflater();
+ try {
+ infl.setInput(outPutBuf);
+ while (!infl.finished()) {
+ infl.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ assertEquals(totalIn, infl.getTotalOut());
+ assertEquals(totalOut, infl.getTotalIn());
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(byteArray[i], outPutInf[i]);
+ }
+ assertEquals("Final decompressed data contained more bytes than original",
+ 0, outPutInf[byteArray.length]);
+ infl.end();
+ }
+
+ /**
+ * java.util.zip.Deflater#deflate(byte[], int, int)
+ */
+ public void test_deflate$BII() {
+ byte outPutBuf[] = new byte[50];
+ byte byteArray[] = { 5, 2, 3, 7, 8 };
+ byte outPutInf[] = new byte[50];
+ int offSet = 1;
+ int length = outPutBuf.length - 1;
+ int x = 0;
+
+ Deflater defl = new Deflater();
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ x += defl.deflate(outPutBuf, offSet, length);
+ }
+ assertEquals("Deflater at end of stream, should return 0", 0, defl.deflate(
+ outPutBuf, offSet, length));
+ int totalOut = defl.getTotalOut();
+ int totalIn = defl.getTotalIn();
+ assertEquals(x, totalOut);
+ assertEquals(byteArray.length, totalIn);
+ defl.end();
+
+ Inflater infl = new Inflater();
+ try {
+ infl.setInput(outPutBuf, offSet, length);
+ while (!infl.finished()) {
+ infl.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ assertEquals(totalIn, infl.getTotalOut());
+ assertEquals(totalOut, infl.getTotalIn());
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(byteArray[i], outPutInf[i]);
+ }
+ assertEquals("Final decompressed data contained more bytes than original",
+ 0, outPutInf[byteArray.length]);
+ infl.end();
+
+ // Set of tests testing the boundaries of the offSet/length
+ defl = new Deflater();
+ outPutBuf = new byte[100];
+ defl.setInput(byteArray);
+ for (int i = 0; i < 2; i++) {
+ if (i == 0) {
+ offSet = outPutBuf.length + 1;
+ length = outPutBuf.length;
+ } else {
+ offSet = 0;
+ length = outPutBuf.length + 1;
+ }
+ try {
+ defl.deflate(outPutBuf, offSet, length);
+ fail("Test " + i
+ + ": ArrayIndexOutOfBoundsException not thrown");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ }
+ defl.end();
+ }
+
+ /**
+ * java.util.zip.Deflater#end()
+ */
+ public void test_end() {
+ byte byteArray[] = { 5, 2, 3, 7, 8 };
+ byte outPutBuf[] = new byte[100];
+
+ Deflater defl = new Deflater();
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.end();
+ helper_end_test(defl, "end");
+ }
+
+ /**
+ * java.util.zip.Deflater#finalize()
+ */
+ public void test_finalize() {
+ MyDeflater mdefl = new MyDeflater();
+ mdefl.myFinalize();
+ System.gc();
+ helper_end_test(mdefl, "finalize");
+ }
+
+ /**
+ * java.util.zip.Deflater#finish()
+ */
+ public void test_finish() throws Exception {
+ // This test already here, its the same as test_deflate()
+ byte byteArray[] = { 5, 2, 3, 7, 8 };
+ byte outPutBuf[] = new byte[100];
+ byte outPutInf[] = new byte[100];
+ int x = 0;
+ Deflater defl = new Deflater();
+ defl.setInput(byteArray);
+ defl.finish();
+
+ // needsInput should never return true after finish() is called
+ if (System.getProperty("java.vendor").startsWith("IBM")) {
+ assertFalse("needsInput() should return false after finish() is called", defl
+ .needsInput());
+ }
+
+ while (!defl.finished()) {
+ x += defl.deflate(outPutBuf);
+ }
+ int totalOut = defl.getTotalOut();
+ int totalIn = defl.getTotalIn();
+ assertEquals(x, totalOut);
+ assertEquals(byteArray.length, totalIn);
+ defl.end();
+
+ Inflater infl = new Inflater();
+ infl.setInput(outPutBuf);
+ while (!infl.finished()) {
+ infl.inflate(outPutInf);
+ }
+ assertEquals(totalIn, infl.getTotalOut());
+ assertEquals(totalOut, infl.getTotalIn());
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(byteArray[i], outPutInf[i]);
+ }
+ assertEquals("Final decompressed data contained more bytes than original",
+ 0, outPutInf[byteArray.length]);
+ infl.end();
+ }
+
+ /**
+ * java.util.zip.Deflater#finished()
+ */
+ public void test_finished() {
+ byte byteArray[] = { 5, 2, 3, 7, 8 };
+ byte outPutBuf[] = new byte[100];
+ Deflater defl = new Deflater();
+ assertTrue("Test 1: Deflater should not be finished.", !defl.finished());
+ defl.setInput(byteArray);
+ assertTrue("Test 2: Deflater should not be finished.", !defl.finished());
+ defl.finish();
+ assertTrue("Test 3: Deflater should not be finished.", !defl.finished());
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ assertTrue("Test 4: Deflater should be finished.", defl.finished());
+ defl.end();
+ assertTrue("Test 5: Deflater should be finished.", defl.finished());
+ }
+
+ /**
+ * java.util.zip.Deflater#getAdler()
+ */
+ public void test_getAdler() {
+ byte byteArray[] = { 'a', 'b', 'c', 1, 2, 3 };
+ byte outPutBuf[] = new byte[100];
+ Deflater defl = new Deflater();
+
+ // getting the checkSum value using the Adler
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ long checkSumD = defl.getAdler();
+ defl.end();
+
+ // getting the checkSum value through the Adler32 class
+ Adler32 adl = new Adler32();
+ adl.update(byteArray);
+ long checkSumR = adl.getValue();
+ assertEquals(
+ "The checksum value returned by getAdler() is not the same as the checksum returned by creating the adler32 instance",
+ checkSumD, checkSumR);
+ }
+
+ /**
+ * java.util.zip.Deflater#getTotalIn()
+ */
+ public void test_getTotalIn() {
+ byte outPutBuf[] = new byte[5];
+ byte byteArray[] = { 1, 3, 4, 7, 8 };
+
+ Deflater defl = new Deflater();
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ assertEquals(byteArray.length, defl.getTotalIn());
+ defl.end();
+
+ defl = new Deflater();
+ int offSet = 2;
+ int length = 3;
+ outPutBuf = new byte[5];
+ defl.setInput(byteArray, offSet, length);
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ assertEquals(length, defl.getTotalIn());
+ defl.end();
+ }
+
+ /**
+ * java.util.zip.Deflater#getTotalOut()
+ */
+ public void test_getTotalOut() {
+ // the getTotalOut should equal the sum of value returned by deflate()
+ byte outPutBuf[] = new byte[5];
+ byte byteArray[] = { 5, 2, 3, 7, 8 };
+ int x = 0;
+ Deflater defl = new Deflater();
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ x += defl.deflate(outPutBuf);
+ }
+ assertEquals(x, defl.getTotalOut());
+ defl.end();
+
+ x = 0;
+ int offSet = 2;
+ int length = 3;
+ defl = new Deflater();
+ outPutBuf = new byte[5];
+ defl.setInput(byteArray, offSet, length);
+ defl.finish();
+ while (!defl.finished()) {
+ x += defl.deflate(outPutBuf);
+ }
+ assertEquals(x, defl.getTotalOut());
+ }
+
+ /**
+ * java.util.zip.Deflater#needsInput()
+ */
+ public void test_needsInput() {
+ Deflater defl = new Deflater();
+ assertTrue(
+ "needsInput give the wrong boolean value as a result of no input buffer",
+ defl.needsInput());
+ byte byteArray[] = { 1, 2, 3 };
+ defl.setInput(byteArray);
+ assertFalse(
+ "needsInput give wrong boolean value as a result of a full input buffer",
+ defl.needsInput());
+ byte[] outPutBuf = new byte[50];
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ byte emptyByteArray[] = new byte[0];
+ defl.setInput(emptyByteArray);
+ assertTrue(
+ "needsInput give wrong boolean value as a result of an empty input buffer",
+ defl.needsInput());
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ // needsInput should NOT return true after finish() has been
+ // called.
+ if (System.getProperty("java.vendor").startsWith("IBM")) {
+ assertFalse(
+ "needsInput gave wrong boolean value as a result of finish() being called",
+ defl.needsInput());
+ }
+ defl.end();
+ }
+
+ /**
+ * java.util.zip.Deflater#reset()
+ */
+ public void test_reset() {
+ byte outPutBuf[] = new byte[100];
+ byte outPutInf[] = new byte[100];
+ byte curArray[] = new byte[5];
+ byte byteArray[] = { 1, 3, 4, 7, 8 };
+ byte byteArray2[] = { 8, 7, 4, 3, 1 };
+ int x = 0;
+ int orgValue = 0;
+ Deflater defl = new Deflater();
+
+ for (int i = 0; i < 3; i++) {
+ if (i == 0) {
+ curArray = byteArray;
+ } else if (i == 1) {
+ curArray = byteArray2;
+ } else {
+ defl.reset();
+ }
+
+ defl.setInput(curArray);
+ defl.finish();
+ while (!defl.finished()) {
+ x += defl.deflate(outPutBuf);
+ }
+
+ if (i == 0) {
+ assertEquals(x, defl.getTotalOut());
+ } else if (i == 1) {
+ assertEquals(x, orgValue);
+ } else {
+ assertEquals(x, orgValue * 2);
+ }
+
+ if (i == 0) {
+ orgValue = x;
+ }
+
+ try {
+ Inflater infl = new Inflater();
+ infl.setInput(outPutBuf);
+ while (!infl.finished()) {
+ infl.inflate(outPutInf);
+ }
+ infl.end();
+ } catch (DataFormatException e) {
+ fail("Test " + i + ": Invalid input to be decompressed");
+ }
+
+ if (i == 1) {
+ curArray = byteArray;
+ }
+
+ for (int j = 0; j < curArray.length; j++) {
+ assertEquals(curArray[j], outPutInf[j]);
+ }
+ assertEquals(0, outPutInf[curArray.length]);
+ }
+ }
+
+ /**
+ * java.util.zip.Deflater#setDictionary(byte[])
+ */
+ public void test_setDictionary$B() {
+ // This test is very close to getAdler()
+ byte dictionaryArray[] = { 'e', 'r', 't', 'a', 'b', 2, 3 };
+ byte byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3',
+ 'w', 'r' };
+ byte outPutBuf[] = new byte[100];
+
+ Deflater defl = new Deflater();
+ long deflAdler = defl.getAdler();
+ assertEquals("No dictionary set, no data deflated, getAdler should return 1",
+ 1, deflAdler);
+ defl.setDictionary(dictionaryArray);
+ deflAdler = defl.getAdler();
+
+ // getting the checkSum value through the Adler32 class
+ Adler32 adl = new Adler32();
+ adl.update(dictionaryArray);
+ long realAdler = adl.getValue();
+ assertEquals(deflAdler, realAdler);
+
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ deflAdler = defl.getAdler();
+ adl = new Adler32();
+ adl.update(byteArray);
+ realAdler = adl.getValue();
+ // Deflate is finished and there were bytes deflated that did not occur
+ // in the dictionaryArray, therefore a new dictionary was automatically
+ // set.
+ assertEquals(realAdler, deflAdler);
+ defl.end();
+ }
+
+ /**
+ * java.util.zip.Deflater#setDictionary(byte[], int, int)
+ */
+ public void test_setDictionary$BII() {
+ // This test is very close to getAdler()
+ byte dictionaryArray[] = { 'e', 'r', 't', 'a', 'b', 2, 3, 'o', 't' };
+ byte byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3',
+ 'w', 'r', 't', 'u', 'i', 'o', 4, 5, 6, 7 };
+ byte outPutBuf[] = new byte[500];
+
+ int offSet = 4;
+ int length = 5;
+
+ Deflater defl = new Deflater();
+ long deflAdler = defl.getAdler();
+ assertEquals("No dictionary set, no data deflated, getAdler should return 1",
+ 1, deflAdler);
+ defl.setDictionary(dictionaryArray, offSet, length);
+ deflAdler = defl.getAdler();
+
+ // getting the checkSum value through the Adler32 class
+ Adler32 adl = new Adler32();
+ adl.update(dictionaryArray, offSet, length);
+ long realAdler = adl.getValue();
+ assertEquals(deflAdler, realAdler);
+
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ deflAdler = defl.getAdler();
+ adl = new Adler32();
+ adl.update(byteArray);
+ realAdler = adl.getValue();
+ // Deflate is finished and there were bytes deflated that did not occur
+ // in the dictionaryArray, therefore a new dictionary was automatically
+ // set.
+ assertEquals(realAdler, deflAdler);
+ defl.end();
+
+ // boundary check
+ defl = new Deflater();
+ for (int i = 0; i < 2; i++) {
+ if (i == 0) {
+ offSet = 0;
+ length = dictionaryArray.length + 1;
+ } else {
+ offSet = dictionaryArray.length + 1;
+ length = 1;
+ }
+ try {
+ defl.setDictionary(dictionaryArray, offSet, length);
+ fail(
+ "Test "
+ + i
+ + ": boundary check for setDictionary failed for offset "
+ + offSet + " and length " + length);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ }
+ }
+
+ /**
+ * java.util.zip.Deflater#setInput(byte[])
+ */
+ public void test_setInput$B() {
+ byte[] byteArray = { 1, 2, 3 };
+ byte[] outPutBuf = new byte[50];
+ byte[] outPutInf = new byte[50];
+
+ Deflater defl = new Deflater();
+ defl.setInput(byteArray);
+ assertTrue("the array buffer in setInput() is empty", !defl
+ .needsInput());
+ // The second setInput() should be ignored since needsInput() return
+ // false
+ defl.setInput(byteArray);
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.end();
+
+ Inflater infl = new Inflater();
+ try {
+ infl.setInput(outPutBuf);
+ while (!infl.finished()) {
+ infl.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(byteArray[i], outPutInf[i]);
+ }
+ assertEquals(byteArray.length, infl.getTotalOut());
+ infl.end();
+ }
+
+ /**
+ * java.util.zip.Deflater#setInput(byte[], int, int)
+ */
+ public void test_setInput$BII() throws Exception {
+ byte[] byteArray = { 1, 2, 3, 4, 5 };
+ byte[] outPutBuf = new byte[50];
+ byte[] outPutInf = new byte[50];
+ int offSet = 1;
+ int length = 3;
+
+ Deflater defl = new Deflater();
+ defl.setInput(byteArray, offSet, length);
+ assertFalse("the array buffer in setInput() is empty", defl.needsInput());
+ // The second setInput() should be ignored since needsInput() return
+ // false
+ defl.setInput(byteArray, offSet, length);
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.end();
+
+ Inflater infl = new Inflater();
+ infl.setInput(outPutBuf);
+ while (!infl.finished()) {
+ infl.inflate(outPutInf);
+ }
+ for (int i = 0; i < length; i++) {
+ assertEquals(byteArray[i + offSet], outPutInf[i]);
+ }
+ assertEquals(length, infl.getTotalOut());
+ infl.end();
+
+ // boundary check
+ defl = new Deflater();
+ for (int i = 0; i < 2; i++) {
+ if (i == 0) {
+ offSet = 0;
+ length = byteArray.length + 1;
+ } else {
+ offSet = byteArray.length + 1;
+ length = 1;
+ }
+ try {
+ defl.setInput(byteArray, offSet, length);
+ fail("Test " + i
+ + ": boundary check for setInput failed for offset "
+ + offSet + " and length " + length);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ }
+ }
+
+ /**
+ * java.util.zip.Deflater#setLevel(int)
+ */
+ public void test_setLevelI() throws Exception {
+ // Very similar to test_Constructor(int)
+ byte[] byteArray = new byte[100];
+ InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
+ inFile.read(byteArray);
+ inFile.close();
+
+ byte[] outPutBuf;
+ int totalOut;
+ for (int i = 0; i < 10; i++) {
+ Deflater defl = new Deflater();
+ defl.setLevel(i);
+ outPutBuf = new byte[500];
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ totalOut = defl.getTotalOut();
+ defl.end();
+
+ outPutBuf = new byte[500];
+ defl = new Deflater(i);
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ assertEquals(totalOut, defl.getTotalOut());
+ defl.end();
+ }
+
+ // testing boundaries
+ try {
+ Deflater boundDefl = new Deflater();
+ // Level must be between 0-9
+ boundDefl.setLevel(-2);
+ fail(
+ "IllegalArgumentException not thrown when setting level to a number < 0.");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ Deflater boundDefl = new Deflater();
+ boundDefl.setLevel(10);
+ fail(
+ "IllegalArgumentException not thrown when setting level to a number > 9.");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * java.util.zip.Deflater#setStrategy(int)
+ */
+ public void test_setStrategyI() throws Exception {
+ byte[] byteArray = new byte[100];
+ InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
+ inFile.read(byteArray);
+ inFile.close();
+
+ for (int i = 0; i < 3; i++) {
+ byte outPutBuf[] = new byte[500];
+ MyDeflater mdefl = new MyDeflater();
+
+ if (i == 0) {
+ mdefl.setStrategy(mdefl.getDefStrategy());
+ } else if (i == 1) {
+ mdefl.setStrategy(mdefl.getHuffman());
+ } else {
+ mdefl.setStrategy(mdefl.getFiltered());
+ }
+
+ mdefl.setInput(byteArray);
+ while (!mdefl.needsInput()) {
+ mdefl.deflate(outPutBuf);
+ }
+ mdefl.finish();
+ while (!mdefl.finished()) {
+ mdefl.deflate(outPutBuf);
+ }
+
+ if (i == 0) {
+ // System.out.println(mdefl.getTotalOut());
+ // ran JDK and found that getTotalOut() = 86 for this particular
+ // file
+ assertEquals("getTotalOut() for the default strategy did not correspond with JDK",
+ 86, mdefl.getTotalOut());
+ } else if (i == 1) {
+ // System.out.println(mdefl.getTotalOut());
+ // ran JDK and found that getTotalOut() = 100 for this
+ // particular file
+ assertEquals("getTotalOut() for the Huffman strategy did not correspond with JDK",
+ 100, mdefl.getTotalOut());
+ } else {
+ // System.out.println(mdefl.getTotalOut());
+ // ran JDK and found that totalOut = 93 for this particular file
+ assertEquals("Total Out for the Filtered strategy did not correspond with JDK",
+ 93, mdefl.getTotalOut());
+ }
+ mdefl.end();
+ }
+
+ // Attempting to setStrategy to an invalid value
+ try {
+ Deflater defl = new Deflater();
+ defl.setStrategy(-412);
+ fail(
+ "IllegalArgumentException not thrown when setting strategy to an invalid value.");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * java.util.zip.Deflater#Deflater()
+ */
+ public void test_Constructor() throws Exception {
+ byte[] byteArray = new byte[100];
+ InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
+ inFile.read(byteArray);
+ inFile.close();
+
+ Deflater defl = new Deflater();
+ byte[] outPutBuf = new byte[500];
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ int totalOut = defl.getTotalOut();
+ defl.end();
+
+ // creating a Deflater using the DEFAULT_COMPRESSION as the int
+ MyDeflater mdefl = new MyDeflater();
+ mdefl = new MyDeflater(mdefl.getDefCompression());
+ outPutBuf = new byte[500];
+ mdefl.setInput(byteArray);
+ while (!mdefl.needsInput()) {
+ mdefl.deflate(outPutBuf);
+ }
+ mdefl.finish();
+ while (!mdefl.finished()) {
+ mdefl.deflate(outPutBuf);
+ }
+ assertEquals(totalOut, mdefl.getTotalOut());
+ mdefl.end();
+ }
+
+ /**
+ * java.util.zip.Deflater#Deflater(int, boolean)
+ */
+ public void test_ConstructorIZ() throws Exception {
+ byte byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3',
+ 'w', 'r' };
+
+ Deflater defl = new Deflater();
+ byte outPutBuf[] = new byte[500];
+ defl.setLevel(2);
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ int totalOut = defl.getTotalOut();
+ defl.end();
+
+ outPutBuf = new byte[500];
+ defl = new Deflater(2, false);
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ assertEquals(totalOut, defl.getTotalOut());
+ defl.end();
+
+ outPutBuf = new byte[500];
+ defl = new Deflater(2, true);
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ assertTrue(
+ "getTotalOut() should not be equal comparing two Deflaters with different header options.",
+ defl.getTotalOut() != totalOut);
+ defl.end();
+
+ byte outPutInf[] = new byte[500];
+ Inflater infl = new Inflater(true);
+ while (!infl.finished()) {
+ if (infl.needsInput()) {
+ infl.setInput(outPutBuf);
+ }
+ infl.inflate(outPutInf);
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(byteArray[i], outPutInf[i]);
+ }
+ assertEquals("final decompressed data contained more bytes than original - constructorIZ",
+ 0, outPutInf[byteArray.length]);
+ infl.end();
+
+ infl = new Inflater(false);
+ outPutInf = new byte[500];
+ int r = 0;
+ try {
+ while (!infl.finished()) {
+ if (infl.needsInput()) {
+ infl.setInput(outPutBuf);
+ }
+ infl.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ r = 1;
+ }
+ assertEquals("header option did not correspond", 1, r);
+
+ // testing boundaries
+ try {
+ Deflater boundDefl = new Deflater();
+ // Level must be between 0-9
+ boundDefl.setLevel(-2);
+ fail("IllegalArgumentException not thrown when setting level to a number < 0.");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ Deflater boundDefl = new Deflater();
+ boundDefl.setLevel(10);
+ fail("IllegalArgumentException not thrown when setting level to a number > 9.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ Deflater boundDefl = new Deflater(-2, true);
+ fail("IllegalArgumentException not thrown when passing level to a number < 0.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ Deflater boundDefl = new Deflater(10, true);
+ fail("IllegalArgumentException not thrown when passing level to a number > 9.");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * java.util.zip.Deflater#Deflater(int)
+ */
+ public void test_ConstructorI() throws Exception {
+ byte[] byteArray = new byte[100];
+ InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
+ inFile.read(byteArray);
+ inFile.close();
+
+ byte outPutBuf[] = new byte[500];
+ Deflater defl = new Deflater(3);
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ int totalOut = defl.getTotalOut();
+ defl.end();
+
+ // test to see if the compression ratio is the same as setting the level
+ // on a deflater
+ outPutBuf = new byte[500];
+ defl = new Deflater();
+ defl.setLevel(3);
+ defl.setInput(byteArray);
+ while (!defl.needsInput()) {
+ defl.deflate(outPutBuf);
+ }
+ defl.finish();
+ while (!defl.finished()) {
+ defl.deflate(outPutBuf);
+ }
+ assertEquals(totalOut, defl.getTotalOut());
+ defl.end();
+
+ // testing boundaries
+ try {
+ Deflater boundDefl = new Deflater();
+ // Level must be between 0-9
+ boundDefl.setLevel(-2);
+ fail("IllegalArgumentException not thrown when setting level to a number < 0.");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ Deflater boundDefl = new Deflater();
+ boundDefl.setLevel(10);
+ fail("IllegalArgumentException not thrown when setting level to a number > 9.");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ private void helper_end_test(Deflater defl, String desc) {
+ // Help tests for test_end() and test_reset().
+ byte byteArray[] = { 5, 2, 3, 7, 8 };
+
+ // Methods where we expect IllegalStateException or NullPointerException
+ // to be thrown
+ try {
+ defl.getTotalOut();
+ fail("defl.getTotalOut() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (IllegalStateException e) {
+ } catch (NullPointerException e) {
+ }
+ try {
+ defl.getTotalIn();
+ fail("defl.getTotalIn() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (IllegalStateException e) {
+ } catch (NullPointerException e) {
+ }
+ try {
+ defl.getAdler();
+ fail("defl.getAdler() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (IllegalStateException e) {
+ } catch (NullPointerException e) {
+ }
+ try {
+ byte[] dict = { 'a', 'b', 'c' };
+ defl.setDictionary(dict);
+ fail("defl.setDictionary() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (IllegalStateException e) {
+ } catch (NullPointerException e) {
+ }
+ try {
+ defl.getTotalIn();
+ fail("defl.getTotalIn() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (IllegalStateException e) {
+ } catch (NullPointerException e) {
+ }
+ try {
+ defl.getTotalIn();
+ fail("defl.getTotalIn() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (IllegalStateException e) {
+ } catch (NullPointerException e) {
+ }
+ try {
+ defl.deflate(byteArray);
+ fail("defl.deflate() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (IllegalStateException e) {
+ } catch (NullPointerException e) {
+ }
+
+ // Methods where we expect NullPointerException to be thrown
+ try {
+ defl.reset();
+ fail("defl.reset() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (NullPointerException expected) {
+ } catch (IllegalStateException expected) {
+ }
+
+ // Methods where we expect NullPointerException to be thrown
+ try {
+ defl.getBytesRead();
+ fail("defl.reset() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (NullPointerException expected) {
+ } catch (IllegalStateException expected) {
+ }
+
+ // Methods where we expect NullPointerException to be thrown
+ try {
+ defl.getBytesWritten();
+ fail("defl.getBytesWritten() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (NullPointerException expected) {
+ } catch (IllegalStateException expected) {
+ }
+
+ // Methods that should be allowed to be called after end() is called
+ defl.needsInput();
+ defl.setStrategy(1);
+ defl.setLevel(1);
+ defl.end();
+
+ // Methods where exceptions should be thrown
+ String vendor = System.getProperty("java.vendor");
+ if (vendor.indexOf("IBM") != -1) {
+ try {
+ defl.setInput(byteArray);
+ fail("defl.setInput() can still be used after " + desc
+ + " is called in test_" + desc);
+ } catch (IllegalStateException e) {
+ }
+ }
+ }
+
+ /**
+ * java.util.zip.Deflater()
+ */
+ public void test_needsDictionary() {
+ Deflater inf = new Deflater();
+ assertEquals(0, inf.getTotalIn());
+ assertEquals(0, inf.getTotalOut());
+ assertEquals(0, inf.getBytesRead());
+ assertEquals(0, inf.getBytesWritten());
+ }
+
+ /**
+ * @throws DataFormatException
+ * @throws UnsupportedEncodingException
+ * java.util.zip.Deflater#getBytesRead()
+ */
+ public void test_getBytesRead() throws DataFormatException,
+ UnsupportedEncodingException {
+ // Regression test for HARMONY-158
+ Deflater def = new Deflater();
+ assertEquals(0, def.getTotalIn());
+ assertEquals(0, def.getTotalOut());
+ assertEquals(0, def.getBytesRead());
+ // Encode a String into bytes
+ String inputString = "blahblahblah??";
+ byte[] input = inputString.getBytes("UTF-8");
+
+ // Compress the bytes
+ byte[] output = new byte[100];
+ def.setInput(input);
+ def.finish();
+ int compressedDataLength = def.deflate(output);
+ assertEquals(14, def.getTotalIn());
+ assertEquals(compressedDataLength, def.getTotalOut());
+ assertEquals(14, def.getBytesRead());
+ }
+
+ /**
+ * @throws DataFormatException
+ * @throws UnsupportedEncodingException
+ * java.util.zip.Deflater#getBytesRead()
+ */
+ public void test_getBytesWritten() throws DataFormatException,
+ UnsupportedEncodingException {
+ // Regression test for HARMONY-158
+ Deflater def = new Deflater();
+ assertEquals(0, def.getTotalIn());
+ assertEquals(0, def.getTotalOut());
+ assertEquals(0, def.getBytesWritten());
+ // Encode a String into bytes
+ String inputString = "blahblahblah??";
+ byte[] input = inputString.getBytes("UTF-8");
+
+ // Compress the bytes
+ byte[] output = new byte[100];
+ def.setInput(input);
+ def.finish();
+ int compressedDataLength = def.deflate(output);
+ assertEquals(14, def.getTotalIn());
+ assertEquals(compressedDataLength, def.getTotalOut());
+ assertEquals(compressedDataLength, def.getBytesWritten());
+ }
+
+ //Regression Test for HARMONY-2481
+ public void test_deflate_beforeSetInput() throws Exception {
+ Deflater deflater = new Deflater();
+ deflater.finish();
+ byte[] buffer = new byte[1024];
+ assertEquals(8, deflater.deflate(buffer));
+ byte[] expectedBytes = { 120, -100, 3, 0, 0, 0, 0, 1 };
+ for (int i = 0; i < expectedBytes.length; i++) {
+ assertEquals(expectedBytes[i], buffer[i]);
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/GZIPInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/GZIPInputStreamTest.java
new file mode 100644
index 0000000..567189d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/GZIPInputStreamTest.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.zip.Checksum;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import tests.support.resource.Support_Resources;
+
+public class GZIPInputStreamTest extends junit.framework.TestCase {
+ File resources;
+
+ class TestGZIPInputStream extends GZIPInputStream {
+ TestGZIPInputStream(InputStream in) throws IOException {
+ super(in);
+ }
+
+ TestGZIPInputStream(InputStream in, int size) throws IOException {
+ super(in, size);
+ }
+
+ Checksum getChecksum() {
+ return crc;
+ }
+
+ boolean endofInput() {
+ return eos;
+ }
+ }
+
+ /**
+ * @tests java.util.zip.GZIPInputStream#GZIPInputStream(java.io.InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() {
+ // test method java.util.zip.GZIPInputStream.constructor
+ try {
+ Support_Resources.copyFile(resources, null, "hyts_gInput.txt.gz");
+ final URL gInput = new File(resources.toString() + "/hyts_gInput.txt.gz").toURL();
+ TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
+ .openConnection().getInputStream());
+ assertNotNull("the constructor for GZIPInputStream is null",
+ inGZIP);
+ assertEquals("the CRC value of the inputStream is not zero", 0, inGZIP
+ .getChecksum().getValue());
+ inGZIP.close();
+ } catch (IOException e) {
+ fail(
+ "an IO error occured while trying to open the input file");
+ }
+ }
+
+ /**
+ * @tests java.util.zip.GZIPInputStream#GZIPInputStream(java.io.InputStream,
+ *int)
+ */
+ public void test_ConstructorLjava_io_InputStreamI() {
+ // test method java.util.zip.GZIPInputStream.constructorI
+ try {
+ Support_Resources.copyFile(resources, null, "hyts_gInput.txt.gz");
+ final URL gInput = new File(resources.toString() + "/hyts_gInput.txt.gz").toURL();
+ TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
+ .openConnection().getInputStream(), 200);
+ assertNotNull("the constructor for GZIPInputStream is null",
+ inGZIP);
+ assertEquals("the CRC value of the inputStream is not zero", 0, inGZIP
+ .getChecksum().getValue());
+ inGZIP.close();
+
+ try {
+ TestGZIPInputStream inGZIP1 = new TestGZIPInputStream(gInput
+ .openConnection().getInputStream(), 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ioe) {
+ //expected
+ }
+
+ Support_Resources.copyFile(resources, null, "hyts_checkInput.txt");
+ final URL jarInput = new File(resources.toString() + "/hyts_checkInput.txt").toURL();
+ try {
+ TestGZIPInputStream inGZIP1 = new TestGZIPInputStream(jarInput
+ .openConnection().getInputStream(), 200);
+ fail("IOException expected");
+ } catch (IOException ex) {
+ //expected
+ }
+
+ } catch (IOException e) {
+ fail(
+ "an IO error occured while trying to open the input file");
+ }
+ }
+
+ /**
+ * @tests java.util.zip.GZIPInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException {
+ // test method java.util.zip.GZIPInputStream.readBII
+ byte orgBuf[] = { '3', '5', '2', 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
+ byte outBuf[] = new byte[100];
+ int result = 0;
+ Support_Resources.copyFile(resources, null, "hyts_gInput.txt.gz");
+ final URL gInput = new File(resources.toString() + "/hyts_gInput.txt.gz").toURL();
+ TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
+ .openConnection().getInputStream());
+ while (!(inGZIP.endofInput())) {
+ result += inGZIP.read(outBuf, result, outBuf.length - result);
+ }
+ assertEquals(
+ "the checkSum value of the compressed and decompressed data does not equal",
+ 2074883667L, inGZIP.getChecksum().getValue());
+ for (int i = 0; i < orgBuf.length; i++) {
+ assertEquals(
+ "the decompressed data does not equal the original data decompressed",
+ orgBuf[i], outBuf[i]);
+ // System.out.println(orgBuf[i] + " " + outBuf[i]);
+ }
+ int r = 0;
+ try {
+ inGZIP.read(outBuf, 100, 1);
+ } catch (IndexOutOfBoundsException e) {
+ r = 1;
+ }
+ inGZIP.close();
+ // line below fails on RI also, comment out.
+ // assertEquals("Boundary Check was not present", 1, r);
+
+ // Create compressed data which is exactly 512 bytes (after the
+ // header),
+ // the size of the InflaterStream internal buffer
+ byte[] test = new byte[507];
+ for (int i = 0; i < 256; i++) {
+ test[i] = (byte) i;
+ }
+ for (int i = 256; i < test.length; i++) {
+ test[i] = (byte) (256 - i);
+ }
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ GZIPOutputStream out = new GZIPOutputStream(bout);
+ out.write(test);
+ out.close();
+ byte[] comp = bout.toByteArray();
+ GZIPInputStream gin2 = new GZIPInputStream(new ByteArrayInputStream(
+ comp), 512);
+ int total = 0;
+ while ((result = gin2.read(test)) != -1) {
+ total += result;
+ }
+ assertEquals("Should return -1", -1, gin2.read());
+ gin2.close();
+ assertEquals("Incorrectly decompressed", test.length, total);
+
+ gin2 = new GZIPInputStream(new ByteArrayInputStream(comp), 512);
+ total = 0;
+ while ((result = gin2.read(new byte[200])) != -1) {
+ total += result;
+ }
+ assertEquals("Should return -1", -1, gin2.read());
+ gin2.close();
+ assertEquals("Incorrectly decompressed", test.length, total);
+
+ gin2 = new GZIPInputStream(new ByteArrayInputStream(comp), 516);
+ total = 0;
+ while ((result = gin2.read(new byte[200])) != -1) {
+ total += result;
+ }
+ assertEquals("Should return -1", -1, gin2.read());
+ gin2.close();
+ assertEquals("Incorrectly decompressed", test.length, total);
+
+ comp[40] = 0;
+ gin2 = new GZIPInputStream(new ByteArrayInputStream(comp), 512);
+ boolean exception = false;
+ try {
+ while (gin2.read(test) != -1) {
+ ;
+ }
+ } catch (IOException e) {
+ exception = true;
+ }
+ assertTrue("Exception expected", exception);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ GZIPOutputStream zipout = new GZIPOutputStream(baos);
+ zipout.write(test);
+ zipout.close();
+ outBuf = new byte[530];
+ GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(baos.toByteArray()));
+ try {
+ in.read(outBuf, 530, 1);
+ fail("Test failed IOOBE was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ while (true) {
+ result = in.read(outBuf, 0, 5);
+ if (result == -1) {
+ //"EOF was reached";
+ break;
+ }
+ }
+ result = -10;
+ result = in.read(null, 100, 1);
+ result = in.read(outBuf, -100, 1);
+ result = in.read(outBuf, -1, 1);// 100, 1);
+ }
+
+ /**
+ * @tests java.util.zip.GZIPInputStream#close()
+ */
+ public void test_close() {
+ // test method java.util.zip.GZIPInputStream.close
+ byte outBuf[] = new byte[100];
+ try {
+ int result = 0;
+ Support_Resources.copyFile(resources, null, "hyts_gInput.txt.gz");
+ final URL gInput = new File(resources.toString() + "/hyts_gInput.txt.gz").toURL();
+ TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
+ .openConnection().getInputStream());
+ while (!(inGZIP.endofInput())) {
+ result += inGZIP.read(outBuf, result, outBuf.length - result);
+ }
+ assertEquals("the checkSum value of the compressed and decompressed data does not equal",
+ 2074883667L, inGZIP.getChecksum().getValue());
+ inGZIP.close();
+ int r = 0;
+ try {
+ inGZIP.read(outBuf, 0, 1);
+ } catch (IOException e) {
+ r = 1;
+ }
+ assertEquals("GZIPInputStream can still be used after close is called",
+ 1, r);
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail("unexpected: " + e);
+ }
+ }
+
+ /**
+ * Regression test for HARMONY-3703.
+ *
+ * @tests java.util.zip.GZIPInputStream#read()
+ */
+ public void test_read() throws IOException {
+ GZIPInputStream gis = null;
+ int result = 0;
+ byte[] buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ File f = new File(resources.getAbsolutePath() + "test.gz");
+ FileOutputStream out = new FileOutputStream(f);
+ GZIPOutputStream gout = new GZIPOutputStream(out);
+
+ // write 100 bytes to the stream
+ for (int i = 0; i < 10; i++) {
+ gout.write(buffer);
+ }
+ gout.finish();
+ out.write(1);
+ out.close();
+
+ gis = new GZIPInputStream(new FileInputStream(f));
+ buffer = new byte[100];
+ gis.read(buffer);
+ result = gis.read();
+ gis.close();
+ f.delete();
+
+ assertEquals("Incorrect value returned at the end of the file", -1, result);
+ }
+
+ @Override
+ protected void setUp() {
+ resources = Support_Resources.createTempFolder();
+ }
+
+ @Override
+ protected void tearDown() {
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/GZIPOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/GZIPOutputStreamTest.java
new file mode 100644
index 0000000..30a94f0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/GZIPOutputStreamTest.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.zip.Checksum;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+public class GZIPOutputStreamTest extends junit.framework.TestCase {
+
+ class TestGZIPOutputStream extends GZIPOutputStream {
+ TestGZIPOutputStream(OutputStream out) throws IOException {
+ super(out);
+ }
+
+ TestGZIPOutputStream(OutputStream out, int size) throws IOException {
+ super(out, size);
+ }
+
+ Checksum getChecksum() {
+ return crc;
+ }
+ }
+
+ /**
+ * java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() {
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("GZIPCon", ".txt"));
+ TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
+ assertNotNull("the constructor for GZIPOutputStream is null",
+ outGZIP);
+ assertEquals("the CRC value of the outputStream is not zero", 0, outGZIP
+ .getChecksum().getValue());
+ outGZIP.close();
+ } catch (IOException e) {
+ fail(
+ "an IO error occured while trying to find the output file or creating GZIP constructor");
+ }
+ }
+
+ /**
+ * java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream,
+ *int)
+ */
+ public void test_ConstructorLjava_io_OutputStreamI() {
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("GZIPOutCon", ".txt"));
+ TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile,
+ 100);
+ assertNotNull("the constructor for GZIPOutputStream is null",
+ outGZIP);
+ assertEquals("the CRC value of the outputStream is not zero", 0, outGZIP
+ .getChecksum().getValue());
+ outGZIP.close();
+ } catch (IOException e) {
+ fail(
+ "an IO error occured while trying to find the output file or creating GZIP constructor");
+ }
+ }
+
+ /**
+ * java.util.zip.GZIPOutputStream#finish()
+ */
+ public void test_finish() {
+ // test method java.util.zip.GZIPOutputStream.finish()
+ byte byteArray[] = { 3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("GZIPOutFinish", ".txt"));
+ TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
+
+ outGZIP.finish();
+ int r = 0;
+ try {
+ outGZIP.write(byteArray, 0, 1);
+ } catch (IOException e) {
+ r = 1;
+ }
+
+ assertEquals("GZIP instance can still be used after finish is called",
+ 1, r);
+ outGZIP.close();
+ } catch (IOException e) {
+ fail(
+ "an IO error occured while trying to find the output file or creating GZIP constructor");
+ }
+ }
+
+ /**
+ * java.util.zip.GZIPOutputStream#close()
+ */
+ public void test_close() {
+ // test method java.util.zip.GZIPOutputStream.close()
+ byte byteArray[] = { 3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("GZIPOutClose2", ".txt"));
+ TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
+ outGZIP.close();
+ int r = 0;
+ try {
+ outGZIP.write(byteArray, 0, 1);
+ } catch (IOException e) {
+ r = 1;
+ }
+ assertEquals("GZIP instance can still be used after close is called",
+ 1, r);
+ } catch (IOException e) {
+ fail(
+ "an IO error occured while trying to find the output file or creating GZIP constructor");
+ }
+ }
+
+ /**
+ * java.util.zip.GZIPOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() {
+ // test method java.util.zip.GZIPOutputStream.writeBII
+ byte byteArray[] = { 3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
+ try {
+ FileOutputStream outFile = new FileOutputStream(
+ File.createTempFile("GZIPOutWrite", ".txt"));
+ TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
+ outGZIP.write(byteArray, 0, 10);
+ // ran JDK and found this CRC32 value is 3097700292
+ // System.out.print(outGZIP.getChecksum().getValue());
+ assertEquals("the checksum value was incorrect result of write from GZIP",
+ 3097700292L, outGZIP.getChecksum().getValue());
+
+ // test for boundary check
+ int r = 0;
+ try {
+ outGZIP.write(byteArray, 0, 11);
+ } catch (IndexOutOfBoundsException e) {
+ r = 1;
+ }
+ assertEquals("out of bounds exception is not present", 1, r);
+ outGZIP.close();
+ } catch (IOException e) {
+ fail(
+ "an IO error occured while trying to find the output file or creating GZIP constructor");
+ }
+ }
+
+ public void testSyncFlush() throws IOException {
+ PipedOutputStream pout = new PipedOutputStream();
+ PipedInputStream pin = new PipedInputStream(pout);
+ GZIPOutputStream out = new GZIPOutputStream(pout, true /* syncFlush */);
+ GZIPInputStream in = new GZIPInputStream(pin);
+
+ out.write(1);
+ out.write(2);
+ out.write(3);
+ out.flush();
+ // flush() is guaranteed to flush data only if syncFlush is true.
+ // The default flush param is NO_FLUSH so it's up to the deflater to
+ // decide how much input it wants to read before generating a compressed
+ // block.
+ assertEquals(1, in.read());
+ assertEquals(2, in.read());
+ assertEquals(3, in.read());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java
new file mode 100644
index 0000000..71871a0
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java
@@ -0,0 +1,480 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
+public class InflaterInputStreamTest extends TestCase {
+
+ // files hyts_construO,hyts_construOD,hyts_construODI needs to be
+ // included as resources
+ byte outPutBuf[] = new byte[500];
+
+ class MyInflaterInputStream extends InflaterInputStream {
+ MyInflaterInputStream(InputStream in) {
+ super(in);
+ }
+
+ MyInflaterInputStream(InputStream in, Inflater infl) {
+ super(in, infl);
+ }
+
+ MyInflaterInputStream(InputStream in, Inflater infl, int size) {
+ super(in, infl, size);
+ }
+
+ void myFill() throws IOException {
+ fill();
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() throws IOException {
+ //FIXME This test doesn't pass in Harmony classlib or Sun 5.0_7 RI
+ /*
+ int result = 0;
+ int buffer[] = new int[500];
+ InputStream infile = Support_Resources
+ .getStream("hyts_construO.bin");
+
+ InflaterInputStream inflatIP = new InflaterInputStream(infile);
+
+ int i = 0;
+ while ((result = inflatIP.read()) != -1) {
+ buffer[i] = result;
+ i++;
+ }
+ inflatIP.close();
+ */
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
+ *java.util.zip.Inflater)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_util_zip_Inflater() throws IOException {
+ byte byteArray[] = new byte[100];
+ InputStream infile = Support_Resources.getStream("hyts_construOD.bin");
+ Inflater inflate = new Inflater();
+ InflaterInputStream inflatIP = new InflaterInputStream(infile,
+ inflate);
+
+ inflatIP.read(byteArray, 0, 5);// only suppose to read in 5 bytes
+ inflatIP.close();
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
+ *java.util.zip.Inflater, int)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_util_zip_InflaterI() throws IOException {
+ int result = 0;
+ int buffer[] = new int[500];
+ InputStream infile = Support_Resources.getStream("hyts_construODI.bin");
+ Inflater inflate = new Inflater();
+ InflaterInputStream inflatIP = new InflaterInputStream(infile,
+ inflate, 1);
+
+ int i = 0;
+ while ((result = inflatIP.read()) != -1) {
+ buffer[i] = result;
+ i++;
+ }
+ inflatIP.close();
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
+ *java.util.zip.Inflater, int)
+ */
+ public void test_ConstructorLjava_io_InputStreamLjava_util_zip_InflaterI_1() throws IOException {
+ InputStream infile = Support_Resources.getStream("hyts_construODI.bin");
+ Inflater inflate = new Inflater();
+ InflaterInputStream inflatIP = null;
+ try {
+ inflatIP = new InflaterInputStream(infile, null, 1);
+ fail("NullPointerException expected");
+ } catch (NullPointerException NPE) {
+ //expected
+ }
+
+ try {
+ inflatIP = new InflaterInputStream(null, inflate, 1);
+ fail("NullPointerException expected");
+ } catch (NullPointerException NPE) {
+ //expected
+ }
+
+ try {
+ inflatIP = new InflaterInputStream(infile, inflate, -1);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException iae) {
+ //expected
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#mark(int)
+ */
+ public void test_markI() {
+ InputStream is = new ByteArrayInputStream(new byte[10]);
+ InflaterInputStream iis = new InflaterInputStream(is);
+ // mark do nothing, do no check
+ iis.mark(0);
+ iis.mark(-1);
+ iis.mark(10000000);
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#markSupported()
+ */
+ public void test_markSupported() {
+ InputStream is = new ByteArrayInputStream(new byte[10]);
+ InflaterInputStream iis = new InflaterInputStream(is);
+ assertFalse(iis.markSupported());
+ assertTrue(is.markSupported());
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#read()
+ */
+ public void test_read() throws IOException {
+ int result = 0;
+ int buffer[] = new int[500];
+ byte orgBuffer[] = { 1, 3, 4, 7, 8 };
+ InputStream infile = Support_Resources
+ .getStream("hyts_construOD.bin");
+ Inflater inflate = new Inflater();
+ InflaterInputStream inflatIP = new InflaterInputStream(infile,
+ inflate);
+
+ int i = 0;
+ while ((result = inflatIP.read()) != -1) {
+ buffer[i] = result;
+ i++;
+ }
+ inflatIP.close();
+
+ for (int j = 0; j < orgBuffer.length; j++) {
+ assertEquals(
+ "original compressed data did not equal decompressed data",
+ orgBuffer[j], buffer[j]);
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#read(byte [], int, int)
+ */
+ public void test_read_LBII() throws IOException {
+ int result = 0;
+ InputStream infile = Support_Resources.getStream("hyts_construOD.bin");
+ Inflater inflate = new Inflater();
+ InflaterInputStream inflatIP = new InflaterInputStream(infile, inflate);
+
+ byte[] b = new byte[3];
+ try {
+ result = inflatIP.read(null, 0, 1);
+ fail("NullPointerException expected");
+ } catch (NullPointerException npe) {
+ //expected
+ }
+
+ assertEquals(0, inflatIP.read(b, 0, 0));
+
+ try {
+ result = inflatIP.read(b, 5, 2); //offset higher
+ fail("IndexOutOfBoundsException expected");
+ } catch (IndexOutOfBoundsException iobe) {
+ //expected
+ }
+
+ inflatIP.close();
+ try {
+ inflatIP.read(b, 0, 1); //read after close
+ fail("IOException expected");
+ } catch (IOException ioe) {
+ //expected
+ }
+ }
+
+ public void testAvailableNonEmptySource() throws Exception {
+ // this byte[] is a deflation of these bytes: { 1, 3, 4, 6 }
+ byte[] deflated = { 72, -119, 99, 100, 102, 97, 3, 0, 0, 31, 0, 15, 0 };
+ InputStream in = new InflaterInputStream(new ByteArrayInputStream(deflated));
+ // InflaterInputStream.available() returns either 1 or 0, even though
+ // that contradicts the behavior defined in InputStream.available()
+ assertEquals(1, in.read());
+ assertEquals(1, in.available());
+ assertEquals(3, in.read());
+ assertEquals(1, in.available());
+ assertEquals(4, in.read());
+ assertEquals(1, in.available());
+ assertEquals(6, in.read());
+ assertEquals(0, in.available());
+ assertEquals(-1, in.read());
+ assertEquals(-1, in.read());
+ }
+
+ public void testAvailableSkip() throws Exception {
+ // this byte[] is a deflation of these bytes: { 1, 3, 4, 6 }
+ byte[] deflated = { 72, -119, 99, 100, 102, 97, 3, 0, 0, 31, 0, 15, 0 };
+ InputStream in = new InflaterInputStream(new ByteArrayInputStream(deflated));
+ assertEquals(1, in.available());
+ assertEquals(4, in.skip(4));
+ assertEquals(0, in.available());
+ }
+
+ public void testAvailableEmptySource() throws Exception {
+ // this byte[] is a deflation of the empty file
+ byte[] deflated = { 120, -100, 3, 0, 0, 0, 0, 1 };
+ InputStream in = new InflaterInputStream(new ByteArrayInputStream(deflated));
+ assertEquals(-1, in.read());
+ assertEquals(-1, in.read());
+ assertEquals(0, in.available());
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws IOException {
+ byte[] test = new byte[507];
+ for (int i = 0; i < 256; i++) {
+ test[i] = (byte) i;
+ }
+ for (int i = 256; i < test.length; i++) {
+ test[i] = (byte) (256 - i);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DeflaterOutputStream dos = new DeflaterOutputStream(baos);
+ dos.write(test);
+ dos.close();
+ InputStream is = new ByteArrayInputStream(baos.toByteArray());
+ InflaterInputStream iis = new InflaterInputStream(is);
+ byte[] outBuf = new byte[530];
+ int result = 0;
+ while (true) {
+ result = iis.read(outBuf, 0, 5);
+ if (result == -1) {
+ //"EOF was reached";
+ break;
+ }
+ }
+ try {
+ iis.read(outBuf, -1, 10);
+ fail("should throw IOOBE.");
+ } catch (IndexOutOfBoundsException e) {
+ // expected;
+ }
+ }
+
+ public void test_read$BII2() throws IOException {
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
+ FileInputStream fis = new FileInputStream(new File(resources,
+ "Broken_manifest.jar"));
+ InflaterInputStream iis = new InflaterInputStream(fis);
+ byte[] outBuf = new byte[530];
+
+ iis.close();
+ try {
+ iis.read(outBuf, 0, 5);
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected.
+ }
+ }
+
+ public void test_read$BII3() throws IOException {
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
+ FileInputStream fis = new FileInputStream(new File(resources,
+ "Broken_manifest.jar"));
+ InflaterInputStream iis = new InflaterInputStream(fis);
+ byte[] outBuf = new byte[530];
+
+ try {
+ iis.read();
+ fail("IOException expected.");
+ } catch (IOException ee) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#reset()
+ */
+ public void test_reset() {
+ InputStream is = new ByteArrayInputStream(new byte[10]);
+ InflaterInputStream iis = new InflaterInputStream(is);
+ try {
+ iis.reset();
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // correct
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#skip(long)
+ */
+ public void test_skipJ() throws IOException {
+ InputStream is = Support_Resources.getStream("hyts_available.tst");
+ InflaterInputStream iis = new InflaterInputStream(is);
+
+ // Tests for skipping a negative number of bytes.
+ try {
+ iis.skip(-3);
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ assertEquals("Incorrect Byte Returned.", 5, iis.read());
+
+ try {
+ iis.skip(Integer.MIN_VALUE);
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ assertEquals("Incorrect Byte Returned.", 4, iis.read());
+
+ // Test to make sure the correct number of bytes were skipped
+ assertEquals("Incorrect Number Of Bytes Skipped.", 3, iis.skip(3));
+
+ // Test to see if the number of bytes skipped returned is true.
+ assertEquals("Incorrect Byte Returned.", 7, iis.read());
+
+ assertEquals("Incorrect Number Of Bytes Skipped.", 0, iis.skip(0));
+ assertEquals("Incorrect Byte Returned.", 0, iis.read());
+
+ // Test for skipping more bytes than available in the stream
+ assertEquals("Incorrect Number Of Bytes Skipped.", 2, iis.skip(4));
+ assertEquals("Incorrect Byte Returned.", -1, iis.read());
+ iis.close();
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#skip(long)
+ */
+ public void test_skipJ2() throws IOException {
+ int result = 0;
+ int buffer[] = new int[100];
+ byte orgBuffer[] = { 1, 3, 4, 7, 8 };
+
+ // testing for negative input to skip
+ InputStream infile = Support_Resources
+ .getStream("hyts_construOD.bin");
+ Inflater inflate = new Inflater();
+ InflaterInputStream inflatIP = new InflaterInputStream(infile,
+ inflate, 10);
+ long skip;
+ try {
+ skip = inflatIP.skip(Integer.MIN_VALUE);
+ fail("Expected IllegalArgumentException when skip() is called with negative parameter");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ inflatIP.close();
+
+ // testing for number of bytes greater than input.
+ InputStream infile2 = Support_Resources
+ .getStream("hyts_construOD.bin");
+ InflaterInputStream inflatIP2 = new InflaterInputStream(infile2);
+
+ // looked at how many bytes the skip skipped. It is
+ // 5 and its supposed to be the entire input stream.
+
+ skip = inflatIP2.skip(Integer.MAX_VALUE);
+ // System.out.println(skip);
+ assertEquals("method skip() returned wrong number of bytes skipped",
+ 5, skip);
+
+ // test for skipping of 2 bytes
+ InputStream infile3 = Support_Resources
+ .getStream("hyts_construOD.bin");
+ InflaterInputStream inflatIP3 = new InflaterInputStream(infile3);
+ skip = inflatIP3.skip(2);
+ assertEquals("the number of bytes returned by skip did not correspond with its input parameters",
+ 2, skip);
+ int i = 0;
+ result = 0;
+ while ((result = inflatIP3.read()) != -1) {
+ buffer[i] = result;
+ i++;
+ }
+ inflatIP2.close();
+
+ for (int j = 2; j < orgBuffer.length; j++) {
+ assertEquals(
+ "original compressed data did not equal decompressed data",
+ orgBuffer[j], buffer[j - 2]);
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#available()
+ */
+ public void test_available() throws IOException {
+ InputStream is = Support_Resources.getStream("hyts_available.tst");
+ InflaterInputStream iis = new InflaterInputStream(is);
+
+ int available;
+ for (int i = 0; i < 11; i++) {
+ iis.read();
+ available = iis.available();
+ if (available == 0) {
+ assertEquals("Expected no more bytes to read", -1, iis.read());
+ } else {
+ assertEquals("Bytes Available Should Return 1.", 1, available);
+ }
+ }
+
+ iis.close();
+ try {
+ iis.available();
+ fail("available after close should throw IOException.");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterInputStream#close()
+ */
+ public void test_close() throws IOException {
+ InflaterInputStream iin = new InflaterInputStream(
+ new ByteArrayInputStream(new byte[0]));
+ iin.close();
+
+ // test for exception
+ iin.close();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterOutputStreamTest.java
new file mode 100644
index 0000000..ab856b1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterOutputStreamTest.java
@@ -0,0 +1,392 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterOutputStream;
+import java.util.zip.ZipException;
+
+import junit.framework.TestCase;
+
+public class InflaterOutputStreamTest extends TestCase {
+
+ private ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ private byte[] compressedBytes = new byte[100];
+
+ private String testString = "Hello world";
+
+ /**
+ * java.util.zip.InflaterOutputStream#InflaterOutputStream(java.io.OutputStream)
+ */
+ public void test_ConstructorLjava_io_OutputStream() throws IOException {
+ new InflaterOutputStream(os);
+
+ try {
+ new InflaterOutputStream(null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#InflaterOutputStream(java.io.OutputStream, Inflater)
+ */
+ public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_Inflater() {
+ new InflaterOutputStream(os, new Inflater());
+
+ try {
+ new InflaterOutputStream(null, new Inflater());
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new InflaterOutputStream(os, null);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#InflaterOutputStream(java.io.OutputStream, Inflater, int)
+ */
+ public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_InflaterI() {
+ new InflaterOutputStream(os, new Inflater(), 20);
+
+ try {
+ new InflaterOutputStream(null, null, 10);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new InflaterOutputStream(null, new Inflater(), -1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new InflaterOutputStream(os, null, -1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new InflaterOutputStream(null, null, -1);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new InflaterOutputStream(os, new Inflater(), 0);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ new InflaterOutputStream(os, new Inflater(), -10000);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#close()
+ */
+ public void test_close() throws IOException {
+ InflaterOutputStream ios = new InflaterOutputStream(os);
+ ios.close();
+ // multiple close
+ ios.close();
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#flush()
+ */
+ public void test_flush() throws IOException {
+ InflaterOutputStream ios = new InflaterOutputStream(os);
+ ios.close();
+ try {
+ ios.flush();
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ ios = new InflaterOutputStream(os);
+ ios.flush();
+ ios.flush();
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#finish()
+ */
+ public void test_finish() throws IOException {
+ InflaterOutputStream ios = new InflaterOutputStream(os);
+ ios.close();
+ try {
+ ios.finish();
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ ios = new InflaterOutputStream(os);
+ ios.finish();
+ ios.finish();
+ ios.flush();
+ ios.flush();
+ ios.finish();
+
+ byte[] bytes1 = { 10, 20, 30, 40, 50 };
+ Deflater defaultDeflater = new Deflater(Deflater.BEST_SPEED);
+ defaultDeflater.setInput(bytes1);
+ defaultDeflater.finish();
+ int length1 = defaultDeflater.deflate(compressedBytes);
+
+ byte[] bytes2 = { 100, 90, 80, 70, 60 };
+ Deflater bestDeflater = new Deflater(Deflater.BEST_COMPRESSION);
+ bestDeflater.setInput(bytes2);
+ bestDeflater.finish();
+ int length2 = bestDeflater.deflate(compressedBytes, length1, compressedBytes.length - length1);
+
+ ios = new InflaterOutputStream(os);
+ for (int i = 0; i < length1; i++) {
+ ios.write(compressedBytes[i]);
+ }
+ ios.finish();
+ ios.close();
+
+ byte[] result = os.toByteArray();
+ for (int i = 0; i < bytes1.length; i++) {
+ assertEquals(bytes1[i], result[i]);
+ }
+
+ ios = new InflaterOutputStream(os);
+ for (int i = length1; i < length2 * 2; i++) {
+ ios.write(compressedBytes[i]);
+ }
+ ios.finish();
+ ios.close();
+
+ result = os.toByteArray();
+ for (int i = 0; i < bytes2.length; i++) {
+ assertEquals(bytes2[i], result[bytes1.length + i]);
+ }
+
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#write(int)
+ */
+ public void test_write_I() throws IOException {
+ int length = compressToBytes(testString);
+
+ // uncompress the data stored in the compressedBytes
+ InflaterOutputStream ios = new InflaterOutputStream(os);
+ for (int i = 0; i < length; i++) {
+ ios.write(compressedBytes[i]);
+ }
+
+ String result = new String(os.toByteArray());
+ assertEquals(testString, result);
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#write(int)
+ */
+ public void test_write_I_Illegal() throws IOException {
+
+ // write after close
+ InflaterOutputStream ios = new InflaterOutputStream(os);
+ ios.close();
+ try {
+ ios.write(-1);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#write(byte[], int, int)
+ */
+ public void test_write_$BII() throws IOException {
+ int length = compressToBytes(testString);
+
+ // uncompress the data stored in the compressedBytes
+ InflaterOutputStream ios = new InflaterOutputStream(os);
+ ios.write(compressedBytes, 0, length);
+
+ String result = new String(os.toByteArray());
+ assertEquals(testString, result);
+ }
+
+ /**
+ * java.util.zip.InflaterOutputStream#write(byte[], int, int)
+ */
+ public void test_write_$BII_Illegal() throws IOException {
+ // write error compression (ZIP) format
+ InflaterOutputStream ios = new InflaterOutputStream(os);
+ byte[] bytes = { 0, 1, 2, 3 };
+ try {
+ ios.write(bytes, 0, 4);
+ fail("Should throw ZipException");
+ } catch (ZipException e) {
+ // expected
+ }
+ try {
+ ios.flush();
+ fail("Should throw ZipException");
+ } catch (ZipException e) {
+ // expected
+ }
+
+ // write after close
+ ios = new InflaterOutputStream(os);
+ ios.close();
+ try {
+ ios.write(bytes, 0, 4);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ ios.write(bytes, -1, 4);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ ios.write(bytes, -1, -4);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ ios.write(bytes, 0, 400);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ ios.write(null, -1, 4);
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ ios = new InflaterOutputStream(os);
+ try {
+ ios.write(null, 0, 4);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ ios.write(null, -1, 4);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ ios.write(null, 0, -4);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ ios.write(null, 0, 1000);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ try {
+ ios.write(bytes, -1, 4);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ios.write(bytes, 0, -4);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ios.write(bytes, 0, 100);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ios.write(bytes, -100, 100);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ ios = new InflaterOutputStream(os);
+ ios.finish();
+
+ try {
+ ios.write(bytes, -1, -100);
+ fail("Should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ ios.write(null, -1, -100);
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ ios = new InflaterOutputStream(os);
+ ios.flush();
+ try {
+ ios.write(bytes, 0, 4);
+ fail("Should throw ZipException");
+ } catch (ZipException e) {
+ // expected
+ }
+ }
+
+ // Compress the test string into compressedBytes
+ private int compressToBytes(String string) {
+ byte[] input = string.getBytes();
+ Deflater deflater = new Deflater();
+ deflater.setInput(input);
+ deflater.finish();
+ return deflater.deflate(compressedBytes);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java
new file mode 100644
index 0000000..a16fab7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java
@@ -0,0 +1,1135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.zip.Adler32;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Inflater;
+import java.util.zip.ZipException;
+import tests.support.resource.Support_Resources;
+
+public class InflaterTest extends junit.framework.TestCase {
+ byte outPutBuff1[] = new byte[500];
+
+ byte outPutDiction[] = new byte[500];
+
+ /**
+ * java.util.zip.Inflater#end()
+ */
+ public void test_end() throws Exception {
+ // test method of java.util.zip.inflater.end()
+ byte byteArray[] = { 5, 2, 3, 7, 8 };
+
+ int r = 0;
+ Inflater inflate = new Inflater();
+ inflate.setInput(byteArray);
+ inflate.end();
+
+ // Note that the RI throws an NPE here instead of an ISE (???).
+ try {
+ inflate.reset();
+ inflate.setInput(byteArray);
+ } catch (IllegalStateException expected) {
+ }
+
+ Inflater i = new Inflater();
+ i.end();
+ // check for exception
+ i.end();
+ }
+
+ /**
+ * java.util.zip.Inflater#finished()
+ */
+ public void test_finished() {
+ // test method of java.util.zip.inflater.finished()
+ byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+ Inflater inflate = new Inflater(false);
+ byte outPutInf[] = new byte[500];
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuff1);
+ }
+
+ inflate.inflate(outPutInf);
+ }
+ assertTrue(
+ "the method finished() returned false when no more data needs to be decompressed",
+ inflate.finished());
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(
+ "Final decompressed data does not equal the original data",
+ outPutInf[i], byteArray[i]);
+ }
+ assertEquals("final decompressed data contained more bytes than original - finished()",
+ 0, outPutInf[byteArray.length]);
+ }
+
+ /**
+ * java.util.zip.Inflater#getAdler()
+ */
+ public void test_getAdler() {
+ // test method of java.util.zip.inflater.getAdler()
+ byte dictionaryArray[] = { 'e', 'r', 't', 'a', 'b', 2, 3 };
+
+ Inflater inflateDiction = new Inflater();
+ inflateDiction.setInput(outPutDiction);
+ if (inflateDiction.needsDictionary() == true) {
+ // getting the checkSum value through the Adler32 class
+ Adler32 adl = new Adler32();
+ adl.update(dictionaryArray);
+ long checkSumR = adl.getValue();
+ assertEquals(
+ "the checksum value returned by getAdler() is not the same as the checksum returned by creating the adler32 instance",
+ inflateDiction.getAdler(), checkSumR);
+ }
+ }
+
+ /**
+ * java.util.zip.Inflater#getRemaining()
+ */
+ public void test_getRemaining() {
+ // test method of java.util.zip.inflater.getRemaining()
+ byte byteArray[] = { 1, 3, 5, 6, 7 };
+ Inflater inflate = new Inflater();
+ assertEquals("upon creating an instance of inflate, getRemaining returned a non zero value",
+ 0, inflate.getRemaining());
+ inflate.setInput(byteArray);
+ assertTrue(
+ "getRemaining returned zero when there is input in the input buffer",
+ inflate.getRemaining() != 0);
+ }
+
+ /**
+ * java.util.zip.Inflater#getTotalIn()
+ */
+ public void test_getTotalIn() {
+ // test method of java.util.zip.inflater.getTotalIn()
+ // creating the decompressed data
+ byte outPutBuf[] = new byte[500];
+ byte byteArray[] = { 1, 3, 4, 7, 8 };
+ byte outPutInf[] = new byte[500];
+ int x = 0;
+ Deflater deflate = new Deflater(1);
+ deflate.setInput(byteArray);
+ while (!(deflate.needsInput())) {
+ x += deflate.deflate(outPutBuf, x, outPutBuf.length - x);
+ }
+ deflate.finish();
+ while (!(deflate.finished())) {
+ x = x + deflate.deflate(outPutBuf, x, outPutBuf.length - x);
+ }
+
+ Inflater inflate = new Inflater();
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuf);
+ }
+
+ inflate.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Input to inflate is invalid or corrupted - getTotalIn");
+ }
+ // System.out.print(deflate.getTotalOut() + " " + inflate.getTotalIn());
+ assertEquals(
+ "the total byte in outPutBuf did not equal the byte returned in getTotalIn",
+ deflate.getTotalOut(), inflate.getTotalIn());
+
+ Inflater inflate2 = new Inflater();
+ int offSet = 0;// seems only can start as 0
+ int length = 4;
+ try {
+ // seems no while loops allowed
+ if (inflate2.needsInput()) {
+ inflate2.setInput(outPutBuff1, offSet, length);
+ }
+
+ inflate2.inflate(outPutInf);
+
+ } catch (DataFormatException e) {
+ fail("Input to inflate is invalid or corrupted - getTotalIn");
+ }
+ // System.out.print(inflate2.getTotalIn() + " " + length);
+ assertEquals(
+ "total byte dictated by length did not equal byte returned in getTotalIn",
+ length, inflate2.getTotalIn());
+ }
+
+ /**
+ * java.util.zip.Inflater#getTotalOut()
+ */
+ public void test_getTotalOut() {
+ // test method of java.util.zip.inflater.Inflater()
+ // creating the decompressed data
+ byte outPutBuf[] = new byte[500];
+ byte byteArray[] = { 1, 3, 4, 7, 8 };
+ int y = 0;
+ int x = 0;
+ Deflater deflate = new Deflater(1);
+ deflate.setInput(byteArray);
+ while (!(deflate.needsInput())) {
+ x += deflate.deflate(outPutBuf, x, outPutBuf.length - x);
+ }
+ deflate.finish();
+ while (!(deflate.finished())) {
+ x = x + deflate.deflate(outPutBuf, x, outPutBuf.length - x);
+ }
+
+ Inflater inflate = new Inflater();
+ byte outPutInf[] = new byte[500];
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuf);
+ }
+
+ y += inflate.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Input to inflate is invalid or corrupted - getTotalIn");
+ }
+
+ assertEquals(
+ "the sum of the bytes returned from inflate does not equal the bytes of getTotalOut()",
+ inflate.getTotalOut(), y);
+ assertEquals(
+ "the total number of bytes to be compressed does not equal the total bytes decompressed",
+ deflate.getTotalIn(), inflate.getTotalOut());
+
+ // testing inflate(byte,int,int)
+ inflate.reset();
+ y = 0;
+ int offSet = 0;// seems only can start as 0
+ int length = 4;
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuf);
+ }
+
+ y += inflate.inflate(outPutInf, offSet, length);
+ }
+ } catch (DataFormatException e) {
+ System.out
+ .println("Input to inflate is invalid or corrupted - getTotalIn");
+ }
+ assertEquals(
+ "the sum of the bytes returned from inflate does not equal the bytes of getTotalOut()",
+ y, inflate.getTotalOut());
+ assertEquals(
+ "the total number of bytes to be compressed does not equal the total bytes decompressed",
+ deflate.getTotalIn(), inflate.getTotalOut());
+ }
+
+ /**
+ * java.util.zip.Inflater#inflate(byte[])
+ */
+ public void test_inflate$B() {
+ // test method of java.util.zip.inflater.inflate(byte)
+
+ byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+ byte outPutInf[] = new byte[500];
+ Inflater inflate = new Inflater();
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuff1);
+ }
+ inflate.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(
+ "Final decompressed data does not equal the original data",
+ byteArray[i], outPutInf[i]);
+ }
+ assertEquals("final decompressed data contained more bytes than original - inflateB",
+ 0, outPutInf[byteArray.length]);
+ // testing for an empty input array
+ byte outPutBuf[] = new byte[500];
+ byte emptyArray[] = new byte[11];
+ int x = 0;
+ Deflater defEmpty = new Deflater(3);
+ defEmpty.setInput(emptyArray);
+ while (!(defEmpty.needsInput())) {
+ x += defEmpty.deflate(outPutBuf, x, outPutBuf.length - x);
+ }
+ defEmpty.finish();
+ while (!(defEmpty.finished())) {
+ x += defEmpty.deflate(outPutBuf, x, outPutBuf.length - x);
+ }
+ assertEquals(
+ "the total number of byte from deflate did not equal getTotalOut - inflate(byte)",
+ x, defEmpty.getTotalOut());
+ assertEquals(
+ "the number of input byte from the array did not correspond with getTotalIn - inflate(byte)",
+ emptyArray.length, defEmpty.getTotalIn());
+ Inflater infEmpty = new Inflater();
+ try {
+ while (!(infEmpty.finished())) {
+ if (infEmpty.needsInput()) {
+ infEmpty.setInput(outPutBuf);
+ }
+ infEmpty.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ for (int i = 0; i < emptyArray.length; i++) {
+ assertEquals(
+ "Final decompressed data does not equal the original data",
+ emptyArray[i], outPutInf[i]);
+ assertEquals("Final decompressed data does not equal zero",
+ 0, outPutInf[i]);
+ }
+ assertEquals("Final decompressed data contains more element than original data",
+ 0, outPutInf[emptyArray.length]);
+ }
+
+ public void test_inflate$B1() {
+ byte codedData[] = {
+ 120, -38, 75, -54, 73, -52, 80, 40, 46, 41, -54, -52, 75, 87,
+ 72, -50, -49, 43, 73, -52, -52, 43, 86, 72, 2, 10, 34, 99,
+ -123, -60, -68, 20, -80, 32, 0, -101, -69, 17, 84 };
+ String codedString = "blah string contains blahblahblahblah and blah";
+
+ Inflater infl1 = new Inflater();
+ Inflater infl2 = new Inflater();
+
+ byte[] result = new byte[100];
+ int decLen = 0;
+
+ infl1.setInput(codedData, 0, codedData.length);
+ try {
+ decLen = infl1.inflate(result);
+ } catch (DataFormatException e) {
+ fail("Unexpected DataFormatException");
+ }
+
+ infl1.end();
+ assertEquals(codedString, new String(result, 0, decLen));
+ codedData[5] = 0;
+
+ infl2.setInput(codedData, 0, codedData.length);
+ try {
+ decLen = infl2.inflate(result);
+ fail("Expected DataFormatException");
+ } catch (DataFormatException e) {
+ // expected
+ }
+
+ infl2.end();
+ }
+
+ /**
+ * java.util.zip.Inflater#inflate(byte[], int, int)
+ */
+ public void test_inflate$BII() {
+ // test method of java.util.zip.inflater.inflate(byte,int,int)
+
+ byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+ byte outPutInf[] = new byte[100];
+ int y = 0;
+ Inflater inflate = new Inflater();
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ assertEquals(0, inflate.inflate(outPutInf, 0, 1));
+ inflate.setInput(outPutBuff1);
+ }
+ y += inflate.inflate(outPutInf, y, outPutInf.length - y);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(
+ "Final decompressed data does not equal the original data",
+ byteArray[i], outPutInf[i]);
+ }
+ assertEquals("final decompressed data contained more bytes than original - inflateB",
+ 0, outPutInf[byteArray.length]);
+
+ // test boundary checks
+ inflate.reset();
+ int r = 0;
+ int offSet = 0;
+ int lengthError = 101;
+ try {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuff1);
+ }
+ inflate.inflate(outPutInf, offSet, lengthError);
+
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ r = 1;
+ }
+ assertEquals("out of bounds error did not get caught", 1, r);
+
+ try {
+ assertEquals(0, inflate.inflate(outPutInf, offSet, 0));
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ inflate.end();
+ try {
+ inflate.inflate(outPutInf, offSet, 1);
+ fail("IllegalStateException expected");
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+
+ public void test_inflate$BII1() {
+ byte codedData[] = {
+ 120, -38, 75, -54, 73, -52, 80, 40, 46, 41, -54, -52, 75, 87,
+ 72, -50, -49, 43, 73, -52, -52, 43, 86, 72, 2, 10, 34, 99,
+ -123, -60, -68, 20, -80, 32, 0, -101, -69, 17, 84 };
+ String codedString = "blah string";
+
+ Inflater infl1 = new Inflater();
+ Inflater infl2 = new Inflater();
+
+ byte[] result = new byte[100];
+ int decLen = 0;
+
+ infl1.setInput(codedData, 0, codedData.length);
+ try {
+ decLen = infl1.inflate(result, 10, 11);
+ } catch (DataFormatException e) {
+ fail("Unexpected DataFormatException");
+ }
+
+ infl1.end();
+ assertEquals(codedString, new String(result, 10, decLen));
+ codedData[5] = 0;
+
+ infl2.setInput(codedData, 0, codedData.length);
+ try {
+ decLen = infl2.inflate(result, 10, 11);
+ fail("Expected DataFormatException");
+ } catch (DataFormatException e) {
+ // expected
+ }
+
+ infl2.end();
+ }
+
+ /*
+ * Regression test for HARMONY-6637
+ */
+ public void testInflateZero() throws Exception {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(
+ byteArrayOutputStream);
+ deflaterOutputStream.close();
+ byte[] input = byteArrayOutputStream.toByteArray();
+
+ Inflater inflater = new Inflater();
+ inflater.setInput(input);
+ byte[] buffer = new byte[0];
+ int numRead = 0;
+ while (!inflater.finished()) {
+ int inflatedChunkSize = inflater.inflate(buffer, numRead,
+ buffer.length - numRead);
+ numRead += inflatedChunkSize;
+ }
+ inflater.end();
+ }
+
+ /**
+ * java.util.zip.Inflater#Inflater()
+ */
+ public void test_Constructor() {
+ // test method of java.util.zip.inflater.Inflater()
+ Inflater inflate = new Inflater();
+ assertNotNull("failed to create the instance of inflater",
+ inflate);
+ }
+
+ /**
+ * java.util.zip.Inflater#Inflater(boolean)
+ */
+ public void test_ConstructorZ() {
+ // test method of java.util.zip.inflater.Inflater(boolean)
+ // note does not throw exception if deflater has a header, but inflater
+ // doesn't or vice versa.
+ byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+ Inflater inflate = new Inflater(true);
+ assertNotNull("failed to create the instance of inflater", inflate);
+ byte outPutInf[] = new byte[500];
+ int r = 0;
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuff1);
+ }
+
+ inflate.inflate(outPutInf);
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals("the output array from inflate should contain 0 because the header of inflate and deflate did not match, but this failed",
+ 0, outPutBuff1[i]);
+ }
+ } catch (DataFormatException e) {
+ r = 1;
+ }
+ assertEquals("Error: exception should be thrown because of header inconsistency",
+ 1, r);
+
+ }
+
+ /**
+ * java.util.zip.Inflater#needsDictionary()
+ */
+ public void test_needsDictionary() {
+ // test method of java.util.zip.inflater.needsDictionary()
+ // note: this flag is set after inflate is called
+ byte outPutInf[] = new byte[500];
+
+ // testing with dictionary set.
+ Inflater inflateDiction = new Inflater();
+ if (inflateDiction.needsInput()) {
+ inflateDiction.setInput(outPutDiction);
+ }
+ try {
+ assertEquals("should return 0 because needs dictionary",
+ 0, inflateDiction.inflate(outPutInf));
+ } catch (DataFormatException e) {
+ fail("Should not cause exception");
+ }
+ assertTrue(
+ "method needsDictionary returned false when dictionary was used in deflater",
+ inflateDiction.needsDictionary());
+
+ // testing without dictionary
+ Inflater inflate = new Inflater();
+ try {
+ inflate.setInput(outPutBuff1);
+ inflate.inflate(outPutInf);
+ assertFalse(
+ "method needsDictionary returned true when dictionary was not used in deflater",
+ inflate.needsDictionary());
+ } catch (DataFormatException e) {
+ fail(
+ "Input to inflate is invalid or corrupted - needsDictionary");
+ }
+
+ // Regression test for HARMONY-86
+ Inflater inf = new Inflater();
+ assertFalse(inf.needsDictionary());
+ assertEquals(0, inf.getTotalIn());
+ assertEquals(0, inf.getTotalOut());
+ assertEquals(0, inf.getBytesRead());
+ assertEquals(0, inf.getBytesWritten());
+ assertEquals(1, inf.getAdler());
+ }
+
+ /**
+ * java.util.zip.Inflater#needsInput()
+ */
+ public void test_needsInput() {
+ // test method of java.util.zip.inflater.needsInput()
+ Inflater inflate = new Inflater();
+ assertTrue(
+ "needsInput give the wrong boolean value as a result of no input buffer",
+ inflate.needsInput());
+
+ byte byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
+ inflate.setInput(byteArray);
+ assertFalse(
+ "methodNeedsInput returned true when the input buffer is full",
+ inflate.needsInput());
+
+ inflate.reset();
+ byte byteArrayEmpty[] = new byte[0];
+ inflate.setInput(byteArrayEmpty);
+ assertTrue(
+ "needsInput give wrong boolean value as a result of an empty input buffer",
+ inflate.needsInput());
+ }
+
+ /**
+ * java.util.zip.Inflater#reset()
+ */
+ public void test_reset() {
+ // test method of java.util.zip.inflater.reset()
+ byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+ byte outPutInf[] = new byte[100];
+ int y = 0;
+ Inflater inflate = new Inflater();
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuff1);
+ }
+ y += inflate.inflate(outPutInf, y, outPutInf.length - y);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(
+ "Final decompressed data does not equal the original data",
+ byteArray[i], outPutInf[i]);
+ }
+ assertEquals("final decompressed data contained more bytes than original - reset",
+ 0, outPutInf[byteArray.length]);
+
+ // testing that resetting the inflater will also return the correct
+ // decompressed data
+
+ inflate.reset();
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutBuff1);
+ }
+ inflate.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertEquals(
+ "Final decompressed data does not equal the original data",
+ byteArray[i], outPutInf[i]);
+ }
+ assertEquals("final decompressed data contained more bytes than original - reset",
+ 0, outPutInf[byteArray.length]);
+
+ }
+
+ /**
+ * java.util.zip.Inflater#setDictionary(byte[])
+ */
+ public void test_setDictionary$B() {
+ //FIXME This test doesn't pass in Harmony classlib or Sun 5.0_7 RI
+ /*
+ // test method of java.util.zip.inflater.setDictionary(byte)
+ byte dictionaryArray[] = { 'e', 'r', 't', 'a', 'b', 2, 3 };
+ byte byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3',
+ 'w', 'r' };
+
+ byte outPutInf[] = new byte[100];
+
+ // trying to inflate without setting a dictionary
+
+ Inflater inflateWO = new Inflater();
+ byte outPutInf2[] = new byte[100];
+ int r = 0;
+ try {
+ while (!(inflateWO.finished())) {
+ if (inflateWO.needsInput()) {
+ inflateWO.setInput(outPutDiction);
+ }
+ inflateWO.inflate(outPutInf2);
+ }
+ } catch (DataFormatException e) {
+ r = 1;
+ }
+ assertEquals("invalid input to be decompressed due to dictionary not set",
+ 1, r);
+ // now setting the dictionary in inflater
+ Inflater inflate = new Inflater();
+ try {
+ while (!(inflate.finished())) {
+ if (inflate.needsInput()) {
+ inflate.setInput(outPutDiction);
+ }
+ if (inflate.needsDictionary()) {
+ inflate.setDictionary(dictionaryArray);
+ }
+ inflate.inflate(outPutInf);
+ }
+ } catch (DataFormatException e) {
+ fail("Invalid input to be decompressed");
+ }
+ for (int i = 0; i < byteArray.length; i++) {
+ assertTrue(
+ "Final decompressed data does not equal the original data",
+ byteArray[i] == outPutInf[i]);
+ }
+ assertEquals("final decompressed data contained more bytes than original - deflateB",
+ 0, outPutInf[byteArray.length]);
+ */
+ }
+
+ /**
+ * java.util.zip.Inflater#setInput(byte[])
+ */
+ public void test_setInput$B() {
+ // test method of java.util.zip.inflater.setInput(byte)
+ byte byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
+ Inflater inflate = new Inflater();
+ inflate.setInput(byteArray);
+ assertTrue("setInputB did not deliver any byte to the input buffer",
+ inflate.getRemaining() != 0);
+ }
+
+ /**
+ * java.util.zip.Inflater#setInput(byte[], int, int)
+ */
+ public void test_setInput$BII() {
+ // test method of java.util.zip.inflater.setInput(byte,int,int)
+ byte byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
+ int offSet = 6;
+ int length = 6;
+ Inflater inflate = new Inflater();
+ inflate.setInput(byteArray, offSet, length);
+ assertEquals(
+ "setInputBII did not deliver the right number of bytes to the input buffer",
+ length, inflate.getRemaining());
+ // boundary check
+ inflate.reset();
+ int r = 0;
+ try {
+ inflate.setInput(byteArray, 100, 100);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ r = 1;
+ }
+ assertEquals("boundary check is not present for setInput", 1, r);
+ }
+
+ @Override
+ protected void setUp() {
+ try {
+ java.io.InputStream infile = Support_Resources
+ .getStream("hyts_compressD.bin");
+ BufferedInputStream inflatIP = new BufferedInputStream(infile);
+ inflatIP.read(outPutBuff1, 0, outPutBuff1.length);
+ inflatIP.close();
+
+ java.io.InputStream infile2 = Support_Resources
+ .getStream("hyts_compDiction.bin");
+ BufferedInputStream inflatIP2 = new BufferedInputStream(infile2);
+ inflatIP2.read(outPutDiction, 0, outPutDiction.length);
+ inflatIP2.close();
+
+ } catch (FileNotFoundException e) {
+ fail(
+ "input file to test InflaterInputStream constructor is not found");
+ } catch (ZipException e) {
+ fail(
+ "read() threw an zip exception while testing constructor");
+ } catch (IOException e) {
+ fail("read() threw an exception while testing constructor");
+ }
+ }
+
+ @Override
+ protected void tearDown() {
+ }
+
+ /**
+ * java.util.zip.Deflater#getBytesRead()
+ */
+ public void test_getBytesRead() throws DataFormatException,
+ UnsupportedEncodingException {
+ // Regression test for HARMONY-158
+ Deflater def = new Deflater();
+ Inflater inf = new Inflater();
+ assertEquals(0, def.getTotalIn());
+ assertEquals(0, def.getTotalOut());
+ assertEquals(0, def.getBytesRead());
+ // Encode a String into bytes
+ String inputString = "blahblahblah??";
+ byte[] input = inputString.getBytes("UTF-8");
+
+ // Compress the bytes
+ byte[] output = new byte[100];
+ def.setInput(input);
+ def.finish();
+ def.deflate(output);
+ inf.setInput(output);
+ int compressedDataLength = inf.inflate(input);
+ assertEquals(16, inf.getTotalIn());
+ assertEquals(compressedDataLength, inf.getTotalOut());
+ assertEquals(16, inf.getBytesRead());
+ }
+
+ /**
+ * java.util.zip.Deflater#getBytesRead()
+ */
+ public void test_getBytesWritten() throws DataFormatException, UnsupportedEncodingException {
+ // Regression test for HARMONY-158
+ Deflater def = new Deflater();
+ Inflater inf = new Inflater();
+ assertEquals(0, def.getTotalIn());
+ assertEquals(0, def.getTotalOut());
+ assertEquals(0, def.getBytesWritten());
+ // Encode a String into bytes
+ String inputString = "blahblahblah??";
+ byte[] input = inputString.getBytes("UTF-8");
+
+ // Compress the bytes
+ byte[] output = new byte[100];
+ def.setInput(input);
+ def.finish();
+ def.deflate(output);
+ inf.setInput(output);
+ int compressedDataLength = inf.inflate(input);
+ assertEquals(16, inf.getTotalIn());
+ assertEquals(compressedDataLength, inf.getTotalOut());
+ assertEquals(14, inf.getBytesWritten());
+ }
+
+ /**
+ * java.util.zip.Deflater#inflate(byte[], int, int)
+ */
+ public void testInflate() throws Exception {
+ // Regression for HARMONY-81
+ Inflater inf = new Inflater();
+ int res = inf.inflate(new byte[0], 0, 0);
+
+ assertEquals(0, res);
+
+ // Regression for HARMONY-2508
+ Inflater inflater = new Inflater();
+ byte[] b = new byte[1024];
+ assertEquals(0, inflater.inflate(b));
+ inflater.end();
+
+ // Regression for HARMONY-2510
+ inflater = new Inflater();
+ inflater.setInput(new byte[] { -1 });
+ try {
+ inflater.inflate(b);
+
+ // The RI detects malformed data on the malformed input { -1 }. Both
+ // this implementation and the native zlib API return "need input"
+ // on that data. This is an error if the stream is exhausted, but
+ // not one that results in an exception in the Inflater API.
+ assertTrue(inflater.needsInput());
+ } catch (DataFormatException e) {
+ // expected
+ }
+
+ inflater = new Inflater();
+ inflater.setInput(new byte[] { -1, -1, -1 });
+ try {
+ inflater.inflate(b);
+ } catch (DataFormatException e) {
+ // expected
+ }
+ }
+
+ public void testSetDictionary$B() throws Exception {
+ int i = 0;
+ String inputString = "blah string contains blahblahblahblah and blah";
+ String dictionary1 = "blah";
+ String dictionary2 = "1234";
+
+ byte[] outputNo = new byte[100];
+ byte[] output1 = new byte[100];
+ byte[] output2 = new byte[100];
+ Deflater defDictNo = new Deflater(9);
+ Deflater defDict1 = new Deflater(9);
+ Deflater defDict2 = new Deflater(9);
+
+ defDict1.setDictionary(dictionary1.getBytes());
+ defDict2.setDictionary(dictionary2.getBytes());
+
+ defDictNo.setInput(inputString.getBytes());
+ defDict1.setInput(inputString.getBytes());
+ defDict2.setInput(inputString.getBytes());
+
+ defDictNo.finish();
+ defDict1.finish();
+ defDict2.finish();
+
+ int dataLenNo = defDictNo.deflate(outputNo);
+ int dataLen1 = defDict1.deflate(output1);
+ int dataLen2 = defDict2.deflate(output2);
+
+ boolean passNo1 = false;
+ boolean passNo2 = false;
+ boolean pass12 = false;
+
+ for (i = 0; i < (dataLenNo < dataLen1 ? dataLenNo : dataLen1); i++) {
+ if (outputNo[i] != output1[i]) {
+ passNo1 = true;
+ break;
+ }
+ }
+ for (i = 0; i < (dataLenNo < dataLen1 ? dataLenNo : dataLen2); i++) {
+ if (outputNo[i] != output2[i]) {
+ passNo2 = true;
+ break;
+ }
+ }
+ for (i = 0; i < (dataLen1 < dataLen2 ? dataLen1 : dataLen2); i++) {
+ if (output1[i] != output2[i]) {
+ pass12 = true;
+ break;
+ }
+ }
+
+ assertTrue(
+ "Compressed data the same for stream with dictionary and without it.",
+ passNo1);
+ assertTrue(
+ "Compressed data the same for stream with dictionary and without it.",
+ passNo2);
+ assertTrue(
+ "Compressed data the same for stream with different dictionaries.",
+ pass12);
+
+ Inflater inflNo = new Inflater();
+ Inflater infl1 = new Inflater();
+ Inflater infl2 = new Inflater();
+
+ byte[] result = new byte[100];
+ int decLen;
+
+ inflNo.setInput(outputNo, 0, dataLenNo);
+ decLen = inflNo.inflate(result);
+
+ assertFalse(inflNo.needsDictionary());
+ inflNo.end();
+ assertEquals(inputString, new String(result, 0, decLen));
+
+ infl1.setInput(output1, 0, dataLen1);
+ decLen = infl1.inflate(result);
+
+ assertTrue(infl1.needsDictionary());
+ infl1.setDictionary(dictionary1.getBytes());
+ decLen = infl1.inflate(result);
+ infl1.end();
+ assertEquals(inputString, new String(result, 0, decLen));
+
+ infl2.setInput(output2, 0, dataLen2);
+ decLen = infl2.inflate(result);
+
+ assertTrue(infl2.needsDictionary());
+ infl2.setDictionary(dictionary2.getBytes());
+ decLen = infl2.inflate(result);
+ infl2.end();
+ assertEquals(inputString, new String(result, 0, decLen));
+
+
+ inflNo = new Inflater();
+ infl1 = new Inflater();
+ inflNo.setInput(outputNo, 0, dataLenNo);
+ try {
+ infl1.setDictionary(dictionary1.getBytes());
+ fail("IllegalArgumentException expected.");
+ } catch (IllegalArgumentException ee) {
+ // expected.
+ }
+ inflNo.end();
+
+ infl1.setInput(output1, 0, dataLen1);
+ decLen = infl1.inflate(result);
+
+ assertTrue(infl1.needsDictionary());
+ try {
+ infl1.setDictionary(dictionary2.getBytes());
+ fail("IllegalArgumentException expected.");
+ } catch (IllegalArgumentException ee) {
+ // expected.
+ }
+ infl1.end();
+ try {
+ infl1.setDictionary(dictionary2.getBytes());
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException ise) {
+ //expected
+ }
+ }
+
+ public void testSetDictionary$BII() throws Exception {
+ int i = 0;
+ String inputString = "blah string contains blahblahblahblah and blah";
+ String dictionary1 = "blah";
+ String dictionary2 = "blahblahblah";
+
+ byte[] output1 = new byte[100];
+ byte[] output2 = new byte[100];
+ byte[] output3 = new byte[100];
+
+ Deflater defDict1 = new Deflater(9);
+ Deflater defDict2 = new Deflater(9);
+ Deflater defDict3 = new Deflater(9);
+
+ defDict1.setDictionary(dictionary1.getBytes());
+ defDict2.setDictionary(dictionary2.getBytes());
+ defDict3.setDictionary(dictionary2.getBytes(), 4, 4);
+
+ defDict1.setInput(inputString.getBytes());
+ defDict2.setInput(inputString.getBytes());
+ defDict3.setInput(inputString.getBytes());
+
+ defDict1.finish();
+ defDict2.finish();
+ defDict3.finish();
+
+ int dataLen1 = defDict1.deflate(output1);
+ int dataLen2 = defDict2.deflate(output2);
+ int dataLen3 = defDict3.deflate(output3);
+
+ boolean pass12 = false;
+ boolean pass23 = false;
+ boolean pass13 = true;
+
+ for (i = 0; i < (dataLen1 < dataLen2 ? dataLen1 : dataLen2); i++) {
+ if (output1[i] != output2[i]) {
+ pass12 = true;
+ break;
+ }
+ }
+ for (i = 0; i < (dataLen2 < dataLen3 ? dataLen2 : dataLen3); i++) {
+ if (output2[i] != output3[i]) {
+ pass23 = true;
+ break;
+ }
+ }
+ for (i = 0; i < (dataLen1 < dataLen3 ? dataLen1 : dataLen3); i++) {
+ if (output1[i] != output3[i]) {
+ pass13 = false;
+ break;
+ }
+ }
+
+ assertTrue(
+ "Compressed data the same for stream with different dictionaries.",
+ pass12);
+ assertTrue(
+ "Compressed data the same for stream with different dictionaries.",
+ pass23);
+ assertTrue(
+ "Compressed data the differs for stream with the same dictionaries.",
+ pass13);
+
+ Inflater infl1 = new Inflater();
+ Inflater infl2 = new Inflater();
+ Inflater infl3 = new Inflater();
+ Inflater infl4 = new Inflater();
+
+ byte[] result = new byte[100];
+ int decLen;
+
+ infl1.setInput(output1, 0, dataLen1);
+ decLen = infl1.inflate(result);
+
+ assertTrue(infl1.needsDictionary());
+ infl1.setDictionary(dictionary2.getBytes(), 4, 4);
+ decLen = infl1.inflate(result);
+ infl1.end();
+ assertEquals(inputString, new String(result, 0, decLen));
+
+ infl2.setInput(output2, 0, dataLen2);
+ decLen = infl2.inflate(result);
+
+ assertTrue(infl2.needsDictionary());
+ try {
+ infl2.setDictionary(dictionary1.getBytes());
+ fail("IllegalArgumentException expected.");
+ } catch (IllegalArgumentException ee) {
+ // expected
+ }
+ infl2.end();
+
+ infl3.setInput(output3, 0, dataLen3);
+ decLen = infl3.inflate(result);
+
+ assertTrue(infl3.needsDictionary());
+ infl3.setDictionary(dictionary1.getBytes());
+ decLen = infl3.inflate(result);
+ infl3.end();
+ assertEquals(inputString, new String(result, 0, decLen));
+
+ //exception test
+ infl4.setInput(output3, 0, dataLen3);
+ decLen = infl4.inflate(result);
+ assertTrue(infl4.needsDictionary());
+
+ try {
+ infl4.setDictionary(dictionary1.getBytes(), 4, 4);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException aiob) {
+ //expected
+ }
+ }
+
+ public void testExceptions() throws Exception {
+ byte byteArray[] = { 5, 2, 3, 7, 8 };
+
+ int r = 0;
+ Inflater inflate = new Inflater();
+ inflate.setInput(byteArray);
+ inflate.end();
+
+ try {
+ inflate.getAdler();
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException expected) {
+ //expected
+ }
+
+ try {
+ inflate.getBytesRead();
+ fail("NullPointerException expected");
+ } catch (IllegalStateException expected) {
+ } catch (NullPointerException expected) {
+ //expected
+ }
+
+ try {
+ inflate.getBytesWritten();
+ fail("NullPointerException expected");
+ } catch (NullPointerException expected) {
+ } catch (IllegalStateException expected) {
+ //expected
+ }
+
+
+ try {
+ inflate.getTotalIn();
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException ise) {
+ //expected
+ }
+
+ try {
+ inflate.getTotalOut();
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException ise) {
+ //expected
+ }
+
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipEntryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipEntryTest.java
new file mode 100644
index 0000000..f034639
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipEntryTest.java
@@ -0,0 +1,453 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.TimeZone;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import libcore.io.Streams;
+import tests.support.resource.Support_Resources;
+
+public class ZipEntryTest extends junit.framework.TestCase {
+ // zip file hyts_ZipFile.zip must be included as a resource
+ private ZipEntry zentry;
+ private ZipFile zfile;
+
+ private long orgSize;
+ private long orgCompressedSize;
+ private long orgCrc;
+ private long orgTime;
+
+ /**
+ * java.util.zip.ZipEntry#ZipEntry(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ // Test for method java.util.zip.ZipEntry(java.lang.String)
+ zentry = zfile.getEntry("File3.txt");
+ assertNotNull("Failed to create ZipEntry", zentry);
+ try {
+ zentry = zfile.getEntry(null);
+ fail("NullPointerException not thrown");
+ } catch (NullPointerException e) {
+ }
+ StringBuffer s = new StringBuffer();
+ for (int i = 0; i < 65535; i++) {
+ s.append('a');
+ }
+ try {
+ zentry = new ZipEntry(s.toString());
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException During Test.");
+ }
+ try {
+ s.append('a');
+ zentry = new ZipEntry(s.toString());
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ String n = null;
+ zentry = new ZipEntry(n);
+ fail("NullPointerException not thrown");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * java.util.zip.ZipEntry#getComment()
+ */
+ public void test_getComment() {
+ // Test for method java.lang.String java.util.zip.ZipEntry.getComment()
+ ZipEntry zipEntry = new ZipEntry("zippy.zip");
+ assertNull("Incorrect Comment Returned.", zipEntry.getComment());
+ zipEntry.setComment("This Is A Comment");
+ assertEquals("Incorrect Comment Returned.",
+ "This Is A Comment", zipEntry.getComment());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#getCompressedSize()
+ */
+ public void test_getCompressedSize() {
+ // Test for method long java.util.zip.ZipEntry.getCompressedSize()
+ assertTrue("Incorrect compressed size returned", zentry
+ .getCompressedSize() == orgCompressedSize);
+ }
+
+ /**
+ * java.util.zip.ZipEntry#getCrc()
+ */
+ public void test_getCrc() {
+ // Test for method long java.util.zip.ZipEntry.getCrc()
+ assertEquals("Failed to get Crc", orgCrc, zentry.getCrc());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#getExtra()
+ */
+ public void test_getExtra() {
+ // Test for method byte [] java.util.zip.ZipEntry.getExtra()
+ assertNull("Incorrect extra information returned",
+ zentry.getExtra());
+ byte[] ba = { 'T', 'E', 'S', 'T' };
+ zentry = new ZipEntry("test.tst");
+ zentry.setExtra(ba);
+ assertEquals("Incorrect Extra Information Returned.",
+ ba, zentry.getExtra());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#getMethod()
+ */
+ public void test_getMethod() {
+ // Test for method int java.util.zip.ZipEntry.getMethod()
+ zentry = zfile.getEntry("File1.txt");
+ assertEquals("Incorrect compression method returned",
+ java.util.zip.ZipEntry.STORED, zentry.getMethod());
+ zentry = zfile.getEntry("File3.txt");
+ assertEquals("Incorrect compression method returned",
+ java.util.zip.ZipEntry.DEFLATED, zentry.getMethod());
+ zentry = new ZipEntry("test.tst");
+ assertEquals("Incorrect Method Returned.", -1, zentry.getMethod());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#getName()
+ */
+ public void test_getName() {
+ // Test for method java.lang.String java.util.zip.ZipEntry.getName()
+ assertEquals("Incorrect name returned - Note return result somewhat ambiguous in spec",
+ "File1.txt", zentry.getName());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#getSize()
+ */
+ public void test_getSize() {
+ // Test for method long java.util.zip.ZipEntry.getSize()
+ assertEquals("Incorrect size returned", orgSize, zentry.getSize());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#getTime()
+ */
+ public void test_getTime() {
+ // Test for method long java.util.zip.ZipEntry.getTime()
+ assertEquals("Failed to get time", orgTime, zentry.getTime());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#isDirectory()
+ */
+ public void test_isDirectory() {
+ // Test for method boolean java.util.zip.ZipEntry.isDirectory()
+ assertTrue("Entry should not answer true to isDirectory", !zentry
+ .isDirectory());
+ zentry = new ZipEntry("Directory/");
+ assertTrue("Entry should answer true to isDirectory", zentry
+ .isDirectory());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#setComment(java.lang.String)
+ */
+ public void test_setCommentLjava_lang_String() {
+ // Test for method void
+ // java.util.zip.ZipEntry.setComment(java.lang.String)
+ zentry = zfile.getEntry("File1.txt");
+ zentry.setComment("Set comment using api");
+ assertEquals("Comment not correctly set",
+ "Set comment using api", zentry.getComment());
+ String n = null;
+ zentry.setComment(n);
+ assertNull("Comment not correctly set", zentry.getComment());
+ StringBuffer s = new StringBuffer();
+ for (int i = 0; i < 0xFFFF; i++) {
+ s.append('a');
+ }
+ try {
+ zentry.setComment(s.toString());
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException During Test.");
+ }
+ try {
+ s.append('a');
+ zentry.setComment(s.toString());
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * java.util.zip.ZipEntry#setCompressedSize(long)
+ */
+ public void test_setCompressedSizeJ() {
+ // Test for method void java.util.zip.ZipEntry.setCompressedSize(long)
+ zentry.setCompressedSize(orgCompressedSize + 10);
+ assertEquals("Set compressed size failed",
+ (orgCompressedSize + 10), zentry.getCompressedSize());
+ zentry.setCompressedSize(0);
+ assertEquals("Set compressed size failed",
+ 0, zentry.getCompressedSize());
+ zentry.setCompressedSize(-25);
+ assertEquals("Set compressed size failed",
+ -25, zentry.getCompressedSize());
+ zentry.setCompressedSize(4294967296l);
+ assertEquals("Set compressed size failed",
+ 4294967296l, zentry.getCompressedSize());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#setCrc(long)
+ */
+ public void test_setCrcJ() {
+ // Test for method void java.util.zip.ZipEntry.setCrc(long)
+ zentry.setCrc(orgCrc + 100);
+ assertEquals("Failed to set Crc", (orgCrc + 100), zentry.getCrc());
+ zentry.setCrc(0);
+ assertEquals("Failed to set Crc", 0, zentry.getCrc());
+ try {
+ zentry.setCrc(-25);
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ zentry.setCrc(4294967295l);
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException during test");
+ }
+ try {
+ zentry.setCrc(4294967296l);
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * java.util.zip.ZipEntry#setExtra(byte[])
+ */
+ public void test_setExtra$B() {
+ // Test for method void java.util.zip.ZipEntry.setExtra(byte [])
+ zentry = zfile.getEntry("File1.txt");
+ zentry.setExtra("Test setting extra information".getBytes());
+ assertEquals("Extra information not written properly", "Test setting extra information", new String(zentry
+ .getExtra(), 0, zentry.getExtra().length)
+ );
+ zentry = new ZipEntry("test.tst");
+ byte[] ba = new byte[0xFFFF];
+ try {
+ zentry.setExtra(ba);
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException during test");
+ }
+ try {
+ ba = new byte[0xFFFF + 1];
+ zentry.setExtra(ba);
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // One constructor
+ ZipEntry zeInput = new ZipEntry("InputZIP");
+ byte[] extraB = { 'a', 'b', 'd', 'e' };
+ zeInput.setExtra(extraB);
+ assertEquals(extraB, zeInput.getExtra());
+ assertEquals(extraB[3], zeInput.getExtra()[3]);
+ assertEquals(extraB.length, zeInput.getExtra().length);
+
+ // test another constructor
+ ZipEntry zeOutput = new ZipEntry(zeInput);
+ assertEquals(zeInput.getExtra()[3], zeOutput.getExtra()[3]);
+ assertEquals(zeInput.getExtra().length, zeOutput.getExtra().length);
+ assertEquals(extraB[3], zeOutput.getExtra()[3]);
+ assertEquals(extraB.length, zeOutput.getExtra().length);
+ }
+
+ /**
+ * java.util.zip.ZipEntry#setMethod(int)
+ */
+ public void test_setMethodI() {
+ // Test for method void java.util.zip.ZipEntry.setMethod(int)
+ zentry = zfile.getEntry("File3.txt");
+ zentry.setMethod(ZipEntry.STORED);
+ assertEquals("Failed to set compression method",
+ ZipEntry.STORED, zentry.getMethod());
+ zentry.setMethod(ZipEntry.DEFLATED);
+ assertEquals("Failed to set compression method",
+ ZipEntry.DEFLATED, zentry.getMethod());
+ try {
+ int error = 1;
+ zentry = new ZipEntry("test.tst");
+ zentry.setMethod(error);
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * java.util.zip.ZipEntry#setSize(long)
+ */
+ public void test_setSizeJ() {
+ // Test for method void java.util.zip.ZipEntry.setSize(long)
+ zentry.setSize(orgSize + 10);
+ assertEquals("Set size failed", (orgSize + 10), zentry.getSize());
+ zentry.setSize(0);
+ assertEquals("Set size failed", 0, zentry.getSize());
+ try {
+ zentry.setSize(-25);
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ zentry.setCrc(4294967295l);
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException during test");
+ }
+ try {
+ zentry.setCrc(4294967296l);
+ fail("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * java.util.zip.ZipEntry#setTime(long)
+ */
+ public void test_setTimeJ() {
+ // Test for method void java.util.zip.ZipEntry.setTime(long)
+ zentry.setTime(orgTime + 10000);
+ assertEquals("Test 1: Failed to set time: " + zentry.getTime(), (orgTime + 10000),
+ zentry.getTime());
+ zentry.setTime(orgTime - 10000);
+ assertEquals("Test 2: Failed to set time: " + zentry.getTime(), (orgTime - 10000),
+ zentry.getTime());
+ TimeZone zone = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("EST"));
+ zentry.setTime(0);
+ assertEquals("Test 3: Failed to set time: " + zentry.getTime(),
+ 315550800000L, zentry.getTime());
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ assertEquals("Test 3a: Failed to set time: " + zentry.getTime(),
+ 315532800000L, zentry.getTime());
+ zentry.setTime(0);
+ TimeZone.setDefault(TimeZone.getTimeZone("EST"));
+ assertEquals("Test 3b: Failed to set time: " + zentry.getTime(),
+ 315550800000L, zentry.getTime());
+
+ zentry.setTime(-25);
+ assertEquals("Test 4: Failed to set time: " + zentry.getTime(),
+ 315550800000L, zentry.getTime());
+ zentry.setTime(4354837200000L);
+ assertEquals("Test 5: Failed to set time: " + zentry.getTime(),
+ 315550800000L, zentry.getTime());
+ } finally {
+ TimeZone.setDefault(zone);
+ }
+ }
+
+ /**
+ * java.util.zip.ZipEntry#toString()
+ */
+ public void test_toString() {
+ // Test for method java.lang.String java.util.zip.ZipEntry.toString()
+ assertTrue("Returned incorrect entry name", zentry.toString().indexOf(
+ "File1.txt") >= 0);
+ }
+
+ /**
+ * java.util.zip.ZipEntry#ZipEntry(java.util.zip.ZipEntry)
+ */
+ public void test_ConstructorLjava_util_zip_ZipEntry() {
+ // Test for method java.util.zip.ZipEntry(util.zip.ZipEntry)
+ zentry.setSize(2);
+ zentry.setCompressedSize(4);
+ zentry.setComment("Testing");
+ ZipEntry zentry2 = new ZipEntry(zentry);
+ assertEquals("ZipEntry Created With Incorrect Size.",
+ 2, zentry2.getSize());
+ assertEquals("ZipEntry Created With Incorrect Compressed Size.", 4, zentry2
+ .getCompressedSize());
+ assertEquals("ZipEntry Created With Incorrect Comment.", "Testing", zentry2
+ .getComment());
+ assertEquals("ZipEntry Created With Incorrect Crc.",
+ orgCrc, zentry2.getCrc());
+ assertEquals("ZipEntry Created With Incorrect Time.",
+ orgTime, zentry2.getTime());
+ }
+
+ /**
+ * java.util.zip.ZipEntry#clone()
+ */
+ public void test_clone() {
+ // Test for method java.util.zip.ZipEntry.clone()
+ Object obj = zentry.clone();
+ assertEquals("toString()", zentry.toString(), obj.toString());
+ assertEquals("hashCode()", zentry.hashCode(), obj.hashCode());
+
+ // One constructor
+ ZipEntry zeInput = new ZipEntry("InputZIP");
+ byte[] extraB = { 'a', 'b', 'd', 'e' };
+ zeInput.setExtra(extraB);
+ assertEquals(extraB, zeInput.getExtra());
+ assertEquals(extraB[3], zeInput.getExtra()[3]);
+ assertEquals(extraB.length, zeInput.getExtra().length);
+
+ // test Clone()
+ ZipEntry zeOutput = (ZipEntry) zeInput.clone();
+ assertEquals(zeInput.getExtra()[3], zeOutput.getExtra()[3]);
+ assertEquals(zeInput.getExtra().length, zeOutput.getExtra().length);
+ assertEquals(extraB[3], zeOutput.getExtra()[3]);
+ assertEquals(extraB.length, zeOutput.getExtra().length);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ // Create a local copy of the file since some tests want to alter
+ // information.
+ final File f = File.createTempFile("ZipEntryTest", ".zip");
+ InputStream is = Support_Resources.getStream("hyts_ZipFile.zip");
+
+ FileOutputStream fos = new java.io.FileOutputStream(f);
+ Streams.copy(is, fos);
+ is.close();
+ fos.close();
+
+ zfile = new ZipFile(f);
+ zentry = zfile.getEntry("File1.txt");
+
+ orgSize = zentry.getSize();
+ orgCompressedSize = zentry.getCompressedSize();
+ orgCrc = zentry.getCrc();
+ orgTime = zentry.getTime();
+ }
+
+ @Override
+ protected void tearDown() {
+ try {
+ if (zfile != null) {
+ zfile.close();
+ }
+ } catch (IOException ignored) {
+ }
+ }
+}
+
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipErrorTest.java
new file mode 100644
index 0000000..6b5125a
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipErrorTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.IOException;
+import java.util.zip.ZipError;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import junit.framework.TestCase;
+
+public class ZipErrorTest extends TestCase {
+
+ /**
+ * {@link java.util.zip.ZipError#ZipError(String)}
+ */
+ public void test_constructor() {
+ ZipError error = new ZipError("ZipError");
+ assertEquals("ZipError", error.getMessage());
+ }
+
+ /**
+ * java.util.zip.ZipError#Serialization()
+ */
+ public void test_serialization() throws Exception {
+ ZipError error = new ZipError("serialization test");
+ SerializationTest.verifySelf(error);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCompatibility() throws Exception {
+ ZipError error = new ZipError("serialization test");
+ SerializationTest.verifyGolden(this, error);
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipFileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipFileTest.java
new file mode 100644
index 0000000..5b96633
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipFileTest.java
@@ -0,0 +1,421 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+import libcore.io.Streams;
+import libcore.java.lang.ref.FinalizationTester;
+import tests.support.resource.Support_Resources;
+
+public class ZipFileTest extends junit.framework.TestCase {
+
+ // the file hyts_zipFile.zip in setup must be included as a resource
+ private String tempFileName;
+ private ZipFile zfile;
+
+ /**
+ * java.util.zip.ZipFile#ZipFile(java.io.File, int)
+ */
+ public void test_ConstructorLjava_io_FileI() throws IOException {
+ zfile.close(); // about to reopen the same temp file
+
+ File file = new File(tempFileName);
+ ZipFile zip = new ZipFile(file, ZipFile.OPEN_DELETE | ZipFile.OPEN_READ);
+ zip.close();
+ assertTrue("Zip should not exist", !file.exists());
+
+ file = new File(tempFileName);
+ try {
+ zip = new ZipFile(file, ZipFile.OPEN_READ);
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+ file = new File(tempFileName);
+ try {
+ zip = new ZipFile(file, -1);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException ee) {
+ // expected
+ }
+ }
+
+ /**
+ * @throws IOException
+ * java.util.zip.ZipFile#ZipFile(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() throws IOException {
+ zfile.close(); // about to reopen the same temp file
+ ZipFile zip = new ZipFile(tempFileName);
+ zip.close();
+ File file = File.createTempFile("zip", "tmp");
+ try {
+ zip = new ZipFile(file.getAbsolutePath());
+ fail("ZipException expected");
+ } catch (ZipException ee) {
+ // expected
+ }
+ file.delete();
+ }
+
+ protected ZipEntry test_finalize1(ZipFile zip) {
+ return zip.getEntry("File1.txt");
+ }
+
+ protected ZipFile test_finalize2(File file) throws IOException {
+ return new ZipFile(file);
+ }
+
+ /**
+ * java.util.zip.ZipFile#finalize()
+ */
+ public void test_finalize() throws IOException {
+ InputStream in = Support_Resources.getStream("hyts_ZipFile.zip");
+ File file = Support_Resources.createTempFile(".jar");
+ OutputStream out = new FileOutputStream(file);
+ int result;
+ byte[] buf = new byte[4096];
+ while ((result = in.read(buf)) != -1) {
+ out.write(buf, 0, result);
+ }
+ in.close();
+ out.close();
+ /*
+ * ZipFile zip = new ZipFile(file); ZipEntry entry1 =
+ * zip.getEntry("File1.txt"); assertNotNull("Did not find entry",
+ * entry1); entry1 = null; zip = null;
+ */
+
+ assertNotNull("Did not find entry", test_finalize1(test_finalize2(file)));
+ FinalizationTester.induceFinalization();
+ file.delete();
+ assertTrue("Zip should not exist", !file.exists());
+ }
+
+ /**
+ * @throws IOException
+ * java.util.zip.ZipFile#close()
+ */
+ public void test_close() throws IOException {
+ // Test for method void java.util.zip.ZipFile.close()
+ File fl = new File(tempFileName);
+ ZipFile zf = new ZipFile(fl);
+ InputStream is1 = zf.getInputStream(zf.getEntry("File1.txt"));
+ InputStream is2 = zf.getInputStream(zf.getEntry("File2.txt"));
+
+ is1.read();
+ is2.read();
+
+ zf.close();
+
+ try {
+ is1.read();
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+
+ try {
+ is2.read();
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.zip.ZipFile#entries()
+ */
+ public void test_entries() throws Exception {
+ // Test for method java.util.Enumeration java.util.zip.ZipFile.entries()
+ Enumeration<? extends ZipEntry> enumer = zfile.entries();
+ int c = 0;
+ while (enumer.hasMoreElements()) {
+ ++c;
+ enumer.nextElement();
+ }
+ assertTrue("Incorrect number of entries returned: " + c, c == 6);
+
+ Enumeration<? extends ZipEntry> enumeration = zfile.entries();
+ zfile.close();
+ try {
+ enumeration.nextElement();
+ fail("did not detect closed file");
+ } catch (IllegalStateException expected) {
+ }
+
+ try {
+ enumeration.hasMoreElements();
+ fail("did not detect closed file");
+ } catch (IllegalStateException expected) {
+ }
+
+ try {
+ zfile.entries();
+ fail("did not detect closed file");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * java.util.zip.ZipFile#getEntry(java.lang.String)
+ */
+ public void test_getEntryLjava_lang_String() throws IOException {
+ // Test for method java.util.zip.ZipEntry
+ // java.util.zip.ZipFile.getEntry(java.lang.String)
+ java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
+ assertNotNull("Could not obtain ZipEntry", zentry);
+ int r;
+ InputStream in;
+
+ zentry = zfile.getEntry("testdir1/File1.txt");
+ assertNotNull("Could not obtain ZipEntry: testdir1/File1.txt", zentry);
+ zentry = zfile.getEntry("testdir1/");
+ assertNotNull("Could not obtain ZipEntry: testdir1/", zentry);
+ in = zfile.getInputStream(zentry);
+ assertNotNull("testdir1/ should not have null input stream", in);
+ r = in.read();
+ in.close();
+ assertEquals("testdir1/ should not contain data", -1, r);
+
+ zentry = zfile.getEntry("testdir1/testdir1");
+ assertNotNull("Could not obtain ZipEntry: testdir1/testdir1", zentry);
+ in = zfile.getInputStream(zentry);
+ byte[] buf = new byte[256];
+ r = in.read(buf);
+ in.close();
+ assertEquals("incorrect contents", "This is also text", new String(buf,
+ 0, r));
+ }
+
+ public void test_getEntryLjava_lang_String_AndroidOnly() throws IOException {
+ java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
+ assertNotNull("Could not obtain ZipEntry", zentry);
+ int r;
+ InputStream in;
+
+ zentry = zfile.getEntry("testdir1");
+ assertNotNull("Must be able to obtain ZipEntry: testdir1", zentry);
+ in = zfile.getInputStream(zentry);
+ /*
+ * Android delivers empty InputStream, RI no InputStream at all. The
+ * spec doesn't clarify this, so we need to deal with both situations.
+ */
+ int data = -1;
+ if (in != null) {
+ data = in.read();
+ in.close();
+ }
+ assertEquals("Must not be able to read directory data", -1, data);
+ }
+
+ public void test_getEntryLjava_lang_String_Ex() throws IOException {
+ java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
+ assertNotNull("Could not obtain ZipEntry", zentry);
+
+ zfile.close();
+ try {
+ zfile.getEntry("File2.txt");
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException ee) {
+ }
+ }
+
+ /**
+ * @throws IOException
+ * java.util.zip.ZipFile#getInputStream(java.util.zip.ZipEntry)
+ */
+ public void test_getInputStreamLjava_util_zip_ZipEntry() throws IOException {
+ // Test for method java.io.InputStream
+ // java.util.zip.ZipFile.getInputStream(java.util.zip.ZipEntry)
+ ZipEntry zentry = null;
+ InputStream is = null;
+ try {
+ zentry = zfile.getEntry("File1.txt");
+ is = zfile.getInputStream(zentry);
+ byte[] rbuf = new byte[1000];
+ int r;
+ is.read(rbuf, 0, r = (int) zentry.getSize());
+ assertEquals("getInputStream read incorrect data", "This is text",
+ new String(rbuf, 0, r));
+ } catch (java.io.IOException e) {
+ fail("IOException during getInputStream");
+ } finally {
+ try {
+ is.close();
+ } catch (java.io.IOException e) {
+ fail("Failed to close input stream");
+ }
+ }
+
+ zentry = zfile.getEntry("File2.txt");
+ zfile.close();
+ try {
+ is = zfile.getInputStream(zentry);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException ee) {
+ // expected
+ }
+
+ // ZipException can not be checked. Stream object returned or null.
+ }
+
+ /**
+ * java.util.zip.ZipFile#getName()
+ */
+ public void test_getName() {
+ // Test for method java.lang.String java.util.zip.ZipFile.getName()
+ assertTrue("Returned incorrect name: " + zfile.getName(), zfile
+ .getName().equals(tempFileName));
+ }
+
+ /**
+ * @throws IOException
+ * java.util.zip.ZipFile#size()
+ */
+ public void test_size() throws IOException {
+ assertEquals(6, zfile.size());
+ zfile.close();
+ try {
+ zfile.size();
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * java.io.InputStream#reset()
+ */
+ public void test_reset() throws IOException {
+ // read an uncompressed entry
+ ZipEntry zentry = zfile.getEntry("File1.txt");
+ InputStream is = zfile.getInputStream(zentry);
+ byte[] rbuf1 = new byte[6];
+ byte[] rbuf2 = new byte[6];
+ int r1, r2;
+ r1 = is.read(rbuf1);
+ assertEquals(rbuf1.length, r1);
+ r2 = is.read(rbuf2);
+ assertEquals(rbuf2.length, r2);
+
+ try {
+ is.reset();
+ fail();
+ } catch (IOException expected) {
+ }
+ is.close();
+
+ // read a compressed entry
+ byte[] rbuf3 = new byte[4185];
+ ZipEntry zentry2 = zfile.getEntry("File3.txt");
+ is = zfile.getInputStream(zentry2);
+ r1 = is.read(rbuf3);
+ assertEquals(4183, r1);
+ try {
+ is.reset();
+ fail();
+ } catch (IOException expected) {
+ }
+ is.close();
+
+ is = zfile.getInputStream(zentry2);
+ r1 = is.read(rbuf3, 0, 3000);
+ assertEquals(3000, r1);
+ try {
+ is.reset();
+ fail();
+ } catch (IOException expected) {
+ }
+ is.close();
+ }
+
+ /**
+ * java.io.InputStream#reset()
+ */
+ public void test_reset_subtest0() throws IOException {
+ // read an uncompressed entry
+ ZipEntry zentry = zfile.getEntry("File1.txt");
+ InputStream is = zfile.getInputStream(zentry);
+ byte[] rbuf1 = new byte[12];
+ byte[] rbuf2 = new byte[12];
+ int r = is.read(rbuf1, 0, 4);
+ assertEquals(4, r);
+ is.mark(0);
+ r = is.read(rbuf1);
+ assertEquals(8, r);
+ assertEquals(-1, is.read());
+
+ try {
+ is.reset();
+ fail();
+ } catch (IOException expected) {
+ }
+
+ is.close();
+
+ // read a compressed entry
+ byte[] rbuf3 = new byte[4185];
+ ZipEntry zentry2 = zfile.getEntry("File3.txt");
+ is = zfile.getInputStream(zentry2);
+ r = is.read(rbuf3, 0, 3000);
+ assertEquals(3000, r);
+ is.mark(0);
+ r = is.read(rbuf3);
+ assertEquals(1183, r);
+ assertEquals(-1, is.read());
+
+ try {
+ is.reset();
+ fail();
+ } catch (IOException expected) {
+ }
+
+ is.close();
+ }
+
+ @Override
+ protected void setUp() throws IOException {
+ // Create a local copy of the file since some tests want to alter information.
+ File tempFile = File.createTempFile("OldZipFileTest", "zip");
+ tempFileName = tempFile.getAbsolutePath();
+
+
+ InputStream is = Support_Resources.getStream("hyts_ZipFile.zip");
+ FileOutputStream fos = new FileOutputStream(tempFile);
+ Streams.copy(is, fos);
+
+ is.close();
+ fos.close();
+ zfile = new ZipFile(tempFile);
+ }
+
+ @Override
+ protected void tearDown() throws IOException {
+ if (zfile != null) {
+ zfile.close();
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java
new file mode 100644
index 0000000..adfe7e1
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
+public class ZipInputStreamTest extends TestCase {
+ // the file hyts_zipFile.zip used in setup needs to included as a resource
+ private ZipEntry zentry;
+
+ private ZipInputStream zis;
+
+ private byte[] zipBytes;
+
+ private byte[] dataBytes = "Some data in my file".getBytes();
+
+ @Override
+ protected void setUp() {
+ try {
+ InputStream is = Support_Resources.getStream("hyts_ZipFile.zip");
+ if (is == null) {
+ System.out.println("file hyts_ZipFile.zip can not be found");
+ }
+ zis = new ZipInputStream(is);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ZipOutputStream zos = new ZipOutputStream(bos);
+ ZipEntry entry = new ZipEntry("myFile");
+ zos.putNextEntry(entry);
+ zos.write(dataBytes);
+ zos.closeEntry();
+ zos.close();
+ zipBytes = bos.toByteArray();
+ } catch (Exception e) {
+ System.out.println("Exception during ZipFile setup:");
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void tearDown() {
+ if (zis != null) {
+ try {
+ zis.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ /**
+ * java.util.zip.ZipInputStream#ZipInputStream(java.io.InputStream)
+ */
+ public void test_ConstructorLjava_io_InputStream() throws Exception {
+ zentry = zis.getNextEntry();
+ zis.closeEntry();
+ }
+
+ /**
+ * java.util.zip.ZipInputStream#close()
+ */
+ public void test_close() {
+ try {
+ zis.close();
+ byte[] rbuf = new byte[10];
+ zis.read(rbuf, 0, 1);
+ } catch (IOException e) {
+ return;
+ }
+ fail("Read data after stream was closed");
+ }
+
+ /**
+ * java.util.zip.ZipInputStream#close()
+ */
+ public void test_close2() throws Exception {
+ // Regression for HARMONY-1101
+ zis.close();
+ // another call to close should NOT cause an exception
+ zis.close();
+ }
+
+ /**
+ * java.util.zip.ZipInputStream#closeEntry()
+ */
+ public void test_closeEntry() throws Exception {
+ zentry = zis.getNextEntry();
+ zis.closeEntry();
+ }
+
+ public void test_closeAfterException() throws Exception {
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
+ FileInputStream fis = new FileInputStream(new File(resources,
+ "Broken_manifest.jar"));
+
+ ZipInputStream zis1 = new ZipInputStream(fis);
+
+ try {
+ for (int i = 0; i < 6; i++) {
+ zis1.getNextEntry();
+ }
+ fail("ZipException expected");
+ } catch (ZipException ee) {
+ // expected
+ }
+
+ zis1.close();
+ try {
+ zis1.getNextEntry();
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.zip.ZipInputStream#getNextEntry()
+ */
+ public void test_getNextEntry() throws Exception {
+ assertNotNull("getNextEntry failed", zis.getNextEntry());
+ }
+
+ /**
+ * java.util.zip.ZipInputStream#read(byte[], int, int)
+ */
+ public void test_read$BII() throws Exception {
+ zentry = zis.getNextEntry();
+ byte[] rbuf = new byte[(int) zentry.getSize()];
+ int r = zis.read(rbuf, 0, rbuf.length);
+ new String(rbuf, 0, r);
+ assertEquals("Failed to read entry", 12, r);
+ }
+
+ public void testReadOneByteAtATime() throws IOException {
+ InputStream in = new FilterInputStream(Support_Resources.getStream("hyts_ZipFile.zip")) {
+ @Override
+ public int read(byte[] buffer, int offset, int count) throws IOException {
+ return super.read(buffer, offset, 1); // one byte at a time
+ }
+
+ @Override
+ public int read(byte[] buffer) throws IOException {
+ return super.read(buffer, 0, 1); // one byte at a time
+ }
+ };
+
+ zis = new ZipInputStream(in);
+ while ((zentry = zis.getNextEntry()) != null) {
+ zentry.getName();
+ }
+ zis.close();
+ }
+
+ /**
+ * java.util.zip.ZipInputStream#skip(long)
+ */
+ public void test_skipJ() throws Exception {
+ zentry = zis.getNextEntry();
+ byte[] rbuf = new byte[(int) zentry.getSize()];
+ zis.skip(2);
+ int r = zis.read(rbuf, 0, rbuf.length);
+ assertEquals("Failed to skip data", 10, r);
+
+ zentry = zis.getNextEntry();
+ zentry = zis.getNextEntry();
+ long s = zis.skip(1025);
+ assertEquals("invalid skip: " + s, 1025, s);
+
+ ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipBytes));
+ zis.getNextEntry();
+ long skipLen = dataBytes.length / 2;
+ assertEquals("Assert 0: failed valid skip", skipLen, zis.skip(skipLen));
+ zis.skip(dataBytes.length);
+ assertEquals("Assert 1: performed invalid skip", 0, zis.skip(1));
+ assertEquals("Assert 2: failed zero len skip", 0, zis.skip(0));
+ try {
+ zis.skip(-1);
+ fail("Assert 3: Expected Illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ public void test_available() throws Exception {
+
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, "hyts_ZipFile.zip");
+ File fl = new File(resources, "hyts_ZipFile.zip");
+ FileInputStream fis = new FileInputStream(fl);
+
+ ZipInputStream zis1 = new ZipInputStream(fis);
+ ZipEntry entry = zis1.getNextEntry();
+ assertNotNull("No entry in the archive.", entry);
+ long entrySize = entry.getSize();
+ assertTrue("Entry size was < 1", entrySize > 0);
+ int i = 0;
+ while (zis1.available() > 0) {
+ zis1.skip(1);
+ i++;
+ }
+ if (i != entrySize) {
+ fail("ZipInputStream.available or ZipInputStream.skip does not " +
+ "working properly. Only skipped " + i +
+ " bytes instead of " + entrySize);
+ }
+ assertEquals(0, zis1.skip(1));
+ assertEquals(0, zis1.available());
+ zis1.closeEntry();
+ assertEquals(1, zis.available());
+ zis1.close();
+ try {
+ zis1.available();
+ fail("IOException expected");
+ } catch (IOException ee) {
+ // expected
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipOutputStreamTest.java
new file mode 100644
index 0000000..7f42fa8
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipOutputStreamTest.java
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.tests.java.util.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.CRC32;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+public class ZipOutputStreamTest extends junit.framework.TestCase {
+
+ ZipOutputStream zos;
+
+ ByteArrayOutputStream bos;
+
+ ZipInputStream zis;
+
+ static final String data = "HelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorld";
+
+ /**
+ * java.util.zip.ZipOutputStream#close()
+ */
+ public void test_close() throws Exception {
+ zos = new ZipOutputStream(bos);
+ zos.putNextEntry(new ZipEntry("XX"));
+ zos.closeEntry();
+ zos.close();
+
+ // Regression for HARMONY-97
+ ZipOutputStream zos = new ZipOutputStream(new ByteArrayOutputStream());
+ zos.putNextEntry(new ZipEntry("myFile"));
+ zos.close();
+ zos.close(); // Should be a no-op
+ }
+
+ /**
+ * java.util.zip.ZipOutputStream#closeEntry()
+ */
+ public void test_closeEntry() throws IOException {
+ ZipEntry ze = new ZipEntry("testEntry");
+ ze.setTime(System.currentTimeMillis());
+ zos.putNextEntry(ze);
+ zos.write("Hello World".getBytes("UTF-8"));
+ zos.closeEntry();
+ assertTrue("closeEntry failed to update required fields",
+ ze.getSize() == 11 && ze.getCompressedSize() == 13);
+
+ }
+
+ /**
+ * java.util.zip.ZipOutputStream#finish()
+ */
+ public void test_finish() throws Exception {
+ ZipEntry ze = new ZipEntry("test");
+ zos.putNextEntry(ze);
+ zos.write("Hello World".getBytes());
+ zos.finish();
+ assertEquals("Finish failed to closeCurrentEntry", 11, ze.getSize());
+
+ ZipOutputStream zos = new ZipOutputStream(new ByteArrayOutputStream());
+ zos.putNextEntry(new ZipEntry("myFile"));
+ zos.finish();
+ zos.close();
+ try {
+ zos.finish();
+ fail("Assert 0: Expected IOException");
+ } catch (IOException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * java.util.zip.ZipOutputStream#putNextEntry(java.util.zip.ZipEntry)
+ */
+ public void test_putNextEntryLjava_util_zip_ZipEntry() throws IOException {
+ ZipEntry ze = new ZipEntry("testEntry");
+ ze.setTime(System.currentTimeMillis());
+ zos.putNextEntry(ze);
+ zos.write("Hello World".getBytes());
+ zos.closeEntry();
+ zos.close();
+ zis = new ZipInputStream(new ByteArrayInputStream(bos.toByteArray()));
+ ZipEntry ze2 = zis.getNextEntry();
+ zis.closeEntry();
+ assertEquals("Failed to write correct entry", ze.getName(), ze2.getName());
+ assertEquals("Failed to write correct entry", ze.getCrc(), ze2.getCrc());
+ try {
+ zos.putNextEntry(ze);
+ fail("Entry with incorrect setting failed to throw exception");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ /**
+ * java.util.zip.ZipOutputStream#setComment(java.lang.String)
+ */
+ public void test_setCommentLjava_lang_String() {
+ // There is no way to get the comment back, so no way to determine if
+ // the comment is set correct
+ zos.setComment("test setComment");
+
+ try {
+ zos.setComment(new String(new byte[0xFFFF + 1]));
+ fail("Comment over 0xFFFF in length should throw exception");
+ } catch (IllegalArgumentException e) {
+ // Passed
+ }
+ }
+
+ /**
+ * java.util.zip.ZipOutputStream#setLevel(int)
+ */
+ public void test_setLevelI() throws IOException {
+ ZipEntry ze = new ZipEntry("test");
+ zos.putNextEntry(ze);
+ zos.write(data.getBytes());
+ zos.closeEntry();
+ long csize = ze.getCompressedSize();
+ zos.setLevel(9); // Max Compression
+ zos.putNextEntry(ze = new ZipEntry("test2"));
+ zos.write(data.getBytes());
+ zos.closeEntry();
+ assertTrue("setLevel failed", csize <= ze.getCompressedSize());
+ }
+
+ /**
+ * java.util.zip.ZipOutputStream#setMethod(int)
+ */
+ public void test_setMethodI() throws IOException {
+ ZipEntry ze = new ZipEntry("test");
+ zos.setMethod(ZipOutputStream.STORED);
+ CRC32 tempCrc = new CRC32();
+ tempCrc.update(data.getBytes());
+ ze.setCrc(tempCrc.getValue());
+ ze.setSize(new String(data).length());
+ zos.putNextEntry(ze);
+ zos.write(data.getBytes());
+ zos.closeEntry();
+ long csize = ze.getCompressedSize();
+ zos.setMethod(ZipOutputStream.DEFLATED);
+ zos.putNextEntry(ze = new ZipEntry("test2"));
+ zos.write(data.getBytes());
+ zos.closeEntry();
+ assertTrue("setLevel failed", csize >= ze.getCompressedSize());
+ }
+
+ /**
+ * java.util.zip.ZipOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII() throws IOException {
+ ZipEntry ze = new ZipEntry("test");
+ zos.putNextEntry(ze);
+ zos.write(data.getBytes());
+ zos.closeEntry();
+ zos.close();
+ zos = null;
+ zis = new ZipInputStream(new ByteArrayInputStream(bos.toByteArray()));
+ zis.getNextEntry();
+ byte[] b = new byte[data.length()];
+ int r = 0;
+ int count = 0;
+ while (count != b.length && (r = zis.read(b, count, b.length)) != -1) {
+ count += r;
+ }
+ zis.closeEntry();
+ assertEquals("Write failed to write correct bytes", new String(b), data);
+
+ File f = File.createTempFile("testZip", "tst");
+ f.deleteOnExit();
+ FileOutputStream stream = new FileOutputStream(f);
+ ZipOutputStream zip = new ZipOutputStream(stream);
+ zip.setMethod(ZipEntry.STORED);
+
+ try {
+ zip.putNextEntry(new ZipEntry("Second"));
+ fail("Not set an entry. Should have thrown ZipException.");
+ } catch (ZipException e) {
+ // expected -- We have not set an entry
+ }
+
+ try {
+ // We try to write data without entry
+ zip.write(new byte[2]);
+ fail("Writing data without an entry. Should have thrown IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ try {
+ // Try to write without an entry and with nonsense offset and
+ // length
+ zip.write(new byte[2], 0, 12);
+ fail("Writing data without an entry. Should have thrown IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ // Regression for HARMONY-4405
+ try {
+ zip.write(null, 0, -2);
+ fail();
+ } catch (NullPointerException expected) {
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ zip.write(null, 0, 2);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ zip.write(new byte[2], 0, -2);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ // Close stream because ZIP is invalid
+ stream.close();
+ }
+
+ /**
+ * java.util.zip.ZipOutputStream#write(byte[], int, int)
+ */
+ public void test_write$BII_2() throws IOException {
+ // Regression for HARMONY-577
+ File f1 = File.createTempFile("testZip1", "tst");
+ f1.deleteOnExit();
+ FileOutputStream stream1 = new FileOutputStream(f1);
+ ZipOutputStream zip1 = new ZipOutputStream(stream1);
+ zip1.putNextEntry(new ZipEntry("one"));
+ zip1.setMethod(ZipOutputStream.STORED);
+ zip1.setMethod(ZipEntry.STORED);
+
+ zip1.write(new byte[2]);
+
+ try {
+ zip1.putNextEntry(new ZipEntry("Second"));
+ fail("ZipException expected");
+ } catch (ZipException e) {
+ // expected - We have not set an entry
+ }
+
+ try {
+ zip1.write(new byte[2]); // try to write data without entry
+ fail("expected IOE there");
+ } catch (IOException e2) {
+ // expected
+ }
+
+ zip1.close();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ zos = new ZipOutputStream(bos = new ByteArrayOutputStream());
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ if (zos != null) {
+ zos.close();
+ }
+ if (zis != null) {
+ zis.close();
+ }
+ } catch (Exception e) {
+ }
+ super.tearDown();
+ }
+}
diff --git a/luni/src/test/java/tests/api/javax/net/ServerSocketFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ServerSocketFactoryTest.java
index 34d7aed..34d7aed 100644
--- a/luni/src/test/java/tests/api/javax/net/ServerSocketFactoryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ServerSocketFactoryTest.java
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/SocketFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/SocketFactoryTest.java
new file mode 100644
index 0000000..d566ee3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/SocketFactoryTest.java
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Boris V. Kuznetsov
+* @version $Revision$
+*/
+
+package tests.api.javax.net;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
+import javax.net.SocketFactory;
+
+import junit.framework.TestCase;
+
+public class SocketFactoryTest extends TestCase {
+
+ public void test_Constructor() throws Exception {
+ new MySocketFactory();
+ }
+
+ public final void test_createSocket() throws Exception {
+ SocketFactory sf = SocketFactory.getDefault();
+
+ Socket s = sf.createSocket();
+ assertNotNull(s);
+ assertEquals(-1, s.getLocalPort());
+ assertEquals(0, s.getPort());
+
+ MySocketFactory msf = new MySocketFactory();
+ try {
+ msf.createSocket();
+ fail("No expected SocketException");
+ } catch (SocketException expected) {
+ }
+ }
+
+ public final void test_createSocket_StringI() throws Exception {
+ SocketFactory sf = SocketFactory.getDefault();
+ int sport = new ServerSocket(0).getLocalPort();
+ int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
+
+ Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport);
+ assertNotNull(s);
+ assertTrue("Failed to create socket", s.getPort() == sport);
+
+ try {
+ sf.createSocket("1.2.3.4hello", sport);
+ fail("UnknownHostException wasn't thrown");
+ } catch (UnknownHostException expected) {
+ }
+
+ for (int i = 0; i < invalidPorts.length; i++) {
+ try {
+ sf.createSocket(InetAddress.getLocalHost().getHostName(), invalidPorts[i]);
+ fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ try {
+ sf.createSocket(InetAddress.getLocalHost().getHostName(), s.getLocalPort());
+ fail("IOException wasn't thrown");
+ } catch (IOException expected) {
+ }
+
+ SocketFactory f = SocketFactory.getDefault();
+ try {
+ f.createSocket(InetAddress.getLocalHost().getHostName(), 8082);
+ fail("IOException wasn't thrown ...");
+ } catch (IOException expected) {
+ }
+ }
+
+ public final void test_createSocket_InetAddressI() throws Exception {
+ SocketFactory sf = SocketFactory.getDefault();
+ int sport = new ServerSocket(0).getLocalPort();
+ int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
+
+ Socket s = sf.createSocket(InetAddress.getLocalHost(), sport);
+ assertNotNull(s);
+ assertTrue("Failed to create socket", s.getPort() == sport);
+
+ for (int i = 0; i < invalidPorts.length; i++) {
+ try {
+ sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i]);
+ fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ try {
+ sf.createSocket(InetAddress.getLocalHost(), s.getLocalPort());
+ fail("IOException wasn't thrown");
+ } catch (IOException expected) {
+ }
+
+ SocketFactory f = SocketFactory.getDefault();
+ try {
+ f.createSocket(InetAddress.getLocalHost(), 8081);
+ fail("IOException wasn't thrown ...");
+ } catch (IOException expected) {
+ }
+ }
+
+ public final void test_createSocket_InetAddressIInetAddressI() throws Exception {
+ SocketFactory sf = SocketFactory.getDefault();
+ int sport = new ServerSocket(0).getLocalPort();
+ int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
+
+ Socket s = sf.createSocket(InetAddress.getLocalHost(), sport,
+ InetAddress.getLocalHost(), 0);
+ assertNotNull(s);
+ assertTrue("1: Failed to create socket", s.getPort() == sport);
+ int portNumber = s.getLocalPort();
+
+ for (int i = 0; i < invalidPorts.length; i++) {
+ try {
+ sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i],
+ InetAddress.getLocalHost(), portNumber);
+ fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sf.createSocket(InetAddress.getLocalHost(), sport,
+ InetAddress.getLocalHost(), invalidPorts[i]);
+ fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ try {
+ sf.createSocket(InetAddress.getLocalHost(), sport,
+ InetAddress.getLocalHost(), portNumber);
+ fail("IOException wasn't thrown");
+ } catch (IOException expected) {
+ }
+
+ SocketFactory f = SocketFactory.getDefault();
+ try {
+ f.createSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082);
+ fail("IOException wasn't thrown ...");
+ } catch (IOException expected) {
+ }
+ }
+
+ /**
+ * javax.net.SocketFactory#createSocket(String host, int port,
+ * InetAddress localHost, int localPort)
+ */
+ public final void test_createSocket_05() throws Exception {
+ SocketFactory sf = SocketFactory.getDefault();
+ int sport = new ServerSocket(0).getLocalPort();
+ int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
+
+ Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport,
+ InetAddress.getLocalHost(), 0);
+ assertNotNull(s);
+ assertTrue("1: Failed to create socket", s.getPort() == sport);
+
+ try {
+ sf.createSocket("1.2.3.4hello", sport, InetAddress.getLocalHost(), 0);
+ fail("UnknownHostException wasn't thrown");
+ } catch (UnknownHostException expected) {
+ }
+
+ for (int i = 0; i < invalidPorts.length; i++) {
+ try {
+ sf.createSocket(InetAddress.getLocalHost().getHostName(), invalidPorts[i],
+ InetAddress.getLocalHost(), 0);
+ fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ sf.createSocket(InetAddress.getLocalHost().getHostName(), sport,
+ InetAddress.getLocalHost(), invalidPorts[i]);
+ fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ try {
+ sf.createSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082);
+ fail("IOException wasn't thrown ...");
+ } catch (IOException expected) {
+ }
+ }
+
+ /**
+ * javax.net.SocketFactory#getDefault()
+ */
+ public final void test_getDefault() {
+ SocketFactory sf = SocketFactory.getDefault();
+ Socket s;
+ try {
+ s = sf.createSocket(InetAddress.getLocalHost().getHostName(), 8082);
+ s.close();
+ } catch (IOException e) {
+ }
+ try {
+ s = sf.createSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082);
+ s.close();
+ } catch (IOException e) {
+ }
+ try {
+ s = sf.createSocket(InetAddress.getLocalHost(), 8081);
+ s.close();
+ } catch (IOException e) {
+ }
+ try {
+ s = sf.createSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082);
+ s.close();
+ } catch (IOException e) {
+ }
+ }
+}
+
+class MySocketFactory extends SocketFactory {
+
+ public MySocketFactory() {
+ super();
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
+ return null;
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
+ throws IOException, UnknownHostException {
+ return null;
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException {
+ return null;
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port,
+ InetAddress localAddress, int localPort) throws IOException {
+ return null;
+ }
+
+}
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/CertPathTrustManagerParametersTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/CertPathTrustManagerParametersTest.java
index 41407e8..41407e8 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/CertPathTrustManagerParametersTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/CertPathTrustManagerParametersTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/CertificatesToPlayWith.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/CertificatesToPlayWith.java
index 5bb6f06..5bb6f06 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/CertificatesToPlayWith.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/CertificatesToPlayWith.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
index c075cea..c075cea 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/HostnameVerifierTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HostnameVerifierTest.java
index 839f3b5..839f3b5 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/HostnameVerifierTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HostnameVerifierTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/HttpsURLConnectionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HttpsURLConnectionTest.java
index e2ebdbd..e2ebdbd 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/HttpsURLConnectionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HttpsURLConnectionTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactory1Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactory1Test.java
index b369ed9..b369ed9 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactory1Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactory1Test.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactory2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactory2Test.java
index 3d44396..3d44396 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactory2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactory2Test.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactorySpiTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactorySpiTest.java
index fd44fda..fd44fda 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/KeyManagerFactorySpiTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyManagerFactorySpiTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyStoreBuilderParametersTest.java
index a2fe49c..a2fe49c 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/KeyStoreBuilderParametersTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLContext1Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContext1Test.java
index ee51cc0..ee51cc0 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLContext1Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContext1Test.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLContext2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContext2Test.java
index 0881615..0881615 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLContext2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContext2Test.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLContextSpiTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContextSpiTest.java
index 45a1c14..45a1c14 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLContextSpiTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLContextSpiTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultHandshakeStatusTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultHandshakeStatusTest.java
index 3b13673..3b13673 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultHandshakeStatusTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultHandshakeStatusTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultStatusTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultStatusTest.java
index 05c8f03..05c8f03 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultStatusTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultStatusTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultTest.java
index 7a2ac78..7a2ac78 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineResultTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineResultTest.java
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java
new file mode 100644
index 0000000..31f5881
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java
@@ -0,0 +1,1210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.javax.net.ssl;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.nio.channels.Pipe;
+import java.nio.channels.Pipe.SinkChannel;
+import java.nio.channels.Pipe.SourceChannel;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import junit.framework.TestCase;
+import libcore.java.security.StandardNames;
+
+/**
+ * Tests for SSLEngine class
+ *
+ */
+public class SSLEngineTest extends TestCase {
+ private static final int MAX_TLS_RECORD_SIZE = 32768;
+
+ private HandshakeHandler clientEngine;
+ private HandshakeHandler serverEngine;
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ /**
+ * Test for <code>SSLEngine()</code> constructor Assertion: creates
+ * SSLEngine object with null host and -1 port
+ */
+ public void test_Constructor() throws Exception {
+ SSLEngine e = getEngine();
+ assertNull(e.getPeerHost());
+ assertEquals(-1, e.getPeerPort());
+ String[] suites = e.getSupportedCipherSuites();
+ e.setEnabledCipherSuites(suites);
+ assertEquals(e.getEnabledCipherSuites().length, suites.length);
+ }
+
+ /**
+ * Test for <code>SSLEngine(String host, int port)</code> constructor
+ */
+ public void test_ConstructorLjava_lang_StringI01() throws Exception {
+ int port = 1010;
+ SSLEngine e = getEngine(null, port);
+ assertNull(e.getPeerHost());
+ assertEquals(e.getPeerPort(), port);
+ try {
+ e.beginHandshake();
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+
+ e = getEngine(null, port);
+ e.setUseClientMode(true);
+ e.beginHandshake();
+
+ e = getEngine(null, port);
+ e.setUseClientMode(false);
+ e.beginHandshake();
+ }
+
+ /**
+ * Test for <code>SSLEngine(String host, int port)</code> constructor
+ */
+ public void test_ConstructorLjava_lang_StringI02() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ SSLEngine e = getEngine(host, port);
+ assertEquals(e.getPeerHost(), host);
+ assertEquals(e.getPeerPort(), port);
+ String[] suites = e.getSupportedCipherSuites();
+ e.setEnabledCipherSuites(suites);
+ assertEquals(e.getEnabledCipherSuites().length, suites.length);
+ e.setUseClientMode(true);
+ assertTrue(e.getUseClientMode());
+ }
+
+ /**
+ * Test for <code>getPeerHost()</code> method
+ */
+ public void test_getPeerHost() throws Exception {
+ SSLEngine e = getEngine();
+ assertNull(e.getPeerHost());
+ e = getEngine("www.fortify.net", 80);
+ assertEquals("Incorrect host name", "www.fortify.net", e.getPeerHost());
+ }
+
+ /**
+ * Test for <code>getPeerPort()</code> method
+ */
+ public void test_getPeerPort() throws Exception {
+ SSLEngine e = getEngine();
+ assertEquals("Incorrect default value of peer port",
+ -1 ,e.getPeerPort());
+ e = getEngine("www.fortify.net", 80);
+ assertEquals("Incorrect peer port", 80, e.getPeerPort());
+ }
+
+ public void test_getSupportedProtocols() throws Exception {
+ SSLEngine sse = getEngine();
+
+ String[] res = sse.getSupportedProtocols();
+ assertNotNull(res);
+ assertTrue(res.length > 0);
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#setEnabledProtocols(String[] protocols)
+ * javax.net.ssl.SSLEngine#getEnabledProtocols()
+ */
+ public void test_EnabledProtocols() throws Exception {
+ SSLEngine sse = getEngine();
+ String[] pr = sse.getSupportedProtocols();
+
+ sse.setEnabledProtocols(pr);
+ String[] res = sse.getEnabledProtocols();
+ assertNotNull("Null array was returned", res);
+ assertEquals("Incorrect array length", res.length, pr.length);
+ assertTrue("Incorrect array was returned", Arrays.equals(res, pr));
+
+ try {
+ sse.setEnabledProtocols(null);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#getSupportedCipherSuites()
+ */
+ public void test_getSupportedCipherSuites() throws Exception {
+ SSLEngine sse = getEngine();
+
+ String[] res = sse.getSupportedCipherSuites();
+ assertNotNull(res);
+ assertTrue(res.length > 0);
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#setEnabledCipherSuites(String[] suites)
+ * javax.net.ssl.SSLEngine#getEnabledCipherSuites()
+ */
+ public void test_EnabledCipherSuites() throws Exception {
+ SSLEngine sse = getEngine();
+ String[] st = sse.getSupportedCipherSuites();
+
+ sse.setEnabledCipherSuites(st);
+ String[] res = sse.getEnabledCipherSuites();
+ assertNotNull("Null array was returned", res);
+ assertEquals("Incorrect array length", res.length, st.length);
+ assertTrue("Incorrect array was returned", Arrays.equals(res, st));
+
+ try {
+ sse.setEnabledCipherSuites(null);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#setEnableSessionCreation(boolean flag)
+ * javax.net.ssl.SSLEngine#getEnableSessionCreation()
+ */
+ public void test_EnableSessionCreation() throws Exception {
+ SSLEngine sse = getEngine();
+ try {
+ assertTrue(sse.getEnableSessionCreation());
+ sse.setEnableSessionCreation(false);
+ assertFalse(sse.getEnableSessionCreation());
+ sse.setEnableSessionCreation(true);
+ assertTrue(sse.getEnableSessionCreation());
+ } catch (Exception ex) {
+ fail("Unexpected exception " + ex);
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#setNeedClientAuth(boolean need)
+ * javax.net.ssl.SSLEngine#getNeedClientAuth()
+ */
+ public void test_NeedClientAuth() throws Exception {
+ SSLEngine sse = getEngine();
+ try {
+ sse.setNeedClientAuth(false);
+ assertFalse(sse.getNeedClientAuth());
+ sse.setNeedClientAuth(true);
+ assertTrue(sse.getNeedClientAuth());
+ } catch (Exception ex) {
+ fail("Unexpected exception " + ex);
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#setWantClientAuth(boolean want)
+ * javax.net.ssl.SSLEngine#getWantClientAuth()
+ */
+ public void test_WantClientAuth() throws Exception {
+ SSLEngine sse = getEngine();
+ sse.setWantClientAuth(false);
+ assertFalse(sse.getWantClientAuth());
+ sse.setWantClientAuth(true);
+ assertTrue(sse.getWantClientAuth());
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#beginHandshake()
+ */
+ public void test_beginHandshake() throws Exception {
+ SSLEngine sse = getEngine();
+ try {
+ sse.beginHandshake();
+ fail("IllegalStateException wasn't thrown");
+ } catch (IllegalStateException expected) {
+ }
+ sse = getEngine("new host", 1080);
+ try {
+ sse.beginHandshake();
+ fail("IllegalStateException wasn't thrown");
+ } catch (IllegalStateException expected) {
+ }
+ sse = getEngine();
+ sse.setUseClientMode(true);
+ sse.beginHandshake();
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#setUseClientMode(boolean mode)
+ * javax.net.ssl.SSLEngine#getUseClientMode()
+ */
+ public void test_UseClientMode() throws Exception {
+ SSLEngine sse = getEngine();
+ sse.setUseClientMode(false);
+ assertFalse(sse.getUseClientMode());
+ sse.setUseClientMode(true);
+ assertTrue(sse.getUseClientMode());
+
+ sse = getEngine(null, 1080);
+ sse.setUseClientMode(true);
+ sse.beginHandshake();
+ try {
+ sse.setUseClientMode(false);
+ fail("IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#getSession()
+ */
+ public void test_getSession() throws Exception {
+ SSLEngine sse = getEngine();
+ assertNotNull(sse.getSession());
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#getHandshakeStatus()
+ */
+ public void test_getHandshakeStatus() throws Exception {
+ SSLEngine sse = getEngine();
+ assertEquals(sse.getHandshakeStatus().toString(), "NOT_HANDSHAKING");
+ sse.setUseClientMode(true);
+ sse.beginHandshake();
+ assertEquals(sse.getHandshakeStatus().toString(), "NEED_WRAP");
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#getDelegatedTask()
+ */
+ public void test_getDelegatedTask() throws Exception {
+ SSLEngine sse = getEngine();
+ assertNull(sse.getDelegatedTask());
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
+ * int offset, int length)
+ * Exception case: SSLException should be thrown.
+ */
+ public void test_unwrap_01() throws Exception {
+ prepareEngines();
+ doHandshake();
+
+ ByteBuffer bbs = ByteBuffer.wrap(new byte[] {1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,31,2,3,1,2,3,1,2,3,1,2,3});
+ ByteBuffer bbd = ByteBuffer.allocate(100);
+ try {
+ clientEngine.engine.unwrap(bbs, new ByteBuffer[] { bbd }, 0, 1);
+ fail("SSLException wasn't thrown");
+ } catch (SSLException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
+ * int offset, int length)
+ * Exception case: IndexOutOfBoundsException should be thrown.
+ */
+ public void test_unwrap_02() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
+
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.unwrap(bb, bbA, -1, 3);
+ fail("IndexOutOfBoundsException wasn't thrown");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ sse.unwrap(bb, bbA, 0, -3);
+ fail("IndexOutOfBoundsException wasn't thrown");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ sse.unwrap(bb, bbA, bbA.length + 1, bbA.length);
+ fail("IndexOutOfBoundsException wasn't thrown");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ sse.unwrap(bb, bbA, 0, bbA.length + 1);
+ fail("IndexOutOfBoundsException wasn't thrown");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
+ * int offset, int length)
+ * Exception case: ReadOnlyBufferException should be thrown.
+ */
+ public void test_unwrap_03() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbR = ByteBuffer.allocate(100).asReadOnlyBuffer();
+ ByteBuffer[] bbA = { bbR, ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
+
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.unwrap(bb, bbA, 0, bbA.length);
+ fail("ReadOnlyBufferException wasn't thrown");
+ } catch (ReadOnlyBufferException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
+ * int offset, int length)
+ * Exception case: IllegalArgumentException should be thrown.
+ */
+ public void test_unwrap_04() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer[] bbA = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100)};
+ ByteBuffer[] bbAN = {ByteBuffer.allocate(100), null, ByteBuffer.allocate(100)};
+ ByteBuffer[] bbN = null;
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ ByteBuffer bN = null;
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.unwrap(bN, bbA, 0, 3);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ sse.unwrap(bb, bbAN, 0, 3);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ sse.unwrap(bb, bbN, 0, 0);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ sse.unwrap(bN, bbN, 0, 0);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
+ * int offset, int length)
+ * Exception case: IllegalStateException should be thrown.
+ */
+ public void test_unwrap_05() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
+
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ SSLEngine sse = getEngine(host, port);
+
+ try {
+ SSLEngineResult result = sse.unwrap(bb, bbA, 0, bbA.length);
+ fail("IllegalStateException wasn't thrown");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
+ * int offset, int length)
+ */
+ public void test_unwrap_06() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
+
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ SSLEngineResult res = sse.unwrap(bb, bbA, 0, bbA.length);
+ assertEquals(0, res.bytesConsumed());
+ assertEquals(0, res.bytesProduced());
+ }
+
+ public void test_wrap_01() throws Exception {
+ prepareEngines();
+ doHandshake();
+ ByteBuffer bbs = ByteBuffer.allocate(100);
+ ByteBuffer bbd = ByteBuffer.allocate(MAX_TLS_RECORD_SIZE);
+ clientEngine.engine.wrap(new ByteBuffer[] { bbs }, 0, 1, bbd);
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
+ * int length, ByteBuffer dst)
+ * Exception case: IndexOutOfBoundsException should be thrown.
+ */
+ public void test_wrap_02() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.wrap(bbA, -1, 3, bb);
+ fail("IndexOutOfBoundsException wasn't thrown");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ sse.wrap(bbA, 0, -3, bb);
+ fail("IndexOutOfBoundsException wasn't thrown");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ sse.wrap(bbA, bbA.length + 1, bbA.length, bb);
+ fail("IndexOutOfBoundsException wasn't thrown");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ sse.wrap(bbA, 0, bbA.length + 1, bb);
+ fail("IndexOutOfBoundsException wasn't thrown");
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
+ * int length, ByteBuffer dst)
+ * Exception case: ReadOnlyBufferException should be thrown.
+ */
+ public void test_wrap_03() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bb = ByteBuffer.allocate(MAX_TLS_RECORD_SIZE).asReadOnlyBuffer();
+ ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.wrap(bbA, 0, bbA.length, bb);
+ fail("ReadOnlyBufferException wasn't thrown");
+ } catch (ReadOnlyBufferException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
+ * int length, ByteBuffer dst)
+ * Exception case: IllegalArgumentException should be thrown.
+ */
+ public void test_wrap_04() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer[] bbA = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100)};
+ ByteBuffer[] bbN = null;
+ ByteBuffer bN = null;
+ SSLEngine e = getEngine(host, port);
+ e.setUseClientMode(true);
+
+ try {
+ e.wrap(bbA, 0, 3, bN);
+ fail("IllegalArgumentException must be thrown for null srcs byte buffer array");
+ } catch (IllegalArgumentException ex) {
+ }
+
+ try {
+ e.wrap(bbN, 0, 0, bN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException ex) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
+ * int length, ByteBuffer dst)
+ * Exception case: IllegalStateException should be thrown.
+ */
+ public void test_wrap_05() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bb = ByteBuffer.allocate(MAX_TLS_RECORD_SIZE);
+ ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
+ SSLEngine sse = getEngine(host, port);
+
+ try {
+ SSLEngineResult result = sse.wrap(bbA, 0, bbA.length, bb);
+ fail("Should fail since mode not set yet");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
+ * int length, ByteBuffer dst)
+ */
+ public void test_wrap_06() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bb = ByteBuffer.allocate(MAX_TLS_RECORD_SIZE);
+ ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ SSLEngineResult result = sse.wrap(bbA, 0, bbA.length, bb);
+ assertEquals(SSLEngineResult.Status.OK, result.getStatus());
+ assertEquals(0, result.bytesConsumed());
+ assertTrue(result.bytesProduced() > 0);
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#closeOutbound()
+ * javax.net.ssl.SSLEngine#isOutboundDone()
+ */
+ public void test_closeOutbound() throws Exception {
+ SSLEngine sse = getEngine();
+
+ assertFalse(sse.isOutboundDone());
+ sse.closeOutbound();
+ assertTrue(sse.isOutboundDone());
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#closeInbound()
+ * javax.net.ssl.SSLEngine#isInboundDone()
+ */
+ public void test_closeInbound() throws Exception {
+ SSLEngine sse = getEngine();
+
+ assertFalse(sse.isInboundDone());
+ sse.closeInbound();
+ assertTrue(sse.isInboundDone());
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
+ * SSLException should be thrown.
+ */
+ public void test_unwrap_ByteBuffer_ByteBuffer_01() throws Exception {
+ prepareEngines();
+ doHandshake();
+ ByteBuffer bbs = ByteBuffer.allocate(100);
+ ByteBuffer bbd = ByteBuffer.allocate(100);
+
+ try {
+ SSLEngineResult unwrap = clientEngine.engine.unwrap(bbs, bbd);
+ fail("SSLException wasn't thrown");
+ } catch (SSLException ex) {
+ //expected
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
+ * ReadOnlyBufferException should be thrown.
+ */
+ public void test_unwrap_ByteBuffer_ByteBuffer_02() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer bbd = ByteBuffer.allocate(100).asReadOnlyBuffer();
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.unwrap(bbs, bbd);
+ fail("ReadOnlyBufferException wasn't thrown");
+ } catch (ReadOnlyBufferException iobe) {
+ //expected
+ } catch (Exception e) {
+ fail(e + " was thrown instead of ReadOnlyBufferException");
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
+ * IllegalArgumentException should be thrown.
+ */
+ public void test_unwrap_ByteBuffer_ByteBuffer_03() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbsN = null;
+ ByteBuffer bbdN = null;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer bbd = ByteBuffer.allocate(100);
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.unwrap(bbsN, bbd);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.unwrap(bbs, bbdN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.unwrap(bbsN, bbdN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
+ * IllegalStateException should be thrown.
+ */
+ public void test_unwrap_ByteBuffer_ByteBuffer_04() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer bbd = ByteBuffer.allocate(100);
+ SSLEngine sse = getEngine(host, port);
+
+ try {
+ sse.unwrap(bbs, bbd);
+ fail("IllegalStateException wasn't thrown");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
+ */
+ public void test_unwrap_ByteBuffer_ByteBuffer_05() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer bbd = ByteBuffer.allocate(100);
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ SSLEngineResult res = sse.unwrap(bbs, bbd);
+ assertEquals(0, res.bytesConsumed());
+ assertEquals(0, res.bytesProduced());
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
+ * SSLException should be thrown.
+ */
+ public void test_unwrap_ByteBuffer$ByteBuffer_01() throws Exception {
+ prepareEngines();
+ doHandshake();
+
+ ByteBuffer bbs = ByteBuffer.allocate(100);
+ ByteBuffer bbd = ByteBuffer.allocate(100);
+
+ try {
+ clientEngine.engine.unwrap(bbs, new ByteBuffer[] { bbd });
+ fail("SSLException wasn't thrown");
+ } catch (SSLException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
+ * ReadOnlyBufferException should be thrown.
+ */
+ public void test_unwrap_ByteBuffer$ByteBuffer_02() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer bbR = ByteBuffer.allocate(100).asReadOnlyBuffer();
+ ByteBuffer[] bbA = { bbR, ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.unwrap(bbs, bbA);
+ fail("ReadOnlyBufferException wasn't thrown");
+ } catch (ReadOnlyBufferException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
+ * IllegalArgumentException should be thrown.
+ */
+ public void test_unwrap_ByteBuffer$ByteBuffer_03() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
+ ByteBuffer[] bbN = { ByteBuffer.allocate(100), null, ByteBuffer.allocate(100) };
+ ByteBuffer[] bbAN = null;
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ ByteBuffer bN = null;
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.unwrap(bN, bbA);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.unwrap(bb, bbAN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.unwrap(bb, bbN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.unwrap(bN, bbAN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
+ * IllegalStateException should be thrown.
+ */
+ public void test_unwrap_ByteBuffer$ByteBuffer_04() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer[] bbd = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
+ SSLEngine sse = getEngine(host, port);
+
+ try {
+ sse.unwrap(bbs, bbd);
+ fail("IllegalStateException wasn't thrown");
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
+ */
+ public void test_unwrap_ByteBuffer$ByteBuffer_05() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer[] bbd = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ SSLEngineResult res = sse.unwrap(bbs, bbd);
+ assertEquals(0, res.bytesConsumed());
+ assertEquals(0, res.bytesProduced());
+ }
+
+ public void test_wrap_ByteBuffer_ByteBuffer_01() throws Exception {
+ prepareEngines();
+ doHandshake();
+ ByteBuffer bbs = ByteBuffer.allocate(20);
+ ByteBuffer bbd = ByteBuffer.allocate(20000);
+ clientEngine.engine.wrap(bbs, bbd);
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer src, ByteBuffer dst)
+ * ReadOnlyBufferException should be thrown.
+ */
+ public void test_wrap_ByteBuffer_ByteBuffer_02() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer bbd = ByteBuffer.allocate(100).asReadOnlyBuffer();
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.wrap(bbs, bbd);
+ fail("ReadOnlyBufferException wasn't thrown");
+ } catch (ReadOnlyBufferException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer src, ByteBuffer dst)
+ * IllegalArgumentException should be thrown.
+ */
+ public void test_wrap_ByteBuffer_ByteBuffer_03() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbsN = null;
+ ByteBuffer bbdN = null;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer bbd = ByteBuffer.allocate(100);
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.wrap(bbsN, bbd);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.wrap(bbs, bbdN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.wrap(bbsN, bbdN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer src, ByteBuffer dst)
+ * IllegalStateException should be thrown.
+ */
+ public void test_wrap_ByteBuffer_ByteBuffer_04() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bbs = ByteBuffer.allocate(10);
+ ByteBuffer bbd = ByteBuffer.allocate(10);
+ SSLEngine sse = getEngine(host, port);
+
+ try {
+ SSLEngineResult result = sse.wrap(bbs, bbd);
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer src, ByteBuffer dst)
+ */
+ public void test_wrap_ByteBuffer_ByteBuffer_05() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ SSLEngineResult res = sse.wrap(bb, ByteBuffer.allocate(10));
+ assertEquals(Status.BUFFER_OVERFLOW, res.getStatus());
+ assertEquals(0, res.bytesConsumed());
+ assertEquals(0, res.bytesProduced());
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
+ * SSLException should be thrown.
+ */
+ public void test_wrap_ByteBuffer$ByteBuffer_01() throws Exception {
+ prepareEngines();
+ doHandshake();
+ ByteBuffer bbs = ByteBuffer.allocate(100);
+ ByteBuffer bbd = ByteBuffer.allocate(20000);
+
+ clientEngine.engine.wrap(new ByteBuffer[] { bbs }, bbd);
+ serverEngine.engine.wrap(new ByteBuffer[] { bbs }, bbd);
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
+ * ReadOnlyBufferException should be thrown.
+ */
+ public void test_wrap_ByteBuffer$ByteBuffer_02() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bb = ByteBuffer.allocate(10).asReadOnlyBuffer();
+ ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.wrap(bbA, bb);
+ fail("ReadOnlyBufferException wasn't thrown");
+ } catch (ReadOnlyBufferException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
+ * IllegalArgumentException should be thrown.
+ */
+ public void test_wrap_ByteBuffer$ByteBuffer_03() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer[] bbA = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100)};
+ ByteBuffer[] bbAN = null;
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ ByteBuffer bN = null;
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ try {
+ sse.wrap(bbA, bN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.wrap(bbAN, bb);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ sse.wrap(bbAN, bN);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
+ * IllegalStateException should be thrown.
+ */
+ public void test_wrap_ByteBuffer$ByteBuffer_04() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bb = ByteBuffer.allocate(10);
+ ByteBuffer[] bbA = { ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5) };
+ SSLEngine sse = getEngine(host, port);
+
+ SSLEngineResult result = sse.wrap(bbA, bb);
+ assertEquals(Status.BUFFER_OVERFLOW, result.getStatus());
+ }
+
+ /**
+ * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
+ */
+ public void test_wrap_ByteBuffer$ByteBuffer_05() throws Exception {
+ String host = "new host";
+ int port = 8080;
+ ByteBuffer bb = ByteBuffer.allocate(2000);
+ ByteBuffer[] bbA = { ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5) };
+ SSLEngine sse = getEngine(host, port);
+ sse.setUseClientMode(true);
+
+ SSLEngineResult res = sse.wrap(bbA, bb);
+ assertEquals(0, res.bytesConsumed());
+ assertEquals(0, res.bytesProduced());
+ }
+
+ private SSLEngine getEngine() throws Exception {
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, null, null);
+ return context.createSSLEngine();
+ }
+
+ private SSLEngine getEngine(String host, int port) throws Exception {
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, null, null);
+ return context.createSSLEngine(host, port);
+ }
+
+ class HandshakeHandler implements Runnable {
+
+ private final SSLEngine engine;
+
+ private final SourceChannel in;
+
+ private final SinkChannel out;
+
+ private final ByteBuffer EMPTY = ByteBuffer.allocate(0);
+
+ @SuppressWarnings("unused")
+ private final String LOGTAG;
+
+ private SSLEngineResult.HandshakeStatus status;
+
+ private ByteBuffer readBuffer;
+
+ private ByteBuffer writeBuffer;
+
+ HandshakeHandler(boolean clientMode, SourceChannel in, SinkChannel out) throws Exception {
+ this.in = in;
+ this.out = out;
+ engine = getEngine();
+ engine.setUseClientMode(clientMode);
+ String[] cipherSuites = engine.getSupportedCipherSuites();
+ Set<String> enabledSuites = new HashSet<String>();
+ for (String cipherSuite : cipherSuites) {
+ if (cipherSuite.contains("anon")) {
+ enabledSuites.add(cipherSuite);
+ }
+ }
+ engine.setEnabledCipherSuites((String[]) enabledSuites.toArray(
+ new String[enabledSuites.size()]));
+
+ engine.beginHandshake();
+ status = engine.getHandshakeStatus();
+
+ if (clientMode) {
+ LOGTAG = "CLIENT: ";
+ } else {
+ LOGTAG = "SERVER: ";
+ }
+
+ log("CipherSuites: " + Arrays.toString(engine.getEnabledCipherSuites()));
+ log(status);
+
+ readBuffer = ByteBuffer.allocate(200000);
+ writeBuffer = ByteBuffer.allocate(20000);
+ }
+
+ public SSLEngineResult.HandshakeStatus getStatus() {
+ return status;
+ }
+
+ private void log(Object o) {
+ //System.out.print(LOGTAG);
+ //System.out.println(o);
+ }
+
+ private ByteBuffer read() throws IOException {
+ if (readBuffer == null || readBuffer.remaining() == 0 || readBuffer.position() == 0) {
+ readBuffer.clear();
+ int read = in.read(readBuffer);
+ log("read: " + read);
+ readBuffer.rewind();
+ readBuffer.limit(read);
+ }
+ return readBuffer;
+ }
+
+ public void run() {
+ try {
+ while (true) {
+ switch (status) {
+ case FINISHED: {
+ log(status);
+ return;
+ }
+ case NEED_TASK: {
+ log(status);
+ Runnable task;
+ while ((task = engine.getDelegatedTask()) != null) {
+ task.run();
+ }
+ status = engine.getHandshakeStatus();
+ break;
+ }
+ case NEED_UNWRAP: {
+ log(status);
+ ByteBuffer source = read();
+ writeBuffer.clear();
+
+ while (status == HandshakeStatus.NEED_UNWRAP) {
+ SSLEngineResult result = engine.unwrap(source, writeBuffer);
+ status = result.getHandshakeStatus();
+ log(result);
+ }
+ break;
+ }
+ case NEED_WRAP: {
+ log(status);
+ writeBuffer.clear();
+
+ int produced = 0;
+ SSLEngineResult result = null;
+ while (status == HandshakeStatus.NEED_WRAP) {
+ result = engine.wrap(EMPTY, writeBuffer);
+ status = result.getHandshakeStatus();
+ produced += result.bytesProduced();
+ log(result);
+ }
+ writeBuffer.rewind();
+ writeBuffer.limit(produced);
+ log("write: " + produced);
+ out.write(writeBuffer);
+ break;
+ }
+ case NOT_HANDSHAKING: {
+ log("Not Handshaking");
+ return;
+ }
+ }
+ }
+ } catch (IOException e) {
+ log(e);
+ } catch (RuntimeException e) {
+ // ignore;
+ }
+ }
+ }
+
+ public void testHandshake() throws Exception {
+
+ prepareEngines();
+
+ assertTrue("handshake failed", doHandshake());
+
+ System.out.println(clientEngine.engine.getSession().getCipherSuite());
+
+ assertEquals("Handshake not finished",
+ SSLEngineResult.HandshakeStatus.FINISHED,
+ clientEngine.getStatus());
+ assertEquals("Handshake not finished",
+ SSLEngineResult.HandshakeStatus.FINISHED,
+ serverEngine.getStatus());
+ }
+
+ void prepareEngines() throws Exception {
+ Pipe clientSendPipe = Pipe.open();
+ Pipe serverSendPipe = Pipe.open();
+
+ SinkChannel clientSink = clientSendPipe.sink();
+ SourceChannel serverSource = clientSendPipe.source();
+ SinkChannel serverSink = serverSendPipe.sink();
+ SourceChannel clientSource = serverSendPipe.source();
+
+ clientEngine = new HandshakeHandler(true, clientSource, clientSink);
+ serverEngine = new HandshakeHandler(false, serverSource, serverSink);
+ }
+
+ boolean doHandshake() throws InterruptedException {
+ Thread clientThread = new Thread(clientEngine);
+ clientThread.start();
+
+ Thread serverThread = new Thread(serverEngine);
+ serverThread.start();
+
+ int i = 0;
+ while (clientThread.isAlive() && serverThread.isAlive() && i < 20) {
+ Thread.sleep(500);
+ i++;
+ }
+
+ if (clientThread.isAlive()) {
+ clientThread.interrupt();
+ }
+
+ if (serverThread.isAlive()) {
+ serverThread.interrupt();
+ }
+
+ return clientEngine.getStatus() == HandshakeStatus.FINISHED && serverEngine.getStatus() == HandshakeStatus.FINISHED;
+ }
+
+}
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLExceptionTest.java
index 9b4ae35..9b4ae35 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLHandshakeExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLHandshakeExceptionTest.java
index a2d0ec5..a2d0ec5 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLHandshakeExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLHandshakeExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLKeyExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLKeyExceptionTest.java
index d6ba998..d6ba998 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLKeyExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLKeyExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java
index a8b9ac4..a8b9ac4 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLProtocolExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLProtocolExceptionTest.java
index 14b562d..14b562d 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLProtocolExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLProtocolExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketFactoryTest.java
index 5958ecb..5958ecb 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketFactoryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketFactoryTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
index 5086f65..5086f65 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionBindingEventTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionBindingEventTest.java
index dfccf68..dfccf68 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionBindingEventTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionBindingEventTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionBindingListenerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionBindingListenerTest.java
index a006a83..a006a83 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionBindingListenerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionBindingListenerTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionContextTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionContextTest.java
index aa95eb8..aa95eb8 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionContextTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionContextTest.java
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java
new file mode 100644
index 0000000..2ba913d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java
@@ -0,0 +1,655 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.javax.net.ssl;
+
+import libcore.java.security.StandardNames;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionBindingEvent;
+import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+import junit.framework.TestCase;
+import libcore.io.Base64;
+import tests.api.javax.net.ssl.HandshakeCompletedEventTest.MyHandshakeListener;
+import tests.api.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager;
+
+public class SSLSessionTest extends TestCase {
+
+ // set to true if on Android, false if on RI
+ boolean useBKS = true;
+
+ /**
+ * javax.net.ssl.SSLSession#getPeerHost()
+ * javax.net.ssl.SSLSession#getPeerPort()
+ */
+ public void test_getPeerHost() throws Exception {
+ SSLSession s = clientSession;
+ assertEquals(InetAddress.getLocalHost().getHostName(), s.getPeerHost());
+ assertEquals(serverSocket.getLocalPort(), s.getPeerPort());
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#invalidate()
+ * javax.net.ssl.SSLSession#isValid()
+ */
+ public void test_invalidate() {
+ SSLSession s = clientSession;
+ assertTrue(s.isValid());
+ s.invalidate();
+ assertFalse(s.isValid());
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getPeerPrincipal()
+ */
+ public void test_getPeerPrincipal() throws Exception {
+ Principal p1 = clientSession.getPeerPrincipal();
+ KeyStore store = server.getStore();
+ X509Certificate cert = (X509Certificate)store.getCertificate("mykey");
+ Principal p2 = cert.getSubjectX500Principal();
+ assertEquals(p1, p2);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getApplicationBufferSize()
+ */
+ public void test_getApplicationBufferSize() {
+ assertTrue(clientSession.getApplicationBufferSize() > 0);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getCipherSuite()
+ */
+ public void test_getCipherSuite() {
+ // Identify the expected cipher suite from the expected list of cipher suites enabled by
+ // default.
+ // This test class initializes the server with an RSA key. Thus, only cipher suites that
+ // authenticate the server using RSA are expected to be used.
+ String expectedCipherSuite = null;
+ for (String cipherSuite : StandardNames.CIPHER_SUITES_DEFAULT) {
+ if (cipherSuite.contains("_RSA_")) {
+ expectedCipherSuite = cipherSuite;
+ break;
+ }
+ }
+ if (expectedCipherSuite == null) {
+ fail("Failed to identify expected cipher suite");
+ }
+ assertEquals(expectedCipherSuite, clientSession.getCipherSuite());
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getCreationTime()
+ */
+ public void test_getCreationTime() {
+ // check if creation time was in the last 10 seconds
+ long currentTime = System.currentTimeMillis();
+ long sessionTime = clientSession.getCreationTime();
+ long diff = currentTime - sessionTime;
+ assertTrue("diff between " + currentTime + " and " + sessionTime + " should be < 10000",
+ diff < 10000);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getId()
+ */
+ public void test_getId() {
+ byte[] id = clientSession.getId();
+ SSLSession sess = clientSslContext.getClientSessionContext().getSession(id);
+ assertNotNull("Could not find session for id " + id, sess);
+ assertEquals(clientSession, sess);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getLastAccessedTime()
+ */
+ public void test_getLastAccessedTime() {
+ // check if last access time was in the last 10 seconds
+ long currentTime = System.currentTimeMillis();
+ long sessionTime = clientSession.getLastAccessedTime();
+ long diff = currentTime - sessionTime;
+ assertTrue("diff between " + currentTime + " and " + sessionTime + " should be < 10000",
+ diff < 10000);
+ assertTrue ("diff should be < 10000 but is " + diff, diff < 10000);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getLocalCertificates()
+ */
+ public void test_getLocalCertificates() throws Exception {
+ KeyStore store = client.getStore();
+ Certificate cert = store.getCertificate("mykey");
+ Certificate[] certs = clientSession.getLocalCertificates();
+ assertEquals(cert, certs[0]);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getLocalPrincipal()
+ */
+ public void test_getLocalPrincipal() throws Exception {
+ Principal p1 = clientSession.getLocalPrincipal();
+ KeyStore store = client.getStore();
+ X509Certificate cert = (X509Certificate)store.getCertificate("mykey");
+ Principal p2 = cert.getSubjectX500Principal();
+ assertEquals(p1, p2);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getPacketBufferSize()
+ */
+ public void test_getPacketBufferSize() {
+ assertTrue(clientSession.getPacketBufferSize() > 0);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getPeerCertificates()
+ */
+ public void test_getPeerCertificates() throws Exception {
+ Certificate[] res = clientSession.getPeerCertificates();
+ assertTrue(res.length > 0);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getPeerCertificateChain()
+ */
+ public void test_getPeerCertificateChain() throws Exception {
+ javax.security.cert.X509Certificate[] res = clientSession.getPeerCertificateChain();
+ assertTrue(res.length > 0);
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getProtocol()
+ */
+ public void test_getProtocol() {
+ assertEquals("TLSv1.2", clientSession.getProtocol());
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getSessionContext()
+ */
+ public void test_getSessionContext() {
+ assertEquals(clientSession.getSessionContext(),
+ clientSslContext.getClientSessionContext());
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#putValue(String name, Object value)
+ * javax.net.ssl.SSLSession#removeValue(String name)
+ * javax.net.ssl.SSLSession#getValueNames()
+ */
+ public void test_putValue() {
+ SSLSession s = clientSession;
+ mySSLSessionBindingListener sbl = new mySSLSessionBindingListener();
+ assertNotNull(s.getValueNames());
+ assertEquals(0, s.getValueNames().length);
+ s.putValue("Name_01", sbl);
+ s.putValue("Name_02", sbl);
+ s.putValue("Name_03", sbl);
+ assertEquals(3, s.getValueNames().length);
+ s.removeValue("Name_01");
+ assertEquals(2, s.getValueNames().length);
+
+ try {
+ s.putValue(null, null);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ try {
+ s.putValue("ABC", null);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ try {
+ s.putValue(null, sbl);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+
+ try {
+ s.removeValue(null);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSession#getValue(String name)
+ */
+ public void test_getValue() {
+ SSLSession s = clientSession;
+ mySSLSessionBindingListener sbl = new mySSLSessionBindingListener();
+
+ try {
+ s.getValue(null);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+
+ s.putValue("Name", sbl);
+ Object obj = s.getValue("Name");
+ assertTrue(obj instanceof SSLSessionBindingListener);
+ }
+
+ Thread serverThread, clientThread;
+ TestServer server;
+ TestClient client;
+
+ @Override
+ protected void setUp() throws Exception {
+ String serverKeys = (useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS);
+ String clientKeys = (useBKS ? CLIENT_KEYS_BKS : CLIENT_KEYS_JKS);
+ server = new TestServer(true, TestServer.CLIENT_AUTH_WANTED, serverKeys);
+ client = new TestClient(true, clientKeys);
+
+ serverThread = new Thread(server);
+ clientThread = new Thread(client);
+
+ serverThread.start();
+ try {
+ Thread.currentThread().sleep(1000);
+ clientThread.start();
+ } catch (InterruptedException e) {
+ fail("Could not create server or cient " + e.getMessage());
+ }
+ while (clientSession == null
+ && server.exception == null
+ && client.exception == null) {
+ try {
+ Thread.currentThread().sleep(500);
+ } catch (InterruptedException e) {
+ fail("couldn't create session");
+ }
+ }
+ if (server.exception != null) {
+ server.exception.printStackTrace();
+ }
+ assertNull("server thread has a pending exception: " + server.exception,
+ server.exception);
+ if (client.exception != null) {
+ client.exception.printStackTrace();
+ }
+ assertNull("client thread has a pending exception: " + client.exception,
+ client.exception);
+ assertNotNull("Could not initialize session", clientSession);
+ }
+
+ @Override
+ protected void tearDown() {
+ notFinished = false;
+ try {
+ serverThread.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ try {
+ clientThread.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ // The server must have completed without an exception.
+ if (server.getException() != null) {
+ throw new RuntimeException(server.getException());
+ }
+
+ // The client must have completed without an exception.
+ if (client.getException() != null) {
+ throw new RuntimeException(client.getException());
+ }
+ }
+
+ public class mySSLSessionBindingListener implements
+ SSLSessionBindingListener {
+ mySSLSessionBindingListener() {
+ }
+ public void valueBound(SSLSessionBindingEvent event) {}
+ public void valueUnbound(SSLSessionBindingEvent event) {}
+ }
+
+ /**
+ * Defines the keystore contents for the server, BKS version. Holds just a
+ * single self-generated key. The subject name is "Test Server".
+ */
+ private static final String SERVER_KEYS_BKS =
+ "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41"
+ + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET"
+ + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV"
+ + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw"
+ + "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U"
+ + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl"
+ + "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy"
+ + "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV"
+ + "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG"
+ + "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU"
+ + "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV"
+ + "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx"
+ + "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR"
+ + "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN"
+ + "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs"
+ + "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck"
+ + "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM"
+ + "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI"
+ + "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f"
+ + "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx"
+ + "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt"
+ + "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw"
+ + "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl"
+ + "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw=";
+
+ /**
+ * Defines the keystore contents for the client, BKS version. Holds just a
+ * single self-generated key. The subject name is "Test Client".
+ */
+ private static final String CLIENT_KEYS_BKS =
+ "AAAAAQAAABT4Rka6fxbFps98Y5k2VilmbibNkQAABfQEAAVteWtleQAAARpYl+POAAAAAQAFWC41"
+ + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU9TANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET"
+ + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV"
+ + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgQ2xpZW50MB4XDTA4MDYwNTExNTg0NVoXDTA4MDkw"
+ + "MzExNTg0NVowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U"
+ + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVu"
+ + "dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApUvmWsQDHPpbDKK13Yez2/q54tTOmRml/qva"
+ + "2K6dZjkjSTW0iRuk7ztaVEvdJpfVIDv1oBsCI51ttyLHROy1epjF+GoL74mJb7fkcd0VOoSOTjtD"
+ + "+3GgZkHPAm5YmUYxiJXqxKKJJqMCTIW46eJaA2nAep9QIwZ14/NFAs4ObV8CAwEAATANBgkqhkiG"
+ + "9w0BAQUFAAOBgQCJrCr3hZQFDlLIfsSKI1/w+BLvyf4fubOid0pBxfklR8KBNPTiqjSmu7pd/C/F"
+ + "1FR8CdZUDoPflZHCOU+fj5r5KUC1HyigY/tEUvlforBpfB0uCF+tXW4DbUfOWhfMtLV4nCOJOOZg"
+ + "awfZLJWBJouLKOp427vDftxTSB+Ks8YjlgAAAqwAAAAU+NH6TtrzjyDdCXm5B6Vo7xX5G4YAAAZx"
+ + "EAUkcZtmykn7YdaYxC1jRFJ+GEJpC8nZVg83QClVuCSIS8a5f8Hl44Bk4oepOZsPzhtz3RdVzDVi"
+ + "RFfoyZFsrk9F5bDTVJ6sQbb/1nfJkLhZFXokka0vND5AXMSoD5Bj1Fqem3cK7fSUyqKvFoRKC3XD"
+ + "FQvhqoam29F1rbl8FaYdPvhhZo8TfZQYUyUKwW+RbR44M5iHPx+ykieMe/C/4bcM3z8cwIbYI1aO"
+ + "gjQKS2MK9bs17xaDzeAh4sBKrskFGrDe+2dgvrSKdoakJhLTNTBSG6m+rzqMSCeQpafLKMSjTSSz"
+ + "+KoQ9bLyax8cbvViGGju0SlVhquloZmKOfHr8TukIoV64h3uCGFOVFtQjCYDOq6NbfRvMh14UVF5"
+ + "zgDIGczoD9dMoULWxBmniGSntoNgZM+QP6Id7DBasZGKfrHIAw3lHBqcvB5smemSu7F4itRoa3D8"
+ + "N7hhUEKAc+xA+8NKmXfiCBoHfPHTwDvt4IR7gWjeP3Xv5vitcKQ/MAfO5RwfzkYCXQ3FfjfzmsE1"
+ + "1IfLRDiBj+lhQSulhRVStKI88Che3M4JUNGKllrc0nt1pWa1vgzmUhhC4LSdm6trTHgyJnB6OcS9"
+ + "t2furYjK88j1AuB4921oxMxRm8c4Crq8Pyuf+n3YKi8Pl2BzBtw++0gj0ODlgwut8SrVj66/nvIB"
+ + "jN3kLVahR8nZrEFF6vTTmyXi761pzq9yOVqI57wJGx8o3Ygox1p+pWUPl1hQR7rrhUbgK/Q5wno9"
+ + "uJk07h3IZnNxE+/IKgeMTP/H4+jmyT4mhsexJ2BFHeiKF1KT/FMcJdSi+ZK5yoNVcYuY8aZbx0Ef"
+ + "lHorCXAmLFB0W6Cz4KPP01nD9YBB4olxiK1t7m0AU9zscdivNiuUaB5OIEr+JuZ6dNw=";
+
+ /**
+ * Defines the keystore contents for the server, JKS version. Holds just a
+ * single self-generated key. The subject name is "Test Server".
+ */
+ private static final String SERVER_KEYS_JKS =
+ "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFfBeAAAArowggK2MA4GCisGAQQBKgIRAQEFAASC"
+ + "AqI2kp5XjnF8YZkhcF92YsJNQkvsmH7zqMM87j23zSoV4DwyE3XeC/gZWq1ToScIhoqZkzlbWcu4"
+ + "T/Zfc/DrfGk/rKbBL1uWKGZ8fMtlZk8KoAhxZk1JSyJvdkyKxqmzUbxk1OFMlN2VJNu97FPVH+du"
+ + "dvjTvmpdoM81INWBW/1fZJeQeDvn4mMbbe0IxgpiLnI9WSevlaDP/sm1X3iO9yEyzHLL+M5Erspo"
+ + "Cwa558fOu5DdsICMXhvDQxjWFKFhPHnKtGe+VvwkG9/bAaDgx3kfhk0w5zvdnkKb+8Ed9ylNRzdk"
+ + "ocAa/mxlMTOsTvDKXjjsBupNPIIj7OP4GNnZaxkJjSs98pEO67op1GX2qhy6FSOPNuq8k/65HzUc"
+ + "PYn6voEeh6vm02U/sjEnzRevQ2+2wXoAdp0EwtQ/DlMe+NvcwPGWKuMgX4A4L93DZGb04N2VmAU3"
+ + "YLOtZwTO0LbuWrcCM/q99G/7LcczkxIVrO2I/rh8RXVczlf9QzcrFObFv4ATuspWJ8xG7DhsMbnk"
+ + "rT94Pq6TogYeoz8o8ZMykesAqN6mt/9+ToIemmXv+e+KU1hI5oLwWMnUG6dXM6hIvrULY6o+QCPH"
+ + "172YQJMa+68HAeS+itBTAF4Clm/bLn6reHCGGU6vNdwU0lYldpiOj9cB3t+u2UuLo6tiFWjLf5Zs"
+ + "EQJETd4g/EK9nHxJn0GAKrWnTw7pEHQJ08elzUuy04C/jEEG+4QXU1InzS4o/kR0Sqz2WTGDoSoq"
+ + "ewuPRU5bzQs/b9daq3mXrnPtRBL6HfSDAdpTK76iHqLCGdqx3avHjVSBm4zFvEuYBCev+3iKOBmg"
+ + "yh7eQRTjz4UOWfy85omMBr7lK8PtfVBDzOXpasxS0uBgdUyBDX4tO6k9jZ8a1kmQRQAAAAEABVgu"
+ + "NTA5AAACSDCCAkQwggGtAgRIR8SKMA0GCSqGSIb3DQEBBAUAMGkxCzAJBgNVBAYTAlVTMRMwEQYD"
+ + "VQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMH"
+ + "QW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBTZXJ2ZXIwHhcNMDgwNjA1MTA0ODQyWhcNMDgwOTAzMTA0"
+ + "ODQyWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8w"
+ + "DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGf"
+ + "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoC6chqCI84rj1PrXuJgbiit4EV909zR6N0jNlYfg"
+ + "itwB39bP39wH03rFm8T59b3mbSptnGmCIpLZn25KPPFsYD3JJ+wFlmiUdEP9H05flfwtFQJnw9uT"
+ + "3rRIdYVMPcQ3RoZzwAMliGr882I2thIDbA6xjGU/1nRIdvk0LtxH3QIDAQABMA0GCSqGSIb3DQEB"
+ + "BAUAA4GBAJn+6YgUlY18Ie+0+Vt8oEi81DNi/bfPrAUAh63fhhBikx/3R9dl3wh09Z6p7cIdNxjW"
+ + "n2ll+cRW9eqF7z75F0Omm0C7/KAEPjukVbszmzeU5VqzkpSt0j84YWi+TfcHRrfvhLbrlmGITVpY"
+ + "ol5pHLDyqGmDs53pgwipWqsn/nEXEBgj3EoqPeqHbDf7YaP8h/5BSt0=";
+
+ /**
+ * Defines the keystore contents for the client, JKS version. Holds just a
+ * single self-generated key. The subject name is "Test Client".
+ */
+ private static final String CLIENT_KEYS_JKS =
+ "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFhyMAAAArkwggK1MA4GCisGAQQBKgIRAQEFAASC"
+ + "AqGVSfXolBStZy4nnRNn4fAr+S7kfU2BS23wwW8uB2Ru3GvtLzlK9q08Gvq/LNqBafjyFTVL5FV5"
+ + "SED/8YomO5a98GpskSeRvytCiTBLJdgGhws5TOGekgIAcBROPGIyOtJPQ0HfOQs+BqgzGDHzHQhw"
+ + "u/8Tm6yQwiP+W/1I9B1QnaEztZA3mhTyMMJsmsFTYroGgAog885D5Cmzd8sYGfxec3R6I+xcmBAY"
+ + "eibR5kGpWwt1R+qMvRrtBqh5r6WSKhCBNax+SJVbtUNRiKyjKccdJg6fGqIWWeivwYTy0OhjA6b4"
+ + "NiZ/ZZs5pxFGWUj/Rlp0RYy8fCF6aw5/5s4Bf4MI6dPSqMG8Hf7sJR91GbcELyzPdM0h5lNavgit"
+ + "QPEzKeuDrGxhY1frJThBsNsS0gxeu+OgfJPEb/H4lpYX5IvuIGbWKcxoO9zq4/fimIZkdA8A+3eY"
+ + "mfDaowvy65NBVQPJSxaOyFhLHfeLqOeCsVENAea02vA7andZHTZehvcrqyKtm+z8ncHGRC2H9H8O"
+ + "jKwKHfxxrYY/jMAKLl00+PBb3kspO+BHI2EcQnQuMw/zr83OR9Meq4TJ0TMuNkApZELAeFckIBbS"
+ + "rBr8NNjAIfjuCTuKHhsTFWiHfk9ZIzigxXagfeDRiyVc6khOuF/bGorj23N2o7Rf3uLoU6PyXWi4"
+ + "uhctR1aL6NzxDoK2PbYCeA9hxbDv8emaVPIzlVwpPK3Ruvv9mkjcOhZ74J8bPK2fQmbplbOljcZi"
+ + "tZijOfzcO/11JrwhuJZRA6wanTqHoujgChV9EukVrmbWGGAcewFnAsSbFXIik7/+QznXaDIt5NgL"
+ + "H/Bcz4Z/fdV7Ae1eUaxKXdPbI//4J+8liVT/d8awjW2tldIaDlmGMR3aoc830+3mAAAAAQAFWC41"
+ + "MDkAAAJIMIICRDCCAa0CBEhHxLgwDQYJKoZIhvcNAQEEBQAwaTELMAkGA1UEBhMCVVMxEzARBgNV"
+ + "BAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01UVjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdB"
+ + "bmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVudDAeFw0wODA2MDUxMDQ5MjhaFw0wODA5MDMxMDQ5"
+ + "MjhaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzAN"
+ + "BgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBDbGllbnQwgZ8w"
+ + "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIK3Q+KiFbmCGg422TAo4gggdhMH6FJhiuz8DxRyeMKR"
+ + "UAfP4MK0wtc8N42waZ6OKvxpBFUy0BRfBsX0GD4Ku99yu9/tavSigTraeJtwV3WWRRjIqk7L3wX5"
+ + "cmgS2KSD43Y0rNUKrko26lnt9N4qiYRBSj+tcAN3Lx9+ptqk1LApAgMBAAEwDQYJKoZIhvcNAQEE"
+ + "BQADgYEANb7Q1GVSuy1RPJ0FmiXoMYCCtvlRLkmJphwxovK0cAQK12Vll+yAzBhHiQHy/RA11mng"
+ + "wYudC7u3P8X/tBT8GR1Yk7QW3KgFyPafp3lQBBCraSsfrjKj+dCLig1uBLUr4f68W8VFWZWWTHqp"
+ + "NMGpCX6qmjbkJQLVK/Yfo1ePaUexPSOX0G9m8+DoV3iyNw6at01NRw==";
+
+
+ SSLServerSocket serverSocket;
+ MyHandshakeListener listener;
+ String host = "localhost";
+ boolean notFinished = true;
+ SSLSession clientSession = null;
+ SSLContext clientSslContext = null;
+ String testData = "PING";
+
+ private String PASSWORD = "android";
+
+ /**
+ * Implements a test SSL socket server. It waits for a connection on a given
+ * port, requests client authentication (if specified), reads from the socket,
+ * and writes to the socket.
+ */
+ class TestServer implements Runnable {
+
+ public static final int CLIENT_AUTH_NONE = 0;
+
+ public static final int CLIENT_AUTH_WANTED = 1;
+
+ public static final int CLIENT_AUTH_NEEDED = 2;
+
+ private TestTrustManager trustManager;
+
+ private Exception exception;
+
+ String keys;
+
+ private int clientAuth;
+
+ private boolean provideKeys;
+
+ private KeyStore store;
+
+ public TestServer(boolean provideKeys, int clientAuth, String keys) throws Exception {
+ this.keys = keys;
+ this.clientAuth = clientAuth;
+ this.provideKeys = provideKeys;
+
+ trustManager = new TestTrustManager();
+
+ store = provideKeys ? getKeyStore(keys) : null;
+ KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null;
+ TrustManager[] trustManagers = new TrustManager[] { trustManager };
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagers, trustManagers, null);
+
+ serverSocket = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket();
+
+ if (clientAuth == CLIENT_AUTH_WANTED) {
+ serverSocket.setWantClientAuth(true);
+ } else if (clientAuth == CLIENT_AUTH_NEEDED) {
+ serverSocket.setNeedClientAuth(true);
+ } else {
+ serverSocket.setWantClientAuth(false);
+ }
+
+ serverSocket.bind(null);
+ }
+
+ public void run() {
+ try {
+ SSLSocket clientSocket = (SSLSocket)serverSocket.accept();
+
+ InputStream istream = clientSocket.getInputStream();
+ byte[] buffer = new byte[1024];
+ istream.read(buffer);
+
+ OutputStream ostream = clientSocket.getOutputStream();
+ ostream.write(testData.getBytes());
+ ostream.flush();
+
+ while (notFinished) {
+ Thread.currentThread().sleep(500);
+ }
+
+ clientSocket.close();
+ serverSocket.close();
+
+ } catch (Exception ex) {
+ exception = ex;
+ }
+ }
+
+ public Exception getException() {
+ return exception;
+ }
+
+ public javax.security.cert.X509Certificate[] getChain() {
+ return trustManager.getChain();
+ }
+
+ public KeyStore getStore() {
+ return store;
+ }
+
+ }
+
+ /**
+ * Implements a test SSL socket client. It opens a connection to localhost on
+ * a given port, writes to the socket, and reads from the socket.
+ */
+ class TestClient implements Runnable {
+
+ private TestTrustManager trustManager;
+
+ private Exception exception;
+
+ private String keys;
+
+ private boolean provideKeys;
+
+ private KeyStore store;
+
+ public TestClient(boolean provideKeys, String keys) {
+ this.keys = keys;
+ this.provideKeys = provideKeys;
+
+ trustManager = new TestTrustManager();
+ }
+
+ public void run() {
+ try {
+ store = provideKeys ? getKeyStore(keys) : null;
+ KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null;
+ TrustManager[] trustManagers = new TrustManager[] { trustManager };
+
+ clientSslContext = SSLContext.getInstance("TLS");
+ clientSslContext.init(keyManagers, trustManagers, null);
+
+ SSLSocket socket = (SSLSocket)clientSslContext.getSocketFactory().createSocket();
+
+ socket.connect(serverSocket.getLocalSocketAddress());
+ OutputStream ostream = socket.getOutputStream();
+ ostream.write(testData.getBytes());
+ ostream.flush();
+
+ InputStream istream = socket.getInputStream();
+ byte[] buffer = new byte[1024];
+ istream.read(buffer);
+
+ clientSession = socket.getSession();
+ while (notFinished) {
+ Thread.currentThread().sleep(500);
+ }
+ socket.close();
+
+ } catch (Exception ex) {
+ exception = ex;
+ }
+ }
+
+ public Exception getException() {
+ return exception;
+ }
+
+ public javax.security.cert.X509Certificate[] getChain() {
+ return trustManager.getChain();
+ }
+
+ public KeyStore getStore() {
+ return store;
+ }
+ }
+
+ /**
+ * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
+ * for the result.
+ */
+ private KeyStore getKeyStore(String keys) throws Exception {
+ byte[] bytes = Base64.decode(keys.getBytes());
+ InputStream inputStream = new ByteArrayInputStream(bytes);
+
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(inputStream, PASSWORD.toCharArray());
+ inputStream.close();
+ return keyStore;
+ }
+
+ /**
+ * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
+ * for the result.
+ */
+ private KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception {
+ String algorithm = KeyManagerFactory.getDefaultAlgorithm();
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm);
+ keyManagerFactory.init(keyStore, PASSWORD.toCharArray());
+
+ return keyManagerFactory.getKeyManagers();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketFactoryTest.java
new file mode 100644
index 0000000..e890032
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketFactoryTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.api.javax.net.ssl;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+import junit.framework.TestCase;
+
+public class SSLSocketFactoryTest extends TestCase {
+
+ private ServerSocket ss;
+
+ protected int startServer(String name) {
+ try {
+ ss = new ServerSocket(0);
+ } catch (IOException e) {
+ fail(name + ": " + e);
+ }
+ return ss.getLocalPort();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocketFactory#SSLSocketFactory()
+ */
+ public void test_Constructor() {
+ try {
+ SocketFactory sf = SSLSocketFactory.getDefault();
+ assertTrue(sf instanceof SSLSocketFactory);
+ } catch (Exception e) {
+ fail("Unexpected exception " + e.toString());
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSocketFactory#getDefault()
+ */
+ public void test_getDefault() {
+ assertNotNull("Incorrect default socket factory",
+ SSLSocketFactory.getDefault());
+ }
+
+ /**
+ * javax.net.ssl.SSLSocketFactory#createSocket(Socket s, String host, int port, boolean autoClose)
+ */
+ public void test_createSocket() throws Exception {
+ SSLSocketFactory sf = (SSLSocketFactory)SSLSocketFactory.getDefault();
+ int sport = startServer("test_createSocket()");
+ int[] invalid = {
+ Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE
+ };
+
+
+ Socket st = new Socket("localhost", sport);
+ Socket s = sf.createSocket(st, "localhost", sport, false);
+ assertFalse(s.isClosed());
+
+ st = new Socket("localhost", sport);
+ s = sf.createSocket(st, "localhost", sport, true);
+ s.close();
+ assertTrue(st.isClosed());
+
+ try {
+ sf.createSocket(null, "localhost", sport, true);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ for (int i = 0; i < invalid.length; i++) {
+ try {
+ s = sf.createSocket(new Socket(), "localhost", 1080, false);
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ try {
+ st = new Socket("1.2.3.4hello", sport);
+ s = sf.createSocket(st, "1.2.3.4hello", sport, false);
+ fail();
+ } catch (UnknownHostException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSocketFactory#getDefaultCipherSuites()
+ */
+ public void test_getDefaultCipherSuites() {
+ try {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ assertTrue("no default cipher suites returned",
+ sf.getDefaultCipherSuites().length > 0);
+ } catch (Exception e) {
+ fail("Unexpected exception " + e.toString());
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSocketFactory#getSupportedCipherSuites()
+ */
+ public void test_getSupportedCipherSuites() {
+ try {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ assertTrue("no supported cipher suites returned",
+ sf.getSupportedCipherSuites().length > 0);
+ } catch (Exception e) {
+ fail("Unexpected exception " + e.toString());
+ }
+ }
+
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
new file mode 100644
index 0000000..950d534
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
@@ -0,0 +1,631 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.api.javax.net.ssl;
+
+import dalvik.annotation.AndroidOnly;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.security.cert.X509Certificate;
+import junit.framework.TestCase;
+import libcore.io.Base64;
+import tests.api.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager;
+import libcore.java.security.StandardNames;
+
+public class SSLSocketTest extends TestCase {
+
+ public class HandshakeCL implements HandshakeCompletedListener {
+ public void handshakeCompleted(HandshakeCompletedEvent event) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#SSLSocket()
+ */
+ public void testConstructor() throws Exception {
+ SSLSocket ssl = getSSLSocket();
+ assertNotNull(ssl);
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#SSLSocket(InetAddress address, int port)
+ */
+ public void testConstructor_InetAddressI() throws Exception {
+ int sport = startServer("Cons InetAddress,I");
+ int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE};
+
+ SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost(), sport);
+ assertNotNull(ssl);
+ assertEquals(sport, ssl.getPort());
+ ssl.close();
+
+ try {
+ getSSLSocket(InetAddress.getLocalHost(), sport + 1);
+ fail();
+ } catch (IOException expected) {
+ }
+
+ for (int i = 0; i < invalidPort.length; i++) {
+ try {
+ getSSLSocket(InetAddress.getLocalHost(), invalidPort[i]);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#SSLSocket(InetAddress address, int port,
+ * InetAddress clientAddress, int clientPort)
+ */
+ public void testConstructor_InetAddressIInetAddressI() throws Exception {
+ int sport = startServer("Cons InetAddress,I,InetAddress,I");
+
+ SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost(), sport,
+ InetAddress.getLocalHost(), 0);
+ assertNotNull(ssl);
+ assertEquals(sport, ssl.getPort());
+ ssl.close();
+
+ try {
+ getSSLSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082);
+ fail();
+ } catch (IOException expected) {
+ }
+
+ try {
+ getSSLSocket(InetAddress.getLocalHost(), -1, InetAddress.getLocalHost(), sport + 1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ getSSLSocket(InetAddress.getLocalHost(), sport, InetAddress.getLocalHost(), -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ getSSLSocket(InetAddress.getLocalHost(), Integer.MIN_VALUE,
+ InetAddress.getLocalHost(), sport + 1);
+ fail();
+ } catch (IOException expectedOnRI) {
+ assertTrue(StandardNames.IS_RI);
+ } catch (IllegalArgumentException expectedOnAndroid) {
+ assertFalse(StandardNames.IS_RI);
+ }
+ try {
+ getSSLSocket(InetAddress.getLocalHost(), sport,
+ InetAddress.getLocalHost(), Integer.MAX_VALUE);
+ fail();
+ } catch (IllegalArgumentException expectedOnAndroid) {
+ assertFalse(StandardNames.IS_RI);
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#SSLSocket(String host, int port)
+ */
+ public void testConstructor_StringI() throws Exception {
+ int sport = startServer("Cons String,I");
+ int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE};
+
+ SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost().getHostName(), sport);
+ assertNotNull(ssl);
+ assertEquals(sport, ssl.getPort());
+ ssl.close();
+
+ try {
+ getSSLSocket("localhost", 8082);
+ fail();
+ } catch (IOException expected) {
+ }
+
+ for (int i = 0; i < invalidPort.length; i++) {
+ try {
+ getSSLSocket(InetAddress.getLocalHost().getHostName(), invalidPort[i]);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ try {
+ getSSLSocket("1.2.3.4hello", sport);
+ fail();
+ } catch (UnknownHostException expected) {
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#SSLSocket(String host, int port, InetAddress clientAddress,
+ * int clientPort)
+ */
+ public void testConstructor_StringIInetAddressI() throws Exception {
+ int sport = startServer("Cons String,I,InetAddress,I");
+ int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE};
+
+ SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost().getHostName(), sport,
+ InetAddress.getLocalHost(), 0);
+ assertNotNull(ssl);
+ assertEquals(sport, ssl.getPort());
+
+ try {
+ getSSLSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082);
+ fail();
+ } catch (IOException expected) {
+ }
+
+ for (int i = 0; i < invalidPort.length; i++) {
+ try {
+ getSSLSocket(InetAddress.getLocalHost().getHostName(), invalidPort[i],
+ InetAddress.getLocalHost(), 0);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ getSSLSocket(InetAddress.getLocalHost().getHostName(), sport,
+ InetAddress.getLocalHost(), invalidPort[i]);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ try {
+ getSSLSocket("1.2.3.4hello", sport, InetAddress.getLocalHost(), 0);
+ fail();
+ } catch (UnknownHostException expected) {
+ }
+ }
+
+ public void test_creationStressTest() throws Exception {
+ // Test the default codepath, which uses /dev/urandom.
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, null);
+ for (int i = 0; i < 2048; ++i) {
+ sslContext.getSocketFactory().createSocket().close();
+ }
+
+ // Test the other codepath, which copies a seed from a byte[].
+ sslContext.init(null, null, new SecureRandom());
+ for (int i = 0; i < 2048; ++i) {
+ sslContext.getSocketFactory().createSocket().close();
+ }
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#addHandshakeCompletedListener(HandshakeCompletedListener listener)
+ */
+ @AndroidOnly("RI doesn't throw the specified IAE")
+ public void test_addHandshakeCompletedListener() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ HandshakeCompletedListener ls = new HandshakeCL();
+ try {
+ ssl.addHandshakeCompletedListener(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ ssl.addHandshakeCompletedListener(ls);
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#removeHandshakeCompletedListener(HandshakeCompletedListener listener)
+ */
+ public void test_removeHandshakeCompletedListener() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ HandshakeCompletedListener ls = new HandshakeCL();
+ try {
+ ssl.removeHandshakeCompletedListener(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ ssl.removeHandshakeCompletedListener(ls);
+ } catch (IllegalArgumentException expected) {
+ }
+
+ ssl.addHandshakeCompletedListener(ls);
+ ssl.removeHandshakeCompletedListener(ls);
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#setEnableSessionCreation(boolean flag)
+ * javax.net.ssl.SSLSocket#getEnableSessionCreation()
+ */
+ public void test_EnableSessionCreation() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ assertTrue(ssl.getEnableSessionCreation());
+ ssl.setEnableSessionCreation(false);
+ assertFalse(ssl.getEnableSessionCreation());
+ ssl.setEnableSessionCreation(true);
+ assertTrue(ssl.getEnableSessionCreation());
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#setNeedClientAuth(boolean need)
+ * javax.net.ssl.SSLSocket#getNeedClientAuthCreation()
+ */
+ public void test_NeedClientAuth() throws UnknownHostException, IOException {
+ SSLSocket ssl = getSSLSocket();
+ ssl.setNeedClientAuth(true);
+ assertTrue(ssl.getNeedClientAuth());
+ ssl.setNeedClientAuth(false);
+ assertFalse(ssl.getNeedClientAuth());
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#setWantClientAuth(boolean want)
+ * javax.net.ssl.SSLSocket#getWantClientAuthCreation()
+ */
+ public void test_WantClientAuth() throws UnknownHostException, IOException {
+ SSLSocket ssl = getSSLSocket();
+ ssl.setWantClientAuth(true);
+ assertTrue(ssl.getWantClientAuth());
+ ssl.setWantClientAuth(false);
+ assertFalse(ssl.getWantClientAuth());
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#getSupportedProtocols()
+ */
+ public void test_getSupportedProtocols() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ String[] res = ssl.getSupportedProtocols();
+ assertTrue("No supported protocols found", res.length > 0);
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#getEnabledProtocols()
+ * javax.net.ssl.SSLSocket#setEnabledProtocols(String[] protocols)
+ */
+ public void test_EnabledProtocols() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ try {
+ ssl.setEnabledProtocols(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ ssl.setEnabledProtocols(new String[] {});
+ try {
+ ssl.setEnabledProtocols(new String[] {"blubb"});
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ ssl.setEnabledProtocols(ssl.getEnabledProtocols());
+ String[] res = ssl.getEnabledProtocols();
+ assertEquals("no enabled protocols set",
+ ssl.getEnabledProtocols().length, res.length);
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#getSession()
+ */
+ public void test_getSession() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ assertNotNull(ssl.getSession());
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#getSupportedCipherSuites()
+ */
+ public void test_getSupportedCipherSuites() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ String[] res = ssl.getSupportedCipherSuites();
+ assertTrue("no supported cipher suites", res.length > 0);
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#getEnabledCipherSuites()
+ * javax.net.ssl.SSLSocket#setEnabledCipherSuites(String[] suites)
+ */
+ public void test_EnabledCipherSuites() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ try {
+ ssl.setEnabledCipherSuites(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ ssl.setEnabledCipherSuites(new String[] {});
+ try {
+ ssl.setEnabledCipherSuites(new String[] {"blubb"});
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
+ String[] res = ssl.getEnabledCipherSuites();
+ assertNotNull("NULL result", res);
+ assertEquals("not all supported cipher suites were enabled",
+ Arrays.asList(ssl.getSupportedCipherSuites()),
+ Arrays.asList(res));
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#getUseClientMode()
+ * javax.net.ssl.SSLSocket#setUseClientMode(boolean mode)
+ */
+ public void test_UseClientMode() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ assertTrue(ssl.getUseClientMode());
+ ssl.setUseClientMode(false);
+ assertFalse(ssl.getUseClientMode());
+ ssl.close();
+
+ ssl = getSSLSocket("localhost", startServer("UseClientMode"));
+ try {
+ ssl.startHandshake();
+ } catch (IOException ioe) {
+ //fail(ioe + " was thrown for method startHandshake()");
+ }
+ try {
+ ssl.setUseClientMode(false);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ ssl.close();
+ }
+
+ /**
+ * javax.net.ssl.SSLSocket#startHandshake()
+ */
+ public void test_startHandshake() throws IOException {
+ SSLSocket ssl = getSSLSocket();
+ try {
+ ssl.startHandshake();
+ fail();
+ } catch (IOException expected) {
+ }
+ ssl.close();
+ }
+
+ private boolean useBKS = !StandardNames.IS_RI;
+
+ private String PASSWORD = "android";
+
+ private boolean serverReady = false;
+
+ /**
+ * Defines the keystore contents for the server, BKS version. Holds just a
+ * single self-generated key. The subject name is "Test Server".
+ */
+ private static final String SERVER_KEYS_BKS = ""
+ + "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41"
+ + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET"
+ + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV"
+ + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw"
+ + "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U"
+ + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl"
+ + "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy"
+ + "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV"
+ + "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG"
+ + "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU"
+ + "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV"
+ + "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx"
+ + "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR"
+ + "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN"
+ + "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs"
+ + "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck"
+ + "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM"
+ + "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI"
+ + "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f"
+ + "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx"
+ + "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt"
+ + "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw"
+ + "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl"
+ + "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw=";
+
+ /**
+ * Defines the keystore contents for the server, JKS version. Holds just a
+ * single self-generated key. The subject name is "Test Server".
+ */
+ private static final String SERVER_KEYS_JKS = ""
+ + "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFfBeAAAArowggK2MA4GCisGAQQBKgIRAQEFAASC"
+ + "AqI2kp5XjnF8YZkhcF92YsJNQkvsmH7zqMM87j23zSoV4DwyE3XeC/gZWq1ToScIhoqZkzlbWcu4"
+ + "T/Zfc/DrfGk/rKbBL1uWKGZ8fMtlZk8KoAhxZk1JSyJvdkyKxqmzUbxk1OFMlN2VJNu97FPVH+du"
+ + "dvjTvmpdoM81INWBW/1fZJeQeDvn4mMbbe0IxgpiLnI9WSevlaDP/sm1X3iO9yEyzHLL+M5Erspo"
+ + "Cwa558fOu5DdsICMXhvDQxjWFKFhPHnKtGe+VvwkG9/bAaDgx3kfhk0w5zvdnkKb+8Ed9ylNRzdk"
+ + "ocAa/mxlMTOsTvDKXjjsBupNPIIj7OP4GNnZaxkJjSs98pEO67op1GX2qhy6FSOPNuq8k/65HzUc"
+ + "PYn6voEeh6vm02U/sjEnzRevQ2+2wXoAdp0EwtQ/DlMe+NvcwPGWKuMgX4A4L93DZGb04N2VmAU3"
+ + "YLOtZwTO0LbuWrcCM/q99G/7LcczkxIVrO2I/rh8RXVczlf9QzcrFObFv4ATuspWJ8xG7DhsMbnk"
+ + "rT94Pq6TogYeoz8o8ZMykesAqN6mt/9+ToIemmXv+e+KU1hI5oLwWMnUG6dXM6hIvrULY6o+QCPH"
+ + "172YQJMa+68HAeS+itBTAF4Clm/bLn6reHCGGU6vNdwU0lYldpiOj9cB3t+u2UuLo6tiFWjLf5Zs"
+ + "EQJETd4g/EK9nHxJn0GAKrWnTw7pEHQJ08elzUuy04C/jEEG+4QXU1InzS4o/kR0Sqz2WTGDoSoq"
+ + "ewuPRU5bzQs/b9daq3mXrnPtRBL6HfSDAdpTK76iHqLCGdqx3avHjVSBm4zFvEuYBCev+3iKOBmg"
+ + "yh7eQRTjz4UOWfy85omMBr7lK8PtfVBDzOXpasxS0uBgdUyBDX4tO6k9jZ8a1kmQRQAAAAEABVgu"
+ + "NTA5AAACSDCCAkQwggGtAgRIR8SKMA0GCSqGSIb3DQEBBAUAMGkxCzAJBgNVBAYTAlVTMRMwEQYD"
+ + "VQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMH"
+ + "QW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBTZXJ2ZXIwHhcNMDgwNjA1MTA0ODQyWhcNMDgwOTAzMTA0"
+ + "ODQyWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8w"
+ + "DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGf"
+ + "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoC6chqCI84rj1PrXuJgbiit4EV909zR6N0jNlYfg"
+ + "itwB39bP39wH03rFm8T59b3mbSptnGmCIpLZn25KPPFsYD3JJ+wFlmiUdEP9H05flfwtFQJnw9uT"
+ + "3rRIdYVMPcQ3RoZzwAMliGr882I2thIDbA6xjGU/1nRIdvk0LtxH3QIDAQABMA0GCSqGSIb3DQEB"
+ + "BAUAA4GBAJn+6YgUlY18Ie+0+Vt8oEi81DNi/bfPrAUAh63fhhBikx/3R9dl3wh09Z6p7cIdNxjW"
+ + "n2ll+cRW9eqF7z75F0Omm0C7/KAEPjukVbszmzeU5VqzkpSt0j84YWi+TfcHRrfvhLbrlmGITVpY"
+ + "ol5pHLDyqGmDs53pgwipWqsn/nEXEBgj3EoqPeqHbDf7YaP8h/5BSt0=";
+
+ protected int startServer(String name) {
+ String keys = useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS;
+ TestServer server = new TestServer(true, keys);
+ Thread serverThread = new Thread(server);
+ serverThread.start();
+ try {
+ while (!serverReady) {
+ Exception e = server.getException();
+ if (e != null) {
+ throw new AssertionError(e);
+ }
+ Thread.currentThread().sleep(50);
+ }
+ // give the server 100 millis to accept
+ Thread.currentThread().sleep(100);
+ } catch (InterruptedException ignore) {
+ }
+ return server.sport;
+ }
+
+ /**
+ * Implements a test SSL socket server. It wait for a connection on a given
+ * port, requests client authentication (if specified), and read 256 bytes
+ * from the socket.
+ */
+ class TestServer implements Runnable {
+
+ public static final int CLIENT_AUTH_NONE = 0;
+
+ public static final int CLIENT_AUTH_WANTED = 1;
+
+ public static final int CLIENT_AUTH_NEEDED = 2;
+
+ private TestTrustManager trustManager;
+
+ private Exception exception;
+
+ String keys;
+
+ private boolean provideKeys;
+
+ int sport;
+
+ public TestServer(boolean provideKeys, String keys) {
+ this.keys = keys;
+ this.provideKeys = provideKeys;
+
+ trustManager = new TestTrustManager();
+ }
+
+ public void run() {
+ try {
+ KeyManager[] keyManagers = provideKeys ? getKeyManagers(keys) : null;
+ TrustManager[] trustManagers = new TrustManager[] { trustManager };
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagers, trustManagers, null);
+
+ SSLServerSocket serverSocket = (SSLServerSocket)
+ sslContext.getServerSocketFactory().createServerSocket();
+ try {
+ serverSocket.bind(new InetSocketAddress(0));
+ sport = serverSocket.getLocalPort();
+ serverReady = true;
+
+ SSLSocket clientSocket = (SSLSocket)serverSocket.accept();
+
+ try {
+ InputStream stream = clientSocket.getInputStream();
+ try {
+ for (int i = 0; i < 256; i++) {
+ int j = stream.read();
+ if (i != j) {
+ throw new RuntimeException("Error reading socket, expected " + i
+ + ", got " + j);
+ }
+ }
+ } finally {
+ stream.close();
+ }
+ } finally {
+ clientSocket.close();
+ }
+ } finally {
+ serverSocket.close();
+ }
+ } catch (Exception ex) {
+ exception = ex;
+ }
+ }
+
+ public Exception getException() {
+ return exception;
+ }
+
+ public X509Certificate[] getChain() {
+ return trustManager.getChain();
+ }
+
+ }
+
+ /**
+ * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
+ * for the result.
+ */
+ private KeyManager[] getKeyManagers(String keys) throws Exception {
+ byte[] bytes = Base64.decode(keys.getBytes());
+ InputStream inputStream = new ByteArrayInputStream(bytes);
+
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(inputStream, PASSWORD.toCharArray());
+ inputStream.close();
+
+ String algorithm = KeyManagerFactory.getDefaultAlgorithm();
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm);
+ keyManagerFactory.init(keyStore, PASSWORD.toCharArray());
+
+ return keyManagerFactory.getKeyManagers();
+ }
+
+ private SSLSocket getSSLSocket() throws IOException {
+ return (SSLSocket) SSLSocketFactory.getDefault().createSocket();
+ }
+
+ private SSLSocket getSSLSocket(InetAddress host, int port) throws IOException {
+ return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port);
+ }
+
+ private SSLSocket getSSLSocket(String host, int port) throws UnknownHostException, IOException {
+ return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port);
+ }
+
+ private SSLSocket getSSLSocket(InetAddress host, int port, InetAddress localHost, int localPort)
+ throws IOException {
+ return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host,
+ port,
+ localHost,
+ localPort);
+ }
+
+ private SSLSocket getSSLSocket(String host, int port, InetAddress localHost, int localPort)
+ throws UnknownHostException, IOException {
+ return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host,
+ port,
+ localHost,
+ localPort);
+ }
+}
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactory1Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactory1Test.java
index 23b24e4..23b24e4 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactory1Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactory1Test.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactory2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactory2Test.java
index 0c0760f..0c0760f 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactory2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactory2Test.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactorySpiTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactorySpiTest.java
index 7bdeb45..7bdeb45 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/TrustManagerFactorySpiTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/TrustManagerFactorySpiTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/X509ExtendedKeyManagerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509ExtendedKeyManagerTest.java
index 514fed8..514fed8 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/X509ExtendedKeyManagerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509ExtendedKeyManagerTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/X509KeyManagerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509KeyManagerTest.java
index 4dddbc6..4dddbc6 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/X509KeyManagerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509KeyManagerTest.java
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/X509TrustManagerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509TrustManagerTest.java
index ade0eca..ade0eca 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/X509TrustManagerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/X509TrustManagerTest.java
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/DestroyFailedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/DestroyFailedExceptionTest.java
new file mode 100644
index 0000000..e274c5c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/DestroyFailedExceptionTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth;
+
+import junit.framework.TestCase;
+import javax.security.auth.DestroyFailedException;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for <code>DestroyFailedException</code> class constructors and methods.
+ *
+ */
+public class DestroyFailedExceptionTest extends TestCase {
+
+ private static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+
+ /**
+ * javax.security.auth.DestroyFailedException#DestroyFailedException()
+ * Assertion: constructs DestroyFailedException with no detail message
+ */
+ public void testDestroyFailedException01() {
+ DestroyFailedException dfE = new DestroyFailedException();
+ assertNull("getMessage() must return null.", dfE.getMessage());
+ assertNull("getCause() must return null", dfE.getCause());
+ }
+
+ /**
+ * javax.security.auth.DestroyFailedException#DestroyFailedException(String msg)
+ * Assertion: constructs with not null parameter.
+ */
+ public void testDestroyFailedException02() {
+ DestroyFailedException dfE;
+ for (int i = 0; i < msgs.length; i++) {
+ dfE = new DestroyFailedException(msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), dfE.getMessage(), msgs[i]);
+ assertNull("getCause() must return null", dfE.getCause());
+ }
+ }
+
+ /**
+ * javax.security.auth.DestroyFailedException#DestroyFailedException(String msg)
+ * Assertion: constructs with null parameter.
+ */
+ public void testDestroyFailedException03() {
+ String msg = null;
+ DestroyFailedException dfE = new DestroyFailedException(msg);
+ assertNull("getMessage() must return null.", dfE.getMessage());
+ assertNull("getCause() must return null", dfE.getCause());
+ }
+
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(getSerializationData());
+ }
+
+ public void testSerializationGolden() throws Exception {
+ SerializationTest.verifyGolden(this, getSerializationData());
+ }
+
+ private Object[] getSerializationData() {
+ return new Object[] { new DestroyFailedException("message") };
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/DestroyableTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/DestroyableTest.java
new file mode 100644
index 0000000..c419f64
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/DestroyableTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth;
+
+import junit.framework.TestCase;
+
+import javax.security.auth.Destroyable;
+import javax.security.auth.DestroyFailedException;
+
+
+/**
+ * Tests for <code>Destroyable</code> class constructors and methods.
+ *
+ */
+public class DestroyableTest extends TestCase {
+
+ /**
+ * javax.security.auth.Destroyable#destroy()
+ * javax.security.auth.Destroyable#isDestroyed()
+ */
+ public void test_destroy() {
+ myDestroyable md = new myDestroyable();
+ try {
+ assertFalse(md.isDestroyed());
+ md.destroy();
+ assertTrue(md.isDestroyed());
+ } catch (Exception e) {
+ fail("Unexpected exception " + e);
+ }
+ }
+
+ private class myDestroyable implements Destroyable {
+
+ boolean destroyDone = false;
+
+ myDestroyable() {
+ }
+
+ public void destroy() throws DestroyFailedException {
+ destroyDone = true;
+ }
+
+ public boolean isDestroyed() {
+ return destroyDone;
+ }
+ }
+}
+
+
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/LoginExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/LoginExceptionTest.java
new file mode 100644
index 0000000..c0540bc
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/LoginExceptionTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth;
+
+import junit.framework.TestCase;
+
+import javax.security.auth.login.LoginException;
+
+/**
+ * Tests for <code>LoginException</code> class constructors and methods.
+ *
+ */
+public class LoginExceptionTest extends TestCase {
+
+ private static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+
+ /**
+ * javax.security.auth.login.LoginException#LoginException()
+ * Assertion: constructs LoginException with no detail message
+ */
+ public void testLoginException01() {
+ LoginException lE = new LoginException();
+ assertNull("getMessage() must return null.", lE.getMessage());
+ assertNull("getCause() must return null", lE.getCause());
+ }
+
+ /**
+ * javax.security.auth.login.LoginException#LoginException(String msg)
+ * Assertion: constructs with not null parameter.
+ */
+ public void testLoginException02() {
+ LoginException lE;
+ for (int i = 0; i < msgs.length; i++) {
+ lE = new LoginException(msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), lE.getMessage(), msgs[i]);
+ assertNull("getCause() must return null", lE.getCause());
+ }
+ }
+
+ /**
+ * javax.security.auth.login.LoginException#LoginException(String msg)
+ * Assertion: constructs with null parameter.
+ */
+ public void testLoginException03() {
+ String msg = null;
+ LoginException lE = new LoginException(msg);
+ assertNull("getMessage() must return null.", lE.getMessage());
+ assertNull("getCause() must return null", lE.getCause());
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/SubjectTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/SubjectTest.java
new file mode 100644
index 0000000..f2ef564
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/SubjectTest.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth;
+
+import junit.framework.TestCase;
+import javax.security.auth.Subject;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for <code>Subject</code> class constructors and methods.
+ *
+ */
+public class SubjectTest extends TestCase {
+
+ /**
+ * javax.security.auth.Subject#Subject()
+ */
+ public void test_Constructor_01() {
+ try {
+ Subject s = new Subject();
+ assertNotNull("Null object returned", s);
+ assertTrue("Set of principal is not empty", s.getPrincipals().isEmpty());
+ assertTrue("Set of private credentials is not empty", s.getPrivateCredentials().isEmpty());
+ assertTrue("Set of public credentials is not empty", s.getPublicCredentials().isEmpty());
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+ /**
+ * javax.security.auth.Subject#doAs(Subject subject, PrivilegedAction action)
+ */
+ public void test_doAs_01() {
+ Subject subj = new Subject();
+ PrivilegedAction<Object> pa = new myPrivilegedAction();
+ PrivilegedAction<Object> paNull = null;
+
+ try {
+ Object obj = Subject.doAs(null, pa);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ Object obj = Subject.doAs(subj, pa);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ Object obj = Subject.doAs(subj, paNull);
+ fail("NullPointerException wasn't thrown");
+ } catch (NullPointerException npe) {
+ }
+ }
+
+ /**
+ * javax.security.auth.Subject#doAs(Subject subject, PrivilegedExceptionAction action)
+ */
+ public void test_doAs_02() {
+ Subject subj = new Subject();
+ PrivilegedExceptionAction<Object> pea = new myPrivilegedExceptionAction();
+ PrivilegedExceptionAction<Object> peaNull = null;
+
+ try {
+ Object obj = Subject.doAs(null, pea);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ Object obj = Subject.doAs(subj, pea);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ Object obj = Subject.doAs(subj, peaNull);
+ fail("NullPointerException wasn't thrown");
+ } catch (NullPointerException npe) {
+ } catch (Exception e) {
+ fail(e + " was thrown instead of NullPointerException");
+ }
+
+ try {
+ Subject.doAs(subj, new PrivilegedExceptionAction<Object>(){
+ public Object run() throws PrivilegedActionException {
+ throw new PrivilegedActionException(null);
+ }
+ });
+ fail("PrivilegedActionException wasn't thrown");
+ } catch (PrivilegedActionException e) {
+ }
+ }
+
+ /**
+ * javax.security.auth.Subject#doAsPrivileged(Subject subject,
+ * PrivilegedAction action,
+ * AccessControlContext acc)
+ */
+ public void test_doAsPrivileged_01() {
+ Subject subj = new Subject();
+ PrivilegedAction<Object> pa = new myPrivilegedAction();
+ PrivilegedAction<Object> paNull = null;
+ AccessControlContext acc = AccessController.getContext();
+
+ try {
+ Object obj = Subject.doAsPrivileged(null, pa, acc);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ Object obj = Subject.doAsPrivileged(subj, pa, acc);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ Object obj = Subject.doAsPrivileged(subj, paNull, acc);
+ fail("NullPointerException wasn't thrown");
+ } catch (NullPointerException npe) {
+ }
+ }
+
+ /**
+ * javax.security.auth.Subject#doAsPrivileged(Subject subject,
+ * PrivilegedExceptionAction action,
+ * AccessControlContext acc)
+ */
+ public void test_doAsPrivileged_02() {
+ Subject subj = new Subject();
+ PrivilegedExceptionAction<Object> pea = new myPrivilegedExceptionAction();
+ PrivilegedExceptionAction<Object> peaNull = null;
+ AccessControlContext acc = AccessController.getContext();
+
+ try {
+ Object obj = Subject.doAsPrivileged(null, pea, acc);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ Object obj = Subject.doAsPrivileged(subj, pea, acc);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ Object obj = Subject.doAsPrivileged(subj, peaNull, acc);
+ fail("NullPointerException wasn't thrown");
+ } catch (NullPointerException npe) {
+ } catch (Exception e) {
+ fail(e + " was thrown instead of NullPointerException");
+ }
+
+ try {
+ Subject.doAsPrivileged(subj, new PrivilegedExceptionAction<Object>(){
+ public Object run() throws PrivilegedActionException {
+ throw new PrivilegedActionException(null);
+ }
+ }, acc);
+ fail("PrivilegedActionException wasn't thrown");
+ } catch (PrivilegedActionException e) {
+ }
+ }
+
+ /**
+ * javax.security.auth.Subject#getSubject(AccessControlContext acc)
+ */
+ public void test_getSubject() {
+ Subject subj = new Subject();
+ AccessControlContext acc = new AccessControlContext(new ProtectionDomain[0]);
+
+ try {
+ assertNull(Subject.getSubject(acc));
+ } catch (Exception e) {
+ fail("Unexpected exception " + e);
+ }
+ }
+
+ /**
+ * javax.security.auth.Subject#toString()
+ */
+ public void test_toString() {
+ Subject subj = new Subject();
+
+ try {
+ assertNotNull("Null returned", subj.toString());
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+ /**
+ * javax.security.auth.Subject#hashCode()
+ */
+ public void test_hashCode() {
+ Subject subj = new Subject();
+
+ try {
+ assertNotNull("Null returned", subj.hashCode());
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(getSerializationData());
+ }
+
+ public void testSerializationGolden() throws Exception {
+ SerializationTest.verifyGolden(this, getSerializationData());
+ }
+
+ private Object[] getSerializationData() {
+ Subject subject = new Subject();
+ return new Object[] { subject, subject.getPrincipals(),
+ subject.getPrivateCredentials(), subject.getPublicCredentials() };
+ }
+}
+
+
+class myPrivilegedAction implements PrivilegedAction <Object> {
+ myPrivilegedAction(){}
+ public Object run() {
+ return new Object();
+ }
+}
+
+class myPrivilegedExceptionAction implements PrivilegedExceptionAction <Object> {
+ myPrivilegedExceptionAction(){}
+ public Object run() {
+ return new Object();
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/CallbackHandlerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/CallbackHandlerTest.java
new file mode 100644
index 0000000..0b4d0fe
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/CallbackHandlerTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth.callback;
+
+import junit.framework.TestCase;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ * Tests for <code>CallbackHandler</code> class constructors and methods.
+ *
+ */
+public class CallbackHandlerTest extends TestCase {
+
+ /**
+ * javax.security.auth.callback.CallbackHandler#handle(Callback[] callbacks)
+ */
+ public void test_CallbackHandler() {
+ CallbackHandlerImpl ch = new CallbackHandlerImpl();
+ assertFalse(ch.called);
+ ch.handle(null);
+ assertTrue(ch.called);
+ }
+
+ private class CallbackHandlerImpl implements CallbackHandler {
+ boolean called = false;
+ public void handle(Callback[] callbacks) {
+ called = true;
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.java
new file mode 100644
index 0000000..024c9e9
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth.callback;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import javax.security.auth.callback.PasswordCallback;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for <code>PasswordCallback</code> class constructors and methods.
+ *
+ */
+public class PasswordCallbackTest extends TestCase {
+
+ /**
+ * javax.security.auth.callback.PasswordCallback#PasswordCallback(String prompt, boolean echoOn)
+ * javax.security.auth.callback.PasswordCallback#getPrompt()
+ * javax.security.auth.callback.PasswordCallback#isEchoOn()
+ */
+ public void test_PasswordCallback() {
+ String prompt = "promptTest";
+
+ try {
+ PasswordCallback pc = new PasswordCallback(prompt, true);
+ assertNotNull("Null object returned", pc);
+ assertEquals(prompt, pc.getPrompt());
+ assertEquals(true, pc.isEchoOn());
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ PasswordCallback pc = new PasswordCallback(prompt, false);
+ assertNotNull("Null object returned", pc);
+ assertEquals(prompt, pc.getPrompt());
+ assertEquals(false, pc.isEchoOn());
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ PasswordCallback pc = new PasswordCallback(null, true);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException npe) {
+ }
+
+ try {
+ PasswordCallback pc = new PasswordCallback("", true);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException npe) {
+ }
+ }
+
+ /**
+ * javax.security.auth.callback.PasswordCallback#getPassword()
+ * javax.security.auth.callback.PasswordCallback#setPassword(char[] password)
+ * javax.security.auth.callback.PasswordCallback#clearPassword()
+ */
+ public void test_Password() {
+ String prompt = "promptTest";
+ char[] psw1 = "testPassword".toCharArray();
+ char[] psw2 = "newPassword".toCharArray();
+ PasswordCallback pc = new PasswordCallback(prompt, true);
+
+ try {
+ assertNull(pc.getPassword());
+ pc.setPassword(psw1);
+ assertEquals(psw1.length, pc.getPassword().length);
+ pc.setPassword(null);
+ assertNull(pc.getPassword());
+ pc.setPassword(psw2);
+ char[] res = pc.getPassword();
+ assertEquals(psw2.length, res.length);
+ for (int i = 0; i < res.length; i++) {
+ assertEquals("Incorrect password was returned", psw2[i], res[i]);
+ }
+ pc.clearPassword();
+ res = pc.getPassword();
+ if (res.equals(psw2)) {
+ fail("Incorrect password was returned after clear");
+ }
+ pc.setPassword(psw1);
+ res = pc.getPassword();
+ assertEquals(psw1.length, res.length);
+ for (int i = 0; i < res.length; i++) {
+ assertEquals("Incorrect result", psw1[i], res[i]);
+ }
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(getSerializationData(), new PasswordCallbackAssert());
+ }
+
+ public void testSerializationGolden() throws Exception {
+ SerializationTest.verifyGolden(this, getSerializationData(),
+ new PasswordCallbackAssert());
+ }
+
+ private Object[] getSerializationData() {
+ char[] pwd = { 'a', 'b', 'c' };
+ PasswordCallback p = new PasswordCallback("prmpt", true);
+ p.setPassword(pwd);
+ return new Object[] { new PasswordCallback("prompt", true), p };
+ }
+
+ public static final class PasswordCallbackAssert implements SerializationTest.SerializableAssert {
+ public void assertDeserialized(Serializable initial, Serializable deserialized) {
+ final PasswordCallback callback1 = (PasswordCallback) initial;
+ final PasswordCallback callback2 = (PasswordCallback) deserialized;
+
+ assertTrue(Arrays.equals(callback1.getPassword(), callback2.getPassword()));
+ assertEquals(callback1.getPrompt(), callback2.getPrompt());
+ assertEquals(callback1.isEchoOn(), callback2.isEchoOn());
+ }
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/UnsupportedCallbackExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/UnsupportedCallbackExceptionTest.java
new file mode 100644
index 0000000..defdbc7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/callback/UnsupportedCallbackExceptionTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth.callback;
+
+import junit.framework.TestCase;
+
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.callback.Callback;
+
+/**
+ * Tests for <code>UnsupportedCallbackException</code> class constructors and methods.
+ *
+ */
+public class UnsupportedCallbackExceptionTest extends TestCase {
+
+ private static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+
+ /**
+ * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback)
+ * javax.security.auth.callback.UnsupportedCallbackExceptionTest#getCallback()
+ * Assertion: constructs with null parameter.
+ */
+ public void testUnsupportedCallbackException01() {
+ Callback c = null;
+ UnsupportedCallbackException ucE = new UnsupportedCallbackException(c);
+ assertNull("getMessage() must return null.", ucE.getMessage());
+ assertNull("getCallback() must return null", ucE.getCallback());
+ }
+
+ /**
+ * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback)
+ * javax.security.auth.callback.UnsupportedCallbackExceptionTest#getCallback()
+ * Assertion: constructs with not null parameter.
+ */
+ public void testUnsupportedCallbackException02() {
+ myCallback c = new myCallback();
+ assertNotNull("Callback object is null", c);
+ UnsupportedCallbackException ucE = new UnsupportedCallbackException(c);
+ assertNull("getMessage() must return null.", ucE.getMessage());
+ assertEquals("Incorrect callback object was returned", c, ucE.getCallback());
+ }
+
+ /**
+ * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback, String msg)
+ * Assertion: constructs with null callback parameter and null message.
+ */
+ public void testUnsupportedCallbackException03() {
+ UnsupportedCallbackException ucE = new UnsupportedCallbackException(null, null);
+ assertNull("getMessage() must return null.", ucE.getMessage());
+ assertNull("getCallback() must return null.", ucE.getCallback());
+ }
+
+ /**
+ * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback, String msg)
+ * Assertion: constructs with null callback parameter and not null message.
+ */
+ public void testUnsupportedCallbackException04() {
+ UnsupportedCallbackException ucE;
+ for (int i = 0; i < msgs.length; i++) {
+ ucE = new UnsupportedCallbackException(null, msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), ucE.getMessage(), msgs[i]);
+ assertNull("getCallback() must return null.", ucE.getCallback());
+ }
+ }
+
+ /**
+ * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback, String msg)
+ * Assertion: constructs with not null callback parameter and null message.
+ */
+ public void testUnsupportedCallbackException05() {
+ myCallback c = new myCallback();
+ assertNotNull("Callback object is null", c);
+ UnsupportedCallbackException ucE = new UnsupportedCallbackException(c, null);
+ assertNull("getMessage() must return null.", ucE.getMessage());
+ assertEquals("Incorrect callback object was returned", c, ucE.getCallback());
+ }
+
+ /**
+ * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback, String msg)
+ * Assertion: constructs with not null parameters.
+ */
+ public void testUnsupportedCallbackException06() {
+ myCallback c = new myCallback();
+ assertNotNull("Callback object is null", c);
+ UnsupportedCallbackException ucE;
+ for (int i = 0; i < msgs.length; i++) {
+ ucE = new UnsupportedCallbackException(c, msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), ucE.getMessage(), msgs[i]);
+ assertEquals("Incorrect callback object was returned", c, ucE.getCallback());
+ }
+ }
+}
+
+class myCallback implements Callback {
+ myCallback(){
+ }
+}
+
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/login/LoginExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/login/LoginExceptionTest.java
new file mode 100644
index 0000000..2d63f16
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/login/LoginExceptionTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth.login;
+
+import junit.framework.TestCase;
+
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for <code>LoginException</code> class constructors and methods.
+ *
+ */
+public class LoginExceptionTest extends TestCase {
+
+ private static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+
+ /**
+ * javax.security.auth.login.LoginException#LoginException()
+ * Assertion: constructs LoginException with no detail message
+ */
+ public void testLoginException01() {
+ LoginException lE = new LoginException();
+ assertNull("getMessage() must return null.", lE.getMessage());
+ assertNull("getCause() must return null", lE.getCause());
+ }
+
+ /**
+ * javax.security.auth.login.LoginException#LoginException(String msg)
+ * Assertion: constructs with not null parameter.
+ */
+ public void testLoginException02() {
+ LoginException lE;
+ for (int i = 0; i < msgs.length; i++) {
+ lE = new LoginException(msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), lE.getMessage(), msgs[i]);
+ assertNull("getCause() must return null", lE.getCause());
+ }
+ }
+
+ /**
+ * javax.security.auth.login.LoginException#LoginException(String msg)
+ * Assertion: constructs with null parameter.
+ */
+ public void testLoginException03() {
+ String msg = null;
+ LoginException lE = new LoginException(msg);
+ assertNull("getMessage() must return null.", lE.getMessage());
+ assertNull("getCause() must return null", lE.getCause());
+ }
+
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(getSerializationData());
+ }
+
+ public void testSerializationGolden() throws Exception {
+ SerializationTest.verifyGolden(this, getSerializationData());
+ }
+
+ private Object[] getSerializationData() {
+ return new Object[] { new LoginException("message") };
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.java
new file mode 100644
index 0000000..34011c7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.java
@@ -0,0 +1,3094 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tests.javax.security.auth.x500;
+
+import javax.security.auth.x500.X500Principal;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.security.tests.support.cert.TestUtils;
+import tests.support.resource.Support_Resources;
+
+
+/**
+ * Tests for <code>X500Principal</code> class constructors and methods.
+ *
+ */
+public class X500PrincipalTest extends TestCase {
+
+ /**
+ * javax.security.auth.x500.X500Principal#X500Principal(String name)
+ */
+ public void test_X500Principal_01() {
+ String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
+
+ try {
+ X500Principal xpr = new X500Principal(name);
+ assertNotNull("Null object returned", xpr);
+ String resName = xpr.getName();
+ assertEquals(name, resName);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ X500Principal xpr = new X500Principal((String)null);
+ fail("NullPointerException wasn't thrown");
+ } catch (NullPointerException npe) {
+ } catch (Exception e) {
+ fail(e + " was thrown instead of NullPointerException");
+ }
+
+ try {
+ X500Principal xpr = new X500Principal("X500PrincipalName");
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException npe) {
+ } catch (Exception e) {
+ fail(e + " was thrown instead of IllegalArgumentException");
+ }
+ }
+
+ /**
+ * javax.security.auth.x500.X500Principal#X500Principal(InputStream is)
+ */
+ public void test_X500Principal_02() {
+ String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
+ byte[] ba = getByteArray(TestUtils.getX509Certificate_v1());
+ ByteArrayInputStream is = new ByteArrayInputStream(ba);
+ InputStream isNull = null;
+
+ try {
+ X500Principal xpr = new X500Principal(is);
+ assertNotNull("Null object returned", xpr);
+ byte[] resArray = xpr.getEncoded();
+ assertEquals(ba.length, resArray.length);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ X500Principal xpr = new X500Principal(isNull);
+ fail("NullPointerException wasn't thrown");
+ } catch (NullPointerException npe) {
+ } catch (Exception e) {
+ fail(e + " was thrown instead of NullPointerException");
+ }
+
+ is = new ByteArrayInputStream(name.getBytes());
+ try {
+ X500Principal xpr = new X500Principal(is);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException npe) {
+ } catch (Exception e) {
+ fail(e + " was thrown instead of IllegalArgumentException");
+ }
+ }
+
+ /**
+ * javax.security.auth.x500.X500Principal#X500Principal(byte[] name)
+ */
+ public void test_X500Principal_03() {
+ String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
+ byte[] ba = getByteArray(TestUtils.getX509Certificate_v1());
+ byte[] baNull = null;
+
+ try {
+ X500Principal xpr = new X500Principal(ba);
+ assertNotNull("Null object returned", xpr);
+ byte[] resArray = xpr.getEncoded();
+ assertEquals(ba.length, resArray.length);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ X500Principal xpr = new X500Principal(baNull);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException npe) {
+ } catch (Exception e) {
+ fail(e + " was thrown instead of IllegalArgumentException");
+ }
+
+ ba = name.getBytes();
+ try {
+ X500Principal xpr = new X500Principal(ba);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException npe) {
+ } catch (Exception e) {
+ fail(e + " was thrown instead of IllegalArgumentException");
+ }
+ }
+
+ /**
+ * javax.security.auth.x500.X500Principal#getName()
+ */
+ public void test_getName() {
+ String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
+ X500Principal xpr = new X500Principal(name);
+ try {
+ String resName = xpr.getName();
+ assertEquals(name, resName);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+ /**
+ * javax.security.auth.x500.X500Principal#getName(String format)
+ */
+ public void test_getName_Format() {
+ String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
+ String expectedName = "cn=duke,ou=javasoft,o=sun microsystems,c=us";
+ X500Principal xpr = new X500Principal(name);
+ try {
+ String resName = xpr.getName(X500Principal.CANONICAL);
+ assertEquals(expectedName, resName);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ expectedName = "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US";
+ try {
+ String resName = xpr.getName(X500Principal.RFC1779);
+ assertEquals(expectedName, resName);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ String resName = xpr.getName(X500Principal.RFC2253);
+ assertEquals(name, resName);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+
+ try {
+ String resName = xpr.getName(null);
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException iae) {
+ }
+ try {
+ String resName = xpr.getName("RFC2254");
+ fail("IllegalArgumentException wasn't thrown");
+ } catch (IllegalArgumentException iae) {
+ }
+ }
+
+ /**
+ * javax.security.auth.x500.X500Principal#hashCode()
+ */
+ public void test_hashCode() {
+ String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
+ X500Principal xpr = new X500Principal(name);
+ try {
+ int res = xpr.hashCode();
+ assertNotNull(res);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+ /**
+ * javax.security.auth.x500.X500Principal#toString()
+ */
+ public void test_toString() {
+ String name = "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US";
+ X500Principal xpr = new X500Principal(name);
+ try {
+ String res = xpr.toString();
+ assertNotNull(res);
+ assertEquals(name, res);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+ /**
+ * javax.security.auth.x500.X500Principal#getEncoded()
+ */
+ public void test_getEncoded() {
+ byte[] ba = getByteArray(TestUtils.getX509Certificate_v1());
+ X500Principal xpr = new X500Principal(ba);
+ try {
+ byte[] res = xpr.getEncoded();
+ assertNotNull(res);
+ assertEquals(ba.length, res.length);
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+ /**
+ * javax.security.auth.x500.X500Principal#equals(Object o)
+ */
+ public void test_equals() {
+ String name1 = "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US";
+ String name2 = "cn=duke,ou=javasoft,o=sun microsystems,c=us";
+ String name3 = "CN=Alex Astapchuk, OU=SSG, O=Intel ZAO, C=RU";
+ X500Principal xpr1 = new X500Principal(name1);
+ X500Principal xpr2 = new X500Principal(name2);
+ X500Principal xpr3 = new X500Principal(name3);
+ try {
+ assertTrue("False returned", xpr1.equals(xpr2));
+ assertFalse("True returned", xpr1.equals(xpr3));
+ } catch (Exception e) {
+ fail("Unexpected exception: " + e);
+ }
+ }
+
+ private byte[] getByteArray(byte[] array) {
+ byte[] x = null;
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(array);
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate)cf.generateCertificate(is);
+ X500Principal xx = cert.getIssuerX500Principal();
+ x = xx.getEncoded();
+ } catch (Exception e) {
+ return null;
+ }
+ return x;
+ }
+
+ /**
+ * @tests javax.security.auth.x500.X500Principal#X500Principal(java.lang.String)
+ */
+ public void test_ConstructorLjava_lang_String() {
+ X500Principal principal = new X500Principal(
+ "CN=Hermione Granger, O=Apache Software Foundation, OU=Harmony, L=Hogwarts, ST=Hants, C=GB");
+ String name = principal.getName();
+ String expectedOuput = "CN=Hermione Granger,O=Apache Software Foundation,OU=Harmony,L=Hogwarts,ST=Hants,C=GB";
+ assertEquals("Output order precedence problem", expectedOuput, name);
+ }
+
+ /**
+ * @tests javax.security.auth.x500.X500Principal#X500Principal(java.lang.String, java.util.Map)
+ */
+ public void test_ConstructorLjava_lang_String_java_util_Map() {
+ Map<String, String> keyword = new HashMap<String, String>();
+ keyword.put("CN", "2.19");
+ keyword.put("OU", "1.2.5.19");
+ keyword.put("O", "1.2.5");
+ X500Principal X500p = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US ,CN=DD", keyword);
+ String name = X500p.getName();
+ String expectedOut = "2.19=#130444756b65,1.2.5.19=#13084a617661536f6674,1.2.5=#131053756e204d6963726f73797374656d73,C=US,2.19=#13024444";
+ assertEquals("Output order precedence problem", expectedOut, name);
+ }
+
+ /**
+ * @tests javax.security.auth.x500.X500Principal#getName(java.lang.String)
+ */
+ public void test_getNameLjava_lang_String() {
+ X500Principal principal = new X500Principal(
+ "CN=Dumbledore, OU=Administration, O=Hogwarts School, C=GB");
+ String canonical = principal.getName(X500Principal.CANONICAL);
+ String expected = "cn=dumbledore,ou=administration,o=hogwarts school,c=gb";
+ assertEquals("CANONICAL output differs from expected result", expected,
+ canonical);
+ }
+
+ /**
+ * @tests javax.security.auth.x500.X500Principal#getName(java.lang.String, java.util.Map)
+ */
+ public void test_getNameLjava_lang_String_java_util_Map() {
+ Map<String, String> keyword = new HashMap<String, String>();
+ keyword.put("CN", "2.19");
+ keyword.put("OU", "1.2.5.19");
+ keyword.put("O", "1.2.5");
+ X500Principal X500p = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US ,CN=DD", keyword);
+ keyword = new HashMap<String, String>();
+ keyword.put("2.19", "mystring");
+ String rfc1779Name = X500p.getName("RFC1779", keyword);
+ String rfc2253Name = X500p.getName("RFC2253", keyword);
+ String expected1779Out = "mystring=Duke, OID.1.2.5.19=JavaSoft, OID.1.2.5=Sun Microsystems, C=US, mystring=DD";
+ String expected2253Out = "mystring=Duke,1.2.5.19=#13084a617661536f6674,1.2.5=#131053756e204d6963726f73797374656d73,C=US,mystring=DD";
+ assertEquals("Output order precedence problem", expected1779Out, rfc1779Name);
+ assertEquals("Output order precedence problem", expected2253Out, rfc2253Name);
+ try {
+ X500p.getName("CANONICAL", keyword);
+ fail("Should throw IllegalArgumentException exception here");
+ } catch (IllegalArgumentException e) {
+ //expected IllegalArgumentException here
+ }
+ }
+
+ private boolean testing = false;
+
+ public void testStreamPosition() throws Exception {
+ //this encoding is read from the file
+ /*byte [] mess = {0x30, 0x30,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
+ 1, 2, 3//extra bytes
+ };
+ */
+
+ InputStream is = Support_Resources
+ .getResourceStream("X500PrincipalTest.0.dat");
+ X500Principal principal = new X500Principal(is);
+ String s = principal.toString();
+ assertEquals("CN=A, CN=B, CN=A, CN=B", s);
+ byte[] restBytes = new byte[] { 0, 0, 0 };
+ is.read(restBytes);
+ assertEquals(restBytes[0], 1);
+ assertEquals(restBytes[1], 2);
+ assertEquals(restBytes[2], 3);
+ is.close();
+ }
+
+ public void testStreamPosition_0() throws Exception {
+ //this encoding is read from the file
+ /*byte [] mess = {0x30, 0x30,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
+ };
+ */
+
+ InputStream is = Support_Resources
+ .getResourceStream("X500PrincipalTest.1.dat");
+ X500Principal principal = new X500Principal(is);
+ String s = principal.toString();
+ assertEquals("CN=A, CN=B, CN=A, CN=B", s);
+ assertEquals(0, is.available());
+ is.close();
+ }
+
+ public void testStreamPosition_1() throws Exception {
+ byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
+ 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
+ 0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
+ 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 2,
+ 3, 4 };
+
+ ByteArrayInputStream is = new ByteArrayInputStream(mess);
+ X500Principal principal = new X500Principal(is);
+
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals(
+ "CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=Z",
+ s);
+ assertEquals(3, is.available());
+ assertEquals(2, is.read());
+ assertEquals(3, is.read());
+ assertEquals(4, is.read());
+ }
+
+ public void testStreamPosition_2() throws Exception {
+ byte[] mess = { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x41, 2 };
+ ByteArrayInputStream is = new ByteArrayInputStream(mess);
+ X500Principal principal = new X500Principal(is);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=A", s);
+ assertEquals(1, is.available());
+ assertEquals(2, is.read());
+ }
+
+ public void testEncodingFromFile() throws Exception {
+ //this encoding is read from the file
+ /*byte [] mess = {0x30, 0x30,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41
+ };
+ */
+ InputStream is = Support_Resources
+ .getResourceStream("X500PrincipalTest.1.dat");
+ X500Principal principal = new X500Principal(is);
+ String s = principal.toString();
+ assertEquals("CN=A, CN=B, CN=A, CN=B", s);
+ is.close();
+ }
+
+ public void testEncodingFromEncoding() {
+ byte[] arr1 = new X500Principal("O=Org.").getEncoded();
+ byte[] arr2 = new X500Principal(new X500Principal("O=Org.")
+ .getEncoded()).getEncoded();
+ assertTrue(Arrays.equals(arr1, arr2));
+ }
+
+ /**
+ * tests if the encoding is backed
+ */
+ public void testSafeEncoding() {
+ byte[] mess = { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x41 };
+ X500Principal principal = new X500Principal(mess);
+ mess[mess.length - 1] = (byte) 0xFF;
+ byte[] enc = principal.getEncoded();
+ assertEquals(enc[mess.length - 1], 0x41);
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * gets toString
+ * checks the result
+ */
+ public void testToString() throws Exception {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ X500Principal principal = new X500Principal(mess);
+ String s = principal.toString();
+ assertNotNull(s);
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * gets hashCode
+ * compares with expected value
+ */
+ public void testHashCode() throws Exception {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ X500Principal principal = new X500Principal(mess);
+ int hash = principal.hashCode();
+ assertEquals(principal.getName(X500Principal.CANONICAL).hashCode(),
+ hash);
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * Inits other X500Principal with equivalent string
+ * checks if <code>equals</code> returns true for first against second one
+ */
+ public void testEquals() throws Exception {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ X500Principal principal = new X500Principal(mess);
+ X500Principal principal2 = new X500Principal("CN=A, CN=B");
+ assertTrue(principal.equals(principal2));
+ }
+
+ /**
+ * @tests javax.security.auth.x500.X500Principal#equals(Object)
+ */
+ public void test_equalsLjava_lang_Object() {
+ X500Principal xp1 = new X500Principal(
+ "C=US, ST=California, L=San Diego, O=Apache, OU=Project Harmony, CN=Test cert");
+ assertEquals(
+ "C=US,ST=California,L=San Diego,O=Apache,OU=Project Harmony,CN=Test cert",
+ xp1.getName());
+ }
+
+ /**
+ * Inits X500Principal with byte array, where Oid does fall into any keyword, but not given as a keyword
+ * Value is given as hex value
+ * (extra spaces are given)
+ * gets Name in RFC1779 format
+ * compares with expected value of name
+ */
+ public void testKWAsOid_RFC1779() throws Exception {
+ String dn = "CN=A, OID.2.5.4.3 = #130142";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=A, CN=B", s);
+ }
+
+ /**
+ * Inits X500Principal with byte array, where Oid does fall into any keyword, but not given as a keyword
+ * Value is given as hex value
+ * (extra spaces are given)
+ * gets Name in RFC2253 format
+ * compares with expected value of name
+ */
+ public void testKWAsOid_RFC2253() throws Exception {
+ String dn = "CN=A, OID.2.5.4.3 = #130142";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=A,CN=B", s);
+ }
+
+ /**
+ * Inits X500Principal with byte array, where Oid does fall into any keyword, but not given as a keyword
+ * Value is given as hex value
+ * (extra spaces are given)
+ * gets Name in CANONICAL format
+ * compares with expected value of name
+ */
+ public void testKWAsOid_CANONICAL() throws Exception {
+ String dn = "CN=A, OID.2.5.4.3 = #130142";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a,cn=b", s);
+ }
+
+ /**
+ * Inits X500Principal with byte array, where Oid does not fall into any keyword
+ * gets Name in RFC1779 format
+ * compares with expected value of name
+ */
+ public void testOid_RFC1779() throws Exception {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[8] = 0x60;
+ X500Principal principal = new X500Principal(mess);
+
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=A, OID.2.16.4.3=B", s);
+ }
+
+ /**
+ * Inits X500Principal with byte array, where Oid does not fall into any keyword
+ * gets Name in RFC2253 format
+ * compares with expected value of name
+ */
+ public void testOid_RFC2253() throws Exception {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x4F, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[8] = 0x60;
+ X500Principal principal = new X500Principal(mess);
+
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=A,2.16.4.3=#13014f", s);
+ }
+
+ /**
+ * Inits X500Principal with byte array, where Oid does not fall into any keyword
+ * gets Name in CANONICAL format
+ * compares with expected value of name
+ */
+ public void testOid_CANONICAL() throws Exception {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x4F, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[8] = 0x60;
+ X500Principal principal = new X500Principal(mess);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a,2.16.4.3=#13014f", s);
+ }
+
+ /**
+ * Inits X500Principal with a string
+ * gets encoded form
+ * compares with expected byte array
+ */
+ public void testNameGetEncoding() throws Exception {
+ byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
+ 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
+ 0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
+ 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
+ String dn = "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z";
+ X500Principal principal = new X500Principal(dn);
+ byte[] s = principal.getEncoded();
+
+ assertTrue(Arrays.equals(mess, s));
+ }
+
+ /**
+ * Inits X500Principal with a string
+ * gets encoded form
+ * compares with expected byte array
+ */
+ public void testNameGetEncoding_01() throws Exception {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ String dn = "CN=A,CN=B";
+ X500Principal principal = new X500Principal(dn);
+ byte[] s = principal.getEncoded();
+
+ assertTrue(Arrays.equals(mess, s));
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * gets Name in RFC1779 format
+ * compares with expected value of name
+ */
+ public void testGetName_RFC1779() throws Exception {
+ byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
+ 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
+ 0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
+ 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
+ X500Principal principal = new X500Principal(mess);
+
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals(
+ "CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=Z",
+ s);
+
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * gets Name in RFC2253 format
+ * compares with expected value of name
+ */
+ public void testGetName_RFC2253() throws Exception {
+ byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
+ 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
+ 0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
+ 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
+ X500Principal principal = new X500Principal(mess);
+
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals(
+ "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z",
+ s);
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * gets Name in CANONICAL format
+ * compares with expected value of name
+ */
+ public void testGetName_CANONICAL() throws Exception {
+ byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
+ 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
+ 0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
+ 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
+ X500Principal principal = new X500Principal(mess);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals(
+ "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z"
+ .toLowerCase(Locale.US), s);
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * gets Name in RFC1779 format
+ * compares with expected value of name
+ */
+ public void testStreamGetName_RFC1779() throws Exception {
+ byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
+ 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
+ 0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
+ 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
+ ByteArrayInputStream is = new ByteArrayInputStream(mess);
+ X500Principal principal = new X500Principal(is);
+
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals(
+ "CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=Z",
+ s);
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * gets Name in RFC2253 format
+ * compares with expected value of name
+ */
+ public void testStreamGetName_RFC2253() throws Exception {
+ byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
+ 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
+ 0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
+ 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
+ ByteArrayInputStream is = new ByteArrayInputStream(mess);
+ X500Principal principal = new X500Principal(is);
+
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals(
+ "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z",
+ s);
+ }
+
+ /**
+ * Inits X500Principal with byte array
+ * gets Name in CANONICAL format
+ * compares with expected value of name
+ */
+ public void testStreamGetName_CANONICAL() throws Exception {
+ byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
+ 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
+ 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
+ 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
+ 0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
+ 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
+ ByteArrayInputStream is = new ByteArrayInputStream(mess);
+ X500Principal principal = new X500Principal(is);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals(
+ "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z"
+ .toLowerCase(Locale.US), s);
+ }
+
+ /**
+ * Inits X500Principal with a string, where OID does not fall into any keyword
+ * gets encoded form
+ * inits new X500Principal with the encoding
+ * gets string in RFC1779 format
+ * compares with expected value
+ */
+ public void testGetName_EncodingWithWrongOidButGoodName_SeveralRDNs_RFC1779()
+ throws Exception {
+ String dn = "OID.2.16.4.3=B; CN=A";
+ X500Principal principal = new X500Principal(dn);
+ byte[] enc = principal.getEncoded();
+ X500Principal principal2 = new X500Principal(enc);
+ String s = principal2.getName(X500Principal.RFC1779);
+ assertEquals("OID.2.16.4.3=B, CN=A", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, where OID does not fall into any keyword
+ * gets encoded form
+ * inits new X500Principal with the encoding
+ * gets string in RFC2253 format
+ * compares with expected value
+ */
+ public void testGetName_EncodingWithWrongOidButGoodName_SeveralRDNs_RFC2253()
+ throws Exception {
+ String dn = "OID.2.16.4.3=B; CN=A";
+ X500Principal principal = new X500Principal(dn);
+ byte[] enc = principal.getEncoded();
+ X500Principal principal2 = new X500Principal(enc);
+ String s = principal2.getName(X500Principal.RFC2253);
+ assertEquals("2.16.4.3=#130142,CN=A", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, where OID does not fall into any keyword
+ * gets encoded form
+ * inits new X500Principal with the encoding
+ * gets string in CANONICAL format
+ * compares with expected value
+ */
+ public void testGetName_EncodingWithWrongOidButGoodName_SeveralRDNs_CANONICAL()
+ throws Exception {
+ String dn = "OID.2.16.4.3=B; CN=A";
+ X500Principal principal = new X500Principal(dn);
+ byte[] enc = principal.getEncoded();
+ X500Principal principal2 = new X500Principal(enc);
+ String s = principal2.getName(X500Principal.CANONICAL);
+ assertEquals("2.16.4.3=#130142,cn=a", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, where OID does not fall into any keyword
+ * gets string in RFC1779 format
+ * compares with expected value
+ */
+ public void testGetName_wrongOidButGoodName_RFC1779() throws Exception {
+ String dn = "OID.2.16.4.3=B + CN=A";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("OID.2.16.4.3=B + CN=A", s);
+ }
+
+ /**
+ * Inits X500Principal with a string, where OID does not fall into any keyword
+ * gets string in RFC2253 format
+ * compares with expected value
+ */
+ public void testGetName_wrongOidButGoodName_RFC2253() throws Exception {
+ String dn = "OID.2.16.4.3=B + CN=A";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("2.16.4.3=#130142+CN=A", s);
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_CANONICAL_SortOrder() throws Exception {
+ String dn = "ST=C + CN=A; OU=B + CN=D";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a+st=c,cn=d+ou=b", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_CANONICAL_SortOrder_01() throws Exception {
+ String dn = "OID.2.16.4.3=B + CN=A";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a+2.16.4.3=#130142", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword, and value given in hex format
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_CANONICAL_SortOrder_02() throws Exception {
+ String dn = "OID.2.16.4.3=#13024220+ CN=A";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a+2.16.4.3=#13024220", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_CANONICAL_SortOrder_03() throws Exception {
+ String dn = "OID.2.16.4.9=A + OID.2.16.4.3=B";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("2.16.4.3=#130142+2.16.4.9=#130141", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_CANONICAL_SortOrder_04() throws Exception {
+ String dn = "OID.2.2.2.2=A + OID.1.1.1.1=B";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("1.1.1.1=#130142+2.2.2.2=#130141", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_CANONICAL_SortOrder_05() throws Exception {
+ String dn = "OID.2.16.4.9=A + OID.2.16.4=B";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("2.16.4=#130142+2.16.4.9=#130141", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_CANONICAL_SortOrder_06() throws Exception {
+ String dn = "OID.1.1.2=A + OID.1.2=B";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("1.1.2=#130141+1.2=#130142", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_CANONICAL_SortOrder_07() throws Exception {
+ String dn = "OID.1.1.1=A + OID.1.1=B";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("1.1=#130142+1.1.1=#130141", s);
+
+ }
+
+ /**
+ * FIXME test is failed - implement unicode normalization
+ *
+ * @throws Exception
+ */
+ public void testGetNameUnicodeNormalized() throws Exception {
+ String unicodeStr = "CN= \u0401\u0410";
+ X500Principal principal = new X500Principal(unicodeStr);
+ principal.getName(X500Principal.CANONICAL);
+ }
+
+ /**
+ * Inits X500Principal with empty string
+ * gets encoding
+ * compares with expected encoding
+ */
+ public void testEmptyInputName() {
+ String dn = "CN=\"\"";
+ byte[] mess = { 0x30, 0x0B, 0x31, 0x09, 0x30, 0x07, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x00 };
+ X500Principal principal = new X500Principal(dn);
+ assertTrue(Arrays.equals(mess, principal.getEncoded()));
+ }
+
+ /**
+ * Inits X500Principal with string as single escaped space
+ * gets encoding
+ * compares with expected encoding
+ */
+ public void testNameSingleEscapedSpace() {
+ String dn = "CN=\\ ";
+ byte[] mess = { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x20 };
+ X500Principal principal = new X500Principal(dn);
+ assertTrue(Arrays.equals(mess, principal.getEncoded()));
+ }
+
+ /**
+ * Inits X500Principal with string with spaces
+ * gets Name in RFC2253 format
+ * compares with expected value of name
+ */
+ public void testNameOnlySpaces_RFC1779() {
+ String dn = "CN=\" \"";
+ X500Principal principal = new X500Principal(dn);
+ assertEquals("CN=\" \"", principal.getName(X500Principal.RFC1779));
+ }
+
+ /**
+ * Inits X500Principal with string with spaces
+ * gets Name in RFC2253 format
+ * compares with expected value of name
+ */
+ public void testNameOnlySpaces_RFC2253() {
+ String dn = "CN=\" \"";
+ X500Principal principal = new X500Principal(dn);
+ assertEquals("CN=\\ \\ ", principal.getName(X500Principal.RFC2253));
+ }
+
+ /**
+ * Inits X500Principal with string with only spaces,
+ * gets Name in CANONICAL format:leading and trailing white space
+ * chars are removed even string doesn't have other chars (bug???)
+ */
+ public void testNameOnlySpaces_CANONICAL() {
+ String dn = "CN=\" \"";
+ X500Principal principal = new X500Principal(dn);
+ assertEquals("cn=", principal.getName(X500Principal.CANONICAL));
+ }
+
+ ///*** Negative Tests ***///
+
+ /**
+ * Inits X500Principal with string, where DN name is improper "CNN"
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName() {
+ try {
+ String dn = "CNN=A";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper input name \"CNN\"");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string, where there is leading ';'
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_01() {
+ try {
+ String dn = ";CN=A";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on leading ';' in input name");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string, where there is leading '='
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_02() {
+ try {
+ String dn = "=CN=A";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on leading '=' in input name");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string, where there is no value
+ * checks if proper exception is thrown
+ */
+ public void testEmptyInputName_0() {
+ String dn = "CN=";
+ byte[] mess = { 0x30, 0x0B, 0x31, 0x09, 0x30, 0x07, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x00 };
+ X500Principal principal = new X500Principal(dn);
+ assertTrue(Arrays.equals(mess, principal.getEncoded()));
+ }
+
+ public void testEmptyInputName_1() {
+ String dn = "CN=\"\", C=\"\"";
+ X500Principal principal = new X500Principal(dn);
+ dn = "CN=, C=";
+ X500Principal principal2 = new X500Principal(dn);
+ assertTrue(Arrays.equals(principal.getEncoded(), principal2
+ .getEncoded()));
+
+ }
+
+ public void testEmptyInputName_2() {
+ String dn = "CN=\"\" + OU=A, C=\"\"";
+ X500Principal principal = new X500Principal(dn);
+ dn = "CN=+OU=A, C=";
+ X500Principal principal2 = new X500Principal(dn);
+ assertTrue(Arrays.equals(principal.getEncoded(), principal2
+ .getEncoded()));
+
+ }
+
+ public void testIllegalInputName_15() {
+ try {
+ String dn = "CN=,C";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper attribute value");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testIllegalInputName_16() {
+ try {
+ String dn = "CN=,C=+";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper attribute value");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given in wrong hex format
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_04() {
+ try {
+ String dn = "CN=#XYZ";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper hex value");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with special chars
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_05() {
+ try {
+ String dn = "CN=X+YZ";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper attribute value");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with special chars
+ * Compatibility issue: according RFC 2253 such string is invalid
+ * but we accept it, not string char is escaped
+ */
+ public void testIllegalInputName_06() {
+ String dn = "CN=X=YZ";
+ X500Principal p = new X500Principal(dn);
+ assertEquals("CN=X\\=YZ", p.getName(X500Principal.RFC2253));
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with not string chars
+ * Compatibility issue: according RFC 2253 such string is invalid
+ * but we accept it, not string char is escaped
+ */
+ public void testIllegalInputName_07() {
+ String dn = "CN=X\"YZ";
+ X500Principal p = new X500Principal(dn);
+ assertEquals("CN=X\\\"YZ", p.getName(X500Principal.RFC2253));
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with special chars
+ * Compatibility issue: according RFC 2253 such string is invalid
+ * but we accept it, special char is escaped
+ */
+ public void testIllegalInputName_08() {
+ String dn = "CN=X<YZ";
+ X500Principal p = new X500Principal(dn);
+ assertEquals("CN=X\\<YZ", p.getName(X500Principal.RFC2253));
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with special chars
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_09() {
+ try {
+ String dn = "CN=#";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper attribute hex value");
+ } catch (IllegalArgumentException e) {
+ //ignore
+ }
+
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with special chars
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_10() {
+ try {
+ String dn = "CN=#13";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper attribute hex value");
+ } catch (IllegalArgumentException e) {
+ //ignore
+ }
+
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with special chars
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_11() {
+ try {
+ String dn = "CN=#1301";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper attribute hex value");
+ } catch (IllegalArgumentException e) {
+ //ignore
+ }
+
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with special chars
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_12() {
+ try {
+ String dn = "CN=#13010101";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper attribute hex value");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given with special chars
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputName_13() {
+ try {
+ String dn = "CN=# 0";
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper attribute hex value");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string, where value is given in hex format, but improper tag
+ * checks if it is ignored
+ */
+ public void testSemiIllegalInputName_14() {
+ String dn = "CN=#7E0142";
+ new X500Principal(dn);
+ }
+
+ public void testInitClause() {
+ try {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[3] = 0x12;//length field
+ new X500Principal(mess);
+
+ fail("No IllegalArgumentException on input array with improper length field");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with byte array = null
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputArray_0() {
+ try {
+ byte[] mess = null;
+ new X500Principal(mess);
+ fail("No IllegalArgumentException on input array with improper length field");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with byte array with wrong length field
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputArray() {
+ try {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[3] = 0x12;//length field
+ new X500Principal(mess);
+
+ fail("No IllegalArgumentException on input array with improper length field");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with input stream with wrong length field
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputArray_is() {
+ try {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[3] = 0x12;//length field
+ ByteArrayInputStream is = new ByteArrayInputStream(mess);
+ new X500Principal(is);
+
+ fail("No IllegalArgumentException on input array with improper length field");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with byte array with wrong inner Sequence tag field
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputArray_01() {
+ try {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[4] = 0x12;//inner Sequence tag field
+ new X500Principal(mess);
+
+ fail("No IllegalArgumentException on input array with improper inner Sequence tag field");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with byte array with wrong last byte of OID
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputArray_02() {
+ try {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[10] = (byte) 0xFE;//last byte of OID
+ new X500Principal(mess);
+
+ fail("No IllegalArgumentException on input array with improper last byte of OID");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with byte array with wrong length of OID
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputArray_03() {
+ try {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[7] = 2;//length of OID
+ new X500Principal(mess);
+
+ fail("No IllegalArgumentException on input array with improper length of OID");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with byte array with wrong tag of value
+ * checks if it is ignored
+ */
+ public void testSemiIllegalInputArray_04() {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[11] = (byte) 0x0F;//tag of value
+ new X500Principal(mess);
+ }
+
+ /**
+ * Inits X500Principal with byte array with wrong length of value
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputArray_05() {
+ try {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[12] = 2;//length of value
+ new X500Principal(mess);
+
+ fail("No IllegalArgumentException on input array with improper length of value");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with input stream with wrong length of value
+ * checks if proper exception is thrown
+ */
+ public void testIllegalInputArray_05_is() {
+ try {
+ byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
+ mess[12] = 2;//length of value
+ ByteArrayInputStream is = new ByteArrayInputStream(mess);
+ new X500Principal(is);
+
+ fail("No IllegalArgumentException on input array with improper length of value");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with string
+ * Calls getName with improper parameter as format
+ * checks if proper exception is thrown
+ */
+ public void testIllegalFormat() {
+ try {
+ String dn = "CN=A";
+ X500Principal principal = new X500Principal(dn);
+ principal.getName("WRONG FORMAT");
+ fail("No IllegalArgumentException on improper parameter as format");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
+ * Gets encoding
+ * Inits other X500Principal with the encoding
+ * gets string in RFC1779 format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_EncodingWithWrongOidButGoodName_MultAVA_RFC1779()
+ throws Exception {
+ String dn = "OID.2.16.4.3=B + CN=A";
+ X500Principal principal = new X500Principal(dn);
+ byte[] enc = principal.getEncoded();
+ X500Principal principal2 = new X500Principal(enc);
+ String s = principal2.getName(X500Principal.RFC1779);
+ assertEquals("OID.2.16.4.3=B + CN=A", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
+ * Gets encoding
+ * Inits other X500Principal with the encoding
+ * gets string in RFC2253 format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_EncodingWithWrongOidButGoodName_MultAVA_RFC2253()
+ throws Exception {
+ String dn = "OID.2.16.4.3=B + CN=A";
+ X500Principal principal = new X500Principal(dn);
+ byte[] enc = principal.getEncoded();
+ X500Principal principal2 = new X500Principal(enc);
+ String s = principal2.getName(X500Principal.RFC2253);
+ assertEquals("2.16.4.3=#130142+CN=A", s);
+
+ }
+
+ /**
+ * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
+ * Gets encoding
+ * Inits other X500Principal with the encoding
+ * gets string in CANONICAL format
+ * compares with expected value paying attention on sorting order of AVAs
+ */
+ public void testGetName_EncodingWithWrongOidButGoodName_MultAVA_CANONICAL()
+ throws Exception {
+ String dn = "OID.2.16.4.3=B + CN=A";
+ X500Principal principal = new X500Principal(dn);
+ byte[] enc = principal.getEncoded();
+ X500Principal principal2 = new X500Principal(enc);
+ String s = principal2.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a+2.16.4.3=#130142", s);
+
+ }
+
+ /**
+ * Inits X500Principal with byte array, where there are leading and tailing spaces
+ * gets Name in RFC1779 format
+ * compares with expected value of name
+ */
+ public void testNameSpaceFromEncoding_RFC1779() throws Exception {
+ byte[] mess = { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x03, 0x20, 0x41, 0x20, };
+ X500Principal principal = new X500Principal(mess);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\" A \"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with byte array, where there are leading and tailing spaces
+ * gets Name in RFC2253 format
+ * compares with expected value of name
+ */
+ public void testNameSpaceFromEncoding_RFC2253() throws Exception {
+ byte[] mess = { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x03, 0x20, 0x41, 0x20, };
+ X500Principal principal = new X500Principal(mess);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=\\ A\\ ", s);
+
+ }
+
+ /**
+ * Inits X500Principal with byte array, where there are leading and tailing spaces
+ * gets Name in CANONICAL format
+ * compares with expected value of name
+ */
+ public void testNameSpaceFromEncoding_CANONICAL() throws Exception {
+ byte[] mess = { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x03, 0x20, 0x41, 0x20, };
+ X500Principal principal = new X500Principal(mess);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a", s);
+
+ }
+
+ /**
+ * Inits X500Principal with byte array, where there are special characters
+ * gets Name in RFC1779 format
+ * compares with expected value of name, checks if the string is in quotes
+ */
+ public void testNameSpecialCharsFromEncoding_RFC1779() throws Exception {
+ byte[] mess = { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x0C, 0x02, 0x3B, 0x2C };
+ X500Principal principal = new X500Principal(mess);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\";,\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with byte array, where there are special characters
+ * gets Name in RFC1779 format
+ * compares with expected value of name, checks if the characters are escaped
+ */
+ public void testNameSpecialCharsFromEncoding_RFC2253() throws Exception {
+ byte[] mess = { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x0C, 0x02, 0x3B, 0x2C };
+ X500Principal principal = new X500Principal(mess);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=\\;\\,", s);
+
+ }
+
+ /**
+ * Inits X500Principal with byte array, where there are special characters
+ * gets Name in CANONICAL format
+ * compares with expected value of name, checks if the characters are escaped
+ */
+ public void testNameSpecialCharsFromEncoding_CANONICAL() throws Exception {
+ byte[] mess = { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x0C, 0x02, 0x3B, 0x2C };
+ X500Principal principal = new X500Principal(mess);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=\\;\\,", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \"B
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "\B"
+ */
+ public void testNameSpecialChars_RFC1779() throws Exception {
+ String dn = "CN=A,CN=\\\"B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=A, CN=\"\\\"B\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \"B
+ * gets Name in RFC2253 format
+ * compares with expected value of name - "\B"
+ */
+ public void testNameSpecialChars_RFC2253() throws Exception {
+ String dn = "CN=A,CN=\\\"B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=A,CN=\\\"B", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \"B
+ * gets Name in CANONICAL format
+ * compares with expected value of name - "\b"
+ */
+ public void testNameSpecialChars_CANONICAL() throws Exception {
+ String dn = "CN=A,CN=\\\"B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a,cn=\\\"b", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\nB
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "\nB"
+ */
+ public void testNameSpecialChars_RFC1779_01() throws Exception {
+ //FIXME see testNameSpecialChars_RFC2253_01
+ // String dn = "CN=\\\nB";
+ // X500Principal principal = new X500Principal(dn);
+ // String s = principal.getName(X500Principal.RFC1779);
+ // assertEquals("CN=\"\nB\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\nB
+ * gets Name in RFC2253 format
+ * compares with expected value of name - \\nB
+ */
+ public void testNameSpecialChars_RFC2253_01() throws Exception {
+
+ try {
+ // compatibility issue:
+ // don't accept escaped \n because it is not a special char
+ new X500Principal("CN=\\\nB");
+ fail("No expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\nB
+ * gets Name in CANONICAL format
+ * compares with expected value of name - \\nb
+ */
+ public void testNameSpecialChars_CANONICAL_01() throws Exception {
+ //FIXME testNameSpecialChars_RFC2253_01
+ // String dn = "CN=\\\nB";
+ // X500Principal principal = new X500Principal(dn);
+ // String s = principal.getName(X500Principal.CANONICAL);
+ // assertEquals("cn=b", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\B
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "\B"
+ */
+ public void testNameSpecialChars_RFC1779_02() throws Exception {
+ String dn = "CN=\\\\B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"\\\\B\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\B
+ * gets Name in RFC2253 format
+ * compares with expected value of name - \\B
+ */
+ public void testNameSpecialChars_RFC2253_02() throws Exception {
+ String dn = "CN=\\\\B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=\\\\B", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\B
+ * gets Name in CANONICAL format
+ * compares with expected value of name - \\b
+ */
+ public void testNameSpecialChars_CANONICAL_02() throws Exception {
+ String dn = "CN=\\\\B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=\\\\b", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"DEF"
+ * gets encoding
+ * compares with expected encoding
+ */
+ public void testNameWithQuotation() throws Exception {
+ String dn = "CN=\"ABCDEF\"";
+
+ X500Principal principal = new X500Principal(dn);
+ byte[] enc = principal.getEncoded();
+ assertTrue(Arrays.equals(new byte[] { 0x30, 0x11, 0x31, 0x0F, 0x30,
+ 0x0D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x06, 0x41, 0x42,
+ 0x43, 0x44, 0x45, 0x46 }, enc));
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "ABCDEF
+ * checks if the proper exception is thrown
+ */
+ public void testNameWithQuotation_01() throws Exception {
+ String dn = "CN=\"ABCDEF";
+ try {
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on string with no closing quotations");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"D#EF"
+ * gets encoding
+ * compares with expected encoding
+ */
+ public void testNameWithQuotation_02() throws Exception {
+ String dn = "CN=\"ABCD#EF\"";
+ X500Principal principal = new X500Principal(dn);
+ byte[] enc = principal.getEncoded();
+ assertTrue(Arrays.equals(new byte[] { 0x30, 0x12, 0x31, 0x10, 0x30,
+ 0x0E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x07, 0x41, 0x42,
+ 0x43, 0x44, 0x23, 0x45, 0x46 }, enc));
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"DEF"
+ * Compatibility issue: according RFC 2253 such string is invalid
+ * but we accept it, not string char is escaped
+ */
+ public void testNameWithQuotation_03() throws Exception {
+ String dn = "CN=ABC\"DEF\"";
+ X500Principal principal = new X500Principal(dn);
+ assertEquals("CN=ABC\\\"DEF\\\"", principal
+ .getName(X500Principal.RFC2253));
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"DEF"
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "ABCDEF"
+ */
+ public void testNameSpecialChars_RFC1779_03() throws Exception {
+ String dn = "CN=\"ABCDEF\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=ABCDEF", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"DEF"
+ * gets Name in RFC2253 format
+ * compares with expected value of name - ABC"DEF"
+ */
+ public void testNameSpecialChars_RFC2253_03() throws Exception {
+ String dn = "CN=\"ABCDEF\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=ABCDEF", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"DEF"
+ * gets Name in CANONICAL format
+ * compares with expected value of name - abc"def"
+ */
+ public void testNameSpecialChars_CANONICAL_03() throws Exception {
+ String dn = "CN=\"ABCDEF\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=abcdef", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"D#EF"
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "ABCD#EF"
+ */
+ public void testNameSpecialChars_RFC1779_04() throws Exception {
+ String dn = "CN=\"ABCD#EF\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"ABCD#EF\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"D#EF"
+ * gets Name in RFC1779 format
+ * compares with expected value of name - ABCD\#EF
+ */
+ public void testNameSpecialChars_RFC2253_04() throws Exception {
+ String dn = "CN=\"ABCD#EF\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=ABCD\\#EF", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ABC"D#EF"
+ * gets Name in RFC1779 format
+ * compares with expected value of name - abc"d#ef"
+ */
+ public void testNameSpecialChars_CANONICAL_04() throws Exception {
+ String dn = "CN=\"ABCD#EF\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=abcd#ef", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - X#YZ
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "X#YZ"
+ */
+ public void testNameSpecialChars_RFC1779_05() {
+ String dn = "CN=X#YZ";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"X#YZ\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - X#YZ
+ * gets Name in RFC2253 format
+ * compares with expected value of name - X\#YZ
+ */
+ public void testNameSpecialChars_RFC2253_05() {
+ String dn = "CN=X#YZ";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.RFC2253);
+
+ assertEquals("CN=X\\#YZ", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - X#YZ
+ * gets Name in CANONICAL format
+ * compares with expected value of name - x#yz
+ */
+ public void testNameSpecialChars_CANONICAL_05() {
+ String dn = "CN=X#YZ";
+ X500Principal principal = new X500Principal(dn);
+
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=x#yz", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - CN=\#XYZ
+ * gets Name in RFC1779 format
+ * compares with expected value of name - CN="#XYZ"
+ */
+ public void testNameSpecialChars_RFC1779_6() throws Exception {
+ String dn = "CN=\\#XYZ";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"#XYZ\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - CN=\#XYZ
+ * gets Name in RFC2253 format
+ * compares with expected value of name - CN=\#XYZ
+ */
+ public void testNameSpecialChars_RFC2253_6() throws Exception {
+ String dn = "CN=\\#XYZ";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=\\#XYZ", s);
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - CN=\#XYZ
+ * gets Name in CANONICAL format
+ * compares with expected value of name - cn=\#xyz
+ */
+ public void testNameSpecialChars_CANONICAL_6() throws Exception {
+ String dn = "CN=\\#XYZ";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=\\#xyz", s);
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - B\'space'
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "B "
+ */
+ public void testNameSpaces_RFC1779() throws Exception {
+ String dn = "CN=A,CN=B\\ ";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=A, CN=\"B \"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - B\'space'
+ * gets Name in RFC2253 format
+ * compares with expected value of name - B\'space'
+ */
+ public void testNameSpaces_RFC2253() throws Exception {
+ String dn = "CN=A,CN=B\\ ";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=A,CN=B\\ ", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - B\'space'
+ * gets Name in CANONICAL format
+ * compares with expected value of name - B\
+ */
+ public void testNameSpaces_CANONICAL() throws Exception {
+ String dn = "CN=A,CN=B\\ ";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a,cn=b", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "B'space''space''space'A"
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "B A"
+ */
+ public void testNameSpaces_RFC1779_01() throws Exception {
+ String dn = "CN=\"B A\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"B A\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "B'space''space''space'A"
+ * gets Name in 2253 format
+ * compares with expected value of name - B'space''space''space'A
+ */
+ public void testNameSpaces_RFC2253_01() throws Exception {
+ String dn = "CN=\"B A\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=B A", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "B'space''space''space'A"
+ * gets Name in CANONICAL format
+ * compares with expected value of name - b'space'a
+ */
+ public void testNameSpaces_CANONICAL_01() throws Exception {
+ String dn = "CN=\"B A\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=b a", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\'space''space'B
+ * gets Name in RFC1779 format
+ * compares with expected value of name - " B"
+ */
+ public void testNameSpaces_RFC1779_02() throws Exception {
+ String dn = "CN=\\ B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\" B\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\'space''space'B
+ * gets Name in RFC1779 format
+ * compares with expected value of name - \'space''space'B
+ */
+ public void testNameSpaces_RFC2253_02() throws Exception {
+ String dn = "CN=\\ B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=\\ \\ B", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - \\'space''space'B
+ * gets Name in CANONICAL format
+ * compares with expected value of name - \'space''space'b
+ */
+ public void testNameSpaces_CANONICAL_02() throws Exception {
+ String dn = "CN=\\ B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=b", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - ""B
+ * checks if the proper exception is thrown
+ */
+ public void testNameQu() throws Exception {
+ String dn = "CN=\"\"B";
+ try {
+ new X500Principal(dn);
+ fail("No IllegalArgumentException on improper string");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "A\"B"
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "A\"B"
+ */
+ public void testNameQu_RFC1779_2() throws Exception {
+ String dn = "CN=\"A\\\"B\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"A\\\"B\"", s);
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "A\"B"
+ * gets Name in RFC2253 format
+ * compares with expected value of name - A\"B
+ */
+ public void testNameQu_RFC2253_2() throws Exception {
+ String dn = "CN=\"A\\\"B\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=A\\\"B", s);
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "A\"B"
+ * gets Name in CANONICAL format
+ * compares with expected value of name - a\"b
+ */
+ public void testNameQu_CANONICAL_2() throws Exception {
+ String dn = "CN=\"A\\\"B\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a\\\"b", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "A\""
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "A\""
+ */
+ public void testNameQu_RFC1779_3() throws Exception {
+ String dn = "CN=\"A\\\"\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"A\\\"\"", s);
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "A\""
+ * gets Name in RFC2253 format
+ * compares with expected value of name - A\"
+ */
+ public void testNameQu_RFC2253_3() throws Exception {
+ String dn = "CN=\"A\\\"\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=A\\\"", s);
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "A\""
+ * gets Name in CANONICAL format
+ * compares with expected value of name - A\"
+ */
+ public void testNameQu_CANONICAL_3() throws Exception {
+ String dn = "CN=\"A\\\"\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a\\\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - "A\", C=B"
+ * gets Name in RFC1779 format
+ * compares with expected value of name - "A\", C=B"
+ */
+ public void testNameQu_4() throws Exception {
+ String dn = "CN=\"A\\\", C=B\"";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"A\\\", C=B\"", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - CN="A\\", C=B
+ * gets Name in RFC1779 format
+ * compares with expected value of name - CN="A\\", C=B
+ */
+ public void testNameQu_5() throws Exception {
+ String dn = "CN=\"A\\\\\", C=B";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=\"A\\\\\", C=B", s);
+
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - CN=A\nB
+ * gets Name in RFC1779 format
+ * compares with expected value of name - CN="A\nB"
+ */
+ public void testNameCR_RFC1779() throws Exception {
+ String dn = "CN=A\nB";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC1779);
+ assertEquals("CN=A\nB", s);
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - CN=A\nB
+ * gets Name in RFC2253 format
+ * compares with expected value of name - CN=A\nB
+ */
+ public void testNameCR_RFC2253() throws Exception {
+ String dn = "CN=A\nB";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.RFC2253);
+ assertEquals("CN=A\nB", s);
+ }
+
+ /**
+ * Inits X500Principal with the string with special characters - CN=A\nB
+ * gets Name in CANONICAL format
+ * compares with expected value of name - cn=a\nb
+ */
+ public void testNameCR_CANONICAL() throws Exception {
+ String dn = "CN=A\nB";
+ X500Principal principal = new X500Principal(dn);
+ String s = principal.getName(X500Principal.CANONICAL);
+ assertEquals("cn=a\nb", s);
+ }
+
+ public static final String[] RFC2253_SPECIAL = new String[] { ",", "=",
+ "+", "<", ">", "#", ";" };
+
+ public void testValidDN() throws Exception {
+
+ TestList list = new TestList();
+
+ list.add("", "", "", "", new byte[] { 0x30, 0x00 }); // empty RDN sequence
+
+ // sequence of RDN: RDN *("," RDN)
+ list.add("CN=A,C=B", "CN=A,C=B", "CN=A, C=B", "cn=a,c=b");
+ list.add("C=B,CN=A", "C=B,CN=A", "C=B, CN=A", "c=b,cn=a");
+ list.add("CN=A,CN=A", "CN=A,CN=A", "CN=A, CN=A", "cn=a,cn=a"); // duplicate RDNs
+
+ // sequence of RDN: RFC 1779 compatibility
+ list.add("CN=A , C=B", "CN=A,C=B", "CN=A, C=B");
+ list.add("CN=A , C=B", "CN=A,C=B", "CN=A, C=B");
+ list.add("CN=A;C=B", "CN=A,C=B", "CN=A, C=B");
+ list.add("CN=A ; C=B", "CN=A,C=B", "CN=A, C=B");
+ //FIXME list.add("CN=A\r,\rC=B", "CN=A,C=B"); // <CR> & comma => comma
+ list.add(" CN=A,C=B ", "CN=A,C=B", "CN=A, C=B"); // spaces at beg&end
+ list.add(" CN=A,C=\"B\" ", "CN=A,C=B", "CN=A, C=B"); // spaces at beg&end
+
+ // set of ATAV: ATAV *("+" ATAV)
+ list.add("CN=A+ST=CA", "CN=A+ST=CA", "CN=A + ST=CA", "cn=a+st=ca");
+ list.add("CN=A+CN=A", "CN=A+CN=A", "CN=A + CN=A", "cn=a+cn=a"); // duplicate AT
+ list
+ .add("2.5.4.3=A+2.5.4.3=A", "CN=A+CN=A", "CN=A + CN=A",
+ "cn=a+cn=a"); // duplicate AT
+
+ // set of ATAV: RFC 1779 compatibility
+ list.add("CN=A + ST=CA", "CN=A+ST=CA", "CN=A + ST=CA");
+ list.add("CN=A + ST=CA", "CN=A+ST=CA", "CN=A + ST=CA");
+ //FIXME list.add("CN=A\r+\rST=CA", "CN=A+ST=CA"); // <CR> & '+' => '+'
+
+ // ATAV = AttributeType "=" AttributeValue
+ list.add("CN=A", "CN=A", "CN=A");
+ list.add("cn=A", "CN=A", "CN=A"); // AT case insensitive
+ list.add("cN=A", "CN=A", "CN=A"); // AT case insensitive
+ list.add("cn=a", "CN=a", "CN=a"); // AT case insensitive
+
+ // ATAV : RFC 1779 compatibility
+ list.add("CN = A", "CN=A", "CN=A");
+ list.add("CN = A", "CN=A", "CN=A");
+ // FIXME list.add("CN\r=\rA", "CN=A"); // <CR> & '=' => '='
+
+ // AttributeType = <name string> | <OID>
+ // testing OID case : OID => <name string>
+ // tested all OIDs from RFC 2253 (2.3) and RFC 1779 (Table 1)
+
+ // different variants of 2.5.4.3 (CN) OID
+ list.add("OID.2.5.4.3=A", "CN=A", "CN=A");
+ list.add("oid.2.5.4.3=A", "CN=A", "CN=A");
+ list.add("2.5.4.3=A", "CN=A", "CN=A");
+ list.add("02.5.4.3=A", "CN=A", "CN=A"); // first: 02 => 2
+ list.add("2.5.4.0003=A", "CN=A", "CN=A"); // last: 0003 => 3
+
+ // the rest of OIDs
+ list.add("2.5.4.7=A", "L=A", "L=A", "l=a");
+ list.add("2.5.4.8=A", "ST=A", "ST=A", "st=a");
+ list.add("2.5.4.10=A", "O=A", "O=A", "o=a");
+ list.add("2.5.4.11=A", "OU=A", "OU=A", "ou=a");
+ list.add("2.5.4.6=A", "C=A", "C=A", "c=a");
+ list.add("2.5.4.9=A", "STREET=A", "STREET=A", "street=a");
+ list.add("0.9.2342.19200300.100.1.25=A", "DC=A",
+ "OID.0.9.2342.19200300.100.1.25=A", "dc=#160141");
+ list.add("0.9.2342.19200300.100.1.1=A", "UID=A",
+ "OID.0.9.2342.19200300.100.1.1=A", "uid=a");
+
+ // attribute types from RFC 2459 (see Appendix A)
+ // keywords are from the API spec
+ list.add("T=A", "2.5.4.12=#130141", "OID.2.5.4.12=A",
+ "2.5.4.12=#130141");
+ list.add("DNQ=A", "2.5.4.46=#130141", "OID.2.5.4.46=A",
+ "2.5.4.46=#130141");
+ list.add("DNQUALIFIER=A", "2.5.4.46=#130141", "OID.2.5.4.46=A",
+ "2.5.4.46=#130141");
+ list.add("SURNAME=A", "2.5.4.4=#130141", "OID.2.5.4.4=A",
+ "2.5.4.4=#130141");
+ list.add("GIVENNAME=A", "2.5.4.42=#130141", "OID.2.5.4.42=A",
+ "2.5.4.42=#130141");
+ list.add("INITIALS=A", "2.5.4.43=#130141", "OID.2.5.4.43=A",
+ "2.5.4.43=#130141");
+ list.add("GENERATION=A", "2.5.4.44=#130141", "OID.2.5.4.44=A",
+ "2.5.4.44=#130141");
+ list.add("EMAILADDRESS=A", "1.2.840.113549.1.9.1=#160141",
+ "OID.1.2.840.113549.1.9.1=A", "1.2.840.113549.1.9.1=#160141",
+ null, (byte) 0x05); //FIXME bug???
+ list.add("SERIALNUMBER=A", "2.5.4.5=#130141", "OID.2.5.4.5=A",
+ "2.5.4.5=#130141");
+
+ // AttributeValue => BER encoding (if OID in dotted-decimal form)
+ // see RFC 2253 (2.4)
+ list.add("OID.2.5.4.12=A", "2.5.4.12=#130141", "OID.2.5.4.12=A");
+ list.add("oid.2.5.4.12=A", "2.5.4.12=#130141", "OID.2.5.4.12=A");
+ list.add("2.5.4.12=A", "2.5.4.12=#130141", "OID.2.5.4.12=A");
+ list.add("1.1=A", "1.1=#130141", "OID.1.1=A");
+
+ //
+ // AttributeValue first alternative : *( stringchar / pair )
+ // testing pair characters.
+ //
+ // Note: for RFC1779 quoted string is returned (unspecified)
+ //
+ list.add("CN=", "CN=", "CN="); // zero string chars
+ list.add("CN= ", "CN=", "CN="); // zero string chars
+ list.add("CN=A+ST=", "CN=A+ST=", "CN=A + ST="); // zero string chars
+ list.add("CN=+ST=A", "CN=+ST=A", "CN= + ST=A"); // empty value for 1 RDN
+ list.add("CN=A+ST= ", "CN=A+ST=", "CN=A + ST="); // empty value for 1 RDN
+ list.add("CN=+ST=", "CN=+ST=", "CN= + ST="); // empty value for both RDNs
+ list.add("CN=,ST=B", "CN=,ST=B", "CN=, ST=B"); // empty value for 1 RDN
+ list.add("CN=,ST=", "CN=,ST=", "CN=, ST="); // empty value for both RDNs
+ list.add("CN=;ST=B", "CN=,ST=B", "CN=, ST=B"); // empty value for 1 RDN
+ list.add("CN=;ST=", "CN=,ST=", "CN=, ST="); // empty value for both RDNs
+ for (String element : RFC2253_SPECIAL) {
+ // \special
+ list.add("CN=\\" + element,
+ "CN=\\" + element, "CN=\"" + element
+ + "\"");
+
+ // A + \special + B
+ list.add("CN=A\\" + element + "B", "CN=A\\"
+ + element + "B", "CN=\"A" + element
+ + "B\"");
+ }
+
+ // pair = \"
+ list.add("CN=\\\"", "CN=\\\"", "CN=\"\\\"\"", null, (byte) 0x02);
+ list.add("CN=\\\"A", "CN=\\\"A", "CN=\"\\\"A\"", null, (byte) 0x02);
+ list.add("CN=\\\",C=\\\"", "CN=\\\",C=\\\"", "CN=\"\\\"\", C=\"\\\"\"",
+ null, (byte) 0x02); // 2 RDN
+ list.add("CN=A\\\"B", "CN=A\\\"B", "CN=\"A\\\"B\"", null, (byte) 0x02); // A\"B
+ list.add("CN=A ST=B", "CN=A ST\\=B", "CN=\"A ST=B\""); // no RDN separator
+
+ // pair = \space
+ list.add("CN=\\ ", "CN=\\ ", "CN=\" \"", "cn=");
+
+ // pair = \hexpair
+ list.add("CN=\\41", "CN=A", "CN=A"); // 0x41=='A'
+ list.add("CN=\\41\\2C", "CN=A\\,", "CN=\"A,\""); // 0x41=='A', 0x2C=','
+ list.add("CN=\\41\\2c", "CN=A\\,", "CN=\"A,\""); // 0x41=='A', 0x2c=','
+ list.add("CN=\\D0\\AF", "CN=" + ((char) 1071), "CN=" + ((char) 1071),
+ new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8 String
+ 0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }); // 0xD0AF == the last letter(capital) of Russian alphabet
+ list.add("CN=\\D0\\AFA\\41", "CN=" + ((char) 1071) + "AA", "CN="
+ + ((char) 1071) + "AA", new byte[] { 0x30, 0x0F, 0x31, 0x0D,
+ 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03,
+ // UTF8 String
+ 0x0C, 0x04, (byte) 0xD0, (byte) 0xAF, 0x41, 0x41 }); // 0xD0AF == the last letter(capital) of Russian alphabet
+ // UTF-8(0xE090AF) is non-shortest form of UTF-8(0xD0AF)
+ //FIXME list.add("CN=\\E0\\90\\AF", "CN=" + ((char) 1071), "CN="
+ // + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
+ // 0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
+ // // UTF8 String
+ // 0x0C, 0x02, (byte) 0xD0, (byte) 0xAF });
+ // UTF-8(0xF08090AF) is non-shortest form of UTF-8(0xD0AF)
+ //FIXME list.add("CN=\\F0\\80\\90\\AF", "CN=" + ((char) 1071), "CN="
+ // + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
+ // 0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
+ // // UTF8 String
+ // 0x0C, 0x02, (byte) 0xD0, (byte) 0xAF });
+ //FIXME list.add("CN=\\D0", "CN=" + ((char) 65533), "CN=" + ((char) 65533),
+ // new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ // 0x55, 0x04, 0x03,
+ // // UTF8 String
+ // 0x0C, 0x01, 0x3F }); // 0xD0 is not correct UTF8 char => '?'
+ list.add("CN=\\41+ST=A", "CN=A+ST=A", "CN=A + ST=A"); // 0x41=='A'
+ list.add("CN=\\41\\2C+ST=A", "CN=A\\,+ST=A", "CN=\"A,\" + ST=A"); // 0x41=='A', 0x2C=','
+ list.add("CN=\\41\\2c+ST=A", "CN=A\\,+ST=A", "CN=\"A,\" + ST=A"); // 0x41=='A', 0x2c=','
+
+ // stringchar '=' or not leading '#'
+ //FIXME RFC 2253 grammar violation: '=' and '#' is a special char
+ list.add("CN==", "CN=\\=", "CN=\"=\"");
+ list.add("CN=A=", "CN=A\\=", "CN=\"A=\"");
+ list.add("CN=A#", "CN=A\\#", "CN=\"A#\"");
+
+ // not leading or trailing spaces
+ list.add("CN=A B", "CN=A B", "CN=A B", "cn=a b");
+ list.add("CN=A\\ B", "CN=A B", "CN=A B", "cn=a b");
+ list.add("CN=A \\,B", "CN=A \\,B", "CN=\"A ,B\"", "cn=a \\,b");
+
+ //not alphabet chars
+ list.add("CN=$", "CN=$", "CN=$", new byte[] { 0x30, 0x0C, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
+ //UTF-8 String: "$"
+ 0x0C, 0x01, 0x24 });
+ list.add("CN=(", "CN=(", "CN=(", new byte[] { 0x30, 0x0C, 0x31, 0x0A,
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
+ //PrintableString: "("
+ 0x13, 0x01, 0x28 });
+
+ //
+ //
+ // AttributeValue second alternative : "#" hexstring
+ //
+ //
+ list.add("CN=#130141", "CN=A", "CN=A", "cn=a"); // ASN1 Printable hex string = 'A'
+ list.add("CN=#140141", "CN=A", "CN=A", "cn=a", new byte[] { 0x30,
+ 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x14, 0x01, 0x41 }); // ASN1 Teletex hex string = 'A'
+
+ list.add("CN=#010100", "CN=#010100", "CN=#010100", "cn=#010100"); // ASN1 Boolean = FALSE
+ list.add("CN=#0101fF", "CN=#0101ff", "CN=#0101FF", "cn=#0101ff"); // ASN1 Boolean = TRUE
+ //FIXME list.add("CN=#3000", "CN=#3000", "CN=#3000"); // ASN1 Sequence
+ //FIXME list.add("CN=#0500", "CN=A", "CN=A"); // ASN1 Null
+ list.add("CN= #0101fF", "CN=#0101ff", "CN=#0101FF", // space at beginning
+ new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x01, 0x01, (byte) 0xFF } // ASN.1 Boolean = TRUE
+ );
+ list.add("CN= #0101fF+ST=A", "CN=#0101ff+ST=A", "CN=#0101FF + ST=A",
+ "cn=#0101ff+st=a"); //space
+ list.add("CN= #0101fF ", "CN=#0101ff", "CN=#0101FF", // space at the end
+ new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x01, 0x01, (byte) 0xFF } // ASN.1 Boolean = TRUE
+ , (byte) 0x00);
+
+ //FIXME unspecified output for RFC1779
+ //FIXME list.add("CN=#1C0141", "CN=A", "CN=A"); // ASN1 Universal hex string = 'A'
+ //FIXME list.add("CN=#1E0141", "CN=A", "CN=A"); // ASN1 Bmp hex string = 'A'
+
+ //
+ // AttributeValue third alternative : " *( quotechar / pair ) "
+ // quotechar = <any character except '\' or '"' >
+ //
+ // Note:
+ // RFC2253: passed quoted AV string is unquoted, special chars are escaped
+ // RFC1779: escaped quoted chars are unescaped
+ //
+ list.add("CN=\"\"", "CN=", "CN="); // empty quoted string
+ list.add("CN=\"A\"", "CN=A", "CN=A"); // "A"
+ for (String element : RFC2253_SPECIAL) {
+ // "special" => \special
+ list.add("CN=\"" + element + "\"", "CN=\\"
+ + element, "CN=\"" + element + "\"");
+
+ // "A + special + B" => A + \special + B
+ list.add("CN=\"A" + element + "B\"", "CN=A\\"
+ + element + "B", "CN=\"A" + element
+ + "B\"");
+ }
+ for (String element : RFC2253_SPECIAL) {
+ // "\special" => \special
+ list.add("CN=\"\\" + element + "\"", "CN=\\"
+ + element, "CN=\"" + element + "\"");
+
+ // "A + \special + B" => A + \special + B
+ list.add("CN=\"A\\" + element + "B\"", "CN=A\\"
+ + element + "B", "CN=\"A" + element
+ + "B\"");
+ }
+ list.add("CN=\"\\\"\"", "CN=\\\"", "CN=\"\\\"\"", null, (byte) 0x02); // "\""
+ list.add("CN=\"A\\\"B\"", "CN=A\\\"B", "CN=\"A\\\"B\"", null,
+ (byte) 0x02); // "A\"B"
+
+ // pair = \hexpair (test cases are the same as for the first alternative)
+ list.add("CN=\"\\41\"", "CN=A", "CN=A"); // 0x41=='A'
+ list.add("CN=\"\\41\\2C\"", "CN=A\\,", "CN=\"A,\""); // 0x41=='A', 0x2C=','
+ list.add("CN=\"\\41\\2c\"", "CN=A\\,", "CN=\"A,\""); // 0x41=='A', 0x2c=','
+ list.add("CN=\"\\D0\\AF\"", "CN=" + ((char) 1071), "CN="
+ + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
+ // UTF8 String
+ 0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }); // 0xD0AF == the last letter(capital) of Russian alphabet
+ list.add("CN=\"\\D0\\AFA\\41\"", "CN=" + ((char) 1071) + "AA", "CN="
+ + ((char) 1071) + "AA", new byte[] { 0x30, 0x0F, 0x31, 0x0D,
+ 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03,
+ // UTF8 String
+ 0x0C, 0x04, (byte) 0xD0, (byte) 0xAF, 0x41, 0x41 }); // 0xD0AF == the last letter(capital) of Russian alphabet
+ list.add("CN=\"\\E0\\90\\AF\"", "CN=" + ((char) 1071), "CN="
+ + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
+ // UTF8 String
+ 0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }); // UTF8(0xE090AF that is not quite correct)== UTF8(0xD0AF) == the last letter(capital) of Russian alphabet
+ list.add("CN=\"\\F0\\80\\90\\AF\"", "CN=" + ((char) 1071), "CN="
+ + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
+ // UTF8 String
+ 0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }); // UTF8(0xF08090AF that is not quite correct)== UTF8(0xD0AF) == the last letter(capital) of Russian alphabet
+
+ list.add("CN=\"\\41\"+ST=A", "CN=A+ST=A", "CN=A + ST=A"); // 0x41=='A'
+ list.add("CN=\"\\41\\2C\"+ST=A", "CN=A\\,+ST=A", "CN=\"A,\" + ST=A"); // 0x41=='A', 0x2C=','
+ list.add("CN=\"\\41\\2c\"+ST=A", "CN=A\\,+ST=A", "CN=\"A,\" + ST=A"); // 0x41=='A', 0x2c=','
+
+ // AttributeValue third alternative : RFC 1779 compatibility
+ //FIXME list.add("CN=\"\r\"", "CN=\"\r\""); // "<CR>"
+ //FIXME list.add("CN=\"\\\r\"", "CN=\"\\\r\""); // "\<CR>"
+
+ // AttributeValue : RFC 1779 compatibility
+ list.add("CN= A ", "CN=A", "CN=A", "cn=a"); // leading & trailing spaces
+ list.add("CN=\\ A ", "CN=\\ \\ A", "CN=\" A\"", "cn=a", null,
+ (byte) 0x01); // escaped leading space
+ list.add("CN= A \\ ", "CN=A\\ \\ ", "CN=\"A \"", "cn=a", null,
+ (byte) 0x01); // escaped trailing space
+
+ list.add("CN= \"A\" ", "CN=A", "CN=A", "cn=a"); // leading & trailing spaces
+
+ StringBuffer errorMsg = new StringBuffer();
+ for (int i = 0; i < list.size(); i++) {
+
+ Object[] obj = list.get(i);
+
+ String dn = (String) obj[0];
+ String rfc2253 = (String) obj[1];
+ String rfc1779 = (String) obj[2];
+ String canonical = (String) obj[3];
+ byte[] encoded = (byte[]) obj[4];
+ byte mask = ((byte[]) obj[5])[0];
+
+ try {
+ X500Principal p = new X500Principal(dn);
+ if (!rfc2253.equals(p.getName(X500Principal.RFC2253))) {
+ if (!testing || ((mask & 0x01) == 0)) {
+
+ errorMsg.append("\nRFC2253: " + i);
+ errorMsg.append(" \tparm: '" + dn + "'");
+ errorMsg.append("\t\texpected: '" + rfc2253 + "'");
+ errorMsg.append("\treturned: '"
+ + p.getName(X500Principal.RFC2253) + "'");
+ }
+ }
+
+ if (!rfc1779.equals(p.getName(X500Principal.RFC1779))) {
+ if (!testing || ((mask & 0x02) == 0)) {
+
+ errorMsg.append("\nRFC1779: " + i);
+ errorMsg.append(" \tparm: '" + dn + "'");
+ errorMsg.append("\t\texpected: '" + rfc1779 + "'");
+ errorMsg.append("\treturned: '"
+ + p.getName(X500Principal.RFC1779) + "'");
+ }
+ }
+
+ if (canonical != null) {
+ if (!canonical.equals(p.getName(X500Principal.CANONICAL))) {
+ if (!testing || ((mask & 0x04) == 0)) {
+
+ errorMsg.append("\nCANONICAL: " + i);
+ errorMsg.append("\tparm: '" + dn + "'");
+ errorMsg.append("\t\texpected: '" + canonical + "'");
+ errorMsg.append("\treturned: '"
+ + p.getName(X500Principal.CANONICAL) + "'");
+ }
+ }
+ }
+
+ if (encoded != null) {
+ if (!Arrays.equals(encoded, p.getEncoded())) {
+ if (!testing || ((mask & 0x08) == 0)) {
+
+ errorMsg.append("\nUnexpected encoding for: " + i
+ + ", dn= '" + dn + "'");
+
+ System.out.println("\nI " + i);
+ byte[] enc = p.getEncoded();
+ for (byte element : enc) {
+ System.out.print(", 0x"
+ + Integer.toHexString(element));
+ }
+ }
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ errorMsg.append("\nIllegalArgumentException: " + i);
+ errorMsg.append("\tparm: '" + dn + "'");
+ } catch (Exception e) {
+ errorMsg.append("\nException: " + i);
+ errorMsg.append("\tparm: '" + dn + "'");
+ errorMsg.append("\texcep: " + e.getClass().getName());
+ }
+ }
+
+ if (errorMsg.length() != 0) {
+ fail(errorMsg.toString());
+ }
+
+ }
+
+ public void testInvalidDN() {
+ String[] illegalDN = new String[] {
+ // RDN
+ //FIXME " ", // space only
+ "CN", // attribute type only
+ "CN=A;", // RFC 1779: BNF allows this, but ...
+ "CN=A,", // RFC 1779: BNF allows this, but ...
+ ",CN=A", // no AttributeType for first RDN
+ "CN=,A", // no AttributeType for second RDN
+ "CN=A+", // no AttributeTypeAndValue for second RDN
+ "CN=#130141 ST=B", // no RDN separator
+
+ // AttributeType = <name string> | <OID>
+ "AAA=A", // no such <name string>
+ "1..1=A", // wrong OID
+ ".1.1=A", // wrong OID
+ "11=A", // wrong OID
+ "1=A", // wrong OID
+ "AID.1.1=A", // wrong OID
+ "1.50=A", // wrong OID
+ "5.1.0=A", // wrong OID
+ "2.-5.4.3=A", // wrong OID
+ "2.5.-4.3=A", // wrong OID
+ "2.5.4-.3=A", // wrong OID
+ //FIXME "2.5.4.-3=A", // wrong OID
+
+ // AttributeValue first alternative : *( stringchar / pair )
+ "CN=,", // stringchar = ','
+ //FIXME "CN==",
+ "CN=+", // stringchar = '+'
+ //FIXME "CN=<", // stringchar = '<'
+ //FIXME "CN=>", // stringchar = '>'
+ "CN=#", // stringchar = '#'
+ //FIXME "CN=Z#", // stringchar = '#'
+ "CN=;", // stringchar = ';'
+ "CN=\"", // stringchar = "
+ //FIXME "CN=A\"B", // stringchar = "
+ "CN=\\", // stringchar = \
+ "CN=A\\", // stringchar = \
+ "CN=A\\B", // stringchar = \
+ "CN=\\z", // invalid pair = \z
+ "CN=\\4", // invalid pair = \4
+ "CN=\\4Z", // invalid pair = \4Z
+ "CN=\\4\\2c", // invalid pair = \4\2c
+
+ // AttributeValue second alternative : "#" hexstring
+ "CN=#", // no hex string
+ "CN=#2", // no hex pair
+ "CN=#22", // hexpair is not BER encoding
+ "CN=#0001", // invalid BER encoding (missed content)
+ "CN=#000201", // invalid BER encoding (wrong length)
+ "CN=#0002010101", // invalid BER encoding (wrong length)
+ "CN=#00FF", // invalid BER encoding (wrong length)
+ "CN=#ZZ", // not hex pair
+
+ // FIXME boolean with indefinite length
+ //"CN=#0100010000", // invalid BER encoding (wrong length)
+
+ // AttributeValue third alternative : " *( quotechar / pair ) "
+ "CN=\"A\" B", // TODO comment me
+ "CN=\"A\\", // TODO comment me
+ "CN=\"\\4\"", // invalid pair = \4
+ "CN=\"\\4Z\"", // invalid pair = \4Z
+ "CN=\"\\4\\2c\"", // invalid pair = \4\2c
+ };
+
+ StringBuffer errorMsg = new StringBuffer();
+ for (String element : illegalDN) {
+
+ try {
+ new X500Principal(element);
+ errorMsg.append("No IllegalArgumentException: '" + element
+ + "'\n");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ if (errorMsg.length() != 0) {
+ fail(errorMsg.toString());
+ }
+ }
+
+ public void testValidEncoding() {
+ TestList list = new TestList();
+
+ //
+ // Empty
+ //
+ list.add(new byte[] { 0x30, 0x00 }, "", "", "");
+ list.add(new byte[] { 0x30, 0x02, 0x31, 0x00 }, "", "", ""); //??? invalid size constraints
+
+ //
+ // Known OID + string with different tags(all string)
+ //
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // PrintableString
+ 0x13, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // TeletexString
+ 0x14, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
+ //FIXME:compatibility list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ // 0x55, 0x04, 0x03,
+ // // UniversalString
+ // 0x1C, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String
+ 0x0C, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
+ //FIXME:compatibility list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ // 0x55, 0x04, 0x03,
+ // // BMPString
+ // 0x1E, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
+
+ //
+ // Unknown OID + string with different tags(all string)
+ //
+ list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ 0x00,
+ // PrintableString
+ 0x13, 0x01, 0x5A }, "0.0=#13015a", "OID.0.0=Z", "0.0=#13015a");
+ list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ 0x00,
+ // TeletexString
+ 0x14, 0x01, 0x5A }, "0.0=#14015a", "OID.0.0=Z", "0.0=#14015a");
+ //FIXME:compatibility list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ // 0x00,
+ // // UniversalString
+ // 0x1C, 0x01, 0x5A }, "0.0=#1c015a", "OID.0.0=Z", "cn=z");
+ list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ 0x00,
+ // UTF8String
+ 0x0C, 0x01, 0x5A }, "0.0=#0c015a", "OID.0.0=Z", "0.0=#0c015a");
+ //FIXME:compatibility list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ // 0x00,
+ // // BMPString
+ // 0x1E, 0x01, 0x5A }, "0.0=#1e015a", "OID.0.0=Z", "cn=z");
+
+ //
+ // Known OID + not a string value
+ //
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // Boolean
+ 0x01, 0x01, (byte) 0xFF }, "CN=#0101ff", "CN=#0101FF",
+ "cn=#0101ff");
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // Integer
+ 0x02, 0x01, 0x0F }, "CN=#02010f", "CN=#02010F", "cn=#02010f");
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // BitString
+ 0x03, 0x01, 0x00 }, "CN=#030100", "CN=#030100", "cn=#030100");
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // SEQUENCE
+ 0x30, 0x01, 0x0A }, "CN=#30010a", "CN=#30010A", "cn=#30010a");
+
+ //
+ // unknown OID + not a string value
+ //
+ list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ 0x00,
+ // Boolean
+ 0x01, 0x01, (byte) 0xFF }, "0.0=#0101ff", "OID.0.0=#0101FF",
+ "0.0=#0101ff");
+ list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ 0x00,
+ // Integer
+ 0x02, 0x01, 0x0F }, "0.0=#02010f", "OID.0.0=#02010F",
+ "0.0=#02010f");
+ list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ 0x00,
+ // BitString
+ 0x03, 0x01, 0x00 }, "0.0=#030100", "OID.0.0=#030100",
+ "0.0=#030100");
+ list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
+ 0x00,
+ // SEQUENCE
+ 0x30, 0x01, 0x0A }, "0.0=#30010a", "OID.0.0=#30010A",
+ "0.0=#30010a");
+
+ //
+ // Known OID + UTF-8 string with chars to be escaped
+ //
+
+ // spaces
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: a single space char
+ 0x0C, 0x01, 0x20 }, "CN=\\ ", "CN=\" \"", "cn=");
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: a space char at the beginning
+ 0x0C, 0x02, 0x20, 0x5A }, "CN=\\ Z", "CN=\" Z\"", "cn=z");
+ list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: two space chars at the beginning
+ 0x0C, 0x03, 0x20, 0x20, 0x5A }, "CN=\\ \\ Z", "CN=\" Z\"",
+ "cn=z", (byte) 0x01);
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: a space char at the end
+ 0x0C, 0x02, 0x5A, 0x20 }, "CN=Z\\ ", "CN=\"Z \"", "cn=z");
+ list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: two space chars at the end
+ 0x0C, 0x03, 0x5A, 0x20, 0x20 }, "CN=Z\\ \\ ", "CN=\"Z \"",
+ "cn=z", (byte) 0x01);
+
+ // special chars
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: a '#' char at the beginning
+ 0x0C, 0x02, 0x23, 0x5A }, "CN=\\#Z", "CN=\"#Z\"", "cn=\\#z");
+ list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: two '#' chars
+ 0x0C, 0x03, 0x23, 0x5A, 0x23 }, "CN=\\#Z\\#", "CN=\"#Z#\"",
+ "cn=\\#z#");
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: ','
+ 0x0C, 0x02, 0x5A, 0x2C }, "CN=Z\\,", "CN=\"Z,\"", "cn=z\\,");
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: '+'
+ 0x0C, 0x02, 0x5A, 0x2B }, "CN=Z\\+", "CN=\"Z+\"", "cn=z\\+");
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: '"'
+ 0x0C, 0x02, 0x5A, 0x22 }, "CN=Z\\\"", "CN=\"Z\\\"\"",
+ "cn=z\\\"", (byte) 0x02);
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: '\'
+ 0x0C, 0x02, 0x5A, 0x5C }, "CN=Z\\\\", "CN=\"Z\\\\\"",
+ "cn=z\\\\", (byte) 0x02);
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: '<'
+ 0x0C, 0x02, 0x5A, 0x3C }, "CN=Z\\<", "CN=\"Z<\"", "cn=z\\<");
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: '>'
+ 0x0C, 0x02, 0x5A, 0x3E }, "CN=Z\\>", "CN=\"Z>\"", "cn=z\\>");
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: ';'
+ 0x0C, 0x02, 0x5A, 0x3B }, "CN=Z\\;", "CN=\"Z;\"", "cn=z\\;");
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: '='
+ 0x0C, 0x02, 0x5A, 0x3D }, "CN=Z\\=", "CN=\"Z=\"", "cn=z=");
+ //FIXME list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ // 0x55, 0x04, 0x03,
+ // // UTF8String: ';'
+ // 0x0C, 0x02, 0x5A, 0x0D }, "CN=Z\\\r", "CN=\"Z\r\"", "cn=z");
+
+ // combinations
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: '\ '
+ 0x0C, 0x02, 0x5C, 0x20 }, "CN=\\\\\\ ", "CN=\"\\\\ \"",
+ "cn=\\\\", (byte) 0x02);
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: ' \'
+ 0x0C, 0x02, 0x20, 0x5C }, "CN=\\ \\\\", "CN=\" \\\\\"",
+ "cn=\\\\", (byte) 0x02);
+ list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: ' \ '
+ 0x0C, 0x03, 0x20, 0x5C, 0x20 }, "CN=\\ \\\\\\ ",
+ "CN=\" \\\\ \"", "cn=\\\\", (byte) 0x02);
+ list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: 'Z Z' no escaping
+ 0x0C, 0x03, 0x5A, 0x20, 0x5A }, "CN=Z Z", "CN=Z Z", "cn=z z");
+ list.add(new byte[] { 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: 'Z Z' no escaping
+ 0x0C, 0x04, 0x5A, 0x20, 0x20, 0x5A }, "CN=Z Z", "CN=\"Z Z\"",
+ "cn=z z", (byte) 0x02);
+ list.add(new byte[] { 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: ' #Z ' no escaping
+ 0x0C, 0x04, 0x20, 0x23, 0x5A, 0x20 }, "CN=\\ \\#Z\\ ",
+ "CN=\" #Z \"", "cn=#z");
+
+ //
+ // Special cases
+ //
+ // list.add(new byte[] {
+ // // Name
+ // 0x30, 0x13, 0x31, 0x11, 0x30, 0x0F,
+ // // OID
+ // 0x06, 0x0A, 0x09, (byte) 0x92, 0x26, (byte) 0x89, (byte) 0x93,
+ // (byte) 0xF2, 0x2C, 0x64, 0x01, 0x01,
+ // // ANY
+ // 0x13, 0x01, 0x41 }, "UID=A", "OID.0.9.2342.19200300.100.1.1=A",
+ // "uid=a");
+ //
+ // list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ // 0x55, 0x04, 0x03, 0x1E, 0x01, 0x5A }, "CN=Z", "CN=Z",
+ // "cn=#1e015a");
+
+ //
+ // Multi-valued DN
+ //
+ list.add(new byte[] { 0x30, 0x14, 0x31, 0x12,
+ // 1
+ 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
+ // UTF8String: 'Z'
+ 0x0C, 0x01, 0x5A,
+ //2
+ 0x30, 0x06, 0x06, 0x01, 0x01,
+ // UTF8String: 'A'
+ 0x0C, 0x01, 0x41 }, "CN=Z+0.1=#0c0141", "CN=Z + OID.0.1=A",
+ "cn=z+0.1=#0c0141");
+
+ //
+ //
+ //
+ list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // UTF8String: the last letter(capital) of Russian alphabet
+ 0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }, "CN=" + ((char) 1071),
+ "CN=" + ((char) 1071), "cn=" + ((char) 1103));
+ // FIXME list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
+ // 0x55, 0x04, 0x03,
+ // // UTF8String: the last letter(capital) of Russian alphabet
+ // 0x0C, 0x03, (byte) 0xE0, (byte) 0x90, (byte) 0xAF }, "CN="
+ // + ((char) 1071), "CN=" + ((char) 1071), "cn=" + ((char) 1103));
+ // FIXME list.add(
+ // new byte[] { 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03,
+ // 0x55, 0x04, 0x03,
+ // // UTF8String: the last letter(capital) of Russian alphabet
+ // 0x0C, 0x04, (byte) 0xF0, (byte) 0x80, (byte) 0x90,
+ // (byte) 0xAF }, "CN=" + ((char) 1071), "CN="
+ // + ((char) 1071), "cn=" + ((char) 1103));
+ list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
+ 0x55, 0x04, 0x03,
+ // PrintableString: char '$' is not in table 8 (X.680)
+ 0x13, 0x01, 0x24 }, "CN=$", "CN=$", "cn=$");
+
+ StringBuffer errorMsg = new StringBuffer();
+ for (int i = 0; i < list.size(); i++) {
+
+ Object[] values = list.get(i);
+ byte[] encoded = (byte[]) values[0];
+ String rfc2253 = (String) values[1];
+ String rfc1179 = (String) values[2];
+ String canonical = (String) values[3];
+ byte mask = ((byte[]) values[4])[0];
+
+ X500Principal p;
+ try {
+ p = new X500Principal(encoded);
+
+ if (!rfc2253.equals(p.getName(X500Principal.RFC2253))) {
+ if (!testing || ((mask & 0x01) == 0)) {
+ errorMsg.append("RFC2253: " + i);
+ errorMsg.append("\t\texpected: '" + rfc2253 + "'");
+ errorMsg.append("\treturned: '"
+ + p.getName(X500Principal.RFC2253) + "'\n");
+ }
+ }
+
+ if (!rfc1179.equals(p.getName(X500Principal.RFC1779))) {
+ if (!testing || ((mask & 0x02) == 0)) {
+ errorMsg.append("RFC1779: " + i);
+ errorMsg.append("\t\texpected: '" + rfc1179 + "'");
+ errorMsg.append("\treturned: '"
+ + p.getName(X500Principal.RFC1779) + "'\n");
+ }
+ }
+
+ if (!canonical.equals(p.getName(X500Principal.CANONICAL))) {
+ if (!testing || ((mask & 0x04) == 0)) {
+ errorMsg.append("CANONICAL: " + i);
+ errorMsg.append("\t\texpected: " + canonical + "'");
+ errorMsg.append("\treturned: '"
+ + p.getName(X500Principal.CANONICAL) + "'\n");
+ }
+ }
+
+ } catch (IllegalArgumentException e) {
+ errorMsg.append("\nIllegalArgumentException: " + i + ", for "
+ + rfc2253);
+ continue;
+ } catch (Exception e) {
+ errorMsg.append("Exception: " + i + ", for " + rfc2253);
+ errorMsg.append("\texcep: " + e.getClass().getName() + "\n");
+ continue;
+ }
+
+ }
+
+ if (errorMsg.length() != 0) {
+ fail(errorMsg.toString());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public static class TestList extends ArrayList<Object[]> {
+ //
+ // TODO comment me
+ //
+ public void add(String param, String rfc2253, String rfc1779) {
+ add(param, rfc2253, rfc1779, (byte[]) null);
+ }
+
+ public void add(String param, String rfc2253, String rfc1779,
+ String canonical) {
+ add(param, rfc2253, rfc1779, canonical, null);
+ }
+
+ public void add(String param, String rfc2253, String rfc1779,
+ byte[] encoded) {
+ add(new Object[] { param, rfc2253, rfc1779, null, encoded,
+ emptyMask });
+ }
+
+ public void add(String param, String rfc2253, String rfc1779,
+ byte[] encoded, byte mask) {
+ add(new Object[] { param, rfc2253, rfc1779, null, encoded,
+ new byte[] { mask } });
+ }
+
+ public void add(String param, String rfc2253, String rfc1779,
+ String canonical, byte[] encoded) {
+ add(new Object[] { param, rfc2253, rfc1779, canonical, encoded,
+ emptyMask });
+ }
+
+ public void add(String param, String rfc2253, String rfc1779,
+ String canonical, byte[] encoded, byte mask) {
+ add(new Object[] { param, rfc2253, rfc1779, canonical, encoded,
+ new byte[] { mask } });
+ }
+
+ //
+ // TODO comment me
+ //
+
+ private static final byte[] emptyMask = new byte[] { 0x00 };
+
+ public void add(byte[] encoding, String rfc2253, String rfc1779,
+ String canonical) {
+ add(new Object[] { encoding, rfc2253, rfc1779, canonical, emptyMask });
+ }
+
+ public void add(byte[] encoding, String rfc2253, String rfc1779,
+ String canonical, byte mask) {
+ add(new Object[] { encoding, rfc2253, rfc1779, canonical,
+ new byte[] { mask } });
+ }
+ }
+
+
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(getSerializationData());
+ }
+
+ public void testSerializationGolden() throws Exception {
+ SerializationTest.verifyGolden(this, getSerializationData());
+ }
+
+ private Object[] getSerializationData() {
+ return new Object[] { new X500Principal("CN=A"),
+ new X500Principal("CN=A, C=B"),
+ new X500Principal("CN=A, CN=B + C=C") };
+ }
+}
+
diff --git a/luni/src/test/java/tests/api/javax/security/cert/CertificateEncodingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateEncodingExceptionTest.java
index 53fbd9f..53fbd9f 100644
--- a/luni/src/test/java/tests/api/javax/security/cert/CertificateEncodingExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateEncodingExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/security/cert/CertificateExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateExceptionTest.java
index ccc3a2c..ccc3a2c 100644
--- a/luni/src/test/java/tests/api/javax/security/cert/CertificateExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/security/cert/CertificateExpiredExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateExpiredExceptionTest.java
index d0e94e3..d0e94e3 100644
--- a/luni/src/test/java/tests/api/javax/security/cert/CertificateExpiredExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateExpiredExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/security/cert/CertificateNotYetValidExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateNotYetValidExceptionTest.java
index c746648..c746648 100644
--- a/luni/src/test/java/tests/api/javax/security/cert/CertificateNotYetValidExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateNotYetValidExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/security/cert/CertificateParsingExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateParsingExceptionTest.java
index bc07ff6..bc07ff6 100644
--- a/luni/src/test/java/tests/api/javax/security/cert/CertificateParsingExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateParsingExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/security/cert/CertificateTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateTest.java
index da1c7a0..da1c7a0 100644
--- a/luni/src/test/java/tests/api/javax/security/cert/CertificateTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/CertificateTest.java
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java
new file mode 100644
index 0000000..64bfbb3
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/cert/X509CertificateTest.java
@@ -0,0 +1,785 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexander Y. Kleymenov
+ * @version $Revision$
+ */
+
+package tests.api.javax.security.cert;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import tests.targets.security.cert.CertificateFactoryTestX509;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.SignatureException;
+import java.security.Provider.Service;
+import java.security.cert.CertificateFactory;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.security.cert.Certificate;
+import javax.security.cert.CertificateEncodingException;
+import javax.security.cert.CertificateException;
+import javax.security.cert.CertificateExpiredException;
+import javax.security.cert.CertificateNotYetValidException;
+import javax.security.cert.X509Certificate;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import tests.targets.security.cert.CertificateFactoryTestX509;
+
+/**
+ */
+public class X509CertificateTest extends TestCase {
+
+ // Testing data was generated by using of classes
+ // from org.apache.harmony.security.asn1 package encoded
+ // by org.apache.harmony.misc.Base64 class.
+
+ private static String base64cert = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIC+jCCAragAwIBAgICAiswDAYHKoZIzjgEAwEBADAdMRswGQYDVQQKExJDZXJ0a"
+ + "WZpY2F0ZSBJc3N1ZXIwIhgPMTk3MDAxMTIxMzQ2NDBaGA8xOTcwMDEyNDAzMzMyMF"
+ + "owHzEdMBsGA1UEChMUU3ViamVjdCBPcmdhbml6YXRpb24wGTAMBgcqhkjOOAQDAQE"
+ + "AAwkAAQIDBAUGBwiBAgCqggIAVaOCAhQwggIQMA8GA1UdDwEB/wQFAwMBqoAwEgYD"
+ + "VR0TAQH/BAgwBgEB/wIBBTAUBgNVHSABAf8ECjAIMAYGBFUdIAAwZwYDVR0RAQH/B"
+ + "F0wW4EMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBcxFTATBgNVBAoTDE9yZ2FuaXphdG"
+ + "lvboYaaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWSHBP///wCIByoDolyDsgMwDAY"
+ + "DVR0eAQH/BAIwADAMBgNVHSQBAf8EAjAAMIGZBgNVHSUBAf8EgY4wgYsGBFUdJQAG"
+ + "CCsGAQUFBwMBBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDB"
+ + "AYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUFBw"
+ + "MJBggrBgEFBQgCAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GA1UdNgEB/wQDAgE"
+ + "BMA4GBCpNhgkBAf8EAwEBATBkBgNVHRIEXTBbgQxyZmNAODIyLk5hbWWCB2ROU05h"
+ + "bWWkFzEVMBMGA1UEChMMT3JnYW5pemF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvd"
+ + "XJjZS5JZIcE////AIgHKgOiXIOyAzAJBgNVHR8EAjAAMAoGA1UdIwQDAQEBMAoGA1"
+ + "UdDgQDAQEBMAoGA1UdIQQDAQEBMAwGByqGSM44BAMBAQADMAAwLQIUAL4QvoazNWP"
+ + "7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
+ + "-----END CERTIFICATE-----";
+
+ /*
+ * a self-signed certificate
+ */
+ private static final String selfSignedCert = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDPzCCAqigAwIBAgIBADANBgkqhkiG9w0BAQUFADB5MQswCQYDVQQGEwJBTjEQ" +
+ "MA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5k" +
+ "cm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBh" +
+ "bmRyb2lkLmNvbTAeFw0wOTAzMjAxNzAwMDZaFw0xMjAzMTkxNzAwMDZaMHkxCzAJ" +
+ "BgNVBAYTAkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQKEwdBbmRyb2lkMRAw" +
+ "DgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMSIwIAYJKoZIhvcNAQkB" +
+ "FhNhbmRyb2lkQGFuZHJvaWQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" +
+ "gQCqQkDtkiEXmV8O5EK4y2Y9YyoWNDx70z4fqD+9muuzJGuM5NovMbxhBycuKHF3" +
+ "WK60iXzrsAYkB1c8VHHbcUEFqz2fBdLKyxy/nYohlo8TYSVpEjt3vfc0sgmp4FKU" +
+ "RDHO2z3rZPHWysV9L9ZvjeQpiwaYipU9epdBmvFmxQmCDQIDAQABo4HWMIHTMB0G" +
+ "A1UdDgQWBBTnm32QKeqQC38IQXZOQSPoQyypAzCBowYDVR0jBIGbMIGYgBTnm32Q" +
+ "KeqQC38IQXZOQSPoQyypA6F9pHsweTELMAkGA1UEBhMCQU4xEDAOBgNVBAgTB0Fu" +
+ "ZHJvaWQxEDAOBgNVBAoTB0FuZHJvaWQxEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNV" +
+ "BAMTB0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb22C" +
+ "AQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAUmDApQu+r5rglS1WF" +
+ "BKXE3R2LasFvbBwdw2E0MAc0TWqLVW91VW4VWMX4r+C+c7rZpYXXtRqFRCuI/czL" +
+ "0e1GaUP/Wa6bXBcm2u7Iv2dVAaAOELmFSVTZeR57Lm9lT9kQLp24kmNndIsiDW3T" +
+ "XZ4pY/k2kxungOKx8b8pGYE9Bw==\n" +
+ "-----END CERTIFICATE-----";
+
+ private java.security.cert.X509Certificate cert;
+
+ private javax.security.cert.X509Certificate tbt_cert;
+
+ private java.security.cert.X509Certificate javaCert;
+
+ private Provider myProvider;
+
+ private javax.security.cert.X509Certificate javaxCert;
+
+ private java.security.cert.Certificate javaSSCert;
+
+ private Provider mySSProvider;
+
+ private Certificate javaxSSCert;
+
+ @Override
+ protected void setUp() throws Exception {
+ try {
+ ByteArrayInputStream bais = new ByteArrayInputStream(base64cert
+ .getBytes());
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ this.cert = (java.security.cert.X509Certificate) cf
+ .generateCertificate(bais);
+ this.tbt_cert = X509Certificate.getInstance(cert.getEncoded());
+
+ // non self signed cert
+ this.javaCert = (java.security.cert.X509Certificate)cf
+ .generateCertificate(new ByteArrayInputStream(selfSignedCert.getBytes()));
+ this.javaxCert = X509Certificate.getInstance(javaCert.getEncoded());
+ myProvider = cf.getProvider();
+ Security.addProvider(myProvider);
+
+ // self signed cert
+ this.javaSSCert = cf.generateCertificate(new ByteArrayInputStream(
+ selfSignedCert.getBytes()));
+ this.javaxSSCert = X509Certificate.getInstance(javaCert
+ .getEncoded());
+ mySSProvider = cf.getProvider();
+ Security.addProvider(mySSProvider);
+
+ } catch (java.security.cert.CertificateException e) {
+ // The requested certificate type is not available.
+ // Test pass..
+ this.cert = null;
+ Logger.global.warning("Error in test setup: Certificate type not supported");
+ } catch (javax.security.cert.CertificateException e) {
+ // The requested certificate type is not available.
+ // Test pass..
+ this.cert = null;
+ Logger.global.warning("Error in test setup: Certificate type not supported");
+ }
+ }
+
+ /**
+ * X509Certificate() constructor testing.
+ * {@link X509Certificate#X509Certificate() }
+ */
+ public void testConstructor() {
+ //Direct constructor, check if it throws an exception
+ X509Certificate cert = new MyCertificate();
+ }
+
+ /**
+ * getInstance(InputStream inStream) method testing.
+ */
+ public void testGetInstance1() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ try {
+ ByteArrayInputStream bais = new ByteArrayInputStream(cert
+ .getEncoded());
+
+ X509Certificate.getInstance(bais);
+ } catch (java.security.cert.CertificateEncodingException e) {
+ fail("Unexpected CertificateEncodingException was thrown.");
+ } catch (CertificateEncodingException e) {
+ fail("Unexpected CertificateEncodingException was thrown.");
+ } catch (CertificateException e) {
+ // The requested certificate type is not available.
+ // Test pass..
+ }
+
+ // Regression for HARMONY-756
+ try {
+ X509Certificate.getInstance((InputStream) null);
+ fail("No expected CertificateException");
+ } catch (CertificateException e) {
+ // expected;
+ }
+ }
+
+ /**
+ * getInstance(byte[] certData) method testing.
+ * @throws CertificateEncodingException
+ * @throws java.security.cert.CertificateEncodingException
+ */
+ public void testGetInstance2() throws java.security.cert.CertificateEncodingException, CertificateEncodingException {
+ boolean certificateException = false;
+ X509Certificate c = null;
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ try {
+ c = X509Certificate.getInstance(cert.getEncoded());
+ } catch (java.security.cert.CertificateEncodingException e) {
+ fail("Unexpected CertificateEncodingException was thrown.");
+ } catch (CertificateException e) {
+ // The requested certificate type is not available.
+ // Test pass..
+ certificateException = true;
+
+ }
+
+ if (! certificateException) {
+ assertNotNull(c);
+ assertTrue(Arrays.equals(c.getEncoded(),cert.getEncoded() ));
+ }
+
+ try {
+ X509Certificate.getInstance(new byte[]{(byte) 1 });
+ } catch (CertificateException e) {
+ //ok
+ }
+
+ // Regression for HARMONY-756
+ try {
+ X509Certificate.getInstance((byte[]) null);
+ fail("No expected CertificateException");
+ } catch (CertificateException e) {
+ // expected;
+ }
+
+ }
+
+ /**
+ * checkValidity() method testing.
+ * @throws CertificateNotYetValidException
+ * @throws CertificateExpiredException
+ * @throws java.security.cert.CertificateExpiredException
+ * @throws java.security.cert.CertificateNotYetValidException
+ */
+ public void testCheckValidity1() throws CertificateExpiredException, CertificateNotYetValidException, java.security.cert.CertificateExpiredException, java.security.cert.CertificateNotYetValidException {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ Date date = new Date();
+ Date nb_date = tbt_cert.getNotBefore();
+ Date na_date = tbt_cert.getNotAfter();
+ try {
+ tbt_cert.checkValidity();
+ assertFalse("CertificateExpiredException expected", date
+ .compareTo(na_date) > 0);
+ assertFalse("CertificateNotYetValidException expected", date
+ .compareTo(nb_date) < 0);
+ } catch (CertificateExpiredException e) {
+ assertTrue("Unexpected CertificateExpiredException was thrown",
+ date.compareTo(na_date) > 0);
+ } catch (CertificateNotYetValidException e) {
+ assertTrue("Unexpected CertificateNotYetValidException was thrown",
+ date.compareTo(nb_date) < 0);
+ }
+
+ try {
+ tbt_cert.checkValidity();
+ } catch (CertificateExpiredException e) {
+ // ok
+ }
+
+ try {
+ cert.checkValidity();
+ } catch (java.security.cert.CertificateExpiredException e) {
+ // ok
+ }
+
+ }
+
+ /**
+ * checkValidity(Date date) method testing.
+ * @throws CertificateNotYetValidException
+ * @throws CertificateExpiredException
+ */
+ public void testCheckValidity2() throws CertificateNotYetValidException, CertificateExpiredException {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ Date[] date = new Date[8];
+ Calendar calendar = Calendar.getInstance();
+ for (int i = 0; i < date.length; i++) {
+ calendar.set(i * 500, Calendar.JANUARY, 1);
+ date[i] = calendar.getTime();
+ }
+ Date nb_date = tbt_cert.getNotBefore();
+ Date na_date = tbt_cert.getNotAfter();
+ for (int i = 0; i < date.length; i++) {
+ try {
+ tbt_cert.checkValidity(date[i]);
+ assertFalse("CertificateExpiredException expected", date[i]
+ .compareTo(na_date) > 0);
+ assertFalse("CertificateNotYetValidException expected", date[i]
+ .compareTo(nb_date) < 0);
+ } catch (CertificateExpiredException e) {
+ assertTrue("Unexpected CertificateExpiredException was thrown",
+ date[i].compareTo(na_date) > 0);
+ } catch (CertificateNotYetValidException e) {
+ assertTrue("Unexpected CertificateNotYetValidException "
+ + "was thrown", date[i].compareTo(nb_date) < 0);
+ }
+ }
+
+ Calendar calendarNow = Calendar.getInstance();
+
+ try {
+ tbt_cert.checkValidity(calendarNow.getTime());
+ } catch (CertificateExpiredException e) {
+ //ok
+ }
+
+ Calendar calendarPast = GregorianCalendar.getInstance();
+ calendarPast.clear();
+
+ try {
+ tbt_cert.checkValidity(calendarPast.getTime());
+ } catch (CertificateNotYetValidException e) {
+ //ok
+ }
+
+ }
+
+ /**
+ * getVersion() method testing.
+ */
+ public void testGetVersion() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ assertEquals("The version is not correct.", tbt_cert.getVersion(), 2);
+ }
+
+ /**
+ * getSerialNumber() method testing.
+ */
+ public void testGetSerialNumber() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ assertEquals("The serial number is not correct.", tbt_cert
+ .getSerialNumber(), cert.getSerialNumber());
+ }
+
+ /**
+ * getIssuerDN() method testing.
+ */
+ public void testGetIssuerDN() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ Logger.global.warning("testGetIssuerDN: error in test setup.");
+ }
+ assertEquals("The issuer DN is not correct.", tbt_cert.getIssuerDN(),
+ cert.getIssuerDN());
+ }
+
+ /**
+ * getSubjectDN() method testing.
+ */
+ public void testGetSubjectDN() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ assertEquals("The subject DN is not correct.", tbt_cert.getSubjectDN(),
+ cert.getSubjectDN());
+ }
+
+ /**
+ * getNotBefore() method testing.
+ */
+ public void testGetNotBefore() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ assertEquals("The NotBefore date is not correct.", tbt_cert
+ .getNotBefore(), cert.getNotBefore());
+ }
+
+ /**
+ * getNotAfter() method testing.
+ */
+ public void testGetNotAfter() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ assertEquals("The NotAfter date is not correct.", tbt_cert
+ .getNotAfter(), cert.getNotAfter());
+ }
+
+ /**
+ * getSigAlgName() method testing.
+ */
+ public void testGetSigAlgName() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ assertEquals("The name of signature algorithm is not correct.",
+ tbt_cert.getSigAlgName(), cert.getSigAlgName());
+ }
+
+ /**
+ * getSigAlgOID() method testing.
+ */
+ public void testGetSigAlgOID() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ assertEquals("The name of OID of signature algorithm is not correct.",
+ tbt_cert.getSigAlgOID(), cert.getSigAlgOID());
+ }
+
+ /**
+ * getSigAlgParams() method testing.
+ */
+ public void testGetSigAlgParams() {
+ if (this.cert == null) {
+ // The requested certificate type is not available.
+ // Test can not be applied.
+ return;
+ }
+ assertTrue("The byte array with encoded algorithm parameters "
+ + "is not correct.", Arrays.equals(tbt_cert.getSigAlgParams(),
+ cert.getSigAlgParams()));
+ }
+
+ /**
+ * The stub class used for testing of non abstract methods.
+ */
+ private class MyCertificate extends X509Certificate {
+
+ public MyCertificate() {
+ super();
+ }
+
+ @Override
+ public void checkValidity() throws CertificateExpiredException,
+ CertificateNotYetValidException {
+ }
+
+ @Override
+ public void checkValidity(Date arg0)
+ throws CertificateExpiredException,
+ CertificateNotYetValidException {
+ }
+
+ @Override
+ public Principal getIssuerDN() {
+ return null;
+ }
+
+ @Override
+ public Date getNotAfter() {
+ return null;
+ }
+
+ @Override
+ public Date getNotBefore() {
+ return null;
+ }
+
+ @Override
+ public BigInteger getSerialNumber() {
+ return null;
+ }
+
+ @Override
+ public String getSigAlgName() {
+ return null;
+ }
+
+ @Override
+ public String getSigAlgOID() {
+ return null;
+ }
+
+ @Override
+ public byte[] getSigAlgParams() {
+ return null;
+ }
+
+ @Override
+ public Principal getSubjectDN() {
+ return null;
+ }
+
+ @Override
+ public int getVersion() {
+ return 0;
+ }
+
+ @Override
+ public byte[] getEncoded() throws CertificateEncodingException {
+ return null;
+ }
+
+ @Override
+ public PublicKey getPublicKey() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return null;
+ }
+
+ @Override
+ public void verify(PublicKey key) throws CertificateException,
+ NoSuchAlgorithmException, InvalidKeyException,
+ NoSuchProviderException, SignatureException {
+ }
+
+ @Override
+ public void verify(PublicKey key, String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException,
+ SignatureException {
+ }
+ }
+
+ public class MyModifiablePublicKey implements PublicKey {
+
+ private PublicKey key;
+ private boolean modifiedAlgo;
+ private String algo;
+ private String format;
+ private boolean modifiedFormat;
+ private boolean modifiedEncoding;
+ private byte[] encoding;
+
+ public MyModifiablePublicKey(PublicKey k) {
+ super();
+ this.key = k;
+ }
+
+ public String getAlgorithm() {
+ if (modifiedAlgo) {
+ return algo;
+ } else {
+ return key.getAlgorithm();
+ }
+ }
+
+ public String getFormat() {
+ if (modifiedFormat) {
+ return this.format;
+ } else {
+ return key.getFormat();
+ }
+
+ }
+
+ public byte[] getEncoded() {
+ if (modifiedEncoding) {
+ return this.encoding;
+ } else {
+ return key.getEncoded();
+ }
+
+ }
+
+ public long getSerVerUID() {
+ return key.serialVersionUID;
+ }
+
+ public void setAlgorithm(String myAlgo) {
+ modifiedAlgo = true;
+ this.algo = myAlgo;
+ }
+
+ public void setFormat(String myFormat) {
+ modifiedFormat = true;
+ format = myFormat;
+ }
+
+ public void setEncoding(byte[] myEncoded) {
+ modifiedEncoding = true;
+ encoding = myEncoded;
+ }
+ }
+
+ /**
+ * @throws CertificateEncodingException
+ * {@link Certificate#getEncoded()}
+ */
+ public void testGetEncoded()
+ throws CertificateEncodingException, java.security.cert.CertificateException {
+ // cert = DER encoding of the ASN1.0 structure
+ assertTrue(Arrays.equals(cert.getEncoded(), tbt_cert.getEncoded()));
+ assertFalse(Arrays.equals(javaxCert.getEncoded(), tbt_cert.getEncoded()));
+ }
+
+ /**
+ * {@link Certificate#getPublicKey()}
+ */
+ public void testGetPublicKey() {
+ PublicKey key = javaxCert.getPublicKey();
+ assertNotNull(key);
+ assertEquals(javaxCert.getPublicKey(), javaCert.getPublicKey());
+ assertEquals(key.getAlgorithm(),"RSA");
+
+ key = javaxSSCert.getPublicKey();
+ assertNotNull(key);
+ assertEquals(key.getAlgorithm(),"RSA");
+
+ //assertTrue(mySSProvider.containsKey(key));
+
+ }
+
+ /**
+ * @throws SignatureException
+ * @throws NoSuchProviderException
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws CertificateException
+ * {@link Certificate#verify(PublicKey)}
+ */
+ // Side Effect: Destroys MD5 provider, hurts succeeding tests
+ public void testVerifyPublicKey() throws InvalidKeyException,
+ NoSuchAlgorithmException, NoSuchProviderException,
+ SignatureException, CertificateException {
+
+ // Preconditions
+ assertNotNull(javaxCert.getPublicKey());
+ assertNotNull(javaxSSCert.getPublicKey());
+ //precondition for self signed certificates
+ /*assertEquals(((X509Certificate) javaxSSCert).getIssuerDN().getName(),
+ ((X509Certificate) javaxSSCert).getSubjectDN());*/
+
+ // must always evaluate true for self signed
+ // here not self signed:
+ try {
+ javaxCert.verify(javaxCert.getPublicKey());
+ } catch (SignatureException e) {
+ // ok
+ }
+
+ PublicKey k = javaxCert.getPublicKey();
+
+ MyModifiablePublicKey changedEncoding = new MyModifiablePublicKey(k);
+ changedEncoding
+ .setEncoding(new byte[javaxCert.getEncoded().length - 1]);
+
+ try {
+ javaxCert.verify(tbt_cert.getPublicKey());
+ } catch (InvalidKeyException e) {
+ // ok
+ }
+
+
+ try {
+ javaxCert.verify(null);
+ } catch (Exception e) {
+ // ok
+ }
+
+ try {
+ javaxCert.verify(changedEncoding);
+ fail("Exception expected");
+ } catch (Exception e) {
+ // ok
+ }
+
+ // following test doesn't work because the algorithm is derived from
+ // somewhere else.
+
+ // MyModifiablePublicKey changedAlgo = new MyModifiablePublicKey(k);
+ // changedAlgo.setAlgorithm("MD5withBla");
+
+ // try {
+ // javaxCert.verify(changedAlgo);
+ // fail("Exception expected");
+ // } catch (SignatureException e) {
+ // // ok
+ // }
+
+ // Security.removeProvider(mySSProvider.getName());
+
+ // try {
+ // javaxSSCert.verify(javaxSSCert.getPublicKey());
+ // } catch (NoSuchProviderException e) {
+ // // ok
+ // }
+
+ // Security.addProvider(mySSProvider);
+
+ // must always evaluate true for self signed
+ // javaxSSCert.verify(javaxSSCert.getPublicKey());
+ }
+
+ /**
+ * @throws SignatureException
+ * @throws NoSuchProviderException
+ * @throws NoSuchAlgorithmException
+ * @throws java.security.cert.CertificateException
+ * @throws InvalidKeyException
+ * @throws IOException
+ * @throws CertificateException
+ * {@link Certificate#verify(PublicKey, String)}
+ */
+ // SideEffect: Destroys MD5 provider, hurts succeeding tests
+ public void testVerifyPublicKeyString() throws InvalidKeyException,
+ java.security.cert.CertificateException, NoSuchAlgorithmException,
+ NoSuchProviderException, SignatureException, IOException,
+ CertificateException {
+
+ try {
+ javaxCert.verify(javaxCert.getPublicKey(), myProvider.getName());
+ } catch (NoSuchAlgorithmException e) {
+ // ok
+ }
+
+ // myProvider.getService(type, algorithm)
+
+ Security.removeProvider(myProvider.getName());
+ try {
+ javaxCert.verify(javaxCert.getPublicKey(), myProvider.getName());
+ } catch (NoSuchProviderException e) {
+ // ok
+ }
+ Security.addProvider(myProvider);
+
+ Provider[] providers = Security.getProviders("Signature.MD5withRSA");
+ if (providers == null || providers.length == 0) {
+ fail("no Provider for Signature.MD5withRSA");
+ return;
+ }
+
+ // self signed cert: should verify with provider
+ try {
+ javaxSSCert.verify(javaxSSCert.getPublicKey(),
+ providers[0].getName());
+ } catch (SignatureException e) {
+ fail("blu");
+ }
+
+ }
+
+ public static Test suite() {
+ return new TestSuite(X509CertificateTest.class);
+ }
+}
diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/DocumentBuilderFactoryTest.java
index 7d79560..7d79560 100644
--- a/luni/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/DocumentBuilderFactoryTest.java
diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/DocumentBuilderTest.java
index 66ce621..66ce621 100644
--- a/luni/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/DocumentBuilderTest.java
diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/FactoryConfigurationErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/FactoryConfigurationErrorTest.java
index cdef4e2..cdef4e2 100644
--- a/luni/src/test/java/tests/api/javax/xml/parsers/FactoryConfigurationErrorTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/FactoryConfigurationErrorTest.java
diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/ParserConfigurationExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/ParserConfigurationExceptionTest.java
index d1feb9f..d1feb9f 100644
--- a/luni/src/test/java/tests/api/javax/xml/parsers/ParserConfigurationExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/ParserConfigurationExceptionTest.java
diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserFactoryTest.java
index 614b9d8..614b9d8 100644
--- a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserFactoryTest.java
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserTest.java
new file mode 100644
index 0000000..a51998c
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserTest.java
@@ -0,0 +1,899 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.api.javax.xml.parsers;
+
+import dalvik.annotation.KnownFailure;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Vector;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import junit.framework.TestCase;
+import org.xml.sax.HandlerBase;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.DefaultHandler;
+import tests.api.javax.xml.parsers.SAXParserTestSupport.MyDefaultHandler;
+import tests.api.javax.xml.parsers.SAXParserTestSupport.MyHandler;
+import tests.api.org.xml.sax.support.BrokenInputStream;
+import tests.api.org.xml.sax.support.MethodLogger;
+import tests.api.org.xml.sax.support.MockHandler;
+import tests.support.resource.Support_Resources;
+
+@SuppressWarnings("deprecation")
+public class SAXParserTest extends TestCase {
+
+ private class MockSAXParser extends SAXParser {
+ public MockSAXParser() {
+ super();
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#getParser()
+ */
+ @Override
+ public Parser getParser() throws SAXException {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#getProperty(java.lang.String)
+ */
+ @Override
+ public Object getProperty(String name) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#getXMLReader()
+ */
+ @Override
+ public XMLReader getXMLReader() throws SAXException {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#isNamespaceAware()
+ */
+ @Override
+ public boolean isNamespaceAware() {
+ // it is a fake
+ return false;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#isValidating()
+ */
+ @Override
+ public boolean isValidating() {
+ // it is a fake
+ return false;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#setProperty(java.lang.String,
+ * java.lang.Object)
+ */
+ @Override
+ public void setProperty(String name, Object value) throws
+ SAXNotRecognizedException, SAXNotSupportedException {
+ // it is a fake
+ }
+ }
+
+ private static final String LEXICAL_HANDLER_PROPERTY
+ = "http://xml.org/sax/properties/lexical-handler";
+
+ SAXParserFactory spf;
+
+ SAXParser parser;
+
+ static HashMap<String, String> ns;
+
+ static Vector<String> el;
+
+ static HashMap<String, String> attr;
+
+ SAXParserTestSupport sp = new SAXParserTestSupport();
+
+ File [] list_wf;
+ File [] list_nwf;
+ File [] list_out_dh;
+ File [] list_out_hb;
+
+ boolean validating = false;
+
+ private InputStream getResource(String name) {
+ return this.getClass().getResourceAsStream(name);
+ }
+
+ public void initFiles() throws Exception {
+ // we differntiate between a validating and a non validating parser
+ try {
+ SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+ validating = parser.isValidating();
+ } catch (Exception e) {
+ fail("could not obtain a SAXParser");
+ }
+
+ String tmpPath = System.getProperty("java.io.tmpdir");
+
+ // nwf = not well formed, wf = well formed
+ list_wf = new File[] {new File(tmpPath + "/" +
+ SAXParserTestSupport.XML_WF + "staff.xml")};
+ list_nwf = new File[] {new File(tmpPath + "/" +
+ SAXParserTestSupport.XML_NWF + "staff.xml")};
+ list_out_dh = new File[] {new File(tmpPath + "/" +
+ SAXParserTestSupport.XML_WF_OUT_DH + "staff.out")};
+ list_out_hb = new File[] {new File(tmpPath + "/" +
+ SAXParserTestSupport.XML_WF_OUT_HB + "staff.out")};
+
+ list_wf[0].deleteOnExit();
+ list_nwf[0].deleteOnExit();
+ list_out_hb[0].deleteOnExit();
+ list_out_dh[0].deleteOnExit();
+
+
+ Support_Resources.copyLocalFileto(list_wf[0],
+ getResource(SAXParserTestSupport.XML_WF + "staff.xml"));
+ Support_Resources.copyLocalFileto(new File(
+ tmpPath + "/" + SAXParserTestSupport.XML_WF + "staff.dtd"),
+ getResource(SAXParserTestSupport.XML_WF + "staff.dtd"));
+
+ Support_Resources.copyLocalFileto(list_nwf[0],
+ getResource(SAXParserTestSupport.XML_NWF + "staff.xml"));
+ Support_Resources.copyLocalFileto(new File(
+ tmpPath + "/" + SAXParserTestSupport.XML_NWF + "staff.dtd"),
+ getResource(SAXParserTestSupport.XML_NWF + "staff.dtd"));
+
+ Support_Resources.copyLocalFileto(list_out_dh[0],
+ getResource(SAXParserTestSupport.XML_WF_OUT_DH + "staff.out"));
+ Support_Resources.copyLocalFileto(list_out_hb[0],
+ getResource(SAXParserTestSupport.XML_WF_OUT_HB + "staff.out"));
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ spf = SAXParserFactory.newInstance();
+ parser = spf.newSAXParser();
+ assertNotNull(parser);
+
+ ns = new HashMap<String, String>();
+ attr = new HashMap<String, String>();
+ el = new Vector<String>();
+ initFiles();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ }
+
+// public static void main(String[] args) throws Exception {
+// SAXParserTest st = new SAXParserTest();
+// st.setUp();
+// st.generateDataFromReferenceImpl();
+//
+// }
+//
+// private void generateDataFromReferenceImpl() {
+// try {
+// for(int i = 0; i < list_wf.length; i++) {
+// MyDefaultHandler dh = new MyDefaultHandler();
+// InputStream is = new FileInputStream(list_wf[i]);
+// parser.parse(is, dh, ParsingSupport.XML_SYSTEM_ID);
+// HashMap refHm = dh.createData();
+//
+// StringBuilder sb = new StringBuilder();
+// for (int j = 0; j < ParsingSupport.KEYS.length; j++) {
+// String key = ParsingSupport.KEYS[j];
+// sb.append(refHm.get(key)).append(
+// ParsingSupport.SEPARATOR_DATA);
+// }
+// FileWriter fw = new FileWriter("/tmp/build_dh"+i+".out");
+// fw.append(sb.toString());
+// fw.close();
+// }
+//
+// for(int i = 0; i < list_nwf.length; i++) {
+// MyHandler hb = new MyHandler();
+// InputStream is = new FileInputStream(list_wf[i]);
+// parser.parse(is, hb, ParsingSupport.XML_SYSTEM_ID);
+// HashMap refHm = hb.createData();
+//
+// StringBuilder sb = new StringBuilder();
+// for (int j = 0; j < ParsingSupport.KEYS.length; j++) {
+// String key = ParsingSupport.KEYS[j];
+// sb.append(refHm.get(key)).append(
+// ParsingSupport.SEPARATOR_DATA);
+// }
+// FileWriter fw = new FileWriter("/tmp/build_hb"+i+".out");
+// fw.append(sb.toString());
+// fw.close();
+// }
+//
+//
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// }
+
+ public void testSAXParser() {
+ try {
+ new MockSAXParser();
+ } catch (Exception e) {
+ fail("unexpected exception " + e.toString());
+ }
+ }
+
+ /**
+ * javax.xml.parser.SAXParser#getSchema().
+ * TODO getSchema() IS NOT SUPPORTED
+ */
+ /* public void test_getSchema() {
+ assertNull(parser.getSchema());
+ SchemaFactory sf =
+ SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ try {
+ Schema schema = sf.newSchema();
+ spf.setSchema(schema);
+ assertNotNull(spf.newSAXParser().getSchema());
+ } catch (ParserConfigurationException pce) {
+ fail("Unexpected ParserConfigurationException " + pce.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+ */
+
+ public void testIsNamespaceAware() {
+ try {
+ spf.setNamespaceAware(true);
+ assertTrue(spf.newSAXParser().isNamespaceAware());
+ spf.setNamespaceAware(false);
+ assertFalse(spf.newSAXParser().isNamespaceAware());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ public void testIsValidating() {
+ try {
+ spf.setValidating(false);
+ assertFalse(spf.newSAXParser().isValidating());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ public void testIsXIncludeAware() {
+ try {
+ spf.setXIncludeAware(false);
+ assertFalse(spf.newSAXParser().isXIncludeAware());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ public void test_parseLjava_io_FileLorg_xml_sax_helpers_DefaultHandler() throws Exception {
+
+ for(int i = 0; i < list_wf.length; i++) {
+ HashMap<String, String> hm =
+ new SAXParserTestSupport().readFile(list_out_dh[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse(list_wf[i], dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse(list_nwf[i], dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((File) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ parser.parse(list_wf[0], (DefaultHandler) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ }
+ }
+
+ public void testParseFileHandlerBase() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ parser.parse(list_wf[i], dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm,
+ dh.createData()));
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse(list_nwf[i], dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((File) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ parser.parse(list_wf[0], (HandlerBase) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ public void test_parseLorg_xml_sax_InputSourceLorg_xml_sax_helpers_DefaultHandler()
+ throws Exception {
+ for(int i = 0; i < list_wf.length; i++) {
+ HashMap<String, String> hm = new SAXParserTestSupport().readFile(
+ list_out_dh[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputSource is = new InputSource(new FileInputStream(list_wf[i]));
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for (File file : list_nwf) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputSource is = new InputSource(new FileInputStream(file));
+ parser.parse(is, dh);
+ fail("SAXException is not thrown");
+ } catch (SAXException expected) {
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((InputSource) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ InputSource is = new InputSource(new FileInputStream(list_wf[0]));
+ parser.parse(is, (DefaultHandler) null);
+
+ InputStream in = null;
+ try {
+ in = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
+ is = new InputSource(in);
+ parser.parse(is, (DefaultHandler) null);
+ fail("IOException expected");
+ } catch(IOException expected) {
+ } finally {
+ in.close();
+ }
+ }
+
+ public void testParseInputSourceHandlerBase() throws Exception {
+ for(int i = 0; i < list_wf.length; i++) {
+ HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputSource is = new InputSource(new FileInputStream(list_wf[i]));
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for (File file : list_nwf) {
+ try {
+ MyHandler dh = new MyHandler();
+ InputSource is = new InputSource(new FileInputStream(file));
+ parser.parse(is, dh);
+ fail("SAXException is not thrown");
+ } catch (SAXException expected) {
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((InputSource) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(IllegalArgumentException expected) {
+ }
+
+ InputSource is = new InputSource(new FileInputStream(list_wf[0]));
+ parser.parse(is, (HandlerBase) null);
+
+ // Reader case
+ is = new InputSource(new InputStreamReader(new FileInputStream(list_wf[0])));
+ parser.parse(is, (HandlerBase) null);
+
+ // SystemID case
+ is = new InputSource(list_wf[0].toURI().toString());
+ parser.parse(is, (HandlerBase) null);
+
+ // Inject IOException
+ InputStream in = null;
+ try {
+ in = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
+ parser.parse(in, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("IOException expected");
+ } catch(IOException expected) {
+ } finally {
+ in.close();
+ }
+ }
+
+ public void test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandler() throws Exception {
+
+ for(int i = 0; i < list_wf.length; i++) {
+
+ HashMap<String, String> hm = new SAXParserTestSupport().readFile(
+ list_out_dh[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputStream is = new FileInputStream(list_nwf[i]);
+ parser.parse(is, dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((InputStream) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (DefaultHandler) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ }
+ }
+
+ @KnownFailure("We supply optional qnames, but this test doesn't expect them")
+ public void test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandlerLjava_lang_String() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ assertEquals(hm, dh.createData());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputStream is = new FileInputStream(list_nwf[i]);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((InputStream) null, dh,
+ SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (DefaultHandler) null,
+ SAXParserTestSupport.XML_SYSTEM_ID);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+//
+// for(int i = 0; i < list_wf.length; i++) {
+//
+// HashMap<String, String> hm = new SAXParserTestSupport().readFile(
+// list_out_dh[i].getPath());
+// MyDefaultHandler dh = new MyDefaultHandler();
+// InputStream is = new FileInputStream(list_wf[i]);
+// parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+// assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+// }
+//
+// for(int i = 0; i < list_nwf.length; i++) {
+// try {
+// MyDefaultHandler dh = new MyDefaultHandler();
+// InputStream is = new FileInputStream(list_nwf[i]);
+// parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+// fail("SAXException is not thrown");
+// } catch(org.xml.sax.SAXException se) {
+// //expected
+// }
+// }
+//
+// try {
+// MyDefaultHandler dh = new MyDefaultHandler();
+// parser.parse((InputStream) null, dh,
+// SAXParserTestSupport.XML_SYSTEM_ID);
+// fail("java.lang.IllegalArgumentException is not thrown");
+// } catch(java.lang.IllegalArgumentException iae) {
+// //expected
+// }
+//
+// try {
+// InputStream is = new FileInputStream(list_wf[0]);
+// parser.parse(is, (DefaultHandler) null,
+// SAXParserTestSupport.XML_SYSTEM_ID);
+// } catch(java.lang.IllegalArgumentException iae) {
+// fail("java.lang.IllegalArgumentException is thrown");
+// }
+//
+// // TODO commented out since our parser is nonvalidating and thus never
+// // tries to load staff.dtd in "/" ... and therefore never can fail with
+// // an IOException
+// /*try {
+// MyDefaultHandler dh = new MyDefaultHandler();
+// InputStream is = new FileInputStream(list_wf[0]);
+// parser.parse(is, dh, "/");
+// fail("Expected IOException was not thrown");
+// } catch(IOException ioe) {
+// // expected
+// }*/
+ }
+
+ public void testParseInputStreamHandlerBase() throws Exception {
+ for(int i = 0; i < list_wf.length; i++) {
+ HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for (File file : list_nwf) {
+ try {
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(file);
+ parser.parse(is, dh);
+ fail("SAXException is not thrown");
+ } catch (SAXException expected) {
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((InputStream) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (HandlerBase) null);
+
+ // Inject IOException
+ try {
+ is = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
+ parser.parse(is, (HandlerBase) null);
+ fail("IOException expected");
+ } catch(IOException e) {
+ // Expected
+ } finally {
+ is.close();
+ }
+ }
+
+ public void testParseInputStreamHandlerBaseString() throws Exception {
+ for(int i = 0; i < list_wf.length; i++) {
+ HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for (File file : list_nwf) {
+ try {
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(file);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("SAXException is not thrown");
+ } catch (SAXException expected) {
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse(null, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(IllegalArgumentException expected) {
+ }
+
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
+
+ // Inject IOException
+ try {
+ is = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
+ parser.parse(is, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("IOException expected");
+ } catch(IOException expected) {
+ } finally {
+ is.close();
+ }
+ }
+
+ public void test_parseLjava_lang_StringLorg_xml_sax_helpers_DefaultHandler() throws Exception {
+
+ for(int i = 0; i < list_wf.length; i++) {
+
+ HashMap<String, String> hm = new SAXParserTestSupport().readFile(
+ list_out_dh[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse(list_wf[i].toURI().toString(), dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse(list_nwf[i].toURI().toString(), dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((String) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ parser.parse(list_wf[0].toURI().toString(), (DefaultHandler) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ }
+ }
+
+ public void testParseStringHandlerBase() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ parser.parse(list_wf[i].toURI().toString(), dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm,
+ dh.createData()));
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse(list_nwf[i].toURI().toString(), dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((String) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ parser.parse(list_wf[0].toURI().toString(), (HandlerBase) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ public void testReset() {
+ try {
+ spf = SAXParserFactory.newInstance();
+ parser = spf.newSAXParser();
+
+ parser.setProperty(LEXICAL_HANDLER_PROPERTY, new MockHandler(new MethodLogger()));
+ parser.reset();
+ assertEquals(null, parser.getProperty(LEXICAL_HANDLER_PROPERTY));
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ public void testGetParser() {
+ spf = SAXParserFactory.newInstance();
+ try {
+ Parser parser = spf.newSAXParser().getParser();
+ assertNotNull(parser);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ public void testGetReader() {
+ spf = SAXParserFactory.newInstance();
+ try {
+ XMLReader reader = spf.newSAXParser().getXMLReader();
+ assertNotNull(reader);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ public void testSetGetProperty() {
+ // Ordinary case
+ String validName = "http://xml.org/sax/properties/lexical-handler";
+ LexicalHandler validValue = new MockHandler(new MethodLogger());
+
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.setProperty(validName, validValue);
+ assertEquals(validValue, parser.getProperty(validName));
+
+ parser.setProperty(validName, null);
+ assertEquals(null, parser.getProperty(validName));
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Unsupported property
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.setProperty("foo", "bar");
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.getProperty("foo");
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // No name case
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.setProperty(null, "bar");
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.getProperty(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+}
diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserTestSupport.java
index 2b7e1da..2b7e1da 100644
--- a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserTestSupport.java
diff --git a/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/apache/harmony/kernel/dalvik/ThreadsTest.java
index 19c6229..19c6229 100644
--- a/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/apache/harmony/kernel/dalvik/ThreadsTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/HandlerBaseTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/HandlerBaseTest.java
index 8dfe38b..8dfe38b 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/HandlerBaseTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/HandlerBaseTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/InputSourceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/InputSourceTest.java
index f9040f0..f9040f0 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/InputSourceTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/InputSourceTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/SAXExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXExceptionTest.java
index 11d00e7..11d00e7 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/SAXExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXExceptionTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/SAXNotRecognizedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXNotRecognizedExceptionTest.java
index 3c73b56..3c73b56 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/SAXNotRecognizedExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXNotRecognizedExceptionTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/SAXNotSupportedExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXNotSupportedExceptionTest.java
index 71ea455..71ea455 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/SAXNotSupportedExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXNotSupportedExceptionTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/SAXParseExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXParseExceptionTest.java
index bfc48d4..bfc48d4 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/SAXParseExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/SAXParseExceptionTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/ext/Attributes2ImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/Attributes2ImplTest.java
index 348bef5..348bef5 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/ext/Attributes2ImplTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/Attributes2ImplTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/ext/DefaultHandler2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/DefaultHandler2Test.java
index 0e6c245..0e6c245 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/ext/DefaultHandler2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/DefaultHandler2Test.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/ext/Locator2ImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/Locator2ImplTest.java
index dbed1de..dbed1de 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/ext/Locator2ImplTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/ext/Locator2ImplTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/AttributeListImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/AttributeListImplTest.java
index 27f36ae..27f36ae 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/AttributeListImplTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/AttributeListImplTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/AttributesImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/AttributesImplTest.java
index 1cc77ee..1cc77ee 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/AttributesImplTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/AttributesImplTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/DefaultHandlerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/DefaultHandlerTest.java
index a9530f2..a9530f2 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/DefaultHandlerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/DefaultHandlerTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/LocatorImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/LocatorImplTest.java
index 8aa9c11..8aa9c11 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/LocatorImplTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/LocatorImplTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/NamespaceSupportTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/NamespaceSupportTest.java
index 2f1ff8d..2f1ff8d 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/NamespaceSupportTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/NamespaceSupportTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/ParserAdapterTest.java
index 2344736..2344736 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/ParserAdapterTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/ParserFactoryTest.java
index b59ce50..b59ce50 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/ParserFactoryTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/XMLFilterImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLFilterImplTest.java
index d00879b..d00879b 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/XMLFilterImplTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLFilterImplTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLReaderAdapterTest.java
index 16104b3..16104b3 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLReaderAdapterTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLReaderFactoryTest.java
index 8205dfd..8205dfd 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/helpers/XMLReaderFactoryTest.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/BrokenInputStream.java
index 8136b86..8136b86 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/BrokenInputStream.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/DoNothingParser.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/DoNothingParser.java
index c18b6ee..c18b6ee 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/DoNothingParser.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/DoNothingParser.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/DoNothingXMLReader.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/DoNothingXMLReader.java
index 8687bff..8687bff 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/DoNothingXMLReader.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/DoNothingXMLReader.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/MethodLogger.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MethodLogger.java
index ad8ef5f..ad8ef5f 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/MethodLogger.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MethodLogger.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/MockFilter.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockFilter.java
index 1189ebd..1189ebd 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/MockFilter.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockFilter.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/MockHandler.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockHandler.java
index 55757c9..55757c9 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/MockHandler.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockHandler.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/MockParser.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockParser.java
index e19e14e..e19e14e 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/MockParser.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockParser.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/MockReader.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockReader.java
index 2f0081c..2f0081c 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/MockReader.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockReader.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/MockResolver.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockResolver.java
index df4ddbf..df4ddbf 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/MockResolver.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockResolver.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/NoAccessParser.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoAccessParser.java
index 9fca514..9fca514 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/NoAccessParser.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoAccessParser.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/NoAccessXMLReader.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoAccessXMLReader.java
index b6a0a68..b6a0a68 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/NoAccessXMLReader.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoAccessXMLReader.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/NoInstanceParser.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoInstanceParser.java
index 48cfba7..48cfba7 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/NoInstanceParser.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoInstanceParser.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/NoInstanceXMLReader.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoInstanceXMLReader.java
index 7b386bc..7b386bc 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/NoInstanceXMLReader.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoInstanceXMLReader.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/NoSubclassParser.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoSubclassParser.java
index 8016c10..8016c10 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/NoSubclassParser.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoSubclassParser.java
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/NoSubclassXMLReader.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoSubclassXMLReader.java
index acdbd88..acdbd88 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/NoSubclassXMLReader.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/NoSubclassXMLReader.java
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/pkg1/TestClass.java b/harmony-tests/src/test/java/org/apache/harmony/tests/pkg1/TestClass.java
new file mode 100644
index 0000000..37765b7
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/pkg1/TestClass.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.pkg1;
+
+import java.io.Serializable;
+
+/**
+ * Used for a serialization test, must have different package and same base name
+ * as the TestClass in o.a.h.l.tests.pkg2
+ */
+public class TestClass implements Serializable {
+ private static final long serialVersionUID = 11111L;
+
+ public int i = 0;
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/pkg2/TestClass.java b/harmony-tests/src/test/java/org/apache/harmony/tests/pkg2/TestClass.java
new file mode 100644
index 0000000..1df7cdd
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/pkg2/TestClass.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.pkg2;
+
+import java.io.Serializable;
+
+/**
+ * Used for a serialization test, must have different package and same base name
+ * as the TestClass in o.a.h.l.tests.pkg1
+ */
+public class TestClass implements Serializable {
+ private static final long serialVersionUID = 11111L;
+ public int i = 0;
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/support/A.java b/harmony-tests/src/test/java/org/apache/harmony/tests/support/A.java
new file mode 100644
index 0000000..11522be
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/support/A.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.support;
+
+public class A implements I {
+ private static P pp = new P();
+
+ public A() {
+ pp.setClazz(getClass());
+ }
+
+ public String find(String key) {
+ return pp.findProp(key);
+ }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/support/B.java b/harmony-tests/src/test/java/org/apache/harmony/tests/support/B.java
new file mode 100644
index 0000000..f0f6473
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/support/B.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.support;
+
+public class B extends A {
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/support/I.java b/harmony-tests/src/test/java/org/apache/harmony/tests/support/I.java
new file mode 100644
index 0000000..65cbd22
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/support/I.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.support;
+
+public interface I {
+ String find(String key);
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/support/P.java b/harmony-tests/src/test/java/org/apache/harmony/tests/support/P.java
new file mode 100644
index 0000000..95e879d
--- /dev/null
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/support/P.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.support;
+
+import java.util.ResourceBundle;
+
+public class P {
+ private Class c;
+
+ public void setClazz(Class c) {
+ this.c = c;
+ }
+
+ public String findProp(String key) {
+ return findProp(this.c, key);
+ }
+
+ private String findProp(Class cls, String key) {
+ String ret = null;
+ try {
+ ResourceBundle b = ResourceBundle.getBundle(cls.getName());
+ ret = (String) b.getObject(key);
+ } catch (Exception e) {
+ }
+ if (ret == null && !cls.equals(Object.class) && !cls.isPrimitive()) {
+ ret = findProp(cls.getSuperclass(), key);
+ }
+ return ret;
+ }
+}
diff --git a/harmony-tests/src/test/java/tests/api/java/math/BigDecimalTest.java b/harmony-tests/src/test/java/tests/api/java/math/BigDecimalTest.java
deleted file mode 100644
index 4fd27bf..0000000
--- a/harmony-tests/src/test/java/tests/api/java/math/BigDecimalTest.java
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.math;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.math.MathContext;
-import java.math.RoundingMode;
-
-
-public class BigDecimalTest extends junit.framework.TestCase {
- BigInteger value = new BigInteger("12345908");
-
- BigInteger value2 = new BigInteger("12334560000");
-
- /**
- * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger)
- */
- public void test_ConstructorLjava_math_BigInteger() {
- BigDecimal big = new BigDecimal(value);
- assertTrue("the BigDecimal value is not initialized properly", big
- .unscaledValue().equals(value)
- && big.scale() == 0);
- }
-
- /**
- * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger, int)
- */
- public void test_ConstructorLjava_math_BigIntegerI() {
- BigDecimal big = new BigDecimal(value2, 5);
- assertTrue("the BigDecimal value is not initialized properly", big
- .unscaledValue().equals(value2)
- && big.scale() == 5);
- assertTrue("the BigDecimal value is not represented properly", big
- .toString().equals("123345.60000"));
- }
-
- /**
- * @tests java.math.BigDecimal#BigDecimal(double)
- */
- public void test_ConstructorD() {
- BigDecimal big = new BigDecimal(123E04);
- assertTrue(
- "the BigDecimal value taking a double argument is not initialized properly",
- big.toString().equals("1230000"));
- big = new BigDecimal(1.2345E-12);
- assertTrue("the double representation is not correct", big
- .doubleValue() == 1.2345E-12);
- big = new BigDecimal(-12345E-3);
- assertTrue("the double representation is not correct", big
- .doubleValue() == -12.345);
- big = new BigDecimal(5.1234567897654321e138);
- assertTrue("the double representation is not correct", big
- .doubleValue() == 5.1234567897654321E138
- && big.scale() == 0);
- big = new BigDecimal(0.1);
- assertTrue(
- "the double representation of 0.1 bigDecimal is not correct",
- big.doubleValue() == 0.1);
- big = new BigDecimal(0.00345);
- assertTrue(
- "the double representation of 0.00345 bigDecimal is not correct",
- big.doubleValue() == 0.00345);
- // regression test for HARMONY-2429
- big = new BigDecimal(-0.0);
- assertTrue(
- "the double representation of -0.0 bigDecimal is not correct",
- big.scale() == 0);
- }
-
- /**
- * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() throws NumberFormatException {
- BigDecimal big = new BigDecimal("345.23499600293850");
- assertTrue("the BigDecimal value is not initialized properly", big
- .toString().equals("345.23499600293850")
- && big.scale() == 14);
- big = new BigDecimal("-12345");
- assertTrue("the BigDecimal value is not initialized properly", big
- .toString().equals("-12345")
- && big.scale() == 0);
- big = new BigDecimal("123.");
- assertTrue("the BigDecimal value is not initialized properly", big
- .toString().equals("123")
- && big.scale() == 0);
-
- new BigDecimal("1.234E02");
- }
-
- /**
- * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
- */
- public void test_constructor_String_plus_exp() {
- /*
- * BigDecimal does not support a + sign in the exponent when converting
- * from a String
- */
- new BigDecimal(+23e-0);
- new BigDecimal(-23e+0);
- }
-
- /**
- * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
- */
- public void test_constructor_String_empty() {
- try {
- new BigDecimal("");
- fail("NumberFormatException expected");
- } catch (NumberFormatException e) {
- }
- }
-
- /**
- * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
- */
- public void test_constructor_String_plus_minus_exp() {
- try {
- new BigDecimal("+35e+-2");
- fail("NumberFormatException expected");
- } catch (NumberFormatException e) {
- }
-
- try {
- new BigDecimal("-35e-+2");
- fail("NumberFormatException expected");
- } catch (NumberFormatException e) {
- }
- }
-
- /**
- * @tests java.math.BigDecimal#BigDecimal(char[])
- */
- public void test_constructor_CC_plus_minus_exp() {
- try {
- new BigDecimal("+35e+-2".toCharArray());
- fail("NumberFormatException expected");
- } catch (NumberFormatException e) {
- }
-
- try {
- new BigDecimal("-35e-+2".toCharArray());
- fail("NumberFormatException expected");
- } catch (NumberFormatException e) {
- }
- }
-
- /**
- * @tests java.math.BigDecimal#abs()
- */
- public void test_abs() {
- BigDecimal big = new BigDecimal("-1234");
- BigDecimal bigabs = big.abs();
- assertTrue("the absolute value of -1234 is not 1234", bigabs.toString()
- .equals("1234"));
- big = new BigDecimal(new BigInteger("2345"), 2);
- bigabs = big.abs();
- assertTrue("the absolute value of 23.45 is not 23.45", bigabs
- .toString().equals("23.45"));
- }
-
- /**
- * @tests java.math.BigDecimal#add(java.math.BigDecimal)
- */
- public void test_addLjava_math_BigDecimal() {
- BigDecimal add1 = new BigDecimal("23.456");
- BigDecimal add2 = new BigDecimal("3849.235");
- BigDecimal sum = add1.add(add2);
- assertTrue("the sum of 23.456 + 3849.235 is wrong", sum.unscaledValue()
- .toString().equals("3872691")
- && sum.scale() == 3);
- assertTrue("the sum of 23.456 + 3849.235 is not printed correctly", sum
- .toString().equals("3872.691"));
- BigDecimal add3 = new BigDecimal(12.34E02D);
- assertTrue("the sum of 23.456 + 12.34E02 is not printed correctly",
- (add1.add(add3)).toString().equals("1257.456"));
- }
-
- /**
- * @tests java.math.BigDecimal#compareTo(java.math.BigDecimal)
- */
- public void test_compareToLjava_math_BigDecimal() {
- BigDecimal comp1 = new BigDecimal("1.00");
- BigDecimal comp2 = new BigDecimal(1.000000D);
- assertTrue("1.00 and 1.000000 should be equal",
- comp1.compareTo(comp2) == 0);
- BigDecimal comp3 = new BigDecimal("1.02");
- assertTrue("1.02 should be bigger than 1.00",
- comp3.compareTo(comp1) == 1);
- BigDecimal comp4 = new BigDecimal(0.98D);
- assertTrue("0.98 should be less than 1.00",
- comp4.compareTo(comp1) == -1);
- }
-
- /**
- * @tests java.math.BigDecimal#divide(java.math.BigDecimal, int)
- */
- public void test_divideLjava_math_BigDecimalI() {
- BigDecimal divd1 = new BigDecimal(value, 2);
- BigDecimal divd2 = new BigDecimal("2.335");
- BigDecimal divd3 = divd1.divide(divd2, BigDecimal.ROUND_UP);
- assertTrue("123459.08/2.335 is not correct", divd3.toString().equals(
- "52873.27")
- && divd3.scale() == divd1.scale());
- assertTrue(
- "the unscaledValue representation of 123459.08/2.335 is not correct",
- divd3.unscaledValue().toString().equals("5287327"));
- divd2 = new BigDecimal(123.4D);
- divd3 = divd1.divide(divd2, BigDecimal.ROUND_DOWN);
- assertTrue("123459.08/123.4 is not correct", divd3.toString().equals(
- "1000.47")
- && divd3.scale() == 2);
- divd2 = new BigDecimal(000D);
-
- try {
- divd1.divide(divd2, BigDecimal.ROUND_DOWN);
- fail("divide by zero is not caught");
- } catch (ArithmeticException e) {
- }
- }
-
- /**
- * @tests java.math.BigDecimal#divide(java.math.BigDecimal, int, int)
- */
- public void test_divideLjava_math_BigDecimalII() {
- BigDecimal divd1 = new BigDecimal(value2, 4);
- BigDecimal divd2 = new BigDecimal("0.0023");
- BigDecimal divd3 = divd1.divide(divd2, 3, BigDecimal.ROUND_HALF_UP);
- assertTrue("1233456/0.0023 is not correct", divd3.toString().equals(
- "536285217.391")
- && divd3.scale() == 3);
- divd2 = new BigDecimal(1345.5E-02D);
- divd3 = divd1.divide(divd2, 0, BigDecimal.ROUND_DOWN);
- assertTrue(
- "1233456/13.455 is not correct or does not have the correct scale",
- divd3.toString().equals("91672") && divd3.scale() == 0);
- divd2 = new BigDecimal(0000D);
-
- try {
- divd1.divide(divd2, 4, BigDecimal.ROUND_DOWN);
- fail("divide by zero is not caught");
- } catch (ArithmeticException e) {
- }
- }
-
- /**
- * @tests java.math.BigDecimal#doubleValue()
- */
- public void test_doubleValue() {
- BigDecimal bigDB = new BigDecimal(-1.234E-112);
-// Commenting out this part because it causes an endless loop (see HARMONY-319 and HARMONY-329)
-// assertTrue(
-// "the double representation of this BigDecimal is not correct",
-// bigDB.doubleValue() == -1.234E-112);
- bigDB = new BigDecimal(5.00E-324);
- assertTrue("the double representation of bigDecimal is not correct",
- bigDB.doubleValue() == 5.00E-324);
- bigDB = new BigDecimal(1.79E308);
- assertTrue("the double representation of bigDecimal is not correct",
- bigDB.doubleValue() == 1.79E308 && bigDB.scale() == 0);
- bigDB = new BigDecimal(-2.33E102);
- assertTrue(
- "the double representation of bigDecimal -2.33E102 is not correct",
- bigDB.doubleValue() == -2.33E102 && bigDB.scale() == 0);
- bigDB = new BigDecimal(Double.MAX_VALUE);
- bigDB = bigDB.add(bigDB);
- assertTrue(
- "a + number out of the double range should return infinity",
- bigDB.doubleValue() == Double.POSITIVE_INFINITY);
- bigDB = new BigDecimal(-Double.MAX_VALUE);
- bigDB = bigDB.add(bigDB);
- assertTrue(
- "a - number out of the double range should return neg infinity",
- bigDB.doubleValue() == Double.NEGATIVE_INFINITY);
- }
-
- /**
- * @tests java.math.BigDecimal#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- BigDecimal equal1 = new BigDecimal(1.00D);
- BigDecimal equal2 = new BigDecimal("1.0");
- assertFalse("1.00 and 1.0 should not be equal",
- equal1.equals(equal2));
- equal2 = new BigDecimal(1.01D);
- assertFalse("1.00 and 1.01 should not be equal",
- equal1.equals(equal2));
- equal2 = new BigDecimal("1.00");
- assertFalse("1.00D and 1.00 should not be equal",
- equal1.equals(equal2));
- BigInteger val = new BigInteger("100");
- equal1 = new BigDecimal("1.00");
- equal2 = new BigDecimal(val, 2);
- assertTrue("1.00(string) and 1.00(bigInteger) should be equal", equal1
- .equals(equal2));
- equal1 = new BigDecimal(100D);
- equal2 = new BigDecimal("2.34576");
- assertFalse("100D and 2.34576 should not be equal", equal1
- .equals(equal2));
- assertFalse("bigDecimal 100D does not equal string 23415", equal1
- .equals("23415"));
- }
-
- /**
- * @tests java.math.BigDecimal#floatValue()
- */
- public void test_floatValue() {
- BigDecimal fl1 = new BigDecimal("234563782344567");
- assertTrue("the float representation of bigDecimal 234563782344567",
- fl1.floatValue() == 234563782344567f);
- BigDecimal fl2 = new BigDecimal(2.345E37);
- assertTrue("the float representation of bigDecimal 2.345E37", fl2
- .floatValue() == 2.345E37F);
- fl2 = new BigDecimal(-1.00E-44);
- assertTrue("the float representation of bigDecimal -1.00E-44", fl2
- .floatValue() == -1.00E-44F);
- fl2 = new BigDecimal(-3E12);
- assertTrue("the float representation of bigDecimal -3E12", fl2
- .floatValue() == -3E12F);
- fl2 = new BigDecimal(Double.MAX_VALUE);
- assertTrue(
- "A number can't be represented by float should return infinity",
- fl2.floatValue() == Float.POSITIVE_INFINITY);
- fl2 = new BigDecimal(-Double.MAX_VALUE);
- assertTrue(
- "A number can't be represented by float should return infinity",
- fl2.floatValue() == Float.NEGATIVE_INFINITY);
-
- }
-
- /**
- * @tests java.math.BigDecimal#hashCode()
- */
- public void test_hashCode() {
- // anything that is equal must have the same hashCode
- BigDecimal hash = new BigDecimal("1.00");
- BigDecimal hash2 = new BigDecimal(1.00D);
- assertTrue("the hashCode of 1.00 and 1.00D is equal",
- hash.hashCode() != hash2.hashCode() && !hash.equals(hash2));
- hash2 = new BigDecimal("1.0");
- assertTrue("the hashCode of 1.0 and 1.00 is equal",
- hash.hashCode() != hash2.hashCode() && !hash.equals(hash2));
- BigInteger val = new BigInteger("100");
- hash2 = new BigDecimal(val, 2);
- assertTrue("hashCode of 1.00 and 1.00(bigInteger) is not equal", hash
- .hashCode() == hash2.hashCode()
- && hash.equals(hash2));
- hash = new BigDecimal(value, 2);
- hash2 = new BigDecimal("-1233456.0000");
- assertTrue("hashCode of 123459.08 and -1233456.0000 is not equal", hash
- .hashCode() != hash2.hashCode()
- && !hash.equals(hash2));
- hash2 = new BigDecimal(value.negate(), 2);
- assertTrue("hashCode of 123459.08 and -123459.08 is not equal", hash
- .hashCode() != hash2.hashCode()
- && !hash.equals(hash2));
- }
-
- /**
- * @tests java.math.BigDecimal#intValue()
- */
- public void test_intValue() {
- BigDecimal int1 = new BigDecimal(value, 3);
- assertTrue("the int value of 12345.908 is not 12345",
- int1.intValue() == 12345);
- int1 = new BigDecimal("1.99");
- assertTrue("the int value of 1.99 is not 1", int1.intValue() == 1);
- int1 = new BigDecimal("23423419083091823091283933");
- // ran JDK and found representation for the above was -249268259
- assertTrue("the int value of 23423419083091823091283933 is wrong", int1
- .intValue() == -249268259);
- int1 = new BigDecimal(-1235D);
- assertTrue("the int value of -1235 is not -1235",
- int1.intValue() == -1235);
- }
-
- /**
- * @tests java.math.BigDecimal#longValue()
- */
- public void test_longValue() {
- BigDecimal long1 = new BigDecimal(value2.negate(), 0);
- assertTrue("the long value of 12334560000 is not 12334560000", long1
- .longValue() == -12334560000L);
- long1 = new BigDecimal(-1345.348E-123D);
- assertTrue("the long value of -1345.348E-123D is not zero", long1
- .longValue() == 0);
- long1 = new BigDecimal("31323423423419083091823091283933");
- // ran JDK and found representation for the above was
- // -5251313250005125155
- assertTrue(
- "the long value of 31323423423419083091823091283933 is wrong",
- long1.longValue() == -5251313250005125155L);
- }
-
- /**
- * @tests java.math.BigDecimal#max(java.math.BigDecimal)
- */
- public void test_maxLjava_math_BigDecimal() {
- BigDecimal max1 = new BigDecimal(value2, 1);
- BigDecimal max2 = new BigDecimal(value2, 4);
- assertTrue("1233456000.0 is not greater than 1233456", max1.max(max2)
- .equals(max1));
- max1 = new BigDecimal(-1.224D);
- max2 = new BigDecimal(-1.2245D);
- assertTrue("-1.224 is not greater than -1.2245", max1.max(max2).equals(
- max1));
- max1 = new BigDecimal(123E18);
- max2 = new BigDecimal(123E19);
- assertTrue("123E19 is the not the max", max1.max(max2).equals(max2));
- }
-
- /**
- * @tests java.math.BigDecimal#min(java.math.BigDecimal)
- */
- public void test_minLjava_math_BigDecimal() {
- BigDecimal min1 = new BigDecimal(-12345.4D);
- BigDecimal min2 = new BigDecimal(-12345.39D);
- assertTrue("-12345.39 should have been returned", min1.min(min2)
- .equals(min1));
- min1 = new BigDecimal(value2, 5);
- min2 = new BigDecimal(value2, 0);
- assertTrue("123345.6 should have been returned", min1.min(min2).equals(
- min1));
- }
-
- /**
- * @tests java.math.BigDecimal#movePointLeft(int)
- */
- public void test_movePointLeftI() {
- BigDecimal movePtLeft = new BigDecimal("123456265.34");
- BigDecimal alreadyMoved = movePtLeft.movePointLeft(5);
- assertTrue("move point left 5 failed", alreadyMoved.scale() == 7
- && alreadyMoved.toString().equals("1234.5626534"));
- movePtLeft = new BigDecimal(value2.negate(), 0);
- alreadyMoved = movePtLeft.movePointLeft(12);
- assertTrue("move point left 12 failed", alreadyMoved.scale() == 12
- && alreadyMoved.toString().equals("-0.012334560000"));
- movePtLeft = new BigDecimal(123E18);
- alreadyMoved = movePtLeft.movePointLeft(2);
- assertTrue("move point left 2 failed",
- alreadyMoved.scale() == movePtLeft.scale() + 2
- && alreadyMoved.doubleValue() == 1.23E18);
- movePtLeft = new BigDecimal(1.123E-12);
- alreadyMoved = movePtLeft.movePointLeft(3);
- assertTrue("move point left 3 failed",
- alreadyMoved.scale() == movePtLeft.scale() + 3
- && alreadyMoved.doubleValue() == 1.123E-15);
- movePtLeft = new BigDecimal(value, 2);
- alreadyMoved = movePtLeft.movePointLeft(-2);
- assertTrue("move point left -2 failed",
- alreadyMoved.scale() == movePtLeft.scale() - 2
- && alreadyMoved.toString().equals("12345908"));
- }
-
- /**
- * @tests java.math.BigDecimal#movePointRight(int)
- */
- public void test_movePointRightI() {
- BigDecimal movePtRight = new BigDecimal("-1.58796521458");
- BigDecimal alreadyMoved = movePtRight.movePointRight(8);
- assertTrue("move point right 8 failed", alreadyMoved.scale() == 3
- && alreadyMoved.toString().equals("-158796521.458"));
- movePtRight = new BigDecimal(value, 2);
- alreadyMoved = movePtRight.movePointRight(4);
- assertTrue("move point right 4 failed", alreadyMoved.scale() == 0
- && alreadyMoved.toString().equals("1234590800"));
- movePtRight = new BigDecimal(134E12);
- alreadyMoved = movePtRight.movePointRight(2);
- assertTrue("move point right 2 failed", alreadyMoved.scale() == 0
- && alreadyMoved.toString().equals("13400000000000000"));
- movePtRight = new BigDecimal(-3.4E-10);
- alreadyMoved = movePtRight.movePointRight(5);
- assertTrue("move point right 5 failed",
- alreadyMoved.scale() == movePtRight.scale() - 5
- && alreadyMoved.doubleValue() == -0.000034);
- alreadyMoved = alreadyMoved.movePointRight(-5);
- assertTrue("move point right -5 failed", alreadyMoved
- .equals(movePtRight));
- }
-
- /**
- * @tests java.math.BigDecimal#multiply(java.math.BigDecimal)
- */
- public void test_multiplyLjava_math_BigDecimal() {
- BigDecimal multi1 = new BigDecimal(value, 5);
- BigDecimal multi2 = new BigDecimal(2.345D);
- BigDecimal result = multi1.multiply(multi2);
- assertTrue("123.45908 * 2.345 is not correct: " + result, result
- .toString().startsWith("289.51154260")
- && result.scale() == multi1.scale() + multi2.scale());
- multi1 = new BigDecimal("34656");
- multi2 = new BigDecimal("-2");
- result = multi1.multiply(multi2);
- assertTrue("34656 * 2 is not correct", result.toString().equals(
- "-69312")
- && result.scale() == 0);
- multi1 = new BigDecimal(-2.345E-02);
- multi2 = new BigDecimal(-134E130);
- result = multi1.multiply(multi2);
- assertTrue("-2.345E-02 * -134E130 is not correct " + result.doubleValue(),
- result.doubleValue() == 3.1422999999999997E130
- && result.scale() == multi1.scale() + multi2.scale());
- multi1 = new BigDecimal("11235");
- multi2 = new BigDecimal("0");
- result = multi1.multiply(multi2);
- assertTrue("11235 * 0 is not correct", result.doubleValue() == 0
- && result.scale() == 0);
- multi1 = new BigDecimal("-0.00234");
- multi2 = new BigDecimal(13.4E10);
- result = multi1.multiply(multi2);
- assertTrue("-0.00234 * 13.4E10 is not correct",
- result.doubleValue() == -313560000
- && result.scale() == multi1.scale() + multi2.scale());
- }
-
- /**
- * @tests java.math.BigDecimal#negate()
- */
- public void test_negate() {
- BigDecimal negate1 = new BigDecimal(value2, 7);
- assertTrue("the negate of 1233.4560000 is not -1233.4560000", negate1
- .negate().toString().equals("-1233.4560000"));
- negate1 = new BigDecimal("-23465839");
- assertTrue("the negate of -23465839 is not 23465839", negate1.negate()
- .toString().equals("23465839"));
- negate1 = new BigDecimal(-3.456E6);
- assertTrue("the negate of -3.456E6 is not 3.456E6", negate1.negate()
- .negate().equals(negate1));
- }
-
- /**
- * @tests java.math.BigDecimal#scale()
- */
- public void test_scale() {
- BigDecimal scale1 = new BigDecimal(value2, 8);
- assertTrue("the scale of the number 123.34560000 is wrong", scale1
- .scale() == 8);
- BigDecimal scale2 = new BigDecimal("29389.");
- assertTrue("the scale of the number 29389. is wrong",
- scale2.scale() == 0);
- BigDecimal scale3 = new BigDecimal(3.374E13);
- assertTrue("the scale of the number 3.374E13 is wrong",
- scale3.scale() == 0);
- BigDecimal scale4 = new BigDecimal("-3.45E-203");
- // note the scale is calculated as 15 digits of 345000.... + exponent -
- // 1. -1 for the 3
- assertTrue("the scale of the number -3.45E-203 is wrong: "
- + scale4.scale(), scale4.scale() == 205);
- scale4 = new BigDecimal("-345.4E-200");
- assertTrue("the scale of the number -345.4E-200 is wrong", scale4
- .scale() == 201);
- }
-
- /**
- * @tests java.math.BigDecimal#setScale(int)
- */
- public void test_setScaleI() {
- // rounding mode defaults to zero
- BigDecimal setScale1 = new BigDecimal(value, 3);
- BigDecimal setScale2 = setScale1.setScale(5);
- BigInteger setresult = new BigInteger("1234590800");
- assertTrue("the number 12345.908 after setting scale is wrong",
- setScale2.unscaledValue().equals(setresult)
- && setScale2.scale() == 5);
-
- try {
- setScale2 = setScale1.setScale(2, BigDecimal.ROUND_UNNECESSARY);
- fail("arithmetic Exception not caught as a result of loosing precision");
- } catch (ArithmeticException e) {
- }
- }
-
- /**
- * @tests java.math.BigDecimal#setScale(int, int)
- */
- public void test_setScaleII() {
- BigDecimal setScale1 = new BigDecimal(2.323E102);
- BigDecimal setScale2 = setScale1.setScale(4);
- assertTrue("the number 2.323E102 after setting scale is wrong",
- setScale2.scale() == 4);
- assertTrue("the representation of the number 2.323E102 is wrong",
- setScale2.doubleValue() == 2.323E102);
- setScale1 = new BigDecimal("-1.253E-12");
- setScale2 = setScale1.setScale(17, BigDecimal.ROUND_CEILING);
- assertTrue("the number -1.253E-12 after setting scale is wrong",
- setScale2.scale() == 17);
- assertTrue(
- "the representation of the number -1.253E-12 after setting scale is wrong, " + setScale2.toString(),
- setScale2.toString().equals("-1.25300E-12"));
-
- // testing rounding Mode ROUND_CEILING
- setScale1 = new BigDecimal(value, 4);
- setScale2 = setScale1.setScale(1, BigDecimal.ROUND_CEILING);
- assertTrue(
- "the number 1234.5908 after setting scale to 1/ROUND_CEILING is wrong",
- setScale2.toString().equals("1234.6") && setScale2.scale() == 1);
- BigDecimal setNeg = new BigDecimal(value.negate(), 4);
- setScale2 = setNeg.setScale(1, BigDecimal.ROUND_CEILING);
- assertTrue(
- "the number -1234.5908 after setting scale to 1/ROUND_CEILING is wrong",
- setScale2.toString().equals("-1234.5")
- && setScale2.scale() == 1);
-
- // testing rounding Mode ROUND_DOWN
- setScale2 = setNeg.setScale(1, BigDecimal.ROUND_DOWN);
- assertTrue(
- "the number -1234.5908 after setting scale to 1/ROUND_DOWN is wrong",
- setScale2.toString().equals("-1234.5")
- && setScale2.scale() == 1);
- setScale1 = new BigDecimal(value, 4);
- setScale2 = setScale1.setScale(1, BigDecimal.ROUND_DOWN);
- assertTrue(
- "the number 1234.5908 after setting scale to 1/ROUND_DOWN is wrong",
- setScale2.toString().equals("1234.5") && setScale2.scale() == 1);
-
- // testing rounding Mode ROUND_FLOOR
- setScale2 = setScale1.setScale(1, BigDecimal.ROUND_FLOOR);
- assertTrue(
- "the number 1234.5908 after setting scale to 1/ROUND_FLOOR is wrong",
- setScale2.toString().equals("1234.5") && setScale2.scale() == 1);
- setScale2 = setNeg.setScale(1, BigDecimal.ROUND_FLOOR);
- assertTrue(
- "the number -1234.5908 after setting scale to 1/ROUND_FLOOR is wrong",
- setScale2.toString().equals("-1234.6")
- && setScale2.scale() == 1);
-
- // testing rounding Mode ROUND_HALF_DOWN
- setScale2 = setScale1.setScale(3, BigDecimal.ROUND_HALF_DOWN);
- assertTrue(
- "the number 1234.5908 after setting scale to 3/ROUND_HALF_DOWN is wrong",
- setScale2.toString().equals("1234.591")
- && setScale2.scale() == 3);
- setScale1 = new BigDecimal(new BigInteger("12345000"), 5);
- setScale2 = setScale1.setScale(1, BigDecimal.ROUND_HALF_DOWN);
- assertTrue(
- "the number 123.45908 after setting scale to 1/ROUND_HALF_DOWN is wrong",
- setScale2.toString().equals("123.4") && setScale2.scale() == 1);
- setScale2 = new BigDecimal("-1234.5000").setScale(0,
- BigDecimal.ROUND_HALF_DOWN);
- assertTrue(
- "the number -1234.5908 after setting scale to 0/ROUND_HALF_DOWN is wrong",
- setScale2.toString().equals("-1234") && setScale2.scale() == 0);
-
- // testing rounding Mode ROUND_HALF_EVEN
- setScale1 = new BigDecimal(1.2345789D);
- setScale2 = setScale1.setScale(4, BigDecimal.ROUND_HALF_EVEN);
- assertTrue(
- "the number 1.2345789 after setting scale to 4/ROUND_HALF_EVEN is wrong",
- setScale2.doubleValue() == 1.2346D && setScale2.scale() == 4);
- setNeg = new BigDecimal(-1.2335789D);
- setScale2 = setNeg.setScale(2, BigDecimal.ROUND_HALF_EVEN);
- assertTrue(
- "the number -1.2335789 after setting scale to 2/ROUND_HALF_EVEN is wrong",
- setScale2.doubleValue() == -1.23D && setScale2.scale() == 2);
- setScale2 = new BigDecimal("1.2345000").setScale(3,
- BigDecimal.ROUND_HALF_EVEN);
- assertTrue(
- "the number 1.2345789 after setting scale to 3/ROUND_HALF_EVEN is wrong",
- setScale2.doubleValue() == 1.234D && setScale2.scale() == 3);
- setScale2 = new BigDecimal("-1.2345000").setScale(3,
- BigDecimal.ROUND_HALF_EVEN);
- assertTrue(
- "the number -1.2335789 after setting scale to 3/ROUND_HALF_EVEN is wrong",
- setScale2.doubleValue() == -1.234D && setScale2.scale() == 3);
-
- // testing rounding Mode ROUND_HALF_UP
- setScale1 = new BigDecimal("134567.34650");
- setScale2 = setScale1.setScale(3, BigDecimal.ROUND_HALF_UP);
- assertTrue(
- "the number 134567.34658 after setting scale to 3/ROUND_HALF_UP is wrong",
- setScale2.toString().equals("134567.347")
- && setScale2.scale() == 3);
- setNeg = new BigDecimal("-1234.4567");
- setScale2 = setNeg.setScale(0, BigDecimal.ROUND_HALF_UP);
- assertTrue(
- "the number -1234.4567 after setting scale to 0/ROUND_HALF_UP is wrong",
- setScale2.toString().equals("-1234") && setScale2.scale() == 0);
-
- // testing rounding Mode ROUND_UNNECESSARY
- try {
- setScale1.setScale(3, BigDecimal.ROUND_UNNECESSARY);
- fail("arithmetic Exception not caught for round unnecessary");
- } catch (ArithmeticException e) {
- }
-
- // testing rounding Mode ROUND_UP
- setScale1 = new BigDecimal("100000.374");
- setScale2 = setScale1.setScale(2, BigDecimal.ROUND_UP);
- assertTrue(
- "the number 100000.374 after setting scale to 2/ROUND_UP is wrong",
- setScale2.toString().equals("100000.38")
- && setScale2.scale() == 2);
- setNeg = new BigDecimal(-134.34589D);
- setScale2 = setNeg.setScale(2, BigDecimal.ROUND_UP);
- assertTrue(
- "the number -134.34589 after setting scale to 2/ROUND_UP is wrong",
- setScale2.doubleValue() == -134.35D && setScale2.scale() == 2);
-
- // testing invalid rounding modes
- try {
- setScale2 = setScale1.setScale(0, -123);
- fail("IllegalArgumentException is not caught for wrong rounding mode");
- } catch (IllegalArgumentException e) {
- }
- }
-
- /**
- * @tests java.math.BigDecimal#signum()
- */
- public void test_signum() {
- BigDecimal sign = new BigDecimal(123E-104);
- assertTrue("123E-104 is not positive in signum()", sign.signum() == 1);
- sign = new BigDecimal("-1234.3959");
- assertTrue("-1234.3959 is not negative in signum()",
- sign.signum() == -1);
- sign = new BigDecimal(000D);
- assertTrue("000D is not zero in signum()", sign.signum() == 0);
- }
-
- /**
- * @tests java.math.BigDecimal#subtract(java.math.BigDecimal)
- */
- public void test_subtractLjava_math_BigDecimal() {
- BigDecimal sub1 = new BigDecimal("13948");
- BigDecimal sub2 = new BigDecimal("2839.489");
- BigDecimal result = sub1.subtract(sub2);
- assertTrue("13948 - 2839.489 is wrong: " + result, result.toString()
- .equals("11108.511")
- && result.scale() == 3);
- BigDecimal result2 = sub2.subtract(sub1);
- assertTrue("2839.489 - 13948 is wrong", result2.toString().equals(
- "-11108.511")
- && result2.scale() == 3);
- assertTrue("13948 - 2839.489 is not the negative of 2839.489 - 13948",
- result.equals(result2.negate()));
- sub1 = new BigDecimal(value, 1);
- sub2 = new BigDecimal("0");
- result = sub1.subtract(sub2);
- assertTrue("1234590.8 - 0 is wrong", result.equals(sub1));
- sub1 = new BigDecimal(1.234E-03);
- sub2 = new BigDecimal(3.423E-10);
- result = sub1.subtract(sub2);
- assertTrue("1.234E-03 - 3.423E-10 is wrong, " + result.doubleValue(),
- result.doubleValue() == 0.0012339996577);
- sub1 = new BigDecimal(1234.0123);
- sub2 = new BigDecimal(1234.0123000);
- result = sub1.subtract(sub2);
- assertTrue("1234.0123 - 1234.0123000 is wrong, " + result.doubleValue(),
- result.doubleValue() == 0.0);
- }
-
- /**
- * @tests java.math.BigDecimal#toBigInteger()
- */
- public void test_toBigInteger() {
- BigDecimal sub1 = new BigDecimal("-29830.989");
- BigInteger result = sub1.toBigInteger();
-
- assertTrue("the bigInteger equivalent of -29830.989 is wrong", result
- .toString().equals("-29830"));
- sub1 = new BigDecimal(-2837E10);
- result = sub1.toBigInteger();
- assertTrue("the bigInteger equivalent of -2837E10 is wrong", result
- .doubleValue() == -2837E10);
- sub1 = new BigDecimal(2.349E-10);
- result = sub1.toBigInteger();
- assertTrue("the bigInteger equivalent of 2.349E-10 is wrong", result
- .equals(BigInteger.ZERO));
- sub1 = new BigDecimal(value2, 6);
- result = sub1.toBigInteger();
- assertTrue("the bigInteger equivalent of 12334.560000 is wrong", result
- .toString().equals("12334"));
- }
-
- /**
- * @tests java.math.BigDecimal#toString()
- */
- public void test_toString() {
- BigDecimal toString1 = new BigDecimal("1234.000");
- assertTrue("the toString representation of 1234.000 is wrong",
- toString1.toString().equals("1234.000"));
- toString1 = new BigDecimal("-123.4E-5");
- assertTrue("the toString representation of -123.4E-5 is wrong: "
- + toString1, toString1.toString().equals("-0.001234"));
- toString1 = new BigDecimal("-1.455E-20");
- assertTrue("the toString representation of -1.455E-20 is wrong",
- toString1.toString().equals("-1.455E-20"));
- toString1 = new BigDecimal(value2, 4);
- assertTrue("the toString representation of 1233456.0000 is wrong",
- toString1.toString().equals("1233456.0000"));
- }
-
- /**
- * @tests java.math.BigDecimal#unscaledValue()
- */
- public void test_unscaledValue() {
- BigDecimal unsVal = new BigDecimal("-2839485.000");
- assertTrue("the unscaledValue of -2839485.000 is wrong", unsVal
- .unscaledValue().toString().equals("-2839485000"));
- unsVal = new BigDecimal(123E10);
- assertTrue("the unscaledValue of 123E10 is wrong", unsVal
- .unscaledValue().toString().equals("1230000000000"));
- unsVal = new BigDecimal("-4.56E-13");
- assertTrue("the unscaledValue of -4.56E-13 is wrong: "
- + unsVal.unscaledValue(), unsVal.unscaledValue().toString()
- .equals("-456"));
- unsVal = new BigDecimal(value, 3);
- assertTrue("the unscaledValue of 12345.908 is wrong", unsVal
- .unscaledValue().toString().equals("12345908"));
-
- }
-
- /**
- * @tests java.math.BigDecimal#valueOf(long)
- */
- public void test_valueOfJ() {
- BigDecimal valueOfL = BigDecimal.valueOf(9223372036854775806L);
- assertTrue("the bigDecimal equivalent of 9223372036854775806 is wrong",
- valueOfL.unscaledValue().toString().equals(
- "9223372036854775806")
- && valueOfL.scale() == 0);
- assertTrue(
- "the toString representation of 9223372036854775806 is wrong",
- valueOfL.toString().equals("9223372036854775806"));
- valueOfL = BigDecimal.valueOf(0L);
- assertTrue("the bigDecimal equivalent of 0 is wrong", valueOfL
- .unscaledValue().toString().equals("0")
- && valueOfL.scale() == 0);
- }
-
- /**
- * @tests java.math.BigDecimal#valueOf(long, int)
- */
- public void test_valueOfJI() {
- BigDecimal valueOfJI = BigDecimal.valueOf(9223372036854775806L, 5);
- assertTrue(
- "the bigDecimal equivalent of 92233720368547.75806 is wrong",
- valueOfJI.unscaledValue().toString().equals(
- "9223372036854775806")
- && valueOfJI.scale() == 5);
- assertTrue(
- "the toString representation of 9223372036854775806 is wrong",
- valueOfJI.toString().equals("92233720368547.75806"));
- valueOfJI = BigDecimal.valueOf(1234L, 8);
- assertTrue(
- "the bigDecimal equivalent of 92233720368547.75806 is wrong",
- valueOfJI.unscaledValue().toString().equals("1234")
- && valueOfJI.scale() == 8);
- assertTrue(
- "the toString representation of 9223372036854775806 is wrong",
- valueOfJI.toString().equals("0.00001234"));
- valueOfJI = BigDecimal.valueOf(0, 3);
- assertTrue(
- "the bigDecimal equivalent of 92233720368547.75806 is wrong",
- valueOfJI.unscaledValue().toString().equals("0")
- && valueOfJI.scale() == 3);
- assertTrue(
- "the toString representation of 9223372036854775806 is wrong",
- valueOfJI.toString().equals("0.000"));
-
- }
-
- public void test_BigDecimal_serialization() throws Exception {
- // Regression for HARMONY-1896
- char[] in = { '1', '5', '6', '7', '8', '7', '.', '0', '0' };
- BigDecimal bd = new BigDecimal(in, 0, 9);
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(bd);
-
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bis);
- BigDecimal nbd = (BigDecimal) ois.readObject();
-
- assertEquals(bd.intValue(), nbd.intValue());
- assertEquals(bd.doubleValue(), nbd.doubleValue(), 0.0);
- assertEquals(bd.toString(), nbd.toString());
- }
-
- /**
- * @tests java.math.BigDecimal#stripTrailingZero(long)
- */
- public void test_stripTrailingZero() {
- BigDecimal sixhundredtest = new BigDecimal("600.0");
- assertTrue("stripTrailingZero failed for 600.0",
- ((sixhundredtest.stripTrailingZeros()).scale() == -2)
- );
-
- /* Single digit, no trailing zero, odd number */
- BigDecimal notrailingzerotest = new BigDecimal("1");
- assertTrue("stripTrailingZero failed for 1",
- ((notrailingzerotest.stripTrailingZeros()).scale() == 0)
- );
-
- // BEGIN android-changed: preserve RI compatibility, so BigDecimal.equals (which checks
- // value *and* scale) continues to work. https://issues.apache.org/jira/browse/HARMONY-4623
- /* Zero */
- BigDecimal zerotest = new BigDecimal("0.0000");
- assertEquals("stripTrailingZero failed for 0.0000", 4, zerotest.stripTrailingZeros().scale());
- }
-
- public void testMathContextConstruction() {
- String a = "-12380945E+61";
- BigDecimal aNumber = new BigDecimal(a);
- int precision = 6;
- RoundingMode rm = RoundingMode.HALF_DOWN;
- MathContext mcIntRm = new MathContext(precision, rm);
- MathContext mcStr = new MathContext("precision=6 roundingMode=HALF_DOWN");
- MathContext mcInt = new MathContext(precision);
- BigDecimal res = aNumber.abs(mcInt);
- assertEquals("MathContext Constructer with int precision failed",
- res,
- new BigDecimal("1.23809E+68"));
-
- assertEquals("Equal MathContexts are not Equal ",
- mcIntRm,
- mcStr);
-
- assertEquals("Different MathContext are reported as Equal ",
- mcInt.equals(mcStr),
- false);
-
- assertEquals("Equal MathContexts have different hashcodes ",
- mcIntRm.hashCode(),
- mcStr.hashCode());
-
- assertEquals("MathContext.toString() returning incorrect value",
- mcIntRm.toString(),
- "precision=6 roundingMode=HALF_DOWN");
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/math/BigIntegerTest.java b/harmony-tests/src/test/java/tests/api/java/math/BigIntegerTest.java
deleted file mode 100644
index 28995cb..0000000
--- a/harmony-tests/src/test/java/tests/api/java/math/BigIntegerTest.java
+++ /dev/null
@@ -1,988 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.math;
-
-import java.math.BigInteger;
-import java.util.Random;
-
-public class BigIntegerTest extends junit.framework.TestCase {
-
- BigInteger minusTwo = new BigInteger("-2", 10);
-
- BigInteger minusOne = new BigInteger("-1", 10);
-
- BigInteger zero = new BigInteger("0", 10);
-
- BigInteger one = new BigInteger("1", 10);
-
- BigInteger two = new BigInteger("2", 10);
-
- BigInteger ten = new BigInteger("10", 10);
-
- BigInteger sixteen = new BigInteger("16", 10);
-
- BigInteger oneThousand = new BigInteger("1000", 10);
-
- BigInteger aZillion = new BigInteger(
- "100000000000000000000000000000000000000000000000000", 10);
-
- BigInteger twoToTheTen = new BigInteger("1024", 10);
-
- BigInteger twoToTheSeventy = two.pow(70);
-
- Random rand = new Random();
-
- BigInteger bi;
-
- BigInteger bi1;
-
- BigInteger bi2;
-
- BigInteger bi3;
-
- BigInteger bi11;
-
- BigInteger bi22;
-
- BigInteger bi33;
-
- BigInteger bi12;
-
- BigInteger bi23;
-
- BigInteger bi13;
-
- BigInteger largePos;
-
- BigInteger smallPos;
-
- BigInteger largeNeg;
-
- BigInteger smallNeg;
-
- BigInteger[][] booleanPairs;
-
- /**
- * @tests java.math.BigInteger#BigInteger(int, java.util.Random)
- */
- public void test_ConstructorILjava_util_Random() {
- // regression test for HARMONY-1047
- try {
- new BigInteger(Integer.MAX_VALUE, (Random)null);
- fail("NegativeArraySizeException expected");
- } catch (NegativeArraySizeException e) {
- // PASSED
- }
-
- bi = new BigInteger(70, rand);
- bi2 = new BigInteger(70, rand);
- assertTrue("Random number is negative", bi.compareTo(zero) >= 0);
- assertTrue("Random number is too big",
- bi.compareTo(twoToTheSeventy) < 0);
- assertTrue(
- "Two random numbers in a row are the same (might not be a bug but it very likely is)",
- !bi.equals(bi2));
- assertTrue("Not zero", new BigInteger(0, rand).equals(BigInteger.ZERO));
- }
-
- /**
- * @tests java.math.BigInteger#BigInteger(byte[])
- */
- public void test_Constructor$B() {
- byte[] myByteArray;
- myByteArray = new byte[] { (byte) 0x00, (byte) 0xFF, (byte) 0xFE };
- bi = new BigInteger(myByteArray);
- assertTrue("Incorrect value for pos number", bi.equals(BigInteger.ZERO
- .setBit(16).subtract(two)));
- myByteArray = new byte[] { (byte) 0xFF, (byte) 0xFE };
- bi = new BigInteger(myByteArray);
- assertTrue("Incorrect value for neg number", bi.equals(minusTwo));
- }
-
- /**
- * @tests java.math.BigInteger#BigInteger(int, byte[])
- */
- public void test_ConstructorI$B() {
- byte[] myByteArray;
- myByteArray = new byte[] { (byte) 0xFF, (byte) 0xFE };
- bi = new BigInteger(1, myByteArray);
- assertTrue("Incorrect value for pos number", bi.equals(BigInteger.ZERO
- .setBit(16).subtract(two)));
- bi = new BigInteger(-1, myByteArray);
- assertTrue("Incorrect value for neg number", bi.equals(BigInteger.ZERO
- .setBit(16).subtract(two).negate()));
- myByteArray = new byte[] { (byte) 0, (byte) 0 };
- bi = new BigInteger(0, myByteArray);
- assertTrue("Incorrect value for zero", bi.equals(zero));
- myByteArray = new byte[] { (byte) 1 };
- try {
- new BigInteger(0, myByteArray);
- fail("Failed to throw NumberFormatException");
- } catch (NumberFormatException e) {
- // correct
- }
- }
-
- /**
- * @tests java.math.BigInteger#BigInteger(java.lang.String)
- */
- public void test_constructor_String_empty() {
- try {
- new BigInteger("");
- fail("Expected NumberFormatException for new BigInteger(\"\")");
- } catch (NumberFormatException e) {
- }
- }
-
- /**
- * @tests java.math.BigInteger#toByteArray()
- */
- public void test_toByteArray() {
- byte[] myByteArray, anotherByteArray;
- myByteArray = new byte[] { 97, 33, 120, 124, 50, 2, 0, 0, 0, 12, 124,
- 42 };
- anotherByteArray = new BigInteger(myByteArray).toByteArray();
- assertTrue("Incorrect byte array returned",
- myByteArray.length == anotherByteArray.length);
- for (int counter = myByteArray.length - 1; counter >= 0; counter--) {
- assertTrue("Incorrect values in returned byte array",
- myByteArray[counter] == anotherByteArray[counter]);
- }
- }
-
- /**
- * @tests java.math.BigInteger#isProbablePrime(int)
- */
- public void test_isProbablePrimeI() {
- int fails = 0;
- bi = new BigInteger(20, 20, rand);
- if (!bi.isProbablePrime(17)) {
- fails++;
- }
- bi = new BigInteger("4", 10);
- if (bi.isProbablePrime(17)) {
- fail("isProbablePrime failed for: " + bi);
- }
- bi = BigInteger.valueOf(17L * 13L);
- if (bi.isProbablePrime(17)) {
- fail("isProbablePrime failed for: " + bi);
- }
- for (long a = 2; a < 1000; a++) {
- if (isPrime(a)) {
- assertTrue("false negative on prime number <1000", BigInteger
- .valueOf(a).isProbablePrime(5));
- } else if (BigInteger.valueOf(a).isProbablePrime(17)) {
- System.out.println("isProbablePrime failed for: " + a);
- fails++;
- }
- }
- for (int a = 0; a < 1000; a++) {
- bi = BigInteger.valueOf(rand.nextInt(1000000)).multiply(
- BigInteger.valueOf(rand.nextInt(1000000)));
- if (bi.isProbablePrime(17)) {
- System.out.println("isProbablePrime failed for: " + bi);
- fails++;
- }
- }
- for (int a = 0; a < 200; a++) {
- bi = new BigInteger(70, rand).multiply(new BigInteger(70, rand));
- if (bi.isProbablePrime(17)) {
- System.out.println("isProbablePrime failed for: " + bi);
- fails++;
- }
- }
- assertTrue("Too many false positives - may indicate a problem",
- fails <= 1);
- }
-
- /**
- * @tests java.math.BigInteger#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- assertTrue("0=0", zero.equals(BigInteger.valueOf(0)));
- assertTrue("-123=-123", BigInteger.valueOf(-123).equals(
- BigInteger.valueOf(-123)));
- assertTrue("0=1", !zero.equals(one));
- assertTrue("0=-1", !zero.equals(minusOne));
- assertTrue("1=-1", !one.equals(minusOne));
- assertTrue("bi3=bi3", bi3.equals(bi3));
- assertTrue("bi3=copy of bi3", bi3.equals(bi3.negate().negate()));
- assertTrue("bi3=bi2", !bi3.equals(bi2));
- }
-
- /**
- * @tests java.math.BigInteger#compareTo(java.math.BigInteger)
- */
- public void test_compareToLjava_math_BigInteger() {
- assertTrue("Smaller number returned >= 0", one.compareTo(two) < 0);
- assertTrue("Larger number returned >= 0", two.compareTo(one) > 0);
- assertTrue("Equal numbers did not return 0", one.compareTo(one) == 0);
- assertTrue("Neg number messed things up",
- two.negate().compareTo(one) < 0);
- }
-
- /**
- * @tests java.math.BigInteger#intValue()
- */
- public void test_intValue() {
- assertTrue("Incorrect intValue for 2**70",
- twoToTheSeventy.intValue() == 0);
- assertTrue("Incorrect intValue for 2", two.intValue() == 2);
- }
-
- /**
- * @tests java.math.BigInteger#longValue()
- */
- public void test_longValue() {
- assertTrue("Incorrect longValue for 2**70",
- twoToTheSeventy.longValue() == 0);
- assertTrue("Incorrect longValue for 2", two.longValue() == 2);
- }
-
- /**
- * @tests java.math.BigInteger#valueOf(long)
- */
- public void test_valueOfJ() {
- assertTrue("Incurred number returned for 2", BigInteger.valueOf(2L)
- .equals(two));
- assertTrue("Incurred number returned for 200", BigInteger.valueOf(200L)
- .equals(BigInteger.valueOf(139).add(BigInteger.valueOf(61))));
- }
-
- /**
- * @tests java.math.BigInteger#add(java.math.BigInteger)
- */
- public void test_addLjava_math_BigInteger() {
- assertTrue("Incorrect sum--wanted a zillion", aZillion.add(aZillion)
- .add(aZillion.negate()).equals(aZillion));
- assertTrue("0+0", zero.add(zero).equals(zero));
- assertTrue("0+1", zero.add(one).equals(one));
- assertTrue("1+0", one.add(zero).equals(one));
- assertTrue("1+1", one.add(one).equals(two));
- assertTrue("0+(-1)", zero.add(minusOne).equals(minusOne));
- assertTrue("(-1)+0", minusOne.add(zero).equals(minusOne));
- assertTrue("(-1)+(-1)", minusOne.add(minusOne).equals(minusTwo));
- assertTrue("1+(-1)", one.add(minusOne).equals(zero));
- assertTrue("(-1)+1", minusOne.add(one).equals(zero));
-
- for (int i = 0; i < 200; i++) {
- BigInteger midbit = zero.setBit(i);
- assertTrue("add fails to carry on bit " + i, midbit.add(midbit)
- .equals(zero.setBit(i + 1)));
- }
- BigInteger bi2p3 = bi2.add(bi3);
- BigInteger bi3p2 = bi3.add(bi2);
- assertTrue("bi2p3=bi3p2", bi2p3.equals(bi3p2));
-
- // add large positive + small positive
-
- // add large positive + small negative
-
- // add large negative + small positive
-
- // add large negative + small negative
- }
-
- /**
- * @tests java.math.BigInteger#negate()
- */
- public void test_negate() {
- assertTrue("Single negation of zero did not result in zero", zero
- .negate().equals(zero));
- assertTrue("Single negation resulted in original nonzero number",
- !aZillion.negate().equals(aZillion));
- assertTrue("Double negation did not result in original number",
- aZillion.negate().negate().equals(aZillion));
-
- assertTrue("0.neg", zero.negate().equals(zero));
- assertTrue("1.neg", one.negate().equals(minusOne));
- assertTrue("2.neg", two.negate().equals(minusTwo));
- assertTrue("-1.neg", minusOne.negate().equals(one));
- assertTrue("-2.neg", minusTwo.negate().equals(two));
- assertTrue("0x62EB40FEF85AA9EBL*2.neg", BigInteger.valueOf(
- 0x62EB40FEF85AA9EBL * 2).negate().equals(
- BigInteger.valueOf(-0x62EB40FEF85AA9EBL * 2)));
- for (int i = 0; i < 200; i++) {
- BigInteger midbit = zero.setBit(i);
- BigInteger negate = midbit.negate();
- assertTrue("negate negate", negate.negate().equals(midbit));
- assertTrue("neg fails on bit " + i, midbit.negate().add(midbit)
- .equals(zero));
- }
- }
-
- /**
- * @tests java.math.BigInteger#signum()
- */
- public void test_signum() {
- assertTrue("Wrong positive signum", two.signum() == 1);
- assertTrue("Wrong zero signum", zero.signum() == 0);
- assertTrue("Wrong neg zero signum", zero.negate().signum() == 0);
- assertTrue("Wrong neg signum", two.negate().signum() == -1);
- }
-
- /**
- * @tests java.math.BigInteger#abs()
- */
- public void test_abs() {
- assertTrue("Invalid number returned for zillion", aZillion.negate()
- .abs().equals(aZillion.abs()));
- assertTrue("Invalid number returned for zero neg", zero.negate().abs()
- .equals(zero));
- assertTrue("Invalid number returned for zero", zero.abs().equals(zero));
- assertTrue("Invalid number returned for two", two.negate().abs()
- .equals(two));
- }
-
- /**
- * @tests java.math.BigInteger#pow(int)
- */
- public void test_powI() {
- assertTrue("Incorrect exponent returned for 2**10", two.pow(10).equals(
- twoToTheTen));
- assertTrue("Incorrect exponent returned for 2**70", two.pow(30)
- .multiply(two.pow(40)).equals(twoToTheSeventy));
- assertTrue("Incorrect exponent returned for 10**50", ten.pow(50)
- .equals(aZillion));
- }
-
- /**
- * @tests java.math.BigInteger#modInverse(java.math.BigInteger)
- */
- public void test_modInverseLjava_math_BigInteger() {
- BigInteger a = zero, mod, inv;
- for (int j = 3; j < 50; j++) {
- mod = BigInteger.valueOf(j);
- for (int i = -j + 1; i < j; i++) {
- try {
- a = BigInteger.valueOf(i);
- inv = a.modInverse(mod);
- assertTrue("bad inverse: " + a + " inv mod " + mod
- + " equals " + inv, one.equals(a.multiply(inv).mod(
- mod)));
- assertTrue("inverse greater than modulo: " + a
- + " inv mod " + mod + " equals " + inv, inv
- .compareTo(mod) < 0);
- assertTrue("inverse less than zero: " + a + " inv mod "
- + mod + " equals " + inv, inv
- .compareTo(BigInteger.ZERO) >= 0);
- } catch (ArithmeticException e) {
- assertTrue("should have found inverse for " + a + " mod "
- + mod, !one.equals(a.gcd(mod)));
- }
- }
- }
- for (int j = 1; j < 10; j++) {
- mod = bi2.add(BigInteger.valueOf(j));
- for (int i = 0; i < 20; i++) {
- try {
- a = bi3.add(BigInteger.valueOf(i));
- inv = a.modInverse(mod);
- assertTrue("bad inverse: " + a + " inv mod " + mod
- + " equals " + inv, one.equals(a.multiply(inv).mod(
- mod)));
- assertTrue("inverse greater than modulo: " + a
- + " inv mod " + mod + " equals " + inv, inv
- .compareTo(mod) < 0);
- assertTrue("inverse less than zero: " + a + " inv mod "
- + mod + " equals " + inv, inv
- .compareTo(BigInteger.ZERO) >= 0);
- } catch (ArithmeticException e) {
- assertTrue("should have found inverse for " + a + " mod "
- + mod, !one.equals(a.gcd(mod)));
- }
- }
- }
- }
-
- /**
- * @tests java.math.BigInteger#shiftRight(int)
- */
- public void test_shiftRightI() {
- assertTrue("1 >> 0", BigInteger.valueOf(1).shiftRight(0).equals(
- BigInteger.ONE));
- assertTrue("1 >> 1", BigInteger.valueOf(1).shiftRight(1).equals(
- BigInteger.ZERO));
- assertTrue("1 >> 63", BigInteger.valueOf(1).shiftRight(63).equals(
- BigInteger.ZERO));
- assertTrue("1 >> 64", BigInteger.valueOf(1).shiftRight(64).equals(
- BigInteger.ZERO));
- assertTrue("1 >> 65", BigInteger.valueOf(1).shiftRight(65).equals(
- BigInteger.ZERO));
- assertTrue("1 >> 1000", BigInteger.valueOf(1).shiftRight(1000).equals(
- BigInteger.ZERO));
- assertTrue("-1 >> 0", BigInteger.valueOf(-1).shiftRight(0).equals(
- minusOne));
- assertTrue("-1 >> 1", BigInteger.valueOf(-1).shiftRight(1).equals(
- minusOne));
- assertTrue("-1 >> 63", BigInteger.valueOf(-1).shiftRight(63).equals(
- minusOne));
- assertTrue("-1 >> 64", BigInteger.valueOf(-1).shiftRight(64).equals(
- minusOne));
- assertTrue("-1 >> 65", BigInteger.valueOf(-1).shiftRight(65).equals(
- minusOne));
- assertTrue("-1 >> 1000", BigInteger.valueOf(-1).shiftRight(1000)
- .equals(minusOne));
-
- BigInteger a = BigInteger.ONE;
- BigInteger c = bi3;
- BigInteger E = bi3.negate();
- BigInteger e = E;
- for (int i = 0; i < 200; i++) {
- BigInteger b = BigInteger.ZERO.setBit(i);
- assertTrue("a==b", a.equals(b));
- a = a.shiftLeft(1);
- assertTrue("a non-neg", a.signum() >= 0);
-
- BigInteger d = bi3.shiftRight(i);
- assertTrue("c==d", c.equals(d));
- c = c.shiftRight(1);
- assertTrue(">>1 == /2", d.divide(two).equals(c));
- assertTrue("c non-neg", c.signum() >= 0);
-
- BigInteger f = E.shiftRight(i);
- assertTrue("e==f", e.equals(f));
- e = e.shiftRight(1);
- assertTrue(">>1 == /2", f.subtract(one).divide(two).equals(e));
- assertTrue("e negative", e.signum() == -1);
-
- assertTrue("b >> i", b.shiftRight(i).equals(one));
- assertTrue("b >> i+1", b.shiftRight(i + 1).equals(zero));
- assertTrue("b >> i-1", b.shiftRight(i - 1).equals(two));
- }
- }
-
- /**
- * @tests java.math.BigInteger#shiftLeft(int)
- */
- public void test_shiftLeftI() {
- assertTrue("1 << 0", one.shiftLeft(0).equals(one));
- assertTrue("1 << 1", one.shiftLeft(1).equals(two));
- assertTrue("1 << 63", one.shiftLeft(63).equals(
- new BigInteger("8000000000000000", 16)));
- assertTrue("1 << 64", one.shiftLeft(64).equals(
- new BigInteger("10000000000000000", 16)));
- assertTrue("1 << 65", one.shiftLeft(65).equals(
- new BigInteger("20000000000000000", 16)));
- assertTrue("-1 << 0", minusOne.shiftLeft(0).equals(minusOne));
- assertTrue("-1 << 1", minusOne.shiftLeft(1).equals(minusTwo));
- assertTrue("-1 << 63", minusOne.shiftLeft(63).equals(
- new BigInteger("-9223372036854775808")));
- assertTrue("-1 << 64", minusOne.shiftLeft(64).equals(
- new BigInteger("-18446744073709551616")));
- assertTrue("-1 << 65", minusOne.shiftLeft(65).equals(
- new BigInteger("-36893488147419103232")));
-
- BigInteger a = bi3;
- BigInteger c = minusOne;
- for (int i = 0; i < 200; i++) {
- BigInteger b = bi3.shiftLeft(i);
- assertTrue("a==b", a.equals(b));
- assertTrue("a >> i == bi3", a.shiftRight(i).equals(bi3));
- a = a.shiftLeft(1);
- assertTrue("<<1 == *2", b.multiply(two).equals(a));
- assertTrue("a non-neg", a.signum() >= 0);
- assertTrue("a.bitCount==b.bitCount", a.bitCount() == b.bitCount());
-
- BigInteger d = minusOne.shiftLeft(i);
- assertTrue("c==d", c.equals(d));
- c = c.shiftLeft(1);
- assertTrue("<<1 == *2 negative", d.multiply(two).equals(c));
- assertTrue("c negative", c.signum() == -1);
- assertTrue("d >> i == minusOne", d.shiftRight(i).equals(minusOne));
- }
- }
-
- /**
- * @tests java.math.BigInteger#multiply(java.math.BigInteger)
- */
- public void test_multiplyLjava_math_BigInteger() {
- assertTrue("Incorrect sum--wanted three zillion", aZillion
- .add(aZillion).add(aZillion).equals(
- aZillion.multiply(new BigInteger("3", 10))));
-
- assertTrue("0*0", zero.multiply(zero).equals(zero));
- assertTrue("0*1", zero.multiply(one).equals(zero));
- assertTrue("1*0", one.multiply(zero).equals(zero));
- assertTrue("1*1", one.multiply(one).equals(one));
- assertTrue("0*(-1)", zero.multiply(minusOne).equals(zero));
- assertTrue("(-1)*0", minusOne.multiply(zero).equals(zero));
- assertTrue("(-1)*(-1)", minusOne.multiply(minusOne).equals(one));
- assertTrue("1*(-1)", one.multiply(minusOne).equals(minusOne));
- assertTrue("(-1)*1", minusOne.multiply(one).equals(minusOne));
-
- testAllMults(bi1, bi1, bi11);
- testAllMults(bi2, bi2, bi22);
- testAllMults(bi3, bi3, bi33);
- testAllMults(bi1, bi2, bi12);
- testAllMults(bi1, bi3, bi13);
- testAllMults(bi2, bi3, bi23);
- }
-
- /**
- * @tests java.math.BigInteger#divide(java.math.BigInteger)
- */
- public void test_divideLjava_math_BigInteger() {
- testAllDivs(bi33, bi3);
- testAllDivs(bi22, bi2);
- testAllDivs(bi11, bi1);
- testAllDivs(bi13, bi1);
- testAllDivs(bi13, bi3);
- testAllDivs(bi12, bi1);
- testAllDivs(bi12, bi2);
- testAllDivs(bi23, bi2);
- testAllDivs(bi23, bi3);
- testAllDivs(largePos, bi1);
- testAllDivs(largePos, bi2);
- testAllDivs(largePos, bi3);
- testAllDivs(largeNeg, bi1);
- testAllDivs(largeNeg, bi2);
- testAllDivs(largeNeg, bi3);
- testAllDivs(largeNeg, largePos);
- testAllDivs(largePos, largeNeg);
- testAllDivs(bi3, bi3);
- testAllDivs(bi2, bi2);
- testAllDivs(bi1, bi1);
- testDivRanges(bi1);
- testDivRanges(bi2);
- testDivRanges(bi3);
- testDivRanges(smallPos);
- testDivRanges(largePos);
- testDivRanges(new BigInteger("62EB40FEF85AA9EB", 16));
- testAllDivs(BigInteger.valueOf(0xCC0225953CL), BigInteger
- .valueOf(0x1B937B765L));
-
- try {
- largePos.divide(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- bi1.divide(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- bi3.negate().divide(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- zero.divide(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
- }
-
- /**
- * @tests java.math.BigInteger#remainder(java.math.BigInteger)
- */
- public void test_remainderLjava_math_BigInteger() {
- try {
- largePos.remainder(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- bi1.remainder(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- bi3.negate().remainder(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- zero.remainder(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
- }
-
- /**
- * @tests java.math.BigInteger#mod(java.math.BigInteger)
- */
- public void test_modLjava_math_BigInteger() {
- try {
- largePos.mod(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- bi1.mod(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- bi3.negate().mod(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- zero.mod(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
- }
-
- /**
- * @tests java.math.BigInteger#divideAndRemainder(java.math.BigInteger)
- */
- public void test_divideAndRemainderLjava_math_BigInteger() {
- try {
- largePos.divideAndRemainder(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- bi1.divideAndRemainder(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- bi3.negate().divideAndRemainder(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
-
- try {
- zero.divideAndRemainder(zero);
- fail("ArithmeticException expected");
- } catch (ArithmeticException e) {
- }
- }
-
- /**
- * @tests java.math.BigInteger#BigInteger(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() {
- assertTrue("new(0)", new BigInteger("0").equals(BigInteger.valueOf(0)));
- assertTrue("new(1)", new BigInteger("1").equals(BigInteger.valueOf(1)));
- assertTrue("new(12345678901234)", new BigInteger("12345678901234")
- .equals(BigInteger.valueOf(12345678901234L)));
- assertTrue("new(-1)", new BigInteger("-1").equals(BigInteger
- .valueOf(-1)));
- assertTrue("new(-12345678901234)", new BigInteger("-12345678901234")
- .equals(BigInteger.valueOf(-12345678901234L)));
- }
-
- /**
- * @tests java.math.BigInteger#BigInteger(java.lang.String, int)
- */
- public void test_ConstructorLjava_lang_StringI() {
- assertTrue("new(0,16)", new BigInteger("0", 16).equals(BigInteger
- .valueOf(0)));
- assertTrue("new(1,16)", new BigInteger("1", 16).equals(BigInteger
- .valueOf(1)));
- assertTrue("new(ABF345678901234,16)", new BigInteger("ABF345678901234",
- 16).equals(BigInteger.valueOf(0xABF345678901234L)));
- assertTrue("new(abf345678901234,16)", new BigInteger("abf345678901234",
- 16).equals(BigInteger.valueOf(0xABF345678901234L)));
- assertTrue("new(-1,16)", new BigInteger("-1", 16).equals(BigInteger
- .valueOf(-1)));
- assertTrue("new(-ABF345678901234,16)", new BigInteger(
- "-ABF345678901234", 16).equals(BigInteger
- .valueOf(-0xABF345678901234L)));
- assertTrue("new(-abf345678901234,16)", new BigInteger(
- "-abf345678901234", 16).equals(BigInteger
- .valueOf(-0xABF345678901234L)));
- assertTrue("new(-101010101,2)", new BigInteger("-101010101", 2)
- .equals(BigInteger.valueOf(-341)));
- }
-
- /**
- * @tests java.math.BigInteger#toString()
- */
- public void test_toString() {
- assertTrue("0.toString", "0".equals(BigInteger.valueOf(0).toString()));
- assertTrue("1.toString", "1".equals(BigInteger.valueOf(1).toString()));
- assertTrue("12345678901234.toString", "12345678901234"
- .equals(BigInteger.valueOf(12345678901234L).toString()));
- assertTrue("-1.toString", "-1"
- .equals(BigInteger.valueOf(-1).toString()));
- assertTrue("-12345678901234.toString", "-12345678901234"
- .equals(BigInteger.valueOf(-12345678901234L).toString()));
- }
-
- /**
- * @tests java.math.BigInteger#toString(int)
- */
- public void test_toStringI() {
- assertTrue("0.toString(16)", "0".equals(BigInteger.valueOf(0).toString(
- 16)));
- assertTrue("1.toString(16)", "1".equals(BigInteger.valueOf(1).toString(
- 16)));
- assertTrue("ABF345678901234.toString(16)", "abf345678901234"
- .equals(BigInteger.valueOf(0xABF345678901234L).toString(16)));
- assertTrue("-1.toString(16)", "-1".equals(BigInteger.valueOf(-1)
- .toString(16)));
- assertTrue("-ABF345678901234.toString(16)", "-abf345678901234"
- .equals(BigInteger.valueOf(-0xABF345678901234L).toString(16)));
- assertTrue("-101010101.toString(2)", "-101010101".equals(BigInteger
- .valueOf(-341).toString(2)));
- }
-
- /**
- * @tests java.math.BigInteger#and(java.math.BigInteger)
- */
- public void test_andLjava_math_BigInteger() {
- for (BigInteger[] element : booleanPairs) {
- BigInteger i1 = element[0], i2 = element[1];
- BigInteger res = i1.and(i2);
- assertTrue("symmetry of and", res.equals(i2.and(i1)));
- int len = Math.max(i1.bitLength(), i2.bitLength()) + 66;
- for (int i = 0; i < len; i++) {
- assertTrue("and", (i1.testBit(i) && i2.testBit(i)) == res
- .testBit(i));
- }
- }
- }
-
- /**
- * @tests java.math.BigInteger#or(java.math.BigInteger)
- */
- public void test_orLjava_math_BigInteger() {
- for (BigInteger[] element : booleanPairs) {
- BigInteger i1 = element[0], i2 = element[1];
- BigInteger res = i1.or(i2);
- assertTrue("symmetry of or", res.equals(i2.or(i1)));
- int len = Math.max(i1.bitLength(), i2.bitLength()) + 66;
- for (int i = 0; i < len; i++) {
- assertTrue("or", (i1.testBit(i) || i2.testBit(i)) == res
- .testBit(i));
- }
- }
- }
-
- /**
- * @tests java.math.BigInteger#xor(java.math.BigInteger)
- */
- public void test_xorLjava_math_BigInteger() {
- for (BigInteger[] element : booleanPairs) {
- BigInteger i1 = element[0], i2 = element[1];
- BigInteger res = i1.xor(i2);
- assertTrue("symmetry of xor", res.equals(i2.xor(i1)));
- int len = Math.max(i1.bitLength(), i2.bitLength()) + 66;
- for (int i = 0; i < len; i++) {
- assertTrue("xor", (i1.testBit(i) ^ i2.testBit(i)) == res
- .testBit(i));
- }
- }
- }
-
- /**
- * @tests java.math.BigInteger#not()
- */
- public void test_not() {
- for (BigInteger[] element : booleanPairs) {
- BigInteger i1 = element[0];
- BigInteger res = i1.not();
- int len = i1.bitLength() + 66;
- for (int i = 0; i < len; i++) {
- assertTrue("not", !i1.testBit(i) == res.testBit(i));
- }
- }
- }
-
- /**
- * @tests java.math.BigInteger#andNot(java.math.BigInteger)
- */
- public void test_andNotLjava_math_BigInteger() {
- for (BigInteger[] element : booleanPairs) {
- BigInteger i1 = element[0], i2 = element[1];
- BigInteger res = i1.andNot(i2);
- int len = Math.max(i1.bitLength(), i2.bitLength()) + 66;
- for (int i = 0; i < len; i++) {
- assertTrue("andNot", (i1.testBit(i) && !i2.testBit(i)) == res
- .testBit(i));
- }
- // asymmetrical
- i1 = element[1];
- i2 = element[0];
- res = i1.andNot(i2);
- for (int i = 0; i < len; i++) {
- assertTrue("andNot reversed",
- (i1.testBit(i) && !i2.testBit(i)) == res.testBit(i));
- }
- }
- //regression for HARMONY-4653
- try{
- BigInteger.ZERO.andNot(null);
- fail("should throw NPE");
- }catch(Exception e){
- //expected
- }
- BigInteger bi = new BigInteger(0, new byte[]{});
- assertEquals(BigInteger.ZERO, bi.andNot(BigInteger.ZERO));
- }
-
-
- public void testClone() {
- // Regression test for HARMONY-1770
- MyBigInteger myBigInteger = new MyBigInteger("12345");
- myBigInteger = (MyBigInteger) myBigInteger.clone();
- }
-
- static class MyBigInteger extends BigInteger implements Cloneable {
- public MyBigInteger(String val) {
- super(val);
- }
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- return null;
- }
- }
- }
-
- @Override
- protected void setUp() {
- bi1 = new BigInteger("2436798324768978", 16);
- bi2 = new BigInteger("4576829475724387584378543764555", 16);
- bi3 = new BigInteger("43987298363278574365732645872643587624387563245",
- 16);
-
- bi33 = new BigInteger(
- "10730846694701319120609898625733976090865327544790136667944805934175543888691400559249041094474885347922769807001",
- 10);
- bi22 = new BigInteger(
- "33301606932171509517158059487795669025817912852219962782230629632224456249",
- 10);
- bi11 = new BigInteger("6809003003832961306048761258711296064", 10);
- bi23 = new BigInteger(
- "597791300268191573513888045771594235932809890963138840086083595706565695943160293610527214057",
- 10);
- bi13 = new BigInteger(
- "270307912162948508387666703213038600031041043966215279482940731158968434008",
- 10);
- bi12 = new BigInteger(
- "15058244971895641717453176477697767050482947161656458456", 10);
-
- largePos = new BigInteger(
- "834759814379857314986743298675687569845986736578576375675678998612743867438632986243982098437620983476924376",
- 16);
- smallPos = new BigInteger("48753269875973284765874598630960986276", 16);
- largeNeg = new BigInteger(
- "-878824397432651481891353247987891423768534321387864361143548364457698487264387568743568743265873246576467643756437657436587436",
- 16);
- smallNeg = new BigInteger("-567863254343798609857456273458769843", 16);
- booleanPairs = new BigInteger[][] { { largePos, smallPos },
- { largePos, smallNeg }, { largeNeg, smallPos },
- { largeNeg, smallNeg } };
- }
-
- private void testDiv(BigInteger i1, BigInteger i2) {
- BigInteger q = i1.divide(i2);
- BigInteger r = i1.remainder(i2);
- BigInteger[] temp = i1.divideAndRemainder(i2);
-
- assertTrue("divide and divideAndRemainder do not agree", q
- .equals(temp[0]));
- assertTrue("remainder and divideAndRemainder do not agree", r
- .equals(temp[1]));
- assertTrue("signum and equals(zero) do not agree on quotient", q
- .signum() != 0
- || q.equals(zero));
- assertTrue("signum and equals(zero) do not agree on remainder", r
- .signum() != 0
- || r.equals(zero));
- assertTrue("wrong sign on quotient", q.signum() == 0
- || q.signum() == i1.signum() * i2.signum());
- assertTrue("wrong sign on remainder", r.signum() == 0
- || r.signum() == i1.signum());
- assertTrue("remainder out of range", r.abs().compareTo(i2.abs()) < 0);
- assertTrue("quotient too small", q.abs().add(one).multiply(i2.abs())
- .compareTo(i1.abs()) > 0);
- assertTrue("quotient too large", q.abs().multiply(i2.abs()).compareTo(
- i1.abs()) <= 0);
- BigInteger p = q.multiply(i2);
- BigInteger a = p.add(r);
- assertTrue("(a/b)*b+(a%b) != a", a.equals(i1));
- try {
- BigInteger mod = i1.mod(i2);
- assertTrue("mod is negative", mod.signum() >= 0);
- assertTrue("mod out of range", mod.abs().compareTo(i2.abs()) < 0);
- assertTrue("positive remainder == mod", r.signum() < 0
- || r.equals(mod));
- assertTrue("negative remainder == mod - divisor", r.signum() >= 0
- || r.equals(mod.subtract(i2)));
- } catch (ArithmeticException e) {
- assertTrue("mod fails on negative divisor only", i2.signum() <= 0);
- }
- }
-
- private void testDivRanges(BigInteger i) {
- BigInteger bound = i.multiply(two);
- for (BigInteger j = bound.negate(); j.compareTo(bound) <= 0; j = j
- .add(i)) {
- BigInteger innerbound = j.add(two);
- BigInteger k = j.subtract(two);
- for (; k.compareTo(innerbound) <= 0; k = k.add(one)) {
- testDiv(k, i);
- }
- }
- }
-
- private boolean isPrime(long b) {
- if (b == 2) {
- return true;
- }
- // check for div by 2
- if ((b & 1L) == 0) {
- return false;
- }
- long maxlen = ((long) Math.sqrt(b)) + 2;
- for (long x = 3; x < maxlen; x += 2) {
- if (b % x == 0) {
- return false;
- }
- }
- return true;
- }
-
- private void testAllMults(BigInteger i1, BigInteger i2, BigInteger ans) {
- assertTrue("i1*i2=ans", i1.multiply(i2).equals(ans));
- assertTrue("i2*i1=ans", i2.multiply(i1).equals(ans));
- assertTrue("-i1*i2=-ans", i1.negate().multiply(i2).equals(ans.negate()));
- assertTrue("-i2*i1=-ans", i2.negate().multiply(i1).equals(ans.negate()));
- assertTrue("i1*-i2=-ans", i1.multiply(i2.negate()).equals(ans.negate()));
- assertTrue("i2*-i1=-ans", i2.multiply(i1.negate()).equals(ans.negate()));
- assertTrue("-i1*-i2=ans", i1.negate().multiply(i2.negate()).equals(ans));
- assertTrue("-i2*-i1=ans", i2.negate().multiply(i1.negate()).equals(ans));
- }
-
- private void testAllDivs(BigInteger i1, BigInteger i2) {
- testDiv(i1, i2);
- testDiv(i1.negate(), i2);
- testDiv(i1, i2.negate());
- testDiv(i1.negate(), i2.negate());
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/ASCCharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/ASCCharsetDecoderTest.java
deleted file mode 100644
index a349b9c..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/ASCCharsetDecoderTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-public class ASCCharsetDecoderTest extends CharsetDecoderTest {
-
- protected void setUp() throws Exception {
- cs = Charset.forName("ascii");
- super.setUp();
- }
-
- /*
- * @see CharsetDecoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- // FIXME: give up this tests
- // public void testDefaultCharsPerByte(){
- // // assertEquals(1, decoder.averageCharsPerByte());
- // // assertEquals(1, decoder.maxCharsPerByte());
- // assertEquals(decoder.averageCharsPerByte(), 1, 0.001);
- // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
- // }
-
- ByteBuffer getUnmappedByteBuffer() {
- // FIXME: different here
- return null;
- // ByteBuffer buffer = ByteBuffer.allocate(8);
- // buffer.put((byte)-1);
- // buffer.put(unibytes);
- // buffer.flip();
- // return buffer;
-
- }
-
- ByteBuffer getMalformedByteBuffer() {
- // FIXME: different here
- ByteBuffer buffer = ByteBuffer.allocate(8);
- buffer.put((byte) -1);
- buffer.put(getByteBuffer());
- buffer.flip();
- return buffer;
-
- // TODO: how malform?
- // return null;
- }
-
- ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
- return null;
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/ASCCharsetTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/ASCCharsetTest.java
deleted file mode 100644
index f46321e..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/ASCCharsetTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-/**
- * Test charset US-ASCII.
- */
-public class ASCCharsetTest extends AbstractCharsetTestCase {
-
- /**
- * Constructor.
- *
- */
- public ASCCharsetTest(String arg0) {
- super(arg0, "US-ASCII", new String[] { "ISO646-US", "ASCII", "cp367",
- "ascii7", "ANSI_X3.4-1986", "iso-ir-6", "us", "646",
- "iso_646.irv:1983", "csASCII", "ANSI_X3.4-1968",
- "ISO_646.irv:1991" }, true, true); // "ibm-367"
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
- */
- public void testEncode_Normal() {
- String input = "ab\u5D14\u654F";
- byte[] output = new byte[] { 97, 98,
- this.testingCharset.newEncoder().replacement()[0],
- this.testingCharset.newEncoder().replacement()[0] };
- internalTestEncode(input, output);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
- */
- public void testDecode_Normal() {
- byte[] input = new byte[] { 97, 98, 63, 63 };
- char[] output = "ab??".toCharArray();
- internalTestDecode(input, output);
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java
deleted file mode 100644
index 0ebf922..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-
-import junit.framework.TestCase;
-
-/**
- * Super class for concrete charset test suites.
- */
-public abstract class AbstractCharsetTestCase extends TestCase {
-
- // the canonical name of this charset
- protected final String canonicalName;
-
- // the aliases set
- protected final String[] aliases;
-
- // canEncode
- protected final boolean canEncode;
-
- // isRegistered
- protected final boolean isRegistered;
-
- // charset instance
- protected Charset testingCharset;
-
- /*
- * Initialize the field "testingCharset" here.
- *
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception {
- super.setUp();
- this.testingCharset = Charset.forName(this.canonicalName);
- }
-
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- /**
- * Constructor for ConcreteCharsetTest.
- *
- */
- public AbstractCharsetTestCase(String arg0, String canonicalName,
- String[] aliases, boolean canEncode, boolean isRegistered) {
- super(arg0);
- this.canonicalName = canonicalName;
- this.canEncode = canEncode;
- this.isRegistered = isRegistered;
- this.aliases = aliases;
- }
-
- /*
- * Test canEncode.
- */
- public void testCanEncode() {
- assertEquals(this.canEncode, this.testingCharset.canEncode());
- }
-
- /*
- * Test isRegistered.
- */
- public void testIsRegistered() {
- assertEquals(this.isRegistered, this.testingCharset.isRegistered());
- }
-
- /*
- * Test name.
- */
- public void testName() {
- assertEquals(this.canonicalName, this.testingCharset.name());
- // assertEquals(this.canonicalName, this.testingCharset.displayName());
- // assertEquals(this.canonicalName,
- // this.testingCharset.displayName(null));
- }
-
- /*
- * Test aliases.
- */
- public void testAliases() {
- for (int i = 0; i < this.aliases.length; i++) {
- Charset c = Charset.forName(this.aliases[i]);
- assertEquals(this.canonicalName, c.name());
- // TODO
- // assertTrue(this.testingCharset.aliases().contains(this.aliases[i]));
- }
- }
-
- /*
- * Test the method encode(String) with null.
- */
- public void testEncode_String_Null() {
- try {
- this.testingCharset.encode((String) null);
- fail("Should throw NullPointerException!");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Test the method encode(CharBuffer) with null.
- */
- public void testEncode_CharBuffer_Null() {
- try {
- this.testingCharset.encode((CharBuffer) null);
- fail("Should throw NullPointerException!");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /*
- * Test encoding.
- */
- protected void internalTestEncode(String input, byte[] output) {
- ByteBuffer bb = this.testingCharset.encode(input);
- int i = 0;
- bb.rewind();
- while (bb.hasRemaining() && i < output.length) {
- assertEquals(output[i], bb.get());
- i++;
- }
- assertFalse(bb.hasRemaining());
- assertEquals(output.length, i);
- }
-
- /*
- * Test encoding.
- */
- public abstract void testEncode_Normal();
-
- /*
- * Test decoding.
- */
- protected void internalTestDecode(byte[] input, char[] output) {
- CharBuffer chb = this.testingCharset.decode(ByteBuffer.wrap(input));
- int i = 0;
- chb.rewind();
- while (chb.hasRemaining() && i < output.length) {
- assertEquals(output[i], chb.get());
- i++;
- }
- assertFalse(chb.hasRemaining());
- assertEquals(output.length, i);
- }
-
- /*
- * Test decoding.
- */
- public abstract void testDecode_Normal();
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetDecoderTest.java
deleted file mode 100644
index 7fbe9e7..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetDecoderTest.java
+++ /dev/null
@@ -1,875 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.MalformedInputException;
-import java.nio.charset.UnmappableCharacterException;
-
-import junit.framework.TestCase;
-
-/**
- * API unit test for java.nio.CharsetDecoder
- */
-public class CharsetDecoderTest extends TestCase {
-
- protected static final int MAX_BYTES = 3;
-
- protected static final double AVER_BYTES = 0.5;
-
- // default charset
- private static final Charset MOCKCS = new CharsetEncoderTest.MockCharset(
- "mock", new String[0]);
-
- Charset cs = MOCKCS;
-
- // default decoder
- protected static CharsetDecoder decoder;
-
- String bom = "";
-
- protected void setUp() throws Exception {
- super.setUp();
- decoder = cs.newDecoder();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- // FIXME: give up this tests
- // /*
- // * test default value
- // */
- // public void testDefaultCharsPerByte() {
- // assertTrue(decoder.averageCharsPerByte() == AVER_BYTES);
- // assertTrue(decoder.maxCharsPerByte() == MAX_BYTES);
- // }
-
- public void testDefaultValues() {
- assertSame(cs, decoder.charset());
- try {
- decoder.detectedCharset();
- fail("should unsupported");
- } catch (UnsupportedOperationException e) {
- }
- try {
- assertTrue(decoder.isCharsetDetected());
- fail("should unsupported");
- } catch (UnsupportedOperationException e) {
- }
- assertFalse(decoder.isAutoDetecting());
- assertSame(CodingErrorAction.REPORT, decoder.malformedInputAction());
- assertSame(CodingErrorAction.REPORT, decoder
- .unmappableCharacterAction());
- assertEquals(decoder.replacement(), "\ufffd");
- }
-
- /*
- * test constructor
- */
- public void testCharsetDecoder() {
- // default value
- decoder = new MockCharsetDecoder(cs, (float) AVER_BYTES, MAX_BYTES);
-
- // normal case
- CharsetDecoder ec = new MockCharsetDecoder(cs, 1, MAX_BYTES);
- assertSame(ec.charset(), cs);
- assertEquals(1.0, ec.averageCharsPerByte(), 0.0);
- assertTrue(ec.maxCharsPerByte() == MAX_BYTES);
-
- /*
- * ------------------------ Exceptional cases -------------------------
- */
- // Normal case: null charset
- ec = new MockCharsetDecoder(null, 1, MAX_BYTES);
- assertNull(ec.charset());
- assertEquals(1.0, ec.averageCharsPerByte(), 0.0);
- assertTrue(ec.maxCharsPerByte() == MAX_BYTES);
-
- ec = new MockCharsetDecoder(new CharsetEncoderTest.MockCharset("mock",
- new String[0]), 1, MAX_BYTES);
-
- // Commented out since the comment is wrong since MAX_BYTES > 1
- // // OK: average length less than max length
- // ec = new MockCharsetDecoder(cs, MAX_BYTES, 1);
- // assertTrue(ec.averageCharsPerByte() == MAX_BYTES);
- // assertTrue(ec.maxCharsPerByte() == 1);
-
- // Illegal Argument: zero length
- try {
- ec = new MockCharsetDecoder(cs, 0, MAX_BYTES);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- try {
- ec = new MockCharsetDecoder(cs, 1, 0);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- // Illegal Argument: negative length
- try {
- ec = new MockCharsetDecoder(cs, -1, MAX_BYTES);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- try {
- ec = new MockCharsetDecoder(cs, 1, -1);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- }
-
- /*
- * test onMalformedInput
- */
- public void testOnMalformedInput() {
- assertSame(CodingErrorAction.REPORT, decoder.malformedInputAction());
- try {
- decoder.onMalformedInput(null);
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
- decoder.onMalformedInput(CodingErrorAction.IGNORE);
- assertSame(CodingErrorAction.IGNORE, decoder.malformedInputAction());
- }
-
- /*
- * test unmappableCharacter
- */
- public void testOnUnmappableCharacter() {
- assertSame(CodingErrorAction.REPORT, decoder
- .unmappableCharacterAction());
- try {
- decoder.onUnmappableCharacter(null);
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
- decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
- assertSame(CodingErrorAction.IGNORE, decoder
- .unmappableCharacterAction());
- }
-
- /*
- * test replaceWith
- */
- public void testReplaceWith() {
- try {
- decoder.replaceWith(null);
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
- try {
- decoder.replaceWith("");
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
- try {
- decoder.replaceWith("testReplaceWith");
- fail("should throw illegal argument exception");
- } catch (IllegalArgumentException e) {
- }
-
- decoder.replaceWith("a");
- assertSame("a", decoder.replacement());
- }
-
- /*
- * Class under test for CharBuffer decode(ByteBuffer)
- */
- public void testDecodeByteBuffer() throws CharacterCodingException {
- implTestDecodeByteBuffer();
- }
-
- void implTestDecodeByteBuffer() throws CharacterCodingException {
- // Null pointer
- try {
- decoder.decode(null);
- fail("should throw null pointer exception");
- } catch (NullPointerException e) {
- }
-
- // empty input buffer
- CharBuffer out = decoder.decode(ByteBuffer.allocate(0));
- assertCharBufferValue("", out);
-
- // normal case
- ByteBuffer in = getByteBuffer();
- out = decoder.decode(in);
- assertEquals(0, out.position());
- assertEquals(getString().length(), out.limit());
- assertEquals(getString().length(), out.remaining());
- assertCharBufferValue(getString(), out);
-
- // normal read only case
- in = getByteBuffer().asReadOnlyBuffer();
- out = decoder.decode(in);
- assertEquals(out.position(), 0);
- assertEquals(out.limit(), getString().length());
- assertEquals(out.remaining(), getString().length());
- assertCharBufferValue(getString(), out);
- }
-
- public void testDecodeByteBufferException()
- throws CharacterCodingException, UnsupportedEncodingException {
- CharBuffer out;
- ByteBuffer in;
- String replaceStr = decoder.replacement() + getString();
-
- // MalformedException:
- decoder.onMalformedInput(CodingErrorAction.REPORT);
- decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- in = getMalformedByteBuffer();
- if (in != null) {
- try {
- CharBuffer buffer = decoder.decode(in);
- assertTrue(buffer.remaining() > 0);
- fail("should throw MalformedInputException");
- } catch (MalformedInputException e) {
- }
-
- decoder.reset();
- in.rewind();
- decoder.onMalformedInput(CodingErrorAction.IGNORE);
- out = decoder.decode(in);
- assertCharBufferValue(getString(), out);
-
- decoder.reset();
- in.rewind();
- decoder.onMalformedInput(CodingErrorAction.REPLACE);
- out = decoder.decode(in);
- assertCharBufferValue(replaceStr, out);
- }
-
- // Unmapped Exception:
- decoder.onMalformedInput(CodingErrorAction.REPORT);
- decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- in = getUnmappedByteBuffer();
- if (in != null) {
- try {
- decoder.decode(in);
- fail("should throw UnmappableCharacterException");
- } catch (UnmappableCharacterException e) {
- }
-
- decoder.reset();
- in.rewind();
- decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
- out = decoder.decode(in);
- assertCharBufferValue(getString(), out);
-
- decoder.reset();
- in.rewind();
- decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
- out = decoder.decode(in);
- assertCharBufferValue(replaceStr, out);
- }
-
- // RuntimeException
- try {
- decoder.decode(getExceptionByteArray());
- fail("should throw runtime exception");
- } catch (RuntimeException e) {
- }
- }
-
- /*
- * Class under test for CoderResult decode(ByteBuffer, CharBuffer, boolean)
- */
- public void testDecodeByteBufferCharBuffer() {
- implTestDecodeByteBufferCharBuffer(getByteBuffer());
- }
-
- public void testDecodeByteBufferCharBufferReadOnly() {
- implTestDecodeByteBufferCharBuffer(getByteBuffer());
- }
-
- void implTestDecodeByteBufferCharBuffer(ByteBuffer in) {
- CharBuffer out = CharBuffer.allocate(100);
-
- // Null pointer
- decoder.reset();
- try {
- decoder.decode(null, out, true);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- }
- try {
- decoder.decode(in, null, true);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- }
-
- // normal case, one complete operation
- decoder.reset();
- in.rewind();
- out.rewind();
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
- assertEquals(out.limit(), 100);
- assertEquals(out.position(), getString().length());
- assertEquals(out.remaining(), 100 - getString().length());
- assertEquals(out.capacity(), 100);
- assertCharBufferValue(getString(), out);
- decoder.flush(out);
-
- // normal case, one complete operation, but call twice, first time set
- // endOfInput to false
- decoder.reset();
- in.rewind();
- out.clear();
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
- assertEquals(out.limit(), 100);
- assertEquals(out.position(), getString().length());
- assertEquals(out.remaining(), 100 - getString().length());
- assertEquals(out.capacity(), 100);
- assertCharBufferValue(getString(), out);
-
- decoder.reset();
- in.rewind();
- out.clear();
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
- in = getHeadlessByteBuffer();
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
- in.rewind();
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
- assertEquals(out.limit(), 100);
- assertTrue(out.position() > 0);
- assertEquals(out.remaining(), out.capacity() - out.position());
- assertEquals(out.capacity(), 100);
- assertCharBufferValue(getString() + getString() + getString(), out);
-
- // overflow
- out = CharBuffer.allocate(4);
- decoder.reset();
- in = getByteBuffer();
- out.rewind();
- assertSame(CoderResult.OVERFLOW, decoder.decode(in, out, false));
-
- assertCharBufferValue(getString().substring(0, 4), out);
- out = CharBuffer.allocate(100);
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
- assertCharBufferValue(getString().substring(4), out);
- in.rewind();
- out = CharBuffer.allocate(100);
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
- assertCharBufferValue(bom + getString(), out);
- }
-
- public void testDecodeCharBufferByteBufferUnmappedException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferUnmappedException(
- getUnmappedByteBuffer(), true);
- }
-
- public void testDecodeCharBufferByteIncompleteBufferUnmappedException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferUnmappedException(
- getUnmappedByteBuffer(), false);
- }
-
- public void testDecodeCharBufferByteReadOnlyBufferUnmappedException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferUnmappedException(
- readOnly(getUnmappedByteBuffer()), true);
- }
-
- public void testDecodeCharBufferByteReadOnlyIncompleteBufferUnmappedException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferUnmappedException(
- readOnly(getUnmappedByteBuffer()), false);
- }
-
- void implTestDecodeCharBufferByteBufferUnmappedException(ByteBuffer in,
- boolean endOfInput) throws CharacterCodingException,
- UnsupportedEncodingException {
- if (null == in) {
- return;
- }
- CharBuffer out = CharBuffer.allocate(50);
-
- decoder.onMalformedInput(CodingErrorAction.REPORT);
- decoder.reset();
- decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- CoderResult result = decoder.decode(in, out, endOfInput);
- assertTrue(result.isUnmappable());
-
- decoder.reset();
- out.clear();
- in.rewind();
- decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
- assertCharBufferValue(getString(), out);
-
- decoder.reset();
- out.clear();
- in.rewind();
- decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
- assertCharBufferValue(decoder.replacement() + getString(), out);
- }
-
- public void testDecodeCharBufferByteBufferMalformedException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferMalformedException(
- getMalformedByteBuffer(), true);
- }
-
- public void testDecodeCharBufferByteIncompleteBufferMalformedException()
- throws CharacterCodingException, UnsupportedEncodingException {
-
- implTestDecodeCharBufferByteBufferMalformedException(
- getMalformedByteBuffer(), false);
- }
-
- public void testDecodeCharBufferByteReadOnlyBufferMalformedException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferMalformedException(
- readOnly(getMalformedByteBuffer()), true);
- }
-
- public void testDecodeCharBufferByteReadOnlyIncompleteBufferMalformedException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferMalformedException(
- readOnly(getMalformedByteBuffer()), false);
- }
-
- void implTestDecodeCharBufferByteBufferMalformedException(ByteBuffer in,
- boolean endOfInput) throws CharacterCodingException,
- UnsupportedEncodingException {
- if (null == in) {
- return;
- }
- CharBuffer out = CharBuffer.allocate(getString().length() * 3);
- decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- decoder.reset();
- decoder.onMalformedInput(CodingErrorAction.REPORT);
- CoderResult result = decoder.decode(in, out, endOfInput);
- assertTrue(result.isMalformed());
-
- decoder.reset();
- out.clear();
- in.rewind();
- decoder.onMalformedInput(CodingErrorAction.IGNORE);
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
- assertCharBufferValue(getString(), out);
-
- decoder.reset();
- out.clear();
- in.rewind();
- decoder.onMalformedInput(CodingErrorAction.REPLACE);
- assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
- assertCharBufferValue(decoder.replacement() + getString(), out);
- }
-
- public void testDecodeCharBufferByteBufferException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferException(getExceptionByteArray(),
- true);
- }
-
- public void testDecodeCharBufferByteIncompleteBufferException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferException(getExceptionByteArray(),
- false);
- }
-
- public void testDecodeCharBufferByteReadOnlyBufferException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferException(
- readOnly(getExceptionByteArray()), true);
- }
-
- public void testDecodeCharBufferByteReadOnlyIncompleteBufferException()
- throws CharacterCodingException, UnsupportedEncodingException {
- implTestDecodeCharBufferByteBufferException(
- readOnly(getExceptionByteArray()), false);
- }
-
- void implTestDecodeCharBufferByteBufferException(ByteBuffer in,
- boolean endOfInput) throws CharacterCodingException,
- UnsupportedEncodingException {
- CharBuffer out = CharBuffer.allocate(50);
- decoder.reset();
- try {
- decoder.decode(in, out, endOfInput);
- fail("should throw runtime exception");
- } catch (RuntimeException e) {
- }
- }
-
- private ByteBuffer readOnly(ByteBuffer b) {
- if (null == b) {
- return null;
- }
- return b.asReadOnlyBuffer();
- }
-
- protected String getString() {
- return " buffer";
- }
-
- protected ByteBuffer getByteBuffer() {
- return ByteBuffer.wrap(new byte[] { 32, 98, 117, 102, 102, 101, 114 });
- }
-
- protected ByteBuffer getHeadlessByteBuffer() {
- return getByteBuffer();
- }
-
- ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
- // "runtime"
- return ByteBuffer
- .wrap(new byte[] { 114, 117, 110, 116, 105, 109, 101 });
- }
-
- ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
- // "unmap buffer"
- byte[] ba = new byte[] { 117, 110, 109, 97, 112, 32, 98, 117, 102, 102,
- 101, 114 };
- return ByteBuffer.wrap(ba);
- }
-
- ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
- // "malform buffer"
- byte[] ba = new byte[] { 109, 97, 108, 102, 111, 114, 109, 32, 98, 117,
- 102, 102, 101, 114 };
- return ByteBuffer.wrap(ba);
- }
-
- private void assertCharBufferValue(String expected, CharBuffer out) {
- if (out.position() != 0) {
- out.flip();
- }
- assertEquals(expected, new String(out.array(), out.arrayOffset(), out
- .arrayOffset() + out.limit()));
- }
-
- /*
- * test flush
- */
- public void testFlush() throws CharacterCodingException {
- CharBuffer out = CharBuffer.allocate(10);
- ByteBuffer in = ByteBuffer.wrap(new byte[] { 12, 12 });
- decoder.decode(in, out, true);
- assertSame(CoderResult.UNDERFLOW, decoder.flush(out));
-
- decoder.reset();
- decoder.decode((ByteBuffer) in.rewind(), (CharBuffer) out.rewind(),
- true);
- assertSame(CoderResult.UNDERFLOW, decoder
- .flush(CharBuffer.allocate(10)));
- }
-
- /*
- * ---------------------------------- methods to test illegal state
- * -----------------------------------
- */
- // Normal case: just after reset, and it also means reset can be done
- // anywhere
- public void testResetIllegalState() throws CharacterCodingException {
- decoder.reset();
- decoder.decode(getByteBuffer());
- decoder.reset();
- decoder.decode(getByteBuffer(), CharBuffer.allocate(3), false);
- decoder.reset();
- decoder.decode(getByteBuffer(), CharBuffer.allocate(3), true);
- decoder.reset();
- }
-
- public void testFlushIllegalState() throws CharacterCodingException {
- ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
- CharBuffer out = CharBuffer.allocate(5);
-
- // Illegal state: after reset.
- decoder.reset();
- try {
- decoder.flush(out);
- fail();
- } catch (IllegalStateException expected) {
- }
-
- // Normal case: after decode with endOfInput is true
- decoder.reset();
- decoder.decode(in, out, true);
- out.rewind();
- CoderResult result = decoder.flush(out);
- assertSame(result, CoderResult.UNDERFLOW);
-
- // Good state: flush twice
- decoder.flush(out);
-
- // Illegal state: flush after decode with endOfInput is false
- decoder.reset();
- decoder.decode(in, out, false);
- try {
- decoder.flush(out);
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- // test illegal states for decode facade
- public void testDecodeFacadeIllegalState() throws CharacterCodingException {
- // decode facade can be execute in anywhere
- ByteBuffer in = getByteBuffer();
-
- // Normal case: just created
- decoder.decode(in);
- in.rewind();
-
- // Normal case: just after decode facade
- decoder.decode(in);
- in.rewind();
-
- // Normal case: just after decode with that endOfInput is true
- decoder.reset();
- decoder.decode(getByteBuffer(), CharBuffer.allocate(30), true);
- decoder.decode(in);
- in.rewind();
-
- // Normal case:just after decode with that endOfInput is false
- decoder.reset();
- decoder.decode(getByteBuffer(), CharBuffer.allocate(30), false);
- decoder.decode(in);
- in.rewind();
-
- // Normal case: just after flush
- decoder.reset();
- decoder.decode(getByteBuffer(), CharBuffer.allocate(30), true);
- decoder.flush(CharBuffer.allocate(10));
- decoder.decode(in);
- in.rewind();
- }
-
- // test illegal states for two decode method with endOfInput is true
- public void testDecodeTrueIllegalState() throws CharacterCodingException {
- ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
- CharBuffer out = CharBuffer.allocate(100);
- // Normal case: just created
- decoder.decode(in, out, true);
- in.rewind();
- out.rewind();
-
- // Normal case: just after decode with that endOfInput is true
- decoder.reset();
- decoder.decode(in, CharBuffer.allocate(30), true);
- in.rewind();
- decoder.decode(in, out, true);
- in.rewind();
- out.rewind();
-
- // Normal case:just after decode with that endOfInput is false
- decoder.reset();
- decoder.decode(in, CharBuffer.allocate(30), false);
- in.rewind();
- decoder.decode(in, out, true);
- in.rewind();
- out.rewind();
-
- // Illegal state: just after flush
- decoder.reset();
- decoder.decode(in, CharBuffer.allocate(30), true);
- decoder.flush(CharBuffer.allocate(10));
- in.rewind();
- try {
- decoder.decode(in, out, true);
- fail("should illegal state");
- } catch (IllegalStateException e) {
- }
- in.rewind();
- out.rewind();
-
- }
-
- // test illegal states for two decode method with endOfInput is false
- public void testDecodeFalseIllegalState() throws CharacterCodingException {
- ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
- CharBuffer out = CharBuffer.allocate(5);
- // Normal case: just created
- decoder.decode(in, out, false);
- in.rewind();
- out.rewind();
-
- // Illegal state: just after decode facade
- decoder.reset();
- decoder.decode(in);
- in.rewind();
- try {
- decoder.decode(in, out, false);
- fail("should illegal state");
- } catch (IllegalStateException e) {
- }
- in.rewind();
- out.rewind();
-
- // Illegal state: just after decode with that endOfInput is true
- decoder.reset();
- decoder.decode(in, CharBuffer.allocate(30), true);
- in.rewind();
- try {
- decoder.decode(in, out, false);
- fail("should illegal state");
- } catch (IllegalStateException e) {
- }
- in.rewind();
- out.rewind();
-
- // Normal case:just after decode with that endOfInput is false
- decoder.reset();
- decoder.decode(in, CharBuffer.allocate(30), false);
- in.rewind();
- decoder.decode(in, out, false);
- in.rewind();
- out.rewind();
-
- // Illegal state: just after flush
- decoder.reset();
- decoder.decode(in, CharBuffer.allocate(30), true);
- in.rewind();
- decoder.flush(CharBuffer.allocate(10));
- try {
- decoder.decode(in, out, false);
- fail("should illegal state");
- } catch (IllegalStateException e) {
- }
- }
-
- /*
- * --------------------------------- illegal state test end
- * ---------------------------------
- */
-
- public void testImplFlush() {
- decoder = new MockCharsetDecoder(cs, 1, 3);
- assertEquals(CoderResult.UNDERFLOW, ((MockCharsetDecoder) decoder)
- .pubImplFlush(null));
- }
-
- public void testImplOnMalformedInput() {
- decoder = new MockCharsetDecoder(cs, 1, 3);
- assertEquals(CoderResult.UNDERFLOW, ((MockCharsetDecoder) decoder)
- .pubImplFlush(null));
-
- }
-
- public void testImplOnUnmappableCharacter() {
- decoder = new MockCharsetDecoder(cs, 1, 3);
- ((MockCharsetDecoder) decoder).pubImplOnUnmappableCharacter(null);
- }
-
- public void testImplReplaceWith() {
- decoder = new MockCharsetDecoder(cs, 1, 3);
- ((MockCharsetDecoder) decoder).pubImplReplaceWith(null);
- }
-
- public void testImplReset() {
- decoder = new MockCharsetDecoder(cs, 1, 3);
- ((MockCharsetDecoder) decoder).pubImplReset();
- }
-
- /*
- * mock decoder
- */
- public static class MockCharsetDecoder extends CharsetDecoder {
- public MockCharsetDecoder(Charset cs, float ave, float max) {
- super(cs, ave, max);
- }
-
- protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
- int inPosition = in.position();
- byte[] input = new byte[in.remaining()];
- in.get(input);
- String result;
- try {
- result = new String(input, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError(e);
- }
- if (result.startsWith("malform")) {
- // reset the cursor to the error position
- in.position(inPosition);
- // set the error length
- return CoderResult.malformedForLength("malform".length());
- } else if (result.startsWith("unmap")) {
- // reset the cursor to the error position
- in.position(inPosition);
- // set the error length
- return CoderResult.unmappableForLength("unmap".length());
- } else if (result.startsWith("runtime")) {
- // reset the cursor to the error position
- in.position(0);
- // set the error length
- throw new RuntimeException("runtime");
- }
- int inLeft = input.length;
- int outLeft = out.remaining();
- CoderResult r = CoderResult.UNDERFLOW;
- int length = inLeft;
- if (outLeft < inLeft) {
- r = CoderResult.OVERFLOW;
- length = outLeft;
- in.position(inPosition + outLeft);
- }
- for (int i = 0; i < length; i++) {
- out.put((char) input[i]);
- }
- return r;
- }
-
- protected CoderResult implFlush(CharBuffer out) {
- CoderResult result = super.implFlush(out);
- if (out.remaining() >= 5) {
- // TODO
- // out.put("flush");
- result = CoderResult.UNDERFLOW;
- } else {
- // out.put("flush", 0, out.remaining());
- result = CoderResult.OVERFLOW;
- }
- return result;
- }
-
- public CoderResult pubImplFlush(CharBuffer out) {
- return super.implFlush(out);
- }
-
- public void pubImplOnMalformedInput(CodingErrorAction newAction) {
- super.implOnMalformedInput(newAction);
- }
-
- public void pubImplOnUnmappableCharacter(CodingErrorAction newAction) {
- super.implOnUnmappableCharacter(newAction);
- }
-
- public void pubImplReplaceWith(String newReplacement) {
- super.implReplaceWith(newReplacement);
- }
-
- public void pubImplReset() {
- super.implReset();
- }
-
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetEncoderTest.java
deleted file mode 100644
index b63f4d9..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetEncoderTest.java
+++ /dev/null
@@ -1,1139 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.nio.charset;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.MalformedInputException;
-import java.nio.charset.UnmappableCharacterException;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.Arrays;
-
-import junit.framework.TestCase;
-
-/**
- * API unit test for java.nio.charset.CharsetEncoder
- */
-public class CharsetEncoderTest extends TestCase {
-
- static final int MAX_BYTES = 3;
-
- static final float AVER_BYTES = 0.5f;
-
- // charset for mock class
- private static final Charset MOCKCS = new MockCharset("CharsetEncoderTest_mock", new String[0]);
-
- Charset cs = MOCKCS;
-
- // default encoder
- CharsetEncoder encoder;
-
- // default for Charset abstract class
- byte[] defaultReplacement = new byte[] { 63 };
-
- // specific for Charset implementation subclass
- byte[] specifiedReplacement = new byte[] { 63 };
-
- static final String unistr = " buffer";// \u8000\u8001\u00a5\u3000\r\n";
-
- byte[] unibytes = new byte[] { 32, 98, 117, 102, 102, 101, 114 };
-
- byte[] unibytesWithRep = null;
-
- byte[] surrogate = new byte[0];
-
- protected void setUp() throws Exception {
- super.setUp();
- encoder = cs.newEncoder();
- if (null == unibytesWithRep) {
- byte[] replacement = encoder.replacement();
- unibytesWithRep = new byte[replacement.length + unibytes.length];
- System.arraycopy(replacement, 0, unibytesWithRep, 0,
- replacement.length);
- System.arraycopy(unibytes, 0, unibytesWithRep, replacement.length,
- unibytes.length);
- }
- }
-
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testSpecificDefaultValue() {
- assertTrue(encoder.averageBytesPerChar() == AVER_BYTES);
- assertTrue(encoder.maxBytesPerChar() == MAX_BYTES);
- }
-
- public void testDefaultValue() {
- assertEquals(CodingErrorAction.REPORT, encoder.malformedInputAction());
- assertEquals(CodingErrorAction.REPORT, encoder.unmappableCharacterAction());
- assertSame(encoder, encoder.onMalformedInput(CodingErrorAction.IGNORE));
- assertSame(encoder, encoder.onUnmappableCharacter(CodingErrorAction.IGNORE));
- if (encoder instanceof MockCharsetEncoder) {
- assertTrue(Arrays.equals(encoder.replacement(), defaultReplacement));
- } else {
- assertTrue(Arrays.equals(encoder.replacement(), specifiedReplacement));
- }
-
- }
-
- /*
- * Class under test for constructor CharsetEncoder(Charset, float, float)
- */
- public void testCharsetEncoderCharsetfloatfloat() {
- // default value
- encoder = new MockCharsetEncoder(cs, (float) AVER_BYTES, MAX_BYTES);
- assertSame(encoder.charset(), cs);
- assertTrue(encoder.averageBytesPerChar() == AVER_BYTES);
- assertTrue(encoder.maxBytesPerChar() == MAX_BYTES);
- assertEquals(CodingErrorAction.REPORT, encoder.malformedInputAction());
- assertEquals(CodingErrorAction.REPORT, encoder
- .unmappableCharacterAction());
- assertEquals(new String(encoder.replacement()), new String(
- defaultReplacement));
- assertSame(encoder, encoder.onMalformedInput(CodingErrorAction.IGNORE));
- assertSame(encoder, encoder
- .onUnmappableCharacter(CodingErrorAction.IGNORE));
-
- // normal case
- CharsetEncoder ec = new MockCharsetEncoder(cs, 1, MAX_BYTES);
- assertSame(ec.charset(), cs);
- assertEquals(1.0, ec.averageBytesPerChar(), 0);
- assertTrue(ec.maxBytesPerChar() == MAX_BYTES);
-
- /*
- * ------------------------ Exceptional cases -------------------------
- */
- // NullPointerException: null charset
- try {
- ec = new MockCharsetEncoder(null, 1, MAX_BYTES);
- fail("should throw null pointer exception");
- } catch (NullPointerException e) {
- }
-
- ec = new MockCharsetEncoder(new MockCharset("mock", new String[0]), 1,
- MAX_BYTES);
-
- // Commented out since the comment is wrong since MAX_BYTES > 1
- // // OK: average length less than max length
- // ec = new MockCharsetEncoder(cs, MAX_BYTES, 1);
- // assertTrue(ec.averageBytesPerChar() == MAX_BYTES);
- // assertTrue(ec.maxBytesPerChar() == 1);
-
- // Illegal Argument: zero length
- try {
- ec = new MockCharsetEncoder(cs, 0, MAX_BYTES);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- try {
- ec = new MockCharsetEncoder(cs, 1, 0);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- // Illegal Argument: negative length
- try {
- ec = new MockCharsetEncoder(cs, -1, MAX_BYTES);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- try {
- ec = new MockCharsetEncoder(cs, 1, -1);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- }
-
- /*
- * Class under test for constructor CharsetEncoder(Charset, float, float,
- * byte[])
- */
- public void testCharsetEncoderCharsetfloatfloatbyteArray() {
- byte[] ba = getLegalByteArray();
- // normal case
- CharsetEncoder ec = new MockCharsetEncoder(cs, 1, MAX_BYTES, ba);
- assertSame(ec.charset(), cs);
- assertEquals(1.0, ec.averageBytesPerChar(), 0.0);
- assertTrue(ec.maxBytesPerChar() == MAX_BYTES);
- assertSame(ba, ec.replacement());
-
- /*
- * ------------------------ Exceptional cases -------------------------
- */
- // NullPointerException: null charset
- try {
- ec = new MockCharsetEncoder(null, 1, MAX_BYTES, ba);
- fail("should throw null pointer exception");
- } catch (NullPointerException e) {
- }
-
- // Illegal Argument: null byte array
- try {
- ec = new MockCharsetEncoder(cs, 1, MAX_BYTES, null);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- // Illegal Argument: empty byte array
- try {
- ec = new MockCharsetEncoder(cs, 1, MAX_BYTES, new byte[0]);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- // Illegal Argument: byte array is longer than max length
- try {
- ec = new MockCharsetEncoder(cs, 1, MAX_BYTES, new byte[] { 1, 2,
- MAX_BYTES, 4 });
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- // Commented out since the comment is wrong since MAX_BYTES > 1
- // This test throws IllegalArgumentException on Harmony and RI
- // // OK: average length less than max length
- // ec = new MockCharsetEncoder(cs, MAX_BYTES, ba.length, ba);
- // assertTrue(ec.averageBytesPerChar() == MAX_BYTES);
- // assertTrue(ec.maxBytesPerChar() == ba.length);
-
- // Illegal Argument: zero length
- try {
- ec = new MockCharsetEncoder(cs, 0, MAX_BYTES, ba);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- try {
- ec = new MockCharsetEncoder(cs, 1, 0, ba);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- // Illegal Argument: negative length
- try {
- ec = new MockCharsetEncoder(cs, -1, MAX_BYTES, ba);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- try {
- ec = new MockCharsetEncoder(cs, 1, -1, ba);
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- }
-
- /*
- * Class under test for boolean canEncode(char)
- */
- public void testCanEncodechar() throws CharacterCodingException {
- // for non-mapped char
- assertTrue(encoder.canEncode('\uc2c0'));
- // surrogate char for unicode
- // 1st byte: d800-dbff
- // 2nd byte: dc00-dfff
- assertTrue(encoder.canEncode('\ud800'));
- // valid surrogate pair
- assertTrue(encoder.canEncode('\udc00'));
- }
-
- /*-----------------------------------------
- * Class under test for illegal state case
- * methods which can change internal states are two encode, flush, two canEncode, reset
- * -----------------------------------------
- */
-
- // Normal case: just after reset, and it also means reset can be done
- // anywhere
- public void testResetIllegalState() throws CharacterCodingException {
- assertSame(encoder, encoder.reset());
- encoder.canEncode('\ud901');
- assertSame(encoder, encoder.reset());
- encoder.canEncode("\ud901\udc00");
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("aaa"));
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("aaa"), ByteBuffer.allocate(3), false);
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("aaa"), ByteBuffer.allocate(3), true);
- assertSame(encoder, encoder.reset());
- }
-
- public void testFlushIllegalState() throws CharacterCodingException {
- CharBuffer in = CharBuffer.wrap("aaa");
- ByteBuffer out = ByteBuffer.allocate(5);
-
- // Illegal state: after reset.
- encoder.reset();
- try {
- encoder.flush(out);
- fail();
- } catch (IllegalStateException expected) {
- }
-
- // Normal case: after encode with endOfInput is true
- assertSame(encoder, encoder.reset());
- encoder.encode(in, out, true);
- out.rewind();
- CoderResult result = encoder.flush(out);
-
- // Good state: flush twice
- encoder.flush(out);
-
- // Illegal state: flush after encode with endOfInput is false
- assertSame(encoder, encoder.reset());
- encoder.encode(in, out, false);
- try {
- encoder.flush(out);
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- public void testFlushAfterConstructing() {
- ByteBuffer out = ByteBuffer.allocate(5);
-
- //Illegal state: flush after instance created
- try {
- encoder.flush(out);
- fail("should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
-
- }
-
- // test illegal states for encode facade
- public void testEncodeFacadeIllegalState() throws CharacterCodingException {
- // encode facade can be execute in anywhere
- CharBuffer in = CharBuffer.wrap("aaa");
- // Normal case: just created
- encoder.encode(in);
- in.rewind();
-
- // Normal case: just after encode facade
- encoder.encode(in);
- in.rewind();
-
- // Normal case: just after canEncode
- assertSame(encoder, encoder.reset());
- encoder.canEncode("\ud902\udc00");
- encoder.encode(in);
- in.rewind();
- assertSame(encoder, encoder.reset());
- encoder.canEncode('\ud902');
- encoder.encode(in);
- in.rewind();
-
- // Normal case: just after encode with that endOfInput is true
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState2"),
- ByteBuffer.allocate(30), true);
- encoder.encode(in);
- in.rewind();
-
- // Normal case:just after encode with that endOfInput is false
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState3"),
- ByteBuffer.allocate(30), false);
- encoder.encode(in);
- in.rewind();
-
- // Normal case: just after flush
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState4"),
- ByteBuffer.allocate(30), true);
- encoder.flush(ByteBuffer.allocate(10));
- encoder.encode(in);
- in.rewind();
- }
-
- // test illegal states for two encode method with endOfInput is true
- public void testEncodeTrueIllegalState() throws CharacterCodingException {
- CharBuffer in = CharBuffer.wrap("aaa");
- ByteBuffer out = ByteBuffer.allocate(5);
- // Normal case: just created
- encoder.encode(in, out, true);
- in.rewind();
- out.rewind();
-
- in.rewind();
- out.rewind();
-
- // Normal case: just after encode with that endOfInput is true
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState2"),
- ByteBuffer.allocate(30), true);
- encoder.encode(in, out, true);
- in.rewind();
- out.rewind();
-
- // Normal case:just after encode with that endOfInput is false
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState3"),
- ByteBuffer.allocate(30), false);
- encoder.encode(in, out, true);
- in.rewind();
- out.rewind();
-
- // Illegal state: just after flush
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState4"),
- ByteBuffer.allocate(30), true);
- encoder.flush(ByteBuffer.allocate(10));
- try {
- encoder.encode(in, out, true);
- fail("should illegal state");
- } catch (IllegalStateException e) {
- }
-
- // Normal case: after canEncode
- assertSame(encoder, encoder.reset());
- encoder.canEncode("\ud906\udc00");
- encoder.encode(in, out, true);
- in.rewind();
- out.rewind();
- assertSame(encoder, encoder.reset());
- encoder.canEncode('\ud905');
- encoder.encode(in, out, true);
- }
-
- // test illegal states for two encode method with endOfInput is false
- public void testEncodeFalseIllegalState() throws CharacterCodingException {
- CharBuffer in = CharBuffer.wrap("aaa");
- ByteBuffer out = ByteBuffer.allocate(5);
- // Normal case: just created
- encoder.encode(in, out, false);
- in.rewind();
- out.rewind();
-
- // Illegal state: just after encode facade
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState1"));
- try {
- encoder.encode(in, out, false);
- fail("should illegal state");
- } catch (IllegalStateException e) {
- }
-
- // Illegal state: just after encode with that endOfInput is true
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState2"),
- ByteBuffer.allocate(30), true);
- try {
- encoder.encode(in, out, false);
- fail("should illegal state");
- } catch (IllegalStateException e) {
- }
-
- // Normal case:just after encode with that endOfInput is false
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState3"),
- ByteBuffer.allocate(30), false);
- encoder.encode(in, out, false);
- in.rewind();
- out.rewind();
-
- // Illegal state: just after flush
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState4"),
- ByteBuffer.allocate(30), true);
- encoder.flush(ByteBuffer.allocate(10));
- try {
- encoder.encode(in, out, false);
- fail("should illegal state");
- } catch (IllegalStateException e) {
- }
-
- // Normal case: after canEncode
- assertSame(encoder, encoder.reset());
- encoder.canEncode("\ud906\udc00");
- encoder.encode(in, out, false);
- in.rewind();
- out.rewind();
- assertSame(encoder, encoder.reset());
- encoder.canEncode('\ud905');
- encoder.encode(in, out, false);
- }
-
- // test illegal states for two canEncode methods
- public void testCanEncodeIllegalState() throws CharacterCodingException {
- // Normal case: just created
- encoder.canEncode("\ud900\udc00");
- encoder.canEncode('\ud900');
-
- // Illegal state: just after encode with that endOfInput is true
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState2"),
- ByteBuffer.allocate(30), true);
- try {
- encoder.canEncode("\ud903\udc00");
- fail("should throw illegal state exception");
- } catch (IllegalStateException e) {
- }
-
- // Illegal state:just after encode with that endOfInput is false
- assertSame(encoder, encoder.reset());
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState3"),
- ByteBuffer.allocate(30), false);
- try {
- encoder.canEncode("\ud904\udc00");
- fail("should throw illegal state exception");
- } catch (IllegalStateException e) {
- }
-
- // Normal case: just after flush
- encoder.encode(CharBuffer.wrap("testCanEncodeIllegalState4"),
- ByteBuffer.allocate(30), true);
- encoder.flush(ByteBuffer.allocate(10));
- encoder.canEncode("\ud905\udc00");
- encoder.canEncode('\ud906');
-
- // Normal case: after reset again
- assertSame(encoder, encoder.reset());
- encoder.canEncode("\ud906\udc00");
- encoder.canEncode('\ud905');
- }
-
- /*
- * --------------------------------- illegal state test end
- * ---------------------------------
- */
-
- /*
- * Class under test for boolean canEncode(CharSequence)
- */
- public void testCanEncodeCharSequence() {
- // for non-mapped char
- assertTrue(encoder.canEncode("\uc2c0"));
- // surrogate char for unicode
- // 1st byte: d800-dbff
- // 2nd byte: dc00-dfff
- // valid surrogate pair
- assertTrue(encoder.canEncode("\ud800\udc00"));
- // invalid surrogate pair
- assertTrue(encoder.canEncode("\ud800\udb00"));
- }
-
- public void test_canEncode_char_ICUBug() {
- // The RI doesn't allow this, but icu4c does.
- assertTrue(encoder.canEncode('\ud800'));
- }
-
- public void test_canEncode_CharSequence_ICUBug() {
- // The RI doesn't allow this, but icu4c does.
- assertTrue(encoder.canEncode("\ud800"));
- }
-
- public void test_canEncode_empty() throws Exception {
- assertTrue(encoder.canEncode(""));
- }
-
- public void test_canEncode_null() throws Exception {
- try {
- encoder.canEncode(null);
- fail();
- } catch (NullPointerException e) {
- }
- }
-
- /*
- * Class under test for Charset charset()
- */
- public void testCharset() {
- try {
- encoder = new MockCharsetEncoder(Charset.forName("gbk"), 1,
- MAX_BYTES);
- // assertSame(encoder.charset(), Charset.forName("gbk"));
- } catch (UnsupportedCharsetException e) {
- System.err
- .println("Don't support GBK encoding, ignore current test");
- }
- }
-
- /*
- * Class under test for ByteBuffer encode(CharBuffer)
- */
- public void testEncodeCharBuffer() throws CharacterCodingException {
- // Null pointer
- try {
- encoder.encode(null);
- fail("should throw null pointer exception");
- } catch (NullPointerException e) {
- }
-
- // empty input buffer
- ByteBuffer out = encoder.encode(CharBuffer.wrap(""));
- assertEquals(out.position(), 0);
- assertByteArray(out, new byte[0]);
- // assertByteArray(out, surrogate);
-
- // normal case
- out = encoder.encode(CharBuffer.wrap(unistr));
- assertEquals(out.position(), 0);
- assertByteArray(out, addSurrogate(unibytes));
-
- // Regression test for harmony-3378
- Charset cs = Charset.forName("UTF-8");
- CharsetEncoder encoder = cs.newEncoder();
- encoder.onMalformedInput(CodingErrorAction.REPLACE);
- encoder = encoder.replaceWith(new byte[] { (byte) 0xef, (byte) 0xbf,
- (byte) 0xbd, });
- CharBuffer in = CharBuffer.wrap("\ud800");
- out = encoder.encode(in);
- assertNotNull(out);
- }
-
- private byte[] addSurrogate(byte[] expected) {
- if (surrogate.length > 0) {
- byte[] temp = new byte[surrogate.length + expected.length];
- System.arraycopy(surrogate, 0, temp, 0, surrogate.length);
- System.arraycopy(expected, 0, temp, surrogate.length,
- expected.length);
- expected = temp;
- }
- return expected;
- }
-
- /**
- * @return
- */
- protected byte[] getEmptyByteArray() {
- return new byte[0];
- }
-
- CharBuffer getMalformedCharBuffer() {
- return CharBuffer.wrap("malform buffer");
- }
-
- CharBuffer getUnmapCharBuffer() {
- return CharBuffer.wrap("unmap buffer");
- }
-
- CharBuffer getExceptionCharBuffer() {
- return CharBuffer.wrap("runtime buffer");
- }
-
- public void testEncodeCharBufferException() throws CharacterCodingException {
- ByteBuffer out;
- CharBuffer in;
- // MalformedException:
- in = getMalformedCharBuffer();
- encoder.onMalformedInput(CodingErrorAction.REPORT);
- encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- if (in != null) {
- try {
- // regression test for Harmony-1379
- encoder.encode(in);
- fail("should throw MalformedInputException");
- } catch (MalformedInputException e) {
- }
-
- encoder.reset();
- in.rewind();
- encoder.onMalformedInput(CodingErrorAction.IGNORE);
- out = encoder.encode(in);
- assertByteArray(out, addSurrogate(unibytes));
-
- encoder.reset();
- in.rewind();
- encoder.onMalformedInput(CodingErrorAction.REPLACE);
- out = encoder.encode(in);
- assertByteArray(out, addSurrogate(unibytesWithRep));
- }
-
- // Unmapped Exception:
- in = getUnmapCharBuffer();
- encoder.onMalformedInput(CodingErrorAction.REPORT);
- encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- if (in != null) {
- encoder.reset();
- try {
- encoder.encode(in);
- fail("should throw UnmappableCharacterException");
- } catch (UnmappableCharacterException e) {
- }
-
- encoder.reset();
- in.rewind();
- encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
- out = encoder.encode(in);
- assertByteArray(out, unibytes);
-
- encoder.reset();
- in.rewind();
- encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
- out = encoder.encode(in);
- assertByteArray(out, unibytesWithRep);
- }
-
- // RuntimeException
- try {
- encoder.encode(getExceptionCharBuffer());
- fail("should throw runtime exception");
- } catch (RuntimeException e) {
- }
- }
-
- /*
- * utility method, extract given bytebuffer to a string and compare with
- * give string
- */
- void assertByteArray(ByteBuffer out, byte[] expected) {
- out = out.duplicate();
- if (out.position() != 0) {
- out.flip();
- }
- byte[] ba = new byte[out.limit() - out.position()];
- out.get(ba);
- // byte[] ba = out.array();
- assertTrue(Arrays.equals(ba, expected));
- }
-
- /*
- * Class under test for CoderResult encode(CharBuffer, ByteBuffer, boolean)
- */
- public void testEncodeCharBufferByteBufferboolean()
- throws CharacterCodingException {
- ByteBuffer out = ByteBuffer.allocate(200);
- CharBuffer in = CharBuffer.wrap(unistr);
- // Null pointer
- try {
- encoder.encode(null, out, true);
- fail("should throw null pointer exception");
- } catch (NullPointerException e) {
- }
- try {
- encoder.encode(in, null, true);
- fail("should throw null pointer exception");
- } catch (NullPointerException e) {
- }
-
- // normal case, one complete operation
- assertSame(encoder, encoder.reset());
- in.rewind();
- out.rewind();
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, true));
- assertEquals(out.limit(), 200);
- assertTrue(out.position() > 0);
- assertTrue(out.remaining() > 0);
- assertEquals(out.capacity(), 200);
- assertByteArray(out, addSurrogate(unibytes));
- in.rewind();
-
- encoder.flush(out);
-
- // normal case, one complete operation, but call twice, first time set
- // endOfInput to false
- assertSame(encoder, encoder.reset());
- in.rewind();
- out = ByteBuffer.allocate(200);
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, false));
- assertEquals(out.limit(), 200);
- assertTrue(out.position() > 0);
- assertTrue(out.remaining() > 0);
- assertEquals(out.capacity(), 200);
- assertByteArray(out, addSurrogate(unibytes));
-
- in.rewind();
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, false));
- in.rewind();
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, true));
- assertEquals(out.limit(), 200);
- assertTrue(out.position() > 0);
- assertTrue(out.remaining() > 0);
- assertEquals(out.capacity(), 200);
-
- assertByteArray(out, addSurrogate(duplicateByteArray(unibytes, 3)));
-
- // overflow
- out = ByteBuffer.allocate(4);
- assertSame(encoder, encoder.reset());
- in.rewind();
- out.rewind();
- assertSame(CoderResult.OVERFLOW, encoder.encode(in, out, true));
- assertEquals(out.limit(), 4);
- assertEquals(out.position(), 4);
- assertEquals(out.remaining(), 0);
- assertEquals(out.capacity(), 4);
- ByteBuffer temp = ByteBuffer.allocate(200);
- out.flip();
- temp.put(out);
- out = temp;
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, true));
- assertEquals(out.limit(), 200);
- assertTrue(out.position() > 0);
- assertTrue(out.remaining() > 0);
- assertEquals(out.capacity(), 200);
- assertByteArray(out, addSurrogate(unibytes));
-
- assertSame(encoder, encoder.reset());
- in.rewind();
- out = ByteBuffer.allocate(4);
- assertSame(CoderResult.OVERFLOW, encoder.encode(in, out, false));
- assertEquals(out.limit(), 4);
- assertEquals(out.position(), 4);
- assertEquals(out.remaining(), 0);
- assertEquals(out.capacity(), 4);
- temp = ByteBuffer.allocate(200);
- out.flip();
- temp.put(out);
- out = temp;
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, false));
- assertEquals(out.limit(), 200);
- assertTrue(out.position() > 0);
- assertTrue(out.remaining() > 0);
- assertEquals(out.capacity(), 200);
- assertByteArray(out, addSurrogate(unibytes));
- }
-
- void printByteBuffer(ByteBuffer buffer) {
- System.out.println("print buffer");
- if (buffer.position() != 0) {
- buffer.flip();
- }
- byte[] ba = buffer.array();
- for (int i = 0; i < ba.length; i++) {
- System.out.println(Integer.toHexString(ba[i]));
- }
- }
-
- public void testEncodeCharBufferByteBufferbooleanExceptionFalse()
- throws CharacterCodingException {
- implTestEncodeCharBufferByteBufferbooleanException(false);
- }
-
- public void testEncodeCharBufferByteBufferbooleanExceptionTrue()
- throws CharacterCodingException {
- implTestEncodeCharBufferByteBufferbooleanException(true);
- }
-
- private byte[] duplicateByteArray(byte[] ba, int times) {
- byte[] result = new byte[ba.length * times];
- for (int i = 0; i < times; i++) {
- System.arraycopy(ba, 0, result, i * ba.length, ba.length);
- }
- return result;
- }
-
- protected void implTestEncodeCharBufferByteBufferbooleanException(
- boolean endOfInput) throws CharacterCodingException {
- ByteBuffer out = ByteBuffer.allocate(100);
-
- // MalformedException:
- CharBuffer in = getMalformedCharBuffer();
- encoder.onMalformedInput(CodingErrorAction.REPORT);
- encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- if (in != null) {
- encoder.reset();
- CoderResult r = encoder.encode(in, out, endOfInput);
- assertTrue(r.isMalformed());
-
- encoder.reset();
- out.clear();
- in.rewind();
- encoder.onMalformedInput(CodingErrorAction.IGNORE);
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
- endOfInput));
- assertCodingErrorAction(endOfInput, out, in, unibytes);
-
- encoder.reset();
- out.clear();
- in.rewind();
- encoder.onMalformedInput(CodingErrorAction.REPLACE);
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
- endOfInput));
- assertCodingErrorAction(endOfInput, out, in, unibytesWithRep);
- } else {
- System.out.println("Cannot find malformed char buffer for "
- + cs.name());
- }
-
- // Unmapped Exception:
- in = getUnmapCharBuffer();
- encoder.onMalformedInput(CodingErrorAction.REPORT);
- encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- if (in != null) {
- encoder.reset();
- out.clear();
- assertTrue(encoder.encode(in, out, endOfInput).isUnmappable());
-
- encoder.reset();
- out.clear();
- in.rewind();
- encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
- endOfInput));
- assertCodingErrorAction(endOfInput, out, in, unibytes);
-
- encoder.reset();
- out.clear();
- in.rewind();
- encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
- endOfInput));
- assertCodingErrorAction(endOfInput, out, in, unibytesWithRep);
- } else {
- System.out.println("Cannot find unmapped char buffer for "
- + cs.name());
- }
-
- // RuntimeException
- try {
- encoder.encode(getExceptionCharBuffer());
- fail("should throw runtime exception");
- } catch (RuntimeException e) {
- }
- }
-
- private void assertCodingErrorAction(boolean endOfInput, ByteBuffer out,
- CharBuffer in, byte[] expect) {
- if (endOfInput) {
- assertByteArray(out, addSurrogate(expect));
- } else {
- in.rewind();
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out,
- endOfInput));
- in.rewind();
- assertSame(CoderResult.UNDERFLOW, encoder.encode(in, out, true));
- assertByteArray(out, addSurrogate(duplicateByteArray(expect, 3)));
- }
- }
-
- /*
- * Class under test for CoderResult flush(ByteBuffer)
- */
- public void testFlush() throws CharacterCodingException {
- ByteBuffer out = ByteBuffer.allocate(6);
- CharBuffer in = CharBuffer.wrap("aaa");
- assertEquals(in.remaining(), 3);
-
- // by encode facade, so that internal state will be wrong
- encoder.encode(CharBuffer.wrap("testFlush"), ByteBuffer.allocate(20),
- true);
- assertSame(CoderResult.UNDERFLOW, encoder
- .flush(ByteBuffer.allocate(50)));
- }
-
- /*
- * test isLegalReplacement(byte[])
- */
- public void test_isLegalReplacement_null() {
- try {
- encoder.isLegalReplacement(null);
- fail("should throw null pointer exception");
- } catch (NullPointerException e) {
- }
- }
-
- public void test_isLegalReplacement_good() {
- assertTrue(encoder.isLegalReplacement(specifiedReplacement));
- }
-
- public void test_isLegalReplacement_bad() {
- assertTrue(encoder.isLegalReplacement(new byte[200]));
- byte[] ba = getIllegalByteArray();
- if (ba != null) {
- assertFalse(encoder.isLegalReplacement(ba));
- }
- }
-
- public void test_isLegalReplacement_empty_array() {
- // ISO, ASC, GB, UTF8 encoder will throw exception in RI
- // others will pass
- assertTrue(encoder.isLegalReplacement(new byte[0]));
- }
-
- public void testOnMalformedInput() {
- assertSame(CodingErrorAction.REPORT, encoder.malformedInputAction());
- try {
- encoder.onMalformedInput(null);
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
- encoder.onMalformedInput(CodingErrorAction.IGNORE);
- assertSame(CodingErrorAction.IGNORE, encoder.malformedInputAction());
- }
-
- public void testOnUnmappableCharacter() {
- assertSame(CodingErrorAction.REPORT, encoder
- .unmappableCharacterAction());
- try {
- encoder.onUnmappableCharacter(null);
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
- encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
- assertSame(CodingErrorAction.IGNORE, encoder
- .unmappableCharacterAction());
- }
-
- public void testReplacement() {
- try {
- encoder.replaceWith(null);
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
- try {
- encoder.replaceWith(new byte[0]);
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
- try {
- encoder.replaceWith(new byte[100]);
- fail("should throw null pointer exception");
- } catch (IllegalArgumentException e) {
- }
-
- byte[] nr = getLegalByteArray();
- assertSame(encoder, encoder.replaceWith(nr));
- assertSame(nr, encoder.replacement());
-
- nr = getIllegalByteArray();
- try {
- encoder.replaceWith(new byte[100]);
- fail();
- } catch (IllegalArgumentException e) {
- }
- }
-
- protected byte[] getLegalByteArray() {
- return new byte[] { 'a' };
- }
-
- protected byte[] getIllegalByteArray() {
- return new byte[155];
- }
-
- /*
- * Mock subclass of CharsetEncoder For protected method test
- */
- public static class MockCharsetEncoder extends CharsetEncoder {
-
- boolean flushed = false;
-
- public boolean isFlushed() {
- boolean result = flushed;
- flushed = false;
- return result;
- }
-
- public boolean isLegalReplacement(byte[] ba) {
- if (ba.length == 155) {// specified magic number, return false
- return false;
- }
- return super.isLegalReplacement(ba);
- }
-
- public MockCharsetEncoder(Charset cs, float aver, float max) {
- super(cs, aver, max);
- }
-
- public MockCharsetEncoder(Charset cs, float aver, float max,
- byte[] replacement) {
- super(cs, aver, max, replacement);
- }
-
- protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
- int inPosition = in.position();
- char[] input = new char[in.remaining()];
- in.get(input);
- String result = new String(input);
- if (result.startsWith("malform")) {
- // reset the cursor to the error position
- in.position(inPosition);
- // in.position(0);
- // set the error length
- return CoderResult.malformedForLength("malform".length());
- } else if (result.startsWith("unmap")) {
- // reset the cursor to the error position
- in.position(inPosition);
- // in.position(0);
- // set the error length
- return CoderResult.unmappableForLength("unmap".length());
- } else if (result.startsWith("runtime")) {
- // reset the cursor to the error position
- in.position(0);
- // set the error length
- throw new RuntimeException("runtime");
- }
- int inLeft = input.length;
- int outLeft = out.remaining();
- CoderResult r = CoderResult.UNDERFLOW;
- int length = inLeft;
- if (outLeft < inLeft) {
- r = CoderResult.OVERFLOW;
- length = outLeft;
- in.position(inPosition + outLeft);
- }
- for (int i = 0; i < length; i++) {
- out.put((byte) input[i]);
- }
- return r;
- }
-
- protected CoderResult implFlush(ByteBuffer out) {
- CoderResult result = super.implFlush(out);
- int length = 0;
- if (out.remaining() >= 5) {
- length = 5;
- result = CoderResult.UNDERFLOW;
- flushed = true;
- // for (int i = 0; i < length; i++) {
- // out.put((byte)'f');
- // }
- } else {
- length = out.remaining();
- result = CoderResult.OVERFLOW;
- }
- return result;
- }
-
- protected void implReplaceWith(byte[] ba) {
- assertSame(ba, replacement());
- }
-
- }
-
- /*
- * mock charset for test encoder initialization
- */
- public static class MockCharset extends Charset {
- protected MockCharset(String arg0, String[] arg1) {
- super(arg0, arg1);
- }
-
- public boolean contains(Charset arg0) {
- return false;
- }
-
- public CharsetDecoder newDecoder() {
- return new CharsetDecoderTest.MockCharsetDecoder(this,
- (float) AVER_BYTES, MAX_BYTES);
- }
-
- public CharsetEncoder newEncoder() {
- return new MockCharsetEncoder(this, (float) AVER_BYTES, MAX_BYTES);
- }
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetTest.java
deleted file mode 100644
index 92f230e..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/CharsetTest.java
+++ /dev/null
@@ -1,906 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.spi.CharsetProvider;
-import java.nio.charset.UnsupportedCharsetException;
-import java.security.Permission;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.Vector;
-
-import junit.framework.TestCase;
-
-/**
- * Test class java.nio.Charset.
- */
-public class CharsetTest extends TestCase {
-
- public void test_allAvailableCharsets() throws Exception {
- // Check that we can instantiate every Charset, CharsetDecoder, and CharsetEncoder.
- for (String charsetName : Charset.availableCharsets().keySet()) {
- if (charsetName.equals("UTF-32")) {
- // Our UTF-32 is broken. http://b/2702411
- // TODO: remove this hack when UTF-32 is fixed.
- continue;
- }
-
- Charset cs = Charset.forName(charsetName);
- assertNotNull(cs.newDecoder());
- if (cs.canEncode()) {
- CharsetEncoder enc = cs.newEncoder();
- assertNotNull(enc);
- assertNotNull(enc.replacement());
- }
- }
- }
-
- public void test_defaultCharset() {
- assertEquals("UTF-8", Charset.defaultCharset().name());
- }
-
- public void test_isRegistered() {
- // Regression for HARMONY-45
-
- // Will contain names of charsets registered with IANA
- Set<String> knownRegisteredCharsets = new HashSet<String>();
-
- // Will contain names of charsets not known to be registered with IANA
- Set<String> unknownRegisteredCharsets = new HashSet<String>();
-
- Set<String> names = Charset.availableCharsets().keySet();
- for (Iterator nameItr = names.iterator(); nameItr.hasNext();) {
- String name = (String) nameItr.next();
- if (name.toLowerCase(Locale.ROOT).startsWith("x-")) {
- unknownRegisteredCharsets.add(name);
- } else {
- knownRegisteredCharsets.add(name);
- }
- }
-
- for (Iterator nameItr = knownRegisteredCharsets.iterator(); nameItr.hasNext();) {
- String name = (String) nameItr.next();
- Charset cs = Charset.forName(name);
- if (!cs.isRegistered()) {
- System.err.println("isRegistered was false for " + name + " " + cs.name() + " " + cs.aliases());
- }
- assertTrue("isRegistered was false for " + name + " " + cs.name() + " " + cs.aliases(), cs.isRegistered());
- }
- for (Iterator nameItr = unknownRegisteredCharsets.iterator(); nameItr.hasNext();) {
- String name = (String) nameItr.next();
- Charset cs = Charset.forName(name);
- assertFalse("isRegistered was true for " + name + " " + cs.name() + " " + cs.aliases(), cs.isRegistered());
- }
- }
-
- public void test_guaranteedCharsetsAvailable() throws Exception {
- // All Java implementations must support these charsets.
- assertNotNull(Charset.forName("ISO-8859-1"));
- assertNotNull(Charset.forName("US-ASCII"));
- assertNotNull(Charset.forName("UTF-16"));
- assertNotNull(Charset.forName("UTF-16BE"));
- assertNotNull(Charset.forName("UTF-16LE"));
- assertNotNull(Charset.forName("UTF-8"));
- }
-
- // http://code.google.com/p/android/issues/detail?id=42769
- public void test_42769() throws Exception {
- ArrayList<Thread> threads = new ArrayList<Thread>();
- for (int i = 0; i < 10; ++i) {
- Thread t = new Thread(new Runnable() {
- public void run() {
- for (int i = 0; i < 50; ++i) {
- Charset.availableCharsets();
- }
- }
- });
- threads.add(t);
- }
-
- for (Thread t : threads) {
- t.start();
- }
- for (Thread t : threads) {
- t.join();
- }
- }
-
- public void test_have_canonical_EUC_JP() throws Exception {
- assertEquals("EUC-JP", Charset.forName("EUC-JP").name());
- }
-
- public void test_EUC_JP_replacement_character() throws Exception {
- // We have text either side of the replacement character, because all kinds of errors
- // could lead to a replacement character being returned.
- assertEncodes(Charset.forName("EUC-JP"), " \ufffd ", ' ', 0xf4, 0xfe, ' ');
- assertDecodes(Charset.forName("EUC-JP"), " \ufffd ", ' ', 0xf4, 0xfe, ' ');
- }
-
- public void test_SCSU_replacement_character() throws Exception {
- // We have text either side of the replacement character, because all kinds of errors
- // could lead to a replacement character being returned.
- assertEncodes(Charset.forName("SCSU"), " \ufffd ", ' ', 14, 0xff, 0xfd, ' ');
- assertDecodes(Charset.forName("SCSU"), " \ufffd ", ' ', 14, 0xff, 0xfd, ' ');
- }
-
- public void test_Shift_JIS_replacement_character() throws Exception {
- // We have text either side of the replacement character, because all kinds of errors
- // could lead to a replacement character being returned.
- assertEncodes(Charset.forName("Shift_JIS"), " \ufffd ", ' ', 0xfc, 0xfc, ' ');
- assertDecodes(Charset.forName("Shift_JIS"), " \ufffd ", ' ', 0xfc, 0xfc, ' ');
- }
-
- public void test_UTF_16() throws Exception {
- Charset cs = Charset.forName("UTF-16");
- // Writes big-endian, with a big-endian BOM.
- assertEncodes(cs, "a\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
- // Reads whatever the BOM tells it to read...
- assertDecodes(cs, "a\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
- assertDecodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
- // ...and defaults to reading big-endian if there's no BOM.
- assertDecodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
- }
-
- public void test_UTF_16BE() throws Exception {
- Charset cs = Charset.forName("UTF-16BE");
- // Writes big-endian, with no BOM.
- assertEncodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
- // Treats a little-endian BOM as an error and continues to read big-endian.
- // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
- assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 'a', 0x06, 0x66);
- // Accepts a big-endian BOM and includes U+FEFF in the decoded output.
- assertDecodes(cs, "\ufeffa\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
- // Defaults to reading big-endian.
- assertDecodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
- }
-
- public void test_UTF_16LE() throws Exception {
- Charset cs = Charset.forName("UTF-16LE");
- // Writes little-endian, with no BOM.
- assertEncodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
- // Accepts a little-endian BOM and includes U+FEFF in the decoded output.
- assertDecodes(cs, "\ufeffa\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
- // Treats a big-endian BOM as an error and continues to read little-endian.
- // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
- assertDecodes(cs, "\ufffda\u0666", 0xfe, 0xff, 'a', 0, 0x66, 0x06);
- // Defaults to reading little-endian.
- assertDecodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
- }
-
- public void test_x_UTF_16LE_BOM() throws Exception {
- Charset cs = Charset.forName("x-UTF-16LE-BOM");
- // Writes little-endian, with a BOM.
- assertEncodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
- // Accepts a little-endian BOM and swallows the BOM.
- assertDecodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
- // Swallows a big-endian BOM, but continues to read little-endian!
- assertDecodes(cs, "\u6100\u6606", 0xfe, 0xff, 'a', 0, 0x66, 0x06);
- // Defaults to reading little-endian.
- assertDecodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
- }
-
- public void test_UTF_32() throws Exception {
- Charset cs = Charset.forName("UTF-32");
- // Writes big-endian, with no BOM.
- assertEncodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- // Reads whatever the BOM tells it to read...
- assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- // ...and defaults to reading big-endian if there's no BOM.
- assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- }
-
- public void test_UTF_32BE() throws Exception {
- Charset cs = Charset.forName("UTF-32BE");
- // Writes big-endian, with no BOM.
- assertEncodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- // Treats a little-endian BOM as an error and continues to read big-endian.
- // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
- assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 0, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- // Accepts a big-endian BOM and swallows the BOM.
- assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- // Defaults to reading big-endian.
- assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- }
-
- public void test_UTF_32LE() throws Exception {
- Charset cs = Charset.forName("UTF-32LE");
- // Writes little-endian, with no BOM.
- assertEncodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- // Accepts a little-endian BOM and swallows the BOM.
- assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- // Treats a big-endian BOM as an error and continues to read little-endian.
- // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
- assertDecodes(cs, "\ufffda\u0666", 0, 0, 0xfe, 0xff, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- // Defaults to reading little-endian.
- assertDecodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- }
-
- public void test_X_UTF_32BE_BOM() throws Exception {
- Charset cs = Charset.forName("X-UTF-32BE-BOM");
- // Writes big-endian, with a big-endian BOM.
- assertEncodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- // Treats a little-endian BOM as an error and continues to read big-endian.
- // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
- assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 0, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- // Swallows a big-endian BOM, and continues to read big-endian.
- assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- // Defaults to reading big-endian.
- assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
- }
-
- public void test_X_UTF_32LE_BOM() throws Exception {
- Charset cs = Charset.forName("X-UTF-32LE-BOM");
- // Writes little-endian, with a little-endian BOM.
- assertEncodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- // Accepts a little-endian BOM and swallows the BOM.
- assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- // Treats a big-endian BOM as an error and continues to read little-endian.
- // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
- assertDecodes(cs, "\ufffda\u0666", 0, 0, 0xfe, 0xff, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- // Defaults to reading little-endian.
- assertDecodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
- }
-
- private byte[] toByteArray(int[] ints) {
- byte[] result = new byte[ints.length];
- for (int i = 0; i < ints.length; ++i) {
- result[i] = (byte) ints[i];
- }
- return result;
- }
-
- private void assertEncodes(Charset cs, String s, int... expectedByteInts) throws Exception {
- ByteBuffer out = cs.encode(s);
- byte[] bytes = new byte[out.remaining()];
- out.get(bytes);
- assertEquals(Arrays.toString(toByteArray(expectedByteInts)), Arrays.toString(bytes));
- }
-
- private void assertDecodes(Charset cs, String s, int... byteInts) throws Exception {
- ByteBuffer in = ByteBuffer.wrap(toByteArray(byteInts));
- CharBuffer out = cs.decode(in);
- assertEquals(s, out.toString());
- }
-
- public void test_forNameLjava_lang_String() {
- // Invoke forName two times with the same canonical name.
- // It should return the same reference.
- Charset cs1 = Charset.forName("UTF-8");
- Charset cs2 = Charset.forName("UTF-8");
- assertSame(cs1, cs2);
-
- // test forName: invoke forName two times for the same Charset using
- // canonical name and alias, it should return the same reference.
- Charset cs3 = Charset.forName("ASCII");
- Charset cs4 = Charset.forName("US-ASCII");
- assertSame(cs3, cs4);
- }
-
- static MockCharset charset1 = new MockCharset("mockCharset00",
- new String[] { "mockCharset01", "mockCharset02" });
-
- static MockCharset charset2 = new MockCharset("mockCharset10",
- new String[] { "mockCharset11", "mockCharset12" });
-
- // Test the required 6 charsets are supported.
- public void testRequiredCharsetSupported() {
- assertTrue(Charset.isSupported("US-ASCII"));
- assertTrue(Charset.isSupported("ASCII"));
- assertTrue(Charset.isSupported("ISO-8859-1"));
- assertTrue(Charset.isSupported("ISO8859_1"));
- assertTrue(Charset.isSupported("UTF-8"));
- assertTrue(Charset.isSupported("UTF8"));
- assertTrue(Charset.isSupported("UTF-16"));
- assertTrue(Charset.isSupported("UTF-16BE"));
- assertTrue(Charset.isSupported("UTF-16LE"));
-
- Charset c1 = Charset.forName("US-ASCII");
- assertEquals("US-ASCII", Charset.forName("US-ASCII").name());
- assertEquals("US-ASCII", Charset.forName("ASCII").name());
- assertEquals("ISO-8859-1", Charset.forName("ISO-8859-1").name());
- assertEquals("ISO-8859-1", Charset.forName("ISO8859_1").name());
- assertEquals("UTF-8", Charset.forName("UTF-8").name());
- assertEquals("UTF-8", Charset.forName("UTF8").name());
- assertEquals("UTF-16", Charset.forName("UTF-16").name());
- assertEquals("UTF-16BE", Charset.forName("UTF-16BE").name());
- assertEquals("UTF-16LE", Charset.forName("UTF-16LE").name());
-
- assertNotSame(Charset.availableCharsets(), Charset.availableCharsets());
- // assertSame(Charset.forName("US-ASCII"), Charset.availableCharsets().get("US-ASCII"));
- // assertSame(Charset.forName("US-ASCII"), c1);
- assertTrue(Charset.availableCharsets().containsKey("US-ASCII"));
- assertTrue(Charset.availableCharsets().containsKey("ISO-8859-1"));
- assertTrue(Charset.availableCharsets().containsKey("UTF-8"));
- assertTrue(Charset.availableCharsets().containsKey("UTF-16"));
- assertTrue(Charset.availableCharsets().containsKey("UTF-16BE"));
- assertTrue(Charset.availableCharsets().containsKey("UTF-16LE"));
- }
-
- public void testIsSupported_Null() {
- try {
- Charset.isSupported(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testIsSupported_EmptyString() {
- try {
- Charset.isSupported("");
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testIsSupported_InvalidInitialCharacter() {
- try {
- Charset.isSupported(".char");
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testIsSupported_IllegalName() {
- try {
- Charset.isSupported(" ///#$$");
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- }
-
- public void testIsSupported_NotSupported() {
- assertFalse(Charset.isSupported("well-formed-name-of-a-charset-that-does-not-exist"));
- }
-
- public void testForName_Null() {
- try {
- Charset.forName(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testForName_EmptyString() {
- try {
- Charset.forName("");
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testForName_InvalidInitialCharacter() {
- try {
- Charset.forName(".char");
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testForName_IllegalName() {
- try {
- Charset.forName(" ///#$$");
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- }
-
- public void testForName_NotSupported() {
- try {
- Charset.forName("impossible");
- fail();
- } catch (UnsupportedCharsetException expected) {
- }
- }
-
- public void testConstructor_Normal() {
- final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
- MockCharset c = new MockCharset(mockName, new String[] { "mock" });
- assertEquals(mockName, c.name());
- assertEquals(mockName, c.displayName());
- assertEquals(mockName, c.displayName(Locale.getDefault()));
- assertEquals("mock", c.aliases().toArray()[0]);
- assertEquals(1, c.aliases().toArray().length);
- }
-
- public void testConstructor_EmptyCanonicalName() {
- try {
- new MockCharset("", new String[0]);
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- }
-
- public void testConstructor_IllegalCanonicalName_Initial() {
- try {
- new MockCharset("-123", new String[] { "mock" });
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- }
-
- public void testConstructor_IllegalCanonicalName_Middle() {
- try {
- new MockCharset("1%%23", new String[] { "mock" });
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- try {
- new MockCharset("1//23", new String[] { "mock" });
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- }
-
- public void testConstructor_NullCanonicalName() {
- try {
- MockCharset c = new MockCharset(null, new String[] { "mock" });
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testConstructor_NullAliases() {
- MockCharset c = new MockCharset("mockChar", null);
- assertEquals("mockChar", c.name());
- assertEquals("mockChar", c.displayName());
- assertEquals("mockChar", c.displayName(Locale.getDefault()));
- assertEquals(0, c.aliases().toArray().length);
- }
-
- public void testConstructor_NullAliase() {
- try {
- new MockCharset("mockChar", new String[] { "mock", null });
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testConstructor_NoAliases() {
- MockCharset c = new MockCharset("mockChar", new String[0]);
- assertEquals("mockChar", c.name());
- assertEquals("mockChar", c.displayName());
- assertEquals("mockChar", c.displayName(Locale.getDefault()));
- assertEquals(0, c.aliases().toArray().length);
- }
-
- public void testConstructor_EmptyAliases() {
- try {
- new MockCharset("mockChar", new String[] { "" });
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- }
-
- // Test the constructor with illegal aliases: starting with neither a digit nor a letter.
- public void testConstructor_IllegalAliases_Initial() {
- try {
- new MockCharset("mockChar", new String[] { "mock", "-123" });
- fail();
- } catch (IllegalCharsetNameException e) {
- }
- }
-
- public void testConstructor_IllegalAliases_Middle() {
- try {
- new MockCharset("mockChar", new String[] { "mock", "22##ab" });
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- try {
- new MockCharset("mockChar", new String[] { "mock", "22%%ab" });
- fail();
- } catch (IllegalCharsetNameException expected) {
- }
- }
-
- public void testAliases_Multiple() {
- final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
- MockCharset c = new MockCharset("mockChar", new String[] { "mock", mockName, "mock2" });
- assertEquals("mockChar", c.name());
- assertEquals(3, c.aliases().size());
- assertTrue(c.aliases().contains("mock"));
- assertTrue(c.aliases().contains(mockName));
- assertTrue(c.aliases().contains("mock2"));
-
- try {
- c.aliases().clear();
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- public void testAliases_Duplicate() {
- final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
- MockCharset c = new MockCharset("mockChar", new String[] { "mockChar",
- "mock", mockName, "mock", "mockChar", "mock", "mock2" });
- assertEquals("mockChar", c.name());
- assertEquals(4, c.aliases().size());
- assertTrue(c.aliases().contains("mockChar"));
- assertTrue(c.aliases().contains("mock"));
- assertTrue(c.aliases().contains(mockName));
- assertTrue(c.aliases().contains("mock2"));
- }
-
- public void testCanEncode() {
- MockCharset c = new MockCharset("mock", null);
- assertTrue(c.canEncode());
- }
-
- public void testIsRegistered() {
- MockCharset c = new MockCharset("mock", null);
- assertTrue(c.isRegistered());
- }
-
- public void testDisplayName_Locale_Null() {
- MockCharset c = new MockCharset("mock", null);
- assertEquals("mock", c.displayName(null));
- }
-
- public void testCompareTo_Normal() {
- MockCharset c1 = new MockCharset("mock", null);
- assertEquals(0, c1.compareTo(c1));
-
- MockCharset c2 = new MockCharset("Mock", null);
- assertEquals(0, c1.compareTo(c2));
-
- c2 = new MockCharset("mock2", null);
- assertTrue(c1.compareTo(c2) < 0);
- assertTrue(c2.compareTo(c1) > 0);
-
- c2 = new MockCharset("mack", null);
- assertTrue(c1.compareTo(c2) > 0);
- assertTrue(c2.compareTo(c1) < 0);
-
- c2 = new MockCharset("m.", null);
- assertTrue(c1.compareTo(c2) > 0);
- assertTrue(c2.compareTo(c1) < 0);
-
- c2 = new MockCharset("m:", null);
- assertEquals("mock".compareToIgnoreCase("m:"), c1.compareTo(c2));
- assertEquals("m:".compareToIgnoreCase("mock"), c2.compareTo(c1));
-
- c2 = new MockCharset("m-", null);
- assertTrue(c1.compareTo(c2) > 0);
- assertTrue(c2.compareTo(c1) < 0);
-
- c2 = new MockCharset("m_", null);
- assertTrue(c1.compareTo(c2) > 0);
- assertTrue(c2.compareTo(c1) < 0);
- }
-
- public void testCompareTo_Null() {
- MockCharset c1 = new MockCharset("mock", null);
- try {
- c1.compareTo(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testCompareTo_DiffCharsetClass() {
- MockCharset c1 = new MockCharset("mock", null);
- MockCharset2 c2 = new MockCharset2("Mock", new String[] { "myname" });
- assertEquals(0, c1.compareTo(c2));
- assertEquals(0, c2.compareTo(c1));
- }
-
- public void testEquals_Normal() {
- MockCharset c1 = new MockCharset("mock", null);
- MockCharset2 c2 = new MockCharset2("mock", null);
- assertTrue(c1.equals(c2));
- assertTrue(c2.equals(c1));
-
- c2 = new MockCharset2("Mock", null);
- assertFalse(c1.equals(c2));
- assertFalse(c2.equals(c1));
- }
-
- public void testEquals_Null() {
- MockCharset c1 = new MockCharset("mock", null);
- assertFalse(c1.equals(null));
- }
-
- public void testEquals_NonCharsetObject() {
- MockCharset c1 = new MockCharset("mock", null);
- assertFalse(c1.equals("test"));
- }
-
- public void testEquals_DiffCharsetClass() {
- MockCharset c1 = new MockCharset("mock", null);
- MockCharset2 c2 = new MockCharset2("mock", null);
- assertTrue(c1.equals(c2));
- assertTrue(c2.equals(c1));
- }
-
- public void testHashCode_DiffCharsetClass() {
- MockCharset c1 = new MockCharset("mock", null);
- assertEquals(c1.hashCode(), "mock".hashCode());
-
- final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
- c1 = new MockCharset(mockName, new String[] { "mockChar", "mock",
- mockName, "mock", "mockChar", "mock", "mock2" });
- assertEquals(mockName.hashCode(), c1.hashCode());
- }
-
- public void testEncode_CharBuffer_Normal() throws Exception {
- MockCharset c1 = new MockCharset("testEncode_CharBuffer_Normal_mock", null);
- ByteBuffer bb = c1.encode(CharBuffer.wrap("abcdefg"));
- assertEquals("abcdefg", new String(bb.array(), "iso8859-1"));
- bb = c1.encode(CharBuffer.wrap(""));
- assertEquals("", new String(bb.array(), "iso8859-1"));
- }
-
- public void testEncode_CharBuffer_Unmappable() throws Exception {
- Charset c1 = Charset.forName("iso8859-1");
- ByteBuffer bb = c1.encode(CharBuffer.wrap("abcd\u5D14efg"));
- assertEquals(new String(bb.array(), "iso8859-1"),
- "abcd" + new String(c1.newEncoder().replacement(), "iso8859-1") + "efg");
- }
-
- public void testEncode_CharBuffer_NullCharBuffer() {
- MockCharset c = new MockCharset("mock", null);
- try {
- c.encode((CharBuffer) null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testEncode_CharBuffer_NullEncoder() {
- MockCharset2 c = new MockCharset2("mock2", null);
- try {
- c.encode(CharBuffer.wrap("hehe"));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testEncode_String_Normal() throws Exception {
- MockCharset c1 = new MockCharset("testEncode_String_Normal_mock", null);
- ByteBuffer bb = c1.encode("abcdefg");
- assertEquals("abcdefg", new String(bb.array(), "iso8859-1"));
- bb = c1.encode("");
- assertEquals("", new String(bb.array(), "iso8859-1"));
- }
-
- public void testEncode_String_Unmappable() throws Exception {
- Charset c1 = Charset.forName("iso8859-1");
- ByteBuffer bb = c1.encode("abcd\u5D14efg");
- assertEquals(new String(bb.array(), "iso8859-1"),
- "abcd" + new String(c1.newEncoder().replacement(), "iso8859-1") + "efg");
- }
-
- public void testEncode_String_NullString() {
- MockCharset c = new MockCharset("mock", null);
- try {
- c.encode((String) null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testEncode_String_NullEncoder() {
- MockCharset2 c = new MockCharset2("mock2", null);
- try {
- c.encode("hehe");
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testDecode_Normal() throws Exception {
- MockCharset c1 = new MockCharset("mock", null);
- CharBuffer cb = c1.decode(ByteBuffer.wrap("abcdefg".getBytes("iso8859-1")));
- assertEquals("abcdefg", new String(cb.array()));
- cb = c1.decode(ByteBuffer.wrap("".getBytes("iso8859-1")));
- assertEquals("", new String(cb.array()));
- }
-
- public void testDecode_Malformed() throws Exception {
- Charset c1 = Charset.forName("iso8859-1");
- CharBuffer cb = c1.decode(ByteBuffer.wrap("abcd\u5D14efg".getBytes("iso8859-1")));
- byte[] replacement = c1.newEncoder().replacement();
- assertEquals(new String(cb.array()).trim(), "abcd" + new String(replacement, "iso8859-1") + "efg");
- }
-
- public void testDecode_NullByteBuffer() {
- MockCharset c = new MockCharset("mock", null);
- try {
- c.decode(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testDecode_NullDecoder() {
- MockCharset2 c = new MockCharset2("mock2", null);
- try {
- c.decode(ByteBuffer.wrap("hehe".getBytes()));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testToString() {
- MockCharset c1 = new MockCharset("mock", null);
- assertTrue(-1 != c1.toString().indexOf("mock"));
- }
-
- static final class MockCharset extends Charset {
- public MockCharset(String canonicalName, String[] aliases) {
- super(canonicalName, aliases);
- }
-
- public boolean contains(Charset cs) {
- return false;
- }
-
- public CharsetDecoder newDecoder() {
- return new MockDecoder(this);
- }
-
- public CharsetEncoder newEncoder() {
- return new MockEncoder(this);
- }
- }
-
- static class MockCharset2 extends Charset {
- public MockCharset2(String canonicalName, String[] aliases) {
- super(canonicalName, aliases);
- }
-
- public boolean contains(Charset cs) {
- return false;
- }
-
- public CharsetDecoder newDecoder() {
- return null;
- }
-
- public CharsetEncoder newEncoder() {
- return null;
- }
- }
-
- static class MockEncoder extends java.nio.charset.CharsetEncoder {
- public MockEncoder(Charset cs) {
- super(cs, 1, 3, new byte[] { (byte) '?' });
- }
-
- protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
- while (in.remaining() > 0) {
- out.put((byte) in.get());
- // out.put((byte) '!');
- }
- return CoderResult.UNDERFLOW;
- }
- }
-
- static class MockDecoder extends java.nio.charset.CharsetDecoder {
- public MockDecoder(Charset cs) {
- super(cs, 1, 10);
- }
-
- protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
- while (in.remaining() > 0) {
- out.put((char) in.get());
- }
- return CoderResult.UNDERFLOW;
- }
- }
-
-
- // Test the method isSupported(String) with charset supported by multiple providers.
- public void testIsSupported_And_ForName_NormalProvider() throws Exception {
- assertTrue(Charset.isSupported("mockCharset10"));
- // ignore case problem in mock, intended
- assertTrue(Charset.isSupported("MockCharset11"));
- assertTrue(Charset.isSupported("MockCharset12"));
- assertTrue(Charset.isSupported("MOCKCharset10"));
- // intended case problem in mock
- assertTrue(Charset.isSupported("MOCKCharset11"));
- assertTrue(Charset.isSupported("MOCKCharset12"));
-
- assertTrue(Charset.forName("mockCharset10") instanceof MockCharset);
- assertTrue(Charset.forName("mockCharset11") instanceof MockCharset);
- assertTrue(Charset.forName("mockCharset12") instanceof MockCharset);
-
- assertTrue(Charset.forName("mockCharset10") == charset2);
- // intended case problem in mock
- Charset.forName("mockCharset11");
- assertTrue(Charset.forName("mockCharset12") == charset2);
- }
-
- // Test the method availableCharsets() with charset supported by multiple providers.
- public void testAvailableCharsets_NormalProvider() throws Exception {
- assertTrue(Charset.availableCharsets().containsKey("mockCharset00"));
- assertTrue(Charset.availableCharsets().containsKey("MOCKCharset00"));
- assertTrue(Charset.availableCharsets().get("mockCharset00") instanceof MockCharset);
- assertTrue(Charset.availableCharsets().get("MOCKCharset00") instanceof MockCharset);
- assertFalse(Charset.availableCharsets().containsKey("mockCharset01"));
- assertFalse(Charset.availableCharsets().containsKey("mockCharset02"));
-
- assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
- assertTrue(Charset.availableCharsets().get("MOCKCharset10") == charset2);
- assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
- assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
-
- assertTrue(Charset.availableCharsets().containsKey("mockCharset10"));
- assertTrue(Charset.availableCharsets().containsKey("MOCKCharset10"));
- assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
- assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
- assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
- }
-
- // Test the method forName(String) when the charset provider supports a
- // built-in charset.
- public void testForName_DuplicateWithBuiltInCharset() throws Exception {
- assertFalse(Charset.forName("us-ascii") instanceof MockCharset);
- assertFalse(Charset.availableCharsets().get("us-ascii") instanceof MockCharset);
- }
-
- public static class MockCharsetProvider extends CharsetProvider {
- public Charset charsetForName(String charsetName) {
- if ("MockCharset00".equalsIgnoreCase(charsetName) ||
- "MockCharset01".equalsIgnoreCase(charsetName) ||
- "MockCharset02".equalsIgnoreCase(charsetName)) {
- return charset1;
- } else if ("MockCharset10".equalsIgnoreCase(charsetName) ||
- "MockCharset11".equalsIgnoreCase(charsetName) ||
- "MockCharset12".equalsIgnoreCase(charsetName)) {
- return charset2;
- }
- return null;
- }
-
- public Iterator charsets() {
- Vector v = new Vector();
- v.add(charset1);
- v.add(charset2);
- return v.iterator();
- }
- }
-
- // Another mock charset provider attempting to provide the built-in charset "ascii" again.
- public static class MockCharsetProviderASCII extends CharsetProvider {
- public Charset charsetForName(String charsetName) {
- if ("US-ASCII".equalsIgnoreCase(charsetName) || "ASCII".equalsIgnoreCase(charsetName)) {
- return new MockCharset("US-ASCII", new String[] { "ASCII" });
- }
- return null;
- }
-
- public Iterator charsets() {
- Vector v = new Vector();
- v.add(new MockCharset("US-ASCII", new String[] { "ASCII" }));
- return v.iterator();
- }
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/CoderResultTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/CoderResultTest.java
deleted file mode 100644
index 469fc98..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/CoderResultTest.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.charset.CoderResult;
-import java.nio.charset.MalformedInputException;
-import java.nio.charset.UnmappableCharacterException;
-
-import junit.framework.TestCase;
-
-/**
- * Test class java.nio.charset.CoderResult.
- */
-public class CoderResultTest extends TestCase {
-
- /*
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- /*
- * Test the constant OVERFLOW and UNDERFLOW.
- */
- public void testConstants() throws Exception {
- assertNotSame(CoderResult.OVERFLOW, CoderResult.UNDERFLOW);
-
- assertNotNull(CoderResult.OVERFLOW);
- assertFalse(CoderResult.OVERFLOW.isError());
- assertFalse(CoderResult.OVERFLOW.isMalformed());
- assertFalse(CoderResult.OVERFLOW.isUnderflow());
- assertFalse(CoderResult.OVERFLOW.isUnmappable());
- assertTrue(CoderResult.OVERFLOW.isOverflow());
- assertTrue(CoderResult.OVERFLOW.toString().indexOf("OVERFLOW") != -1);
- try {
- CoderResult.OVERFLOW.throwException();
- fail("Should throw BufferOverflowException");
- } catch (BufferOverflowException ex) {
- // expected
- }
- try {
- CoderResult.OVERFLOW.length();
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException ex) {
- // expected
- }
-
- assertNotNull(CoderResult.UNDERFLOW);
- assertFalse(CoderResult.UNDERFLOW.isError());
- assertFalse(CoderResult.UNDERFLOW.isMalformed());
- assertTrue(CoderResult.UNDERFLOW.isUnderflow());
- assertFalse(CoderResult.UNDERFLOW.isUnmappable());
- assertFalse(CoderResult.UNDERFLOW.isOverflow());
- assertTrue(CoderResult.UNDERFLOW.toString().indexOf("UNDERFLOW") != -1);
- try {
- CoderResult.UNDERFLOW.throwException();
- fail("Should throw BufferOverflowException");
- } catch (BufferUnderflowException ex) {
- // expected
- }
- try {
- CoderResult.UNDERFLOW.length();
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException ex) {
- // expected
- }
- }
-
- /**
- * Test method isError().
- *
- */
- public void testIsError() {
- assertFalse(CoderResult.UNDERFLOW.isError());
- assertFalse(CoderResult.OVERFLOW.isError());
- assertTrue(CoderResult.malformedForLength(1).isError());
- assertTrue(CoderResult.unmappableForLength(1).isError());
- }
-
- /**
- * Test method isMalformed().
- *
- */
- public void testIsMalformed() {
- assertFalse(CoderResult.UNDERFLOW.isMalformed());
- assertFalse(CoderResult.OVERFLOW.isMalformed());
- assertTrue(CoderResult.malformedForLength(1).isMalformed());
- assertFalse(CoderResult.unmappableForLength(1).isMalformed());
- }
-
- /**
- * Test method isMalformed().
- *
- */
- public void testIsUnmappable() {
- assertFalse(CoderResult.UNDERFLOW.isUnmappable());
- assertFalse(CoderResult.OVERFLOW.isUnmappable());
- assertFalse(CoderResult.malformedForLength(1).isUnmappable());
- assertTrue(CoderResult.unmappableForLength(1).isUnmappable());
- }
-
- /**
- * Test method isOverflow().
- *
- */
- public void testIsOverflow() {
- assertFalse(CoderResult.UNDERFLOW.isOverflow());
- assertTrue(CoderResult.OVERFLOW.isOverflow());
- assertFalse(CoderResult.malformedForLength(1).isOverflow());
- assertFalse(CoderResult.unmappableForLength(1).isOverflow());
- }
-
- /**
- * Test method isUnderflow().
- *
- */
- public void testIsUnderflow() {
- assertTrue(CoderResult.UNDERFLOW.isUnderflow());
- assertFalse(CoderResult.OVERFLOW.isUnderflow());
- assertFalse(CoderResult.malformedForLength(1).isUnderflow());
- assertFalse(CoderResult.unmappableForLength(1).isUnderflow());
- }
-
- /**
- * Test method length().
- *
- */
- public void testLength() {
- try {
- CoderResult.UNDERFLOW.length();
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException ex) {
- // expected
- }
- try {
- CoderResult.OVERFLOW.length();
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException ex) {
- // expected
- }
-
- assertEquals(CoderResult.malformedForLength(1).length(), 1);
- assertEquals(CoderResult.unmappableForLength(1).length(), 1);
- }
-
- /**
- * Test method malformedForLength(int).
- *
- */
- public void testMalformedForLength() {
- assertNotNull(CoderResult.malformedForLength(Integer.MAX_VALUE));
- assertNotNull(CoderResult.malformedForLength(1));
- assertSame(CoderResult.malformedForLength(1), CoderResult
- .malformedForLength(1));
- assertNotSame(CoderResult.malformedForLength(1), CoderResult
- .unmappableForLength(1));
- assertNotSame(CoderResult.malformedForLength(2), CoderResult
- .malformedForLength(1));
- try {
- CoderResult.malformedForLength(-1);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- try {
- CoderResult.malformedForLength(0);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- }
-
- /**
- * Test method unmappableForLength(int).
- *
- */
- public void testUnmappableForLength() {
- assertNotNull(CoderResult.unmappableForLength(Integer.MAX_VALUE));
- assertNotNull(CoderResult.unmappableForLength(1));
- assertSame(CoderResult.unmappableForLength(1), CoderResult
- .unmappableForLength(1));
- assertNotSame(CoderResult.unmappableForLength(2), CoderResult
- .unmappableForLength(1));
- try {
- CoderResult.unmappableForLength(-1);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- try {
- CoderResult.unmappableForLength(0);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- }
-
- /**
- * Test method throwException().
- *
- */
- public void testThrowException() throws Exception {
- try {
- CoderResult.OVERFLOW.throwException();
- fail("Should throw BufferOverflowException");
- } catch (BufferOverflowException ex) {
- // expected
- }
- try {
- CoderResult.UNDERFLOW.throwException();
- fail("Should throw BufferOverflowException");
- } catch (BufferUnderflowException ex) {
- // expected
- }
- try {
- CoderResult.malformedForLength(1).throwException();
- fail("Should throw MalformedInputException");
- } catch (MalformedInputException ex) {
- assertEquals(ex.getInputLength(), 1);
- }
- try {
- CoderResult.unmappableForLength(1).throwException();
- fail("Should throw UnmappableCharacterException");
- } catch (UnmappableCharacterException ex) {
- assertEquals(ex.getInputLength(), 1);
- }
- }
-
- /**
- * Test method toString().
- *
- */
- public void testToString() throws Exception {
- assertTrue(CoderResult.OVERFLOW.toString().indexOf("OVERFLOW") != -1);
- assertTrue(CoderResult.UNDERFLOW.toString().indexOf("UNDERFLOW") != -1);
- assertTrue(CoderResult.malformedForLength(666).toString()
- .indexOf("666") != -1);
- assertTrue(CoderResult.unmappableForLength(666).toString().indexOf(
- "666") != -1);
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/CodingErrorActionTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/CodingErrorActionTest.java
deleted file mode 100644
index da293bb..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/CodingErrorActionTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.charset.CodingErrorAction;
-
-import junit.framework.TestCase;
-
-/**
- * Test class java.nio.charset.CodingErrorAction
- */
-public class CodingErrorActionTest extends TestCase {
-
- /*
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- /*
- * @see TestCase#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- /*
- * Test the constants.
- */
- public void testIGNORE() {
- assertNotNull(CodingErrorAction.IGNORE);
- assertNotNull(CodingErrorAction.REPLACE);
- assertNotNull(CodingErrorAction.REPORT);
- assertNotSame(CodingErrorAction.IGNORE, CodingErrorAction.REPLACE);
- assertNotSame(CodingErrorAction.IGNORE, CodingErrorAction.REPORT);
- assertNotSame(CodingErrorAction.REPLACE, CodingErrorAction.REPORT);
- }
-
- /*
- * Test the method toString().
- */
- public void testToString() {
- assertTrue(CodingErrorAction.IGNORE.toString().indexOf("IGNORE") != -1);
- assertTrue(CodingErrorAction.REPLACE.toString().indexOf("REPLACE") != -1);
- assertTrue(CodingErrorAction.REPORT.toString().indexOf("REPORT") != -1);
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetDecoderTest.java
deleted file mode 100644
index e129c54..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetDecoderTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * test gb18030 decoder
- */
-public class GBCharsetDecoderTest extends CharsetDecoderTest {
-
- protected void setUp() throws Exception {
- cs = Charset.forName("gb18030");
- super.setUp();
- }
-
- /*
- * @see CharsetDecoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- // // FIXME: give up this tests
- // public void testDefaultCharsPerByte(){
- // //assertEquals(1, decoder.averageCharsPerByte());
- // //assertEquals(1, decoder.maxCharsPerByte());
- // assertEquals(decoder.averageCharsPerByte(), 0.25, 0.001);
- // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
- // }
-
- ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
- return null;
- }
-
- ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
- ByteBuffer buffer = ByteBuffer.allocate(20);
- buffer.put(new byte[] { (byte) 0xd8 });
- buffer.put(getByteBuffer());
- buffer.flip();
- return buffer;
- }
-
- ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
- return null;
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetEncoderTest.java
deleted file mode 100644
index ab4eeea..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/GBCharsetEncoderTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-
-/**
- * test case specific activity of gb18030 charset encoder
- */
-public class GBCharsetEncoderTest extends CharsetEncoderTest {
-
- // charset for gb180303
- private static final Charset CS = Charset.forName("gb18030");
-
- /*
- * @see CharsetEncoderTest#setUp()
- */
- protected void setUp() throws Exception {
- cs = CS;
- specifiedReplacement = new byte[] { 0x1a };
- super.setUp();
- }
-
- /*
- * @see CharsetEncoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testCanEncodechar() {
- // normal case for utfCS
- assertTrue(encoder.canEncode('\u0077'));
- assertTrue(encoder.canEncode('\uc2a3'));
-
- // for non-mapped char
- assertTrue(encoder.canEncode('\uc2c0'));
- }
-
- /*
- * Class under test for boolean canEncode(CharSequence)
- */
- public void testCanEncodeCharSequence() {
- // surrogate char
-
- // valid surrogate pair
- assertTrue(encoder.canEncode("\ud800\udc00"));
- // invalid surrogate pair
- assertFalse(encoder.canEncode("\ud800\udb00"));
- }
-
- public void testSpecificDefaultValue() {
- assertEquals(4.0, encoder.maxBytesPerChar(), 0.0);
- assertEquals(2.5, encoder.averageBytesPerChar(), 0.0);
- }
-
- CharBuffer getMalformedCharBuffer() {
- return CharBuffer.wrap("\ud800 buffer");
- }
-
- CharBuffer getUnmapCharBuffer() {
- return null;
- }
-
- CharBuffer getExceptionCharBuffer() {
- return null;
- }
-
- protected byte[] getIllegalByteArray() {
- return new byte[] { (byte) 0xd8, (byte) 0x00 };
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetDecoderTest.java
deleted file mode 100644
index 82ba9b3..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetDecoderTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * test ISO-8859-1 decoder
- */
-public class ISOCharsetDecoderTest extends CharsetDecoderTest {
-
- protected void setUp() throws Exception {
- cs = Charset.forName("iso-8859-1");
- super.setUp();
- }
-
- /*
- * @see CharsetDecoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- // FIXME: give up this tests
- // public void testDefaultCharsPerByte(){
- // assertEquals(1, decoder.averageCharsPerByte());
- // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
- // }
-
- ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
- // TODO how on map?
- return null;
-
- }
-
- ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
- // TODO how malform
- return null;
- }
-
- ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
- return null;
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetEncoderTest.java
deleted file mode 100644
index 8a84938..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetEncoderTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.nio.charset;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.MalformedInputException;
-import java.nio.charset.UnmappableCharacterException;
-
-/**
- * test case specific activity of iso-8859-1 charset encoder
- */
-public class ISOCharsetEncoderTest extends CharsetEncoderTest {
-
- // charset for iso-8859-1
- private static final Charset CS = Charset.forName("iso-8859-1");
-
- /*
- * @see CharsetEncoderTest#setUp()
- */
- protected void setUp() throws Exception {
- cs = CS;
- super.setUp();
- }
-
- /*
- * @see CharsetEncoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Override public void testCanEncodeCharSequence() {
- // normal case for isoCS
- assertTrue(encoder.canEncode("\u0077"));
- assertFalse(encoder.canEncode("\uc2a3"));
- assertFalse(encoder.canEncode("\ud800\udc00"));
- }
-
- @Override public void testCanEncodechar() throws CharacterCodingException {
- assertTrue(encoder.canEncode('\u0077'));
- assertFalse(encoder.canEncode('\uc2a3'));
- }
-
- @Override public void testSpecificDefaultValue() {
- assertEquals(1, encoder.averageBytesPerChar(), 0.001);
- assertEquals(1, encoder.maxBytesPerChar(), 0.001);
- }
-
- CharBuffer getMalformedCharBuffer() {
- return CharBuffer.wrap("\ud800 buffer");
- }
-
- CharBuffer getUnmapCharBuffer() {
- return CharBuffer.wrap("\ud800\udc00 buffer");
- }
-
- CharBuffer getExceptionCharBuffer() {
- return null;
- }
-
- protected byte[] getIllegalByteArray() {
- return null;
- }
-
- public void testMultiStepEncode() throws CharacterCodingException {
- encoder.onMalformedInput(CodingErrorAction.REPORT);
- encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- try {
- encoder.encode(CharBuffer.wrap("\ud800\udc00"));
- fail("should unmappable");
- } catch (UnmappableCharacterException e) {
- }
- encoder.reset();
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetTest.java
deleted file mode 100644
index 689dbf3..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/ISOCharsetTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-/**
- * Test ISO-8859-1.
- */
-public class ISOCharsetTest extends AbstractCharsetTestCase {
-
- /**
- * Constructor.
- */
- public ISOCharsetTest(String arg0) {
- super(arg0, "ISO-8859-1", new String[] { "iso-ir-100", "8859_1",
- "ISO_8859-1", "ISO8859_1", "819", "csISOLatin1", "IBM-819",
- "ISO_8859-1:1987", "latin1", "cp819", "ISO8859-1", "IBM819",
- "ISO_8859_1", "l1" }, true, true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
- */
- public void testEncode_Normal() {
- String input = "ab\u5D14\u654F";
- byte[] output = new byte[] { 97, 98,
- this.testingCharset.newEncoder().replacement()[0],
- this.testingCharset.newEncoder().replacement()[0] };
- internalTestEncode(input, output);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
- */
- public void testDecode_Normal() {
- byte[] input = new byte[] { 97, 98, 63, 63 };
- char[] output = "ab??".toCharArray();
- internalTestDecode(input, output);
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetDecoderTest.java
deleted file mode 100644
index a8e1343..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetDecoderTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- *
- */
-public class UTF16BECharsetDecoderTest extends CharsetDecoderTest {
-
- protected void setUp() throws Exception {
- cs = Charset.forName("utf-16be");
- super.setUp();
- }
-
- /*
- * @see CharsetDecoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- // FIXME: give up this tests
- // public void testDefaultCharsPerByte() {
- // // assertEquals(1, decoder.averageCharsPerByte());
- // // assertEquals(1, decoder.maxCharsPerByte());
- // assertEquals(decoder.averageCharsPerByte(), 0.5, 0.001);
- // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
- // }
-
- ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
- // no unmap byte buffer
- return null;
- }
-
- ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
- // FIXME: different here, RI can parse 0xd8d8
- // ByteBuffer buffer = ByteBuffer.allocate(100);
- // buffer.put((byte)0xd8);
- // buffer.put((byte)0xd8);
- // buffer.put(unibytes);
- // buffer.flip();
- // return buffer;
- return null;
- }
-
- ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
- return null;
- }
-
- protected ByteBuffer getByteBuffer() {
- return ByteBuffer.wrap(new byte[] { 0, 32, 0, 98, 0, 117, 0, 102, 0,
- 102, 0, 101, 0, 114 });
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetEncoderTest.java
deleted file mode 100644
index 68bd2f5..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetEncoderTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-
-/**
- * TODO type def
- */
-public class UTF16BECharsetEncoderTest extends CharsetEncoderTest {
-
- // charset for utf-16be
- private static final Charset CS = Charset.forName("utf-16be");
-
- /*
- * @see CharsetEncoderTest#setUp()
- */
- protected void setUp() throws Exception {
- cs = CS;
- specifiedReplacement = new byte[] { -1, -3 };
- unibytes = new byte[] { 0, 32, 0, 98, 0, 117, 0, 102, 0, 102, 0, 101,
- 0, 114 };
-
- // unibytesWithRep = new byte[] {(byte)0xff, (byte)0xfd,0, 32, 0, 98, 0,
- // 117, 0, 102, 0, 102, 0, 101, 0, 114};
-
- super.setUp();
- }
-
- /*
- * @see CharsetEncoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testCharsetEncoderCharsetfloatfloat() {
- // this constructor is invalid for UTF16LE CharsetEncoder
- }
-
- public void testCanEncodechar() throws CharacterCodingException {
- // normal case for utfCS
- assertTrue(encoder.canEncode('\u0077'));
- assertTrue(encoder.canEncode('\uc2a3'));
-
- // for non-mapped char
- assertTrue(encoder.canEncode('\uc2c0'));
-
- }
-
- public void testCanEncodeCharSequence() {
- // normal case for utfCS
- assertTrue(encoder.canEncode("\u0077"));
- assertTrue(encoder.canEncode("\uc2a3"));
-
- // for non-mapped char
- assertTrue(encoder.canEncode("\uc2c0"));
-
- // surrogate char for unicode
- // 1st byte: d800-dbff
- // 2nd byte: dc00-dfff
- // valid surrogate pair
- assertTrue(encoder.canEncode("\ud800\udc00"));
- // invalid surrogate pair
- assertFalse(encoder.canEncode("\ud800\udb00"));
- }
-
- public void testSpecificDefaultValue() {
- assertEquals(2, encoder.averageBytesPerChar(), 0.001);
- assertEquals(2, encoder.maxBytesPerChar(), 0.001);
- }
-
- CharBuffer getMalformedCharBuffer() {
- return CharBuffer.wrap("\ud800 buffer");
- }
-
- CharBuffer getUnmapCharBuffer() {
- return null;
- }
-
- CharBuffer getExceptionCharBuffer() {
- return null;
- }
-
- protected byte[] getIllegalByteArray() {
- return new byte[] { (byte)0xd8, (byte)0x00, (byte)0xdb, (byte)0x00 };
- }
-
- protected byte[] getLegalByteArray() {
- return new byte[] { (byte) 0x00, (byte) 0xd8 };
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetTest.java
deleted file mode 100644
index 52cee90..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16BECharsetTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-/**
- * Test UTF-16BE.
- */
-public class UTF16BECharsetTest extends AbstractCharsetTestCase {
-
- /**
- * Constructor.
- */
- public UTF16BECharsetTest(String arg0) {
- super(arg0, "UTF-16BE", new String[] { "X-UTF-16BE", "UTF_16BE" },
- true, true); // "ISO-10646-UCS-2"
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
- */
- public void testEncode_Normal() {
- String input = "ab\u5D14\u654F";
- byte[] output = new byte[] { 0, 97, 0, 98, 93, 20, 101, 79 };
- internalTestEncode(input, output);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
- */
- public void testDecode_Normal() {
- byte[] input = new byte[] { 0, 97, 0, 98, 93, 20, 101, 79 };
- char[] output = "ab\u5D14\u654F".toCharArray();
- internalTestDecode(input, output);
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetDecoderTest.java
deleted file mode 100644
index c5bb408..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetDecoderTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-
-/**
- *
- */
-public class UTF16CharsetDecoderTest extends CharsetDecoderTest {
-
- boolean bigEndian = true;
-
- protected void setUp() throws Exception {
- cs = Charset.forName("utf-16");
- bom = "\ufeff";
- super.setUp();
- }
-
- /*
- * @see CharsetDecoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- protected ByteBuffer getByteBuffer() {
- // FIXME: different here
- // if don't specified BOM
- // ICU default is LE
- // JDK default is BE
-
- // maybe start with 0xFEFF, which means big endian
- // 0xFFFE, which means little endian
- byte[] b = (bigEndian) ? new byte[] { -1, -2, 32, 0, 98, 0, 117, 0,
- 102, 0, 102, 0, 101, 0, 114, 0 } : new byte[] { -2, -1, 0, 32,
- 0, 98, 0, 117, 0, 102, 0, 102, 0, 101, 0, 114 };
- return ByteBuffer.wrap(b);
- }
-
- protected ByteBuffer getHeadlessByteBuffer() {
- ByteBuffer b = getByteBuffer();
- b.position(2);
- byte[] bytes = new byte[b.remaining()];
- b.get(bytes);
- return ByteBuffer.wrap(bytes);
- }
-
- public void testLittleEndianByteBufferCharBuffer()
- throws CharacterCodingException, UnsupportedEncodingException {
- bigEndian = false;
- implTestDecodeByteBufferCharBuffer(getByteBuffer());
- bigEndian = true;
- }
-
- public void testLittleEndianReadOnlyByteBufferCharBuffer()
- throws CharacterCodingException, UnsupportedEncodingException {
- bigEndian = false;
- implTestDecodeByteBufferCharBuffer(getByteBuffer().asReadOnlyBuffer());
- bigEndian = true;
- }
-
- public void testLittleEndian() throws CharacterCodingException,
- UnsupportedEncodingException {
- bigEndian = false;
- implTestDecodeByteBuffer();
- bigEndian = true;
- }
-
- // FIXME: give up this tests
- // public void testDefaultCharsPerByte() {
- // // assertEquals(1, decoder.averageCharsPerByte());
- // // assertEquals(1, decoder.maxCharsPerByte());
- // assertEquals(decoder.averageCharsPerByte(), 0.5, 0.001);
- // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
- // }
-
- ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
- return null;
- }
-
- ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
- return null;
- // FIXME: different here, RI can parse 0xd8d8
- // ByteBuffer buffer = ByteBuffer.allocate(100);
- // buffer.put((byte) -1);
- // buffer.put((byte) -2);
- // buffer.put((byte) 0xdc);
- // buffer.put((byte) 0xdc);
- // buffer.put(unibytes);
- // buffer.flip();
- // return buffer;
- }
-
- ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
- return null;
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetEncoderTest.java
deleted file mode 100644
index 6a42d41..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetEncoderTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-
-/**
- * TODO type def
- */
-public class UTF16CharsetEncoderTest extends CharsetEncoderTest {
-
- // charset for utf-16
- // charset for utf-16be
- private static final Charset CS = Charset.forName("utf-16");
-
- private static final CharsetDecoder decoder = CS.newDecoder();
-
- /*
- * @see CharsetEncoderTest#setUp()
- */
- protected void setUp() throws Exception {
- cs = CS;
- specifiedReplacement = new byte[] { -3, -1 };
- surrogate = new byte[] { -1, -2 };
- unibytes = new byte[] { 32, 0, 98, 0, 117, 0, 102, 0, 102, 0, 101, 0,
- 114, 0 };
- unibytesWithRep = new byte[] { -3, -1, 32, 0, 98, 0, 117, 0, 102, 0,
- 102, 0, 101, 0, 114, 0 };
- super.setUp();
- }
-
- /*
- * @see CharsetEncoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testCharsetEncoderCharsetfloatfloat() {
- // this constructor is invalid for UTF16LE CharsetEncoder
- }
-
- public void testCanEncodechar() throws CharacterCodingException {
- // normal case for utfCS
- assertTrue(encoder.canEncode('\u0077'));
- assertTrue(encoder.canEncode('\uc2a3'));
-
- // for non-mapped char
- assertTrue(encoder.canEncode('\uc2c0'));
- }
-
- public void testCanEncodeCharSequence() {
- // normal case for utfCS
- assertTrue(encoder.canEncode("\u0077"));
- assertTrue(encoder.canEncode("\uc2a3"));
-
- // for non-mapped char
- assertTrue(encoder.canEncode("\uc2c0"));
-
- // surrogate char for unicode
- // 1st byte: d800-dbff
- // 2nd byte: dc00-dfff
- // valid surrogate pair
- assertTrue(encoder.canEncode("\ud800\udc00"));
- // invalid surrogate pair
- assertFalse(encoder.canEncode("\ud800\udb00"));
- }
-
- public void testSpecificDefaultValue() {
- assertEquals(encoder.averageBytesPerChar(), 2, 0.001);
- // assertEquals(4, encoder.maxBytesPerChar());
- // FIXME: different here!
- assertEquals(encoder.maxBytesPerChar(), 2, 0.001);
- }
-
- CharBuffer getMalformedCharBuffer() {
- return CharBuffer.wrap("\ud800 buffer");
- }
-
- CharBuffer getUnmapCharBuffer() {
- return null;
- }
-
- CharBuffer getExceptionCharBuffer() {
- return null;
- }
-
- protected byte[] getIllegalByteArray() {
- return new byte[] { (byte)0xd8, (byte)0x00, (byte)0xdb, (byte)0x00 };
- }
-
- protected byte[] getLegalByteArray() {
- // FIXME: Different Here!
- // return new byte[]{(byte)0xd8, 0x00};
- return new byte[] { (byte) 0x00, (byte) 0xd8 };
- }
-
- void assertByteArray(ByteBuffer out, byte[] expected) {
- out = out.duplicate();
- if (out.position() > 0) {
- out.flip();
- }
- try {
- assertEquals(decoder.decode(out), decoder.decode(ByteBuffer
- .wrap(expected)));
- } catch (CharacterCodingException e) {
- fail(e.toString());
- }
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetTest.java
deleted file mode 100644
index 61dcf49..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16CharsetTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-/**
- * Test UTF-16.
- */
-public class UTF16CharsetTest extends AbstractCharsetTestCase {
-
- /**
- * Constructor.
- */
- public UTF16CharsetTest(String arg0) {
- super(arg0, "UTF-16", new String[] { "UTF_16" }, true, true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
- */
- public void testEncode_Normal() {
- // TODO Auto-generated method stub
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
- */
- public void testDecode_Normal() {
- // TODO Auto-generated method stub
-
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetDecoderTest.java
deleted file mode 100644
index e9a8e56..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetDecoderTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * TODO typedef
- */
-public class UTF16LECharsetDecoderTest extends CharsetDecoderTest {
-
- protected void setUp() throws Exception {
- cs = Charset.forName("utf-16le");
- super.setUp();
- }
-
- /*
- * @see CharsetDecoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- // // FIXME: give up this tests
- // public void testDefaultCharsPerByte(){
- // // assertEquals(1, decoder.averageCharsPerByte());
- // // assertEquals(1, decoder.maxCharsPerByte());
- // assertEquals(decoder.averageCharsPerByte(), 0.5, 0.001);
- // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
- // }
-
- ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
- // no unmap byte buffer
- return null;
- }
-
- ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
- // FIXME: different here, JDK can parse 0xd8d8
- // ByteBuffer buffer = ByteBuffer.allocate(100);
- // buffer.put((byte)0xd8);
- // buffer.put((byte)0xd8);
- // buffer.put(unibytes);
- // buffer.flip();
- // return buffer;
- return null;
- }
-
- ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
- return null;
- }
-
- protected ByteBuffer getByteBuffer() {
- return ByteBuffer.wrap(new byte[] { 32, 0, 98, 0, 117, 0, 102, 0, 102,
- 0, 101, 0, 114, 0 });
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetEncoderTest.java
deleted file mode 100644
index 1e9187d..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetEncoderTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-
-/**
- * TODO type def
- */
-public class UTF16LECharsetEncoderTest extends CharsetEncoderTest {
-
- // charset for utf-16le
- private static final Charset CS = Charset.forName("utf-16le");
-
- /*
- * @see CharsetEncoderTest#setUp()
- */
- protected void setUp() throws Exception {
- cs = CS;
- specifiedReplacement = new byte[] { -3, -1 };
-
- unibytes = new byte[] { 32, 0, 98, 0, 117, 0, 102, 0, 102, 0, 101, 0,
- 114, 0 };
-
- // unibytesWithRep = new byte[] {(byte)0xfd, (byte)0xff, 32, 0, 98, 0,
- // 117, 0, 102, 0, 102, 0, 101, 0, 114 ,0};
-
- super.setUp();
- }
-
- /*
- * @see CharsetEncoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testCharsetEncoderCharsetfloatfloat() {
- // this constructor is invalid for UTF16LE CharsetEncoder
- }
-
- public void testCanEncodechar() throws CharacterCodingException {
- // normal case for utfCS
- assertTrue(encoder.canEncode('\u0077'));
- assertTrue(encoder.canEncode('\uc2a3'));
-
- // for non-mapped char
- assertTrue(encoder.canEncode('\uc2c0'));
- }
-
- public void testCanEncodeCharSequence() {
- // normal case for utfCS
- assertTrue(encoder.canEncode("\u0077"));
- assertTrue(encoder.canEncode("\uc2a3"));
-
- // for non-mapped char
- assertTrue(encoder.canEncode("\uc2c0"));
-
- // surrogate char for unicode
- // 1st byte: d800-dbff
- // 2nd byte: dc00-dfff
- // valid surrogate pair
- assertTrue(encoder.canEncode("\ud800\udc00"));
- // invalid surrogate pair
- assertFalse(encoder.canEncode("\ud800\udb00"));
- }
-
- public void testSpecificDefaultValue() {
- assertEquals(2, encoder.averageBytesPerChar(), 0.001);
- assertEquals(2, encoder.maxBytesPerChar(), 0.001);
- }
-
- CharBuffer getMalformedCharBuffer() {
- return CharBuffer.wrap("\ud800 buffer");
- }
-
- CharBuffer getUnmapCharBuffer() {
- return null;
- }
-
- CharBuffer getExceptionCharBuffer() {
- return null;
- }
-
- protected byte[] getIllegalByteArray() {
- return new byte[] { (byte)0x00, (byte)0xd8, (byte)0x00, (byte)0xdb };
- }
-
- protected byte[] getLegalByteArray() {
- return new byte[] { (byte) 0xd8, 0x00 };
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetTest.java
deleted file mode 100644
index d795773..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF16LECharsetTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-/**
- * Test UTF-16LE.
- */
-public class UTF16LECharsetTest extends AbstractCharsetTestCase {
-
- /**
- * Constructor.
- */
- public UTF16LECharsetTest(String arg0) {
- super(arg0, "UTF-16LE", new String[] { "UTF_16LE", "X-UTF-16LE" },
- true, true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
- */
- public void testEncode_Normal() {
- String input = "ab\u5D14\u654F";
- byte[] output = new byte[] { 97, 0, 98, 0, 20, 93, 79, 101 };
- internalTestEncode(input, output);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
- */
- public void testDecode_Normal() {
- byte[] input = new byte[] { 97, 0, 98, 0, 20, 93, 79, 101 };
- char[] output = "ab\u5D14\u654F".toCharArray();
- internalTestDecode(input, output);
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF8CharsetTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF8CharsetTest.java
deleted file mode 100644
index 8ab8b5c..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTF8CharsetTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-
-/**
- * Test UTF-8 charset.
- */
-public class UTF8CharsetTest extends AbstractCharsetTestCase {
-
- /**
- * Constructor for UTF8CharsetTest.
- *
- */
- public UTF8CharsetTest(String arg0) {
- super(arg0, "UTF-8", new String[] { "UTF8" }, true, true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testDecode_Normal()
- */
- public void testDecode_Normal() {
- byte[] input = new byte[] { 97, 98, -27, -76, -108, -26, -107, -113 };
- char[] output = "ab\u5D14\u654F".toCharArray();
- internalTestDecode(input, output);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see tests.api.java.nio.charset.ConcreteCharsetTest#testEncode_Normal()
- */
- public void testEncode_Normal() {
- String input = "ab\u5D14\u654F";
- byte[] output = new byte[] { 97, 98, -27, -76, -108, -26, -107, -113 };
- internalTestEncode(input, output);
- }
-
- public void test_surrogate() throws UnsupportedEncodingException {
- // U+1D11E: MUSICAL SYMBOL G CLEF
- String s = new StringBuilder().appendCodePoint(0x1D11E).toString();
- byte utf8[] = s.getBytes("UTF-8");
- assertEquals(s, new String(utf8, 0, utf8.length, "UTF-8"));
- }
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetDecoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetDecoderTest.java
deleted file mode 100644
index b8ed9fd..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetDecoderTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * test utf-8 decoder
- */
-public class UTFCharsetDecoderTest extends CharsetDecoderTest {
-
- protected void setUp() throws Exception {
- cs = Charset.forName("utf-8");
- super.setUp();
- }
-
- /*
- * @see CharsetDecoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- // FIXME: give up this tests
- // public void testDefaultCharsPerByte(){
- // assertEquals(decoder.averageCharsPerByte(), 0.333, 0.001);
- // assertEquals(decoder.maxCharsPerByte(), 2, 0.001);
- // // assertEquals(1, decoder.averageCharsPerByte());
- // // assertEquals(1, decoder.maxCharsPerByte());
- // }
-
- ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
- return null;
- }
-
- ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
- ByteBuffer buffer = ByteBuffer.allocate(getByteBuffer().remaining() + 1);
- buffer.put((byte) 0xd8);
- buffer.put(getByteBuffer());
- buffer.flip();
- return buffer;
- }
-
- ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
- return null;
- }
-
- protected String getString() {
- return " buffer \u041c\u0430\u0441\u044e\u043b\u044f \u611b";
- }
-
- protected ByteBuffer getByteBuffer() {
- return ByteBuffer.wrap(new byte[] { 32, 98, 117, 102, 102, 101, 114,
- 32, (byte) 0xd0, (byte) 0x9c, (byte) 0xd0, (byte) 0xb0,
- (byte) 0xd1, (byte) 0x81, (byte) 0xd1, (byte) 0x8e,
- (byte) 0xd0, (byte) 0xbb, (byte) 0xd1, (byte) 0x8f, 32,
- (byte) 0xe6, (byte) 0x84, (byte) 0x9b });
- }
-
-}
diff --git a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetEncoderTest.java b/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetEncoderTest.java
deleted file mode 100644
index d483fcb..0000000
--- a/harmony-tests/src/test/java/tests/api/java/nio/charset/UTFCharsetEncoderTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.nio.charset;
-
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-
-/**
- * test case specific activity of utf-8 charset encoder
- */
-public class UTFCharsetEncoderTest extends CharsetEncoderTest {
-
- // charset for UTF-8
- private static final Charset CS = Charset.forName("utf-8");
-
- /*
- * @see CharsetEncoderTest#setUp()
- */
- protected void setUp() throws Exception {
- cs = CS;
- specifiedReplacement = new byte[] { 63 };
- super.setUp();
- }
-
- /*
- * @see CharsetEncoderTest#tearDown()
- */
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testCanEncodechar() throws CharacterCodingException {
- // normal case for utfCS
- assertTrue(encoder.canEncode('\u0077'));
- assertTrue(encoder.canEncode('\uc2a3'));
-
- // for non-mapped char
- assertTrue(encoder.canEncode('\uc2c0'));
- }
-
- public void testCanEncodeCharSequence() {
- // normal case for utfCS
- assertTrue(encoder.canEncode("\u0077"));
- assertTrue(encoder.canEncode("\uc2a3"));
-
- // for non-mapped char
- assertTrue(encoder.canEncode("\uc2c0"));
-
- // surrogate char for unicode
- // 1st byte: d800-dbff
- // 2nd byte: dc00-dfff
- // valid surrogate pair
- assertTrue(encoder.canEncode("\ud800\udc00"));
- // invalid surrogate pair
- assertFalse(encoder.canEncode("\ud800\udb00"));
- }
-
- public void testSpecificDefaultValue() {
- assertEquals(2, encoder.averageBytesPerChar(), 0);
- assertEquals(3, encoder.maxBytesPerChar(), 0);
- }
-
- CharBuffer getMalformedCharBuffer() {
- return CharBuffer.wrap("\ud800 buffer");
- }
-
- CharBuffer getUnmapCharBuffer() {
- return null;
- }
-
- CharBuffer getExceptionCharBuffer() {
- return null;
- }
-
- protected byte[] getIllegalByteArray() {
- return new byte[] { (byte) 0xd8, (byte) 0x00 };
- }
-
- protected void assertFlushed() {
- }
-}
diff --git a/harmony-tests/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider b/harmony-tests/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider
new file mode 100644
index 0000000..9cc124a
--- /dev/null
+++ b/harmony-tests/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider
@@ -0,0 +1,2 @@
+org.apache.harmony.tests.java.nio.charset.CharsetTest$MockCharsetProvider
+org.apache.harmony.tests.java.nio.charset.CharsetTest$MockCharsetProviderASCII
diff --git a/luni/src/test/resources/tests/api/java/lang/reflect/dex1.bytes b/harmony-tests/src/test/resources/resources/dex1.bytes
index dfff949..dfff949 100644
--- a/luni/src/test/resources/tests/api/java/lang/reflect/dex1.bytes
+++ b/harmony-tests/src/test/resources/resources/dex1.bytes
Binary files differ
diff --git a/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs-badencoding.xml b/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs-badencoding.xml
new file mode 100644
index 0000000..182edc7
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs-badencoding.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="badencoding"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
+
+<preferences EXTERNAL_XML_VERSION="1.0">
+ <root type="user">
+ <map/>
+ <node name="tests">
+ <map/>
+ <node name="api">
+ <map/>
+ <node name="java">
+ <map/>
+ <node name="util">
+ <map/>
+ <node name="prefs">
+ <map>
+ <entry key="prefskey" value="newvalue"/>
+ <entry key="prefskey3" value="newvalue3"/>
+ </map>
+ <node name="mock">
+ <map/>
+ <node name="child">
+ <map>
+ <entry key="key2" value="value2"/>
+ </map>
+ <node name="grandson">
+ <map>
+ <entry key="key3" value="value3"/>
+ </map>
+ <node name="grandgrandson">
+ <map>
+ <entry key="key4"
+ value="value4"/>
+ </map>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </root>
+</preferences>
diff --git a/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs-badform.xml b/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs-badform.xml
new file mode 100644
index 0000000..da3aeb9
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs-badform.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
+
+<preferences EXTERNAL_XML_VERSION="1.0">
+ <root type="user">
+ <map/>
+ <node name="java">
+ <map/>
+ <node name="util">
+ <map/>
+ <node name="mock">
+ <map/>
+ <node name="child">
+ <map>
+ <entry key="key2" value="value2"/>
+ </map>
+ <node name="grandson">
+ <map>
+ <entry key="key3" value="value3"/>
+ </map>
+ <node name="grandgrandson">
+ <map>
+ <entry key="key4" value="value4"/>
+ </map>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </root>
diff --git a/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs.xml b/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs.xml
new file mode 100644
index 0000000..7bee4c7
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/prefs/java/util/prefs/userprefs.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
+
+<preferences EXTERNAL_XML_VERSION="1.0">
+ <root type="user">
+ <map/>
+ <node name="org">
+ <map/>
+ <node name="apache">
+ <map/>
+ <node name="harmony">
+ <map/>
+ <node name="tests">
+ <map/>
+ <node name="java">
+ <map/>
+ <node name="util">
+ <map/>
+
+ <node name="prefs">
+ <map>
+ <entry key="prefskey"
+ value="newvalue"/>
+ <entry key="prefskey3"
+ value="newvalue3"/>
+ </map>
+
+ <node name="mock">
+ <map/>
+ <node name="child">
+ <map>
+ <entry key="key2"
+ value="value2"/>
+ </map>
+ <node name="grandson">
+ <map>
+ <entry key="key3"
+ value="value3"/>
+ </map>
+ <node name="grandgrandson">
+ <map>
+ <entry key="key4"
+ value="value4"/>
+ </map>
+ </node>
+ <!--grandgrandson-->
+ </node>
+ <!--grandson-->
+ </node>
+ <!--child-->
+ </node>
+ <!--mock-->
+
+ </node>
+ <!--prefs-->
+ </node>
+ <!--util-->
+ </node>
+ <!--java-->
+ </node>
+ <!--tests-->
+ </node>
+ <!--harmony-->
+ </node>
+ <!--apache-->
+ </node>
+ <!--org-->
+ </root>
+</preferences>
diff --git a/harmony-tests/src/test/resources/resources/test.doc b/harmony-tests/src/test/resources/resources/test.doc
new file mode 100644
index 0000000..9d88f15
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/test.doc
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* A bogus doc file used to see if we can detect
+ * file type based on its file extension.
+ */ \ No newline at end of file
diff --git a/harmony-tests/src/test/resources/resources/test.htx b/harmony-tests/src/test/resources/resources/test.htx
new file mode 100644
index 0000000..2aa810e
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/test.htx
@@ -0,0 +1,22 @@
+<html>
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* A bogus html file used to see if we can detect
+ * file type based on its file extension / content.
+ */ \ No newline at end of file
diff --git a/harmony-tests/src/test/resources/resources/test.java b/harmony-tests/src/test/resources/resources/test.java
new file mode 100644
index 0000000..3ea4660
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/test.java
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* A bogus java file used to see if we can detect
+ * file type based on its file extension.
+ */ \ No newline at end of file
diff --git a/harmony-tests/src/test/resources/resources/test.rtf b/harmony-tests/src/test/resources/resources/test.rtf
new file mode 100644
index 0000000..aa1d82d
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/test.rtf
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* A bogus RTF file used to see if we can detect
+ * file type based on its file extension.
+ */ \ No newline at end of file
diff --git a/harmony-tests/src/test/resources/resources/test.xml b/harmony-tests/src/test/resources/resources/test.xml
new file mode 100644
index 0000000..cb5c342
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/test.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- A bogus XML file used to see if we can detect
+ file type based on its file extension / content.
+--> \ No newline at end of file
diff --git a/harmony-tests/src/test/resources/resources/test_resource.txt b/harmony-tests/src/test/resources/resources/test_resource.txt
new file mode 100644
index 0000000..d5e09e2
--- /dev/null
+++ b/harmony-tests/src/test/resources/resources/test_resource.txt
@@ -0,0 +1 @@
+test_resource \ No newline at end of file
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/FileTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/FileTest.golden.ser
new file mode 100644
index 0000000..0a15a61
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/FileTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/IOErrorTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/IOErrorTest.golden.ser
new file mode 100644
index 0000000..cd0e319
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/IOErrorTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/test_array_integers.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/test_array_integers.ser
new file mode 100644
index 0000000..3c5a5e1
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/test_array_integers.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/test_array_strings.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/test_array_strings.ser
new file mode 100644
index 0000000..ee2de1c
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/test_array_strings.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/testfile b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/testfile
new file mode 100644
index 0000000..bc6c708
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/io/testfile
@@ -0,0 +1 @@
+This is a test message with Unicode character. \u4e2d\u56fd is China's name in Chinese
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/AbstractMethodErrorTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/AbstractMethodErrorTest.golden.ser
new file mode 100644
index 0000000..255e965
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/AbstractMethodErrorTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.0.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.0.ser
new file mode 100644
index 0000000..4168dd9
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.0.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.1.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.1.ser
new file mode 100644
index 0000000..992d528
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.1.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.2.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.2.ser
new file mode 100644
index 0000000..8ce26ac
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.2.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.3.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.3.ser
new file mode 100644
index 0000000..93bc905
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.golden.3.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.harmony.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.harmony.ser
new file mode 100644
index 0000000..8ce26ac
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/EnumTest.harmony.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/IllegalArgumentExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/IllegalArgumentExceptionTest.golden.ser
new file mode 100644
index 0000000..a94e8bf
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/IllegalArgumentExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/IllegalStateExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/IllegalStateExceptionTest.golden.ser
new file mode 100644
index 0000000..14b902b
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/IllegalStateExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/SecurityExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/SecurityExceptionTest.golden.ser
new file mode 100644
index 0000000..76abfd1
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/SecurityExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/StringBufferTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/StringBufferTest.golden.ser
new file mode 100644
index 0000000..861b4ab
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/StringBufferTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/StringBuilderTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/StringBuilderTest.golden.ser
new file mode 100644
index 0000000..fb54290
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/StringBuilderTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/UnsupportedOperationExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/UnsupportedOperationExceptionTest.golden.ser
new file mode 100644
index 0000000..9197188
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/lang/UnsupportedOperationExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/HttpRetryExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/HttpRetryExceptionTest.golden.ser
new file mode 100644
index 0000000..40413eb
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/HttpRetryExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet4AddressTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet4AddressTest.golden.ser
new file mode 100644
index 0000000..bc70d04
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet4AddressTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet6AddressTest.golden.0.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet6AddressTest.golden.0.ser
new file mode 100644
index 0000000..4607c20
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet6AddressTest.golden.0.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet6AddressTest.golden.1.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet6AddressTest.golden.1.ser
new file mode 100644
index 0000000..5d55693
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/Inet6AddressTest.golden.1.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetAddressTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetAddressTest.golden.ser
new file mode 100644
index 0000000..bc70d04
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetAddressTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetSocketAddressTest.golden.0.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetSocketAddressTest.golden.0.ser
new file mode 100644
index 0000000..94fe222
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetSocketAddressTest.golden.0.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetSocketAddressTest.golden.1.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetSocketAddressTest.golden.1.ser
new file mode 100644
index 0000000..1672d5f
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/InetSocketAddressTest.golden.1.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/SocketTimeoutExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/SocketTimeoutExceptionTest.golden.ser
new file mode 100644
index 0000000..a6e7680
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/net/SocketTimeoutExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/BufferOverflowExceptionTest.golden.ser
index 80e8f7c..80e8f7c 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/BufferOverflowExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/BufferUnderflowExceptionTest.golden.ser
index 2e0fc6d..2e0fc6d 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/BufferUnderflowExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/InvalidMarkExceptionTest.golden.ser
index c29debf..c29debf 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/InvalidMarkExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/ReadOnlyBufferExceptionTest.golden.ser
index fbbc876..fbbc876 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/ReadOnlyBufferExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/AlreadyConnectedExceptionTest.golden.ser
index 9bd539c..9bd539c 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/AlreadyConnectedExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/AsynchronousCloseExceptionTest.golden.ser
index 6dbac7d..6dbac7d 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/AsynchronousCloseExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/CancelledKeyExceptionTest.golden.ser
index 40288df..40288df 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/CancelledKeyExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedByInterruptExceptionTest.golden.ser
index 1f1e73b..1f1e73b 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedByInterruptExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedChannelExceptionTest.golden.ser
index ea5b80a..ea5b80a 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedChannelExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedSelectorExceptionTest.golden.ser
index 1831746..1831746 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ClosedSelectorExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ConnectionPendingExceptionTest.golden.ser
index 9e17263..9e17263 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/ConnectionPendingExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/FileLockInterruptionExceptionTest.golden.ser
index 4024191..4024191 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/FileLockInterruptionExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/IllegalBlockingModeExceptionTest.golden.ser
index c15c66b..c15c66b 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/IllegalBlockingModeExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/IllegalSelectorExceptionTest.golden.ser
index 89ed091..89ed091 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/IllegalSelectorExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NoConnectionPendingExceptionTest.golden.ser
index 022d3bc..022d3bc 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NoConnectionPendingExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NonReadableChannelExceptionTest.golden.ser
index 5cf767c..5cf767c 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NonReadableChannelExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NonWritableChannelExceptionTest.golden.ser
index 34a42e9..34a42e9 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NonWritableChannelExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NotYetBoundExceptionTest.golden.ser
index 69d1a57..69d1a57 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NotYetBoundExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NotYetConnectedExceptionTest.golden.ser
index b5cc027..b5cc027 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/NotYetConnectedExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/OverlappingFileLockExceptionTest.golden.ser
index 9c0e175..9c0e175 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/OverlappingFileLockExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/UnresolvedAddressExceptionTest.golden.ser
index 2a24deb..2a24deb 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/UnresolvedAddressExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.golden.ser
index 1dd6a01..1dd6a01 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/CharacterCodingExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/CharacterCodingExceptionTest.golden.ser
index a95c4e4..a95c4e4 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/CharacterCodingExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/CharacterCodingExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/CoderMalfunctionErrorTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/CoderMalfunctionErrorTest.golden.ser
index 6f4a4e3..6f4a4e3 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/CoderMalfunctionErrorTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/CoderMalfunctionErrorTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/IllegalCharsetNameExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/IllegalCharsetNameExceptionTest.golden.ser
index 59e4d0b..59e4d0b 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/IllegalCharsetNameExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/IllegalCharsetNameExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/MalformedInputExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/MalformedInputExceptionTest.golden.ser
index e2f0dec..e2f0dec 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/MalformedInputExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/MalformedInputExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/UnmappableCharacterExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/UnmappableCharacterExceptionTest.golden.ser
index 7933fb9..7933fb9 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/UnmappableCharacterExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/UnmappableCharacterExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/UnsupportedCharsetExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/UnsupportedCharsetExceptionTest.golden.ser
index 07c63bb..07c63bb 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/nio_char/tests/java/nio/charset/UnsupportedCharsetExceptionTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/nio/charset/UnsupportedCharsetExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/java/text/DecimalFormat.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormat.ser
index c20fa78..c20fa78 100644
--- a/luni/src/test/resources/serialization/java/text/DecimalFormat.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormat.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/java/text/DecimalFormatSymbols.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbols.ser
index 6e086af..6e086af 100644
--- a/luni/src/test/resources/serialization/java/text/DecimalFormatSymbols.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbols.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbolsTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbolsTest.golden.ser
new file mode 100644
index 0000000..c8e3948
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbolsTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleEntry.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleEntry.golden.ser
new file mode 100644
index 0000000..0b5d815
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleEntry.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleImmutableEntry.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleImmutableEntry.golden.ser
new file mode 100644
index 0000000..a85543d
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/AbstractMapTest_SimpleImmutableEntry.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/ArrayDequeTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/ArrayDequeTest.golden.ser
new file mode 100644
index 0000000..794419a
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/ArrayDequeTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/BitSetTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/BitSetTest.golden.ser
new file mode 100644
index 0000000..1f38d8d
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/BitSetTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedCollection.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedCollection.golden.ser
new file mode 100644
index 0000000..eec840e
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedCollection.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedList.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedList.golden.ser
new file mode 100644
index 0000000..e9a4122
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedList.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedListRandomAccess.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedListRandomAccess.golden.ser
new file mode 100644
index 0000000..dfa2d43
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedListRandomAccess.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedMap.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedMap.golden.ser
new file mode 100644
index 0000000..13415f6
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedMap.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSet.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSet.golden.ser
new file mode 100644
index 0000000..ed1f305
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSet.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedMap.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedMap.golden.ser
new file mode 100644
index 0000000..eca8ffa
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedMap.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedSet.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedSet.golden.ser
new file mode 100644
index 0000000..4520ed4
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_CheckedSortedSet.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_asLifoQueue.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_asLifoQueue.golden.ser
new file mode 100644
index 0000000..73134df
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_asLifoQueue.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_newSetFromMap.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_newSetFromMap.golden.ser
new file mode 100644
index 0000000..88f97e5
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/Collections_newSetFromMap.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/DuplicateFormatFlagsExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/DuplicateFormatFlagsExceptionTest.golden.ser
new file mode 100644
index 0000000..f26eade
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/DuplicateFormatFlagsExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/EnumMapTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/EnumMapTest.golden.ser
new file mode 100644
index 0000000..8151214
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/EnumMapTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/EnumSetTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/EnumSetTest.golden.ser
new file mode 100644
index 0000000..5271090
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/EnumSetTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/FormatFlagsConversionMismatchExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/FormatFlagsConversionMismatchExceptionTest.golden.ser
new file mode 100644
index 0000000..ff1afb2
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/FormatFlagsConversionMismatchExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/FormatterClosedExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/FormatterClosedExceptionTest.golden.ser
new file mode 100644
index 0000000..02e8dbc
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/FormatterClosedExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/HashMapTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/HashMapTest.golden.ser
new file mode 100644
index 0000000..529512a
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/HashMapTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/util/HashSetTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/HashSetTest.golden.ser
index 5d76a32..5d76a32 100644
--- a/luni/src/test/resources/serialization/tests/api/java/util/HashSetTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/HashSetTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/util/IdentityHashMapTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IdentityHashMapTest.golden.ser
index 8f27937..8f27937 100644
--- a/luni/src/test/resources/serialization/tests/api/java/util/IdentityHashMapTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IdentityHashMapTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatCodePointExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatCodePointExceptionTest.golden.ser
new file mode 100644
index 0000000..23db2c6
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatCodePointExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatConversionExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatConversionExceptionTest.golden.ser
new file mode 100644
index 0000000..52c8817
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatConversionExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatFlagsExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatFlagsExceptionTest.golden.ser
new file mode 100644
index 0000000..b14987f
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatFlagsExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatPrecisionExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatPrecisionExceptionTest.golden.ser
new file mode 100644
index 0000000..e822aec
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatPrecisionExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatWidthExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatWidthExceptionTest.golden.ser
new file mode 100644
index 0000000..8e1a25b
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/IllegalFormatWidthExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/InputMismatchExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/InputMismatchExceptionTest.golden.ser
new file mode 100644
index 0000000..5b76933
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/InputMismatchExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/LinkedListTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/LinkedListTest.golden.ser
new file mode 100644
index 0000000..c94e6dc
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/LinkedListTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/MissingFormatArgumentExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/MissingFormatArgumentExceptionTest.golden.ser
new file mode 100644
index 0000000..ea6797d
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/MissingFormatArgumentExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/MissingFormatWidthExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/MissingFormatWidthExceptionTest.golden.ser
new file mode 100644
index 0000000..19773a5
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/MissingFormatWidthExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/PriorityQueue.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/PriorityQueue.golden.ser
new file mode 100644
index 0000000..d716dda
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/PriorityQueue.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/RandomTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/RandomTest.golden.ser
new file mode 100644
index 0000000..a6b04ff
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/RandomTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/ServiceConfigurationErrorTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/ServiceConfigurationErrorTest.golden.ser
new file mode 100644
index 0000000..d43a064
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/ServiceConfigurationErrorTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/util/UUIDTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UUIDTest.golden.ser
index 9947a3a..9947a3a 100644
--- a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/util/UUIDTest.golden.ser
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UUIDTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UnknownFormatConversionExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UnknownFormatConversionExceptionTest.golden.ser
new file mode 100644
index 0000000..20a59cc
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UnknownFormatConversionExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UnknownFormatFlagsExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UnknownFormatFlagsExceptionTest.golden.ser
new file mode 100644
index 0000000..e4b2278
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/UnknownFormatFlagsExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/prefs/BackingStoreExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/prefs/BackingStoreExceptionTest.golden.ser
new file mode 100644
index 0000000..4d26113
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/prefs/BackingStoreExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/prefs/InvalidPreferencesFormatExceptionTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/prefs/InvalidPreferencesFormatExceptionTest.golden.ser
new file mode 100644
index 0000000..a15948d
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/prefs/InvalidPreferencesFormatExceptionTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/zip/ZipErrorTest.golden.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/zip/ZipErrorTest.golden.ser
new file mode 100644
index 0000000..2600aa5
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/java/util/zip/ZipErrorTest.golden.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/DestroyFailedExceptionTest.golden.0.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/DestroyFailedExceptionTest.golden.0.ser
new file mode 100644
index 0000000..70de6c8
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/DestroyFailedExceptionTest.golden.0.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.0.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.0.ser
new file mode 100644
index 0000000..05b3098
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.0.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.1.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.1.ser
new file mode 100644
index 0000000..82dfd74
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.1.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.2.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.2.ser
new file mode 100644
index 0000000..1030381
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.2.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.3.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.3.ser
new file mode 100644
index 0000000..a83e565
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/SubjectTest.golden.3.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.golden.0.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.golden.0.ser
new file mode 100644
index 0000000..f1b0320
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.golden.0.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.golden.1.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.golden.1.ser
new file mode 100644
index 0000000..ec1350c
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/callback/PasswordCallbackTest.golden.1.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/login/LoginExceptionTest.golden.0.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/login/LoginExceptionTest.golden.0.ser
new file mode 100644
index 0000000..c5000c4
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/login/LoginExceptionTest.golden.0.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.0.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.0.ser
new file mode 100644
index 0000000..6d81da2
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.0.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.1.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.1.ser
new file mode 100644
index 0000000..c209895
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.1.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.2.ser b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.2.ser
new file mode 100644
index 0000000..426a364
--- /dev/null
+++ b/harmony-tests/src/test/resources/serialization/org/apache/harmony/tests/javax/security/auth/x500/X500PrincipalTest.golden.2.ser
Binary files differ
diff --git a/harmony-tests/src/test/resources/tests/resources/X500PrincipalTest.0.dat b/harmony-tests/src/test/resources/tests/resources/X500PrincipalTest.0.dat
new file mode 100644
index 0000000..5a10bf9
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/X500PrincipalTest.0.dat
@@ -0,0 +1,5 @@
+001
+0UB1
+0UA1
+0UB1
+0UA \ No newline at end of file
diff --git a/harmony-tests/src/test/resources/tests/resources/X500PrincipalTest.1.dat b/harmony-tests/src/test/resources/tests/resources/X500PrincipalTest.1.dat
new file mode 100644
index 0000000..2606b98
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/X500PrincipalTest.1.dat
@@ -0,0 +1,5 @@
+001
+0UB1
+0UA1
+0UB1
+0UA \ No newline at end of file
diff --git a/harmony-tests/src/test/resources/tests/resources/hyts_compDiction.bin b/harmony-tests/src/test/resources/tests/resources/hyts_compDiction.bin
new file mode 100644
index 0000000..f0478c8
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/hyts_compDiction.bin
Binary files differ
diff --git a/harmony-tests/src/test/resources/tests/resources/hyts_compressD.bin b/harmony-tests/src/test/resources/tests/resources/hyts_compressD.bin
new file mode 100644
index 0000000..36c89f2
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/hyts_compressD.bin
Binary files differ
diff --git a/harmony-tests/src/test/resources/tests/resources/hyts_construOD.bin b/harmony-tests/src/test/resources/tests/resources/hyts_construOD.bin
new file mode 100644
index 0000000..035d12e
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/hyts_construOD.bin
Binary files differ
diff --git a/harmony-tests/src/test/resources/tests/resources/hyts_construODI.bin b/harmony-tests/src/test/resources/tests/resources/hyts_construODI.bin
new file mode 100644
index 0000000..1e5d284
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/hyts_construODI.bin
Binary files differ
diff --git a/harmony-tests/src/test/resources/tests/resources/hyts_gInput.txt.gz b/harmony-tests/src/test/resources/tests/resources/hyts_gInput.txt.gz
new file mode 100644
index 0000000..e0f5a00
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/hyts_gInput.txt.gz
Binary files differ
diff --git a/harmony-tests/src/test/resources/tests/resources/hyts_resource_fr_FR.properties b/harmony-tests/src/test/resources/tests/resources/hyts_resource_fr_FR.properties
new file mode 100644
index 0000000..0ac2c73
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/hyts_resource_fr_FR.properties
@@ -0,0 +1,3 @@
+property=fr_FR_resource
+propertyInFRFR=valueInFRFR
+ \ No newline at end of file
diff --git a/support/src/test/java/tests/resources/net/lf.jar b/harmony-tests/src/test/resources/tests/resources/net/lf.jar
index aca8f37..aca8f37 100644
--- a/support/src/test/java/tests/resources/net/lf.jar
+++ b/harmony-tests/src/test/resources/tests/resources/net/lf.jar
Binary files differ
diff --git a/harmony-tests/src/test/resources/tests/resources/net/url-test.jar b/harmony-tests/src/test/resources/tests/resources/net/url-test.jar
new file mode 100644
index 0000000..ec33a02
--- /dev/null
+++ b/harmony-tests/src/test/resources/tests/resources/net/url-test.jar
Binary files differ
diff --git a/include/ScopedIcuLocale.h b/include/ScopedIcuLocale.h
new file mode 100644
index 0000000..2109e03
--- /dev/null
+++ b/include/ScopedIcuLocale.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SCOPED_ICU_LOCALE_H_included
+#define SCOPED_ICU_LOCALE_H_included
+
+#include "JNIHelp.h"
+#include "ScopedUtfChars.h"
+#include "unicode/locid.h"
+
+class ScopedIcuLocale {
+ public:
+ ScopedIcuLocale(JNIEnv* env, jstring javaLocaleName) : mEnv(env) {
+ mLocale.setToBogus();
+
+ if (javaLocaleName == NULL) {
+ jniThrowNullPointerException(mEnv, "javaLocaleName == null");
+ return;
+ }
+
+ const ScopedUtfChars localeName(env, javaLocaleName);
+ if (localeName.c_str() == NULL) {
+ return;
+ }
+
+ mLocale = Locale::createFromName(localeName.c_str());
+ }
+
+ ~ScopedIcuLocale() {
+ }
+
+ bool valid() const {
+ return !mLocale.isBogus();
+ }
+
+ Locale& locale() {
+ return mLocale;
+ }
+
+ private:
+ JNIEnv* const mEnv;
+ Locale mLocale;
+
+ // Disallow copy and assignment.
+ ScopedIcuLocale(const ScopedIcuLocale&);
+ void operator=(const ScopedIcuLocale&);
+};
+
+#endif // SCOPED_ICU_LOCALE_H_included
diff --git a/include/StaticAssert.h b/include/StaticAssert.h
deleted file mode 100644
index ab809b3..0000000
--- a/include/StaticAssert.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STATIC_ASSERT_H_included
-#define STATIC_ASSERT_H_included
-
-/**
- * Similar to C++0x's static_assert. Message argument must be a valid identifier, not a string.
- * Called COMPILE_ASSERT in Google, COMPILE_TIME_ASSERT in other places. This is the usual Google
- * implementation.
- */
-#define STATIC_ASSERT(exp, msg) typedef StaticAssert<(bool(exp))> msg[bool(exp) ? 1 : -1]
-template <bool> struct StaticAssert {};
-
-#endif // STATIC_ASSERT_H_included
diff --git a/json/src/main/java/org/json/JSONArray.java b/json/src/main/java/org/json/JSONArray.java
index f6801aa..9b5f2b7 100644
--- a/json/src/main/java/org/json/JSONArray.java
+++ b/json/src/main/java/org/json/JSONArray.java
@@ -187,6 +187,17 @@ public class JSONArray {
}
/**
+ * Same as {@link #put}, with added validity checks.
+ */
+ void checkedPut(Object value) throws JSONException {
+ if (value instanceof Number) {
+ JSON.checkDouble(((Number) value).doubleValue());
+ }
+
+ put(value);
+ }
+
+ /**
* Sets the value at {@code index} to {@code value}, null padding this array
* to the required length if necessary. If a value already exists at {@code
* index}, it will be replaced.
diff --git a/json/src/main/java/org/json/JSONObject.java b/json/src/main/java/org/json/JSONObject.java
index ae3b747..9ea91a6 100644
--- a/json/src/main/java/org/json/JSONObject.java
+++ b/json/src/main/java/org/json/JSONObject.java
@@ -18,9 +18,10 @@ package org.json;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Set;
// Note: this class was written without inspecting the non-free org.json sourcecode.
@@ -104,13 +105,13 @@ public class JSONObject {
}
};
- private final Map<String, Object> nameValuePairs;
+ private final LinkedHashMap<String, Object> nameValuePairs;
/**
* Creates a {@code JSONObject} with no name/value mappings.
*/
public JSONObject() {
- nameValuePairs = new HashMap<String, Object>();
+ nameValuePairs = new LinkedHashMap<String, Object>();
}
/**
@@ -283,33 +284,66 @@ public class JSONObject {
* mapped to {@code name}. In aggregate, this allows values to be added to a
* mapping one at a time.
*
+ * <p> Note that {@code append(String, Object)} provides better semantics.
+ * In particular, the mapping for {@code name} will <b>always</b> be a
+ * {@link JSONArray}. Using {@code accumulate} will result in either a
+ * {@link JSONArray} or a mapping whose type is the type of {@code value}
+ * depending on the number of calls to it.
+ *
* @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
* Integer, Long, Double, {@link #NULL} or null. May not be {@link
* Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
*/
+ // TODO: Change {@code append) to {@link #append} when append is
+ // unhidden.
public JSONObject accumulate(String name, Object value) throws JSONException {
Object current = nameValuePairs.get(checkName(name));
if (current == null) {
return put(name, value);
}
- // check in accumulate, since array.put(Object) doesn't do any checking
- if (value instanceof Number) {
- JSON.checkDouble(((Number) value).doubleValue());
- }
-
if (current instanceof JSONArray) {
JSONArray array = (JSONArray) current;
- array.put(value);
+ array.checkedPut(value);
} else {
JSONArray array = new JSONArray();
- array.put(current);
- array.put(value);
+ array.checkedPut(current);
+ array.checkedPut(value);
nameValuePairs.put(name, array);
}
return this;
}
+ /**
+ * Appends values to the array mapped to {@code name}. A new {@link JSONArray}
+ * mapping for {@code name} will be inserted if no mapping exists. If the existing
+ * mapping for {@code name} is not a {@link JSONArray}, a {@link JSONException}
+ * will be thrown.
+ *
+ * @throws JSONException if {@code name} is {@code null} or if the mapping for
+ * {@code name} is non-null and is not a {@link JSONArray}.
+ *
+ * @hide
+ */
+ public JSONObject append(String name, Object value) throws JSONException {
+ Object current = nameValuePairs.get(checkName(name));
+
+ final JSONArray array;
+ if (current instanceof JSONArray) {
+ array = (JSONArray) current;
+ } else if (current == null) {
+ JSONArray newArray = new JSONArray();
+ nameValuePairs.put(name, newArray);
+ array = newArray;
+ } else {
+ throw new JSONException("Key " + name + " is not a JSONArray");
+ }
+
+ array.checkedPut(value);
+
+ return this;
+ }
+
String checkName(String name) throws JSONException {
if (name == null) {
throw new JSONException("Names must be non-null");
@@ -345,7 +379,7 @@ public class JSONObject {
}
/**
- * Returns the value mapped by {@code name}.
+ * Returns the value mapped by {@code name}, or throws if no such mapping exists.
*
* @throws JSONException if no such mapping exists.
*/
@@ -367,7 +401,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a boolean or
- * can be coerced to a boolean.
+ * can be coerced to a boolean, or throws otherwise.
*
* @throws JSONException if the mapping doesn't exist or cannot be coerced
* to a boolean.
@@ -383,7 +417,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a boolean or
- * can be coerced to a boolean. Returns false otherwise.
+ * can be coerced to a boolean, or false otherwise.
*/
public boolean optBoolean(String name) {
return optBoolean(name, false);
@@ -391,7 +425,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a boolean or
- * can be coerced to a boolean. Returns {@code fallback} otherwise.
+ * can be coerced to a boolean, or {@code fallback} otherwise.
*/
public boolean optBoolean(String name, boolean fallback) {
Object object = opt(name);
@@ -401,7 +435,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a double or
- * can be coerced to a double.
+ * can be coerced to a double, or throws otherwise.
*
* @throws JSONException if the mapping doesn't exist or cannot be coerced
* to a double.
@@ -417,7 +451,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a double or
- * can be coerced to a double. Returns {@code NaN} otherwise.
+ * can be coerced to a double, or {@code NaN} otherwise.
*/
public double optDouble(String name) {
return optDouble(name, Double.NaN);
@@ -425,7 +459,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a double or
- * can be coerced to a double. Returns {@code fallback} otherwise.
+ * can be coerced to a double, or {@code fallback} otherwise.
*/
public double optDouble(String name, double fallback) {
Object object = opt(name);
@@ -435,7 +469,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is an int or
- * can be coerced to an int.
+ * can be coerced to an int, or throws otherwise.
*
* @throws JSONException if the mapping doesn't exist or cannot be coerced
* to an int.
@@ -451,7 +485,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is an int or
- * can be coerced to an int. Returns 0 otherwise.
+ * can be coerced to an int, or 0 otherwise.
*/
public int optInt(String name) {
return optInt(name, 0);
@@ -459,7 +493,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is an int or
- * can be coerced to an int. Returns {@code fallback} otherwise.
+ * can be coerced to an int, or {@code fallback} otherwise.
*/
public int optInt(String name, int fallback) {
Object object = opt(name);
@@ -469,7 +503,8 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a long or
- * can be coerced to a long. Note that JSON represents numbers as doubles,
+ * can be coerced to a long, or throws otherwise.
+ * Note that JSON represents numbers as doubles,
* so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
*
* @throws JSONException if the mapping doesn't exist or cannot be coerced
@@ -486,7 +521,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a long or
- * can be coerced to a long. Returns 0 otherwise. Note that JSON represents numbers as doubles,
+ * can be coerced to a long, or 0 otherwise. Note that JSON represents numbers as doubles,
* so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
*/
public long optLong(String name) {
@@ -495,7 +530,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a long or
- * can be coerced to a long. Returns {@code fallback} otherwise. Note that JSON represents
+ * can be coerced to a long, or {@code fallback} otherwise. Note that JSON represents
* numbers as doubles, so this is <a href="#lossy">lossy</a>; use strings to transfer
* numbers via JSON.
*/
@@ -507,7 +542,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists, coercing it if
- * necessary.
+ * necessary, or throws if no such mapping exists.
*
* @throws JSONException if no such mapping exists.
*/
@@ -522,7 +557,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists, coercing it if
- * necessary. Returns the empty string if no such mapping exists.
+ * necessary, or the empty string if no such mapping exists.
*/
public String optString(String name) {
return optString(name, "");
@@ -530,7 +565,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists, coercing it if
- * necessary. Returns {@code fallback} if no such mapping exists.
+ * necessary, or {@code fallback} if no such mapping exists.
*/
public String optString(String name, String fallback) {
Object object = opt(name);
@@ -540,7 +575,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a {@code
- * JSONArray}.
+ * JSONArray}, or throws otherwise.
*
* @throws JSONException if the mapping doesn't exist or is not a {@code
* JSONArray}.
@@ -556,7 +591,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a {@code
- * JSONArray}. Returns null otherwise.
+ * JSONArray}, or null otherwise.
*/
public JSONArray optJSONArray(String name) {
Object object = opt(name);
@@ -565,7 +600,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a {@code
- * JSONObject}.
+ * JSONObject}, or throws otherwise.
*
* @throws JSONException if the mapping doesn't exist or is not a {@code
* JSONObject}.
@@ -581,7 +616,7 @@ public class JSONObject {
/**
* Returns the value mapped by {@code name} if it exists and is a {@code
- * JSONObject}. Returns null otherwise.
+ * JSONObject}, or null otherwise.
*/
public JSONObject optJSONObject(String name) {
Object object = opt(name);
@@ -616,12 +651,25 @@ public class JSONObject {
* modified after the iterator is returned, the iterator's behavior is
* undefined. The order of the keys is undefined.
*/
- /* Return a raw type for API compatibility */
- public Iterator keys() {
+ public Iterator<String> keys() {
return nameValuePairs.keySet().iterator();
}
/**
+ * Returns the set of {@code String} names in this object. The returned set
+ * is a view of the keys in this object. {@link Set#remove(Object)} will remove
+ * the corresponding mapping from this object and set iterator behaviour
+ * is undefined if this object is modified after it is returned.
+ *
+ * See {@link #keys()}.
+ *
+ * @hide.
+ */
+ public Set<String> keySet() {
+ return nameValuePairs.keySet();
+ }
+
+ /**
* Returns an array containing the string names in this object. This method
* returns null if this object contains no mappings.
*/
diff --git a/json/src/test/java/org/json/JSONArrayTest.java b/json/src/test/java/org/json/JSONArrayTest.java
index 52767db..4c86b8a 100644
--- a/json/src/test/java/org/json/JSONArrayTest.java
+++ b/json/src/test/java/org/json/JSONArrayTest.java
@@ -551,4 +551,17 @@ public class JSONArrayTest extends TestCase {
assertEquals("hello", a.remove(0));
assertEquals(null, a.remove(0));
}
+
+ enum MyEnum { A, B, C; }
+
+ // https://code.google.com/p/android/issues/detail?id=62539
+ public void testEnums() throws Exception {
+ // This works because it's in java.* and any class in there falls back to toString.
+ JSONArray a1 = new JSONArray(java.lang.annotation.RetentionPolicy.values());
+ assertEquals("[\"SOURCE\",\"CLASS\",\"RUNTIME\"]", a1.toString());
+
+ // This doesn't because it's not.
+ JSONArray a2 = new JSONArray(MyEnum.values());
+ assertEquals("[null,null,null]", a2.toString());
+ }
}
diff --git a/json/src/test/java/org/json/JSONObjectTest.java b/json/src/test/java/org/json/JSONObjectTest.java
index 8abd88f..e89db94 100644
--- a/json/src/test/java/org/json/JSONObjectTest.java
+++ b/json/src/test/java/org/json/JSONObjectTest.java
@@ -28,6 +28,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.TreeMap;
import junit.framework.TestCase;
/**
@@ -988,9 +989,44 @@ public class JSONObjectTest extends TestCase {
ArrayList<Object> list = new ArrayList<Object>();
list.add("a");
list.add(new ArrayList<String>());
- HashMap<String, Object> map = new HashMap<String, Object>();
+ Map<String, Object> map = new TreeMap<String, Object>();
map.put("x", "l");
map.put("y", list);
- assertEquals("{\"y\":[\"a\",[]],\"x\":\"l\"}", new JSONObject(map).toString());
+ assertEquals("{\"x\":\"l\",\"y\":[\"a\",[]]}", new JSONObject(map).toString());
+ }
+
+ public void testAppendExistingInvalidKey() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", 5);
+ try {
+ object.append("foo", 6);
+ fail();
+ } catch (JSONException expected) {
+ }
+ }
+
+ public void testAppendExistingArray() throws JSONException {
+ JSONArray array = new JSONArray();
+ JSONObject object = new JSONObject();
+ object.put("foo", array);
+ object.append("foo", 5);
+ assertEquals("[5]", array.toString());
+ }
+
+ public void testAppendPutArray() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.append("foo", 5);
+ assertEquals("{\"foo\":[5]}", object.toString());
+ object.append("foo", new JSONArray());
+ assertEquals("{\"foo\":[5,[]]}", object.toString());
+ }
+
+ public void testAppendNull() {
+ JSONObject object = new JSONObject();
+ try {
+ object.append(null, 5);
+ fail();
+ } catch (JSONException e) {
+ }
}
}
diff --git a/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java b/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java
new file mode 100644
index 0000000..ba4cc66
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java
@@ -0,0 +1,604 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.security.*;
+
+public class AbstractExecutorServiceTest extends JSR166TestCase {
+
+ /**
+ * A no-frills implementation of AbstractExecutorService, designed
+ * to test the submit methods only.
+ */
+ static class DirectExecutorService extends AbstractExecutorService {
+ public void execute(Runnable r) { r.run(); }
+ public void shutdown() { shutdown = true; }
+ public List<Runnable> shutdownNow() {
+ shutdown = true;
+ return Collections.EMPTY_LIST;
+ }
+ public boolean isShutdown() { return shutdown; }
+ public boolean isTerminated() { return isShutdown(); }
+ public boolean awaitTermination(long timeout, TimeUnit unit) {
+ return isShutdown();
+ }
+ private volatile boolean shutdown = false;
+ }
+
+ /**
+ * execute(runnable) runs it to completion
+ */
+ public void testExecuteRunnable() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ final AtomicBoolean done = new AtomicBoolean(false);
+ CheckedRunnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.set(true);
+ }};
+ Future<?> future = e.submit(task);
+ assertNull(future.get());
+ assertNull(future.get(0, MILLISECONDS));
+ assertTrue(done.get());
+ assertTrue(future.isDone());
+ assertFalse(future.isCancelled());
+ }
+
+ /**
+ * Completed submit(callable) returns result
+ */
+ public void testSubmitCallable() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ Future<String> future = e.submit(new StringTask());
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ }
+
+ /**
+ * Completed submit(runnable) returns successfully
+ */
+ public void testSubmitRunnable() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ Future<?> future = e.submit(new NoOpRunnable());
+ future.get();
+ assertTrue(future.isDone());
+ }
+
+ /**
+ * Completed submit(runnable, result) returns result
+ */
+ public void testSubmitRunnable2() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ }
+
+ /**
+ * A submitted privileged action runs to completion
+ */
+ public void testSubmitPrivilegedAction() throws Exception {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ Future future = e.submit(Executors.callable(new PrivilegedAction() {
+ public Object run() {
+ return TEST_STRING;
+ }}));
+
+ assertSame(TEST_STRING, future.get());
+ }};
+
+ runWithPermissions(r,
+ new RuntimePermission("getClassLoader"),
+ new RuntimePermission("setContextClassLoader"),
+ new RuntimePermission("modifyThread"));
+ }
+
+ /**
+ * A submitted privileged exception action runs to completion
+ */
+ public void testSubmitPrivilegedExceptionAction() throws Exception {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
+ public Object run() {
+ return TEST_STRING;
+ }}));
+
+ assertSame(TEST_STRING, future.get());
+ }};
+
+ runWithPermissions(r);
+ }
+
+ /**
+ * A submitted failed privileged exception action reports exception
+ */
+ public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
+ public Object run() throws Exception {
+ throw new IndexOutOfBoundsException();
+ }}));
+
+ try {
+ future.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
+ }}};
+
+ runWithPermissions(r);
+ }
+
+ /**
+ * execute(null runnable) throws NPE
+ */
+ public void testExecuteNullRunnable() {
+ try {
+ ExecutorService e = new DirectExecutorService();
+ e.submit((Runnable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * submit(null callable) throws NPE
+ */
+ public void testSubmitNullCallable() {
+ try {
+ ExecutorService e = new DirectExecutorService();
+ e.submit((Callable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * submit(callable).get() throws InterruptedException if interrupted
+ */
+ public void testInterruptedSubmit() throws InterruptedException {
+ final CountDownLatch submitted = new CountDownLatch(1);
+ final CountDownLatch quittingTime = new CountDownLatch(1);
+ final ExecutorService p
+ = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final Callable<Void> awaiter = new CheckedCallable<Void>() {
+ public Void realCall() throws InterruptedException {
+ quittingTime.await();
+ return null;
+ }};
+ try {
+ Thread t = new Thread(new CheckedInterruptedRunnable() {
+ public void realRun() throws Exception {
+ Future<Void> future = p.submit(awaiter);
+ submitted.countDown();
+ future.get();
+ }});
+ t.start();
+ submitted.await();
+ t.interrupt();
+ t.join();
+ } finally {
+ quittingTime.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * get of submit(callable) throws ExecutionException if callable
+ * throws exception
+ */
+ public void testSubmitEE() throws InterruptedException {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ 60, TimeUnit.SECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+
+ Callable c = new Callable() {
+ public Object call() { throw new ArithmeticException(); }};
+
+ try {
+ p.submit(c).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof ArithmeticException);
+ }
+ joinPool(p);
+ }
+
+ /**
+ * invokeAny(null) throws NPE
+ */
+ public void testInvokeAny1() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ e.invokeAny(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(empty collection) throws IAE
+ */
+ public void testInvokeAny2() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws NPE if c has null elements
+ */
+ public void testInvokeAny3() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ List<Callable<Long>> l = new ArrayList<Callable<Long>>();
+ l.add(new Callable<Long>() {
+ public Long call() { throw new ArithmeticException(); }});
+ l.add(null);
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws ExecutionException if no task in c completes
+ */
+ public void testInvokeAny4() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) returns result of some task in c if at least one completes
+ */
+ public void testInvokeAny5() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(null) throws NPE
+ */
+ public void testInvokeAll1() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ e.invokeAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(empty collection) returns empty collection
+ */
+ public void testInvokeAll2() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) throws NPE if c has null elements
+ */
+ public void testInvokeAll3() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of returned element of invokeAll(c) throws exception on failed task
+ */
+ public void testInvokeAll4() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ }
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) returns results of all completed tasks in c
+ */
+ public void testInvokeAll5() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(null) throws NPE
+ */
+ public void testTimedInvokeAny1() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(null time unit) throws NPE
+ */
+ public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(empty collection) throws IAE
+ */
+ public void testTimedInvokeAny2() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAny3() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ List<Callable<Long>> l = new ArrayList<Callable<Long>>();
+ l.add(new Callable<Long>() {
+ public Long call() { throw new ArithmeticException(); }});
+ l.add(null);
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testTimedInvokeAny4() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) returns result of some task in c
+ */
+ public void testTimedInvokeAny5() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(null) throws NPE
+ */
+ public void testTimedInvokeAll1() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(null time unit) throws NPE
+ */
+ public void testTimedInvokeAllNullTimeUnit() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(empty collection) returns empty collection
+ */
+ public void testTimedInvokeAll2() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAll3() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of returned element of invokeAll(c) throws exception on failed task
+ */
+ public void testTimedInvokeAll4() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ }
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) returns results of all completed tasks in c
+ */
+ public void testTimedInvokeAll5() throws Exception {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll cancels tasks not completed by timeout
+ */
+ public void testTimedInvokeAll6() throws InterruptedException {
+ ExecutorService e = new DirectExecutorService();
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(Executors.callable(possiblyInterruptedRunnable(2 * SHORT_DELAY_MS), TEST_STRING));
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+ assertEquals(l.size(), futures.size());
+ for (Future future : futures)
+ assertTrue(future.isDone());
+ assertFalse(futures.get(0).isCancelled());
+ assertFalse(futures.get(1).isCancelled());
+ assertTrue(futures.get(2).isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java
new file mode 100644
index 0000000..e74fc3c
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java
@@ -0,0 +1,172 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.AbstractQueue;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+public class AbstractQueueTest extends JSR166TestCase {
+
+ static class Succeed extends AbstractQueue<Integer> {
+ public boolean offer(Integer x) {
+ if (x == null) throw new NullPointerException();
+ return true;
+ }
+ public Integer peek() { return one; }
+ public Integer poll() { return one; }
+ public int size() { return 0; }
+ public Iterator iterator() { return null; } // not needed
+ }
+
+ static class Fail extends AbstractQueue<Integer> {
+ public boolean offer(Integer x) {
+ if (x == null) throw new NullPointerException();
+ return false;
+ }
+ public Integer peek() { return null; }
+ public Integer poll() { return null; }
+ public int size() { return 0; }
+ public Iterator iterator() { return null; } // not needed
+ }
+
+ /**
+ * add returns true if offer succeeds
+ */
+ public void testAddS() {
+ Succeed q = new Succeed();
+ assertTrue(q.add(two));
+ }
+
+ /**
+ * add throws ISE true if offer fails
+ */
+ public void testAddF() {
+ Fail q = new Fail();
+ try {
+ q.add(one);
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * add throws NPE if offer does
+ */
+ public void testAddNPE() {
+ Succeed q = new Succeed();
+ try {
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove returns normally if poll succeeds
+ */
+ public void testRemoveS() {
+ Succeed q = new Succeed();
+ q.remove();
+ }
+
+ /**
+ * remove throws NSEE if poll returns null
+ */
+ public void testRemoveF() {
+ Fail q = new Fail();
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * element returns normally if peek succeeds
+ */
+ public void testElementS() {
+ Succeed q = new Succeed();
+ q.element();
+ }
+
+ /**
+ * element throws NSEE if peek returns null
+ */
+ public void testElementF() {
+ Fail q = new Fail();
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ Succeed q = new Succeed();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll(this) throws IAE
+ */
+ public void testAddAllSelf() {
+ try {
+ Succeed q = new Succeed();
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ Succeed q = new Succeed();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ Succeed q = new Succeed();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll throws ISE if an add fails
+ */
+ public void testAddAll4() {
+ try {
+ Fail q = new Fail();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java
new file mode 100644
index 0000000..d957e61
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java
@@ -0,0 +1,1209 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
+import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject;
+
+public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
+
+ /**
+ * A simple mutex class, adapted from the class javadoc. Exclusive
+ * acquire tests exercise this as a sample user extension.
+ */
+ static class Mutex extends AbstractQueuedLongSynchronizer {
+ /** An eccentric value > 32 bits for locked synchronizer state. */
+ static final long LOCKED = (1L << 63) | (1L << 15);
+
+ static final long UNLOCKED = 0;
+
+ public boolean isHeldExclusively() {
+ long state = getState();
+ assertTrue(state == UNLOCKED || state == LOCKED);
+ return state == LOCKED;
+ }
+
+ public boolean tryAcquire(long acquires) {
+ assertEquals(LOCKED, acquires);
+ return compareAndSetState(UNLOCKED, LOCKED);
+ }
+
+ public boolean tryRelease(long releases) {
+ if (getState() != LOCKED) throw new IllegalMonitorStateException();
+ setState(UNLOCKED);
+ return true;
+ }
+
+ public boolean tryAcquireNanos(long nanos) throws InterruptedException {
+ return tryAcquireNanos(LOCKED, nanos);
+ }
+
+ public boolean tryAcquire() {
+ return tryAcquire(LOCKED);
+ }
+
+ public boolean tryRelease() {
+ return tryRelease(LOCKED);
+ }
+
+ public void acquire() {
+ acquire(LOCKED);
+ }
+
+ public void acquireInterruptibly() throws InterruptedException {
+ acquireInterruptibly(LOCKED);
+ }
+
+ public void release() {
+ release(LOCKED);
+ }
+
+ public ConditionObject newCondition() {
+ return new ConditionObject();
+ }
+ }
+
+ /**
+ * A simple latch class, to test shared mode.
+ */
+ static class BooleanLatch extends AbstractQueuedLongSynchronizer {
+ public boolean isSignalled() { return getState() != 0; }
+
+ public long tryAcquireShared(long ignore) {
+ return isSignalled() ? 1 : -1;
+ }
+
+ public boolean tryReleaseShared(long ignore) {
+ setState(1 << 62);
+ return true;
+ }
+ }
+
+ /**
+ * A runnable calling acquireInterruptibly that does not expect to
+ * be interrupted.
+ */
+ class InterruptibleSyncRunnable extends CheckedRunnable {
+ final Mutex sync;
+ InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
+ public void realRun() throws InterruptedException {
+ sync.acquireInterruptibly();
+ }
+ }
+
+ /**
+ * A runnable calling acquireInterruptibly that expects to be
+ * interrupted.
+ */
+ class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
+ final Mutex sync;
+ InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
+ public void realRun() throws InterruptedException {
+ sync.acquireInterruptibly();
+ }
+ }
+
+ /** A constant to clarify calls to checking methods below. */
+ static final Thread[] NO_THREADS = new Thread[0];
+
+ /**
+ * Spin-waits until sync.isQueued(t) becomes true.
+ */
+ void waitForQueuedThread(AbstractQueuedLongSynchronizer sync,
+ Thread t) {
+ long startTime = System.nanoTime();
+ while (!sync.isQueued(t)) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ throw new AssertionFailedError("timed out");
+ Thread.yield();
+ }
+ assertTrue(t.isAlive());
+ }
+
+ /**
+ * Checks that sync has exactly the given queued threads.
+ */
+ void assertHasQueuedThreads(AbstractQueuedLongSynchronizer sync,
+ Thread... expected) {
+ Collection<Thread> actual = sync.getQueuedThreads();
+ assertEquals(expected.length > 0, sync.hasQueuedThreads());
+ assertEquals(expected.length, sync.getQueueLength());
+ assertEquals(expected.length, actual.size());
+ assertEquals(expected.length == 0, actual.isEmpty());
+ assertEquals(new HashSet<Thread>(actual),
+ new HashSet<Thread>(Arrays.asList(expected)));
+ }
+
+ /**
+ * Checks that sync has exactly the given (exclusive) queued threads.
+ */
+ void assertHasExclusiveQueuedThreads(AbstractQueuedLongSynchronizer sync,
+ Thread... expected) {
+ assertHasQueuedThreads(sync, expected);
+ assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
+ new HashSet<Thread>(sync.getQueuedThreads()));
+ assertEquals(0, sync.getSharedQueuedThreads().size());
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ }
+
+ /**
+ * Checks that sync has exactly the given (shared) queued threads.
+ */
+ void assertHasSharedQueuedThreads(AbstractQueuedLongSynchronizer sync,
+ Thread... expected) {
+ assertHasQueuedThreads(sync, expected);
+ assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
+ new HashSet<Thread>(sync.getQueuedThreads()));
+ assertEquals(0, sync.getExclusiveQueuedThreads().size());
+ assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+ }
+
+ /**
+ * Checks that condition c has exactly the given waiter threads,
+ * after acquiring mutex.
+ */
+ void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
+ Thread... threads) {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, threads);
+ sync.release();
+ }
+
+ /**
+ * Checks that condition c has exactly the given waiter threads.
+ */
+ void assertHasWaitersLocked(Mutex sync, ConditionObject c,
+ Thread... threads) {
+ assertEquals(threads.length > 0, sync.hasWaiters(c));
+ assertEquals(threads.length, sync.getWaitQueueLength(c));
+ assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
+ assertEquals(threads.length, sync.getWaitingThreads(c).size());
+ assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
+ new HashSet<Thread>(Arrays.asList(threads)));
+ }
+
+ enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
+
+ /**
+ * Awaits condition using the specified AwaitMethod.
+ */
+ void await(ConditionObject c, AwaitMethod awaitMethod)
+ throws InterruptedException {
+ long timeoutMillis = 2 * LONG_DELAY_MS;
+ switch (awaitMethod) {
+ case await:
+ c.await();
+ break;
+ case awaitTimed:
+ assertTrue(c.await(timeoutMillis, MILLISECONDS));
+ break;
+ case awaitNanos:
+ long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+ long nanosRemaining = c.awaitNanos(nanosTimeout);
+ assertTrue(nanosRemaining > 0);
+ break;
+ case awaitUntil:
+ assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
+ break;
+ }
+ }
+
+ /**
+ * Checks that awaiting the given condition times out (using the
+ * default timeout duration).
+ */
+ void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
+ long timeoutMillis = timeoutMillis();
+ long startTime = System.nanoTime();
+ try {
+ switch (awaitMethod) {
+ case awaitTimed:
+ assertFalse(c.await(timeoutMillis, MILLISECONDS));
+ break;
+ case awaitNanos:
+ long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+ long nanosRemaining = c.awaitNanos(nanosTimeout);
+ assertTrue(nanosRemaining <= 0);
+ break;
+ case awaitUntil:
+ assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
+ break;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ } catch (InterruptedException ie) { threadUnexpectedException(ie); }
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ }
+
+ /**
+ * isHeldExclusively is false upon construction
+ */
+ public void testIsHeldExclusively() {
+ Mutex sync = new Mutex();
+ assertFalse(sync.isHeldExclusively());
+ }
+
+ /**
+ * acquiring released sync succeeds
+ */
+ public void testAcquire() {
+ Mutex sync = new Mutex();
+ sync.acquire();
+ assertTrue(sync.isHeldExclusively());
+ sync.release();
+ assertFalse(sync.isHeldExclusively());
+ }
+
+ /**
+ * tryAcquire on a released sync succeeds
+ */
+ public void testTryAcquire() {
+ Mutex sync = new Mutex();
+ assertTrue(sync.tryAcquire());
+ assertTrue(sync.isHeldExclusively());
+ sync.release();
+ assertFalse(sync.isHeldExclusively());
+ }
+
+ /**
+ * hasQueuedThreads reports whether there are waiting threads
+ */
+ public void testHasQueuedThreads() {
+ final Mutex sync = new Mutex();
+ assertFalse(sync.hasQueuedThreads());
+ sync.acquire();
+ Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t1);
+ assertTrue(sync.hasQueuedThreads());
+ Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+ waitForQueuedThread(sync, t2);
+ assertTrue(sync.hasQueuedThreads());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(sync.hasQueuedThreads());
+ sync.release();
+ awaitTermination(t2);
+ assertFalse(sync.hasQueuedThreads());
+ }
+
+ /**
+ * isQueued(null) throws NullPointerException
+ */
+ public void testIsQueuedNPE() {
+ final Mutex sync = new Mutex();
+ try {
+ sync.isQueued(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * isQueued reports whether a thread is queued
+ */
+ public void testIsQueued() {
+ final Mutex sync = new Mutex();
+ Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+ Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+ assertFalse(sync.isQueued(t1));
+ assertFalse(sync.isQueued(t2));
+ sync.acquire();
+ t1.start();
+ waitForQueuedThread(sync, t1);
+ assertTrue(sync.isQueued(t1));
+ assertFalse(sync.isQueued(t2));
+ t2.start();
+ waitForQueuedThread(sync, t2);
+ assertTrue(sync.isQueued(t1));
+ assertTrue(sync.isQueued(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertFalse(sync.isQueued(t1));
+ assertTrue(sync.isQueued(t2));
+ sync.release();
+ awaitTermination(t2);
+ assertFalse(sync.isQueued(t1));
+ assertFalse(sync.isQueued(t2));
+ }
+
+ /**
+ * getFirstQueuedThread returns first waiting thread or null if none
+ */
+ public void testGetFirstQueuedThread() {
+ final Mutex sync = new Mutex();
+ assertNull(sync.getFirstQueuedThread());
+ sync.acquire();
+ Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t1);
+ assertEquals(t1, sync.getFirstQueuedThread());
+ Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+ waitForQueuedThread(sync, t2);
+ assertEquals(t1, sync.getFirstQueuedThread());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertEquals(t2, sync.getFirstQueuedThread());
+ sync.release();
+ awaitTermination(t2);
+ assertNull(sync.getFirstQueuedThread());
+ }
+
+ /**
+ * hasContended reports false if no thread has ever blocked, else true
+ */
+ public void testHasContended() {
+ final Mutex sync = new Mutex();
+ assertFalse(sync.hasContended());
+ sync.acquire();
+ assertFalse(sync.hasContended());
+ Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t1);
+ assertTrue(sync.hasContended());
+ Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+ waitForQueuedThread(sync, t2);
+ assertTrue(sync.hasContended());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(sync.hasContended());
+ sync.release();
+ awaitTermination(t2);
+ assertTrue(sync.hasContended());
+ }
+
+ /**
+ * getQueuedThreads returns all waiting threads
+ */
+ public void testGetQueuedThreads() {
+ final Mutex sync = new Mutex();
+ Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+ Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ sync.acquire();
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ t1.start();
+ waitForQueuedThread(sync, t1);
+ assertHasExclusiveQueuedThreads(sync, t1);
+ assertTrue(sync.getQueuedThreads().contains(t1));
+ assertFalse(sync.getQueuedThreads().contains(t2));
+ t2.start();
+ waitForQueuedThread(sync, t2);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ assertTrue(sync.getQueuedThreads().contains(t1));
+ assertTrue(sync.getQueuedThreads().contains(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertHasExclusiveQueuedThreads(sync, t2);
+ sync.release();
+ awaitTermination(t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ }
+
+ /**
+ * getExclusiveQueuedThreads returns all exclusive waiting threads
+ */
+ public void testGetExclusiveQueuedThreads() {
+ final Mutex sync = new Mutex();
+ Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+ Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ sync.acquire();
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ t1.start();
+ waitForQueuedThread(sync, t1);
+ assertHasExclusiveQueuedThreads(sync, t1);
+ assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+ assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
+ t2.start();
+ waitForQueuedThread(sync, t2);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+ assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertHasExclusiveQueuedThreads(sync, t2);
+ sync.release();
+ awaitTermination(t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ }
+
+ /**
+ * getSharedQueuedThreads does not include exclusively waiting threads
+ */
+ public void testGetSharedQueuedThreads_Exclusive() {
+ final Mutex sync = new Mutex();
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ sync.acquire();
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t1);
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+ waitForQueuedThread(sync, t2);
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ sync.release();
+ awaitTermination(t2);
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ }
+
+ /**
+ * getSharedQueuedThreads returns all shared waiting threads
+ */
+ public void testGetSharedQueuedThreads_Shared() {
+ final BooleanLatch l = new BooleanLatch();
+ assertHasSharedQueuedThreads(l, NO_THREADS);
+ Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ l.acquireSharedInterruptibly(0);
+ }});
+ waitForQueuedThread(l, t1);
+ assertHasSharedQueuedThreads(l, t1);
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ l.acquireSharedInterruptibly(0);
+ }});
+ waitForQueuedThread(l, t2);
+ assertHasSharedQueuedThreads(l, t1, t2);
+ t1.interrupt();
+ awaitTermination(t1);
+ assertHasSharedQueuedThreads(l, t2);
+ assertTrue(l.releaseShared(0));
+ awaitTermination(t2);
+ assertHasSharedQueuedThreads(l, NO_THREADS);
+ }
+
+ /**
+ * tryAcquireNanos is interruptible
+ */
+ public void testTryAcquireNanos_Interruptible() {
+ final Mutex sync = new Mutex();
+ sync.acquire();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
+ }});
+
+ waitForQueuedThread(sync, t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * tryAcquire on exclusively held sync fails
+ */
+ public void testTryAcquireWhenSynced() {
+ final Mutex sync = new Mutex();
+ sync.acquire();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertFalse(sync.tryAcquire());
+ }});
+
+ awaitTermination(t);
+ sync.release();
+ }
+
+ /**
+ * tryAcquireNanos on an exclusively held sync times out
+ */
+ public void testAcquireNanos_Timeout() {
+ final Mutex sync = new Mutex();
+ sync.acquire();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ long nanos = MILLISECONDS.toNanos(timeoutMillis());
+ assertFalse(sync.tryAcquireNanos(nanos));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }});
+
+ awaitTermination(t);
+ sync.release();
+ }
+
+ /**
+ * getState is true when acquired and false when not
+ */
+ public void testGetState() {
+ final Mutex sync = new Mutex();
+ sync.acquire();
+ assertTrue(sync.isHeldExclusively());
+ sync.release();
+ assertFalse(sync.isHeldExclusively());
+
+ final BooleanLatch acquired = new BooleanLatch();
+ final BooleanLatch done = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertTrue(acquired.releaseShared(0));
+ done.acquireShared(0);
+ sync.release();
+ }});
+
+ acquired.acquireShared(0);
+ assertTrue(sync.isHeldExclusively());
+ assertTrue(done.releaseShared(0));
+ awaitTermination(t);
+ assertFalse(sync.isHeldExclusively());
+ }
+
+ /**
+ * acquireInterruptibly succeeds when released, else is interruptible
+ */
+ public void testAcquireInterruptibly() throws InterruptedException {
+ final Mutex sync = new Mutex();
+ final BooleanLatch threadStarted = new BooleanLatch();
+ sync.acquireInterruptibly();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertTrue(threadStarted.releaseShared(0));
+ sync.acquireInterruptibly();
+ }});
+
+ threadStarted.acquireShared(0);
+ waitForQueuedThread(sync, t);
+ t.interrupt();
+ awaitTermination(t);
+ assertTrue(sync.isHeldExclusively());
+ }
+
+ /**
+ * owns is true for a condition created by sync else false
+ */
+ public void testOwns() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final Mutex sync2 = new Mutex();
+ assertTrue(sync.owns(c));
+ assertFalse(sync2.owns(c));
+ }
+
+ /**
+ * Calling await without holding sync throws IllegalMonitorStateException
+ */
+ public void testAwait_IMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ for (AwaitMethod awaitMethod : AwaitMethod.values()) {
+ long startTime = System.nanoTime();
+ try {
+ await(c, awaitMethod);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {
+ } catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ }
+
+ /**
+ * Calling signal without holding sync throws IllegalMonitorStateException
+ */
+ public void testSignal_IMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ c.signal();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * Calling signalAll without holding sync throws IllegalMonitorStateException
+ */
+ public void testSignalAll_IMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ c.signalAll();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * await/awaitNanos/awaitUntil without a signal times out
+ */
+ public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
+ public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
+ public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
+ public void testAwait_Timeout(AwaitMethod awaitMethod) {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ sync.acquire();
+ assertAwaitTimesOut(c, awaitMethod);
+ sync.release();
+ }
+
+ /**
+ * await/awaitNanos/awaitUntil returns when signalled
+ */
+ public void testSignal_await() { testSignal(AwaitMethod.await); }
+ public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
+ public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
+ public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
+ public void testSignal(final AwaitMethod awaitMethod) {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertTrue(acquired.releaseShared(0));
+ await(c, awaitMethod);
+ sync.release();
+ }});
+
+ acquired.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ c.signal();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t);
+ sync.release();
+ awaitTermination(t);
+ }
+
+ /**
+ * hasWaiters(null) throws NullPointerException
+ */
+ public void testHasWaitersNPE() {
+ final Mutex sync = new Mutex();
+ try {
+ sync.hasWaiters(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getWaitQueueLength(null) throws NullPointerException
+ */
+ public void testGetWaitQueueLengthNPE() {
+ final Mutex sync = new Mutex();
+ try {
+ sync.getWaitQueueLength(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getWaitingThreads throws NPE if null
+ */
+ public void testGetWaitingThreadsNPE() {
+ final Mutex sync = new Mutex();
+ try {
+ sync.getWaitingThreads(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * hasWaiters throws IllegalArgumentException if not owned
+ */
+ public void testHasWaitersIAE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final Mutex sync2 = new Mutex();
+ try {
+ sync2.hasWaiters(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * hasWaiters throws IllegalMonitorStateException if not synced
+ */
+ public void testHasWaitersIMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ sync.hasWaiters(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitQueueLength throws IllegalArgumentException if not owned
+ */
+ public void testGetWaitQueueLengthIAE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final Mutex sync2 = new Mutex();
+ try {
+ sync2.getWaitQueueLength(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitQueueLength throws IllegalMonitorStateException if not synced
+ */
+ public void testGetWaitQueueLengthIMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ sync.getWaitQueueLength(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitingThreads throws IllegalArgumentException if not owned
+ */
+ public void testGetWaitingThreadsIAE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final Mutex sync2 = new Mutex();
+ try {
+ sync2.getWaitingThreads(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitingThreads throws IllegalMonitorStateException if not synced
+ */
+ public void testGetWaitingThreadsIMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ sync.getWaitingThreads(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * hasWaiters returns true when a thread is waiting, else false
+ */
+ public void testHasWaiters() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertFalse(sync.hasWaiters(c));
+ assertTrue(acquired.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+
+ acquired.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ assertTrue(sync.hasWaiters(c));
+ c.signal();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t);
+ assertFalse(sync.hasWaiters(c));
+ sync.release();
+
+ awaitTermination(t);
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitQueueLength returns number of waiting threads
+ */
+ public void testGetWaitQueueLength() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired1 = new BooleanLatch();
+ final BooleanLatch acquired2 = new BooleanLatch();
+ final Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertEquals(0, sync.getWaitQueueLength(c));
+ assertTrue(acquired1.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+ acquired1.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1);
+ assertEquals(1, sync.getWaitQueueLength(c));
+ sync.release();
+
+ final Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1);
+ assertEquals(1, sync.getWaitQueueLength(c));
+ assertTrue(acquired2.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+ acquired2.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1, t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ assertEquals(2, sync.getWaitQueueLength(c));
+ c.signalAll();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ assertEquals(0, sync.getWaitQueueLength(c));
+ sync.release();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitingThreads returns only and all waiting threads
+ */
+ public void testGetWaitingThreads() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired1 = new BooleanLatch();
+ final BooleanLatch acquired2 = new BooleanLatch();
+ final Thread t1 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertTrue(sync.getWaitingThreads(c).isEmpty());
+ assertTrue(acquired1.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+
+ final Thread t2 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1);
+ assertTrue(sync.getWaitingThreads(c).contains(t1));
+ assertFalse(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(1, sync.getWaitingThreads(c).size());
+ assertTrue(acquired2.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertFalse(sync.getWaitingThreads(c).contains(t1));
+ assertFalse(sync.getWaitingThreads(c).contains(t2));
+ assertTrue(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(0, sync.getWaitingThreads(c).size());
+ sync.release();
+
+ t1.start();
+ acquired1.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1);
+ assertTrue(sync.getWaitingThreads(c).contains(t1));
+ assertFalse(sync.getWaitingThreads(c).contains(t2));
+ assertFalse(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(1, sync.getWaitingThreads(c).size());
+ sync.release();
+
+ t2.start();
+ acquired2.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1, t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ assertTrue(sync.getWaitingThreads(c).contains(t1));
+ assertTrue(sync.getWaitingThreads(c).contains(t2));
+ assertFalse(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(2, sync.getWaitingThreads(c).size());
+ c.signalAll();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ assertFalse(sync.getWaitingThreads(c).contains(t1));
+ assertFalse(sync.getWaitingThreads(c).contains(t2));
+ assertTrue(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(0, sync.getWaitingThreads(c).size());
+ sync.release();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * awaitUninterruptibly is uninterruptible
+ */
+ public void testAwaitUninterruptibly() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch pleaseInterrupt = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ sync.acquire();
+ assertTrue(pleaseInterrupt.releaseShared(0));
+ c.awaitUninterruptibly();
+ assertTrue(Thread.interrupted());
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ sync.release();
+ }});
+
+ pleaseInterrupt.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t);
+ sync.release();
+ t.interrupt();
+ assertHasWaitersUnlocked(sync, c, t);
+ assertThreadStaysAlive(t);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ c.signal();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t);
+ sync.release();
+ awaitTermination(t);
+ }
+
+ /**
+ * await/awaitNanos/awaitUntil is interruptible
+ */
+ public void testInterruptible_await() { testInterruptible(AwaitMethod.await); }
+ public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
+ public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
+ public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
+ public void testInterruptible(final AwaitMethod awaitMethod) {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch pleaseInterrupt = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertTrue(pleaseInterrupt.releaseShared(0));
+ await(c, awaitMethod);
+ }});
+
+ pleaseInterrupt.acquireShared(0);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * signalAll wakes up all threads
+ */
+ public void testSignalAll_await() { testSignalAll(AwaitMethod.await); }
+ public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
+ public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
+ public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
+ public void testSignalAll(final AwaitMethod awaitMethod) {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired1 = new BooleanLatch();
+ final BooleanLatch acquired2 = new BooleanLatch();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ acquired1.releaseShared(0);
+ await(c, awaitMethod);
+ sync.release();
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ acquired2.releaseShared(0);
+ await(c, awaitMethod);
+ sync.release();
+ }});
+
+ acquired1.acquireShared(0);
+ acquired2.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1, t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ c.signalAll();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ sync.release();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * toString indicates current state
+ */
+ public void testToString() {
+ Mutex sync = new Mutex();
+ assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
+ sync.acquire();
+ assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
+ }
+
+ /**
+ * A serialized AQS deserializes with current state, but no queued threads
+ */
+ public void testSerialization() {
+ Mutex sync = new Mutex();
+ assertFalse(serialClone(sync).isHeldExclusively());
+ sync.acquire();
+ Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t);
+ assertTrue(sync.isHeldExclusively());
+
+ Mutex clone = serialClone(sync);
+ assertTrue(clone.isHeldExclusively());
+ assertHasExclusiveQueuedThreads(sync, t);
+ assertHasExclusiveQueuedThreads(clone, NO_THREADS);
+ t.interrupt();
+ awaitTermination(t);
+ sync.release();
+ assertFalse(sync.isHeldExclusively());
+ assertTrue(clone.isHeldExclusively());
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ assertHasExclusiveQueuedThreads(clone, NO_THREADS);
+ }
+
+ /**
+ * tryReleaseShared setting state changes getState
+ */
+ public void testGetStateWithReleaseShared() {
+ final BooleanLatch l = new BooleanLatch();
+ assertFalse(l.isSignalled());
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ }
+
+ /**
+ * releaseShared has no effect when already signalled
+ */
+ public void testReleaseShared() {
+ final BooleanLatch l = new BooleanLatch();
+ assertFalse(l.isSignalled());
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ }
+
+ /**
+ * acquireSharedInterruptibly returns after release, but not before
+ */
+ public void testAcquireSharedInterruptibly() {
+ final BooleanLatch l = new BooleanLatch();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ l.acquireSharedInterruptibly(0);
+ assertTrue(l.isSignalled());
+ l.acquireSharedInterruptibly(0);
+ assertTrue(l.isSignalled());
+ }});
+
+ waitForQueuedThread(l, t);
+ assertFalse(l.isSignalled());
+ assertThreadStaysAlive(t);
+ assertHasSharedQueuedThreads(l, t);
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ awaitTermination(t);
+ }
+
+ /**
+ * tryAcquireSharedNanos returns after release, but not before
+ */
+ public void testTryAcquireSharedNanos() {
+ final BooleanLatch l = new BooleanLatch();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
+ assertTrue(l.tryAcquireSharedNanos(0, nanos));
+ assertTrue(l.isSignalled());
+ assertTrue(l.tryAcquireSharedNanos(0, nanos));
+ assertTrue(l.isSignalled());
+ }});
+
+ waitForQueuedThread(l, t);
+ assertFalse(l.isSignalled());
+ assertThreadStaysAlive(t);
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ awaitTermination(t);
+ }
+
+ /**
+ * acquireSharedInterruptibly is interruptible
+ */
+ public void testAcquireSharedInterruptibly_Interruptible() {
+ final BooleanLatch l = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ l.acquireSharedInterruptibly(0);
+ }});
+
+ waitForQueuedThread(l, t);
+ assertFalse(l.isSignalled());
+ t.interrupt();
+ awaitTermination(t);
+ assertFalse(l.isSignalled());
+ }
+
+ /**
+ * tryAcquireSharedNanos is interruptible
+ */
+ public void testTryAcquireSharedNanos_Interruptible() {
+ final BooleanLatch l = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
+ l.tryAcquireSharedNanos(0, nanos);
+ }});
+
+ waitForQueuedThread(l, t);
+ assertFalse(l.isSignalled());
+ t.interrupt();
+ awaitTermination(t);
+ assertFalse(l.isSignalled());
+ }
+
+ /**
+ * tryAcquireSharedNanos times out if not released before timeout
+ */
+ public void testTryAcquireSharedNanos_Timeout() {
+ final BooleanLatch l = new BooleanLatch();
+ final BooleanLatch observedQueued = new BooleanLatch();
+ final long timeoutMillis = timeoutMillis();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ for (long millis = timeoutMillis();
+ !observedQueued.isSignalled();
+ millis *= 2) {
+ long nanos = MILLISECONDS.toNanos(millis);
+ long startTime = System.nanoTime();
+ assertFalse(l.tryAcquireSharedNanos(0, nanos));
+ assertTrue(millisElapsedSince(startTime) >= millis);
+ }
+ assertFalse(l.isSignalled());
+ }});
+
+ waitForQueuedThread(l, t);
+ observedQueued.releaseShared(0);
+ assertFalse(l.isSignalled());
+ awaitTermination(t);
+ assertFalse(l.isSignalled());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java
new file mode 100644
index 0000000..b9dab06
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java
@@ -0,0 +1,1212 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject;
+
+public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
+
+ /**
+ * A simple mutex class, adapted from the class javadoc. Exclusive
+ * acquire tests exercise this as a sample user extension. Other
+ * methods/features of AbstractQueuedSynchronizer are tested via
+ * other test classes, including those for ReentrantLock,
+ * ReentrantReadWriteLock, and Semaphore.
+ */
+ static class Mutex extends AbstractQueuedSynchronizer {
+ /** An eccentric value for locked synchronizer state. */
+ static final int LOCKED = (1 << 31) | (1 << 15);
+
+ static final int UNLOCKED = 0;
+
+ @Override public boolean isHeldExclusively() {
+ int state = getState();
+ assertTrue(state == UNLOCKED || state == LOCKED);
+ return state == LOCKED;
+ }
+
+ @Override public boolean tryAcquire(int acquires) {
+ assertEquals(LOCKED, acquires);
+ return compareAndSetState(UNLOCKED, LOCKED);
+ }
+
+ @Override public boolean tryRelease(int releases) {
+ if (getState() != LOCKED) throw new IllegalMonitorStateException();
+ assertEquals(LOCKED, releases);
+ setState(UNLOCKED);
+ return true;
+ }
+
+ public boolean tryAcquireNanos(long nanos) throws InterruptedException {
+ return tryAcquireNanos(LOCKED, nanos);
+ }
+
+ public boolean tryAcquire() {
+ return tryAcquire(LOCKED);
+ }
+
+ public boolean tryRelease() {
+ return tryRelease(LOCKED);
+ }
+
+ public void acquire() {
+ acquire(LOCKED);
+ }
+
+ public void acquireInterruptibly() throws InterruptedException {
+ acquireInterruptibly(LOCKED);
+ }
+
+ public void release() {
+ release(LOCKED);
+ }
+
+ public ConditionObject newCondition() {
+ return new ConditionObject();
+ }
+ }
+
+ /**
+ * A simple latch class, to test shared mode.
+ */
+ static class BooleanLatch extends AbstractQueuedSynchronizer {
+ public boolean isSignalled() { return getState() != 0; }
+
+ public int tryAcquireShared(int ignore) {
+ return isSignalled() ? 1 : -1;
+ }
+
+ public boolean tryReleaseShared(int ignore) {
+ setState(1);
+ return true;
+ }
+ }
+
+ /**
+ * A runnable calling acquireInterruptibly that does not expect to
+ * be interrupted.
+ */
+ class InterruptibleSyncRunnable extends CheckedRunnable {
+ final Mutex sync;
+ InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
+ public void realRun() throws InterruptedException {
+ sync.acquireInterruptibly();
+ }
+ }
+
+ /**
+ * A runnable calling acquireInterruptibly that expects to be
+ * interrupted.
+ */
+ class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
+ final Mutex sync;
+ InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
+ public void realRun() throws InterruptedException {
+ sync.acquireInterruptibly();
+ }
+ }
+
+ /** A constant to clarify calls to checking methods below. */
+ static final Thread[] NO_THREADS = new Thread[0];
+
+ /**
+ * Spin-waits until sync.isQueued(t) becomes true.
+ */
+ void waitForQueuedThread(AbstractQueuedSynchronizer sync, Thread t) {
+ long startTime = System.nanoTime();
+ while (!sync.isQueued(t)) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ throw new AssertionFailedError("timed out");
+ Thread.yield();
+ }
+ assertTrue(t.isAlive());
+ }
+
+ /**
+ * Checks that sync has exactly the given queued threads.
+ */
+ void assertHasQueuedThreads(AbstractQueuedSynchronizer sync,
+ Thread... expected) {
+ Collection<Thread> actual = sync.getQueuedThreads();
+ assertEquals(expected.length > 0, sync.hasQueuedThreads());
+ assertEquals(expected.length, sync.getQueueLength());
+ assertEquals(expected.length, actual.size());
+ assertEquals(expected.length == 0, actual.isEmpty());
+ assertEquals(new HashSet<Thread>(actual),
+ new HashSet<Thread>(Arrays.asList(expected)));
+ }
+
+ /**
+ * Checks that sync has exactly the given (exclusive) queued threads.
+ */
+ void assertHasExclusiveQueuedThreads(AbstractQueuedSynchronizer sync,
+ Thread... expected) {
+ assertHasQueuedThreads(sync, expected);
+ assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
+ new HashSet<Thread>(sync.getQueuedThreads()));
+ assertEquals(0, sync.getSharedQueuedThreads().size());
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ }
+
+ /**
+ * Checks that sync has exactly the given (shared) queued threads.
+ */
+ void assertHasSharedQueuedThreads(AbstractQueuedSynchronizer sync,
+ Thread... expected) {
+ assertHasQueuedThreads(sync, expected);
+ assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
+ new HashSet<Thread>(sync.getQueuedThreads()));
+ assertEquals(0, sync.getExclusiveQueuedThreads().size());
+ assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+ }
+
+ /**
+ * Checks that condition c has exactly the given waiter threads,
+ * after acquiring mutex.
+ */
+ void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
+ Thread... threads) {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, threads);
+ sync.release();
+ }
+
+ /**
+ * Checks that condition c has exactly the given waiter threads.
+ */
+ void assertHasWaitersLocked(Mutex sync, ConditionObject c,
+ Thread... threads) {
+ assertEquals(threads.length > 0, sync.hasWaiters(c));
+ assertEquals(threads.length, sync.getWaitQueueLength(c));
+ assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
+ assertEquals(threads.length, sync.getWaitingThreads(c).size());
+ assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
+ new HashSet<Thread>(Arrays.asList(threads)));
+ }
+
+ enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
+
+ /**
+ * Awaits condition using the specified AwaitMethod.
+ */
+ void await(ConditionObject c, AwaitMethod awaitMethod)
+ throws InterruptedException {
+ long timeoutMillis = 2 * LONG_DELAY_MS;
+ switch (awaitMethod) {
+ case await:
+ c.await();
+ break;
+ case awaitTimed:
+ assertTrue(c.await(timeoutMillis, MILLISECONDS));
+ break;
+ case awaitNanos:
+ long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+ long nanosRemaining = c.awaitNanos(nanosTimeout);
+ assertTrue(nanosRemaining > 0);
+ break;
+ case awaitUntil:
+ assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
+ break;
+ }
+ }
+
+ /**
+ * Checks that awaiting the given condition times out (using the
+ * default timeout duration).
+ */
+ void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
+ long timeoutMillis = timeoutMillis();
+ long startTime = System.nanoTime();
+ try {
+ switch (awaitMethod) {
+ case awaitTimed:
+ assertFalse(c.await(timeoutMillis, MILLISECONDS));
+ break;
+ case awaitNanos:
+ long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+ long nanosRemaining = c.awaitNanos(nanosTimeout);
+ assertTrue(nanosRemaining <= 0);
+ break;
+ case awaitUntil:
+ assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
+ break;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ } catch (InterruptedException ie) { threadUnexpectedException(ie); }
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ }
+
+ /**
+ * isHeldExclusively is false upon construction
+ */
+ public void testIsHeldExclusively() {
+ Mutex sync = new Mutex();
+ assertFalse(sync.isHeldExclusively());
+ }
+
+ /**
+ * acquiring released sync succeeds
+ */
+ public void testAcquire() {
+ Mutex sync = new Mutex();
+ sync.acquire();
+ assertTrue(sync.isHeldExclusively());
+ sync.release();
+ assertFalse(sync.isHeldExclusively());
+ }
+
+ /**
+ * tryAcquire on a released sync succeeds
+ */
+ public void testTryAcquire() {
+ Mutex sync = new Mutex();
+ assertTrue(sync.tryAcquire());
+ assertTrue(sync.isHeldExclusively());
+ sync.release();
+ assertFalse(sync.isHeldExclusively());
+ }
+
+ /**
+ * hasQueuedThreads reports whether there are waiting threads
+ */
+ public void testHasQueuedThreads() {
+ final Mutex sync = new Mutex();
+ assertFalse(sync.hasQueuedThreads());
+ sync.acquire();
+ Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t1);
+ assertTrue(sync.hasQueuedThreads());
+ Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+ waitForQueuedThread(sync, t2);
+ assertTrue(sync.hasQueuedThreads());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(sync.hasQueuedThreads());
+ sync.release();
+ awaitTermination(t2);
+ assertFalse(sync.hasQueuedThreads());
+ }
+
+ /**
+ * isQueued(null) throws NullPointerException
+ */
+ public void testIsQueuedNPE() {
+ final Mutex sync = new Mutex();
+ try {
+ sync.isQueued(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * isQueued reports whether a thread is queued
+ */
+ public void testIsQueued() {
+ final Mutex sync = new Mutex();
+ Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+ Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+ assertFalse(sync.isQueued(t1));
+ assertFalse(sync.isQueued(t2));
+ sync.acquire();
+ t1.start();
+ waitForQueuedThread(sync, t1);
+ assertTrue(sync.isQueued(t1));
+ assertFalse(sync.isQueued(t2));
+ t2.start();
+ waitForQueuedThread(sync, t2);
+ assertTrue(sync.isQueued(t1));
+ assertTrue(sync.isQueued(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertFalse(sync.isQueued(t1));
+ assertTrue(sync.isQueued(t2));
+ sync.release();
+ awaitTermination(t2);
+ assertFalse(sync.isQueued(t1));
+ assertFalse(sync.isQueued(t2));
+ }
+
+ /**
+ * getFirstQueuedThread returns first waiting thread or null if none
+ */
+ public void testGetFirstQueuedThread() {
+ final Mutex sync = new Mutex();
+ assertNull(sync.getFirstQueuedThread());
+ sync.acquire();
+ Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t1);
+ assertEquals(t1, sync.getFirstQueuedThread());
+ Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+ waitForQueuedThread(sync, t2);
+ assertEquals(t1, sync.getFirstQueuedThread());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertEquals(t2, sync.getFirstQueuedThread());
+ sync.release();
+ awaitTermination(t2);
+ assertNull(sync.getFirstQueuedThread());
+ }
+
+ /**
+ * hasContended reports false if no thread has ever blocked, else true
+ */
+ public void testHasContended() {
+ final Mutex sync = new Mutex();
+ assertFalse(sync.hasContended());
+ sync.acquire();
+ assertFalse(sync.hasContended());
+ Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t1);
+ assertTrue(sync.hasContended());
+ Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+ waitForQueuedThread(sync, t2);
+ assertTrue(sync.hasContended());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(sync.hasContended());
+ sync.release();
+ awaitTermination(t2);
+ assertTrue(sync.hasContended());
+ }
+
+ /**
+ * getQueuedThreads returns all waiting threads
+ */
+ public void testGetQueuedThreads() {
+ final Mutex sync = new Mutex();
+ Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+ Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ sync.acquire();
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ t1.start();
+ waitForQueuedThread(sync, t1);
+ assertHasExclusiveQueuedThreads(sync, t1);
+ assertTrue(sync.getQueuedThreads().contains(t1));
+ assertFalse(sync.getQueuedThreads().contains(t2));
+ t2.start();
+ waitForQueuedThread(sync, t2);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ assertTrue(sync.getQueuedThreads().contains(t1));
+ assertTrue(sync.getQueuedThreads().contains(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertHasExclusiveQueuedThreads(sync, t2);
+ sync.release();
+ awaitTermination(t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ }
+
+ /**
+ * getExclusiveQueuedThreads returns all exclusive waiting threads
+ */
+ public void testGetExclusiveQueuedThreads() {
+ final Mutex sync = new Mutex();
+ Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+ Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ sync.acquire();
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ t1.start();
+ waitForQueuedThread(sync, t1);
+ assertHasExclusiveQueuedThreads(sync, t1);
+ assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+ assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
+ t2.start();
+ waitForQueuedThread(sync, t2);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+ assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertHasExclusiveQueuedThreads(sync, t2);
+ sync.release();
+ awaitTermination(t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ }
+
+ /**
+ * getSharedQueuedThreads does not include exclusively waiting threads
+ */
+ public void testGetSharedQueuedThreads_Exclusive() {
+ final Mutex sync = new Mutex();
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ sync.acquire();
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t1);
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+ waitForQueuedThread(sync, t2);
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ sync.release();
+ awaitTermination(t2);
+ assertTrue(sync.getSharedQueuedThreads().isEmpty());
+ }
+
+ /**
+ * getSharedQueuedThreads returns all shared waiting threads
+ */
+ public void testGetSharedQueuedThreads_Shared() {
+ final BooleanLatch l = new BooleanLatch();
+ assertHasSharedQueuedThreads(l, NO_THREADS);
+ Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ l.acquireSharedInterruptibly(0);
+ }});
+ waitForQueuedThread(l, t1);
+ assertHasSharedQueuedThreads(l, t1);
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ l.acquireSharedInterruptibly(0);
+ }});
+ waitForQueuedThread(l, t2);
+ assertHasSharedQueuedThreads(l, t1, t2);
+ t1.interrupt();
+ awaitTermination(t1);
+ assertHasSharedQueuedThreads(l, t2);
+ assertTrue(l.releaseShared(0));
+ awaitTermination(t2);
+ assertHasSharedQueuedThreads(l, NO_THREADS);
+ }
+
+ /**
+ * tryAcquireNanos is interruptible
+ */
+ public void testTryAcquireNanos_Interruptible() {
+ final Mutex sync = new Mutex();
+ sync.acquire();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
+ }});
+
+ waitForQueuedThread(sync, t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * tryAcquire on exclusively held sync fails
+ */
+ public void testTryAcquireWhenSynced() {
+ final Mutex sync = new Mutex();
+ sync.acquire();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertFalse(sync.tryAcquire());
+ }});
+
+ awaitTermination(t);
+ sync.release();
+ }
+
+ /**
+ * tryAcquireNanos on an exclusively held sync times out
+ */
+ public void testAcquireNanos_Timeout() {
+ final Mutex sync = new Mutex();
+ sync.acquire();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ long nanos = MILLISECONDS.toNanos(timeoutMillis());
+ assertFalse(sync.tryAcquireNanos(nanos));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }});
+
+ awaitTermination(t);
+ sync.release();
+ }
+
+ /**
+ * getState is true when acquired and false when not
+ */
+ public void testGetState() {
+ final Mutex sync = new Mutex();
+ sync.acquire();
+ assertTrue(sync.isHeldExclusively());
+ sync.release();
+ assertFalse(sync.isHeldExclusively());
+
+ final BooleanLatch acquired = new BooleanLatch();
+ final BooleanLatch done = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertTrue(acquired.releaseShared(0));
+ done.acquireShared(0);
+ sync.release();
+ }});
+
+ acquired.acquireShared(0);
+ assertTrue(sync.isHeldExclusively());
+ assertTrue(done.releaseShared(0));
+ awaitTermination(t);
+ assertFalse(sync.isHeldExclusively());
+ }
+
+ /**
+ * acquireInterruptibly succeeds when released, else is interruptible
+ */
+ public void testAcquireInterruptibly() throws InterruptedException {
+ final Mutex sync = new Mutex();
+ final BooleanLatch threadStarted = new BooleanLatch();
+ sync.acquireInterruptibly();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertTrue(threadStarted.releaseShared(0));
+ sync.acquireInterruptibly();
+ }});
+
+ threadStarted.acquireShared(0);
+ waitForQueuedThread(sync, t);
+ t.interrupt();
+ awaitTermination(t);
+ assertTrue(sync.isHeldExclusively());
+ }
+
+ /**
+ * owns is true for a condition created by sync else false
+ */
+ public void testOwns() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final Mutex sync2 = new Mutex();
+ assertTrue(sync.owns(c));
+ assertFalse(sync2.owns(c));
+ }
+
+ /**
+ * Calling await without holding sync throws IllegalMonitorStateException
+ */
+ public void testAwait_IMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ for (AwaitMethod awaitMethod : AwaitMethod.values()) {
+ long startTime = System.nanoTime();
+ try {
+ await(c, awaitMethod);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {
+ } catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ }
+
+ /**
+ * Calling signal without holding sync throws IllegalMonitorStateException
+ */
+ public void testSignal_IMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ c.signal();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * Calling signalAll without holding sync throws IllegalMonitorStateException
+ */
+ public void testSignalAll_IMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ c.signalAll();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * await/awaitNanos/awaitUntil without a signal times out
+ */
+ public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
+ public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
+ public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
+ public void testAwait_Timeout(AwaitMethod awaitMethod) {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ sync.acquire();
+ assertAwaitTimesOut(c, awaitMethod);
+ sync.release();
+ }
+
+ /**
+ * await/awaitNanos/awaitUntil returns when signalled
+ */
+ public void testSignal_await() { testSignal(AwaitMethod.await); }
+ public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
+ public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
+ public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
+ public void testSignal(final AwaitMethod awaitMethod) {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertTrue(acquired.releaseShared(0));
+ await(c, awaitMethod);
+ sync.release();
+ }});
+
+ acquired.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ c.signal();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t);
+ sync.release();
+ awaitTermination(t);
+ }
+
+ /**
+ * hasWaiters(null) throws NullPointerException
+ */
+ public void testHasWaitersNPE() {
+ final Mutex sync = new Mutex();
+ try {
+ sync.hasWaiters(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getWaitQueueLength(null) throws NullPointerException
+ */
+ public void testGetWaitQueueLengthNPE() {
+ final Mutex sync = new Mutex();
+ try {
+ sync.getWaitQueueLength(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getWaitingThreads(null) throws NullPointerException
+ */
+ public void testGetWaitingThreadsNPE() {
+ final Mutex sync = new Mutex();
+ try {
+ sync.getWaitingThreads(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * hasWaiters throws IllegalArgumentException if not owned
+ */
+ public void testHasWaitersIAE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final Mutex sync2 = new Mutex();
+ try {
+ sync2.hasWaiters(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * hasWaiters throws IllegalMonitorStateException if not synced
+ */
+ public void testHasWaitersIMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ sync.hasWaiters(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitQueueLength throws IllegalArgumentException if not owned
+ */
+ public void testGetWaitQueueLengthIAE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final Mutex sync2 = new Mutex();
+ try {
+ sync2.getWaitQueueLength(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitQueueLength throws IllegalMonitorStateException if not synced
+ */
+ public void testGetWaitQueueLengthIMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ sync.getWaitQueueLength(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitingThreads throws IllegalArgumentException if not owned
+ */
+ public void testGetWaitingThreadsIAE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final Mutex sync2 = new Mutex();
+ try {
+ sync2.getWaitingThreads(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitingThreads throws IllegalMonitorStateException if not synced
+ */
+ public void testGetWaitingThreadsIMSE() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ try {
+ sync.getWaitingThreads(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * hasWaiters returns true when a thread is waiting, else false
+ */
+ public void testHasWaiters() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertFalse(sync.hasWaiters(c));
+ assertTrue(acquired.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+
+ acquired.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ assertTrue(sync.hasWaiters(c));
+ c.signal();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t);
+ assertFalse(sync.hasWaiters(c));
+ sync.release();
+
+ awaitTermination(t);
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitQueueLength returns number of waiting threads
+ */
+ public void testGetWaitQueueLength() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired1 = new BooleanLatch();
+ final BooleanLatch acquired2 = new BooleanLatch();
+ final Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertEquals(0, sync.getWaitQueueLength(c));
+ assertTrue(acquired1.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+ acquired1.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1);
+ assertEquals(1, sync.getWaitQueueLength(c));
+ sync.release();
+
+ final Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1);
+ assertEquals(1, sync.getWaitQueueLength(c));
+ assertTrue(acquired2.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+ acquired2.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1, t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ assertEquals(2, sync.getWaitQueueLength(c));
+ c.signalAll();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ assertEquals(0, sync.getWaitQueueLength(c));
+ sync.release();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * getWaitingThreads returns only and all waiting threads
+ */
+ public void testGetWaitingThreads() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired1 = new BooleanLatch();
+ final BooleanLatch acquired2 = new BooleanLatch();
+ final Thread t1 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertTrue(sync.getWaitingThreads(c).isEmpty());
+ assertTrue(acquired1.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+
+ final Thread t2 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1);
+ assertTrue(sync.getWaitingThreads(c).contains(t1));
+ assertFalse(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(1, sync.getWaitingThreads(c).size());
+ assertTrue(acquired2.releaseShared(0));
+ c.await();
+ sync.release();
+ }});
+
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertFalse(sync.getWaitingThreads(c).contains(t1));
+ assertFalse(sync.getWaitingThreads(c).contains(t2));
+ assertTrue(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(0, sync.getWaitingThreads(c).size());
+ sync.release();
+
+ t1.start();
+ acquired1.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1);
+ assertTrue(sync.getWaitingThreads(c).contains(t1));
+ assertFalse(sync.getWaitingThreads(c).contains(t2));
+ assertFalse(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(1, sync.getWaitingThreads(c).size());
+ sync.release();
+
+ t2.start();
+ acquired2.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1, t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ assertTrue(sync.getWaitingThreads(c).contains(t1));
+ assertTrue(sync.getWaitingThreads(c).contains(t2));
+ assertFalse(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(2, sync.getWaitingThreads(c).size());
+ c.signalAll();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ assertFalse(sync.getWaitingThreads(c).contains(t1));
+ assertFalse(sync.getWaitingThreads(c).contains(t2));
+ assertTrue(sync.getWaitingThreads(c).isEmpty());
+ assertEquals(0, sync.getWaitingThreads(c).size());
+ sync.release();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertHasWaitersUnlocked(sync, c, NO_THREADS);
+ }
+
+ /**
+ * awaitUninterruptibly is uninterruptible
+ */
+ public void testAwaitUninterruptibly() {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch pleaseInterrupt = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ sync.acquire();
+ assertTrue(pleaseInterrupt.releaseShared(0));
+ c.awaitUninterruptibly();
+ assertTrue(Thread.interrupted());
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ sync.release();
+ }});
+
+ pleaseInterrupt.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t);
+ sync.release();
+ t.interrupt();
+ assertHasWaitersUnlocked(sync, c, t);
+ assertThreadStaysAlive(t);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ c.signal();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t);
+ sync.release();
+ awaitTermination(t);
+ }
+
+ /**
+ * await/awaitNanos/awaitUntil is interruptible
+ */
+ public void testInterruptible_await() { testInterruptible(AwaitMethod.await); }
+ public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
+ public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
+ public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
+ public void testInterruptible(final AwaitMethod awaitMethod) {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch pleaseInterrupt = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ assertTrue(pleaseInterrupt.releaseShared(0));
+ await(c, awaitMethod);
+ }});
+
+ pleaseInterrupt.acquireShared(0);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * signalAll wakes up all threads
+ */
+ public void testSignalAll_await() { testSignalAll(AwaitMethod.await); }
+ public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
+ public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
+ public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
+ public void testSignalAll(final AwaitMethod awaitMethod) {
+ final Mutex sync = new Mutex();
+ final ConditionObject c = sync.newCondition();
+ final BooleanLatch acquired1 = new BooleanLatch();
+ final BooleanLatch acquired2 = new BooleanLatch();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ acquired1.releaseShared(0);
+ await(c, awaitMethod);
+ sync.release();
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ sync.acquire();
+ acquired2.releaseShared(0);
+ await(c, awaitMethod);
+ sync.release();
+ }});
+
+ acquired1.acquireShared(0);
+ acquired2.acquireShared(0);
+ sync.acquire();
+ assertHasWaitersLocked(sync, c, t1, t2);
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ c.signalAll();
+ assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasExclusiveQueuedThreads(sync, t1, t2);
+ sync.release();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * toString indicates current state
+ */
+ public void testToString() {
+ Mutex sync = new Mutex();
+ assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
+ sync.acquire();
+ assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
+ }
+
+ /**
+ * A serialized AQS deserializes with current state, but no queued threads
+ */
+ public void testSerialization() {
+ Mutex sync = new Mutex();
+ assertFalse(serialClone(sync).isHeldExclusively());
+ sync.acquire();
+ Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
+ waitForQueuedThread(sync, t);
+ assertTrue(sync.isHeldExclusively());
+
+ Mutex clone = serialClone(sync);
+ assertTrue(clone.isHeldExclusively());
+ assertHasExclusiveQueuedThreads(sync, t);
+ assertHasExclusiveQueuedThreads(clone, NO_THREADS);
+ t.interrupt();
+ awaitTermination(t);
+ sync.release();
+ assertFalse(sync.isHeldExclusively());
+ assertTrue(clone.isHeldExclusively());
+ assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+ assertHasExclusiveQueuedThreads(clone, NO_THREADS);
+ }
+
+ /**
+ * tryReleaseShared setting state changes getState
+ */
+ public void testGetStateWithReleaseShared() {
+ final BooleanLatch l = new BooleanLatch();
+ assertFalse(l.isSignalled());
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ }
+
+ /**
+ * releaseShared has no effect when already signalled
+ */
+ public void testReleaseShared() {
+ final BooleanLatch l = new BooleanLatch();
+ assertFalse(l.isSignalled());
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ }
+
+ /**
+ * acquireSharedInterruptibly returns after release, but not before
+ */
+ public void testAcquireSharedInterruptibly() {
+ final BooleanLatch l = new BooleanLatch();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ l.acquireSharedInterruptibly(0);
+ assertTrue(l.isSignalled());
+ l.acquireSharedInterruptibly(0);
+ assertTrue(l.isSignalled());
+ }});
+
+ waitForQueuedThread(l, t);
+ assertFalse(l.isSignalled());
+ assertThreadStaysAlive(t);
+ assertHasSharedQueuedThreads(l, t);
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ awaitTermination(t);
+ }
+
+ /**
+ * tryAcquireSharedNanos returns after release, but not before
+ */
+ public void testTryAcquireSharedNanos() {
+ final BooleanLatch l = new BooleanLatch();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
+ assertTrue(l.tryAcquireSharedNanos(0, nanos));
+ assertTrue(l.isSignalled());
+ assertTrue(l.tryAcquireSharedNanos(0, nanos));
+ assertTrue(l.isSignalled());
+ }});
+
+ waitForQueuedThread(l, t);
+ assertFalse(l.isSignalled());
+ assertThreadStaysAlive(t);
+ assertTrue(l.releaseShared(0));
+ assertTrue(l.isSignalled());
+ awaitTermination(t);
+ }
+
+ /**
+ * acquireSharedInterruptibly is interruptible
+ */
+ public void testAcquireSharedInterruptibly_Interruptible() {
+ final BooleanLatch l = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ l.acquireSharedInterruptibly(0);
+ }});
+
+ waitForQueuedThread(l, t);
+ assertFalse(l.isSignalled());
+ t.interrupt();
+ awaitTermination(t);
+ assertFalse(l.isSignalled());
+ }
+
+ /**
+ * tryAcquireSharedNanos is interruptible
+ */
+ public void testTryAcquireSharedNanos_Interruptible() {
+ final BooleanLatch l = new BooleanLatch();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
+ l.tryAcquireSharedNanos(0, nanos);
+ }});
+
+ waitForQueuedThread(l, t);
+ assertFalse(l.isSignalled());
+ t.interrupt();
+ awaitTermination(t);
+ assertFalse(l.isSignalled());
+ }
+
+ /**
+ * tryAcquireSharedNanos times out if not released before timeout
+ */
+ public void testTryAcquireSharedNanos_Timeout() {
+ final BooleanLatch l = new BooleanLatch();
+ final BooleanLatch observedQueued = new BooleanLatch();
+ final long timeoutMillis = timeoutMillis();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(l.isSignalled());
+ for (long millis = timeoutMillis();
+ !observedQueued.isSignalled();
+ millis *= 2) {
+ long nanos = MILLISECONDS.toNanos(millis);
+ long startTime = System.nanoTime();
+ assertFalse(l.tryAcquireSharedNanos(0, nanos));
+ assertTrue(millisElapsedSince(startTime) >= millis);
+ }
+ assertFalse(l.isSignalled());
+ }});
+
+ waitForQueuedThread(l, t);
+ observedQueued.releaseShared(0);
+ assertFalse(l.isSignalled());
+ awaitTermination(t);
+ assertFalse(l.isSignalled());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueFairTest.java b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueFairTest.java
new file mode 100644
index 0000000..d6ed081
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueFairTest.java
@@ -0,0 +1,25 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+// In the upstream sources this class was nested inside ArrayBlockingQueueTests.
+// It was extracted to the top level because the CTS runner does not support
+// nested test classes. The same transformation was applied to all similar
+// classes from the jsr166 suite (see the parent CL for the complete list). This
+// should be reverted after CTS runner is fixed.
+public class ArrayBlockingQueueFairTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new ArrayBlockingQueue(SIZE, true);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNotFairTest.java b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNotFairTest.java
new file mode 100644
index 0000000..ddb1c5d
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueNotFairTest.java
@@ -0,0 +1,20 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+public class ArrayBlockingQueueNotFairTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new ArrayBlockingQueue(SIZE, false);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java
new file mode 100644
index 0000000..b999496
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java
@@ -0,0 +1,879 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class ArrayBlockingQueueTest extends JSR166TestCase {
+
+ /**
+ * Returns a new queue of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private ArrayBlockingQueue<Integer> populatedQueue(int n) {
+ ArrayBlockingQueue<Integer> q = new ArrayBlockingQueue<Integer>(n);
+ assertTrue(q.isEmpty());
+ for (int i = 0; i < n; i++)
+ assertTrue(q.offer(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(0, q.remainingCapacity());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * A new queue has the indicated capacity
+ */
+ public void testConstructor1() {
+ assertEquals(SIZE, new ArrayBlockingQueue(SIZE).remainingCapacity());
+ }
+
+ /**
+ * Constructor throws IAE if capacity argument nonpositive
+ */
+ public void testConstructor2() {
+ try {
+ new ArrayBlockingQueue(0);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ new ArrayBlockingQueue(1, true, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+ try {
+ new ArrayBlockingQueue(SIZE, false, elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = i;
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ new ArrayBlockingQueue(SIZE, false, Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from too large collection throws IAE
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = i;
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ new ArrayBlockingQueue(SIZE - 1, false, elements);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Queue contains all elements of collection used to initialize
+ */
+ public void testConstructor7() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = i;
+ Collection<Integer> elements = Arrays.asList(ints);
+ ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, true, elements);
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * Queue transitions from empty to full when elements added
+ */
+ public void testEmptyFull() {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(2);
+ assertTrue(q.isEmpty());
+ assertEquals(2, q.remainingCapacity());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ q.add(two);
+ assertFalse(q.isEmpty());
+ assertEquals(0, q.remainingCapacity());
+ assertFalse(q.offer(three));
+ }
+
+ /**
+ * remainingCapacity decreases on add, increases on remove
+ */
+ public void testRemainingCapacity() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remainingCapacity());
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.remainingCapacity());
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * Offer succeeds if not full; fails if full
+ */
+ public void testOffer() {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(1);
+ assertTrue(q.offer(zero));
+ assertFalse(q.offer(one));
+ }
+
+ /**
+ * add succeeds if not full; throws ISE if full
+ */
+ public void testAdd() {
+ try {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.add(new Integer(i)));
+ }
+ assertEquals(0, q.remainingCapacity());
+ q.add(new Integer(SIZE));
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * addAll(this) throws IAE
+ */
+ public void testAddAllSelf() {
+ try {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll throws ISE if not enough room
+ */
+ public void testAddAll4() {
+ try {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(1);
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * Queue contains all elements, in traversal order, of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * all elements successfully put are contained
+ */
+ public void testPut() throws InterruptedException {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ Integer I = new Integer(i);
+ q.put(I);
+ assertTrue(q.contains(I));
+ }
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * put blocks interruptibly if full
+ */
+ public void testBlockingPut() throws InterruptedException {
+ final ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i)
+ q.put(i);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * put blocks interruptibly waiting for take when full
+ */
+ public void testPutWithTake() throws InterruptedException {
+ final int capacity = 2;
+ final ArrayBlockingQueue q = new ArrayBlockingQueue(capacity);
+ final CountDownLatch pleaseTake = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < capacity; i++)
+ q.put(i);
+ pleaseTake.countDown();
+ q.put(86);
+
+ pleaseInterrupt.countDown();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseTake);
+ assertEquals(0, q.remainingCapacity());
+ assertEquals(0, q.take());
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * timed offer times out if full and elements not taken
+ */
+ public void testTimedOffer() throws InterruptedException {
+ final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(new Object());
+ q.put(new Object());
+ long startTime = System.nanoTime();
+ assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ pleaseInterrupt.countDown();
+ try {
+ q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * take retrieves elements in FIFO order
+ */
+ public void testTake() throws InterruptedException {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+ }
+
+ /**
+ * Take removes existing elements until empty, then blocks interruptibly
+ */
+ public void testBlockingTake() throws InterruptedException {
+ final ArrayBlockingQueue q = populatedQueue(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * timed poll with zero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll0() throws InterruptedException {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll(0, MILLISECONDS));
+ }
+ assertNull(q.poll(0, MILLISECONDS));
+ checkEmpty(q);
+ }
+
+ /**
+ * timed poll with nonzero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll() throws InterruptedException {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ long startTime = System.nanoTime();
+ assertEquals(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ checkEmpty(q);
+ }
+
+ /**
+ * Interrupted timed poll throws InterruptedException instead of
+ * returning timeout status
+ */
+ public void testInterruptedTimedPoll() throws InterruptedException {
+ final BlockingQueue<Integer> q = populatedQueue(SIZE);
+ final CountDownLatch aboutToWait = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ long t0 = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+ long t0 = System.nanoTime();
+ aboutToWait.countDown();
+ try {
+ q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {
+ assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+ }
+ }});
+
+ aboutToWait.await();
+ waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+ t.interrupt();
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ checkEmpty(q);
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.poll());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * element returns next element, or throws NSEE if empty
+ */
+ public void testElement() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ assertEquals(i, q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ assertEquals(i, q.poll());
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertEquals(SIZE, q.remainingCapacity());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(one));
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ ArrayBlockingQueue p = new ArrayBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ ArrayBlockingQueue p = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ ArrayBlockingQueue p = populatedQueue(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ void checkToArray(ArrayBlockingQueue q) {
+ int size = q.size();
+ Object[] o = q.toArray();
+ assertEquals(size, o.length);
+ Iterator it = q.iterator();
+ for (int i = 0; i < size; i++) {
+ Integer x = (Integer) it.next();
+ assertEquals((Integer)o[0] + i, (int) x);
+ assertSame(o[i], x);
+ }
+ }
+
+ /**
+ * toArray() contains all elements in FIFO order
+ */
+ public void testToArray() {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray(q);
+ q.add(i);
+ }
+ // Provoke wraparound
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray(q);
+ assertEquals(i, q.poll());
+ checkToArray(q);
+ q.add(SIZE+i);
+ }
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray(q);
+ assertEquals(SIZE+i, q.poll());
+ }
+ }
+
+ void checkToArray2(ArrayBlockingQueue q) {
+ int size = q.size();
+ Integer[] a1 = size == 0 ? null : new Integer[size-1];
+ Integer[] a2 = new Integer[size];
+ Integer[] a3 = new Integer[size+2];
+ if (size > 0) Arrays.fill(a1, 42);
+ Arrays.fill(a2, 42);
+ Arrays.fill(a3, 42);
+ Integer[] b1 = size == 0 ? null : (Integer[]) q.toArray(a1);
+ Integer[] b2 = (Integer[]) q.toArray(a2);
+ Integer[] b3 = (Integer[]) q.toArray(a3);
+ assertSame(a2, b2);
+ assertSame(a3, b3);
+ Iterator it = q.iterator();
+ for (int i = 0; i < size; i++) {
+ Integer x = (Integer) it.next();
+ assertSame(b1[i], x);
+ assertEquals(b1[0] + i, (int) x);
+ assertSame(b2[i], x);
+ assertSame(b3[i], x);
+ }
+ assertNull(a3[size]);
+ assertEquals(42, (int) a3[size+1]);
+ if (size > 0) {
+ assertNotSame(a1, b1);
+ assertEquals(size, b1.length);
+ for (int i = 0; i < a1.length; i++) {
+ assertEquals(42, (int) a1[i]);
+ }
+ }
+ }
+
+ /**
+ * toArray(a) contains all elements in FIFO order
+ */
+ public void testToArray2() {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray2(q);
+ q.add(i);
+ }
+ // Provoke wraparound
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray2(q);
+ assertEquals(i, q.poll());
+ checkToArray2(q);
+ q.add(SIZE+i);
+ }
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray2(q);
+ assertEquals(SIZE+i, q.poll());
+ }
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ try {
+ q.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() throws InterruptedException {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertEquals(it.next(), q.take());
+ }
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
+ q.add(two);
+ q.add(one);
+ q.add(three);
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertSame(it.next(), one);
+ assertSame(it.next(), three);
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * iterator ordering is FIFO
+ */
+ public void testIteratorOrdering() {
+ final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
+ q.add(one);
+ q.add(two);
+ q.add(three);
+
+ assertEquals("queue should be full", 0, q.remainingCapacity());
+
+ int k = 0;
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+ assertEquals(3, k);
+ }
+
+ /**
+ * Modifications do not cause iterators to fail
+ */
+ public void testWeaklyConsistentIteration() {
+ final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ q.remove();
+ it.next();
+ }
+ assertEquals(0, q.size());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * offer transfers elements across Executor tasks
+ */
+ public void testOfferInExecutor() {
+ final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
+ q.add(one);
+ q.add(two);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(q.offer(three));
+ threadsStarted.await();
+ assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(0, q.remainingCapacity());
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ assertEquals(0, q.remainingCapacity());
+ assertSame(one, q.take());
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * timed poll retrieves elements across Executor threads
+ */
+ public void testPollInExecutor() {
+ final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertNull(q.poll());
+ threadsStarted.await();
+ assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ checkEmpty(q);
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ q.put(one);
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * A deserialized serialized queue has same elements in same order
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedQueue(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * drainTo(c) empties queue into another collection c
+ */
+ public void testDrainTo() {
+ ArrayBlockingQueue q = populatedQueue(SIZE);
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(SIZE, l.size());
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ q.add(zero);
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(zero));
+ assertTrue(q.contains(one));
+ l.clear();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(2, l.size());
+ for (int i = 0; i < 2; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ }
+
+ /**
+ * drainTo empties full queue, unblocking a waiting put.
+ */
+ public void testDrainToWithActivePut() throws InterruptedException {
+ final ArrayBlockingQueue q = populatedQueue(SIZE);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(new Integer(SIZE+1));
+ }});
+
+ t.start();
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertTrue(l.size() >= SIZE);
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ t.join();
+ assertTrue(q.size() + l.size() >= SIZE);
+ }
+
+ /**
+ * drainTo(c, n) empties first min(n, size) elements of queue into c
+ */
+ public void testDrainToN() {
+ ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE*2);
+ for (int i = 0; i < SIZE + 2; ++i) {
+ for (int j = 0; j < SIZE; j++)
+ assertTrue(q.offer(new Integer(j)));
+ ArrayList l = new ArrayList();
+ q.drainTo(l, i);
+ int k = (i < SIZE) ? i : SIZE;
+ assertEquals(k, l.size());
+ assertEquals(SIZE-k, q.size());
+ for (int j = 0; j < k; ++j)
+ assertEquals(l.get(j), new Integer(j));
+ while (q.poll() != null) ;
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java b/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java
new file mode 100644
index 0000000..d18a560
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java
@@ -0,0 +1,888 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Random;
+
+public class ArrayDequeTest extends JSR166TestCase {
+
+ /**
+ * Returns a new deque of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private ArrayDeque<Integer> populatedDeque(int n) {
+ ArrayDeque<Integer> q = new ArrayDeque<Integer>();
+ assertTrue(q.isEmpty());
+ for (int i = 0; i < n; ++i)
+ assertTrue(q.offerLast(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * new deque is empty
+ */
+ public void testConstructor1() {
+ assertEquals(0, new ArrayDeque().size());
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ ArrayDeque q = new ArrayDeque((Collection)null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ ArrayDeque q = new ArrayDeque(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ ArrayDeque q = new ArrayDeque(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Deque contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ ArrayDeque q = new ArrayDeque(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.pollFirst());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ ArrayDeque q = new ArrayDeque();
+ assertTrue(q.isEmpty());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.add(new Integer(2));
+ q.removeFirst();
+ q.removeFirst();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.removeFirst();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * push(null) throws NPE
+ */
+ public void testPushNull() {
+ try {
+ ArrayDeque q = new ArrayDeque(1);
+ q.push(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * peekFirst() returns element inserted with push
+ */
+ public void testPush() {
+ ArrayDeque q = populatedDeque(3);
+ q.pollLast();
+ q.push(four);
+ assertSame(four, q.peekFirst());
+ }
+
+ /**
+ * pop() removes next element, or throws NSEE if empty
+ */
+ public void testPop() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pop());
+ }
+ try {
+ q.pop();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * offer(null) throws NPE
+ */
+ public void testOfferNull() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ q.offer(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * offerFirst(null) throws NPE
+ */
+ public void testOfferFirstNull() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ q.offerFirst(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * offerLast(null) throws NPE
+ */
+ public void testOfferLastNull() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ q.offerLast(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * offer(x) succeeds
+ */
+ public void testOffer() {
+ ArrayDeque q = new ArrayDeque();
+ assertTrue(q.offer(zero));
+ assertTrue(q.offer(one));
+ assertSame(zero, q.peekFirst());
+ assertSame(one, q.peekLast());
+ }
+
+ /**
+ * offerFirst(x) succeeds
+ */
+ public void testOfferFirst() {
+ ArrayDeque q = new ArrayDeque();
+ assertTrue(q.offerFirst(zero));
+ assertTrue(q.offerFirst(one));
+ assertSame(one, q.peekFirst());
+ assertSame(zero, q.peekLast());
+ }
+
+ /**
+ * offerLast(x) succeeds
+ */
+ public void testOfferLast() {
+ ArrayDeque q = new ArrayDeque();
+ assertTrue(q.offerLast(zero));
+ assertTrue(q.offerLast(one));
+ assertSame(zero, q.peekFirst());
+ assertSame(one, q.peekLast());
+ }
+
+ /**
+ * add(null) throws NPE
+ */
+ public void testAddNull() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addFirst(null) throws NPE
+ */
+ public void testAddFirstNull() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ q.addFirst(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addLast(null) throws NPE
+ */
+ public void testAddLastNull() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ q.addLast(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * add(x) succeeds
+ */
+ public void testAdd() {
+ ArrayDeque q = new ArrayDeque();
+ assertTrue(q.add(zero));
+ assertTrue(q.add(one));
+ assertSame(zero, q.peekFirst());
+ assertSame(one, q.peekLast());
+ }
+
+ /**
+ * addFirst(x) succeeds
+ */
+ public void testAddFirst() {
+ ArrayDeque q = new ArrayDeque();
+ q.addFirst(zero);
+ q.addFirst(one);
+ assertSame(one, q.peekFirst());
+ assertSame(zero, q.peekLast());
+ }
+
+ /**
+ * addLast(x) succeeds
+ */
+ public void testAddLast() {
+ ArrayDeque q = new ArrayDeque();
+ q.addLast(zero);
+ q.addLast(one);
+ assertSame(zero, q.peekFirst());
+ assertSame(one, q.peekLast());
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ ArrayDeque q = new ArrayDeque();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Deque contains all elements, in traversal order, of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ ArrayDeque q = new ArrayDeque();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.pollFirst());
+ }
+
+ /**
+ * pollFirst() succeeds unless empty
+ */
+ public void testPollFirst() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * pollLast() succeeds unless empty
+ */
+ public void testPollLast() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.pollLast());
+ }
+ assertNull(q.pollLast());
+ }
+
+ /**
+ * poll() succeeds unless empty
+ */
+ public void testPoll() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * remove() removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove(i+1));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * peekFirst() returns next element, or null if empty
+ */
+ public void testPeekFirst() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peekFirst());
+ assertEquals(i, q.pollFirst());
+ assertTrue(q.peekFirst() == null ||
+ !q.peekFirst().equals(i));
+ }
+ assertNull(q.peekFirst());
+ }
+
+ /**
+ * peek() returns next element, or null if empty
+ */
+ public void testPeek() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.poll());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * peekLast() returns next element, or null if empty
+ */
+ public void testPeekLast() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.peekLast());
+ assertEquals(i, q.pollLast());
+ assertTrue(q.peekLast() == null ||
+ !q.peekLast().equals(i));
+ }
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * element() returns first element, or throws NSEE if empty
+ */
+ public void testElement() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ assertEquals(i, q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * getFirst() returns first element, or throws NSEE if empty
+ */
+ public void testFirstElement() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.getFirst());
+ assertEquals(i, q.pollFirst());
+ }
+ try {
+ q.getFirst();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * getLast() returns last element, or throws NSEE if empty
+ */
+ public void testLastElement() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.getLast());
+ assertEquals(i, q.pollLast());
+ }
+ try {
+ q.getLast();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * removeFirst() removes first element, or throws NSEE if empty
+ */
+ public void testRemoveFirst() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.removeFirst());
+ }
+ try {
+ q.removeFirst();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekFirst());
+ }
+
+ /**
+ * removeLast() removes last element, or throws NSEE if empty
+ */
+ public void testRemoveLast() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = SIZE - 1; i >= 0; --i) {
+ assertEquals(i, q.removeLast());
+ }
+ try {
+ q.removeLast();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * removeFirstOccurrence(x) removes x and returns true if present
+ */
+ public void testRemoveFirstOccurrence() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.removeFirstOccurrence(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.removeFirstOccurrence(new Integer(i)));
+ assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * removeLastOccurrence(x) removes x and returns true if present
+ */
+ public void testRemoveLastOccurrence() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.removeLastOccurrence(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.removeLastOccurrence(new Integer(i)));
+ assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ ArrayDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ assertEquals(i, q.pollFirst());
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ ArrayDeque q = populatedDeque(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertTrue(q.add(new Integer(1)));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ ArrayDeque q = populatedDeque(SIZE);
+ ArrayDeque p = new ArrayDeque();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ assertTrue(p.add(new Integer(i)));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ ArrayDeque q = populatedDeque(SIZE);
+ ArrayDeque p = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ assertEquals(changed, (i > 0));
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.removeFirst();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ ArrayDeque q = populatedDeque(SIZE);
+ ArrayDeque p = populatedDeque(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ assertFalse(q.contains(p.removeFirst()));
+ }
+ }
+ }
+
+ void checkToArray(ArrayDeque q) {
+ int size = q.size();
+ Object[] o = q.toArray();
+ assertEquals(size, o.length);
+ Iterator it = q.iterator();
+ for (int i = 0; i < size; i++) {
+ Integer x = (Integer) it.next();
+ assertEquals((Integer)o[0] + i, (int) x);
+ assertSame(o[i], x);
+ }
+ }
+
+ /**
+ * toArray() contains all elements in FIFO order
+ */
+ public void testToArray() {
+ ArrayDeque q = new ArrayDeque();
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray(q);
+ q.addLast(i);
+ }
+ // Provoke wraparound
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray(q);
+ assertEquals(i, q.poll());
+ q.addLast(SIZE+i);
+ }
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray(q);
+ assertEquals(SIZE+i, q.poll());
+ }
+ }
+
+ void checkToArray2(ArrayDeque q) {
+ int size = q.size();
+ Integer[] a1 = size == 0 ? null : new Integer[size-1];
+ Integer[] a2 = new Integer[size];
+ Integer[] a3 = new Integer[size+2];
+ if (size > 0) Arrays.fill(a1, 42);
+ Arrays.fill(a2, 42);
+ Arrays.fill(a3, 42);
+ Integer[] b1 = size == 0 ? null : (Integer[]) q.toArray(a1);
+ Integer[] b2 = (Integer[]) q.toArray(a2);
+ Integer[] b3 = (Integer[]) q.toArray(a3);
+ assertSame(a2, b2);
+ assertSame(a3, b3);
+ Iterator it = q.iterator();
+ for (int i = 0; i < size; i++) {
+ Integer x = (Integer) it.next();
+ assertSame(b1[i], x);
+ assertEquals(b1[0] + i, (int) x);
+ assertSame(b2[i], x);
+ assertSame(b3[i], x);
+ }
+ assertNull(a3[size]);
+ assertEquals(42, (int) a3[size+1]);
+ if (size > 0) {
+ assertNotSame(a1, b1);
+ assertEquals(size, b1.length);
+ for (int i = 0; i < a1.length; i++) {
+ assertEquals(42, (int) a1[i]);
+ }
+ }
+ }
+
+ /**
+ * toArray(a) contains all elements in FIFO order
+ */
+ public void testToArray2() {
+ ArrayDeque q = new ArrayDeque();
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray2(q);
+ q.addLast(i);
+ }
+ // Provoke wraparound
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray2(q);
+ assertEquals(i, q.poll());
+ q.addLast(SIZE+i);
+ }
+ for (int i = 0; i < SIZE; i++) {
+ checkToArray2(q);
+ assertEquals(SIZE+i, q.poll());
+ }
+ }
+
+ /**
+ * toArray(null) throws NullPointerException
+ */
+ public void testToArray_NullArg() {
+ ArrayDeque l = new ArrayDeque();
+ l.add(new Object());
+ try {
+ l.toArray(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ ArrayDeque l = new ArrayDeque();
+ l.add(new Integer(5));
+ try {
+ l.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * Iterator iterates through all elements
+ */
+ public void testIterator() {
+ ArrayDeque q = populatedDeque(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * Iterator ordering is FIFO
+ */
+ public void testIteratorOrdering() {
+ final ArrayDeque q = new ArrayDeque();
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ int k = 0;
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+
+ assertEquals(3, k);
+ }
+
+ /**
+ * iterator.remove() removes current element
+ */
+ public void testIteratorRemove() {
+ final ArrayDeque q = new ArrayDeque();
+ final Random rng = new Random();
+ for (int iters = 0; iters < 100; ++iters) {
+ int max = rng.nextInt(5) + 2;
+ int split = rng.nextInt(max-1) + 1;
+ for (int j = 1; j <= max; ++j)
+ q.add(new Integer(j));
+ Iterator it = q.iterator();
+ for (int j = 1; j <= split; ++j)
+ assertEquals(it.next(), new Integer(j));
+ it.remove();
+ assertEquals(it.next(), new Integer(split+1));
+ for (int j = 1; j <= split; ++j)
+ q.remove(new Integer(j));
+ it = q.iterator();
+ for (int j = split+1; j <= max; ++j) {
+ assertEquals(it.next(), new Integer(j));
+ it.remove();
+ }
+ assertFalse(it.hasNext());
+ assertTrue(q.isEmpty());
+ }
+ }
+
+ /**
+ * Descending iterator iterates through all elements
+ */
+ public void testDescendingIterator() {
+ ArrayDeque q = populatedDeque(SIZE);
+ int i = 0;
+ Iterator it = q.descendingIterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ assertFalse(it.hasNext());
+ try {
+ it.next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * Descending iterator ordering is reverse FIFO
+ */
+ public void testDescendingIteratorOrdering() {
+ final ArrayDeque q = new ArrayDeque();
+ for (int iters = 0; iters < 100; ++iters) {
+ q.add(new Integer(3));
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ int k = 0;
+ for (Iterator it = q.descendingIterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+
+ assertEquals(3, k);
+ q.remove();
+ q.remove();
+ q.remove();
+ }
+ }
+
+ /**
+ * descendingIterator.remove() removes current element
+ */
+ public void testDescendingIteratorRemove() {
+ final ArrayDeque q = new ArrayDeque();
+ final Random rng = new Random();
+ for (int iters = 0; iters < 100; ++iters) {
+ int max = rng.nextInt(5) + 2;
+ int split = rng.nextInt(max-1) + 1;
+ for (int j = max; j >= 1; --j)
+ q.add(new Integer(j));
+ Iterator it = q.descendingIterator();
+ for (int j = 1; j <= split; ++j)
+ assertEquals(it.next(), new Integer(j));
+ it.remove();
+ assertEquals(it.next(), new Integer(split+1));
+ for (int j = 1; j <= split; ++j)
+ q.remove(new Integer(j));
+ it = q.descendingIterator();
+ for (int j = split+1; j <= max; ++j) {
+ assertEquals(it.next(), new Integer(j));
+ it.remove();
+ }
+ assertFalse(it.hasNext());
+ assertTrue(q.isEmpty());
+ }
+ }
+
+ /**
+ * toString() contains toStrings of elements
+ */
+ public void testToString() {
+ ArrayDeque q = populatedDeque(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized deque has same elements in same order
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedDeque(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(y, x);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java b/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java
new file mode 100644
index 0000000..7a50120
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java
@@ -0,0 +1,136 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class AtomicBooleanTest extends JSR166TestCase {
+
+ /**
+ * constructor initializes to given value
+ */
+ public void testConstructor() {
+ assertTrue(new AtomicBoolean(true).get());
+ assertFalse(new AtomicBoolean(false).get());
+ }
+
+ /**
+ * default constructed initializes to false
+ */
+ public void testConstructor2() {
+ AtomicBoolean ai = new AtomicBoolean();
+ assertFalse(ai.get());
+ }
+
+ /**
+ * get returns the last value set
+ */
+ public void testGetSet() {
+ AtomicBoolean ai = new AtomicBoolean(true);
+ assertTrue(ai.get());
+ ai.set(false);
+ assertFalse(ai.get());
+ ai.set(true);
+ assertTrue(ai.get());
+ }
+
+ /**
+ * get returns the last value lazySet in same thread
+ */
+ public void testGetLazySet() {
+ AtomicBoolean ai = new AtomicBoolean(true);
+ assertTrue(ai.get());
+ ai.lazySet(false);
+ assertFalse(ai.get());
+ ai.lazySet(true);
+ assertTrue(ai.get());
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicBoolean ai = new AtomicBoolean(true);
+ assertTrue(ai.compareAndSet(true, false));
+ assertFalse(ai.get());
+ assertTrue(ai.compareAndSet(false, false));
+ assertFalse(ai.get());
+ assertFalse(ai.compareAndSet(true, false));
+ assertFalse(ai.get());
+ assertTrue(ai.compareAndSet(false, true));
+ assertTrue(ai.get());
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ final AtomicBoolean ai = new AtomicBoolean(true);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!ai.compareAndSet(false, true)) Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(ai.compareAndSet(true, false));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicBoolean ai = new AtomicBoolean(true);
+ while (!ai.weakCompareAndSet(true, false));
+ assertFalse(ai.get());
+ while (!ai.weakCompareAndSet(false, false));
+ assertFalse(ai.get());
+ while (!ai.weakCompareAndSet(false, true));
+ assertTrue(ai.get());
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value
+ */
+ public void testGetAndSet() {
+ AtomicBoolean ai = new AtomicBoolean(true);
+ assertEquals(true, ai.getAndSet(false));
+ assertEquals(false, ai.getAndSet(false));
+ assertEquals(false, ai.getAndSet(true));
+ assertTrue(ai.get());
+ }
+
+ /**
+ * a deserialized serialized atomic holds same value
+ */
+ public void testSerialization() throws Exception {
+ AtomicBoolean x = new AtomicBoolean();
+ AtomicBoolean y = serialClone(x);
+ x.set(true);
+ AtomicBoolean z = serialClone(x);
+ assertTrue(x.get());
+ assertFalse(y.get());
+ assertTrue(z.get());
+ }
+
+ /**
+ * toString returns current value.
+ */
+ public void testToString() {
+ AtomicBoolean ai = new AtomicBoolean();
+ assertEquals(Boolean.toString(false), ai.toString());
+ ai.set(true);
+ assertEquals(Boolean.toString(true), ai.toString());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java
new file mode 100644
index 0000000..e81a107
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java
@@ -0,0 +1,337 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+public class AtomicIntegerArrayTest extends JSR166TestCase {
+
+ /**
+ * constructor creates array of given size with all elements zero
+ */
+ public void testConstructor() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++)
+ assertEquals(0, aa.get(i));
+ }
+
+ /**
+ * constructor with null array throws NPE
+ */
+ public void testConstructor2NPE() {
+ try {
+ int[] a = null;
+ AtomicIntegerArray aa = new AtomicIntegerArray(a);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * constructor with array is of same size and has all elements
+ */
+ public void testConstructor2() {
+ int[] a = { 17, 3, -42, 99, -7 };
+ AtomicIntegerArray aa = new AtomicIntegerArray(a);
+ assertEquals(a.length, aa.length());
+ for (int i = 0; i < a.length; i++)
+ assertEquals(a[i], aa.get(i));
+ }
+
+ /**
+ * get and set for out of bound indices throw IndexOutOfBoundsException
+ */
+ public void testIndexing() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int index : new int[] { -1, SIZE }) {
+ try {
+ aa.get(index);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.set(index, 1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.lazySet(index, 1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.compareAndSet(index, 1, 2);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.weakCompareAndSet(index, 1, 2);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.getAndAdd(index, 1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.addAndGet(index, 1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+ }
+
+ /**
+ * get returns the last value set at index
+ */
+ public void testGetSet() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.get(i));
+ aa.set(i, 2);
+ assertEquals(2, aa.get(i));
+ aa.set(i, -3);
+ assertEquals(-3, aa.get(i));
+ }
+ }
+
+ /**
+ * get returns the last value lazySet at index by same thread
+ */
+ public void testGetLazySet() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.lazySet(i, 1);
+ assertEquals(1, aa.get(i));
+ aa.lazySet(i, 2);
+ assertEquals(2, aa.get(i));
+ aa.lazySet(i, -3);
+ assertEquals(-3, aa.get(i));
+ }
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertTrue(aa.compareAndSet(i, 1, 2));
+ assertTrue(aa.compareAndSet(i, 2, -4));
+ assertEquals(-4, aa.get(i));
+ assertFalse(aa.compareAndSet(i, -5, 7));
+ assertEquals(-4, aa.get(i));
+ assertTrue(aa.compareAndSet(i, -4, 7));
+ assertEquals(7, aa.get(i));
+ }
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ final AtomicIntegerArray a = new AtomicIntegerArray(1);
+ a.set(0, 1);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!a.compareAndSet(0, 2, 3))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(a.compareAndSet(0, 1, 2));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertEquals(3, a.get(0));
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ while (!aa.weakCompareAndSet(i, 1, 2));
+ while (!aa.weakCompareAndSet(i, 2, -4));
+ assertEquals(-4, aa.get(i));
+ while (!aa.weakCompareAndSet(i, -4, 7));
+ assertEquals(7, aa.get(i));
+ }
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value at given index
+ */
+ public void testGetAndSet() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.getAndSet(i, 0));
+ assertEquals(0, aa.getAndSet(i, -10));
+ assertEquals(-10, aa.getAndSet(i, 1));
+ }
+ }
+
+ /**
+ * getAndAdd returns previous value and adds given value
+ */
+ public void testGetAndAdd() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.getAndAdd(i, 2));
+ assertEquals(3, aa.get(i));
+ assertEquals(3, aa.getAndAdd(i, -4));
+ assertEquals(-1, aa.get(i));
+ }
+ }
+
+ /**
+ * getAndDecrement returns previous value and decrements
+ */
+ public void testGetAndDecrement() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.getAndDecrement(i));
+ assertEquals(0, aa.getAndDecrement(i));
+ assertEquals(-1, aa.getAndDecrement(i));
+ }
+ }
+
+ /**
+ * getAndIncrement returns previous value and increments
+ */
+ public void testGetAndIncrement() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.getAndIncrement(i));
+ assertEquals(2, aa.get(i));
+ aa.set(i, -2);
+ assertEquals(-2, aa.getAndIncrement(i));
+ assertEquals(-1, aa.getAndIncrement(i));
+ assertEquals(0, aa.getAndIncrement(i));
+ assertEquals(1, aa.get(i));
+ }
+ }
+
+ /**
+ * addAndGet adds given value to current, and returns current value
+ */
+ public void testAddAndGet() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(3, aa.addAndGet(i, 2));
+ assertEquals(3, aa.get(i));
+ assertEquals(-1, aa.addAndGet(i, -4));
+ assertEquals(-1, aa.get(i));
+ }
+ }
+
+ /**
+ * decrementAndGet decrements and returns current value
+ */
+ public void testDecrementAndGet() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(0, aa.decrementAndGet(i));
+ assertEquals(-1, aa.decrementAndGet(i));
+ assertEquals(-2, aa.decrementAndGet(i));
+ assertEquals(-2, aa.get(i));
+ }
+ }
+
+ /**
+ * incrementAndGet increments and returns current value
+ */
+ public void testIncrementAndGet() {
+ AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(2, aa.incrementAndGet(i));
+ assertEquals(2, aa.get(i));
+ aa.set(i, -2);
+ assertEquals(-1, aa.incrementAndGet(i));
+ assertEquals(0, aa.incrementAndGet(i));
+ assertEquals(1, aa.incrementAndGet(i));
+ assertEquals(1, aa.get(i));
+ }
+ }
+
+ static final int COUNTDOWN = 100000;
+
+ class Counter extends CheckedRunnable {
+ final AtomicIntegerArray aa;
+ volatile int counts;
+ Counter(AtomicIntegerArray a) { aa = a; }
+ public void realRun() {
+ for (;;) {
+ boolean done = true;
+ for (int i = 0; i < aa.length(); i++) {
+ int v = aa.get(i);
+ assertTrue(v >= 0);
+ if (v != 0) {
+ done = false;
+ if (aa.compareAndSet(i, v, v-1))
+ ++counts;
+ }
+ }
+ if (done)
+ break;
+ }
+ }
+ }
+
+ /**
+ * Multiple threads using same array of counters successfully
+ * update a number of times equal to total count
+ */
+ public void testCountingInMultipleThreads() throws InterruptedException {
+ final AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++)
+ aa.set(i, COUNTDOWN);
+ Counter c1 = new Counter(aa);
+ Counter c2 = new Counter(aa);
+ Thread t1 = new Thread(c1);
+ Thread t2 = new Thread(c2);
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN);
+ }
+
+ /**
+ * a deserialized serialized array holds same values
+ */
+ public void testSerialization() throws Exception {
+ AtomicIntegerArray x = new AtomicIntegerArray(SIZE);
+ for (int i = 0; i < SIZE; i++)
+ x.set(i, -i);
+ AtomicIntegerArray y = serialClone(x);
+ assertNotSame(x, y);
+ assertEquals(x.length(), y.length());
+ for (int i = 0; i < SIZE; i++) {
+ assertEquals(x.get(i), y.get(i));
+ }
+ }
+
+ /**
+ * toString returns current value.
+ */
+ public void testToString() {
+ int[] a = { 17, 3, -42, 99, -7 };
+ AtomicIntegerArray aa = new AtomicIntegerArray(a);
+ assertEquals(Arrays.toString(a), aa.toString());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
new file mode 100644
index 0000000..f0c1ae6
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
@@ -0,0 +1,232 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
+public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase {
+ volatile int x = 0;
+ int w;
+ long z;
+
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) {
+ return AtomicIntegerFieldUpdater.newUpdater
+ (AtomicIntegerFieldUpdaterTest.class, fieldName);
+ }
+
+ /**
+ * Construction with non-existent field throws RuntimeException
+ */
+ public void testConstructor() {
+ try {
+ updaterFor("y");
+ shouldThrow();
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
+
+ /**
+ * construction with field not of given type throws IllegalArgumentException
+ */
+ public void testConstructor2() {
+ try {
+ updaterFor("z");
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * construction with non-volatile field throws IllegalArgumentException
+ */
+ public void testConstructor3() {
+ try {
+ updaterFor("w");
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * get returns the last value set or assigned
+ */
+ public void testGetSet() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.get(this));
+ a.set(this, 2);
+ assertEquals(2, a.get(this));
+ a.set(this, -3);
+ assertEquals(-3, a.get(this));
+ }
+
+ /**
+ * get returns the last value lazySet by same thread
+ */
+ public void testGetLazySet() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.get(this));
+ a.lazySet(this, 2);
+ assertEquals(2, a.get(this));
+ a.lazySet(this, -3);
+ assertEquals(-3, a.get(this));
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertTrue(a.compareAndSet(this, 1, 2));
+ assertTrue(a.compareAndSet(this, 2, -4));
+ assertEquals(-4, a.get(this));
+ assertFalse(a.compareAndSet(this, -5, 7));
+ assertEquals(-4, a.get(this));
+ assertTrue(a.compareAndSet(this, -4, 7));
+ assertEquals(7, a.get(this));
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ x = 1;
+ final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(a.compareAndSet(this, 1, 2));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertEquals(3, a.get(this));
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ while (!a.weakCompareAndSet(this, 1, 2));
+ while (!a.weakCompareAndSet(this, 2, -4));
+ assertEquals(-4, a.get(this));
+ while (!a.weakCompareAndSet(this, -4, 7));
+ assertEquals(7, a.get(this));
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value
+ */
+ public void testGetAndSet() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.getAndSet(this, 0));
+ assertEquals(0, a.getAndSet(this, -10));
+ assertEquals(-10, a.getAndSet(this, 1));
+ }
+
+ /**
+ * getAndAdd returns previous value and adds given value
+ */
+ public void testGetAndAdd() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.getAndAdd(this, 2));
+ assertEquals(3, a.get(this));
+ assertEquals(3, a.getAndAdd(this, -4));
+ assertEquals(-1, a.get(this));
+ }
+
+ /**
+ * getAndDecrement returns previous value and decrements
+ */
+ public void testGetAndDecrement() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.getAndDecrement(this));
+ assertEquals(0, a.getAndDecrement(this));
+ assertEquals(-1, a.getAndDecrement(this));
+ }
+
+ /**
+ * getAndIncrement returns previous value and increments
+ */
+ public void testGetAndIncrement() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.getAndIncrement(this));
+ assertEquals(2, a.get(this));
+ a.set(this, -2);
+ assertEquals(-2, a.getAndIncrement(this));
+ assertEquals(-1, a.getAndIncrement(this));
+ assertEquals(0, a.getAndIncrement(this));
+ assertEquals(1, a.get(this));
+ }
+
+ /**
+ * addAndGet adds given value to current, and returns current value
+ */
+ public void testAddAndGet() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(3, a.addAndGet(this, 2));
+ assertEquals(3, a.get(this));
+ assertEquals(-1, a.addAndGet(this, -4));
+ assertEquals(-1, a.get(this));
+ }
+
+ /**
+ * decrementAndGet decrements and returns current value
+ */
+ public void testDecrementAndGet() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(0, a.decrementAndGet(this));
+ assertEquals(-1, a.decrementAndGet(this));
+ assertEquals(-2, a.decrementAndGet(this));
+ assertEquals(-2, a.get(this));
+ }
+
+ /**
+ * incrementAndGet increments and returns current value
+ */
+ public void testIncrementAndGet() {
+ AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(2, a.incrementAndGet(this));
+ assertEquals(2, a.get(this));
+ a.set(this, -2);
+ assertEquals(-1, a.incrementAndGet(this));
+ assertEquals(0, a.incrementAndGet(this));
+ assertEquals(1, a.incrementAndGet(this));
+ assertEquals(1, a.get(this));
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java
new file mode 100644
index 0000000..2afaa73
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java
@@ -0,0 +1,261 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class AtomicIntegerTest extends JSR166TestCase {
+
+ final int[] VALUES = {
+ Integer.MIN_VALUE, -1, 0, 1, 42, Integer.MAX_VALUE,
+ };
+
+ /**
+ * constructor initializes to given value
+ */
+ public void testConstructor() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(1, ai.get());
+ }
+
+ /**
+ * default constructed initializes to zero
+ */
+ public void testConstructor2() {
+ AtomicInteger ai = new AtomicInteger();
+ assertEquals(0, ai.get());
+ }
+
+ /**
+ * get returns the last value set
+ */
+ public void testGetSet() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(1, ai.get());
+ ai.set(2);
+ assertEquals(2, ai.get());
+ ai.set(-3);
+ assertEquals(-3, ai.get());
+ }
+
+ /**
+ * get returns the last value lazySet in same thread
+ */
+ public void testGetLazySet() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(1, ai.get());
+ ai.lazySet(2);
+ assertEquals(2, ai.get());
+ ai.lazySet(-3);
+ assertEquals(-3, ai.get());
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertTrue(ai.compareAndSet(1, 2));
+ assertTrue(ai.compareAndSet(2, -4));
+ assertEquals(-4, ai.get());
+ assertFalse(ai.compareAndSet(-5, 7));
+ assertEquals(-4, ai.get());
+ assertTrue(ai.compareAndSet(-4, 7));
+ assertEquals(7, ai.get());
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ final AtomicInteger ai = new AtomicInteger(1);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!ai.compareAndSet(2, 3))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(ai.compareAndSet(1, 2));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertEquals(3, ai.get());
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicInteger ai = new AtomicInteger(1);
+ while (!ai.weakCompareAndSet(1, 2));
+ while (!ai.weakCompareAndSet(2, -4));
+ assertEquals(-4, ai.get());
+ while (!ai.weakCompareAndSet(-4, 7));
+ assertEquals(7, ai.get());
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value
+ */
+ public void testGetAndSet() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(1, ai.getAndSet(0));
+ assertEquals(0, ai.getAndSet(-10));
+ assertEquals(-10, ai.getAndSet(1));
+ }
+
+ /**
+ * getAndAdd returns previous value and adds given value
+ */
+ public void testGetAndAdd() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(1, ai.getAndAdd(2));
+ assertEquals(3, ai.get());
+ assertEquals(3, ai.getAndAdd(-4));
+ assertEquals(-1, ai.get());
+ }
+
+ /**
+ * getAndDecrement returns previous value and decrements
+ */
+ public void testGetAndDecrement() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(1, ai.getAndDecrement());
+ assertEquals(0, ai.getAndDecrement());
+ assertEquals(-1, ai.getAndDecrement());
+ }
+
+ /**
+ * getAndIncrement returns previous value and increments
+ */
+ public void testGetAndIncrement() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(1, ai.getAndIncrement());
+ assertEquals(2, ai.get());
+ ai.set(-2);
+ assertEquals(-2, ai.getAndIncrement());
+ assertEquals(-1, ai.getAndIncrement());
+ assertEquals(0, ai.getAndIncrement());
+ assertEquals(1, ai.get());
+ }
+
+ /**
+ * addAndGet adds given value to current, and returns current value
+ */
+ public void testAddAndGet() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(3, ai.addAndGet(2));
+ assertEquals(3, ai.get());
+ assertEquals(-1, ai.addAndGet(-4));
+ assertEquals(-1, ai.get());
+ }
+
+ /**
+ * decrementAndGet decrements and returns current value
+ */
+ public void testDecrementAndGet() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(0, ai.decrementAndGet());
+ assertEquals(-1, ai.decrementAndGet());
+ assertEquals(-2, ai.decrementAndGet());
+ assertEquals(-2, ai.get());
+ }
+
+ /**
+ * incrementAndGet increments and returns current value
+ */
+ public void testIncrementAndGet() {
+ AtomicInteger ai = new AtomicInteger(1);
+ assertEquals(2, ai.incrementAndGet());
+ assertEquals(2, ai.get());
+ ai.set(-2);
+ assertEquals(-1, ai.incrementAndGet());
+ assertEquals(0, ai.incrementAndGet());
+ assertEquals(1, ai.incrementAndGet());
+ assertEquals(1, ai.get());
+ }
+
+ /**
+ * a deserialized serialized atomic holds same value
+ */
+ public void testSerialization() throws Exception {
+ AtomicInteger x = new AtomicInteger();
+ AtomicInteger y = serialClone(x);
+ assertNotSame(x, y);
+ x.set(22);
+ AtomicInteger z = serialClone(x);
+ assertEquals(22, x.get());
+ assertEquals(0, y.get());
+ assertEquals(22, z.get());
+ }
+
+ /**
+ * toString returns current value.
+ */
+ public void testToString() {
+ AtomicInteger ai = new AtomicInteger();
+ assertEquals("0", ai.toString());
+ for (int x : VALUES) {
+ ai.set(x);
+ assertEquals(Integer.toString(x), ai.toString());
+ }
+ }
+
+ /**
+ * intValue returns current value.
+ */
+ public void testIntValue() {
+ AtomicInteger ai = new AtomicInteger();
+ assertEquals(0, ai.intValue());
+ for (int x : VALUES) {
+ ai.set(x);
+ assertEquals(x, ai.intValue());
+ }
+ }
+
+ /**
+ * longValue returns current value.
+ */
+ public void testLongValue() {
+ AtomicInteger ai = new AtomicInteger();
+ assertEquals(0L, ai.longValue());
+ for (int x : VALUES) {
+ ai.set(x);
+ assertEquals((long)x, ai.longValue());
+ }
+ }
+
+ /**
+ * floatValue returns current value.
+ */
+ public void testFloatValue() {
+ AtomicInteger ai = new AtomicInteger();
+ assertEquals(0.0f, ai.floatValue());
+ for (int x : VALUES) {
+ ai.set(x);
+ assertEquals((float)x, ai.floatValue());
+ }
+ }
+
+ /**
+ * doubleValue returns current value.
+ */
+ public void testDoubleValue() {
+ AtomicInteger ai = new AtomicInteger();
+ assertEquals(0.0d, ai.doubleValue());
+ for (int x : VALUES) {
+ ai.set(x);
+ assertEquals((double)x, ai.doubleValue());
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java
new file mode 100644
index 0000000..53be5dc
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java
@@ -0,0 +1,337 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicLongArray;
+
+public class AtomicLongArrayTest extends JSR166TestCase {
+
+ /**
+ * constructor creates array of given size with all elements zero
+ */
+ public void testConstructor() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++)
+ assertEquals(0, aa.get(i));
+ }
+
+ /**
+ * constructor with null array throws NPE
+ */
+ public void testConstructor2NPE() {
+ try {
+ long[] a = null;
+ AtomicLongArray aa = new AtomicLongArray(a);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * constructor with array is of same size and has all elements
+ */
+ public void testConstructor2() {
+ long[] a = { 17L, 3L, -42L, 99L, -7L };
+ AtomicLongArray aa = new AtomicLongArray(a);
+ assertEquals(a.length, aa.length());
+ for (int i = 0; i < a.length; i++)
+ assertEquals(a[i], aa.get(i));
+ }
+
+ /**
+ * get and set for out of bound indices throw IndexOutOfBoundsException
+ */
+ public void testIndexing() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int index : new int[] { -1, SIZE }) {
+ try {
+ aa.get(index);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.set(index, 1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.lazySet(index, 1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.compareAndSet(index, 1, 2);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.weakCompareAndSet(index, 1, 2);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.getAndAdd(index, 1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.addAndGet(index, 1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+ }
+
+ /**
+ * get returns the last value set at index
+ */
+ public void testGetSet() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.get(i));
+ aa.set(i, 2);
+ assertEquals(2, aa.get(i));
+ aa.set(i, -3);
+ assertEquals(-3, aa.get(i));
+ }
+ }
+
+ /**
+ * get returns the last value lazySet at index by same thread
+ */
+ public void testGetLazySet() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.lazySet(i, 1);
+ assertEquals(1, aa.get(i));
+ aa.lazySet(i, 2);
+ assertEquals(2, aa.get(i));
+ aa.lazySet(i, -3);
+ assertEquals(-3, aa.get(i));
+ }
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertTrue(aa.compareAndSet(i, 1, 2));
+ assertTrue(aa.compareAndSet(i, 2, -4));
+ assertEquals(-4, aa.get(i));
+ assertFalse(aa.compareAndSet(i, -5, 7));
+ assertEquals(-4, aa.get(i));
+ assertTrue(aa.compareAndSet(i, -4, 7));
+ assertEquals(7, aa.get(i));
+ }
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws InterruptedException {
+ final AtomicLongArray a = new AtomicLongArray(1);
+ a.set(0, 1);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!a.compareAndSet(0, 2, 3))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(a.compareAndSet(0, 1, 2));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertEquals(3, a.get(0));
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ while (!aa.weakCompareAndSet(i, 1, 2));
+ while (!aa.weakCompareAndSet(i, 2, -4));
+ assertEquals(-4, aa.get(i));
+ while (!aa.weakCompareAndSet(i, -4, 7));
+ assertEquals(7, aa.get(i));
+ }
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value at given index
+ */
+ public void testGetAndSet() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.getAndSet(i, 0));
+ assertEquals(0, aa.getAndSet(i, -10));
+ assertEquals(-10, aa.getAndSet(i, 1));
+ }
+ }
+
+ /**
+ * getAndAdd returns previous value and adds given value
+ */
+ public void testGetAndAdd() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.getAndAdd(i, 2));
+ assertEquals(3, aa.get(i));
+ assertEquals(3, aa.getAndAdd(i, -4));
+ assertEquals(-1, aa.get(i));
+ }
+ }
+
+ /**
+ * getAndDecrement returns previous value and decrements
+ */
+ public void testGetAndDecrement() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.getAndDecrement(i));
+ assertEquals(0, aa.getAndDecrement(i));
+ assertEquals(-1, aa.getAndDecrement(i));
+ }
+ }
+
+ /**
+ * getAndIncrement returns previous value and increments
+ */
+ public void testGetAndIncrement() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(1, aa.getAndIncrement(i));
+ assertEquals(2, aa.get(i));
+ aa.set(i, -2);
+ assertEquals(-2, aa.getAndIncrement(i));
+ assertEquals(-1, aa.getAndIncrement(i));
+ assertEquals(0, aa.getAndIncrement(i));
+ assertEquals(1, aa.get(i));
+ }
+ }
+
+ /**
+ * addAndGet adds given value to current, and returns current value
+ */
+ public void testAddAndGet() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(3, aa.addAndGet(i, 2));
+ assertEquals(3, aa.get(i));
+ assertEquals(-1, aa.addAndGet(i, -4));
+ assertEquals(-1, aa.get(i));
+ }
+ }
+
+ /**
+ * decrementAndGet decrements and returns current value
+ */
+ public void testDecrementAndGet() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(0, aa.decrementAndGet(i));
+ assertEquals(-1, aa.decrementAndGet(i));
+ assertEquals(-2, aa.decrementAndGet(i));
+ assertEquals(-2, aa.get(i));
+ }
+ }
+
+ /**
+ * incrementAndGet increments and returns current value
+ */
+ public void testIncrementAndGet() {
+ AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, 1);
+ assertEquals(2, aa.incrementAndGet(i));
+ assertEquals(2, aa.get(i));
+ aa.set(i, -2);
+ assertEquals(-1, aa.incrementAndGet(i));
+ assertEquals(0, aa.incrementAndGet(i));
+ assertEquals(1, aa.incrementAndGet(i));
+ assertEquals(1, aa.get(i));
+ }
+ }
+
+ static final long COUNTDOWN = 100000;
+
+ class Counter extends CheckedRunnable {
+ final AtomicLongArray aa;
+ volatile long counts;
+ Counter(AtomicLongArray a) { aa = a; }
+ public void realRun() {
+ for (;;) {
+ boolean done = true;
+ for (int i = 0; i < aa.length(); i++) {
+ long v = aa.get(i);
+ assertTrue(v >= 0);
+ if (v != 0) {
+ done = false;
+ if (aa.compareAndSet(i, v, v-1))
+ ++counts;
+ }
+ }
+ if (done)
+ break;
+ }
+ }
+ }
+
+ /**
+ * Multiple threads using same array of counters successfully
+ * update a number of times equal to total count
+ */
+ public void testCountingInMultipleThreads() throws InterruptedException {
+ final AtomicLongArray aa = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++)
+ aa.set(i, COUNTDOWN);
+ Counter c1 = new Counter(aa);
+ Counter c2 = new Counter(aa);
+ Thread t1 = new Thread(c1);
+ Thread t2 = new Thread(c2);
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN);
+ }
+
+ /**
+ * a deserialized serialized array holds same values
+ */
+ public void testSerialization() throws Exception {
+ AtomicLongArray x = new AtomicLongArray(SIZE);
+ for (int i = 0; i < SIZE; i++)
+ x.set(i, -i);
+ AtomicLongArray y = serialClone(x);
+ assertNotSame(x, y);
+ assertEquals(x.length(), y.length());
+ for (int i = 0; i < SIZE; i++) {
+ assertEquals(x.get(i), y.get(i));
+ }
+ }
+
+ /**
+ * toString returns current value.
+ */
+ public void testToString() {
+ long[] a = { 17, 3, -42, 99, -7 };
+ AtomicLongArray aa = new AtomicLongArray(a);
+ assertEquals(Arrays.toString(a), aa.toString());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
new file mode 100644
index 0000000..c9374e0
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
@@ -0,0 +1,232 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+
+public class AtomicLongFieldUpdaterTest extends JSR166TestCase {
+ volatile long x = 0;
+ int z;
+ long w;
+
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> updaterFor(String fieldName) {
+ return AtomicLongFieldUpdater.newUpdater
+ (AtomicLongFieldUpdaterTest.class, fieldName);
+ }
+
+ /**
+ * Construction with non-existent field throws RuntimeException
+ */
+ public void testConstructor() {
+ try {
+ updaterFor("y");
+ shouldThrow();
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
+
+ /**
+ * construction with field not of given type throws IllegalArgumentException
+ */
+ public void testConstructor2() {
+ try {
+ updaterFor("z");
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * construction with non-volatile field throws IllegalArgumentException
+ */
+ public void testConstructor3() {
+ try {
+ updaterFor("w");
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * get returns the last value set or assigned
+ */
+ public void testGetSet() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.get(this));
+ a.set(this, 2);
+ assertEquals(2, a.get(this));
+ a.set(this, -3);
+ assertEquals(-3, a.get(this));
+ }
+
+ /**
+ * get returns the last value lazySet by same thread
+ */
+ public void testGetLazySet() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.get(this));
+ a.lazySet(this, 2);
+ assertEquals(2, a.get(this));
+ a.lazySet(this, -3);
+ assertEquals(-3, a.get(this));
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertTrue(a.compareAndSet(this, 1, 2));
+ assertTrue(a.compareAndSet(this, 2, -4));
+ assertEquals(-4, a.get(this));
+ assertFalse(a.compareAndSet(this, -5, 7));
+ assertEquals(-4, a.get(this));
+ assertTrue(a.compareAndSet(this, -4, 7));
+ assertEquals(7, a.get(this));
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ x = 1;
+ final AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!a.compareAndSet(AtomicLongFieldUpdaterTest.this, 2, 3))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(a.compareAndSet(this, 1, 2));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertEquals(3, a.get(this));
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ while (!a.weakCompareAndSet(this, 1, 2));
+ while (!a.weakCompareAndSet(this, 2, -4));
+ assertEquals(-4, a.get(this));
+ while (!a.weakCompareAndSet(this, -4, 7));
+ assertEquals(7, a.get(this));
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value
+ */
+ public void testGetAndSet() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.getAndSet(this, 0));
+ assertEquals(0, a.getAndSet(this, -10));
+ assertEquals(-10, a.getAndSet(this, 1));
+ }
+
+ /**
+ * getAndAdd returns previous value and adds given value
+ */
+ public void testGetAndAdd() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.getAndAdd(this, 2));
+ assertEquals(3, a.get(this));
+ assertEquals(3, a.getAndAdd(this, -4));
+ assertEquals(-1, a.get(this));
+ }
+
+ /**
+ * getAndDecrement returns previous value and decrements
+ */
+ public void testGetAndDecrement() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.getAndDecrement(this));
+ assertEquals(0, a.getAndDecrement(this));
+ assertEquals(-1, a.getAndDecrement(this));
+ }
+
+ /**
+ * getAndIncrement returns previous value and increments
+ */
+ public void testGetAndIncrement() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(1, a.getAndIncrement(this));
+ assertEquals(2, a.get(this));
+ a.set(this, -2);
+ assertEquals(-2, a.getAndIncrement(this));
+ assertEquals(-1, a.getAndIncrement(this));
+ assertEquals(0, a.getAndIncrement(this));
+ assertEquals(1, a.get(this));
+ }
+
+ /**
+ * addAndGet adds given value to current, and returns current value
+ */
+ public void testAddAndGet() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(3, a.addAndGet(this, 2));
+ assertEquals(3, a.get(this));
+ assertEquals(-1, a.addAndGet(this, -4));
+ assertEquals(-1, a.get(this));
+ }
+
+ /**
+ * decrementAndGet decrements and returns current value
+ */
+ public void testDecrementAndGet() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(0, a.decrementAndGet(this));
+ assertEquals(-1, a.decrementAndGet(this));
+ assertEquals(-2, a.decrementAndGet(this));
+ assertEquals(-2, a.get(this));
+ }
+
+ /**
+ * incrementAndGet increments and returns current value
+ */
+ public void testIncrementAndGet() {
+ AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+ a = updaterFor("x");
+ x = 1;
+ assertEquals(2, a.incrementAndGet(this));
+ assertEquals(2, a.get(this));
+ a.set(this, -2);
+ assertEquals(-1, a.incrementAndGet(this));
+ assertEquals(0, a.incrementAndGet(this));
+ assertEquals(1, a.incrementAndGet(this));
+ assertEquals(1, a.get(this));
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java
new file mode 100644
index 0000000..d300367
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java
@@ -0,0 +1,264 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class AtomicLongTest extends JSR166TestCase {
+
+ final long[] VALUES = {
+ Long.MIN_VALUE,
+ Integer.MIN_VALUE, -1, 0, 1, 42, Integer.MAX_VALUE,
+ Long.MAX_VALUE,
+ };
+
+ /**
+ * constructor initializes to given value
+ */
+ public void testConstructor() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(1, ai.get());
+ }
+
+ /**
+ * default constructed initializes to zero
+ */
+ public void testConstructor2() {
+ AtomicLong ai = new AtomicLong();
+ assertEquals(0, ai.get());
+ }
+
+ /**
+ * get returns the last value set
+ */
+ public void testGetSet() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(1, ai.get());
+ ai.set(2);
+ assertEquals(2, ai.get());
+ ai.set(-3);
+ assertEquals(-3, ai.get());
+ }
+
+ /**
+ * get returns the last value lazySet in same thread
+ */
+ public void testGetLazySet() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(1, ai.get());
+ ai.lazySet(2);
+ assertEquals(2, ai.get());
+ ai.lazySet(-3);
+ assertEquals(-3, ai.get());
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicLong ai = new AtomicLong(1);
+ assertTrue(ai.compareAndSet(1, 2));
+ assertTrue(ai.compareAndSet(2, -4));
+ assertEquals(-4, ai.get());
+ assertFalse(ai.compareAndSet(-5, 7));
+ assertEquals(-4, ai.get());
+ assertTrue(ai.compareAndSet(-4, 7));
+ assertEquals(7, ai.get());
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ final AtomicLong ai = new AtomicLong(1);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!ai.compareAndSet(2, 3))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(ai.compareAndSet(1, 2));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertEquals(3, ai.get());
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicLong ai = new AtomicLong(1);
+ while (!ai.weakCompareAndSet(1, 2));
+ while (!ai.weakCompareAndSet(2, -4));
+ assertEquals(-4, ai.get());
+ while (!ai.weakCompareAndSet(-4, 7));
+ assertEquals(7, ai.get());
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value
+ */
+ public void testGetAndSet() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(1, ai.getAndSet(0));
+ assertEquals(0, ai.getAndSet(-10));
+ assertEquals(-10, ai.getAndSet(1));
+ }
+
+ /**
+ * getAndAdd returns previous value and adds given value
+ */
+ public void testGetAndAdd() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(1, ai.getAndAdd(2));
+ assertEquals(3, ai.get());
+ assertEquals(3, ai.getAndAdd(-4));
+ assertEquals(-1, ai.get());
+ }
+
+ /**
+ * getAndDecrement returns previous value and decrements
+ */
+ public void testGetAndDecrement() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(1, ai.getAndDecrement());
+ assertEquals(0, ai.getAndDecrement());
+ assertEquals(-1, ai.getAndDecrement());
+ }
+
+ /**
+ * getAndIncrement returns previous value and increments
+ */
+ public void testGetAndIncrement() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(1, ai.getAndIncrement());
+ assertEquals(2, ai.get());
+ ai.set(-2);
+ assertEquals(-2, ai.getAndIncrement());
+ assertEquals(-1, ai.getAndIncrement());
+ assertEquals(0, ai.getAndIncrement());
+ assertEquals(1, ai.get());
+ }
+
+ /**
+ * addAndGet adds given value to current, and returns current value
+ */
+ public void testAddAndGet() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(3, ai.addAndGet(2));
+ assertEquals(3, ai.get());
+ assertEquals(-1, ai.addAndGet(-4));
+ assertEquals(-1, ai.get());
+ }
+
+ /**
+ * decrementAndGet decrements and returns current value
+ */
+ public void testDecrementAndGet() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(0, ai.decrementAndGet());
+ assertEquals(-1, ai.decrementAndGet());
+ assertEquals(-2, ai.decrementAndGet());
+ assertEquals(-2, ai.get());
+ }
+
+ /**
+ * incrementAndGet increments and returns current value
+ */
+ public void testIncrementAndGet() {
+ AtomicLong ai = new AtomicLong(1);
+ assertEquals(2, ai.incrementAndGet());
+ assertEquals(2, ai.get());
+ ai.set(-2);
+ assertEquals(-1, ai.incrementAndGet());
+ assertEquals(0, ai.incrementAndGet());
+ assertEquals(1, ai.incrementAndGet());
+ assertEquals(1, ai.get());
+ }
+
+ /**
+ * a deserialized serialized atomic holds same value
+ */
+ public void testSerialization() throws Exception {
+ AtomicLong x = new AtomicLong();
+ AtomicLong y = serialClone(x);
+ assertNotSame(x, y);
+ x.set(-22);
+ AtomicLong z = serialClone(x);
+ assertNotSame(y, z);
+ assertEquals(-22, x.get());
+ assertEquals(0, y.get());
+ assertEquals(-22, z.get());
+ }
+
+ /**
+ * toString returns current value.
+ */
+ public void testToString() {
+ AtomicLong ai = new AtomicLong();
+ assertEquals("0", ai.toString());
+ for (long x : VALUES) {
+ ai.set(x);
+ assertEquals(Long.toString(x), ai.toString());
+ }
+ }
+
+ /**
+ * intValue returns current value.
+ */
+ public void testIntValue() {
+ AtomicLong ai = new AtomicLong();
+ assertEquals(0, ai.intValue());
+ for (long x : VALUES) {
+ ai.set(x);
+ assertEquals((int)x, ai.intValue());
+ }
+ }
+
+ /**
+ * longValue returns current value.
+ */
+ public void testLongValue() {
+ AtomicLong ai = new AtomicLong();
+ assertEquals(0L, ai.longValue());
+ for (long x : VALUES) {
+ ai.set(x);
+ assertEquals(x, ai.longValue());
+ }
+ }
+
+ /**
+ * floatValue returns current value.
+ */
+ public void testFloatValue() {
+ AtomicLong ai = new AtomicLong();
+ assertEquals(0.0f, ai.floatValue());
+ for (long x : VALUES) {
+ ai.set(x);
+ assertEquals((float)x, ai.floatValue());
+ }
+ }
+
+ /**
+ * doubleValue returns current value.
+ */
+ public void testDoubleValue() {
+ AtomicLong ai = new AtomicLong();
+ assertEquals(0.0d, ai.doubleValue());
+ for (long x : VALUES) {
+ ai.set(x);
+ assertEquals((double)x, ai.doubleValue());
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java
new file mode 100644
index 0000000..fd1f2f1
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java
@@ -0,0 +1,147 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicMarkableReference;
+
+public class AtomicMarkableReferenceTest extends JSR166TestCase {
+
+ /**
+ * constructor initializes to given reference and mark
+ */
+ public void testConstructor() {
+ AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+ assertSame(one, ai.getReference());
+ assertFalse(ai.isMarked());
+ AtomicMarkableReference a2 = new AtomicMarkableReference(null, true);
+ assertNull(a2.getReference());
+ assertTrue(a2.isMarked());
+ }
+
+ /**
+ * get returns the last values of reference and mark set
+ */
+ public void testGetSet() {
+ boolean[] mark = new boolean[1];
+ AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+ assertSame(one, ai.getReference());
+ assertFalse(ai.isMarked());
+ assertSame(one, ai.get(mark));
+ assertFalse(mark[0]);
+ ai.set(two, false);
+ assertSame(two, ai.getReference());
+ assertFalse(ai.isMarked());
+ assertSame(two, ai.get(mark));
+ assertFalse(mark[0]);
+ ai.set(one, true);
+ assertSame(one, ai.getReference());
+ assertTrue(ai.isMarked());
+ assertSame(one, ai.get(mark));
+ assertTrue(mark[0]);
+ }
+
+ /**
+ * attemptMark succeeds in single thread
+ */
+ public void testAttemptMark() {
+ boolean[] mark = new boolean[1];
+ AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+ assertFalse(ai.isMarked());
+ assertTrue(ai.attemptMark(one, true));
+ assertTrue(ai.isMarked());
+ assertSame(one, ai.get(mark));
+ assertTrue(mark[0]);
+ }
+
+ /**
+ * compareAndSet succeeds in changing values if equal to expected reference
+ * and mark else fails
+ */
+ public void testCompareAndSet() {
+ boolean[] mark = new boolean[1];
+ AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+ assertSame(one, ai.get(mark));
+ assertFalse(ai.isMarked());
+ assertFalse(mark[0]);
+
+ assertTrue(ai.compareAndSet(one, two, false, false));
+ assertSame(two, ai.get(mark));
+ assertFalse(mark[0]);
+
+ assertTrue(ai.compareAndSet(two, m3, false, true));
+ assertSame(m3, ai.get(mark));
+ assertTrue(mark[0]);
+
+ assertFalse(ai.compareAndSet(two, m3, true, true));
+ assertSame(m3, ai.get(mark));
+ assertTrue(mark[0]);
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for reference value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ final AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!ai.compareAndSet(two, three, false, false))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(ai.compareAndSet(one, two, false, false));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertSame(three, ai.getReference());
+ assertFalse(ai.isMarked());
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for mark value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads2() throws Exception {
+ final AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!ai.compareAndSet(one, one, true, false))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(ai.compareAndSet(one, one, false, true));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertSame(one, ai.getReference());
+ assertFalse(ai.isMarked());
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing values when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ boolean[] mark = new boolean[1];
+ AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+ assertSame(one, ai.get(mark));
+ assertFalse(ai.isMarked());
+ assertFalse(mark[0]);
+
+ while (!ai.weakCompareAndSet(one, two, false, false));
+ assertSame(two, ai.get(mark));
+ assertFalse(mark[0]);
+
+ while (!ai.weakCompareAndSet(two, m3, false, true));
+ assertSame(m3, ai.get(mark));
+ assertTrue(mark[0]);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java
new file mode 100644
index 0000000..0a4f3d9
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java
@@ -0,0 +1,213 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+public class AtomicReferenceArrayTest extends JSR166TestCase {
+
+ /**
+ * constructor creates array of given size with all elements null
+ */
+ public void testConstructor() {
+ AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ assertNull(aa.get(i));
+ }
+ }
+
+ /**
+ * constructor with null array throws NPE
+ */
+ public void testConstructor2NPE() {
+ try {
+ Integer[] a = null;
+ AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * constructor with array is of same size and has all elements
+ */
+ public void testConstructor2() {
+ Integer[] a = { two, one, three, four, seven };
+ AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a);
+ assertEquals(a.length, aa.length());
+ for (int i = 0; i < a.length; i++)
+ assertEquals(a[i], aa.get(i));
+ }
+
+ /**
+ * Initialize AtomicReferenceArray<Class> with SubClass[]
+ */
+ public void testConstructorSubClassArray() {
+ Integer[] a = { two, one, three, four, seven };
+ AtomicReferenceArray<Number> aa = new AtomicReferenceArray<Number>(a);
+ assertEquals(a.length, aa.length());
+ for (int i = 0; i < a.length; i++) {
+ assertSame(a[i], aa.get(i));
+ Long x = Long.valueOf(i);
+ aa.set(i, x);
+ assertSame(x, aa.get(i));
+ }
+ }
+
+ /**
+ * get and set for out of bound indices throw IndexOutOfBoundsException
+ */
+ public void testIndexing() {
+ AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(SIZE);
+ for (int index : new int[] { -1, SIZE }) {
+ try {
+ aa.get(index);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.set(index, null);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.lazySet(index, null);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.compareAndSet(index, null, null);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ try {
+ aa.weakCompareAndSet(index, null, null);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+ }
+
+ /**
+ * get returns the last value set at index
+ */
+ public void testGetSet() {
+ AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, one);
+ assertSame(one, aa.get(i));
+ aa.set(i, two);
+ assertSame(two, aa.get(i));
+ aa.set(i, m3);
+ assertSame(m3, aa.get(i));
+ }
+ }
+
+ /**
+ * get returns the last value lazySet at index by same thread
+ */
+ public void testGetLazySet() {
+ AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.lazySet(i, one);
+ assertSame(one, aa.get(i));
+ aa.lazySet(i, two);
+ assertSame(two, aa.get(i));
+ aa.lazySet(i, m3);
+ assertSame(m3, aa.get(i));
+ }
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, one);
+ assertTrue(aa.compareAndSet(i, one, two));
+ assertTrue(aa.compareAndSet(i, two, m4));
+ assertSame(m4, aa.get(i));
+ assertFalse(aa.compareAndSet(i, m5, seven));
+ assertSame(m4, aa.get(i));
+ assertTrue(aa.compareAndSet(i, m4, seven));
+ assertSame(seven, aa.get(i));
+ }
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws InterruptedException {
+ final AtomicReferenceArray a = new AtomicReferenceArray(1);
+ a.set(0, one);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!a.compareAndSet(0, two, three))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(a.compareAndSet(0, one, two));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertSame(three, a.get(0));
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, one);
+ while (!aa.weakCompareAndSet(i, one, two));
+ while (!aa.weakCompareAndSet(i, two, m4));
+ assertSame(m4, aa.get(i));
+ while (!aa.weakCompareAndSet(i, m4, seven));
+ assertSame(seven, aa.get(i));
+ }
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value at given index
+ */
+ public void testGetAndSet() {
+ AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ aa.set(i, one);
+ assertSame(one, aa.getAndSet(i, zero));
+ assertSame(zero, aa.getAndSet(i, m10));
+ assertSame(m10, aa.getAndSet(i, one));
+ }
+ }
+
+ /**
+ * a deserialized serialized array holds same values
+ */
+ public void testSerialization() throws Exception {
+ AtomicReferenceArray x = new AtomicReferenceArray(SIZE);
+ for (int i = 0; i < SIZE; i++) {
+ x.set(i, new Integer(-i));
+ }
+ AtomicReferenceArray y = serialClone(x);
+ assertNotSame(x, y);
+ assertEquals(x.length(), y.length());
+ for (int i = 0; i < SIZE; i++) {
+ assertEquals(x.get(i), y.get(i));
+ }
+ }
+
+ /**
+ * toString returns current value.
+ */
+ public void testToString() {
+ Integer[] a = { two, one, three, four, seven };
+ AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a);
+ assertEquals(Arrays.toString(a), aa.toString());
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
new file mode 100644
index 0000000..271c7b7
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
@@ -0,0 +1,160 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase {
+ volatile Integer x = null;
+ Object z;
+ Integer w;
+ volatile int i;
+
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) {
+ return AtomicReferenceFieldUpdater.newUpdater
+ (AtomicReferenceFieldUpdaterTest.class, Integer.class, fieldName);
+ }
+
+ /**
+ * Construction with non-existent field throws RuntimeException
+ */
+ public void testConstructor() {
+ try {
+ updaterFor("y");
+ shouldThrow();
+ } catch (RuntimeException success) {
+ assertNotNull(success.getCause());
+ }
+ }
+
+ /**
+ * construction with field not of given type throws ClassCastException
+ */
+ public void testConstructor2() {
+ try {
+ updaterFor("z");
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * Constructor with non-volatile field throws IllegalArgumentException
+ */
+ public void testConstructor3() {
+ try {
+ updaterFor("w");
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor with non-reference field throws ClassCastException
+ */
+ public void testConstructor4() {
+ try {
+ updaterFor("i");
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * get returns the last value set or assigned
+ */
+ public void testGetSet() {
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
+ a = updaterFor("x");
+ x = one;
+ assertSame(one, a.get(this));
+ a.set(this, two);
+ assertSame(two, a.get(this));
+ a.set(this, m3);
+ assertSame(m3, a.get(this));
+ }
+
+ /**
+ * get returns the last value lazySet by same thread
+ */
+ public void testGetLazySet() {
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
+ a = updaterFor("x");
+ x = one;
+ assertSame(one, a.get(this));
+ a.lazySet(this, two);
+ assertSame(two, a.get(this));
+ a.lazySet(this, m3);
+ assertSame(m3, a.get(this));
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
+ a = updaterFor("x");
+ x = one;
+ assertTrue(a.compareAndSet(this, one, two));
+ assertTrue(a.compareAndSet(this, two, m4));
+ assertSame(m4, a.get(this));
+ assertFalse(a.compareAndSet(this, m5, seven));
+ assertFalse(seven == a.get(this));
+ assertTrue(a.compareAndSet(this, m4, seven));
+ assertSame(seven, a.get(this));
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ x = one;
+ final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
+ a = updaterFor("x");
+
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(a.compareAndSet(this, one, two));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertSame(three, a.get(this));
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
+ a = updaterFor("x");
+ x = one;
+ while (!a.weakCompareAndSet(this, one, two));
+ while (!a.weakCompareAndSet(this, two, m4));
+ assertSame(m4, a.get(this));
+ while (!a.weakCompareAndSet(this, m4, seven));
+ assertSame(seven, a.get(this));
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value
+ */
+ public void testGetAndSet() {
+ AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
+ a = updaterFor("x");
+ x = one;
+ assertSame(one, a.getAndSet(this, zero));
+ assertSame(zero, a.getAndSet(this, m10));
+ assertSame(m10, a.getAndSet(this, 1));
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java
new file mode 100644
index 0000000..8032546
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java
@@ -0,0 +1,137 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class AtomicReferenceTest extends JSR166TestCase {
+
+ /**
+ * constructor initializes to given value
+ */
+ public void testConstructor() {
+ AtomicReference ai = new AtomicReference(one);
+ assertSame(one, ai.get());
+ }
+
+ /**
+ * default constructed initializes to null
+ */
+ public void testConstructor2() {
+ AtomicReference ai = new AtomicReference();
+ assertNull(ai.get());
+ }
+
+ /**
+ * get returns the last value set
+ */
+ public void testGetSet() {
+ AtomicReference ai = new AtomicReference(one);
+ assertSame(one, ai.get());
+ ai.set(two);
+ assertSame(two, ai.get());
+ ai.set(m3);
+ assertSame(m3, ai.get());
+ }
+
+ /**
+ * get returns the last value lazySet in same thread
+ */
+ public void testGetLazySet() {
+ AtomicReference ai = new AtomicReference(one);
+ assertSame(one, ai.get());
+ ai.lazySet(two);
+ assertSame(two, ai.get());
+ ai.lazySet(m3);
+ assertSame(m3, ai.get());
+ }
+
+ /**
+ * compareAndSet succeeds in changing value if equal to expected else fails
+ */
+ public void testCompareAndSet() {
+ AtomicReference ai = new AtomicReference(one);
+ assertTrue(ai.compareAndSet(one, two));
+ assertTrue(ai.compareAndSet(two, m4));
+ assertSame(m4, ai.get());
+ assertFalse(ai.compareAndSet(m5, seven));
+ assertSame(m4, ai.get());
+ assertTrue(ai.compareAndSet(m4, seven));
+ assertSame(seven, ai.get());
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ final AtomicReference ai = new AtomicReference(one);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!ai.compareAndSet(two, three))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(ai.compareAndSet(one, two));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertSame(three, ai.get());
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing value when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ AtomicReference ai = new AtomicReference(one);
+ while (!ai.weakCompareAndSet(one, two));
+ while (!ai.weakCompareAndSet(two, m4));
+ assertSame(m4, ai.get());
+ while (!ai.weakCompareAndSet(m4, seven));
+ assertSame(seven, ai.get());
+ }
+
+ /**
+ * getAndSet returns previous value and sets to given value
+ */
+ public void testGetAndSet() {
+ AtomicReference ai = new AtomicReference(one);
+ assertSame(one, ai.getAndSet(zero));
+ assertSame(zero, ai.getAndSet(m10));
+ assertSame(m10, ai.getAndSet(one));
+ }
+
+ /**
+ * a deserialized serialized atomic holds same value
+ */
+ public void testSerialization() throws Exception {
+ AtomicReference x = new AtomicReference();
+ AtomicReference y = serialClone(x);
+ assertNotSame(x, y);
+ x.set(one);
+ AtomicReference z = serialClone(x);
+ assertNotSame(y, z);
+ assertEquals(one, x.get());
+ assertEquals(null, y.get());
+ assertEquals(one, z.get());
+ }
+
+ /**
+ * toString returns current value.
+ */
+ public void testToString() {
+ AtomicReference<Integer> ai = new AtomicReference<Integer>(one);
+ assertEquals(one.toString(), ai.toString());
+ ai.set(two);
+ assertEquals(two.toString(), ai.toString());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java
new file mode 100644
index 0000000..3e6445e
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java
@@ -0,0 +1,147 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicStampedReference;
+
+public class AtomicStampedReferenceTest extends JSR166TestCase {
+
+ /**
+ * constructor initializes to given reference and stamp
+ */
+ public void testConstructor() {
+ AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+ assertSame(one, ai.getReference());
+ assertEquals(0, ai.getStamp());
+ AtomicStampedReference a2 = new AtomicStampedReference(null, 1);
+ assertNull(a2.getReference());
+ assertEquals(1, a2.getStamp());
+ }
+
+ /**
+ * get returns the last values of reference and stamp set
+ */
+ public void testGetSet() {
+ int[] mark = new int[1];
+ AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+ assertSame(one, ai.getReference());
+ assertEquals(0, ai.getStamp());
+ assertSame(one, ai.get(mark));
+ assertEquals(0, mark[0]);
+ ai.set(two, 0);
+ assertSame(two, ai.getReference());
+ assertEquals(0, ai.getStamp());
+ assertSame(two, ai.get(mark));
+ assertEquals(0, mark[0]);
+ ai.set(one, 1);
+ assertSame(one, ai.getReference());
+ assertEquals(1, ai.getStamp());
+ assertSame(one, ai.get(mark));
+ assertEquals(1, mark[0]);
+ }
+
+ /**
+ * attemptStamp succeeds in single thread
+ */
+ public void testAttemptStamp() {
+ int[] mark = new int[1];
+ AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+ assertEquals(0, ai.getStamp());
+ assertTrue(ai.attemptStamp(one, 1));
+ assertEquals(1, ai.getStamp());
+ assertSame(one, ai.get(mark));
+ assertEquals(1, mark[0]);
+ }
+
+ /**
+ * compareAndSet succeeds in changing values if equal to expected reference
+ * and stamp else fails
+ */
+ public void testCompareAndSet() {
+ int[] mark = new int[1];
+ AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+ assertSame(one, ai.get(mark));
+ assertEquals(0, ai.getStamp());
+ assertEquals(0, mark[0]);
+
+ assertTrue(ai.compareAndSet(one, two, 0, 0));
+ assertSame(two, ai.get(mark));
+ assertEquals(0, mark[0]);
+
+ assertTrue(ai.compareAndSet(two, m3, 0, 1));
+ assertSame(m3, ai.get(mark));
+ assertEquals(1, mark[0]);
+
+ assertFalse(ai.compareAndSet(two, m3, 1, 1));
+ assertSame(m3, ai.get(mark));
+ assertEquals(1, mark[0]);
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for reference value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads() throws Exception {
+ final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!ai.compareAndSet(two, three, 0, 0))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(ai.compareAndSet(one, two, 0, 0));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertSame(three, ai.getReference());
+ assertEquals(0, ai.getStamp());
+ }
+
+ /**
+ * compareAndSet in one thread enables another waiting for stamp value
+ * to succeed
+ */
+ public void testCompareAndSetInMultipleThreads2() throws Exception {
+ final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ while (!ai.compareAndSet(one, one, 1, 2))
+ Thread.yield();
+ }});
+
+ t.start();
+ assertTrue(ai.compareAndSet(one, one, 0, 1));
+ t.join(LONG_DELAY_MS);
+ assertFalse(t.isAlive());
+ assertSame(one, ai.getReference());
+ assertEquals(2, ai.getStamp());
+ }
+
+ /**
+ * repeated weakCompareAndSet succeeds in changing values when equal
+ * to expected
+ */
+ public void testWeakCompareAndSet() {
+ int[] mark = new int[1];
+ AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+ assertSame(one, ai.get(mark));
+ assertEquals(0, ai.getStamp());
+ assertEquals(0, mark[0]);
+
+ while (!ai.weakCompareAndSet(one, two, 0, 0));
+ assertSame(two, ai.get(mark));
+ assertEquals(0, mark[0]);
+
+ while (!ai.weakCompareAndSet(two, m3, 0, 1));
+ assertSame(m3, ai.get(mark));
+ assertEquals(1, mark[0]);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java
new file mode 100644
index 0000000..1ed7559
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java
@@ -0,0 +1,366 @@
+/*
+ * Written by Doug Lea and Martin Buchholz with assistance from members
+ * of JCP JSR-166 Expert Group and released to the public domain, as
+ * explained at http://creativecommons.org/publicdomain/zero/1.0/
+ *
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+/**
+ * Contains "contract" tests applicable to all BlockingQueue implementations.
+ */
+public abstract class BlockingQueueTest extends JSR166TestCase {
+ /*
+ * This is the start of an attempt to refactor the tests for the
+ * various related implementations of related interfaces without
+ * too much duplicated code. junit does not really support such
+ * testing. Here subclasses of TestCase not only contain tests,
+ * but also configuration information that describes the
+ * implementation class, most importantly how to instantiate
+ * instances.
+ */
+
+ //----------------------------------------------------------------
+ // Configuration methods
+ //----------------------------------------------------------------
+
+ /** Returns an empty instance of the implementation class. */
+ protected abstract BlockingQueue emptyCollection();
+
+ /**
+ * Returns an element suitable for insertion in the collection.
+ * Override for collections with unusual element types.
+ */
+ protected Object makeElement(int i) {
+ return Integer.valueOf(i);
+ }
+
+ //----------------------------------------------------------------
+ // Tests
+ //----------------------------------------------------------------
+
+ /**
+ * offer(null) throws NullPointerException
+ */
+ public void testOfferNull() {
+ final Queue q = emptyCollection();
+ try {
+ q.offer(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * add(null) throws NullPointerException
+ */
+ public void testAddNull() {
+ final Collection q = emptyCollection();
+ try {
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * timed offer(null) throws NullPointerException
+ */
+ public void testTimedOfferNull() throws InterruptedException {
+ final BlockingQueue q = emptyCollection();
+ long startTime = System.nanoTime();
+ try {
+ q.offer(null, LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+
+ /**
+ * put(null) throws NullPointerException
+ */
+ public void testPutNull() throws InterruptedException {
+ final BlockingQueue q = emptyCollection();
+ try {
+ q.put(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * put(null) throws NullPointerException
+ */
+ public void testAddAllNull() throws InterruptedException {
+ final Collection q = emptyCollection();
+ try {
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NullPointerException
+ */
+ public void testAddAllNullElements() {
+ final Collection q = emptyCollection();
+ final Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+ try {
+ q.addAll(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * toArray(null) throws NullPointerException
+ */
+ public void testToArray_NullArray() {
+ final Collection q = emptyCollection();
+ try {
+ q.toArray(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * drainTo(null) throws NullPointerException
+ */
+ public void testDrainToNull() {
+ final BlockingQueue q = emptyCollection();
+ try {
+ q.drainTo(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * drainTo(this) throws IllegalArgumentException
+ */
+ public void testDrainToSelf() {
+ final BlockingQueue q = emptyCollection();
+ try {
+ q.drainTo(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * drainTo(null, n) throws NullPointerException
+ */
+ public void testDrainToNullN() {
+ final BlockingQueue q = emptyCollection();
+ try {
+ q.drainTo(null, 0);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * drainTo(this, n) throws IllegalArgumentException
+ */
+ public void testDrainToSelfN() {
+ final BlockingQueue q = emptyCollection();
+ try {
+ q.drainTo(q, 0);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * drainTo(c, n) returns 0 and does nothing when n <= 0
+ */
+ public void testDrainToNonPositiveMaxElements() {
+ final BlockingQueue q = emptyCollection();
+ final int[] ns = { 0, -1, -42, Integer.MIN_VALUE };
+ for (int n : ns)
+ assertEquals(0, q.drainTo(new ArrayList(), n));
+ if (q.remainingCapacity() > 0) {
+ // Not SynchronousQueue, that is
+ Object one = makeElement(1);
+ q.add(one);
+ ArrayList c = new ArrayList();
+ for (int n : ns)
+ assertEquals(0, q.drainTo(new ArrayList(), n));
+ assertEquals(1, q.size());
+ assertSame(one, q.poll());
+ assertTrue(c.isEmpty());
+ }
+ }
+
+ /**
+ * timed poll before a delayed offer times out; after offer succeeds;
+ * on interruption throws
+ */
+ public void testTimedPollWithOffer() throws InterruptedException {
+ final BlockingQueue q = emptyCollection();
+ final CheckedBarrier barrier = new CheckedBarrier(2);
+ final Object zero = makeElement(0);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ barrier.await();
+
+ assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+
+ Thread.currentThread().interrupt();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ barrier.await();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ barrier.await();
+ long startTime = System.nanoTime();
+ assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+
+ barrier.await();
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * take() blocks interruptibly when empty
+ */
+ public void testTakeFromEmptyBlocksInterruptibly() {
+ final BlockingQueue q = emptyCollection();
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ threadStarted.countDown();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(threadStarted);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * take() throws InterruptedException immediately if interrupted
+ * before waiting
+ */
+ public void testTakeFromEmptyAfterInterrupt() {
+ final BlockingQueue q = emptyCollection();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread.currentThread().interrupt();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * timed poll() blocks interruptibly when empty
+ */
+ public void testTimedPollFromEmptyBlocksInterruptibly() {
+ final BlockingQueue q = emptyCollection();
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ threadStarted.countDown();
+ try {
+ q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(threadStarted);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timed poll() throws InterruptedException immediately if
+ * interrupted before waiting
+ */
+ public void testTimedPollFromEmptyAfterInterrupt() {
+ final BlockingQueue q = emptyCollection();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread.currentThread().interrupt();
+ try {
+ q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ * TODO: move to superclass CollectionTest.java
+ */
+ public void testRemoveElement() {
+ final BlockingQueue q = emptyCollection();
+ final int size = Math.min(q.remainingCapacity(), SIZE);
+ final Object[] elts = new Object[size];
+ assertFalse(q.contains(makeElement(99)));
+ assertFalse(q.remove(makeElement(99)));
+ checkEmpty(q);
+ for (int i = 0; i < size; i++)
+ q.add(elts[i] = makeElement(i));
+ for (int i = 1; i < size; i+=2) {
+ for (int pass = 0; pass < 2; pass++) {
+ assertEquals((pass == 0), q.contains(elts[i]));
+ assertEquals((pass == 0), q.remove(elts[i]));
+ assertFalse(q.contains(elts[i]));
+ assertTrue(q.contains(elts[i-1]));
+ if (i < size - 1)
+ assertTrue(q.contains(elts[i+1]));
+ }
+ }
+ if (size > 0)
+ assertTrue(q.contains(elts[0]));
+ for (int i = size-2; i >= 0; i-=2) {
+ assertTrue(q.contains(elts[i]));
+ assertFalse(q.contains(elts[i+1]));
+ assertTrue(q.remove(elts[i]));
+ assertFalse(q.contains(elts[i]));
+ assertFalse(q.remove(elts[i+1]));
+ assertFalse(q.contains(elts[i+1]));
+ }
+ checkEmpty(q);
+ }
+
+ /** For debugging. */
+ public void XXXXtestFails() {
+ fail(emptyCollection().getClass().toString());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java
new file mode 100644
index 0000000..5d9e2ac
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java
@@ -0,0 +1,686 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class ConcurrentHashMapTest extends JSR166TestCase {
+
+ /**
+ * Returns a new map from Integers 1-5 to Strings "A"-"E".
+ */
+ private static ConcurrentHashMap map5() {
+ ConcurrentHashMap map = new ConcurrentHashMap(5);
+ assertTrue(map.isEmpty());
+ map.put(one, "A");
+ map.put(two, "B");
+ map.put(three, "C");
+ map.put(four, "D");
+ map.put(five, "E");
+ assertFalse(map.isEmpty());
+ assertEquals(5, map.size());
+ return map;
+ }
+
+ // classes for testing Comparable fallbacks
+ static class BI implements Comparable<BI> {
+ private final int value;
+ BI(int value) { this.value = value; }
+ public int compareTo(BI other) {
+ return Integer.compare(value, other.value);
+ }
+ public boolean equals(Object x) {
+ return (x instanceof BI) && ((BI)x).value == value;
+ }
+ public int hashCode() { return 42; }
+ }
+ static class CI extends BI { CI(int value) { super(value); } }
+ static class DI extends BI { DI(int value) { super(value); } }
+
+ static class BS implements Comparable<BS> {
+ private final String value;
+ BS(String value) { this.value = value; }
+ public int compareTo(BS other) {
+ return value.compareTo(other.value);
+ }
+ public boolean equals(Object x) {
+ return (x instanceof BS) && value.equals(((BS)x).value);
+ }
+ public int hashCode() { return 42; }
+ }
+
+ static class LexicographicList<E extends Comparable<E>> extends ArrayList<E>
+ implements Comparable<LexicographicList<E>> {
+ static long total;
+ static long n;
+ LexicographicList(Collection<E> c) { super(c); }
+ LexicographicList(E e) { super(Collections.singleton(e)); }
+ public int compareTo(LexicographicList<E> other) {
+ long start = System.currentTimeMillis();
+ int common = Math.min(size(), other.size());
+ int r = 0;
+ for (int i = 0; i < common; i++) {
+ if ((r = get(i).compareTo(other.get(i))) != 0)
+ break;
+ }
+ if (r == 0)
+ r = Integer.compare(size(), other.size());
+ total += System.currentTimeMillis() - start;
+ n++;
+ return r;
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Inserted elements that are subclasses of the same Comparable
+ * class are found.
+ */
+ public void testComparableFamily() {
+ ConcurrentHashMap<BI, Boolean> m =
+ new ConcurrentHashMap<BI, Boolean>();
+ for (int i = 0; i < 1000; i++) {
+ assertTrue(m.put(new CI(i), true) == null);
+ }
+ for (int i = 0; i < 1000; i++) {
+ assertTrue(m.containsKey(new CI(i)));
+ assertTrue(m.containsKey(new DI(i)));
+ }
+ }
+
+ /**
+ * Elements of classes with erased generic type parameters based
+ * on Comparable can be inserted and found.
+ */
+ public void testGenericComparable() {
+ ConcurrentHashMap<Object, Boolean> m =
+ new ConcurrentHashMap<Object, Boolean>();
+ for (int i = 0; i < 1000; i++) {
+ BI bi = new BI(i);
+ BS bs = new BS(String.valueOf(i));
+ LexicographicList<BI> bis = new LexicographicList<BI>(bi);
+ LexicographicList<BS> bss = new LexicographicList<BS>(bs);
+ assertTrue(m.putIfAbsent(bis, true) == null);
+ assertTrue(m.containsKey(bis));
+ if (m.putIfAbsent(bss, true) == null)
+ assertTrue(m.containsKey(bss));
+ assertTrue(m.containsKey(bis));
+ }
+ for (int i = 0; i < 1000; i++) {
+ assertTrue(m.containsKey(new ArrayList(Collections.singleton(new BI(i)))));
+ }
+ }
+
+ /**
+ * Elements of non-comparable classes equal to those of classes
+ * with erased generic type parameters based on Comparable can be
+ * inserted and found.
+ */
+ public void testGenericComparable2() {
+ ConcurrentHashMap<Object, Boolean> m =
+ new ConcurrentHashMap<Object, Boolean>();
+ for (int i = 0; i < 1000; i++) {
+ m.put(new ArrayList(Collections.singleton(new BI(i))), true);
+ }
+
+ for (int i = 0; i < 1000; i++) {
+ LexicographicList<BI> bis = new LexicographicList<BI>(new BI(i));
+ assertTrue(m.containsKey(bis));
+ }
+ }
+
+ /**
+ * clear removes all pairs
+ */
+ public void testClear() {
+ ConcurrentHashMap map = map5();
+ map.clear();
+ assertEquals(0, map.size());
+ }
+
+ /**
+ * Maps with same contents are equal
+ */
+ public void testEquals() {
+ ConcurrentHashMap map1 = map5();
+ ConcurrentHashMap map2 = map5();
+ assertEquals(map1, map2);
+ assertEquals(map2, map1);
+ map1.clear();
+ assertFalse(map1.equals(map2));
+ assertFalse(map2.equals(map1));
+ }
+
+ /**
+ * contains returns true for contained value
+ */
+ public void testContains() {
+ ConcurrentHashMap map = map5();
+ assertTrue(map.contains("A"));
+ assertFalse(map.contains("Z"));
+ }
+
+ /**
+ * containsKey returns true for contained key
+ */
+ public void testContainsKey() {
+ ConcurrentHashMap map = map5();
+ assertTrue(map.containsKey(one));
+ assertFalse(map.containsKey(zero));
+ }
+
+ /**
+ * containsValue returns true for held values
+ */
+ public void testContainsValue() {
+ ConcurrentHashMap map = map5();
+ assertTrue(map.containsValue("A"));
+ assertFalse(map.containsValue("Z"));
+ }
+
+ /**
+ * enumeration returns an enumeration containing the correct
+ * elements
+ */
+ public void testEnumeration() {
+ ConcurrentHashMap map = map5();
+ Enumeration e = map.elements();
+ int count = 0;
+ while (e.hasMoreElements()) {
+ count++;
+ e.nextElement();
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * get returns the correct element at the given key,
+ * or null if not present
+ */
+ public void testGet() {
+ ConcurrentHashMap map = map5();
+ assertEquals("A", (String)map.get(one));
+ ConcurrentHashMap empty = new ConcurrentHashMap();
+ assertNull(map.get("anything"));
+ }
+
+ /**
+ * isEmpty is true of empty map and false for non-empty
+ */
+ public void testIsEmpty() {
+ ConcurrentHashMap empty = new ConcurrentHashMap();
+ ConcurrentHashMap map = map5();
+ assertTrue(empty.isEmpty());
+ assertFalse(map.isEmpty());
+ }
+
+ /**
+ * keys returns an enumeration containing all the keys from the map
+ */
+ public void testKeys() {
+ ConcurrentHashMap map = map5();
+ Enumeration e = map.keys();
+ int count = 0;
+ while (e.hasMoreElements()) {
+ count++;
+ e.nextElement();
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * keySet returns a Set containing all the keys
+ */
+ public void testKeySet() {
+ ConcurrentHashMap map = map5();
+ Set s = map.keySet();
+ assertEquals(5, s.size());
+ assertTrue(s.contains(one));
+ assertTrue(s.contains(two));
+ assertTrue(s.contains(three));
+ assertTrue(s.contains(four));
+ assertTrue(s.contains(five));
+ }
+
+ /**
+ * keySet.toArray returns contains all keys
+ */
+ public void testKeySetToArray() {
+ ConcurrentHashMap map = map5();
+ Set s = map.keySet();
+ Object[] ar = s.toArray();
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ assertEquals(5, ar.length);
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * Values.toArray contains all values
+ */
+ public void testValuesToArray() {
+ ConcurrentHashMap map = map5();
+ Collection v = map.values();
+ Object[] ar = v.toArray();
+ ArrayList s = new ArrayList(Arrays.asList(ar));
+ assertEquals(5, ar.length);
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * entrySet.toArray contains all entries
+ */
+ public void testEntrySetToArray() {
+ ConcurrentHashMap map = map5();
+ Set s = map.entrySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ for (int i = 0; i < 5; ++i) {
+ assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+ assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+ }
+ }
+
+ /**
+ * values collection contains all values
+ */
+ public void testValues() {
+ ConcurrentHashMap map = map5();
+ Collection s = map.values();
+ assertEquals(5, s.size());
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * entrySet contains all pairs
+ */
+ public void testEntrySet() {
+ ConcurrentHashMap map = map5();
+ Set s = map.entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(one) && e.getValue().equals("A")) ||
+ (e.getKey().equals(two) && e.getValue().equals("B")) ||
+ (e.getKey().equals(three) && e.getValue().equals("C")) ||
+ (e.getKey().equals(four) && e.getValue().equals("D")) ||
+ (e.getKey().equals(five) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * putAll adds all key-value pairs from the given map
+ */
+ public void testPutAll() {
+ ConcurrentHashMap empty = new ConcurrentHashMap();
+ ConcurrentHashMap map = map5();
+ empty.putAll(map);
+ assertEquals(5, empty.size());
+ assertTrue(empty.containsKey(one));
+ assertTrue(empty.containsKey(two));
+ assertTrue(empty.containsKey(three));
+ assertTrue(empty.containsKey(four));
+ assertTrue(empty.containsKey(five));
+ }
+
+ /**
+ * putIfAbsent works when the given key is not present
+ */
+ public void testPutIfAbsent() {
+ ConcurrentHashMap map = map5();
+ map.putIfAbsent(six, "Z");
+ assertTrue(map.containsKey(six));
+ }
+
+ /**
+ * putIfAbsent does not add the pair if the key is already present
+ */
+ public void testPutIfAbsent2() {
+ ConcurrentHashMap map = map5();
+ assertEquals("A", map.putIfAbsent(one, "Z"));
+ }
+
+ /**
+ * replace fails when the given key is not present
+ */
+ public void testReplace() {
+ ConcurrentHashMap map = map5();
+ assertNull(map.replace(six, "Z"));
+ assertFalse(map.containsKey(six));
+ }
+
+ /**
+ * replace succeeds if the key is already present
+ */
+ public void testReplace2() {
+ ConcurrentHashMap map = map5();
+ assertNotNull(map.replace(one, "Z"));
+ assertEquals("Z", map.get(one));
+ }
+
+ /**
+ * replace value fails when the given key not mapped to expected value
+ */
+ public void testReplaceValue() {
+ ConcurrentHashMap map = map5();
+ assertEquals("A", map.get(one));
+ assertFalse(map.replace(one, "Z", "Z"));
+ assertEquals("A", map.get(one));
+ }
+
+ /**
+ * replace value succeeds when the given key mapped to expected value
+ */
+ public void testReplaceValue2() {
+ ConcurrentHashMap map = map5();
+ assertEquals("A", map.get(one));
+ assertTrue(map.replace(one, "A", "Z"));
+ assertEquals("Z", map.get(one));
+ }
+
+ /**
+ * remove removes the correct key-value pair from the map
+ */
+ public void testRemove() {
+ ConcurrentHashMap map = map5();
+ map.remove(five);
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(five));
+ }
+
+ /**
+ * remove(key,value) removes only if pair present
+ */
+ public void testRemove2() {
+ ConcurrentHashMap map = map5();
+ map.remove(five, "E");
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(five));
+ map.remove(four, "A");
+ assertEquals(4, map.size());
+ assertTrue(map.containsKey(four));
+ }
+
+ /**
+ * size returns the correct values
+ */
+ public void testSize() {
+ ConcurrentHashMap map = map5();
+ ConcurrentHashMap empty = new ConcurrentHashMap();
+ assertEquals(0, empty.size());
+ assertEquals(5, map.size());
+ }
+
+ /**
+ * toString contains toString of elements
+ */
+ public void testToString() {
+ ConcurrentHashMap map = map5();
+ String s = map.toString();
+ for (int i = 1; i <= 5; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ // Exception tests
+
+ /**
+ * Cannot create with negative capacity
+ */
+ public void testConstructor1() {
+ try {
+ new ConcurrentHashMap(-1,0,1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Cannot create with negative concurrency level
+ */
+ public void testConstructor2() {
+ try {
+ new ConcurrentHashMap(1,0,-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Cannot create with only negative capacity
+ */
+ public void testConstructor3() {
+ try {
+ new ConcurrentHashMap(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * get(null) throws NPE
+ */
+ public void testGet_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.get(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsKey(null) throws NPE
+ */
+ public void testContainsKey_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.containsKey(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsValue(null) throws NPE
+ */
+ public void testContainsValue_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.containsValue(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * contains(null) throws NPE
+ */
+ public void testContains_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.contains(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * put(null,x) throws NPE
+ */
+ public void testPut1_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.put(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * put(x, null) throws NPE
+ */
+ public void testPut2_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.put("whatever", null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * putIfAbsent(null, x) throws NPE
+ */
+ public void testPutIfAbsent1_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.putIfAbsent(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(null, x) throws NPE
+ */
+ public void testReplace_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.replace(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(null, x, y) throws NPE
+ */
+ public void testReplaceValue_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.replace(null, one, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * putIfAbsent(x, null) throws NPE
+ */
+ public void testPutIfAbsent2_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.putIfAbsent("whatever", null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(x, null) throws NPE
+ */
+ public void testReplace2_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.replace("whatever", null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(x, null, y) throws NPE
+ */
+ public void testReplaceValue2_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.replace("whatever", null, "A");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(x, y, null) throws NPE
+ */
+ public void testReplaceValue3_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.replace("whatever", one, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null) throws NPE
+ */
+ public void testRemove1_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.put("sadsdf", "asdads");
+ c.remove(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null, x) throws NPE
+ */
+ public void testRemove2_NullPointerException() {
+ try {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.put("sadsdf", "asdads");
+ c.remove(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(x, null) returns false
+ */
+ public void testRemove3() {
+ ConcurrentHashMap c = new ConcurrentHashMap(5);
+ c.put("sadsdf", "asdads");
+ assertFalse(c.remove("sadsdf", null));
+ }
+
+ /**
+ * A deserialized map equals original
+ */
+ public void testSerialization() throws Exception {
+ Map x = map5();
+ Map y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ /**
+ * SetValue of an EntrySet entry sets value in the map.
+ */
+ public void testSetValueWriteThrough() {
+ // Adapted from a bug report by Eric Zoerner
+ ConcurrentHashMap map = new ConcurrentHashMap(2, 5.0f, 1);
+ assertTrue(map.isEmpty());
+ for (int i = 0; i < 20; i++)
+ map.put(new Integer(i), new Integer(i));
+ assertFalse(map.isEmpty());
+ Map.Entry entry1 = (Map.Entry)map.entrySet().iterator().next();
+ // Unless it happens to be first (in which case remainder of
+ // test is skipped), remove a possibly-colliding key from map
+ // which, under some implementations, may cause entry1 to be
+ // cloned in map
+ if (!entry1.getKey().equals(new Integer(16))) {
+ map.remove(new Integer(16));
+ entry1.setValue("XYZ");
+ assertTrue(map.containsValue("XYZ")); // fails if write-through broken
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java
new file mode 100644
index 0000000..f5b8318
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java
@@ -0,0 +1,858 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.ConcurrentLinkedDeque;
+
+public class ConcurrentLinkedDequeTest extends JSR166TestCase {
+
+ /**
+ * Returns a new deque of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private ConcurrentLinkedDeque<Integer> populatedDeque(int n) {
+ ConcurrentLinkedDeque<Integer> q = new ConcurrentLinkedDeque<Integer>();
+ assertTrue(q.isEmpty());
+ for (int i = 0; i < n; ++i)
+ assertTrue(q.offer(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * new deque is empty
+ */
+ public void testConstructor1() {
+ assertTrue(new ConcurrentLinkedDeque().isEmpty());
+ assertEquals(0, new ConcurrentLinkedDeque().size());
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque((Collection)null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Deque contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ assertTrue(q.isEmpty());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ q.add(two);
+ q.remove();
+ q.remove();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size() changes when elements added and removed
+ */
+ public void testSize() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * push(null) throws NPE
+ */
+ public void testPushNull() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.push(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * peekFirst() returns element inserted with push
+ */
+ public void testPush() {
+ ConcurrentLinkedDeque q = populatedDeque(3);
+ q.pollLast();
+ q.push(four);
+ assertSame(four, q.peekFirst());
+ }
+
+ /**
+ * pop() removes first element, or throws NSEE if empty
+ */
+ public void testPop() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pop());
+ }
+ try {
+ q.pop();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * offer(null) throws NPE
+ */
+ public void testOfferNull() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.offer(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * offerFirst(null) throws NPE
+ */
+ public void testOfferFirstNull() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.offerFirst(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * offerLast(null) throws NPE
+ */
+ public void testOfferLastNull() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.offerLast(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * offer(x) succeeds
+ */
+ public void testOffer() {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ assertTrue(q.offer(zero));
+ assertTrue(q.offer(one));
+ assertSame(zero, q.peekFirst());
+ assertSame(one, q.peekLast());
+ }
+
+ /**
+ * offerFirst(x) succeeds
+ */
+ public void testOfferFirst() {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ assertTrue(q.offerFirst(zero));
+ assertTrue(q.offerFirst(one));
+ assertSame(one, q.peekFirst());
+ assertSame(zero, q.peekLast());
+ }
+
+ /**
+ * offerLast(x) succeeds
+ */
+ public void testOfferLast() {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ assertTrue(q.offerLast(zero));
+ assertTrue(q.offerLast(one));
+ assertSame(zero, q.peekFirst());
+ assertSame(one, q.peekLast());
+ }
+
+ /**
+ * add(null) throws NPE
+ */
+ public void testAddNull() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addFirst(null) throws NPE
+ */
+ public void testAddFirstNull() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.addFirst(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addLast(null) throws NPE
+ */
+ public void testAddLastNull() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.addLast(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * add(x) succeeds
+ */
+ public void testAdd() {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ assertTrue(q.add(zero));
+ assertTrue(q.add(one));
+ assertSame(zero, q.peekFirst());
+ assertSame(one, q.peekLast());
+ }
+
+ /**
+ * addFirst(x) succeeds
+ */
+ public void testAddFirst() {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.addFirst(zero);
+ q.addFirst(one);
+ assertSame(one, q.peekFirst());
+ assertSame(zero, q.peekLast());
+ }
+
+ /**
+ * addLast(x) succeeds
+ */
+ public void testAddLast() {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.addLast(zero);
+ q.addLast(one);
+ assertSame(zero, q.peekFirst());
+ assertSame(one, q.peekLast());
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll(this) throws IAE
+ */
+ public void testAddAllSelf() {
+ try {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Deque contains all elements, in traversal order, of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * pollFirst() succeeds unless empty
+ */
+ public void testPollFirst() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * pollLast() succeeds unless empty
+ */
+ public void testPollLast() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.pollLast());
+ }
+ assertNull(q.pollLast());
+ }
+
+ /**
+ * poll() succeeds unless empty
+ */
+ public void testPoll() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * peek() returns next element, or null if empty
+ */
+ public void testPeek() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.poll());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * element() returns first element, or throws NSEE if empty
+ */
+ public void testElement() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ assertEquals(i, q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove() removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove(i+1));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * peekFirst() returns next element, or null if empty
+ */
+ public void testPeekFirst() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peekFirst());
+ assertEquals(i, q.pollFirst());
+ assertTrue(q.peekFirst() == null ||
+ !q.peekFirst().equals(i));
+ }
+ assertNull(q.peekFirst());
+ }
+
+ /**
+ * peekLast() returns next element, or null if empty
+ */
+ public void testPeekLast() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.peekLast());
+ assertEquals(i, q.pollLast());
+ assertTrue(q.peekLast() == null ||
+ !q.peekLast().equals(i));
+ }
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * getFirst() returns first element, or throws NSEE if empty
+ */
+ public void testFirstElement() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.getFirst());
+ assertEquals(i, q.pollFirst());
+ }
+ try {
+ q.getFirst();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * getLast() returns last element, or throws NSEE if empty
+ */
+ public void testLastElement() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.getLast());
+ assertEquals(i, q.pollLast());
+ }
+ try {
+ q.getLast();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * removeFirst() removes first element, or throws NSEE if empty
+ */
+ public void testRemoveFirst() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.removeFirst());
+ }
+ try {
+ q.removeFirst();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekFirst());
+ }
+
+ /**
+ * removeLast() removes last element, or throws NSEE if empty
+ */
+ public void testRemoveLast() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = SIZE - 1; i >= 0; --i) {
+ assertEquals(i, q.removeLast());
+ }
+ try {
+ q.removeLast();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * removeFirstOccurrence(x) removes x and returns true if present
+ */
+ public void testRemoveFirstOccurrence() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.removeFirstOccurrence(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.removeFirstOccurrence(new Integer(i)));
+ assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * removeLastOccurrence(x) removes x and returns true if present
+ */
+ public void testRemoveLastOccurrence() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.removeLastOccurrence(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.removeLastOccurrence(new Integer(i)));
+ assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.poll();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear() removes all elements
+ */
+ public void testClear() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ ConcurrentLinkedDeque p = new ConcurrentLinkedDeque();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if change
+ */
+ public void testRetainAll() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ ConcurrentLinkedDeque p = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ ConcurrentLinkedDeque p = populatedDeque(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * toArray() contains all elements in FIFO order
+ */
+ public void testToArray() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.poll());
+ }
+
+ /**
+ * toArray(a) contains all elements in FIFO order
+ */
+ public void testToArray2() {
+ ConcurrentLinkedDeque<Integer> q = populatedDeque(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.poll());
+ }
+
+ /**
+ * toArray(null) throws NullPointerException
+ */
+ public void testToArray_NullArg() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ try {
+ q.toArray(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ try {
+ q.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * Iterator iterates through all elements
+ */
+ public void testIterator() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * Iterator ordering is FIFO
+ */
+ public void testIteratorOrdering() {
+ final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.add(one);
+ q.add(two);
+ q.add(three);
+
+ int k = 0;
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+
+ assertEquals(3, k);
+ }
+
+ /**
+ * Modifications do not cause iterators to fail
+ */
+ public void testWeaklyConsistentIteration() {
+ final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ q.add(one);
+ q.add(two);
+ q.add(three);
+
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ q.remove();
+ it.next();
+ }
+
+ assertEquals("deque should be empty again", 0, q.size());
+ }
+
+ /**
+ * iterator.remove() removes current element
+ */
+ public void testIteratorRemove() {
+ final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ final Random rng = new Random();
+ for (int iters = 0; iters < 100; ++iters) {
+ int max = rng.nextInt(5) + 2;
+ int split = rng.nextInt(max-1) + 1;
+ for (int j = 1; j <= max; ++j)
+ q.add(new Integer(j));
+ Iterator it = q.iterator();
+ for (int j = 1; j <= split; ++j)
+ assertEquals(it.next(), new Integer(j));
+ it.remove();
+ assertEquals(it.next(), new Integer(split+1));
+ for (int j = 1; j <= split; ++j)
+ q.remove(new Integer(j));
+ it = q.iterator();
+ for (int j = split+1; j <= max; ++j) {
+ assertEquals(it.next(), new Integer(j));
+ it.remove();
+ }
+ assertFalse(it.hasNext());
+ assertTrue(q.isEmpty());
+ }
+ }
+
+ /**
+ * Descending iterator iterates through all elements
+ */
+ public void testDescendingIterator() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ int i = 0;
+ Iterator it = q.descendingIterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ assertFalse(it.hasNext());
+ try {
+ it.next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * Descending iterator ordering is reverse FIFO
+ */
+ public void testDescendingIteratorOrdering() {
+ final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ for (int iters = 0; iters < 100; ++iters) {
+ q.add(new Integer(3));
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ int k = 0;
+ for (Iterator it = q.descendingIterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+
+ assertEquals(3, k);
+ q.remove();
+ q.remove();
+ q.remove();
+ }
+ }
+
+ /**
+ * descendingIterator.remove() removes current element
+ */
+ public void testDescendingIteratorRemove() {
+ final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+ final Random rng = new Random();
+ for (int iters = 0; iters < 100; ++iters) {
+ int max = rng.nextInt(5) + 2;
+ int split = rng.nextInt(max-1) + 1;
+ for (int j = max; j >= 1; --j)
+ q.add(new Integer(j));
+ Iterator it = q.descendingIterator();
+ for (int j = 1; j <= split; ++j)
+ assertEquals(it.next(), new Integer(j));
+ it.remove();
+ assertEquals(it.next(), new Integer(split+1));
+ for (int j = 1; j <= split; ++j)
+ q.remove(new Integer(j));
+ it = q.descendingIterator();
+ for (int j = split+1; j <= max; ++j) {
+ assertEquals(it.next(), new Integer(j));
+ it.remove();
+ }
+ assertFalse(it.hasNext());
+ assertTrue(q.isEmpty());
+ }
+ }
+
+ /**
+ * toString() contains toStrings of elements
+ */
+ public void testToString() {
+ ConcurrentLinkedDeque q = populatedDeque(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized deque has same elements in same order
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedDeque(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java
new file mode 100644
index 0000000..7924034
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java
@@ -0,0 +1,511 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class ConcurrentLinkedQueueTest extends JSR166TestCase {
+
+ /**
+ * Returns a new queue of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private ConcurrentLinkedQueue<Integer> populatedQueue(int n) {
+ ConcurrentLinkedQueue<Integer> q = new ConcurrentLinkedQueue<Integer>();
+ assertTrue(q.isEmpty());
+ for (int i = 0; i < n; ++i)
+ assertTrue(q.offer(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * new queue is empty
+ */
+ public void testConstructor1() {
+ assertEquals(0, new ConcurrentLinkedQueue().size());
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue((Collection)null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ assertTrue(q.isEmpty());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ q.add(two);
+ q.remove();
+ q.remove();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * offer(null) throws NPE
+ */
+ public void testOfferNull() {
+ try {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ q.offer(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * add(null) throws NPE
+ */
+ public void testAddNull() {
+ try {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Offer returns true
+ */
+ public void testOffer() {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ assertTrue(q.offer(zero));
+ assertTrue(q.offer(one));
+ }
+
+ /**
+ * add returns true
+ */
+ public void testAdd() {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ assertTrue(q.add(new Integer(i)));
+ }
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll(this) throws IAE
+ */
+ public void testAddAllSelf() {
+ try {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements, in traversal order, of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.poll());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * element returns next element, or throws NSEE if empty
+ */
+ public void testElement() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ assertEquals(i, q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove(i+1));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.poll();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ ConcurrentLinkedQueue p = new ConcurrentLinkedQueue();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if change
+ */
+ public void testRetainAll() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ ConcurrentLinkedQueue p = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ ConcurrentLinkedQueue p = populatedQueue(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * toArray contains all elements in FIFO order
+ */
+ public void testToArray() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.poll());
+ }
+
+ /**
+ * toArray(a) contains all elements in FIFO order
+ */
+ public void testToArray2() {
+ ConcurrentLinkedQueue<Integer> q = populatedQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.poll());
+ }
+
+ /**
+ * toArray(null) throws NullPointerException
+ */
+ public void testToArray_NullArg() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ try {
+ q.toArray(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ try {
+ q.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator ordering is FIFO
+ */
+ public void testIteratorOrdering() {
+ final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ q.add(one);
+ q.add(two);
+ q.add(three);
+
+ int k = 0;
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+
+ assertEquals(3, k);
+ }
+
+ /**
+ * Modifications do not cause iterators to fail
+ */
+ public void testWeaklyConsistentIteration() {
+ final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ q.add(one);
+ q.add(two);
+ q.add(three);
+
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ q.remove();
+ it.next();
+ }
+
+ assertEquals("queue should be empty again", 0, q.size());
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+ it = q.iterator();
+ assertSame(it.next(), two);
+ assertSame(it.next(), three);
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ ConcurrentLinkedQueue q = populatedQueue(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized queue has same elements in same order
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedQueue(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java
new file mode 100644
index 0000000..4359287
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java
@@ -0,0 +1,1263 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+public class ConcurrentSkipListMapTest extends JSR166TestCase {
+
+ /**
+ * Returns a new map from Integers 1-5 to Strings "A"-"E".
+ */
+ private static ConcurrentSkipListMap map5() {
+ ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+ assertTrue(map.isEmpty());
+ map.put(one, "A");
+ map.put(five, "E");
+ map.put(three, "C");
+ map.put(two, "B");
+ map.put(four, "D");
+ assertFalse(map.isEmpty());
+ assertEquals(5, map.size());
+ return map;
+ }
+
+ /**
+ * clear removes all pairs
+ */
+ public void testClear() {
+ ConcurrentSkipListMap map = map5();
+ map.clear();
+ assertEquals(0, map.size());
+ }
+
+ /**
+ * copy constructor creates map equal to source map
+ */
+ public void testConstructFromSorted() {
+ ConcurrentSkipListMap map = map5();
+ ConcurrentSkipListMap map2 = new ConcurrentSkipListMap(map);
+ assertEquals(map, map2);
+ }
+
+ /**
+ * Maps with same contents are equal
+ */
+ public void testEquals() {
+ ConcurrentSkipListMap map1 = map5();
+ ConcurrentSkipListMap map2 = map5();
+ assertEquals(map1, map2);
+ assertEquals(map2, map1);
+ map1.clear();
+ assertFalse(map1.equals(map2));
+ assertFalse(map2.equals(map1));
+ }
+
+ /**
+ * containsKey returns true for contained key
+ */
+ public void testContainsKey() {
+ ConcurrentSkipListMap map = map5();
+ assertTrue(map.containsKey(one));
+ assertFalse(map.containsKey(zero));
+ }
+
+ /**
+ * containsValue returns true for held values
+ */
+ public void testContainsValue() {
+ ConcurrentSkipListMap map = map5();
+ assertTrue(map.containsValue("A"));
+ assertFalse(map.containsValue("Z"));
+ }
+
+ /**
+ * get returns the correct element at the given key,
+ * or null if not present
+ */
+ public void testGet() {
+ ConcurrentSkipListMap map = map5();
+ assertEquals("A", (String)map.get(one));
+ ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+ assertNull(empty.get(one));
+ }
+
+ /**
+ * isEmpty is true of empty map and false for non-empty
+ */
+ public void testIsEmpty() {
+ ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+ ConcurrentSkipListMap map = map5();
+ assertTrue(empty.isEmpty());
+ assertFalse(map.isEmpty());
+ }
+
+ /**
+ * firstKey returns first key
+ */
+ public void testFirstKey() {
+ ConcurrentSkipListMap map = map5();
+ assertEquals(one, map.firstKey());
+ }
+
+ /**
+ * lastKey returns last key
+ */
+ public void testLastKey() {
+ ConcurrentSkipListMap map = map5();
+ assertEquals(five, map.lastKey());
+ }
+
+ /**
+ * keySet.toArray returns contains all keys
+ */
+ public void testKeySetToArray() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.keySet();
+ Object[] ar = s.toArray();
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ assertEquals(5, ar.length);
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * descendingkeySet.toArray returns contains all keys
+ */
+ public void testDescendingKeySetToArray() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.descendingKeySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * keySet returns a Set containing all the keys
+ */
+ public void testKeySet() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.keySet();
+ assertEquals(5, s.size());
+ assertTrue(s.contains(one));
+ assertTrue(s.contains(two));
+ assertTrue(s.contains(three));
+ assertTrue(s.contains(four));
+ assertTrue(s.contains(five));
+ }
+
+ /**
+ * keySet is ordered
+ */
+ public void testKeySetOrder() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.keySet();
+ Iterator i = s.iterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, one);
+ int count = 1;
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) < 0);
+ last = k;
+ ++count;
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * descending iterator of key set is inverse ordered
+ */
+ public void testKeySetDescendingIteratorOrder() {
+ ConcurrentSkipListMap map = map5();
+ NavigableSet s = map.navigableKeySet();
+ Iterator i = s.descendingIterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, five);
+ int count = 1;
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) > 0);
+ last = k;
+ ++count;
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * descendingKeySet is ordered
+ */
+ public void testDescendingKeySetOrder() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.descendingKeySet();
+ Iterator i = s.iterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, five);
+ int count = 1;
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) > 0);
+ last = k;
+ ++count;
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * descending iterator of descendingKeySet is ordered
+ */
+ public void testDescendingKeySetDescendingIteratorOrder() {
+ ConcurrentSkipListMap map = map5();
+ NavigableSet s = map.descendingKeySet();
+ Iterator i = s.descendingIterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, one);
+ int count = 1;
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) < 0);
+ last = k;
+ ++count;
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * Values.toArray contains all values
+ */
+ public void testValuesToArray() {
+ ConcurrentSkipListMap map = map5();
+ Collection v = map.values();
+ Object[] ar = v.toArray();
+ ArrayList s = new ArrayList(Arrays.asList(ar));
+ assertEquals(5, ar.length);
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * values collection contains all values
+ */
+ public void testValues() {
+ ConcurrentSkipListMap map = map5();
+ Collection s = map.values();
+ assertEquals(5, s.size());
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * entrySet contains all pairs
+ */
+ public void testEntrySet() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(one) && e.getValue().equals("A")) ||
+ (e.getKey().equals(two) && e.getValue().equals("B")) ||
+ (e.getKey().equals(three) && e.getValue().equals("C")) ||
+ (e.getKey().equals(four) && e.getValue().equals("D")) ||
+ (e.getKey().equals(five) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * descendingEntrySet contains all pairs
+ */
+ public void testDescendingEntrySet() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.descendingMap().entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(one) && e.getValue().equals("A")) ||
+ (e.getKey().equals(two) && e.getValue().equals("B")) ||
+ (e.getKey().equals(three) && e.getValue().equals("C")) ||
+ (e.getKey().equals(four) && e.getValue().equals("D")) ||
+ (e.getKey().equals(five) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * entrySet.toArray contains all entries
+ */
+ public void testEntrySetToArray() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.entrySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ for (int i = 0; i < 5; ++i) {
+ assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+ assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+ }
+ }
+
+ /**
+ * descendingEntrySet.toArray contains all entries
+ */
+ public void testDescendingEntrySetToArray() {
+ ConcurrentSkipListMap map = map5();
+ Set s = map.descendingMap().entrySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ for (int i = 0; i < 5; ++i) {
+ assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+ assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+ }
+ }
+
+ /**
+ * putAll adds all key-value pairs from the given map
+ */
+ public void testPutAll() {
+ ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+ ConcurrentSkipListMap map = map5();
+ empty.putAll(map);
+ assertEquals(5, empty.size());
+ assertTrue(empty.containsKey(one));
+ assertTrue(empty.containsKey(two));
+ assertTrue(empty.containsKey(three));
+ assertTrue(empty.containsKey(four));
+ assertTrue(empty.containsKey(five));
+ }
+
+ /**
+ * putIfAbsent works when the given key is not present
+ */
+ public void testPutIfAbsent() {
+ ConcurrentSkipListMap map = map5();
+ map.putIfAbsent(six, "Z");
+ assertTrue(map.containsKey(six));
+ }
+
+ /**
+ * putIfAbsent does not add the pair if the key is already present
+ */
+ public void testPutIfAbsent2() {
+ ConcurrentSkipListMap map = map5();
+ assertEquals("A", map.putIfAbsent(one, "Z"));
+ }
+
+ /**
+ * replace fails when the given key is not present
+ */
+ public void testReplace() {
+ ConcurrentSkipListMap map = map5();
+ assertNull(map.replace(six, "Z"));
+ assertFalse(map.containsKey(six));
+ }
+
+ /**
+ * replace succeeds if the key is already present
+ */
+ public void testReplace2() {
+ ConcurrentSkipListMap map = map5();
+ assertNotNull(map.replace(one, "Z"));
+ assertEquals("Z", map.get(one));
+ }
+
+ /**
+ * replace value fails when the given key not mapped to expected value
+ */
+ public void testReplaceValue() {
+ ConcurrentSkipListMap map = map5();
+ assertEquals("A", map.get(one));
+ assertFalse(map.replace(one, "Z", "Z"));
+ assertEquals("A", map.get(one));
+ }
+
+ /**
+ * replace value succeeds when the given key mapped to expected value
+ */
+ public void testReplaceValue2() {
+ ConcurrentSkipListMap map = map5();
+ assertEquals("A", map.get(one));
+ assertTrue(map.replace(one, "A", "Z"));
+ assertEquals("Z", map.get(one));
+ }
+
+ /**
+ * remove removes the correct key-value pair from the map
+ */
+ public void testRemove() {
+ ConcurrentSkipListMap map = map5();
+ map.remove(five);
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(five));
+ }
+
+ /**
+ * remove(key,value) removes only if pair present
+ */
+ public void testRemove2() {
+ ConcurrentSkipListMap map = map5();
+ assertTrue(map.containsKey(five));
+ assertEquals("E", map.get(five));
+ map.remove(five, "E");
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(five));
+ map.remove(four, "A");
+ assertEquals(4, map.size());
+ assertTrue(map.containsKey(four));
+ }
+
+ /**
+ * lowerEntry returns preceding entry.
+ */
+ public void testLowerEntry() {
+ ConcurrentSkipListMap map = map5();
+ Map.Entry e1 = map.lowerEntry(three);
+ assertEquals(two, e1.getKey());
+
+ Map.Entry e2 = map.lowerEntry(six);
+ assertEquals(five, e2.getKey());
+
+ Map.Entry e3 = map.lowerEntry(one);
+ assertNull(e3);
+
+ Map.Entry e4 = map.lowerEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higherEntry returns next entry.
+ */
+ public void testHigherEntry() {
+ ConcurrentSkipListMap map = map5();
+ Map.Entry e1 = map.higherEntry(three);
+ assertEquals(four, e1.getKey());
+
+ Map.Entry e2 = map.higherEntry(zero);
+ assertEquals(one, e2.getKey());
+
+ Map.Entry e3 = map.higherEntry(five);
+ assertNull(e3);
+
+ Map.Entry e4 = map.higherEntry(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floorEntry returns preceding entry.
+ */
+ public void testFloorEntry() {
+ ConcurrentSkipListMap map = map5();
+ Map.Entry e1 = map.floorEntry(three);
+ assertEquals(three, e1.getKey());
+
+ Map.Entry e2 = map.floorEntry(six);
+ assertEquals(five, e2.getKey());
+
+ Map.Entry e3 = map.floorEntry(one);
+ assertEquals(one, e3.getKey());
+
+ Map.Entry e4 = map.floorEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceilingEntry returns next entry.
+ */
+ public void testCeilingEntry() {
+ ConcurrentSkipListMap map = map5();
+ Map.Entry e1 = map.ceilingEntry(three);
+ assertEquals(three, e1.getKey());
+
+ Map.Entry e2 = map.ceilingEntry(zero);
+ assertEquals(one, e2.getKey());
+
+ Map.Entry e3 = map.ceilingEntry(five);
+ assertEquals(five, e3.getKey());
+
+ Map.Entry e4 = map.ceilingEntry(six);
+ assertNull(e4);
+ }
+
+ /**
+ * lowerEntry, higherEntry, ceilingEntry, and floorEntry return
+ * immutable entries
+ */
+ public void testEntryImmutability() {
+ ConcurrentSkipListMap map = map5();
+ Map.Entry e = map.lowerEntry(three);
+ assertEquals(two, e.getKey());
+ try {
+ e.setValue("X");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.higherEntry(zero);
+ assertEquals(one, e.getKey());
+ try {
+ e.setValue("X");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.floorEntry(one);
+ assertEquals(one, e.getKey());
+ try {
+ e.setValue("X");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.ceilingEntry(five);
+ assertEquals(five, e.getKey());
+ try {
+ e.setValue("X");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ }
+
+ /**
+ * lowerKey returns preceding element
+ */
+ public void testLowerKey() {
+ ConcurrentSkipListMap q = map5();
+ Object e1 = q.lowerKey(three);
+ assertEquals(two, e1);
+
+ Object e2 = q.lowerKey(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.lowerKey(one);
+ assertNull(e3);
+
+ Object e4 = q.lowerKey(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higherKey returns next element
+ */
+ public void testHigherKey() {
+ ConcurrentSkipListMap q = map5();
+ Object e1 = q.higherKey(three);
+ assertEquals(four, e1);
+
+ Object e2 = q.higherKey(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.higherKey(five);
+ assertNull(e3);
+
+ Object e4 = q.higherKey(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floorKey returns preceding element
+ */
+ public void testFloorKey() {
+ ConcurrentSkipListMap q = map5();
+ Object e1 = q.floorKey(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.floorKey(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.floorKey(one);
+ assertEquals(one, e3);
+
+ Object e4 = q.floorKey(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceilingKey returns next element
+ */
+ public void testCeilingKey() {
+ ConcurrentSkipListMap q = map5();
+ Object e1 = q.ceilingKey(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.ceilingKey(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.ceilingKey(five);
+ assertEquals(five, e3);
+
+ Object e4 = q.ceilingKey(six);
+ assertNull(e4);
+ }
+
+ /**
+ * pollFirstEntry returns entries in order
+ */
+ public void testPollFirstEntry() {
+ ConcurrentSkipListMap map = map5();
+ Map.Entry e = map.pollFirstEntry();
+ assertEquals(one, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(two, e.getKey());
+ map.put(one, "A");
+ e = map.pollFirstEntry();
+ assertEquals(one, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(three, e.getKey());
+ map.remove(four);
+ e = map.pollFirstEntry();
+ assertEquals(five, e.getKey());
+ try {
+ e.setValue("A");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollFirstEntry();
+ assertNull(e);
+ }
+
+ /**
+ * pollLastEntry returns entries in order
+ */
+ public void testPollLastEntry() {
+ ConcurrentSkipListMap map = map5();
+ Map.Entry e = map.pollLastEntry();
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(four, e.getKey());
+ map.put(five, "E");
+ e = map.pollLastEntry();
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(three, e.getKey());
+ map.remove(two);
+ e = map.pollLastEntry();
+ assertEquals(one, e.getKey());
+ try {
+ e.setValue("E");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollLastEntry();
+ assertNull(e);
+ }
+
+ /**
+ * size returns the correct values
+ */
+ public void testSize() {
+ ConcurrentSkipListMap map = map5();
+ ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+ assertEquals(0, empty.size());
+ assertEquals(5, map.size());
+ }
+
+ /**
+ * toString contains toString of elements
+ */
+ public void testToString() {
+ ConcurrentSkipListMap map = map5();
+ String s = map.toString();
+ for (int i = 1; i <= 5; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ // Exception tests
+
+ /**
+ * get(null) of nonempty map throws NPE
+ */
+ public void testGet_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = map5();
+ c.get(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsKey(null) of nonempty map throws NPE
+ */
+ public void testContainsKey_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = map5();
+ c.containsKey(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsValue(null) throws NPE
+ */
+ public void testContainsValue_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+ c.containsValue(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * put(null,x) throws NPE
+ */
+ public void testPut1_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = map5();
+ c.put(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * putIfAbsent(null, x) throws NPE
+ */
+ public void testPutIfAbsent1_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = map5();
+ c.putIfAbsent(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(null, x) throws NPE
+ */
+ public void testReplace_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = map5();
+ c.replace(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(null, x, y) throws NPE
+ */
+ public void testReplaceValue_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = map5();
+ c.replace(null, one, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null) throws NPE
+ */
+ public void testRemove1_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+ c.put("sadsdf", "asdads");
+ c.remove(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null, x) throws NPE
+ */
+ public void testRemove2_NullPointerException() {
+ try {
+ ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+ c.put("sadsdf", "asdads");
+ c.remove(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(x, null) returns false
+ */
+ public void testRemove3() {
+ ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+ c.put("sadsdf", "asdads");
+ assertFalse(c.remove("sadsdf", null));
+ }
+
+ /**
+ * A deserialized map equals original
+ */
+ public void testSerialization() throws Exception {
+ NavigableMap x = map5();
+ NavigableMap y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ /**
+ * subMap returns map with keys in requested range
+ */
+ public void testSubMapContents() {
+ ConcurrentSkipListMap map = map5();
+ NavigableMap sm = map.subMap(two, true, four, false);
+ assertEquals(two, sm.firstKey());
+ assertEquals(three, sm.lastKey());
+ assertEquals(2, sm.size());
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ Iterator r = sm.descendingKeySet().iterator();
+ k = (Integer)(r.next());
+ assertEquals(three, k);
+ k = (Integer)(r.next());
+ assertEquals(two, k);
+ assertFalse(r.hasNext());
+
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(two));
+ assertEquals(4, map.size());
+ assertEquals(1, sm.size());
+ assertEquals(three, sm.firstKey());
+ assertEquals(three, sm.lastKey());
+ assertEquals("C", sm.remove(three));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, map.size());
+ }
+
+ public void testSubMapContents2() {
+ ConcurrentSkipListMap map = map5();
+ NavigableMap sm = map.subMap(two, true, three, false);
+ assertEquals(1, sm.size());
+ assertEquals(two, sm.firstKey());
+ assertEquals(two, sm.lastKey());
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertFalse(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ assertFalse(i.hasNext());
+ Iterator r = sm.descendingKeySet().iterator();
+ k = (Integer)(r.next());
+ assertEquals(two, k);
+ assertFalse(r.hasNext());
+
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(two));
+ assertEquals(4, map.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertSame(sm.remove(three), null);
+ assertEquals(4, map.size());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testHeadMapContents() {
+ ConcurrentSkipListMap map = map5();
+ NavigableMap sm = map.headMap(four, false);
+ assertTrue(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(one, k);
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, map.size());
+ assertEquals(four, map.firstKey());
+ }
+
+ /**
+ * tailMap returns map with keys in requested range
+ */
+ public void testTailMapContents() {
+ ConcurrentSkipListMap map = map5();
+ NavigableMap sm = map.tailMap(two, true);
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertTrue(sm.containsKey(four));
+ assertTrue(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ k = (Integer)(i.next());
+ assertEquals(four, k);
+ k = (Integer)(i.next());
+ assertEquals(five, k);
+ assertFalse(i.hasNext());
+ Iterator r = sm.descendingKeySet().iterator();
+ k = (Integer)(r.next());
+ assertEquals(five, k);
+ k = (Integer)(r.next());
+ assertEquals(four, k);
+ k = (Integer)(r.next());
+ assertEquals(three, k);
+ k = (Integer)(r.next());
+ assertEquals(two, k);
+ assertFalse(r.hasNext());
+
+ Iterator ei = sm.entrySet().iterator();
+ Map.Entry e;
+ e = (Map.Entry)(ei.next());
+ assertEquals(two, e.getKey());
+ assertEquals("B", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(three, e.getKey());
+ assertEquals("C", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(four, e.getKey());
+ assertEquals("D", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ assertFalse(i.hasNext());
+
+ NavigableMap ssm = sm.tailMap(four, true);
+ assertEquals(four, ssm.firstKey());
+ assertEquals(five, ssm.lastKey());
+ assertEquals("D", ssm.remove(four));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, map.size());
+ }
+
+ Random rnd = new Random(666);
+ BitSet bs;
+
+ /**
+ * Submaps of submaps subdivide correctly
+ */
+ public void testRecursiveSubMaps() throws Exception {
+ int mapSize = expensiveTests ? 1000 : 100;
+ Class cl = ConcurrentSkipListMap.class;
+ NavigableMap<Integer, Integer> map = newMap(cl);
+ bs = new BitSet(mapSize);
+
+ populate(map, mapSize);
+ check(map, 0, mapSize - 1, true);
+ check(map.descendingMap(), 0, mapSize - 1, false);
+
+ mutateMap(map, 0, mapSize - 1);
+ check(map, 0, mapSize - 1, true);
+ check(map.descendingMap(), 0, mapSize - 1, false);
+
+ bashSubMap(map.subMap(0, true, mapSize, false),
+ 0, mapSize - 1, true);
+ }
+
+ static NavigableMap<Integer, Integer> newMap(Class cl) throws Exception {
+ NavigableMap<Integer, Integer> result =
+ (NavigableMap<Integer, Integer>) cl.newInstance();
+ assertEquals(0, result.size());
+ assertFalse(result.keySet().iterator().hasNext());
+ return result;
+ }
+
+ void populate(NavigableMap<Integer, Integer> map, int limit) {
+ for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+ int key = rnd.nextInt(limit);
+ put(map, key);
+ }
+ }
+
+ void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
+ int size = map.size();
+ int rangeSize = max - min + 1;
+
+ // Remove a bunch of entries directly
+ for (int i = 0, n = rangeSize / 2; i < n; i++) {
+ remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+ }
+
+ // Remove a bunch of entries with iterator
+ for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+ if (rnd.nextBoolean()) {
+ bs.clear(it.next());
+ it.remove();
+ }
+ }
+
+ // Add entries till we're back to original size
+ while (map.size() < size) {
+ int key = min + rnd.nextInt(rangeSize);
+ assertTrue(key >= min && key<= max);
+ put(map, key);
+ }
+ }
+
+ void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
+ int size = map.size();
+ int rangeSize = max - min + 1;
+
+ // Remove a bunch of entries directly
+ for (int i = 0, n = rangeSize / 2; i < n; i++) {
+ remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+ }
+
+ // Remove a bunch of entries with iterator
+ for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+ if (rnd.nextBoolean()) {
+ bs.clear(it.next());
+ it.remove();
+ }
+ }
+
+ // Add entries till we're back to original size
+ while (map.size() < size) {
+ int key = min - 5 + rnd.nextInt(rangeSize + 10);
+ if (key >= min && key<= max) {
+ put(map, key);
+ } else {
+ try {
+ map.put(key, 2 * key);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+ }
+ }
+
+ void put(NavigableMap<Integer, Integer> map, int key) {
+ if (map.put(key, 2 * key) == null)
+ bs.set(key);
+ }
+
+ void remove(NavigableMap<Integer, Integer> map, int key) {
+ if (map.remove(key) != null)
+ bs.clear(key);
+ }
+
+ void bashSubMap(NavigableMap<Integer, Integer> map,
+ int min, int max, boolean ascending) {
+ check(map, min, max, ascending);
+ check(map.descendingMap(), min, max, !ascending);
+
+ mutateSubMap(map, min, max);
+ check(map, min, max, ascending);
+ check(map.descendingMap(), min, max, !ascending);
+
+ // Recurse
+ if (max - min < 2)
+ return;
+ int midPoint = (min + max) / 2;
+
+ // headMap - pick direction and endpoint inclusion randomly
+ boolean incl = rnd.nextBoolean();
+ NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
+ if (ascending) {
+ if (rnd.nextBoolean())
+ bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
+ else
+ bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+ false);
+ } else {
+ if (rnd.nextBoolean())
+ bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
+ else
+ bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+ true);
+ }
+
+ // tailMap - pick direction and endpoint inclusion randomly
+ incl = rnd.nextBoolean();
+ NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
+ if (ascending) {
+ if (rnd.nextBoolean())
+ bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
+ else
+ bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+ false);
+ } else {
+ if (rnd.nextBoolean()) {
+ bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
+ } else {
+ bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+ true);
+ }
+ }
+
+ // subMap - pick direction and endpoint inclusion randomly
+ int rangeSize = max - min + 1;
+ int[] endpoints = new int[2];
+ endpoints[0] = min + rnd.nextInt(rangeSize);
+ endpoints[1] = min + rnd.nextInt(rangeSize);
+ Arrays.sort(endpoints);
+ boolean lowIncl = rnd.nextBoolean();
+ boolean highIncl = rnd.nextBoolean();
+ if (ascending) {
+ NavigableMap<Integer,Integer> sm = map.subMap(
+ endpoints[0], lowIncl, endpoints[1], highIncl);
+ if (rnd.nextBoolean())
+ bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), true);
+ else
+ bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), false);
+ } else {
+ NavigableMap<Integer,Integer> sm = map.subMap(
+ endpoints[1], highIncl, endpoints[0], lowIncl);
+ if (rnd.nextBoolean())
+ bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), false);
+ else
+ bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), true);
+ }
+ }
+
+ /**
+ * min and max are both inclusive. If max < min, interval is empty.
+ */
+ void check(NavigableMap<Integer, Integer> map,
+ final int min, final int max, final boolean ascending) {
+ class ReferenceSet {
+ int lower(int key) {
+ return ascending ? lowerAscending(key) : higherAscending(key);
+ }
+ int floor(int key) {
+ return ascending ? floorAscending(key) : ceilingAscending(key);
+ }
+ int ceiling(int key) {
+ return ascending ? ceilingAscending(key) : floorAscending(key);
+ }
+ int higher(int key) {
+ return ascending ? higherAscending(key) : lowerAscending(key);
+ }
+ int first() {
+ return ascending ? firstAscending() : lastAscending();
+ }
+ int last() {
+ return ascending ? lastAscending() : firstAscending();
+ }
+ int lowerAscending(int key) {
+ return floorAscending(key - 1);
+ }
+ int floorAscending(int key) {
+ if (key < min)
+ return -1;
+ else if (key > max)
+ key = max;
+
+ // BitSet should support this! Test would run much faster
+ while (key >= min) {
+ if (bs.get(key))
+ return key;
+ key--;
+ }
+ return -1;
+ }
+ int ceilingAscending(int key) {
+ if (key < min)
+ key = min;
+ else if (key > max)
+ return -1;
+ int result = bs.nextSetBit(key);
+ return result > max ? -1 : result;
+ }
+ int higherAscending(int key) {
+ return ceilingAscending(key + 1);
+ }
+ private int firstAscending() {
+ int result = ceilingAscending(min);
+ return result > max ? -1 : result;
+ }
+ private int lastAscending() {
+ int result = floorAscending(max);
+ return result < min ? -1 : result;
+ }
+ }
+ ReferenceSet rs = new ReferenceSet();
+
+ // Test contents using containsKey
+ int size = 0;
+ for (int i = min; i <= max; i++) {
+ boolean bsContainsI = bs.get(i);
+ assertEquals(bsContainsI, map.containsKey(i));
+ if (bsContainsI)
+ size++;
+ }
+ assertEquals(size, map.size());
+
+ // Test contents using contains keySet iterator
+ int size2 = 0;
+ int previousKey = -1;
+ for (int key : map.keySet()) {
+ assertTrue(bs.get(key));
+ size2++;
+ assertTrue(previousKey < 0 ||
+ (ascending ? key - previousKey > 0 : key - previousKey < 0));
+ previousKey = key;
+ }
+ assertEquals(size2, size);
+
+ // Test navigation ops
+ for (int key = min - 1; key <= max + 1; key++) {
+ assertEq(map.lowerKey(key), rs.lower(key));
+ assertEq(map.floorKey(key), rs.floor(key));
+ assertEq(map.higherKey(key), rs.higher(key));
+ assertEq(map.ceilingKey(key), rs.ceiling(key));
+ }
+
+ // Test extrema
+ if (map.size() != 0) {
+ assertEq(map.firstKey(), rs.first());
+ assertEq(map.lastKey(), rs.last());
+ } else {
+ assertEq(rs.first(), -1);
+ assertEq(rs.last(), -1);
+ try {
+ map.firstKey();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ try {
+ map.lastKey();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+ }
+
+ static void assertEq(Integer i, int j) {
+ if (i == null)
+ assertEquals(j, -1);
+ else
+ assertEquals((int) i, j);
+ }
+
+ static boolean eq(Integer i, int j) {
+ return i == null ? j == -1 : i == j;
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java
new file mode 100644
index 0000000..1fd3c5f
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java
@@ -0,0 +1,982 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+public class ConcurrentSkipListSetTest extends JSR166TestCase {
+
+ static class MyReverseComparator implements Comparator {
+ public int compare(Object x, Object y) {
+ return ((Comparable)y).compareTo(x);
+ }
+ }
+
+ /**
+ * Returns a new set of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private ConcurrentSkipListSet<Integer> populatedSet(int n) {
+ ConcurrentSkipListSet<Integer> q =
+ new ConcurrentSkipListSet<Integer>();
+ assertTrue(q.isEmpty());
+ for (int i = n-1; i >= 0; i-=2)
+ assertTrue(q.add(new Integer(i)));
+ for (int i = (n & 1); i < n; i+=2)
+ assertTrue(q.add(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * Returns a new set of first 5 ints.
+ */
+ private ConcurrentSkipListSet set5() {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ assertTrue(q.isEmpty());
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ q.add(four);
+ q.add(five);
+ assertEquals(5, q.size());
+ return q;
+ }
+
+ /**
+ * A new set has unbounded capacity
+ */
+ public void testConstructor1() {
+ assertEquals(0, new ConcurrentSkipListSet().size());
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet((Collection)null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Set contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.pollFirst());
+ }
+
+ /**
+ * The comparator used in constructor is used
+ */
+ public void testConstructor7() {
+ MyReverseComparator cmp = new MyReverseComparator();
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet(cmp);
+ assertEquals(cmp, q.comparator());
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ for (int i = SIZE-1; i >= 0; --i)
+ assertEquals(ints[i], q.pollFirst());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ assertTrue(q.isEmpty());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.add(new Integer(2));
+ q.pollFirst();
+ q.pollFirst();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.pollFirst();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * add(null) throws NPE
+ */
+ public void testAddNull() {
+ try {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Add of comparable element succeeds
+ */
+ public void testAdd() {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ assertTrue(q.add(zero));
+ assertTrue(q.add(one));
+ }
+
+ /**
+ * Add of duplicate element fails
+ */
+ public void testAddDup() {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ assertTrue(q.add(zero));
+ assertFalse(q.add(zero));
+ }
+
+ /**
+ * Add of non-Comparable throws CCE
+ */
+ public void testAddNonComparable() {
+ try {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ q.add(new Object());
+ q.add(new Object());
+ q.add(new Object());
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Set contains all elements of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(SIZE-1-i);
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(i, q.pollFirst());
+ }
+
+ /**
+ * pollFirst succeeds unless empty
+ */
+ public void testPollFirst() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * pollLast succeeds unless empty
+ */
+ public void testPollLast() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.pollLast());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove(i+1));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.pollFirst();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ ConcurrentSkipListSet p = new ConcurrentSkipListSet();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ ConcurrentSkipListSet p = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.pollFirst();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ ConcurrentSkipListSet p = populatedSet(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.pollFirst());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * lower returns preceding element
+ */
+ public void testLower() {
+ ConcurrentSkipListSet q = set5();
+ Object e1 = q.lower(three);
+ assertEquals(two, e1);
+
+ Object e2 = q.lower(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.lower(one);
+ assertNull(e3);
+
+ Object e4 = q.lower(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higher returns next element
+ */
+ public void testHigher() {
+ ConcurrentSkipListSet q = set5();
+ Object e1 = q.higher(three);
+ assertEquals(four, e1);
+
+ Object e2 = q.higher(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.higher(five);
+ assertNull(e3);
+
+ Object e4 = q.higher(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floor returns preceding element
+ */
+ public void testFloor() {
+ ConcurrentSkipListSet q = set5();
+ Object e1 = q.floor(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.floor(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.floor(one);
+ assertEquals(one, e3);
+
+ Object e4 = q.floor(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceiling returns next element
+ */
+ public void testCeiling() {
+ ConcurrentSkipListSet q = set5();
+ Object e1 = q.ceiling(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.ceiling(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.ceiling(five);
+ assertEquals(five, e3);
+
+ Object e4 = q.ceiling(six);
+ assertNull(e4);
+ }
+
+ /**
+ * toArray contains all elements in sorted order
+ */
+ public void testToArray() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.pollFirst());
+ }
+
+ /**
+ * toArray(a) contains all elements in sorted order
+ */
+ public void testToArray2() {
+ ConcurrentSkipListSet<Integer> q = populatedSet(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ assertSame(ints, q.toArray(ints));
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.pollFirst());
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator of empty set has no elements
+ */
+ public void testEmptyIterator() {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(0, i);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ q.add(new Integer(3));
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertEquals(it.next(), new Integer(2));
+ assertEquals(it.next(), new Integer(3));
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ ConcurrentSkipListSet q = populatedSet(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized set has same elements
+ */
+ public void testSerialization() throws Exception {
+ NavigableSet x = populatedSet(SIZE);
+ NavigableSet y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.pollFirst(), y.pollFirst());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * subSet returns set with keys in requested range
+ */
+ public void testSubSetContents() {
+ ConcurrentSkipListSet set = set5();
+ SortedSet sm = set.subSet(two, four);
+ assertEquals(two, sm.first());
+ assertEquals(three, sm.last());
+ assertEquals(2, sm.size());
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(two));
+ assertEquals(4, set.size());
+ assertEquals(1, sm.size());
+ assertEquals(three, sm.first());
+ assertEquals(three, sm.last());
+ assertTrue(sm.remove(three));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, set.size());
+ }
+
+ public void testSubSetContents2() {
+ ConcurrentSkipListSet set = set5();
+ SortedSet sm = set.subSet(two, three);
+ assertEquals(1, sm.size());
+ assertEquals(two, sm.first());
+ assertEquals(two, sm.last());
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertFalse(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(two));
+ assertEquals(4, set.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertFalse(sm.remove(three));
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * headSet returns set with keys in requested range
+ */
+ public void testHeadSetContents() {
+ ConcurrentSkipListSet set = set5();
+ SortedSet sm = set.headSet(four);
+ assertTrue(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(one, k);
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, set.size());
+ assertEquals(four, set.first());
+ }
+
+ /**
+ * tailSet returns set with keys in requested range
+ */
+ public void testTailSetContents() {
+ ConcurrentSkipListSet set = set5();
+ SortedSet sm = set.tailSet(two);
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertTrue(sm.contains(four));
+ assertTrue(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ k = (Integer)(i.next());
+ assertEquals(four, k);
+ k = (Integer)(i.next());
+ assertEquals(five, k);
+ assertFalse(i.hasNext());
+
+ SortedSet ssm = sm.tailSet(four);
+ assertEquals(four, ssm.first());
+ assertEquals(five, ssm.last());
+ assertTrue(ssm.remove(four));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, set.size());
+ }
+
+ Random rnd = new Random(666);
+
+ /**
+ * Subsets of subsets subdivide correctly
+ */
+ public void testRecursiveSubSets() throws Exception {
+ int setSize = expensiveTests ? 1000 : 100;
+ Class cl = ConcurrentSkipListSet.class;
+
+ NavigableSet<Integer> set = newSet(cl);
+ BitSet bs = new BitSet(setSize);
+
+ populate(set, setSize, bs);
+ check(set, 0, setSize - 1, true, bs);
+ check(set.descendingSet(), 0, setSize - 1, false, bs);
+
+ mutateSet(set, 0, setSize - 1, bs);
+ check(set, 0, setSize - 1, true, bs);
+ check(set.descendingSet(), 0, setSize - 1, false, bs);
+
+ bashSubSet(set.subSet(0, true, setSize, false),
+ 0, setSize - 1, true, bs);
+ }
+
+ /**
+ * addAll is idempotent
+ */
+ public void testAddAll_idempotent() throws Exception {
+ Set x = populatedSet(SIZE);
+ Set y = new ConcurrentSkipListSet(x);
+ y.addAll(x);
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ static NavigableSet<Integer> newSet(Class cl) throws Exception {
+ NavigableSet<Integer> result = (NavigableSet<Integer>) cl.newInstance();
+ assertEquals(0, result.size());
+ assertFalse(result.iterator().hasNext());
+ return result;
+ }
+
+ void populate(NavigableSet<Integer> set, int limit, BitSet bs) {
+ for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+ int element = rnd.nextInt(limit);
+ put(set, element, bs);
+ }
+ }
+
+ void mutateSet(NavigableSet<Integer> set, int min, int max, BitSet bs) {
+ int size = set.size();
+ int rangeSize = max - min + 1;
+
+ // Remove a bunch of entries directly
+ for (int i = 0, n = rangeSize / 2; i < n; i++) {
+ remove(set, min - 5 + rnd.nextInt(rangeSize + 10), bs);
+ }
+
+ // Remove a bunch of entries with iterator
+ for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+ if (rnd.nextBoolean()) {
+ bs.clear(it.next());
+ it.remove();
+ }
+ }
+
+ // Add entries till we're back to original size
+ while (set.size() < size) {
+ int element = min + rnd.nextInt(rangeSize);
+ assertTrue(element >= min && element<= max);
+ put(set, element, bs);
+ }
+ }
+
+ void mutateSubSet(NavigableSet<Integer> set, int min, int max,
+ BitSet bs) {
+ int size = set.size();
+ int rangeSize = max - min + 1;
+
+ // Remove a bunch of entries directly
+ for (int i = 0, n = rangeSize / 2; i < n; i++) {
+ remove(set, min - 5 + rnd.nextInt(rangeSize + 10), bs);
+ }
+
+ // Remove a bunch of entries with iterator
+ for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+ if (rnd.nextBoolean()) {
+ bs.clear(it.next());
+ it.remove();
+ }
+ }
+
+ // Add entries till we're back to original size
+ while (set.size() < size) {
+ int element = min - 5 + rnd.nextInt(rangeSize + 10);
+ if (element >= min && element<= max) {
+ put(set, element, bs);
+ } else {
+ try {
+ set.add(element);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+ }
+ }
+
+ void put(NavigableSet<Integer> set, int element, BitSet bs) {
+ if (set.add(element))
+ bs.set(element);
+ }
+
+ void remove(NavigableSet<Integer> set, int element, BitSet bs) {
+ if (set.remove(element))
+ bs.clear(element);
+ }
+
+ void bashSubSet(NavigableSet<Integer> set,
+ int min, int max, boolean ascending,
+ BitSet bs) {
+ check(set, min, max, ascending, bs);
+ check(set.descendingSet(), min, max, !ascending, bs);
+
+ mutateSubSet(set, min, max, bs);
+ check(set, min, max, ascending, bs);
+ check(set.descendingSet(), min, max, !ascending, bs);
+
+ // Recurse
+ if (max - min < 2)
+ return;
+ int midPoint = (min + max) / 2;
+
+ // headSet - pick direction and endpoint inclusion randomly
+ boolean incl = rnd.nextBoolean();
+ NavigableSet<Integer> hm = set.headSet(midPoint, incl);
+ if (ascending) {
+ if (rnd.nextBoolean())
+ bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true, bs);
+ else
+ bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+ false, bs);
+ } else {
+ if (rnd.nextBoolean())
+ bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false, bs);
+ else
+ bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+ true, bs);
+ }
+
+ // tailSet - pick direction and endpoint inclusion randomly
+ incl = rnd.nextBoolean();
+ NavigableSet<Integer> tm = set.tailSet(midPoint,incl);
+ if (ascending) {
+ if (rnd.nextBoolean())
+ bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true, bs);
+ else
+ bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+ false, bs);
+ } else {
+ if (rnd.nextBoolean()) {
+ bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false, bs);
+ } else {
+ bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+ true, bs);
+ }
+ }
+
+ // subSet - pick direction and endpoint inclusion randomly
+ int rangeSize = max - min + 1;
+ int[] endpoints = new int[2];
+ endpoints[0] = min + rnd.nextInt(rangeSize);
+ endpoints[1] = min + rnd.nextInt(rangeSize);
+ Arrays.sort(endpoints);
+ boolean lowIncl = rnd.nextBoolean();
+ boolean highIncl = rnd.nextBoolean();
+ if (ascending) {
+ NavigableSet<Integer> sm = set.subSet(
+ endpoints[0], lowIncl, endpoints[1], highIncl);
+ if (rnd.nextBoolean())
+ bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), true, bs);
+ else
+ bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), false, bs);
+ } else {
+ NavigableSet<Integer> sm = set.subSet(
+ endpoints[1], highIncl, endpoints[0], lowIncl);
+ if (rnd.nextBoolean())
+ bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), false, bs);
+ else
+ bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), true, bs);
+ }
+ }
+
+ /**
+ * min and max are both inclusive. If max < min, interval is empty.
+ */
+ void check(NavigableSet<Integer> set,
+ final int min, final int max, final boolean ascending,
+ final BitSet bs) {
+ class ReferenceSet {
+ int lower(int element) {
+ return ascending ?
+ lowerAscending(element) : higherAscending(element);
+ }
+ int floor(int element) {
+ return ascending ?
+ floorAscending(element) : ceilingAscending(element);
+ }
+ int ceiling(int element) {
+ return ascending ?
+ ceilingAscending(element) : floorAscending(element);
+ }
+ int higher(int element) {
+ return ascending ?
+ higherAscending(element) : lowerAscending(element);
+ }
+ int first() {
+ return ascending ? firstAscending() : lastAscending();
+ }
+ int last() {
+ return ascending ? lastAscending() : firstAscending();
+ }
+ int lowerAscending(int element) {
+ return floorAscending(element - 1);
+ }
+ int floorAscending(int element) {
+ if (element < min)
+ return -1;
+ else if (element > max)
+ element = max;
+
+ // BitSet should support this! Test would run much faster
+ while (element >= min) {
+ if (bs.get(element))
+ return element;
+ element--;
+ }
+ return -1;
+ }
+ int ceilingAscending(int element) {
+ if (element < min)
+ element = min;
+ else if (element > max)
+ return -1;
+ int result = bs.nextSetBit(element);
+ return result > max ? -1 : result;
+ }
+ int higherAscending(int element) {
+ return ceilingAscending(element + 1);
+ }
+ private int firstAscending() {
+ int result = ceilingAscending(min);
+ return result > max ? -1 : result;
+ }
+ private int lastAscending() {
+ int result = floorAscending(max);
+ return result < min ? -1 : result;
+ }
+ }
+ ReferenceSet rs = new ReferenceSet();
+
+ // Test contents using containsElement
+ int size = 0;
+ for (int i = min; i <= max; i++) {
+ boolean bsContainsI = bs.get(i);
+ assertEquals(bsContainsI, set.contains(i));
+ if (bsContainsI)
+ size++;
+ }
+ assertEquals(size, set.size());
+
+ // Test contents using contains elementSet iterator
+ int size2 = 0;
+ int previousElement = -1;
+ for (int element : set) {
+ assertTrue(bs.get(element));
+ size2++;
+ assertTrue(previousElement < 0 || (ascending ?
+ element - previousElement > 0 : element - previousElement < 0));
+ previousElement = element;
+ }
+ assertEquals(size2, size);
+
+ // Test navigation ops
+ for (int element = min - 1; element <= max + 1; element++) {
+ assertEq(set.lower(element), rs.lower(element));
+ assertEq(set.floor(element), rs.floor(element));
+ assertEq(set.higher(element), rs.higher(element));
+ assertEq(set.ceiling(element), rs.ceiling(element));
+ }
+
+ // Test extrema
+ if (set.size() != 0) {
+ assertEq(set.first(), rs.first());
+ assertEq(set.last(), rs.last());
+ } else {
+ assertEq(rs.first(), -1);
+ assertEq(rs.last(), -1);
+ try {
+ set.first();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ try {
+ set.last();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+ }
+
+ static void assertEq(Integer i, int j) {
+ if (i == null)
+ assertEquals(j, -1);
+ else
+ assertEquals((int) i, j);
+ }
+
+ static boolean eq(Integer i, int j) {
+ return i == null ? j == -1 : i == j;
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java
new file mode 100644
index 0000000..7247657
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java
@@ -0,0 +1,1410 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.*;
+
+public class ConcurrentSkipListSubMapTest extends JSR166TestCase {
+
+ /**
+ * Returns a new map from Integers 1-5 to Strings "A"-"E".
+ */
+ private static ConcurrentNavigableMap map5() {
+ ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+ assertTrue(map.isEmpty());
+ map.put(zero, "Z");
+ map.put(one, "A");
+ map.put(five, "E");
+ map.put(three, "C");
+ map.put(two, "B");
+ map.put(four, "D");
+ map.put(seven, "F");
+ assertFalse(map.isEmpty());
+ assertEquals(7, map.size());
+ return map.subMap(one, true, seven, false);
+ }
+
+ /**
+ * Returns a new map from Integers -5 to -1 to Strings "A"-"E".
+ */
+ private static ConcurrentNavigableMap dmap5() {
+ ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+ assertTrue(map.isEmpty());
+ map.put(m1, "A");
+ map.put(m5, "E");
+ map.put(m3, "C");
+ map.put(m2, "B");
+ map.put(m4, "D");
+ assertFalse(map.isEmpty());
+ assertEquals(5, map.size());
+ return map.descendingMap();
+ }
+
+ private static ConcurrentNavigableMap map0() {
+ ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+ assertTrue(map.isEmpty());
+ return map.tailMap(one, true);
+ }
+
+ private static ConcurrentNavigableMap dmap0() {
+ ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+ assertTrue(map.isEmpty());
+ return map;
+ }
+
+ /**
+ * clear removes all pairs
+ */
+ public void testClear() {
+ ConcurrentNavigableMap map = map5();
+ map.clear();
+ assertEquals(0, map.size());
+ }
+
+ /**
+ * Maps with same contents are equal
+ */
+ public void testEquals() {
+ ConcurrentNavigableMap map1 = map5();
+ ConcurrentNavigableMap map2 = map5();
+ assertEquals(map1, map2);
+ assertEquals(map2, map1);
+ map1.clear();
+ assertFalse(map1.equals(map2));
+ assertFalse(map2.equals(map1));
+ }
+
+ /**
+ * containsKey returns true for contained key
+ */
+ public void testContainsKey() {
+ ConcurrentNavigableMap map = map5();
+ assertTrue(map.containsKey(one));
+ assertFalse(map.containsKey(zero));
+ }
+
+ /**
+ * containsValue returns true for held values
+ */
+ public void testContainsValue() {
+ ConcurrentNavigableMap map = map5();
+ assertTrue(map.containsValue("A"));
+ assertFalse(map.containsValue("Z"));
+ }
+
+ /**
+ * get returns the correct element at the given key,
+ * or null if not present
+ */
+ public void testGet() {
+ ConcurrentNavigableMap map = map5();
+ assertEquals("A", (String)map.get(one));
+ ConcurrentNavigableMap empty = map0();
+ assertNull(empty.get(one));
+ }
+
+ /**
+ * isEmpty is true of empty map and false for non-empty
+ */
+ public void testIsEmpty() {
+ ConcurrentNavigableMap empty = map0();
+ ConcurrentNavigableMap map = map5();
+ assertTrue(empty.isEmpty());
+ assertFalse(map.isEmpty());
+ }
+
+ /**
+ * firstKey returns first key
+ */
+ public void testFirstKey() {
+ ConcurrentNavigableMap map = map5();
+ assertEquals(one, map.firstKey());
+ }
+
+ /**
+ * lastKey returns last key
+ */
+ public void testLastKey() {
+ ConcurrentNavigableMap map = map5();
+ assertEquals(five, map.lastKey());
+ }
+
+ /**
+ * keySet returns a Set containing all the keys
+ */
+ public void testKeySet() {
+ ConcurrentNavigableMap map = map5();
+ Set s = map.keySet();
+ assertEquals(5, s.size());
+ assertTrue(s.contains(one));
+ assertTrue(s.contains(two));
+ assertTrue(s.contains(three));
+ assertTrue(s.contains(four));
+ assertTrue(s.contains(five));
+ }
+
+ /**
+ * keySet is ordered
+ */
+ public void testKeySetOrder() {
+ ConcurrentNavigableMap map = map5();
+ Set s = map.keySet();
+ Iterator i = s.iterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, one);
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) < 0);
+ last = k;
+ }
+ }
+
+ /**
+ * values collection contains all values
+ */
+ public void testValues() {
+ ConcurrentNavigableMap map = map5();
+ Collection s = map.values();
+ assertEquals(5, s.size());
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * keySet.toArray returns contains all keys
+ */
+ public void testKeySetToArray() {
+ ConcurrentNavigableMap map = map5();
+ Set s = map.keySet();
+ Object[] ar = s.toArray();
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ assertEquals(5, ar.length);
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * descendingkeySet.toArray returns contains all keys
+ */
+ public void testDescendingKeySetToArray() {
+ ConcurrentNavigableMap map = map5();
+ Set s = map.descendingKeySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * Values.toArray contains all values
+ */
+ public void testValuesToArray() {
+ ConcurrentNavigableMap map = map5();
+ Collection v = map.values();
+ Object[] ar = v.toArray();
+ ArrayList s = new ArrayList(Arrays.asList(ar));
+ assertEquals(5, ar.length);
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * entrySet contains all pairs
+ */
+ public void testEntrySet() {
+ ConcurrentNavigableMap map = map5();
+ Set s = map.entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(one) && e.getValue().equals("A")) ||
+ (e.getKey().equals(two) && e.getValue().equals("B")) ||
+ (e.getKey().equals(three) && e.getValue().equals("C")) ||
+ (e.getKey().equals(four) && e.getValue().equals("D")) ||
+ (e.getKey().equals(five) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * putAll adds all key-value pairs from the given map
+ */
+ public void testPutAll() {
+ ConcurrentNavigableMap empty = map0();
+ ConcurrentNavigableMap map = map5();
+ empty.putAll(map);
+ assertEquals(5, empty.size());
+ assertTrue(empty.containsKey(one));
+ assertTrue(empty.containsKey(two));
+ assertTrue(empty.containsKey(three));
+ assertTrue(empty.containsKey(four));
+ assertTrue(empty.containsKey(five));
+ }
+
+ /**
+ * putIfAbsent works when the given key is not present
+ */
+ public void testPutIfAbsent() {
+ ConcurrentNavigableMap map = map5();
+ map.putIfAbsent(six, "Z");
+ assertTrue(map.containsKey(six));
+ }
+
+ /**
+ * putIfAbsent does not add the pair if the key is already present
+ */
+ public void testPutIfAbsent2() {
+ ConcurrentNavigableMap map = map5();
+ assertEquals("A", map.putIfAbsent(one, "Z"));
+ }
+
+ /**
+ * replace fails when the given key is not present
+ */
+ public void testReplace() {
+ ConcurrentNavigableMap map = map5();
+ assertNull(map.replace(six, "Z"));
+ assertFalse(map.containsKey(six));
+ }
+
+ /**
+ * replace succeeds if the key is already present
+ */
+ public void testReplace2() {
+ ConcurrentNavigableMap map = map5();
+ assertNotNull(map.replace(one, "Z"));
+ assertEquals("Z", map.get(one));
+ }
+
+ /**
+ * replace value fails when the given key not mapped to expected value
+ */
+ public void testReplaceValue() {
+ ConcurrentNavigableMap map = map5();
+ assertEquals("A", map.get(one));
+ assertFalse(map.replace(one, "Z", "Z"));
+ assertEquals("A", map.get(one));
+ }
+
+ /**
+ * replace value succeeds when the given key mapped to expected value
+ */
+ public void testReplaceValue2() {
+ ConcurrentNavigableMap map = map5();
+ assertEquals("A", map.get(one));
+ assertTrue(map.replace(one, "A", "Z"));
+ assertEquals("Z", map.get(one));
+ }
+
+ /**
+ * remove removes the correct key-value pair from the map
+ */
+ public void testRemove() {
+ ConcurrentNavigableMap map = map5();
+ map.remove(five);
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(five));
+ }
+
+ /**
+ * remove(key,value) removes only if pair present
+ */
+ public void testRemove2() {
+ ConcurrentNavigableMap map = map5();
+ assertTrue(map.containsKey(five));
+ assertEquals("E", map.get(five));
+ map.remove(five, "E");
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(five));
+ map.remove(four, "A");
+ assertEquals(4, map.size());
+ assertTrue(map.containsKey(four));
+ }
+
+ /**
+ * lowerEntry returns preceding entry.
+ */
+ public void testLowerEntry() {
+ ConcurrentNavigableMap map = map5();
+ Map.Entry e1 = map.lowerEntry(three);
+ assertEquals(two, e1.getKey());
+
+ Map.Entry e2 = map.lowerEntry(six);
+ assertEquals(five, e2.getKey());
+
+ Map.Entry e3 = map.lowerEntry(one);
+ assertNull(e3);
+
+ Map.Entry e4 = map.lowerEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higherEntry returns next entry.
+ */
+ public void testHigherEntry() {
+ ConcurrentNavigableMap map = map5();
+ Map.Entry e1 = map.higherEntry(three);
+ assertEquals(four, e1.getKey());
+
+ Map.Entry e2 = map.higherEntry(zero);
+ assertEquals(one, e2.getKey());
+
+ Map.Entry e3 = map.higherEntry(five);
+ assertNull(e3);
+
+ Map.Entry e4 = map.higherEntry(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floorEntry returns preceding entry.
+ */
+ public void testFloorEntry() {
+ ConcurrentNavigableMap map = map5();
+ Map.Entry e1 = map.floorEntry(three);
+ assertEquals(three, e1.getKey());
+
+ Map.Entry e2 = map.floorEntry(six);
+ assertEquals(five, e2.getKey());
+
+ Map.Entry e3 = map.floorEntry(one);
+ assertEquals(one, e3.getKey());
+
+ Map.Entry e4 = map.floorEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceilingEntry returns next entry.
+ */
+ public void testCeilingEntry() {
+ ConcurrentNavigableMap map = map5();
+ Map.Entry e1 = map.ceilingEntry(three);
+ assertEquals(three, e1.getKey());
+
+ Map.Entry e2 = map.ceilingEntry(zero);
+ assertEquals(one, e2.getKey());
+
+ Map.Entry e3 = map.ceilingEntry(five);
+ assertEquals(five, e3.getKey());
+
+ Map.Entry e4 = map.ceilingEntry(six);
+ assertNull(e4);
+ }
+
+ /**
+ * pollFirstEntry returns entries in order
+ */
+ public void testPollFirstEntry() {
+ ConcurrentNavigableMap map = map5();
+ Map.Entry e = map.pollFirstEntry();
+ assertEquals(one, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(two, e.getKey());
+ map.put(one, "A");
+ e = map.pollFirstEntry();
+ assertEquals(one, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(three, e.getKey());
+ map.remove(four);
+ e = map.pollFirstEntry();
+ assertEquals(five, e.getKey());
+ try {
+ e.setValue("A");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollFirstEntry();
+ assertNull(e);
+ }
+
+ /**
+ * pollLastEntry returns entries in order
+ */
+ public void testPollLastEntry() {
+ ConcurrentNavigableMap map = map5();
+ Map.Entry e = map.pollLastEntry();
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(four, e.getKey());
+ map.put(five, "E");
+ e = map.pollLastEntry();
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(three, e.getKey());
+ map.remove(two);
+ e = map.pollLastEntry();
+ assertEquals(one, e.getKey());
+ try {
+ e.setValue("E");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollLastEntry();
+ assertNull(e);
+ }
+
+ /**
+ * size returns the correct values
+ */
+ public void testSize() {
+ ConcurrentNavigableMap map = map5();
+ ConcurrentNavigableMap empty = map0();
+ assertEquals(0, empty.size());
+ assertEquals(5, map.size());
+ }
+
+ /**
+ * toString contains toString of elements
+ */
+ public void testToString() {
+ ConcurrentNavigableMap map = map5();
+ String s = map.toString();
+ for (int i = 1; i <= 5; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ // Exception tests
+
+ /**
+ * get(null) of nonempty map throws NPE
+ */
+ public void testGet_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map5();
+ c.get(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsKey(null) of nonempty map throws NPE
+ */
+ public void testContainsKey_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map5();
+ c.containsKey(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsValue(null) throws NPE
+ */
+ public void testContainsValue_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map0();
+ c.containsValue(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * put(null,x) throws NPE
+ */
+ public void testPut1_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map5();
+ c.put(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * putIfAbsent(null, x) throws NPE
+ */
+ public void testPutIfAbsent1_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map5();
+ c.putIfAbsent(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(null, x) throws NPE
+ */
+ public void testReplace_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map5();
+ c.replace(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(null, x, y) throws NPE
+ */
+ public void testReplaceValue_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map5();
+ c.replace(null, one, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null) throws NPE
+ */
+ public void testRemove1_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map5();
+ c.remove(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null, x) throws NPE
+ */
+ public void testRemove2_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = map5();
+ c.remove(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * A deserialized map equals original
+ */
+ public void testSerialization() throws Exception {
+ NavigableMap x = map5();
+ NavigableMap y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ /**
+ * subMap returns map with keys in requested range
+ */
+ public void testSubMapContents() {
+ ConcurrentNavigableMap map = map5();
+ SortedMap sm = map.subMap(two, four);
+ assertEquals(two, sm.firstKey());
+ assertEquals(three, sm.lastKey());
+ assertEquals(2, sm.size());
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(two));
+ assertEquals(4, map.size());
+ assertEquals(1, sm.size());
+ assertEquals(three, sm.firstKey());
+ assertEquals(three, sm.lastKey());
+ assertEquals("C", sm.remove(three));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, map.size());
+ }
+
+ public void testSubMapContents2() {
+ ConcurrentNavigableMap map = map5();
+ SortedMap sm = map.subMap(two, three);
+ assertEquals(1, sm.size());
+ assertEquals(two, sm.firstKey());
+ assertEquals(two, sm.lastKey());
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertFalse(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(two));
+ assertEquals(4, map.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertSame(sm.remove(three), null);
+ assertEquals(4, map.size());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testHeadMapContents() {
+ ConcurrentNavigableMap map = map5();
+ SortedMap sm = map.headMap(four);
+ assertTrue(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(one, k);
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, map.size());
+ assertEquals(four, map.firstKey());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testTailMapContents() {
+ ConcurrentNavigableMap map = map5();
+ SortedMap sm = map.tailMap(two);
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertTrue(sm.containsKey(four));
+ assertTrue(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ k = (Integer)(i.next());
+ assertEquals(four, k);
+ k = (Integer)(i.next());
+ assertEquals(five, k);
+ assertFalse(i.hasNext());
+
+ Iterator ei = sm.entrySet().iterator();
+ Map.Entry e;
+ e = (Map.Entry)(ei.next());
+ assertEquals(two, e.getKey());
+ assertEquals("B", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(three, e.getKey());
+ assertEquals("C", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(four, e.getKey());
+ assertEquals("D", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ assertFalse(i.hasNext());
+
+ SortedMap ssm = sm.tailMap(four);
+ assertEquals(four, ssm.firstKey());
+ assertEquals(five, ssm.lastKey());
+ assertEquals("D", ssm.remove(four));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, map.size());
+ }
+
+ /**
+ * clear removes all pairs
+ */
+ public void testDescendingClear() {
+ ConcurrentNavigableMap map = dmap5();
+ map.clear();
+ assertEquals(0, map.size());
+ }
+
+ /**
+ * Maps with same contents are equal
+ */
+ public void testDescendingEquals() {
+ ConcurrentNavigableMap map1 = dmap5();
+ ConcurrentNavigableMap map2 = dmap5();
+ assertEquals(map1, map2);
+ assertEquals(map2, map1);
+ map1.clear();
+ assertFalse(map1.equals(map2));
+ assertFalse(map2.equals(map1));
+ }
+
+ /**
+ * containsKey returns true for contained key
+ */
+ public void testDescendingContainsKey() {
+ ConcurrentNavigableMap map = dmap5();
+ assertTrue(map.containsKey(m1));
+ assertFalse(map.containsKey(zero));
+ }
+
+ /**
+ * containsValue returns true for held values
+ */
+ public void testDescendingContainsValue() {
+ ConcurrentNavigableMap map = dmap5();
+ assertTrue(map.containsValue("A"));
+ assertFalse(map.containsValue("Z"));
+ }
+
+ /**
+ * get returns the correct element at the given key,
+ * or null if not present
+ */
+ public void testDescendingGet() {
+ ConcurrentNavigableMap map = dmap5();
+ assertEquals("A", (String)map.get(m1));
+ ConcurrentNavigableMap empty = dmap0();
+ assertNull(empty.get(m1));
+ }
+
+ /**
+ * isEmpty is true of empty map and false for non-empty
+ */
+ public void testDescendingIsEmpty() {
+ ConcurrentNavigableMap empty = dmap0();
+ ConcurrentNavigableMap map = dmap5();
+ assertTrue(empty.isEmpty());
+ assertFalse(map.isEmpty());
+ }
+
+ /**
+ * firstKey returns first key
+ */
+ public void testDescendingFirstKey() {
+ ConcurrentNavigableMap map = dmap5();
+ assertEquals(m1, map.firstKey());
+ }
+
+ /**
+ * lastKey returns last key
+ */
+ public void testDescendingLastKey() {
+ ConcurrentNavigableMap map = dmap5();
+ assertEquals(m5, map.lastKey());
+ }
+
+ /**
+ * keySet returns a Set containing all the keys
+ */
+ public void testDescendingKeySet() {
+ ConcurrentNavigableMap map = dmap5();
+ Set s = map.keySet();
+ assertEquals(5, s.size());
+ assertTrue(s.contains(m1));
+ assertTrue(s.contains(m2));
+ assertTrue(s.contains(m3));
+ assertTrue(s.contains(m4));
+ assertTrue(s.contains(m5));
+ }
+
+ /**
+ * keySet is ordered
+ */
+ public void testDescendingKeySetOrder() {
+ ConcurrentNavigableMap map = dmap5();
+ Set s = map.keySet();
+ Iterator i = s.iterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, m1);
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) > 0);
+ last = k;
+ }
+ }
+
+ /**
+ * values collection contains all values
+ */
+ public void testDescendingValues() {
+ ConcurrentNavigableMap map = dmap5();
+ Collection s = map.values();
+ assertEquals(5, s.size());
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * keySet.toArray returns contains all keys
+ */
+ public void testDescendingAscendingKeySetToArray() {
+ ConcurrentNavigableMap map = dmap5();
+ Set s = map.keySet();
+ Object[] ar = s.toArray();
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ assertEquals(5, ar.length);
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * descendingkeySet.toArray returns contains all keys
+ */
+ public void testDescendingDescendingKeySetToArray() {
+ ConcurrentNavigableMap map = dmap5();
+ Set s = map.descendingKeySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * Values.toArray contains all values
+ */
+ public void testDescendingValuesToArray() {
+ ConcurrentNavigableMap map = dmap5();
+ Collection v = map.values();
+ Object[] ar = v.toArray();
+ ArrayList s = new ArrayList(Arrays.asList(ar));
+ assertEquals(5, ar.length);
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * entrySet contains all pairs
+ */
+ public void testDescendingEntrySet() {
+ ConcurrentNavigableMap map = dmap5();
+ Set s = map.entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(m1) && e.getValue().equals("A")) ||
+ (e.getKey().equals(m2) && e.getValue().equals("B")) ||
+ (e.getKey().equals(m3) && e.getValue().equals("C")) ||
+ (e.getKey().equals(m4) && e.getValue().equals("D")) ||
+ (e.getKey().equals(m5) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * putAll adds all key-value pairs from the given map
+ */
+ public void testDescendingPutAll() {
+ ConcurrentNavigableMap empty = dmap0();
+ ConcurrentNavigableMap map = dmap5();
+ empty.putAll(map);
+ assertEquals(5, empty.size());
+ assertTrue(empty.containsKey(m1));
+ assertTrue(empty.containsKey(m2));
+ assertTrue(empty.containsKey(m3));
+ assertTrue(empty.containsKey(m4));
+ assertTrue(empty.containsKey(m5));
+ }
+
+ /**
+ * putIfAbsent works when the given key is not present
+ */
+ public void testDescendingPutIfAbsent() {
+ ConcurrentNavigableMap map = dmap5();
+ map.putIfAbsent(six, "Z");
+ assertTrue(map.containsKey(six));
+ }
+
+ /**
+ * putIfAbsent does not add the pair if the key is already present
+ */
+ public void testDescendingPutIfAbsent2() {
+ ConcurrentNavigableMap map = dmap5();
+ assertEquals("A", map.putIfAbsent(m1, "Z"));
+ }
+
+ /**
+ * replace fails when the given key is not present
+ */
+ public void testDescendingReplace() {
+ ConcurrentNavigableMap map = dmap5();
+ assertNull(map.replace(six, "Z"));
+ assertFalse(map.containsKey(six));
+ }
+
+ /**
+ * replace succeeds if the key is already present
+ */
+ public void testDescendingReplace2() {
+ ConcurrentNavigableMap map = dmap5();
+ assertNotNull(map.replace(m1, "Z"));
+ assertEquals("Z", map.get(m1));
+ }
+
+ /**
+ * replace value fails when the given key not mapped to expected value
+ */
+ public void testDescendingReplaceValue() {
+ ConcurrentNavigableMap map = dmap5();
+ assertEquals("A", map.get(m1));
+ assertFalse(map.replace(m1, "Z", "Z"));
+ assertEquals("A", map.get(m1));
+ }
+
+ /**
+ * replace value succeeds when the given key mapped to expected value
+ */
+ public void testDescendingReplaceValue2() {
+ ConcurrentNavigableMap map = dmap5();
+ assertEquals("A", map.get(m1));
+ assertTrue(map.replace(m1, "A", "Z"));
+ assertEquals("Z", map.get(m1));
+ }
+
+ /**
+ * remove removes the correct key-value pair from the map
+ */
+ public void testDescendingRemove() {
+ ConcurrentNavigableMap map = dmap5();
+ map.remove(m5);
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(m5));
+ }
+
+ /**
+ * remove(key,value) removes only if pair present
+ */
+ public void testDescendingRemove2() {
+ ConcurrentNavigableMap map = dmap5();
+ assertTrue(map.containsKey(m5));
+ assertEquals("E", map.get(m5));
+ map.remove(m5, "E");
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(m5));
+ map.remove(m4, "A");
+ assertEquals(4, map.size());
+ assertTrue(map.containsKey(m4));
+ }
+
+ /**
+ * lowerEntry returns preceding entry.
+ */
+ public void testDescendingLowerEntry() {
+ ConcurrentNavigableMap map = dmap5();
+ Map.Entry e1 = map.lowerEntry(m3);
+ assertEquals(m2, e1.getKey());
+
+ Map.Entry e2 = map.lowerEntry(m6);
+ assertEquals(m5, e2.getKey());
+
+ Map.Entry e3 = map.lowerEntry(m1);
+ assertNull(e3);
+
+ Map.Entry e4 = map.lowerEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higherEntry returns next entry.
+ */
+ public void testDescendingHigherEntry() {
+ ConcurrentNavigableMap map = dmap5();
+ Map.Entry e1 = map.higherEntry(m3);
+ assertEquals(m4, e1.getKey());
+
+ Map.Entry e2 = map.higherEntry(zero);
+ assertEquals(m1, e2.getKey());
+
+ Map.Entry e3 = map.higherEntry(m5);
+ assertNull(e3);
+
+ Map.Entry e4 = map.higherEntry(m6);
+ assertNull(e4);
+ }
+
+ /**
+ * floorEntry returns preceding entry.
+ */
+ public void testDescendingFloorEntry() {
+ ConcurrentNavigableMap map = dmap5();
+ Map.Entry e1 = map.floorEntry(m3);
+ assertEquals(m3, e1.getKey());
+
+ Map.Entry e2 = map.floorEntry(m6);
+ assertEquals(m5, e2.getKey());
+
+ Map.Entry e3 = map.floorEntry(m1);
+ assertEquals(m1, e3.getKey());
+
+ Map.Entry e4 = map.floorEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceilingEntry returns next entry.
+ */
+ public void testDescendingCeilingEntry() {
+ ConcurrentNavigableMap map = dmap5();
+ Map.Entry e1 = map.ceilingEntry(m3);
+ assertEquals(m3, e1.getKey());
+
+ Map.Entry e2 = map.ceilingEntry(zero);
+ assertEquals(m1, e2.getKey());
+
+ Map.Entry e3 = map.ceilingEntry(m5);
+ assertEquals(m5, e3.getKey());
+
+ Map.Entry e4 = map.ceilingEntry(m6);
+ assertNull(e4);
+ }
+
+ /**
+ * pollFirstEntry returns entries in order
+ */
+ public void testDescendingPollFirstEntry() {
+ ConcurrentNavigableMap map = dmap5();
+ Map.Entry e = map.pollFirstEntry();
+ assertEquals(m1, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(m2, e.getKey());
+ map.put(m1, "A");
+ e = map.pollFirstEntry();
+ assertEquals(m1, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(m3, e.getKey());
+ map.remove(m4);
+ e = map.pollFirstEntry();
+ assertEquals(m5, e.getKey());
+ try {
+ e.setValue("A");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollFirstEntry();
+ assertNull(e);
+ }
+
+ /**
+ * pollLastEntry returns entries in order
+ */
+ public void testDescendingPollLastEntry() {
+ ConcurrentNavigableMap map = dmap5();
+ Map.Entry e = map.pollLastEntry();
+ assertEquals(m5, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(m4, e.getKey());
+ map.put(m5, "E");
+ e = map.pollLastEntry();
+ assertEquals(m5, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(m3, e.getKey());
+ map.remove(m2);
+ e = map.pollLastEntry();
+ assertEquals(m1, e.getKey());
+ try {
+ e.setValue("E");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollLastEntry();
+ assertNull(e);
+ }
+
+ /**
+ * size returns the correct values
+ */
+ public void testDescendingSize() {
+ ConcurrentNavigableMap map = dmap5();
+ ConcurrentNavigableMap empty = dmap0();
+ assertEquals(0, empty.size());
+ assertEquals(5, map.size());
+ }
+
+ /**
+ * toString contains toString of elements
+ */
+ public void testDescendingToString() {
+ ConcurrentNavigableMap map = dmap5();
+ String s = map.toString();
+ for (int i = 1; i <= 5; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ // Exception testDescendings
+
+ /**
+ * get(null) of empty map throws NPE
+ */
+ public void testDescendingGet_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap5();
+ c.get(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsKey(null) of empty map throws NPE
+ */
+ public void testDescendingContainsKey_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap5();
+ c.containsKey(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsValue(null) throws NPE
+ */
+ public void testDescendingContainsValue_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap0();
+ c.containsValue(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * put(null,x) throws NPE
+ */
+ public void testDescendingPut1_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap5();
+ c.put(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * putIfAbsent(null, x) throws NPE
+ */
+ public void testDescendingPutIfAbsent1_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap5();
+ c.putIfAbsent(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(null, x) throws NPE
+ */
+ public void testDescendingReplace_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap5();
+ c.replace(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * replace(null, x, y) throws NPE
+ */
+ public void testDescendingReplaceValue_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap5();
+ c.replace(null, m1, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null) throws NPE
+ */
+ public void testDescendingRemove1_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap5();
+ c.remove(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null, x) throws NPE
+ */
+ public void testDescendingRemove2_NullPointerException() {
+ try {
+ ConcurrentNavigableMap c = dmap5();
+ c.remove(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * A deserialized map equals original
+ */
+ public void testDescendingSerialization() throws Exception {
+ NavigableMap x = dmap5();
+ NavigableMap y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ /**
+ * subMap returns map with keys in requested range
+ */
+ public void testDescendingSubMapContents() {
+ ConcurrentNavigableMap map = dmap5();
+ SortedMap sm = map.subMap(m2, m4);
+ assertEquals(m2, sm.firstKey());
+ assertEquals(m3, sm.lastKey());
+ assertEquals(2, sm.size());
+ assertFalse(sm.containsKey(m1));
+ assertTrue(sm.containsKey(m2));
+ assertTrue(sm.containsKey(m3));
+ assertFalse(sm.containsKey(m4));
+ assertFalse(sm.containsKey(m5));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(m2));
+ assertEquals(4, map.size());
+ assertEquals(1, sm.size());
+ assertEquals(m3, sm.firstKey());
+ assertEquals(m3, sm.lastKey());
+ assertEquals("C", sm.remove(m3));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, map.size());
+ }
+
+ public void testDescendingSubMapContents2() {
+ ConcurrentNavigableMap map = dmap5();
+ SortedMap sm = map.subMap(m2, m3);
+ assertEquals(1, sm.size());
+ assertEquals(m2, sm.firstKey());
+ assertEquals(m2, sm.lastKey());
+ assertFalse(sm.containsKey(m1));
+ assertTrue(sm.containsKey(m2));
+ assertFalse(sm.containsKey(m3));
+ assertFalse(sm.containsKey(m4));
+ assertFalse(sm.containsKey(m5));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(m2));
+ assertEquals(4, map.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertSame(sm.remove(m3), null);
+ assertEquals(4, map.size());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testDescendingHeadMapContents() {
+ ConcurrentNavigableMap map = dmap5();
+ SortedMap sm = map.headMap(m4);
+ assertTrue(sm.containsKey(m1));
+ assertTrue(sm.containsKey(m2));
+ assertTrue(sm.containsKey(m3));
+ assertFalse(sm.containsKey(m4));
+ assertFalse(sm.containsKey(m5));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m1, k);
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, map.size());
+ assertEquals(m4, map.firstKey());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testDescendingTailMapContents() {
+ ConcurrentNavigableMap map = dmap5();
+ SortedMap sm = map.tailMap(m2);
+ assertFalse(sm.containsKey(m1));
+ assertTrue(sm.containsKey(m2));
+ assertTrue(sm.containsKey(m3));
+ assertTrue(sm.containsKey(m4));
+ assertTrue(sm.containsKey(m5));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ k = (Integer)(i.next());
+ assertEquals(m4, k);
+ k = (Integer)(i.next());
+ assertEquals(m5, k);
+ assertFalse(i.hasNext());
+
+ Iterator ei = sm.entrySet().iterator();
+ Map.Entry e;
+ e = (Map.Entry)(ei.next());
+ assertEquals(m2, e.getKey());
+ assertEquals("B", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(m3, e.getKey());
+ assertEquals("C", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(m4, e.getKey());
+ assertEquals("D", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(m5, e.getKey());
+ assertEquals("E", e.getValue());
+ assertFalse(i.hasNext());
+
+ SortedMap ssm = sm.tailMap(m4);
+ assertEquals(m4, ssm.firstKey());
+ assertEquals(m5, ssm.lastKey());
+ assertEquals("D", ssm.remove(m4));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, map.size());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java
new file mode 100644
index 0000000..43c1759
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java
@@ -0,0 +1,1123 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+public class ConcurrentSkipListSubSetTest extends JSR166TestCase {
+
+ static class MyReverseComparator implements Comparator {
+ public int compare(Object x, Object y) {
+ return ((Comparable)y).compareTo(x);
+ }
+ }
+
+ /**
+ * Returns a new set of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private NavigableSet<Integer> populatedSet(int n) {
+ ConcurrentSkipListSet<Integer> q =
+ new ConcurrentSkipListSet<Integer>();
+ assertTrue(q.isEmpty());
+
+ for (int i = n-1; i >= 0; i-=2)
+ assertTrue(q.add(new Integer(i)));
+ for (int i = (n & 1); i < n; i+=2)
+ assertTrue(q.add(new Integer(i)));
+ assertTrue(q.add(new Integer(-n)));
+ assertTrue(q.add(new Integer(n)));
+ NavigableSet s = q.subSet(new Integer(0), true, new Integer(n), false);
+ assertFalse(s.isEmpty());
+ assertEquals(n, s.size());
+ return s;
+ }
+
+ /**
+ * Returns a new set of first 5 ints.
+ */
+ private NavigableSet set5() {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ assertTrue(q.isEmpty());
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ q.add(four);
+ q.add(five);
+ q.add(zero);
+ q.add(seven);
+ NavigableSet s = q.subSet(one, true, seven, false);
+ assertEquals(5, s.size());
+ return s;
+ }
+
+ /**
+ * Returns a new set of first 5 negative ints.
+ */
+ private NavigableSet dset5() {
+ ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+ assertTrue(q.isEmpty());
+ q.add(m1);
+ q.add(m2);
+ q.add(m3);
+ q.add(m4);
+ q.add(m5);
+ NavigableSet s = q.descendingSet();
+ assertEquals(5, s.size());
+ return s;
+ }
+
+ private static NavigableSet set0() {
+ ConcurrentSkipListSet set = new ConcurrentSkipListSet();
+ assertTrue(set.isEmpty());
+ return set.tailSet(m1, true);
+ }
+
+ private static NavigableSet dset0() {
+ ConcurrentSkipListSet set = new ConcurrentSkipListSet();
+ assertTrue(set.isEmpty());
+ return set;
+ }
+
+ /**
+ * A new set has unbounded capacity
+ */
+ public void testConstructor1() {
+ assertEquals(0, set0().size());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ NavigableSet q = set0();
+ assertTrue(q.isEmpty());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.add(new Integer(2));
+ q.pollFirst();
+ q.pollFirst();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.pollFirst();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * add(null) throws NPE
+ */
+ public void testAddNull() {
+ try {
+ NavigableSet q = set0();
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Add of comparable element succeeds
+ */
+ public void testAdd() {
+ NavigableSet q = set0();
+ assertTrue(q.add(six));
+ }
+
+ /**
+ * Add of duplicate element fails
+ */
+ public void testAddDup() {
+ NavigableSet q = set0();
+ assertTrue(q.add(six));
+ assertFalse(q.add(six));
+ }
+
+ /**
+ * Add of non-Comparable throws CCE
+ */
+ public void testAddNonComparable() {
+ try {
+ NavigableSet q = set0();
+ q.add(new Object());
+ q.add(new Object());
+ q.add(new Object());
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ NavigableSet q = set0();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ NavigableSet q = set0();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ NavigableSet q = set0();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i+SIZE);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Set contains all elements of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(SIZE-1- i);
+ NavigableSet q = set0();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(new Integer(i), q.pollFirst());
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove(i+1));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.pollFirst();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ NavigableSet q = populatedSet(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = set0();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.pollFirst();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = populatedSet(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.pollFirst());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * lower returns preceding element
+ */
+ public void testLower() {
+ NavigableSet q = set5();
+ Object e1 = q.lower(three);
+ assertEquals(two, e1);
+
+ Object e2 = q.lower(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.lower(one);
+ assertNull(e3);
+
+ Object e4 = q.lower(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higher returns next element
+ */
+ public void testHigher() {
+ NavigableSet q = set5();
+ Object e1 = q.higher(three);
+ assertEquals(four, e1);
+
+ Object e2 = q.higher(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.higher(five);
+ assertNull(e3);
+
+ Object e4 = q.higher(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floor returns preceding element
+ */
+ public void testFloor() {
+ NavigableSet q = set5();
+ Object e1 = q.floor(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.floor(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.floor(one);
+ assertEquals(one, e3);
+
+ Object e4 = q.floor(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceiling returns next element
+ */
+ public void testCeiling() {
+ NavigableSet q = set5();
+ Object e1 = q.ceiling(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.ceiling(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.ceiling(five);
+ assertEquals(five, e3);
+
+ Object e4 = q.ceiling(six);
+ assertNull(e4);
+ }
+
+ /**
+ * toArray contains all elements in sorted order
+ */
+ public void testToArray() {
+ NavigableSet q = populatedSet(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.pollFirst());
+ }
+
+ /**
+ * toArray(a) contains all elements in sorted order
+ */
+ public void testToArray2() {
+ NavigableSet<Integer> q = populatedSet(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.pollFirst());
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ NavigableSet q = populatedSet(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator of empty set has no elements
+ */
+ public void testEmptyIterator() {
+ NavigableSet q = set0();
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(0, i);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final NavigableSet q = set0();
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ q.add(new Integer(3));
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertEquals(it.next(), new Integer(2));
+ assertEquals(it.next(), new Integer(3));
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ NavigableSet q = populatedSet(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized set has same elements
+ */
+ public void testSerialization() throws Exception {
+ NavigableSet x = populatedSet(SIZE);
+ NavigableSet y = serialClone(x);
+
+ assertNotSame(y, x);
+ assertEquals(x.size(), y.size());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.pollFirst(), y.pollFirst());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * subSet returns set with keys in requested range
+ */
+ public void testSubSetContents() {
+ NavigableSet set = set5();
+ SortedSet sm = set.subSet(two, four);
+ assertEquals(two, sm.first());
+ assertEquals(three, sm.last());
+ assertEquals(2, sm.size());
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(two));
+ assertEquals(4, set.size());
+ assertEquals(1, sm.size());
+ assertEquals(three, sm.first());
+ assertEquals(three, sm.last());
+ assertTrue(sm.remove(three));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, set.size());
+ }
+
+ public void testSubSetContents2() {
+ NavigableSet set = set5();
+ SortedSet sm = set.subSet(two, three);
+ assertEquals(1, sm.size());
+ assertEquals(two, sm.first());
+ assertEquals(two, sm.last());
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertFalse(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(two));
+ assertEquals(4, set.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertFalse(sm.remove(three));
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * headSet returns set with keys in requested range
+ */
+ public void testHeadSetContents() {
+ NavigableSet set = set5();
+ SortedSet sm = set.headSet(four);
+ assertTrue(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(one, k);
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, set.size());
+ assertEquals(four, set.first());
+ }
+
+ /**
+ * tailSet returns set with keys in requested range
+ */
+ public void testTailSetContents() {
+ NavigableSet set = set5();
+ SortedSet sm = set.tailSet(two);
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertTrue(sm.contains(four));
+ assertTrue(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ k = (Integer)(i.next());
+ assertEquals(four, k);
+ k = (Integer)(i.next());
+ assertEquals(five, k);
+ assertFalse(i.hasNext());
+
+ SortedSet ssm = sm.tailSet(four);
+ assertEquals(four, ssm.first());
+ assertEquals(five, ssm.last());
+ assertTrue(ssm.remove(four));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testDescendingSize() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.pollFirst();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * add(null) throws NPE
+ */
+ public void testDescendingAddNull() {
+ try {
+ NavigableSet q = dset0();
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Add of comparable element succeeds
+ */
+ public void testDescendingAdd() {
+ NavigableSet q = dset0();
+ assertTrue(q.add(m6));
+ }
+
+ /**
+ * Add of duplicate element fails
+ */
+ public void testDescendingAddDup() {
+ NavigableSet q = dset0();
+ assertTrue(q.add(m6));
+ assertFalse(q.add(m6));
+ }
+
+ /**
+ * Add of non-Comparable throws CCE
+ */
+ public void testDescendingAddNonComparable() {
+ try {
+ NavigableSet q = dset0();
+ q.add(new Object());
+ q.add(new Object());
+ q.add(new Object());
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testDescendingAddAll1() {
+ try {
+ NavigableSet q = dset0();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testDescendingAddAll2() {
+ try {
+ NavigableSet q = dset0();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testDescendingAddAll3() {
+ try {
+ NavigableSet q = dset0();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i+SIZE);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Set contains all elements of successful addAll
+ */
+ public void testDescendingAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(SIZE-1- i);
+ NavigableSet q = dset0();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(new Integer(i), q.pollFirst());
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testDescendingPoll() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testDescendingRemoveElement() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.remove(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.remove(new Integer(i)));
+ assertFalse(q.remove(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testDescendingContains() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.pollFirst();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testDescendingClear() {
+ NavigableSet q = populatedSet(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testDescendingContainsAll() {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = dset0();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testDescendingRetainAll() {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.pollFirst();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testDescendingRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = populatedSet(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.pollFirst());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * lower returns preceding element
+ */
+ public void testDescendingLower() {
+ NavigableSet q = dset5();
+ Object e1 = q.lower(m3);
+ assertEquals(m2, e1);
+
+ Object e2 = q.lower(m6);
+ assertEquals(m5, e2);
+
+ Object e3 = q.lower(m1);
+ assertNull(e3);
+
+ Object e4 = q.lower(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higher returns next element
+ */
+ public void testDescendingHigher() {
+ NavigableSet q = dset5();
+ Object e1 = q.higher(m3);
+ assertEquals(m4, e1);
+
+ Object e2 = q.higher(zero);
+ assertEquals(m1, e2);
+
+ Object e3 = q.higher(m5);
+ assertNull(e3);
+
+ Object e4 = q.higher(m6);
+ assertNull(e4);
+ }
+
+ /**
+ * floor returns preceding element
+ */
+ public void testDescendingFloor() {
+ NavigableSet q = dset5();
+ Object e1 = q.floor(m3);
+ assertEquals(m3, e1);
+
+ Object e2 = q.floor(m6);
+ assertEquals(m5, e2);
+
+ Object e3 = q.floor(m1);
+ assertEquals(m1, e3);
+
+ Object e4 = q.floor(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceiling returns next element
+ */
+ public void testDescendingCeiling() {
+ NavigableSet q = dset5();
+ Object e1 = q.ceiling(m3);
+ assertEquals(m3, e1);
+
+ Object e2 = q.ceiling(zero);
+ assertEquals(m1, e2);
+
+ Object e3 = q.ceiling(m5);
+ assertEquals(m5, e3);
+
+ Object e4 = q.ceiling(m6);
+ assertNull(e4);
+ }
+
+ /**
+ * toArray contains all elements
+ */
+ public void testDescendingToArray() {
+ NavigableSet q = populatedSet(SIZE);
+ Object[] o = q.toArray();
+ Arrays.sort(o);
+ for (int i = 0; i < o.length; i++)
+ assertEquals(o[i], q.pollFirst());
+ }
+
+ /**
+ * toArray(a) contains all elements
+ */
+ public void testDescendingToArray2() {
+ NavigableSet q = populatedSet(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ assertSame(ints, q.toArray(ints));
+ Arrays.sort(ints);
+ for (int i = 0; i < ints.length; i++)
+ assertEquals(ints[i], q.pollFirst());
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testDescendingIterator() {
+ NavigableSet q = populatedSet(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator of empty set has no elements
+ */
+ public void testDescendingEmptyIterator() {
+ NavigableSet q = dset0();
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(0, i);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testDescendingIteratorRemove() {
+ final NavigableSet q = dset0();
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ q.add(new Integer(3));
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertEquals(it.next(), new Integer(2));
+ assertEquals(it.next(), new Integer(3));
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testDescendingToString() {
+ NavigableSet q = populatedSet(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized set has same elements
+ */
+ public void testDescendingSerialization() throws Exception {
+ NavigableSet x = dset5();
+ NavigableSet y = serialClone(x);
+
+ assertNotSame(y, x);
+ assertEquals(x.size(), y.size());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.pollFirst(), y.pollFirst());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * subSet returns set with keys in requested range
+ */
+ public void testDescendingSubSetContents() {
+ NavigableSet set = dset5();
+ SortedSet sm = set.subSet(m2, m4);
+ assertEquals(m2, sm.first());
+ assertEquals(m3, sm.last());
+ assertEquals(2, sm.size());
+ assertFalse(sm.contains(m1));
+ assertTrue(sm.contains(m2));
+ assertTrue(sm.contains(m3));
+ assertFalse(sm.contains(m4));
+ assertFalse(sm.contains(m5));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(m2));
+ assertEquals(4, set.size());
+ assertEquals(1, sm.size());
+ assertEquals(m3, sm.first());
+ assertEquals(m3, sm.last());
+ assertTrue(sm.remove(m3));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, set.size());
+ }
+
+ public void testDescendingSubSetContents2() {
+ NavigableSet set = dset5();
+ SortedSet sm = set.subSet(m2, m3);
+ assertEquals(1, sm.size());
+ assertEquals(m2, sm.first());
+ assertEquals(m2, sm.last());
+ assertFalse(sm.contains(m1));
+ assertTrue(sm.contains(m2));
+ assertFalse(sm.contains(m3));
+ assertFalse(sm.contains(m4));
+ assertFalse(sm.contains(m5));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(m2));
+ assertEquals(4, set.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertFalse(sm.remove(m3));
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * headSet returns set with keys in requested range
+ */
+ public void testDescendingHeadSetContents() {
+ NavigableSet set = dset5();
+ SortedSet sm = set.headSet(m4);
+ assertTrue(sm.contains(m1));
+ assertTrue(sm.contains(m2));
+ assertTrue(sm.contains(m3));
+ assertFalse(sm.contains(m4));
+ assertFalse(sm.contains(m5));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m1, k);
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, set.size());
+ assertEquals(m4, set.first());
+ }
+
+ /**
+ * tailSet returns set with keys in requested range
+ */
+ public void testDescendingTailSetContents() {
+ NavigableSet set = dset5();
+ SortedSet sm = set.tailSet(m2);
+ assertFalse(sm.contains(m1));
+ assertTrue(sm.contains(m2));
+ assertTrue(sm.contains(m3));
+ assertTrue(sm.contains(m4));
+ assertTrue(sm.contains(m5));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ k = (Integer)(i.next());
+ assertEquals(m4, k);
+ k = (Integer)(i.next());
+ assertEquals(m5, k);
+ assertFalse(i.hasNext());
+
+ SortedSet ssm = sm.tailSet(m4);
+ assertEquals(m4, ssm.first());
+ assertEquals(m5, ssm.last());
+ assertTrue(ssm.remove(m4));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, set.size());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java
new file mode 100644
index 0000000..6bef8be
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java
@@ -0,0 +1,705 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class CopyOnWriteArrayListTest extends JSR166TestCase {
+
+ static CopyOnWriteArrayList<Integer> populatedArray(int n) {
+ CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<Integer>();
+ assertTrue(a.isEmpty());
+ for (int i = 0; i < n; i++)
+ a.add(i);
+ assertFalse(a.isEmpty());
+ assertEquals(n, a.size());
+ return a;
+ }
+
+ static CopyOnWriteArrayList<Integer> populatedArray(Integer[] elements) {
+ CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<Integer>();
+ assertTrue(a.isEmpty());
+ for (int i = 0; i < elements.length; i++)
+ a.add(elements[i]);
+ assertFalse(a.isEmpty());
+ assertEquals(elements.length, a.size());
+ return a;
+ }
+
+ /**
+ * a new list is empty
+ */
+ public void testConstructor() {
+ CopyOnWriteArrayList a = new CopyOnWriteArrayList();
+ assertTrue(a.isEmpty());
+ }
+
+ /**
+ * new list contains all elements of initializing array
+ */
+ public void testConstructor2() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ CopyOnWriteArrayList a = new CopyOnWriteArrayList(ints);
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], a.get(i));
+ }
+
+ /**
+ * new list contains all elements of initializing collection
+ */
+ public void testConstructor3() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ CopyOnWriteArrayList a = new CopyOnWriteArrayList(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], a.get(i));
+ }
+
+ /**
+ * addAll adds each element from the given collection
+ */
+ public void testAddAll() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ Vector v = new Vector();
+ v.add(three);
+ v.add(four);
+ v.add(five);
+ full.addAll(v);
+ assertEquals(6, full.size());
+ }
+
+ /**
+ * addAllAbsent adds each element from the given collection that did not
+ * already exist in the List
+ */
+ public void testAddAllAbsent() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ Vector v = new Vector();
+ v.add(three);
+ v.add(four);
+ v.add(one); // will not add this element
+ full.addAllAbsent(v);
+ assertEquals(5, full.size());
+ }
+
+ /**
+ * addIfAbsent will not add the element if it already exists in the list
+ */
+ public void testAddIfAbsent() {
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ full.addIfAbsent(one);
+ assertEquals(SIZE, full.size());
+ }
+
+ /**
+ * addIfAbsent adds the element when it does not exist in the list
+ */
+ public void testAddIfAbsent2() {
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ full.addIfAbsent(three);
+ assertTrue(full.contains(three));
+ }
+
+ /**
+ * clear removes all elements from the list
+ */
+ public void testClear() {
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ full.clear();
+ assertEquals(0, full.size());
+ }
+
+ /**
+ * Cloned list is equal
+ */
+ public void testClone() {
+ CopyOnWriteArrayList l1 = populatedArray(SIZE);
+ CopyOnWriteArrayList l2 = (CopyOnWriteArrayList)(l1.clone());
+ assertEquals(l1, l2);
+ l1.clear();
+ assertFalse(l1.equals(l2));
+ }
+
+ /**
+ * contains is true for added elements
+ */
+ public void testContains() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ assertTrue(full.contains(one));
+ assertFalse(full.contains(five));
+ }
+
+ /**
+ * adding at an index places it in the indicated index
+ */
+ public void testAddIndex() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ full.add(0, m1);
+ assertEquals(4, full.size());
+ assertEquals(m1, full.get(0));
+ assertEquals(zero, full.get(1));
+
+ full.add(2, m2);
+ assertEquals(5, full.size());
+ assertEquals(m2, full.get(2));
+ assertEquals(two, full.get(4));
+ }
+
+ /**
+ * lists with same elements are equal and have same hashCode
+ */
+ public void testEquals() {
+ CopyOnWriteArrayList a = populatedArray(3);
+ CopyOnWriteArrayList b = populatedArray(3);
+ assertTrue(a.equals(b));
+ assertTrue(b.equals(a));
+ assertEquals(a.hashCode(), b.hashCode());
+ a.add(m1);
+ assertFalse(a.equals(b));
+ assertFalse(b.equals(a));
+ b.add(m1);
+ assertTrue(a.equals(b));
+ assertTrue(b.equals(a));
+ assertEquals(a.hashCode(), b.hashCode());
+ }
+
+ /**
+ * containsAll returns true for collection with subset of elements
+ */
+ public void testContainsAll() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ Vector v = new Vector();
+ v.add(one);
+ v.add(two);
+ assertTrue(full.containsAll(v));
+ v.add(six);
+ assertFalse(full.containsAll(v));
+ }
+
+ /**
+ * get returns the value at the given index
+ */
+ public void testGet() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ assertEquals(0, full.get(0));
+ }
+
+ /**
+ * indexOf gives the index for the given object
+ */
+ public void testIndexOf() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ assertEquals(1, full.indexOf(one));
+ assertEquals(-1, full.indexOf("puppies"));
+ }
+
+ /**
+ * indexOf gives the index based on the given index
+ * at which to start searching
+ */
+ public void testIndexOf2() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ assertEquals(1, full.indexOf(one, 0));
+ assertEquals(-1, full.indexOf(one, 2));
+ }
+
+ /**
+ * isEmpty returns true when empty, else false
+ */
+ public void testIsEmpty() {
+ CopyOnWriteArrayList empty = new CopyOnWriteArrayList();
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ assertTrue(empty.isEmpty());
+ assertFalse(full.isEmpty());
+ }
+
+ /**
+ * iterator() returns an iterator containing the elements of the
+ * list in insertion order
+ */
+ public void testIterator() {
+ Collection empty = new CopyOnWriteArrayList();
+ assertFalse(empty.iterator().hasNext());
+ try {
+ empty.iterator().next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+
+ Integer[] elements = new Integer[SIZE];
+ for (int i = 0; i < SIZE; i++)
+ elements[i] = i;
+ Collections.shuffle(Arrays.asList(elements));
+ Collection<Integer> full = populatedArray(elements);
+
+ Iterator it = full.iterator();
+ for (int j = 0; j < SIZE; j++) {
+ assertTrue(it.hasNext());
+ assertEquals(elements[j], it.next());
+ }
+ assertFalse(it.hasNext());
+ try {
+ it.next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * iterator.remove throws UnsupportedOperationException
+ */
+ public void testIteratorRemove() {
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ Iterator it = full.iterator();
+ it.next();
+ try {
+ it.remove();
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ }
+
+ /**
+ * toString contains toString of elements
+ */
+ public void testToString() {
+ assertEquals("[]", new CopyOnWriteArrayList().toString());
+ CopyOnWriteArrayList full = populatedArray(3);
+ String s = full.toString();
+ for (int i = 0; i < 3; ++i)
+ assertTrue(s.contains(String.valueOf(i)));
+ assertEquals(new ArrayList(full).toString(),
+ full.toString());
+ }
+
+ /**
+ * lastIndexOf returns the index for the given object
+ */
+ public void testLastIndexOf1() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ full.add(one);
+ full.add(three);
+ assertEquals(3, full.lastIndexOf(one));
+ assertEquals(-1, full.lastIndexOf(six));
+ }
+
+ /**
+ * lastIndexOf returns the index from the given starting point
+ */
+ public void testLastIndexOf2() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ full.add(one);
+ full.add(three);
+ assertEquals(3, full.lastIndexOf(one, 4));
+ assertEquals(-1, full.lastIndexOf(three, 3));
+ }
+
+ /**
+ * listIterator traverses all elements
+ */
+ public void testListIterator1() {
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ ListIterator i = full.listIterator();
+ int j;
+ for (j = 0; i.hasNext(); j++)
+ assertEquals(j, i.next());
+ assertEquals(SIZE, j);
+ }
+
+ /**
+ * listIterator only returns those elements after the given index
+ */
+ public void testListIterator2() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ ListIterator i = full.listIterator(1);
+ int j;
+ for (j = 0; i.hasNext(); j++)
+ assertEquals(j+1, i.next());
+ assertEquals(2, j);
+ }
+
+ /**
+ * remove(int) removes and returns the object at the given index
+ */
+ public void testRemove_int() {
+ int SIZE = 3;
+ for (int i = 0; i < SIZE; i++) {
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ assertEquals(i, full.remove(i));
+ assertEquals(SIZE - 1, full.size());
+ assertFalse(full.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * remove(Object) removes the object if found and returns true
+ */
+ public void testRemove_Object() {
+ int SIZE = 3;
+ for (int i = 0; i < SIZE; i++) {
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ assertFalse(full.remove(new Integer(-42)));
+ assertTrue(full.remove(new Integer(i)));
+ assertEquals(SIZE - 1, full.size());
+ assertFalse(full.contains(new Integer(i)));
+ }
+ CopyOnWriteArrayList x = new CopyOnWriteArrayList(Arrays.asList(4, 5, 6));
+ assertTrue(x.remove(new Integer(6)));
+ assertEquals(x, Arrays.asList(4, 5));
+ assertTrue(x.remove(new Integer(4)));
+ assertEquals(x, Arrays.asList(5));
+ assertTrue(x.remove(new Integer(5)));
+ assertEquals(x, Arrays.asList());
+ assertFalse(x.remove(new Integer(5)));
+ }
+
+ /**
+ * removeAll removes all elements from the given collection
+ */
+ public void testRemoveAll() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ Vector v = new Vector();
+ v.add(one);
+ v.add(two);
+ full.removeAll(v);
+ assertEquals(1, full.size());
+ }
+
+ /**
+ * set changes the element at the given index
+ */
+ public void testSet() {
+ CopyOnWriteArrayList full = populatedArray(3);
+ assertEquals(2, full.set(2, four));
+ assertEquals(4, full.get(2));
+ }
+
+ /**
+ * size returns the number of elements
+ */
+ public void testSize() {
+ CopyOnWriteArrayList empty = new CopyOnWriteArrayList();
+ CopyOnWriteArrayList full = populatedArray(SIZE);
+ assertEquals(SIZE, full.size());
+ assertEquals(0, empty.size());
+ }
+
+ /**
+ * toArray() returns an Object array containing all elements from
+ * the list in insertion order
+ */
+ public void testToArray() {
+ Object[] a = new CopyOnWriteArrayList().toArray();
+ assertTrue(Arrays.equals(new Object[0], a));
+ assertSame(Object[].class, a.getClass());
+
+ Integer[] elements = new Integer[SIZE];
+ for (int i = 0; i < SIZE; i++)
+ elements[i] = i;
+ Collections.shuffle(Arrays.asList(elements));
+ Collection<Integer> full = populatedArray(elements);
+
+ assertTrue(Arrays.equals(elements, full.toArray()));
+ assertSame(Object[].class, full.toArray().getClass());
+ }
+
+ /**
+ * toArray(Integer array) returns an Integer array containing all
+ * elements from the list in insertion order
+ */
+ public void testToArray2() {
+ Collection empty = new CopyOnWriteArrayList();
+ Integer[] a;
+
+ a = new Integer[0];
+ assertSame(a, empty.toArray(a));
+
+ a = new Integer[SIZE/2];
+ Arrays.fill(a, 42);
+ assertSame(a, empty.toArray(a));
+ assertNull(a[0]);
+ for (int i = 1; i < a.length; i++)
+ assertEquals(42, (int) a[i]);
+
+ Integer[] elements = new Integer[SIZE];
+ for (int i = 0; i < SIZE; i++)
+ elements[i] = i;
+ Collections.shuffle(Arrays.asList(elements));
+ Collection<Integer> full = populatedArray(elements);
+
+ Arrays.fill(a, 42);
+ assertTrue(Arrays.equals(elements, full.toArray(a)));
+ for (int i = 0; i < a.length; i++)
+ assertEquals(42, (int) a[i]);
+ assertSame(Integer[].class, full.toArray(a).getClass());
+
+ a = new Integer[SIZE];
+ Arrays.fill(a, 42);
+ assertSame(a, full.toArray(a));
+ assertTrue(Arrays.equals(elements, a));
+
+ a = new Integer[2*SIZE];
+ Arrays.fill(a, 42);
+ assertSame(a, full.toArray(a));
+ assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
+ assertNull(a[SIZE]);
+ for (int i = SIZE + 1; i < a.length; i++)
+ assertEquals(42, (int) a[i]);
+ }
+
+ /**
+ * sublists contains elements at indexes offset from their base
+ */
+ public void testSubList() {
+ CopyOnWriteArrayList a = populatedArray(10);
+ assertTrue(a.subList(1,1).isEmpty());
+ for (int j = 0; j < 9; ++j) {
+ for (int i = j ; i < 10; ++i) {
+ List b = a.subList(j,i);
+ for (int k = j; k < i; ++k) {
+ assertEquals(new Integer(k), b.get(k-j));
+ }
+ }
+ }
+
+ List s = a.subList(2, 5);
+ assertEquals(3, s.size());
+ s.set(2, m1);
+ assertEquals(a.get(4), m1);
+ s.clear();
+ assertEquals(7, a.size());
+ }
+
+ // Exception tests
+
+ /**
+ * toArray throws an ArrayStoreException when the given array
+ * can not store the objects inside the list
+ */
+ public void testToArray_ArrayStoreException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add("zfasdfsdf");
+ c.add("asdadasd");
+ c.toArray(new Long[5]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * get throws an IndexOutOfBoundsException on a negative index
+ */
+ public void testGet1_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.get(-1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * get throws an IndexOutOfBoundsException on a too high index
+ */
+ public void testGet2_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add("asdasd");
+ c.add("asdad");
+ c.get(100);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * set throws an IndexOutOfBoundsException on a negative index
+ */
+ public void testSet1_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.set(-1,"qwerty");
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * set throws an IndexOutOfBoundsException on a too high index
+ */
+ public void testSet2() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add("asdasd");
+ c.add("asdad");
+ c.set(100, "qwerty");
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * add throws an IndexOutOfBoundsException on a negative index
+ */
+ public void testAdd1_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add(-1,"qwerty");
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * add throws an IndexOutOfBoundsException on a too high index
+ */
+ public void testAdd2_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add("asdasd");
+ c.add("asdasdasd");
+ c.add(100, "qwerty");
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * remove throws an IndexOutOfBoundsException on a negative index
+ */
+ public void testRemove1_IndexOutOfBounds() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.remove(-1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * remove throws an IndexOutOfBoundsException on a too high index
+ */
+ public void testRemove2_IndexOutOfBounds() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add("asdasd");
+ c.add("adasdasd");
+ c.remove(100);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * addAll throws an IndexOutOfBoundsException on a negative index
+ */
+ public void testAddAll1_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.addAll(-1,new LinkedList());
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * addAll throws an IndexOutOfBoundsException on a too high index
+ */
+ public void testAddAll2_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add("asdasd");
+ c.add("asdasdasd");
+ c.addAll(100, new LinkedList());
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * listIterator throws an IndexOutOfBoundsException on a negative index
+ */
+ public void testListIterator1_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.listIterator(-1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * listIterator throws an IndexOutOfBoundsException on a too high index
+ */
+ public void testListIterator2_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add("adasd");
+ c.add("asdasdas");
+ c.listIterator(100);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * subList throws an IndexOutOfBoundsException on a negative index
+ */
+ public void testSubList1_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.subList(-1,100);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * subList throws an IndexOutOfBoundsException on a too high index
+ */
+ public void testSubList2_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.add("asdasd");
+ c.subList(1,100);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * subList throws IndexOutOfBoundsException when the second index
+ * is lower then the first
+ */
+ public void testSubList3_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.subList(3,1);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * a deserialized serialized list is equal
+ */
+ public void testSerialization() throws Exception {
+ List x = populatedArray(SIZE);
+ List y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ assertEquals(x, y);
+ assertEquals(y, x);
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(0), y.remove(0));
+ }
+ assertTrue(y.isEmpty());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java
new file mode 100644
index 0000000..feb283f
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java
@@ -0,0 +1,359 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+public class CopyOnWriteArraySetTest extends JSR166TestCase {
+
+ static CopyOnWriteArraySet<Integer> populatedSet(int n) {
+ CopyOnWriteArraySet<Integer> a = new CopyOnWriteArraySet<Integer>();
+ assertTrue(a.isEmpty());
+ for (int i = 0; i < n; i++)
+ a.add(i);
+ assertFalse(a.isEmpty());
+ assertEquals(n, a.size());
+ return a;
+ }
+
+ static CopyOnWriteArraySet populatedSet(Integer[] elements) {
+ CopyOnWriteArraySet<Integer> a = new CopyOnWriteArraySet<Integer>();
+ assertTrue(a.isEmpty());
+ for (int i = 0; i < elements.length; i++)
+ a.add(elements[i]);
+ assertFalse(a.isEmpty());
+ assertEquals(elements.length, a.size());
+ return a;
+ }
+
+ /**
+ * Default-constructed set is empty
+ */
+ public void testConstructor() {
+ CopyOnWriteArraySet a = new CopyOnWriteArraySet();
+ assertTrue(a.isEmpty());
+ }
+
+ /**
+ * Collection-constructed set holds all of its elements
+ */
+ public void testConstructor3() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ CopyOnWriteArraySet a = new CopyOnWriteArraySet(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertTrue(a.contains(ints[i]));
+ }
+
+ /**
+ * addAll adds each element from the given collection
+ */
+ public void testAddAll() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ Vector v = new Vector();
+ v.add(three);
+ v.add(four);
+ v.add(five);
+ full.addAll(v);
+ assertEquals(6, full.size());
+ }
+
+ /**
+ * addAll adds each element from the given collection that did not
+ * already exist in the set
+ */
+ public void testAddAll2() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ Vector v = new Vector();
+ v.add(three);
+ v.add(four);
+ v.add(one); // will not add this element
+ full.addAll(v);
+ assertEquals(5, full.size());
+ }
+
+ /**
+ * add will not add the element if it already exists in the set
+ */
+ public void testAdd2() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ full.add(one);
+ assertEquals(3, full.size());
+ }
+
+ /**
+ * add adds the element when it does not exist in the set
+ */
+ public void testAdd3() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ full.add(three);
+ assertTrue(full.contains(three));
+ }
+
+ /**
+ * clear removes all elements from the set
+ */
+ public void testClear() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ full.clear();
+ assertEquals(0, full.size());
+ }
+
+ /**
+ * contains returns true for added elements
+ */
+ public void testContains() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ assertTrue(full.contains(one));
+ assertFalse(full.contains(five));
+ }
+
+ /**
+ * Sets with equal elements are equal
+ */
+ public void testEquals() {
+ CopyOnWriteArraySet a = populatedSet(3);
+ CopyOnWriteArraySet b = populatedSet(3);
+ assertTrue(a.equals(b));
+ assertTrue(b.equals(a));
+ assertEquals(a.hashCode(), b.hashCode());
+ a.add(m1);
+ assertFalse(a.equals(b));
+ assertFalse(b.equals(a));
+ b.add(m1);
+ assertTrue(a.equals(b));
+ assertTrue(b.equals(a));
+ assertEquals(a.hashCode(), b.hashCode());
+ }
+
+ /**
+ * containsAll returns true for collections with subset of elements
+ */
+ public void testContainsAll() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ Vector v = new Vector();
+ v.add(one);
+ v.add(two);
+ assertTrue(full.containsAll(v));
+ v.add(six);
+ assertFalse(full.containsAll(v));
+ }
+
+ /**
+ * isEmpty is true when empty, else false
+ */
+ public void testIsEmpty() {
+ CopyOnWriteArraySet empty = new CopyOnWriteArraySet();
+ CopyOnWriteArraySet full = populatedSet(3);
+ assertTrue(empty.isEmpty());
+ assertFalse(full.isEmpty());
+ }
+
+ /**
+ * iterator() returns an iterator containing the elements of the
+ * set in insertion order
+ */
+ public void testIterator() {
+ Collection empty = new CopyOnWriteArraySet();
+ assertFalse(empty.iterator().hasNext());
+ try {
+ empty.iterator().next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+
+ Integer[] elements = new Integer[SIZE];
+ for (int i = 0; i < SIZE; i++)
+ elements[i] = i;
+ Collections.shuffle(Arrays.asList(elements));
+ Collection<Integer> full = populatedSet(elements);
+
+ Iterator it = full.iterator();
+ for (int j = 0; j < SIZE; j++) {
+ assertTrue(it.hasNext());
+ assertEquals(elements[j], it.next());
+ }
+ assertFalse(it.hasNext());
+ try {
+ it.next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * iterator remove is unsupported
+ */
+ public void testIteratorRemove() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ Iterator it = full.iterator();
+ it.next();
+ try {
+ it.remove();
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ }
+
+ /**
+ * toString holds toString of elements
+ */
+ public void testToString() {
+ assertEquals("[]", new CopyOnWriteArraySet().toString());
+ CopyOnWriteArraySet full = populatedSet(3);
+ String s = full.toString();
+ for (int i = 0; i < 3; ++i)
+ assertTrue(s.contains(String.valueOf(i)));
+ assertEquals(new ArrayList(full).toString(),
+ full.toString());
+ }
+
+ /**
+ * removeAll removes all elements from the given collection
+ */
+ public void testRemoveAll() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ Vector v = new Vector();
+ v.add(one);
+ v.add(two);
+ full.removeAll(v);
+ assertEquals(1, full.size());
+ }
+
+ /**
+ * remove removes an element
+ */
+ public void testRemove() {
+ CopyOnWriteArraySet full = populatedSet(3);
+ full.remove(one);
+ assertFalse(full.contains(one));
+ assertEquals(2, full.size());
+ }
+
+ /**
+ * size returns the number of elements
+ */
+ public void testSize() {
+ CopyOnWriteArraySet empty = new CopyOnWriteArraySet();
+ CopyOnWriteArraySet full = populatedSet(3);
+ assertEquals(3, full.size());
+ assertEquals(0, empty.size());
+ }
+
+ /**
+ * toArray() returns an Object array containing all elements from
+ * the set in insertion order
+ */
+ public void testToArray() {
+ Object[] a = new CopyOnWriteArraySet().toArray();
+ assertTrue(Arrays.equals(new Object[0], a));
+ assertSame(Object[].class, a.getClass());
+
+ Integer[] elements = new Integer[SIZE];
+ for (int i = 0; i < SIZE; i++)
+ elements[i] = i;
+ Collections.shuffle(Arrays.asList(elements));
+ Collection<Integer> full = populatedSet(elements);
+
+ assertTrue(Arrays.equals(elements, full.toArray()));
+ assertSame(Object[].class, full.toArray().getClass());
+ }
+
+ /**
+ * toArray(Integer array) returns an Integer array containing all
+ * elements from the set in insertion order
+ */
+ public void testToArray2() {
+ Collection empty = new CopyOnWriteArraySet();
+ Integer[] a;
+
+ a = new Integer[0];
+ assertSame(a, empty.toArray(a));
+
+ a = new Integer[SIZE/2];
+ Arrays.fill(a, 42);
+ assertSame(a, empty.toArray(a));
+ assertNull(a[0]);
+ for (int i = 1; i < a.length; i++)
+ assertEquals(42, (int) a[i]);
+
+ Integer[] elements = new Integer[SIZE];
+ for (int i = 0; i < SIZE; i++)
+ elements[i] = i;
+ Collections.shuffle(Arrays.asList(elements));
+ Collection<Integer> full = populatedSet(elements);
+
+ Arrays.fill(a, 42);
+ assertTrue(Arrays.equals(elements, full.toArray(a)));
+ for (int i = 0; i < a.length; i++)
+ assertEquals(42, (int) a[i]);
+ assertSame(Integer[].class, full.toArray(a).getClass());
+
+ a = new Integer[SIZE];
+ Arrays.fill(a, 42);
+ assertSame(a, full.toArray(a));
+ assertTrue(Arrays.equals(elements, a));
+
+ a = new Integer[2*SIZE];
+ Arrays.fill(a, 42);
+ assertSame(a, full.toArray(a));
+ assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
+ assertNull(a[SIZE]);
+ for (int i = SIZE + 1; i < a.length; i++)
+ assertEquals(42, (int) a[i]);
+ }
+
+ /**
+ * toArray throws an ArrayStoreException when the given array can
+ * not store the objects inside the set
+ */
+ public void testToArray_ArrayStoreException() {
+ try {
+ CopyOnWriteArraySet c = new CopyOnWriteArraySet();
+ c.add("zfasdfsdf");
+ c.add("asdadasd");
+ c.toArray(new Long[5]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * A deserialized serialized set is equal
+ */
+ public void testSerialization() throws Exception {
+ Set x = populatedSet(SIZE);
+ Set y = serialClone(x);
+
+ assertNotSame(y, x);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ /**
+ * addAll is idempotent
+ */
+ public void testAddAll_idempotent() throws Exception {
+ Set x = populatedSet(SIZE);
+ Set y = new CopyOnWriteArraySet(x);
+ y.addAll(x);
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java b/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java
new file mode 100644
index 0000000..bc2aecf
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java
@@ -0,0 +1,190 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class CountDownLatchTest extends JSR166TestCase {
+
+ /**
+ * negative constructor argument throws IAE
+ */
+ public void testConstructor() {
+ try {
+ new CountDownLatch(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * getCount returns initial count and decreases after countDown
+ */
+ public void testGetCount() {
+ final CountDownLatch l = new CountDownLatch(2);
+ assertEquals(2, l.getCount());
+ l.countDown();
+ assertEquals(1, l.getCount());
+ }
+
+ /**
+ * countDown decrements count when positive and has no effect when zero
+ */
+ public void testCountDown() {
+ final CountDownLatch l = new CountDownLatch(1);
+ assertEquals(1, l.getCount());
+ l.countDown();
+ assertEquals(0, l.getCount());
+ l.countDown();
+ assertEquals(0, l.getCount());
+ }
+
+ /**
+ * await returns after countDown to zero, but not before
+ */
+ public void testAwait() {
+ final CountDownLatch l = new CountDownLatch(2);
+ final CountDownLatch pleaseCountDown = new CountDownLatch(1);
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertEquals(2, l.getCount());
+ pleaseCountDown.countDown();
+ l.await();
+ assertEquals(0, l.getCount());
+ }});
+
+ await(pleaseCountDown);
+ assertEquals(2, l.getCount());
+ l.countDown();
+ assertEquals(1, l.getCount());
+ assertThreadStaysAlive(t);
+ l.countDown();
+ assertEquals(0, l.getCount());
+ awaitTermination(t);
+ }
+
+ /**
+ * timed await returns after countDown to zero
+ */
+ public void testTimedAwait() {
+ final CountDownLatch l = new CountDownLatch(2);
+ final CountDownLatch pleaseCountDown = new CountDownLatch(1);
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertEquals(2, l.getCount());
+ pleaseCountDown.countDown();
+ assertTrue(l.await(LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(0, l.getCount());
+ }});
+
+ await(pleaseCountDown);
+ assertEquals(2, l.getCount());
+ l.countDown();
+ assertEquals(1, l.getCount());
+ assertThreadStaysAlive(t);
+ l.countDown();
+ assertEquals(0, l.getCount());
+ awaitTermination(t);
+ }
+
+ /**
+ * await throws IE if interrupted before counted down
+ */
+ public void testAwait_Interruptible() {
+ final CountDownLatch l = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ Thread.currentThread().interrupt();
+ try {
+ l.await();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ l.await();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ assertEquals(1, l.getCount());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timed await throws IE if interrupted before counted down
+ */
+ public void testTimedAwait_Interruptible() {
+ final CountDownLatch l = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ Thread.currentThread().interrupt();
+ try {
+ l.await(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ l.await(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ assertEquals(1, l.getCount());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timed await times out if not counted down before timeout
+ */
+ public void testAwaitTimeout() throws InterruptedException {
+ final CountDownLatch l = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertEquals(1, l.getCount());
+ assertFalse(l.await(timeoutMillis(), MILLISECONDS));
+ assertEquals(1, l.getCount());
+ }});
+
+ awaitTermination(t);
+ assertEquals(1, l.getCount());
+ }
+
+ /**
+ * toString indicates current count
+ */
+ public void testToString() {
+ CountDownLatch s = new CountDownLatch(2);
+ assertTrue(s.toString().contains("Count = 2"));
+ s.countDown();
+ assertTrue(s.toString().contains("Count = 1"));
+ s.countDown();
+ assertTrue(s.toString().contains("Count = 0"));
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java b/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java
new file mode 100644
index 0000000..2f8665b
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java
@@ -0,0 +1,1821 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicReference;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import java.util.HashSet;
+import junit.framework.*;
+
+public class CountedCompleterTest extends JSR166TestCase {
+
+ // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
+ static final int mainPoolSize =
+ Math.max(2, Runtime.getRuntime().availableProcessors());
+
+ private static ForkJoinPool mainPool() {
+ return new ForkJoinPool(mainPoolSize);
+ }
+
+ private static ForkJoinPool singletonPool() {
+ return new ForkJoinPool(1);
+ }
+
+ private static ForkJoinPool asyncSingletonPool() {
+ return new ForkJoinPool(1,
+ ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+ null, true);
+ }
+
+ private void testInvokeOnPool(ForkJoinPool pool, ForkJoinTask a) {
+ try {
+ assertFalse(a.isDone());
+ assertFalse(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+
+ assertNull(pool.invoke(a));
+
+ assertTrue(a.isDone());
+ assertTrue(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+ } finally {
+ joinPool(pool);
+ }
+ }
+
+ void checkNotDone(CountedCompleter a) {
+ assertFalse(a.isDone());
+ assertFalse(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+
+ try {
+ a.get(0L, SECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCompletedNormally(CountedCompleter<?> a) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertTrue(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+
+ {
+ Thread.currentThread().interrupt();
+ long t0 = System.nanoTime();
+ assertNull(a.join());
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ Thread.interrupted();
+ }
+
+ {
+ Thread.currentThread().interrupt();
+ long t0 = System.nanoTime();
+ a.quietlyJoin(); // should be no-op
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ Thread.interrupted();
+ }
+
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+ try {
+ assertNull(a.get());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ try {
+ assertNull(a.get(5L, SECONDS));
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCancelled(CountedCompleter a) {
+ assertTrue(a.isDone());
+ assertTrue(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertTrue(a.getException() instanceof CancellationException);
+ assertNull(a.getRawResult());
+ assertTrue(a.cancel(false));
+ assertTrue(a.cancel(true));
+
+ try {
+ Thread.currentThread().interrupt();
+ a.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ Thread.interrupted();
+
+ {
+ long t0 = System.nanoTime();
+ a.quietlyJoin(); // should be no-op
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCompletedAbnormally(CountedCompleter a, Throwable t) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertSame(t.getClass(), a.getException().getClass());
+ assertNull(a.getRawResult());
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+
+ try {
+ Thread.currentThread().interrupt();
+ a.join();
+ shouldThrow();
+ } catch (Throwable expected) {
+ assertSame(t.getClass(), expected.getClass());
+ }
+ Thread.interrupted();
+
+ {
+ long t0 = System.nanoTime();
+ a.quietlyJoin(); // should be no-op
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.invoke();
+ shouldThrow();
+ } catch (Throwable ex) {
+ assertSame(t, ex);
+ }
+ }
+
+ public static final class FJException extends RuntimeException {
+ FJException() { super(); }
+ }
+
+ abstract class CheckedCC extends CountedCompleter<Object> {
+ final AtomicInteger computeN = new AtomicInteger(0);
+ final AtomicInteger onCompletionN = new AtomicInteger(0);
+ final AtomicInteger onExceptionalCompletionN = new AtomicInteger(0);
+ final AtomicInteger setRawResultN = new AtomicInteger(0);
+ final AtomicReference<Object> rawResult = new AtomicReference<Object>(null);
+ int computeN() { return computeN.get(); }
+ int onCompletionN() { return onCompletionN.get(); }
+ int onExceptionalCompletionN() { return onExceptionalCompletionN.get(); }
+ int setRawResultN() { return setRawResultN.get(); }
+
+ CheckedCC() { super(); }
+ CheckedCC(CountedCompleter p) { super(p); }
+ CheckedCC(CountedCompleter p, int n) { super(p, n); }
+ abstract void realCompute();
+ public final void compute() {
+ computeN.incrementAndGet();
+ realCompute();
+ }
+ public void onCompletion(CountedCompleter caller) {
+ onCompletionN.incrementAndGet();
+ super.onCompletion(caller);
+ }
+ public boolean onExceptionalCompletion(Throwable ex,
+ CountedCompleter caller) {
+ onExceptionalCompletionN.incrementAndGet();
+ assertNotNull(ex);
+ assertTrue(isCompletedAbnormally());
+ assertTrue(super.onExceptionalCompletion(ex, caller));
+ return true;
+ }
+ protected void setRawResult(Object t) {
+ setRawResultN.incrementAndGet();
+ rawResult.set(t);
+ super.setRawResult(t);
+ }
+ void checkIncomplete() {
+ assertEquals(0, computeN());
+ assertEquals(0, onCompletionN());
+ assertEquals(0, onExceptionalCompletionN());
+ assertEquals(0, setRawResultN());
+ checkNotDone(this);
+ }
+ void checkCompletes(Object rawResult) {
+ checkIncomplete();
+ int pendingCount = getPendingCount();
+ complete(rawResult);
+ assertEquals(pendingCount, getPendingCount());
+ assertEquals(0, computeN());
+ assertEquals(1, onCompletionN());
+ assertEquals(0, onExceptionalCompletionN());
+ assertEquals(1, setRawResultN());
+ assertSame(rawResult, this.rawResult.get());
+ checkCompletedNormally(this);
+ }
+ void checkCompletesExceptionally(Throwable ex) {
+ checkIncomplete();
+ completeExceptionally(ex);
+ checkCompletedExceptionally(ex);
+ }
+ void checkCompletedExceptionally(Throwable ex) {
+ assertEquals(0, computeN());
+ assertEquals(0, onCompletionN());
+ assertEquals(1, onExceptionalCompletionN());
+ assertEquals(0, setRawResultN());
+ assertNull(this.rawResult.get());
+ checkCompletedAbnormally(this, ex);
+ }
+ }
+
+ final class NoopCC extends CheckedCC {
+ NoopCC() { super(); }
+ NoopCC(CountedCompleter p) { super(p); }
+ protected void realCompute() {}
+ }
+
+ /**
+ * A newly constructed CountedCompleter is not completed;
+ * complete() causes completion. pendingCount is ignored.
+ */
+ public void testComplete() {
+ for (Object x : new Object[] { Boolean.TRUE, null }) {
+ for (int pendingCount : new int[] { 0, 42 }) {
+ testComplete(new NoopCC(), x, pendingCount);
+ testComplete(new NoopCC(new NoopCC()), x, pendingCount);
+ }
+ }
+ }
+ void testComplete(NoopCC cc, Object x, int pendingCount) {
+ cc.setPendingCount(pendingCount);
+ cc.checkCompletes(x);
+ }
+
+ /**
+ * completeExceptionally completes exceptionally
+ */
+ public void testCompleteExceptionally() {
+ new NoopCC()
+ .checkCompletesExceptionally(new FJException());
+ new NoopCC(new NoopCC())
+ .checkCompletesExceptionally(new FJException());
+ }
+
+ /**
+ * completeExceptionally(null) throws NullPointerException
+ */
+ public void testCompleteExceptionally_null() {
+ try {
+ new NoopCC()
+ .checkCompletesExceptionally(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * setPendingCount sets the reported pending count
+ */
+ public void testSetPendingCount() {
+ NoopCC a = new NoopCC();
+ assertEquals(0, a.getPendingCount());
+ a.setPendingCount(1);
+ assertEquals(1, a.getPendingCount());
+ a.setPendingCount(27);
+ assertEquals(27, a.getPendingCount());
+ }
+
+ /**
+ * addToPendingCount adds to the reported pending count
+ */
+ public void testAddToPendingCount() {
+ NoopCC a = new NoopCC();
+ assertEquals(0, a.getPendingCount());
+ a.addToPendingCount(1);
+ assertEquals(1, a.getPendingCount());
+ a.addToPendingCount(27);
+ assertEquals(28, a.getPendingCount());
+ }
+
+ /**
+ * decrementPendingCountUnlessZero decrements reported pending
+ * count unless zero
+ */
+ public void testDecrementPendingCount() {
+ NoopCC a = new NoopCC();
+ assertEquals(0, a.getPendingCount());
+ a.addToPendingCount(1);
+ assertEquals(1, a.getPendingCount());
+ a.decrementPendingCountUnlessZero();
+ assertEquals(0, a.getPendingCount());
+ a.decrementPendingCountUnlessZero();
+ assertEquals(0, a.getPendingCount());
+ }
+
+ /**
+ * compareAndSetPendingCount compares and sets the reported
+ * pending count
+ */
+ public void testCompareAndSetPendingCount() {
+ NoopCC a = new NoopCC();
+ assertEquals(0, a.getPendingCount());
+ assertTrue(a.compareAndSetPendingCount(0, 1));
+ assertEquals(1, a.getPendingCount());
+ assertTrue(a.compareAndSetPendingCount(1, 2));
+ assertEquals(2, a.getPendingCount());
+ assertFalse(a.compareAndSetPendingCount(1, 3));
+ assertEquals(2, a.getPendingCount());
+ }
+
+ /**
+ * getCompleter returns parent or null if at root
+ */
+ public void testGetCompleter() {
+ NoopCC a = new NoopCC();
+ assertNull(a.getCompleter());
+ CountedCompleter b = new NoopCC(a);
+ assertSame(a, b.getCompleter());
+ CountedCompleter c = new NoopCC(b);
+ assertSame(b, c.getCompleter());
+ }
+
+ /**
+ * getRoot returns self if no parent, else parent's root
+ */
+ public void testGetRoot() {
+ NoopCC a = new NoopCC();
+ NoopCC b = new NoopCC(a);
+ NoopCC c = new NoopCC(b);
+ assertSame(a, a.getRoot());
+ assertSame(a, b.getRoot());
+ assertSame(a, c.getRoot());
+ }
+
+ /**
+ * tryComplete decrements pending count unless zero, in which case
+ * causes completion
+ */
+ public void testTryComplete() {
+ NoopCC a = new NoopCC();
+ assertEquals(0, a.getPendingCount());
+ int n = 3;
+ a.setPendingCount(n);
+ for (; n > 0; n--) {
+ assertEquals(n, a.getPendingCount());
+ a.tryComplete();
+ a.checkIncomplete();
+ assertEquals(n - 1, a.getPendingCount());
+ }
+ a.tryComplete();
+ assertEquals(0, a.computeN());
+ assertEquals(1, a.onCompletionN());
+ assertEquals(0, a.onExceptionalCompletionN());
+ assertEquals(0, a.setRawResultN());
+ checkCompletedNormally(a);
+ }
+
+ /**
+ * propagateCompletion decrements pending count unless zero, in
+ * which case causes completion, without invoking onCompletion
+ */
+ public void testPropagateCompletion() {
+ NoopCC a = new NoopCC();
+ assertEquals(0, a.getPendingCount());
+ int n = 3;
+ a.setPendingCount(n);
+ for (; n > 0; n--) {
+ assertEquals(n, a.getPendingCount());
+ a.propagateCompletion();
+ a.checkIncomplete();
+ assertEquals(n - 1, a.getPendingCount());
+ }
+ a.propagateCompletion();
+ assertEquals(0, a.computeN());
+ assertEquals(0, a.onCompletionN());
+ assertEquals(0, a.onExceptionalCompletionN());
+ assertEquals(0, a.setRawResultN());
+ checkCompletedNormally(a);
+ }
+
+ /**
+ * firstComplete returns this if pending count is zero else null
+ */
+ public void testFirstComplete() {
+ NoopCC a = new NoopCC();
+ a.setPendingCount(1);
+ assertNull(a.firstComplete());
+ a.checkIncomplete();
+ assertSame(a, a.firstComplete());
+ a.checkIncomplete();
+ }
+
+ /**
+ * firstComplete.nextComplete returns parent if pending count is
+ * zero else null
+ */
+ public void testNextComplete() {
+ NoopCC a = new NoopCC();
+ NoopCC b = new NoopCC(a);
+ a.setPendingCount(1);
+ b.setPendingCount(1);
+ assertNull(b.firstComplete());
+ assertSame(b, b.firstComplete());
+ assertNull(b.nextComplete());
+ a.checkIncomplete();
+ b.checkIncomplete();
+ assertSame(a, b.nextComplete());
+ assertSame(a, b.nextComplete());
+ a.checkIncomplete();
+ b.checkIncomplete();
+ assertNull(a.nextComplete());
+ b.checkIncomplete();
+ checkCompletedNormally(a);
+ }
+
+ /**
+ * quietlyCompleteRoot completes root task
+ */
+ public void testQuietlyCompleteRoot() {
+ NoopCC a = new NoopCC();
+ NoopCC b = new NoopCC(a);
+ NoopCC c = new NoopCC(b);
+ a.setPendingCount(1);
+ b.setPendingCount(1);
+ c.setPendingCount(1);
+ c.quietlyCompleteRoot();
+ assertTrue(a.isDone());
+ assertFalse(b.isDone());
+ assertFalse(c.isDone());
+ }
+
+ // Invocation tests use some interdependent task classes
+ // to better test propagation etc
+
+
+ // Version of Fibonacci with different classes for left vs right forks
+ abstract class CCF extends CheckedCC {
+ int number;
+ int rnumber;
+
+ public CCF(CountedCompleter parent, int n) {
+ super(parent, 1);
+ this.number = n;
+ }
+
+ protected final void realCompute() {
+ CCF f = this;
+ int n = number;
+ while (n >= 2) {
+ new RCCF(f, n - 2).fork();
+ f = new LCCF(f, --n);
+ }
+ f.complete(null);
+ }
+ }
+
+ final class LCCF extends CCF {
+ public LCCF(int n) { this(null, n); }
+ public LCCF(CountedCompleter parent, int n) {
+ super(parent, n);
+ }
+ public final void onCompletion(CountedCompleter caller) {
+ super.onCompletion(caller);
+ CCF p = (CCF)getCompleter();
+ int n = number + rnumber;
+ if (p != null)
+ p.number = n;
+ else
+ number = n;
+ }
+ }
+ final class RCCF extends CCF {
+ public RCCF(CountedCompleter parent, int n) {
+ super(parent, n);
+ }
+ public final void onCompletion(CountedCompleter caller) {
+ super.onCompletion(caller);
+ CCF p = (CCF)getCompleter();
+ int n = number + rnumber;
+ if (p != null)
+ p.rnumber = n;
+ else
+ number = n;
+ }
+ }
+
+ // Version of CCF with forced failure in left completions
+ abstract class FailingCCF extends CheckedCC {
+ int number;
+ int rnumber;
+
+ public FailingCCF(CountedCompleter parent, int n) {
+ super(parent, 1);
+ this.number = n;
+ }
+
+ protected final void realCompute() {
+ FailingCCF f = this;
+ int n = number;
+ while (n >= 2) {
+ new RFCCF(f, n - 2).fork();
+ f = new LFCCF(f, --n);
+ }
+ f.complete(null);
+ }
+ }
+
+ final class LFCCF extends FailingCCF {
+ public LFCCF(int n) { this(null, n); }
+ public LFCCF(CountedCompleter parent, int n) {
+ super(parent, n);
+ }
+ public final void onCompletion(CountedCompleter caller) {
+ super.onCompletion(caller);
+ FailingCCF p = (FailingCCF)getCompleter();
+ int n = number + rnumber;
+ if (p != null)
+ p.number = n;
+ else
+ number = n;
+ }
+ }
+ final class RFCCF extends FailingCCF {
+ public RFCCF(CountedCompleter parent, int n) {
+ super(parent, n);
+ }
+ public final void onCompletion(CountedCompleter caller) {
+ super.onCompletion(caller);
+ completeExceptionally(new FJException());
+ }
+ }
+
+ /**
+ * invoke returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks; getRawResult returns null.
+ */
+ public void testInvoke() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertNull(f.invoke());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks
+ */
+ public void testQuietlyInvoke() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ f.quietlyInvoke();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task returns when task completes
+ */
+ public void testForkJoin() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertNull(f.join());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * get of a forked task returns when task completes
+ */
+ public void testForkGet() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertNull(f.get());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task returns when task completes
+ */
+ public void testForkTimedGet() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get with null time unit throws NPE
+ */
+ public void testForkTimedGetNPE() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(5L, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes
+ */
+ public void testForkQuietlyJoin() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * helpQuiesce returns when tasks are complete.
+ * getQueuedTaskCount returns 0 when quiescent
+ */
+ public void testForkHelpQuiesce() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ helpQuiesce();
+ assertEquals(21, f.number);
+ assertEquals(0, getQueuedTaskCount());
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task completes abnormally
+ */
+ public void testAbnormalInvoke() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes abnormally
+ */
+ public void testAbnormalQuietlyInvoke() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ f.quietlyInvoke();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkJoin() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkGet() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingCCF f = new LFCCF(8);
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkTimedGet() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingCCF f = new LFCCF(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes abnormally
+ */
+ public void testAbnormalForkQuietlyJoin() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task cancelled
+ */
+ public void testCancelledInvoke() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkJoin() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkGet() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkTimedGet() throws Exception {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task cancelled
+ */
+ public void testCancelledForkQuietlyJoin() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ checkCancelled(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * getPool of executing task returns its pool
+ */
+ public void testGetPool() {
+ final ForkJoinPool mainPool = mainPool();
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertSame(mainPool, getPool());
+ }};
+ testInvokeOnPool(mainPool, a);
+ }
+
+ /**
+ * getPool of non-FJ task returns null
+ */
+ public void testGetPool2() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertNull(getPool());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * inForkJoinPool of executing task returns true
+ */
+ public void testInForkJoinPool() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertTrue(inForkJoinPool());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * inForkJoinPool of non-FJ task returns false
+ */
+ public void testInForkJoinPool2() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertFalse(inForkJoinPool());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * setRawResult(null) succeeds
+ */
+ public void testSetRawResult() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ setRawResult(null);
+ assertNull(getRawResult());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * invoke task throws exception after invoking completeExceptionally
+ */
+ public void testCompleteExceptionally2() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF n = new LCCF(8);
+ CCF f = new LCCF(n, 8);
+ FJException ex = new FJException();
+ f.completeExceptionally(ex);
+ f.checkCompletedExceptionally(ex);
+ n.checkCompletedExceptionally(ex);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) invokes all task arguments
+ */
+ public void testInvokeAll2() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ CCF g = new LCCF(9);
+ invokeAll(f, g);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument invokes task
+ */
+ public void testInvokeAll1() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ invokeAll(f);
+ checkCompletedNormally(f);
+ assertEquals(21, f.number);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument invokes tasks
+ */
+ public void testInvokeAll3() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ CCF g = new LCCF(9);
+ CCF h = new LCCF(7);
+ invokeAll(f, g, h);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ assertEquals(13, h.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) invokes all tasks in the collection
+ */
+ public void testInvokeAllCollection() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ CCF g = new LCCF(9);
+ CCF h = new LCCF(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ invokeAll(set);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ assertEquals(13, h.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with any null task throws NPE
+ */
+ public void testInvokeAllNPE() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ CCF g = new LCCF(9);
+ CCF h = null;
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) throw exception if any task does
+ */
+ public void testAbnormalInvokeAll2() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ FailingCCF g = new LFCCF(9);
+ try {
+ invokeAll(f, g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument throws exception if task does
+ */
+ public void testAbnormalInvokeAll1() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF g = new LFCCF(9);
+ try {
+ invokeAll(g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument throws exception if any task does
+ */
+ public void testAbnormalInvokeAll3() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ FailingCCF g = new LFCCF(9);
+ CCF h = new LCCF(7);
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) throws exception if any task does
+ */
+ public void testAbnormalInvokeAllCollection() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ CCF g = new LCCF(9);
+ CCF h = new LCCF(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ try {
+ invokeAll(set);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * tryUnfork returns true for most recent unexecuted task,
+ * and suppresses execution
+ */
+ public void testTryUnfork() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF g = new LCCF(9);
+ assertSame(g, g.fork());
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertTrue(f.tryUnfork());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * getSurplusQueuedTaskCount returns > 0 when
+ * there are more tasks than threads
+ */
+ public void testGetSurplusQueuedTaskCount() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF h = new LCCF(7);
+ assertSame(h, h.fork());
+ CCF g = new LCCF(9);
+ assertSame(g, g.fork());
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertTrue(getSurplusQueuedTaskCount() > 0);
+ helpQuiesce();
+ assertEquals(0, getSurplusQueuedTaskCount());
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * peekNextLocalTask returns most recent unexecuted task.
+ */
+ public void testPeekNextLocalTask() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF g = new LCCF(9);
+ assertSame(g, g.fork());
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertSame(f, peekNextLocalTask());
+ assertNull(f.join());
+ checkCompletedNormally(f);
+ helpQuiesce();
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * pollNextLocalTask returns most recent unexecuted task without
+ * executing it
+ */
+ public void testPollNextLocalTask() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF g = new LCCF(9);
+ assertSame(g, g.fork());
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollNextLocalTask());
+ helpQuiesce();
+ checkNotDone(f);
+ assertEquals(34, g.number);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it
+ */
+ public void testPollTask() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF g = new LCCF(9);
+ assertSame(g, g.fork());
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollTask());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * peekNextLocalTask returns least recent unexecuted task in async mode
+ */
+ public void testPeekNextLocalTaskAsync() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF g = new LCCF(9);
+ assertSame(g, g.fork());
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertSame(g, peekNextLocalTask());
+ assertNull(f.join());
+ helpQuiesce();
+ checkCompletedNormally(f);
+ assertEquals(34, g.number);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ /**
+ * pollNextLocalTask returns least recent unexecuted task without
+ * executing it, in async mode
+ */
+ public void testPollNextLocalTaskAsync() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF g = new LCCF(9);
+ assertSame(g, g.fork());
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollNextLocalTask());
+ helpQuiesce();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ checkNotDone(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it, in
+ * async mode
+ */
+ public void testPollTaskAsync() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF g = new LCCF(9);
+ assertSame(g, g.fork());
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollTask());
+ helpQuiesce();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ checkNotDone(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ // versions for singleton pools
+
+ /**
+ * invoke returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks; getRawResult returns null.
+ */
+ public void testInvokeSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertNull(f.invoke());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks
+ */
+ public void testQuietlyInvokeSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ f.quietlyInvoke();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * join of a forked task returns when task completes
+ */
+ public void testForkJoinSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertNull(f.join());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * get of a forked task returns when task completes
+ */
+ public void testForkGetSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertNull(f.get());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * timed get of a forked task returns when task completes
+ */
+ public void testForkTimedGetSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * timed get with null time unit throws NPE
+ */
+ public void testForkTimedGetNPESingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(5L, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes
+ */
+ public void testForkQuietlyJoinSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * helpQuiesce returns when tasks are complete.
+ * getQueuedTaskCount returns 0 when quiescent
+ */
+ public void testForkHelpQuiesceSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertSame(f, f.fork());
+ helpQuiesce();
+ assertEquals(0, getQueuedTaskCount());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task completes abnormally
+ */
+ public void testAbnormalInvokeSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes abnormally
+ */
+ public void testAbnormalQuietlyInvokeSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ f.quietlyInvoke();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkJoinSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkGetSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingCCF f = new LFCCF(8);
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkTimedGetSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingCCF f = new LFCCF(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes abnormally
+ */
+ public void testAbnormalForkQuietlyJoinSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task cancelled
+ */
+ public void testCancelledInvokeSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkJoinSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkGetSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkTimedGetSingleton() throws Exception {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task cancelled
+ */
+ public void testCancelledForkQuietlyJoinSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ checkCancelled(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invoke task throws exception after invoking completeExceptionally
+ */
+ public void testCompleteExceptionallySingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF n = new LCCF(8);
+ CCF f = new LCCF(n, 8);
+ FJException ex = new FJException();
+ f.completeExceptionally(ex);
+ f.checkCompletedExceptionally(ex);
+ n.checkCompletedExceptionally(ex);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) invokes all task arguments
+ */
+ public void testInvokeAll2Singleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ CCF g = new LCCF(9);
+ invokeAll(f, g);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument invokes task
+ */
+ public void testInvokeAll1Singleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ invokeAll(f);
+ checkCompletedNormally(f);
+ assertEquals(21, f.number);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument invokes tasks
+ */
+ public void testInvokeAll3Singleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ CCF g = new LCCF(9);
+ CCF h = new LCCF(7);
+ invokeAll(f, g, h);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ assertEquals(13, h.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) invokes all tasks in the collection
+ */
+ public void testInvokeAllCollectionSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ CCF g = new LCCF(9);
+ CCF h = new LCCF(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ invokeAll(set);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ assertEquals(13, h.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with any null task throws NPE
+ */
+ public void testInvokeAllNPESingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ CCF g = new LCCF(9);
+ CCF h = null;
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) throw exception if any task does
+ */
+ public void testAbnormalInvokeAll2Singleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ FailingCCF g = new LFCCF(9);
+ try {
+ invokeAll(f, g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument throws exception if task does
+ */
+ public void testAbnormalInvokeAll1Singleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF g = new LFCCF(9);
+ try {
+ invokeAll(g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument throws exception if any task does
+ */
+ public void testAbnormalInvokeAll3Singleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ CCF f = new LCCF(8);
+ FailingCCF g = new LFCCF(9);
+ CCF h = new LCCF(7);
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) throws exception if any task does
+ */
+ public void testAbnormalInvokeAllCollectionSingleton() {
+ ForkJoinTask a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingCCF f = new LFCCF(8);
+ CCF g = new LCCF(9);
+ CCF h = new LCCF(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ try {
+ invokeAll(set);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java b/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java
new file mode 100644
index 0000000..3239030
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java
@@ -0,0 +1,458 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class CyclicBarrierTest extends JSR166TestCase {
+
+ private volatile int countAction;
+ private class MyAction implements Runnable {
+ public void run() { ++countAction; }
+ }
+
+ /**
+ * Spin-waits till the number of waiters == numberOfWaiters.
+ */
+ void awaitNumberWaiting(CyclicBarrier barrier, int numberOfWaiters) {
+ long startTime = System.nanoTime();
+ while (barrier.getNumberWaiting() != numberOfWaiters) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ }
+
+ /**
+ * Creating with negative parties throws IAE
+ */
+ public void testConstructor1() {
+ try {
+ new CyclicBarrier(-1, (Runnable)null);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Creating with negative parties and no action throws IAE
+ */
+ public void testConstructor2() {
+ try {
+ new CyclicBarrier(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * getParties returns the number of parties given in constructor
+ */
+ public void testGetParties() {
+ CyclicBarrier b = new CyclicBarrier(2);
+ assertEquals(2, b.getParties());
+ assertEquals(0, b.getNumberWaiting());
+ }
+
+ /**
+ * A 1-party barrier triggers after single await
+ */
+ public void testSingleParty() throws Exception {
+ CyclicBarrier b = new CyclicBarrier(1);
+ assertEquals(1, b.getParties());
+ assertEquals(0, b.getNumberWaiting());
+ b.await();
+ b.await();
+ assertEquals(0, b.getNumberWaiting());
+ }
+
+ /**
+ * The supplied barrier action is run at barrier
+ */
+ public void testBarrierAction() throws Exception {
+ countAction = 0;
+ CyclicBarrier b = new CyclicBarrier(1, new MyAction());
+ assertEquals(1, b.getParties());
+ assertEquals(0, b.getNumberWaiting());
+ b.await();
+ b.await();
+ assertEquals(0, b.getNumberWaiting());
+ assertEquals(2, countAction);
+ }
+
+ /**
+ * A 2-party/thread barrier triggers after both threads invoke await
+ */
+ public void testTwoParties() throws Exception {
+ final CyclicBarrier b = new CyclicBarrier(2);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ b.await();
+ b.await();
+ b.await();
+ b.await();
+ }});
+
+ b.await();
+ b.await();
+ b.await();
+ b.await();
+ awaitTermination(t);
+ }
+
+ /**
+ * An interruption in one party causes others waiting in await to
+ * throw BrokenBarrierException
+ */
+ public void testAwait1_Interrupted_BrokenBarrier() {
+ final CyclicBarrier c = new CyclicBarrier(3);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+ Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+ public void realRun() throws Exception {
+ pleaseInterrupt.countDown();
+ c.await();
+ }};
+ Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+ public void realRun() throws Exception {
+ pleaseInterrupt.countDown();
+ c.await();
+ }};
+
+ t1.start();
+ t2.start();
+ await(pleaseInterrupt);
+ t1.interrupt();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * An interruption in one party causes others waiting in timed await to
+ * throw BrokenBarrierException
+ */
+ public void testAwait2_Interrupted_BrokenBarrier() throws Exception {
+ final CyclicBarrier c = new CyclicBarrier(3);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+ Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+ public void realRun() throws Exception {
+ pleaseInterrupt.countDown();
+ c.await(LONG_DELAY_MS, MILLISECONDS);
+ }};
+ Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+ public void realRun() throws Exception {
+ pleaseInterrupt.countDown();
+ c.await(LONG_DELAY_MS, MILLISECONDS);
+ }};
+
+ t1.start();
+ t2.start();
+ await(pleaseInterrupt);
+ t1.interrupt();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * A timeout in timed await throws TimeoutException
+ */
+ public void testAwait3_TimeoutException() throws InterruptedException {
+ final CyclicBarrier c = new CyclicBarrier(2);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ long startTime = System.nanoTime();
+ try {
+ c.await(timeoutMillis(), MILLISECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {}
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * A timeout in one party causes others waiting in timed await to
+ * throw BrokenBarrierException
+ */
+ public void testAwait4_Timeout_BrokenBarrier() throws InterruptedException {
+ final CyclicBarrier c = new CyclicBarrier(3);
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ try {
+ c.await(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (BrokenBarrierException success) {}
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ awaitNumberWaiting(c, 1);
+ long startTime = System.nanoTime();
+ try {
+ c.await(timeoutMillis(), MILLISECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {}
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }});
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * A timeout in one party causes others waiting in await to
+ * throw BrokenBarrierException
+ */
+ public void testAwait5_Timeout_BrokenBarrier() throws InterruptedException {
+ final CyclicBarrier c = new CyclicBarrier(3);
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ try {
+ c.await();
+ shouldThrow();
+ } catch (BrokenBarrierException success) {}
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ awaitNumberWaiting(c, 1);
+ long startTime = System.nanoTime();
+ try {
+ c.await(timeoutMillis(), MILLISECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {}
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }});
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * A reset of an active barrier causes waiting threads to throw
+ * BrokenBarrierException
+ */
+ public void testReset_BrokenBarrier() throws InterruptedException {
+ final CyclicBarrier c = new CyclicBarrier(3);
+ final CountDownLatch pleaseReset = new CountDownLatch(2);
+ Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
+ public void realRun() throws Exception {
+ pleaseReset.countDown();
+ c.await();
+ }};
+ Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+ public void realRun() throws Exception {
+ pleaseReset.countDown();
+ c.await();
+ }};
+
+ t1.start();
+ t2.start();
+ await(pleaseReset);
+
+ awaitNumberWaiting(c, 2);
+ c.reset();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * A reset before threads enter barrier does not throw
+ * BrokenBarrierException
+ */
+ public void testReset_NoBrokenBarrier() throws Exception {
+ final CyclicBarrier c = new CyclicBarrier(3);
+ c.reset();
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ c.await();
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ c.await();
+ }});
+
+ c.await();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * All threads block while a barrier is broken.
+ */
+ public void testReset_Leakage() throws InterruptedException {
+ final CyclicBarrier c = new CyclicBarrier(2);
+ final AtomicBoolean done = new AtomicBoolean();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ while (!done.get()) {
+ try {
+ while (c.isBroken())
+ c.reset();
+
+ c.await();
+ shouldThrow();
+ }
+ catch (BrokenBarrierException ok) {}
+ catch (InterruptedException ok) {}
+ }}});
+
+ for (int i = 0; i < 4; i++) {
+ delay(timeoutMillis());
+ t.interrupt();
+ }
+ done.set(true);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * Reset of a non-broken barrier does not break barrier
+ */
+ public void testResetWithoutBreakage() throws Exception {
+ final CyclicBarrier barrier = new CyclicBarrier(3);
+ for (int i = 0; i < 3; i++) {
+ final CyclicBarrier start = new CyclicBarrier(3);
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ start.await();
+ barrier.await();
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ start.await();
+ barrier.await();
+ }});
+
+ start.await();
+ barrier.await();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertFalse(barrier.isBroken());
+ assertEquals(0, barrier.getNumberWaiting());
+ if (i == 1) barrier.reset();
+ assertFalse(barrier.isBroken());
+ assertEquals(0, barrier.getNumberWaiting());
+ }
+ }
+
+ /**
+ * Reset of a barrier after interruption reinitializes it.
+ */
+ public void testResetAfterInterrupt() throws Exception {
+ final CyclicBarrier barrier = new CyclicBarrier(3);
+ for (int i = 0; i < 2; i++) {
+ final CyclicBarrier start = new CyclicBarrier(3);
+ Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+ public void realRun() throws Exception {
+ start.await();
+ barrier.await();
+ }};
+
+ Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+ public void realRun() throws Exception {
+ start.await();
+ barrier.await();
+ }};
+
+ t1.start();
+ t2.start();
+ start.await();
+ t1.interrupt();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertTrue(barrier.isBroken());
+ assertEquals(0, barrier.getNumberWaiting());
+ barrier.reset();
+ assertFalse(barrier.isBroken());
+ assertEquals(0, barrier.getNumberWaiting());
+ }
+ }
+
+ /**
+ * Reset of a barrier after timeout reinitializes it.
+ */
+ public void testResetAfterTimeout() throws Exception {
+ final CyclicBarrier barrier = new CyclicBarrier(3);
+ for (int i = 0; i < 2; i++) {
+ assertEquals(0, barrier.getNumberWaiting());
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ try {
+ barrier.await();
+ shouldThrow();
+ } catch (BrokenBarrierException success) {}
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ awaitNumberWaiting(barrier, 1);
+ long startTime = System.nanoTime();
+ try {
+ barrier.await(timeoutMillis(), MILLISECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {}
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }});
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertEquals(0, barrier.getNumberWaiting());
+ assertTrue(barrier.isBroken());
+ assertEquals(0, barrier.getNumberWaiting());
+ barrier.reset();
+ assertFalse(barrier.isBroken());
+ assertEquals(0, barrier.getNumberWaiting());
+ }
+ }
+
+ /**
+ * Reset of a barrier after a failed command reinitializes it.
+ */
+ public void testResetAfterCommandException() throws Exception {
+ final CyclicBarrier barrier =
+ new CyclicBarrier(3, new Runnable() {
+ public void run() {
+ throw new NullPointerException(); }});
+ for (int i = 0; i < 2; i++) {
+ final CyclicBarrier start = new CyclicBarrier(3);
+ Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
+ public void realRun() throws Exception {
+ start.await();
+ barrier.await();
+ }};
+
+ Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+ public void realRun() throws Exception {
+ start.await();
+ barrier.await();
+ }};
+
+ t1.start();
+ t2.start();
+ start.await();
+ awaitNumberWaiting(barrier, 2);
+ try {
+ barrier.await();
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertTrue(barrier.isBroken());
+ assertEquals(0, barrier.getNumberWaiting());
+ barrier.reset();
+ assertFalse(barrier.isBroken());
+ assertEquals(0, barrier.getNumberWaiting());
+ }
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java b/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java
new file mode 100644
index 0000000..dc221ab
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java
@@ -0,0 +1,766 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class DelayQueueTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new DelayQueue();
+ }
+
+ protected PDelay makeElement(int i) {
+ return new PDelay(i);
+ }
+
+ private static final int NOCAP = Integer.MAX_VALUE;
+
+ /**
+ * A delayed implementation for testing.
+ * Most tests use Pseudodelays, where delays are all elapsed
+ * (so, no blocking solely for delays) but are still ordered
+ */
+ static class PDelay implements Delayed {
+ int pseudodelay;
+ PDelay(int i) { pseudodelay = i; }
+ public int compareTo(PDelay other) {
+ int a = this.pseudodelay;
+ int b = other.pseudodelay;
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
+ }
+ public int compareTo(Delayed y) {
+ return compareTo((PDelay)y);
+ }
+ public boolean equals(Object other) {
+ return (other instanceof PDelay) &&
+ this.pseudodelay == ((PDelay)other).pseudodelay;
+ }
+ // suppress [overrides] javac warning
+ public int hashCode() { return pseudodelay; }
+ public long getDelay(TimeUnit ignore) {
+ return Integer.MIN_VALUE + pseudodelay;
+ }
+ public String toString() {
+ return String.valueOf(pseudodelay);
+ }
+ }
+
+ /**
+ * Delayed implementation that actually delays
+ */
+ static class NanoDelay implements Delayed {
+ long trigger;
+ NanoDelay(long i) {
+ trigger = System.nanoTime() + i;
+ }
+ public int compareTo(NanoDelay y) {
+ long i = trigger;
+ long j = y.trigger;
+ if (i < j) return -1;
+ if (i > j) return 1;
+ return 0;
+ }
+
+ public int compareTo(Delayed y) {
+ return compareTo((NanoDelay)y);
+ }
+
+ public boolean equals(Object other) {
+ return equals((NanoDelay)other);
+ }
+ public boolean equals(NanoDelay other) {
+ return other.trigger == trigger;
+ }
+
+ // suppress [overrides] javac warning
+ public int hashCode() { return (int) trigger; }
+
+ public long getDelay(TimeUnit unit) {
+ long n = trigger - System.nanoTime();
+ return unit.convert(n, TimeUnit.NANOSECONDS);
+ }
+
+ public long getTriggerTime() {
+ return trigger;
+ }
+
+ public String toString() {
+ return String.valueOf(trigger);
+ }
+ }
+
+ /**
+ * Returns a new queue of given size containing consecutive
+ * PDelays 0 ... n.
+ */
+ private DelayQueue<PDelay> populatedQueue(int n) {
+ DelayQueue<PDelay> q = new DelayQueue<PDelay>();
+ assertTrue(q.isEmpty());
+ for (int i = n-1; i >= 0; i-=2)
+ assertTrue(q.offer(new PDelay(i)));
+ for (int i = (n & 1); i < n; i+=2)
+ assertTrue(q.offer(new PDelay(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(NOCAP, q.remainingCapacity());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * A new queue has unbounded capacity
+ */
+ public void testConstructor1() {
+ assertEquals(NOCAP, new DelayQueue().remainingCapacity());
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ DelayQueue q = new DelayQueue(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ try {
+ PDelay[] ints = new PDelay[SIZE];
+ DelayQueue q = new DelayQueue(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ try {
+ PDelay[] ints = new PDelay[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new PDelay(i);
+ DelayQueue q = new DelayQueue(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ PDelay[] ints = new PDelay[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new PDelay(i);
+ DelayQueue q = new DelayQueue(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ DelayQueue q = new DelayQueue();
+ assertTrue(q.isEmpty());
+ assertEquals(NOCAP, q.remainingCapacity());
+ q.add(new PDelay(1));
+ assertFalse(q.isEmpty());
+ q.add(new PDelay(2));
+ q.remove();
+ q.remove();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * remainingCapacity does not change when elements added or removed,
+ * but size does
+ */
+ public void testRemainingCapacity() {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(NOCAP, q.remainingCapacity());
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(NOCAP, q.remainingCapacity());
+ assertEquals(i, q.size());
+ q.add(new PDelay(i));
+ }
+ }
+
+ /**
+ * offer non-null succeeds
+ */
+ public void testOffer() {
+ DelayQueue q = new DelayQueue();
+ assertTrue(q.offer(new PDelay(0)));
+ assertTrue(q.offer(new PDelay(1)));
+ }
+
+ /**
+ * add succeeds
+ */
+ public void testAdd() {
+ DelayQueue q = new DelayQueue();
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ assertTrue(q.add(new PDelay(i)));
+ }
+ }
+
+ /**
+ * addAll(this) throws IAE
+ */
+ public void testAddAllSelf() {
+ try {
+ DelayQueue q = populatedQueue(SIZE);
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ DelayQueue q = new DelayQueue();
+ PDelay[] ints = new PDelay[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new PDelay(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of successful addAll
+ */
+ public void testAddAll5() {
+ PDelay[] empty = new PDelay[0];
+ PDelay[] ints = new PDelay[SIZE];
+ for (int i = SIZE-1; i >= 0; --i)
+ ints[i] = new PDelay(i);
+ DelayQueue q = new DelayQueue();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * all elements successfully put are contained
+ */
+ public void testPut() {
+ DelayQueue q = new DelayQueue();
+ for (int i = 0; i < SIZE; ++i) {
+ PDelay I = new PDelay(i);
+ q.put(I);
+ assertTrue(q.contains(I));
+ }
+ assertEquals(SIZE, q.size());
+ }
+
+ /**
+ * put doesn't block waiting for take
+ */
+ public void testPutWithTake() throws InterruptedException {
+ final DelayQueue q = new DelayQueue();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ q.put(new PDelay(0));
+ q.put(new PDelay(0));
+ q.put(new PDelay(0));
+ q.put(new PDelay(0));
+ }});
+
+ awaitTermination(t);
+ assertEquals(4, q.size());
+ }
+
+ /**
+ * timed offer does not time out
+ */
+ public void testTimedOffer() throws InterruptedException {
+ final DelayQueue q = new DelayQueue();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(new PDelay(0));
+ q.put(new PDelay(0));
+ assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, MILLISECONDS));
+ assertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, MILLISECONDS));
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * take retrieves elements in priority order
+ */
+ public void testTake() throws InterruptedException {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(new PDelay(i), ((PDelay)q.take()));
+ }
+ }
+
+ /**
+ * Take removes existing elements until empty, then blocks interruptibly
+ */
+ public void testBlockingTake() throws InterruptedException {
+ final DelayQueue q = populatedQueue(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(new PDelay(i), ((PDelay)q.take()));
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(new PDelay(i), ((PDelay)q.poll()));
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * timed poll with zero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll0() throws InterruptedException {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(new PDelay(i), ((PDelay)q.poll(0, MILLISECONDS)));
+ }
+ assertNull(q.poll(0, MILLISECONDS));
+ }
+
+ /**
+ * timed poll with nonzero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll() throws InterruptedException {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ long startTime = System.nanoTime();
+ assertEquals(new PDelay(i), ((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS)));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ checkEmpty(q);
+ }
+
+ /**
+ * Interrupted timed poll throws InterruptedException instead of
+ * returning timeout status
+ */
+ public void testInterruptedTimedPoll() throws InterruptedException {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS)));
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(new PDelay(i), ((PDelay)q.peek()));
+ assertEquals(new PDelay(i), ((PDelay)q.poll()));
+ if (q.isEmpty())
+ assertNull(q.peek());
+ else
+ assertFalse(new PDelay(i).equals(q.peek()));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * element returns next element, or throws NSEE if empty
+ */
+ public void testElement() {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(new PDelay(i), ((PDelay)q.element()));
+ q.poll();
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(new PDelay(i), ((PDelay)q.remove()));
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ DelayQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new PDelay(i)));
+ q.poll();
+ assertFalse(q.contains(new PDelay(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ DelayQueue q = populatedQueue(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertEquals(NOCAP, q.remainingCapacity());
+ PDelay x = new PDelay(1);
+ q.add(x);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(x));
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ DelayQueue q = populatedQueue(SIZE);
+ DelayQueue p = new DelayQueue();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new PDelay(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ DelayQueue q = populatedQueue(SIZE);
+ DelayQueue p = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ DelayQueue q = populatedQueue(SIZE);
+ DelayQueue p = populatedQueue(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ PDelay I = (PDelay)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * toArray contains all elements
+ */
+ public void testToArray() throws InterruptedException {
+ DelayQueue q = populatedQueue(SIZE);
+ Object[] o = q.toArray();
+ Arrays.sort(o);
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.take());
+ }
+
+ /**
+ * toArray(a) contains all elements
+ */
+ public void testToArray2() {
+ DelayQueue<PDelay> q = populatedQueue(SIZE);
+ PDelay[] ints = new PDelay[SIZE];
+ PDelay[] array = q.toArray(ints);
+ assertSame(ints, array);
+ Arrays.sort(ints);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.remove());
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ DelayQueue q = populatedQueue(SIZE);
+ try {
+ q.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ DelayQueue q = populatedQueue(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final DelayQueue q = new DelayQueue();
+ q.add(new PDelay(2));
+ q.add(new PDelay(1));
+ q.add(new PDelay(3));
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+ it = q.iterator();
+ assertEquals(new PDelay(2), it.next());
+ assertEquals(new PDelay(3), it.next());
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ DelayQueue q = populatedQueue(SIZE);
+ String s = q.toString();
+ for (Object e : q)
+ assertTrue(s.contains(e.toString()));
+ }
+
+ /**
+ * timed poll transfers elements across Executor tasks
+ */
+ public void testPollInExecutor() {
+ final DelayQueue q = new DelayQueue();
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertNull(q.poll());
+ threadsStarted.await();
+ assertNotNull(q.poll(LONG_DELAY_MS, MILLISECONDS));
+ checkEmpty(q);
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ q.put(new PDelay(1));
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * Delayed actions do not occur until their delay elapses
+ */
+ public void testDelay() throws InterruptedException {
+ DelayQueue<NanoDelay> q = new DelayQueue<NanoDelay>();
+ for (int i = 0; i < SIZE; ++i)
+ q.add(new NanoDelay(1000000L * (SIZE - i)));
+
+ long last = 0;
+ for (int i = 0; i < SIZE; ++i) {
+ NanoDelay e = q.take();
+ long tt = e.getTriggerTime();
+ assertTrue(System.nanoTime() - tt >= 0);
+ if (i != 0)
+ assertTrue(tt >= last);
+ last = tt;
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * peek of a non-empty queue returns non-null even if not expired
+ */
+ public void testPeekDelayed() {
+ DelayQueue q = new DelayQueue();
+ q.add(new NanoDelay(Long.MAX_VALUE));
+ assertNotNull(q.peek());
+ }
+
+ /**
+ * poll of a non-empty queue returns null if no expired elements.
+ */
+ public void testPollDelayed() {
+ DelayQueue q = new DelayQueue();
+ q.add(new NanoDelay(Long.MAX_VALUE));
+ assertNull(q.poll());
+ }
+
+ /**
+ * timed poll of a non-empty queue returns null if no expired elements.
+ */
+ public void testTimedPollDelayed() throws InterruptedException {
+ DelayQueue q = new DelayQueue();
+ q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ }
+
+ /**
+ * drainTo(c) empties queue into another collection c
+ */
+ public void testDrainTo() {
+ DelayQueue q = new DelayQueue();
+ PDelay[] elems = new PDelay[SIZE];
+ for (int i = 0; i < SIZE; ++i) {
+ elems[i] = new PDelay(i);
+ q.add(elems[i]);
+ }
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(elems[i], l.get(i));
+ q.add(elems[0]);
+ q.add(elems[1]);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(elems[0]));
+ assertTrue(q.contains(elems[1]));
+ l.clear();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(2, l.size());
+ for (int i = 0; i < 2; ++i)
+ assertEquals(elems[i], l.get(i));
+ }
+
+ /**
+ * drainTo empties queue
+ */
+ public void testDrainToWithActivePut() throws InterruptedException {
+ final DelayQueue q = populatedQueue(SIZE);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ q.put(new PDelay(SIZE+1));
+ }});
+
+ t.start();
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertTrue(l.size() >= SIZE);
+ t.join();
+ assertTrue(q.size() + l.size() >= SIZE);
+ }
+
+ /**
+ * drainTo(c, n) empties first min(n, size) elements of queue into c
+ */
+ public void testDrainToN() {
+ for (int i = 0; i < SIZE + 2; ++i) {
+ DelayQueue q = populatedQueue(SIZE);
+ ArrayList l = new ArrayList();
+ q.drainTo(l, i);
+ int k = (i < SIZE) ? i : SIZE;
+ assertEquals(SIZE-k, q.size());
+ assertEquals(k, l.size());
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/EntryTest.java b/jsr166-tests/src/test/java/jsr166/EntryTest.java
new file mode 100644
index 0000000..4387a53
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/EntryTest.java
@@ -0,0 +1,123 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+
+public class EntryTest extends JSR166TestCase {
+
+ static final String k1 = "1";
+ static final String v1 = "a";
+ static final String k2 = "2";
+ static final String v2 = "b";
+
+ /**
+ * A new SimpleEntry(k, v) holds k, v.
+ */
+ public void testConstructor1() {
+ Map.Entry e = new AbstractMap.SimpleEntry(k1, v1);
+ assertEquals(k1, e.getKey());
+ assertEquals(v1, e.getValue());
+ }
+
+ /**
+ * A new SimpleImmutableEntry(k, v) holds k, v.
+ */
+ public void testConstructor2() {
+ Map.Entry s = new AbstractMap.SimpleImmutableEntry(k1, v1);
+ assertEquals(k1, s.getKey());
+ assertEquals(v1, s.getValue());
+ }
+
+ /**
+ * A new SimpleEntry(entry(k, v)) holds k, v.
+ */
+ public void testConstructor3() {
+ Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+ Map.Entry e = new AbstractMap.SimpleEntry(e2);
+ assertEquals(k1, e.getKey());
+ assertEquals(v1, e.getValue());
+ }
+
+ /**
+ * A new SimpleImmutableEntry(entry(k, v)) holds k, v.
+ */
+ public void testConstructor4() {
+ Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+ Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+ assertEquals(k1, s.getKey());
+ assertEquals(v1, s.getValue());
+ }
+
+ /**
+ * Entries with same key-value pairs are equal and have same
+ * hashcodes
+ */
+ public void testEquals() {
+ Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+ Map.Entry e = new AbstractMap.SimpleEntry(e2);
+ Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+ Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+ assertEquals(e2, e);
+ assertEquals(e2.hashCode(), e.hashCode());
+ assertEquals(s2, s);
+ assertEquals(s2.hashCode(), s.hashCode());
+ assertEquals(e2, s2);
+ assertEquals(e2.hashCode(), s2.hashCode());
+ assertEquals(e, s);
+ assertEquals(e.hashCode(), s.hashCode());
+ }
+
+ /**
+ * Entries with different key-value pairs are not equal
+ */
+ public void testNotEquals() {
+ Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+ Map.Entry e = new AbstractMap.SimpleEntry(k2, v1);
+ assertFalse(e2.equals(e));
+ e = new AbstractMap.SimpleEntry(k1, v2);
+ assertFalse(e2.equals(e));
+ e = new AbstractMap.SimpleEntry(k2, v2);
+ assertFalse(e2.equals(e));
+
+ Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+ Map.Entry s = new AbstractMap.SimpleImmutableEntry(k2, v1);
+ assertFalse(s2.equals(s));
+ s = new AbstractMap.SimpleImmutableEntry(k1, v2);
+ assertFalse(s2.equals(s));
+ s = new AbstractMap.SimpleImmutableEntry(k2, v2);
+ assertFalse(s2.equals(s));
+ }
+
+ /**
+ * getValue returns last setValue for SimpleEntry
+ */
+ public void testSetValue1() {
+ Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+ Map.Entry e = new AbstractMap.SimpleEntry(e2);
+ assertEquals(k1, e.getKey());
+ assertEquals(v1, e.getValue());
+ e.setValue(k2);
+ assertEquals(k2, e.getValue());
+ assertFalse(e2.equals(e));
+ }
+
+ /**
+ * setValue for SimpleImmutableEntry throws UnsupportedOperationException
+ */
+ public void testSetValue2() {
+ Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+ Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+ assertEquals(k1, s.getKey());
+ assertEquals(v1, s.getValue());
+ try {
+ s.setValue(k2);
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ExchangerTest.java b/jsr166-tests/src/test/java/jsr166/ExchangerTest.java
new file mode 100644
index 0000000..b0f325e
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ExchangerTest.java
@@ -0,0 +1,146 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Exchanger;
+import java.util.concurrent.TimeoutException;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class ExchangerTest extends JSR166TestCase {
+
+ /**
+ * exchange exchanges objects across two threads
+ */
+ public void testExchange() {
+ final Exchanger e = new Exchanger();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertSame(one, e.exchange(two));
+ assertSame(two, e.exchange(one));
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertSame(two, e.exchange(one));
+ assertSame(one, e.exchange(two));
+ }});
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * timed exchange exchanges objects across two threads
+ */
+ public void testTimedExchange() {
+ final Exchanger e = new Exchanger();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
+ assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
+ assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
+ }});
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * interrupt during wait for exchange throws IE
+ */
+ public void testExchange_InterruptedException() {
+ final Exchanger e = new Exchanger();
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ e.exchange(one);
+ }});
+
+ await(threadStarted);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * interrupt during wait for timed exchange throws IE
+ */
+ public void testTimedExchange_InterruptedException() {
+ final Exchanger e = new Exchanger();
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws Exception {
+ threadStarted.countDown();
+ e.exchange(null, LONG_DELAY_MS, MILLISECONDS);
+ }});
+
+ await(threadStarted);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timeout during wait for timed exchange throws TimeoutException
+ */
+ public void testExchange_TimeoutException() {
+ final Exchanger e = new Exchanger();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ long startTime = System.nanoTime();
+ try {
+ e.exchange(null, timeoutMillis(), MILLISECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {}
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * If one exchanging thread is interrupted, another succeeds.
+ */
+ public void testReplacementAfterExchange() {
+ final Exchanger e = new Exchanger();
+ final CountDownLatch exchanged = new CountDownLatch(2);
+ final CountDownLatch interrupted = new CountDownLatch(1);
+ Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertSame(two, e.exchange(one));
+ exchanged.countDown();
+ e.exchange(two);
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertSame(one, e.exchange(two));
+ exchanged.countDown();
+ interrupted.await();
+ assertSame(three, e.exchange(one));
+ }});
+ Thread t3 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ interrupted.await();
+ assertSame(one, e.exchange(three));
+ }});
+
+ await(exchanged);
+ t1.interrupt();
+ awaitTermination(t1);
+ interrupted.countDown();
+ awaitTermination(t2);
+ awaitTermination(t3);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java b/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java
new file mode 100644
index 0000000..eced0ba
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java
@@ -0,0 +1,221 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.security.*;
+
+public class ExecutorCompletionServiceTest extends JSR166TestCase {
+
+ /**
+ * Creating a new ECS with null Executor throw NPE
+ */
+ public void testConstructorNPE() {
+ try {
+ ExecutorCompletionService ecs = new ExecutorCompletionService(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Creating a new ECS with null queue throw NPE
+ */
+ public void testConstructorNPE2() {
+ try {
+ ExecutorService e = Executors.newCachedThreadPool();
+ ExecutorCompletionService ecs = new ExecutorCompletionService(e, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Submitting a null callable throws NPE
+ */
+ public void testSubmitNPE() {
+ ExecutorService e = Executors.newCachedThreadPool();
+ ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+ try {
+ Callable c = null;
+ ecs.submit(c);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Submitting a null runnable throws NPE
+ */
+ public void testSubmitNPE2() {
+ ExecutorService e = Executors.newCachedThreadPool();
+ ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+ try {
+ Runnable r = null;
+ ecs.submit(r, Boolean.TRUE);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * A taken submitted task is completed
+ */
+ public void testTake() throws InterruptedException {
+ ExecutorService e = Executors.newCachedThreadPool();
+ ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+ try {
+ Callable c = new StringTask();
+ ecs.submit(c);
+ Future f = ecs.take();
+ assertTrue(f.isDone());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Take returns the same future object returned by submit
+ */
+ public void testTake2() throws InterruptedException {
+ ExecutorService e = Executors.newCachedThreadPool();
+ ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+ try {
+ Callable c = new StringTask();
+ Future f1 = ecs.submit(c);
+ Future f2 = ecs.take();
+ assertSame(f1, f2);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * If poll returns non-null, the returned task is completed
+ */
+ public void testPoll1() throws Exception {
+ ExecutorService e = Executors.newCachedThreadPool();
+ ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+ try {
+ assertNull(ecs.poll());
+ Callable c = new StringTask();
+ ecs.submit(c);
+
+ long startTime = System.nanoTime();
+ Future f;
+ while ((f = ecs.poll()) == null) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ assertTrue(f.isDone());
+ assertSame(TEST_STRING, f.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * If timed poll returns non-null, the returned task is completed
+ */
+ public void testPoll2() throws InterruptedException {
+ ExecutorService e = Executors.newCachedThreadPool();
+ ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+ try {
+ assertNull(ecs.poll());
+ Callable c = new StringTask();
+ ecs.submit(c);
+ Future f = ecs.poll(SHORT_DELAY_MS, MILLISECONDS);
+ if (f != null)
+ assertTrue(f.isDone());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Submitting to underlying AES that overrides newTaskFor(Callable)
+ * returns and eventually runs Future returned by newTaskFor.
+ */
+ public void testNewTaskForCallable() throws InterruptedException {
+ final AtomicBoolean done = new AtomicBoolean(false);
+ class MyCallableFuture<V> extends FutureTask<V> {
+ MyCallableFuture(Callable<V> c) { super(c); }
+ protected void done() { done.set(true); }
+ }
+ ExecutorService e = new ThreadPoolExecutor(
+ 1, 1, 30L, TimeUnit.SECONDS,
+ new ArrayBlockingQueue<Runnable>(1)) {
+ protected <T> RunnableFuture<T> newTaskFor(Callable<T> c) {
+ return new MyCallableFuture<T>(c);
+ }};
+ ExecutorCompletionService<String> ecs =
+ new ExecutorCompletionService<String>(e);
+ try {
+ assertNull(ecs.poll());
+ Callable<String> c = new StringTask();
+ Future f1 = ecs.submit(c);
+ assertTrue("submit must return MyCallableFuture",
+ f1 instanceof MyCallableFuture);
+ Future f2 = ecs.take();
+ assertSame("submit and take must return same objects", f1, f2);
+ assertTrue("completed task must have set done", done.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Submitting to underlying AES that overrides newTaskFor(Runnable,T)
+ * returns and eventually runs Future returned by newTaskFor.
+ */
+ public void testNewTaskForRunnable() throws InterruptedException {
+ final AtomicBoolean done = new AtomicBoolean(false);
+ class MyRunnableFuture<V> extends FutureTask<V> {
+ MyRunnableFuture(Runnable t, V r) { super(t, r); }
+ protected void done() { done.set(true); }
+ }
+ ExecutorService e = new ThreadPoolExecutor(
+ 1, 1, 30L, TimeUnit.SECONDS,
+ new ArrayBlockingQueue<Runnable>(1)) {
+ protected <T> RunnableFuture<T> newTaskFor(Runnable t, T r) {
+ return new MyRunnableFuture<T>(t, r);
+ }};
+ ExecutorCompletionService<String> ecs =
+ new ExecutorCompletionService<String>(e);
+ try {
+ assertNull(ecs.poll());
+ Runnable r = new NoOpRunnable();
+ Future f1 = ecs.submit(r, null);
+ assertTrue("submit must return MyRunnableFuture",
+ f1 instanceof MyRunnableFuture);
+ Future f2 = ecs.take();
+ assertSame("submit and take must return same objects", f1, f2);
+ assertTrue("completed task must have set done", done.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java b/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java
new file mode 100644
index 0000000..18c0975
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java
@@ -0,0 +1,585 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.security.*;
+
+public class ExecutorsTest extends JSR166TestCase {
+
+ /**
+ * A newCachedThreadPool can execute runnables
+ */
+ public void testNewCachedThreadPool1() {
+ ExecutorService e = Executors.newCachedThreadPool();
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ joinPool(e);
+ }
+
+ /**
+ * A newCachedThreadPool with given ThreadFactory can execute runnables
+ */
+ public void testNewCachedThreadPool2() {
+ ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ joinPool(e);
+ }
+
+ /**
+ * A newCachedThreadPool with null ThreadFactory throws NPE
+ */
+ public void testNewCachedThreadPool3() {
+ try {
+ ExecutorService e = Executors.newCachedThreadPool(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * A new SingleThreadExecutor can execute runnables
+ */
+ public void testNewSingleThreadExecutor1() {
+ ExecutorService e = Executors.newSingleThreadExecutor();
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ joinPool(e);
+ }
+
+ /**
+ * A new SingleThreadExecutor with given ThreadFactory can execute runnables
+ */
+ public void testNewSingleThreadExecutor2() {
+ ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ joinPool(e);
+ }
+
+ /**
+ * A new SingleThreadExecutor with null ThreadFactory throws NPE
+ */
+ public void testNewSingleThreadExecutor3() {
+ try {
+ ExecutorService e = Executors.newSingleThreadExecutor(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * A new SingleThreadExecutor cannot be casted to concrete implementation
+ */
+ public void testCastNewSingleThreadExecutor() {
+ ExecutorService e = Executors.newSingleThreadExecutor();
+ try {
+ ThreadPoolExecutor tpe = (ThreadPoolExecutor)e;
+ shouldThrow();
+ } catch (ClassCastException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * A new newFixedThreadPool can execute runnables
+ */
+ public void testNewFixedThreadPool1() {
+ ExecutorService e = Executors.newFixedThreadPool(2);
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ joinPool(e);
+ }
+
+ /**
+ * A new newFixedThreadPool with given ThreadFactory can execute runnables
+ */
+ public void testNewFixedThreadPool2() {
+ ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ joinPool(e);
+ }
+
+ /**
+ * A new newFixedThreadPool with null ThreadFactory throws NPE
+ */
+ public void testNewFixedThreadPool3() {
+ try {
+ ExecutorService e = Executors.newFixedThreadPool(2, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * A new newFixedThreadPool with 0 threads throws IAE
+ */
+ public void testNewFixedThreadPool4() {
+ try {
+ ExecutorService e = Executors.newFixedThreadPool(0);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * An unconfigurable newFixedThreadPool can execute runnables
+ */
+ public void testUnconfigurableExecutorService() {
+ ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2));
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ e.execute(new NoOpRunnable());
+ joinPool(e);
+ }
+
+ /**
+ * unconfigurableExecutorService(null) throws NPE
+ */
+ public void testUnconfigurableExecutorServiceNPE() {
+ try {
+ ExecutorService e = Executors.unconfigurableExecutorService(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * unconfigurableScheduledExecutorService(null) throws NPE
+ */
+ public void testUnconfigurableScheduledExecutorServiceNPE() {
+ try {
+ ExecutorService e = Executors.unconfigurableScheduledExecutorService(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * a newSingleThreadScheduledExecutor successfully runs delayed task
+ */
+ public void testNewSingleThreadScheduledExecutor() throws Exception {
+ ScheduledExecutorService p = Executors.newSingleThreadScheduledExecutor();
+ try {
+ final CountDownLatch proceed = new CountDownLatch(1);
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ await(proceed);
+ }};
+ long startTime = System.nanoTime();
+ Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
+ timeoutMillis(), MILLISECONDS);
+ assertFalse(f.isDone());
+ proceed.countDown();
+ assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertSame(Boolean.TRUE, f.get());
+ assertTrue(f.isDone());
+ assertFalse(f.isCancelled());
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * a newScheduledThreadPool successfully runs delayed task
+ */
+ public void testNewScheduledThreadPool() throws Exception {
+ ScheduledExecutorService p = Executors.newScheduledThreadPool(2);
+ try {
+ final CountDownLatch proceed = new CountDownLatch(1);
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ await(proceed);
+ }};
+ long startTime = System.nanoTime();
+ Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
+ timeoutMillis(), MILLISECONDS);
+ assertFalse(f.isDone());
+ proceed.countDown();
+ assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertSame(Boolean.TRUE, f.get());
+ assertTrue(f.isDone());
+ assertFalse(f.isCancelled());
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * an unconfigurable newScheduledThreadPool successfully runs delayed task
+ */
+ public void testUnconfigurableScheduledExecutorService() throws Exception {
+ ScheduledExecutorService p =
+ Executors.unconfigurableScheduledExecutorService
+ (Executors.newScheduledThreadPool(2));
+ try {
+ final CountDownLatch proceed = new CountDownLatch(1);
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ await(proceed);
+ }};
+ long startTime = System.nanoTime();
+ Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
+ timeoutMillis(), MILLISECONDS);
+ assertFalse(f.isDone());
+ proceed.countDown();
+ assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertSame(Boolean.TRUE, f.get());
+ assertTrue(f.isDone());
+ assertFalse(f.isCancelled());
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * Future.get on submitted tasks will time out if they compute too long.
+ */
+ public void testTimedCallable() throws Exception {
+ final ExecutorService[] executors = {
+ Executors.newSingleThreadExecutor(),
+ Executors.newCachedThreadPool(),
+ Executors.newFixedThreadPool(2),
+ Executors.newScheduledThreadPool(2),
+ };
+
+ final Runnable sleeper = new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ delay(LONG_DELAY_MS);
+ }};
+
+ List<Thread> threads = new ArrayList<Thread>();
+ for (final ExecutorService executor : executors) {
+ threads.add(newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long startTime = System.nanoTime();
+ Future future = executor.submit(sleeper);
+ assertFutureTimesOut(future);
+ }}));
+ }
+ for (Thread thread : threads)
+ awaitTermination(thread);
+ for (ExecutorService executor : executors)
+ joinPool(executor);
+ }
+
+ /**
+ * ThreadPoolExecutor using defaultThreadFactory has
+ * specified group, priority, daemon status, and name
+ */
+ public void testDefaultThreadFactory() throws Exception {
+ final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
+ final CountDownLatch done = new CountDownLatch(1);
+ Runnable r = new CheckedRunnable() {
+ public void realRun() {
+ try {
+ Thread current = Thread.currentThread();
+ assertTrue(!current.isDaemon());
+ assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
+ ThreadGroup g = current.getThreadGroup();
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ assertTrue(g == s.getThreadGroup());
+ else
+ assertTrue(g == egroup);
+ String name = current.getName();
+ assertTrue(name.endsWith("thread-1"));
+ } catch (SecurityException ok) {
+ // Also pass if not allowed to change setting
+ }
+ done.countDown();
+ }};
+ ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
+
+ e.execute(r);
+ await(done);
+
+ try {
+ e.shutdown();
+ } catch (SecurityException ok) {
+ }
+
+ joinPool(e);
+ }
+
+ /**
+ * ThreadPoolExecutor using privilegedThreadFactory has
+ * specified group, priority, daemon status, name,
+ * access control context and context class loader
+ */
+ public void testPrivilegedThreadFactory() throws Exception {
+ final CountDownLatch done = new CountDownLatch(1);
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
+ final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
+ // final AccessControlContext thisacc = AccessController.getContext(); // Android removed
+ Runnable r = new CheckedRunnable() {
+ public void realRun() {
+ Thread current = Thread.currentThread();
+ assertTrue(!current.isDaemon());
+ assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
+ ThreadGroup g = current.getThreadGroup();
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ assertTrue(g == s.getThreadGroup());
+ else
+ assertTrue(g == egroup);
+ String name = current.getName();
+ assertTrue(name.endsWith("thread-1"));
+ assertSame(thisccl, current.getContextClassLoader());
+ // assertEquals(thisacc, AccessController.getContext()); // Android removed
+ done.countDown();
+ }};
+ ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
+ e.execute(r);
+ await(done);
+ e.shutdown();
+ joinPool(e);
+ }};
+
+ runWithPermissions(r,
+ new RuntimePermission("getClassLoader"),
+ new RuntimePermission("setContextClassLoader"),
+ new RuntimePermission("modifyThread"));
+ }
+
+ boolean haveCCLPermissions() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ try {
+ sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ } catch (AccessControlException e) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void checkCCL() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ }
+ }
+
+ class CheckCCL implements Callable<Object> {
+ public Object call() {
+ checkCCL();
+ return null;
+ }
+ }
+
+ /**
+ * Without class loader permissions, creating
+ * privilegedCallableUsingCurrentClassLoader throws ACE
+ */
+ public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ if (System.getSecurityManager() == null)
+ return;
+ try {
+ Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
+ shouldThrow();
+ } catch (AccessControlException success) {}
+ }};
+
+ runWithoutPermissions(r);
+ }
+
+ /**
+ * With class loader permissions, calling
+ * privilegedCallableUsingCurrentClassLoader does not throw ACE
+ */
+ public void testPrivilegedCallableUsingCCLWithPrivs() throws Exception {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ Executors.privilegedCallableUsingCurrentClassLoader
+ (new NoOpCallable())
+ .call();
+ }};
+
+ runWithPermissions(r,
+ new RuntimePermission("getClassLoader"),
+ new RuntimePermission("setContextClassLoader"));
+ }
+
+ /**
+ * Without permissions, calling privilegedCallable throws ACE
+ */
+ public void testPrivilegedCallableWithNoPrivs() throws Exception {
+ // Avoid classloader-related SecurityExceptions in swingui.TestRunner
+ Executors.privilegedCallable(new CheckCCL());
+
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ if (System.getSecurityManager() == null)
+ return;
+ Callable task = Executors.privilegedCallable(new CheckCCL());
+ try {
+ task.call();
+ shouldThrow();
+ } catch (AccessControlException success) {}
+ }};
+
+ runWithoutPermissions(r);
+
+ // It seems rather difficult to test that the
+ // AccessControlContext of the privilegedCallable is used
+ // instead of its caller. Below is a failed attempt to do
+ // that, which does not work because the AccessController
+ // cannot capture the internal state of the current Policy.
+ // It would be much more work to differentiate based on,
+ // e.g. CodeSource.
+
+// final AccessControlContext[] noprivAcc = new AccessControlContext[1];
+// final Callable[] task = new Callable[1];
+
+// runWithPermissions
+// (new CheckedRunnable() {
+// public void realRun() {
+// if (System.getSecurityManager() == null)
+// return;
+// noprivAcc[0] = AccessController.getContext();
+// task[0] = Executors.privilegedCallable(new CheckCCL());
+// try {
+// AccessController.doPrivileged(new PrivilegedAction<Void>() {
+// public Void run() {
+// checkCCL();
+// return null;
+// }}, noprivAcc[0]);
+// shouldThrow();
+// } catch (AccessControlException success) {}
+// }});
+
+// runWithPermissions
+// (new CheckedRunnable() {
+// public void realRun() throws Exception {
+// if (System.getSecurityManager() == null)
+// return;
+// // Verify that we have an underprivileged ACC
+// try {
+// AccessController.doPrivileged(new PrivilegedAction<Void>() {
+// public Void run() {
+// checkCCL();
+// return null;
+// }}, noprivAcc[0]);
+// shouldThrow();
+// } catch (AccessControlException success) {}
+
+// try {
+// task[0].call();
+// shouldThrow();
+// } catch (AccessControlException success) {}
+// }},
+// new RuntimePermission("getClassLoader"),
+// new RuntimePermission("setContextClassLoader"));
+ }
+
+ /**
+ * With permissions, calling privilegedCallable succeeds
+ */
+ public void testPrivilegedCallableWithPrivs() throws Exception {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ Executors.privilegedCallable(new CheckCCL()).call();
+ }};
+
+ runWithPermissions(r,
+ new RuntimePermission("getClassLoader"),
+ new RuntimePermission("setContextClassLoader"));
+ }
+
+ /**
+ * callable(Runnable) returns null when called
+ */
+ public void testCallable1() throws Exception {
+ Callable c = Executors.callable(new NoOpRunnable());
+ assertNull(c.call());
+ }
+
+ /**
+ * callable(Runnable, result) returns result when called
+ */
+ public void testCallable2() throws Exception {
+ Callable c = Executors.callable(new NoOpRunnable(), one);
+ assertSame(one, c.call());
+ }
+
+ /**
+ * callable(PrivilegedAction) returns its result when called
+ */
+ public void testCallable3() throws Exception {
+ Callable c = Executors.callable(new PrivilegedAction() {
+ public Object run() { return one; }});
+ assertSame(one, c.call());
+ }
+
+ /**
+ * callable(PrivilegedExceptionAction) returns its result when called
+ */
+ public void testCallable4() throws Exception {
+ Callable c = Executors.callable(new PrivilegedExceptionAction() {
+ public Object run() { return one; }});
+ assertSame(one, c.call());
+ }
+
+ /**
+ * callable(null Runnable) throws NPE
+ */
+ public void testCallableNPE1() {
+ try {
+ Callable c = Executors.callable((Runnable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * callable(null, result) throws NPE
+ */
+ public void testCallableNPE2() {
+ try {
+ Callable c = Executors.callable((Runnable) null, one);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * callable(null PrivilegedAction) throws NPE
+ */
+ public void testCallableNPE3() {
+ try {
+ Callable c = Executors.callable((PrivilegedAction) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * callable(null PrivilegedExceptionAction) throws NPE
+ */
+ public void testCallableNPE4() {
+ try {
+ Callable c = Executors.callable((PrivilegedExceptionAction) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java b/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java
new file mode 100644
index 0000000..8416198
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java
@@ -0,0 +1,996 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.ReentrantLock;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import java.security.AccessControlException;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+
+public class ForkJoinPoolTest extends JSR166TestCase {
+
+ /*
+ * Testing coverage notes:
+ *
+ * 1. shutdown and related methods are tested via super.joinPool.
+ *
+ * 2. newTaskFor and adapters are tested in submit/invoke tests
+ *
+ * 3. We cannot portably test monitoring methods such as
+ * getStealCount() since they rely ultimately on random task
+ * stealing that may cause tasks not to be stolen/propagated
+ * across threads, especially on uniprocessors.
+ *
+ * 4. There are no independently testable ForkJoinWorkerThread
+ * methods, but they are covered here and in task tests.
+ */
+
+ // Some classes to test extension and factory methods
+
+ static class MyHandler implements Thread.UncaughtExceptionHandler {
+ volatile int catches = 0;
+ public void uncaughtException(Thread t, Throwable e) {
+ ++catches;
+ }
+ }
+
+ // to test handlers
+ static class FailingFJWSubclass extends ForkJoinWorkerThread {
+ public FailingFJWSubclass(ForkJoinPool p) { super(p) ; }
+ protected void onStart() { super.onStart(); throw new Error(); }
+ }
+
+ static class FailingThreadFactory
+ implements ForkJoinPool.ForkJoinWorkerThreadFactory {
+ volatile int calls = 0;
+ public ForkJoinWorkerThread newThread(ForkJoinPool p) {
+ if (++calls > 1) return null;
+ return new FailingFJWSubclass(p);
+ }
+ }
+
+ static class SubFJP extends ForkJoinPool { // to expose protected
+ SubFJP() { super(1); }
+ public int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
+ return super.drainTasksTo(c);
+ }
+ public ForkJoinTask<?> pollSubmission() {
+ return super.pollSubmission();
+ }
+ }
+
+ static class ManagedLocker implements ForkJoinPool.ManagedBlocker {
+ final ReentrantLock lock;
+ boolean hasLock = false;
+ ManagedLocker(ReentrantLock lock) { this.lock = lock; }
+ public boolean block() {
+ if (!hasLock)
+ lock.lock();
+ return true;
+ }
+ public boolean isReleasable() {
+ return hasLock || (hasLock = lock.tryLock());
+ }
+ }
+
+ // A simple recursive task for testing
+ static final class FibTask extends RecursiveTask<Integer> {
+ final int number;
+ FibTask(int n) { number = n; }
+ public Integer compute() {
+ int n = number;
+ if (n <= 1)
+ return n;
+ FibTask f1 = new FibTask(n - 1);
+ f1.fork();
+ return (new FibTask(n - 2)).compute() + f1.join();
+ }
+ }
+
+ // A failing task for testing
+ static final class FailingTask extends ForkJoinTask<Void> {
+ public final Void getRawResult() { return null; }
+ protected final void setRawResult(Void mustBeNull) { }
+ protected final boolean exec() { throw new Error(); }
+ FailingTask() {}
+ }
+
+ // Fib needlessly using locking to test ManagedBlockers
+ static final class LockingFibTask extends RecursiveTask<Integer> {
+ final int number;
+ final ManagedLocker locker;
+ final ReentrantLock lock;
+ LockingFibTask(int n, ManagedLocker locker, ReentrantLock lock) {
+ number = n;
+ this.locker = locker;
+ this.lock = lock;
+ }
+ public Integer compute() {
+ int n;
+ LockingFibTask f1 = null;
+ LockingFibTask f2 = null;
+ locker.block();
+ n = number;
+ if (n > 1) {
+ f1 = new LockingFibTask(n - 1, locker, lock);
+ f2 = new LockingFibTask(n - 2, locker, lock);
+ }
+ lock.unlock();
+ if (n <= 1)
+ return n;
+ else {
+ f1.fork();
+ return f2.compute() + f1.join();
+ }
+ }
+ }
+
+ /**
+ * Successfully constructed pool reports default factory,
+ * parallelism and async mode policies, no active threads or
+ * tasks, and quiescent running state.
+ */
+ public void testDefaultInitialState() {
+ ForkJoinPool p = new ForkJoinPool(1);
+ try {
+ assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+ p.getFactory());
+ assertFalse(p.getAsyncMode());
+ assertEquals(0, p.getActiveThreadCount());
+ assertEquals(0, p.getStealCount());
+ assertEquals(0, p.getQueuedTaskCount());
+ assertEquals(0, p.getQueuedSubmissionCount());
+ assertFalse(p.hasQueuedSubmissions());
+ assertFalse(p.isShutdown());
+ assertFalse(p.isTerminating());
+ assertFalse(p.isTerminated());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * Constructor throws if size argument is less than zero
+ */
+ public void testConstructor1() {
+ try {
+ new ForkJoinPool(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if factory argument is null
+ */
+ public void testConstructor2() {
+ try {
+ new ForkJoinPool(1, null, null, false);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getParallelism returns size set in constructor
+ */
+ public void testGetParallelism() {
+ ForkJoinPool p = new ForkJoinPool(1);
+ try {
+ assertEquals(1, p.getParallelism());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getPoolSize returns number of started workers.
+ */
+ public void testGetPoolSize() {
+ ForkJoinPool p = new ForkJoinPool(1);
+ try {
+ assertEquals(0, p.getActiveThreadCount());
+ Future<String> future = p.submit(new StringTask());
+ assertEquals(1, p.getPoolSize());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * awaitTermination on a non-shutdown pool times out
+ */
+ public void testAwaitTermination_timesOut() throws InterruptedException {
+ ForkJoinPool p = new ForkJoinPool(1);
+ assertFalse(p.isTerminated());
+ assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
+ assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
+ assertFalse(p.awaitTermination(-1L, NANOSECONDS));
+ assertFalse(p.awaitTermination(-1L, MILLISECONDS));
+ assertFalse(p.awaitTermination(0L, NANOSECONDS));
+ assertFalse(p.awaitTermination(0L, MILLISECONDS));
+ long timeoutNanos = 999999L;
+ long startTime = System.nanoTime();
+ assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
+ assertTrue(System.nanoTime() - startTime >= timeoutNanos);
+ assertFalse(p.isTerminated());
+ startTime = System.nanoTime();
+ long timeoutMillis = timeoutMillis();
+ assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ assertFalse(p.isTerminated());
+ p.shutdown();
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ }
+
+ /**
+ * setUncaughtExceptionHandler changes handler for uncaught exceptions.
+ *
+ * Additionally tests: Overriding ForkJoinWorkerThread.onStart
+ * performs its defined action
+ */
+ public void testSetUncaughtExceptionHandler() throws InterruptedException {
+ final CountDownLatch uehInvoked = new CountDownLatch(1);
+ final Thread.UncaughtExceptionHandler eh =
+ new Thread.UncaughtExceptionHandler() {
+ public void uncaughtException(Thread t, Throwable e) {
+ uehInvoked.countDown();
+ }};
+ ForkJoinPool p = new ForkJoinPool(1, new FailingThreadFactory(),
+ eh, false);
+ try {
+ assertSame(eh, p.getUncaughtExceptionHandler());
+ try {
+ p.execute(new FibTask(8));
+ assertTrue(uehInvoked.await(MEDIUM_DELAY_MS, MILLISECONDS));
+ } catch (RejectedExecutionException ok) {
+ }
+ } finally {
+ p.shutdownNow(); // failure might have prevented processing task
+ joinPool(p);
+ }
+ }
+
+ /**
+ * After invoking a single task, isQuiescent eventually becomes
+ * true, at which time queues are empty, threads are not active,
+ * the task has completed successfully, and construction
+ * parameters continue to hold
+ */
+ public void testIsQuiescent() throws Exception {
+ ForkJoinPool p = new ForkJoinPool(2);
+ try {
+ assertTrue(p.isQuiescent());
+ long startTime = System.nanoTime();
+ FibTask f = new FibTask(20);
+ p.invoke(f);
+ assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+ p.getFactory());
+ while (! p.isQuiescent()) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ throw new AssertionFailedError("timed out");
+ assertFalse(p.getAsyncMode());
+ assertFalse(p.isShutdown());
+ assertFalse(p.isTerminating());
+ assertFalse(p.isTerminated());
+ Thread.yield();
+ }
+
+ assertTrue(p.isQuiescent());
+ assertFalse(p.getAsyncMode());
+ assertEquals(0, p.getActiveThreadCount());
+ assertEquals(0, p.getQueuedTaskCount());
+ assertEquals(0, p.getQueuedSubmissionCount());
+ assertFalse(p.hasQueuedSubmissions());
+ assertFalse(p.isShutdown());
+ assertFalse(p.isTerminating());
+ assertFalse(p.isTerminated());
+ assertTrue(f.isDone());
+ assertEquals(6765, (int) f.get());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * Completed submit(ForkJoinTask) returns result
+ */
+ public void testSubmitForkJoinTask() throws Throwable {
+ ForkJoinPool p = new ForkJoinPool(1);
+ try {
+ ForkJoinTask<Integer> f = p.submit(new FibTask(8));
+ assertEquals(21, (int) f.get());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * A task submitted after shutdown is rejected
+ */
+ public void testSubmitAfterShutdown() {
+ ForkJoinPool p = new ForkJoinPool(1);
+ try {
+ p.shutdown();
+ assertTrue(p.isShutdown());
+ try {
+ ForkJoinTask<Integer> f = p.submit(new FibTask(8));
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * Pool maintains parallelism when using ManagedBlocker
+ */
+ public void testBlockingForkJoinTask() throws Throwable {
+ ForkJoinPool p = new ForkJoinPool(4);
+ try {
+ ReentrantLock lock = new ReentrantLock();
+ ManagedLocker locker = new ManagedLocker(lock);
+ ForkJoinTask<Integer> f = new LockingFibTask(20, locker, lock);
+ p.execute(f);
+ assertEquals(6765, (int) f.get());
+ } finally {
+ p.shutdownNow(); // don't wait out shutdown
+ }
+ }
+
+ /**
+ * pollSubmission returns unexecuted submitted task, if present
+ */
+ public void testPollSubmission() {
+ final CountDownLatch done = new CountDownLatch(1);
+ SubFJP p = new SubFJP();
+ try {
+ ForkJoinTask a = p.submit(awaiter(done));
+ ForkJoinTask b = p.submit(awaiter(done));
+ ForkJoinTask c = p.submit(awaiter(done));
+ ForkJoinTask r = p.pollSubmission();
+ assertTrue(r == a || r == b || r == c);
+ assertFalse(r.isDone());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * drainTasksTo transfers unexecuted submitted tasks, if present
+ */
+ public void testDrainTasksTo() {
+ final CountDownLatch done = new CountDownLatch(1);
+ SubFJP p = new SubFJP();
+ try {
+ ForkJoinTask a = p.submit(awaiter(done));
+ ForkJoinTask b = p.submit(awaiter(done));
+ ForkJoinTask c = p.submit(awaiter(done));
+ ArrayList<ForkJoinTask> al = new ArrayList();
+ p.drainTasksTo(al);
+ assertTrue(al.size() > 0);
+ for (ForkJoinTask r : al) {
+ assertTrue(r == a || r == b || r == c);
+ assertFalse(r.isDone());
+ }
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ // FJ Versions of AbstractExecutorService tests
+
+ /**
+ * execute(runnable) runs it to completion
+ */
+ public void testExecuteRunnable() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ final AtomicBoolean done = new AtomicBoolean(false);
+ CheckedRunnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.set(true);
+ }};
+ Future<?> future = e.submit(task);
+ assertNull(future.get());
+ assertNull(future.get(0, MILLISECONDS));
+ assertTrue(done.get());
+ assertTrue(future.isDone());
+ assertFalse(future.isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Completed submit(callable) returns result
+ */
+ public void testSubmitCallable() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ Future<String> future = e.submit(new StringTask());
+ assertSame(TEST_STRING, future.get());
+ assertTrue(future.isDone());
+ assertFalse(future.isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Completed submit(runnable) returns successfully
+ */
+ public void testSubmitRunnable() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ Future<?> future = e.submit(new NoOpRunnable());
+ assertNull(future.get());
+ assertTrue(future.isDone());
+ assertFalse(future.isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Completed submit(runnable, result) returns result
+ */
+ public void testSubmitRunnable2() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+ assertSame(TEST_STRING, future.get());
+ assertTrue(future.isDone());
+ assertFalse(future.isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * A submitted privileged action runs to completion
+ */
+ public void testSubmitPrivilegedAction() throws Exception {
+ final Callable callable = Executors.callable(new PrivilegedAction() {
+ public Object run() { return TEST_STRING; }});
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ Future future = e.submit(callable);
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }};
+
+ runWithPermissions(r, new RuntimePermission("modifyThread"));
+ }
+
+ /**
+ * A submitted privileged exception action runs to completion
+ */
+ public void testSubmitPrivilegedExceptionAction() throws Exception {
+ final Callable callable =
+ Executors.callable(new PrivilegedExceptionAction() {
+ public Object run() { return TEST_STRING; }});
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ Future future = e.submit(callable);
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }};
+
+ runWithPermissions(r, new RuntimePermission("modifyThread"));
+ }
+
+ /**
+ * A submitted failed privileged exception action reports exception
+ */
+ public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
+ final Callable callable =
+ Executors.callable(new PrivilegedExceptionAction() {
+ public Object run() { throw new IndexOutOfBoundsException(); }});
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws Exception {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ Future future = e.submit(callable);
+ try {
+ future.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
+ }
+ } finally {
+ joinPool(e);
+ }
+ }};
+
+ runWithPermissions(r, new RuntimePermission("modifyThread"));
+ }
+
+ /**
+ * execute(null runnable) throws NullPointerException
+ */
+ public void testExecuteNullRunnable() {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ Future<?> future = e.submit((Runnable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * submit(null callable) throws NullPointerException
+ */
+ public void testSubmitNullCallable() {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ Future<String> future = e.submit((Callable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * submit(callable).get() throws InterruptedException if interrupted
+ */
+ public void testInterruptedSubmit() throws InterruptedException {
+ final CountDownLatch submitted = new CountDownLatch(1);
+ final CountDownLatch quittingTime = new CountDownLatch(1);
+ final ExecutorService p = new ForkJoinPool(1);
+ final Callable<Void> awaiter = new CheckedCallable<Void>() {
+ public Void realCall() throws InterruptedException {
+ assertTrue(quittingTime.await(MEDIUM_DELAY_MS, MILLISECONDS));
+ return null;
+ }};
+ try {
+ Thread t = new Thread(new CheckedInterruptedRunnable() {
+ public void realRun() throws Exception {
+ Future<Void> future = p.submit(awaiter);
+ submitted.countDown();
+ future.get();
+ }});
+ t.start();
+ assertTrue(submitted.await(MEDIUM_DELAY_MS, MILLISECONDS));
+ t.interrupt();
+ t.join();
+ } finally {
+ quittingTime.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * get of submit(callable) throws ExecutionException if callable
+ * throws exception
+ */
+ public void testSubmitEE() throws Throwable {
+ ForkJoinPool p = new ForkJoinPool(1);
+ try {
+ p.submit(new Callable() {
+ public Object call() { throw new ArithmeticException(); }})
+ .get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof ArithmeticException);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * invokeAny(null) throws NullPointerException
+ */
+ public void testInvokeAny1() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ e.invokeAny(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(empty collection) throws IllegalArgumentException
+ */
+ public void testInvokeAny2() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws NullPointerException if c has a single null element
+ */
+ public void testInvokeAny3() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(null);
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws NullPointerException if c has null elements
+ */
+ public void testInvokeAny4() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws ExecutionException if no task in c completes
+ */
+ public void testInvokeAny5() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) returns result of some task in c if at least one completes
+ */
+ public void testInvokeAny6() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(null) throws NullPointerException
+ */
+ public void testInvokeAll1() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ e.invokeAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(empty collection) returns empty collection
+ */
+ public void testInvokeAll2() throws InterruptedException {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ List<Future<String>> r
+ = e.invokeAll(new ArrayList<Callable<String>>());
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) throws NullPointerException if c has null elements
+ */
+ public void testInvokeAll3() throws InterruptedException {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of returned element of invokeAll(c) throws
+ * ExecutionException on failed task
+ */
+ public void testInvokeAll4() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) returns results of all completed tasks in c
+ */
+ public void testInvokeAll5() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(null) throws NullPointerException
+ */
+ public void testTimedInvokeAny1() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(null time unit) throws NullPointerException
+ */
+ public void testTimedInvokeAnyNullTimeUnit() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(empty collection) throws IllegalArgumentException
+ */
+ public void testTimedInvokeAny2() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>(),
+ MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws NullPointerException if c has null elements
+ */
+ public void testTimedInvokeAny3() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testTimedInvokeAny4() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) returns result of some task in c
+ */
+ public void testTimedInvokeAny5() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(null) throws NullPointerException
+ */
+ public void testTimedInvokeAll1() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(null time unit) throws NullPointerException
+ */
+ public void testTimedInvokeAllNullTimeUnit() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(empty collection) returns empty collection
+ */
+ public void testTimedInvokeAll2() throws InterruptedException {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ List<Future<String>> r
+ = e.invokeAll(new ArrayList<Callable<String>>(),
+ MEDIUM_DELAY_MS, MILLISECONDS);
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) throws NullPointerException if c has null elements
+ */
+ public void testTimedInvokeAll3() throws InterruptedException {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of returned element of invokeAll(c) throws exception on failed task
+ */
+ public void testTimedInvokeAll4() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures
+ = e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) returns results of all completed tasks in c
+ */
+ public void testTimedInvokeAll5() throws Throwable {
+ ExecutorService e = new ForkJoinPool(1);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures
+ = e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java b/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java
new file mode 100644
index 0000000..080fd9c
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java
@@ -0,0 +1,1605 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import java.util.HashSet;
+import junit.framework.*;
+
+public class ForkJoinTaskTest extends JSR166TestCase {
+
+ // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
+ static final int mainPoolSize =
+ Math.max(2, Runtime.getRuntime().availableProcessors());
+
+ private static ForkJoinPool mainPool() {
+ return new ForkJoinPool(mainPoolSize);
+ }
+
+ private static ForkJoinPool singletonPool() {
+ return new ForkJoinPool(1);
+ }
+
+ private static ForkJoinPool asyncSingletonPool() {
+ return new ForkJoinPool(1,
+ ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+ null, true);
+ }
+
+ private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
+ try {
+ assertFalse(a.isDone());
+ assertFalse(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+
+ assertNull(pool.invoke(a));
+
+ assertTrue(a.isDone());
+ assertTrue(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+ } finally {
+ joinPool(pool);
+ }
+ }
+
+ void checkNotDone(ForkJoinTask a) {
+ assertFalse(a.isDone());
+ assertFalse(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+
+ try {
+ a.get(0L, SECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ <T> void checkCompletedNormally(ForkJoinTask<T> a) {
+ checkCompletedNormally(a, null);
+ }
+
+ <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertTrue(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertNull(a.getException());
+ assertSame(expected, a.getRawResult());
+
+ {
+ Thread.currentThread().interrupt();
+ long t0 = System.nanoTime();
+ assertSame(expected, a.join());
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ Thread.interrupted();
+ }
+
+ {
+ Thread.currentThread().interrupt();
+ long t0 = System.nanoTime();
+ a.quietlyJoin(); // should be no-op
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ Thread.interrupted();
+ }
+
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+ try {
+ assertSame(expected, a.get());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ try {
+ assertSame(expected, a.get(5L, SECONDS));
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCancelled(ForkJoinTask a) {
+ assertTrue(a.isDone());
+ assertTrue(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertTrue(a.getException() instanceof CancellationException);
+ assertNull(a.getRawResult());
+ assertTrue(a.cancel(false));
+ assertTrue(a.cancel(true));
+
+ try {
+ Thread.currentThread().interrupt();
+ a.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ Thread.interrupted();
+
+ {
+ long t0 = System.nanoTime();
+ a.quietlyJoin(); // should be no-op
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertSame(t.getClass(), a.getException().getClass());
+ assertNull(a.getRawResult());
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+
+ try {
+ Thread.currentThread().interrupt();
+ a.join();
+ shouldThrow();
+ } catch (Throwable expected) {
+ assertSame(t.getClass(), expected.getClass());
+ }
+ Thread.interrupted();
+
+ {
+ long t0 = System.nanoTime();
+ a.quietlyJoin(); // should be no-op
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ /*
+ * Testing coverage notes:
+ *
+ * To test extension methods and overrides, most tests use
+ * BinaryAsyncAction extension class that processes joins
+ * differently than supplied Recursive forms.
+ */
+
+ public static final class FJException extends RuntimeException {
+ FJException() { super(); }
+ }
+
+ abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
+ private volatile int controlState;
+
+ static final AtomicIntegerFieldUpdater<BinaryAsyncAction> controlStateUpdater =
+ AtomicIntegerFieldUpdater.newUpdater(BinaryAsyncAction.class,
+ "controlState");
+
+ private BinaryAsyncAction parent;
+
+ private BinaryAsyncAction sibling;
+
+ protected BinaryAsyncAction() {
+ }
+
+ public final Void getRawResult() { return null; }
+ protected final void setRawResult(Void mustBeNull) { }
+
+ public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
+ x.parent = y.parent = this;
+ x.sibling = y;
+ y.sibling = x;
+ }
+
+ protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+ }
+
+ protected boolean onException() {
+ return true;
+ }
+
+ public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
+ linkSubtasks(x, y);
+ y.fork();
+ x.fork();
+ }
+
+ private void completeThis() {
+ super.complete(null);
+ }
+
+ private void completeThisExceptionally(Throwable ex) {
+ super.completeExceptionally(ex);
+ }
+
+ public final void complete() {
+ BinaryAsyncAction a = this;
+ for (;;) {
+ BinaryAsyncAction s = a.sibling;
+ BinaryAsyncAction p = a.parent;
+ a.sibling = null;
+ a.parent = null;
+ a.completeThis();
+ if (p == null || p.compareAndSetControlState(0, 1))
+ break;
+ try {
+ p.onComplete(a, s);
+ } catch (Throwable rex) {
+ p.completeExceptionally(rex);
+ return;
+ }
+ a = p;
+ }
+ }
+
+ public final void completeExceptionally(Throwable ex) {
+ BinaryAsyncAction a = this;
+ while (!a.isCompletedAbnormally()) {
+ a.completeThisExceptionally(ex);
+ BinaryAsyncAction s = a.sibling;
+ if (s != null)
+ s.cancel(false);
+ if (!a.onException() || (a = a.parent) == null)
+ break;
+ }
+ }
+
+ public final BinaryAsyncAction getParent() {
+ return parent;
+ }
+
+ public BinaryAsyncAction getSibling() {
+ return sibling;
+ }
+
+ public void reinitialize() {
+ parent = sibling = null;
+ super.reinitialize();
+ }
+
+ protected final int getControlState() {
+ return controlState;
+ }
+
+ protected final boolean compareAndSetControlState(int expect,
+ int update) {
+ return controlStateUpdater.compareAndSet(this, expect, update);
+ }
+
+ protected final void setControlState(int value) {
+ controlState = value;
+ }
+
+ protected final void incrementControlState() {
+ controlStateUpdater.incrementAndGet(this);
+ }
+
+ protected final void decrementControlState() {
+ controlStateUpdater.decrementAndGet(this);
+ }
+
+ }
+
+ static final class AsyncFib extends BinaryAsyncAction {
+ int number;
+ public AsyncFib(int n) {
+ this.number = n;
+ }
+
+ public final boolean exec() {
+ AsyncFib f = this;
+ int n = f.number;
+ if (n > 1) {
+ while (n > 1) {
+ AsyncFib p = f;
+ AsyncFib r = new AsyncFib(n - 2);
+ f = new AsyncFib(--n);
+ p.linkSubtasks(r, f);
+ r.fork();
+ }
+ f.number = n;
+ }
+ f.complete();
+ return false;
+ }
+
+ protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+ number = ((AsyncFib)x).number + ((AsyncFib)y).number;
+ }
+ }
+
+ static final class FailingAsyncFib extends BinaryAsyncAction {
+ int number;
+ public FailingAsyncFib(int n) {
+ this.number = n;
+ }
+
+ public final boolean exec() {
+ FailingAsyncFib f = this;
+ int n = f.number;
+ if (n > 1) {
+ while (n > 1) {
+ FailingAsyncFib p = f;
+ FailingAsyncFib r = new FailingAsyncFib(n - 2);
+ f = new FailingAsyncFib(--n);
+ p.linkSubtasks(r, f);
+ r.fork();
+ }
+ f.number = n;
+ }
+ f.complete();
+ return false;
+ }
+
+ protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+ completeExceptionally(new FJException());
+ }
+ }
+
+ /**
+ * invoke returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks; getRawResult returns null.
+ */
+ public void testInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertNull(f.invoke());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks
+ */
+ public void testQuietlyInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ f.quietlyInvoke();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task returns when task completes
+ */
+ public void testForkJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertNull(f.join());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * get of a forked task returns when task completes
+ */
+ public void testForkGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertNull(f.get());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task returns when task completes
+ */
+ public void testForkTimedGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get with null time unit throws NPE
+ */
+ public void testForkTimedGetNPE() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(5L, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes
+ */
+ public void testForkQuietlyJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * helpQuiesce returns when tasks are complete.
+ * getQueuedTaskCount returns 0 when quiescent
+ */
+ public void testForkHelpQuiesce() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ helpQuiesce();
+ assertEquals(21, f.number);
+ assertEquals(0, getQueuedTaskCount());
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task completes abnormally
+ */
+ public void testAbnormalInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes abnormally
+ */
+ public void testAbnormalQuietlyInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ f.quietlyInvoke();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkTimedGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes abnormally
+ */
+ public void testAbnormalForkQuietlyJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task cancelled
+ */
+ public void testCancelledInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkTimedGet() throws Exception {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task cancelled
+ */
+ public void testCancelledForkQuietlyJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ checkCancelled(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * getPool of executing task returns its pool
+ */
+ public void testGetPool() {
+ final ForkJoinPool mainPool = mainPool();
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertSame(mainPool, getPool());
+ }};
+ testInvokeOnPool(mainPool, a);
+ }
+
+ /**
+ * getPool of non-FJ task returns null
+ */
+ public void testGetPool2() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertNull(getPool());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * inForkJoinPool of executing task returns true
+ */
+ public void testInForkJoinPool() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertTrue(inForkJoinPool());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * inForkJoinPool of non-FJ task returns false
+ */
+ public void testInForkJoinPool2() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertFalse(inForkJoinPool());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * setRawResult(null) succeeds
+ */
+ public void testSetRawResult() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ setRawResult(null);
+ assertNull(getRawResult());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * invoke task throws exception after invoking completeExceptionally
+ */
+ public void testCompleteExceptionally() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ f.completeExceptionally(new FJException());
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) invokes all task arguments
+ */
+ public void testInvokeAll2() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ invokeAll(f, g);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument invokes task
+ */
+ public void testInvokeAll1() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ invokeAll(f);
+ checkCompletedNormally(f);
+ assertEquals(21, f.number);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument invokes tasks
+ */
+ public void testInvokeAll3() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ AsyncFib h = new AsyncFib(7);
+ invokeAll(f, g, h);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ assertEquals(13, h.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) invokes all tasks in the collection
+ */
+ public void testInvokeAllCollection() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ AsyncFib h = new AsyncFib(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ invokeAll(set);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ assertEquals(13, h.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with any null task throws NPE
+ */
+ public void testInvokeAllNPE() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ AsyncFib h = null;
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) throw exception if any task does
+ */
+ public void testAbnormalInvokeAll2() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ FailingAsyncFib g = new FailingAsyncFib(9);
+ try {
+ invokeAll(f, g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument throws exception if task does
+ */
+ public void testAbnormalInvokeAll1() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib g = new FailingAsyncFib(9);
+ try {
+ invokeAll(g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument throws exception if any task does
+ */
+ public void testAbnormalInvokeAll3() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ FailingAsyncFib g = new FailingAsyncFib(9);
+ AsyncFib h = new AsyncFib(7);
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) throws exception if any task does
+ */
+ public void testAbnormalInvokeAllCollection() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ AsyncFib h = new AsyncFib(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ try {
+ invokeAll(set);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * tryUnfork returns true for most recent unexecuted task,
+ * and suppresses execution
+ */
+ public void testTryUnfork() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib g = new AsyncFib(9);
+ assertSame(g, g.fork());
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertTrue(f.tryUnfork());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * getSurplusQueuedTaskCount returns > 0 when
+ * there are more tasks than threads
+ */
+ public void testGetSurplusQueuedTaskCount() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib h = new AsyncFib(7);
+ assertSame(h, h.fork());
+ AsyncFib g = new AsyncFib(9);
+ assertSame(g, g.fork());
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertTrue(getSurplusQueuedTaskCount() > 0);
+ helpQuiesce();
+ assertEquals(0, getSurplusQueuedTaskCount());
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * peekNextLocalTask returns most recent unexecuted task.
+ */
+ public void testPeekNextLocalTask() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib g = new AsyncFib(9);
+ assertSame(g, g.fork());
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertSame(f, peekNextLocalTask());
+ assertNull(f.join());
+ checkCompletedNormally(f);
+ helpQuiesce();
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * pollNextLocalTask returns most recent unexecuted task without
+ * executing it
+ */
+ public void testPollNextLocalTask() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib g = new AsyncFib(9);
+ assertSame(g, g.fork());
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollNextLocalTask());
+ helpQuiesce();
+ checkNotDone(f);
+ assertEquals(34, g.number);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it
+ */
+ public void testPollTask() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib g = new AsyncFib(9);
+ assertSame(g, g.fork());
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollTask());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * peekNextLocalTask returns least recent unexecuted task in async mode
+ */
+ public void testPeekNextLocalTaskAsync() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib g = new AsyncFib(9);
+ assertSame(g, g.fork());
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertSame(g, peekNextLocalTask());
+ assertNull(f.join());
+ helpQuiesce();
+ checkCompletedNormally(f);
+ assertEquals(34, g.number);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ /**
+ * pollNextLocalTask returns least recent unexecuted task without
+ * executing it, in async mode
+ */
+ public void testPollNextLocalTaskAsync() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib g = new AsyncFib(9);
+ assertSame(g, g.fork());
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollNextLocalTask());
+ helpQuiesce();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ checkNotDone(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it, in
+ * async mode
+ */
+ public void testPollTaskAsync() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib g = new AsyncFib(9);
+ assertSame(g, g.fork());
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollTask());
+ helpQuiesce();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ checkNotDone(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ // versions for singleton pools
+
+ /**
+ * invoke returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks; getRawResult returns null.
+ */
+ public void testInvokeSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertNull(f.invoke());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks
+ */
+ public void testQuietlyInvokeSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ f.quietlyInvoke();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * join of a forked task returns when task completes
+ */
+ public void testForkJoinSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertNull(f.join());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * get of a forked task returns when task completes
+ */
+ public void testForkGetSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertNull(f.get());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * timed get of a forked task returns when task completes
+ */
+ public void testForkTimedGetSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * timed get with null time unit throws NPE
+ */
+ public void testForkTimedGetNPESingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(5L, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes
+ */
+ public void testForkQuietlyJoinSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * helpQuiesce returns when tasks are complete.
+ * getQueuedTaskCount returns 0 when quiescent
+ */
+ public void testForkHelpQuiesceSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertSame(f, f.fork());
+ helpQuiesce();
+ assertEquals(0, getQueuedTaskCount());
+ assertEquals(21, f.number);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task completes abnormally
+ */
+ public void testAbnormalInvokeSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes abnormally
+ */
+ public void testAbnormalQuietlyInvokeSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ f.quietlyInvoke();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkJoinSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkGetSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkTimedGetSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes abnormally
+ */
+ public void testAbnormalForkQuietlyJoinSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task cancelled
+ */
+ public void testCancelledInvokeSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkJoinSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkGetSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkTimedGetSingleton() throws Exception {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task cancelled
+ */
+ public void testCancelledForkQuietlyJoinSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ checkCancelled(f);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invoke task throws exception after invoking completeExceptionally
+ */
+ public void testCompleteExceptionallySingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ f.completeExceptionally(new FJException());
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) invokes all task arguments
+ */
+ public void testInvokeAll2Singleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ invokeAll(f, g);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument invokes task
+ */
+ public void testInvokeAll1Singleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ invokeAll(f);
+ checkCompletedNormally(f);
+ assertEquals(21, f.number);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument invokes tasks
+ */
+ public void testInvokeAll3Singleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ AsyncFib h = new AsyncFib(7);
+ invokeAll(f, g, h);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ assertEquals(13, h.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) invokes all tasks in the collection
+ */
+ public void testInvokeAllCollectionSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ AsyncFib h = new AsyncFib(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ invokeAll(set);
+ assertEquals(21, f.number);
+ assertEquals(34, g.number);
+ assertEquals(13, h.number);
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with any null task throws NPE
+ */
+ public void testInvokeAllNPESingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ AsyncFib h = null;
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) throw exception if any task does
+ */
+ public void testAbnormalInvokeAll2Singleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ FailingAsyncFib g = new FailingAsyncFib(9);
+ try {
+ invokeAll(f, g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument throws exception if task does
+ */
+ public void testAbnormalInvokeAll1Singleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib g = new FailingAsyncFib(9);
+ try {
+ invokeAll(g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument throws exception if any task does
+ */
+ public void testAbnormalInvokeAll3Singleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ AsyncFib f = new AsyncFib(8);
+ FailingAsyncFib g = new FailingAsyncFib(9);
+ AsyncFib h = new AsyncFib(7);
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) throws exception if any task does
+ */
+ public void testAbnormalInvokeAllCollectionSingleton() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingAsyncFib f = new FailingAsyncFib(8);
+ AsyncFib g = new AsyncFib(9);
+ AsyncFib h = new AsyncFib(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ try {
+ invokeAll(set);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java b/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java
new file mode 100644
index 0000000..baab79e
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java
@@ -0,0 +1,799 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import java.util.*;
+
+public class FutureTaskTest extends JSR166TestCase {
+
+ void checkIsDone(Future<?> f) {
+ assertTrue(f.isDone());
+ assertFalse(f.cancel(false));
+ assertFalse(f.cancel(true));
+ if (f instanceof PublicFutureTask) {
+ PublicFutureTask pf = (PublicFutureTask) f;
+ assertEquals(1, pf.doneCount());
+ assertFalse(pf.runAndReset());
+ assertEquals(1, pf.doneCount());
+ Object r = null; Object exInfo = null;
+ try {
+ r = f.get();
+ } catch (CancellationException t) {
+ exInfo = CancellationException.class;
+ } catch (ExecutionException t) {
+ exInfo = t.getCause();
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+
+ // Check that run and runAndReset have no effect.
+ int savedRunCount = pf.runCount();
+ pf.run();
+ pf.runAndReset();
+ assertEquals(savedRunCount, pf.runCount());
+ try {
+ assertSame(r, f.get());
+ } catch (CancellationException t) {
+ assertSame(exInfo, CancellationException.class);
+ } catch (ExecutionException t) {
+ assertSame(exInfo, t.getCause());
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+ assertTrue(f.isDone());
+ }
+ }
+
+ void checkNotDone(Future<?> f) {
+ assertFalse(f.isDone());
+ assertFalse(f.isCancelled());
+ if (f instanceof PublicFutureTask) {
+ PublicFutureTask pf = (PublicFutureTask) f;
+ assertEquals(0, pf.doneCount());
+ assertEquals(0, pf.setCount());
+ assertEquals(0, pf.setExceptionCount());
+ }
+ }
+
+ void checkIsRunning(Future<?> f) {
+ checkNotDone(f);
+ if (f instanceof FutureTask) {
+ FutureTask ft = (FutureTask<?>) f;
+ // Check that run methods do nothing
+ ft.run();
+ if (f instanceof PublicFutureTask) {
+ PublicFutureTask pf = (PublicFutureTask) f;
+ int savedRunCount = pf.runCount();
+ pf.run();
+ assertFalse(pf.runAndReset());
+ assertEquals(savedRunCount, pf.runCount());
+ }
+ checkNotDone(f);
+ }
+ }
+
+ <T> void checkCompletedNormally(Future<T> f, T expected) {
+ checkIsDone(f);
+ assertFalse(f.isCancelled());
+
+ try {
+ assertSame(expected, f.get());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ try {
+ assertSame(expected, f.get(5L, SECONDS));
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCancelled(Future<?> f) {
+ checkIsDone(f);
+ assertTrue(f.isCancelled());
+
+ try {
+ f.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ f.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void tryToConfuseDoneTask(PublicFutureTask pf) {
+ pf.set(new Object());
+ pf.setException(new Error());
+ for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
+ pf.cancel(true);
+ }
+ }
+
+ void checkCompletedAbnormally(Future<?> f, Throwable t) {
+ checkIsDone(f);
+ assertFalse(f.isCancelled());
+
+ try {
+ f.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t, success.getCause());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ f.get(5L, SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t, success.getCause());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ /**
+ * Subclass to expose protected methods
+ */
+ static class PublicFutureTask extends FutureTask {
+ private final AtomicInteger runCount;
+ private final AtomicInteger doneCount = new AtomicInteger(0);
+ private final AtomicInteger runAndResetCount = new AtomicInteger(0);
+ private final AtomicInteger setCount = new AtomicInteger(0);
+ private final AtomicInteger setExceptionCount = new AtomicInteger(0);
+ public int runCount() { return runCount.get(); }
+ public int doneCount() { return doneCount.get(); }
+ public int runAndResetCount() { return runAndResetCount.get(); }
+ public int setCount() { return setCount.get(); }
+ public int setExceptionCount() { return setExceptionCount.get(); }
+
+ PublicFutureTask(Runnable runnable) {
+ this(runnable, seven);
+ }
+ PublicFutureTask(Runnable runnable, Object result) {
+ this(runnable, result, new AtomicInteger(0));
+ }
+ private PublicFutureTask(final Runnable runnable, Object result,
+ final AtomicInteger runCount) {
+ super(new Runnable() {
+ public void run() {
+ runCount.getAndIncrement();
+ runnable.run();
+ }}, result);
+ this.runCount = runCount;
+ }
+ PublicFutureTask(Callable callable) {
+ this(callable, new AtomicInteger(0));
+ }
+ private PublicFutureTask(final Callable callable,
+ final AtomicInteger runCount) {
+ super(new Callable() {
+ public Object call() throws Exception {
+ runCount.getAndIncrement();
+ return callable.call();
+ }});
+ this.runCount = runCount;
+ }
+ @Override public void done() {
+ assertTrue(isDone());
+ doneCount.incrementAndGet();
+ super.done();
+ }
+ @Override public boolean runAndReset() {
+ runAndResetCount.incrementAndGet();
+ return super.runAndReset();
+ }
+ @Override public void set(Object x) {
+ setCount.incrementAndGet();
+ super.set(x);
+ }
+ @Override public void setException(Throwable t) {
+ setExceptionCount.incrementAndGet();
+ super.setException(t);
+ }
+ }
+
+ class Counter extends CheckedRunnable {
+ final AtomicInteger count = new AtomicInteger(0);
+ public int get() { return count.get(); }
+ public void realRun() {
+ count.getAndIncrement();
+ }
+ }
+
+ /**
+ * creating a future with a null callable throws NullPointerException
+ */
+ public void testConstructor() {
+ try {
+ new FutureTask(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * creating a future with null runnable throws NullPointerException
+ */
+ public void testConstructor2() {
+ try {
+ new FutureTask(null, Boolean.TRUE);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * isDone is true when a task completes
+ */
+ public void testIsDone() {
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ assertFalse(task.isDone());
+ task.run();
+ assertTrue(task.isDone());
+ checkCompletedNormally(task, Boolean.TRUE);
+ assertEquals(1, task.runCount());
+ }
+
+ /**
+ * runAndReset of a non-cancelled task succeeds
+ */
+ public void testRunAndReset() {
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ for (int i = 0; i < 3; i++) {
+ assertTrue(task.runAndReset());
+ checkNotDone(task);
+ assertEquals(i+1, task.runCount());
+ assertEquals(i+1, task.runAndResetCount());
+ assertEquals(0, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ }
+ }
+
+ /**
+ * runAndReset after cancellation fails
+ */
+ public void testRunAndResetAfterCancel() {
+ for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ assertTrue(task.cancel(mayInterruptIfRunning));
+ for (int i = 0; i < 3; i++) {
+ assertFalse(task.runAndReset());
+ assertEquals(0, task.runCount());
+ assertEquals(i+1, task.runAndResetCount());
+ assertEquals(0, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ }
+ tryToConfuseDoneTask(task);
+ checkCancelled(task);
+ }
+ }
+
+ /**
+ * setting value causes get to return it
+ */
+ public void testSet() throws Exception {
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ task.set(one);
+ for (int i = 0; i < 3; i++) {
+ assertSame(one, task.get());
+ assertSame(one, task.get(LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(1, task.setCount());
+ }
+ tryToConfuseDoneTask(task);
+ checkCompletedNormally(task, one);
+ assertEquals(0, task.runCount());
+ }
+
+ /**
+ * setException causes get to throw ExecutionException
+ */
+ public void testSetException_get() throws Exception {
+ Exception nse = new NoSuchElementException();
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ task.setException(nse);
+
+ try {
+ task.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(nse, success.getCause());
+ checkCompletedAbnormally(task, nse);
+ }
+
+ try {
+ task.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(nse, success.getCause());
+ checkCompletedAbnormally(task, nse);
+ }
+
+ assertEquals(1, task.setExceptionCount());
+ assertEquals(0, task.setCount());
+ tryToConfuseDoneTask(task);
+ checkCompletedAbnormally(task, nse);
+ assertEquals(0, task.runCount());
+ }
+
+ /**
+ * cancel(false) before run succeeds
+ */
+ public void testCancelBeforeRun() {
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ assertTrue(task.cancel(false));
+ task.run();
+ assertEquals(0, task.runCount());
+ assertEquals(0, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ assertTrue(task.isCancelled());
+ assertTrue(task.isDone());
+ tryToConfuseDoneTask(task);
+ assertEquals(0, task.runCount());
+ checkCancelled(task);
+ }
+
+ /**
+ * cancel(true) before run succeeds
+ */
+ public void testCancelBeforeRun2() {
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ assertTrue(task.cancel(true));
+ task.run();
+ assertEquals(0, task.runCount());
+ assertEquals(0, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ assertTrue(task.isCancelled());
+ assertTrue(task.isDone());
+ tryToConfuseDoneTask(task);
+ assertEquals(0, task.runCount());
+ checkCancelled(task);
+ }
+
+ /**
+ * cancel(false) of a completed task fails
+ */
+ public void testCancelAfterRun() {
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ task.run();
+ assertFalse(task.cancel(false));
+ assertEquals(1, task.runCount());
+ assertEquals(1, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ tryToConfuseDoneTask(task);
+ checkCompletedNormally(task, Boolean.TRUE);
+ assertEquals(1, task.runCount());
+ }
+
+ /**
+ * cancel(true) of a completed task fails
+ */
+ public void testCancelAfterRun2() {
+ PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+ task.run();
+ assertFalse(task.cancel(true));
+ assertEquals(1, task.runCount());
+ assertEquals(1, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ tryToConfuseDoneTask(task);
+ checkCompletedNormally(task, Boolean.TRUE);
+ assertEquals(1, task.runCount());
+ }
+
+ /**
+ * cancel(true) interrupts a running task that subsequently succeeds
+ */
+ public void testCancelInterrupt() {
+ final CountDownLatch pleaseCancel = new CountDownLatch(1);
+ final PublicFutureTask task =
+ new PublicFutureTask(new CheckedRunnable() {
+ public void realRun() {
+ pleaseCancel.countDown();
+ try {
+ delay(LONG_DELAY_MS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ Thread t = newStartedThread(task);
+ await(pleaseCancel);
+ assertTrue(task.cancel(true));
+ assertTrue(task.isCancelled());
+ assertTrue(task.isDone());
+ awaitTermination(t);
+ assertEquals(1, task.runCount());
+ assertEquals(1, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ tryToConfuseDoneTask(task);
+ checkCancelled(task);
+ }
+
+ /**
+ * cancel(true) tries to interrupt a running task, but
+ * Thread.interrupt throws (simulating a restrictive security
+ * manager)
+ */
+ public void testCancelInterrupt_ThrowsSecurityException() {
+ final CountDownLatch pleaseCancel = new CountDownLatch(1);
+ final CountDownLatch cancelled = new CountDownLatch(1);
+ final PublicFutureTask task =
+ new PublicFutureTask(new CheckedRunnable() {
+ public void realRun() {
+ pleaseCancel.countDown();
+ await(cancelled);
+ assertFalse(Thread.interrupted());
+ }});
+
+ final Thread t = new Thread(task) {
+ // Simulate a restrictive security manager.
+ @Override public void interrupt() {
+ throw new SecurityException();
+ }};
+ t.setDaemon(true);
+ t.start();
+
+ await(pleaseCancel);
+ try {
+ task.cancel(true);
+ shouldThrow();
+ } catch (SecurityException expected) {}
+
+ // We failed to deliver the interrupt, but the world retains
+ // its sanity, as if we had done task.cancel(false)
+ assertTrue(task.isCancelled());
+ assertTrue(task.isDone());
+ assertEquals(1, task.runCount());
+ assertEquals(1, task.doneCount());
+ assertEquals(0, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ cancelled.countDown();
+ awaitTermination(t);
+ assertEquals(1, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ tryToConfuseDoneTask(task);
+ checkCancelled(task);
+ }
+
+ /**
+ * cancel(true) interrupts a running task that subsequently throws
+ */
+ public void testCancelInterrupt_taskFails() {
+ final CountDownLatch pleaseCancel = new CountDownLatch(1);
+ final PublicFutureTask task =
+ new PublicFutureTask(new Runnable() {
+ public void run() {
+ try {
+ pleaseCancel.countDown();
+ delay(LONG_DELAY_MS);
+ threadShouldThrow();
+ } catch (InterruptedException success) {
+ } catch (Throwable t) { threadUnexpectedException(t); }
+ throw new RuntimeException();
+ }});
+
+ Thread t = newStartedThread(task);
+ await(pleaseCancel);
+ assertTrue(task.cancel(true));
+ assertTrue(task.isCancelled());
+ awaitTermination(t);
+ assertEquals(1, task.runCount());
+ assertEquals(0, task.setCount());
+ assertEquals(1, task.setExceptionCount());
+ tryToConfuseDoneTask(task);
+ checkCancelled(task);
+ }
+
+ /**
+ * cancel(false) does not interrupt a running task
+ */
+ public void testCancelNoInterrupt() {
+ final CountDownLatch pleaseCancel = new CountDownLatch(1);
+ final CountDownLatch cancelled = new CountDownLatch(1);
+ final PublicFutureTask task =
+ new PublicFutureTask(new CheckedCallable<Boolean>() {
+ public Boolean realCall() {
+ pleaseCancel.countDown();
+ await(cancelled);
+ assertFalse(Thread.interrupted());
+ return Boolean.TRUE;
+ }});
+
+ Thread t = newStartedThread(task);
+ await(pleaseCancel);
+ assertTrue(task.cancel(false));
+ assertTrue(task.isCancelled());
+ cancelled.countDown();
+ awaitTermination(t);
+ assertEquals(1, task.runCount());
+ assertEquals(1, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ tryToConfuseDoneTask(task);
+ checkCancelled(task);
+ }
+
+ /**
+ * run in one thread causes get in another thread to retrieve value
+ */
+ public void testGetRun() {
+ final CountDownLatch pleaseRun = new CountDownLatch(2);
+
+ final PublicFutureTask task =
+ new PublicFutureTask(new CheckedCallable<Object>() {
+ public Object realCall() {
+ return two;
+ }});
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ pleaseRun.countDown();
+ assertSame(two, task.get());
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ pleaseRun.countDown();
+ assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
+ }});
+
+ await(pleaseRun);
+ checkNotDone(task);
+ assertTrue(t1.isAlive());
+ assertTrue(t2.isAlive());
+ task.run();
+ checkCompletedNormally(task, two);
+ assertEquals(1, task.runCount());
+ assertEquals(1, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ awaitTermination(t1);
+ awaitTermination(t2);
+ tryToConfuseDoneTask(task);
+ checkCompletedNormally(task, two);
+ }
+
+ /**
+ * set in one thread causes get in another thread to retrieve value
+ */
+ public void testGetSet() {
+ final CountDownLatch pleaseSet = new CountDownLatch(2);
+
+ final PublicFutureTask task =
+ new PublicFutureTask(new CheckedCallable<Object>() {
+ public Object realCall() throws InterruptedException {
+ return two;
+ }});
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ pleaseSet.countDown();
+ assertSame(two, task.get());
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ pleaseSet.countDown();
+ assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
+ }});
+
+ await(pleaseSet);
+ checkNotDone(task);
+ assertTrue(t1.isAlive());
+ assertTrue(t2.isAlive());
+ task.set(two);
+ assertEquals(0, task.runCount());
+ assertEquals(1, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ tryToConfuseDoneTask(task);
+ checkCompletedNormally(task, two);
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * Cancelling a task causes timed get in another thread to throw
+ * CancellationException
+ */
+ public void testTimedGet_Cancellation() {
+ testTimedGet_Cancellation(false);
+ }
+ public void testTimedGet_Cancellation_interrupt() {
+ testTimedGet_Cancellation(true);
+ }
+ public void testTimedGet_Cancellation(final boolean mayInterruptIfRunning) {
+ final CountDownLatch pleaseCancel = new CountDownLatch(3);
+ final CountDownLatch cancelled = new CountDownLatch(1);
+ final Callable<Object> callable =
+ new CheckedCallable<Object>() {
+ public Object realCall() throws InterruptedException {
+ pleaseCancel.countDown();
+ if (mayInterruptIfRunning) {
+ try {
+ delay(2*LONG_DELAY_MS);
+ } catch (InterruptedException success) {}
+ } else {
+ await(cancelled);
+ }
+ return two;
+ }};
+ final PublicFutureTask task = new PublicFutureTask(callable);
+
+ Thread t1 = new ThreadShouldThrow(CancellationException.class) {
+ public void realRun() throws Exception {
+ pleaseCancel.countDown();
+ task.get();
+ }};
+ Thread t2 = new ThreadShouldThrow(CancellationException.class) {
+ public void realRun() throws Exception {
+ pleaseCancel.countDown();
+ task.get(2*LONG_DELAY_MS, MILLISECONDS);
+ }};
+ t1.start();
+ t2.start();
+ Thread t3 = newStartedThread(task);
+ await(pleaseCancel);
+ checkIsRunning(task);
+ task.cancel(mayInterruptIfRunning);
+ checkCancelled(task);
+ awaitTermination(t1);
+ awaitTermination(t2);
+ cancelled.countDown();
+ awaitTermination(t3);
+ assertEquals(1, task.runCount());
+ assertEquals(1, task.setCount());
+ assertEquals(0, task.setExceptionCount());
+ tryToConfuseDoneTask(task);
+ checkCancelled(task);
+ }
+
+ /**
+ * A runtime exception in task causes get to throw ExecutionException
+ */
+ public void testGet_ExecutionException() throws InterruptedException {
+ final ArithmeticException e = new ArithmeticException();
+ final PublicFutureTask task = new PublicFutureTask(new Callable() {
+ public Object call() {
+ throw e;
+ }});
+
+ task.run();
+ assertEquals(1, task.runCount());
+ assertEquals(0, task.setCount());
+ assertEquals(1, task.setExceptionCount());
+ try {
+ task.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(e, success.getCause());
+ tryToConfuseDoneTask(task);
+ checkCompletedAbnormally(task, success.getCause());
+ }
+ }
+
+ /**
+ * A runtime exception in task causes timed get to throw ExecutionException
+ */
+ public void testTimedGet_ExecutionException2() throws Exception {
+ final ArithmeticException e = new ArithmeticException();
+ final PublicFutureTask task = new PublicFutureTask(new Callable() {
+ public Object call() {
+ throw e;
+ }});
+
+ task.run();
+ try {
+ task.get(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(e, success.getCause());
+ tryToConfuseDoneTask(task);
+ checkCompletedAbnormally(task, success.getCause());
+ }
+ }
+
+ /**
+ * get is interruptible
+ */
+ public void testGet_interruptible() {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ final FutureTask task = new FutureTask(new NoOpCallable());
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ Thread.currentThread().interrupt();
+ try {
+ task.get();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ task.get();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ t.interrupt();
+ awaitTermination(t);
+ checkNotDone(task);
+ }
+
+ /**
+ * timed get is interruptible
+ */
+ public void testTimedGet_interruptible() {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ final FutureTask task = new FutureTask(new NoOpCallable());
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ Thread.currentThread().interrupt();
+ try {
+ task.get(2*LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ task.get(2*LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ t.interrupt();
+ awaitTermination(t);
+ checkNotDone(task);
+ }
+
+ /**
+ * A timed out timed get throws TimeoutException
+ */
+ public void testGet_TimeoutException() throws Exception {
+ FutureTask task = new FutureTask(new NoOpCallable());
+ long startTime = System.nanoTime();
+ try {
+ task.get(timeoutMillis(), MILLISECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }
+ }
+
+ /**
+ * timed get with null TimeUnit throws NullPointerException
+ */
+ public void testGet_NullTimeUnit() throws Exception {
+ FutureTask task = new FutureTask(new NoOpCallable());
+ long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
+
+ for (long timeout : timeouts) {
+ try {
+ task.get(timeout, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ task.run();
+
+ for (long timeout : timeouts) {
+ try {
+ task.get(timeout, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
new file mode 100644
index 0000000..d9bf255
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
@@ -0,0 +1,1140 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.PropertyPermission;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.security.SecurityPermission;
+
+/**
+ * Base class for JSR166 Junit TCK tests. Defines some constants,
+ * utility methods and classes, as well as a simple framework for
+ * helping to make sure that assertions failing in generated threads
+ * cause the associated test that generated them to itself fail (which
+ * JUnit does not otherwise arrange). The rules for creating such
+ * tests are:
+ *
+ * <ol>
+ *
+ * <li> All assertions in code running in generated threads must use
+ * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
+ * #threadAssertEquals}, or {@link #threadAssertNull}, (not
+ * {@code fail}, {@code assertTrue}, etc.) It is OK (but not
+ * particularly recommended) for other code to use these forms too.
+ * Only the most typically used JUnit assertion methods are defined
+ * this way, but enough to live with.</li>
+ *
+ * <li> If you override {@link #setUp} or {@link #tearDown}, make sure
+ * to invoke {@code super.setUp} and {@code super.tearDown} within
+ * them. These methods are used to clear and check for thread
+ * assertion failures.</li>
+ *
+ * <li>All delays and timeouts must use one of the constants {@code
+ * SHORT_DELAY_MS}, {@code SMALL_DELAY_MS}, {@code MEDIUM_DELAY_MS},
+ * {@code LONG_DELAY_MS}. The idea here is that a SHORT is always
+ * discriminable from zero time, and always allows enough time for the
+ * small amounts of computation (creating a thread, calling a few
+ * methods, etc) needed to reach a timeout point. Similarly, a SMALL
+ * is always discriminable as larger than SHORT and smaller than
+ * MEDIUM. And so on. These constants are set to conservative values,
+ * but even so, if there is ever any doubt, they can all be increased
+ * in one spot to rerun tests on slower platforms.</li>
+ *
+ * <li> All threads generated must be joined inside each test case
+ * method (or {@code fail} to do so) before returning from the
+ * method. The {@code joinPool} method can be used to do this when
+ * using Executors.</li>
+ *
+ * </ol>
+ *
+ * <p><b>Other notes</b>
+ * <ul>
+ *
+ * <li> Usually, there is one testcase method per JSR166 method
+ * covering "normal" operation, and then as many exception-testing
+ * methods as there are exceptions the method can throw. Sometimes
+ * there are multiple tests per JSR166 method when the different
+ * "normal" behaviors differ significantly. And sometimes testcases
+ * cover multiple methods when they cannot be tested in
+ * isolation.</li>
+ *
+ * <li> The documentation style for testcases is to provide as javadoc
+ * a simple sentence or two describing the property that the testcase
+ * method purports to test. The javadocs do not say anything about how
+ * the property is tested. To find out, read the code.</li>
+ *
+ * <li> These tests are "conformance tests", and do not attempt to
+ * test throughput, latency, scalability or other performance factors
+ * (see the separate "jtreg" tests for a set intended to check these
+ * for the most central aspects of functionality.) So, most tests use
+ * the smallest sensible numbers of threads, collection sizes, etc
+ * needed to check basic conformance.</li>
+ *
+ * <li>The test classes currently do not declare inclusion in
+ * any particular package to simplify things for people integrating
+ * them in TCK test suites.</li>
+ *
+ * <li> As a convenience, the {@code main} of this class (JSR166TestCase)
+ * runs all JSR166 unit tests.</li>
+ *
+ * </ul>
+ */
+public class JSR166TestCase extends TestCase {
+
+ protected static final boolean expensiveTests = false;
+
+ public static long SHORT_DELAY_MS;
+ public static long SMALL_DELAY_MS;
+ public static long MEDIUM_DELAY_MS;
+ public static long LONG_DELAY_MS;
+
+
+ /**
+ * Returns the shortest timed delay. This could
+ * be reimplemented to use for example a Property.
+ */
+ protected long getShortDelay() {
+ return 50;
+ }
+
+ /**
+ * Sets delays as multiples of SHORT_DELAY.
+ */
+ protected void setDelays() {
+ SHORT_DELAY_MS = getShortDelay();
+ SMALL_DELAY_MS = SHORT_DELAY_MS * 5;
+ MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10;
+ LONG_DELAY_MS = SHORT_DELAY_MS * 200;
+ }
+
+ /**
+ * Returns a timeout in milliseconds to be used in tests that
+ * verify that operations block or time out.
+ */
+ long timeoutMillis() {
+ return SHORT_DELAY_MS / 4;
+ }
+
+ /**
+ * Returns a new Date instance representing a time delayMillis
+ * milliseconds in the future.
+ */
+ Date delayedDate(long delayMillis) {
+ return new Date(System.currentTimeMillis() + delayMillis);
+ }
+
+ /**
+ * The first exception encountered if any threadAssertXXX method fails.
+ */
+ private final AtomicReference<Throwable> threadFailure
+ = new AtomicReference<Throwable>(null);
+
+ /**
+ * Records an exception so that it can be rethrown later in the test
+ * harness thread, triggering a test case failure. Only the first
+ * failure is recorded; subsequent calls to this method from within
+ * the same test have no effect.
+ */
+ public void threadRecordFailure(Throwable t) {
+ threadFailure.compareAndSet(null, t);
+ }
+
+ public void setUp() {
+ setDelays();
+ }
+
+ /**
+ * Extra checks that get done for all test cases.
+ *
+ * Triggers test case failure if any thread assertions have failed,
+ * by rethrowing, in the test harness thread, any exception recorded
+ * earlier by threadRecordFailure.
+ *
+ * Triggers test case failure if interrupt status is set in the main thread.
+ */
+ public void tearDown() throws Exception {
+ Throwable t = threadFailure.getAndSet(null);
+ if (t != null) {
+ if (t instanceof Error)
+ throw (Error) t;
+ else if (t instanceof RuntimeException)
+ throw (RuntimeException) t;
+ else if (t instanceof Exception)
+ throw (Exception) t;
+ else {
+ AssertionFailedError afe =
+ new AssertionFailedError(t.toString());
+ afe.initCause(t);
+ throw afe;
+ }
+ }
+
+ if (Thread.interrupted())
+ throw new AssertionFailedError("interrupt status set in main thread");
+
+ checkForkJoinPoolThreadLeaks();
+ }
+
+ /**
+ * Find missing try { ... } finally { joinPool(e); }
+ */
+ void checkForkJoinPoolThreadLeaks() throws InterruptedException {
+ Thread[] survivors = new Thread[5];
+ int count = Thread.enumerate(survivors);
+ for (int i = 0; i < count; i++) {
+ Thread thread = survivors[i];
+ String name = thread.getName();
+ if (name.startsWith("ForkJoinPool-")) {
+ // give thread some time to terminate
+ thread.join(LONG_DELAY_MS);
+ if (!thread.isAlive()) continue;
+ thread.stop();
+ throw new AssertionFailedError
+ (String.format("Found leaked ForkJoinPool thread test=%s thread=%s%n",
+ toString(), name));
+ }
+ }
+ }
+
+ /**
+ * Just like fail(reason), but additionally recording (using
+ * threadRecordFailure) any AssertionFailedError thrown, so that
+ * the current testcase will fail.
+ */
+ public void threadFail(String reason) {
+ try {
+ fail(reason);
+ } catch (AssertionFailedError t) {
+ threadRecordFailure(t);
+ fail(reason);
+ }
+ }
+
+ /**
+ * Just like assertTrue(b), but additionally recording (using
+ * threadRecordFailure) any AssertionFailedError thrown, so that
+ * the current testcase will fail.
+ */
+ public void threadAssertTrue(boolean b) {
+ try {
+ assertTrue(b);
+ } catch (AssertionFailedError t) {
+ threadRecordFailure(t);
+ throw t;
+ }
+ }
+
+ /**
+ * Just like assertFalse(b), but additionally recording (using
+ * threadRecordFailure) any AssertionFailedError thrown, so that
+ * the current testcase will fail.
+ */
+ public void threadAssertFalse(boolean b) {
+ try {
+ assertFalse(b);
+ } catch (AssertionFailedError t) {
+ threadRecordFailure(t);
+ throw t;
+ }
+ }
+
+ /**
+ * Just like assertNull(x), but additionally recording (using
+ * threadRecordFailure) any AssertionFailedError thrown, so that
+ * the current testcase will fail.
+ */
+ public void threadAssertNull(Object x) {
+ try {
+ assertNull(x);
+ } catch (AssertionFailedError t) {
+ threadRecordFailure(t);
+ throw t;
+ }
+ }
+
+ /**
+ * Just like assertEquals(x, y), but additionally recording (using
+ * threadRecordFailure) any AssertionFailedError thrown, so that
+ * the current testcase will fail.
+ */
+ public void threadAssertEquals(long x, long y) {
+ try {
+ assertEquals(x, y);
+ } catch (AssertionFailedError t) {
+ threadRecordFailure(t);
+ throw t;
+ }
+ }
+
+ /**
+ * Just like assertEquals(x, y), but additionally recording (using
+ * threadRecordFailure) any AssertionFailedError thrown, so that
+ * the current testcase will fail.
+ */
+ public void threadAssertEquals(Object x, Object y) {
+ try {
+ assertEquals(x, y);
+ } catch (AssertionFailedError t) {
+ threadRecordFailure(t);
+ throw t;
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+ }
+
+ /**
+ * Just like assertSame(x, y), but additionally recording (using
+ * threadRecordFailure) any AssertionFailedError thrown, so that
+ * the current testcase will fail.
+ */
+ public void threadAssertSame(Object x, Object y) {
+ try {
+ assertSame(x, y);
+ } catch (AssertionFailedError t) {
+ threadRecordFailure(t);
+ throw t;
+ }
+ }
+
+ /**
+ * Calls threadFail with message "should throw exception".
+ */
+ public void threadShouldThrow() {
+ threadFail("should throw exception");
+ }
+
+ /**
+ * Calls threadFail with message "should throw" + exceptionName.
+ */
+ public void threadShouldThrow(String exceptionName) {
+ threadFail("should throw " + exceptionName);
+ }
+
+ /**
+ * Records the given exception using {@link #threadRecordFailure},
+ * then rethrows the exception, wrapping it in an
+ * AssertionFailedError if necessary.
+ */
+ public void threadUnexpectedException(Throwable t) {
+ threadRecordFailure(t);
+ t.printStackTrace();
+ if (t instanceof RuntimeException)
+ throw (RuntimeException) t;
+ else if (t instanceof Error)
+ throw (Error) t;
+ else {
+ AssertionFailedError afe =
+ new AssertionFailedError("unexpected exception: " + t);
+ afe.initCause(t);
+ throw afe;
+ }
+ }
+
+ /**
+ * Delays, via Thread.sleep, for the given millisecond delay, but
+ * if the sleep is shorter than specified, may re-sleep or yield
+ * until time elapses.
+ */
+ static void delay(long millis) throws InterruptedException {
+ long startTime = System.nanoTime();
+ long ns = millis * 1000 * 1000;
+ for (;;) {
+ if (millis > 0L)
+ Thread.sleep(millis);
+ else // too short to sleep
+ Thread.yield();
+ long d = ns - (System.nanoTime() - startTime);
+ if (d > 0L)
+ millis = d / (1000 * 1000);
+ else
+ break;
+ }
+ }
+
+ /**
+ * Waits out termination of a thread pool or fails doing so.
+ */
+ void joinPool(ExecutorService exec) {
+ try {
+ exec.shutdown();
+ assertTrue("ExecutorService did not terminate in a timely manner",
+ exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS));
+ } catch (SecurityException ok) {
+ // Allowed in case test doesn't have privs
+ } catch (InterruptedException ie) {
+ fail("Unexpected InterruptedException");
+ }
+ }
+
+ /**
+ * Checks that thread does not terminate within the default
+ * millisecond delay of {@code timeoutMillis()}.
+ */
+ void assertThreadStaysAlive(Thread thread) {
+ assertThreadStaysAlive(thread, timeoutMillis());
+ }
+
+ /**
+ * Checks that thread does not terminate within the given millisecond delay.
+ */
+ void assertThreadStaysAlive(Thread thread, long millis) {
+ try {
+ // No need to optimize the failing case via Thread.join.
+ delay(millis);
+ assertTrue(thread.isAlive());
+ } catch (InterruptedException ie) {
+ fail("Unexpected InterruptedException");
+ }
+ }
+
+ /**
+ * Checks that the threads do not terminate within the default
+ * millisecond delay of {@code timeoutMillis()}.
+ */
+ void assertThreadsStayAlive(Thread... threads) {
+ assertThreadsStayAlive(timeoutMillis(), threads);
+ }
+
+ /**
+ * Checks that the threads do not terminate within the given millisecond delay.
+ */
+ void assertThreadsStayAlive(long millis, Thread... threads) {
+ try {
+ // No need to optimize the failing case via Thread.join.
+ delay(millis);
+ for (Thread thread : threads)
+ assertTrue(thread.isAlive());
+ } catch (InterruptedException ie) {
+ fail("Unexpected InterruptedException");
+ }
+ }
+
+ /**
+ * Checks that future.get times out, with the default timeout of
+ * {@code timeoutMillis()}.
+ */
+ void assertFutureTimesOut(Future future) {
+ assertFutureTimesOut(future, timeoutMillis());
+ }
+
+ /**
+ * Checks that future.get times out, with the given millisecond timeout.
+ */
+ void assertFutureTimesOut(Future future, long timeoutMillis) {
+ long startTime = System.nanoTime();
+ try {
+ future.get(timeoutMillis, MILLISECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {
+ } catch (Exception e) {
+ threadUnexpectedException(e);
+ } finally { future.cancel(true); }
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ }
+
+ /**
+ * Fails with message "should throw exception".
+ */
+ public void shouldThrow() {
+ fail("Should throw exception");
+ }
+
+ /**
+ * Fails with message "should throw " + exceptionName.
+ */
+ public void shouldThrow(String exceptionName) {
+ fail("Should throw " + exceptionName);
+ }
+
+ /**
+ * The number of elements to place in collections, arrays, etc.
+ */
+ public static final int SIZE = 20;
+
+ // Some convenient Integer constants
+
+ public static final Integer zero = new Integer(0);
+ public static final Integer one = new Integer(1);
+ public static final Integer two = new Integer(2);
+ public static final Integer three = new Integer(3);
+ public static final Integer four = new Integer(4);
+ public static final Integer five = new Integer(5);
+ public static final Integer six = new Integer(6);
+ public static final Integer seven = new Integer(7);
+ public static final Integer eight = new Integer(8);
+ public static final Integer nine = new Integer(9);
+ public static final Integer m1 = new Integer(-1);
+ public static final Integer m2 = new Integer(-2);
+ public static final Integer m3 = new Integer(-3);
+ public static final Integer m4 = new Integer(-4);
+ public static final Integer m5 = new Integer(-5);
+ public static final Integer m6 = new Integer(-6);
+ public static final Integer m10 = new Integer(-10);
+
+
+ /**
+ * android-changed
+ * Android does not use a SecurityManager. This will simply execute
+ * the runnable ingoring permisions.
+ */
+ public void runWithPermissions(Runnable r, Permission... permissions) {
+ r.run();
+ }
+
+ /**
+ * android-changed
+ * Android does not use a SecurityManager. This will simply execute
+ * the runnable ingoring permisions.
+ */
+ public void runWithSecurityManagerWithPermissions(Runnable r,
+ Permission... permissions) {
+ r.run();
+ }
+
+ /**
+ * Runs a runnable without any permissions.
+ */
+ public void runWithoutPermissions(Runnable r) {
+ runWithPermissions(r);
+ }
+
+ /**
+ * A security policy where new permissions can be dynamically added
+ * or all cleared.
+ */
+ public static class AdjustablePolicy extends java.security.Policy {
+ Permissions perms = new Permissions();
+ AdjustablePolicy(Permission... permissions) {
+ for (Permission permission : permissions)
+ perms.add(permission);
+ }
+ void addPermission(Permission perm) { perms.add(perm); }
+ void clearPermissions() { perms = new Permissions(); }
+ public PermissionCollection getPermissions(CodeSource cs) {
+ return perms;
+ }
+ public PermissionCollection getPermissions(ProtectionDomain pd) {
+ return perms;
+ }
+ public boolean implies(ProtectionDomain pd, Permission p) {
+ return perms.implies(p);
+ }
+ public void refresh() {}
+ public String toString() {
+ List<Permission> ps = new ArrayList<Permission>();
+ for (Enumeration<Permission> e = perms.elements(); e.hasMoreElements();)
+ ps.add(e.nextElement());
+ return "AdjustablePolicy with permissions " + ps;
+ }
+ }
+
+ /**
+ * Returns a policy containing all the permissions we ever need.
+ */
+ public static Policy permissivePolicy() {
+ return new AdjustablePolicy
+ // Permissions j.u.c. needs directly
+ (new RuntimePermission("modifyThread"),
+ new RuntimePermission("getClassLoader"),
+ new RuntimePermission("setContextClassLoader"),
+ // Permissions needed to change permissions!
+ new SecurityPermission("getPolicy"),
+ new SecurityPermission("setPolicy"),
+ new RuntimePermission("setSecurityManager"),
+ // Permissions needed by the junit test harness
+ new RuntimePermission("accessDeclaredMembers"),
+ new PropertyPermission("*", "read"),
+ new java.io.FilePermission("<<ALL FILES>>", "read"));
+ }
+
+ /**
+ * Sleeps until the given time has elapsed.
+ * Throws AssertionFailedError if interrupted.
+ */
+ void sleep(long millis) {
+ try {
+ delay(millis);
+ } catch (InterruptedException ie) {
+ AssertionFailedError afe =
+ new AssertionFailedError("Unexpected InterruptedException");
+ afe.initCause(ie);
+ throw afe;
+ }
+ }
+
+ /**
+ * Spin-waits up to the specified number of milliseconds for the given
+ * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
+ */
+ void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
+ long startTime = System.nanoTime();
+ for (;;) {
+ Thread.State s = thread.getState();
+ if (s == Thread.State.BLOCKED ||
+ s == Thread.State.WAITING ||
+ s == Thread.State.TIMED_WAITING)
+ return;
+ else if (s == Thread.State.TERMINATED)
+ fail("Unexpected thread termination");
+ else if (millisElapsedSince(startTime) > timeoutMillis) {
+ threadAssertTrue(thread.isAlive());
+ return;
+ }
+ Thread.yield();
+ }
+ }
+
+ /**
+ * Waits up to LONG_DELAY_MS for the given thread to enter a wait
+ * state: BLOCKED, WAITING, or TIMED_WAITING.
+ */
+ void waitForThreadToEnterWaitState(Thread thread) {
+ waitForThreadToEnterWaitState(thread, LONG_DELAY_MS);
+ }
+
+ /**
+ * Returns the number of milliseconds since time given by
+ * startNanoTime, which must have been previously returned from a
+ * call to {@link System.nanoTime()}.
+ */
+ long millisElapsedSince(long startNanoTime) {
+ return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
+ }
+
+ /**
+ * Returns a new started daemon Thread running the given runnable.
+ */
+ Thread newStartedThread(Runnable runnable) {
+ Thread t = new Thread(runnable);
+ t.setDaemon(true);
+ t.start();
+ return t;
+ }
+
+ /**
+ * Waits for the specified time (in milliseconds) for the thread
+ * to terminate (using {@link Thread#join(long)}), else interrupts
+ * the thread (in the hope that it may terminate later) and fails.
+ */
+ void awaitTermination(Thread t, long timeoutMillis) {
+ try {
+ t.join(timeoutMillis);
+ } catch (InterruptedException ie) {
+ threadUnexpectedException(ie);
+ } finally {
+ if (t.getState() != Thread.State.TERMINATED) {
+ t.interrupt();
+ fail("Test timed out");
+ }
+ }
+ }
+
+ /**
+ * Waits for LONG_DELAY_MS milliseconds for the thread to
+ * terminate (using {@link Thread#join(long)}), else interrupts
+ * the thread (in the hope that it may terminate later) and fails.
+ */
+ void awaitTermination(Thread t) {
+ awaitTermination(t, LONG_DELAY_MS);
+ }
+
+ // Some convenient Runnable classes
+
+ public abstract class CheckedRunnable implements Runnable {
+ protected abstract void realRun() throws Throwable;
+
+ public final void run() {
+ try {
+ realRun();
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+ }
+ }
+
+ public abstract class RunnableShouldThrow implements Runnable {
+ protected abstract void realRun() throws Throwable;
+
+ final Class<?> exceptionClass;
+
+ <T extends Throwable> RunnableShouldThrow(Class<T> exceptionClass) {
+ this.exceptionClass = exceptionClass;
+ }
+
+ public final void run() {
+ try {
+ realRun();
+ threadShouldThrow(exceptionClass.getSimpleName());
+ } catch (Throwable t) {
+ if (! exceptionClass.isInstance(t))
+ threadUnexpectedException(t);
+ }
+ }
+ }
+
+ public abstract class ThreadShouldThrow extends Thread {
+ protected abstract void realRun() throws Throwable;
+
+ final Class<?> exceptionClass;
+
+ <T extends Throwable> ThreadShouldThrow(Class<T> exceptionClass) {
+ this.exceptionClass = exceptionClass;
+ }
+
+ public final void run() {
+ try {
+ realRun();
+ threadShouldThrow(exceptionClass.getSimpleName());
+ } catch (Throwable t) {
+ if (! exceptionClass.isInstance(t))
+ threadUnexpectedException(t);
+ }
+ }
+ }
+
+ public abstract class CheckedInterruptedRunnable implements Runnable {
+ protected abstract void realRun() throws Throwable;
+
+ public final void run() {
+ try {
+ realRun();
+ threadShouldThrow("InterruptedException");
+ } catch (InterruptedException success) {
+ threadAssertFalse(Thread.interrupted());
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+ }
+ }
+
+ public abstract class CheckedCallable<T> implements Callable<T> {
+ protected abstract T realCall() throws Throwable;
+
+ public final T call() {
+ try {
+ return realCall();
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ return null;
+ }
+ }
+ }
+
+ public abstract class CheckedInterruptedCallable<T>
+ implements Callable<T> {
+ protected abstract T realCall() throws Throwable;
+
+ public final T call() {
+ try {
+ T result = realCall();
+ threadShouldThrow("InterruptedException");
+ return result;
+ } catch (InterruptedException success) {
+ threadAssertFalse(Thread.interrupted());
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+ return null;
+ }
+ }
+
+ public static class NoOpRunnable implements Runnable {
+ public void run() {}
+ }
+
+ public static class NoOpCallable implements Callable {
+ public Object call() { return Boolean.TRUE; }
+ }
+
+ public static final String TEST_STRING = "a test string";
+
+ public static class StringTask implements Callable<String> {
+ public String call() { return TEST_STRING; }
+ }
+
+ public Callable<String> latchAwaitingStringTask(final CountDownLatch latch) {
+ return new CheckedCallable<String>() {
+ protected String realCall() {
+ try {
+ latch.await();
+ } catch (InterruptedException quittingTime) {}
+ return TEST_STRING;
+ }};
+ }
+
+ public Runnable awaiter(final CountDownLatch latch) {
+ return new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ await(latch);
+ }};
+ }
+
+ public void await(CountDownLatch latch) {
+ try {
+ assertTrue(latch.await(LONG_DELAY_MS, MILLISECONDS));
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+ }
+
+ public void await(Semaphore semaphore) {
+ try {
+ assertTrue(semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS));
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+ }
+
+// /**
+// * Spin-waits up to LONG_DELAY_MS until flag becomes true.
+// */
+// public void await(AtomicBoolean flag) {
+// await(flag, LONG_DELAY_MS);
+// }
+
+// /**
+// * Spin-waits up to the specified timeout until flag becomes true.
+// */
+// public void await(AtomicBoolean flag, long timeoutMillis) {
+// long startTime = System.nanoTime();
+// while (!flag.get()) {
+// if (millisElapsedSince(startTime) > timeoutMillis)
+// throw new AssertionFailedError("timed out");
+// Thread.yield();
+// }
+// }
+
+ public static class NPETask implements Callable<String> {
+ public String call() { throw new NullPointerException(); }
+ }
+
+ public static class CallableOne implements Callable<Integer> {
+ public Integer call() { return one; }
+ }
+
+ public class ShortRunnable extends CheckedRunnable {
+ protected void realRun() throws Throwable {
+ delay(SHORT_DELAY_MS);
+ }
+ }
+
+ public class ShortInterruptedRunnable extends CheckedInterruptedRunnable {
+ protected void realRun() throws InterruptedException {
+ delay(SHORT_DELAY_MS);
+ }
+ }
+
+ public class SmallRunnable extends CheckedRunnable {
+ protected void realRun() throws Throwable {
+ delay(SMALL_DELAY_MS);
+ }
+ }
+
+ public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
+ protected void realRun() {
+ try {
+ delay(SMALL_DELAY_MS);
+ } catch (InterruptedException ok) {}
+ }
+ }
+
+ public class SmallCallable extends CheckedCallable {
+ protected Object realCall() throws InterruptedException {
+ delay(SMALL_DELAY_MS);
+ return Boolean.TRUE;
+ }
+ }
+
+ public class MediumRunnable extends CheckedRunnable {
+ protected void realRun() throws Throwable {
+ delay(MEDIUM_DELAY_MS);
+ }
+ }
+
+ public class MediumInterruptedRunnable extends CheckedInterruptedRunnable {
+ protected void realRun() throws InterruptedException {
+ delay(MEDIUM_DELAY_MS);
+ }
+ }
+
+ public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
+ return new CheckedRunnable() {
+ protected void realRun() {
+ try {
+ delay(timeoutMillis);
+ } catch (InterruptedException ok) {}
+ }};
+ }
+
+ public class MediumPossiblyInterruptedRunnable extends CheckedRunnable {
+ protected void realRun() {
+ try {
+ delay(MEDIUM_DELAY_MS);
+ } catch (InterruptedException ok) {}
+ }
+ }
+
+ public class LongPossiblyInterruptedRunnable extends CheckedRunnable {
+ protected void realRun() {
+ try {
+ delay(LONG_DELAY_MS);
+ } catch (InterruptedException ok) {}
+ }
+ }
+
+ /**
+ * For use as ThreadFactory in constructors
+ */
+ public static class SimpleThreadFactory implements ThreadFactory {
+ public Thread newThread(Runnable r) {
+ return new Thread(r);
+ }
+ }
+
+ public interface TrackedRunnable extends Runnable {
+ boolean isDone();
+ }
+
+ public static TrackedRunnable trackedRunnable(final long timeoutMillis) {
+ return new TrackedRunnable() {
+ private volatile boolean done = false;
+ public boolean isDone() { return done; }
+ public void run() {
+ try {
+ delay(timeoutMillis);
+ done = true;
+ } catch (InterruptedException ok) {}
+ }
+ };
+ }
+
+ public static class TrackedShortRunnable implements Runnable {
+ public volatile boolean done = false;
+ public void run() {
+ try {
+ delay(SHORT_DELAY_MS);
+ done = true;
+ } catch (InterruptedException ok) {}
+ }
+ }
+
+ public static class TrackedSmallRunnable implements Runnable {
+ public volatile boolean done = false;
+ public void run() {
+ try {
+ delay(SMALL_DELAY_MS);
+ done = true;
+ } catch (InterruptedException ok) {}
+ }
+ }
+
+ public static class TrackedMediumRunnable implements Runnable {
+ public volatile boolean done = false;
+ public void run() {
+ try {
+ delay(MEDIUM_DELAY_MS);
+ done = true;
+ } catch (InterruptedException ok) {}
+ }
+ }
+
+ public static class TrackedLongRunnable implements Runnable {
+ public volatile boolean done = false;
+ public void run() {
+ try {
+ delay(LONG_DELAY_MS);
+ done = true;
+ } catch (InterruptedException ok) {}
+ }
+ }
+
+ public static class TrackedNoOpRunnable implements Runnable {
+ public volatile boolean done = false;
+ public void run() {
+ done = true;
+ }
+ }
+
+ public static class TrackedCallable implements Callable {
+ public volatile boolean done = false;
+ public Object call() {
+ try {
+ delay(SMALL_DELAY_MS);
+ done = true;
+ } catch (InterruptedException ok) {}
+ return Boolean.TRUE;
+ }
+ }
+
+ /**
+ * Analog of CheckedRunnable for RecursiveAction
+ */
+ public abstract class CheckedRecursiveAction extends RecursiveAction {
+ protected abstract void realCompute() throws Throwable;
+
+ @Override protected final void compute() {
+ try {
+ realCompute();
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ }
+ }
+ }
+
+ /**
+ * Analog of CheckedCallable for RecursiveTask
+ */
+ public abstract class CheckedRecursiveTask<T> extends RecursiveTask<T> {
+ protected abstract T realCompute() throws Throwable;
+
+ @Override protected final T compute() {
+ try {
+ return realCompute();
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ return null;
+ }
+ }
+ }
+
+ /**
+ * For use as RejectedExecutionHandler in constructors
+ */
+ public static class NoOpREHandler implements RejectedExecutionHandler {
+ public void rejectedExecution(Runnable r,
+ ThreadPoolExecutor executor) {}
+ }
+
+ /**
+ * A CyclicBarrier that uses timed await and fails with
+ * AssertionFailedErrors instead of throwing checked exceptions.
+ */
+ public class CheckedBarrier extends CyclicBarrier {
+ public CheckedBarrier(int parties) { super(parties); }
+
+ public int await() {
+ try {
+ return super.await(2 * LONG_DELAY_MS, MILLISECONDS);
+ } catch (TimeoutException e) {
+ throw new AssertionFailedError("timed out");
+ } catch (Exception e) {
+ AssertionFailedError afe =
+ new AssertionFailedError("Unexpected exception: " + e);
+ afe.initCause(e);
+ throw afe;
+ }
+ }
+ }
+
+ void checkEmpty(BlockingQueue q) {
+ try {
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertNull(q.peek());
+ assertNull(q.poll());
+ assertNull(q.poll(0, MILLISECONDS));
+ assertEquals(q.toString(), "[]");
+ assertTrue(Arrays.equals(q.toArray(), new Object[0]));
+ assertFalse(q.iterator().hasNext());
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ try {
+ q.iterator().next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ } catch (InterruptedException ie) {
+ threadUnexpectedException(ie);
+ }
+ }
+
+ void assertSerialEquals(Object x, Object y) {
+ assertTrue(Arrays.equals(serialBytes(x), serialBytes(y)));
+ }
+
+ void assertNotSerialEquals(Object x, Object y) {
+ assertFalse(Arrays.equals(serialBytes(x), serialBytes(y)));
+ }
+
+ byte[] serialBytes(Object o) {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(o);
+ oos.flush();
+ oos.close();
+ return bos.toByteArray();
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ return new byte[0];
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ <T> T serialClone(T o) {
+ try {
+ ObjectInputStream ois = new ObjectInputStream
+ (new ByteArrayInputStream(serialBytes(o)));
+ T clone = (T) ois.readObject();
+ assertSame(o.getClass(), clone.getClass());
+ return clone;
+ } catch (Throwable t) {
+ threadUnexpectedException(t);
+ return null;
+ }
+ }
+
+ public void assertThrows(Class<? extends Throwable> expectedExceptionClass,
+ Runnable... throwingActions) {
+ for (Runnable throwingAction : throwingActions) {
+ boolean threw = false;
+ try { throwingAction.run(); }
+ catch (Throwable t) {
+ threw = true;
+ if (!expectedExceptionClass.isInstance(t)) {
+ AssertionFailedError afe =
+ new AssertionFailedError
+ ("Expected " + expectedExceptionClass.getName() +
+ ", got " + t.getClass().getName());
+ afe.initCause(t);
+ threadUnexpectedException(afe);
+ }
+ }
+ if (!threw)
+ shouldThrow(expectedExceptionClass.getName());
+ }
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeBoundedTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeBoundedTest.java
new file mode 100644
index 0000000..7b43583
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeBoundedTest.java
@@ -0,0 +1,18 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+
+public class LinkedBlockingDequeBoundedTest extends JSR166TestCase {
+
+ protected BlockingQueue emptyCollection() {
+ return new LinkedBlockingDeque(SIZE);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java
new file mode 100644
index 0000000..4016f6d
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java
@@ -0,0 +1,1757 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingDeque;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class LinkedBlockingDequeTest extends JSR166TestCase {
+
+ /**
+ * Returns a new deque of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private LinkedBlockingDeque<Integer> populatedDeque(int n) {
+ LinkedBlockingDeque<Integer> q =
+ new LinkedBlockingDeque<Integer>(n);
+ assertTrue(q.isEmpty());
+ for (int i = 0; i < n; i++)
+ assertTrue(q.offer(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(0, q.remainingCapacity());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque();
+ assertTrue(q.isEmpty());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.add(new Integer(2));
+ q.removeFirst();
+ q.removeFirst();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.removeFirst();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * offerFirst(null) throws NullPointerException
+ */
+ public void testOfferFirstNull() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque();
+ try {
+ q.offerFirst(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * offerLast(null) throws NullPointerException
+ */
+ public void testOfferLastNull() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque();
+ try {
+ q.offerLast(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * OfferFirst succeeds
+ */
+ public void testOfferFirst() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque();
+ assertTrue(q.offerFirst(new Integer(0)));
+ assertTrue(q.offerFirst(new Integer(1)));
+ }
+
+ /**
+ * OfferLast succeeds
+ */
+ public void testOfferLast() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque();
+ assertTrue(q.offerLast(new Integer(0)));
+ assertTrue(q.offerLast(new Integer(1)));
+ }
+
+ /**
+ * pollFirst succeeds unless empty
+ */
+ public void testPollFirst() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * pollLast succeeds unless empty
+ */
+ public void testPollLast() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.pollLast());
+ }
+ assertNull(q.pollLast());
+ }
+
+ /**
+ * peekFirst returns next element, or null if empty
+ */
+ public void testPeekFirst() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peekFirst());
+ assertEquals(i, q.pollFirst());
+ assertTrue(q.peekFirst() == null ||
+ !q.peekFirst().equals(i));
+ }
+ assertNull(q.peekFirst());
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.pollFirst());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * peekLast returns next element, or null if empty
+ */
+ public void testPeekLast() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.peekLast());
+ assertEquals(i, q.pollLast());
+ assertTrue(q.peekLast() == null ||
+ !q.peekLast().equals(i));
+ }
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * getFirst() returns first element, or throws NSEE if empty
+ */
+ public void testFirstElement() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.getFirst());
+ assertEquals(i, q.pollFirst());
+ }
+ try {
+ q.getFirst();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekFirst());
+ }
+
+ /**
+ * getLast() returns last element, or throws NSEE if empty
+ */
+ public void testLastElement() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.getLast());
+ assertEquals(i, q.pollLast());
+ }
+ try {
+ q.getLast();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * removeFirst() removes first element, or throws NSEE if empty
+ */
+ public void testRemoveFirst() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.removeFirst());
+ }
+ try {
+ q.removeFirst();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekFirst());
+ }
+
+ /**
+ * removeLast() removes last element, or throws NSEE if empty
+ */
+ public void testRemoveLast() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = SIZE - 1; i >= 0; --i) {
+ assertEquals(i, q.removeLast());
+ }
+ try {
+ q.removeLast();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * remove removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * removeFirstOccurrence(x) removes x and returns true if present
+ */
+ public void testRemoveFirstOccurrence() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.removeFirstOccurrence(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.removeFirstOccurrence(new Integer(i)));
+ assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * removeLastOccurrence(x) removes x and returns true if present
+ */
+ public void testRemoveLastOccurrence() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.removeLastOccurrence(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.removeLastOccurrence(new Integer(i)));
+ assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * peekFirst returns element inserted with addFirst
+ */
+ public void testAddFirst() {
+ LinkedBlockingDeque q = populatedDeque(3);
+ q.pollLast();
+ q.addFirst(four);
+ assertSame(four, q.peekFirst());
+ }
+
+ /**
+ * peekLast returns element inserted with addLast
+ */
+ public void testAddLast() {
+ LinkedBlockingDeque q = populatedDeque(3);
+ q.pollLast();
+ q.addLast(four);
+ assertSame(four, q.peekLast());
+ }
+
+ /**
+ * A new deque has the indicated capacity, or Integer.MAX_VALUE if
+ * none given
+ */
+ public void testConstructor1() {
+ assertEquals(SIZE, new LinkedBlockingDeque(SIZE).remainingCapacity());
+ assertEquals(Integer.MAX_VALUE, new LinkedBlockingDeque().remainingCapacity());
+ }
+
+ /**
+ * Constructor throws IllegalArgumentException if capacity argument nonpositive
+ */
+ public void testConstructor2() {
+ try {
+ new LinkedBlockingDeque(0);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Initializing from null Collection throws NullPointerException
+ */
+ public void testConstructor3() {
+ try {
+ new LinkedBlockingDeque(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NullPointerException
+ */
+ public void testConstructor4() {
+ Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+ try {
+ new LinkedBlockingDeque(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws
+ * NullPointerException
+ */
+ public void testConstructor5() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = i;
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ new LinkedBlockingDeque(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Deque contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = i;
+ LinkedBlockingDeque q = new LinkedBlockingDeque(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * Deque transitions from empty to full when elements added
+ */
+ public void testEmptyFull() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+ assertTrue(q.isEmpty());
+ assertEquals("should have room for 2", 2, q.remainingCapacity());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ q.add(two);
+ assertFalse(q.isEmpty());
+ assertEquals(0, q.remainingCapacity());
+ assertFalse(q.offer(three));
+ }
+
+ /**
+ * remainingCapacity decreases on add, increases on remove
+ */
+ public void testRemainingCapacity() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remainingCapacity());
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.remainingCapacity());
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * push(null) throws NPE
+ */
+ public void testPushNull() {
+ try {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+ q.push(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * push succeeds if not full; throws ISE if full
+ */
+ public void testPush() {
+ try {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ Integer I = new Integer(i);
+ q.push(I);
+ assertEquals(I, q.peek());
+ }
+ assertEquals(0, q.remainingCapacity());
+ q.push(new Integer(SIZE));
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * peekFirst returns element inserted with push
+ */
+ public void testPushWithPeek() {
+ LinkedBlockingDeque q = populatedDeque(3);
+ q.pollLast();
+ q.push(four);
+ assertSame(four, q.peekFirst());
+ }
+
+ /**
+ * pop removes next element, or throws NSEE if empty
+ */
+ public void testPop() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pop());
+ }
+ try {
+ q.pop();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * Offer succeeds if not full; fails if full
+ */
+ public void testOffer() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+ assertTrue(q.offer(zero));
+ assertFalse(q.offer(one));
+ }
+
+ /**
+ * add succeeds if not full; throws ISE if full
+ */
+ public void testAdd() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i)
+ assertTrue(q.add(new Integer(i)));
+ assertEquals(0, q.remainingCapacity());
+ try {
+ q.add(new Integer(SIZE));
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * addAll(this) throws IAE
+ */
+ public void testAddAllSelf() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ try {
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ q.addAll(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll throws IllegalStateException if not enough room
+ */
+ public void testAddAll4() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE - 1);
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ q.addAll(elements);
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * Deque contains all elements, in traversal order, of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * all elements successfully put are contained
+ */
+ public void testPut() throws InterruptedException {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ Integer I = new Integer(i);
+ q.put(I);
+ assertTrue(q.contains(I));
+ }
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * put blocks interruptibly if full
+ */
+ public void testBlockingPut() throws InterruptedException {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i)
+ q.put(i);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * put blocks interruptibly waiting for take when full
+ */
+ public void testPutWithTake() throws InterruptedException {
+ final int capacity = 2;
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+ final CountDownLatch pleaseTake = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < capacity; i++)
+ q.put(i);
+ pleaseTake.countDown();
+ q.put(86);
+
+ pleaseInterrupt.countDown();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseTake);
+ assertEquals(0, q.remainingCapacity());
+ assertEquals(0, q.take());
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * timed offer times out if full and elements not taken
+ */
+ public void testTimedOffer() throws InterruptedException {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(new Object());
+ q.put(new Object());
+ long startTime = System.nanoTime();
+ assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ pleaseInterrupt.countDown();
+ try {
+ q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * take retrieves elements in FIFO order
+ */
+ public void testTake() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+ }
+
+ /**
+ * take removes existing elements until empty, then blocks interruptibly
+ */
+ public void testBlockingTake() throws InterruptedException {
+ final LinkedBlockingDeque q = populatedDeque(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * timed poll with zero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll0() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll(0, MILLISECONDS));
+ }
+ assertNull(q.poll(0, MILLISECONDS));
+ }
+
+ /**
+ * timed poll with nonzero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ long startTime = System.nanoTime();
+ assertEquals(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ checkEmpty(q);
+ }
+
+ /**
+ * Interrupted timed poll throws InterruptedException instead of
+ * returning timeout status
+ */
+ public void testInterruptedTimedPoll() throws InterruptedException {
+ final BlockingQueue<Integer> q = populatedDeque(SIZE);
+ final CountDownLatch aboutToWait = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ long t0 = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+ long t0 = System.nanoTime();
+ aboutToWait.countDown();
+ try {
+ q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {
+ assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+ }
+ }});
+
+ aboutToWait.await();
+ waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+ t.interrupt();
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ checkEmpty(q);
+ }
+
+ /**
+ * putFirst(null) throws NPE
+ */
+ public void testPutFirstNull() throws InterruptedException {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ try {
+ q.putFirst(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * all elements successfully putFirst are contained
+ */
+ public void testPutFirst() throws InterruptedException {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ Integer I = new Integer(i);
+ q.putFirst(I);
+ assertTrue(q.contains(I));
+ }
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * putFirst blocks interruptibly if full
+ */
+ public void testBlockingPutFirst() throws InterruptedException {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i)
+ q.putFirst(i);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.putFirst(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.putFirst(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * putFirst blocks interruptibly waiting for take when full
+ */
+ public void testPutFirstWithTake() throws InterruptedException {
+ final int capacity = 2;
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+ final CountDownLatch pleaseTake = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < capacity; i++)
+ q.putFirst(i);
+ pleaseTake.countDown();
+ q.putFirst(86);
+
+ pleaseInterrupt.countDown();
+ try {
+ q.putFirst(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseTake);
+ assertEquals(0, q.remainingCapacity());
+ assertEquals(capacity - 1, q.take());
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * timed offerFirst times out if full and elements not taken
+ */
+ public void testTimedOfferFirst() throws InterruptedException {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.putFirst(new Object());
+ q.putFirst(new Object());
+ long startTime = System.nanoTime();
+ assertFalse(q.offerFirst(new Object(), timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ pleaseInterrupt.countDown();
+ try {
+ q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * take retrieves elements in FIFO order
+ */
+ public void testTakeFirst() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.takeFirst());
+ }
+ }
+
+ /**
+ * takeFirst() blocks interruptibly when empty
+ */
+ public void testTakeFirstFromEmptyBlocksInterruptibly() {
+ final BlockingDeque q = new LinkedBlockingDeque();
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ threadStarted.countDown();
+ try {
+ q.takeFirst();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(threadStarted);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * takeFirst() throws InterruptedException immediately if interrupted
+ * before waiting
+ */
+ public void testTakeFirstFromEmptyAfterInterrupt() {
+ final BlockingDeque q = new LinkedBlockingDeque();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread.currentThread().interrupt();
+ try {
+ q.takeFirst();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * takeLast() blocks interruptibly when empty
+ */
+ public void testTakeLastFromEmptyBlocksInterruptibly() {
+ final BlockingDeque q = new LinkedBlockingDeque();
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ threadStarted.countDown();
+ try {
+ q.takeLast();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(threadStarted);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * takeLast() throws InterruptedException immediately if interrupted
+ * before waiting
+ */
+ public void testTakeLastFromEmptyAfterInterrupt() {
+ final BlockingDeque q = new LinkedBlockingDeque();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread.currentThread().interrupt();
+ try {
+ q.takeLast();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * takeFirst removes existing elements until empty, then blocks interruptibly
+ */
+ public void testBlockingTakeFirst() throws InterruptedException {
+ final LinkedBlockingDeque q = populatedDeque(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.takeFirst());
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.takeFirst();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.takeFirst();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timed pollFirst with zero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPollFirst0() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst(0, MILLISECONDS));
+ }
+ assertNull(q.pollFirst(0, MILLISECONDS));
+ }
+
+ /**
+ * timed pollFirst with nonzero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPollFirst() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ long startTime = System.nanoTime();
+ assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ long startTime = System.nanoTime();
+ assertNull(q.pollFirst(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ checkEmpty(q);
+ }
+
+ /**
+ * Interrupted timed pollFirst throws InterruptedException instead of
+ * returning timeout status
+ */
+ public void testInterruptedTimedPollFirst() throws InterruptedException {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.pollFirst(SMALL_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timed pollFirst before a delayed offerFirst fails; after offerFirst succeeds;
+ * on interruption throws
+ */
+ public void testTimedPollFirstWithOfferFirst() throws InterruptedException {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+ final CheckedBarrier barrier = new CheckedBarrier(2);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ assertNull(q.pollFirst(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ barrier.await();
+
+ assertSame(zero, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
+
+ Thread.currentThread().interrupt();
+ try {
+ q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+
+ barrier.await();
+ try {
+ q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }});
+
+ barrier.await();
+ long startTime = System.nanoTime();
+ assertTrue(q.offerFirst(zero, LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ barrier.await();
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * putLast(null) throws NPE
+ */
+ public void testPutLastNull() throws InterruptedException {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ try {
+ q.putLast(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * all elements successfully putLast are contained
+ */
+ public void testPutLast() throws InterruptedException {
+ LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ Integer I = new Integer(i);
+ q.putLast(I);
+ assertTrue(q.contains(I));
+ }
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * putLast blocks interruptibly if full
+ */
+ public void testBlockingPutLast() throws InterruptedException {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i)
+ q.putLast(i);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.putLast(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.putLast(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * putLast blocks interruptibly waiting for take when full
+ */
+ public void testPutLastWithTake() throws InterruptedException {
+ final int capacity = 2;
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+ final CountDownLatch pleaseTake = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < capacity; i++)
+ q.putLast(i);
+ pleaseTake.countDown();
+ q.putLast(86);
+
+ pleaseInterrupt.countDown();
+ try {
+ q.putLast(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseTake);
+ assertEquals(0, q.remainingCapacity());
+ assertEquals(0, q.take());
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * timed offerLast times out if full and elements not taken
+ */
+ public void testTimedOfferLast() throws InterruptedException {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.putLast(new Object());
+ q.putLast(new Object());
+ long startTime = System.nanoTime();
+ assertFalse(q.offerLast(new Object(), timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ pleaseInterrupt.countDown();
+ try {
+ q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * takeLast retrieves elements in FIFO order
+ */
+ public void testTakeLast() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i-1, q.takeLast());
+ }
+ }
+
+ /**
+ * takeLast removes existing elements until empty, then blocks interruptibly
+ */
+ public void testBlockingTakeLast() throws InterruptedException {
+ final LinkedBlockingDeque q = populatedDeque(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i-1, q.takeLast());
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.takeLast();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.takeLast();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timed pollLast with zero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPollLast0() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i-1, q.pollLast(0, MILLISECONDS));
+ }
+ assertNull(q.pollLast(0, MILLISECONDS));
+ }
+
+ /**
+ * timed pollLast with nonzero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPollLast() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ long startTime = System.nanoTime();
+ assertEquals(SIZE-i-1, q.pollLast(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ long startTime = System.nanoTime();
+ assertNull(q.pollLast(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ checkEmpty(q);
+ }
+
+ /**
+ * Interrupted timed pollLast throws InterruptedException instead of
+ * returning timeout status
+ */
+ public void testInterruptedTimedPollLast() throws InterruptedException {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i-1, q.pollLast(LONG_DELAY_MS, MILLISECONDS));
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.pollLast(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.pollLast(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timed poll before a delayed offerLast fails; after offerLast succeeds;
+ * on interruption throws
+ */
+ public void testTimedPollWithOfferLast() throws InterruptedException {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+ final CheckedBarrier barrier = new CheckedBarrier(2);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ barrier.await();
+
+ assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+
+ Thread.currentThread().interrupt();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ barrier.await();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ barrier.await();
+ long startTime = System.nanoTime();
+ assertTrue(q.offerLast(zero, LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+
+ barrier.await();
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * element returns next element, or throws NSEE if empty
+ */
+ public void testElement() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ q.poll();
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.poll();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertEquals(SIZE, q.remainingCapacity());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(one));
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ LinkedBlockingDeque p = new LinkedBlockingDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ LinkedBlockingDeque p = populatedDeque(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ LinkedBlockingDeque p = populatedDeque(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * toArray contains all elements in FIFO order
+ */
+ public void testToArray() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.poll());
+ }
+
+ /**
+ * toArray(a) contains all elements in FIFO order
+ */
+ public void testToArray2() {
+ LinkedBlockingDeque<Integer> q = populatedDeque(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.remove());
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ try {
+ q.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() throws InterruptedException {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertEquals(it.next(), q.take());
+ }
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+ q.add(two);
+ q.add(one);
+ q.add(three);
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertSame(it.next(), one);
+ assertSame(it.next(), three);
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * iterator ordering is FIFO
+ */
+ public void testIteratorOrdering() {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ assertEquals(0, q.remainingCapacity());
+ int k = 0;
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+ assertEquals(3, k);
+ }
+
+ /**
+ * Modifications do not cause iterators to fail
+ */
+ public void testWeaklyConsistentIteration() {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ q.remove();
+ it.next();
+ }
+ assertEquals(0, q.size());
+ }
+
+ /**
+ * Descending iterator iterates through all elements
+ */
+ public void testDescendingIterator() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ int i = 0;
+ Iterator it = q.descendingIterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ assertFalse(it.hasNext());
+ try {
+ it.next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * Descending iterator ordering is reverse FIFO
+ */
+ public void testDescendingIteratorOrdering() {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque();
+ for (int iters = 0; iters < 100; ++iters) {
+ q.add(new Integer(3));
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ int k = 0;
+ for (Iterator it = q.descendingIterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+
+ assertEquals(3, k);
+ q.remove();
+ q.remove();
+ q.remove();
+ }
+ }
+
+ /**
+ * descendingIterator.remove removes current element
+ */
+ public void testDescendingIteratorRemove() {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque();
+ for (int iters = 0; iters < 100; ++iters) {
+ q.add(new Integer(3));
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ Iterator it = q.descendingIterator();
+ assertEquals(it.next(), new Integer(1));
+ it.remove();
+ assertEquals(it.next(), new Integer(2));
+ it = q.descendingIterator();
+ assertEquals(it.next(), new Integer(2));
+ assertEquals(it.next(), new Integer(3));
+ it.remove();
+ assertFalse(it.hasNext());
+ q.remove();
+ }
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * offer transfers elements across Executor tasks
+ */
+ public void testOfferInExecutor() {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+ q.add(one);
+ q.add(two);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(q.offer(three));
+ threadsStarted.await();
+ assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(0, q.remainingCapacity());
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ assertSame(one, q.take());
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * timed poll retrieves elements across Executor threads
+ */
+ public void testPollInExecutor() {
+ final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertNull(q.poll());
+ threadsStarted.await();
+ assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ checkEmpty(q);
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ q.put(one);
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * A deserialized serialized deque has same elements in same order
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedDeque(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(y, x);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * drainTo(c) empties deque into another collection c
+ */
+ public void testDrainTo() {
+ LinkedBlockingDeque q = populatedDeque(SIZE);
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(SIZE, l.size());
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ q.add(zero);
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(zero));
+ assertTrue(q.contains(one));
+ l.clear();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(2, l.size());
+ for (int i = 0; i < 2; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ }
+
+ /**
+ * drainTo empties full deque, unblocking a waiting put.
+ */
+ public void testDrainToWithActivePut() throws InterruptedException {
+ final LinkedBlockingDeque q = populatedDeque(SIZE);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(new Integer(SIZE+1));
+ }});
+
+ t.start();
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertTrue(l.size() >= SIZE);
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ t.join();
+ assertTrue(q.size() + l.size() >= SIZE);
+ }
+
+ /**
+ * drainTo(c, n) empties first min(n, size) elements of queue into c
+ */
+ public void testDrainToN() {
+ LinkedBlockingDeque q = new LinkedBlockingDeque();
+ for (int i = 0; i < SIZE + 2; ++i) {
+ for (int j = 0; j < SIZE; j++)
+ assertTrue(q.offer(new Integer(j)));
+ ArrayList l = new ArrayList();
+ q.drainTo(l, i);
+ int k = (i < SIZE) ? i : SIZE;
+ assertEquals(k, l.size());
+ assertEquals(SIZE-k, q.size());
+ for (int j = 0; j < k; ++j)
+ assertEquals(l.get(j), new Integer(j));
+ while (q.poll() != null) ;
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeUnboundedTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeUnboundedTest.java
new file mode 100644
index 0000000..4302f45
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeUnboundedTest.java
@@ -0,0 +1,18 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+
+public class LinkedBlockingDequeUnboundedTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new LinkedBlockingDeque();
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueBoundedTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueBoundedTest.java
new file mode 100644
index 0000000..67984b2
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueBoundedTest.java
@@ -0,0 +1,20 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class LinkedBlockingQueueBoundedTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new LinkedBlockingQueue(SIZE);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java
new file mode 100644
index 0000000..fe0b871
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java
@@ -0,0 +1,812 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class LinkedBlockingQueueTest extends JSR166TestCase {
+
+ /**
+ * Returns a new queue of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private LinkedBlockingQueue<Integer> populatedQueue(int n) {
+ LinkedBlockingQueue<Integer> q =
+ new LinkedBlockingQueue<Integer>(n);
+ assertTrue(q.isEmpty());
+ for (int i = 0; i < n; i++)
+ assertTrue(q.offer(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(0, q.remainingCapacity());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * A new queue has the indicated capacity, or Integer.MAX_VALUE if
+ * none given
+ */
+ public void testConstructor1() {
+ assertEquals(SIZE, new LinkedBlockingQueue(SIZE).remainingCapacity());
+ assertEquals(Integer.MAX_VALUE, new LinkedBlockingQueue().remainingCapacity());
+ }
+
+ /**
+ * Constructor throws IllegalArgumentException if capacity argument nonpositive
+ */
+ public void testConstructor2() {
+ try {
+ new LinkedBlockingQueue(0);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Initializing from null Collection throws NullPointerException
+ */
+ public void testConstructor3() {
+ try {
+ new LinkedBlockingQueue(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NullPointerException
+ */
+ public void testConstructor4() {
+ Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+ try {
+ new LinkedBlockingQueue(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws
+ * NullPointerException
+ */
+ public void testConstructor5() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ new LinkedBlockingQueue(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * Queue transitions from empty to full when elements added
+ */
+ public void testEmptyFull() {
+ LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+ assertTrue(q.isEmpty());
+ assertEquals("should have room for 2", 2, q.remainingCapacity());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ q.add(two);
+ assertFalse(q.isEmpty());
+ assertEquals(0, q.remainingCapacity());
+ assertFalse(q.offer(three));
+ }
+
+ /**
+ * remainingCapacity decreases on add, increases on remove
+ */
+ public void testRemainingCapacity() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remainingCapacity());
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.remainingCapacity());
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * Offer succeeds if not full; fails if full
+ */
+ public void testOffer() {
+ LinkedBlockingQueue q = new LinkedBlockingQueue(1);
+ assertTrue(q.offer(zero));
+ assertFalse(q.offer(one));
+ }
+
+ /**
+ * add succeeds if not full; throws IllegalStateException if full
+ */
+ public void testAdd() {
+ LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i)
+ assertTrue(q.add(new Integer(i)));
+ assertEquals(0, q.remainingCapacity());
+ try {
+ q.add(new Integer(SIZE));
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * addAll(this) throws IllegalArgumentException
+ */
+ public void testAddAllSelf() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ try {
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ q.addAll(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll throws IllegalStateException if not enough room
+ */
+ public void testAddAll4() {
+ LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE - 1);
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ q.addAll(elements);
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * Queue contains all elements, in traversal order, of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * all elements successfully put are contained
+ */
+ public void testPut() throws InterruptedException {
+ LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ Integer I = new Integer(i);
+ q.put(I);
+ assertTrue(q.contains(I));
+ }
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * put blocks interruptibly if full
+ */
+ public void testBlockingPut() throws InterruptedException {
+ final LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i)
+ q.put(i);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(SIZE, q.size());
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * put blocks interruptibly waiting for take when full
+ */
+ public void testPutWithTake() throws InterruptedException {
+ final int capacity = 2;
+ final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+ final CountDownLatch pleaseTake = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < capacity; i++)
+ q.put(i);
+ pleaseTake.countDown();
+ q.put(86);
+
+ pleaseInterrupt.countDown();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseTake);
+ assertEquals(0, q.remainingCapacity());
+ assertEquals(0, q.take());
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * timed offer times out if full and elements not taken
+ */
+ public void testTimedOffer() {
+ final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(new Object());
+ q.put(new Object());
+ long startTime = System.nanoTime();
+ assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ pleaseInterrupt.countDown();
+ try {
+ q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * take retrieves elements in FIFO order
+ */
+ public void testTake() throws InterruptedException {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+ }
+
+ /**
+ * Take removes existing elements until empty, then blocks interruptibly
+ */
+ public void testBlockingTake() throws InterruptedException {
+ final BlockingQueue q = populatedQueue(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * timed poll with zero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll0() throws InterruptedException {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll(0, MILLISECONDS));
+ }
+ assertNull(q.poll(0, MILLISECONDS));
+ }
+
+ /**
+ * timed poll with nonzero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll() throws InterruptedException {
+ LinkedBlockingQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ long startTime = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ checkEmpty(q);
+ }
+
+ /**
+ * Interrupted timed poll throws InterruptedException instead of
+ * returning timeout status
+ */
+ public void testInterruptedTimedPoll() throws InterruptedException {
+ final BlockingQueue<Integer> q = populatedQueue(SIZE);
+ final CountDownLatch aboutToWait = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ long t0 = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+ long t0 = System.nanoTime();
+ aboutToWait.countDown();
+ try {
+ q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {
+ assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+ }
+ }});
+
+ aboutToWait.await();
+ waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+ t.interrupt();
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ checkEmpty(q);
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.poll());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * element returns next element, or throws NSEE if empty
+ */
+ public void testElement() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ assertEquals(i, q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * An add following remove(x) succeeds
+ */
+ public void testRemoveElementAndAdd() throws InterruptedException {
+ LinkedBlockingQueue q = new LinkedBlockingQueue();
+ assertTrue(q.add(new Integer(1)));
+ assertTrue(q.add(new Integer(2)));
+ assertTrue(q.remove(new Integer(1)));
+ assertTrue(q.remove(new Integer(2)));
+ assertTrue(q.add(new Integer(3)));
+ assertNotNull(q.take());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.poll();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertEquals(SIZE, q.remainingCapacity());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(one));
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ LinkedBlockingQueue p = new LinkedBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ LinkedBlockingQueue p = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ LinkedBlockingQueue p = populatedQueue(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * toArray contains all elements in FIFO order
+ */
+ public void testToArray() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.poll());
+ }
+
+ /**
+ * toArray(a) contains all elements in FIFO order
+ */
+ public void testToArray2() throws InterruptedException {
+ LinkedBlockingQueue<Integer> q = populatedQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.poll());
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ try {
+ q.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() throws InterruptedException {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertEquals(it.next(), q.take());
+ }
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final LinkedBlockingQueue q = new LinkedBlockingQueue(3);
+ q.add(two);
+ q.add(one);
+ q.add(three);
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertSame(it.next(), one);
+ assertSame(it.next(), three);
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * iterator ordering is FIFO
+ */
+ public void testIteratorOrdering() {
+ final LinkedBlockingQueue q = new LinkedBlockingQueue(3);
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ assertEquals(0, q.remainingCapacity());
+ int k = 0;
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+ assertEquals(3, k);
+ }
+
+ /**
+ * Modifications do not cause iterators to fail
+ */
+ public void testWeaklyConsistentIteration() {
+ final LinkedBlockingQueue q = new LinkedBlockingQueue(3);
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ q.remove();
+ it.next();
+ }
+ assertEquals(0, q.size());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * offer transfers elements across Executor tasks
+ */
+ public void testOfferInExecutor() {
+ final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+ q.add(one);
+ q.add(two);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(q.offer(three));
+ threadsStarted.await();
+ assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(0, q.remainingCapacity());
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ assertSame(one, q.take());
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * timed poll retrieves elements across Executor threads
+ */
+ public void testPollInExecutor() {
+ final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertNull(q.poll());
+ threadsStarted.await();
+ assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ checkEmpty(q);
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ q.put(one);
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * A deserialized serialized queue has same elements in same order
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedQueue(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * drainTo(c) empties queue into another collection c
+ */
+ public void testDrainTo() {
+ LinkedBlockingQueue q = populatedQueue(SIZE);
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(SIZE, l.size());
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ q.add(zero);
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(zero));
+ assertTrue(q.contains(one));
+ l.clear();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(2, l.size());
+ for (int i = 0; i < 2; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ }
+
+ /**
+ * drainTo empties full queue, unblocking a waiting put.
+ */
+ public void testDrainToWithActivePut() throws InterruptedException {
+ final LinkedBlockingQueue q = populatedQueue(SIZE);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(new Integer(SIZE+1));
+ }});
+
+ t.start();
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertTrue(l.size() >= SIZE);
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ t.join();
+ assertTrue(q.size() + l.size() >= SIZE);
+ }
+
+ /**
+ * drainTo(c, n) empties first min(n, size) elements of queue into c
+ */
+ public void testDrainToN() {
+ LinkedBlockingQueue q = new LinkedBlockingQueue();
+ for (int i = 0; i < SIZE + 2; ++i) {
+ for (int j = 0; j < SIZE; j++)
+ assertTrue(q.offer(new Integer(j)));
+ ArrayList l = new ArrayList();
+ q.drainTo(l, i);
+ int k = (i < SIZE) ? i : SIZE;
+ assertEquals(k, l.size());
+ assertEquals(SIZE-k, q.size());
+ for (int j = 0; j < k; ++j)
+ assertEquals(l.get(j), new Integer(j));
+ while (q.poll() != null) ;
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueUnboundedTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueUnboundedTest.java
new file mode 100644
index 0000000..b1fcdd9
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueUnboundedTest.java
@@ -0,0 +1,20 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class LinkedBlockingQueueUnboundedTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new LinkedBlockingQueue();
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedListTest.java b/jsr166-tests/src/test/java/jsr166/LinkedListTest.java
new file mode 100644
index 0000000..5b09100
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LinkedListTest.java
@@ -0,0 +1,627 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+
+public class LinkedListTest extends JSR166TestCase {
+
+ /**
+ * Returns a new queue of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private LinkedList<Integer> populatedQueue(int n) {
+ LinkedList<Integer> q = new LinkedList<Integer>();
+ assertTrue(q.isEmpty());
+ for (int i = 0; i < n; ++i)
+ assertTrue(q.offer(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * new queue is empty
+ */
+ public void testConstructor1() {
+ assertEquals(0, new LinkedList().size());
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ LinkedList q = new LinkedList((Collection)null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = i;
+ LinkedList q = new LinkedList(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ LinkedList q = new LinkedList();
+ assertTrue(q.isEmpty());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.add(new Integer(2));
+ q.remove();
+ q.remove();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * offer(null) succeeds
+ */
+ public void testOfferNull() {
+ LinkedList q = new LinkedList();
+ q.offer(null);
+ }
+
+ /**
+ * Offer succeeds
+ */
+ public void testOffer() {
+ LinkedList q = new LinkedList();
+ assertTrue(q.offer(new Integer(0)));
+ assertTrue(q.offer(new Integer(1)));
+ }
+
+ /**
+ * add succeeds
+ */
+ public void testAdd() {
+ LinkedList q = new LinkedList();
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ assertTrue(q.add(new Integer(i)));
+ }
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ LinkedList q = new LinkedList();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements, in traversal order, of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = i;
+ LinkedList q = new LinkedList();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * addAll with too large an index throws IOOBE
+ */
+ public void testAddAll2_IndexOutOfBoundsException() {
+ LinkedList l = new LinkedList();
+ l.add(new Object());
+ LinkedList m = new LinkedList();
+ m.add(new Object());
+ try {
+ l.addAll(4,m);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * addAll with negative index throws IOOBE
+ */
+ public void testAddAll4_BadIndex() {
+ LinkedList l = new LinkedList();
+ l.add(new Object());
+ LinkedList m = new LinkedList();
+ m.add(new Object());
+ try {
+ l.addAll(-1,m);
+ shouldThrow();
+ } catch (IndexOutOfBoundsException success) {}
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.poll());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * element returns next element, or throws NSEE if empty
+ */
+ public void testElement() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ assertEquals(i, q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove((Integer)i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove((Integer)i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove((Integer)(i+1)));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.poll();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ LinkedList q = populatedQueue(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertTrue(q.add(new Integer(1)));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ LinkedList q = populatedQueue(SIZE);
+ LinkedList p = new LinkedList();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ assertTrue(p.add(new Integer(i)));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ LinkedList q = populatedQueue(SIZE);
+ LinkedList p = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ LinkedList q = populatedQueue(SIZE);
+ LinkedList p = populatedQueue(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * toArray contains all elements in FIFO order
+ */
+ public void testToArray() {
+ LinkedList q = populatedQueue(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.poll());
+ }
+
+ /**
+ * toArray(a) contains all elements in FIFO order
+ */
+ public void testToArray2() {
+ LinkedList<Integer> q = populatedQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.poll());
+ }
+
+ /**
+ * toArray(null) throws NullPointerException
+ */
+ public void testToArray_NullArg() {
+ LinkedList l = new LinkedList();
+ l.add(new Object());
+ try {
+ l.toArray(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ LinkedList l = new LinkedList();
+ l.add(new Integer(5));
+ try {
+ l.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ LinkedList q = populatedQueue(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator ordering is FIFO
+ */
+ public void testIteratorOrdering() {
+ final LinkedList q = new LinkedList();
+ q.add(new Integer(1));
+ q.add(new Integer(2));
+ q.add(new Integer(3));
+ int k = 0;
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+
+ assertEquals(3, k);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final LinkedList q = new LinkedList();
+ q.add(new Integer(1));
+ q.add(new Integer(2));
+ q.add(new Integer(3));
+ Iterator it = q.iterator();
+ assertEquals(1, it.next());
+ it.remove();
+ it = q.iterator();
+ assertEquals(2, it.next());
+ assertEquals(3, it.next());
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * Descending iterator iterates through all elements
+ */
+ public void testDescendingIterator() {
+ LinkedList q = populatedQueue(SIZE);
+ int i = 0;
+ Iterator it = q.descendingIterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ assertFalse(it.hasNext());
+ try {
+ it.next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * Descending iterator ordering is reverse FIFO
+ */
+ public void testDescendingIteratorOrdering() {
+ final LinkedList q = new LinkedList();
+ q.add(new Integer(3));
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ int k = 0;
+ for (Iterator it = q.descendingIterator(); it.hasNext();) {
+ assertEquals(++k, it.next());
+ }
+
+ assertEquals(3, k);
+ }
+
+ /**
+ * descendingIterator.remove removes current element
+ */
+ public void testDescendingIteratorRemove() {
+ final LinkedList q = new LinkedList();
+ q.add(three);
+ q.add(two);
+ q.add(one);
+ Iterator it = q.descendingIterator();
+ it.next();
+ it.remove();
+ it = q.descendingIterator();
+ assertSame(it.next(), two);
+ assertSame(it.next(), three);
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ LinkedList q = populatedQueue(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * peek returns element inserted with addFirst
+ */
+ public void testAddFirst() {
+ LinkedList q = populatedQueue(3);
+ q.addFirst(four);
+ assertSame(four, q.peek());
+ }
+
+ /**
+ * peekFirst returns element inserted with push
+ */
+ public void testPush() {
+ LinkedList q = populatedQueue(3);
+ q.push(four);
+ assertSame(four, q.peekFirst());
+ }
+
+ /**
+ * pop removes next element, or throws NSEE if empty
+ */
+ public void testPop() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pop());
+ }
+ try {
+ q.pop();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * OfferFirst succeeds
+ */
+ public void testOfferFirst() {
+ LinkedList q = new LinkedList();
+ assertTrue(q.offerFirst(new Integer(0)));
+ assertTrue(q.offerFirst(new Integer(1)));
+ }
+
+ /**
+ * OfferLast succeeds
+ */
+ public void testOfferLast() {
+ LinkedList q = new LinkedList();
+ assertTrue(q.offerLast(new Integer(0)));
+ assertTrue(q.offerLast(new Integer(1)));
+ }
+
+ /**
+ * pollLast succeeds unless empty
+ */
+ public void testPollLast() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.pollLast());
+ }
+ assertNull(q.pollLast());
+ }
+
+ /**
+ * peekFirst returns next element, or null if empty
+ */
+ public void testPeekFirst() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peekFirst());
+ assertEquals(i, q.pollFirst());
+ assertTrue(q.peekFirst() == null ||
+ !q.peekFirst().equals(i));
+ }
+ assertNull(q.peekFirst());
+ }
+
+ /**
+ * peekLast returns next element, or null if empty
+ */
+ public void testPeekLast() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.peekLast());
+ assertEquals(i, q.pollLast());
+ assertTrue(q.peekLast() == null ||
+ !q.peekLast().equals(i));
+ }
+ assertNull(q.peekLast());
+ }
+
+ public void testFirstElement() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.getFirst());
+ assertEquals(i, q.pollFirst());
+ }
+ try {
+ q.getFirst();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * getLast returns next element, or throws NSEE if empty
+ */
+ public void testLastElement() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.getLast());
+ assertEquals(i, q.pollLast());
+ }
+ try {
+ q.getLast();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ assertNull(q.peekLast());
+ }
+
+ /**
+ * removeFirstOccurrence(x) removes x and returns true if present
+ */
+ public void testRemoveFirstOccurrence() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.removeFirstOccurrence(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.removeFirstOccurrence(new Integer(i)));
+ assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * removeLastOccurrence(x) removes x and returns true if present
+ */
+ public void testRemoveLastOccurrence() {
+ LinkedList q = populatedQueue(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.removeLastOccurrence(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.removeLastOccurrence(new Integer(i)));
+ assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java b/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java
new file mode 100644
index 0000000..94427df
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java
@@ -0,0 +1,1007 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include John Vint
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedTransferQueue;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class LinkedTransferQueueTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new LinkedTransferQueue();
+ }
+
+ /**
+ * Constructor builds new queue with size being zero and empty
+ * being true
+ */
+ public void testConstructor1() {
+ assertEquals(0, new LinkedTransferQueue().size());
+ assertTrue(new LinkedTransferQueue().isEmpty());
+ }
+
+ /**
+ * Initializing constructor with null collection throws
+ * NullPointerException
+ */
+ public void testConstructor2() {
+ try {
+ new LinkedTransferQueue(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws
+ * NullPointerException
+ */
+ public void testConstructor3() {
+ Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+ try {
+ new LinkedTransferQueue(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing constructor with a collection containing some null elements
+ * throws NullPointerException
+ */
+ public void testConstructor4() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = i;
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ new LinkedTransferQueue(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of the collection it is initialized by
+ */
+ public void testConstructor5() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i) {
+ ints[i] = i;
+ }
+ List intList = Arrays.asList(ints);
+ LinkedTransferQueue q
+ = new LinkedTransferQueue(intList);
+ assertEquals(q.size(), intList.size());
+ assertEquals(q.toString(), intList.toString());
+ assertTrue(Arrays.equals(q.toArray(),
+ intList.toArray()));
+ assertTrue(Arrays.equals(q.toArray(new Object[0]),
+ intList.toArray(new Object[0])));
+ assertTrue(Arrays.equals(q.toArray(new Object[SIZE]),
+ intList.toArray(new Object[SIZE])));
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(ints[i], q.poll());
+ }
+ }
+
+ /**
+ * remainingCapacity() always returns Integer.MAX_VALUE
+ */
+ public void testRemainingCapacity() {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+ assertEquals(SIZE - i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+ assertEquals(i, q.size());
+ q.add(i);
+ }
+ }
+
+ /**
+ * addAll(this) throws IllegalArgumentException
+ */
+ public void testAddAllSelf() {
+ try {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws
+ * NullPointerException after possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ LinkedTransferQueue q = new LinkedTransferQueue();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE - 1; ++i) {
+ ints[i] = i;
+ }
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements, in traversal order, of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i) {
+ ints[i] = i;
+ }
+ LinkedTransferQueue q = new LinkedTransferQueue();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(ints[i], q.poll());
+ }
+ }
+
+ /**
+ * all elements successfully put are contained
+ */
+ public void testPut() {
+ LinkedTransferQueue<Integer> q = new LinkedTransferQueue<Integer>();
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.put(i);
+ assertTrue(q.contains(i));
+ }
+ }
+
+ /**
+ * take retrieves elements in FIFO order
+ */
+ public void testTake() throws InterruptedException {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, (int) q.take());
+ }
+ }
+
+ /**
+ * take removes existing elements until empty, then blocks interruptibly
+ */
+ public void testBlockingTake() throws InterruptedException {
+ final BlockingQueue q = populatedQueue(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() throws InterruptedException {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, (int) q.poll());
+ }
+ assertNull(q.poll());
+ checkEmpty(q);
+ }
+
+ /**
+ * timed poll with zero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll0() throws InterruptedException {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, (int) q.poll(0, MILLISECONDS));
+ }
+ assertNull(q.poll(0, MILLISECONDS));
+ checkEmpty(q);
+ }
+
+ /**
+ * timed poll with nonzero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll() throws InterruptedException {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ long startTime = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ checkEmpty(q);
+ }
+
+ /**
+ * Interrupted timed poll throws InterruptedException instead of
+ * returning timeout status
+ */
+ public void testInterruptedTimedPoll() throws InterruptedException {
+ final BlockingQueue<Integer> q = populatedQueue(SIZE);
+ final CountDownLatch aboutToWait = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ long t0 = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+ long t0 = System.nanoTime();
+ aboutToWait.countDown();
+ try {
+ q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {
+ assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+ }
+ }});
+
+ aboutToWait.await();
+ waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+ t.interrupt();
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ checkEmpty(q);
+ }
+
+ /**
+ * timed poll after thread interrupted throws InterruptedException
+ * instead of returning timeout status
+ */
+ public void testTimedPollAfterInterrupt() throws InterruptedException {
+ final BlockingQueue<Integer> q = populatedQueue(SIZE);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ Thread.currentThread().interrupt();
+ for (int i = 0; i < SIZE; ++i) {
+ long t0 = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+ try {
+ q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ checkEmpty(q);
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() throws InterruptedException {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, (int) q.peek());
+ assertEquals(i, (int) q.poll());
+ assertTrue(q.peek() == null ||
+ i != (int) q.peek());
+ }
+ assertNull(q.peek());
+ checkEmpty(q);
+ }
+
+ /**
+ * element returns next element, or throws NoSuchElementException if empty
+ */
+ public void testElement() throws InterruptedException {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, (int) q.element());
+ assertEquals(i, (int) q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ checkEmpty(q);
+ }
+
+ /**
+ * remove removes next element, or throws NoSuchElementException if empty
+ */
+ public void testRemove() throws InterruptedException {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, (int) q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ checkEmpty(q);
+ }
+
+ /**
+ * An add following remove(x) succeeds
+ */
+ public void testRemoveElementAndAdd() throws InterruptedException {
+ LinkedTransferQueue q = new LinkedTransferQueue();
+ assertTrue(q.add(one));
+ assertTrue(q.add(two));
+ assertTrue(q.remove(one));
+ assertTrue(q.remove(two));
+ assertTrue(q.add(three));
+ assertSame(q.take(), three);
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(i));
+ assertEquals(i, (int) q.poll());
+ assertFalse(q.contains(i));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() throws InterruptedException {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ q.clear();
+ checkEmpty(q);
+ assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertEquals(1, q.size());
+ assertTrue(q.contains(one));
+ q.clear();
+ checkEmpty(q);
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ LinkedTransferQueue<Integer> p = new LinkedTransferQueue<Integer>();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(i);
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true
+ * if changed
+ */
+ public void testRetainAll() {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ LinkedTransferQueue p = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0) {
+ assertFalse(changed);
+ } else {
+ assertTrue(changed);
+ }
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE - i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true
+ * if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ LinkedTransferQueue p = populatedQueue(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE - i, q.size());
+ for (int j = 0; j < i; ++j) {
+ assertFalse(q.contains(p.remove()));
+ }
+ }
+ }
+
+ /**
+ * toArray() contains all elements in FIFO order
+ */
+ public void testToArray() {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++) {
+ assertSame(o[i], q.poll());
+ }
+ }
+
+ /**
+ * toArray(a) contains all elements in FIFO order
+ */
+ public void testToArray2() {
+ LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++) {
+ assertSame(ints[i], q.poll());
+ }
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ try {
+ q.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() throws InterruptedException {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ Iterator it = q.iterator();
+ int i = 0;
+ while (it.hasNext()) {
+ assertEquals(it.next(), i++);
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator.remove() removes current element
+ */
+ public void testIteratorRemove() {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ q.add(two);
+ q.add(one);
+ q.add(three);
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertSame(it.next(), one);
+ assertSame(it.next(), three);
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * iterator ordering is FIFO
+ */
+ public void testIteratorOrdering() {
+ final LinkedTransferQueue<Integer> q
+ = new LinkedTransferQueue<Integer>();
+ assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+ int k = 0;
+ for (Integer n : q) {
+ assertEquals(++k, (int) n);
+ }
+ assertEquals(3, k);
+ }
+
+ /**
+ * Modifications do not cause iterators to fail
+ */
+ public void testWeaklyConsistentIteration() {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ for (Iterator it = q.iterator(); it.hasNext();) {
+ q.remove();
+ it.next();
+ }
+ assertEquals(0, q.size());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * offer transfers elements across Executor tasks
+ */
+ public void testOfferInExecutor() {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ assertSame(one, q.take());
+ checkEmpty(q);
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * timed poll retrieves elements across Executor threads
+ */
+ public void testPollInExecutor() {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertNull(q.poll());
+ threadsStarted.await();
+ assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ checkEmpty(q);
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ q.put(one);
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * A deserialized serialized queue has same elements in same order
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedQueue(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(y, x);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * drainTo(c) empties queue into another collection c
+ */
+ public void testDrainTo() {
+ LinkedTransferQueue q = populatedQueue(SIZE);
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(SIZE, l.size());
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, l.get(i));
+ }
+ q.add(zero);
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(zero));
+ assertTrue(q.contains(one));
+ l.clear();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(2, l.size());
+ for (int i = 0; i < 2; ++i) {
+ assertEquals(i, l.get(i));
+ }
+ }
+
+ /**
+ * drainTo(c) empties full queue, unblocking a waiting put.
+ */
+ public void testDrainToWithActivePut() throws InterruptedException {
+ final LinkedTransferQueue q = populatedQueue(SIZE);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ q.put(SIZE + 1);
+ }});
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertTrue(l.size() >= SIZE);
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(i, l.get(i));
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ assertTrue(q.size() + l.size() >= SIZE);
+ }
+
+ /**
+ * drainTo(c, n) empties first min(n, size) elements of queue into c
+ */
+ public void testDrainToN() {
+ LinkedTransferQueue q = new LinkedTransferQueue();
+ for (int i = 0; i < SIZE + 2; ++i) {
+ for (int j = 0; j < SIZE; j++) {
+ assertTrue(q.offer(j));
+ }
+ ArrayList l = new ArrayList();
+ q.drainTo(l, i);
+ int k = (i < SIZE) ? i : SIZE;
+ assertEquals(k, l.size());
+ assertEquals(SIZE - k, q.size());
+ for (int j = 0; j < k; ++j)
+ assertEquals(j, l.get(j));
+ while (q.poll() != null)
+ ;
+ }
+ }
+
+ /**
+ * timed poll() or take() increments the waiting consumer count;
+ * offer(e) decrements the waiting consumer count
+ */
+ public void testWaitingConsumer() throws InterruptedException {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ assertEquals(0, q.getWaitingConsumerCount());
+ assertFalse(q.hasWaitingConsumer());
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(0, q.getWaitingConsumerCount());
+ assertFalse(q.hasWaitingConsumer());
+ }});
+
+ threadStarted.await();
+ waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+ assertEquals(1, q.getWaitingConsumerCount());
+ assertTrue(q.hasWaitingConsumer());
+
+ assertTrue(q.offer(one));
+ assertEquals(0, q.getWaitingConsumerCount());
+ assertFalse(q.hasWaitingConsumer());
+
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ }
+
+ /**
+ * transfer(null) throws NullPointerException
+ */
+ public void testTransfer1() throws InterruptedException {
+ try {
+ LinkedTransferQueue q = new LinkedTransferQueue();
+ q.transfer(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * transfer waits until a poll occurs. The transfered element
+ * is returned by this associated poll.
+ */
+ public void testTransfer2() throws InterruptedException {
+ final LinkedTransferQueue<Integer> q
+ = new LinkedTransferQueue<Integer>();
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ q.transfer(five);
+ checkEmpty(q);
+ }});
+
+ threadStarted.await();
+ waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+ assertEquals(1, q.size());
+ assertSame(five, q.poll());
+ checkEmpty(q);
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ }
+
+ /**
+ * transfer waits until a poll occurs, and then transfers in fifo order
+ */
+ public void testTransfer3() throws InterruptedException {
+ final LinkedTransferQueue<Integer> q
+ = new LinkedTransferQueue<Integer>();
+
+ Thread first = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.transfer(four);
+ assertTrue(!q.contains(four));
+ assertEquals(1, q.size());
+ }});
+
+ Thread interruptedThread = newStartedThread(
+ new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ while (q.isEmpty())
+ Thread.yield();
+ q.transfer(five);
+ }});
+
+ while (q.size() < 2)
+ Thread.yield();
+ assertEquals(2, q.size());
+ assertSame(four, q.poll());
+ first.join();
+ assertEquals(1, q.size());
+ interruptedThread.interrupt();
+ interruptedThread.join();
+ checkEmpty(q);
+ }
+
+ /**
+ * transfer waits until a poll occurs, at which point the polling
+ * thread returns the element
+ */
+ public void testTransfer4() throws InterruptedException {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.transfer(four);
+ assertFalse(q.contains(four));
+ assertSame(three, q.poll());
+ }});
+
+ while (q.isEmpty())
+ Thread.yield();
+ assertFalse(q.isEmpty());
+ assertEquals(1, q.size());
+ assertTrue(q.offer(three));
+ assertSame(four, q.poll());
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ }
+
+ /**
+ * transfer waits until a take occurs. The transfered element
+ * is returned by this associated take.
+ */
+ public void testTransfer5() throws InterruptedException {
+ final LinkedTransferQueue<Integer> q
+ = new LinkedTransferQueue<Integer>();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.transfer(four);
+ checkEmpty(q);
+ }});
+
+ while (q.isEmpty())
+ Thread.yield();
+ assertFalse(q.isEmpty());
+ assertEquals(1, q.size());
+ assertSame(four, q.take());
+ checkEmpty(q);
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ }
+
+ /**
+ * tryTransfer(null) throws NullPointerException
+ */
+ public void testTryTransfer1() {
+ try {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ q.tryTransfer(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * tryTransfer returns false and does not enqueue if there are no
+ * consumers waiting to poll or take.
+ */
+ public void testTryTransfer2() throws InterruptedException {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ assertFalse(q.tryTransfer(new Object()));
+ assertFalse(q.hasWaitingConsumer());
+ checkEmpty(q);
+ }
+
+ /**
+ * If there is a consumer waiting in timed poll, tryTransfer
+ * returns true while successfully transfering object.
+ */
+ public void testTryTransfer3() throws InterruptedException {
+ final Object hotPotato = new Object();
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ while (! q.hasWaitingConsumer())
+ Thread.yield();
+ assertTrue(q.hasWaitingConsumer());
+ checkEmpty(q);
+ assertTrue(q.tryTransfer(hotPotato));
+ }});
+
+ assertSame(hotPotato, q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+ checkEmpty(q);
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ }
+
+ /**
+ * If there is a consumer waiting in take, tryTransfer returns
+ * true while successfully transfering object.
+ */
+ public void testTryTransfer4() throws InterruptedException {
+ final Object hotPotato = new Object();
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ while (! q.hasWaitingConsumer())
+ Thread.yield();
+ assertTrue(q.hasWaitingConsumer());
+ checkEmpty(q);
+ assertTrue(q.tryTransfer(hotPotato));
+ }});
+
+ assertSame(q.take(), hotPotato);
+ checkEmpty(q);
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ }
+
+ /**
+ * tryTransfer blocks interruptibly if no takers
+ */
+ public void testTryTransfer5() throws InterruptedException {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ assertTrue(q.isEmpty());
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ Thread.currentThread().interrupt();
+ try {
+ q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ checkEmpty(q);
+ }
+
+ /**
+ * tryTransfer gives up after the timeout and returns false
+ */
+ public void testTryTransfer6() throws InterruptedException {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long t0 = System.nanoTime();
+ assertFalse(q.tryTransfer(new Object(),
+ timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(t0) >= timeoutMillis());
+ checkEmpty(q);
+ }});
+
+ awaitTermination(t);
+ checkEmpty(q);
+ }
+
+ /**
+ * tryTransfer waits for any elements previously in to be removed
+ * before transfering to a poll or take
+ */
+ public void testTryTransfer7() throws InterruptedException {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ assertTrue(q.offer(four));
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertTrue(q.tryTransfer(five, MEDIUM_DELAY_MS, MILLISECONDS));
+ checkEmpty(q);
+ }});
+
+ while (q.size() != 2)
+ Thread.yield();
+ assertEquals(2, q.size());
+ assertSame(four, q.poll());
+ assertSame(five, q.poll());
+ checkEmpty(q);
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ }
+
+ /**
+ * tryTransfer attempts to enqueue into the queue and fails
+ * returning false not enqueueing and the successive poll is null
+ */
+ public void testTryTransfer8() throws InterruptedException {
+ final LinkedTransferQueue q = new LinkedTransferQueue();
+ assertTrue(q.offer(four));
+ assertEquals(1, q.size());
+ long t0 = System.nanoTime();
+ assertFalse(q.tryTransfer(five, timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(t0) >= timeoutMillis());
+ assertEquals(1, q.size());
+ assertSame(four, q.poll());
+ assertNull(q.poll());
+ checkEmpty(q);
+ }
+
+ private LinkedTransferQueue<Integer> populatedQueue(int n) {
+ LinkedTransferQueue<Integer> q = new LinkedTransferQueue<Integer>();
+ checkEmpty(q);
+ for (int i = 0; i < n; i++) {
+ assertEquals(i, q.size());
+ assertTrue(q.offer(i));
+ assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+ }
+ assertFalse(q.isEmpty());
+ return q;
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LockSupportTest.java b/jsr166-tests/src/test/java/jsr166/LockSupportTest.java
new file mode 100644
index 0000000..051de35
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LockSupportTest.java
@@ -0,0 +1,362 @@
+/*
+ * Written by Doug Lea and Martin Buchholz with assistance from
+ * members of JCP JSR-166 Expert Group and released to the public
+ * domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.LockSupport;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class LockSupportTest extends JSR166TestCase {
+
+ /**
+ * Returns the blocker object used by tests in this file.
+ * Any old object will do; we'll return a convenient one.
+ */
+ static Object theBlocker() {
+ return LockSupportTest.class;
+ }
+
+ enum ParkMethod {
+ park() {
+ void park() {
+ LockSupport.park();
+ }
+ void park(long millis) {
+ throw new UnsupportedOperationException();
+ }
+ },
+ parkUntil() {
+ void park(long millis) {
+ LockSupport.parkUntil(deadline(millis));
+ }
+ },
+ parkNanos() {
+ void park(long millis) {
+ LockSupport.parkNanos(MILLISECONDS.toNanos(millis));
+ }
+ },
+ parkBlocker() {
+ void park() {
+ LockSupport.park(theBlocker());
+ }
+ void park(long millis) {
+ throw new UnsupportedOperationException();
+ }
+ },
+ parkUntilBlocker() {
+ void park(long millis) {
+ LockSupport.parkUntil(theBlocker(), deadline(millis));
+ }
+ },
+ parkNanosBlocker() {
+ void park(long millis) {
+ LockSupport.parkNanos(theBlocker(),
+ MILLISECONDS.toNanos(millis));
+ }
+ };
+
+ void park() { park(2 * LONG_DELAY_MS); }
+ abstract void park(long millis);
+
+ /** Returns a deadline to use with parkUntil. */
+ long deadline(long millis) {
+ // beware of rounding
+ return System.currentTimeMillis() + millis + 1;
+ }
+ }
+
+ /**
+ * park is released by subsequent unpark
+ */
+ public void testParkBeforeUnpark_park() {
+ testParkBeforeUnpark(ParkMethod.park);
+ }
+ public void testParkBeforeUnpark_parkNanos() {
+ testParkBeforeUnpark(ParkMethod.parkNanos);
+ }
+ public void testParkBeforeUnpark_parkUntil() {
+ testParkBeforeUnpark(ParkMethod.parkUntil);
+ }
+ public void testParkBeforeUnpark_parkBlocker() {
+ testParkBeforeUnpark(ParkMethod.parkBlocker);
+ }
+ public void testParkBeforeUnpark_parkNanosBlocker() {
+ testParkBeforeUnpark(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkBeforeUnpark_parkUntilBlocker() {
+ testParkBeforeUnpark(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkBeforeUnpark(final ParkMethod parkMethod) {
+ final CountDownLatch pleaseUnpark = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ pleaseUnpark.countDown();
+ parkMethod.park();
+ }});
+
+ await(pleaseUnpark);
+ LockSupport.unpark(t);
+ awaitTermination(t);
+ }
+
+ /**
+ * park is released by preceding unpark
+ */
+ public void testParkAfterUnpark_park() {
+ testParkAfterUnpark(ParkMethod.park);
+ }
+ public void testParkAfterUnpark_parkNanos() {
+ testParkAfterUnpark(ParkMethod.parkNanos);
+ }
+ public void testParkAfterUnpark_parkUntil() {
+ testParkAfterUnpark(ParkMethod.parkUntil);
+ }
+ public void testParkAfterUnpark_parkBlocker() {
+ testParkAfterUnpark(ParkMethod.parkBlocker);
+ }
+ public void testParkAfterUnpark_parkNanosBlocker() {
+ testParkAfterUnpark(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkAfterUnpark_parkUntilBlocker() {
+ testParkAfterUnpark(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkAfterUnpark(final ParkMethod parkMethod) {
+ final CountDownLatch pleaseUnpark = new CountDownLatch(1);
+ final AtomicBoolean pleasePark = new AtomicBoolean(false);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ pleaseUnpark.countDown();
+ while (!pleasePark.get())
+ Thread.yield();
+ parkMethod.park();
+ }});
+
+ await(pleaseUnpark);
+ LockSupport.unpark(t);
+ pleasePark.set(true);
+ awaitTermination(t);
+ }
+
+ /**
+ * park is released by subsequent interrupt
+ */
+ public void testParkBeforeInterrupt_park() {
+ testParkBeforeInterrupt(ParkMethod.park);
+ }
+ public void testParkBeforeInterrupt_parkNanos() {
+ testParkBeforeInterrupt(ParkMethod.parkNanos);
+ }
+ public void testParkBeforeInterrupt_parkUntil() {
+ testParkBeforeInterrupt(ParkMethod.parkUntil);
+ }
+ public void testParkBeforeInterrupt_parkBlocker() {
+ testParkBeforeInterrupt(ParkMethod.parkBlocker);
+ }
+ public void testParkBeforeInterrupt_parkNanosBlocker() {
+ testParkBeforeInterrupt(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkBeforeInterrupt_parkUntilBlocker() {
+ testParkBeforeInterrupt(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkBeforeInterrupt(final ParkMethod parkMethod) {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ pleaseInterrupt.countDown();
+ do {
+ parkMethod.park();
+ // park may return spuriously
+ } while (! Thread.currentThread().isInterrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * park is released by preceding interrupt
+ */
+ public void testParkAfterInterrupt_park() {
+ testParkAfterInterrupt(ParkMethod.park);
+ }
+ public void testParkAfterInterrupt_parkNanos() {
+ testParkAfterInterrupt(ParkMethod.parkNanos);
+ }
+ public void testParkAfterInterrupt_parkUntil() {
+ testParkAfterInterrupt(ParkMethod.parkUntil);
+ }
+ public void testParkAfterInterrupt_parkBlocker() {
+ testParkAfterInterrupt(ParkMethod.parkBlocker);
+ }
+ public void testParkAfterInterrupt_parkNanosBlocker() {
+ testParkAfterInterrupt(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkAfterInterrupt_parkUntilBlocker() {
+ testParkAfterInterrupt(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkAfterInterrupt(final ParkMethod parkMethod) {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ final AtomicBoolean pleasePark = new AtomicBoolean(false);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ pleaseInterrupt.countDown();
+ while (!pleasePark.get())
+ Thread.yield();
+ assertTrue(Thread.currentThread().isInterrupted());
+ parkMethod.park();
+ assertTrue(Thread.currentThread().isInterrupted());
+ }});
+
+ await(pleaseInterrupt);
+ t.interrupt();
+ pleasePark.set(true);
+ awaitTermination(t);
+ }
+
+ /**
+ * timed park times out if not unparked
+ */
+ public void testParkTimesOut_parkNanos() {
+ testParkTimesOut(ParkMethod.parkNanos);
+ }
+ public void testParkTimesOut_parkUntil() {
+ testParkTimesOut(ParkMethod.parkUntil);
+ }
+ public void testParkTimesOut_parkNanosBlocker() {
+ testParkTimesOut(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkTimesOut_parkUntilBlocker() {
+ testParkTimesOut(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkTimesOut(final ParkMethod parkMethod) {
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ for (;;) {
+ long startTime = System.nanoTime();
+ parkMethod.park(timeoutMillis());
+ // park may return spuriously
+ if (millisElapsedSince(startTime) >= timeoutMillis())
+ return;
+ }
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * getBlocker(null) throws NullPointerException
+ */
+ public void testGetBlockerNull() {
+ try {
+ LockSupport.getBlocker(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getBlocker returns the blocker object passed to park
+ */
+ public void testGetBlocker_parkBlocker() {
+ testGetBlocker(ParkMethod.parkBlocker);
+ }
+ public void testGetBlocker_parkNanosBlocker() {
+ testGetBlocker(ParkMethod.parkNanosBlocker);
+ }
+ public void testGetBlocker_parkUntilBlocker() {
+ testGetBlocker(ParkMethod.parkUntilBlocker);
+ }
+ public void testGetBlocker(final ParkMethod parkMethod) {
+ final CountDownLatch started = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread t = Thread.currentThread();
+ started.countDown();
+ do {
+ assertNull(LockSupport.getBlocker(t));
+ parkMethod.park();
+ assertNull(LockSupport.getBlocker(t));
+ // park may return spuriously
+ } while (! Thread.currentThread().isInterrupted());
+ }});
+
+ long startTime = System.nanoTime();
+ await(started);
+ for (;;) {
+ Object x = LockSupport.getBlocker(t);
+ if (x == theBlocker()) { // success
+ t.interrupt();
+ awaitTermination(t);
+ assertNull(LockSupport.getBlocker(t));
+ return;
+ } else {
+ assertNull(x); // ok
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ }
+ }
+
+ /**
+ * timed park(0) returns immediately.
+ *
+ * Requires hotspot fix for:
+ * 6763959 java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
+ * which is in jdk7-b118 and 6u25.
+ */
+ public void testPark0_parkNanos() {
+ testPark0(ParkMethod.parkNanos);
+ }
+ public void testPark0_parkUntil() {
+ testPark0(ParkMethod.parkUntil);
+ }
+ public void testPark0_parkNanosBlocker() {
+ testPark0(ParkMethod.parkNanosBlocker);
+ }
+ public void testPark0_parkUntilBlocker() {
+ testPark0(ParkMethod.parkUntilBlocker);
+ }
+ public void testPark0(final ParkMethod parkMethod) {
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ parkMethod.park(0L);
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * timed park(Long.MIN_VALUE) returns immediately.
+ */
+ public void testParkNeg_parkNanos() {
+ testParkNeg(ParkMethod.parkNanos);
+ }
+ public void testParkNeg_parkUntil() {
+ testParkNeg(ParkMethod.parkUntil);
+ }
+ public void testParkNeg_parkNanosBlocker() {
+ testParkNeg(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkNeg_parkUntilBlocker() {
+ testParkNeg(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkNeg(final ParkMethod parkMethod) {
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ parkMethod.park(Long.MIN_VALUE);
+ }});
+
+ awaitTermination(t);
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/PhaserTest.java b/jsr166-tests/src/test/java/jsr166/PhaserTest.java
new file mode 100644
index 0000000..3889c1f
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/PhaserTest.java
@@ -0,0 +1,786 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include John Vint
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeoutException;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class PhaserTest extends JSR166TestCase {
+
+ private static final int maxParties = 65535;
+
+ /** Checks state of unterminated phaser. */
+ protected void assertState(Phaser phaser,
+ int phase, int parties, int unarrived) {
+ assertEquals(phase, phaser.getPhase());
+ assertEquals(parties, phaser.getRegisteredParties());
+ assertEquals(unarrived, phaser.getUnarrivedParties());
+ assertEquals(parties - unarrived, phaser.getArrivedParties());
+ assertFalse(phaser.isTerminated());
+ }
+
+ /** Checks state of terminated phaser. */
+ protected void assertTerminated(Phaser phaser, int maxPhase, int parties) {
+ assertTrue(phaser.isTerminated());
+ int expectedPhase = maxPhase + Integer.MIN_VALUE;
+ assertEquals(expectedPhase, phaser.getPhase());
+ assertEquals(parties, phaser.getRegisteredParties());
+ assertEquals(expectedPhase, phaser.register());
+ assertEquals(expectedPhase, phaser.arrive());
+ assertEquals(expectedPhase, phaser.arriveAndDeregister());
+ }
+
+ protected void assertTerminated(Phaser phaser, int maxPhase) {
+ assertTerminated(phaser, maxPhase, 0);
+ }
+
+ /**
+ * Empty constructor builds a new Phaser with no parent, no registered
+ * parties and initial phase number of 0
+ */
+ public void testConstructorDefaultValues() {
+ Phaser phaser = new Phaser();
+ assertNull(phaser.getParent());
+ assertEquals(0, phaser.getRegisteredParties());
+ assertEquals(0, phaser.getArrivedParties());
+ assertEquals(0, phaser.getUnarrivedParties());
+ assertEquals(0, phaser.getPhase());
+ }
+
+ /**
+ * Constructing with a negative number of parties throws
+ * IllegalArgumentException
+ */
+ public void testConstructorNegativeParties() {
+ try {
+ new Phaser(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructing with a negative number of parties throws
+ * IllegalArgumentException
+ */
+ public void testConstructorNegativeParties2() {
+ try {
+ new Phaser(new Phaser(), -1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructing with a number of parties > 65535 throws
+ * IllegalArgumentException
+ */
+ public void testConstructorPartiesExceedsLimit() {
+ new Phaser(maxParties);
+ try {
+ new Phaser(maxParties + 1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+
+ new Phaser(new Phaser(), maxParties);
+ try {
+ new Phaser(new Phaser(), maxParties + 1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * The parent provided to the constructor should be returned from
+ * a later call to getParent
+ */
+ public void testConstructor3() {
+ Phaser parent = new Phaser();
+ assertSame(parent, new Phaser(parent).getParent());
+ assertNull(new Phaser(null).getParent());
+ }
+
+ /**
+ * The parent being input into the parameter should equal the original
+ * parent when being returned
+ */
+ public void testConstructor5() {
+ Phaser parent = new Phaser();
+ assertSame(parent, new Phaser(parent, 0).getParent());
+ assertNull(new Phaser(null, 0).getParent());
+ }
+
+ /**
+ * register() will increment the number of unarrived parties by
+ * one and not affect its arrived parties
+ */
+ public void testRegister1() {
+ Phaser phaser = new Phaser();
+ assertState(phaser, 0, 0, 0);
+ assertEquals(0, phaser.register());
+ assertState(phaser, 0, 1, 1);
+ }
+
+ /**
+ * Registering more than 65536 parties causes IllegalStateException
+ */
+ public void testRegister2() {
+ Phaser phaser = new Phaser(0);
+ assertState(phaser, 0, 0, 0);
+ assertEquals(0, phaser.bulkRegister(maxParties - 10));
+ assertState(phaser, 0, maxParties - 10, maxParties - 10);
+ for (int i = 0; i < 10; i++) {
+ assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
+ assertEquals(0, phaser.register());
+ }
+ assertState(phaser, 0, maxParties, maxParties);
+ try {
+ phaser.register();
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+
+ try {
+ phaser.bulkRegister(Integer.MAX_VALUE);
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+
+ assertEquals(0, phaser.bulkRegister(0));
+ assertState(phaser, 0, maxParties, maxParties);
+ }
+
+ /**
+ * register() correctly returns the current barrier phase number
+ * when invoked
+ */
+ public void testRegister3() {
+ Phaser phaser = new Phaser();
+ assertEquals(0, phaser.register());
+ assertEquals(0, phaser.arrive());
+ assertEquals(1, phaser.register());
+ assertState(phaser, 1, 2, 2);
+ }
+
+ /**
+ * register causes the next arrive to not increment the phase
+ * rather retain the phase number
+ */
+ public void testRegister4() {
+ Phaser phaser = new Phaser(1);
+ assertEquals(0, phaser.arrive());
+ assertEquals(1, phaser.register());
+ assertEquals(1, phaser.arrive());
+ assertState(phaser, 1, 2, 1);
+ }
+
+ /**
+ * register on a subphaser that is currently empty succeeds, even
+ * in the presence of another non-empty subphaser
+ */
+ public void testRegisterEmptySubPhaser() {
+ Phaser root = new Phaser();
+ Phaser child1 = new Phaser(root, 1);
+ Phaser child2 = new Phaser(root, 0);
+ assertEquals(0, child2.register());
+ assertState(root, 0, 2, 2);
+ assertState(child1, 0, 1, 1);
+ assertState(child2, 0, 1, 1);
+ assertEquals(0, child2.arriveAndDeregister());
+ assertState(root, 0, 1, 1);
+ assertState(child1, 0, 1, 1);
+ assertState(child2, 0, 0, 0);
+ assertEquals(0, child2.register());
+ assertEquals(0, child2.arriveAndDeregister());
+ assertState(root, 0, 1, 1);
+ assertState(child1, 0, 1, 1);
+ assertState(child2, 0, 0, 0);
+ assertEquals(0, child1.arriveAndDeregister());
+ assertTerminated(root, 1);
+ assertTerminated(child1, 1);
+ assertTerminated(child2, 1);
+ }
+
+ /**
+ * Invoking bulkRegister with a negative parameter throws an
+ * IllegalArgumentException
+ */
+ public void testBulkRegister1() {
+ try {
+ new Phaser().bulkRegister(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * bulkRegister should correctly record the number of unarrived
+ * parties with the number of parties being registered
+ */
+ public void testBulkRegister2() {
+ Phaser phaser = new Phaser();
+ assertEquals(0, phaser.bulkRegister(0));
+ assertState(phaser, 0, 0, 0);
+ assertEquals(0, phaser.bulkRegister(20));
+ assertState(phaser, 0, 20, 20);
+ }
+
+ /**
+ * Registering with a number of parties greater than or equal to 1<<16
+ * throws IllegalStateException.
+ */
+ public void testBulkRegister3() {
+ assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
+
+ try {
+ new Phaser().bulkRegister(1 << 16);
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+
+ try {
+ new Phaser(2).bulkRegister((1 << 16) - 2);
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * the phase number increments correctly when tripping the barrier
+ */
+ public void testPhaseIncrement1() {
+ for (int size = 1; size < nine; size++) {
+ final Phaser phaser = new Phaser(size);
+ for (int index = 0; index <= (1 << size); index++) {
+ int phase = phaser.arrive();
+ assertTrue(index % size == 0 ? (index / size) == phase : index - (phase * size) > 0);
+ }
+ }
+ }
+
+ /**
+ * arrive() on a registered phaser increments phase.
+ */
+ public void testArrive1() {
+ Phaser phaser = new Phaser(1);
+ assertState(phaser, 0, 1, 1);
+ assertEquals(0, phaser.arrive());
+ assertState(phaser, 1, 1, 1);
+ }
+
+ /**
+ * arriveAndDeregister does not wait for others to arrive at barrier
+ */
+ public void testArriveAndDeregister() {
+ final Phaser phaser = new Phaser(1);
+ for (int i = 0; i < 10; i++) {
+ assertState(phaser, 0, 1, 1);
+ assertEquals(0, phaser.register());
+ assertState(phaser, 0, 2, 2);
+ assertEquals(0, phaser.arriveAndDeregister());
+ assertState(phaser, 0, 1, 1);
+ }
+ assertEquals(0, phaser.arriveAndDeregister());
+ assertTerminated(phaser, 1);
+ }
+
+ /**
+ * arriveAndDeregister does not wait for others to arrive at barrier
+ */
+ public void testArrive2() {
+ final Phaser phaser = new Phaser();
+ assertEquals(0, phaser.register());
+ List<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < 10; i++) {
+ assertEquals(0, phaser.register());
+ threads.add(newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(0, phaser.arriveAndDeregister());
+ }}));
+ }
+
+ for (Thread thread : threads)
+ awaitTermination(thread);
+ assertState(phaser, 0, 1, 1);
+ assertEquals(0, phaser.arrive());
+ assertState(phaser, 1, 1, 1);
+ }
+
+ /**
+ * arrive() returns a negative number if the Phaser is terminated
+ */
+ public void testArrive3() {
+ Phaser phaser = new Phaser(1);
+ phaser.forceTermination();
+ assertTerminated(phaser, 0, 1);
+ assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
+ assertTrue(phaser.arrive() < 0);
+ assertTrue(phaser.register() < 0);
+ assertTrue(phaser.arriveAndDeregister() < 0);
+ assertTrue(phaser.awaitAdvance(1) < 0);
+ assertTrue(phaser.getPhase() < 0);
+ }
+
+ /**
+ * arriveAndDeregister() throws IllegalStateException if number of
+ * registered or unarrived parties would become negative
+ */
+ public void testArriveAndDeregister1() {
+ try {
+ Phaser phaser = new Phaser();
+ phaser.arriveAndDeregister();
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * arriveAndDeregister reduces the number of arrived parties
+ */
+ public void testArriveAndDeregister2() {
+ final Phaser phaser = new Phaser(1);
+ assertEquals(0, phaser.register());
+ assertEquals(0, phaser.arrive());
+ assertState(phaser, 0, 2, 1);
+ assertEquals(0, phaser.arriveAndDeregister());
+ assertState(phaser, 1, 1, 1);
+ }
+
+ /**
+ * arriveAndDeregister arrives at the barrier on a phaser with a parent and
+ * when a deregistration occurs and causes the phaser to have zero parties
+ * its parent will be deregistered as well
+ */
+ public void testArriveAndDeregister3() {
+ Phaser parent = new Phaser();
+ Phaser child = new Phaser(parent);
+ assertState(child, 0, 0, 0);
+ assertState(parent, 0, 0, 0);
+ assertEquals(0, child.register());
+ assertState(child, 0, 1, 1);
+ assertState(parent, 0, 1, 1);
+ assertEquals(0, child.arriveAndDeregister());
+ assertTerminated(child, 1);
+ assertTerminated(parent, 1);
+ }
+
+ /**
+ * arriveAndDeregister deregisters one party from its parent when
+ * the number of parties of child is zero after deregistration
+ */
+ public void testArriveAndDeregister4() {
+ Phaser parent = new Phaser();
+ Phaser child = new Phaser(parent);
+ assertEquals(0, parent.register());
+ assertEquals(0, child.register());
+ assertState(child, 0, 1, 1);
+ assertState(parent, 0, 2, 2);
+ assertEquals(0, child.arriveAndDeregister());
+ assertState(child, 0, 0, 0);
+ assertState(parent, 0, 1, 1);
+ }
+
+ /**
+ * arriveAndDeregister deregisters one party from its parent when
+ * the number of parties of root is nonzero after deregistration.
+ */
+ public void testArriveAndDeregister5() {
+ Phaser root = new Phaser();
+ Phaser parent = new Phaser(root);
+ Phaser child = new Phaser(parent);
+ assertState(root, 0, 0, 0);
+ assertState(parent, 0, 0, 0);
+ assertState(child, 0, 0, 0);
+ assertEquals(0, child.register());
+ assertState(root, 0, 1, 1);
+ assertState(parent, 0, 1, 1);
+ assertState(child, 0, 1, 1);
+ assertEquals(0, child.arriveAndDeregister());
+ assertTerminated(child, 1);
+ assertTerminated(parent, 1);
+ assertTerminated(root, 1);
+ }
+
+ /**
+ * arriveAndDeregister returns the phase in which it leaves the
+ * phaser in after deregistration
+ */
+ public void testArriveAndDeregister6() {
+ final Phaser phaser = new Phaser(2);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(0, phaser.arrive());
+ }});
+ assertEquals(1, phaser.arriveAndAwaitAdvance());
+ assertState(phaser, 1, 2, 2);
+ assertEquals(1, phaser.arriveAndDeregister());
+ assertState(phaser, 1, 1, 1);
+ assertEquals(1, phaser.arriveAndDeregister());
+ assertTerminated(phaser, 2);
+ awaitTermination(t);
+ }
+
+ /**
+ * awaitAdvance succeeds upon advance
+ */
+ public void testAwaitAdvance1() {
+ final Phaser phaser = new Phaser(1);
+ assertEquals(0, phaser.arrive());
+ assertEquals(1, phaser.awaitAdvance(0));
+ }
+
+ /**
+ * awaitAdvance with a negative parameter will return without affecting the
+ * phaser
+ */
+ public void testAwaitAdvance2() {
+ Phaser phaser = new Phaser();
+ assertTrue(phaser.awaitAdvance(-1) < 0);
+ assertState(phaser, 0, 0, 0);
+ }
+
+ /**
+ * awaitAdvanceInterruptibly blocks interruptibly
+ */
+ public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException {
+ final Phaser phaser = new Phaser(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread.currentThread().interrupt();
+ try {
+ phaser.awaitAdvanceInterruptibly(0);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ phaser.awaitAdvanceInterruptibly(0);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws TimeoutException {
+ Thread.currentThread().interrupt();
+ try {
+ phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertState(phaser, 0, 1, 1);
+ assertThreadsStayAlive(t1, t2);
+ t1.interrupt();
+ t2.interrupt();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertState(phaser, 0, 1, 1);
+ assertEquals(0, phaser.arrive());
+ assertState(phaser, 1, 1, 1);
+ }
+
+ /**
+ * awaitAdvance continues waiting if interrupted before waiting
+ */
+ public void testAwaitAdvanceAfterInterrupt() {
+ final Phaser phaser = new Phaser();
+ assertEquals(0, phaser.register());
+ final CountDownLatch pleaseArrive = new CountDownLatch(1);
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread.currentThread().interrupt();
+ assertEquals(0, phaser.register());
+ assertEquals(0, phaser.arrive());
+ pleaseArrive.countDown();
+ assertTrue(Thread.currentThread().isInterrupted());
+ assertEquals(1, phaser.awaitAdvance(0));
+ assertTrue(Thread.interrupted());
+ }});
+
+ await(pleaseArrive);
+ waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
+ assertEquals(0, phaser.arrive());
+ awaitTermination(t);
+
+ Thread.currentThread().interrupt();
+ assertEquals(1, phaser.awaitAdvance(0));
+ assertTrue(Thread.interrupted());
+ }
+
+ /**
+ * awaitAdvance continues waiting if interrupted while waiting
+ */
+ public void testAwaitAdvanceBeforeInterrupt() {
+ final Phaser phaser = new Phaser();
+ assertEquals(0, phaser.register());
+ final CountDownLatch pleaseArrive = new CountDownLatch(1);
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(0, phaser.register());
+ assertEquals(0, phaser.arrive());
+ assertFalse(Thread.currentThread().isInterrupted());
+ pleaseArrive.countDown();
+ assertEquals(1, phaser.awaitAdvance(0));
+ assertTrue(Thread.interrupted());
+ }});
+
+ await(pleaseArrive);
+ waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
+ t.interrupt();
+ assertEquals(0, phaser.arrive());
+ awaitTermination(t);
+
+ Thread.currentThread().interrupt();
+ assertEquals(1, phaser.awaitAdvance(0));
+ assertTrue(Thread.interrupted());
+ }
+
+ /**
+ * arriveAndAwaitAdvance continues waiting if interrupted before waiting
+ */
+ public void testArriveAndAwaitAdvanceAfterInterrupt() {
+ final Phaser phaser = new Phaser();
+ assertEquals(0, phaser.register());
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread.currentThread().interrupt();
+ assertEquals(0, phaser.register());
+ pleaseInterrupt.countDown();
+ assertTrue(Thread.currentThread().isInterrupted());
+ assertEquals(1, phaser.arriveAndAwaitAdvance());
+ assertTrue(Thread.currentThread().isInterrupted());
+ }});
+
+ await(pleaseInterrupt);
+ waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
+ Thread.currentThread().interrupt();
+ assertEquals(1, phaser.arriveAndAwaitAdvance());
+ assertTrue(Thread.interrupted());
+ awaitTermination(t);
+ }
+
+ /**
+ * arriveAndAwaitAdvance continues waiting if interrupted while waiting
+ */
+ public void testArriveAndAwaitAdvanceBeforeInterrupt() {
+ final Phaser phaser = new Phaser();
+ assertEquals(0, phaser.register());
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(0, phaser.register());
+ assertFalse(Thread.currentThread().isInterrupted());
+ pleaseInterrupt.countDown();
+ assertEquals(1, phaser.arriveAndAwaitAdvance());
+ assertTrue(Thread.currentThread().isInterrupted());
+ }});
+
+ await(pleaseInterrupt);
+ waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
+ t.interrupt();
+ Thread.currentThread().interrupt();
+ assertEquals(1, phaser.arriveAndAwaitAdvance());
+ assertTrue(Thread.interrupted());
+ awaitTermination(t);
+ }
+
+ /**
+ * awaitAdvance atomically waits for all parties within the same phase to
+ * complete before continuing
+ */
+ public void testAwaitAdvance4() {
+ final Phaser phaser = new Phaser(4);
+ final AtomicInteger count = new AtomicInteger(0);
+ List<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < 4; i++)
+ threads.add(newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ for (int k = 0; k < 3; k++) {
+ assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
+ count.incrementAndGet();
+ assertEquals(2*k+1, phaser.arrive());
+ assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
+ assertEquals(4*(k+1), count.get());
+ }}}));
+
+ for (Thread thread : threads)
+ awaitTermination(thread);
+ }
+
+ /**
+ * awaitAdvance returns the current phase
+ */
+ public void testAwaitAdvance5() {
+ final Phaser phaser = new Phaser(1);
+ assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
+ assertEquals(1, phaser.getPhase());
+ assertEquals(1, phaser.register());
+ List<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < 8; i++) {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final boolean goesFirst = ((i & 1) == 0);
+ threads.add(newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ if (goesFirst)
+ latch.countDown();
+ else
+ await(latch);
+ phaser.arrive();
+ }}));
+ if (goesFirst)
+ await(latch);
+ else
+ latch.countDown();
+ assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
+ assertEquals(i + 2, phaser.getPhase());
+ }
+ for (Thread thread : threads)
+ awaitTermination(thread);
+ }
+
+ /**
+ * awaitAdvance returns the current phase in child phasers
+ */
+ public void testAwaitAdvanceTieredPhaser() throws Exception {
+ final Phaser parent = new Phaser();
+ final List<Phaser> zeroPartyChildren = new ArrayList<Phaser>(3);
+ final List<Phaser> onePartyChildren = new ArrayList<Phaser>(3);
+ for (int i = 0; i < 3; i++) {
+ zeroPartyChildren.add(new Phaser(parent, 0));
+ onePartyChildren.add(new Phaser(parent, 1));
+ }
+ final List<Phaser> phasers = new ArrayList<Phaser>();
+ phasers.addAll(zeroPartyChildren);
+ phasers.addAll(onePartyChildren);
+ phasers.add(parent);
+ for (Phaser phaser : phasers) {
+ assertEquals(-42, phaser.awaitAdvance(-42));
+ assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
+ assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
+ }
+
+ for (Phaser child : onePartyChildren)
+ assertEquals(0, child.arrive());
+ for (Phaser phaser : phasers) {
+ assertEquals(-42, phaser.awaitAdvance(-42));
+ assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
+ assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, phaser.awaitAdvance(0));
+ assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
+ assertEquals(1, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
+ }
+
+ for (Phaser child : onePartyChildren)
+ assertEquals(1, child.arrive());
+ for (Phaser phaser : phasers) {
+ assertEquals(-42, phaser.awaitAdvance(-42));
+ assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
+ assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(2, phaser.awaitAdvance(0));
+ assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
+ assertEquals(2, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(2, phaser.awaitAdvance(1));
+ assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
+ assertEquals(2, phaser.awaitAdvanceInterruptibly(1, SMALL_DELAY_MS, MILLISECONDS));
+ }
+ }
+
+ /**
+ * awaitAdvance returns when the phaser is externally terminated
+ */
+ public void testAwaitAdvance6() {
+ final Phaser phaser = new Phaser(3);
+ final CountDownLatch pleaseForceTermination = new CountDownLatch(2);
+ final List<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < 2; i++) {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(0, phaser.arrive());
+ pleaseForceTermination.countDown();
+ assertTrue(phaser.awaitAdvance(0) < 0);
+ assertTrue(phaser.isTerminated());
+ assertTrue(phaser.getPhase() < 0);
+ assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
+ assertEquals(3, phaser.getRegisteredParties());
+ }};
+ threads.add(newStartedThread(r));
+ }
+ await(pleaseForceTermination);
+ phaser.forceTermination();
+ assertTrue(phaser.isTerminated());
+ assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
+ for (Thread thread : threads)
+ awaitTermination(thread);
+ assertEquals(3, phaser.getRegisteredParties());
+ }
+
+ /**
+ * arriveAndAwaitAdvance throws IllegalStateException with no
+ * unarrived parties
+ */
+ public void testArriveAndAwaitAdvance1() {
+ try {
+ Phaser phaser = new Phaser();
+ phaser.arriveAndAwaitAdvance();
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * arriveAndAwaitAdvance waits for all threads to arrive, the
+ * number of arrived parties is the same number that is accounted
+ * for when the main thread awaitsAdvance
+ */
+ public void testArriveAndAwaitAdvance3() {
+ final Phaser phaser = new Phaser(1);
+ final int THREADS = 3;
+ final CountDownLatch pleaseArrive = new CountDownLatch(THREADS);
+ final List<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < THREADS; i++)
+ threads.add(newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(0, phaser.register());
+ pleaseArrive.countDown();
+ assertEquals(1, phaser.arriveAndAwaitAdvance());
+ }}));
+
+ await(pleaseArrive);
+ long startTime = System.nanoTime();
+ while (phaser.getArrivedParties() < THREADS)
+ Thread.yield();
+ assertEquals(THREADS, phaser.getArrivedParties());
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ for (Thread thread : threads)
+ waitForThreadToEnterWaitState(thread, SHORT_DELAY_MS);
+ for (Thread thread : threads)
+ assertTrue(thread.isAlive());
+ assertState(phaser, 0, THREADS + 1, 1);
+ phaser.arriveAndAwaitAdvance();
+ for (Thread thread : threads)
+ awaitTermination(thread);
+ assertState(phaser, 1, THREADS + 1, THREADS + 1);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueGenericTest.java b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueGenericTest.java
new file mode 100644
index 0000000..8c5da7b
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueGenericTest.java
@@ -0,0 +1,20 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+
+public class PriorityBlockingQueueGenericTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new PriorityBlockingQueue();
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueInitialCapacityTest.java b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueInitialCapacityTest.java
new file mode 100644
index 0000000..7dee1fe
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueInitialCapacityTest.java
@@ -0,0 +1,20 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+
+public class PriorityBlockingQueueInitialCapacityTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new PriorityBlockingQueue(SIZE);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java
new file mode 100644
index 0000000..89d6d24
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java
@@ -0,0 +1,699 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class PriorityBlockingQueueTest extends JSR166TestCase {
+
+ private static final int NOCAP = Integer.MAX_VALUE;
+
+ /** Sample Comparator */
+ static class MyReverseComparator implements Comparator {
+ public int compare(Object x, Object y) {
+ return ((Comparable)y).compareTo(x);
+ }
+ }
+
+ /**
+ * Returns a new queue of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private PriorityBlockingQueue<Integer> populatedQueue(int n) {
+ PriorityBlockingQueue<Integer> q =
+ new PriorityBlockingQueue<Integer>(n);
+ assertTrue(q.isEmpty());
+ for (int i = n-1; i >= 0; i-=2)
+ assertTrue(q.offer(new Integer(i)));
+ for (int i = (n & 1); i < n; i+=2)
+ assertTrue(q.offer(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(NOCAP, q.remainingCapacity());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * A new queue has unbounded capacity
+ */
+ public void testConstructor1() {
+ assertEquals(NOCAP, new PriorityBlockingQueue(SIZE).remainingCapacity());
+ }
+
+ /**
+ * Constructor throws IAE if capacity argument nonpositive
+ */
+ public void testConstructor2() {
+ try {
+ new PriorityBlockingQueue(0);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ new PriorityBlockingQueue(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+ try {
+ new PriorityBlockingQueue(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = i;
+ Collection<Integer> elements = Arrays.asList(ints);
+ try {
+ new PriorityBlockingQueue(elements);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = i;
+ PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * The comparator used in constructor is used
+ */
+ public void testConstructor7() {
+ MyReverseComparator cmp = new MyReverseComparator();
+ PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE, cmp);
+ assertEquals(cmp, q.comparator());
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ for (int i = SIZE-1; i >= 0; --i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ PriorityBlockingQueue q = new PriorityBlockingQueue(2);
+ assertTrue(q.isEmpty());
+ assertEquals(NOCAP, q.remainingCapacity());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ q.add(two);
+ q.remove();
+ q.remove();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * remainingCapacity does not change when elements added or removed,
+ * but size does
+ */
+ public void testRemainingCapacity() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(NOCAP, q.remainingCapacity());
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(NOCAP, q.remainingCapacity());
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * Offer of comparable element succeeds
+ */
+ public void testOffer() {
+ PriorityBlockingQueue q = new PriorityBlockingQueue(1);
+ assertTrue(q.offer(zero));
+ assertTrue(q.offer(one));
+ }
+
+ /**
+ * Offer of non-Comparable throws CCE
+ */
+ public void testOfferNonComparable() {
+ try {
+ PriorityBlockingQueue q = new PriorityBlockingQueue(1);
+ q.offer(new Object());
+ q.offer(new Object());
+ q.offer(new Object());
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * add of comparable succeeds
+ */
+ public void testAdd() {
+ PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ assertTrue(q.add(new Integer(i)));
+ }
+ }
+
+ /**
+ * addAll(this) throws IAE
+ */
+ public void testAddAllSelf() {
+ try {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = SIZE-1; i >= 0; --i)
+ ints[i] = new Integer(i);
+ PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * all elements successfully put are contained
+ */
+ public void testPut() {
+ PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ Integer I = new Integer(i);
+ q.put(I);
+ assertTrue(q.contains(I));
+ }
+ assertEquals(SIZE, q.size());
+ }
+
+ /**
+ * put doesn't block waiting for take
+ */
+ public void testPutWithTake() throws InterruptedException {
+ final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
+ final int size = 4;
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ for (int i = 0; i < size; i++)
+ q.put(new Integer(0));
+ }});
+
+ awaitTermination(t);
+ assertEquals(size, q.size());
+ q.take();
+ }
+
+ /**
+ * timed offer does not time out
+ */
+ public void testTimedOffer() throws InterruptedException {
+ final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ q.put(new Integer(0));
+ q.put(new Integer(0));
+ assertTrue(q.offer(new Integer(0), SHORT_DELAY_MS, MILLISECONDS));
+ assertTrue(q.offer(new Integer(0), LONG_DELAY_MS, MILLISECONDS));
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * take retrieves elements in priority order
+ */
+ public void testTake() throws InterruptedException {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+ }
+
+ /**
+ * Take removes existing elements until empty, then blocks interruptibly
+ */
+ public void testBlockingTake() throws InterruptedException {
+ final PriorityBlockingQueue q = populatedQueue(SIZE);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.take());
+ }
+
+ Thread.currentThread().interrupt();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.take();
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * timed poll with zero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll0() throws InterruptedException {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll(0, MILLISECONDS));
+ }
+ assertNull(q.poll(0, MILLISECONDS));
+ }
+
+ /**
+ * timed poll with nonzero timeout succeeds when non-empty, else times out
+ */
+ public void testTimedPoll() throws InterruptedException {
+ PriorityBlockingQueue<Integer> q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ long startTime = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ checkEmpty(q);
+ }
+
+ /**
+ * Interrupted timed poll throws InterruptedException instead of
+ * returning timeout status
+ */
+ public void testInterruptedTimedPoll() throws InterruptedException {
+ final BlockingQueue<Integer> q = populatedQueue(SIZE);
+ final CountDownLatch aboutToWait = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < SIZE; ++i) {
+ long t0 = System.nanoTime();
+ assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+ }
+ long t0 = System.nanoTime();
+ aboutToWait.countDown();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {
+ assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+ }
+ }});
+
+ aboutToWait.await();
+ waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+ t.interrupt();
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.poll());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * element returns next element, or throws NSEE if empty
+ */
+ public void testElement() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ assertEquals(i, q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.poll();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(one));
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ PriorityBlockingQueue p = new PriorityBlockingQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ PriorityBlockingQueue p = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ PriorityBlockingQueue p = populatedQueue(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * toArray contains all elements
+ */
+ public void testToArray() throws InterruptedException {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ Object[] o = q.toArray();
+ Arrays.sort(o);
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.take());
+ }
+
+ /**
+ * toArray(a) contains all elements
+ */
+ public void testToArray2() throws InterruptedException {
+ PriorityBlockingQueue<Integer> q = populatedQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ Arrays.sort(ints);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.take());
+ }
+
+ /**
+ * toArray(incompatible array type) throws ArrayStoreException
+ */
+ public void testToArray1_BadArg() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ try {
+ q.toArray(new String[10]);
+ shouldThrow();
+ } catch (ArrayStoreException success) {}
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final PriorityBlockingQueue q = new PriorityBlockingQueue(3);
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ q.add(new Integer(3));
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertEquals(it.next(), new Integer(2));
+ assertEquals(it.next(), new Integer(3));
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * timed poll transfers elements across Executor tasks
+ */
+ public void testPollInExecutor() {
+ final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertNull(q.poll());
+ threadsStarted.await();
+ assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ checkEmpty(q);
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ q.put(one);
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * A deserialized serialized queue has same elements
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedQueue(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * drainTo(c) empties queue into another collection c
+ */
+ public void testDrainTo() {
+ PriorityBlockingQueue q = populatedQueue(SIZE);
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(SIZE, l.size());
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ q.add(zero);
+ q.add(one);
+ assertFalse(q.isEmpty());
+ assertTrue(q.contains(zero));
+ assertTrue(q.contains(one));
+ l.clear();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(2, l.size());
+ for (int i = 0; i < 2; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ }
+
+ /**
+ * drainTo empties queue
+ */
+ public void testDrainToWithActivePut() throws InterruptedException {
+ final PriorityBlockingQueue q = populatedQueue(SIZE);
+ Thread t = new Thread(new CheckedRunnable() {
+ public void realRun() {
+ q.put(new Integer(SIZE+1));
+ }});
+
+ t.start();
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertTrue(l.size() >= SIZE);
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(l.get(i), new Integer(i));
+ t.join();
+ assertTrue(q.size() + l.size() >= SIZE);
+ }
+
+ /**
+ * drainTo(c, n) empties first min(n, size) elements of queue into c
+ */
+ public void testDrainToN() {
+ PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE*2);
+ for (int i = 0; i < SIZE + 2; ++i) {
+ for (int j = 0; j < SIZE; j++)
+ assertTrue(q.offer(new Integer(j)));
+ ArrayList l = new ArrayList();
+ q.drainTo(l, i);
+ int k = (i < SIZE) ? i : SIZE;
+ assertEquals(k, l.size());
+ assertEquals(SIZE-k, q.size());
+ for (int j = 0; j < k; ++j)
+ assertEquals(l.get(j), new Integer(j));
+ while (q.poll() != null) ;
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java b/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java
new file mode 100644
index 0000000..2b237dd
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java
@@ -0,0 +1,492 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
+import java.util.Queue;
+
+public class PriorityQueueTest extends JSR166TestCase {
+
+ static class MyReverseComparator implements Comparator {
+ public int compare(Object x, Object y) {
+ return ((Comparable)y).compareTo(x);
+ }
+ }
+
+ /**
+ * Returns a new queue of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private PriorityQueue<Integer> populatedQueue(int n) {
+ PriorityQueue<Integer> q = new PriorityQueue<Integer>(n);
+ assertTrue(q.isEmpty());
+ for (int i = n-1; i >= 0; i-=2)
+ assertTrue(q.offer(new Integer(i)));
+ for (int i = (n & 1); i < n; i+=2)
+ assertTrue(q.offer(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * A new queue has unbounded capacity
+ */
+ public void testConstructor1() {
+ assertEquals(0, new PriorityQueue(SIZE).size());
+ }
+
+ /**
+ * Constructor throws IAE if capacity argument nonpositive
+ */
+ public void testConstructor2() {
+ try {
+ PriorityQueue q = new PriorityQueue(0);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ PriorityQueue q = new PriorityQueue((Collection)null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * The comparator used in constructor is used
+ */
+ public void testConstructor7() {
+ MyReverseComparator cmp = new MyReverseComparator();
+ PriorityQueue q = new PriorityQueue(SIZE, cmp);
+ assertEquals(cmp, q.comparator());
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ for (int i = SIZE-1; i >= 0; --i)
+ assertEquals(ints[i], q.poll());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ PriorityQueue q = new PriorityQueue(2);
+ assertTrue(q.isEmpty());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.add(new Integer(2));
+ q.remove();
+ q.remove();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ PriorityQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.remove();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * offer(null) throws NPE
+ */
+ public void testOfferNull() {
+ try {
+ PriorityQueue q = new PriorityQueue(1);
+ q.offer(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * add(null) throws NPE
+ */
+ public void testAddNull() {
+ try {
+ PriorityQueue q = new PriorityQueue(1);
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Offer of comparable element succeeds
+ */
+ public void testOffer() {
+ PriorityQueue q = new PriorityQueue(1);
+ assertTrue(q.offer(zero));
+ assertTrue(q.offer(one));
+ }
+
+ /**
+ * Offer of non-Comparable throws CCE
+ */
+ public void testOfferNonComparable() {
+ try {
+ PriorityQueue q = new PriorityQueue(1);
+ q.offer(new Object());
+ q.offer(new Object());
+ q.offer(new Object());
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * add of comparable succeeds
+ */
+ public void testAdd() {
+ PriorityQueue q = new PriorityQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ assertTrue(q.add(new Integer(i)));
+ }
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ PriorityQueue q = new PriorityQueue(1);
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ PriorityQueue q = new PriorityQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ PriorityQueue q = new PriorityQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Queue contains all elements of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(SIZE-1-i);
+ PriorityQueue q = new PriorityQueue(SIZE);
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(new Integer(i), q.poll());
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ PriorityQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.poll());
+ }
+ assertNull(q.poll());
+ }
+
+ /**
+ * peek returns next element, or null if empty
+ */
+ public void testPeek() {
+ PriorityQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.peek());
+ assertEquals(i, q.poll());
+ assertTrue(q.peek() == null ||
+ !q.peek().equals(i));
+ }
+ assertNull(q.peek());
+ }
+
+ /**
+ * element returns next element, or throws NSEE if empty
+ */
+ public void testElement() {
+ PriorityQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.element());
+ assertEquals(i, q.poll());
+ }
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove removes next element, or throws NSEE if empty
+ */
+ public void testRemove() {
+ PriorityQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.remove());
+ }
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ PriorityQueue q = populatedQueue(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove(i+1));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ PriorityQueue q = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.poll();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ PriorityQueue q = populatedQueue(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ PriorityQueue q = populatedQueue(SIZE);
+ PriorityQueue p = new PriorityQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ PriorityQueue q = populatedQueue(SIZE);
+ PriorityQueue p = populatedQueue(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.remove();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ PriorityQueue q = populatedQueue(SIZE);
+ PriorityQueue p = populatedQueue(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.remove());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * toArray contains all elements
+ */
+ public void testToArray() {
+ PriorityQueue q = populatedQueue(SIZE);
+ Object[] o = q.toArray();
+ Arrays.sort(o);
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.poll());
+ }
+
+ /**
+ * toArray(a) contains all elements
+ */
+ public void testToArray2() {
+ PriorityQueue<Integer> q = populatedQueue(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ Arrays.sort(ints);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.poll());
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ PriorityQueue q = populatedQueue(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final PriorityQueue q = new PriorityQueue(3);
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ q.add(new Integer(3));
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertEquals(it.next(), new Integer(2));
+ assertEquals(it.next(), new Integer(3));
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ PriorityQueue q = populatedQueue(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized queue has same elements
+ */
+ public void testSerialization() throws Exception {
+ Queue x = populatedQueue(SIZE);
+ Queue y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.remove(), y.remove());
+ }
+ assertTrue(y.isEmpty());
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java b/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java
new file mode 100644
index 0000000..ad61a2e
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java
@@ -0,0 +1,1237 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class RecursiveActionTest extends JSR166TestCase {
+
+ private static ForkJoinPool mainPool() {
+ return new ForkJoinPool();
+ }
+
+ private static ForkJoinPool singletonPool() {
+ return new ForkJoinPool(1);
+ }
+
+ private static ForkJoinPool asyncSingletonPool() {
+ return new ForkJoinPool(1,
+ ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+ null, true);
+ }
+
+ private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
+ try {
+ checkNotDone(a);
+
+ assertNull(pool.invoke(a));
+
+ checkCompletedNormally(a);
+ } finally {
+ joinPool(pool);
+ }
+ }
+
+ void checkNotDone(RecursiveAction a) {
+ assertFalse(a.isDone());
+ assertFalse(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+
+ if (! ForkJoinTask.inForkJoinPool()) {
+ Thread.currentThread().interrupt();
+ try {
+ a.get();
+ shouldThrow();
+ } catch (InterruptedException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ Thread.currentThread().interrupt();
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ try {
+ a.get(0L, SECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCompletedNormally(RecursiveAction a) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertTrue(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+ assertNull(a.join());
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+ try {
+ assertNull(a.get());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ try {
+ assertNull(a.get(5L, SECONDS));
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCancelled(RecursiveAction a) {
+ assertTrue(a.isDone());
+ assertTrue(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertTrue(a.getException() instanceof CancellationException);
+ assertNull(a.getRawResult());
+
+ try {
+ a.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCompletedAbnormally(RecursiveAction a, Throwable t) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertSame(t.getClass(), a.getException().getClass());
+ assertNull(a.getRawResult());
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+
+ try {
+ a.join();
+ shouldThrow();
+ } catch (Throwable expected) {
+ assertSame(expected.getClass(), t.getClass());
+ }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ public static final class FJException extends RuntimeException {
+ public FJException() { super(); }
+ public FJException(Throwable cause) { super(cause); }
+ }
+
+ // A simple recursive action for testing
+ final class FibAction extends CheckedRecursiveAction {
+ final int number;
+ int result;
+ FibAction(int n) { number = n; }
+ protected void realCompute() {
+ int n = number;
+ if (n <= 1)
+ result = n;
+ else {
+ FibAction f1 = new FibAction(n - 1);
+ FibAction f2 = new FibAction(n - 2);
+ invokeAll(f1, f2);
+ result = f1.result + f2.result;
+ }
+ }
+ }
+
+ // A recursive action failing in base case
+ static final class FailingFibAction extends RecursiveAction {
+ final int number;
+ int result;
+ FailingFibAction(int n) { number = n; }
+ public void compute() {
+ int n = number;
+ if (n <= 1)
+ throw new FJException();
+ else {
+ FailingFibAction f1 = new FailingFibAction(n - 1);
+ FailingFibAction f2 = new FailingFibAction(n - 2);
+ invokeAll(f1, f2);
+ result = f1.result + f2.result;
+ }
+ }
+ }
+
+ /**
+ * invoke returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks. getRawResult of a RecursiveAction returns null;
+ */
+ public void testInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ assertNull(f.invoke());
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks
+ */
+ public void testQuietlyInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ f.quietlyInvoke();
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task returns when task completes
+ */
+ public void testForkJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertNull(f.join());
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join/quietlyJoin of a forked task succeeds in the presence of interrupts
+ */
+ public void testJoinIgnoresInterrupts() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ final Thread myself = Thread.currentThread();
+
+ // test join()
+ assertSame(f, f.fork());
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ assertNull(f.join());
+ Thread.interrupted();
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+
+ f = new FibAction(8);
+ f.cancel(true);
+ assertSame(f, f.fork());
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ Thread.interrupted();
+ checkCancelled(f);
+ }
+
+ f = new FibAction(8);
+ f.completeExceptionally(new FJException());
+ assertSame(f, f.fork());
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ Thread.interrupted();
+ checkCompletedAbnormally(f, success);
+ }
+
+ // test quietlyJoin()
+ f = new FibAction(8);
+ assertSame(f, f.fork());
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ f.quietlyJoin();
+ Thread.interrupted();
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+
+ f = new FibAction(8);
+ f.cancel(true);
+ assertSame(f, f.fork());
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ f.quietlyJoin();
+ Thread.interrupted();
+ checkCancelled(f);
+
+ f = new FibAction(8);
+ f.completeExceptionally(new FJException());
+ assertSame(f, f.fork());
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ f.quietlyJoin();
+ Thread.interrupted();
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ a.reinitialize();
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * join/quietlyJoin of a forked task when not in ForkJoinPool
+ * succeeds in the presence of interrupts
+ */
+ public void testJoinIgnoresInterruptsOutsideForkJoinPool() {
+ final SynchronousQueue<FibAction[]> sq =
+ new SynchronousQueue<FibAction[]>();
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws InterruptedException {
+ FibAction[] fibActions = new FibAction[6];
+ for (int i = 0; i < fibActions.length; i++)
+ fibActions[i] = new FibAction(8);
+
+ fibActions[1].cancel(false);
+ fibActions[2].completeExceptionally(new FJException());
+ fibActions[4].cancel(true);
+ fibActions[5].completeExceptionally(new FJException());
+
+ for (int i = 0; i < fibActions.length; i++)
+ fibActions[i].fork();
+
+ sq.put(fibActions);
+
+ helpQuiesce();
+ }};
+
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ FibAction[] fibActions = sq.take();
+ FibAction f;
+ final Thread myself = Thread.currentThread();
+
+ // test join() ------------
+
+ f = fibActions[0];
+ assertFalse(ForkJoinTask.inForkJoinPool());
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ assertNull(f.join());
+ assertTrue(Thread.interrupted());
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+
+ f = fibActions[1];
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ assertTrue(Thread.interrupted());
+ checkCancelled(f);
+ }
+
+ f = fibActions[2];
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ assertTrue(Thread.interrupted());
+ checkCompletedAbnormally(f, success);
+ }
+
+ // test quietlyJoin() ---------
+
+ f = fibActions[3];
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ f.quietlyJoin();
+ assertTrue(Thread.interrupted());
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+
+ f = fibActions[4];
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ f.quietlyJoin();
+ assertTrue(Thread.interrupted());
+ checkCancelled(f);
+
+ f = fibActions[5];
+ myself.interrupt();
+ assertTrue(myself.isInterrupted());
+ f.quietlyJoin();
+ assertTrue(Thread.interrupted());
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+
+ Thread t;
+
+ t = newStartedThread(r);
+ testInvokeOnPool(mainPool(), a);
+ awaitTermination(t, LONG_DELAY_MS);
+
+ a.reinitialize();
+ t = newStartedThread(r);
+ testInvokeOnPool(singletonPool(), a);
+ awaitTermination(t, LONG_DELAY_MS);
+ }
+
+ /**
+ * get of a forked task returns when task completes
+ */
+ public void testForkGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertNull(f.get());
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task returns when task completes
+ */
+ public void testForkTimedGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertNull(f.get(5L, SECONDS));
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get with null time unit throws NPE
+ */
+ public void testForkTimedGetNPE() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(5L, null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes
+ */
+ public void testForkQuietlyJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * helpQuiesce returns when tasks are complete.
+ * getQueuedTaskCount returns 0 when quiescent
+ */
+ public void testForkHelpQuiesce() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ helpQuiesce();
+ assertEquals(21, f.result);
+ assertEquals(0, getQueuedTaskCount());
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task completes abnormally
+ */
+ public void testAbnormalInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingFibAction f = new FailingFibAction(8);
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes abnormally
+ */
+ public void testAbnormalQuietlyInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingFibAction f = new FailingFibAction(8);
+ f.quietlyInvoke();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingFibAction f = new FailingFibAction(8);
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingFibAction f = new FailingFibAction(8);
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkTimedGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FailingFibAction f = new FailingFibAction(8);
+ assertSame(f, f.fork());
+ try {
+ f.get(5L, TimeUnit.SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes abnormally
+ */
+ public void testAbnormalForkQuietlyJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingFibAction f = new FailingFibAction(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invoke task throws exception when task cancelled
+ */
+ public void testCancelledInvoke() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ assertTrue(f.cancel(true));
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * join of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FibAction f = new FibAction(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * timed get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkTimedGet() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() throws Exception {
+ FibAction f = new FibAction(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ f.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task cancelled
+ */
+ public void testCancelledForkQuietlyJoin() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ checkCancelled(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * getPool of executing task returns its pool
+ */
+ public void testGetPool() {
+ final ForkJoinPool mainPool = mainPool();
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertSame(mainPool, getPool());
+ }};
+ testInvokeOnPool(mainPool, a);
+ }
+
+ /**
+ * getPool of non-FJ task returns null
+ */
+ public void testGetPool2() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertNull(getPool());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * inForkJoinPool of executing task returns true
+ */
+ public void testInForkJoinPool() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertTrue(inForkJoinPool());
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * inForkJoinPool of non-FJ task returns false
+ */
+ public void testInForkJoinPool2() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ assertFalse(inForkJoinPool());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * getPool of current thread in pool returns its pool
+ */
+ public void testWorkerGetPool() {
+ final ForkJoinPool mainPool = mainPool();
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ ForkJoinWorkerThread w =
+ (ForkJoinWorkerThread) Thread.currentThread();
+ assertSame(mainPool, w.getPool());
+ }};
+ testInvokeOnPool(mainPool, a);
+ }
+
+ /**
+ * getPoolIndex of current thread in pool returns 0 <= value < poolSize
+ */
+ public void testWorkerGetPoolIndex() {
+ final ForkJoinPool mainPool = mainPool();
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ ForkJoinWorkerThread w =
+ (ForkJoinWorkerThread) Thread.currentThread();
+ assertTrue(w.getPoolIndex() >= 0);
+ // pool size can shrink after assigning index, so cannot check
+ // assertTrue(w.getPoolIndex() < mainPool.getPoolSize());
+ }};
+ testInvokeOnPool(mainPool, a);
+ }
+
+ /**
+ * setRawResult(null) succeeds
+ */
+ public void testSetRawResult() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ setRawResult(null);
+ assertNull(getRawResult());
+ }};
+ assertNull(a.invoke());
+ }
+
+ /**
+ * A reinitialized normally completed task may be re-invoked
+ */
+ public void testReinitialize() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ checkNotDone(f);
+
+ for (int i = 0; i < 3; i++) {
+ assertNull(f.invoke());
+ assertEquals(21, f.result);
+ checkCompletedNormally(f);
+ f.reinitialize();
+ checkNotDone(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * A reinitialized abnormally completed task may be re-invoked
+ */
+ public void testReinitializeAbnormal() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingFibAction f = new FailingFibAction(8);
+ checkNotDone(f);
+
+ for (int i = 0; i < 3; i++) {
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ f.reinitialize();
+ checkNotDone(f);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invoke task throws exception after invoking completeExceptionally
+ */
+ public void testCompleteExceptionally() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ f.completeExceptionally(new FJException());
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invoke task suppresses execution invoking complete
+ */
+ public void testComplete() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ f.complete(null);
+ assertNull(f.invoke());
+ assertEquals(0, f.result);
+ checkCompletedNormally(f);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) invokes all task arguments
+ */
+ public void testInvokeAll2() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ FibAction g = new FibAction(9);
+ invokeAll(f, g);
+ checkCompletedNormally(f);
+ assertEquals(21, f.result);
+ checkCompletedNormally(g);
+ assertEquals(34, g.result);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument invokes task
+ */
+ public void testInvokeAll1() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ invokeAll(f);
+ checkCompletedNormally(f);
+ assertEquals(21, f.result);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument invokes tasks
+ */
+ public void testInvokeAll3() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ FibAction g = new FibAction(9);
+ FibAction h = new FibAction(7);
+ invokeAll(f, g, h);
+ assertTrue(f.isDone());
+ assertTrue(g.isDone());
+ assertTrue(h.isDone());
+ checkCompletedNormally(f);
+ assertEquals(21, f.result);
+ checkCompletedNormally(g);
+ assertEquals(34, g.result);
+ checkCompletedNormally(g);
+ assertEquals(13, h.result);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) invokes all tasks in the collection
+ */
+ public void testInvokeAllCollection() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ FibAction g = new FibAction(9);
+ FibAction h = new FibAction(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ invokeAll(set);
+ assertTrue(f.isDone());
+ assertTrue(g.isDone());
+ assertTrue(h.isDone());
+ checkCompletedNormally(f);
+ assertEquals(21, f.result);
+ checkCompletedNormally(g);
+ assertEquals(34, g.result);
+ checkCompletedNormally(g);
+ assertEquals(13, h.result);
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with any null task throws NPE
+ */
+ public void testInvokeAllNPE() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ FibAction g = new FibAction(9);
+ FibAction h = null;
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(t1, t2) throw exception if any task does
+ */
+ public void testAbnormalInvokeAll2() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ FailingFibAction g = new FailingFibAction(9);
+ try {
+ invokeAll(f, g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument throws exception if task does
+ */
+ public void testAbnormalInvokeAll1() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingFibAction g = new FailingFibAction(9);
+ try {
+ invokeAll(g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument throws exception if any task does
+ */
+ public void testAbnormalInvokeAll3() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction f = new FibAction(8);
+ FailingFibAction g = new FailingFibAction(9);
+ FibAction h = new FibAction(7);
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * invokeAll(collection) throws exception if any task does
+ */
+ public void testAbnormalInvokeAllCollection() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FailingFibAction f = new FailingFibAction(8);
+ FibAction g = new FibAction(9);
+ FibAction h = new FibAction(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ try {
+ invokeAll(set);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ }};
+ testInvokeOnPool(mainPool(), a);
+ }
+
+ /**
+ * tryUnfork returns true for most recent unexecuted task,
+ * and suppresses execution
+ */
+ public void testTryUnfork() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction g = new FibAction(9);
+ assertSame(g, g.fork());
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertTrue(f.tryUnfork());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * getSurplusQueuedTaskCount returns > 0 when
+ * there are more tasks than threads
+ */
+ public void testGetSurplusQueuedTaskCount() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction h = new FibAction(7);
+ assertSame(h, h.fork());
+ FibAction g = new FibAction(9);
+ assertSame(g, g.fork());
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertTrue(getSurplusQueuedTaskCount() > 0);
+ helpQuiesce();
+ assertEquals(0, getSurplusQueuedTaskCount());
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ checkCompletedNormally(h);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * peekNextLocalTask returns most recent unexecuted task.
+ */
+ public void testPeekNextLocalTask() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction g = new FibAction(9);
+ assertSame(g, g.fork());
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertSame(f, peekNextLocalTask());
+ assertNull(f.join());
+ checkCompletedNormally(f);
+ helpQuiesce();
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * pollNextLocalTask returns most recent unexecuted task
+ * without executing it
+ */
+ public void testPollNextLocalTask() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction g = new FibAction(9);
+ assertSame(g, g.fork());
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollNextLocalTask());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it
+ */
+ public void testPollTask() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction g = new FibAction(9);
+ assertSame(g, g.fork());
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollTask());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(singletonPool(), a);
+ }
+
+ /**
+ * peekNextLocalTask returns least recent unexecuted task in async mode
+ */
+ public void testPeekNextLocalTaskAsync() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction g = new FibAction(9);
+ assertSame(g, g.fork());
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertSame(g, peekNextLocalTask());
+ assertNull(f.join());
+ helpQuiesce();
+ checkCompletedNormally(f);
+ checkCompletedNormally(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ /**
+ * pollNextLocalTask returns least recent unexecuted task without
+ * executing it, in async mode
+ */
+ public void testPollNextLocalTaskAsync() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction g = new FibAction(9);
+ assertSame(g, g.fork());
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollNextLocalTask());
+ helpQuiesce();
+ checkCompletedNormally(f);
+ checkNotDone(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it, in
+ * async mode
+ */
+ public void testPollTaskAsync() {
+ RecursiveAction a = new CheckedRecursiveAction() {
+ protected void realCompute() {
+ FibAction g = new FibAction(9);
+ assertSame(g, g.fork());
+ FibAction f = new FibAction(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollTask());
+ helpQuiesce();
+ checkCompletedNormally(f);
+ checkNotDone(g);
+ }};
+ testInvokeOnPool(asyncSingletonPool(), a);
+ }
+
+ /** Demo from RecursiveAction javadoc */
+ static class SortTask extends RecursiveAction {
+ final long[] array; final int lo, hi;
+ SortTask(long[] array, int lo, int hi) {
+ this.array = array; this.lo = lo; this.hi = hi;
+ }
+ SortTask(long[] array) { this(array, 0, array.length); }
+ protected void compute() {
+ if (hi - lo < THRESHOLD)
+ sortSequentially(lo, hi);
+ else {
+ int mid = (lo + hi) >>> 1;
+ invokeAll(new SortTask(array, lo, mid),
+ new SortTask(array, mid, hi));
+ merge(lo, mid, hi);
+ }
+ }
+ // implementation details follow:
+ static final int THRESHOLD = 100;
+ void sortSequentially(int lo, int hi) {
+ Arrays.sort(array, lo, hi);
+ }
+ void merge(int lo, int mid, int hi) {
+ long[] buf = Arrays.copyOfRange(array, lo, mid);
+ for (int i = 0, j = lo, k = mid; i < buf.length; j++)
+ array[j] = (k == hi || buf[i] < array[k]) ?
+ buf[i++] : array[k++];
+ }
+ }
+
+ /**
+ * SortTask demo works as advertised
+ */
+ public void testSortTaskDemo() {
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ long[] array = new long[1007];
+ for (int i = 0; i < array.length; i++)
+ array[i] = rnd.nextLong();
+ long[] arrayClone = array.clone();
+ testInvokeOnPool(mainPool(), new SortTask(array));
+ Arrays.sort(arrayClone);
+ assertTrue(Arrays.equals(array, arrayClone));
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java b/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java
new file mode 100644
index 0000000..48b6470
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java
@@ -0,0 +1,1020 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import java.util.HashSet;
+
+public class RecursiveTaskTest extends JSR166TestCase {
+
+ private static ForkJoinPool mainPool() {
+ return new ForkJoinPool();
+ }
+
+ private static ForkJoinPool singletonPool() {
+ return new ForkJoinPool(1);
+ }
+
+ private static ForkJoinPool asyncSingletonPool() {
+ return new ForkJoinPool(1,
+ ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+ null, true);
+ }
+
+ private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) {
+ try {
+ checkNotDone(a);
+
+ T result = pool.invoke(a);
+
+ checkCompletedNormally(a, result);
+ return result;
+ } finally {
+ joinPool(pool);
+ }
+ }
+
+ void checkNotDone(RecursiveTask a) {
+ assertFalse(a.isDone());
+ assertFalse(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertFalse(a.isCancelled());
+ assertNull(a.getException());
+ assertNull(a.getRawResult());
+
+ if (! ForkJoinTask.inForkJoinPool()) {
+ Thread.currentThread().interrupt();
+ try {
+ a.get();
+ shouldThrow();
+ } catch (InterruptedException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ Thread.currentThread().interrupt();
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ try {
+ a.get(0L, SECONDS);
+ shouldThrow();
+ } catch (TimeoutException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ <T> void checkCompletedNormally(RecursiveTask<T> a, T expected) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertTrue(a.isCompletedNormally());
+ assertFalse(a.isCompletedAbnormally());
+ assertNull(a.getException());
+ assertSame(expected, a.getRawResult());
+ assertSame(expected, a.join());
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+ try {
+ assertSame(expected, a.get());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ try {
+ assertSame(expected, a.get(5L, SECONDS));
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ /**
+ * Waits for the task to complete, and checks that when it does,
+ * it will have an Integer result equals to the given int.
+ */
+ void checkCompletesNormally(RecursiveTask<Integer> a, int expected) {
+ Integer r = a.join();
+ assertEquals(expected, (int) r);
+ checkCompletedNormally(a, r);
+ }
+
+ /**
+ * Like checkCompletesNormally, but verifies that the task has
+ * already completed.
+ */
+ void checkCompletedNormally(RecursiveTask<Integer> a, int expected) {
+ Integer r = a.getRawResult();
+ assertEquals(expected, (int) r);
+ checkCompletedNormally(a, r);
+ }
+
+ void checkCancelled(RecursiveTask a) {
+ assertTrue(a.isDone());
+ assertTrue(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertTrue(a.getException() instanceof CancellationException);
+ assertNull(a.getRawResult());
+
+ try {
+ a.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ void checkCompletedAbnormally(RecursiveTask a, Throwable t) {
+ assertTrue(a.isDone());
+ assertFalse(a.isCancelled());
+ assertFalse(a.isCompletedNormally());
+ assertTrue(a.isCompletedAbnormally());
+ assertSame(t.getClass(), a.getException().getClass());
+ assertNull(a.getRawResult());
+ assertFalse(a.cancel(false));
+ assertFalse(a.cancel(true));
+
+ try {
+ a.join();
+ shouldThrow();
+ } catch (Throwable expected) {
+ assertSame(t.getClass(), expected.getClass());
+ }
+
+ try {
+ a.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+ try {
+ a.get(5L, SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertSame(t.getClass(), success.getCause().getClass());
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+
+ public static final class FJException extends RuntimeException {
+ public FJException() { super(); }
+ }
+
+ // An invalid return value for Fib
+ static final Integer NoResult = Integer.valueOf(-17);
+
+ // A simple recursive task for testing
+ final class FibTask extends CheckedRecursiveTask<Integer> {
+ final int number;
+ FibTask(int n) { number = n; }
+ public Integer realCompute() {
+ int n = number;
+ if (n <= 1)
+ return n;
+ FibTask f1 = new FibTask(n - 1);
+ f1.fork();
+ return (new FibTask(n - 2)).compute() + f1.join();
+ }
+
+ public void publicSetRawResult(Integer result) {
+ setRawResult(result);
+ }
+ }
+
+ // A recursive action failing in base case
+ final class FailingFibTask extends RecursiveTask<Integer> {
+ final int number;
+ int result;
+ FailingFibTask(int n) { number = n; }
+ public Integer compute() {
+ int n = number;
+ if (n <= 1)
+ throw new FJException();
+ FailingFibTask f1 = new FailingFibTask(n - 1);
+ f1.fork();
+ return (new FibTask(n - 2)).compute() + f1.join();
+ }
+ }
+
+ /**
+ * invoke returns value when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks. getRawResult of a completed non-null task
+ * returns value;
+ */
+ public void testInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ Integer r = f.invoke();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes normally.
+ * isCompletedAbnormally and isCancelled return false for normally
+ * completed tasks
+ */
+ public void testQuietlyInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ f.quietlyInvoke();
+ checkCompletedNormally(f, 21);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * join of a forked task returns when task completes
+ */
+ public void testForkJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ Integer r = f.join();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * get of a forked task returns when task completes
+ */
+ public void testForkGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ Integer r = f.get();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * timed get of a forked task returns when task completes
+ */
+ public void testForkTimedGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ Integer r = f.get(5L, SECONDS);
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes
+ */
+ public void testForkQuietlyJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ Integer r = f.getRawResult();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ return r;
+ }};
+ assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * helpQuiesce returns when tasks are complete.
+ * getQueuedTaskCount returns 0 when quiescent
+ */
+ public void testForkHelpQuiesce() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ helpQuiesce();
+ assertEquals(0, getQueuedTaskCount());
+ checkCompletedNormally(f, 21);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invoke task throws exception when task completes abnormally
+ */
+ public void testAbnormalInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyInvoke task returns when task completes abnormally
+ */
+ public void testAbnormalQuietlyInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ f.quietlyInvoke();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * join of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.join();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FailingFibTask f = new FailingFibTask(8);
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * timed get of a forked task throws exception when task completes abnormally
+ */
+ public void testAbnormalForkTimedGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FailingFibTask f = new FailingFibTask(8);
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.get(5L, SECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ Throwable cause = success.getCause();
+ assertTrue(cause instanceof FJException);
+ checkCompletedAbnormally(f, cause);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task completes abnormally
+ */
+ public void testAbnormalForkQuietlyJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ assertTrue(f.getException() instanceof FJException);
+ checkCompletedAbnormally(f, f.getException());
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invoke task throws exception when task cancelled
+ */
+ public void testCancelledInvoke() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ try {
+ Integer r = f.invoke();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * join of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.join();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.get();
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * timed get of a forked task throws exception when task cancelled
+ */
+ public void testCancelledForkTimedGet() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() throws Exception {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ try {
+ Integer r = f.get(5L, SECONDS);
+ shouldThrow();
+ } catch (CancellationException success) {
+ checkCancelled(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * quietlyJoin of a forked task returns when task cancelled
+ */
+ public void testCancelledForkQuietlyJoin() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ assertTrue(f.cancel(true));
+ assertSame(f, f.fork());
+ f.quietlyJoin();
+ checkCancelled(f);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * getPool of executing task returns its pool
+ */
+ public void testGetPool() {
+ final ForkJoinPool mainPool = mainPool();
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ assertSame(mainPool, getPool());
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool, a));
+ }
+
+ /**
+ * getPool of non-FJ task returns null
+ */
+ public void testGetPool2() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ assertNull(getPool());
+ return NoResult;
+ }};
+ assertSame(NoResult, a.invoke());
+ }
+
+ /**
+ * inForkJoinPool of executing task returns true
+ */
+ public void testInForkJoinPool() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ assertTrue(inForkJoinPool());
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * inForkJoinPool of non-FJ task returns false
+ */
+ public void testInForkJoinPool2() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ assertFalse(inForkJoinPool());
+ return NoResult;
+ }};
+ assertSame(NoResult, a.invoke());
+ }
+
+ /**
+ * The value set by setRawResult is returned by getRawResult
+ */
+ public void testSetRawResult() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ setRawResult(NoResult);
+ assertSame(NoResult, getRawResult());
+ return NoResult;
+ }
+ };
+ assertSame(NoResult, a.invoke());
+ }
+
+ /**
+ * A reinitialized normally completed task may be re-invoked
+ */
+ public void testReinitialize() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ checkNotDone(f);
+
+ for (int i = 0; i < 3; i++) {
+ Integer r = f.invoke();
+ assertEquals(21, (int) r);
+ checkCompletedNormally(f, r);
+ f.reinitialize();
+ f.publicSetRawResult(null);
+ checkNotDone(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * A reinitialized abnormally completed task may be re-invoked
+ */
+ public void testReinitializeAbnormal() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ checkNotDone(f);
+
+ for (int i = 0; i < 3; i++) {
+ try {
+ f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ f.reinitialize();
+ checkNotDone(f);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invoke task throws exception after invoking completeExceptionally
+ */
+ public void testCompleteExceptionally() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ f.completeExceptionally(new FJException());
+ try {
+ Integer r = f.invoke();
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invoke task suppresses execution invoking complete
+ */
+ public void testComplete() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ f.complete(NoResult);
+ Integer r = f.invoke();
+ assertSame(NoResult, r);
+ checkCompletedNormally(f, NoResult);
+ return r;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(t1, t2) invokes all task arguments
+ */
+ public void testInvokeAll2() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FibTask g = new FibTask(9);
+ invokeAll(f, g);
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument invokes task
+ */
+ public void testInvokeAll1() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ invokeAll(f);
+ checkCompletedNormally(f, 21);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument invokes tasks
+ */
+ public void testInvokeAll3() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FibTask g = new FibTask(9);
+ FibTask h = new FibTask(7);
+ invokeAll(f, g, h);
+ assertTrue(f.isDone());
+ assertTrue(g.isDone());
+ assertTrue(h.isDone());
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ checkCompletedNormally(h, 13);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(collection) invokes all tasks in the collection
+ */
+ public void testInvokeAllCollection() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FibTask g = new FibTask(9);
+ FibTask h = new FibTask(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ invokeAll(set);
+ assertTrue(f.isDone());
+ assertTrue(g.isDone());
+ assertTrue(h.isDone());
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ checkCompletedNormally(h, 13);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with any null task throws NPE
+ */
+ public void testInvokeAllNPE() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FibTask g = new FibTask(9);
+ FibTask h = null;
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(t1, t2) throw exception if any task does
+ */
+ public void testAbnormalInvokeAll2() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FailingFibTask g = new FailingFibTask(9);
+ try {
+ invokeAll(f, g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with 1 argument throws exception if task does
+ */
+ public void testAbnormalInvokeAll1() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask g = new FailingFibTask(9);
+ try {
+ invokeAll(g);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(tasks) with > 2 argument throws exception if any task does
+ */
+ public void testAbnormalInvokeAll3() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask f = new FibTask(8);
+ FailingFibTask g = new FailingFibTask(9);
+ FibTask h = new FibTask(7);
+ try {
+ invokeAll(f, g, h);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(g, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * invokeAll(collection) throws exception if any task does
+ */
+ public void testAbnormalInvokeAllCollection() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FailingFibTask f = new FailingFibTask(8);
+ FibTask g = new FibTask(9);
+ FibTask h = new FibTask(7);
+ HashSet set = new HashSet();
+ set.add(f);
+ set.add(g);
+ set.add(h);
+ try {
+ invokeAll(set);
+ shouldThrow();
+ } catch (FJException success) {
+ checkCompletedAbnormally(f, success);
+ }
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+ }
+
+ /**
+ * tryUnfork returns true for most recent unexecuted task,
+ * and suppresses execution
+ */
+ public void testTryUnfork() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertTrue(f.tryUnfork());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * getSurplusQueuedTaskCount returns > 0 when
+ * there are more tasks than threads
+ */
+ public void testGetSurplusQueuedTaskCount() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask h = new FibTask(7);
+ assertSame(h, h.fork());
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertTrue(getSurplusQueuedTaskCount() > 0);
+ helpQuiesce();
+ assertEquals(0, getSurplusQueuedTaskCount());
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ checkCompletedNormally(h, 13);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * peekNextLocalTask returns most recent unexecuted task.
+ */
+ public void testPeekNextLocalTask() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(f, peekNextLocalTask());
+ checkCompletesNormally(f, 21);
+ helpQuiesce();
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * pollNextLocalTask returns most recent unexecuted task
+ * without executing it
+ */
+ public void testPollNextLocalTask() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollNextLocalTask());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it
+ */
+ public void testPollTask() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(f, pollTask());
+ helpQuiesce();
+ checkNotDone(f);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+ }
+
+ /**
+ * peekNextLocalTask returns least recent unexecuted task in async mode
+ */
+ public void testPeekNextLocalTaskAsync() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(g, peekNextLocalTask());
+ assertEquals(21, (int) f.join());
+ helpQuiesce();
+ checkCompletedNormally(f, 21);
+ checkCompletedNormally(g, 34);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+ }
+
+ /**
+ * pollNextLocalTask returns least recent unexecuted task without
+ * executing it, in async mode
+ */
+ public void testPollNextLocalTaskAsync() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollNextLocalTask());
+ helpQuiesce();
+ checkCompletedNormally(f, 21);
+ checkNotDone(g);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+ }
+
+ /**
+ * pollTask returns an unexecuted task without executing it, in
+ * async mode
+ */
+ public void testPollTaskAsync() {
+ RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+ public Integer realCompute() {
+ FibTask g = new FibTask(9);
+ assertSame(g, g.fork());
+ FibTask f = new FibTask(8);
+ assertSame(f, f.fork());
+ assertSame(g, pollTask());
+ helpQuiesce();
+ checkCompletedNormally(f, 21);
+ checkNotDone(g);
+ return NoResult;
+ }};
+ assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java b/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java
new file mode 100644
index 0000000..6fe8122
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java
@@ -0,0 +1,1133 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.*;
+
+public class ReentrantLockTest extends JSR166TestCase {
+
+ /**
+ * A runnable calling lockInterruptibly
+ */
+ class InterruptibleLockRunnable extends CheckedRunnable {
+ final ReentrantLock lock;
+ InterruptibleLockRunnable(ReentrantLock l) { lock = l; }
+ public void realRun() throws InterruptedException {
+ lock.lockInterruptibly();
+ }
+ }
+
+ /**
+ * A runnable calling lockInterruptibly that expects to be
+ * interrupted
+ */
+ class InterruptedLockRunnable extends CheckedInterruptedRunnable {
+ final ReentrantLock lock;
+ InterruptedLockRunnable(ReentrantLock l) { lock = l; }
+ public void realRun() throws InterruptedException {
+ lock.lockInterruptibly();
+ }
+ }
+
+ /**
+ * Subclass to expose protected methods
+ */
+ static class PublicReentrantLock extends ReentrantLock {
+ PublicReentrantLock() { super(); }
+ PublicReentrantLock(boolean fair) { super(fair); }
+ public Thread getOwner() {
+ return super.getOwner();
+ }
+ public Collection<Thread> getQueuedThreads() {
+ return super.getQueuedThreads();
+ }
+ public Collection<Thread> getWaitingThreads(Condition c) {
+ return super.getWaitingThreads(c);
+ }
+ }
+
+ /**
+ * Releases write lock, checking that it had a hold count of 1.
+ */
+ void releaseLock(PublicReentrantLock lock) {
+ assertLockedByMoi(lock);
+ lock.unlock();
+ assertFalse(lock.isHeldByCurrentThread());
+ assertNotLocked(lock);
+ }
+
+ /**
+ * Spin-waits until lock.hasQueuedThread(t) becomes true.
+ */
+ void waitForQueuedThread(PublicReentrantLock lock, Thread t) {
+ long startTime = System.nanoTime();
+ while (!lock.hasQueuedThread(t)) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ throw new AssertionFailedError("timed out");
+ Thread.yield();
+ }
+ assertTrue(t.isAlive());
+ assertNotSame(t, lock.getOwner());
+ }
+
+ /**
+ * Checks that lock is not locked.
+ */
+ void assertNotLocked(PublicReentrantLock lock) {
+ assertFalse(lock.isLocked());
+ assertFalse(lock.isHeldByCurrentThread());
+ assertNull(lock.getOwner());
+ assertEquals(0, lock.getHoldCount());
+ }
+
+ /**
+ * Checks that lock is locked by the given thread.
+ */
+ void assertLockedBy(PublicReentrantLock lock, Thread t) {
+ assertTrue(lock.isLocked());
+ assertSame(t, lock.getOwner());
+ assertEquals(t == Thread.currentThread(),
+ lock.isHeldByCurrentThread());
+ assertEquals(t == Thread.currentThread(),
+ lock.getHoldCount() > 0);
+ }
+
+ /**
+ * Checks that lock is locked by the current thread.
+ */
+ void assertLockedByMoi(PublicReentrantLock lock) {
+ assertLockedBy(lock, Thread.currentThread());
+ }
+
+ /**
+ * Checks that condition c has no waiters.
+ */
+ void assertHasNoWaiters(PublicReentrantLock lock, Condition c) {
+ assertHasWaiters(lock, c, new Thread[] {});
+ }
+
+ /**
+ * Checks that condition c has exactly the given waiter threads.
+ */
+ void assertHasWaiters(PublicReentrantLock lock, Condition c,
+ Thread... threads) {
+ lock.lock();
+ assertEquals(threads.length > 0, lock.hasWaiters(c));
+ assertEquals(threads.length, lock.getWaitQueueLength(c));
+ assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
+ assertEquals(threads.length, lock.getWaitingThreads(c).size());
+ assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
+ new HashSet<Thread>(Arrays.asList(threads)));
+ lock.unlock();
+ }
+
+ enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
+
+ /**
+ * Awaits condition using the specified AwaitMethod.
+ */
+ void await(Condition c, AwaitMethod awaitMethod)
+ throws InterruptedException {
+ long timeoutMillis = 2 * LONG_DELAY_MS;
+ switch (awaitMethod) {
+ case await:
+ c.await();
+ break;
+ case awaitTimed:
+ assertTrue(c.await(timeoutMillis, MILLISECONDS));
+ break;
+ case awaitNanos:
+ long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+ long nanosRemaining = c.awaitNanos(nanosTimeout);
+ assertTrue(nanosRemaining > 0);
+ break;
+ case awaitUntil:
+ assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
+ break;
+ }
+ }
+
+ /**
+ * Constructor sets given fairness, and is in unlocked state
+ */
+ public void testConstructor() {
+ PublicReentrantLock lock;
+
+ lock = new PublicReentrantLock();
+ assertFalse(lock.isFair());
+ assertNotLocked(lock);
+
+ lock = new PublicReentrantLock(true);
+ assertTrue(lock.isFair());
+ assertNotLocked(lock);
+
+ lock = new PublicReentrantLock(false);
+ assertFalse(lock.isFair());
+ assertNotLocked(lock);
+ }
+
+ /**
+ * locking an unlocked lock succeeds
+ */
+ public void testLock() { testLock(false); }
+ public void testLock_fair() { testLock(true); }
+ public void testLock(boolean fair) {
+ PublicReentrantLock lock = new PublicReentrantLock(fair);
+ lock.lock();
+ assertLockedByMoi(lock);
+ releaseLock(lock);
+ }
+
+ /**
+ * Unlocking an unlocked lock throws IllegalMonitorStateException
+ */
+ public void testUnlock_IMSE() { testUnlock_IMSE(false); }
+ public void testUnlock_IMSE_fair() { testUnlock_IMSE(true); }
+ public void testUnlock_IMSE(boolean fair) {
+ ReentrantLock lock = new ReentrantLock(fair);
+ try {
+ lock.unlock();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * tryLock on an unlocked lock succeeds
+ */
+ public void testTryLock() { testTryLock(false); }
+ public void testTryLock_fair() { testTryLock(true); }
+ public void testTryLock(boolean fair) {
+ PublicReentrantLock lock = new PublicReentrantLock(fair);
+ assertTrue(lock.tryLock());
+ assertLockedByMoi(lock);
+ assertTrue(lock.tryLock());
+ assertLockedByMoi(lock);
+ lock.unlock();
+ releaseLock(lock);
+ }
+
+ /**
+ * hasQueuedThreads reports whether there are waiting threads
+ */
+ public void testHasQueuedThreads() { testHasQueuedThreads(false); }
+ public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
+ public void testHasQueuedThreads(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+ Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+ assertFalse(lock.hasQueuedThreads());
+ lock.lock();
+ assertFalse(lock.hasQueuedThreads());
+ t1.start();
+ waitForQueuedThread(lock, t1);
+ assertTrue(lock.hasQueuedThreads());
+ t2.start();
+ waitForQueuedThread(lock, t2);
+ assertTrue(lock.hasQueuedThreads());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(lock.hasQueuedThreads());
+ lock.unlock();
+ awaitTermination(t2);
+ assertFalse(lock.hasQueuedThreads());
+ }
+
+ /**
+ * getQueueLength reports number of waiting threads
+ */
+ public void testGetQueueLength() { testGetQueueLength(false); }
+ public void testGetQueueLength_fair() { testGetQueueLength(true); }
+ public void testGetQueueLength(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+ Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+ assertEquals(0, lock.getQueueLength());
+ lock.lock();
+ t1.start();
+ waitForQueuedThread(lock, t1);
+ assertEquals(1, lock.getQueueLength());
+ t2.start();
+ waitForQueuedThread(lock, t2);
+ assertEquals(2, lock.getQueueLength());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertEquals(1, lock.getQueueLength());
+ lock.unlock();
+ awaitTermination(t2);
+ assertEquals(0, lock.getQueueLength());
+ }
+
+ /**
+ * hasQueuedThread(null) throws NPE
+ */
+ public void testHasQueuedThreadNPE() { testHasQueuedThreadNPE(false); }
+ public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
+ public void testHasQueuedThreadNPE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ try {
+ lock.hasQueuedThread(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * hasQueuedThread reports whether a thread is queued
+ */
+ public void testHasQueuedThread() { testHasQueuedThread(false); }
+ public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
+ public void testHasQueuedThread(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+ Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+ assertFalse(lock.hasQueuedThread(t1));
+ assertFalse(lock.hasQueuedThread(t2));
+ lock.lock();
+ t1.start();
+ waitForQueuedThread(lock, t1);
+ assertTrue(lock.hasQueuedThread(t1));
+ assertFalse(lock.hasQueuedThread(t2));
+ t2.start();
+ waitForQueuedThread(lock, t2);
+ assertTrue(lock.hasQueuedThread(t1));
+ assertTrue(lock.hasQueuedThread(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertFalse(lock.hasQueuedThread(t1));
+ assertTrue(lock.hasQueuedThread(t2));
+ lock.unlock();
+ awaitTermination(t2);
+ assertFalse(lock.hasQueuedThread(t1));
+ assertFalse(lock.hasQueuedThread(t2));
+ }
+
+ /**
+ * getQueuedThreads includes waiting threads
+ */
+ public void testGetQueuedThreads() { testGetQueuedThreads(false); }
+ public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
+ public void testGetQueuedThreads(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+ Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ lock.lock();
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ t1.start();
+ waitForQueuedThread(lock, t1);
+ assertEquals(1, lock.getQueuedThreads().size());
+ assertTrue(lock.getQueuedThreads().contains(t1));
+ t2.start();
+ waitForQueuedThread(lock, t2);
+ assertEquals(2, lock.getQueuedThreads().size());
+ assertTrue(lock.getQueuedThreads().contains(t1));
+ assertTrue(lock.getQueuedThreads().contains(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertFalse(lock.getQueuedThreads().contains(t1));
+ assertTrue(lock.getQueuedThreads().contains(t2));
+ assertEquals(1, lock.getQueuedThreads().size());
+ lock.unlock();
+ awaitTermination(t2);
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ }
+
+ /**
+ * timed tryLock is interruptible
+ */
+ public void testTryLock_Interruptible() { testTryLock_Interruptible(false); }
+ public void testTryLock_Interruptible_fair() { testTryLock_Interruptible(true); }
+ public void testTryLock_Interruptible(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ lock.lock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
+ }});
+
+ waitForQueuedThread(lock, t);
+ t.interrupt();
+ awaitTermination(t);
+ releaseLock(lock);
+ }
+
+ /**
+ * tryLock on a locked lock fails
+ */
+ public void testTryLockWhenLocked() { testTryLockWhenLocked(false); }
+ public void testTryLockWhenLocked_fair() { testTryLockWhenLocked(true); }
+ public void testTryLockWhenLocked(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ lock.lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertFalse(lock.tryLock());
+ }});
+
+ awaitTermination(t);
+ releaseLock(lock);
+ }
+
+ /**
+ * Timed tryLock on a locked lock times out
+ */
+ public void testTryLock_Timeout() { testTryLock_Timeout(false); }
+ public void testTryLock_Timeout_fair() { testTryLock_Timeout(true); }
+ public void testTryLock_Timeout(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ lock.lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ assertFalse(lock.tryLock(timeoutMillis, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ }});
+
+ awaitTermination(t);
+ releaseLock(lock);
+ }
+
+ /**
+ * getHoldCount returns number of recursive holds
+ */
+ public void testGetHoldCount() { testGetHoldCount(false); }
+ public void testGetHoldCount_fair() { testGetHoldCount(true); }
+ public void testGetHoldCount(boolean fair) {
+ ReentrantLock lock = new ReentrantLock(fair);
+ for (int i = 1; i <= SIZE; i++) {
+ lock.lock();
+ assertEquals(i, lock.getHoldCount());
+ }
+ for (int i = SIZE; i > 0; i--) {
+ lock.unlock();
+ assertEquals(i-1, lock.getHoldCount());
+ }
+ }
+
+ /**
+ * isLocked is true when locked and false when not
+ */
+ public void testIsLocked() { testIsLocked(false); }
+ public void testIsLocked_fair() { testIsLocked(true); }
+ public void testIsLocked(boolean fair) {
+ try {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ assertFalse(lock.isLocked());
+ lock.lock();
+ assertTrue(lock.isLocked());
+ lock.lock();
+ assertTrue(lock.isLocked());
+ lock.unlock();
+ assertTrue(lock.isLocked());
+ lock.unlock();
+ assertFalse(lock.isLocked());
+ final CyclicBarrier barrier = new CyclicBarrier(2);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ lock.lock();
+ assertTrue(lock.isLocked());
+ barrier.await();
+ barrier.await();
+ lock.unlock();
+ }});
+
+ barrier.await();
+ assertTrue(lock.isLocked());
+ barrier.await();
+ awaitTermination(t);
+ assertFalse(lock.isLocked());
+ } catch (Exception e) {
+ threadUnexpectedException(e);
+ }
+ }
+
+ /**
+ * lockInterruptibly succeeds when unlocked, else is interruptible
+ */
+ public void testLockInterruptibly() { testLockInterruptibly(false); }
+ public void testLockInterruptibly_fair() { testLockInterruptibly(true); }
+ public void testLockInterruptibly(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ try {
+ lock.lockInterruptibly();
+ } catch (InterruptedException ie) {
+ threadUnexpectedException(ie);
+ }
+ assertLockedByMoi(lock);
+ Thread t = newStartedThread(new InterruptedLockRunnable(lock));
+ waitForQueuedThread(lock, t);
+ t.interrupt();
+ assertTrue(lock.isLocked());
+ assertTrue(lock.isHeldByCurrentThread());
+ awaitTermination(t);
+ releaseLock(lock);
+ }
+
+ /**
+ * Calling await without holding lock throws IllegalMonitorStateException
+ */
+ public void testAwait_IMSE() { testAwait_IMSE(false); }
+ public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
+ public void testAwait_IMSE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ for (AwaitMethod awaitMethod : AwaitMethod.values()) {
+ long startTime = System.nanoTime();
+ try {
+ await(c, awaitMethod);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {
+ } catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ }
+
+ /**
+ * Calling signal without holding lock throws IllegalMonitorStateException
+ */
+ public void testSignal_IMSE() { testSignal_IMSE(false); }
+ public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
+ public void testSignal_IMSE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ try {
+ c.signal();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * awaitNanos without a signal times out
+ */
+ public void testAwaitNanos_Timeout() { testAwaitNanos_Timeout(false); }
+ public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
+ public void testAwaitNanos_Timeout(boolean fair) {
+ try {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ lock.lock();
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+ long nanosRemaining = c.awaitNanos(timeoutNanos);
+ assertTrue(nanosRemaining <= 0);
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ lock.unlock();
+ } catch (InterruptedException e) {
+ threadUnexpectedException(e);
+ }
+ }
+
+ /**
+ * timed await without a signal times out
+ */
+ public void testAwait_Timeout() { testAwait_Timeout(false); }
+ public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
+ public void testAwait_Timeout(boolean fair) {
+ try {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ lock.lock();
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ assertFalse(c.await(timeoutMillis, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ lock.unlock();
+ } catch (InterruptedException e) {
+ threadUnexpectedException(e);
+ }
+ }
+
+ /**
+ * awaitUntil without a signal times out
+ */
+ public void testAwaitUntil_Timeout() { testAwaitUntil_Timeout(false); }
+ public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
+ public void testAwaitUntil_Timeout(boolean fair) {
+ try {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ lock.lock();
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ java.util.Date d = new java.util.Date();
+ assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis)));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ lock.unlock();
+ } catch (InterruptedException e) {
+ threadUnexpectedException(e);
+ }
+ }
+
+ /**
+ * await returns when signalled
+ */
+ public void testAwait() { testAwait(false); }
+ public void testAwait_fair() { testAwait(true); }
+ public void testAwait(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch locked = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ locked.countDown();
+ c.await();
+ lock.unlock();
+ }});
+
+ await(locked);
+ lock.lock();
+ assertHasWaiters(lock, c, t);
+ c.signal();
+ assertHasNoWaiters(lock, c);
+ assertTrue(t.isAlive());
+ lock.unlock();
+ awaitTermination(t);
+ }
+
+ /**
+ * hasWaiters throws NPE if null
+ */
+ public void testHasWaitersNPE() { testHasWaitersNPE(false); }
+ public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
+ public void testHasWaitersNPE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ try {
+ lock.hasWaiters(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getWaitQueueLength throws NPE if null
+ */
+ public void testGetWaitQueueLengthNPE() { testGetWaitQueueLengthNPE(false); }
+ public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
+ public void testGetWaitQueueLengthNPE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ try {
+ lock.getWaitQueueLength(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getWaitingThreads throws NPE if null
+ */
+ public void testGetWaitingThreadsNPE() { testGetWaitingThreadsNPE(false); }
+ public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
+ public void testGetWaitingThreadsNPE(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ try {
+ lock.getWaitingThreads(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * hasWaiters throws IllegalArgumentException if not owned
+ */
+ public void testHasWaitersIAE() { testHasWaitersIAE(false); }
+ public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
+ public void testHasWaitersIAE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final ReentrantLock lock2 = new ReentrantLock(fair);
+ try {
+ lock2.hasWaiters(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * hasWaiters throws IllegalMonitorStateException if not locked
+ */
+ public void testHasWaitersIMSE() { testHasWaitersIMSE(false); }
+ public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
+ public void testHasWaitersIMSE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ try {
+ lock.hasWaiters(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * getWaitQueueLength throws IllegalArgumentException if not owned
+ */
+ public void testGetWaitQueueLengthIAE() { testGetWaitQueueLengthIAE(false); }
+ public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
+ public void testGetWaitQueueLengthIAE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final ReentrantLock lock2 = new ReentrantLock(fair);
+ try {
+ lock2.getWaitQueueLength(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * getWaitQueueLength throws IllegalMonitorStateException if not locked
+ */
+ public void testGetWaitQueueLengthIMSE() { testGetWaitQueueLengthIMSE(false); }
+ public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
+ public void testGetWaitQueueLengthIMSE(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ try {
+ lock.getWaitQueueLength(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * getWaitingThreads throws IllegalArgumentException if not owned
+ */
+ public void testGetWaitingThreadsIAE() { testGetWaitingThreadsIAE(false); }
+ public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
+ public void testGetWaitingThreadsIAE(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final PublicReentrantLock lock2 = new PublicReentrantLock(fair);
+ try {
+ lock2.getWaitingThreads(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * getWaitingThreads throws IllegalMonitorStateException if not locked
+ */
+ public void testGetWaitingThreadsIMSE() { testGetWaitingThreadsIMSE(false); }
+ public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
+ public void testGetWaitingThreadsIMSE(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ try {
+ lock.getWaitingThreads(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * hasWaiters returns true when a thread is waiting, else false
+ */
+ public void testHasWaiters() { testHasWaiters(false); }
+ public void testHasWaiters_fair() { testHasWaiters(true); }
+ public void testHasWaiters(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch pleaseSignal = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ assertHasNoWaiters(lock, c);
+ assertFalse(lock.hasWaiters(c));
+ pleaseSignal.countDown();
+ c.await();
+ assertHasNoWaiters(lock, c);
+ assertFalse(lock.hasWaiters(c));
+ lock.unlock();
+ }});
+
+ await(pleaseSignal);
+ lock.lock();
+ assertHasWaiters(lock, c, t);
+ assertTrue(lock.hasWaiters(c));
+ c.signal();
+ assertHasNoWaiters(lock, c);
+ assertFalse(lock.hasWaiters(c));
+ lock.unlock();
+ awaitTermination(t);
+ assertHasNoWaiters(lock, c);
+ }
+
+ /**
+ * getWaitQueueLength returns number of waiting threads
+ */
+ public void testGetWaitQueueLength() { testGetWaitQueueLength(false); }
+ public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
+ public void testGetWaitQueueLength(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch locked1 = new CountDownLatch(1);
+ final CountDownLatch locked2 = new CountDownLatch(1);
+ Thread t1 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ assertFalse(lock.hasWaiters(c));
+ assertEquals(0, lock.getWaitQueueLength(c));
+ locked1.countDown();
+ c.await();
+ lock.unlock();
+ }});
+
+ Thread t2 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ assertTrue(lock.hasWaiters(c));
+ assertEquals(1, lock.getWaitQueueLength(c));
+ locked2.countDown();
+ c.await();
+ lock.unlock();
+ }});
+
+ lock.lock();
+ assertEquals(0, lock.getWaitQueueLength(c));
+ lock.unlock();
+
+ t1.start();
+ await(locked1);
+
+ lock.lock();
+ assertHasWaiters(lock, c, t1);
+ assertEquals(1, lock.getWaitQueueLength(c));
+ lock.unlock();
+
+ t2.start();
+ await(locked2);
+
+ lock.lock();
+ assertHasWaiters(lock, c, t1, t2);
+ assertEquals(2, lock.getWaitQueueLength(c));
+ c.signalAll();
+ assertHasNoWaiters(lock, c);
+ lock.unlock();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+
+ assertHasNoWaiters(lock, c);
+ }
+
+ /**
+ * getWaitingThreads returns only and all waiting threads
+ */
+ public void testGetWaitingThreads() { testGetWaitingThreads(false); }
+ public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
+ public void testGetWaitingThreads(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch locked1 = new CountDownLatch(1);
+ final CountDownLatch locked2 = new CountDownLatch(1);
+ Thread t1 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ assertTrue(lock.getWaitingThreads(c).isEmpty());
+ locked1.countDown();
+ c.await();
+ lock.unlock();
+ }});
+
+ Thread t2 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ assertFalse(lock.getWaitingThreads(c).isEmpty());
+ locked2.countDown();
+ c.await();
+ lock.unlock();
+ }});
+
+ lock.lock();
+ assertTrue(lock.getWaitingThreads(c).isEmpty());
+ lock.unlock();
+
+ t1.start();
+ await(locked1);
+
+ lock.lock();
+ assertHasWaiters(lock, c, t1);
+ assertTrue(lock.getWaitingThreads(c).contains(t1));
+ assertFalse(lock.getWaitingThreads(c).contains(t2));
+ assertEquals(1, lock.getWaitingThreads(c).size());
+ lock.unlock();
+
+ t2.start();
+ await(locked2);
+
+ lock.lock();
+ assertHasWaiters(lock, c, t1, t2);
+ assertTrue(lock.getWaitingThreads(c).contains(t1));
+ assertTrue(lock.getWaitingThreads(c).contains(t2));
+ assertEquals(2, lock.getWaitingThreads(c).size());
+ c.signalAll();
+ assertHasNoWaiters(lock, c);
+ lock.unlock();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+
+ assertHasNoWaiters(lock, c);
+ }
+
+ /**
+ * awaitUninterruptibly is uninterruptible
+ */
+ public void testAwaitUninterruptibly() { testAwaitUninterruptibly(false); }
+ public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
+ public void testAwaitUninterruptibly(boolean fair) {
+ final ReentrantLock lock = new ReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ // Interrupt before awaitUninterruptibly
+ lock.lock();
+ pleaseInterrupt.countDown();
+ Thread.currentThread().interrupt();
+ c.awaitUninterruptibly();
+ assertTrue(Thread.interrupted());
+ lock.unlock();
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ // Interrupt during awaitUninterruptibly
+ lock.lock();
+ pleaseInterrupt.countDown();
+ c.awaitUninterruptibly();
+ assertTrue(Thread.interrupted());
+ lock.unlock();
+ }});
+
+ await(pleaseInterrupt);
+ lock.lock();
+ lock.unlock();
+ t2.interrupt();
+
+ assertThreadStaysAlive(t1);
+ assertTrue(t2.isAlive());
+
+ lock.lock();
+ c.signalAll();
+ lock.unlock();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * await/awaitNanos/awaitUntil is interruptible
+ */
+ public void testInterruptible_await() { testInterruptible(false, AwaitMethod.await); }
+ public void testInterruptible_await_fair() { testInterruptible(true, AwaitMethod.await); }
+ public void testInterruptible_awaitTimed() { testInterruptible(false, AwaitMethod.awaitTimed); }
+ public void testInterruptible_awaitTimed_fair() { testInterruptible(true, AwaitMethod.awaitTimed); }
+ public void testInterruptible_awaitNanos() { testInterruptible(false, AwaitMethod.awaitNanos); }
+ public void testInterruptible_awaitNanos_fair() { testInterruptible(true, AwaitMethod.awaitNanos); }
+ public void testInterruptible_awaitUntil() { testInterruptible(false, AwaitMethod.awaitUntil); }
+ public void testInterruptible_awaitUntil_fair() { testInterruptible(true, AwaitMethod.awaitUntil); }
+ public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
+ final PublicReentrantLock lock =
+ new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ assertLockedByMoi(lock);
+ assertHasNoWaiters(lock, c);
+ pleaseInterrupt.countDown();
+ try {
+ await(c, awaitMethod);
+ } finally {
+ assertLockedByMoi(lock);
+ assertHasNoWaiters(lock, c);
+ lock.unlock();
+ assertFalse(Thread.interrupted());
+ }
+ }});
+
+ await(pleaseInterrupt);
+ assertHasWaiters(lock, c, t);
+ t.interrupt();
+ awaitTermination(t);
+ assertNotLocked(lock);
+ }
+
+ /**
+ * signalAll wakes up all threads
+ */
+ public void testSignalAll_await() { testSignalAll(false, AwaitMethod.await); }
+ public void testSignalAll_await_fair() { testSignalAll(true, AwaitMethod.await); }
+ public void testSignalAll_awaitTimed() { testSignalAll(false, AwaitMethod.awaitTimed); }
+ public void testSignalAll_awaitTimed_fair() { testSignalAll(true, AwaitMethod.awaitTimed); }
+ public void testSignalAll_awaitNanos() { testSignalAll(false, AwaitMethod.awaitNanos); }
+ public void testSignalAll_awaitNanos_fair() { testSignalAll(true, AwaitMethod.awaitNanos); }
+ public void testSignalAll_awaitUntil() { testSignalAll(false, AwaitMethod.awaitUntil); }
+ public void testSignalAll_awaitUntil_fair() { testSignalAll(true, AwaitMethod.awaitUntil); }
+ public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch pleaseSignal = new CountDownLatch(2);
+ class Awaiter extends CheckedRunnable {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ pleaseSignal.countDown();
+ await(c, awaitMethod);
+ lock.unlock();
+ }
+ }
+
+ Thread t1 = newStartedThread(new Awaiter());
+ Thread t2 = newStartedThread(new Awaiter());
+
+ await(pleaseSignal);
+ lock.lock();
+ assertHasWaiters(lock, c, t1, t2);
+ c.signalAll();
+ assertHasNoWaiters(lock, c);
+ lock.unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * signal wakes up waiting threads in FIFO order
+ */
+ public void testSignalWakesFifo() { testSignalWakesFifo(false); }
+ public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
+ public void testSignalWakesFifo(boolean fair) {
+ final PublicReentrantLock lock =
+ new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch locked1 = new CountDownLatch(1);
+ final CountDownLatch locked2 = new CountDownLatch(1);
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ locked1.countDown();
+ c.await();
+ lock.unlock();
+ }});
+
+ await(locked1);
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ locked2.countDown();
+ c.await();
+ lock.unlock();
+ }});
+
+ await(locked2);
+
+ lock.lock();
+ assertHasWaiters(lock, c, t1, t2);
+ assertFalse(lock.hasQueuedThreads());
+ c.signal();
+ assertHasWaiters(lock, c, t2);
+ assertTrue(lock.hasQueuedThread(t1));
+ assertFalse(lock.hasQueuedThread(t2));
+ c.signal();
+ assertHasNoWaiters(lock, c);
+ assertTrue(lock.hasQueuedThread(t1));
+ assertTrue(lock.hasQueuedThread(t2));
+ lock.unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * await after multiple reentrant locking preserves lock count
+ */
+ public void testAwaitLockCount() { testAwaitLockCount(false); }
+ public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
+ public void testAwaitLockCount(boolean fair) {
+ final PublicReentrantLock lock = new PublicReentrantLock(fair);
+ final Condition c = lock.newCondition();
+ final CountDownLatch pleaseSignal = new CountDownLatch(2);
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ assertLockedByMoi(lock);
+ assertEquals(1, lock.getHoldCount());
+ pleaseSignal.countDown();
+ c.await();
+ assertLockedByMoi(lock);
+ assertEquals(1, lock.getHoldCount());
+ lock.unlock();
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.lock();
+ lock.lock();
+ assertLockedByMoi(lock);
+ assertEquals(2, lock.getHoldCount());
+ pleaseSignal.countDown();
+ c.await();
+ assertLockedByMoi(lock);
+ assertEquals(2, lock.getHoldCount());
+ lock.unlock();
+ lock.unlock();
+ }});
+
+ await(pleaseSignal);
+ lock.lock();
+ assertHasWaiters(lock, c, t1, t2);
+ assertEquals(1, lock.getHoldCount());
+ c.signalAll();
+ assertHasNoWaiters(lock, c);
+ lock.unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * A serialized lock deserializes as unlocked
+ */
+ public void testSerialization() { testSerialization(false); }
+ public void testSerialization_fair() { testSerialization(true); }
+ public void testSerialization(boolean fair) {
+ ReentrantLock lock = new ReentrantLock(fair);
+ lock.lock();
+
+ ReentrantLock clone = serialClone(lock);
+ assertEquals(lock.isFair(), clone.isFair());
+ assertTrue(lock.isLocked());
+ assertFalse(clone.isLocked());
+ assertEquals(1, lock.getHoldCount());
+ assertEquals(0, clone.getHoldCount());
+ clone.lock();
+ clone.lock();
+ assertTrue(clone.isLocked());
+ assertEquals(2, clone.getHoldCount());
+ assertEquals(1, lock.getHoldCount());
+ clone.unlock();
+ clone.unlock();
+ assertTrue(lock.isLocked());
+ assertFalse(clone.isLocked());
+ }
+
+ /**
+ * toString indicates current lock state
+ */
+ public void testToString() { testToString(false); }
+ public void testToString_fair() { testToString(true); }
+ public void testToString(boolean fair) {
+ ReentrantLock lock = new ReentrantLock(fair);
+ assertTrue(lock.toString().contains("Unlocked"));
+ lock.lock();
+ assertTrue(lock.toString().contains("Locked"));
+ lock.unlock();
+ assertTrue(lock.toString().contains("Unlocked"));
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java b/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java
new file mode 100644
index 0000000..2be27d2
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java
@@ -0,0 +1,1670 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.CountDownLatch;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.*;
+
+public class ReentrantReadWriteLockTest extends JSR166TestCase {
+
+ /**
+ * A runnable calling lockInterruptibly
+ */
+ class InterruptibleLockRunnable extends CheckedRunnable {
+ final ReentrantReadWriteLock lock;
+ InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lockInterruptibly();
+ }
+ }
+
+ /**
+ * A runnable calling lockInterruptibly that expects to be
+ * interrupted
+ */
+ class InterruptedLockRunnable extends CheckedInterruptedRunnable {
+ final ReentrantReadWriteLock lock;
+ InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lockInterruptibly();
+ }
+ }
+
+ /**
+ * Subclass to expose protected methods
+ */
+ static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
+ PublicReentrantReadWriteLock() { super(); }
+ PublicReentrantReadWriteLock(boolean fair) { super(fair); }
+ public Thread getOwner() {
+ return super.getOwner();
+ }
+ public Collection<Thread> getQueuedThreads() {
+ return super.getQueuedThreads();
+ }
+ public Collection<Thread> getWaitingThreads(Condition c) {
+ return super.getWaitingThreads(c);
+ }
+ }
+
+ /**
+ * Releases write lock, checking that it had a hold count of 1.
+ */
+ void releaseWriteLock(PublicReentrantReadWriteLock lock) {
+ ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
+ assertWriteLockedByMoi(lock);
+ assertEquals(1, lock.getWriteHoldCount());
+ writeLock.unlock();
+ assertNotWriteLocked(lock);
+ }
+
+ /**
+ * Spin-waits until lock.hasQueuedThread(t) becomes true.
+ */
+ void waitForQueuedThread(PublicReentrantReadWriteLock lock, Thread t) {
+ long startTime = System.nanoTime();
+ while (!lock.hasQueuedThread(t)) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ throw new AssertionFailedError("timed out");
+ Thread.yield();
+ }
+ assertTrue(t.isAlive());
+ assertNotSame(t, lock.getOwner());
+ }
+
+ /**
+ * Checks that lock is not write-locked.
+ */
+ void assertNotWriteLocked(PublicReentrantReadWriteLock lock) {
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isWriteLockedByCurrentThread());
+ assertFalse(lock.writeLock().isHeldByCurrentThread());
+ assertEquals(0, lock.getWriteHoldCount());
+ assertEquals(0, lock.writeLock().getHoldCount());
+ assertNull(lock.getOwner());
+ }
+
+ /**
+ * Checks that lock is write-locked by the given thread.
+ */
+ void assertWriteLockedBy(PublicReentrantReadWriteLock lock, Thread t) {
+ assertTrue(lock.isWriteLocked());
+ assertSame(t, lock.getOwner());
+ assertEquals(t == Thread.currentThread(),
+ lock.isWriteLockedByCurrentThread());
+ assertEquals(t == Thread.currentThread(),
+ lock.writeLock().isHeldByCurrentThread());
+ assertEquals(t == Thread.currentThread(),
+ lock.getWriteHoldCount() > 0);
+ assertEquals(t == Thread.currentThread(),
+ lock.writeLock().getHoldCount() > 0);
+ assertEquals(0, lock.getReadLockCount());
+ }
+
+ /**
+ * Checks that lock is write-locked by the current thread.
+ */
+ void assertWriteLockedByMoi(PublicReentrantReadWriteLock lock) {
+ assertWriteLockedBy(lock, Thread.currentThread());
+ }
+
+ /**
+ * Checks that condition c has no waiters.
+ */
+ void assertHasNoWaiters(PublicReentrantReadWriteLock lock, Condition c) {
+ assertHasWaiters(lock, c, new Thread[] {});
+ }
+
+ /**
+ * Checks that condition c has exactly the given waiter threads.
+ */
+ void assertHasWaiters(PublicReentrantReadWriteLock lock, Condition c,
+ Thread... threads) {
+ lock.writeLock().lock();
+ assertEquals(threads.length > 0, lock.hasWaiters(c));
+ assertEquals(threads.length, lock.getWaitQueueLength(c));
+ assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
+ assertEquals(threads.length, lock.getWaitingThreads(c).size());
+ assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
+ new HashSet<Thread>(Arrays.asList(threads)));
+ lock.writeLock().unlock();
+ }
+
+ enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
+
+ /**
+ * Awaits condition using the specified AwaitMethod.
+ */
+ void await(Condition c, AwaitMethod awaitMethod)
+ throws InterruptedException {
+ switch (awaitMethod) {
+ case await:
+ c.await();
+ break;
+ case awaitTimed:
+ assertTrue(c.await(2 * LONG_DELAY_MS, MILLISECONDS));
+ break;
+ case awaitNanos:
+ long nanosRemaining = c.awaitNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
+ assertTrue(nanosRemaining > 0);
+ break;
+ case awaitUntil:
+ java.util.Date d = new java.util.Date();
+ assertTrue(c.awaitUntil(new java.util.Date(d.getTime() + 2 * LONG_DELAY_MS)));
+ break;
+ }
+ }
+
+ /**
+ * Constructor sets given fairness, and is in unlocked state
+ */
+ public void testConstructor() {
+ PublicReentrantReadWriteLock lock;
+
+ lock = new PublicReentrantReadWriteLock();
+ assertFalse(lock.isFair());
+ assertNotWriteLocked(lock);
+ assertEquals(0, lock.getReadLockCount());
+
+ lock = new PublicReentrantReadWriteLock(true);
+ assertTrue(lock.isFair());
+ assertNotWriteLocked(lock);
+ assertEquals(0, lock.getReadLockCount());
+
+ lock = new PublicReentrantReadWriteLock(false);
+ assertFalse(lock.isFair());
+ assertNotWriteLocked(lock);
+ assertEquals(0, lock.getReadLockCount());
+ }
+
+ /**
+ * write-locking and read-locking an unlocked lock succeed
+ */
+ public void testLock() { testLock(false); }
+ public void testLock_fair() { testLock(true); }
+ public void testLock(boolean fair) {
+ PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ assertNotWriteLocked(lock);
+ lock.writeLock().lock();
+ assertWriteLockedByMoi(lock);
+ lock.writeLock().unlock();
+ assertNotWriteLocked(lock);
+ assertEquals(0, lock.getReadLockCount());
+ lock.readLock().lock();
+ assertNotWriteLocked(lock);
+ assertEquals(1, lock.getReadLockCount());
+ lock.readLock().unlock();
+ assertNotWriteLocked(lock);
+ assertEquals(0, lock.getReadLockCount());
+ }
+
+ /**
+ * getWriteHoldCount returns number of recursive holds
+ */
+ public void testGetWriteHoldCount() { testGetWriteHoldCount(false); }
+ public void testGetWriteHoldCount_fair() { testGetWriteHoldCount(true); }
+ public void testGetWriteHoldCount(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ for (int i = 1; i <= SIZE; i++) {
+ lock.writeLock().lock();
+ assertEquals(i,lock.getWriteHoldCount());
+ }
+ for (int i = SIZE; i > 0; i--) {
+ lock.writeLock().unlock();
+ assertEquals(i-1,lock.getWriteHoldCount());
+ }
+ }
+
+ /**
+ * writelock.getHoldCount returns number of recursive holds
+ */
+ public void testGetHoldCount() { testGetHoldCount(false); }
+ public void testGetHoldCount_fair() { testGetHoldCount(true); }
+ public void testGetHoldCount(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ for (int i = 1; i <= SIZE; i++) {
+ lock.writeLock().lock();
+ assertEquals(i,lock.writeLock().getHoldCount());
+ }
+ for (int i = SIZE; i > 0; i--) {
+ lock.writeLock().unlock();
+ assertEquals(i-1,lock.writeLock().getHoldCount());
+ }
+ }
+
+ /**
+ * getReadHoldCount returns number of recursive holds
+ */
+ public void testGetReadHoldCount() { testGetReadHoldCount(false); }
+ public void testGetReadHoldCount_fair() { testGetReadHoldCount(true); }
+ public void testGetReadHoldCount(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ for (int i = 1; i <= SIZE; i++) {
+ lock.readLock().lock();
+ assertEquals(i,lock.getReadHoldCount());
+ }
+ for (int i = SIZE; i > 0; i--) {
+ lock.readLock().unlock();
+ assertEquals(i-1,lock.getReadHoldCount());
+ }
+ }
+
+ /**
+ * write-unlocking an unlocked lock throws IllegalMonitorStateException
+ */
+ public void testWriteUnlock_IMSE() { testWriteUnlock_IMSE(false); }
+ public void testWriteUnlock_IMSE_fair() { testWriteUnlock_IMSE(true); }
+ public void testWriteUnlock_IMSE(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ try {
+ lock.writeLock().unlock();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * read-unlocking an unlocked lock throws IllegalMonitorStateException
+ */
+ public void testReadUnlock_IMSE() { testReadUnlock_IMSE(false); }
+ public void testReadUnlock_IMSE_fair() { testReadUnlock_IMSE(true); }
+ public void testReadUnlock_IMSE(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ try {
+ lock.readLock().unlock();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * write-lockInterruptibly is interruptible
+ */
+ public void testWriteLockInterruptibly_Interruptible() { testWriteLockInterruptibly_Interruptible(false); }
+ public void testWriteLockInterruptibly_Interruptible_fair() { testWriteLockInterruptibly_Interruptible(true); }
+ public void testWriteLockInterruptibly_Interruptible(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lockInterruptibly();
+ }});
+
+ waitForQueuedThread(lock, t);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * timed write-tryLock is interruptible
+ */
+ public void testWriteTryLock_Interruptible() { testWriteTryLock_Interruptible(false); }
+ public void testWriteTryLock_Interruptible_fair() { testWriteTryLock_Interruptible(true); }
+ public void testWriteTryLock_Interruptible(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
+ }});
+
+ waitForQueuedThread(lock, t);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * read-lockInterruptibly is interruptible
+ */
+ public void testReadLockInterruptibly_Interruptible() { testReadLockInterruptibly_Interruptible(false); }
+ public void testReadLockInterruptibly_Interruptible_fair() { testReadLockInterruptibly_Interruptible(true); }
+ public void testReadLockInterruptibly_Interruptible(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.readLock().lockInterruptibly();
+ }});
+
+ waitForQueuedThread(lock, t);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * timed read-tryLock is interruptible
+ */
+ public void testReadTryLock_Interruptible() { testReadTryLock_Interruptible(false); }
+ public void testReadTryLock_Interruptible_fair() { testReadTryLock_Interruptible(true); }
+ public void testReadTryLock_Interruptible(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.readLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
+ }});
+
+ waitForQueuedThread(lock, t);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * write-tryLock on an unlocked lock succeeds
+ */
+ public void testWriteTryLock() { testWriteTryLock(false); }
+ public void testWriteTryLock_fair() { testWriteTryLock(true); }
+ public void testWriteTryLock(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ assertTrue(lock.writeLock().tryLock());
+ assertWriteLockedByMoi(lock);
+ assertTrue(lock.writeLock().tryLock());
+ assertWriteLockedByMoi(lock);
+ lock.writeLock().unlock();
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * write-tryLock fails if locked
+ */
+ public void testWriteTryLockWhenLocked() { testWriteTryLockWhenLocked(false); }
+ public void testWriteTryLockWhenLocked_fair() { testWriteTryLockWhenLocked(true); }
+ public void testWriteTryLockWhenLocked(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertFalse(lock.writeLock().tryLock());
+ }});
+
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * read-tryLock fails if locked
+ */
+ public void testReadTryLockWhenLocked() { testReadTryLockWhenLocked(false); }
+ public void testReadTryLockWhenLocked_fair() { testReadTryLockWhenLocked(true); }
+ public void testReadTryLockWhenLocked(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertFalse(lock.readLock().tryLock());
+ }});
+
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * Multiple threads can hold a read lock when not write-locked
+ */
+ public void testMultipleReadLocks() { testMultipleReadLocks(false); }
+ public void testMultipleReadLocks_fair() { testMultipleReadLocks(true); }
+ public void testMultipleReadLocks(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ lock.readLock().lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertTrue(lock.readLock().tryLock());
+ lock.readLock().unlock();
+ assertTrue(lock.readLock().tryLock(LONG_DELAY_MS, MILLISECONDS));
+ lock.readLock().unlock();
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ }});
+
+ awaitTermination(t);
+ lock.readLock().unlock();
+ }
+
+ /**
+ * A writelock succeeds only after a reading thread unlocks
+ */
+ public void testWriteAfterReadLock() { testWriteAfterReadLock(false); }
+ public void testWriteAfterReadLock_fair() { testWriteAfterReadLock(true); }
+ public void testWriteAfterReadLock(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.readLock().lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(1, lock.getReadLockCount());
+ lock.writeLock().lock();
+ assertEquals(0, lock.getReadLockCount());
+ lock.writeLock().unlock();
+ }});
+ waitForQueuedThread(lock, t);
+ assertNotWriteLocked(lock);
+ assertEquals(1, lock.getReadLockCount());
+ lock.readLock().unlock();
+ assertEquals(0, lock.getReadLockCount());
+ awaitTermination(t);
+ assertNotWriteLocked(lock);
+ }
+
+ /**
+ * A writelock succeeds only after reading threads unlock
+ */
+ public void testWriteAfterMultipleReadLocks() { testWriteAfterMultipleReadLocks(false); }
+ public void testWriteAfterMultipleReadLocks_fair() { testWriteAfterMultipleReadLocks(true); }
+ public void testWriteAfterMultipleReadLocks(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.readLock().lock();
+ lock.readLock().lock();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.readLock().lock();
+ assertEquals(3, lock.getReadLockCount());
+ lock.readLock().unlock();
+ }});
+ awaitTermination(t1);
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(2, lock.getReadLockCount());
+ lock.writeLock().lock();
+ assertEquals(0, lock.getReadLockCount());
+ lock.writeLock().unlock();
+ }});
+ waitForQueuedThread(lock, t2);
+ assertNotWriteLocked(lock);
+ assertEquals(2, lock.getReadLockCount());
+ lock.readLock().unlock();
+ lock.readLock().unlock();
+ assertEquals(0, lock.getReadLockCount());
+ awaitTermination(t2);
+ assertNotWriteLocked(lock);
+ }
+
+ /**
+ * A thread that tries to acquire a fair read lock (non-reentrantly)
+ * will block if there is a waiting writer thread
+ */
+ public void testReaderWriterReaderFairFifo() {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(true);
+ final AtomicBoolean t1GotLock = new AtomicBoolean(false);
+
+ lock.readLock().lock();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(1, lock.getReadLockCount());
+ lock.writeLock().lock();
+ assertEquals(0, lock.getReadLockCount());
+ t1GotLock.set(true);
+ lock.writeLock().unlock();
+ }});
+ waitForQueuedThread(lock, t1);
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertEquals(1, lock.getReadLockCount());
+ lock.readLock().lock();
+ assertEquals(1, lock.getReadLockCount());
+ assertTrue(t1GotLock.get());
+ lock.readLock().unlock();
+ }});
+ waitForQueuedThread(lock, t2);
+ assertTrue(t1.isAlive());
+ assertNotWriteLocked(lock);
+ assertEquals(1, lock.getReadLockCount());
+ lock.readLock().unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ assertNotWriteLocked(lock);
+ }
+
+ /**
+ * Readlocks succeed only after a writing thread unlocks
+ */
+ public void testReadAfterWriteLock() { testReadAfterWriteLock(false); }
+ public void testReadAfterWriteLock_fair() { testReadAfterWriteLock(true); }
+ public void testReadAfterWriteLock(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ }});
+
+ waitForQueuedThread(lock, t1);
+ waitForQueuedThread(lock, t2);
+ releaseWriteLock(lock);
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * Read trylock succeeds if write locked by current thread
+ */
+ public void testReadHoldingWriteLock() { testReadHoldingWriteLock(false); }
+ public void testReadHoldingWriteLock_fair() { testReadHoldingWriteLock(true); }
+ public void testReadHoldingWriteLock(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ assertTrue(lock.readLock().tryLock());
+ lock.readLock().unlock();
+ lock.writeLock().unlock();
+ }
+
+ /**
+ * Read trylock succeeds (barging) even in the presence of waiting
+ * readers and/or writers
+ */
+ public void testReadTryLockBarging() { testReadTryLockBarging(false); }
+ public void testReadTryLockBarging_fair() { testReadTryLockBarging(true); }
+ public void testReadTryLockBarging(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.readLock().lock();
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.writeLock().lock();
+ lock.writeLock().unlock();
+ }});
+
+ waitForQueuedThread(lock, t1);
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ }});
+
+ if (fair)
+ waitForQueuedThread(lock, t2);
+
+ Thread t3 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.readLock().tryLock();
+ lock.readLock().unlock();
+ }});
+
+ assertTrue(lock.getReadLockCount() > 0);
+ awaitTermination(t3);
+ assertTrue(t1.isAlive());
+ if (fair) assertTrue(t2.isAlive());
+ lock.readLock().unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * Read lock succeeds if write locked by current thread even if
+ * other threads are waiting for readlock
+ */
+ public void testReadHoldingWriteLock2() { testReadHoldingWriteLock2(false); }
+ public void testReadHoldingWriteLock2_fair() { testReadHoldingWriteLock2(true); }
+ public void testReadHoldingWriteLock2(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ lock.readLock().lock();
+ lock.readLock().unlock();
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ }});
+
+ waitForQueuedThread(lock, t1);
+ waitForQueuedThread(lock, t2);
+ assertWriteLockedByMoi(lock);
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ releaseWriteLock(lock);
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * Read lock succeeds if write locked by current thread even if
+ * other threads are waiting for writelock
+ */
+ public void testReadHoldingWriteLock3() { testReadHoldingWriteLock3(false); }
+ public void testReadHoldingWriteLock3_fair() { testReadHoldingWriteLock3(true); }
+ public void testReadHoldingWriteLock3(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ lock.readLock().lock();
+ lock.readLock().unlock();
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.writeLock().lock();
+ lock.writeLock().unlock();
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.writeLock().lock();
+ lock.writeLock().unlock();
+ }});
+
+ waitForQueuedThread(lock, t1);
+ waitForQueuedThread(lock, t2);
+ assertWriteLockedByMoi(lock);
+ lock.readLock().lock();
+ lock.readLock().unlock();
+ assertWriteLockedByMoi(lock);
+ lock.writeLock().unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * Write lock succeeds if write locked by current thread even if
+ * other threads are waiting for writelock
+ */
+ public void testWriteHoldingWriteLock4() { testWriteHoldingWriteLock4(false); }
+ public void testWriteHoldingWriteLock4_fair() { testWriteHoldingWriteLock4(true); }
+ public void testWriteHoldingWriteLock4(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ lock.writeLock().lock();
+ lock.writeLock().unlock();
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.writeLock().lock();
+ lock.writeLock().unlock();
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ lock.writeLock().lock();
+ lock.writeLock().unlock();
+ }});
+
+ waitForQueuedThread(lock, t1);
+ waitForQueuedThread(lock, t2);
+ assertWriteLockedByMoi(lock);
+ assertEquals(1, lock.getWriteHoldCount());
+ lock.writeLock().lock();
+ assertWriteLockedByMoi(lock);
+ assertEquals(2, lock.getWriteHoldCount());
+ lock.writeLock().unlock();
+ assertWriteLockedByMoi(lock);
+ assertEquals(1, lock.getWriteHoldCount());
+ lock.writeLock().unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * Read tryLock succeeds if readlocked but not writelocked
+ */
+ public void testTryLockWhenReadLocked() { testTryLockWhenReadLocked(false); }
+ public void testTryLockWhenReadLocked_fair() { testTryLockWhenReadLocked(true); }
+ public void testTryLockWhenReadLocked(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ lock.readLock().lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertTrue(lock.readLock().tryLock());
+ lock.readLock().unlock();
+ }});
+
+ awaitTermination(t);
+ lock.readLock().unlock();
+ }
+
+ /**
+ * write tryLock fails when readlocked
+ */
+ public void testWriteTryLockWhenReadLocked() { testWriteTryLockWhenReadLocked(false); }
+ public void testWriteTryLockWhenReadLocked_fair() { testWriteTryLockWhenReadLocked(true); }
+ public void testWriteTryLockWhenReadLocked(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ lock.readLock().lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ assertFalse(lock.writeLock().tryLock());
+ }});
+
+ awaitTermination(t);
+ lock.readLock().unlock();
+ }
+
+ /**
+ * write timed tryLock times out if locked
+ */
+ public void testWriteTryLock_Timeout() { testWriteTryLock_Timeout(false); }
+ public void testWriteTryLock_Timeout_fair() { testWriteTryLock_Timeout(true); }
+ public void testWriteTryLock_Timeout(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ assertFalse(lock.writeLock().tryLock(timeoutMillis, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ }});
+
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * read timed tryLock times out if write-locked
+ */
+ public void testReadTryLock_Timeout() { testReadTryLock_Timeout(false); }
+ public void testReadTryLock_Timeout_fair() { testReadTryLock_Timeout(true); }
+ public void testReadTryLock_Timeout(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ assertFalse(lock.readLock().tryLock(timeoutMillis, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ }});
+
+ awaitTermination(t);
+ assertTrue(lock.writeLock().isHeldByCurrentThread());
+ lock.writeLock().unlock();
+ }
+
+ /**
+ * write lockInterruptibly succeeds if unlocked, else is interruptible
+ */
+ public void testWriteLockInterruptibly() { testWriteLockInterruptibly(false); }
+ public void testWriteLockInterruptibly_fair() { testWriteLockInterruptibly(true); }
+ public void testWriteLockInterruptibly(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ try {
+ lock.writeLock().lockInterruptibly();
+ } catch (InterruptedException ie) {
+ threadUnexpectedException(ie);
+ }
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lockInterruptibly();
+ }});
+
+ waitForQueuedThread(lock, t);
+ t.interrupt();
+ assertTrue(lock.writeLock().isHeldByCurrentThread());
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * read lockInterruptibly succeeds if lock free else is interruptible
+ */
+ public void testReadLockInterruptibly() { testReadLockInterruptibly(false); }
+ public void testReadLockInterruptibly_fair() { testReadLockInterruptibly(true); }
+ public void testReadLockInterruptibly(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ try {
+ lock.readLock().lockInterruptibly();
+ lock.readLock().unlock();
+ lock.writeLock().lockInterruptibly();
+ } catch (InterruptedException ie) {
+ threadUnexpectedException(ie);
+ }
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.readLock().lockInterruptibly();
+ }});
+
+ waitForQueuedThread(lock, t);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock);
+ }
+
+ /**
+ * Calling await without holding lock throws IllegalMonitorStateException
+ */
+ public void testAwait_IMSE() { testAwait_IMSE(false); }
+ public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
+ public void testAwait_IMSE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ for (AwaitMethod awaitMethod : AwaitMethod.values()) {
+ long startTime = System.nanoTime();
+ try {
+ await(c, awaitMethod);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {
+ } catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+ }
+
+ /**
+ * Calling signal without holding lock throws IllegalMonitorStateException
+ */
+ public void testSignal_IMSE() { testSignal_IMSE(false); }
+ public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
+ public void testSignal_IMSE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ try {
+ c.signal();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * Calling signalAll without holding lock throws IllegalMonitorStateException
+ */
+ public void testSignalAll_IMSE() { testSignalAll_IMSE(false); }
+ public void testSignalAll_IMSE_fair() { testSignalAll_IMSE(true); }
+ public void testSignalAll_IMSE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ try {
+ c.signalAll();
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * awaitNanos without a signal times out
+ */
+ public void testAwaitNanos_Timeout() { testAwaitNanos_Timeout(false); }
+ public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
+ public void testAwaitNanos_Timeout(boolean fair) {
+ try {
+ final ReentrantReadWriteLock lock =
+ new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ lock.writeLock().lock();
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+ long nanosRemaining = c.awaitNanos(timeoutNanos);
+ assertTrue(nanosRemaining <= 0);
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ lock.writeLock().unlock();
+ } catch (InterruptedException e) {
+ threadUnexpectedException(e);
+ }
+ }
+
+ /**
+ * timed await without a signal times out
+ */
+ public void testAwait_Timeout() { testAwait_Timeout(false); }
+ public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
+ public void testAwait_Timeout(boolean fair) {
+ try {
+ final ReentrantReadWriteLock lock =
+ new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ lock.writeLock().lock();
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ assertFalse(c.await(timeoutMillis, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ lock.writeLock().unlock();
+ } catch (InterruptedException e) {
+ threadUnexpectedException(e);
+ }
+ }
+
+ /**
+ * awaitUntil without a signal times out
+ */
+ public void testAwaitUntil_Timeout() { testAwaitUntil_Timeout(false); }
+ public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
+ public void testAwaitUntil_Timeout(boolean fair) {
+ try {
+ final ReentrantReadWriteLock lock =
+ new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ lock.writeLock().lock();
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ java.util.Date d = new java.util.Date();
+ assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis)));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ lock.writeLock().unlock();
+ } catch (InterruptedException e) {
+ threadUnexpectedException(e);
+ }
+ }
+
+ /**
+ * await returns when signalled
+ */
+ public void testAwait() { testAwait(false); }
+ public void testAwait_fair() { testAwait(true); }
+ public void testAwait(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch locked = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lock();
+ locked.countDown();
+ c.await();
+ lock.writeLock().unlock();
+ }});
+
+ await(locked);
+ lock.writeLock().lock();
+ assertHasWaiters(lock, c, t);
+ c.signal();
+ assertHasNoWaiters(lock, c);
+ assertTrue(t.isAlive());
+ lock.writeLock().unlock();
+ awaitTermination(t);
+ }
+
+ /**
+ * awaitUninterruptibly is uninterruptible
+ */
+ public void testAwaitUninterruptibly() { testAwaitUninterruptibly(false); }
+ public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
+ public void testAwaitUninterruptibly(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ // Interrupt before awaitUninterruptibly
+ lock.writeLock().lock();
+ pleaseInterrupt.countDown();
+ Thread.currentThread().interrupt();
+ c.awaitUninterruptibly();
+ assertTrue(Thread.interrupted());
+ lock.writeLock().unlock();
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ // Interrupt during awaitUninterruptibly
+ lock.writeLock().lock();
+ pleaseInterrupt.countDown();
+ c.awaitUninterruptibly();
+ assertTrue(Thread.interrupted());
+ lock.writeLock().unlock();
+ }});
+
+ await(pleaseInterrupt);
+ lock.writeLock().lock();
+ lock.writeLock().unlock();
+ t2.interrupt();
+
+ assertThreadStaysAlive(t1);
+ assertTrue(t2.isAlive());
+
+ lock.writeLock().lock();
+ c.signalAll();
+ lock.writeLock().unlock();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * await/awaitNanos/awaitUntil is interruptible
+ */
+ public void testInterruptible_await() { testInterruptible(false, AwaitMethod.await); }
+ public void testInterruptible_await_fair() { testInterruptible(true, AwaitMethod.await); }
+ public void testInterruptible_awaitTimed() { testInterruptible(false, AwaitMethod.awaitTimed); }
+ public void testInterruptible_awaitTimed_fair() { testInterruptible(true, AwaitMethod.awaitTimed); }
+ public void testInterruptible_awaitNanos() { testInterruptible(false, AwaitMethod.awaitNanos); }
+ public void testInterruptible_awaitNanos_fair() { testInterruptible(true, AwaitMethod.awaitNanos); }
+ public void testInterruptible_awaitUntil() { testInterruptible(false, AwaitMethod.awaitUntil); }
+ public void testInterruptible_awaitUntil_fair() { testInterruptible(true, AwaitMethod.awaitUntil); }
+ public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch locked = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lock();
+ assertWriteLockedByMoi(lock);
+ assertHasNoWaiters(lock, c);
+ locked.countDown();
+ try {
+ await(c, awaitMethod);
+ } finally {
+ assertWriteLockedByMoi(lock);
+ assertHasNoWaiters(lock, c);
+ lock.writeLock().unlock();
+ assertFalse(Thread.interrupted());
+ }
+ }});
+
+ await(locked);
+ assertHasWaiters(lock, c, t);
+ t.interrupt();
+ awaitTermination(t);
+ assertNotWriteLocked(lock);
+ }
+
+ /**
+ * signalAll wakes up all threads
+ */
+ public void testSignalAll_await() { testSignalAll(false, AwaitMethod.await); }
+ public void testSignalAll_await_fair() { testSignalAll(true, AwaitMethod.await); }
+ public void testSignalAll_awaitTimed() { testSignalAll(false, AwaitMethod.awaitTimed); }
+ public void testSignalAll_awaitTimed_fair() { testSignalAll(true, AwaitMethod.awaitTimed); }
+ public void testSignalAll_awaitNanos() { testSignalAll(false, AwaitMethod.awaitNanos); }
+ public void testSignalAll_awaitNanos_fair() { testSignalAll(true, AwaitMethod.awaitNanos); }
+ public void testSignalAll_awaitUntil() { testSignalAll(false, AwaitMethod.awaitUntil); }
+ public void testSignalAll_awaitUntil_fair() { testSignalAll(true, AwaitMethod.awaitUntil); }
+ public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch locked = new CountDownLatch(2);
+ final Lock writeLock = lock.writeLock();
+ class Awaiter extends CheckedRunnable {
+ public void realRun() throws InterruptedException {
+ writeLock.lock();
+ locked.countDown();
+ await(c, awaitMethod);
+ writeLock.unlock();
+ }
+ }
+
+ Thread t1 = newStartedThread(new Awaiter());
+ Thread t2 = newStartedThread(new Awaiter());
+
+ await(locked);
+ writeLock.lock();
+ assertHasWaiters(lock, c, t1, t2);
+ c.signalAll();
+ assertHasNoWaiters(lock, c);
+ writeLock.unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * signal wakes up waiting threads in FIFO order
+ */
+ public void testSignalWakesFifo() { testSignalWakesFifo(false); }
+ public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
+ public void testSignalWakesFifo(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch locked1 = new CountDownLatch(1);
+ final CountDownLatch locked2 = new CountDownLatch(1);
+ final Lock writeLock = lock.writeLock();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ writeLock.lock();
+ locked1.countDown();
+ c.await();
+ writeLock.unlock();
+ }});
+
+ await(locked1);
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ writeLock.lock();
+ locked2.countDown();
+ c.await();
+ writeLock.unlock();
+ }});
+
+ await(locked2);
+
+ writeLock.lock();
+ assertHasWaiters(lock, c, t1, t2);
+ assertFalse(lock.hasQueuedThreads());
+ c.signal();
+ assertHasWaiters(lock, c, t2);
+ assertTrue(lock.hasQueuedThread(t1));
+ assertFalse(lock.hasQueuedThread(t2));
+ c.signal();
+ assertHasNoWaiters(lock, c);
+ assertTrue(lock.hasQueuedThread(t1));
+ assertTrue(lock.hasQueuedThread(t2));
+ writeLock.unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * await after multiple reentrant locking preserves lock count
+ */
+ public void testAwaitLockCount() { testAwaitLockCount(false); }
+ public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
+ public void testAwaitLockCount(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch locked = new CountDownLatch(2);
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lock();
+ assertWriteLockedByMoi(lock);
+ assertEquals(1, lock.writeLock().getHoldCount());
+ locked.countDown();
+ c.await();
+ assertWriteLockedByMoi(lock);
+ assertEquals(1, lock.writeLock().getHoldCount());
+ lock.writeLock().unlock();
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lock();
+ lock.writeLock().lock();
+ assertWriteLockedByMoi(lock);
+ assertEquals(2, lock.writeLock().getHoldCount());
+ locked.countDown();
+ c.await();
+ assertWriteLockedByMoi(lock);
+ assertEquals(2, lock.writeLock().getHoldCount());
+ lock.writeLock().unlock();
+ lock.writeLock().unlock();
+ }});
+
+ await(locked);
+ lock.writeLock().lock();
+ assertHasWaiters(lock, c, t1, t2);
+ c.signalAll();
+ assertHasNoWaiters(lock, c);
+ lock.writeLock().unlock();
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * A serialized lock deserializes as unlocked
+ */
+ public void testSerialization() { testSerialization(false); }
+ public void testSerialization_fair() { testSerialization(true); }
+ public void testSerialization(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ lock.writeLock().lock();
+ lock.readLock().lock();
+
+ ReentrantReadWriteLock clone = serialClone(lock);
+ assertEquals(lock.isFair(), clone.isFair());
+ assertTrue(lock.isWriteLocked());
+ assertFalse(clone.isWriteLocked());
+ assertEquals(1, lock.getReadLockCount());
+ assertEquals(0, clone.getReadLockCount());
+ clone.writeLock().lock();
+ clone.readLock().lock();
+ assertTrue(clone.isWriteLocked());
+ assertEquals(1, clone.getReadLockCount());
+ clone.readLock().unlock();
+ clone.writeLock().unlock();
+ assertFalse(clone.isWriteLocked());
+ assertEquals(1, lock.getReadLockCount());
+ assertEquals(0, clone.getReadLockCount());
+ }
+
+ /**
+ * hasQueuedThreads reports whether there are waiting threads
+ */
+ public void testHasQueuedThreads() { testHasQueuedThreads(false); }
+ public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
+ public void testHasQueuedThreads(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+ Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+ assertFalse(lock.hasQueuedThreads());
+ lock.writeLock().lock();
+ assertFalse(lock.hasQueuedThreads());
+ t1.start();
+ waitForQueuedThread(lock, t1);
+ assertTrue(lock.hasQueuedThreads());
+ t2.start();
+ waitForQueuedThread(lock, t2);
+ assertTrue(lock.hasQueuedThreads());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(lock.hasQueuedThreads());
+ lock.writeLock().unlock();
+ awaitTermination(t2);
+ assertFalse(lock.hasQueuedThreads());
+ }
+
+ /**
+ * hasQueuedThread(null) throws NPE
+ */
+ public void testHasQueuedThreadNPE() { testHasQueuedThreadNPE(false); }
+ public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
+ public void testHasQueuedThreadNPE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ try {
+ lock.hasQueuedThread(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * hasQueuedThread reports whether a thread is queued
+ */
+ public void testHasQueuedThread() { testHasQueuedThread(false); }
+ public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
+ public void testHasQueuedThread(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+ Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+ assertFalse(lock.hasQueuedThread(t1));
+ assertFalse(lock.hasQueuedThread(t2));
+ lock.writeLock().lock();
+ t1.start();
+ waitForQueuedThread(lock, t1);
+ assertTrue(lock.hasQueuedThread(t1));
+ assertFalse(lock.hasQueuedThread(t2));
+ t2.start();
+ waitForQueuedThread(lock, t2);
+ assertTrue(lock.hasQueuedThread(t1));
+ assertTrue(lock.hasQueuedThread(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertFalse(lock.hasQueuedThread(t1));
+ assertTrue(lock.hasQueuedThread(t2));
+ lock.writeLock().unlock();
+ awaitTermination(t2);
+ assertFalse(lock.hasQueuedThread(t1));
+ assertFalse(lock.hasQueuedThread(t2));
+ }
+
+ /**
+ * getQueueLength reports number of waiting threads
+ */
+ public void testGetQueueLength() { testGetQueueLength(false); }
+ public void testGetQueueLength_fair() { testGetQueueLength(true); }
+ public void testGetQueueLength(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+ Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+ assertEquals(0, lock.getQueueLength());
+ lock.writeLock().lock();
+ t1.start();
+ waitForQueuedThread(lock, t1);
+ assertEquals(1, lock.getQueueLength());
+ t2.start();
+ waitForQueuedThread(lock, t2);
+ assertEquals(2, lock.getQueueLength());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertEquals(1, lock.getQueueLength());
+ lock.writeLock().unlock();
+ awaitTermination(t2);
+ assertEquals(0, lock.getQueueLength());
+ }
+
+ /**
+ * getQueuedThreads includes waiting threads
+ */
+ public void testGetQueuedThreads() { testGetQueuedThreads(false); }
+ public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
+ public void testGetQueuedThreads(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+ Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ lock.writeLock().lock();
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ t1.start();
+ waitForQueuedThread(lock, t1);
+ assertEquals(1, lock.getQueuedThreads().size());
+ assertTrue(lock.getQueuedThreads().contains(t1));
+ t2.start();
+ waitForQueuedThread(lock, t2);
+ assertEquals(2, lock.getQueuedThreads().size());
+ assertTrue(lock.getQueuedThreads().contains(t1));
+ assertTrue(lock.getQueuedThreads().contains(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertFalse(lock.getQueuedThreads().contains(t1));
+ assertTrue(lock.getQueuedThreads().contains(t2));
+ assertEquals(1, lock.getQueuedThreads().size());
+ lock.writeLock().unlock();
+ awaitTermination(t2);
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ }
+
+ /**
+ * hasWaiters throws NPE if null
+ */
+ public void testHasWaitersNPE() { testHasWaitersNPE(false); }
+ public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
+ public void testHasWaitersNPE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ try {
+ lock.hasWaiters(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getWaitQueueLength throws NPE if null
+ */
+ public void testGetWaitQueueLengthNPE() { testGetWaitQueueLengthNPE(false); }
+ public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
+ public void testGetWaitQueueLengthNPE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ try {
+ lock.getWaitQueueLength(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getWaitingThreads throws NPE if null
+ */
+ public void testGetWaitingThreadsNPE() { testGetWaitingThreadsNPE(false); }
+ public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
+ public void testGetWaitingThreadsNPE(boolean fair) {
+ final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(fair);
+ try {
+ lock.getWaitingThreads(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * hasWaiters throws IllegalArgumentException if not owned
+ */
+ public void testHasWaitersIAE() { testHasWaitersIAE(false); }
+ public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
+ public void testHasWaitersIAE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
+ try {
+ lock2.hasWaiters(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * hasWaiters throws IllegalMonitorStateException if not locked
+ */
+ public void testHasWaitersIMSE() { testHasWaitersIMSE(false); }
+ public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
+ public void testHasWaitersIMSE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ try {
+ lock.hasWaiters(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * getWaitQueueLength throws IllegalArgumentException if not owned
+ */
+ public void testGetWaitQueueLengthIAE() { testGetWaitQueueLengthIAE(false); }
+ public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
+ public void testGetWaitQueueLengthIAE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
+ try {
+ lock2.getWaitQueueLength(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * getWaitQueueLength throws IllegalMonitorStateException if not locked
+ */
+ public void testGetWaitQueueLengthIMSE() { testGetWaitQueueLengthIMSE(false); }
+ public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
+ public void testGetWaitQueueLengthIMSE(boolean fair) {
+ final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ try {
+ lock.getWaitQueueLength(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * getWaitingThreads throws IllegalArgumentException if not owned
+ */
+ public void testGetWaitingThreadsIAE() { testGetWaitingThreadsIAE(false); }
+ public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
+ public void testGetWaitingThreadsIAE(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final PublicReentrantReadWriteLock lock2 =
+ new PublicReentrantReadWriteLock(fair);
+ try {
+ lock2.getWaitingThreads(c);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * getWaitingThreads throws IllegalMonitorStateException if not locked
+ */
+ public void testGetWaitingThreadsIMSE() { testGetWaitingThreadsIMSE(false); }
+ public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
+ public void testGetWaitingThreadsIMSE(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ try {
+ lock.getWaitingThreads(c);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * hasWaiters returns true when a thread is waiting, else false
+ */
+ public void testHasWaiters() { testHasWaiters(false); }
+ public void testHasWaiters_fair() { testHasWaiters(true); }
+ public void testHasWaiters(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch locked = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lock();
+ assertHasNoWaiters(lock, c);
+ assertFalse(lock.hasWaiters(c));
+ locked.countDown();
+ c.await();
+ assertHasNoWaiters(lock, c);
+ assertFalse(lock.hasWaiters(c));
+ lock.writeLock().unlock();
+ }});
+
+ await(locked);
+ lock.writeLock().lock();
+ assertHasWaiters(lock, c, t);
+ assertTrue(lock.hasWaiters(c));
+ c.signal();
+ assertHasNoWaiters(lock, c);
+ assertFalse(lock.hasWaiters(c));
+ lock.writeLock().unlock();
+ awaitTermination(t);
+ assertHasNoWaiters(lock, c);
+ }
+
+ /**
+ * getWaitQueueLength returns number of waiting threads
+ */
+ public void testGetWaitQueueLength() { testGetWaitQueueLength(false); }
+ public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
+ public void testGetWaitQueueLength(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch locked = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lock();
+ assertEquals(0, lock.getWaitQueueLength(c));
+ locked.countDown();
+ c.await();
+ lock.writeLock().unlock();
+ }});
+
+ await(locked);
+ lock.writeLock().lock();
+ assertHasWaiters(lock, c, t);
+ assertEquals(1, lock.getWaitQueueLength(c));
+ c.signal();
+ assertHasNoWaiters(lock, c);
+ assertEquals(0, lock.getWaitQueueLength(c));
+ lock.writeLock().unlock();
+ awaitTermination(t);
+ }
+
+ /**
+ * getWaitingThreads returns only and all waiting threads
+ */
+ public void testGetWaitingThreads() { testGetWaitingThreads(false); }
+ public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
+ public void testGetWaitingThreads(boolean fair) {
+ final PublicReentrantReadWriteLock lock =
+ new PublicReentrantReadWriteLock(fair);
+ final Condition c = lock.writeLock().newCondition();
+ final CountDownLatch locked1 = new CountDownLatch(1);
+ final CountDownLatch locked2 = new CountDownLatch(1);
+ Thread t1 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lock();
+ assertTrue(lock.getWaitingThreads(c).isEmpty());
+ locked1.countDown();
+ c.await();
+ lock.writeLock().unlock();
+ }});
+
+ Thread t2 = new Thread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLock().lock();
+ assertFalse(lock.getWaitingThreads(c).isEmpty());
+ locked2.countDown();
+ c.await();
+ lock.writeLock().unlock();
+ }});
+
+ lock.writeLock().lock();
+ assertTrue(lock.getWaitingThreads(c).isEmpty());
+ lock.writeLock().unlock();
+
+ t1.start();
+ await(locked1);
+ t2.start();
+ await(locked2);
+
+ lock.writeLock().lock();
+ assertTrue(lock.hasWaiters(c));
+ assertTrue(lock.getWaitingThreads(c).contains(t1));
+ assertTrue(lock.getWaitingThreads(c).contains(t2));
+ assertEquals(2, lock.getWaitingThreads(c).size());
+ c.signalAll();
+ assertHasNoWaiters(lock, c);
+ lock.writeLock().unlock();
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+
+ assertHasNoWaiters(lock, c);
+ }
+
+ /**
+ * toString indicates current lock state
+ */
+ public void testToString() { testToString(false); }
+ public void testToString_fair() { testToString(true); }
+ public void testToString(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ assertTrue(lock.toString().contains("Write locks = 0"));
+ assertTrue(lock.toString().contains("Read locks = 0"));
+ lock.writeLock().lock();
+ assertTrue(lock.toString().contains("Write locks = 1"));
+ assertTrue(lock.toString().contains("Read locks = 0"));
+ lock.writeLock().unlock();
+ lock.readLock().lock();
+ lock.readLock().lock();
+ assertTrue(lock.toString().contains("Write locks = 0"));
+ assertTrue(lock.toString().contains("Read locks = 2"));
+ }
+
+ /**
+ * readLock.toString indicates current lock state
+ */
+ public void testReadLockToString() { testReadLockToString(false); }
+ public void testReadLockToString_fair() { testReadLockToString(true); }
+ public void testReadLockToString(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ assertTrue(lock.readLock().toString().contains("Read locks = 0"));
+ lock.readLock().lock();
+ lock.readLock().lock();
+ assertTrue(lock.readLock().toString().contains("Read locks = 2"));
+ }
+
+ /**
+ * writeLock.toString indicates current lock state
+ */
+ public void testWriteLockToString() { testWriteLockToString(false); }
+ public void testWriteLockToString_fair() { testWriteLockToString(true); }
+ public void testWriteLockToString(boolean fair) {
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+ assertTrue(lock.writeLock().toString().contains("Unlocked"));
+ lock.writeLock().lock();
+ assertTrue(lock.writeLock().toString().contains("Locked"));
+ lock.writeLock().unlock();
+ assertTrue(lock.writeLock().toString().contains("Unlocked"));
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java
new file mode 100644
index 0000000..b72ad02
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java
@@ -0,0 +1,1213 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ScheduledExecutorSubclassTest extends JSR166TestCase {
+
+ static class CustomTask<V> implements RunnableScheduledFuture<V> {
+ RunnableScheduledFuture<V> task;
+ volatile boolean ran;
+ CustomTask(RunnableScheduledFuture<V> t) { task = t; }
+ public boolean isPeriodic() { return task.isPeriodic(); }
+ public void run() {
+ ran = true;
+ task.run();
+ }
+ public long getDelay(TimeUnit unit) { return task.getDelay(unit); }
+ public int compareTo(Delayed t) {
+ return task.compareTo(((CustomTask)t).task);
+ }
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ return task.cancel(mayInterruptIfRunning);
+ }
+ public boolean isCancelled() { return task.isCancelled(); }
+ public boolean isDone() { return task.isDone(); }
+ public V get() throws InterruptedException, ExecutionException {
+ V v = task.get();
+ assertTrue(ran);
+ return v;
+ }
+ public V get(long time, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ V v = task.get(time, unit);
+ assertTrue(ran);
+ return v;
+ }
+ }
+
+ public class CustomExecutor extends ScheduledThreadPoolExecutor {
+
+ protected <V> RunnableScheduledFuture<V> decorateTask(Runnable r, RunnableScheduledFuture<V> task) {
+ return new CustomTask<V>(task);
+ }
+
+ protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> c, RunnableScheduledFuture<V> task) {
+ return new CustomTask<V>(task);
+ }
+ CustomExecutor(int corePoolSize) { super(corePoolSize); }
+ CustomExecutor(int corePoolSize, RejectedExecutionHandler handler) {
+ super(corePoolSize, handler);
+ }
+
+ CustomExecutor(int corePoolSize, ThreadFactory threadFactory) {
+ super(corePoolSize, threadFactory);
+ }
+ CustomExecutor(int corePoolSize, ThreadFactory threadFactory,
+ RejectedExecutionHandler handler) {
+ super(corePoolSize, threadFactory, handler);
+ }
+
+ }
+
+ /**
+ * execute successfully executes a runnable
+ */
+ public void testExecute() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ }};
+ try {
+ p.execute(task);
+ assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * delayed schedule of callable successfully executes after delay
+ */
+ public void testSchedule1() throws Exception {
+ CustomExecutor p = new CustomExecutor(1);
+ final long startTime = System.nanoTime();
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Callable task = new CheckedCallable<Boolean>() {
+ public Boolean realCall() {
+ done.countDown();
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ return Boolean.TRUE;
+ }};
+ Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
+ assertSame(Boolean.TRUE, f.get());
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ assertTrue(done.await(0L, MILLISECONDS));
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * delayed schedule of runnable successfully executes after delay
+ */
+ public void testSchedule3() throws Exception {
+ CustomExecutor p = new CustomExecutor(1);
+ final long startTime = System.nanoTime();
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }};
+ Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
+ await(done);
+ assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * scheduleAtFixedRate executes runnable after given initial delay
+ */
+ public void testSchedule4() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ final long startTime = System.nanoTime();
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }};
+ ScheduledFuture f =
+ p.scheduleAtFixedRate(task, timeoutMillis(),
+ LONG_DELAY_MS, MILLISECONDS);
+ await(done);
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ f.cancel(true);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * scheduleWithFixedDelay executes runnable after given initial delay
+ */
+ public void testSchedule5() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ final long startTime = System.nanoTime();
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }};
+ ScheduledFuture f =
+ p.scheduleWithFixedDelay(task, timeoutMillis(),
+ LONG_DELAY_MS, MILLISECONDS);
+ await(done);
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ f.cancel(true);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ static class RunnableCounter implements Runnable {
+ AtomicInteger count = new AtomicInteger(0);
+ public void run() { count.getAndIncrement(); }
+ }
+
+ /**
+ * scheduleAtFixedRate executes series of tasks at given rate
+ */
+ public void testFixedRateSequence() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ RunnableCounter counter = new RunnableCounter();
+ ScheduledFuture h =
+ p.scheduleAtFixedRate(counter, 0, 1, MILLISECONDS);
+ delay(SMALL_DELAY_MS);
+ h.cancel(true);
+ int c = counter.count.get();
+ // By time scaling conventions, we must have at least
+ // an execution per SHORT delay, but no more than one SHORT more
+ assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
+ assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
+ joinPool(p);
+ }
+
+ /**
+ * scheduleWithFixedDelay executes series of tasks with given period
+ */
+ public void testFixedDelaySequence() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ RunnableCounter counter = new RunnableCounter();
+ ScheduledFuture h =
+ p.scheduleWithFixedDelay(counter, 0, 1, MILLISECONDS);
+ delay(SMALL_DELAY_MS);
+ h.cancel(true);
+ int c = counter.count.get();
+ assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
+ assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
+ joinPool(p);
+ }
+
+ /**
+ * execute(null) throws NPE
+ */
+ public void testExecuteNull() throws InterruptedException {
+ CustomExecutor se = new CustomExecutor(1);
+ try {
+ se.execute(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ joinPool(se);
+ }
+
+ /**
+ * schedule(null) throws NPE
+ */
+ public void testScheduleNull() throws InterruptedException {
+ CustomExecutor se = new CustomExecutor(1);
+ try {
+ TrackedCallable callable = null;
+ Future f = se.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ joinPool(se);
+ }
+
+ /**
+ * execute throws RejectedExecutionException if shutdown
+ */
+ public void testSchedule1_RejectedExecutionException() {
+ CustomExecutor se = new CustomExecutor(1);
+ try {
+ se.shutdown();
+ se.schedule(new NoOpRunnable(),
+ MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+
+ joinPool(se);
+ }
+
+ /**
+ * schedule throws RejectedExecutionException if shutdown
+ */
+ public void testSchedule2_RejectedExecutionException() {
+ CustomExecutor se = new CustomExecutor(1);
+ try {
+ se.shutdown();
+ se.schedule(new NoOpCallable(),
+ MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+ joinPool(se);
+ }
+
+ /**
+ * schedule callable throws RejectedExecutionException if shutdown
+ */
+ public void testSchedule3_RejectedExecutionException() {
+ CustomExecutor se = new CustomExecutor(1);
+ try {
+ se.shutdown();
+ se.schedule(new NoOpCallable(),
+ MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+ joinPool(se);
+ }
+
+ /**
+ * scheduleAtFixedRate throws RejectedExecutionException if shutdown
+ */
+ public void testScheduleAtFixedRate1_RejectedExecutionException() {
+ CustomExecutor se = new CustomExecutor(1);
+ try {
+ se.shutdown();
+ se.scheduleAtFixedRate(new NoOpRunnable(),
+ MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+ joinPool(se);
+ }
+
+ /**
+ * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
+ */
+ public void testScheduleWithFixedDelay1_RejectedExecutionException() {
+ CustomExecutor se = new CustomExecutor(1);
+ try {
+ se.shutdown();
+ se.scheduleWithFixedDelay(new NoOpRunnable(),
+ MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+ joinPool(se);
+ }
+
+ /**
+ * getActiveCount increases but doesn't overestimate, when a
+ * thread becomes active
+ */
+ public void testGetActiveCount() throws InterruptedException {
+ final ThreadPoolExecutor p = new CustomExecutor(2);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getActiveCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getActiveCount());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getActiveCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getCompletedTaskCount increases, but doesn't overestimate,
+ * when tasks complete
+ */
+ public void testGetCompletedTaskCount() throws InterruptedException {
+ final ThreadPoolExecutor p = new CustomExecutor(2);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch threadProceed = new CountDownLatch(1);
+ final CountDownLatch threadDone = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getCompletedTaskCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(0, p.getCompletedTaskCount());
+ threadProceed.await();
+ threadDone.countDown();
+ }});
+ await(threadStarted);
+ assertEquals(0, p.getCompletedTaskCount());
+ threadProceed.countDown();
+ threadDone.await();
+ long startTime = System.nanoTime();
+ while (p.getCompletedTaskCount() != 1) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getCorePoolSize returns size given in constructor if not otherwise set
+ */
+ public void testGetCorePoolSize() {
+ CustomExecutor p = new CustomExecutor(1);
+ assertEquals(1, p.getCorePoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * getLargestPoolSize increases, but doesn't overestimate, when
+ * multiple threads active
+ */
+ public void testGetLargestPoolSize() throws InterruptedException {
+ final int THREADS = 3;
+ final ThreadPoolExecutor p = new CustomExecutor(THREADS);
+ final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getLargestPoolSize());
+ for (int i = 0; i < THREADS; i++)
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.countDown();
+ done.await();
+ assertEquals(THREADS, p.getLargestPoolSize());
+ }});
+ assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(THREADS, p.getLargestPoolSize());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ assertEquals(THREADS, p.getLargestPoolSize());
+ }
+ }
+
+ /**
+ * getPoolSize increases, but doesn't overestimate, when threads
+ * become active
+ */
+ public void testGetPoolSize() throws InterruptedException {
+ final ThreadPoolExecutor p = new CustomExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getPoolSize());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getPoolSize());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getPoolSize());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getTaskCount increases, but doesn't overestimate, when tasks
+ * submitted
+ */
+ public void testGetTaskCount() throws InterruptedException {
+ final ThreadPoolExecutor p = new CustomExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ final int TASKS = 5;
+ try {
+ assertEquals(0, p.getTaskCount());
+ for (int i = 0; i < TASKS; i++)
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(TASKS, p.getTaskCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getThreadFactory returns factory in constructor if not set
+ */
+ public void testGetThreadFactory() {
+ ThreadFactory tf = new SimpleThreadFactory();
+ CustomExecutor p = new CustomExecutor(1, tf);
+ assertSame(tf, p.getThreadFactory());
+ joinPool(p);
+ }
+
+ /**
+ * setThreadFactory sets the thread factory returned by getThreadFactory
+ */
+ public void testSetThreadFactory() {
+ ThreadFactory tf = new SimpleThreadFactory();
+ CustomExecutor p = new CustomExecutor(1);
+ p.setThreadFactory(tf);
+ assertSame(tf, p.getThreadFactory());
+ joinPool(p);
+ }
+
+ /**
+ * setThreadFactory(null) throws NPE
+ */
+ public void testSetThreadFactoryNull() {
+ CustomExecutor p = new CustomExecutor(1);
+ try {
+ p.setThreadFactory(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * isShutdown is false before shutdown, true after
+ */
+ public void testIsShutdown() {
+ CustomExecutor p = new CustomExecutor(1);
+ try {
+ assertFalse(p.isShutdown());
+ }
+ finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.isShutdown());
+ }
+
+ /**
+ * isTerminated is false before termination, true after
+ */
+ public void testIsTerminated() throws InterruptedException {
+ final ThreadPoolExecutor p = new CustomExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ assertFalse(p.isTerminated());
+ try {
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(p.isTerminated());
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
+ done.countDown();
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ }
+
+ /**
+ * isTerminating is not true when running or when terminated
+ */
+ public void testIsTerminating() throws InterruptedException {
+ final ThreadPoolExecutor p = new CustomExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertFalse(p.isTerminating());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(p.isTerminating());
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
+ done.countDown();
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ assertFalse(p.isTerminating());
+ }
+
+ /**
+ * getQueue returns the work queue, which contains queued tasks
+ */
+ public void testGetQueue() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new CustomExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ for (int i = 0; i < tasks.length; i++) {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ }};
+ tasks[i] = p.schedule(r, 1, MILLISECONDS);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ BlockingQueue<Runnable> q = p.getQueue();
+ assertTrue(q.contains(tasks[tasks.length - 1]));
+ assertFalse(q.contains(tasks[0]));
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * remove(task) removes queued task, and fails to remove active task
+ */
+ public void testRemove() throws InterruptedException {
+ final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ for (int i = 0; i < tasks.length; i++) {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ }};
+ tasks[i] = p.schedule(r, 1, MILLISECONDS);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ BlockingQueue<Runnable> q = p.getQueue();
+ assertFalse(p.remove((Runnable)tasks[0]));
+ assertTrue(q.contains((Runnable)tasks[4]));
+ assertTrue(q.contains((Runnable)tasks[3]));
+ assertTrue(p.remove((Runnable)tasks[4]));
+ assertFalse(p.remove((Runnable)tasks[4]));
+ assertFalse(q.contains((Runnable)tasks[4]));
+ assertTrue(q.contains((Runnable)tasks[3]));
+ assertTrue(p.remove((Runnable)tasks[3]));
+ assertFalse(q.contains((Runnable)tasks[3]));
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * purge removes cancelled tasks from the queue
+ */
+ public void testPurge() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ for (int i = 0; i < tasks.length; i++)
+ tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
+ LONG_DELAY_MS, MILLISECONDS);
+ try {
+ int max = tasks.length;
+ if (tasks[4].cancel(true)) --max;
+ if (tasks[3].cancel(true)) --max;
+ // There must eventually be an interference-free point at
+ // which purge will not fail. (At worst, when queue is empty.)
+ long startTime = System.nanoTime();
+ do {
+ p.purge();
+ long count = p.getTaskCount();
+ if (count == max)
+ return;
+ } while (millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
+ fail("Purge failed to remove cancelled tasks");
+ } finally {
+ for (ScheduledFuture task : tasks)
+ task.cancel(true);
+ joinPool(p);
+ }
+ }
+
+ /**
+ * shutdownNow returns a list containing tasks that were not run
+ */
+ public void testShutdownNow() {
+ CustomExecutor p = new CustomExecutor(1);
+ for (int i = 0; i < 5; i++)
+ p.schedule(new SmallPossiblyInterruptedRunnable(),
+ LONG_DELAY_MS, MILLISECONDS);
+ try {
+ List<Runnable> l = p.shutdownNow();
+ assertTrue(p.isShutdown());
+ assertEquals(5, l.size());
+ } catch (SecurityException ok) {
+ // Allowed in case test doesn't have privs
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * In default setting, shutdown cancels periodic but not delayed
+ * tasks at shutdown
+ */
+ public void testShutdown1() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ for (int i = 0; i < tasks.length; i++)
+ tasks[i] = p.schedule(new NoOpRunnable(),
+ SHORT_DELAY_MS, MILLISECONDS);
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ BlockingQueue<Runnable> q = p.getQueue();
+ for (ScheduledFuture task : tasks) {
+ assertFalse(task.isDone());
+ assertFalse(task.isCancelled());
+ assertTrue(q.contains(task));
+ }
+ assertTrue(p.isShutdown());
+ assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ for (ScheduledFuture task : tasks) {
+ assertTrue(task.isDone());
+ assertFalse(task.isCancelled());
+ }
+ }
+
+ /**
+ * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false,
+ * delayed tasks are cancelled at shutdown
+ */
+ public void testShutdown2() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ p.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+ assertFalse(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ for (int i = 0; i < tasks.length; i++)
+ tasks[i] = p.schedule(new NoOpRunnable(),
+ SHORT_DELAY_MS, MILLISECONDS);
+ BlockingQueue q = p.getQueue();
+ assertEquals(tasks.length, q.size());
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertTrue(p.isShutdown());
+ assertTrue(q.isEmpty());
+ assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ for (ScheduledFuture task : tasks) {
+ assertTrue(task.isDone());
+ assertTrue(task.isCancelled());
+ }
+ }
+
+ /**
+ * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false,
+ * periodic tasks are cancelled at shutdown
+ */
+ public void testShutdown3() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+ p.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+ assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+ long initialDelay = LONG_DELAY_MS;
+ ScheduledFuture task =
+ p.scheduleAtFixedRate(new NoOpRunnable(), initialDelay,
+ 5, MILLISECONDS);
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertTrue(p.isShutdown());
+ assertTrue(p.getQueue().isEmpty());
+ assertTrue(task.isDone());
+ assertTrue(task.isCancelled());
+ joinPool(p);
+ }
+
+ /**
+ * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true,
+ * periodic tasks are not cancelled at shutdown
+ */
+ public void testShutdown4() throws InterruptedException {
+ CustomExecutor p = new CustomExecutor(1);
+ final CountDownLatch counter = new CountDownLatch(2);
+ try {
+ p.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
+ assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertTrue(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+ final Runnable r = new CheckedRunnable() {
+ public void realRun() {
+ counter.countDown();
+ }};
+ ScheduledFuture task =
+ p.scheduleAtFixedRate(r, 1, 1, MILLISECONDS);
+ assertFalse(task.isDone());
+ assertFalse(task.isCancelled());
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertFalse(task.isCancelled());
+ assertFalse(p.isTerminated());
+ assertTrue(p.isShutdown());
+ assertTrue(counter.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(task.isCancelled());
+ assertTrue(task.cancel(false));
+ assertTrue(task.isDone());
+ assertTrue(task.isCancelled());
+ assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ }
+ finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * completed submit of callable returns result
+ */
+ public void testSubmitCallable() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ Future<String> future = e.submit(new StringTask());
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * completed submit of runnable returns successfully
+ */
+ public void testSubmitRunnable() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ Future<?> future = e.submit(new NoOpRunnable());
+ future.get();
+ assertTrue(future.isDone());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * completed submit of (runnable, result) returns result
+ */
+ public void testSubmitRunnable2() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(null) throws NPE
+ */
+ public void testInvokeAny1() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ e.invokeAny(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(empty collection) throws IAE
+ */
+ public void testInvokeAny2() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws NPE if c has null elements
+ */
+ public void testInvokeAny3() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testInvokeAny4() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) returns result of some task
+ */
+ public void testInvokeAny5() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(null) throws NPE
+ */
+ public void testInvokeAll1() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ e.invokeAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(empty collection) returns empty collection
+ */
+ public void testInvokeAll2() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) throws NPE if c has null elements
+ */
+ public void testInvokeAll3() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of invokeAll(c) throws exception on failed task
+ */
+ public void testInvokeAll4() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) returns results of all completed tasks
+ */
+ public void testInvokeAll5() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(null) throws NPE
+ */
+ public void testTimedInvokeAny1() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(,,null) throws NPE
+ */
+ public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(empty collection) throws IAE
+ */
+ public void testTimedInvokeAny2() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAny3() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testTimedInvokeAny4() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) returns result of some task
+ */
+ public void testTimedInvokeAny5() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(null) throws NPE
+ */
+ public void testTimedInvokeAll1() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(,,null) throws NPE
+ */
+ public void testTimedInvokeAllNullTimeUnit() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(empty collection) returns empty collection
+ */
+ public void testTimedInvokeAll2() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAll3() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of element of invokeAll(c) throws exception on failed task
+ */
+ public void testTimedInvokeAll4() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) returns results of all completed tasks
+ */
+ public void testTimedInvokeAll5() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) cancels tasks not completed by timeout
+ */
+ public void testTimedInvokeAll6() throws Exception {
+ ExecutorService e = new CustomExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+ assertEquals(l.size(), futures.size());
+ for (Future future : futures)
+ assertTrue(future.isDone());
+ assertFalse(futures.get(0).isCancelled());
+ assertTrue(futures.get(1).isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java
new file mode 100644
index 0000000..4eea2c9
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java
@@ -0,0 +1,1164 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ScheduledExecutorTest extends JSR166TestCase {
+
+ /**
+ * execute successfully executes a runnable
+ */
+ public void testExecute() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ }};
+ try {
+ p.execute(task);
+ assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * delayed schedule of callable successfully executes after delay
+ */
+ public void testSchedule1() throws Exception {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final long startTime = System.nanoTime();
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Callable task = new CheckedCallable<Boolean>() {
+ public Boolean realCall() {
+ done.countDown();
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ return Boolean.TRUE;
+ }};
+ Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
+ assertSame(Boolean.TRUE, f.get());
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ assertTrue(done.await(0L, MILLISECONDS));
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * delayed schedule of runnable successfully executes after delay
+ */
+ public void testSchedule3() throws Exception {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final long startTime = System.nanoTime();
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }};
+ Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
+ await(done);
+ assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * scheduleAtFixedRate executes runnable after given initial delay
+ */
+ public void testSchedule4() throws Exception {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final long startTime = System.nanoTime();
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }};
+ ScheduledFuture f =
+ p.scheduleAtFixedRate(task, timeoutMillis(),
+ LONG_DELAY_MS, MILLISECONDS);
+ await(done);
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ f.cancel(true);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * scheduleWithFixedDelay executes runnable after given initial delay
+ */
+ public void testSchedule5() throws Exception {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final long startTime = System.nanoTime();
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }};
+ ScheduledFuture f =
+ p.scheduleWithFixedDelay(task, timeoutMillis(),
+ LONG_DELAY_MS, MILLISECONDS);
+ await(done);
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ f.cancel(true);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ static class RunnableCounter implements Runnable {
+ AtomicInteger count = new AtomicInteger(0);
+ public void run() { count.getAndIncrement(); }
+ }
+
+ /**
+ * scheduleAtFixedRate executes series of tasks at given rate
+ */
+ public void testFixedRateSequence() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ RunnableCounter counter = new RunnableCounter();
+ ScheduledFuture h =
+ p.scheduleAtFixedRate(counter, 0, 1, MILLISECONDS);
+ delay(SMALL_DELAY_MS);
+ h.cancel(true);
+ int c = counter.count.get();
+ // By time scaling conventions, we must have at least
+ // an execution per SHORT delay, but no more than one SHORT more
+ assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
+ assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
+ joinPool(p);
+ }
+
+ /**
+ * scheduleWithFixedDelay executes series of tasks with given period
+ */
+ public void testFixedDelaySequence() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ RunnableCounter counter = new RunnableCounter();
+ ScheduledFuture h =
+ p.scheduleWithFixedDelay(counter, 0, 1, MILLISECONDS);
+ delay(SMALL_DELAY_MS);
+ h.cancel(true);
+ int c = counter.count.get();
+ assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
+ assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
+ joinPool(p);
+ }
+
+ /**
+ * execute(null) throws NPE
+ */
+ public void testExecuteNull() throws InterruptedException {
+ ScheduledThreadPoolExecutor se = null;
+ try {
+ se = new ScheduledThreadPoolExecutor(1);
+ se.execute(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+
+ joinPool(se);
+ }
+
+ /**
+ * schedule(null) throws NPE
+ */
+ public void testScheduleNull() throws InterruptedException {
+ ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
+ try {
+ TrackedCallable callable = null;
+ Future f = se.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ joinPool(se);
+ }
+
+ /**
+ * execute throws RejectedExecutionException if shutdown
+ */
+ public void testSchedule1_RejectedExecutionException() throws InterruptedException {
+ ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
+ try {
+ se.shutdown();
+ se.schedule(new NoOpRunnable(),
+ MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+
+ joinPool(se);
+ }
+
+ /**
+ * schedule throws RejectedExecutionException if shutdown
+ */
+ public void testSchedule2_RejectedExecutionException() throws InterruptedException {
+ ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
+ try {
+ se.shutdown();
+ se.schedule(new NoOpCallable(),
+ MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+ joinPool(se);
+ }
+
+ /**
+ * schedule callable throws RejectedExecutionException if shutdown
+ */
+ public void testSchedule3_RejectedExecutionException() throws InterruptedException {
+ ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
+ try {
+ se.shutdown();
+ se.schedule(new NoOpCallable(),
+ MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+ joinPool(se);
+ }
+
+ /**
+ * scheduleAtFixedRate throws RejectedExecutionException if shutdown
+ */
+ public void testScheduleAtFixedRate1_RejectedExecutionException() throws InterruptedException {
+ ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
+ try {
+ se.shutdown();
+ se.scheduleAtFixedRate(new NoOpRunnable(),
+ MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+ joinPool(se);
+ }
+
+ /**
+ * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
+ */
+ public void testScheduleWithFixedDelay1_RejectedExecutionException() throws InterruptedException {
+ ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
+ try {
+ se.shutdown();
+ se.scheduleWithFixedDelay(new NoOpRunnable(),
+ MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {
+ } catch (SecurityException ok) {
+ }
+ joinPool(se);
+ }
+
+ /**
+ * getActiveCount increases but doesn't overestimate, when a
+ * thread becomes active
+ */
+ public void testGetActiveCount() throws InterruptedException {
+ final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getActiveCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getActiveCount());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getActiveCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getCompletedTaskCount increases, but doesn't overestimate,
+ * when tasks complete
+ */
+ public void testGetCompletedTaskCount() throws InterruptedException {
+ final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch threadProceed = new CountDownLatch(1);
+ final CountDownLatch threadDone = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getCompletedTaskCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(0, p.getCompletedTaskCount());
+ threadProceed.await();
+ threadDone.countDown();
+ }});
+ await(threadStarted);
+ assertEquals(0, p.getCompletedTaskCount());
+ threadProceed.countDown();
+ threadDone.await();
+ long startTime = System.nanoTime();
+ while (p.getCompletedTaskCount() != 1) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getCorePoolSize returns size given in constructor if not otherwise set
+ */
+ public void testGetCorePoolSize() throws InterruptedException {
+ ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ assertEquals(1, p.getCorePoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * getLargestPoolSize increases, but doesn't overestimate, when
+ * multiple threads active
+ */
+ public void testGetLargestPoolSize() throws InterruptedException {
+ final int THREADS = 3;
+ final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(THREADS);
+ final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getLargestPoolSize());
+ for (int i = 0; i < THREADS; i++)
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.countDown();
+ done.await();
+ assertEquals(THREADS, p.getLargestPoolSize());
+ }});
+ assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(THREADS, p.getLargestPoolSize());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ assertEquals(THREADS, p.getLargestPoolSize());
+ }
+ }
+
+ /**
+ * getPoolSize increases, but doesn't overestimate, when threads
+ * become active
+ */
+ public void testGetPoolSize() throws InterruptedException {
+ final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getPoolSize());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getPoolSize());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getPoolSize());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getTaskCount increases, but doesn't overestimate, when tasks
+ * submitted
+ */
+ public void testGetTaskCount() throws InterruptedException {
+ final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ final int TASKS = 5;
+ try {
+ assertEquals(0, p.getTaskCount());
+ for (int i = 0; i < TASKS; i++)
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(TASKS, p.getTaskCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getThreadFactory returns factory in constructor if not set
+ */
+ public void testGetThreadFactory() throws InterruptedException {
+ ThreadFactory tf = new SimpleThreadFactory();
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1, tf);
+ assertSame(tf, p.getThreadFactory());
+ joinPool(p);
+ }
+
+ /**
+ * setThreadFactory sets the thread factory returned by getThreadFactory
+ */
+ public void testSetThreadFactory() throws InterruptedException {
+ ThreadFactory tf = new SimpleThreadFactory();
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ p.setThreadFactory(tf);
+ assertSame(tf, p.getThreadFactory());
+ joinPool(p);
+ }
+
+ /**
+ * setThreadFactory(null) throws NPE
+ */
+ public void testSetThreadFactoryNull() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ try {
+ p.setThreadFactory(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * isShutdown is false before shutdown, true after
+ */
+ public void testIsShutdown() {
+
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ try {
+ assertFalse(p.isShutdown());
+ }
+ finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.isShutdown());
+ }
+
+ /**
+ * isTerminated is false before termination, true after
+ */
+ public void testIsTerminated() throws InterruptedException {
+ final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ assertFalse(p.isTerminated());
+ try {
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(p.isTerminated());
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
+ done.countDown();
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ }
+
+ /**
+ * isTerminating is not true when running or when terminated
+ */
+ public void testIsTerminating() throws InterruptedException {
+ final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertFalse(p.isTerminating());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(p.isTerminating());
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
+ done.countDown();
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ assertFalse(p.isTerminating());
+ }
+
+ /**
+ * getQueue returns the work queue, which contains queued tasks
+ */
+ public void testGetQueue() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ for (int i = 0; i < tasks.length; i++) {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ }};
+ tasks[i] = p.schedule(r, 1, MILLISECONDS);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ BlockingQueue<Runnable> q = p.getQueue();
+ assertTrue(q.contains(tasks[tasks.length - 1]));
+ assertFalse(q.contains(tasks[0]));
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * remove(task) removes queued task, and fails to remove active task
+ */
+ public void testRemove() throws InterruptedException {
+ final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ for (int i = 0; i < tasks.length; i++) {
+ Runnable r = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ }};
+ tasks[i] = p.schedule(r, 1, MILLISECONDS);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ BlockingQueue<Runnable> q = p.getQueue();
+ assertFalse(p.remove((Runnable)tasks[0]));
+ assertTrue(q.contains((Runnable)tasks[4]));
+ assertTrue(q.contains((Runnable)tasks[3]));
+ assertTrue(p.remove((Runnable)tasks[4]));
+ assertFalse(p.remove((Runnable)tasks[4]));
+ assertFalse(q.contains((Runnable)tasks[4]));
+ assertTrue(q.contains((Runnable)tasks[3]));
+ assertTrue(p.remove((Runnable)tasks[3]));
+ assertFalse(q.contains((Runnable)tasks[3]));
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * purge eventually removes cancelled tasks from the queue
+ */
+ public void testPurge() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ for (int i = 0; i < tasks.length; i++)
+ tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
+ LONG_DELAY_MS, MILLISECONDS);
+ try {
+ int max = tasks.length;
+ if (tasks[4].cancel(true)) --max;
+ if (tasks[3].cancel(true)) --max;
+ // There must eventually be an interference-free point at
+ // which purge will not fail. (At worst, when queue is empty.)
+ long startTime = System.nanoTime();
+ do {
+ p.purge();
+ long count = p.getTaskCount();
+ if (count == max)
+ return;
+ } while (millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
+ fail("Purge failed to remove cancelled tasks");
+ } finally {
+ for (ScheduledFuture task : tasks)
+ task.cancel(true);
+ joinPool(p);
+ }
+ }
+
+ /**
+ * shutdownNow returns a list containing tasks that were not run
+ */
+ public void testShutdownNow() {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ for (int i = 0; i < 5; i++)
+ p.schedule(new SmallPossiblyInterruptedRunnable(),
+ LONG_DELAY_MS, MILLISECONDS);
+ try {
+ List<Runnable> l = p.shutdownNow();
+ assertTrue(p.isShutdown());
+ assertEquals(5, l.size());
+ } catch (SecurityException ok) {
+ // Allowed in case test doesn't have privs
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * In default setting, shutdown cancels periodic but not delayed
+ * tasks at shutdown
+ */
+ public void testShutdown1() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ for (int i = 0; i < tasks.length; i++)
+ tasks[i] = p.schedule(new NoOpRunnable(),
+ SHORT_DELAY_MS, MILLISECONDS);
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ BlockingQueue<Runnable> q = p.getQueue();
+ for (ScheduledFuture task : tasks) {
+ assertFalse(task.isDone());
+ assertFalse(task.isCancelled());
+ assertTrue(q.contains(task));
+ }
+ assertTrue(p.isShutdown());
+ assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ for (ScheduledFuture task : tasks) {
+ assertTrue(task.isDone());
+ assertFalse(task.isCancelled());
+ }
+ }
+
+ /**
+ * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false,
+ * delayed tasks are cancelled at shutdown
+ */
+ public void testShutdown2() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ p.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+ assertFalse(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+ ScheduledFuture[] tasks = new ScheduledFuture[5];
+ for (int i = 0; i < tasks.length; i++)
+ tasks[i] = p.schedule(new NoOpRunnable(),
+ SHORT_DELAY_MS, MILLISECONDS);
+ BlockingQueue q = p.getQueue();
+ assertEquals(tasks.length, q.size());
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertTrue(p.isShutdown());
+ assertTrue(q.isEmpty());
+ assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ for (ScheduledFuture task : tasks) {
+ assertTrue(task.isDone());
+ assertTrue(task.isCancelled());
+ }
+ }
+
+ /**
+ * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false,
+ * periodic tasks are cancelled at shutdown
+ */
+ public void testShutdown3() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+ p.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+ assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+ long initialDelay = LONG_DELAY_MS;
+ ScheduledFuture task =
+ p.scheduleAtFixedRate(new NoOpRunnable(), initialDelay,
+ 5, MILLISECONDS);
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertTrue(p.isShutdown());
+ assertTrue(p.getQueue().isEmpty());
+ assertTrue(task.isDone());
+ assertTrue(task.isCancelled());
+ joinPool(p);
+ }
+
+ /**
+ * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true,
+ * periodic tasks are not cancelled at shutdown
+ */
+ public void testShutdown4() throws InterruptedException {
+ ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ final CountDownLatch counter = new CountDownLatch(2);
+ try {
+ p.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
+ assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+ assertTrue(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+ final Runnable r = new CheckedRunnable() {
+ public void realRun() {
+ counter.countDown();
+ }};
+ ScheduledFuture task =
+ p.scheduleAtFixedRate(r, 1, 1, MILLISECONDS);
+ assertFalse(task.isDone());
+ assertFalse(task.isCancelled());
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertFalse(task.isCancelled());
+ assertFalse(p.isTerminated());
+ assertTrue(p.isShutdown());
+ assertTrue(counter.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(task.isCancelled());
+ assertTrue(task.cancel(false));
+ assertTrue(task.isDone());
+ assertTrue(task.isCancelled());
+ assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ }
+ finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * completed submit of callable returns result
+ */
+ public void testSubmitCallable() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ Future<String> future = e.submit(new StringTask());
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * completed submit of runnable returns successfully
+ */
+ public void testSubmitRunnable() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ Future<?> future = e.submit(new NoOpRunnable());
+ future.get();
+ assertTrue(future.isDone());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * completed submit of (runnable, result) returns result
+ */
+ public void testSubmitRunnable2() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(null) throws NPE
+ */
+ public void testInvokeAny1() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ e.invokeAny(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(empty collection) throws IAE
+ */
+ public void testInvokeAny2() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws NPE if c has null elements
+ */
+ public void testInvokeAny3() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testInvokeAny4() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) returns result of some task
+ */
+ public void testInvokeAny5() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(null) throws NPE
+ */
+ public void testInvokeAll1() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ e.invokeAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(empty collection) returns empty collection
+ */
+ public void testInvokeAll2() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) throws NPE if c has null elements
+ */
+ public void testInvokeAll3() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of invokeAll(c) throws exception on failed task
+ */
+ public void testInvokeAll4() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) returns results of all completed tasks
+ */
+ public void testInvokeAll5() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(null) throws NPE
+ */
+ public void testTimedInvokeAny1() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(,,null) throws NPE
+ */
+ public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(empty collection) throws IAE
+ */
+ public void testTimedInvokeAny2() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAny3() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testTimedInvokeAny4() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) returns result of some task
+ */
+ public void testTimedInvokeAny5() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(null) throws NPE
+ */
+ public void testTimedInvokeAll1() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(,,null) throws NPE
+ */
+ public void testTimedInvokeAllNullTimeUnit() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(empty collection) returns empty collection
+ */
+ public void testTimedInvokeAll2() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAll3() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of element of invokeAll(c) throws exception on failed task
+ */
+ public void testTimedInvokeAll4() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) returns results of all completed tasks
+ */
+ public void testTimedInvokeAll5() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) cancels tasks not completed by timeout
+ */
+ public void testTimedInvokeAll6() throws Exception {
+ ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+ assertEquals(l.size(), futures.size());
+ for (Future future : futures)
+ assertTrue(future.isDone());
+ assertFalse(futures.get(0).isCancelled());
+ assertTrue(futures.get(1).isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java b/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java
new file mode 100644
index 0000000..f303285
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java
@@ -0,0 +1,629 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class SemaphoreTest extends JSR166TestCase {
+
+ /**
+ * Subclass to expose protected methods
+ */
+ static class PublicSemaphore extends Semaphore {
+ PublicSemaphore(int permits) { super(permits); }
+ PublicSemaphore(int permits, boolean fair) { super(permits, fair); }
+ public Collection<Thread> getQueuedThreads() {
+ return super.getQueuedThreads();
+ }
+ public boolean hasQueuedThread(Thread t) {
+ return super.getQueuedThreads().contains(t);
+ }
+ public void reducePermits(int reduction) {
+ super.reducePermits(reduction);
+ }
+ }
+
+ /**
+ * A runnable calling acquire
+ */
+ class InterruptibleLockRunnable extends CheckedRunnable {
+ final Semaphore lock;
+ InterruptibleLockRunnable(Semaphore s) { lock = s; }
+ public void realRun() {
+ try {
+ lock.acquire();
+ }
+ catch (InterruptedException ignored) {}
+ }
+ }
+
+ /**
+ * A runnable calling acquire that expects to be interrupted
+ */
+ class InterruptedLockRunnable extends CheckedInterruptedRunnable {
+ final Semaphore lock;
+ InterruptedLockRunnable(Semaphore s) { lock = s; }
+ public void realRun() throws InterruptedException {
+ lock.acquire();
+ }
+ }
+
+ /**
+ * Spin-waits until s.hasQueuedThread(t) becomes true.
+ */
+ void waitForQueuedThread(PublicSemaphore s, Thread t) {
+ long startTime = System.nanoTime();
+ while (!s.hasQueuedThread(t)) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ throw new AssertionFailedError("timed out");
+ Thread.yield();
+ }
+ assertTrue(s.hasQueuedThreads());
+ assertTrue(t.isAlive());
+ }
+
+ /**
+ * Spin-waits until s.hasQueuedThreads() becomes true.
+ */
+ void waitForQueuedThreads(Semaphore s) {
+ long startTime = System.nanoTime();
+ while (!s.hasQueuedThreads()) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ throw new AssertionFailedError("timed out");
+ Thread.yield();
+ }
+ }
+
+ enum AcquireMethod {
+ acquire() {
+ void acquire(Semaphore s) throws InterruptedException {
+ s.acquire();
+ }
+ },
+ acquireN() {
+ void acquire(Semaphore s, int permits) throws InterruptedException {
+ s.acquire(permits);
+ }
+ },
+ acquireUninterruptibly() {
+ void acquire(Semaphore s) {
+ s.acquireUninterruptibly();
+ }
+ },
+ acquireUninterruptiblyN() {
+ void acquire(Semaphore s, int permits) {
+ s.acquireUninterruptibly(permits);
+ }
+ },
+ tryAcquire() {
+ void acquire(Semaphore s) {
+ assertTrue(s.tryAcquire());
+ }
+ },
+ tryAcquireN() {
+ void acquire(Semaphore s, int permits) {
+ assertTrue(s.tryAcquire(permits));
+ }
+ },
+ tryAcquireTimed() {
+ void acquire(Semaphore s) throws InterruptedException {
+ assertTrue(s.tryAcquire(2 * LONG_DELAY_MS, MILLISECONDS));
+ }
+ },
+ tryAcquireTimedN {
+ void acquire(Semaphore s, int permits) throws InterruptedException {
+ assertTrue(s.tryAcquire(permits, 2 * LONG_DELAY_MS, MILLISECONDS));
+ }
+ };
+
+ // Intentionally meta-circular
+
+ /** Acquires 1 permit. */
+ void acquire(Semaphore s) throws InterruptedException {
+ acquire(s, 1);
+ }
+ /** Acquires the given number of permits. */
+ void acquire(Semaphore s, int permits) throws InterruptedException {
+ for (int i = 0; i < permits; i++)
+ acquire(s);
+ }
+ }
+
+ /**
+ * Zero, negative, and positive initial values are allowed in constructor
+ */
+ public void testConstructor() { testConstructor(false); }
+ public void testConstructor_fair() { testConstructor(true); }
+ public void testConstructor(boolean fair) {
+ for (int permits : new int[] { -42, -1, 0, 1, 42 }) {
+ Semaphore s = new Semaphore(permits, fair);
+ assertEquals(permits, s.availablePermits());
+ assertEquals(fair, s.isFair());
+ }
+ }
+
+ /**
+ * Constructor without fairness argument behaves as nonfair
+ */
+ public void testConstructorDefaultsToNonFair() {
+ for (int permits : new int[] { -42, -1, 0, 1, 42 }) {
+ Semaphore s = new Semaphore(permits);
+ assertEquals(permits, s.availablePermits());
+ assertFalse(s.isFair());
+ }
+ }
+
+ /**
+ * tryAcquire succeeds when sufficient permits, else fails
+ */
+ public void testTryAcquireInSameThread() { testTryAcquireInSameThread(false); }
+ public void testTryAcquireInSameThread_fair() { testTryAcquireInSameThread(true); }
+ public void testTryAcquireInSameThread(boolean fair) {
+ Semaphore s = new Semaphore(2, fair);
+ assertEquals(2, s.availablePermits());
+ assertTrue(s.tryAcquire());
+ assertTrue(s.tryAcquire());
+ assertEquals(0, s.availablePermits());
+ assertFalse(s.tryAcquire());
+ assertFalse(s.tryAcquire());
+ assertEquals(0, s.availablePermits());
+ }
+
+ /**
+ * timed tryAcquire times out
+ */
+ public void testTryAcquire_timeout() { testTryAcquire_timeout(false); }
+ public void testTryAcquire_timeout_fair() { testTryAcquire_timeout(true); }
+ public void testTryAcquire_timeout(boolean fair) {
+ Semaphore s = new Semaphore(0, fair);
+ long startTime = System.nanoTime();
+ try { assertFalse(s.tryAcquire(timeoutMillis(), MILLISECONDS)); }
+ catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }
+
+ /**
+ * timed tryAcquire(N) times out
+ */
+ public void testTryAcquireN_timeout() { testTryAcquireN_timeout(false); }
+ public void testTryAcquireN_timeout_fair() { testTryAcquireN_timeout(true); }
+ public void testTryAcquireN_timeout(boolean fair) {
+ Semaphore s = new Semaphore(2, fair);
+ long startTime = System.nanoTime();
+ try { assertFalse(s.tryAcquire(3, timeoutMillis(), MILLISECONDS)); }
+ catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }
+
+ /**
+ * acquire(), acquire(N), timed tryAcquired, timed tryAcquire(N)
+ * are interruptible
+ */
+ public void testInterruptible_acquire() { testInterruptible(false, AcquireMethod.acquire); }
+ public void testInterruptible_acquire_fair() { testInterruptible(true, AcquireMethod.acquire); }
+ public void testInterruptible_acquireN() { testInterruptible(false, AcquireMethod.acquireN); }
+ public void testInterruptible_acquireN_fair() { testInterruptible(true, AcquireMethod.acquireN); }
+ public void testInterruptible_tryAcquireTimed() { testInterruptible(false, AcquireMethod.tryAcquireTimed); }
+ public void testInterruptible_tryAcquireTimed_fair() { testInterruptible(true, AcquireMethod.tryAcquireTimed); }
+ public void testInterruptible_tryAcquireTimedN() { testInterruptible(false, AcquireMethod.tryAcquireTimedN); }
+ public void testInterruptible_tryAcquireTimedN_fair() { testInterruptible(true, AcquireMethod.tryAcquireTimedN); }
+ public void testInterruptible(boolean fair, final AcquireMethod acquirer) {
+ final PublicSemaphore s = new PublicSemaphore(0, fair);
+ final Semaphore pleaseInterrupt = new Semaphore(0, fair);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ // Interrupt before acquire
+ Thread.currentThread().interrupt();
+ try {
+ acquirer.acquire(s);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+
+ // Interrupt during acquire
+ try {
+ acquirer.acquire(s);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+
+ // Interrupt before acquire(N)
+ Thread.currentThread().interrupt();
+ try {
+ acquirer.acquire(s, 3);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+
+ pleaseInterrupt.release();
+
+ // Interrupt during acquire(N)
+ try {
+ acquirer.acquire(s, 3);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ waitForQueuedThread(s, t);
+ t.interrupt();
+ await(pleaseInterrupt);
+ waitForQueuedThread(s, t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * acquireUninterruptibly(), acquireUninterruptibly(N) are
+ * uninterruptible
+ */
+ public void testUninterruptible_acquireUninterruptibly() { testUninterruptible(false, AcquireMethod.acquireUninterruptibly); }
+ public void testUninterruptible_acquireUninterruptibly_fair() { testUninterruptible(true, AcquireMethod.acquireUninterruptibly); }
+ public void testUninterruptible_acquireUninterruptiblyN() { testUninterruptible(false, AcquireMethod.acquireUninterruptiblyN); }
+ public void testUninterruptible_acquireUninterruptiblyN_fair() { testUninterruptible(true, AcquireMethod.acquireUninterruptiblyN); }
+ public void testUninterruptible(boolean fair, final AcquireMethod acquirer) {
+ final PublicSemaphore s = new PublicSemaphore(0, fair);
+ final Semaphore pleaseInterrupt = new Semaphore(-1, fair);
+
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ // Interrupt before acquire
+ pleaseInterrupt.release();
+ Thread.currentThread().interrupt();
+ acquirer.acquire(s);
+ assertTrue(Thread.interrupted());
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ // Interrupt during acquire
+ pleaseInterrupt.release();
+ acquirer.acquire(s);
+ assertTrue(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ waitForQueuedThread(s, t1);
+ waitForQueuedThread(s, t2);
+ t2.interrupt();
+
+ assertThreadStaysAlive(t1);
+ assertTrue(t2.isAlive());
+
+ s.release(2);
+
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * hasQueuedThreads reports whether there are waiting threads
+ */
+ public void testHasQueuedThreads() { testHasQueuedThreads(false); }
+ public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
+ public void testHasQueuedThreads(boolean fair) {
+ final PublicSemaphore lock = new PublicSemaphore(1, fair);
+ assertFalse(lock.hasQueuedThreads());
+ lock.acquireUninterruptibly();
+ Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
+ waitForQueuedThread(lock, t1);
+ assertTrue(lock.hasQueuedThreads());
+ Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
+ waitForQueuedThread(lock, t2);
+ assertTrue(lock.hasQueuedThreads());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertTrue(lock.hasQueuedThreads());
+ lock.release();
+ awaitTermination(t2);
+ assertFalse(lock.hasQueuedThreads());
+ }
+
+ /**
+ * getQueueLength reports number of waiting threads
+ */
+ public void testGetQueueLength() { testGetQueueLength(false); }
+ public void testGetQueueLength_fair() { testGetQueueLength(true); }
+ public void testGetQueueLength(boolean fair) {
+ final PublicSemaphore lock = new PublicSemaphore(1, fair);
+ assertEquals(0, lock.getQueueLength());
+ lock.acquireUninterruptibly();
+ Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
+ waitForQueuedThread(lock, t1);
+ assertEquals(1, lock.getQueueLength());
+ Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
+ waitForQueuedThread(lock, t2);
+ assertEquals(2, lock.getQueueLength());
+ t1.interrupt();
+ awaitTermination(t1);
+ assertEquals(1, lock.getQueueLength());
+ lock.release();
+ awaitTermination(t2);
+ assertEquals(0, lock.getQueueLength());
+ }
+
+ /**
+ * getQueuedThreads includes waiting threads
+ */
+ public void testGetQueuedThreads() { testGetQueuedThreads(false); }
+ public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
+ public void testGetQueuedThreads(boolean fair) {
+ final PublicSemaphore lock = new PublicSemaphore(1, fair);
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ lock.acquireUninterruptibly();
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
+ waitForQueuedThread(lock, t1);
+ assertTrue(lock.getQueuedThreads().contains(t1));
+ Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
+ waitForQueuedThread(lock, t2);
+ assertTrue(lock.getQueuedThreads().contains(t1));
+ assertTrue(lock.getQueuedThreads().contains(t2));
+ t1.interrupt();
+ awaitTermination(t1);
+ assertFalse(lock.getQueuedThreads().contains(t1));
+ assertTrue(lock.getQueuedThreads().contains(t2));
+ lock.release();
+ awaitTermination(t2);
+ assertTrue(lock.getQueuedThreads().isEmpty());
+ }
+
+ /**
+ * drainPermits reports and removes given number of permits
+ */
+ public void testDrainPermits() { testDrainPermits(false); }
+ public void testDrainPermits_fair() { testDrainPermits(true); }
+ public void testDrainPermits(boolean fair) {
+ Semaphore s = new Semaphore(0, fair);
+ assertEquals(0, s.availablePermits());
+ assertEquals(0, s.drainPermits());
+ s.release(10);
+ assertEquals(10, s.availablePermits());
+ assertEquals(10, s.drainPermits());
+ assertEquals(0, s.availablePermits());
+ assertEquals(0, s.drainPermits());
+ }
+
+ /**
+ * release(-N) throws IllegalArgumentException
+ */
+ public void testReleaseIAE() { testReleaseIAE(false); }
+ public void testReleaseIAE_fair() { testReleaseIAE(true); }
+ public void testReleaseIAE(boolean fair) {
+ Semaphore s = new Semaphore(10, fair);
+ try {
+ s.release(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * reducePermits(-N) throws IllegalArgumentException
+ */
+ public void testReducePermitsIAE() { testReducePermitsIAE(false); }
+ public void testReducePermitsIAE_fair() { testReducePermitsIAE(true); }
+ public void testReducePermitsIAE(boolean fair) {
+ PublicSemaphore s = new PublicSemaphore(10, fair);
+ try {
+ s.reducePermits(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * reducePermits reduces number of permits
+ */
+ public void testReducePermits() { testReducePermits(false); }
+ public void testReducePermits_fair() { testReducePermits(true); }
+ public void testReducePermits(boolean fair) {
+ PublicSemaphore s = new PublicSemaphore(10, fair);
+ assertEquals(10, s.availablePermits());
+ s.reducePermits(0);
+ assertEquals(10, s.availablePermits());
+ s.reducePermits(1);
+ assertEquals(9, s.availablePermits());
+ s.reducePermits(10);
+ assertEquals(-1, s.availablePermits());
+ s.reducePermits(10);
+ assertEquals(-11, s.availablePermits());
+ s.reducePermits(0);
+ assertEquals(-11, s.availablePermits());
+ }
+
+ /**
+ * a reserialized semaphore has same number of permits and
+ * fairness, but no queued threads
+ */
+ public void testSerialization() { testSerialization(false); }
+ public void testSerialization_fair() { testSerialization(true); }
+ public void testSerialization(boolean fair) {
+ try {
+ Semaphore s = new Semaphore(3, fair);
+ s.acquire();
+ s.acquire();
+ s.release();
+
+ Semaphore clone = serialClone(s);
+ assertEquals(fair, s.isFair());
+ assertEquals(fair, clone.isFair());
+ assertEquals(2, s.availablePermits());
+ assertEquals(2, clone.availablePermits());
+ clone.acquire();
+ clone.acquire();
+ clone.release();
+ assertEquals(2, s.availablePermits());
+ assertEquals(1, clone.availablePermits());
+
+ s = new Semaphore(0, fair);
+ Thread t = newStartedThread(new InterruptibleLockRunnable(s));
+ waitForQueuedThreads(s);
+ clone = serialClone(s);
+ assertEquals(fair, s.isFair());
+ assertEquals(fair, clone.isFair());
+ assertEquals(0, s.availablePermits());
+ assertEquals(0, clone.availablePermits());
+ assertTrue(s.hasQueuedThreads());
+ assertFalse(clone.hasQueuedThreads());
+ s.release();
+ awaitTermination(t);
+ assertFalse(s.hasQueuedThreads());
+ assertFalse(clone.hasQueuedThreads());
+ } catch (InterruptedException e) { threadUnexpectedException(e); }
+ }
+
+ /**
+ * tryAcquire(n) succeeds when sufficient permits, else fails
+ */
+ public void testTryAcquireNInSameThread() { testTryAcquireNInSameThread(false); }
+ public void testTryAcquireNInSameThread_fair() { testTryAcquireNInSameThread(true); }
+ public void testTryAcquireNInSameThread(boolean fair) {
+ Semaphore s = new Semaphore(2, fair);
+ assertEquals(2, s.availablePermits());
+ assertFalse(s.tryAcquire(3));
+ assertEquals(2, s.availablePermits());
+ assertTrue(s.tryAcquire(2));
+ assertEquals(0, s.availablePermits());
+ assertFalse(s.tryAcquire(1));
+ assertFalse(s.tryAcquire(2));
+ assertEquals(0, s.availablePermits());
+ }
+
+ /**
+ * acquire succeeds if permits available
+ */
+ public void testReleaseAcquireSameThread_acquire() { testReleaseAcquireSameThread(false, AcquireMethod.acquire); }
+ public void testReleaseAcquireSameThread_acquire_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquire); }
+ public void testReleaseAcquireSameThread_acquireN() { testReleaseAcquireSameThread(false, AcquireMethod.acquireN); }
+ public void testReleaseAcquireSameThread_acquireN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireN); }
+ public void testReleaseAcquireSameThread_acquireUninterruptibly() { testReleaseAcquireSameThread(false, AcquireMethod.acquireUninterruptibly); }
+ public void testReleaseAcquireSameThread_acquireUninterruptibly_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireUninterruptibly); }
+ public void testReleaseAcquireSameThread_acquireUninterruptiblyN() { testReleaseAcquireSameThread(false, AcquireMethod.acquireUninterruptibly); }
+ public void testReleaseAcquireSameThread_acquireUninterruptiblyN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireUninterruptibly); }
+ public void testReleaseAcquireSameThread_tryAcquire() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquire); }
+ public void testReleaseAcquireSameThread_tryAcquire_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquire); }
+ public void testReleaseAcquireSameThread_tryAcquireN() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireN); }
+ public void testReleaseAcquireSameThread_tryAcquireN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireN); }
+ public void testReleaseAcquireSameThread_tryAcquireTimed() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireTimed); }
+ public void testReleaseAcquireSameThread_tryAcquireTimed_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireTimed); }
+ public void testReleaseAcquireSameThread_tryAcquireTimedN() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireTimedN); }
+ public void testReleaseAcquireSameThread_tryAcquireTimedN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireTimedN); }
+ public void testReleaseAcquireSameThread(boolean fair,
+ final AcquireMethod acquirer) {
+ Semaphore s = new Semaphore(1, fair);
+ for (int i = 1; i < 6; i++) {
+ s.release(i);
+ assertEquals(1 + i, s.availablePermits());
+ try {
+ acquirer.acquire(s, i);
+ } catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertEquals(1, s.availablePermits());
+ }
+ }
+
+ /**
+ * release in one thread enables acquire in another thread
+ */
+ public void testReleaseAcquireDifferentThreads_acquire() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquire); }
+ public void testReleaseAcquireDifferentThreads_acquire_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquire); }
+ public void testReleaseAcquireDifferentThreads_acquireN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireN); }
+ public void testReleaseAcquireDifferentThreads_acquireN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireN); }
+ public void testReleaseAcquireDifferentThreads_acquireUninterruptibly() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireUninterruptibly); }
+ public void testReleaseAcquireDifferentThreads_acquireUninterruptibly_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireUninterruptibly); }
+ public void testReleaseAcquireDifferentThreads_acquireUninterruptiblyN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireUninterruptibly); }
+ public void testReleaseAcquireDifferentThreads_acquireUninterruptiblyN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireUninterruptibly); }
+ public void testReleaseAcquireDifferentThreads_tryAcquireTimed() { testReleaseAcquireDifferentThreads(false, AcquireMethod.tryAcquireTimed); }
+ public void testReleaseAcquireDifferentThreads_tryAcquireTimed_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.tryAcquireTimed); }
+ public void testReleaseAcquireDifferentThreads_tryAcquireTimedN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.tryAcquireTimedN); }
+ public void testReleaseAcquireDifferentThreads_tryAcquireTimedN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.tryAcquireTimedN); }
+ public void testReleaseAcquireDifferentThreads(boolean fair,
+ final AcquireMethod acquirer) {
+ final Semaphore s = new Semaphore(0, fair);
+ final int rounds = 4;
+ long startTime = System.nanoTime();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ for (int i = 0; i < rounds; i++) {
+ assertFalse(s.hasQueuedThreads());
+ if (i % 2 == 0)
+ acquirer.acquire(s);
+ else
+ acquirer.acquire(s, 3);
+ }}});
+
+ for (int i = 0; i < rounds; i++) {
+ while (! (s.availablePermits() == 0 && s.hasQueuedThreads()))
+ Thread.yield();
+ assertTrue(t.isAlive());
+ if (i % 2 == 0)
+ s.release();
+ else
+ s.release(3);
+ }
+ awaitTermination(t);
+ assertEquals(0, s.availablePermits());
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ }
+
+ /**
+ * fair locks are strictly FIFO
+ */
+ public void testFairLocksFifo() {
+ final PublicSemaphore s = new PublicSemaphore(1, true);
+ final CountDownLatch pleaseRelease = new CountDownLatch(1);
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ // Will block; permits are available, but not three
+ s.acquire(3);
+ }});
+
+ waitForQueuedThreads(s);
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ // Will fail, even though 1 permit is available
+ assertFalse(s.tryAcquire(0L, MILLISECONDS));
+ assertFalse(s.tryAcquire(1, 0L, MILLISECONDS));
+
+ // untimed tryAcquire will barge and succeed
+ assertTrue(s.tryAcquire());
+ s.release(2);
+ assertTrue(s.tryAcquire(2));
+ s.release();
+
+ pleaseRelease.countDown();
+ // Will queue up behind t1, even though 1 permit is available
+ s.acquire();
+ }});
+
+ await(pleaseRelease);
+ waitForQueuedThread(s, t2);
+ s.release(2);
+ awaitTermination(t1);
+ assertTrue(t2.isAlive());
+ s.release();
+ awaitTermination(t2);
+ }
+
+ /**
+ * toString indicates current number of permits
+ */
+ public void testToString() { testToString(false); }
+ public void testToString_fair() { testToString(true); }
+ public void testToString(boolean fair) {
+ PublicSemaphore s = new PublicSemaphore(0, fair);
+ assertTrue(s.toString().contains("Permits = 0"));
+ s.release();
+ assertTrue(s.toString().contains("Permits = 1"));
+ s.release(2);
+ assertTrue(s.toString().contains("Permits = 3"));
+ s.reducePermits(5);
+ assertTrue(s.toString().contains("Permits = -2"));
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/SynchronousQueueFairTest.java b/jsr166-tests/src/test/java/jsr166/SynchronousQueueFairTest.java
new file mode 100644
index 0000000..fb4634f
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/SynchronousQueueFairTest.java
@@ -0,0 +1,20 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+
+public class SynchronousQueueFairTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new SynchronousQueue(true);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/SynchronousQueueNotFairTest.java b/jsr166-tests/src/test/java/jsr166/SynchronousQueueNotFairTest.java
new file mode 100644
index 0000000..be15341
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/SynchronousQueueNotFairTest.java
@@ -0,0 +1,20 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+
+public class SynchronousQueueNotFairTest extends BlockingQueueTest {
+
+ protected BlockingQueue emptyCollection() {
+ return new SynchronousQueue(true);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java b/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java
new file mode 100644
index 0000000..bd030cf
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java
@@ -0,0 +1,589 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.SynchronousQueue;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class SynchronousQueueTest extends JSR166TestCase {
+
+ /**
+ * Any SynchronousQueue is both empty and full
+ */
+ public void testEmptyFull() { testEmptyFull(false); }
+ public void testEmptyFull_fair() { testEmptyFull(true); }
+ public void testEmptyFull(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertEquals(0, q.remainingCapacity());
+ assertFalse(q.offer(zero));
+ }
+
+ /**
+ * offer fails if no active taker
+ */
+ public void testOffer() { testOffer(false); }
+ public void testOffer_fair() { testOffer(true); }
+ public void testOffer(boolean fair) {
+ SynchronousQueue q = new SynchronousQueue(fair);
+ assertFalse(q.offer(one));
+ }
+
+ /**
+ * add throws IllegalStateException if no active taker
+ */
+ public void testAdd() { testAdd(false); }
+ public void testAdd_fair() { testAdd(true); }
+ public void testAdd(boolean fair) {
+ SynchronousQueue q = new SynchronousQueue(fair);
+ assertEquals(0, q.remainingCapacity());
+ try {
+ q.add(one);
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * addAll(this) throws IllegalArgumentException
+ */
+ public void testAddAll_self() { testAddAll_self(false); }
+ public void testAddAll_self_fair() { testAddAll_self(true); }
+ public void testAddAll_self(boolean fair) {
+ SynchronousQueue q = new SynchronousQueue(fair);
+ try {
+ q.addAll(q);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * addAll throws ISE if no active taker
+ */
+ public void testAddAll_ISE() { testAddAll_ISE(false); }
+ public void testAddAll_ISE_fair() { testAddAll_ISE(true); }
+ public void testAddAll_ISE(boolean fair) {
+ SynchronousQueue q = new SynchronousQueue(fair);
+ Integer[] ints = new Integer[1];
+ for (int i = 0; i < ints.length; i++)
+ ints[i] = i;
+ Collection<Integer> coll = Arrays.asList(ints);
+ try {
+ q.addAll(coll);
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * put blocks interruptibly if no active taker
+ */
+ public void testBlockingPut() { testBlockingPut(false); }
+ public void testBlockingPut_fair() { testBlockingPut(true); }
+ public void testBlockingPut(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ Thread.currentThread().interrupt();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * put blocks interruptibly waiting for take
+ */
+ public void testPutWithTake() { testPutWithTake(false); }
+ public void testPutWithTake_fair() { testPutWithTake(true); }
+ public void testPutWithTake(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ final CountDownLatch pleaseTake = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ pleaseTake.countDown();
+ q.put(one);
+
+ pleaseInterrupt.countDown();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseTake);
+ assertEquals(0, q.remainingCapacity());
+ try { assertSame(one, q.take()); }
+ catch (InterruptedException e) { threadUnexpectedException(e); }
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ assertEquals(0, q.remainingCapacity());
+ }
+
+ /**
+ * timed offer times out if elements not taken
+ */
+ public void testTimedOffer() { testTimedOffer(false); }
+ public void testTimedOffer_fair() { testTimedOffer(true); }
+ public void testTimedOffer(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ pleaseInterrupt.countDown();
+ try {
+ q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * poll return null if no active putter
+ */
+ public void testPoll() { testPoll(false); }
+ public void testPoll_fair() { testPoll(true); }
+ public void testPoll(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ assertNull(q.poll());
+ }
+
+ /**
+ * timed poll with zero timeout times out if no active putter
+ */
+ public void testTimedPoll0() { testTimedPoll0(false); }
+ public void testTimedPoll0_fair() { testTimedPoll0(true); }
+ public void testTimedPoll0(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ try { assertNull(q.poll(0, MILLISECONDS)); }
+ catch (InterruptedException e) { threadUnexpectedException(e); }
+ }
+
+ /**
+ * timed poll with nonzero timeout times out if no active putter
+ */
+ public void testTimedPoll() { testTimedPoll(false); }
+ public void testTimedPoll_fair() { testTimedPoll(true); }
+ public void testTimedPoll(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ long startTime = System.nanoTime();
+ try { assertNull(q.poll(timeoutMillis(), MILLISECONDS)); }
+ catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ }
+
+ /**
+ * timed poll before a delayed offer times out, returning null;
+ * after offer succeeds; on interruption throws
+ */
+ public void testTimedPollWithOffer() { testTimedPollWithOffer(false); }
+ public void testTimedPollWithOffer_fair() { testTimedPollWithOffer(true); }
+ public void testTimedPollWithOffer(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ final CountDownLatch pleaseOffer = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ pleaseOffer.countDown();
+ startTime = System.nanoTime();
+ assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
+
+ Thread.currentThread().interrupt();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseOffer);
+ long startTime = System.nanoTime();
+ try { assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); }
+ catch (InterruptedException e) { threadUnexpectedException(e); }
+ assertTrue(millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * peek() returns null if no active putter
+ */
+ public void testPeek() { testPeek(false); }
+ public void testPeek_fair() { testPeek(true); }
+ public void testPeek(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ assertNull(q.peek());
+ }
+
+ /**
+ * element() throws NoSuchElementException if no active putter
+ */
+ public void testElement() { testElement(false); }
+ public void testElement_fair() { testElement(true); }
+ public void testElement(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ try {
+ q.element();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * remove() throws NoSuchElementException if no active putter
+ */
+ public void testRemove() { testRemove(false); }
+ public void testRemove_fair() { testRemove(true); }
+ public void testRemove(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ try {
+ q.remove();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * contains returns false
+ */
+ public void testContains() { testContains(false); }
+ public void testContains_fair() { testContains(true); }
+ public void testContains(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ assertFalse(q.contains(zero));
+ }
+
+ /**
+ * clear ensures isEmpty
+ */
+ public void testClear() { testClear(false); }
+ public void testClear_fair() { testClear(true); }
+ public void testClear(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll returns false unless empty
+ */
+ public void testContainsAll() { testContainsAll(false); }
+ public void testContainsAll_fair() { testContainsAll(true); }
+ public void testContainsAll(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ Integer[] empty = new Integer[0];
+ assertTrue(q.containsAll(Arrays.asList(empty)));
+ Integer[] ints = new Integer[1]; ints[0] = zero;
+ assertFalse(q.containsAll(Arrays.asList(ints)));
+ }
+
+ /**
+ * retainAll returns false
+ */
+ public void testRetainAll() { testRetainAll(false); }
+ public void testRetainAll_fair() { testRetainAll(true); }
+ public void testRetainAll(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ Integer[] empty = new Integer[0];
+ assertFalse(q.retainAll(Arrays.asList(empty)));
+ Integer[] ints = new Integer[1]; ints[0] = zero;
+ assertFalse(q.retainAll(Arrays.asList(ints)));
+ }
+
+ /**
+ * removeAll returns false
+ */
+ public void testRemoveAll() { testRemoveAll(false); }
+ public void testRemoveAll_fair() { testRemoveAll(true); }
+ public void testRemoveAll(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ Integer[] empty = new Integer[0];
+ assertFalse(q.removeAll(Arrays.asList(empty)));
+ Integer[] ints = new Integer[1]; ints[0] = zero;
+ assertFalse(q.containsAll(Arrays.asList(ints)));
+ }
+
+ /**
+ * toArray is empty
+ */
+ public void testToArray() { testToArray(false); }
+ public void testToArray_fair() { testToArray(true); }
+ public void testToArray(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ Object[] o = q.toArray();
+ assertEquals(0, o.length);
+ }
+
+ /**
+ * toArray(Integer array) returns its argument with the first
+ * element (if present) nulled out
+ */
+ public void testToArray2() { testToArray2(false); }
+ public void testToArray2_fair() { testToArray2(true); }
+ public void testToArray2(boolean fair) {
+ final SynchronousQueue<Integer> q
+ = new SynchronousQueue<Integer>(fair);
+ Integer[] a;
+
+ a = new Integer[0];
+ assertSame(a, q.toArray(a));
+
+ a = new Integer[3];
+ Arrays.fill(a, 42);
+ assertSame(a, q.toArray(a));
+ assertNull(a[0]);
+ for (int i = 1; i < a.length; i++)
+ assertEquals(42, (int) a[i]);
+ }
+
+ /**
+ * toArray(null) throws NPE
+ */
+ public void testToArray_null() { testToArray_null(false); }
+ public void testToArray_null_fair() { testToArray_null(true); }
+ public void testToArray_null(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ try {
+ Object o[] = q.toArray(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * iterator does not traverse any elements
+ */
+ public void testIterator() { testIterator(false); }
+ public void testIterator_fair() { testIterator(true); }
+ public void testIterator(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ Iterator it = q.iterator();
+ assertFalse(it.hasNext());
+ try {
+ Object x = it.next();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+
+ /**
+ * iterator remove throws ISE
+ */
+ public void testIteratorRemove() { testIteratorRemove(false); }
+ public void testIteratorRemove_fair() { testIteratorRemove(true); }
+ public void testIteratorRemove(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ Iterator it = q.iterator();
+ try {
+ it.remove();
+ shouldThrow();
+ } catch (IllegalStateException success) {}
+ }
+
+ /**
+ * toString returns a non-null string
+ */
+ public void testToString() { testToString(false); }
+ public void testToString_fair() { testToString(true); }
+ public void testToString(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ String s = q.toString();
+ assertNotNull(s);
+ }
+
+ /**
+ * offer transfers elements across Executor tasks
+ */
+ public void testOfferInExecutor() { testOfferInExecutor(false); }
+ public void testOfferInExecutor_fair() { testOfferInExecutor(true); }
+ public void testOfferInExecutor(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(q.offer(one));
+ threadsStarted.await();
+ assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
+ assertEquals(0, q.remainingCapacity());
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ assertSame(one, q.take());
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * timed poll retrieves elements across Executor threads
+ */
+ public void testPollInExecutor() { testPollInExecutor(false); }
+ public void testPollInExecutor_fair() { testPollInExecutor(true); }
+ public void testPollInExecutor(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertNull(q.poll());
+ threadsStarted.await();
+ assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(q.isEmpty());
+ }});
+
+ executor.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.await();
+ q.put(one);
+ }});
+
+ joinPool(executor);
+ }
+
+ /**
+ * a deserialized serialized queue is usable
+ */
+ public void testSerialization() {
+ final SynchronousQueue x = new SynchronousQueue();
+ final SynchronousQueue y = new SynchronousQueue(false);
+ final SynchronousQueue z = new SynchronousQueue(true);
+ assertSerialEquals(x, y);
+ assertNotSerialEquals(x, z);
+ SynchronousQueue[] qs = { x, y, z };
+ for (SynchronousQueue q : qs) {
+ SynchronousQueue clone = serialClone(q);
+ assertNotSame(q, clone);
+ assertSerialEquals(q, clone);
+ assertTrue(clone.isEmpty());
+ assertEquals(0, clone.size());
+ assertEquals(0, clone.remainingCapacity());
+ assertFalse(clone.offer(zero));
+ }
+ }
+
+ /**
+ * drainTo(c) of empty queue doesn't transfer elements
+ */
+ public void testDrainTo() { testDrainTo(false); }
+ public void testDrainTo_fair() { testDrainTo(true); }
+ public void testDrainTo(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ ArrayList l = new ArrayList();
+ q.drainTo(l);
+ assertEquals(0, q.size());
+ assertEquals(0, l.size());
+ }
+
+ /**
+ * drainTo empties queue, unblocking a waiting put.
+ */
+ public void testDrainToWithActivePut() { testDrainToWithActivePut(false); }
+ public void testDrainToWithActivePut_fair() { testDrainToWithActivePut(true); }
+ public void testDrainToWithActivePut(boolean fair) {
+ final SynchronousQueue q = new SynchronousQueue(fair);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(one);
+ }});
+
+ ArrayList l = new ArrayList();
+ long startTime = System.nanoTime();
+ while (l.isEmpty()) {
+ q.drainTo(l);
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ assertTrue(l.size() == 1);
+ assertSame(one, l.get(0));
+ awaitTermination(t);
+ }
+
+ /**
+ * drainTo(c, n) empties up to n elements of queue into c
+ */
+ public void testDrainToN() throws InterruptedException {
+ final SynchronousQueue q = new SynchronousQueue();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(one);
+ }});
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ q.put(two);
+ }});
+
+ ArrayList l = new ArrayList();
+ delay(SHORT_DELAY_MS);
+ q.drainTo(l, 1);
+ assertEquals(1, l.size());
+ q.drainTo(l, 1);
+ assertEquals(2, l.size());
+ assertTrue(l.contains(one));
+ assertTrue(l.contains(two));
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/SystemTest.java b/jsr166-tests/src/test/java/jsr166/SystemTest.java
new file mode 100644
index 0000000..32caec2
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/SystemTest.java
@@ -0,0 +1,63 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+
+public class SystemTest extends JSR166TestCase {
+
+ /**
+ * Worst case rounding for millisecs; set for 60 cycle millis clock.
+ * This value might need to be changed on JVMs with coarser
+ * System.currentTimeMillis clocks.
+ */
+ static final long MILLIS_ROUND = 17;
+
+ /**
+ * Nanos between readings of millis is no longer than millis (plus
+ * possible rounding).
+ * This shows only that nano timing not (much) worse than milli.
+ */
+ public void testNanoTime1() throws InterruptedException {
+ long m1 = System.currentTimeMillis();
+ Thread.sleep(1);
+ long n1 = System.nanoTime();
+ Thread.sleep(SHORT_DELAY_MS);
+ long n2 = System.nanoTime();
+ Thread.sleep(1);
+ long m2 = System.currentTimeMillis();
+ long millis = m2 - m1;
+ long nanos = n2 - n1;
+ assertTrue(nanos >= 0);
+ long nanosAsMillis = nanos / 1000000;
+ assertTrue(nanosAsMillis <= millis + MILLIS_ROUND);
+ }
+
+ /**
+ * Millis between readings of nanos is less than nanos, adjusting
+ * for rounding.
+ * This shows only that nano timing not (much) worse than milli.
+ */
+ public void testNanoTime2() throws InterruptedException {
+ long n1 = System.nanoTime();
+ Thread.sleep(1);
+ long m1 = System.currentTimeMillis();
+ Thread.sleep(SHORT_DELAY_MS);
+ long m2 = System.currentTimeMillis();
+ Thread.sleep(1);
+ long n2 = System.nanoTime();
+ long millis = m2 - m1;
+ long nanos = n2 - n1;
+
+ assertTrue(nanos >= 0);
+ long nanosAsMillis = nanos / 1000000;
+ assertTrue(millis <= nanosAsMillis + MILLIS_ROUND);
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java b/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java
new file mode 100644
index 0000000..665a2b7
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java
@@ -0,0 +1,290 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class ThreadLocalRandomTest extends JSR166TestCase {
+
+ /*
+ * Testing coverage notes:
+ *
+ * We don't test randomness properties, but only that repeated
+ * calls, up to NCALLS tries, produce at least one different
+ * result. For bounded versions, we sample various intervals
+ * across multiples of primes.
+ */
+
+ //
+ static final int NCALLS = 10000;
+
+ // max sampled int bound
+ static final int MAX_INT_BOUND = (1 << 28);
+
+ // Max sampled long bound
+ static final long MAX_LONG_BOUND = (1L << 42);
+
+ /**
+ * setSeed throws UnsupportedOperationException
+ */
+ public void testSetSeed() {
+ try {
+ ThreadLocalRandom.current().setSeed(17);
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ }
+
+ /**
+ * Repeated calls to nextInt produce at least one different result
+ */
+ public void testNextInt() {
+ int f = ThreadLocalRandom.current().nextInt();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextInt() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextLong produce at least one different result
+ */
+ public void testNextLong() {
+ long f = ThreadLocalRandom.current().nextLong();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextLong() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextBoolean produce at least one different result
+ */
+ public void testNextBoolean() {
+ boolean f = ThreadLocalRandom.current().nextBoolean();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextBoolean() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextFloat produce at least one different result
+ */
+ public void testNextFloat() {
+ float f = ThreadLocalRandom.current().nextFloat();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextFloat() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextDouble produce at least one different result
+ */
+ public void testNextDouble() {
+ double f = ThreadLocalRandom.current().nextDouble();
+ double i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextGaussian produce at least one different result
+ */
+ public void testNextGaussian() {
+ double f = ThreadLocalRandom.current().nextGaussian();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextGaussian() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * nextInt(negative) throws IllegalArgumentException;
+ */
+ public void testNextIntBoundedNeg() {
+ try {
+ int f = ThreadLocalRandom.current().nextInt(-17);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * nextInt(least >= bound) throws IllegalArgumentException;
+ */
+ public void testNextIntBadBounds() {
+ try {
+ int f = ThreadLocalRandom.current().nextInt(17, 2);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * nextInt(bound) returns 0 <= value < bound;
+ * repeated calls produce at least one different result
+ */
+ public void testNextIntBounded() {
+ // sample bound space across prime number increments
+ for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+ int f = ThreadLocalRandom.current().nextInt(bound);
+ assertTrue(0 <= f && f < bound);
+ int i = 0;
+ int j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextInt(bound)) == f) {
+ assertTrue(0 <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * nextInt(least, bound) returns least <= value < bound;
+ * repeated calls produce at least one different result
+ */
+ public void testNextIntBounded2() {
+ for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
+ for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
+ int f = ThreadLocalRandom.current().nextInt(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ int j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextInt(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * nextLong(negative) throws IllegalArgumentException;
+ */
+ public void testNextLongBoundedNeg() {
+ try {
+ long f = ThreadLocalRandom.current().nextLong(-17);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * nextLong(least >= bound) throws IllegalArgumentException;
+ */
+ public void testNextLongBadBounds() {
+ try {
+ long f = ThreadLocalRandom.current().nextLong(17, 2);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * nextLong(bound) returns 0 <= value < bound;
+ * repeated calls produce at least one different result
+ */
+ public void testNextLongBounded() {
+ for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
+ long f = ThreadLocalRandom.current().nextLong(bound);
+ assertTrue(0 <= f && f < bound);
+ int i = 0;
+ long j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextLong(bound)) == f) {
+ assertTrue(0 <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * nextLong(least, bound) returns least <= value < bound;
+ * repeated calls produce at least one different result
+ */
+ public void testNextLongBounded2() {
+ for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
+ for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+ long f = ThreadLocalRandom.current().nextLong(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ long j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextLong(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * nextDouble(least, bound) returns least <= value < bound;
+ * repeated calls produce at least one different result
+ */
+ public void testNextDoubleBounded2() {
+ for (double least = 0.0001; least < 1.0e20; least *= 8) {
+ for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
+ double f = ThreadLocalRandom.current().nextDouble(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ double j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextDouble(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * Different threads produce different pseudo-random sequences
+ */
+ public void testDifferentSequences() {
+ // Don't use main thread's ThreadLocalRandom - it is likely to
+ // be polluted by previous tests.
+ final AtomicReference<ThreadLocalRandom> threadLocalRandom =
+ new AtomicReference<ThreadLocalRandom>();
+ final AtomicLong rand = new AtomicLong();
+
+ long firstRand = 0;
+ ThreadLocalRandom firstThreadLocalRandom = null;
+
+ final CheckedRunnable getRandomState = new CheckedRunnable() {
+ public void realRun() {
+ ThreadLocalRandom current = ThreadLocalRandom.current();
+ assertSame(current, ThreadLocalRandom.current());
+ // test bug: the following is not guaranteed and not true in JDK8
+ // assertNotSame(current, threadLocalRandom.get());
+ rand.set(current.nextLong());
+ threadLocalRandom.set(current);
+ }};
+
+ Thread first = newStartedThread(getRandomState);
+ awaitTermination(first);
+ firstRand = rand.get();
+ firstThreadLocalRandom = threadLocalRandom.get();
+
+ for (int i = 0; i < NCALLS; i++) {
+ Thread t = newStartedThread(getRandomState);
+ awaitTermination(t);
+ if (firstRand != rand.get())
+ return;
+ }
+ fail("all threads generate the same pseudo-random sequence");
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java b/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java
new file mode 100644
index 0000000..885c2b2
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java
@@ -0,0 +1,96 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.Semaphore;
+
+public class ThreadLocalTest extends JSR166TestCase {
+
+ static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
+ public Integer initialValue() {
+ return one;
+ }
+ };
+
+ static InheritableThreadLocal<Integer> itl =
+ new InheritableThreadLocal<Integer>() {
+ protected Integer initialValue() {
+ return zero;
+ }
+
+ protected Integer childValue(Integer parentValue) {
+ return new Integer(parentValue.intValue() + 1);
+ }
+ };
+
+ /**
+ * remove causes next access to return initial value
+ */
+ public void testRemove() {
+ assertSame(tl.get(), one);
+ tl.set(two);
+ assertSame(tl.get(), two);
+ tl.remove();
+ assertSame(tl.get(), one);
+ }
+
+ /**
+ * remove in InheritableThreadLocal causes next access to return
+ * initial value
+ */
+ public void testRemoveITL() {
+ assertSame(itl.get(), zero);
+ itl.set(two);
+ assertSame(itl.get(), two);
+ itl.remove();
+ assertSame(itl.get(), zero);
+ }
+
+ private class ITLThread extends Thread {
+ final int[] x;
+ ITLThread(int[] array) { x = array; }
+ public void run() {
+ Thread child = null;
+ if (itl.get().intValue() < x.length - 1) {
+ child = new ITLThread(x);
+ child.start();
+ }
+ Thread.yield();
+
+ int threadId = itl.get().intValue();
+ for (int j = 0; j < threadId; j++) {
+ x[threadId]++;
+ Thread.yield();
+ }
+
+ if (child != null) { // Wait for child (if any)
+ try {
+ child.join();
+ } catch (InterruptedException e) {
+ threadUnexpectedException(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * InheritableThreadLocal propagates generic values.
+ */
+ public void testGenericITL() throws InterruptedException {
+ final int threadCount = 10;
+ final int x[] = new int[threadCount];
+ Thread progenitor = new ITLThread(x);
+ progenitor.start();
+ progenitor.join();
+ for (int i = 0; i < threadCount; i++) {
+ assertEquals(i, x[i]);
+ }
+ }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java
new file mode 100644
index 0000000..f16f422
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java
@@ -0,0 +1,1769 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.*;
+
+public class ThreadPoolExecutorSubclassTest extends JSR166TestCase {
+
+ static class CustomTask<V> implements RunnableFuture<V> {
+ final Callable<V> callable;
+ final ReentrantLock lock = new ReentrantLock();
+ final Condition cond = lock.newCondition();
+ boolean done;
+ boolean cancelled;
+ V result;
+ Thread thread;
+ Exception exception;
+ CustomTask(Callable<V> c) {
+ if (c == null) throw new NullPointerException();
+ callable = c;
+ }
+ CustomTask(final Runnable r, final V res) {
+ if (r == null) throw new NullPointerException();
+ callable = new Callable<V>() {
+ public V call() throws Exception { r.run(); return res; }};
+ }
+ public boolean isDone() {
+ lock.lock(); try { return done; } finally { lock.unlock() ; }
+ }
+ public boolean isCancelled() {
+ lock.lock(); try { return cancelled; } finally { lock.unlock() ; }
+ }
+ public boolean cancel(boolean mayInterrupt) {
+ lock.lock();
+ try {
+ if (!done) {
+ cancelled = true;
+ done = true;
+ if (mayInterrupt && thread != null)
+ thread.interrupt();
+ return true;
+ }
+ return false;
+ }
+ finally { lock.unlock() ; }
+ }
+ public void run() {
+ lock.lock();
+ try {
+ if (done)
+ return;
+ thread = Thread.currentThread();
+ }
+ finally { lock.unlock() ; }
+ V v = null;
+ Exception e = null;
+ try {
+ v = callable.call();
+ }
+ catch (Exception ex) {
+ e = ex;
+ }
+ lock.lock();
+ try {
+ result = v;
+ exception = e;
+ done = true;
+ thread = null;
+ cond.signalAll();
+ }
+ finally { lock.unlock(); }
+ }
+ public V get() throws InterruptedException, ExecutionException {
+ lock.lock();
+ try {
+ while (!done)
+ cond.await();
+ if (exception != null)
+ throw new ExecutionException(exception);
+ return result;
+ }
+ finally { lock.unlock(); }
+ }
+ public V get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ long nanos = unit.toNanos(timeout);
+ lock.lock();
+ try {
+ for (;;) {
+ if (done) break;
+ if (nanos < 0)
+ throw new TimeoutException();
+ nanos = cond.awaitNanos(nanos);
+ }
+ if (exception != null)
+ throw new ExecutionException(exception);
+ return result;
+ }
+ finally { lock.unlock(); }
+ }
+ }
+
+ static class CustomTPE extends ThreadPoolExecutor {
+ protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
+ return new CustomTask<V>(c);
+ }
+ protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
+ return new CustomTask<V>(r, v);
+ }
+
+ CustomTPE(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
+ workQueue);
+ }
+ CustomTPE(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue,
+ ThreadFactory threadFactory) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+ threadFactory);
+ }
+
+ CustomTPE(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue,
+ RejectedExecutionHandler handler) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+ handler);
+ }
+ CustomTPE(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue,
+ ThreadFactory threadFactory,
+ RejectedExecutionHandler handler) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
+ workQueue, threadFactory, handler);
+ }
+
+ final CountDownLatch beforeCalled = new CountDownLatch(1);
+ final CountDownLatch afterCalled = new CountDownLatch(1);
+ final CountDownLatch terminatedCalled = new CountDownLatch(1);
+
+ public CustomTPE() {
+ super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
+ }
+ protected void beforeExecute(Thread t, Runnable r) {
+ beforeCalled.countDown();
+ }
+ protected void afterExecute(Runnable r, Throwable t) {
+ afterCalled.countDown();
+ }
+ protected void terminated() {
+ terminatedCalled.countDown();
+ }
+
+ public boolean beforeCalled() {
+ return beforeCalled.getCount() == 0;
+ }
+ public boolean afterCalled() {
+ return afterCalled.getCount() == 0;
+ }
+ public boolean terminatedCalled() {
+ return terminatedCalled.getCount() == 0;
+ }
+ }
+
+ static class FailingThreadFactory implements ThreadFactory {
+ int calls = 0;
+ public Thread newThread(Runnable r) {
+ if (++calls > 1) return null;
+ return new Thread(r);
+ }
+ }
+
+ /**
+ * execute successfully executes a runnable
+ */
+ public void testExecute() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch done = new CountDownLatch(1);
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ }};
+ try {
+ p.execute(task);
+ assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getActiveCount increases but doesn't overestimate, when a
+ * thread becomes active
+ */
+ public void testGetActiveCount() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new CustomTPE(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getActiveCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getActiveCount());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getActiveCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * prestartCoreThread starts a thread if under corePoolSize, else doesn't
+ */
+ public void testPrestartCoreThread() {
+ ThreadPoolExecutor p = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(0, p.getPoolSize());
+ assertTrue(p.prestartCoreThread());
+ assertEquals(1, p.getPoolSize());
+ assertTrue(p.prestartCoreThread());
+ assertEquals(2, p.getPoolSize());
+ assertFalse(p.prestartCoreThread());
+ assertEquals(2, p.getPoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * prestartAllCoreThreads starts all corePoolSize threads
+ */
+ public void testPrestartAllCoreThreads() {
+ ThreadPoolExecutor p = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(0, p.getPoolSize());
+ p.prestartAllCoreThreads();
+ assertEquals(2, p.getPoolSize());
+ p.prestartAllCoreThreads();
+ assertEquals(2, p.getPoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * getCompletedTaskCount increases, but doesn't overestimate,
+ * when tasks complete
+ */
+ public void testGetCompletedTaskCount() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new CustomTPE(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch threadProceed = new CountDownLatch(1);
+ final CountDownLatch threadDone = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getCompletedTaskCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(0, p.getCompletedTaskCount());
+ threadProceed.await();
+ threadDone.countDown();
+ }});
+ await(threadStarted);
+ assertEquals(0, p.getCompletedTaskCount());
+ threadProceed.countDown();
+ threadDone.await();
+ long startTime = System.nanoTime();
+ while (p.getCompletedTaskCount() != 1) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getCorePoolSize returns size given in constructor if not otherwise set
+ */
+ public void testGetCorePoolSize() {
+ ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(1, p.getCorePoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * getKeepAliveTime returns value given in constructor if not otherwise set
+ */
+ public void testGetKeepAliveTime() {
+ ThreadPoolExecutor p = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(1, p.getKeepAliveTime(TimeUnit.SECONDS));
+ joinPool(p);
+ }
+
+ /**
+ * getThreadFactory returns factory in constructor if not set
+ */
+ public void testGetThreadFactory() {
+ ThreadFactory tf = new SimpleThreadFactory();
+ ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), tf, new NoOpREHandler());
+ assertSame(tf, p.getThreadFactory());
+ joinPool(p);
+ }
+
+ /**
+ * setThreadFactory sets the thread factory returned by getThreadFactory
+ */
+ public void testSetThreadFactory() {
+ ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ ThreadFactory tf = new SimpleThreadFactory();
+ p.setThreadFactory(tf);
+ assertSame(tf, p.getThreadFactory());
+ joinPool(p);
+ }
+
+ /**
+ * setThreadFactory(null) throws NPE
+ */
+ public void testSetThreadFactoryNull() {
+ ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setThreadFactory(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getRejectedExecutionHandler returns handler in constructor if not set
+ */
+ public void testGetRejectedExecutionHandler() {
+ RejectedExecutionHandler h = new NoOpREHandler();
+ ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), h);
+ assertSame(h, p.getRejectedExecutionHandler());
+ joinPool(p);
+ }
+
+ /**
+ * setRejectedExecutionHandler sets the handler returned by
+ * getRejectedExecutionHandler
+ */
+ public void testSetRejectedExecutionHandler() {
+ ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ RejectedExecutionHandler h = new NoOpREHandler();
+ p.setRejectedExecutionHandler(h);
+ assertSame(h, p.getRejectedExecutionHandler());
+ joinPool(p);
+ }
+
+ /**
+ * setRejectedExecutionHandler(null) throws NPE
+ */
+ public void testSetRejectedExecutionHandlerNull() {
+ ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setRejectedExecutionHandler(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getLargestPoolSize increases, but doesn't overestimate, when
+ * multiple threads active
+ */
+ public void testGetLargestPoolSize() throws InterruptedException {
+ final int THREADS = 3;
+ final ThreadPoolExecutor p =
+ new CustomTPE(THREADS, THREADS,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getLargestPoolSize());
+ for (int i = 0; i < THREADS; i++)
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.countDown();
+ done.await();
+ assertEquals(THREADS, p.getLargestPoolSize());
+ }});
+ assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(THREADS, p.getLargestPoolSize());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ assertEquals(THREADS, p.getLargestPoolSize());
+ }
+ }
+
+ /**
+ * getMaximumPoolSize returns value given in constructor if not
+ * otherwise set
+ */
+ public void testGetMaximumPoolSize() {
+ ThreadPoolExecutor p = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(2, p.getMaximumPoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * getPoolSize increases, but doesn't overestimate, when threads
+ * become active
+ */
+ public void testGetPoolSize() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getPoolSize());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getPoolSize());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getPoolSize());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getTaskCount increases, but doesn't overestimate, when tasks submitted
+ */
+ public void testGetTaskCount() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getTaskCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getTaskCount());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getTaskCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * isShutdown is false before shutdown, true after
+ */
+ public void testIsShutdown() {
+
+ ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ assertFalse(p.isShutdown());
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertTrue(p.isShutdown());
+ joinPool(p);
+ }
+
+ /**
+ * isTerminated is false before termination, true after
+ */
+ public void testIsTerminated() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertFalse(p.isTerminating());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(p.isTerminating());
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
+ done.countDown();
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ assertFalse(p.isTerminating());
+ }
+
+ /**
+ * isTerminating is not true when running or when terminated
+ */
+ public void testIsTerminating() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertFalse(p.isTerminating());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(p.isTerminating());
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
+ done.countDown();
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ assertFalse(p.isTerminating());
+ }
+
+ /**
+ * getQueue returns the work queue, which contains queued tasks
+ */
+ public void testGetQueue() throws InterruptedException {
+ final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
+ final ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ q);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ FutureTask[] tasks = new FutureTask[5];
+ for (int i = 0; i < tasks.length; i++) {
+ Callable task = new CheckedCallable<Boolean>() {
+ public Boolean realCall() throws InterruptedException {
+ threadStarted.countDown();
+ assertSame(q, p.getQueue());
+ done.await();
+ return Boolean.TRUE;
+ }};
+ tasks[i] = new FutureTask(task);
+ p.execute(tasks[i]);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertSame(q, p.getQueue());
+ assertFalse(q.contains(tasks[0]));
+ assertTrue(q.contains(tasks[tasks.length - 1]));
+ assertEquals(tasks.length - 1, q.size());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * remove(task) removes queued task, and fails to remove active task
+ */
+ public void testRemove() throws InterruptedException {
+ BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
+ final ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ q);
+ Runnable[] tasks = new Runnable[6];
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ for (int i = 0; i < tasks.length; i++) {
+ tasks[i] = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ }};
+ p.execute(tasks[i]);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.remove(tasks[0]));
+ assertTrue(q.contains(tasks[4]));
+ assertTrue(q.contains(tasks[3]));
+ assertTrue(p.remove(tasks[4]));
+ assertFalse(p.remove(tasks[4]));
+ assertFalse(q.contains(tasks[4]));
+ assertTrue(q.contains(tasks[3]));
+ assertTrue(p.remove(tasks[3]));
+ assertFalse(q.contains(tasks[3]));
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * purge removes cancelled tasks from the queue
+ */
+ public void testPurge() throws InterruptedException {
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
+ final ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ q);
+ FutureTask[] tasks = new FutureTask[5];
+ try {
+ for (int i = 0; i < tasks.length; i++) {
+ Callable task = new CheckedCallable<Boolean>() {
+ public Boolean realCall() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ return Boolean.TRUE;
+ }};
+ tasks[i] = new FutureTask(task);
+ p.execute(tasks[i]);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(tasks.length, p.getTaskCount());
+ assertEquals(tasks.length - 1, q.size());
+ assertEquals(1L, p.getActiveCount());
+ assertEquals(0L, p.getCompletedTaskCount());
+ tasks[4].cancel(true);
+ tasks[3].cancel(false);
+ p.purge();
+ assertEquals(tasks.length - 3, q.size());
+ assertEquals(tasks.length - 2, p.getTaskCount());
+ p.purge(); // Nothing to do
+ assertEquals(tasks.length - 3, q.size());
+ assertEquals(tasks.length - 2, p.getTaskCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * shutdownNow returns a list containing tasks that were not run
+ */
+ public void testShutdownNow() {
+ ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List l;
+ try {
+ for (int i = 0; i < 5; i++)
+ p.execute(new MediumPossiblyInterruptedRunnable());
+ }
+ finally {
+ try {
+ l = p.shutdownNow();
+ } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.isShutdown());
+ assertTrue(l.size() <= 4);
+ }
+
+ // Exception Tests
+
+ /**
+ * Constructor throws if corePoolSize argument is less than zero
+ */
+ public void testConstructor1() {
+ try {
+ new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is less than zero
+ */
+ public void testConstructor2() {
+ try {
+ new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is equal to zero
+ */
+ public void testConstructor3() {
+ try {
+ new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if keepAliveTime is less than zero
+ */
+ public void testConstructor4() {
+ try {
+ new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize is greater than the maximumPoolSize
+ */
+ public void testConstructor5() {
+ try {
+ new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if workQueue is set to null
+ */
+ public void testConstructorNullPointerException() {
+ try {
+ new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize argument is less than zero
+ */
+ public void testConstructor6() {
+ try {
+ new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is less than zero
+ */
+ public void testConstructor7() {
+ try {
+ new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is equal to zero
+ */
+ public void testConstructor8() {
+ try {
+ new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if keepAliveTime is less than zero
+ */
+ public void testConstructor9() {
+ try {
+ new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize is greater than the maximumPoolSize
+ */
+ public void testConstructor10() {
+ try {
+ new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if workQueue is set to null
+ */
+ public void testConstructorNullPointerException2() {
+ try {
+ new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if threadFactory is set to null
+ */
+ public void testConstructorNullPointerException3() {
+ try {
+ ThreadFactory f = null;
+ new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize argument is less than zero
+ */
+ public void testConstructor11() {
+ try {
+ new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is less than zero
+ */
+ public void testConstructor12() {
+ try {
+ new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is equal to zero
+ */
+ public void testConstructor13() {
+ try {
+ new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if keepAliveTime is less than zero
+ */
+ public void testConstructor14() {
+ try {
+ new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize is greater than the maximumPoolSize
+ */
+ public void testConstructor15() {
+ try {
+ new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if workQueue is set to null
+ */
+ public void testConstructorNullPointerException4() {
+ try {
+ new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new NoOpREHandler());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if handler is set to null
+ */
+ public void testConstructorNullPointerException5() {
+ try {
+ RejectedExecutionHandler r = null;
+ new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),r);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize argument is less than zero
+ */
+ public void testConstructor16() {
+ try {
+ new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is less than zero
+ */
+ public void testConstructor17() {
+ try {
+ new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is equal to zero
+ */
+ public void testConstructor18() {
+ try {
+ new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if keepAliveTime is less than zero
+ */
+ public void testConstructor19() {
+ try {
+ new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize is greater than the maximumPoolSize
+ */
+ public void testConstructor20() {
+ try {
+ new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if workQueue is null
+ */
+ public void testConstructorNullPointerException6() {
+ try {
+ new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory(),new NoOpREHandler());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if handler is null
+ */
+ public void testConstructorNullPointerException7() {
+ try {
+ RejectedExecutionHandler r = null;
+ new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),r);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if ThreadFactory is null
+ */
+ public void testConstructorNullPointerException8() {
+ try {
+ new CustomTPE(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ (ThreadFactory) null,
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * execute throws RejectedExecutionException if saturated.
+ */
+ public void testSaturatedExecute() {
+ ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1));
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ done.await();
+ }};
+ for (int i = 0; i < 2; ++i)
+ p.execute(task);
+ for (int i = 0; i < 2; ++i) {
+ try {
+ p.execute(task);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+ assertTrue(p.getTaskCount() <= 2);
+ }
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * executor using CallerRunsPolicy runs task if saturated.
+ */
+ public void testSaturatedExecute2() {
+ RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
+ ThreadPoolExecutor p = new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1),
+ h);
+ try {
+ TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+ for (int i = 0; i < tasks.length; ++i)
+ tasks[i] = new TrackedNoOpRunnable();
+ TrackedLongRunnable mr = new TrackedLongRunnable();
+ p.execute(mr);
+ for (int i = 0; i < tasks.length; ++i)
+ p.execute(tasks[i]);
+ for (int i = 1; i < tasks.length; ++i)
+ assertTrue(tasks[i].done);
+ try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * executor using DiscardPolicy drops task if saturated.
+ */
+ public void testSaturatedExecute3() {
+ RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
+ ThreadPoolExecutor p =
+ new CustomTPE(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1),
+ h);
+ try {
+ TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+ for (int i = 0; i < tasks.length; ++i)
+ tasks[i] = new TrackedNoOpRunnable();
+ p.execute(new TrackedLongRunnable());
+ for (TrackedNoOpRunnable task : tasks)
+ p.execute(task);
+ for (TrackedNoOpRunnable task : tasks)
+ assertFalse(task.done);
+ try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * executor using DiscardOldestPolicy drops oldest task if saturated.
+ */
+ public void testSaturatedExecute4() {
+ RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
+ ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+ try {
+ p.execute(new TrackedLongRunnable());
+ TrackedLongRunnable r2 = new TrackedLongRunnable();
+ p.execute(r2);
+ assertTrue(p.getQueue().contains(r2));
+ TrackedNoOpRunnable r3 = new TrackedNoOpRunnable();
+ p.execute(r3);
+ assertFalse(p.getQueue().contains(r2));
+ assertTrue(p.getQueue().contains(r3));
+ try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute throws RejectedExecutionException if shutdown
+ */
+ public void testRejectedExecutionExceptionOnShutdown() {
+ ThreadPoolExecutor p =
+ new CustomTPE(1,1,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(1));
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ try {
+ p.execute(new NoOpRunnable());
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+
+ joinPool(p);
+ }
+
+ /**
+ * execute using CallerRunsPolicy drops task on shutdown
+ */
+ public void testCallerRunsOnShutdown() {
+ RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
+ ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ try {
+ TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+ p.execute(r);
+ assertFalse(r.done);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute using DiscardPolicy drops task on shutdown
+ */
+ public void testDiscardOnShutdown() {
+ RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
+ ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ try {
+ TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+ p.execute(r);
+ assertFalse(r.done);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute using DiscardOldestPolicy drops task on shutdown
+ */
+ public void testDiscardOldestOnShutdown() {
+ RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
+ ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ try {
+ TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+ p.execute(r);
+ assertFalse(r.done);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute(null) throws NPE
+ */
+ public void testExecuteNull() {
+ ThreadPoolExecutor p = null;
+ try {
+ p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+ p.execute(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+
+ joinPool(p);
+ }
+
+ /**
+ * setCorePoolSize of negative value throws IllegalArgumentException
+ */
+ public void testCorePoolSizeIllegalArgumentException() {
+ ThreadPoolExecutor p =
+ new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setCorePoolSize(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ joinPool(p);
+ }
+
+ /**
+ * setMaximumPoolSize(int) throws IllegalArgumentException
+ * if given a value less the core pool size
+ */
+ public void testMaximumPoolSizeIllegalArgumentException() {
+ ThreadPoolExecutor p =
+ new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setMaximumPoolSize(1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ joinPool(p);
+ }
+
+ /**
+ * setMaximumPoolSize throws IllegalArgumentException
+ * if given a negative value
+ */
+ public void testMaximumPoolSizeIllegalArgumentException2() {
+ ThreadPoolExecutor p =
+ new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setMaximumPoolSize(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ joinPool(p);
+ }
+
+ /**
+ * setKeepAliveTime throws IllegalArgumentException
+ * when given a negative value
+ */
+ public void testKeepAliveTimeIllegalArgumentException() {
+ ThreadPoolExecutor p =
+ new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+
+ try {
+ p.setKeepAliveTime(-1,MILLISECONDS);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ joinPool(p);
+ }
+
+ /**
+ * terminated() is called on termination
+ */
+ public void testTerminated() {
+ CustomTPE p = new CustomTPE();
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertTrue(p.terminatedCalled());
+ joinPool(p);
+ }
+
+ /**
+ * beforeExecute and afterExecute are called when executing task
+ */
+ public void testBeforeAfter() throws InterruptedException {
+ CustomTPE p = new CustomTPE();
+ try {
+ final CountDownLatch done = new CountDownLatch(1);
+ final CheckedRunnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ }};
+ p.execute(task);
+ await(p.afterCalled);
+ assertEquals(0, done.getCount());
+ assertTrue(p.afterCalled());
+ assertTrue(p.beforeCalled());
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * completed submit of callable returns result
+ */
+ public void testSubmitCallable() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ Future<String> future = e.submit(new StringTask());
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * completed submit of runnable returns successfully
+ */
+ public void testSubmitRunnable() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ Future<?> future = e.submit(new NoOpRunnable());
+ future.get();
+ assertTrue(future.isDone());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * completed submit of (runnable, result) returns result
+ */
+ public void testSubmitRunnable2() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(null) throws NPE
+ */
+ public void testInvokeAny1() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAny(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(empty collection) throws IAE
+ */
+ public void testInvokeAny2() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws NPE if c has null elements
+ */
+ public void testInvokeAny3() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testInvokeAny4() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) returns result of some task
+ */
+ public void testInvokeAny5() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(null) throws NPE
+ */
+ public void testInvokeAll1() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(empty collection) returns empty collection
+ */
+ public void testInvokeAll2() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) throws NPE if c has null elements
+ */
+ public void testInvokeAll3() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of element of invokeAll(c) throws exception on failed task
+ */
+ public void testInvokeAll4() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) returns results of all completed tasks
+ */
+ public void testInvokeAll5() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(null) throws NPE
+ */
+ public void testTimedInvokeAny1() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(,,null) throws NPE
+ */
+ public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(empty collection) throws IAE
+ */
+ public void testTimedInvokeAny2() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAny3() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testTimedInvokeAny4() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) returns result of some task
+ */
+ public void testTimedInvokeAny5() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(null) throws NPE
+ */
+ public void testTimedInvokeAll1() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(,,null) throws NPE
+ */
+ public void testTimedInvokeAllNullTimeUnit() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(empty collection) returns empty collection
+ */
+ public void testTimedInvokeAll2() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAll3() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of element of invokeAll(c) throws exception on failed task
+ */
+ public void testTimedInvokeAll4() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) returns results of all completed tasks
+ */
+ public void testTimedInvokeAll5() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) cancels tasks not completed by timeout
+ */
+ public void testTimedInvokeAll6() throws Exception {
+ ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+ assertEquals(l.size(), futures.size());
+ for (Future future : futures)
+ assertTrue(future.isDone());
+ assertFalse(futures.get(0).isCancelled());
+ assertTrue(futures.get(1).isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Execution continues if there is at least one thread even if
+ * thread factory fails to create more
+ */
+ public void testFailingThreadFactory() throws InterruptedException {
+ final ExecutorService e =
+ new CustomTPE(100, 100,
+ LONG_DELAY_MS, MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ new FailingThreadFactory());
+ try {
+ final int TASKS = 100;
+ final CountDownLatch done = new CountDownLatch(TASKS);
+ for (int k = 0; k < TASKS; ++k)
+ e.execute(new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ }});
+ assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * allowsCoreThreadTimeOut is by default false.
+ */
+ public void testAllowsCoreThreadTimeOut() {
+ ThreadPoolExecutor p = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+ assertFalse(p.allowsCoreThreadTimeOut());
+ joinPool(p);
+ }
+
+ /**
+ * allowCoreThreadTimeOut(true) causes idle threads to time out
+ */
+ public void testAllowCoreThreadTimeOut_true() throws Exception {
+ long coreThreadTimeOut = SHORT_DELAY_MS;
+ final ThreadPoolExecutor p =
+ new CustomTPE(2, 10,
+ coreThreadTimeOut, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ try {
+ p.allowCoreThreadTimeOut(true);
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getPoolSize());
+ }});
+ await(threadStarted);
+ delay(coreThreadTimeOut);
+ long startTime = System.nanoTime();
+ while (p.getPoolSize() > 0
+ && millisElapsedSince(startTime) < LONG_DELAY_MS)
+ Thread.yield();
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ assertEquals(0, p.getPoolSize());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * allowCoreThreadTimeOut(false) causes idle threads not to time out
+ */
+ public void testAllowCoreThreadTimeOut_false() throws Exception {
+ long coreThreadTimeOut = SHORT_DELAY_MS;
+ final ThreadPoolExecutor p =
+ new CustomTPE(2, 10,
+ coreThreadTimeOut, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ try {
+ p.allowCoreThreadTimeOut(false);
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertTrue(p.getPoolSize() >= 1);
+ }});
+ delay(2 * coreThreadTimeOut);
+ assertTrue(p.getPoolSize() >= 1);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java
new file mode 100644
index 0000000..55f769b
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java
@@ -0,0 +1,2010 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import java.util.*;
+
+public class ThreadPoolExecutorTest extends JSR166TestCase {
+
+ static class ExtendedTPE extends ThreadPoolExecutor {
+ final CountDownLatch beforeCalled = new CountDownLatch(1);
+ final CountDownLatch afterCalled = new CountDownLatch(1);
+ final CountDownLatch terminatedCalled = new CountDownLatch(1);
+
+ public ExtendedTPE() {
+ super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
+ }
+ protected void beforeExecute(Thread t, Runnable r) {
+ beforeCalled.countDown();
+ }
+ protected void afterExecute(Runnable r, Throwable t) {
+ afterCalled.countDown();
+ }
+ protected void terminated() {
+ terminatedCalled.countDown();
+ }
+
+ public boolean beforeCalled() {
+ return beforeCalled.getCount() == 0;
+ }
+ public boolean afterCalled() {
+ return afterCalled.getCount() == 0;
+ }
+ public boolean terminatedCalled() {
+ return terminatedCalled.getCount() == 0;
+ }
+ }
+
+ static class FailingThreadFactory implements ThreadFactory {
+ int calls = 0;
+ public Thread newThread(Runnable r) {
+ if (++calls > 1) return null;
+ return new Thread(r);
+ }
+ }
+
+ /**
+ * execute successfully executes a runnable
+ */
+ public void testExecute() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch done = new CountDownLatch(1);
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ }};
+ try {
+ p.execute(task);
+ assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getActiveCount increases but doesn't overestimate, when a
+ * thread becomes active
+ */
+ public void testGetActiveCount() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getActiveCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getActiveCount());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getActiveCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * prestartCoreThread starts a thread if under corePoolSize, else doesn't
+ */
+ public void testPrestartCoreThread() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(0, p.getPoolSize());
+ assertTrue(p.prestartCoreThread());
+ assertEquals(1, p.getPoolSize());
+ assertTrue(p.prestartCoreThread());
+ assertEquals(2, p.getPoolSize());
+ assertFalse(p.prestartCoreThread());
+ assertEquals(2, p.getPoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * prestartAllCoreThreads starts all corePoolSize threads
+ */
+ public void testPrestartAllCoreThreads() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(0, p.getPoolSize());
+ p.prestartAllCoreThreads();
+ assertEquals(2, p.getPoolSize());
+ p.prestartAllCoreThreads();
+ assertEquals(2, p.getPoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * getCompletedTaskCount increases, but doesn't overestimate,
+ * when tasks complete
+ */
+ public void testGetCompletedTaskCount() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch threadProceed = new CountDownLatch(1);
+ final CountDownLatch threadDone = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getCompletedTaskCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(0, p.getCompletedTaskCount());
+ threadProceed.await();
+ threadDone.countDown();
+ }});
+ await(threadStarted);
+ assertEquals(0, p.getCompletedTaskCount());
+ threadProceed.countDown();
+ threadDone.await();
+ long startTime = System.nanoTime();
+ while (p.getCompletedTaskCount() != 1) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getCorePoolSize returns size given in constructor if not otherwise set
+ */
+ public void testGetCorePoolSize() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(1, p.getCorePoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * getKeepAliveTime returns value given in constructor if not otherwise set
+ */
+ public void testGetKeepAliveTime() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 2,
+ 1000, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(1, p.getKeepAliveTime(TimeUnit.SECONDS));
+ joinPool(p);
+ }
+
+ /**
+ * getThreadFactory returns factory in constructor if not set
+ */
+ public void testGetThreadFactory() {
+ ThreadFactory tf = new SimpleThreadFactory();
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ tf,
+ new NoOpREHandler());
+ assertSame(tf, p.getThreadFactory());
+ joinPool(p);
+ }
+
+ /**
+ * setThreadFactory sets the thread factory returned by getThreadFactory
+ */
+ public void testSetThreadFactory() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ ThreadFactory tf = new SimpleThreadFactory();
+ p.setThreadFactory(tf);
+ assertSame(tf, p.getThreadFactory());
+ joinPool(p);
+ }
+
+ /**
+ * setThreadFactory(null) throws NPE
+ */
+ public void testSetThreadFactoryNull() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setThreadFactory(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getRejectedExecutionHandler returns handler in constructor if not set
+ */
+ public void testGetRejectedExecutionHandler() {
+ final RejectedExecutionHandler h = new NoOpREHandler();
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ h);
+ assertSame(h, p.getRejectedExecutionHandler());
+ joinPool(p);
+ }
+
+ /**
+ * setRejectedExecutionHandler sets the handler returned by
+ * getRejectedExecutionHandler
+ */
+ public void testSetRejectedExecutionHandler() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ RejectedExecutionHandler h = new NoOpREHandler();
+ p.setRejectedExecutionHandler(h);
+ assertSame(h, p.getRejectedExecutionHandler());
+ joinPool(p);
+ }
+
+ /**
+ * setRejectedExecutionHandler(null) throws NPE
+ */
+ public void testSetRejectedExecutionHandlerNull() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setRejectedExecutionHandler(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getLargestPoolSize increases, but doesn't overestimate, when
+ * multiple threads active
+ */
+ public void testGetLargestPoolSize() throws InterruptedException {
+ final int THREADS = 3;
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(THREADS, THREADS,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getLargestPoolSize());
+ for (int i = 0; i < THREADS; i++)
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadsStarted.countDown();
+ done.await();
+ assertEquals(THREADS, p.getLargestPoolSize());
+ }});
+ assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(THREADS, p.getLargestPoolSize());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ assertEquals(THREADS, p.getLargestPoolSize());
+ }
+ }
+
+ /**
+ * getMaximumPoolSize returns value given in constructor if not
+ * otherwise set
+ */
+ public void testGetMaximumPoolSize() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 3,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ assertEquals(3, p.getMaximumPoolSize());
+ joinPool(p);
+ }
+
+ /**
+ * getPoolSize increases, but doesn't overestimate, when threads
+ * become active
+ */
+ public void testGetPoolSize() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getPoolSize());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getPoolSize());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getPoolSize());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * getTaskCount increases, but doesn't overestimate, when tasks submitted
+ */
+ public void testGetTaskCount() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertEquals(0, p.getTaskCount());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertEquals(1, p.getTaskCount());
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(1, p.getTaskCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * isShutdown is false before shutdown, true after
+ */
+ public void testIsShutdown() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ assertFalse(p.isShutdown());
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertTrue(p.isShutdown());
+ joinPool(p);
+ }
+
+ /**
+ * awaitTermination on a non-shutdown pool times out
+ */
+ public void testAwaitTermination_timesOut() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ assertFalse(p.isTerminated());
+ assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
+ assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
+ assertFalse(p.awaitTermination(-1L, NANOSECONDS));
+ assertFalse(p.awaitTermination(-1L, MILLISECONDS));
+ assertFalse(p.awaitTermination(0L, NANOSECONDS));
+ assertFalse(p.awaitTermination(0L, MILLISECONDS));
+ long timeoutNanos = 999999L;
+ long startTime = System.nanoTime();
+ assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
+ assertTrue(System.nanoTime() - startTime >= timeoutNanos);
+ assertFalse(p.isTerminated());
+ startTime = System.nanoTime();
+ long timeoutMillis = timeoutMillis();
+ assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ assertFalse(p.isTerminated());
+ p.shutdown();
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ }
+
+ /**
+ * isTerminated is false before termination, true after
+ */
+ public void testIsTerminated() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ assertFalse(p.isTerminated());
+ try {
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(p.isTerminated());
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
+ done.countDown();
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ }
+
+ /**
+ * isTerminating is not true when running or when terminated
+ */
+ public void testIsTerminating() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ assertFalse(p.isTerminating());
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ assertFalse(p.isTerminating());
+ threadStarted.countDown();
+ done.await();
+ }});
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
+ done.countDown();
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertTrue(p.isTerminated());
+ assertFalse(p.isTerminating());
+ }
+
+ /**
+ * getQueue returns the work queue, which contains queued tasks
+ */
+ public void testGetQueue() throws InterruptedException {
+ final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ q);
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ FutureTask[] tasks = new FutureTask[5];
+ for (int i = 0; i < tasks.length; i++) {
+ Callable task = new CheckedCallable<Boolean>() {
+ public Boolean realCall() throws InterruptedException {
+ threadStarted.countDown();
+ assertSame(q, p.getQueue());
+ done.await();
+ return Boolean.TRUE;
+ }};
+ tasks[i] = new FutureTask(task);
+ p.execute(tasks[i]);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertSame(q, p.getQueue());
+ assertFalse(q.contains(tasks[0]));
+ assertTrue(q.contains(tasks[tasks.length - 1]));
+ assertEquals(tasks.length - 1, q.size());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * remove(task) removes queued task, and fails to remove active task
+ */
+ public void testRemove() throws InterruptedException {
+ BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ q);
+ Runnable[] tasks = new Runnable[5];
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ for (int i = 0; i < tasks.length; i++) {
+ tasks[i] = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ }};
+ p.execute(tasks[i]);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertFalse(p.remove(tasks[0]));
+ assertTrue(q.contains(tasks[4]));
+ assertTrue(q.contains(tasks[3]));
+ assertTrue(p.remove(tasks[4]));
+ assertFalse(p.remove(tasks[4]));
+ assertFalse(q.contains(tasks[4]));
+ assertTrue(q.contains(tasks[3]));
+ assertTrue(p.remove(tasks[3]));
+ assertFalse(q.contains(tasks[3]));
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * purge removes cancelled tasks from the queue
+ */
+ public void testPurge() throws InterruptedException {
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ q);
+ FutureTask[] tasks = new FutureTask[5];
+ try {
+ for (int i = 0; i < tasks.length; i++) {
+ Callable task = new CheckedCallable<Boolean>() {
+ public Boolean realCall() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ return Boolean.TRUE;
+ }};
+ tasks[i] = new FutureTask(task);
+ p.execute(tasks[i]);
+ }
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ assertEquals(tasks.length, p.getTaskCount());
+ assertEquals(tasks.length - 1, q.size());
+ assertEquals(1L, p.getActiveCount());
+ assertEquals(0L, p.getCompletedTaskCount());
+ tasks[4].cancel(true);
+ tasks[3].cancel(false);
+ p.purge();
+ assertEquals(tasks.length - 3, q.size());
+ assertEquals(tasks.length - 2, p.getTaskCount());
+ p.purge(); // Nothing to do
+ assertEquals(tasks.length - 3, q.size());
+ assertEquals(tasks.length - 2, p.getTaskCount());
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * shutdownNow returns a list containing tasks that were not run
+ */
+ public void testShutdownNow() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List l;
+ try {
+ for (int i = 0; i < 5; i++)
+ p.execute(new MediumPossiblyInterruptedRunnable());
+ }
+ finally {
+ try {
+ l = p.shutdownNow();
+ } catch (SecurityException ok) { return; }
+ }
+ assertTrue(p.isShutdown());
+ assertTrue(l.size() <= 4);
+ }
+
+ // Exception Tests
+
+ /**
+ * Constructor throws if corePoolSize argument is less than zero
+ */
+ public void testConstructor1() {
+ try {
+ new ThreadPoolExecutor(-1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is less than zero
+ */
+ public void testConstructor2() {
+ try {
+ new ThreadPoolExecutor(1, -1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is equal to zero
+ */
+ public void testConstructor3() {
+ try {
+ new ThreadPoolExecutor(1, 0,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if keepAliveTime is less than zero
+ */
+ public void testConstructor4() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ -1L, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize is greater than the maximumPoolSize
+ */
+ public void testConstructor5() {
+ try {
+ new ThreadPoolExecutor(2, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if workQueue is set to null
+ */
+ public void testConstructorNullPointerException() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ (BlockingQueue) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize argument is less than zero
+ */
+ public void testConstructor6() {
+ try {
+ new ThreadPoolExecutor(-1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is less than zero
+ */
+ public void testConstructor7() {
+ try {
+ new ThreadPoolExecutor(1, -1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is equal to zero
+ */
+ public void testConstructor8() {
+ try {
+ new ThreadPoolExecutor(1, 0,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if keepAliveTime is less than zero
+ */
+ public void testConstructor9() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ -1L, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize is greater than the maximumPoolSize
+ */
+ public void testConstructor10() {
+ try {
+ new ThreadPoolExecutor(2, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if workQueue is set to null
+ */
+ public void testConstructorNullPointerException2() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ (BlockingQueue) null,
+ new SimpleThreadFactory());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if threadFactory is set to null
+ */
+ public void testConstructorNullPointerException3() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ (ThreadFactory) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize argument is less than zero
+ */
+ public void testConstructor11() {
+ try {
+ new ThreadPoolExecutor(-1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is less than zero
+ */
+ public void testConstructor12() {
+ try {
+ new ThreadPoolExecutor(1, -1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is equal to zero
+ */
+ public void testConstructor13() {
+ try {
+ new ThreadPoolExecutor(1, 0,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if keepAliveTime is less than zero
+ */
+ public void testConstructor14() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ -1L, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize is greater than the maximumPoolSize
+ */
+ public void testConstructor15() {
+ try {
+ new ThreadPoolExecutor(2, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if workQueue is set to null
+ */
+ public void testConstructorNullPointerException4() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ (BlockingQueue) null,
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if handler is set to null
+ */
+ public void testConstructorNullPointerException5() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ (RejectedExecutionHandler) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize argument is less than zero
+ */
+ public void testConstructor16() {
+ try {
+ new ThreadPoolExecutor(-1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory(),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is less than zero
+ */
+ public void testConstructor17() {
+ try {
+ new ThreadPoolExecutor(1, -1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory(),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if maximumPoolSize is equal to zero
+ */
+ public void testConstructor18() {
+ try {
+ new ThreadPoolExecutor(1, 0,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory(),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if keepAliveTime is less than zero
+ */
+ public void testConstructor19() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ -1L, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory(),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if corePoolSize is greater than the maximumPoolSize
+ */
+ public void testConstructor20() {
+ try {
+ new ThreadPoolExecutor(2, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory(),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+
+ /**
+ * Constructor throws if workQueue is null
+ */
+ public void testConstructorNullPointerException6() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ (BlockingQueue) null,
+ new SimpleThreadFactory(),
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if handler is null
+ */
+ public void testConstructorNullPointerException7() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ new SimpleThreadFactory(),
+ (RejectedExecutionHandler) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Constructor throws if ThreadFactory is null
+ */
+ public void testConstructorNullPointerException8() {
+ try {
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10),
+ (ThreadFactory) null,
+ new NoOpREHandler());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * get of submitted callable throws InterruptedException if interrupted
+ */
+ public void testInterruptedSubmit() throws InterruptedException {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ 60, TimeUnit.SECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws Exception {
+ Callable task = new CheckedCallable<Boolean>() {
+ public Boolean realCall() throws InterruptedException {
+ threadStarted.countDown();
+ done.await();
+ return Boolean.TRUE;
+ }};
+ p.submit(task).get();
+ }});
+
+ assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+ t.interrupt();
+ awaitTermination(t, MEDIUM_DELAY_MS);
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute throws RejectedExecutionException if saturated.
+ */
+ public void testSaturatedExecute() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1));
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ done.await();
+ }};
+ for (int i = 0; i < 2; ++i)
+ p.execute(task);
+ for (int i = 0; i < 2; ++i) {
+ try {
+ p.execute(task);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+ assertTrue(p.getTaskCount() <= 2);
+ }
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * submit(runnable) throws RejectedExecutionException if saturated.
+ */
+ public void testSaturatedSubmitRunnable() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1));
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ done.await();
+ }};
+ for (int i = 0; i < 2; ++i)
+ p.submit(task);
+ for (int i = 0; i < 2; ++i) {
+ try {
+ p.execute(task);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+ assertTrue(p.getTaskCount() <= 2);
+ }
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * submit(callable) throws RejectedExecutionException if saturated.
+ */
+ public void testSaturatedSubmitCallable() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1));
+ final CountDownLatch done = new CountDownLatch(1);
+ try {
+ Runnable task = new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ done.await();
+ }};
+ for (int i = 0; i < 2; ++i)
+ p.submit(Executors.callable(task));
+ for (int i = 0; i < 2; ++i) {
+ try {
+ p.execute(task);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+ assertTrue(p.getTaskCount() <= 2);
+ }
+ } finally {
+ done.countDown();
+ joinPool(p);
+ }
+ }
+
+ /**
+ * executor using CallerRunsPolicy runs task if saturated.
+ */
+ public void testSaturatedExecute2() {
+ RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS,
+ MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1),
+ h);
+ try {
+ TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+ for (int i = 0; i < tasks.length; ++i)
+ tasks[i] = new TrackedNoOpRunnable();
+ TrackedLongRunnable mr = new TrackedLongRunnable();
+ p.execute(mr);
+ for (int i = 0; i < tasks.length; ++i)
+ p.execute(tasks[i]);
+ for (int i = 1; i < tasks.length; ++i)
+ assertTrue(tasks[i].done);
+ try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * executor using DiscardPolicy drops task if saturated.
+ */
+ public void testSaturatedExecute3() {
+ RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy();
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1),
+ h);
+ try {
+ TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+ for (int i = 0; i < tasks.length; ++i)
+ tasks[i] = new TrackedNoOpRunnable();
+ p.execute(new TrackedLongRunnable());
+ for (TrackedNoOpRunnable task : tasks)
+ p.execute(task);
+ for (TrackedNoOpRunnable task : tasks)
+ assertFalse(task.done);
+ try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * executor using DiscardOldestPolicy drops oldest task if saturated.
+ */
+ public void testSaturatedExecute4() {
+ RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy();
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1),
+ h);
+ try {
+ p.execute(new TrackedLongRunnable());
+ TrackedLongRunnable r2 = new TrackedLongRunnable();
+ p.execute(r2);
+ assertTrue(p.getQueue().contains(r2));
+ TrackedNoOpRunnable r3 = new TrackedNoOpRunnable();
+ p.execute(r3);
+ assertFalse(p.getQueue().contains(r2));
+ assertTrue(p.getQueue().contains(r3));
+ try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute throws RejectedExecutionException if shutdown
+ */
+ public void testRejectedExecutionExceptionOnShutdown() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1));
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ try {
+ p.execute(new NoOpRunnable());
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+
+ joinPool(p);
+ }
+
+ /**
+ * execute using CallerRunsPolicy drops task on shutdown
+ */
+ public void testCallerRunsOnShutdown() {
+ RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1), h);
+
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ try {
+ TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+ p.execute(r);
+ assertFalse(r.done);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute using DiscardPolicy drops task on shutdown
+ */
+ public void testDiscardOnShutdown() {
+ RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy();
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1),
+ h);
+
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ try {
+ TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+ p.execute(r);
+ assertFalse(r.done);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute using DiscardOldestPolicy drops task on shutdown
+ */
+ public void testDiscardOldestOnShutdown() {
+ RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy();
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(1),
+ h);
+
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ try {
+ TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+ p.execute(r);
+ assertFalse(r.done);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute(null) throws NPE
+ */
+ public void testExecuteNull() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.execute(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+
+ joinPool(p);
+ }
+
+ /**
+ * setCorePoolSize of negative value throws IllegalArgumentException
+ */
+ public void testCorePoolSizeIllegalArgumentException() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setCorePoolSize(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ joinPool(p);
+ }
+
+ /**
+ * setMaximumPoolSize(int) throws IllegalArgumentException if
+ * given a value less the core pool size
+ */
+ public void testMaximumPoolSizeIllegalArgumentException() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 3,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setMaximumPoolSize(1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ joinPool(p);
+ }
+
+ /**
+ * setMaximumPoolSize throws IllegalArgumentException
+ * if given a negative value
+ */
+ public void testMaximumPoolSizeIllegalArgumentException2() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 3,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setMaximumPoolSize(-1);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ joinPool(p);
+ }
+
+ /**
+ * setKeepAliveTime throws IllegalArgumentException
+ * when given a negative value
+ */
+ public void testKeepAliveTimeIllegalArgumentException() {
+ ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 3,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ p.setKeepAliveTime(-1,MILLISECONDS);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ }
+ joinPool(p);
+ }
+
+ /**
+ * terminated() is called on termination
+ */
+ public void testTerminated() {
+ ExtendedTPE p = new ExtendedTPE();
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ assertTrue(p.terminatedCalled());
+ joinPool(p);
+ }
+
+ /**
+ * beforeExecute and afterExecute are called when executing task
+ */
+ public void testBeforeAfter() throws InterruptedException {
+ ExtendedTPE p = new ExtendedTPE();
+ try {
+ final CountDownLatch done = new CountDownLatch(1);
+ final CheckedRunnable task = new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ }};
+ p.execute(task);
+ await(p.afterCalled);
+ assertEquals(0, done.getCount());
+ assertTrue(p.afterCalled());
+ assertTrue(p.beforeCalled());
+ try { p.shutdown(); } catch (SecurityException ok) { return; }
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * completed submit of callable returns result
+ */
+ public void testSubmitCallable() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ Future<String> future = e.submit(new StringTask());
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * completed submit of runnable returns successfully
+ */
+ public void testSubmitRunnable() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ Future<?> future = e.submit(new NoOpRunnable());
+ future.get();
+ assertTrue(future.isDone());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * completed submit of (runnable, result) returns result
+ */
+ public void testSubmitRunnable2() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+ String result = future.get();
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(null) throws NPE
+ */
+ public void testInvokeAny1() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAny(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(empty collection) throws IAE
+ */
+ public void testInvokeAny2() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>());
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws NPE if c has null elements
+ */
+ public void testInvokeAny3() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testInvokeAny4() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) returns result of some task
+ */
+ public void testInvokeAny5() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(null) throws NPE
+ */
+ public void testInvokeAll1() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(empty collection) returns empty collection
+ */
+ public void testInvokeAll2() throws InterruptedException {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) throws NPE if c has null elements
+ */
+ public void testInvokeAll3() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of element of invokeAll(c) throws exception on failed task
+ */
+ public void testInvokeAll4() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ }
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAll(c) returns results of all completed tasks
+ */
+ public void testInvokeAll5() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures = e.invokeAll(l);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(null) throws NPE
+ */
+ public void testTimedInvokeAny1() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(,,null) throws NPE
+ */
+ public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(empty collection) throws IAE
+ */
+ public void testTimedInvokeAny2() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAny3() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(latchAwaitingStringTask(latch));
+ l.add(null);
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ latch.countDown();
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) throws ExecutionException if no task completes
+ */
+ public void testTimedInvokeAny4() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAny(c) returns result of some task
+ */
+ public void testTimedInvokeAny5() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(null) throws NPE
+ */
+ public void testTimedInvokeAll1() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(,,null) throws NPE
+ */
+ public void testTimedInvokeAllNullTimeUnit() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(empty collection) returns empty collection
+ */
+ public void testTimedInvokeAll2() throws InterruptedException {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ assertTrue(r.isEmpty());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) throws NPE if c has null elements
+ */
+ public void testTimedInvokeAll3() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(null);
+ try {
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * get of element of invokeAll(c) throws exception on failed task
+ */
+ public void testTimedInvokeAll4() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(1, futures.size());
+ try {
+ futures.get(0).get();
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) returns results of all completed tasks
+ */
+ public void testTimedInvokeAll5() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ assertEquals(2, futures.size());
+ for (Future<String> future : futures)
+ assertSame(TEST_STRING, future.get());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * timed invokeAll(c) cancels tasks not completed by timeout
+ */
+ public void testTimedInvokeAll6() throws Exception {
+ ExecutorService e =
+ new ThreadPoolExecutor(2, 2,
+ LONG_DELAY_MS, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
+ l.add(new StringTask());
+ List<Future<String>> futures =
+ e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+ assertEquals(l.size(), futures.size());
+ for (Future future : futures)
+ assertTrue(future.isDone());
+ assertFalse(futures.get(0).isCancelled());
+ assertTrue(futures.get(1).isCancelled());
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * Execution continues if there is at least one thread even if
+ * thread factory fails to create more
+ */
+ public void testFailingThreadFactory() throws InterruptedException {
+ final ExecutorService e =
+ new ThreadPoolExecutor(100, 100,
+ LONG_DELAY_MS, MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ new FailingThreadFactory());
+ try {
+ final int TASKS = 100;
+ final CountDownLatch done = new CountDownLatch(TASKS);
+ for (int k = 0; k < TASKS; ++k)
+ e.execute(new CheckedRunnable() {
+ public void realRun() {
+ done.countDown();
+ }});
+ assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * allowsCoreThreadTimeOut is by default false.
+ */
+ public void testAllowsCoreThreadTimeOut() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 2,
+ 1000, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ assertFalse(p.allowsCoreThreadTimeOut());
+ joinPool(p);
+ }
+
+ /**
+ * allowCoreThreadTimeOut(true) causes idle threads to time out
+ */
+ public void testAllowCoreThreadTimeOut_true() throws Exception {
+ long coreThreadTimeOut = SHORT_DELAY_MS;
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 10,
+ coreThreadTimeOut, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ try {
+ p.allowCoreThreadTimeOut(true);
+ p.execute(new CheckedRunnable() {
+ public void realRun() {
+ threadStarted.countDown();
+ assertEquals(1, p.getPoolSize());
+ }});
+ await(threadStarted);
+ delay(coreThreadTimeOut);
+ long startTime = System.nanoTime();
+ while (p.getPoolSize() > 0
+ && millisElapsedSince(startTime) < LONG_DELAY_MS)
+ Thread.yield();
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+ assertEquals(0, p.getPoolSize());
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * allowCoreThreadTimeOut(false) causes idle threads not to time out
+ */
+ public void testAllowCoreThreadTimeOut_false() throws Exception {
+ long coreThreadTimeOut = SHORT_DELAY_MS;
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(2, 10,
+ coreThreadTimeOut, MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(10));
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+ try {
+ p.allowCoreThreadTimeOut(false);
+ p.execute(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ threadStarted.countDown();
+ assertTrue(p.getPoolSize() >= 1);
+ }});
+ delay(2 * coreThreadTimeOut);
+ assertTrue(p.getPoolSize() >= 1);
+ } finally {
+ joinPool(p);
+ }
+ }
+
+ /**
+ * execute allows the same task to be submitted multiple times, even
+ * if rejected
+ */
+ public void testRejectedRecycledTask() throws InterruptedException {
+ final int nTasks = 1000;
+ final CountDownLatch done = new CountDownLatch(nTasks);
+ final Runnable recycledTask = new Runnable() {
+ public void run() {
+ done.countDown();
+ }};
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 30, 60, TimeUnit.SECONDS,
+ new ArrayBlockingQueue(30));
+ try {
+ for (int i = 0; i < nTasks; ++i) {
+ for (;;) {
+ try {
+ p.execute(recycledTask);
+ break;
+ }
+ catch (RejectedExecutionException ignore) {}
+ }
+ }
+ // enough time to run all tasks
+ assertTrue(done.await(nTasks * SHORT_DELAY_MS, MILLISECONDS));
+ } finally {
+ joinPool(p);
+ }
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadTest.java b/jsr166-tests/src/test/java/jsr166/ThreadTest.java
new file mode 100644
index 0000000..12c2f8a
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ThreadTest.java
@@ -0,0 +1,65 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+
+public class ThreadTest extends JSR166TestCase {
+
+ static class MyHandler implements Thread.UncaughtExceptionHandler {
+ public void uncaughtException(Thread t, Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * getUncaughtExceptionHandler returns ThreadGroup unless set,
+ * otherwise returning value of last setUncaughtExceptionHandler.
+ */
+ public void testGetAndSetUncaughtExceptionHandler() {
+ // these must be done all at once to avoid state
+ // dependencies across tests
+ Thread current = Thread.currentThread();
+ ThreadGroup tg = current.getThreadGroup();
+ MyHandler eh = new MyHandler();
+ assertEquals(tg, current.getUncaughtExceptionHandler());
+ current.setUncaughtExceptionHandler(eh);
+ assertEquals(eh, current.getUncaughtExceptionHandler());
+ current.setUncaughtExceptionHandler(null);
+ assertEquals(tg, current.getUncaughtExceptionHandler());
+ }
+
+ /**
+ * getDefaultUncaughtExceptionHandler returns value of last
+ * setDefaultUncaughtExceptionHandler.
+ */
+ public void testGetAndSetDefaultUncaughtExceptionHandler() {
+ // BEGIN android-remove (when running as cts the RuntimeInit will
+ // set a default handler)
+ // assertEquals(null, Thread.getDefaultUncaughtExceptionHandler());
+ // END android-remove
+
+ // failure due to securityException is OK.
+ // Would be nice to explicitly test both ways, but cannot yet.
+ try {
+ Thread current = Thread.currentThread();
+ ThreadGroup tg = current.getThreadGroup();
+ MyHandler eh = new MyHandler();
+ Thread.setDefaultUncaughtExceptionHandler(eh);
+ assertEquals(eh, Thread.getDefaultUncaughtExceptionHandler());
+ Thread.setDefaultUncaughtExceptionHandler(null);
+ }
+ catch (SecurityException ok) {
+ }
+ assertEquals(null, Thread.getDefaultUncaughtExceptionHandler());
+ }
+
+ // How to test actually using UEH within junit?
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java b/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java
new file mode 100644
index 0000000..7fa9e1a
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java
@@ -0,0 +1,457 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class TimeUnitTest extends JSR166TestCase {
+
+ // (loops to 88888 check increments at all time divisions.)
+
+ /**
+ * convert correctly converts sample values across the units
+ */
+ public void testConvert() {
+ for (long t = 0; t < 88888; ++t) {
+ assertEquals(t*60*60*24,
+ TimeUnit.SECONDS.convert(t,
+ TimeUnit.DAYS));
+ assertEquals(t*60*60,
+ TimeUnit.SECONDS.convert(t,
+ TimeUnit.HOURS));
+ assertEquals(t*60,
+ TimeUnit.SECONDS.convert(t,
+ TimeUnit.MINUTES));
+ assertEquals(t,
+ TimeUnit.SECONDS.convert(t,
+ TimeUnit.SECONDS));
+ assertEquals(t,
+ TimeUnit.SECONDS.convert(1000L*t,
+ TimeUnit.MILLISECONDS));
+ assertEquals(t,
+ TimeUnit.SECONDS.convert(1000000L*t,
+ TimeUnit.MICROSECONDS));
+ assertEquals(t,
+ TimeUnit.SECONDS.convert(1000000000L*t,
+ TimeUnit.NANOSECONDS));
+
+ assertEquals(1000L*t*60*60*24,
+ TimeUnit.MILLISECONDS.convert(t,
+ TimeUnit.DAYS));
+ assertEquals(1000L*t*60*60,
+ TimeUnit.MILLISECONDS.convert(t,
+ TimeUnit.HOURS));
+ assertEquals(1000L*t*60,
+ TimeUnit.MILLISECONDS.convert(t,
+ TimeUnit.MINUTES));
+ assertEquals(1000L*t,
+ TimeUnit.MILLISECONDS.convert(t,
+ TimeUnit.SECONDS));
+ assertEquals(t,
+ TimeUnit.MILLISECONDS.convert(t,
+ TimeUnit.MILLISECONDS));
+ assertEquals(t,
+ TimeUnit.MILLISECONDS.convert(1000L*t,
+ TimeUnit.MICROSECONDS));
+ assertEquals(t,
+ TimeUnit.MILLISECONDS.convert(1000000L*t,
+ TimeUnit.NANOSECONDS));
+
+ assertEquals(1000000L*t*60*60*24,
+ TimeUnit.MICROSECONDS.convert(t,
+ TimeUnit.DAYS));
+ assertEquals(1000000L*t*60*60,
+ TimeUnit.MICROSECONDS.convert(t,
+ TimeUnit.HOURS));
+ assertEquals(1000000L*t*60,
+ TimeUnit.MICROSECONDS.convert(t,
+ TimeUnit.MINUTES));
+ assertEquals(1000000L*t,
+ TimeUnit.MICROSECONDS.convert(t,
+ TimeUnit.SECONDS));
+ assertEquals(1000L*t,
+ TimeUnit.MICROSECONDS.convert(t,
+ TimeUnit.MILLISECONDS));
+ assertEquals(t,
+ TimeUnit.MICROSECONDS.convert(t,
+ TimeUnit.MICROSECONDS));
+ assertEquals(t,
+ TimeUnit.MICROSECONDS.convert(1000L*t,
+ TimeUnit.NANOSECONDS));
+
+ assertEquals(1000000000L*t*60*60*24,
+ TimeUnit.NANOSECONDS.convert(t,
+ TimeUnit.DAYS));
+ assertEquals(1000000000L*t*60*60,
+ TimeUnit.NANOSECONDS.convert(t,
+ TimeUnit.HOURS));
+ assertEquals(1000000000L*t*60,
+ TimeUnit.NANOSECONDS.convert(t,
+ TimeUnit.MINUTES));
+ assertEquals(1000000000L*t,
+ TimeUnit.NANOSECONDS.convert(t,
+ TimeUnit.SECONDS));
+ assertEquals(1000000L*t,
+ TimeUnit.NANOSECONDS.convert(t,
+ TimeUnit.MILLISECONDS));
+ assertEquals(1000L*t,
+ TimeUnit.NANOSECONDS.convert(t,
+ TimeUnit.MICROSECONDS));
+ assertEquals(t,
+ TimeUnit.NANOSECONDS.convert(t,
+ TimeUnit.NANOSECONDS));
+ }
+ }
+
+ /**
+ * toNanos correctly converts sample values in different units to
+ * nanoseconds
+ */
+ public void testToNanos() {
+ for (long t = 0; t < 88888; ++t) {
+ assertEquals(t*1000000000L*60*60*24,
+ TimeUnit.DAYS.toNanos(t));
+ assertEquals(t*1000000000L*60*60,
+ TimeUnit.HOURS.toNanos(t));
+ assertEquals(t*1000000000L*60,
+ TimeUnit.MINUTES.toNanos(t));
+ assertEquals(1000000000L*t,
+ TimeUnit.SECONDS.toNanos(t));
+ assertEquals(1000000L*t,
+ TimeUnit.MILLISECONDS.toNanos(t));
+ assertEquals(1000L*t,
+ TimeUnit.MICROSECONDS.toNanos(t));
+ assertEquals(t,
+ TimeUnit.NANOSECONDS.toNanos(t));
+ }
+ }
+
+ /**
+ * toMicros correctly converts sample values in different units to
+ * microseconds
+ */
+ public void testToMicros() {
+ for (long t = 0; t < 88888; ++t) {
+ assertEquals(t*1000000L*60*60*24,
+ TimeUnit.DAYS.toMicros(t));
+ assertEquals(t*1000000L*60*60,
+ TimeUnit.HOURS.toMicros(t));
+ assertEquals(t*1000000L*60,
+ TimeUnit.MINUTES.toMicros(t));
+ assertEquals(1000000L*t,
+ TimeUnit.SECONDS.toMicros(t));
+ assertEquals(1000L*t,
+ TimeUnit.MILLISECONDS.toMicros(t));
+ assertEquals(t,
+ TimeUnit.MICROSECONDS.toMicros(t));
+ assertEquals(t,
+ TimeUnit.NANOSECONDS.toMicros(t*1000L));
+ }
+ }
+
+ /**
+ * toMillis correctly converts sample values in different units to
+ * milliseconds
+ */
+ public void testToMillis() {
+ for (long t = 0; t < 88888; ++t) {
+ assertEquals(t*1000L*60*60*24,
+ TimeUnit.DAYS.toMillis(t));
+ assertEquals(t*1000L*60*60,
+ TimeUnit.HOURS.toMillis(t));
+ assertEquals(t*1000L*60,
+ TimeUnit.MINUTES.toMillis(t));
+ assertEquals(1000L*t,
+ TimeUnit.SECONDS.toMillis(t));
+ assertEquals(t,
+ TimeUnit.MILLISECONDS.toMillis(t));
+ assertEquals(t,
+ TimeUnit.MICROSECONDS.toMillis(t*1000L));
+ assertEquals(t,
+ TimeUnit.NANOSECONDS.toMillis(t*1000000L));
+ }
+ }
+
+ /**
+ * toSeconds correctly converts sample values in different units to
+ * seconds
+ */
+ public void testToSeconds() {
+ for (long t = 0; t < 88888; ++t) {
+ assertEquals(t*60*60*24,
+ TimeUnit.DAYS.toSeconds(t));
+ assertEquals(t*60*60,
+ TimeUnit.HOURS.toSeconds(t));
+ assertEquals(t*60,
+ TimeUnit.MINUTES.toSeconds(t));
+ assertEquals(t,
+ TimeUnit.SECONDS.toSeconds(t));
+ assertEquals(t,
+ TimeUnit.MILLISECONDS.toSeconds(t*1000L));
+ assertEquals(t,
+ TimeUnit.MICROSECONDS.toSeconds(t*1000000L));
+ assertEquals(t,
+ TimeUnit.NANOSECONDS.toSeconds(t*1000000000L));
+ }
+ }
+
+ /**
+ * toMinutes correctly converts sample values in different units to
+ * minutes
+ */
+ public void testToMinutes() {
+ for (long t = 0; t < 88888; ++t) {
+ assertEquals(t*60*24,
+ TimeUnit.DAYS.toMinutes(t));
+ assertEquals(t*60,
+ TimeUnit.HOURS.toMinutes(t));
+ assertEquals(t,
+ TimeUnit.MINUTES.toMinutes(t));
+ assertEquals(t,
+ TimeUnit.SECONDS.toMinutes(t*60));
+ assertEquals(t,
+ TimeUnit.MILLISECONDS.toMinutes(t*1000L*60));
+ assertEquals(t,
+ TimeUnit.MICROSECONDS.toMinutes(t*1000000L*60));
+ assertEquals(t,
+ TimeUnit.NANOSECONDS.toMinutes(t*1000000000L*60));
+ }
+ }
+
+ /**
+ * toHours correctly converts sample values in different units to
+ * hours
+ */
+ public void testToHours() {
+ for (long t = 0; t < 88888; ++t) {
+ assertEquals(t*24,
+ TimeUnit.DAYS.toHours(t));
+ assertEquals(t,
+ TimeUnit.HOURS.toHours(t));
+ assertEquals(t,
+ TimeUnit.MINUTES.toHours(t*60));
+ assertEquals(t,
+ TimeUnit.SECONDS.toHours(t*60*60));
+ assertEquals(t,
+ TimeUnit.MILLISECONDS.toHours(t*1000L*60*60));
+ assertEquals(t,
+ TimeUnit.MICROSECONDS.toHours(t*1000000L*60*60));
+ assertEquals(t,
+ TimeUnit.NANOSECONDS.toHours(t*1000000000L*60*60));
+ }
+ }
+
+ /**
+ * toDays correctly converts sample values in different units to
+ * days
+ */
+ public void testToDays() {
+ for (long t = 0; t < 88888; ++t) {
+ assertEquals(t,
+ TimeUnit.DAYS.toDays(t));
+ assertEquals(t,
+ TimeUnit.HOURS.toDays(t*24));
+ assertEquals(t,
+ TimeUnit.MINUTES.toDays(t*60*24));
+ assertEquals(t,
+ TimeUnit.SECONDS.toDays(t*60*60*24));
+ assertEquals(t,
+ TimeUnit.MILLISECONDS.toDays(t*1000L*60*60*24));
+ assertEquals(t,
+ TimeUnit.MICROSECONDS.toDays(t*1000000L*60*60*24));
+ assertEquals(t,
+ TimeUnit.NANOSECONDS.toDays(t*1000000000L*60*60*24));
+ }
+ }
+
+ /**
+ * convert saturates positive too-large values to Long.MAX_VALUE
+ * and negative to LONG.MIN_VALUE
+ */
+ public void testConvertSaturate() {
+ assertEquals(Long.MAX_VALUE,
+ TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2,
+ TimeUnit.SECONDS));
+ assertEquals(Long.MIN_VALUE,
+ TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
+ TimeUnit.SECONDS));
+ assertEquals(Long.MAX_VALUE,
+ TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2,
+ TimeUnit.MINUTES));
+ assertEquals(Long.MIN_VALUE,
+ TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
+ TimeUnit.MINUTES));
+ assertEquals(Long.MAX_VALUE,
+ TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2,
+ TimeUnit.HOURS));
+ assertEquals(Long.MIN_VALUE,
+ TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
+ TimeUnit.HOURS));
+ assertEquals(Long.MAX_VALUE,
+ TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2,
+ TimeUnit.DAYS));
+ assertEquals(Long.MIN_VALUE,
+ TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
+ TimeUnit.DAYS));
+ }
+
+ /**
+ * toNanos saturates positive too-large values to Long.MAX_VALUE
+ * and negative to LONG.MIN_VALUE
+ */
+ public void testToNanosSaturate() {
+ assertEquals(Long.MAX_VALUE,
+ TimeUnit.MILLISECONDS.toNanos(Long.MAX_VALUE / 2));
+ assertEquals(Long.MIN_VALUE,
+ TimeUnit.MILLISECONDS.toNanos(-Long.MAX_VALUE / 3));
+ }
+
+ /**
+ * toString returns name of unit
+ */
+ public void testToString() {
+ assertEquals("SECONDS", TimeUnit.SECONDS.toString());
+ }
+
+ /**
+ * name returns name of unit
+ */
+ public void testName() {
+ assertEquals("SECONDS", TimeUnit.SECONDS.name());
+ }
+
+ /**
+ * Timed wait without holding lock throws
+ * IllegalMonitorStateException
+ */
+ public void testTimedWait_IllegalMonitorException() {
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ Object o = new Object();
+ TimeUnit tu = TimeUnit.MILLISECONDS;
+
+ try {
+ tu.timedWait(o, LONG_DELAY_MS);
+ threadShouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * timedWait throws InterruptedException when interrupted
+ */
+ public void testTimedWait_Interruptible() {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ Object o = new Object();
+ TimeUnit tu = TimeUnit.MILLISECONDS;
+
+ Thread.currentThread().interrupt();
+ try {
+ synchronized (o) {
+ tu.timedWait(o, LONG_DELAY_MS);
+ }
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ synchronized (o) {
+ tu.timedWait(o, LONG_DELAY_MS);
+ }
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * timedJoin throws InterruptedException when interrupted
+ */
+ public void testTimedJoin_Interruptible() {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ final Thread s = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ Thread.sleep(LONG_DELAY_MS);
+ }});
+ final Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ TimeUnit tu = TimeUnit.MILLISECONDS;
+ Thread.currentThread().interrupt();
+ try {
+ tu.timedJoin(s, LONG_DELAY_MS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ tu.timedJoin(s, LONG_DELAY_MS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ s.interrupt();
+ awaitTermination(s);
+ }
+
+ /**
+ * timedSleep throws InterruptedException when interrupted
+ */
+ public void testTimedSleep_Interruptible() {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ TimeUnit tu = TimeUnit.MILLISECONDS;
+ Thread.currentThread().interrupt();
+ try {
+ tu.sleep(LONG_DELAY_MS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ tu.sleep(LONG_DELAY_MS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * a deserialized serialized unit is the same instance
+ */
+ public void testSerialization() throws Exception {
+ TimeUnit x = TimeUnit.MILLISECONDS;
+ assertSame(x, serialClone(x));
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/TreeMapTest.java b/jsr166-tests/src/test/java/jsr166/TreeMapTest.java
new file mode 100644
index 0000000..87baa1a
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/TreeMapTest.java
@@ -0,0 +1,1068 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+
+public class TreeMapTest extends JSR166TestCase {
+
+ /**
+ * Returns a new map from Integers 1-5 to Strings "A"-"E".
+ */
+ private static TreeMap map5() {
+ TreeMap map = new TreeMap();
+ assertTrue(map.isEmpty());
+ map.put(one, "A");
+ map.put(five, "E");
+ map.put(three, "C");
+ map.put(two, "B");
+ map.put(four, "D");
+ assertFalse(map.isEmpty());
+ assertEquals(5, map.size());
+ return map;
+ }
+
+ /**
+ * clear removes all pairs
+ */
+ public void testClear() {
+ TreeMap map = map5();
+ map.clear();
+ assertEquals(0, map.size());
+ }
+
+ /**
+ * copy constructor creates map equal to source map
+ */
+ public void testConstructFromSorted() {
+ TreeMap map = map5();
+ TreeMap map2 = new TreeMap(map);
+ assertEquals(map, map2);
+ }
+
+ /**
+ * Maps with same contents are equal
+ */
+ public void testEquals() {
+ TreeMap map1 = map5();
+ TreeMap map2 = map5();
+ assertEquals(map1, map2);
+ assertEquals(map2, map1);
+ map1.clear();
+ assertFalse(map1.equals(map2));
+ assertFalse(map2.equals(map1));
+ }
+
+ /**
+ * containsKey returns true for contained key
+ */
+ public void testContainsKey() {
+ TreeMap map = map5();
+ assertTrue(map.containsKey(one));
+ assertFalse(map.containsKey(zero));
+ }
+
+ /**
+ * containsValue returns true for held values
+ */
+ public void testContainsValue() {
+ TreeMap map = map5();
+ assertTrue(map.containsValue("A"));
+ assertFalse(map.containsValue("Z"));
+ }
+
+ /**
+ * get returns the correct element at the given key,
+ * or null if not present
+ */
+ public void testGet() {
+ TreeMap map = map5();
+ assertEquals("A", (String)map.get(one));
+ TreeMap empty = new TreeMap();
+ assertNull(empty.get(one));
+ }
+
+ /**
+ * isEmpty is true of empty map and false for non-empty
+ */
+ public void testIsEmpty() {
+ TreeMap empty = new TreeMap();
+ TreeMap map = map5();
+ assertTrue(empty.isEmpty());
+ assertFalse(map.isEmpty());
+ }
+
+ /**
+ * firstKey returns first key
+ */
+ public void testFirstKey() {
+ TreeMap map = map5();
+ assertEquals(one, map.firstKey());
+ }
+
+ /**
+ * lastKey returns last key
+ */
+ public void testLastKey() {
+ TreeMap map = map5();
+ assertEquals(five, map.lastKey());
+ }
+
+ /**
+ * keySet.toArray returns contains all keys
+ */
+ public void testKeySetToArray() {
+ TreeMap map = map5();
+ Set s = map.keySet();
+ Object[] ar = s.toArray();
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ assertEquals(5, ar.length);
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * descendingkeySet.toArray returns contains all keys
+ */
+ public void testDescendingKeySetToArray() {
+ TreeMap map = map5();
+ Set s = map.descendingKeySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * keySet returns a Set containing all the keys
+ */
+ public void testKeySet() {
+ TreeMap map = map5();
+ Set s = map.keySet();
+ assertEquals(5, s.size());
+ assertTrue(s.contains(one));
+ assertTrue(s.contains(two));
+ assertTrue(s.contains(three));
+ assertTrue(s.contains(four));
+ assertTrue(s.contains(five));
+ }
+
+ /**
+ * keySet is ordered
+ */
+ public void testKeySetOrder() {
+ TreeMap map = map5();
+ Set s = map.keySet();
+ Iterator i = s.iterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, one);
+ int count = 1;
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) < 0);
+ last = k;
+ ++count;
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * descending iterator of key set is inverse ordered
+ */
+ public void testKeySetDescendingIteratorOrder() {
+ TreeMap map = map5();
+ NavigableSet s = map.navigableKeySet();
+ Iterator i = s.descendingIterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, five);
+ int count = 1;
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) > 0);
+ last = k;
+ ++count;
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * descendingKeySet is ordered
+ */
+ public void testDescendingKeySetOrder() {
+ TreeMap map = map5();
+ Set s = map.descendingKeySet();
+ Iterator i = s.iterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, five);
+ int count = 1;
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) > 0);
+ last = k;
+ ++count;
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * descending iterator of descendingKeySet is ordered
+ */
+ public void testDescendingKeySetDescendingIteratorOrder() {
+ TreeMap map = map5();
+ NavigableSet s = map.descendingKeySet();
+ Iterator i = s.descendingIterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, one);
+ int count = 1;
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) < 0);
+ last = k;
+ ++count;
+ }
+ assertEquals(5, count);
+ }
+
+ /**
+ * values collection contains all values
+ */
+ public void testValues() {
+ TreeMap map = map5();
+ Collection s = map.values();
+ assertEquals(5, s.size());
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * entrySet contains all pairs
+ */
+ public void testEntrySet() {
+ TreeMap map = map5();
+ Set s = map.entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(one) && e.getValue().equals("A")) ||
+ (e.getKey().equals(two) && e.getValue().equals("B")) ||
+ (e.getKey().equals(three) && e.getValue().equals("C")) ||
+ (e.getKey().equals(four) && e.getValue().equals("D")) ||
+ (e.getKey().equals(five) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * descendingEntrySet contains all pairs
+ */
+ public void testDescendingEntrySet() {
+ TreeMap map = map5();
+ Set s = map.descendingMap().entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(one) && e.getValue().equals("A")) ||
+ (e.getKey().equals(two) && e.getValue().equals("B")) ||
+ (e.getKey().equals(three) && e.getValue().equals("C")) ||
+ (e.getKey().equals(four) && e.getValue().equals("D")) ||
+ (e.getKey().equals(five) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * entrySet.toArray contains all entries
+ */
+ public void testEntrySetToArray() {
+ TreeMap map = map5();
+ Set s = map.entrySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ for (int i = 0; i < 5; ++i) {
+ assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+ assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+ }
+ }
+
+ /**
+ * descendingEntrySet.toArray contains all entries
+ */
+ public void testDescendingEntrySetToArray() {
+ TreeMap map = map5();
+ Set s = map.descendingMap().entrySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ for (int i = 0; i < 5; ++i) {
+ assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+ assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+ }
+ }
+
+ /**
+ * putAll adds all key-value pairs from the given map
+ */
+ public void testPutAll() {
+ TreeMap empty = new TreeMap();
+ TreeMap map = map5();
+ empty.putAll(map);
+ assertEquals(5, empty.size());
+ assertTrue(empty.containsKey(one));
+ assertTrue(empty.containsKey(two));
+ assertTrue(empty.containsKey(three));
+ assertTrue(empty.containsKey(four));
+ assertTrue(empty.containsKey(five));
+ }
+
+ /**
+ * remove removes the correct key-value pair from the map
+ */
+ public void testRemove() {
+ TreeMap map = map5();
+ map.remove(five);
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(five));
+ }
+
+ /**
+ * lowerEntry returns preceding entry.
+ */
+ public void testLowerEntry() {
+ TreeMap map = map5();
+ Map.Entry e1 = map.lowerEntry(three);
+ assertEquals(two, e1.getKey());
+
+ Map.Entry e2 = map.lowerEntry(six);
+ assertEquals(five, e2.getKey());
+
+ Map.Entry e3 = map.lowerEntry(one);
+ assertNull(e3);
+
+ Map.Entry e4 = map.lowerEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higherEntry returns next entry.
+ */
+ public void testHigherEntry() {
+ TreeMap map = map5();
+ Map.Entry e1 = map.higherEntry(three);
+ assertEquals(four, e1.getKey());
+
+ Map.Entry e2 = map.higherEntry(zero);
+ assertEquals(one, e2.getKey());
+
+ Map.Entry e3 = map.higherEntry(five);
+ assertNull(e3);
+
+ Map.Entry e4 = map.higherEntry(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floorEntry returns preceding entry.
+ */
+ public void testFloorEntry() {
+ TreeMap map = map5();
+ Map.Entry e1 = map.floorEntry(three);
+ assertEquals(three, e1.getKey());
+
+ Map.Entry e2 = map.floorEntry(six);
+ assertEquals(five, e2.getKey());
+
+ Map.Entry e3 = map.floorEntry(one);
+ assertEquals(one, e3.getKey());
+
+ Map.Entry e4 = map.floorEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceilingEntry returns next entry.
+ */
+ public void testCeilingEntry() {
+ TreeMap map = map5();
+ Map.Entry e1 = map.ceilingEntry(three);
+ assertEquals(three, e1.getKey());
+
+ Map.Entry e2 = map.ceilingEntry(zero);
+ assertEquals(one, e2.getKey());
+
+ Map.Entry e3 = map.ceilingEntry(five);
+ assertEquals(five, e3.getKey());
+
+ Map.Entry e4 = map.ceilingEntry(six);
+ assertNull(e4);
+ }
+
+ /**
+ * lowerKey returns preceding element
+ */
+ public void testLowerKey() {
+ TreeMap q = map5();
+ Object e1 = q.lowerKey(three);
+ assertEquals(two, e1);
+
+ Object e2 = q.lowerKey(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.lowerKey(one);
+ assertNull(e3);
+
+ Object e4 = q.lowerKey(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higherKey returns next element
+ */
+ public void testHigherKey() {
+ TreeMap q = map5();
+ Object e1 = q.higherKey(three);
+ assertEquals(four, e1);
+
+ Object e2 = q.higherKey(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.higherKey(five);
+ assertNull(e3);
+
+ Object e4 = q.higherKey(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floorKey returns preceding element
+ */
+ public void testFloorKey() {
+ TreeMap q = map5();
+ Object e1 = q.floorKey(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.floorKey(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.floorKey(one);
+ assertEquals(one, e3);
+
+ Object e4 = q.floorKey(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceilingKey returns next element
+ */
+ public void testCeilingKey() {
+ TreeMap q = map5();
+ Object e1 = q.ceilingKey(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.ceilingKey(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.ceilingKey(five);
+ assertEquals(five, e3);
+
+ Object e4 = q.ceilingKey(six);
+ assertNull(e4);
+ }
+
+ /**
+ * pollFirstEntry returns entries in order
+ */
+ public void testPollFirstEntry() {
+ TreeMap map = map5();
+ Map.Entry e = map.pollFirstEntry();
+ assertEquals(one, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(two, e.getKey());
+ map.put(one, "A");
+ e = map.pollFirstEntry();
+ assertEquals(one, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(three, e.getKey());
+ map.remove(four);
+ e = map.pollFirstEntry();
+ assertEquals(five, e.getKey());
+ try {
+ e.setValue("A");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollFirstEntry();
+ assertNull(e);
+ }
+
+ /**
+ * pollLastEntry returns entries in order
+ */
+ public void testPollLastEntry() {
+ TreeMap map = map5();
+ Map.Entry e = map.pollLastEntry();
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(four, e.getKey());
+ map.put(five, "E");
+ e = map.pollLastEntry();
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(three, e.getKey());
+ map.remove(two);
+ e = map.pollLastEntry();
+ assertEquals(one, e.getKey());
+ try {
+ e.setValue("E");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollLastEntry();
+ assertNull(e);
+ }
+
+ /**
+ * size returns the correct values
+ */
+ public void testSize() {
+ TreeMap map = map5();
+ TreeMap empty = new TreeMap();
+ assertEquals(0, empty.size());
+ assertEquals(5, map.size());
+ }
+
+ /**
+ * toString contains toString of elements
+ */
+ public void testToString() {
+ TreeMap map = map5();
+ String s = map.toString();
+ for (int i = 1; i <= 5; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ // Exception tests
+
+ /**
+ * get(null) of nonempty map throws NPE
+ */
+ public void testGet_NullPointerException() {
+ try {
+ TreeMap c = map5();
+ c.get(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsKey(null) of nonempty map throws NPE
+ */
+ public void testContainsKey_NullPointerException() {
+ try {
+ TreeMap c = map5();
+ c.containsKey(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null) throws NPE for nonempty map
+ */
+ public void testRemove1_NullPointerException() {
+ try {
+ TreeMap c = new TreeMap();
+ c.put("sadsdf", "asdads");
+ c.remove(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * A deserialized map equals original
+ */
+ public void testSerialization() throws Exception {
+ NavigableMap x = map5();
+ NavigableMap y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ /**
+ * subMap returns map with keys in requested range
+ */
+ public void testSubMapContents() {
+ TreeMap map = map5();
+ NavigableMap sm = map.subMap(two, true, four, false);
+ assertEquals(two, sm.firstKey());
+ assertEquals(three, sm.lastKey());
+ assertEquals(2, sm.size());
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ Iterator r = sm.descendingKeySet().iterator();
+ k = (Integer)(r.next());
+ assertEquals(three, k);
+ k = (Integer)(r.next());
+ assertEquals(two, k);
+ assertFalse(r.hasNext());
+
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(two));
+ assertEquals(4, map.size());
+ assertEquals(1, sm.size());
+ assertEquals(three, sm.firstKey());
+ assertEquals(three, sm.lastKey());
+ assertEquals("C", sm.remove(three));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, map.size());
+ }
+
+ public void testSubMapContents2() {
+ TreeMap map = map5();
+ NavigableMap sm = map.subMap(two, true, three, false);
+ assertEquals(1, sm.size());
+ assertEquals(two, sm.firstKey());
+ assertEquals(two, sm.lastKey());
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertFalse(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ assertFalse(i.hasNext());
+ Iterator r = sm.descendingKeySet().iterator();
+ k = (Integer)(r.next());
+ assertEquals(two, k);
+ assertFalse(r.hasNext());
+
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(two));
+ assertEquals(4, map.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertSame(sm.remove(three), null);
+ assertEquals(4, map.size());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testHeadMapContents() {
+ TreeMap map = map5();
+ NavigableMap sm = map.headMap(four, false);
+ assertTrue(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(one, k);
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, map.size());
+ assertEquals(four, map.firstKey());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testTailMapContents() {
+ TreeMap map = map5();
+ NavigableMap sm = map.tailMap(two, true);
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertTrue(sm.containsKey(four));
+ assertTrue(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ k = (Integer)(i.next());
+ assertEquals(four, k);
+ k = (Integer)(i.next());
+ assertEquals(five, k);
+ assertFalse(i.hasNext());
+ Iterator r = sm.descendingKeySet().iterator();
+ k = (Integer)(r.next());
+ assertEquals(five, k);
+ k = (Integer)(r.next());
+ assertEquals(four, k);
+ k = (Integer)(r.next());
+ assertEquals(three, k);
+ k = (Integer)(r.next());
+ assertEquals(two, k);
+ assertFalse(r.hasNext());
+
+ Iterator ei = sm.entrySet().iterator();
+ Map.Entry e;
+ e = (Map.Entry)(ei.next());
+ assertEquals(two, e.getKey());
+ assertEquals("B", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(three, e.getKey());
+ assertEquals("C", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(four, e.getKey());
+ assertEquals("D", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ assertFalse(i.hasNext());
+
+ NavigableMap ssm = sm.tailMap(four, true);
+ assertEquals(four, ssm.firstKey());
+ assertEquals(five, ssm.lastKey());
+ assertEquals("D", ssm.remove(four));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, map.size());
+ }
+
+ Random rnd = new Random(666);
+ BitSet bs;
+
+ /**
+ * Submaps of submaps subdivide correctly
+ */
+ public void testRecursiveSubMaps() throws Exception {
+ int mapSize = expensiveTests ? 1000 : 100;
+ Class cl = TreeMap.class;
+ NavigableMap<Integer, Integer> map = newMap(cl);
+ bs = new BitSet(mapSize);
+
+ populate(map, mapSize);
+ check(map, 0, mapSize - 1, true);
+ check(map.descendingMap(), 0, mapSize - 1, false);
+
+ mutateMap(map, 0, mapSize - 1);
+ check(map, 0, mapSize - 1, true);
+ check(map.descendingMap(), 0, mapSize - 1, false);
+
+ bashSubMap(map.subMap(0, true, mapSize, false),
+ 0, mapSize - 1, true);
+ }
+
+ static NavigableMap<Integer, Integer> newMap(Class cl) throws Exception {
+ NavigableMap<Integer, Integer> result
+ = (NavigableMap<Integer, Integer>) cl.newInstance();
+ assertEquals(0, result.size());
+ assertFalse(result.keySet().iterator().hasNext());
+ return result;
+ }
+
+ void populate(NavigableMap<Integer, Integer> map, int limit) {
+ for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+ int key = rnd.nextInt(limit);
+ put(map, key);
+ }
+ }
+
+ void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
+ int size = map.size();
+ int rangeSize = max - min + 1;
+
+ // Remove a bunch of entries directly
+ for (int i = 0, n = rangeSize / 2; i < n; i++) {
+ remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+ }
+
+ // Remove a bunch of entries with iterator
+ for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+ if (rnd.nextBoolean()) {
+ bs.clear(it.next());
+ it.remove();
+ }
+ }
+
+ // Add entries till we're back to original size
+ while (map.size() < size) {
+ int key = min + rnd.nextInt(rangeSize);
+ assertTrue(key >= min && key<= max);
+ put(map, key);
+ }
+ }
+
+ void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
+ int size = map.size();
+ int rangeSize = max - min + 1;
+
+ // Remove a bunch of entries directly
+ for (int i = 0, n = rangeSize / 2; i < n; i++) {
+ remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+ }
+
+ // Remove a bunch of entries with iterator
+ for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+ if (rnd.nextBoolean()) {
+ bs.clear(it.next());
+ it.remove();
+ }
+ }
+
+ // Add entries till we're back to original size
+ while (map.size() < size) {
+ int key = min - 5 + rnd.nextInt(rangeSize + 10);
+ if (key >= min && key<= max) {
+ put(map, key);
+ } else {
+ try {
+ map.put(key, 2 * key);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+ }
+ }
+
+ void put(NavigableMap<Integer, Integer> map, int key) {
+ if (map.put(key, 2 * key) == null)
+ bs.set(key);
+ }
+
+ void remove(NavigableMap<Integer, Integer> map, int key) {
+ if (map.remove(key) != null)
+ bs.clear(key);
+ }
+
+ void bashSubMap(NavigableMap<Integer, Integer> map,
+ int min, int max, boolean ascending) {
+ check(map, min, max, ascending);
+ check(map.descendingMap(), min, max, !ascending);
+
+ mutateSubMap(map, min, max);
+ check(map, min, max, ascending);
+ check(map.descendingMap(), min, max, !ascending);
+
+ // Recurse
+ if (max - min < 2)
+ return;
+ int midPoint = (min + max) / 2;
+
+ // headMap - pick direction and endpoint inclusion randomly
+ boolean incl = rnd.nextBoolean();
+ NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
+ if (ascending) {
+ if (rnd.nextBoolean())
+ bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
+ else
+ bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+ false);
+ } else {
+ if (rnd.nextBoolean())
+ bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
+ else
+ bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+ true);
+ }
+
+ // tailMap - pick direction and endpoint inclusion randomly
+ incl = rnd.nextBoolean();
+ NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
+ if (ascending) {
+ if (rnd.nextBoolean())
+ bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
+ else
+ bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+ false);
+ } else {
+ if (rnd.nextBoolean()) {
+ bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
+ } else {
+ bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+ true);
+ }
+ }
+
+ // subMap - pick direction and endpoint inclusion randomly
+ int rangeSize = max - min + 1;
+ int[] endpoints = new int[2];
+ endpoints[0] = min + rnd.nextInt(rangeSize);
+ endpoints[1] = min + rnd.nextInt(rangeSize);
+ Arrays.sort(endpoints);
+ boolean lowIncl = rnd.nextBoolean();
+ boolean highIncl = rnd.nextBoolean();
+ if (ascending) {
+ NavigableMap<Integer,Integer> sm = map.subMap(
+ endpoints[0], lowIncl, endpoints[1], highIncl);
+ if (rnd.nextBoolean())
+ bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), true);
+ else
+ bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), false);
+ } else {
+ NavigableMap<Integer,Integer> sm = map.subMap(
+ endpoints[1], highIncl, endpoints[0], lowIncl);
+ if (rnd.nextBoolean())
+ bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), false);
+ else
+ bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), true);
+ }
+ }
+
+ /**
+ * min and max are both inclusive. If max < min, interval is empty.
+ */
+ void check(NavigableMap<Integer, Integer> map,
+ final int min, final int max, final boolean ascending) {
+ class ReferenceSet {
+ int lower(int key) {
+ return ascending ? lowerAscending(key) : higherAscending(key);
+ }
+ int floor(int key) {
+ return ascending ? floorAscending(key) : ceilingAscending(key);
+ }
+ int ceiling(int key) {
+ return ascending ? ceilingAscending(key) : floorAscending(key);
+ }
+ int higher(int key) {
+ return ascending ? higherAscending(key) : lowerAscending(key);
+ }
+ int first() {
+ return ascending ? firstAscending() : lastAscending();
+ }
+ int last() {
+ return ascending ? lastAscending() : firstAscending();
+ }
+ int lowerAscending(int key) {
+ return floorAscending(key - 1);
+ }
+ int floorAscending(int key) {
+ if (key < min)
+ return -1;
+ else if (key > max)
+ key = max;
+
+ // BitSet should support this! Test would run much faster
+ while (key >= min) {
+ if (bs.get(key))
+ return key;
+ key--;
+ }
+ return -1;
+ }
+ int ceilingAscending(int key) {
+ if (key < min)
+ key = min;
+ else if (key > max)
+ return -1;
+ int result = bs.nextSetBit(key);
+ return result > max ? -1 : result;
+ }
+ int higherAscending(int key) {
+ return ceilingAscending(key + 1);
+ }
+ private int firstAscending() {
+ int result = ceilingAscending(min);
+ return result > max ? -1 : result;
+ }
+ private int lastAscending() {
+ int result = floorAscending(max);
+ return result < min ? -1 : result;
+ }
+ }
+ ReferenceSet rs = new ReferenceSet();
+
+ // Test contents using containsKey
+ int size = 0;
+ for (int i = min; i <= max; i++) {
+ boolean bsContainsI = bs.get(i);
+ assertEquals(bsContainsI, map.containsKey(i));
+ if (bsContainsI)
+ size++;
+ }
+ assertEquals(size, map.size());
+
+ // Test contents using contains keySet iterator
+ int size2 = 0;
+ int previousKey = -1;
+ for (int key : map.keySet()) {
+ assertTrue(bs.get(key));
+ size2++;
+ assertTrue(previousKey < 0 ||
+ (ascending ? key - previousKey > 0 : key - previousKey < 0));
+ previousKey = key;
+ }
+ assertEquals(size2, size);
+
+ // Test navigation ops
+ for (int key = min - 1; key <= max + 1; key++) {
+ assertEq(map.lowerKey(key), rs.lower(key));
+ assertEq(map.floorKey(key), rs.floor(key));
+ assertEq(map.higherKey(key), rs.higher(key));
+ assertEq(map.ceilingKey(key), rs.ceiling(key));
+ }
+
+ // Test extrema
+ if (map.size() != 0) {
+ assertEq(map.firstKey(), rs.first());
+ assertEq(map.lastKey(), rs.last());
+ } else {
+ assertEq(rs.first(), -1);
+ assertEq(rs.last(), -1);
+ try {
+ map.firstKey();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ try {
+ map.lastKey();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+ }
+
+ static void assertEq(Integer i, int j) {
+ if (i == null)
+ assertEquals(j, -1);
+ else
+ assertEquals((int) i, j);
+ }
+
+ static boolean eq(Integer i, int j) {
+ return i == null ? j == -1 : i == j;
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/TreeSetTest.java b/jsr166-tests/src/test/java/jsr166/TreeSetTest.java
new file mode 100644
index 0000000..2957019
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/TreeSetTest.java
@@ -0,0 +1,985 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+public class TreeSetTest extends JSR166TestCase {
+
+ static class MyReverseComparator implements Comparator {
+ public int compare(Object x, Object y) {
+ return ((Comparable)y).compareTo(x);
+ }
+ }
+
+ /**
+ * The number of elements to place in collections, arrays, etc.
+ */
+ static final int SIZE = 20;
+
+ /**
+ * Returns a new set of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private TreeSet<Integer> populatedSet(int n) {
+ TreeSet<Integer> q = new TreeSet<Integer>();
+ assertTrue(q.isEmpty());
+ for (int i = n-1; i >= 0; i-=2)
+ assertTrue(q.add(new Integer(i)));
+ for (int i = (n & 1); i < n; i+=2)
+ assertTrue(q.add(new Integer(i)));
+ assertFalse(q.isEmpty());
+ assertEquals(n, q.size());
+ return q;
+ }
+
+ /**
+ * Returns a new set of first 5 ints.
+ */
+ private TreeSet set5() {
+ TreeSet q = new TreeSet();
+ assertTrue(q.isEmpty());
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ q.add(four);
+ q.add(five);
+ assertEquals(5, q.size());
+ return q;
+ }
+
+ /**
+ * A new set has unbounded capacity
+ */
+ public void testConstructor1() {
+ assertEquals(0, new TreeSet().size());
+ }
+
+ /**
+ * Initializing from null Collection throws NPE
+ */
+ public void testConstructor3() {
+ try {
+ TreeSet q = new TreeSet((Collection)null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection of null elements throws NPE
+ */
+ public void testConstructor4() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ TreeSet q = new TreeSet(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Initializing from Collection with some null elements throws NPE
+ */
+ public void testConstructor5() {
+ try {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ TreeSet q = new TreeSet(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Set contains all elements of collection used to initialize
+ */
+ public void testConstructor6() {
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ TreeSet q = new TreeSet(Arrays.asList(ints));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(ints[i], q.pollFirst());
+ }
+
+ /**
+ * The comparator used in constructor is used
+ */
+ public void testConstructor7() {
+ MyReverseComparator cmp = new MyReverseComparator();
+ TreeSet q = new TreeSet(cmp);
+ assertEquals(cmp, q.comparator());
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ for (int i = SIZE-1; i >= 0; --i)
+ assertEquals(ints[i], q.pollFirst());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ TreeSet q = new TreeSet();
+ assertTrue(q.isEmpty());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.add(new Integer(2));
+ q.pollFirst();
+ q.pollFirst();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ TreeSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.pollFirst();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * add(null) throws NPE if nonempty
+ */
+ public void testAddNull() {
+ try {
+ TreeSet q = populatedSet(SIZE);
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Add of comparable element succeeds
+ */
+ public void testAdd() {
+ TreeSet q = new TreeSet();
+ assertTrue(q.add(zero));
+ assertTrue(q.add(one));
+ }
+
+ /**
+ * Add of duplicate element fails
+ */
+ public void testAddDup() {
+ TreeSet q = new TreeSet();
+ assertTrue(q.add(zero));
+ assertFalse(q.add(zero));
+ }
+
+ /**
+ * Add of non-Comparable throws CCE
+ */
+ public void testAddNonComparable() {
+ try {
+ TreeSet q = new TreeSet();
+ q.add(new Object());
+ q.add(new Object());
+ q.add(new Object());
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ TreeSet q = new TreeSet();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ TreeSet q = new TreeSet();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ TreeSet q = new TreeSet();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Set contains all elements of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(SIZE-1-i);
+ TreeSet q = new TreeSet();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(new Integer(i), q.pollFirst());
+ }
+
+ /**
+ * pollFirst succeeds unless empty
+ */
+ public void testPollFirst() {
+ TreeSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * pollLast succeeds unless empty
+ */
+ public void testPollLast() {
+ TreeSet q = populatedSet(SIZE);
+ for (int i = SIZE-1; i >= 0; --i) {
+ assertEquals(i, q.pollLast());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ TreeSet q = populatedSet(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove(i+1));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ TreeSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.pollFirst();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ TreeSet q = populatedSet(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ q.add(new Integer(1));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ TreeSet q = populatedSet(SIZE);
+ TreeSet p = new TreeSet();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ TreeSet q = populatedSet(SIZE);
+ TreeSet p = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.pollFirst();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ TreeSet q = populatedSet(SIZE);
+ TreeSet p = populatedSet(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.pollFirst());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * lower returns preceding element
+ */
+ public void testLower() {
+ TreeSet q = set5();
+ Object e1 = q.lower(three);
+ assertEquals(two, e1);
+
+ Object e2 = q.lower(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.lower(one);
+ assertNull(e3);
+
+ Object e4 = q.lower(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higher returns next element
+ */
+ public void testHigher() {
+ TreeSet q = set5();
+ Object e1 = q.higher(three);
+ assertEquals(four, e1);
+
+ Object e2 = q.higher(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.higher(five);
+ assertNull(e3);
+
+ Object e4 = q.higher(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floor returns preceding element
+ */
+ public void testFloor() {
+ TreeSet q = set5();
+ Object e1 = q.floor(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.floor(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.floor(one);
+ assertEquals(one, e3);
+
+ Object e4 = q.floor(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceiling returns next element
+ */
+ public void testCeiling() {
+ TreeSet q = set5();
+ Object e1 = q.ceiling(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.ceiling(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.ceiling(five);
+ assertEquals(five, e3);
+
+ Object e4 = q.ceiling(six);
+ assertNull(e4);
+ }
+
+ /**
+ * toArray contains all elements in sorted order
+ */
+ public void testToArray() {
+ TreeSet q = populatedSet(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.pollFirst());
+ }
+
+ /**
+ * toArray(a) contains all elements in sorted order
+ */
+ public void testToArray2() {
+ TreeSet<Integer> q = populatedSet(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.pollFirst());
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ TreeSet q = populatedSet(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator of empty set has no elements
+ */
+ public void testEmptyIterator() {
+ TreeSet q = new TreeSet();
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(0, i);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final TreeSet q = new TreeSet();
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ q.add(new Integer(3));
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertEquals(it.next(), new Integer(2));
+ assertEquals(it.next(), new Integer(3));
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ TreeSet q = populatedSet(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized set has same elements
+ */
+ public void testSerialization() throws Exception {
+ NavigableSet x = populatedSet(SIZE);
+ NavigableSet y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.pollFirst(), y.pollFirst());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * subSet returns set with keys in requested range
+ */
+ public void testSubSetContents() {
+ TreeSet set = set5();
+ SortedSet sm = set.subSet(two, four);
+ assertEquals(two, sm.first());
+ assertEquals(three, sm.last());
+ assertEquals(2, sm.size());
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(two));
+ assertEquals(4, set.size());
+ assertEquals(1, sm.size());
+ assertEquals(three, sm.first());
+ assertEquals(three, sm.last());
+ assertTrue(sm.remove(three));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, set.size());
+ }
+
+ public void testSubSetContents2() {
+ TreeSet set = set5();
+ SortedSet sm = set.subSet(two, three);
+ assertEquals(1, sm.size());
+ assertEquals(two, sm.first());
+ assertEquals(two, sm.last());
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertFalse(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(two));
+ assertEquals(4, set.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertFalse(sm.remove(three));
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * headSet returns set with keys in requested range
+ */
+ public void testHeadSetContents() {
+ TreeSet set = set5();
+ SortedSet sm = set.headSet(four);
+ assertTrue(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(one, k);
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, set.size());
+ assertEquals(four, set.first());
+ }
+
+ /**
+ * tailSet returns set with keys in requested range
+ */
+ public void testTailSetContents() {
+ TreeSet set = set5();
+ SortedSet sm = set.tailSet(two);
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertTrue(sm.contains(four));
+ assertTrue(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ k = (Integer)(i.next());
+ assertEquals(four, k);
+ k = (Integer)(i.next());
+ assertEquals(five, k);
+ assertFalse(i.hasNext());
+
+ SortedSet ssm = sm.tailSet(four);
+ assertEquals(four, ssm.first());
+ assertEquals(five, ssm.last());
+ assertTrue(ssm.remove(four));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, set.size());
+ }
+
+ Random rnd = new Random(666);
+ BitSet bs;
+
+ /**
+ * Subsets of subsets subdivide correctly
+ */
+ public void testRecursiveSubSets() throws Exception {
+ int setSize = expensiveTests ? 1000 : 100;
+ Class cl = TreeSet.class;
+
+ NavigableSet<Integer> set = newSet(cl);
+ bs = new BitSet(setSize);
+
+ populate(set, setSize);
+ check(set, 0, setSize - 1, true);
+ check(set.descendingSet(), 0, setSize - 1, false);
+
+ mutateSet(set, 0, setSize - 1);
+ check(set, 0, setSize - 1, true);
+ check(set.descendingSet(), 0, setSize - 1, false);
+
+ bashSubSet(set.subSet(0, true, setSize, false),
+ 0, setSize - 1, true);
+ }
+
+ /**
+ * addAll is idempotent
+ */
+ public void testAddAll_idempotent() throws Exception {
+ Set x = populatedSet(SIZE);
+ Set y = new TreeSet(x);
+ y.addAll(x);
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ static NavigableSet<Integer> newSet(Class cl) throws Exception {
+ NavigableSet<Integer> result = (NavigableSet<Integer>) cl.newInstance();
+ assertEquals(0, result.size());
+ assertFalse(result.iterator().hasNext());
+ return result;
+ }
+
+ void populate(NavigableSet<Integer> set, int limit) {
+ for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+ int element = rnd.nextInt(limit);
+ put(set, element);
+ }
+ }
+
+ void mutateSet(NavigableSet<Integer> set, int min, int max) {
+ int size = set.size();
+ int rangeSize = max - min + 1;
+
+ // Remove a bunch of entries directly
+ for (int i = 0, n = rangeSize / 2; i < n; i++) {
+ remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
+ }
+
+ // Remove a bunch of entries with iterator
+ for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+ if (rnd.nextBoolean()) {
+ bs.clear(it.next());
+ it.remove();
+ }
+ }
+
+ // Add entries till we're back to original size
+ while (set.size() < size) {
+ int element = min + rnd.nextInt(rangeSize);
+ assertTrue(element >= min && element<= max);
+ put(set, element);
+ }
+ }
+
+ void mutateSubSet(NavigableSet<Integer> set, int min, int max) {
+ int size = set.size();
+ int rangeSize = max - min + 1;
+
+ // Remove a bunch of entries directly
+ for (int i = 0, n = rangeSize / 2; i < n; i++) {
+ remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
+ }
+
+ // Remove a bunch of entries with iterator
+ for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+ if (rnd.nextBoolean()) {
+ bs.clear(it.next());
+ it.remove();
+ }
+ }
+
+ // Add entries till we're back to original size
+ while (set.size() < size) {
+ int element = min - 5 + rnd.nextInt(rangeSize + 10);
+ if (element >= min && element<= max) {
+ put(set, element);
+ } else {
+ try {
+ set.add(element);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {}
+ }
+ }
+ }
+
+ void put(NavigableSet<Integer> set, int element) {
+ if (set.add(element))
+ bs.set(element);
+ }
+
+ void remove(NavigableSet<Integer> set, int element) {
+ if (set.remove(element))
+ bs.clear(element);
+ }
+
+ void bashSubSet(NavigableSet<Integer> set,
+ int min, int max, boolean ascending) {
+ check(set, min, max, ascending);
+ check(set.descendingSet(), min, max, !ascending);
+
+ mutateSubSet(set, min, max);
+ check(set, min, max, ascending);
+ check(set.descendingSet(), min, max, !ascending);
+
+ // Recurse
+ if (max - min < 2)
+ return;
+ int midPoint = (min + max) / 2;
+
+ // headSet - pick direction and endpoint inclusion randomly
+ boolean incl = rnd.nextBoolean();
+ NavigableSet<Integer> hm = set.headSet(midPoint, incl);
+ if (ascending) {
+ if (rnd.nextBoolean())
+ bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true);
+ else
+ bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+ false);
+ } else {
+ if (rnd.nextBoolean())
+ bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false);
+ else
+ bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+ true);
+ }
+
+ // tailSet - pick direction and endpoint inclusion randomly
+ incl = rnd.nextBoolean();
+ NavigableSet<Integer> tm = set.tailSet(midPoint,incl);
+ if (ascending) {
+ if (rnd.nextBoolean())
+ bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true);
+ else
+ bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+ false);
+ } else {
+ if (rnd.nextBoolean()) {
+ bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false);
+ } else {
+ bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+ true);
+ }
+ }
+
+ // subSet - pick direction and endpoint inclusion randomly
+ int rangeSize = max - min + 1;
+ int[] endpoints = new int[2];
+ endpoints[0] = min + rnd.nextInt(rangeSize);
+ endpoints[1] = min + rnd.nextInt(rangeSize);
+ Arrays.sort(endpoints);
+ boolean lowIncl = rnd.nextBoolean();
+ boolean highIncl = rnd.nextBoolean();
+ if (ascending) {
+ NavigableSet<Integer> sm = set.subSet(
+ endpoints[0], lowIncl, endpoints[1], highIncl);
+ if (rnd.nextBoolean())
+ bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), true);
+ else
+ bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), false);
+ } else {
+ NavigableSet<Integer> sm = set.subSet(
+ endpoints[1], highIncl, endpoints[0], lowIncl);
+ if (rnd.nextBoolean())
+ bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), false);
+ else
+ bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+ endpoints[1] - (highIncl ? 0 : 1), true);
+ }
+ }
+
+ /**
+ * min and max are both inclusive. If max < min, interval is empty.
+ */
+ void check(NavigableSet<Integer> set,
+ final int min, final int max, final boolean ascending) {
+ class ReferenceSet {
+ int lower(int element) {
+ return ascending ?
+ lowerAscending(element) : higherAscending(element);
+ }
+ int floor(int element) {
+ return ascending ?
+ floorAscending(element) : ceilingAscending(element);
+ }
+ int ceiling(int element) {
+ return ascending ?
+ ceilingAscending(element) : floorAscending(element);
+ }
+ int higher(int element) {
+ return ascending ?
+ higherAscending(element) : lowerAscending(element);
+ }
+ int first() {
+ return ascending ? firstAscending() : lastAscending();
+ }
+ int last() {
+ return ascending ? lastAscending() : firstAscending();
+ }
+ int lowerAscending(int element) {
+ return floorAscending(element - 1);
+ }
+ int floorAscending(int element) {
+ if (element < min)
+ return -1;
+ else if (element > max)
+ element = max;
+
+ // BitSet should support this! Test would run much faster
+ while (element >= min) {
+ if (bs.get(element))
+ return element;
+ element--;
+ }
+ return -1;
+ }
+ int ceilingAscending(int element) {
+ if (element < min)
+ element = min;
+ else if (element > max)
+ return -1;
+ int result = bs.nextSetBit(element);
+ return result > max ? -1 : result;
+ }
+ int higherAscending(int element) {
+ return ceilingAscending(element + 1);
+ }
+ private int firstAscending() {
+ int result = ceilingAscending(min);
+ return result > max ? -1 : result;
+ }
+ private int lastAscending() {
+ int result = floorAscending(max);
+ return result < min ? -1 : result;
+ }
+ }
+ ReferenceSet rs = new ReferenceSet();
+
+ // Test contents using containsElement
+ int size = 0;
+ for (int i = min; i <= max; i++) {
+ boolean bsContainsI = bs.get(i);
+ assertEquals(bsContainsI, set.contains(i));
+ if (bsContainsI)
+ size++;
+ }
+ assertEquals(size, set.size());
+
+ // Test contents using contains elementSet iterator
+ int size2 = 0;
+ int previousElement = -1;
+ for (int element : set) {
+ assertTrue(bs.get(element));
+ size2++;
+ assertTrue(previousElement < 0 || (ascending ?
+ element - previousElement > 0 : element - previousElement < 0));
+ previousElement = element;
+ }
+ assertEquals(size2, size);
+
+ // Test navigation ops
+ for (int element = min - 1; element <= max + 1; element++) {
+ assertEq(set.lower(element), rs.lower(element));
+ assertEq(set.floor(element), rs.floor(element));
+ assertEq(set.higher(element), rs.higher(element));
+ assertEq(set.ceiling(element), rs.ceiling(element));
+ }
+
+ // Test extrema
+ if (set.size() != 0) {
+ assertEq(set.first(), rs.first());
+ assertEq(set.last(), rs.last());
+ } else {
+ assertEq(rs.first(), -1);
+ assertEq(rs.last(), -1);
+ try {
+ set.first();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ try {
+ set.last();
+ shouldThrow();
+ } catch (NoSuchElementException success) {}
+ }
+ }
+
+ static void assertEq(Integer i, int j) {
+ if (i == null)
+ assertEquals(j, -1);
+ else
+ assertEquals((int) i, j);
+ }
+
+ static boolean eq(Integer i, int j) {
+ return i == null ? j == -1 : i == j;
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java b/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java
new file mode 100644
index 0000000..17201f3
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java
@@ -0,0 +1,1097 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.*;
+
+public class TreeSubMapTest extends JSR166TestCase {
+
+ /**
+ * Returns a new map from Integers 1-5 to Strings "A"-"E".
+ */
+ private static NavigableMap map5() {
+ TreeMap map = new TreeMap();
+ assertTrue(map.isEmpty());
+ map.put(zero, "Z");
+ map.put(one, "A");
+ map.put(five, "E");
+ map.put(three, "C");
+ map.put(two, "B");
+ map.put(four, "D");
+ map.put(seven, "F");
+ assertFalse(map.isEmpty());
+ assertEquals(7, map.size());
+ return map.subMap(one, true, seven, false);
+ }
+
+ private static NavigableMap map0() {
+ TreeMap map = new TreeMap();
+ assertTrue(map.isEmpty());
+ return map.tailMap(one, true);
+ }
+
+ /**
+ * Returns a new map from Integers -5 to -1 to Strings "A"-"E".
+ */
+ private static NavigableMap dmap5() {
+ TreeMap map = new TreeMap();
+ assertTrue(map.isEmpty());
+ map.put(m1, "A");
+ map.put(m5, "E");
+ map.put(m3, "C");
+ map.put(m2, "B");
+ map.put(m4, "D");
+ assertFalse(map.isEmpty());
+ assertEquals(5, map.size());
+ return map.descendingMap();
+ }
+
+ private static NavigableMap dmap0() {
+ TreeMap map = new TreeMap();
+ assertTrue(map.isEmpty());
+ return map;
+ }
+
+ /**
+ * clear removes all pairs
+ */
+ public void testClear() {
+ NavigableMap map = map5();
+ map.clear();
+ assertEquals(0, map.size());
+ }
+
+ /**
+ * Maps with same contents are equal
+ */
+ public void testEquals() {
+ NavigableMap map1 = map5();
+ NavigableMap map2 = map5();
+ assertEquals(map1, map2);
+ assertEquals(map2, map1);
+ map1.clear();
+ assertFalse(map1.equals(map2));
+ assertFalse(map2.equals(map1));
+ }
+
+ /**
+ * containsKey returns true for contained key
+ */
+ public void testContainsKey() {
+ NavigableMap map = map5();
+ assertTrue(map.containsKey(one));
+ assertFalse(map.containsKey(zero));
+ }
+
+ /**
+ * containsValue returns true for held values
+ */
+ public void testContainsValue() {
+ NavigableMap map = map5();
+ assertTrue(map.containsValue("A"));
+ assertFalse(map.containsValue("Z"));
+ }
+
+ /**
+ * get returns the correct element at the given key,
+ * or null if not present
+ */
+ public void testGet() {
+ NavigableMap map = map5();
+ assertEquals("A", (String)map.get(one));
+ NavigableMap empty = map0();
+ assertNull(empty.get(one));
+ }
+
+ /**
+ * isEmpty is true of empty map and false for non-empty
+ */
+ public void testIsEmpty() {
+ NavigableMap empty = map0();
+ NavigableMap map = map5();
+ assertTrue(empty.isEmpty());
+ assertFalse(map.isEmpty());
+ }
+
+ /**
+ * firstKey returns first key
+ */
+ public void testFirstKey() {
+ NavigableMap map = map5();
+ assertEquals(one, map.firstKey());
+ }
+
+ /**
+ * lastKey returns last key
+ */
+ public void testLastKey() {
+ NavigableMap map = map5();
+ assertEquals(five, map.lastKey());
+ }
+
+ /**
+ * keySet returns a Set containing all the keys
+ */
+ public void testKeySet() {
+ NavigableMap map = map5();
+ Set s = map.keySet();
+ assertEquals(5, s.size());
+ assertTrue(s.contains(one));
+ assertTrue(s.contains(two));
+ assertTrue(s.contains(three));
+ assertTrue(s.contains(four));
+ assertTrue(s.contains(five));
+ }
+
+ /**
+ * keySet is ordered
+ */
+ public void testKeySetOrder() {
+ NavigableMap map = map5();
+ Set s = map.keySet();
+ Iterator i = s.iterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, one);
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) < 0);
+ last = k;
+ }
+ }
+
+ /**
+ * values collection contains all values
+ */
+ public void testValues() {
+ NavigableMap map = map5();
+ Collection s = map.values();
+ assertEquals(5, s.size());
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * entrySet contains all pairs
+ */
+ public void testEntrySet() {
+ NavigableMap map = map5();
+ Set s = map.entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(one) && e.getValue().equals("A")) ||
+ (e.getKey().equals(two) && e.getValue().equals("B")) ||
+ (e.getKey().equals(three) && e.getValue().equals("C")) ||
+ (e.getKey().equals(four) && e.getValue().equals("D")) ||
+ (e.getKey().equals(five) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * putAll adds all key-value pairs from the given map
+ */
+ public void testPutAll() {
+ NavigableMap empty = map0();
+ NavigableMap map = map5();
+ empty.putAll(map);
+ assertEquals(5, empty.size());
+ assertTrue(empty.containsKey(one));
+ assertTrue(empty.containsKey(two));
+ assertTrue(empty.containsKey(three));
+ assertTrue(empty.containsKey(four));
+ assertTrue(empty.containsKey(five));
+ }
+
+ /**
+ * remove removes the correct key-value pair from the map
+ */
+ public void testRemove() {
+ NavigableMap map = map5();
+ map.remove(five);
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(five));
+ }
+
+ /**
+ * lowerEntry returns preceding entry.
+ */
+ public void testLowerEntry() {
+ NavigableMap map = map5();
+ Map.Entry e1 = map.lowerEntry(three);
+ assertEquals(two, e1.getKey());
+
+ Map.Entry e2 = map.lowerEntry(six);
+ assertEquals(five, e2.getKey());
+
+ Map.Entry e3 = map.lowerEntry(one);
+ assertNull(e3);
+
+ Map.Entry e4 = map.lowerEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higherEntry returns next entry.
+ */
+ public void testHigherEntry() {
+ NavigableMap map = map5();
+ Map.Entry e1 = map.higherEntry(three);
+ assertEquals(four, e1.getKey());
+
+ Map.Entry e2 = map.higherEntry(zero);
+ assertEquals(one, e2.getKey());
+
+ Map.Entry e3 = map.higherEntry(five);
+ assertNull(e3);
+
+ Map.Entry e4 = map.higherEntry(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floorEntry returns preceding entry.
+ */
+ public void testFloorEntry() {
+ NavigableMap map = map5();
+ Map.Entry e1 = map.floorEntry(three);
+ assertEquals(three, e1.getKey());
+
+ Map.Entry e2 = map.floorEntry(six);
+ assertEquals(five, e2.getKey());
+
+ Map.Entry e3 = map.floorEntry(one);
+ assertEquals(one, e3.getKey());
+
+ Map.Entry e4 = map.floorEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceilingEntry returns next entry.
+ */
+ public void testCeilingEntry() {
+ NavigableMap map = map5();
+ Map.Entry e1 = map.ceilingEntry(three);
+ assertEquals(three, e1.getKey());
+
+ Map.Entry e2 = map.ceilingEntry(zero);
+ assertEquals(one, e2.getKey());
+
+ Map.Entry e3 = map.ceilingEntry(five);
+ assertEquals(five, e3.getKey());
+
+ Map.Entry e4 = map.ceilingEntry(six);
+ assertNull(e4);
+ }
+
+ /**
+ * pollFirstEntry returns entries in order
+ */
+ public void testPollFirstEntry() {
+ NavigableMap map = map5();
+ Map.Entry e = map.pollFirstEntry();
+ assertEquals(one, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(two, e.getKey());
+ map.put(one, "A");
+ e = map.pollFirstEntry();
+ assertEquals(one, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(three, e.getKey());
+ map.remove(four);
+ e = map.pollFirstEntry();
+ assertEquals(five, e.getKey());
+ try {
+ e.setValue("A");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ assertTrue(map.isEmpty());
+ Map.Entry f = map.firstEntry();
+ assertNull(f);
+ e = map.pollFirstEntry();
+ assertNull(e);
+ }
+
+ /**
+ * pollLastEntry returns entries in order
+ */
+ public void testPollLastEntry() {
+ NavigableMap map = map5();
+ Map.Entry e = map.pollLastEntry();
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(four, e.getKey());
+ map.put(five, "E");
+ e = map.pollLastEntry();
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(three, e.getKey());
+ map.remove(two);
+ e = map.pollLastEntry();
+ assertEquals(one, e.getKey());
+ try {
+ e.setValue("E");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollLastEntry();
+ assertNull(e);
+ }
+
+ /**
+ * size returns the correct values
+ */
+ public void testSize() {
+ NavigableMap map = map5();
+ NavigableMap empty = map0();
+ assertEquals(0, empty.size());
+ assertEquals(5, map.size());
+ }
+
+ /**
+ * toString contains toString of elements
+ */
+ public void testToString() {
+ NavigableMap map = map5();
+ String s = map.toString();
+ for (int i = 1; i <= 5; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ // Exception tests
+
+ /**
+ * get(null) of nonempty map throws NPE
+ */
+ public void testGet_NullPointerException() {
+ try {
+ NavigableMap c = map5();
+ c.get(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * containsKey(null) of nonempty map throws NPE
+ */
+ public void testContainsKey_NullPointerException() {
+ try {
+ NavigableMap c = map5();
+ c.containsKey(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * put(null,x) throws NPE
+ */
+ public void testPut1_NullPointerException() {
+ try {
+ NavigableMap c = map5();
+ c.put(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * remove(null) throws NPE
+ */
+ public void testRemove1_NullPointerException() {
+ try {
+ NavigableMap c = map5();
+ c.remove(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * A deserialized map equals original
+ */
+ public void testSerialization() throws Exception {
+ NavigableMap x = map5();
+ NavigableMap y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ /**
+ * subMap returns map with keys in requested range
+ */
+ public void testSubMapContents() {
+ NavigableMap map = map5();
+ SortedMap sm = map.subMap(two, four);
+ assertEquals(two, sm.firstKey());
+ assertEquals(three, sm.lastKey());
+ assertEquals(2, sm.size());
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(two));
+ assertEquals(4, map.size());
+ assertEquals(1, sm.size());
+ assertEquals(three, sm.firstKey());
+ assertEquals(three, sm.lastKey());
+ assertEquals("C", sm.remove(three));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, map.size());
+ }
+
+ public void testSubMapContents2() {
+ NavigableMap map = map5();
+ SortedMap sm = map.subMap(two, three);
+ assertEquals(1, sm.size());
+ assertEquals(two, sm.firstKey());
+ assertEquals(two, sm.lastKey());
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertFalse(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(two));
+ assertEquals(4, map.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertSame(sm.remove(three), null);
+ assertEquals(4, map.size());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testHeadMapContents() {
+ NavigableMap map = map5();
+ SortedMap sm = map.headMap(four);
+ assertTrue(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertFalse(sm.containsKey(four));
+ assertFalse(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(one, k);
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, map.size());
+ assertEquals(four, map.firstKey());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testTailMapContents() {
+ NavigableMap map = map5();
+ SortedMap sm = map.tailMap(two);
+ assertFalse(sm.containsKey(one));
+ assertTrue(sm.containsKey(two));
+ assertTrue(sm.containsKey(three));
+ assertTrue(sm.containsKey(four));
+ assertTrue(sm.containsKey(five));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ k = (Integer)(i.next());
+ assertEquals(four, k);
+ k = (Integer)(i.next());
+ assertEquals(five, k);
+ assertFalse(i.hasNext());
+
+ Iterator ei = sm.entrySet().iterator();
+ Map.Entry e;
+ e = (Map.Entry)(ei.next());
+ assertEquals(two, e.getKey());
+ assertEquals("B", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(three, e.getKey());
+ assertEquals("C", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(four, e.getKey());
+ assertEquals("D", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(five, e.getKey());
+ assertEquals("E", e.getValue());
+ assertFalse(i.hasNext());
+
+ SortedMap ssm = sm.tailMap(four);
+ assertEquals(four, ssm.firstKey());
+ assertEquals(five, ssm.lastKey());
+ assertEquals("D", ssm.remove(four));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, map.size());
+ }
+
+ /**
+ * clear removes all pairs
+ */
+ public void testDescendingClear() {
+ NavigableMap map = dmap5();
+ map.clear();
+ assertEquals(0, map.size());
+ }
+
+ /**
+ * Maps with same contents are equal
+ */
+ public void testDescendingEquals() {
+ NavigableMap map1 = dmap5();
+ NavigableMap map2 = dmap5();
+ assertEquals(map1, map2);
+ assertEquals(map2, map1);
+ map1.clear();
+ assertFalse(map1.equals(map2));
+ assertFalse(map2.equals(map1));
+ }
+
+ /**
+ * containsKey returns true for contained key
+ */
+ public void testDescendingContainsKey() {
+ NavigableMap map = dmap5();
+ assertTrue(map.containsKey(m1));
+ assertFalse(map.containsKey(zero));
+ }
+
+ /**
+ * containsValue returns true for held values
+ */
+ public void testDescendingContainsValue() {
+ NavigableMap map = dmap5();
+ assertTrue(map.containsValue("A"));
+ assertFalse(map.containsValue("Z"));
+ }
+
+ /**
+ * get returns the correct element at the given key,
+ * or null if not present
+ */
+ public void testDescendingGet() {
+ NavigableMap map = dmap5();
+ assertEquals("A", (String)map.get(m1));
+ NavigableMap empty = dmap0();
+ assertNull(empty.get(m1));
+ }
+
+ /**
+ * isEmpty is true of empty map and false for non-empty
+ */
+ public void testDescendingIsEmpty() {
+ NavigableMap empty = dmap0();
+ NavigableMap map = dmap5();
+ assertTrue(empty.isEmpty());
+ assertFalse(map.isEmpty());
+ }
+
+ /**
+ * firstKey returns first key
+ */
+ public void testDescendingFirstKey() {
+ NavigableMap map = dmap5();
+ assertEquals(m1, map.firstKey());
+ }
+
+ /**
+ * lastKey returns last key
+ */
+ public void testDescendingLastKey() {
+ NavigableMap map = dmap5();
+ assertEquals(m5, map.lastKey());
+ }
+
+ /**
+ * keySet returns a Set containing all the keys
+ */
+ public void testDescendingKeySet() {
+ NavigableMap map = dmap5();
+ Set s = map.keySet();
+ assertEquals(5, s.size());
+ assertTrue(s.contains(m1));
+ assertTrue(s.contains(m2));
+ assertTrue(s.contains(m3));
+ assertTrue(s.contains(m4));
+ assertTrue(s.contains(m5));
+ }
+
+ /**
+ * keySet is ordered
+ */
+ public void testDescendingKeySetOrder() {
+ NavigableMap map = dmap5();
+ Set s = map.keySet();
+ Iterator i = s.iterator();
+ Integer last = (Integer)i.next();
+ assertEquals(last, m1);
+ while (i.hasNext()) {
+ Integer k = (Integer)i.next();
+ assertTrue(last.compareTo(k) > 0);
+ last = k;
+ }
+ }
+
+ /**
+ * values collection contains all values
+ */
+ public void testDescendingValues() {
+ NavigableMap map = dmap5();
+ Collection s = map.values();
+ assertEquals(5, s.size());
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * keySet.toArray returns contains all keys
+ */
+ public void testDescendingAscendingKeySetToArray() {
+ NavigableMap map = dmap5();
+ Set s = map.keySet();
+ Object[] ar = s.toArray();
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ assertEquals(5, ar.length);
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * descendingkeySet.toArray returns contains all keys
+ */
+ public void testDescendingDescendingKeySetToArray() {
+ NavigableMap map = dmap5();
+ Set s = map.descendingKeySet();
+ Object[] ar = s.toArray();
+ assertEquals(5, ar.length);
+ assertTrue(s.containsAll(Arrays.asList(ar)));
+ ar[0] = m10;
+ assertFalse(s.containsAll(Arrays.asList(ar)));
+ }
+
+ /**
+ * Values.toArray contains all values
+ */
+ public void testDescendingValuesToArray() {
+ NavigableMap map = dmap5();
+ Collection v = map.values();
+ Object[] ar = v.toArray();
+ ArrayList s = new ArrayList(Arrays.asList(ar));
+ assertEquals(5, ar.length);
+ assertTrue(s.contains("A"));
+ assertTrue(s.contains("B"));
+ assertTrue(s.contains("C"));
+ assertTrue(s.contains("D"));
+ assertTrue(s.contains("E"));
+ }
+
+ /**
+ * entrySet contains all pairs
+ */
+ public void testDescendingEntrySet() {
+ NavigableMap map = dmap5();
+ Set s = map.entrySet();
+ assertEquals(5, s.size());
+ Iterator it = s.iterator();
+ while (it.hasNext()) {
+ Map.Entry e = (Map.Entry) it.next();
+ assertTrue(
+ (e.getKey().equals(m1) && e.getValue().equals("A")) ||
+ (e.getKey().equals(m2) && e.getValue().equals("B")) ||
+ (e.getKey().equals(m3) && e.getValue().equals("C")) ||
+ (e.getKey().equals(m4) && e.getValue().equals("D")) ||
+ (e.getKey().equals(m5) && e.getValue().equals("E")));
+ }
+ }
+
+ /**
+ * putAll adds all key-value pairs from the given map
+ */
+ public void testDescendingPutAll() {
+ NavigableMap empty = dmap0();
+ NavigableMap map = dmap5();
+ empty.putAll(map);
+ assertEquals(5, empty.size());
+ assertTrue(empty.containsKey(m1));
+ assertTrue(empty.containsKey(m2));
+ assertTrue(empty.containsKey(m3));
+ assertTrue(empty.containsKey(m4));
+ assertTrue(empty.containsKey(m5));
+ }
+
+ /**
+ * remove removes the correct key-value pair from the map
+ */
+ public void testDescendingRemove() {
+ NavigableMap map = dmap5();
+ map.remove(m5);
+ assertEquals(4, map.size());
+ assertFalse(map.containsKey(m5));
+ }
+
+ /**
+ * lowerEntry returns preceding entry.
+ */
+ public void testDescendingLowerEntry() {
+ NavigableMap map = dmap5();
+ Map.Entry e1 = map.lowerEntry(m3);
+ assertEquals(m2, e1.getKey());
+
+ Map.Entry e2 = map.lowerEntry(m6);
+ assertEquals(m5, e2.getKey());
+
+ Map.Entry e3 = map.lowerEntry(m1);
+ assertNull(e3);
+
+ Map.Entry e4 = map.lowerEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higherEntry returns next entry.
+ */
+ public void testDescendingHigherEntry() {
+ NavigableMap map = dmap5();
+ Map.Entry e1 = map.higherEntry(m3);
+ assertEquals(m4, e1.getKey());
+
+ Map.Entry e2 = map.higherEntry(zero);
+ assertEquals(m1, e2.getKey());
+
+ Map.Entry e3 = map.higherEntry(m5);
+ assertNull(e3);
+
+ Map.Entry e4 = map.higherEntry(m6);
+ assertNull(e4);
+ }
+
+ /**
+ * floorEntry returns preceding entry.
+ */
+ public void testDescendingFloorEntry() {
+ NavigableMap map = dmap5();
+ Map.Entry e1 = map.floorEntry(m3);
+ assertEquals(m3, e1.getKey());
+
+ Map.Entry e2 = map.floorEntry(m6);
+ assertEquals(m5, e2.getKey());
+
+ Map.Entry e3 = map.floorEntry(m1);
+ assertEquals(m1, e3.getKey());
+
+ Map.Entry e4 = map.floorEntry(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceilingEntry returns next entry.
+ */
+ public void testDescendingCeilingEntry() {
+ NavigableMap map = dmap5();
+ Map.Entry e1 = map.ceilingEntry(m3);
+ assertEquals(m3, e1.getKey());
+
+ Map.Entry e2 = map.ceilingEntry(zero);
+ assertEquals(m1, e2.getKey());
+
+ Map.Entry e3 = map.ceilingEntry(m5);
+ assertEquals(m5, e3.getKey());
+
+ Map.Entry e4 = map.ceilingEntry(m6);
+ assertNull(e4);
+ }
+
+ /**
+ * pollFirstEntry returns entries in order
+ */
+ public void testDescendingPollFirstEntry() {
+ NavigableMap map = dmap5();
+ Map.Entry e = map.pollFirstEntry();
+ assertEquals(m1, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(m2, e.getKey());
+ map.put(m1, "A");
+ e = map.pollFirstEntry();
+ assertEquals(m1, e.getKey());
+ assertEquals("A", e.getValue());
+ e = map.pollFirstEntry();
+ assertEquals(m3, e.getKey());
+ map.remove(m4);
+ e = map.pollFirstEntry();
+ assertEquals(m5, e.getKey());
+ try {
+ e.setValue("A");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollFirstEntry();
+ assertNull(e);
+ }
+
+ /**
+ * pollLastEntry returns entries in order
+ */
+ public void testDescendingPollLastEntry() {
+ NavigableMap map = dmap5();
+ Map.Entry e = map.pollLastEntry();
+ assertEquals(m5, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(m4, e.getKey());
+ map.put(m5, "E");
+ e = map.pollLastEntry();
+ assertEquals(m5, e.getKey());
+ assertEquals("E", e.getValue());
+ e = map.pollLastEntry();
+ assertEquals(m3, e.getKey());
+ map.remove(m2);
+ e = map.pollLastEntry();
+ assertEquals(m1, e.getKey());
+ try {
+ e.setValue("E");
+ shouldThrow();
+ } catch (UnsupportedOperationException success) {}
+ e = map.pollLastEntry();
+ assertNull(e);
+ }
+
+ /**
+ * size returns the correct values
+ */
+ public void testDescendingSize() {
+ NavigableMap map = dmap5();
+ NavigableMap empty = dmap0();
+ assertEquals(0, empty.size());
+ assertEquals(5, map.size());
+ }
+
+ /**
+ * toString contains toString of elements
+ */
+ public void testDescendingToString() {
+ NavigableMap map = dmap5();
+ String s = map.toString();
+ for (int i = 1; i <= 5; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ // Exception testDescendings
+
+ /**
+ * get(null) of nonempty map throws NPE
+ */
+ public void testDescendingGet_NullPointerException() {
+ try {
+ NavigableMap c = dmap5();
+ c.get(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * put(null,x) throws NPE
+ */
+ public void testDescendingPut1_NullPointerException() {
+ try {
+ NavigableMap c = dmap5();
+ c.put(null, "whatever");
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * A deserialized map equals original
+ */
+ public void testDescendingSerialization() throws Exception {
+ NavigableMap x = dmap5();
+ NavigableMap y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+ /**
+ * subMap returns map with keys in requested range
+ */
+ public void testDescendingSubMapContents() {
+ NavigableMap map = dmap5();
+ SortedMap sm = map.subMap(m2, m4);
+ assertEquals(m2, sm.firstKey());
+ assertEquals(m3, sm.lastKey());
+ assertEquals(2, sm.size());
+ assertFalse(sm.containsKey(m1));
+ assertTrue(sm.containsKey(m2));
+ assertTrue(sm.containsKey(m3));
+ assertFalse(sm.containsKey(m4));
+ assertFalse(sm.containsKey(m5));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(m2));
+ assertEquals(4, map.size());
+ assertEquals(1, sm.size());
+ assertEquals(m3, sm.firstKey());
+ assertEquals(m3, sm.lastKey());
+ assertEquals("C", sm.remove(m3));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, map.size());
+ }
+
+ public void testDescendingSubMapContents2() {
+ NavigableMap map = dmap5();
+ SortedMap sm = map.subMap(m2, m3);
+ assertEquals(1, sm.size());
+ assertEquals(m2, sm.firstKey());
+ assertEquals(m2, sm.lastKey());
+ assertFalse(sm.containsKey(m1));
+ assertTrue(sm.containsKey(m2));
+ assertFalse(sm.containsKey(m3));
+ assertFalse(sm.containsKey(m4));
+ assertFalse(sm.containsKey(m5));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.keySet().iterator();
+ j.next();
+ j.remove();
+ assertFalse(map.containsKey(m2));
+ assertEquals(4, map.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertSame(sm.remove(m3), null);
+ assertEquals(4, map.size());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testDescendingHeadMapContents() {
+ NavigableMap map = dmap5();
+ SortedMap sm = map.headMap(m4);
+ assertTrue(sm.containsKey(m1));
+ assertTrue(sm.containsKey(m2));
+ assertTrue(sm.containsKey(m3));
+ assertFalse(sm.containsKey(m4));
+ assertFalse(sm.containsKey(m5));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m1, k);
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, map.size());
+ assertEquals(m4, map.firstKey());
+ }
+
+ /**
+ * headMap returns map with keys in requested range
+ */
+ public void testDescendingTailMapContents() {
+ NavigableMap map = dmap5();
+ SortedMap sm = map.tailMap(m2);
+ assertFalse(sm.containsKey(m1));
+ assertTrue(sm.containsKey(m2));
+ assertTrue(sm.containsKey(m3));
+ assertTrue(sm.containsKey(m4));
+ assertTrue(sm.containsKey(m5));
+ Iterator i = sm.keySet().iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ k = (Integer)(i.next());
+ assertEquals(m4, k);
+ k = (Integer)(i.next());
+ assertEquals(m5, k);
+ assertFalse(i.hasNext());
+
+ Iterator ei = sm.entrySet().iterator();
+ Map.Entry e;
+ e = (Map.Entry)(ei.next());
+ assertEquals(m2, e.getKey());
+ assertEquals("B", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(m3, e.getKey());
+ assertEquals("C", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(m4, e.getKey());
+ assertEquals("D", e.getValue());
+ e = (Map.Entry)(ei.next());
+ assertEquals(m5, e.getKey());
+ assertEquals("E", e.getValue());
+ assertFalse(i.hasNext());
+
+ SortedMap ssm = sm.tailMap(m4);
+ assertEquals(m4, ssm.firstKey());
+ assertEquals(m5, ssm.lastKey());
+ assertEquals("D", ssm.remove(m4));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, map.size());
+ }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java b/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java
new file mode 100644
index 0000000..ba61748
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java
@@ -0,0 +1,1116 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.SortedSet;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class TreeSubSetTest extends JSR166TestCase {
+
+ static class MyReverseComparator implements Comparator {
+ public int compare(Object x, Object y) {
+ return ((Comparable)y).compareTo(x);
+ }
+ }
+
+ /**
+ * Returns a new set of given size containing consecutive
+ * Integers 0 ... n.
+ */
+ private NavigableSet<Integer> populatedSet(int n) {
+ TreeSet<Integer> q = new TreeSet<Integer>();
+ assertTrue(q.isEmpty());
+
+ for (int i = n-1; i >= 0; i-=2)
+ assertTrue(q.add(new Integer(i)));
+ for (int i = (n & 1); i < n; i+=2)
+ assertTrue(q.add(new Integer(i)));
+ assertTrue(q.add(new Integer(-n)));
+ assertTrue(q.add(new Integer(n)));
+ NavigableSet s = q.subSet(new Integer(0), true, new Integer(n), false);
+ assertFalse(s.isEmpty());
+ assertEquals(n, s.size());
+ return s;
+ }
+
+ /**
+ * Returns a new set of first 5 ints.
+ */
+ private NavigableSet set5() {
+ TreeSet q = new TreeSet();
+ assertTrue(q.isEmpty());
+ q.add(one);
+ q.add(two);
+ q.add(three);
+ q.add(four);
+ q.add(five);
+ q.add(zero);
+ q.add(seven);
+ NavigableSet s = q.subSet(one, true, seven, false);
+ assertEquals(5, s.size());
+ return s;
+ }
+
+ private NavigableSet dset5() {
+ TreeSet q = new TreeSet();
+ assertTrue(q.isEmpty());
+ q.add(m1);
+ q.add(m2);
+ q.add(m3);
+ q.add(m4);
+ q.add(m5);
+ NavigableSet s = q.descendingSet();
+ assertEquals(5, s.size());
+ return s;
+ }
+
+ private static NavigableSet set0() {
+ TreeSet set = new TreeSet();
+ assertTrue(set.isEmpty());
+ return set.tailSet(m1, false);
+ }
+
+ private static NavigableSet dset0() {
+ TreeSet set = new TreeSet();
+ assertTrue(set.isEmpty());
+ return set;
+ }
+
+ /**
+ * A new set has unbounded capacity
+ */
+ public void testConstructor1() {
+ assertEquals(0, set0().size());
+ }
+
+ /**
+ * isEmpty is true before add, false after
+ */
+ public void testEmpty() {
+ NavigableSet q = set0();
+ assertTrue(q.isEmpty());
+ assertTrue(q.add(new Integer(1)));
+ assertFalse(q.isEmpty());
+ assertTrue(q.add(new Integer(2)));
+ q.pollFirst();
+ q.pollFirst();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testSize() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.pollFirst();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * add(null) throws NPE
+ */
+ public void testAddNull() {
+ try {
+ NavigableSet q = set0();
+ q.add(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Add of comparable element succeeds
+ */
+ public void testAdd() {
+ NavigableSet q = set0();
+ assertTrue(q.add(six));
+ }
+
+ /**
+ * Add of duplicate element fails
+ */
+ public void testAddDup() {
+ NavigableSet q = set0();
+ assertTrue(q.add(six));
+ assertFalse(q.add(six));
+ }
+
+ /**
+ * Add of non-Comparable throws CCE
+ */
+ public void testAddNonComparable() {
+ try {
+ NavigableSet q = set0();
+ q.add(new Object());
+ q.add(new Object());
+ q.add(new Object());
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testAddAll1() {
+ try {
+ NavigableSet q = set0();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testAddAll2() {
+ try {
+ NavigableSet q = set0();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testAddAll3() {
+ try {
+ NavigableSet q = set0();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i+SIZE);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Set contains all elements of successful addAll
+ */
+ public void testAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(SIZE-1- i);
+ NavigableSet q = set0();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(new Integer(i), q.pollFirst());
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testPoll() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testRemoveElement() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertTrue(q.contains(i-1));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.contains(i));
+ assertTrue(q.remove(i));
+ assertFalse(q.contains(i));
+ assertFalse(q.remove(i+1));
+ assertFalse(q.contains(i+1));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testContains() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.pollFirst();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testClear() {
+ NavigableSet q = populatedSet(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertTrue(q.add(new Integer(1)));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testContainsAll() {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = set0();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testRetainAll() {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.pollFirst();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = populatedSet(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.pollFirst());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * lower returns preceding element
+ */
+ public void testLower() {
+ NavigableSet q = set5();
+ Object e1 = q.lower(three);
+ assertEquals(two, e1);
+
+ Object e2 = q.lower(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.lower(one);
+ assertNull(e3);
+
+ Object e4 = q.lower(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higher returns next element
+ */
+ public void testHigher() {
+ NavigableSet q = set5();
+ Object e1 = q.higher(three);
+ assertEquals(four, e1);
+
+ Object e2 = q.higher(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.higher(five);
+ assertNull(e3);
+
+ Object e4 = q.higher(six);
+ assertNull(e4);
+ }
+
+ /**
+ * floor returns preceding element
+ */
+ public void testFloor() {
+ NavigableSet q = set5();
+ Object e1 = q.floor(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.floor(six);
+ assertEquals(five, e2);
+
+ Object e3 = q.floor(one);
+ assertEquals(one, e3);
+
+ Object e4 = q.floor(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceiling returns next element
+ */
+ public void testCeiling() {
+ NavigableSet q = set5();
+ Object e1 = q.ceiling(three);
+ assertEquals(three, e1);
+
+ Object e2 = q.ceiling(zero);
+ assertEquals(one, e2);
+
+ Object e3 = q.ceiling(five);
+ assertEquals(five, e3);
+
+ Object e4 = q.ceiling(six);
+ assertNull(e4);
+ }
+
+ /**
+ * toArray contains all elements in sorted order
+ */
+ public void testToArray() {
+ NavigableSet q = populatedSet(SIZE);
+ Object[] o = q.toArray();
+ for (int i = 0; i < o.length; i++)
+ assertSame(o[i], q.pollFirst());
+ }
+
+ /**
+ * toArray(a) contains all elements in sorted order
+ */
+ public void testToArray2() {
+ NavigableSet<Integer> q = populatedSet(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ Integer[] array = q.toArray(ints);
+ assertSame(ints, array);
+ for (int i = 0; i < ints.length; i++)
+ assertSame(ints[i], q.pollFirst());
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testIterator() {
+ NavigableSet q = populatedSet(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator of empty set has no elements
+ */
+ public void testEmptyIterator() {
+ NavigableSet q = set0();
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(0, i);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testIteratorRemove() {
+ final NavigableSet q = set0();
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ q.add(new Integer(3));
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertEquals(2, it.next());
+ assertEquals(3, it.next());
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testToString() {
+ NavigableSet q = populatedSet(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized set has same elements
+ */
+ public void testSerialization() throws Exception {
+ NavigableSet x = populatedSet(SIZE);
+ NavigableSet y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.pollFirst(), y.pollFirst());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * subSet returns set with keys in requested range
+ */
+ public void testSubSetContents() {
+ NavigableSet set = set5();
+ SortedSet sm = set.subSet(two, four);
+ assertEquals(two, sm.first());
+ assertEquals(three, sm.last());
+ assertEquals(2, sm.size());
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(two));
+ assertEquals(4, set.size());
+ assertEquals(1, sm.size());
+ assertEquals(three, sm.first());
+ assertEquals(three, sm.last());
+ assertTrue(sm.remove(three));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, set.size());
+ }
+
+ public void testSubSetContents2() {
+ NavigableSet set = set5();
+ SortedSet sm = set.subSet(two, three);
+ assertEquals(1, sm.size());
+ assertEquals(two, sm.first());
+ assertEquals(two, sm.last());
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertFalse(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(two));
+ assertEquals(4, set.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertFalse(sm.remove(three));
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * headSet returns set with keys in requested range
+ */
+ public void testHeadSetContents() {
+ NavigableSet set = set5();
+ SortedSet sm = set.headSet(four);
+ assertTrue(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertFalse(sm.contains(four));
+ assertFalse(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(one, k);
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, set.size());
+ assertEquals(four, set.first());
+ }
+
+ /**
+ * tailSet returns set with keys in requested range
+ */
+ public void testTailSetContents() {
+ NavigableSet set = set5();
+ SortedSet sm = set.tailSet(two);
+ assertFalse(sm.contains(one));
+ assertTrue(sm.contains(two));
+ assertTrue(sm.contains(three));
+ assertTrue(sm.contains(four));
+ assertTrue(sm.contains(five));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(two, k);
+ k = (Integer)(i.next());
+ assertEquals(three, k);
+ k = (Integer)(i.next());
+ assertEquals(four, k);
+ k = (Integer)(i.next());
+ assertEquals(five, k);
+ assertFalse(i.hasNext());
+
+ SortedSet ssm = sm.tailSet(four);
+ assertEquals(four, ssm.first());
+ assertEquals(five, ssm.last());
+ assertTrue(ssm.remove(four));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * size changes when elements added and removed
+ */
+ public void testDescendingSize() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(SIZE-i, q.size());
+ q.pollFirst();
+ }
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.size());
+ q.add(new Integer(i));
+ }
+ }
+
+ /**
+ * Add of comparable element succeeds
+ */
+ public void testDescendingAdd() {
+ NavigableSet q = dset0();
+ assertTrue(q.add(m6));
+ }
+
+ /**
+ * Add of duplicate element fails
+ */
+ public void testDescendingAddDup() {
+ NavigableSet q = dset0();
+ assertTrue(q.add(m6));
+ assertFalse(q.add(m6));
+ }
+
+ /**
+ * Add of non-Comparable throws CCE
+ */
+ public void testDescendingAddNonComparable() {
+ try {
+ NavigableSet q = dset0();
+ q.add(new Object());
+ q.add(new Object());
+ q.add(new Object());
+ shouldThrow();
+ } catch (ClassCastException success) {}
+ }
+
+ /**
+ * addAll(null) throws NPE
+ */
+ public void testDescendingAddAll1() {
+ try {
+ NavigableSet q = dset0();
+ q.addAll(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with null elements throws NPE
+ */
+ public void testDescendingAddAll2() {
+ try {
+ NavigableSet q = dset0();
+ Integer[] ints = new Integer[SIZE];
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * addAll of a collection with any null elements throws NPE after
+ * possibly adding some elements
+ */
+ public void testDescendingAddAll3() {
+ try {
+ NavigableSet q = dset0();
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE-1; ++i)
+ ints[i] = new Integer(i+SIZE);
+ q.addAll(Arrays.asList(ints));
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * Set contains all elements of successful addAll
+ */
+ public void testDescendingAddAll5() {
+ Integer[] empty = new Integer[0];
+ Integer[] ints = new Integer[SIZE];
+ for (int i = 0; i < SIZE; ++i)
+ ints[i] = new Integer(SIZE-1- i);
+ NavigableSet q = dset0();
+ assertFalse(q.addAll(Arrays.asList(empty)));
+ assertTrue(q.addAll(Arrays.asList(ints)));
+ for (int i = 0; i < SIZE; ++i)
+ assertEquals(new Integer(i), q.pollFirst());
+ }
+
+ /**
+ * poll succeeds unless empty
+ */
+ public void testDescendingPoll() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertEquals(i, q.pollFirst());
+ }
+ assertNull(q.pollFirst());
+ }
+
+ /**
+ * remove(x) removes x and returns true if present
+ */
+ public void testDescendingRemoveElement() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 1; i < SIZE; i+=2) {
+ assertTrue(q.remove(new Integer(i)));
+ }
+ for (int i = 0; i < SIZE; i+=2) {
+ assertTrue(q.remove(new Integer(i)));
+ assertFalse(q.remove(new Integer(i+1)));
+ }
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * contains(x) reports true when elements added but not yet removed
+ */
+ public void testDescendingContains() {
+ NavigableSet q = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.contains(new Integer(i)));
+ q.pollFirst();
+ assertFalse(q.contains(new Integer(i)));
+ }
+ }
+
+ /**
+ * clear removes all elements
+ */
+ public void testDescendingClear() {
+ NavigableSet q = populatedSet(SIZE);
+ q.clear();
+ assertTrue(q.isEmpty());
+ assertEquals(0, q.size());
+ assertTrue(q.add(new Integer(1)));
+ assertFalse(q.isEmpty());
+ q.clear();
+ assertTrue(q.isEmpty());
+ }
+
+ /**
+ * containsAll(c) is true when c contains a subset of elements
+ */
+ public void testDescendingContainsAll() {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = dset0();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(q.containsAll(p));
+ assertFalse(p.containsAll(q));
+ p.add(new Integer(i));
+ }
+ assertTrue(p.containsAll(q));
+ }
+
+ /**
+ * retainAll(c) retains only those elements of c and reports true if changed
+ */
+ public void testDescendingRetainAll() {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = populatedSet(SIZE);
+ for (int i = 0; i < SIZE; ++i) {
+ boolean changed = q.retainAll(p);
+ if (i == 0)
+ assertFalse(changed);
+ else
+ assertTrue(changed);
+
+ assertTrue(q.containsAll(p));
+ assertEquals(SIZE-i, q.size());
+ p.pollFirst();
+ }
+ }
+
+ /**
+ * removeAll(c) removes only those elements of c and reports true if changed
+ */
+ public void testDescendingRemoveAll() {
+ for (int i = 1; i < SIZE; ++i) {
+ NavigableSet q = populatedSet(SIZE);
+ NavigableSet p = populatedSet(i);
+ assertTrue(q.removeAll(p));
+ assertEquals(SIZE-i, q.size());
+ for (int j = 0; j < i; ++j) {
+ Integer I = (Integer)(p.pollFirst());
+ assertFalse(q.contains(I));
+ }
+ }
+ }
+
+ /**
+ * lower returns preceding element
+ */
+ public void testDescendingLower() {
+ NavigableSet q = dset5();
+ Object e1 = q.lower(m3);
+ assertEquals(m2, e1);
+
+ Object e2 = q.lower(m6);
+ assertEquals(m5, e2);
+
+ Object e3 = q.lower(m1);
+ assertNull(e3);
+
+ Object e4 = q.lower(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * higher returns next element
+ */
+ public void testDescendingHigher() {
+ NavigableSet q = dset5();
+ Object e1 = q.higher(m3);
+ assertEquals(m4, e1);
+
+ Object e2 = q.higher(zero);
+ assertEquals(m1, e2);
+
+ Object e3 = q.higher(m5);
+ assertNull(e3);
+
+ Object e4 = q.higher(m6);
+ assertNull(e4);
+ }
+
+ /**
+ * floor returns preceding element
+ */
+ public void testDescendingFloor() {
+ NavigableSet q = dset5();
+ Object e1 = q.floor(m3);
+ assertEquals(m3, e1);
+
+ Object e2 = q.floor(m6);
+ assertEquals(m5, e2);
+
+ Object e3 = q.floor(m1);
+ assertEquals(m1, e3);
+
+ Object e4 = q.floor(zero);
+ assertNull(e4);
+ }
+
+ /**
+ * ceiling returns next element
+ */
+ public void testDescendingCeiling() {
+ NavigableSet q = dset5();
+ Object e1 = q.ceiling(m3);
+ assertEquals(m3, e1);
+
+ Object e2 = q.ceiling(zero);
+ assertEquals(m1, e2);
+
+ Object e3 = q.ceiling(m5);
+ assertEquals(m5, e3);
+
+ Object e4 = q.ceiling(m6);
+ assertNull(e4);
+ }
+
+ /**
+ * toArray contains all elements
+ */
+ public void testDescendingToArray() {
+ NavigableSet q = populatedSet(SIZE);
+ Object[] o = q.toArray();
+ Arrays.sort(o);
+ for (int i = 0; i < o.length; i++)
+ assertEquals(o[i], q.pollFirst());
+ }
+
+ /**
+ * toArray(a) contains all elements
+ */
+ public void testDescendingToArray2() {
+ NavigableSet q = populatedSet(SIZE);
+ Integer[] ints = new Integer[SIZE];
+ assertSame(ints, q.toArray(ints));
+ Arrays.sort(ints);
+ for (int i = 0; i < ints.length; i++)
+ assertEquals(ints[i], q.pollFirst());
+ }
+
+ /**
+ * iterator iterates through all elements
+ */
+ public void testDescendingIterator() {
+ NavigableSet q = populatedSet(SIZE);
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(i, SIZE);
+ }
+
+ /**
+ * iterator of empty set has no elements
+ */
+ public void testDescendingEmptyIterator() {
+ NavigableSet q = dset0();
+ int i = 0;
+ Iterator it = q.iterator();
+ while (it.hasNext()) {
+ assertTrue(q.contains(it.next()));
+ ++i;
+ }
+ assertEquals(0, i);
+ }
+
+ /**
+ * iterator.remove removes current element
+ */
+ public void testDescendingIteratorRemove() {
+ final NavigableSet q = dset0();
+ q.add(new Integer(2));
+ q.add(new Integer(1));
+ q.add(new Integer(3));
+
+ Iterator it = q.iterator();
+ it.next();
+ it.remove();
+
+ it = q.iterator();
+ assertEquals(2, it.next());
+ assertEquals(3, it.next());
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * toString contains toStrings of elements
+ */
+ public void testDescendingToString() {
+ NavigableSet q = populatedSet(SIZE);
+ String s = q.toString();
+ for (int i = 0; i < SIZE; ++i) {
+ assertTrue(s.contains(String.valueOf(i)));
+ }
+ }
+
+ /**
+ * A deserialized serialized set has same elements
+ */
+ public void testDescendingSerialization() throws Exception {
+ NavigableSet x = dset5();
+ NavigableSet y = serialClone(x);
+
+ assertNotSame(x, y);
+ assertEquals(x.size(), y.size());
+ assertEquals(x.toString(), y.toString());
+ assertEquals(x, y);
+ assertEquals(y, x);
+ while (!x.isEmpty()) {
+ assertFalse(y.isEmpty());
+ assertEquals(x.pollFirst(), y.pollFirst());
+ }
+ assertTrue(y.isEmpty());
+ }
+
+ /**
+ * subSet returns set with keys in requested range
+ */
+ public void testDescendingSubSetContents() {
+ NavigableSet set = dset5();
+ SortedSet sm = set.subSet(m2, m4);
+ assertEquals(m2, sm.first());
+ assertEquals(m3, sm.last());
+ assertEquals(2, sm.size());
+ assertFalse(sm.contains(m1));
+ assertTrue(sm.contains(m2));
+ assertTrue(sm.contains(m3));
+ assertFalse(sm.contains(m4));
+ assertFalse(sm.contains(m5));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(m2));
+ assertEquals(4, set.size());
+ assertEquals(1, sm.size());
+ assertEquals(m3, sm.first());
+ assertEquals(m3, sm.last());
+ assertTrue(sm.remove(m3));
+ assertTrue(sm.isEmpty());
+ assertEquals(3, set.size());
+ }
+
+ public void testDescendingSubSetContents2() {
+ NavigableSet set = dset5();
+ SortedSet sm = set.subSet(m2, m3);
+ assertEquals(1, sm.size());
+ assertEquals(m2, sm.first());
+ assertEquals(m2, sm.last());
+ assertFalse(sm.contains(m1));
+ assertTrue(sm.contains(m2));
+ assertFalse(sm.contains(m3));
+ assertFalse(sm.contains(m4));
+ assertFalse(sm.contains(m5));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ assertFalse(i.hasNext());
+ Iterator j = sm.iterator();
+ j.next();
+ j.remove();
+ assertFalse(set.contains(m2));
+ assertEquals(4, set.size());
+ assertEquals(0, sm.size());
+ assertTrue(sm.isEmpty());
+ assertFalse(sm.remove(m3));
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * headSet returns set with keys in requested range
+ */
+ public void testDescendingHeadSetContents() {
+ NavigableSet set = dset5();
+ SortedSet sm = set.headSet(m4);
+ assertTrue(sm.contains(m1));
+ assertTrue(sm.contains(m2));
+ assertTrue(sm.contains(m3));
+ assertFalse(sm.contains(m4));
+ assertFalse(sm.contains(m5));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m1, k);
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ assertFalse(i.hasNext());
+ sm.clear();
+ assertTrue(sm.isEmpty());
+ assertEquals(2, set.size());
+ assertEquals(m4, set.first());
+ }
+
+ /**
+ * tailSet returns set with keys in requested range
+ */
+ public void testDescendingTailSetContents() {
+ NavigableSet set = dset5();
+ SortedSet sm = set.tailSet(m2);
+ assertFalse(sm.contains(m1));
+ assertTrue(sm.contains(m2));
+ assertTrue(sm.contains(m3));
+ assertTrue(sm.contains(m4));
+ assertTrue(sm.contains(m5));
+ Iterator i = sm.iterator();
+ Object k;
+ k = (Integer)(i.next());
+ assertEquals(m2, k);
+ k = (Integer)(i.next());
+ assertEquals(m3, k);
+ k = (Integer)(i.next());
+ assertEquals(m4, k);
+ k = (Integer)(i.next());
+ assertEquals(m5, k);
+ assertFalse(i.hasNext());
+
+ SortedSet ssm = sm.tailSet(m4);
+ assertEquals(m4, ssm.first());
+ assertEquals(m5, ssm.last());
+ assertTrue(ssm.remove(m4));
+ assertEquals(1, ssm.size());
+ assertEquals(3, sm.size());
+ assertEquals(4, set.size());
+ }
+
+ /**
+ * addAll is idempotent
+ */
+ public void testAddAll_idempotent() throws Exception {
+ Set x = populatedSet(SIZE);
+ Set y = new TreeSet(x);
+ y.addAll(x);
+ assertEquals(x, y);
+ assertEquals(y, x);
+ }
+
+}
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 8f19e3a..43fa00e 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -16,6 +16,9 @@
package dalvik.system;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* Provides an interface to VM-global, Dalvik-specific features.
* An application cannot create its own Runtime instance, and must obtain
@@ -30,6 +33,20 @@ public final class VMRuntime {
*/
private static final VMRuntime THE_ONE = new VMRuntime();
+ private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
+ = new HashMap<String, String>();
+ static {
+ ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
+ ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
+ ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
+ ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
+ ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
+ ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
+ ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");
+ }
+
+ private int targetSdkVersion;
+
/**
* Prevents this class from being instantiated.
*/
@@ -73,6 +90,21 @@ public final class VMRuntime {
public native String vmLibrary();
/**
+ * Returns the VM's instruction set.
+ */
+ public native String vmInstructionSet();
+
+ /**
+ * Returns whether the VM is running in 64-bit mode.
+ */
+ public native boolean is64Bit();
+
+ /**
+ * Returns whether the VM is running with JNI checking enabled.
+ */
+ public native boolean isCheckJniEnabled();
+
+ /**
* Gets the current ideal heap utilization, represented as a number
* between zero and one. After a GC happens, the Dalvik heap may
* be resized so that (size of live objects) / (size of heap) is
@@ -116,9 +148,23 @@ public final class VMRuntime {
* app starts to run, because it may change the VM's behavior in
* dangerous ways. Use 0 to mean "current" (since callers won't
* necessarily know the actual current SDK version, and the
- * allocated version numbers start at 1).
+ * allocated version numbers start at 1), and 10000 to mean
+ * CUR_DEVELOPMENT.
+ */
+ public synchronized void setTargetSdkVersion(int targetSdkVersion) {
+ this.targetSdkVersion = targetSdkVersion;
+ setTargetSdkVersionNative(this.targetSdkVersion);
+ }
+
+ /**
+ * Gets the target SDK version. See {@link #setTargetSdkVersion} for
+ * special values.
*/
- public native void setTargetSdkVersion(int targetSdkVersion);
+ public synchronized int getTargetSdkVersion() {
+ return targetSdkVersion;
+ }
+
+ private native void setTargetSdkVersionNative(int targetSdkVersion);
/**
* This method exists for binary compatibility. It was part of a
@@ -207,6 +253,13 @@ public final class VMRuntime {
public native Object newNonMovableArray(Class<?> componentType, int length);
/**
+ * Returns an array of at least minLength, but potentially larger. The increased size comes from
+ * avoiding any padding after the array. The amount of padding varies depending on the
+ * componentType and the memory allocator implementation.
+ */
+ public native Object newUnpaddedArray(Class<?> componentType, int minLength);
+
+ /**
* Returns the address of array[0]. This differs from using JNI in that JNI might lie and
* give you the address of a copy of the array when in forcecopy mode.
*/
@@ -241,7 +294,59 @@ public final class VMRuntime {
public native void trimHeap();
public native void concurrentGC();
- public void preloadDexCaches() {
- // Do nothing with ART, image generation already does this.
+ /**
+ * Let the heap know of the new process state. This can change allocation and garbage collection
+ * behavior regarding trimming and compaction.
+ */
+ public native void updateProcessState(int state);
+
+ /**
+ * Fill in dex caches with classes, fields, and methods that are
+ * already loaded. Typically used after Zygote preloading.
+ */
+ public native void preloadDexCaches();
+
+ /**
+ * Register application info
+ */
+ public static native void registerAppInfo(String appDir, String processName, String pkgname);
+
+ /**
+ * Returns the runtime instruction set corresponding to a given ABI. Multiple
+ * compatible ABIs might map to the same instruction set. For example
+ * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
+ *
+ * This influences the compilation of the applications classes.
+ */
+ public static String getInstructionSet(String abi) {
+ final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
+ if (instructionSet == null) {
+ throw new IllegalArgumentException("Unsupported ABI: " + abi);
+ }
+
+ return instructionSet;
}
+
+ public static boolean is64BitInstructionSet(String instructionSet) {
+ return "arm64".equals(instructionSet) ||
+ "x86_64".equals(instructionSet) ||
+ "mips64".equals(instructionSet);
+ }
+
+ public static boolean is64BitAbi(String abi) {
+ return is64BitInstructionSet(getInstructionSet(abi));
+ }
+
+ /**
+ * Return false if the boot class path for the given instruction
+ * set mapped from disk storage, versus being interpretted from
+ * dirty pages in memory.
+ */
+ public static native boolean isBootClassPathOnDisk(String instructionSet);
+
+ /**
+ * Returns the instruction set of the current runtime.
+ */
+ public static native String getCurrentInstructionSet();
+
}
diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java
index d1b9a18..c66b01a 100644
--- a/libart/src/main/java/java/lang/Class.java
+++ b/libart/src/main/java/java/lang/Class.java
@@ -37,7 +37,6 @@ import dalvik.system.VMStack;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
-import java.lang.reflect.AbstractMethod;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.ArtField;
@@ -63,6 +62,7 @@ import libcore.reflect.Types;
import libcore.util.BasicLruCache;
import libcore.util.CollectionUtils;
import libcore.util.EmptyArray;
+import libcore.util.SneakyThrow;
/**
* The in-memory representation of a Java class. This representation serves as
@@ -166,6 +166,9 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*/
private transient Object[] ifTable;
+ /** Interface method table (imt), for quick "invoke-interface". */
+ private transient ArtMethod[] imTable;
+
/** Lazily computed name of this class; always prefer calling getName(). */
private transient String name;
@@ -952,7 +955,10 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* method or constructor.
*/
public Class<?> getDeclaringClass() {
- return AnnotationAccess.getDeclaringClass(this);
+ if (AnnotationAccess.isAnonymousClass(this)) {
+ return null;
+ }
+ return AnnotationAccess.getEnclosingClass(this);
}
/**
@@ -967,9 +973,10 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
return declaringClass;
}
AccessibleObject member = AnnotationAccess.getEnclosingMethodOrConstructor(this);
- return member != null
- ? ((Member) member).getDeclaringClass()
- : null;
+ if (member != null) {
+ return ((Member) member).getDeclaringClass();
+ }
+ return AnnotationAccess.getEnclosingClass(this);
}
/**
@@ -1139,6 +1146,12 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*/
public Type getGenericSuperclass() {
Type genericSuperclass = getSuperclass();
+ // This method is specified to return null for all cases where getSuperclass
+ // returns null, i.e, for primitives, interfaces, void and java.lang.Object.
+ if (genericSuperclass == null) {
+ return null;
+ }
+
String annotationSignature = AnnotationAccess.getSignature(this);
if (annotationSignature != null) {
GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
@@ -1541,7 +1554,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
Class<?> caller = VMStack.getStackClass1();
if (!caller.canAccess(this)) {
- throw new IllegalAccessException(this + " is not accessible from " + caller);
+ throw new IllegalAccessException(this + " is not accessible from " + caller);
}
Constructor<T> init;
try {
@@ -1553,14 +1566,13 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
throw t;
}
if (!caller.canAccessMember(this, init.getAccessFlags())) {
- throw new IllegalAccessException(init + " is not accessible from " + caller);
+ throw new IllegalAccessException(init + " is not accessible from " + caller);
}
try {
- return init.newInstance();
+ return init.newInstance(null, init.isAccessible());
} catch (InvocationTargetException e) {
- InstantiationException t = new InstantiationException(this);
- t.initCause(e);
- throw t;
+ SneakyThrow.sneakyThrow(e.getCause());
+ return null; // Unreachable.
}
}
diff --git a/libart/src/main/java/java/lang/ClassLoader.java b/libart/src/main/java/java/lang/ClassLoader.java
index fb2eb8f..9079dc4 100644
--- a/libart/src/main/java/java/lang/ClassLoader.java
+++ b/libart/src/main/java/java/lang/ClassLoader.java
@@ -42,8 +42,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* Loads classes and resources from a repository. One or more class loaders are
@@ -100,8 +100,8 @@ public abstract class ClassLoader {
*
* @hide
*/
- public final Map<Set<Class<?>>, Class<?>> proxyCache
- = Collections.synchronizedMap(new HashMap<Set<Class<?>>, Class<?>>());
+ public final Map<List<Class<?>>, Class<?>> proxyCache =
+ new HashMap<List<Class<?>>, Class<?>>();
/**
* Create the system class loader. Note this is NOT the bootstrap class
diff --git a/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java
index 1422c13..6b3344c 100644
--- a/libart/src/main/java/java/lang/Daemons.java
+++ b/libart/src/main/java/java/lang/Daemons.java
@@ -192,6 +192,7 @@ public final class Daemons {
// The RI silently swallows these, but Android has always logged.
System.logE("Uncaught exception thrown by finalizer", ex);
} finally {
+ // Done finalizing, stop holding the object as live.
finalizingObject = null;
}
}
@@ -207,24 +208,29 @@ public final class Daemons {
@Override public void run() {
while (isRunning()) {
- Object object = waitForObject();
- if (object == null) {
+ boolean waitSuccessful = waitForObject();
+ if (waitSuccessful == false) {
// We have been interrupted, need to see if this daemon has been stopped.
continue;
}
- boolean finalized = waitForFinalization(object);
+ boolean finalized = waitForFinalization();
if (!finalized && !VMRuntime.getRuntime().isDebuggerActive()) {
- finalizerTimedOut(object);
- break;
+ Object finalizedObject = FinalizerDaemon.INSTANCE.finalizingObject;
+ // At this point we probably timed out, look at the object in case the finalize
+ // just finished.
+ if (finalizedObject != null) {
+ finalizerTimedOut(finalizedObject);
+ break;
+ }
}
}
}
- private Object waitForObject() {
+ private boolean waitForObject() {
while (true) {
Object object = FinalizerDaemon.INSTANCE.finalizingObject;
if (object != null) {
- return object;
+ return true;
}
synchronized (this) {
// wait until something is ready to be finalized
@@ -233,7 +239,7 @@ public final class Daemons {
wait();
} catch (InterruptedException e) {
// Daemon.stop may have interrupted us.
- return null;
+ return false;
}
}
}
@@ -257,9 +263,14 @@ public final class Daemons {
}
}
- private boolean waitForFinalization(Object object) {
- sleepFor(FinalizerDaemon.INSTANCE.finalizingStartedNanos, MAX_FINALIZE_NANOS);
- return object != FinalizerDaemon.INSTANCE.finalizingObject;
+ private boolean waitForFinalization() {
+ long startTime = FinalizerDaemon.INSTANCE.finalizingStartedNanos;
+ sleepFor(startTime, MAX_FINALIZE_NANOS);
+ // If we are finalizing an object and the start time is the same, it must be that we
+ // timed out finalizing something. It may not be the same object that we started out
+ // with but this doesn't matter.
+ return FinalizerDaemon.INSTANCE.finalizingObject == null ||
+ FinalizerDaemon.INSTANCE.finalizingStartedNanos != startTime;
}
private static void finalizerTimedOut(Object object) {
@@ -312,11 +323,9 @@ public final class Daemons {
private static class GCDaemon extends Daemon {
private static final GCDaemon INSTANCE = new GCDaemon();
- private int count = 0;
public void requestGC() {
synchronized (this) {
- ++count;
notify();
}
}
@@ -325,11 +334,8 @@ public final class Daemons {
while (isRunning()) {
try {
synchronized (this) {
- // Wait until a request comes in, unless we have a pending request.
- while (count == 0) {
- wait();
- }
- --count;
+ // Wait until a request comes in.
+ wait();
}
VMRuntime.getRuntime().concurrentGC();
} catch (InterruptedException ignored) {
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
index 3603f9c..e4caffa 100644
--- a/libart/src/main/java/java/lang/DexCache.java
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -43,9 +43,6 @@ final class DexCache {
/** Lazily initialized dex file wrapper. Volatile to avoid double-check locking issues. */
private volatile Dex dex;
- /** Indexed by the type index array of locations of initialized static storage. */
- Object[] initializedStaticStorage;
-
/** The location of the associated dex file. */
String location;
@@ -74,7 +71,7 @@ final class DexCache {
String[] strings;
/** Holds C pointer to dexFile. */
- private int dexFile;
+ private long dexFile;
// Only created by the VM.
private DexCache() {}
diff --git a/libart/src/main/java/java/lang/Enum.java b/libart/src/main/java/java/lang/Enum.java
index f98554a..ac5fc9a 100644
--- a/libart/src/main/java/java/lang/Enum.java
+++ b/libart/src/main/java/java/lang/Enum.java
@@ -39,6 +39,7 @@ public abstract class Enum<E extends Enum<E>> implements Serializable, Comparabl
}
try {
Method method = enumType.getDeclaredMethod("values", EmptyArray.CLASS);
+ method.setAccessible(true);
return (Object[]) method.invoke((Object[]) null);
} catch (NoSuchMethodException impossible) {
throw new AssertionError("impossible", impossible);
@@ -148,7 +149,7 @@ public abstract class Enum<E extends Enum<E>> implements Serializable, Comparabl
* @see java.lang.Comparable
*/
public final int compareTo(E o) {
- return ordinal - o.ordinal;
+ return ordinal - ((Enum<?>) o).ordinal;
}
/**
diff --git a/libart/src/main/java/java/lang/Object.java b/libart/src/main/java/java/lang/Object.java
index 9c59870..20fdbf9 100644
--- a/libart/src/main/java/java/lang/Object.java
+++ b/libart/src/main/java/java/lang/Object.java
@@ -133,13 +133,19 @@ public class Object {
private transient Class<?> shadow$_klass_;
private transient int shadow$_monitor_;
+ // Uncomment the following two fields to enable brooks pointers.
+ // Meant to do "#ifdef USE_BROOKS_POINTER ... #endif" but no macros.
+ //
+ // Note names use a 'x' prefix and the _x_rb_ptr_ field is of
+ // type int instead of Object to go with the alphabetical/by-type
+ // field order.
+ // private transient int shadow$_x_rb_ptr_;
+ // private transient int shadow$_x_xpadding_;
+
/**
* Constructs a new instance of {@code Object}.
*/
public Object() {
- if (shadow$_klass_.isFinalizable()) {
- java.lang.ref.FinalizerReference.add(this);
- }
}
/**
@@ -267,6 +273,12 @@ public class Object {
* @see #equals
*/
public int hashCode() {
+ int lockWord = shadow$_monitor_;
+ final int lockWordMask = 0xC0000000; // Top 2 bits.
+ final int lockWordStateHash = 0x80000000; // Top 2 bits are value 2 (kStateHash).
+ if ((lockWord & lockWordMask) == lockWordStateHash) {
+ return lockWord & ~lockWordMask;
+ }
return System.identityHashCode(this);
}
@@ -278,10 +290,9 @@ public class Object {
* that called {@code notify()} has to release the object's monitor first.
* Also, the chosen thread still has to compete against other threads that
* try to synchronize on the same object.
- * <p>
- * This method can only be invoked by a thread which owns this object's
+ *
+ * <p>This method can only be invoked by a thread which owns this object's
* monitor. A thread becomes owner of an object's monitor
- * </p>
* <ul>
* <li>by executing a synchronized method of that object;</li>
* <li>by executing the body of a {@code synchronized} statement that
@@ -304,10 +315,9 @@ public class Object {
* will not run immediately. The thread that called {@code notify()} has to
* release the object's monitor first. Also, the threads still have to
* compete against other threads that try to synchronize on the same object.
- * <p>
- * This method can only be invoked by a thread which owns this object's
+ *
+ * <p>This method can only be invoked by a thread which owns this object's
* monitor. A thread becomes owner of an object's monitor
- * </p>
* <ul>
* <li>by executing a synchronized method of that object;</li>
* <li>by executing the body of a {@code synchronized} statement that
@@ -349,23 +359,22 @@ public class Object {
* notify()} or {@code notifyAll()} method of this object. This method can
* only be invoked by a thread which owns this object's monitor; see
* {@link #notify()} on how a thread can become the owner of a monitor.
- * <p>
- * A waiting thread can be sent {@code interrupt()} to cause it to
+ *
+ * <p>A waiting thread can be sent {@code interrupt()} to cause it to
* prematurely stop waiting, so {@code wait} should be called in a loop to
* check that the condition that has been waited for has been met before
* continuing.
- * </p>
- * <p>
- * While the thread waits, it gives up ownership of this object's monitor.
- * When it is notified (or interrupted), it re-acquires the monitor before
- * it starts running.
- * </p>
+ *
+ * <p>While the thread waits, it gives up ownership of this object's
+ * monitor. When it is notified (or interrupted), it re-acquires the monitor
+ * before it starts running.
*
* @throws IllegalMonitorStateException
* if the thread calling this method is not the owner of this
* object's monitor.
- * @throws InterruptedException
- * if another thread interrupts this thread while it is waiting.
+ * @throws InterruptedException if the current thread has been interrupted.
+ * The interrupted status of the current thread will be cleared before the exception
+ * is thrown.
* @see #notify
* @see #notifyAll
* @see #wait(long)
@@ -380,17 +389,18 @@ public class Object {
* specified timeout expires. This method can only be invoked by a thread
* which owns this object's monitor; see {@link #notify()} on how a thread
* can become the owner of a monitor.
- * <p>
- * A waiting thread can be sent {@code interrupt()} to cause it to
+ *
+ * <p>A waiting thread can be sent {@code interrupt()} to cause it to
* prematurely stop waiting, so {@code wait} should be called in a loop to
* check that the condition that has been waited for has been met before
* continuing.
- * </p>
- * <p>
- * While the thread waits, it gives up ownership of this object's monitor.
- * When it is notified (or interrupted), it re-acquires the monitor before
- * it starts running.
- * </p>
+ *
+ * <p>While the thread waits, it gives up ownership of this object's
+ * monitor. When it is notified (or interrupted), it re-acquires the monitor
+ * before it starts running.
+ *
+ * <p>A timeout of zero means the calling thread should wait forever unless interrupted or
+ * notified.
*
* @param millis
* the maximum time to wait in milliseconds.
@@ -399,8 +409,9 @@ public class Object {
* @throws IllegalMonitorStateException
* if the thread calling this method is not the owner of this
* object's monitor.
- * @throws InterruptedException
- * if another thread interrupts this thread while it is waiting.
+ * @throws InterruptedException if the current thread has been interrupted.
+ * The interrupted status of the current thread will be cleared before the exception
+ * is thrown.
* @see #notify
* @see #notifyAll
* @see #wait()
@@ -417,17 +428,18 @@ public class Object {
* specified timeout expires. This method can only be invoked by a thread
* that owns this object's monitor; see {@link #notify()} on how a thread
* can become the owner of a monitor.
- * <p>
- * A waiting thread can be sent {@code interrupt()} to cause it to
+ *
+ * <p>A waiting thread can be sent {@code interrupt()} to cause it to
* prematurely stop waiting, so {@code wait} should be called in a loop to
* check that the condition that has been waited for has been met before
* continuing.
- * </p>
- * <p>
- * While the thread waits, it gives up ownership of this object's monitor.
- * When it is notified (or interrupted), it re-acquires the monitor before
- * it starts running.
- * </p>
+ *
+ * <p>While the thread waits, it gives up ownership of this object's
+ * monitor. When it is notified (or interrupted), it re-acquires the monitor
+ * before it starts running.
+ *
+ * <p>A timeout of zero means the calling thread should wait forever unless interrupted or
+ * notified.
*
* @param millis
* the maximum time to wait in milliseconds.
@@ -440,8 +452,9 @@ public class Object {
* @throws IllegalMonitorStateException
* if the thread calling this method is not the owner of this
* object's monitor.
- * @throws InterruptedException
- * if another thread interrupts this thread while it is waiting.
+ * @throws InterruptedException if the current thread has been interrupted.
+ * The interrupted status of the current thread will be cleared before the exception
+ * is thrown.
* @see #notify
* @see #notifyAll
* @see #wait()
diff --git a/libart/src/main/java/java/lang/String.java b/libart/src/main/java/java/lang/String.java
index 385f549..0107b6e 100644
--- a/libart/src/main/java/java/lang/String.java
+++ b/libart/src/main/java/java/lang/String.java
@@ -31,23 +31,22 @@ import java.util.regex.Pattern;
import libcore.util.EmptyArray;
/**
- * An immutable sequence of characters/code units ({@code char}s). A
- * {@code String} is represented by array of UTF-16 values, such that
- * Unicode supplementary characters (code points) are stored/encoded as
- * surrogate pairs via Unicode code units ({@code char}).
+ * An immutable sequence of UTF-16 {@code char}s.
+ * See {@link Character} for details about the relationship between {@code char} and
+ * Unicode code points.
*
* <a name="backing_array"><h3>Backing Arrays</h3></a>
- * This class is implemented using a char[]. The length of the array may exceed
+ * This class is implemented using a {@code char[]}. The length of the array may exceed
* the length of the string. For example, the string "Hello" may be backed by
* the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with
* offset 0 and length 5.
*
- * <p>Multiple strings can share the same char[] because strings are immutable.
+ * <p>Multiple strings can share the same {@code char[]} because strings are immutable.
* The {@link #substring} method <strong>always</strong> returns a string that
* shares the backing array of its source string. Generally this is an
- * optimization: fewer character arrays need to be allocated, and less copying
+ * optimization: fewer {@code char[]}s need to be allocated, and less copying
* is necessary. But this can also lead to unwanted heap retention. Taking a
- * short substring of long string means that the long shared char[] won't be
+ * short substring of long string means that the long shared {@code char[]} won't be
* garbage until both strings are garbage. This typically happens when parsing
* small substrings out of a large input. To avoid this where necessary, call
* {@code new String(longString.subString(...))}. The string copy constructor
@@ -64,23 +63,12 @@ public final class String implements Serializable, Comparable<String>, CharSeque
private static final char REPLACEMENT_CHAR = (char) 0xfffd;
- /**
- * CaseInsensitiveComparator compares Strings ignoring the case of the
- * characters.
- */
private static final class CaseInsensitiveComparator implements
Comparator<String>, Serializable {
private static final long serialVersionUID = 8575799808933029326L;
/**
- * Compare the two objects to determine the relative ordering.
- *
- * @param o1
- * an Object to compare
- * @param o2
- * an Object to compare
- * @return an int < 0 if object1 is less than object2, 0 if they are
- * equal, and > 0 if object1 is greater
+ * See {@link java.lang.String#compareToIgnoreCase}.
*
* @exception ClassCastException
* if objects are not the correct type
@@ -91,7 +79,9 @@ public final class String implements Serializable, Comparable<String>, CharSeque
}
/**
- * A comparator ignoring the case of the characters.
+ * Compares strings using {@link #compareToIgnoreCase}.
+ * This is not suitable for case-insensitive string comparison for all locales.
+ * Use a {@link java.text.Collator} instead.
*/
public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
@@ -131,7 +121,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque
/**
* Converts the byte array to a string, setting the high byte of every
- * character to the specified value.
+ * {@code char} to the specified value.
*
* @param data
* the byte array to convert to a string.
@@ -161,7 +151,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque
/**
* Converts the byte array to a string, setting the high byte of every
- * character to {@code high}.
+ * {@code char} to {@code high}.
*
* @throws NullPointerException
* if {@code data == null}.
@@ -220,7 +210,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque
* Converts the byte array to a string using the given charset.
*
* <p>The behavior when the bytes cannot be decoded by the given charset
- * is to replace malformed input and unmappable characters with the charset's default
+ * is to replace malformed input and unmappable code points with the charset's default
* replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control.
*
* @throws IndexOutOfBoundsException
@@ -382,8 +372,8 @@ outer:
}
/**
- * Initializes this string to contain the characters in the specified
- * character array. Modifying the character array after creating the string
+ * Initializes this string to contain the given {@code char}s.
+ * Modifying the array after creating the string
* has no effect on the string.
*
* @throws NullPointerException if {@code data == null}
@@ -393,8 +383,8 @@ outer:
}
/**
- * Initializes this string to contain the specified characters in the
- * character array. Modifying the character array after creating the string
+ * Initializes this string to contain the given {@code char}s.
+ * Modifying the array after creating the string
* has no effect on the string.
*
* @throws NullPointerException
@@ -414,7 +404,7 @@ outer:
/*
* Internal version of the String(char[], int, int) constructor.
- * Does not range check, null check, or copy the character array.
+ * Does not range check, null check, or copy the array.
*/
String(int offset, int charCount, char[] chars) {
this.value = chars;
@@ -423,8 +413,8 @@ outer:
}
/**
- * Constructs a new string with the same sequence of characters as {@code
- * toCopy}. The returned string's <a href="#backing_array">backing array</a>
+ * Constructs a copy of the given string.
+ * The returned string's <a href="#backing_array">backing array</a>
* is no larger than necessary.
*/
public String(String toCopy) {
@@ -496,13 +486,8 @@ outer:
}
/**
- * Returns the character at the specified offset in this string.
- *
- * @param index
- * the zero-based index in this string.
- * @return the character at the index.
- * @throws IndexOutOfBoundsException
- * if {@code index < 0} or {@code index >= length()}.
+ * Returns the {@code char} at {@code index}.
+ * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}.
*/
public char charAt(int index) {
if (index < 0 || index >= count) {
@@ -538,44 +523,36 @@ outer:
}
/**
- * Compares the specified string to this string using the Unicode values of
- * the characters. Returns 0 if the strings contain the same characters in
- * the same order. Returns a negative integer if the first non-equal
- * character in this string has a Unicode value which is less than the
- * Unicode value of the character at the same position in the specified
- * string, or if this string is a prefix of the specified string. Returns a
- * positive integer if the first non-equal character in this string has a
- * Unicode value which is greater than the Unicode value of the character at
- * the same position in the specified string, or if the specified string is
- * a prefix of this string.
+ * Compares this string to the given string.
+ *
+ * <p>The strings are compared one {@code char} at a time.
+ * In the discussion of the return value below, note that {@code char} does not
+ * mean code point, though this should only be visible for surrogate pairs.
+ *
+ * <p>If there is an index at which the two strings differ, the result is
+ * the difference between the two {@code char}s at the lowest such index.
+ * If not, but the lengths of the strings differ, the result is the difference
+ * between the two strings' lengths.
+ * If the strings are the same length and every {@code char} is the same, the result is 0.
*
- * @param string
- * the string to compare.
- * @return 0 if the strings are equal, a negative integer if this string is
- * before the specified string, or a positive integer if this string
- * is after the specified string.
* @throws NullPointerException
* if {@code string} is {@code null}.
*/
public native int compareTo(String string);
/**
- * Compares the specified string to this string using the Unicode values of
- * the characters, ignoring case differences. Returns 0 if the strings
- * contain the same characters in the same order. Returns a negative integer
- * if the first non-equal character in this string has a Unicode value which
- * is less than the Unicode value of the character at the same position in
- * the specified string, or if this string is a prefix of the specified
- * string. Returns a positive integer if the first non-equal character in
- * this string has a Unicode value which is greater than the Unicode value
- * of the character at the same position in the specified string, or if the
- * specified string is a prefix of this string.
+ * Compares this string to the given string, ignoring case differences.
+ *
+ * <p>The strings are compared one {@code char} at a time. This is not suitable
+ * for case-insensitive string comparison for all locales.
+ * Use a {@link java.text.Collator} instead.
+ *
+ * <p>If there is an index at which the two strings differ, the result is
+ * the difference between the two {@code char}s at the lowest such index.
+ * If not, but the lengths of the strings differ, the result is the difference
+ * between the two strings' lengths.
+ * If the strings are the same length and every {@code char} is the same, the result is 0.
*
- * @param string
- * the string to compare.
- * @return 0 if the strings are equal, a negative integer if this string is
- * before the specified string, or a positive integer if this string
- * is after the specified string.
* @throws NullPointerException
* if {@code string} is {@code null}.
*/
@@ -616,13 +593,10 @@ outer:
}
/**
- * Creates a new string containing the characters in the specified character
- * array. Modifying the character array after creating the string has no
+ * Creates a new string by copying the given {@code char[]}.
+ * Modifying the array after creating the string has no
* effect on the string.
*
- * @param data
- * the array of characters.
- * @return the new string.
* @throws NullPointerException
* if {@code data} is {@code null}.
*/
@@ -631,17 +605,10 @@ outer:
}
/**
- * Creates a new string containing the specified characters in the character
- * array. Modifying the character array after creating the string has no
+ * Creates a new string by copying the given subsequence of the given {@code char[]}.
+ * Modifying the array after creating the string has no
* effect on the string.
- *
- * @param data
- * the array of characters.
- * @param start
- * the starting offset in the character array.
- * @param length
- * the number of characters to use.
- * @return the new string.
+
* @throws NullPointerException
* if {@code data} is {@code null}.
* @throws IndexOutOfBoundsException
@@ -656,10 +623,6 @@ outer:
* Compares the specified string to this string to determine if the
* specified string is a suffix.
*
- * @param suffix
- * the suffix to look for.
- * @return {@code true} if the specified string is a suffix of this string,
- * {@code false} otherwise.
* @throws NullPointerException
* if {@code suffix} is {@code null}.
*/
@@ -668,15 +631,9 @@ outer:
}
/**
- * Compares the specified object to this string and returns true if they are
- * equal. The object must be an instance of string with the same characters
- * in the same order.
- *
- * @param other
- * the object to compare.
- * @return {@code true} if the specified object is equal to this string,
- * {@code false} otherwise.
- * @see #hashCode
+ * Compares the given object to this string and returns true if they are
+ * equal. The object must be an instance of {@code String} with the same length,
+ * where for every index, {@code charAt} on each string returns the same value.
*/
@Override public boolean equals(Object other) {
if (other == this) {
@@ -715,13 +672,11 @@ outer:
}
/**
- * Compares the specified string to this string ignoring the case of the
- * characters and returns true if they are equal.
+ * Compares the given string to this string ignoring case.
*
- * @param string
- * the string to compare.
- * @return {@code true} if the specified string is equal to this string,
- * {@code false} otherwise.
+ * <p>The strings are compared one {@code char} at a time. This is not suitable
+ * for case-insensitive string comparison for all locales.
+ * Use a {@link java.text.Collator} instead.
*/
@FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
public boolean equalsIgnoreCase(String string) {
@@ -745,17 +700,17 @@ outer:
}
/**
- * Mangles this string into a byte array by stripping the high order bits from
- * each character. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
+ * Mangles a subsequence of this string into a byte array by stripping the high order bits from
+ * each {@code char}. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
*
* @param start
- * the starting offset of characters to copy.
+ * the start offset in this string.
* @param end
- * the ending offset of characters to copy.
+ * the end+1 offset in this string.
* @param data
* the destination byte array.
* @param index
- * the starting offset in the destination byte array.
+ * the start offset in the destination byte array.
* @throws NullPointerException
* if {@code data} is {@code null}.
* @throws IndexOutOfBoundsException
@@ -765,7 +720,6 @@ outer:
*/
@Deprecated
public void getBytes(int start, int end, byte[] data, int index) {
- // Note: last character not copied!
if (start >= 0 && start <= end && end <= count) {
end += offset;
try {
@@ -781,7 +735,7 @@ outer:
}
/**
- * Returns a new byte array containing the characters of this string encoded using the
+ * Returns a new byte array containing the code points in this string encoded using the
* system's {@link java.nio.charset.Charset#defaultCharset default charset}.
*
* <p>The behavior when this string cannot be represented in the system's default charset
@@ -793,7 +747,7 @@ outer:
}
/**
- * Returns a new byte array containing the characters of this string encoded using the
+ * Returns a new byte array containing the code points of this string encoded using the
* named charset.
*
* <p>The behavior when this string cannot be represented in the named charset
@@ -806,11 +760,11 @@ outer:
}
/**
- * Returns a new byte array containing the characters of this string encoded using the
+ * Returns a new byte array containing the code points of this string encoded using the
* given charset.
*
* <p>The behavior when this string cannot be represented in the given charset
- * is to replace malformed input and unmappable characters with the charset's default
+ * is to replace malformed input and unmappable code points with the charset's default
* replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control.
*
* @since 1.6
@@ -835,17 +789,17 @@ outer:
}
/**
- * Copies the specified characters in this string to the character array
- * starting at the specified offset in the character array.
+ * Copies the given subsequence of this string to the given array
+ * starting at the given offset.
*
* @param start
- * the starting offset of characters to copy.
+ * the start offset in this string.
* @param end
- * the ending offset of characters to copy.
+ * the end+1 offset in this string.
* @param buffer
- * the destination character array.
+ * the destination array.
* @param index
- * the starting offset in the character array.
+ * the start offset in the destination array.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
* @throws IndexOutOfBoundsException
@@ -854,7 +808,6 @@ outer:
* index}
*/
public void getChars(int start, int end, char[] buffer, int index) {
- // Note: last character not copied!
if (start >= 0 && start <= end && end <= count) {
System.arraycopy(value, start + offset, buffer, index, end - start);
} else {
@@ -864,12 +817,11 @@ outer:
}
/**
- * Version of getChars without bounds checks, for use by other classes
+ * getChars without bounds checks, for use by other classes
* within the java.lang package only. The caller is responsible for
* ensuring that start >= 0 && start <= end && end <= count.
*/
void _getChars(int start, int end, char[] buffer, int index) {
- // NOTE last character not copied!
System.arraycopy(value, start + offset, buffer, index, end - start);
}
@@ -890,14 +842,9 @@ outer:
}
/**
- * Searches in this string for the first index of the specified character.
- * The search for the character starts at the beginning and moves towards
+ * Returns the first index of the given code point, or -1.
+ * The search starts at the beginning and moves towards
* the end of this string.
- *
- * @param c
- * the character to find.
- * @return the index in this string of the specified character, -1 if the
- * character isn't found.
*/
public int indexOf(int c) {
// TODO: just "return indexOf(c, 0);" when the JIT can inline that deep.
@@ -908,16 +855,9 @@ outer:
}
/**
- * Searches in this string for the index of the specified character. The
- * search for the character starts at the specified offset and moves towards
+ * Returns the next index of the given code point, or -1. The
+ * search starts at the given offset and moves towards
* the end of this string.
- *
- * @param c
- * the character to find.
- * @param start
- * the starting offset.
- * @return the index in this string of the specified character, -1 if the
- * character isn't found.
*/
public int indexOf(int c, int start) {
if (c > 0xffff) {
@@ -938,14 +878,10 @@ outer:
}
/**
- * Searches in this string for the first index of the specified string. The
- * search for the string starts at the beginning and moves towards the end
+ * Returns the first index of the given string, or -1. The
+ * search starts at the beginning and moves towards the end
* of this string.
*
- * @param string
- * the string to find.
- * @return the index of the first character of the specified string in this
- * string, -1 if the specified string is not a substring.
* @throws NullPointerException
* if {@code string} is {@code null}.
*/
@@ -981,16 +917,10 @@ outer:
}
/**
- * Searches in this string for the index of the specified string. The search
- * for the string starts at the specified offset and moves towards the end
+ * Returns the next index of the given string in this string, or -1. The search
+ * for the string starts at the given offset and moves towards the end
* of this string.
*
- * @param subString
- * the string to find.
- * @param start
- * the starting offset.
- * @return the index of the first character of the specified string in this
- * string, -1 if the specified string is not a substring.
* @throws NullPointerException
* if {@code subString} is {@code null}.
*/
@@ -1053,7 +983,7 @@ outer:
/**
* Returns the last index of the code point {@code c}, or -1.
- * The search for the character starts at the end and moves towards the
+ * The search starts at the end and moves towards the
* beginning of this string.
*/
public int lastIndexOf(int c) {
@@ -1073,7 +1003,7 @@ outer:
/**
* Returns the last index of the code point {@code c}, or -1.
- * The search for the character starts at offset {@code start} and moves towards
+ * The search starts at offset {@code start} and moves towards
* the beginning of this string.
*/
public int lastIndexOf(int c, int start) {
@@ -1106,14 +1036,10 @@ outer:
}
/**
- * Searches in this string for the last index of the specified string. The
- * search for the string starts at the end and moves towards the beginning
+ * Returns the index of the start of the last match for the given string in this string, or -1.
+ * The search for the string starts at the end and moves towards the beginning
* of this string.
*
- * @param string
- * the string to find.
- * @return the index of the first character of the specified string in this
- * string, -1 if the specified string is not a substring.
* @throws NullPointerException
* if {@code string} is {@code null}.
*/
@@ -1123,16 +1049,11 @@ outer:
}
/**
- * Searches in this string for the index of the specified string. The search
- * for the string starts at the specified offset and moves towards the
- * beginning of this string.
+ * Returns the index of the start of the previous match for the given string in this string,
+ * or -1.
+ * The search for the string starts at the given index and moves towards the beginning
+ * of this string.
*
- * @param subString
- * the string to find.
- * @param start
- * the starting offset.
- * @return the index of the first character of the specified string in this
- * string , -1 if the specified string is not a substring.
* @throws NullPointerException
* if {@code subString} is {@code null}.
*/
@@ -1169,26 +1090,21 @@ outer:
}
/**
- * Returns the number of characters in this string.
+ * Returns the number of {@code char}s in this string. If this string contains surrogate pairs,
+ * this is not the same as the number of code points.
*/
public int length() {
return count;
}
/**
- * Compares the specified string to this string and compares the specified
- * range of characters to determine if they are the same.
+ * Returns true if the given subsequence of the given string matches this string starting
+ * at the given offset.
*
- * @param thisStart
- * the starting offset in this string.
- * @param string
- * the string to compare.
- * @param start
- * the starting offset in the specified string.
- * @param length
- * the number of characters to compare.
- * @return {@code true} if the ranges of characters are equal, {@code false}
- * otherwise
+ * @param thisStart the start offset in this string.
+ * @param string the other string.
+ * @param start the start offset in {@code string}.
+ * @param length the number of {@code char}s to compare.
* @throws NullPointerException
* if {@code string} is {@code null}.
*/
@@ -1217,22 +1133,21 @@ outer:
}
/**
- * Compares the specified string to this string and compares the specified
- * range of characters to determine if they are the same. When ignoreCase is
- * true, the case of the characters is ignored during the comparison.
+ * Returns true if the given subsequence of the given string matches this string starting
+ * at the given offset.
+ *
+ * <p>If ignoreCase is true, case is ignored during the comparison.
+ * The strings are compared one {@code char} at a time. This is not suitable
+ * for case-insensitive string comparison for all locales.
+ * Use a {@link java.text.Collator} instead.
*
* @param ignoreCase
- * specifies if case should be ignored.
- * @param thisStart
- * the starting offset in this string.
- * @param string
- * the string to compare.
- * @param start
- * the starting offset in the specified string.
- * @param length
- * the number of characters to compare.
- * @return {@code true} if the ranges of characters are equal, {@code false}
- * otherwise.
+ * specifies if case should be ignored (use {@link java.text.Collator} instead for
+ * non-ASCII case insensitivity).
+ * @param thisStart the start offset in this string.
+ * @param string the other string.
+ * @param start the start offset in {@code string}.
+ * @param length the number of {@code char}s to compare.
* @throws NullPointerException
* if {@code string} is {@code null}.
*/
@@ -1264,14 +1179,7 @@ outer:
}
/**
- * Copies this string replacing occurrences of the specified character with
- * another character.
- *
- * @param oldChar
- * the character to replace.
- * @param newChar
- * the replacement character.
- * @return a new string with occurrences of oldChar replaced by newChar.
+ * Returns a copy of this string after replacing occurrences of the given {@code char} with another.
*/
public String replace(char oldChar, char newChar) {
char[] buffer = value;
@@ -1300,15 +1208,10 @@ outer:
}
/**
- * Copies this string replacing occurrences of the specified target sequence
- * with another sequence. The string is processed from the beginning to the
+ * Returns a copy of this string after replacing occurrences of {@code target} replaced
+ * with {@code replacement}. The string is processed from the beginning to the
* end.
*
- * @param target
- * the sequence to replace.
- * @param replacement
- * the replacement sequence.
- * @return the resulting string.
* @throws NullPointerException
* if {@code target} or {@code replacement} is {@code null}.
*/
@@ -1329,11 +1232,11 @@ outer:
String replacementString = replacement.toString();
- // The empty target matches at the start and end and between each character.
+ // The empty target matches at the start and end and between each char.
int targetLength = targetString.length();
if (targetLength == 0) {
- // The result contains the original 'count' characters, a copy of the
- // replacement string before every one of those characters, and a final
+ // The result contains the original 'count' chars, a copy of the
+ // replacement string before every one of those chars, and a final
// copy of the replacement string at the end.
int resultLength = count + (count + 1) * replacementString.length();
StringBuilder result = new StringBuilder(resultLength);
@@ -1349,7 +1252,7 @@ outer:
StringBuilder result = new StringBuilder(count);
int searchStart = 0;
do {
- // Copy characters before the match...
+ // Copy chars before the match...
result.append(value, offset + searchStart, matchStart - searchStart);
// Insert the replacement...
result.append(replacementString);
@@ -1394,13 +1297,9 @@ outer:
}
/**
- * Returns a string containing a suffix of this string. The returned string
- * shares this string's <a href="#backing_array">backing array</a>.
+ * Returns a string containing a suffix of this string starting at {@code start}.
+ * The returned string shares this string's <a href="#backing_array">backing array</a>.
*
- * @param start
- * the offset of the first character.
- * @return a new string containing the characters from start to the end of
- * the string.
* @throws IndexOutOfBoundsException
* if {@code start < 0} or {@code start > length()}.
*/
@@ -1415,24 +1314,18 @@ outer:
}
/**
- * Returns a string containing a subsequence of characters from this string.
- * The returned string shares this string's <a href="#backing_array">backing
- * array</a>.
+ * Returns a string containing the given subsequence of this string.
+ * The returned string shares this string's <a href="#backing_array">backing array</a>.
*
- * @param start
- * the offset of the first character.
- * @param end
- * the offset one past the last character.
- * @return a new string containing the characters from start to end - 1
+ * @param start the start offset.
+ * @param end the end+1 offset.
* @throws IndexOutOfBoundsException
- * if {@code start < 0}, {@code start > end} or {@code end >
- * length()}.
+ * if {@code start < 0}, {@code start > end} or {@code end > length()}.
*/
public String substring(int start, int end) {
if (start == 0 && end == count) {
return this;
}
- // NOTE last character not copied!
// Fast range check.
if (start >= 0 && start <= end && end <= count) {
return new String(offset + start, end - start, value);
@@ -1441,8 +1334,8 @@ outer:
}
/**
- * Returns a new {@code char} array containing a copy of the characters in this string.
- * This is expensive and rarely useful. If you just want to iterate over the characters in
+ * Returns a new {@code char} array containing a copy of the {@code char}s in this string.
+ * This is expensive and rarely useful. If you just want to iterate over the {@code char}s in
* the string, use {@link #charAt} instead.
*/
public char[] toCharArray() {
@@ -1514,11 +1407,8 @@ outer:
}
/**
- * Copies this string removing white space characters from the beginning and
- * end of the string.
- *
- * @return a new string with characters <code><= \\u0020</code> removed from
- * the beginning and the end.
+ * Returns a string with no code points <code><= \\u0020</code> at
+ * the beginning or end.
*/
public String trim() {
int start = offset, last = offset + count - 1;
@@ -1536,13 +1426,10 @@ outer:
}
/**
- * Creates a new string containing the characters in the specified character
- * array. Modifying the character array after creating the string has no
+ * Returns a new string containing the same {@code char}s as the given
+ * array. Modifying the array after creating the string has no
* effect on the string.
*
- * @param data
- * the array of characters.
- * @return the new string.
* @throws NullPointerException
* if {@code data} is {@code null}.
*/
@@ -1551,20 +1438,12 @@ outer:
}
/**
- * Creates a new string containing the specified characters in the character
- * array. Modifying the character array after creating the string has no
+ * Returns a new string containing the same {@code char}s as the given
+ * subset of the given array. Modifying the array after creating the string has no
* effect on the string.
*
- * @param data
- * the array of characters.
- * @param start
- * the starting offset in the character array.
- * @param length
- * the number of characters to use.
- * @return the new string.
* @throws IndexOutOfBoundsException
- * if {@code length < 0}, {@code start < 0} or {@code start +
- * length > data.length}
+ * if {@code length < 0}, {@code start < 0} or {@code start + length > data.length}
* @throws NullPointerException
* if {@code data} is {@code null}.
*/
@@ -1573,11 +1452,7 @@ outer:
}
/**
- * Converts the specified character to its string representation.
- *
- * @param value
- * the character.
- * @return the character converted to a string.
+ * Returns a new string of just the given {@code char}.
*/
public static String valueOf(char value) {
String s;
@@ -1591,44 +1466,28 @@ outer:
}
/**
- * Converts the specified double to its string representation.
- *
- * @param value
- * the double.
- * @return the double converted to a string.
+ * Returns the string representation of the given double.
*/
public static String valueOf(double value) {
return Double.toString(value);
}
/**
- * Converts the specified float to its string representation.
- *
- * @param value
- * the float.
- * @return the float converted to a string.
+ * Returns the string representation of the given float.
*/
public static String valueOf(float value) {
return Float.toString(value);
}
/**
- * Converts the specified integer to its string representation.
- *
- * @param value
- * the integer.
- * @return the integer converted to a string.
+ * Returns the string representation of the given int.
*/
public static String valueOf(int value) {
return Integer.toString(value);
}
/**
- * Converts the specified long to its string representation.
- *
- * @param value
- * the long.
- * @return the long converted to a string.
+ * Returns the string representation of the given long.
*/
public static String valueOf(long value) {
return Long.toString(value);
@@ -1661,36 +1520,27 @@ outer:
}
/**
- * Returns whether the characters in the StringBuffer {@code strbuf} are the
- * same as those in this string.
+ * Returns true if the {@code char}s in the given {@code StringBuffer} are the same
+ * as those in this string.
*
- * @param strbuf
- * the StringBuffer to compare this string to.
- * @return {@code true} if the characters in {@code strbuf} are identical to
- * those in this string. If they are not, {@code false} will be
- * returned.
* @throws NullPointerException
- * if {@code strbuf} is {@code null}.
+ * if {@code sb} is {@code null}.
* @since 1.4
*/
- public boolean contentEquals(StringBuffer strbuf) {
- synchronized (strbuf) {
- int size = strbuf.length();
+ public boolean contentEquals(StringBuffer sb) {
+ synchronized (sb) {
+ int size = sb.length();
if (count != size) {
return false;
}
- return regionMatches(0, new String(0, size, strbuf.getValue()), 0,
- size);
+ return regionMatches(0, new String(0, size, sb.getValue()), 0, size);
}
}
/**
- * Compares a {@code CharSequence} to this {@code String} to determine if
- * their contents are equal.
+ * Returns true if the {@code char}s in the given {@code CharSequence} are the same
+ * as those in this string.
*
- * @param cs
- * the character sequence to compare to.
- * @return {@code true} if equal, otherwise {@code false}
* @since 1.5
*/
public boolean contentEquals(CharSequence cs) {
@@ -1809,14 +1659,8 @@ outer:
}
/**
- * Has the same result as the substring function, but is present so that
- * string may implement the CharSequence interface.
+ * Equivalent to {@link #substring(int, int)} but needed to implement {@code CharSequence}.
*
- * @param start
- * the offset the first character.
- * @param end
- * the offset of one past the last character to include.
- * @return the subsequence requested.
* @throws IndexOutOfBoundsException
* if {@code start < 0}, {@code end < 0}, {@code start > end} or
* {@code end > length()}.
@@ -1877,13 +1721,8 @@ outer:
}
/**
- * Determines if this {@code String} contains the sequence of characters in
- * the {@code CharSequence} passed.
+ * Returns true if this string contains the {@code chars}s from the given {@code CharSequence}.
*
- * @param cs
- * the character sequence to search for.
- * @return {@code true} if the sequence of characters are contained in this
- * string, otherwise {@code false}.
* @since 1.5
*/
public boolean contains(CharSequence cs) {
diff --git a/libart/src/main/java/java/lang/Thread.java b/libart/src/main/java/java/lang/Thread.java
index 5c81e36..852e2cf 100644
--- a/libart/src/main/java/java/lang/Thread.java
+++ b/libart/src/main/java/java/lang/Thread.java
@@ -124,8 +124,8 @@ public class Thread implements Runnable {
*/
public static final int NORM_PRIORITY = 5;
- /* some of these are accessed directly by the VM; do not rename them */
- private volatile int nativePeer;
+ /* Some of these are accessed directly by the VM; do not rename them. */
+ private volatile long nativePeer;
volatile ThreadGroup group;
volatile boolean daemon;
volatile String name;
@@ -712,8 +712,9 @@ public class Thread implements Runnable {
* Blocks the current Thread (<code>Thread.currentThread()</code>) until
* the receiver finishes its execution and dies.
*
- * @throws InterruptedException if <code>interrupt()</code> was called for
- * the receiver while it was in the <code>join()</code> call
+ * @throws InterruptedException if the current thread has been interrupted.
+ * The interrupted status of the current thread will be cleared before the exception is
+ * thrown.
* @see Object#notifyAll
* @see java.lang.ThreadDeath
*/
@@ -730,9 +731,12 @@ public class Thread implements Runnable {
* the receiver finishes its execution and dies or the specified timeout
* expires, whatever happens first.
*
+ * <p>A timeout of zero means the calling thread should wait forever unless interrupted.
+ *
* @param millis The maximum time to wait (in milliseconds).
- * @throws InterruptedException if <code>interrupt()</code> was called for
- * the receiver while it was in the <code>join()</code> call
+ * @throws InterruptedException if the current thread has been interrupted.
+ * The interrupted status of the current thread will be cleared before the exception is
+ * thrown.
* @see Object#notifyAll
* @see java.lang.ThreadDeath
*/
@@ -745,10 +749,13 @@ public class Thread implements Runnable {
* the receiver finishes its execution and dies or the specified timeout
* expires, whatever happens first.
*
+ * <p>A timeout of zero means the calling thread should wait forever unless interrupted.
+ *
* @param millis The maximum time to wait (in milliseconds).
* @param nanos Extra nanosecond precision
- * @throws InterruptedException if <code>interrupt()</code> was called for
- * the receiver while it was in the <code>join()</code> call
+ * @throws InterruptedException if the current thread has been interrupted.
+ * The interrupted status of the current thread will be cleared before the exception is
+ * thrown.
* @see Object#notifyAll
* @see java.lang.ThreadDeath
*/
@@ -969,9 +976,9 @@ public class Thread implements Runnable {
*
* @param time
* The time to sleep in milliseconds.
- * @throws InterruptedException
- * if <code>interrupt()</code> was called for this Thread while
- * it was sleeping
+ * @throws InterruptedException if the current thread has been interrupted.
+ * The interrupted status of the current thread will be cleared before the exception
+ * is thrown.
* @see Thread#interrupt()
*/
public static void sleep(long time) throws InterruptedException {
@@ -987,15 +994,29 @@ public class Thread implements Runnable {
* The time to sleep in milliseconds.
* @param nanos
* Extra nanosecond precision
- * @throws InterruptedException
- * if <code>interrupt()</code> was called for this Thread while
- * it was sleeping
+ * @throws InterruptedException if the current thread has been interrupted.
+ * The interrupted status of the current thread will be cleared before the exception
+ * is thrown.
* @see Thread#interrupt()
*/
public static void sleep(long millis, int nanos) throws InterruptedException {
+ if (millis < 0) {
+ throw new IllegalArgumentException("millis < 0: " + millis);
+ }
+ if (nanos < 0) {
+ throw new IllegalArgumentException("nanos < 0: " + nanos);
+ }
+ if (nanos > 999999) {
+ throw new IllegalArgumentException("nanos > 999999: " + nanos);
+ }
+
// The JLS 3rd edition, section 17.9 says: "...sleep for zero
// time...need not have observable effects."
if (millis == 0 && nanos == 0) {
+ // ...but we still have to handle being interrupted.
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
return;
}
diff --git a/libart/src/main/java/java/lang/ref/Reference.java b/libart/src/main/java/java/lang/ref/Reference.java
new file mode 100644
index 0000000..70967b5
--- /dev/null
+++ b/libart/src/main/java/java/lang/ref/Reference.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.ref;
+
+/**
+ * Provides an abstract class which describes behavior common to all reference
+ * objects. It is not possible to create immediate subclasses of
+ * {@code Reference} in addition to the ones provided by this package. It is
+ * also not desirable to do so, since references require very close cooperation
+ * with the system's garbage collector. The existing, specialized reference
+ * classes should be used instead.
+ *
+ * <p>Three different type of references exist, each being weaker than the preceding one:
+ * {@link java.lang.ref.SoftReference}, {@link java.lang.ref.WeakReference}, and
+ * {@link java.lang.ref.PhantomReference}. "Weakness" here means that less restrictions are
+ * being imposed on the garbage collector as to when it is allowed to
+ * actually garbage-collect the referenced object.
+ *
+ * <p>In order to use reference objects properly it is important to understand
+ * the different types of reachability that trigger their clearing and
+ * enqueueing. The following table lists these, from strongest to weakest.
+ * For each row, an object is said to have the reachability on the left side
+ * if (and only if) it fulfills all of the requirements on the right side. In
+ * all rows, consider the <em>root set</em> to be a set of references that
+ * are "resistant" to garbage collection (that is, running threads, method
+ * parameters, local variables, static fields and the like).
+ *
+ * <p><table>
+ * <tr>
+ * <td>Strongly reachable</td>
+ * <td> <ul>
+ * <li>There exists at least one path from the root set to the object that does not traverse any
+ * instance of a {@code java.lang.ref.Reference} subclass.
+ * </li>
+ * </ul> </td>
+ * </tr>
+ *
+ * <tr>
+ * <td>Softly reachable</td>
+ * <td> <ul>
+ * <li>The object is not strongly reachable.</li>
+ * <li>There exists at least one path from the root set to the object that does traverse
+ * a {@code java.lang.ref.SoftReference} instance, but no {@code java.lang.ref.WeakReference}
+ * or {@code java.lang.ref.PhantomReference} instances.</li>
+ * </ul> </td>
+ * </tr>
+ *
+ * <tr>
+ * <td>Weakly reachable</td>
+ * <td> <ul>
+ * <li>The object is neither strongly nor softly reachable.</li>
+ * <li>There exists at least one path from the root set to the object that does traverse a
+ * {@code java.lang.ref.WeakReference} instance, but no {@code java.lang.ref.PhantomReference}
+ * instances.</li>
+ * </ul> </td>
+ * </tr>
+ *
+ * <tr>
+ * <td>Phantom-reachable</td>
+ * <td> <ul>
+ * <li>The object is neither strongly, softly, nor weakly reachable.</li>
+ * <li>The object is referenced by a {@code java.lang.ref.PhantomReference} instance.</li>
+ * <li>The object has already been finalized.</li>
+ * </ul> </td>
+ * </tr>
+ * </table>
+ */
+public abstract class Reference<T> {
+
+ /**
+ * Forces JNI path.
+ * If GC is not in progress (ie: not going through slow path), the referent
+ * can be quickly returned through intrinsic without passing through JNI.
+ * This flag forces the JNI path so that it can be tested and benchmarked.
+ */
+ private static boolean disableIntrinsic = false;
+
+ /**
+ * Slow path flag for the reference processor.
+ * Used by the reference processor to determine whether or not the referent
+ * can be immediately returned. Because the referent might get swept during
+ * GC, the slow path, which passes through JNI, must be taken.
+ */
+ private static boolean slowPathEnabled = false;
+
+ /**
+ * The object to which this reference refers.
+ * VM requirement: this field <em>must</em> be called "referent"
+ * and be an object.
+ */
+ volatile T referent;
+
+ /**
+ * If non-null, the queue on which this reference will be enqueued
+ * when the referent is appropriately reachable.
+ * VM requirement: this field <em>must</em> be called "queue"
+ * and be a java.lang.ref.ReferenceQueue.
+ */
+ volatile ReferenceQueue<? super T> queue;
+
+ /**
+ * Used internally by java.lang.ref.ReferenceQueue.
+ * VM requirement: this field <em>must</em> be called "queueNext"
+ * and be a java.lang.ref.Reference.
+ */
+ @SuppressWarnings("unchecked")
+ volatile Reference queueNext;
+
+ /**
+ * Used internally by the VM. This field forms a circular and
+ * singly linked list of reference objects discovered by the
+ * garbage collector and awaiting processing by the reference
+ * queue thread.
+ *
+ * @hide
+ */
+ public volatile Reference<?> pendingNext;
+
+ /**
+ * Constructs a new instance of this class.
+ */
+ Reference() {
+ }
+
+ Reference(T r, ReferenceQueue<? super T> q) {
+ referent = r;
+ queue = q;
+ }
+
+ /**
+ * Makes the referent {@code null}. This does not force the reference
+ * object to be enqueued.
+ */
+ public void clear() {
+ referent = null;
+ }
+
+ /**
+ * Adds an object to its reference queue.
+ *
+ * @return {@code true} if this call has caused the {@code Reference} to
+ * become enqueued, or {@code false} otherwise
+ *
+ * @hide
+ */
+ public final synchronized boolean enqueueInternal() {
+ if (queue != null && queueNext == null) {
+ queue.enqueue(this);
+ queue = null;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Forces the reference object to be enqueued if it has been associated with
+ * a queue.
+ *
+ * @return {@code true} if this call has caused the {@code Reference} to
+ * become enqueued, or {@code false} otherwise
+ */
+ public boolean enqueue() {
+ return enqueueInternal();
+ }
+
+ /**
+ * Returns the referent of the reference object.
+ *
+ * @return the referent to which reference refers, or {@code null} if the
+ * object has been cleared.
+ */
+ public T get() {
+ return getReferent();
+ }
+
+ /**
+ * Returns the referent of the reference object.
+ *
+ * @return the referent to which reference refers, or {@code null} if the
+ * object has been cleared. Required since the compiler
+ * intrisifies getReferent() since we can't intrinsify Reference.get()
+ * due to incorrect devirtualization (and inlining) of PhantomReference.get().
+ */
+ private final native T getReferent();
+
+ /**
+ * Checks whether the reference object has been enqueued.
+ *
+ * @return {@code true} if the {@code Reference} has been enqueued, {@code
+ * false} otherwise
+ */
+ public boolean isEnqueued() {
+ return queueNext != null;
+ }
+
+}
diff --git a/libart/src/main/java/java/lang/reflect/AbstractMethod.java b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
index ff52b41..7e6491d 100644
--- a/libart/src/main/java/java/lang/reflect/AbstractMethod.java
+++ b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
@@ -46,8 +46,16 @@ import libcore.reflect.Types;
*/
public abstract class AbstractMethod extends AccessibleObject {
+ /**
+ * Hidden to workaround b/16828157.
+ * @hide
+ */
protected final ArtMethod artMethod;
+ /**
+ * Hidden to workaround b/16828157.
+ * @hide
+ */
protected AbstractMethod(ArtMethod artMethod) {
if (artMethod == null) {
throw new NullPointerException("artMethod == null");
@@ -135,7 +143,7 @@ public abstract class AbstractMethod extends AccessibleObject {
*
* @return the parameter types
*/
- public Class<?>[] getParameterTypes() {
+ Class<?>[] getParameterTypes() {
return artMethod.getParameterTypes();
}
diff --git a/libart/src/main/java/java/lang/reflect/AccessibleObject.java b/libart/src/main/java/java/lang/reflect/AccessibleObject.java
index dd57a12..a1e2743 100644
--- a/libart/src/main/java/java/lang/reflect/AccessibleObject.java
+++ b/libart/src/main/java/java/lang/reflect/AccessibleObject.java
@@ -71,6 +71,13 @@ public class AccessibleObject implements AnnotatedElement {
* IllegalAccessExceptions}.
*/
public void setAccessible(boolean flag) {
+ try {
+ if (equals(Class.class.getDeclaredConstructor())) {
+ throw new SecurityException("Can't make class constructor accessible");
+ }
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError("Couldn't find class constructor");
+ }
this.flag = flag;
}
diff --git a/libart/src/main/java/java/lang/reflect/ArtMethod.java b/libart/src/main/java/java/lang/reflect/ArtMethod.java
index fd73331..6d21f59 100644
--- a/libart/src/main/java/java/lang/reflect/ArtMethod.java
+++ b/libart/src/main/java/java/lang/reflect/ArtMethod.java
@@ -42,39 +42,71 @@ import libcore.util.EmptyArray;
* @hide
*/
public final class ArtMethod {
+ /* A note on the field order here, it reflects the same field order as laid out by ART. */
/** Method's declaring class */
private Class<?> declaringClass;
- /** Method access flags (modifiers) */
- private int accessFlags;
- /** DexFile index */
- private int methodDexIndex;
- /** Dispatch table entry */
- private int methodIndex;
- /** DexFile offset of CodeItem for this Method */
- private int codeItemOffset;
- /* ART compiler meta-data */
- private int frameSizeInBytes;
- private int coreSpillMask;
- private int fpSpillMask;
- private int mappingTable;
- private int gcMap;
- private int vmapTable;
- /** ART: compiled managed code associated with this Method */
- private int entryPointFromCompiledCode;
- /** ART: entry point from interpreter associated with this Method */
- private int entryPointFromInterpreter;
- /** ART: if this is a native method, the native code that will be invoked */
- private int nativeMethod;
- /* ART: dex cache fast access */
- private String[] dexCacheStrings;
- Class<?>[] dexCacheResolvedTypes;
+
+ /** Short-cut to declaringClass.dexCache.resolvedMethods */
private ArtMethod[] dexCacheResolvedMethods;
- private Object[] dexCacheInitializedStaticStorage;
+
+ /** Short-cut to declaringClass.dexCache.resolvedTypes */
+ /* package */ Class<?>[] dexCacheResolvedTypes;
+
+ /** Short-cut to declaringClass.dexCache.strings */
+ private String[] dexCacheStrings;
+
+ /**
+ * Method dispatch from the interpreter invokes this pointer which may cause a bridge into
+ * compiled code.
+ */
+ private long entryPointFromInterpreter;
+
+ /**
+ * Pointer to JNI function registered to this method, or a function to resolve the JNI function.
+ */
+ private long entryPointFromJni;
+
+ /**
+ * Method dispatch from portable compiled code invokes this pointer which may cause bridging
+ * into quick compiled code or the interpreter.
+ * Uncomment to enable.
+ */
+ // private long entryPointFromPortableCompiledCode;
+
+ /**
+ * Method dispatch from quick compiled code invokes this pointer which may cause bridging
+ * into portable compiled code or the interpreter.
+ */
+ private long entryPointFromQuickCompiledCode;
/**
- * Only created by art directly.
+ * Pointer to a data structure created by the compiler and used by the garbage collector to
+ * determine which registers hold live references to objects within the heap.
*/
+ private long gcMap;
+
+ /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */
+ private int accessFlags;
+
+ /* Dex file fields. The defining dex file is available via declaringClass.dexCache */
+
+ /** The offset of the code item associated with this method within its defining dex file */
+ private int dexCodeItemOffset;
+
+ /** The method index of this method within its defining dex file */
+ private int dexMethodIndex;
+
+ /* End of dex file fields. */
+
+ /**
+ * Entry within a dispatch table for this method. For static/direct methods the index is
+ * into the declaringClass.directMethods, for virtual methods the vtable and for
+ * interface methods the ifTable.
+ */
+ private int methodIndex;
+
+ /** Only created by ART directly. */
private ArtMethod() {}
Class getDeclaringClass() {
@@ -86,7 +118,7 @@ public final class ArtMethod {
}
int getDexMethodIndex() {
- return methodDexIndex;
+ return dexMethodIndex;
}
public static String getMethodName(ArtMethod artMethod) {
@@ -127,7 +159,7 @@ public final class ArtMethod {
Class<?>[] getParameterTypes() {
Dex dex = getDeclaringClass().getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(methodDexIndex);
+ short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
if (types.length == 0) {
return EmptyArray.CLASS;
}
@@ -141,7 +173,7 @@ public final class ArtMethod {
Class<?> getReturnType() {
Dex dex = declaringClass.getDex();
- int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(methodDexIndex);
+ int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
// Note, in the case of a Proxy the dex cache types are equal.
return getDexCacheType(dex, returnTypeIndex);
}
@@ -153,7 +185,7 @@ public final class ArtMethod {
*/
int compareParameters(Class<?>[] params) {
Dex dex = getDeclaringClass().getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(methodDexIndex);
+ short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
int length = Math.min(types.length, params.length);
for (int i = 0; i < length; i++) {
Class<?> aType = getDexCacheType(dex, types[i]);
@@ -169,7 +201,7 @@ public final class ArtMethod {
}
Annotation[][] getParameterAnnotations() {
- return AnnotationAccess.getParameterAnnotations(declaringClass, methodDexIndex);
+ return AnnotationAccess.getParameterAnnotations(declaringClass, dexMethodIndex);
}
/**
@@ -211,7 +243,7 @@ public final class ArtMethod {
// Proxy method's declaring class' dex cache refers to that of Proxy. The local cache in
// Method refers to the original interface's dex cache and is ensured to be resolved by
// proxy generation.
- return dexCacheResolvedMethods[methodDexIndex];
+ return dexCacheResolvedMethods[dexMethodIndex];
}
return this;
}
diff --git a/libart/src/main/java/java/lang/reflect/Constructor.java b/libart/src/main/java/java/lang/reflect/Constructor.java
index b3df2f0..2eb12b0 100644
--- a/libart/src/main/java/java/lang/reflect/Constructor.java
+++ b/libart/src/main/java/java/lang/reflect/Constructor.java
@@ -111,7 +111,7 @@ public final class Constructor<T> extends AbstractMethod implements GenericDecla
* parameter types of this constructor. If the constructor was declared with
* no parameters, an empty array will be returned.
*/
- public Class<?>[] getParameterTypes() {
+ @Override public Class<?>[] getParameterTypes() {
return super.getParameterTypes();
}
@@ -283,8 +283,14 @@ public final class Constructor<T> extends AbstractMethod implements GenericDecla
*
* @see AccessibleObject
*/
- public native T newInstance(Object... args) throws InstantiationException,
- IllegalAccessException, IllegalArgumentException, InvocationTargetException;
+ public T newInstance(Object... args) throws InstantiationException,
+ IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ return newInstance(args, isAccessible());
+ }
+
+ /** @hide */
+ public native T newInstance(Object[] args, boolean accessible) throws InstantiationException,
+ IllegalAccessException, IllegalArgumentException, InvocationTargetException;
/**
* Returns a string containing a concise, human-readable description of this
diff --git a/libart/src/main/java/java/lang/reflect/Field.java b/libart/src/main/java/java/lang/reflect/Field.java
index 4e982c7..11e8a6e 100644
--- a/libart/src/main/java/java/lang/reflect/Field.java
+++ b/libart/src/main/java/java/lang/reflect/Field.java
@@ -275,7 +275,12 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native Object get(Object object) throws IllegalAccessException, IllegalArgumentException;
+ public Object get(Object object) throws IllegalAccessException, IllegalArgumentException {
+ return get(object, isAccessible());
+ }
+
+ private native Object get(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns the value of the field in the specified object as a {@code
@@ -300,8 +305,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native boolean getBoolean(Object object) throws IllegalAccessException,
- IllegalArgumentException;
+ public boolean getBoolean(Object object) throws IllegalAccessException,
+ IllegalArgumentException {
+ return getBoolean(object, isAccessible());
+ }
+
+ private native boolean getBoolean(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns the value of the field in the specified object as a {@code byte}.
@@ -326,8 +336,12 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native byte getByte(Object object) throws IllegalAccessException,
- IllegalArgumentException;
+ public byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException {
+ return getByte(object, isAccessible());
+ }
+
+ private native byte getByte(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns the value of the field in the specified object as a {@code char}.
@@ -352,8 +366,12 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native char getChar(Object object) throws IllegalAccessException,
- IllegalArgumentException;
+ public char getChar(Object object) throws IllegalAccessException, IllegalArgumentException {
+ return getChar(object, isAccessible());
+ }
+
+ private native char getChar(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns the value of the field in the specified object as a {@code
@@ -378,8 +396,12 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native double getDouble(Object object) throws IllegalAccessException,
- IllegalArgumentException;
+ public double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException {
+ return getDouble(object, isAccessible());
+ }
+
+ private native double getDouble(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns the value of the field in the specified object as a {@code float}
@@ -404,8 +426,12 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native float getFloat(Object object) throws IllegalAccessException,
- IllegalArgumentException;
+ public float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException {
+ return getFloat(object, isAccessible());
+ }
+
+ private native float getFloat(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns the value of the field in the specified object as an {@code int}.
@@ -430,8 +456,12 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native int getInt(Object object) throws IllegalAccessException,
- IllegalArgumentException;
+ public int getInt(Object object) throws IllegalAccessException, IllegalArgumentException {
+ return getInt(object, isAccessible());
+ }
+
+ private native int getInt(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns the value of the field in the specified object as a {@code long}.
@@ -456,8 +486,12 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native long getLong(Object object) throws IllegalAccessException,
- IllegalArgumentException;
+ public long getLong(Object object) throws IllegalAccessException, IllegalArgumentException {
+ return getLong(object, isAccessible());
+ }
+
+ private native long getLong(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns the value of the field in the specified object as a {@code short}
@@ -482,8 +516,12 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native short getShort(Object object) throws IllegalAccessException,
- IllegalArgumentException;
+ public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException {
+ return getShort(object, isAccessible());
+ }
+
+ private native short getShort(Object object, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Sets the value of the field in the specified object to the value. This
@@ -514,8 +552,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void set(Object object, Object value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void set(Object object, Object value) throws IllegalAccessException,
+ IllegalArgumentException {
+ set(object, value, isAccessible());
+ }
+
+ private native void set(Object object, Object value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Sets the value of the field in the specified object to the {@code
@@ -545,8 +588,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void setBoolean(Object object, boolean value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void setBoolean(Object object, boolean value) throws IllegalAccessException,
+ IllegalArgumentException {
+ setBoolean(object, value, isAccessible());
+ }
+
+ private native void setBoolean(Object object, boolean value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Sets the value of the field in the specified object to the {@code byte}
@@ -575,8 +623,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void setByte(Object object, byte value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void setByte(Object object, byte value) throws IllegalAccessException,
+ IllegalArgumentException {
+ setByte(object, value, isAccessible());
+ }
+
+ private native void setByte(Object object, byte value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Sets the value of the field in the specified object to the {@code char}
@@ -605,8 +658,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void setChar(Object object, char value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void setChar(Object object, char value) throws IllegalAccessException,
+ IllegalArgumentException {
+ setChar(object, value, isAccessible());
+ }
+
+ private native void setChar(Object object, char value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Sets the value of the field in the specified object to the {@code double}
@@ -635,8 +693,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void setDouble(Object object, double value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void setDouble(Object object, double value) throws IllegalAccessException,
+ IllegalArgumentException {
+ setDouble(object, value, isAccessible());
+ }
+
+ private native void setDouble(Object object, double value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Sets the value of the field in the specified object to the {@code float}
@@ -665,8 +728,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void setFloat(Object object, float value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void setFloat(Object object, float value) throws IllegalAccessException,
+ IllegalArgumentException {
+ setFloat(object, value, isAccessible());
+ }
+
+ private native void setFloat(Object object, float value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Set the value of the field in the specified object to the {@code int}
@@ -695,8 +763,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void setInt(Object object, int value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void setInt(Object object, int value) throws IllegalAccessException,
+ IllegalArgumentException {
+ setInt(object, value, isAccessible());
+ }
+
+ private native void setInt(Object object, int value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Sets the value of the field in the specified object to the {@code long}
@@ -725,8 +798,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void setLong(Object object, long value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void setLong(Object object, long value) throws IllegalAccessException,
+ IllegalArgumentException {
+ setLong(object, value, isAccessible());
+ }
+
+ private native void setLong(Object object, long value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Sets the value of the field in the specified object to the {@code short}
@@ -755,8 +833,13 @@ public final class Field extends AccessibleObject implements Member {
* @throws IllegalAccessException
* if this field is not accessible
*/
- public native void setShort(Object object, short value) throws IllegalAccessException,
- IllegalArgumentException;
+ public void setShort(Object object, short value) throws IllegalAccessException,
+ IllegalArgumentException {
+ setShort(object, value, isAccessible());
+ }
+
+ private native void setShort(Object object, short value, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException;
/**
* Returns a string containing a concise, human-readable description of this
diff --git a/libart/src/main/java/java/lang/reflect/Method.java b/libart/src/main/java/java/lang/reflect/Method.java
index 3089932..058fb96 100644
--- a/libart/src/main/java/java/lang/reflect/Method.java
+++ b/libart/src/main/java/java/lang/reflect/Method.java
@@ -367,8 +367,13 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @throws InvocationTargetException
* if an exception was thrown by the invoked method
*/
- public native Object invoke(Object receiver, Object... args)
- throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
+ public Object invoke(Object receiver, Object... args)
+ throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ return invoke(receiver, args, isAccessible());
+ }
+
+ private native Object invoke(Object receiver, Object[] args, boolean accessible)
+ throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
/**
* Returns a string containing a concise, human-readable description of this
diff --git a/libart/src/main/java/java/lang/reflect/Proxy.java b/libart/src/main/java/java/lang/reflect/Proxy.java
index 51b3ad5..31f9cd9 100644
--- a/libart/src/main/java/java/lang/reflect/Proxy.java
+++ b/libart/src/main/java/java/lang/reflect/Proxy.java
@@ -25,7 +25,6 @@ import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
import libcore.util.EmptyArray;
/**
@@ -40,7 +39,7 @@ public class Proxy implements Serializable {
private static final long serialVersionUID = -2222568056686623797L;
- private static int NextClassNameIndex = 0;
+ private static int nextClassNameIndex = 0;
/**
* Orders methods by their name, parameters, return type and inheritance relationship.
@@ -117,22 +116,33 @@ public class Proxy implements Serializable {
throw new NullPointerException("interfaces == null");
}
- Set<Class<?>> interfacesSet = new CopyOnWriteArraySet<Class<?>>(Arrays.asList(interfaces));
+ // Make a copy of the list early on because we're using the list as a
+ // cache key and we don't want it changing under us.
+ final List<Class<?>> interfaceList = new ArrayList<Class<?>>(interfaces.length);
+ Collections.addAll(interfaceList, interfaces);
+
+ // We use a HashSet *only* for detecting duplicates and null entries. We
+ // can't use it as our cache key because we need to preserve the order in
+ // which these interfaces were specified. (Different orders should define
+ // different proxies.)
+ final Set<Class<?>> interfaceSet = new HashSet<Class<?>>(interfaceList);
+ if (interfaceSet.contains(null)) {
+ throw new NullPointerException("interface list contains null: " + interfaceList);
+ }
- Class<?> proxy = loader.proxyCache.get(interfacesSet);
- if (proxy != null) {
- return proxy;
+ if (interfaceSet.size() != interfaces.length) {
+ throw new IllegalArgumentException("duplicate interface in list: " + interfaceList);
}
- if (interfacesSet.size() != interfaces.length) {
- throw new IllegalArgumentException(
- "interfaces has duplicates: " + Arrays.toString(interfaces));
+ synchronized (loader.proxyCache) {
+ Class<?> proxy = loader.proxyCache.get(interfaceList);
+ if (proxy != null) {
+ return proxy;
+ }
}
+
String commonPackageName = null;
for (Class<?> c : interfaces) {
- if (c == null) {
- throw new NullPointerException("interfaces contained a null element");
- }
if (!c.isInterface()) {
throw new IllegalArgumentException(c + " is not an interface");
}
@@ -152,11 +162,6 @@ public class Proxy implements Serializable {
}
}
- String baseName = commonPackageName != null && !commonPackageName.isEmpty()
- ? commonPackageName + ".$Proxy"
- : "$Proxy";
- String name = baseName + NextClassNameIndex++;
-
List<Method> methods = getMethods(interfaces);
Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
validateReturnTypes(methods);
@@ -167,8 +172,21 @@ public class Proxy implements Serializable {
methodsArray[i] = methods.get(i).getArtMethod();
}
Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
- Class<?> result = generateProxy(name, interfaces, loader, methodsArray, exceptionsArray);
- loader.proxyCache.put(interfacesSet, result);
+
+ String baseName = commonPackageName != null && !commonPackageName.isEmpty()
+ ? commonPackageName + ".$Proxy"
+ : "$Proxy";
+
+ Class<?> result;
+ synchronized (loader.proxyCache) {
+ result = loader.proxyCache.get(interfaceSet);
+ if (result == null) {
+ String name = baseName + nextClassNameIndex++;
+ result = generateProxy(name, interfaces, loader, methodsArray, exceptionsArray);
+ loader.proxyCache.put(interfaceList, result);
+ }
+ }
+
return result;
}
diff --git a/libart/src/main/java/sun/misc/Unsafe.java b/libart/src/main/java/sun/misc/Unsafe.java
index 0a4d8b2..6f5f5ee 100644
--- a/libart/src/main/java/sun/misc/Unsafe.java
+++ b/libart/src/main/java/sun/misc/Unsafe.java
@@ -81,12 +81,7 @@ public final class Unsafe {
if (component == null) {
throw new IllegalArgumentException("Valid for array classes only: " + clazz);
}
- // TODO: make the following not specific to the object model.
- int offset = 12;
- if (component == long.class || component == double.class) {
- offset += 4; // 4 bytes of padding.
- }
- return offset;
+ return getArrayBaseOffsetForComponentType(component);
}
/**
@@ -100,21 +95,12 @@ public final class Unsafe {
if (component == null) {
throw new IllegalArgumentException("Valid for array classes only: " + clazz);
}
- // TODO: make the following not specific to the object model.
- if (!component.isPrimitive()) {
- return 4;
- } else if (component == long.class || component == double.class) {
- return 8;
- } else if (component == int.class || component == float.class) {
- return 4;
- } else if (component == char.class || component == short.class) {
- return 2;
- } else {
- // component == byte.class || component == boolean.class.
- return 1;
- }
+ return getArrayIndexScaleForComponentType(component);
}
+ private static native int getArrayBaseOffsetForComponentType(Class component_class);
+ private static native int getArrayIndexScaleForComponentType(Class component_class);
+
/**
* Performs a compare-and-set operation on an <code>int</code>
* field within the given object.
diff --git a/libdvm/src/main/java/dalvik/system/VMRuntime.java b/libdvm/src/main/java/dalvik/system/VMRuntime.java
deleted file mode 100644
index e1b4a00..0000000
--- a/libdvm/src/main/java/dalvik/system/VMRuntime.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.system;
-
-/**
- * Provides an interface to VM-global, Dalvik-specific features.
- * An application cannot create its own Runtime instance, and must obtain
- * one from the getRuntime method.
- *
- * @hide
- */
-public final class VMRuntime {
-
- /**
- * Holds the VMRuntime singleton.
- */
- private static final VMRuntime THE_ONE = new VMRuntime();
-
- /**
- * Prevents this class from being instantiated.
- */
- private VMRuntime() {
- }
-
- /**
- * Returns the object that represents the VM instance's Dalvik-specific
- * runtime environment.
- *
- * @return the runtime object
- */
- public static VMRuntime getRuntime() {
- return THE_ONE;
- }
-
- /**
- * Returns a copy of the VM's command-line property settings.
- * These are in the form "name=value" rather than "-Dname=value".
- */
- public native String[] properties();
-
- /**
- * Returns the VM's boot class path.
- */
- public native String bootClassPath();
-
- /**
- * Returns the VM's class path.
- */
- public native String classPath();
-
- /**
- * Returns the VM's version.
- */
- public native String vmVersion();
-
- /**
- * Returns the name of the shared library providing the VM implementation.
- */
- public native String vmLibrary();
-
- /**
- * Gets the current ideal heap utilization, represented as a number
- * between zero and one. After a GC happens, the Dalvik heap may
- * be resized so that (size of live objects) / (size of heap) is
- * equal to this number.
- *
- * @return the current ideal heap utilization
- */
- public native float getTargetHeapUtilization();
-
- /**
- * Sets the current ideal heap utilization, represented as a number
- * between zero and one. After a GC happens, the Dalvik heap may
- * be resized so that (size of live objects) / (size of heap) is
- * equal to this number.
- *
- * <p>This is only a hint to the garbage collector and may be ignored.
- *
- * @param newTarget the new suggested ideal heap utilization.
- * This value may be adjusted internally.
- * @return the previous ideal heap utilization
- * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
- */
- public float setTargetHeapUtilization(float newTarget) {
- if (newTarget <= 0.0f || newTarget >= 1.0f) {
- throw new IllegalArgumentException(newTarget +
- " out of range (0,1)");
- }
- /* Synchronize to make sure that only one thread gets
- * a given "old" value if both update at the same time.
- * Allows for reliable save-and-restore semantics.
- */
- synchronized (this) {
- float oldTarget = getTargetHeapUtilization();
- nativeSetTargetHeapUtilization(newTarget);
- return oldTarget;
- }
- }
-
- /**
- * Sets the target SDK version. Should only be called before the
- * app starts to run, because it may change the VM's behavior in
- * dangerous ways. Use 0 to mean "current" (since callers won't
- * necessarily know the actual current SDK version, and the
- * allocated version numbers start at 1).
- */
- public native void setTargetSdkVersion(int targetSdkVersion);
-
- /**
- * This method exists for binary compatibility. It was part of a
- * heap sizing API which was removed in Android 3.0 (Honeycomb).
- */
- @Deprecated
- public long getMinimumHeapSize() {
- return 0;
- }
-
- /**
- * This method exists for binary compatibility. It was part of a
- * heap sizing API which was removed in Android 3.0 (Honeycomb).
- */
- @Deprecated
- public long setMinimumHeapSize(long size) {
- return 0;
- }
-
- /**
- * This method exists for binary compatibility. It used to
- * perform a garbage collection that cleared SoftReferences.
- */
- @Deprecated
- public void gcSoftReferences() {}
-
- /**
- * This method exists for binary compatibility. It is equivalent
- * to {@link System#runFinalization}.
- */
- @Deprecated
- public void runFinalizationSync() {
- System.runFinalization();
- }
-
- /**
- * Implements setTargetHeapUtilization().
- *
- * @param newTarget the new suggested ideal heap utilization.
- * This value may be adjusted internally.
- */
- private native void nativeSetTargetHeapUtilization(float newTarget);
-
- /**
- * This method exists for binary compatibility. It was part of
- * the external allocation API which was removed in Android 3.0 (Honeycomb).
- */
- @Deprecated
- public boolean trackExternalAllocation(long size) {
- return true;
- }
-
- /**
- * This method exists for binary compatibility. It was part of
- * the external allocation API which was removed in Android 3.0 (Honeycomb).
- */
- @Deprecated
- public void trackExternalFree(long size) {}
-
- /**
- * This method exists for binary compatibility. It was part of
- * the external allocation API which was removed in Android 3.0 (Honeycomb).
- */
- @Deprecated
- public long getExternalBytesAllocated() {
- return 0;
- }
-
- /**
- * Tells the VM to enable the JIT compiler. If the VM does not have a JIT
- * implementation, calling this method should have no effect.
- */
- public native void startJitCompilation();
-
- /**
- * Tells the VM to disable the JIT compiler. If the VM does not have a JIT
- * implementation, calling this method should have no effect.
- */
- public native void disableJitCompilation();
-
- /**
- * Returns an array allocated in an area of the Java heap where it will never be moved.
- * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
- * and Bitmaps.
- */
- public native Object newNonMovableArray(Class<?> componentType, int length);
-
- /**
- * Returns the address of array[0]. This differs from using JNI in that JNI might lie and
- * give you the address of a copy of the array when in forcecopy mode.
- */
- public native long addressOf(Object array);
-
- /**
- * Removes any growth limits, allowing the application to allocate
- * up to the maximum heap size.
- */
- public native void clearGrowthLimit();
-
- /**
- * Returns true if either a Java debugger or native debugger is active.
- */
- public native boolean isDebuggerActive();
-
- /**
- * Registers a native allocation so that the heap knows about it and performs GC as required.
- * If the number of native allocated bytes exceeds the native allocation watermark, the
- * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
- * watermark, it is determined that the application is registering native allocations at an
- * unusually high rate and a GC is performed inside of the function to prevent memory usage
- * from excessively increasing.
- */
- public native void registerNativeAllocation(int bytes);
-
- /**
- * Registers a native free by reducing the number of native bytes accounted for.
- */
- public native void registerNativeFree(int bytes);
-
- /**
- * Fill in dex caches with classes, fields, and methods that are already loaded.
- */
- public native void preloadDexCaches();
-}
diff --git a/libdvm/src/main/java/dalvik/system/VMStack.java b/libdvm/src/main/java/dalvik/system/VMStack.java
deleted file mode 100644
index bae1829..0000000
--- a/libdvm/src/main/java/dalvik/system/VMStack.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.system;
-
-/**
- * Provides a limited interface to the Dalvik VM stack. This class is mostly
- * used for implementing security checks.
- *
- * @hide
- */
-public final class VMStack {
- /**
- * Returns the defining class loader of the caller's caller.
- *
- * @return the requested class loader, or {@code null} if this is the
- * bootstrap class loader.
- */
- native public static ClassLoader getCallingClassLoader();
-
- /**
- * Returns the class of the caller's caller's caller.
- *
- * @return the requested class, or {@code null}.
- */
- native public static Class<?> getStackClass2();
-
- /**
- * Creates an array of classes from the methods at the top of the stack.
- * We continue until we reach the bottom of the stack or exceed the
- * specified maximum depth.
- * <p>
- * The topmost stack frame (this method) and the one above that (the
- * caller) are excluded from the array. Frames with java.lang.reflect
- * classes are skipped over.
- * <p>
- * The classes in the array are the defining classes of the methods.
- * <p>
- * This is similar to Harmony's VMStack.getClasses, except that this
- * implementation doesn't have a concept of "privileged" frames.
- *
- * @param maxDepth
- * maximum number of classes to return, or -1 for all
- * @return an array with classes for the most-recent methods on the stack
- */
- native public static Class<?>[] getClasses(int maxDepth);
-
- /**
- * Returns the first ClassLoader on the call stack that isn't either of
- * the passed-in ClassLoaders.
- */
- public static ClassLoader getClosestUserClassLoader(ClassLoader bootstrap,
- ClassLoader system) {
- Class<?>[] stackClasses = VMStack.getClasses(-1);
- for (Class<?> stackClass : stackClasses) {
- ClassLoader loader = stackClass.getClassLoader();
- if (loader != null && loader != bootstrap && loader != system) {
- return loader;
- }
- }
- return null;
- }
-
- /**
- * Retrieves the stack trace from the specified thread.
- *
- * @param t
- * thread of interest
- * @return an array of stack trace elements, or null if the thread
- * doesn't have a stack trace (e.g. because it exited)
- */
- native public static StackTraceElement[] getThreadStackTrace(Thread t);
-
- /**
- * Retrieves a partial stack trace from the specified thread into
- * the provided array.
- *
- * @param t
- * thread of interest
- * @param stackTraceElements
- * preallocated array for use when only the top of stack is
- * desired. Unused elements will be filled with null values.
- * @return the number of elements filled
- */
- native public static int fillStackTraceElements(Thread t,
- StackTraceElement[] stackTraceElements);
-}
diff --git a/libdvm/src/main/java/java/lang/Class.java b/libdvm/src/main/java/java/lang/Class.java
deleted file mode 100644
index 4b36f3c..0000000
--- a/libdvm/src/main/java/java/lang/Class.java
+++ /dev/null
@@ -1,1348 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2006-2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import com.android.dex.Dex;
-import dalvik.system.VMStack;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Inherited;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericDeclaration;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.net.URL;
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import org.apache.harmony.kernel.vm.StringUtils;
-import libcore.reflect.AnnotationAccess;
-import libcore.reflect.GenericSignatureParser;
-import libcore.reflect.InternalNames;
-import libcore.reflect.Types;
-import libcore.util.BasicLruCache;
-import libcore.util.CollectionUtils;
-import libcore.util.EmptyArray;
-
-/**
- * The in-memory representation of a Java class. This representation serves as
- * the starting point for querying class-related information, a process usually
- * called "reflection". There are basically three types of {@code Class}
- * instances: those representing real classes and interfaces, those representing
- * primitive types, and those representing array classes.
- *
- * <h4>Class instances representing object types (classes or interfaces)</h4>
- * <p>
- * These represent an ordinary class or interface as found in the class
- * hierarchy. The name associated with these {@code Class} instances is simply
- * the fully qualified class name of the class or interface that it represents.
- * In addition to this human-readable name, each class is also associated by a
- * so-called <em>signature</em>, which is the letter "L", followed by the
- * class name and a semicolon (";"). The signature is what the runtime system
- * uses internally for identifying the class (for example in a DEX file).
- * </p>
- * <h4>Classes representing primitive types</h4>
- * <p>
- * These represent the standard Java primitive types and hence share their
- * names (for example "int" for the {@code int} primitive type). Although it is
- * not possible to create new instances based on these {@code Class} instances,
- * they are still useful for providing reflection information, and as the
- * component type of array classes. There is one {@code Class} instance for each
- * primitive type, and their signatures are:
- * </p>
- * <ul>
- * <li>{@code B} representing the {@code byte} primitive type</li>
- * <li>{@code S} representing the {@code short} primitive type</li>
- * <li>{@code I} representing the {@code int} primitive type</li>
- * <li>{@code J} representing the {@code long} primitive type</li>
- * <li>{@code F} representing the {@code float} primitive type</li>
- * <li>{@code D} representing the {@code double} primitive type</li>
- * <li>{@code C} representing the {@code char} primitive type</li>
- * <li>{@code Z} representing the {@code boolean} primitive type</li>
- * <li>{@code V} representing void function return values</li>
- * </ul>
- * <p>
- * <h4>Classes representing array classes</h4>
- * <p>
- * These represent the classes of Java arrays. There is one such {@code Class}
- * instance per combination of array leaf component type and arity (number of
- * dimensions). In this case, the name associated with the {@code Class}
- * consists of one or more left square brackets (one per dimension in the array)
- * followed by the signature of the class representing the leaf component type,
- * which can be either an object type or a primitive type. The signature of a
- * {@code Class} representing an array type is the same as its name. Examples
- * of array class signatures are:
- * </p>
- * <ul>
- * <li>{@code [I} representing the {@code int[]} type</li>
- * <li>{@code [Ljava/lang/String;} representing the {@code String[]} type</li>
- * <li>{@code [[[C} representing the {@code char[][][]} type (three dimensions!)</li>
- * </ul>
- */
-public final class Class<T> implements Serializable, AnnotatedElement, GenericDeclaration, Type {
-
- private static final long serialVersionUID = 3206093459760846163L;
-
- /**
- * Class def index from dex file. An index of -1 indicates that there is no class definition,
- * for example for an array type.
- */
- private transient int dexClassDefIndex;
-
- /** The type index of this class within the dex file that defines it. */
- private transient int dexTypeIndex;
-
- /**
- * Have we computed the type and class def indices? Volatile to avoid double check locking bugs.
- */
- private transient volatile boolean dexIndicesInitialized;
-
- /**
- * Lazily computed name of this class; always prefer calling getName().
- */
- private transient String name;
-
- private Class() {
- // Prevent this class to be instantiated, instance
- // should be created by JVM only
- }
-
- /**
- * Returns the dex file from which this class was loaded.
- * @hide
- */
- public native Dex getDex();
-
- /** Lazily compute indices in to Dex */
- private synchronized void computeDexIndices() {
- if (!dexIndicesInitialized) {
- Dex dex = getDex();
- dexTypeIndex = dex.findTypeIndex(InternalNames.getInternalName(this));
- if (dexTypeIndex < 0) {
- dexTypeIndex = -1;
- dexClassDefIndex = -1;
- } else {
- dexClassDefIndex = dex.findClassDefIndexFromTypeIndex(dexTypeIndex);
- }
- dexIndicesInitialized = true;
- }
- }
-
- /**
- * The class def of this class in its own Dex, or -1 if there is no class def.
- *
- * @hide
- */
- public int getDexClassDefIndex() {
- if (!dexIndicesInitialized) {
- computeDexIndices();
- }
- return dexClassDefIndex;
- }
-
- /**
- * The type index of this class in its own Dex, or -1 if it is unknown. If a class is referenced
- * by multiple Dex files, it will have a different type index in each. Dex files support 65534
- * type indices, with 65535 representing no index.
- *
- * @hide
- */
- public int getDexTypeIndex() {
- if (!dexIndicesInitialized) {
- computeDexIndices();
- }
- return dexTypeIndex;
- }
-
- /**
- * Returns a {@code Class} object which represents the class with the
- * given name. The name should be the name of a non-primitive class, as described in
- * the {@link Class class definition}.
- * Primitive types can not be found using this method; use {@code int.class} or {@code Integer.TYPE} instead.
- *
- * <p>If the class has not yet been loaded, it is loaded and initialized
- * first. This is done through either the class loader of the calling class
- * or one of its parent class loaders. It is possible that a static initializer is run as
- * a result of this call.
- *
- * @throws ClassNotFoundException
- * if the requested class can not be found.
- * @throws LinkageError
- * if an error occurs during linkage
- * @throws ExceptionInInitializerError
- * if an exception occurs during static initialization of a
- * class.
- */
- public static Class<?> forName(String className) throws ClassNotFoundException {
- return forName(className, true, VMStack.getCallingClassLoader());
- }
-
- /**
- * Returns a {@code Class} object which represents the class with the
- * given name. The name should be the name of a non-primitive class, as described in
- * the {@link Class class definition}.
- * Primitive types can not be found using this method; use {@code int.class} or {@code Integer.TYPE} instead.
- *
- * <p>If the class has not yet been loaded, it is loaded first, using the given class loader.
- * If the class has not yet been initialized and {@code shouldInitialize} is true,
- * the class will be initialized.
- *
- * @throws ClassNotFoundException
- * if the requested class can not be found.
- * @throws LinkageError
- * if an error occurs during linkage
- * @throws ExceptionInInitializerError
- * if an exception occurs during static initialization of a
- * class.
- */
- public static Class<?> forName(String className, boolean shouldInitialize,
- ClassLoader classLoader) throws ClassNotFoundException {
-
- if (classLoader == null) {
- classLoader = ClassLoader.getSystemClassLoader();
- }
- // Catch an Exception thrown by the underlying native code. It wraps
- // up everything inside a ClassNotFoundException, even if e.g. an
- // Error occurred during initialization. This as a workaround for
- // an ExceptionInInitializerError that's also wrapped. It is actually
- // expected to be thrown. Maybe the same goes for other errors.
- // Not wrapping up all the errors will break android though.
- Class<?> result;
- try {
- result = classForName(className, shouldInitialize,
- classLoader);
- } catch (ClassNotFoundException e) {
- Throwable cause = e.getCause();
- if (cause instanceof ExceptionInInitializerError) {
- throw (ExceptionInInitializerError) cause;
- }
- throw e;
- }
- return result;
- }
-
- private static native Class<?> classForName(String className, boolean shouldInitialize,
- ClassLoader classLoader) throws ClassNotFoundException;
-
- /**
- * Returns an array containing {@code Class} objects for all public classes
- * and interfaces that are members of this class. This includes public
- * members inherited from super classes and interfaces. If there are no such
- * class members or if this object represents a primitive type then an array
- * of length 0 is returned.
- */
- public Class<?>[] getClasses() {
- Class<?>[] result = getDeclaredClasses(this, true);
- // Traverse all superclasses.
- for (Class<?> c = this.getSuperclass(); c != null; c = c.getSuperclass()) {
- Class<?>[] temp = getDeclaredClasses(c, true);
- if (temp.length != 0) {
- result = arraycopy(new Class[result.length + temp.length], result, temp);
- }
- }
- return result;
- }
-
- @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
- if (annotationType == null) {
- throw new NullPointerException("annotationType == null");
- }
-
- A annotation = getDeclaredAnnotation(annotationType);
- if (annotation != null) {
- return annotation;
- }
-
- if (annotationType.isAnnotationPresent(Inherited.class)) {
- for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
- annotation = sup.getDeclaredAnnotation(annotationType);
- if (annotation != null) {
- return annotation;
- }
- }
- }
-
- return null;
- }
-
- /**
- * Returns an array containing all the annotations of this class. If there are no annotations
- * then an empty array is returned.
- *
- * @see #getDeclaredAnnotations()
- */
- public Annotation[] getAnnotations() {
- /*
- * We need to get the annotations declared on this class, plus the
- * annotations from superclasses that have the "@Inherited" annotation
- * set. We create a temporary map to use while we accumulate the
- * annotations and convert it to an array at the end.
- *
- * It's possible to have duplicates when annotations are inherited.
- * We use a Map to filter those out.
- *
- * HashMap might be overkill here.
- */
- HashMap<Class, Annotation> map = new HashMap<Class, Annotation>();
- Annotation[] declaredAnnotations = getDeclaredAnnotations();
-
- for (int i = declaredAnnotations.length-1; i >= 0; --i) {
- map.put(declaredAnnotations[i].annotationType(), declaredAnnotations[i]);
- }
- for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
- declaredAnnotations = sup.getDeclaredAnnotations();
- for (int i = declaredAnnotations.length-1; i >= 0; --i) {
- Class<?> clazz = declaredAnnotations[i].annotationType();
- if (!map.containsKey(clazz) && clazz.isAnnotationPresent(Inherited.class)) {
- map.put(clazz, declaredAnnotations[i]);
- }
- }
- }
-
- /* convert annotation values from HashMap to array */
- Collection<Annotation> coll = map.values();
- return coll.toArray(new Annotation[coll.size()]);
- }
-
- /**
- * Returns the canonical name of this class. If this class does not have a
- * canonical name as defined in the Java Language Specification, then the
- * method returns {@code null}.
- */
- public String getCanonicalName() {
- if (isLocalClass() || isAnonymousClass())
- return null;
-
- if (isArray()) {
- /*
- * The canonical name of an array type depends on the (existence of)
- * the component type's canonical name.
- */
- String name = getComponentType().getCanonicalName();
- if (name != null) {
- return name + "[]";
- }
- } else if (isMemberClass()) {
- /*
- * The canonical name of an inner class depends on the (existence
- * of) the declaring class' canonical name.
- */
- String name = getDeclaringClass().getCanonicalName();
- if (name != null) {
- return name + "." + getSimpleName();
- }
- } else {
- /*
- * The canonical name of a top-level class or primitive type is
- * equal to the fully qualified name.
- */
- return getName();
- }
-
- /*
- * Other classes don't have a canonical name.
- */
- return null;
- }
-
- /**
- * Returns the class loader which was used to load the class represented by
- * this {@code Class}. Implementations are free to return {@code null} for
- * classes that were loaded by the bootstrap class loader. The Android
- * reference implementation, though, always returns a reference to an actual
- * class loader.
- */
- public ClassLoader getClassLoader() {
- if (this.isPrimitive()) {
- return null;
- }
-
- ClassLoader loader = getClassLoaderImpl();
- if (loader == null) {
- loader = BootClassLoader.getInstance();
- }
- return loader;
- }
-
- /**
- * This must be provided by the VM vendor, as it is used by other provided
- * class implementations in this package. Outside of this class, it is used
- * by SecurityManager.classLoaderDepth(),
- * currentClassLoader() and currentLoadedClass(). Return the ClassLoader for
- * this Class without doing any security checks. The bootstrap ClassLoader
- * is returned, unlike getClassLoader() which returns null in place of the
- * bootstrap ClassLoader.
- */
- ClassLoader getClassLoaderImpl() {
- ClassLoader loader = getClassLoader(this);
- return loader == null ? BootClassLoader.getInstance() : loader;
- }
-
- /*
- * Returns the defining class loader for the given class.
- */
- private static native ClassLoader getClassLoader(Class<?> c);
-
- /**
- * Returns a {@code Class} object which represents the component type if
- * this class represents an array type. Returns {@code null} if this class
- * does not represent an array type. The component type of an array type is
- * the type of the elements of the array.
- */
- public native Class<?> getComponentType();
-
- /**
- * Returns a {@code Constructor} object which represents the public
- * constructor matching the given parameter types.
- * {@code (Class[]) null} is equivalent to the empty array.
- *
- * <p>See {@link #getMethod} for details of the search order.
- * Use {@link #getDeclaredConstructor} if you don't want to search superclasses.
- *
- * @throws NoSuchMethodException
- * if the constructor can not be found.
- */
- @SuppressWarnings("unchecked")
- public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException {
- return (Constructor) getConstructorOrMethod("<init>", false, true, parameterTypes);
- }
-
- /**
- * Returns a constructor or method with the given name. Use "<init>" to return a constructor.
- */
- private Member getConstructorOrMethod(String name, boolean searchSuperTypes,
- boolean publicOnly, Class<?>[] parameterTypes) throws NoSuchMethodException {
- if (searchSuperTypes && !publicOnly) {
- throw new AssertionError(); // can't lookup non-public members recursively
- }
- if (name == null) {
- throw new NullPointerException("name == null");
- }
- if (parameterTypes == null) {
- parameterTypes = EmptyArray.CLASS;
- }
- for (Class<?> c : parameterTypes) {
- if (c == null) {
- throw new NoSuchMethodException("parameter type is null");
- }
- }
- Member result = searchSuperTypes
- ? getPublicConstructorOrMethodRecursive(name, parameterTypes)
- : Class.getDeclaredConstructorOrMethod(this, name, parameterTypes);
- if (result == null || publicOnly && (result.getModifiers() & Modifier.PUBLIC) == 0) {
- throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes));
- }
- return result;
- }
-
- private Member getPublicConstructorOrMethodRecursive(String name, Class<?>[] parameterTypes) {
- // search superclasses
- for (Class<?> c = this; c != null; c = c.getSuperclass()) {
- Member result = Class.getDeclaredConstructorOrMethod(c, name, parameterTypes);
- if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
- return result;
- }
- }
-
- // search implemented interfaces
- for (Class<?> c = this; c != null; c = c.getSuperclass()) {
- for (Class<?> ifc : c.getInterfaces()) {
- Member result = ifc.getPublicConstructorOrMethodRecursive(name, parameterTypes);
- if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
- return result;
- }
- }
- }
-
- return null;
- }
-
- /**
- * Returns an array containing {@code Constructor} objects for all public
- * constructors for this {@code Class}. If there
- * are no public constructors or if this {@code Class} represents an array
- * class, a primitive type or void then an empty array is returned.
- *
- * @see #getDeclaredConstructors()
- */
- public Constructor<?>[] getConstructors() {
- return getDeclaredConstructors(this, true);
- }
-
- /**
- * Returns the annotations that are directly defined on the class
- * represented by this {@code Class}. Annotations that are inherited are not
- * included in the result. If there are no annotations at all, an empty
- * array is returned.
- *
- * @see #getAnnotations()
- */
- public native Annotation[] getDeclaredAnnotations();
-
- /**
- * Returns the annotation if it exists.
- */
- native private <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass);
-
- /**
- * Returns true if the annotation exists.
- */
- native private boolean isDeclaredAnnotationPresent(Class<? extends Annotation> annotationClass);
-
- /**
- * Returns an array containing {@code Class} objects for all classes and
- * interfaces that are declared as members of the class which this {@code
- * Class} represents. If there are no classes or interfaces declared or if
- * this class represents an array class, a primitive type or void, then an
- * empty array is returned.
- */
- public Class<?>[] getDeclaredClasses() {
- return getDeclaredClasses(this, false);
- }
-
- /*
- * Returns the list of member classes of the given class.
- * If no members exist, an empty array is returned.
- */
- private static native Class<?>[] getDeclaredClasses(Class<?> c, boolean publicOnly);
-
- /**
- * Returns a {@code Constructor} object which represents the constructor
- * matching the given parameter types that is declared by the class
- * represented by this {@code Class}.
- * {@code (Class[]) null} is equivalent to the empty array.
- *
- * <p>Use {@link #getConstructor} if you want to search superclasses.
- *
- * @throws NoSuchMethodException
- * if the requested constructor can not be found.
- */
- @SuppressWarnings("unchecked")
- public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
- throws NoSuchMethodException {
- return (Constructor) getConstructorOrMethod("<init>", false, false, parameterTypes);
- }
-
- /**
- * Returns an array containing {@code Constructor} objects for all
- * constructors declared in the class represented by this {@code Class}. If
- * there are no constructors or if this {@code Class} represents an array
- * class, a primitive type, or void then an empty array is returned.
- *
- * @see #getConstructors()
- */
- public Constructor<?>[] getDeclaredConstructors() {
- return getDeclaredConstructors(this, false);
- }
-
- /*
- * Returns the list of constructors. If no constructors exist, an empty array is returned.
- */
- private static native <T> Constructor<T>[] getDeclaredConstructors(Class<T> c,
- boolean publicOnly);
-
- /**
- * Returns a {@code Field} object for the field with the given name
- * which is declared in the class represented by this {@code Class}.
- *
- * @throws NoSuchFieldException if the requested field can not be found.
- * @see #getField(String)
- */
- public Field getDeclaredField(String name) throws NoSuchFieldException {
- if (name == null) {
- throw new NullPointerException("name == null");
- }
- Field result = getDeclaredField(this, name);
- if (result == null) {
- throw new NoSuchFieldException(name);
- }
- return result;
- }
-
- /**
- * Returns an array containing {@code Field} objects for all fields declared
- * in the class represented by this {@code Class}. If there are no fields or
- * if this {@code Class} represents an array class, a primitive type or void
- * then an empty array is returned.
- *
- * @see #getFields()
- */
- public Field[] getDeclaredFields() {
- return getDeclaredFields(this, false);
- }
-
- /*
- * Returns the list of fields without performing any security checks
- * first. If no fields exist at all, an empty array is returned.
- */
- static native Field[] getDeclaredFields(Class<?> c, boolean publicOnly);
-
- /**
- * Returns the field if it is defined by {@code c}; null otherwise. This
- * may return a non-public member.
- */
- static native Field getDeclaredField(Class<?> c, String name);
-
- /**
- * Returns a {@code Method} object which represents the method matching the
- * given name and parameter types that is declared by the class
- * represented by this {@code Class}.
- * {@code (Class[]) null} is equivalent to the empty array.
- *
- * <p>See {@link #getMethod} if you want to search superclasses.
- *
- * @throws NoSuchMethodException
- * if the requested method can not be found.
- * @throws NullPointerException
- * if {@code name} is {@code null}.
- */
- public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
- throws NoSuchMethodException {
- Member member = getConstructorOrMethod(name, false, false, parameterTypes);
- if (member instanceof Constructor) {
- throw new NoSuchMethodException(name);
- }
- return (Method) member;
- }
-
- /**
- * Returns an array containing {@code Method} objects for all methods
- * declared in the class represented by this {@code Class}. If there are no
- * methods or if this {@code Class} represents an array class, a primitive
- * type or void then an empty array is returned.
- *
- * @see #getMethods()
- */
- public Method[] getDeclaredMethods() {
- return getDeclaredMethods(this, false);
- }
-
- /**
- * Returns the list of methods. If no methods exist, an empty array is returned.
- */
- static native Method[] getDeclaredMethods(Class<?> c, boolean publicOnly);
-
- /**
- * Returns the constructor or method if it is defined by {@code c}; null
- * otherwise. This may return a non-public member. Use "<init>" to get a constructor.
- */
- static native Member getDeclaredConstructorOrMethod(Class c, String name, Class[] args);
-
- /**
- * Returns the declaring {@code Class} of this {@code Class}. Returns
- * {@code null} if the class is not a member of another class or if this
- * {@code Class} represents an array class, a primitive type, or void.
- */
- public native Class<?> getDeclaringClass();
-
- /**
- * Returns the enclosing {@code Class} of this {@code Class}. If there is no
- * enclosing class the method returns {@code null}.
- */
- public native Class<?> getEnclosingClass();
-
- /**
- * Returns the enclosing {@code Constructor} of this {@code Class}, if it is an
- * anonymous or local/automatic class; otherwise {@code null}.
- */
- public native Constructor<?> getEnclosingConstructor();
-
- /**
- * Returns the enclosing {@code Method} of this {@code Class}, if it is an
- * anonymous or local/automatic class; otherwise {@code null}.
- */
- public native Method getEnclosingMethod();
-
- /**
- * Returns the {@code enum} constants associated with this {@code Class}.
- * Returns {@code null} if this {@code Class} does not represent an {@code
- * enum} type.
- */
- @SuppressWarnings("unchecked") // we only cast after confirming that this class is an enum
- public T[] getEnumConstants() {
- if (!isEnum()) {
- return null;
- }
- return (T[]) Enum.getSharedConstants((Class) this).clone();
- }
-
- /**
- * Returns a {@code Field} object which represents the public field with the
- * given name. This method first searches the class C represented by
- * this {@code Class}, then the interfaces implemented by C and finally the
- * superclasses of C.
- *
- * @throws NoSuchFieldException
- * if the field can not be found.
- * @see #getDeclaredField(String)
- */
- public Field getField(String name) throws NoSuchFieldException {
- if (name == null) {
- throw new NullPointerException("name == null");
- }
- Field result = getPublicFieldRecursive(name);
- if (result == null) {
- throw new NoSuchFieldException(name);
- }
- return result;
- }
-
- private Field getPublicFieldRecursive(String name) {
- // search superclasses
- for (Class<?> c = this; c != null; c = c.getSuperclass()) {
- Field result = Class.getDeclaredField(c, name);
- if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
- return result;
- }
- }
-
- // search implemented interfaces
- for (Class<?> c = this; c != null; c = c.getSuperclass()) {
- for (Class<?> ifc : c.getInterfaces()) {
- Field result = ifc.getPublicFieldRecursive(name);
- if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
- return result;
- }
- }
- }
-
- return null;
- }
-
- /**
- * Returns an array containing {@code Field} objects for all public fields
- * for the class C represented by this {@code Class}. Fields may be declared
- * in C, the interfaces it implements or in the superclasses of C. The
- * elements in the returned array are in no particular order.
- *
- * <p>If there are no public fields or if this class represents an array class,
- * a primitive type or {@code void} then an empty array is returned.
- *
- * @see #getDeclaredFields()
- */
- public Field[] getFields() {
- List<Field> fields = new ArrayList<Field>();
- getPublicFieldsRecursive(fields);
-
- /*
- * The result may include duplicates when this class implements an interface
- * through multiple paths. Remove those duplicates.
- */
- CollectionUtils.removeDuplicates(fields, Field.ORDER_BY_NAME_AND_DECLARING_CLASS);
- return fields.toArray(new Field[fields.size()]);
- }
-
- /**
- * Populates {@code result} with public fields defined by this class, its
- * superclasses, and all implemented interfaces.
- */
- private void getPublicFieldsRecursive(List<Field> result) {
- // search superclasses
- for (Class<?> c = this; c != null; c = c.getSuperclass()) {
- for (Field field : Class.getDeclaredFields(c, true)) {
- result.add(field);
- }
- }
-
- // search implemented interfaces
- for (Class<?> c = this; c != null; c = c.getSuperclass()) {
- for (Class<?> ifc : c.getInterfaces()) {
- ifc.getPublicFieldsRecursive(result);
- }
- }
- }
-
- /**
- * Returns the {@link Type}s of the interfaces that this {@code Class} directly
- * implements. If the {@code Class} represents a primitive type or {@code
- * void} then an empty array is returned.
- */
- public Type[] getGenericInterfaces() {
- Type[] result;
- synchronized (Caches.genericInterfaces) {
- result = Caches.genericInterfaces.get(this);
- if (result == null) {
- String annotationSignature = AnnotationAccess.getSignature(this);
- if (annotationSignature == null) {
- result = getInterfaces();
- } else {
- GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
- parser.parseForClass(this, annotationSignature);
- result = Types.getTypeArray(parser.interfaceTypes, false);
- }
- Caches.genericInterfaces.put(this, result);
- }
- }
- return (result.length == 0) ? result : result.clone();
- }
-
- /**
- * Returns the {@code Type} that represents the superclass of this {@code
- * class}.
- */
- public Type getGenericSuperclass() {
- Type genericSuperclass = getSuperclass();
- String annotationSignature = AnnotationAccess.getSignature(this);
- if (annotationSignature != null) {
- GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
- parser.parseForClass(this, annotationSignature);
- genericSuperclass = parser.superclassType;
- }
- return Types.getType(genericSuperclass);
- }
-
- /**
- * Returns an array of {@code Class} objects that match the interfaces
- * in the {@code implements} declaration of the class represented
- * by this {@code Class}. The order of the elements in the array is
- * identical to the order in the original class declaration. If the class
- * does not implement any interfaces, an empty array is returned.
- */
- public native Class<?>[] getInterfaces();
-
- /**
- * Returns a {@code Method} object which represents the public method with
- * the given name and parameter types.
- * {@code (Class[]) null} is equivalent to the empty array.
- *
- * <p>This method first searches the class C represented by this {@code Class},
- * then the superclasses of C,
- * and finally the interfaces implemented by C and its superclasses.
- *
- * <p>Use {@link #getDeclaredMethod} if you don't want to search superclasses.
- *
- * @throws NoSuchMethodException
- * if the method can not be found.
- */
- public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException {
- Member member = getConstructorOrMethod(name, true, true, parameterTypes);
- if (member instanceof Constructor) {
- throw new NoSuchMethodException(name);
- }
- return (Method) member;
- }
-
- /**
- * Returns an array containing {@code Method} objects for all public methods
- * for the class C represented by this {@code Class}. Methods may be
- * declared in C, the interfaces it implements or in the superclasses of C.
- * The elements in the returned array are in no particular order.
- *
- * <p>If there are no public methods or if this {@code Class} represents a
- * primitive type or {@code void} then an empty array is returned.
- *
- * @see #getDeclaredMethods()
- */
- public Method[] getMethods() {
- List<Method> methods = new ArrayList<Method>();
- getPublicMethodsRecursive(methods);
-
- /*
- * Remove methods defined by multiple types, preferring to keep methods
- * declared by derived types.
- */
- CollectionUtils.removeDuplicates(methods, Method.ORDER_BY_SIGNATURE);
- return methods.toArray(new Method[methods.size()]);
- }
-
- /**
- * Populates {@code result} with public methods defined by this class, its
- * superclasses, and all implemented interfaces, including overridden methods.
- */
- private void getPublicMethodsRecursive(List<Method> result) {
- // search superclasses
- for (Class<?> c = this; c != null; c = c.getSuperclass()) {
- for (Method method : Class.getDeclaredMethods(c, true)) {
- result.add(method);
- }
- }
-
- // search implemented interfaces
- for (Class<?> c = this; c != null; c = c.getSuperclass()) {
- for (Class<?> ifc : c.getInterfaces()) {
- ifc.getPublicMethodsRecursive(result);
- }
- }
- }
-
- /**
- * Returns an integer that represents the modifiers of the class represented
- * by this {@code Class}. The returned value is a combination of bits
- * defined by constants in the {@link Modifier} class.
- */
- public int getModifiers() {
- return getModifiers(this, false);
- }
-
- /*
- * Returns the modifiers for the given class.
- *
- * {@code ignoreInnerClassesAttrib} determines whether we look for and use the
- * flags from an "inner class" attribute
- */
- private static native int getModifiers(Class<?> clazz, boolean ignoreInnerClassesAttrib);
-
- /**
- * Returns the name of the class represented by this {@code Class}. For a
- * description of the format which is used, see the class definition of
- * {@link Class}.
- */
- public String getName() {
- String result = name;
- return (result == null) ? (name = getNameNative()) : result;
- }
-
- private native String getNameNative();
-
- /**
- * Returns the simple name of the class represented by this {@code Class} as
- * defined in the source code. If there is no name (that is, the class is
- * anonymous) then an empty string is returned. If the receiver is an array
- * then the name of the underlying type with square braces appended (for
- * example {@code "Integer[]"}) is returned.
- *
- * @return the simple name of the class represented by this {@code Class}.
- */
- public String getSimpleName() {
- if (isArray()) {
- return getComponentType().getSimpleName() + "[]";
- }
-
- String name = getName();
-
- if (isAnonymousClass()) {
- return "";
- }
-
- if (isMemberClass() || isLocalClass()) {
- return getInnerClassName();
- }
-
- int dot = name.lastIndexOf('.');
- if (dot != -1) {
- return name.substring(dot + 1);
- }
-
- return name;
- }
-
- /*
- * Returns the simple name of a member or local class, or null otherwise.
- */
- private native String getInnerClassName();
-
- /**
- * Returns null.
- */
- public ProtectionDomain getProtectionDomain() {
- return null;
- }
-
- /**
- * Returns the URL of the given resource, or null if the resource is not found.
- * The mapping between the resource name and the URL is managed by the class' class loader.
- *
- * @see ClassLoader
- */
- public URL getResource(String resourceName) {
- // Get absolute resource name, but without the leading slash
- if (resourceName.startsWith("/")) {
- resourceName = resourceName.substring(1);
- } else {
- String pkg = getName();
- int dot = pkg.lastIndexOf('.');
- if (dot != -1) {
- pkg = pkg.substring(0, dot).replace('.', '/');
- } else {
- pkg = "";
- }
-
- resourceName = pkg + "/" + resourceName;
- }
-
- // Delegate to proper class loader
- ClassLoader loader = getClassLoader();
- if (loader != null) {
- return loader.getResource(resourceName);
- } else {
- return ClassLoader.getSystemResource(resourceName);
- }
- }
-
- /**
- * Returns a read-only stream for the contents of the given resource, or null if the resource
- * is not found.
- * The mapping between the resource name and the stream is managed by the class' class loader.
- *
- * @see ClassLoader
- */
- public InputStream getResourceAsStream(String resourceName) {
- // Get absolute resource name, but without the leading slash
- if (resourceName.startsWith("/")) {
- resourceName = resourceName.substring(1);
- } else {
- String pkg = getName();
- int dot = pkg.lastIndexOf('.');
- if (dot != -1) {
- pkg = pkg.substring(0, dot).replace('.', '/');
- } else {
- pkg = "";
- }
-
- resourceName = pkg + "/" + resourceName;
- }
-
- // Delegate to proper class loader
- ClassLoader loader = getClassLoader();
- if (loader != null) {
- return loader.getResourceAsStream(resourceName);
- } else {
- return ClassLoader.getSystemResourceAsStream(resourceName);
- }
- }
-
- /**
- * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files.
- * All classes from any given dex file will have the same signers, but different dex
- * files may have different signers. This does not fit well with the original
- * {@code ClassLoader}-based model of {@code getSigners}.)
- */
- public Object[] getSigners() {
- // See http://code.google.com/p/android/issues/detail?id=1766.
- return null;
- }
-
- /**
- * Returns the {@code Class} object which represents the superclass of the
- * class represented by this {@code Class}. If this {@code Class} represents
- * the {@code Object} class, a primitive type, an interface or void then the
- * method returns {@code null}. If this {@code Class} represents an array
- * class then the {@code Object} class is returned.
- */
- public native Class<? super T> getSuperclass();
-
- /**
- * Returns an array containing {@code TypeVariable} objects for type
- * variables declared by the generic class represented by this {@code
- * Class}. Returns an empty array if the class is not generic.
- */
- @SuppressWarnings("unchecked")
- public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
- String annotationSignature = AnnotationAccess.getSignature(this);
- if (annotationSignature == null) {
- return EmptyArray.TYPE_VARIABLE;
- }
- GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
- parser.parseForClass(this, annotationSignature);
- return parser.formalTypeParameters;
- }
-
- /**
- * Tests whether this {@code Class} represents an annotation class.
- */
- public boolean isAnnotation() {
- final int ACC_ANNOTATION = 0x2000; // not public in reflect.Modifiers
- int mod = getModifiers(this, true);
- return (mod & ACC_ANNOTATION) != 0;
- }
-
- @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
- if (annotationType == null) {
- throw new NullPointerException("annotationType == null");
- }
-
- if (isDeclaredAnnotationPresent(annotationType)) {
- return true;
- }
-
- if (annotationType.isDeclaredAnnotationPresent(Inherited.class)) {
- for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
- if (sup.isDeclaredAnnotationPresent(annotationType)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Tests whether the class represented by this {@code Class} is
- * anonymous.
- */
- native public boolean isAnonymousClass();
-
- /**
- * Tests whether the class represented by this {@code Class} is an array class.
- */
- public boolean isArray() {
- return getComponentType() != null;
- }
-
- /**
- * Tests whether the given class type can be converted to the class
- * represented by this {@code Class}. Conversion may be done via an identity
- * conversion or a widening reference conversion (if either the receiver or
- * the argument represent primitive types, only the identity conversion
- * applies).
- *
- * @throws NullPointerException
- * if {@code c} is {@code null}.
- */
- public native boolean isAssignableFrom(Class<?> c);
-
- /**
- * Tests whether the class represented by this {@code Class} is an
- * {@code enum}.
- */
- public boolean isEnum() {
- if (getSuperclass() != Enum.class) {
- return false;
- }
- int mod = getModifiers(this, true);
- return (mod & 0x4000) != 0;
- }
-
- /**
- * Tests whether the given object can be cast to the class
- * represented by this {@code Class}. This is the runtime version of the
- * {@code instanceof} operator.
- *
- * @return {@code true} if {@code object} can be cast to the type
- * represented by this {@code Class}; {@code false} if {@code
- * object} is {@code null} or cannot be cast.
- */
- public native boolean isInstance(Object object);
-
- /**
- * Tests whether this {@code Class} represents an interface.
- */
- public native boolean isInterface();
-
- /**
- * Tests whether the class represented by this {@code Class} is defined
- * locally.
- */
- public boolean isLocalClass() {
- boolean enclosed = (getEnclosingMethod() != null ||
- getEnclosingConstructor() != null);
- return enclosed && !isAnonymousClass();
- }
-
- /**
- * Tests whether the class represented by this {@code Class} is a member
- * class.
- */
- public boolean isMemberClass() {
- return getDeclaringClass() != null;
- }
-
- /**
- * Tests whether this {@code Class} represents a primitive type.
- */
- public native boolean isPrimitive();
-
- /**
- * Tests whether this {@code Class} represents a synthetic type.
- */
- public boolean isSynthetic() {
- final int ACC_SYNTHETIC = 0x1000; // not public in reflect.Modifiers
- int mod = getModifiers(this, true);
- return (mod & ACC_SYNTHETIC) != 0;
- }
-
- /**
- * Returns a new instance of the class represented by this {@code Class},
- * created by invoking the default (that is, zero-argument) constructor. If
- * there is no such constructor, or if the creation fails (either because of
- * a lack of available memory or because an exception is thrown by the
- * constructor), an {@code InstantiationException} is thrown. If the default
- * constructor exists but is not accessible from the context where this
- * method is invoked, an {@code IllegalAccessException} is thrown.
- *
- * @throws IllegalAccessException
- * if the default constructor is not visible.
- * @throws InstantiationException
- * if the instance can not be created.
- */
- public T newInstance() throws InstantiationException, IllegalAccessException {
- return newInstanceImpl();
- }
-
- private native T newInstanceImpl() throws IllegalAccessException, InstantiationException;
-
- @Override
- public String toString() {
- if (isPrimitive()) {
- return getSimpleName();
- }
- return (isInterface() ? "interface " : "class ") + getName();
- }
-
- /**
- * Returns the {@code Package} of which the class represented by this
- * {@code Class} is a member. Returns {@code null} if no {@code Package}
- * object was created by the class loader of the class.
- */
- public Package getPackage() {
- // TODO This might be a hack, but the VM doesn't have the necessary info.
- ClassLoader loader = getClassLoader();
- if (loader != null) {
- String name = getName();
- int dot = name.lastIndexOf('.');
- return (dot != -1 ? loader.getPackage(name.substring(0, dot)) : null);
- }
- return null;
- }
-
- /**
- * Returns the assertion status for the class represented by this {@code
- * Class}. Assertion is enabled / disabled based on the class loader,
- * package or class default at runtime.
- */
- public native boolean desiredAssertionStatus();
-
- /**
- * Casts this {@code Class} to represent a subclass of the given class.
- * If successful, this {@code Class} is returned; otherwise a {@code
- * ClassCastException} is thrown.
- *
- * @throws ClassCastException
- * if this {@code Class} cannot be cast to the given type.
- */
- @SuppressWarnings("unchecked")
- public <U> Class<? extends U> asSubclass(Class<U> c) {
- if (c.isAssignableFrom(this)) {
- return (Class<? extends U>)this;
- }
- String actualClassName = this.getName();
- String desiredClassName = c.getName();
- throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName);
- }
-
- /**
- * Casts the given object to the type represented by this {@code Class}.
- * If the object is {@code null} then the result is also {@code null}.
- *
- * @throws ClassCastException
- * if the object cannot be cast to the given type.
- */
- @SuppressWarnings("unchecked")
- public T cast(Object obj) {
- if (obj == null) {
- return null;
- } else if (this.isInstance(obj)) {
- return (T)obj;
- }
- String actualClassName = obj.getClass().getName();
- String desiredClassName = this.getName();
- throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName);
- }
-
- /**
- * Copies two arrays into one. Assumes that the destination array is large
- * enough.
- *
- * @param result the destination array
- * @param head the first source array
- * @param tail the second source array
- * @return the destination array, that is, result
- */
- private static <T extends Object> T[] arraycopy(T[] result, T[] head, T[] tail) {
- System.arraycopy(head, 0, result, 0, head.length);
- System.arraycopy(tail, 0, result, head.length, tail.length);
- return result;
- }
-
- /**
- * The annotation directory offset of this class in its own Dex, or 0 if it
- * is unknown.
- *
- * TODO: 0 is a sentinel that means 'no annotations directory'; this should be -1 if unknown
- *
- * @hide
- */
- public int getDexAnnotationDirectoryOffset() {
- Dex dex = getDex();
- if (dex == null) {
- return 0;
- }
- int classDefIndex = getDexClassDefIndex();
- if (classDefIndex < 0) {
- return 0;
- }
- return dex.annotationDirectoryOffsetFromClassDefIndex(classDefIndex);
- }
-
-
- /**
- * Returns a resolved type from the dex cache, computing the type from the dex file if
- * necessary.
- * TODO: use Dalvik's dex cache.
- * @hide
- */
- public Class<?> getDexCacheType(Dex dex, int typeIndex) {
- String internalName = dex.typeNames().get(typeIndex);
- return InternalNames.getClass(getClassLoader(), internalName);
- }
-
- /**
- * Returns a string from the dex cache, computing the string from the dex file if necessary.
- *
- * @hide
- */
- public String getDexCacheString(Dex dex, int dexStringIndex) {
- return dex.strings().get(dexStringIndex);
- }
-
-
- private static class Caches {
- /**
- * Cache to avoid frequent recalculation of generic interfaces, which is generally uncommon.
- * Sized sufficient to allow ConcurrentHashMapTest to run without recalculating its generic
- * interfaces (required to avoid time outs). Validated by running reflection heavy code
- * such as applications using Guice-like frameworks.
- */
- private static final BasicLruCache<Class, Type[]> genericInterfaces
- = new BasicLruCache<Class, Type[]>(8);
- }
-}
diff --git a/libdvm/src/main/java/java/lang/ClassLoader.java b/libdvm/src/main/java/java/lang/ClassLoader.java
deleted file mode 100644
index c6a8091..0000000
--- a/libdvm/src/main/java/java/lang/ClassLoader.java
+++ /dev/null
@@ -1,836 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import dalvik.system.PathClassLoader;
-import dalvik.system.VMStack;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.security.ProtectionDomain;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Loads classes and resources from a repository. One or more class loaders are
- * installed at runtime. These are consulted whenever the runtime system needs a
- * specific class that is not yet available in-memory. Typically, class loaders
- * are grouped into a tree where child class loaders delegate all requests to
- * parent class loaders. Only if the parent class loader cannot satisfy the
- * request, the child class loader itself tries to handle it.
- * <p>
- * {@code ClassLoader} is an abstract class that implements the common
- * infrastructure required by all class loaders. Android provides several
- * concrete implementations of the class, with
- * {@link dalvik.system.PathClassLoader} being the one typically used. Other
- * applications may implement subclasses of {@code ClassLoader} to provide
- * special ways for loading classes.
- * </p>
- * @see Class
- */
-public abstract class ClassLoader {
-
- /**
- * The 'System' ClassLoader - the one that is responsible for loading
- * classes from the classpath. It is not equal to the bootstrap class loader -
- * that one handles the built-in classes.
- *
- * Because of a potential class initialization race between ClassLoader and
- * java.lang.System, reproducible when using JDWP with "suspend=y", we defer
- * creation of the system class loader until first use. We use a static
- * inner class to get synchronization at init time without having to sync on
- * every access.
- *
- * @see #getSystemClassLoader()
- */
- static private class SystemClassLoader {
- public static ClassLoader loader = ClassLoader.createSystemClassLoader();
- }
-
- /**
- * The parent ClassLoader.
- */
- private ClassLoader parent;
-
- /**
- * The packages known to the class loader.
- */
- private Map<String, Package> packages = new HashMap<String, Package>();
-
- /**
- * Create the system class loader. Note this is NOT the bootstrap class
- * loader (which is managed by the VM). We use a null value for the parent
- * to indicate that the bootstrap loader is our parent.
- */
- private static ClassLoader createSystemClassLoader() {
- String classPath = System.getProperty("java.class.path", ".");
-
- // String[] paths = classPath.split(":");
- // URL[] urls = new URL[paths.length];
- // for (int i = 0; i < paths.length; i++) {
- // try {
- // urls[i] = new URL("file://" + paths[i]);
- // }
- // catch (Exception ex) {
- // ex.printStackTrace();
- // }
- // }
- //
- // return new java.net.URLClassLoader(urls, null);
-
- // TODO Make this a java.net.URLClassLoader once we have those?
- return new PathClassLoader(classPath, BootClassLoader.getInstance());
- }
-
- /**
- * Returns the system class loader. This is the parent for new
- * {@code ClassLoader} instances and is typically the class loader used to
- * start the application.
- */
- public static ClassLoader getSystemClassLoader() {
- return SystemClassLoader.loader;
- }
-
- /**
- * Finds the URL of the resource with the specified name. The system class
- * loader's resource lookup algorithm is used to find the resource.
- *
- * @return the {@code URL} object for the requested resource or {@code null}
- * if the resource can not be found.
- * @param resName
- * the name of the resource to find.
- * @see Class#getResource
- */
- public static URL getSystemResource(String resName) {
- return SystemClassLoader.loader.getResource(resName);
- }
-
- /**
- * Returns an enumeration of URLs for the resource with the specified name.
- * The system class loader's resource lookup algorithm is used to find the
- * resource.
- *
- * @return an enumeration of {@code URL} objects containing the requested
- * resources.
- * @param resName
- * the name of the resource to find.
- * @throws IOException
- * if an I/O error occurs.
- */
- public static Enumeration<URL> getSystemResources(String resName) throws IOException {
- return SystemClassLoader.loader.getResources(resName);
- }
-
- /**
- * Returns a stream for the resource with the specified name. The system
- * class loader's resource lookup algorithm is used to find the resource.
- * Basically, the contents of the java.class.path are searched in order,
- * looking for a path which matches the specified resource.
- *
- * @return a stream for the resource or {@code null}.
- * @param resName
- * the name of the resource to find.
- * @see Class#getResourceAsStream
- */
- public static InputStream getSystemResourceAsStream(String resName) {
- return SystemClassLoader.loader.getResourceAsStream(resName);
- }
-
- /**
- * Constructs a new instance of this class with the system class loader as
- * its parent.
- */
- protected ClassLoader() {
- this(getSystemClassLoader(), false);
- }
-
- /**
- * Constructs a new instance of this class with the specified class loader
- * as its parent.
- *
- * @param parentLoader
- * The {@code ClassLoader} to use as the new class loader's
- * parent.
- */
- protected ClassLoader(ClassLoader parentLoader) {
- this(parentLoader, false);
- }
-
- /*
- * constructor for the BootClassLoader which needs parent to be null.
- */
- ClassLoader(ClassLoader parentLoader, boolean nullAllowed) {
- if (parentLoader == null && !nullAllowed) {
- throw new NullPointerException("parentLoader == null && !nullAllowed");
- }
- parent = parentLoader;
- }
-
- /**
- * Constructs a new class from an array of bytes containing a class
- * definition in class file format.
- *
- * @param classRep
- * the memory image of a class file.
- * @param offset
- * the offset into {@code classRep}.
- * @param length
- * the length of the class file.
- * @return the {@code Class} object created from the specified subset of
- * data in {@code classRep}.
- * @throws ClassFormatError
- * if {@code classRep} does not contain a valid class.
- * @throws IndexOutOfBoundsException
- * if {@code offset < 0}, {@code length < 0} or if
- * {@code offset + length} is greater than the length of
- * {@code classRep}.
- * @deprecated Use {@link #defineClass(String, byte[], int, int)} instead.
- */
- @Deprecated
- protected final Class<?> defineClass(byte[] classRep, int offset, int length)
- throws ClassFormatError {
- throw new UnsupportedOperationException("can't load this type of class file");
- }
-
- /**
- * Constructs a new class from an array of bytes containing a class
- * definition in class file format.
- *
- * @param className
- * the expected name of the new class, may be {@code null} if not
- * known.
- * @param classRep
- * the memory image of a class file.
- * @param offset
- * the offset into {@code classRep}.
- * @param length
- * the length of the class file.
- * @return the {@code Class} object created from the specified subset of
- * data in {@code classRep}.
- * @throws ClassFormatError
- * if {@code classRep} does not contain a valid class.
- * @throws IndexOutOfBoundsException
- * if {@code offset < 0}, {@code length < 0} or if
- * {@code offset + length} is greater than the length of
- * {@code classRep}.
- */
- protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length)
- throws ClassFormatError {
- throw new UnsupportedOperationException("can't load this type of class file");
- }
-
- /**
- * Constructs a new class from an array of bytes containing a class
- * definition in class file format and assigns the specified protection
- * domain to the new class. If the provided protection domain is
- * {@code null} then a default protection domain is assigned to the class.
- *
- * @param className
- * the expected name of the new class, may be {@code null} if not
- * known.
- * @param classRep
- * the memory image of a class file.
- * @param offset
- * the offset into {@code classRep}.
- * @param length
- * the length of the class file.
- * @param protectionDomain
- * the protection domain to assign to the loaded class, may be
- * {@code null}.
- * @return the {@code Class} object created from the specified subset of
- * data in {@code classRep}.
- * @throws ClassFormatError
- * if {@code classRep} does not contain a valid class.
- * @throws IndexOutOfBoundsException
- * if {@code offset < 0}, {@code length < 0} or if
- * {@code offset + length} is greater than the length of
- * {@code classRep}.
- * @throws NoClassDefFoundError
- * if {@code className} is not equal to the name of the class
- * contained in {@code classRep}.
- */
- protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length,
- ProtectionDomain protectionDomain) throws java.lang.ClassFormatError {
- throw new UnsupportedOperationException("can't load this type of class file");
- }
-
- /**
- * Defines a new class with the specified name, byte code from the byte
- * buffer and the optional protection domain. If the provided protection
- * domain is {@code null} then a default protection domain is assigned to
- * the class.
- *
- * @param name
- * the expected name of the new class, may be {@code null} if not
- * known.
- * @param b
- * the byte buffer containing the byte code of the new class.
- * @param protectionDomain
- * the protection domain to assign to the loaded class, may be
- * {@code null}.
- * @return the {@code Class} object created from the data in {@code b}.
- * @throws ClassFormatError
- * if {@code b} does not contain a valid class.
- * @throws NoClassDefFoundError
- * if {@code className} is not equal to the name of the class
- * contained in {@code b}.
- */
- protected final Class<?> defineClass(String name, ByteBuffer b,
- ProtectionDomain protectionDomain) throws ClassFormatError {
-
- byte[] temp = new byte[b.remaining()];
- b.get(temp);
- return defineClass(name, temp, 0, temp.length, protectionDomain);
- }
-
- /**
- * Overridden by subclasses, throws a {@code ClassNotFoundException} by
- * default. This method is called by {@code loadClass} after the parent
- * {@code ClassLoader} has failed to find a loaded class of the same name.
- *
- * @param className
- * the name of the class to look for.
- * @return the {@code Class} object that is found.
- * @throws ClassNotFoundException
- * if the class cannot be found.
- */
- protected Class<?> findClass(String className) throws ClassNotFoundException {
- throw new ClassNotFoundException(className);
- }
-
- /**
- * Returns the class with the specified name if it has already been loaded
- * by the VM or {@code null} if it has not yet been loaded.
- *
- * @param className
- * the name of the class to look for.
- * @return the {@code Class} object or {@code null} if the requested class
- * has not been loaded.
- */
- protected final Class<?> findLoadedClass(String className) {
- ClassLoader loader;
- if (this == BootClassLoader.getInstance())
- loader = null;
- else
- loader = this;
- return VMClassLoader.findLoadedClass(loader, className);
- }
-
- /**
- * Finds the class with the specified name, loading it using the system
- * class loader if necessary.
- *
- * @param className
- * the name of the class to look for.
- * @return the {@code Class} object with the requested {@code className}.
- * @throws ClassNotFoundException
- * if the class can not be found.
- */
- protected final Class<?> findSystemClass(String className) throws ClassNotFoundException {
- return Class.forName(className, false, getSystemClassLoader());
- }
-
- /**
- * Returns this class loader's parent.
- *
- * @return this class loader's parent or {@code null}.
- */
- public final ClassLoader getParent() {
- return parent;
- }
-
- /**
- * Returns the URL of the resource with the specified name. This
- * implementation first tries to use the parent class loader to find the
- * resource; if this fails then {@link #findResource(String)} is called to
- * find the requested resource.
- *
- * @param resName
- * the name of the resource to find.
- * @return the {@code URL} object for the requested resource or {@code null}
- * if the resource can not be found
- * @see Class#getResource
- */
- public URL getResource(String resName) {
- URL resource = parent.getResource(resName);
- if (resource == null) {
- resource = findResource(resName);
- }
- return resource;
- }
-
- /**
- * Returns an enumeration of URLs for the resource with the specified name.
- * This implementation first uses this class loader's parent to find the
- * resource, then it calls {@link #findResources(String)} to get additional
- * URLs. The returned enumeration contains the {@code URL} objects of both
- * find operations.
- *
- * @return an enumeration of {@code URL} objects for the requested resource.
- * @param resName
- * the name of the resource to find.
- * @throws IOException
- * if an I/O error occurs.
- */
- @SuppressWarnings("unchecked")
- public Enumeration<URL> getResources(String resName) throws IOException {
-
- Enumeration first = parent.getResources(resName);
- Enumeration second = findResources(resName);
-
- return new TwoEnumerationsInOne(first, second);
- }
-
- /**
- * Returns a stream for the resource with the specified name. See
- * {@link #getResource(String)} for a description of the lookup algorithm
- * used to find the resource.
- *
- * @return a stream for the resource or {@code null} if the resource can not be found
- * @param resName
- * the name of the resource to find.
- * @see Class#getResourceAsStream
- */
- public InputStream getResourceAsStream(String resName) {
- try {
- URL url = getResource(resName);
- if (url != null) {
- return url.openStream();
- }
- } catch (IOException ex) {
- // Don't want to see the exception.
- }
-
- return null;
- }
-
- /**
- * Loads the class with the specified name. Invoking this method is
- * equivalent to calling {@code loadClass(className, false)}.
- * <p>
- * <strong>Note:</strong> In the Android reference implementation, the
- * second parameter of {@link #loadClass(String, boolean)} is ignored
- * anyway.
- * </p>
- *
- * @return the {@code Class} object.
- * @param className
- * the name of the class to look for.
- * @throws ClassNotFoundException
- * if the class can not be found.
- */
- public Class<?> loadClass(String className) throws ClassNotFoundException {
- return loadClass(className, false);
- }
-
- /**
- * Loads the class with the specified name, optionally linking it after
- * loading. The following steps are performed:
- * <ol>
- * <li> Call {@link #findLoadedClass(String)} to determine if the requested
- * class has already been loaded.</li>
- * <li>If the class has not yet been loaded: Invoke this method on the
- * parent class loader.</li>
- * <li>If the class has still not been loaded: Call
- * {@link #findClass(String)} to find the class.</li>
- * </ol>
- * <p>
- * <strong>Note:</strong> In the Android reference implementation, the
- * {@code resolve} parameter is ignored; classes are never linked.
- * </p>
- *
- * @return the {@code Class} object.
- * @param className
- * the name of the class to look for.
- * @param resolve
- * Indicates if the class should be resolved after loading. This
- * parameter is ignored on the Android reference implementation;
- * classes are not resolved.
- * @throws ClassNotFoundException
- * if the class can not be found.
- */
- protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
- Class<?> clazz = findLoadedClass(className);
-
- if (clazz == null) {
- try {
- clazz = parent.loadClass(className, false);
- } catch (ClassNotFoundException e) {
- // Don't want to see this.
- }
-
- if (clazz == null) {
- clazz = findClass(className);
- }
- }
-
- return clazz;
- }
-
- /**
- * Forces a class to be linked (initialized). If the class has already been
- * linked this operation has no effect.
- * <p>
- * <strong>Note:</strong> In the Android reference implementation, this
- * method has no effect.
- * </p>
- *
- * @param clazz
- * the class to link.
- */
- protected final void resolveClass(Class<?> clazz) {
- // no-op, doesn't make sense on android.
- }
-
- /**
- * Finds the URL of the resource with the specified name. This
- * implementation just returns {@code null}; it should be overridden in
- * subclasses.
- *
- * @param resName
- * the name of the resource to find.
- * @return the {@code URL} object for the requested resource.
- */
- protected URL findResource(String resName) {
- return null;
- }
-
- /**
- * Finds an enumeration of URLs for the resource with the specified name.
- * This implementation just returns an empty {@code Enumeration}; it should
- * be overridden in subclasses.
- *
- * @param resName
- * the name of the resource to find.
- * @return an enumeration of {@code URL} objects for the requested resource.
- * @throws IOException
- * if an I/O error occurs.
- */
- @SuppressWarnings( {
- "unchecked", "unused"
- })
- protected Enumeration<URL> findResources(String resName) throws IOException {
- return Collections.emptyEnumeration();
- }
-
- /**
- * Returns the absolute path of the native library with the specified name,
- * or {@code null}. If this method returns {@code null} then the virtual
- * machine searches the directories specified by the system property
- * "java.library.path".
- * <p>
- * This implementation always returns {@code null}.
- * </p>
- *
- * @param libName
- * the name of the library to find.
- * @return the absolute path of the library.
- */
- protected String findLibrary(String libName) {
- return null;
- }
-
- /**
- * Returns the package with the specified name. Package information is
- * searched in this class loader.
- *
- * @param name
- * the name of the package to find.
- * @return the package with the requested name; {@code null} if the package
- * can not be found.
- */
- protected Package getPackage(String name) {
- synchronized (packages) {
- return packages.get(name);
- }
- }
-
- /**
- * Returns all the packages known to this class loader.
- *
- * @return an array with all packages known to this class loader.
- */
- protected Package[] getPackages() {
- synchronized (packages) {
- Collection<Package> col = packages.values();
- Package[] result = new Package[col.size()];
- col.toArray(result);
- return result;
- }
- }
-
- /**
- * Defines and returns a new {@code Package} using the specified
- * information. If {@code sealBase} is {@code null}, the package is left
- * unsealed. Otherwise, the package is sealed using this URL.
- *
- * @param name
- * the name of the package.
- * @param specTitle
- * the title of the specification.
- * @param specVersion
- * the version of the specification.
- * @param specVendor
- * the vendor of the specification.
- * @param implTitle
- * the implementation title.
- * @param implVersion
- * the implementation version.
- * @param implVendor
- * the specification vendor.
- * @param sealBase
- * the URL used to seal this package or {@code null} to leave the
- * package unsealed.
- * @return the {@code Package} object that has been created.
- * @throws IllegalArgumentException
- * if a package with the specified name already exists.
- */
- protected Package definePackage(String name, String specTitle, String specVersion,
- String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)
- throws IllegalArgumentException {
-
- synchronized (packages) {
- if (packages.containsKey(name)) {
- throw new IllegalArgumentException("Package " + name + " already defined");
- }
-
- Package newPackage = new Package(name, specTitle, specVersion, specVendor, implTitle,
- implVersion, implVendor, sealBase);
-
- packages.put(name, newPackage);
-
- return newPackage;
- }
- }
-
- /**
- * Sets the signers of the specified class. This implementation does
- * nothing.
- *
- * @param c
- * the {@code Class} object for which to set the signers.
- * @param signers
- * the signers for {@code c}.
- */
- protected final void setSigners(Class<?> c, Object[] signers) {
- }
-
- /**
- * Sets the assertion status of the class with the specified name.
- * <p>
- * <strong>Note: </strong>This method does nothing in the Android reference
- * implementation.
- * </p>
- *
- * @param cname
- * the name of the class for which to set the assertion status.
- * @param enable
- * the new assertion status.
- */
- public void setClassAssertionStatus(String cname, boolean enable) {
- }
-
- /**
- * Sets the assertion status of the package with the specified name.
- * <p>
- * <strong>Note: </strong>This method does nothing in the Android reference
- * implementation.
- * </p>
- *
- * @param pname
- * the name of the package for which to set the assertion status.
- * @param enable
- * the new assertion status.
- */
- public void setPackageAssertionStatus(String pname, boolean enable) {
- }
-
- /**
- * Sets the default assertion status for this class loader.
- * <p>
- * <strong>Note: </strong>This method does nothing in the Android reference
- * implementation.
- * </p>
- *
- * @param enable
- * the new assertion status.
- */
- public void setDefaultAssertionStatus(boolean enable) {
- }
-
- /**
- * Sets the default assertion status for this class loader to {@code false}
- * and removes any package default and class assertion status settings.
- * <p>
- * <strong>Note:</strong> This method does nothing in the Android reference
- * implementation.
- * </p>
- */
- public void clearAssertionStatus() {
- }
-}
-
-/*
- * Provides a helper class that combines two existing URL enumerations into one.
- * It is required for the getResources() methods. Items are fetched from the
- * first enumeration until it's empty, then from the second one.
- */
-class TwoEnumerationsInOne implements Enumeration<URL> {
-
- private Enumeration<URL> first;
-
- private Enumeration<URL> second;
-
- public TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second) {
- this.first = first;
- this.second = second;
- }
-
- public boolean hasMoreElements() {
- return first.hasMoreElements() || second.hasMoreElements();
- }
-
- public URL nextElement() {
- if (first.hasMoreElements()) {
- return first.nextElement();
- } else {
- return second.nextElement();
- }
- }
-
-}
-
-/**
- * Provides an explicit representation of the boot class loader. It sits at the
- * head of the class loader chain and delegates requests to the VM's internal
- * class loading mechanism.
- */
-class BootClassLoader extends ClassLoader {
-
- private static BootClassLoader instance;
-
- @FindBugsSuppressWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED")
- public static synchronized BootClassLoader getInstance() {
- if (instance == null) {
- instance = new BootClassLoader();
- }
-
- return instance;
- }
-
- public BootClassLoader() {
- super(null, true);
- }
-
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- return VMClassLoader.loadClass(name, false);
- }
-
- @Override
- protected URL findResource(String name) {
- return VMClassLoader.getResource(name);
- }
-
- @SuppressWarnings("unused")
- @Override
- protected Enumeration<URL> findResources(String resName) throws IOException {
- return Collections.enumeration(VMClassLoader.getResources(resName));
- }
-
- /**
- * Returns package information for the given package. Unfortunately, the
- * Android BootClassLoader doesn't really have this information, and as a
- * non-secure ClassLoader, it isn't even required to, according to the spec.
- * Yet, we want to provide it, in order to make all those hopeful callers of
- * {@code myClass.getPackage().getName()} happy. Thus we construct a Package
- * object the first time it is being requested and fill most of the fields
- * with dummy values. The Package object is then put into the ClassLoader's
- * Package cache, so we see the same one next time. We don't create Package
- * objects for null arguments or for the default package.
- * <p>
- * There a limited chance that we end up with multiple Package objects
- * representing the same package: It can happen when when a package is
- * scattered across different JAR files being loaded by different
- * ClassLoaders. Rather unlikely, and given that this whole thing is more or
- * less a workaround, probably not worth the effort.
- */
- @Override
- protected Package getPackage(String name) {
- if (name != null && !name.isEmpty()) {
- synchronized (this) {
- Package pack = super.getPackage(name);
-
- if (pack == null) {
- pack = definePackage(name, "Unknown", "0.0", "Unknown", "Unknown", "0.0",
- "Unknown", null);
- }
-
- return pack;
- }
- }
-
- return null;
- }
-
- @Override
- public URL getResource(String resName) {
- return findResource(resName);
- }
-
- @Override
- protected Class<?> loadClass(String className, boolean resolve)
- throws ClassNotFoundException {
- Class<?> clazz = findLoadedClass(className);
-
- if (clazz == null) {
- clazz = findClass(className);
- }
-
- return clazz;
- }
-
- @Override
- public Enumeration<URL> getResources(String resName) throws IOException {
- return findResources(resName);
- }
-}
-
-/**
- * TODO Open issues - Missing / empty methods - Signer stuff - Protection
- * domains - Assertions
- */
diff --git a/libdvm/src/main/java/java/lang/Daemons.java b/libdvm/src/main/java/java/lang/Daemons.java
deleted file mode 100644
index 78a4152..0000000
--- a/libdvm/src/main/java/java/lang/Daemons.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import dalvik.system.VMRuntime;
-import java.lang.ref.FinalizerReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.util.concurrent.TimeoutException;
-import libcore.util.EmptyArray;
-
-/**
- * Calls Object.finalize() on objects in the finalizer reference queue. The VM
- * will abort if any finalize() call takes more than the maximum finalize time
- * to complete.
- *
- * @hide
- */
-public final class Daemons {
- private static final int NANOS_PER_MILLI = 1000 * 1000;
- private static final int NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;
- private static final long MAX_FINALIZE_NANOS = 10L * NANOS_PER_SECOND;
-
- public static void start() {
- ReferenceQueueDaemon.INSTANCE.start();
- FinalizerDaemon.INSTANCE.start();
- FinalizerWatchdogDaemon.INSTANCE.start();
- }
-
- public static void stop() {
- ReferenceQueueDaemon.INSTANCE.stop();
- FinalizerDaemon.INSTANCE.stop();
- FinalizerWatchdogDaemon.INSTANCE.stop();
- }
-
- /**
- * A background task that provides runtime support to the application.
- * Daemons can be stopped and started, but only so that the zygote can be a
- * single-threaded process when it forks.
- */
- private static abstract class Daemon implements Runnable {
- private Thread thread;
-
- public synchronized void start() {
- if (thread != null) {
- throw new IllegalStateException("already running");
- }
- thread = new Thread(ThreadGroup.mSystem, this,
- getClass().getSimpleName());
- thread.setDaemon(true);
- thread.start();
- }
-
- public abstract void run();
-
- /**
- * Returns true while the current thread should continue to run; false
- * when it should return.
- */
- protected synchronized boolean isRunning() {
- return thread != null;
- }
-
- public synchronized void interrupt() {
- if (thread == null) {
- throw new IllegalStateException("not running");
- }
- thread.interrupt();
- }
-
- /**
- * Waits for the runtime thread to stop. This interrupts the thread
- * currently running the runnable and then waits for it to exit.
- */
- public void stop() {
- Thread threadToStop;
- synchronized (this) {
- threadToStop = thread;
- thread = null;
- }
- if (threadToStop == null) {
- throw new IllegalStateException("not running");
- }
- threadToStop.interrupt();
- while (true) {
- try {
- threadToStop.join();
- return;
- } catch (InterruptedException ignored) {
- }
- }
- }
-
- /**
- * Returns the current stack trace of the thread, or an empty stack trace
- * if the thread is not currently running.
- */
- public synchronized StackTraceElement[] getStackTrace() {
- return thread != null ? thread.getStackTrace() : EmptyArray.STACK_TRACE_ELEMENT;
- }
- }
-
- /**
- * This heap management thread moves elements from the garbage collector's
- * pending list to the managed reference queue.
- */
- private static class ReferenceQueueDaemon extends Daemon {
- private static final ReferenceQueueDaemon INSTANCE = new ReferenceQueueDaemon();
-
- @Override public void run() {
- while (isRunning()) {
- Reference<?> list;
- try {
- synchronized (ReferenceQueue.class) {
- while (ReferenceQueue.unenqueued == null) {
- ReferenceQueue.class.wait();
- }
- list = ReferenceQueue.unenqueued;
- ReferenceQueue.unenqueued = null;
- }
- } catch (InterruptedException e) {
- continue;
- }
- enqueue(list);
- }
- }
-
- private void enqueue(Reference<?> list) {
- while (list != null) {
- Reference<?> reference;
- // pendingNext is owned by the GC so no synchronization is required
- if (list == list.pendingNext) {
- reference = list;
- reference.pendingNext = null;
- list = null;
- } else {
- reference = list.pendingNext;
- list.pendingNext = reference.pendingNext;
- reference.pendingNext = null;
- }
- reference.enqueueInternal();
- }
- }
- }
-
- private static class FinalizerDaemon extends Daemon {
- private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();
- private final ReferenceQueue<Object> queue = FinalizerReference.queue;
- private volatile Object finalizingObject;
- private volatile long finalizingStartedNanos;
-
- @Override public void run() {
- while (isRunning()) {
- // Take a reference, blocking until one is ready or the thread should stop
- try {
- doFinalize((FinalizerReference<?>) queue.remove());
- } catch (InterruptedException ignored) {
- }
- }
- }
-
- @FindBugsSuppressWarnings("FI_EXPLICIT_INVOCATION")
- private void doFinalize(FinalizerReference<?> reference) {
- FinalizerReference.remove(reference);
- Object object = reference.get();
- reference.clear();
- try {
- finalizingStartedNanos = System.nanoTime();
- finalizingObject = object;
- synchronized (FinalizerWatchdogDaemon.INSTANCE) {
- FinalizerWatchdogDaemon.INSTANCE.notify();
- }
- object.finalize();
- } catch (Throwable ex) {
- // The RI silently swallows these, but Android has always logged.
- System.logE("Uncaught exception thrown by finalizer", ex);
- } finally {
- finalizingObject = null;
- }
- }
- }
-
- /**
- * The watchdog exits the VM if the finalizer ever gets stuck. We consider
- * the finalizer to be stuck if it spends more than MAX_FINALIZATION_MILLIS
- * on one instance.
- */
- private static class FinalizerWatchdogDaemon extends Daemon {
- private static final FinalizerWatchdogDaemon INSTANCE = new FinalizerWatchdogDaemon();
-
- @Override public void run() {
- while (isRunning()) {
- Object object = waitForObject();
- if (object == null) {
- // We have been interrupted, need to see if this daemon has been stopped.
- continue;
- }
- boolean finalized = waitForFinalization(object);
- if (!finalized && !VMRuntime.getRuntime().isDebuggerActive()) {
- finalizerTimedOut(object);
- break;
- }
- }
- }
-
- private Object waitForObject() {
- while (true) {
- Object object = FinalizerDaemon.INSTANCE.finalizingObject;
- if (object != null) {
- return object;
- }
- synchronized (this) {
- // wait until something is ready to be finalized
- // http://code.google.com/p/android/issues/detail?id=22778
- try {
- wait();
- } catch (InterruptedException e) {
- // Daemon.stop may have interrupted us.
- return null;
- }
- }
- }
- }
-
- private void sleepFor(long startNanos, long durationNanos) {
- while (true) {
- long elapsedNanos = System.nanoTime() - startNanos;
- long sleepNanos = durationNanos - elapsedNanos;
- long sleepMills = sleepNanos / NANOS_PER_MILLI;
- if (sleepMills <= 0) {
- return;
- }
- try {
- Thread.sleep(sleepMills);
- } catch (InterruptedException e) {
- if (!isRunning()) {
- return;
- }
- }
- }
- }
-
- private boolean waitForFinalization(Object object) {
- sleepFor(FinalizerDaemon.INSTANCE.finalizingStartedNanos, MAX_FINALIZE_NANOS);
- return object != FinalizerDaemon.INSTANCE.finalizingObject;
- }
-
- private static void finalizerTimedOut(Object object) {
- // The current object has exceeded the finalization deadline; abort!
- String message = object.getClass().getName() + ".finalize() timed out after "
- + (MAX_FINALIZE_NANOS / NANOS_PER_SECOND) + " seconds";
- Exception syntheticException = new TimeoutException(message);
- // We use the stack from where finalize() was running to show where it was stuck.
- syntheticException.setStackTrace(FinalizerDaemon.INSTANCE.getStackTrace());
- Thread.UncaughtExceptionHandler h = Thread.getDefaultUncaughtExceptionHandler();
- if (h == null) {
- // If we have no handler, log and exit.
- System.logE(message, syntheticException);
- System.exit(2);
- }
- // Otherwise call the handler to do crash reporting.
- // We don't just throw because we're not the thread that
- // timed out; we're the thread that detected it.
- h.uncaughtException(Thread.currentThread(), syntheticException);
- }
- }
-}
diff --git a/libdvm/src/main/java/java/lang/Enum.java b/libdvm/src/main/java/java/lang/Enum.java
deleted file mode 100644
index 7a0f514..0000000
--- a/libdvm/src/main/java/java/lang/Enum.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import libcore.util.BasicLruCache;
-import libcore.util.EmptyArray;
-
-/**
- * The superclass of all enumerated types. Actual enumeration types inherit from
- * this class, but extending this class does not make a class an enumeration
- * type, since the compiler needs to generate special information for it.
- */
-public abstract class Enum<E extends Enum<E>> implements Serializable, Comparable<E> {
-
- private static final long serialVersionUID = -4300926546619394005L;
-
- private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache
- = new BasicLruCache<Class<? extends Enum>, Object[]>(64) {
- @Override protected Object[] create(Class<? extends Enum> enumType) {
- if (!enumType.isEnum()) {
- return null;
- }
- Method method = (Method) Class.getDeclaredConstructorOrMethod(
- enumType, "values", EmptyArray.CLASS);
- try {
- return (Object[]) method.invoke((Object[]) null);
- } catch (IllegalAccessException impossible) {
- throw new AssertionError();
- } catch (InvocationTargetException impossible) {
- throw new AssertionError();
- }
- }
- };
-
- private final String name;
-
- private final int ordinal;
-
- /**
- * Constructor for constants of enum subtypes.
- *
- * @param name
- * the enum constant's declared name.
- * @param ordinal
- * the enum constant's ordinal, which corresponds to its position
- * in the enum declaration, starting at zero.
- */
- protected Enum(String name, int ordinal) {
- this.name = name;
- this.ordinal = ordinal;
- }
-
- /**
- * Returns the name of this enum constant. The name is the field as it
- * appears in the {@code enum} declaration.
- *
- * @return the name of this enum constant.
- * @see #toString()
- */
- public final String name() {
- return name;
- }
-
- /**
- * Returns the position of the enum constant in the declaration. The first
- * constant has an ordinal value of zero.
- *
- * @return the ordinal value of this enum constant.
- */
- public final int ordinal() {
- return ordinal;
- }
-
- /**
- * Returns a string containing a concise, human-readable description of this
- * object. In this case, the enum constant's name is returned.
- *
- * @return a printable representation of this object.
- */
- @Override
- public String toString() {
- return name;
- }
-
- /**
- * Compares this object with the specified object and indicates if they are
- * equal. In order to be equal, {@code object} must be identical to this
- * enum constant.
- *
- * @param other
- * the object to compare this enum constant with.
- * @return {@code true} if the specified object is equal to this
- * {@code Enum}; {@code false} otherwise.
- */
- @Override
- public final boolean equals(Object other) {
- return this == other;
- }
-
- @Override
- public final int hashCode() {
- return ordinal + (name == null ? 0 : name.hashCode());
- }
-
- /**
- * {@code Enum} objects are singletons, they may not be cloned. This method
- * always throws a {@code CloneNotSupportedException}.
- *
- * @return does not return.
- * @throws CloneNotSupportedException
- * is always thrown.
- */
- @Override
- protected final Object clone() throws CloneNotSupportedException {
- throw new CloneNotSupportedException("Enums may not be cloned");
- }
-
- /**
- * Compares this object to the specified enum object to determine their
- * relative order. This method compares the object's ordinal values, that
- * is, their position in the enum declaration.
- *
- * @param o
- * the enum object to compare this object to.
- * @return a negative value if the ordinal value of this enum constant is
- * less than the ordinal value of {@code o}; 0 if the ordinal
- * values of this enum constant and {@code o} are equal; a positive
- * value if the ordinal value of this enum constant is greater than
- * the ordinal value of {@code o}.
- * @see java.lang.Comparable
- */
- public final int compareTo(E o) {
- return ordinal - o.ordinal;
- }
-
- /**
- * Returns the enum constant's declaring class.
- *
- * @return the class object representing the constant's enum type.
- */
- @SuppressWarnings("unchecked")
- public final Class<E> getDeclaringClass() {
- Class<?> myClass = getClass();
- Class<?> mySuperClass = myClass.getSuperclass();
- if (Enum.class == mySuperClass) {
- return (Class<E>)myClass;
- }
- return (Class<E>)mySuperClass;
- }
-
- /**
- * Returns the constant with the specified name of the specified enum type.
- *
- * @param enumType
- * the class of the enumerated type to search for the constant
- * value.
- * @param name
- * the name of the constant value to find.
- * @return the enum constant.
- * @throws NullPointerException
- * if either {@code enumType} or {@code name} are {@code null}.
- * @throws IllegalArgumentException
- * if {@code enumType} is not an enumerated type or does not
- * have a constant value called {@code name}.
- */
- public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
- if (enumType == null) {
- throw new NullPointerException("enumType == null");
- } else if (name == null) {
- throw new NullPointerException("name == null");
- }
- T[] values = getSharedConstants(enumType);
- if (values == null) {
- throw new IllegalArgumentException(enumType + " is not an enum type");
- }
- for (T value : values) {
- if (name.equals(value.name())) {
- return value;
- }
- }
- throw new IllegalArgumentException(name + " is not a constant in " + enumType.getName());
- }
-
- /**
- * Returns a shared, mutable array containing the constants of this enum. It
- * is an error to modify the returned array.
- *
- * @hide
- */
- @SuppressWarnings("unchecked") // the cache always returns the type matching enumType
- public static <T extends Enum<T>> T[] getSharedConstants(Class<T> enumType) {
- return (T[]) sharedConstantsCache.get(enumType);
- }
-
- /**
- * Enum types may not have finalizers.
- *
- * @since 1.6
- */
- @Override
- @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
- protected final void finalize() {
- }
-}
diff --git a/libdvm/src/main/java/java/lang/Object.java b/libdvm/src/main/java/java/lang/Object.java
deleted file mode 100644
index 4bca034..0000000
--- a/libdvm/src/main/java/java/lang/Object.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-/**
- * The root class of the Java class hierarchy. All non-primitive types
- * (including arrays) inherit either directly or indirectly from this class.
- *
- * <a name="writing_equals"><h4>Writing a correct {@code equals} method</h4></a>
- * <p>Follow this style to write a canonical {@code equals} method:
- * <pre>
- * // Use @Override to avoid accidental overloading.
- * &#x0040;Override public boolean equals(Object o) {
- * // Return true if the objects are identical.
- * // (This is just an optimization, not required for correctness.)
- * if (this == o) {
- * return true;
- * }
- *
- * // Return false if the other object has the wrong type.
- * // This type may be an interface depending on the interface's specification.
- * if (!(o instanceof MyType)) {
- * return false;
- * }
- *
- * // Cast to the appropriate type.
- * // This will succeed because of the instanceof, and lets us access private fields.
- * MyType lhs = (MyType) o;
- *
- * // Check each field. Primitive fields, reference fields, and nullable reference
- * // fields are all treated differently.
- * return primitiveField == lhs.primitiveField &amp;&amp;
- * referenceField.equals(lhs.referenceField) &amp;&amp;
- * (nullableField == null ? lhs.nullableField == null
- * : nullableField.equals(lhs.nullableField));
- * }
- * </pre>
- * <p>If you override {@code equals}, you should also override {@code hashCode}: equal
- * instances must have equal hash codes.
- *
- * <p>See <i>Effective Java</i> item 8 for much more detail and clarification.
- *
- * <a name="writing_hashCode"><h4>Writing a correct {@code hashCode} method</h4></a>
- * <p>Follow this style to write a canonical {@code hashCode} method:
- * <pre>
- * &#x0040;Override public int hashCode() {
- * // Start with a non-zero constant.
- * int result = 17;
- *
- * // Include a hash for each field.
- * result = 31 * result + (booleanField ? 1 : 0);
- *
- * result = 31 * result + byteField;
- * result = 31 * result + charField;
- * result = 31 * result + shortField;
- * result = 31 * result + intField;
- *
- * result = 31 * result + (int) (longField ^ (longField >>> 32));
- *
- * result = 31 * result + Float.floatToIntBits(floatField);
- *
- * long doubleFieldBits = Double.doubleToLongBits(doubleField);
- * result = 31 * result + (int) (doubleFieldBits ^ (doubleFieldBits >>> 32));
- *
- * result = 31 * result + Arrays.hashCode(arrayField);
- *
- * result = 31 * result + referenceField.hashCode();
- * result = 31 * result +
- * (nullableReferenceField == null ? 0
- * : nullableReferenceField.hashCode());
- *
- * return result;
- * }
- * </pre>
- *
- * <p>If you don't intend your type to be used as a hash key, don't simply rely on the default
- * {@code hashCode} implementation, because that silently and non-obviously breaks any future
- * code that does use your type as a hash key. You should throw instead:
- * <pre>
- * &#x0040;Override public int hashCode() {
- * throw new UnsupportedOperationException();
- * }
- * </pre>
- *
- * <p>See <i>Effective Java</i> item 9 for much more detail and clarification.
- *
- * <a name="writing_toString"><h4>Writing a useful {@code toString} method</h4></a>
- * <p>For debugging convenience, it's common to override {@code toString} in this style:
- * <pre>
- * &#x0040;Override public String toString() {
- * return getClass().getName() + "[" +
- * "primitiveField=" + primitiveField + ", " +
- * "referenceField=" + referenceField + ", " +
- * "arrayField=" + Arrays.toString(arrayField) + "]";
- * }
- * </pre>
- * <p>The set of fields to include is generally the same as those that would be tested
- * in your {@code equals} implementation.
- * <p>See <i>Effective Java</i> item 10 for much more detail and clarification.
- */
-public class Object {
- /**
- * Constructs a new instance of {@code Object}.
- */
- public Object() {
- }
-
- /**
- * Creates and returns a copy of this {@code Object}. The default
- * implementation returns a so-called "shallow" copy: It creates a new
- * instance of the same class and then copies the field values (including
- * object references) from this instance to the new instance. A "deep" copy,
- * in contrast, would also recursively clone nested objects. A subclass that
- * needs to implement this kind of cloning should call {@code super.clone()}
- * to create the new instance and then create deep copies of the nested,
- * mutable objects.
- *
- * @return a copy of this object.
- * @throws CloneNotSupportedException
- * if this object's class does not implement the {@code
- * Cloneable} interface.
- */
- protected Object clone() throws CloneNotSupportedException {
- if (!(this instanceof Cloneable)) {
- throw new CloneNotSupportedException("Class doesn't implement Cloneable");
- }
-
- return internalClone((Cloneable) this);
- }
-
- /*
- * Native helper method for cloning.
- */
- private native Object internalClone(Cloneable o);
-
- /**
- * Compares this instance with the specified object and indicates if they
- * are equal. In order to be equal, {@code o} must represent the same object
- * as this instance using a class-specific comparison. The general contract
- * is that this comparison should be reflexive, symmetric, and transitive.
- * Also, no object reference other than null is equal to null.
- *
- * <p>The default implementation returns {@code true} only if {@code this ==
- * o}. See <a href="{@docRoot}reference/java/lang/Object.html#writing_equals">Writing a correct
- * {@code equals} method</a>
- * if you intend implementing your own {@code equals} method.
- *
- * <p>The general contract for the {@code equals} and {@link
- * #hashCode()} methods is that if {@code equals} returns {@code true} for
- * any two objects, then {@code hashCode()} must return the same value for
- * these objects. This means that subclasses of {@code Object} usually
- * override either both methods or neither of them.
- *
- * @param o
- * the object to compare this instance with.
- * @return {@code true} if the specified object is equal to this {@code
- * Object}; {@code false} otherwise.
- * @see #hashCode
- */
- public boolean equals(Object o) {
- return this == o;
- }
-
- /**
- * Invoked when the garbage collector has detected that this instance is no longer reachable.
- * The default implementation does nothing, but this method can be overridden to free resources.
- *
- * <p>Note that objects that override {@code finalize} are significantly more expensive than
- * objects that don't. Finalizers may be run a long time after the object is no longer
- * reachable, depending on memory pressure, so it's a bad idea to rely on them for cleanup.
- * Note also that finalizers are run on a single VM-wide finalizer thread,
- * so doing blocking work in a finalizer is a bad idea. A finalizer is usually only necessary
- * for a class that has a native peer and needs to call a native method to destroy that peer.
- * Even then, it's better to provide an explicit {@code close} method (and implement
- * {@link java.io.Closeable}), and insist that callers manually dispose of instances. This
- * works well for something like files, but less well for something like a {@code BigInteger}
- * where typical calling code would have to deal with lots of temporaries. Unfortunately,
- * code that creates lots of temporaries is the worst kind of code from the point of view of
- * the single finalizer thread.
- *
- * <p>If you <i>must</i> use finalizers, consider at least providing your own
- * {@link java.lang.ref.ReferenceQueue} and having your own thread process that queue.
- *
- * <p>Unlike constructors, finalizers are not automatically chained. You are responsible for
- * calling {@code super.finalize()} yourself.
- *
- * <p>Uncaught exceptions thrown by finalizers are ignored and do not terminate the finalizer
- * thread.
- *
- * See <i>Effective Java</i> Item 7, "Avoid finalizers" for more.
- */
- @FindBugsSuppressWarnings("FI_EMPTY")
- protected void finalize() throws Throwable {
- }
-
- /**
- * Returns the unique instance of {@link Class} that represents this
- * object's class. Note that {@code getClass()} is a special case in that it
- * actually returns {@code Class<? extends Foo>} where {@code Foo} is the
- * erasure of the type of the expression {@code getClass()} was called upon.
- * <p>
- * As an example, the following code actually compiles, although one might
- * think it shouldn't:
- * <p>
- * <pre>{@code
- * List<Integer> l = new ArrayList<Integer>();
- * Class<? extends List> c = l.getClass();}</pre>
- *
- * @return this object's {@code Class} instance.
- */
- public final native Class<?> getClass();
-
- /**
- * Returns an integer hash code for this object. By contract, any two
- * objects for which {@link #equals} returns {@code true} must return
- * the same hash code value. This means that subclasses of {@code Object}
- * usually override both methods or neither method.
- *
- * <p>Note that hash values must not change over time unless information used in equals
- * comparisons also changes.
- *
- * <p>See <a href="{@docRoot}reference/java/lang/Object.html#writing_hashCode">Writing a correct
- * {@code hashCode} method</a>
- * if you intend implementing your own {@code hashCode} method.
- *
- * @return this object's hash code.
- * @see #equals
- */
- public native int hashCode();
-
- /**
- * Causes a thread which is waiting on this object's monitor (by means of
- * calling one of the {@code wait()} methods) to be woken up. If more than
- * one thread is waiting, one of them is chosen at the discretion of the
- * VM. The chosen thread will not run immediately. The thread
- * that called {@code notify()} has to release the object's monitor first.
- * Also, the chosen thread still has to compete against other threads that
- * try to synchronize on the same object.
- * <p>
- * This method can only be invoked by a thread which owns this object's
- * monitor. A thread becomes owner of an object's monitor
- * </p>
- * <ul>
- * <li>by executing a synchronized method of that object;</li>
- * <li>by executing the body of a {@code synchronized} statement that
- * synchronizes on the object;</li>
- * <li>by executing a synchronized static method if the object is of type
- * {@code Class}.</li>
- * </ul>
- *
- * @see #notifyAll
- * @see #wait()
- * @see #wait(long)
- * @see #wait(long,int)
- * @see java.lang.Thread
- */
- public final native void notify();
-
- /**
- * Causes all threads which are waiting on this object's monitor (by means
- * of calling one of the {@code wait()} methods) to be woken up. The threads
- * will not run immediately. The thread that called {@code notify()} has to
- * release the object's monitor first. Also, the threads still have to
- * compete against other threads that try to synchronize on the same object.
- * <p>
- * This method can only be invoked by a thread which owns this object's
- * monitor. A thread becomes owner of an object's monitor
- * </p>
- * <ul>
- * <li>by executing a synchronized method of that object;</li>
- * <li>by executing the body of a {@code synchronized} statement that
- * synchronizes on the object;</li>
- * <li>by executing a synchronized static method if the object is of type
- * {@code Class}.</li>
- * </ul>
- *
- * @throws IllegalMonitorStateException
- * if the thread calling this method is not the owner of this
- * object's monitor.
- * @see #notify
- * @see #wait()
- * @see #wait(long)
- * @see #wait(long,int)
- * @see java.lang.Thread
- */
- public final native void notifyAll();
-
- /**
- * Returns a string containing a concise, human-readable description of this
- * object. Subclasses are encouraged to override this method and provide an
- * implementation that takes into account the object's type and data. The
- * default implementation is equivalent to the following expression:
- * <pre>
- * getClass().getName() + '@' + Integer.toHexString(hashCode())</pre>
- * <p>See <a href="{@docRoot}reference/java/lang/Object.html#writing_toString">Writing a useful
- * {@code toString} method</a>
- * if you intend implementing your own {@code toString} method.
- *
- * @return a printable representation of this object.
- */
- public String toString() {
- return getClass().getName() + '@' + Integer.toHexString(hashCode());
- }
-
- /**
- * Causes the calling thread to wait until another thread calls the {@code
- * notify()} or {@code notifyAll()} method of this object. This method can
- * only be invoked by a thread which owns this object's monitor; see
- * {@link #notify()} on how a thread can become the owner of a monitor.
- * <p>
- * A waiting thread can be sent {@code interrupt()} to cause it to
- * prematurely stop waiting, so {@code wait} should be called in a loop to
- * check that the condition that has been waited for has been met before
- * continuing.
- * </p>
- * <p>
- * While the thread waits, it gives up ownership of this object's monitor.
- * When it is notified (or interrupted), it re-acquires the monitor before
- * it starts running.
- * </p>
- *
- * @throws IllegalMonitorStateException
- * if the thread calling this method is not the owner of this
- * object's monitor.
- * @throws InterruptedException
- * if another thread interrupts this thread while it is waiting.
- * @see #notify
- * @see #notifyAll
- * @see #wait(long)
- * @see #wait(long,int)
- * @see java.lang.Thread
- */
- public final void wait() throws InterruptedException {
- wait(0, 0);
- }
-
- /**
- * Causes the calling thread to wait until another thread calls the {@code
- * notify()} or {@code notifyAll()} method of this object or until the
- * specified timeout expires. This method can only be invoked by a thread
- * which owns this object's monitor; see {@link #notify()} on how a thread
- * can become the owner of a monitor.
- * <p>
- * A waiting thread can be sent {@code interrupt()} to cause it to
- * prematurely stop waiting, so {@code wait} should be called in a loop to
- * check that the condition that has been waited for has been met before
- * continuing.
- * </p>
- * <p>
- * While the thread waits, it gives up ownership of this object's monitor.
- * When it is notified (or interrupted), it re-acquires the monitor before
- * it starts running.
- * </p>
- *
- * @param millis
- * the maximum time to wait in milliseconds.
- * @throws IllegalArgumentException
- * if {@code millis < 0}.
- * @throws IllegalMonitorStateException
- * if the thread calling this method is not the owner of this
- * object's monitor.
- * @throws InterruptedException
- * if another thread interrupts this thread while it is waiting.
- * @see #notify
- * @see #notifyAll
- * @see #wait()
- * @see #wait(long,int)
- * @see java.lang.Thread
- */
- public final void wait(long millis) throws InterruptedException {
- wait(millis, 0);
- }
-
- /**
- * Causes the calling thread to wait until another thread calls the {@code
- * notify()} or {@code notifyAll()} method of this object or until the
- * specified timeout expires. This method can only be invoked by a thread
- * that owns this object's monitor; see {@link #notify()} on how a thread
- * can become the owner of a monitor.
- * <p>
- * A waiting thread can be sent {@code interrupt()} to cause it to
- * prematurely stop waiting, so {@code wait} should be called in a loop to
- * check that the condition that has been waited for has been met before
- * continuing.
- * </p>
- * <p>
- * While the thread waits, it gives up ownership of this object's monitor.
- * When it is notified (or interrupted), it re-acquires the monitor before
- * it starts running.
- * </p>
- *
- * @param millis
- * the maximum time to wait in milliseconds.
- * @param nanos
- * the fraction of a millisecond to wait, specified in
- * nanoseconds.
- * @throws IllegalArgumentException
- * if {@code millis < 0}, {@code nanos < 0} or {@code nanos >
- * 999999}.
- * @throws IllegalMonitorStateException
- * if the thread calling this method is not the owner of this
- * object's monitor.
- * @throws InterruptedException
- * if another thread interrupts this thread while it is waiting.
- * @see #notify
- * @see #notifyAll
- * @see #wait()
- * @see #wait(long,int)
- * @see java.lang.Thread
- */
- public final native void wait(long millis, int nanos) throws InterruptedException;
-}
diff --git a/libdvm/src/main/java/java/lang/String.java b/libdvm/src/main/java/java/lang/String.java
deleted file mode 100644
index 27469f0..0000000
--- a/libdvm/src/main/java/java/lang/String.java
+++ /dev/null
@@ -1,2046 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.Charsets;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Formatter;
-import java.util.Locale;
-import java.util.regex.Pattern;
-import libcore.util.EmptyArray;
-
-/**
- * An immutable sequence of characters/code units ({@code char}s). A
- * {@code String} is represented by array of UTF-16 values, such that
- * Unicode supplementary characters (code points) are stored/encoded as
- * surrogate pairs via Unicode code units ({@code char}).
- *
- * <a name="backing_array"><h3>Backing Arrays</h3></a>
- * This class is implemented using a char[]. The length of the array may exceed
- * the length of the string. For example, the string "Hello" may be backed by
- * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with
- * offset 0 and length 5.
- *
- * <p>Multiple strings can share the same char[] because strings are immutable.
- * The {@link #substring} method <strong>always</strong> returns a string that
- * shares the backing array of its source string. Generally this is an
- * optimization: fewer character arrays need to be allocated, and less copying
- * is necessary. But this can also lead to unwanted heap retention. Taking a
- * short substring of long string means that the long shared char[] won't be
- * garbage until both strings are garbage. This typically happens when parsing
- * small substrings out of a large input. To avoid this where necessary, call
- * {@code new String(longString.subString(...))}. The string copy constructor
- * always ensures that the backing array is no larger than necessary.
- *
- * @see StringBuffer
- * @see StringBuilder
- * @see Charset
- * @since 1.0
- */
-public final class String implements Serializable, Comparable<String>, CharSequence {
-
- private static final long serialVersionUID = -6849794470754667710L;
-
- private static final char REPLACEMENT_CHAR = (char) 0xfffd;
-
- /**
- * CaseInsensitiveComparator compares Strings ignoring the case of the
- * characters.
- */
- private static final class CaseInsensitiveComparator implements
- Comparator<String>, Serializable {
- private static final long serialVersionUID = 8575799808933029326L;
-
- /**
- * Compare the two objects to determine the relative ordering.
- *
- * @param o1
- * an Object to compare
- * @param o2
- * an Object to compare
- * @return an int < 0 if object1 is less than object2, 0 if they are
- * equal, and > 0 if object1 is greater
- *
- * @exception ClassCastException
- * if objects are not the correct type
- */
- public int compare(String o1, String o2) {
- return o1.compareToIgnoreCase(o2);
- }
- }
-
- /**
- * A comparator ignoring the case of the characters.
- */
- public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
-
- private static final char[] ASCII;
- static {
- ASCII = new char[128];
- for (int i = 0; i < ASCII.length; ++i) {
- ASCII[i] = (char) i;
- }
- }
-
- private final char[] value;
-
- private final int offset;
-
- private final int count;
-
- private int hashCode;
-
- /**
- * Creates an empty string.
- */
- public String() {
- value = EmptyArray.CHAR;
- offset = 0;
- count = 0;
- }
-
- /*
- * Private constructor used for JIT optimization.
- */
- @SuppressWarnings("unused")
- private String(String s, char c) {
- offset = 0;
- value = new char[s.count + 1];
- count = s.count + 1;
- System.arraycopy(s.value, s.offset, value, 0, s.count);
- value[s.count] = c;
- }
-
- /**
- * Converts the byte array to a string using the system's
- * {@link java.nio.charset.Charset#defaultCharset default charset}.
- */
- @FindBugsSuppressWarnings("DM_DEFAULT_ENCODING")
- public String(byte[] data) {
- this(data, 0, data.length);
- }
-
- /**
- * Converts the byte array to a string, setting the high byte of every
- * character to the specified value.
- *
- * @param data
- * the byte array to convert to a string.
- * @param high
- * the high byte to use.
- * @throws NullPointerException
- * if {@code data == null}.
- * @deprecated Use {@link #String(byte[])} or {@link #String(byte[], String)} instead.
- */
- @Deprecated
- public String(byte[] data, int high) {
- this(data, high, 0, data.length);
- }
-
- /**
- * Converts a subsequence of the byte array to a string using the system's
- * {@link java.nio.charset.Charset#defaultCharset default charset}.
- *
- * @throws NullPointerException
- * if {@code data == null}.
- * @throws IndexOutOfBoundsException
- * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
- */
- public String(byte[] data, int offset, int byteCount) {
- this(data, offset, byteCount, Charset.defaultCharset());
- }
-
- /**
- * Converts the byte array to a string, setting the high byte of every
- * character to {@code high}.
- *
- * @throws NullPointerException
- * if {@code data == null}.
- * @throws IndexOutOfBoundsException
- * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
- *
- * @deprecated Use {@link #String(byte[], int, int)} instead.
- */
- @Deprecated
- public String(byte[] data, int high, int offset, int byteCount) {
- if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
- throw failedBoundsCheck(data.length, offset, byteCount);
- }
- this.offset = 0;
- this.value = new char[byteCount];
- this.count = byteCount;
- high <<= 8;
- for (int i = 0; i < count; i++) {
- value[i] = (char) (high + (data[offset++] & 0xff));
- }
- }
-
- /**
- * Converts the byte array to a string using the named charset.
- *
- * <p>The behavior when the bytes cannot be decoded by the named charset
- * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
- *
- * @throws NullPointerException
- * if {@code data == null}.
- * @throws IndexOutOfBoundsException
- * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
- * @throws UnsupportedEncodingException
- * if the named charset is not supported.
- */
- public String(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException {
- this(data, offset, byteCount, Charset.forNameUEE(charsetName));
- }
-
- /**
- * Converts the byte array to a string using the named charset.
- *
- * <p>The behavior when the bytes cannot be decoded by the named charset
- * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
- *
- * @throws NullPointerException
- * if {@code data == null}.
- * @throws UnsupportedEncodingException
- * if {@code charsetName} is not supported.
- */
- public String(byte[] data, String charsetName) throws UnsupportedEncodingException {
- this(data, 0, data.length, Charset.forNameUEE(charsetName));
- }
-
- /**
- * Converts the byte array to a string using the given charset.
- *
- * <p>The behavior when the bytes cannot be decoded by the given charset
- * is to replace malformed input and unmappable characters with the charset's default
- * replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control.
- *
- * @throws IndexOutOfBoundsException
- * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
- * @throws NullPointerException
- * if {@code data == null}
- *
- * @since 1.6
- */
- public String(byte[] data, int offset, int byteCount, Charset charset) {
- if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
- throw failedBoundsCheck(data.length, offset, byteCount);
- }
-
- // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed and because 'count' and
- // 'value' are final.
- String canonicalCharsetName = charset.name();
- if (canonicalCharsetName.equals("UTF-8")) {
- byte[] d = data;
- char[] v = new char[byteCount];
-
- int idx = offset;
- int last = offset + byteCount;
- int s = 0;
-outer:
- while (idx < last) {
- byte b0 = d[idx++];
- if ((b0 & 0x80) == 0) {
- // 0xxxxxxx
- // Range: U-00000000 - U-0000007F
- int val = b0 & 0xff;
- v[s++] = (char) val;
- } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) ||
- ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) {
- int utfCount = 1;
- if ((b0 & 0xf0) == 0xe0) utfCount = 2;
- else if ((b0 & 0xf8) == 0xf0) utfCount = 3;
- else if ((b0 & 0xfc) == 0xf8) utfCount = 4;
- else if ((b0 & 0xfe) == 0xfc) utfCount = 5;
-
- // 110xxxxx (10xxxxxx)+
- // Range: U-00000080 - U-000007FF (count == 1)
- // Range: U-00000800 - U-0000FFFF (count == 2)
- // Range: U-00010000 - U-001FFFFF (count == 3)
- // Range: U-00200000 - U-03FFFFFF (count == 4)
- // Range: U-04000000 - U-7FFFFFFF (count == 5)
-
- if (idx + utfCount > last) {
- v[s++] = REPLACEMENT_CHAR;
- continue;
- }
-
- // Extract usable bits from b0
- int val = b0 & (0x1f >> (utfCount - 1));
- for (int i = 0; i < utfCount; ++i) {
- byte b = d[idx++];
- if ((b & 0xc0) != 0x80) {
- v[s++] = REPLACEMENT_CHAR;
- idx--; // Put the input char back
- continue outer;
- }
- // Push new bits in from the right side
- val <<= 6;
- val |= b & 0x3f;
- }
-
- // Note: Java allows overlong char
- // specifications To disallow, check that val
- // is greater than or equal to the minimum
- // value for each count:
- //
- // count min value
- // ----- ----------
- // 1 0x80
- // 2 0x800
- // 3 0x10000
- // 4 0x200000
- // 5 0x4000000
-
- // Allow surrogate values (0xD800 - 0xDFFF) to
- // be specified using 3-byte UTF values only
- if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) {
- v[s++] = REPLACEMENT_CHAR;
- continue;
- }
-
- // Reject chars greater than the Unicode maximum of U+10FFFF.
- if (val > 0x10FFFF) {
- v[s++] = REPLACEMENT_CHAR;
- continue;
- }
-
- // Encode chars from U+10000 up as surrogate pairs
- if (val < 0x10000) {
- v[s++] = (char) val;
- } else {
- int x = val & 0xffff;
- int u = (val >> 16) & 0x1f;
- int w = (u - 1) & 0xffff;
- int hi = 0xd800 | (w << 6) | (x >> 10);
- int lo = 0xdc00 | (x & 0x3ff);
- v[s++] = (char) hi;
- v[s++] = (char) lo;
- }
- } else {
- // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff
- v[s++] = REPLACEMENT_CHAR;
- }
- }
-
- if (s == byteCount) {
- // We guessed right, so we can use our temporary array as-is.
- this.offset = 0;
- this.value = v;
- this.count = s;
- } else {
- // Our temporary array was too big, so reallocate and copy.
- this.offset = 0;
- this.value = new char[s];
- this.count = s;
- System.arraycopy(v, 0, value, 0, s);
- }
- } else if (canonicalCharsetName.equals("ISO-8859-1")) {
- this.offset = 0;
- this.value = new char[byteCount];
- this.count = byteCount;
- Charsets.isoLatin1BytesToChars(data, offset, byteCount, value);
- } else if (canonicalCharsetName.equals("US-ASCII")) {
- this.offset = 0;
- this.value = new char[byteCount];
- this.count = byteCount;
- Charsets.asciiBytesToChars(data, offset, byteCount, value);
- } else {
- CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
- this.offset = 0;
- this.count = cb.length();
- if (count > 0) {
- // We could use cb.array() directly, but that would mean we'd have to trust
- // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later,
- // which would break String's immutability guarantee. It would also tend to
- // mean that we'd be wasting memory because CharsetDecoder doesn't trim the
- // array. So we copy.
- this.value = new char[count];
- System.arraycopy(cb.array(), 0, value, 0, count);
- } else {
- this.value = EmptyArray.CHAR;
- }
- }
- }
-
- /**
- * Converts the byte array to a String using the given charset.
- *
- * @throws NullPointerException if {@code data == null}
- * @since 1.6
- */
- public String(byte[] data, Charset charset) {
- this(data, 0, data.length, charset);
- }
-
- /**
- * Initializes this string to contain the characters in the specified
- * character array. Modifying the character array after creating the string
- * has no effect on the string.
- *
- * @throws NullPointerException if {@code data == null}
- */
- public String(char[] data) {
- this(data, 0, data.length);
- }
-
- /**
- * Initializes this string to contain the specified characters in the
- * character array. Modifying the character array after creating the string
- * has no effect on the string.
- *
- * @throws NullPointerException
- * if {@code data == null}.
- * @throws IndexOutOfBoundsException
- * if {@code charCount < 0 || offset < 0 || offset + charCount > data.length}
- */
- public String(char[] data, int offset, int charCount) {
- if ((offset | charCount) < 0 || charCount > data.length - offset) {
- throw failedBoundsCheck(data.length, offset, charCount);
- }
- this.offset = 0;
- this.value = new char[charCount];
- this.count = charCount;
- System.arraycopy(data, offset, value, 0, count);
- }
-
- /*
- * Internal version of the String(char[], int, int) constructor.
- * Does not range check, null check, or copy the character array.
- */
- String(int offset, int charCount, char[] chars) {
- this.value = chars;
- this.offset = offset;
- this.count = charCount;
- }
-
- /**
- * Constructs a new string with the same sequence of characters as {@code
- * toCopy}. The returned string's <a href="#backing_array">backing array</a>
- * is no larger than necessary.
- */
- public String(String toCopy) {
- value = (toCopy.value.length == toCopy.count)
- ? toCopy.value
- : Arrays.copyOfRange(toCopy.value, toCopy.offset, toCopy.offset + toCopy.length());
- offset = 0;
- count = value.length;
- }
-
- /*
- * Private constructor useful for JIT optimization.
- */
- @SuppressWarnings( { "unused", "nls" })
- private String(String s1, String s2) {
- if (s1 == null) {
- s1 = "null";
- }
- if (s2 == null) {
- s2 = "null";
- }
- count = s1.count + s2.count;
- value = new char[count];
- offset = 0;
- System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
- System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
- }
-
- /*
- * Private constructor useful for JIT optimization.
- */
- @SuppressWarnings( { "unused", "nls" })
- private String(String s1, String s2, String s3) {
- if (s1 == null) {
- s1 = "null";
- }
- if (s2 == null) {
- s2 = "null";
- }
- if (s3 == null) {
- s3 = "null";
- }
- count = s1.count + s2.count + s3.count;
- value = new char[count];
- offset = 0;
- System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
- System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
- System.arraycopy(s3.value, s3.offset, value, s1.count + s2.count, s3.count);
- }
-
- /**
- * Creates a {@code String} from the contents of the specified
- * {@code StringBuffer}.
- */
- public String(StringBuffer stringBuffer) {
- offset = 0;
- synchronized (stringBuffer) {
- value = stringBuffer.shareValue();
- count = stringBuffer.length();
- }
- }
-
- /**
- * Creates a {@code String} from the sub-array of Unicode code points.
- *
- * @throws NullPointerException
- * if {@code codePoints == null}.
- * @throws IllegalArgumentException
- * if any of the elements of {@code codePoints} are not valid
- * Unicode code points.
- * @throws IndexOutOfBoundsException
- * if {@code offset} or {@code count} are not within the bounds
- * of {@code codePoints}.
- * @since 1.5
- */
- public String(int[] codePoints, int offset, int count) {
- if (codePoints == null) {
- throw new NullPointerException("codePoints == null");
- }
- if ((offset | count) < 0 || count > codePoints.length - offset) {
- throw failedBoundsCheck(codePoints.length, offset, count);
- }
- this.offset = 0;
- this.value = new char[count * 2];
- int end = offset + count;
- int c = 0;
- for (int i = offset; i < end; i++) {
- c += Character.toChars(codePoints[i], this.value, c);
- }
- this.count = c;
- }
-
- /**
- * Creates a {@code String} from the contents of the specified {@code
- * StringBuilder}.
- *
- * @throws NullPointerException
- * if {@code stringBuilder == null}.
- * @since 1.5
- */
- public String(StringBuilder stringBuilder) {
- if (stringBuilder == null) {
- throw new NullPointerException("stringBuilder == null");
- }
- this.offset = 0;
- this.count = stringBuilder.length();
- this.value = new char[this.count];
- stringBuilder.getChars(0, this.count, this.value, 0);
- }
-
- /*
- * Creates a {@code String} that is s1 + v1. May be used by JIT code.
- */
- @SuppressWarnings("unused")
- private String(String s1, int v1) {
- if (s1 == null) {
- s1 = "null";
- }
- String s2 = String.valueOf(v1);
- int len = s1.count + s2.count;
- value = new char[len];
- offset = 0;
- System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
- System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
- count = len;
- }
-
- /**
- * Returns the character at the specified offset in this string.
- *
- * @param index
- * the zero-based index in this string.
- * @return the character at the index.
- * @throws IndexOutOfBoundsException
- * if {@code index < 0} or {@code index >= length()}.
- */
- public char charAt(int index) {
- if (index < 0 || index >= count) {
- throw indexAndLength(index);
- }
- return value[offset + index];
- }
-
- private StringIndexOutOfBoundsException indexAndLength(int index) {
- throw new StringIndexOutOfBoundsException(this, index);
- }
-
- private StringIndexOutOfBoundsException startEndAndLength(int start, int end) {
- throw new StringIndexOutOfBoundsException(this, start, end - start);
- }
-
- private StringIndexOutOfBoundsException failedBoundsCheck(int arrayLength, int offset, int count) {
- throw new StringIndexOutOfBoundsException(arrayLength, offset, count);
- }
-
- /**
- * This isn't equivalent to either of ICU's u_foldCase case folds, and thus any of the Unicode
- * case folds, but it's what the RI uses.
- */
- private char foldCase(char ch) {
- if (ch < 128) {
- if ('A' <= ch && ch <= 'Z') {
- return (char) (ch + ('a' - 'A'));
- }
- return ch;
- }
- return Character.toLowerCase(Character.toUpperCase(ch));
- }
-
- /**
- * Compares the specified string to this string using the Unicode values of
- * the characters. Returns 0 if the strings contain the same characters in
- * the same order. Returns a negative integer if the first non-equal
- * character in this string has a Unicode value which is less than the
- * Unicode value of the character at the same position in the specified
- * string, or if this string is a prefix of the specified string. Returns a
- * positive integer if the first non-equal character in this string has a
- * Unicode value which is greater than the Unicode value of the character at
- * the same position in the specified string, or if the specified string is
- * a prefix of this string.
- *
- * @param string
- * the string to compare.
- * @return 0 if the strings are equal, a negative integer if this string is
- * before the specified string, or a positive integer if this string
- * is after the specified string.
- * @throws NullPointerException
- * if {@code string} is {@code null}.
- */
- public native int compareTo(String string);
-
- /**
- * Compares the specified string to this string using the Unicode values of
- * the characters, ignoring case differences. Returns 0 if the strings
- * contain the same characters in the same order. Returns a negative integer
- * if the first non-equal character in this string has a Unicode value which
- * is less than the Unicode value of the character at the same position in
- * the specified string, or if this string is a prefix of the specified
- * string. Returns a positive integer if the first non-equal character in
- * this string has a Unicode value which is greater than the Unicode value
- * of the character at the same position in the specified string, or if the
- * specified string is a prefix of this string.
- *
- * @param string
- * the string to compare.
- * @return 0 if the strings are equal, a negative integer if this string is
- * before the specified string, or a positive integer if this string
- * is after the specified string.
- * @throws NullPointerException
- * if {@code string} is {@code null}.
- */
- public int compareToIgnoreCase(String string) {
- int o1 = offset, o2 = string.offset, result;
- int end = offset + (count < string.count ? count : string.count);
- char c1, c2;
- char[] target = string.value;
- while (o1 < end) {
- if ((c1 = value[o1++]) == (c2 = target[o2++])) {
- continue;
- }
- c1 = foldCase(c1);
- c2 = foldCase(c2);
- if ((result = c1 - c2) != 0) {
- return result;
- }
- }
- return count - string.count;
- }
-
- /**
- * Concatenates this string and the specified string.
- *
- * @param string
- * the string to concatenate
- * @return a new string which is the concatenation of this string and the
- * specified string.
- */
- public String concat(String string) {
- if (string.count > 0 && count > 0) {
- char[] buffer = new char[count + string.count];
- System.arraycopy(value, offset, buffer, 0, count);
- System.arraycopy(string.value, string.offset, buffer, count, string.count);
- return new String(0, buffer.length, buffer);
- }
- return count == 0 ? string : this;
- }
-
- /**
- * Creates a new string containing the characters in the specified character
- * array. Modifying the character array after creating the string has no
- * effect on the string.
- *
- * @param data
- * the array of characters.
- * @return the new string.
- * @throws NullPointerException
- * if {@code data} is {@code null}.
- */
- public static String copyValueOf(char[] data) {
- return new String(data, 0, data.length);
- }
-
- /**
- * Creates a new string containing the specified characters in the character
- * array. Modifying the character array after creating the string has no
- * effect on the string.
- *
- * @param data
- * the array of characters.
- * @param start
- * the starting offset in the character array.
- * @param length
- * the number of characters to use.
- * @return the new string.
- * @throws NullPointerException
- * if {@code data} is {@code null}.
- * @throws IndexOutOfBoundsException
- * if {@code length < 0, start < 0} or {@code start + length >
- * data.length}.
- */
- public static String copyValueOf(char[] data, int start, int length) {
- return new String(data, start, length);
- }
-
- /**
- * Compares the specified string to this string to determine if the
- * specified string is a suffix.
- *
- * @param suffix
- * the suffix to look for.
- * @return {@code true} if the specified string is a suffix of this string,
- * {@code false} otherwise.
- * @throws NullPointerException
- * if {@code suffix} is {@code null}.
- */
- public boolean endsWith(String suffix) {
- return regionMatches(count - suffix.count, suffix, 0, suffix.count);
- }
-
- /**
- * Compares the specified object to this string and returns true if they are
- * equal. The object must be an instance of string with the same characters
- * in the same order.
- *
- * @param object
- * the object to compare.
- * @return {@code true} if the specified object is equal to this string,
- * {@code false} otherwise.
- * @see #hashCode
- */
- @Override public native boolean equals(Object object);
-
- /**
- * Compares the specified string to this string ignoring the case of the
- * characters and returns true if they are equal.
- *
- * @param string
- * the string to compare.
- * @return {@code true} if the specified string is equal to this string,
- * {@code false} otherwise.
- */
- @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
- public boolean equalsIgnoreCase(String string) {
- if (string == this) {
- return true;
- }
- if (string == null || count != string.count) {
- return false;
- }
- int o1 = offset, o2 = string.offset;
- int end = offset + count;
- char[] target = string.value;
- while (o1 < end) {
- char c1 = value[o1++];
- char c2 = target[o2++];
- if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Mangles this string into a byte array by stripping the high order bits from
- * each character. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
- *
- * @param start
- * the starting offset of characters to copy.
- * @param end
- * the ending offset of characters to copy.
- * @param data
- * the destination byte array.
- * @param index
- * the starting offset in the destination byte array.
- * @throws NullPointerException
- * if {@code data} is {@code null}.
- * @throws IndexOutOfBoundsException
- * if {@code start < 0}, {@code end > length()}, {@code index <
- * 0} or {@code end - start > data.length - index}.
- * @deprecated Use {@link #getBytes()} or {@link #getBytes(String)} instead.
- */
- @Deprecated
- public void getBytes(int start, int end, byte[] data, int index) {
- // Note: last character not copied!
- if (start >= 0 && start <= end && end <= count) {
- end += offset;
- try {
- for (int i = offset + start; i < end; i++) {
- data[index++] = (byte) value[i];
- }
- } catch (ArrayIndexOutOfBoundsException ignored) {
- throw failedBoundsCheck(data.length, index, end - start);
- }
- } else {
- throw startEndAndLength(start, end);
- }
- }
-
- /**
- * Returns a new byte array containing the characters of this string encoded using the
- * system's {@link java.nio.charset.Charset#defaultCharset default charset}.
- *
- * <p>The behavior when this string cannot be represented in the system's default charset
- * is unspecified. In practice, when the default charset is UTF-8 (as it is on Android),
- * all strings can be encoded.
- */
- public byte[] getBytes() {
- return getBytes(Charset.defaultCharset());
- }
-
- /**
- * Returns a new byte array containing the characters of this string encoded using the
- * named charset.
- *
- * <p>The behavior when this string cannot be represented in the named charset
- * is unspecified. Use {@link java.nio.charset.CharsetEncoder} for more control.
- *
- * @throws UnsupportedEncodingException if the charset is not supported
- */
- public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
- return getBytes(Charset.forNameUEE(charsetName));
- }
-
- /**
- * Returns a new byte array containing the characters of this string encoded using the
- * given charset.
- *
- * <p>The behavior when this string cannot be represented in the given charset
- * is to replace malformed input and unmappable characters with the charset's default
- * replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control.
- *
- * @since 1.6
- */
- public byte[] getBytes(Charset charset) {
- String canonicalCharsetName = charset.name();
- if (canonicalCharsetName.equals("UTF-8")) {
- return Charsets.toUtf8Bytes(value, offset, count);
- } else if (canonicalCharsetName.equals("ISO-8859-1")) {
- return Charsets.toIsoLatin1Bytes(value, offset, count);
- } else if (canonicalCharsetName.equals("US-ASCII")) {
- return Charsets.toAsciiBytes(value, offset, count);
- } else if (canonicalCharsetName.equals("UTF-16BE")) {
- return Charsets.toBigEndianUtf16Bytes(value, offset, count);
- } else {
- CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count);
- ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer());
- byte[] bytes = new byte[buffer.limit()];
- buffer.get(bytes);
- return bytes;
- }
- }
-
- /**
- * Copies the specified characters in this string to the character array
- * starting at the specified offset in the character array.
- *
- * @param start
- * the starting offset of characters to copy.
- * @param end
- * the ending offset of characters to copy.
- * @param buffer
- * the destination character array.
- * @param index
- * the starting offset in the character array.
- * @throws NullPointerException
- * if {@code buffer} is {@code null}.
- * @throws IndexOutOfBoundsException
- * if {@code start < 0}, {@code end > length()}, {@code start >
- * end}, {@code index < 0}, {@code end - start > buffer.length -
- * index}
- */
- public void getChars(int start, int end, char[] buffer, int index) {
- // Note: last character not copied!
- if (start >= 0 && start <= end && end <= count) {
- System.arraycopy(value, start + offset, buffer, index, end - start);
- } else {
- // We throw StringIndexOutOfBoundsException rather than System.arraycopy's AIOOBE.
- throw startEndAndLength(start, end);
- }
- }
-
- /**
- * Version of getChars without bounds checks, for use by other classes
- * within the java.lang package only. The caller is responsible for
- * ensuring that start >= 0 && start <= end && end <= count.
- */
- void _getChars(int start, int end, char[] buffer, int index) {
- // NOTE last character not copied!
- System.arraycopy(value, start + offset, buffer, index, end - start);
- }
-
- @Override public int hashCode() {
- int hash = hashCode;
- if (hash == 0) {
- if (count == 0) {
- return 0;
- }
- final int end = count + offset;
- final char[] chars = value;
- for (int i = offset; i < end; ++i) {
- hash = 31*hash + chars[i];
- }
- hashCode = hash;
- }
- return hash;
- }
-
- /**
- * Searches in this string for the first index of the specified character.
- * The search for the character starts at the beginning and moves towards
- * the end of this string.
- *
- * @param c
- * the character to find.
- * @return the index in this string of the specified character, -1 if the
- * character isn't found.
- */
- public int indexOf(int c) {
- // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep.
- if (c > 0xffff) {
- return indexOfSupplementary(c, 0);
- }
- return fastIndexOf(c, 0);
- }
-
- /**
- * Searches in this string for the index of the specified character. The
- * search for the character starts at the specified offset and moves towards
- * the end of this string.
- *
- * @param c
- * the character to find.
- * @param start
- * the starting offset.
- * @return the index in this string of the specified character, -1 if the
- * character isn't found.
- */
- public int indexOf(int c, int start) {
- if (c > 0xffff) {
- return indexOfSupplementary(c, start);
- }
- return fastIndexOf(c, start);
- }
-
- private native int fastIndexOf(int c, int start);
-
- private int indexOfSupplementary(int c, int start) {
- if (!Character.isSupplementaryCodePoint(c)) {
- return -1;
- }
- char[] chars = Character.toChars(c);
- String needle = new String(0, chars.length, chars);
- return indexOf(needle, start);
- }
-
- /**
- * Searches in this string for the first index of the specified string. The
- * search for the string starts at the beginning and moves towards the end
- * of this string.
- *
- * @param string
- * the string to find.
- * @return the index of the first character of the specified string in this
- * string, -1 if the specified string is not a substring.
- * @throws NullPointerException
- * if {@code string} is {@code null}.
- */
- public int indexOf(String string) {
- int start = 0;
- int subCount = string.count;
- int _count = count;
- if (subCount > 0) {
- if (subCount > _count) {
- return -1;
- }
- char[] target = string.value;
- int subOffset = string.offset;
- char firstChar = target[subOffset];
- int end = subOffset + subCount;
- while (true) {
- int i = indexOf(firstChar, start);
- if (i == -1 || subCount + i > _count) {
- return -1; // handles subCount > count || start >= count
- }
- int o1 = offset + i, o2 = subOffset;
- char[] _value = value;
- while (++o2 < end && _value[++o1] == target[o2]) {
- // Intentionally empty
- }
- if (o2 == end) {
- return i;
- }
- start = i + 1;
- }
- }
- return start < _count ? start : _count;
- }
-
- /**
- * Searches in this string for the index of the specified string. The search
- * for the string starts at the specified offset and moves towards the end
- * of this string.
- *
- * @param subString
- * the string to find.
- * @param start
- * the starting offset.
- * @return the index of the first character of the specified string in this
- * string, -1 if the specified string is not a substring.
- * @throws NullPointerException
- * if {@code subString} is {@code null}.
- */
- public int indexOf(String subString, int start) {
- if (start < 0) {
- start = 0;
- }
- int subCount = subString.count;
- int _count = count;
- if (subCount > 0) {
- if (subCount + start > _count) {
- return -1;
- }
- char[] target = subString.value;
- int subOffset = subString.offset;
- char firstChar = target[subOffset];
- int end = subOffset + subCount;
- while (true) {
- int i = indexOf(firstChar, start);
- if (i == -1 || subCount + i > _count) {
- return -1; // handles subCount > count || start >= count
- }
- int o1 = offset + i, o2 = subOffset;
- char[] _value = value;
- while (++o2 < end && _value[++o1] == target[o2]) {
- // Intentionally empty
- }
- if (o2 == end) {
- return i;
- }
- start = i + 1;
- }
- }
- return start < _count ? start : _count;
- }
-
- /**
- * Returns an interned string equal to this string. The VM maintains an internal set of
- * unique strings. All string literals found in loaded classes'
- * constant pools are automatically interned. Manually-interned strings are only weakly
- * referenced, so calling {@code intern} won't lead to unwanted retention.
- *
- * <p>Interning is typically used because it guarantees that for interned strings
- * {@code a} and {@code b}, {@code a.equals(b)} can be simplified to
- * {@code a == b}. (This is not true of non-interned strings.)
- *
- * <p>Many applications find it simpler and more convenient to use an explicit
- * {@link java.util.HashMap} to implement their own pools.
- */
- public native String intern();
-
- /**
- * Returns true if the length of this string is 0.
- *
- * @since 1.6
- */
- public boolean isEmpty() {
- return count == 0;
- }
-
- /**
- * Returns the last index of the code point {@code c}, or -1.
- * The search for the character starts at the end and moves towards the
- * beginning of this string.
- */
- public int lastIndexOf(int c) {
- if (c > 0xffff) {
- return lastIndexOfSupplementary(c, Integer.MAX_VALUE);
- }
- int _count = count;
- int _offset = offset;
- char[] _value = value;
- for (int i = _offset + _count - 1; i >= _offset; --i) {
- if (_value[i] == c) {
- return i - _offset;
- }
- }
- return -1;
- }
-
- /**
- * Returns the last index of the code point {@code c}, or -1.
- * The search for the character starts at offset {@code start} and moves towards
- * the beginning of this string.
- */
- public int lastIndexOf(int c, int start) {
- if (c > 0xffff) {
- return lastIndexOfSupplementary(c, start);
- }
- int _count = count;
- int _offset = offset;
- char[] _value = value;
- if (start >= 0) {
- if (start >= _count) {
- start = _count - 1;
- }
- for (int i = _offset + start; i >= _offset; --i) {
- if (_value[i] == c) {
- return i - _offset;
- }
- }
- }
- return -1;
- }
-
- private int lastIndexOfSupplementary(int c, int start) {
- if (!Character.isSupplementaryCodePoint(c)) {
- return -1;
- }
- char[] chars = Character.toChars(c);
- String needle = new String(0, chars.length, chars);
- return lastIndexOf(needle, start);
- }
-
- /**
- * Searches in this string for the last index of the specified string. The
- * search for the string starts at the end and moves towards the beginning
- * of this string.
- *
- * @param string
- * the string to find.
- * @return the index of the first character of the specified string in this
- * string, -1 if the specified string is not a substring.
- * @throws NullPointerException
- * if {@code string} is {@code null}.
- */
- public int lastIndexOf(String string) {
- // Use count instead of count - 1 so lastIndexOf("") returns count
- return lastIndexOf(string, count);
- }
-
- /**
- * Searches in this string for the index of the specified string. The search
- * for the string starts at the specified offset and moves towards the
- * beginning of this string.
- *
- * @param subString
- * the string to find.
- * @param start
- * the starting offset.
- * @return the index of the first character of the specified string in this
- * string , -1 if the specified string is not a substring.
- * @throws NullPointerException
- * if {@code subString} is {@code null}.
- */
- public int lastIndexOf(String subString, int start) {
- int subCount = subString.count;
- if (subCount <= count && start >= 0) {
- if (subCount > 0) {
- if (start > count - subCount) {
- start = count - subCount;
- }
- // count and subCount are both >= 1
- char[] target = subString.value;
- int subOffset = subString.offset;
- char firstChar = target[subOffset];
- int end = subOffset + subCount;
- while (true) {
- int i = lastIndexOf(firstChar, start);
- if (i == -1) {
- return -1;
- }
- int o1 = offset + i, o2 = subOffset;
- while (++o2 < end && value[++o1] == target[o2]) {
- // Intentionally empty
- }
- if (o2 == end) {
- return i;
- }
- start = i - 1;
- }
- }
- return start < count ? start : count;
- }
- return -1;
- }
-
- /**
- * Returns the number of characters in this string.
- */
- public int length() {
- return count;
- }
-
- /**
- * Compares the specified string to this string and compares the specified
- * range of characters to determine if they are the same.
- *
- * @param thisStart
- * the starting offset in this string.
- * @param string
- * the string to compare.
- * @param start
- * the starting offset in the specified string.
- * @param length
- * the number of characters to compare.
- * @return {@code true} if the ranges of characters are equal, {@code false}
- * otherwise
- * @throws NullPointerException
- * if {@code string} is {@code null}.
- */
- public boolean regionMatches(int thisStart, String string, int start, int length) {
- if (string == null) {
- throw new NullPointerException("string == null");
- }
- if (start < 0 || string.count - start < length) {
- return false;
- }
- if (thisStart < 0 || count - thisStart < length) {
- return false;
- }
- if (length <= 0) {
- return true;
- }
- int o1 = offset + thisStart, o2 = string.offset + start;
- char[] value1 = value;
- char[] value2 = string.value;
- for (int i = 0; i < length; ++i) {
- if (value1[o1 + i] != value2[o2 + i]) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Compares the specified string to this string and compares the specified
- * range of characters to determine if they are the same. When ignoreCase is
- * true, the case of the characters is ignored during the comparison.
- *
- * @param ignoreCase
- * specifies if case should be ignored.
- * @param thisStart
- * the starting offset in this string.
- * @param string
- * the string to compare.
- * @param start
- * the starting offset in the specified string.
- * @param length
- * the number of characters to compare.
- * @return {@code true} if the ranges of characters are equal, {@code false}
- * otherwise.
- * @throws NullPointerException
- * if {@code string} is {@code null}.
- */
- public boolean regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length) {
- if (!ignoreCase) {
- return regionMatches(thisStart, string, start, length);
- }
- if (string == null) {
- throw new NullPointerException("string == null");
- }
- if (thisStart < 0 || length > count - thisStart) {
- return false;
- }
- if (start < 0 || length > string.count - start) {
- return false;
- }
- thisStart += offset;
- start += string.offset;
- int end = thisStart + length;
- char[] target = string.value;
- while (thisStart < end) {
- char c1 = value[thisStart++];
- char c2 = target[start++];
- if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Copies this string replacing occurrences of the specified character with
- * another character.
- *
- * @param oldChar
- * the character to replace.
- * @param newChar
- * the replacement character.
- * @return a new string with occurrences of oldChar replaced by newChar.
- */
- public String replace(char oldChar, char newChar) {
- char[] buffer = value;
- int _offset = offset;
- int _count = count;
-
- int idx = _offset;
- int last = _offset + _count;
- boolean copied = false;
- while (idx < last) {
- if (buffer[idx] == oldChar) {
- if (!copied) {
- char[] newBuffer = new char[_count];
- System.arraycopy(buffer, _offset, newBuffer, 0, _count);
- buffer = newBuffer;
- idx -= _offset;
- last -= _offset;
- copied = true;
- }
- buffer[idx] = newChar;
- }
- idx++;
- }
-
- return copied ? new String(0, count, buffer) : this;
- }
-
- /**
- * Copies this string replacing occurrences of the specified target sequence
- * with another sequence. The string is processed from the beginning to the
- * end.
- *
- * @param target
- * the sequence to replace.
- * @param replacement
- * the replacement sequence.
- * @return the resulting string.
- * @throws NullPointerException
- * if {@code target} or {@code replacement} is {@code null}.
- */
- public String replace(CharSequence target, CharSequence replacement) {
- if (target == null) {
- throw new NullPointerException("target == null");
- }
- if (replacement == null) {
- throw new NullPointerException("replacement == null");
- }
-
- String targetString = target.toString();
- int matchStart = indexOf(targetString, 0);
- if (matchStart == -1) {
- // If there's nothing to replace, return the original string untouched.
- return this;
- }
-
- String replacementString = replacement.toString();
-
- // The empty target matches at the start and end and between each character.
- int targetLength = targetString.length();
- if (targetLength == 0) {
- // The result contains the original 'count' characters, a copy of the
- // replacement string before every one of those characters, and a final
- // copy of the replacement string at the end.
- int resultLength = count + (count + 1) * replacementString.length();
- StringBuilder result = new StringBuilder(resultLength);
- result.append(replacementString);
- int end = offset + count;
- for (int i = offset; i != end; ++i) {
- result.append(value[i]);
- result.append(replacementString);
- }
- return result.toString();
- }
-
- StringBuilder result = new StringBuilder(count);
- int searchStart = 0;
- do {
- // Copy characters before the match...
- result.append(value, offset + searchStart, matchStart - searchStart);
- // Insert the replacement...
- result.append(replacementString);
- // And skip over the match...
- searchStart = matchStart + targetLength;
- } while ((matchStart = indexOf(targetString, searchStart)) != -1);
- // Copy any trailing chars...
- result.append(value, offset + searchStart, count - searchStart);
- return result.toString();
- }
-
- /**
- * Compares the specified string to this string to determine if the
- * specified string is a prefix.
- *
- * @param prefix
- * the string to look for.
- * @return {@code true} if the specified string is a prefix of this string,
- * {@code false} otherwise
- * @throws NullPointerException
- * if {@code prefix} is {@code null}.
- */
- public boolean startsWith(String prefix) {
- return startsWith(prefix, 0);
- }
-
- /**
- * Compares the specified string to this string, starting at the specified
- * offset, to determine if the specified string is a prefix.
- *
- * @param prefix
- * the string to look for.
- * @param start
- * the starting offset.
- * @return {@code true} if the specified string occurs in this string at the
- * specified offset, {@code false} otherwise.
- * @throws NullPointerException
- * if {@code prefix} is {@code null}.
- */
- public boolean startsWith(String prefix, int start) {
- return regionMatches(start, prefix, 0, prefix.count);
- }
-
- /**
- * Returns a string containing a suffix of this string. The returned string
- * shares this string's <a href="#backing_array">backing array</a>.
- *
- * @param start
- * the offset of the first character.
- * @return a new string containing the characters from start to the end of
- * the string.
- * @throws IndexOutOfBoundsException
- * if {@code start < 0} or {@code start > length()}.
- */
- public String substring(int start) {
- if (start == 0) {
- return this;
- }
- if (start >= 0 && start <= count) {
- return new String(offset + start, count - start, value);
- }
- throw indexAndLength(start);
- }
-
- /**
- * Returns a string containing a subsequence of characters from this string.
- * The returned string shares this string's <a href="#backing_array">backing
- * array</a>.
- *
- * @param start
- * the offset of the first character.
- * @param end
- * the offset one past the last character.
- * @return a new string containing the characters from start to end - 1
- * @throws IndexOutOfBoundsException
- * if {@code start < 0}, {@code start > end} or {@code end >
- * length()}.
- */
- public String substring(int start, int end) {
- if (start == 0 && end == count) {
- return this;
- }
- // NOTE last character not copied!
- // Fast range check.
- if (start >= 0 && start <= end && end <= count) {
- return new String(offset + start, end - start, value);
- }
- throw startEndAndLength(start, end);
- }
-
- /**
- * Returns a new {@code char} array containing a copy of the characters in this string.
- * This is expensive and rarely useful. If you just want to iterate over the characters in
- * the string, use {@link #charAt} instead.
- */
- public char[] toCharArray() {
- char[] buffer = new char[count];
- System.arraycopy(value, offset, buffer, 0, count);
- return buffer;
- }
-
- /**
- * Converts this string to lower case, using the rules of the user's default locale.
- * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
- *
- * @return a new lower case string, or {@code this} if it's already all lower case.
- */
- public String toLowerCase() {
- return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count);
- }
-
- /**
- * Converts this string to lower case, using the rules of {@code locale}.
- *
- * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
- * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
- * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
- * correct case mapping of Greek characters: any locale will do.
- *
- * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
- * for full details of context- and language-specific special cases.
- *
- * @return a new lower case string, or {@code this} if it's already all lower case.
- */
- public String toLowerCase(Locale locale) {
- return CaseMapper.toLowerCase(locale, this, value, offset, count);
- }
-
- /**
- * Returns this string.
- */
- @Override
- public String toString() {
- return this;
- }
-
- /**
- * Converts this this string to upper case, using the rules of the user's default locale.
- * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
- *
- * @return a new upper case string, or {@code this} if it's already all upper case.
- */
- public String toUpperCase() {
- return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count);
- }
-
- /**
- * Converts this this string to upper case, using the rules of {@code locale}.
- *
- * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
- * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
- * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
- * correct case mapping of Greek characters: any locale will do.
- *
- * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
- * for full details of context- and language-specific special cases.
- *
- * @return a new upper case string, or {@code this} if it's already all upper case.
- */
- public String toUpperCase(Locale locale) {
- return CaseMapper.toUpperCase(locale, this, value, offset, count);
- }
-
- /**
- * Copies this string removing white space characters from the beginning and
- * end of the string.
- *
- * @return a new string with characters <code><= \\u0020</code> removed from
- * the beginning and the end.
- */
- public String trim() {
- int start = offset, last = offset + count - 1;
- int end = last;
- while ((start <= end) && (value[start] <= ' ')) {
- start++;
- }
- while ((end >= start) && (value[end] <= ' ')) {
- end--;
- }
- if (start == offset && end == last) {
- return this;
- }
- return new String(start, end - start + 1, value);
- }
-
- /**
- * Creates a new string containing the characters in the specified character
- * array. Modifying the character array after creating the string has no
- * effect on the string.
- *
- * @param data
- * the array of characters.
- * @return the new string.
- * @throws NullPointerException
- * if {@code data} is {@code null}.
- */
- public static String valueOf(char[] data) {
- return new String(data, 0, data.length);
- }
-
- /**
- * Creates a new string containing the specified characters in the character
- * array. Modifying the character array after creating the string has no
- * effect on the string.
- *
- * @param data
- * the array of characters.
- * @param start
- * the starting offset in the character array.
- * @param length
- * the number of characters to use.
- * @return the new string.
- * @throws IndexOutOfBoundsException
- * if {@code length < 0}, {@code start < 0} or {@code start +
- * length > data.length}
- * @throws NullPointerException
- * if {@code data} is {@code null}.
- */
- public static String valueOf(char[] data, int start, int length) {
- return new String(data, start, length);
- }
-
- /**
- * Converts the specified character to its string representation.
- *
- * @param value
- * the character.
- * @return the character converted to a string.
- */
- public static String valueOf(char value) {
- String s;
- if (value < 128) {
- s = new String(value, 1, ASCII);
- } else {
- s = new String(0, 1, new char[] { value });
- }
- s.hashCode = value;
- return s;
- }
-
- /**
- * Converts the specified double to its string representation.
- *
- * @param value
- * the double.
- * @return the double converted to a string.
- */
- public static String valueOf(double value) {
- return Double.toString(value);
- }
-
- /**
- * Converts the specified float to its string representation.
- *
- * @param value
- * the float.
- * @return the float converted to a string.
- */
- public static String valueOf(float value) {
- return Float.toString(value);
- }
-
- /**
- * Converts the specified integer to its string representation.
- *
- * @param value
- * the integer.
- * @return the integer converted to a string.
- */
- public static String valueOf(int value) {
- return Integer.toString(value);
- }
-
- /**
- * Converts the specified long to its string representation.
- *
- * @param value
- * the long.
- * @return the long converted to a string.
- */
- public static String valueOf(long value) {
- return Long.toString(value);
- }
-
- /**
- * Converts the specified object to its string representation. If the object
- * is null return the string {@code "null"}, otherwise use {@code
- * toString()} to get the string representation.
- *
- * @param value
- * the object.
- * @return the object converted to a string, or the string {@code "null"}.
- */
- public static String valueOf(Object value) {
- return value != null ? value.toString() : "null";
- }
-
- /**
- * Converts the specified boolean to its string representation. When the
- * boolean is {@code true} return {@code "true"}, otherwise return {@code
- * "false"}.
- *
- * @param value
- * the boolean.
- * @return the boolean converted to a string.
- */
- public static String valueOf(boolean value) {
- return value ? "true" : "false";
- }
-
- /**
- * Returns whether the characters in the StringBuffer {@code strbuf} are the
- * same as those in this string.
- *
- * @param strbuf
- * the StringBuffer to compare this string to.
- * @return {@code true} if the characters in {@code strbuf} are identical to
- * those in this string. If they are not, {@code false} will be
- * returned.
- * @throws NullPointerException
- * if {@code strbuf} is {@code null}.
- * @since 1.4
- */
- public boolean contentEquals(StringBuffer strbuf) {
- synchronized (strbuf) {
- int size = strbuf.length();
- if (count != size) {
- return false;
- }
- return regionMatches(0, new String(0, size, strbuf.getValue()), 0,
- size);
- }
- }
-
- /**
- * Compares a {@code CharSequence} to this {@code String} to determine if
- * their contents are equal.
- *
- * @param cs
- * the character sequence to compare to.
- * @return {@code true} if equal, otherwise {@code false}
- * @since 1.5
- */
- public boolean contentEquals(CharSequence cs) {
- if (cs == null) {
- throw new NullPointerException("cs == null");
- }
-
- int len = cs.length();
-
- if (len != count) {
- return false;
- }
-
- if (len == 0 && count == 0) {
- return true; // since both are empty strings
- }
-
- return regionMatches(0, cs.toString(), 0, len);
- }
-
- /**
- * Tests whether this string matches the given {@code regularExpression}. This method returns
- * true only if the regular expression matches the <i>entire</i> input string. A common mistake is
- * to assume that this method behaves like {@link #contains}; if you want to match anywhere
- * within the input string, you need to add {@code .*} to the beginning and end of your
- * regular expression. See {@link Pattern#matches}.
- *
- * <p>If the same regular expression is to be used for multiple operations, it may be more
- * efficient to reuse a compiled {@code Pattern}.
- *
- * @throws PatternSyntaxException
- * if the syntax of the supplied regular expression is not
- * valid.
- * @throws NullPointerException if {@code regularExpression == null}
- * @since 1.4
- */
- public boolean matches(String regularExpression) {
- return Pattern.matches(regularExpression, this);
- }
-
- /**
- * Replaces all matches for {@code regularExpression} within this string with the given
- * {@code replacement}.
- * See {@link Pattern} for regular expression syntax.
- *
- * <p>If the same regular expression is to be used for multiple operations, it may be more
- * efficient to reuse a compiled {@code Pattern}.
- *
- * @throws PatternSyntaxException
- * if the syntax of the supplied regular expression is not
- * valid.
- * @throws NullPointerException if {@code regularExpression == null}
- * @see Pattern
- * @since 1.4
- */
- public String replaceAll(String regularExpression, String replacement) {
- return Pattern.compile(regularExpression).matcher(this).replaceAll(replacement);
- }
-
- /**
- * Replaces the first match for {@code regularExpression} within this string with the given
- * {@code replacement}.
- * See {@link Pattern} for regular expression syntax.
- *
- * <p>If the same regular expression is to be used for multiple operations, it may be more
- * efficient to reuse a compiled {@code Pattern}.
- *
- * @throws PatternSyntaxException
- * if the syntax of the supplied regular expression is not
- * valid.
- * @throws NullPointerException if {@code regularExpression == null}
- * @see Pattern
- * @since 1.4
- */
- public String replaceFirst(String regularExpression, String replacement) {
- return Pattern.compile(regularExpression).matcher(this).replaceFirst(replacement);
- }
-
- /**
- * Splits this string using the supplied {@code regularExpression}.
- * Equivalent to {@code split(regularExpression, 0)}.
- * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
- * See {@link Pattern} for regular expression syntax.
- *
- * <p>If the same regular expression is to be used for multiple operations, it may be more
- * efficient to reuse a compiled {@code Pattern}.
- *
- * @throws NullPointerException if {@code regularExpression == null}
- * @throws PatternSyntaxException
- * if the syntax of the supplied regular expression is not
- * valid.
- * @see Pattern
- * @since 1.4
- */
- public String[] split(String regularExpression) {
- return split(regularExpression, 0);
- }
-
- /**
- * Splits this string using the supplied {@code regularExpression}.
- * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
- * See {@link Pattern} for regular expression syntax.
- *
- * <p>If the same regular expression is to be used for multiple operations, it may be more
- * efficient to reuse a compiled {@code Pattern}.
- *
- * @throws NullPointerException if {@code regularExpression == null}
- * @throws PatternSyntaxException
- * if the syntax of the supplied regular expression is not
- * valid.
- * @since 1.4
- */
- public String[] split(String regularExpression, int limit) {
- String[] result = java.util.regex.Splitter.fastSplit(regularExpression, this, limit);
- return result != null ? result : Pattern.compile(regularExpression).split(this, limit);
- }
-
- /**
- * Has the same result as the substring function, but is present so that
- * string may implement the CharSequence interface.
- *
- * @param start
- * the offset the first character.
- * @param end
- * the offset of one past the last character to include.
- * @return the subsequence requested.
- * @throws IndexOutOfBoundsException
- * if {@code start < 0}, {@code end < 0}, {@code start > end} or
- * {@code end > length()}.
- * @see java.lang.CharSequence#subSequence(int, int)
- * @since 1.4
- */
- public CharSequence subSequence(int start, int end) {
- return substring(start, end);
- }
-
- /**
- * Returns the Unicode code point at the given {@code index}.
- *
- * @throws IndexOutOfBoundsException if {@code index < 0 || index >= length()}
- * @see Character#codePointAt(char[], int, int)
- * @since 1.5
- */
- public int codePointAt(int index) {
- if (index < 0 || index >= count) {
- throw indexAndLength(index);
- }
- return Character.codePointAt(value, offset + index, offset + count);
- }
-
- /**
- * Returns the Unicode code point that precedes the given {@code index}.
- *
- * @throws IndexOutOfBoundsException if {@code index < 1 || index > length()}
- * @see Character#codePointBefore(char[], int, int)
- * @since 1.5
- */
- public int codePointBefore(int index) {
- if (index < 1 || index > count) {
- throw indexAndLength(index);
- }
- return Character.codePointBefore(value, offset + index, offset);
- }
-
- /**
- * Calculates the number of Unicode code points between {@code start}
- * and {@code end}.
- *
- * @param start
- * the inclusive beginning index of the subsequence.
- * @param end
- * the exclusive end index of the subsequence.
- * @return the number of Unicode code points in the subsequence.
- * @throws IndexOutOfBoundsException
- * if {@code start < 0 || end > length() || start > end}
- * @see Character#codePointCount(CharSequence, int, int)
- * @since 1.5
- */
- public int codePointCount(int start, int end) {
- if (start < 0 || end > count || start > end) {
- throw startEndAndLength(start, end);
- }
- return Character.codePointCount(value, offset + start, end - start);
- }
-
- /**
- * Determines if this {@code String} contains the sequence of characters in
- * the {@code CharSequence} passed.
- *
- * @param cs
- * the character sequence to search for.
- * @return {@code true} if the sequence of characters are contained in this
- * string, otherwise {@code false}.
- * @since 1.5
- */
- public boolean contains(CharSequence cs) {
- if (cs == null) {
- throw new NullPointerException("cs == null");
- }
- return indexOf(cs.toString()) >= 0;
- }
-
- /**
- * Returns the index within this object that is offset from {@code index} by
- * {@code codePointOffset} code points.
- *
- * @param index
- * the index within this object to calculate the offset from.
- * @param codePointOffset
- * the number of code points to count.
- * @return the index within this object that is the offset.
- * @throws IndexOutOfBoundsException
- * if {@code index} is negative or greater than {@code length()}
- * or if there aren't enough code points before or after {@code
- * index} to match {@code codePointOffset}.
- * @since 1.5
- */
- public int offsetByCodePoints(int index, int codePointOffset) {
- int s = index + offset;
- int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset);
- return r - offset;
- }
-
- /**
- * Returns a localized formatted string, using the supplied format and arguments,
- * using the user's default locale.
- *
- * <p>If you're formatting a string other than for human
- * consumption, you should use the {@code format(Locale, String, Object...)}
- * overload and supply {@code Locale.US}. See
- * "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
- *
- * @param format the format string (see {@link java.util.Formatter#format})
- * @param args
- * the list of arguments passed to the formatter. If there are
- * more arguments than required by {@code format},
- * additional arguments are ignored.
- * @return the formatted string.
- * @throws NullPointerException if {@code format == null}
- * @throws java.util.IllegalFormatException
- * if the format is invalid.
- * @since 1.5
- */
- public static String format(String format, Object... args) {
- return format(Locale.getDefault(), format, args);
- }
-
- /**
- * Returns a formatted string, using the supplied format and arguments,
- * localized to the given locale.
- *
- * @param locale
- * the locale to apply; {@code null} value means no localization.
- * @param format the format string (see {@link java.util.Formatter#format})
- * @param args
- * the list of arguments passed to the formatter. If there are
- * more arguments than required by {@code format},
- * additional arguments are ignored.
- * @return the formatted string.
- * @throws NullPointerException if {@code format == null}
- * @throws java.util.IllegalFormatException
- * if the format is invalid.
- * @since 1.5
- */
- public static String format(Locale locale, String format, Object... args) {
- if (format == null) {
- throw new NullPointerException("format == null");
- }
- int bufferSize = format.length() + (args == null ? 0 : args.length * 10);
- Formatter f = new Formatter(new StringBuilder(bufferSize), locale);
- return f.format(format, args).toString();
- }
-
- /*
- * An implementation of a String.indexOf that is supposed to perform
- * substantially better than the default algorithm if the "needle" (the
- * subString being searched for) is a constant string.
- *
- * For example, a JIT, upon encountering a call to String.indexOf(String),
- * where the needle is a constant string, may compute the values cache, md2
- * and lastChar, and change the call to the following method.
- */
- @FindBugsSuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD")
- @SuppressWarnings("unused")
- private static int indexOf(String haystackString, String needleString,
- int cache, int md2, char lastChar) {
- char[] haystack = haystackString.value;
- int haystackOffset = haystackString.offset;
- int haystackLength = haystackString.count;
- char[] needle = needleString.value;
- int needleOffset = needleString.offset;
- int needleLength = needleString.count;
- int needleLengthMinus1 = needleLength - 1;
- int haystackEnd = haystackOffset + haystackLength;
- outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) {
- if (lastChar == haystack[i]) {
- for (int j = 0; j < needleLengthMinus1; ++j) {
- if (needle[j + needleOffset] != haystack[i + j
- - needleLengthMinus1]) {
- int skip = 1;
- if ((cache & (1 << haystack[i])) == 0) {
- skip += j;
- }
- i += Math.max(md2, skip);
- continue outer_loop;
- }
- }
- return i - needleLengthMinus1 - haystackOffset;
- }
-
- if ((cache & (1 << haystack[i])) == 0) {
- i += needleLengthMinus1;
- }
- i++;
- }
- return -1;
- }
-}
diff --git a/libdvm/src/main/java/java/lang/Thread.java b/libdvm/src/main/java/java/lang/Thread.java
deleted file mode 100644
index ee4bdbe..0000000
--- a/libdvm/src/main/java/java/lang/Thread.java
+++ /dev/null
@@ -1,1281 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import dalvik.system.VMStack;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import libcore.util.EmptyArray;
-
-/**
- * A {@code Thread} is a concurrent unit of execution. It has its own call stack
- * for methods being invoked, their arguments and local variables. Each application
- * has at least one thread running when it is started, the main thread, in the main
- * {@link ThreadGroup}. The runtime keeps its own threads in the system thread
- * group.
- *
- * <p>There are two ways to execute code in a new thread.
- * You can either subclass {@code Thread} and overriding its {@link #run()} method,
- * or construct a new {@code Thread} and pass a {@link Runnable} to the constructor.
- * In either case, the {@link #start()} method must be called to actually execute
- * the new {@code Thread}.
- *
- * <p>Each {@code Thread} has an integer priority that affect how the thread is
- * scheduled by the OS. A new thread inherits the priority of its parent.
- * A thread's priority can be set using the {@link #setPriority(int)} method.
- */
-public class Thread implements Runnable {
- private static final int NANOS_PER_MILLI = 1000000;
-
- /** Park states */
- private static class ParkState {
- /** park state indicating unparked */
- private static final int UNPARKED = 1;
-
- /** park state indicating preemptively unparked */
- private static final int PREEMPTIVELY_UNPARKED = 2;
-
- /** park state indicating parked */
- private static final int PARKED = 3;
- }
-
- /**
- * A representation of a thread's state. A given thread may only be in one
- * state at a time.
- */
- public enum State {
- /**
- * The thread has been created, but has never been started.
- */
- NEW,
- /**
- * The thread may be run.
- */
- RUNNABLE,
- /**
- * The thread is blocked and waiting for a lock.
- */
- BLOCKED,
- /**
- * The thread is waiting.
- */
- WAITING,
- /**
- * The thread is waiting for a specified amount of time.
- */
- TIMED_WAITING,
- /**
- * The thread has been terminated.
- */
- TERMINATED
- }
-
- /**
- * The maximum priority value allowed for a thread.
- * This corresponds to (but does not have the same value as)
- * {@code android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY}.
- */
- public static final int MAX_PRIORITY = 10;
-
- /**
- * The minimum priority value allowed for a thread.
- * This corresponds to (but does not have the same value as)
- * {@code android.os.Process.THREAD_PRIORITY_LOWEST}.
- */
- public static final int MIN_PRIORITY = 1;
-
- /**
- * The normal (default) priority value assigned to the main thread.
- * This corresponds to (but does not have the same value as)
- * {@code android.os.Process.THREAD_PRIORITY_DEFAULT}.
-
- */
- public static final int NORM_PRIORITY = 5;
-
- /* some of these are accessed directly by the VM; do not rename them */
- volatile VMThread vmThread;
- volatile ThreadGroup group;
- volatile boolean daemon;
- volatile String name;
- volatile int priority;
- volatile long stackSize;
- Runnable target;
- private static int count = 0;
-
- /**
- * Holds the thread's ID. We simply count upwards, so
- * each Thread has a unique ID.
- */
- private long id;
-
- /**
- * Normal thread local values.
- */
- ThreadLocal.Values localValues;
-
- /**
- * Inheritable thread local values.
- */
- ThreadLocal.Values inheritableValues;
-
- /** Callbacks to run on interruption. */
- private final List<Runnable> interruptActions = new ArrayList<Runnable>();
-
- /**
- * Holds the class loader for this Thread, in case there is one.
- */
- private ClassLoader contextClassLoader;
-
- /**
- * Holds the handler for uncaught exceptions in this Thread,
- * in case there is one.
- */
- private UncaughtExceptionHandler uncaughtHandler;
-
- /**
- * Holds the default handler for uncaught exceptions, in case there is one.
- */
- private static UncaughtExceptionHandler defaultUncaughtHandler;
-
- /**
- * Reflects whether this Thread has already been started. A Thread
- * can only be started once (no recycling). Also, we need it to deduce
- * the proper Thread status.
- */
- boolean hasBeenStarted = false;
-
- /** the park state of the thread */
- private int parkState = ParkState.UNPARKED;
-
- /** The synchronization object responsible for this thread parking. */
- private Object parkBlocker;
-
- /**
- * Constructs a new {@code Thread} with no {@code Runnable} object and a
- * newly generated name. The new {@code Thread} will belong to the same
- * {@code ThreadGroup} as the {@code Thread} calling this constructor.
- *
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- */
- public Thread() {
- create(null, null, null, 0);
- }
-
- /**
- * Constructs a new {@code Thread} with a {@code Runnable} object and a
- * newly generated name. The new {@code Thread} will belong to the same
- * {@code ThreadGroup} as the {@code Thread} calling this constructor.
- *
- * @param runnable
- * a {@code Runnable} whose method <code>run</code> will be
- * executed by the new {@code Thread}
- *
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- */
- public Thread(Runnable runnable) {
- create(null, runnable, null, 0);
- }
-
- /**
- * Constructs a new {@code Thread} with a {@code Runnable} object and name
- * provided. The new {@code Thread} will belong to the same {@code
- * ThreadGroup} as the {@code Thread} calling this constructor.
- *
- * @param runnable
- * a {@code Runnable} whose method <code>run</code> will be
- * executed by the new {@code Thread}
- * @param threadName
- * the name for the {@code Thread} being created
- *
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- */
- public Thread(Runnable runnable, String threadName) {
- if (threadName == null) {
- throw new NullPointerException("threadName == null");
- }
-
- create(null, runnable, threadName, 0);
- }
-
- /**
- * Constructs a new {@code Thread} with no {@code Runnable} object and the
- * name provided. The new {@code Thread} will belong to the same {@code
- * ThreadGroup} as the {@code Thread} calling this constructor.
- *
- * @param threadName
- * the name for the {@code Thread} being created
- *
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- *
- */
- public Thread(String threadName) {
- if (threadName == null) {
- throw new NullPointerException("threadName == null");
- }
-
- create(null, null, threadName, 0);
- }
-
- /**
- * Constructs a new {@code Thread} with a {@code Runnable} object and a
- * newly generated name. The new {@code Thread} will belong to the {@code
- * ThreadGroup} passed as parameter.
- *
- * @param group
- * {@code ThreadGroup} to which the new {@code Thread} will
- * belong
- * @param runnable
- * a {@code Runnable} whose method <code>run</code> will be
- * executed by the new {@code Thread}
- * @throws IllegalThreadStateException
- * if <code>group.destroy()</code> has already been done
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- */
- public Thread(ThreadGroup group, Runnable runnable) {
- create(group, runnable, null, 0);
- }
-
- /**
- * Constructs a new {@code Thread} with a {@code Runnable} object, the given
- * name and belonging to the {@code ThreadGroup} passed as parameter.
- *
- * @param group
- * ThreadGroup to which the new {@code Thread} will belong
- * @param runnable
- * a {@code Runnable} whose method <code>run</code> will be
- * executed by the new {@code Thread}
- * @param threadName
- * the name for the {@code Thread} being created
- * @throws IllegalThreadStateException
- * if <code>group.destroy()</code> has already been done
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- */
- public Thread(ThreadGroup group, Runnable runnable, String threadName) {
- if (threadName == null) {
- throw new NullPointerException("threadName == null");
- }
-
- create(group, runnable, threadName, 0);
- }
-
- /**
- * Constructs a new {@code Thread} with no {@code Runnable} object, the
- * given name and belonging to the {@code ThreadGroup} passed as parameter.
- *
- * @param group
- * {@code ThreadGroup} to which the new {@code Thread} will belong
- * @param threadName
- * the name for the {@code Thread} being created
- * @throws IllegalThreadStateException
- * if <code>group.destroy()</code> has already been done
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- */
- public Thread(ThreadGroup group, String threadName) {
- if (threadName == null) {
- throw new NullPointerException("threadName == null");
- }
-
- create(group, null, threadName, 0);
- }
-
- /**
- * Constructs a new {@code Thread} with a {@code Runnable} object, the given
- * name and belonging to the {@code ThreadGroup} passed as parameter.
- *
- * @param group
- * {@code ThreadGroup} to which the new {@code Thread} will
- * belong
- * @param runnable
- * a {@code Runnable} whose method <code>run</code> will be
- * executed by the new {@code Thread}
- * @param threadName
- * the name for the {@code Thread} being created
- * @param stackSize
- * a stack size for the new {@code Thread}. This has a highly
- * platform-dependent interpretation. It may even be ignored
- * completely.
- * @throws IllegalThreadStateException
- * if <code>group.destroy()</code> has already been done
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- */
- public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
- if (threadName == null) {
- throw new NullPointerException("threadName == null");
- }
- create(group, runnable, threadName, stackSize);
- }
-
- /**
- * Package-scope method invoked by Dalvik VM to create "internal"
- * threads or attach threads created externally.
- *
- * Don't call Thread.currentThread(), since there may not be such
- * a thing (e.g. for Main).
- */
- Thread(ThreadGroup group, String name, int priority, boolean daemon) {
- synchronized (Thread.class) {
- id = ++Thread.count;
- }
-
- if (name == null) {
- this.name = "Thread-" + id;
- } else {
- this.name = name;
- }
-
- if (group == null) {
- throw new InternalError("group not specified");
- }
-
- this.group = group;
-
- this.target = null;
- this.stackSize = 0;
- this.priority = priority;
- this.daemon = daemon;
-
- /* add ourselves to our ThreadGroup of choice */
- this.group.addThread(this);
- }
-
- /**
- * Initializes a new, existing Thread object with a runnable object,
- * the given name and belonging to the ThreadGroup passed as parameter.
- * This is the method that the several public constructors delegate their
- * work to.
- *
- * @param group ThreadGroup to which the new Thread will belong
- * @param runnable a java.lang.Runnable whose method <code>run</code> will
- * be executed by the new Thread
- * @param threadName Name for the Thread being created
- * @param stackSize Platform dependent stack size
- * @throws IllegalThreadStateException if <code>group.destroy()</code> has
- * already been done
- * @see java.lang.ThreadGroup
- * @see java.lang.Runnable
- */
- private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
- Thread currentThread = Thread.currentThread();
- if (group == null) {
- group = currentThread.getThreadGroup();
- }
-
- if (group.isDestroyed()) {
- throw new IllegalThreadStateException("Group already destroyed");
- }
-
- this.group = group;
-
- synchronized (Thread.class) {
- id = ++Thread.count;
- }
-
- if (threadName == null) {
- this.name = "Thread-" + id;
- } else {
- this.name = threadName;
- }
-
- this.target = runnable;
- this.stackSize = stackSize;
-
- this.priority = currentThread.getPriority();
-
- this.contextClassLoader = currentThread.contextClassLoader;
-
- // Transfer over InheritableThreadLocals.
- if (currentThread.inheritableValues != null) {
- inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
- }
-
- // add ourselves to our ThreadGroup of choice
- this.group.addThread(this);
- }
-
- /**
- * Returns the number of active {@code Thread}s in the running {@code
- * Thread}'s group and its subgroups.
- *
- * @return the number of {@code Thread}s
- */
- public static int activeCount() {
- return currentThread().getThreadGroup().activeCount();
- }
-
- /**
- * Does nothing.
- */
- public final void checkAccess() {
- }
-
- /**
- * Returns the number of stack frames in this thread.
- *
- * @return Number of stack frames
- * @deprecated The results of this call were never well defined. To make
- * things worse, it would depend on whether the Thread was
- * suspended or not, and suspend was deprecated too.
- */
- @Deprecated
- public int countStackFrames() {
- return getStackTrace().length;
- }
-
- /**
- * Returns the Thread of the caller, that is, the current Thread.
- *
- * @return the current Thread.
- */
- public static Thread currentThread() {
- return VMThread.currentThread();
- }
-
- /**
- * Throws {@code UnsupportedOperationException}.
- * @deprecated Not implemented.
- */
- @Deprecated
- public void destroy() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Prints to the standard error stream a text representation of the current
- * stack for this Thread.
- *
- * @see Throwable#printStackTrace()
- */
- public static void dumpStack() {
- new Throwable("stack dump").printStackTrace();
- }
-
- /**
- * Copies an array with all Threads which are in the same ThreadGroup as the
- * receiver - and subgroups - into the array <code>threads</code> passed as
- * parameter. If the array passed as parameter is too small no exception is
- * thrown - the extra elements are simply not copied.
- *
- * @param threads
- * array into which the Threads will be copied
- * @return How many Threads were copied over
- */
- public static int enumerate(Thread[] threads) {
- Thread thread = Thread.currentThread();
- return thread.getThreadGroup().enumerate(threads);
- }
-
- /**
- * Returns a map of all the currently live threads to their stack traces.
- */
- public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
- Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>();
-
- // Find out how many live threads we have. Allocate a bit more
- // space than needed, in case new ones are just being created.
- int count = ThreadGroup.mSystem.activeCount();
- Thread[] threads = new Thread[count + count / 2];
-
- // Enumerate the threads and collect the stacktraces.
- count = ThreadGroup.mSystem.enumerate(threads);
- for (int i = 0; i < count; i++) {
- map.put(threads[i], threads[i].getStackTrace());
- }
-
- return map;
- }
-
- /**
- * Returns the context ClassLoader for this Thread.
- *
- * @return ClassLoader The context ClassLoader
- * @see java.lang.ClassLoader
- * @see #getContextClassLoader()
- */
- public ClassLoader getContextClassLoader() {
- return contextClassLoader;
- }
-
- /**
- * Returns the default exception handler that's executed when uncaught
- * exception terminates a thread.
- *
- * @return an {@link UncaughtExceptionHandler} or <code>null</code> if
- * none exists.
- */
- public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
- return defaultUncaughtHandler;
- }
-
- /**
- * Returns the thread's identifier. The ID is a positive <code>long</code>
- * generated on thread creation, is unique to the thread, and doesn't change
- * during the lifetime of the thread; the ID may be reused after the thread
- * has been terminated.
- *
- * @return the thread's ID.
- */
- public long getId() {
- return id;
- }
-
- /**
- * Returns the name of the Thread.
- */
- public final String getName() {
- return name;
- }
-
- /**
- * Returns the priority of the Thread.
- */
- public final int getPriority() {
- return priority;
- }
-
- /**
- * Returns an array of {@link StackTraceElement} representing the current thread's stack.
- */
- public StackTraceElement[] getStackTrace() {
- StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
- return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT;
- }
-
- /**
- * Returns the current state of the Thread. This method is useful for
- * monitoring purposes.
- *
- * @return a {@link State} value.
- */
- public State getState() {
- // TODO This is ugly and should be implemented better.
- VMThread vmt = this.vmThread;
-
- // Make sure we have a valid reference to an object. If native code
- // deletes the reference we won't run into a null reference later.
- VMThread thread = vmThread;
- if (thread != null) {
- // If the Thread Object became invalid or was not yet started,
- // getStatus() will return -1.
- int state = thread.getStatus();
- if(state != -1) {
- return VMThread.STATE_MAP[state];
- }
- }
- return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW;
- }
-
- /**
- * Returns the ThreadGroup to which this Thread belongs.
- *
- * @return the Thread's ThreadGroup
- */
- public final ThreadGroup getThreadGroup() {
- // TODO This should actually be done at native termination.
- if (getState() == Thread.State.TERMINATED) {
- return null;
- } else {
- return group;
- }
- }
-
- /**
- * Returns the thread's uncaught exception handler. If not explicitly set,
- * then the ThreadGroup's handler is returned. If the thread is terminated,
- * then <code>null</code> is returned.
- *
- * @return an {@link UncaughtExceptionHandler} instance or {@code null}.
- */
- public UncaughtExceptionHandler getUncaughtExceptionHandler() {
- if (uncaughtHandler != null)
- return uncaughtHandler;
- else
- return group; // ThreadGroup is instance of UEH
- }
-
- /**
- * Posts an interrupt request to this {@code Thread}. The behavior depends on
- * the state of this {@code Thread}:
- * <ul>
- * <li>
- * {@code Thread}s blocked in one of {@code Object}'s {@code wait()} methods
- * or one of {@code Thread}'s {@code join()} or {@code sleep()} methods will
- * be woken up, their interrupt status will be cleared, and they receive an
- * {@link InterruptedException}.
- * <li>
- * {@code Thread}s blocked in an I/O operation of an
- * {@link java.nio.channels.InterruptibleChannel} will have their interrupt
- * status set and receive an
- * {@link java.nio.channels.ClosedByInterruptException}. Also, the channel
- * will be closed.
- * <li>
- * {@code Thread}s blocked in a {@link java.nio.channels.Selector} will have
- * their interrupt status set and return immediately. They don't receive an
- * exception in this case.
- * <ul>
- *
- * @see Thread#interrupted
- * @see Thread#isInterrupted
- */
- public void interrupt() {
- // Interrupt this thread before running actions so that other
- // threads that observe the interrupt as a result of an action
- // will see that this thread is in the interrupted state.
- VMThread vmt = this.vmThread;
- if (vmt != null) {
- vmt.interrupt();
- }
-
- synchronized (interruptActions) {
- for (int i = interruptActions.size() - 1; i >= 0; i--) {
- interruptActions.get(i).run();
- }
- }
- }
-
- /**
- * Returns a <code>boolean</code> indicating whether the current Thread (
- * <code>currentThread()</code>) has a pending interrupt request (<code>
- * true</code>) or not (<code>false</code>). It also has the side-effect of
- * clearing the flag.
- *
- * @return a <code>boolean</code> indicating the interrupt status
- * @see Thread#currentThread
- * @see Thread#interrupt
- * @see Thread#isInterrupted
- */
- public static boolean interrupted() {
- return VMThread.interrupted();
- }
-
- /**
- * Returns <code>true</code> if the receiver has already been started and
- * still runs code (hasn't died yet). Returns <code>false</code> either if
- * the receiver hasn't been started yet or if it has already started and run
- * to completion and died.
- *
- * @return a <code>boolean</code> indicating the liveness of the Thread
- * @see Thread#start
- */
- public final boolean isAlive() {
- return (vmThread != null);
- }
-
- /**
- * Tests whether this is a daemon thread.
- * A daemon thread only runs as long as there are non-daemon threads running.
- * When the last non-daemon thread ends, the runtime will exit. This is not
- * normally relevant to applications with a UI.
- */
- public final boolean isDaemon() {
- return daemon;
- }
-
- /**
- * Returns a <code>boolean</code> indicating whether the receiver has a
- * pending interrupt request (<code>true</code>) or not (
- * <code>false</code>)
- *
- * @return a <code>boolean</code> indicating the interrupt status
- * @see Thread#interrupt
- * @see Thread#interrupted
- */
- public boolean isInterrupted() {
- VMThread vmt = this.vmThread;
- if (vmt != null) {
- return vmt.isInterrupted();
- }
-
- return false;
- }
-
- /**
- * Blocks the current Thread (<code>Thread.currentThread()</code>) until
- * the receiver finishes its execution and dies.
- *
- * @throws InterruptedException if <code>interrupt()</code> was called for
- * the receiver while it was in the <code>join()</code> call
- * @see Object#notifyAll
- * @see java.lang.ThreadDeath
- */
- public final void join() throws InterruptedException {
- VMThread t = vmThread;
- if (t == null) {
- return;
- }
-
- synchronized (t) {
- while (isAlive()) {
- t.wait();
- }
- }
- }
-
- /**
- * Blocks the current Thread (<code>Thread.currentThread()</code>) until
- * the receiver finishes its execution and dies or the specified timeout
- * expires, whatever happens first.
- *
- * @param millis The maximum time to wait (in milliseconds).
- * @throws InterruptedException if <code>interrupt()</code> was called for
- * the receiver while it was in the <code>join()</code> call
- * @see Object#notifyAll
- * @see java.lang.ThreadDeath
- */
- public final void join(long millis) throws InterruptedException {
- join(millis, 0);
- }
-
- /**
- * Blocks the current Thread (<code>Thread.currentThread()</code>) until
- * the receiver finishes its execution and dies or the specified timeout
- * expires, whatever happens first.
- *
- * @param millis The maximum time to wait (in milliseconds).
- * @param nanos Extra nanosecond precision
- * @throws InterruptedException if <code>interrupt()</code> was called for
- * the receiver while it was in the <code>join()</code> call
- * @see Object#notifyAll
- * @see java.lang.ThreadDeath
- */
- public final void join(long millis, int nanos) throws InterruptedException {
- if (millis < 0 || nanos < 0 || nanos >= NANOS_PER_MILLI) {
- throw new IllegalArgumentException("bad timeout: millis=" + millis + ",nanos=" + nanos);
- }
-
- // avoid overflow: if total > 292,277 years, just wait forever
- boolean overflow = millis >= (Long.MAX_VALUE - nanos) / NANOS_PER_MILLI;
- boolean forever = (millis | nanos) == 0;
- if (forever | overflow) {
- join();
- return;
- }
-
- VMThread t = vmThread;
- if (t == null) {
- return;
- }
-
- synchronized (t) {
- if (!isAlive()) {
- return;
- }
-
- // guaranteed not to overflow
- long nanosToWait = millis * NANOS_PER_MILLI + nanos;
-
- // wait until this thread completes or the timeout has elapsed
- long start = System.nanoTime();
- while (true) {
- t.wait(millis, nanos);
- if (!isAlive()) {
- break;
- }
- long nanosElapsed = System.nanoTime() - start;
- long nanosRemaining = nanosToWait - nanosElapsed;
- if (nanosRemaining <= 0) {
- break;
- }
- millis = nanosRemaining / NANOS_PER_MILLI;
- nanos = (int) (nanosRemaining - millis * NANOS_PER_MILLI);
- }
- }
- }
-
- /**
- * Throws {@code UnsupportedOperationException}.
- * @deprecated Only useful in conjunction with deprecated method {@link Thread#suspend}.
- */
- @Deprecated
- public final void resume() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Calls the <code>run()</code> method of the Runnable object the receiver
- * holds. If no Runnable is set, does nothing.
- *
- * @see Thread#start
- */
- public void run() {
- if (target != null) {
- target.run();
- }
- }
-
- /**
- * Set the context ClassLoader for the receiver.
- *
- * @param cl The context ClassLoader
- * @see #getContextClassLoader()
- */
- public void setContextClassLoader(ClassLoader cl) {
- contextClassLoader = cl;
- }
-
- /**
- * Marks this thread as a daemon thread.
- * A daemon thread only runs as long as there are non-daemon threads running.
- * When the last non-daemon thread ends, the runtime will exit. This is not
- * normally relevant to applications with a UI.
- * @throws IllegalThreadStateException - if this thread has already started.
- */
- public final void setDaemon(boolean isDaemon) {
- checkNotStarted();
- if (vmThread == null) {
- daemon = isDaemon;
- }
- }
-
- private void checkNotStarted() {
- if (hasBeenStarted) {
- throw new IllegalThreadStateException("Thread already started");
- }
- }
-
- /**
- * Sets the default uncaught exception handler. This handler is invoked in
- * case any Thread dies due to an unhandled exception.
- *
- * @param handler
- * The handler to set or null.
- */
- public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
- Thread.defaultUncaughtHandler = handler;
- }
-
- /**
- * Adds a runnable to be invoked upon interruption. If this thread has
- * already been interrupted, the runnable will be invoked immediately. The
- * action should be idempotent as it may be invoked multiple times for a
- * single interruption.
- *
- * <p>Each call to this method must be matched with a corresponding call to
- * {@link #popInterruptAction$}.
- *
- * @hide used by NIO
- */
- public final void pushInterruptAction$(Runnable interruptAction) {
- synchronized (interruptActions) {
- interruptActions.add(interruptAction);
- }
-
- if (interruptAction != null && isInterrupted()) {
- interruptAction.run();
- }
- }
-
- /**
- * Removes {@code interruptAction} so it is not invoked upon interruption.
- *
- * @param interruptAction the pushed action, used to check that the call
- * stack is correctly nested.
- *
- * @hide used by NIO
- */
- public final void popInterruptAction$(Runnable interruptAction) {
- synchronized (interruptActions) {
- Runnable removed = interruptActions.remove(interruptActions.size() - 1);
- if (interruptAction != removed) {
- throw new IllegalArgumentException(
- "Expected " + interruptAction + " but was " + removed);
- }
- }
- }
-
- /**
- * Sets the name of the Thread.
- *
- * @param threadName the new name for the Thread
- * @see Thread#getName
- */
- public final void setName(String threadName) {
- if (threadName == null) {
- throw new NullPointerException("threadName == null");
- }
-
- name = threadName;
- VMThread vmt = this.vmThread;
- if (vmt != null) {
- /* notify the VM that the thread name has changed */
- vmt.nameChanged(threadName);
- }
- }
-
- /**
- * Sets the priority of this thread. If the requested priority is greater than the
- * parent thread group's {@link java.lang.ThreadGroup#getMaxPriority}, the group's maximum
- * priority will be used instead.
- *
- * @throws IllegalArgumentException - if the new priority is greater than {@link #MAX_PRIORITY}
- * or less than {@link #MIN_PRIORITY}
- */
- public final void setPriority(int priority) {
- if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
- throw new IllegalArgumentException("Priority out of range: " + priority);
- }
-
- if (priority > group.getMaxPriority()) {
- priority = group.getMaxPriority();
- }
-
- this.priority = priority;
-
- VMThread vmt = this.vmThread;
- if (vmt != null) {
- vmt.setPriority(priority);
- }
- }
-
- /**
- * <p>
- * Sets the uncaught exception handler. This handler is invoked in case this
- * Thread dies due to an unhandled exception.
- * </p>
- *
- * @param handler
- * The handler to set or <code>null</code>.
- */
- public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
- uncaughtHandler = handler;
- }
-
- /**
- * Causes the thread which sent this message to sleep for the given interval
- * of time (given in milliseconds). The precision is not guaranteed - the
- * Thread may sleep more or less than requested.
- *
- * @param time
- * The time to sleep in milliseconds.
- * @throws InterruptedException
- * if <code>interrupt()</code> was called for this Thread while
- * it was sleeping
- * @see Thread#interrupt()
- */
- public static void sleep(long time) throws InterruptedException {
- Thread.sleep(time, 0);
- }
-
- /**
- * Causes the thread which sent this message to sleep for the given interval
- * of time (given in milliseconds and nanoseconds). The precision is not
- * guaranteed - the Thread may sleep more or less than requested.
- *
- * @param millis
- * The time to sleep in milliseconds.
- * @param nanos
- * Extra nanosecond precision
- * @throws InterruptedException
- * if <code>interrupt()</code> was called for this Thread while
- * it was sleeping
- * @see Thread#interrupt()
- */
- public static void sleep(long millis, int nanos) throws InterruptedException {
- VMThread.sleep(millis, nanos);
- }
-
- /**
- * Starts the new Thread of execution. The <code>run()</code> method of
- * the receiver will be called by the receiver Thread itself (and not the
- * Thread calling <code>start()</code>).
- *
- * @throws IllegalThreadStateException - if this thread has already started.
- * @see Thread#run
- */
- public synchronized void start() {
- checkNotStarted();
-
- hasBeenStarted = true;
-
- VMThread.create(this, stackSize);
- }
-
- /**
- * Requests the receiver Thread to stop and throw ThreadDeath. The Thread is
- * resumed if it was suspended and awakened if it was sleeping, so that it
- * can proceed to throw ThreadDeath.
- *
- * @deprecated Stopping a thread in this manner is unsafe and can
- * leave your application and the VM in an unpredictable state.
- */
- @Deprecated
- public final void stop() {
- stop(new ThreadDeath());
- }
-
- /**
- * Throws {@code UnsupportedOperationException}.
- * @deprecated Stopping a thread in this manner is unsafe and can
- * leave your application and the VM in an unpredictable state.
- */
- @Deprecated
- public final synchronized void stop(Throwable throwable) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Throws {@code UnsupportedOperationException}.
- * @deprecated May cause deadlocks.
- */
- @Deprecated
- public final void suspend() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Returns a string containing a concise, human-readable description of the
- * Thread. It includes the Thread's name, priority, and group name.
- *
- * @return a printable representation for the receiver.
- */
- @Override
- public String toString() {
- return "Thread[" + name + "," + priority + "," + group.getName() + "]";
- }
-
- /**
- * Causes the calling Thread to yield execution time to another Thread that
- * is ready to run. The actual scheduling is implementation-dependent.
- */
- public static void yield() {
- VMThread.yield();
- }
-
- /**
- * Indicates whether the current Thread has a monitor lock on the specified
- * object.
- *
- * @param object the object to test for the monitor lock
- * @return true if the current thread has a monitor lock on the specified
- * object; false otherwise
- */
- public static boolean holdsLock(Object object) {
- return currentThread().vmThread.holdsLock(object);
- }
-
- /**
- * Implemented by objects that want to handle cases where a thread is being
- * terminated by an uncaught exception. Upon such termination, the handler
- * is notified of the terminating thread and causal exception. If there is
- * no explicit handler set then the thread's group is the default handler.
- */
- public static interface UncaughtExceptionHandler {
- /**
- * The thread is being terminated by an uncaught exception. Further
- * exceptions thrown in this method are prevent the remainder of the
- * method from executing, but are otherwise ignored.
- *
- * @param thread the thread that has an uncaught exception
- * @param ex the exception that was thrown
- */
- void uncaughtException(Thread thread, Throwable ex);
- }
-
- /**
- * Unparks this thread. This unblocks the thread it if it was
- * previously parked, or indicates that the thread is "preemptively
- * unparked" if it wasn't already parked. The latter means that the
- * next time the thread is told to park, it will merely clear its
- * latent park bit and carry on without blocking.
- *
- * <p>See {@link java.util.concurrent.locks.LockSupport} for more
- * in-depth information of the behavior of this method.</p>
- *
- * @hide for Unsafe
- */
- public void unpark() {
- VMThread vmt = vmThread;
-
- if (vmt == null) {
- /*
- * vmThread is null before the thread is start()ed. In
- * this case, we just go ahead and set the state to
- * PREEMPTIVELY_UNPARKED. Since this happens before the
- * thread is started, we don't have to worry about
- * synchronizing with it.
- */
- parkState = ParkState.PREEMPTIVELY_UNPARKED;
- return;
- }
-
- synchronized (vmt) {
- switch (parkState) {
- case ParkState.PREEMPTIVELY_UNPARKED: {
- /*
- * Nothing to do in this case: By definition, a
- * preemptively unparked thread is to remain in
- * the preemptively unparked state if it is told
- * to unpark.
- */
- break;
- }
- case ParkState.UNPARKED: {
- parkState = ParkState.PREEMPTIVELY_UNPARKED;
- break;
- }
- default /*parked*/: {
- parkState = ParkState.UNPARKED;
- vmt.notifyAll();
- break;
- }
- }
- }
- }
-
- /**
- * Parks the current thread for a particular number of nanoseconds, or
- * indefinitely. If not indefinitely, this method unparks the thread
- * after the given number of nanoseconds if no other thread unparks it
- * first. If the thread has been "preemptively unparked," this method
- * cancels that unparking and returns immediately. This method may
- * also return spuriously (that is, without the thread being told to
- * unpark and without the indicated amount of time elapsing).
- *
- * <p>See {@link java.util.concurrent.locks.LockSupport} for more
- * in-depth information of the behavior of this method.</p>
- *
- * <p>This method must only be called when <code>this</code> is the current
- * thread.
- *
- * @param nanos number of nanoseconds to park for or <code>0</code>
- * to park indefinitely
- * @throws IllegalArgumentException thrown if <code>nanos &lt; 0</code>
- *
- * @hide for Unsafe
- */
- public void parkFor(long nanos) {
- VMThread vmt = vmThread;
-
- if (vmt == null) {
- // Running threads should always have an associated vmThread.
- throw new AssertionError();
- }
-
- synchronized (vmt) {
- switch (parkState) {
- case ParkState.PREEMPTIVELY_UNPARKED: {
- parkState = ParkState.UNPARKED;
- break;
- }
- case ParkState.UNPARKED: {
- long millis = nanos / NANOS_PER_MILLI;
- nanos %= NANOS_PER_MILLI;
-
- parkState = ParkState.PARKED;
- try {
- vmt.wait(millis, (int) nanos);
- } catch (InterruptedException ex) {
- interrupt();
- } finally {
- /*
- * Note: If parkState manages to become
- * PREEMPTIVELY_UNPARKED before hitting this
- * code, it should left in that state.
- */
- if (parkState == ParkState.PARKED) {
- parkState = ParkState.UNPARKED;
- }
- }
- break;
- }
- default /*parked*/: {
- throw new AssertionError(
- "shouldn't happen: attempt to repark");
- }
- }
- }
- }
-
- /**
- * Parks the current thread until the specified system time. This
- * method attempts to unpark the current thread immediately after
- * <code>System.currentTimeMillis()</code> reaches the specified
- * value, if no other thread unparks it first. If the thread has
- * been "preemptively unparked," this method cancels that
- * unparking and returns immediately. This method may also return
- * spuriously (that is, without the thread being told to unpark
- * and without the indicated amount of time elapsing).
- *
- * <p>See {@link java.util.concurrent.locks.LockSupport} for more
- * in-depth information of the behavior of this method.</p>
- *
- * <p>This method must only be called when <code>this</code> is the
- * current thread.
- *
- * @param time the time after which the thread should be unparked,
- * in absolute milliseconds-since-the-epoch
- *
- * @hide for Unsafe
- */
- public void parkUntil(long time) {
- VMThread vmt = vmThread;
-
- if (vmt == null) {
- // Running threads should always have an associated vmThread.
- throw new AssertionError();
- }
-
- synchronized (vmt) {
- /*
- * Note: This conflates the two time bases of "wall clock"
- * time and "monotonic uptime" time. However, given that
- * the underlying system can only wait on monotonic time,
- * it is unclear if there is any way to avoid the
- * conflation. The downside here is that if, having
- * calculated the delay, the wall clock gets moved ahead,
- * this method may not return until well after the wall
- * clock has reached the originally designated time. The
- * reverse problem (the wall clock being turned back)
- * isn't a big deal, since this method is allowed to
- * spuriously return for any reason, and this situation
- * can safely be construed as just such a spurious return.
- */
- long delayMillis = time - System.currentTimeMillis();
-
- if (delayMillis <= 0) {
- parkState = ParkState.UNPARKED;
- } else {
- parkFor(delayMillis * NANOS_PER_MILLI);
- }
- }
- }
-}
diff --git a/libdvm/src/main/java/java/lang/ThreadGroup.java b/libdvm/src/main/java/java/lang/ThreadGroup.java
deleted file mode 100644
index 7fc6b72..0000000
--- a/libdvm/src/main/java/java/lang/ThreadGroup.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import libcore.util.CollectionUtils;
-
-/**
- * {@code ThreadGroup} is a means of organizing threads into a hierarchical structure.
- * This class is obsolete. See <i>Effective Java</i> Item 73, "Avoid thread groups" for details.
- * @see Thread
- */
-public class ThreadGroup implements Thread.UncaughtExceptionHandler {
-
- // Name of this ThreadGroup
- // VM needs this field name for debugging.
- private String name;
-
- // Maximum priority for Threads inside this ThreadGroup
- private int maxPriority = Thread.MAX_PRIORITY;
-
- // The ThreadGroup to which this ThreadGroup belongs
- // VM needs this field name for debugging.
- final ThreadGroup parent;
-
- /**
- * Weak references to the threads in this group.
- * Access is guarded by synchronizing on this field.
- */
- private final List<WeakReference<Thread>> threadRefs = new ArrayList<WeakReference<Thread>>(5);
-
- /**
- * View of the threads.
- * Access is guarded by synchronizing on threadRefs.
- */
- private final Iterable<Thread> threads = CollectionUtils.dereferenceIterable(threadRefs, true);
-
- /**
- * Thread groups. Access is guarded by synchronizing on this field.
- */
- private final List<ThreadGroup> groups = new ArrayList<ThreadGroup>(3);
-
- // Whether this ThreadGroup is a daemon ThreadGroup or not
- private boolean isDaemon;
-
- // Whether this ThreadGroup has already been destroyed or not
- private boolean isDestroyed;
-
- /* the VM uses these directly; do not rename */
- static final ThreadGroup mSystem = new ThreadGroup();
- static final ThreadGroup mMain = new ThreadGroup(mSystem, "main");
-
- /**
- * Constructs a new {@code ThreadGroup} with the given name. The new {@code ThreadGroup}
- * will be child of the {@code ThreadGroup} to which the calling thread belongs.
- *
- * @param name the name
- * @see Thread#currentThread
- */
- public ThreadGroup(String name) {
- this(Thread.currentThread().getThreadGroup(), name);
- }
-
- /**
- * Constructs a new {@code ThreadGroup} with the given name, as a child of the
- * given {@code ThreadGroup}.
- *
- * @param parent the parent
- * @param name the name
- * @throws NullPointerException if {@code parent == null}
- * @throws IllegalThreadStateException if {@code parent} has been
- * destroyed already
- */
- public ThreadGroup(ThreadGroup parent, String name) {
- if (parent == null) {
- throw new NullPointerException("parent == null");
- }
- this.name = name;
- this.parent = parent;
- if (parent != null) {
- parent.add(this);
- this.setMaxPriority(parent.getMaxPriority());
- if (parent.isDaemon()) {
- this.setDaemon(true);
- }
- }
- }
-
- /**
- * Initialize the special "system" ThreadGroup. Was "main" in Harmony,
- * but we have an additional group above that in Android.
- */
- private ThreadGroup() {
- this.name = "system";
- this.parent = null;
- }
-
- /**
- * Returns the number of running {@code Thread}s which are children of this thread group,
- * directly or indirectly.
- *
- * @return the number of children
- */
- public int activeCount() {
- int count = 0;
- synchronized (threadRefs) {
- for (Thread thread : threads) {
- if (thread.isAlive()) {
- count++;
- }
- }
- }
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- count += group.activeCount();
- }
- }
- return count;
- }
-
- /**
- * Returns the number of {@code ThreadGroup}s which are children of this group,
- * directly or indirectly.
- *
- * @return the number of children
- */
- public int activeGroupCount() {
- int count = 0;
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- // One for this group & the subgroups
- count += 1 + group.activeGroupCount();
- }
- }
- return count;
- }
-
- /**
- * Adds a {@code ThreadGroup} to this thread group.
- *
- * @param g ThreadGroup to add
- * @throws IllegalThreadStateException if this group has been destroyed already
- */
- private void add(ThreadGroup g) throws IllegalThreadStateException {
- synchronized (groups) {
- if (isDestroyed) {
- throw new IllegalThreadStateException();
- }
- groups.add(g);
- }
- }
-
- /**
- * Does nothing. The definition of this method depends on the deprecated
- * method {@link #suspend()}. The exact behavior of this call was never
- * specified.
- *
- * @param b Used to control low memory implicit suspension
- * @return {@code true} (always)
- *
- * @deprecated Required deprecated method {@link #suspend()}.
- */
- @Deprecated
- public boolean allowThreadSuspension(boolean b) {
- // Does not apply to this VM, no-op
- return true;
- }
-
- /**
- * Does nothing.
- */
- public final void checkAccess() {
- }
-
- /**
- * Destroys this thread group and recursively all its subgroups. It is only legal
- * to destroy a {@code ThreadGroup} that has no threads in it. Any daemon
- * {@code ThreadGroup} is destroyed automatically when it becomes empty (no threads
- * or thread groups in it).
- *
- * @throws IllegalThreadStateException if this thread group or any of its
- * subgroups has been destroyed already or if it still contains
- * threads.
- */
- public final void destroy() {
- synchronized (threadRefs) {
- synchronized (groups) {
- if (isDestroyed) {
- throw new IllegalThreadStateException(
- "Thread group was already destroyed: "
- + (this.name != null ? this.name : "n/a"));
- }
- if (threads.iterator().hasNext()) {
- throw new IllegalThreadStateException(
- "Thread group still contains threads: "
- + (this.name != null ? this.name : "n/a"));
- }
- // Call recursively for subgroups
- while (!groups.isEmpty()) {
- // We always get the first element - remember, when the
- // child dies it removes itself from our collection. See
- // below.
- groups.get(0).destroy();
- }
-
- if (parent != null) {
- parent.remove(this);
- }
-
- // Now that the ThreadGroup is really destroyed it can be tagged as so
- this.isDestroyed = true;
- }
- }
- }
-
- /*
- * Auxiliary method that destroys this thread group and recursively all its
- * subgroups if this is a daemon ThreadGroup.
- *
- * @see #destroy
- * @see #setDaemon
- * @see #isDaemon
- */
- private void destroyIfEmptyDaemon() {
- // Has to be non-destroyed daemon to make sense
- synchronized (threadRefs) {
- if (isDaemon && !isDestroyed && !threads.iterator().hasNext()) {
- synchronized (groups) {
- if (groups.isEmpty()) {
- destroy();
- }
- }
- }
- }
- }
-
- /**
- * Iterates over all active threads in this group (and its sub-groups) and
- * stores the threads in the given array. Returns when the array is full or
- * no more threads remain, whichever happens first.
- *
- * <p>Note that this method will silently ignore any threads that don't fit in the
- * supplied array.
- *
- * @param threads the array into which the {@code Thread}s will be copied
- * @return the number of {@code Thread}s that were copied
- */
- public int enumerate(Thread[] threads) {
- return enumerate(threads, true);
- }
-
- /**
- * Iterates over all active threads in this group (and, optionally, its
- * sub-groups) and stores the threads in the given array. Returns when the
- * array is full or no more threads remain, whichever happens first.
- *
- * <p>Note that this method will silently ignore any threads that don't fit in the
- * supplied array.
- *
- * @param threads the array into which the {@code Thread}s will be copied
- * @param recurse indicates whether {@code Thread}s in subgroups should be
- * recursively copied as well
- * @return the number of {@code Thread}s that were copied
- */
- public int enumerate(Thread[] threads, boolean recurse) {
- return enumerateGeneric(threads, recurse, 0, true);
- }
-
- /**
- * Iterates over all thread groups in this group (and its sub-groups) and
- * and stores the groups in the given array. Returns when the array is full
- * or no more groups remain, whichever happens first.
- *
- * <p>Note that this method will silently ignore any thread groups that don't fit in the
- * supplied array.
- *
- * @param groups the array into which the {@code ThreadGroup}s will be copied
- * @return the number of {@code ThreadGroup}s that were copied
- */
- public int enumerate(ThreadGroup[] groups) {
- return enumerate(groups, true);
- }
-
- /**
- * Iterates over all thread groups in this group (and, optionally, its
- * sub-groups) and stores the groups in the given array. Returns when
- * the array is full or no more groups remain, whichever happens first.
- *
- * <p>Note that this method will silently ignore any thread groups that don't fit in the
- * supplied array.
- *
- * @param groups the array into which the {@code ThreadGroup}s will be copied
- * @param recurse indicates whether {@code ThreadGroup}s in subgroups should be
- * recursively copied as well or not
- * @return the number of {@code ThreadGroup}s that were copied
- */
- public int enumerate(ThreadGroup[] groups, boolean recurse) {
- return enumerateGeneric(groups, recurse, 0, false);
- }
-
- /**
- * Copies into <param>enumeration</param> starting at
- * <param>enumerationIndex</param> all Threads or ThreadGroups in the
- * receiver. If <param>recurse</param> is true, recursively enumerate the
- * elements in subgroups.
- *
- * If the array passed as parameter is too small no exception is thrown -
- * the extra elements are simply not copied.
- *
- * @param enumeration array into which the elements will be copied
- * @param recurse Indicates whether subgroups should be enumerated or not
- * @param enumerationIndex Indicates in which position of the enumeration
- * array we are
- * @param enumeratingThreads Indicates whether we are enumerating Threads or
- * ThreadGroups
- * @return How many elements were enumerated/copied over
- */
- private int enumerateGeneric(Object[] enumeration, boolean recurse, int enumerationIndex,
- boolean enumeratingThreads) {
- if (enumeratingThreads) {
- synchronized (threadRefs) {
- // walk the references directly so we can iterate in reverse order
- for (int i = threadRefs.size() - 1; i >= 0; --i) {
- Thread thread = threadRefs.get(i).get();
- if (thread != null && thread.isAlive()) {
- if (enumerationIndex >= enumeration.length) {
- return enumerationIndex;
- }
- enumeration[enumerationIndex++] = thread;
- }
- }
- }
- } else {
- synchronized (groups) {
- for (int i = groups.size() - 1; i >= 0; --i) {
- if (enumerationIndex >= enumeration.length) {
- return enumerationIndex;
- }
- enumeration[enumerationIndex++] = groups.get(i);
- }
- }
- }
-
- if (recurse) {
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- if (enumerationIndex >= enumeration.length) {
- return enumerationIndex;
- }
- enumerationIndex = group.enumerateGeneric(enumeration, recurse,
- enumerationIndex, enumeratingThreads);
- }
- }
- }
- return enumerationIndex;
- }
-
- /**
- * Returns the maximum allowed priority for a {@code Thread} in this thread group.
- *
- * @return the maximum priority
- *
- * @see #setMaxPriority
- */
- public final int getMaxPriority() {
- return maxPriority;
- }
-
- /**
- * Returns the name of this thread group.
- *
- * @return the group's name
- */
- public final String getName() {
- return name;
- }
-
- /**
- * Returns this thread group's parent {@code ThreadGroup}. It can be null if this
- * is the the root ThreadGroup.
- *
- * @return the parent
- */
- public final ThreadGroup getParent() {
- return parent;
- }
-
- /**
- * Interrupts every {@code Thread} in this group and recursively in all its
- * subgroups.
- *
- * @see Thread#interrupt
- */
- public final void interrupt() {
- synchronized (threadRefs) {
- for (Thread thread : threads) {
- thread.interrupt();
- }
- }
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- group.interrupt();
- }
- }
- }
-
- /**
- * Checks whether this thread group is a daemon {@code ThreadGroup}.
- *
- * @return true if this thread group is a daemon {@code ThreadGroup}
- *
- * @see #setDaemon
- * @see #destroy
- */
- public final boolean isDaemon() {
- return isDaemon;
- }
-
- /**
- * Checks whether this thread group has already been destroyed.
- *
- * @return true if this thread group has already been destroyed
- * @see #destroy
- */
- public synchronized boolean isDestroyed() {
- return isDestroyed;
- }
-
- /**
- * Outputs to {@code System.out} a text representation of the
- * hierarchy of {@code Thread}s and {@code ThreadGroup}s in this thread group (and recursively).
- * Proper indentation is used to show the nesting of groups inside groups
- * and threads inside groups.
- */
- public void list() {
- // We start in a fresh line
- System.out.println();
- list(0);
- }
-
- /*
- * Outputs to {@code System.out}a text representation of the
- * hierarchy of Threads and ThreadGroups in this thread group (and recursively).
- * The indentation will be four spaces per level of nesting.
- *
- * @param levels How many levels of nesting, so that proper indentation can
- * be output.
- */
- private void list(int levels) {
- indent(levels);
- System.out.println(this.toString());
-
- ++levels;
- synchronized (threadRefs) {
- for (Thread thread : threads) {
- indent(levels);
- System.out.println(thread);
- }
- }
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- group.list(levels);
- }
- }
- }
-
- private void indent(int levels) {
- for (int i = 0; i < levels; i++) {
- System.out.print(" "); // 4 spaces for each level
- }
- }
-
- /**
- * Checks whether this thread group is a direct or indirect parent group of a
- * given {@code ThreadGroup}.
- *
- * @param g the potential child {@code ThreadGroup}
- * @return true if this thread group is parent of {@code g}
- */
- public final boolean parentOf(ThreadGroup g) {
- while (g != null) {
- if (this == g) {
- return true;
- }
- g = g.parent;
- }
- return false;
- }
-
- /**
- * Removes an immediate subgroup.
- *
- * @param g ThreadGroup to remove
- *
- * @see #add(Thread)
- * @see #add(ThreadGroup)
- */
- private void remove(ThreadGroup g) {
- synchronized (groups) {
- for (Iterator<ThreadGroup> i = groups.iterator(); i.hasNext(); ) {
- ThreadGroup threadGroup = i.next();
- if (threadGroup.equals(g)) {
- i.remove();
- break;
- }
- }
- }
- destroyIfEmptyDaemon();
- }
-
- /**
- * Resumes every thread in this group and recursively in all its
- * subgroups.
- *
- * @see Thread#resume
- * @see #suspend
- *
- * @deprecated Requires deprecated method {@link Thread#resume()}.
- */
- @SuppressWarnings("deprecation")
- @Deprecated
- public final void resume() {
- synchronized (threadRefs) {
- for (Thread thread : threads) {
- thread.resume();
- }
- }
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- group.resume();
- }
- }
- }
-
- /**
- * Sets whether this is a daemon {@code ThreadGroup} or not. Daemon
- * thread groups are automatically destroyed when they become empty.
- *
- * @param isDaemon the new value
- * @see #isDaemon
- * @see #destroy
- */
- public final void setDaemon(boolean isDaemon) {
- this.isDaemon = isDaemon;
- }
-
- /**
- * Configures the maximum allowed priority for a {@code Thread} in this group and
- * recursively in all its subgroups.
- *
- * <p>A caller can never increase the maximum priority of a thread group.
- * Such an attempt will not result in an exception, it will
- * simply leave the thread group with its current maximum priority.
- *
- * @param newMax the new maximum priority to be set
- *
- * @throws IllegalArgumentException if the new priority is greater than
- * Thread.MAX_PRIORITY or less than Thread.MIN_PRIORITY
- *
- * @see #getMaxPriority
- */
- public final void setMaxPriority(int newMax) {
- if (newMax <= this.maxPriority) {
- if (newMax < Thread.MIN_PRIORITY) {
- newMax = Thread.MIN_PRIORITY;
- }
-
- int parentPriority = parent == null ? newMax : parent.getMaxPriority();
- this.maxPriority = parentPriority <= newMax ? parentPriority : newMax;
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- group.setMaxPriority(newMax);
- }
- }
- }
- }
-
- /**
- * Stops every thread in this group and recursively in all its subgroups.
- *
- * @see Thread#stop()
- * @see Thread#stop(Throwable)
- * @see ThreadDeath
- *
- * @deprecated Requires deprecated method {@link Thread#stop()}.
- */
- @SuppressWarnings("deprecation")
- @Deprecated
- public final void stop() {
- if (stopHelper()) {
- Thread.currentThread().stop();
- }
- }
-
- @SuppressWarnings("deprecation")
- private boolean stopHelper() {
- boolean stopCurrent = false;
- synchronized (threadRefs) {
- Thread current = Thread.currentThread();
- for (Thread thread : threads) {
- if (thread == current) {
- stopCurrent = true;
- } else {
- thread.stop();
- }
- }
- }
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- stopCurrent |= group.stopHelper();
- }
- }
- return stopCurrent;
- }
-
- /**
- * Suspends every thread in this group and recursively in all its
- * subgroups.
- *
- * @see Thread#suspend
- * @see #resume
- *
- * @deprecated Requires deprecated method {@link Thread#suspend()}.
- */
- @SuppressWarnings("deprecation")
- @Deprecated
- public final void suspend() {
- if (suspendHelper()) {
- Thread.currentThread().suspend();
- }
- }
-
- @SuppressWarnings("deprecation")
- private boolean suspendHelper() {
- boolean suspendCurrent = false;
- synchronized (threadRefs) {
- Thread current = Thread.currentThread();
- for (Thread thread : threads) {
- if (thread == current) {
- suspendCurrent = true;
- } else {
- thread.suspend();
- }
- }
- }
- synchronized (groups) {
- for (ThreadGroup group : groups) {
- suspendCurrent |= group.suspendHelper();
- }
- }
- return suspendCurrent;
- }
-
- @Override
- public String toString() {
- return getClass().getName() + "[name=" + getName()
- + ",maxPriority=" + getMaxPriority() + "]";
- }
-
- /**
- * Handles uncaught exceptions. Any uncaught exception in any {@code Thread}
- * is forwarded to the thread's {@code ThreadGroup} by invoking this
- * method.
- *
- * <p>New code should use {@link Thread#setUncaughtExceptionHandler} instead of thread groups.
- *
- * @param t the Thread that terminated with an uncaught exception
- * @param e the uncaught exception itself
- */
- public void uncaughtException(Thread t, Throwable e) {
- if (parent != null) {
- parent.uncaughtException(t, e);
- } else if (Thread.getDefaultUncaughtExceptionHandler() != null) {
- // TODO The spec is unclear regarding this. What do we do?
- Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, e);
- } else if (!(e instanceof ThreadDeath)) {
- // No parent group, has to be 'system' Thread Group
- e.printStackTrace(System.err);
- }
- }
-
- /**
- * Called by the Thread constructor.
- */
- final void addThread(Thread thread) throws IllegalThreadStateException {
- synchronized (threadRefs) {
- if (isDestroyed) {
- throw new IllegalThreadStateException();
- }
- threadRefs.add(new WeakReference<Thread>(thread));
- }
- }
-
- /**
- * Called by the VM when a Thread dies.
- */
- final void removeThread(Thread thread) throws IllegalThreadStateException {
- synchronized (threadRefs) {
- for (Iterator<Thread> i = threads.iterator(); i.hasNext(); ) {
- if (i.next().equals(thread)) {
- i.remove();
- break;
- }
- }
- }
- destroyIfEmptyDaemon();
- }
-}
diff --git a/libdvm/src/main/java/java/lang/VMClassLoader.java b/libdvm/src/main/java/java/lang/VMClassLoader.java
deleted file mode 100644
index d7162c6..0000000
--- a/libdvm/src/main/java/java/lang/VMClassLoader.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-class VMClassLoader {
-
- /**
- * Get a resource from a file in the bootstrap class path.
- *
- * It would be simpler to just walk through the class path elements
- * ourselves, but that would require reopening Jar files.
- *
- * We assume that the bootclasspath can't change once the VM has
- * started. This assumption seems to be supported by the spec.
- */
- static URL getResource(String name) {
- int numEntries = getBootClassPathSize();
- for (int i = 0; i < numEntries; i++) {
- String urlStr = getBootClassPathResource(name, i);
- if (urlStr != null) {
- try {
- return new URL(urlStr);
- } catch (MalformedURLException mue) {
- mue.printStackTrace();
- // unexpected; keep going
- }
- }
- }
- return null;
- }
-
- /*
- * Get an enumeration with all matching resources.
- */
- static List<URL> getResources(String name) {
- ArrayList<URL> list = new ArrayList<URL>();
- int numEntries = getBootClassPathSize();
- for (int i = 0; i < numEntries; i++) {
- String urlStr = getBootClassPathResource(name, i);
- if (urlStr != null) {
- try {
- list.add(new URL(urlStr));
- } catch (MalformedURLException mue) {
- mue.printStackTrace();
- // unexpected; keep going
- }
- }
- }
- return list;
- }
-
- /**
- * Load class with bootstrap class loader.
- */
- native static Class loadClass(String name, boolean resolve) throws ClassNotFoundException;
-
- native static Class getPrimitiveClass(char type);
-
- native static Class findLoadedClass(ClassLoader cl, String name);
-
- /**
- * Boot class path manipulation, for getResources().
- */
- native private static int getBootClassPathSize();
- native private static String getBootClassPathResource(String name, int index);
-}
diff --git a/libdvm/src/main/java/java/lang/VMThread.java b/libdvm/src/main/java/java/lang/VMThread.java
deleted file mode 100644
index 01f6ee3..0000000
--- a/libdvm/src/main/java/java/lang/VMThread.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-class VMThread {
- Thread thread;
- int vmData;
-
- VMThread(Thread t) {
- thread = t;
- }
-
- native static void create(Thread t, long stackSize);
-
- static native Thread currentThread();
- static native boolean interrupted();
- static native void sleep (long msec, int nsec) throws InterruptedException;
- static native void yield();
-
- native void interrupt();
-
- native boolean isInterrupted();
-
- /**
- * Starts the VMThread (and thus the Java Thread) with the given
- * stack size.
- */
- void start(long stackSize) {
- VMThread.create(thread, stackSize);
- }
-
- /**
- * Queries whether this Thread holds a monitor lock on the
- * given object.
- */
- native boolean holdsLock(Object object);
-
- native void setPriority(int newPriority);
- native int getStatus();
-
- /**
- * Holds a mapping from native Thread statuses to Java one. Required for
- * translating back the result of getStatus().
- */
- static final Thread.State[] STATE_MAP = new Thread.State[] {
- Thread.State.TERMINATED, // ZOMBIE
- Thread.State.RUNNABLE, // RUNNING
- Thread.State.TIMED_WAITING, // TIMED_WAIT
- Thread.State.BLOCKED, // MONITOR
- Thread.State.WAITING, // WAIT
- Thread.State.NEW, // INITIALIZING
- Thread.State.NEW, // STARTING
- Thread.State.RUNNABLE, // NATIVE
- Thread.State.WAITING, // VMWAIT
- Thread.State.RUNNABLE // SUSPENDED
- };
-
- /**
- * Tell the VM that the thread's name has changed. This is useful for
- * DDMS, which would otherwise be oblivious to Thread.setName calls.
- */
- native void nameChanged(String newName);
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/AccessibleObject.java b/libdvm/src/main/java/java/lang/reflect/AccessibleObject.java
deleted file mode 100644
index f3d96af..0000000
--- a/libdvm/src/main/java/java/lang/reflect/AccessibleObject.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.util.Hashtable;
-import org.apache.harmony.kernel.vm.StringUtils;
-
-/**
- * {@code AccessibleObject} is the superclass of all member reflection classes
- * (Field, Constructor, Method). AccessibleObject provides the ability to toggle
- * a flag controlling access checks for these objects. By default, accessing a
- * member (for example, setting a field or invoking a method) checks the
- * validity of the access (for example, invoking a private method from outside
- * the defining class is prohibited) and throws IllegalAccessException if the
- * operation is not permitted. If the accessible flag is set to true, these
- * checks are omitted. This allows privileged code, such as Java object
- * serialization, object inspectors, and debuggers to have complete access to
- * objects.
- *
- * @see Field
- * @see Constructor
- * @see Method
- */
-public class AccessibleObject implements AnnotatedElement {
-
- /**
- * If true, object is accessible, bypassing normal access checks
- */
- boolean flag = false;
-
- // Holds a mapping from Java type names to native type codes.
- static Hashtable<String, String> trans;
-
- static {
- trans = new Hashtable<String, String>(9);
- trans.put("byte", "B");
- trans.put("char", "C");
- trans.put("short", "S");
- trans.put("int", "I");
- trans.put("long", "J");
- trans.put("float", "F");
- trans.put("double", "D");
- trans.put("void", "V");
- trans.put("boolean", "Z");
- }
-
- /**
- * Attempts to set the value of the accessible flag for all the objects in
- * the array provided. Setting this
- * flag to {@code false} will enable access checks, setting to {@code true}
- * will disable them.
- *
- * @param objects
- * the accessible objects
- * @param flag
- * the new value for the accessible flag
- *
- * @see #setAccessible(boolean)
- */
- public static void setAccessible(AccessibleObject[] objects, boolean flag) {
- for (AccessibleObject object : objects) {
- object.flag = flag;
- }
- }
-
- /**
- * Constructs a new {@code AccessibleObject} instance. {@code
- * AccessibleObject} instances can only be constructed by the virtual
- * machine.
- */
- protected AccessibleObject() {
- }
-
- /**
- * Indicates whether this object is accessible without access checks being
- * performed. Returns the accessible flag.
- *
- * @return {@code true} if this object is accessible without access
- * checks, {@code false} otherwise
- */
- public boolean isAccessible() {
- return flag;
- }
-
- /**
- * Attempts to set the value of the accessible flag. Setting this flag to
- * {@code false} will enable access checks, setting to {@code true} will
- * disable them.
- *
- * @param flag
- * the new value for the accessible flag
- */
- public void setAccessible(boolean flag) {
- this.flag = flag;
- }
-
- public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
- throw new UnsupportedOperationException();
- }
-
- public Annotation[] getDeclaredAnnotations() {
- throw new UnsupportedOperationException();
- }
-
- public Annotation[] getAnnotations() {
- // for all but Class, getAnnotations == getDeclaredAnnotations
- return getDeclaredAnnotations();
- }
-
- public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Returns the signature for a class. This is the kind of signature used
- * internally by the JVM, with one-character codes representing the basic
- * types. It is not suitable for printing.
- *
- * @param clazz
- * the class for which a signature is required
- *
- * @return The signature as a string
- */
- String getSignature(Class<?> clazz) {
- String result = "";
- String nextType = clazz.getName();
-
- if(trans.containsKey(nextType)) {
- result = trans.get(nextType);
- } else {
- if(clazz.isArray()) {
- result = "[" + getSignature(clazz.getComponentType());
- } else {
- result = "L" + nextType + ";";
- }
- }
- return result;
- }
-
- /**
- * Returns a printable String consisting of the canonical names of the
- * classes contained in an array. The form is that used in parameter and
- * exception lists, that is, the class or type names are separated by
- * commas.
- *
- * @param types
- * the array of classes
- *
- * @return The String of names
- */
- String toString(Class<?>[] types) {
- StringBuilder result = new StringBuilder();
-
- if (types.length != 0) {
- appendTypeName(result, types[0]);
- for (int i = 1; i < types.length; i++) {
- result.append(',');
- appendTypeName(result, types[i]);
- }
- }
-
- return result.toString();
- }
-
- /**
- * Gets the Signature attribute for this instance. Returns {@code null}
- * if not found.
- */
- /*package*/ String getSignatureAttribute() {
- /*
- * Note: This method would have been declared abstract, but the
- * standard API lists this class as concrete.
- */
- throw new UnsupportedOperationException();
- }
-
- /**
- * Retrieve the signature attribute from an arbitrary class. This is
- * the same as Class.getSignatureAttribute(), but it can be used from
- * the java.lang.reflect package.
- */
- /*package*/ static String getClassSignatureAttribute(Class clazz) {
- Object[] annotation = getClassSignatureAnnotation(clazz);
-
- if (annotation == null) {
- return null;
- }
-
- return StringUtils.combineStrings(annotation);
- }
-
- /**
- * Retrieve the signature annotation from an arbitrary class. This is
- * the same as Class.getSignatureAttribute(), but it can be used from
- * the java.lang.reflect package.
- */
- private static native Object[] getClassSignatureAnnotation(Class clazz);
-
- /**
- * Appends the best {@link #toString} name for {@code c} to {@code out}.
- * This works around the fact that {@link Class#getName} is lousy for
- * primitive arrays (it writes "[C" instead of "char[]") and {@link
- * Class#getCanonicalName()} is lousy for nested classes (it uses a "."
- * separator rather than a "$" separator).
- */
- void appendTypeName(StringBuilder out, Class<?> c) {
- int dimensions = 0;
- while (c.isArray()) {
- c = c.getComponentType();
- dimensions++;
- }
- out.append(c.getName());
- for (int d = 0; d < dimensions; d++) {
- out.append("[]");
- }
- }
-
- /**
- * Appends names of the specified array classes to the buffer. The array
- * elements may represent a simple type, a reference type or an array type.
- * Output format: java.lang.Object[], java.io.File, void
- *
- * @param types array of classes to print the names
- * @throws NullPointerException if any of the arguments is null
- */
- void appendArrayGenericType(StringBuilder sb, Type[] types) {
- if (types.length > 0) {
- appendGenericType(sb, types[0]);
- for (int i = 1; i < types.length; i++) {
- sb.append(',');
- appendGenericType(sb, types[i]);
- }
- }
- }
-
- /**
- * Appends the generic type representation to the buffer.
- *
- * @param sb buffer
- * @param obj the generic type which representation should be appended to the buffer
- *
- * @throws NullPointerException if any of the arguments is null
- */
- void appendGenericType(StringBuilder sb, Type obj) {
- if (obj instanceof TypeVariable) {
- sb.append(((TypeVariable)obj).getName());
- } else if (obj instanceof ParameterizedType) {
- sb.append(obj.toString());
- } else if (obj instanceof GenericArrayType) { //XXX: is it a working branch?
- Type simplified = ((GenericArrayType)obj).getGenericComponentType();
- appendGenericType(sb, simplified);
- sb.append("[]");
- } else if (obj instanceof Class) {
- Class c = ((Class<?>)obj);
- if (c.isArray()){
- String as[] = c.getName().split("\\[");
- int len = as.length-1;
- if (as[len].length() > 1){
- sb.append(as[len].substring(1, as[len].length()-1));
- } else {
- char ch = as[len].charAt(0);
- if (ch == 'I')
- sb.append("int");
- else if (ch == 'B')
- sb.append("byte");
- else if (ch == 'J')
- sb.append("long");
- else if (ch == 'F')
- sb.append("float");
- else if (ch == 'D')
- sb.append("double");
- else if (ch == 'S')
- sb.append("short");
- else if (ch == 'C')
- sb.append("char");
- else if (ch == 'Z')
- sb.append("boolean");
- else if (ch == 'V') //XXX: is it a working branch?
- sb.append("void");
- }
- for (int i = 0; i < len; i++){
- sb.append("[]");
- }
- } else {
- sb.append(c.getName());
- }
- }
- }
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/Constructor.java b/libdvm/src/main/java/java/lang/reflect/Constructor.java
deleted file mode 100644
index ab417d2..0000000
--- a/libdvm/src/main/java/java/lang/reflect/Constructor.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import libcore.util.EmptyArray;
-import org.apache.harmony.kernel.vm.StringUtils;
-import libcore.reflect.GenericSignatureParser;
-import libcore.reflect.ListOfTypes;
-import libcore.reflect.Types;
-
-/**
- * This class represents a constructor. Information about the constructor can be
- * accessed, and the constructor can be invoked dynamically.
- *
- * @param <T> the class that declares this constructor
- */
-public final class Constructor<T> extends AccessibleObject implements GenericDeclaration,
- Member {
-
- Class<T> declaringClass;
-
- Class<?>[] parameterTypes;
-
- Class<?>[] exceptionTypes;
-
- ListOfTypes genericExceptionTypes;
- ListOfTypes genericParameterTypes;
- TypeVariable<Constructor<T>>[] formalTypeParameters;
- private volatile boolean genericTypesAreInitialized = false;
-
- private synchronized void initGenericTypes() {
- if (!genericTypesAreInitialized) {
- String signatureAttribute = getSignatureAttribute();
- GenericSignatureParser parser = new GenericSignatureParser(
- declaringClass.getClassLoader());
- parser.parseForConstructor(this, signatureAttribute, exceptionTypes);
- formalTypeParameters = parser.formalTypeParameters;
- genericParameterTypes = parser.parameterTypes;
- genericExceptionTypes = parser.exceptionTypes;
- genericTypesAreInitialized = true;
- }
- }
-
- int slot;
-
- private int methodDexIndex;
-
- /**
- * Prevent this class from being instantiated.
- */
- private Constructor(){
- //do nothing
- }
-
- /**
- * Creates an instance of the class. Only called from native code, thus
- * private.
- *
- * @param declaringClass
- * the class this constructor object belongs to
- * @param ptypes
- * the parameter types of the constructor
- * @param extypes
- * the exception types of the constructor
- * @param slot
- * the slot of the constructor inside the VM class structure
- */
- private Constructor(Class<T> declaringClass, Class<?>[] ptypes, Class<?>[] extypes, int slot, int methodDexIndex) {
- this.declaringClass = declaringClass;
- this.parameterTypes = ptypes;
- this.exceptionTypes = extypes; // may be null
- this.slot = slot;
- this.methodDexIndex = methodDexIndex;
- }
-
- /** @hide */
- public int getDexMethodIndex() {
- return methodDexIndex;
- }
-
- @Override /*package*/ String getSignatureAttribute() {
- Object[] annotation = Method.getSignatureAnnotation(declaringClass, slot);
-
- if (annotation == null) {
- return null;
- }
-
- return StringUtils.combineStrings(annotation);
- }
-
- public TypeVariable<Constructor<T>>[] getTypeParameters() {
- initGenericTypes();
- return formalTypeParameters.clone();
- }
-
- /**
- * Returns the string representation of the constructor's declaration,
- * including the type parameters.
- *
- * @return the string representation of the constructor's declaration
- */
- public String toGenericString() {
- StringBuilder sb = new StringBuilder(80);
- initGenericTypes();
- // append modifiers if any
- int modifier = getModifiers();
- if (modifier != 0) {
- sb.append(Modifier.toString(modifier & ~Modifier.VARARGS)).append(' ');
- }
- // append type parameters
- if (formalTypeParameters != null && formalTypeParameters.length > 0) {
- sb.append('<');
- for (int i = 0; i < formalTypeParameters.length; i++) {
- appendGenericType(sb, formalTypeParameters[i]);
- if (i < formalTypeParameters.length - 1) {
- sb.append(",");
- }
- }
- sb.append("> ");
- }
- // append constructor name
- appendTypeName(sb, getDeclaringClass());
- // append parameters
- sb.append('(');
- appendArrayGenericType(sb, Types.getTypeArray(genericParameterTypes, false));
- sb.append(')');
- // append exceptions if any
- Type[] genericExceptionTypeArray = Types.getTypeArray(genericExceptionTypes, false);
- if (genericExceptionTypeArray.length > 0) {
- sb.append(" throws ");
- appendArrayGenericType(sb, genericExceptionTypeArray);
- }
- return sb.toString();
- }
-
- /**
- * Returns the generic parameter types as an array of {@code Type}
- * instances, in declaration order. If this constructor has no generic
- * parameters, an empty array is returned.
- *
- * @return the parameter types
- *
- * @throws GenericSignatureFormatError
- * if the generic constructor signature is invalid
- * @throws TypeNotPresentException
- * if any parameter type points to a missing type
- * @throws MalformedParameterizedTypeException
- * if any parameter type points to a type that cannot be
- * instantiated for some reason
- */
- public Type[] getGenericParameterTypes() {
- initGenericTypes();
- return Types.getTypeArray(genericParameterTypes, true);
- }
-
- /**
- * Returns the exception types as an array of {@code Type} instances. If
- * this constructor has no declared exceptions, an empty array will be
- * returned.
- *
- * @return an array of generic exception types
- *
- * @throws GenericSignatureFormatError
- * if the generic constructor signature is invalid
- * @throws TypeNotPresentException
- * if any exception type points to a missing type
- * @throws MalformedParameterizedTypeException
- * if any exception type points to a type that cannot be
- * instantiated for some reason
- */
- public Type[] getGenericExceptionTypes() {
- initGenericTypes();
- return Types.getTypeArray(genericExceptionTypes, true);
- }
-
- @Override
- public Annotation[] getDeclaredAnnotations() {
- return Method.getDeclaredAnnotations(declaringClass, slot);
- }
-
- @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
- if (annotationType == null) {
- throw new NullPointerException("annotationType == null");
- }
- return Method.getAnnotation(declaringClass, slot, annotationType);
- }
-
- @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
- if (annotationType == null) {
- throw new NullPointerException("annotationType == null");
- }
- return Method.isAnnotationPresent(declaringClass, slot, annotationType);
- }
-
- /**
- * Returns an array of arrays that represent the annotations of the formal
- * parameters of this constructor. If there are no parameters on this
- * constructor, then an empty array is returned. If there are no annotations
- * set, then an array of empty arrays is returned.
- *
- * @return an array of arrays of {@code Annotation} instances
- */
- public Annotation[][] getParameterAnnotations() {
- Annotation[][] parameterAnnotations
- = Method.getParameterAnnotations(declaringClass, slot);
- if (parameterAnnotations.length == 0) {
- return Method.noAnnotations(parameterTypes.length);
- }
- return parameterAnnotations;
- }
-
- /**
- * Indicates whether or not this constructor takes a variable number of
- * arguments.
- *
- * @return {@code true} if a vararg is declare, otherwise
- * {@code false}
- */
- public boolean isVarArgs() {
- int mods = Method.getMethodModifiers(declaringClass, slot);
- return (mods & Modifier.VARARGS) != 0;
- }
-
- /**
- * Indicates whether or not this constructor is synthetic (artificially
- * introduced by the compiler).
- *
- * @return {@code true} if this constructor is synthetic, {@code false}
- * otherwise
- */
- public boolean isSynthetic() {
- int mods = Method.getMethodModifiers(declaringClass, slot);
- return (mods & Modifier.SYNTHETIC) != 0;
- }
-
- /**
- * Indicates whether or not the specified {@code object} is equal to this
- * constructor. To be equal, the specified object must be an instance
- * of {@code Constructor} with the same declaring class and parameter types
- * as this constructor.
- *
- * @param object
- * the object to compare
- *
- * @return {@code true} if the specified object is equal to this
- * constructor, {@code false} otherwise
- *
- * @see #hashCode
- */
- @Override
- public boolean equals(Object object) {
- return object instanceof Constructor && toString().equals(object.toString());
- }
-
- /**
- * Returns the class that declares this constructor.
- *
- * @return the declaring class
- */
- public Class<T> getDeclaringClass() {
- return declaringClass;
- }
-
- /**
- * Returns the exception types as an array of {@code Class} instances. If
- * this constructor has no declared exceptions, an empty array will be
- * returned.
- *
- * @return the declared exception classes
- */
- public Class<?>[] getExceptionTypes() {
- if (exceptionTypes == null) {
- return EmptyArray.CLASS;
- }
- return exceptionTypes.clone();
- }
-
- /**
- * Returns the modifiers for this constructor. The {@link Modifier} class
- * should be used to decode the result.
- *
- * @return the modifiers for this constructor
- *
- * @see Modifier
- */
- public int getModifiers() {
- return Method.getMethodModifiers(declaringClass, slot);
- }
-
- /**
- * Returns the name of this constructor.
- *
- * @return the name of this constructor
- */
- public String getName() {
- return declaringClass.getName();
- }
-
- /**
- * Returns an array of the {@code Class} objects associated with the
- * parameter types of this constructor. If the constructor was declared with
- * no parameters, an empty array will be returned.
- *
- * @return the parameter types
- */
- public Class<?>[] getParameterTypes() {
- return parameterTypes.clone();
- }
-
- /**
- * Returns the constructor's signature in non-printable form. This is called
- * (only) from IO native code and needed for deriving the serialVersionUID
- * of the class
- *
- * @return the constructor's signature
- */
- @SuppressWarnings("unused")
- private String getSignature() {
- StringBuilder result = new StringBuilder();
-
- result.append('(');
- for (int i = 0; i < parameterTypes.length; i++) {
- result.append(getSignature(parameterTypes[i]));
- }
- result.append(")V");
-
- return result.toString();
- }
-
- /**
- * Returns an integer hash code for this constructor. Constructors which are
- * equal return the same value for this method. The hash code for a
- * Constructor is the hash code of the name of the declaring class.
- *
- * @return the hash code
- *
- * @see #equals
- */
- @Override
- public int hashCode() {
- return declaringClass.getName().hashCode();
- }
-
- /**
- * Returns a new instance of the declaring class, initialized by dynamically
- * invoking the constructor represented by this {@code Constructor} object.
- * This reproduces the effect of {@code new declaringClass(arg1, arg2, ... ,
- * argN)} This method performs the following:
- * <ul>
- * <li>A new instance of the declaring class is created. If the declaring
- * class cannot be instantiated (i.e. abstract class, an interface, an array
- * type, or a primitive type) then an InstantiationException is thrown.</li>
- * <li>If this Constructor object is enforcing access control (see
- * {@link AccessibleObject}) and this constructor is not accessible from the
- * current context, an IllegalAccessException is thrown.</li>
- * <li>If the number of arguments passed and the number of parameters do not
- * match, an IllegalArgumentException is thrown.</li>
- * <li>For each argument passed:
- * <ul>
- * <li>If the corresponding parameter type is a primitive type, the argument
- * is unboxed. If the unboxing fails, an IllegalArgumentException is
- * thrown.</li>
- * <li>If the resulting argument cannot be converted to the parameter type
- * via a widening conversion, an IllegalArgumentException is thrown.</li>
- * </ul>
- * <li>The constructor represented by this {@code Constructor} object is
- * then invoked. If an exception is thrown during the invocation, it is
- * caught and wrapped in an InvocationTargetException. This exception is
- * then thrown. If the invocation completes normally, the newly initialized
- * object is returned.
- * </ul>
- *
- * @param args
- * the arguments to the constructor
- *
- * @return the new, initialized, object
- *
- * @exception InstantiationException
- * if the class cannot be instantiated
- * @exception IllegalAccessException
- * if this constructor is not accessible
- * @exception IllegalArgumentException
- * if an incorrect number of arguments are passed, or an
- * argument could not be converted by a widening conversion
- * @exception InvocationTargetException
- * if an exception was thrown by the invoked constructor
- *
- * @see AccessibleObject
- */
- public T newInstance(Object... args) throws InstantiationException, IllegalAccessException,
- IllegalArgumentException, InvocationTargetException {
- return constructNative (args, declaringClass, parameterTypes, slot, flag);
- }
-
- private native T constructNative(Object[] args, Class<T> declaringClass,
- Class<?>[] parameterTypes, int slot,
- boolean noAccessCheck) throws InstantiationException, IllegalAccessException,
- InvocationTargetException;
-
- /**
- * Returns a string containing a concise, human-readable description of this
- * constructor. The format of the string is:
- *
- * <ol>
- * <li>modifiers (if any)
- * <li>declaring class name
- * <li>'('
- * <li>parameter types, separated by ',' (if any)
- * <li>')'
- * <li>'throws' plus exception types, separated by ',' (if any)
- * </ol>
- *
- * For example:
- * {@code public String(byte[],String) throws UnsupportedEncodingException}
- *
- * @return a printable representation for this constructor
- */
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
-
- if (result.length() != 0)
- result.append(' ');
- result.append(declaringClass.getName());
- result.append("(");
- result.append(toString(parameterTypes));
- result.append(")");
- if (exceptionTypes != null && exceptionTypes.length != 0) {
- result.append(" throws ");
- result.append(toString(exceptionTypes));
- }
-
- return result.toString();
- }
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/Field.java b/libdvm/src/main/java/java/lang/reflect/Field.java
deleted file mode 100644
index fa8e5e7..0000000
--- a/libdvm/src/main/java/java/lang/reflect/Field.java
+++ /dev/null
@@ -1,931 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.util.Comparator;
-import org.apache.harmony.kernel.vm.StringUtils;
-import libcore.reflect.GenericSignatureParser;
-import libcore.reflect.Types;
-
-/**
- * This class represents a field. Information about the field can be accessed,
- * and the field's value can be accessed dynamically.
- */
-public final class Field extends AccessibleObject implements Member {
-
- /**
- * Orders fields by their name and declaring class.
- *
- * @hide
- */
- public static final Comparator<Field> ORDER_BY_NAME_AND_DECLARING_CLASS
- = new Comparator<Field>() {
- @Override public int compare(Field a, Field b) {
- int comparison = a.name.compareTo(b.name);
- if (comparison != 0) {
- return comparison;
- }
-
- return a.getDeclaringClass().getName().compareTo(b.getDeclaringClass().getName());
- }
- };
-
- private Class<?> declaringClass;
-
- private Class<?> type;
-
- private Type genericType;
-
- private volatile boolean genericTypesAreInitialized = false;
-
- private String name;
-
- private int slot;
-
- private final int fieldDexIndex;
-
- private static final char TYPE_BOOLEAN = 'Z';
-
- private static final char TYPE_BYTE = 'B';
-
- private static final char TYPE_CHAR = 'C';
-
- private static final char TYPE_SHORT = 'S';
-
- private static final char TYPE_INTEGER = 'I';
-
- private static final char TYPE_FLOAT = 'F';
-
- private static final char TYPE_LONG = 'J';
-
- private static final char TYPE_DOUBLE = 'D';
-
- private Field(Class<?> declaringClass, Class<?> type, String name, int slot, int fieldDexIndex) {
- this.declaringClass = declaringClass;
- this.type = type;
- this.name = name;
- this.slot = slot;
- this.fieldDexIndex = fieldDexIndex;
- }
-
- /**
- * Returns the index of this field's ID in its dex file.
- * @hide
- */
- public int getDexFieldIndex() {
- return fieldDexIndex;
- }
-
- private synchronized void initGenericType() {
- if (!genericTypesAreInitialized) {
- String signatureAttribute = getSignatureAttribute();
- GenericSignatureParser parser = new GenericSignatureParser(
- declaringClass.getClassLoader());
- parser.parseForField(this.declaringClass, signatureAttribute);
- genericType = parser.fieldType;
- if (genericType == null) {
- genericType = getType();
- }
- genericTypesAreInitialized = true;
- }
- }
-
- /** {@inheritDoc} */
- @Override
- /* package */String getSignatureAttribute() {
- Object[] annotation = getSignatureAnnotation(declaringClass, slot);
-
- if (annotation == null) {
- return null;
- }
-
- return StringUtils.combineStrings(annotation);
- }
-
- /**
- * Get the Signature annotation for this field. Returns null if not found.
- */
- native private Object[] getSignatureAnnotation(Class declaringClass, int slot);
-
- /**
- * Indicates whether or not this field is synthetic.
- *
- * @return {@code true} if this field is synthetic, {@code false} otherwise
- */
- public boolean isSynthetic() {
- int flags = getFieldModifiers(declaringClass, slot);
- return (flags & Modifier.SYNTHETIC) != 0;
- }
-
- /**
- * Returns the string representation of this field, including the field's
- * generic type.
- *
- * @return the string representation of this field
- */
- public String toGenericString() {
- StringBuilder sb = new StringBuilder(80);
- // append modifiers if any
- int modifier = getModifiers();
- if (modifier != 0) {
- sb.append(Modifier.toString(modifier)).append(' ');
- }
- // append generic type
- appendGenericType(sb, getGenericType());
- sb.append(' ');
- // append full field name
- sb.append(getDeclaringClass().getName()).append('.').append(getName());
- return sb.toString();
- }
-
- /**
- * Indicates whether or not this field is an enumeration constant.
- *
- * @return {@code true} if this field is an enumeration constant, {@code
- * false} otherwise
- */
- public boolean isEnumConstant() {
- int flags = getFieldModifiers(declaringClass, slot);
- return (flags & Modifier.ENUM) != 0;
- }
-
- /**
- * Returns the generic type of this field.
- *
- * @return the generic type
- * @throws GenericSignatureFormatError
- * if the generic field signature is invalid
- * @throws TypeNotPresentException
- * if the generic type points to a missing type
- * @throws MalformedParameterizedTypeException
- * if the generic type points to a type that cannot be
- * instantiated for some reason
- */
- public Type getGenericType() {
- initGenericType();
- return Types.getType(genericType);
- }
-
- @Override public Annotation[] getDeclaredAnnotations() {
- return getDeclaredAnnotations(declaringClass, slot);
- }
- private static native Annotation[] getDeclaredAnnotations(Class declaringClass, int slot);
-
- @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
- if (annotationType == null) {
- throw new NullPointerException("annotationType == null");
- }
- return getAnnotation(declaringClass, slot, annotationType);
- }
- private static native <A extends Annotation> A getAnnotation(
- Class<?> declaringClass, int slot, Class<A> annotationType);
-
- @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
- if (annotationType == null) {
- throw new NullPointerException("annotationType == null");
- }
- return isAnnotationPresent(declaringClass, slot, annotationType);
- }
- private static native boolean isAnnotationPresent(
- Class<?> declaringClass, int slot, Class<? extends Annotation> annotationType);
-
- /**
- * Indicates whether or not the specified {@code object} is equal to this
- * field. To be equal, the specified object must be an instance of
- * {@code Field} with the same declaring class, type and name as this field.
- *
- * @param object
- * the object to compare
- * @return {@code true} if the specified object is equal to this method,
- * {@code false} otherwise
- * @see #hashCode
- */
- @Override
- public boolean equals(Object object) {
- return object instanceof Field && toString().equals(object.toString());
- }
-
- /**
- * Returns the value of the field in the specified object. This reproduces
- * the effect of {@code object.fieldName}
- *
- * <p>If the type of this field is a primitive type, the field value is
- * automatically boxed.
- *
- * <p>If this field is static, the object argument is ignored.
- * Otherwise, if the object is null, a NullPointerException is thrown. If
- * the object is not an instance of the declaring class of the method, an
- * IllegalArgumentException is thrown.
- *
- * <p>If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value, possibly boxed
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public Object get(Object object) throws IllegalAccessException, IllegalArgumentException {
- return getField(object, declaringClass, type, slot, flag);
- }
-
- /**
- * Returns the value of the field in the specified object as a {@code
- * boolean}. This reproduces the effect of {@code object.fieldName}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public boolean getBoolean(Object object) throws IllegalAccessException,
- IllegalArgumentException {
- return getZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN);
- }
-
- /**
- * Returns the value of the field in the specified object as a {@code byte}.
- * This reproduces the effect of {@code object.fieldName}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException {
- return getBField(object, declaringClass, type, slot, flag, TYPE_BYTE);
- }
-
- /**
- * Returns the value of the field in the specified object as a {@code char}.
- * This reproduces the effect of {@code object.fieldName}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public char getChar(Object object) throws IllegalAccessException, IllegalArgumentException {
- return getCField(object, declaringClass, type, slot, flag, TYPE_CHAR);
- }
-
- /**
- * Returns the class that declares this field.
- *
- * @return the declaring class
- */
- public Class<?> getDeclaringClass() {
- return declaringClass;
- }
-
- /**
- * Returns the value of the field in the specified object as a {@code
- * double}. This reproduces the effect of {@code object.fieldName}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException {
- return getDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE);
- }
-
- /**
- * Returns the value of the field in the specified object as a {@code float}
- * . This reproduces the effect of {@code object.fieldName}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException {
- return getFField(object, declaringClass, type, slot, flag, TYPE_FLOAT);
- }
-
- /**
- * Returns the value of the field in the specified object as an {@code int}.
- * This reproduces the effect of {@code object.fieldName}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public int getInt(Object object) throws IllegalAccessException, IllegalArgumentException {
- return getIField(object, declaringClass, type, slot, flag, TYPE_INTEGER);
- }
-
- /**
- * Returns the value of the field in the specified object as a {@code long}.
- * This reproduces the effect of {@code object.fieldName}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public long getLong(Object object) throws IllegalAccessException, IllegalArgumentException {
- return getJField(object, declaringClass, type, slot, flag, TYPE_LONG);
- }
-
- /**
- * Returns the modifiers for this field. The {@link Modifier} class should
- * be used to decode the result.
- *
- * @return the modifiers for this field
- * @see Modifier
- */
- public int getModifiers() {
- return getFieldModifiers(declaringClass, slot);
- }
-
- private native int getFieldModifiers(Class<?> declaringClass, int slot);
-
- /**
- * Returns the name of this field.
- *
- * @return the name of this field
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the value of the field in the specified object as a {@code short}
- * . This reproduces the effect of {@code object.fieldName}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * @param object
- * the object to access
- * @return the field value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException {
- return getSField(object, declaringClass, type, slot, flag, TYPE_SHORT);
- }
-
- /**
- * Returns the constructor's signature in non-printable form. This is called
- * (only) from IO native code and needed for deriving the serialVersionUID
- * of the class
- *
- * @return the constructor's signature.
- */
- @SuppressWarnings("unused")
- private String getSignature() {
- return getSignature(type);
- }
-
- /**
- * Return the {@link Class} associated with the type of this field.
- *
- * @return the type of this field
- */
- public Class<?> getType() {
- return type;
- }
-
- /**
- * Returns an integer hash code for this field. Objects which are equal
- * return the same value for this method.
- * <p>
- * The hash code for a Field is the exclusive-or combination of the hash
- * code of the field's name and the hash code of the name of its declaring
- * class.
- *
- * @return the hash code for this field
- * @see #equals
- */
- @Override
- public int hashCode() {
- return name.hashCode() ^ getDeclaringClass().getName().hashCode();
- }
-
- /**
- * Sets the value of the field in the specified object to the value. This
- * reproduces the effect of {@code object.fieldName = value}
- *
- * <p>If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- *
- * <p>If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- *
- * <p>If the field type is a primitive type, the value is automatically
- * unboxed. If the unboxing fails, an IllegalArgumentException is thrown. If
- * the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void set(Object object, Object value) throws IllegalAccessException,
- IllegalArgumentException {
- setField(object, declaringClass, type, slot, flag, value);
- }
-
- /**
- * Sets the value of the field in the specified object to the {@code
- * boolean} value. This reproduces the effect of {@code object.fieldName =
- * value}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- * <p>
- * If the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void setBoolean(Object object, boolean value) throws IllegalAccessException,
- IllegalArgumentException {
- setZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN, value);
- }
-
- /**
- * Sets the value of the field in the specified object to the {@code byte}
- * value. This reproduces the effect of {@code object.fieldName = value}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- * <p>
- * If the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void setByte(Object object, byte value) throws IllegalAccessException,
- IllegalArgumentException {
- setBField(object, declaringClass, type, slot, flag, TYPE_BYTE, value);
- }
-
- /**
- * Sets the value of the field in the specified object to the {@code char}
- * value. This reproduces the effect of {@code object.fieldName = value}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- * <p>
- * If the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void setChar(Object object, char value) throws IllegalAccessException,
- IllegalArgumentException {
- setCField(object, declaringClass, type, slot, flag, TYPE_CHAR, value);
- }
-
- /**
- * Sets the value of the field in the specified object to the {@code double}
- * value. This reproduces the effect of {@code object.fieldName = value}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- * <p>
- * If the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void setDouble(Object object, double value) throws IllegalAccessException,
- IllegalArgumentException {
- setDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE, value);
- }
-
- /**
- * Sets the value of the field in the specified object to the {@code float}
- * value. This reproduces the effect of {@code object.fieldName = value}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- * <p>
- * If the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void setFloat(Object object, float value) throws IllegalAccessException,
- IllegalArgumentException {
- setFField(object, declaringClass, type, slot, flag, TYPE_FLOAT, value);
- }
-
- /**
- * Set the value of the field in the specified object to the {@code int}
- * value. This reproduces the effect of {@code object.fieldName = value}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- * <p>
- * If the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void setInt(Object object, int value) throws IllegalAccessException,
- IllegalArgumentException {
- setIField(object, declaringClass, type, slot, flag, TYPE_INTEGER, value);
- }
-
- /**
- * Sets the value of the field in the specified object to the {@code long}
- * value. This reproduces the effect of {@code object.fieldName = value}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- * <p>
- * If the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void setLong(Object object, long value) throws IllegalAccessException,
- IllegalArgumentException {
- setJField(object, declaringClass, type, slot, flag, TYPE_LONG, value);
- }
-
- /**
- * Sets the value of the field in the specified object to the {@code short}
- * value. This reproduces the effect of {@code object.fieldName = value}
- * <p>
- * If this field is static, the object argument is ignored.
- * Otherwise, if the object is {@code null}, a NullPointerException is
- * thrown. If the object is not an instance of the declaring class of the
- * method, an IllegalArgumentException is thrown.
- * <p>
- * If this Field object is enforcing access control (see AccessibleObject)
- * and this field is not accessible from the current context, an
- * IllegalAccessException is thrown.
- * <p>
- * If the value cannot be converted to the field type via a widening
- * conversion, an IllegalArgumentException is thrown.
- *
- * @param object
- * the object to access
- * @param value
- * the new value
- * @throws NullPointerException
- * if the object is {@code null} and the field is non-static
- * @throws IllegalArgumentException
- * if the object is not compatible with the declaring class
- * @throws IllegalAccessException
- * if this field is not accessible
- */
- public void setShort(Object object, short value) throws IllegalAccessException,
- IllegalArgumentException {
- setSField(object, declaringClass, type, slot, flag, TYPE_SHORT, value);
- }
-
- /**
- * Returns a string containing a concise, human-readable description of this
- * field.
- * <p>
- * The format of the string is:
- * <ol>
- * <li>modifiers (if any)
- * <li>type
- * <li>declaring class name
- * <li>'.'
- * <li>field name
- * </ol>
- * <p>
- * For example: {@code public static java.io.InputStream
- * java.lang.System.in}
- *
- * @return a printable representation for this field
- */
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
- if (result.length() != 0) {
- result.append(' ');
- }
- appendTypeName(result, type);
- result.append(' ');
- appendTypeName(result, declaringClass);
- result.append('.');
- result.append(name);
- return result.toString();
- }
-
- private native Object getField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck) throws IllegalAccessException;
-
- private native double getDField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
- private native int getIField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
- private native long getJField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
- private native boolean getZField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
- private native float getFField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
- private native char getCField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
- private native short getSField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
- private native byte getBField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
- private native void setField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, Object value) throws IllegalAccessException;
-
- private native void setDField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor, double v) throws IllegalAccessException;
-
- private native void setIField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor, int i) throws IllegalAccessException;
-
- private native void setJField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor, long j) throws IllegalAccessException;
-
- private native void setZField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor, boolean z) throws IllegalAccessException;
-
- private native void setFField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor, float f) throws IllegalAccessException;
-
- private native void setCField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor, char c) throws IllegalAccessException;
-
- private native void setSField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor, short s) throws IllegalAccessException;
-
- private native void setBField(Object o, Class<?> declaringClass, Class<?> type, int slot,
- boolean noAccessCheck, char descriptor, byte b) throws IllegalAccessException;
-
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/Method.java b/libdvm/src/main/java/java/lang/reflect/Method.java
deleted file mode 100644
index f8efbf4..0000000
--- a/libdvm/src/main/java/java/lang/reflect/Method.java
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.util.Arrays;
-import java.util.Comparator;
-import libcore.util.EmptyArray;
-import org.apache.harmony.kernel.vm.StringUtils;
-import libcore.reflect.GenericSignatureParser;
-import libcore.reflect.ListOfTypes;
-import libcore.reflect.Types;
-
-/**
- * This class represents a method. Information about the method can be accessed,
- * and the method can be invoked dynamically.
- */
-public final class Method extends AccessibleObject implements GenericDeclaration, Member {
-
- /**
- * Orders methods by their name, parameters and return type.
- *
- * @hide
- */
- public static final Comparator<Method> ORDER_BY_SIGNATURE = new Comparator<Method>() {
- public int compare(Method a, Method b) {
- int comparison = a.name.compareTo(b.name);
- if (comparison != 0) {
- return comparison;
- }
-
- Class<?>[] aParameters = a.parameterTypes;
- Class<?>[] bParameters = b.parameterTypes;
- int length = Math.min(aParameters.length, bParameters.length);
- for (int i = 0; i < length; i++) {
- comparison = aParameters[i].getName().compareTo(bParameters[i].getName());
- if (comparison != 0) {
- return comparison;
- }
- }
-
- if (aParameters.length != bParameters.length) {
- return aParameters.length - bParameters.length;
- }
-
- // this is necessary for methods that have covariant return types.
- return a.getReturnType().getName().compareTo(b.getReturnType().getName());
- }
- };
-
- private int slot;
-
- private final int methodDexIndex;
-
- private Class<?> declaringClass;
-
- private String name;
-
- private Class<?>[] parameterTypes;
-
- private Class<?>[] exceptionTypes;
-
- private Class<?> returnType;
-
- private ListOfTypes genericExceptionTypes;
- private ListOfTypes genericParameterTypes;
- private Type genericReturnType;
- private TypeVariable<Method>[] formalTypeParameters;
- private volatile boolean genericTypesAreInitialized = false;
-
- private synchronized void initGenericTypes() {
- if (!genericTypesAreInitialized) {
- String signatureAttribute = getSignatureAttribute();
- GenericSignatureParser parser = new GenericSignatureParser(
- declaringClass.getClassLoader());
- parser.parseForMethod(this, signatureAttribute, exceptionTypes);
- formalTypeParameters = parser.formalTypeParameters;
- genericParameterTypes = parser.parameterTypes;
- genericExceptionTypes = parser.exceptionTypes;
- genericReturnType = parser.returnType;
- genericTypesAreInitialized = true;
- }
- }
-
- private Method(Class<?> declaring, Class<?>[] paramTypes, Class<?>[] exceptTypes, Class<?> returnType, String name, int slot, int methodDexIndex) {
- this.declaringClass = declaring;
- this.name = name;
- this.slot = slot;
- this.parameterTypes = paramTypes;
- this.exceptionTypes = exceptTypes; // may be null
- this.returnType = returnType;
- this.methodDexIndex = methodDexIndex;
- }
-
- /** @hide */
- public int getDexMethodIndex() {
- return methodDexIndex;
- }
-
- public TypeVariable<Method>[] getTypeParameters() {
- initGenericTypes();
- return formalTypeParameters.clone();
- }
-
- /** {@inheritDoc} */
- @Override /*package*/ String getSignatureAttribute() {
- Object[] annotation = getSignatureAnnotation(declaringClass, slot);
-
- if (annotation == null) {
- return null;
- }
-
- return StringUtils.combineStrings(annotation);
- }
-
- /**
- * Returns the Signature annotation for this method. Returns {@code null} if
- * not found.
- */
- static native Object[] getSignatureAnnotation(Class declaringClass, int slot);
-
- /**
- * Returns the string representation of the method's declaration, including
- * the type parameters.
- *
- * @return the string representation of this method
- */
- public String toGenericString() {
- StringBuilder sb = new StringBuilder(80);
-
- initGenericTypes();
-
- // append modifiers if any
- int modifier = getModifiers();
- if (modifier != 0) {
- sb.append(Modifier.toString(modifier & ~(Modifier.BRIDGE +
- Modifier.VARARGS))).append(' ');
- }
- // append type parameters
- if (formalTypeParameters != null && formalTypeParameters.length > 0) {
- sb.append('<');
- for (int i = 0; i < formalTypeParameters.length; i++) {
- appendGenericType(sb, formalTypeParameters[i]);
- if (i < formalTypeParameters.length - 1) {
- sb.append(",");
- }
- }
- sb.append("> ");
- }
- // append return type
- appendGenericType(sb, Types.getType(genericReturnType));
- sb.append(' ');
- // append method name
- appendTypeName(sb, getDeclaringClass());
- sb.append(".").append(getName());
- // append parameters
- sb.append('(');
- appendArrayGenericType(sb, Types.getTypeArray(genericParameterTypes, false));
- sb.append(')');
- // append exceptions if any
- Type[] genericExceptionTypeArray = Types.getTypeArray(genericExceptionTypes, false);
- if (genericExceptionTypeArray.length > 0) {
- sb.append(" throws ");
- appendArrayGenericType(sb, genericExceptionTypeArray);
- }
- return sb.toString();
- }
-
- /**
- * Returns the parameter types as an array of {@code Type} instances, in
- * declaration order. If this method has no parameters, an empty array is
- * returned.
- *
- * @return the parameter types
- *
- * @throws GenericSignatureFormatError
- * if the generic method signature is invalid
- * @throws TypeNotPresentException
- * if any parameter type points to a missing type
- * @throws MalformedParameterizedTypeException
- * if any parameter type points to a type that cannot be
- * instantiated for some reason
- */
- public Type[] getGenericParameterTypes() {
- initGenericTypes();
- return Types.getTypeArray(genericParameterTypes, true);
- }
-
- /**
- * Returns the exception types as an array of {@code Type} instances. If
- * this method has no declared exceptions, an empty array will be returned.
- *
- * @return an array of generic exception types
- *
- * @throws GenericSignatureFormatError
- * if the generic method signature is invalid
- * @throws TypeNotPresentException
- * if any exception type points to a missing type
- * @throws MalformedParameterizedTypeException
- * if any exception type points to a type that cannot be
- * instantiated for some reason
- */
- public Type[] getGenericExceptionTypes() {
- initGenericTypes();
- return Types.getTypeArray(genericExceptionTypes, true);
- }
-
- /**
- * Returns the return type of this method as a {@code Type} instance.
- *
- * @return the return type of this method
- *
- * @throws GenericSignatureFormatError
- * if the generic method signature is invalid
- * @throws TypeNotPresentException
- * if the return type points to a missing type
- * @throws MalformedParameterizedTypeException
- * if the return type points to a type that cannot be
- * instantiated for some reason
- */
- public Type getGenericReturnType() {
- initGenericTypes();
- return Types.getType(genericReturnType);
- }
-
- @Override
- public Annotation[] getDeclaredAnnotations() {
- return getDeclaredAnnotations(declaringClass, slot);
- }
- static native Annotation[] getDeclaredAnnotations(Class<?> declaringClass, int slot);
-
- @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
- if (annotationType == null) {
- throw new NullPointerException("annotationType == null");
- }
- return getAnnotation(declaringClass, slot, annotationType);
- }
- static native <A extends Annotation> A getAnnotation(
- Class<?> declaringClass, int slot, Class<A> annotationType);
-
- @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
- if (annotationType == null) {
- throw new NullPointerException("annotationType == null");
- }
- return isAnnotationPresent(declaringClass, slot, annotationType);
- }
- static native boolean isAnnotationPresent(
- Class<?> declaringClass, int slot, Class<? extends Annotation> annotationType);
-
- private static final Annotation[] NO_ANNOTATIONS = new Annotation[0];
-
- /**
- * Creates an array of empty Annotation arrays.
- */
- /*package*/ static Annotation[][] noAnnotations(int size) {
- Annotation[][] annotations = new Annotation[size][];
- for (int i = 0; i < size; i++) {
- annotations[i] = NO_ANNOTATIONS;
- }
- return annotations;
- }
-
- /**
- * Returns an array of arrays that represent the annotations of the formal
- * parameters of this method. If there are no parameters on this method,
- * then an empty array is returned. If there are no annotations set, then
- * and array of empty arrays is returned.
- *
- * @return an array of arrays of {@code Annotation} instances
- */
- public Annotation[][] getParameterAnnotations() {
- Annotation[][] parameterAnnotations
- = getParameterAnnotations(declaringClass, slot);
- if (parameterAnnotations.length == 0) {
- return noAnnotations(parameterTypes.length);
- }
- return parameterAnnotations;
- }
-
- static native Annotation[][] getParameterAnnotations(Class declaringClass, int slot);
-
- /**
- * Indicates whether or not this method takes a variable number argument.
- *
- * @return {@code true} if a vararg is declared, {@code false} otherwise
- */
- public boolean isVarArgs() {
- int modifiers = getMethodModifiers(declaringClass, slot);
- return (modifiers & Modifier.VARARGS) != 0;
- }
-
- /**
- * Indicates whether or not this method is a bridge.
- *
- * @return {@code true} if this method is a bridge, {@code false} otherwise
- */
- public boolean isBridge() {
- int modifiers = getMethodModifiers(declaringClass, slot);
- return (modifiers & Modifier.BRIDGE) != 0;
- }
-
- /**
- * Indicates whether or not this method is synthetic.
- *
- * @return {@code true} if this method is synthetic, {@code false} otherwise
- */
- public boolean isSynthetic() {
- int modifiers = getMethodModifiers(declaringClass, slot);
- return (modifiers & Modifier.SYNTHETIC) != 0;
- }
-
- /**
- * Returns the default value for the annotation member represented by this
- * method.
- *
- * @return the default value, or {@code null} if none
- *
- * @throws TypeNotPresentException
- * if this annotation member is of type {@code Class} and no
- * definition can be found
- */
- public Object getDefaultValue() {
- return getDefaultValue(declaringClass, slot);
- }
- native private Object getDefaultValue(Class declaringClass, int slot);
-
- /**
- * Indicates whether or not the specified {@code object} is equal to this
- * method. To be equal, the specified object must be an instance
- * of {@code Method} with the same declaring class and parameter types
- * as this method.
- *
- * @param object
- * the object to compare
- *
- * @return {@code true} if the specified object is equal to this
- * method, {@code false} otherwise
- *
- * @see #hashCode
- */
- @Override
- public boolean equals(Object object) {
- if (this == object) {
- return true;
- }
- if (!(object instanceof Method)) {
- return false;
- }
- Method rhs = (Method) object;
- // We don't compare exceptionTypes because two methods
- // can't differ only by their declared exceptions.
- return declaringClass.equals(rhs.declaringClass) &&
- name.equals(rhs.name) &&
- getModifiers() == rhs.getModifiers() &&
- returnType.equals(rhs.returnType) &&
- Arrays.equals(parameterTypes, rhs.parameterTypes);
- }
-
- /**
- * Returns the class that declares this method.
- *
- * @return the declaring class
- */
- public Class<?> getDeclaringClass() {
- return declaringClass;
- }
-
- /**
- * Returns the exception types as an array of {@code Class} instances. If
- * this method has no declared exceptions, an empty array is returned.
- *
- * @return the declared exception classes
- */
- public Class<?>[] getExceptionTypes() {
- if (exceptionTypes == null) {
- return EmptyArray.CLASS;
- }
- return exceptionTypes.clone();
- }
-
- /**
- * Returns the modifiers for this method. The {@link Modifier} class should
- * be used to decode the result.
- *
- * @return the modifiers for this method
- *
- * @see Modifier
- */
- public int getModifiers() {
- return getMethodModifiers(declaringClass, slot);
- }
-
- static native int getMethodModifiers(Class<?> declaringClass, int slot);
-
- /**
- * Returns the name of the method represented by this {@code Method}
- * instance.
- *
- * @return the name of this method
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns an array of {@code Class} objects associated with the parameter
- * types of this method. If the method was declared with no parameters, an
- * empty array will be returned.
- *
- * @return the parameter types
- */
- public Class<?>[] getParameterTypes() {
- return parameterTypes.clone();
- }
-
- /**
- * Returns the {@code Class} associated with the return type of this
- * method.
- *
- * @return the return type
- */
- public Class<?> getReturnType() {
- return returnType;
- }
-
- /**
- * Returns an integer hash code for this method. Objects which are equal
- * return the same value for this method. The hash code for this Method is
- * the hash code of the name of this method.
- *
- * @return hash code for this method
- *
- * @see #equals
- */
- @Override
- public int hashCode() {
- return name.hashCode();
- }
-
- /**
- * Returns the result of dynamically invoking this method. Equivalent to
- * {@code receiver.methodName(arg1, arg2, ... , argN)}.
- *
- * <p>If the method is static, the receiver argument is ignored (and may be null).
- *
- * <p>If the method takes no arguments, you can pass {@code (Object[]) null} instead of
- * allocating an empty array.
- *
- * <p>If you're calling a varargs method, you need to pass an {@code Object[]} for the
- * varargs parameter: that conversion is usually done in {@code javac}, not the VM, and
- * the reflection machinery does not do this for you. (It couldn't, because it would be
- * ambiguous.)
- *
- * <p>Reflective method invocation follows the usual process for method lookup.
- *
- * <p>If an exception is thrown during the invocation it is caught and
- * wrapped in an InvocationTargetException. This exception is then thrown.
- *
- * <p>If the invocation completes normally, the return value itself is
- * returned. If the method is declared to return a primitive type, the
- * return value is boxed. If the return type is void, null is returned.
- *
- * @param receiver
- * the object on which to call this method (or null for static methods)
- * @param args
- * the arguments to the method
- * @return the result
- *
- * @throws NullPointerException
- * if {@code receiver == null} for a non-static method
- * @throws IllegalAccessException
- * if this method is not accessible (see {@link AccessibleObject})
- * @throws IllegalArgumentException
- * if the number of arguments doesn't match the number of parameters, the receiver
- * is incompatible with the declaring class, or an argument could not be unboxed
- * or converted by a widening conversion to the corresponding parameter type
- * @throws InvocationTargetException
- * if an exception was thrown by the invoked method
- */
- public Object invoke(Object receiver, Object... args)
- throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- if (args == null) {
- args = EmptyArray.OBJECT;
- }
- return invokeNative(receiver, args, declaringClass, parameterTypes, returnType, slot, flag);
- }
-
- private native Object invokeNative(Object obj, Object[] args, Class<?> declaringClass,
- Class<?>[] parameterTypes, Class<?> returnType, int slot, boolean noAccessCheck)
- throws IllegalAccessException, IllegalArgumentException,
- InvocationTargetException;
-
- /**
- * Returns a string containing a concise, human-readable description of this
- * method. The format of the string is:
- *
- * <ol>
- * <li>modifiers (if any)
- * <li>return type or 'void'
- * <li>declaring class name
- * <li>'('
- * <li>parameter types, separated by ',' (if any)
- * <li>')'
- * <li>'throws' plus exception types, separated by ',' (if any)
- * </ol>
- *
- * For example: {@code public native Object
- * java.lang.Method.invoke(Object,Object) throws
- * IllegalAccessException,IllegalArgumentException
- * ,InvocationTargetException}
- *
- * @return a printable representation for this method
- */
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
-
- if (result.length() != 0)
- result.append(' ');
- result.append(returnType.getName());
- result.append(' ');
- result.append(declaringClass.getName());
- result.append('.');
- result.append(name);
- result.append("(");
- result.append(toString(parameterTypes));
- result.append(")");
- if (exceptionTypes != null && exceptionTypes.length != 0) {
- result.append(" throws ");
- result.append(toString(exceptionTypes));
- }
-
- return result.toString();
- }
-
- /**
- * Returns the constructor's signature in non-printable form. This is called
- * (only) from IO native code and needed for deriving the serialVersionUID
- * of the class
- *
- * @return The constructor's signature.
- */
- @SuppressWarnings("unused")
- private String getSignature() {
- StringBuilder result = new StringBuilder();
-
- result.append('(');
- for (int i = 0; i < parameterTypes.length; i++) {
- result.append(getSignature(parameterTypes[i]));
- }
- result.append(')');
- result.append(getSignature(returnType));
-
- return result.toString();
- }
-
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/Proxy.java b/libdvm/src/main/java/java/lang/reflect/Proxy.java
deleted file mode 100644
index 3b10887..0000000
--- a/libdvm/src/main/java/java/lang/reflect/Proxy.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang.reflect;
-
-import java.io.Serializable;
-import java.lang.ref.WeakReference;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-/**
- * {@code Proxy} defines methods for creating dynamic proxy classes and instances.
- * A proxy class implements a declared set of interfaces and delegates method
- * invocations to an {@code InvocationHandler}.
- *
- * @see InvocationHandler
- * @since 1.3
- */
-public class Proxy implements Serializable {
-
- private static final long serialVersionUID = -2222568056686623797L;
-
- // maps class loaders to created classes by interface names
- private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>> loaderCache = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();
-
- // to find previously created types
- private static final Map<Class<?>, String> proxyCache = new WeakHashMap<Class<?>, String>();
-
- private static int NextClassNameIndex = 0;
-
- /**
- * The invocation handler on which the method calls are dispatched.
- */
- protected InvocationHandler h;
-
- @SuppressWarnings("unused")
- private Proxy() {
- }
-
- /**
- * Constructs a new {@code Proxy} instance with the specified invocation
- * handler.
- *
- * @param h
- * the invocation handler for the newly created proxy
- */
- protected Proxy(InvocationHandler h) {
- this.h = h;
- }
-
- /**
- * Returns the dynamically built {@code Class} for the specified interfaces.
- * Creates a new {@code Class} when necessary. The order of the interfaces
- * is relevant. Invocations of this method with the same interfaces but
- * different order result in different generated classes. The interfaces
- * must be visible from the supplied class loader; no duplicates are
- * permitted. All non-public interfaces must be defined in the same package.
- *
- * @param loader
- * the class loader that will define the proxy class
- * @param interfaces
- * an array of {@code Class} objects, each one identifying an
- * interface that will be implemented by the returned proxy
- * class
- * @return a proxy class that implements all of the interfaces referred to
- * in the contents of {@code interfaces}
- * @throws IllegalArgumentException
- * if any of the interface restrictions are violated
- * @throws NullPointerException
- * if either {@code interfaces} or any of its elements are
- * {@code null}
- */
- public static Class<?> getProxyClass(ClassLoader loader,
- Class<?>... interfaces) throws IllegalArgumentException {
- // check that interfaces are a valid array of visible interfaces
- if (interfaces == null) {
- throw new NullPointerException("interfaces == null");
- }
- String commonPackageName = null;
- for (int i = 0, length = interfaces.length; i < length; i++) {
- Class<?> next = interfaces[i];
- if (next == null) {
- throw new NullPointerException("interfaces[" + i + "] == null");
- }
- String name = next.getName();
- if (!next.isInterface()) {
- throw new IllegalArgumentException(name + " is not an interface");
- }
- if (loader != next.getClassLoader()) {
- try {
- if (next != Class.forName(name, false, loader)) {
- throw new IllegalArgumentException(name +
- " is not visible from class loader");
- }
- } catch (ClassNotFoundException ex) {
- throw new IllegalArgumentException(name + " is not visible from class loader");
- }
- }
- for (int j = i + 1; j < length; j++) {
- if (next == interfaces[j]) {
- throw new IllegalArgumentException(name + " appears more than once");
- }
- }
- if (!Modifier.isPublic(next.getModifiers())) {
- int last = name.lastIndexOf('.');
- String p = last == -1 ? "" : name.substring(0, last);
- if (commonPackageName == null) {
- commonPackageName = p;
- } else if (!commonPackageName.equals(p)) {
- throw new IllegalArgumentException("non-public interfaces must be " +
- "in the same package");
- }
- }
- }
-
- // search cache for matching proxy class using the class loader
- synchronized (loaderCache) {
- Map<String, WeakReference<Class<?>>> interfaceCache = loaderCache
- .get(loader);
- if (interfaceCache == null) {
- loaderCache
- .put(
- loader,
- (interfaceCache = new HashMap<String, WeakReference<Class<?>>>()));
- }
-
- String interfaceKey = "";
- if (interfaces.length == 1) {
- interfaceKey = interfaces[0].getName();
- } else {
- StringBuilder names = new StringBuilder();
- for (int i = 0, length = interfaces.length; i < length; i++) {
- names.append(interfaces[i].getName());
- names.append(' ');
- }
- interfaceKey = names.toString();
- }
-
- Class<?> newClass;
- WeakReference<Class<?>> ref = interfaceCache.get(interfaceKey);
- if (ref == null) {
- String nextClassName = "$Proxy" + NextClassNameIndex++;
- if (commonPackageName != null && commonPackageName.length() > 0) {
- nextClassName = commonPackageName + "." + nextClassName;
- }
- if (loader == null) {
- loader = ClassLoader.getSystemClassLoader();
- }
- newClass = generateProxy(nextClassName.replace('.', '/'), interfaces, loader);
- // Need a weak reference to the class so it can
- // be unloaded if the class loader is discarded
- interfaceCache.put(interfaceKey, new WeakReference<Class<?>>(newClass));
- synchronized (proxyCache) {
- // the value is unused
- proxyCache.put(newClass, "");
- }
- } else {
- newClass = ref.get();
- assert newClass != null : "\ninterfaceKey=\"" + interfaceKey + "\""
- + "\nloaderCache=\"" + loaderCache + "\""
- + "\nintfCache=\"" + interfaceCache + "\""
- + "\nproxyCache=\"" + proxyCache + "\"";
- }
- return newClass;
- }
- }
-
- /**
- * Returns an instance of the dynamically built class for the specified
- * interfaces. Method invocations on the returned instance are forwarded to
- * the specified invocation handler. The interfaces must be visible from the
- * supplied class loader; no duplicates are permitted. All non-public
- * interfaces must be defined in the same package.
- *
- * @param loader
- * the class loader that will define the proxy class
- * @param interfaces
- * an array of {@code Class} objects, each one identifying an
- * interface that will be implemented by the returned proxy
- * object
- * @param h
- * the invocation handler that handles the dispatched method
- * invocations
- * @return a new proxy object that delegates to the handler {@code h}
- * @throws IllegalArgumentException
- * if any of the interface restrictions are violated
- * @throws NullPointerException
- * if the interfaces or any of its elements are null
- */
- public static Object newProxyInstance(ClassLoader loader,
- Class<?>[] interfaces, InvocationHandler h)
- throws IllegalArgumentException {
- if (h == null) {
- throw new NullPointerException("h == null");
- }
- try {
- return getProxyClass(loader, interfaces).getConstructor(
- new Class<?>[] { InvocationHandler.class }).newInstance(
- new Object[] { h });
- } catch (NoSuchMethodException ex) {
- throw (InternalError) (new InternalError(ex.toString())
- .initCause(ex));
- } catch (IllegalAccessException ex) {
- throw (InternalError) (new InternalError(ex.toString())
- .initCause(ex));
- } catch (InstantiationException ex) {
- throw (InternalError) (new InternalError(ex.toString())
- .initCause(ex));
- } catch (InvocationTargetException ex) {
- Throwable target = ex.getTargetException();
- throw (InternalError) (new InternalError(target.toString())
- .initCause(target));
- }
- }
-
- /**
- * Indicates whether or not the specified class is a dynamically generated
- * proxy class.
- *
- * @param cl
- * the class
- * @return {@code true} if the class is a proxy class, {@code false}
- * otherwise
- * @throws NullPointerException
- * if the class is {@code null}
- */
- public static boolean isProxyClass(Class<?> cl) {
- if (cl == null) {
- throw new NullPointerException("cl == null");
- }
- synchronized (proxyCache) {
- return proxyCache.containsKey(cl);
- }
- }
-
- /**
- * Returns the invocation handler of the specified proxy instance.
- *
- * @param proxy
- * the proxy instance
- * @return the invocation handler of the specified proxy instance
- * @throws IllegalArgumentException
- * if the supplied {@code proxy} is not a proxy object
- */
- public static InvocationHandler getInvocationHandler(Object proxy)
- throws IllegalArgumentException {
-
- if (isProxyClass(proxy.getClass())) {
- return ((Proxy) proxy).h;
- }
-
- throw new IllegalArgumentException("not a proxy instance");
- }
-
- native private static Class generateProxy(String name, Class[] interfaces,
- ClassLoader loader);
-
- /*
- * The VM clones this method's descriptor when generating a proxy class.
- * There is no implementation.
- */
- native private static void constructorPrototype(InvocationHandler h);
-}
diff --git a/libdvm/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java b/libdvm/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java
deleted file mode 100644
index 01d0e30..0000000
--- a/libdvm/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.kernel.vm;
-
-/**
- * String utility functions.
- */
-public final class StringUtils {
- /**
- * This class is uninstantiable.
- */
- private StringUtils() {
- // This space intentionally left blank.
- }
-
- /**
- * Combine a list of strings in an <code>Object[]</code> into a single
- * string.
- *
- * @param list non-null; the strings to combine
- * @return non-null; the combined form
- */
- public static String combineStrings(Object[] list) {
- int listLength = list.length;
-
- switch (listLength) {
- case 0: {
- return "";
- }
- case 1: {
- return (String) list[0];
- }
- }
-
- int strLength = 0;
-
- for (int i = 0; i < listLength; i++) {
- strLength += ((String) list[i]).length();
- }
-
- StringBuilder sb = new StringBuilder(strLength);
-
- for (int i = 0; i < listLength; i++) {
- sb.append(list[i]);
- }
-
- return sb.toString();
- }
-}
diff --git a/libdvm/src/main/java/sun/misc/Unsafe.java b/libdvm/src/main/java/sun/misc/Unsafe.java
deleted file mode 100644
index 884340b..0000000
--- a/libdvm/src/main/java/sun/misc/Unsafe.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package sun.misc;
-
-import dalvik.system.VMStack;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-
-/**
- * The package name notwithstanding, this class is the quasi-standard
- * way for Java code to gain access to and use functionality which,
- * when unsupervised, would allow one to break the pointer/type safety
- * of Java.
- */
-public final class Unsafe {
- /** Traditional dalvik name. */
- private static final Unsafe THE_ONE = new Unsafe();
- /** Traditional RI name. */
- private static final Unsafe theUnsafe = THE_ONE;
-
- /**
- * This class is only privately instantiable.
- */
- private Unsafe() {}
-
- /**
- * Gets the unique instance of this class. This is only allowed in
- * very limited situations.
- */
- public static Unsafe getUnsafe() {
- /*
- * Only code on the bootclasspath is allowed to get at the
- * Unsafe instance.
- */
- ClassLoader calling = VMStack.getCallingClassLoader();
- if ((calling != null) && (calling != Unsafe.class.getClassLoader())) {
- throw new SecurityException("Unsafe access denied");
- }
-
- return THE_ONE;
- }
-
- /**
- * Gets the raw byte offset from the start of an object's memory to
- * the memory used to store the indicated instance field.
- *
- * @param field non-null; the field in question, which must be an
- * instance field
- * @return the offset to the field
- */
- public long objectFieldOffset(Field field) {
- if (Modifier.isStatic(field.getModifiers())) {
- throw new IllegalArgumentException(
- "valid for instance fields only");
- }
-
- return objectFieldOffset0(field);
- }
-
- /**
- * Helper for {@link #objectFieldOffset}, which does all the work,
- * assuming the parameter is deemed valid.
- *
- * @param field non-null; the instance field
- * @return the offset to the field
- */
- private static native long objectFieldOffset0(Field field);
-
- /**
- * Gets the offset from the start of an array object's memory to
- * the memory used to store its initial (zeroeth) element.
- *
- * @param clazz non-null; class in question; must be an array class
- * @return the offset to the initial element
- */
- public int arrayBaseOffset(Class clazz) {
- if (! clazz.isArray()) {
- throw new IllegalArgumentException(
- "valid for array classes only");
- }
-
- return arrayBaseOffset0(clazz);
- }
-
- /**
- * Helper for {@link #arrayBaseOffset}, which does all the work,
- * assuming the parameter is deemed valid.
- *
- * @return the offset to the field
- */
- private static native int arrayBaseOffset0(Class clazz);
-
- /**
- * Gets the size of each element of the given array class.
- *
- * @param clazz non-null; class in question; must be an array class
- * @return &gt; 0; the size of each element of the array
- */
- public int arrayIndexScale(Class clazz) {
- if (! clazz.isArray()) {
- throw new IllegalArgumentException(
- "valid for array classes only");
- }
-
- return arrayIndexScale0(clazz);
- }
-
- /**
- * Helper for {@link #arrayIndexScale}, which does all the work,
- * assuming the parameter is deemed valid.
- *
- * @return the offset to the field
- */
- private static native int arrayIndexScale0(Class clazz);
-
- /**
- * Performs a compare-and-set operation on an <code>int</code>
- * field within the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param expectedValue expected value of the field
- * @param newValue new value to store in the field if the contents are
- * as expected
- * @return <code>true</code> if the new value was in fact stored, and
- * <code>false</code> if not
- */
- public native boolean compareAndSwapInt(Object obj, long offset,
- int expectedValue, int newValue);
-
- /**
- * Performs a compare-and-set operation on a <code>long</code>
- * field within the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param expectedValue expected value of the field
- * @param newValue new value to store in the field if the contents are
- * as expected
- * @return <code>true</code> if the new value was in fact stored, and
- * <code>false</code> if not
- */
- public native boolean compareAndSwapLong(Object obj, long offset,
- long expectedValue, long newValue);
-
- /**
- * Performs a compare-and-set operation on an <code>Object</code>
- * field (that is, a reference field) within the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param expectedValue expected value of the field
- * @param newValue new value to store in the field if the contents are
- * as expected
- * @return <code>true</code> if the new value was in fact stored, and
- * <code>false</code> if not
- */
- public native boolean compareAndSwapObject(Object obj, long offset,
- Object expectedValue, Object newValue);
-
- /**
- * Gets an <code>int</code> field from the given object,
- * using <code>volatile</code> semantics.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @return the retrieved value
- */
- public native int getIntVolatile(Object obj, long offset);
-
- /**
- * Stores an <code>int</code> field into the given object,
- * using <code>volatile</code> semantics.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param newValue the value to store
- */
- public native void putIntVolatile(Object obj, long offset, int newValue);
-
- /**
- * Gets a <code>long</code> field from the given object,
- * using <code>volatile</code> semantics.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @return the retrieved value
- */
- public native long getLongVolatile(Object obj, long offset);
-
- /**
- * Stores a <code>long</code> field into the given object,
- * using <code>volatile</code> semantics.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param newValue the value to store
- */
- public native void putLongVolatile(Object obj, long offset, long newValue);
-
- /**
- * Gets an <code>Object</code> field from the given object,
- * using <code>volatile</code> semantics.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @return the retrieved value
- */
- public native Object getObjectVolatile(Object obj, long offset);
-
- /**
- * Stores an <code>Object</code> field into the given object,
- * using <code>volatile</code> semantics.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param newValue the value to store
- */
- public native void putObjectVolatile(Object obj, long offset,
- Object newValue);
-
- /**
- * Gets an <code>int</code> field from the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @return the retrieved value
- */
- public native int getInt(Object obj, long offset);
-
- /**
- * Stores an <code>int</code> field into the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param newValue the value to store
- */
- public native void putInt(Object obj, long offset, int newValue);
-
- /**
- * Lazy set an int field.
- */
- public native void putOrderedInt(Object obj, long offset, int newValue);
-
- /**
- * Gets a <code>long</code> field from the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @return the retrieved value
- */
- public native long getLong(Object obj, long offset);
-
- /**
- * Stores a <code>long</code> field into the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param newValue the value to store
- */
- public native void putLong(Object obj, long offset, long newValue);
-
- /**
- * Lazy set a long field.
- */
- public native void putOrderedLong(Object obj, long offset, long newValue);
-
- /**
- * Gets an <code>Object</code> field from the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @return the retrieved value
- */
- public native Object getObject(Object obj, long offset);
-
- /**
- * Stores an <code>Object</code> field into the given object.
- *
- * @param obj non-null; object containing the field
- * @param offset offset to the field within <code>obj</code>
- * @param newValue the value to store
- */
- public native void putObject(Object obj, long offset, Object newValue);
-
- /**
- * Lazy set an object field.
- */
- public native void putOrderedObject(Object obj, long offset,
- Object newValue);
-
- /**
- * Parks the calling thread for the specified amount of time,
- * unless the "permit" for the thread is already available (due to
- * a previous call to {@link #unpark}. This method may also return
- * spuriously (that is, without the thread being told to unpark
- * and without the indicated amount of time elapsing).
- *
- * <p>See {@link java.util.concurrent.locks.LockSupport} for more
- * in-depth information of the behavior of this method.</p>
- *
- * @param absolute whether the given time value is absolute
- * milliseconds-since-the-epoch (<code>true</code>) or relative
- * nanoseconds-from-now (<code>false</code>)
- * @param time the (absolute millis or relative nanos) time value
- */
- public void park(boolean absolute, long time) {
- if (absolute) {
- Thread.currentThread().parkUntil(time);
- } else {
- Thread.currentThread().parkFor(time);
- }
- }
-
- /**
- * Unparks the given object, which must be a {@link Thread}.
- *
- * <p>See {@link java.util.concurrent.locks.LockSupport} for more
- * in-depth information of the behavior of this method.</p>
- *
- * @param obj non-null; the object to unpark
- */
- public void unpark(Object obj) {
- if (obj instanceof Thread) {
- ((Thread) obj).unpark();
- } else {
- throw new IllegalArgumentException("valid for Threads only");
- }
- }
-
- /**
- * Allocates an instance of the given class without running the constructor.
- * The class' <clinit> will be run, if necessary.
- */
- public native Object allocateInstance(Class<?> c);
-}
diff --git a/luni/src/main/files/cacerts/03f2b8cf.0 b/luni/src/main/files/cacerts/03f2b8cf.0
new file mode 100644
index 0000000..82813fb
--- /dev/null
+++ b/luni/src/main/files/cacerts/03f2b8cf.0
@@ -0,0 +1,120 @@
+-----BEGIN CERTIFICATE-----
+MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBG
+MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNV
+BAMMEkNBIOayg+mAmuagueivgeS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgw
+MTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRl
+ZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k8H/r
+D195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld1
+9AXbbQs5uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExf
+v5RxadmWPgxDT74wwJ85dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnk
+UkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+L
+NVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFyb7Ao65vh4YOhn0pdr8yb
++gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc76DbT52V
+qyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6K
+yX2m+Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0G
+AbQOXDBGVWCvOGU6yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaK
+J/kR8slC/k7e3x9cxKSGhxYzoacXGKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwEC
+AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUAA4ICAQBqinA4
+WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6
+yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj
+/feTZU7n85iYr83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6
+jBAyvd0zaziGfjk9DgNyp115j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2
+ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0AkLppRQjbbpCBhqcqBT/mhDn4t/lX
+X0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97qA4bLJyuQHCH2u2n
+FoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Yjj4D
+u9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10l
+O1Hm13ZBONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Le
+ie2uPAmvylezkolwQOQvT8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR1
+2KvxAmLBsX5VYc8T1yaw15zLKYs4SgsOkI26oQ==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 50:70:6b:cd:d8:13:fc:1b:4e:3b:33:72:d2:11:48:8d
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=CN, O=WoSign CA Limited, CN=CA \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6
+ Validity
+ Not Before: Aug 8 01:00:01 2009 GMT
+ Not After : Aug 8 01:00:01 2039 GMT
+ Subject: C=CN, O=WoSign CA Limited, CN=CA \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:d0:49:21:1e:25:fc:87:c1:2a:c2:ac:db:76:86:
+ 06:4e:e7:d0:74:34:dc:ed:65:35:fc:50:d6:88:3f:
+ a4:f0:7f:eb:0f:5f:79:2f:89:b1:fd:bc:63:58:37:
+ 93:9b:38:f8:b7:5b:a9:fa:d8:71:c7:b4:bc:80:97:
+ 8d:6c:4b:f1:50:d5:2a:29:aa:a8:19:7a:96:e6:95:
+ 8e:74:ed:97:0a:57:75:f4:05:db:6d:0b:39:b9:01:
+ 7f:aa:f6:d6:da:6c:e6:05:e0:a4:4d:52:fc:db:d0:
+ 74:b7:11:8c:7b:8d:4f:ff:87:83:ae:ff:05:03:13:
+ 57:50:37:fe:8c:96:52:10:4c:5f:bf:94:71:69:d9:
+ 96:3e:0c:43:4f:be:30:c0:9f:39:74:4f:06:45:5d:
+ a3:d6:56:39:68:07:cc:87:4f:50:77:93:71:d9:44:
+ 08:b1:8a:34:e9:89:ac:db:9b:4e:e1:d9:e4:52:45:
+ 8c:2e:14:1f:91:6b:19:1d:68:29:2c:56:c4:e2:1e:
+ 13:57:64:f0:61:e3:b9:11:df:b0:e1:57:a0:1b:ad:
+ d7:5f:d1:af:db:2b:2d:3f:d0:68:8e:0f:ea:9f:0f:
+ 8b:35:58:1b:13:1c:f4:de:35:a1:0a:5d:d6:ea:df:
+ 12:6f:c0:fb:69:07:46:72:dc:81:f6:04:23:17:e0:
+ 4d:75:e1:72:6f:b0:28:eb:9b:e1:e1:83:a1:9f:4a:
+ 5d:af:cc:9b:fa:02:20:b6:18:62:77:91:3b:a3:d5:
+ 65:ad:dc:7c:90:77:1c:44:41:a4:4a:8b:eb:95:72:
+ e9:f6:09:64:dc:a8:2d:9f:74:78:e8:c1:a2:09:63:
+ 9c:ef:a0:db:4f:9d:95:ab:20:4f:b7:b0:f7:87:5c:
+ a6:a0:e4:37:38:c7:5c:e3:35:0f:2c:ad:a3:80:a2:
+ ec:2e:5d:c0:cf:ed:8b:05:c2:e6:73:6e:f6:89:d5:
+ f5:d2:46:8e:ea:6d:63:1b:1e:8a:c9:7d:a6:f8:9c:
+ eb:e5:d5:63:85:4d:73:66:69:11:fe:c8:0e:f4:c1:
+ c7:66:49:53:7e:e4:19:6b:f1:e9:7a:59:a3:6d:7e:
+ c5:17:e6:27:c6:ef:1b:db:6f:fc:0d:4d:06:01:b4:
+ 0e:5c:30:46:55:60:af:38:65:3a:ca:47:ba:ac:2c:
+ cc:46:1f:b2:46:96:3f:f3:ed:26:05:ee:77:a1:6a:
+ 6b:7e:2d:6d:58:5c:4a:d4:8e:67:b8:f1:da:d5:46:
+ 8a:27:f9:11:f2:c9:42:fe:4e:de:df:1f:5c:c4:a4:
+ 86:87:16:33:a1:a7:17:18:a5:0d:e4:05:e5:2b:c2:
+ 2b:0b:a2:95:90:b9:fd:60:3c:4e:89:3e:e7:9c:ee:
+ 1f:bb:01
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ E0:4D:BF:DC:9B:41:5D:13:E8:64:F0:A7:E9:15:A4:E1:81:C1:BA:31
+ Signature Algorithm: sha256WithRSAEncryption
+ 6a:8a:70:38:59:b6:da:8b:18:c8:be:2a:d3:b6:19:d5:66:29:
+ 7a:5d:cd:5b:2f:73:1c:26:4e:a3:7d:6f:ab:b7:29:4d:a6:e9:
+ a5:11:83:a7:39:73:af:10:44:92:e6:25:5d:4f:61:fa:c8:06:
+ be:4e:4b:ef:fe:f3:31:fe:c6:7c:70:0a:41:58:da:e8:99:4b:
+ 96:c9:78:bc:98:7c:02:29:ed:09:80:e6:0a:3a:82:02:2a:e2:
+ c9:2f:c8:56:19:26:ee:78:1c:23:fd:f7:93:65:4e:e7:f3:98:
+ 98:af:cd:dd:d9:9e:40:88:31:28:3a:ab:2e:0b:b0:ac:0c:24:
+ fa:7a:26:98:f3:12:61:10:f4:5d:17:f7:7e:e2:78:97:54:e2:
+ 8c:e8:29:ba:8c:10:32:bd:dd:33:6b:38:86:7e:39:3d:0e:03:
+ 72:a7:5d:79:8f:45:8a:59:ae:5b:21:6e:31:46:d5:59:8d:cf:
+ 15:5f:dd:31:25:cf:db:60:d6:81:44:72:29:02:57:f6:96:d4:
+ d6:ff:ea:29:db:39:c5:b8:2c:8a:1a:8d:ce:cb:e7:42:31:86:
+ 05:68:0e:9e:14:dd:00:90:ba:69:45:08:db:6e:90:81:86:a7:
+ 2a:05:3f:e6:84:39:f8:b7:f9:57:5f:4c:a4:79:5a:10:0c:5e:
+ d5:6b:ff:35:5f:05:51:1e:6c:a3:75:a9:cf:50:83:d3:7c:f4:
+ 66:f7:82:8d:3d:0c:7d:e8:df:7b:a8:0e:1b:2c:9c:ae:40:70:
+ 87:da:ed:a7:16:82:5a:be:35:6c:20:4e:22:61:d9:bc:51:7a:
+ cd:7a:61:dc:4b:11:f9:fe:67:34:cf:2e:04:66:61:5c:57:97:
+ 23:8c:f3:86:1b:48:df:2a:af:a7:c1:ff:d8:8e:3e:03:bb:d8:
+ 2a:b0:fa:14:25:b2:51:6b:86:43:85:2e:07:23:16:80:8d:4c:
+ fb:b4:63:3b:cc:c3:74:ed:1b:a3:1e:fe:35:0f:5f:7c:1d:16:
+ 86:f5:0e:c3:95:f1:2f:af:5d:25:3b:51:e6:d7:76:41:38:d1:
+ 4b:03:39:28:a5:1e:91:72:d4:7d:ab:97:33:c4:d3:3e:e0:69:
+ b6:28:79:a0:09:8d:1c:d1:ff:41:72:48:06:fc:9a:2e:e7:20:
+ f9:9b:a2:de:89:ed:ae:3c:09:af:ca:57:b3:92:89:70:40:e4:
+ 2f:4f:c2:70:83:40:d7:24:2c:6b:e7:09:1f:d3:d5:c7:c1:08:
+ f4:db:0e:3b:1c:07:0b:43:11:84:21:86:e9:80:d4:75:d8:ab:
+ f1:02:62:c1:b1:7e:55:61:cf:13:d7:26:b0:d7:9c:cb:29:8b:
+ 38:4a:0b:0e:90:8d:ba:a1
+SHA1 Fingerprint=16:32:47:8D:89:F9:21:3A:92:00:85:63:F5:A4:A7:D3:12:40:8A:D6
diff --git a/luni/src/main/files/cacerts/1dbdda5b.0 b/luni/src/main/files/cacerts/1dbdda5b.0
deleted file mode 100644
index b9e52f6..0000000
--- a/luni/src/main/files/cacerts/1dbdda5b.0
+++ /dev/null
@@ -1,74 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC+TCCAmKgAwIBAgIENvEbGTANBgkqhkiG9w0BAQUFADA2MQswCQYDVQQGEwJF
-UzENMAsGA1UEChMERk5NVDEYMBYGA1UECxMPRk5NVCBDbGFzZSAyIENBMB4XDTk5
-MDMxODE0NTYxOVoXDTE5MDMxODE1MjYxOVowNjELMAkGA1UEBhMCRVMxDTALBgNV
-BAoTBEZOTVQxGDAWBgNVBAsTD0ZOTVQgQ2xhc2UgMiBDQTCBnTANBgkqhkiG9w0B
-AQEFAAOBiwAwgYcCgYEAmD+tGTaTPT7+dkIU/TVv8fqtInpY40bQXcZa+WItjzFe
-/rQw/lB0rNadHeBixkndFBJ9cQusBsE/1waH4JCJ1uXjA7LyJ7GfM8iqazZKo8Q/
-eUGdiUYvKz5j1DhWkaodsQ1CdU3zh07jD03MtGy/YhOH6tCbjrbi/xn0lAnVlmEC
-AQOjggEUMIIBEDARBglghkgBhvhCAQEEBAMCAAcwWAYDVR0fBFEwTzBNoEugSaRH
-MEUxCzAJBgNVBAYTAkVTMQ0wCwYDVQQKEwRGTk1UMRgwFgYDVQQLEw9GTk1UIENs
-YXNlIDIgQ0ExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5OTAzMTgxNDU2
-MTlagQ8yMDE5MDMxODE0NTYxOVowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFECa
-dkSXdAfErBTLHo1POkV8MNdhMB0GA1UdDgQWBBRAmnZEl3QHxKwUyx6NTzpFfDDX
-YTAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG
-SIb3DQEBBQUAA4GBAGFMoHxZY1tm+O5lE85DgEe5sjXJyITHa3NgReSdN531jiW5
-+aqqyuP4Q5wvoIkFsUUylCoeA41dpt7PV5Xa3yZgX8vflR64zgjY+IrJT6lodZPj
-LwVMZGACokIeb4ZoZVUO2ENv8pExPqNHPCgFr0W2nSJMJntLfVsV+RlG3whd
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 921770777 (0x36f11b19)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=ES, O=FNMT, OU=FNMT Clase 2 CA
- Validity
- Not Before: Mar 18 14:56:19 1999 GMT
- Not After : Mar 18 15:26:19 2019 GMT
- Subject: C=ES, O=FNMT, OU=FNMT Clase 2 CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:98:3f:ad:19:36:93:3d:3e:fe:76:42:14:fd:35:
- 6f:f1:fa:ad:22:7a:58:e3:46:d0:5d:c6:5a:f9:62:
- 2d:8f:31:5e:fe:b4:30:fe:50:74:ac:d6:9d:1d:e0:
- 62:c6:49:dd:14:12:7d:71:0b:ac:06:c1:3f:d7:06:
- 87:e0:90:89:d6:e5:e3:03:b2:f2:27:b1:9f:33:c8:
- aa:6b:36:4a:a3:c4:3f:79:41:9d:89:46:2f:2b:3e:
- 63:d4:38:56:91:aa:1d:b1:0d:42:75:4d:f3:87:4e:
- e3:0f:4d:cc:b4:6c:bf:62:13:87:ea:d0:9b:8e:b6:
- e2:ff:19:f4:94:09:d5:96:61
- Exponent: 3 (0x3)
- X509v3 extensions:
- Netscape Cert Type:
- SSL CA, S/MIME CA, Object Signing CA
- X509v3 CRL Distribution Points:
-
- Full Name:
- DirName: C = ES, O = FNMT, OU = FNMT Clase 2 CA, CN = CRL1
-
- X509v3 Private Key Usage Period:
- Not Before: Mar 18 14:56:19 1999 GMT, Not After: Mar 18 14:56:19 2019 GMT
- X509v3 Key Usage:
- Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- keyid:40:9A:76:44:97:74:07:C4:AC:14:CB:1E:8D:4F:3A:45:7C:30:D7:61
-
- X509v3 Subject Key Identifier:
- 40:9A:76:44:97:74:07:C4:AC:14:CB:1E:8D:4F:3A:45:7C:30:D7:61
- X509v3 Basic Constraints:
- CA:TRUE
- 1.2.840.113533.7.65.0:
- 0
-..V4.0....
- Signature Algorithm: sha1WithRSAEncryption
- 61:4c:a0:7c:59:63:5b:66:f8:ee:65:13:ce:43:80:47:b9:b2:
- 35:c9:c8:84:c7:6b:73:60:45:e4:9d:37:9d:f5:8e:25:b9:f9:
- aa:aa:ca:e3:f8:43:9c:2f:a0:89:05:b1:45:32:94:2a:1e:03:
- 8d:5d:a6:de:cf:57:95:da:df:26:60:5f:cb:df:95:1e:b8:ce:
- 08:d8:f8:8a:c9:4f:a9:68:75:93:e3:2f:05:4c:64:60:02:a2:
- 42:1e:6f:86:68:65:55:0e:d8:43:6f:f2:91:31:3e:a3:47:3c:
- 28:05:af:45:b6:9d:22:4c:26:7b:4b:7d:5b:15:f9:19:46:df:
- 08:5d
-SHA1 Fingerprint=43:F9:B1:10:D5:BA:FD:48:22:52:31:B0:D0:08:2B:37:2F:EF:9A:54
diff --git a/luni/src/main/files/cacerts/1f58a078.0 b/luni/src/main/files/cacerts/1f58a078.0
new file mode 100644
index 0000000..ac07485
--- /dev/null
+++ b/luni/src/main/files/cacerts/1f58a078.0
@@ -0,0 +1,120 @@
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
+MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
+qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
+n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
+c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
+o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
+IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
+IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
+8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
+vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
+7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
+cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
+ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
+roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
+W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
+lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
+csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
+dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
+KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
+HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
+WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 44:57:34:24:5b:81:89:9b:35:f2:ce:b8:2b:3b:5b:a7:26:f0:75:28
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2 G3
+ Validity
+ Not Before: Jan 12 18:59:32 2012 GMT
+ Not After : Jan 12 18:59:32 2042 GMT
+ Subject: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2 G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:a1:ae:25:b2:01:18:dc:57:88:3f:46:eb:f9:af:
+ e2:eb:23:71:e2:9a:d1:61:66:21:5f:aa:af:27:51:
+ e5:6e:1b:16:d4:2d:7d:50:b0:53:77:bd:78:3a:60:
+ e2:64:02:9b:7c:86:9b:d6:1a:8e:ad:ff:1f:15:7f:
+ d5:95:1e:12:cb:e6:14:84:04:c1:df:36:b3:16:9f:
+ 8a:e3:c9:db:98:34:ce:d8:33:17:28:46:fc:a7:c9:
+ f0:d2:b4:d5:4d:09:72:49:f9:f2:87:e3:a9:da:7d:
+ a1:7d:6b:b2:3a:25:a9:6d:52:44:ac:f8:be:6e:fb:
+ dc:a6:73:91:90:61:a6:03:14:20:f2:e7:87:a3:88:
+ ad:ad:a0:8c:ff:a6:0b:25:52:25:e7:16:01:d5:cb:
+ b8:35:81:0c:a3:3b:f0:e1:e1:fc:5a:5d:ce:80:71:
+ 6d:f8:49:ab:3e:3b:ba:b8:d7:80:01:fb:a5:eb:5b:
+ b3:c5:5e:60:2a:31:a0:af:37:e8:20:3a:9f:a8:32:
+ 2c:0c:cc:09:1d:d3:9e:8e:5d:bc:4c:98:ee:c5:1a:
+ 68:7b:ec:53:a6:e9:14:35:a3:df:cd:80:9f:0c:48:
+ fb:1c:f4:f1:bf:4a:b8:fa:d5:8c:71:4a:c7:1f:ad:
+ fe:41:9a:b3:83:5d:f2:84:56:ef:a5:57:43:ce:29:
+ ad:8c:ab:55:bf:c4:fb:5b:01:dd:23:21:a1:58:00:
+ 8e:c3:d0:6a:13:ed:13:e3:12:2b:80:dc:67:e6:95:
+ b2:cd:1e:22:6e:2a:f8:41:d4:f2:ca:14:07:8d:8a:
+ 55:12:c6:69:f5:b8:86:68:2f:53:5e:b0:d2:aa:21:
+ c1:98:e6:30:e3:67:55:c7:9b:6e:ac:19:a8:55:a6:
+ 45:06:d0:23:3a:db:eb:65:5d:2a:11:11:f0:3b:4f:
+ ca:6d:f4:34:c4:71:e4:ff:00:5a:f6:5c:ae:23:60:
+ 85:73:f1:e4:10:b1:25:ae:d5:92:bb:13:c1:0c:e0:
+ 39:da:b4:39:57:b5:ab:35:aa:72:21:3b:83:35:e7:
+ 31:df:7a:21:6e:b8:32:08:7d:1d:32:91:15:4a:62:
+ 72:cf:e3:77:a1:bc:d5:11:1b:76:01:67:08:e0:41:
+ 0b:c3:eb:15:6e:f8:a4:19:d9:a2:ab:af:e2:27:52:
+ 56:2b:02:8a:2c:14:24:f9:bf:42:02:bf:26:c8:c6:
+ 8f:e0:6e:38:7d:53:2d:e5:ed:98:b3:95:63:68:7f:
+ f9:35:f4:df:88:c5:60:35:92:c0:7c:69:1c:61:95:
+ 16:d0:eb:de:0b:af:3e:04:10:45:65:58:50:38:af:
+ 48:f2:59:b6:16:f2:3c:0d:90:02:c6:70:2e:01:ad:
+ 3c:15:d7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ ED:E7:6F:76:5A:BF:60:EC:49:5B:C6:A5:77:BB:72:16:71:9B:C4:3D
+ Signature Algorithm: sha256WithRSAEncryption
+ 91:df:80:3f:43:09:7e:71:c2:f7:eb:b3:88:8f:e1:51:b2:bc:
+ 3d:75:f9:28:5d:c8:bc:99:9b:7b:5d:aa:e5:ca:e1:0a:f7:e8:
+ b2:d3:9f:dd:67:31:7e:ba:01:aa:c7:6a:41:3b:90:d4:08:5c:
+ b2:60:6a:90:f0:c8:ce:03:62:f9:8b:ed:fb:6e:2a:dc:06:4d:
+ 3c:29:0f:89:16:8a:58:4c:48:0f:e8:84:61:ea:3c:72:a6:77:
+ e4:42:ae:88:a3:43:58:79:7e:ae:ca:a5:53:0d:a9:3d:70:bd:
+ 20:19:61:a4:6c:38:fc:43:32:e1:c1:47:ff:f8:ec:f1:11:22:
+ 32:96:9c:c2:f6:5b:69:96:7b:20:0c:43:41:9a:5b:f6:59:19:
+ 88:de:55:88:37:51:0b:78:5c:0a:1e:a3:42:fd:c7:9d:88:0f:
+ c0:f2:78:02:24:54:93:af:89:87:88:c9:4a:80:1d:ea:d0:6e:
+ 3e:61:2e:36:bb:35:0e:27:96:fd:66:34:3b:61:72:73:f1:16:
+ 5c:47:06:54:49:00:7a:58:12:b0:0a:ef:85:fd:b1:b8:33:75:
+ 6a:93:1c:12:e6:60:5e:6f:1d:7f:c9:1f:23:cb:84:61:9f:1e:
+ 82:44:f9:5f:ad:62:55:24:9a:52:98:ed:51:e7:a1:7e:97:3a:
+ e6:2f:1f:11:da:53:80:2c:85:9e:ab:35:10:db:22:5f:6a:c5:
+ 5e:97:53:f2:32:02:09:30:a3:58:f0:0d:01:d5:72:c6:b1:7c:
+ 69:7b:c3:f5:36:45:cc:61:6e:5e:4c:94:c5:5e:ae:e8:0e:5e:
+ 8b:bf:f7:cd:e0:ed:a1:0e:1b:33:ee:54:18:fe:0f:be:ef:7e:
+ 84:6b:43:e3:70:98:db:5d:75:b2:0d:59:07:85:15:23:39:d6:
+ f1:df:a9:26:0f:d6:48:c7:b3:a6:22:f5:33:37:5a:95:47:9f:
+ 7b:ba:18:15:6f:ff:d6:14:64:83:49:d2:0a:67:21:db:0f:35:
+ 63:60:28:22:e3:b1:95:83:cd:85:a6:dd:2f:0f:e7:67:52:6e:
+ bb:2f:85:7c:f5:4a:73:e7:c5:3e:c0:bd:21:12:05:3f:fc:b7:
+ 03:49:02:5b:c8:25:e6:e2:54:38:f5:79:87:8c:1d:53:b2:4e:
+ 85:7b:06:38:c7:2c:f8:f8:b0:72:8d:25:e5:77:52:f4:03:1c:
+ 48:a6:50:5f:88:20:30:6e:f2:82:43:ab:3d:97:84:e7:53:fb:
+ 21:c1:4f:0f:22:9a:86:b8:59:2a:f6:47:3d:19:88:2d:e8:85:
+ e1:9e:ec:85:08:6a:b1:6c:34:c9:1d:ec:48:2b:3b:78:ed:66:
+ c4:8e:79:69:83:de:7f:8c
+SHA1 Fingerprint=09:3C:61:F3:8B:8B:DC:7D:55:DF:75:38:02:05:00:E1:25:F5:C8:36
diff --git a/luni/src/main/files/cacerts/2e8714cb.0 b/luni/src/main/files/cacerts/2e8714cb.0
deleted file mode 100644
index c67d949..0000000
--- a/luni/src/main/files/cacerts/2e8714cb.0
+++ /dev/null
@@ -1,103 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFUjCCBDqgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN
-MAsGA1UEChMES0lTQTEuMCwGA1UECxMlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkgQ2VudHJhbDEWMBQGA1UEAxMNS0lTQSBSb290Q0EgMzAeFw0wNDExMTkw
-NjM5NTFaFw0xNDExMTkwNjM5NTFaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKEwRL
-SVNBMS4wLAYDVQQLEyVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50
-cmFsMRYwFAYDVQQDEw1LSVNBIFJvb3RDQSAzMIIBIDANBgkqhkiG9w0BAQEFAAOC
-AQ0AMIIBCAKCAQEA3rrtF2Wu0b1KPazbgHLMWOHn4ZPazDB6z+8Lri2nQ6u/p0LP
-CFYIpEcdffqG79gwlyY0YTyADvjU65/8IjAboW0+40zSVU4WQDfC9gdu2we1pYyW
-geKbXH6UYcjOhDyx+gDmctMJhXfp3F4hT7TkTvTiF6tQrxz/oTlYdVsSspa5jfBw
-YkhbVigqpYeRNrkeJPW5unu2UlFbF1pgBWycwubGjD756t08jP+J3kNwrB248XXN
-OMpTDUdoasY8GMq94bS+DvTQ49IT+rBRERHUQavo9DmO4TSETwuTqmo4/OXGeEeu
-dhf6oYA3BgAVCP1rI476cg2V1ktisWjC3TSbXQIBA6OCAg8wggILMB8GA1UdIwQY
-MBaAFI+B8NqmzXQ8vmb0FWtGpP4GKMyqMB0GA1UdDgQWBBSPgfDaps10PL5m9BVr
-RqT+BijMqjAOBgNVHQ8BAf8EBAMCAQYwggEuBgNVHSAEggElMIIBITCCAR0GBFUd
-IAAwggETMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LnJvb3RjYS5vci5rci9yY2Ev
-Y3BzLmh0bWwwgd4GCCsGAQUFBwICMIHRHoHOx3QAIMd4yZ3BHLKUACCs9cd4x3jJ
-ncEcx4WyyLLkACgAVABoAGkAcwAgAGMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGkA
-cwAgAGEAYwBjAHIAZQBkAGkAdABlAGQAIAB1AG4AZABlAHIAIABFAGwAZQBjAHQA
-cgBvAG4AaQBjACAAUwBpAGcAbgBhAHQAdQByAGUAIABBAGMAdAAgAG8AZgAgAHQA
-aABlACAAUgBlAHAAdQBiAGwAaQBjACAAbwBmACAASwBvAHIAZQBhACkwMwYDVR0R
-BCwwKqQoMCYxJDAiBgNVBAMMG+2VnOq1reygleuztOuztO2YuOynhO2dpeybkDAz
-BgNVHRIELDAqpCgwJjEkMCIGA1UEAwwb7ZWc6rWt7KCV67O067O07Zi47KeE7Z2l
-7JuQMA8GA1UdEwEB/wQFMAMBAf8wDAYDVR0kBAUwA4ABADANBgkqhkiG9w0BAQUF
-AAOCAQEAz9b3Dv2wjG4FFY6oXCuyWtEeV6ZeGKqCEQj8mbdbp+PI0qLT+SQ09+Pk
-rolUR9NpScmAwRHr4inH9gaLX7riXs+rw87P7pIl3J85Hg4D9N6QW6FwmVzHc07J
-pHVJeyWhn4KSjU3sYcUMMqfHODiAVToqgx2cZHm5Dac1Smjvj/8F2LpOVmHY+Epw
-mAiWk9hgxzrsX58dKzVPSBShmrtv7tIDhlPxEMcHVGJeNo7iHCsdF03m9VrvirqC
-6HfZKBF+N4dKlArJQOk1pTr7ZD7yXxZ683bXzu4/RB1Fql8RqlMcOh9SUWJUD6OQ
-Nc9Nb7rHviwJ8TX4Absk3TC8SA/u2Q==
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 2 (0x2)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=KR, O=KISA, OU=Korea Certification Authority Central, CN=KISA RootCA 3
- Validity
- Not Before: Nov 19 06:39:51 2004 GMT
- Not After : Nov 19 06:39:51 2014 GMT
- Subject: C=KR, O=KISA, OU=Korea Certification Authority Central, CN=KISA RootCA 3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:de:ba:ed:17:65:ae:d1:bd:4a:3d:ac:db:80:72:
- cc:58:e1:e7:e1:93:da:cc:30:7a:cf:ef:0b:ae:2d:
- a7:43:ab:bf:a7:42:cf:08:56:08:a4:47:1d:7d:fa:
- 86:ef:d8:30:97:26:34:61:3c:80:0e:f8:d4:eb:9f:
- fc:22:30:1b:a1:6d:3e:e3:4c:d2:55:4e:16:40:37:
- c2:f6:07:6e:db:07:b5:a5:8c:96:81:e2:9b:5c:7e:
- 94:61:c8:ce:84:3c:b1:fa:00:e6:72:d3:09:85:77:
- e9:dc:5e:21:4f:b4:e4:4e:f4:e2:17:ab:50:af:1c:
- ff:a1:39:58:75:5b:12:b2:96:b9:8d:f0:70:62:48:
- 5b:56:28:2a:a5:87:91:36:b9:1e:24:f5:b9:ba:7b:
- b6:52:51:5b:17:5a:60:05:6c:9c:c2:e6:c6:8c:3e:
- f9:ea:dd:3c:8c:ff:89:de:43:70:ac:1d:b8:f1:75:
- cd:38:ca:53:0d:47:68:6a:c6:3c:18:ca:bd:e1:b4:
- be:0e:f4:d0:e3:d2:13:fa:b0:51:11:11:d4:41:ab:
- e8:f4:39:8e:e1:34:84:4f:0b:93:aa:6a:38:fc:e5:
- c6:78:47:ae:76:17:fa:a1:80:37:06:00:15:08:fd:
- 6b:23:8e:fa:72:0d:95:d6:4b:62:b1:68:c2:dd:34:
- 9b:5d
- Exponent: 3 (0x3)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:8F:81:F0:DA:A6:CD:74:3C:BE:66:F4:15:6B:46:A4:FE:06:28:CC:AA
-
- X509v3 Subject Key Identifier:
- 8F:81:F0:DA:A6:CD:74:3C:BE:66:F4:15:6B:46:A4:FE:06:28:CC:AA
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.rootca.or.kr/rca/cps.html
- User Notice:
- Explicit Text: Çt
-
- X509v3 Subject Alternative Name:
- DirName:/CN=\xED\x95\x9C\xEA\xB5\xAD\xEC\xA0\x95\xEB\xB3\xB4\xEB\xB3\xB4\xED\x98\xB8\xEC\xA7\x84\xED\x9D\xA5\xEC\x9B\x90
- X509v3 Issuer Alternative Name:
- DirName:/CN=\xED\x95\x9C\xEA\xB5\xAD\xEC\xA0\x95\xEB\xB3\xB4\xEB\xB3\xB4\xED\x98\xB8\xEC\xA7\x84\xED\x9D\xA5\xEC\x9B\x90
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Policy Constraints:
- Require Explicit Policy:0
- Signature Algorithm: sha1WithRSAEncryption
- cf:d6:f7:0e:fd:b0:8c:6e:05:15:8e:a8:5c:2b:b2:5a:d1:1e:
- 57:a6:5e:18:aa:82:11:08:fc:99:b7:5b:a7:e3:c8:d2:a2:d3:
- f9:24:34:f7:e3:e4:ae:89:54:47:d3:69:49:c9:80:c1:11:eb:
- e2:29:c7:f6:06:8b:5f:ba:e2:5e:cf:ab:c3:ce:cf:ee:92:25:
- dc:9f:39:1e:0e:03:f4:de:90:5b:a1:70:99:5c:c7:73:4e:c9:
- a4:75:49:7b:25:a1:9f:82:92:8d:4d:ec:61:c5:0c:32:a7:c7:
- 38:38:80:55:3a:2a:83:1d:9c:64:79:b9:0d:a7:35:4a:68:ef:
- 8f:ff:05:d8:ba:4e:56:61:d8:f8:4a:70:98:08:96:93:d8:60:
- c7:3a:ec:5f:9f:1d:2b:35:4f:48:14:a1:9a:bb:6f:ee:d2:03:
- 86:53:f1:10:c7:07:54:62:5e:36:8e:e2:1c:2b:1d:17:4d:e6:
- f5:5a:ef:8a:ba:82:e8:77:d9:28:11:7e:37:87:4a:94:0a:c9:
- 40:e9:35:a5:3a:fb:64:3e:f2:5f:16:7a:f3:76:d7:ce:ee:3f:
- 44:1d:45:aa:5f:11:aa:53:1c:3a:1f:52:51:62:54:0f:a3:90:
- 35:cf:4d:6f:ba:c7:be:2c:09:f1:35:f8:01:bb:24:dd:30:bc:
- 48:0f:ee:d9
-SHA1 Fingerprint=5F:4E:1F:CF:31:B7:91:3B:85:0B:54:F6:E5:FF:50:1A:2B:6F:C6:CF
diff --git a/luni/src/main/files/cacerts/48478734.0 b/luni/src/main/files/cacerts/48478734.0
deleted file mode 100644
index e317faf..0000000
--- a/luni/src/main/files/cacerts/48478734.0
+++ /dev/null
@@ -1,76 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDczCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN
-MAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgMTAeFw0wNTA4MjQw
-ODA1NDZaFw0yNTA4MjQwODA1NDZaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKDARL
-SVNBMS4wLAYDVQQLDCVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50
-cmFsMRYwFAYDVQQDDA1LSVNBIFJvb3RDQSAxMIIBIDANBgkqhkiG9w0BAQEFAAOC
-AQ0AMIIBCAKCAQEAvATk+hM58DSWIGtsaLv623f/J/es7C/n/fB/bW+MKs0lCVsk
-9KFo/CjsySXirO3eyDOE9bClCTqnsUdIxcxPjHmc+QZXfd3uOPbPFLKc6tPAXXdi
-8EcNuRpAU1xkcK8IWsD3z3X5bI1kKB4g/rcbGdNaZoNy4rCbvdMlFQ0yb2Q3lIVG
-yHK+d9VuHygvx2nt54OJM1jT3qC/QOhDUO7cTWu8peqmyGGO9cNkrwYV3CmLP3WM
-vHFE2/yttRcdbYmDz8Yzvb9Fov4Kn6MRXw+5H5wawkbMnChmn3AmPC7fqoD+jMUE
-CSVPzZNHPDfqAmeS/vwiJFys0izgXAEzisEZ2wIBA6MyMDAwHQYDVR0OBBYEFL+2
-J9gDWnZlTGEBQVYx5Yt7OtnMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF
-BQADggEBABOvUQveimpb5poKyLGQSk6hAp3MiNKrZr097LuxQpVqslxa/6FjZJap
-aBV/JV6K+KRzwYCKhQoOUugy50X4TmWAkZl0Q+VFnUkq8JSV3enhMNITbslOsXfl
-BM+tWh6UCVrXPAgcrnrpFDLBRa3SJkhyrKhB2vAhhzle3/xk/2F0KpzZm4tfwjeT
-2KM3LzuTa7IbB6d/CVDv0zq+IWuKkDsnSlFOa56ch534eJAx7REnxqhZvvwYC/uO
-fi5C4e3nCSG9uRPFVmf0JqZCQ5BEVLRxm3bkGhKsGigA35vB1fjbXKP4krG9tNT5
-UNkAAk/bg9ART6RCVmE6fhMy04Qfybo=
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 4 (0x4)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=KR, O=KISA, OU=Korea Certification Authority Central, CN=KISA RootCA 1
- Validity
- Not Before: Aug 24 08:05:46 2005 GMT
- Not After : Aug 24 08:05:46 2025 GMT
- Subject: C=KR, O=KISA, OU=Korea Certification Authority Central, CN=KISA RootCA 1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bc:04:e4:fa:13:39:f0:34:96:20:6b:6c:68:bb:
- fa:db:77:ff:27:f7:ac:ec:2f:e7:fd:f0:7f:6d:6f:
- 8c:2a:cd:25:09:5b:24:f4:a1:68:fc:28:ec:c9:25:
- e2:ac:ed:de:c8:33:84:f5:b0:a5:09:3a:a7:b1:47:
- 48:c5:cc:4f:8c:79:9c:f9:06:57:7d:dd:ee:38:f6:
- cf:14:b2:9c:ea:d3:c0:5d:77:62:f0:47:0d:b9:1a:
- 40:53:5c:64:70:af:08:5a:c0:f7:cf:75:f9:6c:8d:
- 64:28:1e:20:fe:b7:1b:19:d3:5a:66:83:72:e2:b0:
- 9b:bd:d3:25:15:0d:32:6f:64:37:94:85:46:c8:72:
- be:77:d5:6e:1f:28:2f:c7:69:ed:e7:83:89:33:58:
- d3:de:a0:bf:40:e8:43:50:ee:dc:4d:6b:bc:a5:ea:
- a6:c8:61:8e:f5:c3:64:af:06:15:dc:29:8b:3f:75:
- 8c:bc:71:44:db:fc:ad:b5:17:1d:6d:89:83:cf:c6:
- 33:bd:bf:45:a2:fe:0a:9f:a3:11:5f:0f:b9:1f:9c:
- 1a:c2:46:cc:9c:28:66:9f:70:26:3c:2e:df:aa:80:
- fe:8c:c5:04:09:25:4f:cd:93:47:3c:37:ea:02:67:
- 92:fe:fc:22:24:5c:ac:d2:2c:e0:5c:01:33:8a:c1:
- 19:db
- Exponent: 3 (0x3)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- BF:B6:27:D8:03:5A:76:65:4C:61:01:41:56:31:E5:8B:7B:3A:D9:CC
- X509v3 Basic Constraints: critical
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- 13:af:51:0b:de:8a:6a:5b:e6:9a:0a:c8:b1:90:4a:4e:a1:02:
- 9d:cc:88:d2:ab:66:bd:3d:ec:bb:b1:42:95:6a:b2:5c:5a:ff:
- a1:63:64:96:a9:68:15:7f:25:5e:8a:f8:a4:73:c1:80:8a:85:
- 0a:0e:52:e8:32:e7:45:f8:4e:65:80:91:99:74:43:e5:45:9d:
- 49:2a:f0:94:95:dd:e9:e1:30:d2:13:6e:c9:4e:b1:77:e5:04:
- cf:ad:5a:1e:94:09:5a:d7:3c:08:1c:ae:7a:e9:14:32:c1:45:
- ad:d2:26:48:72:ac:a8:41:da:f0:21:87:39:5e:df:fc:64:ff:
- 61:74:2a:9c:d9:9b:8b:5f:c2:37:93:d8:a3:37:2f:3b:93:6b:
- b2:1b:07:a7:7f:09:50:ef:d3:3a:be:21:6b:8a:90:3b:27:4a:
- 51:4e:6b:9e:9c:87:9d:f8:78:90:31:ed:11:27:c6:a8:59:be:
- fc:18:0b:fb:8e:7e:2e:42:e1:ed:e7:09:21:bd:b9:13:c5:56:
- 67:f4:26:a6:42:43:90:44:54:b4:71:9b:76:e4:1a:12:ac:1a:
- 28:00:df:9b:c1:d5:f8:db:5c:a3:f8:92:b1:bd:b4:d4:f9:50:
- d9:00:02:4f:db:83:d0:11:4f:a4:42:56:61:3a:7e:13:32:d3:
- 84:1f:c9:ba
-SHA1 Fingerprint=02:72:68:29:3E:5F:5D:17:AA:A4:B3:C3:E6:36:1E:1F:92:57:5E:AA
diff --git a/luni/src/main/files/cacerts/52b525c7.0 b/luni/src/main/files/cacerts/52b525c7.0
new file mode 100644
index 0000000..98adef0
--- /dev/null
+++ b/luni/src/main/files/cacerts/52b525c7.0
@@ -0,0 +1,120 @@
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
+MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
+wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
+rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
+68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
+4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
+UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
+abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
+3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
+KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
+hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
+Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
+zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
+ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
+MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
+cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
+qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
+YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
+b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
+8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
+NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
+ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
+q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
+nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 78:58:5f:2e:ad:2c:19:4b:e3:37:07:35:34:13:28:b5:96:d4:65:93
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 1 G3
+ Validity
+ Not Before: Jan 12 17:27:44 2012 GMT
+ Not After : Jan 12 17:27:44 2042 GMT
+ Subject: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 1 G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:a0:be:50:10:8e:e9:f2:6c:40:b4:04:9c:85:b9:
+ 31:ca:dc:2d:e4:11:a9:04:3c:1b:55:c1:e7:58:30:
+ 1d:24:b4:c3:ef:85:de:8c:2c:e1:c1:3d:df:82:e6:
+ 4f:ad:47:87:6c:ec:5b:49:c1:4a:d5:bb:8f:ec:87:
+ ac:7f:82:9a:86:ec:3d:03:99:52:01:d2:35:9e:ac:
+ da:f0:53:c9:66:3c:d4:ac:02:01:da:24:d3:3b:a8:
+ 02:46:af:a4:1c:e3:f8:73:58:76:b7:f6:0e:90:0d:
+ b5:f0:cf:cc:fa:f9:c6:4c:e5:c3:86:30:0a:8d:17:
+ 7e:35:eb:c5:df:bb:0e:9c:c0:8d:87:e3:88:38:85:
+ 67:fa:3e:c7:ab:e0:13:9c:05:18:98:cf:93:f5:b1:
+ 92:b4:fc:23:d3:cf:d5:c4:27:49:e0:9e:3c:9b:08:
+ a3:8b:5d:2a:21:e0:fc:39:aa:53:da:7d:7e:cf:1a:
+ 09:53:bc:5d:05:04:cf:a1:4a:8f:8b:76:82:0d:a1:
+ f8:d2:c7:14:77:5b:90:36:07:81:9b:3e:06:fa:52:
+ 5e:63:c5:a6:00:fe:a5:e9:52:1b:52:b5:92:39:72:
+ 03:09:62:bd:b0:60:16:6e:a6:dd:25:c2:03:66:dd:
+ f3:04:d1:40:e2:4e:8b:86:f4:6f:e5:83:a0:27:84:
+ 5e:04:c1:f5:90:bd:30:3d:c4:ef:a8:69:bc:38:9b:
+ a4:a4:96:d1:62:da:69:c0:01:96:ae:cb:c4:51:34:
+ ea:0c:aa:ff:21:8e:59:8f:4a:5c:e4:61:9a:a7:d2:
+ e9:2a:78:8d:51:3d:3a:15:ee:a2:59:8e:a9:5c:de:
+ c5:f9:90:22:e5:88:45:71:dd:91:99:6c:7a:9f:3d:
+ 3d:98:7c:5e:f6:be:16:68:a0:5e:ae:0b:23:fc:5a:
+ 0f:aa:22:76:2d:c9:a1:10:1d:e4:d3:44:23:90:88:
+ 9f:c6:2a:e6:d7:f5:9a:b3:58:1e:2f:30:89:08:1b:
+ 54:a2:b5:98:23:ec:08:77:1c:95:5d:61:d1:cb:89:
+ 9c:5f:a2:4a:91:9a:ef:21:aa:49:16:08:a8:bd:61:
+ 28:31:c9:74:ad:85:f6:d9:c5:b1:8b:d1:e5:10:32:
+ 4d:5f:8b:20:3a:3c:49:1f:33:85:59:0d:db:cb:09:
+ 75:43:69:73:fb:6b:71:7d:f0:df:c4:4c:7d:c6:a3:
+ 2e:c8:95:79:cb:73:a2:8e:4e:4d:24:fb:5e:e4:04:
+ be:72:1b:a6:27:2d:49:5a:99:7a:d7:5c:09:20:b7:
+ 7f:94:b9:4f:f1:0d:1c:5e:88:42:1b:11:b7:e7:91:
+ db:9e:6c:f4:6a:df:8c:06:98:03:ad:cc:28:ef:a5:
+ 47:f3:53
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ A3:97:D6:F3:5E:A2:10:E1:AB:45:9F:3C:17:64:3C:EE:01:70:9C:CC
+ Signature Algorithm: sha256WithRSAEncryption
+ 18:fa:5b:75:fc:3e:7a:c7:5f:77:c7:ca:df:cf:5f:c3:12:c4:
+ 40:5d:d4:32:aa:b8:6a:d7:d5:15:15:46:98:23:a5:e6:90:5b:
+ 18:99:4c:e3:ad:42:a3:82:31:36:88:cd:e9:fb:c4:04:96:48:
+ 8b:01:c7:8d:01:cf:5b:33:06:96:46:66:74:1d:4f:ed:c1:b6:
+ b9:b4:0d:61:cc:63:7e:d7:2e:77:8c:96:1c:2a:23:68:6b:85:
+ 57:76:70:33:13:fe:e1:4f:a6:23:77:18:fa:1a:8c:e8:bd:65:
+ c9:cf:3f:f4:c9:17:dc:eb:c7:bc:c0:04:2e:2d:46:2f:69:66:
+ c3:1b:8f:fe:ec:3e:d3:ca:94:bf:76:0a:25:0d:a9:7b:02:1c:
+ a9:d0:3b:5f:0b:c0:81:3a:3d:64:e1:bf:a7:2d:4e:bd:4d:c4:
+ d8:29:c6:22:18:d0:c5:ac:72:02:82:3f:aa:3a:a2:3a:22:97:
+ 31:dd:08:63:c3:75:14:b9:60:28:2d:5b:68:e0:16:a9:66:82:
+ 23:51:f5:eb:53:d8:31:9b:7b:e9:b7:9d:4b:eb:88:16:cf:f9:
+ 5d:38:8a:49:30:8f:ed:f1:eb:19:f4:77:1a:31:18:4d:67:54:
+ 6c:2f:6f:65:f9:db:3d:ec:21:ec:5e:f4:f4:8b:ca:60:65:54:
+ d1:71:64:f4:f9:a6:a3:81:33:36:33:71:f0:a4:78:5f:4e:ad:
+ 83:21:de:34:49:8d:e8:59:ac:9d:f2:76:5a:36:f2:13:f4:af:
+ e0:09:c7:61:2a:6c:f7:e0:9d:ae:bb:86:4a:28:6f:2e:ee:b4:
+ 79:cd:90:33:c3:b3:76:fa:f5:f0:6c:9d:01:90:fa:9e:90:f6:
+ 9c:72:cf:47:da:c3:1f:e4:35:20:53:f2:54:d1:df:61:83:a6:
+ 02:e2:25:38:de:85:32:2d:5e:73:90:52:5d:42:c4:ce:3d:4b:
+ e1:f9:19:84:1d:d5:a2:50:cc:41:fb:41:14:c3:bd:d6:c9:5a:
+ a3:63:66:02:80:bd:05:3a:3b:47:9c:ec:00:26:4c:f5:88:51:
+ bf:a8:23:7f:18:07:b0:0b:ed:8b:26:a1:64:d3:61:4a:eb:5c:
+ 9f:de:b3:af:67:03:b3:1f:dd:6d:5d:69:68:69:ab:5e:3a:ec:
+ 7c:69:bc:c7:3b:85:4e:9e:15:b9:b4:15:4f:c3:95:7a:58:d7:
+ c9:6c:e9:6c:b9:f3:29:63:5e:b4:2c:f0:2d:3d:ed:5a:65:e0:
+ a9:5b:40:c2:48:99:81:6d:9e:1f:06:2a:3c:12:b4:8b:0f:9b:
+ a2:24:f0:a6:8d:d6:7a:e0:4b:b6:64:96:63:95:84:c2:4a:cd:
+ 1c:2e:24:87:33:60:e5:c3
+SHA1 Fingerprint=1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67
diff --git a/luni/src/main/files/cacerts/5a5372fc.0 b/luni/src/main/files/cacerts/5a5372fc.0
deleted file mode 100644
index b69d119..0000000
--- a/luni/src/main/files/cacerts/5a5372fc.0
+++ /dev/null
@@ -1,74 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx
-ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
-b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD
-EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05
-OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G
-A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
-Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l
-dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG
-SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK
-gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX
-iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc
-Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E
-BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G
-SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu
-b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh
-bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv
-Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln
-aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0
-IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
-c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph
-biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo
-ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP
-UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj
-YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo
-dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA
-bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06
-sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa
-n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS
-NitjrFgBazMpUIaD8QFI
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 105 (0x69)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=HU, L=Budapest, O=NetLock Halozatbiztonsagi Kft., OU=Tanusitvanykiadok, CN=NetLock Uzleti (Class B) Tanusitvanykiado
- Validity
- Not Before: Feb 25 14:10:22 1999 GMT
- Not After : Feb 20 14:10:22 2019 GMT
- Subject: C=HU, L=Budapest, O=NetLock Halozatbiztonsagi Kft., OU=Tanusitvanykiadok, CN=NetLock Uzleti (Class B) Tanusitvanykiado
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:b1:ea:04:ec:20:a0:23:c2:8f:38:60:cf:c7:46:
- b3:d5:1b:fe:fb:b9:99:9e:04:dc:1c:7f:8c:4a:81:
- 98:ee:a4:d4:ca:8a:17:b9:22:7f:83:0a:75:4c:9b:
- c0:69:d8:64:39:a3:ed:92:a3:fd:5b:5c:74:1a:c0:
- 47:ca:3a:69:76:9a:ba:e2:44:17:fc:4c:a3:d5:fe:
- b8:97:88:af:88:03:89:1f:a4:f2:04:3e:c8:07:0b:
- e6:f9:b3:2f:7a:62:14:09:46:14:ca:64:f5:8b:80:
- b5:62:a8:d8:6b:d6:71:93:2d:b3:bf:09:54:58:ed:
- 06:eb:a8:7b:dc:43:b1:a1:69
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:4
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Netscape Cert Type:
- SSL CA, S/MIME CA, Object Signing CA
- Netscape Comment:
- FIGYELEM! Ezen tanusitvany a NetLock Kft. Altalanos Szolgaltatasi Felteteleiben leirt eljarasok alapjan keszult. A hitelesites folyamatat a NetLock Kft. termekfelelosseg-biztositasa vedi. A digitalis alairas elfogadasanak feltetele az eloirt ellenorzesi eljaras megtetele. Az eljaras leirasa megtalalhato a NetLock Kft. Internet honlapjan a https://www.netlock.net/docs cimen vagy kerheto az ellenorzes@netlock.net e-mail cimen. IMPORTANT! The issuance and the use of this certificate is subject to the NetLock CPS available at https://www.netlock.net/docs or by e-mail at cps@netlock.net.
- Signature Algorithm: md5WithRSAEncryption
- 04:db:ae:8c:17:af:f8:0e:90:31:4e:cd:3e:09:c0:6d:3a:b0:
- f8:33:4c:47:4c:e3:75:88:10:97:ac:b0:38:15:91:c6:29:96:
- cc:21:c0:6d:3c:a5:74:cf:d8:82:a5:39:c3:65:e3:42:70:bb:
- 22:90:e3:7d:db:35:76:e1:a0:b5:da:9f:70:6e:93:1a:30:39:
- 1d:30:db:2e:e3:7c:b2:91:b2:d1:37:29:fa:b9:d6:17:5c:47:
- 4f:e3:1d:38:eb:9f:d5:7b:95:a8:28:9e:15:4a:d1:d1:d0:2b:
- 00:97:a0:e2:92:36:2b:63:ac:58:01:6b:33:29:50:86:83:f1:
- 01:48
-SHA1 Fingerprint=87:9F:4B:EE:05:DF:98:58:3B:E3:60:D6:33:E7:0D:3F:FE:98:71:AF
diff --git a/luni/src/main/files/cacerts/635ccfd5.0 b/luni/src/main/files/cacerts/635ccfd5.0
deleted file mode 100644
index 79753cd..0000000
--- a/luni/src/main/files/cacerts/635ccfd5.0
+++ /dev/null
@@ -1,74 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx
-ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
-b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD
-EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X
-DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw
-DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u
-c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr
-TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN
-BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA
-OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC
-2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW
-RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P
-AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW
-ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0
-YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz
-b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO
-ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB
-IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs
-b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
-ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s
-YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg
-a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g
-SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0
-aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg
-YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg
-Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY
-ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g
-pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4
-Fp1hBWeAyNDYpQcCNJgEjTME1A==
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 104 (0x68)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=HU, L=Budapest, O=NetLock Halozatbiztonsagi Kft., OU=Tanusitvanykiadok, CN=NetLock Expressz (Class C) Tanusitvanykiado
- Validity
- Not Before: Feb 25 14:08:11 1999 GMT
- Not After : Feb 20 14:08:11 2019 GMT
- Subject: C=HU, L=Budapest, O=NetLock Halozatbiztonsagi Kft., OU=Tanusitvanykiadok, CN=NetLock Expressz (Class C) Tanusitvanykiado
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:eb:ec:b0:6c:61:8a:23:25:af:60:20:e3:d9:9f:
- fc:93:0b:db:5d:8d:b0:a1:b3:40:3a:82:ce:fd:75:
- e0:78:32:03:86:5a:86:95:91:ed:53:fa:9d:40:fc:
- e6:e8:dd:d9:5b:7a:03:bd:5d:f3:3b:0c:c3:51:79:
- 9b:ad:55:a0:e9:d0:03:10:af:0a:ba:14:42:d9:52:
- 26:11:22:c7:d2:20:cc:82:a4:9a:a9:fe:b8:81:76:
- 9d:6a:b7:d2:36:75:3e:b1:86:09:f6:6e:6d:7e:4e:
- b7:7a:ec:ae:71:84:f6:04:33:08:25:32:eb:74:ac:
- 16:44:c6:e4:40:93:1d:7f:ad
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:4
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Netscape Cert Type:
- SSL CA, S/MIME CA, Object Signing CA
- Netscape Comment:
- FIGYELEM! Ezen tanusitvany a NetLock Kft. Altalanos Szolgaltatasi Felteteleiben leirt eljarasok alapjan keszult. A hitelesites folyamatat a NetLock Kft. termekfelelosseg-biztositasa vedi. A digitalis alairas elfogadasanak feltetele az eloirt ellenorzesi eljaras megtetele. Az eljaras leirasa megtalalhato a NetLock Kft. Internet honlapjan a https://www.netlock.net/docs cimen vagy kerheto az ellenorzes@netlock.net e-mail cimen. IMPORTANT! The issuance and the use of this certificate is subject to the NetLock CPS available at https://www.netlock.net/docs or by e-mail at cps@netlock.net.
- Signature Algorithm: md5WithRSAEncryption
- 10:ad:7f:d7:0c:32:80:0a:d8:86:f1:79:98:b5:ad:d4:cd:b3:
- 36:c4:96:48:c1:5c:cd:9a:d9:05:2e:9f:be:50:eb:f4:26:14:
- 10:2d:d4:66:17:f8:9e:c1:27:fd:f1:ed:e4:7b:4b:a0:6c:b5:
- ab:9a:57:70:a6:ed:a0:a4:ed:2e:f5:fd:fc:bd:fe:4d:37:08:
- 0c:bc:e3:96:83:22:f5:49:1b:7f:4b:2b:b4:54:c1:80:7c:99:
- 4e:1d:d0:8c:ee:d0:ac:e5:92:fa:75:56:fe:64:a0:13:8f:b8:
- b8:16:9d:61:05:67:80:c8:d0:d8:a5:07:02:34:98:04:8d:33:
- 04:d4
-SHA1 Fingerprint=E3:92:51:2F:0A:CF:F5:05:DF:F6:DE:06:7F:75:37:E1:65:EA:57:4B
diff --git a/luni/src/main/files/cacerts/6adf0799.0 b/luni/src/main/files/cacerts/6adf0799.0
deleted file mode 100644
index 74b4813..0000000
--- a/luni/src/main/files/cacerts/6adf0799.0
+++ /dev/null
@@ -1,80 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC
-VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v
-dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0
-MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww
-KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G
-A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13
-5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE
-SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O
-JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu
-ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE
-AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB
-AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB
-CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw
-b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo
-7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/
-0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7
-nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx
-x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ
-33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 971282334 (0x39e4979e)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Wells Fargo, OU=Wells Fargo Certification Authority, CN=Wells Fargo Root Certificate Authority
- Validity
- Not Before: Oct 11 16:41:28 2000 GMT
- Not After : Jan 14 16:41:28 2021 GMT
- Subject: C=US, O=Wells Fargo, OU=Wells Fargo Certification Authority, CN=Wells Fargo Root Certificate Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d5:a8:33:3b:26:f9:34:ff:cd:9b:7e:e5:04:47:
- ce:00:e2:7d:77:e7:31:c2:2e:27:a5:4d:68:b9:31:
- ba:8d:43:59:97:c7:73:aa:7f:3d:5c:40:9e:05:e5:
- a1:e2:89:d9:4c:b8:3f:9b:f9:0c:b4:c8:62:19:2c:
- 45:ae:91:1e:73:71:41:c4:4b:13:fd:70:c2:25:ac:
- 22:f5:75:0b:b7:53:e4:a5:2b:dd:ce:bd:1c:3a:7a:
- c3:f7:13:8f:26:54:9c:16:6b:6b:af:fb:d8:96:b1:
- 60:9a:48:e0:25:22:24:79:34:ce:0e:26:00:0b:4e:
- ab:fd:8b:ce:82:d7:2f:08:70:68:c1:a8:0a:f9:74:
- 4f:07:ab:a4:f9:e2:83:7e:27:73:74:3e:b8:f9:38:
- 42:fc:a5:a8:5b:48:23:b3:eb:e3:25:b2:80:ae:96:
- d4:0a:9c:c2:78:9a:c6:68:18:ae:37:62:37:5e:51:
- 75:a8:58:63:c0:51:ee:40:78:7e:a8:af:1a:a0:e1:
- b0:78:9d:50:8c:7b:e7:b3:fc:8e:23:b0:db:65:00:
- 70:84:01:08:00:14:6e:54:86:9a:ba:cc:f9:37:10:
- f6:e0:de:84:2d:9d:a4:85:37:d3:87:e3:15:d0:c1:
- 17:90:7e:19:21:6a:12:a9:76:fd:12:02:e9:4f:21:
- 5e:17
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.114171.903.1.11
- CPS: http://www.wellsfargo.com/certpolicy
-
- Signature Algorithm: sha1WithRSAEncryption
- d2:27:dd:9c:0a:77:2b:bb:22:f2:02:b5:4a:4a:91:f9:d1:2d:
- be:e4:bb:1a:68:ef:0e:a4:00:e9:ee:e7:ef:ee:f6:f9:e5:74:
- a4:c2:d8:52:58:c4:74:fb:ce:6b:b5:3b:29:79:18:5a:ef:9b:
- ed:1f:6b:36:ee:48:25:25:14:b6:56:a2:10:e8:ee:a7:7f:d0:
- 3f:a3:d0:c3:5d:26:ee:07:cc:c3:c1:24:21:87:1e:df:2a:12:
- 53:6f:41:16:e7:ed:ae:94:fa:8c:72:fa:13:47:f0:3c:7e:ae:
- 7d:11:3a:13:ec:ed:fa:6f:72:64:7b:9d:7d:7f:26:fd:7a:fb:
- 25:ad:ea:3e:29:7f:4c:e3:00:57:32:b0:b3:e9:ed:53:17:d9:
- 8b:b2:14:0e:30:e8:e5:d5:13:c6:64:af:c4:00:d5:d8:58:24:
- fc:f5:8f:ec:f1:c7:7d:a5:db:0f:27:d1:c6:f2:40:88:e6:1f:
- f6:61:a8:f4:42:c8:b9:37:d3:a9:be:2c:56:78:c2:72:9b:59:
- 5d:35:40:8a:e8:4e:63:1a:b6:e9:20:6a:51:e2:ce:a4:90:df:
- 76:70:99:5c:70:43:4d:b7:b6:a7:19:64:4e:92:b7:c5:91:3c:
- 7f:48:16:65:7b:16:fd:cb:fc:fb:d9:d5:d6:4f:21:65:3b:4a:
- 7f:47:a3:fb
-SHA1 Fingerprint=93:E6:AB:22:03:03:B5:23:28:DC:DA:56:9E:BA:E4:D1:D1:CC:FB:65
diff --git a/luni/src/main/files/cacerts/8d6437c3.0 b/luni/src/main/files/cacerts/8d6437c3.0
new file mode 100644
index 0000000..2097b64
--- /dev/null
+++ b/luni/src/main/files/cacerts/8d6437c3.0
@@ -0,0 +1,80 @@
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 0b:93:1c:3a:d6:39:67:ea:67:23:bf:c3:af:9a:f4:4b
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G2
+ Validity
+ Not Before: Aug 1 12:00:00 2013 GMT
+ Not After : Jan 15 12:00:00 2038 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d9:e7:28:2f:52:3f:36:72:49:88:93:34:f3:f8:
+ 6a:1e:31:54:80:9f:ad:54:41:b5:47:df:96:a8:d4:
+ af:80:2d:b9:0a:cf:75:fd:89:a5:7d:24:fa:e3:22:
+ 0c:2b:bc:95:17:0b:33:bf:19:4d:41:06:90:00:bd:
+ 0c:4d:10:fe:07:b5:e7:1c:6e:22:55:31:65:97:bd:
+ d3:17:d2:1e:62:f3:db:ea:6c:50:8c:3f:84:0c:96:
+ cf:b7:cb:03:e0:ca:6d:a1:14:4c:1b:89:dd:ed:00:
+ b0:52:7c:af:91:6c:b1:38:13:d1:e9:12:08:c0:00:
+ b0:1c:2b:11:da:77:70:36:9b:ae:ce:79:87:dc:82:
+ 70:e6:09:74:70:55:69:af:a3:68:9f:bf:dd:b6:79:
+ b3:f2:9d:70:29:55:f4:ab:ff:95:61:f3:c9:40:6f:
+ 1d:d1:be:93:bb:d3:88:2a:bb:9d:bf:72:5a:56:71:
+ 3b:3f:d4:f3:d1:0a:fe:28:ef:a3:ee:d9:99:af:03:
+ d3:8f:60:b7:f2:92:a1:b1:bd:89:89:1f:30:cd:c3:
+ a6:2e:62:33:ae:16:02:77:44:5a:e7:81:0a:3c:a7:
+ 44:2e:79:b8:3f:04:bc:5c:a0:87:e1:1b:af:51:8e:
+ cd:ec:2c:fa:f8:fe:6d:f0:3a:7c:aa:8b:e4:67:95:
+ 31:8d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ CE:C3:4A:B9:99:55:F2:B8:DB:60:BF:A9:7E:BD:56:B5:97:36:A7:D6
+ Signature Algorithm: sha256WithRSAEncryption
+ ca:a5:55:8c:e3:c8:41:6e:69:27:a7:75:11:ef:3c:86:36:6f:
+ d2:9d:c6:78:38:1d:69:96:a2:92:69:2e:38:6c:9b:7d:04:d4:
+ 89:a5:b1:31:37:8a:c9:21:cc:ab:6c:cd:8b:1c:9a:d6:bf:48:
+ d2:32:66:c1:8a:c0:f3:2f:3a:ef:c0:e3:d4:91:86:d1:50:e3:
+ 03:db:73:77:6f:4a:39:53:ed:de:26:c7:b5:7d:af:2b:42:d1:
+ 75:62:e3:4a:2b:02:c7:50:4b:e0:69:e2:96:6c:0e:44:66:10:
+ 44:8f:ad:05:eb:f8:79:ac:a6:1b:e8:37:34:9d:53:c9:61:aa:
+ a2:52:af:4a:70:16:86:c2:3a:c8:b1:13:70:36:d8:cf:ee:f4:
+ 0a:34:d5:5b:4c:fd:07:9c:a2:ba:d9:01:72:5c:f3:4d:c1:dd:
+ 0e:b1:1c:0d:c4:63:be:ad:f4:14:fb:89:ec:a2:41:0e:4c:cc:
+ c8:57:40:d0:6e:03:aa:cd:0c:8e:89:99:99:6c:f0:3c:30:af:
+ 38:df:6f:bc:a3:be:29:20:27:ab:74:ff:13:22:78:de:97:52:
+ 55:1e:83:b5:54:20:03:ee:ae:c0:4f:56:de:37:cc:c3:7f:aa:
+ 04:27:bb:d3:77:b8:62:db:17:7c:9c:28:22:13:73:6c:cf:26:
+ f5:8a:29:e7
+SHA1 Fingerprint=A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F
diff --git a/luni/src/main/files/cacerts/961f5451.0 b/luni/src/main/files/cacerts/961f5451.0
new file mode 100644
index 0000000..2a61cb0
--- /dev/null
+++ b/luni/src/main/files/cacerts/961f5451.0
@@ -0,0 +1,121 @@
+-----BEGIN CERTIFICATE-----
+MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV
+MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
+BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw
+MTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
+b1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN
+rLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U
+fcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc
+f+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2
+ZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M
+x1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR
+aG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch
+zDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar
+uHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K
+mYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA
+Sh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv
+HYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H
+EtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
+LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ
+MuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e
+JXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN
+g64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp
+dIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab
+R80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ
+PkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce
+xGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+
+J7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl
+OtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT
+ee5Ehr7XHuQe+w==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 5e:68:d6:11:71:94:63:50:56:00:68:f3:3e:c9:c5:91
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
+ Validity
+ Not Before: Aug 8 01:00:01 2009 GMT
+ Not After : Aug 8 01:00:01 2039 GMT
+ Subject: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:bd:ca:8d:ac:b8:91:15:56:97:7b:6b:5c:7a:c2:
+ de:6b:d9:a1:b0:c3:10:23:fa:a7:a1:b2:cc:31:fa:
+ 3e:d9:a6:29:6f:16:3d:e0:6b:f8:b8:40:5f:db:39:
+ a8:00:7a:8b:a0:4d:54:7d:c2:22:78:fc:8e:09:b8:
+ a8:85:d7:cc:95:97:4b:74:d8:9e:7e:f0:00:e4:0e:
+ 89:ae:49:28:44:1a:10:99:32:0f:25:88:53:a4:0d:
+ b3:0f:12:08:16:0b:03:71:27:1c:7f:e1:db:d2:fd:
+ 67:68:c4:05:5d:0a:0e:5d:70:d7:d8:97:a0:bc:53:
+ 41:9a:91:8d:f4:9e:36:66:7a:7e:56:c1:90:5f:e6:
+ b1:68:20:36:a4:8c:24:2c:2c:47:0b:59:76:66:30:
+ b5:be:de:ed:8f:f8:9d:d3:bb:01:30:e6:f2:f3:0e:
+ e0:2c:92:80:f3:85:f9:28:8a:b4:54:2e:9a:ed:f7:
+ 76:fc:15:68:16:eb:4a:6c:eb:2e:12:8f:d4:cf:fe:
+ 0c:c7:5c:1d:0b:7e:05:32:be:5e:b0:09:2a:42:d5:
+ c9:4e:90:b3:59:0d:bb:7a:7e:cd:d5:08:5a:b4:7f:
+ d8:1c:69:11:f9:27:0f:7b:06:af:54:83:18:7b:e1:
+ dd:54:7a:51:68:6e:77:fc:c6:bf:52:4a:66:46:a1:
+ b2:67:1a:bb:a3:4f:77:a0:be:5d:ff:fc:56:0b:43:
+ 72:77:90:ca:9e:f9:f2:39:f5:0d:a9:f4:ea:d7:e7:
+ b3:10:2f:30:42:37:21:cc:30:70:c9:86:98:0f:cc:
+ 58:4d:83:bb:7d:e5:1a:a5:37:8d:b6:ac:32:97:00:
+ 3a:63:71:24:1e:9e:37:c4:ff:74:d4:37:c0:e2:fe:
+ 88:46:60:11:dd:08:3f:50:36:ab:b8:7a:a4:95:62:
+ 6a:6e:b0:ca:6a:21:5a:69:f3:f3:fb:1d:70:39:95:
+ f3:a7:6e:a6:81:89:a1:88:c5:3b:71:ca:a3:52:ee:
+ 83:bb:fd:a0:77:f4:e4:6f:e7:42:db:6d:4a:99:8a:
+ 34:48:bc:17:dc:e4:80:08:22:b6:f2:31:c0:3f:04:
+ 3e:eb:9f:20:79:d6:b8:06:64:64:02:31:d7:a9:cd:
+ 52:fb:84:45:69:09:00:2a:dc:55:8b:c4:06:46:4b:
+ c0:4a:1d:09:5b:39:28:fd:a9:ab:ce:00:f9:2e:48:
+ 4b:26:e6:30:4c:a5:58:ca:b4:44:82:4f:e7:91:1e:
+ 33:c3:b0:93:ff:11:fc:81:d2:ca:1f:71:29:dd:76:
+ 4f:92:25:af:1d:81:b7:0f:2f:8c:c3:06:cc:2f:27:
+ a3:4a:e4:0e:99:ba:7c:1e:45:1f:7f:aa:19:45:96:
+ fd:fc:3d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E
+ Signature Algorithm: sha1WithRSAEncryption
+ a8:cb:72:40:b2:76:c1:7e:7b:fc:ad:64:e3:32:7b:cc:3c:b6:
+ 5d:46:d3:f5:2c:e2:70:5d:c8:2e:d8:06:7d:98:d1:0b:21:a0:
+ 89:59:24:01:9d:f9:af:09:7d:0a:23:82:34:d5:fc:7c:72:99:
+ b9:a3:d7:54:f4:ea:52:70:0e:c5:f5:d6:3b:e1:3a:09:32:e6:
+ 21:39:93:bd:b3:15:ea:4f:6a:f4:f5:8b:3f:2f:7c:8d:58:2e:
+ c5:e1:39:a0:3e:c7:3d:4a:73:9e:40:7a:c0:2b:61:a9:67:c9:
+ f3:24:b9:b3:6d:55:2c:5a:1d:9e:25:72:ce:0b:ad:aa:c7:55:
+ 62:0b:be:fb:63:b3:61:44:23:a3:cb:e1:1a:0e:f7:9a:06:4d:
+ de:d4:23:4e:21:96:5b:39:5b:57:1d:2f:5d:08:5e:09:79:ff:
+ 7c:97:b5:4d:83:ae:0d:d6:e6:a3:79:e0:33:d0:99:96:02:30:
+ a7:3e:ff:d2:a3:43:3f:05:5a:06:ea:44:02:da:7c:f8:48:d0:
+ 33:a9:f9:07:c7:95:e1:f5:3e:f5:5d:71:ba:f2:95:a9:74:88:
+ 61:59:e3:bf:ca:5a:13:ba:72:b4:8c:5d:36:87:e9:a6:c5:3c:
+ 13:bf:de:d0:44:26:ee:b7:ec:2e:70:fa:d7:9d:b7:ac:e5:c5:
+ 40:5a:e6:d7:6c:7b:2c:c3:56:9b:47:cd:0b:ce:fa:1b:b4:21:
+ d7:b7:66:b8:f4:25:30:8b:5c:0d:b9:ea:67:b2:f4:6d:ae:d5:
+ a1:9e:4f:d8:9f:e9:27:02:b0:1d:06:d6:8f:e3:fb:48:12:9f:
+ 7f:11:a1:10:3e:4c:51:3a:96:b0:d1:13:f1:c7:d8:26:ae:3a:
+ ca:91:c4:69:9d:df:01:29:64:51:6f:68:da:14:ec:08:41:97:
+ 90:8d:d0:b2:80:f2:cf:c2:3d:bf:91:68:c5:80:67:1e:c4:60:
+ 13:55:d5:61:99:57:7c:ba:95:0f:61:49:3a:ca:75:bc:c9:0a:
+ 93:3f:67:0e:12:f2:28:e2:31:1b:c0:57:16:df:08:7c:19:c1:
+ 7e:0f:1f:85:1e:0a:36:7c:5b:7e:27:bc:7a:bf:e0:db:f4:da:
+ 52:bd:de:0c:54:70:31:91:43:95:c8:bc:f0:3e:dd:09:7e:30:
+ 64:50:ed:7f:01:a4:33:67:4d:68:4f:be:15:ef:b0:f6:02:11:
+ a2:1b:13:25:3a:dc:c2:59:f1:e3:5c:46:bb:67:2c:02:46:ea:
+ 1e:48:a6:e6:5b:d9:b5:bc:51:a2:92:96:db:aa:c6:37:22:a6:
+ fe:cc:20:74:a3:2d:a9:2e:6b:cb:c0:82:11:21:b5:93:79:ee:
+ 44:86:be:d7:1e:e4:1e:fb
+SHA1 Fingerprint=B9:42:94:BF:91:EA:8F:B6:4B:E6:10:97:C7:FB:00:13:59:B6:76:CB
diff --git a/luni/src/main/files/cacerts/a2c66da8.0 b/luni/src/main/files/cacerts/a2c66da8.0
new file mode 100644
index 0000000..f922408
--- /dev/null
+++ b/luni/src/main/files/cacerts/a2c66da8.0
@@ -0,0 +1,121 @@
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 05:9b:1b:57:9e:8e:21:32:e2:39:07:bd:a7:77:75:5c
+ Signature Algorithm: sha384WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Trusted Root G4
+ Validity
+ Not Before: Aug 1 12:00:00 2013 GMT
+ Not After : Jan 15 12:00:00 2038 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Trusted Root G4
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:bf:e6:90:73:68:de:bb:e4:5d:4a:3c:30:22:30:
+ 69:33:ec:c2:a7:25:2e:c9:21:3d:f2:8a:d8:59:c2:
+ e1:29:a7:3d:58:ab:76:9a:cd:ae:7b:1b:84:0d:c4:
+ 30:1f:f3:1b:a4:38:16:eb:56:c6:97:6d:1d:ab:b2:
+ 79:f2:ca:11:d2:e4:5f:d6:05:3c:52:0f:52:1f:c6:
+ 9e:15:a5:7e:be:9f:a9:57:16:59:55:72:af:68:93:
+ 70:c2:b2:ba:75:99:6a:73:32:94:d1:10:44:10:2e:
+ df:82:f3:07:84:e6:74:3b:6d:71:e2:2d:0c:1b:ee:
+ 20:d5:c9:20:1d:63:29:2d:ce:ec:5e:4e:c8:93:f8:
+ 21:61:9b:34:eb:05:c6:5e:ec:5b:1a:bc:eb:c9:cf:
+ cd:ac:34:40:5f:b1:7a:66:ee:77:c8:48:a8:66:57:
+ 57:9f:54:58:8e:0c:2b:b7:4f:a7:30:d9:56:ee:ca:
+ 7b:5d:e3:ad:c9:4f:5e:e5:35:e7:31:cb:da:93:5e:
+ dc:8e:8f:80:da:b6:91:98:40:90:79:c3:78:c7:b6:
+ b1:c4:b5:6a:18:38:03:10:8d:d8:d4:37:a4:2e:05:
+ 7d:88:f5:82:3e:10:91:70:ab:55:82:41:32:d7:db:
+ 04:73:2a:6e:91:01:7c:21:4c:d4:bc:ae:1b:03:75:
+ 5d:78:66:d9:3a:31:44:9a:33:40:bf:08:d7:5a:49:
+ a4:c2:e6:a9:a0:67:dd:a4:27:bc:a1:4f:39:b5:11:
+ 58:17:f7:24:5c:46:8f:64:f7:c1:69:88:76:98:76:
+ 3d:59:5d:42:76:87:89:97:69:7a:48:f0:e0:a2:12:
+ 1b:66:9a:74:ca:de:4b:1e:e7:0e:63:ae:e6:d4:ef:
+ 92:92:3a:9e:3d:dc:00:e4:45:25:89:b6:9a:44:19:
+ 2b:7e:c0:94:b4:d2:61:6d:eb:33:d9:c5:df:4b:04:
+ 00:cc:7d:1c:95:c3:8f:f7:21:b2:b2:11:b7:bb:7f:
+ f2:d5:8c:70:2c:41:60:aa:b1:63:18:44:95:1a:76:
+ 62:7e:f6:80:b0:fb:e8:64:a6:33:d1:89:07:e1:bd:
+ b7:e6:43:a4:18:b8:a6:77:01:e1:0f:94:0c:21:1d:
+ b2:54:29:25:89:6c:e5:0e:52:51:47:74:be:26:ac:
+ b6:41:75:de:7a:ac:5f:8d:3f:c9:bc:d3:41:11:12:
+ 5b:e5:10:50:eb:31:c5:ca:72:16:22:09:df:7c:4c:
+ 75:3f:63:ec:21:5f:c4:20:51:6b:6f:b1:ab:86:8b:
+ 4f:c2:d6:45:5f:9d:20:fc:a1:1e:c5:c0:8f:a2:b1:
+ 7e:0a:26:99:f5:e4:69:2f:98:1d:2d:f5:d9:a9:b2:
+ 1d:e5:1b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ EC:D7:E3:82:D2:71:5D:64:4C:DF:2E:67:3F:E7:BA:98:AE:1C:0F:4F
+ Signature Algorithm: sha384WithRSAEncryption
+ bb:61:d9:7d:a9:6c:be:17:c4:91:1b:c3:a1:a2:00:8d:e3:64:
+ 68:0f:56:cf:77:ae:70:f9:fd:9a:4a:99:b9:c9:78:5c:0c:0c:
+ 5f:e4:e6:14:29:56:0b:36:49:5d:44:63:e0:ad:9c:96:18:66:
+ 1b:23:0d:3d:79:e9:6d:6b:d6:54:f8:d2:3c:c1:43:40:ae:1d:
+ 50:f5:52:fc:90:3b:bb:98:99:69:6b:c7:c1:a7:a8:68:a4:27:
+ dc:9d:f9:27:ae:30:85:b9:f6:67:4d:3a:3e:8f:59:39:22:53:
+ 44:eb:c8:5d:03:ca:ed:50:7a:7d:62:21:0a:80:c8:73:66:d1:
+ a0:05:60:5f:e8:a5:b4:a7:af:a8:f7:6d:35:9c:7c:5a:8a:d6:
+ a2:38:99:f3:78:8b:f4:4d:d2:20:0b:de:04:ee:8c:9b:47:81:
+ 72:0d:c0:14:32:ef:30:59:2e:ae:e0:71:f2:56:e4:6a:97:6f:
+ 92:50:6d:96:8d:68:7a:9a:b2:36:14:7a:06:f2:24:b9:09:11:
+ 50:d7:08:b1:b8:89:7a:84:23:61:42:29:e5:a3:cd:a2:20:41:
+ d7:d1:9c:64:d9:ea:26:a1:8b:14:d7:4c:19:b2:50:41:71:3d:
+ 3f:4d:70:23:86:0c:4a:dc:81:d2:cc:32:94:84:0d:08:09:97:
+ 1c:4f:c0:ee:6b:20:74:30:d2:e0:39:34:10:85:21:15:01:08:
+ e8:55:32:de:71:49:d9:28:17:50:4d:e6:be:4d:d1:75:ac:d0:
+ ca:fb:41:b8:43:a5:aa:d3:c3:05:44:4f:2c:36:9b:e2:fa:e2:
+ 45:b8:23:53:6c:06:6f:67:55:7f:46:b5:4c:3f:6e:28:5a:79:
+ 26:d2:a4:a8:62:97:d2:1e:e2:ed:4a:8b:bc:1b:fd:47:4a:0d:
+ df:67:66:7e:b2:5b:41:d0:3b:e4:f4:3b:f4:04:63:e9:ef:c2:
+ 54:00:51:a0:8a:2a:c9:ce:78:cc:d5:ea:87:04:18:b3:ce:af:
+ 49:88:af:f3:92:99:b6:b3:e6:61:0f:d2:85:00:e7:50:1a:e4:
+ 1b:95:9d:19:a1:b9:9c:b1:9b:b1:00:1e:ef:d0:0f:4f:42:6c:
+ c9:0a:bc:ee:43:fa:3a:71:a5:c8:4d:26:a5:35:fd:89:5d:bc:
+ 85:62:1d:32:d2:a0:2b:54:ed:9a:57:c1:db:fa:10:cf:19:b7:
+ 8b:4a:1b:8f:01:b6:27:95:53:e8:b6:89:6d:5b:bc:68:d4:23:
+ e8:8b:51:a2:56:f9:f0:a6:80:a0:d6:1e:b3:bc:0f:0f:53:75:
+ 29:aa:ea:13:77:e4:de:8c:81:21:ad:07:10:47:11:ad:87:3d:
+ 07:d1:75:bc:cf:f3:66:7e
+SHA1 Fingerprint=DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4
diff --git a/luni/src/main/files/cacerts/bcdd5959.0 b/luni/src/main/files/cacerts/bcdd5959.0
deleted file mode 100644
index 39e952b..0000000
--- a/luni/src/main/files/cacerts/bcdd5959.0
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
-NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
-dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
-WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
-v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
-UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
-IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
-W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com
- Validity
- Not Before: Jun 26 00:19:54 1999 GMT
- Not After : Jun 26 00:19:54 2019 GMT
- Subject: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:ce:3a:71:ca:e5:ab:c8:59:92:55:d7:ab:d8:74:
- 0e:f9:ee:d9:f6:55:47:59:65:47:0e:05:55:dc:eb:
- 98:36:3c:5c:53:5d:d3:30:cf:38:ec:bd:41:89:ed:
- 25:42:09:24:6b:0a:5e:b3:7c:dd:52:2d:4c:e6:d4:
- d6:7d:5a:59:a9:65:d4:49:13:2d:24:4d:1c:50:6f:
- b5:c1:85:54:3b:fe:71:e4:d3:5c:42:f9:80:e0:91:
- 1a:0a:5b:39:36:67:f3:3f:55:7c:1b:3f:b4:5f:64:
- 73:34:e3:b4:12:bf:87:64:f8:da:12:ff:37:27:c1:
- b3:43:bb:ef:7b:6e:2e:69:f7
- Exponent: 65537 (0x10001)
- Signature Algorithm: sha1WithRSAEncryption
- 3b:7f:50:6f:6f:50:94:99:49:62:38:38:1f:4b:f8:a5:c8:3e:
- a7:82:81:f6:2b:c7:e8:c5:ce:e8:3a:10:82:cb:18:00:8e:4d:
- bd:a8:58:7f:a1:79:00:b5:bb:e9:8d:af:41:d9:0f:34:ee:21:
- 81:19:a0:32:49:28:f4:c4:8e:56:d5:52:33:fd:50:d5:7e:99:
- 6c:03:e4:c9:4c:fc:cb:6c:ab:66:b3:4a:21:8c:e5:b5:0c:32:
- 3e:10:b2:cc:6c:a1:dc:9a:98:4c:02:5b:f3:ce:b9:9e:a5:72:
- 0e:4a:b7:3f:3c:e6:16:68:f8:be:ed:74:4c:bc:5b:d5:62:1f:
- 43:dd
-SHA1 Fingerprint=31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6
diff --git a/luni/src/main/files/cacerts/c491639e.0 b/luni/src/main/files/cacerts/c491639e.0
new file mode 100644
index 0000000..ec9e422
--- /dev/null
+++ b/luni/src/main/files/cacerts/c491639e.0
@@ -0,0 +1,53 @@
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 0b:a1:5a:fa:1d:df:a0:b5:49:44:af:cd:24:a0:6c:ec
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G3
+ Validity
+ Not Before: Aug 1 12:00:00 2013 GMT
+ Not After : Jan 15 12:00:00 2038 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G3
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:19:e7:bc:ac:44:65:ed:cd:b8:3f:58:fb:8d:b1:
+ 57:a9:44:2d:05:15:f2:ef:0b:ff:10:74:9f:b5:62:
+ 52:5f:66:7e:1f:e5:dc:1b:45:79:0b:cc:c6:53:0a:
+ 9d:8d:5d:02:d9:a9:59:de:02:5a:f6:95:2a:0e:8d:
+ 38:4a:8a:49:c6:bc:c6:03:38:07:5f:55:da:7e:09:
+ 6e:e2:7f:5e:d0:45:20:0f:59:76:10:d6:a0:24:f0:
+ 2d:de:36:f2:6c:29:39
+ ASN1 OID: secp384r1
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ CB:D0:BD:A9:E1:98:05:51:A1:4D:37:A2:83:79:CE:8D:1D:2A:E4:84
+ Signature Algorithm: ecdsa-with-SHA384
+ 30:64:02:30:25:a4:81:45:02:6b:12:4b:75:74:4f:c8:23:e3:
+ 70:f2:75:72:de:7c:89:f0:cf:91:72:61:9e:5e:10:92:59:56:
+ b9:83:c7:10:e7:38:e9:58:26:36:7d:d5:e4:34:86:39:02:30:
+ 7c:36:53:f0:30:e5:62:63:3a:99:e2:b6:a3:3b:9b:34:fa:1e:
+ da:10:92:71:5e:91:13:a7:dd:a4:6e:92:cc:32:d6:f5:21:66:
+ c7:2f:ea:96:63:6a:65:45:92:95:01:b4
+SHA1 Fingerprint=F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89
diff --git a/luni/src/main/files/cacerts/c8763593.0 b/luni/src/main/files/cacerts/c8763593.0
deleted file mode 100644
index 70675c7..0000000
--- a/luni/src/main/files/cacerts/c8763593.0
+++ /dev/null
@@ -1,132 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsx
-CzAJBgNVBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRp
-ZmljYWNpw7NuIERpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwa
-QUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAw
-NDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2Ft
-ZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJhIFMu
-QS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeG
-qentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzL
-fDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQ
-Y5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4
-Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ
-54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+b
-MMCm8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48j
-ilSH5L887uvDdUhfHjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++Ej
-YfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/zt
-A/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5lw1omdMEWux+IBkAC1vImHF
-rEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1bczwmPS9KvqfJ
-pxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCB
-lTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFy
-YS5jb20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW50
-7WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBs
-YSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6
-xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBc
-unvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/
-Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dp
-ezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42
-gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNECW8DYSwaN0
-jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpOe9+
-XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJD
-W2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/
-RL5hRqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35r
-MDOhYil/SrnhLecUIw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxk
-BYn8eNZcLCZDqQ==
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 07:7e:52:93:7b:e0:15:e3:57:f0:69:8c:cb:ec:0c
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=CO, O=Sociedad Cameral de Certificaci\xC3\xB3n Digital - Certic\xC3\xA1mara S.A., CN=AC Ra\xC3\xADz Certic\xC3\xA1mara S.A.
- Validity
- Not Before: Nov 27 20:46:29 2006 GMT
- Not After : Apr 2 21:42:02 2030 GMT
- Subject: C=CO, O=Sociedad Cameral de Certificaci\xC3\xB3n Digital - Certic\xC3\xA1mara S.A., CN=AC Ra\xC3\xADz Certic\xC3\xA1mara S.A.
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:ab:6b:89:a3:53:cc:48:23:08:fb:c3:cf:51:96:
- 08:2e:b8:08:7a:6d:3c:90:17:86:a9:e9:ed:2e:13:
- 34:47:b2:d0:70:dc:c9:3c:d0:8d:ca:ee:4b:17:ab:
- d0:85:b0:a7:23:04:cb:a8:a2:fc:e5:75:db:40:ca:
- 62:89:8f:50:9e:01:3d:26:5b:18:84:1c:cb:7c:37:
- b7:7d:ec:d3:7f:73:19:b0:6a:b2:d8:88:8a:2d:45:
- 74:a8:f7:b3:b8:c0:d4:da:cd:22:89:74:4d:5a:15:
- 39:73:18:74:4f:b5:eb:99:a7:c1:1e:88:b4:c2:93:
- 90:63:97:f3:a7:a7:12:b2:09:22:07:33:d9:91:cd:
- 0e:9c:1f:0e:20:c7:ee:bb:33:8d:8f:c2:d2:58:a7:
- 5f:fd:65:37:e2:88:c2:d8:8f:86:75:5e:f9:2d:a7:
- 87:33:f2:78:37:2f:8b:bc:1d:86:37:39:b1:94:f2:
- d8:bc:4a:9c:83:18:5a:06:fc:f3:d4:d4:ba:8c:15:
- 09:25:f0:f9:b6:8d:04:7e:17:12:33:6b:57:48:4c:
- 4f:db:26:1e:eb:cc:90:e7:8b:f9:68:7c:70:0f:a3:
- 2a:d0:3a:38:df:37:97:e2:5b:de:80:61:d3:80:d8:
- 91:83:42:5a:4c:04:89:68:11:3c:ac:5f:68:80:41:
- cc:60:42:ce:0d:5a:2a:0c:0f:9b:30:c0:a6:f0:86:
- db:ab:49:d7:97:6d:48:8b:f9:03:c0:52:67:9b:12:
- f7:c2:f2:2e:98:65:42:d9:d6:9a:e3:d0:19:31:0c:
- ad:87:d5:57:02:7a:30:e8:86:26:fb:8f:23:8a:54:
- 87:e4:bf:3c:ee:eb:c3:75:48:5f:1e:39:6f:81:62:
- 6c:c5:2d:c4:17:54:19:b7:37:8d:9c:37:91:c8:f6:
- 0b:d5:ea:63:6f:83:ac:38:c2:f3:3f:de:9a:fb:e1:
- 23:61:f0:c8:26:cb:36:c8:a1:f3:30:8f:a4:a3:a2:
- a1:dd:53:b3:de:f0:9a:32:1f:83:91:79:30:c1:a9:
- 1f:53:9b:53:a2:15:53:3f:dd:9d:b3:10:3b:48:7d:
- 89:0f:fc:ed:03:f5:fb:25:64:75:0e:17:19:0d:8f:
- 00:16:67:79:7a:40:fc:2d:59:07:d9:90:fa:9a:ad:
- 3d:dc:80:8a:e6:5c:35:a2:67:4c:11:6b:b1:f8:80:
- 64:00:2d:6f:22:61:c5:ac:4b:26:e5:5a:10:82:9b:
- a4:83:7b:34:f7:9e:89:91:20:97:8e:b7:42:c7:66:
- c3:d0:e9:a4:d6:f5:20:8d:c4:c3:95:ac:44:0a:9d:
- 5b:73:3c:26:3d:2f:4a:be:a7:c9:a7:10:1e:fb:9f:
- 50:69:f3
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- D1:09:D0:E9:D7:CE:79:74:54:F9:3A:30:B3:F4:6D:2C:03:03:1B:68
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.certicamara.com/dpc/
- User Notice:
- Explicit Text: Limitaciones de garantías de este certificado se pueden encontrar en la DPC.
-
- Signature Algorithm: sha1WithRSAEncryption
- 5c:94:b5:b8:45:91:4d:8e:61:1f:03:28:0f:53:7c:e6:a4:59:
- a9:b3:8a:7a:c5:b0:ff:08:7c:2c:a3:71:1c:21:13:67:a1:95:
- 12:40:35:83:83:8f:74:db:33:5c:f0:49:76:0a:81:52:dd:49:
- d4:9a:32:33:ef:9b:a7:cb:75:e5:7a:cb:97:12:90:5c:ba:7b:
- c5:9b:df:bb:39:23:c8:ff:98:ce:0a:4d:22:01:48:07:7e:8a:
- c0:d5:20:42:94:44:ef:bf:77:a2:89:67:48:1b:40:03:05:a1:
- 89:ec:cf:62:e3:3d:25:76:66:bf:26:b7:bb:22:be:6f:ff:39:
- 57:74:ba:7a:c9:01:95:c1:95:51:e8:ab:2c:f8:b1:86:20:e9:
- 3f:cb:35:5b:d2:17:e9:2a:fe:83:13:17:40:ee:88:62:65:5b:
- d5:3b:60:e9:7b:3c:b8:c9:d5:7f:36:02:25:aa:68:c2:31:15:
- b7:30:65:eb:7f:1d:48:79:b1:cf:39:e2:42:80:16:d3:f5:93:
- 23:fc:4c:97:c9:5a:37:6c:7c:22:d8:4a:cd:d2:8e:36:83:39:
- 91:90:10:c8:f1:c9:35:7e:3f:b8:d3:81:c6:20:64:1a:b6:50:
- c2:21:a4:78:dc:d0:2f:3b:64:93:74:f0:96:90:f1:ef:fb:09:
- 5a:34:40:96:f0:36:12:c1:a3:74:8c:93:7e:41:de:77:8b:ec:
- 86:d9:d2:0f:3f:2d:d1:cc:40:a2:89:66:48:1e:20:b3:9c:23:
- 59:73:a9:44:73:bc:24:79:90:56:37:b3:c6:29:7e:a3:0f:f1:
- 29:39:ef:7e:5c:28:32:70:35:ac:da:b8:c8:75:66:fc:9b:4c:
- 39:47:8e:1b:6f:9b:4d:02:54:22:33:ef:61:ba:9e:29:84:ef:
- 4e:4b:33:47:76:97:6a:cb:7e:5f:fd:15:a6:9e:42:43:5b:66:
- 5a:8a:88:0d:f7:16:b9:3f:51:65:2b:66:6a:8b:d1:38:52:a2:
- d6:46:11:fa:fc:9a:1c:74:9e:8f:97:0b:02:4f:64:c6:f5:68:
- d3:4b:2d:ff:a4:37:1e:8b:3f:bf:44:be:61:46:a1:84:3d:08:
- 27:4c:81:20:77:89:08:ea:67:40:5e:6c:08:51:5f:34:5a:8c:
- 96:68:cd:d7:f7:89:c2:1c:d3:32:00:af:52:cb:d3:60:5b:2a:
- 3a:47:7e:6b:30:33:a1:62:29:7f:4a:b9:e1:2d:e7:14:23:0e:
- 0e:18:47:e1:79:fc:15:55:d0:b1:fc:25:71:63:75:33:1c:23:
- 2b:af:5c:d9:ed:47:77:60:0e:3b:0f:1e:d2:c0:dc:64:05:89:
- fc:78:d6:5c:2c:26:43:a9
-SHA1 Fingerprint=CB:A1:C5:F8:B0:E3:5E:B8:B9:45:12:D3:F9:34:A2:E9:06:10:D3:36
diff --git a/luni/src/main/files/cacerts/c90bc37d.0 b/luni/src/main/files/cacerts/c90bc37d.0
new file mode 100644
index 0000000..e4460c1
--- /dev/null
+++ b/luni/src/main/files/cacerts/c90bc37d.0
@@ -0,0 +1,80 @@
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 03:3a:f1:e6:a7:11:a9:a0:bb:28:64:b1:1d:09:fa:e5
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
+ Validity
+ Not Before: Aug 1 12:00:00 2013 GMT
+ Not After : Jan 15 12:00:00 2038 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bb:37:cd:34:dc:7b:6b:c9:b2:68:90:ad:4a:75:
+ ff:46:ba:21:0a:08:8d:f5:19:54:c9:fb:88:db:f3:
+ ae:f2:3a:89:91:3c:7a:e6:ab:06:1a:6b:cf:ac:2d:
+ e8:5e:09:24:44:ba:62:9a:7e:d6:a3:a8:7e:e0:54:
+ 75:20:05:ac:50:b7:9c:63:1a:6c:30:dc:da:1f:19:
+ b1:d7:1e:de:fd:d7:e0:cb:94:83:37:ae:ec:1f:43:
+ 4e:dd:7b:2c:d2:bd:2e:a5:2f:e4:a9:b8:ad:3a:d4:
+ 99:a4:b6:25:e9:9b:6b:00:60:92:60:ff:4f:21:49:
+ 18:f7:67:90:ab:61:06:9c:8f:f2:ba:e9:b4:e9:92:
+ 32:6b:b5:f3:57:e8:5d:1b:cd:8c:1d:ab:95:04:95:
+ 49:f3:35:2d:96:e3:49:6d:dd:77:e3:fb:49:4b:b4:
+ ac:55:07:a9:8f:95:b3:b4:23:bb:4c:6d:45:f0:f6:
+ a9:b2:95:30:b4:fd:4c:55:8c:27:4a:57:14:7c:82:
+ 9d:cd:73:92:d3:16:4a:06:0c:8c:50:d1:8f:1e:09:
+ be:17:a1:e6:21:ca:fd:83:e5:10:bc:83:a5:0a:c4:
+ 67:28:f6:73:14:14:3d:46:76:c3:87:14:89:21:34:
+ 4d:af:0f:45:0c:a6:49:a1:ba:bb:9c:c5:b1:33:83:
+ 29:85
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 4E:22:54:20:18:95:E6:E3:6E:E6:0F:FA:FA:B9:12:ED:06:17:8F:39
+ Signature Algorithm: sha256WithRSAEncryption
+ 60:67:28:94:6f:0e:48:63:eb:31:dd:ea:67:18:d5:89:7d:3c:
+ c5:8b:4a:7f:e9:be:db:2b:17:df:b0:5f:73:77:2a:32:13:39:
+ 81:67:42:84:23:f2:45:67:35:ec:88:bf:f8:8f:b0:61:0c:34:
+ a4:ae:20:4c:84:c6:db:f8:35:e1:76:d9:df:a6:42:bb:c7:44:
+ 08:86:7f:36:74:24:5a:da:6c:0d:14:59:35:bd:f2:49:dd:b6:
+ 1f:c9:b3:0d:47:2a:3d:99:2f:bb:5c:bb:b5:d4:20:e1:99:5f:
+ 53:46:15:db:68:9b:f0:f3:30:d5:3e:31:e2:8d:84:9e:e3:8a:
+ da:da:96:3e:35:13:a5:5f:f0:f9:70:50:70:47:41:11:57:19:
+ 4e:c0:8f:ae:06:c4:95:13:17:2f:1b:25:9f:75:f2:b1:8e:99:
+ a1:6f:13:b1:41:71:fe:88:2a:c8:4f:10:20:55:d7:f3:14:45:
+ e5:e0:44:f4:ea:87:95:32:93:0e:fe:53:46:fa:2c:9d:ff:8b:
+ 22:b9:4b:d9:09:45:a4:de:a4:b8:9a:58:dd:1b:7d:52:9f:8e:
+ 59:43:88:81:a4:9e:26:d5:6f:ad:dd:0d:c6:37:7d:ed:03:92:
+ 1b:e5:77:5f:76:ee:3c:8d:c4:5d:56:5b:a2:d9:66:6e:b3:35:
+ 37:e5:32:b6
+SHA1 Fingerprint=DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4
diff --git a/luni/src/main/files/cacerts/d06393bb.0 b/luni/src/main/files/cacerts/d06393bb.0
new file mode 100644
index 0000000..0029410
--- /dev/null
+++ b/luni/src/main/files/cacerts/d06393bb.0
@@ -0,0 +1,80 @@
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
+AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
+FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
+1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
+jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
+wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
+WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
+NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
+uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
+IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
+g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
+BSeOE6Fuwg==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center, CN=T-TeleSec GlobalRoot Class 2
+ Validity
+ Not Before: Oct 1 10:40:14 2008 GMT
+ Not After : Oct 1 23:59:59 2033 GMT
+ Subject: C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center, CN=T-TeleSec GlobalRoot Class 2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:aa:5f:da:1b:5f:e8:73:91:e5:da:5c:f4:a2:e6:
+ 47:e5:f3:68:55:60:05:1d:02:a4:b3:9b:59:f3:1e:
+ 8a:af:34:ad:fc:0d:c2:d9:48:19:ee:69:8f:c9:20:
+ fc:21:aa:07:19:ed:b0:5c:ac:65:c7:5f:ed:02:7c:
+ 7b:7c:2d:1b:d6:ba:b9:80:c2:18:82:16:84:fa:66:
+ b0:08:c6:54:23:81:e4:cd:b9:49:3f:f6:4f:6e:37:
+ 48:28:38:0f:c5:be:e7:68:70:fd:39:97:4d:d2:c7:
+ 98:91:50:aa:c4:44:b3:23:7d:39:47:e9:52:62:d6:
+ 12:93:5e:b7:31:96:42:05:fb:76:a7:1e:a3:f5:c2:
+ fc:e9:7a:c5:6c:a9:71:4f:ea:cb:78:bc:60:af:c7:
+ de:f4:d9:cb:be:7e:33:a5:6e:94:83:f0:34:fa:21:
+ ab:ea:8e:72:a0:3f:a4:de:30:5b:ef:86:4d:6a:95:
+ 5b:43:44:a8:10:15:1c:e5:01:57:c5:98:f1:e6:06:
+ 28:91:aa:20:c5:b7:53:26:51:43:b2:0b:11:95:58:
+ e1:c0:0f:76:d9:c0:8d:7c:81:f3:72:70:9e:6f:fe:
+ 1a:8e:d9:5f:35:c6:b2:6f:34:7c:be:48:4f:e2:5a:
+ 39:d7:d8:9d:78:9e:9f:86:3e:03:5e:19:8b:44:a2:
+ d5:c7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ BF:59:20:36:00:79:A0:A0:22:6B:8C:D5:F2:61:D2:B8:2C:CB:82:4A
+ Signature Algorithm: sha256WithRSAEncryption
+ 31:03:a2:61:0b:1f:74:e8:72:36:c6:6d:f9:4d:9e:fa:22:a8:
+ e1:81:56:cf:cd:bb:9f:ea:ab:91:19:38:af:aa:7c:15:4d:f3:
+ b6:a3:8d:a5:f4:8e:f6:44:a9:a7:e8:21:95:ad:3e:00:62:16:
+ 88:f0:02:ba:fc:61:23:e6:33:9b:30:7a:6b:36:62:7b:ad:04:
+ 23:84:58:65:e2:db:2b:8a:e7:25:53:37:62:53:5f:bc:da:01:
+ 62:29:a2:a6:27:71:e6:3a:22:7e:c1:6f:1d:95:70:20:4a:07:
+ 34:df:ea:ff:15:80:e5:ba:d7:7a:d8:5b:75:7c:05:7a:29:47:
+ 7e:40:a8:31:13:77:cd:40:3b:b4:51:47:7a:2e:11:e3:47:11:
+ de:9d:66:d0:8b:d5:54:66:fa:83:55:ea:7c:c2:29:89:1b:e9:
+ 6f:b3:ce:e2:05:84:c9:2f:3e:78:85:62:6e:c9:5f:c1:78:63:
+ 74:58:c0:48:18:0c:99:39:eb:a4:cc:1a:b5:79:5a:8d:15:9c:
+ d8:14:0d:f6:7a:07:57:c7:22:83:05:2d:3c:9b:25:26:3d:18:
+ b3:a9:43:7c:c8:c8:ab:64:8f:0e:a3:bf:9c:1b:9d:30:db:da:
+ d0:19:2e:aa:3c:f1:fb:33:80:76:e4:cd:ad:19:4f:05:27:8e:
+ 13:a1:6e:c2
+SHA1 Fingerprint=59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9
diff --git a/luni/src/main/files/cacerts/d537fba6.0 b/luni/src/main/files/cacerts/d537fba6.0
deleted file mode 100644
index 0ae2700..0000000
--- a/luni/src/main/files/cacerts/d537fba6.0
+++ /dev/null
@@ -1,96 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE
-SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg
-Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV
-BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl
-cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA
-vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu
-Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a
-0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1
-4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN
-eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD
-R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG
-A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu
-dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME
-Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3
-WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw
-HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ
-KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO
-Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX
-wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
-2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89
-9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0
-jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38
-aQNiuJkFBT1reBK9sG9l
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 986490188 (0x3acca54c)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=DK, O=TDC Internet, OU=TDC Internet Root CA
- Validity
- Not Before: Apr 5 16:33:17 2001 GMT
- Not After : Apr 5 17:03:17 2021 GMT
- Subject: C=DK, O=TDC Internet, OU=TDC Internet Root CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c4:b8:40:bc:91:d5:63:1f:d7:99:a0:8b:0c:40:
- 1e:74:b7:48:9d:46:8c:02:b2:e0:24:5f:f0:19:13:
- a7:37:83:6b:5d:c7:8e:f9:84:30:ce:1a:3b:fa:fb:
- ce:8b:6d:23:c6:c3:6e:66:9f:89:a5:df:e0:42:50:
- 67:fa:1f:6c:1e:f4:d0:05:d6:bf:ca:d6:4e:e4:68:
- 60:6c:46:aa:1c:5d:63:e1:07:86:0e:65:00:a7:2e:
- a6:71:c6:bc:b9:81:a8:3a:7d:1a:d2:f9:d1:ac:4b:
- cb:ce:75:af:dc:7b:fa:81:73:d4:fc:ba:bd:41:88:
- d4:74:b3:f9:5e:38:3a:3c:43:a8:d2:95:4e:77:6d:
- 13:0c:9d:8f:78:01:b7:5a:20:1f:03:37:35:e2:2c:
- db:4b:2b:2c:78:b9:49:db:c4:d0:c7:9c:9c:e4:8a:
- 20:09:21:16:56:66:ff:05:ec:5b:e3:f0:cf:ab:24:
- 24:5e:c3:7f:70:7a:12:c4:d2:b5:10:a0:b6:21:e1:
- 8d:78:69:55:44:69:f5:ca:96:1c:34:85:17:25:77:
- e2:f6:2f:27:98:78:fd:79:06:3a:a2:d6:5a:43:c1:
- ff:ec:04:3b:ee:13:ef:d3:58:5a:ff:92:eb:ec:ae:
- da:f2:37:03:47:41:b6:97:c9:2d:0a:41:22:bb:bb:
- e6:a7
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- Netscape Cert Type:
- SSL CA, S/MIME CA, Object Signing CA
- X509v3 CRL Distribution Points:
-
- Full Name:
- DirName: C = DK, O = TDC Internet, OU = TDC Internet Root CA, CN = CRL1
-
- X509v3 Private Key Usage Period:
- Not Before: Apr 5 16:33:17 2001 GMT, Not After: Apr 5 17:03:17 2021 GMT
- X509v3 Key Usage:
- Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- keyid:6C:64:01:C7:FD:85:6D:AC:C8:DA:9E:50:08:85:08:B5:3C:56:A8:50
-
- X509v3 Subject Key Identifier:
- 6C:64:01:C7:FD:85:6D:AC:C8:DA:9E:50:08:85:08:B5:3C:56:A8:50
- X509v3 Basic Constraints:
- CA:TRUE
- 1.2.840.113533.7.65.0:
- 0...V5.0:4.0....
- Signature Algorithm: sha1WithRSAEncryption
- 4e:43:cc:d1:dd:1d:10:1b:06:7f:b7:a4:fa:d3:d9:4d:fb:23:
- 9f:23:54:5b:e6:8b:2f:04:28:8b:b5:27:6d:89:a1:ec:98:69:
- dc:e7:8d:26:83:05:79:74:ec:b4:b9:a3:97:c1:35:00:fd:15:
- da:39:81:3a:95:31:90:de:97:e9:86:a8:99:77:0c:e5:5a:a0:
- 84:ff:12:16:ac:6e:b8:8d:c3:7b:92:c2:ac:2e:d0:7d:28:ec:
- b6:f3:60:38:69:6f:3e:d8:04:55:3e:9e:cc:55:d2:ba:fe:bb:
- 47:04:d7:0a:d9:16:0a:34:29:f5:58:13:d5:4f:cf:8f:56:4b:
- b3:1e:ee:d3:98:79:da:08:1e:0c:6f:b8:f8:16:27:ef:c2:6f:
- 3d:f6:a3:4b:3e:0e:e4:6d:6c:db:3b:41:12:9b:bd:0d:47:23:
- 7f:3c:4a:d0:af:c0:af:f6:ef:1b:b5:15:c4:eb:83:c4:09:5f:
- 74:8b:d9:11:fb:c2:56:b1:3c:f8:70:ca:34:8d:43:40:13:8c:
- fd:99:03:54:79:c6:2e:ea:86:a1:f6:3a:d4:09:bc:f4:bc:66:
- cc:3d:58:d0:57:49:0a:ee:25:e2:41:ee:13:f9:9b:38:34:d1:
- 00:f5:7e:e7:94:1d:fc:69:03:62:b8:99:05:05:3d:6b:78:12:
- bd:b0:6f:65
-SHA1 Fingerprint=21:FC:BD:8E:7F:6C:AF:05:1B:D1:B3:43:EC:A8:E7:61:47:F2:0F:8A
diff --git a/luni/src/main/files/cacerts/e442e424.0 b/luni/src/main/files/cacerts/e442e424.0
new file mode 100644
index 0000000..c715660
--- /dev/null
+++ b/luni/src/main/files/cacerts/e442e424.0
@@ -0,0 +1,120 @@
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
+MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
+/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
+FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
+U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
+ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
+FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
+A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
+eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
+sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
+VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
+A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
+ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
+FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
+oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
+u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
+0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
+3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
+8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
+DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
+PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
+ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 2e:f5:9b:02:28:a7:db:7a:ff:d5:a3:a9:ee:bd:03:a0:cf:12:6a:1d
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3 G3
+ Validity
+ Not Before: Jan 12 20:26:32 2012 GMT
+ Not After : Jan 12 20:26:32 2042 GMT
+ Subject: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3 G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:b3:cb:0e:10:67:8e:ea:14:97:a7:32:2a:0a:56:
+ 36:7f:68:4c:c7:b3:6f:3a:23:14:91:ff:19:7f:a5:
+ ca:ac:ee:b3:76:9d:7a:e9:8b:1b:ab:6b:31:db:fa:
+ 0b:53:4c:af:c5:a5:1a:79:3c:8a:4c:ff:ac:df:25:
+ de:4e:d9:82:32:0b:44:de:ca:db:8c:ac:a3:6e:16:
+ 83:3b:a6:64:4b:32:89:fb:16:16:38:7e:eb:43:e2:
+ d3:74:4a:c2:62:0a:73:0a:dd:49:b3:57:d2:b0:0a:
+ 85:9d:71:3c:de:a3:cb:c0:32:f3:01:39:20:43:1b:
+ 35:d1:53:b3:b1:ee:c5:93:69:82:3e:16:b5:28:46:
+ a1:de:ea:89:09:ed:43:b8:05:46:8a:86:f5:59:47:
+ be:1b:6f:01:21:10:b9:fd:a9:d2:28:ca:10:39:09:
+ ca:13:36:cf:9c:ad:ad:40:74:79:2b:02:3f:34:ff:
+ fa:20:69:7d:d3:ee:61:f5:ba:b3:e7:30:d0:37:23:
+ 86:72:61:45:29:48:59:68:6f:77:a6:2e:81:be:07:
+ 4d:6f:af:ce:c4:45:13:91:14:70:06:8f:1f:9f:f8:
+ 87:69:b1:0e:ef:c3:89:19:eb:ea:1c:61:fc:7a:6c:
+ 8a:dc:d6:03:0b:9e:26:ba:12:dd:d4:54:39:ab:26:
+ a3:33:ea:75:81:da:2d:cd:0f:4f:e4:03:d1:ef:15:
+ 97:1b:6b:90:c5:02:90:93:66:02:21:b1:47:de:8b:
+ 9a:4a:80:b9:55:8f:b5:a2:2f:c0:d6:33:67:da:7e:
+ c4:a7:b4:04:44:eb:47:fb:e6:58:b9:f7:0c:f0:7b:
+ 2b:b1:c0:70:29:c3:40:62:2d:3b:48:69:dc:23:3c:
+ 48:eb:7b:09:79:a9:6d:da:a8:30:98:cf:80:72:03:
+ 88:a6:5b:46:ae:72:79:7c:08:03:21:65:ae:b7:e1:
+ 1c:a5:b1:2a:a2:31:de:66:04:f7:c0:74:e8:71:de:
+ ff:3d:59:cc:96:26:12:8b:85:95:57:1a:ab:6b:75:
+ 0b:44:3d:11:28:3c:7b:61:b7:e2:8f:67:4f:e5:ec:
+ 3c:4c:60:80:69:57:38:1e:01:5b:8d:55:e8:c7:df:
+ c0:cc:77:23:34:49:75:7c:f6:98:11:eb:2d:de:ed:
+ 41:2e:14:05:02:7f:e0:fe:20:eb:35:e7:11:ac:22:
+ ce:57:3d:de:c9:30:6d:10:03:85:cd:f1:ff:8c:16:
+ b5:c1:b2:3e:88:6c:60:7f:90:4f:95:f7:f6:2d:ad:
+ 01:39:07:04:fa:75:80:7d:bf:49:50:ed:ef:c9:c4:
+ 7c:1c:eb:80:7e:db:b6:d0:dd:13:fe:c9:d3:9c:d7:
+ b2:97:a9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ C6:17:D0:BC:A8:EA:02:43:F2:1B:06:99:5D:2B:90:20:B9:D7:9C:E4
+ Signature Algorithm: sha256WithRSAEncryption
+ 34:61:d9:56:b5:12:87:55:4d:dd:a3:35:31:46:bb:a4:07:72:
+ bc:5f:61:62:e8:a5:fb:0b:37:b1:3c:b6:b3:fa:29:9d:7f:02:
+ f5:a4:c9:a8:93:b7:7a:71:28:69:8f:73:e1:52:90:da:d5:be:
+ 3a:e5:b7:76:6a:56:80:21:df:5d:e6:e9:3a:9e:e5:3e:f6:a2:
+ 69:c7:2a:0a:b0:18:47:dc:20:70:7d:52:a3:3e:59:7c:c1:ba:
+ c9:c8:15:40:61:ca:72:d6:70:ac:d2:b7:f0:1c:e4:86:29:f0:
+ ce:ef:68:63:d0:b5:20:8a:15:61:9a:7e:86:98:b4:c9:c2:76:
+ fb:cc:ba:30:16:cc:a3:61:c6:74:13:e5:6b:ef:a3:15:ea:03:
+ fe:13:8b:64:e4:d3:c1:d2:e8:84:fb:49:d1:10:4d:79:66:eb:
+ aa:fd:f4:8d:31:1e:70:14:ad:dc:de:67:13:4c:81:15:61:bc:
+ b7:d9:91:77:71:19:81:60:bb:f0:58:a5:b5:9c:0b:f7:8f:22:
+ 55:27:c0:4b:01:6d:3b:99:0d:d4:1d:9b:63:67:2f:d0:ee:0d:
+ ca:66:bc:94:4f:a6:ad:ed:fc:ee:63:ac:57:3f:65:25:cf:b2:
+ 86:8f:d0:08:ff:b8:76:14:6e:de:e5:27:ec:ab:78:b5:53:b9:
+ b6:3f:e8:20:f9:d2:a8:be:61:46:ca:87:8c:84:f3:f9:f1:a0:
+ 68:9b:22:1e:81:26:9b:10:04:91:71:c0:06:1f:dc:a0:d3:b9:
+ 56:a7:e3:98:2d:7f:83:9d:df:8c:2b:9c:32:8e:32:94:f0:01:
+ 3c:22:2a:9f:43:c2:2e:c3:98:39:07:38:7b:fc:5e:00:42:1f:
+ f3:32:26:79:83:84:f6:e5:f0:c1:51:12:c0:0b:1e:04:23:0c:
+ 54:a5:4c:2f:49:c5:4a:d1:b6:6e:60:0d:6b:fc:6b:8b:85:24:
+ 64:b7:89:0e:ab:25:47:5b:3c:cf:7e:49:bd:c7:e9:0a:c6:da:
+ f7:7e:0e:17:08:d3:48:97:d0:71:92:f0:0f:39:3e:34:6a:1c:
+ 7d:d8:f2:22:ae:bb:69:f4:33:b4:a6:48:55:d1:0f:0e:26:e8:
+ ec:b6:0b:2d:a7:85:35:cd:fd:59:c8:9f:d1:cd:3e:5a:29:34:
+ b9:3d:84:ce:b1:65:d4:59:91:91:56:75:21:c1:77:9e:f9:7a:
+ e1:60:9d:d3:ad:04:18:f4:7c:eb:5e:93:8f:53:4a:22:29:f8:
+ 48:2b:3e:4d:86:ac:5b:7f:cb:06:99:59:60:d8:58:65:95:8d:
+ 44:d1:f7:7f:7e:27:7f:7d:ae:80:f5:07:4c:b6:3e:9c:71:54:
+ 99:04:4b:fd:58:f9:98:f4
+SHA1 Fingerprint=48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D
diff --git a/luni/src/main/files/cacerts/ed39abd0.0 b/luni/src/main/files/cacerts/ed39abd0.0
new file mode 100644
index 0000000..188e375
--- /dev/null
+++ b/luni/src/main/files/cacerts/ed39abd0.0
@@ -0,0 +1,53 @@
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 05:55:56:bc:f2:5e:a4:35:35:c3:a4:0f:d5:ab:45:72
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G3
+ Validity
+ Not Before: Aug 1 12:00:00 2013 GMT
+ Not After : Jan 15 12:00:00 2038 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G3
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:dd:a7:d9:bb:8a:b8:0b:fb:0b:7f:21:d2:f0:be:
+ be:73:f3:33:5d:1a:bc:34:ea:de:c6:9b:bc:d0:95:
+ f6:f0:cc:d0:0b:ba:61:5b:51:46:7e:9e:2d:9f:ee:
+ 8e:63:0c:17:ec:07:70:f5:cf:84:2e:40:83:9c:e8:
+ 3f:41:6d:3b:ad:d3:a4:14:59:36:78:9d:03:43:ee:
+ 10:13:6c:72:de:ae:88:a7:a1:6b:b5:43:ce:67:dc:
+ 23:ff:03:1c:a3:e2:3e
+ ASN1 OID: secp384r1
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ B3:DB:48:A4:F9:A1:C5:D8:AE:36:41:CC:11:63:69:62:29:BC:4B:C6
+ Signature Algorithm: ecdsa-with-SHA384
+ 30:65:02:31:00:ad:bc:f2:6c:3f:12:4a:d1:2d:39:c3:0a:09:
+ 97:73:f4:88:36:8c:88:27:bb:e6:88:8d:50:85:a7:63:f9:9e:
+ 32:de:66:93:0f:f1:cc:b1:09:8f:dd:6c:ab:fa:6b:7f:a0:02:
+ 30:39:66:5b:c2:64:8d:b8:9e:50:dc:a8:d5:49:a2:ed:c7:dc:
+ d1:49:7f:17:01:b8:c8:86:8f:4e:8c:88:2b:a8:9a:a9:8a:c5:
+ d1:00:bd:f8:54:e2:9a:e5:5b:7c:b3:27:17
+SHA1 Fingerprint=7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E
diff --git a/luni/src/main/files/cacerts/f4996e82.0 b/luni/src/main/files/cacerts/f4996e82.0
deleted file mode 100644
index 4f59124..0000000
--- a/luni/src/main/files/cacerts/f4996e82.0
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy
-NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y
-LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+
-TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y
-TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0
-LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW
-I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw
-nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 1 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com
- Validity
- Not Before: Jun 25 22:23:48 1999 GMT
- Not After : Jun 25 22:23:48 2019 GMT
- Subject: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 1 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:d8:59:82:7a:89:b8:96:ba:a6:2f:68:6f:58:2e:
- a7:54:1c:06:6e:f4:ea:8d:48:bc:31:94:17:f0:f3:
- 4e:bc:b2:b8:35:92:76:b0:d0:a5:a5:01:d7:00:03:
- 12:22:19:08:f8:ff:11:23:9b:ce:07:f5:bf:69:1a:
- 26:fe:4e:e9:d1:7f:9d:2c:40:1d:59:68:6e:a6:f8:
- 58:b0:9d:1a:8f:d3:3f:f1:dc:19:06:81:a8:0e:e0:
- 3a:dd:c8:53:45:09:06:e6:0f:70:c3:fa:40:a6:0e:
- e2:56:05:0f:18:4d:fc:20:82:d1:73:55:74:8d:76:
- 72:a0:1d:9d:1d:c0:dd:3f:71
- Exponent: 65537 (0x10001)
- Signature Algorithm: sha1WithRSAEncryption
- 50:68:3d:49:f4:2c:1c:06:94:df:95:60:7f:96:7b:17:fe:4f:
- 71:ad:64:c8:dd:77:d2:ef:59:55:e8:3f:e8:8e:05:2a:21:f2:
- 07:d2:b5:a7:52:fe:9c:b1:b6:e2:5b:77:17:40:ea:72:d6:23:
- cb:28:81:32:c3:00:79:18:ec:59:17:89:c9:c6:6a:1e:71:c9:
- fd:b7:74:a5:25:45:69:c5:48:ab:19:e1:45:8a:25:6b:19:ee:
- e5:bb:12:f5:7f:f7:a6:8d:51:c3:f0:9d:74:b7:a9:3e:a0:a5:
- ff:b6:49:03:13:da:22:cc:ed:71:82:2b:99:cf:3a:b7:f5:2d:
- 72:c8
-SHA1 Fingerprint=E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E
diff --git a/luni/src/main/java/android/system/ErrnoException.java b/luni/src/main/java/android/system/ErrnoException.java
new file mode 100644
index 0000000..90155c8
--- /dev/null
+++ b/luni/src/main/java/android/system/ErrnoException.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import java.io.IOException;
+import java.net.SocketException;
+import libcore.io.Libcore;
+
+/**
+ * A checked exception thrown when {@link Os} methods fail. This exception contains the native
+ * errno value, for comparison against the constants in {@link OsConstants}, should sophisticated
+ * callers need to adjust their behavior based on the exact failure.
+ */
+public final class ErrnoException extends Exception {
+ private final String functionName;
+
+ /**
+ * The errno value, for comparison with the {@code E} constants in {@link OsConstants}.
+ */
+ public final int errno;
+
+ /**
+ * Constructs an instance with the given function name and errno value.
+ */
+ public ErrnoException(String functionName, int errno) {
+ this.functionName = functionName;
+ this.errno = errno;
+ }
+
+ /**
+ * Constructs an instance with the given function name, errno value, and cause.
+ */
+ public ErrnoException(String functionName, int errno, Throwable cause) {
+ super(cause);
+ this.functionName = functionName;
+ this.errno = errno;
+ }
+
+ /**
+ * Converts the stashed function name and errno value to a human-readable string.
+ * We do this here rather than in the constructor so that callers only pay for
+ * this if they need it.
+ */
+ @Override public String getMessage() {
+ String errnoName = OsConstants.errnoName(errno);
+ if (errnoName == null) {
+ errnoName = "errno " + errno;
+ }
+ String description = Libcore.os.strerror(errno);
+ return functionName + " failed: " + errnoName + " (" + description + ")";
+ }
+
+ /**
+ * @hide - internal use only.
+ */
+ public IOException rethrowAsIOException() throws IOException {
+ IOException newException = new IOException(getMessage());
+ newException.initCause(this);
+ throw newException;
+ }
+
+ /**
+ * @hide - internal use only.
+ */
+ public SocketException rethrowAsSocketException() throws SocketException {
+ throw new SocketException(getMessage(), this);
+ }
+}
diff --git a/luni/src/main/java/android/system/GaiException.java b/luni/src/main/java/android/system/GaiException.java
new file mode 100644
index 0000000..dc10566
--- /dev/null
+++ b/luni/src/main/java/android/system/GaiException.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import java.net.UnknownHostException;
+import libcore.io.Libcore;
+
+/**
+ * An unchecked exception thrown when {@code getaddrinfo} or {@code getnameinfo} fails.
+ * This exception contains the native {@link #error} value, should sophisticated
+ * callers need to adjust their behavior based on the exact failure.
+ *
+ * @hide
+ */
+public final class GaiException extends RuntimeException {
+ private final String functionName;
+
+ /**
+ * The native error value, for comparison with the {@code GAI_} constants in {@link OsConstants}.
+ */
+ public final int error;
+
+ /**
+ * Constructs an instance with the given function name and error value.
+ */
+ public GaiException(String functionName, int error) {
+ this.functionName = functionName;
+ this.error = error;
+ }
+
+ /**
+ * Constructs an instance with the given function name, error value, and cause.
+ */
+ public GaiException(String functionName, int error, Throwable cause) {
+ super(cause);
+ this.functionName = functionName;
+ this.error = error;
+ }
+
+ /**
+ * Converts the stashed function name and error value to a human-readable string.
+ * We do this here rather than in the constructor so that callers only pay for
+ * this if they need it.
+ */
+ @Override public String getMessage() {
+ String gaiName = OsConstants.gaiName(error);
+ if (gaiName == null) {
+ gaiName = "GAI_ error " + error;
+ }
+ String description = Libcore.os.gai_strerror(error);
+ return functionName + " failed: " + gaiName + " (" + description + ")";
+ }
+
+ /**
+ * @hide - internal use only.
+ */
+ public UnknownHostException rethrowAsUnknownHostException(String detailMessage) throws UnknownHostException {
+ UnknownHostException newException = new UnknownHostException(detailMessage);
+ newException.initCause(this);
+ throw newException;
+ }
+
+ /**
+ * @hide - internal use only.
+ */
+ public UnknownHostException rethrowAsUnknownHostException() throws UnknownHostException {
+ throw rethrowAsUnknownHostException(getMessage());
+ }
+}
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
new file mode 100644
index 0000000..0b80b52
--- /dev/null
+++ b/luni/src/main/java/android/system/Os.java
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import android.system.ErrnoException;
+import android.system.GaiException;
+import android.system.StructAddrinfo;
+import android.system.StructFlock;
+import android.system.StructGroupReq;
+import android.system.StructGroupSourceReq;
+import android.system.StructLinger;
+import android.system.StructPasswd;
+import android.system.StructPollfd;
+import android.system.StructStat;
+import android.system.StructStatVfs;
+import android.system.StructTimeval;
+import android.system.StructUcred;
+import android.system.StructUtsname;
+import android.util.MutableInt;
+import android.util.MutableLong;
+import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import libcore.io.Libcore;
+
+/**
+ * Access to low-level system functionality. Most of these are system calls. Most users will want
+ * to use higher-level APIs where available, but this class provides access to the underlying
+ * primitives used to implement the higher-level APIs.
+ *
+ * <p>The corresponding constants can be found in {@link OsConstants}.
+ */
+public final class Os {
+ private Os() {}
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/accept.2.html">accept(2)</a>.
+ */
+ public static FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { return Libcore.os.accept(fd, peerAddress); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/access.2.html">access(2)</a>.
+ */
+ public static boolean access(String path, int mode) throws ErrnoException { return Libcore.os.access(path, mode); }
+
+ /** @hide */ public static InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return Libcore.os.android_getaddrinfo(node, hints, netId); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/bind.2.html">bind(2)</a>.
+ */
+ public static void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { Libcore.os.bind(fd, address, port); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/chmod.2.html">chmod(2)</a>.
+ */
+ public static void chmod(String path, int mode) throws ErrnoException { Libcore.os.chmod(path, mode); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/chown.2.html">chown(2)</a>.
+ */
+ public static void chown(String path, int uid, int gid) throws ErrnoException { Libcore.os.chown(path, uid, gid); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/close.2.html">close(2)</a>.
+ */
+ public static void close(FileDescriptor fd) throws ErrnoException { Libcore.os.close(fd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/connect.2.html">connect(2)</a>.
+ */
+ public static void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { Libcore.os.connect(fd, address, port); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/dup.2.html">dup(2)</a>.
+ */
+ public static FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException { return Libcore.os.dup(oldFd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/dup2.2.html">dup2(2)</a>.
+ */
+ public static FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException { return Libcore.os.dup2(oldFd, newFd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/environ.3.html">environ(3)</a>.
+ */
+ public static String[] environ() { return Libcore.os.environ(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/execv.2.html">execv(2)</a>.
+ */
+ public static void execv(String filename, String[] argv) throws ErrnoException { Libcore.os.execv(filename, argv); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/execve.2.html">execve(2)</a>.
+ */
+ public static void execve(String filename, String[] argv, String[] envp) throws ErrnoException { Libcore.os.execve(filename, argv, envp); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/fchmod.2.html">fchmod(2)</a>.
+ */
+ public static void fchmod(FileDescriptor fd, int mode) throws ErrnoException { Libcore.os.fchmod(fd, mode); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/fchown.2.html">fchown(2)</a>.
+ */
+ public static void fchown(FileDescriptor fd, int uid, int gid) throws ErrnoException { Libcore.os.fchown(fd, uid, gid); }
+
+ /** @hide */ public static int fcntlVoid(FileDescriptor fd, int cmd) throws ErrnoException { return Libcore.os.fcntlVoid(fd, cmd); }
+ /** @hide */ public static int fcntlLong(FileDescriptor fd, int cmd, long arg) throws ErrnoException { return Libcore.os.fcntlLong(fd, cmd, arg); }
+ /** @hide */ public static int fcntlFlock(FileDescriptor fd, int cmd, StructFlock arg) throws ErrnoException { return Libcore.os.fcntlFlock(fd, cmd, arg); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/fdatasync.2.html">fdatasync(2)</a>.
+ */
+ public static void fdatasync(FileDescriptor fd) throws ErrnoException { Libcore.os.fdatasync(fd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/fstat.2.html">fstat(2)</a>.
+ */
+ public static StructStat fstat(FileDescriptor fd) throws ErrnoException { return Libcore.os.fstat(fd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/fstatvfs.2.html">fstatvfs(2)</a>.
+ */
+ public static StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException { return Libcore.os.fstatvfs(fd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/fsync.2.html">fsync(2)</a>.
+ */
+ public static void fsync(FileDescriptor fd) throws ErrnoException { Libcore.os.fsync(fd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/ftruncate.2.html">ftruncate(2)</a>.
+ */
+ public static void ftruncate(FileDescriptor fd, long length) throws ErrnoException { Libcore.os.ftruncate(fd, length); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/gai_strerror.3.html">gai_strerror(3)</a>.
+ */
+ public static String gai_strerror(int error) { return Libcore.os.gai_strerror(error); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/getegid.2.html">getegid(2)</a>.
+ */
+ public static int getegid() { return Libcore.os.getegid(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/geteuid.2.html">geteuid(2)</a>.
+ */
+ public static int geteuid() { return Libcore.os.geteuid(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/getgid.2.html">getgid(2)</a>.
+ */
+ public static int getgid() { return Libcore.os.getgid(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/getenv.3.html">getenv(3)</a>.
+ */
+ public static String getenv(String name) { return Libcore.os.getenv(name); }
+
+ /** @hide */ public static String getnameinfo(InetAddress address, int flags) throws GaiException { return Libcore.os.getnameinfo(address, flags); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/getpeername.2.html">getpeername(2)</a>.
+ */
+ public static SocketAddress getpeername(FileDescriptor fd) throws ErrnoException { return Libcore.os.getpeername(fd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/getpid.2.html">getpid(2)</a>.
+ */
+ public static int getpid() { return Libcore.os.getpid(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/getppid.2.html">getppid(2)</a>.
+ */
+ public static int getppid() { return Libcore.os.getppid(); }
+
+ /** @hide */ public static StructPasswd getpwnam(String name) throws ErrnoException { return Libcore.os.getpwnam(name); }
+
+ /** @hide */ public static StructPasswd getpwuid(int uid) throws ErrnoException { return Libcore.os.getpwuid(uid); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/getsockname.2.html">getsockname(2)</a>.
+ */
+ public static SocketAddress getsockname(FileDescriptor fd) throws ErrnoException { return Libcore.os.getsockname(fd); }
+
+ /** @hide */ public static int getsockoptByte(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptByte(fd, level, option); }
+ /** @hide */ public static InetAddress getsockoptInAddr(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInAddr(fd, level, option); }
+ /** @hide */ public static int getsockoptInt(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInt(fd, level, option); }
+ /** @hide */ public static StructLinger getsockoptLinger(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptLinger(fd, level, option); }
+ /** @hide */ public static StructTimeval getsockoptTimeval(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptTimeval(fd, level, option); }
+ /** @hide */ public static StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptUcred(fd, level, option); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/gettid.2.html">gettid(2)</a>.
+ */
+ public static int gettid() { return Libcore.os.gettid(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/getuid.2.html">getuid(2)</a>.
+ */
+ public static int getuid() { return Libcore.os.getuid(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/if_indextoname.3.html">if_indextoname(3)</a>.
+ */
+ public static String if_indextoname(int index) { return Libcore.os.if_indextoname(index); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/inet_pton.3.html">inet_pton(3)</a>.
+ */
+ public static InetAddress inet_pton(int family, String address) { return Libcore.os.inet_pton(family, address); }
+
+ /** @hide */ public static InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return Libcore.os.ioctlInetAddress(fd, cmd, interfaceName); }
+ /** @hide */ public static int ioctlInt(FileDescriptor fd, int cmd, MutableInt arg) throws ErrnoException { return Libcore.os.ioctlInt(fd, cmd, arg); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/isatty.3.html">isatty(3)</a>.
+ */
+ public static boolean isatty(FileDescriptor fd) { return Libcore.os.isatty(fd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/kill.2.html">kill(2)</a>.
+ */
+ public static void kill(int pid, int signal) throws ErrnoException { Libcore.os.kill(pid, signal); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/lchown.2.html">lchown(2)</a>.
+ */
+ public static void lchown(String path, int uid, int gid) throws ErrnoException { Libcore.os.lchown(path, uid, gid); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/link.2.html">link(2)</a>.
+ */
+ public static void link(String oldPath, String newPath) throws ErrnoException { Libcore.os.link(oldPath, newPath); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/listen.2.html">listen(2)</a>.
+ */
+ public static void listen(FileDescriptor fd, int backlog) throws ErrnoException { Libcore.os.listen(fd, backlog); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/lseek.2.html">lseek(2)</a>.
+ */
+ public static long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { return Libcore.os.lseek(fd, offset, whence); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/lstat.2.html">lstat(2)</a>.
+ */
+ public static StructStat lstat(String path) throws ErrnoException { return Libcore.os.lstat(path); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/mincore.2.html">mincore(2)</a>.
+ */
+ public static void mincore(long address, long byteCount, byte[] vector) throws ErrnoException { Libcore.os.mincore(address, byteCount, vector); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/mkdir.2.html">mkdir(2)</a>.
+ */
+ public static void mkdir(String path, int mode) throws ErrnoException { Libcore.os.mkdir(path, mode); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/mkfifo.3.html">mkfifo(3)</a>.
+ */
+ public static void mkfifo(String path, int mode) throws ErrnoException { Libcore.os.mkfifo(path, mode); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/mlock.2.html">mlock(2)</a>.
+ */
+ public static void mlock(long address, long byteCount) throws ErrnoException { Libcore.os.mlock(address, byteCount); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/mmap.2.html">mmap(2)</a>.
+ */
+ public static long mmap(long address, long byteCount, int prot, int flags, FileDescriptor fd, long offset) throws ErrnoException { return Libcore.os.mmap(address, byteCount, prot, flags, fd, offset); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/msync.2.html">msync(2)</a>.
+ */
+ public static void msync(long address, long byteCount, int flags) throws ErrnoException { Libcore.os.msync(address, byteCount, flags); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/munlock.2.html">munlock(2)</a>.
+ */
+ public static void munlock(long address, long byteCount) throws ErrnoException { Libcore.os.munlock(address, byteCount); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/munmap.2.html">munmap(2)</a>.
+ */
+ public static void munmap(long address, long byteCount) throws ErrnoException { Libcore.os.munmap(address, byteCount); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/open.2.html">open(2)</a>.
+ */
+ public static FileDescriptor open(String path, int flags, int mode) throws ErrnoException { return Libcore.os.open(path, flags, mode); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/pipe.2.html">pipe(2)</a>.
+ */
+ public static FileDescriptor[] pipe() throws ErrnoException { return Libcore.os.pipe(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/poll.2.html">poll(2)</a>.
+ */
+ public static int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException { return Libcore.os.poll(fds, timeoutMs); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/posix_fallocate.2.html">posix_fallocate(2)</a>.
+ */
+ public static void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException { Libcore.os.posix_fallocate(fd, offset, length); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/prctl.2.html">prctl(2)</a>.
+ */
+ public static int prctl(int option, long arg2, long arg3, long arg4, long arg5) throws ErrnoException { return Libcore.os.prctl(option, arg2, arg3, arg4, arg5); };
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/pread.2.html">pread(2)</a>.
+ */
+ public static int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { return Libcore.os.pread(fd, buffer, offset); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/pread.2.html">pread(2)</a>.
+ */
+ public static int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { return Libcore.os.pread(fd, bytes, byteOffset, byteCount, offset); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/pwrite.2.html">pwrite(2)</a>.
+ */
+ public static int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { return Libcore.os.pwrite(fd, buffer, offset); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/pwrite.2.html">pwrite(2)</a>.
+ */
+ public static int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { return Libcore.os.pwrite(fd, bytes, byteOffset, byteCount, offset); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/read.2.html">read(2)</a>.
+ */
+ public static int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { return Libcore.os.read(fd, buffer); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/read.2.html">read(2)</a>.
+ */
+ public static int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { return Libcore.os.read(fd, bytes, byteOffset, byteCount); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/readlink.2.html">readlink(2)</a>.
+ */
+ public static String readlink(String path) throws ErrnoException { return Libcore.os.readlink(path); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/readv.2.html">readv(2)</a>.
+ */
+ public static int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { return Libcore.os.readv(fd, buffers, offsets, byteCounts); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/recvfrom.2.html">recvfrom(2)</a>.
+ */
+ public static int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return Libcore.os.recvfrom(fd, buffer, flags, srcAddress); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/recvfrom.2.html">recvfrom(2)</a>.
+ */
+ public static int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return Libcore.os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/remove.3.html">remove(3)</a>.
+ */
+ public static void remove(String path) throws ErrnoException { Libcore.os.remove(path); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/rename.2.html">rename(2)</a>.
+ */
+ public static void rename(String oldPath, String newPath) throws ErrnoException { Libcore.os.rename(oldPath, newPath); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/sendfile.2.html">sendfile(2)</a>.
+ */
+ public static long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException { return Libcore.os.sendfile(outFd, inFd, inOffset, byteCount); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/sendto.2.html">sendto(2)</a>.
+ */
+ public static int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, buffer, flags, inetAddress, port); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/sendto.2.html">sendto(2)</a>.
+ */
+ public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/setegid.2.html">setegid(2)</a>.
+ */
+ public static void setegid(int egid) throws ErrnoException { Libcore.os.setegid(egid); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/setenv.3.html">setenv(3)</a>.
+ */
+ public static void setenv(String name, String value, boolean overwrite) throws ErrnoException { Libcore.os.setenv(name, value, overwrite); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/seteuid.2.html">seteuid(2)</a>.
+ */
+ public static void seteuid(int euid) throws ErrnoException { Libcore.os.seteuid(euid); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/setgid.2.html">setgid(2)</a>.
+ */
+ public static void setgid(int gid) throws ErrnoException { Libcore.os.setgid(gid); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/setsid.2.html">setsid(2)</a>.
+ */
+ public static int setsid() throws ErrnoException { return Libcore.os.setsid(); }
+
+ /** @hide */ public static void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptByte(fd, level, option, value); }
+ /** @hide */ public static void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException { Libcore.os.setsockoptIfreq(fd, level, option, value); }
+ /** @hide */ public static void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptInt(fd, level, option, value); }
+ /** @hide */ public static void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptIpMreqn(fd, level, option, value); }
+ /** @hide */ public static void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException { Libcore.os.setsockoptGroupReq(fd, level, option, value); }
+ /** @hide */ public static void setsockoptGroupSourceReq(FileDescriptor fd, int level, int option, StructGroupSourceReq value) throws ErrnoException { Libcore.os.setsockoptGroupSourceReq(fd, level, option, value); }
+ /** @hide */ public static void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { Libcore.os.setsockoptLinger(fd, level, option, value); }
+ /** @hide */ public static void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { Libcore.os.setsockoptTimeval(fd, level, option, value); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/setuid.2.html">setuid(2)</a>.
+ */
+ public static void setuid(int uid) throws ErrnoException { Libcore.os.setuid(uid); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/shutdown.2.html">shutdown(2)</a>.
+ */
+ public static void shutdown(FileDescriptor fd, int how) throws ErrnoException { Libcore.os.shutdown(fd, how); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/socket.2.html">socket(2)</a>.
+ */
+ public static FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException { return Libcore.os.socket(domain, type, protocol); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/socketpair.2.html">socketpair(2)</a>.
+ */
+ public static void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException { Libcore.os.socketpair(domain, type, protocol, fd1, fd2); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/stat.2.html">stat(2)</a>.
+ */
+ public static StructStat stat(String path) throws ErrnoException { return Libcore.os.stat(path); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/statvfs.2.html">statvfs(2)</a>.
+ */
+ public static StructStatVfs statvfs(String path) throws ErrnoException { return Libcore.os.statvfs(path); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/strerror.3.html">strerror(2)</a>.
+ */
+ public static String strerror(int errno) { return Libcore.os.strerror(errno); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/strsignal.3.html">strsignal(3)</a>.
+ */
+ public static String strsignal(int signal) { return Libcore.os.strsignal(signal); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/symlink.2.html">symlink(2)</a>.
+ */
+ public static void symlink(String oldPath, String newPath) throws ErrnoException { Libcore.os.symlink(oldPath, newPath); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/sysconf.3.html">sysconf(3)</a>.
+ */
+ public static long sysconf(int name) { return Libcore.os.sysconf(name); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/tcdrain.3.html">tcdrain(3)</a>.
+ */
+ public static void tcdrain(FileDescriptor fd) throws ErrnoException { Libcore.os.tcdrain(fd); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/tcsendbreak.3.html">tcsendbreak(3)</a>.
+ */
+ public static void tcsendbreak(FileDescriptor fd, int duration) throws ErrnoException { Libcore.os.tcsendbreak(fd, duration); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/umask.2.html">umask(2)</a>.
+ */
+ public static int umask(int mask) { return Libcore.os.umask(mask); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/uname.2.html">uname(2)</a>.
+ */
+ public static StructUtsname uname() { return Libcore.os.uname(); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man3/unsetenv.3.html">unsetenv(3)</a>.
+ */
+ public static void unsetenv(String name) throws ErrnoException { Libcore.os.unsetenv(name); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/waitpid.2.html">waitpid(2)</a>.
+ */
+ public static int waitpid(int pid, MutableInt status, int options) throws ErrnoException { return Libcore.os.waitpid(pid, status, options); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/write.2.html">write(2)</a>.
+ */
+ public static int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { return Libcore.os.write(fd, buffer); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/write.2.html">write(2)</a>.
+ */
+ public static int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { return Libcore.os.write(fd, bytes, byteOffset, byteCount); }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/writev.2.html">writev(2)</a>.
+ */
+ public static int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { return Libcore.os.writev(fd, buffers, offsets, byteCounts); }
+}
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
new file mode 100644
index 0000000..c758eb7
--- /dev/null
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -0,0 +1,850 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+/**
+ * Constants and helper functions for use with {@link Os}.
+ */
+public final class OsConstants {
+ private OsConstants() {
+ }
+
+ /**
+ * Tests whether the given mode is a block device.
+ */
+ public static boolean S_ISBLK(int mode) { return (mode & S_IFMT) == S_IFBLK; }
+
+ /**
+ * Tests whether the given mode is a character device.
+ */
+ public static boolean S_ISCHR(int mode) { return (mode & S_IFMT) == S_IFCHR; }
+
+ /**
+ * Tests whether the given mode is a directory.
+ */
+ public static boolean S_ISDIR(int mode) { return (mode & S_IFMT) == S_IFDIR; }
+
+ /**
+ * Tests whether the given mode is a FIFO.
+ */
+ public static boolean S_ISFIFO(int mode) { return (mode & S_IFMT) == S_IFIFO; }
+
+ /**
+ * Tests whether the given mode is a regular file.
+ */
+ public static boolean S_ISREG(int mode) { return (mode & S_IFMT) == S_IFREG; }
+
+ /**
+ * Tests whether the given mode is a symbolic link.
+ */
+ public static boolean S_ISLNK(int mode) { return (mode & S_IFMT) == S_IFLNK; }
+
+ /**
+ * Tests whether the given mode is a socket.
+ */
+ public static boolean S_ISSOCK(int mode) { return (mode & S_IFMT) == S_IFSOCK; }
+
+ /**
+ * Extracts the exit status of a child. Only valid if WIFEXITED returns true.
+ */
+ public static int WEXITSTATUS(int status) { return (status & 0xff00) >> 8; }
+
+ /**
+ * Tests whether the child dumped core. Only valid if WIFSIGNALED returns true.
+ */
+ public static boolean WCOREDUMP(int status) { return (status & 0x80) != 0; }
+
+ /**
+ * Returns the signal that caused the child to exit. Only valid if WIFSIGNALED returns true.
+ */
+ public static int WTERMSIG(int status) { return status & 0x7f; }
+
+ /**
+ * Returns the signal that cause the child to stop. Only valid if WIFSTOPPED returns true.
+ */
+ public static int WSTOPSIG(int status) { return WEXITSTATUS(status); }
+
+ /**
+ * Tests whether the child exited normally.
+ */
+ public static boolean WIFEXITED(int status) { return (WTERMSIG(status) == 0); }
+
+ /**
+ * Tests whether the child was stopped (not terminated) by a signal.
+ */
+ public static boolean WIFSTOPPED(int status) { return (WTERMSIG(status) == 0x7f); }
+
+ /**
+ * Tests whether the child was terminated by a signal.
+ */
+ public static boolean WIFSIGNALED(int status) { return (WTERMSIG(status + 1) >= 2); }
+
+ public static final int AF_INET = placeholder();
+ public static final int AF_INET6 = placeholder();
+ public static final int AF_UNIX = placeholder();
+ public static final int AF_UNSPEC = placeholder();
+ public static final int AI_ADDRCONFIG = placeholder();
+ public static final int AI_ALL = placeholder();
+ public static final int AI_CANONNAME = placeholder();
+ public static final int AI_NUMERICHOST = placeholder();
+ public static final int AI_NUMERICSERV = placeholder();
+ public static final int AI_PASSIVE = placeholder();
+ public static final int AI_V4MAPPED = placeholder();
+ public static final int CAP_AUDIT_CONTROL = placeholder();
+ public static final int CAP_AUDIT_WRITE = placeholder();
+ public static final int CAP_BLOCK_SUSPEND = placeholder();
+ public static final int CAP_CHOWN = placeholder();
+ public static final int CAP_DAC_OVERRIDE = placeholder();
+ public static final int CAP_DAC_READ_SEARCH = placeholder();
+ public static final int CAP_FOWNER = placeholder();
+ public static final int CAP_FSETID = placeholder();
+ public static final int CAP_IPC_LOCK = placeholder();
+ public static final int CAP_IPC_OWNER = placeholder();
+ public static final int CAP_KILL = placeholder();
+ public static final int CAP_LAST_CAP = placeholder();
+ public static final int CAP_LEASE = placeholder();
+ public static final int CAP_LINUX_IMMUTABLE = placeholder();
+ public static final int CAP_MAC_ADMIN = placeholder();
+ public static final int CAP_MAC_OVERRIDE = placeholder();
+ public static final int CAP_MKNOD = placeholder();
+ public static final int CAP_NET_ADMIN = placeholder();
+ public static final int CAP_NET_BIND_SERVICE = placeholder();
+ public static final int CAP_NET_BROADCAST = placeholder();
+ public static final int CAP_NET_RAW = placeholder();
+ public static final int CAP_SETFCAP = placeholder();
+ public static final int CAP_SETGID = placeholder();
+ public static final int CAP_SETPCAP = placeholder();
+ public static final int CAP_SETUID = placeholder();
+ public static final int CAP_SYS_ADMIN = placeholder();
+ public static final int CAP_SYS_BOOT = placeholder();
+ public static final int CAP_SYS_CHROOT = placeholder();
+ public static final int CAP_SYSLOG = placeholder();
+ public static final int CAP_SYS_MODULE = placeholder();
+ public static final int CAP_SYS_NICE = placeholder();
+ public static final int CAP_SYS_PACCT = placeholder();
+ public static final int CAP_SYS_PTRACE = placeholder();
+ public static final int CAP_SYS_RAWIO = placeholder();
+ public static final int CAP_SYS_RESOURCE = placeholder();
+ public static final int CAP_SYS_TIME = placeholder();
+ public static final int CAP_SYS_TTY_CONFIG = placeholder();
+ public static final int CAP_WAKE_ALARM = placeholder();
+ public static final int E2BIG = placeholder();
+ public static final int EACCES = placeholder();
+ public static final int EADDRINUSE = placeholder();
+ public static final int EADDRNOTAVAIL = placeholder();
+ public static final int EAFNOSUPPORT = placeholder();
+ public static final int EAGAIN = placeholder();
+ public static final int EAI_AGAIN = placeholder();
+ public static final int EAI_BADFLAGS = placeholder();
+ public static final int EAI_FAIL = placeholder();
+ public static final int EAI_FAMILY = placeholder();
+ public static final int EAI_MEMORY = placeholder();
+ public static final int EAI_NODATA = placeholder();
+ public static final int EAI_NONAME = placeholder();
+ public static final int EAI_OVERFLOW = placeholder();
+ public static final int EAI_SERVICE = placeholder();
+ public static final int EAI_SOCKTYPE = placeholder();
+ public static final int EAI_SYSTEM = placeholder();
+ public static final int EALREADY = placeholder();
+ public static final int EBADF = placeholder();
+ public static final int EBADMSG = placeholder();
+ public static final int EBUSY = placeholder();
+ public static final int ECANCELED = placeholder();
+ public static final int ECHILD = placeholder();
+ public static final int ECONNABORTED = placeholder();
+ public static final int ECONNREFUSED = placeholder();
+ public static final int ECONNRESET = placeholder();
+ public static final int EDEADLK = placeholder();
+ public static final int EDESTADDRREQ = placeholder();
+ public static final int EDOM = placeholder();
+ public static final int EDQUOT = placeholder();
+ public static final int EEXIST = placeholder();
+ public static final int EFAULT = placeholder();
+ public static final int EFBIG = placeholder();
+ public static final int EHOSTUNREACH = placeholder();
+ public static final int EIDRM = placeholder();
+ public static final int EILSEQ = placeholder();
+ public static final int EINPROGRESS = placeholder();
+ public static final int EINTR = placeholder();
+ public static final int EINVAL = placeholder();
+ public static final int EIO = placeholder();
+ public static final int EISCONN = placeholder();
+ public static final int EISDIR = placeholder();
+ public static final int ELOOP = placeholder();
+ public static final int EMFILE = placeholder();
+ public static final int EMLINK = placeholder();
+ public static final int EMSGSIZE = placeholder();
+ public static final int EMULTIHOP = placeholder();
+ public static final int ENAMETOOLONG = placeholder();
+ public static final int ENETDOWN = placeholder();
+ public static final int ENETRESET = placeholder();
+ public static final int ENETUNREACH = placeholder();
+ public static final int ENFILE = placeholder();
+ public static final int ENOBUFS = placeholder();
+ public static final int ENODATA = placeholder();
+ public static final int ENODEV = placeholder();
+ public static final int ENOENT = placeholder();
+ public static final int ENOEXEC = placeholder();
+ public static final int ENOLCK = placeholder();
+ public static final int ENOLINK = placeholder();
+ public static final int ENOMEM = placeholder();
+ public static final int ENOMSG = placeholder();
+ public static final int ENOPROTOOPT = placeholder();
+ public static final int ENOSPC = placeholder();
+ public static final int ENOSR = placeholder();
+ public static final int ENOSTR = placeholder();
+ public static final int ENOSYS = placeholder();
+ public static final int ENOTCONN = placeholder();
+ public static final int ENOTDIR = placeholder();
+ public static final int ENOTEMPTY = placeholder();
+ public static final int ENOTSOCK = placeholder();
+ public static final int ENOTSUP = placeholder();
+ public static final int ENOTTY = placeholder();
+ public static final int ENXIO = placeholder();
+ public static final int EOPNOTSUPP = placeholder();
+ public static final int EOVERFLOW = placeholder();
+ public static final int EPERM = placeholder();
+ public static final int EPIPE = placeholder();
+ public static final int EPROTO = placeholder();
+ public static final int EPROTONOSUPPORT = placeholder();
+ public static final int EPROTOTYPE = placeholder();
+ public static final int ERANGE = placeholder();
+ public static final int EROFS = placeholder();
+ public static final int ESPIPE = placeholder();
+ public static final int ESRCH = placeholder();
+ public static final int ESTALE = placeholder();
+ public static final int ETIME = placeholder();
+ public static final int ETIMEDOUT = placeholder();
+ public static final int ETXTBSY = placeholder();
+ // On Linux, EWOULDBLOCK == EAGAIN. Use EAGAIN instead, to reduce confusion.
+ public static final int EXDEV = placeholder();
+ public static final int EXIT_FAILURE = placeholder();
+ public static final int EXIT_SUCCESS = placeholder();
+ public static final int FD_CLOEXEC = placeholder();
+ public static final int FIONREAD = placeholder();
+ public static final int F_DUPFD = placeholder();
+ public static final int F_GETFD = placeholder();
+ public static final int F_GETFL = placeholder();
+ public static final int F_GETLK = placeholder();
+ public static final int F_GETLK64 = placeholder();
+ public static final int F_GETOWN = placeholder();
+ public static final int F_OK = placeholder();
+ public static final int F_RDLCK = placeholder();
+ public static final int F_SETFD = placeholder();
+ public static final int F_SETFL = placeholder();
+ public static final int F_SETLK = placeholder();
+ public static final int F_SETLK64 = placeholder();
+ public static final int F_SETLKW = placeholder();
+ public static final int F_SETLKW64 = placeholder();
+ public static final int F_SETOWN = placeholder();
+ public static final int F_UNLCK = placeholder();
+ public static final int F_WRLCK = placeholder();
+ public static final int IFA_F_DADFAILED = placeholder();
+ public static final int IFA_F_DEPRECATED = placeholder();
+ public static final int IFA_F_HOMEADDRESS = placeholder();
+ public static final int IFA_F_NODAD = placeholder();
+ public static final int IFA_F_OPTIMISTIC = placeholder();
+ public static final int IFA_F_PERMANENT = placeholder();
+ public static final int IFA_F_SECONDARY = placeholder();
+ public static final int IFA_F_TEMPORARY = placeholder();
+ public static final int IFA_F_TENTATIVE = placeholder();
+ public static final int IFF_ALLMULTI = placeholder();
+ public static final int IFF_AUTOMEDIA = placeholder();
+ public static final int IFF_BROADCAST = placeholder();
+ public static final int IFF_DEBUG = placeholder();
+ public static final int IFF_DYNAMIC = placeholder();
+ public static final int IFF_LOOPBACK = placeholder();
+ public static final int IFF_MASTER = placeholder();
+ public static final int IFF_MULTICAST = placeholder();
+ public static final int IFF_NOARP = placeholder();
+ public static final int IFF_NOTRAILERS = placeholder();
+ public static final int IFF_POINTOPOINT = placeholder();
+ public static final int IFF_PORTSEL = placeholder();
+ public static final int IFF_PROMISC = placeholder();
+ public static final int IFF_RUNNING = placeholder();
+ public static final int IFF_SLAVE = placeholder();
+ public static final int IFF_UP = placeholder();
+ public static final int IPPROTO_ICMP = placeholder();
+ public static final int IPPROTO_ICMPV6 = placeholder();
+ public static final int IPPROTO_IP = placeholder();
+ public static final int IPPROTO_IPV6 = placeholder();
+ public static final int IPPROTO_RAW = placeholder();
+ public static final int IPPROTO_TCP = placeholder();
+ public static final int IPPROTO_UDP = placeholder();
+ public static final int IPV6_CHECKSUM = placeholder();
+ public static final int IPV6_MULTICAST_HOPS = placeholder();
+ public static final int IPV6_MULTICAST_IF = placeholder();
+ public static final int IPV6_MULTICAST_LOOP = placeholder();
+ public static final int IPV6_RECVDSTOPTS = placeholder();
+ public static final int IPV6_RECVHOPLIMIT = placeholder();
+ public static final int IPV6_RECVHOPOPTS = placeholder();
+ public static final int IPV6_RECVPKTINFO = placeholder();
+ public static final int IPV6_RECVRTHDR = placeholder();
+ public static final int IPV6_RECVTCLASS = placeholder();
+ public static final int IPV6_TCLASS = placeholder();
+ public static final int IPV6_UNICAST_HOPS = placeholder();
+ public static final int IPV6_V6ONLY = placeholder();
+ public static final int IP_MULTICAST_IF = placeholder();
+ public static final int IP_MULTICAST_LOOP = placeholder();
+ public static final int IP_MULTICAST_TTL = placeholder();
+ public static final int IP_TOS = placeholder();
+ public static final int IP_TTL = placeholder();
+ public static final int MAP_FIXED = placeholder();
+ public static final int MAP_PRIVATE = placeholder();
+ public static final int MAP_SHARED = placeholder();
+ public static final int MCAST_JOIN_GROUP = placeholder();
+ public static final int MCAST_LEAVE_GROUP = placeholder();
+ public static final int MCAST_JOIN_SOURCE_GROUP = placeholder();
+ public static final int MCAST_LEAVE_SOURCE_GROUP = placeholder();
+ public static final int MCAST_BLOCK_SOURCE = placeholder();
+ public static final int MCAST_UNBLOCK_SOURCE = placeholder();
+ public static final int MCL_CURRENT = placeholder();
+ public static final int MCL_FUTURE = placeholder();
+ public static final int MSG_CTRUNC = placeholder();
+ public static final int MSG_DONTROUTE = placeholder();
+ public static final int MSG_EOR = placeholder();
+ public static final int MSG_OOB = placeholder();
+ public static final int MSG_PEEK = placeholder();
+ public static final int MSG_TRUNC = placeholder();
+ public static final int MSG_WAITALL = placeholder();
+ public static final int MS_ASYNC = placeholder();
+ public static final int MS_INVALIDATE = placeholder();
+ public static final int MS_SYNC = placeholder();
+ public static final int NI_DGRAM = placeholder();
+ public static final int NI_NAMEREQD = placeholder();
+ public static final int NI_NOFQDN = placeholder();
+ public static final int NI_NUMERICHOST = placeholder();
+ public static final int NI_NUMERICSERV = placeholder();
+ public static final int O_ACCMODE = placeholder();
+ public static final int O_APPEND = placeholder();
+ public static final int O_CREAT = placeholder();
+ public static final int O_EXCL = placeholder();
+ public static final int O_NOCTTY = placeholder();
+ public static final int O_NOFOLLOW = placeholder();
+ public static final int O_NONBLOCK = placeholder();
+ public static final int O_RDONLY = placeholder();
+ public static final int O_RDWR = placeholder();
+ public static final int O_SYNC = placeholder();
+ public static final int O_TRUNC = placeholder();
+ public static final int O_WRONLY = placeholder();
+ public static final int POLLERR = placeholder();
+ public static final int POLLHUP = placeholder();
+ public static final int POLLIN = placeholder();
+ public static final int POLLNVAL = placeholder();
+ public static final int POLLOUT = placeholder();
+ public static final int POLLPRI = placeholder();
+ public static final int POLLRDBAND = placeholder();
+ public static final int POLLRDNORM = placeholder();
+ public static final int POLLWRBAND = placeholder();
+ public static final int POLLWRNORM = placeholder();
+ public static final int PR_GET_DUMPABLE = placeholder();
+ public static final int PR_SET_DUMPABLE = placeholder();
+ public static final int PR_SET_NO_NEW_PRIVS = placeholder();
+ public static final int PROT_EXEC = placeholder();
+ public static final int PROT_NONE = placeholder();
+ public static final int PROT_READ = placeholder();
+ public static final int PROT_WRITE = placeholder();
+ public static final int R_OK = placeholder();
+ public static final int RT_SCOPE_HOST = placeholder();
+ public static final int RT_SCOPE_LINK = placeholder();
+ public static final int RT_SCOPE_NOWHERE = placeholder();
+ public static final int RT_SCOPE_SITE = placeholder();
+ public static final int RT_SCOPE_UNIVERSE = placeholder();
+ public static final int SEEK_CUR = placeholder();
+ public static final int SEEK_END = placeholder();
+ public static final int SEEK_SET = placeholder();
+ public static final int SHUT_RD = placeholder();
+ public static final int SHUT_RDWR = placeholder();
+ public static final int SHUT_WR = placeholder();
+ public static final int SIGABRT = placeholder();
+ public static final int SIGALRM = placeholder();
+ public static final int SIGBUS = placeholder();
+ public static final int SIGCHLD = placeholder();
+ public static final int SIGCONT = placeholder();
+ public static final int SIGFPE = placeholder();
+ public static final int SIGHUP = placeholder();
+ public static final int SIGILL = placeholder();
+ public static final int SIGINT = placeholder();
+ public static final int SIGIO = placeholder();
+ public static final int SIGKILL = placeholder();
+ public static final int SIGPIPE = placeholder();
+ public static final int SIGPROF = placeholder();
+ public static final int SIGPWR = placeholder();
+ public static final int SIGQUIT = placeholder();
+ public static final int SIGRTMAX = placeholder();
+ public static final int SIGRTMIN = placeholder();
+ public static final int SIGSEGV = placeholder();
+ public static final int SIGSTKFLT = placeholder();
+ public static final int SIGSTOP = placeholder();
+ public static final int SIGSYS = placeholder();
+ public static final int SIGTERM = placeholder();
+ public static final int SIGTRAP = placeholder();
+ public static final int SIGTSTP = placeholder();
+ public static final int SIGTTIN = placeholder();
+ public static final int SIGTTOU = placeholder();
+ public static final int SIGURG = placeholder();
+ public static final int SIGUSR1 = placeholder();
+ public static final int SIGUSR2 = placeholder();
+ public static final int SIGVTALRM = placeholder();
+ public static final int SIGWINCH = placeholder();
+ public static final int SIGXCPU = placeholder();
+ public static final int SIGXFSZ = placeholder();
+ public static final int SIOCGIFADDR = placeholder();
+ public static final int SIOCGIFBRDADDR = placeholder();
+ public static final int SIOCGIFDSTADDR = placeholder();
+ public static final int SIOCGIFNETMASK = placeholder();
+ public static final int SOCK_DGRAM = placeholder();
+ public static final int SOCK_RAW = placeholder();
+ public static final int SOCK_SEQPACKET = placeholder();
+ public static final int SOCK_STREAM = placeholder();
+ public static final int SOL_SOCKET = placeholder();
+ public static final int SO_BINDTODEVICE = placeholder();
+ public static final int SO_BROADCAST = placeholder();
+ public static final int SO_DEBUG = placeholder();
+ public static final int SO_DONTROUTE = placeholder();
+ public static final int SO_ERROR = placeholder();
+ public static final int SO_KEEPALIVE = placeholder();
+ public static final int SO_LINGER = placeholder();
+ public static final int SO_OOBINLINE = placeholder();
+ public static final int SO_PASSCRED = placeholder();
+ public static final int SO_PEERCRED = placeholder();
+ public static final int SO_RCVBUF = placeholder();
+ public static final int SO_RCVLOWAT = placeholder();
+ public static final int SO_RCVTIMEO = placeholder();
+ public static final int SO_REUSEADDR = placeholder();
+ public static final int SO_SNDBUF = placeholder();
+ public static final int SO_SNDLOWAT = placeholder();
+ public static final int SO_SNDTIMEO = placeholder();
+ public static final int SO_TYPE = placeholder();
+ public static final int STDERR_FILENO = placeholder();
+ public static final int STDIN_FILENO = placeholder();
+ public static final int STDOUT_FILENO = placeholder();
+ public static final int S_IFBLK = placeholder();
+ public static final int S_IFCHR = placeholder();
+ public static final int S_IFDIR = placeholder();
+ public static final int S_IFIFO = placeholder();
+ public static final int S_IFLNK = placeholder();
+ public static final int S_IFMT = placeholder();
+ public static final int S_IFREG = placeholder();
+ public static final int S_IFSOCK = placeholder();
+ public static final int S_IRGRP = placeholder();
+ public static final int S_IROTH = placeholder();
+ public static final int S_IRUSR = placeholder();
+ public static final int S_IRWXG = placeholder();
+ public static final int S_IRWXO = placeholder();
+ public static final int S_IRWXU = placeholder();
+ public static final int S_ISGID = placeholder();
+ public static final int S_ISUID = placeholder();
+ public static final int S_ISVTX = placeholder();
+ public static final int S_IWGRP = placeholder();
+ public static final int S_IWOTH = placeholder();
+ public static final int S_IWUSR = placeholder();
+ public static final int S_IXGRP = placeholder();
+ public static final int S_IXOTH = placeholder();
+ public static final int S_IXUSR = placeholder();
+ public static final int TCP_NODELAY = placeholder();
+ public static final int WCONTINUED = placeholder();
+ public static final int WEXITED = placeholder();
+ public static final int WNOHANG = placeholder();
+ public static final int WNOWAIT = placeholder();
+ public static final int WSTOPPED = placeholder();
+ public static final int WUNTRACED = placeholder();
+ public static final int W_OK = placeholder();
+ public static final int X_OK = placeholder();
+ public static final int _SC_2_CHAR_TERM = placeholder();
+ public static final int _SC_2_C_BIND = placeholder();
+ public static final int _SC_2_C_DEV = placeholder();
+ public static final int _SC_2_C_VERSION = placeholder();
+ public static final int _SC_2_FORT_DEV = placeholder();
+ public static final int _SC_2_FORT_RUN = placeholder();
+ public static final int _SC_2_LOCALEDEF = placeholder();
+ public static final int _SC_2_SW_DEV = placeholder();
+ public static final int _SC_2_UPE = placeholder();
+ public static final int _SC_2_VERSION = placeholder();
+ public static final int _SC_AIO_LISTIO_MAX = placeholder();
+ public static final int _SC_AIO_MAX = placeholder();
+ public static final int _SC_AIO_PRIO_DELTA_MAX = placeholder();
+ public static final int _SC_ARG_MAX = placeholder();
+ public static final int _SC_ASYNCHRONOUS_IO = placeholder();
+ public static final int _SC_ATEXIT_MAX = placeholder();
+ public static final int _SC_AVPHYS_PAGES = placeholder();
+ public static final int _SC_BC_BASE_MAX = placeholder();
+ public static final int _SC_BC_DIM_MAX = placeholder();
+ public static final int _SC_BC_SCALE_MAX = placeholder();
+ public static final int _SC_BC_STRING_MAX = placeholder();
+ public static final int _SC_CHILD_MAX = placeholder();
+ public static final int _SC_CLK_TCK = placeholder();
+ public static final int _SC_COLL_WEIGHTS_MAX = placeholder();
+ public static final int _SC_DELAYTIMER_MAX = placeholder();
+ public static final int _SC_EXPR_NEST_MAX = placeholder();
+ public static final int _SC_FSYNC = placeholder();
+ public static final int _SC_GETGR_R_SIZE_MAX = placeholder();
+ public static final int _SC_GETPW_R_SIZE_MAX = placeholder();
+ public static final int _SC_IOV_MAX = placeholder();
+ public static final int _SC_JOB_CONTROL = placeholder();
+ public static final int _SC_LINE_MAX = placeholder();
+ public static final int _SC_LOGIN_NAME_MAX = placeholder();
+ public static final int _SC_MAPPED_FILES = placeholder();
+ public static final int _SC_MEMLOCK = placeholder();
+ public static final int _SC_MEMLOCK_RANGE = placeholder();
+ public static final int _SC_MEMORY_PROTECTION = placeholder();
+ public static final int _SC_MESSAGE_PASSING = placeholder();
+ public static final int _SC_MQ_OPEN_MAX = placeholder();
+ public static final int _SC_MQ_PRIO_MAX = placeholder();
+ public static final int _SC_NGROUPS_MAX = placeholder();
+ public static final int _SC_NPROCESSORS_CONF = placeholder();
+ public static final int _SC_NPROCESSORS_ONLN = placeholder();
+ public static final int _SC_OPEN_MAX = placeholder();
+ public static final int _SC_PAGESIZE = placeholder();
+ public static final int _SC_PAGE_SIZE = placeholder();
+ public static final int _SC_PASS_MAX = placeholder();
+ public static final int _SC_PHYS_PAGES = placeholder();
+ public static final int _SC_PRIORITIZED_IO = placeholder();
+ public static final int _SC_PRIORITY_SCHEDULING = placeholder();
+ public static final int _SC_REALTIME_SIGNALS = placeholder();
+ public static final int _SC_RE_DUP_MAX = placeholder();
+ public static final int _SC_RTSIG_MAX = placeholder();
+ public static final int _SC_SAVED_IDS = placeholder();
+ public static final int _SC_SEMAPHORES = placeholder();
+ public static final int _SC_SEM_NSEMS_MAX = placeholder();
+ public static final int _SC_SEM_VALUE_MAX = placeholder();
+ public static final int _SC_SHARED_MEMORY_OBJECTS = placeholder();
+ public static final int _SC_SIGQUEUE_MAX = placeholder();
+ public static final int _SC_STREAM_MAX = placeholder();
+ public static final int _SC_SYNCHRONIZED_IO = placeholder();
+ public static final int _SC_THREADS = placeholder();
+ public static final int _SC_THREAD_ATTR_STACKADDR = placeholder();
+ public static final int _SC_THREAD_ATTR_STACKSIZE = placeholder();
+ public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS = placeholder();
+ public static final int _SC_THREAD_KEYS_MAX = placeholder();
+ public static final int _SC_THREAD_PRIORITY_SCHEDULING = placeholder();
+ public static final int _SC_THREAD_PRIO_INHERIT = placeholder();
+ public static final int _SC_THREAD_PRIO_PROTECT = placeholder();
+ public static final int _SC_THREAD_SAFE_FUNCTIONS = placeholder();
+ public static final int _SC_THREAD_STACK_MIN = placeholder();
+ public static final int _SC_THREAD_THREADS_MAX = placeholder();
+ public static final int _SC_TIMERS = placeholder();
+ public static final int _SC_TIMER_MAX = placeholder();
+ public static final int _SC_TTY_NAME_MAX = placeholder();
+ public static final int _SC_TZNAME_MAX = placeholder();
+ public static final int _SC_VERSION = placeholder();
+ public static final int _SC_XBS5_ILP32_OFF32 = placeholder();
+ public static final int _SC_XBS5_ILP32_OFFBIG = placeholder();
+ public static final int _SC_XBS5_LP64_OFF64 = placeholder();
+ public static final int _SC_XBS5_LPBIG_OFFBIG = placeholder();
+ public static final int _SC_XOPEN_CRYPT = placeholder();
+ public static final int _SC_XOPEN_ENH_I18N = placeholder();
+ public static final int _SC_XOPEN_LEGACY = placeholder();
+ public static final int _SC_XOPEN_REALTIME = placeholder();
+ public static final int _SC_XOPEN_REALTIME_THREADS = placeholder();
+ public static final int _SC_XOPEN_SHM = placeholder();
+ public static final int _SC_XOPEN_UNIX = placeholder();
+ public static final int _SC_XOPEN_VERSION = placeholder();
+ public static final int _SC_XOPEN_XCU_VERSION = placeholder();
+
+ /**
+ * Returns the string name of a getaddrinfo(3) error value.
+ * For example, "EAI_AGAIN".
+ */
+ public static String gaiName(int error) {
+ if (error == EAI_AGAIN) {
+ return "EAI_AGAIN";
+ }
+ if (error == EAI_BADFLAGS) {
+ return "EAI_BADFLAGS";
+ }
+ if (error == EAI_FAIL) {
+ return "EAI_FAIL";
+ }
+ if (error == EAI_FAMILY) {
+ return "EAI_FAMILY";
+ }
+ if (error == EAI_MEMORY) {
+ return "EAI_MEMORY";
+ }
+ if (error == EAI_NODATA) {
+ return "EAI_NODATA";
+ }
+ if (error == EAI_NONAME) {
+ return "EAI_NONAME";
+ }
+ if (error == EAI_OVERFLOW) {
+ return "EAI_OVERFLOW";
+ }
+ if (error == EAI_SERVICE) {
+ return "EAI_SERVICE";
+ }
+ if (error == EAI_SOCKTYPE) {
+ return "EAI_SOCKTYPE";
+ }
+ if (error == EAI_SYSTEM) {
+ return "EAI_SYSTEM";
+ }
+ return null;
+ }
+
+ /**
+ * Returns the string name of an errno value.
+ * For example, "EACCES". See {@link Os#strerror} for human-readable errno descriptions.
+ */
+ public static String errnoName(int errno) {
+ if (errno == E2BIG) {
+ return "E2BIG";
+ }
+ if (errno == EACCES) {
+ return "EACCES";
+ }
+ if (errno == EADDRINUSE) {
+ return "EADDRINUSE";
+ }
+ if (errno == EADDRNOTAVAIL) {
+ return "EADDRNOTAVAIL";
+ }
+ if (errno == EAFNOSUPPORT) {
+ return "EAFNOSUPPORT";
+ }
+ if (errno == EAGAIN) {
+ return "EAGAIN";
+ }
+ if (errno == EALREADY) {
+ return "EALREADY";
+ }
+ if (errno == EBADF) {
+ return "EBADF";
+ }
+ if (errno == EBADMSG) {
+ return "EBADMSG";
+ }
+ if (errno == EBUSY) {
+ return "EBUSY";
+ }
+ if (errno == ECANCELED) {
+ return "ECANCELED";
+ }
+ if (errno == ECHILD) {
+ return "ECHILD";
+ }
+ if (errno == ECONNABORTED) {
+ return "ECONNABORTED";
+ }
+ if (errno == ECONNREFUSED) {
+ return "ECONNREFUSED";
+ }
+ if (errno == ECONNRESET) {
+ return "ECONNRESET";
+ }
+ if (errno == EDEADLK) {
+ return "EDEADLK";
+ }
+ if (errno == EDESTADDRREQ) {
+ return "EDESTADDRREQ";
+ }
+ if (errno == EDOM) {
+ return "EDOM";
+ }
+ if (errno == EDQUOT) {
+ return "EDQUOT";
+ }
+ if (errno == EEXIST) {
+ return "EEXIST";
+ }
+ if (errno == EFAULT) {
+ return "EFAULT";
+ }
+ if (errno == EFBIG) {
+ return "EFBIG";
+ }
+ if (errno == EHOSTUNREACH) {
+ return "EHOSTUNREACH";
+ }
+ if (errno == EIDRM) {
+ return "EIDRM";
+ }
+ if (errno == EILSEQ) {
+ return "EILSEQ";
+ }
+ if (errno == EINPROGRESS) {
+ return "EINPROGRESS";
+ }
+ if (errno == EINTR) {
+ return "EINTR";
+ }
+ if (errno == EINVAL) {
+ return "EINVAL";
+ }
+ if (errno == EIO) {
+ return "EIO";
+ }
+ if (errno == EISCONN) {
+ return "EISCONN";
+ }
+ if (errno == EISDIR) {
+ return "EISDIR";
+ }
+ if (errno == ELOOP) {
+ return "ELOOP";
+ }
+ if (errno == EMFILE) {
+ return "EMFILE";
+ }
+ if (errno == EMLINK) {
+ return "EMLINK";
+ }
+ if (errno == EMSGSIZE) {
+ return "EMSGSIZE";
+ }
+ if (errno == EMULTIHOP) {
+ return "EMULTIHOP";
+ }
+ if (errno == ENAMETOOLONG) {
+ return "ENAMETOOLONG";
+ }
+ if (errno == ENETDOWN) {
+ return "ENETDOWN";
+ }
+ if (errno == ENETRESET) {
+ return "ENETRESET";
+ }
+ if (errno == ENETUNREACH) {
+ return "ENETUNREACH";
+ }
+ if (errno == ENFILE) {
+ return "ENFILE";
+ }
+ if (errno == ENOBUFS) {
+ return "ENOBUFS";
+ }
+ if (errno == ENODATA) {
+ return "ENODATA";
+ }
+ if (errno == ENODEV) {
+ return "ENODEV";
+ }
+ if (errno == ENOENT) {
+ return "ENOENT";
+ }
+ if (errno == ENOEXEC) {
+ return "ENOEXEC";
+ }
+ if (errno == ENOLCK) {
+ return "ENOLCK";
+ }
+ if (errno == ENOLINK) {
+ return "ENOLINK";
+ }
+ if (errno == ENOMEM) {
+ return "ENOMEM";
+ }
+ if (errno == ENOMSG) {
+ return "ENOMSG";
+ }
+ if (errno == ENOPROTOOPT) {
+ return "ENOPROTOOPT";
+ }
+ if (errno == ENOSPC) {
+ return "ENOSPC";
+ }
+ if (errno == ENOSR) {
+ return "ENOSR";
+ }
+ if (errno == ENOSTR) {
+ return "ENOSTR";
+ }
+ if (errno == ENOSYS) {
+ return "ENOSYS";
+ }
+ if (errno == ENOTCONN) {
+ return "ENOTCONN";
+ }
+ if (errno == ENOTDIR) {
+ return "ENOTDIR";
+ }
+ if (errno == ENOTEMPTY) {
+ return "ENOTEMPTY";
+ }
+ if (errno == ENOTSOCK) {
+ return "ENOTSOCK";
+ }
+ if (errno == ENOTSUP) {
+ return "ENOTSUP";
+ }
+ if (errno == ENOTTY) {
+ return "ENOTTY";
+ }
+ if (errno == ENXIO) {
+ return "ENXIO";
+ }
+ if (errno == EOPNOTSUPP) {
+ return "EOPNOTSUPP";
+ }
+ if (errno == EOVERFLOW) {
+ return "EOVERFLOW";
+ }
+ if (errno == EPERM) {
+ return "EPERM";
+ }
+ if (errno == EPIPE) {
+ return "EPIPE";
+ }
+ if (errno == EPROTO) {
+ return "EPROTO";
+ }
+ if (errno == EPROTONOSUPPORT) {
+ return "EPROTONOSUPPORT";
+ }
+ if (errno == EPROTOTYPE) {
+ return "EPROTOTYPE";
+ }
+ if (errno == ERANGE) {
+ return "ERANGE";
+ }
+ if (errno == EROFS) {
+ return "EROFS";
+ }
+ if (errno == ESPIPE) {
+ return "ESPIPE";
+ }
+ if (errno == ESRCH) {
+ return "ESRCH";
+ }
+ if (errno == ESTALE) {
+ return "ESTALE";
+ }
+ if (errno == ETIME) {
+ return "ETIME";
+ }
+ if (errno == ETIMEDOUT) {
+ return "ETIMEDOUT";
+ }
+ if (errno == ETXTBSY) {
+ return "ETXTBSY";
+ }
+ if (errno == EXDEV) {
+ return "EXDEV";
+ }
+ return null;
+ }
+
+ private static native void initConstants();
+
+ // A hack to avoid these constants being inlined by javac...
+ private static int placeholder() { return 0; }
+ // ...because we want to initialize them at runtime.
+ static {
+ initConstants();
+ }
+}
diff --git a/luni/src/main/java/android/system/StructAddrinfo.java b/luni/src/main/java/android/system/StructAddrinfo.java
new file mode 100644
index 0000000..2425946
--- /dev/null
+++ b/luni/src/main/java/android/system/StructAddrinfo.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import java.net.InetAddress;
+import libcore.util.Objects;
+
+/**
+ * Information returned/taken by getaddrinfo(3). Corresponds to C's {@code struct addrinfo} from
+ * <a href="http://pubs.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html">&lt;netdb.h&gt;</a>
+ *
+ * TODO: we currently only _take_ a StructAddrinfo; getaddrinfo returns an InetAddress[].
+ *
+ * @hide
+ */
+public final class StructAddrinfo {
+ /** Flags describing the kind of lookup to be done. (Such as AI_ADDRCONFIG.) */
+ public int ai_flags;
+
+ /** Desired address family for results. (Such as AF_INET6 for IPv6. AF_UNSPEC means "any".) */
+ public int ai_family;
+
+ /** Socket type. (Such as SOCK_DGRAM. 0 means "any".) */
+ public int ai_socktype;
+
+ /** Protocol. (Such as IPPROTO_IPV6 IPv6. 0 means "any".) */
+ public int ai_protocol;
+
+ /** Address length. (Not useful in Java.) */
+ // public int ai_addrlen;
+
+ /** Address. */
+ public InetAddress ai_addr;
+
+ /** Canonical name of service location (if AI_CANONNAME provided in ai_flags). */
+ // public String ai_canonname;
+
+ /** Next element in linked list. */
+ public StructAddrinfo ai_next;
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructFlock.java b/luni/src/main/java/android/system/StructFlock.java
new file mode 100644
index 0000000..92cd95a
--- /dev/null
+++ b/luni/src/main/java/android/system/StructFlock.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Information returned/taken by fcntl(2) F_GETFL and F_SETFL. Corresponds to C's
+ * {@code struct flock} from
+ * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fcntl.h.html">&lt;fcntl.h&gt;</a>
+ *
+ * @hide
+ */
+public final class StructFlock {
+ /** The operation type, one of F_RDLCK, F_WRLCK, or F_UNLCK. */
+ public short l_type;
+
+ /** How to interpret l_start, one of SEEK_CUR, SEEK_END, SEEK_SET. */
+ public short l_whence;
+
+ /** Start offset. */
+ public long l_start; /*off_t*/
+
+ /** Byte count to operate on. */
+ public long l_len; /*off_t*/
+
+ /** Process blocking our lock (filled in by F_GETLK, otherwise unused). */
+ public int l_pid; /*pid_t*/
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructGroupReq.java b/luni/src/main/java/android/system/StructGroupReq.java
new file mode 100644
index 0000000..8ed5950
--- /dev/null
+++ b/luni/src/main/java/android/system/StructGroupReq.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import java.net.InetAddress;
+import libcore.util.Objects;
+
+/**
+ * Corresponds to C's {@code struct group_req}.
+ *
+ * @hide
+ */
+public final class StructGroupReq {
+ public final int gr_interface;
+ public final InetAddress gr_group;
+
+ public StructGroupReq(int gr_interface, InetAddress gr_group) {
+ this.gr_interface = gr_interface;
+ this.gr_group = gr_group;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructGroupSourceReq.java b/luni/src/main/java/android/system/StructGroupSourceReq.java
new file mode 100644
index 0000000..c300338
--- /dev/null
+++ b/luni/src/main/java/android/system/StructGroupSourceReq.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import java.net.InetAddress;
+import libcore.util.Objects;
+
+/**
+ * Corresponds to C's {@code struct group_source_req}.
+ *
+ * @hide
+ */
+public final class StructGroupSourceReq {
+ public final int gsr_interface;
+ public final InetAddress gsr_group;
+ public final InetAddress gsr_source;
+
+ public StructGroupSourceReq(int gsr_interface, InetAddress gsr_group, InetAddress gsr_source) {
+ this.gsr_interface = gsr_interface;
+ this.gsr_group = gsr_group;
+ this.gsr_source = gsr_source;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructLinger.java b/luni/src/main/java/android/system/StructLinger.java
new file mode 100644
index 0000000..55ffc5c
--- /dev/null
+++ b/luni/src/main/java/android/system/StructLinger.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to C's {@code struct linger} from
+ * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html">&lt;sys/socket.h&gt;</a>
+ *
+ * @hide
+ */
+public final class StructLinger {
+ /** Whether or not linger is enabled. Non-zero is on. */
+ public final int l_onoff;
+
+ /** Linger time in seconds. */
+ public final int l_linger;
+
+ public StructLinger(int l_onoff, int l_linger) {
+ this.l_onoff = l_onoff;
+ this.l_linger = l_linger;
+ }
+
+ public boolean isOn() {
+ return l_onoff != 0;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructPasswd.java b/luni/src/main/java/android/system/StructPasswd.java
new file mode 100644
index 0000000..04a7826
--- /dev/null
+++ b/luni/src/main/java/android/system/StructPasswd.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Information returned by {@link Os#getpwnam} and {@link Os#getpwuid}. Corresponds to C's
+ * {@code struct passwd} from {@code &lt;pwd.h&gt;}.
+ *
+ * @hide
+ */
+public final class StructPasswd {
+ public final String pw_name;
+ public final int pw_uid;
+ public final int pw_gid;
+ public final String pw_dir;
+ public final String pw_shell;
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructPasswd(String pw_name, int pw_uid, int pw_gid, String pw_dir, String pw_shell) {
+ this.pw_name = pw_name;
+ this.pw_uid = pw_uid;
+ this.pw_gid = pw_gid;
+ this.pw_dir = pw_dir;
+ this.pw_shell = pw_shell;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructPollfd.java b/luni/src/main/java/android/system/StructPollfd.java
new file mode 100644
index 0000000..b812612
--- /dev/null
+++ b/luni/src/main/java/android/system/StructPollfd.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import java.io.FileDescriptor;
+import libcore.util.Objects;
+
+/**
+ * Used as an in/out parameter to {@link Os#poll}.
+ * Corresponds to C's {@code struct pollfd} from {@code &lt;poll.h&gt;}.
+ */
+public final class StructPollfd {
+ /** The file descriptor to poll. */
+ public FileDescriptor fd;
+
+ /**
+ * The events we're interested in. POLLIN corresponds to being in select(2)'s read fd set,
+ * POLLOUT to the write fd set.
+ */
+ public short events;
+
+ /** The events that actually happened. */
+ public short revents;
+
+ /**
+ * A non-standard extension that lets callers conveniently map back to the object
+ * their fd belongs to. This is used by Selector, for example, to associate each
+ * FileDescriptor with the corresponding SelectionKey.
+ */
+ public Object userData;
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructStat.java b/luni/src/main/java/android/system/StructStat.java
new file mode 100644
index 0000000..a6958c1
--- /dev/null
+++ b/luni/src/main/java/android/system/StructStat.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * File information returned by {@link Os#fstat}, {@link Os#lstat}, and {@link Os#stat}.
+ * Corresponds to C's {@code struct stat} from {@code &lt;stat.h&gt;}.
+ */
+public final class StructStat {
+ /** Device ID of device containing file. */
+ public final long st_dev; /*dev_t*/
+
+ /** File serial number (inode). */
+ public final long st_ino; /*ino_t*/
+
+ /** Mode (permissions) of file. */
+ public final int st_mode; /*mode_t*/
+
+ /** Number of hard links to the file. */
+ public final long st_nlink; /*nlink_t*/
+
+ /** User ID of file. */
+ public final int st_uid; /*uid_t*/
+
+ /** Group ID of file. */
+ public final int st_gid; /*gid_t*/
+
+ /** Device ID (if file is character or block special). */
+ public final long st_rdev; /*dev_t*/
+
+ /**
+ * For regular files, the file size in bytes.
+ * For symbolic links, the length in bytes of the pathname contained in the symbolic link.
+ * For a shared memory object, the length in bytes.
+ * For a typed memory object, the length in bytes.
+ * For other file types, the use of this field is unspecified.
+ */
+ public final long st_size; /*off_t*/
+
+ /** Time of last access. */
+ public final long st_atime; /*time_t*/
+
+ /** Time of last data modification. */
+ public final long st_mtime; /*time_t*/
+
+ /** Time of last status change. */
+ public final long st_ctime; /*time_t*/
+
+ /**
+ * A file system-specific preferred I/O block size for this object.
+ * For some file system types, this may vary from file to file.
+ */
+ public final long st_blksize; /*blksize_t*/
+
+ /** Number of blocks allocated for this object. */
+ public final long st_blocks; /*blkcnt_t*/
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructStat(long st_dev, long st_ino, int st_mode, long st_nlink, int st_uid, int st_gid,
+ long st_rdev, long st_size, long st_atime, long st_mtime, long st_ctime,
+ long st_blksize, long st_blocks) {
+ this.st_dev = st_dev;
+ this.st_ino = st_ino;
+ this.st_mode = st_mode;
+ this.st_nlink = st_nlink;
+ this.st_uid = st_uid;
+ this.st_gid = st_gid;
+ this.st_rdev = st_rdev;
+ this.st_size = st_size;
+ this.st_atime = st_atime;
+ this.st_mtime = st_mtime;
+ this.st_ctime = st_ctime;
+ this.st_blksize = st_blksize;
+ this.st_blocks = st_blocks;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructStatVfs.java b/luni/src/main/java/android/system/StructStatVfs.java
new file mode 100644
index 0000000..942a39a
--- /dev/null
+++ b/luni/src/main/java/android/system/StructStatVfs.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * File information returned by {@link Os#fstatvfs} and {@link Os#statvfs}.
+ */
+public final class StructStatVfs {
+ /** File system block size (used for block counts). */
+ public final long f_bsize; /*unsigned long*/
+
+ /** Fundamental file system block size. */
+ public final long f_frsize; /*unsigned long*/
+
+ /** Total block count. */
+ public final long f_blocks; /*fsblkcnt_t*/
+
+ /** Free block count. */
+ public final long f_bfree; /*fsblkcnt_t*/
+
+ /** Free block count available to non-root. */
+ public final long f_bavail; /*fsblkcnt_t*/
+
+ /** Total file (inode) count. */
+ public final long f_files; /*fsfilcnt_t*/
+
+ /** Free file (inode) count. */
+ public final long f_ffree; /*fsfilcnt_t*/
+
+ /** Free file (inode) count available to non-root. */
+ public final long f_favail; /*fsfilcnt_t*/
+
+ /** File system id. */
+ public final long f_fsid; /*unsigned long*/
+
+ /** Bit mask of ST_* flags. */
+ public final long f_flag; /*unsigned long*/
+
+ /** Maximum filename length. */
+ public final long f_namemax; /*unsigned long*/
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructStatVfs(long f_bsize, long f_frsize, long f_blocks, long f_bfree, long f_bavail,
+ long f_files, long f_ffree, long f_favail,
+ long f_fsid, long f_flag, long f_namemax) {
+ this.f_bsize = f_bsize;
+ this.f_frsize = f_frsize;
+ this.f_blocks = f_blocks;
+ this.f_bfree = f_bfree;
+ this.f_bavail = f_bavail;
+ this.f_files = f_files;
+ this.f_ffree = f_ffree;
+ this.f_favail = f_favail;
+ this.f_fsid = f_fsid;
+ this.f_flag = f_flag;
+ this.f_namemax = f_namemax;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructTimeval.java b/luni/src/main/java/android/system/StructTimeval.java
new file mode 100644
index 0000000..8a155b4
--- /dev/null
+++ b/luni/src/main/java/android/system/StructTimeval.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to C's {@code struct timeval} from
+ * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_time.h.html">&lt;sys/time.h&gt;</a>
+ *
+ * @hide
+ */
+public final class StructTimeval {
+ /** Seconds. */
+ public final long tv_sec;
+
+ /** Microseconds. */
+ public final long tv_usec;
+
+ private StructTimeval(long tv_sec, long tv_usec) {
+ this.tv_sec = tv_sec;
+ this.tv_usec = tv_usec;
+ }
+
+ public static StructTimeval fromMillis(long millis) {
+ long tv_sec = millis / 1000;
+ long tv_usec = (millis - (tv_sec * 1000)) * 1000;
+ return new StructTimeval(tv_sec, tv_usec);
+ }
+
+ public long toMillis() {
+ return (tv_sec * 1000) + (tv_usec / 1000);
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructUcred.java b/luni/src/main/java/android/system/StructUcred.java
new file mode 100644
index 0000000..a1e3cd6
--- /dev/null
+++ b/luni/src/main/java/android/system/StructUcred.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to C's {@code struct ucred}.
+ *
+ * @hide
+ */
+public final class StructUcred {
+ /** The peer's process id. */
+ public final int pid;
+
+ /** The peer process' uid. */
+ public final int uid;
+
+ /** The peer process' gid. */
+ public final int gid;
+
+ public StructUcred(int pid, int uid, int gid) {
+ this.pid = pid;
+ this.uid = uid;
+ this.gid = gid;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructUtsname.java b/luni/src/main/java/android/system/StructUtsname.java
new file mode 100644
index 0000000..5d9127b
--- /dev/null
+++ b/luni/src/main/java/android/system/StructUtsname.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Information returned by {@link Os#uname}.
+ * Corresponds to C's {@code struct utsname} from {@code &lt;sys/utsname.h&gt;}.
+ */
+public final class StructUtsname {
+ /** The OS name, such as "Linux". */
+ public final String sysname;
+
+ /** The machine's unqualified name on some implementation-defined network. */
+ public final String nodename;
+
+ /** The OS release, such as "2.6.35-27-generic". */
+ public final String release;
+
+ /** The OS version, such as "#48-Ubuntu SMP Tue Feb 22 20:25:29 UTC 2011". */
+ public final String version;
+
+ /** The machine architecture, such as "armv7l" or "x86_64". */
+ public final String machine;
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructUtsname(String sysname, String nodename, String release, String version, String machine) {
+ this.sysname = sysname;
+ this.nodename = nodename;
+ this.release = release;
+ this.version = version;
+ this.machine = machine;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/util/MutableBoolean.java b/luni/src/main/java/android/util/MutableBoolean.java
new file mode 100644
index 0000000..5a8a200
--- /dev/null
+++ b/luni/src/main/java/android/util/MutableBoolean.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableBoolean {
+ public boolean value;
+
+ public MutableBoolean(boolean value) {
+ this.value = value;
+ }
+}
diff --git a/luni/src/main/java/android/util/MutableByte.java b/luni/src/main/java/android/util/MutableByte.java
new file mode 100644
index 0000000..7397ba4
--- /dev/null
+++ b/luni/src/main/java/android/util/MutableByte.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableByte {
+ public byte value;
+
+ public MutableByte(byte value) {
+ this.value = value;
+ }
+}
diff --git a/luni/src/main/java/android/util/MutableChar.java b/luni/src/main/java/android/util/MutableChar.java
new file mode 100644
index 0000000..f435331
--- /dev/null
+++ b/luni/src/main/java/android/util/MutableChar.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableChar {
+ public char value;
+
+ public MutableChar(char value) {
+ this.value = value;
+ }
+}
diff --git a/luni/src/main/java/android/util/MutableDouble.java b/luni/src/main/java/android/util/MutableDouble.java
new file mode 100644
index 0000000..f62f47e
--- /dev/null
+++ b/luni/src/main/java/android/util/MutableDouble.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableDouble {
+ public double value;
+
+ public MutableDouble(double value) {
+ this.value = value;
+ }
+}
diff --git a/luni/src/main/java/android/util/MutableFloat.java b/luni/src/main/java/android/util/MutableFloat.java
new file mode 100644
index 0000000..6b5441c
--- /dev/null
+++ b/luni/src/main/java/android/util/MutableFloat.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableFloat {
+ public float value;
+
+ public MutableFloat(float value) {
+ this.value = value;
+ }
+}
diff --git a/luni/src/main/java/android/util/MutableInt.java b/luni/src/main/java/android/util/MutableInt.java
new file mode 100644
index 0000000..2f93030
--- /dev/null
+++ b/luni/src/main/java/android/util/MutableInt.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableInt {
+ public int value;
+
+ public MutableInt(int value) {
+ this.value = value;
+ }
+}
diff --git a/luni/src/main/java/android/util/MutableLong.java b/luni/src/main/java/android/util/MutableLong.java
new file mode 100644
index 0000000..94beab5
--- /dev/null
+++ b/luni/src/main/java/android/util/MutableLong.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableLong {
+ public long value;
+
+ public MutableLong(long value) {
+ this.value = value;
+ }
+}
diff --git a/luni/src/main/java/android/util/MutableShort.java b/luni/src/main/java/android/util/MutableShort.java
new file mode 100644
index 0000000..cdd9923
--- /dev/null
+++ b/luni/src/main/java/android/util/MutableShort.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ */
+public final class MutableShort {
+ public short value;
+
+ public MutableShort(short value) {
+ this.value = value;
+ }
+}
diff --git a/luni/src/main/java/java/io/BufferedInputStream.java b/luni/src/main/java/java/io/BufferedInputStream.java
index 5a810e7..85236b6 100644
--- a/luni/src/main/java/java/io/BufferedInputStream.java
+++ b/luni/src/main/java/java/io/BufferedInputStream.java
@@ -37,6 +37,13 @@ import java.util.Arrays;
*/
public class BufferedInputStream extends FilterInputStream {
/**
+ * The default buffer size if it is not specified.
+ *
+ * @hide
+ */
+ public static final int DEFAULT_BUFFER_SIZE = 8192;
+
+ /**
* The buffer containing the current bytes read from the target InputStream.
*/
protected volatile byte[] buf;
@@ -73,7 +80,7 @@ public class BufferedInputStream extends FilterInputStream {
* @param in the {@code InputStream} the buffer reads from.
*/
public BufferedInputStream(InputStream in) {
- this(in, 8192);
+ this(in, DEFAULT_BUFFER_SIZE);
}
/**
@@ -325,7 +332,7 @@ public class BufferedInputStream extends FilterInputStream {
if (buf == null) {
throw new IOException("Stream is closed");
}
- if (-1 == markpos) {
+ if (markpos == -1) {
throw new IOException("Mark has been invalidated.");
}
pos = markpos;
diff --git a/luni/src/main/java/java/io/Console.java b/luni/src/main/java/java/io/Console.java
index a1d2097..fe07694c 100644
--- a/luni/src/main/java/java/io/Console.java
+++ b/luni/src/main/java/java/io/Console.java
@@ -16,9 +16,7 @@
package java.io;
import java.util.Formatter;
-import libcore.io.ErrnoException;
import libcore.io.Libcore;
-import static libcore.io.OsConstants.*;
/**
* Provides access to the console, if available. The system-wide instance can
@@ -48,12 +46,12 @@ public final class Console implements Flushable {
}
try {
return new Console(System.in, System.out);
- } catch (IOException ex) {
+ } catch (UnsupportedEncodingException ex) {
throw new AssertionError(ex);
}
}
- private Console(InputStream in, OutputStream out) throws IOException {
+ private Console(InputStream in, OutputStream out) throws UnsupportedEncodingException {
this.reader = new ConsoleReader(in);
this.writer = new ConsoleWriter(out);
}
@@ -129,48 +127,17 @@ public final class Console implements Flushable {
}
/**
- * Reads a password from the console. The password will not be echoed to the display.
- *
- * @return a character array containing the password, or null at EOF.
+ * This method is unimplemented on Android.
*/
public char[] readPassword() {
- synchronized (CONSOLE_LOCK) {
- int previousState = setEcho(false, 0);
- try {
- String password = readLine();
- writer.println(); // We won't have echoed the user's newline.
- return (password == null) ? null : password.toCharArray();
- } finally {
- setEcho(true, previousState);
- }
- }
- }
-
- private static int setEcho(boolean on, int previousState) {
- try {
- return setEchoImpl(on, previousState);
- } catch (IOException ex) {
- throw new IOError(ex);
- }
+ throw new UnsupportedOperationException();
}
- private static native int setEchoImpl(boolean on, int previousState) throws IOException;
/**
- * Reads a password from the console. The password will not be echoed to the display.
- * A formatted prompt is also displayed.
- *
- * @param format the format string (see {@link java.util.Formatter#format})
- * @param args
- * the list of arguments passed to the formatter. If there are
- * more arguments than required by {@code format},
- * additional arguments are ignored.
- * @return a character array containing the password, or null at EOF.
+ * This method is unimplemented on Android.
*/
public char[] readPassword(String format, Object... args) {
- synchronized (CONSOLE_LOCK) {
- format(format, args);
- return readPassword();
- }
+ throw new UnsupportedOperationException();
}
/**
@@ -181,7 +148,7 @@ public final class Console implements Flushable {
}
private static class ConsoleReader extends BufferedReader {
- public ConsoleReader(InputStream in) throws IOException {
+ public ConsoleReader(InputStream in) throws UnsupportedEncodingException {
super(new InputStreamReader(in, System.getProperty("file.encoding")), 256);
lock = CONSOLE_LOCK;
}
diff --git a/luni/src/main/java/java/io/File.java b/luni/src/main/java/java/io/File.java
index a8b4810..d107c28 100644
--- a/luni/src/main/java/java/io/File.java
+++ b/luni/src/main/java/java/io/File.java
@@ -17,19 +17,19 @@
package java.io;
+import android.system.ErrnoException;
+import android.system.StructStat;
+import android.system.StructStatVfs;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-import libcore.io.ErrnoException;
+import libcore.io.DeleteOnExit;
import libcore.io.IoUtils;
import libcore.io.Libcore;
-import libcore.io.StructStat;
-import libcore.io.StructStatVfs;
-import org.apache.harmony.luni.util.DeleteOnExit;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* An "abstract" representation of a file system entity identified by a
@@ -411,15 +411,10 @@ public class File implements Serializable, Comparable<File> {
* if an I/O error occurs.
*/
public String getCanonicalPath() throws IOException {
- return realpath(getAbsolutePath());
+ return canonicalizePath(getAbsolutePath());
}
- /**
- * TODO: move this stuff to libcore.os.
- * @hide
- */
- private static native String realpath(String path);
- private static native String readlink(String path);
+ private static native String canonicalizePath(String path);
/**
* Returns a new file created using the canonical path of this file.
diff --git a/luni/src/main/java/java/io/FileDescriptor.java b/luni/src/main/java/java/io/FileDescriptor.java
index e4eb06c..eba0e4d 100644
--- a/luni/src/main/java/java/io/FileDescriptor.java
+++ b/luni/src/main/java/java/io/FileDescriptor.java
@@ -17,9 +17,9 @@
package java.io;
-import libcore.io.ErrnoException;
+import android.system.ErrnoException;
import libcore.io.Libcore;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* Wraps a Unix file descriptor. It's possible to get the file descriptor used by some
@@ -105,6 +105,15 @@ public final class FileDescriptor {
this.descriptor = fd;
}
+ /**
+ * @hide internal use only
+ */
+ public boolean isSocket() {
+ return isSocket(descriptor);
+ }
+
+ private static native boolean isSocket(int fd);
+
@Override public String toString() {
return "FileDescriptor[" + descriptor + "]";
}
diff --git a/luni/src/main/java/java/io/FileInputStream.java b/luni/src/main/java/java/io/FileInputStream.java
index b2e620f..7944ef1 100644
--- a/luni/src/main/java/java/io/FileInputStream.java
+++ b/luni/src/main/java/java/io/FileInputStream.java
@@ -19,15 +19,13 @@ package java.io;
import dalvik.system.CloseGuard;
-import java.nio.NioUtils;
+import android.system.ErrnoException;
import java.nio.channels.FileChannel;
-import java.util.Arrays;
-import libcore.io.ErrnoException;
+import java.nio.NioUtils;
import libcore.io.IoBridge;
-import libcore.io.IoUtils;
import libcore.io.Libcore;
import libcore.io.Streams;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* An input stream that reads bytes from a file.
@@ -75,7 +73,7 @@ public class FileInputStream extends InputStream {
if (file == null) {
throw new NullPointerException("file == null");
}
- this.fd = IoBridge.open(file.getAbsolutePath(), O_RDONLY);
+ this.fd = IoBridge.open(file.getPath(), O_RDONLY);
this.shouldClose = true;
guard.open("close");
}
@@ -118,7 +116,7 @@ public class FileInputStream extends InputStream {
channel.close();
}
if (shouldClose) {
- IoUtils.close(fd);
+ IoBridge.closeAndSignalBlockedThreads(fd);
} else {
// An owned fd has been invalidated by IoUtils.close, but
// we need to explicitly stop using an unowned fd (http://b/4361076).
diff --git a/luni/src/main/java/java/io/FileOutputStream.java b/luni/src/main/java/java/io/FileOutputStream.java
index e04ab5f..f91ee20 100644
--- a/luni/src/main/java/java/io/FileOutputStream.java
+++ b/luni/src/main/java/java/io/FileOutputStream.java
@@ -20,10 +20,9 @@ package java.io;
import dalvik.system.CloseGuard;
import java.nio.NioUtils;
import java.nio.channels.FileChannel;
-import java.util.Arrays;
import libcore.io.IoBridge;
-import libcore.io.IoUtils;
-import static libcore.io.OsConstants.*;
+
+import static android.system.OsConstants.*;
/**
* An output stream that writes bytes to a file. If the output file exists, it
@@ -85,7 +84,7 @@ public class FileOutputStream extends OutputStream {
throw new NullPointerException("file == null");
}
this.mode = O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC);
- this.fd = IoBridge.open(file.getAbsolutePath(), mode);
+ this.fd = IoBridge.open(file.getPath(), mode);
this.shouldClose = true;
this.guard.open("close");
}
@@ -136,7 +135,7 @@ public class FileOutputStream extends OutputStream {
channel.close();
}
if (shouldClose) {
- IoUtils.close(fd);
+ IoBridge.closeAndSignalBlockedThreads(fd);
} else {
// An owned fd has been invalidated by IoUtils.close, but
// we need to explicitly stop using an unowned fd (http://b/4361076).
diff --git a/luni/src/main/java/java/io/InputStream.java b/luni/src/main/java/java/io/InputStream.java
index 973382e..c489b2a 100644
--- a/luni/src/main/java/java/io/InputStream.java
+++ b/luni/src/main/java/java/io/InputStream.java
@@ -209,19 +209,21 @@ public abstract class InputStream extends Object implements Closeable {
}
/**
- * Skips at most {@code n} bytes in this stream. This method does nothing and returns
- * 0 if {@code n} is negative, but some subclasses may throw.
+ * Skips at most {@code byteCount} bytes in this stream. The number of actual
+ * bytes skipped may be anywhere between 0 and {@code byteCount}. If
+ * {@code byteCount} is negative, this method does nothing and returns 0, but
+ * some subclasses may throw.
*
- * <p>Note the "at most" in the description of this method: this method may choose to skip
- * fewer bytes than requested. Callers should <i>always</i> check the return value.
+ * <p>Note the "at most" in the description of this method: this method may
+ * choose to skip fewer bytes than requested. Callers should <i>always</i>
+ * check the return value.
*
- * <p>This default implementation reads bytes into a temporary
- * buffer. Concrete subclasses should provide their own implementation.
+ * <p>This default implementation reads bytes into a temporary buffer. Concrete
+ * subclasses should provide their own implementation.
*
- * @param byteCount the number of bytes to skip.
* @return the number of bytes actually skipped.
- * @throws IOException
- * if this stream is closed or another IOException occurs.
+ * @throws IOException if this stream is closed or another IOException
+ * occurs.
*/
public long skip(long byteCount) throws IOException {
return Streams.skipByReading(this, byteCount);
diff --git a/luni/src/main/java/java/io/InputStreamReader.java b/luni/src/main/java/java/io/InputStreamReader.java
index 01e7f29..d57b916 100644
--- a/luni/src/main/java/java/io/InputStreamReader.java
+++ b/luni/src/main/java/java/io/InputStreamReader.java
@@ -23,8 +23,6 @@ import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
-import java.nio.charset.MalformedInputException;
-import java.nio.charset.UnmappableCharacterException;
import java.util.Arrays;
/**
@@ -260,7 +258,9 @@ public class InputStreamReader extends Reader {
if (result == CoderResult.UNDERFLOW && endOfInput) {
result = decoder.decode(bytes, out, true);
- decoder.flush(out);
+ if (result == CoderResult.UNDERFLOW) {
+ result = decoder.flush(out);
+ }
decoder.reset();
}
if (result.isMalformed() || result.isUnmappable()) {
diff --git a/luni/src/main/java/java/io/ObjectInputStream.java b/luni/src/main/java/java/io/ObjectInputStream.java
index 17a6974..3a89b52 100644
--- a/luni/src/main/java/java/io/ObjectInputStream.java
+++ b/luni/src/main/java/java/io/ObjectInputStream.java
@@ -1739,9 +1739,7 @@ public class ObjectInputStream extends InputStream implements ObjectInput, Objec
*/
protected Class<?> resolveProxyClass(String[] interfaceNames)
throws IOException, ClassNotFoundException {
- // TODO: This method is opportunity for performance enhancement
- // We can cache the classloader and recently used interfaces.
- ClassLoader loader = ClassLoader.getSystemClassLoader();
+ ClassLoader loader = callerClassLoader;
Class<?>[] interfaces = new Class<?>[interfaceNames.length];
for (int i = 0; i < interfaceNames.length; i++) {
interfaces[i] = Class.forName(interfaceNames[i], false, loader);
diff --git a/luni/src/main/java/java/io/ObjectOutput.java b/luni/src/main/java/java/io/ObjectOutput.java
index 2e454ec..e6d7b0c 100644
--- a/luni/src/main/java/java/io/ObjectOutput.java
+++ b/luni/src/main/java/java/io/ObjectOutput.java
@@ -18,7 +18,7 @@
package java.io;
/**
- * Defines an interface for classes that allow reading serialized objects.
+ * Defines an interface for classes that allow writing serialized objects.
*
* @see ObjectOutputStream
* @see ObjectInput
diff --git a/luni/src/main/java/java/io/ObjectOutputStream.java b/luni/src/main/java/java/io/ObjectOutputStream.java
index 6a2fbed..f67919d 100644
--- a/luni/src/main/java/java/io/ObjectOutputStream.java
+++ b/luni/src/main/java/java/io/ObjectOutputStream.java
@@ -39,15 +39,13 @@ import libcore.io.SizeOf;
*/
public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants {
- private static final Class<?>[] WRITE_UNSHARED_PARAM_TYPES = new Class[] { Object.class };
-
/*
* Mask to zero SC_BLOC_DATA bit.
*/
private static final byte NOT_SC_BLOCK_DATA = (byte) (SC_BLOCK_DATA ^ 0xFF);
/*
- * How many nested levels to writeObject. We may not need this.
+ * How many nested levels to writeObject.
*/
private int nestedLevels;
@@ -98,11 +96,6 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
private int protocolVersion;
/*
- * Used to detect nested exception when saving an exception due to an error
- */
- private StreamCorruptedException nestedException;
-
- /*
* Used to keep track of the PutField object for the class/object being
* written
*/
@@ -271,7 +264,6 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
this.subclassOverridingImplementation = false;
resetState();
- this.nestedException = new StreamCorruptedException();
// So write...() methods can be used by
// subclasses during writeStreamHeader()
primitiveTypes = this.output;
@@ -462,20 +454,6 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
output.flush();
}
- /*
- * These methods get the value of a field named fieldName of object
- * instance. The field is declared by declaringClass. The field is the same
- * type as the method return value.
- *
- * these methods could be implemented non-natively on top of
- * java.lang.reflect at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch
- * private fields, except by the use of a native method like this one.
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native Object getFieldL(Object instance, Class<?> declaringClass, String fieldName, String fieldTypeName);
-
/**
* Return the next handle to be used to indicate cyclic
* references being saved to the stream.
@@ -1236,7 +1214,7 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
// The handle for the classDesc is NOT the handle for the class object
// being dumped. We must allocate a new handle and return it.
if (clDesc.isEnum()) {
- writeEnumDesc(object, clDesc, unshared);
+ writeEnumDesc(clDesc, unshared);
} else {
writeClassDesc(clDesc, unshared);
}
@@ -1521,14 +1499,15 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
primitiveTypes = output;
}
} catch (IOException ioEx1) {
- // This will make it pass through until the top caller. It also
- // lets it pass through the nested exception.
- if (nestedLevels == 0 && ioEx1 != nestedException) {
+ // This will make it pass through until the top caller. Only the top caller writes the
+ // exception (where it can).
+ if (nestedLevels == 0) {
try {
writeNewException(ioEx1);
} catch (IOException ioEx2) {
- nestedException.fillInStackTrace();
- throw nestedException;
+ // If writing the exception to the output stream causes another exception there
+ // is no need to propagate the second exception or generate a third exception,
+ // both of which might obscure details of the root cause.
}
}
throw ioEx1; // and then we propagate the original exception
@@ -1563,9 +1542,8 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
writeNull();
return -1;
}
- int handle = -1;
if (!unshared) {
- handle = dumpCycle(object);
+ int handle = dumpCycle(object);
if (handle != -1) {
return handle; // cyclic reference
}
@@ -1592,7 +1570,7 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
if (clDesc.isSerializable() && computeClassBasedReplacement) {
if (clDesc.hasMethodWriteReplace()){
Method methodWriteReplace = clDesc.getMethodWriteReplace();
- Object replObj = null;
+ Object replObj;
try {
replObj = methodWriteReplace.invoke(object, (Object[]) null);
} catch (IllegalAccessException iae) {
@@ -1677,7 +1655,7 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
}
// write for Enum Class Desc only, which is different from other classes
- private ObjectStreamClass writeEnumDesc(Class<?> theClass, ObjectStreamClass classDesc, boolean unshared)
+ private ObjectStreamClass writeEnumDesc(ObjectStreamClass classDesc, boolean unshared)
throws IOException {
// write classDesc, classDesc for enum is different
@@ -1716,7 +1694,7 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
if (superClassDesc != null) {
// super class is also enum
superClassDesc.setFlags((byte) (SC_SERIALIZABLE | SC_ENUM));
- writeEnumDesc(superClassDesc.forClass(), superClassDesc, unshared);
+ writeEnumDesc(superClassDesc, unshared);
} else {
output.writeByte(TC_NULL);
}
@@ -1740,7 +1718,7 @@ public class ObjectOutputStream extends OutputStream implements ObjectOutput, Ob
theClass = theClass.getSuperclass();
}
ObjectStreamClass classDesc = ObjectStreamClass.lookup(theClass);
- writeEnumDesc(theClass, classDesc, unshared);
+ writeEnumDesc(classDesc, unshared);
int previousHandle = -1;
if (unshared) {
diff --git a/luni/src/main/java/java/io/OutputStreamWriter.java b/luni/src/main/java/java/io/OutputStreamWriter.java
index d69c87a..bc8710d 100644
--- a/luni/src/main/java/java/io/OutputStreamWriter.java
+++ b/luni/src/main/java/java/io/OutputStreamWriter.java
@@ -122,8 +122,8 @@ public class OutputStreamWriter extends Writer {
}
/**
- * Closes this writer. This implementation flushes the buffer as well as the
- * target stream. The target stream is then closed and the resources for the
+ * Closes this writer. This implementation flushes the buffer but <strong>does not</strong>
+ * flush the target stream. The target stream is then closed and the resources for the
* buffer and converter are released.
*
* <p>Only the first invocation of this method has any effect. Subsequent calls
diff --git a/luni/src/main/java/java/io/PipedInputStream.java b/luni/src/main/java/java/io/PipedInputStream.java
index 2c27695..3e81cb8 100644
--- a/luni/src/main/java/java/io/PipedInputStream.java
+++ b/luni/src/main/java/java/io/PipedInputStream.java
@@ -390,6 +390,7 @@ public class PipedInputStream extends InputStream {
if (lastReader != null && !lastReader.isAlive()) {
throw new IOException("Pipe broken");
}
+
notifyAll();
wait(1000);
}
@@ -402,6 +403,10 @@ public class PipedInputStream extends InputStream {
if (in == -1) {
in = 0;
}
+ if (lastReader != null && !lastReader.isAlive()) {
+ throw new IOException("Pipe broken");
+ }
+
buffer[in++] = (byte) oneByte;
if (in == buffer.length) {
in = 0;
diff --git a/luni/src/main/java/java/io/PipedOutputStream.java b/luni/src/main/java/java/io/PipedOutputStream.java
index 1b139e9..4c431c1 100644
--- a/luni/src/main/java/java/io/PipedOutputStream.java
+++ b/luni/src/main/java/java/io/PipedOutputStream.java
@@ -140,7 +140,7 @@ public class PipedOutputStream extends OutputStream {
* @throws IOException
* if this stream is not connected, if the target stream is
* closed or if the thread reading from the target stream is no
- * longer alive. This case is currently not handled correctly.
+ * longer alive.
*/
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
diff --git a/luni/src/main/java/java/io/PipedReader.java b/luni/src/main/java/java/io/PipedReader.java
index 908505d..7bf9ed4 100644
--- a/luni/src/main/java/java/io/PipedReader.java
+++ b/luni/src/main/java/java/io/PipedReader.java
@@ -33,7 +33,7 @@ public class PipedReader extends Reader {
private Thread lastWriter;
- private boolean isClosed;
+ boolean isClosed;
/**
* The circular buffer through which data is passed. Data is read from the
diff --git a/luni/src/main/java/java/io/PipedWriter.java b/luni/src/main/java/java/io/PipedWriter.java
index ad8974b..e85f69c 100644
--- a/luni/src/main/java/java/io/PipedWriter.java
+++ b/luni/src/main/java/java/io/PipedWriter.java
@@ -17,8 +17,6 @@
package java.io;
-import java.util.Arrays;
-
/**
* Places information on a communications pipe. When two threads want to pass
* data back and forth, one creates a piped writer and the other creates a piped
@@ -115,6 +113,9 @@ public class PipedWriter extends Writer {
}
synchronized (reader) {
+ if (reader.isClosed) {
+ throw new IOException("Pipe is broken");
+ }
reader.notifyAll();
}
}
diff --git a/luni/src/main/java/java/io/RandomAccessFile.java b/luni/src/main/java/java/io/RandomAccessFile.java
index a60da3e..da99765 100644
--- a/luni/src/main/java/java/io/RandomAccessFile.java
+++ b/luni/src/main/java/java/io/RandomAccessFile.java
@@ -17,19 +17,18 @@
package java.io;
+import android.system.ErrnoException;
import dalvik.system.CloseGuard;
import java.nio.ByteOrder;
-import java.nio.NioUtils;
import java.nio.channels.FileChannel;
import java.nio.charset.ModifiedUtf8;
+import java.nio.NioUtils;
import java.util.Arrays;
-import libcore.io.ErrnoException;
import libcore.io.IoBridge;
-import libcore.io.IoUtils;
import libcore.io.Libcore;
import libcore.io.Memory;
import libcore.io.SizeOf;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* Allows reading from and writing to a file in a random-access manner. This is
@@ -115,7 +114,7 @@ public class RandomAccessFile implements DataInput, DataOutput, Closeable {
throw new IllegalArgumentException("Invalid mode: " + mode);
}
this.mode = flags;
- this.fd = IoBridge.open(file.getAbsolutePath(), flags);
+ this.fd = IoBridge.open(file.getPath(), flags);
// if we are in "rws" mode, attempt to sync file+metadata
if (syncMetadata) {
@@ -163,7 +162,7 @@ public class RandomAccessFile implements DataInput, DataOutput, Closeable {
channel.close();
channel = null;
}
- IoUtils.close(fd);
+ IoBridge.closeAndSignalBlockedThreads(fd);
}
}
diff --git a/luni/src/main/java/java/lang/AbstractStringBuilder.java b/luni/src/main/java/java/lang/AbstractStringBuilder.java
index c3107f2..4d84078 100644
--- a/luni/src/main/java/java/lang/AbstractStringBuilder.java
+++ b/luni/src/main/java/java/lang/AbstractStringBuilder.java
@@ -17,9 +17,10 @@
package java.lang;
+import libcore.util.EmptyArray;
+
import java.io.InvalidObjectException;
import java.util.Arrays;
-import libcore.util.EmptyArray;
/**
* A modifiable {@link CharSequence sequence of characters} for use in creating
@@ -192,14 +193,8 @@ abstract class AbstractStringBuilder {
}
/**
- * Retrieves the character at the {@code index}.
- *
- * @param index
- * the index of the character to retrieve.
- * @return the char value.
- * @throws IndexOutOfBoundsException
- * if {@code index} is negative or greater than or equal to the
- * current {@link #length()}.
+ * Returns the character at {@code index}.
+ * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}.
*/
public char charAt(int index) {
if (index < 0 || index >= count) {
@@ -217,50 +212,46 @@ abstract class AbstractStringBuilder {
}
final void delete0(int start, int end) {
- if (start >= 0) {
- if (end > count) {
- end = count;
- }
- if (end == start) {
- return;
- }
- if (end > start) {
- int length = count - end;
- if (length >= 0) {
- if (!shared) {
- System.arraycopy(value, end, value, start, length);
- } else {
- char[] newData = new char[value.length];
- System.arraycopy(value, 0, newData, 0, start);
- System.arraycopy(value, end, newData, start, length);
- value = newData;
- shared = false;
- }
- }
- count -= end - start;
- return;
- }
+ // NOTE: StringBuilder#delete(int, int) is specified not to throw if
+ // the end index is >= count, as long as it's >= start. This means
+ // we have to clamp it to count here.
+ if (end > count) {
+ end = count;
}
- throw startEndAndLength(start, end);
- }
- final void deleteCharAt0(int index) {
- if (index < 0 || index >= count) {
- throw indexAndLength(index);
+ if (start < 0 || start > count || start > end) {
+ throw startEndAndLength(start, end);
}
- int length = count - index - 1;
- if (length > 0) {
+
+ // NOTE: StringBuilder#delete(int, int) throws only if start > count
+ // (start == count is considered valid, oddly enough). Since 'end' is
+ // already a clamped value, that case is handled here.
+ if (end == start) {
+ return;
+ }
+
+ // At this point we know for sure that end > start.
+ int length = count - end;
+ if (length >= 0) {
if (!shared) {
- System.arraycopy(value, index + 1, value, index, length);
+ System.arraycopy(value, end, value, start, length);
} else {
char[] newData = new char[value.length];
- System.arraycopy(value, 0, newData, 0, index);
- System.arraycopy(value, index + 1, newData, index, length);
+ System.arraycopy(value, 0, newData, 0, start);
+ System.arraycopy(value, end, newData, start, length);
value = newData;
shared = false;
}
}
- count--;
+ count -= end - start;
+ }
+
+ final void deleteCharAt0(int index) {
+ if (index < 0 || index >= count) {
+ throw indexAndLength(index);
+ }
+
+ delete0(index, index + 1);
}
/**
@@ -552,7 +543,7 @@ abstract class AbstractStringBuilder {
*
* @param length
* the new length of this StringBuffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code length < 0}.
* @see #length
*/
diff --git a/luni/src/main/java/java/lang/CaseMapper.java b/luni/src/main/java/java/lang/CaseMapper.java
index 5ec41f5..1da621c 100644
--- a/luni/src/main/java/java/lang/CaseMapper.java
+++ b/luni/src/main/java/java/lang/CaseMapper.java
@@ -18,6 +18,7 @@ package java.lang;
import java.util.Locale;
import libcore.icu.ICU;
+import libcore.icu.Transliterator;
/**
* Performs case operations as described by http://unicode.org/reports/tr21/tr21-5.html.
@@ -45,9 +46,10 @@ class CaseMapper {
*/
public static String toLowerCase(Locale locale, String s, char[] value, int offset, int count) {
// Punt hard cases to ICU4C.
+ // Note that Greek isn't a particularly hard case for toLowerCase, only toUpperCase.
String languageCode = locale.getLanguage();
if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
- return ICU.toLowerCase(s, locale.toString());
+ return ICU.toLowerCase(s, locale);
}
char[] newValue = null;
@@ -57,7 +59,7 @@ class CaseMapper {
char newCh;
if (ch == LATIN_CAPITAL_I_WITH_DOT || Character.isHighSurrogate(ch)) {
// Punt these hard cases.
- return ICU.toLowerCase(s, locale.toString());
+ return ICU.toLowerCase(s, locale);
} else if (ch == GREEK_CAPITAL_SIGMA && isFinalSigma(value, offset, count, i)) {
newCh = GREEK_SMALL_FINAL_SIGMA;
} else {
@@ -139,10 +141,19 @@ class CaseMapper {
return index;
}
+ private static final ThreadLocal<Transliterator> EL_UPPER = new ThreadLocal<Transliterator>() {
+ @Override protected Transliterator initialValue() {
+ return new Transliterator("el-Upper");
+ }
+ };
+
public static String toUpperCase(Locale locale, String s, char[] value, int offset, int count) {
String languageCode = locale.getLanguage();
if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
- return ICU.toUpperCase(s, locale.toString());
+ return ICU.toUpperCase(s, locale);
+ }
+ if (languageCode.equals("el")) {
+ return EL_UPPER.get().transliterate(s);
}
char[] output = null;
@@ -150,7 +161,7 @@ class CaseMapper {
for (int o = offset, end = offset + count; o < end; o++) {
char ch = value[o];
if (Character.isHighSurrogate(ch)) {
- return ICU.toUpperCase(s, locale.toString());
+ return ICU.toUpperCase(s, locale);
}
int index = upperIndex(ch);
if (index == -1) {
diff --git a/luni/src/main/java/java/lang/CharSequence.java b/luni/src/main/java/java/lang/CharSequence.java
index fc1ecd3..0e1ea3f 100644
--- a/luni/src/main/java/java/lang/CharSequence.java
+++ b/luni/src/main/java/java/lang/CharSequence.java
@@ -32,15 +32,8 @@ public interface CharSequence {
public int length();
/**
- * Returns the character at the specified index, with the first character
- * having index zero.
- *
- * @param index
- * the index of the character to return.
- * @return the requested character.
- * @throws IndexOutOfBoundsException
- * if {@code index < 0} or {@code index} is greater than the
- * length of this sequence.
+ * Returns the character at {@code index}.
+ * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}.
*/
public char charAt(int index);
diff --git a/luni/src/main/java/java/lang/Character.java b/luni/src/main/java/java/lang/Character.java
index 5762bd4..2046ba8 100644
--- a/luni/src/main/java/java/lang/Character.java
+++ b/luni/src/main/java/java/lang/Character.java
@@ -46,7 +46,7 @@ import java.util.Arrays;
* point or a UTF-16 unit that's part of a surrogate pair. The {@code int} type
* is used to represent all Unicode code points.
*
- * <a name="unicode_categories"><h3>Unicode categories</h3></a>
+ * <a name="unicode_categories"></a><h3>Unicode categories</h3>
* <p>Here's a list of the Unicode character categories and the corresponding Java constant,
* grouped semantically to provide a convenient overview. This table is also useful in
* conjunction with {@code \p} and {@code \P} in {@link java.util.regex.Pattern regular expressions}.
@@ -1489,7 +1489,7 @@ public final class Character implements Serializable, Comparable<Character> {
if (blockName == null) {
throw new NullPointerException("blockName == null");
}
- int block = forNameImpl(blockName);
+ int block = unicodeBlockForName(blockName);
if (block == -1) {
throw new IllegalArgumentException("Unknown block: " + blockName);
}
@@ -1510,7 +1510,7 @@ public final class Character implements Serializable, Comparable<Character> {
*/
public static UnicodeBlock of(int codePoint) {
checkValidCodePoint(codePoint);
- int block = ofImpl(codePoint);
+ int block = unicodeBlockForCodePoint(codePoint);
if (block == -1 || block >= BLOCKS.length) {
return null;
}
@@ -1522,9 +1522,14 @@ public final class Character implements Serializable, Comparable<Character> {
}
}
- private static native int forNameImpl(String blockName);
+ private static native int unicodeBlockForName(String blockName);
+
+ private static native int unicodeBlockForCodePoint(int codePoint);
+
+ private static native int unicodeScriptForName(String blockName);
+
+ private static native int unicodeScriptForCodePoint(int codePoint);
- private static native int ofImpl(int codePoint);
/**
* Constructs a new {@code Character} with the specified primitive char
@@ -2525,25 +2530,28 @@ public final class Character implements Serializable, Comparable<Character> {
}
/**
- * Gets the Unicode directionality of the specified character.
- *
- * @param codePoint
- * the Unicode code point to get the directionality of.
- * @return the Unicode directionality of {@code codePoint}.
+ * Returns the Unicode directionality of the given code point.
+ * This will be one of the {@code DIRECTIONALITY_} constants.
+ * For characters whose directionality is undefined, or whose
+ * directionality has no appropriate constant in this class,
+ * {@code DIRECTIONALITY_UNDEFINED} is returned.
*/
public static byte getDirectionality(int codePoint) {
if (getType(codePoint) == Character.UNASSIGNED) {
return Character.DIRECTIONALITY_UNDEFINED;
}
- byte directionality = getDirectionalityImpl(codePoint);
- if (directionality == -1) {
- return -1;
+ byte directionality = getIcuDirectionality(codePoint);
+ if (directionality >= 0 && directionality < DIRECTIONALITY.length) {
+ return DIRECTIONALITY[directionality];
}
- return DIRECTIONALITY[directionality];
+ return Character.DIRECTIONALITY_UNDEFINED;
}
- private static native byte getDirectionalityImpl(int codePoint);
+ /**
+ * @hide - internal use only.
+ */
+ public static native byte getIcuDirectionality(int codePoint);
/**
* Indicates whether the specified character is mirrored.
diff --git a/luni/src/main/java/java/lang/Double.java b/luni/src/main/java/java/lang/Double.java
index 456529b..cb8c301 100644
--- a/luni/src/main/java/java/lang/Double.java
+++ b/luni/src/main/java/java/lang/Double.java
@@ -171,7 +171,13 @@ public final class Double extends Number implements Comparable<Double> {
* {@code value}. All <em>Not-a-Number (NaN)</em> values are converted to a single NaN
* representation ({@code 0x7ff8000000000000L}) (compare to {@link #doubleToRawLongBits}).
*/
- public static native long doubleToLongBits(double value);
+ public static long doubleToLongBits(double value) {
+ if (value != value) {
+ return 0x7ff8000000000000L; // NaN.
+ } else {
+ return doubleToRawLongBits(value);
+ }
+ }
/**
* Returns an integer corresponding to the bits of the given
diff --git a/luni/src/main/java/java/lang/Float.java b/luni/src/main/java/java/lang/Float.java
index 900b2a0..5f316f1 100644
--- a/luni/src/main/java/java/lang/Float.java
+++ b/luni/src/main/java/java/lang/Float.java
@@ -199,7 +199,13 @@ public final class Float extends Number implements Comparable<Float> {
* float {@code value}. All <em>Not-a-Number (NaN)</em> values are converted to a single NaN
* representation ({@code 0x7fc00000}) (compare to {@link #floatToRawIntBits}).
*/
- public static native int floatToIntBits(float value);
+ public static int floatToIntBits(float value) {
+ if (value != value) {
+ return 0x7fc00000; // NaN.
+ } else {
+ return floatToRawIntBits(value);
+ }
+ }
/**
* Returns an integer corresponding to the bits of the given
diff --git a/luni/src/main/java/java/lang/Integer.java b/luni/src/main/java/java/lang/Integer.java
index fc38b41..8ae0312 100644
--- a/luni/src/main/java/java/lang/Integer.java
+++ b/luni/src/main/java/java/lang/Integer.java
@@ -126,7 +126,8 @@ public final class Integer extends Number implements Comparable<Integer> {
/**
* Compares two {@code int} values.
- * @return 0 if lhs = rhs, less than 0 if lhs &lt; rhs, and greater than 0 if lhs &gt; rhs.
+ * @return 0 if lhs = rhs, less than 0 if lhs &lt; rhs, and greater than 0
+ * if lhs &gt; rhs.
* @since 1.7
*/
public static int compare(int lhs, int rhs) {
@@ -140,24 +141,26 @@ public final class Integer extends Number implements Comparable<Integer> {
/**
* Parses the specified string and returns a {@code Integer} instance if the
* string can be decoded into an integer value. The string may be an
- * optional minus sign "-" followed by a hexadecimal ("0x..." or "#..."),
- * octal ("0..."), or decimal ("...") representation of an integer.
+ * optional sign character ("-" or "+") followed by a hexadecimal ("0x..."
+ * or "#..."), octal ("0..."), or decimal ("...") representation of an
+ * integer.
*
* @param string
* a string representation of an integer value.
* @return an {@code Integer} containing the value represented by
* {@code string}.
* @throws NumberFormatException
- * if {@code string} cannot be parsed as an integer value.
+ * if {@code string} cannot be parsed as an integer value.
*/
public static Integer decode(String string) throws NumberFormatException {
- int length = string.length(), i = 0;
+ int length = string.length();
if (length == 0) {
throw invalidInt(string);
}
+ int i = 0;
char firstDigit = string.charAt(i);
boolean negative = firstDigit == '-';
- if (negative) {
+ if (negative || firstDigit == '+') {
if (length == 1) {
throw invalidInt(string);
}
@@ -319,8 +322,8 @@ public final class Integer extends Number implements Comparable<Integer> {
/**
* Parses the specified string as a signed decimal integer value. The ASCII
- * character \u002d ('-') is recognized as the minus sign.
- *
+ * characters \u002d ('-') and \u002b ('+') are recognized as the minus and
+ * plus signs.
* @param string
* the string representation of an integer value.
* @return the primitive integer value represented by {@code string}.
@@ -333,7 +336,8 @@ public final class Integer extends Number implements Comparable<Integer> {
/**
* Parses the specified string as a signed integer value using the specified
- * radix. The ASCII character \u002d ('-') is recognized as the minus sign.
+ * radix. The ASCII characters \u002d ('-') and \u002b ('+') are recognized
+ * as the minus and plus signs.
*
* @param string
* the string representation of an integer value.
@@ -350,24 +354,56 @@ public final class Integer extends Number implements Comparable<Integer> {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
throw new NumberFormatException("Invalid radix: " + radix);
}
- if (string == null) {
+ if (string == null || string.isEmpty()) {
throw invalidInt(string);
}
- int length = string.length(), i = 0;
- if (length == 0) {
+
+ char firstChar = string.charAt(0);
+ int firstDigitIndex = (firstChar == '-' || firstChar == '+') ? 1 : 0;
+ if (firstDigitIndex == string.length()) {
throw invalidInt(string);
}
- boolean negative = string.charAt(i) == '-';
- if (negative && ++i == length) {
+
+ return parse(string, firstDigitIndex, radix, firstChar == '-');
+ }
+
+ /**
+ * Equivalent to {@code parsePositiveInt(string, 10)}.
+ *
+ * @see #parsePositiveInt(String, int)
+ *
+ * @hide
+ */
+ public static int parsePositiveInt(String string) throws NumberFormatException {
+ return parsePositiveInt(string, 10);
+ }
+
+ /**
+ * Parses the specified string as a positive integer value using the
+ * specified radix. 0 is considered a positive integer.
+ * <p>
+ * This method behaves the same as {@link #parseInt(String, int)} except
+ * that it disallows leading '+' and '-' characters. See that method for
+ * error conditions.
+ *
+ * @see #parseInt(String, int)
+ *
+ * @hide
+ */
+ public static int parsePositiveInt(String string, int radix) throws NumberFormatException {
+ if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
+ throw new NumberFormatException("Invalid radix: " + radix);
+ }
+ if (string == null || string.length() == 0) {
throw invalidInt(string);
}
-
- return parse(string, i, radix, negative);
+ return parse(string, 0, radix, false);
}
private static int parse(String string, int offset, int radix, boolean negative) throws NumberFormatException {
int max = Integer.MIN_VALUE / radix;
- int result = 0, length = string.length();
+ int result = 0;
+ int length = string.length();
while (offset < length) {
int digit = Character.digit(string.charAt(offset++), radix);
if (digit == -1) {
diff --git a/luni/src/main/java/java/lang/Long.java b/luni/src/main/java/java/lang/Long.java
index 84169af..5c11564 100644
--- a/luni/src/main/java/java/lang/Long.java
+++ b/luni/src/main/java/java/lang/Long.java
@@ -127,8 +127,8 @@ public final class Long extends Number implements Comparable<Long> {
/**
* Parses the specified string and returns a {@code Long} instance if the
* string can be decoded into a long value. The string may be an optional
- * minus sign "-" followed by a hexadecimal ("0x..." or "#..."), octal
- * ("0..."), or decimal ("...") representation of a long.
+ * optional sign character ("-" or "+") followed by a hexadecimal ("0x..."
+ * or "#..."), octal ("0..."), or decimal ("...") representation of a long.
*
* @param string
* a string representation of a long value.
@@ -137,13 +137,15 @@ public final class Long extends Number implements Comparable<Long> {
* if {@code string} cannot be parsed as a long value.
*/
public static Long decode(String string) throws NumberFormatException {
- int length = string.length(), i = 0;
+ int length = string.length();
if (length == 0) {
throw invalidLong(string);
}
+
+ int i = 0;
char firstDigit = string.charAt(i);
boolean negative = firstDigit == '-';
- if (negative) {
+ if (negative || firstDigit == '+') {
if (length == 1) {
throw invalidLong(string);
}
@@ -306,7 +308,8 @@ public final class Long extends Number implements Comparable<Long> {
/**
* Parses the specified string as a signed decimal long value. The ASCII
- * character \u002d ('-') is recognized as the minus sign.
+ * characters \u002d ('-') and \u002b ('+') are recognized as the minus and
+ * plus signs.
*
* @param string
* the string representation of a long value.
@@ -320,7 +323,8 @@ public final class Long extends Number implements Comparable<Long> {
/**
* Parses the specified string as a signed long value using the specified
- * radix. The ASCII character \u002d ('-') is recognized as the minus sign.
+ * radix. The ASCII characters \u002d ('-') and \u002b ('+') are recognized
+ * as the minus and plus signs.
*
* @param string
* the string representation of a long value.
@@ -337,24 +341,22 @@ public final class Long extends Number implements Comparable<Long> {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
throw new NumberFormatException("Invalid radix: " + radix);
}
- if (string == null) {
- throw invalidLong(string);
- }
- int length = string.length(), i = 0;
- if (length == 0) {
+ if (string == null || string.isEmpty()) {
throw invalidLong(string);
}
- boolean negative = string.charAt(i) == '-';
- if (negative && ++i == length) {
+ char firstChar = string.charAt(0);
+ int firstDigitIndex = (firstChar == '-' || firstChar == '+') ? 1 : 0;
+ if (firstDigitIndex == string.length()) {
throw invalidLong(string);
}
- return parse(string, i, radix, negative);
+ return parse(string, firstDigitIndex, radix, firstChar == '-');
}
private static long parse(String string, int offset, int radix, boolean negative) {
long max = Long.MIN_VALUE / radix;
- long result = 0, length = string.length();
+ long result = 0;
+ int length = string.length();
while (offset < length) {
int digit = Character.digit(string.charAt(offset++), radix);
if (digit == -1) {
@@ -378,6 +380,39 @@ public final class Long extends Number implements Comparable<Long> {
return result;
}
+ /**
+ * Equivalent to {@code parsePositiveLong(string, 10)}.
+ *
+ * @see #parsePositiveLong(String, int)
+ *
+ * @hide
+ */
+ public static long parsePositiveLong(String string) throws NumberFormatException {
+ return parsePositiveLong(string, 10);
+ }
+
+ /**
+ * Parses the specified string as a positive long value using the
+ * specified radix. 0 is considered a positive long.
+ * <p>
+ * This method behaves the same as {@link #parseLong(String, int)} except
+ * that it disallows leading '+' and '-' characters. See that method for
+ * error conditions.
+ *
+ * @see #parseLong(String, int)
+ *
+ * @hide
+ */
+ public static long parsePositiveLong(String string, int radix) throws NumberFormatException {
+ if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
+ throw new NumberFormatException("Invalid radix: " + radix);
+ }
+ if (string == null || string.length() == 0) {
+ throw invalidLong(string);
+ }
+ return parse(string, 0, radix, false);
+ }
+
@Override
public short shortValue() {
return (short) value;
diff --git a/luni/src/main/java/java/lang/ProcessManager.java b/luni/src/main/java/java/lang/ProcessManager.java
index 28314b7..ec87fda 100644
--- a/luni/src/main/java/java/lang/ProcessManager.java
+++ b/luni/src/main/java/java/lang/ProcessManager.java
@@ -16,23 +16,23 @@
package java.lang;
+import android.system.ErrnoException;
+import android.util.MutableInt;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.InputStream;
+import java.io.IOException;
import java.io.OutputStream;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;
-import libcore.util.MutableInt;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* Manages child processes.
diff --git a/luni/src/main/java/java/lang/Runtime.java b/luni/src/main/java/java/lang/Runtime.java
index 8538f8a..a3cb83e 100644
--- a/luni/src/main/java/java/lang/Runtime.java
+++ b/luni/src/main/java/java/lang/Runtime.java
@@ -48,7 +48,7 @@ import java.util.StringTokenizer;
import libcore.io.IoUtils;
import libcore.io.Libcore;
import libcore.util.EmptyArray;
-import static libcore.io.OsConstants._SC_NPROCESSORS_CONF;
+import static android.system.OsConstants._SC_NPROCESSORS_CONF;
/**
* Allows Java applications to interface with the environment in which they are
@@ -307,57 +307,64 @@ public class Runtime {
}
/**
- * Loads and links the dynamic library that is identified through the
- * specified path. This method is similar to {@link #loadLibrary(String)},
- * but it accepts a full path specification whereas {@code loadLibrary} just
- * accepts the name of the library to load.
+ * Loads the shared library found at the given absolute path.
+ * This should be of the form {@code /path/to/library/libMyLibrary.so}.
+ * Most callers should use {@link #loadLibrary(String)} instead, and
+ * let the system find the correct file to load.
*
- * @param pathName
- * the absolute (platform dependent) path to the library to load.
- * @throws UnsatisfiedLinkError
- * if the library can not be loaded.
+ * @throws UnsatisfiedLinkError if the library can not be loaded,
+ * either because it's not found or because there is something wrong with it.
*/
- public void load(String pathName) {
- load(pathName, VMStack.getCallingClassLoader());
+ public void load(String absolutePath) {
+ load(absolutePath, VMStack.getCallingClassLoader());
}
/*
- * Loads and links the given library without security checks.
+ * Loads the given shared library using the given ClassLoader.
*/
- void load(String pathName, ClassLoader loader) {
- if (pathName == null) {
- throw new NullPointerException("pathName == null");
+ void load(String absolutePath, ClassLoader loader) {
+ if (absolutePath == null) {
+ throw new NullPointerException("absolutePath == null");
}
- String error = doLoad(pathName, loader);
+ String error = doLoad(absolutePath, loader);
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
}
/**
- * Loads and links the library with the specified name. The mapping of the
- * specified library name to the full path for loading the library is
- * implementation-dependent.
+ * Loads a shared library. Class loaders have some influence over this
+ * process, but for a typical Android app, it works as follows:
*
- * @param libName
- * the name of the library to load.
- * @throws UnsatisfiedLinkError
- * if the library can not be loaded.
+ * <p>Given the name {@code "MyLibrary"}, that string will be passed to
+ * {@link System#mapLibraryName}. That means it would be a mistake
+ * for the caller to include the usual {@code "lib"} prefix and {@code ".so"}
+ * suffix.
+ *
+ * <p>That file will then be searched for on the application's native library
+ * search path. This consists of the application's own native library directory
+ * followed by the system's native library directories.
+ *
+ * @throws UnsatisfiedLinkError if the library can not be loaded,
+ * either because it's not found or because there is something wrong with it.
*/
- public void loadLibrary(String libName) {
- loadLibrary(libName, VMStack.getCallingClassLoader());
+ public void loadLibrary(String nickname) {
+ loadLibrary(nickname, VMStack.getCallingClassLoader());
}
/*
- * Searches for a library, then loads and links it without security checks.
+ * Searches for and loads the given shared library using the given ClassLoader.
*/
void loadLibrary(String libraryName, ClassLoader loader) {
if (loader != null) {
String filename = loader.findLibrary(libraryName);
if (filename == null) {
- throw new UnsatisfiedLinkError("Couldn't load " + libraryName +
- " from loader " + loader +
- ": findLibrary returned null");
+ // It's not necessarily true that the ClassLoader used
+ // System.mapLibraryName, but the default setup does, and it's
+ // misleading to say we didn't find "libMyLibrary.so" when we
+ // actually searched for "liblibMyLibrary.so.so".
+ throw new UnsatisfiedLinkError(loader + " couldn't find \"" +
+ System.mapLibraryName(libraryName) + "\"");
}
String error = doLoad(filename, loader);
if (error != null) {
diff --git a/luni/src/main/java/java/lang/StringToReal.java b/luni/src/main/java/java/lang/StringToReal.java
index 97f6d6b..4bd4fb1 100644
--- a/luni/src/main/java/java/lang/StringToReal.java
+++ b/luni/src/main/java/java/lang/StringToReal.java
@@ -122,20 +122,20 @@ final class StringToReal {
result.e = -result.e;
}
} catch (NumberFormatException ex) {
- // We already checked the string, so the exponent must have been out of range for an int.
+ // We already checked the string, so the exponent must have been out of range for an
+ // int.
if (negativeExponent) {
result.zero = true;
} else {
result.infinity = true;
}
- return result;
+ // Fall through: We want to check the content of the mantissa and throw an
+ // exception if it contains invalid characters. For example: "JUNK" * 10^12 should
+ // be treated as an error, not as infinity.
}
} else {
end = length;
}
- if (length == 0) {
- throw invalidReal(s, isDouble);
- }
int start = 0;
c = s.charAt(start);
@@ -151,7 +151,19 @@ final class StringToReal {
throw invalidReal(s, isDouble);
}
- int decimal = s.indexOf('.');
+ // Confirm that the mantissa should parse.
+ int decimal = -1;
+ for (int i = start; i < end; i++) {
+ char mc = s.charAt(i);
+ if (mc == '.') {
+ if (decimal != -1) {
+ throw invalidReal(s, isDouble);
+ }
+ decimal = i;
+ } else if (mc < '0' || mc > '9') {
+ throw invalidReal(s, isDouble);
+ }
+ }
if (decimal > -1) {
result.e -= end - decimal - 1;
s = s.substring(start, decimal) + s.substring(decimal + 1, end);
@@ -159,10 +171,17 @@ final class StringToReal {
s = s.substring(start, end);
}
- if ((length = s.length()) == 0) {
+ length = s.length();
+ if (length == 0) {
throw invalidReal(s, isDouble);
}
+ // All syntactic checks that might throw an exception are above. If we have established
+ // one of the non-exception error conditions we can stop here.
+ if (result.infinity || result.zero) {
+ return result;
+ }
+
end = length;
while (end > 1 && s.charAt(end - 1) == '0') {
--end;
@@ -237,7 +256,7 @@ final class StringToReal {
* the String that will be parsed to a floating point
* @return the double closest to the real number
*
- * @exception NumberFormatException
+ * @throws NumberFormatException
* if the String doesn't represent a double
*/
public static double parseDouble(String s) {
@@ -278,7 +297,7 @@ final class StringToReal {
* the String that will be parsed to a floating point
* @return the float closest to the real number
*
- * @exception NumberFormatException
+ * @throws NumberFormatException
* if the String doesn't represent a float
*/
public static float parseFloat(String s) {
diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java
index 68ca506..55ca762 100644
--- a/luni/src/main/java/java/lang/System.java
+++ b/luni/src/main/java/java/lang/System.java
@@ -32,6 +32,9 @@
package java.lang;
+import android.system.ErrnoException;
+import android.system.StructPasswd;
+import android.system.StructUtsname;
import dalvik.system.VMRuntime;
import dalvik.system.VMStack;
import java.io.BufferedInputStream;
@@ -39,8 +42,8 @@ import java.io.Console;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.InputStream;
+import java.io.IOException;
import java.io.PrintStream;
import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider;
@@ -51,11 +54,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import libcore.icu.ICU;
-import libcore.io.ErrnoException;
import libcore.io.Libcore;
-import libcore.io.StructPasswd;
-import libcore.io.StructUtsname;
-import libcore.util.ZoneInfoDB;
/**
* Provides access to system-related information and resources including
@@ -83,12 +82,31 @@ public final class System {
public static final PrintStream err;
private static final String lineSeparator;
+ private static final Properties unchangeableSystemProperties;
private static Properties systemProperties;
+ /**
+ * Dedicated lock for GC / Finalization logic.
+ */
+ private static final Object lock = new Object();
+
+ /**
+ * Whether or not we need to do a GC before running the finalizers.
+ */
+ private static boolean runGC;
+
+ /**
+ * If we just ran finalization, we might want to do a GC to free the finalized objects.
+ * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc().
+ */
+ private static boolean justRanFinalization;
+
static {
err = new PrintStream(new FileOutputStream(FileDescriptor.err));
out = new PrintStream(new FileOutputStream(FileDescriptor.out));
in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
+ unchangeableSystemProperties = initUnchangeableSystemProperties();
+ systemProperties = createSystemProperties();
lineSeparator = System.getProperty("line.separator");
}
@@ -153,7 +171,433 @@ public final class System {
* @param length
* the number of elements to be copied.
*/
- public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length);
+
+ public static native void arraycopy(Object src, int srcPos,
+ Object dst, int dstPos, int length);
+
+ /**
+ * The char array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The char[] specialized version of arraycopy().
+ *
+ * @hide internal use only
+ */
+ public static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD) {
+ // Copy char by char for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyCharUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The char[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ private static native void arraycopyCharUnchecked(char[] src, int srcPos,
+ char[] dst, int dstPos, int length);
+
+ /**
+ * The byte array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The byte[] specialized version of arraycopy().
+ *
+ * @hide internal use only
+ */
+ public static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD) {
+ // Copy byte by byte for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyByteUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The byte[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ private static native void arraycopyByteUnchecked(byte[] src, int srcPos,
+ byte[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The short[] specialized version of arraycopy().
+ *
+ * @hide internal use only
+ */
+ public static void arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD) {
+ // Copy short by short for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyShortUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The short[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ private static native void arraycopyShortUnchecked(short[] src, int srcPos,
+ short[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The int[] specialized version of arraycopy().
+ *
+ * @hide internal use only
+ */
+ public static void arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD) {
+ // Copy int by int for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyIntUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The int[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ private static native void arraycopyIntUnchecked(int[] src, int srcPos,
+ int[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The long[] specialized version of arraycopy().
+ *
+ * @hide internal use only
+ */
+ public static void arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD) {
+ // Copy long by long for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyLongUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The long[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ private static native void arraycopyLongUnchecked(long[] src, int srcPos,
+ long[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The float[] specialized version of arraycopy().
+ *
+ * @hide internal use only
+ */
+ public static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD) {
+ // Copy float by float for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for floater arrays.
+ arraycopyFloatUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The float[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ private static native void arraycopyFloatUnchecked(float[] src, int srcPos,
+ float[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The double[] specialized version of arraycopy().
+ *
+ * @hide internal use only
+ */
+ public static void arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD) {
+ // Copy double by double for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for floater arrays.
+ arraycopyDoubleUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The double[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ private static native void arraycopyDoubleUnchecked(double[] src, int srcPos,
+ double[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The boolean[] specialized version of arraycopy().
+ *
+ * @hide internal use only
+ */
+ public static void arraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD) {
+ // Copy boolean by boolean for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for floater arrays.
+ arraycopyBooleanUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The boolean[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ private static native void arraycopyBooleanUnchecked(boolean[] src, int srcPos,
+ boolean[] dst, int dstPos, int length);
/**
* Returns the current time in milliseconds since January 1, 1970 00:00:00.0 UTC.
@@ -196,7 +640,18 @@ public final class System {
* that the garbage collector will actually be run.
*/
public static void gc() {
- Runtime.getRuntime().gc();
+ boolean shouldRunGC;
+ synchronized(lock) {
+ shouldRunGC = justRanFinalization;
+ if (shouldRunGC) {
+ justRanFinalization = false;
+ } else {
+ runGC = true;
+ }
+ }
+ if (shouldRunGC) {
+ Runtime.getRuntime().gc();
+ }
}
/**
@@ -246,13 +701,10 @@ public final class System {
* @return the system properties.
*/
public static Properties getProperties() {
- if (systemProperties == null) {
- initSystemProperties();
- }
return systemProperties;
}
- private static void initSystemProperties() {
+ private static Properties initUnchangeableSystemProperties() {
VMRuntime runtime = VMRuntime.getRuntime();
Properties p = new Properties();
@@ -277,15 +729,6 @@ public final class System {
}
p.put("java.home", javaHome);
- // On Android, each app gets its own temporary directory. This is just a fallback
- // default, useful only on the host.
- p.put("java.io.tmpdir", "/tmp");
-
- String ldLibraryPath = getenv("LD_LIBRARY_PATH");
- if (ldLibraryPath != null) {
- p.put("java.library.path", ldLibraryPath);
- }
-
p.put("java.specification.name", "Dalvik Core Library");
p.put("java.specification.vendor", projectName);
p.put("java.specification.version", "0.9");
@@ -313,7 +756,6 @@ public final class System {
try {
StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid());
- p.put("user.home", passwd.pw_dir);
p.put("user.name", passwd.pw_name);
} catch (ErrnoException exception) {
throw new AssertionError(exception);
@@ -333,8 +775,36 @@ public final class System {
// Override built-in properties with settings from the command line.
parsePropertyAssignments(p, runtime.properties());
+ return p;
+ }
+
+ /**
+ * Inits an unchangeable system property with the given value.
+ * This is useful when the environment needs to change under native bridge emulation.
+ */
+ private static void initUnchangeableSystemProperty(String name, String value) {
+ checkPropertyName(name);
+ unchangeableSystemProperties.put(name, value);
+ }
+
+ private static void setDefaultChangeableProperties(Properties p) {
+ // On Android, each app gets its own temporary directory.
+ // (See android.app.ActivityThread.) This is just a fallback default,
+ // useful only on the host.
+ p.put("java.io.tmpdir", "/tmp");
- systemProperties = p;
+ // Android has always had an empty "user.home" (see docs for getProperty).
+ // This is not useful for normal android apps which need to use android specific
+ // APIs such as {@code Context.getFilesDir} and {@code Context.getCacheDir} but
+ // we make it changeable for backward compatibility, so that they can change it
+ // to a writeable location if required.
+ p.put("user.home", "");
+ }
+
+ private static Properties createSystemProperties() {
+ Properties p = new PropertiesWithNonOverrideableDefaults(unchangeableSystemProperties);
+ setDefaultChangeableProperties(p);
+ return p;
}
/**
@@ -360,7 +830,7 @@ public final class System {
* Returns the value of a particular system property or {@code null} if no
* such property exists.
*
- * <p>The following properties are always provided by the Dalvik VM:
+ * <p>The following properties are always provided by the Dalvik VM:</p>
* <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <td><b>Name</b></td> <td><b>Meaning</b></td> <td><b>Example</b></td></tr>
@@ -401,7 +871,8 @@ public final class System {
*
* </table>
*
- * <p>It is a mistake to try to override any of these. Doing so will have unpredictable results.
+ * <p> All of the above properties except for {@code user.home} and {@code java.io.tmpdir}
+ * <b>cannot be modified</b>. Any attempt to change them will be a no-op.
*
* @param propertyName
* the name of the system property to look up.
@@ -418,22 +889,26 @@ public final class System {
*/
public static String getProperty(String name, String defaultValue) {
checkPropertyName(name);
- return getProperties().getProperty(name, defaultValue);
+ return systemProperties.getProperty(name, defaultValue);
}
/**
- * Sets the value of a particular system property.
+ * Sets the value of a particular system property. Most system properties
+ * are read only and cannot be cleared or modified. See {@link #setProperty} for a
+ * list of such properties.
*
* @return the old value of the property or {@code null} if the property
* didn't exist.
*/
public static String setProperty(String name, String value) {
checkPropertyName(name);
- return (String) getProperties().setProperty(name, value);
+ return (String) systemProperties.setProperty(name, value);
}
/**
- * Removes a specific system property.
+ * Removes a specific system property. Most system properties
+ * are read only and cannot be cleared or modified. See {@link #setProperty} for a
+ * list of such properties.
*
* @return the property value or {@code null} if the property didn't exist.
* @throws NullPointerException
@@ -443,7 +918,7 @@ public final class System {
*/
public static String clearProperty(String name) {
checkPropertyName(name);
- return (String) getProperties().remove(name);
+ return (String) systemProperties.remove(name);
}
private static void checkPropertyName(String name) {
@@ -500,27 +975,14 @@ public final class System {
}
/**
- * Loads and links the dynamic library that is identified through the
- * specified path. This method is similar to {@link #loadLibrary(String)},
- * but it accepts a full path specification whereas {@code loadLibrary} just
- * accepts the name of the library to load.
- *
- * @param pathName
- * the path of the file to be loaded.
+ * See {@link Runtime#load}.
*/
public static void load(String pathName) {
Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader());
}
/**
- * Loads and links the library with the specified name. The mapping of the
- * specified library name to the full path for loading the library is
- * implementation-dependent.
- *
- * @param libName
- * the name of the library to load.
- * @throws UnsatisfiedLinkError
- * if the library could not be loaded.
+ * See {@link Runtime#loadLibrary}.
*/
public static void loadLibrary(String libName) {
Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
@@ -575,7 +1037,18 @@ public final class System {
* to perform any outstanding object finalization.
*/
public static void runFinalization() {
+ boolean shouldRunGC;
+ synchronized(lock) {
+ shouldRunGC = runGC;
+ runGC = false;
+ }
+ if (shouldRunGC) {
+ Runtime.getRuntime().gc();
+ }
Runtime.getRuntime().runFinalization();
+ synchronized(lock) {
+ justRanFinalization = true;
+ }
}
/**
@@ -594,12 +1067,21 @@ public final class System {
}
/**
- * Sets all system properties. This does not take a copy; the passed-in object is used
- * directly. Passing null causes the VM to reinitialize the properties to how they were
- * when the VM was started.
+ * Attempts to set all system properties. Copies all properties from
+ * {@code p} and discards system properties that are read only and cannot
+ * be modified. See {@link #setProperty} for a list of such properties.
*/
public static void setProperties(Properties p) {
- systemProperties = p;
+ PropertiesWithNonOverrideableDefaults userProperties =
+ new PropertiesWithNonOverrideableDefaults(unchangeableSystemProperties);
+ if (p != null) {
+ userProperties.putAll(p);
+ } else {
+ // setProperties(null) is documented to restore defaults.
+ setDefaultChangeableProperties(userProperties);
+ }
+
+ systemProperties = userProperties;
}
/**
@@ -621,25 +1103,46 @@ public final class System {
/**
* Returns the platform specific file name format for the shared library
- * named by the argument.
- *
- * @param userLibName
- * the name of the library to look up.
- * @return the platform specific filename for the library.
+ * named by the argument. On Android, this would turn {@code "MyLibrary"} into
+ * {@code "libMyLibrary.so"}.
*/
- public static native String mapLibraryName(String userLibName);
+ public static native String mapLibraryName(String nickname);
/**
- * Sets the value of the named static field in the receiver to the passed in
- * argument.
- *
- * @param fieldName
- * the name of the field to set, one of in, out, or err
- * @param stream
- * the new value of the field
+ * Used to set System.err, System.in, and System.out.
*/
- private static native void setFieldImpl(String fieldName, String signature, Object stream);
+ private static native void setFieldImpl(String field, String signature, Object stream);
+ /**
+ * A properties class that prohibits changes to any of the properties
+ * contained in its defaults.
+ */
+ static final class PropertiesWithNonOverrideableDefaults extends Properties {
+ PropertiesWithNonOverrideableDefaults(Properties defaults) {
+ super(defaults);
+ }
+
+ @Override
+ public Object put(Object key, Object value) {
+ if (defaults.containsKey(key)) {
+ logE("Ignoring attempt to set property \"" + key +
+ "\" to value \"" + value + "\".");
+ return defaults.get(key);
+ }
+
+ return super.put(key, value);
+ }
+
+ @Override
+ public Object remove(Object key) {
+ if (defaults.containsKey(key)) {
+ logE("Ignoring attempt to remove property \"" + key + "\".");
+ return null;
+ }
+
+ return super.remove(key);
+ }
+ }
/**
* The unmodifiable environment variables map. System.getenv() specifies
diff --git a/luni/src/main/java/java/lang/ref/FinalizerReference.java b/luni/src/main/java/java/lang/ref/FinalizerReference.java
index 14eaae4..5416a80 100644
--- a/luni/src/main/java/java/lang/ref/FinalizerReference.java
+++ b/luni/src/main/java/java/lang/ref/FinalizerReference.java
@@ -83,12 +83,18 @@ public final class FinalizerReference<T> extends Reference<T> {
* Waits for all currently-enqueued references to be finalized.
*/
public static void finalizeAllEnqueued() throws InterruptedException {
- Sentinel sentinel = new Sentinel();
- enqueueSentinelReference(sentinel);
+ // Alloate a new sentinel, this creates a FinalizerReference.
+ Sentinel sentinel;
+ // Keep looping until we safely enqueue our sentinel FinalizerReference.
+ // This is done to prevent races where the GC updates the pendingNext
+ // before we get the chance.
+ do {
+ sentinel = new Sentinel();
+ } while (!enqueueSentinelReference(sentinel));
sentinel.awaitFinalization();
}
- private static void enqueueSentinelReference(Sentinel sentinel) {
+ private static boolean enqueueSentinelReference(Sentinel sentinel) {
synchronized (LIST_LOCK) {
// When a finalizable object is allocated, a FinalizerReference is added to the list.
// We search the list for that FinalizerReference (it should be at or near the head),
@@ -98,8 +104,20 @@ public final class FinalizerReference<T> extends Reference<T> {
FinalizerReference<Sentinel> sentinelReference = (FinalizerReference<Sentinel>) r;
sentinelReference.referent = null;
sentinelReference.zombie = sentinel;
- sentinelReference.enqueueInternal();
- return;
+ // Make a single element list, then enqueue the reference on the daemon unenqueued
+ // list. This is required instead of enqueuing directly on the finalizer queue
+ // since there could be recently freed objects in the unqueued list which are not
+ // yet on the finalizer queue. This could cause the sentinel to run before the
+ // objects are finalized. b/17381967
+ // Make circular list if unenqueued goes through native so that we can prevent
+ // races where the GC updates the pendingNext before we do. If it is non null, then
+ // we update the pending next to make a circular list while holding a lock.
+ // b/17462553
+ if (!sentinelReference.makeCircularListIfUnenqueued()) {
+ return false;
+ }
+ ReferenceQueue.add(sentinelReference);
+ return true;
}
}
}
@@ -108,6 +126,8 @@ public final class FinalizerReference<T> extends Reference<T> {
throw new AssertionError("newly-created live Sentinel not on list!");
}
+ private native boolean makeCircularListIfUnenqueued();
+
/**
* A marker object that we can immediately enqueue. When this object's
* finalize() method is called, we know all previously-enqueued finalizable
diff --git a/luni/src/main/java/java/lang/ref/Reference.java b/luni/src/main/java/java/lang/ref/Reference.java
deleted file mode 100644
index bd63535..0000000
--- a/luni/src/main/java/java/lang/ref/Reference.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang.ref;
-
-/**
- * Provides an abstract class which describes behavior common to all reference
- * objects. It is not possible to create immediate subclasses of
- * {@code Reference} in addition to the ones provided by this package. It is
- * also not desirable to do so, since references require very close cooperation
- * with the system's garbage collector. The existing, specialized reference
- * classes should be used instead.
- *
- * <p>Three different type of references exist, each being weaker than the preceding one:
- * {@link java.lang.ref.SoftReference}, {@link java.lang.ref.WeakReference}, and
- * {@link java.lang.ref.PhantomReference}. "Weakness" here means that less restrictions are
- * being imposed on the garbage collector as to when it is allowed to
- * actually garbage-collect the referenced object.
- *
- * <p>In order to use reference objects properly it is important to understand
- * the different types of reachability that trigger their clearing and
- * enqueueing. The following table lists these, from strongest to weakest.
- * For each row, an object is said to have the reachability on the left side
- * if (and only if) it fulfills all of the requirements on the right side. In
- * all rows, consider the <em>root set</em> to be a set of references that
- * are "resistant" to garbage collection (that is, running threads, method
- * parameters, local variables, static fields and the like).
- *
- * <p><table>
- * <tr>
- * <td>Strongly reachable</td>
- * <td> <ul>
- * <li>There exists at least one path from the root set to the object that does not traverse any
- * instance of a {@code java.lang.ref.Reference} subclass.
- * </li>
- * </ul> </td>
- * </tr>
- *
- * <tr>
- * <td>Softly reachable</td>
- * <td> <ul>
- * <li>The object is not strongly reachable.</li>
- * <li>There exists at least one path from the root set to the object that does traverse
- * a {@code java.lang.ref.SoftReference} instance, but no {@code java.lang.ref.WeakReference}
- * or {@code java.lang.ref.PhantomReference} instances.</li>
- * </ul> </td>
- * </tr>
- *
- * <tr>
- * <td>Weakly reachable</td>
- * <td> <ul>
- * <li>The object is neither strongly nor softly reachable.</li>
- * <li>There exists at least one path from the root set to the object that does traverse a
- * {@code java.lang.ref.WeakReference} instance, but no {@code java.lang.ref.PhantomReference}
- * instances.</li>
- * </ul> </td>
- * </tr>
- *
- * <tr>
- * <td>Phantom-reachable</td>
- * <td> <ul>
- * <li>The object is neither strongly, softly, nor weakly reachable.</li>
- * <li>The object is referenced by a {@code java.lang.ref.PhantomReference} instance.</li>
- * <li>The object has already been finalized.</li>
- * </ul> </td>
- * </tr>
- * </table>
- */
-public abstract class Reference<T> {
-
- /**
- * The object to which this reference refers.
- * VM requirement: this field <em>must</em> be called "referent"
- * and be an object.
- */
- volatile T referent;
-
- /**
- * If non-null, the queue on which this reference will be enqueued
- * when the referent is appropriately reachable.
- * VM requirement: this field <em>must</em> be called "queue"
- * and be a java.lang.ref.ReferenceQueue.
- */
- volatile ReferenceQueue<? super T> queue;
-
- /**
- * Used internally by java.lang.ref.ReferenceQueue.
- * VM requirement: this field <em>must</em> be called "queueNext"
- * and be a java.lang.ref.Reference.
- */
- @SuppressWarnings("unchecked")
- volatile Reference queueNext;
-
- /**
- * Used internally by the VM. This field forms a circular and
- * singly linked list of reference objects discovered by the
- * garbage collector and awaiting processing by the reference
- * queue thread.
- *
- * @hide
- */
- public volatile Reference<?> pendingNext;
-
- /**
- * Constructs a new instance of this class.
- */
- Reference() {
- }
-
- Reference(T r, ReferenceQueue<? super T> q) {
- referent = r;
- queue = q;
- }
-
- /**
- * Makes the referent {@code null}. This does not force the reference
- * object to be enqueued.
- */
- public void clear() {
- referent = null;
- }
-
- /**
- * Adds an object to its reference queue.
- *
- * @return {@code true} if this call has caused the {@code Reference} to
- * become enqueued, or {@code false} otherwise
- *
- * @hide
- */
- public final synchronized boolean enqueueInternal() {
- if (queue != null && queueNext == null) {
- queue.enqueue(this);
- queue = null;
- return true;
- }
- return false;
- }
-
- /**
- * Forces the reference object to be enqueued if it has been associated with
- * a queue.
- *
- * @return {@code true} if this call has caused the {@code Reference} to
- * become enqueued, or {@code false} otherwise
- */
- public boolean enqueue() {
- return enqueueInternal();
- }
-
- /**
- * Returns the referent of the reference object.
- *
- * @return the referent to which reference refers, or {@code null} if the
- * object has been cleared.
- */
- public T get() {
- return referent;
- }
-
- /**
- * Checks whether the reference object has been enqueued.
- *
- * @return {@code true} if the {@code Reference} has been enqueued, {@code
- * false} otherwise
- */
- public boolean isEnqueued() {
- return queueNext != null;
- }
-
-}
diff --git a/luni/src/main/java/java/lang/ref/ReferenceQueue.java b/luni/src/main/java/java/lang/ref/ReferenceQueue.java
index 2b8089c..4c78fbf 100644
--- a/luni/src/main/java/java/lang/ref/ReferenceQueue.java
+++ b/luni/src/main/java/java/lang/ref/ReferenceQueue.java
@@ -28,6 +28,7 @@ public class ReferenceQueue<T> {
private static final int NANOS_PER_MILLI = 1000000;
private Reference<? extends T> head;
+ private Reference<? extends T> tail;
/**
* Constructs a new instance of this class.
@@ -48,18 +49,16 @@ public class ReferenceQueue<T> {
return null;
}
- Reference<? extends T> ret;
+ Reference<? extends T> ret = head;
- ret = head;
-
- if (head == head.queueNext) {
+ if (head == tail) {
+ tail = null;
head = null;
} else {
head = head.queueNext;
}
ret.queueNext = null;
-
return ret;
}
@@ -133,12 +132,16 @@ public class ReferenceQueue<T> {
* reference object to be enqueued.
*/
synchronized void enqueue(Reference<? extends T> reference) {
- if (head == null) {
- reference.queueNext = reference;
+ if (tail == null) {
+ head = reference;
} else {
- reference.queueNext = head;
+ tail.queueNext = reference;
}
- head = reference;
+
+ // The newly enqueued reference becomes the new tail, and always
+ // points to itself.
+ tail = reference;
+ tail.queueNext = reference;
notify();
}
@@ -150,9 +153,18 @@ public class ReferenceQueue<T> {
if (unenqueued == null) {
unenqueued = list;
} else {
- Reference<?> next = unenqueued.pendingNext;
- unenqueued.pendingNext = list.pendingNext;
- list.pendingNext = next;
+ // Find the last element in unenqueued.
+ Reference<?> last = unenqueued;
+ while (last.pendingNext != unenqueued) {
+ last = last.pendingNext;
+ }
+ // Add our list to the end. Update the pendingNext to point back to enqueued.
+ last.pendingNext = list;
+ last = list;
+ while (last.pendingNext != list) {
+ last = last.pendingNext;
+ }
+ last.pendingNext = unenqueued;
}
ReferenceQueue.class.notifyAll();
}
diff --git a/luni/src/main/java/java/lang/reflect/Array.java b/luni/src/main/java/java/lang/reflect/Array.java
index 088a434..a7dacfe 100644
--- a/luni/src/main/java/java/lang/reflect/Array.java
+++ b/luni/src/main/java/java/lang/reflect/Array.java
@@ -352,16 +352,16 @@ public final class Array {
public static Object newInstance(Class<?> componentType, int size) throws NegativeArraySizeException {
if (!componentType.isPrimitive()) {
return createObjectArray(componentType, size);
- } else if (componentType == boolean.class) {
- return new boolean[size];
- } else if (componentType == byte.class) {
- return new byte[size];
} else if (componentType == char.class) {
return new char[size];
- } else if (componentType == short.class) {
- return new short[size];
} else if (componentType == int.class) {
return new int[size];
+ } else if (componentType == byte.class) {
+ return new byte[size];
+ } else if (componentType == boolean.class) {
+ return new boolean[size];
+ } else if (componentType == short.class) {
+ return new short[size];
} else if (componentType == long.class) {
return new long[size];
} else if (componentType == float.class) {
diff --git a/luni/src/main/java/java/lang/reflect/Modifier.java b/luni/src/main/java/java/lang/reflect/Modifier.java
index 5f973d5..257064e 100644
--- a/luni/src/main/java/java/lang/reflect/Modifier.java
+++ b/luni/src/main/java/java/lang/reflect/Modifier.java
@@ -106,7 +106,7 @@ public class Modifier {
* require they implement.
* @hide
*/
- public static final int MIRANDA = 0x8000;
+ public static final int MIRANDA = 0x200000;
/**
* Dex addition to mark instance constructors and static class
diff --git a/luni/src/main/java/java/math/BigDecimal.java b/luni/src/main/java/java/math/BigDecimal.java
index 03ce8dd..f735607 100644
--- a/luni/src/main/java/java/math/BigDecimal.java
+++ b/luni/src/main/java/java/math/BigDecimal.java
@@ -1025,6 +1025,14 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>, Serial
}
long diffScale = ((long)this.scale - divisor.scale) - scale;
+
+ // Check whether the diffScale will fit into an int. See http://b/17393664.
+ if (bitLength(diffScale) > 32) {
+ throw new ArithmeticException(
+ "Unable to perform divisor / dividend scaling: the difference in scale is too" +
+ " big (" + diffScale + ")");
+ }
+
if(this.bitLength < 64 && divisor.bitLength < 64 ) {
if(diffScale == 0) {
return dividePrimitiveLongs(this.smallValue,
diff --git a/luni/src/main/java/java/math/Multiplication.java b/luni/src/main/java/java/math/Multiplication.java
index 98cabee..093b1b7 100644
--- a/luni/src/main/java/java/math/Multiplication.java
+++ b/luni/src/main/java/java/math/Multiplication.java
@@ -125,49 +125,45 @@ class Multiplication {
} else if (exp <= 50) {
// To calculate: 10^exp
return BigInteger.TEN.pow(intExp);
- } else if (exp <= 1000) {
- // To calculate: 5^exp * 2^exp
- return bigFivePows[1].pow(intExp).shiftLeft(intExp);
}
- // "LARGE POWERS"
- /*
- * To check if there is free memory to allocate a BigInteger of the
- * estimated size, measured in bytes: 1 + [exp / log10(2)]
- */
- long byteArraySize = 1 + (long)(exp / 2.4082399653118496);
-
- if (byteArraySize > Runtime.getRuntime().freeMemory()) {
- throw new ArithmeticException();
- }
- if (exp <= Integer.MAX_VALUE) {
- // To calculate: 5^exp * 2^exp
- return bigFivePows[1].pow(intExp).shiftLeft(intExp);
- }
- /*
- * "HUGE POWERS"
- *
- * This branch probably won't be executed since the power of ten is too
- * big.
- */
- // To calculate: 5^exp
- BigInteger powerOfFive = bigFivePows[1].pow(Integer.MAX_VALUE);
- BigInteger res = powerOfFive;
- long longExp = exp - Integer.MAX_VALUE;
-
- intExp = (int)(exp % Integer.MAX_VALUE);
- while (longExp > Integer.MAX_VALUE) {
- res = res.multiply(powerOfFive);
- longExp -= Integer.MAX_VALUE;
- }
- res = res.multiply(bigFivePows[1].pow(intExp));
- // To calculate: 5^exp << exp
- res = res.shiftLeft(Integer.MAX_VALUE);
- longExp = exp - Integer.MAX_VALUE;
- while (longExp > Integer.MAX_VALUE) {
- res = res.shiftLeft(Integer.MAX_VALUE);
- longExp -= Integer.MAX_VALUE;
+
+ BigInteger res = null;
+ try {
+ // "LARGE POWERS"
+ if (exp <= Integer.MAX_VALUE) {
+ // To calculate: 5^exp * 2^exp
+ res = bigFivePows[1].pow(intExp).shiftLeft(intExp);
+ } else {
+ /*
+ * "HUGE POWERS"
+ *
+ * This branch probably won't be executed since the power of ten is too
+ * big.
+ */
+ // To calculate: 5^exp
+ BigInteger powerOfFive = bigFivePows[1].pow(Integer.MAX_VALUE);
+ res = powerOfFive;
+ long longExp = exp - Integer.MAX_VALUE;
+
+ intExp = (int) (exp % Integer.MAX_VALUE);
+ while (longExp > Integer.MAX_VALUE) {
+ res = res.multiply(powerOfFive);
+ longExp -= Integer.MAX_VALUE;
+ }
+ res = res.multiply(bigFivePows[1].pow(intExp));
+ // To calculate: 5^exp << exp
+ res = res.shiftLeft(Integer.MAX_VALUE);
+ longExp = exp - Integer.MAX_VALUE;
+ while (longExp > Integer.MAX_VALUE) {
+ res = res.shiftLeft(Integer.MAX_VALUE);
+ longExp -= Integer.MAX_VALUE;
+ }
+ res = res.shiftLeft(intExp);
+ }
+ } catch (OutOfMemoryError error) {
+ throw new ArithmeticException(error.getMessage());
}
- res = res.shiftLeft(intExp);
+
return res;
}
diff --git a/luni/src/main/java/java/net/AddressCache.java b/luni/src/main/java/java/net/AddressCache.java
index 194761a..2aba78b 100644
--- a/luni/src/main/java/java/net/AddressCache.java
+++ b/luni/src/main/java/java/net/AddressCache.java
@@ -37,8 +37,36 @@ class AddressCache {
private static final long TTL_NANOS = 2 * 1000000000L;
// The actual cache.
- private final BasicLruCache<String, AddressCacheEntry> cache
- = new BasicLruCache<String, AddressCacheEntry>(MAX_ENTRIES);
+ private final BasicLruCache<AddressCacheKey, AddressCacheEntry> cache
+ = new BasicLruCache<AddressCacheKey, AddressCacheEntry>(MAX_ENTRIES);
+
+ static class AddressCacheKey {
+ private final String mHostname;
+ private final int mNetId;
+
+ AddressCacheKey(String hostname, int netId) {
+ mHostname = hostname;
+ mNetId = netId;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof AddressCacheKey)) {
+ return false;
+ }
+ AddressCacheKey lhs = (AddressCacheKey) o;
+ return mHostname.equals(lhs.mHostname) && mNetId == lhs.mNetId;
+ }
+
+ @Override public int hashCode() {
+ int result = 17;
+ result = 31 * result + mNetId;
+ result = 31 * result + mHostname.hashCode();
+ return result;
+ }
+ }
static class AddressCacheEntry {
// Either an InetAddress[] for a positive entry,
@@ -67,12 +95,12 @@ class AddressCache {
}
/**
- * Returns the cached InetAddress[] associated with 'hostname'. Returns null if nothing is known
- * about 'hostname'. Returns a String suitable for use as an UnknownHostException detail
- * message if 'hostname' is known not to exist.
+ * Returns the cached InetAddress[] for 'hostname' on network 'netId'. Returns null
+ * if nothing is known about 'hostname'. Returns a String suitable for use as an
+ * UnknownHostException detail message if 'hostname' is known not to exist.
*/
- public Object get(String hostname) {
- AddressCacheEntry entry = cache.get(hostname);
+ public Object get(String hostname, int netId) {
+ AddressCacheEntry entry = cache.get(new AddressCacheKey(hostname, netId));
// Do we have a valid cache entry?
if (entry != null && entry.expiryNanos >= System.nanoTime()) {
return entry.value;
@@ -86,15 +114,15 @@ class AddressCache {
* Associates the given 'addresses' with 'hostname'. The association will expire after a
* certain length of time.
*/
- public void put(String hostname, InetAddress[] addresses) {
- cache.put(hostname, new AddressCacheEntry(addresses));
+ public void put(String hostname, int netId, InetAddress[] addresses) {
+ cache.put(new AddressCacheKey(hostname, netId), new AddressCacheEntry(addresses));
}
/**
* Records that 'hostname' is known not to have any associated addresses. (I.e. insert a
* negative cache entry.)
*/
- public void putUnknownHost(String hostname, String detailMessage) {
- cache.put(hostname, new AddressCacheEntry(detailMessage));
+ public void putUnknownHost(String hostname, int netId, String detailMessage) {
+ cache.put(new AddressCacheKey(hostname, netId), new AddressCacheEntry(detailMessage));
}
}
diff --git a/luni/src/main/java/java/net/DatagramSocket.java b/luni/src/main/java/java/net/DatagramSocket.java
index 49f141a..f9b72d8 100644
--- a/luni/src/main/java/java/net/DatagramSocket.java
+++ b/luni/src/main/java/java/net/DatagramSocket.java
@@ -17,14 +17,14 @@
package java.net;
+import android.system.ErrnoException;
import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.channels.DatagramChannel;
-import libcore.io.ErrnoException;
import libcore.io.IoBridge;
import libcore.io.Libcore;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* This class implements a UDP socket for sending and receiving {@code
@@ -114,6 +114,17 @@ public class DatagramSocket implements Closeable {
}
/**
+ * Sets the DatagramSocket and its related DatagramSocketImpl state as if a successful close()
+ * took place, without actually performing an OS close().
+ *
+ * @hide used in java.nio
+ */
+ public void onClose() {
+ isClosed = true;
+ impl.onClose();
+ }
+
+ /**
* Disconnects this UDP datagram socket from the remote host. This method
* called on an unconnected socket does nothing.
*/
@@ -127,6 +138,19 @@ public class DatagramSocket implements Closeable {
isConnected = false;
}
+ /**
+ * Sets the DatagramSocket and its related DatagramSocketImpl state as if a successful
+ * disconnect() took place, without actually performing a disconnect().
+ *
+ * @hide used in java.nio
+ */
+ public void onDisconnect() {
+ address = null;
+ port = -1;
+ isConnected = false;
+ impl.onDisconnect();
+ }
+
synchronized void createSocket(int aPort, InetAddress addr) throws SocketException {
impl = factory != null ? factory.createDatagramSocketImpl()
: new PlainDatagramSocketImpl();
@@ -152,8 +176,8 @@ public class DatagramSocket implements Closeable {
}
/**
- * Returns the local address to which this socket is bound,
- * or {@code null} if this socket is closed.
+ * Returns the local address to which this socket is bound, a wildcard address if this
+ * socket is not yet bound, or {@code null} if this socket is closed.
*/
public InetAddress getLocalAddress() {
try {
@@ -439,9 +463,12 @@ public class DatagramSocket implements Closeable {
*/
public void bind(SocketAddress localAddr) throws SocketException {
checkOpen();
- int localPort = 0;
- InetAddress addr = Inet4Address.ANY;
- if (localAddr != null) {
+ int localPort;
+ InetAddress addr;
+ if (localAddr == null) {
+ localPort = 0;
+ addr = Inet4Address.ANY;
+ } else {
if (!(localAddr instanceof InetSocketAddress)) {
throw new IllegalArgumentException("Local address not an InetSocketAddress: " +
localAddr.getClass());
@@ -459,6 +486,17 @@ public class DatagramSocket implements Closeable {
}
/**
+ * Sets the DatagramSocket and its related DatagramSocketImpl state as if a successful bind()
+ * took place, without actually performing an OS bind().
+ *
+ * @hide used in java.nio
+ */
+ public void onBind(InetAddress localAddress, int localPort) {
+ isBound = true;
+ impl.onBind(localAddress, localPort);
+ }
+
+ /**
* Connects this datagram socket to the address and port specified by {@code peer}.
* Future calls to {@link #send} will use this as the default target, and {@link #receive}
* will only accept packets from this source.
@@ -492,6 +530,19 @@ public class DatagramSocket implements Closeable {
}
/**
+ * Sets the DatagramSocket and its related DatagramSocketImpl state as if a successful connect()
+ * took place, without actually performing an OS connect().
+ *
+ * @hide used in java.nio
+ */
+ public void onConnect(InetAddress remoteAddress, int remotePort) {
+ isConnected = true;
+ this.address = remoteAddress;
+ this.port = remotePort;
+ impl.onConnect(remoteAddress, remotePort);
+ }
+
+ /**
* Connects this datagram socket to the specific {@code address} and {@code port}.
* Future calls to {@link #send} will use this as the default target, and {@link #receive}
* will only accept packets from this source.
@@ -537,10 +588,11 @@ public class DatagramSocket implements Closeable {
}
/**
- * Returns the {@code SocketAddress} this socket is bound to, or null for an unbound socket.
+ * Returns the {@code SocketAddress} this socket is bound to, or {@code null} for an unbound or
+ * closed socket.
*/
public SocketAddress getLocalSocketAddress() {
- if (!isBound()) {
+ if (isClosed() || !isBound()) {
return null;
}
return new InetSocketAddress(getLocalAddress(), getLocalPort());
diff --git a/luni/src/main/java/java/net/DatagramSocketImpl.java b/luni/src/main/java/java/net/DatagramSocketImpl.java
index 097eb17..1a39987 100644
--- a/luni/src/main/java/java/net/DatagramSocketImpl.java
+++ b/luni/src/main/java/java/net/DatagramSocketImpl.java
@@ -268,4 +268,40 @@ public abstract class DatagramSocketImpl implements SocketOptions {
* if an error occurs while peeking at the data.
*/
protected abstract int peekData(DatagramPacket pack) throws IOException;
+
+ /**
+ * Initialize the bind() state.
+ * @hide used in java.nio.
+ */
+ protected void onBind(InetAddress localAddress, int localPort) {
+ // Do not add any code to these methods. They are concrete only to preserve API
+ // compatibility.
+ }
+
+ /**
+ * Initialize the connect() state.
+ * @hide used in java.nio.
+ */
+ protected void onConnect(InetAddress remoteAddress, int remotePort) {
+ // Do not add any code to these methods. They are concrete only to preserve API
+ // compatibility.
+ }
+
+ /**
+ * Initialize the disconnected state.
+ * @hide used in java.nio.
+ */
+ protected void onDisconnect() {
+ // Do not add any code to these methods. They are concrete only to preserve API
+ // compatibility.
+ }
+
+ /**
+ * Initialize the closed state.
+ * @hide used in java.nio.
+ */
+ protected void onClose() {
+ // Do not add any code to these methods. They are concrete only to preserve API
+ // compatibility.
+ }
}
diff --git a/luni/src/main/java/java/net/HttpCookie.java b/luni/src/main/java/java/net/HttpCookie.java
index ce1a8d2..dd81fd6 100644
--- a/luni/src/main/java/java/net/HttpCookie.java
+++ b/luni/src/main/java/java/net/HttpCookie.java
@@ -53,10 +53,12 @@ import libcore.util.Objects;
* in this format is {@code 1}.
* </ul>
*
- * <p>This implementation silently discards unrecognized attributes. In
- * particular, the {@code HttpOnly} attribute is widely served but isn't in any
- * of the above specs. It was introduced by Internet Explorer to prevent server
- * cookies from being exposed in the DOM to JavaScript, etc.
+ * <p>Support for the "HttpOnly" attribute specified in
+ * <a href="http://tools.ietf.org/html/rfc6265">RFC 6265</a> is also included. RFC 6265 is intended
+ * to obsolete RFC 2965. Support for features from RFC 2965 that have been deprecated by RFC 6265
+ * such as Cookie2, Set-Cookie2 headers and version information remain supported by this class.
+ *
+ * <p>This implementation silently discards unrecognized attributes.
*
* @since 1.6
*/
@@ -65,16 +67,17 @@ public final class HttpCookie implements Cloneable {
private static final Set<String> RESERVED_NAMES = new HashSet<String>();
static {
- RESERVED_NAMES.add("comment"); // RFC 2109 RFC 2965
- RESERVED_NAMES.add("commenturl"); // RFC 2965
- RESERVED_NAMES.add("discard"); // RFC 2965
- RESERVED_NAMES.add("domain"); // Netscape RFC 2109 RFC 2965
+ RESERVED_NAMES.add("comment"); // RFC 2109 RFC 2965 RFC 6265
+ RESERVED_NAMES.add("commenturl"); // RFC 2965 RFC 6265
+ RESERVED_NAMES.add("discard"); // RFC 2965 RFC 6265
+ RESERVED_NAMES.add("domain"); // Netscape RFC 2109 RFC 2965 RFC 6265
RESERVED_NAMES.add("expires"); // Netscape
- RESERVED_NAMES.add("max-age"); // RFC 2109 RFC 2965
- RESERVED_NAMES.add("path"); // Netscape RFC 2109 RFC 2965
- RESERVED_NAMES.add("port"); // RFC 2965
- RESERVED_NAMES.add("secure"); // Netscape RFC 2109 RFC 2965
- RESERVED_NAMES.add("version"); // RFC 2109 RFC 2965
+ RESERVED_NAMES.add("httponly"); // RFC 6265
+ RESERVED_NAMES.add("max-age"); // RFC 2109 RFC 2965 RFC 6265
+ RESERVED_NAMES.add("path"); // Netscape RFC 2109 RFC 2965 RFC 6265
+ RESERVED_NAMES.add("port"); // RFC 2965 RFC 6265
+ RESERVED_NAMES.add("secure"); // Netscape RFC 2109 RFC 2965 RFC 6265
+ RESERVED_NAMES.add("version"); // RFC 2109 RFC 2965 RFC 6265
}
/**
@@ -332,14 +335,26 @@ public final class HttpCookie implements Cloneable {
}
}
} else if (name.equals("max-age") && cookie.maxAge == -1L) {
- hasMaxAge = true;
- cookie.maxAge = Long.parseLong(value);
+ // RFCs 2109 and 2965 suggests a zero max-age as a way of deleting a cookie.
+ // RFC 6265 specifies the value must be > 0 but also describes what to do if the
+ // value is negative, zero or non-numeric in section 5.2.2. The RI does none of this
+ // and accepts negative, positive values and throws an IllegalArgumentException
+ // if the value is non-numeric.
+ try {
+ long maxAge = Long.parseLong(value);
+ hasMaxAge = true;
+ cookie.maxAge = maxAge;
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid max-age: " + value);
+ }
} else if (name.equals("path") && cookie.path == null) {
cookie.path = value;
} else if (name.equals("port") && cookie.portList == null) {
cookie.portList = value != null ? value : "";
} else if (name.equals("secure")) {
cookie.secure = true;
+ } else if (name.equals("httponly")) {
+ cookie.httpOnly = true;
} else if (name.equals("version") && !hasVersion) {
cookie.version = Integer.parseInt(value);
}
@@ -430,6 +445,7 @@ public final class HttpCookie implements Cloneable {
private String path;
private String portList;
private boolean secure;
+ private boolean httpOnly;
private String value;
private int version = 1;
@@ -698,7 +714,21 @@ public final class HttpCookie implements Cloneable {
/**
* Returns a string representing this cookie in the format used by the
- * {@code Cookie} header line in an HTTP request.
+ * {@code Cookie} header line in an HTTP request as specified by RFC 2965 section 3.3.4.
+ *
+ * <p>The resulting string does not include a "Cookie:" prefix or any version information.
+ * The returned {@code String} is not suitable for passing to {@link #parse(String)}: Several of
+ * the attributes that would be needed to preserve all of the cookie's information are omitted.
+ * The String is formatted for an HTTP request not an HTTP response.
+ *
+ * <p>The attributes included and the format depends on the cookie's {@code version}:
+ * <ul>
+ * <li>Version 0: Includes only the name and value. Conforms to RFC 2965 (for
+ * version 0 cookies). This should also be used to conform with RFC 6265.
+ * </li>
+ * <li>Version 1: Includes the name and value, and Path, Domain and Port attributes.
+ * Conforms to RFC 2965 (for version 1 cookies).</li>
+ * </ul>
*/
@Override public String toString() {
if (version == 0) {
diff --git a/luni/src/main/java/java/net/HttpURLConnection.java b/luni/src/main/java/java/net/HttpURLConnection.java
index 89a4bc4..4e5b4ee 100644
--- a/luni/src/main/java/java/net/HttpURLConnection.java
+++ b/luni/src/main/java/java/net/HttpURLConnection.java
@@ -784,11 +784,15 @@ public abstract class HttpURLConnection extends URLConnection {
* only servers may not support this mode.
*
* <p>When HTTP chunked encoding is used, the stream is divided into
- * chunks, each prefixed with a header containing the chunk's size. Setting
- * a large chunk length requires a large internal buffer, potentially
- * wasting memory. Setting a small chunk length increases the number of
+ * chunks, each prefixed with a header containing the chunk's size.
+ * A large chunk length requires a large internal buffer, potentially
+ * wasting memory. A small chunk length increases the number of
* bytes that must be transmitted because of the header on every chunk.
- * Most caller should use {@code 0} to get the system default.
+ *
+ * <p>Implementation details: In some releases the {@code chunkLength} is
+ * treated as a hint: chunks sent to the server may actually be larger or
+ * smaller. To force a chunk to be sent to the server call
+ * {@link java.io.OutputStream#flush()}.
*
* @see #setFixedLengthStreamingMode
* @param chunkLength the length to use, or {@code 0} for the default chunk
diff --git a/luni/src/main/java/java/net/Inet4Address.java b/luni/src/main/java/java/net/Inet4Address.java
index 7c26639..f0b1b5b 100644
--- a/luni/src/main/java/java/net/Inet4Address.java
+++ b/luni/src/main/java/java/net/Inet4Address.java
@@ -20,7 +20,7 @@ package java.net;
import java.io.ObjectStreamException;
import java.nio.ByteOrder;
import libcore.io.Memory;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* An IPv4 address. See {@link InetAddress}.
diff --git a/luni/src/main/java/java/net/Inet6Address.java b/luni/src/main/java/java/net/Inet6Address.java
index 37e9c18..8ab0f8d 100644
--- a/luni/src/main/java/java/net/Inet6Address.java
+++ b/luni/src/main/java/java/net/Inet6Address.java
@@ -23,7 +23,7 @@ import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.util.Arrays;
import java.util.Enumeration;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* An IPv6 address. See {@link InetAddress}.
diff --git a/luni/src/main/java/java/net/InetAddress.java b/luni/src/main/java/java/net/InetAddress.java
index 98ad098..5cfa15a 100644
--- a/luni/src/main/java/java/net/InetAddress.java
+++ b/luni/src/main/java/java/net/InetAddress.java
@@ -17,6 +17,9 @@
package java.net;
+import android.system.ErrnoException;
+import android.system.GaiException;
+import android.system.StructAddrinfo;
import dalvik.system.BlockGuard;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -28,18 +31,13 @@ import java.io.Serializable;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
-import libcore.io.ErrnoException;
-import libcore.io.GaiException;
+import java.util.concurrent.CountDownLatch;
+import java.util.List;
import libcore.io.IoBridge;
import libcore.io.Libcore;
import libcore.io.Memory;
-import libcore.io.StructAddrinfo;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* An Internet Protocol (IP) address. This can be either an IPv4 address or an IPv6 address, and
@@ -129,6 +127,9 @@ public class InetAddress implements Serializable {
private static final long serialVersionUID = 3286316764910316507L;
+ /** Using NetID of NETID_UNSET indicates resolution should be done on default network. */
+ private static final int NETID_UNSET = 0;
+
private int family;
byte[] ipaddress;
@@ -211,14 +212,29 @@ public class InetAddress implements Serializable {
* @throws UnknownHostException if the address lookup fails.
*/
public static InetAddress[] getAllByName(String host) throws UnknownHostException {
- return getAllByNameImpl(host).clone();
+ return getAllByNameImpl(host, NETID_UNSET).clone();
}
/**
- * Returns the InetAddresses for {@code host}. The returned array is shared
- * and must be cloned before it is returned to application code.
+ * Operates identically to {@code getAllByName} except host resolution is
+ * performed on the network designated by {@code netId}.
+ *
+ * @param host the hostname or literal IP string to be resolved.
+ * @param netId the network to use for host resolution.
+ * @return the array of addresses associated with the specified host.
+ * @throws UnknownHostException if the address lookup fails.
+ * @hide internal use only
*/
- private static InetAddress[] getAllByNameImpl(String host) throws UnknownHostException {
+ public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
+ return getAllByNameImpl(host, netId).clone();
+ }
+
+ /**
+ * Returns the InetAddresses for {@code host} on network {@code netId}. The
+ * returned array is shared and must be cloned before it is returned to
+ * application code.
+ */
+ private static InetAddress[] getAllByNameImpl(String host, int netId) throws UnknownHostException {
if (host == null || host.isEmpty()) {
return loopbackAddresses();
}
@@ -233,7 +249,7 @@ public class InetAddress implements Serializable {
return new InetAddress[] { result };
}
- return lookupHostByName(host).clone();
+ return lookupHostByName(host, netId).clone();
}
private static InetAddress makeInetAddress(byte[] bytes, String hostName) throws UnknownHostException {
@@ -266,7 +282,7 @@ public class InetAddress implements Serializable {
hints.ai_flags = AI_NUMERICHOST;
InetAddress[] addresses = null;
try {
- addresses = Libcore.os.getaddrinfo(address, hints);
+ addresses = Libcore.os.android_getaddrinfo(address, hints, NETID_UNSET);
} catch (GaiException ignored) {
}
return (addresses != null) ? addresses[0] : null;
@@ -286,7 +302,22 @@ public class InetAddress implements Serializable {
* if the address lookup fails.
*/
public static InetAddress getByName(String host) throws UnknownHostException {
- return getAllByNameImpl(host)[0];
+ return getAllByNameImpl(host, NETID_UNSET)[0];
+ }
+
+ /**
+ * Operates identically to {@code getByName} except host resolution is
+ * performed on the network designated by {@code netId}.
+ *
+ * @param host
+ * the hostName to be resolved to an address or {@code null}.
+ * @param netId the network to use for host resolution.
+ * @return the {@code InetAddress} instance representing the host.
+ * @throws UnknownHostException if the address lookup fails.
+ * @hide internal use only
+ */
+ public static InetAddress getByNameOnNet(String host, int netId) throws UnknownHostException {
+ return getAllByNameImpl(host, netId)[0];
}
/**
@@ -362,7 +393,7 @@ public class InetAddress implements Serializable {
*/
public static InetAddress getLocalHost() throws UnknownHostException {
String host = Libcore.os.uname().nodename;
- return lookupHostByName(host)[0];
+ return lookupHostByName(host, NETID_UNSET)[0];
}
/**
@@ -379,12 +410,14 @@ public class InetAddress implements Serializable {
* Resolves a hostname to its IP addresses using a cache.
*
* @param host the hostname to resolve.
+ * @param netId the network to perform resolution upon.
* @return the IP addresses of the host.
*/
- private static InetAddress[] lookupHostByName(String host) throws UnknownHostException {
+ private static InetAddress[] lookupHostByName(String host, int netId)
+ throws UnknownHostException {
BlockGuard.getThreadPolicy().onNetwork();
// Do we have a result cached?
- Object cachedResult = addressCache.get(host);
+ Object cachedResult = addressCache.get(host, netId);
if (cachedResult != null) {
if (cachedResult instanceof InetAddress[]) {
// A cached positive result.
@@ -402,12 +435,12 @@ public class InetAddress implements Serializable {
// for SOCK_STREAM and one for SOCK_DGRAM. Since we do not return the family
// anyway, just pick one.
hints.ai_socktype = SOCK_STREAM;
- InetAddress[] addresses = Libcore.os.getaddrinfo(host, hints);
+ InetAddress[] addresses = Libcore.os.android_getaddrinfo(host, hints, netId);
// TODO: should getaddrinfo set the hostname of the InetAddresses it returns?
for (InetAddress address : addresses) {
address.hostName = host;
}
- addressCache.put(host, addresses);
+ addressCache.put(host, netId, addresses);
return addresses;
} catch (GaiException gaiException) {
// If the failure appears to have been a lack of INTERNET permission, throw a clear
@@ -420,7 +453,7 @@ public class InetAddress implements Serializable {
}
// Otherwise, throw an UnknownHostException.
String detailMessage = "Unable to resolve host \"" + host + "\": " + Libcore.os.gai_strerror(gaiException.error);
- addressCache.putUnknownHost(host, detailMessage);
+ addressCache.putUnknownHost(host, netId, detailMessage);
throw gaiException.rethrowAsUnknownHostException(detailMessage);
}
}
@@ -734,7 +767,7 @@ public class InetAddress implements Serializable {
}
}
- IoBridge.closeSocket(fd);
+ IoBridge.closeAndSignalBlockedThreads(fd);
return reached;
}
diff --git a/luni/src/main/java/java/net/InetUnixAddress.java b/luni/src/main/java/java/net/InetUnixAddress.java
index 44b9cba..51236e2 100644
--- a/luni/src/main/java/java/net/InetUnixAddress.java
+++ b/luni/src/main/java/java/net/InetUnixAddress.java
@@ -18,7 +18,7 @@ package java.net;
import java.nio.charset.StandardCharsets;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* An AF_UNIX address. See {@link InetAddress}.
diff --git a/luni/src/main/java/java/net/JarURLConnection.java b/luni/src/main/java/java/net/JarURLConnection.java
index 4b84893..e5c8fac 100644
--- a/luni/src/main/java/java/net/JarURLConnection.java
+++ b/luni/src/main/java/java/net/JarURLConnection.java
@@ -18,11 +18,13 @@
package java.net;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.security.cert.Certificate;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
+import libcore.net.UriCodec;
/**
* This class establishes a connection to a {@code jar:} URL using the {@code
@@ -64,12 +66,13 @@ public abstract class JarURLConnection extends URLConnection {
*/
protected JarURLConnection(URL url) throws MalformedURLException {
super(url);
- file = url.getFile();
+ file = decode(url.getFile());
+
int sepIdx;
if ((sepIdx = file.indexOf("!/")) < 0) {
throw new MalformedURLException();
}
- fileURL = new URL(url.getFile().substring(0,sepIdx));
+ fileURL = new URL(file.substring(0, sepIdx));
sepIdx += 2;
if (file.length() == sepIdx) {
return;
@@ -189,4 +192,17 @@ public abstract class JarURLConnection extends URLConnection {
Manifest m = getJarFile().getManifest();
return (m == null) ? null : m.getMainAttributes();
}
+
+ private static String decode(String encoded) throws MalformedURLException {
+ try {
+ // "+" means "+" in URLs. i.e. like RFC 3986, not like
+ // MIME application/x-www-form-urlencoded
+ final boolean convertPlus = false;
+ return UriCodec.decode(
+ encoded, convertPlus, StandardCharsets.UTF_8, true /* throwOnFailure */);
+ } catch (IllegalArgumentException e) {
+ throw new MalformedURLException("Unable to decode URL", e);
+ }
+ }
+
}
diff --git a/luni/src/main/java/java/net/MulticastSocket.java b/luni/src/main/java/java/net/MulticastSocket.java
index 6f4a582..24e66c5 100644
--- a/luni/src/main/java/java/net/MulticastSocket.java
+++ b/luni/src/main/java/java/net/MulticastSocket.java
@@ -229,6 +229,9 @@ public class MulticastSocket extends DatagramSocket {
private void checkJoinOrLeave(InetAddress groupAddr) throws IOException {
checkOpen();
+ if (groupAddr == null) {
+ throw new IllegalArgumentException("groupAddress == null");
+ }
if (!groupAddr.isMulticastAddress()) {
throw new IOException("Not a multicast group: " + groupAddr);
}
@@ -351,7 +354,8 @@ public class MulticastSocket extends DatagramSocket {
/**
* Disables multicast loopback if {@code disable == true}.
* See {@link SocketOptions#IP_MULTICAST_LOOP}, and note that the sense of this is the
- * opposite of the underlying Unix {@code IP_MULTICAST_LOOP}.
+ * opposite of the underlying Unix {@code IP_MULTICAST_LOOP}: true means disabled, false
+ * means enabled.
*
* @throws SocketException if an error occurs.
*/
diff --git a/luni/src/main/java/java/net/NetworkInterface.java b/luni/src/main/java/java/net/NetworkInterface.java
index 3128b98..852c09b 100644
--- a/luni/src/main/java/java/net/NetworkInterface.java
+++ b/luni/src/main/java/java/net/NetworkInterface.java
@@ -17,6 +17,7 @@
package java.net;
+import android.system.ErrnoException;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -26,10 +27,9 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* This class is used to represent a network interface of the local device. An
diff --git a/luni/src/main/java/java/net/PlainDatagramSocketImpl.java b/luni/src/main/java/java/net/PlainDatagramSocketImpl.java
index 3226527..eb0c99d 100644
--- a/luni/src/main/java/java/net/PlainDatagramSocketImpl.java
+++ b/luni/src/main/java/java/net/PlainDatagramSocketImpl.java
@@ -17,23 +17,15 @@
package java.net;
+import android.system.ErrnoException;
+import android.system.StructGroupReq;
import dalvik.system.CloseGuard;
import java.io.FileDescriptor;
import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocketImpl;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import libcore.io.ErrnoException;
import libcore.io.IoBridge;
import libcore.io.Libcore;
-import libcore.io.StructGroupReq;
import libcore.util.EmptyArray;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* @hide used in java.nio.
@@ -78,15 +70,25 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl {
}
@Override
+ protected void onBind(InetAddress localAddress, int localPort) {
+ this.localPort = localPort;
+ }
+
+ @Override
public synchronized void close() {
guard.close();
try {
- IoBridge.closeSocket(fd);
+ IoBridge.closeAndSignalBlockedThreads(fd);
} catch (IOException ignored) {
}
}
@Override
+ protected void onClose() {
+ guard.close();
+ }
+
+ @Override
public void create() throws SocketException {
this.fd = IoBridge.socket(false);
}
@@ -179,7 +181,8 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl {
public void send(DatagramPacket packet) throws IOException {
int port = isNativeConnected ? 0 : packet.getPort();
InetAddress address = isNativeConnected ? null : packet.getAddress();
- IoBridge.sendto(fd, packet.getData(), packet.getOffset(), packet.getLength(), 0, address, port);
+ IoBridge.sendto(fd, packet.getData(), packet.getOffset(), packet.getLength(), 0, address,
+ port);
}
public void setOption(int option, Object value) throws SocketException {
@@ -211,6 +214,13 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl {
}
@Override
+ protected void onConnect(InetAddress remoteAddress, int remotePort) {
+ isNativeConnected = true;
+ connectedAddress = remoteAddress;
+ connectedPort = remotePort;
+ }
+
+ @Override
public void disconnect() {
try {
Libcore.os.connect(fd, InetAddress.UNSPECIFIED, 0);
@@ -224,6 +234,13 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl {
isNativeConnected = false;
}
+ @Override
+ protected void onDisconnect() {
+ connectedPort = -1;
+ connectedAddress = null;
+ isNativeConnected = false;
+ }
+
/**
* Set the received address and port in the packet. We do this when the
* Datagram socket is connected at the native level and the
diff --git a/luni/src/main/java/java/net/PlainSocketImpl.java b/luni/src/main/java/java/net/PlainSocketImpl.java
index 18942d6..4e5ba44 100644
--- a/luni/src/main/java/java/net/PlainSocketImpl.java
+++ b/luni/src/main/java/java/net/PlainSocketImpl.java
@@ -17,28 +17,19 @@
package java.net;
+import android.system.ErrnoException;
import dalvik.system.CloseGuard;
import java.io.FileDescriptor;
-import java.io.IOException;
import java.io.InputStream;
+import java.io.IOException;
import java.io.OutputStream;
-import java.net.ConnectException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.SocketImpl;
-import java.net.SocketTimeoutException;
-import java.net.UnknownHostException;
import java.nio.ByteOrder;
import java.util.Arrays;
-import libcore.io.ErrnoException;
import libcore.io.IoBridge;
import libcore.io.Libcore;
import libcore.io.Memory;
import libcore.io.Streams;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* @hide used in java.nio.
@@ -120,15 +111,6 @@ public class PlainSocketImpl extends SocketImpl {
return proxy != null && proxy.type() == Proxy.Type.SOCKS;
}
- public void initLocalPort(int localPort) {
- this.localport = localPort;
- }
-
- public void initRemoteAddressAndPort(InetAddress remoteAddress, int remotePort) {
- this.address = remoteAddress;
- this.port = remotePort;
- }
-
private void checkNotClosed() throws IOException {
if (!fd.valid()) {
throw new SocketException("Socket is closed");
@@ -148,7 +130,6 @@ public class PlainSocketImpl extends SocketImpl {
@Override protected void bind(InetAddress address, int port) throws IOException {
IoBridge.bind(fd, address, port);
- this.address = address;
if (port != 0) {
this.localport = port;
} else {
@@ -157,9 +138,19 @@ public class PlainSocketImpl extends SocketImpl {
}
@Override
+ public void onBind(InetAddress localAddress, int localPort) {
+ localport = localPort;
+ }
+
+ @Override
protected synchronized void close() throws IOException {
guard.close();
- IoBridge.closeSocket(fd);
+ IoBridge.closeAndSignalBlockedThreads(fd);
+ }
+
+ @Override
+ public void onClose() {
+ guard.close();
}
@Override
@@ -191,8 +182,14 @@ public class PlainSocketImpl extends SocketImpl {
} else {
IoBridge.connect(fd, normalAddr, aPort, timeout);
}
- super.address = normalAddr;
- super.port = aPort;
+ address = normalAddr;
+ port = aPort;
+ }
+
+ @Override
+ public void onConnect(InetAddress remoteAddress, int remotePort) {
+ address = remoteAddress;
+ port = remotePort;
}
@Override
diff --git a/luni/src/main/java/java/net/ServerSocket.java b/luni/src/main/java/java/net/ServerSocket.java
index 399511f..72b197f 100644
--- a/luni/src/main/java/java/net/ServerSocket.java
+++ b/luni/src/main/java/java/net/ServerSocket.java
@@ -21,6 +21,8 @@ import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.ServerSocketChannel;
+import libcore.io.IoBridge;
+
/**
* This class represents a server-side socket that waits for incoming client
* connections. A {@code ServerSocket} handles the requests and sends back an
@@ -49,6 +51,8 @@ public class ServerSocket implements Closeable {
private boolean isClosed;
+ private InetAddress localAddress;
+
/**
* Constructs a new unbound {@code ServerSocket}.
*
@@ -99,7 +103,7 @@ public class ServerSocket implements Closeable {
impl.create(true);
try {
impl.bind(addr, port);
- isBound = true;
+ readBackBindState();
impl.listen(backlog > 0 ? backlog : DEFAULT_BACKLOG);
} catch (IOException e) {
close();
@@ -109,6 +113,14 @@ public class ServerSocket implements Closeable {
}
/**
+ * Read the cached isBound and localAddress state from the underlying OS socket.
+ */
+ private void readBackBindState() throws SocketException {
+ localAddress = IoBridge.getSocketLocalAddress(impl.fd);
+ isBound = true;
+ }
+
+ /**
* Waits for an incoming request and blocks until the connection is opened.
* This method returns a socket object representing the just opened
* connection.
@@ -152,8 +164,8 @@ public class ServerSocket implements Closeable {
}
/**
- * Gets the local IP address of this server socket or {@code null} if the
- * socket is unbound. This is useful for multihomed hosts.
+ * Gets the local IP address of this server socket if this socket has ever been bound,
+ * {@code null} otherwise. This is useful for multihomed hosts.
*
* @return the local address of this server socket.
*/
@@ -161,12 +173,13 @@ public class ServerSocket implements Closeable {
if (!isBound()) {
return null;
}
- return impl.getInetAddress();
+ return localAddress;
}
/**
- * Gets the local port of this server socket or {@code -1} if the socket is
- * unbound.
+ * Gets the local port of this server socket or {@code -1} if the socket is not bound.
+ * If the socket has ever been bound this method will return the local port it was bound to,
+ * even after it has been closed.
*
* @return the local port this server is listening on.
*/
@@ -300,9 +313,12 @@ public class ServerSocket implements Closeable {
if (isBound()) {
throw new BindException("Socket is already bound");
}
- int port = 0;
- InetAddress addr = Inet4Address.ANY;
- if (localAddr != null) {
+ InetAddress addr;
+ int port;
+ if (localAddr == null) {
+ addr = Inet4Address.ANY;
+ port = 0;
+ } else {
if (!(localAddr instanceof InetSocketAddress)) {
throw new IllegalArgumentException("Local address not an InetSocketAddress: " +
localAddr.getClass());
@@ -317,7 +333,7 @@ public class ServerSocket implements Closeable {
synchronized (this) {
try {
impl.bind(addr, port);
- isBound = true;
+ readBackBindState();
impl.listen(backlog > 0 ? backlog : DEFAULT_BACKLOG);
} catch (IOException e) {
close();
@@ -327,8 +343,9 @@ public class ServerSocket implements Closeable {
}
/**
- * Gets the local socket address of this server socket or {@code null} if
- * the socket is unbound. This is useful on multihomed hosts.
+ * Gets the local socket address of this server socket or {@code null} if the socket is unbound.
+ * This is useful on multihomed hosts. If the socket has ever been bound this method will return
+ * the local address it was bound to, even after it has been closed.
*
* @return the local socket address and port this socket is bound to.
*/
@@ -336,7 +353,7 @@ public class ServerSocket implements Closeable {
if (!isBound()) {
return null;
}
- return new InetSocketAddress(getInetAddress(), getLocalPort());
+ return new InetSocketAddress(localAddress, getLocalPort());
}
/**
diff --git a/luni/src/main/java/java/net/Socket.java b/luni/src/main/java/java/net/Socket.java
index 36fdf28..5dd350a 100644
--- a/luni/src/main/java/java/net/Socket.java
+++ b/luni/src/main/java/java/net/Socket.java
@@ -312,12 +312,29 @@ public class Socket implements Closeable {
*/
public synchronized void close() throws IOException {
isClosed = true;
- // RI compatibility: the RI returns the any address (but the original local port) after close.
+ isConnected = false;
+ // RI compatibility: the RI returns the any address (but the original local port) after
+ // close.
localAddress = Inet4Address.ANY;
impl.close();
}
/**
+ * Sets the Socket and its related SocketImpl state as if a successful close() took place,
+ * without actually performing an OS close().
+ *
+ * @hide used in java.nio
+ */
+ public void onClose() {
+ isClosed = true;
+ isConnected = false;
+ // RI compatibility: the RI returns the any address (but the original local port) after
+ // close.
+ localAddress = Inet4Address.ANY;
+ impl.onClose();
+ }
+
+ /**
* Returns the IP address of the target host this socket is connected to, or null if this
* socket is not yet connected.
*/
@@ -329,7 +346,9 @@ public class Socket implements Closeable {
}
/**
- * Returns an input stream to read data from this socket.
+ * Returns an input stream to read data from this socket. If the socket has an associated
+ * {@link SocketChannel} and that channel is in non-blocking mode then reads from the
+ * stream will throw a {@link java.nio.channels.IllegalBlockingModeException}.
*
* @return the byte-oriented input stream.
* @throws IOException
@@ -353,15 +372,16 @@ public class Socket implements Closeable {
}
/**
- * Returns the local IP address this socket is bound to, or {@code InetAddress.ANY} if
- * the socket is unbound.
+ * Returns the local IP address this socket is bound to, or an address for which
+ * {@link InetAddress#isAnyLocalAddress()} returns true if the socket is closed or unbound.
*/
public InetAddress getLocalAddress() {
return localAddress;
}
/**
- * Returns the local port this socket is bound to, or -1 if the socket is unbound.
+ * Returns the local port this socket is bound to, or -1 if the socket is unbound. If the socket
+ * has been closed this method will still return the local port the socket was bound to.
*/
public int getLocalPort() {
if (!isBound()) {
@@ -371,7 +391,9 @@ public class Socket implements Closeable {
}
/**
- * Returns an output stream to write data into this socket.
+ * Returns an output stream to write data into this socket. If the socket has an associated
+ * {@link SocketChannel} and that channel is in non-blocking mode then writes to the
+ * stream will throw a {@link java.nio.channels.IllegalBlockingModeException}.
*
* @return the byte-oriented output stream.
* @throws IOException
@@ -564,6 +586,7 @@ public class Socket implements Closeable {
impl.bind(addr, localPort);
}
isBound = true;
+ cacheLocalAddress();
impl.connect(dstAddress, dstPort);
isConnected = true;
cacheLocalAddress();
@@ -672,9 +695,10 @@ public class Socket implements Closeable {
}
/**
- * Returns the local address and port of this socket as a SocketAddress or
- * null if the socket is unbound. This is useful on multihomed
- * hosts.
+ * Returns the local address and port of this socket as a SocketAddress or null if the socket
+ * has never been bound. If the socket is closed but has previously been bound then an address
+ * for which {@link InetAddress#isAnyLocalAddress()} returns true will be returned with the
+ * previously-bound port. This is useful on multihomed hosts.
*/
public SocketAddress getLocalSocketAddress() {
if (!isBound()) {
@@ -744,9 +768,12 @@ public class Socket implements Closeable {
throw new BindException("Socket is already bound");
}
- int port = 0;
- InetAddress addr = Inet4Address.ANY;
- if (localAddr != null) {
+ int port;
+ InetAddress addr;
+ if (localAddr == null) {
+ port = 0;
+ addr = Inet4Address.ANY;
+ } else {
if (!(localAddr instanceof InetSocketAddress)) {
throw new IllegalArgumentException("Local address not an InetSocketAddress: " +
localAddr.getClass());
@@ -771,6 +798,18 @@ public class Socket implements Closeable {
}
/**
+ * Sets the Socket and its related SocketImpl state as if a successful bind() took place,
+ * without actually performing an OS bind().
+ *
+ * @hide used in java.nio
+ */
+ public void onBind(InetAddress localAddress, int localPort) {
+ isBound = true;
+ this.localAddress = localAddress;
+ impl.onBind(localAddress, localPort);
+ }
+
+ /**
* Connects this socket to the given remote host address and port specified
* by the SocketAddress {@code remoteAddr}.
*
@@ -851,6 +890,17 @@ public class Socket implements Closeable {
}
/**
+ * Sets the Socket and its related SocketImpl state as if a successful connect() took place,
+ * without actually performing an OS connect().
+ *
+ * @hide internal use only
+ */
+ public void onConnect(InetAddress remoteAddress, int remotePort) {
+ isConnected = true;
+ impl.onConnect(remoteAddress, remotePort);
+ }
+
+ /**
* Returns whether the incoming channel of the socket has already been
* closed.
*
diff --git a/luni/src/main/java/java/net/SocketImpl.java b/luni/src/main/java/java/net/SocketImpl.java
index 92de9cf..bd36ec7 100644
--- a/luni/src/main/java/java/net/SocketImpl.java
+++ b/luni/src/main/java/java/net/SocketImpl.java
@@ -294,4 +294,31 @@ public abstract class SocketImpl implements SocketOptions {
*/
protected void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
}
+
+ /**
+ * Initialize the bind() state.
+ * @hide used in java.nio.
+ */
+ public void onBind(InetAddress localAddress, int localPort) {
+ // Do not add any code to these methods. They are concrete only to preserve API
+ // compatibility.
+ }
+
+ /**
+ * Initialize the connect() state.
+ * @hide used in java.nio.
+ */
+ public void onConnect(InetAddress remoteAddress, int remotePort) {
+ // Do not add any code to these methods. They are concrete only to preserve API
+ // compatibility.
+ }
+
+ /**
+ * Initialize the close() state.
+ * @hide used in java.nio.
+ */
+ public void onClose() {
+ // Do not add any code to these methods. They are concrete only to preserve API
+ // compatibility.
+ }
}
diff --git a/luni/src/main/java/java/net/SocketOptions.java b/luni/src/main/java/java/net/SocketOptions.java
index e23fc97..d0df689 100644
--- a/luni/src/main/java/java/net/SocketOptions.java
+++ b/luni/src/main/java/java/net/SocketOptions.java
@@ -28,19 +28,27 @@ package java.net;
*/
public interface SocketOptions {
/**
- * Number of seconds to wait when closing a socket if there
- * is still some buffered data to be sent.
+ * Number of seconds to wait when closing a socket if there is still some buffered data to be
+ * sent.
*
- * <p>If this option is set to 0, the TCP socket is closed forcefully and the
- * call to {@code close} returns immediately.
+ * <p>The option can be set to disabled using {@link #setOption(int, Object)} with a value of
+ * {@code Boolean.FALSE}.
*
- * <p>If this option is set to a value greater than 0, the value is interpreted
- * as the number of seconds to wait. If all data could be sent
- * during this time, the socket is closed normally. Otherwise the connection will be
- * closed forcefully.
+ * <p>If this option is set to 0, the TCP socket is closed forcefully and the call to
+ * {@code close} returns immediately.
*
- * <p>Valid values for this option are in the range 0 to 65535 inclusive. (Larger
+ * If this option is disabled, closing a socket will return immediately and the close will be
+ * handled in the background.
+ *
+ * <p>If this option is set to a value greater than 0, the value is interpreted as the number of
+ * seconds to wait. If all data could be sent during this time, the socket is closed normally.
+ * Otherwise the connection will be closed forcefully.
+ *
+ * <p>Valid numeric values for this option are in the range 0 to 65535 inclusive. (Larger
* timeouts will be treated as 65535s timeouts; roughly 18 hours.)
+ *
+ * <p>This option is intended for use with sockets in blocking mode. The behavior of this option
+ * for non-blocking sockets is undefined.
*/
public static final int SO_LINGER = 128;
@@ -54,16 +62,21 @@ public interface SocketOptions {
public static final int SO_TIMEOUT = 4102;
/**
- * This boolean option specifies whether data is sent immediately on this socket.
- * As a side-effect this could lead to low packet efficiency. The
- * socket implementation uses the Nagle's algorithm to try to reach a higher
- * packet efficiency if this option is disabled.
+ * This boolean option specifies whether data is sent immediately on this socket or buffered.
+ * <p>
+ * If set to {@code Boolean.TRUE} the Nagle algorithm is disabled and there is no buffering.
+ * This could lead to low packet efficiency. When set to {@code Boolean.FALSE} the the socket
+ * implementation uses buffering to try to reach a higher packet efficiency.
+ *
+ * <p>See <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122: Requirements for Internet
+ * Hosts -- Communication Layers</a> for more information about buffering and the Nagle
+ * algorithm.
*/
public static final int TCP_NODELAY = 1;
/**
* This is an IPv4-only socket option whose functionality is subsumed by
- * {@link #IP_MULTICAST_IF} and not implemented on Android.
+ * {@link #IP_MULTICAST_IF2} and not implemented on Android.
*/
public static final int IP_MULTICAST_IF = 16;
@@ -73,9 +86,18 @@ public interface SocketOptions {
public static final int SO_BINDADDR = 15;
/**
- * This boolean option specifies whether a reuse of a local address is allowed even
- * if another socket is not yet removed by the operating system. It's only
- * available on a {@code MulticastSocket}.
+ * This boolean option specifies whether a reuse of a local address is allowed when another
+ * socket has not yet been removed by the operating system.
+ *
+ * <p>For connection-oriented sockets, if this option is disabled and if there is another socket
+ * in state TIME_WAIT on a given address then another socket binding to that address would fail.
+ * Setting this value after a socket is bound has no effect.
+ *
+ * <p>For datagram sockets this option determines whether several sockets can listen on the
+ * same address; when enabled each socket will receive a copy of the datagram.
+ *
+ * <p>See <a href="https://www.ietf.org/rfc/rfc793.txt">RFC 793: Transmission Control Protocol
+ * </a> for more information about socket re-use.
*/
public static final int SO_REUSEADDR = 4;
@@ -93,11 +115,18 @@ public interface SocketOptions {
* This is a hint to the kernel; the kernel may use a larger buffer.
*
* <p>For datagram sockets, packets larger than this value will be discarded.
+ *
+ * <p>See <a href="http://www.ietf.org/rfc/rfc1323.txt">RFC1323: TCP Extensions for High
+ * Performance</a> for more information about TCP/IP buffering.
*/
public static final int SO_RCVBUF = 4098;
/**
- * This boolean option specifies whether the kernel sends keepalive messages.
+ * This boolean option specifies whether the kernel sends keepalive messages on
+ * connection-oriented sockets.
+ *
+ * <p>See <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122: Requirements for Internet
+ * Hosts -- Communication Layers</a> for more information on keep-alive.
*/
public static final int SO_KEEPALIVE = 8;
@@ -114,15 +143,18 @@ public interface SocketOptions {
/**
* This boolean option specifies whether the local loopback of multicast packets is
- * enabled or disabled. This option is enabled by default on multicast
- * sockets. Note that the sense of this option in Java is the
- * <i>opposite</i> of the underlying Unix {@code IP_MULTICAST_LOOP}.
- * See {@link MulticastSocket#setLoopbackMode}.
+ * enabled or disabled. This loopback is enabled by default on multicast sockets.
+ *
+ * <p>See <a href="http://tools.ietf.org/rfc/rfc1112.txt">RFC 1112: Host Extensions for IP
+ * Multicasting</a> for more information about IP multicast.
+ *
+ * <p>See {@link MulticastSocket#setLoopbackMode}.
*/
public static final int IP_MULTICAST_LOOP = 18;
/**
- * This boolean option can be used to enable broadcasting on datagram sockets.
+ * This boolean option can be used to enable or disable broadcasting on datagram sockets. This
+ * option must be enabled to send broadcast messages. The default value is false.
*/
public static final int SO_BROADCAST = 32;
@@ -135,6 +167,9 @@ public interface SocketOptions {
/**
* This integer option sets the outgoing interface for multicast packets
* using an interface index.
+ *
+ * <p>See <a href="http://tools.ietf.org/rfc/rfc1112.txt">RFC 1112: Host Extensions for IP
+ * Multicasting</a> for more information about IP multicast.
*/
public static final int IP_MULTICAST_IF2 = 31;
diff --git a/luni/src/main/java/java/net/URI.java b/luni/src/main/java/java/net/URI.java
index 6b7b1da..f206473 100644
--- a/luni/src/main/java/java/net/URI.java
+++ b/luni/src/main/java/java/net/URI.java
@@ -461,11 +461,14 @@ public final class URI implements Comparable<URI>, Serializable {
if (index < (temp.length() - 1)) { // port part is not empty
try {
- tempPort = Integer.parseInt(temp.substring(index + 1));
- if (tempPort < 0) {
+ char firstPortChar = temp.charAt(index + 1);
+ if (firstPortChar >= '0' && firstPortChar <= '9') {
+ // allow only digits, no signs
+ tempPort = Integer.parseInt(temp.substring(index + 1));
+ } else {
if (forceServer) {
throw new URISyntaxException(authority,
- "Invalid port number", hostIndex + index + 1);
+ "Invalid port number", hostIndex + index + 1);
}
return;
}
@@ -766,33 +769,51 @@ public final class URI implements Comparable<URI>, Serializable {
}
/**
- * Returns true if {@code first} and {@code second} are equal after
- * unescaping hex sequences like %F1 and %2b.
+ * Returns true if the given URI escaped strings {@code first} and {@code second} are
+ * equal.
+ *
+ * TODO: This method assumes that both strings are escaped using the same escape rules
+ * yet it still performs case insensitive comparison of the escaped sequences.
+ * Why is this necessary ? We can just replace it with first.equals(second)
+ * otherwise.
*/
private boolean escapedEquals(String first, String second) {
- if (first.indexOf('%') != second.indexOf('%')) {
- return first.equals(second);
+ // This length test isn't a micro-optimization. We need it because we sometimes
+ // calculate the number of characters to match based on the length of the second
+ // string. If the second string is shorter than the first, we might attempt to match
+ // 0 chars, and regionMatches is specified to return true in that case.
+ if (first.length() != second.length()) {
+ return false;
}
- int index, prevIndex = 0;
- while ((index = first.indexOf('%', prevIndex)) != -1
- && second.indexOf('%', prevIndex) == index) {
- boolean match = first.substring(prevIndex, index).equals(
- second.substring(prevIndex, index));
- if (!match) {
+ int prevIndex = 0;
+ while (true) {
+ int index = first.indexOf('%', prevIndex);
+ int index1 = second.indexOf('%', prevIndex);
+ if (index != index1) {
+ return false;
+ }
+
+ // index == index1 from this point on.
+
+ if (index == -1) {
+ // No more escapes, match the remainder of the string
+ // normally.
+ return first.regionMatches(prevIndex, second, prevIndex,
+ second.length() - prevIndex);
+ }
+
+ if (!first.regionMatches(prevIndex, second, prevIndex, (index - prevIndex))) {
return false;
}
- match = first.substring(index + 1, index + 3).equalsIgnoreCase(
- second.substring(index + 1, index + 3));
- if (!match) {
+ if (!first.regionMatches(true /* ignore case */, index + 1, second, index + 1, 2)) {
return false;
}
index += 3;
prevIndex = index;
}
- return first.substring(prevIndex).equals(second.substring(prevIndex));
}
@Override public boolean equals(Object o) {
diff --git a/luni/src/main/java/java/net/URLConnection.java b/luni/src/main/java/java/net/URLConnection.java
index 74c15ce..2fb3f45 100644
--- a/luni/src/main/java/java/net/URLConnection.java
+++ b/luni/src/main/java/java/net/URLConnection.java
@@ -308,9 +308,8 @@ public abstract class URLConnection {
/**
* Returns the content length in bytes specified by the response header field
- * {@code content-length} or {@code -1} if this field is not set.
- *
- * @return the value of the response header field {@code content-length}.
+ * {@code content-length} or {@code -1} if this field is not set or cannot be represented as an
+ * {@code int}.
*/
public int getContentLength() {
return getHeaderFieldInt("Content-Length", -1);
@@ -531,7 +530,7 @@ public abstract class URLConnection {
/**
* Returns the specified header value as a number. Returns the {@code
* defaultValue} if no such header field could be found or the value could
- * not be parsed as an {@code Integer}.
+ * not be parsed as an {@code int}.
*
* @param field
* the header field name whose value is needed.
diff --git a/luni/src/main/java/java/net/URLStreamHandler.java b/luni/src/main/java/java/net/URLStreamHandler.java
index 8a6c264..d21bb9c 100644
--- a/luni/src/main/java/java/net/URLStreamHandler.java
+++ b/luni/src/main/java/java/net/URLStreamHandler.java
@@ -131,9 +131,11 @@ public abstract class URLStreamHandler {
host = spec.substring(hostStart, hostEnd);
int portStart = hostEnd + 1;
if (portStart < fileStart) {
- port = Integer.parseInt(spec.substring(portStart, fileStart));
- if (port < 0) {
- throw new IllegalArgumentException("port < 0: " + port);
+ char firstPortChar = spec.charAt(portStart);
+ if (firstPortChar >= '0' && firstPortChar <= '9') {
+ port = Integer.parseInt(spec.substring(portStart, fileStart));
+ } else {
+ throw new IllegalArgumentException("invalid port: " + port);
}
}
path = null;
diff --git a/luni/src/main/java/java/nio/Buffer.java b/luni/src/main/java/java/nio/Buffer.java
index 9b7be52..53ad171 100644
--- a/luni/src/main/java/java/nio/Buffer.java
+++ b/luni/src/main/java/java/nio/Buffer.java
@@ -85,22 +85,16 @@ public abstract class Buffer {
/**
* For direct buffers, the effective address of the data; zero otherwise.
* This is set in the constructor.
- * TODO: make this final at the cost of loads of extra constructors? [how many?]
*/
- long effectiveDirectAddress;
+ final long effectiveDirectAddress;
- /**
- * For direct buffers, the underlying MemoryBlock; null otherwise.
- */
- final MemoryBlock block;
-
- Buffer(int elementSizeShift, int capacity, MemoryBlock block) {
+ Buffer(int elementSizeShift, int capacity, long effectiveDirectAddress) {
this._elementSizeShift = elementSizeShift;
if (capacity < 0) {
throw new IllegalArgumentException("capacity < 0: " + capacity);
}
this.capacity = this.limit = capacity;
- this.block = block;
+ this.effectiveDirectAddress = effectiveDirectAddress;
}
/**
@@ -296,7 +290,7 @@ public abstract class Buffer {
* the new limit, must not be negative and not greater than
* capacity.
* @return this buffer.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if <code>newLimit</code> is invalid.
*/
public final Buffer limit(int newLimit) {
@@ -344,7 +338,7 @@ public abstract class Buffer {
* the new position, must be not negative and not greater than
* limit.
* @return this buffer.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if <code>newPosition</code> is invalid.
*/
public final Buffer position(int newPosition) {
@@ -377,7 +371,7 @@ public abstract class Buffer {
* Resets the position of this buffer to the <code>mark</code>.
*
* @return this buffer.
- * @exception InvalidMarkException
+ * @throws InvalidMarkException
* if the mark is not set.
*/
public final Buffer reset() {
@@ -409,4 +403,9 @@ public abstract class Buffer {
return getClass().getName() +
"[position=" + position + ",limit=" + limit + ",capacity=" + capacity + "]";
}
+
+ /** @hide for testing only */
+ public final int getElementSizeShift() {
+ return _elementSizeShift;
+ }
}
diff --git a/luni/src/main/java/java/nio/ByteArrayBuffer.java b/luni/src/main/java/java/nio/ByteArrayBuffer.java
index e8d7ecc..6a273ed 100644
--- a/luni/src/main/java/java/nio/ByteArrayBuffer.java
+++ b/luni/src/main/java/java/nio/ByteArrayBuffer.java
@@ -38,7 +38,7 @@ final class ByteArrayBuffer extends ByteBuffer {
}
private ByteArrayBuffer(int capacity, byte[] backingArray, int arrayOffset, boolean isReadOnly) {
- super(capacity, null);
+ super(capacity, 0);
this.backingArray = backingArray;
this.arrayOffset = arrayOffset;
this.isReadOnly = isReadOnly;
diff --git a/luni/src/main/java/java/nio/ByteBuffer.java b/luni/src/main/java/java/nio/ByteBuffer.java
index 456a309..61093fa 100644
--- a/luni/src/main/java/java/nio/ByteBuffer.java
+++ b/luni/src/main/java/java/nio/ByteBuffer.java
@@ -69,7 +69,11 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
if (capacity < 0) {
throw new IllegalArgumentException("capacity < 0: " + capacity);
}
- return new DirectByteBuffer(MemoryBlock.allocate(capacity), capacity, 0, false, null);
+ // Ensure alignment by 8.
+ MemoryBlock memoryBlock = MemoryBlock.allocate(capacity + 7);
+ long address = memoryBlock.toLong();
+ long alignedAddress = (address + 7) & ~(long)7;
+ return new DirectByteBuffer(memoryBlock, capacity, (int)(alignedAddress - address), false, null);
}
/**
@@ -101,7 +105,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the length, must not be negative and not greater than
* {@code array.length - start}.
* @return the created byte buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code byteCount} is invalid.
*/
public static ByteBuffer wrap(byte[] array, int start, int byteCount) {
@@ -112,17 +116,17 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
return buf;
}
- ByteBuffer(int capacity, MemoryBlock block) {
- super(0, capacity, block);
+ ByteBuffer(int capacity, long effectiveDirectAddress) {
+ super(0, capacity, effectiveDirectAddress);
}
/**
* Returns the byte array which this buffer is based on, if there is one.
*
* @return the byte array which this buffer is based on.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if this buffer is based on a read-only array.
- * @exception UnsupportedOperationException
+ * @throws UnsupportedOperationException
* if this buffer is not based on an array.
*/
@Override public final byte[] array() {
@@ -137,9 +141,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* position of the buffer.
*
* @return the offset of the byte array which this buffer is based on.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if this buffer is based on a read-only array.
- * @exception UnsupportedOperationException
+ * @throws UnsupportedOperationException
* if this buffer is not based on an array.
*/
@Override public final int arrayOffset() {
@@ -260,7 +264,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* cleared.
*
* @return {@code this}
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer compact();
@@ -274,7 +278,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @return a negative value if this is less than {@code other}; 0 if this
* equals to {@code other}; a positive value if this is greater
* than {@code other}.
- * @exception ClassCastException
+ * @throws ClassCastException
* if {@code other} is not a byte buffer.
*/
@Override public int compareTo(ByteBuffer otherBuffer) {
@@ -350,7 +354,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* Returns the byte at the current position and increases the position by 1.
*
* @return the byte at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is equal or greater than limit.
*/
public abstract byte get();
@@ -365,7 +369,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param dst
* the destination byte array.
* @return {@code this}
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code dst.length} is greater than {@code remaining()}.
*/
public ByteBuffer get(byte[] dst) {
@@ -386,8 +390,8 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the number of bytes to read, must not be negative and not
* greater than {@code dst.length - dstOffset}
* @return {@code this}
- * @exception IndexOutOfBoundsException if {@code dstOffset < 0 || byteCount < 0}
- * @exception BufferUnderflowException if {@code byteCount > remaining()}
+ * @throws IndexOutOfBoundsException if {@code dstOffset < 0 || byteCount < 0}
+ * @throws BufferUnderflowException if {@code byteCount > remaining()}
*/
public ByteBuffer get(byte[] dst, int dstOffset, int byteCount) {
Arrays.checkOffsetAndCount(dst.length, dstOffset, byteCount);
@@ -406,7 +410,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param index
* the index, must not be negative and less than limit.
* @return the byte at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
*/
public abstract byte get(int index);
@@ -418,7 +422,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* according to the current byte order and returned.
*
* @return the char at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is greater than {@code limit - 2}.
*/
public abstract char getChar();
@@ -434,7 +438,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the index, must not be negative and equal or less than
* {@code limit - 2}.
* @return the char at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
*/
public abstract char getChar(int index);
@@ -447,7 +451,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* according to the current byte order and returned.
*
* @return the double at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is greater than {@code limit - 8}.
*/
public abstract double getDouble();
@@ -463,7 +467,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the index, must not be negative and equal or less than
* {@code limit - 8}.
* @return the double at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
*/
public abstract double getDouble(int index);
@@ -476,7 +480,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* according to the current byte order and returned.
*
* @return the float at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is greater than {@code limit - 4}.
*/
public abstract float getFloat();
@@ -492,7 +496,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the index, must not be negative and equal or less than
* {@code limit - 4}.
* @return the float at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
*/
public abstract float getFloat(int index);
@@ -504,7 +508,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* according to the current byte order and returned.
*
* @return the int at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is greater than {@code limit - 4}.
*/
public abstract int getInt();
@@ -520,7 +524,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the index, must not be negative and equal or less than
* {@code limit - 4}.
* @return the int at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
*/
public abstract int getInt(int index);
@@ -532,7 +536,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* according to the current byte order and returned.
*
* @return the long at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is greater than {@code limit - 8}.
*/
public abstract long getLong();
@@ -548,7 +552,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the index, must not be negative and equal or less than
* {@code limit - 8}.
* @return the long at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
*/
public abstract long getLong(int index);
@@ -560,7 +564,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* according to the current byte order and returned.
*
* @return the short at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is greater than {@code limit - 2}.
*/
public abstract short getShort();
@@ -576,7 +580,7 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the index, must not be negative and equal or less than
* {@code limit - 2}.
* @return the short at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
*/
public abstract short getShort(int index);
@@ -609,6 +613,30 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
@Override public abstract boolean isDirect();
/**
+ * Indicates whether this buffer is still accessible.
+ *
+ * @return {@code true} if this buffer is accessible, {@code false} if the
+ * buffer was made inaccessible (e.g. freed) and should not be used.
+ * @hide
+ */
+ public boolean isAccessible() {
+ return true;
+ }
+
+ /**
+ * Sets buffer accessibility (only supported for direct byte buffers). If
+ * {@code accessible} is {@code false}, {@link #isAccessible} will return
+ * false, and any attempt to access the buffer will throw an exception. If
+ * {@code true}, the buffer will become useable again, unless it has been
+ * freed.
+ *
+ * @hide
+ */
+ public void setAccessible(boolean accessible) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Returns the byte order used by this buffer when converting bytes from/to
* other primitive types.
* <p>
@@ -667,9 +695,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param b
* the byte to write.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is equal or greater than limit.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer put(byte b);
@@ -684,9 +712,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param src
* the source byte array.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code src.length}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public final ByteBuffer put(byte[] src) {
@@ -707,11 +735,11 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* the number of bytes to write, must not be negative and not
* greater than {@code src.length - srcOffset}.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code byteCount}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code srcOffset} or {@code byteCount} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public ByteBuffer put(byte[] src, int srcOffset, int byteCount) {
@@ -733,21 +761,27 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param src
* the source byte buffer.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code src.remaining()} is greater than this buffer's
* {@code remaining()}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code src} is this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public ByteBuffer put(ByteBuffer src) {
+ if (!isAccessible()) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
if (isReadOnly()) {
throw new ReadOnlyBufferException();
}
if (src == this) {
throw new IllegalArgumentException("src == this");
}
+ if (!src.isAccessible()) {
+ throw new IllegalStateException("src buffer is inaccessible");
+ }
int srcByteCount = src.remaining();
if (srcByteCount > remaining()) {
throw new BufferOverflowException();
@@ -782,9 +816,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param b
* the byte to write.
* @return {@code this}
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer put(int index, byte b);
@@ -798,9 +832,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the char to write.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is greater than {@code limit - 2}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putChar(char value);
@@ -817,9 +851,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the char to write.
* @return {@code this}
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putChar(int index, char value);
@@ -833,9 +867,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the double to write.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is greater than {@code limit - 8}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putDouble(double value);
@@ -852,9 +886,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the double to write.
* @return {@code this}
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putDouble(int index, double value);
@@ -868,9 +902,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the float to write.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is greater than {@code limit - 4}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putFloat(float value);
@@ -887,9 +921,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the float to write.
* @return {@code this}
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putFloat(int index, float value);
@@ -903,9 +937,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the int to write.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is greater than {@code limit - 4}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putInt(int value);
@@ -922,9 +956,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the int to write.
* @return {@code this}
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putInt(int index, int value);
@@ -938,9 +972,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the long to write.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is greater than {@code limit - 8}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putLong(long value);
@@ -957,9 +991,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the long to write.
* @return {@code this}
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putLong(int index, long value);
@@ -973,9 +1007,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the short to write.
* @return {@code this}
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is greater than {@code limit - 2}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putShort(short value);
@@ -992,9 +1026,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer
* @param value
* the short to write.
* @return {@code this}
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if {@code index} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ByteBuffer putShort(int index, short value);
diff --git a/luni/src/main/java/java/nio/ByteBufferAsCharBuffer.java b/luni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
index 16d0688..9d06cce 100644
--- a/luni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
+++ b/luni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
@@ -42,10 +42,9 @@ final class ByteBufferAsCharBuffer extends CharBuffer {
}
private ByteBufferAsCharBuffer(ByteBuffer byteBuffer) {
- super(byteBuffer.capacity() / SizeOf.CHAR);
+ super(byteBuffer.capacity() / SizeOf.CHAR, byteBuffer.effectiveDirectAddress);
this.byteBuffer = byteBuffer;
this.byteBuffer.clear();
- this.effectiveDirectAddress = byteBuffer.effectiveDirectAddress;
}
@Override
diff --git a/luni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java b/luni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
index 044bf59..8271daf 100644
--- a/luni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
+++ b/luni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
@@ -42,10 +42,9 @@ final class ByteBufferAsDoubleBuffer extends DoubleBuffer {
}
private ByteBufferAsDoubleBuffer(ByteBuffer byteBuffer) {
- super(byteBuffer.capacity() / SizeOf.DOUBLE);
+ super(byteBuffer.capacity() / SizeOf.DOUBLE, byteBuffer.effectiveDirectAddress);
this.byteBuffer = byteBuffer;
this.byteBuffer.clear();
- this.effectiveDirectAddress = byteBuffer.effectiveDirectAddress;
}
@Override
diff --git a/luni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java b/luni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
index a67affe..eaf2b8f 100644
--- a/luni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
+++ b/luni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
@@ -41,10 +41,9 @@ final class ByteBufferAsFloatBuffer extends FloatBuffer {
}
ByteBufferAsFloatBuffer(ByteBuffer byteBuffer) {
- super(byteBuffer.capacity() / SizeOf.FLOAT);
+ super(byteBuffer.capacity() / SizeOf.FLOAT, byteBuffer.effectiveDirectAddress);
this.byteBuffer = byteBuffer;
this.byteBuffer.clear();
- this.effectiveDirectAddress = byteBuffer.effectiveDirectAddress;
}
@Override
diff --git a/luni/src/main/java/java/nio/ByteBufferAsIntBuffer.java b/luni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
index a3211b8..f584f1a 100644
--- a/luni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
+++ b/luni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
@@ -42,10 +42,9 @@ final class ByteBufferAsIntBuffer extends IntBuffer {
}
private ByteBufferAsIntBuffer(ByteBuffer byteBuffer) {
- super(byteBuffer.capacity() / SizeOf.INT);
+ super(byteBuffer.capacity() / SizeOf.INT, byteBuffer.effectiveDirectAddress);
this.byteBuffer = byteBuffer;
this.byteBuffer.clear();
- this.effectiveDirectAddress = byteBuffer.effectiveDirectAddress;
}
@Override
diff --git a/luni/src/main/java/java/nio/ByteBufferAsLongBuffer.java b/luni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
index 550c675..8afa66e 100644
--- a/luni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
+++ b/luni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
@@ -42,10 +42,9 @@ final class ByteBufferAsLongBuffer extends LongBuffer {
}
private ByteBufferAsLongBuffer(ByteBuffer byteBuffer) {
- super(byteBuffer.capacity() / SizeOf.LONG);
+ super(byteBuffer.capacity() / SizeOf.LONG, byteBuffer.effectiveDirectAddress);
this.byteBuffer = byteBuffer;
this.byteBuffer.clear();
- this.effectiveDirectAddress = byteBuffer.effectiveDirectAddress;
}
@Override
diff --git a/luni/src/main/java/java/nio/ByteBufferAsShortBuffer.java b/luni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
index ff81409..52afc0e 100644
--- a/luni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
+++ b/luni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
@@ -41,10 +41,9 @@ final class ByteBufferAsShortBuffer extends ShortBuffer {
}
private ByteBufferAsShortBuffer(ByteBuffer byteBuffer) {
- super(byteBuffer.capacity() / SizeOf.SHORT);
+ super(byteBuffer.capacity() / SizeOf.SHORT, byteBuffer.effectiveDirectAddress);
this.byteBuffer = byteBuffer;
this.byteBuffer.clear();
- this.effectiveDirectAddress = byteBuffer.effectiveDirectAddress;
}
@Override
diff --git a/luni/src/main/java/java/nio/CharArrayBuffer.java b/luni/src/main/java/java/nio/CharArrayBuffer.java
index 245a799..8f9fd9b 100644
--- a/luni/src/main/java/java/nio/CharArrayBuffer.java
+++ b/luni/src/main/java/java/nio/CharArrayBuffer.java
@@ -33,7 +33,7 @@ final class CharArrayBuffer extends CharBuffer {
}
private CharArrayBuffer(int capacity, char[] backingArray, int arrayOffset, boolean isReadOnly) {
- super(capacity);
+ super(capacity, 0);
this.backingArray = backingArray;
this.arrayOffset = arrayOffset;
this.isReadOnly = isReadOnly;
diff --git a/luni/src/main/java/java/nio/CharBuffer.java b/luni/src/main/java/java/nio/CharBuffer.java
index 92cab01..748a787 100644
--- a/luni/src/main/java/java/nio/CharBuffer.java
+++ b/luni/src/main/java/java/nio/CharBuffer.java
@@ -83,7 +83,7 @@ public abstract class CharBuffer extends Buffer implements
* the length, must not be negative and not greater than
* {@code array.length - start}.
* @return the created char buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code charCount} is invalid.
*/
public static CharBuffer wrap(char[] array, int start, int charCount) {
@@ -124,7 +124,7 @@ public abstract class CharBuffer extends Buffer implements
* the end index, must be no less than {@code start} and no
* greater than {@code cs.length()}.
* @return the created char buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code end} is invalid.
*/
public static CharBuffer wrap(CharSequence cs, int start, int end) {
@@ -137,8 +137,8 @@ public abstract class CharBuffer extends Buffer implements
return result;
}
- CharBuffer(int capacity) {
- super(1, capacity, null);
+ CharBuffer(int capacity, long effectiveDirectAddress) {
+ super(1, capacity, effectiveDirectAddress);
}
public final char[] array() {
@@ -165,17 +165,8 @@ public abstract class CharBuffer extends Buffer implements
public abstract CharBuffer asReadOnlyBuffer();
/**
- * Returns the character located at the specified index in the buffer. The
- * index value is referenced from the current buffer position.
- *
- * @param index
- * the index referenced from the current buffer position. It must
- * not be less than zero but less than the value obtained from a
- * call to {@code remaining()}.
- * @return the character located at the specified index (referenced from the
- * current position) in the buffer.
- * @exception IndexOutOfBoundsException
- * if the index is invalid.
+ * Returns the character located at the given offset <i>relative to the current position</i>.
+ * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= remaining()}.
*/
public final char charAt(int index) {
if (index < 0 || index >= remaining()) {
@@ -192,7 +183,7 @@ public abstract class CharBuffer extends Buffer implements
* {@code remaining()}; the limit is set to capacity; the mark is cleared.
*
* @return this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract CharBuffer compact();
@@ -206,7 +197,7 @@ public abstract class CharBuffer extends Buffer implements
* @return a negative value if this is less than {@code otherBuffer}; 0 if
* this equals to {@code otherBuffer}; a positive value if this is
* greater than {@code otherBuffer}.
- * @exception ClassCastException
+ * @throws ClassCastException
* if {@code otherBuffer} is not a char buffer.
*/
public int compareTo(CharBuffer otherBuffer) {
@@ -278,7 +269,7 @@ public abstract class CharBuffer extends Buffer implements
* Returns the char at the current position and increases the position by 1.
*
* @return the char at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is equal or greater than limit.
*/
public abstract char get();
@@ -293,7 +284,7 @@ public abstract class CharBuffer extends Buffer implements
* @param dst
* the destination char array.
* @return this buffer.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code dst.length} is greater than {@code remaining()}.
*/
public CharBuffer get(char[] dst) {
@@ -314,9 +305,9 @@ public abstract class CharBuffer extends Buffer implements
* The number of chars to read, must be no less than zero and no
* greater than {@code dst.length - dstOffset}.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code dstOffset} or {@code charCount} is invalid.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code charCount} is greater than {@code remaining()}.
*/
public CharBuffer get(char[] dst, int dstOffset, int charCount) {
@@ -336,7 +327,7 @@ public abstract class CharBuffer extends Buffer implements
* @param index
* the index, must not be negative and less than limit.
* @return a char at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
*/
public abstract char get(int index);
@@ -422,9 +413,9 @@ public abstract class CharBuffer extends Buffer implements
* @param c
* the char to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is equal or greater than limit.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract CharBuffer put(char c);
@@ -439,9 +430,9 @@ public abstract class CharBuffer extends Buffer implements
* @param src
* the source char array.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code src.length}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public final CharBuffer put(char[] src) {
@@ -462,11 +453,11 @@ public abstract class CharBuffer extends Buffer implements
* the number of chars to write, must be no less than zero and no
* greater than {@code src.length - srcOffset}.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code charCount}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code srcOffset} or {@code charCount} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public CharBuffer put(char[] src, int srcOffset, int charCount) {
@@ -488,12 +479,12 @@ public abstract class CharBuffer extends Buffer implements
* @param src
* the source char buffer.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code src.remaining()} is greater than this buffer's
* {@code remaining()}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code src} is this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public CharBuffer put(CharBuffer src) {
@@ -522,9 +513,9 @@ public abstract class CharBuffer extends Buffer implements
* @param c
* the char to write.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract CharBuffer put(int index, char c);
@@ -539,9 +530,9 @@ public abstract class CharBuffer extends Buffer implements
* @param str
* the string to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than the length of string.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public final CharBuffer put(String str) {
@@ -561,11 +552,11 @@ public abstract class CharBuffer extends Buffer implements
* the last char to write (excluding), must be less than
* {@code start} and not greater than {@code str.length()}.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code end - start}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code end} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public CharBuffer put(String str, int start, int end) {
@@ -625,7 +616,7 @@ public abstract class CharBuffer extends Buffer implements
* {@code remaining()}.
* @return a new char buffer represents a sub-sequence of this buffer's
* current remaining content.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code end} is invalid.
*/
public abstract CharBuffer subSequence(int start, int end);
@@ -649,9 +640,9 @@ public abstract class CharBuffer extends Buffer implements
* @param c
* the char to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is equal or greater than limit.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public CharBuffer append(char c) {
@@ -670,9 +661,9 @@ public abstract class CharBuffer extends Buffer implements
* @param csq
* the {@code CharSequence} to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than the length of csq.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public CharBuffer append(CharSequence csq) {
@@ -695,11 +686,11 @@ public abstract class CharBuffer extends Buffer implements
* the last char to write (excluding), must be less than
* {@code start} and not greater than {@code csq.length()}.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code end - start}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code end} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public CharBuffer append(CharSequence csq, int start, int end) {
diff --git a/luni/src/main/java/java/nio/CharSequenceAdapter.java b/luni/src/main/java/java/nio/CharSequenceAdapter.java
index f686827..fb8a0f1 100644
--- a/luni/src/main/java/java/nio/CharSequenceAdapter.java
+++ b/luni/src/main/java/java/nio/CharSequenceAdapter.java
@@ -42,7 +42,7 @@ final class CharSequenceAdapter extends CharBuffer {
final CharSequence sequence;
CharSequenceAdapter(CharSequence chseq) {
- super(chseq.length());
+ super(chseq.length(), 0);
sequence = chseq;
}
diff --git a/luni/src/main/java/java/nio/DatagramChannelImpl.java b/luni/src/main/java/java/nio/DatagramChannelImpl.java
index 39f2128..9008637 100644
--- a/luni/src/main/java/java/nio/DatagramChannelImpl.java
+++ b/luni/src/main/java/java/nio/DatagramChannelImpl.java
@@ -17,15 +17,18 @@
package java.nio;
+import android.system.ErrnoException;
import java.io.FileDescriptor;
-import java.io.IOException;
import java.io.InterruptedIOException;
+import java.io.IOException;
import java.net.ConnectException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.DatagramSocketImpl;
+import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
import java.net.PlainDatagramSocketImpl;
import java.net.SocketAddress;
import java.net.SocketException;
@@ -35,8 +38,10 @@ import java.nio.channels.DatagramChannel;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.spi.SelectorProvider;
+import java.nio.channels.UnresolvedAddressException;
+import java.nio.channels.UnsupportedAddressTypeException;
import java.util.Arrays;
-import libcore.io.ErrnoException;
+import java.util.Set;
import libcore.io.IoBridge;
import libcore.io.IoUtils;
import libcore.io.Libcore;
@@ -50,10 +55,13 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
private final FileDescriptor fd;
// Our internal DatagramSocket.
- private DatagramSocket socket = null;
+ private DatagramSocket socket;
+
+ // The remote address to be connected.
+ InetSocketAddress connectAddress;
- // The address to be connected.
- InetSocketAddress connectAddress = null;
+ // The local address.
+ InetAddress localAddress;
// local port
private int localPort;
@@ -98,19 +106,38 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
}
/**
- * @see java.nio.channels.DatagramChannel#isConnected()
+ * Initialise the isBound, localAddress and localPort state from the file descriptor. Used when
+ * some or all of the bound state has been left to the OS to decide, or when the Socket handled
+ * bind() or connect().
+ *
+ * @param updateSocketState
+ * if the associated socket (if present) needs to be updated
+ * @hide used to sync state, non-private to avoid synthetic method
*/
+ void onBind(boolean updateSocketState) {
+ SocketAddress sa;
+ try {
+ sa = Libcore.os.getsockname(fd);
+ } catch (ErrnoException errnoException) {
+ throw new AssertionError(errnoException);
+ }
+ isBound = true;
+ InetSocketAddress localSocketAddress = (InetSocketAddress) sa;
+ localAddress = localSocketAddress.getAddress();
+ localPort = localSocketAddress.getPort();
+ if (updateSocketState && socket != null) {
+ socket.onBind(localAddress, localPort);
+ }
+ }
+
@Override
synchronized public boolean isConnected() {
return connected;
}
- /**
- * @see java.nio.channels.DatagramChannel#connect(java.net.SocketAddress)
- */
@Override
synchronized public DatagramChannel connect(SocketAddress address) throws IOException {
- // must open
+ // must be open
checkOpen();
// status must be un-connected.
if (connected) {
@@ -119,43 +146,71 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
// check the address
InetSocketAddress inetSocketAddress = SocketChannelImpl.validateAddress(address);
+ InetAddress remoteAddress = inetSocketAddress.getAddress();
+ int remotePort = inetSocketAddress.getPort();
try {
begin();
- IoBridge.connect(fd, inetSocketAddress.getAddress(), inetSocketAddress.getPort());
+ IoBridge.connect(fd, remoteAddress, remotePort);
} catch (ConnectException e) {
// ConnectException means connect fail, not exception
} finally {
end(true);
}
- // set the connected address.
- connectAddress = inetSocketAddress;
- connected = true;
- isBound = true;
+ // connect() performs a bind() if an explicit bind() was not performed. Keep the local
+ // address state held by the channel and the socket up to date.
+ if (!isBound) {
+ onBind(true /* updateSocketState */);
+ }
+
+ // Keep the connected state held by the channel and the socket up to date.
+ onConnect(remoteAddress, remotePort, true /* updateSocketState */);
return this;
}
/**
- * @see java.nio.channels.DatagramChannel#disconnect()
+ * Initialize the state associated with being connected, optionally syncing the socket if there
+ * is one.
+ * @hide used to sync state, non-private to avoid synthetic method
*/
+ void onConnect(InetAddress remoteAddress, int remotePort, boolean updateSocketState) {
+ connected = true;
+ connectAddress = new InetSocketAddress(remoteAddress, remotePort);
+ if (updateSocketState && socket != null) {
+ socket.onConnect(remoteAddress, remotePort);
+ }
+ }
+
@Override
synchronized public DatagramChannel disconnect() throws IOException {
if (!isConnected() || !isOpen()) {
return this;
}
- connected = false;
- connectAddress = null;
+
+ // Keep the disconnected state held by the channel and the socket up to date.
+ onDisconnect(true /* updateSocketState */);
+
try {
Libcore.os.connect(fd, InetAddress.UNSPECIFIED, 0);
} catch (ErrnoException errnoException) {
throw errnoException.rethrowAsIOException();
}
- if (socket != null) {
- socket.disconnect();
- }
return this;
}
+ /**
+ * Initialize the state associated with being disconnected, optionally syncing the socket if
+ * there is one.
+ * @hide used to sync state, non-private to avoid synthetic method
+ */
+ void onDisconnect(boolean updateSocketState) {
+ connected = false;
+ connectAddress = null;
+ if (updateSocketState && socket != null && socket.isConnected()) {
+ socket.onDisconnect();
+ }
+ }
+
@Override
public SocketAddress receive(ByteBuffer target) throws IOException {
target.checkWritable();
@@ -191,7 +246,7 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
SocketAddress retAddr = null;
DatagramPacket receivePacket;
int oldposition = target.position();
- int received = 0;
+ int received;
// TODO: disallow mapped buffers and lose this conditional?
if (target.hasArray()) {
receivePacket = new DatagramPacket(target.array(), target.position() + target.arrayOffset(), target.remaining());
@@ -200,7 +255,7 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
}
do {
received = IoBridge.recvfrom(false, fd, receivePacket.getData(), receivePacket.getOffset(), receivePacket.getLength(), 0, receivePacket, isConnected());
- if (receivePacket != null && receivePacket.getAddress() != null) {
+ if (receivePacket.getAddress() != null) {
if (received > 0) {
if (target.hasArray()) {
target.position(oldposition + received);
@@ -220,10 +275,10 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
SocketAddress retAddr = null;
DatagramPacket receivePacket = new DatagramPacket(EmptyArray.BYTE, 0);
int oldposition = target.position();
- int received = 0;
+ int received;
do {
received = IoBridge.recvfrom(false, fd, target, 0, receivePacket, isConnected());
- if (receivePacket != null && receivePacket.getAddress() != null) {
+ if (receivePacket.getAddress() != null) {
// copy the data of received packet
if (received > 0) {
target.position(oldposition + received);
@@ -259,7 +314,9 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
if (sendCount > 0) {
source.position(oldPosition + sendCount);
}
- isBound = true;
+ if (!isBound) {
+ onBind(true /* updateSocketState */);
+ }
} finally {
end(sendCount >= 0);
}
@@ -276,7 +333,7 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
return 0;
}
- int readCount = 0;
+ int readCount;
if (target.isDirect() || target.hasArray()) {
readCount = readImpl(target);
if (readCount > 0) {
@@ -405,11 +462,12 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
}
@Override protected synchronized void implCloseSelectableChannel() throws IOException {
- connected = false;
+ // A closed channel is not connected.
+ onDisconnect(true /* updateSocketState */);
+ IoBridge.closeAndSignalBlockedThreads(fd);
+
if (socket != null && !socket.isClosed()) {
- socket.close();
- } else {
- IoBridge.closeSocket(fd);
+ socket.onClose();
}
}
@@ -420,7 +478,7 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
/*
* Status check, must be open.
*/
- private void checkOpen() throws IOException {
+ private void checkOpen() throws ClosedChannelException {
if (!isOpen()) {
throw new ClosedChannelException();
}
@@ -460,15 +518,29 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
/*
* The internal datagramChannelImpl.
*/
- private DatagramChannelImpl channelImpl;
+ private final DatagramChannelImpl channelImpl;
/*
* Constructor initialize the datagramSocketImpl and datagramChannelImpl
*/
- DatagramSocketAdapter(DatagramSocketImpl socketimpl,
- DatagramChannelImpl channelImpl) {
+ DatagramSocketAdapter(DatagramSocketImpl socketimpl, DatagramChannelImpl channelImpl) {
super(socketimpl);
this.channelImpl = channelImpl;
+
+ // Sync state socket state with the channel it is being created from
+ if (channelImpl.isBound) {
+ onBind(channelImpl.localAddress, channelImpl.localPort);
+ }
+ if (channelImpl.connected) {
+ onConnect(
+ channelImpl.connectAddress.getAddress(),
+ channelImpl.connectAddress.getPort());
+ } else {
+ onDisconnect();
+ }
+ if (!channelImpl.isOpen()) {
+ onClose();
+ }
}
/*
@@ -479,92 +551,78 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
return channelImpl;
}
- /**
- * @see java.net.DatagramSocket#isBound()
- */
- @Override
- public boolean isBound() {
- return channelImpl.isBound;
- }
-
- /**
- * @see java.net.DatagramSocket#isConnected()
- */
- @Override
- public boolean isConnected() {
- return channelImpl.isConnected();
- }
-
- /**
- * @see java.net.DatagramSocket#getInetAddress()
- */
@Override
- public InetAddress getInetAddress() {
- if (channelImpl.connectAddress == null) {
- return null;
- }
- return channelImpl.connectAddress.getAddress();
- }
-
- @Override public InetAddress getLocalAddress() {
- try {
- return IoBridge.getSocketLocalAddress(channelImpl.fd);
- } catch (SocketException ex) {
- return null;
+ public void bind(SocketAddress localAddr) throws SocketException {
+ if (channelImpl.isConnected()) {
+ throw new AlreadyConnectedException();
}
+ super.bind(localAddr);
+ channelImpl.onBind(false /* updateSocketState */);
}
- /**
- * @see java.net.DatagramSocket#getPort()
- */
@Override
- public int getPort() {
- if (channelImpl.connectAddress == null) {
- return -1;
+ public void connect(SocketAddress peer) throws SocketException {
+ if (isConnected()) {
+ // RI compatibility: If the socket is already connected this fails.
+ throw new IllegalStateException("Socket is already connected.");
}
- return channelImpl.connectAddress.getPort();
+ super.connect(peer);
+ // Connect may have performed an implicit bind(). Sync up here.
+ channelImpl.onBind(false /* updateSocketState */);
+
+ InetSocketAddress inetSocketAddress = (InetSocketAddress) peer;
+ channelImpl.onConnect(
+ inetSocketAddress.getAddress(), inetSocketAddress.getPort(),
+ false /* updateSocketState */);
}
- /**
- * @see java.net.DatagramSocket#bind(java.net.SocketAddress)
- */
@Override
- public void bind(SocketAddress localAddr) throws SocketException {
- if (channelImpl.isConnected()) {
- throw new AlreadyConnectedException();
+ public void connect(InetAddress address, int port) {
+ // To avoid implementing connect() twice call this.connect(SocketAddress) in preference
+ // to super.connect().
+ try {
+ connect(new InetSocketAddress(address, port));
+ } catch (SocketException e) {
+ // Ignored - there is nothing we can report here.
}
- super.bind(localAddr);
- channelImpl.isBound = true;
}
- /**
- * @see java.net.DatagramSocket#receive(java.net.DatagramPacket)
- */
@Override
public void receive(DatagramPacket packet) throws IOException {
if (!channelImpl.isBlocking()) {
throw new IllegalBlockingModeException();
}
+
+ boolean wasBound = isBound();
super.receive(packet);
+ if (!wasBound) {
+ // DatagramSocket.receive() will implicitly bind if it hasn't been done explicitly.
+ // Sync the channel state with the socket.
+ channelImpl.onBind(false /* updateSocketState */);
+ }
}
- /**
- * @see java.net.DatagramSocket#send(java.net.DatagramPacket)
- */
@Override
public void send(DatagramPacket packet) throws IOException {
if (!channelImpl.isBlocking()) {
throw new IllegalBlockingModeException();
}
+
+ // DatagramSocket.send() will implicitly bind if it hasn't been done explicitly. Force
+ // bind() here so that the channel state stays in sync with the socket.
+ boolean wasBound = isBound();
super.send(packet);
+ if (!wasBound) {
+ // DatagramSocket.send() will implicitly bind if it hasn't been done explicitly.
+ // Sync the channel state with the socket.
+ channelImpl.onBind(false /* updateSocketState */);
+ }
}
- /**
- * @see java.net.DatagramSocket#close()
- */
@Override
public void close() {
synchronized (channelImpl) {
+ super.close();
if (channelImpl.isOpen()) {
try {
channelImpl.close();
@@ -572,21 +630,13 @@ class DatagramChannelImpl extends DatagramChannel implements FileDescriptorChann
// Ignore
}
}
- super.close();
}
}
- /**
- * @see java.net.DatagramSocket#disconnect()
- */
@Override
public void disconnect() {
- try {
- channelImpl.disconnect();
- } catch (IOException e) {
- // Ignore
- }
super.disconnect();
+ channelImpl.onDisconnect(false /* updateSocketState */);
}
}
}
diff --git a/luni/src/main/java/java/nio/DirectByteBuffer.java b/luni/src/main/java/java/nio/DirectByteBuffer.java
index 1d12f2e..f19fb42 100644
--- a/luni/src/main/java/java/nio/DirectByteBuffer.java
+++ b/luni/src/main/java/java/nio/DirectByteBuffer.java
@@ -30,15 +30,16 @@ class DirectByteBuffer extends MappedByteBuffer {
private final boolean isReadOnly;
protected DirectByteBuffer(MemoryBlock block, int capacity, int offset, boolean isReadOnly, MapMode mapMode) {
- super(block, capacity, mapMode);
+ super(block, capacity, mapMode, block.toLong() + offset);
long baseSize = block.getSize();
+ // We're throwing this exception after we passed a bogus value
+ // to the superclass constructor, but it doesn't make any
+ // difference in this case.
if (baseSize >= 0 && (capacity + offset) > baseSize) {
throw new IllegalArgumentException("capacity + offset > baseSize");
}
- this.effectiveDirectAddress = block.toLong() + offset;
-
this.offset = offset;
this.isReadOnly = isReadOnly;
}
@@ -49,6 +50,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
private static DirectByteBuffer copy(DirectByteBuffer other, int markOfOther, boolean isReadOnly) {
+ other.checkNotFreed();
DirectByteBuffer buf = new DirectByteBuffer(other.block, other.capacity(), other.offset, isReadOnly, other.mapMode);
buf.limit = other.limit;
buf.position = other.position();
@@ -61,6 +63,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer compact() {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -76,6 +79,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer slice() {
+ checkNotFreed();
return new DirectByteBuffer(block, remaining(), offset + position, isReadOnly, mapMode);
}
@@ -84,6 +88,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override byte[] protectedArray() {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -104,6 +109,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public final ByteBuffer get(byte[] dst, int dstOffset, int byteCount) {
+ checkIsAccessible();
checkGetBounds(1, dst.length, dstOffset, byteCount);
this.block.peekByteArray(offset + position, dst, dstOffset, byteCount);
position += byteCount;
@@ -111,42 +117,49 @@ class DirectByteBuffer extends MappedByteBuffer {
}
final void get(char[] dst, int dstOffset, int charCount) {
+ checkIsAccessible();
int byteCount = checkGetBounds(SizeOf.CHAR, dst.length, dstOffset, charCount);
this.block.peekCharArray(offset + position, dst, dstOffset, charCount, order.needsSwap);
position += byteCount;
}
final void get(double[] dst, int dstOffset, int doubleCount) {
+ checkIsAccessible();
int byteCount = checkGetBounds(SizeOf.DOUBLE, dst.length, dstOffset, doubleCount);
this.block.peekDoubleArray(offset + position, dst, dstOffset, doubleCount, order.needsSwap);
position += byteCount;
}
final void get(float[] dst, int dstOffset, int floatCount) {
+ checkIsAccessible();
int byteCount = checkGetBounds(SizeOf.FLOAT, dst.length, dstOffset, floatCount);
this.block.peekFloatArray(offset + position, dst, dstOffset, floatCount, order.needsSwap);
position += byteCount;
}
final void get(int[] dst, int dstOffset, int intCount) {
+ checkIsAccessible();
int byteCount = checkGetBounds(SizeOf.INT, dst.length, dstOffset, intCount);
this.block.peekIntArray(offset + position, dst, dstOffset, intCount, order.needsSwap);
position += byteCount;
}
final void get(long[] dst, int dstOffset, int longCount) {
+ checkIsAccessible();
int byteCount = checkGetBounds(SizeOf.LONG, dst.length, dstOffset, longCount);
this.block.peekLongArray(offset + position, dst, dstOffset, longCount, order.needsSwap);
position += byteCount;
}
final void get(short[] dst, int dstOffset, int shortCount) {
+ checkIsAccessible();
int byteCount = checkGetBounds(SizeOf.SHORT, dst.length, dstOffset, shortCount);
this.block.peekShortArray(offset + position, dst, dstOffset, shortCount, order.needsSwap);
position += byteCount;
}
@Override public final byte get() {
+ checkIsAccessible();
if (position == limit) {
throw new BufferUnderflowException();
}
@@ -154,11 +167,13 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public final byte get(int index) {
+ checkIsAccessible();
checkIndex(index);
return this.block.peekByte(offset + index);
}
@Override public final char getChar() {
+ checkIsAccessible();
int newPosition = position + SizeOf.CHAR;
if (newPosition > limit) {
throw new BufferUnderflowException();
@@ -169,11 +184,13 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public final char getChar(int index) {
+ checkIsAccessible();
checkIndex(index, SizeOf.CHAR);
return (char) this.block.peekShort(offset + index, order);
}
@Override public final double getDouble() {
+ checkIsAccessible();
int newPosition = position + SizeOf.DOUBLE;
if (newPosition > limit) {
throw new BufferUnderflowException();
@@ -184,11 +201,13 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public final double getDouble(int index) {
+ checkIsAccessible();
checkIndex(index, SizeOf.DOUBLE);
return Double.longBitsToDouble(this.block.peekLong(offset + index, order));
}
@Override public final float getFloat() {
+ checkIsAccessible();
int newPosition = position + SizeOf.FLOAT;
if (newPosition > limit) {
throw new BufferUnderflowException();
@@ -199,11 +218,13 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public final float getFloat(int index) {
+ checkIsAccessible();
checkIndex(index, SizeOf.FLOAT);
return Float.intBitsToFloat(this.block.peekInt(offset + index, order));
}
@Override public final int getInt() {
+ checkIsAccessible();
int newPosition = position + SizeOf.INT;
if (newPosition > limit) {
throw new BufferUnderflowException();
@@ -214,11 +235,13 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public final int getInt(int index) {
+ checkIsAccessible();
checkIndex(index, SizeOf.INT);
return this.block.peekInt(offset + index, order);
}
@Override public final long getLong() {
+ checkIsAccessible();
int newPosition = position + SizeOf.LONG;
if (newPosition > limit) {
throw new BufferUnderflowException();
@@ -229,11 +252,13 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public final long getLong(int index) {
+ checkIsAccessible();
checkIndex(index, SizeOf.LONG);
return this.block.peekLong(offset + index, order);
}
@Override public final short getShort() {
+ checkIsAccessible();
int newPosition = position + SizeOf.SHORT;
if (newPosition > limit) {
throw new BufferUnderflowException();
@@ -244,6 +269,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public final short getShort(int index) {
+ checkIsAccessible();
checkIndex(index, SizeOf.SHORT);
return this.block.peekShort(offset + index, order);
}
@@ -252,35 +278,56 @@ class DirectByteBuffer extends MappedByteBuffer {
return true;
}
+ /** @hide */
+ @Override public final boolean isAccessible() {
+ return block.isAccessible();
+ }
+
+ /** @hide */
+ @Override public void setAccessible(boolean accessible) {
+ block.setAccessible(accessible);
+ }
+
+ /**
+ * Invalidates the buffer. Subsequent operations which touch the inner
+ * buffer will throw {@link IllegalStateException}.
+ */
public final void free() {
block.free();
}
@Override public final CharBuffer asCharBuffer() {
+ checkNotFreed();
return ByteBufferAsCharBuffer.asCharBuffer(this);
}
@Override public final DoubleBuffer asDoubleBuffer() {
+ checkNotFreed();
return ByteBufferAsDoubleBuffer.asDoubleBuffer(this);
}
@Override public final FloatBuffer asFloatBuffer() {
+ checkNotFreed();
return ByteBufferAsFloatBuffer.asFloatBuffer(this);
}
@Override public final IntBuffer asIntBuffer() {
+ checkNotFreed();
return ByteBufferAsIntBuffer.asIntBuffer(this);
}
@Override public final LongBuffer asLongBuffer() {
+ checkNotFreed();
return ByteBufferAsLongBuffer.asLongBuffer(this);
}
@Override public final ShortBuffer asShortBuffer() {
+ checkNotFreed();
return ByteBufferAsShortBuffer.asShortBuffer(this);
}
@Override public ByteBuffer put(byte value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -292,6 +339,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer put(int index, byte value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -301,6 +349,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer put(byte[] src, int srcOffset, int byteCount) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -311,42 +360,49 @@ class DirectByteBuffer extends MappedByteBuffer {
}
final void put(char[] src, int srcOffset, int charCount) {
+ checkIsAccessible();
int byteCount = checkPutBounds(SizeOf.CHAR, src.length, srcOffset, charCount);
this.block.pokeCharArray(offset + position, src, srcOffset, charCount, order.needsSwap);
position += byteCount;
}
final void put(double[] src, int srcOffset, int doubleCount) {
+ checkIsAccessible();
int byteCount = checkPutBounds(SizeOf.DOUBLE, src.length, srcOffset, doubleCount);
this.block.pokeDoubleArray(offset + position, src, srcOffset, doubleCount, order.needsSwap);
position += byteCount;
}
final void put(float[] src, int srcOffset, int floatCount) {
+ checkIsAccessible();
int byteCount = checkPutBounds(SizeOf.FLOAT, src.length, srcOffset, floatCount);
this.block.pokeFloatArray(offset + position, src, srcOffset, floatCount, order.needsSwap);
position += byteCount;
}
final void put(int[] src, int srcOffset, int intCount) {
+ checkIsAccessible();
int byteCount = checkPutBounds(SizeOf.INT, src.length, srcOffset, intCount);
this.block.pokeIntArray(offset + position, src, srcOffset, intCount, order.needsSwap);
position += byteCount;
}
final void put(long[] src, int srcOffset, int longCount) {
+ checkIsAccessible();
int byteCount = checkPutBounds(SizeOf.LONG, src.length, srcOffset, longCount);
this.block.pokeLongArray(offset + position, src, srcOffset, longCount, order.needsSwap);
position += byteCount;
}
final void put(short[] src, int srcOffset, int shortCount) {
+ checkIsAccessible();
int byteCount = checkPutBounds(SizeOf.SHORT, src.length, srcOffset, shortCount);
this.block.pokeShortArray(offset + position, src, srcOffset, shortCount, order.needsSwap);
position += byteCount;
}
@Override public ByteBuffer putChar(char value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -360,6 +416,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putChar(int index, char value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -369,6 +426,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putDouble(double value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -382,6 +440,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putDouble(int index, double value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -391,6 +450,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putFloat(float value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -404,6 +464,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putFloat(int index, float value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -413,6 +474,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putInt(int value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -426,6 +488,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putInt(int index, int value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -435,6 +498,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putLong(long value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -448,6 +512,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putLong(int index, long value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -457,6 +522,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putShort(short value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -470,6 +536,7 @@ class DirectByteBuffer extends MappedByteBuffer {
}
@Override public ByteBuffer putShort(int index, short value) {
+ checkIsAccessible();
if (isReadOnly) {
throw new ReadOnlyBufferException();
}
@@ -477,4 +544,18 @@ class DirectByteBuffer extends MappedByteBuffer {
this.block.pokeShort(offset + index, value, order);
return this;
}
+
+ private void checkIsAccessible() {
+ checkNotFreed();
+ if (!block.isAccessible()) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ }
+
+ private void checkNotFreed() {
+ if (block.isFreed()) {
+ throw new IllegalStateException("buffer was freed");
+ }
+ }
+
}
diff --git a/luni/src/main/java/java/nio/DoubleArrayBuffer.java b/luni/src/main/java/java/nio/DoubleArrayBuffer.java
index f8e4e59..a2d9e79 100644
--- a/luni/src/main/java/java/nio/DoubleArrayBuffer.java
+++ b/luni/src/main/java/java/nio/DoubleArrayBuffer.java
@@ -33,7 +33,7 @@ final class DoubleArrayBuffer extends DoubleBuffer {
}
private DoubleArrayBuffer(int capacity, double[] backingArray, int arrayOffset, boolean isReadOnly) {
- super(capacity);
+ super(capacity, 0);
this.backingArray = backingArray;
this.arrayOffset = arrayOffset;
this.isReadOnly = isReadOnly;
diff --git a/luni/src/main/java/java/nio/DoubleBuffer.java b/luni/src/main/java/java/nio/DoubleBuffer.java
index 2fa74d2..f3062fb 100644
--- a/luni/src/main/java/java/nio/DoubleBuffer.java
+++ b/luni/src/main/java/java/nio/DoubleBuffer.java
@@ -81,7 +81,7 @@ public abstract class DoubleBuffer extends Buffer implements
* the length, must not be negative and not greater than
* {@code array.length - start}.
* @return the created double buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code doubleCount} is invalid.
*/
public static DoubleBuffer wrap(double[] array, int start, int doubleCount) {
@@ -92,8 +92,8 @@ public abstract class DoubleBuffer extends Buffer implements
return buf;
}
- DoubleBuffer(int capacity) {
- super(3, capacity, null);
+ DoubleBuffer(int capacity, long effectiveDirectAddress) {
+ super(3, capacity, effectiveDirectAddress);
}
public final double[] array() {
@@ -127,7 +127,7 @@ public abstract class DoubleBuffer extends Buffer implements
* limit is set to capacity; the mark is cleared.
*
* @return this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract DoubleBuffer compact();
@@ -141,7 +141,7 @@ public abstract class DoubleBuffer extends Buffer implements
* @return a negative value if this is less than {@code other}; 0 if this
* equals to {@code other}; a positive value if this is greater
* than {@code other}.
- * @exception ClassCastException
+ * @throws ClassCastException
* if {@code other} is not a double buffer.
*/
public int compareTo(DoubleBuffer otherBuffer) {
@@ -223,7 +223,7 @@ public abstract class DoubleBuffer extends Buffer implements
* 1.
*
* @return the double at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is equal or greater than limit.
*/
public abstract double get();
@@ -238,7 +238,7 @@ public abstract class DoubleBuffer extends Buffer implements
* @param dst
* the destination double array.
* @return this buffer.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code dst.length} is greater than {@code remaining()}.
*/
public DoubleBuffer get(double[] dst) {
@@ -259,9 +259,9 @@ public abstract class DoubleBuffer extends Buffer implements
* the number of doubles to read, must be no less than zero and
* not greater than {@code dst.length - dstOffset}.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code dstOffset} or {@code doubleCount} is invalid.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code doubleCount} is greater than {@code remaining()}.
*/
public DoubleBuffer get(double[] dst, int dstOffset, int doubleCount) {
@@ -281,7 +281,7 @@ public abstract class DoubleBuffer extends Buffer implements
* @param index
* the index, must not be negative and less than limit.
* @return a double at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
*/
public abstract double get(int index);
@@ -360,9 +360,9 @@ public abstract class DoubleBuffer extends Buffer implements
* @param d
* the double to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is equal or greater than limit.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract DoubleBuffer put(double d);
@@ -377,9 +377,9 @@ public abstract class DoubleBuffer extends Buffer implements
* @param src
* the source double array.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code src.length}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public final DoubleBuffer put(double[] src) {
@@ -400,11 +400,11 @@ public abstract class DoubleBuffer extends Buffer implements
* the number of doubles to write, must be no less than zero and
* not greater than {@code src.length - srcOffset}.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code doubleCount}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code srcOffset} or {@code doubleCount} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public DoubleBuffer put(double[] src, int srcOffset, int doubleCount) {
@@ -426,12 +426,12 @@ public abstract class DoubleBuffer extends Buffer implements
* @param src
* the source double buffer.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code src.remaining()} is greater than this buffer's
* {@code remaining()}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code src} is this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public DoubleBuffer put(DoubleBuffer src) {
@@ -459,9 +459,9 @@ public abstract class DoubleBuffer extends Buffer implements
* @param d
* the double to write.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract DoubleBuffer put(int index, double d);
diff --git a/luni/src/main/java/java/nio/FileChannelImpl.java b/luni/src/main/java/java/nio/FileChannelImpl.java
index a1be7fb..d72b9f0 100644
--- a/luni/src/main/java/java/nio/FileChannelImpl.java
+++ b/luni/src/main/java/java/nio/FileChannelImpl.java
@@ -17,12 +17,17 @@
package java.nio;
+import android.system.ErrnoException;
+import android.system.StructFlock;
+import android.util.MutableLong;
import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.IOException;
+import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
+import java.nio.channels.FileLockInterruptionException;
import java.nio.channels.NonReadableChannelException;
import java.nio.channels.NonWritableChannelException;
import java.nio.channels.OverlappingFileLockException;
@@ -32,11 +37,8 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
-import libcore.io.ErrnoException;
import libcore.io.Libcore;
-import libcore.io.StructFlock;
-import libcore.util.MutableLong;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* Our concrete implementation of the abstract FileChannel class.
@@ -50,7 +52,7 @@ final class FileChannelImpl extends FileChannel {
}
};
- private final Object stream;
+ private final Closeable ioObject;
private final FileDescriptor fd;
private final int mode;
@@ -61,9 +63,9 @@ final class FileChannelImpl extends FileChannel {
* Create a new file channel implementation class that wraps the given
* fd and operates in the specified mode.
*/
- public FileChannelImpl(Object stream, FileDescriptor fd, int mode) {
+ public FileChannelImpl(Closeable ioObject, FileDescriptor fd, int mode) {
this.fd = fd;
- this.stream = stream;
+ this.ioObject = ioObject;
this.mode = mode;
}
@@ -86,9 +88,7 @@ final class FileChannelImpl extends FileChannel {
}
protected void implCloseChannel() throws IOException {
- if (stream instanceof Closeable) {
- ((Closeable) stream).close();
- }
+ ioObject.close();
}
private FileLock basicLock(long position, long size, boolean shared, boolean wait) throws IOException {
@@ -166,7 +166,11 @@ final class FileChannelImpl extends FileChannel {
resultLock = basicLock(position, size, shared, true);
completed = true;
} finally {
- end(completed);
+ try {
+ end(completed);
+ } catch (ClosedByInterruptException e) {
+ throw new FileLockInterruptionException();
+ }
}
}
return resultLock;
@@ -461,6 +465,9 @@ final class FileChannelImpl extends FileChannel {
throw errnoException.rethrowAsIOException();
}
}
+ if (position() > size) {
+ position(size);
+ }
return this;
}
diff --git a/luni/src/main/java/java/nio/FloatArrayBuffer.java b/luni/src/main/java/java/nio/FloatArrayBuffer.java
index 698174c..ac512a5 100644
--- a/luni/src/main/java/java/nio/FloatArrayBuffer.java
+++ b/luni/src/main/java/java/nio/FloatArrayBuffer.java
@@ -33,7 +33,7 @@ final class FloatArrayBuffer extends FloatBuffer {
}
private FloatArrayBuffer(int capacity, float[] backingArray, int arrayOffset, boolean isReadOnly) {
- super(capacity);
+ super(capacity, 0);
this.backingArray = backingArray;
this.arrayOffset = arrayOffset;
this.isReadOnly = isReadOnly;
diff --git a/luni/src/main/java/java/nio/FloatBuffer.java b/luni/src/main/java/java/nio/FloatBuffer.java
index cb7e55e..68514c5 100644
--- a/luni/src/main/java/java/nio/FloatBuffer.java
+++ b/luni/src/main/java/java/nio/FloatBuffer.java
@@ -80,9 +80,9 @@ public abstract class FloatBuffer extends Buffer implements
* the length, must not be negative and not greater than
* {@code array.length - start}.
* @return the created float buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code floatCount} is invalid.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code array} is null.
*/
public static FloatBuffer wrap(float[] array, int start, int floatCount) {
@@ -93,8 +93,8 @@ public abstract class FloatBuffer extends Buffer implements
return buf;
}
- FloatBuffer(int capacity) {
- super(2, capacity, null);
+ FloatBuffer(int capacity, long effectiveDirectAddress) {
+ super(2, capacity, effectiveDirectAddress);
}
public final float[] array() {
@@ -128,7 +128,7 @@ public abstract class FloatBuffer extends Buffer implements
* limit is set to capacity; the mark is cleared.
*
* @return this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract FloatBuffer compact();
@@ -142,7 +142,7 @@ public abstract class FloatBuffer extends Buffer implements
* @return a negative value if this is less than {@code otherBuffer}; 0 if
* this equals to {@code otherBuffer}; a positive value if this is
* greater than {@code otherBuffer}.
- * @exception ClassCastException
+ * @throws ClassCastException
* if {@code otherBuffer} is not a float buffer.
*/
public int compareTo(FloatBuffer otherBuffer) {
@@ -224,7 +224,7 @@ public abstract class FloatBuffer extends Buffer implements
* 1.
*
* @return the float at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is equal or greater than limit.
*/
public abstract float get();
@@ -239,7 +239,7 @@ public abstract class FloatBuffer extends Buffer implements
* @param dst
* the destination float array.
* @return this buffer.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code dst.length} is greater than {@code remaining()}.
*/
public FloatBuffer get(float[] dst) {
@@ -260,9 +260,9 @@ public abstract class FloatBuffer extends Buffer implements
* the number of floats to read, must be no less than zero and no
* greater than {@code dst.length - dstOffset}.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code dstOffset} or {@code floatCount} is invalid.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code floatCount} is greater than {@code remaining()}.
*/
public FloatBuffer get(float[] dst, int dstOffset, int floatCount) {
@@ -282,7 +282,7 @@ public abstract class FloatBuffer extends Buffer implements
* @param index
* the index, must not be negative and less than limit.
* @return a float at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
*/
public abstract float get(int index);
@@ -359,9 +359,9 @@ public abstract class FloatBuffer extends Buffer implements
* @param f
* the float to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is equal or greater than limit.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract FloatBuffer put(float f);
@@ -376,9 +376,9 @@ public abstract class FloatBuffer extends Buffer implements
* @param src
* the source float array.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code src.length}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public final FloatBuffer put(float[] src) {
@@ -399,11 +399,11 @@ public abstract class FloatBuffer extends Buffer implements
* the number of floats to write, must be no less than zero and
* no greater than {@code src.length - srcOffset}.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code floatCount}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code srcOffset} or {@code floatCount} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public FloatBuffer put(float[] src, int srcOffset, int floatCount) {
@@ -425,12 +425,12 @@ public abstract class FloatBuffer extends Buffer implements
* @param src
* the source float buffer.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code src.remaining()} is greater than this buffer's
* {@code remaining()}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code src} is this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public FloatBuffer put(FloatBuffer src) {
@@ -458,9 +458,9 @@ public abstract class FloatBuffer extends Buffer implements
* @param f
* the float to write.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract FloatBuffer put(int index, float f);
diff --git a/luni/src/main/java/java/nio/IntArrayBuffer.java b/luni/src/main/java/java/nio/IntArrayBuffer.java
index a5f9f39..423b1af 100644
--- a/luni/src/main/java/java/nio/IntArrayBuffer.java
+++ b/luni/src/main/java/java/nio/IntArrayBuffer.java
@@ -33,7 +33,7 @@ final class IntArrayBuffer extends IntBuffer {
}
private IntArrayBuffer(int capacity, int[] backingArray, int arrayOffset, boolean isReadOnly) {
- super(capacity);
+ super(capacity, 0);
this.backingArray = backingArray;
this.arrayOffset = arrayOffset;
this.isReadOnly = isReadOnly;
diff --git a/luni/src/main/java/java/nio/IntBuffer.java b/luni/src/main/java/java/nio/IntBuffer.java
index a20f6c2..50e95b0 100644
--- a/luni/src/main/java/java/nio/IntBuffer.java
+++ b/luni/src/main/java/java/nio/IntBuffer.java
@@ -78,7 +78,7 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* the length, must not be negative and not greater than
* {@code array.length - start}.
* @return the created int buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code intCount} is invalid.
*/
public static IntBuffer wrap(int[] array, int start, int intCount) {
@@ -89,8 +89,8 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
return buf;
}
- IntBuffer(int capacity) {
- super(2, capacity, null);
+ IntBuffer(int capacity, long effectiveDirectAddress) {
+ super(2, capacity, effectiveDirectAddress);
}
public final int[] array() {
@@ -124,7 +124,7 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* limit is set to capacity; the mark is cleared.
*
* @return this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract IntBuffer compact();
@@ -138,7 +138,7 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* @return a negative value if this is less than {@code other}; 0 if this
* equals to {@code other}; a positive value if this is greater
* than {@code other}.
- * @exception ClassCastException
+ * @throws ClassCastException
* if {@code other} is not an int buffer.
*/
public int compareTo(IntBuffer otherBuffer) {
@@ -210,7 +210,7 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* Returns the int at the current position and increases the position by 1.
*
* @return the int at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is equal or greater than limit.
*/
public abstract int get();
@@ -225,7 +225,7 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* @param dst
* the destination int array.
* @return this buffer.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code dst.length} is greater than {@code remaining()}.
*/
public IntBuffer get(int[] dst) {
@@ -246,9 +246,9 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* the number of ints to read, must be no less than zero and not
* greater than {@code dst.length - dstOffset}.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code dstOffset} or {@code intCount} is invalid.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code intCount} is greater than {@code remaining()}.
*/
public IntBuffer get(int[] dst, int dstOffset, int intCount) {
@@ -268,7 +268,7 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* @param index
* the index, must not be negative and less than limit.
* @return an int at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
*/
public abstract int get(int index);
@@ -345,9 +345,9 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* @param i
* the int to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is equal or greater than limit.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract IntBuffer put(int i);
@@ -362,9 +362,9 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* @param src
* the source int array.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code src.length}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public final IntBuffer put(int[] src) {
@@ -385,11 +385,11 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* the number of ints to write, must be no less than zero and not
* greater than {@code src.length - srcOffset}.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code intCount}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code srcOffset} or {@code intCount} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public IntBuffer put(int[] src, int srcOffset, int intCount) {
@@ -414,12 +414,12 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* @param src
* the source int buffer.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code src.remaining()} is greater than this buffer's
* {@code remaining()}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code src} is this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public IntBuffer put(IntBuffer src) {
@@ -447,9 +447,9 @@ public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer>
* @param i
* the int to write.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract IntBuffer put(int index, int i);
diff --git a/luni/src/main/java/java/nio/IoVec.java b/luni/src/main/java/java/nio/IoVec.java
index f14f4f2..e20709c 100644
--- a/luni/src/main/java/java/nio/IoVec.java
+++ b/luni/src/main/java/java/nio/IoVec.java
@@ -16,10 +16,10 @@
package java.nio;
+import android.system.ErrnoException;
import java.io.FileDescriptor;
import java.io.IOException;
import libcore.io.Libcore;
-import libcore.io.ErrnoException;
/**
* Used to implement java.nio read(ByteBuffer[])/write(ByteBuffer[]) operations as POSIX readv(2)
diff --git a/luni/src/main/java/java/nio/LongArrayBuffer.java b/luni/src/main/java/java/nio/LongArrayBuffer.java
index 6419d73..f03a91e 100644
--- a/luni/src/main/java/java/nio/LongArrayBuffer.java
+++ b/luni/src/main/java/java/nio/LongArrayBuffer.java
@@ -33,7 +33,7 @@ final class LongArrayBuffer extends LongBuffer {
}
private LongArrayBuffer(int capacity, long[] backingArray, int arrayOffset, boolean isReadOnly) {
- super(capacity);
+ super(capacity, 0);
this.backingArray = backingArray;
this.arrayOffset = arrayOffset;
this.isReadOnly = isReadOnly;
diff --git a/luni/src/main/java/java/nio/LongBuffer.java b/luni/src/main/java/java/nio/LongBuffer.java
index 55adab6..09f8418 100644
--- a/luni/src/main/java/java/nio/LongBuffer.java
+++ b/luni/src/main/java/java/nio/LongBuffer.java
@@ -80,7 +80,7 @@ public abstract class LongBuffer extends Buffer implements
* the length, must not be negative and not greater than
* {@code array.length - start}.
* @return the created long buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code longCount} is invalid.
*/
public static LongBuffer wrap(long[] array, int start, int longCount) {
@@ -91,8 +91,8 @@ public abstract class LongBuffer extends Buffer implements
return buf;
}
- LongBuffer(int capacity) {
- super(3, capacity, null);
+ LongBuffer(int capacity, long effectiveDirectAddress) {
+ super(3, capacity, effectiveDirectAddress);
}
public final long[] array() {
@@ -126,7 +126,7 @@ public abstract class LongBuffer extends Buffer implements
* limit is set to capacity; the mark is cleared.
*
* @return this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract LongBuffer compact();
@@ -140,7 +140,7 @@ public abstract class LongBuffer extends Buffer implements
* @return a negative value if this is less than {@code otherBuffer}; 0 if
* this equals to {@code otherBuffer}; a positive value if this is
* greater than {@code otherBuffer}
- * @exception ClassCastException
+ * @throws ClassCastException
* if {@code otherBuffer} is not a long buffer.
*/
public int compareTo(LongBuffer otherBuffer) {
@@ -212,7 +212,7 @@ public abstract class LongBuffer extends Buffer implements
* Returns the long at the current position and increase the position by 1.
*
* @return the long at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is equal or greater than limit.
*/
public abstract long get();
@@ -227,7 +227,7 @@ public abstract class LongBuffer extends Buffer implements
* @param dst
* the destination long array.
* @return this buffer.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code dst.length} is greater than {@code remaining()}.
*/
public LongBuffer get(long[] dst) {
@@ -248,9 +248,9 @@ public abstract class LongBuffer extends Buffer implements
* the number of longs to read, must be no less than zero and not
* greater than {@code dst.length - dstOffset}.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code dstOffset} or {@code longCount} is invalid.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code longCount} is greater than {@code remaining()}.
*/
public LongBuffer get(long[] dst, int dstOffset, int longCount) {
@@ -270,7 +270,7 @@ public abstract class LongBuffer extends Buffer implements
* @param index
* the index, must not be negative and less than limit.
* @return the long at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
*/
public abstract long get(int index);
@@ -349,9 +349,9 @@ public abstract class LongBuffer extends Buffer implements
* @param l
* the long to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is equal or greater than limit.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract LongBuffer put(long l);
@@ -366,9 +366,9 @@ public abstract class LongBuffer extends Buffer implements
* @param src
* the source long array.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code src.length}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public final LongBuffer put(long[] src) {
@@ -389,11 +389,11 @@ public abstract class LongBuffer extends Buffer implements
* the number of longs to write, must be no less than zero and
* not greater than {@code src.length - srcOffset}.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code longCount}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code srcOffset} or {@code longCount} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public LongBuffer put(long[] src, int srcOffset, int longCount) {
@@ -415,12 +415,12 @@ public abstract class LongBuffer extends Buffer implements
* @param src
* the source long buffer.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code src.remaining()} is greater than this buffer's
* {@code remaining()}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code src} is this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public LongBuffer put(LongBuffer src) {
@@ -448,9 +448,9 @@ public abstract class LongBuffer extends Buffer implements
* @param l
* the long to write.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract LongBuffer put(int index, long l);
diff --git a/luni/src/main/java/java/nio/MappedByteBuffer.java b/luni/src/main/java/java/nio/MappedByteBuffer.java
index 2d44d0f..ce19c0c 100644
--- a/luni/src/main/java/java/nio/MappedByteBuffer.java
+++ b/luni/src/main/java/java/nio/MappedByteBuffer.java
@@ -16,11 +16,11 @@
package java.nio;
+import android.system.ErrnoException;
import java.nio.channels.FileChannel.MapMode;
-import libcore.io.ErrnoException;
import libcore.io.Libcore;
-import libcore.io.Memory;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.MS_SYNC;
+import static android.system.OsConstants._SC_PAGE_SIZE;
/**
* {@code MappedByteBuffer} is a special kind of direct byte buffer which maps a
@@ -38,10 +38,12 @@ import static libcore.io.OsConstants.*;
*/
public abstract class MappedByteBuffer extends ByteBuffer {
final MapMode mapMode;
+ final MemoryBlock block;
- MappedByteBuffer(MemoryBlock block, int capacity, MapMode mapMode) {
- super(capacity, block);
+ MappedByteBuffer(MemoryBlock block, int capacity, MapMode mapMode, long effectiveDirectAddress) {
+ super(capacity, effectiveDirectAddress);
this.mapMode = mapMode;
+ this.block = block;
}
/**
diff --git a/luni/src/main/java/java/nio/MemoryBlock.java b/luni/src/main/java/java/nio/MemoryBlock.java
index 718b020..b62e3c6 100644
--- a/luni/src/main/java/java/nio/MemoryBlock.java
+++ b/luni/src/main/java/java/nio/MemoryBlock.java
@@ -17,14 +17,18 @@
package java.nio;
+import android.system.ErrnoException;
import dalvik.system.VMRuntime;
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.channels.FileChannel.MapMode;
-import libcore.io.ErrnoException;
import libcore.io.Libcore;
import libcore.io.Memory;
-import static libcore.io.OsConstants.*;
+
+import static android.system.OsConstants.MAP_PRIVATE;
+import static android.system.OsConstants.MAP_SHARED;
+import static android.system.OsConstants.PROT_READ;
+import static android.system.OsConstants.PROT_WRITE;
class MemoryBlock {
/**
@@ -44,8 +48,8 @@ class MemoryBlock {
// a state where munmap(2) could return an error.
throw new AssertionError(errnoException);
}
- address = 0;
}
+ super.free();
}
@Override protected void finalize() throws Throwable {
@@ -74,7 +78,7 @@ class MemoryBlock {
@Override public void free() {
array = null;
- address = 0;
+ super.free();
}
}
@@ -90,6 +94,8 @@ class MemoryBlock {
protected long address;
protected final long size;
+ private boolean accessible;
+ private boolean freed;
public static MemoryBlock mmap(FileDescriptor fd, long offset, long size, MapMode mapMode) throws IOException {
if (size == 0) {
@@ -134,6 +140,8 @@ class MemoryBlock {
private MemoryBlock(long address, long size) {
this.address = address;
this.size = size;
+ accessible = true;
+ freed = false;
}
// Used to support array/arrayOffset/hasArray for direct buffers.
@@ -142,6 +150,20 @@ class MemoryBlock {
}
public void free() {
+ address = 0;
+ freed = true;
+ }
+
+ public boolean isFreed() {
+ return freed;
+ }
+
+ public boolean isAccessible() {
+ return !isFreed() && accessible;
+ }
+
+ public final void setAccessible(boolean accessible) {
+ this.accessible = accessible;
}
public final void pokeByte(int offset, byte value) {
diff --git a/luni/src/main/java/java/nio/NIOAccess.java b/luni/src/main/java/java/nio/NIOAccess.java
index 12af44d..ddb102e 100644
--- a/luni/src/main/java/java/nio/NIOAccess.java
+++ b/luni/src/main/java/java/nio/NIOAccess.java
@@ -24,17 +24,11 @@ final class NIOAccess {
/**
* Returns the underlying native pointer to the data of the given
* Buffer starting at the Buffer's current position, or 0 if the
- * Buffer is not backed by native heap storage. Note that this is
- * different than what the Harmony implementation calls a "base
- * address."
- *
- * @param b the Buffer to be queried
- * @return the native pointer to the Buffer's data at its current
- * position, or 0 if there is none
+ * Buffer is not backed by native heap storage.
*/
static long getBasePointer(Buffer b) {
long address = b.effectiveDirectAddress;
- if (address == 0) {
+ if (address == 0L) {
return 0L;
}
return address + (b.position << b._elementSizeShift);
@@ -43,10 +37,6 @@ final class NIOAccess {
/**
* Returns the underlying Java array containing the data of the
* given Buffer, or null if the Buffer is not backed by a Java array.
- *
- * @param b the Buffer to be queried
- * @return the Java array containing the Buffer's data, or null if
- * there is none
*/
static Object getBaseArray(Buffer b) {
return b.hasArray() ? b.array() : null;
@@ -58,9 +48,6 @@ final class NIOAccess {
* the actual start of the data. The start of the data takes into
* account the Buffer's current position. This method is only
* meaningful if getBaseArray() returns non-null.
- *
- * @param b the Buffer to be queried
- * @return the data offset in bytes to the start of this Buffer's data
*/
static int getBaseArrayOffset(Buffer b) {
return b.hasArray() ? ((b.arrayOffset() + b.position) << b._elementSizeShift) : 0;
diff --git a/luni/src/main/java/java/nio/NioUtils.java b/luni/src/main/java/java/nio/NioUtils.java
index a1a46b6..f2a0b10 100644
--- a/luni/src/main/java/java/nio/NioUtils.java
+++ b/luni/src/main/java/java/nio/NioUtils.java
@@ -16,8 +16,12 @@
package java.nio;
+import java.io.Closeable;
import java.io.FileDescriptor;
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
+import java.util.Set;
/**
* @hide internal use only
@@ -43,8 +47,8 @@ public final class NioUtils {
/**
* Helps bridge between io and nio.
*/
- public static FileChannel newFileChannel(Object stream, FileDescriptor fd, int mode) {
- return new FileChannelImpl(stream, fd, mode);
+ public static FileChannel newFileChannel(Closeable ioObject, FileDescriptor fd, int mode) {
+ return new FileChannelImpl(ioObject, fd, mode);
}
/**
diff --git a/luni/src/main/java/java/nio/PipeImpl.java b/luni/src/main/java/java/nio/PipeImpl.java
index d4dde3b..ebc8a91 100644
--- a/luni/src/main/java/java/nio/PipeImpl.java
+++ b/luni/src/main/java/java/nio/PipeImpl.java
@@ -16,16 +16,16 @@
package java.nio;
+import android.system.ErrnoException;
import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.channels.Pipe;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/*
* Implements {@link java.nio.channels.Pipe}.
diff --git a/luni/src/main/java/java/nio/SelectorImpl.java b/luni/src/main/java/java/nio/SelectorImpl.java
index d63fa63..45406b1 100644
--- a/luni/src/main/java/java/nio/SelectorImpl.java
+++ b/luni/src/main/java/java/nio/SelectorImpl.java
@@ -15,33 +15,38 @@
*/
package java.nio;
+import android.system.ErrnoException;
+import android.system.StructPollfd;
import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.IllegalSelectorException;
-import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
-import static java.nio.channels.SelectionKey.*;
import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.AbstractSelectionKey;
import java.nio.channels.spi.AbstractSelector;
import java.nio.channels.spi.SelectorProvider;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UnsafeArrayList;
-import libcore.io.ErrnoException;
import libcore.io.IoBridge;
import libcore.io.IoUtils;
import libcore.io.Libcore;
-import libcore.io.StructPollfd;
-import libcore.util.EmptyArray;
-import static libcore.io.OsConstants.*;
+
+import static android.system.OsConstants.EINTR;
+import static android.system.OsConstants.POLLERR;
+import static android.system.OsConstants.POLLHUP;
+import static android.system.OsConstants.POLLIN;
+import static android.system.OsConstants.POLLOUT;
+import static java.nio.channels.SelectionKey.OP_ACCEPT;
+import static java.nio.channels.SelectionKey.OP_CONNECT;
+import static java.nio.channels.SelectionKey.OP_READ;
+import static java.nio.channels.SelectionKey.OP_WRITE;
/*
* Default implementation of java.nio.channels.Selector
@@ -255,7 +260,7 @@ final class SelectorImpl extends AbstractSelector {
int ops = key.interestOpsNoCheck();
int selectedOps = 0;
- if ((pollFd.revents & POLLHUP) != 0) {
+ if ((pollFd.revents & POLLHUP) != 0 || (pollFd.revents & POLLERR) != 0) {
// If there was an error condition, we definitely want to wake listeners,
// regardless of what they're waiting for. Failure is always interesting.
selectedOps |= ops;
@@ -321,6 +326,7 @@ final class SelectorImpl extends AbstractSelector {
try {
Libcore.os.write(wakeupOut, new byte[] { 1 }, 0, 1);
} catch (ErrnoException ignored) {
+ } catch (InterruptedIOException ignored) {
}
return this;
}
diff --git a/luni/src/main/java/java/nio/ServerSocketChannelImpl.java b/luni/src/main/java/java/nio/ServerSocketChannelImpl.java
index 3fb61a3..ae33672 100644
--- a/luni/src/main/java/java/nio/ServerSocketChannelImpl.java
+++ b/luni/src/main/java/java/nio/ServerSocketChannelImpl.java
@@ -17,13 +17,13 @@
package java.nio;
+import android.system.ErrnoException;
import java.io.FileDescriptor;
import java.io.IOException;
-import java.net.PlainServerSocketImpl;
+import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
-import java.net.SocketImpl;
import java.net.SocketTimeoutException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.IllegalBlockingModeException;
@@ -31,9 +31,11 @@ import java.nio.channels.NotYetBoundException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
-import libcore.io.ErrnoException;
+import java.nio.channels.UnresolvedAddressException;
+import java.nio.channels.UnsupportedAddressTypeException;
+import java.util.Set;
import libcore.io.IoUtils;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* The default ServerSocketChannel.
@@ -41,31 +43,28 @@ import static libcore.io.OsConstants.*;
final class ServerSocketChannelImpl extends ServerSocketChannel implements FileDescriptorChannel {
private final ServerSocketAdapter socket;
- private final SocketImpl impl;
-
- private boolean isBound = false;
private final Object acceptLock = new Object();
public ServerSocketChannelImpl(SelectorProvider sp) throws IOException {
super(sp);
this.socket = new ServerSocketAdapter(this);
- this.impl = socket.getImpl$();
}
@Override public ServerSocket socket() {
return socket;
}
- @Override public SocketChannel accept() throws IOException {
+ @Override
+ public SocketChannel accept() throws IOException {
if (!isOpen()) {
throw new ClosedChannelException();
}
- if (!isBound) {
+ if (!socket.isBound()) {
throw new NotYetBoundException();
}
- // Create an empty socket channel. This will be populated by ServerSocketAdapter.accept.
+ // Create an empty socket channel. This will be populated by ServerSocketAdapter.implAccept.
SocketChannelImpl result = new SocketChannelImpl(provider(), false);
try {
begin();
@@ -81,9 +80,9 @@ final class ServerSocketChannelImpl extends ServerSocketChannel implements FileD
}
}
} finally {
- end(result.socket().isConnected());
+ end(result.isConnected());
}
- return result.socket().isConnected() ? result : null;
+ return result.isConnected() ? result : null;
}
private boolean shouldThrowSocketTimeoutExceptionFromAccept(SocketTimeoutException e) {
@@ -100,17 +99,19 @@ final class ServerSocketChannelImpl extends ServerSocketChannel implements FileD
}
@Override protected void implConfigureBlocking(boolean blocking) throws IOException {
- IoUtils.setBlocking(impl.getFD$(), blocking);
+ IoUtils.setBlocking(socket.getFD$(), blocking);
}
+ @Override
synchronized protected void implCloseSelectableChannel() throws IOException {
if (!socket.isClosed()) {
socket.close();
}
}
+ @Override
public FileDescriptor getFD() {
- return impl.getFD$();
+ return socket.getFD$();
}
private static class ServerSocketAdapter extends ServerSocket {
@@ -120,13 +121,8 @@ final class ServerSocketChannelImpl extends ServerSocketChannel implements FileD
this.channelImpl = aChannelImpl;
}
- @Override public void bind(SocketAddress localAddress, int backlog) throws IOException {
- super.bind(localAddress, backlog);
- channelImpl.isBound = true;
- }
-
@Override public Socket accept() throws IOException {
- if (!channelImpl.isBound) {
+ if (!isBound()) {
throw new IllegalBlockingModeException();
}
SocketChannel sc = channelImpl.accept();
@@ -142,9 +138,12 @@ final class ServerSocketChannelImpl extends ServerSocketChannel implements FileD
try {
synchronized (this) {
super.implAccept(clientSocket);
- clientSocketChannel.setConnected();
- clientSocketChannel.setBound(true);
- clientSocketChannel.finishAccept();
+
+ // Sync the client socket's associated channel state with the Socket and OS.
+ InetSocketAddress remoteAddress =
+ new InetSocketAddress(
+ clientSocket.getInetAddress(), clientSocket.getPort());
+ clientSocketChannel.onAccept(remoteAddress, false /* updateSocketState */);
}
connectOK = true;
} finally {
@@ -159,23 +158,17 @@ final class ServerSocketChannelImpl extends ServerSocketChannel implements FileD
return channelImpl;
}
- @Override public boolean isBound() {
- return channelImpl.isBound;
- }
-
- @Override public void bind(SocketAddress localAddress) throws IOException {
- super.bind(localAddress);
- channelImpl.isBound = true;
- }
-
@Override public void close() throws IOException {
synchronized (channelImpl) {
+ super.close();
if (channelImpl.isOpen()) {
channelImpl.close();
- } else {
- super.close();
}
}
}
+
+ private FileDescriptor getFD$() {
+ return super.getImpl$().getFD$();
+ }
}
}
diff --git a/luni/src/main/java/java/nio/ShortArrayBuffer.java b/luni/src/main/java/java/nio/ShortArrayBuffer.java
index a092cb0..3c41174 100644
--- a/luni/src/main/java/java/nio/ShortArrayBuffer.java
+++ b/luni/src/main/java/java/nio/ShortArrayBuffer.java
@@ -33,7 +33,7 @@ final class ShortArrayBuffer extends ShortBuffer {
}
private ShortArrayBuffer(int capacity, short[] backingArray, int arrayOffset, boolean isReadOnly) {
- super(capacity);
+ super(capacity, 0);
this.backingArray = backingArray;
this.arrayOffset = arrayOffset;
this.isReadOnly = isReadOnly;
diff --git a/luni/src/main/java/java/nio/ShortBuffer.java b/luni/src/main/java/java/nio/ShortBuffer.java
index 8da01ed..cbc5a47 100644
--- a/luni/src/main/java/java/nio/ShortBuffer.java
+++ b/luni/src/main/java/java/nio/ShortBuffer.java
@@ -80,7 +80,7 @@ public abstract class ShortBuffer extends Buffer implements
* the length, must not be negative and not greater than
* {@code array.length - start}.
* @return the created short buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code start} or {@code shortCount} is invalid.
*/
public static ShortBuffer wrap(short[] array, int start, int shortCount) {
@@ -91,8 +91,8 @@ public abstract class ShortBuffer extends Buffer implements
return buf;
}
- ShortBuffer(int capacity) {
- super(1, capacity, null);
+ ShortBuffer(int capacity, long effectiveDirectAddress) {
+ super(1, capacity, effectiveDirectAddress);
}
public final short[] array() {
@@ -126,7 +126,7 @@ public abstract class ShortBuffer extends Buffer implements
* limit is set to capacity; the mark is cleared.
*
* @return this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ShortBuffer compact();
@@ -140,7 +140,7 @@ public abstract class ShortBuffer extends Buffer implements
* @return a negative value if this is less than {@code otherBuffer}; 0 if
* this equals to {@code otherBuffer}; a positive value if this is
* greater than {@code otherBuffer}.
- * @exception ClassCastException
+ * @throws ClassCastException
* if {@code otherBuffer} is not a short buffer.
*/
public int compareTo(ShortBuffer otherBuffer) {
@@ -213,7 +213,7 @@ public abstract class ShortBuffer extends Buffer implements
* 1.
*
* @return the short at the current position.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if the position is equal or greater than limit.
*/
public abstract short get();
@@ -228,7 +228,7 @@ public abstract class ShortBuffer extends Buffer implements
* @param dst
* the destination short array.
* @return this buffer.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code dst.length} is greater than {@code remaining()}.
*/
public ShortBuffer get(short[] dst) {
@@ -249,9 +249,9 @@ public abstract class ShortBuffer extends Buffer implements
* the number of shorts to read, must be no less than zero and
* not greater than {@code dst.length - dstOffset}.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code dstOffset} or {@code shortCount} is invalid.
- * @exception BufferUnderflowException
+ * @throws BufferUnderflowException
* if {@code shortCount} is greater than {@code remaining()}.
*/
public ShortBuffer get(short[] dst, int dstOffset, int shortCount) {
@@ -271,7 +271,7 @@ public abstract class ShortBuffer extends Buffer implements
* @param index
* the index, must not be negative and less than limit.
* @return a short at the specified index.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
*/
public abstract short get(int index);
@@ -348,9 +348,9 @@ public abstract class ShortBuffer extends Buffer implements
* @param s
* the short to write.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if position is equal or greater than limit.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ShortBuffer put(short s);
@@ -365,9 +365,9 @@ public abstract class ShortBuffer extends Buffer implements
* @param src
* the source short array.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code src.length}.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public final ShortBuffer put(short[] src) {
@@ -388,11 +388,11 @@ public abstract class ShortBuffer extends Buffer implements
* the number of shorts to write, must be no less than zero and
* not greater than {@code src.length - srcOffset}.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code remaining()} is less than {@code shortCount}.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if either {@code srcOffset} or {@code shortCount} is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public ShortBuffer put(short[] src, int srcOffset, int shortCount) {
@@ -414,12 +414,12 @@ public abstract class ShortBuffer extends Buffer implements
* @param src
* the source short buffer.
* @return this buffer.
- * @exception BufferOverflowException
+ * @throws BufferOverflowException
* if {@code src.remaining()} is greater than this buffer's
* {@code remaining()}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code src} is this buffer.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public ShortBuffer put(ShortBuffer src) {
@@ -447,9 +447,9 @@ public abstract class ShortBuffer extends Buffer implements
* @param s
* the short to write.
* @return this buffer.
- * @exception IndexOutOfBoundsException
+ * @throws IndexOutOfBoundsException
* if index is invalid.
- * @exception ReadOnlyBufferException
+ * @throws ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
*/
public abstract ShortBuffer put(int index, short s);
diff --git a/luni/src/main/java/java/nio/SocketChannelImpl.java b/luni/src/main/java/java/nio/SocketChannelImpl.java
index 714005f..d5cb716 100644
--- a/luni/src/main/java/java/nio/SocketChannelImpl.java
+++ b/luni/src/main/java/java/nio/SocketChannelImpl.java
@@ -17,9 +17,12 @@
package java.nio;
+import android.system.ErrnoException;
import java.io.FileDescriptor;
-import java.io.IOException;
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
import java.io.InputStream;
+import java.io.IOException;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.Inet4Address;
@@ -30,7 +33,6 @@ import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketUtils;
-import java.net.UnknownHostException;
import java.nio.channels.AlreadyConnectedException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ConnectionPendingException;
@@ -38,15 +40,15 @@ import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.NoConnectionPendingException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.SelectorProvider;
import java.nio.channels.UnresolvedAddressException;
import java.nio.channels.UnsupportedAddressTypeException;
-import java.nio.channels.spi.SelectorProvider;
import java.util.Arrays;
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
+import java.util.Set;
import libcore.io.IoBridge;
import libcore.io.IoUtils;
-import static libcore.io.OsConstants.*;
+import libcore.io.Libcore;
+import static android.system.OsConstants.*;
/*
* The default implementation class of java.nio.channels.SocketChannel.
@@ -74,6 +76,7 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
// The address to be connected.
private InetSocketAddress connectAddress = null;
+ // The local address the socket is bound to.
private InetAddress localAddress = null;
private int localPort;
@@ -133,20 +136,34 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
return socket;
}
- @Override
- synchronized public boolean isConnected() {
- return status == SOCKET_STATUS_CONNECTED;
- }
-
- /*
- * Status setting used by other class.
+ /**
+ * Initialise the isBound, localAddress and localPort state from the file descriptor. Used when
+ * some or all of the bound state has been left to the OS to decide, or when the Socket handled
+ * bind() or connect().
+ *
+ * @param updateSocketState
+ * if the associated socket (if present) needs to be updated
+ * @hide package visible for other nio classes
*/
- synchronized void setConnected() {
- status = SOCKET_STATUS_CONNECTED;
+ void onBind(boolean updateSocketState) {
+ SocketAddress sa;
+ try {
+ sa = Libcore.os.getsockname(fd);
+ } catch (ErrnoException errnoException) {
+ throw new AssertionError(errnoException);
+ }
+ isBound = true;
+ InetSocketAddress localSocketAddress = (InetSocketAddress) sa;
+ localAddress = localSocketAddress.getAddress();
+ localPort = localSocketAddress.getPort();
+ if (updateSocketState && socket != null) {
+ socket.onBind(localAddress, localPort);
+ }
}
- void setBound(boolean flag) {
- isBound = flag;
+ @Override
+ synchronized public boolean isConnected() {
+ return status == SOCKET_STATUS_CONNECTED;
}
@Override
@@ -169,16 +186,22 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
normalAddr = InetAddress.getLocalHost();
}
+ boolean isBlocking = isBlocking();
boolean finished = false;
+ int newStatus;
try {
- if (isBlocking()) {
+ if (isBlocking) {
begin();
}
- finished = IoBridge.connect(fd, normalAddr, port);
- isBound = finished;
+ // When in blocking mode, IoBridge.connect() will return without an exception when the
+ // socket is connected. When in non-blocking mode it will return without an exception
+ // without knowing the result of the connection attempt, which could still be going on.
+ IoBridge.connect(fd, normalAddr, port);
+ newStatus = isBlocking ? SOCKET_STATUS_CONNECTED : SOCKET_STATUS_PENDING;
+ finished = true;
} catch (IOException e) {
if (isEINPROGRESS(e)) {
- status = SOCKET_STATUS_PENDING;
+ newStatus = SOCKET_STATUS_PENDING;
} else {
if (isOpen()) {
close();
@@ -187,26 +210,36 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
throw e;
}
} finally {
- if (isBlocking()) {
+ if (isBlocking) {
end(finished);
}
}
- initLocalAddressAndPort();
- connectAddress = inetSocketAddress;
- if (socket != null) {
- socket.socketImpl().initRemoteAddressAndPort(connectAddress.getAddress(),
- connectAddress.getPort());
+ // If the channel was not bound, a connection attempt will have caused an implicit bind() to
+ // take place. Keep the local address state held by the channel and the socket up to date.
+ if (!isBound) {
+ onBind(true /* updateSocketState */);
}
- synchronized (this) {
- if (isBlocking()) {
- status = (finished ? SOCKET_STATUS_CONNECTED : SOCKET_STATUS_UNCONNECTED);
- } else {
- status = SOCKET_STATUS_PENDING;
- }
+ // Keep the connected state held by the channel and the socket up to date.
+ onConnectStatusChanged(inetSocketAddress, newStatus, true /* updateSocketState */);
+
+ return status == SOCKET_STATUS_CONNECTED;
+ }
+
+ /**
+ * Initialise the connect() state with the supplied information.
+ *
+ * @param updateSocketState
+ * if the associated socket (if present) needs to be updated
+ * @hide package visible for other nio classes
+ */
+ void onConnectStatusChanged(InetSocketAddress address, int status, boolean updateSocketState) {
+ this.status = status;
+ connectAddress = address;
+ if (status == SOCKET_STATUS_CONNECTED && updateSocketState && socket != null) {
+ socket.onConnect(connectAddress.getAddress(), connectAddress.getPort());
}
- return finished;
}
private boolean isEINPROGRESS(IOException e) {
@@ -222,21 +255,6 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
return false;
}
- private void initLocalAddressAndPort() {
- SocketAddress sa;
- try {
- sa = Libcore.os.getsockname(fd);
- } catch (ErrnoException errnoException) {
- throw new AssertionError(errnoException);
- }
- InetSocketAddress isa = (InetSocketAddress) sa;
- localAddress = isa.getAddress();
- localPort = isa.getPort();
- if (socket != null) {
- socket.socketImpl().initLocalPort(localPort);
- }
- }
-
@Override
public boolean finishConnect() throws IOException {
synchronized (this) {
@@ -257,7 +275,6 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
InetAddress inetAddress = connectAddress.getAddress();
int port = connectAddress.getPort();
finished = IoBridge.isConnected(fd, inetAddress, port, 0, 0); // Return immediately.
- isBound = finished;
} catch (ConnectException e) {
if (isOpen()) {
close();
@@ -270,15 +287,13 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
synchronized (this) {
status = (finished ? SOCKET_STATUS_CONNECTED : status);
- isBound = finished;
+ if (finished && socket != null) {
+ socket.onConnect(connectAddress.getAddress(), connectAddress.getPort());
+ }
}
return finished;
}
- void finishAccept() {
- initLocalAddressAndPort();
- }
-
@Override
public int read(ByteBuffer dst) throws IOException {
dst.checkWritable();
@@ -447,23 +462,17 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
}
/*
- * Get local address.
- */
- public InetAddress getLocalAddress() throws UnknownHostException {
- return isBound ? localAddress : Inet4Address.ANY;
- }
-
- /*
* Do really closing action here.
*/
@Override
protected synchronized void implCloseSelectableChannel() throws IOException {
if (status != SOCKET_STATUS_CLOSED) {
status = SOCKET_STATUS_CLOSED;
+ // IoBridge.closeAndSignalBlockedThreads(fd) is idempotent: It is safe to call on an
+ // already-closed file descriptor.
+ IoBridge.closeAndSignalBlockedThreads(fd);
if (socket != null && !socket.isClosed()) {
- socket.close();
- } else {
- IoBridge.closeSocket(fd);
+ socket.onClose();
}
}
}
@@ -479,6 +488,12 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
return fd;
}
+ /* @hide used by ServerSocketChannelImpl to sync channel state during accept() */
+ public void onAccept(InetSocketAddress remoteAddress, boolean updateSocketState) {
+ onBind(updateSocketState);
+ onConnectStatusChanged(remoteAddress, SOCKET_STATUS_CONNECTED, updateSocketState);
+ }
+
/*
* Adapter classes for internal socket.
*/
@@ -486,15 +501,24 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
private final SocketChannelImpl channel;
private final PlainSocketImpl socketImpl;
- SocketAdapter(PlainSocketImpl socketImpl, SocketChannelImpl channel) throws SocketException {
+ SocketAdapter(PlainSocketImpl socketImpl, SocketChannelImpl channel)
+ throws SocketException {
super(socketImpl);
this.socketImpl = socketImpl;
this.channel = channel;
SocketUtils.setCreated(this);
- }
- PlainSocketImpl socketImpl() {
- return socketImpl;
+ // Sync state socket state with the channel it is being created from
+ if (channel.isBound) {
+ onBind(channel.localAddress, channel.localPort);
+ }
+ if (channel.isConnected()) {
+ onConnect(channel.connectAddress.getAddress(), channel.connectAddress.getPort());
+ }
+ if (!channel.isOpen()) {
+ onClose();
+ }
+
}
@Override
@@ -503,25 +527,6 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
}
@Override
- public boolean isBound() {
- return channel.isBound;
- }
-
- @Override
- public boolean isConnected() {
- return channel.isConnected();
- }
-
- @Override
- public InetAddress getLocalAddress() {
- try {
- return channel.getLocalAddress();
- } catch (UnknownHostException e) {
- return null;
- }
- }
-
- @Override
public void connect(SocketAddress remoteAddr, int timeout) throws IOException {
if (!channel.isBlocking()) {
throw new IllegalBlockingModeException();
@@ -530,10 +535,11 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
throw new AlreadyConnectedException();
}
super.connect(remoteAddr, timeout);
- channel.initLocalAddressAndPort();
+ channel.onBind(false);
if (super.isConnected()) {
- channel.setConnected();
- channel.isBound = super.isBound();
+ InetSocketAddress remoteInetAddress = (InetSocketAddress) remoteAddr;
+ channel.onConnectStatusChanged(
+ remoteInetAddress, SOCKET_STATUS_CONNECTED, false /* updateSocketState */);
}
}
@@ -546,47 +552,29 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
throw new ConnectionPendingException();
}
super.bind(localAddr);
- channel.initLocalAddressAndPort();
- channel.isBound = true;
+ channel.onBind(false);
}
@Override
public void close() throws IOException {
synchronized (channel) {
+ super.close();
if (channel.isOpen()) {
+ // channel.close() recognizes the socket is closed and avoids recursion. There
+ // is no channel.onClose() because the "closed" field is private.
channel.close();
- } else {
- super.close();
}
- channel.status = SocketChannelImpl.SOCKET_STATUS_CLOSED;
}
}
@Override
public OutputStream getOutputStream() throws IOException {
- checkOpenAndConnected();
- if (isOutputShutdown()) {
- throw new SocketException("Socket output is shutdown");
- }
- return new SocketChannelOutputStream(channel);
+ return new BlockingCheckOutputStream(super.getOutputStream(), channel);
}
@Override
public InputStream getInputStream() throws IOException {
- checkOpenAndConnected();
- if (isInputShutdown()) {
- throw new SocketException("Socket input is shutdown");
- }
- return new SocketChannelInputStream(channel);
- }
-
- private void checkOpenAndConnected() throws SocketException {
- if (!channel.isOpen()) {
- throw new SocketException("Socket is closed");
- }
- if (!channel.isConnected()) {
- throw new SocketException("Socket is not connected");
- }
+ return new BlockingCheckInputStream(super.getInputStream(), channel);
}
@Override
@@ -596,86 +584,92 @@ class SocketChannelImpl extends SocketChannel implements FileDescriptorChannel {
}
/*
- * This output stream delegates all operations to the associated channel.
* Throws an IllegalBlockingModeException if the channel is in non-blocking
* mode when performing write operations.
*/
- private static class SocketChannelOutputStream extends OutputStream {
+ private static class BlockingCheckOutputStream extends FilterOutputStream {
private final SocketChannel channel;
- public SocketChannelOutputStream(SocketChannel channel) {
+ public BlockingCheckOutputStream(OutputStream out, SocketChannel channel) {
+ super(out);
this.channel = channel;
}
- /*
- * Closes this stream and channel.
- *
- * @exception IOException thrown if an error occurs during the close
- */
@Override
- public void close() throws IOException {
- channel.close();
+ public void write(byte[] buffer, int offset, int byteCount) throws IOException {
+ checkBlocking();
+ out.write(buffer, offset, byteCount);
}
@Override
- public void write(byte[] buffer, int offset, int byteCount) throws IOException {
- Arrays.checkOffsetAndCount(buffer.length, offset, byteCount);
- ByteBuffer buf = ByteBuffer.wrap(buffer, offset, byteCount);
- if (!channel.isBlocking()) {
- throw new IllegalBlockingModeException();
- }
- channel.write(buf);
+ public void write(int oneByte) throws IOException {
+ checkBlocking();
+ out.write(oneByte);
}
@Override
- public void write(int oneByte) throws IOException {
+ public void write(byte[] buffer) throws IOException {
+ checkBlocking();
+ out.write(buffer);
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ // channel.close() recognizes the socket is closed and avoids recursion. There is no
+ // channel.onClose() because the "closed" field is private.
+ channel.close();
+ }
+
+ private void checkBlocking() {
if (!channel.isBlocking()) {
throw new IllegalBlockingModeException();
}
- ByteBuffer buffer = ByteBuffer.allocate(1);
- buffer.put(0, (byte) (oneByte & 0xFF));
- channel.write(buffer);
}
}
/*
- * This input stream delegates all operations to the associated channel.
* Throws an IllegalBlockingModeException if the channel is in non-blocking
* mode when performing read operations.
*/
- private static class SocketChannelInputStream extends InputStream {
+ private static class BlockingCheckInputStream extends FilterInputStream {
private final SocketChannel channel;
- public SocketChannelInputStream(SocketChannel channel) {
+ public BlockingCheckInputStream(InputStream in, SocketChannel channel) {
+ super(in);
this.channel = channel;
}
- /*
- * Closes this stream and channel.
- */
@Override
- public void close() throws IOException {
- channel.close();
+ public int read() throws IOException {
+ checkBlocking();
+ return in.read();
}
@Override
- public int read() throws IOException {
- if (!channel.isBlocking()) {
- throw new IllegalBlockingModeException();
- }
- ByteBuffer buf = ByteBuffer.allocate(1);
- int result = channel.read(buf);
- return (result == -1) ? result : (buf.get(0) & 0xff);
+ public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
+ checkBlocking();
+ return in.read(buffer, byteOffset, byteCount);
}
@Override
- public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
- Arrays.checkOffsetAndCount(buffer.length, byteOffset, byteCount);
+ public int read(byte[] buffer) throws IOException {
+ checkBlocking();
+ return in.read(buffer);
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ // channel.close() recognizes the socket is closed and avoids recursion. There is no
+ // channel.onClose() because the "closed" field is private.
+ channel.close();
+ }
+
+ private void checkBlocking() {
if (!channel.isBlocking()) {
throw new IllegalBlockingModeException();
}
- ByteBuffer buf = ByteBuffer.wrap(buffer, byteOffset, byteCount);
- return channel.read(buf);
}
}
}
diff --git a/luni/src/main/java/java/nio/channels/DatagramChannel.java b/luni/src/main/java/java/nio/channels/DatagramChannel.java
index 486b168..2cff7f0 100644
--- a/luni/src/main/java/java/nio/channels/DatagramChannel.java
+++ b/luni/src/main/java/java/nio/channels/DatagramChannel.java
@@ -19,10 +19,13 @@ package java.nio.channels;
import java.io.IOException;
import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
+import java.util.Set;
/**
* A {@code DatagramChannel} is a selectable channel that represents a partial
diff --git a/luni/src/main/java/java/nio/channels/FileChannel.java b/luni/src/main/java/java/nio/channels/FileChannel.java
index 298ea8b..d6c140b 100644
--- a/luni/src/main/java/java/nio/channels/FileChannel.java
+++ b/luni/src/main/java/java/nio/channels/FileChannel.java
@@ -77,7 +77,7 @@ import java.nio.channels.spi.AbstractInterruptibleChannel;
* content, size, etc.
*/
public abstract class FileChannel extends AbstractInterruptibleChannel
- implements GatheringByteChannel, ScatteringByteChannel, ByteChannel {
+ implements ByteChannel, GatheringByteChannel, ScatteringByteChannel {
/**
* {@code MapMode} defines file mapping mode constants.
@@ -281,10 +281,9 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
long position, long size) throws IOException;
/**
- * Returns the current value of the file position pointer.
+ * Returns the current position as a positive integer number of bytes from
+ * the start of the file.
*
- * @return the current position as a positive integer number of bytes from
- * the start of the file.
* @throws ClosedChannelException
* if this channel is closed.
* @throws IOException
@@ -302,9 +301,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* succeed but they will fill the bytes between the current end of file and
* the new position with the required number of (unspecified) byte values.
*
- * @param offset
- * the new file position, in bytes.
- * @return the receiver.
+ * @return this.
* @throws IllegalArgumentException
* if the new position is negative.
* @throws ClosedChannelException
@@ -312,7 +309,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @throws IOException
* if another I/O error occurs.
*/
- public abstract FileChannel position(long offset) throws IOException;
+ public abstract FileChannel position(long newPosition) throws IOException;
/**
* Reads bytes from this file channel into the given buffer.
@@ -362,7 +359,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* the buffer to receive the bytes.
* @param position
* the (non-negative) position at which to read the bytes.
- * @return the number of bytes actually read.
+ * @return the number of bytes actually read, or -1 if the end of the file has been reached.
* @throws AsynchronousCloseException
* if this channel is closed by another thread while this method
* is executing.
@@ -398,7 +395,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
*
* @param buffers
* the array of byte buffers into which the bytes will be copied.
- * @return the number of bytes actually read.
+ * @return the number of bytes actually read, or -1 if the end of the file has been reached.
* @throws AsynchronousCloseException
* if this channel is closed by another thread during this read
* operation.
@@ -413,6 +410,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* if the channel has not been opened in a mode that permits
* reading.
*/
+ @Override
public final long read(ByteBuffer[] buffers) throws IOException {
return read(buffers, 0, buffers.length);
}
@@ -433,7 +431,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* the index of the first buffer to store bytes in.
* @param number
* the maximum number of buffers to store bytes in.
- * @return the number of bytes actually read.
+ * @return the number of bytes actually read, or -1 if the end of the file has been reached.
* @throws AsynchronousCloseException
* if this channel is closed by another thread during this read
* operation.
@@ -458,7 +456,6 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
/**
* Returns the size of the file underlying this channel in bytes.
*
- * @return the size of the file in bytes.
* @throws ClosedChannelException
* if this channel is closed.
* @throws IOException
@@ -712,6 +709,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @throws NonWritableChannelException
* if this channel was not opened for writing.
*/
+ @Override
public final long write(ByteBuffer[] buffers) throws IOException {
return write(buffers, 0, buffers.length);
}
@@ -752,6 +750,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @throws NonWritableChannelException
* if this channel was not opened for writing.
*/
+ @Override
public abstract long write(ByteBuffer[] buffers, int offset, int length)
throws IOException;
}
diff --git a/luni/src/main/java/java/nio/channels/FileLock.java b/luni/src/main/java/java/nio/channels/FileLock.java
index 360f826..5b26475 100644
--- a/luni/src/main/java/java/nio/channels/FileLock.java
+++ b/luni/src/main/java/java/nio/channels/FileLock.java
@@ -108,8 +108,6 @@ public abstract class FileLock implements AutoCloseable {
/**
* Returns the lock's {@link FileChannel}.
- *
- * @return the channel.
*/
public final FileChannel channel() {
return channel;
diff --git a/luni/src/main/java/java/nio/channels/ServerSocketChannel.java b/luni/src/main/java/java/nio/channels/ServerSocketChannel.java
index f3c3390..ef50155 100644
--- a/luni/src/main/java/java/nio/channels/ServerSocketChannel.java
+++ b/luni/src/main/java/java/nio/channels/ServerSocketChannel.java
@@ -19,8 +19,10 @@ package java.nio.channels;
import java.io.IOException;
import java.net.ServerSocket;
+import java.net.SocketAddress;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
+import java.util.Set;
/**
* A {@code ServerSocketChannel} is a partial abstraction of a selectable,
@@ -35,7 +37,6 @@ import java.nio.channels.spi.SelectorProvider;
* related {@code ServerSocket} instance.
*/
public abstract class ServerSocketChannel extends AbstractSelectableChannel {
-
/**
* Constructs a new {@link ServerSocketChannel}.
*
diff --git a/luni/src/main/java/java/nio/channels/SocketChannel.java b/luni/src/main/java/java/nio/channels/SocketChannel.java
index 753c88f..a91fccd 100644
--- a/luni/src/main/java/java/nio/channels/SocketChannel.java
+++ b/luni/src/main/java/java/nio/channels/SocketChannel.java
@@ -23,36 +23,44 @@ import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
+import java.util.Set;
/**
* A {@code SocketChannel} is a selectable channel that provides a partial
- * abstraction of stream connecting socket. {@code socket()} returns the related
- * {@link Socket} instance which can handle the socket.
- * <p>
- * A socket channel is open but not connected when created by {@code open()}.
- * After connecting it by calling {@code connect(SocketAddress)}, it will remain
- * connected until it gets closed. If the connection is non-blocking then
- * {@code connect(SocketAddress)} is used to initiate the connection, followed
- * by a call of {@code finishConnect()} to perform the final steps of
- * connecting. {@code isConnectionPending()} indicates if the connection is
- * blocked or not; {@code isConnected()} indicates if the socket is finally
- * connected or not.
- * <p>
- * The input and output sides of a channel can be shut down independently and
- * asynchronously without closing the channel. The {@code shutdownInput} method
+ * abstraction of stream connecting socket.
+ *
+ * The {@link #socket()} method returns a {@link Socket} instance which
+ * allows a wider range of socket operations than {@code SocketChannel} itself.
+ *
+ * <p>A socket channel is open but not connected when created by {@link #open}.
+ * After connecting it by calling {@link #connect(SocketAddress)}, it will remain
+ * connected until closed.
+ *
+ * <p>If the connection is non-blocking then
+ * {@link #connect(SocketAddress)} is used to initiate the connection, followed
+ * by a call of {@link #finishConnect} to perform the final steps of
+ * connecting. {@link #isConnectionPending} to tests whether we're still
+ * trying to connect; {@link #isConnected} tests whether the socket connect
+ * completed successfully. Note that realistic code should use a {@link Selector}
+ * instead of polling. Note also that {@link java.net.Socket} can connect with a
+ * timeout, which is the most common use for a non-blocking connect.
+ *
+ * <p>The input and output sides of a channel can be shut down independently and
+ * asynchronously without closing the channel. The {@link Socket#shutdownInput} method
+ * on the socket returned by {@link #socket}
* is used for the input side of a channel and subsequent read operations return
* -1, which means end of stream. If another thread is blocked in a read
* operation when the shutdown occurs, the read will end without effect and
- * return end of stream. The {@code shutdownOutput} method is used for the
+ * return end of stream. Likewise the {@link Socket#shutdownOutput} method is used for the
* output side of the channel; subsequent write operations throw a
* {@link ClosedChannelException}. If the output is shut down and another thread
* is blocked in a write operation, an {@link AsynchronousCloseException} will
* be thrown to the pending thread.
- * <p>
- * Socket channels are thread-safe, no more than one thread can read or write at
- * any given time. The {@code connect(SocketAddress)} and {@code
- * finishConnect()} methods are synchronized against each other; when they are
- * processing, calls to {@code read} and {@code write} will block.
+ *
+ * <p>Socket channels are thread-safe, no more than one thread can read or write at
+ * any given time. The {@link #connect(SocketAddress)} and {@link
+ * #finishConnect()} methods are synchronized against each other; when they are
+ * processing, calls to {@link #read} and {@link #write} will block.
*/
public abstract class SocketChannel extends AbstractSelectableChannel implements
ByteChannel, ScatteringByteChannel, GatheringByteChannel {
diff --git a/luni/src/main/java/java/nio/charset/CharsetDecoderICU.java b/luni/src/main/java/java/nio/charset/CharsetDecoderICU.java
index 8b32efa..5dfdd9f 100644
--- a/luni/src/main/java/java/nio/charset/CharsetDecoderICU.java
+++ b/luni/src/main/java/java/nio/charset/CharsetDecoderICU.java
@@ -25,13 +25,13 @@ final class CharsetDecoderICU extends CharsetDecoder {
private static final int INPUT_OFFSET = 0;
private static final int OUTPUT_OFFSET = 1;
- private static final int INVALID_BYTES = 2;
+ private static final int INVALID_BYTE_COUNT = 2;
/*
* data[INPUT_OFFSET] = on input contains the start of input and on output the number of input bytes consumed
* data[OUTPUT_OFFSET] = on input contains the start of output and on output the number of output chars written
- * data[INVALID_BYTES] = number of invalid bytes
+ * data[INVALID_BYTE_COUNT] = number of invalid bytes
*/
- private int[] data = new int[3];
+ private final int[] data = new int[3];
/* handle to the ICU converter that is opened */
private long converterHandle = 0;
@@ -90,7 +90,7 @@ final class CharsetDecoderICU extends CharsetDecoder {
NativeConverter.resetByteToChar(converterHandle);
data[INPUT_OFFSET] = 0;
data[OUTPUT_OFFSET] = 0;
- data[INVALID_BYTES] = 0;
+ data[INVALID_BYTE_COUNT] = 0;
output = null;
input = null;
allocatedInput = null;
@@ -107,15 +107,15 @@ final class CharsetDecoderICU extends CharsetDecoder {
data[INPUT_OFFSET] = 0;
data[OUTPUT_OFFSET] = getArray(out);
- data[INVALID_BYTES] = 0; // Make sure we don't see earlier errors.
+ data[INVALID_BYTE_COUNT] = 0; // Make sure we don't see earlier errors.
int error = NativeConverter.decode(converterHandle, input, inEnd, output, outEnd, data, true);
if (ICU.U_FAILURE(error)) {
if (error == ICU.U_BUFFER_OVERFLOW_ERROR) {
return CoderResult.OVERFLOW;
} else if (error == ICU.U_TRUNCATED_CHAR_FOUND) {
- if (data[INPUT_OFFSET] > 0) {
- return CoderResult.malformedForLength(data[INPUT_OFFSET]);
+ if (data[INVALID_BYTE_COUNT] > 0) {
+ return CoderResult.malformedForLength(data[INVALID_BYTE_COUNT]);
}
}
}
@@ -140,9 +140,9 @@ final class CharsetDecoderICU extends CharsetDecoder {
if (error == ICU.U_BUFFER_OVERFLOW_ERROR) {
return CoderResult.OVERFLOW;
} else if (error == ICU.U_INVALID_CHAR_FOUND) {
- return CoderResult.unmappableForLength(data[INVALID_BYTES]);
+ return CoderResult.unmappableForLength(data[INVALID_BYTE_COUNT]);
} else if (error == ICU.U_ILLEGAL_CHAR_FOUND) {
- return CoderResult.malformedForLength(data[INVALID_BYTES]);
+ return CoderResult.malformedForLength(data[INVALID_BYTE_COUNT]);
} else {
throw new AssertionError(error);
}
diff --git a/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java b/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java
index 4bc4354..3583e19 100644
--- a/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java
+++ b/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java
@@ -40,7 +40,7 @@ final class CharsetEncoderICU extends CharsetEncoder {
private static final int INPUT_OFFSET = 0;
private static final int OUTPUT_OFFSET = 1;
- private static final int INVALID_CHARS = 2;
+ private static final int INVALID_CHAR_COUNT = 2;
/*
* data[INPUT_OFFSET] = on input contains the start of input and on output the number of input chars consumed
* data[OUTPUT_OFFSET] = on input contains the start of output and on output the number of output bytes written
@@ -118,7 +118,7 @@ final class CharsetEncoderICU extends CharsetEncoder {
NativeConverter.resetCharToByte(converterHandle);
data[INPUT_OFFSET] = 0;
data[OUTPUT_OFFSET] = 0;
- data[INVALID_CHARS] = 0;
+ data[INVALID_CHAR_COUNT] = 0;
output = null;
input = null;
allocatedInput = null;
@@ -135,15 +135,15 @@ final class CharsetEncoderICU extends CharsetEncoder {
data[INPUT_OFFSET] = 0;
data[OUTPUT_OFFSET] = getArray(out);
- data[INVALID_CHARS] = 0; // Make sure we don't see earlier errors.
+ data[INVALID_CHAR_COUNT] = 0; // Make sure we don't see earlier errors.
int error = NativeConverter.encode(converterHandle, input, inEnd, output, outEnd, data, true);
if (ICU.U_FAILURE(error)) {
if (error == ICU.U_BUFFER_OVERFLOW_ERROR) {
return CoderResult.OVERFLOW;
} else if (error == ICU.U_TRUNCATED_CHAR_FOUND) {
- if (data[INPUT_OFFSET] > 0) {
- return CoderResult.malformedForLength(data[INPUT_OFFSET]);
+ if (data[INVALID_CHAR_COUNT] > 0) {
+ return CoderResult.malformedForLength(data[INVALID_CHAR_COUNT]);
}
}
}
@@ -161,7 +161,7 @@ final class CharsetEncoderICU extends CharsetEncoder {
data[INPUT_OFFSET] = getArray(in);
data[OUTPUT_OFFSET]= getArray(out);
- data[INVALID_CHARS] = 0; // Make sure we don't see earlier errors.
+ data[INVALID_CHAR_COUNT] = 0; // Make sure we don't see earlier errors.
try {
int error = NativeConverter.encode(converterHandle, input, inEnd, output, outEnd, data, false);
@@ -169,9 +169,9 @@ final class CharsetEncoderICU extends CharsetEncoder {
if (error == ICU.U_BUFFER_OVERFLOW_ERROR) {
return CoderResult.OVERFLOW;
} else if (error == ICU.U_INVALID_CHAR_FOUND) {
- return CoderResult.unmappableForLength(data[INVALID_CHARS]);
+ return CoderResult.unmappableForLength(data[INVALID_CHAR_COUNT]);
} else if (error == ICU.U_ILLEGAL_CHAR_FOUND) {
- return CoderResult.malformedForLength(data[INVALID_CHARS]);
+ return CoderResult.malformedForLength(data[INVALID_CHAR_COUNT]);
} else {
throw new AssertionError(error);
}
@@ -231,7 +231,7 @@ final class CharsetEncoderICU extends CharsetEncoder {
private void setPosition(ByteBuffer out) {
if (out.hasArray()) {
- out.position(out.position() + data[OUTPUT_OFFSET] - out.arrayOffset());
+ out.position(data[OUTPUT_OFFSET] - out.arrayOffset());
} else {
out.put(output, 0, data[OUTPUT_OFFSET]);
}
@@ -240,7 +240,17 @@ final class CharsetEncoderICU extends CharsetEncoder {
}
private void setPosition(CharBuffer in) {
- in.position(in.position() + data[INPUT_OFFSET] - data[INVALID_CHARS]);
+ int position = in.position() + data[INPUT_OFFSET] - data[INVALID_CHAR_COUNT];
+ if (position < 0) {
+ // The calculated position might be negative if we encountered an
+ // invalid char that spanned input buffers. We adjust it to 0 in this case.
+ //
+ // NOTE: The API doesn't allow us to adjust the position of the previous
+ // input buffer. (Doing that wouldn't serve any useful purpose anyway.)
+ position = 0;
+ }
+
+ in.position(position);
// release reference to input array, which may not be ours
input = null;
}
diff --git a/luni/src/main/java/java/security/AlgorithmParameterGenerator.java b/luni/src/main/java/java/security/AlgorithmParameterGenerator.java
index 61548d7..167204c 100644
--- a/luni/src/main/java/java/security/AlgorithmParameterGenerator.java
+++ b/luni/src/main/java/java/security/AlgorithmParameterGenerator.java
@@ -129,7 +129,8 @@ public class AlgorithmParameterGenerator {
/**
* Returns a new instance of {@code AlgorithmParameterGenerator} from the
- * specified provider for the specified algorithm.
+ * specified provider for the specified algorithm. The {@code provider}
+ * supplied does not have to be registered.
*
* @param algorithm
* the name of the algorithm to use.
diff --git a/luni/src/main/java/java/security/AlgorithmParameters.java b/luni/src/main/java/java/security/AlgorithmParameters.java
index 073460e..27af018 100644
--- a/luni/src/main/java/java/security/AlgorithmParameters.java
+++ b/luni/src/main/java/java/security/AlgorithmParameters.java
@@ -131,7 +131,8 @@ public class AlgorithmParameters {
/**
* Returns a new instance of {@code AlgorithmParameters} from the specified
- * provider for the specified algorithm.
+ * provider for the specified algorithm. The {@code provider} supplied does
+ * not have to be registered.
*
* @param algorithm
* the name of the algorithm to use.
diff --git a/luni/src/main/java/java/security/GuardedObject.java b/luni/src/main/java/java/security/GuardedObject.java
index 34a5113..dd2e98f 100644
--- a/luni/src/main/java/java/security/GuardedObject.java
+++ b/luni/src/main/java/java/security/GuardedObject.java
@@ -53,7 +53,7 @@ public class GuardedObject implements Serializable {
* SecurityException} is thrown.
*
* @return the guarded object.
- * @exception SecurityException
+ * @throws SecurityException
* if access is not granted to the guarded object.
*/
public Object getObject() throws SecurityException {
diff --git a/luni/src/main/java/java/security/KeyFactory.java b/luni/src/main/java/java/security/KeyFactory.java
index 3bd05b9..c22212f 100644
--- a/luni/src/main/java/java/security/KeyFactory.java
+++ b/luni/src/main/java/java/security/KeyFactory.java
@@ -112,7 +112,8 @@ public class KeyFactory {
/**
* Returns a new instance of {@code KeyFactory} that utilizes the specified
- * algorithm from the specified provider.
+ * algorithm from the specified provider. The {@code provider} supplied
+ * does not have to be registered.
*
* @param algorithm
* the name of the algorithm.
diff --git a/luni/src/main/java/java/security/KeyPairGenerator.java b/luni/src/main/java/java/security/KeyPairGenerator.java
index 8a713d0..d05e902 100644
--- a/luni/src/main/java/java/security/KeyPairGenerator.java
+++ b/luni/src/main/java/java/security/KeyPairGenerator.java
@@ -124,7 +124,8 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
/**
* Returns a new instance of {@code KeyPairGenerator} that utilizes the
- * specified algorithm from the specified provider.
+ * specified algorithm from the specified provider. The {@code provider}
+ * supplied does not have to be registered.
*
* @param algorithm
* the name of the algorithm to use
diff --git a/luni/src/main/java/java/security/KeyStore.java b/luni/src/main/java/java/security/KeyStore.java
index b0e4945..0611e59 100644
--- a/luni/src/main/java/java/security/KeyStore.java
+++ b/luni/src/main/java/java/security/KeyStore.java
@@ -159,7 +159,8 @@ public class KeyStore {
/**
* Returns a new instance of {@code KeyStore} from the specified provider
- * with the given type.
+ * with the given type. The {@code provider} supplied does not have to be
+ * registered.
*
* @param type
* the type of the returned {@code KeyStore}.
diff --git a/luni/src/main/java/java/security/MessageDigest.java b/luni/src/main/java/java/security/MessageDigest.java
index 658b41f..1d37a90 100644
--- a/luni/src/main/java/java/security/MessageDigest.java
+++ b/luni/src/main/java/java/security/MessageDigest.java
@@ -132,7 +132,8 @@ public abstract class MessageDigest extends MessageDigestSpi {
/**
* Returns a new instance of {@code MessageDigest} that utilizes the
- * specified algorithm from the specified provider.
+ * specified algorithm from the specified provider. The
+ * {@code provider} supplied does not have to be registered.
*
* @param algorithm
* the name of the algorithm to use
@@ -302,12 +303,12 @@ public abstract class MessageDigest extends MessageDigestSpi {
if (digesta.length != digestb.length) {
return false;
}
+ // Perform a constant time comparison to avoid timing attacks.
+ int v = 0;
for (int i = 0; i < digesta.length; i++) {
- if (digesta[i] != digestb[i]) {
- return false;
- }
+ v |= (digesta[i] ^ digestb[i]);
}
- return true;
+ return v == 0;
}
/**
@@ -351,14 +352,6 @@ public abstract class MessageDigest extends MessageDigestSpi {
}
}
- @Override
- public Object clone() throws CloneNotSupportedException {
- if (this instanceof Cloneable) {
- return super.clone();
- }
- throw new CloneNotSupportedException();
- }
-
/**
* Updates this {@code MessageDigest} using the given {@code input}.
*
@@ -420,12 +413,8 @@ public abstract class MessageDigest extends MessageDigestSpi {
// Returns a clone if the spiImpl is cloneable
@Override
public Object clone() throws CloneNotSupportedException {
- if (spiImpl instanceof Cloneable) {
- MessageDigestSpi spi = (MessageDigestSpi) spiImpl.clone();
- return new MessageDigestImpl(spi, getProvider(), getAlgorithm());
- }
-
- throw new CloneNotSupportedException();
+ MessageDigestSpi spi = (MessageDigestSpi) spiImpl.clone();
+ return new MessageDigestImpl(spi, getProvider(), getAlgorithm());
}
}
}
diff --git a/luni/src/main/java/java/security/Provider.java b/luni/src/main/java/java/security/Provider.java
index a6de19c..1704b58 100644
--- a/luni/src/main/java/java/security/Provider.java
+++ b/luni/src/main/java/java/security/Provider.java
@@ -804,6 +804,79 @@ public abstract class Provider extends Properties {
* provider it belongs and other properties.
*/
public static class Service {
+ /** Attribute name of supported key classes. */
+ private static final String ATTR_SUPPORTED_KEY_CLASSES = "SupportedKeyClasses";
+
+ /** Attribute name of supported key formats. */
+ private static final String ATTR_SUPPORTED_KEY_FORMATS = "SupportedKeyFormats";
+
+ /** Whether this type supports calls to {@link #supportsParameter(Object)}. */
+ private static final HashMap<String, Boolean> supportsParameterTypes
+ = new HashMap<String, Boolean>();
+ static {
+ // Does not support parameter
+ supportsParameterTypes.put("AlgorithmParameterGenerator", false);
+ supportsParameterTypes.put("AlgorithmParameters", false);
+ supportsParameterTypes.put("CertificateFactory", false);
+ supportsParameterTypes.put("CertPathBuilder", false);
+ supportsParameterTypes.put("CertPathValidator", false);
+ supportsParameterTypes.put("CertStore", false);
+ supportsParameterTypes.put("KeyFactory", false);
+ supportsParameterTypes.put("KeyGenerator", false);
+ supportsParameterTypes.put("KeyManagerFactory", false);
+ supportsParameterTypes.put("KeyPairGenerator", false);
+ supportsParameterTypes.put("KeyStore", false);
+ supportsParameterTypes.put("MessageDigest", false);
+ supportsParameterTypes.put("SecretKeyFactory", false);
+ supportsParameterTypes.put("SecureRandom", false);
+ supportsParameterTypes.put("SSLContext", false);
+ supportsParameterTypes.put("TrustManagerFactory", false);
+
+ // Supports parameter
+ supportsParameterTypes.put("Cipher", true);
+ supportsParameterTypes.put("KeyAgreement", true);
+ supportsParameterTypes.put("Mac", true);
+ supportsParameterTypes.put("Signature", true);
+ }
+
+ /** Constructor argument classes for calls to {@link #newInstance(Object)}. */
+ private static final HashMap<String, Class<?>> constructorParameterClasses = new HashMap<String, Class<?>>();
+ static {
+ // Types that take a parameter to newInstance
+ constructorParameterClasses.put("CertStore",
+ loadClassOrThrow("java.security.cert.CertStoreParameters"));
+
+ // Types that do not take any kind of parameter
+ constructorParameterClasses.put("AlgorithmParameterGenerator", null);
+ constructorParameterClasses.put("AlgorithmParameters", null);
+ constructorParameterClasses.put("CertificateFactory", null);
+ constructorParameterClasses.put("CertPathBuilder", null);
+ constructorParameterClasses.put("CertPathValidator", null);
+ constructorParameterClasses.put("KeyFactory", null);
+ constructorParameterClasses.put("KeyGenerator", null);
+ constructorParameterClasses.put("KeyManagerFactory", null);
+ constructorParameterClasses.put("KeyPairGenerator", null);
+ constructorParameterClasses.put("KeyStore", null);
+ constructorParameterClasses.put("MessageDigest", null);
+ constructorParameterClasses.put("SecretKeyFactory", null);
+ constructorParameterClasses.put("SecureRandom", null);
+ constructorParameterClasses.put("SSLContext", null);
+ constructorParameterClasses.put("TrustManagerFactory", null);
+ constructorParameterClasses.put("Cipher", null);
+ constructorParameterClasses.put("KeyAgreement", null);
+ constructorParameterClasses.put("Mac", null);
+ constructorParameterClasses.put("Signature", null);
+ }
+
+ /** Called to load a class if it's critical that the class exists. */
+ private static Class<?> loadClassOrThrow(String className) {
+ try {
+ return Provider.class.getClassLoader().loadClass(className);
+ } catch (Exception e) {
+ throw new AssertionError(e);
+ }
+ }
+
// The provider
private Provider provider;
@@ -828,6 +901,15 @@ public abstract class Provider extends Properties {
// For newInstance() optimization
private String lastClassName;
+ /** Indicates whether supportedKeyClasses and supportedKeyFormats. */
+ private volatile boolean supportedKeysInitialized;
+
+ /** List of classes that this service supports. */
+ private Class<?>[] keyClasses;
+
+ /** List of key formats this service supports. */
+ private String[] keyFormats;
+
/**
* Constructs a new instance of {@code Service} with the given
* attributes.
@@ -993,28 +1075,52 @@ public abstract class Provider extends Properties {
throw new NoSuchAlgorithmException(type + " " + algorithm + " implementation not found: " + e);
}
}
- if (constructorParameter == null) {
- try {
- return implementation.newInstance();
- } catch (Exception e) {
- throw new NoSuchAlgorithmException(
- type + " " + algorithm + " implementation not found", e);
+
+ // We don't know whether this takes a parameter or not.
+ if (!constructorParameterClasses.containsKey(type)) {
+ if (constructorParameter == null) {
+ return newInstanceNoParameter();
+ } else {
+ return newInstanceWithParameter(constructorParameter,
+ constructorParameter.getClass());
}
}
- if (!supportsParameter(constructorParameter)) {
- throw new InvalidParameterException(type + ": service cannot use the parameter");
+
+ // A known type, but it's not required to have a parameter even if a
+ // class is specified.
+ if (constructorParameter == null) {
+ return newInstanceNoParameter();
}
- Class[] parameterTypes = new Class[1];
- Object[] initargs = { constructorParameter };
+ // Make sure the provided constructor class is valid.
+ final Class<?> expectedClass = constructorParameterClasses.get(type);
+ if (expectedClass == null) {
+ throw new IllegalArgumentException("Constructor parameter not supported for "
+ + type);
+ }
+ if (!expectedClass.isAssignableFrom(constructorParameter.getClass())) {
+ throw new IllegalArgumentException("Expecting constructor parameter of type "
+ + expectedClass.getName() + " but was "
+ + constructorParameter.getClass().getName());
+ }
+ return newInstanceWithParameter(constructorParameter, expectedClass);
+ }
+
+ private Object newInstanceWithParameter(Object constructorParameter,
+ Class<?> parameterClass) throws NoSuchAlgorithmException {
try {
- if (type.equalsIgnoreCase("CertStore")) {
- parameterTypes[0] = Class.forName("java.security.cert.CertStoreParameters");
- } else {
- parameterTypes[0] = constructorParameter.getClass();
- }
- return implementation.getConstructor(parameterTypes)
- .newInstance(initargs);
+ Class<?>[] parameterTypes = { parameterClass };
+ Object[] initargs = { constructorParameter };
+ return implementation.getConstructor(parameterTypes).newInstance(initargs);
+ } catch (Exception e) {
+ throw new NoSuchAlgorithmException(type + " " + algorithm
+ + " implementation not found", e);
+ }
+ }
+
+ private Object newInstanceNoParameter() throws NoSuchAlgorithmException {
+ try {
+ return implementation.newInstance();
} catch (Exception e) {
throw new NoSuchAlgorithmException(type + " " + algorithm
+ " implementation not found", e);
@@ -1031,7 +1137,111 @@ public abstract class Provider extends Properties {
* constructor parameter, {@code false} otherwise.
*/
public boolean supportsParameter(Object parameter) {
- return true;
+ Boolean supportsParameter = supportsParameterTypes.get(type);
+ if (supportsParameter == null) {
+ return true;
+ }
+ if (!supportsParameter) {
+ throw new InvalidParameterException("Cannot use a parameter with " + type);
+ }
+
+ /*
+ * Only Key parameters are allowed, but allow null since there might
+ * not be any listed classes or formats for this instance.
+ */
+ if (parameter != null && !(parameter instanceof Key)) {
+ throw new InvalidParameterException("Parameter should be of type Key");
+ }
+
+ ensureSupportedKeysInitialized();
+
+ // No restriction specified by Provider registration.
+ if (keyClasses == null && keyFormats == null) {
+ return true;
+ }
+
+ // Restriction specified by registration, so null is not acceptable.
+ if (parameter == null) {
+ return false;
+ }
+
+ Key keyParam = (Key) parameter;
+ if (keyClasses != null && isInArray(keyClasses, keyParam.getClass())) {
+ return true;
+ }
+ if (keyFormats != null && isInArray(keyFormats, keyParam.getFormat())) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Initialize the list of supported key classes and formats.
+ */
+ private void ensureSupportedKeysInitialized() {
+ if (supportedKeysInitialized) {
+ return;
+ }
+
+ final String supportedClassesString = getAttribute(ATTR_SUPPORTED_KEY_CLASSES);
+ if (supportedClassesString != null) {
+ String[] keyClassNames = supportedClassesString.split("\\|");
+ ArrayList<Class<?>> supportedClassList = new ArrayList<Class<?>>(
+ keyClassNames.length);
+ final ClassLoader classLoader = getProvider().getClass().getClassLoader();
+ for (String keyClassName : keyClassNames) {
+ try {
+ Class<?> keyClass = classLoader.loadClass(keyClassName);
+ if (Key.class.isAssignableFrom(keyClass)) {
+ supportedClassList.add(keyClass);
+ }
+ } catch (ClassNotFoundException ignored) {
+ }
+ }
+ keyClasses = supportedClassList.toArray(new Class<?>[supportedClassList.size()]);
+ }
+
+ final String supportedFormatString = getAttribute(ATTR_SUPPORTED_KEY_FORMATS);
+ if (supportedFormatString != null) {
+ keyFormats = supportedFormatString.split("\\|");
+ }
+
+ supportedKeysInitialized = true;
+ }
+
+ /**
+ * Check if an item is in the array. The array of supported key classes
+ * and formats is usually just a length of 1, so a simple array is
+ * faster than a Set.
+ */
+ private static <T> boolean isInArray(T[] itemList, T target) {
+ if (target == null) {
+ return false;
+ }
+ for (T item : itemList) {
+ if (target.equals(item)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if an item is in the array. The array of supported key classes
+ * and formats is usually just a length of 1, so a simple array is
+ * faster than a Set.
+ */
+ private static boolean isInArray(Class<?>[] itemList, Class<?> target) {
+ if (target == null) {
+ return false;
+ }
+ for (Class<?> item : itemList) {
+ if (item.isAssignableFrom(target)) {
+ return true;
+ }
+ }
+ return false;
}
/**
diff --git a/luni/src/main/java/java/security/SecureRandom.java b/luni/src/main/java/java/security/SecureRandom.java
index 281885b..7a03801 100644
--- a/luni/src/main/java/java/security/SecureRandom.java
+++ b/luni/src/main/java/java/security/SecureRandom.java
@@ -46,8 +46,8 @@ import org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl;
* For deriving keys from passwords, see
* {@link javax.crypto.SecretKeyFactory}.
*
- * <h3><a name="insecure_seed">Seeding {@code SecureRandom} may be
- * insecure</a></h3>
+ * <h3><a name="insecure_seed"></a>Seeding {@code SecureRandom} may be
+ * insecure</h3>
* A seed is an array of bytes used to bootstrap random number generation.
* To produce cryptographically secure random numbers, both the seed and the
* algorithm must be secure.
@@ -190,7 +190,8 @@ public class SecureRandom extends Random {
/**
* Returns a new instance of {@code SecureRandom} that utilizes the
- * specified algorithm from the specified provider.
+ * specified algorithm from the specified provider. The
+ * {@code provider} supplied does not have to be registered.
*
* @param algorithm
* the name of the algorithm to use.
diff --git a/luni/src/main/java/java/security/Security.java b/luni/src/main/java/java/security/Security.java
index 0b6961b..b859f9a 100644
--- a/luni/src/main/java/java/security/Security.java
+++ b/luni/src/main/java/java/security/Security.java
@@ -19,6 +19,7 @@ package java.security;
import java.io.BufferedInputStream;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
@@ -72,10 +73,9 @@ public final class Security {
// Register default providers
private static void registerDefaultProviders() {
secprops.put("security.provider.1", "com.android.org.conscrypt.OpenSSLProvider");
- secprops.put("security.provider.2", "org.apache.harmony.security.provider.cert.DRLCertFactory");
- secprops.put("security.provider.3", "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider");
- secprops.put("security.provider.4", "org.apache.harmony.security.provider.crypto.CryptoProvider");
- secprops.put("security.provider.5", "com.android.org.conscrypt.JSSEProvider");
+ secprops.put("security.provider.2", "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider");
+ secprops.put("security.provider.3", "org.apache.harmony.security.provider.crypto.CryptoProvider");
+ secprops.put("security.provider.4", "com.android.org.conscrypt.JSSEProvider");
}
/**
@@ -96,7 +96,7 @@ public final class Security {
String prop = "Alg." + propName + "." + algName;
Provider[] providers = getProviders();
for (Provider provider : providers) {
- for (Enumeration e = provider.propertyNames(); e.hasMoreElements(); ) {
+ for (Enumeration<?> e = provider.propertyNames(); e.hasMoreElements();) {
String propertyName = (String) e.nextElement();
if (propertyName.equalsIgnoreCase(prop)) {
return provider.getProperty(propertyName);
@@ -184,7 +184,8 @@ public final class Security {
* @return an array containing all installed providers.
*/
public static synchronized Provider[] getProviders() {
- return Services.getProviders();
+ ArrayList<Provider> providers = Services.getProviders();
+ return providers.toArray(new Provider[providers.size()]);
}
/**
@@ -274,7 +275,7 @@ public final class Security {
if (filter.isEmpty()) {
return null;
}
- java.util.List<Provider> result = Services.getProvidersList();
+ ArrayList<Provider> result = new ArrayList<Provider>(Services.getProviders());
Set<Entry<String, String>> keys = filter.entrySet();
Map.Entry<String, String> entry;
for (Iterator<Entry<String, String>> it = keys.iterator(); it.hasNext();) {
@@ -306,18 +307,7 @@ public final class Security {
if (serv.length() == 0 || alg.length() == 0) {
throw new InvalidParameterException();
}
- Provider p;
- for (int k = 0; k < result.size(); k++) {
- try {
- p = result.get(k);
- } catch (IndexOutOfBoundsException e) {
- break;
- }
- if (!p.implementsAlg(serv, alg, attribute, val)) {
- result.remove(p);
- k--;
- }
- }
+ filterProviders(result, serv, alg, attribute, val);
}
if (result.size() > 0) {
return result.toArray(new Provider[result.size()]);
@@ -325,6 +315,17 @@ public final class Security {
return null;
}
+ private static void filterProviders(ArrayList<Provider> providers, String service,
+ String algorithm, String attribute, String attrValue) {
+ Iterator<Provider> it = providers.iterator();
+ while (it.hasNext()) {
+ Provider p = it.next();
+ if (!p.implementsAlg(service, algorithm, attribute, attrValue)) {
+ it.remove();
+ }
+ }
+ }
+
/**
* Returns the value of the security property named by the argument.
*
@@ -347,6 +348,7 @@ public final class Security {
* Sets the value of the specified security property.
*/
public static void setProperty(String key, String value) {
+ Services.setNeedRefresh();
secprops.put(key, value);
}
@@ -384,9 +386,9 @@ public final class Security {
*
*/
private static void renumProviders() {
- Provider[] p = Services.getProviders();
- for (int i = 0; i < p.length; i++) {
- p[i].setProviderNumber(i + 1);
+ ArrayList<Provider> providers = Services.getProviders();
+ for (int i = 0; i < providers.size(); i++) {
+ providers.get(i).setProviderNumber(i + 1);
}
}
diff --git a/luni/src/main/java/java/security/Signature.java b/luni/src/main/java/java/security/Signature.java
index 0372c33..a39d59b 100644
--- a/luni/src/main/java/java/security/Signature.java
+++ b/luni/src/main/java/java/security/Signature.java
@@ -21,10 +21,11 @@ import java.nio.ByteBuffer;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import org.apache.harmony.security.fortress.Engine;
-
+import org.apache.harmony.security.fortress.Engine.SpiAndProvider;
/**
* {@code Signature} is an engine class which is capable of creating and
@@ -39,13 +40,13 @@ public abstract class Signature extends SignatureSpi {
private static final String SERVICE = "Signature";
// Used to access common engine functionality
- private static Engine ENGINE = new Engine(SERVICE);
+ private static final Engine ENGINE = new Engine(SERVICE);
// The provider
- private Provider provider;
+ Provider provider;
// The algorithm.
- private String algorithm;
+ final String algorithm;
/**
* Constant that indicates that this {@code Signature} instance has not yet
@@ -101,16 +102,7 @@ public abstract class Signature extends SignatureSpi {
if (algorithm == null) {
throw new NullPointerException("algorithm == null");
}
- Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
- Object spi = sap.spi;
- Provider provider = sap.provider;
- if (spi instanceof Signature) {
- Signature result = (Signature) spi;
- result.algorithm = algorithm;
- result.provider = provider;
- return result;
- }
- return new SignatureImpl((SignatureSpi) spi, provider, algorithm);
+ return getSignature(algorithm, null);
}
/**
@@ -143,12 +135,13 @@ public abstract class Signature extends SignatureSpi {
if (p == null) {
throw new NoSuchProviderException(provider);
}
- return getSignatureInstance(algorithm, p);
+ return getSignature(algorithm, p);
}
/**
* Returns a new instance of {@code Signature} that utilizes the specified
- * algorithm from the specified provider.
+ * algorithm from the specified provider. The {@code provider} supplied
+ * does not have to be registered.
*
* @param algorithm
* the name of the algorithm to use.
@@ -170,19 +163,68 @@ public abstract class Signature extends SignatureSpi {
if (provider == null) {
throw new IllegalArgumentException("provider == null");
}
- return getSignatureInstance(algorithm, provider);
+ return getSignature(algorithm, provider);
+ }
+
+ private static Signature getSignature(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException {
+ if (algorithm == null || algorithm.isEmpty()) {
+ throw new NoSuchAlgorithmException("Unknown algorithm: " + algorithm);
+ }
+
+ SpiAndProvider spiAndProvider = tryAlgorithm(null, provider, algorithm);
+ if (spiAndProvider == null) {
+ if (provider == null) {
+ throw new NoSuchAlgorithmException("No provider found for " + algorithm);
+ } else {
+ throw new NoSuchAlgorithmException("Provider " + provider.getName()
+ + " does not provide " + algorithm);
+ }
+ }
+ if (spiAndProvider.spi instanceof Signature) {
+ return (Signature) spiAndProvider.spi;
+ }
+ return new SignatureImpl(algorithm, provider);
+ }
+
+ private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) {
+ if (provider != null) {
+ Provider.Service service = provider.getService(SERVICE, algorithm);
+ if (service == null) {
+ return null;
+ }
+ return tryAlgorithmWithProvider(key, service);
+ }
+ ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
+ if (services == null) {
+ return null;
+ }
+ for (Provider.Service service : services) {
+ Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service);
+ if (sap != null) {
+ return sap;
+ }
+ }
+ return null;
}
- private static Signature getSignatureInstance(String algorithm,
- Provider provider) throws NoSuchAlgorithmException {
- Object spi = ENGINE.getInstance(algorithm, provider, null);
- if (spi instanceof Signature) {
- Signature result = (Signature) spi;
- result.algorithm = algorithm;
- result.provider = provider;
- return result;
+ private static Engine.SpiAndProvider tryAlgorithmWithProvider(Key key, Provider.Service service) {
+ try {
+ if (key != null && !service.supportsParameter(key)) {
+ return null;
+ }
+
+ Engine.SpiAndProvider sap = ENGINE.getInstance(service, null);
+ if (sap.spi == null || sap.provider == null) {
+ return null;
+ }
+ if (!(sap.spi instanceof SignatureSpi)) {
+ return null;
+ }
+ return sap;
+ } catch (NoSuchAlgorithmException ignored) {
}
- return new SignatureImpl((SignatureSpi) spi, provider, algorithm);
+ return null;
}
/**
@@ -191,10 +233,18 @@ public abstract class Signature extends SignatureSpi {
* @return the provider associated with this {@code Signature}.
*/
public final Provider getProvider() {
+ ensureProviderChosen();
return provider;
}
/**
+ * This makes sure the provider is chosen since Signature is abstract and
+ * getProvider is final but we need to support late binding.
+ */
+ void ensureProviderChosen() {
+ }
+
+ /**
* Returns the name of the algorithm of this {@code Signature}.
*
* @return the name of the algorithm of this {@code Signature}.
@@ -237,10 +287,10 @@ public abstract class Signature extends SignatureSpi {
public final void initVerify(Certificate certificate)
throws InvalidKeyException {
if (certificate instanceof X509Certificate) {
- Set ce = ((X509Certificate) certificate).getCriticalExtensionOIDs();
+ Set<String> ce = ((X509Certificate) certificate).getCriticalExtensionOIDs();
boolean critical = false;
if (ce != null && !ce.isEmpty()) {
- for (Iterator i = ce.iterator(); i.hasNext();) {
+ for (Iterator<String> i = ce.iterator(); i.hasNext();) {
if ("2.5.29.15".equals(i.next())) {
//KeyUsage OID = 2.5.29.15
critical = true;
@@ -574,92 +624,115 @@ public abstract class Signature extends SignatureSpi {
return engineGetParameter(param);
}
- @Override
- public Object clone() throws CloneNotSupportedException {
- if (this instanceof Cloneable) {
- return super.clone();
- }
- throw new CloneNotSupportedException();
- }
-
/**
- *
* Internal Signature implementation
- *
*/
private static class SignatureImpl extends Signature {
+ /**
+ * Lock held while the SPI is initializing.
+ */
+ private final Object initLock = new Object();
+
+ // The provider specified when creating this instance.
+ private final Provider specifiedProvider;
+
private SignatureSpi spiImpl;
- // Constructor
- public SignatureImpl(SignatureSpi signatureSpi, Provider provider,
- String algorithm) {
+ public SignatureImpl(String algorithm, Provider provider) {
super(algorithm);
- super.provider = provider;
- spiImpl = signatureSpi;
+ this.specifiedProvider = provider;
+ }
+
+ private SignatureImpl(String algorithm, Provider provider, SignatureSpi spi) {
+ this(algorithm, provider);
+ spiImpl = spi;
+ }
+
+ @Override
+ void ensureProviderChosen() {
+ getSpi(null);
}
- // engineSign() implementation
@Override
protected byte[] engineSign() throws SignatureException {
- return spiImpl.engineSign();
+ return getSpi().engineSign();
}
- // engineUpdate() implementation
@Override
protected void engineUpdate(byte arg0) throws SignatureException {
- spiImpl.engineUpdate(arg0);
+ getSpi().engineUpdate(arg0);
}
- // engineVerify() implementation
@Override
protected boolean engineVerify(byte[] arg0) throws SignatureException {
- return spiImpl.engineVerify(arg0);
+ return getSpi().engineVerify(arg0);
}
- // engineUpdate() implementation
@Override
- protected void engineUpdate(byte[] arg0, int arg1, int arg2)
- throws SignatureException {
- spiImpl.engineUpdate(arg0, arg1, arg2);
+ protected void engineUpdate(byte[] arg0, int arg1, int arg2) throws SignatureException {
+ getSpi().engineUpdate(arg0, arg1, arg2);
}
- // engineInitSign() implementation
@Override
- protected void engineInitSign(PrivateKey arg0)
- throws InvalidKeyException {
- spiImpl.engineInitSign(arg0);
+ protected void engineInitSign(PrivateKey arg0) throws InvalidKeyException {
+ getSpi(arg0).engineInitSign(arg0);
}
- // engineInitVerify() implementation
@Override
- protected void engineInitVerify(PublicKey arg0)
- throws InvalidKeyException {
- spiImpl.engineInitVerify(arg0);
+ protected void engineInitVerify(PublicKey arg0) throws InvalidKeyException {
+ getSpi(arg0).engineInitVerify(arg0);
}
- // engineGetParameter() implementation
@Override
- protected Object engineGetParameter(String arg0)
- throws InvalidParameterException {
- return spiImpl.engineGetParameter(arg0);
+ protected Object engineGetParameter(String arg0) throws InvalidParameterException {
+ return getSpi().engineGetParameter(arg0);
}
- // engineSetParameter() implementation
@Override
protected void engineSetParameter(String arg0, Object arg1)
throws InvalidParameterException {
- spiImpl.engineSetParameter(arg0, arg1);
+ getSpi().engineSetParameter(arg0, arg1);
+ }
+
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec arg0)
+ throws InvalidAlgorithmParameterException {
+ getSpi().engineSetParameter(arg0);
}
- // Returns a clone if the spiImpl is cloneable
@Override
public Object clone() throws CloneNotSupportedException {
- if (spiImpl instanceof Cloneable) {
- SignatureSpi spi = (SignatureSpi) spiImpl.clone();
- return new SignatureImpl(spi, getProvider(), getAlgorithm());
+ SignatureSpi spi = spiImpl != null ? (SignatureSpi) spiImpl.clone() : null;
+ return new SignatureImpl(getAlgorithm(), getProvider(), spi);
+ }
+
+ /**
+ * Makes sure a CipherSpi that matches this type is selected.
+ */
+ private SignatureSpi getSpi(Key key) {
+ synchronized (initLock) {
+ if (spiImpl != null && key == null) {
+ return spiImpl;
+ }
+
+ final Engine.SpiAndProvider sap = tryAlgorithm(key, specifiedProvider, algorithm);
+ if (sap == null) {
+ throw new ProviderException("No provider for " + getAlgorithm());
+ }
+
+ spiImpl = (SignatureSpi) sap.spi;
+ provider = sap.provider;
+
+ return spiImpl;
}
- throw new CloneNotSupportedException();
+ }
+
+ /**
+ * Convenience call when the Key is not available.
+ */
+ private SignatureSpi getSpi() {
+ return getSpi(null);
}
}
}
diff --git a/luni/src/main/java/java/security/SignatureSpi.java b/luni/src/main/java/java/security/SignatureSpi.java
index 27be30c..66c43d7 100644
--- a/luni/src/main/java/java/security/SignatureSpi.java
+++ b/luni/src/main/java/java/security/SignatureSpi.java
@@ -307,9 +307,6 @@ public abstract class SignatureSpi {
@Override
public Object clone() throws CloneNotSupportedException {
- if (this instanceof Cloneable) {
- return super.clone();
- }
- throw new CloneNotSupportedException();
+ return super.clone();
}
}
diff --git a/luni/src/main/java/java/security/cert/CRLReason.java b/luni/src/main/java/java/security/cert/CRLReason.java
new file mode 100644
index 0000000..6f663db
--- /dev/null
+++ b/luni/src/main/java/java/security/cert/CRLReason.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.security.cert;
+
+import java.io.Serializable;
+
+/**
+ * The reason a CRL entry was revoked. See <a
+ * href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280</a> for more information.
+ *
+ * @since 1.7
+ * @hide
+ */
+public enum CRLReason implements Comparable<CRLReason>, Serializable {
+ UNSPECIFIED,
+ KEY_COMPROMISE,
+ CA_COMPROMISE,
+ AFFILIATION_CHANGED,
+ SUPERSEDED,
+ CESSATION_OF_OPERATION,
+ CERTIFICATE_HOLD,
+ UNUSED,
+ REMOVE_FROM_CRL,
+ PRIVILEGE_WITHDRAWN,
+ AA_COMPROMISE;
+}
diff --git a/luni/src/main/java/java/security/cert/CertPathValidator.java b/luni/src/main/java/java/security/cert/CertPathValidator.java
index a3a666a..962f530 100644
--- a/luni/src/main/java/java/security/cert/CertPathValidator.java
+++ b/luni/src/main/java/java/security/cert/CertPathValidator.java
@@ -140,7 +140,8 @@ public class CertPathValidator {
/**
* Returns a new certification path validator for the specified algorithm
- * from the specified provider.
+ * from the specified provider. The {@code provider} supplied does not
+ * have to be registered.
*
* @param algorithm
* the algorithm name.
diff --git a/luni/src/main/java/java/security/cert/CertStore.java b/luni/src/main/java/java/security/cert/CertStore.java
index 72d356f..606c93b 100644
--- a/luni/src/main/java/java/security/cert/CertStore.java
+++ b/luni/src/main/java/java/security/cert/CertStore.java
@@ -151,7 +151,9 @@ public class CertStore {
/**
* Creates a new {@code CertStore} instance from the specified provider with
- * the specified type and initialized with the specified parameters.
+ * the specified type and initialized with the specified parameters. The
+ * {@code provider} supplied does not have to be registered.
+ *
* @param type
* the certificate store type.
* @param params
diff --git a/luni/src/main/java/java/security/cert/Certificate.java b/luni/src/main/java/java/security/cert/Certificate.java
index 15c1dbe..675cf9f 100644
--- a/luni/src/main/java/java/security/cert/Certificate.java
+++ b/luni/src/main/java/java/security/cert/Certificate.java
@@ -152,15 +152,15 @@ public abstract class Certificate implements Serializable {
* performed.
* @param sigProvider
* String the name of the signature provider.
- * @exception CertificateException
+ * @throws CertificateException
* if encoding errors are detected.
- * @exception NoSuchAlgorithmException
+ * @throws NoSuchAlgorithmException
* if an unsupported algorithm is detected.
- * @exception InvalidKeyException
+ * @throws InvalidKeyException
* if an invalid key is detected.
- * @exception NoSuchProviderException
+ * @throws NoSuchProviderException
* if the specified provider does not exists.
- * @exception SignatureException
+ * @throws SignatureException
* if signature errors are detected.
*/
public abstract void verify(PublicKey key, String sigProvider)
diff --git a/luni/src/main/java/java/security/cert/CertificateFactory.java b/luni/src/main/java/java/security/cert/CertificateFactory.java
index f882d52..2805c0e 100644
--- a/luni/src/main/java/java/security/cert/CertificateFactory.java
+++ b/luni/src/main/java/java/security/cert/CertificateFactory.java
@@ -128,7 +128,8 @@ public class CertificateFactory {
/**
* Creates a new {@code CertificateFactory} instance from the specified
- * provider that provides the requested certificate type.
+ * provider that provides the requested certificate type. The
+ * {@code provider} supplied does not have to be registered.
*
* @param type
* the certificate type.
@@ -280,7 +281,7 @@ public class CertificateFactory {
* @param inStream
* the stream from where data is read to create the CRL.
* @return an initialized CRL.
- * @exception CRLException
+ * @throws CRLException
* if parsing problems are detected.
*/
public final CRL generateCRL(InputStream inStream) throws CRLException {
@@ -294,7 +295,7 @@ public class CertificateFactory {
* @param inStream
* the stream from which the data is read to create the CRLs.
* @return an initialized collection of CRLs.
- * @exception CRLException
+ * @throws CRLException
* if parsing problems are detected.
*/
public final Collection<? extends CRL> generateCRLs(InputStream inStream)
diff --git a/luni/src/main/java/java/security/cert/CertificateFactorySpi.java b/luni/src/main/java/java/security/cert/CertificateFactorySpi.java
index 117ef65..d157d9c 100644
--- a/luni/src/main/java/java/security/cert/CertificateFactorySpi.java
+++ b/luni/src/main/java/java/security/cert/CertificateFactorySpi.java
@@ -44,7 +44,7 @@ public abstract class CertificateFactorySpi {
* the stream from which the data is read to create the
* certificate.
* @return an initialized certificate.
- * @exception CertificateException
+ * @throws CertificateException
* if parsing problems are detected.
*/
public abstract Certificate engineGenerateCertificate(InputStream inStream)
@@ -57,7 +57,7 @@ public abstract class CertificateFactorySpi {
* @param inStream
* the stream from where data is read to create the certificates.
* @return a collection of certificates.
- * @exception CertificateException
+ * @throws CertificateException
* if parsing problems are detected.
*/
public abstract Collection<? extends Certificate>
@@ -70,7 +70,7 @@ public abstract class CertificateFactorySpi {
* @param inStream
* the stream from where data is read to create the CRL.
* @return an CRL instance.
- * @exception CRLException
+ * @throws CRLException
* if parsing problems are detected.
*/
public abstract CRL engineGenerateCRL(InputStream inStream)
@@ -83,7 +83,7 @@ public abstract class CertificateFactorySpi {
* @param inStream
* the stream from which the data is read to create the CRLs.
* @return a collection of CRLs.
- * @exception CRLException
+ * @throws CRLException
* if parsing problems are detected.
*/
public abstract Collection<? extends CRL>
diff --git a/luni/src/main/java/java/security/cert/CertificateRevokedException.java b/luni/src/main/java/java/security/cert/CertificateRevokedException.java
new file mode 100644
index 0000000..4d88a4d
--- /dev/null
+++ b/luni/src/main/java/java/security/cert/CertificateRevokedException.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.security.cert;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.x500.X500Principal;
+import org.apache.harmony.security.x509.InvalidityDate;
+
+/**
+ * Exception that is thrown when a certificate is invalid because it has been
+ * revoked.
+ *
+ * @since 1.7
+ * @hide
+ */
+public class CertificateRevokedException extends CertificateException {
+
+ private static final long serialVersionUID = 7839996631571608627L;
+
+ private final Date revocationDate;
+
+ private final CRLReason reason;
+
+ private final X500Principal authority;
+
+ // Maps may not be serializable, so serialize it manually.
+ private transient Map<String, Extension> extensions;
+
+ /**
+ * @param revocationDate date the certificate was revoked
+ * @param reason reason the certificate was revoked if available
+ * @param authority authority that revoked the certificate
+ * @param extensions X.509 extensions associated with this revocation
+ */
+ public CertificateRevokedException(Date revocationDate, CRLReason reason,
+ X500Principal authority, Map<String, Extension> extensions) {
+ this.revocationDate = revocationDate;
+ this.reason = reason;
+ this.authority = authority;
+ this.extensions = extensions;
+ }
+
+ /**
+ * Returns the principal of the authority that issued the revocation.
+ */
+ public X500Principal getAuthorityName() {
+ return authority;
+ }
+
+ /**
+ * X.509 extensions that are associated with this revocation.
+ */
+ public Map<String, Extension> getExtensions() {
+ return Collections.unmodifiableMap(extensions);
+ }
+
+ /**
+ * Returns the date when the certificate was known to become invalid if
+ * available.
+ */
+ public Date getInvalidityDate() {
+ if (extensions == null) {
+ return null;
+ }
+
+ Extension invalidityDateExtension = extensions.get("2.5.29.24");
+ if (invalidityDateExtension == null) {
+ return null;
+ }
+
+ try {
+ InvalidityDate invalidityDate = new InvalidityDate(invalidityDateExtension.getValue());
+ return invalidityDate.getDate();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the detail message of the thrown exception.
+ */
+ public String getMessage() {
+ StringBuffer sb = new StringBuffer("Certificate was revoked");
+ if (revocationDate != null) {
+ sb.append(" on ").append(revocationDate.toString());
+ }
+ if (reason != null) {
+ sb.append(" due to ").append(reason);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns the date the certificate was revoked.
+ */
+ public Date getRevocationDate() {
+ return (Date) revocationDate.clone();
+ }
+
+ /**
+ * Returns the reason the certificate was revoked if available.
+ */
+ public CRLReason getRevocationReason() {
+ return reason;
+ }
+
+ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+
+ int size = stream.readInt();
+ extensions = new HashMap<String, Extension>(size);
+ for (int i = 0; i < size; i++) {
+ String oid = (String) stream.readObject();
+ boolean critical = stream.readBoolean();
+ int valueLen = stream.readInt();
+ byte[] value = new byte[valueLen];
+ stream.read(value);
+ extensions.put(oid,
+ new org.apache.harmony.security.x509.Extension(oid, critical, value));
+ }
+ }
+
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+
+ stream.writeInt(extensions.size());
+ for (Extension e : extensions.values()) {
+ stream.writeObject(e.getId());
+ stream.writeBoolean(e.isCritical());
+ byte[] value = e.getValue();
+ stream.writeInt(value.length);
+ stream.write(value);
+ }
+ }
+}
diff --git a/luni/src/main/java/java/security/cert/Extension.java b/luni/src/main/java/java/security/cert/Extension.java
new file mode 100644
index 0000000..8013809
--- /dev/null
+++ b/luni/src/main/java/java/security/cert/Extension.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.security.cert;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The Extension part of an X.509 certificate (as specified in <a
+ * href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280 &mdash; Internet X.509
+ * Public Key Infrastructure: Certificate and Certificate Revocation List (CRL)
+ * Profile</p>):
+ *
+ * <pre>
+ * Extension ::= SEQUENCE {
+ * extnID OBJECT IDENTIFIER,
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING
+ * }
+ * </pre>
+ *
+ * @since 1.7
+ * @hide
+ */
+public interface Extension {
+ /**
+ * Returns the OID (Object Identifier) for this extension encoded as a
+ * string (e.g., "2.5.29.15").
+ */
+ String getId();
+
+ /**
+ * Returns {@code true} if this extension is critical. If this is true and
+ * an implementation does not understand this extension, it must reject it.
+ * See RFC 3280 section 4.2 for more information.
+ */
+ boolean isCritical();
+
+ /**
+ * The DER-encoded value of this extension.
+ */
+ byte[] getValue();
+
+ /**
+ * Writes the DER-encoded extension to {@code out}.
+ *
+ * @throws IOException when there is an encoding error or error writing to
+ * {@code out}
+ */
+ void encode(OutputStream out) throws IOException;
+}
diff --git a/luni/src/main/java/java/security/cert/X509CRLEntry.java b/luni/src/main/java/java/security/cert/X509CRLEntry.java
index 4b4c15d..451cfd5 100644
--- a/luni/src/main/java/java/security/cert/X509CRLEntry.java
+++ b/luni/src/main/java/java/security/cert/X509CRLEntry.java
@@ -17,10 +17,13 @@
package java.security.cert;
+import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Date;
import javax.security.auth.x500.X500Principal;
+import org.apache.harmony.security.asn1.ASN1OctetString;
+import org.apache.harmony.security.x509.ReasonCode;
/**
* Abstract base class for entries in a certificate revocation list (CRL).
@@ -121,5 +124,25 @@ public abstract class X509CRLEntry implements X509Extension {
* @return a string representation of this instance.
*/
public abstract String toString();
-}
+ /**
+ * Returns the reason this CRL entry was revoked. If the implementation
+ * doesn't support reasons, this will return {@code null}.
+ *
+ * @since 1.7
+ * @hide
+ */
+ public CRLReason getRevocationReason() {
+ byte[] reasonBytes = getExtensionValue("2.5.29.21");
+ if (reasonBytes == null) {
+ return null;
+ }
+
+ try {
+ byte[] rawBytes = (byte[]) ASN1OctetString.getInstance().decode(reasonBytes);
+ return new ReasonCode(rawBytes).getReason();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/luni/src/main/java/java/security/interfaces/DSAParams.java b/luni/src/main/java/java/security/interfaces/DSAParams.java
index ed1fcb5..64ddb01 100644
--- a/luni/src/main/java/java/security/interfaces/DSAParams.java
+++ b/luni/src/main/java/java/security/interfaces/DSAParams.java
@@ -39,9 +39,9 @@ public interface DSAParams {
public BigInteger getP();
/**
- * Returns the subprime ({@code q} value.
+ * Returns the subprime ({@code q}) value.
*
- * @return the subprime ({@code q} value.
+ * @return the subprime ({@code q}) value.
*/
public BigInteger getQ();
diff --git a/luni/src/main/java/java/security/security.properties b/luni/src/main/java/java/security/security.properties
index dd5830d..a06283b 100644
--- a/luni/src/main/java/java/security/security.properties
+++ b/luni/src/main/java/java/security/security.properties
@@ -20,13 +20,11 @@
#
# Android's provider of OpenSSL backed implementations
security.provider.1=com.android.org.conscrypt.OpenSSLProvider
-# Favor Harmony's CertificateFactory.X509 over BouncyCastle's
-security.provider.2=org.apache.harmony.security.provider.cert.DRLCertFactory
# Android's stripped down BouncyCastle provider
-security.provider.3=com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
+security.provider.2=com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
# Remaining Harmony providers
-security.provider.4=org.apache.harmony.security.provider.crypto.CryptoProvider
-security.provider.5=com.android.org.conscrypt.JSSEProvider
+security.provider.3=org.apache.harmony.security.provider.crypto.CryptoProvider
+security.provider.4=com.android.org.conscrypt.JSSEProvider
diff --git a/luni/src/main/java/java/security/spec/ECParameterSpec.java b/luni/src/main/java/java/security/spec/ECParameterSpec.java
index 9860ac0..37b39ac 100644
--- a/luni/src/main/java/java/security/spec/ECParameterSpec.java
+++ b/luni/src/main/java/java/security/spec/ECParameterSpec.java
@@ -32,7 +32,7 @@ public class ECParameterSpec implements AlgorithmParameterSpec {
// Cofactor
private final int cofactor;
// Name of curve if available.
- private final String curveName;
+ private String curveName;
/**
* Creates a new {@code ECParameterSpec} with the specified elliptic curve,
@@ -52,23 +52,10 @@ public class ECParameterSpec implements AlgorithmParameterSpec {
*/
public ECParameterSpec(EllipticCurve curve, ECPoint generator,
BigInteger order, int cofactor) {
- this(curve, generator, order, cofactor, null);
- }
-
- /**
- * Creates a new {@code ECParameterSpec} with the specified named curve
- * and all of its parameters.
- *
- * @see #ECParameterSpec(EllipticCurve, ECPoint, BigInteger, int)
- * @hide
- */
- public ECParameterSpec(EllipticCurve curve, ECPoint generator,
- BigInteger order, int cofactor, String curveName) {
this.curve = curve;
this.generator = generator;
this.order = order;
this.cofactor = cofactor;
- this.curveName = curveName;
// throw NullPointerException if curve, generator or order is null
if (this.curve == null) {
throw new NullPointerException("curve == null");
@@ -125,6 +112,15 @@ public class ECParameterSpec implements AlgorithmParameterSpec {
}
/**
+ * Used to set the curve name if available.
+ *
+ * @hide
+ */
+ public void setCurveName(String curveName) {
+ this.curveName = curveName;
+ }
+
+ /**
* Returns the name of the curve if this is a named curve. Returns
* {@code null} if this is not known to be a named curve.
*
diff --git a/luni/src/main/java/java/sql/Date.java b/luni/src/main/java/java/sql/Date.java
index 4aac326..206d885 100644
--- a/luni/src/main/java/java/sql/Date.java
+++ b/luni/src/main/java/java/sql/Date.java
@@ -214,23 +214,19 @@ public class Date extends java.util.Date {
if (dateString == null) {
throw new IllegalArgumentException("dateString == null");
}
- int firstIndex = dateString.indexOf('-');
- int secondIndex = dateString.indexOf('-', firstIndex + 1);
- // secondIndex == -1 means none or only one separator '-' has been
- // found.
- // The string is separated into three parts by two separator characters,
- // if the first or the third part is null string, we should throw
- // IllegalArgumentException to follow RI
- if (secondIndex == -1 || firstIndex == 0
- || secondIndex + 1 == dateString.length()) {
+ if (dateString.length() > 10) {
+ // early fail to avoid parsing huge invalid strings
throw new IllegalArgumentException();
}
- // parse each part of the string
- int year = Integer.parseInt(dateString.substring(0, firstIndex));
- int month = Integer.parseInt(dateString.substring(firstIndex + 1,
- secondIndex));
- int day = Integer.parseInt(dateString.substring(secondIndex + 1,
- dateString.length()));
+
+ String[] parts = dateString.split("-");
+ if (parts.length != 3) {
+ throw new IllegalArgumentException();
+ }
+
+ int year = Integer.parsePositiveInt(parts[0]);
+ int month = Integer.parsePositiveInt(parts[1]);
+ int day = Integer.parsePositiveInt(parts[2]);
return new Date(year - 1900, month - 1, day);
}
diff --git a/luni/src/main/java/java/sql/Timestamp.java b/luni/src/main/java/java/sql/Timestamp.java
index f35fa9b..a45a2b8 100644
--- a/luni/src/main/java/java/sql/Timestamp.java
+++ b/luni/src/main/java/java/sql/Timestamp.java
@@ -408,7 +408,7 @@ public class Timestamp extends Date {
throw new IllegalArgumentException("Argument cannot be null");
}
- // omit trailing whitespace
+ // Omit trailing whitespace
s = s.trim();
if (!Pattern.matches(TIME_FORMAT_REGEX, s)) {
throw badTimestampString(s);
@@ -424,14 +424,14 @@ public class Timestamp extends Date {
* with the ParsePosition indicating the index of the "." which should
* precede the nanoseconds value
*/
- Date theDate;
+ Date date;
try {
- theDate = df.parse(s, pp);
+ date = df.parse(s, pp);
} catch (Exception e) {
throw badTimestampString(s);
}
- if (theDate == null) {
+ if (date == null) {
throw badTimestampString(s);
}
@@ -445,66 +445,38 @@ public class Timestamp extends Date {
*/
int position = pp.getIndex();
int remaining = s.length() - position;
- int theNanos;
+ int nanos;
if (remaining == 0) {
// First, allow for the case where no fraction of a second is given:
- theNanos = 0;
+ nanos = 0;
} else {
- /*
- * Case where fraction of a second is specified: Require 1 character
- * plus the "." in the remaining part of the string...
- */
- if ((s.length() - position) < ".n".length()) {
+ // Validate the string is in the range ".0" to ".999999999"
+ if (remaining < 2 || remaining > 10 || s.charAt(position) != '.') {
throw badTimestampString(s);
}
-
- /*
- * If we're strict, we should not allow any EXTRA characters after
- * the 9 digits
- */
- if ((s.length() - position) > ".nnnnnnnnn".length()) {
- throw badTimestampString(s);
- }
-
- // Require the next character to be a "."
- if (s.charAt(position) != '.') {
- throw new NumberFormatException("Bad input string format: expected '.' not '" +
- s.charAt(position) + "' in \"" + s + "\"");
- }
- // Get the length of the number string - need to account for the '.'
- int nanoLength = s.length() - position - 1;
-
- // Get the 9 characters following the "." as an integer
- String theNanoString = s.substring(position + 1, position + 1
- + nanoLength);
- /*
- * We must adjust for the cases where the nanos String was not 9
- * characters long by padding out with zeros
- */
- theNanoString = theNanoString + "000000000";
- theNanoString = theNanoString.substring(0, 9);
-
try {
- theNanos = Integer.parseInt(theNanoString);
- } catch (Exception e) {
- // If we get here, the string was not a number
+ nanos = Integer.parsePositiveInt(s.substring(position + 1));
+ } catch (NumberFormatException e) {
throw badTimestampString(s);
}
+ // We must adjust for the cases where the nanos String was not 9
+ // characters long (i.e. ".123" means 123000000 nanos)
+ if (nanos != 0) {
+ for (int i = remaining - 1; i < 9; i++) {
+ nanos *= 10;
+ }
+ }
}
- if (theNanos < 0 || theNanos > 999999999) {
- throw badTimestampString(s);
- }
-
- Timestamp theTimestamp = new Timestamp(theDate.getTime());
- theTimestamp.setNanos(theNanos);
+ Timestamp timestamp = new Timestamp(date.getTime());
+ timestamp.setNanos(nanos);
- return theTimestamp;
+ return timestamp;
}
private static IllegalArgumentException badTimestampString(String s) {
- throw new IllegalArgumentException("Timestamp format must be " +
+ return new IllegalArgumentException("Timestamp format must be " +
"yyyy-MM-dd HH:mm:ss.fffffffff; was '" + s + "'");
}
}
diff --git a/luni/src/main/java/java/text/Bidi.java b/luni/src/main/java/java/text/Bidi.java
index e4b30e6..d73ea4a 100644
--- a/luni/src/main/java/java/text/Bidi.java
+++ b/luni/src/main/java/java/text/Bidi.java
@@ -421,28 +421,20 @@ public final class Bidi {
/**
* Returns the base level.
- *
- * @return the base level.
*/
public int getBaseLevel() {
return baseLevel;
}
/**
- * Returns the length of the text in the {@code Bidi} object.
- *
- * @return the length.
+ * Returns the length of the text.
*/
public int getLength() {
return length;
}
/**
- * Returns the level of a specified character.
- *
- * @param offset
- * the offset of the character.
- * @return the level.
+ * Returns the level of the given character.
*/
public int getLevelAt(int offset) {
try {
@@ -453,74 +445,51 @@ public final class Bidi {
}
/**
- * Returns the number of runs in the bidirectional text.
- *
- * @return the number of runs, at least 1.
+ * Returns the number of runs in the text, at least 1.
*/
public int getRunCount() {
return unidirectional ? 1 : runs.length;
}
/**
- * Returns the level of the specified run.
- *
- * @param run
- * the index of the run.
- * @return the level of the run.
+ * Returns the level of the given run.
*/
public int getRunLevel(int run) {
return unidirectional ? baseLevel : runs[run].getLevel();
}
/**
- * Returns the limit offset of the specified run.
- *
- * @param run
- * the index of the run.
- * @return the limit offset of the run.
+ * Returns the limit offset of the given run.
*/
public int getRunLimit(int run) {
return unidirectional ? length : runs[run].getLimit();
}
/**
- * Returns the start offset of the specified run.
- *
- * @param run
- * the index of the run.
- * @return the start offset of the run.
+ * Returns the start offset of the given run.
*/
public int getRunStart(int run) {
return unidirectional ? 0 : runs[run].getStart();
}
/**
- * Indicates whether the text is from left to right, that is, both the base
+ * Returns true if the text is from left to right, that is, both the base
* direction and the text direction is from left to right.
- *
- * @return {@code true} if the text is from left to right; {@code false}
- * otherwise.
*/
public boolean isLeftToRight() {
return direction == UBiDiDirection_UBIDI_LTR;
}
/**
- * Indicates whether the text direction is mixed.
- *
- * @return {@code true} if the text direction is mixed; {@code false}
- * otherwise.
+ * Returns true if the text direction is mixed.
*/
public boolean isMixed() {
return direction == UBiDiDirection_UBIDI_MIXED;
}
/**
- * Indicates whether the text is from right to left, that is, both the base
+ * Returns true if the text is from right to left, that is, both the base
* direction and the text direction is from right to left.
- *
- * @return {@code true} if the text is from right to left; {@code false}
- * otherwise.
*/
public boolean isRightToLeft() {
return direction == UBiDiDirection_UBIDI_RTL;
diff --git a/luni/src/main/java/java/text/BreakIterator.java b/luni/src/main/java/java/text/BreakIterator.java
index b14647c..81545b2 100644
--- a/luni/src/main/java/java/text/BreakIterator.java
+++ b/luni/src/main/java/java/text/BreakIterator.java
@@ -268,13 +268,9 @@ public abstract class BreakIterator implements Cloneable {
/**
* Returns a new instance of {@code BreakIterator} to iterate over
* characters using the given locale.
- *
- * @param where
- * the given locale.
- * @return a new instance of {@code BreakIterator} using the given locale.
*/
- public static BreakIterator getCharacterInstance(Locale where) {
- return new RuleBasedBreakIterator(NativeBreakIterator.getCharacterInstance(where));
+ public static BreakIterator getCharacterInstance(Locale locale) {
+ return new RuleBasedBreakIterator(NativeBreakIterator.getCharacterInstance(locale));
}
/**
@@ -290,14 +286,9 @@ public abstract class BreakIterator implements Cloneable {
/**
* Returns a new instance of {@code BreakIterator} to iterate over
* line breaks using the given locale.
- *
- * @param where
- * the given locale.
- * @return a new instance of {@code BreakIterator} using the given locale.
- * @throws NullPointerException if {@code where} is {@code null}.
*/
- public static BreakIterator getLineInstance(Locale where) {
- return new RuleBasedBreakIterator(NativeBreakIterator.getLineInstance(where));
+ public static BreakIterator getLineInstance(Locale locale) {
+ return new RuleBasedBreakIterator(NativeBreakIterator.getLineInstance(locale));
}
/**
@@ -313,14 +304,9 @@ public abstract class BreakIterator implements Cloneable {
/**
* Returns a new instance of {@code BreakIterator} to iterate over
* sentence-breaks using the given locale.
- *
- * @param where
- * the given locale.
- * @return a new instance of {@code BreakIterator} using the given locale.
- * @throws NullPointerException if {@code where} is {@code null}.
*/
- public static BreakIterator getSentenceInstance(Locale where) {
- return new RuleBasedBreakIterator(NativeBreakIterator.getSentenceInstance(where));
+ public static BreakIterator getSentenceInstance(Locale locale) {
+ return new RuleBasedBreakIterator(NativeBreakIterator.getSentenceInstance(locale));
}
/**
@@ -336,14 +322,9 @@ public abstract class BreakIterator implements Cloneable {
/**
* Returns a new instance of {@code BreakIterator} to iterate over
* word-breaks using the given locale.
- *
- * @param where
- * the given locale.
- * @return a new instance of {@code BreakIterator} using the given locale.
- * @throws NullPointerException if {@code where} is {@code null}.
*/
- public static BreakIterator getWordInstance(Locale where) {
- return new RuleBasedBreakIterator(NativeBreakIterator.getWordInstance(where));
+ public static BreakIterator getWordInstance(Locale locale) {
+ return new RuleBasedBreakIterator(NativeBreakIterator.getWordInstance(locale));
}
/**
diff --git a/luni/src/main/java/java/text/CollationElementIterator.java b/luni/src/main/java/java/text/CollationElementIterator.java
index 5da3b65..4f75a9a 100644
--- a/luni/src/main/java/java/text/CollationElementIterator.java
+++ b/luni/src/main/java/java/text/CollationElementIterator.java
@@ -43,6 +43,11 @@ import libcore.icu.CollationElementIteratorICU;
* "&#92;u0086b": the first collation element is collation_element('a'), the
* second one is collation_element('e'), and the third collation element is
* collation_element('b').
+ *
+ * <p>Note that calls to {@code next} and {@code previous} can not be mixed.
+ * To change iteration direction, {@code reset}, {@code setOffset} or {@code setText}
+ * must be called to reset the iterator. If a change of direction is done without one
+ * of these calls, the result is undefined.
*/
public final class CollationElementIterator {
@@ -61,7 +66,7 @@ public final class CollationElementIterator {
}
/**
- * Obtains the maximum length of any expansion sequence that ends with the
+ * Returns the maximum length of any expansion sequence that ends with the
* specified collation element. Returns {@code 1} if there is no expansion
* with this collation element as the last element.
*
@@ -69,15 +74,13 @@ public final class CollationElementIterator {
* a collation element that has been previously obtained from a
* call to either the {@link #next()} or {@link #previous()}
* method.
- * @return the maximum length of any expansion sequence ending with the
- * specified collation element.
*/
public int getMaxExpansion(int order) {
return this.icuIterator.getMaxExpansion(order);
}
/**
- * Obtains the character offset in the source string corresponding to the
+ * Returns the character offset in the source string corresponding to the
* next collation element. This value could be any of:
* <ul>
* <li>The index of the first character in the source string that matches
@@ -94,42 +97,33 @@ public final class CollationElementIterator {
* <li>The length of the source string, if iteration has reached the end.
* </li>
* </ul>
- *
- * @return The position of the collation element in the source string that
- * will be returned by the next invocation of the {@link #next()}
- * method.
*/
public int getOffset() {
return this.icuIterator.getOffset();
}
/**
- * Obtains the next collation element in the source string.
- *
- * @return the next collation element or {@code NULLORDER} if the end
- * of the iteration has been reached.
+ * Returns the next collation element in the source string or {@code NULLORDER} if
+ * the end of the iteration has been reached.
*/
public int next() {
return this.icuIterator.next();
}
/**
- * Obtains the previous collation element in the source string.
- *
- * @return the previous collation element, or {@code NULLORDER} when
- * the start of the iteration has been reached.
+ * Returns the previous collation element in the source string or {@code NULLORDER} if
+ * the start of the iteration has been reached.
*/
public int previous() {
return this.icuIterator.previous();
}
/**
- * Obtains the primary order of the specified collation element, i.e. the
+ * Returns the primary order of the specified collation element, i.e. the
* first 16 bits. This value is unsigned.
*
* @param order
* the element of the collation.
- * @return the element's 16 bit primary order.
*/
public static final int primaryOrder(int order) {
return CollationElementIteratorICU.primaryOrder(order);
@@ -149,12 +143,11 @@ public final class CollationElementIterator {
}
/**
- * Obtains the secondary order of the specified collation element, i.e. the
+ * Returns the secondary order of the specified collation element, i.e. the
* 16th to 23th bits, inclusive. This value is unsigned.
*
* @param order
* the element of the collator.
- * @return the 8 bit secondary order of the element.
*/
public static final short secondaryOrder(int order) {
return (short) CollationElementIteratorICU.secondaryOrder(order);
@@ -209,12 +202,11 @@ public final class CollationElementIterator {
}
/**
- * Obtains the tertiary order of the specified collation element, i.e. the
+ * Returns the tertiary order of the specified collation element, i.e. the
* last 8 bits. This value is unsigned.
*
* @param order
* the element of the collation.
- * @return the 8 bit tertiary order of the element.
*/
public static final short tertiaryOrder(int order) {
return (short) CollationElementIteratorICU.tertiaryOrder(order);
diff --git a/luni/src/main/java/java/text/DateFormat.java b/luni/src/main/java/java/text/DateFormat.java
index ac64eed..3055843 100644
--- a/luni/src/main/java/java/text/DateFormat.java
+++ b/luni/src/main/java/java/text/DateFormat.java
@@ -388,6 +388,9 @@ public abstract class DateFormat extends Format {
*/
public static final DateFormat getDateInstance(int style, Locale locale) {
checkDateStyle(style);
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
return new SimpleDateFormat(LocaleData.get(locale).getDateFormat(style), locale);
}
@@ -440,6 +443,9 @@ public abstract class DateFormat extends Format {
public static final DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) {
checkTimeStyle(timeStyle);
checkDateStyle(dateStyle);
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
LocaleData localeData = LocaleData.get(locale);
String pattern = localeData.getDateFormat(dateStyle) + " " + localeData.getTimeFormat(timeStyle);
return new SimpleDateFormat(pattern, locale);
@@ -457,6 +463,12 @@ public abstract class DateFormat extends Format {
}
/**
+ * @hide for internal use only.
+ */
+ public static final void set24HourTimePref(boolean is24Hour) {
+ }
+
+ /**
* Returns the {@code NumberFormat} used by this {@code DateFormat}.
*
* @return the {@code NumberFormat} used by this date format.
@@ -508,6 +520,10 @@ public abstract class DateFormat extends Format {
*/
public static final DateFormat getTimeInstance(int style, Locale locale) {
checkTimeStyle(style);
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
+
return new SimpleDateFormat(LocaleData.get(locale).getTimeFormat(style), locale);
}
diff --git a/luni/src/main/java/java/text/DateFormatSymbols.java b/luni/src/main/java/java/text/DateFormatSymbols.java
index e75b82c..ee34bbd 100644
--- a/luni/src/main/java/java/text/DateFormatSymbols.java
+++ b/luni/src/main/java/java/text/DateFormatSymbols.java
@@ -62,16 +62,14 @@ public class DateFormatSymbols implements Serializable, Cloneable {
transient LocaleData localeData;
// Localized display names.
- String[][] zoneStrings;
- // Has the user called setZoneStrings?
- transient boolean customZoneStrings;
+ private String[][] zoneStrings;
- /**
- * Locale, necessary to lazily load time zone strings. We force the time
- * zone names to load upon serialization, so this will never be needed
- * post deserialization.
+ /*
+ * Locale, necessary to lazily load time zone strings. Added to the serialized form for
+ * Android's L release. May be null if the object was deserialized using data from older
+ * releases. See b/16502916.
*/
- transient final Locale locale;
+ private final Locale locale;
/**
* Gets zone strings, initializing them if necessary. Does not create
@@ -102,7 +100,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* the locale.
*/
public DateFormatSymbols(Locale locale) {
- this.locale = locale;
+ this.locale = LocaleData.mapInvalidAndNullLocales(locale);
this.localPatternChars = SimpleDateFormat.PATTERN_CHARS;
this.localeData = LocaleData.get(locale);
@@ -152,6 +150,12 @@ public class DateFormatSymbols implements Serializable, Cloneable {
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
+
+ Locale locale = this.locale;
+ if (locale == null) {
+ // Before the L release Android did not serialize the locale. Handle its absence.
+ locale = Locale.getDefault();
+ }
this.localeData = LocaleData.get(locale);
}
@@ -215,7 +219,6 @@ public class DateFormatSymbols implements Serializable, Cloneable {
// 'zoneStrings' is so large, we just print a representative value.
return getClass().getName() +
"[amPmStrings=" + Arrays.toString(ampms) +
- ",customZoneStrings=" + customZoneStrings +
",eras=" + Arrays.toString(eras) +
",localPatternChars=" + localPatternChars +
",months=" + Arrays.toString(months) +
@@ -251,8 +254,6 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Returns the pattern characters used by {@link SimpleDateFormat} to
* specify date and time fields.
- *
- * @return a string containing the pattern characters.
*/
public String getLocalPatternChars() {
return localPatternChars;
@@ -485,6 +486,25 @@ public class DateFormatSymbols implements Serializable, Cloneable {
}
}
this.zoneStrings = clone2dStringArray(zoneStrings);
- this.customZoneStrings = true;
+ }
+
+ /**
+ * Returns the display name of the timezone specified. Returns null if no name was found in the
+ * zone strings.
+ *
+ * @param daylight whether to return the daylight savings or the standard name
+ * @param style one of the {@link TimeZone} styles such as {@link TimeZone#SHORT}
+ *
+ * @hide used internally
+ */
+ String getTimeZoneDisplayName(TimeZone tz, boolean daylight, int style) {
+ if (style != TimeZone.SHORT && style != TimeZone.LONG) {
+ throw new IllegalArgumentException("Bad style: " + style);
+ }
+
+ // If custom zone strings have been set with setZoneStrings() we use those. Otherwise we
+ // use the ones from LocaleData.
+ String[][] zoneStrings = internalZoneStrings();
+ return TimeZoneNames.getDisplayName(zoneStrings, tz.getID(), daylight, style);
}
}
diff --git a/luni/src/main/java/java/text/DecimalFormat.java b/luni/src/main/java/java/text/DecimalFormat.java
index 948bec1..554fd74 100644
--- a/luni/src/main/java/java/text/DecimalFormat.java
+++ b/luni/src/main/java/java/text/DecimalFormat.java
@@ -373,11 +373,11 @@ import libcore.icu.NativeDecimalFormat;
* digits is fixed at one and there is no exponent grouping.
* <li>Exponential patterns may not contain grouping separators.
* </ul>
- * <a name="sigdig">
+ * <a name="sigdig"></a>
* <h4> <strong><font color="red">NEW</font>&nbsp;</strong> Significant
* Digits</h4>
* <p>
- * </a> {@code DecimalFormat} has two ways of controlling how many digits are
+ * {@code DecimalFormat} has two ways of controlling how many digits are
* shown: (a) significant digit counts or (b) integer and fraction digit counts.
* Integer and fraction digit counts are described above. When a formatter uses
* significant digits counts, the number of integer and fraction digits is not
@@ -487,6 +487,12 @@ import libcore.icu.NativeDecimalFormat;
* <em>escapes</em> the following character. If there is no character after
* the pad escape, then the pattern is illegal.</li>
* </ul>
+ *
+ * <h4>Serialization</h4>
+ * <p>
+ * Features marked as <strong><font color="red">NEW</font></strong> and patterns that use
+ * characters not documented above are unlikely to serialize/deserialize correctly.
+ *
* <h4>Synchronization</h4>
* <p>
* {@code DecimalFormat} objects are not synchronized. Multiple threads should
@@ -574,6 +580,7 @@ public class DecimalFormat extends NumberFormat {
*/
public void applyLocalizedPattern(String pattern) {
ndf.applyLocalizedPattern(pattern);
+ updateFieldsFromNative();
}
/**
@@ -586,7 +593,18 @@ public class DecimalFormat extends NumberFormat {
* if the pattern cannot be parsed.
*/
public void applyPattern(String pattern) {
+ // The underlying ICU4C accepts a super-set of the pattern spec documented by the Android
+ // APIs. For example, rounding increments (pattern characters '1'-'9'). They will work but
+ // see class doc for issues with serialization/deserialization they may cause.
ndf.applyPattern(pattern);
+ updateFieldsFromNative();
+ }
+
+ private void updateFieldsFromNative() {
+ maximumIntegerDigits = ndf.getMaximumIntegerDigits();
+ minimumIntegerDigits = ndf.getMinimumIntegerDigits();
+ maximumFractionDigits = ndf.getMaximumFractionDigits();
+ minimumFractionDigits = ndf.getMinimumFractionDigits();
}
/**
@@ -659,21 +677,6 @@ public class DecimalFormat extends NumberFormat {
@Override
public StringBuffer format(double value, StringBuffer buffer, FieldPosition position) {
checkBufferAndFieldPosition(buffer, position);
- // All float/double/Float/Double formatting ends up here...
- if (roundingMode == RoundingMode.UNNECESSARY) {
- // ICU4C doesn't support this rounding mode, so we have to fake it.
- try {
- setRoundingMode(RoundingMode.UP);
- String upResult = format(value, new StringBuffer(), new FieldPosition(0)).toString();
- setRoundingMode(RoundingMode.DOWN);
- String downResult = format(value, new StringBuffer(), new FieldPosition(0)).toString();
- if (!upResult.equals(downResult)) {
- throw new ArithmeticException("rounding mode UNNECESSARY but rounding required");
- }
- } finally {
- setRoundingMode(RoundingMode.UNNECESSARY);
- }
- }
buffer.append(ndf.formatDouble(value, position));
return buffer;
}
@@ -735,16 +738,6 @@ public class DecimalFormat extends NumberFormat {
}
/**
- * Returns the multiplier which is applied to the number before formatting
- * or after parsing.
- *
- * @return the multiplier.
- */
- public int getMultiplier() {
- return ndf.getMultiplier();
- }
-
- /**
* Returns the prefix which is formatted or parsed before a negative number.
*
* @return the negative prefix.
@@ -826,16 +819,10 @@ public class DecimalFormat extends NumberFormat {
// In this implementation, NativeDecimalFormat is wrapped to
// fulfill most of the format and parse feature. And this method is
// delegated to the wrapped instance of NativeDecimalFormat.
+ super.setParseIntegerOnly(value);
ndf.setParseIntegerOnly(value);
}
- /**
- * Indicates whether parsing with this decimal format will only
- * return numbers of type {@code java.lang.Integer}.
- *
- * @return {@code true} if this {@code DecimalFormat}'s parse method only
- * returns {@code java.lang.Integer}; {@code false} otherwise.
- */
@Override
public boolean isParseIntegerOnly() {
return ndf.isParseIntegerOnly();
@@ -898,9 +885,6 @@ public class DecimalFormat extends NumberFormat {
/**
* Sets the {@code DecimalFormatSymbols} used by this decimal format.
- *
- * @param value
- * the {@code DecimalFormatSymbols} to set.
*/
public void setDecimalFormatSymbols(DecimalFormatSymbols value) {
if (value != null) {
@@ -913,24 +897,17 @@ public class DecimalFormat extends NumberFormat {
/**
* Sets the currency used by this decimal format. The min and max fraction
* digits remain the same.
- *
- * @param currency
- * the currency this {@code DecimalFormat} should use.
- * @see DecimalFormatSymbols#setCurrency(Currency)
*/
@Override
public void setCurrency(Currency currency) {
- ndf.setCurrency(Currency.getInstance(currency.getCurrencyCode()));
- symbols.setCurrency(currency);
+ Currency instance = Currency.getInstance(currency.getCurrencyCode());
+ symbols.setCurrency(instance);
+ ndf.setCurrency(symbols.getCurrencySymbol(), currency.getCurrencyCode());
}
/**
- * Sets whether the decimal separator is shown when there are no fractional
+ * Sets whether the decimal separator is shown even when there are no fractional
* digits.
- *
- * @param value
- * {@code true} if the decimal separator should always be
- * formatted; {@code false} otherwise.
*/
public void setDecimalSeparatorAlwaysShown(boolean value) {
ndf.setDecimalSeparatorAlwaysShown(value);
@@ -940,20 +917,14 @@ public class DecimalFormat extends NumberFormat {
* Sets the number of digits grouped together by the grouping separator.
* This only allows to set the primary grouping size; the secondary grouping
* size can only be set with a pattern.
- *
- * @param value
- * the number of digits grouped together.
*/
public void setGroupingSize(int value) {
ndf.setGroupingSize(value);
}
/**
- * Sets whether or not grouping will be used in this format. Grouping
- * affects both parsing and formatting.
- *
- * @param value
- * {@code true} if grouping is used; {@code false} otherwise.
+ * Sets whether or not digit grouping will be used in this format. Grouping
+ * affects both formatting and parsing.
*/
@Override
public void setGroupingUsed(boolean value) {
@@ -961,9 +932,8 @@ public class DecimalFormat extends NumberFormat {
}
/**
- * Indicates whether grouping will be used in this format.
- *
- * @return {@code true} if grouping is used; {@code false} otherwise.
+ * Returns true if digit grouping is used in this format. Grouping affects both
+ * formatting and parsing.
*/
@Override
public boolean isGroupingUsed() {
@@ -974,8 +944,6 @@ public class DecimalFormat extends NumberFormat {
* Sets the maximum number of digits after the decimal point.
* If the value passed is negative then it is replaced by 0.
* Regardless of this setting, no more than 340 digits will be used.
- *
- * @param value the maximum number of fraction digits.
*/
@Override
public void setMaximumFractionDigits(int value) {
@@ -989,8 +957,6 @@ public class DecimalFormat extends NumberFormat {
* Sets the maximum number of digits before the decimal point.
* If the value passed is negative then it is replaced by 0.
* Regardless of this setting, no more than 309 digits will be used.
- *
- * @param value the maximum number of integer digits.
*/
@Override
public void setMaximumIntegerDigits(int value) {
@@ -1002,8 +968,6 @@ public class DecimalFormat extends NumberFormat {
* Sets the minimum number of digits after the decimal point.
* If the value passed is negative then it is replaced by 0.
* Regardless of this setting, no more than 340 digits will be used.
- *
- * @param value the minimum number of fraction digits.
*/
@Override
public void setMinimumFractionDigits(int value) {
@@ -1015,8 +979,6 @@ public class DecimalFormat extends NumberFormat {
* Sets the minimum number of digits before the decimal point.
* If the value passed is negative then it is replaced by 0.
* Regardless of this setting, no more than 309 digits will be used.
- *
- * @param value the minimum number of integer digits.
*/
@Override
public void setMinimumIntegerDigits(int value) {
@@ -1025,11 +987,20 @@ public class DecimalFormat extends NumberFormat {
}
/**
+ * Returns the multiplier which is applied to the number before formatting
+ * or after parsing. The multiplier is meant for tasks like parsing percentages.
+ * For example, given a multiplier of 100, 1.23 would be formatted as "123" and
+ * "123" would be parsed as 1.23.
+ */
+ public int getMultiplier() {
+ return ndf.getMultiplier();
+ }
+
+ /**
* Sets the multiplier which is applied to the number before formatting or
- * after parsing.
- *
- * @param value
- * the multiplier.
+ * after parsing. The multiplier meant for tasks like parsing percentages.
+ * For example, given a multiplier of 100, 1.23 would be formatted as "123" and
+ * "123" would be parsed as 1.23.
*/
public void setMultiplier(int value) {
ndf.setMultiplier(value);
@@ -1037,9 +1008,6 @@ public class DecimalFormat extends NumberFormat {
/**
* Sets the prefix which is formatted or parsed before a negative number.
- *
- * @param value
- * the negative prefix.
*/
public void setNegativePrefix(String value) {
ndf.setNegativePrefix(value);
@@ -1047,9 +1015,6 @@ public class DecimalFormat extends NumberFormat {
/**
* Sets the suffix which is formatted or parsed after a negative number.
- *
- * @param value
- * the negative suffix.
*/
public void setNegativeSuffix(String value) {
ndf.setNegativeSuffix(value);
@@ -1057,9 +1022,6 @@ public class DecimalFormat extends NumberFormat {
/**
* Sets the prefix which is formatted or parsed before a positive number.
- *
- * @param value
- * the positive prefix.
*/
public void setPositivePrefix(String value) {
ndf.setPositivePrefix(value);
@@ -1067,9 +1029,6 @@ public class DecimalFormat extends NumberFormat {
/**
* Sets the suffix which is formatted or parsed after a positive number.
- *
- * @param value
- * the positive suffix.
*/
public void setPositiveSuffix(String value) {
ndf.setPositiveSuffix(value);
@@ -1239,9 +1198,12 @@ public class DecimalFormat extends NumberFormat {
throw new NullPointerException("roundingMode == null");
}
this.roundingMode = roundingMode;
- if (roundingMode != RoundingMode.UNNECESSARY) { // ICU4C doesn't support UNNECESSARY.
- double roundingIncrement = 1.0 / Math.pow(10, Math.max(0, getMaximumFractionDigits()));
- ndf.setRoundingMode(roundingMode, roundingIncrement);
- }
+ // DecimalFormat does not allow specification of a rounding increment. If anything other
+ // than 0.0 is used here the resulting DecimalFormat cannot be deserialized because the
+ // serialization format does not include rounding increment information.
+ double roundingIncrement = 0.0;
+ ndf.setRoundingMode(roundingMode, roundingIncrement);
}
+
+ public String toString() { return ndf.toString(); }
}
diff --git a/luni/src/main/java/java/text/DecimalFormatSymbols.java b/luni/src/main/java/java/text/DecimalFormatSymbols.java
index 708b291..fba2d6e 100644
--- a/luni/src/main/java/java/text/DecimalFormatSymbols.java
+++ b/luni/src/main/java/java/text/DecimalFormatSymbols.java
@@ -50,7 +50,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
private char percent;
private char perMill;
private char monetarySeparator;
- private char minusSign;
+ private String minusSign;
private String infinity, NaN, currencySymbol, intlCurrencySymbol;
private transient Currency currency;
@@ -81,6 +81,11 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
* the locale.
*/
public DecimalFormatSymbols(Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
+
+ locale = LocaleData.mapInvalidAndNullLocales(locale);
LocaleData localeData = LocaleData.get(locale);
this.zeroDigit = localeData.zeroDigit;
this.digit = '#';
@@ -179,7 +184,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
groupingSeparator == obj.groupingSeparator &&
infinity.equals(obj.infinity) &&
intlCurrencySymbol.equals(obj.intlCurrencySymbol) &&
- minusSign == obj.minusSign &&
+ minusSign.equals(obj.minusSign) &&
monetarySeparator == obj.monetarySeparator &&
NaN.equals(obj.NaN) &&
patternSeparator == obj.patternSeparator &&
@@ -288,6 +293,16 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
* @return the minus sign as a character.
*/
public char getMinusSign() {
+ if (minusSign.length() == 1) {
+ return minusSign.charAt(0);
+ }
+
+ throw new UnsupportedOperationException(
+ "Minus sign spans multiple characters: " + minusSign);
+ }
+
+ /** @hide */
+ public String getMinusSignString() {
return minusSign;
}
@@ -366,7 +381,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
result = 31*result + percent;
result = 31*result + perMill;
result = 31*result + monetarySeparator;
- result = 31*result + minusSign;
+ result = 31*result + minusSign.hashCode();
result = 31*result + exponentSeparator.hashCode();
result = 31*result + infinity.hashCode();
result = 31*result + NaN.hashCode();
@@ -487,7 +502,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
* the minus sign character.
*/
public void setMinusSign(char value) {
- this.minusSign = value;
+ this.minusSign = String.valueOf(value);
}
/**
diff --git a/luni/src/main/java/java/text/FieldPosition.java b/luni/src/main/java/java/text/FieldPosition.java
index d5bccc7..c26ba33 100644
--- a/luni/src/main/java/java/text/FieldPosition.java
+++ b/luni/src/main/java/java/text/FieldPosition.java
@@ -21,152 +21,114 @@ package java.text;
* Identifies fields in formatted strings. If a {@code FieldPosition} is passed
* to the format method with such a parameter, then the indices will be set to
* the start and end indices of the field in the formatted string.
- * <p>
- * A {@code FieldPosition} can be created by using the integer constants in the
+ *
+ * <p>A {@code FieldPosition} can be created by using the integer constants in the
* various format classes (for example {@code NumberFormat.INTEGER_FIELD}) or
* one of the fields of type {@code Format.Field}.
- * <p>
- * If more than one field information is needed, the method
+ *
+ * <p>If more than one field position is needed, the method
* {@link NumberFormat#formatToCharacterIterator(Object)} should be used.
*/
public class FieldPosition {
- private int myField, beginIndex, endIndex;
-
- private Format.Field myAttribute;
-
- /**
- * Constructs a new {@code FieldPosition} for the specified field.
- *
- * @param field
- * the field to identify.
- */
- public FieldPosition(int field) {
- myField = field;
- }
-
- /**
- * Constructs a new {@code FieldPosition} for the specified {@code Field}
- * attribute.
- *
- * @param attribute
- * the field attribute to identify.
- */
- public FieldPosition(Format.Field attribute) {
- myAttribute = attribute;
- myField = -1;
- }
-
- /**
- * Constructs a new {@code FieldPosition} for the specified {@code Field}
- * attribute and field id.
- *
- * @param attribute
- * the field attribute to identify.
- * @param field
- * the field to identify.
- */
- public FieldPosition(Format.Field attribute, int field) {
- myAttribute = attribute;
- myField = field;
- }
-
- void clear() {
- beginIndex = endIndex = 0;
- }
-
- /**
- * Compares the specified object to this field position and indicates if
- * they are equal. In order to be equal, {@code object} must be an instance
- * of {@code FieldPosition} with the same field, begin index and end index.
- *
- * @param object
- * the object to compare with this object.
- * @return {@code true} if the specified object is equal to this field
- * position; {@code false} otherwise.
- * @see #hashCode
- */
- @Override
- public boolean equals(Object object) {
- if (!(object instanceof FieldPosition)) {
- return false;
- }
- FieldPosition pos = (FieldPosition) object;
- return myField == pos.myField && myAttribute == pos.myAttribute
- && beginIndex == pos.beginIndex && endIndex == pos.endIndex;
- }
-
- /**
- * Returns the index of the beginning of the field.
- *
- * @return the first index of the field.
- */
- public int getBeginIndex() {
- return beginIndex;
- }
-
- /**
- * Returns the index one past the end of the field.
- *
- * @return one past the index of the last character in the field.
- */
- public int getEndIndex() {
- return endIndex;
- }
-
- /**
- * Returns the field which is being identified.
- *
- * @return the field constant.
- */
- public int getField() {
- return myField;
- }
-
- /**
- * Returns the attribute which is being identified.
- *
- * @return the field.
- */
- public Format.Field getFieldAttribute() {
- return myAttribute;
- }
-
- @Override
- public int hashCode() {
- int attributeHash = (myAttribute == null) ? 0 : myAttribute.hashCode();
- return attributeHash + myField * 10 + beginIndex * 100 + endIndex;
- }
-
- /**
- * Sets the index of the beginning of the field.
- *
- * @param index
- * the index of the first character in the field.
- */
- public void setBeginIndex(int index) {
- beginIndex = index;
- }
-
- /**
- * Sets the index of the end of the field.
- *
- * @param index
- * one past the index of the last character in the field.
- */
- public void setEndIndex(int index) {
- endIndex = index;
- }
-
- /**
- * Returns the string representation of this field position.
- *
- * @return the string representation of this field position.
- */
- @Override
- public String toString() {
- return getClass().getName() + "[attribute=" + myAttribute + ", field="
- + myField + ", beginIndex=" + beginIndex + ", endIndex="
- + endIndex + "]";
+ private int field;
+ private int beginIndex;
+ private int endIndex;
+ private Format.Field attribute;
+
+ /**
+ * Constructs a new {@code FieldPosition} for the given field id.
+ */
+ public FieldPosition(int field) {
+ this.field = field;
+ }
+
+ /**
+ * Constructs a new {@code FieldPosition} for the given {@code Field} attribute.
+ */
+ public FieldPosition(Format.Field attribute) {
+ this.attribute = attribute;
+ this.field = -1;
+ }
+
+ /**
+ * Constructs a new {@code FieldPosition} for the given {@code Field} attribute and field id.
+ */
+ public FieldPosition(Format.Field attribute, int field) {
+ this.attribute = attribute;
+ this.field = field;
+ }
+
+ /**
+ * Compares the given object to this field position and indicates if
+ * they are equal. In order to be equal, {@code object} must be an instance
+ * of {@code FieldPosition} with the same field, begin index and end index.
+ */
+ @Override public boolean equals(Object object) {
+ if (!(object instanceof FieldPosition)) {
+ return false;
}
+ FieldPosition pos = (FieldPosition) object;
+ return field == pos.field && this.attribute == pos.attribute &&
+ beginIndex == pos.beginIndex && endIndex == pos.endIndex;
+ }
+
+ /**
+ * Returns the index of the beginning of the field.
+ */
+ public int getBeginIndex() {
+ return beginIndex;
+ }
+
+ /**
+ * Returns the index one past the end of the field.
+ */
+ public int getEndIndex() {
+ return endIndex;
+ }
+
+ /**
+ * Returns the field which is being identified.
+ */
+ public int getField() {
+ return field;
+ }
+
+ /**
+ * Returns the attribute which is being identified.
+ */
+ public Format.Field getFieldAttribute() {
+ return attribute;
+ }
+
+ @Override public int hashCode() {
+ int attributeHash = (attribute == null) ? 0 : attribute.hashCode();
+ return attributeHash + field * 10 + beginIndex * 100 + endIndex;
+ }
+
+ /**
+ * Sets the index of the beginning of the field.
+ */
+ public void setBeginIndex(int index) {
+ beginIndex = index;
+ }
+
+ /**
+ * Sets the index of the end of the field.
+ */
+ public void setEndIndex(int index) {
+ endIndex = index;
+ }
+
+ /**
+ * Returns the string representation of this field position.
+ */
+ @Override public String toString() {
+ return getClass().getName() + "[" +
+ "attribute=" + attribute +
+ ",field=" + field +
+ ",beginIndex=" + beginIndex +
+ ",endIndex=" + endIndex +
+ "]";
+ }
}
diff --git a/luni/src/main/java/java/text/MessageFormat.java b/luni/src/main/java/java/text/MessageFormat.java
index 2ab78db..cf306a7 100644
--- a/luni/src/main/java/java/text/MessageFormat.java
+++ b/luni/src/main/java/java/text/MessageFormat.java
@@ -45,7 +45,7 @@ import libcore.util.EmptyArray;
* behavior. Any locale-specific behavior is defined by the pattern that you
* provide as well as the subformats used for inserted arguments.
*
- * <h4><a name="patterns">Patterns and their interpretation</a></h4>
+ * <h4><a name="patterns"></a>Patterns and their interpretation</h4>
*
* {@code MessageFormat} uses patterns of the following form:
* <blockquote>
@@ -321,7 +321,7 @@ import libcore.util.EmptyArray;
* // result now equals {new String("z")}
* </pre>
* </blockquote>
- * <h4><a name="synchronization">Synchronization</a></h4>
+ * <h4><a name="synchronization"></a>Synchronization</h4>
* <p>
* Message formats are not synchronized. It is recommended to create separate
* format instances for each thread. If multiple threads access a format
diff --git a/luni/src/main/java/java/text/NumberFormat.java b/luni/src/main/java/java/text/NumberFormat.java
index 36fdd0f..a1f10d4 100644
--- a/luni/src/main/java/java/text/NumberFormat.java
+++ b/luni/src/main/java/java/text/NumberFormat.java
@@ -155,8 +155,10 @@ public abstract class NumberFormat extends Format {
private boolean groupingUsed = true, parseIntegerOnly = false;
- private int maximumIntegerDigits = 40, minimumIntegerDigits = 1,
- maximumFractionDigits = 3, minimumFractionDigits = 0;
+ int maximumIntegerDigits = 40;
+ int minimumIntegerDigits = 1;
+ int maximumFractionDigits = 3;
+ int minimumFractionDigits = 0;
/**
* Used by subclasses. This was public in Java 5.
@@ -208,8 +210,7 @@ public abstract class NumberFormat extends Format {
* @return the formatted string.
*/
public final String format(double value) {
- return format(value, new StringBuffer(), new FieldPosition(0))
- .toString();
+ return format(value, new StringBuffer(), new FieldPosition(0)).toString();
}
/**
@@ -241,8 +242,7 @@ public abstract class NumberFormat extends Format {
* @return the formatted string.
*/
public final String format(long value) {
- return format(value, new StringBuffer(), new FieldPosition(0))
- .toString();
+ return format(value, new StringBuffer(), new FieldPosition(0)).toString();
}
/**
@@ -301,7 +301,11 @@ public abstract class NumberFormat extends Format {
double dv = ((Number) object).doubleValue();
return format(dv, buffer, field);
}
- throw new IllegalArgumentException("Bad class: " + object.getClass());
+ if (object == null) {
+ throw new IllegalArgumentException("Can't format null object");
+ } else {
+ throw new IllegalArgumentException("Bad class: " + object.getClass());
+ }
}
/**
@@ -349,6 +353,10 @@ public abstract class NumberFormat extends Format {
* @return a {@code NumberFormat} for handling currency values.
*/
public static NumberFormat getCurrencyInstance(Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
+
return getInstance(LocaleData.get(locale).currencyPattern, locale);
}
@@ -372,6 +380,10 @@ public abstract class NumberFormat extends Format {
* @return a {@code NumberFormat} for handling integers.
*/
public static NumberFormat getIntegerInstance(Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
+
NumberFormat result = getInstance(LocaleData.get(locale).integerPattern, locale);
result.setParseIntegerOnly(true);
return result;
@@ -465,6 +477,9 @@ public abstract class NumberFormat extends Format {
* @return a {@code NumberFormat} for handling {@code Number} objects.
*/
public static NumberFormat getNumberInstance(Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
return getInstance(LocaleData.get(locale).numberPattern, locale);
}
@@ -492,6 +507,10 @@ public abstract class NumberFormat extends Format {
* treated as 5,300%, which is rarely what you intended.
*/
public static NumberFormat getPercentInstance(Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
+
return getInstance(LocaleData.get(locale).percentPattern, locale);
}
@@ -514,11 +533,8 @@ public abstract class NumberFormat extends Format {
}
/**
- * Indicates whether this number format only parses integer numbers. Parsing
+ * Returns true if this number format only parses integer numbers. Parsing
* stops if a decimal separator is encountered.
- *
- * @return {@code true} if this number format only parses integers,
- * {@code false} if if parsese integers as well as fractions.
*/
public boolean isParseIntegerOnly() {
return parseIntegerOnly;
@@ -742,10 +758,6 @@ public abstract class NumberFormat extends Format {
* The instances of this inner class are used as attribute keys and values
* in {@code AttributedCharacterIterator} that the
* {@link NumberFormat#formatToCharacterIterator(Object)} method returns.
- * <p>
- * There is no public constructor in this class, the only instances are the
- * constants defined here.
- * <p>
*/
public static class Field extends Format.Field {
@@ -809,9 +821,6 @@ public abstract class NumberFormat extends Format {
/**
* Constructs a new instance of {@code NumberFormat.Field} with the
* given field name.
- *
- * @param fieldName
- * the field name.
*/
protected Field(String fieldName) {
super(fieldName);
diff --git a/luni/src/main/java/java/text/RuleBasedCollator.java b/luni/src/main/java/java/text/RuleBasedCollator.java
index cda06db..4e84ef7 100644
--- a/luni/src/main/java/java/text/RuleBasedCollator.java
+++ b/luni/src/main/java/java/text/RuleBasedCollator.java
@@ -20,243 +20,60 @@ package java.text;
import libcore.icu.RuleBasedCollatorICU;
/**
- * A concrete implementation class for {@code Collation}.
- * <p>
- * {@code RuleBasedCollator} has the following restrictions for efficiency
- * (other subclasses may be used for more complex languages):
- * <ol>
- * <li> If a French secondary ordering is specified it applies to the whole
- * collator object.</li>
- * <li> All non-mentioned Unicode characters are at the end of the collation
- * order.</li>
- * <li> If a character is not located in the {@code RuleBasedCollator}, the
- * default Unicode Collation Algorithm (UCA) rule-based table is automatically
- * searched as a backup.</li>
- * </ol>
- * <p>
- * The collation table is composed of a list of collation rules, where each rule
- * is of three forms:
- * <blockquote>
- * <pre>
- * &lt;modifier&gt;
- * &lt;relation&gt; &lt;text-argument&gt;
- * &lt;reset&gt; &lt;text-argument&gt;
- * </pre>
- * </blockquote>
- * <p>
- * The rule elements are defined as follows:
- * <ul type="disc">
- * <li><strong>Modifier</strong>: There is a single modifier which is used to
- * specify that all accents (secondary differences) are backwards:
- * <ul type=square>
- * <li>'@' : Indicates that accents are sorted backwards, as in French.
- * </ul>
- * </li>
- * <li><strong>Relation</strong>: The relations are the following:
- * <ul type=square>
- * <li>'&lt;' : Greater, as a letter difference (primary)
- * <li>';' : Greater, as an accent difference (secondary)
- * <li>',' : Greater, as a case difference (tertiary)
- * <li>'=' : Equal
- * </ul>
- * </li>
- * <li><strong>Text-Argument</strong>: A text-argument is any sequence of
- * characters, excluding special characters (that is, common whitespace
- * characters [0009-000D, 0020] and rule syntax characters [0021-002F,
- * 003A-0040, 005B-0060, 007B-007E]). If those characters are desired, you can
- * put them in single quotes (for example, use '&amp;' for ampersand). Note that
- * unquoted white space characters are ignored; for example, {@code b c} is
- * treated as {@code bc}.</li>
- * <li><strong>Reset</strong>: There is a single reset which is used primarily
- * for contractions and expansions, but which can also be used to add a
- * modification at the end of a set of rules:
- * <ul type=square>
- * <li>'&amp;' : Indicates that the next rule follows the position to where the reset
- * text-argument would be sorted.
- * </ul>
- * </li>
- * </ul>
- * <p>
- * This sounds more complicated than it is in practice. For example, the
- * following are equivalent ways of expressing the same thing:
- * <blockquote>
+ * A concrete subclass of {@link Collator}.
+ * It is based on the ICU RuleBasedCollator which implements the
+ * CLDR and Unicode collation algorithms.
+ *
+ * <p>Most of the time, you create a {@link Collator} instance for a {@link java.util.Locale}
+ * by calling the {@link Collator#getInstance} factory method.
+ * You can construct a {@code RuleBasedCollator} if you need a custom sort order.
+ *
+ * <p>The root collator's sort order is the CLDR root collation order
+ * which in turn is the Unicode default sort order with a few modifications.
+ * A {@code RuleBasedCollator} is built from a rule {@code String} which changes the
+ * sort order of some characters and strings relative to the default order.
+ *
+ * <p>A rule string usually contains one or more rule chains.
+ * A rule chain consists of a reset followed by one or more rules.
+ * The reset anchors the following rules in the default sort order.
+ * The rules change the order of the their characters and strings
+ * relative to the reset point.
+ *
+ * <p>A reset is an ampersand {@code &amp;} followed by one or more characters for the reset position.
+ * A rule is a relation operator, which specifies the level of difference,
+ * also followed by one or more characters.
+ * A multi-character rule creates a "contraction".
+ * A multi-character reset position usually creates "expansions".
+ *
+ * <p>For example, the following rules
+ * make "ä" sort with a diacritic-like (secondary) difference from "ae"
+ * (like in German phonebook sorting),
+ * and make "Ã¥" and "aa" sort as a base letter (primary) after "z" (like in Danish).
+ * Uppercase forms sort with a case-like (tertiary) difference after their lowercase forms.
*
- * <pre>
- * a < b < c
- * a < b & b < c
- * a < c & a < b
- * </pre>
- *
- * </blockquote>
- * <p>
- * Notice that the order is important, as the subsequent item goes immediately
- * after the text-argument. The following are not equivalent:
* <blockquote>
- *
* <pre>
- * a < b & a < c
- * a < c & a < b
+ * &amp;AE&lt;&lt;ä &lt;&lt;&lt;Ä
+ * &amp;z&lt;Ã¥&lt;&lt;&lt;Ã…&lt;&lt;&lt;aa&lt;&lt;&lt;Aa&lt;&lt;&lt;AA
* </pre>
- *
* </blockquote>
- * <p>
- * Either the text-argument must already be present in the sequence, or some
- * initial substring of the text-argument must be present. For example
- * {@code "a < b & ae < e"} is valid since "a" is present in the sequence before
- * "ae" is reset. In this latter case, "ae" is not entered and treated as a
- * single character; instead, "e" is sorted as if it were expanded to two
- * characters: "a" followed by an "e". This difference appears in natural
- * languages: in traditional Spanish "ch" is treated as if it contracts to a
- * single character (expressed as {@code "c < ch < d"}), while in traditional
- * German a-umlaut is treated as if it expands to two characters (expressed as
- * {@code "a,A < b,B ... & ae;\u00e3 & AE;\u00c3"}, where \u00e3 and \u00c3
- * are the escape sequences for a-umlaut).
- * <h4>Ignorable Characters</h4>
- * <p>
- * For ignorable characters, the first rule must start with a relation (the
- * examples we have used above are really fragments; {@code "a < b"} really
- * should be {@code "< a < b"}). If, however, the first relation is not
- * {@code "<"}, then all text-arguments up to the first {@code "<"} are
- * ignorable. For example, {@code ", - < a < b"} makes {@code "-"} an ignorable
- * character.
- * <h4>Normalization and Accents</h4>
- * <p>
- * {@code RuleBasedCollator} automatically processes its rule table to include
- * both pre-composed and combining-character versions of accented characters.
- * Even if the provided rule string contains only base characters and separate
- * combining accent characters, the pre-composed accented characters matching
- * all canonical combinations of characters from the rule string will be entered
- * in the table.
- * <p>
- * This allows you to use a RuleBasedCollator to compare accented strings even
- * when the collator is set to NO_DECOMPOSITION. However, if the strings to be
- * collated contain combining sequences that may not be in canonical order, you
- * should set the collator to CANONICAL_DECOMPOSITION to enable sorting of
- * combining sequences. For more information, see <a
- * href="http://www.aw.com/devpress">The Unicode Standard, Version 3.0</a>.
- * <h4>Errors</h4>
- * <p>
- * The following rules are not valid:
- * <ul type="disc">
- * <li>A text-argument contains unquoted punctuation symbols, for example
- * {@code "a < b-c < d"}.</li>
- * <li>A relation or reset character is not followed by a text-argument, for
- * example {@code "a < , b"}.</li>
- * <li>A reset where the text-argument (or an initial substring of the
- * text-argument) is not already in the sequence or allocated in the default UCA
- * table, for example {@code "a < b & e < f"}.</li>
- * </ul>
- * <p>
- * If you produce one of these errors, {@code RuleBasedCollator} throws a
- * {@code ParseException}.
- * <h4>Examples</h4>
- * <p>
- * Normally, to create a rule-based collator object, you will use
- * {@code Collator}'s factory method {@code getInstance}. However, to create a
- * rule-based collator object with specialized rules tailored to your needs, you
- * construct the {@code RuleBasedCollator} with the rules contained in a
- * {@code String} object. For example:
- * <blockquote>
- *
- * <pre>
- * String Simple = "< a < b < c < d";
- * RuleBasedCollator mySimple = new RuleBasedCollator(Simple);
- * </pre>
- *
- * </blockquote>
- * <p>
- * Or:
- * <blockquote>
- *
- * <pre>
- * String Norwegian = "< a,A< b,B< c,C< d,D< e,E< f,F< g,G< h,H< i,I"
- * + "< j,J< k,K< l,L< m,M< n,N< o,O< p,P< q,Q< r,R"
- * + "< s,S< t,T< u,U< v,V< w,W< x,X< y,Y< z,Z"
- * + "< \u00E5=a\u030A,\u00C5=A\u030A"
- * + ";aa,AA< \u00E6,\u00C6< \u00F8,\u00D8";
- * RuleBasedCollator myNorwegian = new RuleBasedCollator(Norwegian);
- * </pre>
- *
- * </blockquote>
- * <p>
- * Combining {@code Collator}s is as simple as concatenating strings. Here is
- * an example that combines two {@code Collator}s from two different locales:
- * <blockquote>
- *
- * <pre>
- * // Create an en_US Collator object
- * RuleBasedCollator en_USCollator = (RuleBasedCollator)Collator
- * .getInstance(new Locale("en", "US", ""));
- *
- * // Create a da_DK Collator object
- * RuleBasedCollator da_DKCollator = (RuleBasedCollator)Collator
- * .getInstance(new Locale("da", "DK", ""));
*
- * // Combine the two collators
- * // First, get the collation rules from en_USCollator
- * String en_USRules = en_USCollator.getRules();
- *
- * // Second, get the collation rules from da_DKCollator
- * String da_DKRules = da_DKCollator.getRules();
- *
- * RuleBasedCollator newCollator = new RuleBasedCollator(en_USRules + da_DKRules);
- * // newCollator has the combined rules
- * </pre>
- *
- * </blockquote>
- * <p>
- * The next example shows to make changes on an existing table to create a new
- * {@code Collator} object. For example, add {@code "& C < ch, cH, Ch, CH"} to
- * the {@code en_USCollator} object to create your own:
- * <blockquote>
- *
- * <pre>
- * // Create a new Collator object with additional rules
- * String addRules = "& C < ch, cH, Ch, CH";
- *
- * RuleBasedCollator myCollator = new RuleBasedCollator(en_USCollator + addRules);
- * // myCollator contains the new rules
- * </pre>
- *
- * </blockquote>
- * <p>
- * The following example demonstrates how to change the order of non-spacing
- * accents:
- * <blockquote>
- *
- * <pre>
- * // old rule
- * String oldRules = "= \u00a8 ; \u00af ; \u00bf" + "< a , A ; ae, AE ; \u00e6 , \u00c6"
- * + "< b , B < c, C < e, E & C < d, D";
- *
- * // change the order of accent characters
- * String addOn = "& \u00bf ; \u00af ; \u00a8;";
- *
- * RuleBasedCollator myCollator = new RuleBasedCollator(oldRules + addOn);
- * </pre>
- *
- * </blockquote>
- * <p>
- * The last example shows how to put new primary ordering in before the default
- * setting. For example, in the Japanese {@code Collator}, you can either sort
- * English characters before or after Japanese characters:
- * <blockquote>
- *
- * <pre>
- * // get en_US Collator rules
- * RuleBasedCollator en_USCollator = (RuleBasedCollator)
- * Collator.getInstance(Locale.US);
- *
- * // add a few Japanese character to sort before English characters
- * // suppose the last character before the first base letter 'a' in
- * // the English collation rule is \u30A2
- * String jaString = "& \u30A2 , \u30FC < \u30C8";
+ * <p>For details see
+ * <ul>
+ * <li>CLDR <a href="http://www.unicode.org/reports/tr35/tr35-collation.html#Rules">Collation Rule Syntax</a>
+ * <li>ICU User Guide <a href="http://userguide.icu-project.org/collation/customization">Collation Customization</a>
+ * </ul>
*
- * RuleBasedCollator myJapaneseCollator =
- * new RuleBasedCollator(en_USCollator.getRules() + jaString);
- * </pre>
+ * <p>Note: earlier versions of {@code RuleBasedCollator} up to and including Android 4.4 (KitKat)
+ * allowed the omission of the reset from the first rule chain.
+ * This was interpreted as an implied reset after the last non-Han script in the default order.
+ * However, this is not a useful reset position, except for large tailorings of
+ * Han characters themselves.
+ * Starting with the CLDR 24 collation specification and the ICU 53 implementation,
+ * the initial reset is required.
*
- * </blockquote>
+ * <p>If the rule string does not follow the syntax, then {@code RuleBasedCollator} throws a
+ * {@code ParseException}.
*/
public class RuleBasedCollator extends Collator {
RuleBasedCollator(RuleBasedCollatorICU wrapper) {
@@ -265,13 +82,11 @@ public class RuleBasedCollator extends Collator {
/**
* Constructs a new instance of {@code RuleBasedCollator} using the
- * specified {@code rules}. The {@code rules} are usually either
- * hand-written based on the {@link RuleBasedCollator class description} or
- * the result of a former {@link #getRules()} call.
+ * specified {@code rules}. (See the {@link RuleBasedCollator class description}.)
* <p>
- * Note that the {@code rules} are actually interpreted as a delta to the
- * standard Unicode Collation Algorithm (UCA). This differs
- * slightly from other implementations which work with full {@code rules}
+ * Note that the {@code rules} are interpreted as a delta to the
+ * default sort order. This differs
+ * from other implementations which work with full {@code rules}
* specifications and may result in different behavior.
*
* @param rules
@@ -286,9 +101,6 @@ public class RuleBasedCollator extends Collator {
if (rules == null) {
throw new NullPointerException("rules == null");
}
- if (rules.isEmpty()) {
- throw new ParseException("empty rules", 0);
- }
try {
icuColl = new RuleBasedCollatorICU(rules);
} catch (Exception e) {
@@ -336,14 +148,9 @@ public class RuleBasedCollator extends Collator {
/**
* Returns the collation rules of this collator. These {@code rules} can be
* fed into the {@code RuleBasedCollator(String)} constructor.
- * <p>
- * Note that the {@code rules} are actually interpreted as a delta to the
- * standard Unicode Collation Algorithm (UCA). Hence, an empty {@code rules}
- * string results in the default UCA rules being applied. This differs
- * slightly from other implementations which work with full {@code rules}
- * specifications and may result in different behavior.
*
- * @return the collation rules.
+ * <p>The returned string will be empty unless you constructed the instance yourself.
+ * The string forms of the collation rules are omitted to save space on the device.
*/
public String getRules() {
return icuColl.getRules();
@@ -367,13 +174,6 @@ public class RuleBasedCollator extends Collator {
* the collation rules, strength and decomposition mode for this
* {@code RuleBasedCollator}. See the {@code Collator} class description
* for an example of use.
- * <p>
- * General recommendation: If comparisons are to be done with the same strings
- * multiple times, it is more efficient to generate {@code CollationKey}
- * objects for the strings and use
- * {@code CollationKey.compareTo(CollationKey)} for the comparisons. If each
- * string is compared to only once, using
- * {@code RuleBasedCollator.compare(String, String)} has better performance.
*
* @param source
* the source text.
diff --git a/luni/src/main/java/java/text/SimpleDateFormat.java b/luni/src/main/java/java/text/SimpleDateFormat.java
index 5fd8a56..8f83ff7 100644
--- a/luni/src/main/java/java/text/SimpleDateFormat.java
+++ b/luni/src/main/java/java/text/SimpleDateFormat.java
@@ -517,7 +517,8 @@ public class SimpleDateFormat extends DateFormat {
int next, last = -1, count = 0;
calendar.setTime(date);
if (field != null) {
- field.clear();
+ field.setBeginIndex(0);
+ field.setEndIndex(0);
}
final int patternLength = pattern.length();
@@ -623,8 +624,7 @@ public class SimpleDateFormat extends DateFormat {
break;
case MILLISECOND_FIELD:
dateFormatField = Field.MILLISECOND;
- int value = calendar.get(Calendar.MILLISECOND);
- appendNumber(buffer, count, value);
+ appendMilliseconds(buffer, count, calendar.get(Calendar.MILLISECOND));
break;
case STAND_ALONE_DAY_OF_WEEK_FIELD:
dateFormatField = Field.DAY_OF_WEEK;
@@ -740,15 +740,9 @@ public class SimpleDateFormat extends DateFormat {
TimeZone tz = calendar.getTimeZone();
boolean daylight = (calendar.get(Calendar.DST_OFFSET) != 0);
int style = count < 4 ? TimeZone.SHORT : TimeZone.LONG;
- if (!formatData.customZoneStrings) {
- buffer.append(tz.getDisplayName(daylight, style, formatData.locale));
- return;
- }
- // We can't call TimeZone.getDisplayName() because it would not use
- // the custom DateFormatSymbols of this SimpleDateFormat.
- String custom = TimeZoneNames.getDisplayName(formatData.zoneStrings, tz.getID(), daylight, style);
- if (custom != null) {
- buffer.append(custom);
+ String zoneString = formatData.getTimeZoneDisplayName(tz, daylight, style);
+ if (zoneString != null) {
+ buffer.append(zoneString);
return;
}
}
@@ -759,21 +753,29 @@ public class SimpleDateFormat extends DateFormat {
// See http://www.unicode.org/reports/tr35/#Date_Format_Patterns for the different counts.
// @param generalTimeZone "GMT-08:00" rather than "-0800".
private void appendNumericTimeZone(StringBuffer buffer, int count, boolean generalTimeZone) {
- int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
- char sign = '+';
- if (offset < 0) {
- sign = '-';
- offset = -offset;
- }
- if (generalTimeZone || count == 4) {
- buffer.append("GMT");
+ int offsetMillis = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
+ boolean includeGmt = generalTimeZone || count == 4;
+ boolean includeMinuteSeparator = generalTimeZone || count >= 4;
+ buffer.append(TimeZone.createGmtOffsetString(includeGmt, includeMinuteSeparator,
+ offsetMillis));
+ }
+
+ private void appendMilliseconds(StringBuffer buffer, int count, int value) {
+ // Unlike other fields, milliseconds are truncated by count. So 361 formatted SS is "36".
+ numberFormat.setMinimumIntegerDigits((count > 3) ? 3 : count);
+ numberFormat.setMaximumIntegerDigits(10);
+ // We need to left-justify.
+ if (count == 1) {
+ value /= 100;
+ } else if (count == 2) {
+ value /= 10;
}
- buffer.append(sign);
- appendNumber(buffer, 2, offset / 3600000);
- if (generalTimeZone || count >= 4) {
- buffer.append(':');
+ FieldPosition p = new FieldPosition(0);
+ numberFormat.format(Integer.valueOf(value), buffer, p);
+ if (count > 3) {
+ numberFormat.setMinimumIntegerDigits(count - 3);
+ numberFormat.format(Integer.valueOf(0), buffer, p);
}
- appendNumber(buffer, 2, (offset % 3600000) / 60000);
}
private void appendNumber(StringBuffer buffer, int count, int value) {
@@ -905,8 +907,7 @@ public class SimpleDateFormat extends DateFormat {
field = Calendar.SECOND;
break;
case MILLISECOND_FIELD:
- field = Calendar.MILLISECOND;
- break;
+ return parseFractionalSeconds(string, offset, absolute);
case STAND_ALONE_DAY_OF_WEEK_FIELD:
return parseDayOfWeek(string, offset, true);
case DAY_OF_WEEK_FIELD:
@@ -951,6 +952,31 @@ public class SimpleDateFormat extends DateFormat {
return offset;
}
+ /**
+ * Parses the fractional seconds section of a formatted date and assigns
+ * it to the {@code Calendar.MILLISECOND} field. Note that fractional seconds
+ * are somewhat unique, because they are zero suffixed.
+ */
+ private int parseFractionalSeconds(String string, int offset, int count) {
+ final ParsePosition parsePosition = new ParsePosition(offset);
+ final Number fractionalSeconds = parseNumber(count, string, parsePosition);
+ if (fractionalSeconds == null) {
+ return -parsePosition.getErrorIndex() - 1;
+ }
+
+ // NOTE: We could've done this using two parses instead. The first parse
+ // looking at |count| digits (to verify the date matched the format), and
+ // then a second parse that consumed just the first three digits. That
+ // would've avoided the floating point arithmetic, but would've demanded
+ // that we round values ourselves.
+ final double result = fractionalSeconds.doubleValue();
+ final int numDigitsParsed = parsePosition.getIndex() - offset;
+ final double divisor = Math.pow(10, numDigitsParsed);
+
+ calendar.set(Calendar.MILLISECOND, (int) ((result / divisor) * 1000));
+ return parsePosition.getIndex();
+ }
+
private int parseDayOfWeek(String string, int offset, boolean standAlone) {
LocaleData ld = formatData.localeData;
int index = parseText(string, offset,
@@ -1085,25 +1111,7 @@ public class SimpleDateFormat extends DateFormat {
}
if (max == 0) {
position.setIndex(index);
- Number n = numberFormat.parse(string, position);
- // In RTL locales, NumberFormat might have parsed "2012-" in an ISO date as the
- // negative number -2012.
- // Ideally, we wouldn't have this broken API that exposes a NumberFormat and expects
- // us to use it. The next best thing would be a way to ask the NumberFormat to parse
- // positive numbers only, but icu4c supports negative (BCE) years. The best we can do
- // is try to recognize when icu4c has done this, and undo it.
- if (n != null && n.longValue() < 0) {
- if (numberFormat instanceof DecimalFormat) {
- DecimalFormat df = (DecimalFormat) numberFormat;
- char lastChar = string.charAt(position.getIndex() - 1);
- char minusSign = df.getDecimalFormatSymbols().getMinusSign();
- if (lastChar == minusSign) {
- n = Long.valueOf(-n.longValue()); // Make the value positive.
- position.setIndex(position.getIndex() - 1); // Spit out the negative sign.
- }
- }
- }
- return n;
+ return numberFormat.parse(string, position);
}
int result = 0;
@@ -1168,6 +1176,8 @@ public class SimpleDateFormat extends DateFormat {
if (foundGMT) {
offset += 3;
}
+
+ // Check for an offset, which may have been preceded by "GMT"
char sign;
if (offset < string.length() && ((sign = string.charAt(offset)) == '+' || sign == '-')) {
ParsePosition position = new ParsePosition(offset + 1);
@@ -1195,10 +1205,14 @@ public class SimpleDateFormat extends DateFormat {
calendar.setTimeZone(new SimpleTimeZone(raw, ""));
return position.getIndex();
}
+
+ // If there was "GMT" but no offset.
if (foundGMT) {
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
return offset;
}
+
+ // Exhaustively look for the string in this DateFormat's localized time zone strings.
for (String[] row : formatData.internalZoneStrings()) {
for (int i = TimeZoneNames.LONG_NAME; i < TimeZoneNames.NAME_COUNT; ++i) {
if (row[i] == null) {
diff --git a/luni/src/main/java/java/text/spi/BreakIteratorProvider.java b/luni/src/main/java/java/text/spi/BreakIteratorProvider.java
deleted file mode 100644
index a28bc53..0000000
--- a/luni/src/main/java/java/text/spi/BreakIteratorProvider.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.text.spi;
-
-import java.text.BreakIterator;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * This abstract class should be extended by service providers that provide
- * instances of {@code BreakIterator}.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class BreakIteratorProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected BreakIteratorProvider() {
- // Do nothing.
- }
-
- /**
- * Returns an instance of {@code BreakIterator} for word breaks in the
- * given locale.
- *
- * @param locale the locale
- * @return an instance of {@code BreakIterator}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract BreakIterator getWordInstance(Locale locale);
-
- /**
- * Returns an instance of {@code BreakIterator} for line breaks in the
- * given locale.
- *
- * @param locale the locale
- * @return an instance of {@code BreakIterator}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract BreakIterator getLineInstance(Locale locale);
-
- /**
- * Returns an instance of {@code BreakIterator} for character breaks in the
- * given locale.
- *
- * @param locale the locale
- * @return an instance of {@code BreakIterator}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract BreakIterator getCharacterInstance(Locale locale);
-
- /**
- * Returns an instance of {@code BreakIterator} for sentence breaks in the
- * given locale.
- *
- * @param locale the locale
- * @return an instance of {@code BreakIterator}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract BreakIterator getSentenceInstance(Locale locale);
-}
diff --git a/luni/src/main/java/java/text/spi/CollatorProvider.java b/luni/src/main/java/java/text/spi/CollatorProvider.java
deleted file mode 100644
index 0862432..0000000
--- a/luni/src/main/java/java/text/spi/CollatorProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.text.spi;
-
-import java.text.Collator;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * This abstract class should be extended by service providers which provide
- * instances of {@code Collator}.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class CollatorProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected CollatorProvider() {
- // Do nothing.
- }
-
- /**
- * Returns an instance of {@code Collator} for the given locale.
- *
- * @param locale the locale
- * @return an instance of {@code Collator}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract Collator getInstance(Locale locale);
-}
diff --git a/luni/src/main/java/java/text/spi/DateFormatProvider.java b/luni/src/main/java/java/text/spi/DateFormatProvider.java
deleted file mode 100644
index 59fefed..0000000
--- a/luni/src/main/java/java/text/spi/DateFormatProvider.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.text.spi;
-
-import java.text.DateFormat;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * This abstract class should be extended by service providers that provide
- * instances of {@code DateFormat}.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class DateFormatProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected DateFormatProvider() {
- // Do nothing.
- }
-
- /**
- * Returns an instance of {@code DateFormat} that formats times
- * in the given style for the given locale.
- *
- * @param style the given time formatting style.
- * @param locale the locale
- * @return an instance of {@code DateFormat}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract DateFormat getTimeInstance(int style, Locale locale);
-
- /**
- * Returns an instance of {@code DateFormat} that formats dates
- * in the given style for the given locale.
- *
- * @param style the given date formatting style.
- * @param locale the locale
- * @return an instance of {@code DateFormat}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract DateFormat getDateInstance(int style, Locale locale);
-
- /**
- * Returns an instance of {@code DateFormat} that formats dates and times
- * in the given style for the given locale.
- *
- * @param dateStyle the given date formatting style.
- * @param timeStyle the given time formatting style.
- * @param locale the locale
- * @return an instance of {@code DateFormat}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale);
-}
diff --git a/luni/src/main/java/java/text/spi/DateFormatSymbolsProvider.java b/luni/src/main/java/java/text/spi/DateFormatSymbolsProvider.java
deleted file mode 100644
index cb34b71..0000000
--- a/luni/src/main/java/java/text/spi/DateFormatSymbolsProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.text.spi;
-
-import java.text.DateFormatSymbols;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * This abstract class should be extended by service providers that provide
- * instances of {@code DateFormatSymbols}.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class DateFormatSymbolsProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected DateFormatSymbolsProvider() {
- // Do nothing.
- }
-
- /**
- * Returns an instance of {@code DateFormatSymbols} for the given locale.
- *
- * @param locale the locale
- * @return an instance of {@code DateFormatSymbols}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract DateFormatSymbols getInstance(Locale locale);
-}
diff --git a/luni/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java b/luni/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java
deleted file mode 100644
index f9f5e7d..0000000
--- a/luni/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.text.spi;
-
-import java.text.DecimalFormatSymbols;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * This abstract class should be extended by service providers that provide
- * instances of {@code DecimalFormatSymbols}.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class DecimalFormatSymbolsProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected DecimalFormatSymbolsProvider() {
- // Do nothing.
- }
-
- /**
- * Returns an instance of {@code DecimalFormatSymbols} for the given locale.
- *
- * @param locale the locale
- * @return an instance of {@code DecimalFormatSymbols}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract DecimalFormatSymbols getInstance(Locale locale);
-
-}
diff --git a/luni/src/main/java/java/text/spi/NumberFormatProvider.java b/luni/src/main/java/java/text/spi/NumberFormatProvider.java
deleted file mode 100644
index c889f78..0000000
--- a/luni/src/main/java/java/text/spi/NumberFormatProvider.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.text.spi;
-
-import java.text.NumberFormat;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * This abstract class should be extended by service providers that provide
- * {@code NumberFormat} instances.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class NumberFormatProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected NumberFormatProvider() {
- // Do nothing.
- }
-
- /**
- * Returns an instance of {@code NumberFormat} that formats
- * monetary values for the given locale.
- *
- * @param locale the locale
- * @return an instance of {@code NumberFormat}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract NumberFormat getCurrencyInstance(Locale locale);
-
- /**
- * Returns an instance of {@code NumberFormat} that formats
- * integer values for the given locale. The returned {@code NumberFormat}
- * is configured to round floating point numbers to the nearest integer
- * using half-even rounding mode for formatting, and to parse only the
- * integer part of an input string.
- *
- * @param locale the locale
- * @return an instance of {@code NumberFormat}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract NumberFormat getIntegerInstance(Locale locale);
-
- /**
- * Returns an instance of {@code NumberFormat} class for general
- * use in the given locale.
- *
- * @param locale the locale
- * @return an instance of {@code NumberFormat}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract NumberFormat getNumberInstance(Locale locale);
-
- /**
- * Returns an instance of {@code NumberFormat} class that formats
- * percentage values for the given locale.
- *
- * @param locale the locale
- * @return an instance of {@code NumberFormat}
- * @throws NullPointerException if {@code locale == null}
- * @throws IllegalArgumentException
- * if locale isn't one of the locales returned from
- * getAvailableLocales().
- */
- public abstract NumberFormat getPercentInstance(Locale locale);
-}
diff --git a/luni/src/main/java/java/util/Arrays.java b/luni/src/main/java/java/util/Arrays.java
index d3e05a0..3b477d0 100644
--- a/luni/src/main/java/java/util/Arrays.java
+++ b/luni/src/main/java/java/util/Arrays.java
@@ -1319,31 +1319,25 @@ public class Arrays {
/*
* element is an array
*/
- if (!cl.isPrimitive()) {
+ if (element instanceof Object[]) {
return deepHashCode((Object[]) element);
- }
- if (cl.equals(int.class)) {
+ } else if (cl == int.class) {
return hashCode((int[]) element);
- }
- if (cl.equals(char.class)) {
+ } else if (cl == char.class) {
return hashCode((char[]) element);
- }
- if (cl.equals(boolean.class)) {
+ } else if (cl == boolean.class) {
return hashCode((boolean[]) element);
- }
- if (cl.equals(byte.class)) {
+ } else if (cl == byte.class) {
return hashCode((byte[]) element);
- }
- if (cl.equals(long.class)) {
+ } else if (cl == long.class) {
return hashCode((long[]) element);
- }
- if (cl.equals(float.class)) {
+ } else if (cl == float.class) {
return hashCode((float[]) element);
- }
- if (cl.equals(double.class)) {
+ } else if (cl == double.class) {
return hashCode((double[]) element);
+ } else {
+ return hashCode((short[]) element);
}
- return hashCode((short[]) element);
}
/**
@@ -1665,32 +1659,25 @@ public class Arrays {
/*
* compare as arrays
*/
- if (!cl1.isPrimitive()) {
+ if (e1 instanceof Object[]) {
return deepEquals((Object[]) e1, (Object[]) e2);
- }
-
- if (cl1.equals(int.class)) {
+ } else if (cl1 == int.class) {
return equals((int[]) e1, (int[]) e2);
- }
- if (cl1.equals(char.class)) {
+ } else if (cl1 == char.class) {
return equals((char[]) e1, (char[]) e2);
- }
- if (cl1.equals(boolean.class)) {
+ } else if (cl1 == boolean.class) {
return equals((boolean[]) e1, (boolean[]) e2);
- }
- if (cl1.equals(byte.class)) {
+ } else if (cl1 == byte.class) {
return equals((byte[]) e1, (byte[]) e2);
- }
- if (cl1.equals(long.class)) {
+ } else if (cl1 == long.class) {
return equals((long[]) e1, (long[]) e2);
- }
- if (cl1.equals(float.class)) {
+ } else if (cl1 == float.class) {
return equals((float[]) e1, (float[]) e2);
- }
- if (cl1.equals(double.class)) {
+ } else if (cl1 == double.class) {
return equals((double[]) e1, (double[]) e2);
+ } else {
+ return equals((short[]) e1, (short[]) e2);
}
- return equals((short[]) e1, (short[]) e2);
}
/**
diff --git a/luni/src/main/java/java/util/Calendar.java b/luni/src/main/java/java/util/Calendar.java
index 4ed2ad1..fc4cef6 100644
--- a/luni/src/main/java/java/util/Calendar.java
+++ b/luni/src/main/java/java/util/Calendar.java
@@ -642,13 +642,24 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
/**
* Field number for {@code get} and {@code set} indicating the
- * raw offset from GMT in milliseconds.
+ * raw (non-DST) offset from GMT in milliseconds.
+ * Equivalent to {@link java.util.TimeZone#getRawOffset}.
+ *
+ * <p>To determine the total offset from GMT at the time represented
+ * by this calendar, you will need to add the {@code ZONE_OFFSET} and
+ * {@code DST_OFFSET} fields.
*/
public static final int ZONE_OFFSET = 15;
/**
* Field number for {@code get} and {@code set} indicating the
- * daylight savings offset in milliseconds.
+ * daylight savings offset from the {@code ZONE_OFFSET} in milliseconds.
+ * Equivalent to {@link java.util.TimeZone#getDSTSavings} if the represented time
+ * falls inside DST, or 0 otherwise.
+ *
+ * <p>To determine the total offset from GMT at the time represented
+ * by this calendar, you will need to add the {@code ZONE_OFFSET} and
+ * {@code DST_OFFSET} fields.
*/
public static final int DST_OFFSET = 16;
@@ -716,6 +727,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
*/
protected Calendar(TimeZone timezone, Locale locale) {
this(timezone);
+ locale = LocaleData.mapInvalidAndNullLocales(locale);
LocaleData localeData = LocaleData.get(locale);
setFirstDayOfWeek(localeData.firstDayOfWeek.intValue());
setMinimalDaysInFirstWeek(localeData.minimalDaysInFirstWeek.intValue());
diff --git a/luni/src/main/java/java/util/Collections.java b/luni/src/main/java/java/util/Collections.java
index ce4e579..4541d64 100644
--- a/luni/src/main/java/java/util/Collections.java
+++ b/luni/src/main/java/java/util/Collections.java
@@ -1212,7 +1212,7 @@ public class Collections {
int length = c.size();
Object[] result = new Object[length];
Iterator<?> it = iterator();
- for (int i = length; --i >= 0;) {
+ for (int i = 0; i < length; i++) {
result[i] = it.next();
}
return result;
diff --git a/luni/src/main/java/java/util/Currency.java b/luni/src/main/java/java/util/Currency.java
index b5b04a0..f43ddae 100644
--- a/luni/src/main/java/java/util/Currency.java
+++ b/luni/src/main/java/java/util/Currency.java
@@ -35,7 +35,7 @@ public final class Currency implements Serializable {
private Currency(String currencyCode) {
this.currencyCode = currencyCode;
- String symbol = ICU.getCurrencySymbol(Locale.US.toString(), currencyCode);
+ String symbol = ICU.getCurrencySymbol(Locale.US, currencyCode);
if (symbol == null) {
throw new IllegalArgumentException("Unsupported ISO 4217 currency code: " +
currencyCode);
@@ -65,6 +65,9 @@ public final class Currency implements Serializable {
*/
public static Currency getInstance(Locale locale) {
synchronized (localesToCurrencies) {
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
Currency currency = localesToCurrencies.get(locale);
if (currency != null) {
return currency;
@@ -123,7 +126,7 @@ public final class Currency implements Serializable {
* @since 1.7
*/
public String getDisplayName(Locale locale) {
- return ICU.getCurrencyDisplayName(locale.toString(), currencyCode);
+ return ICU.getCurrencyDisplayName(locale, currencyCode);
}
/**
@@ -146,10 +149,9 @@ public final class Currency implements Serializable {
* <p>If there is no locale-specific currency symbol, the ISO 4217 currency code is returned.
*/
public String getSymbol(Locale locale) {
- if (locale.getCountry().length() == 0) {
- return currencyCode;
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
}
-
// Check the locale first, in case the locale has the same currency.
LocaleData localeData = LocaleData.get(locale);
if (localeData.internationalCurrencySymbol.equals(currencyCode)) {
@@ -157,7 +159,7 @@ public final class Currency implements Serializable {
}
// Try ICU, and fall back to the currency code if ICU has nothing.
- String symbol = ICU.getCurrencySymbol(locale.toString(), currencyCode);
+ String symbol = ICU.getCurrencySymbol(locale, currencyCode);
return symbol != null ? symbol : currencyCode;
}
diff --git a/luni/src/main/java/java/util/EnumMap.java b/luni/src/main/java/java/util/EnumMap.java
index 827fb51..dfacb46 100644
--- a/luni/src/main/java/java/util/EnumMap.java
+++ b/luni/src/main/java/java/util/EnumMap.java
@@ -174,7 +174,7 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V> implements
@Override
@SuppressWarnings("unchecked")
public String toString() {
- if (-1 == prePosition) {
+ if (prePosition == -1) {
return super.toString();
}
return type.get(
@@ -183,7 +183,7 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V> implements
}
private void checkStatus() {
- if (-1 == prePosition) {
+ if (prePosition == -1) {
throw new IllegalStateException();
}
}
diff --git a/luni/src/main/java/java/util/Formatter.java b/luni/src/main/java/java/util/Formatter.java
index 98bdccc..dd9a09a 100644
--- a/luni/src/main/java/java/util/Formatter.java
+++ b/luni/src/main/java/java/util/Formatter.java
@@ -2065,7 +2065,7 @@ public final class Formatter implements Closeable, Flushable {
formatToken.setPrecision(FormatToken.UNSET);
int startIndex = 0;
- if (result.charAt(0) == localeData.minusSign) {
+ if (startsWithMinusSign(result, localeData.minusSign)) {
if (formatToken.flagParenthesis) {
return wrapParentheses(result);
}
@@ -2081,8 +2081,9 @@ public final class Formatter implements Closeable, Flushable {
}
char firstChar = result.charAt(0);
- if (formatToken.flagZero && (firstChar == '+' || firstChar == localeData.minusSign)) {
- startIndex = 1;
+ if (formatToken.flagZero && (firstChar == '+' ||
+ startsWithMinusSign(result, localeData.minusSign))) {
+ startIndex = localeData.minusSign.length();
}
if (conversionType == 'a' || conversionType == 'A') {
@@ -2091,6 +2092,20 @@ public final class Formatter implements Closeable, Flushable {
return padding(result, startIndex);
}
+ private static boolean startsWithMinusSign(CharSequence cs, String minusSign) {
+ if (cs.length() < minusSign.length()) {
+ return false;
+ }
+
+ for (int i = 0; i < minusSign.length(); ++i) {
+ if (minusSign.charAt(i) != cs.charAt(i)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
private void transformE(StringBuilder result) {
// All zeros in this method are *pattern* characters, so no localization.
final int precision = formatToken.getPrecision();
diff --git a/luni/src/main/java/java/util/GregorianCalendar.java b/luni/src/main/java/java/util/GregorianCalendar.java
index 9ff9ccc..be96684 100644
--- a/luni/src/main/java/java/util/GregorianCalendar.java
+++ b/luni/src/main/java/java/util/GregorianCalendar.java
@@ -331,7 +331,16 @@ public class GregorianCalendar extends Calendar {
setTimeInMillis(System.currentTimeMillis());
}
- GregorianCalendar(boolean ignored) {
+ /**
+ * A minimum-cost constructor that does not initialize the current time or perform any date
+ * calculations. For use internally when the time will be set later. Other constructors, such as
+ * {@link GregorianCalendar#GregorianCalendar()}, set the time to the current system clock
+ * and recalculate the fields incurring unnecessary cost when the time or fields will be set
+ * later.
+ *
+ * @hide used internally
+ */
+ public GregorianCalendar(boolean ignored) {
super(TimeZone.getDefault());
setFirstDayOfWeek(SUNDAY);
setMinimalDaysInFirstWeek(1);
@@ -458,16 +467,17 @@ public class GregorianCalendar extends Calendar {
complete();
}
- private void fullFieldsCalc(long timeVal, int zoneOffset) {
+ private void fullFieldsCalc() {
int millis = (int) (time % 86400000);
- long days = timeVal / 86400000;
+ long days = time / 86400000;
if (millis < 0) {
millis += 86400000;
days--;
}
- // Cannot add ZONE_OFFSET to time as it might overflow
- millis += zoneOffset;
+ // Adding fields[ZONE_OFFSET] to time might make it overflow, so we add
+ // it to millis (the number of milliseconds in the current day) instead.
+ millis += fields[ZONE_OFFSET];
while (millis < 0) {
millis += 86400000;
days--;
@@ -477,9 +487,9 @@ public class GregorianCalendar extends Calendar {
days++;
}
- int dayOfYear = computeYearAndDay(days, timeVal + zoneOffset);
+ int dayOfYear = computeYearAndDay(days, time + fields[ZONE_OFFSET]);
fields[DAY_OF_YEAR] = dayOfYear;
- if(fields[YEAR] == changeYear && gregorianCutover <= timeVal + zoneOffset){
+ if (fields[YEAR] == changeYear && gregorianCutover <= time + fields[ZONE_OFFSET]){
dayOfYear += currentYearSkew;
}
int month = dayOfYear / 32;
@@ -493,7 +503,7 @@ public class GregorianCalendar extends Calendar {
int dstOffset = fields[YEAR] <= 0 ? 0 : getTimeZone().getOffset(AD,
fields[YEAR], month, date, fields[DAY_OF_WEEK], millis);
if (fields[YEAR] > 0) {
- dstOffset -= zoneOffset;
+ dstOffset -= fields[ZONE_OFFSET];
}
fields[DST_OFFSET] = dstOffset;
if (dstOffset != 0) {
@@ -507,10 +517,10 @@ public class GregorianCalendar extends Calendar {
days++;
}
if (oldDays != days) {
- dayOfYear = computeYearAndDay(days, timeVal - zoneOffset
+ dayOfYear = computeYearAndDay(days, time - fields[ZONE_OFFSET]
+ dstOffset);
fields[DAY_OF_YEAR] = dayOfYear;
- if(fields[YEAR] == changeYear && gregorianCutover <= timeVal - zoneOffset + dstOffset){
+ if(fields[YEAR] == changeYear && gregorianCutover <= time - fields[ZONE_OFFSET] + dstOffset){
dayOfYear += currentYearSkew;
}
month = dayOfYear / 32;
@@ -567,10 +577,26 @@ public class GregorianCalendar extends Calendar {
TimeZone timeZone = getTimeZone();
int dstOffset = timeZone.inDaylightTime(new Date(time)) ? timeZone.getDSTSavings() : 0;
int zoneOffset = timeZone.getRawOffset();
+
+ // We unconditionally overwrite DST_OFFSET and ZONE_OFFSET with
+ // values from the timezone that's currently in use. This gives us
+ // much more consistent behavior, and matches ICU4J behavior (though
+ // it is inconsistent with the RI).
+ //
+ // Anything callers can do with ZONE_OFFSET they can do by constructing
+ // a SimpleTimeZone with the required offset.
+ //
+ // DST_OFFSET is a bit of a WTF, given that it's dependent on the rest
+ // of the fields. There's no sensible reason we'd want to allow it to
+ // be set, nor can we implement consistent full-fields calculation after
+ // this field is set without maintaining a large deal of additional state.
+ //
+ // At the very least, we will need isSet to differentiate between fields
+ // set by the user and fields set by our internal field calculation.
fields[DST_OFFSET] = dstOffset;
fields[ZONE_OFFSET] = zoneOffset;
- fullFieldsCalc(time, zoneOffset);
+ fullFieldsCalc();
for (int i = 0; i < FIELD_COUNT; i++) {
isSet[i] = true;
@@ -670,8 +696,16 @@ public class GregorianCalendar extends Calendar {
if (useMonth
&& (lastDateFieldSet == DAY_OF_WEEK || lastDateFieldSet == WEEK_OF_YEAR)) {
if (isSet[WEEK_OF_YEAR] && isSet[DAY_OF_WEEK]) {
- useMonth = lastDateFieldSet != WEEK_OF_YEAR && weekMonthSet
- && isSet[DAY_OF_WEEK];
+ if (lastDateFieldSet == WEEK_OF_YEAR) {
+ useMonth = false;
+ } else if (lastDateFieldSet == DAY_OF_WEEK) {
+ // DAY_OF_WEEK belongs to both the Month + Week + Day and the
+ // WeekOfYear + Day combinations. We're supposed to use the most
+ // recent combination, as specified by the single set field. We can't
+ // know for sure in this case, so we always prefer the week-month-day
+ // combination if week-month is already set.
+ useMonth = weekMonthSet;
+ }
} else if (isSet[DAY_OF_YEAR]) {
useMonth = isSet[DATE] && isSet[MONTH];
}
diff --git a/luni/src/main/java/java/util/HashMap.java b/luni/src/main/java/java/util/HashMap.java
index 80fbd0c..b6fe646 100644
--- a/luni/src/main/java/java/util/HashMap.java
+++ b/luni/src/main/java/java/util/HashMap.java
@@ -297,12 +297,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Seria
return e == null ? null : e.value;
}
- // Doug Lea's supplemental secondaryHash function (inlined).
- // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
- int hash = key.hashCode();
- hash ^= (hash >>> 20) ^ (hash >>> 12);
- hash ^= (hash >>> 7) ^ (hash >>> 4);
-
+ int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
@@ -327,12 +322,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Seria
return entryForNullKey != null;
}
- // Doug Lea's supplemental secondaryHash function (inlined).
- // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
- int hash = key.hashCode();
- hash ^= (hash >>> 20) ^ (hash >>> 12);
- hash ^= (hash >>> 7) ^ (hash >>> 4);
-
+ int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
@@ -344,15 +334,6 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Seria
return false;
}
- // Doug Lea's supplemental secondaryHash function (non-inlined).
- // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
- static int secondaryHash(Object key) {
- int hash = key.hashCode();
- hash ^= (hash >>> 20) ^ (hash >>> 12);
- hash ^= (hash >>> 7) ^ (hash >>> 4);
- return hash;
- }
-
/**
* Returns whether this map contains the specified value.
*
@@ -401,7 +382,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Seria
return putValueForNullKey(value);
}
- int hash = secondaryHash(key);
+ int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
@@ -464,7 +445,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Seria
return;
}
- int hash = secondaryHash(key);
+ int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
HashMapEntry<K, V> first = tab[index];
@@ -632,7 +613,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Seria
if (key == null) {
return removeNullKey();
}
- int hash = secondaryHash(key);
+ int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index], prev = null;
@@ -852,7 +833,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Seria
return e != null && Objects.equal(value, e.value);
}
- int hash = secondaryHash(key);
+ int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
@@ -880,7 +861,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Seria
return true;
}
- int hash = secondaryHash(key);
+ int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index], prev = null;
diff --git a/luni/src/main/java/java/util/IllformedLocaleException.java b/luni/src/main/java/java/util/IllformedLocaleException.java
new file mode 100644
index 0000000..3dec1cd
--- /dev/null
+++ b/luni/src/main/java/java/util/IllformedLocaleException.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+/**
+ * Thrown when a locale subtag or field is not well formed.
+ *
+ * See {@link Locale} and {@link Locale.Builder}.
+ *
+ * @since 1.7
+ */
+public class IllformedLocaleException extends RuntimeException {
+
+ private final int errorIndex;
+
+ /**
+ * Constructs a new instance with no detail message and an error index
+ * of {@code -1}.
+ */
+ public IllformedLocaleException() {
+ this(null, -1);
+ }
+
+ /**
+ * Constructs a new instance with the specified error message.
+ */
+ public IllformedLocaleException(String message) {
+ this(message, -1);
+ }
+
+ /**
+ * Constructs a new instance with the specified error message and
+ * error index.
+ */
+ public IllformedLocaleException(String message, int errorIndex) {
+ super(message);
+ this.errorIndex = errorIndex;
+ }
+
+ public int getErrorIndex() {
+ return errorIndex;
+ }
+}
diff --git a/luni/src/main/java/java/util/LinkedHashMap.java b/luni/src/main/java/java/util/LinkedHashMap.java
index e61b0f9..3d6e6c3 100644
--- a/luni/src/main/java/java/util/LinkedHashMap.java
+++ b/luni/src/main/java/java/util/LinkedHashMap.java
@@ -74,7 +74,7 @@ public class LinkedHashMap<K, V> extends HashMap<K, V> {
*
* @param initialCapacity
* the initial capacity of this map.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* when the capacity is less than zero.
*/
public LinkedHashMap(int initialCapacity) {
@@ -247,8 +247,7 @@ public class LinkedHashMap<K, V> extends HashMap<K, V> {
return e.value;
}
- // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
- int hash = secondaryHash(key);
+ int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index fc8f7c6..a6368e8 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -22,6 +22,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
import libcore.icu.ICU;
/**
@@ -40,7 +41,7 @@ import libcore.icu.ICU;
* rewriting happens even if you construct your own {@code Locale} object, not just for
* instances returned by the various lookup methods.
*
- * <a name="available_locales"><h3>Available locales</h3></a>
+ * <a name="available_locales"></a><h3>Available locales</h3>
* <p>This class' constructors do no error checking. You can create a {@code Locale} for languages
* and countries that don't exist, and you can create instances for combinations that don't
* exist (such as "de_US" for "German as spoken in the US").
@@ -59,7 +60,7 @@ import libcore.icu.ICU;
* device you're running on, or {@link Locale#getAvailableLocales} to get a list of all the locales
* available on the device you're running on.
*
- * <a name="locale_data"><h3>Locale data</h3></a>
+ * <a name="locale_data"></a><h3>Locale data</h3>
* <p>Note that locale data comes solely from ICU. User-supplied locale service providers (using
* the {@code java.text.spi} or {@code java.util.spi} mechanisms) are not supported.
*
@@ -79,24 +80,28 @@ import libcore.icu.ICU;
* <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-8">CLDR 1.8</a></td>
* <td><a href="http://www.unicode.org/versions/Unicode5.2.0/">Unicode 5.2</a></td></tr>
* <tr><td>Android 4.0 (Ice Cream Sandwich)</td>
- * <td>ICU 4.6</td>
+ * <td><a href="http://site.icu-project.org/download/46">ICU 4.6</a></td>
* <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-9">CLDR 1.9</a></td>
* <td><a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode 6.0</a></td></tr>
* <tr><td>Android 4.1 (Jelly Bean)</td>
- * <td>ICU 4.8</td>
+ * <td><a href="http://site.icu-project.org/download/48">ICU 4.8</a></td>
* <td><a href="http://cldr.unicode.org/index/downloads/cldr-2-0">CLDR 2.0</a></td>
* <td><a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode 6.0</a></td></tr>
* <tr><td>Android 4.3 (Jelly Bean MR2)</td>
- * <td>ICU 50</td>
+ * <td><a href="http://site.icu-project.org/download/50">ICU 50</a></td>
* <td><a href="http://cldr.unicode.org/index/downloads/cldr-22-1">CLDR 22.1</a></td>
* <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
* <tr><td>Android 4.4 (KitKat)</td>
- * <td>ICU 51</td>
+ * <td><a href="http://site.icu-project.org/download/51">ICU 51</a></td>
* <td><a href="http://cldr.unicode.org/index/downloads/cldr-23">CLDR 23</a></td>
* <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
+ * <tr><td>Android 5.0 (Lollipop)</td>
+ * <td><a href="http://site.icu-project.org/download/53">ICU 53</a></td>
+ * <td><a href="http://cldr.unicode.org/index/downloads/cldr-25">CLDR 25</a></td>
+ * <td><a href="http://www.unicode.org/versions/Unicode6.3.0/">Unicode 6.3</a></td></tr>
* </table>
*
- * <a name="default_locale"><h3>Be wary of the default locale</h3></a>
+ * <a name="default_locale"></a><h3>Be wary of the default locale</h3>
* <p>Note that there are many convenience methods that automatically use the default locale, but
* using them may lead to subtle bugs.
*
@@ -243,6 +248,31 @@ public final class Locale implements Cloneable, Serializable {
public static final Locale US = new Locale(true, "en", "US");
/**
+ * BCP-47 extension identifier (or "singleton") for the private
+ * use extension.
+ *
+ * See {@link #getExtension(char)} and {@link Builder#setExtension(char, String)}.
+ *
+ * @since 1.7
+ */
+ public static final char PRIVATE_USE_EXTENSION = 'x';
+
+ /**
+ * BCP-47 extension identifier (or "singleton") for the unicode locale extension.
+ *
+ *
+ * See {@link #getExtension(char)} and {@link Builder#setExtension(char, String)}.
+ *
+ * @since 1.7
+ */
+ public static final char UNICODE_LOCALE_EXTENSION = 'u';
+
+ /**
+ * ISO 639-3 generic code for undetermined languages.
+ */
+ private static final String UNDETERMINED_LANGUAGE = "und";
+
+ /**
* The current default locale. It is temporarily assigned to US because we
* need a default locale to lookup the real default locale.
*/
@@ -255,70 +285,663 @@ public final class Locale implements Cloneable, Serializable {
defaultLocale = new Locale(language, region, variant);
}
+ /**
+ * A class that helps construct {@link Locale} instances.
+ *
+ * Unlike the public {@code Locale} constructors, the methods of this class
+ * perform much stricter checks on their input.
+ *
+ * Validity checks on the {@code language}, {@code country}, {@code variant}
+ * and {@code extension} values are carried out as per the
+ * <a href="https://tools.ietf.org/html/bcp47">BCP-47</a> specification.
+ *
+ * In addition, we treat the <a href="http://www.unicode.org/reports/tr35/">
+ * Unicode locale extension</a> specially and provide methods to manipulate
+ * the structured state (keywords and attributes) specified therein.
+ *
+ * @since 1.7
+ */
+ public static final class Builder {
+ private String language;
+ private String region;
+ private String variant;
+ private String script;
+
+ private final Set<String> attributes;
+ private final Map<String, String> keywords;
+ private final Map<Character, String> extensions;
+
+ public Builder() {
+ language = region = variant = script = "";
+
+ // NOTE: We use sorted maps in the builder & the locale class itself
+ // because serialized forms of the unicode locale extension (and
+ // of the extension map itself) are specified to be in alphabetic
+ // order of keys.
+ attributes = new TreeSet<String>();
+ keywords = new TreeMap<String, String>();
+ extensions = new TreeMap<Character, String>();
+ }
+
+ /**
+ * Sets the locale language. If {@code language} is {@code null} or empty, the
+ * previous value is cleared.
+ *
+ * As per BCP-47, the language must be between 2 and 3 ASCII characters
+ * in length and must only contain characters in the range {@code [a-zA-Z]}.
+ *
+ * This value is usually an <a href="http://www.loc.gov/standards/iso639-2/">
+ * ISO-639-2</a> alpha-2 or alpha-3 code, though no explicit checks are
+ * carried out that it's a valid code in that namespace.
+ *
+ * Values are normalized to lower case.
+ *
+ * Note that we don't support BCP-47 "extlang" languages because they were
+ * only ever used to substitute for a lack of 3 letter language codes.
+ *
+ * @throws IllformedLocaleException if the language was invalid.
+ */
+ public Builder setLanguage(String language) {
+ this.language = normalizeAndValidateLanguage(language, true /* strict */);
+ return this;
+ }
+
+ private static String normalizeAndValidateLanguage(String language, boolean strict) {
+ if (language == null || language.isEmpty()) {
+ return "";
+ }
+
+ final String lowercaseLanguage = language.toLowerCase(Locale.ROOT);
+ if (!isValidBcp47Alpha(lowercaseLanguage, 2, 3)) {
+ if (strict) {
+ throw new IllformedLocaleException("Invalid language: " + language);
+ } else {
+ return UNDETERMINED_LANGUAGE;
+ }
+ }
+
+ return lowercaseLanguage;
+ }
+
+ /**
+ * Set the state of this builder to the parsed contents of the BCP-47 language
+ * tag {@code languageTag}.
+ *
+ * This method is equivalent to a call to {@link #clear} if {@code languageTag}
+ * is {@code null} or empty.
+ *
+ * <b>NOTE:</b> In contrast to {@link Locale#forLanguageTag(String)}, which
+ * simply ignores malformed input, this method will throw an exception if
+ * its input is malformed.
+ *
+ * @throws IllformedLocaleException if {@code languageTag} is not a well formed
+ * BCP-47 tag.
+ */
+ public Builder setLanguageTag(String languageTag) {
+ if (languageTag == null || languageTag.isEmpty()) {
+ clear();
+ return this;
+ }
+
+ final Locale fromIcu = forLanguageTag(languageTag, true /* strict */);
+ // When we ask ICU for strict parsing, it might return a null locale
+ // if the language tag is malformed.
+ if (fromIcu == null) {
+ throw new IllformedLocaleException("Invalid languageTag: " + languageTag);
+ }
+
+ setLocale(fromIcu);
+ return this;
+ }
+
+ /**
+ * Sets the locale region. If {@code region} is {@code null} or empty, the
+ * previous value is cleared.
+ *
+ * As per BCP-47, the region must either be a 2 character ISO-3166-1 code
+ * (each character in the range [a-zA-Z]) OR a 3 digit UN M.49 code.
+ *
+ * Values are normalized to upper case.
+ *
+ * @throws IllformedLocaleException if {@code} region is invalid.
+ */
+ public Builder setRegion(String region) {
+ this.region = normalizeAndValidateRegion(region, true /* strict */);
+ return this;
+ }
+
+ private static String normalizeAndValidateRegion(String region, boolean strict) {
+ if (region == null || region.isEmpty()) {
+ return "";
+ }
+
+ final String uppercaseRegion = region.toUpperCase(Locale.ROOT);
+ if (!isValidBcp47Alpha(uppercaseRegion, 2, 2) &&
+ !isUnM49AreaCode(uppercaseRegion)) {
+ if (strict) {
+ throw new IllformedLocaleException("Invalid region: " + region);
+ } else {
+ return "";
+ }
+ }
+
+ return uppercaseRegion;
+ }
+
+ /**
+ * Sets the locale variant. If {@code variant} is {@code null} or empty,
+ * the previous value is cleared.
+ *
+ * The input string my consist of one or more variants separated by
+ * valid separators ('-' or '_').
+ *
+ * As per BCP-47, each variant must be between 5 and 8 alphanumeric characters
+ * in length (each character in the range {@code [a-zA-Z0-9]}) but
+ * can be exactly 4 characters in length if the first character is a digit.
+ *
+ * Note that this is a much stricter interpretation of {@code variant}
+ * than the public {@code Locale} constructors. The latter allowed free form
+ * variants.
+ *
+ * Variants are case sensitive and all separators are normalized to {@code '_'}.
+ *
+ * @throws IllformedLocaleException if {@code} variant is invalid.
+ */
+ public Builder setVariant(String variant) {
+ this.variant = normalizeAndValidateVariant(variant);
+ return this;
+ }
+
+ private static String normalizeAndValidateVariant(String variant) {
+ if (variant == null || variant.isEmpty()) {
+ return "";
+ }
+
+ // Note that unlike extensions, we canonicalize to lower case alphabets
+ // and underscores instead of hyphens.
+ final String normalizedVariant = variant.replace('-', '_');
+ String[] subTags = normalizedVariant.split("_");
+
+ for (String subTag : subTags) {
+ if (!isValidVariantSubtag(subTag)) {
+ throw new IllformedLocaleException("Invalid variant: " + variant);
+ }
+ }
+
+ return normalizedVariant;
+ }
+
+ private static boolean isValidVariantSubtag(String subTag) {
+ // The BCP-47 spec states that :
+ // - Subtags can be between [5, 8] alphanumeric chars in length.
+ // - Subtags that start with a number are allowed to be 4 chars in length.
+ if (subTag.length() >= 5 && subTag.length() <= 8) {
+ if (isAsciiAlphaNum(subTag)) {
+ return true;
+ }
+ } else if (subTag.length() == 4) {
+ final char firstChar = subTag.charAt(0);
+ if ((firstChar >= '0' && firstChar <= '9') && isAsciiAlphaNum(subTag)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Sets the locale script. If {@code script} is {@code null} or empty,
+ * the previous value is cleared.
+ *
+ * As per BCP-47, the script must be 4 characters in length, and
+ * each character in the range {@code [a-zA-Z]}.
+ *
+ * A script usually represents a valid ISO 15924 script code, though no
+ * other registry or validity checks are performed.
+ *
+ * Scripts are normalized to title cased values.
+ *
+ * @throws IllformedLocaleException if {@code script} is invalid.
+ */
+ public Builder setScript(String script) {
+ this.script = normalizeAndValidateScript(script, true /* strict */);
+ return this;
+ }
+
+ private static String normalizeAndValidateScript(String script, boolean strict) {
+ if (script == null || script.isEmpty()) {
+ return "";
+ }
+
+ if (!isValidBcp47Alpha(script, 4, 4)) {
+ if (strict) {
+ throw new IllformedLocaleException("Invalid script: " + script);
+ } else {
+ return "";
+ }
+ }
+
+ return titleCaseAsciiWord(script);
+ }
+
+ /**
+ * Sets the state of the builder to the {@link Locale} represented by
+ * {@code locale}.
+ *
+ * Note that the locale's language, region and variant are validated as per
+ * the rules specified in {@link #setLanguage}, {@link #setRegion} and
+ * {@link #setVariant}.
+ *
+ * All existing builder state is discarded.
+ *
+ * @throws IllformedLocaleException if {@code locale} is invalid.
+ * @throws NullPointerException if {@code locale} is null.
+ */
+ public Builder setLocale(Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException("locale == null");
+ }
+
+ // Make copies of the existing values so that we don't partially
+ // update the state if we encounter an error.
+ final String backupLanguage = language;
+ final String backupRegion = region;
+ final String backupVariant = variant;
+
+ try {
+ setLanguage(locale.getLanguage());
+ setRegion(locale.getCountry());
+ setVariant(locale.getVariant());
+ } catch (IllformedLocaleException ifle) {
+ language = backupLanguage;
+ region = backupRegion;
+ variant = backupVariant;
+
+ throw ifle;
+ }
+
+ // The following values can be set only via the builder class, so
+ // there's no need to normalize them or check their validity.
+
+ this.script = locale.getScript();
+
+ extensions.clear();
+ extensions.putAll(locale.extensions);
+
+ keywords.clear();
+ keywords.putAll(locale.unicodeKeywords);
+
+ attributes.clear();
+ attributes.addAll(locale.unicodeAttributes);
+
+ return this;
+ }
+
+ /**
+ * Adds the specified attribute to the list of attributes in the unicode
+ * locale extension.
+ *
+ * Attributes must be between 3 and 8 characters in length, and each character
+ * must be in the range {@code [a-zA-Z0-9]}.
+ *
+ * Attributes are normalized to lower case values. All added attributes and
+ * keywords are combined to form a complete unicode locale extension on
+ * {@link Locale} objects built by this builder, and accessible via
+ * {@link Locale#getExtension(char)} with the {@link Locale#UNICODE_LOCALE_EXTENSION}
+ * key.
+ *
+ * @throws IllformedLocaleException if {@code attribute} is invalid.
+ * @throws NullPointerException if {@code attribute} is null.
+ */
+ public Builder addUnicodeLocaleAttribute(String attribute) {
+ if (attribute == null) {
+ throw new NullPointerException("attribute == null");
+ }
+
+ final String lowercaseAttribute = attribute.toLowerCase(Locale.ROOT);
+ if (!isValidBcp47Alphanum(lowercaseAttribute, 3, 8)) {
+ throw new IllformedLocaleException("Invalid locale attribute: " + attribute);
+ }
+
+ attributes.add(lowercaseAttribute);
+
+ return this;
+ }
+
+ /**
+ * Removes an attribute from the list of attributes in the unicode locale
+ * extension.
+ *
+ * {@code attribute} must be valid as per the rules specified in
+ * {@link #addUnicodeLocaleAttribute}.
+ *
+ * This method has no effect if {@code attribute} hasn't already been
+ * added.
+ *
+ * @throws IllformedLocaleException if {@code attribute} is invalid.
+ * @throws NullPointerException if {@code attribute} is null.
+ */
+ public Builder removeUnicodeLocaleAttribute(String attribute) {
+ if (attribute == null) {
+ throw new NullPointerException("attribute == null");
+ }
+
+ // Weirdly, remove is specified to check whether the attribute
+ // is valid, so we have to perform the full alphanumeric check here.
+ final String lowercaseAttribute = attribute.toLowerCase(Locale.ROOT);
+ if (!isValidBcp47Alphanum(lowercaseAttribute, 3, 8)) {
+ throw new IllformedLocaleException("Invalid locale attribute: " + attribute);
+ }
+
+ attributes.remove(attribute);
+ return this;
+ }
+
+ /**
+ * Sets the extension identified by {@code key} to {@code value}.
+ *
+ * {@code key} must be in the range {@code [a-zA-Z0-9]}.
+ *
+ * If {@code value} is {@code null} or empty, the extension is removed.
+ *
+ * In the general case, {@code value} must be a series of subtags separated
+ * by ({@code "-"} or {@code "_"}). Each subtag must be between
+ * 2 and 8 characters in length, and each character in the subtag must be in
+ * the range {@code [a-zA-Z0-9]}.
+ *
+ * <p>
+ * There are two special cases :
+ * <li>
+ * <ul>
+ * The unicode locale extension
+ * ({@code key == 'u'}, {@link Locale#UNICODE_LOCALE_EXTENSION}) : Setting
+ * the unicode locale extension results in all existing keyword and attribute
+ * state being replaced by the parsed result of {@code value}. For example,
+ * {@code builder.setExtension('u', "baaaz-baaar-fo-baar-ba-baaz")}
+ * is equivalent to:
+ * <pre>
+ * builder.addUnicodeLocaleAttribute("baaaz");
+ * builder.addUnicodeLocaleAttribute("baaar");
+ * builder.setUnicodeLocaleKeyword("fo", "baar");
+ * builder.setUnicodeLocaleKeyword("ba", "baaa");
+ * </pre>
+ * </ul>
+ * <ul>
+ * The private use extension
+ * ({@code key == 'x'}, {@link Locale#PRIVATE_USE_EXTENSION}) : Each subtag in a
+ * private use extension can be between 1 and 8 characters in length (in contrast
+ * to a minimum length of 2 for all other extensions).
+ * </ul>
+ * </li>
+ *
+ * @throws IllformedLocaleException if {@code value} is invalid.
+ */
+ public Builder setExtension(char key, String value) {
+ if (value == null || value.isEmpty()) {
+ extensions.remove(key);
+ return this;
+ }
+
+ final String normalizedValue = value.toLowerCase(Locale.ROOT).replace('_', '-');
+ final String[] subtags = normalizedValue.split("-");
+
+ // Lengths for subtags in the private use extension should be [1, 8] chars.
+ // For all other extensions, they should be [2, 8] chars.
+ //
+ // http://www.rfc-editor.org/rfc/bcp/bcp47.txt
+ final int minimumLength = (key == PRIVATE_USE_EXTENSION) ? 1 : 2;
+ for (String subtag : subtags) {
+ if (!isValidBcp47Alphanum(subtag, minimumLength, 8)) {
+ throw new IllformedLocaleException(
+ "Invalid private use extension : " + value);
+ }
+ }
+
+ // We need to take special action in the case of unicode extensions,
+ // since we claim to understand their keywords and attributes.
+ if (key == UNICODE_LOCALE_EXTENSION) {
+ // First clear existing attributes and keywords.
+ extensions.clear();
+ attributes.clear();
+
+ parseUnicodeExtension(subtags, keywords, attributes);
+ } else {
+ extensions.put(key, normalizedValue);
+ }
+
+ return this;
+ }
+
+ /**
+ * Clears all extensions from this builder. Note that this also implicitly
+ * clears all state related to the unicode locale extension; all attributes
+ * and keywords set by {@link #addUnicodeLocaleAttribute} and
+ * {@link #setUnicodeLocaleKeyword} are cleared.
+ */
+ public Builder clearExtensions() {
+ extensions.clear();
+ attributes.clear();
+ keywords.clear();
+ return this;
+ }
+
+ /**
+ * Adds a key / type pair to the list of unicode locale extension keys.
+ *
+ * {@code key} must be 2 characters in length, and each character must be
+ * in the range {@code [a-zA-Z0-9]}.
+ *
+ * {#code type} can either be empty, or a series of one or more subtags
+ * separated by a separator ({@code "-"} or {@code "_"}). Each subtag must
+ * be between 3 and 8 characters in length and each character in the subtag
+ * must be in the range {@code [a-zA-Z0-9]}.
+ *
+ * Note that the type is normalized to lower case, and all separators
+ * are normalized to {@code "-"}. All added attributes and
+ * keywords are combined to form a complete unicode locale extension on
+ * {@link Locale} objects built by this builder, and accessible via
+ * {@link Locale#getExtension(char)} with the {@link Locale#UNICODE_LOCALE_EXTENSION}
+ * key.
+ *
+ * @throws IllformedLocaleException if {@code key} or {@code value} are
+ * invalid.
+ */
+ public Builder setUnicodeLocaleKeyword(String key, String type) {
+ if (key == null) {
+ throw new NullPointerException("key == null");
+ }
+
+ if (type == null && keywords != null) {
+ keywords.remove(key);
+ return this;
+ }
+
+ final String lowerCaseKey = key.toLowerCase(Locale.ROOT);
+ // The key must be exactly two alphanumeric characters.
+ if (lowerCaseKey.length() != 2 || !isAsciiAlphaNum(lowerCaseKey)) {
+ throw new IllformedLocaleException("Invalid unicode locale keyword: " + key);
+ }
+
+ // The type can be one or more alphanumeric strings of length [3, 8] characters,
+ // separated by a separator char, which is one of "_" or "-". Though the spec
+ // doesn't require it, we normalize all "_" to "-" to make the rest of our
+ // processing easier.
+ final String lowerCaseType = type.toLowerCase(Locale.ROOT).replace("_", "-");
+ if (!isValidTypeList(lowerCaseType)) {
+ throw new IllformedLocaleException("Invalid unicode locale type: " + type);
+ }
+
+ // Everything checks out fine, add the <key, type> mapping to the list.
+ keywords.put(lowerCaseKey, lowerCaseType);
+
+ return this;
+ }
+
+ /**
+ * Clears all existing state from this builder.
+ */
+ public Builder clear() {
+ clearExtensions();
+ language = region = variant = script = "";
+
+ return this;
+ }
+
+ /**
+ * Constructs a locale from the existing state of the builder. Note that this
+ * method is guaranteed to succeed since field validity checks are performed
+ * at the point of setting them.
+ */
+ public Locale build() {
+ // NOTE: We need to make a copy of attributes, keywords and extensions
+ // because the RI allows this builder to reused.
+ return new Locale(language, region, variant, script,
+ attributes, keywords, extensions,
+ true /* has validated fields */);
+ }
+ }
+
+ /**
+ * Returns a locale for a given BCP-47 language tag. This method is more
+ * lenient than {@link Builder#setLanguageTag}. For a given language tag, parsing
+ * will proceed up to the first malformed subtag. All subsequent tags are discarded.
+ * Note that language tags use {@code -} rather than {@code _}, for example {@code en-US}.
+ *
+ * @throws NullPointerException if {@code languageTag} is {@code null}.
+ *
+ * @since 1.7
+ */
+ public static Locale forLanguageTag(String languageTag) {
+ if (languageTag == null) {
+ throw new NullPointerException("languageTag == null");
+ }
+
+ return forLanguageTag(languageTag, false /* strict */);
+ }
+
private transient String countryCode;
private transient String languageCode;
private transient String variantCode;
+ private transient String scriptCode;
+
+ /* Sorted, Unmodifiable */
+ private transient Set<String> unicodeAttributes;
+ /* Sorted, Unmodifiable */
+ private transient Map<String, String> unicodeKeywords;
+ /* Sorted, Unmodifiable */
+ private transient Map<Character, String> extensions;
+
+ /**
+ * Whether this instance was constructed from a builder. We can make
+ * stronger assumptions about the validity of Locale fields if this was
+ * constructed by a builder.
+ */
+ private transient final boolean hasValidatedFields;
+
private transient String cachedToStringResult;
+ private transient String cachedLanguageTag;
+ private transient String cachedIcuLocaleId;
/**
* There's a circular dependency between toLowerCase/toUpperCase and
* Locale.US. Work around this by avoiding these methods when constructing
* the built-in locales.
- *
- * @param unused required for this constructor to have a unique signature
*/
- private Locale(boolean unused, String lowerCaseLanguageCode, String upperCaseCountryCode) {
+ private Locale(boolean hasValidatedFields, String lowerCaseLanguageCode,
+ String upperCaseCountryCode) {
this.languageCode = lowerCaseLanguageCode;
this.countryCode = upperCaseCountryCode;
this.variantCode = "";
+ this.scriptCode = "";
+
+ this.unicodeAttributes = Collections.EMPTY_SET;
+ this.unicodeKeywords = Collections.EMPTY_MAP;
+ this.extensions = Collections.EMPTY_MAP;
+
+ this.hasValidatedFields = hasValidatedFields;
}
/**
* Constructs a new {@code Locale} using the specified language.
*/
public Locale(String language) {
- this(language, "", "");
+ this(language, "", "", "", Collections.EMPTY_SET, Collections.EMPTY_MAP,
+ Collections.EMPTY_MAP, false /* has validated fields */);
}
/**
* Constructs a new {@code Locale} using the specified language and country codes.
*/
public Locale(String language, String country) {
- this(language, country, "");
+ this(language, country, "", "", Collections.EMPTY_SET, Collections.EMPTY_MAP,
+ Collections.EMPTY_MAP, false /* has validated fields */);
}
/**
- * Constructs a new {@code Locale} using the specified language, country,
- * and variant codes.
+ * Required by libcore.icu.ICU.
+ *
+ * @hide
*/
- public Locale(String language, String country, String variant) {
+ public Locale(String language, String country, String variant, String scriptCode,
+ /* nonnull */ Set<String> unicodeAttributes,
+ /* nonnull */ Map<String, String> unicodeKeywords,
+ /* nonnull */ Map<Character, String> extensions,
+ boolean hasValidatedFields) {
if (language == null || country == null || variant == null) {
throw new NullPointerException("language=" + language +
- ",country=" + country +
- ",variant=" + variant);
+ ",country=" + country +
+ ",variant=" + variant);
}
- if (language.isEmpty() && country.isEmpty()) {
- languageCode = "";
- countryCode = "";
- variantCode = variant;
- return;
+
+ if (hasValidatedFields) {
+ this.languageCode = adjustLanguageCode(language);
+ this.countryCode = country;
+ this.variantCode = variant;
+ } else {
+ if (language.isEmpty() && country.isEmpty()) {
+ languageCode = "";
+ countryCode = "";
+ variantCode = variant;
+ } else {
+ languageCode = adjustLanguageCode(language);
+ countryCode = country.toUpperCase(Locale.US);
+ variantCode = variant;
+ }
}
- languageCode = language.toLowerCase(Locale.US);
- // Map new language codes to the obsolete language
- // codes so the correct resource bundles will be used.
- if (languageCode.equals("he")) {
- languageCode = "iw";
- } else if (languageCode.equals("id")) {
- languageCode = "in";
- } else if (languageCode.equals("yi")) {
- languageCode = "ji";
+ this.scriptCode = scriptCode;
+
+ if (hasValidatedFields) {
+ Set<String> attribsCopy = new TreeSet<String>(unicodeAttributes);
+ Map<String, String> keywordsCopy = new TreeMap<String, String>(unicodeKeywords);
+ Map<Character, String> extensionsCopy = new TreeMap<Character, String>(extensions);
+
+ // We need to transform the list of attributes & keywords set on the
+ // builder to a unicode locale extension. i.e, if we have any keywords
+ // or attributes set, Locale#getExtension('u') should return a well
+ // formed extension.
+ addUnicodeExtensionToExtensionsMap(attribsCopy, keywordsCopy, extensionsCopy);
+
+ this.unicodeAttributes = Collections.unmodifiableSet(attribsCopy);
+ this.unicodeKeywords = Collections.unmodifiableMap(keywordsCopy);
+ this.extensions = Collections.unmodifiableMap(extensionsCopy);
+ } else {
+ this.unicodeAttributes = unicodeAttributes;
+ this.unicodeKeywords = unicodeKeywords;
+ this.extensions = extensions;
}
- countryCode = country.toUpperCase(Locale.US);
+ this.hasValidatedFields = hasValidatedFields;
+ }
- // Work around for be compatible with RI
- variantCode = variant;
+ /**
+ * Constructs a new {@code Locale} using the specified language, country,
+ * and variant codes.
+ */
+ public Locale(String language, String country, String variant) {
+ this(language, country, variant, "", Collections.EMPTY_SET,
+ Collections.EMPTY_MAP, Collections.EMPTY_MAP,
+ false /* has validated fields */);
}
@Override public Object clone() {
@@ -341,7 +964,10 @@ public final class Locale implements Cloneable, Serializable {
Locale o = (Locale) object;
return languageCode.equals(o.languageCode)
&& countryCode.equals(o.countryCode)
- && variantCode.equals(o.variantCode);
+ && variantCode.equals(o.variantCode)
+ && scriptCode.equals(o.scriptCode)
+ && extensions.equals(o.extensions);
+
}
return false;
}
@@ -399,9 +1025,16 @@ public final class Locale implements Cloneable, Serializable {
if (countryCode.isEmpty()) {
return "";
}
- String result = ICU.getDisplayCountryNative(toString(), locale.toString());
+
+ final String normalizedRegion = Builder.normalizeAndValidateRegion(
+ countryCode, false /* strict */);
+ if (normalizedRegion.isEmpty()) {
+ return countryCode;
+ }
+
+ String result = ICU.getDisplayCountry(this, locale);
if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
- result = ICU.getDisplayCountryNative(toString(), Locale.getDefault().toString());
+ result = ICU.getDisplayCountry(this, Locale.getDefault());
}
return result;
}
@@ -422,17 +1055,24 @@ public final class Locale implements Cloneable, Serializable {
return "";
}
- // http://b/8049507 --- frameworks/base should use fil_PH instead of tl_PH.
- // Until then, we're stuck covering their tracks, making it look like they're
- // using "fil" when they're not.
- String localeString = toString();
- if (languageCode.equals("tl")) {
- localeString = toNewString("fil", countryCode, variantCode);
+ // Hacks for backward compatibility.
+ //
+ // Our language tag will contain "und" if the languageCode is invalid
+ // or missing. ICU will then return "langue indéterminée" or the equivalent
+ // display language for the indeterminate language code.
+ //
+ // Sigh... ugh... and what not.
+ final String normalizedLanguage = Builder.normalizeAndValidateLanguage(
+ languageCode, false /* strict */);
+ if (UNDETERMINED_LANGUAGE.equals(normalizedLanguage)) {
+ return languageCode;
}
- String result = ICU.getDisplayLanguageNative(localeString, locale.toString());
+ // TODO: We need a new hack or a complete fix for http://b/8049507 --- We would
+ // cover the frameworks' tracks when they were using "tl" instead of "fil".
+ String result = ICU.getDisplayLanguage(this, locale);
if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
- result = ICU.getDisplayLanguageNative(localeString, Locale.getDefault().toString());
+ result = ICU.getDisplayLanguage(this, Locale.getDefault());
}
return result;
}
@@ -447,13 +1087,14 @@ public final class Locale implements Cloneable, Serializable {
/**
* Returns this locale's language name, country name, and variant, localized
* to {@code locale}. The exact output form depends on whether this locale
- * corresponds to a specific language, country and variant.
+ * corresponds to a specific language, script, country and variant.
*
* <p>For example:
* <ul>
* <li>{@code new Locale("en").getDisplayName(Locale.US)} -> {@code English}
* <li>{@code new Locale("en", "US").getDisplayName(Locale.US)} -> {@code English (United States)}
* <li>{@code new Locale("en", "US", "POSIX").getDisplayName(Locale.US)} -> {@code English (United States,Computer)}
+ * <li>{@code Locale.fromLanguageTag("zh-Hant-CN").getDisplayName(Locale.US)} -> {@code Chinese (Traditional Han,China)}
* <li>{@code new Locale("en").getDisplayName(Locale.FRANCE)} -> {@code anglais}
* <li>{@code new Locale("en", "US").getDisplayName(Locale.FRANCE)} -> {@code anglais (États-Unis)}
* <li>{@code new Locale("en", "US", "POSIX").getDisplayName(Locale.FRANCE)} -> {@code anglais (États-Unis,informatique)}.
@@ -467,9 +1108,19 @@ public final class Locale implements Cloneable, Serializable {
buffer.append(displayLanguage.isEmpty() ? languageCode : displayLanguage);
++count;
}
+ if (!scriptCode.isEmpty()) {
+ if (count == 1) {
+ buffer.append(" (");
+ }
+ String displayScript = getDisplayScript(locale);
+ buffer.append(displayScript.isEmpty() ? scriptCode : displayScript);
+ ++count;
+ }
if (!countryCode.isEmpty()) {
if (count == 1) {
buffer.append(" (");
+ } else if (count == 2) {
+ buffer.append(",");
}
String displayCountry = getDisplayCountry(locale);
buffer.append(displayCountry.isEmpty() ? countryCode : displayCountry);
@@ -478,7 +1129,7 @@ public final class Locale implements Cloneable, Serializable {
if (!variantCode.isEmpty()) {
if (count == 1) {
buffer.append(" (");
- } else if (count == 2) {
+ } else if (count == 2 || count == 3) {
buffer.append(",");
}
String displayVariant = getDisplayVariant(locale);
@@ -495,6 +1146,8 @@ public final class Locale implements Cloneable, Serializable {
* Returns the full variant name in the default {@code Locale} for the variant code of
* this {@code Locale}. If there is no matching variant name, the variant code is
* returned.
+ *
+ * @since 1.7
*/
public final String getDisplayVariant() {
return getDisplayVariant(getDefault());
@@ -504,14 +1157,31 @@ public final class Locale implements Cloneable, Serializable {
* Returns the full variant name in the specified {@code Locale} for the variant code
* of this {@code Locale}. If there is no matching variant name, the variant code is
* returned.
+ *
+ * @since 1.7
*/
public String getDisplayVariant(Locale locale) {
- if (variantCode.length() == 0) {
+ if (variantCode.isEmpty()) {
+ return "";
+ }
+
+ try {
+ Builder.normalizeAndValidateVariant(variantCode);
+ } catch (IllformedLocaleException ilfe) {
return variantCode;
}
- String result = ICU.getDisplayVariantNative(toString(), locale.toString());
+
+ String result = ICU.getDisplayVariant(this, locale);
if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
- result = ICU.getDisplayVariantNative(toString(), Locale.getDefault().toString());
+ result = ICU.getDisplayVariant(this, Locale.getDefault());
+ }
+
+ // The "old style" locale constructors allow us to pass in variants that aren't
+ // valid BCP-47 variant subtags. When that happens, toLanguageTag will not emit
+ // them. Note that we know variantCode.length() > 0 due to the isEmpty check at
+ // the beginning of this function.
+ if (result.isEmpty()) {
+ return variantCode;
}
return result;
}
@@ -522,7 +1192,10 @@ public final class Locale implements Cloneable, Serializable {
* @throws MissingResourceException if there's no 3-letter country code for this locale.
*/
public String getISO3Country() {
- String code = ICU.getISO3CountryNative(toString());
+ // The results of getISO3Country do not depend on the languageCode,
+ // so we pass an arbitrarily selected language code here. This guards
+ // against errors caused by malformed or invalid language codes.
+ String code = ICU.getISO3Country("en-" + countryCode);
if (!countryCode.isEmpty() && code.isEmpty()) {
throw new MissingResourceException("No 3-letter country code for locale: " + this, "FormatData_" + this, "ShortCountry");
}
@@ -535,7 +1208,16 @@ public final class Locale implements Cloneable, Serializable {
* @throws MissingResourceException if there's no 3-letter language code for this locale.
*/
public String getISO3Language() {
- String code = ICU.getISO3LanguageNative(toString());
+ // For backward compatibility, we must return "" for an empty language
+ // code and not "und" which is the accurate ISO-639-3 code for an
+ // undetermined language.
+ if (languageCode.isEmpty()) {
+ return "";
+ }
+
+ // The results of getISO3Language do not depend on the country code
+ // or any of the other locale fields, so we pass just the language here.
+ String code = ICU.getISO3Language(languageCode);
if (!languageCode.isEmpty() && code.isEmpty()) {
throw new MissingResourceException("No 3-letter language code for locale: " + this, "FormatData_" + this, "ShortLanguage");
}
@@ -574,10 +1256,335 @@ public final class Locale implements Cloneable, Serializable {
return variantCode;
}
+ /**
+ * Returns the script code for this {@code Locale} or an empty {@code String} if no script
+ * was set.
+ *
+ * If set, the script code will be a title cased string of length 4, as per the ISO 15924
+ * specification.
+ *
+ * @since 1.7
+ */
+ public String getScript() {
+ return scriptCode;
+ }
+
+ /**
+ * Equivalent to {@code getDisplayScript(Locale.getDefault()))}
+ *
+ * @since 1.7
+ */
+ public String getDisplayScript() {
+ return getDisplayScript(getDefault());
+ }
+
+ /**
+ * Returns the name of this locale's script code, localized to {@link Locale}. If the
+ * script code is unknown, the return value of this method is the same as that of
+ * {@link #getScript()}.
+ *
+ * @since 1.7
+ */
+ public String getDisplayScript(Locale locale) {
+ if (scriptCode.isEmpty()) {
+ return "";
+ }
+
+ String result = ICU.getDisplayScript(this, locale);
+ if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
+ result = ICU.getDisplayScript(this, Locale.getDefault());
+ }
+
+ return result;
+
+ }
+
+ /**
+ * Returns a well formed BCP-47 language tag that identifies this locale.
+ *
+ * Note that this locale itself might consist of ill formed fields, since the
+ * public {@code Locale} constructors do not perform validity checks to maintain
+ * backwards compatibility. When this is the case, this method will either replace
+ * ill formed fields with standard BCP-47 subtags (For eg. "und" (undetermined)
+ * for invalid languages) or omit them altogether.
+ *
+ * Additionally, ill formed variants will result in the remainder of the tag
+ * (both variants and extensions) being moved to the private use extension,
+ * where they will appear after a subtag whose value is {@code "lvariant"}.
+ *
+ * It's also important to note that the BCP-47 tag is well formed in the sense
+ * that it is unambiguously parseable into its specified components. We do not
+ * require that any of the components are registered with the applicable registries.
+ * For example, we do not require scripts to be a registered ISO 15924 scripts or
+ * languages to appear in the ISO-639-2 code list.
+ *
+ * @since 1.7
+ */
+ public String toLanguageTag() {
+ if (cachedLanguageTag == null) {
+ cachedLanguageTag = makeLanguageTag();
+ }
+
+ return cachedLanguageTag;
+ }
+
+ /**
+ * Constructs a valid BCP-47 language tag from locale fields. Additional validation
+ * is required when this Locale was not constructed using a Builder and variants
+ * set this way are treated specially.
+ *
+ * In both cases, we convert empty language tags to "und", omit invalid country tags
+ * and perform a special case conversion of "no-NO-NY" to "nn-NO".
+ */
+ private String makeLanguageTag() {
+ // We only need to revalidate the language, country and variant because
+ // the rest of the fields can only be set via the builder which validates
+ // them anyway.
+ String language = "";
+ String region = "";
+ String variant = "";
+ String illFormedVariantSubtags = "";
+
+ if (hasValidatedFields) {
+ language = languageCode;
+ region = countryCode;
+ // Note that we are required to normalize hyphens to underscores
+ // in the builder, but we must use hyphens in the BCP-47 language tag.
+ variant = variantCode.replace('_', '-');
+ } else {
+ language = Builder.normalizeAndValidateLanguage(languageCode, false /* strict */);
+ region = Builder.normalizeAndValidateRegion(countryCode, false /* strict */);
+
+ try {
+ variant = Builder.normalizeAndValidateVariant(variantCode);
+ } catch (IllformedLocaleException ilfe) {
+ // If our variant is ill formed, we must attempt to split it into
+ // its constituent subtags and preserve the well formed bits and
+ // move the rest to the private use extension (if they're well
+ // formed extension subtags).
+ String split[] = splitIllformedVariant(variantCode);
+
+ variant = split[0];
+ illFormedVariantSubtags = split[1];
+ }
+ }
+
+ if (language.isEmpty()) {
+ language = UNDETERMINED_LANGUAGE;
+ }
+
+ if ("no".equals(language) && "NO".equals(region) && "NY".equals(variant)) {
+ language = "nn";
+ region = "NO";
+ variant = "";
+ }
+
+ final StringBuilder sb = new StringBuilder(16);
+ sb.append(language);
+
+ if (!scriptCode.isEmpty()) {
+ sb.append('-');
+ sb.append(scriptCode);
+ }
+
+ if (!region.isEmpty()) {
+ sb.append('-');
+ sb.append(region);
+ }
+
+ if (!variant.isEmpty()) {
+ sb.append('-');
+ sb.append(variant);
+ }
+
+ // Extensions (optional, omitted if empty). Note that we don't
+ // emit the private use extension here, but add it in the end.
+ for (Map.Entry<Character, String> extension : extensions.entrySet()) {
+ if (!extension.getKey().equals('x')) {
+ sb.append('-').append(extension.getKey());
+ sb.append('-').append(extension.getValue());
+ }
+ }
+
+ // The private use extension comes right at the very end.
+ final String privateUse = extensions.get('x');
+ if (privateUse != null) {
+ sb.append("-x-");
+ sb.append(privateUse);
+ }
+
+ // If we have any ill-formed variant subtags, we append them to the
+ // private use extension (or add a private use extension if one doesn't
+ // exist).
+ if (!illFormedVariantSubtags.isEmpty()) {
+ if (privateUse == null) {
+ sb.append("-x-lvariant-");
+ } else {
+ sb.append('-');
+ }
+ sb.append(illFormedVariantSubtags);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Splits ill formed variants into a set of valid variant subtags (which
+ * can be used directly in language tag construction) and a set of invalid
+ * variant subtags (which can be appended to the private use extension),
+ * provided that each subtag is a valid private use extension subtag.
+ *
+ * This method returns a two element String array. The first element is a string
+ * containing the concatenation of valid variant subtags which can be appended
+ * to a BCP-47 tag directly and the second containing the concatenation of
+ * invalid variant subtags which can be appended to the private use extension
+ * directly.
+ *
+ * This method assumes that {@code variant} contains at least one ill formed
+ * variant subtag.
+ */
+ private static String[] splitIllformedVariant(String variant) {
+ final String normalizedVariant = variant.replace('_', '-');
+ final String[] subTags = normalizedVariant.split("-");
+
+ final String[] split = new String[] { "", "" };
+
+ // First go through the list of variant subtags and check if they're
+ // valid private use extension subtags. If they're not, we will omit
+ // the first such subtag and all subtags after.
+ //
+ // NOTE: |firstInvalidSubtag| is the index of the first variant
+ // subtag we decide to omit altogether, whereas |firstIllformedSubtag| is the
+ // index of the first subtag we decide to append to the private use extension.
+ //
+ // In other words:
+ // [0, firstIllformedSubtag) => expressed as variant subtags.
+ // [firstIllformedSubtag, firstInvalidSubtag) => expressed as private use
+ // extension subtags.
+ // [firstInvalidSubtag, subTags.length) => omitted.
+ int firstInvalidSubtag = subTags.length;
+ for (int i = 0; i < subTags.length; ++i) {
+ if (!isValidBcp47Alphanum(subTags[i], 1, 8)) {
+ firstInvalidSubtag = i;
+ break;
+ }
+ }
+
+ if (firstInvalidSubtag == 0) {
+ return split;
+ }
+
+ // We now consider each subtag that could potentially be appended to
+ // the private use extension and check if it's valid.
+ int firstIllformedSubtag = firstInvalidSubtag;
+ for (int i = 0; i < firstInvalidSubtag; ++i) {
+ final String subTag = subTags[i];
+ // The BCP-47 spec states that :
+ // - Subtags can be between [5, 8] alphanumeric chars in length.
+ // - Subtags that start with a number are allowed to be 4 chars in length.
+ if (subTag.length() >= 5 && subTag.length() <= 8) {
+ if (!isAsciiAlphaNum(subTag)) {
+ firstIllformedSubtag = i;
+ }
+ } else if (subTag.length() == 4) {
+ final char firstChar = subTag.charAt(0);
+ if (!(firstChar >= '0' && firstChar <= '9') || !isAsciiAlphaNum(subTag)) {
+ firstIllformedSubtag = i;
+ }
+ } else {
+ firstIllformedSubtag = i;
+ }
+ }
+
+ split[0] = concatenateRange(subTags, 0, firstIllformedSubtag);
+ split[1] = concatenateRange(subTags, firstIllformedSubtag, firstInvalidSubtag);
+
+ return split;
+ }
+
+ /**
+ * Builds a string by concatenating array elements within the range [start, end).
+ * The supplied range is assumed to be valid and no checks are performed.
+ */
+ private static String concatenateRange(String[] array, int start, int end) {
+ StringBuilder builder = new StringBuilder(32);
+ for (int i = start; i < end; ++i) {
+ if (i != start) {
+ builder.append('-');
+ }
+ builder.append(array[i]);
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Returns the set of BCP-47 extensions this locale contains.
+ *
+ * See <a href="https://tools.ietf.org/html/bcp47#section-2.1">
+ * the IETF BCP-47 specification</a> (Section 2.2.6) for details.
+ *
+ * @since 1.7
+ */
+ public Set<Character> getExtensionKeys() {
+ return extensions.keySet();
+ }
+
+ /**
+ * Returns the BCP-47 extension whose key is {@code extensionKey}, or {@code null}
+ * if this locale does not contain the extension.
+ *
+ * Individual Keywords and attributes for the unicode
+ * locale extension can be fetched using {@link #getUnicodeLocaleAttributes()},
+ * {@link #getUnicodeLocaleKeys()} and {@link #getUnicodeLocaleType}.
+ *
+ * @since 1.7
+ */
+ public String getExtension(char extensionKey) {
+ return extensions.get(extensionKey);
+ }
+
+ /**
+ * Returns the {@code type} for the specified unicode locale extension {@code key}.
+ *
+ * For more information about types and keywords, see {@link Builder#setUnicodeLocaleKeyword}
+ * and <a href="http://www.unicode.org/reports/tr35/#BCP47">Unicode Technical Standard #35</a>
+ *
+ * @since 1.7
+ */
+ public String getUnicodeLocaleType(String keyWord) {
+ return unicodeKeywords.get(keyWord);
+ }
+
+ /**
+ * Returns the set of unicode locale extension attributes this locale contains.
+ *
+ * For more information about attributes, see {@link Builder#addUnicodeLocaleAttribute}
+ * and <a href="http://www.unicode.org/reports/tr35/#BCP47">Unicode Technical Standard #35</a>
+ *
+ * @since 1.7
+ */
+ public Set<String> getUnicodeLocaleAttributes() {
+ return unicodeAttributes;
+ }
+
+ /**
+ * Returns the set of unicode locale extension keywords this locale contains.
+ *
+ * For more information about types and keywords, see {@link Builder#setUnicodeLocaleKeyword}
+ * and <a href="http://www.unicode.org/reports/tr35/#BCP47">Unicode Technical Standard #35</a>
+ *
+ * @since 1.7
+ */
+ public Set<String> getUnicodeLocaleKeys() {
+ return unicodeKeywords.keySet();
+ }
+
@Override
public synchronized int hashCode() {
- return countryCode.hashCode() + languageCode.hashCode()
- + variantCode.hashCode();
+ return countryCode.hashCode()
+ + languageCode.hashCode() + variantCode.hashCode()
+ + scriptCode.hashCode() + extensions.hashCode();
}
/**
@@ -592,7 +1599,9 @@ public final class Locale implements Cloneable, Serializable {
if (locale == null) {
throw new NullPointerException("locale == null");
}
+ String languageTag = locale.toLanguageTag();
defaultLocale = locale;
+ ICU.setDefaultLocale(languageTag);
}
/**
@@ -610,30 +1619,59 @@ public final class Locale implements Cloneable, Serializable {
public final String toString() {
String result = cachedToStringResult;
if (result == null) {
- result = cachedToStringResult = toNewString(languageCode, countryCode, variantCode);
+ result = cachedToStringResult = toNewString(languageCode, countryCode, variantCode,
+ scriptCode, extensions);
}
return result;
}
- private static String toNewString(String languageCode, String countryCode, String variantCode) {
+ private static String toNewString(String languageCode, String countryCode,
+ String variantCode, String scriptCode, Map<Character, String> extensions) {
// The string form of a locale that only has a variant is the empty string.
if (languageCode.length() == 0 && countryCode.length() == 0) {
return "";
}
+
// Otherwise, the output format is "ll_cc_variant", where language and country are always
// two letters, but the variant is an arbitrary length. A size of 11 characters has room
// for "en_US_POSIX", the largest "common" value. (In practice, the string form is almost
// always 5 characters: "ll_cc".)
StringBuilder result = new StringBuilder(11);
result.append(languageCode);
- if (countryCode.length() > 0 || variantCode.length() > 0) {
+
+ final boolean hasScriptOrExtensions = !scriptCode.isEmpty() || !extensions.isEmpty();
+
+ if (!countryCode.isEmpty() || !variantCode.isEmpty() || hasScriptOrExtensions) {
result.append('_');
}
result.append(countryCode);
- if (variantCode.length() > 0) {
+ if (!variantCode.isEmpty() || hasScriptOrExtensions) {
result.append('_');
}
result.append(variantCode);
+
+ if (hasScriptOrExtensions) {
+ if (!variantCode.isEmpty()) {
+ result.append('_');
+ }
+
+ // Note that this is notably different from the BCP-47 spec (for
+ // backwards compatibility). We are forced to append a "#" before the script tag.
+ // and also put the script code right at the end.
+ result.append("#");
+ if (!scriptCode.isEmpty() ) {
+ result.append(scriptCode);
+ }
+
+ // Note the use of "-" instead of "_" before the extensions.
+ if (!extensions.isEmpty()) {
+ if (!scriptCode.isEmpty()) {
+ result.append('-');
+ }
+ result.append(serializeExtensions(extensions));
+ }
+ }
+
return result.toString();
}
@@ -642,6 +1680,8 @@ public final class Locale implements Cloneable, Serializable {
new ObjectStreamField("hashcode", int.class),
new ObjectStreamField("language", String.class),
new ObjectStreamField("variant", String.class),
+ new ObjectStreamField("script", String.class),
+ new ObjectStreamField("extensions", String.class),
};
private void writeObject(ObjectOutputStream stream) throws IOException {
@@ -650,6 +1690,12 @@ public final class Locale implements Cloneable, Serializable {
fields.put("hashcode", -1);
fields.put("language", languageCode);
fields.put("variant", variantCode);
+ fields.put("script", scriptCode);
+
+ if (!extensions.isEmpty()) {
+ fields.put("extensions", serializeExtensions(extensions));
+ }
+
stream.writeFields();
}
@@ -658,5 +1704,545 @@ public final class Locale implements Cloneable, Serializable {
countryCode = (String) fields.get("country", "");
languageCode = (String) fields.get("language", "");
variantCode = (String) fields.get("variant", "");
+ scriptCode = (String) fields.get("script", "");
+
+ this.unicodeKeywords = Collections.EMPTY_MAP;
+ this.unicodeAttributes = Collections.EMPTY_SET;
+ this.extensions = Collections.EMPTY_MAP;
+
+ String extensions = (String) fields.get("extensions", null);
+ if (extensions != null) {
+ readExtensions(extensions);
+ }
+ }
+
+ private void readExtensions(String extensions) {
+ Map<Character, String> extensionsMap = new TreeMap<Character, String>();
+ parseSerializedExtensions(extensions, extensionsMap);
+ this.extensions = Collections.unmodifiableMap(extensionsMap);
+
+ if (extensionsMap.containsKey(UNICODE_LOCALE_EXTENSION)) {
+ String unicodeExtension = extensionsMap.get(UNICODE_LOCALE_EXTENSION);
+ String[] subTags = unicodeExtension.split("-");
+
+ Map<String, String> unicodeKeywords = new TreeMap<String, String>();
+ Set<String> unicodeAttributes = new TreeSet<String>();
+ parseUnicodeExtension(subTags, unicodeKeywords, unicodeAttributes);
+
+ this.unicodeKeywords = Collections.unmodifiableMap(unicodeKeywords);
+ this.unicodeAttributes = Collections.unmodifiableSet(unicodeAttributes);
+ }
+ }
+
+ /**
+ * The serialized form for extensions is straightforward. It's simply
+ * of the form key1-value1-key2-value2 where each value might in turn contain
+ * multiple subtags separated by hyphens. Each key is guaranteed to be a single
+ * character in length.
+ *
+ * This method assumes that {@code extensionsMap} is non-empty.
+ *
+ * Visible for testing.
+ *
+ * @hide
+ */
+ public static String serializeExtensions(Map<Character, String> extensionsMap) {
+ Iterator<Map.Entry<Character, String>> entryIterator = extensionsMap.entrySet().iterator();
+ StringBuilder sb = new StringBuilder(64);
+
+ while (true) {
+ final Map.Entry<Character, String> entry = entryIterator.next();
+ sb.append(entry.getKey());
+ sb.append('-');
+ sb.append(entry.getValue());
+
+ if (entryIterator.hasNext()) {
+ sb.append('-');
+ } else {
+ break;
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Visible for testing.
+ *
+ * @hide
+ */
+ public static void parseSerializedExtensions(String extString, Map<Character, String> outputMap) {
+ // This probably isn't the most efficient approach, but it's the
+ // most straightforward to code.
+ //
+ // Start by splitting the string on "-". We will then keep track of
+ // where each of the extension keys (single characters) appear in the
+ // original string and then use those indices to construct substrings
+ // representing the values.
+ final String[] subTags = extString.split("-");
+ final int[] typeStartIndices = new int[subTags.length / 2];
+
+ int length = 0;
+ int count = 0;
+ for (String subTag : subTags) {
+ if (subTag.length() > 0) {
+ // Account for the length of the "-" at the end of each subtag.
+ length += (subTag.length() + 1);
+ }
+
+ if (subTag.length() == 1) {
+ typeStartIndices[count++] = length;
+ }
+ }
+
+ for (int i = 0; i < count; ++i) {
+ final int valueStart = typeStartIndices[i];
+ // Since the start Index points to the beginning of the next type
+ // ....prev-k-next.....
+ // |_ here
+ // (idx - 2) is the index of the next key
+ // (idx - 3) is the (non inclusive) end of the previous type.
+ final int valueEnd = (i == (count - 1)) ?
+ extString.length() : (typeStartIndices[i + 1] - 3);
+
+ outputMap.put(extString.charAt(typeStartIndices[i] - 2),
+ extString.substring(valueStart, valueEnd));
+ }
+ }
+
+
+ /**
+ * A UN M.49 is a 3 digit numeric code.
+ */
+ private static boolean isUnM49AreaCode(String code) {
+ if (code.length() != 3) {
+ return false;
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ final char character = code.charAt(i);
+ if (!(character >= '0' && character <= '9')) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /*
+ * Checks whether a given string is an ASCII alphanumeric string.
+ */
+ private static boolean isAsciiAlphaNum(String string) {
+ for (int i = 0; i < string.length(); i++) {
+ final char character = string.charAt(i);
+ if (!(character >= 'a' && character <= 'z' ||
+ character >= 'A' && character <= 'Z' ||
+ character >= '0' && character <= '9')) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean isValidBcp47Alpha(String string, int lowerBound, int upperBound) {
+ final int length = string.length();
+ if (length < lowerBound || length > upperBound) {
+ return false;
+ }
+
+ for (int i = 0; i < length; ++i) {
+ final char character = string.charAt(i);
+ if (!(character >= 'a' && character <= 'z' ||
+ character >= 'A' && character <= 'Z')) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean isValidBcp47Alphanum(String attributeOrType,
+ int lowerBound, int upperBound) {
+ if (attributeOrType.length() < lowerBound || attributeOrType.length() > upperBound) {
+ return false;
+ }
+
+ return isAsciiAlphaNum(attributeOrType);
+ }
+
+ private static String titleCaseAsciiWord(String word) {
+ try {
+ byte[] chars = word.toLowerCase(Locale.ROOT).getBytes(StandardCharsets.US_ASCII);
+ chars[0] = (byte) ((int) chars[0] + 'A' - 'a');
+ return new String(chars, StandardCharsets.US_ASCII);
+ } catch (UnsupportedOperationException uoe) {
+ throw new AssertionError(uoe);
+ }
+ }
+
+ /**
+ * A type list must contain one or more alphanumeric subtags whose lengths
+ * are between 3 and 8.
+ */
+ private static boolean isValidTypeList(String lowerCaseTypeList) {
+ final String[] splitList = lowerCaseTypeList.split("-");
+ for (String type : splitList) {
+ if (!isValidBcp47Alphanum(type, 3, 8)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static void addUnicodeExtensionToExtensionsMap(
+ Set<String> attributes, Map<String, String> keywords,
+ Map<Character, String> extensions) {
+ if (attributes.isEmpty() && keywords.isEmpty()) {
+ return;
+ }
+
+ // Assume that the common case is a low number of keywords & attributes
+ // (usually one or two).
+ final StringBuilder sb = new StringBuilder(32);
+
+ // All attributes must appear before keywords, in lexical order.
+ if (!attributes.isEmpty()) {
+ Iterator<String> attributesIterator = attributes.iterator();
+ while (true) {
+ sb.append(attributesIterator.next());
+ if (attributesIterator.hasNext()) {
+ sb.append('-');
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (!keywords.isEmpty()) {
+ if (!attributes.isEmpty()) {
+ sb.append('-');
+ }
+
+ Iterator<Map.Entry<String, String>> keywordsIterator = keywords.entrySet().iterator();
+ while (true) {
+ final Map.Entry<String, String> keyWord = keywordsIterator.next();
+ sb.append(keyWord.getKey());
+ if (!keyWord.getValue().isEmpty()) {
+ sb.append('-');
+ sb.append(keyWord.getValue());
+ }
+ if (keywordsIterator.hasNext()) {
+ sb.append('-');
+ } else {
+ break;
+ }
+ }
+ }
+
+ extensions.put(UNICODE_LOCALE_EXTENSION, sb.toString());
+ }
+
+ /**
+ * This extension is described by http://www.unicode.org/reports/tr35/#RFC5234
+ * unicode_locale_extensions = sep "u" (1*(sep keyword) / 1*(sep attribute) *(sep keyword)).
+ *
+ * It must contain at least one keyword or attribute and attributes (if any)
+ * must appear before keywords. Attributes can't appear after keywords because
+ * they will be indistinguishable from a subtag of the keyword type.
+ *
+ * Visible for testing.
+ *
+ * @hide
+ */
+ public static void parseUnicodeExtension(String[] subtags,
+ Map<String, String> keywords, Set<String> attributes) {
+ String lastKeyword = null;
+ List<String> subtagsForKeyword = new ArrayList<String>();
+ for (String subtag : subtags) {
+ if (subtag.length() == 2) {
+ if (subtagsForKeyword.size() > 0) {
+ keywords.put(lastKeyword, joinBcp47Subtags(subtagsForKeyword));
+ subtagsForKeyword.clear();
+ }
+
+ lastKeyword = subtag;
+ } else if (subtag.length() > 2) {
+ if (lastKeyword == null) {
+ attributes.add(subtag);
+ } else {
+ subtagsForKeyword.add(subtag);
+ }
+ }
+ }
+
+ if (subtagsForKeyword.size() > 0) {
+ keywords.put(lastKeyword, joinBcp47Subtags(subtagsForKeyword));
+ } else if (lastKeyword != null) {
+ keywords.put(lastKeyword, "");
+ }
+ }
+
+ /**
+ * Joins a list of subtags into a BCP-47 tag using the standard separator
+ * ("-").
+ */
+ private static String joinBcp47Subtags(List<String> strings) {
+ final int size = strings.size();
+
+ StringBuilder sb = new StringBuilder(strings.get(0).length());
+ for (int i = 0; i < size; ++i) {
+ sb.append(strings.get(i));
+ if (i != size - 1) {
+ sb.append('-');
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * @hide for internal use only.
+ */
+ public static String adjustLanguageCode(String languageCode) {
+ String adjusted = languageCode.toLowerCase(Locale.US);
+ // Map new language codes to the obsolete language
+ // codes so the correct resource bundles will be used.
+ if (languageCode.equals("he")) {
+ adjusted = "iw";
+ } else if (languageCode.equals("id")) {
+ adjusted = "in";
+ } else if (languageCode.equals("yi")) {
+ adjusted = "ji";
+ }
+
+ return adjusted;
+ }
+
+ /**
+ * Map of grandfathered language tags to their modern replacements.
+ */
+ private static final TreeMap<String, String> GRANDFATHERED_LOCALES;
+
+ static {
+ GRANDFATHERED_LOCALES = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+
+ // From http://tools.ietf.org/html/bcp47
+ //
+ // grandfathered = irregular ; non-redundant tags registered
+ // / regular ; during the RFC 3066 era
+ // irregular =
+ GRANDFATHERED_LOCALES.put("en-GB-oed", "en-GB-x-oed");
+ GRANDFATHERED_LOCALES.put("i-ami", "ami");
+ GRANDFATHERED_LOCALES.put("i-bnn", "bnn");
+ GRANDFATHERED_LOCALES.put("i-default", "en-x-i-default");
+ GRANDFATHERED_LOCALES.put("i-enochian", "und-x-i-enochian");
+ GRANDFATHERED_LOCALES.put("i-hak", "hak");
+ GRANDFATHERED_LOCALES.put("i-klingon", "tlh");
+ GRANDFATHERED_LOCALES.put("i-lux", "lb");
+ GRANDFATHERED_LOCALES.put("i-mingo", "see-x-i-mingo");
+ GRANDFATHERED_LOCALES.put("i-navajo", "nv");
+ GRANDFATHERED_LOCALES.put("i-pwn", "pwn");
+ GRANDFATHERED_LOCALES.put("i-tao", "tao");
+ GRANDFATHERED_LOCALES.put("i-tay", "tay");
+ GRANDFATHERED_LOCALES.put("i-tsu", "tsu");
+ GRANDFATHERED_LOCALES.put("sgn-BE-FR", "sfb");
+ GRANDFATHERED_LOCALES.put("sgn-BE-NL", "vgt");
+ GRANDFATHERED_LOCALES.put("sgn-CH-DE", "sgg");
+
+ // regular =
+ GRANDFATHERED_LOCALES.put("art-lojban", "jbo");
+ GRANDFATHERED_LOCALES.put("cel-gaulish", "xtg-x-cel-gaulish");
+ GRANDFATHERED_LOCALES.put("no-bok", "nb");
+ GRANDFATHERED_LOCALES.put("no-nyn", "nn");
+ GRANDFATHERED_LOCALES.put("zh-guoyu", "cmn");
+ GRANDFATHERED_LOCALES.put("zh-hakka", "hak");
+ GRANDFATHERED_LOCALES.put("zh-min", "nan-x-zh-min");
+ GRANDFATHERED_LOCALES.put("zh-min-nan", "nan");
+ GRANDFATHERED_LOCALES.put("zh-xiang", "hsn");
+ }
+
+ private static String convertGrandfatheredTag(String original) {
+ final String converted = GRANDFATHERED_LOCALES.get(original);
+ return converted != null ? converted : original;
+ }
+
+ /**
+ * Scans elements of {@code subtags} in the range {@code [startIndex, endIndex)}
+ * and appends valid variant subtags upto the first invalid subtag (if any) to
+ * {@code normalizedVariants}.
+ */
+ private static void extractVariantSubtags(String[] subtags, int startIndex, int endIndex,
+ List<String> normalizedVariants) {
+ for (int i = startIndex; i < endIndex; i++) {
+ final String subtag = subtags[i];
+
+ if (Builder.isValidVariantSubtag(subtag)) {
+ normalizedVariants.add(subtag);
+ } else {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Scans elements of {@code subtags} in the range {@code [startIndex, endIndex)}
+ * and inserts valid extensions into {@code extensions}. The scan is aborted
+ * when an invalid extension is encountered. Returns the index of the first
+ * unparsable element of {@code subtags}.
+ */
+ private static int extractExtensions(String[] subtags, int startIndex, int endIndex,
+ Map<Character, String> extensions) {
+ int privateUseExtensionIndex = -1;
+ int extensionKeyIndex = -1;
+
+ int i = startIndex;
+ for (; i < endIndex; i++) {
+ final String subtag = subtags[i];
+
+ final boolean parsingPrivateUse = (privateUseExtensionIndex != -1) &&
+ (extensionKeyIndex == privateUseExtensionIndex);
+
+ // Note that private use extensions allow subtags of length 1.
+ // Private use extensions *must* come last, so there's no ambiguity
+ // in that case.
+ if (subtag.length() == 1 && !parsingPrivateUse) {
+ // Emit the last extension we encountered if any. First check
+ // whether we encountered two keys in a row (which is an error).
+ // Also checks if we already have an extension with the same key,
+ // which is again an error.
+ if (extensionKeyIndex != -1) {
+ if ((i - 1) == extensionKeyIndex) {
+ return extensionKeyIndex;
+ }
+
+ final String key = subtags[extensionKeyIndex];
+ if (extensions.containsKey(key.charAt(0))) {
+ return extensionKeyIndex;
+ }
+
+ final String value = concatenateRange(subtags, extensionKeyIndex + 1, i);
+ extensions.put(key.charAt(0), value.toLowerCase(Locale.ROOT));
+ }
+
+ // Mark the start of the next extension. Also keep track of whether this
+ // is a private use extension, and throw an error if it doesn't come last.
+ extensionKeyIndex = i;
+ if ("x".equals(subtag)) {
+ privateUseExtensionIndex = i;
+ } else if (privateUseExtensionIndex != -1) {
+ // The private use extension must come last.
+ return privateUseExtensionIndex;
+ }
+ } else if (extensionKeyIndex != -1) {
+ // We must have encountered a valid key in order to start parsing
+ // its subtags.
+ if (!isValidBcp47Alphanum(subtag, parsingPrivateUse ? 1 : 2, 8)) {
+ return i;
+ }
+ } else {
+ // Encountered a value without a preceding key.
+ return i;
+ }
+ }
+
+ if (extensionKeyIndex != -1) {
+ if ((i - 1) == extensionKeyIndex) {
+ return extensionKeyIndex;
+ }
+
+ final String key = subtags[extensionKeyIndex];
+ if (extensions.containsKey(key.charAt(0))) {
+ return extensionKeyIndex;
+ }
+
+ final String value = concatenateRange(subtags, extensionKeyIndex + 1, i);
+ extensions.put(key.charAt(0), value.toLowerCase(Locale.ROOT));
+ }
+
+ return i;
+ }
+
+ private static Locale forLanguageTag(/* @Nonnull */ String tag, boolean strict) {
+ final String converted = convertGrandfatheredTag(tag);
+ final String[] subtags = converted.split("-");
+
+ int lastSubtag = subtags.length;
+ for (int i = 0; i < subtags.length; ++i) {
+ final String subtag = subtags[i];
+ if (subtag.isEmpty() || subtag.length() > 8) {
+ if (strict) {
+ throw new IllformedLocaleException("Invalid subtag at index: " + i
+ + " in tag: " + tag);
+ } else {
+ lastSubtag = (i - 1);
+ }
+
+ break;
+ }
+ }
+
+ final String languageCode = Builder.normalizeAndValidateLanguage(subtags[0], strict);
+ String scriptCode = "";
+ int nextSubtag = 1;
+ if (lastSubtag > nextSubtag) {
+ scriptCode = Builder.normalizeAndValidateScript(subtags[nextSubtag], false /* strict */);
+ if (!scriptCode.isEmpty()) {
+ nextSubtag++;
+ }
+ }
+
+ String regionCode = "";
+ if (lastSubtag > nextSubtag) {
+ regionCode = Builder.normalizeAndValidateRegion(subtags[nextSubtag], false /* strict */);
+ if (!regionCode.isEmpty()) {
+ nextSubtag++;
+ }
+ }
+
+ List<String> variants = null;
+ if (lastSubtag > nextSubtag) {
+ variants = new ArrayList<String>();
+ extractVariantSubtags(subtags, nextSubtag, lastSubtag, variants);
+ nextSubtag += variants.size();
+ }
+
+ Map<Character, String> extensions = Collections.EMPTY_MAP;
+ if (lastSubtag > nextSubtag) {
+ extensions = new TreeMap<Character, String>();
+ nextSubtag = extractExtensions(subtags, nextSubtag, lastSubtag, extensions);
+ }
+
+ if (nextSubtag != lastSubtag) {
+ if (strict) {
+ throw new IllformedLocaleException("Unparseable subtag: " + subtags[nextSubtag]
+ + " from language tag: " + tag);
+ }
+ }
+
+ Set<String> unicodeKeywords = Collections.EMPTY_SET;
+ Map<String, String> unicodeAttributes = Collections.EMPTY_MAP;
+ if (extensions.containsKey(UNICODE_LOCALE_EXTENSION)) {
+ unicodeKeywords = new TreeSet<String>();
+ unicodeAttributes = new TreeMap<String, String>();
+ parseUnicodeExtension(extensions.get(UNICODE_LOCALE_EXTENSION).split("-"),
+ unicodeAttributes, unicodeKeywords);
+ }
+
+ String variantCode = "";
+ if (variants != null && !variants.isEmpty()) {
+ StringBuilder variantsBuilder = new StringBuilder(variants.size() * 8);
+ for (int i = 0; i < variants.size(); ++i) {
+ if (i != 0) {
+ variantsBuilder.append('_');
+ }
+ variantsBuilder.append(variants.get(i));
+ }
+ variantCode = variantsBuilder.toString();
+ }
+
+ return new Locale(languageCode, regionCode, variantCode, scriptCode,
+ unicodeKeywords, unicodeAttributes, extensions, true /* has validated fields */);
}
}
diff --git a/luni/src/main/java/java/util/Properties.java b/luni/src/main/java/java/util/Properties.java
index cd19295..532d35c 100644
--- a/luni/src/main/java/java/util/Properties.java
+++ b/luni/src/main/java/java/util/Properties.java
@@ -52,7 +52,7 @@ import org.xml.sax.SAXParseException;
* values to be used when a given key is not found in this {@code Properties}
* instance.
*
- * <a name="character_encoding"><h3>Character Encoding</h3></a>
+ * <a name="character_encoding"></a><h3>Character Encoding</h3>
* <p>Note that in some cases {@code Properties} uses ISO-8859-1 instead of UTF-8.
* ISO-8859-1 is only capable of representing a tiny subset of Unicode.
* Use either the {@code loadFromXML}/{@code storeToXML} methods (which use UTF-8 by
diff --git a/luni/src/main/java/java/util/Random.java b/luni/src/main/java/java/util/Random.java
index 4a67244..091d584 100644
--- a/luni/src/main/java/java/util/Random.java
+++ b/luni/src/main/java/java/util/Random.java
@@ -56,15 +56,19 @@ public class Random implements Serializable {
private double nextNextGaussian;
/**
+ * Used to generate initial seeds.
+ */
+ private static volatile long seedBase = 0;
+
+ /**
* Constructs a random generator with an initial state that is
* unlikely to be duplicated by a subsequent instantiation.
- *
- * <p>The initial state (that is, the seed) is <i>partially</i> based
- * on the current time of day in milliseconds.
*/
public Random() {
- // Note: Using identityHashCode() to be hermetic wrt subclasses.
- setSeed(System.currentTimeMillis() + System.identityHashCode(this));
+ // Note: Don't use identityHashCode(this) since that causes the monitor to
+ // get inflated when we synchronize.
+ setSeed(System.nanoTime() + seedBase);
+ ++seedBase;
}
/**
@@ -85,6 +89,9 @@ public class Random implements Serializable {
* Volume 2: Seminumerical Algorithms</i>, section 3.2.1.
*
* <p>Most applications will want to use one of this class' convenience methods instead.
+ *
+ * <p>Subclasses only need to override this method to alter the behavior
+ * of all the public methods.
*/
protected synchronized int next(int bits) {
seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1);
diff --git a/luni/src/main/java/java/util/Scanner.java b/luni/src/main/java/java/util/Scanner.java
index 7d504b7..7d0e795 100644
--- a/luni/src/main/java/java/util/Scanner.java
+++ b/luni/src/main/java/java/util/Scanner.java
@@ -159,12 +159,15 @@ public final class Scanner implements Closeable, Iterator<String> {
if (charsetName == null) {
throw new IllegalArgumentException("charsetName == null");
}
+
+ InputStreamReader streamReader;
try {
- setInput(new InputStreamReader(fis, charsetName));
+ streamReader = new InputStreamReader(fis, charsetName);
} catch (UnsupportedEncodingException e) {
IoUtils.closeQuietly(fis);
throw new IllegalArgumentException(e.getMessage());
}
+ initialize(streamReader);
}
/**
@@ -174,7 +177,7 @@ public final class Scanner implements Closeable, Iterator<String> {
* the string to be scanned.
*/
public Scanner(String src) {
- setInput(new StringReader(src));
+ initialize(new StringReader(src));
}
/**
@@ -203,11 +206,14 @@ public final class Scanner implements Closeable, Iterator<String> {
if (src == null) {
throw new NullPointerException("src == null");
}
+
+ InputStreamReader streamReader;
try {
- setInput(new InputStreamReader(src, charsetName));
+ streamReader = new InputStreamReader(src, charsetName);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e.getMessage());
}
+ initialize(streamReader);
}
/**
@@ -220,7 +226,7 @@ public final class Scanner implements Closeable, Iterator<String> {
if (src == null) {
throw new NullPointerException("src == null");
}
- setInput(src);
+ initialize(src);
}
/**
@@ -252,13 +258,14 @@ public final class Scanner implements Closeable, Iterator<String> {
if (charsetName == null) {
throw new IllegalArgumentException("charsetName == null");
}
- setInput(Channels.newReader(src, charsetName));
+ initialize(Channels.newReader(src, charsetName));
}
- private void setInput(Readable input) {
+ private void initialize(Readable input) {
this.input = input;
- buffer.limit(0);
- matcher = delimiter.matcher(buffer);
+ matcher = delimiter.matcher("");
+ matcher.useTransparentBounds(true);
+ matcher.useAnchoringBounds(false);
}
/**
@@ -535,7 +542,7 @@ public final class Scanner implements Closeable, Iterator<String> {
checkOpen();
checkNotNull(pattern);
matchSuccessful = false;
- saveCurrentStatus();
+ prepareForScan();
// if the next token exists, set the match region, otherwise return
// false
if (!setTokenRegion()) {
@@ -790,7 +797,7 @@ public final class Scanner implements Closeable, Iterator<String> {
* @throws IllegalStateException if this {@code Scanner} is closed.
*/
public boolean hasNextLine() {
- saveCurrentStatus();
+ prepareForScan();
String result = findWithinHorizon(LINE_PATTERN, 0);
recoverPreviousStatus();
return result != null;
@@ -954,7 +961,7 @@ public final class Scanner implements Closeable, Iterator<String> {
checkOpen();
checkNotNull(pattern);
matchSuccessful = false;
- saveCurrentStatus();
+ prepareForScan();
if (!setTokenRegion()) {
recoverPreviousStatus();
// if setting match region fails
@@ -1204,7 +1211,7 @@ public final class Scanner implements Closeable, Iterator<String> {
Pattern floatPattern = getFloatPattern();
String floatString = next(floatPattern);
floatString = removeLocaleInfoFromFloat(floatString);
- double doubleValue = 0;
+ double doubleValue;
try {
doubleValue = Double.parseDouble(floatString);
} catch (NumberFormatException e) {
@@ -1248,7 +1255,7 @@ public final class Scanner implements Closeable, Iterator<String> {
Pattern floatPattern = getFloatPattern();
String floatString = next(floatPattern);
floatString = removeLocaleInfoFromFloat(floatString);
- float floatValue = 0;
+ float floatValue;
try {
floatValue = Float.parseFloat(floatString);
} catch (NumberFormatException e) {
@@ -1310,7 +1317,7 @@ public final class Scanner implements Closeable, Iterator<String> {
Pattern integerPattern = getIntegerPattern(radix);
String intString = next(integerPattern);
intString = removeLocaleInfo(intString, int.class);
- int intValue = 0;
+ int intValue;
try {
intValue = Integer.parseInt(intString, radix);
} catch (NumberFormatException e) {
@@ -1340,7 +1347,7 @@ public final class Scanner implements Closeable, Iterator<String> {
matcher.usePattern(LINE_PATTERN);
matcher.region(findStartIndex, bufferLength);
- String result = null;
+ String result;
while (true) {
if (matcher.find()) {
if (inputExhausted || matcher.end() != bufferLength
@@ -1422,7 +1429,7 @@ public final class Scanner implements Closeable, Iterator<String> {
Pattern integerPattern = getIntegerPattern(radix);
String intString = next(integerPattern);
intString = removeLocaleInfo(intString, int.class);
- long longValue = 0;
+ long longValue;
try {
longValue = Long.parseLong(intString, radix);
} catch (NumberFormatException e) {
@@ -1484,7 +1491,7 @@ public final class Scanner implements Closeable, Iterator<String> {
Pattern integerPattern = getIntegerPattern(radix);
String intString = next(integerPattern);
intString = removeLocaleInfo(intString, int.class);
- short shortValue = 0;
+ short shortValue;
try {
shortValue = Short.parseShort(intString, radix);
} catch (NumberFormatException e) {
@@ -1662,23 +1669,46 @@ public final class Scanner implements Closeable, Iterator<String> {
}
/*
- * Change the matcher's string after reading input
+ * Change the matcher's input after modifying the contents of the buffer.
+ * The current implementation of Matcher causes a copy of the buffer to be taken.
*/
private void resetMatcher() {
- if (matcher == null) {
- matcher = delimiter.matcher(buffer);
- } else {
- matcher.reset(buffer);
- }
- matcher.useTransparentBounds(true);
- matcher.useAnchoringBounds(false);
+ matcher.reset(buffer);
matcher.region(findStartIndex, bufferLength);
}
/*
- * Save the matcher's last find position
- */
- private void saveCurrentStatus() {
+ * Recover buffer space for characters that are already processed and save the matcher's state
+ * in case parsing fails. See recoverPrevousState. This method must be called before
+ * any buffer offsets are calculated.
+ */
+ private void prepareForScan() {
+ // Compacting the buffer recovers space taken by already processed characters. This does not
+ // prevent the buffer growing in all situations but keeps the buffer small when delimiters
+ // exist regularly.
+ if (findStartIndex >= buffer.capacity() / 2) {
+ // When over half the buffer is filled with characters no longer being considered by the
+ // scanner we take the cost of compacting the buffer.
+
+ // Move all characters from [findStartIndex, findStartIndex + remaining()) to
+ // [0, remaining()).
+ int oldPosition = buffer.position();
+ buffer.position(findStartIndex);
+ buffer.compact();
+ buffer.position(oldPosition);
+
+ // Update Scanner state to reflect the new buffer state.
+ bufferLength -= findStartIndex;
+ findStartIndex = 0;
+ preStartIndex = -1;
+
+ // The matcher must also be informed that the buffer has changed because it operates on
+ // a String copy.
+ resetMatcher();
+ }
+
+ // Save the matcher's last find position so it can be returned to if the next token cannot
+ // be parsed.
preStartIndex = findStartIndex;
}
@@ -1822,7 +1852,7 @@ public final class Scanner implements Closeable, Iterator<String> {
boolean negative = removeLocaleSign(tokenBuilder);
// Remove group separator
String groupSeparator = String.valueOf(dfs.getGroupingSeparator());
- int separatorIndex = -1;
+ int separatorIndex;
while ((separatorIndex = tokenBuilder.indexOf(groupSeparator)) != -1) {
tokenBuilder.delete(separatorIndex, separatorIndex + 1);
}
@@ -1909,9 +1939,9 @@ public final class Scanner implements Closeable, Iterator<String> {
*/
private boolean setTokenRegion() {
// The position where token begins
- int tokenStartIndex = 0;
+ int tokenStartIndex;
// The position where token ends
- int tokenEndIndex = 0;
+ int tokenEndIndex;
// Use delimiter pattern
matcher.usePattern(delimiter);
matcher.region(findStartIndex, bufferLength);
@@ -1945,8 +1975,7 @@ public final class Scanner implements Closeable, Iterator<String> {
if (matcher.find()) {
findComplete = true;
// If just delimiter remains
- if (matcher.start() == findStartIndex
- && matcher.end() == bufferLength) {
+ if (matcher.start() == findStartIndex && matcher.end() == bufferLength) {
// If more input resource exists
if (!inputExhausted) {
readMore();
@@ -1964,7 +1993,7 @@ public final class Scanner implements Closeable, Iterator<String> {
}
}
tokenStartIndex = matcher.end();
- findStartIndex = matcher.end();
+ findStartIndex = tokenStartIndex;
return tokenStartIndex;
}
@@ -1984,7 +2013,7 @@ public final class Scanner implements Closeable, Iterator<String> {
setSuccess = true;
}
// If the first delimiter of scanner is not at the find start position
- if (-1 != findIndex && preStartIndex != matcher.start()) {
+ if (findIndex != -1 && preStartIndex != matcher.start()) {
tokenStartIndex = preStartIndex;
tokenEndIndex = matcher.start();
findStartIndex = matcher.start();
@@ -1996,7 +2025,7 @@ public final class Scanner implements Closeable, Iterator<String> {
}
private int findDelimiterAfter() {
- int tokenEndIndex = 0;
+ int tokenEndIndex;
boolean findComplete = false;
while (!findComplete) {
if (matcher.find()) {
@@ -2014,7 +2043,7 @@ public final class Scanner implements Closeable, Iterator<String> {
}
}
tokenEndIndex = matcher.start();
- findStartIndex = matcher.start();
+ findStartIndex = tokenEndIndex;
return tokenEndIndex;
}
@@ -2032,7 +2061,7 @@ public final class Scanner implements Closeable, Iterator<String> {
}
// Read input resource
- int readCount = 0;
+ int readCount;
try {
buffer.limit(buffer.capacity());
buffer.position(oldBufferLength);
diff --git a/luni/src/main/java/java/util/TimeZone.java b/luni/src/main/java/java/util/TimeZone.java
index c024e8d..854a4a6 100644
--- a/luni/src/main/java/java/util/TimeZone.java
+++ b/luni/src/main/java/java/util/TimeZone.java
@@ -63,7 +63,7 @@ import org.apache.harmony.luni.internal.util.TimezoneGetter;
*
* @see Calendar
* @see GregorianCalendar
- * @see SimpleDateFormat
+ * @see java.text.SimpleDateFormat
*/
public abstract class TimeZone implements Serializable, Cloneable {
private static final long serialVersionUID = 3581463369166924961L;
@@ -206,27 +206,48 @@ public abstract class TimeZone implements Serializable, Cloneable {
// upgrade to icu4c 50 and rewrite the underlying native code. See also the
// "element[j] != null" check in SimpleDateFormat.parseTimeZone, and the extra work in
// DateFormatSymbols.getZoneStrings.
-
- int offset = getRawOffset();
+ int offsetMillis = getRawOffset();
if (daylightTime) {
- offset += getDSTSavings();
+ offsetMillis += getDSTSavings();
}
- offset /= 60000;
+ return createGmtOffsetString(true /* includeGmt */, true /* includeMinuteSeparator */,
+ offsetMillis);
+ }
+
+ /**
+ * Returns a string representation of an offset from UTC.
+ *
+ * <p>The format is "[GMT](+|-)HH[:]MM". The output is not localized.
+ *
+ * @param includeGmt true to include "GMT", false to exclude
+ * @param includeMinuteSeparator true to include the separator between hours and minutes, false
+ * to exclude.
+ * @param offsetMillis the offset from UTC
+ *
+ * @hide used internally by SimpleDateFormat
+ */
+ public static String createGmtOffsetString(boolean includeGmt,
+ boolean includeMinuteSeparator, int offsetMillis) {
+ int offsetMinutes = offsetMillis / 60000;
char sign = '+';
- if (offset < 0) {
+ if (offsetMinutes < 0) {
sign = '-';
- offset = -offset;
+ offsetMinutes = -offsetMinutes;
}
StringBuilder builder = new StringBuilder(9);
- builder.append("GMT");
+ if (includeGmt) {
+ builder.append("GMT");
+ }
builder.append(sign);
- appendNumber(builder, 2, offset / 60);
- builder.append(':');
- appendNumber(builder, 2, offset % 60);
+ appendNumber(builder, 2, offsetMinutes / 60);
+ if (includeMinuteSeparator) {
+ builder.append(':');
+ }
+ appendNumber(builder, 2, offsetMinutes % 60);
return builder.toString();
}
- private void appendNumber(StringBuilder builder, int count, int value) {
+ private static void appendNumber(StringBuilder builder, int count, int value) {
String string = Integer.toString(value);
for (int i = 0; i < count - string.length(); i++) {
builder.append('0');
@@ -329,7 +350,6 @@ public abstract class TimeZone implements Serializable, Cloneable {
}
// Special cases? These can clone an existing instance.
- // TODO: should we just add a cache to ZoneInfoDB instead?
if (id.length() == 3) {
if (id.equals("GMT")) {
return (TimeZone) GMT.clone();
diff --git a/luni/src/main/java/java/util/Timer.java b/luni/src/main/java/java/util/Timer.java
index 25ac432..7192f9b 100644
--- a/luni/src/main/java/java/util/Timer.java
+++ b/luni/src/main/java/java/util/Timer.java
@@ -356,9 +356,7 @@ public class Timer {
* Creates a new named {@code Timer} which may be specified to be run as a
* daemon thread.
*
- * @param name the name of the {@code Timer}.
- * @param isDaemon true if {@code Timer}'s thread should be a daemon thread.
- * @throws NullPointerException is {@code name} is {@code null}
+ * @throws NullPointerException if {@code name == null}
*/
public Timer(String name, boolean isDaemon) {
if (name == null) {
@@ -371,8 +369,7 @@ public class Timer {
/**
* Creates a new named {@code Timer} which does not run as a daemon thread.
*
- * @param name the name of the Timer.
- * @throws NullPointerException is {@code name} is {@code null}
+ * @throws NullPointerException if {@code name == null}
*/
public Timer(String name) {
this(name, false);
diff --git a/luni/src/main/java/java/util/TreeSet.java b/luni/src/main/java/java/util/TreeSet.java
index 502329e..791ffa6 100644
--- a/luni/src/main/java/java/util/TreeSet.java
+++ b/luni/src/main/java/java/util/TreeSet.java
@@ -258,7 +258,7 @@ public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>,
/**
* Returns the first element in this set.
- * @exception NoSuchElementException when this TreeSet is empty
+ * @throws NoSuchElementException when this TreeSet is empty
*/
public E first() {
return backingMap.firstKey();
@@ -266,7 +266,7 @@ public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>,
/**
* Returns the last element in this set.
- * @exception NoSuchElementException when this TreeSet is empty
+ * @throws NoSuchElementException when this TreeSet is empty
*/
public E last() {
return backingMap.lastKey();
@@ -413,10 +413,10 @@ public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>,
* @return a subset where the elements are greater or equal to
* <code>start</code> and less than <code>end</code>
*
- * @exception ClassCastException
+ * @throws ClassCastException
* when the start or end object cannot be compared with the
* elements in this TreeSet
- * @exception NullPointerException
+ * @throws NullPointerException
* when the start or end object is null and the comparator
* cannot handle null
*/
@@ -434,10 +434,10 @@ public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>,
* the end element
* @return a subset where the elements are less than <code>end</code>
*
- * @exception ClassCastException
+ * @throws ClassCastException
* when the end object cannot be compared with the elements
* in this TreeSet
- * @exception NullPointerException
+ * @throws NullPointerException
* when the end object is null and the comparator cannot
* handle null
*/
@@ -457,10 +457,10 @@ public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>,
* @return a subset where the elements are greater or equal to
* <code>start</code>
*
- * @exception ClassCastException
+ * @throws ClassCastException
* when the start object cannot be compared with the elements
* in this TreeSet
- * @exception NullPointerException
+ * @throws NullPointerException
* when the start object is null and the comparator cannot
* handle null
*/
diff --git a/luni/src/main/java/java/util/UUID.java b/luni/src/main/java/java/util/UUID.java
index 3594d87..020ac95 100644
--- a/luni/src/main/java/java/util/UUID.java
+++ b/luni/src/main/java/java/util/UUID.java
@@ -182,28 +182,17 @@ public final class UUID implements Serializable, Comparable<UUID> {
throw new NullPointerException("uuid == null");
}
- int[] position = new int[5];
- int lastPosition = 1;
- int startPosition = 0;
-
- int i = 0;
- for (; i < position.length && lastPosition > 0; i++) {
- position[i] = uuid.indexOf("-", startPosition);
- lastPosition = position[i];
- startPosition = position[i] + 1;
- }
-
- // should have and only can have four "-" in UUID
- if (i != position.length || lastPosition != -1) {
+ String[] parts = uuid.split("-");
+ if (parts.length != 5) {
throw new IllegalArgumentException("Invalid UUID: " + uuid);
}
- long m1 = Long.parseLong(uuid.substring(0, position[0]), 16);
- long m2 = Long.parseLong(uuid.substring(position[0] + 1, position[1]), 16);
- long m3 = Long.parseLong(uuid.substring(position[1] + 1, position[2]), 16);
+ long m1 = Long.parsePositiveLong(parts[0], 16);
+ long m2 = Long.parsePositiveLong(parts[1], 16);
+ long m3 = Long.parsePositiveLong(parts[2], 16);
- long lsb1 = Long.parseLong(uuid.substring(position[2] + 1, position[3]), 16);
- long lsb2 = Long.parseLong(uuid.substring(position[3] + 1), 16);
+ long lsb1 = Long.parsePositiveLong(parts[3], 16);
+ long lsb2 = Long.parsePositiveLong(parts[4], 16);
long msb = (m1 << 32) | (m2 << 16) | m3;
long lsb = (lsb1 << 48) | lsb2;
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
index c85a5cc..ea3b1e9 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
@@ -5,865 +5,729 @@
*/
package java.util.concurrent;
-import java.util.concurrent.locks.*;
-import java.util.*;
+
+import java.io.ObjectStreamField;
import java.io.Serializable;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.LockSupport;
+import java.util.concurrent.locks.ReentrantLock;
// BEGIN android-note
// removed link to collections framework docs
+// removed links to hidden api
// END android-note
/**
* A hash table supporting full concurrency of retrievals and
- * adjustable expected concurrency for updates. This class obeys the
+ * high expected concurrency for updates. This class obeys the
* same functional specification as {@link java.util.Hashtable}, and
* includes versions of methods corresponding to each method of
- * <tt>Hashtable</tt>. However, even though all operations are
+ * {@code Hashtable}. However, even though all operations are
* thread-safe, retrieval operations do <em>not</em> entail locking,
* and there is <em>not</em> any support for locking the entire table
* in a way that prevents all access. This class is fully
- * interoperable with <tt>Hashtable</tt> in programs that rely on its
+ * interoperable with {@code Hashtable} in programs that rely on its
* thread safety but not on its synchronization details.
*
- * <p> Retrieval operations (including <tt>get</tt>) generally do not
- * block, so may overlap with update operations (including
- * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results
- * of the most recently <em>completed</em> update operations holding
- * upon their onset. For aggregate operations such as <tt>putAll</tt>
- * and <tt>clear</tt>, concurrent retrievals may reflect insertion or
- * removal of only some entries. Similarly, Iterators and
- * Enumerations return elements reflecting the state of the hash table
- * at some point at or since the creation of the iterator/enumeration.
- * They do <em>not</em> throw {@link ConcurrentModificationException}.
- * However, iterators are designed to be used by only one thread at a time.
+ * <p>Retrieval operations (including {@code get}) generally do not
+ * block, so may overlap with update operations (including {@code put}
+ * and {@code remove}). Retrievals reflect the results of the most
+ * recently <em>completed</em> update operations holding upon their
+ * onset. (More formally, an update operation for a given key bears a
+ * <em>happens-before</em> relation with any (non-null) retrieval for
+ * that key reporting the updated value.) For aggregate operations
+ * such as {@code putAll} and {@code clear}, concurrent retrievals may
+ * reflect insertion or removal of only some entries. Similarly,
+ * Iterators and Enumerations return elements reflecting the state of
+ * the hash table at some point at or since the creation of the
+ * iterator/enumeration. They do <em>not</em> throw {@link
+ * ConcurrentModificationException}. However, iterators are designed
+ * to be used by only one thread at a time. Bear in mind that the
+ * results of aggregate status methods including {@code size}, {@code
+ * isEmpty}, and {@code containsValue} are typically useful only when
+ * a map is not undergoing concurrent updates in other threads.
+ * Otherwise the results of these methods reflect transient states
+ * that may be adequate for monitoring or estimation purposes, but not
+ * for program control.
*
- * <p> The allowed concurrency among update operations is guided by
- * the optional <tt>concurrencyLevel</tt> constructor argument
- * (default <tt>16</tt>), which is used as a hint for internal sizing. The
- * table is internally partitioned to try to permit the indicated
- * number of concurrent updates without contention. Because placement
- * in hash tables is essentially random, the actual concurrency will
- * vary. Ideally, you should choose a value to accommodate as many
- * threads as will ever concurrently modify the table. Using a
- * significantly higher value than you need can waste space and time,
- * and a significantly lower value can lead to thread contention. But
- * overestimates and underestimates within an order of magnitude do
- * not usually have much noticeable impact. A value of one is
- * appropriate when it is known that only one thread will modify and
- * all others will only read. Also, resizing this or any other kind of
- * hash table is a relatively slow operation, so, when possible, it is
- * a good idea to provide estimates of expected table sizes in
- * constructors.
+ * <p>The table is dynamically expanded when there are too many
+ * collisions (i.e., keys that have distinct hash codes but fall into
+ * the same slot modulo the table size), with the expected average
+ * effect of maintaining roughly two bins per mapping (corresponding
+ * to a 0.75 load factor threshold for resizing). There may be much
+ * variance around this average as mappings are added and removed, but
+ * overall, this maintains a commonly accepted time/space tradeoff for
+ * hash tables. However, resizing this or any other kind of hash
+ * table may be a relatively slow operation. When possible, it is a
+ * good idea to provide a size estimate as an optional {@code
+ * initialCapacity} constructor argument. An additional optional
+ * {@code loadFactor} constructor argument provides a further means of
+ * customizing initial table capacity by specifying the table density
+ * to be used in calculating the amount of space to allocate for the
+ * given number of elements. Also, for compatibility with previous
+ * versions of this class, constructors may optionally specify an
+ * expected {@code concurrencyLevel} as an additional hint for
+ * internal sizing. Note that using many keys with exactly the same
+ * {@code hashCode()} is a sure way to slow down performance of any
+ * hash table. To ameliorate impact, when keys are {@link Comparable},
+ * this class may use comparison order among keys to help break ties.
*
* <p>This class and its views and iterators implement all of the
* <em>optional</em> methods of the {@link Map} and {@link Iterator}
* interfaces.
*
- * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class
- * does <em>not</em> allow <tt>null</tt> to be used as a key or value.
+ * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class
+ * does <em>not</em> allow {@code null} to be used as a key or value.
*
* @since 1.5
* @author Doug Lea
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
*/
-public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
- implements ConcurrentMap<K, V>, Serializable {
+public class ConcurrentHashMap<K,V> extends java.util.AbstractMap<K,V>
+ implements ConcurrentMap<K,V>, Serializable {
private static final long serialVersionUID = 7249069246763182397L;
/*
- * The basic strategy is to subdivide the table among Segments,
- * each of which itself is a concurrently readable hash table. To
- * reduce footprint, all but one segments are constructed only
- * when first needed (see ensureSegment). To maintain visibility
- * in the presence of lazy construction, accesses to segments as
- * well as elements of segment's table must use volatile access,
- * which is done via Unsafe within methods segmentAt etc
- * below. These provide the functionality of AtomicReferenceArrays
- * but reduce the levels of indirection. Additionally,
- * volatile-writes of table elements and entry "next" fields
- * within locked operations use the cheaper "lazySet" forms of
- * writes (via putOrderedObject) because these writes are always
- * followed by lock releases that maintain sequential consistency
- * of table updates.
- *
- * Historical note: The previous version of this class relied
- * heavily on "final" fields, which avoided some volatile reads at
- * the expense of a large initial footprint. Some remnants of
- * that design (including forced construction of segment 0) exist
- * to ensure serialization compatibility.
+ * Overview:
+ *
+ * The primary design goal of this hash table is to maintain
+ * concurrent readability (typically method get(), but also
+ * iterators and related methods) while minimizing update
+ * contention. Secondary goals are to keep space consumption about
+ * the same or better than java.util.HashMap, and to support high
+ * initial insertion rates on an empty table by many threads.
+ *
+ * This map usually acts as a binned (bucketed) hash table. Each
+ * key-value mapping is held in a Node. Most nodes are instances
+ * of the basic Node class with hash, key, value, and next
+ * fields. However, various subclasses exist: TreeNodes are
+ * arranged in balanced trees, not lists. TreeBins hold the roots
+ * of sets of TreeNodes. ForwardingNodes are placed at the heads
+ * of bins during resizing. ReservationNodes are used as
+ * placeholders while establishing values in computeIfAbsent and
+ * related methods. The types TreeBin, ForwardingNode, and
+ * ReservationNode do not hold normal user keys, values, or
+ * hashes, and are readily distinguishable during search etc
+ * because they have negative hash fields and null key and value
+ * fields. (These special nodes are either uncommon or transient,
+ * so the impact of carrying around some unused fields is
+ * insignificant.)
+ *
+ * The table is lazily initialized to a power-of-two size upon the
+ * first insertion. Each bin in the table normally contains a
+ * list of Nodes (most often, the list has only zero or one Node).
+ * Table accesses require volatile/atomic reads, writes, and
+ * CASes. Because there is no other way to arrange this without
+ * adding further indirections, we use intrinsics
+ * (sun.misc.Unsafe) operations.
+ *
+ * We use the top (sign) bit of Node hash fields for control
+ * purposes -- it is available anyway because of addressing
+ * constraints. Nodes with negative hash fields are specially
+ * handled or ignored in map methods.
+ *
+ * Insertion (via put or its variants) of the first node in an
+ * empty bin is performed by just CASing it to the bin. This is
+ * by far the most common case for put operations under most
+ * key/hash distributions. Other update operations (insert,
+ * delete, and replace) require locks. We do not want to waste
+ * the space required to associate a distinct lock object with
+ * each bin, so instead use the first node of a bin list itself as
+ * a lock. Locking support for these locks relies on builtin
+ * "synchronized" monitors.
+ *
+ * Using the first node of a list as a lock does not by itself
+ * suffice though: When a node is locked, any update must first
+ * validate that it is still the first node after locking it, and
+ * retry if not. Because new nodes are always appended to lists,
+ * once a node is first in a bin, it remains first until deleted
+ * or the bin becomes invalidated (upon resizing).
+ *
+ * The main disadvantage of per-bin locks is that other update
+ * operations on other nodes in a bin list protected by the same
+ * lock can stall, for example when user equals() or mapping
+ * functions take a long time. However, statistically, under
+ * random hash codes, this is not a common problem. Ideally, the
+ * frequency of nodes in bins follows a Poisson distribution
+ * (http://en.wikipedia.org/wiki/Poisson_distribution) with a
+ * parameter of about 0.5 on average, given the resizing threshold
+ * of 0.75, although with a large variance because of resizing
+ * granularity. Ignoring variance, the expected occurrences of
+ * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The
+ * first values are:
+ *
+ * 0: 0.60653066
+ * 1: 0.30326533
+ * 2: 0.07581633
+ * 3: 0.01263606
+ * 4: 0.00157952
+ * 5: 0.00015795
+ * 6: 0.00001316
+ * 7: 0.00000094
+ * 8: 0.00000006
+ * more: less than 1 in ten million
+ *
+ * Lock contention probability for two threads accessing distinct
+ * elements is roughly 1 / (8 * #elements) under random hashes.
+ *
+ * Actual hash code distributions encountered in practice
+ * sometimes deviate significantly from uniform randomness. This
+ * includes the case when N > (1<<30), so some keys MUST collide.
+ * Similarly for dumb or hostile usages in which multiple keys are
+ * designed to have identical hash codes or ones that differs only
+ * in masked-out high bits. So we use a secondary strategy that
+ * applies when the number of nodes in a bin exceeds a
+ * threshold. These TreeBins use a balanced tree to hold nodes (a
+ * specialized form of red-black trees), bounding search time to
+ * O(log N). Each search step in a TreeBin is at least twice as
+ * slow as in a regular list, but given that N cannot exceed
+ * (1<<64) (before running out of addresses) this bounds search
+ * steps, lock hold times, etc, to reasonable constants (roughly
+ * 100 nodes inspected per operation worst case) so long as keys
+ * are Comparable (which is very common -- String, Long, etc).
+ * TreeBin nodes (TreeNodes) also maintain the same "next"
+ * traversal pointers as regular nodes, so can be traversed in
+ * iterators in the same way.
+ *
+ * The table is resized when occupancy exceeds a percentage
+ * threshold (nominally, 0.75, but see below). Any thread
+ * noticing an overfull bin may assist in resizing after the
+ * initiating thread allocates and sets up the replacement
+ * array. However, rather than stalling, these other threads may
+ * proceed with insertions etc. The use of TreeBins shields us
+ * from the worst case effects of overfilling while resizes are in
+ * progress. Resizing proceeds by transferring bins, one by one,
+ * from the table to the next table. To enable concurrency, the
+ * next table must be (incrementally) prefilled with place-holders
+ * serving as reverse forwarders to the old table. Because we are
+ * using power-of-two expansion, the elements from each bin must
+ * either stay at same index, or move with a power of two
+ * offset. We eliminate unnecessary node creation by catching
+ * cases where old nodes can be reused because their next fields
+ * won't change. On average, only about one-sixth of them need
+ * cloning when a table doubles. The nodes they replace will be
+ * garbage collectable as soon as they are no longer referenced by
+ * any reader thread that may be in the midst of concurrently
+ * traversing table. Upon transfer, the old table bin contains
+ * only a special forwarding node (with hash field "MOVED") that
+ * contains the next table as its key. On encountering a
+ * forwarding node, access and update operations restart, using
+ * the new table.
+ *
+ * Each bin transfer requires its bin lock, which can stall
+ * waiting for locks while resizing. However, because other
+ * threads can join in and help resize rather than contend for
+ * locks, average aggregate waits become shorter as resizing
+ * progresses. The transfer operation must also ensure that all
+ * accessible bins in both the old and new table are usable by any
+ * traversal. This is arranged by proceeding from the last bin
+ * (table.length - 1) up towards the first. Upon seeing a
+ * forwarding node, traversals (see class Traverser) arrange to
+ * move to the new table without revisiting nodes. However, to
+ * ensure that no intervening nodes are skipped, bin splitting can
+ * only begin after the associated reverse-forwarders are in
+ * place.
+ *
+ * The traversal scheme also applies to partial traversals of
+ * ranges of bins (via an alternate Traverser constructor)
+ * to support partitioned aggregate operations. Also, read-only
+ * operations give up if ever forwarded to a null table, which
+ * provides support for shutdown-style clearing, which is also not
+ * currently implemented.
+ *
+ * Lazy table initialization minimizes footprint until first use,
+ * and also avoids resizings when the first operation is from a
+ * putAll, constructor with map argument, or deserialization.
+ * These cases attempt to override the initial capacity settings,
+ * but harmlessly fail to take effect in cases of races.
+ *
+ * The element count is maintained using a specialization of
+ * LongAdder. We need to incorporate a specialization rather than
+ * just use a LongAdder in order to access implicit
+ * contention-sensing that leads to creation of multiple
+ * CounterCells. The counter mechanics avoid contention on
+ * updates but can encounter cache thrashing if read too
+ * frequently during concurrent access. To avoid reading so often,
+ * resizing under contention is attempted only upon adding to a
+ * bin already holding two or more nodes. Under uniform hash
+ * distributions, the probability of this occurring at threshold
+ * is around 13%, meaning that only about 1 in 8 puts check
+ * threshold (and after resizing, many fewer do so).
+ *
+ * TreeBins use a special form of comparison for search and
+ * related operations (which is the main reason we cannot use
+ * existing collections such as TreeMaps). TreeBins contain
+ * Comparable elements, but may contain others, as well as
+ * elements that are Comparable but not necessarily Comparable
+ * for the same T, so we cannot invoke compareTo among them. To
+ * handle this, the tree is ordered primarily by hash value, then
+ * by Comparable.compareTo order if applicable. On lookup at a
+ * node, if elements are not comparable or compare as 0 then both
+ * left and right children may need to be searched in the case of
+ * tied hash values. (This corresponds to the full list search
+ * that would be necessary if all elements were non-Comparable and
+ * had tied hashes.) The red-black balancing code is updated from
+ * pre-jdk-collections
+ * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java)
+ * based in turn on Cormen, Leiserson, and Rivest "Introduction to
+ * Algorithms" (CLR).
+ *
+ * TreeBins also require an additional locking mechanism. While
+ * list traversal is always possible by readers even during
+ * updates, tree traversal is not, mainly because of tree-rotations
+ * that may change the root node and/or its linkages. TreeBins
+ * include a simple read-write lock mechanism parasitic on the
+ * main bin-synchronization strategy: Structural adjustments
+ * associated with an insertion or removal are already bin-locked
+ * (and so cannot conflict with other writers) but must wait for
+ * ongoing readers to finish. Since there can be only one such
+ * waiter, we use a simple scheme using a single "waiter" field to
+ * block writers. However, readers need never block. If the root
+ * lock is held, they proceed along the slow traversal path (via
+ * next-pointers) until the lock becomes available or the list is
+ * exhausted, whichever comes first. These cases are not fast, but
+ * maximize aggregate expected throughput.
+ *
+ * Maintaining API and serialization compatibility with previous
+ * versions of this class introduces several oddities. Mainly: We
+ * leave untouched but unused constructor arguments refering to
+ * concurrencyLevel. We accept a loadFactor constructor argument,
+ * but apply it only to initial table capacity (which is the only
+ * time that we can guarantee to honor it.) We also declare an
+ * unused "Segment" class that is instantiated in minimal form
+ * only when serializing.
+ *
+ * This file is organized to make things a little easier to follow
+ * while reading than they might otherwise: First the main static
+ * declarations and utilities, then fields, then main public
+ * methods (with a few factorings of multiple public methods into
+ * internal ones), then sizing methods, trees, traversers, and
+ * bulk operations.
*/
/* ---------------- Constants -------------- */
/**
- * The default initial capacity for this table,
- * used when not otherwise specified in a constructor.
+ * The largest possible table capacity. This value must be
+ * exactly 1<<30 to stay within Java array allocation and indexing
+ * bounds for power of two table sizes, and is further required
+ * because the top two bits of 32bit hash fields are used for
+ * control purposes.
*/
- static final int DEFAULT_INITIAL_CAPACITY = 16;
+ private static final int MAXIMUM_CAPACITY = 1 << 30;
/**
- * The default load factor for this table, used when not
- * otherwise specified in a constructor.
+ * The default initial table capacity. Must be a power of 2
+ * (i.e., at least 1) and at most MAXIMUM_CAPACITY.
*/
- static final float DEFAULT_LOAD_FACTOR = 0.75f;
+ private static final int DEFAULT_CAPACITY = 16;
/**
- * The default concurrency level for this table, used when not
- * otherwise specified in a constructor.
+ * The largest possible (non-power of two) array size.
+ * Needed by toArray and related methods.
*/
- static final int DEFAULT_CONCURRENCY_LEVEL = 16;
+ static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
- * The maximum capacity, used if a higher value is implicitly
- * specified by either of the constructors with arguments. MUST
- * be a power of two <= 1<<30 to ensure that entries are indexable
- * using ints.
+ * The default concurrency level for this table. Unused but
+ * defined for compatibility with previous versions of this class.
*/
- static final int MAXIMUM_CAPACITY = 1 << 30;
+ private static final int DEFAULT_CONCURRENCY_LEVEL = 16;
/**
- * The minimum capacity for per-segment tables. Must be a power
- * of two, at least two to avoid immediate resizing on next use
- * after lazy construction.
+ * The load factor for this table. Overrides of this value in
+ * constructors affect only the initial table capacity. The
+ * actual floating point value isn't normally used -- it is
+ * simpler to use expressions such as {@code n - (n >>> 2)} for
+ * the associated resizing threshold.
*/
- static final int MIN_SEGMENT_TABLE_CAPACITY = 2;
+ private static final float LOAD_FACTOR = 0.75f;
/**
- * The maximum number of segments to allow; used to bound
- * constructor arguments. Must be power of two less than 1 << 24.
+ * The bin count threshold for using a tree rather than list for a
+ * bin. Bins are converted to trees when adding an element to a
+ * bin with at least this many nodes. The value must be greater
+ * than 2, and should be at least 8 to mesh with assumptions in
+ * tree removal about conversion back to plain bins upon
+ * shrinkage.
*/
- static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
+ static final int TREEIFY_THRESHOLD = 8;
/**
- * Number of unsynchronized retries in size and containsValue
- * methods before resorting to locking. This is used to avoid
- * unbounded retries if tables undergo continuous modification
- * which would make it impossible to obtain an accurate result.
+ * The bin count threshold for untreeifying a (split) bin during a
+ * resize operation. Should be less than TREEIFY_THRESHOLD, and at
+ * most 6 to mesh with shrinkage detection under removal.
*/
- static final int RETRIES_BEFORE_LOCK = 2;
-
- /* ---------------- Fields -------------- */
+ static final int UNTREEIFY_THRESHOLD = 6;
/**
- * Mask value for indexing into segments. The upper bits of a
- * key's hash code are used to choose the segment.
+ * The smallest table capacity for which bins may be treeified.
+ * (Otherwise the table is resized if too many nodes in a bin.)
+ * The value should be at least 4 * TREEIFY_THRESHOLD to avoid
+ * conflicts between resizing and treeification thresholds.
*/
- final int segmentMask;
+ static final int MIN_TREEIFY_CAPACITY = 64;
/**
- * Shift value for indexing within segments.
+ * Minimum number of rebinnings per transfer step. Ranges are
+ * subdivided to allow multiple resizer threads. This value
+ * serves as a lower bound to avoid resizers encountering
+ * excessive memory contention. The value should be at least
+ * DEFAULT_CAPACITY.
*/
- final int segmentShift;
+ private static final int MIN_TRANSFER_STRIDE = 16;
- /**
- * The segments, each of which is a specialized hash table.
+ /*
+ * Encodings for Node hash fields. See above for explanation.
*/
- final Segment<K,V>[] segments;
+ static final int MOVED = 0x8fffffff; // (-1) hash for forwarding nodes
+ static final int TREEBIN = 0x80000000; // hash for roots of trees
+ static final int RESERVED = 0x80000001; // hash for transient reservations
+ static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash
+
+ /** Number of CPUS, to place bounds on some sizings */
+ static final int NCPU = Runtime.getRuntime().availableProcessors();
- transient Set<K> keySet;
- transient Set<Map.Entry<K,V>> entrySet;
- transient Collection<V> values;
+ /** For serialization compatibility. */
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("segments", Segment[].class),
+ new ObjectStreamField("segmentMask", Integer.TYPE),
+ new ObjectStreamField("segmentShift", Integer.TYPE)
+ };
+
+ /* ---------------- Nodes -------------- */
/**
- * ConcurrentHashMap list entry. Note that this is never exported
- * out as a user-visible Map.Entry.
+ * Key-value entry. This class is never exported out as a
+ * user-mutable Map.Entry (i.e., one supporting setValue; see
+ * MapEntry below), but can be used for read-only traversals used
+ * in bulk tasks. Subclasses of Node with a negative hash field
+ * are special, and contain null keys and values (but are never
+ * exported). Otherwise, keys and vals are never null.
*/
- static final class HashEntry<K,V> {
+ static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
- volatile V value;
- volatile HashEntry<K,V> next;
+ volatile V val;
+ Node<K,V> next;
- HashEntry(int hash, K key, V value, HashEntry<K,V> next) {
+ Node(int hash, K key, V val, Node<K,V> next) {
this.hash = hash;
this.key = key;
- this.value = value;
+ this.val = val;
this.next = next;
}
- /**
- * Sets next field with volatile write semantics. (See above
- * about use of putOrderedObject.)
- */
- final void setNext(HashEntry<K,V> n) {
- UNSAFE.putOrderedObject(this, nextOffset, n);
+ public final K getKey() { return key; }
+ public final V getValue() { return val; }
+ public final int hashCode() { return key.hashCode() ^ val.hashCode(); }
+ public final String toString(){ return key + "=" + val; }
+ public final V setValue(V value) {
+ throw new UnsupportedOperationException();
}
- // Unsafe mechanics
- static final sun.misc.Unsafe UNSAFE;
- static final long nextOffset;
- static {
- try {
- UNSAFE = sun.misc.Unsafe.getUnsafe();
- Class<?> k = HashEntry.class;
- nextOffset = UNSAFE.objectFieldOffset
- (k.getDeclaredField("next"));
- } catch (Exception e) {
- throw new Error(e);
+ public final boolean equals(Object o) {
+ Object k, v, u; Map.Entry<?,?> e;
+ return ((o instanceof Map.Entry) &&
+ (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+ (v = e.getValue()) != null &&
+ (k == key || k.equals(key)) &&
+ (v == (u = val) || v.equals(u)));
+ }
+
+ /**
+ * Virtualized support for map.get(); overridden in subclasses.
+ */
+ Node<K,V> find(int h, Object k) {
+ Node<K,V> e = this;
+ if (k != null) {
+ do {
+ K ek;
+ if (e.hash == h &&
+ ((ek = e.key) == k || (ek != null && k.equals(ek))))
+ return e;
+ } while ((e = e.next) != null);
}
+ return null;
}
}
+ /* ---------------- Static utilities -------------- */
+
/**
- * Gets the ith element of given table (if nonnull) with volatile
- * read semantics. Note: This is manually integrated into a few
- * performance-sensitive methods to reduce call overhead.
+ * Spreads (XORs) higher bits of hash to lower and also forces top
+ * bit to 0. Because the table uses power-of-two masking, sets of
+ * hashes that vary only in bits above the current mask will
+ * always collide. (Among known examples are sets of Float keys
+ * holding consecutive whole numbers in small tables.) So we
+ * apply a transform that spreads the impact of higher bits
+ * downward. There is a tradeoff between speed, utility, and
+ * quality of bit-spreading. Because many common sets of hashes
+ * are already reasonably distributed (so don't benefit from
+ * spreading), and because we use trees to handle large sets of
+ * collisions in bins, we just XOR some shifted bits in the
+ * cheapest possible way to reduce systematic lossage, as well as
+ * to incorporate impact of the highest bits that would otherwise
+ * never be used in index calculations because of table bounds.
*/
- @SuppressWarnings("unchecked")
- static final <K,V> HashEntry<K,V> entryAt(HashEntry<K,V>[] tab, int i) {
- return (tab == null) ? null :
- (HashEntry<K,V>) UNSAFE.getObjectVolatile
- (tab, ((long)i << TSHIFT) + TBASE);
+ static final int spread(int h) {
+ return (h ^ (h >>> 16)) & HASH_BITS;
}
/**
- * Sets the ith element of given table, with volatile write
- * semantics. (See above about use of putOrderedObject.)
+ * Returns a power of two table size for the given desired capacity.
+ * See Hackers Delight, sec 3.2
*/
- static final <K,V> void setEntryAt(HashEntry<K,V>[] tab, int i,
- HashEntry<K,V> e) {
- UNSAFE.putOrderedObject(tab, ((long)i << TSHIFT) + TBASE, e);
+ private static final int tableSizeFor(int c) {
+ int n = c - 1;
+ n |= n >>> 1;
+ n |= n >>> 2;
+ n |= n >>> 4;
+ n |= n >>> 8;
+ n |= n >>> 16;
+ return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
+
/**
- * Applies a supplemental hash function to a given hashCode, which
- * defends against poor quality hash functions. This is critical
- * because ConcurrentHashMap uses power-of-two length hash tables,
- * that otherwise encounter collisions for hashCodes that do not
- * differ in lower or upper bits.
+ * Returns x's Class if it is of the form "class C implements
+ * Comparable<C>", else null.
*/
- private static int hash(int h) {
- // Spread bits to regularize both segment and index locations,
- // using variant of single-word Wang/Jenkins hash.
- h += (h << 15) ^ 0xffffcd7d;
- h ^= (h >>> 10);
- h += (h << 3);
- h ^= (h >>> 6);
- h += (h << 2) + (h << 14);
- return h ^ (h >>> 16);
+ static Class<?> comparableClassFor(Object x) {
+ if (x instanceof Comparable) {
+ Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
+ if ((c = x.getClass()) == String.class) // bypass checks
+ return c;
+ if ((ts = c.getGenericInterfaces()) != null) {
+ for (int i = 0; i < ts.length; ++i) {
+ if (((t = ts[i]) instanceof ParameterizedType) &&
+ ((p = (ParameterizedType)t).getRawType() ==
+ Comparable.class) &&
+ (as = p.getActualTypeArguments()) != null &&
+ as.length == 1 && as[0] == c) // type arg is c
+ return c;
+ }
+ }
+ }
+ return null;
}
/**
- * Segments are specialized versions of hash tables. This
- * subclasses from ReentrantLock opportunistically, just to
- * simplify some locking and avoid separate construction.
+ * Returns k.compareTo(x) if x matches kc (k's screened comparable
+ * class), else 0.
*/
- static final class Segment<K,V> extends ReentrantLock implements Serializable {
- /*
- * Segments maintain a table of entry lists that are always
- * kept in a consistent state, so can be read (via volatile
- * reads of segments and tables) without locking. This
- * requires replicating nodes when necessary during table
- * resizing, so the old lists can be traversed by readers
- * still using old version of table.
- *
- * This class defines only mutative methods requiring locking.
- * Except as noted, the methods of this class perform the
- * per-segment versions of ConcurrentHashMap methods. (Other
- * methods are integrated directly into ConcurrentHashMap
- * methods.) These mutative methods use a form of controlled
- * spinning on contention via methods scanAndLock and
- * scanAndLockForPut. These intersperse tryLocks with
- * traversals to locate nodes. The main benefit is to absorb
- * cache misses (which are very common for hash tables) while
- * obtaining locks so that traversal is faster once
- * acquired. We do not actually use the found nodes since they
- * must be re-acquired under lock anyway to ensure sequential
- * consistency of updates (and in any case may be undetectably
- * stale), but they will normally be much faster to re-locate.
- * Also, scanAndLockForPut speculatively creates a fresh node
- * to use in put if no node is found.
- */
+ @SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparable
+ static int compareComparables(Class<?> kc, Object k, Object x) {
+ return (x == null || x.getClass() != kc ? 0 :
+ ((Comparable)k).compareTo(x));
+ }
- private static final long serialVersionUID = 2249069246763182397L;
+ /* ---------------- Table element access -------------- */
- /**
- * The maximum number of times to tryLock in a prescan before
- * possibly blocking on acquire in preparation for a locked
- * segment operation. On multiprocessors, using a bounded
- * number of retries maintains cache acquired while locating
- * nodes.
- */
- static final int MAX_SCAN_RETRIES =
- Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;
+ /*
+ * Volatile access methods are used for table elements as well as
+ * elements of in-progress next table while resizing. All uses of
+ * the tab arguments must be null checked by callers. All callers
+ * also paranoically precheck that tab's length is not zero (or an
+ * equivalent check), thus ensuring that any index argument taking
+ * the form of a hash value anded with (length - 1) is a valid
+ * index. Note that, to be correct wrt arbitrary concurrency
+ * errors by users, these checks must operate on local variables,
+ * which accounts for some odd-looking inline assignments below.
+ * Note that calls to setTabAt always occur within locked regions,
+ * and so do not need full volatile semantics, but still require
+ * ordering to maintain concurrent readability.
+ */
- /**
- * The per-segment table. Elements are accessed via
- * entryAt/setEntryAt providing volatile semantics.
- */
- transient volatile HashEntry<K,V>[] table;
+ @SuppressWarnings("unchecked")
+ static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
+ return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
+ }
- /**
- * The number of elements. Accessed only either within locks
- * or among other volatile reads that maintain visibility.
- */
- transient int count;
+ static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
+ Node<K,V> c, Node<K,V> v) {
+ return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
+ }
- /**
- * The total number of mutative operations in this segment.
- * Even though this may overflows 32 bits, it provides
- * sufficient accuracy for stability checks in CHM isEmpty()
- * and size() methods. Accessed only either within locks or
- * among other volatile reads that maintain visibility.
- */
- transient int modCount;
+ static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) {
+ U.putOrderedObject(tab, ((long)i << ASHIFT) + ABASE, v);
+ }
- /**
- * The table is rehashed when its size exceeds this threshold.
- * (The value of this field is always <tt>(int)(capacity *
- * loadFactor)</tt>.)
- */
- transient int threshold;
+ /* ---------------- Fields -------------- */
- /**
- * The load factor for the hash table. Even though this value
- * is same for all segments, it is replicated to avoid needing
- * links to outer object.
- * @serial
- */
- final float loadFactor;
+ /**
+ * The array of bins. Lazily initialized upon first insertion.
+ * Size is always a power of two. Accessed directly by iterators.
+ */
+ transient volatile Node<K,V>[] table;
- Segment(float lf, int threshold, HashEntry<K,V>[] tab) {
- this.loadFactor = lf;
- this.threshold = threshold;
- this.table = tab;
- }
+ /**
+ * The next table to use; non-null only while resizing.
+ */
+ private transient volatile Node<K,V>[] nextTable;
- final V put(K key, int hash, V value, boolean onlyIfAbsent) {
- HashEntry<K,V> node = tryLock() ? null :
- scanAndLockForPut(key, hash, value);
- V oldValue;
- try {
- HashEntry<K,V>[] tab = table;
- int index = (tab.length - 1) & hash;
- HashEntry<K,V> first = entryAt(tab, index);
- for (HashEntry<K,V> e = first;;) {
- if (e != null) {
- K k;
- if ((k = e.key) == key ||
- (e.hash == hash && key.equals(k))) {
- oldValue = e.value;
- if (!onlyIfAbsent) {
- e.value = value;
- ++modCount;
- }
- break;
- }
- e = e.next;
- }
- else {
- if (node != null)
- node.setNext(first);
- else
- node = new HashEntry<K,V>(hash, key, value, first);
- int c = count + 1;
- if (c > threshold && tab.length < MAXIMUM_CAPACITY)
- rehash(node);
- else
- setEntryAt(tab, index, node);
- ++modCount;
- count = c;
- oldValue = null;
- break;
- }
- }
- } finally {
- unlock();
- }
- return oldValue;
- }
+ /**
+ * Base counter value, used mainly when there is no contention,
+ * but also as a fallback during table initialization
+ * races. Updated via CAS.
+ */
+ private transient volatile long baseCount;
- /**
- * Doubles size of table and repacks entries, also adding the
- * given node to new table
- */
- @SuppressWarnings("unchecked")
- private void rehash(HashEntry<K,V> node) {
- /*
- * Reclassify nodes in each list to new table. Because we
- * are using power-of-two expansion, the elements from
- * each bin must either stay at same index, or move with a
- * power of two offset. We eliminate unnecessary node
- * creation by catching cases where old nodes can be
- * reused because their next fields won't change.
- * Statistically, at the default threshold, only about
- * one-sixth of them need cloning when a table
- * doubles. The nodes they replace will be garbage
- * collectable as soon as they are no longer referenced by
- * any reader thread that may be in the midst of
- * concurrently traversing table. Entry accesses use plain
- * array indexing because they are followed by volatile
- * table write.
- */
- HashEntry<K,V>[] oldTable = table;
- int oldCapacity = oldTable.length;
- int newCapacity = oldCapacity << 1;
- threshold = (int)(newCapacity * loadFactor);
- HashEntry<K,V>[] newTable =
- (HashEntry<K,V>[]) new HashEntry<?,?>[newCapacity];
- int sizeMask = newCapacity - 1;
- for (int i = 0; i < oldCapacity ; i++) {
- HashEntry<K,V> e = oldTable[i];
- if (e != null) {
- HashEntry<K,V> next = e.next;
- int idx = e.hash & sizeMask;
- if (next == null) // Single node on list
- newTable[idx] = e;
- else { // Reuse consecutive sequence at same slot
- HashEntry<K,V> lastRun = e;
- int lastIdx = idx;
- for (HashEntry<K,V> last = next;
- last != null;
- last = last.next) {
- int k = last.hash & sizeMask;
- if (k != lastIdx) {
- lastIdx = k;
- lastRun = last;
- }
- }
- newTable[lastIdx] = lastRun;
- // Clone remaining nodes
- for (HashEntry<K,V> p = e; p != lastRun; p = p.next) {
- V v = p.value;
- int h = p.hash;
- int k = h & sizeMask;
- HashEntry<K,V> n = newTable[k];
- newTable[k] = new HashEntry<K,V>(h, p.key, v, n);
- }
- }
- }
- }
- int nodeIndex = node.hash & sizeMask; // add the new node
- node.setNext(newTable[nodeIndex]);
- newTable[nodeIndex] = node;
- table = newTable;
- }
+ /**
+ * Table initialization and resizing control. When negative, the
+ * table is being initialized or resized: -1 for initialization,
+ * else -(1 + the number of active resizing threads). Otherwise,
+ * when table is null, holds the initial table size to use upon
+ * creation, or 0 for default. After initialization, holds the
+ * next element count value upon which to resize the table.
+ */
+ private transient volatile int sizeCtl;
- /**
- * Scans for a node containing given key while trying to
- * acquire lock, creating and returning one if not found. Upon
- * return, guarantees that lock is held. Unlike in most
- * methods, calls to method equals are not screened: Since
- * traversal speed doesn't matter, we might as well help warm
- * up the associated code and accesses as well.
- *
- * @return a new node if key not found, else null
- */
- private HashEntry<K,V> scanAndLockForPut(K key, int hash, V value) {
- HashEntry<K,V> first = entryForHash(this, hash);
- HashEntry<K,V> e = first;
- HashEntry<K,V> node = null;
- int retries = -1; // negative while locating node
- while (!tryLock()) {
- HashEntry<K,V> f; // to recheck first below
- if (retries < 0) {
- if (e == null) {
- if (node == null) // speculatively create node
- node = new HashEntry<K,V>(hash, key, value, null);
- retries = 0;
- }
- else if (key.equals(e.key))
- retries = 0;
- else
- e = e.next;
- }
- else if (++retries > MAX_SCAN_RETRIES) {
- lock();
- break;
- }
- else if ((retries & 1) == 0 &&
- (f = entryForHash(this, hash)) != first) {
- e = first = f; // re-traverse if entry changed
- retries = -1;
- }
- }
- return node;
- }
+ /**
+ * The next table index (plus one) to split while resizing.
+ */
+ private transient volatile int transferIndex;
- /**
- * Scans for a node containing the given key while trying to
- * acquire lock for a remove or replace operation. Upon
- * return, guarantees that lock is held. Note that we must
- * lock even if the key is not found, to ensure sequential
- * consistency of updates.
- */
- private void scanAndLock(Object key, int hash) {
- // similar to but simpler than scanAndLockForPut
- HashEntry<K,V> first = entryForHash(this, hash);
- HashEntry<K,V> e = first;
- int retries = -1;
- while (!tryLock()) {
- HashEntry<K,V> f;
- if (retries < 0) {
- if (e == null || key.equals(e.key))
- retries = 0;
- else
- e = e.next;
- }
- else if (++retries > MAX_SCAN_RETRIES) {
- lock();
- break;
- }
- else if ((retries & 1) == 0 &&
- (f = entryForHash(this, hash)) != first) {
- e = first = f;
- retries = -1;
- }
- }
- }
+ /**
+ * The least available table index to split while resizing.
+ */
+ private transient volatile int transferOrigin;
- /**
- * Remove; match on key only if value null, else match both.
- */
- final V remove(Object key, int hash, Object value) {
- if (!tryLock())
- scanAndLock(key, hash);
- V oldValue = null;
- try {
- HashEntry<K,V>[] tab = table;
- int index = (tab.length - 1) & hash;
- HashEntry<K,V> e = entryAt(tab, index);
- HashEntry<K,V> pred = null;
- while (e != null) {
- K k;
- HashEntry<K,V> next = e.next;
- if ((k = e.key) == key ||
- (e.hash == hash && key.equals(k))) {
- V v = e.value;
- if (value == null || value == v || value.equals(v)) {
- if (pred == null)
- setEntryAt(tab, index, next);
- else
- pred.setNext(next);
- ++modCount;
- --count;
- oldValue = v;
- }
- break;
- }
- pred = e;
- e = next;
- }
- } finally {
- unlock();
- }
- return oldValue;
- }
+ /**
+ * Spinlock (locked via CAS) used when resizing and/or creating CounterCells.
+ */
+ private transient volatile int cellsBusy;
- final boolean replace(K key, int hash, V oldValue, V newValue) {
- if (!tryLock())
- scanAndLock(key, hash);
- boolean replaced = false;
- try {
- HashEntry<K,V> e;
- for (e = entryForHash(this, hash); e != null; e = e.next) {
- K k;
- if ((k = e.key) == key ||
- (e.hash == hash && key.equals(k))) {
- if (oldValue.equals(e.value)) {
- e.value = newValue;
- ++modCount;
- replaced = true;
- }
- break;
- }
- }
- } finally {
- unlock();
- }
- return replaced;
- }
+ /**
+ * Table of counter cells. When non-null, size is a power of 2.
+ */
+ private transient volatile CounterCell[] counterCells;
- final V replace(K key, int hash, V value) {
- if (!tryLock())
- scanAndLock(key, hash);
- V oldValue = null;
- try {
- HashEntry<K,V> e;
- for (e = entryForHash(this, hash); e != null; e = e.next) {
- K k;
- if ((k = e.key) == key ||
- (e.hash == hash && key.equals(k))) {
- oldValue = e.value;
- e.value = value;
- ++modCount;
- break;
- }
- }
- } finally {
- unlock();
- }
- return oldValue;
- }
+ // views
+ private transient KeySetView<K,V> keySet;
+ private transient ValuesView<K,V> values;
+ private transient EntrySetView<K,V> entrySet;
- final void clear() {
- lock();
- try {
- HashEntry<K,V>[] tab = table;
- for (int i = 0; i < tab.length ; i++)
- setEntryAt(tab, i, null);
- ++modCount;
- count = 0;
- } finally {
- unlock();
- }
- }
- }
- // Accessing segments
+ /* ---------------- Public operations -------------- */
/**
- * Gets the jth element of given segment array (if nonnull) with
- * volatile element access semantics via Unsafe. (The null check
- * can trigger harmlessly only during deserialization.) Note:
- * because each element of segments array is set only once (using
- * fully ordered writes), some performance-sensitive methods rely
- * on this method only as a recheck upon null reads.
+ * Creates a new, empty map with the default initial table size (16).
*/
- @SuppressWarnings("unchecked")
- static final <K,V> Segment<K,V> segmentAt(Segment<K,V>[] ss, int j) {
- long u = (j << SSHIFT) + SBASE;
- return ss == null ? null :
- (Segment<K,V>) UNSAFE.getObjectVolatile(ss, u);
+ public ConcurrentHashMap() {
}
/**
- * Returns the segment for the given index, creating it and
- * recording in segment table (via CAS) if not already present.
+ * Creates a new, empty map with an initial table size
+ * accommodating the specified number of elements without the need
+ * to dynamically resize.
*
- * @param k the index
- * @return the segment
- */
- @SuppressWarnings("unchecked")
- private Segment<K,V> ensureSegment(int k) {
- final Segment<K,V>[] ss = this.segments;
- long u = (k << SSHIFT) + SBASE; // raw offset
- Segment<K,V> seg;
- if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u)) == null) {
- Segment<K,V> proto = ss[0]; // use segment 0 as prototype
- int cap = proto.table.length;
- float lf = proto.loadFactor;
- int threshold = (int)(cap * lf);
- HashEntry<K,V>[] tab = (HashEntry<K,V>[])new HashEntry<?,?>[cap];
- if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u))
- == null) { // recheck
- Segment<K,V> s = new Segment<K,V>(lf, threshold, tab);
- while ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u))
- == null) {
- if (UNSAFE.compareAndSwapObject(ss, u, null, seg = s))
- break;
- }
- }
- }
- return seg;
- }
-
- // Hash-based segment and entry accesses
-
- /**
- * Gets the segment for the given hash code.
+ * @param initialCapacity The implementation performs internal
+ * sizing to accommodate this many elements.
+ * @throws IllegalArgumentException if the initial capacity of
+ * elements is negative
*/
- @SuppressWarnings("unchecked")
- private Segment<K,V> segmentForHash(int h) {
- long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;
- return (Segment<K,V>) UNSAFE.getObjectVolatile(segments, u);
+ public ConcurrentHashMap(int initialCapacity) {
+ if (initialCapacity < 0)
+ throw new IllegalArgumentException();
+ int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
+ MAXIMUM_CAPACITY :
+ tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
+ this.sizeCtl = cap;
}
/**
- * Gets the table entry for the given segment and hash code.
+ * Creates a new map with the same mappings as the given map.
+ *
+ * @param m the map
*/
- @SuppressWarnings("unchecked")
- static final <K,V> HashEntry<K,V> entryForHash(Segment<K,V> seg, int h) {
- HashEntry<K,V>[] tab;
- return (seg == null || (tab = seg.table) == null) ? null :
- (HashEntry<K,V>) UNSAFE.getObjectVolatile
- (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE);
+ public ConcurrentHashMap(Map<? extends K, ? extends V> m) {
+ this.sizeCtl = DEFAULT_CAPACITY;
+ putAll(m);
}
- /* ---------------- Public operations -------------- */
-
/**
- * Creates a new, empty map with the specified initial
- * capacity, load factor and concurrency level.
+ * Creates a new, empty map with an initial table size based on
+ * the given number of elements ({@code initialCapacity}) and
+ * initial table density ({@code loadFactor}).
*
* @param initialCapacity the initial capacity. The implementation
- * performs internal sizing to accommodate this many elements.
- * @param loadFactor the load factor threshold, used to control resizing.
- * Resizing may be performed when the average number of elements per
- * bin exceeds this threshold.
- * @param concurrencyLevel the estimated number of concurrently
- * updating threads. The implementation performs internal sizing
- * to try to accommodate this many threads.
- * @throws IllegalArgumentException if the initial capacity is
- * negative or the load factor or concurrencyLevel are
- * nonpositive.
- */
- @SuppressWarnings("unchecked")
- public ConcurrentHashMap(int initialCapacity,
- float loadFactor, int concurrencyLevel) {
- if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)
- throw new IllegalArgumentException();
- if (concurrencyLevel > MAX_SEGMENTS)
- concurrencyLevel = MAX_SEGMENTS;
- // Find power-of-two sizes best matching arguments
- int sshift = 0;
- int ssize = 1;
- while (ssize < concurrencyLevel) {
- ++sshift;
- ssize <<= 1;
- }
- this.segmentShift = 32 - sshift;
- this.segmentMask = ssize - 1;
- if (initialCapacity > MAXIMUM_CAPACITY)
- initialCapacity = MAXIMUM_CAPACITY;
- int c = initialCapacity / ssize;
- if (c * ssize < initialCapacity)
- ++c;
- int cap = MIN_SEGMENT_TABLE_CAPACITY;
- while (cap < c)
- cap <<= 1;
- // create segments and segments[0]
- Segment<K,V> s0 =
- new Segment<K,V>(loadFactor, (int)(cap * loadFactor),
- (HashEntry<K,V>[])new HashEntry<?,?>[cap]);
- Segment<K,V>[] ss = (Segment<K,V>[])new Segment<?,?>[ssize];
- UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0]
- this.segments = ss;
- }
-
- /**
- * Creates a new, empty map with the specified initial capacity
- * and load factor and with the default concurrencyLevel (16).
- *
- * @param initialCapacity The implementation performs internal
- * sizing to accommodate this many elements.
- * @param loadFactor the load factor threshold, used to control resizing.
- * Resizing may be performed when the average number of elements per
- * bin exceeds this threshold.
+ * performs internal sizing to accommodate this many elements,
+ * given the specified load factor.
+ * @param loadFactor the load factor (table density) for
+ * establishing the initial table size
* @throws IllegalArgumentException if the initial capacity of
* elements is negative or the load factor is nonpositive
*
* @since 1.6
*/
public ConcurrentHashMap(int initialCapacity, float loadFactor) {
- this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL);
+ this(initialCapacity, loadFactor, 1);
}
/**
- * Creates a new, empty map with the specified initial capacity,
- * and with default load factor (0.75) and concurrencyLevel (16).
+ * Creates a new, empty map with an initial table size based on
+ * the given number of elements ({@code initialCapacity}), table
+ * density ({@code loadFactor}), and number of concurrently
+ * updating threads ({@code concurrencyLevel}).
*
* @param initialCapacity the initial capacity. The implementation
- * performs internal sizing to accommodate this many elements.
- * @throws IllegalArgumentException if the initial capacity of
- * elements is negative.
+ * performs internal sizing to accommodate this many elements,
+ * given the specified load factor.
+ * @param loadFactor the load factor (table density) for
+ * establishing the initial table size
+ * @param concurrencyLevel the estimated number of concurrently
+ * updating threads. The implementation may use this value as
+ * a sizing hint.
+ * @throws IllegalArgumentException if the initial capacity is
+ * negative or the load factor or concurrencyLevel are
+ * nonpositive
*/
- public ConcurrentHashMap(int initialCapacity) {
- this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
+ public ConcurrentHashMap(int initialCapacity,
+ float loadFactor, int concurrencyLevel) {
+ if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0)
+ throw new IllegalArgumentException();
+ if (initialCapacity < concurrencyLevel) // Use at least as many bins
+ initialCapacity = concurrencyLevel; // as estimated threads
+ long size = (long)(1.0 + (long)initialCapacity / loadFactor);
+ int cap = (size >= (long)MAXIMUM_CAPACITY) ?
+ MAXIMUM_CAPACITY : tableSizeFor((int)size);
+ this.sizeCtl = cap;
}
- /**
- * Creates a new, empty map with a default initial capacity (16),
- * load factor (0.75) and concurrencyLevel (16).
- */
- public ConcurrentHashMap() {
- this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
- }
+ // Original (since JDK1.2) Map methods
/**
- * Creates a new map with the same mappings as the given map.
- * The map is created with a capacity of 1.5 times the number
- * of mappings in the given map or 16 (whichever is greater),
- * and a default load factor (0.75) and concurrencyLevel (16).
- *
- * @param m the map
+ * {@inheritDoc}
*/
- public ConcurrentHashMap(Map<? extends K, ? extends V> m) {
- this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
- DEFAULT_INITIAL_CAPACITY),
- DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
- putAll(m);
+ public int size() {
+ long n = sumCount();
+ return ((n < 0L) ? 0 :
+ (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :
+ (int)n);
}
/**
- * Returns <tt>true</tt> if this map contains no key-value mappings.
- *
- * @return <tt>true</tt> if this map contains no key-value mappings
+ * {@inheritDoc}
*/
public boolean isEmpty() {
- /*
- * Sum per-segment modCounts to avoid mis-reporting when
- * elements are concurrently added and removed in one segment
- * while checking another, in which case the table was never
- * actually empty at any point. (The sum ensures accuracy up
- * through at least 1<<31 per-segment modifications before
- * recheck.) Methods size() and containsValue() use similar
- * constructions for stability checks.
- */
- long sum = 0L;
- final Segment<K,V>[] segments = this.segments;
- for (int j = 0; j < segments.length; ++j) {
- Segment<K,V> seg = segmentAt(segments, j);
- if (seg != null) {
- if (seg.count != 0)
- return false;
- sum += seg.modCount;
- }
- }
- if (sum != 0L) { // recheck unless no modifications
- for (int j = 0; j < segments.length; ++j) {
- Segment<K,V> seg = segmentAt(segments, j);
- if (seg != null) {
- if (seg.count != 0)
- return false;
- sum -= seg.modCount;
- }
- }
- if (sum != 0L)
- return false;
- }
- return true;
- }
-
- /**
- * Returns the number of key-value mappings in this map. If the
- * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
- * <tt>Integer.MAX_VALUE</tt>.
- *
- * @return the number of key-value mappings in this map
- */
- public int size() {
- // Try a few times to get accurate count. On failure due to
- // continuous async changes in table, resort to locking.
- final Segment<K,V>[] segments = this.segments;
- final int segmentCount = segments.length;
-
- long previousSum = 0L;
- for (int retries = -1; retries < RETRIES_BEFORE_LOCK; retries++) {
- long sum = 0L; // sum of modCounts
- long size = 0L;
- for (int i = 0; i < segmentCount; i++) {
- Segment<K,V> segment = segmentAt(segments, i);
- if (segment != null) {
- sum += segment.modCount;
- size += segment.count;
- }
- }
- if (sum == previousSum)
- return ((size >>> 31) == 0) ? (int) size : Integer.MAX_VALUE;
- previousSum = sum;
- }
-
- long size = 0L;
- for (int i = 0; i < segmentCount; i++) {
- Segment<K,V> segment = ensureSegment(i);
- segment.lock();
- size += segment.count;
- }
- for (int i = 0; i < segmentCount; i++)
- segments[i].unlock();
- return ((size >>> 31) == 0) ? (int) size : Integer.MAX_VALUE;
+ return sumCount() <= 0L; // ignore transient negative values
}
/**
@@ -878,18 +742,20 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
* @throws NullPointerException if the specified key is null
*/
public V get(Object key) {
- Segment<K,V> s; // manually integrate access methods to reduce overhead
- HashEntry<K,V>[] tab;
- int h = hash(key.hashCode());
- long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;
- if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null &&
- (tab = s.table) != null) {
- for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile
- (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE);
- e != null; e = e.next) {
- K k;
- if ((k = e.key) == key || (e.hash == h && key.equals(k)))
- return e.value;
+ Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;
+ int h = spread(key.hashCode());
+ if ((tab = table) != null && (n = tab.length) > 0 &&
+ (e = tabAt(tab, (n - 1) & h)) != null) {
+ if ((eh = e.hash) == h) {
+ if ((ek = e.key) == key || (ek != null && key.equals(ek)))
+ return e.val;
+ }
+ else if (eh < 0)
+ return (p = e.find(h, key)) != null ? p.val : null;
+ while ((e = e.next) != null) {
+ if (e.hash == h &&
+ ((ek = e.key) == key || (ek != null && key.equals(ek))))
+ return e.val;
}
}
return null;
@@ -898,149 +764,121 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
/**
* Tests if the specified object is a key in this table.
*
- * @param key possible key
- * @return <tt>true</tt> if and only if the specified object
+ * @param key possible key
+ * @return {@code true} if and only if the specified object
* is a key in this table, as determined by the
- * <tt>equals</tt> method; <tt>false</tt> otherwise.
+ * {@code equals} method; {@code false} otherwise
* @throws NullPointerException if the specified key is null
*/
- @SuppressWarnings("unchecked")
public boolean containsKey(Object key) {
- Segment<K,V> s; // same as get() except no need for volatile value read
- HashEntry<K,V>[] tab;
- int h = hash(key.hashCode());
- long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;
- if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null &&
- (tab = s.table) != null) {
- for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile
- (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE);
- e != null; e = e.next) {
- K k;
- if ((k = e.key) == key || (e.hash == h && key.equals(k)))
- return true;
- }
- }
- return false;
+ return get(key) != null;
}
/**
- * Returns <tt>true</tt> if this map maps one or more keys to the
- * specified value. Note: This method requires a full internal
- * traversal of the hash table, and so is much slower than
- * method <tt>containsKey</tt>.
+ * Returns {@code true} if this map maps one or more keys to the
+ * specified value. Note: This method may require a full traversal
+ * of the map, and is much slower than method {@code containsKey}.
*
* @param value value whose presence in this map is to be tested
- * @return <tt>true</tt> if this map maps one or more keys to the
+ * @return {@code true} if this map maps one or more keys to the
* specified value
* @throws NullPointerException if the specified value is null
*/
public boolean containsValue(Object value) {
- // Same idea as size()
if (value == null)
throw new NullPointerException();
- final Segment<K,V>[] segments = this.segments;
- long previousSum = 0L;
- int lockCount = 0;
- try {
- for (int retries = -1; ; retries++) {
- long sum = 0L; // sum of modCounts
- for (int j = 0; j < segments.length; j++) {
- Segment<K,V> segment;
- if (retries == RETRIES_BEFORE_LOCK) {
- segment = ensureSegment(j);
- segment.lock();
- lockCount++;
- } else {
- segment = segmentAt(segments, j);
- if (segment == null)
- continue;
- }
- HashEntry<K,V>[] tab = segment.table;
- if (tab != null) {
- for (int i = 0 ; i < tab.length; i++) {
- HashEntry<K,V> e;
- for (e = entryAt(tab, i); e != null; e = e.next) {
- V v = e.value;
- if (v != null && value.equals(v))
- return true;
- }
- }
- sum += segment.modCount;
- }
- }
- if ((retries >= 0 && sum == previousSum) || lockCount > 0)
- return false;
- previousSum = sum;
+ Node<K,V>[] t;
+ if ((t = table) != null) {
+ Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+ for (Node<K,V> p; (p = it.advance()) != null; ) {
+ V v;
+ if ((v = p.val) == value || (v != null && value.equals(v)))
+ return true;
}
- } finally {
- for (int j = 0; j < lockCount; j++)
- segments[j].unlock();
}
- }
-
- /**
- * Legacy method testing if some key maps into the specified value
- * in this table. This method is identical in functionality to
- * {@link #containsValue}, and exists solely to ensure
- * full compatibility with class {@link java.util.Hashtable},
- * which supported this method prior to introduction of the
- * Java Collections framework.
- *
- * @param value a value to search for
- * @return <tt>true</tt> if and only if some key maps to the
- * <tt>value</tt> argument in this table as
- * determined by the <tt>equals</tt> method;
- * <tt>false</tt> otherwise
- * @throws NullPointerException if the specified value is null
- */
- public boolean contains(Object value) {
- return containsValue(value);
+ return false;
}
/**
* Maps the specified key to the specified value in this table.
* Neither the key nor the value can be null.
*
- * <p> The value can be retrieved by calling the <tt>get</tt> method
+ * <p>The value can be retrieved by calling the {@code get} method
* with a key that is equal to the original key.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
- * @return the previous value associated with <tt>key</tt>, or
- * <tt>null</tt> if there was no mapping for <tt>key</tt>
+ * @return the previous value associated with {@code key}, or
+ * {@code null} if there was no mapping for {@code key}
* @throws NullPointerException if the specified key or value is null
*/
- @SuppressWarnings("unchecked")
public V put(K key, V value) {
- Segment<K,V> s;
- if (value == null)
- throw new NullPointerException();
- int hash = hash(key.hashCode());
- int j = (hash >>> segmentShift) & segmentMask;
- if ((s = (Segment<K,V>)UNSAFE.getObject // nonvolatile; recheck
- (segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegment
- s = ensureSegment(j);
- return s.put(key, hash, value, false);
+ return putVal(key, value, false);
}
- /**
- * {@inheritDoc}
- *
- * @return the previous value associated with the specified key,
- * or <tt>null</tt> if there was no mapping for the key
- * @throws NullPointerException if the specified key or value is null
- */
- @SuppressWarnings("unchecked")
- public V putIfAbsent(K key, V value) {
- Segment<K,V> s;
- if (value == null)
- throw new NullPointerException();
- int hash = hash(key.hashCode());
- int j = (hash >>> segmentShift) & segmentMask;
- if ((s = (Segment<K,V>)UNSAFE.getObject
- (segments, (j << SSHIFT) + SBASE)) == null)
- s = ensureSegment(j);
- return s.put(key, hash, value, true);
+ /** Implementation for put and putIfAbsent */
+ final V putVal(K key, V value, boolean onlyIfAbsent) {
+ if (key == null || value == null) throw new NullPointerException();
+ int hash = spread(key.hashCode());
+ int binCount = 0;
+ for (Node<K,V>[] tab = table;;) {
+ Node<K,V> f; int n, i, fh;
+ if (tab == null || (n = tab.length) == 0)
+ tab = initTable();
+ else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
+ if (casTabAt(tab, i, null,
+ new Node<K,V>(hash, key, value, null)))
+ break; // no lock when adding to empty bin
+ }
+ else if ((fh = f.hash) == MOVED)
+ tab = helpTransfer(tab, f);
+ else {
+ V oldVal = null;
+ synchronized (f) {
+ if (tabAt(tab, i) == f) {
+ if (fh >= 0) {
+ binCount = 1;
+ for (Node<K,V> e = f;; ++binCount) {
+ K ek;
+ if (e.hash == hash &&
+ ((ek = e.key) == key ||
+ (ek != null && key.equals(ek)))) {
+ oldVal = e.val;
+ if (!onlyIfAbsent)
+ e.val = value;
+ break;
+ }
+ Node<K,V> pred = e;
+ if ((e = e.next) == null) {
+ pred.next = new Node<K,V>(hash, key,
+ value, null);
+ break;
+ }
+ }
+ }
+ else if (f instanceof TreeBin) {
+ Node<K,V> p;
+ binCount = 2;
+ if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
+ value)) != null) {
+ oldVal = p.val;
+ if (!onlyIfAbsent)
+ p.val = value;
+ }
+ }
+ }
+ }
+ if (binCount != 0) {
+ if (binCount >= TREEIFY_THRESHOLD)
+ treeifyBin(tab, i);
+ if (oldVal != null)
+ return oldVal;
+ break;
+ }
+ }
+ }
+ addCount(1L, binCount);
+ return null;
}
/**
@@ -1051,8 +889,9 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
* @param m mappings to be stored in this map
*/
public void putAll(Map<? extends K, ? extends V> m) {
+ tryPresize(m.size());
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
- put(e.getKey(), e.getValue());
+ putVal(e.getKey(), e.getValue(), false);
}
/**
@@ -1060,87 +899,147 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
* This method does nothing if the key is not in the map.
*
* @param key the key that needs to be removed
- * @return the previous value associated with <tt>key</tt>, or
- * <tt>null</tt> if there was no mapping for <tt>key</tt>
+ * @return the previous value associated with {@code key}, or
+ * {@code null} if there was no mapping for {@code key}
* @throws NullPointerException if the specified key is null
*/
public V remove(Object key) {
- int hash = hash(key.hashCode());
- Segment<K,V> s = segmentForHash(hash);
- return s == null ? null : s.remove(key, hash, null);
- }
-
- /**
- * {@inheritDoc}
- *
- * @throws NullPointerException if the specified key is null
- */
- public boolean remove(Object key, Object value) {
- int hash = hash(key.hashCode());
- Segment<K,V> s;
- return value != null && (s = segmentForHash(hash)) != null &&
- s.remove(key, hash, value) != null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @throws NullPointerException if any of the arguments are null
- */
- public boolean replace(K key, V oldValue, V newValue) {
- int hash = hash(key.hashCode());
- if (oldValue == null || newValue == null)
- throw new NullPointerException();
- Segment<K,V> s = segmentForHash(hash);
- return s != null && s.replace(key, hash, oldValue, newValue);
+ return replaceNode(key, null, null);
}
/**
- * {@inheritDoc}
- *
- * @return the previous value associated with the specified key,
- * or <tt>null</tt> if there was no mapping for the key
- * @throws NullPointerException if the specified key or value is null
+ * Implementation for the four public remove/replace methods:
+ * Replaces node value with v, conditional upon match of cv if
+ * non-null. If resulting value is null, delete.
*/
- public V replace(K key, V value) {
- int hash = hash(key.hashCode());
- if (value == null)
- throw new NullPointerException();
- Segment<K,V> s = segmentForHash(hash);
- return s == null ? null : s.replace(key, hash, value);
+ final V replaceNode(Object key, V value, Object cv) {
+ int hash = spread(key.hashCode());
+ for (Node<K,V>[] tab = table;;) {
+ Node<K,V> f; int n, i, fh;
+ if (tab == null || (n = tab.length) == 0 ||
+ (f = tabAt(tab, i = (n - 1) & hash)) == null)
+ break;
+ else if ((fh = f.hash) == MOVED)
+ tab = helpTransfer(tab, f);
+ else {
+ V oldVal = null;
+ boolean validated = false;
+ synchronized (f) {
+ if (tabAt(tab, i) == f) {
+ if (fh >= 0) {
+ validated = true;
+ for (Node<K,V> e = f, pred = null;;) {
+ K ek;
+ if (e.hash == hash &&
+ ((ek = e.key) == key ||
+ (ek != null && key.equals(ek)))) {
+ V ev = e.val;
+ if (cv == null || cv == ev ||
+ (ev != null && cv.equals(ev))) {
+ oldVal = ev;
+ if (value != null)
+ e.val = value;
+ else if (pred != null)
+ pred.next = e.next;
+ else
+ setTabAt(tab, i, e.next);
+ }
+ break;
+ }
+ pred = e;
+ if ((e = e.next) == null)
+ break;
+ }
+ }
+ else if (f instanceof TreeBin) {
+ validated = true;
+ TreeBin<K,V> t = (TreeBin<K,V>)f;
+ TreeNode<K,V> r, p;
+ if ((r = t.root) != null &&
+ (p = r.findTreeNode(hash, key, null)) != null) {
+ V pv = p.val;
+ if (cv == null || cv == pv ||
+ (pv != null && cv.equals(pv))) {
+ oldVal = pv;
+ if (value != null)
+ p.val = value;
+ else if (t.removeTreeNode(p))
+ setTabAt(tab, i, untreeify(t.first));
+ }
+ }
+ }
+ }
+ }
+ if (validated) {
+ if (oldVal != null) {
+ if (value == null)
+ addCount(-1L, -1);
+ return oldVal;
+ }
+ break;
+ }
+ }
+ }
+ return null;
}
/**
* Removes all of the mappings from this map.
*/
public void clear() {
- final Segment<K,V>[] segments = this.segments;
- for (int j = 0; j < segments.length; ++j) {
- Segment<K,V> s = segmentAt(segments, j);
- if (s != null)
- s.clear();
+ long delta = 0L; // negative number of deletions
+ int i = 0;
+ Node<K,V>[] tab = table;
+ while (tab != null && i < tab.length) {
+ int fh;
+ Node<K,V> f = tabAt(tab, i);
+ if (f == null)
+ ++i;
+ else if ((fh = f.hash) == MOVED) {
+ tab = helpTransfer(tab, f);
+ i = 0; // restart
+ }
+ else {
+ synchronized (f) {
+ if (tabAt(tab, i) == f) {
+ Node<K,V> p = (fh >= 0 ? f :
+ (f instanceof TreeBin) ?
+ ((TreeBin<K,V>)f).first : null);
+ while (p != null) {
+ --delta;
+ p = p.next;
+ }
+ setTabAt(tab, i++, null);
+ }
+ }
+ }
}
+ if (delta != 0L)
+ addCount(delta, -1);
}
/**
* Returns a {@link Set} view of the keys contained in this map.
* The set is backed by the map, so changes to the map are
- * reflected in the set, and vice-versa. The set supports element
+ * reflected in the set, and vice-versa. The set supports element
* removal, which removes the corresponding mapping from this map,
- * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
- * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
- * operations. It does not support the <tt>add</tt> or
- * <tt>addAll</tt> operations.
+ * via the {@code Iterator.remove}, {@code Set.remove},
+ * {@code removeAll}, {@code retainAll}, and {@code clear}
+ * operations. It does not support the {@code add} or
+ * {@code addAll} operations.
*
- * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
+ * <p>The view's {@code iterator} is a "weakly consistent" iterator
* that will never throw {@link ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
* reflect any modifications subsequent to construction.
+ *
+ * @return the set view
+ *
*/
public Set<K> keySet() {
- Set<K> ks = keySet;
- return (ks != null) ? ks : (keySet = new KeySet());
+ KeySetView<K,V> ks;
+ return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null));
}
/**
@@ -1148,20 +1047,22 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
* The collection is backed by the map, so changes to the map are
* reflected in the collection, and vice-versa. The collection
* supports element removal, which removes the corresponding
- * mapping from this map, via the <tt>Iterator.remove</tt>,
- * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
- * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not
- * support the <tt>add</tt> or <tt>addAll</tt> operations.
+ * mapping from this map, via the {@code Iterator.remove},
+ * {@code Collection.remove}, {@code removeAll},
+ * {@code retainAll}, and {@code clear} operations. It does not
+ * support the {@code add} or {@code addAll} operations.
*
- * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
+ * <p>The view's {@code iterator} is a "weakly consistent" iterator
* that will never throw {@link ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
* reflect any modifications subsequent to construction.
+ *
+ * @return the collection view
*/
public Collection<V> values() {
- Collection<V> vs = values;
- return (vs != null) ? vs : (values = new Values());
+ ValuesView<K,V> vs;
+ return (vs = values) != null ? vs : (values = new ValuesView<K,V>(this));
}
/**
@@ -1169,20 +1070,329 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
* The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. The set supports element
* removal, which removes the corresponding mapping from the map,
- * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
- * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
- * operations. It does not support the <tt>add</tt> or
- * <tt>addAll</tt> operations.
+ * via the {@code Iterator.remove}, {@code Set.remove},
+ * {@code removeAll}, {@code retainAll}, and {@code clear}
+ * operations.
*
- * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
+ * <p>The view's {@code iterator} is a "weakly consistent" iterator
* that will never throw {@link ConcurrentModificationException},
* and guarantees to traverse elements as they existed upon
* construction of the iterator, and may (but is not guaranteed to)
* reflect any modifications subsequent to construction.
+ *
+ * @return the set view
*/
public Set<Map.Entry<K,V>> entrySet() {
- Set<Map.Entry<K,V>> es = entrySet;
- return (es != null) ? es : (entrySet = new EntrySet());
+ EntrySetView<K,V> es;
+ return (es = entrySet) != null ? es : (entrySet = new EntrySetView<K,V>(this));
+ }
+
+ /**
+ * Returns the hash code value for this {@link Map}, i.e.,
+ * the sum of, for each key-value pair in the map,
+ * {@code key.hashCode() ^ value.hashCode()}.
+ *
+ * @return the hash code value for this map
+ */
+ public int hashCode() {
+ int h = 0;
+ Node<K,V>[] t;
+ if ((t = table) != null) {
+ Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+ for (Node<K,V> p; (p = it.advance()) != null; )
+ h += p.key.hashCode() ^ p.val.hashCode();
+ }
+ return h;
+ }
+
+ /**
+ * Returns a string representation of this map. The string
+ * representation consists of a list of key-value mappings (in no
+ * particular order) enclosed in braces ("{@code {}}"). Adjacent
+ * mappings are separated by the characters {@code ", "} (comma
+ * and space). Each key-value mapping is rendered as the key
+ * followed by an equals sign ("{@code =}") followed by the
+ * associated value.
+ *
+ * @return a string representation of this map
+ */
+ public String toString() {
+ Node<K,V>[] t;
+ int f = (t = table) == null ? 0 : t.length;
+ Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f);
+ StringBuilder sb = new StringBuilder();
+ sb.append('{');
+ Node<K,V> p;
+ if ((p = it.advance()) != null) {
+ for (;;) {
+ K k = p.key;
+ V v = p.val;
+ sb.append(k == this ? "(this Map)" : k);
+ sb.append('=');
+ sb.append(v == this ? "(this Map)" : v);
+ if ((p = it.advance()) == null)
+ break;
+ sb.append(',').append(' ');
+ }
+ }
+ return sb.append('}').toString();
+ }
+
+ /**
+ * Compares the specified object with this map for equality.
+ * Returns {@code true} if the given object is a map with the same
+ * mappings as this map. This operation may return misleading
+ * results if either map is concurrently modified during execution
+ * of this method.
+ *
+ * @param o object to be compared for equality with this map
+ * @return {@code true} if the specified object is equal to this map
+ */
+ public boolean equals(Object o) {
+ if (o != this) {
+ if (!(o instanceof Map))
+ return false;
+ Map<?,?> m = (Map<?,?>) o;
+ Node<K,V>[] t;
+ int f = (t = table) == null ? 0 : t.length;
+ Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f);
+ for (Node<K,V> p; (p = it.advance()) != null; ) {
+ V val = p.val;
+ Object v = m.get(p.key);
+ if (v == null || (v != val && !v.equals(val)))
+ return false;
+ }
+ for (Map.Entry<?,?> e : m.entrySet()) {
+ Object mk, mv, v;
+ if ((mk = e.getKey()) == null ||
+ (mv = e.getValue()) == null ||
+ (v = get(mk)) == null ||
+ (mv != v && !mv.equals(v)))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Stripped-down version of helper class used in previous version,
+ * declared for the sake of serialization compatibility
+ */
+ static class Segment<K,V> extends ReentrantLock implements Serializable {
+ private static final long serialVersionUID = 2249069246763182397L;
+ final float loadFactor;
+ Segment(float lf) { this.loadFactor = lf; }
+ }
+
+ /**
+ * Saves the state of the {@code ConcurrentHashMap} instance to a
+ * stream (i.e., serializes it).
+ * @param s the stream
+ * @serialData
+ * the key (Object) and value (Object)
+ * for each key-value mapping, followed by a null pair.
+ * The key-value mappings are emitted in no particular order.
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+ // For serialization compatibility
+ // Emulate segment calculation from previous version of this class
+ int sshift = 0;
+ int ssize = 1;
+ while (ssize < DEFAULT_CONCURRENCY_LEVEL) {
+ ++sshift;
+ ssize <<= 1;
+ }
+ int segmentShift = 32 - sshift;
+ int segmentMask = ssize - 1;
+ @SuppressWarnings("unchecked") Segment<K,V>[] segments = (Segment<K,V>[])
+ new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
+ for (int i = 0; i < segments.length; ++i)
+ segments[i] = new Segment<K,V>(LOAD_FACTOR);
+ s.putFields().put("segments", segments);
+ s.putFields().put("segmentShift", segmentShift);
+ s.putFields().put("segmentMask", segmentMask);
+ s.writeFields();
+
+ Node<K,V>[] t;
+ if ((t = table) != null) {
+ Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+ for (Node<K,V> p; (p = it.advance()) != null; ) {
+ s.writeObject(p.key);
+ s.writeObject(p.val);
+ }
+ }
+ s.writeObject(null);
+ s.writeObject(null);
+ segments = null; // throw away
+ }
+
+ /**
+ * Reconstitutes the instance from a stream (that is, deserializes it).
+ * @param s the stream
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ /*
+ * To improve performance in typical cases, we create nodes
+ * while reading, then place in table once size is known.
+ * However, we must also validate uniqueness and deal with
+ * overpopulated bins while doing so, which requires
+ * specialized versions of putVal mechanics.
+ */
+ sizeCtl = -1; // force exclusion for table construction
+ s.defaultReadObject();
+ long size = 0L;
+ Node<K,V> p = null;
+ for (;;) {
+ @SuppressWarnings("unchecked") K k = (K) s.readObject();
+ @SuppressWarnings("unchecked") V v = (V) s.readObject();
+ if (k != null && v != null) {
+ p = new Node<K,V>(spread(k.hashCode()), k, v, p);
+ ++size;
+ }
+ else
+ break;
+ }
+ if (size == 0L)
+ sizeCtl = 0;
+ else {
+ int n;
+ if (size >= (long)(MAXIMUM_CAPACITY >>> 1))
+ n = MAXIMUM_CAPACITY;
+ else {
+ int sz = (int)size;
+ n = tableSizeFor(sz + (sz >>> 1) + 1);
+ }
+ @SuppressWarnings({"rawtypes","unchecked"})
+ Node<K,V>[] tab = (Node<K,V>[])new Node[n];
+ int mask = n - 1;
+ long added = 0L;
+ while (p != null) {
+ boolean insertAtFront;
+ Node<K,V> next = p.next, first;
+ int h = p.hash, j = h & mask;
+ if ((first = tabAt(tab, j)) == null)
+ insertAtFront = true;
+ else {
+ K k = p.key;
+ if (first.hash < 0) {
+ TreeBin<K,V> t = (TreeBin<K,V>)first;
+ if (t.putTreeVal(h, k, p.val) == null)
+ ++added;
+ insertAtFront = false;
+ }
+ else {
+ int binCount = 0;
+ insertAtFront = true;
+ Node<K,V> q; K qk;
+ for (q = first; q != null; q = q.next) {
+ if (q.hash == h &&
+ ((qk = q.key) == k ||
+ (qk != null && k.equals(qk)))) {
+ insertAtFront = false;
+ break;
+ }
+ ++binCount;
+ }
+ if (insertAtFront && binCount >= TREEIFY_THRESHOLD) {
+ insertAtFront = false;
+ ++added;
+ p.next = first;
+ TreeNode<K,V> hd = null, tl = null;
+ for (q = p; q != null; q = q.next) {
+ TreeNode<K,V> t = new TreeNode<K,V>
+ (q.hash, q.key, q.val, null, null);
+ if ((t.prev = tl) == null)
+ hd = t;
+ else
+ tl.next = t;
+ tl = t;
+ }
+ setTabAt(tab, j, new TreeBin<K,V>(hd));
+ }
+ }
+ }
+ if (insertAtFront) {
+ ++added;
+ p.next = first;
+ setTabAt(tab, j, p);
+ }
+ p = next;
+ }
+ table = tab;
+ sizeCtl = n - (n >>> 2);
+ baseCount = added;
+ }
+ }
+
+ // ConcurrentMap methods
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return the previous value associated with the specified key,
+ * or {@code null} if there was no mapping for the key
+ * @throws NullPointerException if the specified key or value is null
+ */
+ public V putIfAbsent(K key, V value) {
+ return putVal(key, value, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws NullPointerException if the specified key is null
+ */
+ public boolean remove(Object key, Object value) {
+ if (key == null)
+ throw new NullPointerException();
+ return value != null && replaceNode(key, null, value) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws NullPointerException if any of the arguments are null
+ */
+ public boolean replace(K key, V oldValue, V newValue) {
+ if (key == null || oldValue == null || newValue == null)
+ throw new NullPointerException();
+ return replaceNode(key, newValue, oldValue) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return the previous value associated with the specified key,
+ * or {@code null} if there was no mapping for the key
+ * @throws NullPointerException if the specified key or value is null
+ */
+ public V replace(K key, V value) {
+ if (key == null || value == null)
+ throw new NullPointerException();
+ return replaceNode(key, value, null);
+ }
+ // Hashtable legacy methods
+
+ /**
+ * Legacy method testing if some key maps into the specified value
+ * in this table. This method is identical in functionality to
+ * {@link #containsValue(Object)}, and exists solely to ensure
+ * full compatibility with class {@link java.util.Hashtable}.
+ *
+ * @param value a value to search for
+ * @return {@code true} if and only if some key maps to the
+ * {@code value} argument in this table as
+ * determined by the {@code equals} method;
+ * {@code false} otherwise
+ * @throws NullPointerException if the specified value is null
+ */
+ public boolean contains(Object value) {
+ // BEGIN android-note
+ // removed deprecation
+ // END android-note
+ return containsValue(value);
}
/**
@@ -1192,7 +1402,9 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
* @see #keySet()
*/
public Enumeration<K> keys() {
- return new KeyIterator();
+ Node<K,V>[] t;
+ int f = (t = table) == null ? 0 : t.length;
+ return new KeyIterator<K,V>(t, f, 0, f, this);
}
/**
@@ -1202,281 +1414,1787 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
* @see #values()
*/
public Enumeration<V> elements() {
- return new ValueIterator();
+ Node<K,V>[] t;
+ int f = (t = table) == null ? 0 : t.length;
+ return new ValueIterator<K,V>(t, f, 0, f, this);
}
- /* ---------------- Iterator Support -------------- */
+ // ConcurrentHashMap-only methods
- abstract class HashIterator {
- int nextSegmentIndex;
- int nextTableIndex;
- HashEntry<K,V>[] currentTable;
- HashEntry<K, V> nextEntry;
- HashEntry<K, V> lastReturned;
+ /**
+ * Returns the number of mappings. This method should be used
+ * instead of {@link #size} because a ConcurrentHashMap may
+ * contain more mappings than can be represented as an int. The
+ * value returned is an estimate; the actual count may differ if
+ * there are concurrent insertions or removals.
+ *
+ * @return the number of mappings
+ * @since 1.8
+ *
+ * @hide
+ */
+ public long mappingCount() {
+ long n = sumCount();
+ return (n < 0L) ? 0L : n; // ignore transient negative values
+ }
- HashIterator() {
- nextSegmentIndex = segments.length - 1;
- nextTableIndex = -1;
- advance();
+ /**
+ * Creates a new {@link Set} backed by a ConcurrentHashMap
+ * from the given type to {@code Boolean.TRUE}.
+ *
+ * @return the new set
+ * @since 1.8
+ *
+ * @hide
+ */
+ public static <K> KeySetView<K,Boolean> newKeySet() {
+ return new KeySetView<K,Boolean>
+ (new ConcurrentHashMap<K,Boolean>(), Boolean.TRUE);
+ }
+
+ /**
+ * Creates a new {@link Set} backed by a ConcurrentHashMap
+ * from the given type to {@code Boolean.TRUE}.
+ *
+ * @param initialCapacity The implementation performs internal
+ * sizing to accommodate this many elements.
+ * @throws IllegalArgumentException if the initial capacity of
+ * elements is negative
+ * @return the new set
+ * @since 1.8
+ *
+ * @hide
+ */
+ public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
+ return new KeySetView<K,Boolean>
+ (new ConcurrentHashMap<K,Boolean>(initialCapacity), Boolean.TRUE);
+ }
+
+ /**
+ * Returns a {@link Set} view of the keys in this map, using the
+ * given common mapped value for any additions (i.e., {@link
+ * Collection#add} and {@link Collection#addAll(Collection)}).
+ * This is of course only appropriate if it is acceptable to use
+ * the same value for all additions from this view.
+ *
+ * @param mappedValue the mapped value to use for any additions
+ * @return the set view
+ * @throws NullPointerException if the mappedValue is null
+ *
+ * @hide
+ */
+ public Set<K> keySet(V mappedValue) {
+ if (mappedValue == null)
+ throw new NullPointerException();
+ return new KeySetView<K,V>(this, mappedValue);
+ }
+
+ /* ---------------- Special Nodes -------------- */
+
+ /**
+ * A node inserted at head of bins during transfer operations.
+ */
+ static final class ForwardingNode<K,V> extends Node<K,V> {
+ final Node<K,V>[] nextTable;
+ ForwardingNode(Node<K,V>[] tab) {
+ super(MOVED, null, null, null);
+ this.nextTable = tab;
+ }
+
+ Node<K,V> find(int h, Object k) {
+ Node<K,V> e; int n;
+ Node<K,V>[] tab = nextTable;
+ if (k != null && tab != null && (n = tab.length) > 0 &&
+ (e = tabAt(tab, (n - 1) & h)) != null) {
+ do {
+ int eh; K ek;
+ if ((eh = e.hash) == h &&
+ ((ek = e.key) == k || (ek != null && k.equals(ek))))
+ return e;
+ if (eh < 0)
+ return e.find(h, k);
+ } while ((e = e.next) != null);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * A place-holder node used in computeIfAbsent and compute
+ */
+ static final class ReservationNode<K,V> extends Node<K,V> {
+ ReservationNode() {
+ super(RESERVED, null, null, null);
+ }
+
+ Node<K,V> find(int h, Object k) {
+ return null;
+ }
+ }
+
+ /* ---------------- Table Initialization and Resizing -------------- */
+
+ /**
+ * Initializes table, using the size recorded in sizeCtl.
+ */
+ private final Node<K,V>[] initTable() {
+ Node<K,V>[] tab; int sc;
+ while ((tab = table) == null || tab.length == 0) {
+ if ((sc = sizeCtl) < 0)
+ Thread.yield(); // lost initialization race; just spin
+ else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
+ try {
+ if ((tab = table) == null || tab.length == 0) {
+ int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
+ @SuppressWarnings({"rawtypes","unchecked"})
+ Node<K,V>[] nt = (Node<K,V>[])new Node[n];
+ table = tab = nt;
+ sc = n - (n >>> 2);
+ }
+ } finally {
+ sizeCtl = sc;
+ }
+ break;
+ }
+ }
+ return tab;
+ }
+
+ /**
+ * Adds to count, and if table is too small and not already
+ * resizing, initiates transfer. If already resizing, helps
+ * perform transfer if work is available. Rechecks occupancy
+ * after a transfer to see if another resize is already needed
+ * because resizings are lagging additions.
+ *
+ * @param x the count to add
+ * @param check if <0, don't check resize, if <= 1 only check if uncontended
+ */
+ private final void addCount(long x, int check) {
+ CounterCell[] as; long b, s;
+ if ((as = counterCells) != null ||
+ !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {
+ CounterHashCode hc; CounterCell a; long v; int m;
+ boolean uncontended = true;
+ if ((hc = threadCounterHashCode.get()) == null ||
+ as == null || (m = as.length - 1) < 0 ||
+ (a = as[m & hc.code]) == null ||
+ !(uncontended =
+ U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {
+ fullAddCount(x, hc, uncontended);
+ return;
+ }
+ if (check <= 1)
+ return;
+ s = sumCount();
+ }
+ if (check >= 0) {
+ Node<K,V>[] tab, nt; int sc;
+ while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
+ tab.length < MAXIMUM_CAPACITY) {
+ if (sc < 0) {
+ if (sc == -1 || transferIndex <= transferOrigin ||
+ (nt = nextTable) == null)
+ break;
+ if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
+ transfer(tab, nt);
+ }
+ else if (U.compareAndSwapInt(this, SIZECTL, sc, -2))
+ transfer(tab, null);
+ s = sumCount();
+ }
+ }
+ }
+
+ /**
+ * Helps transfer if a resize is in progress.
+ */
+ final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) {
+ Node<K,V>[] nextTab; int sc;
+ if ((f instanceof ForwardingNode) &&
+ (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
+ if (nextTab == nextTable && tab == table &&
+ transferIndex > transferOrigin && (sc = sizeCtl) < -1 &&
+ U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
+ transfer(tab, nextTab);
+ return nextTab;
+ }
+ return table;
+ }
+
+ /**
+ * Tries to presize table to accommodate the given number of elements.
+ *
+ * @param size number of elements (doesn't need to be perfectly accurate)
+ */
+ private final void tryPresize(int size) {
+ int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
+ tableSizeFor(size + (size >>> 1) + 1);
+ int sc;
+ while ((sc = sizeCtl) >= 0) {
+ Node<K,V>[] tab = table; int n;
+ if (tab == null || (n = tab.length) == 0) {
+ n = (sc > c) ? sc : c;
+ if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
+ try {
+ if (table == tab) {
+ @SuppressWarnings({"rawtypes","unchecked"})
+ Node<K,V>[] nt = (Node<K,V>[])new Node[n];
+ table = nt;
+ sc = n - (n >>> 2);
+ }
+ } finally {
+ sizeCtl = sc;
+ }
+ }
+ }
+ else if (c <= sc || n >= MAXIMUM_CAPACITY)
+ break;
+ else if (tab == table &&
+ U.compareAndSwapInt(this, SIZECTL, sc, -2))
+ transfer(tab, null);
+ }
+ }
+
+ /**
+ * Moves and/or copies the nodes in each bin to new table. See
+ * above for explanation.
+ */
+ private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {
+ int n = tab.length, stride;
+ if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)
+ stride = MIN_TRANSFER_STRIDE; // subdivide range
+ if (nextTab == null) { // initiating
+ try {
+ @SuppressWarnings({"rawtypes","unchecked"})
+ Node<K,V>[] nt = (Node<K,V>[])new Node[n << 1];
+ nextTab = nt;
+ } catch (Throwable ex) { // try to cope with OOME
+ sizeCtl = Integer.MAX_VALUE;
+ return;
+ }
+ nextTable = nextTab;
+ transferOrigin = n;
+ transferIndex = n;
+ ForwardingNode<K,V> rev = new ForwardingNode<K,V>(tab);
+ for (int k = n; k > 0;) { // progressively reveal ready slots
+ int nextk = (k > stride) ? k - stride : 0;
+ for (int m = nextk; m < k; ++m)
+ nextTab[m] = rev;
+ for (int m = n + nextk; m < n + k; ++m)
+ nextTab[m] = rev;
+ U.putOrderedInt(this, TRANSFERORIGIN, k = nextk);
+ }
+ }
+ int nextn = nextTab.length;
+ ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab);
+ boolean advance = true;
+ for (int i = 0, bound = 0;;) {
+ int nextIndex, nextBound, fh; Node<K,V> f;
+ while (advance) {
+ if (--i >= bound)
+ advance = false;
+ else if ((nextIndex = transferIndex) <= transferOrigin) {
+ i = -1;
+ advance = false;
+ }
+ else if (U.compareAndSwapInt
+ (this, TRANSFERINDEX, nextIndex,
+ nextBound = (nextIndex > stride ?
+ nextIndex - stride : 0))) {
+ bound = nextBound;
+ i = nextIndex - 1;
+ advance = false;
+ }
+ }
+ if (i < 0 || i >= n || i + n >= nextn) {
+ for (int sc;;) {
+ if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) {
+ if (sc == -1) {
+ nextTable = null;
+ table = nextTab;
+ sizeCtl = (n << 1) - (n >>> 1);
+ }
+ return;
+ }
+ }
+ }
+ else if ((f = tabAt(tab, i)) == null) {
+ if (casTabAt(tab, i, null, fwd)) {
+ setTabAt(nextTab, i, null);
+ setTabAt(nextTab, i + n, null);
+ advance = true;
+ }
+ }
+ else if ((fh = f.hash) == MOVED)
+ advance = true; // already processed
+ else {
+ synchronized (f) {
+ if (tabAt(tab, i) == f) {
+ Node<K,V> ln, hn;
+ if (fh >= 0) {
+ int runBit = fh & n;
+ Node<K,V> lastRun = f;
+ for (Node<K,V> p = f.next; p != null; p = p.next) {
+ int b = p.hash & n;
+ if (b != runBit) {
+ runBit = b;
+ lastRun = p;
+ }
+ }
+ if (runBit == 0) {
+ ln = lastRun;
+ hn = null;
+ }
+ else {
+ hn = lastRun;
+ ln = null;
+ }
+ for (Node<K,V> p = f; p != lastRun; p = p.next) {
+ int ph = p.hash; K pk = p.key; V pv = p.val;
+ if ((ph & n) == 0)
+ ln = new Node<K,V>(ph, pk, pv, ln);
+ else
+ hn = new Node<K,V>(ph, pk, pv, hn);
+ }
+ }
+ else if (f instanceof TreeBin) {
+ TreeBin<K,V> t = (TreeBin<K,V>)f;
+ TreeNode<K,V> lo = null, loTail = null;
+ TreeNode<K,V> hi = null, hiTail = null;
+ int lc = 0, hc = 0;
+ for (Node<K,V> e = t.first; e != null; e = e.next) {
+ int h = e.hash;
+ TreeNode<K,V> p = new TreeNode<K,V>
+ (h, e.key, e.val, null, null);
+ if ((h & n) == 0) {
+ if ((p.prev = loTail) == null)
+ lo = p;
+ else
+ loTail.next = p;
+ loTail = p;
+ ++lc;
+ }
+ else {
+ if ((p.prev = hiTail) == null)
+ hi = p;
+ else
+ hiTail.next = p;
+ hiTail = p;
+ ++hc;
+ }
+ }
+ ln = (lc <= UNTREEIFY_THRESHOLD) ? untreeify(lo) :
+ (hc != 0) ? new TreeBin<K,V>(lo) : t;
+ hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) :
+ (lc != 0) ? new TreeBin<K,V>(hi) : t;
+ }
+ else
+ ln = hn = null;
+ setTabAt(nextTab, i, ln);
+ setTabAt(nextTab, i + n, hn);
+ setTabAt(tab, i, fwd);
+ advance = true;
+ }
+ }
+ }
+ }
+ }
+
+ /* ---------------- Conversion from/to TreeBins -------------- */
+
+ /**
+ * Replaces all linked nodes in bin at given index unless table is
+ * too small, in which case resizes instead.
+ */
+ private final void treeifyBin(Node<K,V>[] tab, int index) {
+ Node<K,V> b; int n, sc;
+ if (tab != null) {
+ if ((n = tab.length) < MIN_TREEIFY_CAPACITY) {
+ if (tab == table && (sc = sizeCtl) >= 0 &&
+ U.compareAndSwapInt(this, SIZECTL, sc, -2))
+ transfer(tab, null);
+ }
+ else if ((b = tabAt(tab, index)) != null) {
+ synchronized (b) {
+ if (tabAt(tab, index) == b) {
+ TreeNode<K,V> hd = null, tl = null;
+ for (Node<K,V> e = b; e != null; e = e.next) {
+ TreeNode<K,V> p =
+ new TreeNode<K,V>(e.hash, e.key, e.val,
+ null, null);
+ if ((p.prev = tl) == null)
+ hd = p;
+ else
+ tl.next = p;
+ tl = p;
+ }
+ setTabAt(tab, index, new TreeBin<K,V>(hd));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a list on non-TreeNodes replacing those in given list.
+ */
+ static <K,V> Node<K,V> untreeify(Node<K,V> b) {
+ Node<K,V> hd = null, tl = null;
+ for (Node<K,V> q = b; q != null; q = q.next) {
+ Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val, null);
+ if (tl == null)
+ hd = p;
+ else
+ tl.next = p;
+ tl = p;
+ }
+ return hd;
+ }
+
+ /* ---------------- TreeNodes -------------- */
+
+ /**
+ * Nodes for use in TreeBins
+ */
+ static final class TreeNode<K,V> extends Node<K,V> {
+ TreeNode<K,V> parent; // red-black tree links
+ TreeNode<K,V> left;
+ TreeNode<K,V> right;
+ TreeNode<K,V> prev; // needed to unlink next upon deletion
+ boolean red;
+
+ TreeNode(int hash, K key, V val, Node<K,V> next,
+ TreeNode<K,V> parent) {
+ super(hash, key, val, next);
+ this.parent = parent;
+ }
+
+ Node<K,V> find(int h, Object k) {
+ return findTreeNode(h, k, null);
}
/**
- * Sets nextEntry to first node of next non-empty table
- * (in backwards order, to simplify checks).
+ * Returns the TreeNode (or null if not found) for the given key
+ * starting at given root.
*/
- final void advance() {
- for (;;) {
- if (nextTableIndex >= 0) {
- if ((nextEntry = entryAt(currentTable,
- nextTableIndex--)) != null)
+ final TreeNode<K,V> findTreeNode(int h, Object k, Class<?> kc) {
+ if (k != null) {
+ TreeNode<K,V> p = this;
+ do {
+ int ph, dir; K pk; TreeNode<K,V> q;
+ TreeNode<K,V> pl = p.left, pr = p.right;
+ if ((ph = p.hash) > h)
+ p = pl;
+ else if (ph < h)
+ p = pr;
+ else if ((pk = p.key) == k || (pk != null && k.equals(pk)))
+ return p;
+ else if (pl == null && pr == null)
break;
+ else if ((kc != null ||
+ (kc = comparableClassFor(k)) != null) &&
+ (dir = compareComparables(kc, k, pk)) != 0)
+ p = (dir < 0) ? pl : pr;
+ else if (pl == null)
+ p = pr;
+ else if (pr == null ||
+ (q = pr.findTreeNode(h, k, kc)) == null)
+ p = pl;
+ else
+ return q;
+ } while (p != null);
+ }
+ return null;
+ }
+ }
+
+ /* ---------------- TreeBins -------------- */
+
+ /**
+ * TreeNodes used at the heads of bins. TreeBins do not hold user
+ * keys or values, but instead point to list of TreeNodes and
+ * their root. They also maintain a parasitic read-write lock
+ * forcing writers (who hold bin lock) to wait for readers (who do
+ * not) to complete before tree restructuring operations.
+ */
+ static final class TreeBin<K,V> extends Node<K,V> {
+ TreeNode<K,V> root;
+ volatile TreeNode<K,V> first;
+ volatile Thread waiter;
+ volatile int lockState;
+ // values for lockState
+ static final int WRITER = 1; // set while holding write lock
+ static final int WAITER = 2; // set when waiting for write lock
+ static final int READER = 4; // increment value for setting read lock
+
+ /**
+ * Creates bin with initial set of nodes headed by b.
+ */
+ TreeBin(TreeNode<K,V> b) {
+ super(TREEBIN, null, null, null);
+ this.first = b;
+ TreeNode<K,V> r = null;
+ for (TreeNode<K,V> x = b, next; x != null; x = next) {
+ next = (TreeNode<K,V>)x.next;
+ x.left = x.right = null;
+ if (r == null) {
+ x.parent = null;
+ x.red = false;
+ r = x;
}
- else if (nextSegmentIndex >= 0) {
- Segment<K,V> seg = segmentAt(segments, nextSegmentIndex--);
- if (seg != null && (currentTable = seg.table) != null)
- nextTableIndex = currentTable.length - 1;
+ else {
+ Object key = x.key;
+ int hash = x.hash;
+ Class<?> kc = null;
+ for (TreeNode<K,V> p = r;;) {
+ int dir, ph;
+ if ((ph = p.hash) > hash)
+ dir = -1;
+ else if (ph < hash)
+ dir = 1;
+ else if ((kc != null ||
+ (kc = comparableClassFor(key)) != null))
+ dir = compareComparables(kc, key, p.key);
+ else
+ dir = 0;
+ TreeNode<K,V> xp = p;
+ if ((p = (dir <= 0) ? p.left : p.right) == null) {
+ x.parent = xp;
+ if (dir <= 0)
+ xp.left = x;
+ else
+ xp.right = x;
+ r = balanceInsertion(r, x);
+ break;
+ }
+ }
}
- else
+ }
+ this.root = r;
+ }
+
+ /**
+ * Acquires write lock for tree restructuring.
+ */
+ private final void lockRoot() {
+ if (!U.compareAndSwapInt(this, LOCKSTATE, 0, WRITER))
+ contendedLock(); // offload to separate method
+ }
+
+ /**
+ * Releases write lock for tree restructuring.
+ */
+ private final void unlockRoot() {
+ lockState = 0;
+ }
+
+ /**
+ * Possibly blocks awaiting root lock.
+ */
+ private final void contendedLock() {
+ boolean waiting = false;
+ for (int s;;) {
+ if (((s = lockState) & WRITER) == 0) {
+ if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) {
+ if (waiting)
+ waiter = null;
+ return;
+ }
+ }
+ else if ((s & WAITER) == 0) {
+ if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) {
+ waiting = true;
+ waiter = Thread.currentThread();
+ }
+ }
+ else if (waiting)
+ LockSupport.park(this);
+ }
+ }
+
+ /**
+ * Returns matching node or null if none. Tries to search
+ * using tree comparisons from root, but continues linear
+ * search when lock not available.
+ */
+ final Node<K,V> find(int h, Object k) {
+ if (k != null) {
+ for (Node<K,V> e = first; e != null; e = e.next) {
+ int s; K ek;
+ if (((s = lockState) & (WAITER|WRITER)) != 0) {
+ if (e.hash == h &&
+ ((ek = e.key) == k || (ek != null && k.equals(ek))))
+ return e;
+ }
+ else if (U.compareAndSwapInt(this, LOCKSTATE, s,
+ s + READER)) {
+ TreeNode<K,V> r, p;
+ try {
+ p = ((r = root) == null ? null :
+ r.findTreeNode(h, k, null));
+ } finally {
+
+ Thread w;
+ int ls;
+ do {} while (!U.compareAndSwapInt
+ (this, LOCKSTATE,
+ ls = lockState, ls - READER));
+ if (ls == (READER|WAITER) && (w = waiter) != null)
+ LockSupport.unpark(w);
+ }
+ return p;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Finds or adds a node.
+ * @return null if added
+ */
+ final TreeNode<K,V> putTreeVal(int h, K k, V v) {
+ Class<?> kc = null;
+ for (TreeNode<K,V> p = root;;) {
+ int dir, ph; K pk; TreeNode<K,V> q, pr;
+ if (p == null) {
+ first = root = new TreeNode<K,V>(h, k, v, null, null);
+ break;
+ }
+ else if ((ph = p.hash) > h)
+ dir = -1;
+ else if (ph < h)
+ dir = 1;
+ else if ((pk = p.key) == k || (pk != null && k.equals(pk)))
+ return p;
+ else if ((kc == null &&
+ (kc = comparableClassFor(k)) == null) ||
+ (dir = compareComparables(kc, k, pk)) == 0) {
+ if (p.left == null)
+ dir = 1;
+ else if ((pr = p.right) == null ||
+ (q = pr.findTreeNode(h, k, kc)) == null)
+ dir = -1;
+ else
+ return q;
+ }
+ TreeNode<K,V> xp = p;
+ if ((p = (dir < 0) ? p.left : p.right) == null) {
+ TreeNode<K,V> x, f = first;
+ first = x = new TreeNode<K,V>(h, k, v, f, xp);
+ if (f != null)
+ f.prev = x;
+ if (dir < 0)
+ xp.left = x;
+ else
+ xp.right = x;
+ if (!xp.red)
+ x.red = true;
+ else {
+ lockRoot();
+ try {
+ root = balanceInsertion(root, x);
+ } finally {
+ unlockRoot();
+ }
+ }
break;
+ }
}
+ assert checkInvariants(root);
+ return null;
}
- final HashEntry<K,V> nextEntry() {
- HashEntry<K,V> e = nextEntry;
- if (e == null)
- throw new NoSuchElementException();
- lastReturned = e; // cannot assign until after null check
- if ((nextEntry = e.next) == null)
- advance();
- return e;
+ /**
+ * Removes the given node, that must be present before this
+ * call. This is messier than typical red-black deletion code
+ * because we cannot swap the contents of an interior node
+ * with a leaf successor that is pinned by "next" pointers
+ * that are accessible independently of lock. So instead we
+ * swap the tree linkages.
+ *
+ * @return true if now too small, so should be untreeified
+ */
+ final boolean removeTreeNode(TreeNode<K,V> p) {
+ TreeNode<K,V> next = (TreeNode<K,V>)p.next;
+ TreeNode<K,V> pred = p.prev; // unlink traversal pointers
+ TreeNode<K,V> r, rl;
+ if (pred == null)
+ first = next;
+ else
+ pred.next = next;
+ if (next != null)
+ next.prev = pred;
+ if (first == null) {
+ root = null;
+ return true;
+ }
+ if ((r = root) == null || r.right == null || // too small
+ (rl = r.left) == null || rl.left == null)
+ return true;
+ lockRoot();
+ try {
+ TreeNode<K,V> replacement;
+ TreeNode<K,V> pl = p.left;
+ TreeNode<K,V> pr = p.right;
+ if (pl != null && pr != null) {
+ TreeNode<K,V> s = pr, sl;
+ while ((sl = s.left) != null) // find successor
+ s = sl;
+ boolean c = s.red; s.red = p.red; p.red = c; // swap colors
+ TreeNode<K,V> sr = s.right;
+ TreeNode<K,V> pp = p.parent;
+ if (s == pr) { // p was s's direct parent
+ p.parent = s;
+ s.right = p;
+ }
+ else {
+ TreeNode<K,V> sp = s.parent;
+ if ((p.parent = sp) != null) {
+ if (s == sp.left)
+ sp.left = p;
+ else
+ sp.right = p;
+ }
+ if ((s.right = pr) != null)
+ pr.parent = s;
+ }
+ p.left = null;
+ if ((p.right = sr) != null)
+ sr.parent = p;
+ if ((s.left = pl) != null)
+ pl.parent = s;
+ if ((s.parent = pp) == null)
+ r = s;
+ else if (p == pp.left)
+ pp.left = s;
+ else
+ pp.right = s;
+ if (sr != null)
+ replacement = sr;
+ else
+ replacement = p;
+ }
+ else if (pl != null)
+ replacement = pl;
+ else if (pr != null)
+ replacement = pr;
+ else
+ replacement = p;
+ if (replacement != p) {
+ TreeNode<K,V> pp = replacement.parent = p.parent;
+ if (pp == null)
+ r = replacement;
+ else if (p == pp.left)
+ pp.left = replacement;
+ else
+ pp.right = replacement;
+ p.left = p.right = p.parent = null;
+ }
+
+ root = (p.red) ? r : balanceDeletion(r, replacement);
+
+ if (p == replacement) { // detach pointers
+ TreeNode<K,V> pp;
+ if ((pp = p.parent) != null) {
+ if (p == pp.left)
+ pp.left = null;
+ else if (p == pp.right)
+ pp.right = null;
+ p.parent = null;
+ }
+ }
+ } finally {
+ unlockRoot();
+ }
+ assert checkInvariants(root);
+ return false;
+ }
+
+ /* ------------------------------------------------------------ */
+ // Red-black tree methods, all adapted from CLR
+
+ static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,
+ TreeNode<K,V> p) {
+ TreeNode<K,V> r, pp, rl;
+ if (p != null && (r = p.right) != null) {
+ if ((rl = p.right = r.left) != null)
+ rl.parent = p;
+ if ((pp = r.parent = p.parent) == null)
+ (root = r).red = false;
+ else if (pp.left == p)
+ pp.left = r;
+ else
+ pp.right = r;
+ r.left = p;
+ p.parent = r;
+ }
+ return root;
+ }
+
+ static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root,
+ TreeNode<K,V> p) {
+ TreeNode<K,V> l, pp, lr;
+ if (p != null && (l = p.left) != null) {
+ if ((lr = p.left = l.right) != null)
+ lr.parent = p;
+ if ((pp = l.parent = p.parent) == null)
+ (root = l).red = false;
+ else if (pp.right == p)
+ pp.right = l;
+ else
+ pp.left = l;
+ l.right = p;
+ p.parent = l;
+ }
+ return root;
}
- public final boolean hasNext() { return nextEntry != null; }
- public final boolean hasMoreElements() { return nextEntry != null; }
+ static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
+ TreeNode<K,V> x) {
+ x.red = true;
+ for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
+ if ((xp = x.parent) == null) {
+ x.red = false;
+ return x;
+ }
+ else if (!xp.red || (xpp = xp.parent) == null)
+ return root;
+ if (xp == (xppl = xpp.left)) {
+ if ((xppr = xpp.right) != null && xppr.red) {
+ xppr.red = false;
+ xp.red = false;
+ xpp.red = true;
+ x = xpp;
+ }
+ else {
+ if (x == xp.right) {
+ root = rotateLeft(root, x = xp);
+ xpp = (xp = x.parent) == null ? null : xp.parent;
+ }
+ if (xp != null) {
+ xp.red = false;
+ if (xpp != null) {
+ xpp.red = true;
+ root = rotateRight(root, xpp);
+ }
+ }
+ }
+ }
+ else {
+ if (xppl != null && xppl.red) {
+ xppl.red = false;
+ xp.red = false;
+ xpp.red = true;
+ x = xpp;
+ }
+ else {
+ if (x == xp.left) {
+ root = rotateRight(root, x = xp);
+ xpp = (xp = x.parent) == null ? null : xp.parent;
+ }
+ if (xp != null) {
+ xp.red = false;
+ if (xpp != null) {
+ xpp.red = true;
+ root = rotateLeft(root, xpp);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root,
+ TreeNode<K,V> x) {
+ for (TreeNode<K,V> xp, xpl, xpr;;) {
+ if (x == null || x == root)
+ return root;
+ else if ((xp = x.parent) == null) {
+ x.red = false;
+ return x;
+ }
+ else if (x.red) {
+ x.red = false;
+ return root;
+ }
+ else if ((xpl = xp.left) == x) {
+ if ((xpr = xp.right) != null && xpr.red) {
+ xpr.red = false;
+ xp.red = true;
+ root = rotateLeft(root, xp);
+ xpr = (xp = x.parent) == null ? null : xp.right;
+ }
+ if (xpr == null)
+ x = xp;
+ else {
+ TreeNode<K,V> sl = xpr.left, sr = xpr.right;
+ if ((sr == null || !sr.red) &&
+ (sl == null || !sl.red)) {
+ xpr.red = true;
+ x = xp;
+ }
+ else {
+ if (sr == null || !sr.red) {
+ if (sl != null)
+ sl.red = false;
+ xpr.red = true;
+ root = rotateRight(root, xpr);
+ xpr = (xp = x.parent) == null ?
+ null : xp.right;
+ }
+ if (xpr != null) {
+ xpr.red = (xp == null) ? false : xp.red;
+ if ((sr = xpr.right) != null)
+ sr.red = false;
+ }
+ if (xp != null) {
+ xp.red = false;
+ root = rotateLeft(root, xp);
+ }
+ x = root;
+ }
+ }
+ }
+ else { // symmetric
+ if (xpl != null && xpl.red) {
+ xpl.red = false;
+ xp.red = true;
+ root = rotateRight(root, xp);
+ xpl = (xp = x.parent) == null ? null : xp.left;
+ }
+ if (xpl == null)
+ x = xp;
+ else {
+ TreeNode<K,V> sl = xpl.left, sr = xpl.right;
+ if ((sl == null || !sl.red) &&
+ (sr == null || !sr.red)) {
+ xpl.red = true;
+ x = xp;
+ }
+ else {
+ if (sl == null || !sl.red) {
+ if (sr != null)
+ sr.red = false;
+ xpl.red = true;
+ root = rotateLeft(root, xpl);
+ xpl = (xp = x.parent) == null ?
+ null : xp.left;
+ }
+ if (xpl != null) {
+ xpl.red = (xp == null) ? false : xp.red;
+ if ((sl = xpl.left) != null)
+ sl.red = false;
+ }
+ if (xp != null) {
+ xp.red = false;
+ root = rotateRight(root, xp);
+ }
+ x = root;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Recursive invariant check
+ */
+ static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
+ TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
+ tb = t.prev, tn = (TreeNode<K,V>)t.next;
+ if (tb != null && tb.next != t)
+ return false;
+ if (tn != null && tn.prev != t)
+ return false;
+ if (tp != null && t != tp.left && t != tp.right)
+ return false;
+ if (tl != null && (tl.parent != t || tl.hash > t.hash))
+ return false;
+ if (tr != null && (tr.parent != t || tr.hash < t.hash))
+ return false;
+ if (t.red && tl != null && tl.red && tr != null && tr.red)
+ return false;
+ if (tl != null && !checkInvariants(tl))
+ return false;
+ if (tr != null && !checkInvariants(tr))
+ return false;
+ return true;
+ }
+
+ private static final sun.misc.Unsafe U;
+ private static final long LOCKSTATE;
+ static {
+ try {
+ U = sun.misc.Unsafe.getUnsafe();
+ Class<?> k = TreeBin.class;
+ LOCKSTATE = U.objectFieldOffset
+ (k.getDeclaredField("lockState"));
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+ }
+
+ /* ----------------Table Traversal -------------- */
+
+ /**
+ * Encapsulates traversal for methods such as containsValue; also
+ * serves as a base class for other iterators.
+ *
+ * Method advance visits once each still-valid node that was
+ * reachable upon iterator construction. It might miss some that
+ * were added to a bin after the bin was visited, which is OK wrt
+ * consistency guarantees. Maintaining this property in the face
+ * of possible ongoing resizes requires a fair amount of
+ * bookkeeping state that is difficult to optimize away amidst
+ * volatile accesses. Even so, traversal maintains reasonable
+ * throughput.
+ *
+ * Normally, iteration proceeds bin-by-bin traversing lists.
+ * However, if the table has been resized, then all future steps
+ * must traverse both the bin at the current index as well as at
+ * (index + baseSize); and so on for further resizings. To
+ * paranoically cope with potential sharing by users of iterators
+ * across threads, iteration terminates if a bounds checks fails
+ * for a table read.
+ */
+ static class Traverser<K,V> {
+ Node<K,V>[] tab; // current table; updated if resized
+ Node<K,V> next; // the next entry to use
+ int index; // index of bin to use next
+ int baseIndex; // current index of initial table
+ int baseLimit; // index bound for initial table
+ final int baseSize; // initial table size
+
+ Traverser(Node<K,V>[] tab, int size, int index, int limit) {
+ this.tab = tab;
+ this.baseSize = size;
+ this.baseIndex = this.index = index;
+ this.baseLimit = limit;
+ this.next = null;
+ }
+
+ /**
+ * Advances if possible, returning next valid node, or null if none.
+ */
+ final Node<K,V> advance() {
+ Node<K,V> e;
+ if ((e = next) != null)
+ e = e.next;
+ for (;;) {
+ Node<K,V>[] t; int i, n; K ek; // must use locals in checks
+ if (e != null)
+ return next = e;
+ if (baseIndex >= baseLimit || (t = tab) == null ||
+ (n = t.length) <= (i = index) || i < 0)
+ return next = null;
+ if ((e = tabAt(t, index)) != null && e.hash < 0) {
+ if (e instanceof ForwardingNode) {
+ tab = ((ForwardingNode<K,V>)e).nextTable;
+ e = null;
+ continue;
+ }
+ else if (e instanceof TreeBin)
+ e = ((TreeBin<K,V>)e).first;
+ else
+ e = null;
+ }
+ if ((index += baseSize) >= n)
+ index = ++baseIndex; // visit upper slots if present
+ }
+ }
+ }
+
+ /**
+ * Base of key, value, and entry Iterators. Adds fields to
+ * Traverser to support iterator.remove.
+ */
+ static class BaseIterator<K,V> extends Traverser<K,V> {
+ final ConcurrentHashMap<K,V> map;
+ Node<K,V> lastReturned;
+ BaseIterator(Node<K,V>[] tab, int size, int index, int limit,
+ ConcurrentHashMap<K,V> map) {
+ super(tab, size, index, limit);
+ this.map = map;
+ advance();
+ }
+
+ public final boolean hasNext() { return next != null; }
+ public final boolean hasMoreElements() { return next != null; }
public final void remove() {
- if (lastReturned == null)
+ Node<K,V> p;
+ if ((p = lastReturned) == null)
throw new IllegalStateException();
- ConcurrentHashMap.this.remove(lastReturned.key);
lastReturned = null;
+ map.replaceNode(p.key, null, null);
+ }
+ }
+
+ static final class KeyIterator<K,V> extends BaseIterator<K,V>
+ implements Iterator<K>, Enumeration<K> {
+ KeyIterator(Node<K,V>[] tab, int index, int size, int limit,
+ ConcurrentHashMap<K,V> map) {
+ super(tab, index, size, limit, map);
+ }
+
+ public final K next() {
+ Node<K,V> p;
+ if ((p = next) == null)
+ throw new NoSuchElementException();
+ K k = p.key;
+ lastReturned = p;
+ advance();
+ return k;
}
+
+ public final K nextElement() { return next(); }
}
- final class KeyIterator
- extends HashIterator
- implements Iterator<K>, Enumeration<K>
- {
- public final K next() { return super.nextEntry().key; }
- public final K nextElement() { return super.nextEntry().key; }
+ static final class ValueIterator<K,V> extends BaseIterator<K,V>
+ implements Iterator<V>, Enumeration<V> {
+ ValueIterator(Node<K,V>[] tab, int index, int size, int limit,
+ ConcurrentHashMap<K,V> map) {
+ super(tab, index, size, limit, map);
+ }
+
+ public final V next() {
+ Node<K,V> p;
+ if ((p = next) == null)
+ throw new NoSuchElementException();
+ V v = p.val;
+ lastReturned = p;
+ advance();
+ return v;
+ }
+
+ public final V nextElement() { return next(); }
}
- final class ValueIterator
- extends HashIterator
- implements Iterator<V>, Enumeration<V>
- {
- public final V next() { return super.nextEntry().value; }
- public final V nextElement() { return super.nextEntry().value; }
+ static final class EntryIterator<K,V> extends BaseIterator<K,V>
+ implements Iterator<Map.Entry<K,V>> {
+ EntryIterator(Node<K,V>[] tab, int index, int size, int limit,
+ ConcurrentHashMap<K,V> map) {
+ super(tab, index, size, limit, map);
+ }
+
+ public final Map.Entry<K,V> next() {
+ Node<K,V> p;
+ if ((p = next) == null)
+ throw new NoSuchElementException();
+ K k = p.key;
+ V v = p.val;
+ lastReturned = p;
+ advance();
+ return new MapEntry<K,V>(k, v, map);
+ }
}
/**
- * Custom Entry class used by EntryIterator.next(), that relays
- * setValue changes to the underlying map.
+ * Exported Entry for EntryIterator
*/
- final class WriteThroughEntry
- extends AbstractMap.SimpleEntry<K,V>
- {
- WriteThroughEntry(K k, V v) {
- super(k,v);
+ static final class MapEntry<K,V> implements Map.Entry<K,V> {
+ final K key; // non-null
+ V val; // non-null
+ final ConcurrentHashMap<K,V> map;
+ MapEntry(K key, V val, ConcurrentHashMap<K,V> map) {
+ this.key = key;
+ this.val = val;
+ this.map = map;
+ }
+ public K getKey() { return key; }
+ public V getValue() { return val; }
+ public int hashCode() { return key.hashCode() ^ val.hashCode(); }
+ public String toString() { return key + "=" + val; }
+
+ public boolean equals(Object o) {
+ Object k, v; Map.Entry<?,?> e;
+ return ((o instanceof Map.Entry) &&
+ (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+ (v = e.getValue()) != null &&
+ (k == key || k.equals(key)) &&
+ (v == val || v.equals(val)));
}
/**
* Sets our entry's value and writes through to the map. The
- * value to return is somewhat arbitrary here. Since a
- * WriteThroughEntry does not necessarily track asynchronous
- * changes, the most recent "previous" value could be
- * different from what we return (or could even have been
- * removed in which case the put will re-establish). We do not
- * and cannot guarantee more.
+ * value to return is somewhat arbitrary here. Since we do not
+ * necessarily track asynchronous changes, the most recent
+ * "previous" value could be different from what we return (or
+ * could even have been removed, in which case the put will
+ * re-establish). We do not and cannot guarantee more.
*/
public V setValue(V value) {
if (value == null) throw new NullPointerException();
- V v = super.setValue(value);
- ConcurrentHashMap.this.put(getKey(), value);
+ V v = val;
+ val = value;
+ map.put(key, value);
return v;
}
}
- final class EntryIterator
- extends HashIterator
- implements Iterator<Entry<K,V>>
- {
- public Map.Entry<K,V> next() {
- HashEntry<K,V> e = super.nextEntry();
- return new WriteThroughEntry(e.key, e.value);
+ /* ----------------Views -------------- */
+
+ /**
+ * Base class for views.
+ *
+ */
+ abstract static class CollectionView<K,V,E>
+ implements Collection<E>, java.io.Serializable {
+ private static final long serialVersionUID = 7249069246763182397L;
+ final ConcurrentHashMap<K,V> map;
+ CollectionView(ConcurrentHashMap<K,V> map) { this.map = map; }
+
+ /**
+ * Returns the map backing this view.
+ *
+ * @return the map backing this view
+ */
+ public ConcurrentHashMap<K,V> getMap() { return map; }
+
+ /**
+ * Removes all of the elements from this view, by removing all
+ * the mappings from the map backing this view.
+ */
+ public final void clear() { map.clear(); }
+ public final int size() { return map.size(); }
+ public final boolean isEmpty() { return map.isEmpty(); }
+
+ // implementations below rely on concrete classes supplying these
+ // abstract methods
+ /**
+ * Returns a "weakly consistent" iterator that will never
+ * throw {@link ConcurrentModificationException}, and
+ * guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not
+ * guaranteed to) reflect any modifications subsequent to
+ * construction.
+ */
+ public abstract Iterator<E> iterator();
+ public abstract boolean contains(Object o);
+ public abstract boolean remove(Object o);
+
+ private static final String oomeMsg = "Required array size too large";
+
+ public final Object[] toArray() {
+ long sz = map.mappingCount();
+ if (sz > MAX_ARRAY_SIZE)
+ throw new OutOfMemoryError(oomeMsg);
+ int n = (int)sz;
+ Object[] r = new Object[n];
+ int i = 0;
+ for (E e : this) {
+ if (i == n) {
+ if (n >= MAX_ARRAY_SIZE)
+ throw new OutOfMemoryError(oomeMsg);
+ if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
+ n = MAX_ARRAY_SIZE;
+ else
+ n += (n >>> 1) + 1;
+ r = Arrays.copyOf(r, n);
+ }
+ r[i++] = e;
+ }
+ return (i == n) ? r : Arrays.copyOf(r, i);
+ }
+
+ @SuppressWarnings("unchecked")
+ public final <T> T[] toArray(T[] a) {
+ long sz = map.mappingCount();
+ if (sz > MAX_ARRAY_SIZE)
+ throw new OutOfMemoryError(oomeMsg);
+ int m = (int)sz;
+ T[] r = (a.length >= m) ? a :
+ (T[])java.lang.reflect.Array
+ .newInstance(a.getClass().getComponentType(), m);
+ int n = r.length;
+ int i = 0;
+ for (E e : this) {
+ if (i == n) {
+ if (n >= MAX_ARRAY_SIZE)
+ throw new OutOfMemoryError(oomeMsg);
+ if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
+ n = MAX_ARRAY_SIZE;
+ else
+ n += (n >>> 1) + 1;
+ r = Arrays.copyOf(r, n);
+ }
+ r[i++] = (T)e;
+ }
+ if (a == r && i < n) {
+ r[i] = null; // null-terminate
+ return r;
+ }
+ return (i == n) ? r : Arrays.copyOf(r, i);
+ }
+
+ /**
+ * Returns a string representation of this collection.
+ * The string representation consists of the string representations
+ * of the collection's elements in the order they are returned by
+ * its iterator, enclosed in square brackets ({@code "[]"}).
+ * Adjacent elements are separated by the characters {@code ", "}
+ * (comma and space). Elements are converted to strings as by
+ * {@link String#valueOf(Object)}.
+ *
+ * @return a string representation of this collection
+ */
+ public final String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append('[');
+ Iterator<E> it = iterator();
+ if (it.hasNext()) {
+ for (;;) {
+ Object e = it.next();
+ sb.append(e == this ? "(this Collection)" : e);
+ if (!it.hasNext())
+ break;
+ sb.append(',').append(' ');
+ }
+ }
+ return sb.append(']').toString();
}
+
+ public final boolean containsAll(Collection<?> c) {
+ if (c != this) {
+ for (Object e : c) {
+ if (e == null || !contains(e))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public final boolean removeAll(Collection<?> c) {
+ boolean modified = false;
+ for (Iterator<E> it = iterator(); it.hasNext();) {
+ if (c.contains(it.next())) {
+ it.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ public final boolean retainAll(Collection<?> c) {
+ boolean modified = false;
+ for (Iterator<E> it = iterator(); it.hasNext();) {
+ if (!c.contains(it.next())) {
+ it.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
}
- final class KeySet extends AbstractSet<K> {
- public Iterator<K> iterator() {
- return new KeyIterator();
+ /**
+ * A view of a ConcurrentHashMap as a {@link Set} of keys, in
+ * which additions may optionally be enabled by mapping to a
+ * common value. This class cannot be directly instantiated.
+ * See {@link #keySet() keySet()},
+ * {@link #keySet(Object) keySet(V)},
+ * {@link #newKeySet() newKeySet()},
+ * {@link #newKeySet(int) newKeySet(int)}.
+ *
+ * @since 1.8
+ *
+ * @hide
+ */
+ public static class KeySetView<K,V> extends CollectionView<K,V,K>
+ implements Set<K>, java.io.Serializable {
+ private static final long serialVersionUID = 7249069246763182397L;
+ private final V value;
+ KeySetView(ConcurrentHashMap<K,V> map, V value) { // non-public
+ super(map);
+ this.value = value;
}
- public int size() {
- return ConcurrentHashMap.this.size();
+
+ /**
+ * Returns the default mapped value for additions,
+ * or {@code null} if additions are not supported.
+ *
+ * @return the default mapped value for additions, or {@code null}
+ * if not supported
+ */
+ public V getMappedValue() { return value; }
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the specified key is null
+ */
+ public boolean contains(Object o) { return map.containsKey(o); }
+
+ /**
+ * Removes the key from this map view, by removing the key (and its
+ * corresponding value) from the backing map. This method does
+ * nothing if the key is not in the map.
+ *
+ * @param o the key to be removed from the backing map
+ * @return {@code true} if the backing map contained the specified key
+ * @throws NullPointerException if the specified key is null
+ */
+ public boolean remove(Object o) { return map.remove(o) != null; }
+
+ /**
+ * @return an iterator over the keys of the backing map
+ */
+ public Iterator<K> iterator() {
+ Node<K,V>[] t;
+ ConcurrentHashMap<K,V> m = map;
+ int f = (t = m.table) == null ? 0 : t.length;
+ return new KeyIterator<K,V>(t, f, 0, f, m);
}
- public boolean isEmpty() {
- return ConcurrentHashMap.this.isEmpty();
+
+ /**
+ * Adds the specified key to this set view by mapping the key to
+ * the default mapped value in the backing map, if defined.
+ *
+ * @param e key to be added
+ * @return {@code true} if this set changed as a result of the call
+ * @throws NullPointerException if the specified key is null
+ * @throws UnsupportedOperationException if no default mapped value
+ * for additions was provided
+ */
+ public boolean add(K e) {
+ V v;
+ if ((v = value) == null)
+ throw new UnsupportedOperationException();
+ return map.putVal(e, v, true) == null;
}
- public boolean contains(Object o) {
- return ConcurrentHashMap.this.containsKey(o);
+
+ /**
+ * Adds all of the elements in the specified collection to this set,
+ * as if by calling {@link #add} on each one.
+ *
+ * @param c the elements to be inserted into this set
+ * @return {@code true} if this set changed as a result of the call
+ * @throws NullPointerException if the collection or any of its
+ * elements are {@code null}
+ * @throws UnsupportedOperationException if no default mapped value
+ * for additions was provided
+ */
+ public boolean addAll(Collection<? extends K> c) {
+ boolean added = false;
+ V v;
+ if ((v = value) == null)
+ throw new UnsupportedOperationException();
+ for (K e : c) {
+ if (map.putVal(e, v, true) == null)
+ added = true;
+ }
+ return added;
}
- public boolean remove(Object o) {
- return ConcurrentHashMap.this.remove(o) != null;
+
+ public int hashCode() {
+ int h = 0;
+ for (K e : this)
+ h += e.hashCode();
+ return h;
}
- public void clear() {
- ConcurrentHashMap.this.clear();
+
+ public boolean equals(Object o) {
+ Set<?> c;
+ return ((o instanceof Set) &&
+ ((c = (Set<?>)o) == this ||
+ (containsAll(c) && c.containsAll(this))));
}
+
}
- final class Values extends AbstractCollection<V> {
- public Iterator<V> iterator() {
- return new ValueIterator();
+ /**
+ * A view of a ConcurrentHashMap as a {@link Collection} of
+ * values, in which additions are disabled. This class cannot be
+ * directly instantiated. See {@link #values()}.
+ */
+ static final class ValuesView<K,V> extends CollectionView<K,V,V>
+ implements Collection<V>, java.io.Serializable {
+ private static final long serialVersionUID = 2249069246763182397L;
+ ValuesView(ConcurrentHashMap<K,V> map) { super(map); }
+ public final boolean contains(Object o) {
+ return map.containsValue(o);
}
- public int size() {
- return ConcurrentHashMap.this.size();
+
+ public final boolean remove(Object o) {
+ if (o != null) {
+ for (Iterator<V> it = iterator(); it.hasNext();) {
+ if (o.equals(it.next())) {
+ it.remove();
+ return true;
+ }
+ }
+ }
+ return false;
}
- public boolean isEmpty() {
- return ConcurrentHashMap.this.isEmpty();
+
+ public final Iterator<V> iterator() {
+ ConcurrentHashMap<K,V> m = map;
+ Node<K,V>[] t;
+ int f = (t = m.table) == null ? 0 : t.length;
+ return new ValueIterator<K,V>(t, f, 0, f, m);
}
- public boolean contains(Object o) {
- return ConcurrentHashMap.this.containsValue(o);
+
+ public final boolean add(V e) {
+ throw new UnsupportedOperationException();
}
- public void clear() {
- ConcurrentHashMap.this.clear();
+ public final boolean addAll(Collection<? extends V> c) {
+ throw new UnsupportedOperationException();
}
+
}
- final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
- public Iterator<Map.Entry<K,V>> iterator() {
- return new EntryIterator();
- }
+ /**
+ * A view of a ConcurrentHashMap as a {@link Set} of (key, value)
+ * entries. This class cannot be directly instantiated. See
+ * {@link #entrySet()}.
+ */
+ static final class EntrySetView<K,V> extends CollectionView<K,V,Map.Entry<K,V>>
+ implements Set<Map.Entry<K,V>>, java.io.Serializable {
+ private static final long serialVersionUID = 2249069246763182397L;
+ EntrySetView(ConcurrentHashMap<K,V> map) { super(map); }
+
public boolean contains(Object o) {
- if (!(o instanceof Map.Entry))
- return false;
- Map.Entry<?,?> e = (Map.Entry<?,?>)o;
- V v = ConcurrentHashMap.this.get(e.getKey());
- return v != null && v.equals(e.getValue());
+ Object k, v, r; Map.Entry<?,?> e;
+ return ((o instanceof Map.Entry) &&
+ (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+ (r = map.get(k)) != null &&
+ (v = e.getValue()) != null &&
+ (v == r || v.equals(r)));
}
+
public boolean remove(Object o) {
- if (!(o instanceof Map.Entry))
- return false;
- Map.Entry<?,?> e = (Map.Entry<?,?>)o;
- return ConcurrentHashMap.this.remove(e.getKey(), e.getValue());
+ Object k, v; Map.Entry<?,?> e;
+ return ((o instanceof Map.Entry) &&
+ (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+ (v = e.getValue()) != null &&
+ map.remove(k, v));
}
- public int size() {
- return ConcurrentHashMap.this.size();
+
+ /**
+ * @return an iterator over the entries of the backing map
+ */
+ public Iterator<Map.Entry<K,V>> iterator() {
+ ConcurrentHashMap<K,V> m = map;
+ Node<K,V>[] t;
+ int f = (t = m.table) == null ? 0 : t.length;
+ return new EntryIterator<K,V>(t, f, 0, f, m);
}
- public boolean isEmpty() {
- return ConcurrentHashMap.this.isEmpty();
+
+ public boolean add(Entry<K,V> e) {
+ return map.putVal(e.getKey(), e.getValue(), false) == null;
}
- public void clear() {
- ConcurrentHashMap.this.clear();
+
+ public boolean addAll(Collection<? extends Entry<K,V>> c) {
+ boolean added = false;
+ for (Entry<K,V> e : c) {
+ if (add(e))
+ added = true;
+ }
+ return added;
}
+
+ public final int hashCode() {
+ int h = 0;
+ Node<K,V>[] t;
+ if ((t = map.table) != null) {
+ Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+ for (Node<K,V> p; (p = it.advance()) != null; ) {
+ h += p.hashCode();
+ }
+ }
+ return h;
+ }
+
+ public final boolean equals(Object o) {
+ Set<?> c;
+ return ((o instanceof Set) &&
+ ((c = (Set<?>)o) == this ||
+ (containsAll(c) && c.containsAll(this))));
+ }
+
}
- /* ---------------- Serialization Support -------------- */
+
+ /* ---------------- Counters -------------- */
+
+ // Adapted from LongAdder and Striped64.
+ // See their internal docs for explanation.
+
+ // A padded cell for distributing counts
+ static final class CounterCell {
+ volatile long p0, p1, p2, p3, p4, p5, p6;
+ volatile long value;
+ volatile long q0, q1, q2, q3, q4, q5, q6;
+ CounterCell(long x) { value = x; }
+ }
/**
- * Saves the state of the <tt>ConcurrentHashMap</tt> instance to a
- * stream (i.e., serializes it).
- * @param s the stream
- * @serialData
- * the key (Object) and value (Object)
- * for each key-value mapping, followed by a null pair.
- * The key-value mappings are emitted in no particular order.
+ * Holder for the thread-local hash code determining which
+ * CounterCell to use. The code is initialized via the
+ * counterHashCodeGenerator, but may be moved upon collisions.
*/
- private void writeObject(java.io.ObjectOutputStream s)
- throws java.io.IOException {
- // force all segments for serialization compatibility
- for (int k = 0; k < segments.length; ++k)
- ensureSegment(k);
- s.defaultWriteObject();
-
- final Segment<K,V>[] segments = this.segments;
- for (int k = 0; k < segments.length; ++k) {
- Segment<K,V> seg = segmentAt(segments, k);
- seg.lock();
- try {
- HashEntry<K,V>[] tab = seg.table;
- for (int i = 0; i < tab.length; ++i) {
- HashEntry<K,V> e;
- for (e = entryAt(tab, i); e != null; e = e.next) {
- s.writeObject(e.key);
- s.writeObject(e.value);
- }
- }
- } finally {
- seg.unlock();
- }
- }
- s.writeObject(null);
- s.writeObject(null);
+ static final class CounterHashCode {
+ int code;
}
/**
- * Reconstitutes the <tt>ConcurrentHashMap</tt> instance from a
- * stream (i.e., deserializes it).
- * @param s the stream
+ * Generates initial value for per-thread CounterHashCodes.
*/
- @SuppressWarnings("unchecked")
- private void readObject(java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException {
- s.defaultReadObject();
+ static final AtomicInteger counterHashCodeGenerator = new AtomicInteger();
- // Re-initialize segments to be minimally sized, and let grow.
- int cap = MIN_SEGMENT_TABLE_CAPACITY;
- final Segment<K,V>[] segments = this.segments;
- for (int k = 0; k < segments.length; ++k) {
- Segment<K,V> seg = segments[k];
- if (seg != null) {
- seg.threshold = (int)(cap * seg.loadFactor);
- seg.table = (HashEntry<K,V>[]) new HashEntry<?,?>[cap];
+ /**
+ * Increment for counterHashCodeGenerator. See class ThreadLocal
+ * for explanation.
+ */
+ static final int SEED_INCREMENT = 0x61c88647;
+
+ /**
+ * Per-thread counter hash codes. Shared across all instances.
+ */
+ static final ThreadLocal<CounterHashCode> threadCounterHashCode =
+ new ThreadLocal<CounterHashCode>();
+
+ final long sumCount() {
+ CounterCell[] as = counterCells; CounterCell a;
+ long sum = baseCount;
+ if (as != null) {
+ for (int i = 0; i < as.length; ++i) {
+ if ((a = as[i]) != null)
+ sum += a.value;
}
}
+ return sum;
+ }
- // Read the keys and values, and put the mappings in the table
+ // See LongAdder version for explanation
+ private final void fullAddCount(long x, CounterHashCode hc,
+ boolean wasUncontended) {
+ int h;
+ if (hc == null) {
+ hc = new CounterHashCode();
+ int s = counterHashCodeGenerator.addAndGet(SEED_INCREMENT);
+ h = hc.code = (s == 0) ? 1 : s; // Avoid zero
+ threadCounterHashCode.set(hc);
+ }
+ else
+ h = hc.code;
+ boolean collide = false; // True if last slot nonempty
for (;;) {
- K key = (K) s.readObject();
- V value = (V) s.readObject();
- if (key == null)
- break;
- put(key, value);
+ CounterCell[] as; CounterCell a; int n; long v;
+ if ((as = counterCells) != null && (n = as.length) > 0) {
+ if ((a = as[(n - 1) & h]) == null) {
+ if (cellsBusy == 0) { // Try to attach new Cell
+ CounterCell r = new CounterCell(x); // Optimistic create
+ if (cellsBusy == 0 &&
+ U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
+ boolean created = false;
+ try { // Recheck under lock
+ CounterCell[] rs; int m, j;
+ if ((rs = counterCells) != null &&
+ (m = rs.length) > 0 &&
+ rs[j = (m - 1) & h] == null) {
+ rs[j] = r;
+ created = true;
+ }
+ } finally {
+ cellsBusy = 0;
+ }
+ if (created)
+ break;
+ continue; // Slot is now non-empty
+ }
+ }
+ collide = false;
+ }
+ else if (!wasUncontended) // CAS already known to fail
+ wasUncontended = true; // Continue after rehash
+ else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))
+ break;
+ else if (counterCells != as || n >= NCPU)
+ collide = false; // At max size or stale
+ else if (!collide)
+ collide = true;
+ else if (cellsBusy == 0 &&
+ U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
+ try {
+ if (counterCells == as) {// Expand table unless stale
+ CounterCell[] rs = new CounterCell[n << 1];
+ for (int i = 0; i < n; ++i)
+ rs[i] = as[i];
+ counterCells = rs;
+ }
+ } finally {
+ cellsBusy = 0;
+ }
+ collide = false;
+ continue; // Retry with expanded table
+ }
+ h ^= h << 13; // Rehash
+ h ^= h >>> 17;
+ h ^= h << 5;
+ }
+ else if (cellsBusy == 0 && counterCells == as &&
+ U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
+ boolean init = false;
+ try { // Initialize table
+ if (counterCells == as) {
+ CounterCell[] rs = new CounterCell[2];
+ rs[h & 1] = new CounterCell(x);
+ counterCells = rs;
+ init = true;
+ }
+ } finally {
+ cellsBusy = 0;
+ }
+ if (init)
+ break;
+ }
+ else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x))
+ break; // Fall back on using base
}
+ hc.code = h; // Record index for next time
}
// Unsafe mechanics
- private static final sun.misc.Unsafe UNSAFE;
- private static final long SBASE;
- private static final int SSHIFT;
- private static final long TBASE;
- private static final int TSHIFT;
+ private static final sun.misc.Unsafe U;
+ private static final long SIZECTL;
+ private static final long TRANSFERINDEX;
+ private static final long TRANSFERORIGIN;
+ private static final long BASECOUNT;
+ private static final long CELLSBUSY;
+ private static final long CELLVALUE;
+ private static final long ABASE;
+ private static final int ASHIFT;
static {
- int ss, ts;
try {
- UNSAFE = sun.misc.Unsafe.getUnsafe();
- Class<?> tc = HashEntry[].class;
- Class<?> sc = Segment[].class;
- TBASE = UNSAFE.arrayBaseOffset(tc);
- SBASE = UNSAFE.arrayBaseOffset(sc);
- ts = UNSAFE.arrayIndexScale(tc);
- ss = UNSAFE.arrayIndexScale(sc);
+ U = sun.misc.Unsafe.getUnsafe();
+ Class<?> k = ConcurrentHashMap.class;
+ SIZECTL = U.objectFieldOffset
+ (k.getDeclaredField("sizeCtl"));
+ TRANSFERINDEX = U.objectFieldOffset
+ (k.getDeclaredField("transferIndex"));
+ TRANSFERORIGIN = U.objectFieldOffset
+ (k.getDeclaredField("transferOrigin"));
+ BASECOUNT = U.objectFieldOffset
+ (k.getDeclaredField("baseCount"));
+ CELLSBUSY = U.objectFieldOffset
+ (k.getDeclaredField("cellsBusy"));
+ Class<?> ck = CounterCell.class;
+ CELLVALUE = U.objectFieldOffset
+ (ck.getDeclaredField("value"));
+ Class<?> ak = Node[].class;
+ ABASE = U.arrayBaseOffset(ak);
+ int scale = U.arrayIndexScale(ak);
+ if ((scale & (scale - 1)) != 0)
+ throw new Error("data type scale not a power of two");
+ ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
} catch (Exception e) {
throw new Error(e);
}
- if ((ss & (ss-1)) != 0 || (ts & (ts-1)) != 0)
- throw new Error("data type scale not a power of two");
- SSHIFT = 31 - Integer.numberOfLeadingZeros(ss);
- TSHIFT = 31 - Integer.numberOfLeadingZeros(ts);
}
}
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
index 54b53ae..b38d6a5 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
@@ -56,8 +56,6 @@ import java.util.Queue;
* actions subsequent to the access or removal of that element from
* the {@code ConcurrentLinkedDeque} in another thread.
*
- * @hide
- *
* @since 1.7
* @author Doug Lea
* @author Martin Buchholz
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
index 873f825..b39a533 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
@@ -31,7 +31,7 @@ import java.util.Queue;
* Like most other concurrent collection implementations, this class
* does not permit the use of {@code null} elements.
*
- * <p>This implementation employs an efficient &quot;wait-free&quot;
+ * <p>This implementation employs an efficient <em>non-blocking</em>
* algorithm based on one described in <a
* href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple,
* Fast, and Practical Non-Blocking and Blocking Concurrent Queue
diff --git a/luni/src/main/java/java/util/concurrent/CountedCompleter.java b/luni/src/main/java/java/util/concurrent/CountedCompleter.java
index ffe7582..d5f794e 100644
--- a/luni/src/main/java/java/util/concurrent/CountedCompleter.java
+++ b/luni/src/main/java/java/util/concurrent/CountedCompleter.java
@@ -8,14 +8,15 @@ package java.util.concurrent;
/**
* A {@link ForkJoinTask} with a completion action performed when
- * triggered and there are no remaining pending
- * actions. CountedCompleters are in general more robust in the
+ * triggered and there are no remaining pending actions.
+ * CountedCompleters are in general more robust in the
* presence of subtask stalls and blockage than are other forms of
* ForkJoinTasks, but are less intuitive to program. Uses of
* CountedCompleter are similar to those of other completion based
* components (such as {@link java.nio.channels.CompletionHandler})
* except that multiple <em>pending</em> completions may be necessary
- * to trigger the completion action {@link #onCompletion}, not just one.
+ * to trigger the completion action {@link #onCompletion(CountedCompleter)},
+ * not just one.
* Unless initialized otherwise, the {@linkplain #getPendingCount pending
* count} starts at zero, but may be (atomically) changed using
* methods {@link #setPendingCount}, {@link #addToPendingCount}, and
@@ -40,9 +41,10 @@ package java.util.concurrent;
* <p>A concrete CountedCompleter class must define method {@link
* #compute}, that should in most cases (as illustrated below), invoke
* {@code tryComplete()} once before returning. The class may also
- * optionally override method {@link #onCompletion} to perform an
- * action upon normal completion, and method {@link
- * #onExceptionalCompletion} to perform an action upon any exception.
+ * optionally override method {@link #onCompletion(CountedCompleter)}
+ * to perform an action upon normal completion, and method
+ * {@link #onExceptionalCompletion(Throwable, CountedCompleter)} to
+ * perform an action upon any exception.
*
* <p>CountedCompleters most often do not bear results, in which case
* they are normally declared as {@code CountedCompleter<Void>}, and
@@ -63,13 +65,14 @@ package java.util.concurrent;
* only as an internal helper for other computations, so its own task
* status (as reported in methods such as {@link ForkJoinTask#isDone})
* is arbitrary; this status changes only upon explicit invocations of
- * {@link #complete}, {@link ForkJoinTask#cancel}, {@link
- * ForkJoinTask#completeExceptionally} or upon exceptional completion
- * of method {@code compute}. Upon any exceptional completion, the
- * exception may be relayed to a task's completer (and its completer,
- * and so on), if one exists and it has not otherwise already
- * completed. Similarly, cancelling an internal CountedCompleter has
- * only a local effect on that completer, so is not often useful.
+ * {@link #complete}, {@link ForkJoinTask#cancel},
+ * {@link ForkJoinTask#completeExceptionally(Throwable)} or upon
+ * exceptional completion of method {@code compute}. Upon any
+ * exceptional completion, the exception may be relayed to a task's
+ * completer (and its completer, and so on), if one exists and it has
+ * not otherwise already completed. Similarly, cancelling an internal
+ * CountedCompleter has only a local effect on that completer, so is
+ * not often useful.
*
* <p><b>Sample Usages.</b>
*
@@ -96,8 +99,8 @@ package java.util.concurrent;
* improve load balancing. In the recursive case, the second of each
* pair of subtasks to finish triggers completion of its parent
* (because no result combination is performed, the default no-op
- * implementation of method {@code onCompletion} is not overridden). A
- * static utility method sets up the base task and invokes it
+ * implementation of method {@code onCompletion} is not overridden).
+ * A static utility method sets up the base task and invokes it
* (here, implicitly using the {@link ForkJoinPool#commonPool()}).
*
* <pre> {@code
@@ -152,12 +155,11 @@ package java.util.concurrent;
* }
* }</pre>
*
- * As a further improvement, notice that the left task need not even
- * exist. Instead of creating a new one, we can iterate using the
- * original task, and add a pending count for each fork. Additionally,
- * because no task in this tree implements an {@link #onCompletion}
- * method, {@code tryComplete()} can be replaced with {@link
- * #propagateCompletion}.
+ * As a further improvement, notice that the left task need not even exist.
+ * Instead of creating a new one, we can iterate using the original task,
+ * and add a pending count for each fork. Additionally, because no task
+ * in this tree implements an {@link #onCompletion(CountedCompleter)} method,
+ * {@code tryComplete()} can be replaced with {@link #propagateCompletion}.
*
* <pre> {@code
* class ForEach<E> ...
@@ -235,7 +237,7 @@ package java.util.concurrent;
*
* <p><b>Recording subtasks.</b> CountedCompleter tasks that combine
* results of multiple subtasks usually need to access these results
- * in method {@link #onCompletion}. As illustrated in the following
+ * in method {@link #onCompletion(CountedCompleter)}. As illustrated in the following
* class (that performs a simplified form of map-reduce where mappings
* and reductions are all of type {@code E}), one way to do this in
* divide and conquer designs is to have each subtask record its
@@ -357,7 +359,7 @@ package java.util.concurrent;
*
* <p><b>Triggers.</b> Some CountedCompleters are themselves never
* forked, but instead serve as bits of plumbing in other designs;
- * including those in which the completion of one of more async tasks
+ * including those in which the completion of one or more async tasks
* triggers another async task. For example:
*
* <pre> {@code
@@ -438,20 +440,21 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
}
/**
- * Performs an action when method {@link #completeExceptionally}
- * is invoked or method {@link #compute} throws an exception, and
- * this task has not otherwise already completed normally. On
- * entry to this method, this task {@link
- * ForkJoinTask#isCompletedAbnormally}. The return value of this
- * method controls further propagation: If {@code true} and this
- * task has a completer, then this completer is also completed
- * exceptionally. The default implementation of this method does
- * nothing except return {@code true}.
+ * Performs an action when method {@link
+ * #completeExceptionally(Throwable)} is invoked or method {@link
+ * #compute} throws an exception, and this task has not already
+ * otherwise completed normally. On entry to this method, this task
+ * {@link ForkJoinTask#isCompletedAbnormally}. The return value
+ * of this method controls further propagation: If {@code true}
+ * and this task has a completer that has not completed, then that
+ * completer is also completed exceptionally, with the same
+ * exception as this completer. The default implementation of
+ * this method does nothing except return {@code true}.
*
* @param ex the exception
* @param caller the task invoking this method (which may
* be this task itself)
- * @return true if this exception should be propagated to this
+ * @return {@code true} if this exception should be propagated to this
* task's completer, if one exists
*/
public boolean onExceptionalCompletion(Throwable ex, CountedCompleter<?> caller) {
@@ -492,7 +495,7 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
* @param delta the value to add
*/
public final void addToPendingCount(int delta) {
- int c; // note: can replace with intrinsic in jdk8
+ int c;
do {} while (!U.compareAndSwapInt(this, PENDING, c = pending, c+delta));
}
@@ -502,7 +505,7 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
*
* @param expected the expected value
* @param count the new value
- * @return true if successful
+ * @return {@code true} if successful
*/
public final boolean compareAndSetPendingCount(int expected, int count) {
return U.compareAndSwapInt(this, PENDING, expected, count);
@@ -536,9 +539,9 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
/**
* If the pending count is nonzero, decrements the count;
- * otherwise invokes {@link #onCompletion} and then similarly
- * tries to complete this task's completer, if one exists,
- * else marks this task as complete.
+ * otherwise invokes {@link #onCompletion(CountedCompleter)}
+ * and then similarly tries to complete this task's completer,
+ * if one exists, else marks this task as complete.
*/
public final void tryComplete() {
CountedCompleter<?> a = this, s = a;
@@ -557,12 +560,12 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
/**
* Equivalent to {@link #tryComplete} but does not invoke {@link
- * #onCompletion} along the completion path: If the pending count
- * is nonzero, decrements the count; otherwise, similarly tries to
- * complete this task's completer, if one exists, else marks this
- * task as complete. This method may be useful in cases where
- * {@code onCompletion} should not, or need not, be invoked for
- * each completer in a computation.
+ * #onCompletion(CountedCompleter)} along the completion path:
+ * If the pending count is nonzero, decrements the count;
+ * otherwise, similarly tries to complete this task's completer, if
+ * one exists, else marks this task as complete. This method may be
+ * useful in cases where {@code onCompletion} should not, or need
+ * not, be invoked for each completer in a computation.
*/
public final void propagateCompletion() {
CountedCompleter<?> a = this, s = a;
@@ -579,13 +582,15 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
}
/**
- * Regardless of pending count, invokes {@link #onCompletion},
- * marks this task as complete and further triggers {@link
- * #tryComplete} on this task's completer, if one exists. The
- * given rawResult is used as an argument to {@link #setRawResult}
- * before invoking {@link #onCompletion} or marking this task as
- * complete; its value is meaningful only for classes overriding
- * {@code setRawResult}.
+ * Regardless of pending count, invokes
+ * {@link #onCompletion(CountedCompleter)}, marks this task as
+ * complete and further triggers {@link #tryComplete} on this
+ * task's completer, if one exists. The given rawResult is
+ * used as an argument to {@link #setRawResult} before invoking
+ * {@link #onCompletion(CountedCompleter)} or marking this task
+ * as complete; its value is meaningful only for classes
+ * overriding {@code setRawResult}. This method does not modify
+ * the pending count.
*
* <p>This method may be useful when forcing completion as soon as
* any one (versus all) of several subtask results are obtained.
@@ -604,7 +609,6 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
p.tryComplete();
}
-
/**
* If this task's pending count is zero, returns this task;
* otherwise decrements its pending count and returns {@code
@@ -668,8 +672,9 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
void internalPropagateException(Throwable ex) {
CountedCompleter<?> a = this, s = a;
while (a.onExceptionalCompletion(ex, s) &&
- (a = (s = a).completer) != null && a.status >= 0)
- a.recordExceptionalCompletion(ex);
+ (a = (s = a).completer) != null && a.status >= 0 &&
+ a.recordExceptionalCompletion(ex) == EXCEPTIONAL)
+ ;
}
/**
diff --git a/luni/src/main/java/java/util/concurrent/ForkJoinPool.java b/luni/src/main/java/java/util/concurrent/ForkJoinPool.java
index 87ffff3..9448616 100644
--- a/luni/src/main/java/java/util/concurrent/ForkJoinPool.java
+++ b/luni/src/main/java/java/util/concurrent/ForkJoinPool.java
@@ -6,6 +6,7 @@
package java.util.concurrent;
+import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -17,6 +18,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/**
@@ -37,7 +39,7 @@ import java.util.concurrent.TimeUnit;
* ForkJoinPool}s may also be appropriate for use with event-style
* tasks that are never joined.
*
- * <p>A static {@link #commonPool()} is available and appropriate for
+ * <p>A static {@code commonPool()} is available and appropriate for
* most applications. The common pool is used by any ForkJoinTask that
* is not explicitly submitted to a specified pool. Using the common
* pool normally reduces resource usage (its threads are slowly
@@ -49,9 +51,9 @@ import java.util.concurrent.TimeUnit;
* level; by default, equal to the number of available processors. The
* pool attempts to maintain enough active (or available) threads by
* dynamically adding, suspending, or resuming internal worker
- * threads, even if some tasks are stalled waiting to join
- * others. However, no such adjustments are guaranteed in the face of
- * blocked I/O or other unmanaged synchronization. The nested {@link
+ * threads, even if some tasks are stalled waiting to join others.
+ * However, no such adjustments are guaranteed in the face of blocked
+ * I/O or other unmanaged synchronization. The nested {@link
* ManagedBlocker} interface enables extension of the kinds of
* synchronization accommodated.
*
@@ -75,38 +77,45 @@ import java.util.concurrent.TimeUnit;
* there is little difference among choice of methods.
*
* <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Summary of task execution methods</caption>
* <tr>
* <td></td>
* <td ALIGN=CENTER> <b>Call from non-fork/join clients</b></td>
* <td ALIGN=CENTER> <b>Call from within fork/join computations</b></td>
* </tr>
* <tr>
- * <td> <b>Arrange async execution</td>
+ * <td> <b>Arrange async execution</b></td>
* <td> {@link #execute(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#fork}</td>
* </tr>
* <tr>
- * <td> <b>Await and obtain result</td>
+ * <td> <b>Await and obtain result</b></td>
* <td> {@link #invoke(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#invoke}</td>
* </tr>
* <tr>
- * <td> <b>Arrange exec and obtain Future</td>
+ * <td> <b>Arrange exec and obtain Future</b></td>
* <td> {@link #submit(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#fork} (ForkJoinTasks <em>are</em> Futures)</td>
* </tr>
* </table>
*
* <p>The common pool is by default constructed with default
- * parameters, but these may be controlled by setting three {@link
- * System#getProperty system properties} with prefix {@code
- * java.util.concurrent.ForkJoinPool.common}: {@code parallelism} --
- * an integer greater than zero, {@code threadFactory} -- the class
- * name of a {@link ForkJoinWorkerThreadFactory}, and {@code
- * exceptionHandler} -- the class name of a {@link
- * java.lang.Thread.UncaughtExceptionHandler
- * Thread.UncaughtExceptionHandler}. Upon any error in establishing
- * these settings, default parameters are used.
+ * parameters, but these may be controlled by setting three
+ * {@linkplain System#getProperty system properties}:
+ * <ul>
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.parallelism}
+ * - the parallelism level, a non-negative integer
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.threadFactory}
+ * - the class name of a {@link ForkJoinWorkerThreadFactory}
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.exceptionHandler}
+ * - the class name of a {@link UncaughtExceptionHandler}
+ * </ul>
+ * The system class loader is used to load these classes.
+ * Upon any error in establishing these settings, default parameters
+ * are used. It is possible to disable or limit the use of threads in
+ * the common pool by setting the parallelism property to zero, and/or
+ * using a factory that may return {@code null}.
*
* <p><b>Implementation notes</b>: This implementation restricts the
* maximum number of running threads to 32767. Attempts to create
@@ -118,7 +127,6 @@ import java.util.concurrent.TimeUnit;
* or internal resources have been exhausted.
*
* @since 1.7
- * @hide
* @author Doug Lea
*/
public class ForkJoinPool extends AbstractExecutorService {
@@ -153,32 +161,35 @@ public class ForkJoinPool extends AbstractExecutorService {
* (http://research.sun.com/scalable/pubs/index.html) and
* "Idempotent work stealing" by Michael, Saraswat, and Vechev,
* PPoPP 2009 (http://portal.acm.org/citation.cfm?id=1504186).
- * The main differences ultimately stem from GC requirements that
- * we null out taken slots as soon as we can, to maintain as small
- * a footprint as possible even in programs generating huge
- * numbers of tasks. To accomplish this, we shift the CAS
- * arbitrating pop vs poll (steal) from being on the indices
- * ("base" and "top") to the slots themselves. So, both a
- * successful pop and poll mainly entail a CAS of a slot from
- * non-null to null. Because we rely on CASes of references, we
- * do not need tag bits on base or top. They are simple ints as
- * used in any circular array-based queue (see for example
- * ArrayDeque). Updates to the indices must still be ordered in a
- * way that guarantees that top == base means the queue is empty,
- * but otherwise may err on the side of possibly making the queue
- * appear nonempty when a push, pop, or poll have not fully
- * committed. Note that this means that the poll operation,
- * considered individually, is not wait-free. One thief cannot
- * successfully continue until another in-progress one (or, if
- * previously empty, a push) completes. However, in the
- * aggregate, we ensure at least probabilistic non-blockingness.
- * If an attempted steal fails, a thief always chooses a different
- * random victim target to try next. So, in order for one thief to
- * progress, it suffices for any in-progress poll or new push on
- * any empty queue to complete. (This is why we normally use
- * method pollAt and its variants that try once at the apparent
- * base index, else consider alternative actions, rather than
- * method poll.)
+ * See also "Correct and Efficient Work-Stealing for Weak Memory
+ * Models" by Le, Pop, Cohen, and Nardelli, PPoPP 2013
+ * (http://www.di.ens.fr/~zappa/readings/ppopp13.pdf) for an
+ * analysis of memory ordering (atomic, volatile etc) issues. The
+ * main differences ultimately stem from GC requirements that we
+ * null out taken slots as soon as we can, to maintain as small a
+ * footprint as possible even in programs generating huge numbers
+ * of tasks. To accomplish this, we shift the CAS arbitrating pop
+ * vs poll (steal) from being on the indices ("base" and "top") to
+ * the slots themselves. So, both a successful pop and poll
+ * mainly entail a CAS of a slot from non-null to null. Because
+ * we rely on CASes of references, we do not need tag bits on base
+ * or top. They are simple ints as used in any circular
+ * array-based queue (see for example ArrayDeque). Updates to the
+ * indices must still be ordered in a way that guarantees that top
+ * == base means the queue is empty, but otherwise may err on the
+ * side of possibly making the queue appear nonempty when a push,
+ * pop, or poll have not fully committed. Note that this means
+ * that the poll operation, considered individually, is not
+ * wait-free. One thief cannot successfully continue until another
+ * in-progress one (or, if previously empty, a push) completes.
+ * However, in the aggregate, we ensure at least probabilistic
+ * non-blockingness. If an attempted steal fails, a thief always
+ * chooses a different random victim target to try next. So, in
+ * order for one thief to progress, it suffices for any
+ * in-progress poll or new push on any empty queue to
+ * complete. (This is why we normally use method pollAt and its
+ * variants that try once at the apparent base index, else
+ * consider alternative actions, rather than method poll.)
*
* This approach also enables support of a user mode in which local
* task processing is in FIFO, not LIFO order, simply by using
@@ -197,18 +208,17 @@ public class ForkJoinPool extends AbstractExecutorService {
* for work-stealing (this would contaminate lifo/fifo
* processing). Instead, we randomly associate submission queues
* with submitting threads, using a form of hashing. The
- * ThreadLocal Submitter class contains a value initially used as
- * a hash code for choosing existing queues, but may be randomly
- * repositioned upon contention with other submitters. In
- * essence, submitters act like workers except that they are
- * restricted to executing local tasks that they submitted (or in
- * the case of CountedCompleters, others with the same root task).
- * However, because most shared/external queue operations are more
- * expensive than internal, and because, at steady state, external
- * submitters will compete for CPU with workers, ForkJoinTask.join
- * and related methods disable them from repeatedly helping to
- * process tasks if all workers are active. Insertion of tasks in
- * shared mode requires a lock (mainly to protect in the case of
+ * Submitter probe value serves as a hash code for
+ * choosing existing queues, and may be randomly repositioned upon
+ * contention with other submitters. In essence, submitters act
+ * like workers except that they are restricted to executing local
+ * tasks that they submitted. However, because most
+ * shared/external queue operations are more expensive than
+ * internal, and because, at steady state, external submitters
+ * will compete for CPU with workers, ForkJoinTask.join and
+ * related methods disable them from repeatedly helping to process
+ * tasks if all workers are active. Insertion of tasks in shared
+ * mode requires a lock (mainly to protect in the case of
* resizing) but we use only a simple spinlock (using bits in
* field qlock), because submitters encountering a busy queue move
* on to try or create other queues -- they block only when
@@ -298,37 +308,35 @@ public class ForkJoinPool extends AbstractExecutorService {
* has not yet entered the wait queue. We solve this by requiring
* a full sweep of all workers (via repeated calls to method
* scan()) both before and after a newly waiting worker is added
- * to the wait queue. During a rescan, the worker might release
- * some other queued worker rather than itself, which has the same
- * net effect. Because enqueued workers may actually be rescanning
- * rather than waiting, we set and clear the "parker" field of
- * WorkQueues to reduce unnecessary calls to unpark. (This
- * requires a secondary recheck to avoid missed signals.) Note
- * the unusual conventions about Thread.interrupts surrounding
- * parking and other blocking: Because interrupts are used solely
- * to alert threads to check termination, which is checked anyway
- * upon blocking, we clear status (using Thread.interrupted)
- * before any call to park, so that park does not immediately
- * return due to status being set via some other unrelated call to
- * interrupt in user code.
+ * to the wait queue. Because enqueued workers may actually be
+ * rescanning rather than waiting, we set and clear the "parker"
+ * field of WorkQueues to reduce unnecessary calls to unpark.
+ * (This requires a secondary recheck to avoid missed signals.)
+ * Note the unusual conventions about Thread.interrupts
+ * surrounding parking and other blocking: Because interrupts are
+ * used solely to alert threads to check termination, which is
+ * checked anyway upon blocking, we clear status (using
+ * Thread.interrupted) before any call to park, so that park does
+ * not immediately return due to status being set via some other
+ * unrelated call to interrupt in user code.
*
* Signalling. We create or wake up workers only when there
* appears to be at least one task they might be able to find and
- * execute. However, many other threads may notice the same task
- * and each signal to wake up a thread that might take it. So in
- * general, pools will be over-signalled. When a submission is
- * added or another worker adds a task to a queue that has fewer
- * than two tasks, they signal waiting workers (or trigger
- * creation of new ones if fewer than the given parallelism level
- * -- signalWork), and may leave a hint to the unparked worker to
- * help signal others upon wakeup). These primary signals are
- * buttressed by others (see method helpSignal) whenever other
- * threads scan for work or do not have a task to process. On
- * most platforms, signalling (unpark) overhead time is noticeably
+ * execute. When a submission is added or another worker adds a
+ * task to a queue that has fewer than two tasks, they signal
+ * waiting workers (or trigger creation of new ones if fewer than
+ * the given parallelism level -- signalWork). These primary
+ * signals are buttressed by others whenever other threads remove
+ * a task from a queue and notice that there are other tasks there
+ * as well. So in general, pools will be over-signalled. On most
+ * platforms, signalling (unpark) overhead time is noticeably
* long, and the time between signalling a thread and it actually
* making progress can be very noticeably long, so it is worth
* offloading these delays from critical paths as much as
- * possible.
+ * possible. Additionally, workers spin-down gradually, by staying
+ * alive so long as they see the ctl state changing. Similar
+ * stability-sensing techniques are also used before blocking in
+ * awaitJoin and helpComplete.
*
* Trimming workers. To release resources after periods of lack of
* use, a worker starting to wait when the pool is quiescent will
@@ -409,12 +417,6 @@ public class ForkJoinPool extends AbstractExecutorService {
* to find work (see MAX_HELP) and fall back to suspending the
* worker and if necessary replacing it with another.
*
- * Helping actions for CountedCompleters are much simpler: Method
- * helpComplete can take and execute any task with the same root
- * as the task being waited on. However, this still entails some
- * traversal of completer chains, so is less efficient than using
- * CountedCompleters without explicit joins.
- *
* It is impossible to keep exactly the target parallelism number
* of threads running at any given time. Determining the
* existence of conservatively safe helping targets, the
@@ -441,7 +443,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* Common Pool
* ===========
*
- * The static commonPool always exists after static
+ * The static common pool always exists after static
* initialization. Since it (or any other created pool) need
* never be used, we minimize initial construction overhead and
* footprint to the setup of about a dozen fields, with no nested
@@ -449,8 +451,11 @@ public class ForkJoinPool extends AbstractExecutorService {
* fullExternalPush during the first submission to the pool.
*
* When external threads submit to the common pool, they can
- * perform some subtask processing (see externalHelpJoin and
- * related methods). We do not need to record whether these
+ * perform subtask processing (see externalHelpJoin and related
+ * methods). This caller-helps policy makes it sensible to set
+ * common pool parallelism level to one (or more) less than the
+ * total number of available cores, or even zero for pure
+ * caller-runs. We do not need to record whether external
* submissions are to the common pool -- if not, externalHelpJoin
* returns quickly (at the most helping to signal some common pool
* workers). These submitters would otherwise be blocked waiting
@@ -520,6 +525,7 @@ public class ForkJoinPool extends AbstractExecutorService {
*
* @param pool the pool this thread works in
* @throws NullPointerException if the pool is null
+ * @return the new worker thread
*/
public ForkJoinWorkerThread newThread(ForkJoinPool pool);
}
@@ -536,26 +542,6 @@ public class ForkJoinPool extends AbstractExecutorService {
}
/**
- * Per-thread records for threads that submit to pools. Currently
- * holds only pseudo-random seed / index that is used to choose
- * submission queues in method externalPush. In the future, this may
- * also incorporate a means to implement different task rejection
- * and resubmission policies.
- *
- * Seeds for submitters and workers/workQueues work in basically
- * the same way but are initialized and updated using slightly
- * different mechanics. Both are initialized using the same
- * approach as in class ThreadLocal, where successive values are
- * unlikely to collide with previous values. Seeds are then
- * randomly modified upon collisions using xorshifts, which
- * requires a non-zero seed.
- */
- static final class Submitter {
- int seed;
- Submitter(int s) { seed = s; }
- }
-
- /**
* Class for artificial tasks that are used to replace the target
* of local joins if they are removed from an interior queue slot
* in WorkQueue.tryRemoveAndExec. We don't need the proxy to
@@ -614,17 +600,8 @@ public class ForkJoinPool extends AbstractExecutorService {
* do not want multiple WorkQueue instances or multiple queue
* arrays sharing cache lines. (It would be best for queue objects
* and their arrays to share, but there is nothing available to
- * help arrange that). Unfortunately, because they are recorded
- * in a common array, WorkQueue instances are often moved to be
- * adjacent by garbage collectors. To reduce impact, we use field
- * padding that works OK on common platforms; this effectively
- * trades off slightly slower average field access for the sake of
- * avoiding really bad worst-case access. (Until better JVM
- * support is in place, this padding is dependent on transient
- * properties of JVM field layout rules.) We also take care in
- * allocating, sizing and resizing the array. Non-shared queue
- * arrays are initialized by workers before use. Others are
- * allocated on first use.
+ * help arrange that). The @Contended annotation alerts JVMs to
+ * try to keep instances apart.
*/
static final class WorkQueue {
/**
@@ -650,13 +627,12 @@ public class ForkJoinPool extends AbstractExecutorService {
// Heuristic padding to ameliorate unfortunate memory placements
volatile long pad00, pad01, pad02, pad03, pad04, pad05, pad06;
- int seed; // for random scanning; initialize nonzero
volatile int eventCount; // encoded inactivation count; < 0 if inactive
int nextWait; // encoded record of next event waiter
- int hint; // steal or signal hint (index)
- int poolIndex; // index of this queue in pool (or 0)
- final int mode; // 0: lifo, > 0: fifo, < 0: shared
int nsteals; // number of steals
+ int hint; // steal index hint
+ short poolIndex; // index of this queue in pool
+ final short mode; // 0: lifo, > 0: fifo, < 0: shared
volatile int qlock; // 1: locked, -1: terminate; else 0
volatile int base; // index of next slot for poll
int top; // index of next slot for push
@@ -674,8 +650,8 @@ public class ForkJoinPool extends AbstractExecutorService {
int seed) {
this.pool = pool;
this.owner = owner;
- this.mode = mode;
- this.seed = seed;
+ this.mode = (short)mode;
+ this.hint = seed; // store initial seed for runWorker
// Place indices in the center of array (that is not yet allocated)
base = top = INITIAL_QUEUE_CAPACITY >>> 1;
}
@@ -688,7 +664,7 @@ public class ForkJoinPool extends AbstractExecutorService {
return (n >= 0) ? 0 : -n; // ignore transient negative
}
- /**
+ /**
* Provides a more accurate estimate of whether this queue has
* any tasks than does queueSize, by checking whether a
* near-empty queue has at least one unclaimed task.
@@ -713,20 +689,18 @@ public class ForkJoinPool extends AbstractExecutorService {
*/
final void push(ForkJoinTask<?> task) {
ForkJoinTask<?>[] a; ForkJoinPool p;
- int s = top, m, n;
+ int s = top, n;
if ((a = array) != null) { // ignore if queue removed
- int j = (((m = a.length - 1) & s) << ASHIFT) + ABASE;
- U.putOrderedObject(a, j, task);
- if ((n = (top = s + 1) - base) <= 2) {
- if ((p = pool) != null)
- p.signalWork(this);
- }
+ int m = a.length - 1;
+ U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);
+ if ((n = (top = s + 1) - base) <= 2)
+ (p = pool).signalWork(p.workQueues, this);
else if (n >= m)
growArray();
}
}
- /**
+ /**
* Initializes or doubles the capacity of array. Call either
* by owner or with lock held -- it is OK for base, but not
* top, to move while resizings are in progress.
@@ -784,9 +758,8 @@ public class ForkJoinPool extends AbstractExecutorService {
if ((a = array) != null) {
int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
if ((t = (ForkJoinTask<?>)U.getObjectVolatile(a, j)) != null &&
- base == b &&
- U.compareAndSwapObject(a, j, t, null)) {
- base = b + 1;
+ base == b && U.compareAndSwapObject(a, j, t, null)) {
+ U.putOrderedInt(this, QBASE, b + 1);
return t;
}
}
@@ -802,9 +775,8 @@ public class ForkJoinPool extends AbstractExecutorService {
int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
if (t != null) {
- if (base == b &&
- U.compareAndSwapObject(a, j, t, null)) {
- base = b + 1;
+ if (U.compareAndSwapObject(a, j, t, null)) {
+ U.putOrderedInt(this, QBASE, b + 1);
return t;
}
}
@@ -861,46 +833,43 @@ public class ForkJoinPool extends AbstractExecutorService {
ForkJoinTask.cancelIgnoringExceptions(t);
}
- /**
- * Computes next value for random probes. Scans don't require
- * a very high quality generator, but also not a crummy one.
- * Marsaglia xor-shift is cheap and works well enough. Note:
- * This is manually inlined in its usages in ForkJoinPool to
- * avoid writes inside busy scan loops.
- */
- final int nextSeed() {
- int r = seed;
- r ^= r << 13;
- r ^= r >>> 17;
- return seed = r ^= r << 5;
- }
-
// Specialized execution methods
/**
- * Pops and runs tasks until empty.
+ * Polls and runs tasks until empty.
*/
- private void popAndExecAll() {
- // A bit faster than repeated pop calls
- ForkJoinTask<?>[] a; int m, s; long j; ForkJoinTask<?> t;
- while ((a = array) != null && (m = a.length - 1) >= 0 &&
- (s = top - 1) - base >= 0 &&
- (t = ((ForkJoinTask<?>)
- U.getObject(a, j = ((m & s) << ASHIFT) + ABASE)))
- != null) {
- if (U.compareAndSwapObject(a, j, t, null)) {
- top = s;
- t.doExec();
- }
- }
+ final void pollAndExecAll() {
+ for (ForkJoinTask<?> t; (t = poll()) != null;)
+ t.doExec();
}
/**
- * Polls and runs tasks until empty.
+ * Executes a top-level task and any local tasks remaining
+ * after execution.
*/
- private void pollAndExecAll() {
- for (ForkJoinTask<?> t; (t = poll()) != null;)
- t.doExec();
+ final void runTask(ForkJoinTask<?> task) {
+ if ((currentSteal = task) != null) {
+ task.doExec();
+ ForkJoinTask<?>[] a = array;
+ int md = mode;
+ ++nsteals;
+ currentSteal = null;
+ if (md != 0)
+ pollAndExecAll();
+ else if (a != null) {
+ int s, m = a.length - 1;
+ while ((s = top - 1) - base >= 0) {
+ long i = ((m & s) << ASHIFT) + ABASE;
+ ForkJoinTask<?> t = (ForkJoinTask<?>)U.getObject(a, i);
+ if (t == null)
+ break;
+ if (U.compareAndSwapObject(a, i, t, null)) {
+ top = s;
+ t.doExec();
+ }
+ }
+ }
+ }
}
/**
@@ -911,13 +880,15 @@ public class ForkJoinPool extends AbstractExecutorService {
* @return false if no progress can be made, else true
*/
final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
- boolean stat = true, removed = false, empty = true;
+ boolean stat;
ForkJoinTask<?>[] a; int m, s, b, n;
- if ((a = array) != null && (m = a.length - 1) >= 0 &&
+ if (task != null && (a = array) != null && (m = a.length - 1) >= 0 &&
(n = (s = top) - (b = base)) > 0) {
+ boolean removed = false, empty = true;
+ stat = true;
for (ForkJoinTask<?> t;;) { // traverse from s to b
- int j = ((--s & m) << ASHIFT) + ABASE;
- t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
+ long j = ((--s & m) << ASHIFT) + ABASE;
+ t = (ForkJoinTask<?>)U.getObject(a, j);
if (t == null) // inconsistent length
break;
else if (t == task) {
@@ -945,68 +916,95 @@ public class ForkJoinPool extends AbstractExecutorService {
break;
}
}
+ if (removed)
+ task.doExec();
}
- if (removed)
- task.doExec();
+ else
+ stat = false;
return stat;
}
/**
- * Polls for and executes the given task or any other task in
- * its CountedCompleter computation.
+ * Tries to poll for and execute the given task or any other
+ * task in its CountedCompleter computation.
*/
- final boolean pollAndExecCC(ForkJoinTask<?> root) {
- ForkJoinTask<?>[] a; int b; Object o;
- outer: while ((b = base) - top < 0 && (a = array) != null) {
+ final boolean pollAndExecCC(CountedCompleter<?> root) {
+ ForkJoinTask<?>[] a; int b; Object o; CountedCompleter<?> t, r;
+ if ((b = base) - top < 0 && (a = array) != null) {
long j = (((a.length - 1) & b) << ASHIFT) + ABASE;
- if ((o = U.getObject(a, j)) == null ||
- !(o instanceof CountedCompleter))
- break;
- for (CountedCompleter<?> t = (CountedCompleter<?>)o, r = t;;) {
- if (r == root) {
- if (base == b &&
- U.compareAndSwapObject(a, j, t, null)) {
- base = b + 1;
- t.doExec();
+ if ((o = U.getObjectVolatile(a, j)) == null)
+ return true; // retry
+ if (o instanceof CountedCompleter) {
+ for (t = (CountedCompleter<?>)o, r = t;;) {
+ if (r == root) {
+ if (base == b &&
+ U.compareAndSwapObject(a, j, t, null)) {
+ U.putOrderedInt(this, QBASE, b + 1);
+ t.doExec();
+ }
return true;
}
- else
- break; // restart
+ else if ((r = r.completer) == null)
+ break; // not part of root computation
}
- if ((r = r.completer) == null)
- break outer; // not part of root computation
}
}
return false;
}
/**
- * Executes a top-level task and any local tasks remaining
- * after execution.
+ * Tries to pop and execute the given task or any other task
+ * in its CountedCompleter computation.
*/
- final void runTask(ForkJoinTask<?> t) {
- if (t != null) {
- (currentSteal = t).doExec();
- currentSteal = null;
- ++nsteals;
- if (base - top < 0) { // process remaining local tasks
- if (mode == 0)
- popAndExecAll();
- else
- pollAndExecAll();
+ final boolean externalPopAndExecCC(CountedCompleter<?> root) {
+ ForkJoinTask<?>[] a; int s; Object o; CountedCompleter<?> t, r;
+ if (base - (s = top) < 0 && (a = array) != null) {
+ long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
+ if ((o = U.getObject(a, j)) instanceof CountedCompleter) {
+ for (t = (CountedCompleter<?>)o, r = t;;) {
+ if (r == root) {
+ if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
+ if (top == s && array == a &&
+ U.compareAndSwapObject(a, j, t, null)) {
+ top = s - 1;
+ qlock = 0;
+ t.doExec();
+ }
+ else
+ qlock = 0;
+ }
+ return true;
+ }
+ else if ((r = r.completer) == null)
+ break;
+ }
}
}
+ return false;
}
/**
- * Executes a non-top-level (stolen) task.
+ * Internal version
*/
- final void runSubtask(ForkJoinTask<?> t) {
- if (t != null) {
- ForkJoinTask<?> ps = currentSteal;
- (currentSteal = t).doExec();
- currentSteal = ps;
+ final boolean internalPopAndExecCC(CountedCompleter<?> root) {
+ ForkJoinTask<?>[] a; int s; Object o; CountedCompleter<?> t, r;
+ if (base - (s = top) < 0 && (a = array) != null) {
+ long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
+ if ((o = U.getObject(a, j)) instanceof CountedCompleter) {
+ for (t = (CountedCompleter<?>)o, r = t;;) {
+ if (r == root) {
+ if (U.compareAndSwapObject(a, j, t, null)) {
+ top = s - 1;
+ t.doExec();
+ }
+ return true;
+ }
+ else if ((r = r.completer) == null)
+ break;
+ }
+ }
}
+ return false;
}
/**
@@ -1023,6 +1021,7 @@ public class ForkJoinPool extends AbstractExecutorService {
// Unsafe mechanics
private static final sun.misc.Unsafe U;
+ private static final long QBASE;
private static final long QLOCK;
private static final int ABASE;
private static final int ASHIFT;
@@ -1031,6 +1030,8 @@ public class ForkJoinPool extends AbstractExecutorService {
U = sun.misc.Unsafe.getUnsafe();
Class<?> k = WorkQueue.class;
Class<?> ak = ForkJoinTask[].class;
+ QBASE = U.objectFieldOffset
+ (k.getDeclaredField("base"));
QLOCK = U.objectFieldOffset
(k.getDeclaredField("qlock"));
ABASE = U.arrayBaseOffset(ak);
@@ -1047,13 +1048,6 @@ public class ForkJoinPool extends AbstractExecutorService {
// static fields (initialized in static initializer below)
/**
- * Creates a new ForkJoinWorkerThread. This factory is used unless
- * overridden in ForkJoinPool constructors.
- */
- public static final ForkJoinWorkerThreadFactory
- defaultForkJoinWorkerThreadFactory;
-
- /**
* Per-thread submission bookkeeping. Shared across all pools
* to reduce ThreadLocal pollution and because random motion
* to avoid contention in one pool is likely to hold for others.
@@ -1063,6 +1057,13 @@ public class ForkJoinPool extends AbstractExecutorService {
static final ThreadLocal<Submitter> submitters;
/**
+ * Creates a new ForkJoinWorkerThread. This factory is used unless
+ * overridden in ForkJoinPool constructors.
+ */
+ public static final ForkJoinWorkerThreadFactory
+ defaultForkJoinWorkerThreadFactory;
+
+ /**
* Permission required for callers of methods that may start or
* kill threads.
*/
@@ -1074,12 +1075,15 @@ public class ForkJoinPool extends AbstractExecutorService {
* to paranoically avoid potential initialization circularities
* as well as to simplify generated code.
*/
- static final ForkJoinPool commonPool;
+ static final ForkJoinPool common;
/**
- * Common pool parallelism. Must equal commonPool.parallelism.
+ * Common pool parallelism. To allow simpler use and management
+ * when common pool threads are disabled, we allow the underlying
+ * common.parallelism field to be zero, but in that case still report
+ * parallelism as 1 to reflect resulting caller-runs mechanics.
*/
- static final int commonPoolParallelism;
+ static final int commonParallelism;
/**
* Sequence number for creating workerNamePrefix.
@@ -1114,7 +1118,7 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* Tolerance for idle timeouts, to cope with timer undershoots
*/
- private static final long TIMEOUT_SLOP = 2000000L; // 20ms
+ private static final long TIMEOUT_SLOP = 2000000L;
/**
* The maximum stolen->joining link depth allowed in method
@@ -1216,30 +1220,19 @@ public class ForkJoinPool extends AbstractExecutorService {
static final int FIFO_QUEUE = 1;
static final int SHARED_QUEUE = -1;
- // bounds for #steps in scan loop -- must be power 2 minus 1
- private static final int MIN_SCAN = 0x1ff; // cover estimation slop
- private static final int MAX_SCAN = 0x1ffff; // 4 * max workers
-
- // Instance fields
-
- /*
- * Field layout of this class tends to matter more than one would
- * like. Runtime layout order is only loosely related to
- * declaration order and may differ across JVMs, but the following
- * empirically works OK on current JVMs.
- */
-
// Heuristic padding to ameliorate unfortunate memory placements
volatile long pad00, pad01, pad02, pad03, pad04, pad05, pad06;
+ // Instance fields
volatile long stealCount; // collects worker counts
volatile long ctl; // main pool control
volatile int plock; // shutdown status and seqLock
volatile int indexSeed; // worker/submitter index seed
- final int config; // mode and parallelism level
+ final short parallelism; // parallelism level
+ final short mode; // LIFO/FIFO
WorkQueue[] workQueues; // main registry
final ForkJoinWorkerThreadFactory factory;
- final Thread.UncaughtExceptionHandler ueh; // per-worker UEH
+ final UncaughtExceptionHandler ueh; // per-worker UEH
final String workerNamePrefix; // to create worker name string
volatile Object pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17;
@@ -1254,24 +1247,13 @@ public class ForkJoinPool extends AbstractExecutorService {
* a more conservative alternative to a pure spinlock.
*/
private int acquirePlock() {
- int spins = PL_SPINS, r = 0, ps, nps;
+ int spins = PL_SPINS, ps, nps;
for (;;) {
if (((ps = plock) & PL_LOCK) == 0 &&
U.compareAndSwapInt(this, PLOCK, ps, nps = ps + PL_LOCK))
return nps;
- else if (r == 0) { // randomize spins if possible
- Thread t = Thread.currentThread(); WorkQueue w; Submitter z;
- if ((t instanceof ForkJoinWorkerThread) &&
- (w = ((ForkJoinWorkerThread)t).workQueue) != null)
- r = w.seed;
- else if ((z = submitters.get()) != null)
- r = z.seed;
- else
- r = 1;
- }
else if (spins >= 0) {
- r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift
- if (r >= 0)
+ if (ThreadLocalRandom.current().nextInt() >= 0)
--spins;
}
else if (U.compareAndSwapInt(this, PLOCK, ps, ps | PL_SIGNAL)) {
@@ -1303,48 +1285,15 @@ public class ForkJoinPool extends AbstractExecutorService {
}
/**
- * Performs secondary initialization, called when plock is zero.
- * Creates workQueue array and sets plock to a valid value. The
- * lock body must be exception-free (so no try/finally) so we
- * optimistically allocate new array outside the lock and throw
- * away if (very rarely) not needed. (A similar tactic is used in
- * fullExternalPush.) Because the plock seq value can eventually
- * wrap around zero, this method harmlessly fails to reinitialize
- * if workQueues exists, while still advancing plock.
- *
- * Additionally tries to create the first worker.
- */
- private void initWorkers() {
- WorkQueue[] ws, nws; int ps;
- int p = config & SMASK; // find power of two table size
- int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots
- n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16;
- n = (n + 1) << 1;
- if ((ws = workQueues) == null || ws.length == 0)
- nws = new WorkQueue[n];
- else
- nws = null;
- if (((ps = plock) & PL_LOCK) != 0 ||
- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
- ps = acquirePlock();
- if (((ws = workQueues) == null || ws.length == 0) && nws != null)
- workQueues = nws;
- int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
- if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
- releasePlock(nps);
- tryAddWorker();
- }
-
- /**
* Tries to create and start one worker if fewer than target
* parallelism level exist. Adjusts counts etc on failure.
*/
private void tryAddWorker() {
- long c; int u;
+ long c; int u, e;
while ((u = (int)((c = ctl) >>> 32)) < 0 &&
- (u & SHORT_SIGN) != 0 && (int)c == 0) {
- long nc = (long)(((u + UTC_UNIT) & UTC_MASK) |
- ((u + UAC_UNIT) & UAC_MASK)) << 32;
+ (u & SHORT_SIGN) != 0 && (e = (int)c) >= 0) {
+ long nc = ((long)(((u + UTC_UNIT) & UTC_MASK) |
+ ((u + UAC_UNIT) & UAC_MASK)) << 32) | (long)e;
if (U.compareAndSwapLong(this, CTL, c, nc)) {
ForkJoinWorkerThreadFactory fac;
Throwable ex = null;
@@ -1355,8 +1304,8 @@ public class ForkJoinPool extends AbstractExecutorService {
wt.start();
break;
}
- } catch (Throwable e) {
- ex = e;
+ } catch (Throwable rex) {
+ ex = rex;
}
deregisterWorker(wt, ex);
break;
@@ -1377,14 +1326,14 @@ public class ForkJoinPool extends AbstractExecutorService {
* @return the worker's queue
*/
final WorkQueue registerWorker(ForkJoinWorkerThread wt) {
- Thread.UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
+ UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
wt.setDaemon(true);
if ((handler = ueh) != null)
wt.setUncaughtExceptionHandler(handler);
do {} while (!U.compareAndSwapInt(this, INDEXSEED, s = indexSeed,
s += SEED_INCREMENT) ||
s == 0); // skip 0
- WorkQueue w = new WorkQueue(this, wt, config >>> 16, s);
+ WorkQueue w = new WorkQueue(this, wt, mode, s);
if (((ps = plock) & PL_LOCK) != 0 ||
!U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
ps = acquirePlock();
@@ -1404,14 +1353,15 @@ public class ForkJoinPool extends AbstractExecutorService {
}
}
}
- w.eventCount = w.poolIndex = r; // volatile write orders
+ w.poolIndex = (short)r;
+ w.eventCount = r; // volatile write orders
ws[r] = w;
}
} finally {
if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
releasePlock(nps);
}
- wt.setName(workerNamePrefix.concat(Integer.toString(w.poolIndex)));
+ wt.setName(workerNamePrefix.concat(Integer.toString(w.poolIndex >>> 1)));
return w;
}
@@ -1421,17 +1371,17 @@ public class ForkJoinPool extends AbstractExecutorService {
* array, and adjusts counts. If pool is shutting down, tries to
* complete termination.
*
- * @param wt the worker thread or null if construction failed
+ * @param wt the worker thread, or null if construction failed
* @param ex the exception causing failure, or null if none
*/
final void deregisterWorker(ForkJoinWorkerThread wt, Throwable ex) {
WorkQueue w = null;
if (wt != null && (w = wt.workQueue) != null) {
- int ps;
+ int ps; long sc;
w.qlock = -1; // ensure set
- long ns = w.nsteals, sc; // collect steal count
do {} while (!U.compareAndSwapLong(this, STEALCOUNT,
- sc = stealCount, sc + ns));
+ sc = stealCount,
+ sc + w.nsteals));
if (((ps = plock) & PL_LOCK) != 0 ||
!U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
ps = acquirePlock();
@@ -1460,7 +1410,7 @@ public class ForkJoinPool extends AbstractExecutorService {
if (e > 0) { // activate or create replacement
if ((ws = workQueues) == null ||
(i = e & SMASK) >= ws.length ||
- (v = ws[i]) != null)
+ (v = ws[i]) == null)
break;
long nc = (((long)(v.nextWait & E_MASK)) |
((long)(u + UAC_UNIT) << 32));
@@ -1489,6 +1439,26 @@ public class ForkJoinPool extends AbstractExecutorService {
// Submissions
/**
+ * Per-thread records for threads that submit to pools. Currently
+ * holds only pseudo-random seed / index that is used to choose
+ * submission queues in method externalPush. In the future, this may
+ * also incorporate a means to implement different task rejection
+ * and resubmission policies.
+ *
+ * Seeds for submitters and workers/workQueues work in basically
+ * the same way but are initialized and updated using slightly
+ * different mechanics. Both are initialized using the same
+ * approach as in class ThreadLocal, where successive values are
+ * unlikely to collide with previous values. Seeds are then
+ * randomly modified upon collisions using xorshifts, which
+ * requires a non-zero seed.
+ */
+ static final class Submitter {
+ int seed;
+ Submitter(int s) { seed = s; }
+ }
+
+ /**
* Unless shutting down, adds the given task to a submission queue
* at submitter's current queue index (modulo submission
* range). Only the most common path is directly handled in this
@@ -1497,19 +1467,21 @@ public class ForkJoinPool extends AbstractExecutorService {
* @param task the task. Caller must ensure non-null.
*/
final void externalPush(ForkJoinTask<?> task) {
- WorkQueue[] ws; WorkQueue q; Submitter z; int m; ForkJoinTask<?>[] a;
- if ((z = submitters.get()) != null && plock > 0 &&
- (ws = workQueues) != null && (m = (ws.length - 1)) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
+ Submitter z = submitters.get();
+ WorkQueue q; int r, m, s, n, am; ForkJoinTask<?>[] a;
+ int ps = plock;
+ WorkQueue[] ws = workQueues;
+ if (z != null && ps > 0 && ws != null && (m = (ws.length - 1)) >= 0 &&
+ (q = ws[m & (r = z.seed) & SQMASK]) != null && r != 0 &&
U.compareAndSwapInt(q, QLOCK, 0, 1)) { // lock
- int b = q.base, s = q.top, n, an;
- if ((a = q.array) != null && (an = a.length) > (n = s + 1 - b)) {
- int j = (((an - 1) & s) << ASHIFT) + ABASE;
+ if ((a = q.array) != null &&
+ (am = a.length - 1) > (n = (s = q.top) - q.base)) {
+ int j = ((am & s) << ASHIFT) + ABASE;
U.putOrderedObject(a, j, task);
q.top = s + 1; // push on to deque
q.qlock = 0;
- if (n <= 2)
- signalWork(q);
+ if (n <= 1)
+ signalWork(ws, q);
return;
}
q.qlock = 0;
@@ -1520,13 +1492,19 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* Full version of externalPush. This method is called, among
* other times, upon the first submission of the first task to the
- * pool, so must perform secondary initialization (via
- * initWorkers). It also detects first submission by an external
- * thread by looking up its ThreadLocal, and creates a new shared
- * queue if the one at index if empty or contended. The plock lock
- * body must be exception-free (so no try/finally) so we
- * optimistically allocate new queues outside the lock and throw
- * them away if (very rarely) not needed.
+ * pool, so must perform secondary initialization. It also
+ * detects first submission by an external thread by looking up
+ * its ThreadLocal, and creates a new shared queue if the one at
+ * index if empty or contended. The plock lock body must be
+ * exception-free (so no try/finally) so we optimistically
+ * allocate new queues outside the lock and throw them away if
+ * (very rarely) not needed.
+ *
+ * Secondary initialization occurs when plock is zero, to create
+ * workQueue array and set plock to a valid value. This lock body
+ * must also be exception-free. Because the plock seq value can
+ * eventually wrap around zero, this method harmlessly fails to
+ * reinitialize if workQueues exists, while still advancing plock.
*/
private void fullExternalPush(ForkJoinTask<?> task) {
int r = 0; // random index seed
@@ -1537,17 +1515,31 @@ public class ForkJoinPool extends AbstractExecutorService {
r += SEED_INCREMENT) && r != 0)
submitters.set(z = new Submitter(r));
}
- else if (r == 0) { // move to a different index
+ else if (r == 0) { // move to a different index
r = z.seed;
- r ^= r << 13; // same xorshift as WorkQueues
+ r ^= r << 13; // same xorshift as WorkQueues
r ^= r >>> 17;
- z.seed = r ^ (r << 5);
+ z.seed = r ^= (r << 5);
}
- else if ((ps = plock) < 0)
+ if ((ps = plock) < 0)
throw new RejectedExecutionException();
else if (ps == 0 || (ws = workQueues) == null ||
- (m = ws.length - 1) < 0)
- initWorkers();
+ (m = ws.length - 1) < 0) { // initialize workQueues
+ int p = parallelism; // find power of two table size
+ int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots
+ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4;
+ n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
+ WorkQueue[] nws = ((ws = workQueues) == null || ws.length == 0 ?
+ new WorkQueue[n] : null);
+ if (((ps = plock) & PL_LOCK) != 0 ||
+ !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+ ps = acquirePlock();
+ if (((ws = workQueues) == null || ws.length == 0) && nws != null)
+ workQueues = nws;
+ int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
+ if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+ releasePlock(nps);
+ }
else if ((q = ws[k = r & m & SQMASK]) != null) {
if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
ForkJoinTask<?>[] a = q.array;
@@ -1565,7 +1557,7 @@ public class ForkJoinPool extends AbstractExecutorService {
q.qlock = 0; // unlock
}
if (submitted) {
- signalWork(q);
+ signalWork(ws, q);
return;
}
}
@@ -1573,6 +1565,7 @@ public class ForkJoinPool extends AbstractExecutorService {
}
else if (((ps = plock) & PL_LOCK) == 0) { // create new queue
q = new WorkQueue(this, null, SHARED_QUEUE, r);
+ q.poolIndex = (short)k;
if (((ps = plock) & PL_LOCK) != 0 ||
!U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
ps = acquirePlock();
@@ -1583,7 +1576,7 @@ public class ForkJoinPool extends AbstractExecutorService {
releasePlock(nps);
}
else
- r = 0; // try elsewhere while lock held
+ r = 0;
}
}
@@ -1594,41 +1587,42 @@ public class ForkJoinPool extends AbstractExecutorService {
*/
final void incrementActiveCount() {
long c;
- do {} while (!U.compareAndSwapLong(this, CTL, c = ctl, c + AC_UNIT));
+ do {} while (!U.compareAndSwapLong
+ (this, CTL, c = ctl, ((c & ~AC_MASK) |
+ ((c & AC_MASK) + AC_UNIT))));
}
/**
* Tries to create or activate a worker if too few are active.
*
- * @param q the (non-null) queue holding tasks to be signalled
+ * @param ws the worker array to use to find signallees
+ * @param q if non-null, the queue holding tasks to be processed
*/
- final void signalWork(WorkQueue q) {
- int hint = q.poolIndex;
- long c; int e, u, i, n; WorkQueue[] ws; WorkQueue w; Thread p;
- while ((u = (int)((c = ctl) >>> 32)) < 0) {
- if ((e = (int)c) > 0) {
- if ((ws = workQueues) != null && ws.length > (i = e & SMASK) &&
- (w = ws[i]) != null && w.eventCount == (e | INT_SIGN)) {
- long nc = (((long)(w.nextWait & E_MASK)) |
- ((long)(u + UAC_UNIT) << 32));
- if (U.compareAndSwapLong(this, CTL, c, nc)) {
- w.hint = hint;
- w.eventCount = (e + E_SEQ) & E_MASK;
- if ((p = w.parker) != null)
- U.unpark(p);
- break;
- }
- if (q.top - q.base <= 0)
- break;
- }
- else
- break;
- }
- else {
+ final void signalWork(WorkQueue[] ws, WorkQueue q) {
+ for (;;) {
+ long c; int e, u, i; WorkQueue w; Thread p;
+ if ((u = (int)((c = ctl) >>> 32)) >= 0)
+ break;
+ if ((e = (int)c) <= 0) {
if ((short)u < 0)
tryAddWorker();
break;
}
+ if (ws == null || ws.length <= (i = e & SMASK) ||
+ (w = ws[i]) == null)
+ break;
+ long nc = (((long)(w.nextWait & E_MASK)) |
+ ((long)(u + UAC_UNIT)) << 32);
+ int ne = (e + E_SEQ) & E_MASK;
+ if (w.eventCount == (e | INT_SIGN) &&
+ U.compareAndSwapLong(this, CTL, c, nc)) {
+ w.eventCount = ne;
+ if ((p = w.parker) != null)
+ U.unpark(p);
+ break;
+ }
+ if (q != null && q.base >= q.top)
+ break;
}
}
@@ -1639,214 +1633,154 @@ public class ForkJoinPool extends AbstractExecutorService {
*/
final void runWorker(WorkQueue w) {
w.growArray(); // allocate queue
- do { w.runTask(scan(w)); } while (w.qlock >= 0);
+ for (int r = w.hint; scan(w, r) == 0; ) {
+ r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift
+ }
}
/**
- * Scans for and, if found, returns one task, else possibly
+ * Scans for and, if found, runs one task, else possibly
* inactivates the worker. This method operates on single reads of
* volatile state and is designed to be re-invoked continuously,
* in part because it returns upon detecting inconsistencies,
* contention, or state changes that indicate possible success on
* re-invocation.
*
- * The scan searches for tasks across queues (starting at a random
- * index, and relying on registerWorker to irregularly scatter
- * them within array to avoid bias), checking each at least twice.
- * The scan terminates upon either finding a non-empty queue, or
- * completing the sweep. If the worker is not inactivated, it
- * takes and returns a task from this queue. Otherwise, if not
- * activated, it signals workers (that may include itself) and
- * returns so caller can retry. Also returns for true if the
- * worker array may have changed during an empty scan. On failure
- * to find a task, we take one of the following actions, after
- * which the caller will retry calling this method unless
- * terminated.
- *
- * * If pool is terminating, terminate the worker.
- *
- * * If not already enqueued, try to inactivate and enqueue the
- * worker on wait queue. Or, if inactivating has caused the pool
- * to be quiescent, relay to idleAwaitWork to possibly shrink
- * pool.
- *
- * * If already enqueued and none of the above apply, possibly
- * park awaiting signal, else lingering to help scan and signal.
- *
- * * If a non-empty queue discovered or left as a hint,
- * help wake up other workers before return.
+ * The scan searches for tasks across queues starting at a random
+ * index, checking each at least twice. The scan terminates upon
+ * either finding a non-empty queue, or completing the sweep. If
+ * the worker is not inactivated, it takes and runs a task from
+ * this queue. Otherwise, if not activated, it tries to activate
+ * itself or some other worker by signalling. On failure to find a
+ * task, returns (for retry) if pool state may have changed during
+ * an empty scan, or tries to inactivate if active, else possibly
+ * blocks or terminates via method awaitWork.
*
* @param w the worker (via its WorkQueue)
- * @return a task or null if none found
+ * @param r a random seed
+ * @return worker qlock status if would have waited, else 0
*/
- private final ForkJoinTask<?> scan(WorkQueue w) {
+ private final int scan(WorkQueue w, int r) {
WorkQueue[] ws; int m;
- int ps = plock; // read plock before ws
- if (w != null && (ws = workQueues) != null && (m = ws.length - 1) >= 0) {
- int ec = w.eventCount; // ec is negative if inactive
- int r = w.seed; r ^= r << 13; r ^= r >>> 17; w.seed = r ^= r << 5;
- w.hint = -1; // update seed and clear hint
- int j = ((m + m + 1) | MIN_SCAN) & MAX_SCAN;
- do {
- WorkQueue q; ForkJoinTask<?>[] a; int b;
- if ((q = ws[(r + j) & m]) != null && (b = q.base) - q.top < 0 &&
- (a = q.array) != null) { // probably nonempty
- int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
- ForkJoinTask<?> t = (ForkJoinTask<?>)
- U.getObjectVolatile(a, i);
- if (q.base == b && ec >= 0 && t != null &&
- U.compareAndSwapObject(a, i, t, null)) {
- if ((q.base = b + 1) - q.top < 0)
- signalWork(q);
- return t; // taken
- }
- else if ((ec < 0 || j < m) && (int)(ctl >> AC_SHIFT) <= 0) {
- w.hint = (r + j) & m; // help signal below
- break; // cannot take
+ long c = ctl; // for consistency check
+ if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 && w != null) {
+ for (int j = m + m + 1, ec = w.eventCount;;) {
+ WorkQueue q; int b, e; ForkJoinTask<?>[] a; ForkJoinTask<?> t;
+ if ((q = ws[(r - j) & m]) != null &&
+ (b = q.base) - q.top < 0 && (a = q.array) != null) {
+ long i = (((a.length - 1) & b) << ASHIFT) + ABASE;
+ if ((t = ((ForkJoinTask<?>)
+ U.getObjectVolatile(a, i))) != null) {
+ if (ec < 0)
+ helpRelease(c, ws, w, q, b);
+ else if (q.base == b &&
+ U.compareAndSwapObject(a, i, t, null)) {
+ U.putOrderedInt(q, QBASE, b + 1);
+ if ((b + 1) - q.top < 0)
+ signalWork(ws, q);
+ w.runTask(t);
+ }
}
+ break;
}
- } while (--j >= 0);
-
- int h, e, ns; long c, sc; WorkQueue q;
- if ((ns = w.nsteals) != 0) {
- if (U.compareAndSwapLong(this, STEALCOUNT,
- sc = stealCount, sc + ns))
- w.nsteals = 0; // collect steals and rescan
- }
- else if (plock != ps) // consistency check
- ; // skip
- else if ((e = (int)(c = ctl)) < 0)
- w.qlock = -1; // pool is terminating
- else {
- if ((h = w.hint) < 0) {
- if (ec >= 0) { // try to enqueue/inactivate
- long nc = (((long)ec |
- ((c - AC_UNIT) & (AC_MASK|TC_MASK))));
- w.nextWait = e; // link and mark inactive
+ else if (--j < 0) {
+ if ((ec | (e = (int)c)) < 0) // inactive or terminating
+ return awaitWork(w, c, ec);
+ else if (ctl == c) { // try to inactivate and enqueue
+ long nc = (long)ec | ((c - AC_UNIT) & (AC_MASK|TC_MASK));
+ w.nextWait = e;
w.eventCount = ec | INT_SIGN;
- if (ctl != c || !U.compareAndSwapLong(this, CTL, c, nc))
- w.eventCount = ec; // unmark on CAS failure
- else if ((int)(c >> AC_SHIFT) == 1 - (config & SMASK))
- idleAwaitWork(w, nc, c);
- }
- else if (w.eventCount < 0 && !tryTerminate(false, false) &&
- ctl == c) { // block
- Thread wt = Thread.currentThread();
- Thread.interrupted(); // clear status
- U.putObject(wt, PARKBLOCKER, this);
- w.parker = wt; // emulate LockSupport.park
- if (w.eventCount < 0) // recheck
- U.park(false, 0L);
- w.parker = null;
- U.putObject(wt, PARKBLOCKER, null);
- }
- }
- if ((h >= 0 || (h = w.hint) >= 0) &&
- (ws = workQueues) != null && h < ws.length &&
- (q = ws[h]) != null) { // signal others before retry
- WorkQueue v; Thread p; int u, i, s;
- for (int n = (config & SMASK) >>> 1;;) {
- int idleCount = (w.eventCount < 0) ? 0 : -1;
- if (((s = idleCount - q.base + q.top) <= n &&
- (n = s) <= 0) ||
- (u = (int)((c = ctl) >>> 32)) >= 0 ||
- (e = (int)c) <= 0 || m < (i = e & SMASK) ||
- (v = ws[i]) == null)
- break;
- long nc = (((long)(v.nextWait & E_MASK)) |
- ((long)(u + UAC_UNIT) << 32));
- if (v.eventCount != (e | INT_SIGN) ||
- !U.compareAndSwapLong(this, CTL, c, nc))
- break;
- v.hint = h;
- v.eventCount = (e + E_SEQ) & E_MASK;
- if ((p = v.parker) != null)
- U.unpark(p);
- if (--n <= 0)
- break;
+ if (!U.compareAndSwapLong(this, CTL, c, nc))
+ w.eventCount = ec; // back out
}
+ break;
}
}
}
- return null;
+ return 0;
}
/**
- * If inactivating worker w has caused the pool to become
- * quiescent, checks for pool termination, and, so long as this is
- * not the only worker, waits for event for up to a given
- * duration. On timeout, if ctl has not changed, terminates the
- * worker, which will in turn wake up another worker to possibly
- * repeat this process.
+ * A continuation of scan(), possibly blocking or terminating
+ * worker w. Returns without blocking if pool state has apparently
+ * changed since last invocation. Also, if inactivating w has
+ * caused the pool to become quiescent, checks for pool
+ * termination, and, so long as this is not the only worker, waits
+ * for event for up to a given duration. On timeout, if ctl has
+ * not changed, terminates the worker, which will in turn wake up
+ * another worker to possibly repeat this process.
*
* @param w the calling worker
- * @param currentCtl the ctl value triggering possible quiescence
- * @param prevCtl the ctl value to restore if thread is terminated
- */
- private void idleAwaitWork(WorkQueue w, long currentCtl, long prevCtl) {
- if (w != null && w.eventCount < 0 &&
- !tryTerminate(false, false) && (int)prevCtl != 0) {
- int dc = -(short)(currentCtl >>> TC_SHIFT);
- long parkTime = dc < 0 ? FAST_IDLE_TIMEOUT: (dc + 1) * IDLE_TIMEOUT;
- long deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP;
- Thread wt = Thread.currentThread();
- while (ctl == currentCtl) {
- Thread.interrupted(); // timed variant of version in scan()
- U.putObject(wt, PARKBLOCKER, this);
- w.parker = wt;
- if (ctl == currentCtl)
- U.park(false, parkTime);
- w.parker = null;
- U.putObject(wt, PARKBLOCKER, null);
- if (ctl != currentCtl)
- break;
- if (deadline - System.nanoTime() <= 0L &&
- U.compareAndSwapLong(this, CTL, currentCtl, prevCtl)) {
- w.eventCount = (w.eventCount + E_SEQ) | E_MASK;
- w.qlock = -1; // shrink
- break;
+ * @param c the ctl value on entry to scan
+ * @param ec the worker's eventCount on entry to scan
+ */
+ private final int awaitWork(WorkQueue w, long c, int ec) {
+ int stat, ns; long parkTime, deadline;
+ if ((stat = w.qlock) >= 0 && w.eventCount == ec && ctl == c &&
+ !Thread.interrupted()) {
+ int e = (int)c;
+ int u = (int)(c >>> 32);
+ int d = (u >> UAC_SHIFT) + parallelism; // active count
+
+ if (e < 0 || (d <= 0 && tryTerminate(false, false)))
+ stat = w.qlock = -1; // pool is terminating
+ else if ((ns = w.nsteals) != 0) { // collect steals and retry
+ long sc;
+ w.nsteals = 0;
+ do {} while (!U.compareAndSwapLong(this, STEALCOUNT,
+ sc = stealCount, sc + ns));
+ }
+ else {
+ long pc = ((d > 0 || ec != (e | INT_SIGN)) ? 0L :
+ ((long)(w.nextWait & E_MASK)) | // ctl to restore
+ ((long)(u + UAC_UNIT)) << 32);
+ if (pc != 0L) { // timed wait if last waiter
+ int dc = -(short)(c >>> TC_SHIFT);
+ parkTime = (dc < 0 ? FAST_IDLE_TIMEOUT:
+ (dc + 1) * IDLE_TIMEOUT);
+ deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP;
+ }
+ else
+ parkTime = deadline = 0L;
+ if (w.eventCount == ec && ctl == c) {
+ Thread wt = Thread.currentThread();
+ U.putObject(wt, PARKBLOCKER, this);
+ w.parker = wt; // emulate LockSupport.park
+ if (w.eventCount == ec && ctl == c)
+ U.park(false, parkTime); // must recheck before park
+ w.parker = null;
+ U.putObject(wt, PARKBLOCKER, null);
+ if (parkTime != 0L && ctl == c &&
+ deadline - System.nanoTime() <= 0L &&
+ U.compareAndSwapLong(this, CTL, c, pc))
+ stat = w.qlock = -1; // shrink pool
}
}
}
+ return stat;
}
/**
- * Scans through queues looking for work while joining a task; if
- * any present, signals. May return early if more signalling is
- * detectably unneeded.
- *
- * @param task return early if done
- * @param origin an index to start scan
- */
- private void helpSignal(ForkJoinTask<?> task, int origin) {
- WorkQueue[] ws; WorkQueue w; Thread p; long c; int m, u, e, i, s;
- if (task != null && task.status >= 0 &&
- (u = (int)(ctl >>> 32)) < 0 && (u >> UAC_SHIFT) < 0 &&
- (ws = workQueues) != null && (m = ws.length - 1) >= 0) {
- outer: for (int k = origin, j = m; j >= 0; --j) {
- WorkQueue q = ws[k++ & m];
- for (int n = m;;) { // limit to at most m signals
- if (task.status < 0)
- break outer;
- if (q == null ||
- ((s = -q.base + q.top) <= n && (n = s) <= 0))
- break;
- if ((u = (int)((c = ctl) >>> 32)) >= 0 ||
- (e = (int)c) <= 0 || m < (i = e & SMASK) ||
- (w = ws[i]) == null)
- break outer;
- long nc = (((long)(w.nextWait & E_MASK)) |
- ((long)(u + UAC_UNIT) << 32));
- if (w.eventCount != (e | INT_SIGN))
- break outer;
- if (U.compareAndSwapLong(this, CTL, c, nc)) {
- w.eventCount = (e + E_SEQ) & E_MASK;
- if ((p = w.parker) != null)
- U.unpark(p);
- if (--n <= 0)
- break;
- }
- }
+ * Possibly releases (signals) a worker. Called only from scan()
+ * when a worker with apparently inactive status finds a non-empty
+ * queue. This requires revalidating all of the associated state
+ * from caller.
+ */
+ private final void helpRelease(long c, WorkQueue[] ws, WorkQueue w,
+ WorkQueue q, int b) {
+ WorkQueue v; int e, i; Thread p;
+ if (w != null && w.eventCount < 0 && (e = (int)c) > 0 &&
+ ws != null && ws.length > (i = e & SMASK) &&
+ (v = ws[i]) != null && ctl == c) {
+ long nc = (((long)(v.nextWait & E_MASK)) |
+ ((long)((int)(c >>> 32) + UAC_UNIT)) << 32);
+ int ne = (e + E_SEQ) & E_MASK;
+ if (q != null && q.base == b && w.eventCount < 0 &&
+ v.eventCount == (e | INT_SIGN) &&
+ U.compareAndSwapLong(this, CTL, c, nc)) {
+ v.eventCount = ne;
+ if ((p = v.parker) != null)
+ U.unpark(p);
}
}
}
@@ -1871,7 +1805,8 @@ public class ForkJoinPool extends AbstractExecutorService {
*/
private int tryHelpStealer(WorkQueue joiner, ForkJoinTask<?> task) {
int stat = 0, steps = 0; // bound to avoid cycles
- if (joiner != null && task != null) { // hoist null checks
+ if (task != null && joiner != null &&
+ joiner.base - joiner.top >= 0) { // hoist checks
restart: for (;;) {
ForkJoinTask<?> subtask = task; // current target
for (WorkQueue j = joiner, v;;) { // v is stealer of subtask
@@ -1898,7 +1833,7 @@ public class ForkJoinPool extends AbstractExecutorService {
}
}
for (;;) { // help stealer or descend to its stealer
- ForkJoinTask[] a; int b;
+ ForkJoinTask[] a; int b;
if (subtask.status < 0) // surround probes with
continue restart; // consistency checks
if ((b = v.base) - v.top < 0 && (a = v.array) != null) {
@@ -1909,13 +1844,23 @@ public class ForkJoinPool extends AbstractExecutorService {
v.currentSteal != subtask)
continue restart; // stale
stat = 1; // apparent progress
- if (t != null && v.base == b &&
- U.compareAndSwapObject(a, i, t, null)) {
- v.base = b + 1; // help stealer
- joiner.runSubtask(t);
+ if (v.base == b) {
+ if (t == null)
+ break restart;
+ if (U.compareAndSwapObject(a, i, t, null)) {
+ U.putOrderedInt(v, QBASE, b + 1);
+ ForkJoinTask<?> ps = joiner.currentSteal;
+ int jt = joiner.top;
+ do {
+ joiner.currentSteal = t;
+ t.doExec(); // clear local tasks too
+ } while (task.status >= 0 &&
+ joiner.top != jt &&
+ (t = joiner.pop()) != null);
+ joiner.currentSteal = ps;
+ break restart;
+ }
}
- else if (v.base == b && ++steps == MAX_HELP)
- break restart; // v apparently stalled
}
else { // empty -- try to descend
ForkJoinTask<?> next = v.currentJoin;
@@ -1942,27 +1887,33 @@ public class ForkJoinPool extends AbstractExecutorService {
* and run tasks within the target's computation.
*
* @param task the task to join
- * @param mode if shared, exit upon completing any task
- * if all workers are active
- */
- private int helpComplete(ForkJoinTask<?> task, int mode) {
- WorkQueue[] ws; WorkQueue q; int m, n, s, u;
- if (task != null && (ws = workQueues) != null &&
- (m = ws.length - 1) >= 0) {
- for (int j = 1, origin = j;;) {
+ */
+ private int helpComplete(WorkQueue joiner, CountedCompleter<?> task) {
+ WorkQueue[] ws; int m;
+ int s = 0;
+ if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
+ joiner != null && task != null) {
+ int j = joiner.poolIndex;
+ int scans = m + m + 1;
+ long c = 0L; // for stability check
+ for (int k = scans; ; j += 2) {
+ WorkQueue q;
if ((s = task.status) < 0)
- return s;
- if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) {
- origin = j;
- if (mode == SHARED_QUEUE &&
- ((u = (int)(ctl >>> 32)) >= 0 || (u >> UAC_SHIFT) >= 0))
+ break;
+ else if (joiner.internalPopAndExecCC(task))
+ k = scans;
+ else if ((s = task.status) < 0)
+ break;
+ else if ((q = ws[j & m]) != null && q.pollAndExecCC(task))
+ k = scans;
+ else if (--k < 0) {
+ if (c == (c = ctl))
break;
+ k = scans;
}
- else if ((j = (j + 2) & m) == origin)
- break;
}
}
- return 0;
+ return s;
}
/**
@@ -1971,17 +1922,22 @@ public class ForkJoinPool extends AbstractExecutorService {
* for blocking. Fails on contention or termination. Otherwise,
* adds a new thread if no idle workers are available and pool
* may become starved.
+ *
+ * @param c the assumed ctl value
*/
- final boolean tryCompensate() {
- int pc = config & SMASK, e, i, tc; long c;
- WorkQueue[] ws; WorkQueue w; Thread p;
- if ((ws = workQueues) != null && (e = (int)(c = ctl)) >= 0) {
- if (e != 0 && (i = e & SMASK) < ws.length &&
- (w = ws[i]) != null && w.eventCount == (e | INT_SIGN)) {
+ final boolean tryCompensate(long c) {
+ WorkQueue[] ws = workQueues;
+ int pc = parallelism, e = (int)c, m, tc;
+ if (ws != null && (m = ws.length - 1) >= 0 && e >= 0 && ctl == c) {
+ WorkQueue w = ws[e & m];
+ if (e != 0 && w != null) {
+ Thread p;
long nc = ((long)(w.nextWait & E_MASK) |
(c & (AC_MASK|TC_MASK)));
- if (U.compareAndSwapLong(this, CTL, c, nc)) {
- w.eventCount = (e + E_SEQ) & E_MASK;
+ int ne = (e + E_SEQ) & E_MASK;
+ if (w.eventCount == (e | INT_SIGN) &&
+ U.compareAndSwapLong(this, CTL, c, nc)) {
+ w.eventCount = ne;
if ((p = w.parker) != null)
U.unpark(p);
return true; // replace with idle worker
@@ -2024,23 +1980,20 @@ public class ForkJoinPool extends AbstractExecutorService {
*/
final int awaitJoin(WorkQueue joiner, ForkJoinTask<?> task) {
int s = 0;
- if (joiner != null && task != null && (s = task.status) >= 0) {
+ if (task != null && (s = task.status) >= 0 && joiner != null) {
ForkJoinTask<?> prevJoin = joiner.currentJoin;
joiner.currentJoin = task;
- do {} while ((s = task.status) >= 0 && !joiner.isEmpty() &&
- joiner.tryRemoveAndExec(task)); // process local tasks
- if (s >= 0 && (s = task.status) >= 0) {
- helpSignal(task, joiner.poolIndex);
- if ((s = task.status) >= 0 &&
- (task instanceof CountedCompleter))
- s = helpComplete(task, LIFO_QUEUE);
- }
+ do {} while (joiner.tryRemoveAndExec(task) && // process local tasks
+ (s = task.status) >= 0);
+ if (s >= 0 && (task instanceof CountedCompleter))
+ s = helpComplete(joiner, (CountedCompleter<?>)task);
+ long cc = 0; // for stability checks
while (s >= 0 && (s = task.status) >= 0) {
- if ((!joiner.isEmpty() || // try helping
- (s = tryHelpStealer(joiner, task)) == 0) &&
+ if ((s = tryHelpStealer(joiner, task)) == 0 &&
(s = task.status) >= 0) {
- helpSignal(task, joiner.poolIndex);
- if ((s = task.status) >= 0 && tryCompensate()) {
+ if (!tryCompensate(cc))
+ cc = ctl;
+ else {
if (task.trySetSignal() && (s = task.status) >= 0) {
synchronized (task) {
if (task.status >= 0) {
@@ -2053,9 +2006,11 @@ public class ForkJoinPool extends AbstractExecutorService {
task.notifyAll();
}
}
- long c; // re-activate
+ long c; // reactivate
do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c + AC_UNIT));
+ (this, CTL, c = ctl,
+ ((c & ~AC_MASK) |
+ ((c & AC_MASK) + AC_UNIT))));
}
}
}
@@ -2077,15 +2032,11 @@ public class ForkJoinPool extends AbstractExecutorService {
if (joiner != null && task != null && (s = task.status) >= 0) {
ForkJoinTask<?> prevJoin = joiner.currentJoin;
joiner.currentJoin = task;
- do {} while ((s = task.status) >= 0 && !joiner.isEmpty() &&
- joiner.tryRemoveAndExec(task));
- if (s >= 0 && (s = task.status) >= 0) {
- helpSignal(task, joiner.poolIndex);
- if ((s = task.status) >= 0 &&
- (task instanceof CountedCompleter))
- s = helpComplete(task, LIFO_QUEUE);
- }
- if (s >= 0 && joiner.isEmpty()) {
+ do {} while (joiner.tryRemoveAndExec(task) && // process local tasks
+ (s = task.status) >= 0);
+ if (s >= 0) {
+ if (task instanceof CountedCompleter)
+ helpComplete(joiner, (CountedCompleter<?>)task);
do {} while (task.status >= 0 &&
tryHelpStealer(joiner, task) > 0);
}
@@ -2095,29 +2046,22 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* Returns a (probably) non-empty steal queue, if one is found
- * during a random, then cyclic scan, else null. This method must
- * be retried by caller if, by the time it tries to use the queue,
- * it is empty.
- * @param r a (random) seed for scanning
- */
- private WorkQueue findNonEmptyStealQueue(int r) {
- for (WorkQueue[] ws;;) {
- int ps = plock, m, n;
- if ((ws = workQueues) == null || (m = ws.length - 1) < 1)
- return null;
- for (int j = (m + 1) << 2; ;) {
- WorkQueue q = ws[(((r + j) << 1) | 1) & m];
- if (q != null && (n = q.base - q.top) < 0) {
- if (n < -1)
- signalWork(q);
- return q;
- }
- else if (--j < 0) {
- if (plock == ps)
- return null;
- break;
+ * during a scan, else null. This method must be retried by
+ * caller if, by the time it tries to use the queue, it is empty.
+ */
+ private WorkQueue findNonEmptyStealQueue() {
+ int r = ThreadLocalRandom.current().nextInt();
+ for (;;) {
+ int ps = plock, m; WorkQueue[] ws; WorkQueue q;
+ if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
+ for (int j = (m + 1) << 2; j >= 0; --j) {
+ if ((q = ws[(((r - j) << 1) | 1) & m]) != null &&
+ q.base - q.top < 0)
+ return q;
}
}
+ if (plock == ps)
+ return null;
}
}
@@ -2128,38 +2072,36 @@ public class ForkJoinPool extends AbstractExecutorService {
* find tasks either.
*/
final void helpQuiescePool(WorkQueue w) {
+ ForkJoinTask<?> ps = w.currentSteal;
for (boolean active = true;;) {
- ForkJoinTask<?> localTask; // exhaust local queue
- while ((localTask = w.nextLocalTask()) != null)
- localTask.doExec();
- // Similar to loop in scan(), but ignoring submissions
- WorkQueue q = findNonEmptyStealQueue(w.nextSeed());
- if (q != null) {
- ForkJoinTask<?> t; int b;
+ long c; WorkQueue q; ForkJoinTask<?> t; int b;
+ while ((t = w.nextLocalTask()) != null)
+ t.doExec();
+ if ((q = findNonEmptyStealQueue()) != null) {
if (!active) { // re-establish active count
- long c;
active = true;
do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c + AC_UNIT));
+ (this, CTL, c = ctl,
+ ((c & ~AC_MASK) |
+ ((c & AC_MASK) + AC_UNIT))));
+ }
+ if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) {
+ (w.currentSteal = t).doExec();
+ w.currentSteal = ps;
}
- if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
- w.runSubtask(t);
}
- else {
- long c;
- if (active) { // decrement active count without queuing
+ else if (active) { // decrement active count without queuing
+ long nc = ((c = ctl) & ~AC_MASK) | ((c & AC_MASK) - AC_UNIT);
+ if ((int)(nc >> AC_SHIFT) + parallelism == 0)
+ break; // bypass decrement-then-increment
+ if (U.compareAndSwapLong(this, CTL, c, nc))
active = false;
- do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c -= AC_UNIT));
- }
- else
- c = ctl; // re-increment on exit
- if ((int)(c >> AC_SHIFT) + (config & SMASK) == 0) {
- do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c + AC_UNIT));
- break;
- }
}
+ else if ((int)((c = ctl) >> AC_SHIFT) + parallelism <= 0 &&
+ U.compareAndSwapLong
+ (this, CTL, c, ((c & ~AC_MASK) |
+ ((c & AC_MASK) + AC_UNIT))))
+ break;
}
}
@@ -2173,7 +2115,7 @@ public class ForkJoinPool extends AbstractExecutorService {
WorkQueue q; int b;
if ((t = w.nextLocalTask()) != null)
return t;
- if ((q = findNonEmptyStealQueue(w.nextSeed())) == null)
+ if ((q = findNonEmptyStealQueue()) == null)
return null;
if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
return t;
@@ -2229,7 +2171,7 @@ public class ForkJoinPool extends AbstractExecutorService {
static int getSurplusQueuedTaskCount() {
Thread t; ForkJoinWorkerThread wt; ForkJoinPool pool; WorkQueue q;
if (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)) {
- int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).config & SMASK;
+ int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).parallelism;
int n = (q = wt.workQueue).top - q.base;
int a = (int)(pool.ctl >> AC_SHIFT) + p;
return n - (a > (p >>>= 1) ? 0 :
@@ -2258,45 +2200,47 @@ public class ForkJoinPool extends AbstractExecutorService {
* @return true if now terminating or terminated
*/
private boolean tryTerminate(boolean now, boolean enable) {
- if (this == commonPool) // cannot shut down
+ int ps;
+ if (this == common) // cannot shut down
return false;
+ if ((ps = plock) >= 0) { // enable by setting plock
+ if (!enable)
+ return false;
+ if ((ps & PL_LOCK) != 0 ||
+ !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+ ps = acquirePlock();
+ int nps = ((ps + PL_LOCK) & ~SHUTDOWN) | SHUTDOWN;
+ if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+ releasePlock(nps);
+ }
for (long c;;) {
- if (((c = ctl) & STOP_BIT) != 0) { // already terminating
- if ((short)(c >>> TC_SHIFT) == -(config & SMASK)) {
+ if (((c = ctl) & STOP_BIT) != 0) { // already terminating
+ if ((short)(c >>> TC_SHIFT) + parallelism <= 0) {
synchronized (this) {
- notifyAll(); // signal when 0 workers
+ notifyAll(); // signal when 0 workers
}
}
return true;
}
- if (plock >= 0) { // not yet enabled
- int ps;
- if (!enable)
- return false;
- if (((ps = plock) & PL_LOCK) != 0 ||
- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
- ps = acquirePlock();
- if (!U.compareAndSwapInt(this, PLOCK, ps, SHUTDOWN))
- releasePlock(SHUTDOWN);
- }
- if (!now) { // check if idle & no tasks
- if ((int)(c >> AC_SHIFT) != -(config & SMASK) ||
- hasQueuedSubmissions())
+ if (!now) { // check if idle & no tasks
+ WorkQueue[] ws; WorkQueue w;
+ if ((int)(c >> AC_SHIFT) + parallelism > 0)
return false;
- // Check for unqueued inactive workers. One pass suffices.
- WorkQueue[] ws = workQueues; WorkQueue w;
- if (ws != null) {
- for (int i = 1; i < ws.length; i += 2) {
- if ((w = ws[i]) != null && w.eventCount >= 0)
+ if ((ws = workQueues) != null) {
+ for (int i = 0; i < ws.length; ++i) {
+ if ((w = ws[i]) != null &&
+ (!w.isEmpty() ||
+ ((i & 1) != 0 && w.eventCount >= 0))) {
+ signalWork(ws, w);
return false;
+ }
}
}
}
if (U.compareAndSwapLong(this, CTL, c, c | STOP_BIT)) {
for (int pass = 0; pass < 3; ++pass) {
- WorkQueue[] ws = workQueues;
- if (ws != null) {
- WorkQueue w; Thread wt;
+ WorkQueue[] ws; WorkQueue w; Thread wt;
+ if ((ws = workQueues) != null) {
int n = ws.length;
for (int i = 0; i < n; ++i) {
if ((w = ws[i]) != null) {
@@ -2307,7 +2251,7 @@ public class ForkJoinPool extends AbstractExecutorService {
if (!wt.isInterrupted()) {
try {
wt.interrupt();
- } catch (SecurityException ignore) {
+ } catch (Throwable ignore) {
}
}
U.unpark(wt);
@@ -2318,7 +2262,7 @@ public class ForkJoinPool extends AbstractExecutorService {
// Wake up workers parked on event queue
int i, e; long cc; Thread p;
while ((e = (int)(cc = ctl) & E_MASK) != 0 &&
- (i = e & SMASK) < n &&
+ (i = e & SMASK) < n && i >= 0 &&
(w = ws[i]) != null) {
long nc = ((long)(w.nextWait & E_MASK) |
((cc + AC_UNIT) & AC_MASK) |
@@ -2344,9 +2288,9 @@ public class ForkJoinPool extends AbstractExecutorService {
* least one task.
*/
static WorkQueue commonSubmitterQueue() {
- ForkJoinPool p; WorkQueue[] ws; int m; Submitter z;
+ Submitter z; ForkJoinPool p; WorkQueue[] ws; int m, r;
return ((z = submitters.get()) != null &&
- (p = commonPool) != null &&
+ (p = common) != null &&
(ws = p.workQueues) != null &&
(m = ws.length - 1) >= 0) ?
ws[m & z.seed & SQMASK] : null;
@@ -2355,127 +2299,57 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* Tries to pop the given task from submitter's queue in common pool.
*/
- static boolean tryExternalUnpush(ForkJoinTask<?> t) {
- ForkJoinPool p; WorkQueue[] ws; WorkQueue q; Submitter z;
- ForkJoinTask<?>[] a; int m, s;
- if (t != null &&
- (z = submitters.get()) != null &&
- (p = commonPool) != null &&
- (ws = p.workQueues) != null &&
- (m = ws.length - 1) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
- (s = q.top) != q.base &&
- (a = q.array) != null) {
+ final boolean tryExternalUnpush(ForkJoinTask<?> task) {
+ WorkQueue joiner; ForkJoinTask<?>[] a; int m, s;
+ Submitter z = submitters.get();
+ WorkQueue[] ws = workQueues;
+ boolean popped = false;
+ if (z != null && ws != null && (m = ws.length - 1) >= 0 &&
+ (joiner = ws[z.seed & m & SQMASK]) != null &&
+ joiner.base != (s = joiner.top) &&
+ (a = joiner.array) != null) {
long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
- if (U.getObject(a, j) == t &&
- U.compareAndSwapInt(q, QLOCK, 0, 1)) {
- if (q.array == a && q.top == s && // recheck
- U.compareAndSwapObject(a, j, t, null)) {
- q.top = s - 1;
- q.qlock = 0;
- return true;
+ if (U.getObject(a, j) == task &&
+ U.compareAndSwapInt(joiner, QLOCK, 0, 1)) {
+ if (joiner.top == s && joiner.array == a &&
+ U.compareAndSwapObject(a, j, task, null)) {
+ joiner.top = s - 1;
+ popped = true;
}
- q.qlock = 0;
+ joiner.qlock = 0;
}
}
- return false;
+ return popped;
}
- /**
- * Tries to pop and run local tasks within the same computation
- * as the given root. On failure, tries to help complete from
- * other queues via helpComplete.
- */
- private void externalHelpComplete(WorkQueue q, ForkJoinTask<?> root) {
- ForkJoinTask<?>[] a; int m;
- if (q != null && (a = q.array) != null && (m = (a.length - 1)) >= 0 &&
- root != null && root.status >= 0) {
- for (;;) {
- int s, u; Object o; CountedCompleter<?> task = null;
- if ((s = q.top) - q.base > 0) {
- long j = ((m & (s - 1)) << ASHIFT) + ABASE;
- if ((o = U.getObject(a, j)) != null &&
- (o instanceof CountedCompleter)) {
- CountedCompleter<?> t = (CountedCompleter<?>)o, r = t;
- do {
- if (r == root) {
- if (U.compareAndSwapInt(q, QLOCK, 0, 1)) {
- if (q.array == a && q.top == s &&
- U.compareAndSwapObject(a, j, t, null)) {
- q.top = s - 1;
- task = t;
- }
- q.qlock = 0;
- }
- break;
- }
- } while ((r = r.completer) != null);
- }
- }
- if (task != null)
- task.doExec();
- if (root.status < 0 ||
- (u = (int)(ctl >>> 32)) >= 0 || (u >> UAC_SHIFT) >= 0)
+ final int externalHelpComplete(CountedCompleter<?> task) {
+ WorkQueue joiner; int m, j;
+ Submitter z = submitters.get();
+ WorkQueue[] ws = workQueues;
+ int s = 0;
+ if (z != null && ws != null && (m = ws.length - 1) >= 0 &&
+ (joiner = ws[(j = z.seed) & m & SQMASK]) != null && task != null) {
+ int scans = m + m + 1;
+ long c = 0L; // for stability check
+ j |= 1; // poll odd queues
+ for (int k = scans; ; j += 2) {
+ WorkQueue q;
+ if ((s = task.status) < 0)
break;
- if (task == null) {
- helpSignal(root, q.poolIndex);
- if (root.status >= 0)
- helpComplete(root, SHARED_QUEUE);
+ else if (joiner.externalPopAndExecCC(task))
+ k = scans;
+ else if ((s = task.status) < 0)
break;
+ else if ((q = ws[j & m]) != null && q.pollAndExecCC(task))
+ k = scans;
+ else if (--k < 0) {
+ if (c == (c = ctl))
+ break;
+ k = scans;
}
}
}
- }
-
- /**
- * Tries to help execute or signal availability of the given task
- * from submitter's queue in common pool.
- */
- static void externalHelpJoin(ForkJoinTask<?> t) {
- // Some hard-to-avoid overlap with tryExternalUnpush
- ForkJoinPool p; WorkQueue[] ws; WorkQueue q, w; Submitter z;
- ForkJoinTask<?>[] a; int m, s, n;
- if (t != null &&
- (z = submitters.get()) != null &&
- (p = commonPool) != null &&
- (ws = p.workQueues) != null &&
- (m = ws.length - 1) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
- (a = q.array) != null) {
- int am = a.length - 1;
- if ((s = q.top) != q.base) {
- long j = ((am & (s - 1)) << ASHIFT) + ABASE;
- if (U.getObject(a, j) == t &&
- U.compareAndSwapInt(q, QLOCK, 0, 1)) {
- if (q.array == a && q.top == s &&
- U.compareAndSwapObject(a, j, t, null)) {
- q.top = s - 1;
- q.qlock = 0;
- t.doExec();
- }
- else
- q.qlock = 0;
- }
- }
- if (t.status >= 0) {
- if (t instanceof CountedCompleter)
- p.externalHelpComplete(q, t);
- else
- p.helpSignal(t, q.poolIndex);
- }
- }
- }
-
- /**
- * Restricted version of helpQuiescePool for external callers
- */
- static void externalHelpQuiescePool() {
- ForkJoinPool p; ForkJoinTask<?> t; WorkQueue q; int b;
- if ((p = commonPool) != null &&
- (q = p.findNonEmptyStealQueue(1)) != null &&
- (b = q.base) - q.top < 0 &&
- (t = q.pollAt(b)) != null)
- t.doExec();
+ return s;
}
// Exported methods
@@ -2529,49 +2403,65 @@ public class ForkJoinPool extends AbstractExecutorService {
*/
public ForkJoinPool(int parallelism,
ForkJoinWorkerThreadFactory factory,
- Thread.UncaughtExceptionHandler handler,
+ UncaughtExceptionHandler handler,
boolean asyncMode) {
+ this(checkParallelism(parallelism),
+ checkFactory(factory),
+ handler,
+ (asyncMode ? FIFO_QUEUE : LIFO_QUEUE),
+ "ForkJoinPool-" + nextPoolId() + "-worker-");
checkPermission();
- if (factory == null)
- throw new NullPointerException();
+ }
+
+ private static int checkParallelism(int parallelism) {
if (parallelism <= 0 || parallelism > MAX_CAP)
throw new IllegalArgumentException();
- this.factory = factory;
- this.ueh = handler;
- this.config = parallelism | (asyncMode ? (FIFO_QUEUE << 16) : 0);
- long np = (long)(-parallelism); // offset ctl counts
- this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
- int pn = nextPoolId();
- StringBuilder sb = new StringBuilder("ForkJoinPool-");
- sb.append(Integer.toString(pn));
- sb.append("-worker-");
- this.workerNamePrefix = sb.toString();
+ return parallelism;
+ }
+
+ private static ForkJoinWorkerThreadFactory checkFactory
+ (ForkJoinWorkerThreadFactory factory) {
+ if (factory == null)
+ throw new NullPointerException();
+ return factory;
}
/**
- * Constructor for common pool, suitable only for static initialization.
- * Basically the same as above, but uses smallest possible initial footprint.
+ * Creates a {@code ForkJoinPool} with the given parameters, without
+ * any security checks or parameter validation. Invoked directly by
+ * makeCommonPool.
*/
- ForkJoinPool(int parallelism, long ctl,
- ForkJoinWorkerThreadFactory factory,
- Thread.UncaughtExceptionHandler handler) {
- this.config = parallelism;
- this.ctl = ctl;
+ private ForkJoinPool(int parallelism,
+ ForkJoinWorkerThreadFactory factory,
+ UncaughtExceptionHandler handler,
+ int mode,
+ String workerNamePrefix) {
+ this.workerNamePrefix = workerNamePrefix;
this.factory = factory;
this.ueh = handler;
- this.workerNamePrefix = "ForkJoinPool.commonPool-worker-";
+ this.mode = (short)mode;
+ this.parallelism = (short)parallelism;
+ long np = (long)(-parallelism); // offset ctl counts
+ this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
}
/**
- * Returns the common pool instance.
+ * Returns the common pool instance. This pool is statically
+ * constructed; its run state is unaffected by attempts to {@link
+ * #shutdown} or {@link #shutdownNow}. However this pool and any
+ * ongoing processing are automatically terminated upon program
+ * {@link System#exit}. Any program that relies on asynchronous
+ * task processing to complete before program termination should
+ * invoke {@code commonPool().}{@link #awaitQuiescence awaitQuiescence},
+ * before exit.
*
* @return the common pool instance
* @since 1.8
* @hide
*/
public static ForkJoinPool commonPool() {
- // assert commonPool != null : "static init error";
- return commonPool;
+ // assert common != null : "static init error";
+ return common;
}
// Execution methods
@@ -2627,7 +2517,7 @@ public class ForkJoinPool extends AbstractExecutorService {
if (task instanceof ForkJoinTask<?>) // avoid re-wrap
job = (ForkJoinTask<?>) task;
else
- job = new ForkJoinTask.AdaptedRunnableAction(task);
+ job = new ForkJoinTask.RunnableExecuteAction(task);
externalPush(job);
}
@@ -2729,7 +2619,7 @@ public class ForkJoinPool extends AbstractExecutorService {
*
* @return the handler, or {@code null} if none
*/
- public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
+ public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return ueh;
}
@@ -2739,7 +2629,8 @@ public class ForkJoinPool extends AbstractExecutorService {
* @return the targeted parallelism level of this pool
*/
public int getParallelism() {
- return config & SMASK;
+ int par;
+ return ((par = parallelism) > 0) ? par : 1;
}
/**
@@ -2750,7 +2641,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* @hide
*/
public static int getCommonPoolParallelism() {
- return commonPoolParallelism;
+ return commonParallelism;
}
/**
@@ -2762,7 +2653,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* @return the number of worker threads
*/
public int getPoolSize() {
- return (config & SMASK) + (short)(ctl >>> TC_SHIFT);
+ return parallelism + (short)(ctl >>> TC_SHIFT);
}
/**
@@ -2772,7 +2663,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* @return {@code true} if this pool uses async mode
*/
public boolean getAsyncMode() {
- return (config >>> 16) == FIFO_QUEUE;
+ return mode == FIFO_QUEUE;
}
/**
@@ -2803,7 +2694,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* @return the number of active threads
*/
public int getActiveThreadCount() {
- int r = (config & SMASK) + (int)(ctl >> AC_SHIFT);
+ int r = parallelism + (int)(ctl >> AC_SHIFT);
return (r <= 0) ? 0 : r; // suppress momentarily negative values
}
@@ -2819,7 +2710,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* @return {@code true} if all threads are currently idle
*/
public boolean isQuiescent() {
- return (int)(ctl >> AC_SHIFT) + (config & SMASK) == 0;
+ return parallelism + (int)(ctl >> AC_SHIFT) <= 0;
}
/**
@@ -2982,7 +2873,7 @@ public class ForkJoinPool extends AbstractExecutorService {
}
}
}
- int pc = (config & SMASK);
+ int pc = parallelism;
int tc = pc + (short)(c >>> TC_SHIFT);
int ac = pc + (int)(c >> AC_SHIFT);
if (ac < 0) // ignore transient negative
@@ -3008,15 +2899,10 @@ public class ForkJoinPool extends AbstractExecutorService {
* Possibly initiates an orderly shutdown in which previously
* submitted tasks are executed, but no new tasks will be
* accepted. Invocation has no effect on execution state if this
- * is the {@link #commonPool()}, and no additional effect if
+ * is the {@code commonPool()}, and no additional effect if
* already shut down. Tasks that are in the process of being
* submitted concurrently during the course of this method may or
* may not be rejected.
- *
- * @throws SecurityException if a security manager exists and
- * the caller is not permitted to modify threads
- * because it does not hold {@link
- * java.lang.RuntimePermission}{@code ("modifyThread")}
*/
public void shutdown() {
checkPermission();
@@ -3026,7 +2912,7 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* Possibly attempts to cancel and/or stop all tasks, and reject
* all subsequently submitted tasks. Invocation has no effect on
- * execution state if this is the {@link #commonPool()}, and no
+ * execution state if this is the {@code commonPool()}, and no
* additional effect if already shut down. Otherwise, tasks that
* are in the process of being submitted or executed concurrently
* during the course of this method may or may not be
@@ -3051,7 +2937,7 @@ public class ForkJoinPool extends AbstractExecutorService {
public boolean isTerminated() {
long c = ctl;
return ((c & STOP_BIT) != 0L &&
- (short)(c >>> TC_SHIFT) == -(config & SMASK));
+ (short)(c >>> TC_SHIFT) + parallelism <= 0);
}
/**
@@ -3070,7 +2956,7 @@ public class ForkJoinPool extends AbstractExecutorService {
public boolean isTerminating() {
long c = ctl;
return ((c & STOP_BIT) != 0L &&
- (short)(c >>> TC_SHIFT) != -(config & SMASK));
+ (short)(c >>> TC_SHIFT) + parallelism > 0);
}
/**
@@ -3085,9 +2971,10 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* Blocks until all tasks have completed execution after a
* shutdown request, or the timeout occurs, or the current thread
- * is interrupted, whichever happens first. Note that the {@link
- * #commonPool()} never terminates until program shutdown so
- * this method will always time out.
+ * is interrupted, whichever happens first. Because the {@code
+ * commonPool()} never terminates until program shutdown, when
+ * applied to the common pool, this method is equivalent to {@link
+ * #awaitQuiescence(long, TimeUnit)} but always returns {@code false}.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
@@ -3097,6 +2984,12 @@ public class ForkJoinPool extends AbstractExecutorService {
*/
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (this == common) {
+ awaitQuiescence(timeout, unit);
+ return false;
+ }
long nanos = unit.toNanos(timeout);
if (isTerminated())
return true;
@@ -3117,6 +3010,59 @@ public class ForkJoinPool extends AbstractExecutorService {
}
/**
+ * If called by a ForkJoinTask operating in this pool, equivalent
+ * in effect to {@link ForkJoinTask#helpQuiesce}. Otherwise,
+ * waits and/or attempts to assist performing tasks until this
+ * pool {@link #isQuiescent} or the indicated timeout elapses.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return {@code true} if quiescent; {@code false} if the
+ * timeout elapsed.
+ */
+ public boolean awaitQuiescence(long timeout, TimeUnit unit) {
+ long nanos = unit.toNanos(timeout);
+ ForkJoinWorkerThread wt;
+ Thread thread = Thread.currentThread();
+ if ((thread instanceof ForkJoinWorkerThread) &&
+ (wt = (ForkJoinWorkerThread)thread).pool == this) {
+ helpQuiescePool(wt.workQueue);
+ return true;
+ }
+ long startTime = System.nanoTime();
+ WorkQueue[] ws;
+ int r = 0, m;
+ boolean found = true;
+ while (!isQuiescent() && (ws = workQueues) != null &&
+ (m = ws.length - 1) >= 0) {
+ if (!found) {
+ if ((System.nanoTime() - startTime) > nanos)
+ return false;
+ Thread.yield(); // cannot block
+ }
+ found = false;
+ for (int j = (m + 1) << 2; j >= 0; --j) {
+ ForkJoinTask<?> t; WorkQueue q; int b;
+ if ((q = ws[r++ & m]) != null && (b = q.base) - q.top < 0) {
+ found = true;
+ if ((t = q.pollAt(b)) != null)
+ t.doExec();
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Waits and/or attempts to assist performing tasks indefinitely
+ * until the {@code commonPool()} {@link #isQuiescent}.
+ */
+ static void quiesceCommonPool() {
+ common.awaitQuiescence(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ }
+
+ /**
* Interface for extending managed parallelism for tasks running
* in {@link ForkJoinPool}s.
*
@@ -3125,9 +3071,9 @@ public class ForkJoinPool extends AbstractExecutorService {
* not necessary. Method {@code block} blocks the current thread
* if necessary (perhaps internally invoking {@code isReleasable}
* before actually blocking). These actions are performed by any
- * thread invoking {@link ForkJoinPool#managedBlock}. The
- * unusual methods in this API accommodate synchronizers that may,
- * but don't usually, block for long periods. Similarly, they
+ * thread invoking {@link ForkJoinPool#managedBlock(ManagedBlocker)}.
+ * The unusual methods in this API accommodate synchronizers that
+ * may, but don't usually, block for long periods. Similarly, they
* allow more efficient internal handling of cases in which
* additional workers may be, but usually are not, needed to
* ensure sufficient parallelism. Toward this end,
@@ -3185,6 +3131,7 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* Returns {@code true} if blocking is unnecessary.
+ * @return {@code true} if blocking is unnecessary
*/
boolean isReleasable();
}
@@ -3214,21 +3161,8 @@ public class ForkJoinPool extends AbstractExecutorService {
Thread t = Thread.currentThread();
if (t instanceof ForkJoinWorkerThread) {
ForkJoinPool p = ((ForkJoinWorkerThread)t).pool;
- while (!blocker.isReleasable()) { // variant of helpSignal
- WorkQueue[] ws; WorkQueue q; int m, u;
- if ((ws = p.workQueues) != null && (m = ws.length - 1) >= 0) {
- for (int i = 0; i <= m; ++i) {
- if (blocker.isReleasable())
- return;
- if ((q = ws[i]) != null && q.base - q.top < 0) {
- p.signalWork(q);
- if ((u = (int)(p.ctl >>> 32)) >= 0 ||
- (u >> UAC_SHIFT) >= 0)
- break;
- }
- }
- }
- if (p.tryCompensate()) {
+ while (!blocker.isReleasable()) {
+ if (p.tryCompensate(p.ctl)) {
try {
do {} while (!blocker.isReleasable() &&
!blocker.block());
@@ -3266,6 +3200,7 @@ public class ForkJoinPool extends AbstractExecutorService {
private static final long STEALCOUNT;
private static final long PLOCK;
private static final long INDEXSEED;
+ private static final long QBASE;
private static final long QLOCK;
static {
@@ -3285,6 +3220,8 @@ public class ForkJoinPool extends AbstractExecutorService {
PARKBLOCKER = U.objectFieldOffset
(tk.getDeclaredField("parkBlocker"));
Class<?> wk = WorkQueue.class;
+ QBASE = U.objectFieldOffset
+ (wk.getDeclaredField("base"));
QLOCK = U.objectFieldOffset
(wk.getDeclaredField("qlock"));
Class<?> ak = ForkJoinTask[].class;
@@ -3298,45 +3235,51 @@ public class ForkJoinPool extends AbstractExecutorService {
}
submitters = new ThreadLocal<Submitter>();
- ForkJoinWorkerThreadFactory fac = defaultForkJoinWorkerThreadFactory =
+ defaultForkJoinWorkerThreadFactory =
new DefaultForkJoinWorkerThreadFactory();
modifyThreadPermission = new RuntimePermission("modifyThread");
- /*
- * Establish common pool parameters. For extra caution,
- * computations to set up common pool state are here; the
- * constructor just assigns these values to fields.
- */
+ common = java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction<ForkJoinPool>() {
+ public ForkJoinPool run() { return makeCommonPool(); }});
+ int par = common.parallelism; // report 1 even if threads disabled
+ commonParallelism = par > 0 ? par : 1;
+ }
- int par = 0;
- Thread.UncaughtExceptionHandler handler = null;
- try { // TBD: limit or report ignored exceptions?
+ /**
+ * Creates and returns the common pool, respecting user settings
+ * specified via system properties.
+ */
+ private static ForkJoinPool makeCommonPool() {
+ int parallelism = -1;
+ ForkJoinWorkerThreadFactory factory
+ = defaultForkJoinWorkerThreadFactory;
+ UncaughtExceptionHandler handler = null;
+ try { // ignore exceptions in accessing/parsing properties
String pp = System.getProperty
("java.util.concurrent.ForkJoinPool.common.parallelism");
- String hp = System.getProperty
- ("java.util.concurrent.ForkJoinPool.common.exceptionHandler");
String fp = System.getProperty
("java.util.concurrent.ForkJoinPool.common.threadFactory");
+ String hp = System.getProperty
+ ("java.util.concurrent.ForkJoinPool.common.exceptionHandler");
+ if (pp != null)
+ parallelism = Integer.parseInt(pp);
if (fp != null)
- fac = ((ForkJoinWorkerThreadFactory)ClassLoader.
- getSystemClassLoader().loadClass(fp).newInstance());
+ factory = ((ForkJoinWorkerThreadFactory)ClassLoader.
+ getSystemClassLoader().loadClass(fp).newInstance());
if (hp != null)
- handler = ((Thread.UncaughtExceptionHandler)ClassLoader.
+ handler = ((UncaughtExceptionHandler)ClassLoader.
getSystemClassLoader().loadClass(hp).newInstance());
- if (pp != null)
- par = Integer.parseInt(pp);
} catch (Exception ignore) {
}
- if (par <= 0)
- par = Runtime.getRuntime().availableProcessors();
- if (par > MAX_CAP)
- par = MAX_CAP;
- commonPoolParallelism = par;
- long np = (long)(-par); // precompute initial ctl value
- long ct = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
-
- commonPool = new ForkJoinPool(par, ct, fac, handler);
+ if (parallelism < 0 && // default 1 less than #cores
+ (parallelism = Runtime.getRuntime().availableProcessors() - 1) < 0)
+ parallelism = 0;
+ if (parallelism > MAX_CAP)
+ parallelism = MAX_CAP;
+ return new ForkJoinPool(parallelism, factory, handler, LIFO_QUEUE,
+ "ForkJoinPool.commonPool-worker-");
}
}
diff --git a/luni/src/main/java/java/util/concurrent/ForkJoinTask.java b/luni/src/main/java/java/util/concurrent/ForkJoinTask.java
index 818788e..c6bc6de 100644
--- a/luni/src/main/java/java/util/concurrent/ForkJoinTask.java
+++ b/luni/src/main/java/java/util/concurrent/ForkJoinTask.java
@@ -32,8 +32,8 @@ import java.lang.reflect.Constructor;
*
* <p>A "main" {@code ForkJoinTask} begins execution when it is
* explicitly submitted to a {@link ForkJoinPool}, or, if not already
- * engaged in a ForkJoin computation, commenced in the {@link
- * ForkJoinPool#commonPool()} via {@link #fork}, {@link #invoke}, or
+ * engaged in a ForkJoin computation, commenced in the {@code
+ * ForkJoinPool.commonPool()} via {@link #fork}, {@link #invoke}, or
* related methods. Once started, it will usually in turn start other
* subtasks. As indicated by the name of this class, many programs
* using {@code ForkJoinTask} employ only methods {@link #fork} and
@@ -74,10 +74,9 @@ import java.lang.reflect.Constructor;
* but doing do requires three further considerations: (1) Completion
* of few if any <em>other</em> tasks should be dependent on a task
* that blocks on external synchronization or I/O. Event-style async
- * tasks that are never joined (for example, those subclassing {@link
- * CountedCompleter}) often fall into this category. (2) To minimize
- * resource impact, tasks should be small; ideally performing only the
- * (possibly) blocking action. (3) Unless the {@link
+ * tasks that are never joined often fall into this category.
+ * (2) To minimize resource impact, tasks should be small; ideally
+ * performing only the (possibly) blocking action. (3) Unless the {@link
* ForkJoinPool.ManagedBlocker} API is used, or the number of possibly
* blocked tasks is known to be less than the pool's {@link
* ForkJoinPool#getParallelism} level, the pool cannot guarantee that
@@ -120,13 +119,11 @@ import java.lang.reflect.Constructor;
* <p>The ForkJoinTask class is not usually directly subclassed.
* Instead, you subclass one of the abstract classes that support a
* particular style of fork/join processing, typically {@link
- * RecursiveAction} for most computations that do not return results,
- * {@link RecursiveTask} for those that do, and {@link
- * CountedCompleter} for those in which completed actions trigger
- * other actions. Normally, a concrete ForkJoinTask subclass declares
- * fields comprising its parameters, established in a constructor, and
- * then defines a {@code compute} method that somehow uses the control
- * methods supplied by this base class.
+ * RecursiveAction} for most computations that do not return results
+ * and {@link RecursiveTask} for those that do. Normally, a concrete
+ * ForkJoinTask subclass declares fields comprising its parameters,
+ * established in a constructor, and then defines a {@code compute}
+ * method that somehow uses the control methods supplied by this base class.
*
* <p>Method {@link #join} and its variants are appropriate for use
* only when completion dependencies are acyclic; that is, the
@@ -136,11 +133,11 @@ import java.lang.reflect.Constructor;
* supports other methods and techniques (for example the use of
* {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that
* may be of use in constructing custom subclasses for problems that
- * are not statically structured as DAGs. To support such usages a
+ * are not statically structured as DAGs. To support such usages, a
* ForkJoinTask may be atomically <em>tagged</em> with a {@code short}
- * value using {@link #setForkJoinTaskTag} or {@link
- * #compareAndSetForkJoinTaskTag} and checked using {@link
- * #getForkJoinTaskTag}. The ForkJoinTask implementation does not use
+ * value using {@code setForkJoinTaskTag} or {@code
+ * compareAndSetForkJoinTaskTag} and checked using {@code
+ * getForkJoinTaskTag}. The ForkJoinTask implementation does not use
* these {@code protected} methods or tags for any purpose, but they
* may be of use in the construction of specialized subclasses. For
* example, parallel graph traversals can use the supplied methods to
@@ -178,7 +175,6 @@ import java.lang.reflect.Constructor;
* execution. Serialization is not relied on during execution itself.
*
* @since 1.7
- * @hide
* @author Doug Lea
*/
public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
@@ -286,25 +282,35 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
*/
private int externalAwaitDone() {
int s;
- ForkJoinPool.externalHelpJoin(this);
- boolean interrupted = false;
- while ((s = status) >= 0) {
- if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
- synchronized (this) {
- if (status >= 0) {
- try {
- wait();
- } catch (InterruptedException ie) {
- interrupted = true;
+ ForkJoinPool cp = ForkJoinPool.common;
+ if ((s = status) >= 0) {
+ if (cp != null) {
+ if (this instanceof CountedCompleter)
+ s = cp.externalHelpComplete((CountedCompleter<?>)this);
+ else if (cp.tryExternalUnpush(this))
+ s = doExec();
+ }
+ if (s >= 0 && (s = status) >= 0) {
+ boolean interrupted = false;
+ do {
+ if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+ synchronized (this) {
+ if (status >= 0) {
+ try {
+ wait();
+ } catch (InterruptedException ie) {
+ interrupted = true;
+ }
+ }
+ else
+ notifyAll();
}
}
- else
- notifyAll();
- }
+ } while ((s = status) >= 0);
+ if (interrupted)
+ Thread.currentThread().interrupt();
}
}
- if (interrupted)
- Thread.currentThread().interrupt();
return s;
}
@@ -313,9 +319,15 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
*/
private int externalInterruptibleAwaitDone() throws InterruptedException {
int s;
+ ForkJoinPool cp = ForkJoinPool.common;
if (Thread.interrupted())
throw new InterruptedException();
- ForkJoinPool.externalHelpJoin(this);
+ if ((s = status) >= 0 && cp != null) {
+ if (this instanceof CountedCompleter)
+ cp.externalHelpComplete((CountedCompleter<?>)this);
+ else if (cp.tryExternalUnpush(this))
+ doExec();
+ }
while ((s = status) >= 0) {
if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
synchronized (this) {
@@ -329,7 +341,6 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
return s;
}
-
/**
* Implementation for join, get, quietlyJoin. Directly handles
* only cases of already-completed, external wait, and
@@ -601,14 +612,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
/**
* A version of "sneaky throw" to relay exceptions
*/
- static void rethrow(final Throwable ex) {
- if (ex != null) {
- if (ex instanceof Error)
- throw (Error)ex;
- if (ex instanceof RuntimeException)
- throw (RuntimeException)ex;
- throw uncheckedThrowable(ex, RuntimeException.class);
- }
+ static void rethrow(Throwable ex) {
+ if (ex != null)
+ ForkJoinTask.<RuntimeException>uncheckedThrow(ex);
}
/**
@@ -617,8 +623,8 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
* unchecked exceptions
*/
@SuppressWarnings("unchecked") static <T extends Throwable>
- T uncheckedThrowable(final Throwable t, final Class<T> c) {
- return (T)t; // rely on vacuous cast
+ void uncheckedThrow(Throwable t) throws T {
+ throw (T)t; // rely on vacuous cast
}
/**
@@ -635,8 +641,8 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
/**
* Arranges to asynchronously execute this task in the pool the
- * current task is running in, if applicable, or using the {@link
- * ForkJoinPool#commonPool()} if not {@link #inForkJoinPool}. While
+ * current task is running in, if applicable, or using the {@code
+ * ForkJoinPool.commonPool()} if not {@link #inForkJoinPool}. While
* it is not necessarily enforced, it is a usage error to fork a
* task more than once unless it has completed and been
* reinitialized. Subsequent modifications to the state of this
@@ -653,7 +659,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
((ForkJoinWorkerThread)t).workQueue.push(this);
else
- ForkJoinPool.commonPool.externalPush(this);
+ ForkJoinPool.common.externalPush(this);
return this;
}
@@ -774,8 +780,6 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
* @param tasks the collection of tasks
* @return the tasks argument, to simplify usage
* @throws NullPointerException if tasks or any element are null
-
- * @hide
*/
public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) {
if (!(tasks instanceof RandomAccess) || !(tasks instanceof List<?>)) {
@@ -831,7 +835,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
* <p>This method is designed to be invoked by <em>other</em>
* tasks. To terminate the current task, you can just return or
* throw an unchecked exception from its computation method, or
- * invoke {@link #completeExceptionally}.
+ * invoke {@link #completeExceptionally(Throwable)}.
*
* @param mayInterruptIfRunning this value has no effect in the
* default implementation because interrupts are not used to
@@ -984,6 +988,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
// Messy in part because we measure in nanosecs, but wait in millisecs
int s; long ms;
long ns = unit.toNanos(timeout);
+ ForkJoinPool cp;
if ((s = status) >= 0 && ns > 0L) {
long deadline = System.nanoTime() + ns;
ForkJoinPool p = null;
@@ -995,8 +1000,12 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
w = wt.workQueue;
p.helpJoinOnce(w, this); // no retries on failure
}
- else
- ForkJoinPool.externalHelpJoin(this);
+ else if ((cp = ForkJoinPool.common) != null) {
+ if (this instanceof CountedCompleter)
+ cp.externalHelpComplete((CountedCompleter<?>)this);
+ else if (cp.tryExternalUnpush(this))
+ doExec();
+ }
boolean canBlock = false;
boolean interrupted = false;
try {
@@ -1004,7 +1013,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
if (w != null && w.qlock < 0)
cancelIgnoringExceptions(this);
else if (!canBlock) {
- if (p == null || p.tryCompensate())
+ if (p == null || p.tryCompensate(p.ctl))
canBlock = true;
}
else {
@@ -1080,7 +1089,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
wt.pool.helpQuiescePool(wt.workQueue);
}
else
- ForkJoinPool.externalHelpQuiescePool();
+ ForkJoinPool.quiesceCommonPool();
}
/**
@@ -1145,7 +1154,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
Thread t;
return (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
((ForkJoinWorkerThread)t).workQueue.tryUnpush(this) :
- ForkJoinPool.tryExternalUnpush(this));
+ ForkJoinPool.common.tryExternalUnpush(this));
}
/**
@@ -1316,7 +1325,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
*
* @param e the expected tag value
* @param tag the new tag value
- * @return true if successful; i.e., the current value was
+ * @return {@code true} if successful; i.e., the current value was
* equal to e and is now tag.
* @since 1.8
* @hide
@@ -1370,6 +1379,24 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
}
/**
+ * Adaptor for Runnables in which failure forces worker exception
+ */
+ static final class RunnableExecuteAction extends ForkJoinTask<Void> {
+ final Runnable runnable;
+ RunnableExecuteAction(Runnable runnable) {
+ if (runnable == null) throw new NullPointerException();
+ this.runnable = runnable;
+ }
+ public final Void getRawResult() { return null; }
+ public final void setRawResult(Void v) { }
+ public final boolean exec() { runnable.run(); return true; }
+ void internalPropagateException(Throwable ex) {
+ rethrow(ex); // rethrow outside exec() catches.
+ }
+ private static final long serialVersionUID = 5232453952276885070L;
+ }
+
+ /**
* Adaptor for Callables
*/
static final class AdaptedCallable<T> extends ForkJoinTask<T>
@@ -1480,5 +1507,4 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
throw new Error(e);
}
}
-
}
diff --git a/luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java b/luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java
index f31763c..ae28700 100644
--- a/luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java
+++ b/luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java
@@ -14,11 +14,10 @@ package java.util.concurrent;
* scheduling or execution. However, you can override initialization
* and termination methods surrounding the main task processing loop.
* If you do create such a subclass, you will also need to supply a
- * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to use it
- * in a {@code ForkJoinPool}.
+ * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to
+ * {@linkplain ForkJoinPool#ForkJoinPool use it} in a {@code ForkJoinPool}.
*
* @since 1.7
- * @hide
* @author Doug Lea
*/
public class ForkJoinWorkerThread extends Thread {
@@ -61,16 +60,17 @@ public class ForkJoinWorkerThread extends Thread {
}
/**
- * Returns the index number of this thread in its pool. The
- * returned value ranges from zero to the maximum number of
- * threads (minus one) that have ever been created in the pool.
- * This method may be useful for applications that track status or
- * collect results per-worker rather than per-task.
+ * Returns the unique index number of this thread in its pool.
+ * The returned value ranges from zero to the maximum number of
+ * threads (minus one) that may exist in the pool, and does not
+ * change during the lifetime of the thread. This method may be
+ * useful for applications that track status or collect results
+ * per-worker-thread rather than per-task.
*
* @return the index number
*/
public int getPoolIndex() {
- return workQueue.poolIndex;
+ return workQueue.poolIndex >>> 1; // ignore odd/even tag bit
}
/**
diff --git a/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java b/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java
index cff5dbf..a041fb1 100644
--- a/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java
+++ b/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java
@@ -50,7 +50,6 @@ import java.util.concurrent.locks.LockSupport;
* the {@code LinkedTransferQueue} in another thread.
*
* @since 1.7
- * @hide
* @author Doug Lea
* @param <E> the type of elements held in this collection
*/
diff --git a/luni/src/main/java/java/util/concurrent/Phaser.java b/luni/src/main/java/java/util/concurrent/Phaser.java
index a9adbe5..a97d187 100644
--- a/luni/src/main/java/java/util/concurrent/Phaser.java
+++ b/luni/src/main/java/java/util/concurrent/Phaser.java
@@ -227,7 +227,6 @@ import java.util.concurrent.locks.LockSupport;
* of participants.
*
* @since 1.7
- * @hide
* @author Doug Lea
*/
public class Phaser {
diff --git a/luni/src/main/java/java/util/concurrent/RecursiveAction.java b/luni/src/main/java/java/util/concurrent/RecursiveAction.java
index 8d666f6..e3a6340 100644
--- a/luni/src/main/java/java/util/concurrent/RecursiveAction.java
+++ b/luni/src/main/java/java/util/concurrent/RecursiveAction.java
@@ -131,7 +131,6 @@ package java.util.concurrent;
* }}</pre>
*
* @since 1.7
- * @hide
* @author Doug Lea
*/
public abstract class RecursiveAction extends ForkJoinTask<Void> {
diff --git a/luni/src/main/java/java/util/concurrent/RecursiveTask.java b/luni/src/main/java/java/util/concurrent/RecursiveTask.java
index 421c9d3..80baa52 100644
--- a/luni/src/main/java/java/util/concurrent/RecursiveTask.java
+++ b/luni/src/main/java/java/util/concurrent/RecursiveTask.java
@@ -34,7 +34,6 @@ package java.util.concurrent;
* sequentially solve rather than subdividing.
*
* @since 1.7
- * @hide
* @author Doug Lea
*/
public abstract class RecursiveTask<V> extends ForkJoinTask<V> {
diff --git a/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java b/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
index a52351b..483981d 100644
--- a/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
+++ b/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
@@ -690,7 +690,6 @@ public class ScheduledThreadPoolExecutor
* @param value if {@code true}, remove on cancellation, else don't
* @see #getRemoveOnCancelPolicy
* @since 1.7
- * @hide
*/
public void setRemoveOnCancelPolicy(boolean value) {
removeOnCancel = value;
@@ -705,7 +704,6 @@ public class ScheduledThreadPoolExecutor
* from the queue
* @see #setRemoveOnCancelPolicy
* @since 1.7
- * @hide
*/
public boolean getRemoveOnCancelPolicy() {
return removeOnCancel;
diff --git a/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java b/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
index a559321..5baf75f 100644
--- a/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
+++ b/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
@@ -30,7 +30,6 @@ import java.util.Random;
* generation methods.
*
* @since 1.7
- * @hide
* @author Doug Lea
*/
public class ThreadLocalRandom extends Random {
diff --git a/luni/src/main/java/java/util/concurrent/TransferQueue.java b/luni/src/main/java/java/util/concurrent/TransferQueue.java
index 9cd5773..4c2be6f 100644
--- a/luni/src/main/java/java/util/concurrent/TransferQueue.java
+++ b/luni/src/main/java/java/util/concurrent/TransferQueue.java
@@ -33,7 +33,6 @@ package java.util.concurrent;
* and {@code transfer} are effectively synonymous.
*
* @since 1.7
- * @hide
* @author Doug Lea
* @param <E> the type of elements held in this collection
*/
diff --git a/luni/src/main/java/java/util/concurrent/atomic/Fences.java b/luni/src/main/java/java/util/concurrent/atomic/Fences.java
index 7ecf45a..5714ba0 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/Fences.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/Fences.java
@@ -453,7 +453,6 @@ package java.util.concurrent.atomic;
*
* </dl>
*
- * @since 1.7
* @hide
* @author Doug Lea
*/
diff --git a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
index 4c5e280..37aa9d0 100644
--- a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
+++ b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
@@ -1255,7 +1255,6 @@ public abstract class AbstractQueuedLongSynchronizer
* current thread, and {@code false} if the current thread
* is at the head of the queue or the queue is empty
* @since 1.7
- * @hide
*/
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
diff --git a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
index 0350060..e711da5 100644
--- a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
+++ b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -1485,7 +1485,6 @@ public abstract class AbstractQueuedSynchronizer
* current thread, and {@code false} if the current thread
* is at the head of the queue or the queue is empty
* @since 1.7
- * @hide
*/
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
diff --git a/luni/src/main/java/java/util/jar/Attributes.java b/luni/src/main/java/java/util/jar/Attributes.java
index 7e32897..483621b 100644
--- a/luni/src/main/java/java/util/jar/Attributes.java
+++ b/luni/src/main/java/java/util/jar/Attributes.java
@@ -288,7 +288,7 @@ public class Attributes implements Cloneable, Map<Object, Object> {
* @param value
* the value to store in this {@code Attributes}.
* @return the value being stored.
- * @exception ClassCastException
+ * @throws ClassCastException
* when key is not an {@code Attributes.Name} or value is not
* a {@code String}.
*/
@@ -307,9 +307,14 @@ public class Attributes implements Cloneable, Map<Object, Object> {
* Attributes}).
*/
public void putAll(Map<?, ?> attrib) {
- if (attrib == null || !(attrib instanceof Attributes)) {
+ if (attrib == null) {
+ throw new NullPointerException("attrib == null");
+ }
+
+ if (!(attrib instanceof Attributes)) {
throw new ClassCastException(attrib.getClass().getName() + " not an Attributes");
}
+
this.map.putAll(attrib);
}
diff --git a/luni/src/main/java/java/util/jar/JarEntry.java b/luni/src/main/java/java/util/jar/JarEntry.java
index 381dd52..bceef63 100644
--- a/luni/src/main/java/java/util/jar/JarEntry.java
+++ b/luni/src/main/java/java/util/jar/JarEntry.java
@@ -20,14 +20,14 @@ package java.util.jar;
import java.io.IOException;
import java.security.CodeSigner;
import java.security.cert.CertPath;
+import java.security.cert.CertPathValidator;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
import java.util.zip.ZipEntry;
-import javax.security.auth.x500.X500Principal;
/**
* Represents a single file in a JAR archive together with the manifest
@@ -39,7 +39,7 @@ import javax.security.auth.x500.X500Principal;
public class JarEntry extends ZipEntry {
private Attributes attributes;
- JarFile parentJar;
+ final JarFile parentJar;
CodeSigner signers[];
@@ -56,6 +56,7 @@ public class JarEntry extends ZipEntry {
*/
public JarEntry(String name) {
super(name);
+ parentJar = null;
}
/**
@@ -65,15 +66,35 @@ public class JarEntry extends ZipEntry {
* The ZipEntry to obtain values from.
*/
public JarEntry(ZipEntry entry) {
+ this(entry, null);
+ }
+
+ JarEntry(ZipEntry entry, JarFile parentJar) {
super(entry);
+ this.parentJar = parentJar;
+ }
+
+ /**
+ * Create a new {@code JarEntry} using the values obtained from the
+ * argument.
+ *
+ * @param je
+ * The {@code JarEntry} to obtain values from.
+ */
+ public JarEntry(JarEntry je) {
+ super(je);
+ parentJar = je.parentJar;
+ attributes = je.attributes;
+ signers = je.signers;
}
+
/**
* Returns the {@code Attributes} object associated with this entry or
* {@code null} if none exists.
*
* @return the {@code Attributes} for this entry.
- * @exception IOException
+ * @throws IOException
* If an error occurs obtaining the {@code Attributes}.
* @see Attributes
*/
@@ -93,8 +114,12 @@ public class JarEntry extends ZipEntry {
* entry or {@code null} if none exists. Make sure that the everything is
* read from the input stream before calling this method, or else the method
* returns {@code null}.
+ * <p>
+ * This method returns all the signers' unverified chains concatenated
+ * together in one array. To know which certificates were tied to the
+ * private keys that made the signatures on this entry, see
+ * {@link #getCodeSigners()} instead.
*
- * @return the certificate for this entry.
* @see java.security.cert.Certificate
*/
public Certificate[] getCertificates() {
@@ -105,7 +130,27 @@ public class JarEntry extends ZipEntry {
if (jarVerifier == null) {
return null;
}
- return jarVerifier.getCertificates(getName());
+
+ Certificate[][] certChains = jarVerifier.getCertificateChains(getName());
+ if (certChains == null) {
+ return null;
+ }
+
+ // Measure number of certs.
+ int count = 0;
+ for (Certificate[] chain : certChains) {
+ count += chain.length;
+ }
+
+ // Create new array and copy all the certs into it.
+ Certificate[] certs = new Certificate[count];
+ int i = 0;
+ for (Certificate[] chain : certChains) {
+ System.arraycopy(chain, 0, certs, i, chain.length);
+ i += chain.length;
+ }
+
+ return certs;
}
void setAttributes(Attributes attrib) {
@@ -113,86 +158,64 @@ public class JarEntry extends ZipEntry {
}
/**
- * Create a new {@code JarEntry} using the values obtained from the
- * argument.
- *
- * @param je
- * The {@code JarEntry} to obtain values from.
- */
- public JarEntry(JarEntry je) {
- super(je);
- parentJar = je.parentJar;
- attributes = je.attributes;
- signers = je.signers;
- }
-
- /**
* Returns the code signers for the digital signatures associated with the
* JAR file. If there is no such code signer, it returns {@code null}. Make
* sure that the everything is read from the input stream before calling
* this method, or else the method returns {@code null}.
+ * <p>
+ * Only the digital signature on the entry is cryptographically verified.
+ * None of the certificates in the the {@link CertPath} returned from
+ * {@link CodeSigner#getSignerCertPath()} are verified and must be verified
+ * by the caller if needed. See {@link CertPathValidator} for more
+ * information.
*
- * @return the code signers for the JAR entry.
+ * @return an array of CodeSigner for this JAR entry.
* @see CodeSigner
*/
public CodeSigner[] getCodeSigners() {
+ if (parentJar == null) {
+ return null;
+ }
+
+ JarVerifier jarVerifier = parentJar.verifier;
+ if (jarVerifier == null) {
+ return null;
+ }
+
if (signers == null) {
- signers = getCodeSigners(getCertificates());
+ signers = getCodeSigners(jarVerifier.getCertificateChains(getName()));
}
if (signers == null) {
return null;
}
- CodeSigner[] tmp = new CodeSigner[signers.length];
- System.arraycopy(signers, 0, tmp, 0, tmp.length);
- return tmp;
+ return signers.clone();
}
- private CodeSigner[] getCodeSigners(Certificate[] certs) {
- if (certs == null) {
+ private CodeSigner[] getCodeSigners(Certificate[][] certChains) {
+ if (certChains == null) {
return null;
}
- X500Principal prevIssuer = null;
- ArrayList<Certificate> list = new ArrayList<Certificate>(certs.length);
- ArrayList<CodeSigner> asigners = new ArrayList<CodeSigner>();
+ ArrayList<CodeSigner> asigners = new ArrayList<CodeSigner>(certChains.length);
- for (Certificate element : certs) {
- if (!(element instanceof X509Certificate)) {
- // Only X509Certificate-s are taken into account - see API spec.
- continue;
- }
- X509Certificate x509 = (X509Certificate) element;
- if (prevIssuer != null) {
- X500Principal subj = x509.getSubjectX500Principal();
- if (!prevIssuer.equals(subj)) {
- // Ok, this ends the previous chain,
- // so transform this one into CertPath ...
- addCodeSigner(asigners, list);
- // ... and start a new one
- list.clear();
- }// else { it's still the same chain }
-
- }
- prevIssuer = x509.getIssuerX500Principal();
- list.add(x509);
- }
- if (!list.isEmpty()) {
- addCodeSigner(asigners, list);
- }
- if (asigners.isEmpty()) {
- // 'signers' is 'null' already
- return null;
+ for (Certificate[] chain : certChains) {
+ addCodeSigner(asigners, chain);
}
CodeSigner[] tmp = new CodeSigner[asigners.size()];
asigners.toArray(tmp);
return tmp;
-
}
- private void addCodeSigner(ArrayList<CodeSigner> asigners,
- List<Certificate> list) {
+ private void addCodeSigner(ArrayList<CodeSigner> asigners, Certificate[] certs) {
+ for (Certificate cert : certs) {
+ // Only X509Certificate instances are counted. See API spec.
+ if (!(cert instanceof X509Certificate)) {
+ return;
+ }
+ }
+
CertPath certPath = null;
if (!isFactoryChecked) {
try {
@@ -207,7 +230,7 @@ public class JarEntry extends ZipEntry {
return;
}
try {
- certPath = factory.generateCertPath(list);
+ certPath = factory.generateCertPath(Arrays.asList(certs));
} catch (CertificateException ex) {
// do nothing
}
diff --git a/luni/src/main/java/java/util/jar/JarFile.java b/luni/src/main/java/java/util/jar/JarFile.java
index 5293a89..6b147f6 100644
--- a/luni/src/main/java/java/util/jar/JarFile.java
+++ b/luni/src/main/java/java/util/jar/JarFile.java
@@ -23,7 +23,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import libcore.io.Streams;
@@ -48,28 +50,24 @@ public class JarFile extends ZipFile {
// The manifest after it has been read from the JAR.
private Manifest manifest;
- // The entry for the MANIFEST.MF file before it is read.
- private ZipEntry manifestEntry;
+ // The entry for the MANIFEST.MF file before the first call to getManifest().
+ private byte[] manifestBytes;
JarVerifier verifier;
private boolean closed = false;
static final class JarFileInputStream extends FilterInputStream {
- private long count;
-
- private ZipEntry zipEntry;
-
- private JarVerifier.VerifierEntry entry;
+ private final JarVerifier.VerifierEntry entry;
+ private long count;
private boolean done = false;
- JarFileInputStream(InputStream is, ZipEntry ze,
- JarVerifier.VerifierEntry e) {
+ JarFileInputStream(InputStream is, long size, JarVerifier.VerifierEntry e) {
super(is);
- zipEntry = ze;
- count = zipEntry.getSize();
entry = e;
+
+ count = size;
}
@Override
@@ -140,6 +138,24 @@ public class JarFile extends ZipFile {
}
}
+ static final class JarFileEnumerator implements Enumeration<JarEntry> {
+ final Enumeration<? extends ZipEntry> ze;
+ final JarFile jf;
+
+ JarFileEnumerator(Enumeration<? extends ZipEntry> zenum, JarFile jf) {
+ ze = zenum;
+ this.jf = jf;
+ }
+
+ public boolean hasMoreElements() {
+ return ze.hasMoreElements();
+ }
+
+ public JarEntry nextElement() {
+ return new JarEntry(ze.nextElement(), jf /* parentJar */);
+ }
+ }
+
/**
* Create a new {@code JarFile} using the contents of the specified file.
*
@@ -163,11 +179,7 @@ public class JarFile extends ZipFile {
* If the file cannot be read.
*/
public JarFile(File file, boolean verify) throws IOException {
- super(file);
- if (verify) {
- verifier = new JarVerifier(file.getPath());
- }
- readMetaEntries();
+ this(file, verify, ZipFile.OPEN_READ);
}
/**
@@ -184,21 +196,30 @@ public class JarFile extends ZipFile {
* If the file cannot be read.
*/
public JarFile(File file, boolean verify, int mode) throws IOException {
- this(file, verify, mode, false);
- }
-
- /**
- * See previous constructor for other parameter definitions.
- * @param chainCheck
- * whether or not to check certificate chain signatures
- * @hide
- */
- public JarFile(File file, boolean verify, int mode, boolean chainCheck) throws IOException {
super(file, mode);
- if (verify) {
- verifier = new JarVerifier(file.getPath(), chainCheck);
+
+ // Step 1: Scan the central directory for meta entries (MANIFEST.mf
+ // & possibly the signature files) and read them fully.
+ HashMap<String, byte[]> metaEntries = readMetaEntries(this, verify);
+
+ // Step 2: Construct a verifier with the information we have.
+ // Verification is possible *only* if the JAR file contains a manifest
+ // *AND* it contains signing related information (signature block
+ // files and the signature files).
+ //
+ // TODO: Is this really the behaviour we want if verify == true ?
+ // We silently skip verification for files that have no manifest or
+ // no signatures.
+ if (verify && metaEntries.containsKey(MANIFEST_NAME) &&
+ metaEntries.size() > 1) {
+ // We create the manifest straight away, so that we can create
+ // the jar verifier as well.
+ manifest = new Manifest(metaEntries.get(MANIFEST_NAME), true);
+ verifier = new JarVerifier(getName(), manifest, metaEntries);
+ } else {
+ verifier = null;
+ manifestBytes = metaEntries.get(MANIFEST_NAME);
}
- readMetaEntries();
}
/**
@@ -226,21 +247,7 @@ public class JarFile extends ZipFile {
* If file cannot be opened or read.
*/
public JarFile(String filename, boolean verify) throws IOException {
- this(filename, verify, false);
- }
-
- /**
- * See previous constructor for other parameter definitions.
- * @param chainCheck
- * whether or not to check certificate chain signatures
- * @hide
- */
- public JarFile(String filename, boolean verify, boolean chainCheck) throws IOException {
- super(filename);
- if (verify) {
- verifier = new JarVerifier(filename, chainCheck);
- }
- readMetaEntries();
+ this(new File(filename), verify, ZipFile.OPEN_READ);
}
/**
@@ -253,26 +260,6 @@ public class JarFile extends ZipFile {
*/
@Override
public Enumeration<JarEntry> entries() {
- class JarFileEnumerator implements Enumeration<JarEntry> {
- Enumeration<? extends ZipEntry> ze;
-
- JarFile jf;
-
- JarFileEnumerator(Enumeration<? extends ZipEntry> zenum, JarFile jf) {
- ze = zenum;
- this.jf = jf;
- }
-
- public boolean hasMoreElements() {
- return ze.hasMoreElements();
- }
-
- public JarEntry nextElement() {
- JarEntry je = new JarEntry(ze.nextElement());
- je.parentJar = jf;
- return je;
- }
- }
return new JarFileEnumerator(super.entries(), this);
}
@@ -303,73 +290,70 @@ public class JarFile extends ZipFile {
if (closed) {
throw new IllegalStateException("JarFile has been closed");
}
+
if (manifest != null) {
return manifest;
}
- try {
- InputStream is = super.getInputStream(manifestEntry);
- if (verifier != null) {
- verifier.addMetaEntry(manifestEntry.getName(), Streams.readFully(is));
- is = super.getInputStream(manifestEntry);
- }
- try {
- manifest = new Manifest(is, verifier != null);
- } finally {
- is.close();
- }
- manifestEntry = null; // Can discard the entry now.
- } catch (NullPointerException e) {
- manifestEntry = null;
+
+ // If manifest == null && manifestBytes == null, there's no manifest.
+ if (manifestBytes == null) {
+ return null;
}
+
+ // We hit this code path only if the verification isn't necessary. If
+ // we did decide to verify this file, we'd have created the Manifest and
+ // the associated Verifier in the constructor itself.
+ manifest = new Manifest(manifestBytes, false);
+ manifestBytes = null;
+
return manifest;
}
/**
- * Called by the JarFile constructors, this method reads the contents of the
+ * Called by the JarFile constructors, Reads the contents of the
* file's META-INF/ directory and picks out the MANIFEST.MF file and
- * verifier signature files if they exist. Any signature files found are
- * registered with the verifier.
+ * verifier signature files if they exist.
*
* @throws IOException
* if there is a problem reading the jar file entries.
+ * @return a map of entry names to their {@code byte[]} content.
*/
- private void readMetaEntries() throws IOException {
+ static HashMap<String, byte[]> readMetaEntries(ZipFile zipFile,
+ boolean verificationRequired) throws IOException {
// Get all meta directory entries
- ZipEntry[] metaEntries = getMetaEntriesImpl();
- if (metaEntries == null) {
- verifier = null;
- return;
- }
+ List<ZipEntry> metaEntries = getMetaEntries(zipFile);
- boolean signed = false;
+ HashMap<String, byte[]> metaEntriesMap = new HashMap<String, byte[]>();
for (ZipEntry entry : metaEntries) {
String entryName = entry.getName();
// Is this the entry for META-INF/MANIFEST.MF ?
- if (manifestEntry == null && entryName.equalsIgnoreCase(MANIFEST_NAME)) {
- manifestEntry = entry;
+ //
+ // TODO: Why do we need the containsKey check ? Shouldn't we discard
+ // files that contain duplicate entries like this as invalid ?.
+ if (entryName.equalsIgnoreCase(MANIFEST_NAME) &&
+ !metaEntriesMap.containsKey(MANIFEST_NAME)) {
+
+ metaEntriesMap.put(MANIFEST_NAME, Streams.readFully(
+ zipFile.getInputStream(entry)));
+
// If there is no verifier then we don't need to look any further.
- if (verifier == null) {
+ if (!verificationRequired) {
break;
}
- } else {
+ } else if (verificationRequired) {
// Is this an entry that the verifier needs?
- if (verifier != null
- && (endsWithIgnoreCase(entryName, ".SF")
- || endsWithIgnoreCase(entryName, ".DSA")
- || endsWithIgnoreCase(entryName, ".RSA")
- || endsWithIgnoreCase(entryName, ".EC"))) {
- signed = true;
- InputStream is = super.getInputStream(entry);
- verifier.addMetaEntry(entryName, Streams.readFully(is));
+ if (endsWithIgnoreCase(entryName, ".SF")
+ || endsWithIgnoreCase(entryName, ".DSA")
+ || endsWithIgnoreCase(entryName, ".RSA")
+ || endsWithIgnoreCase(entryName, ".EC")) {
+ InputStream is = zipFile.getInputStream(entry);
+ metaEntriesMap.put(entryName.toUpperCase(Locale.US), Streams.readFully(is));
}
}
}
- // If there were no signature files, then no verifier work to do.
- if (!signed) {
- verifier = null;
- }
+ return metaEntriesMap;
}
private static boolean endsWithIgnoreCase(String s, String suffix) {
@@ -388,24 +372,21 @@ public class JarFile extends ZipFile {
*/
@Override
public InputStream getInputStream(ZipEntry ze) throws IOException {
- if (manifestEntry != null) {
+ if (manifestBytes != null) {
getManifest();
}
+
if (verifier != null) {
- verifier.setManifest(getManifest());
- if (manifest != null) {
- verifier.mainAttributesEnd = manifest.getMainAttributesEnd();
- }
if (verifier.readCertificates()) {
verifier.removeMetaEntries();
- if (manifest != null) {
- manifest.removeChunks();
- }
+ manifest.removeChunks();
+
if (!verifier.isSignedJar()) {
verifier = null;
}
}
}
+
InputStream in = super.getInputStream(ze);
if (in == null) {
return null;
@@ -417,7 +398,7 @@ public class JarFile extends ZipFile {
if (entry == null) {
return in;
}
- return new JarFileInputStream(in, ze, entry);
+ return new JarFileInputStream(in, ze.getSize(), entry);
}
/**
@@ -434,20 +415,17 @@ public class JarFile extends ZipFile {
if (ze == null) {
return ze;
}
- JarEntry je = new JarEntry(ze);
- je.parentJar = this;
- return je;
+ return new JarEntry(ze, this /* parentJar */);
}
/**
* Returns all the ZipEntry's that relate to files in the
* JAR's META-INF directory.
- *
- * @return the list of ZipEntry's or {@code null} if there are none.
*/
- private ZipEntry[] getMetaEntriesImpl() {
+ private static List<ZipEntry> getMetaEntries(ZipFile zipFile) {
List<ZipEntry> list = new ArrayList<ZipEntry>(8);
- Enumeration<? extends ZipEntry> allEntries = entries();
+
+ Enumeration<? extends ZipEntry> allEntries = zipFile.entries();
while (allEntries.hasMoreElements()) {
ZipEntry ze = allEntries.nextElement();
if (ze.getName().startsWith(META_DIR)
@@ -455,12 +433,8 @@ public class JarFile extends ZipFile {
list.add(ze);
}
}
- if (list.size() == 0) {
- return null;
- }
- ZipEntry[] result = new ZipEntry[list.size()];
- list.toArray(result);
- return result;
+
+ return list;
}
/**
diff --git a/luni/src/main/java/java/util/jar/JarInputStream.java b/luni/src/main/java/java/util/jar/JarInputStream.java
index 5e08b5d..585c135 100644
--- a/luni/src/main/java/java/util/jar/JarInputStream.java
+++ b/luni/src/main/java/java/util/jar/JarInputStream.java
@@ -21,9 +21,11 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.HashMap;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
+import libcore.io.Streams;
/**
* The input stream from which the JAR file to be read may be fetched. It is
@@ -31,15 +33,20 @@ import java.util.zip.ZipInputStream;
*
* @see ZipInputStream
*/
+// TODO: The semantics provided by this class are really weird. The jar file
+// spec does not impose any ordering constraints on the entries of a jar file.
+// In particular, the Manifest and META-INF directory *need not appear first*. This
+// class will silently skip certificate checks for jar files where the manifest
+// isn't the first entry. To do this correctly, we need O(input_stream_length) memory.
public class JarInputStream extends ZipInputStream {
private Manifest manifest;
- private boolean eos = false;
+ private boolean verified = false;
- private JarEntry mEntry;
+ private JarEntry currentJarEntry;
- private JarEntry jarEntry;
+ private JarEntry pendingJarEntry;
private boolean isMeta;
@@ -60,38 +67,44 @@ public class JarInputStream extends ZipInputStream {
*/
public JarInputStream(InputStream stream, boolean verify) throws IOException {
super(stream);
- if (verify) {
- verifier = new JarVerifier("JarInputStream");
- }
- if ((mEntry = getNextJarEntry()) == null) {
+
+ verifier = null;
+ pendingJarEntry = null;
+ currentJarEntry = null;
+
+ if (getNextJarEntry() == null) {
return;
}
- if (mEntry.getName().equalsIgnoreCase(JarFile.META_DIR)) {
- mEntry = null; // modifies behavior of getNextJarEntry()
+
+ if (currentJarEntry.getName().equalsIgnoreCase(JarFile.META_DIR)) {
+ // Fetch the next entry, in the hope that it's the manifest file.
closeEntry();
- mEntry = getNextJarEntry();
+ getNextJarEntry();
}
- if (mEntry.getName().equalsIgnoreCase(JarFile.MANIFEST_NAME)) {
- mEntry = null;
- manifest = new Manifest(this, verify);
+
+ if (currentJarEntry.getName().equalsIgnoreCase(JarFile.MANIFEST_NAME)) {
+ final byte[] manifestBytes = Streams.readFullyNoClose(this);
+ manifest = new Manifest(manifestBytes, verify);
closeEntry();
+
if (verify) {
- verifier.setManifest(manifest);
- if (manifest != null) {
- verifier.mainAttributesEnd = manifest.getMainAttributesEnd();
- }
+ HashMap<String, byte[]> metaEntries = new HashMap<String, byte[]>();
+ metaEntries.put(JarFile.MANIFEST_NAME, manifestBytes);
+ verifier = new JarVerifier("JarInputStream", manifest, metaEntries);
}
-
- } else {
- Attributes temp = new Attributes(3);
- temp.map.put("hidden", null);
- mEntry.setAttributes(temp);
- /*
- * if not from the first entry, we will not get enough
- * information,so no verify will be taken out.
- */
- verifier = null;
}
+
+ // There was no manifest available, so we should return the current
+ // entry the next time getNextEntry is called.
+ pendingJarEntry = currentJarEntry;
+ currentJarEntry = null;
+
+ // If the manifest isn't the first entry, we will not have enough
+ // information to perform verification on entries that precede it.
+ //
+ // TODO: Should we throw if verify == true in this case ?
+ // TODO: We need all meta entries to be placed before the manifest
+ // as well.
}
/**
@@ -138,32 +151,39 @@ public class JarInputStream extends ZipInputStream {
*/
@Override
public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
- if (mEntry != null) {
+ if (currentJarEntry == null) {
return -1;
}
+
int r = super.read(buffer, byteOffset, byteCount);
- if (verStream != null && !eos) {
+ // verifier can be null if we've been asked not to verify or if
+ // the manifest wasn't found.
+ //
+ // verStream will be null if we're reading the manifest or if we have
+ // no signatures or if the digest for this entry isn't present in the
+ // manifest.
+ if (verifier != null && verStream != null && !verified) {
if (r == -1) {
- eos = true;
- if (verifier != null) {
- if (isMeta) {
- verifier.addMetaEntry(jarEntry.getName(),
- ((ByteArrayOutputStream) verStream)
- .toByteArray());
- try {
- verifier.readCertificates();
- } catch (SecurityException e) {
- verifier = null;
- throw e;
- }
- } else {
- ((JarVerifier.VerifierEntry) verStream).verify();
+ // We've hit the end of this stream for the first time, so attempt
+ // a verification.
+ verified = true;
+ if (isMeta) {
+ verifier.addMetaEntry(currentJarEntry.getName(),
+ ((ByteArrayOutputStream) verStream).toByteArray());
+ try {
+ verifier.readCertificates();
+ } catch (SecurityException e) {
+ verifier = null;
+ throw e;
}
+ } else {
+ ((JarVerifier.VerifierEntry) verStream).verify();
}
} else {
verStream.write(buffer, byteOffset, r);
}
}
+
return r;
}
@@ -177,26 +197,47 @@ public class JarInputStream extends ZipInputStream {
*/
@Override
public ZipEntry getNextEntry() throws IOException {
- if (mEntry != null) {
- jarEntry = mEntry;
- mEntry = null;
- jarEntry.setAttributes(null);
- } else {
- jarEntry = (JarEntry) super.getNextEntry();
- if (jarEntry == null) {
- return null;
- }
- if (verifier != null) {
- isMeta = jarEntry.getName().toUpperCase(Locale.US).startsWith(JarFile.META_DIR);
- if (isMeta) {
- verStream = new ByteArrayOutputStream();
- } else {
- verStream = verifier.initEntry(jarEntry.getName());
- }
+ // NOTE: This function must update the value of currentJarEntry
+ // as a side effect.
+
+ if (pendingJarEntry != null) {
+ JarEntry pending = pendingJarEntry;
+ pendingJarEntry = null;
+ currentJarEntry = pending;
+ return pending;
+ }
+
+ currentJarEntry = (JarEntry) super.getNextEntry();
+ if (currentJarEntry == null) {
+ return null;
+ }
+
+ if (verifier != null) {
+ isMeta = currentJarEntry.getName().toUpperCase(Locale.US).startsWith(JarFile.META_DIR);
+ if (isMeta) {
+ final int entrySize = (int) currentJarEntry.getSize();
+ verStream = new ByteArrayOutputStream(entrySize > 0 ? entrySize : 8192);
+ } else {
+ verStream = verifier.initEntry(currentJarEntry.getName());
}
}
- eos = false;
- return jarEntry;
+
+ verified = false;
+ return currentJarEntry;
+ }
+
+ @Override
+ public void closeEntry() throws IOException {
+ // NOTE: This was the old behavior. A call to closeEntry() before the
+ // first call to getNextEntry should be a no-op. If we don't return early
+ // here, the super class will close pendingJarEntry for us and reads will
+ // fail.
+ if (pendingJarEntry != null) {
+ return;
+ }
+
+ super.closeEntry();
+ currentJarEntry = null;
}
@Override
diff --git a/luni/src/main/java/java/util/jar/JarVerifier.java b/luni/src/main/java/java/util/jar/JarVerifier.java
index 8185c6d..467e298 100644
--- a/luni/src/main/java/java/util/jar/JarVerifier.java
+++ b/luni/src/main/java/java/util/jar/JarVerifier.java
@@ -17,6 +17,7 @@
package java.util.jar;
+import org.apache.harmony.security.utils.JarUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -31,10 +32,7 @@ import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.Vector;
import libcore.io.Base64;
-import org.apache.harmony.security.utils.JarUtils;
/**
* Non-public class used by {@link JarFile} and {@link JarInputStream} to manage
@@ -63,44 +61,42 @@ class JarVerifier {
};
private final String jarName;
+ private final Manifest manifest;
+ private final HashMap<String, byte[]> metaEntries;
+ private final int mainAttributesEnd;
- private Manifest man;
-
- private HashMap<String, byte[]> metaEntries = new HashMap<String, byte[]>(5);
-
- private final Hashtable<String, HashMap<String, Attributes>> signatures = new Hashtable<String, HashMap<String, Attributes>>(
- 5);
+ private final Hashtable<String, HashMap<String, Attributes>> signatures =
+ new Hashtable<String, HashMap<String, Attributes>>(5);
- private final Hashtable<String, Certificate[]> certificates = new Hashtable<String, Certificate[]>(
- 5);
+ private final Hashtable<String, Certificate[]> certificates =
+ new Hashtable<String, Certificate[]>(5);
- private final Hashtable<String, Certificate[]> verifiedEntries = new Hashtable<String, Certificate[]>();
-
- int mainAttributesEnd;
-
- /** Whether or not to check certificate chain signatures. */
- private final boolean chainCheck;
+ private final Hashtable<String, Certificate[][]> verifiedEntries =
+ new Hashtable<String, Certificate[][]>();
/**
* Stores and a hash and a message digest and verifies that massage digest
* matches the hash.
*/
- class VerifierEntry extends OutputStream {
+ static class VerifierEntry extends OutputStream {
- private String name;
+ private final String name;
- private MessageDigest digest;
+ private final MessageDigest digest;
- private byte[] hash;
+ private final byte[] hash;
- private Certificate[] certificates;
+ private final Certificate[][] certChains;
+
+ private final Hashtable<String, Certificate[][]> verifiedEntries;
VerifierEntry(String name, MessageDigest digest, byte[] hash,
- Certificate[] certificates) {
+ Certificate[][] certChains, Hashtable<String, Certificate[][]> verifedEntries) {
this.name = name;
this.digest = digest;
this.hash = hash;
- this.certificates = certificates;
+ this.certChains = certChains;
+ this.verifiedEntries = verifedEntries;
}
/**
@@ -122,7 +118,7 @@ class JarVerifier {
/**
* Verifies that the digests stored in the manifest match the decrypted
* digests from the .SF file. This indicates the validity of the
- * signing, not the integrity of the file, as it's digest must be
+ * signing, not the integrity of the file, as its digest must be
* calculated and verified when its contents are read.
*
* @throws SecurityException
@@ -133,40 +129,33 @@ class JarVerifier {
void verify() {
byte[] d = digest.digest();
if (!MessageDigest.isEqual(d, Base64.decode(hash))) {
- throw invalidDigest(JarFile.MANIFEST_NAME, name, jarName);
+ throw invalidDigest(JarFile.MANIFEST_NAME, name, name);
}
- verifiedEntries.put(name, certificates);
+ verifiedEntries.put(name, certChains);
}
-
}
- private SecurityException invalidDigest(String signatureFile, String name, String jarName) {
+ private static SecurityException invalidDigest(String signatureFile, String name,
+ String jarName) {
throw new SecurityException(signatureFile + " has invalid digest for " + name +
" in " + jarName);
}
- private SecurityException failedVerification(String jarName, String signatureFile) {
+ private static SecurityException failedVerification(String jarName, String signatureFile) {
throw new SecurityException(jarName + " failed verification of " + signatureFile);
}
/**
- * Convenience constructor for backward compatibility.
- */
- JarVerifier(String name) {
- this(name, false);
- }
-
- /**
* Constructs and returns a new instance of {@code JarVerifier}.
*
* @param name
* the name of the JAR file being verified.
- * @param chainCheck
- * whether to check the certificate chain signatures
*/
- JarVerifier(String name, boolean chainCheck) {
+ JarVerifier(String name, Manifest manifest, HashMap<String, byte[]> metaEntries) {
jarName = name;
- this.chainCheck = chainCheck;
+ this.manifest = manifest;
+ this.metaEntries = metaEntries;
+ this.mainAttributesEnd = manifest.getMainAttributesEnd();
}
/**
@@ -185,17 +174,17 @@ class JarVerifier {
// If no manifest is present by the time an entry is found,
// verification cannot occur. If no signature files have
// been found, do not verify.
- if (man == null || signatures.size() == 0) {
+ if (manifest == null || signatures.isEmpty()) {
return null;
}
- Attributes attributes = man.getAttributes(name);
+ Attributes attributes = manifest.getAttributes(name);
// entry has no digest
if (attributes == null) {
return null;
}
- ArrayList<Certificate> certs = new ArrayList<Certificate>();
+ ArrayList<Certificate[]> certChains = new ArrayList<Certificate[]>();
Iterator<Map.Entry<String, HashMap<String, Attributes>>> it = signatures.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, HashMap<String, Attributes>> entry = it.next();
@@ -203,15 +192,18 @@ class JarVerifier {
if (hm.get(name) != null) {
// Found an entry for entry name in .SF file
String signatureFile = entry.getKey();
- certs.addAll(getSignerCertificates(signatureFile, certificates));
+ Certificate[] certChain = certificates.get(signatureFile);
+ if (certChain != null) {
+ certChains.add(certChain);
+ }
}
}
// entry is not signed
- if (certs.isEmpty()) {
+ if (certChains.isEmpty()) {
return null;
}
- Certificate[] certificatesArray = certs.toArray(new Certificate[certs.size()]);
+ Certificate[][] certChainsArray = certChains.toArray(new Certificate[certChains.size()][]);
for (int i = 0; i < DIGEST_ALGORITHMS.length; i++) {
final String algorithm = DIGEST_ALGORITHMS[i];
@@ -223,9 +215,8 @@ class JarVerifier {
try {
return new VerifierEntry(name, MessageDigest.getInstance(algorithm), hashBytes,
- certificatesArray);
- } catch (NoSuchAlgorithmException e) {
- // ignored
+ certChainsArray, verifiedEntries);
+ } catch (NoSuchAlgorithmException ignored) {
}
}
return null;
@@ -266,18 +257,15 @@ class JarVerifier {
* corresponding signature file.
*/
synchronized boolean readCertificates() {
- if (metaEntries == null) {
+ if (metaEntries.isEmpty()) {
return false;
}
+
Iterator<String> it = metaEntries.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
if (key.endsWith(".DSA") || key.endsWith(".RSA") || key.endsWith(".EC")) {
verifyCertificate(key);
- // Check for recursive class load
- if (metaEntries == null) {
- return false;
- }
it.remove();
}
}
@@ -295,9 +283,9 @@ class JarVerifier {
return;
}
- byte[] manifest = metaEntries.get(JarFile.MANIFEST_NAME);
+ byte[] manifestBytes = metaEntries.get(JarFile.MANIFEST_NAME);
// Manifest entry is required for any verifications.
- if (manifest == null) {
+ if (manifestBytes == null) {
return;
}
@@ -305,15 +293,7 @@ class JarVerifier {
try {
Certificate[] signerCertChain = JarUtils.verifySignature(
new ByteArrayInputStream(sfBytes),
- new ByteArrayInputStream(sBlockBytes),
- chainCheck);
- /*
- * Recursive call in loading security provider related class which
- * is in a signed JAR.
- */
- if (metaEntries == null) {
- return;
- }
+ new ByteArrayInputStream(sBlockBytes));
if (signerCertChain != null) {
certificates.put(signatureFile, signerCertChain);
}
@@ -350,22 +330,22 @@ class JarVerifier {
// such verification.
if (mainAttributesEnd > 0 && !createdBySigntool) {
String digestAttribute = "-Digest-Manifest-Main-Attributes";
- if (!verify(attributes, digestAttribute, manifest, 0, mainAttributesEnd, false, true)) {
+ if (!verify(attributes, digestAttribute, manifestBytes, 0, mainAttributesEnd, false, true)) {
throw failedVerification(jarName, signatureFile);
}
}
// Use .SF to verify the whole manifest.
String digestAttribute = createdBySigntool ? "-Digest" : "-Digest-Manifest";
- if (!verify(attributes, digestAttribute, manifest, 0, manifest.length, false, false)) {
+ if (!verify(attributes, digestAttribute, manifestBytes, 0, manifestBytes.length, false, false)) {
Iterator<Map.Entry<String, Attributes>> it = entries.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Attributes> entry = it.next();
- Manifest.Chunk chunk = man.getChunk(entry.getKey());
+ Manifest.Chunk chunk = manifest.getChunk(entry.getKey());
if (chunk == null) {
return;
}
- if (!verify(entry.getValue(), "-Digest", manifest,
+ if (!verify(entry.getValue(), "-Digest", manifestBytes,
chunk.start, chunk.end, createdBySigntool, false)) {
throw invalidDigest(signatureFile, entry.getKey(), jarName);
}
@@ -376,16 +356,6 @@ class JarVerifier {
}
/**
- * Associate this verifier with the specified {@link Manifest} object.
- *
- * @param mf
- * a {@code java.util.jar.Manifest} object.
- */
- void setManifest(Manifest mf) {
- man = mf;
- }
-
- /**
* Returns a <code>boolean</code> indication of whether or not the
* associated jar file is signed.
*
@@ -424,58 +394,23 @@ class JarVerifier {
}
/**
- * Returns all of the {@link java.security.cert.Certificate} instances that
+ * Returns all of the {@link java.security.cert.Certificate} chains that
* were used to verify the signature on the JAR entry called
- * {@code name}.
+ * {@code name}. Callers must not modify the returned arrays.
*
* @param name
* the name of a JAR entry.
- * @return an array of {@link java.security.cert.Certificate}.
+ * @return an array of {@link java.security.cert.Certificate} chains.
*/
- Certificate[] getCertificates(String name) {
- Certificate[] verifiedCerts = verifiedEntries.get(name);
- if (verifiedCerts == null) {
- return null;
- }
- return verifiedCerts.clone();
+ Certificate[][] getCertificateChains(String name) {
+ return verifiedEntries.get(name);
}
/**
* Remove all entries from the internal collection of data held about each
* JAR entry in the {@code META-INF} directory.
- *
- * @see #addMetaEntry(String, byte[])
*/
void removeMetaEntries() {
- metaEntries = null;
- }
-
- /**
- * Returns a {@code Vector} of all of the
- * {@link java.security.cert.Certificate}s that are associated with the
- * signing of the named signature file.
- *
- * @param signatureFileName
- * the name of a signature file.
- * @param certificates
- * a {@code Map} of all of the certificate chains discovered so
- * far while attempting to verify the JAR that contains the
- * signature file {@code signatureFileName}. This object is
- * previously set in the course of one or more calls to
- * {@link #verifyJarSignatureFile(String, String, String, Map, Map)}
- * where it was passed as the last argument.
- * @return all of the {@code Certificate} entries for the signer of the JAR
- * whose actions led to the creation of the named signature file.
- */
- public static Vector<Certificate> getSignerCertificates(
- String signatureFileName, Map<String, Certificate[]> certificates) {
- Vector<Certificate> result = new Vector<Certificate>();
- Certificate[] certChain = certificates.get(signatureFileName);
- if (certChain != null) {
- for (Certificate element : certChain) {
- result.add(element);
- }
- }
- return result;
+ metaEntries.clear();
}
}
diff --git a/luni/src/main/java/java/util/jar/Manifest.java b/luni/src/main/java/java/util/jar/Manifest.java
index b6ebddc..6a3936d 100644
--- a/luni/src/main/java/java/util/jar/Manifest.java
+++ b/luni/src/main/java/java/util/jar/Manifest.java
@@ -17,11 +17,9 @@
package java.util.jar;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetEncoder;
@@ -43,26 +41,12 @@ public class Manifest implements Cloneable {
private static final byte[] VALUE_SEPARATOR = new byte[] { ':', ' ' };
- private static final Field BAIS_BUF = getByteArrayInputStreamField("buf");
- private static final Field BAIS_POS = getByteArrayInputStreamField("pos");
+ private final Attributes mainAttributes;
+ private final HashMap<String, Attributes> entries;
- private static Field getByteArrayInputStreamField(String name) {
- try {
- Field f = ByteArrayInputStream.class.getDeclaredField(name);
- f.setAccessible(true);
- return f;
- } catch (Exception ex) {
- throw new AssertionError(ex);
- }
- }
-
- private Attributes mainAttributes = new Attributes();
-
- private HashMap<String, Attributes> entries = new HashMap<String, Attributes>();
-
- static class Chunk {
- int start;
- int end;
+ static final class Chunk {
+ final int start;
+ final int end;
Chunk(int start, int end) {
this.start = start;
@@ -82,6 +66,8 @@ public class Manifest implements Cloneable {
* Creates a new {@code Manifest} instance.
*/
public Manifest() {
+ entries = new HashMap<String, Attributes>();
+ mainAttributes = new Attributes();
}
/**
@@ -94,7 +80,8 @@ public class Manifest implements Cloneable {
* if an IO error occurs while creating this {@code Manifest}
*/
public Manifest(InputStream is) throws IOException {
- read(is);
+ this();
+ read(Streams.readFully(is));
}
/**
@@ -111,11 +98,12 @@ public class Manifest implements Cloneable {
.getEntries()).clone();
}
- Manifest(InputStream is, boolean readChunks) throws IOException {
+ Manifest(byte[] manifestBytes, boolean readChunks) throws IOException {
+ this();
if (readChunks) {
chunks = new HashMap<String, Chunk>();
}
- read(is);
+ read(manifestBytes);
}
/**
@@ -192,58 +180,20 @@ public class Manifest implements Cloneable {
* If an error occurs reading the manifest.
*/
public void read(InputStream is) throws IOException {
- byte[] buf;
- if (is instanceof ByteArrayInputStream) {
- buf = exposeByteArrayInputStreamBytes((ByteArrayInputStream) is);
- } else {
- buf = Streams.readFullyNoClose(is);
- }
+ read(Streams.readFullyNoClose(is));
+ }
+ private void read(byte[] buf) throws IOException {
if (buf.length == 0) {
return;
}
- // a workaround for HARMONY-5662
- // replace EOF and NUL with another new line
- // which does not trigger an error
- byte b = buf[buf.length - 1];
- if (b == 0 || b == 26) {
- buf[buf.length - 1] = '\n';
- }
-
ManifestReader im = new ManifestReader(buf, mainAttributes);
mainEnd = im.getEndOfMainSection();
im.readEntries(entries, chunks);
}
/**
- * Returns a byte[] containing all the bytes from a ByteArrayInputStream.
- * Where possible, this returns the actual array rather than a copy.
- */
- private static byte[] exposeByteArrayInputStreamBytes(ByteArrayInputStream bais) {
- byte[] buffer;
- synchronized (bais) {
- byte[] buf;
- int pos;
- try {
- buf = (byte[]) BAIS_BUF.get(bais);
- pos = BAIS_POS.getInt(bais);
- } catch (IllegalAccessException iae) {
- throw new AssertionError(iae);
- }
- int available = bais.available();
- if (pos == 0 && buf.length == available) {
- buffer = buf;
- } else {
- buffer = new byte[available];
- System.arraycopy(buf, pos, buffer, 0, available);
- }
- bais.skip(available);
- }
- return buffer;
- }
-
- /**
* Returns the hash code for this instance.
*
* @return this {@code Manifest}'s hashCode.
diff --git a/luni/src/main/java/java/util/jar/StrictJarFile.java b/luni/src/main/java/java/util/jar/StrictJarFile.java
new file mode 100644
index 0000000..4a8af5f
--- /dev/null
+++ b/luni/src/main/java/java/util/jar/StrictJarFile.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package java.util.jar;
+
+import dalvik.system.CloseGuard;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.security.cert.Certificate;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.zip.Inflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+/**
+ * A subset of the JarFile API implemented as a thin wrapper over
+ * system/core/libziparchive.
+ *
+ * @hide for internal use only. Not API compatible (or as forgiving) as
+ * {@link java.util.jar.JarFile}
+ */
+public final class StrictJarFile {
+
+ private final long nativeHandle;
+
+ // NOTE: It's possible to share a file descriptor with the native
+ // code, at the cost of some additional complexity.
+ private final RandomAccessFile raf;
+
+ private final Manifest manifest;
+ private final JarVerifier verifier;
+
+ private final boolean isSigned;
+
+ private final CloseGuard guard = CloseGuard.get();
+ private boolean closed;
+
+ public StrictJarFile(String fileName) throws IOException {
+ this.nativeHandle = nativeOpenJarFile(fileName);
+ this.raf = new RandomAccessFile(fileName, "r");
+
+ try {
+ // Read the MANIFEST and signature files up front and try to
+ // parse them. We never want to accept a JAR File with broken signatures
+ // or manifests, so it's best to throw as early as possible.
+ HashMap<String, byte[]> metaEntries = getMetaEntries();
+ this.manifest = new Manifest(metaEntries.get(JarFile.MANIFEST_NAME), true);
+ this.verifier = new JarVerifier(fileName, manifest, metaEntries);
+
+ isSigned = verifier.readCertificates() && verifier.isSignedJar();
+ } catch (IOException ioe) {
+ nativeClose(this.nativeHandle);
+ throw ioe;
+ }
+
+ guard.open("close");
+ }
+
+ public Manifest getManifest() {
+ return manifest;
+ }
+
+ public Iterator<ZipEntry> iterator() throws IOException {
+ return new EntryIterator(nativeHandle, "");
+ }
+
+ public ZipEntry findEntry(String name) {
+ return nativeFindEntry(nativeHandle, name);
+ }
+
+ /**
+ * Return all certificate chains for a given {@link ZipEntry} belonging to this jar.
+ * This method MUST be called only after fully exhausting the InputStream belonging
+ * to this entry.
+ *
+ * Returns {@code null} if this jar file isn't signed or if this method is
+ * called before the stream is processed.
+ */
+ public Certificate[][] getCertificateChains(ZipEntry ze) {
+ if (isSigned) {
+ return verifier.getCertificateChains(ze.getName());
+ }
+
+ return null;
+ }
+
+ /**
+ * Return all certificates for a given {@link ZipEntry} belonging to this jar.
+ * This method MUST be called only after fully exhausting the InputStream belonging
+ * to this entry.
+ *
+ * Returns {@code null} if this jar file isn't signed or if this method is
+ * called before the stream is processed.
+ *
+ * @deprecated Switch callers to use getCertificateChains instead
+ */
+ @Deprecated
+ public Certificate[] getCertificates(ZipEntry ze) {
+ if (isSigned) {
+ Certificate[][] certChains = verifier.getCertificateChains(ze.getName());
+
+ // Measure number of certs.
+ int count = 0;
+ for (Certificate[] chain : certChains) {
+ count += chain.length;
+ }
+
+ // Create new array and copy all the certs into it.
+ Certificate[] certs = new Certificate[count];
+ int i = 0;
+ for (Certificate[] chain : certChains) {
+ System.arraycopy(chain, 0, certs, i, chain.length);
+ i += chain.length;
+ }
+
+ return certs;
+ }
+
+ return null;
+ }
+
+ public InputStream getInputStream(ZipEntry ze) {
+ final InputStream is = getZipInputStream(ze);
+
+ if (isSigned) {
+ JarVerifier.VerifierEntry entry = verifier.initEntry(ze.getName());
+ if (entry == null) {
+ return is;
+ }
+
+ return new JarFile.JarFileInputStream(is, ze.getSize(), entry);
+ }
+
+ return is;
+ }
+
+ public void close() throws IOException {
+ if (!closed) {
+ guard.close();
+
+ nativeClose(nativeHandle);
+ IoUtils.closeQuietly(raf);
+ closed = true;
+ }
+ }
+
+ private InputStream getZipInputStream(ZipEntry ze) {
+ if (ze.getMethod() == ZipEntry.STORED) {
+ return new ZipFile.RAFStream(raf, ze.getDataOffset(),
+ ze.getDataOffset() + ze.getSize());
+ } else {
+ final ZipFile.RAFStream wrapped = new ZipFile.RAFStream(
+ raf, ze.getDataOffset(), ze.getDataOffset() + ze.getCompressedSize());
+
+ int bufSize = Math.max(1024, (int) Math.min(ze.getSize(), 65535L));
+ return new ZipFile.ZipInflaterInputStream(wrapped, new Inflater(true), bufSize, ze);
+ }
+ }
+
+ static final class EntryIterator implements Iterator<ZipEntry> {
+ private final long iterationHandle;
+ private ZipEntry nextEntry;
+
+ EntryIterator(long nativeHandle, String prefix) throws IOException {
+ iterationHandle = nativeStartIteration(nativeHandle, prefix);
+ }
+
+ public ZipEntry next() {
+ if (nextEntry != null) {
+ final ZipEntry ze = nextEntry;
+ nextEntry = null;
+ return ze;
+ }
+
+ return nativeNextEntry(iterationHandle);
+ }
+
+ public boolean hasNext() {
+ if (nextEntry != null) {
+ return true;
+ }
+
+ final ZipEntry ze = nativeNextEntry(iterationHandle);
+ if (ze == null) {
+ return false;
+ }
+
+ nextEntry = ze;
+ return true;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private HashMap<String, byte[]> getMetaEntries() throws IOException {
+ HashMap<String, byte[]> metaEntries = new HashMap<String, byte[]>();
+
+ Iterator<ZipEntry> entryIterator = new EntryIterator(nativeHandle, "META-INF/");
+ while (entryIterator.hasNext()) {
+ final ZipEntry entry = entryIterator.next();
+ metaEntries.put(entry.getName(), Streams.readFully(getInputStream(entry)));
+ }
+
+ return metaEntries;
+ }
+
+ private static native long nativeOpenJarFile(String fileName) throws IOException;
+ private static native long nativeStartIteration(long nativeHandle, String prefix);
+ private static native ZipEntry nativeNextEntry(long iterationHandle);
+ private static native ZipEntry nativeFindEntry(long nativeHandle, String entryName);
+ private static native void nativeClose(long nativeHandle);
+}
diff --git a/luni/src/main/java/java/util/logging/SocketHandler.java b/luni/src/main/java/java/util/logging/SocketHandler.java
index 85a9e6c..48bfc0e 100644
--- a/luni/src/main/java/java/util/logging/SocketHandler.java
+++ b/luni/src/main/java/java/util/logging/SocketHandler.java
@@ -108,12 +108,9 @@ public class SocketHandler extends StreamHandler {
// check the validity of the port number
int p = 0;
try {
- p = Integer.parseInt(port);
+ p = Integer.parsePositiveInt(port);
} catch (NumberFormatException e) {
- throw new IllegalArgumentException("Illegal port argument");
- }
- if (p <= 0) {
- throw new IllegalArgumentException("Illegal port argument");
+ throw new IllegalArgumentException("Illegal port argument " + port);
}
// establish the network connection
try {
diff --git a/luni/src/main/java/java/util/prefs/FilePreferencesFactoryImpl.java b/luni/src/main/java/java/util/prefs/FilePreferencesFactoryImpl.java
index 8f2d0aa..154c71e 100644
--- a/luni/src/main/java/java/util/prefs/FilePreferencesFactoryImpl.java
+++ b/luni/src/main/java/java/util/prefs/FilePreferencesFactoryImpl.java
@@ -24,10 +24,12 @@ package java.util.prefs;
*/
class FilePreferencesFactoryImpl implements PreferencesFactory {
// user root preferences
- private static final Preferences USER_ROOT = new FilePreferencesImpl(true);
+ private static final Preferences USER_ROOT = new FilePreferencesImpl(
+ System.getProperty("user.home") + "/.java/.userPrefs", true);
// system root preferences
- private static final Preferences SYSTEM_ROOT = new FilePreferencesImpl(false);
+ private static final Preferences SYSTEM_ROOT = new FilePreferencesImpl(
+ System.getProperty("java.home") + "/.systemPrefs", false);
public FilePreferencesFactoryImpl() {
}
@@ -39,5 +41,4 @@ class FilePreferencesFactoryImpl implements PreferencesFactory {
public Preferences systemRoot() {
return SYSTEM_ROOT;
}
-
}
diff --git a/luni/src/main/java/java/util/prefs/FilePreferencesImpl.java b/luni/src/main/java/java/util/prefs/FilePreferencesImpl.java
index bd367a6..de1ead4 100644
--- a/luni/src/main/java/java/util/prefs/FilePreferencesImpl.java
+++ b/luni/src/main/java/java/util/prefs/FilePreferencesImpl.java
@@ -30,20 +30,15 @@ import java.util.Set;
* TODO some sync mechanism with backend, Performance - check file edit date
*
* @since 1.4
+ *
+ * @hide
*/
-class FilePreferencesImpl extends AbstractPreferences {
-
+public class FilePreferencesImpl extends AbstractPreferences {
//prefs file name
private static final String PREFS_FILE_NAME = "prefs.xml";
- //home directory for user prefs
- private static String USER_HOME = System.getProperty("user.home") + "/.java/.userPrefs";
-
- //home directory for system prefs
- private static String SYSTEM_HOME = System.getProperty("java.home") + "/.systemPrefs";
-
//file path for this preferences node
- private String path;
+ private final String path;
//internal cache for prefs key-value pair
private Properties prefs;
@@ -67,13 +62,15 @@ class FilePreferencesImpl extends AbstractPreferences {
*/
/**
- * Construct root <code>FilePreferencesImpl</code> instance, construct
- * user root if userNode is true, system root otherwise
+ * Construct root <code>FilePreferencesImpl</code> instance rooted
+ * at the given path.
+ *
+ * @hide
*/
- FilePreferencesImpl(boolean userNode) {
+ public FilePreferencesImpl(String path, boolean isUserNode) {
super(null, "");
- this.userNode = userNode;
- path = userNode ? USER_HOME : SYSTEM_HOME;
+ this.path = path;
+ this.userNode = isUserNode;
initPrefs();
}
diff --git a/luni/src/main/java/java/util/prefs/Preferences.java b/luni/src/main/java/java/util/prefs/Preferences.java
index b808052..342be70 100644
--- a/luni/src/main/java/java/util/prefs/Preferences.java
+++ b/luni/src/main/java/java/util/prefs/Preferences.java
@@ -98,8 +98,17 @@ public abstract class Preferences {
*/
public static final int MAX_VALUE_LENGTH = 8192;
- //factory used to get user/system prefs root
- private static final PreferencesFactory factory = findPreferencesFactory();
+ // factory used to get user/system prefs root
+ private static volatile PreferencesFactory factory = findPreferencesFactory();
+
+ /**
+ * @hide for testing only.
+ */
+ public static PreferencesFactory setPreferencesFactory(PreferencesFactory pf) {
+ PreferencesFactory previous = factory;
+ factory = pf;
+ return previous;
+ }
private static PreferencesFactory findPreferencesFactory() {
// Try the system property first...
@@ -780,6 +789,11 @@ public abstract class Preferences {
public abstract void sync() throws BackingStoreException;
/**
+ * <strong>Legacy code; do not use.</strong> On Android, the Preference nodes
+ * corresponding to the "system" and "user" preferences are stored in sections
+ * of the file system that are inaccessible to apps. Further, allowing apps to set
+ * "system wide" preferences is contrary to android's security model.
+ *
* Returns the system preference node for the package of the given class.
* The absolute path of the returned node is one slash followed by the given
* class's full package name, replacing each period character ('.') with
@@ -796,11 +810,16 @@ public abstract class Preferences {
* @throws NullPointerException
* if the given class is {@code null}.
*/
- public static Preferences systemNodeForPackage (Class<?> c) {
+ public static Preferences systemNodeForPackage(Class<?> c) {
return factory.systemRoot().node(getNodeName(c));
}
/**
+ * <strong>Legacy code; do not use.</strong> On Android, the Preference nodes
+ * corresponding to the "system" and "user" preferences are stored in sections
+ * of the file system that are inaccessible to apps. Further, allowing apps to set
+ * "system wide" preferences is contrary to android's security model.
+ *
* Returns the root node of the system preference hierarchy.
*
* @return the system preference hierarchy root node.
@@ -810,6 +829,13 @@ public abstract class Preferences {
}
/**
+ *
+ * <strong>Legacy code; do not use.</strong> On Android, the Preference nodes
+ * corresponding to the "system" and "user" preferences are stored in sections
+ * of the file system that are inaccessible to apps. Further, allowing apps to set
+ * "system wide" preferences is contrary to android's security model.
+ *
+ * <p>
* Returns the user preference node for the package of the given class.
* The absolute path of the returned node is one slash followed by the given
* class's full package name, replacing each period character ('.') with
@@ -820,13 +846,11 @@ public abstract class Preferences {
* by this method won't necessarily be persisted until the method {@code
* flush()} is invoked.
*
- * @param c
- * the given class.
* @return the user preference node for the package of the given class.
* @throws NullPointerException
* if the given class is {@code null}.
*/
- public static Preferences userNodeForPackage (Class<?> c) {
+ public static Preferences userNodeForPackage(Class<?> c) {
return factory.userRoot().node(getNodeName(c));
}
@@ -840,6 +864,11 @@ public abstract class Preferences {
}
/**
+ * <strong>Legacy code; do not use.</strong> On Android, the Preference nodes
+ * corresponding to the "system" and "user" preferences are stored in sections
+ * of the file system that are inaccessible to apps. Further, allowing apps to set
+ * "system wide" preferences is contrary to android's security model.
+ *
* Returns the root node of the user preference hierarchy.
*
* @return the user preference hierarchy root node.
diff --git a/luni/src/main/java/java/util/regex/MatchResult.java b/luni/src/main/java/java/util/regex/MatchResult.java
index 76c17a8..c77206d 100644
--- a/luni/src/main/java/java/util/regex/MatchResult.java
+++ b/luni/src/main/java/java/util/regex/MatchResult.java
@@ -19,79 +19,65 @@ package java.util.regex;
/**
* Holds the results of a successful match of a {@link Pattern} against a
- * given string. The result is divided into groups, with one group for each
- * pair of parentheses in the regular expression and an additional group for
- * the whole regular expression. The start, end, and contents of each group
- * can be queried.
- *
- * @see Matcher
- * @see Matcher#toMatchResult()
+ * given string. Typically this is an instance of {@link Matcher}, but
+ * since that's a mutable class it's also possible to freeze its current
+ * state using {@link Matcher#toMatchResult}.
*/
public interface MatchResult {
/**
* Returns the index of the first character following the text that matched
* the whole regular expression.
- *
- * @return the character index.
*/
int end();
/**
* Returns the index of the first character following the text that matched
- * a given group.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- *
- * @return the character index.
+ * a given group. See {@link #group} for an explanation of group indexes.
*/
int end(int group);
/**
* Returns the text that matched the whole regular expression.
- *
- * @return the text.
*/
String group();
/**
* Returns the text that matched a given group of the regular expression.
*
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
+ * <p>Explicit capturing groups in the pattern are numbered left to right in order
+ * of their <i>opening</i> parenthesis, starting at 1.
+ * The special group 0 represents the entire match (as if the entire pattern is surrounded
+ * by an implicit capturing group).
+ * For example, "a((b)c)" matching "abc" would give the following groups:
+ * <pre>
+ * 0 "abc"
+ * 1 "bc"
+ * 2 "b"
+ * </pre>
*
- * @return the text that matched the group.
+ * <p>An optional capturing group that failed to match as part of an overall
+ * successful match (for example, "a(b)?c" matching "ac") returns null.
+ * A capturing group that matched the empty string (for example, "a(b?)c" matching "ac")
+ * returns the empty string.
*/
String group(int group);
/**
- * Returns the number of groups in the result, which is always equal to
+ * Returns the number of groups in the results, which is always equal to
* the number of groups in the original regular expression.
- *
- * @return the number of groups.
*/
int groupCount();
/**
- * Returns the index of the first character of the text that matched
- * the whole regular expression.
- *
- * @return the character index.
+ * Returns the index of the first character of the text that matched the
+ * whole regular expression.
*/
int start();
/**
* Returns the index of the first character of the text that matched a given
- * group.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- *
- * @return the character index.
+ * group. See {@link #group} for an explanation of group indexes.
*/
int start(int group);
}
diff --git a/luni/src/main/java/java/util/regex/MatchResultImpl.java b/luni/src/main/java/java/util/regex/MatchResultImpl.java
index b685757..6a0d948 100644
--- a/luni/src/main/java/java/util/regex/MatchResultImpl.java
+++ b/luni/src/main/java/java/util/regex/MatchResultImpl.java
@@ -32,7 +32,7 @@ class MatchResultImpl implements MatchResult {
/**
* Holds the offsets of the groups in the input text. The first two
- * elements specifiy start and end of the zero group, the next two specify
+ * elements specify start and end of the zero group, the next two specify
* group 1, and so on.
*/
private int[] offsets;
diff --git a/luni/src/main/java/java/util/regex/Matcher.java b/luni/src/main/java/java/util/regex/Matcher.java
index 02531d7..d181d45 100644
--- a/luni/src/main/java/java/util/regex/Matcher.java
+++ b/luni/src/main/java/java/util/regex/Matcher.java
@@ -276,8 +276,6 @@ public final class Matcher implements MatchResult {
* walk through the input and replace all matches of the {@code Pattern}
* with something else.
*
- * @param buffer
- * the {@code StringBuffer} to append to.
* @return the {@code StringBuffer}.
* @throws IllegalStateException
* if no successful match has been made.
@@ -325,57 +323,12 @@ public final class Matcher implements MatchResult {
/**
* Returns the {@link Pattern} instance used inside this matcher.
- *
- * @return the {@code Pattern} instance.
*/
public Pattern pattern() {
return pattern;
}
/**
- * Returns the text that matched a given group of the regular expression.
- * Explicit capturing groups in the pattern are numbered left to right in order
- * of their <i>opening</i> parenthesis, starting at 1.
- * The special group 0 represents the entire match (as if the entire pattern is surrounded
- * by an implicit capturing group).
- * For example, "a((b)c)" matching "abc" would give the following groups:
- * <pre>
- * 0 "abc"
- * 1 "bc"
- * 2 "b"
- * </pre>
- *
- * <p>An optional capturing group that failed to match as part of an overall
- * successful match (for example, "a(b)?c" matching "ac") returns null.
- * A capturing group that matched the empty string (for example, "a(b?)c" matching "ac")
- * returns the empty string.
- *
- * @throws IllegalStateException
- * if no successful match has been made.
- */
- public String group(int group) {
- ensureMatch();
- int from = matchOffsets[group * 2];
- int to = matchOffsets[(group * 2) + 1];
- if (from == -1 || to == -1) {
- return null;
- } else {
- return input.substring(from, to);
- }
- }
-
- /**
- * Returns the text that matched the whole regular expression.
- *
- * @return the text.
- * @throws IllegalStateException
- * if no successful match has been made.
- */
- public String group() {
- return group(0);
- }
-
- /**
* Returns true if there is another match in the input, starting
* from the given position. The region is ignored.
*
@@ -393,7 +346,7 @@ public final class Matcher implements MatchResult {
}
/**
- * Returns the next occurrence of the {@link Pattern} in the input. If a
+ * Moves to the next occurrence of the pattern in the input. If a
* previous match was successful, the method continues the search from the
* first character following that match in the input. Otherwise it searches
* either from the region start (if one has been set), or from position 0.
@@ -436,45 +389,8 @@ public final class Matcher implements MatchResult {
}
/**
- * Returns the index of the first character of the text that matched a given
- * group.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- * @return the character index.
- * @throws IllegalStateException
- * if no successful match has been made.
- */
- public int start(int group) throws IllegalStateException {
- ensureMatch();
- return matchOffsets[group * 2];
- }
-
- /**
- * Returns the index of the first character following the text that matched
- * a given group.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- * @return the character index.
- * @throws IllegalStateException
- * if no successful match has been made.
- */
- public int end(int group) {
- ensureMatch();
- return matchOffsets[(group * 2) + 1];
- }
-
- /**
* Returns a replacement string for the given one that has all backslashes
* and dollar signs escaped.
- *
- * @param s
- * the input string.
- * @return the input string, with all backslashes and dollar signs having
- * been escaped.
*/
public static String quoteReplacement(String s) {
StringBuilder result = new StringBuilder(s.length());
@@ -489,47 +405,10 @@ public final class Matcher implements MatchResult {
}
/**
- * Returns the index of the first character of the text that matched the
- * whole regular expression.
- *
- * @return the character index.
- * @throws IllegalStateException
- * if no successful match has been made.
- */
- public int start() {
- return start(0);
- }
-
- /**
- * Returns the number of groups in the results, which is always equal to
- * the number of groups in the original regular expression.
- *
- * @return the number of groups.
- */
- public int groupCount() {
- synchronized (this) {
- return groupCountImpl(address);
- }
- }
-
- /**
- * Returns the index of the first character following the text that matched
- * the whole regular expression.
- *
- * @return the character index.
- * @throws IllegalStateException
- * if no successful match has been made.
- */
- public int end() {
- return end(0);
- }
-
- /**
* Converts the current match into a separate {@link MatchResult} instance
* that is independent from this matcher. The new object is unaffected when
* the state of this matcher changes.
*
- * @return the new {@code MatchResult}.
* @throws IllegalStateException
* if no successful match has been made.
*/
@@ -544,8 +423,6 @@ public final class Matcher implements MatchResult {
* '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
* by default.
*
- * @param value
- * the new value for anchoring bounds.
* @return the {@code Matcher} itself.
*/
public Matcher useAnchoringBounds(boolean value) {
@@ -572,8 +449,6 @@ public final class Matcher implements MatchResult {
* region are subject to lookahead and lookbehind, otherwise they are not.
* Transparent bounds are disabled by default.
*
- * @param value
- * the new value for transparent bounds.
* @return the {@code Matcher} itself.
*/
public Matcher useTransparentBounds(boolean value) {
@@ -666,6 +541,78 @@ public final class Matcher implements MatchResult {
" lastmatch=" + (matchFound ? group() : "") + "]";
}
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalStateException if no successful match has been made.
+ */
+ public int end() {
+ return end(0);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalStateException if no successful match has been made.
+ */
+ public int end(int group) {
+ ensureMatch();
+ return matchOffsets[(group * 2) + 1];
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalStateException if no successful match has been made.
+ */
+ public String group() {
+ return group(0);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalStateException if no successful match has been made.
+ */
+ public String group(int group) {
+ ensureMatch();
+ int from = matchOffsets[group * 2];
+ int to = matchOffsets[(group * 2) + 1];
+ if (from == -1 || to == -1) {
+ return null;
+ } else {
+ return input.substring(from, to);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int groupCount() {
+ synchronized (this) {
+ return groupCountImpl(address);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalStateException if no successful match has been made.
+ */
+ public int start() {
+ return start(0);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalStateException if no successful match has been made.
+ */
+ public int start(int group) throws IllegalStateException {
+ ensureMatch();
+ return matchOffsets[group * 2];
+ }
+
private static native void closeImpl(long addr);
private static native boolean findImpl(long addr, String s, int startIndex, int[] offsets);
private static native boolean findNextImpl(long addr, String s, int[] offsets);
diff --git a/luni/src/main/java/java/util/regex/Pattern.java b/luni/src/main/java/java/util/regex/Pattern.java
index a33ee93..8f3fb12 100644
--- a/luni/src/main/java/java/util/regex/Pattern.java
+++ b/luni/src/main/java/java/util/regex/Pattern.java
@@ -183,7 +183,7 @@ import java.io.Serializable;
* <tr> <td> <i>a</i>|<i>b</i> </td> <td>Either expression <i>a</i> or expression <i>b</i>.</td> </tr>
* </table>
*
- * <a name="flags"><h3>Flags</h3></a>
+ * <a name="flags"></a><h3>Flags</h3>
* <p><table>
* <tr> <td> (?dimsux-dimsux:<i>a</i>) </td> <td>Evaluates the expression <i>a</i> with the given flags enabled/disabled.</td> </tr>
* <tr> <td> (?dimsux-dimsux) </td> <td>Evaluates the rest of the pattern with the given flags enabled/disabled.</td> </tr>
diff --git a/luni/src/main/java/java/util/spi/CurrencyNameProvider.java b/luni/src/main/java/java/util/spi/CurrencyNameProvider.java
deleted file mode 100644
index d717aa2..0000000
--- a/luni/src/main/java/java/util/spi/CurrencyNameProvider.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.spi;
-
-import java.util.Locale;
-
-/**
- * This abstract class should be extended by service providers that provide
- * localized currency symbols (currency names) from currency codes.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class CurrencyNameProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected CurrencyNameProvider() {
- // do nothing
- }
-
- /**
- * Returns the localized currency symbol for the given currency code.
- *
- * @param code an ISO 4217 currency code
- * @param locale a locale
- * @return the symbol or null if there is no available symbol in the locale
- * @throws NullPointerException
- * if {@code code == null || locale == null}
- * @throws IllegalArgumentException
- * if code or locale is not in a legal format or not available
- */
- public abstract String getSymbol(String code, Locale locale);
-}
diff --git a/luni/src/main/java/java/util/spi/LocaleNameProvider.java b/luni/src/main/java/java/util/spi/LocaleNameProvider.java
deleted file mode 100644
index 0d25074..0000000
--- a/luni/src/main/java/java/util/spi/LocaleNameProvider.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.spi;
-
-import java.util.Locale;
-
-/**
- * This abstract class should be extended by service providers that provide
- * localized locale names.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class LocaleNameProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected LocaleNameProvider() {
- // do nothing
- }
-
- /**
- * Returns the localized name for the given ISO 639 language code.
- *
- * @param languageCode an ISO 639 language code
- * @param locale a locale
- * @return the name or null if unavailable
- * @throws NullPointerException
- * if {@code code == null || locale == null}
- * @throws IllegalArgumentException
- * if code or locale is not in a legal format or not available
- */
- public abstract String getDisplayLanguage(String languageCode, Locale locale);
-
- /**
- * Returns the localized name for the given ISO 3166 country code.
- *
- * @param countryCode an ISO 3166 language code
- * @param locale a locale
- * @return the name or null if unavailable
- * @throws NullPointerException
- * if {@code code == null || locale == null}
- * @throws IllegalArgumentException
- * if code or locale is not in a legal format or not available
- */
- public abstract String getDisplayCountry(String countryCode, Locale locale);
-
- /**
- * Returns the localized name for the given variant code.
- *
- * @param variantCode a variant code
- * @param locale a locale
- * @return the name or null if unavailable
- * @throws NullPointerException
- * if {@code code == null || locale == null}
- * @throws IllegalArgumentException
- * if code or locale is not in a legal format or not available
- */
- public abstract String getDisplayVariant(String variantCode, Locale locale);
-}
diff --git a/luni/src/main/java/java/util/spi/LocaleServiceProvider.java b/luni/src/main/java/java/util/spi/LocaleServiceProvider.java
deleted file mode 100644
index b1b62de..0000000
--- a/luni/src/main/java/java/util/spi/LocaleServiceProvider.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.spi;
-
-import java.util.Locale;
-
-/**
- * The base class for all the locale related service provider interfaces (SPIs).
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected LocaleServiceProvider() {
- // do nothing
- }
-
- /**
- * Returns all locales for which this locale service provider has localized objects or names.
- */
- public abstract Locale[] getAvailableLocales();
-}
diff --git a/luni/src/main/java/java/util/spi/TimeZoneNameProvider.java b/luni/src/main/java/java/util/spi/TimeZoneNameProvider.java
deleted file mode 100644
index 533d14e..0000000
--- a/luni/src/main/java/java/util/spi/TimeZoneNameProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.spi;
-
-import java.util.Locale;
-
-/**
- * This abstract class should be extended by service providers that provide
- * localized time zone names.
- * <p>Note that Android does not support user-supplied locale service providers.
- * @since 1.6
- * @hide
- */
-public abstract class TimeZoneNameProvider extends LocaleServiceProvider {
- /**
- * Default constructor, for use by subclasses.
- */
- protected TimeZoneNameProvider() {
- // do nothing
- }
-
- /**
- * Returns the localized name for the given time zone in the given locale.
- *
- * @param id the time zone id
- * @param daylight true to return the name for daylight saving time.
- * @param style TimeZone.LONG or TimeZone.SHORT
- * @param locale the locale
- * @return the readable time zone name, or null if it is unavailable
- * @throws NullPointerException
- * if {@code id == null || locale == null}
- * @throws IllegalArgumentException
- * if locale is not available or style is invalid
- */
- public abstract String getDisplayName(String id, boolean daylight, int style, Locale locale);
-}
diff --git a/luni/src/main/java/java/util/zip/Deflater.java b/luni/src/main/java/java/util/zip/Deflater.java
index 3365031..040058b 100644
--- a/luni/src/main/java/java/util/zip/Deflater.java
+++ b/luni/src/main/java/java/util/zip/Deflater.java
@@ -51,7 +51,7 @@ import libcore.util.EmptyArray;
* {@link DeflaterOutputStream} to handle all this for you. {@link DeflaterOutputStream} also helps
* minimize memory requirements&nbsp;&mdash; the sample code above is very expensive.
*
- * <a name="compression_level"><h3>Compression levels</h3></a>
+ * <a name="compression_level"></a><h3>Compression levels</h3>
* <p>A compression level must be {@link #DEFAULT_COMPRESSION} to compromise between speed and
* compression (currently equivalent to level 6), or between 0 ({@link #NO_COMPRESSION}, where
* the input is simply copied) and 9 ({@link #BEST_COMPRESSION}). Level 1 ({@link #BEST_SPEED})
@@ -347,7 +347,7 @@ public class Deflater {
/**
* Resets the {@code Deflater} to accept new input without affecting any
- * previously made settings for the compression strategy or level. This
+ * previous compression strategy or level settings. This
* operation <i>must</i> be called after {@link #finished} returns
* true if the {@code Deflater} is to be reused.
*/
@@ -417,7 +417,7 @@ public class Deflater {
* Sets the given <a href="#compression_level">compression level</a>
* to be used when compressing data. This value must be set
* prior to calling {@link #setInput setInput}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* If the compression level is invalid.
*/
public synchronized void setLevel(int level) {
@@ -435,7 +435,7 @@ public class Deflater {
* FILTERED, HUFFMAN_ONLY or DEFAULT_STRATEGY. This value must be set prior
* to calling {@link #setInput setInput}.
*
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* If the strategy specified is not one of FILTERED,
* HUFFMAN_ONLY or DEFAULT_STRATEGY.
*/
diff --git a/luni/src/main/java/java/util/zip/DeflaterInputStream.java b/luni/src/main/java/java/util/zip/DeflaterInputStream.java
index f987e39..16bf92f 100644
--- a/luni/src/main/java/java/util/zip/DeflaterInputStream.java
+++ b/luni/src/main/java/java/util/zip/DeflaterInputStream.java
@@ -133,17 +133,20 @@ public class DeflaterInputStream extends FilterInputStream {
def.setInput(buf, 0, bytesRead);
}
}
- int bytesDeflated = def.deflate(buf, 0, Math.min(buf.length, byteCount - count));
+ int bytesDeflated = def.deflate(buffer, byteOffset + count, byteCount - count);
if (bytesDeflated == -1) {
break;
}
- System.arraycopy(buf, 0, buffer, byteOffset + count, bytesDeflated);
count += bytesDeflated;
}
if (count == 0) {
count = -1;
available = false;
}
+
+ if (def.finished()) {
+ available = false;
+ }
return count;
}
diff --git a/luni/src/main/java/java/util/zip/DeflaterOutputStream.java b/luni/src/main/java/java/util/zip/DeflaterOutputStream.java
index 6cce5a5..3377afd 100644
--- a/luni/src/main/java/java/util/zip/DeflaterOutputStream.java
+++ b/luni/src/main/java/java/util/zip/DeflaterOutputStream.java
@@ -188,7 +188,10 @@ public class DeflaterOutputStream extends FilterOutputStream {
* Doing so may degrade compression but improve interactive behavior.
*/
@Override public void flush() throws IOException {
- if (syncFlush) {
+ // Though not documented, it's illegal to call deflate with any flush param
+ // other than Z_FINISH after the deflater has finished. See the error checking
+ // at the start of the deflate function in deflate.c.
+ if (syncFlush && !done) {
int byteCount;
while ((byteCount = def.deflate(buf, 0, buf.length, Deflater.SYNC_FLUSH)) != 0) {
out.write(buf, 0, byteCount);
diff --git a/luni/src/main/java/java/util/zip/GZIPInputStream.java b/luni/src/main/java/java/util/zip/GZIPInputStream.java
index 08599ea..1bfc496 100644
--- a/luni/src/main/java/java/util/zip/GZIPInputStream.java
+++ b/luni/src/main/java/java/util/zip/GZIPInputStream.java
@@ -20,9 +20,11 @@ package java.util.zip;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.PushbackInputStream;
import java.nio.ByteOrder;
import java.util.Arrays;
import libcore.io.Memory;
+import libcore.io.Streams;
/**
* The {@code GZIPInputStream} class is used to read data stored in the GZIP
@@ -43,6 +45,9 @@ import libcore.io.Memory;
* zis.close();
* }
* </pre>
+ *
+ * <p>Note that this class ignores all remaining data at the end of the last
+ * GZIP member.
*/
public class GZIPInputStream extends InflaterInputStream {
private static final int FCOMMENT = 16;
@@ -53,6 +58,8 @@ public class GZIPInputStream extends InflaterInputStream {
private static final int FNAME = 8;
+ private static final int GZIP_TRAILER_SIZE = 8;
+
/**
* The magic header for the GZIP format.
*/
@@ -94,48 +101,18 @@ public class GZIPInputStream extends InflaterInputStream {
*/
public GZIPInputStream(InputStream is, int size) throws IOException {
super(is, new Inflater(true), size);
- byte[] header = new byte[10];
- readFully(header, 0, header.length);
- short magic = Memory.peekShort(header, 0, ByteOrder.LITTLE_ENDIAN);
- if (magic != (short) GZIP_MAGIC) {
- throw new IOException(String.format("unknown format (magic number %x)", magic));
- }
- int flags = header[3];
- boolean hcrc = (flags & FHCRC) != 0;
- if (hcrc) {
- crc.update(header, 0, header.length);
- }
- if ((flags & FEXTRA) != 0) {
- readFully(header, 0, 2);
- if (hcrc) {
- crc.update(header, 0, 2);
- }
- int length = Memory.peekShort(header, 0, ByteOrder.LITTLE_ENDIAN) & 0xffff;
- while (length > 0) {
- int max = length > buf.length ? buf.length : length;
- int result = in.read(buf, 0, max);
- if (result == -1) {
- throw new EOFException();
- }
- if (hcrc) {
- crc.update(buf, 0, result);
- }
- length -= result;
- }
- }
- if ((flags & FNAME) != 0) {
- readZeroTerminated(hcrc);
- }
- if ((flags & FCOMMENT) != 0) {
- readZeroTerminated(hcrc);
- }
- if (hcrc) {
- readFully(header, 0, 2);
- short crc16 = Memory.peekShort(header, 0, ByteOrder.LITTLE_ENDIAN);
- if ((short) crc.getValue() != crc16) {
- throw new IOException("CRC mismatch");
+
+ try {
+ byte[] header = readHeader(is);
+ final short magic = Memory.peekShort(header, 0, ByteOrder.LITTLE_ENDIAN);
+ if (magic != (short) GZIP_MAGIC) {
+ throw new IOException(String.format("unknown format (magic number %x)", magic));
}
- crc.reset();
+
+ parseGzipHeader(is, header, crc, buf);
+ } catch (IOException e) {
+ close(); // release the inflater
+ throw e;
}
}
@@ -171,11 +148,109 @@ public class GZIPInputStream extends InflaterInputStream {
if (eos) {
verifyCrc();
+ eos = maybeReadNextMember();
+ if (!eos) {
+ crc.reset();
+ inf.reset();
+ eof = false;
+ len = 0;
+ }
}
return bytesRead;
}
+ private boolean maybeReadNextMember() throws IOException {
+ // If we have any unconsumed data in the inflater buffer, we have to
+ // scan that first. The fact that we've reached here implies we've
+ // successfully consumed the GZIP trailer.
+ final int remaining = inf.getRemaining() - GZIP_TRAILER_SIZE;
+ if (remaining > 0) {
+ // NOTE: We make sure we create a pushback stream exactly once,
+ // even if the input stream contains multiple members.
+ //
+ // The push back stream we create must therefore be able to contain
+ // (worst case) the entire buffer even though there may be fewer bytes
+ // remaining when it is first created.
+ if (!(in instanceof PushbackInputStream)) {
+ in = new PushbackInputStream(in, buf.length);
+ }
+ ((PushbackInputStream) in).unread(buf,
+ inf.getCurrentOffset() + GZIP_TRAILER_SIZE, remaining);
+ }
+
+ final byte[] buffer;
+ try {
+ buffer = readHeader(in);
+ } catch (EOFException eof) {
+ // We've reached the end of the stream and there are no more members
+ // to read. Note that we might also hit this if there are fewer than
+ // GZIP_HEADER_LENGTH bytes at the end of a member. We don't care
+ // because we're specified to ignore all data at the end of the last
+ // gzip record.
+ return true;
+ }
+
+ final short magic = Memory.peekShort(buffer, 0, ByteOrder.LITTLE_ENDIAN);
+ if (magic != (short) GZIP_MAGIC) {
+ // Don't throw here because we've already read one valid member
+ // from this stream.
+ return true;
+ }
+
+ // We've encountered the gzip magic number, so we assume there's another
+ // member in the stream.
+ parseGzipHeader(in, buffer, crc, buf);
+ return false;
+ }
+
+ private static byte[] readHeader(InputStream in) throws IOException {
+ byte[] header = new byte[10];
+ Streams.readFully(in, header, 0, header.length);
+ return header;
+ }
+
+ private static void parseGzipHeader(InputStream in, byte[] header,
+ CRC32 crc, byte[] scratch) throws IOException {
+ final byte flags = header[3];
+ final boolean hcrc = (flags & FHCRC) != 0;
+ if (hcrc) {
+ crc.update(header, 0, header.length);
+ }
+ if ((flags & FEXTRA) != 0) {
+ Streams.readFully(in, header, 0, 2);
+ if (hcrc) {
+ crc.update(header, 0, 2);
+ }
+ int length = Memory.peekShort(scratch, 0, ByteOrder.LITTLE_ENDIAN) & 0xffff;
+ while (length > 0) {
+ int max = length > scratch.length ? scratch.length : length;
+ int result = in.read(scratch, 0, max);
+ if (result == -1) {
+ throw new EOFException();
+ }
+ if (hcrc) {
+ crc.update(scratch, 0, result);
+ }
+ length -= result;
+ }
+ }
+ if ((flags & FNAME) != 0) {
+ readZeroTerminated(in, crc, hcrc);
+ }
+ if ((flags & FCOMMENT) != 0) {
+ readZeroTerminated(in, crc, hcrc);
+ }
+ if (hcrc) {
+ Streams.readFully(in, header, 0, 2);
+ short crc16 = Memory.peekShort(scratch, 0, ByteOrder.LITTLE_ENDIAN);
+ if ((short) crc.getValue() != crc16) {
+ throw new IOException("CRC mismatch");
+ }
+ crc.reset();
+ }
+ }
+
private void verifyCrc() throws IOException {
// Get non-compressed bytes read by fill
int size = inf.getRemaining();
@@ -184,7 +259,7 @@ public class GZIPInputStream extends InflaterInputStream {
int copySize = (size > trailerSize) ? trailerSize : size;
System.arraycopy(buf, len - size, b, 0, copySize);
- readFully(b, copySize, trailerSize - copySize);
+ Streams.readFully(in, b, copySize, trailerSize - copySize);
if (Memory.peekInt(b, 0, ByteOrder.LITTLE_ENDIAN) != (int) crc.getValue()) {
throw new IOException("CRC mismatch");
@@ -194,20 +269,11 @@ public class GZIPInputStream extends InflaterInputStream {
}
}
- private void readFully(byte[] buffer, int offset, int length) throws IOException {
- int result;
- while (length > 0) {
- result = in.read(buffer, offset, length);
- if (result == -1) {
- throw new EOFException();
- }
- offset += result;
- length -= result;
- }
- }
-
- private void readZeroTerminated(boolean hcrc) throws IOException {
+ private static void readZeroTerminated(InputStream in, CRC32 crc, boolean hcrc)
+ throws IOException {
int result;
+ // TODO: Fix these single byte reads. This method is used to consume the
+ // header FNAME & FCOMMENT which aren't widely used in gzip files.
while ((result = in.read()) > 0) {
if (hcrc) {
crc.update(result);
diff --git a/luni/src/main/java/java/util/zip/GZIPOutputStream.java b/luni/src/main/java/java/util/zip/GZIPOutputStream.java
index 8dd907b..0111292 100644
--- a/luni/src/main/java/java/util/zip/GZIPOutputStream.java
+++ b/luni/src/main/java/java/util/zip/GZIPOutputStream.java
@@ -51,7 +51,7 @@ public class GZIPOutputStream extends DeflaterOutputStream {
* the given stream.
*/
public GZIPOutputStream(OutputStream os) throws IOException {
- this(os, BUF_SIZE, true);
+ this(os, BUF_SIZE, false);
}
/**
@@ -65,11 +65,10 @@ public class GZIPOutputStream extends DeflaterOutputStream {
/**
* Constructs a new {@code GZIPOutputStream} to write data in GZIP format to
- * the given stream with the given internal buffer size and
- * flushing behavior (see {@link DeflaterOutputStream#flush}).
+ * the given stream with the given internal buffer size.
*/
public GZIPOutputStream(OutputStream os, int bufferSize) throws IOException {
- this(os, bufferSize, true);
+ this(os, bufferSize, false);
}
/**
diff --git a/luni/src/main/java/java/util/zip/Inflater.java b/luni/src/main/java/java/util/zip/Inflater.java
index ee10aa7..581ed94 100644
--- a/luni/src/main/java/java/util/zip/Inflater.java
+++ b/luni/src/main/java/java/util/zip/Inflater.java
@@ -170,6 +170,15 @@ public class Inflater {
}
/**
+ * Returns the offset of the next byte to read in the underlying buffer.
+ *
+ * For internal use only.
+ */
+ synchronized int getCurrentOffset() {
+ return inRead;
+ }
+
+ /**
* Returns the total number of bytes of input read by this {@code Inflater}. This
* method is limited to 32 bits; use {@link #getBytesRead} instead.
*/
diff --git a/luni/src/main/java/java/util/zip/InflaterInputStream.java b/luni/src/main/java/java/util/zip/InflaterInputStream.java
index 25b2fe8..e5ad3db 100644
--- a/luni/src/main/java/java/util/zip/InflaterInputStream.java
+++ b/luni/src/main/java/java/util/zip/InflaterInputStream.java
@@ -266,12 +266,7 @@ public class InflaterInputStream extends FilterInputStream {
}
/**
- * Reset the position of the stream to the last marked position. This
- * implementation overrides the supertype implementation and always throws
- * an {@link IOException IOException} when called.
- *
- * @throws IOException
- * if the method is called
+ * This operation is not supported and throws {@code IOException}.
*/
@Override
public void reset() throws IOException {
diff --git a/luni/src/main/java/java/util/zip/ZipEntry.java b/luni/src/main/java/java/util/zip/ZipEntry.java
index f64c717..217cc3c 100644
--- a/luni/src/main/java/java/util/zip/ZipEntry.java
+++ b/luni/src/main/java/java/util/zip/ZipEntry.java
@@ -20,14 +20,15 @@ package java.util.zip;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteOrder;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
-import libcore.io.Streams;
import libcore.io.BufferIterator;
import libcore.io.HeapBufferIterator;
+import libcore.io.Streams;
/**
* An entry within a zip file.
@@ -54,6 +55,8 @@ public class ZipEntry implements ZipConstants, Cloneable {
int nameLength = -1;
long localHeaderRelOffset = -1;
+ long dataOffset = -1;
+
/**
* Zip entry state: Deflated.
*/
@@ -64,6 +67,23 @@ public class ZipEntry implements ZipConstants, Cloneable {
*/
public static final int STORED = 0;
+ ZipEntry(String name, String comment, long crc, long compressedSize,
+ long size, int compressionMethod, int time, int modDate, byte[] extra,
+ int nameLength, long localHeaderRelOffset, long dataOffset) {
+ this.name = name;
+ this.comment = comment;
+ this.crc = crc;
+ this.compressedSize = compressedSize;
+ this.size = size;
+ this.compressionMethod = compressionMethod;
+ this.time = time;
+ this.modDate = modDate;
+ this.extra = extra;
+ this.nameLength = nameLength;
+ this.localHeaderRelOffset = localHeaderRelOffset;
+ this.dataOffset = dataOffset;
+ }
+
/**
* Constructs a new {@code ZipEntry} with the specified name. The name is actually a path,
* and may contain {@code /} characters.
@@ -75,9 +95,7 @@ public class ZipEntry implements ZipConstants, Cloneable {
if (name == null) {
throw new NullPointerException("name == null");
}
- if (name.length() > 0xFFFF) {
- throw new IllegalArgumentException("Name too long: " + name.length());
- }
+ validateStringLength("Name", name);
this.name = name;
}
@@ -184,11 +202,8 @@ public class ZipEntry implements ZipConstants, Cloneable {
this.comment = null;
return;
}
+ validateStringLength("Comment", comment);
- byte[] commentBytes = comment.getBytes(StandardCharsets.UTF_8);
- if (commentBytes.length > 0xffff) {
- throw new IllegalArgumentException("Comment too long: " + commentBytes.length);
- }
this.comment = comment;
}
@@ -287,6 +302,17 @@ public class ZipEntry implements ZipConstants, Cloneable {
}
}
+
+ /** @hide */
+ public void setDataOffset(long value) {
+ dataOffset = value;
+ }
+
+ /** @hide */
+ public long getDataOffset() {
+ return dataOffset;
+ }
+
/**
* Returns the string representation of this {@code ZipEntry}.
*
@@ -316,6 +342,7 @@ public class ZipEntry implements ZipConstants, Cloneable {
extra = ze.extra;
nameLength = ze.nameLength;
localHeaderRelOffset = ze.localHeaderRelOffset;
+ dataOffset = ze.dataOffset;
}
/**
@@ -344,12 +371,14 @@ public class ZipEntry implements ZipConstants, Cloneable {
/*
* Internal constructor. Creates a new ZipEntry by reading the
* Central Directory Entry (CDE) from "in", which must be positioned
- * at the CDE signature.
+ * at the CDE signature. If the GPBF_UTF8_FLAG is set in the CDE then
+ * UTF-8 is used to decode the string information, otherwise the
+ * defaultCharset is used.
*
* On exit, "in" will be positioned at the start of the next entry
* in the Central Directory.
*/
- ZipEntry(byte[] cdeHdrBuf, InputStream cdStream) throws IOException {
+ ZipEntry(byte[] cdeHdrBuf, InputStream cdStream, Charset defaultCharset) throws IOException {
Streams.readFully(cdStream, cdeHdrBuf, 0, cdeHdrBuf.length);
BufferIterator it = HeapBufferIterator.iterator(cdeHdrBuf, 0, cdeHdrBuf.length,
@@ -367,6 +396,13 @@ public class ZipEntry implements ZipConstants, Cloneable {
throw new ZipException("Invalid General Purpose Bit Flag: " + gpbf);
}
+ // If the GPBF_UTF8_FLAG is set then the character encoding is UTF-8 whatever the default
+ // provided.
+ Charset charset = defaultCharset;
+ if ((gpbf & ZipFile.GPBF_UTF8_FLAG) != 0) {
+ charset = StandardCharsets.UTF_8;
+ }
+
compressionMethod = it.readShort() & 0xffff;
time = it.readShort() & 0xffff;
modDate = it.readShort() & 0xffff;
@@ -389,19 +425,17 @@ public class ZipEntry implements ZipConstants, Cloneable {
if (containsNulByte(nameBytes)) {
throw new ZipException("Filename contains NUL byte: " + Arrays.toString(nameBytes));
}
- name = new String(nameBytes, 0, nameBytes.length, StandardCharsets.UTF_8);
+ name = new String(nameBytes, 0, nameBytes.length, charset);
if (extraLength > 0) {
extra = new byte[extraLength];
Streams.readFully(cdStream, extra, 0, extraLength);
}
- // The RI has always assumed UTF-8. (If GPBF_UTF8_FLAG isn't set, the encoding is
- // actually IBM-437.)
if (commentByteCount > 0) {
byte[] commentBytes = new byte[commentByteCount];
Streams.readFully(cdStream, commentBytes, 0, commentByteCount);
- comment = new String(commentBytes, 0, commentBytes.length, StandardCharsets.UTF_8);
+ comment = new String(commentBytes, 0, commentBytes.length, charset);
}
}
@@ -413,4 +447,14 @@ public class ZipEntry implements ZipConstants, Cloneable {
}
return false;
}
+
+ private static void validateStringLength(String argument, String string) {
+ // This check is not perfect: the character encoding is determined when the entry is
+ // written out. UTF-8 is probably a worst-case: most alternatives should be single byte per
+ // character.
+ byte[] bytes = string.getBytes(StandardCharsets.UTF_8);
+ if (bytes.length > 0xffff) {
+ throw new IllegalArgumentException(argument + " too long: " + bytes.length);
+ }
+ }
}
diff --git a/luni/src/main/java/java/util/zip/ZipFile.java b/luni/src/main/java/java/util/zip/ZipFile.java
index c25bbc1..b44156e 100644
--- a/luni/src/main/java/java/util/zip/ZipFile.java
+++ b/luni/src/main/java/java/util/zip/ZipFile.java
@@ -32,6 +32,7 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import libcore.io.BufferIterator;
import libcore.io.HeapBufferIterator;
+import libcore.io.IoUtils;
import libcore.io.Streams;
/**
@@ -108,6 +109,9 @@ public class ZipFile implements Closeable, ZipConstants {
/**
* Constructs a new {@code ZipFile} allowing read access to the contents of the given file.
+ *
+ * <p>UTF-8 is used to decode all comments and entry names in the file.
+ *
* @throws ZipException if a zip error occurs.
* @throws IOException if an {@code IOException} occurs.
*/
@@ -117,6 +121,9 @@ public class ZipFile implements Closeable, ZipConstants {
/**
* Constructs a new {@code ZipFile} allowing read access to the contents of the given file.
+ *
+ * <p>UTF-8 is used to decode all comments and entry names in the file.
+ *
* @throws IOException if an IOException occurs.
*/
public ZipFile(String name) throws IOException {
@@ -125,9 +132,11 @@ public class ZipFile implements Closeable, ZipConstants {
/**
* Constructs a new {@code ZipFile} allowing access to the given file.
- * The {@code mode} must be either {@code OPEN_READ} or {@code OPEN_READ|OPEN_DELETE}.
*
- * <p>If the {@code OPEN_DELETE} flag is supplied, the file will be deleted at or before the
+ * <p>UTF-8 is used to decode all comments and entry names in the file.
+ *
+ * <p>The {@code mode} must be either {@code OPEN_READ} or {@code OPEN_READ|OPEN_DELETE}.
+ * If the {@code OPEN_DELETE} flag is supplied, the file will be deleted at or before the
* time that the {@code ZipFile} is closed (the contents will remain accessible until
* this {@code ZipFile} is closed); it also calls {@code File.deleteOnExit}.
*
@@ -148,7 +157,19 @@ public class ZipFile implements Closeable, ZipConstants {
raf = new RandomAccessFile(filename, "r");
- readCentralDir();
+ // Make sure to close the RandomAccessFile if reading the central directory fails.
+ boolean mustCloseFile = true;
+ try {
+ readCentralDir();
+
+ // Read succeeded so do not close the underlying RandomAccessFile.
+ mustCloseFile = false;
+ } finally {
+ if (mustCloseFile) {
+ IoUtils.closeQuietly(raf);
+ }
+ }
+
guard.open("close");
}
@@ -357,6 +378,9 @@ public class ZipFile implements Closeable, ZipConstants {
raf.seek(0);
final int headerMagic = Integer.reverseBytes(raf.readInt());
+ if (headerMagic == ENDSIG) {
+ throw new ZipException("Empty zip archive not supported");
+ }
if (headerMagic != LOCSIG) {
throw new ZipException("Not a zip archive");
}
@@ -411,7 +435,7 @@ public class ZipFile implements Closeable, ZipConstants {
BufferedInputStream bufferedStream = new BufferedInputStream(rafStream, 4096);
byte[] hdrBuf = new byte[CENHDR]; // Reuse the same buffer for each entry.
for (int i = 0; i < numEntries; ++i) {
- ZipEntry newEntry = new ZipEntry(hdrBuf, bufferedStream);
+ ZipEntry newEntry = new ZipEntry(hdrBuf, bufferedStream, StandardCharsets.UTF_8);
if (newEntry.localHeaderRelOffset >= centralDirOffset) {
throw new ZipException("Local file header offset is after central directory");
}
@@ -434,16 +458,23 @@ public class ZipFile implements Closeable, ZipConstants {
* collisions.)
*
* <p>We could support mark/reset, but we don't currently need them.
+ *
+ * @hide
*/
- static class RAFStream extends InputStream {
+ public static class RAFStream extends InputStream {
private final RandomAccessFile sharedRaf;
private long endOffset;
private long offset;
- public RAFStream(RandomAccessFile raf, long initialOffset) throws IOException {
+
+ public RAFStream(RandomAccessFile raf, long initialOffset, long endOffset) {
sharedRaf = raf;
offset = initialOffset;
- endOffset = raf.length();
+ this.endOffset = endOffset;
+ }
+
+ public RAFStream(RandomAccessFile raf, long initialOffset) throws IOException {
+ this(raf, initialOffset, raf.length());
}
@Override public int available() throws IOException {
@@ -491,7 +522,8 @@ public class ZipFile implements Closeable, ZipConstants {
}
}
- static class ZipInflaterInputStream extends InflaterInputStream {
+ /** @hide */
+ public static class ZipInflaterInputStream extends InflaterInputStream {
private final ZipEntry entry;
private long bytesRead = 0;
diff --git a/luni/src/main/java/java/util/zip/ZipInputStream.java b/luni/src/main/java/java/util/zip/ZipInputStream.java
index 9c18f49..4c0034e 100644
--- a/luni/src/main/java/java/util/zip/ZipInputStream.java
+++ b/luni/src/main/java/java/util/zip/ZipInputStream.java
@@ -22,8 +22,7 @@ import java.io.InputStream;
import java.io.PushbackInputStream;
import java.nio.ByteOrder;
import java.nio.charset.ModifiedUtf8;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import libcore.io.Memory;
import libcore.io.Streams;
@@ -86,12 +85,14 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants
private final CRC32 crc = new CRC32();
- private byte[] nameBuf = new byte[256];
+ private byte[] stringBytesBuf = new byte[256];
- private char[] charBuf = new char[256];
+ private char[] stringCharBuf = new char[256];
/**
* Constructs a new {@code ZipInputStream} to read zip entries from the given input stream.
+ *
+ * <p>UTF-8 is used to decode all strings in the file.
*/
public ZipInputStream(InputStream stream) {
super(new PushbackInputStream(stream, BUF_SIZE), new Inflater(true));
@@ -125,12 +126,6 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants
if (currentEntry == null) {
return;
}
- if (currentEntry instanceof java.util.jar.JarEntry) {
- Attributes temp = ((JarEntry) currentEntry).getAttributes();
- if (temp != null && temp.containsKey("hidden")) {
- return;
- }
- }
/*
* The following code is careful to leave the ZipInputStream in a
@@ -257,14 +252,8 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants
}
int extraLength = peekShort(LOCEXT - LOCVER);
- if (nameLength > nameBuf.length) {
- nameBuf = new byte[nameLength];
- // The bytes are modified UTF-8, so the number of chars will always be less than or
- // equal to the number of bytes. It's fine if this buffer is too long.
- charBuf = new char[nameLength];
- }
- Streams.readFully(in, nameBuf, 0, nameLength);
- currentEntry = createZipEntry(ModifiedUtf8.decode(nameBuf, charBuf, 0, nameLength));
+ String name = readString(nameLength);
+ currentEntry = createZipEntry(name);
currentEntry.time = ceLastModifiedTime;
currentEntry.modDate = ceLastModifiedDate;
currentEntry.setMethod(ceCompressionMethod);
@@ -281,6 +270,22 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants
return currentEntry;
}
+ /**
+ * Reads bytes from the current stream position returning the string representation.
+ */
+ private String readString(int byteLength) throws IOException {
+ if (byteLength > stringBytesBuf.length) {
+ stringBytesBuf = new byte[byteLength];
+ }
+ Streams.readFully(in, stringBytesBuf, 0, byteLength);
+ // The number of chars will always be less than or equal to the number of bytes. It's
+ // fine if this buffer is too long.
+ if (byteLength > stringCharBuf.length) {
+ stringCharBuf = new char[byteLength];
+ }
+ return ModifiedUtf8.decode(stringBytesBuf, stringCharBuf, 0, byteLength);
+ }
+
private int peekShort(int offset) {
return Memory.peekShort(hdrBuf, offset, ByteOrder.LITTLE_ENDIAN) & 0xffff;
}
diff --git a/luni/src/main/java/java/util/zip/ZipOutputStream.java b/luni/src/main/java/java/util/zip/ZipOutputStream.java
index 04de03f..8278355 100644
--- a/luni/src/main/java/java/util/zip/ZipOutputStream.java
+++ b/luni/src/main/java/java/util/zip/ZipOutputStream.java
@@ -85,13 +85,19 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
private final CRC32 crc = new CRC32();
- private int offset = 0, curOffset = 0, nameLength;
+ private int offset = 0, curOffset = 0;
+ /** The charset-encoded name for the current entry. */
private byte[] nameBytes;
+ /** The charset-encoded comment for the current entry. */
+ private byte[] entryCommentBytes;
+
/**
- * Constructs a new {@code ZipOutputStream} that writes a zip file
- * to the given {@code OutputStream}.
+ * Constructs a new {@code ZipOutputStream} that writes a zip file to the given
+ * {@code OutputStream}.
+ *
+ * <p>UTF-8 will be used to encode the file comment, entry names and comments.
*/
public ZipOutputStream(OutputStream os) {
super(os, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
@@ -153,8 +159,8 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
// Update the CentralDirectory
// http://www.pkware.com/documents/casestudies/APPNOTE.TXT
int flags = currentEntry.getMethod() == STORED ? 0 : ZipFile.GPBF_DATA_DESCRIPTOR_FLAG;
- // Since gingerbread, we always set the UTF-8 flag on individual files.
- // Some tools insist that the central directory also have the UTF-8 flag.
+ // Since gingerbread, we always set the UTF-8 flag on individual files if appropriate.
+ // Some tools insist that the central directory have the UTF-8 flag.
// http://code.google.com/p/android/issues/detail?id=20214
flags |= ZipFile.GPBF_UTF8_FLAG;
writeLong(cDir, CENSIG);
@@ -172,19 +178,14 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
curOffset += writeLong(cDir, crc.tbytes);
writeLong(cDir, crc.tbytes);
}
- curOffset += writeShort(cDir, nameLength);
+ curOffset += writeShort(cDir, nameBytes.length);
if (currentEntry.extra != null) {
curOffset += writeShort(cDir, currentEntry.extra.length);
} else {
writeShort(cDir, 0);
}
- String comment = currentEntry.getComment();
- byte[] commentBytes = EmptyArray.BYTE;
- if (comment != null) {
- commentBytes = comment.getBytes(StandardCharsets.UTF_8);
- }
- writeShort(cDir, commentBytes.length); // Comment length.
+ writeShort(cDir, entryCommentBytes.length); // Comment length.
writeShort(cDir, 0); // Disk Start
writeShort(cDir, 0); // Internal File Attributes
writeLong(cDir, 0); // External File Attributes
@@ -195,8 +196,9 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
cDir.write(currentEntry.extra);
}
offset += curOffset;
- if (commentBytes.length > 0) {
- cDir.write(commentBytes);
+ if (entryCommentBytes.length > 0) {
+ cDir.write(entryCommentBytes);
+ entryCommentBytes = EmptyArray.BYTE;
}
currentEntry = null;
crc.reset();
@@ -295,9 +297,13 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
throw new ZipException("Too many entries for the zip file format's 16-bit entry count");
}
nameBytes = ze.name.getBytes(StandardCharsets.UTF_8);
- nameLength = nameBytes.length;
- if (nameLength > 0xffff) {
- throw new IllegalArgumentException("Name too long: " + nameLength + " UTF-8 bytes");
+ checkSizeIsWithinShort("Name", nameBytes);
+ entryCommentBytes = EmptyArray.BYTE;
+ if (ze.comment != null) {
+ entryCommentBytes = ze.comment.getBytes(StandardCharsets.UTF_8);
+ // The comment is not written out until the entry is finished, but it is validated here
+ // to fail-fast.
+ checkSizeIsWithinShort("Comment", entryCommentBytes);
}
def.setLevel(compressionLevel);
@@ -310,7 +316,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
// http://www.pkware.com/documents/casestudies/APPNOTE.TXT
int flags = (method == STORED) ? 0 : ZipFile.GPBF_DATA_DESCRIPTOR_FLAG;
// Java always outputs UTF-8 filenames. (Before Java 7, the RI didn't set this flag and used
- // modified UTF-8. From Java 7, it sets this flag and uses normal UTF-8.)
+ // modified UTF-8. From Java 7, when using UTF_8 it sets this flag and uses normal UTF-8.)
flags |= ZipFile.GPBF_UTF8_FLAG;
writeLong(out, LOCSIG); // Entry header
writeShort(out, ZIP_VERSION_2_0); // Minimum version needed to extract.
@@ -331,7 +337,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
writeLong(out, 0);
writeLong(out, 0);
}
- writeShort(out, nameLength);
+ writeShort(out, nameBytes.length);
if (currentEntry.extra != null) {
writeShort(out, currentEntry.extra.length);
} else {
@@ -345,18 +351,16 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
/**
* Sets the comment associated with the file being written. See {@link ZipFile#getComment}.
- * @throws IllegalArgumentException if the comment is >= 64 Ki UTF-8 bytes.
+ * @throws IllegalArgumentException if the comment is >= 64 Ki encoded bytes.
*/
public void setComment(String comment) {
if (comment == null) {
- this.commentBytes = null;
+ this.commentBytes = EmptyArray.BYTE;
return;
}
byte[] newCommentBytes = comment.getBytes(StandardCharsets.UTF_8);
- if (newCommentBytes.length > 0xffff) {
- throw new IllegalArgumentException("Comment too long: " + newCommentBytes.length + " bytes");
- }
+ checkSizeIsWithinShort("Comment", newCommentBytes);
this.commentBytes = newCommentBytes;
}
@@ -400,7 +404,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
/**
* Writes data for the current entry to the underlying stream.
*
- * @exception IOException
+ * @throws IOException
* If an error occurs writing to the stream
*/
@Override
@@ -423,4 +427,11 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
throw new IOException("Stream is closed");
}
}
+
+ private void checkSizeIsWithinShort(String property, byte[] bytes) {
+ if (bytes.length > 0xffff) {
+ throw new IllegalArgumentException(property + " too long in UTF-8:" + bytes.length +
+ " bytes");
+ }
+ }
}
diff --git a/luni/src/main/java/javax/crypto/Cipher.java b/luni/src/main/java/javax/crypto/Cipher.java
index ba40b86..2e3b341 100644
--- a/luni/src/main/java/javax/crypto/Cipher.java
+++ b/luni/src/main/java/javax/crypto/Cipher.java
@@ -26,11 +26,15 @@ import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
+import java.security.Provider.Service;
+import java.security.ProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Locale;
import java.util.Set;
import org.apache.harmony.crypto.internal.NullCipherSpi;
import org.apache.harmony.security.fortress.Engine;
@@ -54,7 +58,7 @@ import org.apache.harmony.security.fortress.Engine;
* <ul>
* {@code Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");}
* </ul>
- * When a block cipher is requested in in stream cipher mode, the number of bits
+ * When a block cipher is requested in stream cipher mode, the number of bits
* to be processed at a time can be optionally specified by appending it to the
* mode name. e.g. <i>"AES/CFB8/NoPadding"</i>. If no number is specified, a
* provider specific default value is used.
@@ -98,6 +102,11 @@ public class Cipher {
private int mode;
+ /** Items that need to be set on the Cipher instance. */
+ private enum NeedToSet {
+ NONE, MODE, PADDING, BOTH,
+ };
+
/**
* The service name.
*/
@@ -108,20 +117,46 @@ public class Cipher {
*/
private static final Engine ENGINE = new Engine(SERVICE);
+ /** The attribute used for supported paddings. */
+ private static final String ATTRIBUTE_PADDINGS = "SupportedPaddings";
+
+ /** The attribute used for supported modes. */
+ private static final String ATTRIBUTE_MODES = "SupportedModes";
+
/**
* The provider.
*/
private Provider provider;
/**
+ * The provider specified when instance created.
+ */
+ private final Provider specifiedProvider;
+
+ /**
* The SPI implementation.
*/
private CipherSpi spiImpl;
/**
+ * The SPI implementation.
+ */
+ private final CipherSpi specifiedSpi;
+
+ /**
* The transformation.
*/
- private String transformation;
+ private final String transformation;
+
+ /**
+ * The transformation split into parts.
+ */
+ private final String[] transformParts;
+
+ /**
+ * Lock held while the SPI is initializing.
+ */
+ private final Object initLock = new Object();
private static SecureRandom secureRandom;
@@ -138,19 +173,27 @@ public class Cipher {
* if either cipherSpi is {@code null} or provider is {@code
* null} and {@code cipherSpi} is a {@code NullCipherSpi}.
*/
- protected Cipher(CipherSpi cipherSpi, Provider provider,
- String transformation) {
+ protected Cipher(CipherSpi cipherSpi, Provider provider, String transformation) {
if (cipherSpi == null) {
throw new NullPointerException("cipherSpi == null");
}
if (!(cipherSpi instanceof NullCipherSpi) && provider == null) {
throw new NullPointerException("provider == null");
}
- this.provider = provider;
+ this.specifiedProvider = provider;
+ this.specifiedSpi = cipherSpi;
this.transformation = transformation;
- this.spiImpl = cipherSpi;
+ this.transformParts = null;
}
+ private Cipher(String transformation, String[] transformParts, Provider provider) {
+ this.transformation = transformation;
+ this.transformParts = transformParts;
+ this.specifiedProvider = provider;
+ this.specifiedSpi = null;
+ }
+
+
/**
* Creates a new Cipher for the specified transformation. The installed
* providers are searched in order for an implementation of the specified
@@ -211,7 +254,8 @@ public class Cipher {
}
/**
- * Creates a new cipher for the specified transformation.
+ * Creates a new cipher for the specified transformation. The
+ * {@code provider} supplied does not have to be registered.
*
* @param transformation
* the name of the transformation to create a cipher for.
@@ -234,8 +278,7 @@ public class Cipher {
if (provider == null) {
throw new IllegalArgumentException("provider == null");
}
- Cipher c = getCipher(transformation, provider);
- return c;
+ return getCipher(transformation, provider);
}
private static NoSuchAlgorithmException invalidTransformation(String transformation)
@@ -244,91 +287,31 @@ public class Cipher {
}
/**
- * Find appropriate Cipher according the specification rules
- *
- * @param transformation
- * @param provider
- * @return
- * @throws NoSuchAlgorithmException
- * @throws NoSuchPaddingException
+ * Create a Cipher instance but don't choose a CipherSpi until we have more
+ * information.
*/
- private static synchronized Cipher getCipher(String transformation, Provider provider)
+ private static Cipher getCipher(String transformation, Provider provider)
throws NoSuchAlgorithmException, NoSuchPaddingException {
-
if (transformation == null || transformation.isEmpty()) {
throw invalidTransformation(transformation);
}
- String[] transf = checkTransformation(transformation);
-
- boolean needSetPadding = false;
- boolean needSetMode = false;
- Object engineSpi = null;
- Provider engineProvider = provider;
- if (transf[1] == null && transf[2] == null) { // "algorithm"
+ String[] transformParts = checkTransformation(transformation);
+ if (tryCombinations(null, provider, transformParts) == null) {
if (provider == null) {
- Engine.SpiAndProvider sap = ENGINE.getInstance(transf[0], null);
- engineSpi = sap.spi;
- engineProvider = sap.provider;
+ throw new NoSuchAlgorithmException("No provider found for " + transformation);
} else {
- engineSpi = ENGINE.getInstance(transf[0], provider, null);
+ throw new NoSuchAlgorithmException("Provider " + provider.getName()
+ + " does not provide " + transformation);
}
- } else {
- String[] searchOrder = {
- transf[0] + "/" + transf[1] + "/" + transf[2], // "algorithm/mode/padding"
- transf[0] + "/" + transf[1], // "algorithm/mode"
- transf[0] + "//" + transf[2], // "algorithm//padding"
- transf[0] // "algorithm"
- };
- int i;
- for (i = 0; i < searchOrder.length; i++) {
- try {
- if (provider == null) {
- Engine.SpiAndProvider sap = ENGINE.getInstance(searchOrder[i], null);
- engineSpi = sap.spi;
- engineProvider = sap.provider;
- } else {
- engineSpi = ENGINE.getInstance(searchOrder[i], provider, null);
- }
- break;
- } catch (NoSuchAlgorithmException e) {
- if (i == searchOrder.length-1) {
- throw new NoSuchAlgorithmException(transformation, e);
- }
- }
- }
- switch (i) {
- case 1: // "algorithm/mode"
- needSetPadding = true;
- break;
- case 2: // "algorithm//padding"
- needSetMode = true;
- break;
- case 3: // "algorithm"
- needSetPadding = true;
- needSetMode = true;
- }
- }
- if (engineSpi == null || engineProvider == null) {
- throw new NoSuchAlgorithmException(transformation);
}
- if (!(engineSpi instanceof CipherSpi)) {
- throw new NoSuchAlgorithmException(engineSpi.getClass().getName());
- }
- CipherSpi cspi = (CipherSpi) engineSpi;
- Cipher c = new Cipher(cspi, engineProvider, transformation);
- if (needSetMode) {
- c.spiImpl.engineSetMode(transf[1]);
- }
- if (needSetPadding) {
- c.spiImpl.engineSetPadding(transf[2]);
- }
- return c;
+ return new Cipher(transformation, transformParts, provider);
}
- private static String[] checkTransformation(String transformation) throws NoSuchAlgorithmException {
+ private static String[] checkTransformation(String transformation)
+ throws NoSuchAlgorithmException {
// ignore an extra prefix / characters such as in
- // "/DES/CBC/PKCS5Paddin" http://b/3387688
+ // "/DES/CBC/PKCS5Padding" http://b/3387688
if (transformation.startsWith("/")) {
transformation = transformation.substring(1);
}
@@ -356,11 +339,163 @@ public class Cipher {
}
/**
+ * Makes sure a CipherSpi that matches this type is selected.
+ */
+ private CipherSpi getSpi(Key key) {
+ if (specifiedSpi != null) {
+ return specifiedSpi;
+ }
+
+ synchronized (initLock) {
+ if (spiImpl != null && key == null) {
+ return spiImpl;
+ }
+
+ final Engine.SpiAndProvider sap = tryCombinations(key, specifiedProvider,
+ transformParts);
+ if (sap == null) {
+ throw new ProviderException("No provider for " + transformation);
+ }
+
+ spiImpl = (CipherSpi) sap.spi;
+ provider = sap.provider;
+
+ return spiImpl;
+ }
+ }
+
+ /**
+ * Convenience call when the Key is not available.
+ */
+ private CipherSpi getSpi() {
+ return getSpi(null);
+ }
+
+ /**
+ * Try all combinations of mode strings:
+ *
+ * <pre>
+ * [cipher]/[mode]/[padding]
+ * [cipher]/[mode]
+ * [cipher]//[padding]
+ * [cipher]
+ * </pre>
+ */
+ private static Engine.SpiAndProvider tryCombinations(Key key, Provider provider,
+ String[] transformParts) {
+ Engine.SpiAndProvider sap = null;
+
+ if (transformParts[1] != null && transformParts[2] != null) {
+ sap = tryTransform(key, provider, transformParts[0] + "/" + transformParts[1] + "/"
+ + transformParts[2], transformParts, NeedToSet.NONE);
+ if (sap != null) {
+ return sap;
+ }
+ }
+
+ if (transformParts[1] != null) {
+ sap = tryTransform(key, provider, transformParts[0] + "/" + transformParts[1],
+ transformParts, NeedToSet.PADDING);
+ if (sap != null) {
+ return sap;
+ }
+ }
+
+ if (transformParts[2] != null) {
+ sap = tryTransform(key, provider, transformParts[0] + "//" + transformParts[2],
+ transformParts, NeedToSet.MODE);
+ if (sap != null) {
+ return sap;
+ }
+ }
+
+ return tryTransform(key, provider, transformParts[0], transformParts, NeedToSet.BOTH);
+ }
+
+ private static Engine.SpiAndProvider tryTransform(Key key, Provider provider, String transform,
+ String[] transformParts, NeedToSet type) {
+ if (provider != null) {
+ Provider.Service service = provider.getService(SERVICE, transform);
+ if (service == null) {
+ return null;
+ }
+ return tryTransformWithProvider(key, transformParts, type, service);
+ }
+ ArrayList<Provider.Service> services = ENGINE.getServices(transform);
+ if (services == null) {
+ return null;
+ }
+ for (Provider.Service service : services) {
+ Engine.SpiAndProvider sap = tryTransformWithProvider(key, transformParts, type, service);
+ if (sap != null) {
+ return sap;
+ }
+ }
+ return null;
+ }
+
+ private static Engine.SpiAndProvider tryTransformWithProvider(Key key, String[] transformParts,
+ NeedToSet type, Provider.Service service) {
+ try {
+ if (key != null && !service.supportsParameter(key)) {
+ return null;
+ }
+
+ /*
+ * Check to see if the Cipher even supports the attributes before
+ * trying to instantiate it.
+ */
+ if (!matchAttribute(service, ATTRIBUTE_MODES, transformParts[1])
+ || !matchAttribute(service, ATTRIBUTE_PADDINGS, transformParts[2])) {
+ return null;
+ }
+
+ Engine.SpiAndProvider sap = ENGINE.getInstance(service, null);
+ if (sap.spi == null || sap.provider == null) {
+ return null;
+ }
+ if (!(sap.spi instanceof CipherSpi)) {
+ return null;
+ }
+ CipherSpi spi = (CipherSpi) sap.spi;
+ if (((type == NeedToSet.MODE) || (type == NeedToSet.BOTH))
+ && (transformParts[1] != null)) {
+ spi.engineSetMode(transformParts[1]);
+ }
+ if (((type == NeedToSet.PADDING) || (type == NeedToSet.BOTH))
+ && (transformParts[2] != null)) {
+ spi.engineSetPadding(transformParts[2]);
+ }
+ return sap;
+ } catch (NoSuchAlgorithmException ignored) {
+ } catch (NoSuchPaddingException ignored) {
+ }
+ return null;
+ }
+
+ /**
+ * If the attribute listed exists, check that it matches the regular
+ * expression.
+ */
+ private static boolean matchAttribute(Service service, String attr, String value) {
+ if (value == null) {
+ return true;
+ }
+ final String pattern = service.getAttribute(attr);
+ if (pattern == null) {
+ return true;
+ }
+ final String valueUc = value.toUpperCase(Locale.US);
+ return valueUc.matches(pattern.toUpperCase(Locale.US));
+ }
+
+ /**
* Returns the provider of this cipher instance.
*
* @return the provider of this cipher instance.
*/
public final Provider getProvider() {
+ getSpi();
return provider;
}
@@ -382,7 +517,7 @@ public class Cipher {
* @return this ciphers block size.
*/
public final int getBlockSize() {
- return spiImpl.engineGetBlockSize();
+ return getSpi().engineGetBlockSize();
}
/**
@@ -399,7 +534,7 @@ public class Cipher {
if (mode == 0) {
throw new IllegalStateException("Cipher has not yet been initialized");
}
- return spiImpl.engineGetOutputSize(inputLen);
+ return getSpi().engineGetOutputSize(inputLen);
}
/**
@@ -408,7 +543,7 @@ public class Cipher {
* @return the <i>initialization vector</i> for this cipher instance.
*/
public final byte[] getIV() {
- return spiImpl.engineGetIV();
+ return getSpi().engineGetIV();
}
/**
@@ -423,7 +558,7 @@ public class Cipher {
* parameters.
*/
public final AlgorithmParameters getParameters() {
- return spiImpl.engineGetParameters();
+ return getSpi().engineGetParameters();
}
/**
@@ -442,6 +577,13 @@ public class Cipher {
}
+ private void checkMode(int mode) {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE && mode != UNWRAP_MODE
+ && mode != WRAP_MODE) {
+ throw new InvalidParameterException("Invalid mode: " + mode);
+ }
+ }
+
/**
* Initializes this cipher instance with the specified key.
* <p>
@@ -516,17 +658,10 @@ public class Cipher {
// FIXME InvalidKeyException
// if keysize exceeds the maximum allowable keysize
// (jurisdiction policy files)
- spiImpl.engineInit(opmode, key, random);
+ getSpi(key).engineInit(opmode, key, random);
mode = opmode;
}
- private void checkMode(int mode) {
- if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE
- && mode != UNWRAP_MODE && mode != WRAP_MODE) {
- throw new InvalidParameterException("Invalid mode: " + mode);
- }
- }
-
/**
* Initializes this cipher instance with the specified key and algorithm
* parameters.
@@ -613,7 +748,7 @@ public class Cipher {
// FIXME InvalidAlgorithmParameterException
// cryptographic strength exceed the legal limits
// (jurisdiction policy files)
- spiImpl.engineInit(opmode, key, params, random);
+ getSpi(key).engineInit(opmode, key, params, random);
mode = opmode;
}
@@ -704,7 +839,7 @@ public class Cipher {
// FIXME InvalidAlgorithmParameterException
// cryptographic strength exceed the legal limits
// (jurisdiction policy files)
- spiImpl.engineInit(opmode, key, params, random);
+ getSpi(key).engineInit(opmode, key, params, random);
mode = opmode;
}
@@ -828,7 +963,8 @@ public class Cipher {
// FIXME InvalidKeyException
// if keysize exceeds the maximum allowable keysize
// (jurisdiction policy files)
- spiImpl.engineInit(opmode, certificate.getPublicKey(), random);
+ final Key key = certificate.getPublicKey();
+ getSpi(key).engineInit(opmode, key, random);
mode = opmode;
}
@@ -856,7 +992,7 @@ public class Cipher {
if (input.length == 0) {
return null;
}
- return spiImpl.engineUpdate(input, 0, input.length);
+ return getSpi().engineUpdate(input, 0, input.length);
}
/**
@@ -890,7 +1026,7 @@ public class Cipher {
if (input.length == 0) {
return null;
}
- return spiImpl.engineUpdate(input, inputOffset, inputLen);
+ return getSpi().engineUpdate(input, inputOffset, inputLen);
}
private static void checkInputOffsetAndCount(int inputArrayLength,
@@ -986,7 +1122,7 @@ public class Cipher {
if (input.length == 0) {
return 0;
}
- return spiImpl.engineUpdate(input, inputOffset, inputLen, output,
+ return getSpi().engineUpdate(input, inputOffset, inputLen, output,
outputOffset);
}
@@ -1022,7 +1158,7 @@ public class Cipher {
if (input == output) {
throw new IllegalArgumentException("input == output");
}
- return spiImpl.engineUpdate(input, output);
+ return getSpi().engineUpdate(input, output);
}
/**
@@ -1053,7 +1189,7 @@ public class Cipher {
if (input.length == 0) {
return;
}
- spiImpl.engineUpdateAAD(input, 0, input.length);
+ getSpi().engineUpdateAAD(input, 0, input.length);
}
/**
@@ -1089,7 +1225,7 @@ public class Cipher {
if (input.length == 0) {
return;
}
- spiImpl.engineUpdateAAD(input, inputOffset, inputLen);
+ getSpi().engineUpdateAAD(input, inputOffset, inputLen);
}
/**
@@ -1115,7 +1251,7 @@ public class Cipher {
if (input == null) {
throw new IllegalArgumentException("input == null");
}
- spiImpl.engineUpdateAAD(input);
+ getSpi().engineUpdateAAD(input);
}
/**
@@ -1139,7 +1275,7 @@ public class Cipher {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
- return spiImpl.engineDoFinal(null, 0, 0);
+ return getSpi().engineDoFinal(null, 0, 0);
}
/**
@@ -1175,7 +1311,7 @@ public class Cipher {
if (outputOffset < 0) {
throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset);
}
- return spiImpl.engineDoFinal(null, 0, 0, output, outputOffset);
+ return getSpi().engineDoFinal(null, 0, 0, output, outputOffset);
}
/**
@@ -1201,7 +1337,7 @@ public class Cipher {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
- return spiImpl.engineDoFinal(input, 0, input.length);
+ return getSpi().engineDoFinal(input, 0, input.length);
}
/**
@@ -1236,7 +1372,7 @@ public class Cipher {
throw new IllegalStateException();
}
checkInputOffsetAndCount(input.length, inputOffset, inputLen);
- return spiImpl.engineDoFinal(input, inputOffset, inputLen);
+ return getSpi().engineDoFinal(input, inputOffset, inputLen);
}
/**
@@ -1314,7 +1450,7 @@ public class Cipher {
throw new IllegalStateException();
}
checkInputOffsetAndCount(input.length, inputOffset, inputLen);
- return spiImpl.engineDoFinal(input, inputOffset, inputLen, output,
+ return getSpi().engineDoFinal(input, inputOffset, inputLen, output,
outputOffset);
}
@@ -1354,7 +1490,7 @@ public class Cipher {
if (input == output) {
throw new IllegalArgumentException("input == output");
}
- return spiImpl.engineDoFinal(input, output);
+ return getSpi().engineDoFinal(input, output);
}
/**
@@ -1376,7 +1512,7 @@ public class Cipher {
if (mode != WRAP_MODE) {
throw new IllegalStateException();
}
- return spiImpl.engineWrap(key);
+ return getSpi().engineWrap(key);
}
/**
@@ -1406,7 +1542,7 @@ public class Cipher {
if (mode != UNWRAP_MODE) {
throw new IllegalStateException();
}
- return spiImpl.engineUnwrap(wrappedKey, wrappedKeyAlgorithm,
+ return getSpi().engineUnwrap(wrappedKey, wrappedKeyAlgorithm,
wrappedKeyType);
}
diff --git a/luni/src/main/java/javax/crypto/CipherInputStream.java b/luni/src/main/java/javax/crypto/CipherInputStream.java
index f2f59c1..3061655 100644
--- a/luni/src/main/java/javax/crypto/CipherInputStream.java
+++ b/luni/src/main/java/javax/crypto/CipherInputStream.java
@@ -17,6 +17,7 @@
package javax.crypto;
+import java.io.BufferedInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -34,11 +35,8 @@ import libcore.io.Streams;
* CipherInputStream} tries to read the data an decrypt them before returning.
*/
public class CipherInputStream extends FilterInputStream {
-
- private static final int I_BUFFER_SIZE = 20;
-
private final Cipher cipher;
- private final byte[] inputBuffer = new byte[I_BUFFER_SIZE];
+ private final byte[] inputBuffer;
private byte[] outputBuffer;
private int outputIndex; // index of the first byte to return from outputBuffer
private int outputLength; // count of the bytes to return from outputBuffer
@@ -60,6 +58,11 @@ public class CipherInputStream extends FilterInputStream {
public CipherInputStream(InputStream is, Cipher c) {
super(is);
this.cipher = c;
+ int blockSize = Math.max(c.getBlockSize(), 1);
+ int bufferSize = Math.max(blockSize,
+ BufferedInputStream.DEFAULT_BUFFER_SIZE / blockSize * blockSize);
+ inputBuffer = new byte[bufferSize];
+ outputBuffer = new byte[bufferSize + ((blockSize > 1) ? 2 * blockSize : 0)];
}
/**
@@ -76,19 +79,13 @@ public class CipherInputStream extends FilterInputStream {
}
/**
- * Reads the next byte from this cipher input stream.
- *
- * @return the next byte, or {@code -1} if the end of the stream is reached.
- * @throws IOException
- * if an error occurs.
+ * Attempts to fill the input buffer and process some data through the
+ * cipher. Returns {@code true} if output from the cipher is available to
+ * use.
*/
- @Override
- public int read() throws IOException {
+ private boolean fillBuffer() throws IOException {
if (finished) {
- return (outputIndex == outputLength) ? -1 : outputBuffer[outputIndex++] & 0xFF;
- }
- if (outputIndex < outputLength) {
- return outputBuffer[outputIndex++] & 0xFF;
+ return false;
}
outputIndex = 0;
outputLength = 0;
@@ -107,7 +104,7 @@ public class CipherInputStream extends FilterInputStream {
throw new IOException("Error while finalizing cipher", e);
}
finished = true;
- break;
+ return outputLength != 0;
}
try {
outputLength = cipher.update(inputBuffer, 0, byteCount, outputBuffer, 0);
@@ -115,7 +112,25 @@ public class CipherInputStream extends FilterInputStream {
throw new AssertionError(e); // should not happen since we sized with getOutputSize
}
}
- return read();
+ return true;
+ }
+
+ /**
+ * Reads the next byte from this cipher input stream.
+ *
+ * @return the next byte, or {@code -1} if the end of the stream is reached.
+ * @throws IOException
+ * if an error occurs.
+ */
+ @Override
+ public int read() throws IOException {
+ if (in == null) {
+ throw new NullPointerException("in == null");
+ }
+ if (outputIndex == outputLength && !fillBuffer()) {
+ return -1;
+ }
+ return outputBuffer[outputIndex++] & 0xFF;
}
/**
@@ -137,18 +152,18 @@ public class CipherInputStream extends FilterInputStream {
if (in == null) {
throw new NullPointerException("in == null");
}
-
- int i;
- for (i = 0; i < len; ++i) {
- int b = read();
- if (b == -1) {
- return (i == 0) ? -1 : i;
- }
- if (buf != null) {
- buf[off+i] = (byte) b;
- }
+ if (outputIndex == outputLength && !fillBuffer()) {
+ return -1;
+ }
+ int available = outputLength - outputIndex;
+ if (available < len) {
+ len = available;
+ }
+ if (buf != null) {
+ System.arraycopy(outputBuffer, outputIndex, buf, off, len);
}
- return i;
+ outputIndex += len;
+ return len;
}
@Override
@@ -158,7 +173,7 @@ public class CipherInputStream extends FilterInputStream {
@Override
public int available() throws IOException {
- return 0;
+ return outputLength - outputIndex;
}
/**
diff --git a/luni/src/main/java/javax/crypto/ExemptionMechanism.java b/luni/src/main/java/javax/crypto/ExemptionMechanism.java
index 8745b78..c2d42e6 100644
--- a/luni/src/main/java/javax/crypto/ExemptionMechanism.java
+++ b/luni/src/main/java/javax/crypto/ExemptionMechanism.java
@@ -142,6 +142,7 @@ public class ExemptionMechanism {
/**
* Returns a new {@code ExemptionMechanism} instance that provides the
* specified exemption mechanism algorithm from the specified provider.
+ * The {@code provider} supplied does not have to be registered.
*
* @param algorithm
* the name of the requested exemption mechanism.
diff --git a/luni/src/main/java/javax/crypto/KeyAgreement.java b/luni/src/main/java/javax/crypto/KeyAgreement.java
index 51b4cd1..abcfd0e 100644
--- a/luni/src/main/java/javax/crypto/KeyAgreement.java
+++ b/luni/src/main/java/javax/crypto/KeyAgreement.java
@@ -23,9 +23,11 @@ import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
+import java.security.ProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
import org.apache.harmony.security.fortress.Engine;
/**
@@ -35,22 +37,33 @@ import org.apache.harmony.security.fortress.Engine;
*/
public class KeyAgreement {
+ // The service name.
+ private static final String SERVICE = "KeyAgreement";
+
// Used to access common engine functionality
- private static final Engine ENGINE = new Engine("KeyAgreement");
+ private static final Engine ENGINE = new Engine(SERVICE);
// Store SecureRandom
private static final SecureRandom RANDOM = new SecureRandom();
// Store used provider
- private final Provider provider;
+ private Provider provider;
+
+ // Provider that was requested during creation.
+ private final Provider specifiedProvider;
// Store used spi implementation
- private final KeyAgreementSpi spiImpl;
+ private KeyAgreementSpi spiImpl;
// Store used algorithm name
private final String algorithm;
/**
+ * Lock held while the SPI is initializing.
+ */
+ private final Object initLock = new Object();
+
+ /**
* Creates a new {@code KeyAgreement} instance.
*
* @param keyAgreeSpi
@@ -62,9 +75,9 @@ public class KeyAgreement {
*/
protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider,
String algorithm) {
- this.provider = provider;
- this.algorithm = algorithm;
this.spiImpl = keyAgreeSpi;
+ this.specifiedProvider = provider;
+ this.algorithm = algorithm;
}
/**
@@ -82,6 +95,7 @@ public class KeyAgreement {
* @return the provider for this {@code KeyAgreement} instance.
*/
public final Provider getProvider() {
+ getSpi();
return provider;
}
@@ -96,13 +110,8 @@ public class KeyAgreement {
* @throws NullPointerException
* if the specified algorithm is {@code null}.
*/
- public static final KeyAgreement getInstance(String algorithm)
- throws NoSuchAlgorithmException {
- if (algorithm == null) {
- throw new NullPointerException("algorithm == null");
- }
- Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
- return new KeyAgreement((KeyAgreementSpi) sap.spi, sap.provider, algorithm);
+ public static final KeyAgreement getInstance(String algorithm) throws NoSuchAlgorithmException {
+ return getKeyAgreement(algorithm, null);
}
/**
@@ -124,9 +133,8 @@ public class KeyAgreement {
* @throws IllegalArgumentException
* if the specified provider name is {@code null} or empty.
*/
- public static final KeyAgreement getInstance(String algorithm,
- String provider) throws NoSuchAlgorithmException,
- NoSuchProviderException {
+ public static final KeyAgreement getInstance(String algorithm, String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException {
if (provider == null || provider.isEmpty()) {
throw new IllegalArgumentException("Provider is null or empty");
}
@@ -134,12 +142,13 @@ public class KeyAgreement {
if (impProvider == null) {
throw new NoSuchProviderException(provider);
}
- return getInstance(algorithm, impProvider);
+ return getKeyAgreement(algorithm, impProvider);
}
/**
* Create a new {@code KeyAgreement} for the specified algorithm from the
- * specified provider.
+ * specified provider. The {@code provider} supplied does not have to be
+ * registered.
*
* @param algorithm
* the name of the key agreement algorithm to create.
@@ -155,29 +164,108 @@ public class KeyAgreement {
* @throws NullPointerException
* if the specified algorithm name is {@code null}.
*/
- public static final KeyAgreement getInstance(String algorithm,
- Provider provider) throws NoSuchAlgorithmException {
+ public static final KeyAgreement getInstance(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException {
if (provider == null) {
throw new IllegalArgumentException("provider == null");
}
+ return getKeyAgreement(algorithm, provider);
+ }
+
+ private static KeyAgreement getKeyAgreement(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException {
if (algorithm == null) {
throw new NullPointerException("algorithm == null");
}
- Object spi = ENGINE.getInstance(algorithm, provider, null);
- return new KeyAgreement((KeyAgreementSpi) spi, provider, algorithm);
+
+ if (tryAlgorithm(null, provider, algorithm) == null) {
+ if (provider == null) {
+ throw new NoSuchAlgorithmException("No provider found for " + algorithm);
+ } else {
+ throw new NoSuchAlgorithmException("Provider " + provider.getName()
+ + " does not provide " + algorithm);
+ }
+ }
+ return new KeyAgreement(null, provider, algorithm);
+ }
+
+ private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) {
+ if (provider != null) {
+ Provider.Service service = provider.getService(SERVICE, algorithm);
+ if (service == null) {
+ return null;
+ }
+ return tryAlgorithmWithProvider(key, service);
+ }
+ ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
+ if (services == null) {
+ return null;
+ }
+ for (Provider.Service service : services) {
+ Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service);
+ if (sap != null) {
+ return sap;
+ }
+ }
+ return null;
+ }
+
+ private static Engine.SpiAndProvider tryAlgorithmWithProvider(Key key, Provider.Service service) {
+ try {
+ if (key != null && !service.supportsParameter(key)) {
+ return null;
+ }
+
+ Engine.SpiAndProvider sap = ENGINE.getInstance(service, null);
+ if (sap.spi == null || sap.provider == null) {
+ return null;
+ }
+ if (!(sap.spi instanceof KeyAgreementSpi)) {
+ return null;
+ }
+ return sap;
+ } catch (NoSuchAlgorithmException ignored) {
+ }
+ return null;
+ }
+
+ /**
+ * Makes sure a KeyAgreementSpi that matches this type is selected.
+ */
+ private KeyAgreementSpi getSpi(Key key) {
+ synchronized (initLock) {
+ if (spiImpl != null && key == null) {
+ return spiImpl;
+ }
+
+ final Engine.SpiAndProvider sap = tryAlgorithm(key, specifiedProvider, algorithm);
+ if (sap == null) {
+ throw new ProviderException("No provider for " + getAlgorithm());
+ }
+
+ spiImpl = (KeyAgreementSpi) sap.spi;
+ provider = sap.provider;
+
+ return spiImpl;
+ }
+ }
+
+ /**
+ * Convenience call when the Key is not available.
+ */
+ private KeyAgreementSpi getSpi() {
+ return getSpi(null);
}
/**
* Initializes this {@code KeyAgreement} with the specified key.
*
- * @param key
- * the key to initialize this key agreement.
- * @throws InvalidKeyException
- * if the specified key cannot be used to initialize this key
- * agreement.
+ * @param key the key to initialize this key agreement.
+ * @throws InvalidKeyException if the specified key cannot be used to
+ * initialize this key agreement.
*/
public final void init(Key key) throws InvalidKeyException {
- spiImpl.engineInit(key, RANDOM);//new SecureRandom());
+ getSpi(key).engineInit(key, RANDOM);//new SecureRandom());
}
/**
@@ -194,7 +282,7 @@ public class KeyAgreement {
*/
public final void init(Key key, SecureRandom random)
throws InvalidKeyException {
- spiImpl.engineInit(key, random);
+ getSpi(key).engineInit(key, random);
}
/**
@@ -214,7 +302,7 @@ public class KeyAgreement {
*/
public final void init(Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException {
- spiImpl.engineInit(key, params, RANDOM);//new SecureRandom());
+ getSpi(key).engineInit(key, params, RANDOM);//new SecureRandom());
}
/**
@@ -237,7 +325,7 @@ public class KeyAgreement {
public final void init(Key key, AlgorithmParameterSpec params,
SecureRandom random) throws InvalidKeyException,
InvalidAlgorithmParameterException {
- spiImpl.engineInit(key, params, random);
+ getSpi(key).engineInit(key, params, random);
}
/**
@@ -259,7 +347,7 @@ public class KeyAgreement {
*/
public final Key doPhase(Key key, boolean lastPhase)
throws InvalidKeyException, IllegalStateException {
- return spiImpl.engineDoPhase(key, lastPhase);
+ return getSpi().engineDoPhase(key, lastPhase);
}
/**
@@ -270,7 +358,7 @@ public class KeyAgreement {
* if this key agreement is not complete.
*/
public final byte[] generateSecret() throws IllegalStateException {
- return spiImpl.engineGenerateSecret();
+ return getSpi().engineGenerateSecret();
}
/**
@@ -289,7 +377,7 @@ public class KeyAgreement {
*/
public final int generateSecret(byte[] sharedSecret, int offset)
throws IllegalStateException, ShortBufferException {
- return spiImpl.engineGenerateSecret(sharedSecret, offset);
+ return getSpi().engineGenerateSecret(sharedSecret, offset);
}
/**
@@ -311,7 +399,7 @@ public class KeyAgreement {
public final SecretKey generateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,
InvalidKeyException {
- return spiImpl.engineGenerateSecret(algorithm);
+ return getSpi().engineGenerateSecret(algorithm);
}
}
diff --git a/luni/src/main/java/javax/crypto/KeyGenerator.java b/luni/src/main/java/javax/crypto/KeyGenerator.java
index 606998a..fc409da 100644
--- a/luni/src/main/java/javax/crypto/KeyGenerator.java
+++ b/luni/src/main/java/javax/crypto/KeyGenerator.java
@@ -137,7 +137,8 @@ public class KeyGenerator {
/**
* Creates a new {@code KeyGenerator} instance that provides the specified
- * key algorithm from the specified provider.
+ * key algorithm from the specified provider. The {@code provider}
+ * supplied does not have to be registered.
*
* @param algorithm
* the name of the requested key algorithm.
diff --git a/luni/src/main/java/javax/crypto/Mac.java b/luni/src/main/java/javax/crypto/Mac.java
index c208456..5a73dc5 100644
--- a/luni/src/main/java/javax/crypto/Mac.java
+++ b/luni/src/main/java/javax/crypto/Mac.java
@@ -24,8 +24,10 @@ import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
+import java.security.ProviderException;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
import org.apache.harmony.security.fortress.Engine;
@@ -35,18 +37,29 @@ import org.apache.harmony.security.fortress.Engine;
*/
public class Mac implements Cloneable {
+ // The service name.
+ private static final String SERVICE = "Mac";
+
//Used to access common engine functionality
- private static final Engine ENGINE = new Engine("Mac");
+ private static final Engine ENGINE = new Engine(SERVICE);
// Store used provider
- private final Provider provider;
+ private Provider provider;
+
+ // Provider that was requested during creation.
+ private final Provider specifiedProvider;
// Store used spi implementation
- private final MacSpi spiImpl;
+ private MacSpi spiImpl;
// Store used algorithm name
private final String algorithm;
+ /**
+ * Lock held while the SPI is initializing.
+ */
+ private final Object initLock = new Object();
+
// Store Mac state (initialized or not initialized)
private boolean isInitMac;
@@ -61,7 +74,7 @@ public class Mac implements Cloneable {
* the name of the MAC algorithm.
*/
protected Mac(MacSpi macSpi, Provider provider, String algorithm) {
- this.provider = provider;
+ this.specifiedProvider = provider;
this.algorithm = algorithm;
this.spiImpl = macSpi;
this.isInitMac = false;
@@ -82,6 +95,7 @@ public class Mac implements Cloneable {
* @return the provider of this {@code Mac} instance.
*/
public final Provider getProvider() {
+ getSpi();
return provider;
}
@@ -100,11 +114,7 @@ public class Mac implements Cloneable {
*/
public static final Mac getInstance(String algorithm)
throws NoSuchAlgorithmException {
- if (algorithm == null) {
- throw new NullPointerException("algorithm == null");
- }
- Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
- return new Mac((MacSpi) sap.spi, sap.provider, algorithm);
+ return getMac(algorithm, null);
}
/**
@@ -136,12 +146,13 @@ public class Mac implements Cloneable {
if (impProvider == null) {
throw new NoSuchProviderException(provider);
}
- return getInstance(algorithm, impProvider);
+ return getMac(algorithm, impProvider);
}
/**
* Creates a new {@code Mac} instance that provides the specified MAC
- * algorithm from the specified provider.
+ * algorithm from the specified provider. The {@code provider} supplied
+ * does not have to be registered.
*
* @param algorithm
* the name of the requested MAC algorithm.
@@ -162,11 +173,102 @@ public class Mac implements Cloneable {
if (provider == null) {
throw new IllegalArgumentException("provider == null");
}
+ return getMac(algorithm, provider);
+ }
+
+ private static Mac getMac(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException {
if (algorithm == null) {
throw new NullPointerException("algorithm == null");
}
- Object spi = ENGINE.getInstance(algorithm, provider, null);
- return new Mac((MacSpi) spi, provider, algorithm);
+
+ if (tryAlgorithm(null, provider, algorithm) == null) {
+ if (provider == null) {
+ throw new NoSuchAlgorithmException("No provider found for " + algorithm);
+ } else {
+ throw new NoSuchAlgorithmException("Provider " + provider.getName()
+ + " does not provide " + algorithm);
+ }
+ }
+ return new Mac(null, provider, algorithm);
+ }
+
+ private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) {
+ if (provider != null) {
+ Provider.Service service = provider.getService(SERVICE, algorithm);
+ if (service == null) {
+ return null;
+ }
+ return tryAlgorithmWithProvider(key, service);
+ }
+ ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
+ if (services == null) {
+ return null;
+ }
+ for (Provider.Service service : services) {
+ Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service);
+ if (sap != null) {
+ return sap;
+ }
+ }
+ return null;
+ }
+
+ private static Engine.SpiAndProvider tryAlgorithmWithProvider(Key key, Provider.Service service) {
+ try {
+ if (key != null && !service.supportsParameter(key)) {
+ return null;
+ }
+
+ Engine.SpiAndProvider sap = ENGINE.getInstance(service, null);
+ if (sap.spi == null || sap.provider == null) {
+ return null;
+ }
+ if (!(sap.spi instanceof MacSpi)) {
+ return null;
+ }
+ return sap;
+ } catch (NoSuchAlgorithmException ignored) {
+ }
+ return null;
+ }
+
+ /**
+ * Makes sure a MacSpi that matches this type is selected.
+ */
+ private MacSpi getSpi(Key key) {
+ synchronized (initLock) {
+ if (spiImpl != null && provider != null && key == null) {
+ return spiImpl;
+ }
+
+ if (algorithm == null) {
+ return null;
+ }
+
+ final Engine.SpiAndProvider sap = tryAlgorithm(key, specifiedProvider, algorithm);
+ if (sap == null) {
+ throw new ProviderException("No provider for " + getAlgorithm());
+ }
+
+ /*
+ * Set our Spi if we've never been initialized or if we have the Spi
+ * specified and have a null provider.
+ */
+ if (spiImpl == null || provider != null) {
+ spiImpl = (MacSpi) sap.spi;
+ }
+ provider = sap.provider;
+
+ return spiImpl;
+ }
+ }
+
+ /**
+ * Convenience call when the Key is not available.
+ */
+ private MacSpi getSpi() {
+ return getSpi(null);
}
/**
@@ -175,7 +277,7 @@ public class Mac implements Cloneable {
* @return the length of this MAC (in bytes).
*/
public final int getMacLength() {
- return spiImpl.engineGetMacLength();
+ return getSpi().engineGetMacLength();
}
/**
@@ -198,7 +300,7 @@ public class Mac implements Cloneable {
if (key == null) {
throw new InvalidKeyException("key == null");
}
- spiImpl.engineInit(key, params);
+ getSpi(key).engineInit(key, params);
isInitMac = true;
}
@@ -219,7 +321,7 @@ public class Mac implements Cloneable {
throw new InvalidKeyException("key == null");
}
try {
- spiImpl.engineInit(key, null);
+ getSpi(key).engineInit(key, null);
isInitMac = true;
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
@@ -238,7 +340,7 @@ public class Mac implements Cloneable {
if (!isInitMac) {
throw new IllegalStateException();
}
- spiImpl.engineUpdate(input);
+ getSpi().engineUpdate(input);
}
/**
@@ -269,7 +371,7 @@ public class Mac implements Cloneable {
+ " input.length=" + input.length
+ " offset=" + offset + ", len=" + len);
}
- spiImpl.engineUpdate(input, offset, len);
+ getSpi().engineUpdate(input, offset, len);
}
/**
@@ -285,7 +387,7 @@ public class Mac implements Cloneable {
throw new IllegalStateException();
}
if (input != null) {
- spiImpl.engineUpdate(input, 0, input.length);
+ getSpi().engineUpdate(input, 0, input.length);
}
}
@@ -304,7 +406,7 @@ public class Mac implements Cloneable {
throw new IllegalStateException();
}
if (input != null) {
- spiImpl.engineUpdate(input);
+ getSpi().engineUpdate(input);
} else {
throw new IllegalArgumentException("input == null");
}
@@ -326,7 +428,7 @@ public class Mac implements Cloneable {
if (!isInitMac) {
throw new IllegalStateException();
}
- return spiImpl.engineDoFinal();
+ return getSpi().engineDoFinal();
}
/**
@@ -361,11 +463,12 @@ public class Mac implements Cloneable {
if ((outOffset < 0) || (outOffset >= output.length)) {
throw new ShortBufferException("Incorrect outOffset: " + outOffset);
}
- int t = spiImpl.engineGetMacLength();
+ MacSpi spi = getSpi();
+ int t = spi.engineGetMacLength();
if (t > (output.length - outOffset)) {
throw new ShortBufferException("Output buffer is short. Needed " + t + " bytes.");
}
- byte[] result = spiImpl.engineDoFinal();
+ byte[] result = spi.engineDoFinal();
System.arraycopy(result, 0, output, outOffset, result.length);
}
@@ -389,10 +492,11 @@ public class Mac implements Cloneable {
if (!isInitMac) {
throw new IllegalStateException();
}
+ MacSpi spi = getSpi();
if (input != null) {
- spiImpl.engineUpdate(input, 0, input.length);
+ spi.engineUpdate(input, 0, input.length);
}
- return spiImpl.engineDoFinal();
+ return spi.engineDoFinal();
}
/**
@@ -403,7 +507,7 @@ public class Mac implements Cloneable {
* initialized with different parameters.
*/
public final void reset() {
- spiImpl.engineReset();
+ getSpi().engineReset();
}
/**
@@ -415,7 +519,11 @@ public class Mac implements Cloneable {
*/
@Override
public final Object clone() throws CloneNotSupportedException {
- MacSpi newSpiImpl = (MacSpi)spiImpl.clone();
+ MacSpi newSpiImpl = null;
+ final MacSpi spi = getSpi();
+ if (spi != null) {
+ newSpiImpl = (MacSpi) spi.clone();
+ }
Mac mac = new Mac(newSpiImpl, this.provider, this.algorithm);
mac.isInitMac = this.isInitMac;
return mac;
diff --git a/luni/src/main/java/javax/crypto/SealedObject.java b/luni/src/main/java/javax/crypto/SealedObject.java
index cfb970b..4b91184 100644
--- a/luni/src/main/java/javax/crypto/SealedObject.java
+++ b/luni/src/main/java/javax/crypto/SealedObject.java
@@ -19,6 +19,7 @@ package javax.crypto;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -29,6 +30,7 @@ import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import libcore.io.IoUtils;
/**
* A {@code SealedObject} is a wrapper around a {@code serializable} object
@@ -57,14 +59,21 @@ public class SealedObject implements Serializable {
private String paramsAlg;
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
- // We do unshared reads here to ensure we have our own clones of the byte[]s.
- encodedParams = (byte[]) s.readUnshared();
- encryptedContent = (byte[]) s.readUnshared();
- // These are regular shared reads because the algorithms used by a given stream are
- // almost certain to the be same for each object, and String is immutable anyway,
- // so there's no security concern about sharing.
- sealAlg = (String) s.readObject();
- paramsAlg = (String) s.readObject();
+ // This implementation is based on the latest recommendations for safe deserialization at
+ // the time of writing. See the Serialization spec section A.6.
+ ObjectInputStream.GetField fields = s.readFields();
+
+ // The mutable byte arrays are cloned and the immutable strings are not.
+ this.encodedParams = getSafeCopy(fields, "encodedParams");
+ this.encryptedContent = getSafeCopy(fields, "encryptedContent");
+ this.paramsAlg = (String) fields.get("paramsAlg", null);
+ this.sealAlg = (String) fields.get("sealAlg", null);
+ }
+
+ private static byte[] getSafeCopy(ObjectInputStream.GetField fields, String fieldName)
+ throws IOException {
+ byte[] fieldValue = (byte[]) fields.get(fieldName, null);
+ return fieldValue != null ? fieldValue.clone() : null;
}
/**
@@ -87,13 +96,14 @@ public class SealedObject implements Serializable {
* if the cipher is {@code null}.
*/
public SealedObject(Serializable object, Cipher c)
- throws IOException, IllegalBlockSizeException {
+ throws IOException, IllegalBlockSizeException {
if (c == null) {
throw new NullPointerException("c == null");
}
+ ObjectOutputStream oos = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos = new ObjectOutputStream(bos);
oos.writeObject(object);
oos.flush();
AlgorithmParameters ap = c.getParameters();
@@ -105,6 +115,8 @@ public class SealedObject implements Serializable {
// should be never thrown because the cipher
// should be initialized for encryption
throw new IOException(e.toString());
+ } finally {
+ IoUtils.closeQuietly(oos);
}
}
@@ -119,8 +131,10 @@ public class SealedObject implements Serializable {
if (so == null) {
throw new NullPointerException("so == null");
}
- this.encryptedContent = so.encryptedContent;
- this.encodedParams = so.encodedParams;
+ // For safety: clone the mutable arrays so that each object has its own independent copy of
+ // the data.
+ this.encryptedContent = so.encryptedContent != null ? so.encryptedContent.clone() : null;
+ this.encodedParams = so.encodedParams != null ? so.encodedParams.clone() : null;
this.sealAlg = so.sealAlg;
this.paramsAlg = so.paramsAlg;
}
@@ -158,18 +172,14 @@ public class SealedObject implements Serializable {
try {
Cipher cipher = Cipher.getInstance(sealAlg);
if ((paramsAlg != null) && (paramsAlg.length() != 0)) {
- AlgorithmParameters params =
- AlgorithmParameters.getInstance(paramsAlg);
+ AlgorithmParameters params = AlgorithmParameters.getInstance(paramsAlg);
params.init(encodedParams);
cipher.init(Cipher.DECRYPT_MODE, key, params);
} else {
cipher.init(Cipher.DECRYPT_MODE, key);
}
byte[] serialized = cipher.doFinal(encryptedContent);
- ObjectInputStream ois =
- new ObjectInputStream(
- new ByteArrayInputStream(serialized));
- return ois.readObject();
+ return readSerialized(serialized);
} catch (NoSuchPaddingException e) {
// should not be thrown because cipher text was made
// with existing padding
@@ -186,7 +196,7 @@ public class SealedObject implements Serializable {
// should not be thrown because the cipher text
// was correctly made
throw new NoSuchAlgorithmException(e.toString());
- } catch (IllegalStateException e) {
+ } catch (IllegalStateException e) {
// should never be thrown because cipher is initialized
throw new NoSuchAlgorithmException(e.toString());
}
@@ -217,10 +227,7 @@ public class SealedObject implements Serializable {
throw new NullPointerException("c == null");
}
byte[] serialized = c.doFinal(encryptedContent);
- ObjectInputStream ois =
- new ObjectInputStream(
- new ByteArrayInputStream(serialized));
- return ois.readObject();
+ return readSerialized(serialized);
}
/**
@@ -253,18 +260,14 @@ public class SealedObject implements Serializable {
try {
Cipher cipher = Cipher.getInstance(sealAlg, provider);
if ((paramsAlg != null) && (paramsAlg.length() != 0)) {
- AlgorithmParameters params =
- AlgorithmParameters.getInstance(paramsAlg);
+ AlgorithmParameters params = AlgorithmParameters.getInstance(paramsAlg);
params.init(encodedParams);
cipher.init(Cipher.DECRYPT_MODE, key, params);
} else {
cipher.init(Cipher.DECRYPT_MODE, key);
}
byte[] serialized = cipher.doFinal(encryptedContent);
- ObjectInputStream ois =
- new ObjectInputStream(
- new ByteArrayInputStream(serialized));
- return ois.readObject();
+ return readSerialized(serialized);
} catch (NoSuchPaddingException e) {
// should not be thrown because cipher text was made
// with existing padding
@@ -286,4 +289,15 @@ public class SealedObject implements Serializable {
throw new NoSuchAlgorithmException(e.toString());
}
}
+
+ private static Object readSerialized(byte[] serialized)
+ throws IOException, ClassNotFoundException {
+ ObjectInputStream ois = null;
+ try {
+ ois = new ObjectInputStream(new ByteArrayInputStream(serialized));
+ return ois.readObject();
+ } finally {
+ IoUtils.closeQuietly(ois);
+ }
+ }
}
diff --git a/luni/src/main/java/javax/crypto/SecretKeyFactory.java b/luni/src/main/java/javax/crypto/SecretKeyFactory.java
index 8ab3eb8..9298b8e 100644
--- a/luni/src/main/java/javax/crypto/SecretKeyFactory.java
+++ b/luni/src/main/java/javax/crypto/SecretKeyFactory.java
@@ -143,7 +143,8 @@ public class SecretKeyFactory {
/**
* Creates a new {@code SecretKeyFactory} instance for the specified key
- * algorithm from the specified provider.
+ * algorithm from the specified provider. The {@code provider} supplied
+ * does not have to be registered.
*
* @param algorithm
* the name of the key algorithm.
diff --git a/luni/src/main/java/javax/net/ssl/SSLContext.java b/luni/src/main/java/javax/net/ssl/SSLContext.java
index a59f301..efc1947 100644
--- a/luni/src/main/java/javax/net/ssl/SSLContext.java
+++ b/luni/src/main/java/javax/net/ssl/SSLContext.java
@@ -82,6 +82,46 @@ public class SSLContext {
/**
* Creates a new {@code SSLContext} instance for the specified protocol.
*
+ * <p>The following protocols are supported:
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Protocol</th>
+ * <th>API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>Default</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>SSL</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>SSLv3</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.1</td>
+ * <td>16+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.2</td>
+ * <td>16+</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
* @param protocol
* the requested protocol to create a context for.
* @return the created {@code SSLContext} instance.
@@ -103,6 +143,79 @@ public class SSLContext {
* Creates a new {@code SSLContext} instance for the specified protocol from
* the specified provider.
*
+ * <p>The following combinations are supported:
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Protocol</th>
+ * <th>Provider</th>
+ * <th>API Levels</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>Default</td>
+ * <td>AndroidOpenSSL</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>SSL</td>
+ * <td>AndroidOpenSSL</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>SSL</td>
+ * <td>HarmonyJSSE</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSLv3</td>
+ * <td>AndroidOpenSSL</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>SSLv3</td>
+ * <td>HarmonyJSSE</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS</td>
+ * <td>AndroidOpenSSL</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS</td>
+ * <td>HarmonyJSSE</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1</td>
+ * <td>AndroidOpenSSL</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1</td>
+ * <td>HarmonyJSSE</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.1</td>
+ * <td>AndroidOpenSSL</td>
+ * <td>16+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.2</td>
+ * <td>AndroidOpenSSL</td>
+ * <td>16+</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * <p><strong>NOTE:</strong> The best practice is to rely on platform
+ * defaults rather than explicitly specify a provider.
+ * {@link #getDefault()} and {@link #getInstance(String)} are normally
+ * preferred over this method.
+ *
* @param protocol
* the requested protocol to create a context for.
* @param provider
@@ -201,16 +314,33 @@ public class SSLContext {
}
/**
- * Initializes this {@code SSLContext} instance. All of the arguments are
- * optional, and the security providers will be searched for the required
- * implementations of the needed algorithms.
+ * Initializes this {@code SSLContext} instance. Three aspects of the context can be configured
+ * during initialization:
+ * <ul>
+ * <li>Providers of key material for key exchange and peer authentication
+ * ({@link KeyManager} instances),</li>
+ * <li>Providers of trust decisions about peers ({@link TrustManager} instances),
+ * </li>
+ * <li>Provider of randomness ({@link SecureRandom} instance).</li>
+ * </ul>
+ *
+ * <p>For each type of {@code KeyManager} or {@code TrustManager} used by this context, only the
+ * first matching instance from {@code km} or {@code tm} will be used. For example, only the
+ * first instance of {@link X509TrustManager} from {@code tm} will be used.
+ *
+ * <p>For any parameter set to {@code null} defaults will be used. In that case, the installed
+ * security providers will be searched for the highest priority implementation of the required
+ * primitives. For {@code km} and {@code tm}, the highest priority implementation
+ * of {@link KeyManagerFactory} and {@link TrustManagerFactory} will be used to obtain the
+ * required types of {@code KeyManager} and {@code TrustManager}. For {@code sr}, the default
+ * {@code SecureRandom} implementation will be used.
*
* @param km
- * the key sources or {@code null}.
+ * the key sources or {@code null} for default.
* @param tm
- * the trust decision sources or {@code null}.
+ * the trust decision sources or {@code null} for default.
* @param sr
- * the randomness source or {@code null.}
+ * the randomness source or {@code null} for default.
* @throws KeyManagementException
* if initializing this instance fails.
*/
diff --git a/luni/src/main/java/javax/net/ssl/SSLEngine.java b/luni/src/main/java/javax/net/ssl/SSLEngine.java
index a6c9946..cbf02ac 100644
--- a/luni/src/main/java/javax/net/ssl/SSLEngine.java
+++ b/luni/src/main/java/javax/net/ssl/SSLEngine.java
@@ -24,6 +24,629 @@ import java.nio.ByteBuffer;
* protocols. It includes the setup, handshake, and encrypt/decrypt
* functionality needed to create a secure connection.
*
+ * <h3>Default configuration</h3>
+ * <p>{@code SSLEngine} instances obtained from default {@link SSLContext} are configured as
+ * follows:
+ *
+ * <h4>Protocols</h4>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Protocol</th>
+ * <th>Supported (API Levels)</th>
+ * <th>Enabled by default (API Levels)</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>SSLv3</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.1</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.2</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * <h4>Cipher suites</h4>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Cipher suite</th>
+ * <th>Supported (API Levels)</th>
+ * <th>Enabled by default (API Levels)</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_WITH_DES_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_WITH_RC4_128_MD5</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_DES_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_NULL_MD5</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_NULL_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_RC4_128_MD5</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_RC4_128_SHA</td>
+ * <td>9+</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_DES_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_DES_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_DSS_WITH_DES_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_RSA_WITH_DES_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_DES_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_NULL_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_RC4_128_SHA</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_NULL_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_RC4_128_SHA</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_NULL_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_NULL_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_FALLBACK_SCSV</td>
+ * <td>21+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA</td>
+ * <td>21+</td>
+ * <td>21+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA</td>
+ * <td>21+</td>
+ * <td>21+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_NULL_WITH_NULL_NULL</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>21+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_PSK_WITH_AES_128_CBC_SHA</td>
+ * <td>21+</td>
+ * <td>21+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_PSK_WITH_AES_256_CBC_SHA</td>
+ * <td>21+</td>
+ * <td>21+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_PSK_WITH_RC4_128_SHA</td>
+ * <td>21+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_256_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_DES_CBC_SHA</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_NULL_MD5</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_NULL_SHA</td>
+ * <td>1-8</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_NULL_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * <p><em>NOTE</em>: PSK cipher suites are enabled by default only if the {@code SSLContext} through
+ * which the engine was created has been initialized with a {@code PSKKeyManager}.
+ *
* @since 1.5
*/
public abstract class SSLEngine {
diff --git a/luni/src/main/java/javax/net/ssl/SSLEngineResult.java b/luni/src/main/java/javax/net/ssl/SSLEngineResult.java
index 8a98831..3360832 100644
--- a/luni/src/main/java/javax/net/ssl/SSLEngineResult.java
+++ b/luni/src/main/java/javax/net/ssl/SSLEngineResult.java
@@ -110,16 +110,16 @@ public class SSLEngineResult {
public SSLEngineResult(SSLEngineResult.Status status,
SSLEngineResult.HandshakeStatus handshakeStatus, int bytesConsumed, int bytesProduced) {
if (status == null) {
- throw new IllegalArgumentException("status is null");
+ throw new IllegalArgumentException("status == null");
}
if (handshakeStatus == null) {
- throw new IllegalArgumentException("handshakeStatus is null");
+ throw new IllegalArgumentException("handshakeStatus == null");
}
if (bytesConsumed < 0) {
- throw new IllegalArgumentException("bytesConsumed is negative");
+ throw new IllegalArgumentException("bytesConsumed < 0: " + bytesConsumed);
}
if (bytesProduced < 0) {
- throw new IllegalArgumentException("bytesProduced is negative");
+ throw new IllegalArgumentException("bytesProduced < 0: " + bytesProduced);
}
this.status = status;
this.handshakeStatus = handshakeStatus;
diff --git a/luni/src/main/java/javax/net/ssl/SSLParameters.java b/luni/src/main/java/javax/net/ssl/SSLParameters.java
index 6694ef2..054abe2 100644
--- a/luni/src/main/java/javax/net/ssl/SSLParameters.java
+++ b/luni/src/main/java/javax/net/ssl/SSLParameters.java
@@ -27,6 +27,7 @@ public class SSLParameters {
private String[] protocols;
private boolean needClientAuth;
private boolean wantClientAuth;
+ private String endpointIdentificationAlgorithm;
/**
* The default SSLParameters constructor. Cipher suites and
diff --git a/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java b/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
index cce72cd..03b8828 100644
--- a/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
+++ b/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
@@ -20,6 +20,7 @@ package javax.net.ssl;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import javax.net.ServerSocketFactory;
+import org.apache.harmony.security.fortress.Services;
/**
* The factory for SSL server sockets.
@@ -32,6 +33,8 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory {
private static String defaultName;
+ private static int lastCacheVersion = -1;
+
/**
* Returns the default {@code SSLServerSocketFactory} instance. The default
* implementation is defined by the security property
@@ -40,6 +43,12 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory {
* @return the default {@code SSLServerSocketFactory} instance.
*/
public static synchronized ServerSocketFactory getDefault() {
+ int newCacheVersion = Services.getCacheVersion();
+ if (lastCacheVersion != newCacheVersion) {
+ defaultServerSocketFactory = null;
+ defaultName = null;
+ lastCacheVersion = newCacheVersion;
+ }
if (defaultServerSocketFactory != null) {
return defaultServerSocketFactory;
}
diff --git a/luni/src/main/java/javax/net/ssl/SSLSocket.java b/luni/src/main/java/javax/net/ssl/SSLSocket.java
index 5049f81..dc406e1 100644
--- a/luni/src/main/java/javax/net/ssl/SSLSocket.java
+++ b/luni/src/main/java/javax/net/ssl/SSLSocket.java
@@ -25,6 +25,715 @@ import java.net.UnknownHostException;
/**
* The extension of {@code Socket} providing secure protocols like SSL (Secure
* Sockets Layer) or TLS (Transport Layer Security).
+ *
+ * <h3>Default configuration</h3>
+ * <p>{@code SSLSocket} instances obtained from default {@link SSLSocketFactory},
+ * {@link SSLServerSocketFactory}, and {@link SSLContext} are configured as follows:
+ *
+ * <h4>Protocols</h4>
+ *
+ * <p>Client socket:
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Protocol</th>
+ * <th>Supported (API Levels)</th>
+ * <th>Enabled by default (API Levels)</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>SSLv3</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.1</td>
+ * <td>16+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.2</td>
+ * <td>16+</td>
+ * <td>20+</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * <p>Server socket:
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Protocol</th>
+ * <th>Supported (API Levels)</th>
+ * <th>Enabled by default (API Levels)</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>SSLv3</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.1</td>
+ * <td>16+</td>
+ * <td>16+</td>
+ * </tr>
+ * <tr>
+ * <td>TLSv1.2</td>
+ * <td>16+</td>
+ * <td>16+</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * <h4>Cipher suites</h4>
+ *
+ * <p>Methods that operate with cipher suite names (for example,
+ * {@link #getSupportedCipherSuites() getSupportedCipherSuites},
+ * {@link #setEnabledCipherSuites(String[]) setEnabledCipherSuites}) have used
+ * standard names for cipher suites since API Level 9, as listed in the table
+ * below. Prior to API Level 9, non-standard (OpenSSL) names had been used (see
+ * the table following this table).
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Cipher suite</th>
+ * <th>Supported (API Levels)</th>
+ * <th>Enabled by default (API Levels)</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_WITH_DES_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_DH_anon_WITH_RC4_128_MD5</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_DES_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_NULL_MD5</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_NULL_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_RC4_128_MD5</td>
+ * <td>9+</td>
+ * <td>9-19</td>
+ * </tr>
+ * <tr>
+ * <td>SSL_RSA_WITH_RC4_128_SHA</td>
+ * <td>9+</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td>
+ * <td>9+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_NULL_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_ECDSA_WITH_RC4_128_SHA</td>
+ * <td>11+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA</td>
+ * <td>21+</td>
+ * <td>21+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA</td>
+ * <td>21+</td>
+ * <td>21+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_NULL_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDHE_RSA_WITH_RC4_128_SHA</td>
+ * <td>11+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_NULL_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td>
+ * <td>11+</td>
+ * <td>11-19</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_NULL_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td>
+ * <td>11+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</td>
+ * <td>11+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_FALLBACK_SCSV</td>
+ * <td>21+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>21+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_PSK_WITH_AES_128_CBC_SHA</td>
+ * <td>21+</td>
+ * <td>21+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_PSK_WITH_AES_256_CBC_SHA</td>
+ * <td>21+</td>
+ * <td>21+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_PSK_WITH_RC4_128_SHA</td>
+ * <td>21+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>9+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_128_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_128_GCM_SHA256</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>9+</td>
+ * <td>11+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_256_CBC_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_AES_256_GCM_SHA384</td>
+ * <td>20+</td>
+ * <td>20+</td>
+ * </tr>
+ * <tr>
+ * <td>TLS_RSA_WITH_NULL_SHA256</td>
+ * <td>20+</td>
+ * <td></td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * <p><em>NOTE</em>: PSK cipher suites are enabled by default only if the {@code SSLContext} through
+ * which the socket was created has been initialized with a {@code PSKKeyManager}.
+ *
+ * <p>API Levels 1 to 8 use OpenSSL names for cipher suites. The table below
+ * lists these OpenSSL names and their corresponding standard names used in API
+ * Levels 9 and newer.
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>OpenSSL cipher suite</th>
+ * <th>Standard cipher suite</th>
+ * <th>Supported (API Levels)</th>
+ * <th>Enabled by default (API Levels)</th>
+ * </tr>
+ * </thead>
+ *
+ * <tbody>
+ * <tr>
+ * <td>AES128-SHA</td>
+ * <td>TLS_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>AES256-SHA</td>
+ * <td>TLS_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-8, 11+</td>
+ * </tr>
+ * <tr>
+ * <td>DES-CBC-MD5</td>
+ * <td>SSL_CK_DES_64_CBC_WITH_MD5</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>DES-CBC-SHA</td>
+ * <td>SSL_RSA_WITH_DES_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>DES-CBC3-MD5</td>
+ * <td>SSL_CK_DES_192_EDE3_CBC_WITH_MD5</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>DES-CBC3-SHA</td>
+ * <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>DHE-DSS-AES128-SHA</td>
+ * <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DHE-DSS-AES256-SHA</td>
+ * <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-8, 11+</td>
+ * </tr>
+ * <tr>
+ * <td>DHE-RSA-AES128-SHA</td>
+ * <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * <tr>
+ * <td>DHE-RSA-AES256-SHA</td>
+ * <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-8, 11+</td>
+ * </tr>
+ * <tr>
+ * <td>EDH-DSS-DES-CBC-SHA</td>
+ * <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>EDH-DSS-DES-CBC3-SHA</td>
+ * <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>EDH-RSA-DES-CBC-SHA</td>
+ * <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>EDH-RSA-DES-CBC3-SHA</td>
+ * <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>EXP-DES-CBC-SHA</td>
+ * <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>EXP-EDH-DSS-DES-CBC-SHA</td>
+ * <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>EXP-EDH-RSA-DES-CBC-SHA</td>
+ * <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>EXP-RC2-CBC-MD5</td>
+ * <td>SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>EXP-RC4-MD5</td>
+ * <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>RC2-CBC-MD5</td>
+ * <td>SSL_CK_RC2_128_CBC_WITH_MD5</td>
+ * <td>1-8</td>
+ * <td>1-8</td>
+ * </tr>
+ * <tr>
+ * <td>RC4-MD5</td>
+ * <td>SSL_RSA_WITH_RC4_128_MD5</td>
+ * <td>1+</td>
+ * <td>1-19</td>
+ * </tr>
+ * <tr>
+ * <td>RC4-SHA</td>
+ * <td>SSL_RSA_WITH_RC4_128_SHA</td>
+ * <td>1+</td>
+ * <td>1+</td>
+ * </tr>
+ * </tbody>
+ * </table>
*/
public abstract class SSLSocket extends Socket {
@@ -188,13 +897,11 @@ public abstract class SSLSocket extends Socket {
public abstract SSLSession getSession();
/**
- * Registers the specified listener to receive notification on completion of a
- * handshake on this connection.
+ * Registers the specified listener to receive notification on completion of
+ * a handshake on this connection.
*
- * @param listener
- * the listener to register.
- * @throws IllegalArgumentException
- * if {@code listener} is {@code null}.
+ * @param listener the listener to register.
+ * @throws IllegalArgumentException if {@code listener} is {@code null}.
*/
public abstract void addHandshakeCompletedListener(HandshakeCompletedListener listener);
diff --git a/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java b/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
index b07d0fd..b506fa6 100644
--- a/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
+++ b/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
@@ -22,6 +22,7 @@ import java.net.Socket;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import javax.net.SocketFactory;
+import org.apache.harmony.security.fortress.Services;
/**
* The abstract factory implementation to create {@code SSLSocket}s.
@@ -32,7 +33,7 @@ public abstract class SSLSocketFactory extends SocketFactory {
// The default SSL socket factory
private static SocketFactory defaultSocketFactory;
- private static String defaultName;
+ private static int lastCacheVersion = -1;
/**
* Returns the default {@code SSLSocketFactory} instance. The default is
@@ -41,23 +42,39 @@ public abstract class SSLSocketFactory extends SocketFactory {
* @return the default ssl socket factory instance.
*/
public static synchronized SocketFactory getDefault() {
- if (defaultSocketFactory != null) {
+ int newCacheVersion = Services.getCacheVersion();
+ if (defaultSocketFactory != null && lastCacheVersion == newCacheVersion) {
return defaultSocketFactory;
}
- if (defaultName == null) {
- defaultName = Security.getProperty("ssl.SocketFactory.provider");
- if (defaultName != null) {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if (cl == null) {
- cl = ClassLoader.getSystemClassLoader();
- }
- try {
- final Class<?> sfc = Class.forName(defaultName, true, cl);
- defaultSocketFactory = (SocketFactory) sfc.newInstance();
- } catch (Exception e) {
- System.logE("Problem creating " + defaultName, e);
+ lastCacheVersion = newCacheVersion;
+
+ String newName = Security.getProperty("ssl.SocketFactory.provider");
+ if (newName != null) {
+ /* The cache could have been invalidated, but the provider name didn't change. This
+ * will be the most common state, so check for it early without resetting the default
+ * SocketFactory.
+ */
+ if (defaultSocketFactory != null) {
+ if (newName.equals(defaultSocketFactory.getClass().getName())) {
+ return defaultSocketFactory;
+ } else {
+ defaultSocketFactory = null;
}
}
+
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (cl == null) {
+ cl = ClassLoader.getSystemClassLoader();
+ }
+ try {
+ final Class<?> sfc = Class.forName(newName, true, cl);
+ defaultSocketFactory = (SocketFactory) sfc.newInstance();
+ } catch (Exception e) {
+ System.logW("Could not create " + newName + " with ClassLoader "
+ + cl.toString() + ": " + e.getMessage());
+ }
+ } else {
+ defaultSocketFactory = null;
}
if (defaultSocketFactory == null) {
@@ -71,10 +88,12 @@ public abstract class SSLSocketFactory extends SocketFactory {
defaultSocketFactory = context.getSocketFactory();
}
}
+
if (defaultSocketFactory == null) {
// Use internal implementation
defaultSocketFactory = new DefaultSSLSocketFactory("No SSLSocketFactory installed");
}
+
return defaultSocketFactory;
}
diff --git a/luni/src/main/java/javax/security/cert/Certificate.java b/luni/src/main/java/javax/security/cert/Certificate.java
index b3e31f6..08ce36b 100644
--- a/luni/src/main/java/javax/security/cert/Certificate.java
+++ b/luni/src/main/java/javax/security/cert/Certificate.java
@@ -126,15 +126,15 @@ public abstract class Certificate {
* public key for which verification should be performed.
* @param sigProvider
* the name of the signature provider.
- * @exception CertificateException
+ * @throws CertificateException
* if encoding errors are detected
- * @exception NoSuchAlgorithmException
+ * @throws NoSuchAlgorithmException
* if an unsupported algorithm is detected
- * @exception InvalidKeyException
+ * @throws InvalidKeyException
* if an invalid key is detected
- * @exception NoSuchProviderException
+ * @throws NoSuchProviderException
* if the specified provider does not exists.
- * @exception SignatureException
+ * @throws SignatureException
* if signature errors are detected
*/
public abstract void verify(PublicKey key, String sigProvider)
@@ -157,4 +157,3 @@ public abstract class Certificate {
*/
public abstract PublicKey getPublicKey();
}
-
diff --git a/luni/src/main/java/javax/xml/transform/overview.html b/luni/src/main/java/javax/xml/transform/overview.html
index 918db9b..fe3372b 100644
--- a/luni/src/main/java/javax/xml/transform/overview.html
+++ b/luni/src/main/java/javax/xml/transform/overview.html
@@ -177,7 +177,7 @@
<H3>TRaX Patterns</H3>
<ul>
<p>
-<b><a name="pattern-Processor">Processor</a></b>
+<b><a name="pattern-Processor"></a>Processor</b>
<br>
<br>
<i>Intent: </i>Generic concept for the
@@ -191,7 +191,7 @@
operations. Different Processors can be used concurrently by different
threads.</p>
<p>
-<b><a name="pattern-TransformerFactory">TransformerFactory</a></b>
+<b><a name="pattern-TransformerFactory"></a>TransformerFactory</b>
<br>
<br>
<i>Intent: </i>Serve as a vendor-neutral Processor interface for
@@ -205,7 +205,7 @@
TransformerFactory may not perform multiple concurrent
operations.</p>
<p>
-<b><a name="pattern-Templates">Templates</a></b>
+<b><a name="pattern-Templates"></a>Templates</b>
<br>
<br>
<i>Intent: </i>The
@@ -215,7 +215,7 @@
<i>Thread safety: </i>Thread-safe for concurrent
usage over multiple threads once construction is complete.</p>
<p>
-<b><a name="pattern-Transformer">Transformer</a></b>
+<b><a name="pattern-Transformer"></a>Transformer</b>
<br>
<br>
<i>Intent: </i>Act as a per-thread
@@ -228,7 +228,7 @@
<i>Notes: </i>The Transformer is bound to the Templates
object that created it.</p>
<p>
-<b><a name="pattern-Source">Source</a></b>
+<b><a name="pattern-Source"></a>Source</b>
<br>
<br>
<i>Intent: </i>Serve as a
@@ -239,7 +239,7 @@
threads for read-only operations; must be synchronized for edit
operations.</p>
<p>
-<b><a name="pattern-Result">Result</a></b>
+<b><a name="pattern-Result"></a>Result</b>
<br>
<br>
<i>Potential alternate name: </i>ResultTarget<br>
diff --git a/luni/src/main/java/libcore/icu/CollationElementIteratorICU.java b/luni/src/main/java/libcore/icu/CollationElementIteratorICU.java
index 5779d17..d9f105d 100644
--- a/luni/src/main/java/libcore/icu/CollationElementIteratorICU.java
+++ b/luni/src/main/java/libcore/icu/CollationElementIteratorICU.java
@@ -37,15 +37,6 @@ import java.text.CharacterIterator;
* @stable ICU 2.4
*/
public final class CollationElementIteratorICU {
- // public data member -------------------------------------------
-
- /**
- * @stable ICU 2.4
- */
- public static final int NULLORDER = 0xFFFFFFFF;
-
- // public methods -----------------------------------------------
-
/**
* Reset the collation elements to their initial state.
* This will move the 'cursor' to the beginning of the text.
diff --git a/luni/src/main/java/libcore/icu/DateIntervalFormat.java b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
index ab9085f..3855654 100644
--- a/luni/src/main/java/libcore/icu/DateIntervalFormat.java
+++ b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
@@ -92,7 +92,7 @@ public final class DateIntervalFormat {
// This is not the behavior of icu4c's DateIntervalFormat, but it's the historical behavior
// of Android's DateUtils.formatDateRange.
if (startMs != endMs && endsAtMidnight &&
- ((flags & FORMAT_SHOW_TIME) == 0 || julianDay(startCalendar) == julianDay(endCalendar))) {
+ ((flags & FORMAT_SHOW_TIME) == 0 || dayDistance(startCalendar, endCalendar) <= 1)) {
endCalendar.roll(Calendar.DAY_OF_MONTH, false);
endMs -= DAY_IN_MS;
}
@@ -224,8 +224,12 @@ public final class DateIntervalFormat {
return c.get(Calendar.YEAR) == now.get(Calendar.YEAR);
}
+ private static int dayDistance(Calendar c1, Calendar c2) {
+ return julianDay(c2) - julianDay(c1);
+ }
+
private static int julianDay(Calendar c) {
- long utcMs = c.get(Calendar.MILLISECOND) + c.get(Calendar.ZONE_OFFSET);
+ long utcMs = c.getTimeInMillis() + c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);
return (int) (utcMs / DAY_IN_MS) + EPOCH_JULIAN_DAY;
}
diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java
index 76d9c54..0ef3f93 100644
--- a/luni/src/main/java/libcore/icu/ICU.java
+++ b/luni/src/main/java/libcore/icu/ICU.java
@@ -16,8 +16,13 @@
package libcore.icu;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
import libcore.util.BasicLruCache;
/**
@@ -53,30 +58,173 @@ public final class ICU {
return isoCountries.clone();
}
+ private static final int IDX_LANGUAGE = 0;
+ private static final int IDX_SCRIPT = 1;
+ private static final int IDX_REGION = 2;
+ private static final int IDX_VARIANT = 3;
+
+ /*
+ * Parse the {Language, Script, Region, Variant*} section of the ICU locale
+ * ID. This is the bit that appears before the keyword separate "@". The general
+ * structure is a series of ASCII alphanumeric strings (subtags)
+ * separated by underscores.
+ *
+ * Each subtag is interpreted according to its position in the list of subtags
+ * AND its length (groan...). The various cases are explained in comments
+ * below.
+ */
+ private static void parseLangScriptRegionAndVariants(String string,
+ String[] outputArray) {
+ final int first = string.indexOf('_');
+ final int second = string.indexOf('_', first + 1);
+ final int third = string.indexOf('_', second + 1);
+
+ if (first == -1) {
+ outputArray[IDX_LANGUAGE] = string;
+ } else if (second == -1) {
+ // Language and country ("ja_JP") OR
+ // Language and script ("en_Latn") OR
+ // Language and variant ("en_POSIX").
+
+ outputArray[IDX_LANGUAGE] = string.substring(0, first);
+ final String secondString = string.substring(first + 1);
+
+ if (secondString.length() == 4) {
+ // 4 Letter ISO script code.
+ outputArray[IDX_SCRIPT] = secondString;
+ } else if (secondString.length() == 2 || secondString.length() == 3) {
+ // 2 or 3 Letter region code.
+ outputArray[IDX_REGION] = secondString;
+ } else {
+ // If we're here, the length of the second half is either 1 or greater
+ // than 5. Assume that ICU won't hand us malformed tags, and therefore
+ // assume the rest of the string is a series of variant tags.
+ outputArray[IDX_VARIANT] = secondString;
+ }
+ } else if (third == -1) {
+ // Language and country and variant ("ja_JP_TRADITIONAL") OR
+ // Language and script and variant ("en_Latn_POSIX") OR
+ // Language and script and region ("en_Latn_US"). OR
+ // Language and variant with multiple subtags ("en_POSIX_XISOP")
+
+ outputArray[IDX_LANGUAGE] = string.substring(0, first);
+ final String secondString = string.substring(first + 1, second);
+ final String thirdString = string.substring(second + 1);
+
+ if (secondString.length() == 4) {
+ // The second subtag is a script.
+ outputArray[IDX_SCRIPT] = secondString;
+
+ // The third subtag can be either a region or a variant, depending
+ // on its length.
+ if (thirdString.length() == 2 || thirdString.length() == 3 ||
+ thirdString.isEmpty()) {
+ outputArray[IDX_REGION] = thirdString;
+ } else {
+ outputArray[IDX_VARIANT] = thirdString;
+ }
+ } else if (secondString.isEmpty() ||
+ secondString.length() == 2 || secondString.length() == 3) {
+ // The second string is a region, and the third a variant.
+ outputArray[IDX_REGION] = secondString;
+ outputArray[IDX_VARIANT] = thirdString;
+ } else {
+ // Variant with multiple subtags.
+ outputArray[IDX_VARIANT] = string.substring(first + 1);
+ }
+ } else {
+ // Language, script, region and variant with 1 or more subtags
+ // ("en_Latn_US_POSIX") OR
+ // Language, region and variant with 2 or more subtags
+ // (en_US_POSIX_VARIANT).
+ outputArray[IDX_LANGUAGE] = string.substring(0, first);
+ final String secondString = string.substring(first + 1, second);
+ if (secondString.length() == 4) {
+ outputArray[IDX_SCRIPT] = secondString;
+ outputArray[IDX_REGION] = string.substring(second + 1, third);
+ outputArray[IDX_VARIANT] = string.substring(third + 1);
+ } else {
+ outputArray[IDX_REGION] = secondString;
+ outputArray[IDX_VARIANT] = string.substring(second + 1);
+ }
+ }
+ }
+
/**
* Returns the appropriate {@code Locale} given a {@code String} of the form returned
* by {@code toString}. This is very lenient, and doesn't care what's between the underscores:
* this method can parse strings that {@code Locale.toString} won't produce.
* Used to remove duplication.
*/
- public static Locale localeFromString(String localeName) {
- int first = localeName.indexOf('_');
- int second = localeName.indexOf('_', first + 1);
- if (first == -1) {
- // Language only ("ja").
- return new Locale(localeName);
- } else if (second == -1) {
- // Language and country ("ja_JP").
- String language = localeName.substring(0, first);
- String country = localeName.substring(first + 1);
- return new Locale(language, country);
+ public static Locale localeFromIcuLocaleId(String localeId) {
+ // @ == ULOC_KEYWORD_SEPARATOR_UNICODE (uloc.h).
+ final int extensionsIndex = localeId.indexOf('@');
+
+ Map<Character, String> extensionsMap = Collections.EMPTY_MAP;
+ Map<String, String> unicodeKeywordsMap = Collections.EMPTY_MAP;
+ Set<String> unicodeAttributeSet = Collections.EMPTY_SET;
+
+ if (extensionsIndex != -1) {
+ extensionsMap = new HashMap<Character, String>();
+ unicodeKeywordsMap = new HashMap<String, String>();
+ unicodeAttributeSet = new HashSet<String>();
+
+ // ICU sends us a semi-colon (ULOC_KEYWORD_ITEM_SEPARATOR) delimited string
+ // containing all "keywords" it could parse. An ICU keyword is a key-value pair
+ // separated by an "=" (ULOC_KEYWORD_ASSIGN).
+ //
+ // Each keyword item can be one of three things :
+ // - A unicode extension attribute list: In this case the item key is "attribute"
+ // and the value is a hyphen separated list of unicode attributes.
+ // - A unicode extension keyword: In this case, the item key will be larger than
+ // 1 char in length, and the value will be the unicode extension value.
+ // - A BCP-47 extension subtag: In this case, the item key will be exactly one
+ // char in length, and the value will be a sequence of unparsed subtags that
+ // represent the extension.
+ //
+ // Note that this implies that unicode extension keywords are "promoted" to
+ // to the same namespace as the top level extension subtags and their values.
+ // There can't be any collisions in practice because the BCP-47 spec imposes
+ // restrictions on their lengths.
+ final String extensionsString = localeId.substring(extensionsIndex + 1);
+ final String[] extensions = extensionsString.split(";");
+ for (String extension : extensions) {
+ // This is the special key for the unicode attributes
+ if (extension.startsWith("attribute=")) {
+ String unicodeAttributeValues = extension.substring("attribute=".length());
+ for (String unicodeAttribute : unicodeAttributeValues.split("-")) {
+ unicodeAttributeSet.add(unicodeAttribute);
+ }
+ } else {
+ final int separatorIndex = extension.indexOf('=');
+
+ if (separatorIndex == 1) {
+ // This is a BCP-47 extension subtag.
+ final String value = extension.substring(2);
+ final char extensionId = extension.charAt(0);
+
+ extensionsMap.put(extensionId, value);
+ } else {
+ // This is a unicode extension keyword.
+ unicodeKeywordsMap.put(extension.substring(0, separatorIndex),
+ extension.substring(separatorIndex + 1));
+ }
+ }
+ }
+ }
+
+ final String[] outputArray = new String[] { "", "", "", "" };
+ if (extensionsIndex == -1) {
+ parseLangScriptRegionAndVariants(localeId, outputArray);
} else {
- // Language and country and variant ("ja_JP_TRADITIONAL").
- String language = localeName.substring(0, first);
- String country = localeName.substring(first + 1, second);
- String variant = localeName.substring(second + 1);
- return new Locale(language, country, variant);
+ parseLangScriptRegionAndVariants(localeId.substring(0, extensionsIndex),
+ outputArray);
}
+
+ return new Locale(outputArray[IDX_LANGUAGE], outputArray[IDX_REGION],
+ outputArray[IDX_VARIANT], outputArray[IDX_SCRIPT],
+ unicodeAttributeSet, unicodeKeywordsMap, extensionsMap,
+ true /* has validated fields */);
}
public static Locale[] localesFromStrings(String[] localeNames) {
@@ -85,7 +233,7 @@ public final class ICU {
// both so that we never need to convert back when talking to it.
LinkedHashSet<Locale> set = new LinkedHashSet<Locale>();
for (String localeName : localeNames) {
- set.add(localeFromString(localeName));
+ set.add(localeFromIcuLocaleId(localeName));
}
return set.toArray(new Locale[set.size()]);
}
@@ -125,19 +273,20 @@ public final class ICU {
return localesFromStrings(getAvailableNumberFormatLocalesNative());
}
- public static String getBestDateTimePattern(String skeleton, String localeName) {
- String key = skeleton + "\t" + localeName;
+ public static String getBestDateTimePattern(String skeleton, Locale locale) {
+ String languageTag = locale.toLanguageTag();
+ String key = skeleton + "\t" + languageTag;
synchronized (CACHED_PATTERNS) {
String pattern = CACHED_PATTERNS.get(key);
if (pattern == null) {
- pattern = getBestDateTimePatternNative(skeleton, localeName);
+ pattern = getBestDateTimePatternNative(skeleton, languageTag);
CACHED_PATTERNS.put(key, pattern);
}
return pattern;
}
}
- private static native String getBestDateTimePatternNative(String skeleton, String localeName);
+ private static native String getBestDateTimePatternNative(String skeleton, String languageTag);
public static char[] getDateFormatOrder(String pattern) {
char[] result = new char[3];
@@ -197,8 +346,17 @@ public final class ICU {
// --- Case mapping.
- public static native String toLowerCase(String s, String localeName);
- public static native String toUpperCase(String s, String localeName);
+ public static String toLowerCase(String s, Locale locale) {
+ return toLowerCase(s, locale.toLanguageTag());
+ }
+
+ private static native String toLowerCase(String s, String languageTag);
+
+ public static String toUpperCase(String s, Locale locale) {
+ return toUpperCase(s, locale.toLanguageTag());
+ }
+
+ private static native String toUpperCase(String s, String languageTag);
// --- Errors.
@@ -224,22 +382,79 @@ public final class ICU {
public static native String[] getAvailableCurrencyCodes();
public static native String getCurrencyCode(String countryCode);
- public static native String getCurrencyDisplayName(String locale, String currencyCode);
+
+ public static String getCurrencyDisplayName(Locale locale, String currencyCode) {
+ return getCurrencyDisplayName(locale.toLanguageTag(), currencyCode);
+ }
+
+ private static native String getCurrencyDisplayName(String languageTag, String currencyCode);
+
public static native int getCurrencyFractionDigits(String currencyCode);
- public static native String getCurrencySymbol(String locale, String currencyCode);
+ public static native int getCurrencyNumericCode(String currencyCode);
+
+ public static String getCurrencySymbol(Locale locale, String currencyCode) {
+ return getCurrencySymbol(locale.toLanguageTag(), currencyCode);
+ }
+
+ private static native String getCurrencySymbol(String languageTag, String currencyCode);
+
+ public static String getDisplayCountry(Locale targetLocale, Locale locale) {
+ return getDisplayCountryNative(targetLocale.toLanguageTag(), locale.toLanguageTag());
+ }
- public static native String getDisplayCountryNative(String countryCode, String locale);
- public static native String getDisplayLanguageNative(String languageCode, String locale);
- public static native String getDisplayVariantNative(String variantCode, String locale);
+ private static native String getDisplayCountryNative(String targetLanguageTag, String languageTag);
+
+ public static String getDisplayLanguage(Locale targetLocale, Locale locale) {
+ return getDisplayLanguageNative(targetLocale.toLanguageTag(), locale.toLanguageTag());
+ }
+
+ private static native String getDisplayLanguageNative(String targetLanguageTag, String languageTag);
+
+ public static String getDisplayVariant(Locale targetLocale, Locale locale) {
+ return getDisplayVariantNative(targetLocale.toLanguageTag(), locale.toLanguageTag());
+ }
+
+ private static native String getDisplayVariantNative(String targetLanguageTag, String languageTag);
+
+ public static String getDisplayScript(Locale targetLocale, Locale locale) {
+ return getDisplayScriptNative(targetLocale.toLanguageTag(), locale.toLanguageTag());
+ }
- public static native String getISO3CountryNative(String locale);
- public static native String getISO3LanguageNative(String locale);
+ private static native String getDisplayScriptNative(String targetLanguageTag, String languageTag);
+ public static native String getISO3Country(String languageTag);
+
+ public static native String getISO3Language(String languageTag);
+
+ public static Locale addLikelySubtags(Locale locale) {
+ return Locale.forLanguageTag(addLikelySubtags(locale.toLanguageTag()).replace('_', '-'));
+ }
+
+ /**
+ * @deprecated use {@link #addLikelySubtags(java.util.Locale)} instead.
+ */
+ @Deprecated
public static native String addLikelySubtags(String locale);
+
+ /**
+ * @deprecated use {@link java.util.Locale#getScript()} instead. This has been kept
+ * around only for the support library.
+ */
+ @Deprecated
public static native String getScript(String locale);
private static native String[] getISOLanguagesNative();
private static native String[] getISOCountriesNative();
- static native boolean initLocaleDataNative(String locale, LocaleData result);
+ static native boolean initLocaleDataNative(String languageTag, LocaleData result);
+
+ /**
+ * Takes a BCP-47 language tag (Locale.toLanguageTag()). e.g. en-US, not en_US
+ */
+ public static native void setDefaultLocale(String languageTag);
+
+ /**
+ * Returns a locale name, not a BCP-47 language tag. e.g. en_US not en-US.
+ */
+ public static native String getDefaultLocale();
}
diff --git a/luni/src/main/java/libcore/icu/LocaleData.java b/luni/src/main/java/libcore/icu/LocaleData.java
index f00c30f..9e07244 100644
--- a/luni/src/main/java/libcore/icu/LocaleData.java
+++ b/luni/src/main/java/libcore/icu/LocaleData.java
@@ -79,6 +79,10 @@ public final class LocaleData {
public String mediumDateFormat;
public String shortDateFormat;
+ // Used by TimePicker. Not currently used by UTS#35.
+ public String narrowAm; // "a".
+ public String narrowPm; // "p".
+
// shortDateFormat, but guaranteed to have 4-digit years.
// Used by android.text.format.DateFormat.getDateFormatStringForSetting.
public String shortDateFormat4;
@@ -95,7 +99,7 @@ public final class LocaleData {
public char percent;
public char perMill;
public char monetarySeparator;
- public char minusSign;
+ public String minusSign;
public String exponentSeparator;
public String infinity;
public String NaN;
@@ -112,27 +116,40 @@ public final class LocaleData {
private LocaleData() {
}
+ public static Locale mapInvalidAndNullLocales(Locale locale) {
+ if (locale == null) {
+ return Locale.getDefault();
+ }
+
+ if ("und".equals(locale.toLanguageTag())) {
+ return Locale.ROOT;
+ }
+
+ return locale;
+ }
+
/**
* Returns a shared LocaleData for the given locale.
*/
public static LocaleData get(Locale locale) {
if (locale == null) {
- locale = Locale.getDefault();
+ throw new NullPointerException("locale == null");
}
- String localeName = locale.toString();
+
+ final String languageTag = locale.toLanguageTag();
synchronized (localeDataCache) {
- LocaleData localeData = localeDataCache.get(localeName);
+ LocaleData localeData = localeDataCache.get(languageTag);
if (localeData != null) {
return localeData;
}
}
LocaleData newLocaleData = initLocaleData(locale);
synchronized (localeDataCache) {
- LocaleData localeData = localeDataCache.get(localeName);
+ LocaleData localeData = localeDataCache.get(languageTag);
if (localeData != null) {
return localeData;
}
- localeDataCache.put(localeName, newLocaleData);
+ localeDataCache.put(languageTag, newLocaleData);
return newLocaleData;
}
}
@@ -171,13 +188,13 @@ public final class LocaleData {
private static LocaleData initLocaleData(Locale locale) {
LocaleData localeData = new LocaleData();
- if (!ICU.initLocaleDataNative(locale.toString(), localeData)) {
+ if (!ICU.initLocaleDataNative(locale.toLanguageTag(), localeData)) {
throw new AssertionError("couldn't initialize LocaleData for locale " + locale);
}
// Get the "h:mm a" and "HH:mm" 12- and 24-hour time format strings.
- localeData.timeFormat12 = ICU.getBestDateTimePattern("hm", locale.toString());
- localeData.timeFormat24 = ICU.getBestDateTimePattern("Hm", locale.toString());
+ localeData.timeFormat12 = ICU.getBestDateTimePattern("hm", locale);
+ localeData.timeFormat24 = ICU.getBestDateTimePattern("Hm", locale);
// Fix up a couple of patterns.
if (localeData.fullTimeFormat != null) {
diff --git a/luni/src/main/java/libcore/icu/NativeBreakIterator.java b/luni/src/main/java/libcore/icu/NativeBreakIterator.java
index 7168d96..992aac2 100644
--- a/luni/src/main/java/libcore/icu/NativeBreakIterator.java
+++ b/luni/src/main/java/libcore/icu/NativeBreakIterator.java
@@ -138,23 +138,23 @@ public final class NativeBreakIterator implements Cloneable {
}
public int preceding(int offset) {
- return precedingImpl(this.address, this.string, offset);
+ return precedingImpl(this.address, this.string, offset);
}
- public static NativeBreakIterator getCharacterInstance(Locale where) {
- return new NativeBreakIterator(getCharacterInstanceImpl(where.toString()), BI_CHAR_INSTANCE);
+ public static NativeBreakIterator getCharacterInstance(Locale locale) {
+ return new NativeBreakIterator(getCharacterInstanceImpl(locale.toLanguageTag()), BI_CHAR_INSTANCE);
}
- public static NativeBreakIterator getLineInstance(Locale where) {
- return new NativeBreakIterator(getLineInstanceImpl(where.toString()), BI_LINE_INSTANCE);
+ public static NativeBreakIterator getLineInstance(Locale locale) {
+ return new NativeBreakIterator(getLineInstanceImpl(locale.toLanguageTag()), BI_LINE_INSTANCE);
}
- public static NativeBreakIterator getSentenceInstance(Locale where) {
- return new NativeBreakIterator(getSentenceInstanceImpl(where.toString()), BI_SENT_INSTANCE);
+ public static NativeBreakIterator getSentenceInstance(Locale locale) {
+ return new NativeBreakIterator(getSentenceInstanceImpl(locale.toLanguageTag()), BI_SENT_INSTANCE);
}
- public static NativeBreakIterator getWordInstance(Locale where) {
- return new NativeBreakIterator(getWordInstanceImpl(where.toString()), BI_WORD_INSTANCE);
+ public static NativeBreakIterator getWordInstance(Locale locale) {
+ return new NativeBreakIterator(getWordInstanceImpl(locale.toLanguageTag()), BI_WORD_INSTANCE);
}
private static native long getCharacterInstanceImpl(String locale);
diff --git a/luni/src/main/java/libcore/icu/NativeCollation.java b/luni/src/main/java/libcore/icu/NativeCollation.java
index 0373fef..b4b4f46 100644
--- a/luni/src/main/java/libcore/icu/NativeCollation.java
+++ b/luni/src/main/java/libcore/icu/NativeCollation.java
@@ -10,6 +10,8 @@
package libcore.icu;
+import java.util.Locale;
+
/**
* Package static class for declaring all native methods for collation use.
* @author syn wee quek
@@ -23,10 +25,13 @@ public final class NativeCollation {
public static native void closeCollator(long address);
public static native int compare(long address, String source, String target);
public static native int getAttribute(long address, int type);
- public static native int getCollationElementIterator(long address, String source);
+ public static native long getCollationElementIterator(long address, String source);
public static native String getRules(long address);
public static native byte[] getSortKey(long address, String source);
- public static native long openCollator(String locale);
+ public static long openCollator(Locale locale) {
+ return openCollator(locale.toLanguageTag());
+ }
+ private static native long openCollator(String languageTag);
public static native long openCollatorFromRules(String rules, int normalizationMode, int collationStrength);
public static native long safeClone(long address);
public static native void setAttribute(long address, int type, int value);
diff --git a/luni/src/main/java/libcore/icu/NativeDecimalFormat.java b/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
index 0e9ffc4..fd179c1 100644
--- a/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
+++ b/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
@@ -27,7 +27,6 @@ import java.text.Format;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Currency;
-import java.util.NoSuchElementException;
public final class NativeDecimalFormat implements Cloneable {
/**
@@ -92,6 +91,47 @@ public final class NativeDecimalFormat implements Cloneable {
private static final int UNUM_PUBLIC_RULESETS = 7;
/**
+ * A table for translating between NumberFormat.Field instances
+ * and icu4c UNUM_x_FIELD constants.
+ */
+ private static final Format.Field[] ICU4C_FIELD_IDS = {
+ // The old java field values were 0 for integer and 1 for fraction.
+ // The new java field attributes are all objects. ICU assigns the values
+ // starting from 0 in the following order; note that integer and
+ // fraction positions match the old field values.
+ NumberFormat.Field.INTEGER, // 0 UNUM_INTEGER_FIELD
+ NumberFormat.Field.FRACTION, // 1 UNUM_FRACTION_FIELD
+ NumberFormat.Field.DECIMAL_SEPARATOR, // 2 UNUM_DECIMAL_SEPARATOR_FIELD
+ NumberFormat.Field.EXPONENT_SYMBOL, // 3 UNUM_EXPONENT_SYMBOL_FIELD
+ NumberFormat.Field.EXPONENT_SIGN, // 4 UNUM_EXPONENT_SIGN_FIELD
+ NumberFormat.Field.EXPONENT, // 5 UNUM_EXPONENT_FIELD
+ NumberFormat.Field.GROUPING_SEPARATOR, // 6 UNUM_GROUPING_SEPARATOR_FIELD
+ NumberFormat.Field.CURRENCY, // 7 UNUM_CURRENCY_FIELD
+ NumberFormat.Field.PERCENT, // 8 UNUM_PERCENT_FIELD
+ NumberFormat.Field.PERMILLE, // 9 UNUM_PERMILL_FIELD
+ NumberFormat.Field.SIGN, // 10 UNUM_SIGN_FIELD
+ };
+
+ private static int translateFieldId(FieldPosition fp) {
+ int id = fp.getField();
+ if (id < -1 || id > 1) {
+ id = -1;
+ }
+ if (id == -1) {
+ Format.Field attr = fp.getFieldAttribute();
+ if (attr != null) {
+ for (int i = 0; i < ICU4C_FIELD_IDS.length; ++i) {
+ if (ICU4C_FIELD_IDS[i].equals(attr)) {
+ id = i;
+ break;
+ }
+ }
+ }
+ }
+ return id;
+ }
+
+ /**
* The address of the ICU DecimalFormat* on the native heap.
*/
private long address;
@@ -111,19 +151,12 @@ public final class NativeDecimalFormat implements Cloneable {
private transient boolean parseBigDecimal;
- /**
- * Cache the BigDecimal form of the multiplier. This is null until we've
- * formatted a BigDecimal (with a multiplier that is not 1), or the user has
- * explicitly called {@link #setMultiplier(int)} with any multiplier.
- */
- private BigDecimal multiplierBigDecimal = null;
-
public NativeDecimalFormat(String pattern, DecimalFormatSymbols dfs) {
try {
this.address = open(pattern, dfs.getCurrencySymbol(),
dfs.getDecimalSeparator(), dfs.getDigit(), dfs.getExponentSeparator(),
dfs.getGroupingSeparator(), dfs.getInfinity(),
- dfs.getInternationalCurrencySymbol(), dfs.getMinusSign(),
+ dfs.getInternationalCurrencySymbol(), dfs.getMinusSignString(),
dfs.getMonetaryDecimalSeparator(), dfs.getNaN(), dfs.getPatternSeparator(),
dfs.getPercent(), dfs.getPerMill(), dfs.getZeroDigit());
this.lastPattern = pattern;
@@ -211,13 +244,30 @@ public final class NativeDecimalFormat implements Cloneable {
obj.isGroupingUsed() == this.isGroupingUsed();
}
+ public String toString() {
+ return getClass().getName() + "[\"" + toPattern() + "\"" +
+ ",isDecimalSeparatorAlwaysShown=" + isDecimalSeparatorAlwaysShown() +
+ ",groupingSize=" + getGroupingSize() +
+ ",multiplier=" + getMultiplier() +
+ ",negativePrefix=" + getNegativePrefix() +
+ ",negativeSuffix=" + getNegativeSuffix() +
+ ",positivePrefix=" + getPositivePrefix() +
+ ",positiveSuffix=" + getPositiveSuffix() +
+ ",maxIntegerDigits=" + getMaximumIntegerDigits() +
+ ",maxFractionDigits=" + getMaximumFractionDigits() +
+ ",minIntegerDigits=" + getMinimumIntegerDigits() +
+ ",minFractionDigits=" + getMinimumFractionDigits() +
+ ",grouping=" + isGroupingUsed() +
+ "]";
+ }
+
/**
* Copies the DecimalFormatSymbols settings into our native peer in bulk.
*/
public void setDecimalFormatSymbols(final DecimalFormatSymbols dfs) {
setDecimalFormatSymbols(this.address, dfs.getCurrencySymbol(), dfs.getDecimalSeparator(),
dfs.getDigit(), dfs.getExponentSeparator(), dfs.getGroupingSeparator(),
- dfs.getInfinity(), dfs.getInternationalCurrencySymbol(), dfs.getMinusSign(),
+ dfs.getInfinity(), dfs.getInternationalCurrencySymbol(), dfs.getMinusSignString(),
dfs.getMonetaryDecimalSeparator(), dfs.getNaN(), dfs.getPatternSeparator(),
dfs.getPercent(), dfs.getPerMill(), dfs.getZeroDigit());
}
@@ -233,8 +283,8 @@ public final class NativeDecimalFormat implements Cloneable {
public char[] formatBigDecimal(BigDecimal value, FieldPosition field) {
FieldPositionIterator fpi = FieldPositionIterator.forFieldPosition(field);
char[] result = formatDigitList(this.address, value.toString(), fpi);
- if (fpi != null) {
- FieldPositionIterator.setFieldPosition(fpi, field);
+ if (fpi != null && field != null) {
+ updateFieldPosition(field, fpi);
}
return result;
}
@@ -242,8 +292,8 @@ public final class NativeDecimalFormat implements Cloneable {
public char[] formatBigInteger(BigInteger value, FieldPosition field) {
FieldPositionIterator fpi = FieldPositionIterator.forFieldPosition(field);
char[] result = formatDigitList(this.address, value.toString(10), fpi);
- if (fpi != null) {
- FieldPositionIterator.setFieldPosition(fpi, field);
+ if (fpi != null && field != null) {
+ updateFieldPosition(field, fpi);
}
return result;
}
@@ -251,8 +301,8 @@ public final class NativeDecimalFormat implements Cloneable {
public char[] formatLong(long value, FieldPosition field) {
FieldPositionIterator fpi = FieldPositionIterator.forFieldPosition(field);
char[] result = formatLong(this.address, value, fpi);
- if (fpi != null) {
- FieldPositionIterator.setFieldPosition(fpi, field);
+ if (fpi != null && field != null) {
+ updateFieldPosition(field, fpi);
}
return result;
}
@@ -260,12 +310,25 @@ public final class NativeDecimalFormat implements Cloneable {
public char[] formatDouble(double value, FieldPosition field) {
FieldPositionIterator fpi = FieldPositionIterator.forFieldPosition(field);
char[] result = formatDouble(this.address, value, fpi);
- if (fpi != null) {
- FieldPositionIterator.setFieldPosition(fpi, field);
+ if (fpi != null && field != null) {
+ updateFieldPosition(field, fpi);
}
return result;
}
+ private static void updateFieldPosition(FieldPosition fp, FieldPositionIterator fpi) {
+ int field = translateFieldId(fp);
+ if (field != -1) {
+ while (fpi.next()) {
+ if (fpi.fieldId() == field) {
+ fp.setBeginIndex(fpi.start());
+ fp.setEndIndex(fpi.limit());
+ return;
+ }
+ }
+ }
+ }
+
public void applyLocalizedPattern(String pattern) {
applyPattern(this.address, true, pattern);
lastPattern = null;
@@ -352,6 +415,10 @@ public final class NativeDecimalFormat implements Cloneable {
}
public int getGroupingSize() {
+ // Work around http://bugs.icu-project.org/trac/ticket/10864 in icu4c 53.
+ if (!isGroupingUsed()) {
+ return 0;
+ }
return getAttribute(this.address, UNUM_GROUPING_SIZE);
}
@@ -408,9 +475,9 @@ public final class NativeDecimalFormat implements Cloneable {
setAttribute(this.address, UNUM_DECIMAL_ALWAYS_SHOWN, i);
}
- public void setCurrency(Currency currency) {
- setSymbol(this.address, UNUM_CURRENCY_SYMBOL, currency.getSymbol());
- setSymbol(this.address, UNUM_INTL_CURRENCY_SYMBOL, currency.getCurrencyCode());
+ public void setCurrency(String currencySymbol, String currencyCode) {
+ setSymbol(this.address, UNUM_CURRENCY_SYMBOL, currencySymbol);
+ setSymbol(this.address, UNUM_INTL_CURRENCY_SYMBOL, currencyCode);
}
public void setGroupingSize(int value) {
@@ -440,8 +507,6 @@ public final class NativeDecimalFormat implements Cloneable {
public void setMultiplier(int value) {
setAttribute(this.address, UNUM_MULTIPLIER, value);
- // Update the cached BigDecimal for multiplier.
- multiplierBigDecimal = BigDecimal.valueOf(value);
}
public void setNegativePrefix(String value) {
@@ -501,6 +566,7 @@ public final class NativeDecimalFormat implements Cloneable {
case HALF_EVEN: nativeRoundingMode = 4; break;
case HALF_DOWN: nativeRoundingMode = 5; break;
case HALF_UP: nativeRoundingMode = 6; break;
+ case UNNECESSARY: nativeRoundingMode = 7; break;
default: throw new AssertionError();
}
setRoundingMode(address, nativeRoundingMode, roundingIncrement);
@@ -515,104 +581,33 @@ public final class NativeDecimalFormat implements Cloneable {
}
public static FieldPositionIterator forFieldPosition(FieldPosition fp) {
- if (fp != null && fp.getField() != -1) {
- return new FieldPositionIterator();
- }
- return null;
- }
-
- private static int getNativeFieldPositionId(FieldPosition fp) {
- // NOTE: -1, 0, and 1 were the only valid original java field values
- // for NumberFormat. They take precedence. This assumes any other
- // value is a mistake and the actual value is in the attribute.
- // Clients can construct FieldPosition combining any attribute with any field
- // value, which is just wrong, but there you go.
-
- int id = fp.getField();
- if (id < -1 || id > 1) {
- id = -1;
- }
- if (id == -1) {
- Format.Field attr = fp.getFieldAttribute();
- if (attr != null) {
- for (int i = 0; i < fields.length; ++i) {
- if (fields[i].equals(attr)) {
- id = i;
- break;
- }
- }
- }
- }
- return id;
- }
-
- private static void setFieldPosition(FieldPositionIterator fpi, FieldPosition fp) {
- if (fpi != null && fp != null) {
- int field = getNativeFieldPositionId(fp);
- if (field != -1) {
- while (fpi.next()) {
- if (fpi.fieldId() == field) {
- fp.setBeginIndex(fpi.start());
- fp.setEndIndex(fpi.limit());
- break;
- }
- }
- }
- }
+ return (fp != null) ? new FieldPositionIterator() : null;
}
public boolean next() {
- // if pos == data.length, we've already returned false once
- if (data == null || pos == data.length) {
- throw new NoSuchElementException();
+ if (data == null) {
+ return false;
}
pos += 3;
return pos < data.length;
}
- private void checkValid() {
- if (data == null || pos < 0 || pos == data.length) {
- throw new NoSuchElementException();
- }
- }
-
public int fieldId() {
return data[pos];
}
public Format.Field field() {
- checkValid();
- return fields[data[pos]];
+ return ICU4C_FIELD_IDS[data[pos]];
}
public int start() {
- checkValid();
return data[pos + 1];
}
public int limit() {
- checkValid();
return data[pos + 2];
}
- private static Format.Field fields[] = {
- // The old java field values were 0 for integer and 1 for fraction.
- // The new java field attributes are all objects. ICU assigns the values
- // starting from 0 in the following order; note that integer and
- // fraction positions match the old field values.
- NumberFormat.Field.INTEGER,
- NumberFormat.Field.FRACTION,
- NumberFormat.Field.DECIMAL_SEPARATOR,
- NumberFormat.Field.EXPONENT_SYMBOL,
- NumberFormat.Field.EXPONENT_SIGN,
- NumberFormat.Field.EXPONENT,
- NumberFormat.Field.GROUPING_SEPARATOR,
- NumberFormat.Field.CURRENCY,
- NumberFormat.Field.PERCENT,
- NumberFormat.Field.PERMILLE,
- NumberFormat.Field.SIGN,
- };
-
// called by native
private void setData(int[] data) {
this.data = data;
@@ -630,13 +625,13 @@ public final class NativeDecimalFormat implements Cloneable {
private static native String getTextAttribute(long addr, int symbol);
private static native long open(String pattern, String currencySymbol,
char decimalSeparator, char digit, String exponentSeparator, char groupingSeparator,
- String infinity, String internationalCurrencySymbol, char minusSign,
+ String infinity, String internationalCurrencySymbol, String minusSign,
char monetaryDecimalSeparator, String nan, char patternSeparator, char percent,
char perMill, char zeroDigit);
private static native Number parse(long addr, String string, ParsePosition position, boolean parseBigDecimal);
private static native void setDecimalFormatSymbols(long addr, String currencySymbol,
char decimalSeparator, char digit, String exponentSeparator, char groupingSeparator,
- String infinity, String internationalCurrencySymbol, char minusSign,
+ String infinity, String internationalCurrencySymbol, String minusSign,
char monetaryDecimalSeparator, String nan, char patternSeparator, char percent,
char perMill, char zeroDigit);
private static native void setSymbol(long addr, int symbol, String str);
diff --git a/luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java b/luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java
index 3ea942d..b23013b 100644
--- a/luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java
+++ b/luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java
@@ -52,7 +52,7 @@ public final class RuleBasedCollatorICU implements Cloneable {
}
public RuleBasedCollatorICU(Locale locale) {
- address = NativeCollation.openCollator(locale.toString());
+ address = NativeCollation.openCollator(locale);
}
private RuleBasedCollatorICU(long address) {
diff --git a/luni/src/main/java/libcore/icu/TimeZoneNames.java b/luni/src/main/java/libcore/icu/TimeZoneNames.java
index 5bb54a1..3413a5d 100644
--- a/luni/src/main/java/libcore/icu/TimeZoneNames.java
+++ b/luni/src/main/java/libcore/icu/TimeZoneNames.java
@@ -53,15 +53,8 @@ public final class TimeZoneNames {
}
public static class ZoneStringsCache extends BasicLruCache<Locale, String[][]> {
- // De-duplicate the strings (http://b/2672057).
- private final HashMap<String, String> internTable = new HashMap<String, String>();
-
public ZoneStringsCache() {
- // We make room for all the time zones known to the system, since each set of strings
- // isn't particularly large (and we remove duplicates), but is currently (Honeycomb)
- // really expensive to compute.
- // If you change this, you might want to change the scope of the intern table too.
- super(availableTimeZoneIds.length);
+ super(5); // Room for a handful of locales.
}
@Override protected String[][] create(Locale locale) {
@@ -85,11 +78,13 @@ public final class TimeZoneNames {
long nativeDuration = nativeEnd - nativeStart;
long duration = end - start;
System.logI("Loaded time zone names for \"" + locale + "\" in " + duration + "ms" +
- " (" + nativeDuration + "ms in ICU)");
+ " (" + nativeDuration + "ms in ICU)");
return result;
}
+ // De-duplicate the strings (http://b/2672057).
private synchronized void internStrings(String[][] result) {
+ HashMap<String, String> internTable = new HashMap<String, String>();
for (int i = 0; i < result.length; ++i) {
for (int j = 1; j < NAME_COUNT; ++j) {
String original = result[i][j];
@@ -162,5 +157,7 @@ public final class TimeZoneNames {
return ids.toArray(new String[ids.size()]);
}
+ public static native String getExemplarLocation(String locale, String tz);
+
private static native void fillZoneStrings(String locale, String[][] result);
}
diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
index c61a3cf..b3dc74b 100644
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -16,14 +16,22 @@
package libcore.io;
+import android.system.ErrnoException;
+import android.system.StructLinger;
+import android.system.StructPollfd;
+import android.system.StructStat;
+import android.system.StructStatVfs;
+import android.util.MutableLong;
import dalvik.system.BlockGuard;
import dalvik.system.SocketTagger;
import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
+import static dalvik.system.BlockGuard.DISALLOW_NETWORK;
/**
* Informs BlockGuard of any activity it should be aware of.
@@ -55,9 +63,27 @@ public class BlockGuardOs extends ForwardingOs {
return tagSocket(os.accept(fd, peerAddress));
}
+ @Override public boolean access(String path, int mode) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ return os.access(path, mode);
+ }
+
+ @Override public void chmod(String path, int mode) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.chmod(path, mode);
+ }
+
+ @Override public void chown(String path, int uid, int gid) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.chown(path, uid, gid);
+ }
+
@Override public void close(FileDescriptor fd) throws ErrnoException {
try {
- if (S_ISSOCK(Libcore.os.fstat(fd).st_mode)) {
+ // The usual case is that this _isn't_ a socket, so the getsockopt(2) call in
+ // isLingerSocket will throw, and that's really expensive. Try to avoid asking
+ // if we don't care.
+ if (fd.isSocket()) {
if (isLingerSocket(fd)) {
// If the fd is a socket with SO_LINGER set, we might block indefinitely.
// We allow non-linger sockets so that apps can close their network
@@ -85,6 +111,16 @@ public class BlockGuardOs extends ForwardingOs {
os.connect(fd, address, port);
}
+ @Override public void fchmod(FileDescriptor fd, int mode) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.fchmod(fd, mode);
+ }
+
+ @Override public void fchown(FileDescriptor fd, int uid, int gid) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.fchown(fd, uid, gid);
+ }
+
// TODO: Untag newFd when needed for dup2(FileDescriptor oldFd, int newFd)
@Override public void fdatasync(FileDescriptor fd) throws ErrnoException {
@@ -92,6 +128,16 @@ public class BlockGuardOs extends ForwardingOs {
os.fdatasync(fd);
}
+ @Override public StructStat fstat(FileDescriptor fd) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ return os.fstat(fd);
+ }
+
+ @Override public StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ return os.fstatvfs(fd);
+ }
+
@Override public void fsync(FileDescriptor fd) throws ErrnoException {
BlockGuard.getThreadPolicy().onWriteToDisk();
os.fsync(fd);
@@ -102,6 +148,36 @@ public class BlockGuardOs extends ForwardingOs {
os.ftruncate(fd, length);
}
+ @Override public void lchown(String path, int uid, int gid) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.lchown(path, uid, gid);
+ }
+
+ @Override public void link(String oldPath, String newPath) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.link(oldPath, newPath);
+ }
+
+ @Override public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ return os.lseek(fd, offset, whence);
+ }
+
+ @Override public StructStat lstat(String path) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ return os.lstat(path);
+ }
+
+ @Override public void mkdir(String path, int mode) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.mkdir(path, mode);
+ }
+
+ @Override public void mkfifo(String path, int mode) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.mkfifo(path, mode);
+ }
+
@Override public FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
if ((mode & O_ACCMODE) != O_RDONLY) {
@@ -119,37 +195,47 @@ public class BlockGuardOs extends ForwardingOs {
return os.poll(fds, timeoutMs);
}
- @Override public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException {
+ @Override public void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.posix_fallocate(fd, offset, length);
+ }
+
+ @Override public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onReadFromDisk();
return os.pread(fd, buffer, offset);
}
- @Override public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException {
+ @Override public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onReadFromDisk();
return os.pread(fd, bytes, byteOffset, byteCount, offset);
}
- @Override public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException {
+ @Override public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onWriteToDisk();
return os.pwrite(fd, buffer, offset);
}
- @Override public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException {
+ @Override public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onWriteToDisk();
return os.pwrite(fd, bytes, byteOffset, byteCount, offset);
}
- @Override public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException {
+ @Override public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onReadFromDisk();
return os.read(fd, buffer);
}
- @Override public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException {
+ @Override public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onReadFromDisk();
return os.read(fd, bytes, byteOffset, byteCount);
}
- @Override public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException {
+ @Override public String readlink(String path) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ return os.readlink(path);
+ }
+
+ @Override public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onReadFromDisk();
return os.readv(fd, buffers, offsets, byteCounts);
}
@@ -164,6 +250,21 @@ public class BlockGuardOs extends ForwardingOs {
return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress);
}
+ @Override public void remove(String path) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.remove(path);
+ }
+
+ @Override public void rename(String oldPath, String newPath) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.rename(oldPath, newPath);
+ }
+
+ @Override public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ return os.sendfile(outFd, inFd, inOffset, byteCount);
+ }
+
@Override public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException {
BlockGuard.getThreadPolicy().onNetwork();
return os.sendto(fd, buffer, flags, inetAddress, port);
@@ -187,17 +288,32 @@ public class BlockGuardOs extends ForwardingOs {
tagSocket(fd2);
}
- @Override public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException {
+ @Override public StructStat stat(String path) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ return os.stat(path);
+ }
+
+ @Override public StructStatVfs statvfs(String path) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ return os.statvfs(path);
+ }
+
+ @Override public void symlink(String oldPath, String newPath) throws ErrnoException {
+ BlockGuard.getThreadPolicy().onWriteToDisk();
+ os.symlink(oldPath, newPath);
+ }
+
+ @Override public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onWriteToDisk();
return os.write(fd, buffer);
}
- @Override public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException {
+ @Override public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onWriteToDisk();
return os.write(fd, bytes, byteOffset, byteCount);
}
- @Override public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException {
+ @Override public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException {
BlockGuard.getThreadPolicy().onWriteToDisk();
return os.writev(fd, buffers, offsets, byteCounts);
}
diff --git a/luni/src/main/java/libcore/io/DeleteOnExit.java b/luni/src/main/java/libcore/io/DeleteOnExit.java
new file mode 100644
index 0000000..36d7948
--- /dev/null
+++ b/luni/src/main/java/libcore/io/DeleteOnExit.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Implements the actual DeleteOnExit mechanism. Is registered as a shutdown
+ * hook in the Runtime, once it is actually being used.
+ */
+public class DeleteOnExit extends Thread {
+
+ /**
+ * Our singleton instance.
+ */
+ private static DeleteOnExit instance;
+
+ /**
+ * Returns our singleton instance, creating it if necessary.
+ */
+ public static synchronized DeleteOnExit getInstance() {
+ if (instance == null) {
+ instance = new DeleteOnExit();
+ Runtime.getRuntime().addShutdownHook(instance);
+ }
+
+ return instance;
+ }
+
+ /**
+ * Our list of files scheduled for deletion.
+ */
+ private final ArrayList<String> files = new ArrayList<String>();
+
+
+ private DeleteOnExit() {
+ }
+
+ /**
+ * Schedules a file for deletion.
+ *
+ * @param filename The file to delete.
+ */
+ public void addFile(String filename) {
+ synchronized (files) {
+ if (!files.contains(filename)) {
+ files.add(filename);
+ }
+ }
+ }
+
+ /**
+ * Does the actual work. Note we (a) first sort the files lexicographically
+ * and then (b) delete them in reverse order. This is to make sure files
+ * get deleted before their parent directories.
+ */
+ @Override
+ public void run() {
+ Collections.sort(files);
+ for (int i = files.size() - 1; i >= 0; i--) {
+ new File(files.get(i)).delete();
+ }
+ }
+}
diff --git a/luni/src/main/java/libcore/io/ErrnoException.java b/luni/src/main/java/libcore/io/ErrnoException.java
deleted file mode 100644
index f484ce9..0000000
--- a/luni/src/main/java/libcore/io/ErrnoException.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-import java.io.IOException;
-import java.net.SocketException;
-
-/**
- * A checked exception thrown when {@link Os} methods fail. This exception contains the native
- * errno value, for comparison against the constants in {@link OsConstants}, should sophisticated
- * callers need to adjust their behavior based on the exact failure.
- */
-public final class ErrnoException extends Exception {
- private final String functionName;
- public final int errno;
-
- public ErrnoException(String functionName, int errno) {
- this.functionName = functionName;
- this.errno = errno;
- }
-
- public ErrnoException(String functionName, int errno, Throwable cause) {
- super(cause);
- this.functionName = functionName;
- this.errno = errno;
- }
-
- /**
- * Converts the stashed function name and errno value to a human-readable string.
- * We do this here rather than in the constructor so that callers only pay for
- * this if they need it.
- */
- @Override public String getMessage() {
- String errnoName = OsConstants.errnoName(errno);
- if (errnoName == null) {
- errnoName = "errno " + errno;
- }
- String description = Libcore.os.strerror(errno);
- return functionName + " failed: " + errnoName + " (" + description + ")";
- }
-
- public IOException rethrowAsIOException() throws IOException {
- IOException newException = new IOException(getMessage());
- newException.initCause(this);
- throw newException;
- }
-
- public SocketException rethrowAsSocketException() throws SocketException {
- throw new SocketException(getMessage(), this);
- }
-}
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index 3800416..bf4b448 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -16,14 +16,29 @@
package libcore.io;
+import android.system.ErrnoException;
+import android.system.GaiException;
+import android.system.StructAddrinfo;
+import android.system.StructFlock;
+import android.system.StructGroupReq;
+import android.system.StructGroupSourceReq;
+import android.system.StructLinger;
+import android.system.StructPasswd;
+import android.system.StructPollfd;
+import android.system.StructStat;
+import android.system.StructStatVfs;
+import android.system.StructTimeval;
+import android.system.StructUcred;
+import android.system.StructUtsname;
+import android.util.MutableInt;
+import android.util.MutableLong;
import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import libcore.util.MutableInt;
-import libcore.util.MutableLong;
/**
* Subclass this if you want to override some {@link Os} methods but otherwise delegate.
@@ -37,6 +52,7 @@ public class ForwardingOs implements Os {
public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { return os.accept(fd, peerAddress); }
public boolean access(String path, int mode) throws ErrnoException { return os.access(path, mode); }
+ public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return os.android_getaddrinfo(node, hints, netId); }
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); }
public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); }
public void chown(String path, int uid, int gid) throws ErrnoException { os.chown(path, uid, gid); }
@@ -58,7 +74,6 @@ public class ForwardingOs implements Os {
public void fsync(FileDescriptor fd) throws ErrnoException { os.fsync(fd); }
public void ftruncate(FileDescriptor fd, long length) throws ErrnoException { os.ftruncate(fd, length); }
public String gai_strerror(int error) { return os.gai_strerror(error); }
- public InetAddress[] getaddrinfo(String node, StructAddrinfo hints) throws GaiException { return os.getaddrinfo(node, hints); }
public int getegid() { return os.getegid(); }
public int geteuid() { return os.geteuid(); }
public int getgid() { return os.getgid(); }
@@ -85,11 +100,13 @@ public class ForwardingOs implements Os {
public boolean isatty(FileDescriptor fd) { return os.isatty(fd); }
public void kill(int pid, int signal) throws ErrnoException { os.kill(pid, signal); }
public void lchown(String path, int uid, int gid) throws ErrnoException { os.lchown(path, uid, gid); }
+ public void link(String oldPath, String newPath) throws ErrnoException { os.link(oldPath, newPath); }
public void listen(FileDescriptor fd, int backlog) throws ErrnoException { os.listen(fd, backlog); }
public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { return os.lseek(fd, offset, whence); }
public StructStat lstat(String path) throws ErrnoException { return os.lstat(path); }
public void mincore(long address, long byteCount, byte[] vector) throws ErrnoException { os.mincore(address, byteCount, vector); }
public void mkdir(String path, int mode) throws ErrnoException { os.mkdir(path, mode); }
+ public void mkfifo(String path, int mode) throws ErrnoException { os.mkfifo(path, mode); }
public void mlock(long address, long byteCount) throws ErrnoException { os.mlock(address, byteCount); }
public long mmap(long address, long byteCount, int prot, int flags, FileDescriptor fd, long offset) throws ErrnoException { return os.mmap(address, byteCount, prot, flags, fd, offset); }
public void msync(long address, long byteCount, int flags) throws ErrnoException { os.msync(address, byteCount, flags); }
@@ -98,13 +115,16 @@ public class ForwardingOs implements Os {
public FileDescriptor open(String path, int flags, int mode) throws ErrnoException { return os.open(path, flags, mode); }
public FileDescriptor[] pipe() throws ErrnoException { return os.pipe(); }
public int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException { return os.poll(fds, timeoutMs); }
- public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException { return os.pread(fd, buffer, offset); }
- public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException { return os.pread(fd, bytes, byteOffset, byteCount, offset); }
- public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException { return os.pwrite(fd, buffer, offset); }
- public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException { return os.pwrite(fd, bytes, byteOffset, byteCount, offset); }
- public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException { return os.read(fd, buffer); }
- public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException { return os.read(fd, bytes, byteOffset, byteCount); }
- public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException { return os.readv(fd, buffers, offsets, byteCounts); }
+ public void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException { os.posix_fallocate(fd, offset, length); }
+ public int prctl(int option, long arg2, long arg3, long arg4, long arg5) throws ErrnoException { return os.prctl(option, arg2, arg3, arg4, arg5); };
+ public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { return os.pread(fd, buffer, offset); }
+ public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { return os.pread(fd, bytes, byteOffset, byteCount, offset); }
+ public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { return os.pwrite(fd, buffer, offset); }
+ public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { return os.pwrite(fd, bytes, byteOffset, byteCount, offset); }
+ public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { return os.read(fd, buffer); }
+ public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { return os.read(fd, bytes, byteOffset, byteCount); }
+ public String readlink(String path) throws ErrnoException { return os.readlink(path); }
+ public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { return os.readv(fd, buffers, offsets, byteCounts); }
public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, buffer, flags, srcAddress); }
public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); }
public void remove(String path) throws ErrnoException { os.remove(path); }
@@ -122,6 +142,7 @@ public class ForwardingOs implements Os {
public void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException { os.setsockoptInt(fd, level, option, value); }
public void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException { os.setsockoptIpMreqn(fd, level, option, value); }
public void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException { os.setsockoptGroupReq(fd, level, option, value); }
+ public void setsockoptGroupSourceReq(FileDescriptor fd, int level, int option, StructGroupSourceReq value) throws ErrnoException { os.setsockoptGroupSourceReq(fd, level, option, value); }
public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { os.setsockoptLinger(fd, level, option, value); }
public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { os.setsockoptTimeval(fd, level, option, value); }
public void setuid(int uid) throws ErrnoException { os.setuid(uid); }
@@ -140,7 +161,7 @@ public class ForwardingOs implements Os {
public StructUtsname uname() { return os.uname(); }
public void unsetenv(String name) throws ErrnoException { os.unsetenv(name); }
public int waitpid(int pid, MutableInt status, int options) throws ErrnoException { return os.waitpid(pid, status, options); }
- public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException { return os.write(fd, buffer); }
- public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException { return os.write(fd, bytes, byteOffset, byteCount); }
- public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException { return os.writev(fd, buffers, offsets, byteCounts); }
+ public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { return os.write(fd, buffer); }
+ public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { return os.write(fd, bytes, byteOffset, byteCount); }
+ public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { return os.writev(fd, buffers, offsets, byteCounts); }
}
diff --git a/luni/src/main/java/libcore/io/GaiException.java b/luni/src/main/java/libcore/io/GaiException.java
deleted file mode 100644
index 08143dc..0000000
--- a/luni/src/main/java/libcore/io/GaiException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-import java.net.UnknownHostException;
-import libcore.io.OsConstants;
-
-/**
- * An unchecked exception thrown when the {@link Os} {@code getaddrinfo} or {@code getnameinfo}
- * methods fail. This exception contains the native error value, for comparison against the
- * {@code GAI_} constants in {@link OsConstants}, should sophisticated
- * callers need to adjust their behavior based on the exact failure.
- */
-public final class GaiException extends RuntimeException {
- private final String functionName;
- public final int error;
-
- public GaiException(String functionName, int error) {
- this.functionName = functionName;
- this.error = error;
- }
-
- public GaiException(String functionName, int error, Throwable cause) {
- super(cause);
- this.functionName = functionName;
- this.error = error;
- }
-
- /**
- * Converts the stashed function name and error value to a human-readable string.
- * We do this here rather than in the constructor so that callers only pay for
- * this if they need it.
- */
- @Override public String getMessage() {
- String gaiName = OsConstants.gaiName(error);
- if (gaiName == null) {
- gaiName = "GAI_ error " + error;
- }
- String description = Libcore.os.gai_strerror(error);
- return functionName + " failed: " + gaiName + " (" + description + ")";
- }
-
- public UnknownHostException rethrowAsUnknownHostException(String detailMessage) throws UnknownHostException {
- UnknownHostException newException = new UnknownHostException(detailMessage);
- newException.initCause(this);
- throw newException;
- }
-
- public UnknownHostException rethrowAsUnknownHostException() throws UnknownHostException {
- throw rethrowAsUnknownHostException(getMessage());
- }
-}
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index 28adba1..acc8d4f 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -16,6 +16,13 @@
package libcore.io;
+import android.system.ErrnoException;
+import android.system.StructGroupReq;
+import android.system.StructGroupSourceReq;
+import android.system.StructLinger;
+import android.system.StructPollfd;
+import android.system.StructTimeval;
+import android.util.MutableInt;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -35,8 +42,7 @@ import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Arrays;
-import static libcore.io.OsConstants.*;
-import libcore.util.MutableInt;
+import static android.system.OsConstants.*;
/**
* Implements java.io/java.net/java.nio semantics in terms of the underlying POSIX system calls.
@@ -71,16 +77,20 @@ public final class IoBridge {
public static void bind(FileDescriptor fd, InetAddress address, int port) throws SocketException {
- if (address instanceof Inet6Address && ((Inet6Address) address).getScopeId() == 0) {
- // Linux won't let you bind a link-local address without a scope id. Find one.
- NetworkInterface nif = NetworkInterface.getByInetAddress(address);
- if (nif == null) {
- throw new SocketException("Can't bind to a link-local address without a scope id: " + address);
- }
- try {
- address = Inet6Address.getByAddress(address.getHostName(), address.getAddress(), nif.getIndex());
- } catch (UnknownHostException ex) {
- throw new AssertionError(ex); // Can't happen.
+ if (address instanceof Inet6Address) {
+ Inet6Address inet6Address = (Inet6Address) address;
+ if (inet6Address.getScopeId() == 0 && inet6Address.isLinkLocalAddress()) {
+ // Linux won't let you bind a link-local address without a scope id.
+ // Find one.
+ NetworkInterface nif = NetworkInterface.getByInetAddress(address);
+ if (nif == null) {
+ throw new SocketException("Can't bind to a link-local address without a scope id: " + address);
+ }
+ try {
+ address = Inet6Address.getByAddress(address.getHostName(), address.getAddress(), nif.getIndex());
+ } catch (UnknownHostException ex) {
+ throw new AssertionError(ex); // Can't happen.
+ }
}
}
try {
@@ -95,9 +105,9 @@ public final class IoBridge {
* Connects socket 'fd' to 'inetAddress' on 'port', with no timeout. The lack of a timeout
* means this method won't throw SocketTimeoutException.
*/
- public static boolean connect(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException {
+ public static void connect(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException {
try {
- return IoBridge.connect(fd, inetAddress, port, 0);
+ IoBridge.connect(fd, inetAddress, port, 0);
} catch (SocketTimeoutException ex) {
throw new AssertionError(ex); // Can't happen for a connect without a timeout.
}
@@ -107,9 +117,9 @@ public final class IoBridge {
* Connects socket 'fd' to 'inetAddress' on 'port', with a the given 'timeoutMs'.
* Use timeoutMs == 0 for a blocking connect with no timeout.
*/
- public static boolean connect(FileDescriptor fd, InetAddress inetAddress, int port, int timeoutMs) throws SocketException, SocketTimeoutException {
+ public static void connect(FileDescriptor fd, InetAddress inetAddress, int port, int timeoutMs) throws SocketException, SocketTimeoutException {
try {
- return connectErrno(fd, inetAddress, port, timeoutMs);
+ connectErrno(fd, inetAddress, port, timeoutMs);
} catch (ErrnoException errnoException) {
throw new ConnectException(connectDetail(inetAddress, port, timeoutMs, errnoException), errnoException);
} catch (SocketException ex) {
@@ -121,11 +131,11 @@ public final class IoBridge {
}
}
- private static boolean connectErrno(FileDescriptor fd, InetAddress inetAddress, int port, int timeoutMs) throws ErrnoException, IOException {
+ private static void connectErrno(FileDescriptor fd, InetAddress inetAddress, int port, int timeoutMs) throws ErrnoException, IOException {
// With no timeout, just call connect(2) directly.
if (timeoutMs == 0) {
Libcore.os.connect(fd, inetAddress, port);
- return true;
+ return;
}
// For connect with a timeout, we:
@@ -143,7 +153,7 @@ public final class IoBridge {
try {
Libcore.os.connect(fd, inetAddress, port);
IoUtils.setBlocking(fd, true); // 4. set the socket back to blocking.
- return true; // We connected immediately.
+ return; // We connected immediately.
} catch (ErrnoException errnoException) {
if (errnoException.errno != EINPROGRESS) {
throw errnoException;
@@ -160,7 +170,6 @@ public final class IoBridge {
}
} while (!IoBridge.isConnected(fd, inetAddress, port, timeoutMs, remainingTimeoutMs));
IoUtils.setBlocking(fd, true); // 4. set the socket back to blocking.
- return true; // Or we'd have thrown.
}
private static String connectDetail(InetAddress inetAddress, int port, int timeoutMs, ErrnoException cause) {
@@ -174,9 +183,15 @@ public final class IoBridge {
return detail;
}
- public static void closeSocket(FileDescriptor fd) throws IOException {
- if (!fd.valid()) {
- // Socket.close doesn't throw if you try to close an already-closed socket.
+ /**
+ * Closes the supplied file descriptor and sends a signal to any threads are currently blocking.
+ * In order for the signal to be sent the blocked threads must have registered with
+ * the AsynchronousCloseMonitor before they entered the blocking operation.
+ *
+ * <p>This method is a no-op if passed a {@code null} or already-closed file descriptor.
+ */
+ public static void closeAndSignalBlockedThreads(FileDescriptor fd) throws IOException {
+ if (fd == null || !fd.valid()) {
return;
}
int intFd = fd.getInt$();
@@ -226,6 +241,10 @@ public final class IoBridge {
// Socket options used by java.net but not exposed in SocketOptions.
public static final int JAVA_MCAST_JOIN_GROUP = 19;
public static final int JAVA_MCAST_LEAVE_GROUP = 20;
+ public static final int JAVA_MCAST_JOIN_SOURCE_GROUP = 21;
+ public static final int JAVA_MCAST_LEAVE_SOURCE_GROUP = 22;
+ public static final int JAVA_MCAST_BLOCK_SOURCE = 23;
+ public static final int JAVA_MCAST_UNBLOCK_SOURCE = 24;
public static final int JAVA_IP_MULTICAST_TTL = 17;
/**
@@ -369,16 +388,46 @@ public final class IoBridge {
return;
case IoBridge.JAVA_MCAST_JOIN_GROUP:
case IoBridge.JAVA_MCAST_LEAVE_GROUP:
+ {
StructGroupReq groupReq = (StructGroupReq) value;
int level = (groupReq.gr_group instanceof Inet4Address) ? IPPROTO_IP : IPPROTO_IPV6;
int op = (option == JAVA_MCAST_JOIN_GROUP) ? MCAST_JOIN_GROUP : MCAST_LEAVE_GROUP;
Libcore.os.setsockoptGroupReq(fd, level, op, groupReq);
return;
+ }
+ case IoBridge.JAVA_MCAST_JOIN_SOURCE_GROUP:
+ case IoBridge.JAVA_MCAST_LEAVE_SOURCE_GROUP:
+ case IoBridge.JAVA_MCAST_BLOCK_SOURCE:
+ case IoBridge.JAVA_MCAST_UNBLOCK_SOURCE:
+ {
+ StructGroupSourceReq groupSourceReq = (StructGroupSourceReq) value;
+ int level = (groupSourceReq.gsr_group instanceof Inet4Address)
+ ? IPPROTO_IP : IPPROTO_IPV6;
+ int op = getGroupSourceReqOp(option);
+ Libcore.os.setsockoptGroupSourceReq(fd, level, op, groupSourceReq);
+ return;
+ }
default:
throw new SocketException("Unknown socket option: " + option);
}
}
+ private static int getGroupSourceReqOp(int javaValue) {
+ switch (javaValue) {
+ case IoBridge.JAVA_MCAST_JOIN_SOURCE_GROUP:
+ return MCAST_JOIN_SOURCE_GROUP;
+ case IoBridge.JAVA_MCAST_LEAVE_SOURCE_GROUP:
+ return MCAST_LEAVE_SOURCE_GROUP;
+ case IoBridge.JAVA_MCAST_BLOCK_SOURCE:
+ return MCAST_BLOCK_SOURCE;
+ case IoBridge.JAVA_MCAST_UNBLOCK_SOURCE:
+ return MCAST_UNBLOCK_SOURCE;
+ default:
+ throw new AssertionError(
+ "Unknown java value for setsocketopt op lookup: " + javaValue);
+ }
+ }
+
/**
* java.io only throws FileNotFoundException when opening files, regardless of what actually
* went wrong. Additionally, java.io is more restrictive than POSIX when it comes to opening
@@ -391,12 +440,10 @@ public final class IoBridge {
// On Android, we don't want default permissions to allow global access.
int mode = ((flags & O_ACCMODE) == O_RDONLY) ? 0 : 0600;
fd = Libcore.os.open(path, flags, mode);
- if (fd.valid()) {
- // Posix open(2) fails with EISDIR only if you ask for write permission.
- // Java disallows reading directories too.
- if (S_ISDIR(Libcore.os.fstat(fd).st_mode)) {
- throw new ErrnoException("open", EISDIR);
- }
+ // Posix open(2) fails with EISDIR only if you ask for write permission.
+ // Java disallows reading directories too.
+ if (S_ISDIR(Libcore.os.fstat(fd).st_mode)) {
+ throw new ErrnoException("open", EISDIR);
}
return fd;
} catch (ErrnoException errnoException) {
diff --git a/luni/src/main/java/libcore/io/IoUtils.java b/luni/src/main/java/libcore/io/IoUtils.java
index 10ef671..5a19f17 100644
--- a/luni/src/main/java/libcore/io/IoUtils.java
+++ b/luni/src/main/java/libcore/io/IoUtils.java
@@ -16,6 +16,8 @@
package libcore.io;
+import android.system.ErrnoException;
+import android.system.StructStat;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
@@ -25,7 +27,7 @@ import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Random;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
public final class IoUtils {
private static final Random TEMPORARY_DIRECTORY_PRNG = new Random();
diff --git a/luni/src/main/java/libcore/io/Memory.java b/luni/src/main/java/libcore/io/Memory.java
index 5743949..e148457 100644
--- a/luni/src/main/java/libcore/io/Memory.java
+++ b/luni/src/main/java/libcore/io/Memory.java
@@ -151,9 +151,33 @@ public final class Memory {
public static native void memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount);
public static native byte peekByte(long address);
- public static native int peekInt(long address, boolean swap);
- public static native long peekLong(long address, boolean swap);
- public static native short peekShort(long address, boolean swap);
+
+ public static int peekInt(long address, boolean swap) {
+ int result = peekIntNative(address);
+ if (swap) {
+ result = Integer.reverseBytes(result);
+ }
+ return result;
+ }
+ private static native int peekIntNative(long address);
+
+ public static long peekLong(long address, boolean swap) {
+ long result = peekLongNative(address);
+ if (swap) {
+ result = Long.reverseBytes(result);
+ }
+ return result;
+ }
+ private static native long peekLongNative(long address);
+
+ public static short peekShort(long address, boolean swap) {
+ short result = peekShortNative(address);
+ if (swap) {
+ result = Short.reverseBytes(result);
+ }
+ return result;
+ }
+ private static native short peekShortNative(long address);
public static native void peekByteArray(long address, byte[] dst, int dstOffset, int byteCount);
public static native void peekCharArray(long address, char[] dst, int dstOffset, int charCount, boolean swap);
@@ -164,9 +188,30 @@ public final class Memory {
public static native void peekShortArray(long address, short[] dst, int dstOffset, int shortCount, boolean swap);
public static native void pokeByte(long address, byte value);
- public static native void pokeInt(long address, int value, boolean swap);
- public static native void pokeLong(long address, long value, boolean swap);
- public static native void pokeShort(long address, short value, boolean swap);
+
+ public static void pokeInt(long address, int value, boolean swap) {
+ if (swap) {
+ value = Integer.reverseBytes(value);
+ }
+ pokeIntNative(address, value);
+ }
+ private static native void pokeIntNative(long address, int value);
+
+ public static void pokeLong(long address, long value, boolean swap) {
+ if (swap) {
+ value = Long.reverseBytes(value);
+ }
+ pokeLongNative(address, value);
+ }
+ private static native void pokeLongNative(long address, long value);
+
+ public static void pokeShort(long address, short value, boolean swap) {
+ if (swap) {
+ value = Short.reverseBytes(value);
+ }
+ pokeShortNative(address, value);
+ }
+ private static native void pokeShortNative(long address, short value);
public static native void pokeByteArray(long address, byte[] src, int offset, int count);
public static native void pokeCharArray(long address, char[] src, int offset, int count, boolean swap);
diff --git a/luni/src/main/java/libcore/io/MemoryMappedFile.java b/luni/src/main/java/libcore/io/MemoryMappedFile.java
index 2d8aa2b..b4cd8fc 100644
--- a/luni/src/main/java/libcore/io/MemoryMappedFile.java
+++ b/luni/src/main/java/libcore/io/MemoryMappedFile.java
@@ -16,16 +16,16 @@
package libcore.io;
+import android.system.ErrnoException;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteOrder;
-import java.nio.NioUtils;
import java.nio.channels.FileChannel;
-import libcore.io.ErrnoException;
+import java.nio.NioUtils;
import libcore.io.Libcore;
import libcore.io.Memory;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
/**
* A memory-mapped file. Use {@link #mmap} to map a file, {@link #close} to unmap a file,
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 2b68027..511bb27 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -16,18 +16,34 @@
package libcore.io;
+import android.system.ErrnoException;
+import android.system.GaiException;
+import android.system.StructAddrinfo;
+import android.system.StructFlock;
+import android.system.StructGroupReq;
+import android.system.StructGroupSourceReq;
+import android.system.StructLinger;
+import android.system.StructPasswd;
+import android.system.StructPollfd;
+import android.system.StructStat;
+import android.system.StructStatVfs;
+import android.system.StructTimeval;
+import android.system.StructUcred;
+import android.system.StructUtsname;
+import android.util.MutableInt;
+import android.util.MutableLong;
import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import libcore.util.MutableInt;
-import libcore.util.MutableLong;
public interface Os {
public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException;
public boolean access(String path, int mode) throws ErrnoException;
+ public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public void chmod(String path, int mode) throws ErrnoException;
public void chown(String path, int uid, int gid) throws ErrnoException;
@@ -49,7 +65,6 @@ public interface Os {
public void fsync(FileDescriptor fd) throws ErrnoException;
public void ftruncate(FileDescriptor fd, long length) throws ErrnoException;
public String gai_strerror(int error);
- public InetAddress[] getaddrinfo(String node, StructAddrinfo hints) throws GaiException;
public int getegid();
public int geteuid();
public int getgid();
@@ -77,11 +92,13 @@ public interface Os {
public boolean isatty(FileDescriptor fd);
public void kill(int pid, int signal) throws ErrnoException;
public void lchown(String path, int uid, int gid) throws ErrnoException;
+ public void link(String oldPath, String newPath) throws ErrnoException;
public void listen(FileDescriptor fd, int backlog) throws ErrnoException;
public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException;
public StructStat lstat(String path) throws ErrnoException;
public void mincore(long address, long byteCount, byte[] vector) throws ErrnoException;
public void mkdir(String path, int mode) throws ErrnoException;
+ public void mkfifo(String path, int mode) throws ErrnoException;
public void mlock(long address, long byteCount) throws ErrnoException;
public long mmap(long address, long byteCount, int prot, int flags, FileDescriptor fd, long offset) throws ErrnoException;
public void msync(long address, long byteCount, int flags) throws ErrnoException;
@@ -91,13 +108,16 @@ public interface Os {
public FileDescriptor[] pipe() throws ErrnoException;
/* TODO: if we used the non-standard ppoll(2) behind the scenes, we could take a long timeout. */
public int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException;
- public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException;
- public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException;
- public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException;
- public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException;
- public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException;
- public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException;
- public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException;
+ public void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException;
+ public int prctl(int option, long arg2, long arg3, long arg4, long arg5) throws ErrnoException;
+ public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException;
+ public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException;
+ public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException;
+ public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException;
+ public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException;
+ public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException;
+ public String readlink(String path) throws ErrnoException;
+ public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException;
public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException;
public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException;
public void remove(String path) throws ErrnoException;
@@ -115,6 +135,7 @@ public interface Os {
public void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
public void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
public void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException;
+ public void setsockoptGroupSourceReq(FileDescriptor fd, int level, int option, StructGroupSourceReq value) throws ErrnoException;
public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException;
public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException;
public void setuid(int uid) throws ErrnoException;
@@ -133,7 +154,7 @@ public interface Os {
public StructUtsname uname();
public void unsetenv(String name) throws ErrnoException;
public int waitpid(int pid, MutableInt status, int options) throws ErrnoException;
- public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException;
- public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException;
- public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException;
+ public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException;
+ public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException;
+ public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException;
}
diff --git a/luni/src/main/java/libcore/io/OsConstants.java b/luni/src/main/java/libcore/io/OsConstants.java
deleted file mode 100644
index edecdd9..0000000
--- a/luni/src/main/java/libcore/io/OsConstants.java
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-public final class OsConstants {
- private OsConstants() { }
-
- public static boolean S_ISBLK(int mode) { return (mode & S_IFMT) == S_IFBLK; }
- public static boolean S_ISCHR(int mode) { return (mode & S_IFMT) == S_IFCHR; }
- public static boolean S_ISDIR(int mode) { return (mode & S_IFMT) == S_IFDIR; }
- public static boolean S_ISFIFO(int mode) { return (mode & S_IFMT) == S_IFIFO; }
- public static boolean S_ISREG(int mode) { return (mode & S_IFMT) == S_IFREG; }
- public static boolean S_ISLNK(int mode) { return (mode & S_IFMT) == S_IFLNK; }
- public static boolean S_ISSOCK(int mode) { return (mode & S_IFMT) == S_IFSOCK; }
-
- public static int WEXITSTATUS(int status) { return (status & 0xff00) >> 8; }
- public static boolean WCOREDUMP(int status) { return (status & 0x80) != 0; }
- public static int WTERMSIG(int status) { return status & 0x7f; }
- public static int WSTOPSIG(int status) { return WEXITSTATUS(status); }
- public static boolean WIFEXITED(int status) { return (WTERMSIG(status) == 0); }
- public static boolean WIFSTOPPED(int status) { return (WTERMSIG(status) == 0x7f); }
- public static boolean WIFSIGNALED(int status) { return (WTERMSIG(status + 1) >= 2); }
-
- public static final int AF_INET = placeholder();
- public static final int AF_INET6 = placeholder();
- public static final int AF_UNIX = placeholder();
- public static final int AF_UNSPEC = placeholder();
- public static final int AI_ADDRCONFIG = placeholder();
- public static final int AI_ALL = placeholder();
- public static final int AI_CANONNAME = placeholder();
- public static final int AI_NUMERICHOST = placeholder();
- public static final int AI_NUMERICSERV = placeholder();
- public static final int AI_PASSIVE = placeholder();
- public static final int AI_V4MAPPED = placeholder();
- public static final int CAP_AUDIT_CONTROL = placeholder();
- public static final int CAP_AUDIT_WRITE = placeholder();
- public static final int CAP_CHOWN = placeholder();
- public static final int CAP_DAC_OVERRIDE = placeholder();
- public static final int CAP_DAC_READ_SEARCH = placeholder();
- public static final int CAP_FOWNER = placeholder();
- public static final int CAP_FSETID = placeholder();
- public static final int CAP_IPC_LOCK = placeholder();
- public static final int CAP_IPC_OWNER = placeholder();
- public static final int CAP_KILL = placeholder();
- public static final int CAP_LAST_CAP = placeholder();
- public static final int CAP_LEASE = placeholder();
- public static final int CAP_LINUX_IMMUTABLE = placeholder();
- public static final int CAP_MAC_ADMIN = placeholder();
- public static final int CAP_MAC_OVERRIDE = placeholder();
- public static final int CAP_MKNOD = placeholder();
- public static final int CAP_NET_ADMIN = placeholder();
- public static final int CAP_NET_BIND_SERVICE = placeholder();
- public static final int CAP_NET_BROADCAST = placeholder();
- public static final int CAP_NET_RAW = placeholder();
- public static final int CAP_SETFCAP = placeholder();
- public static final int CAP_SETGID = placeholder();
- public static final int CAP_SETPCAP = placeholder();
- public static final int CAP_SETUID = placeholder();
- public static final int CAP_SYS_ADMIN = placeholder();
- public static final int CAP_SYS_BOOT = placeholder();
- public static final int CAP_SYS_CHROOT = placeholder();
- public static final int CAP_SYSLOG = placeholder();
- public static final int CAP_SYS_MODULE = placeholder();
- public static final int CAP_SYS_NICE = placeholder();
- public static final int CAP_SYS_PACCT = placeholder();
- public static final int CAP_SYS_PTRACE = placeholder();
- public static final int CAP_SYS_RAWIO = placeholder();
- public static final int CAP_SYS_RESOURCE = placeholder();
- public static final int CAP_SYS_TIME = placeholder();
- public static final int CAP_SYS_TTY_CONFIG = placeholder();
- public static final int CAP_WAKE_ALARM = placeholder();
- public static final int E2BIG = placeholder();
- public static final int EACCES = placeholder();
- public static final int EADDRINUSE = placeholder();
- public static final int EADDRNOTAVAIL = placeholder();
- public static final int EAFNOSUPPORT = placeholder();
- public static final int EAGAIN = placeholder();
- public static final int EAI_AGAIN = placeholder();
- public static final int EAI_BADFLAGS = placeholder();
- public static final int EAI_FAIL = placeholder();
- public static final int EAI_FAMILY = placeholder();
- public static final int EAI_MEMORY = placeholder();
- public static final int EAI_NODATA = placeholder();
- public static final int EAI_NONAME = placeholder();
- public static final int EAI_OVERFLOW = placeholder();
- public static final int EAI_SERVICE = placeholder();
- public static final int EAI_SOCKTYPE = placeholder();
- public static final int EAI_SYSTEM = placeholder();
- public static final int EALREADY = placeholder();
- public static final int EBADF = placeholder();
- public static final int EBADMSG = placeholder();
- public static final int EBUSY = placeholder();
- public static final int ECANCELED = placeholder();
- public static final int ECHILD = placeholder();
- public static final int ECONNABORTED = placeholder();
- public static final int ECONNREFUSED = placeholder();
- public static final int ECONNRESET = placeholder();
- public static final int EDEADLK = placeholder();
- public static final int EDESTADDRREQ = placeholder();
- public static final int EDOM = placeholder();
- public static final int EDQUOT = placeholder();
- public static final int EEXIST = placeholder();
- public static final int EFAULT = placeholder();
- public static final int EFBIG = placeholder();
- public static final int EHOSTUNREACH = placeholder();
- public static final int EIDRM = placeholder();
- public static final int EILSEQ = placeholder();
- public static final int EINPROGRESS = placeholder();
- public static final int EINTR = placeholder();
- public static final int EINVAL = placeholder();
- public static final int EIO = placeholder();
- public static final int EISCONN = placeholder();
- public static final int EISDIR = placeholder();
- public static final int ELOOP = placeholder();
- public static final int EMFILE = placeholder();
- public static final int EMLINK = placeholder();
- public static final int EMSGSIZE = placeholder();
- public static final int EMULTIHOP = placeholder();
- public static final int ENAMETOOLONG = placeholder();
- public static final int ENETDOWN = placeholder();
- public static final int ENETRESET = placeholder();
- public static final int ENETUNREACH = placeholder();
- public static final int ENFILE = placeholder();
- public static final int ENOBUFS = placeholder();
- public static final int ENODATA = placeholder();
- public static final int ENODEV = placeholder();
- public static final int ENOENT = placeholder();
- public static final int ENOEXEC = placeholder();
- public static final int ENOLCK = placeholder();
- public static final int ENOLINK = placeholder();
- public static final int ENOMEM = placeholder();
- public static final int ENOMSG = placeholder();
- public static final int ENOPROTOOPT = placeholder();
- public static final int ENOSPC = placeholder();
- public static final int ENOSR = placeholder();
- public static final int ENOSTR = placeholder();
- public static final int ENOSYS = placeholder();
- public static final int ENOTCONN = placeholder();
- public static final int ENOTDIR = placeholder();
- public static final int ENOTEMPTY = placeholder();
- public static final int ENOTSOCK = placeholder();
- public static final int ENOTSUP = placeholder();
- public static final int ENOTTY = placeholder();
- public static final int ENXIO = placeholder();
- public static final int EOPNOTSUPP = placeholder();
- public static final int EOVERFLOW = placeholder();
- public static final int EPERM = placeholder();
- public static final int EPIPE = placeholder();
- public static final int EPROTO = placeholder();
- public static final int EPROTONOSUPPORT = placeholder();
- public static final int EPROTOTYPE = placeholder();
- public static final int ERANGE = placeholder();
- public static final int EROFS = placeholder();
- public static final int ESPIPE = placeholder();
- public static final int ESRCH = placeholder();
- public static final int ESTALE = placeholder();
- public static final int ETIME = placeholder();
- public static final int ETIMEDOUT = placeholder();
- public static final int ETXTBSY = placeholder();
- // On Linux, EWOULDBLOCK == EAGAIN. Use EAGAIN instead, to reduce confusion.
- public static final int EXDEV = placeholder();
- public static final int EXIT_FAILURE = placeholder();
- public static final int EXIT_SUCCESS = placeholder();
- public static final int FD_CLOEXEC = placeholder();
- public static final int FIONREAD = placeholder();
- public static final int F_DUPFD = placeholder();
- public static final int F_GETFD = placeholder();
- public static final int F_GETFL = placeholder();
- public static final int F_GETLK = placeholder();
- public static final int F_GETLK64 = placeholder();
- public static final int F_GETOWN = placeholder();
- public static final int F_OK = placeholder();
- public static final int F_RDLCK = placeholder();
- public static final int F_SETFD = placeholder();
- public static final int F_SETFL = placeholder();
- public static final int F_SETLK = placeholder();
- public static final int F_SETLK64 = placeholder();
- public static final int F_SETLKW = placeholder();
- public static final int F_SETLKW64 = placeholder();
- public static final int F_SETOWN = placeholder();
- public static final int F_UNLCK = placeholder();
- public static final int F_WRLCK = placeholder();
- public static final int IFF_ALLMULTI = placeholder();
- public static final int IFF_AUTOMEDIA = placeholder();
- public static final int IFF_BROADCAST = placeholder();
- public static final int IFF_DEBUG = placeholder();
- public static final int IFF_DYNAMIC = placeholder();
- public static final int IFF_LOOPBACK = placeholder();
- public static final int IFF_MASTER = placeholder();
- public static final int IFF_MULTICAST = placeholder();
- public static final int IFF_NOARP = placeholder();
- public static final int IFF_NOTRAILERS = placeholder();
- public static final int IFF_POINTOPOINT = placeholder();
- public static final int IFF_PORTSEL = placeholder();
- public static final int IFF_PROMISC = placeholder();
- public static final int IFF_RUNNING = placeholder();
- public static final int IFF_SLAVE = placeholder();
- public static final int IFF_UP = placeholder();
- public static final int IPPROTO_ICMP = placeholder();
- public static final int IPPROTO_ICMPV6 = placeholder();
- public static final int IPPROTO_IP = placeholder();
- public static final int IPPROTO_IPV6 = placeholder();
- public static final int IPPROTO_RAW = placeholder();
- public static final int IPPROTO_TCP = placeholder();
- public static final int IPPROTO_UDP = placeholder();
- public static final int IPV6_CHECKSUM = placeholder();
- public static final int IPV6_MULTICAST_HOPS = placeholder();
- public static final int IPV6_MULTICAST_IF = placeholder();
- public static final int IPV6_MULTICAST_LOOP = placeholder();
- public static final int IPV6_RECVDSTOPTS = placeholder();
- public static final int IPV6_RECVHOPLIMIT = placeholder();
- public static final int IPV6_RECVHOPOPTS = placeholder();
- public static final int IPV6_RECVPKTINFO = placeholder();
- public static final int IPV6_RECVRTHDR = placeholder();
- public static final int IPV6_RECVTCLASS = placeholder();
- public static final int IPV6_TCLASS = placeholder();
- public static final int IPV6_UNICAST_HOPS = placeholder();
- public static final int IPV6_V6ONLY = placeholder();
- public static final int IP_MULTICAST_IF = placeholder();
- public static final int IP_MULTICAST_LOOP = placeholder();
- public static final int IP_MULTICAST_TTL = placeholder();
- public static final int IP_TOS = placeholder();
- public static final int IP_TTL = placeholder();
- public static final int MAP_FIXED = placeholder();
- public static final int MAP_PRIVATE = placeholder();
- public static final int MAP_SHARED = placeholder();
- public static final int MCAST_JOIN_GROUP = placeholder();
- public static final int MCAST_LEAVE_GROUP = placeholder();
- public static final int MCL_CURRENT = placeholder();
- public static final int MCL_FUTURE = placeholder();
- public static final int MSG_CTRUNC = placeholder();
- public static final int MSG_DONTROUTE = placeholder();
- public static final int MSG_EOR = placeholder();
- public static final int MSG_OOB = placeholder();
- public static final int MSG_PEEK = placeholder();
- public static final int MSG_TRUNC = placeholder();
- public static final int MSG_WAITALL = placeholder();
- public static final int MS_ASYNC = placeholder();
- public static final int MS_INVALIDATE = placeholder();
- public static final int MS_SYNC = placeholder();
- public static final int NI_DGRAM = placeholder();
- public static final int NI_NAMEREQD = placeholder();
- public static final int NI_NOFQDN = placeholder();
- public static final int NI_NUMERICHOST = placeholder();
- public static final int NI_NUMERICSERV = placeholder();
- public static final int O_ACCMODE = placeholder();
- public static final int O_APPEND = placeholder();
- public static final int O_CREAT = placeholder();
- public static final int O_EXCL = placeholder();
- public static final int O_NOCTTY = placeholder();
- public static final int O_NOFOLLOW = placeholder();
- public static final int O_NONBLOCK = placeholder();
- public static final int O_RDONLY = placeholder();
- public static final int O_RDWR = placeholder();
- public static final int O_SYNC = placeholder();
- public static final int O_TRUNC = placeholder();
- public static final int O_WRONLY = placeholder();
- public static final int POLLERR = placeholder();
- public static final int POLLHUP = placeholder();
- public static final int POLLIN = placeholder();
- public static final int POLLNVAL = placeholder();
- public static final int POLLOUT = placeholder();
- public static final int POLLPRI = placeholder();
- public static final int POLLRDBAND = placeholder();
- public static final int POLLRDNORM = placeholder();
- public static final int POLLWRBAND = placeholder();
- public static final int POLLWRNORM = placeholder();
- public static final int PROT_EXEC = placeholder();
- public static final int PROT_NONE = placeholder();
- public static final int PROT_READ = placeholder();
- public static final int PROT_WRITE = placeholder();
- public static final int R_OK = placeholder();
- public static final int SEEK_CUR = placeholder();
- public static final int SEEK_END = placeholder();
- public static final int SEEK_SET = placeholder();
- public static final int SHUT_RD = placeholder();
- public static final int SHUT_RDWR = placeholder();
- public static final int SHUT_WR = placeholder();
- public static final int SIGABRT = placeholder();
- public static final int SIGALRM = placeholder();
- public static final int SIGBUS = placeholder();
- public static final int SIGCHLD = placeholder();
- public static final int SIGCONT = placeholder();
- public static final int SIGFPE = placeholder();
- public static final int SIGHUP = placeholder();
- public static final int SIGILL = placeholder();
- public static final int SIGINT = placeholder();
- public static final int SIGIO = placeholder();
- public static final int SIGKILL = placeholder();
- public static final int SIGPIPE = placeholder();
- public static final int SIGPROF = placeholder();
- public static final int SIGPWR = placeholder();
- public static final int SIGQUIT = placeholder();
- public static final int SIGRTMAX = placeholder();
- public static final int SIGRTMIN = placeholder();
- public static final int SIGSEGV = placeholder();
- public static final int SIGSTKFLT = placeholder();
- public static final int SIGSTOP = placeholder();
- public static final int SIGSYS = placeholder();
- public static final int SIGTERM = placeholder();
- public static final int SIGTRAP = placeholder();
- public static final int SIGTSTP = placeholder();
- public static final int SIGTTIN = placeholder();
- public static final int SIGTTOU = placeholder();
- public static final int SIGURG = placeholder();
- public static final int SIGUSR1 = placeholder();
- public static final int SIGUSR2 = placeholder();
- public static final int SIGVTALRM = placeholder();
- public static final int SIGWINCH = placeholder();
- public static final int SIGXCPU = placeholder();
- public static final int SIGXFSZ = placeholder();
- public static final int SIOCGIFADDR = placeholder();
- public static final int SIOCGIFBRDADDR = placeholder();
- public static final int SIOCGIFDSTADDR = placeholder();
- public static final int SIOCGIFNETMASK = placeholder();
- public static final int SOCK_DGRAM = placeholder();
- public static final int SOCK_RAW = placeholder();
- public static final int SOCK_SEQPACKET = placeholder();
- public static final int SOCK_STREAM = placeholder();
- public static final int SOL_SOCKET = placeholder();
- public static final int SO_BINDTODEVICE = placeholder();
- public static final int SO_BROADCAST = placeholder();
- public static final int SO_DEBUG = placeholder();
- public static final int SO_DONTROUTE = placeholder();
- public static final int SO_ERROR = placeholder();
- public static final int SO_KEEPALIVE = placeholder();
- public static final int SO_LINGER = placeholder();
- public static final int SO_OOBINLINE = placeholder();
- public static final int SO_PASSCRED = placeholder();
- public static final int SO_PEERCRED = placeholder();
- public static final int SO_RCVBUF = placeholder();
- public static final int SO_RCVLOWAT = placeholder();
- public static final int SO_RCVTIMEO = placeholder();
- public static final int SO_REUSEADDR = placeholder();
- public static final int SO_SNDBUF = placeholder();
- public static final int SO_SNDLOWAT = placeholder();
- public static final int SO_SNDTIMEO = placeholder();
- public static final int SO_TYPE = placeholder();
- public static final int STDERR_FILENO = placeholder();
- public static final int STDIN_FILENO = placeholder();
- public static final int STDOUT_FILENO = placeholder();
- public static final int S_IFBLK = placeholder();
- public static final int S_IFCHR = placeholder();
- public static final int S_IFDIR = placeholder();
- public static final int S_IFIFO = placeholder();
- public static final int S_IFLNK = placeholder();
- public static final int S_IFMT = placeholder();
- public static final int S_IFREG = placeholder();
- public static final int S_IFSOCK = placeholder();
- public static final int S_IRGRP = placeholder();
- public static final int S_IROTH = placeholder();
- public static final int S_IRUSR = placeholder();
- public static final int S_IRWXG = placeholder();
- public static final int S_IRWXO = placeholder();
- public static final int S_IRWXU = placeholder();
- public static final int S_ISGID = placeholder();
- public static final int S_ISUID = placeholder();
- public static final int S_ISVTX = placeholder();
- public static final int S_IWGRP = placeholder();
- public static final int S_IWOTH = placeholder();
- public static final int S_IWUSR = placeholder();
- public static final int S_IXGRP = placeholder();
- public static final int S_IXOTH = placeholder();
- public static final int S_IXUSR = placeholder();
- public static final int TCP_NODELAY = placeholder();
- public static final int WCONTINUED = placeholder();
- public static final int WEXITED = placeholder();
- public static final int WNOHANG = placeholder();
- public static final int WNOWAIT = placeholder();
- public static final int WSTOPPED = placeholder();
- public static final int WUNTRACED = placeholder();
- public static final int W_OK = placeholder();
- public static final int X_OK = placeholder();
- public static final int _SC_2_CHAR_TERM = placeholder();
- public static final int _SC_2_C_BIND = placeholder();
- public static final int _SC_2_C_DEV = placeholder();
- public static final int _SC_2_C_VERSION = placeholder();
- public static final int _SC_2_FORT_DEV = placeholder();
- public static final int _SC_2_FORT_RUN = placeholder();
- public static final int _SC_2_LOCALEDEF = placeholder();
- public static final int _SC_2_SW_DEV = placeholder();
- public static final int _SC_2_UPE = placeholder();
- public static final int _SC_2_VERSION = placeholder();
- public static final int _SC_AIO_LISTIO_MAX = placeholder();
- public static final int _SC_AIO_MAX = placeholder();
- public static final int _SC_AIO_PRIO_DELTA_MAX = placeholder();
- public static final int _SC_ARG_MAX = placeholder();
- public static final int _SC_ASYNCHRONOUS_IO = placeholder();
- public static final int _SC_ATEXIT_MAX = placeholder();
- public static final int _SC_AVPHYS_PAGES = placeholder();
- public static final int _SC_BC_BASE_MAX = placeholder();
- public static final int _SC_BC_DIM_MAX = placeholder();
- public static final int _SC_BC_SCALE_MAX = placeholder();
- public static final int _SC_BC_STRING_MAX = placeholder();
- public static final int _SC_CHILD_MAX = placeholder();
- public static final int _SC_CLK_TCK = placeholder();
- public static final int _SC_COLL_WEIGHTS_MAX = placeholder();
- public static final int _SC_DELAYTIMER_MAX = placeholder();
- public static final int _SC_EXPR_NEST_MAX = placeholder();
- public static final int _SC_FSYNC = placeholder();
- public static final int _SC_GETGR_R_SIZE_MAX = placeholder();
- public static final int _SC_GETPW_R_SIZE_MAX = placeholder();
- public static final int _SC_IOV_MAX = placeholder();
- public static final int _SC_JOB_CONTROL = placeholder();
- public static final int _SC_LINE_MAX = placeholder();
- public static final int _SC_LOGIN_NAME_MAX = placeholder();
- public static final int _SC_MAPPED_FILES = placeholder();
- public static final int _SC_MEMLOCK = placeholder();
- public static final int _SC_MEMLOCK_RANGE = placeholder();
- public static final int _SC_MEMORY_PROTECTION = placeholder();
- public static final int _SC_MESSAGE_PASSING = placeholder();
- public static final int _SC_MQ_OPEN_MAX = placeholder();
- public static final int _SC_MQ_PRIO_MAX = placeholder();
- public static final int _SC_NGROUPS_MAX = placeholder();
- public static final int _SC_NPROCESSORS_CONF = placeholder();
- public static final int _SC_NPROCESSORS_ONLN = placeholder();
- public static final int _SC_OPEN_MAX = placeholder();
- public static final int _SC_PAGESIZE = placeholder();
- public static final int _SC_PAGE_SIZE = placeholder();
- public static final int _SC_PASS_MAX = placeholder();
- public static final int _SC_PHYS_PAGES = placeholder();
- public static final int _SC_PRIORITIZED_IO = placeholder();
- public static final int _SC_PRIORITY_SCHEDULING = placeholder();
- public static final int _SC_REALTIME_SIGNALS = placeholder();
- public static final int _SC_RE_DUP_MAX = placeholder();
- public static final int _SC_RTSIG_MAX = placeholder();
- public static final int _SC_SAVED_IDS = placeholder();
- public static final int _SC_SEMAPHORES = placeholder();
- public static final int _SC_SEM_NSEMS_MAX = placeholder();
- public static final int _SC_SEM_VALUE_MAX = placeholder();
- public static final int _SC_SHARED_MEMORY_OBJECTS = placeholder();
- public static final int _SC_SIGQUEUE_MAX = placeholder();
- public static final int _SC_STREAM_MAX = placeholder();
- public static final int _SC_SYNCHRONIZED_IO = placeholder();
- public static final int _SC_THREADS = placeholder();
- public static final int _SC_THREAD_ATTR_STACKADDR = placeholder();
- public static final int _SC_THREAD_ATTR_STACKSIZE = placeholder();
- public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS = placeholder();
- public static final int _SC_THREAD_KEYS_MAX = placeholder();
- public static final int _SC_THREAD_PRIORITY_SCHEDULING = placeholder();
- public static final int _SC_THREAD_PRIO_INHERIT = placeholder();
- public static final int _SC_THREAD_PRIO_PROTECT = placeholder();
- public static final int _SC_THREAD_SAFE_FUNCTIONS = placeholder();
- public static final int _SC_THREAD_STACK_MIN = placeholder();
- public static final int _SC_THREAD_THREADS_MAX = placeholder();
- public static final int _SC_TIMERS = placeholder();
- public static final int _SC_TIMER_MAX = placeholder();
- public static final int _SC_TTY_NAME_MAX = placeholder();
- public static final int _SC_TZNAME_MAX = placeholder();
- public static final int _SC_VERSION = placeholder();
- public static final int _SC_XBS5_ILP32_OFF32 = placeholder();
- public static final int _SC_XBS5_ILP32_OFFBIG = placeholder();
- public static final int _SC_XBS5_LP64_OFF64 = placeholder();
- public static final int _SC_XBS5_LPBIG_OFFBIG = placeholder();
- public static final int _SC_XOPEN_CRYPT = placeholder();
- public static final int _SC_XOPEN_ENH_I18N = placeholder();
- public static final int _SC_XOPEN_LEGACY = placeholder();
- public static final int _SC_XOPEN_REALTIME = placeholder();
- public static final int _SC_XOPEN_REALTIME_THREADS = placeholder();
- public static final int _SC_XOPEN_SHM = placeholder();
- public static final int _SC_XOPEN_UNIX = placeholder();
- public static final int _SC_XOPEN_VERSION = placeholder();
- public static final int _SC_XOPEN_XCU_VERSION = placeholder();
-
- public static String gaiName(int error) {
- if (error == EAI_AGAIN) {
- return "EAI_AGAIN";
- }
- if (error == EAI_BADFLAGS) {
- return "EAI_BADFLAGS";
- }
- if (error == EAI_FAIL) {
- return "EAI_FAIL";
- }
- if (error == EAI_FAMILY) {
- return "EAI_FAMILY";
- }
- if (error == EAI_MEMORY) {
- return "EAI_MEMORY";
- }
- if (error == EAI_NODATA) {
- return "EAI_NODATA";
- }
- if (error == EAI_NONAME) {
- return "EAI_NONAME";
- }
- if (error == EAI_OVERFLOW) {
- return "EAI_OVERFLOW";
- }
- if (error == EAI_SERVICE) {
- return "EAI_SERVICE";
- }
- if (error == EAI_SOCKTYPE) {
- return "EAI_SOCKTYPE";
- }
- if (error == EAI_SYSTEM) {
- return "EAI_SYSTEM";
- }
- return null;
- }
-
- public static String errnoName(int errno) {
- if (errno == E2BIG) {
- return "E2BIG";
- }
- if (errno == EACCES) {
- return "EACCES";
- }
- if (errno == EADDRINUSE) {
- return "EADDRINUSE";
- }
- if (errno == EADDRNOTAVAIL) {
- return "EADDRNOTAVAIL";
- }
- if (errno == EAFNOSUPPORT) {
- return "EAFNOSUPPORT";
- }
- if (errno == EAGAIN) {
- return "EAGAIN";
- }
- if (errno == EALREADY) {
- return "EALREADY";
- }
- if (errno == EBADF) {
- return "EBADF";
- }
- if (errno == EBADMSG) {
- return "EBADMSG";
- }
- if (errno == EBUSY) {
- return "EBUSY";
- }
- if (errno == ECANCELED) {
- return "ECANCELED";
- }
- if (errno == ECHILD) {
- return "ECHILD";
- }
- if (errno == ECONNABORTED) {
- return "ECONNABORTED";
- }
- if (errno == ECONNREFUSED) {
- return "ECONNREFUSED";
- }
- if (errno == ECONNRESET) {
- return "ECONNRESET";
- }
- if (errno == EDEADLK) {
- return "EDEADLK";
- }
- if (errno == EDESTADDRREQ) {
- return "EDESTADDRREQ";
- }
- if (errno == EDOM) {
- return "EDOM";
- }
- if (errno == EDQUOT) {
- return "EDQUOT";
- }
- if (errno == EEXIST) {
- return "EEXIST";
- }
- if (errno == EFAULT) {
- return "EFAULT";
- }
- if (errno == EFBIG) {
- return "EFBIG";
- }
- if (errno == EHOSTUNREACH) {
- return "EHOSTUNREACH";
- }
- if (errno == EIDRM) {
- return "EIDRM";
- }
- if (errno == EILSEQ) {
- return "EILSEQ";
- }
- if (errno == EINPROGRESS) {
- return "EINPROGRESS";
- }
- if (errno == EINTR) {
- return "EINTR";
- }
- if (errno == EINVAL) {
- return "EINVAL";
- }
- if (errno == EIO) {
- return "EIO";
- }
- if (errno == EISCONN) {
- return "EISCONN";
- }
- if (errno == EISDIR) {
- return "EISDIR";
- }
- if (errno == ELOOP) {
- return "ELOOP";
- }
- if (errno == EMFILE) {
- return "EMFILE";
- }
- if (errno == EMLINK) {
- return "EMLINK";
- }
- if (errno == EMSGSIZE) {
- return "EMSGSIZE";
- }
- if (errno == EMULTIHOP) {
- return "EMULTIHOP";
- }
- if (errno == ENAMETOOLONG) {
- return "ENAMETOOLONG";
- }
- if (errno == ENETDOWN) {
- return "ENETDOWN";
- }
- if (errno == ENETRESET) {
- return "ENETRESET";
- }
- if (errno == ENETUNREACH) {
- return "ENETUNREACH";
- }
- if (errno == ENFILE) {
- return "ENFILE";
- }
- if (errno == ENOBUFS) {
- return "ENOBUFS";
- }
- if (errno == ENODATA) {
- return "ENODATA";
- }
- if (errno == ENODEV) {
- return "ENODEV";
- }
- if (errno == ENOENT) {
- return "ENOENT";
- }
- if (errno == ENOEXEC) {
- return "ENOEXEC";
- }
- if (errno == ENOLCK) {
- return "ENOLCK";
- }
- if (errno == ENOLINK) {
- return "ENOLINK";
- }
- if (errno == ENOMEM) {
- return "ENOMEM";
- }
- if (errno == ENOMSG) {
- return "ENOMSG";
- }
- if (errno == ENOPROTOOPT) {
- return "ENOPROTOOPT";
- }
- if (errno == ENOSPC) {
- return "ENOSPC";
- }
- if (errno == ENOSR) {
- return "ENOSR";
- }
- if (errno == ENOSTR) {
- return "ENOSTR";
- }
- if (errno == ENOSYS) {
- return "ENOSYS";
- }
- if (errno == ENOTCONN) {
- return "ENOTCONN";
- }
- if (errno == ENOTDIR) {
- return "ENOTDIR";
- }
- if (errno == ENOTEMPTY) {
- return "ENOTEMPTY";
- }
- if (errno == ENOTSOCK) {
- return "ENOTSOCK";
- }
- if (errno == ENOTSUP) {
- return "ENOTSUP";
- }
- if (errno == ENOTTY) {
- return "ENOTTY";
- }
- if (errno == ENXIO) {
- return "ENXIO";
- }
- if (errno == EOPNOTSUPP) {
- return "EOPNOTSUPP";
- }
- if (errno == EOVERFLOW) {
- return "EOVERFLOW";
- }
- if (errno == EPERM) {
- return "EPERM";
- }
- if (errno == EPIPE) {
- return "EPIPE";
- }
- if (errno == EPROTO) {
- return "EPROTO";
- }
- if (errno == EPROTONOSUPPORT) {
- return "EPROTONOSUPPORT";
- }
- if (errno == EPROTOTYPE) {
- return "EPROTOTYPE";
- }
- if (errno == ERANGE) {
- return "ERANGE";
- }
- if (errno == EROFS) {
- return "EROFS";
- }
- if (errno == ESPIPE) {
- return "ESPIPE";
- }
- if (errno == ESRCH) {
- return "ESRCH";
- }
- if (errno == ESTALE) {
- return "ESTALE";
- }
- if (errno == ETIME) {
- return "ETIME";
- }
- if (errno == ETIMEDOUT) {
- return "ETIMEDOUT";
- }
- if (errno == ETXTBSY) {
- return "ETXTBSY";
- }
- if (errno == EXDEV) {
- return "EXDEV";
- }
- return null;
- }
-
- private static native void initConstants();
-
- // A hack to avoid these constants being inlined by javac...
- private static int placeholder() { return 0; }
- // ...because we want to initialize them at runtime.
- static {
- initConstants();
- }
-}
diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Posix.java
index b99941c..f5eaaa3 100644
--- a/luni/src/main/java/libcore/io/Posix.java
+++ b/luni/src/main/java/libcore/io/Posix.java
@@ -16,21 +16,37 @@
package libcore.io;
+import android.system.ErrnoException;
+import android.system.GaiException;
+import android.system.StructAddrinfo;
+import android.system.StructFlock;
+import android.system.StructGroupReq;
+import android.system.StructGroupSourceReq;
+import android.system.StructLinger;
+import android.system.StructPasswd;
+import android.system.StructPollfd;
+import android.system.StructStat;
+import android.system.StructStatVfs;
+import android.system.StructTimeval;
+import android.system.StructUcred;
+import android.system.StructUtsname;
+import android.util.MutableInt;
+import android.util.MutableLong;
import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.NioUtils;
-import libcore.util.MutableInt;
-import libcore.util.MutableLong;
public final class Posix implements Os {
Posix() { }
public native FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException;
public native boolean access(String path, int mode) throws ErrnoException;
+ public native InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public native void chmod(String path, int mode) throws ErrnoException;
public native void chown(String path, int uid, int gid) throws ErrnoException;
@@ -52,7 +68,6 @@ public final class Posix implements Os {
public native void fsync(FileDescriptor fd) throws ErrnoException;
public native void ftruncate(FileDescriptor fd, long length) throws ErrnoException;
public native String gai_strerror(int error);
- public native InetAddress[] getaddrinfo(String node, StructAddrinfo hints) throws GaiException;
public native int getegid();
public native int geteuid();
public native int getgid();
@@ -79,11 +94,13 @@ public final class Posix implements Os {
public native boolean isatty(FileDescriptor fd);
public native void kill(int pid, int signal) throws ErrnoException;
public native void lchown(String path, int uid, int gid) throws ErrnoException;
+ public native void link(String oldPath, String newPath) throws ErrnoException;
public native void listen(FileDescriptor fd, int backlog) throws ErrnoException;
public native long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException;
public native StructStat lstat(String path) throws ErrnoException;
public native void mincore(long address, long byteCount, byte[] vector) throws ErrnoException;
public native void mkdir(String path, int mode) throws ErrnoException;
+ public native void mkfifo(String path, int mode) throws ErrnoException;
public native void mlock(long address, long byteCount) throws ErrnoException;
public native long mmap(long address, long byteCount, int prot, int flags, FileDescriptor fd, long offset) throws ErrnoException;
public native void msync(long address, long byteCount, int flags) throws ErrnoException;
@@ -92,43 +109,46 @@ public final class Posix implements Os {
public native FileDescriptor open(String path, int flags, int mode) throws ErrnoException;
public native FileDescriptor[] pipe() throws ErrnoException;
public native int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException;
- public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException {
+ public native void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException;
+ public native int prctl(int option, long arg2, long arg3, long arg4, long arg5) throws ErrnoException;
+ public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException {
if (buffer.isDirect()) {
return preadBytes(fd, buffer, buffer.position(), buffer.remaining(), offset);
} else {
return preadBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining(), offset);
}
}
- public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException {
+ public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException {
// This indirection isn't strictly necessary, but ensures that our public interface is type safe.
return preadBytes(fd, bytes, byteOffset, byteCount, offset);
}
- private native int preadBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException;
- public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException {
+ private native int preadBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException;
+ public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException {
if (buffer.isDirect()) {
return pwriteBytes(fd, buffer, buffer.position(), buffer.remaining(), offset);
} else {
return pwriteBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining(), offset);
}
}
- public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException {
+ public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException {
// This indirection isn't strictly necessary, but ensures that our public interface is type safe.
return pwriteBytes(fd, bytes, byteOffset, byteCount, offset);
}
- private native int pwriteBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException;
- public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException {
+ private native int pwriteBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException;
+ public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException {
if (buffer.isDirect()) {
return readBytes(fd, buffer, buffer.position(), buffer.remaining());
} else {
return readBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining());
}
}
- public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException {
+ public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException {
// This indirection isn't strictly necessary, but ensures that our public interface is type safe.
return readBytes(fd, bytes, byteOffset, byteCount);
}
- private native int readBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException;
- public native int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException;
+ private native int readBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException, InterruptedIOException;
+ public native String readlink(String path) throws ErrnoException;
+ public native int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException;
public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException {
if (buffer.isDirect()) {
return recvfromBytes(fd, buffer, buffer.position(), buffer.remaining(), flags, srcAddress);
@@ -166,6 +186,7 @@ public final class Posix implements Os {
public native void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
public native void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
public native void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException;
+ public native void setsockoptGroupSourceReq(FileDescriptor fd, int level, int option, StructGroupSourceReq value) throws ErrnoException;
public native void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException;
public native void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException;
public native void setuid(int uid) throws ErrnoException;
@@ -190,17 +211,17 @@ public final class Posix implements Os {
public native StructUtsname uname();
public native void unsetenv(String name) throws ErrnoException;
public native int waitpid(int pid, MutableInt status, int options) throws ErrnoException;
- public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException {
+ public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException {
if (buffer.isDirect()) {
return writeBytes(fd, buffer, buffer.position(), buffer.remaining());
} else {
return writeBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining());
}
}
- public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException {
+ public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException {
// This indirection isn't strictly necessary, but ensures that our public interface is type safe.
return writeBytes(fd, bytes, byteOffset, byteCount);
}
- private native int writeBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException;
- public native int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException;
+ private native int writeBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException, InterruptedIOException;
+ public native int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException;
}
diff --git a/luni/src/main/java/libcore/io/Streams.java b/luni/src/main/java/libcore/io/Streams.java
index cbad4a4..1f78edd 100644
--- a/luni/src/main/java/libcore/io/Streams.java
+++ b/luni/src/main/java/libcore/io/Streams.java
@@ -135,8 +135,9 @@ public final class Streams {
}
/**
- * Call {@code in.read()} repeatedly until either the stream is exhausted or
- * {@code byteCount} bytes have been read.
+ * Skip <b>at most</b> {@code byteCount} bytes from {@code in} by calling read
+ * repeatedly until either the stream is exhausted or we read fewer bytes than
+ * we ask for.
*
* <p>This method reuses the skip buffer but is careful to never use it at
* the same time that another stream is using it. Otherwise streams that use
diff --git a/luni/src/main/java/libcore/io/StructAddrinfo.java b/luni/src/main/java/libcore/io/StructAddrinfo.java
deleted file mode 100644
index 8c8181d..0000000
--- a/luni/src/main/java/libcore/io/StructAddrinfo.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-import java.net.InetAddress;
-
-/**
- * Information returned/taken by getaddrinfo(3). Corresponds to C's {@code struct addrinfo} from
- * <a href="http://pubs.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html">&lt;netdb.h&gt;</a>
- *
- * TODO: we currently only _take_ a StructAddrinfo; getaddrinfo returns an InetAddress[].
- */
-public final class StructAddrinfo {
- /** Flags describing the kind of lookup to be done. (Such as AI_ADDRCONFIG.) */
- public int ai_flags;
-
- /** Desired address family for results. (Such as AF_INET6 for IPv6. AF_UNSPEC means "any".) */
- public int ai_family;
-
- /** Socket type. (Such as SOCK_DGRAM. 0 means "any".) */
- public int ai_socktype;
-
- /** Protocol. (Such as IPPROTO_IPV6 IPv6. 0 means "any".) */
- public int ai_protocol;
-
- /** Address length. (Not useful in Java.) */
- // public int ai_addrlen;
-
- /** Address. */
- public InetAddress ai_addr;
-
- /** Canonical name of service location (if AI_CANONNAME provided in ai_flags). */
- // public String ai_canonname;
-
- /** Next element in linked list. */
- public StructAddrinfo ai_next;
-}
diff --git a/luni/src/main/java/libcore/io/StructFlock.java b/luni/src/main/java/libcore/io/StructFlock.java
deleted file mode 100644
index 11c29df..0000000
--- a/luni/src/main/java/libcore/io/StructFlock.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-/**
- * Information returned/taken by fcntl(2) F_GETFL and F_SETFL. Corresponds to C's
- * {@code struct flock} from
- * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fcntl.h.html">&lt;fcntl.h&gt;</a>
- */
-public final class StructFlock {
- /** The operation type, one of F_RDLCK, F_WRLCK, or F_UNLCK. */
- public short l_type;
-
- /** How to interpret l_start, one of SEEK_CUR, SEEK_END, SEEK_SET. */
- public short l_whence;
-
- /** Start offset. */
- public long l_start; /*off_t*/
-
- /** Byte count to operate on. */
- public long l_len; /*off_t*/
-
- /** Process blocking our lock (filled in by F_GETLK, otherwise unused). */
- public int l_pid; /*pid_t*/
-}
diff --git a/luni/src/main/java/libcore/io/StructGroupReq.java b/luni/src/main/java/libcore/io/StructGroupReq.java
deleted file mode 100644
index 0bdf783..0000000
--- a/luni/src/main/java/libcore/io/StructGroupReq.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-import java.net.InetAddress;
-
-/**
- * Corresponds to C's {@code struct group_req}.
- */
-public final class StructGroupReq {
- public final int gr_interface;
- public final InetAddress gr_group;
-
- public StructGroupReq(int gr_interface, InetAddress gr_group) {
- this.gr_interface = gr_interface;
- this.gr_group = gr_group;
- }
-
- @Override public String toString() {
- return "StructGroupReq[gr_interface=" + gr_interface + ",gr_group=" + gr_group + "]";
- }
-}
diff --git a/luni/src/main/java/libcore/io/StructLinger.java b/luni/src/main/java/libcore/io/StructLinger.java
deleted file mode 100644
index 9f149af..0000000
--- a/luni/src/main/java/libcore/io/StructLinger.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-/**
- * Corresponds to C's {@code struct linger} from
- * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html">&lt;sys/socket.h&gt;</a>
- */
-public final class StructLinger {
- /** Whether or not linger is enabled. Non-zero is on. */
- public final int l_onoff;
-
- /** Linger time in seconds. */
- public final int l_linger;
-
- public StructLinger(int l_onoff, int l_linger) {
- this.l_onoff = l_onoff;
- this.l_linger = l_linger;
- }
-
- public boolean isOn() {
- return l_onoff != 0;
- }
-
- @Override public String toString() {
- return "StructLinger[l_onoff=" + l_onoff + ",l_linger=" + l_linger + "]";
- }
-}
diff --git a/luni/src/main/java/libcore/io/StructPasswd.java b/luni/src/main/java/libcore/io/StructPasswd.java
deleted file mode 100644
index 6f5e058..0000000
--- a/luni/src/main/java/libcore/io/StructPasswd.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-/**
- * Information returned by getpwnam(3) and getpwuid(3). Corresponds to C's
- * {@code struct passwd} from
- * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pwd.h.html">&lt;pwd.h&gt;</a>
- */
-public final class StructPasswd {
- public String pw_name;
- public int pw_uid; /* uid_t */
- public int pw_gid; /* gid_t */
- public String pw_dir;
- public String pw_shell;
-
- public StructPasswd(String pw_name, int pw_uid, int pw_gid, String pw_dir, String pw_shell) {
- this.pw_name = pw_name;
- this.pw_uid = pw_uid;
- this.pw_gid = pw_gid;
- this.pw_dir = pw_dir;
- this.pw_shell = pw_shell;
- }
-}
diff --git a/luni/src/main/java/libcore/io/StructPollfd.java b/luni/src/main/java/libcore/io/StructPollfd.java
deleted file mode 100644
index c659d6e..0000000
--- a/luni/src/main/java/libcore/io/StructPollfd.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-import java.io.FileDescriptor;
-
-/**
- * Corresponds to C's {@code struct pollfd} from
- * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/poll.h.html">&lt;poll.h&gt;</a>
- */
-public final class StructPollfd {
- /** The file descriptor to poll. */
- public FileDescriptor fd;
-
- /**
- * The events we're interested in. POLLIN corresponds to being in select(2)'s read fd set,
- * POLLOUT to the write fd set.
- */
- public short events;
-
- /** The events that actually happened. */
- public short revents;
-
- /**
- * A non-standard extension that lets callers conveniently map back to the object
- * their fd belongs to. This is used by Selector, for example, to associate each
- * FileDescriptor with the corresponding SelectionKey.
- */
- public Object userData;
-
- @Override public String toString() {
- return "StructPollfd[fd=" + fd + ",events=" + events + ",revents=" + revents + "]";
- }
-}
diff --git a/luni/src/main/java/libcore/io/StructStat.java b/luni/src/main/java/libcore/io/StructStat.java
deleted file mode 100644
index 05ecca7..0000000
--- a/luni/src/main/java/libcore/io/StructStat.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-/**
- * File information returned by fstat(2), lstat(2), and stat(2). Corresponds to C's
- * {@code struct stat} from
- * <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html">&lt;stat.h&gt;</a>
- */
-public final class StructStat {
- /** Device ID of device containing file. */
- public final long st_dev; /*dev_t*/
-
- /** File serial number (inode). */
- public final long st_ino; /*ino_t*/
-
- /** Mode (permissions) of file. */
- public final int st_mode; /*mode_t*/
-
- /** Number of hard links to the file. */
- public final long st_nlink; /*nlink_t*/
-
- /** User ID of file. */
- public final int st_uid; /*uid_t*/
-
- /** Group ID of file. */
- public final int st_gid; /*gid_t*/
-
- /** Device ID (if file is character or block special). */
- public final long st_rdev; /*dev_t*/
-
- /**
- * For regular files, the file size in bytes.
- * For symbolic links, the length in bytes of the pathname contained in the symbolic link.
- * For a shared memory object, the length in bytes.
- * For a typed memory object, the length in bytes.
- * For other file types, the use of this field is unspecified.
- */
- public final long st_size; /*off_t*/
-
- /** Time of last access. */
- public final long st_atime; /*time_t*/
-
- /** Time of last data modification. */
- public final long st_mtime; /*time_t*/
-
- /** Time of last status change. */
- public final long st_ctime; /*time_t*/
-
- /**
- * A file system-specific preferred I/O block size for this object.
- * For some file system types, this may vary from file to file.
- */
- public final long st_blksize; /*blksize_t*/
-
- /** Number of blocks allocated for this object. */
- public final long st_blocks; /*blkcnt_t*/
-
- StructStat(long st_dev, long st_ino, int st_mode, long st_nlink, int st_uid, int st_gid,
- long st_rdev, long st_size, long st_atime, long st_mtime, long st_ctime,
- long st_blksize, long st_blocks) {
- this.st_dev = st_dev;
- this.st_ino = st_ino;
- this.st_mode = st_mode;
- this.st_nlink = st_nlink;
- this.st_uid = st_uid;
- this.st_gid = st_gid;
- this.st_rdev = st_rdev;
- this.st_size = st_size;
- this.st_atime = st_atime;
- this.st_mtime = st_mtime;
- this.st_ctime = st_ctime;
- this.st_blksize = st_blksize;
- this.st_blocks = st_blocks;
- }
-}
diff --git a/luni/src/main/java/libcore/io/StructStatVfs.java b/luni/src/main/java/libcore/io/StructStatVfs.java
deleted file mode 100644
index bb78ff2..0000000
--- a/luni/src/main/java/libcore/io/StructStatVfs.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-/**
- * File information returned by fstatvfs(2) and statvfs(2).
- */
-public final class StructStatVfs {
- /** File system block size (used for block counts). */
- public final long f_bsize; /*unsigned long*/
-
- /** Fundamental file system block size. */
- public final long f_frsize; /*unsigned long*/
-
- /** Total block count. */
- public final long f_blocks; /*fsblkcnt_t*/
-
- /** Free block count. */
- public final long f_bfree; /*fsblkcnt_t*/
-
- /** Free block count available to non-root. */
- public final long f_bavail; /*fsblkcnt_t*/
-
- /** Total file (inode) count. */
- public final long f_files; /*fsfilcnt_t*/
-
- /** Free file (inode) count. */
- public final long f_ffree; /*fsfilcnt_t*/
-
- /** Free file (inode) count available to non-root. */
- public final long f_favail; /*fsfilcnt_t*/
-
- /** File system id. */
- public final long f_fsid; /*unsigned long*/
-
- /** Bit mask of ST_* flags. */
- public final long f_flag; /*unsigned long*/
-
- /** Maximum filename length. */
- public final long f_namemax; /*unsigned long*/
-
- StructStatVfs(long f_bsize, long f_frsize, long f_blocks, long f_bfree, long f_bavail,
- long f_files, long f_ffree, long f_favail,
- long f_fsid, long f_flag, long f_namemax) {
- this.f_bsize = f_bsize;
- this.f_frsize = f_frsize;
- this.f_blocks = f_blocks;
- this.f_bfree = f_bfree;
- this.f_bavail = f_bavail;
- this.f_files = f_files;
- this.f_ffree = f_ffree;
- this.f_favail = f_favail;
- this.f_fsid = f_fsid;
- this.f_flag = f_flag;
- this.f_namemax = f_namemax;
- }
-}
diff --git a/luni/src/main/java/libcore/io/StructTimeval.java b/luni/src/main/java/libcore/io/StructTimeval.java
deleted file mode 100644
index 0ed3509..0000000
--- a/luni/src/main/java/libcore/io/StructTimeval.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-/**
- * Corresponds to C's {@code struct timeval} from
- * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_time.h.html">&lt;sys/time.h&gt;</a>
- */
-public final class StructTimeval {
- /** Seconds. */
- public final long tv_sec;
-
- /** Microseconds. */
- public final long tv_usec;
-
- private StructTimeval(long tv_sec, long tv_usec) {
- this.tv_sec = tv_sec;
- this.tv_usec = tv_usec;
- }
-
- public static StructTimeval fromMillis(long millis) {
- long tv_sec = millis / 1000;
- long tv_usec = (millis - (tv_sec * 1000)) * 1000;
- return new StructTimeval(tv_sec, tv_usec);
- }
-
- public long toMillis() {
- return (tv_sec * 1000) + (tv_usec / 1000);
- }
-
- @Override public String toString() {
- return "StructTimeval[tv_sec=" + tv_sec + ",tv_usec=" + tv_usec + "]";
- }
-}
diff --git a/luni/src/main/java/libcore/io/StructUcred.java b/luni/src/main/java/libcore/io/StructUcred.java
deleted file mode 100644
index 359995d..0000000
--- a/luni/src/main/java/libcore/io/StructUcred.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-/**
- * Corresponds to C's {@code struct ucred}.
- */
-public final class StructUcred {
- /** The peer's process id. */
- public final int pid;
-
- /** The peer process' uid. */
- public final int uid;
-
- /** The peer process' gid. */
- public final int gid;
-
- private StructUcred(int pid, int uid, int gid) {
- this.pid = pid;
- this.uid = uid;
- this.gid = gid;
- }
-
- @Override public String toString() {
- return "StructUcred[pid=" + pid + ",uid=" + uid + ",gid=" + gid + "]";
- }
-}
diff --git a/luni/src/main/java/libcore/io/StructUtsname.java b/luni/src/main/java/libcore/io/StructUtsname.java
deleted file mode 100644
index e6a8e42..0000000
--- a/luni/src/main/java/libcore/io/StructUtsname.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-/**
- * Information returned by uname(2). Corresponds to C's
- * {@code struct utsname} from
- * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_utsname.h.html">&lt;sys/utsname.h&gt;</a>
- */
-public final class StructUtsname {
- /** The OS name, such as "Linux". */
- public final String sysname;
-
- /** The machine's unqualified name on some implementation-defined network. */
- public final String nodename;
-
- /** The OS release, such as "2.6.35-27-generic". */
- public final String release;
-
- /** The OS version, such as "#48-Ubuntu SMP Tue Feb 22 20:25:29 UTC 2011". */
- public final String version;
-
- /** The machine architecture, such as "armv7l" or "x86_64". */
- public final String machine;
-
- StructUtsname(String sysname, String nodename, String release, String version, String machine) {
- this.sysname = sysname;
- this.nodename = nodename;
- this.release = release;
- this.version = version;
- this.machine = machine;
- }
-}
diff --git a/luni/src/main/java/libcore/net/MimeUtils.java b/luni/src/main/java/libcore/net/MimeUtils.java
index aaa5670..a5a1469 100644
--- a/luni/src/main/java/libcore/net/MimeUtils.java
+++ b/luni/src/main/java/libcore/net/MimeUtils.java
@@ -49,14 +49,13 @@ public final class MimeUtils {
add("application/andrew-inset", "ez");
add("application/dsptype", "tsp");
- add("application/futuresplash", "spl");
add("application/hta", "hta");
add("application/mac-binhex40", "hqx");
- add("application/mac-compactpro", "cpt");
add("application/mathematica", "nb");
add("application/msaccess", "mdb");
add("application/oda", "oda");
add("application/ogg", "ogg");
+ add("application/ogg", "oga");
add("application/pdf", "pdf");
add("application/pgp-keys", "key");
add("application/pgp-signature", "pgp");
@@ -133,14 +132,15 @@ public final class MimeUtils {
add("application/x-dms", "dms");
add("application/x-doom", "wad");
add("application/x-dvi", "dvi");
- add("application/x-flac", "flac");
add("application/x-font", "pfa");
add("application/x-font", "pfb");
add("application/x-font", "gsf");
add("application/x-font", "pcf");
add("application/x-font", "pcf.Z");
add("application/x-freemind", "mm");
+ // application/futuresplash isn't IANA, so application/x-futuresplash should come first.
add("application/x-futuresplash", "spl");
+ add("application/futuresplash", "spl");
add("application/x-gnumeric", "gnumeric");
add("application/x-go-sgf", "sgf");
add("application/x-graphing-calculator", "gcf");
@@ -212,11 +212,19 @@ public final class MimeUtils {
add("application/x-xfig", "fig");
add("application/xhtml+xml", "xhtml");
add("audio/3gpp", "3gpp");
+ add("audio/aac", "aac");
+ add("audio/aac-adts", "aac");
add("audio/amr", "amr");
+ add("audio/amr-wb", "awb");
add("audio/basic", "snd");
+ add("audio/flac", "flac");
+ add("application/x-flac", "flac");
+ add("audio/imelody", "imy");
add("audio/midi", "mid");
add("audio/midi", "midi");
+ add("audio/midi", "ota");
add("audio/midi", "kar");
+ add("audio/midi", "rtttl");
add("audio/midi", "xmf");
add("audio/mobile-xmf", "mxmf");
// add ".mp3" first so it will be the default for guessExtensionFromMimeType
@@ -231,6 +239,7 @@ public final class MimeUtils {
add("audio/x-aiff", "aiff");
add("audio/x-aiff", "aifc");
add("audio/x-gsm", "gsm");
+ add("audio/x-matroska", "mka");
add("audio/x-mpegurl", "m3u");
add("audio/x-ms-wma", "wma");
add("audio/x-ms-wax", "wax");
@@ -241,8 +250,12 @@ public final class MimeUtils {
add("audio/x-scpls", "pls");
add("audio/x-sd2", "sd2");
add("audio/x-wav", "wav");
+ // image/bmp isn't IANA, so image/x-ms-bmp should come first.
+ add("image/x-ms-bmp", "bmp");
add("image/bmp", "bmp");
add("image/gif", "gif");
+ // image/ico isn't IANA, so image/x-icon should come first.
+ add("image/x-icon", "ico");
add("image/ico", "cur");
add("image/ico", "ico");
add("image/ief", "ief");
@@ -258,15 +271,14 @@ public final class MimeUtils {
add("image/vnd.djvu", "djvu");
add("image/vnd.djvu", "djv");
add("image/vnd.wap.wbmp", "wbmp");
+ add("image/webp", "webp");
add("image/x-cmu-raster", "ras");
add("image/x-coreldraw", "cdr");
add("image/x-coreldrawpattern", "pat");
add("image/x-coreldrawtemplate", "cdt");
add("image/x-corelphotopaint", "cpt");
- add("image/x-icon", "ico");
add("image/x-jg", "art");
add("image/x-jng", "jng");
- add("image/x-ms-bmp", "bmp");
add("image/x-photoshop", "psd");
add("image/x-portable-anymap", "pnm");
add("image/x-portable-bitmap", "pbm");
@@ -298,7 +310,6 @@ public final class MimeUtils {
add("text/plain", "po"); // reserve "pot" for vnd.ms-powerpoint
add("text/richtext", "rtx");
add("text/rtf", "rtf");
- add("text/texmacs", "ts");
add("text/text", "phps");
add("text/tab-separated-values", "tsv");
add("text/xml", "xml");
@@ -334,12 +345,15 @@ public final class MimeUtils {
add("text/x-vcard", "vcf");
add("video/3gpp", "3gpp");
add("video/3gpp", "3gp");
- add("video/3gpp", "3g2");
+ add("video/3gpp2", "3gpp2");
+ add("video/3gpp2", "3g2");
+ add("video/avi", "avi");
add("video/dl", "dl");
add("video/dv", "dif");
add("video/dv", "dv");
add("video/fli", "fli");
add("video/m4v", "m4v");
+ add("video/mp2ts", "ts");
add("video/mpeg", "mpeg");
add("video/mpeg", "mpg");
add("video/mpeg", "mpe");
@@ -348,8 +362,10 @@ public final class MimeUtils {
add("video/quicktime", "qt");
add("video/quicktime", "mov");
add("video/vnd.mpegurl", "mxu");
+ add("video/webm", "webm");
add("video/x-la-asf", "lsf");
add("video/x-la-asf", "lsx");
+ add("video/x-matroska", "mkv");
add("video/x-mng", "mng");
add("video/x-ms-asf", "asf");
add("video/x-ms-asf", "asx");
@@ -357,7 +373,6 @@ public final class MimeUtils {
add("video/x-ms-wmv", "wmv");
add("video/x-ms-wmx", "wmx");
add("video/x-ms-wvx", "wvx");
- add("video/x-msvideo", "avi");
add("video/x-sgi-movie", "movie");
add("video/x-webex", "wrf");
add("x-conference/x-cooltalk", "ice");
@@ -366,18 +381,17 @@ public final class MimeUtils {
}
private static void add(String mimeType, String extension) {
- //
- // if we have an existing x --> y mapping, we do not want to
- // override it with another mapping x --> ?
- // this is mostly because of the way the mime-type map below
- // is constructed (if a mime type maps to several extensions
- // the first extension is considered the most popular and is
- // added first; we do not want to overwrite it later).
- //
+ // If we have an existing x -> y mapping, we do not want to
+ // override it with another mapping x -> y2.
+ // If a mime type maps to several extensions
+ // the first extension added is considered the most popular
+ // so we do not want to overwrite it later.
if (!mimeTypeToExtensionMap.containsKey(mimeType)) {
mimeTypeToExtensionMap.put(mimeType, extension);
}
- extensionToMimeTypeMap.put(extension, mimeType);
+ if (!extensionToMimeTypeMap.containsKey(extension)) {
+ extensionToMimeTypeMap.put(extension, mimeType);
+ }
}
private static InputStream getContentTypesPropertiesStream() {
diff --git a/luni/src/main/java/libcore/net/RawSocket.java b/luni/src/main/java/libcore/net/RawSocket.java
deleted file mode 100644
index 08a7d09..0000000
--- a/luni/src/main/java/libcore/net/RawSocket.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.net;
-
-import dalvik.system.CloseGuard;
-import java.io.Closeable;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.SocketException;
-import java.util.Arrays;
-import libcore.io.IoBridge;
-
-/**
- * This class allows raw L2 packets to be sent and received via the
- * specified network interface. The receive-side implementation is
- * restricted to UDP packets for efficiency.
- *
- * @hide
- */
-public class RawSocket implements Closeable {
- /**
- * Ethernet IP protocol type, part of the L2 header of IP packets.
- */
- public static final short ETH_P_IP = (short) 0x0800;
-
- /**
- * Ethernet ARP protocol type, part of the L2 header of ARP packets.
- */
- public static final short ETH_P_ARP = (short) 0x0806;
-
- private static native void create(FileDescriptor fd, short
- protocolType, String interfaceName)
- throws SocketException;
- private static native int sendPacket(FileDescriptor fd,
- String interfaceName, short protocolType, byte[] destMac, byte[] packet,
- int offset, int byteCount);
- private static native int recvPacket(FileDescriptor fd, byte[] packet,
- int offset, int byteCount, int destPort, int timeoutMillis);
-
- private final FileDescriptor fd;
- private final String mInterfaceName;
- private final short mProtocolType;
- private final CloseGuard guard = CloseGuard.get();
-
- /**
- * Creates a socket on the specified interface.
- */
- public RawSocket(String interfaceName, short protocolType)
- throws SocketException {
- mInterfaceName = interfaceName;
- mProtocolType = protocolType;
- fd = new FileDescriptor();
- create(fd, mProtocolType, mInterfaceName);
- guard.open("close");
- }
-
- /**
- * Reads a raw packet into the specified buffer, with the
- * specified timeout. If the destPort is -1, then the IP
- * destination port is not verified, otherwise only packets
- * destined for the specified UDP port are returned. Returns the
- * length actually read. No indication of overflow is signaled.
- * The packet data will start at the IP header (EthernetII
- * dest/source/type headers are removed).
- */
- public int read(byte[] packet, int offset, int byteCount, int destPort,
- int timeoutMillis) {
- if (packet == null) {
- throw new NullPointerException("packet == null");
- }
-
- Arrays.checkOffsetAndCount(packet.length, offset, byteCount);
-
- if (destPort > 65535) {
- throw new IllegalArgumentException("Port out of range: "
- + destPort);
- }
-
- return recvPacket(fd, packet, offset, byteCount, destPort,
- timeoutMillis);
- }
-
- /**
- * Writes a raw packet to the desired interface. A L2 header will
- * be added which includes the specified destination address, our
- * source MAC, and the specified protocol type. The caller is responsible
- * for computing correct IP-header and payload checksums.
- */
- public int write(byte[] destMac, byte[] packet, int offset, int byteCount) {
- if (destMac == null) {
- throw new NullPointerException("destMac == null");
- }
-
- if (packet == null) {
- throw new NullPointerException("packet == null");
- }
-
- Arrays.checkOffsetAndCount(packet.length, offset, byteCount);
-
- if (destMac.length != 6) {
- throw new IllegalArgumentException("MAC length must be 6: "
- + destMac.length);
- }
-
- return sendPacket(fd, mInterfaceName, mProtocolType, destMac, packet,
- offset, byteCount);
- }
-
- /**
- * Closes the socket. After this method is invoked, subsequent
- * read/write operations will fail.
- */
- public void close() throws IOException {
- guard.close();
- IoBridge.closeSocket(fd);
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- if (guard != null) {
- guard.warnIfOpen();
- }
- close();
- } finally {
- super.finalize();
- }
- }
-}
diff --git a/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
new file mode 100644
index 0000000..d1c7c21
--- /dev/null
+++ b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.event;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A singleton used to dispatch network events to registered listeners.
+ */
+public class NetworkEventDispatcher {
+
+ private static final NetworkEventDispatcher instance = new NetworkEventDispatcher();
+
+ private final List<NetworkEventListener> listeners =
+ new CopyOnWriteArrayList<NetworkEventListener>();
+
+ /**
+ * Returns the shared {@link NetworkEventDispatcher} instance.
+ */
+ public static NetworkEventDispatcher getInstance() {
+ return instance;
+ }
+
+ /** Visible for testing. Use {@link #getInstance()} instead. */
+ protected NetworkEventDispatcher() {
+ }
+
+ /**
+ * Registers a listener to be notified when network events occur.
+ * It can be deregistered using {@link #removeListener(NetworkEventListener)}
+ */
+ public void addListener(NetworkEventListener toAdd) {
+ if (toAdd == null) {
+ throw new NullPointerException("toAdd == null");
+ }
+ listeners.add(toAdd);
+ }
+
+ /**
+ * De-registers a listener previously added with {@link #addListener(NetworkEventListener)}. If
+ * the listener was not previously registered this is a no-op.
+ */
+ public void removeListener(NetworkEventListener toRemove) {
+ for (NetworkEventListener listener : listeners) {
+ if (listener == toRemove) {
+ listeners.remove(listener);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Notifies registered listeners of a network configuration change.
+ */
+ public void onNetworkConfigurationChanged() {
+ for (NetworkEventListener listener : listeners) {
+ try {
+ listener.onNetworkConfigurationChanged();
+ } catch (RuntimeException e) {
+ System.logI("Exception thrown during network event propagation", e);
+ }
+ }
+ }
+}
diff --git a/luni/src/main/java/libcore/net/event/NetworkEventListener.java b/luni/src/main/java/libcore/net/event/NetworkEventListener.java
new file mode 100644
index 0000000..73b9f88
--- /dev/null
+++ b/luni/src/main/java/libcore/net/event/NetworkEventListener.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.event;
+
+/**
+ * A base class for objects interested in network events.
+ */
+public class NetworkEventListener {
+
+ public void onNetworkConfigurationChanged() {
+ // no-op
+ }
+}
diff --git a/luni/src/main/java/libcore/net/url/FileURLConnection.java b/luni/src/main/java/libcore/net/url/FileURLConnection.java
index b4654cd..43eaa7d 100644
--- a/luni/src/main/java/libcore/net/url/FileURLConnection.java
+++ b/luni/src/main/java/libcore/net/url/FileURLConnection.java
@@ -28,6 +28,11 @@ import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
import libcore.net.UriCodec;
/**
@@ -38,17 +43,45 @@ import libcore.net.UriCodec;
*/
public class FileURLConnection extends URLConnection {
+ private static final Comparator<String> HEADER_COMPARATOR = new Comparator<String>() {
+ @Override
+ public int compare(String a, String b) {
+ if (a == b) {
+ return 0;
+ } else if (a == null) {
+ return -1;
+ } else if (b == null) {
+ return 1;
+ } else {
+ return String.CASE_INSENSITIVE_ORDER.compare(a, b);
+ }
+ }
+ };
+
private String filename;
private InputStream is;
- private int length = -1;
+ private long length = -1;
+
+ private long lastModified = -1;
private boolean isDir;
private FilePermission permission;
/**
+ * A set of three key value pairs representing the headers we support.
+ */
+ private final String[] headerKeysAndValues;
+
+ private static final int CONTENT_TYPE_VALUE_IDX = 1;
+ private static final int CONTENT_LENGTH_VALUE_IDX = 3;
+ private static final int LAST_MODIFIED_VALUE_IDX = 5;
+
+ private Map<String, List<String>> headerFields;
+
+ /**
* Creates an instance of <code>FileURLConnection</code> for establishing
* a connection to the file pointed by this <code>URL<code>
*
@@ -61,6 +94,10 @@ public class FileURLConnection extends URLConnection {
filename = "";
}
filename = UriCodec.decode(filename);
+ headerKeysAndValues = new String[] {
+ "content-type", null,
+ "content-length", null,
+ "last-modified", null };
}
/**
@@ -74,27 +111,122 @@ public class FileURLConnection extends URLConnection {
@Override
public void connect() throws IOException {
File f = new File(filename);
+ IOException error = null;
if (f.isDirectory()) {
isDir = true;
is = getDirectoryListing(f);
// use -1 for the contentLength
+ lastModified = f.lastModified();
+ headerKeysAndValues[CONTENT_TYPE_VALUE_IDX] = "text/html";
} else {
- is = new BufferedInputStream(new FileInputStream(f));
- long lengthAsLong = f.length();
- length = lengthAsLong <= Integer.MAX_VALUE ? (int) lengthAsLong : Integer.MAX_VALUE;
+ try {
+ is = new BufferedInputStream(new FileInputStream(f));
+ } catch (IOException ioe) {
+ error = ioe;
+ }
+
+ if (error == null) {
+ length = f.length();
+ lastModified = f.lastModified();
+ headerKeysAndValues[CONTENT_TYPE_VALUE_IDX] = getContentTypeForPlainFiles();
+ } else {
+ headerKeysAndValues[CONTENT_TYPE_VALUE_IDX] = "content/unknown";
+ }
}
+
+ headerKeysAndValues[CONTENT_LENGTH_VALUE_IDX] = String.valueOf(length);
+ headerKeysAndValues[LAST_MODIFIED_VALUE_IDX] = String.valueOf(lastModified);
+
connected = true;
+ if (error != null) {
+ throw error;
+ }
+ }
+
+ @Override
+ public String getHeaderField(String key) {
+ if (!connected) {
+ try {
+ connect();
+ } catch (IOException ioe) {
+ return null;
+ }
+ }
+
+ for (int i = 0; i < headerKeysAndValues.length; i += 2) {
+ if (headerKeysAndValues[i].equalsIgnoreCase(key)) {
+ return headerKeysAndValues[i + 1];
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getHeaderFieldKey(int position) {
+ if (!connected) {
+ try {
+ connect();
+ } catch (IOException ioe) {
+ return null;
+ }
+ }
+
+ if (position < 0 || position > headerKeysAndValues.length / 2) {
+ return null;
+ }
+
+ return headerKeysAndValues[position * 2];
+ }
+
+ @Override
+ public String getHeaderField(int position) {
+ if (!connected) {
+ try {
+ connect();
+ } catch (IOException ioe) {
+ return null;
+ }
+ }
+
+ if (position < 0 || position > headerKeysAndValues.length / 2) {
+ return null;
+ }
+
+ return headerKeysAndValues[(position * 2) + 1];
+ }
+
+ @Override
+ public Map<String, List<String>> getHeaderFields() {
+ if (headerFields == null) {
+ final TreeMap<String, List<String>> headerFieldsMap = new TreeMap<>(HEADER_COMPARATOR);
+
+ for (int i = 0; i < headerKeysAndValues.length; i+=2) {
+ headerFieldsMap.put(headerKeysAndValues[i],
+ Collections.singletonList(headerKeysAndValues[i + 1]));
+ }
+
+ headerFields = Collections.unmodifiableMap(headerFieldsMap);
+ }
+
+ return headerFields;
}
/**
- * Returns the length of the file in bytes.
- *
- * @return the length of the file
- *
- * @see #getContentType()
+ * Returns the length of the file in bytes, or {@code -1} if the length cannot be
+ * represented as an {@code int}. See {@link #getContentLengthLong()} for a method that can
+ * handle larger files.
*/
@Override
public int getContentLength() {
+ long length = getContentLengthLong();
+ return length <= Integer.MAX_VALUE ? (int) length : -1;
+ }
+
+ /**
+ * Returns the length of the file in bytes.
+ */
+ private long getContentLengthLong() {
try {
if (!connected) {
connect();
@@ -113,16 +245,11 @@ public class FileURLConnection extends URLConnection {
*/
@Override
public String getContentType() {
- try {
- if (!connected) {
- connect();
- }
- } catch (IOException e) {
- return "content/unknown";
- }
- if (isDir) {
- return "text/plain";
- }
+ // The content-type header field is always at position 0.
+ return getHeaderField(0);
+ }
+
+ private String getContentTypeForPlainFiles() {
String result = guessContentTypeFromName(url.getFile());
if (result != null) {
return result;
diff --git a/luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java b/luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java
index 762f0e2..b01a20a 100644
--- a/luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java
+++ b/luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java
@@ -258,12 +258,10 @@ public class JarURLConnectionImpl extends JarURLConnection {
}
/**
- * Returns the content length of the resource. Test cases reveal that if the
- * URL is referring to a Jar file, this method answers a content-length
- * returned by URLConnection. For jar entry it should return it's size.
- * Otherwise, it will return -1.
- *
- * @return the content length
+ * Returns the content length of the resource. Test cases reveal that if the URL is referring to
+ * a Jar file, this method answers a content-length returned by URLConnection. For a jar entry
+ * it returns the entry's size if it can be represented as an {@code int}. Otherwise, it will
+ * return -1.
*/
@Override
public int getContentLength() {
diff --git a/luni/src/main/java/libcore/reflect/AnnotationAccess.java b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
index 4e34284..2a72c18 100644
--- a/luni/src/main/java/libcore/reflect/AnnotationAccess.java
+++ b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
@@ -16,7 +16,6 @@
package libcore.reflect;
-import com.android.dex.ClassDef;
import com.android.dex.Dex;
import com.android.dex.EncodedValueReader;
import com.android.dex.FieldId;
@@ -167,7 +166,7 @@ public final class AnnotationAccess {
*/
public static <A extends Annotation> A getDeclaredAnnotation(
AnnotatedElement element, Class<A> annotationClass) {
- com.android.dex.Annotation a = getMethodAnnotation(element, annotationClass);
+ com.android.dex.Annotation a = getAnnotation(element, annotationClass);
return a != null
? toAnnotationInstance(getDexClass(element), annotationClass, a)
: null;
@@ -178,29 +177,29 @@ public final class AnnotationAccess {
*/
public static boolean isDeclaredAnnotationPresent(
AnnotatedElement element, Class<? extends Annotation> annotationClass) {
- return getMethodAnnotation(element, annotationClass) != null;
+ return getAnnotation(element, annotationClass) != null;
}
- private static com.android.dex.Annotation getMethodAnnotation(
+ private static com.android.dex.Annotation getAnnotation(
AnnotatedElement element, Class<? extends Annotation> annotationClass) {
- Class<?> dexClass = getDexClass(element);
- Dex dex = dexClass.getDex();
- int annotationTypeIndex = getTypeIndex(dex, annotationClass);
- if (annotationTypeIndex == -1) {
- return null; // The dex file doesn't use this annotation.
- }
-
int annotationSetOffset = getAnnotationSetOffset(element);
if (annotationSetOffset == 0) {
return null; // no annotation
}
+ Class<?> dexClass = getDexClass(element);
+ Dex dex = dexClass.getDex();
Dex.Section setIn = dex.open(annotationSetOffset); // annotation_set_item
+ String annotationInternalName = InternalNames.getInternalName(annotationClass);
for (int i = 0, size = setIn.readInt(); i < size; i++) {
int annotationOffset = setIn.readInt();
Dex.Section annotationIn = dex.open(annotationOffset); // annotation_item
+ // The internal string name of the annotation is compared here and deliberately not
+ // the value of annotationClass.getTypeIndex(). The annotationClass may have been
+ // defined by a different dex file, which would make the indexes incomparable.
com.android.dex.Annotation candidate = annotationIn.readAnnotation();
- if (candidate.getTypeIndex() == annotationTypeIndex) {
+ String candidateInternalName = dex.typeNames().get(candidate.getTypeIndex());
+ if (candidateInternalName.equals(annotationInternalName)) {
return candidate;
}
}
@@ -228,19 +227,22 @@ public final class AnnotationAccess {
int methodsSize = directoryIn.readInt();
directoryIn.readInt(); // parameters size
- int fieldIndex = element instanceof Field ? ((Field) element).getDexFieldIndex() : -1;
- for (int i = 0; i < fieldsSize; i++) {
- int candidateFieldIndex = directoryIn.readInt();
- int annotationSetOffset = directoryIn.readInt();
- if (candidateFieldIndex == fieldIndex) {
- return annotationSetOffset;
- }
- }
- // we must read all fields prior to methods, if we were searching for a field then we missed
if (element instanceof Field) {
+ int fieldIndex = ((Field) element).getDexFieldIndex();
+ for (int i = 0; i < fieldsSize; i++) {
+ int candidateFieldIndex = directoryIn.readInt();
+ int annotationSetOffset = directoryIn.readInt();
+ if (candidateFieldIndex == fieldIndex) {
+ return annotationSetOffset;
+ }
+ }
+ // if we were searching for a field then we missed
return 0;
}
+ // Skip through the fields without reading them and look for constructors or methods.
+ directoryIn.skip(8 * fieldsSize);
+
int methodIndex= element instanceof Method ? ((Method) element).getDexMethodIndex()
: ((Constructor<?>) element).getDexMethodIndex();
for (int i = 0; i < methodsSize; i++) {
@@ -265,23 +267,6 @@ public final class AnnotationAccess {
: ((Member) element).getDeclaringClass();
}
- public static int getFieldIndex(Class<?> declaringClass, Class<?> type, String name) {
- Dex dex = declaringClass.getDex();
- int declaringClassIndex = getTypeIndex(dex, declaringClass);
- int typeIndex = getTypeIndex(dex, type);
- int nameIndex = dex.findStringIndex(name);
- FieldId fieldId = new FieldId(dex, declaringClassIndex, typeIndex, nameIndex);
- return dex.findFieldIndex(fieldId);
- }
-
- public static int getMethodIndex(Class<?> declaringClass, String name, int protoIndex) {
- Dex dex = declaringClass.getDex();
- int declaringClassIndex = getTypeIndex(dex, declaringClass);
- int nameIndex = dex.findStringIndex(name);
- MethodId methodId = new MethodId(dex, declaringClassIndex, protoIndex, nameIndex);
- return dex.findMethodIndex(methodId);
- }
-
/**
* Returns the parameter annotations on {@code member}.
*/
@@ -354,6 +339,8 @@ public final class AnnotationAccess {
*/
Class<?> annotationClass = method.getDeclaringClass();
+ // All lookups of type and string indexes are within the Dex that declares the annotation so
+ // the indexes can be compared directly.
Dex dex = annotationClass.getDex();
EncodedValueReader reader = getOnlyAnnotationValue(
dex, annotationClass, "Ldalvik/annotation/AnnotationDefault;");
@@ -362,7 +349,7 @@ public final class AnnotationAccess {
}
int fieldCount = reader.readAnnotation();
- if (reader.getAnnotationType() != getTypeIndex(dex, annotationClass)) {
+ if (reader.getAnnotationType() != annotationClass.getDexTypeIndex()) {
throw new AssertionError("annotation value type != annotation class");
}
@@ -384,7 +371,7 @@ public final class AnnotationAccess {
* Returns the class of which {@code c} is a direct member. If {@code c} is
* defined in a method or constructor, this is not transitive.
*/
- public static Class<?> getDeclaringClass(Class<?> c) {
+ public static Class<?> getEnclosingClass(Class<?> c) {
/*
* public class Bar {
* @EnclosingClass(value=Bar)
@@ -537,22 +524,6 @@ public final class AnnotationAccess {
* was derived.
*/
- /** Find dex's type index for the class c */
- private static int getTypeIndex(Dex dex, Class<?> c) {
- if (dex == c.getDex()) {
- return c.getDexTypeIndex();
- }
- if (dex == null) {
- return -1;
- }
- int typeIndex = dex.findTypeIndex(InternalNames.getInternalName(c));
- if (typeIndex < 0) {
- typeIndex = -1;
- }
- return typeIndex;
- }
-
-
private static EncodedValueReader getAnnotationReader(
Dex dex, AnnotatedElement element, String annotationName, int expectedFieldCount) {
int annotationSetOffset = getAnnotationSetOffset(element);
diff --git a/luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java b/luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java
index ef22576..5919a19 100644
--- a/luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java
+++ b/luni/src/main/java/libcore/reflect/GenericArrayTypeImpl.java
@@ -18,6 +18,7 @@ package libcore.reflect;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Type;
+import java.util.Objects;
public final class GenericArrayTypeImpl implements GenericArrayType {
private final Type componentType;
@@ -34,6 +35,20 @@ public final class GenericArrayTypeImpl implements GenericArrayType {
}
}
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GenericArrayType)) {
+ return false;
+ }
+ GenericArrayType that = (GenericArrayType) o;
+ return Objects.equals(getGenericComponentType(), that.getGenericComponentType());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(getGenericComponentType());
+ }
+
public String toString() {
return componentType.toString() + "[]";
}
diff --git a/luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java b/luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java
index 99dfe8b..2cd5ac3 100644
--- a/luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java
+++ b/luni/src/main/java/libcore/reflect/ParameterizedTypeImpl.java
@@ -18,17 +18,22 @@ package libcore.reflect;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Objects;
public final class ParameterizedTypeImpl implements ParameterizedType {
private final ListOfTypes args;
private final ParameterizedTypeImpl ownerType0; // Potentially unresolved.
- private Type ownerTypeRes;
- private Class rawType; // Already resolved.
+ private Type ownerTypeRes; // Potentially unresolved.
+ private Class rawType; // Potentially unresolved.
private final String rawTypeName;
- private ClassLoader loader;
+ private final ClassLoader loader;
public ParameterizedTypeImpl(ParameterizedTypeImpl ownerType, String rawTypeName,
ListOfTypes args, ClassLoader loader) {
+ if (args == null) {
+ throw new NullPointerException();
+ }
this.ownerType0 = ownerType;
this.rawTypeName = rawTypeName;
this.args = args;
@@ -37,7 +42,6 @@ public final class ParameterizedTypeImpl implements ParameterizedType {
public Type[] getActualTypeArguments() {
- // ASSUMPTION: args is never null!!!
return args.getResolvedTypes().clone();
}
@@ -76,6 +80,23 @@ public final class ParameterizedTypeImpl implements ParameterizedType {
}
@Override
+ public boolean equals(Object o) {
+ if (!(o instanceof ParameterizedType)) {
+ return false;
+ }
+ ParameterizedType that = (ParameterizedType) o;
+ return Objects.equals(getRawType(), that.getRawType()) &&
+ Objects.equals(getOwnerType(), that.getOwnerType()) &&
+ Arrays.equals(args.getResolvedTypes(), that.getActualTypeArguments());
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * (31 * Objects.hashCode(getRawType()) + Objects.hashCode(getOwnerType())) +
+ Arrays.hashCode(args.getResolvedTypes());
+ }
+
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(rawTypeName);
diff --git a/luni/src/main/java/libcore/util/EmptyArray.java b/luni/src/main/java/libcore/util/EmptyArray.java
index 1713bfc..eac06f2 100644
--- a/luni/src/main/java/libcore/util/EmptyArray.java
+++ b/luni/src/main/java/libcore/util/EmptyArray.java
@@ -23,7 +23,9 @@ public final class EmptyArray {
public static final byte[] BYTE = new byte[0];
public static final char[] CHAR = new char[0];
public static final double[] DOUBLE = new double[0];
+ public static final float[] FLOAT = new float[0];
public static final int[] INT = new int[0];
+ public static final long[] LONG = new long[0];
public static final Class<?>[] CLASS = new Class[0];
public static final Object[] OBJECT = new Object[0];
diff --git a/luni/src/main/java/libcore/util/MutableBoolean.java b/luni/src/main/java/libcore/util/MutableBoolean.java
deleted file mode 100644
index 359a8f9..0000000
--- a/luni/src/main/java/libcore/util/MutableBoolean.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-public final class MutableBoolean {
- public boolean value;
-
- public MutableBoolean(boolean value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/MutableByte.java b/luni/src/main/java/libcore/util/MutableByte.java
deleted file mode 100644
index 13f780b..0000000
--- a/luni/src/main/java/libcore/util/MutableByte.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-public final class MutableByte {
- public byte value;
-
- public MutableByte(byte value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/MutableChar.java b/luni/src/main/java/libcore/util/MutableChar.java
deleted file mode 100644
index 1cafc3c..0000000
--- a/luni/src/main/java/libcore/util/MutableChar.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-public final class MutableChar {
- public char value;
-
- public MutableChar(char value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/MutableDouble.java b/luni/src/main/java/libcore/util/MutableDouble.java
deleted file mode 100644
index 4473ae6..0000000
--- a/luni/src/main/java/libcore/util/MutableDouble.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-public final class MutableDouble {
- public double value;
-
- public MutableDouble(double value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/MutableFloat.java b/luni/src/main/java/libcore/util/MutableFloat.java
deleted file mode 100644
index f81fba5..0000000
--- a/luni/src/main/java/libcore/util/MutableFloat.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-public final class MutableFloat {
- public float value;
-
- public MutableFloat(float value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/MutableInt.java b/luni/src/main/java/libcore/util/MutableInt.java
deleted file mode 100644
index c8feb3a..0000000
--- a/luni/src/main/java/libcore/util/MutableInt.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-public final class MutableInt {
- public int value;
-
- public MutableInt(int value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/MutableLong.java b/luni/src/main/java/libcore/util/MutableLong.java
deleted file mode 100644
index ad9b78e..0000000
--- a/luni/src/main/java/libcore/util/MutableLong.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-public final class MutableLong {
- public long value;
-
- public MutableLong(long value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/MutableShort.java b/luni/src/main/java/libcore/util/MutableShort.java
deleted file mode 100644
index 78b4c33..0000000
--- a/luni/src/main/java/libcore/util/MutableShort.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-public final class MutableShort {
- public short value;
-
- public MutableShort(short value) {
- this.value = value;
- }
-}
diff --git a/luni/src/main/java/libcore/util/ZoneInfo.java b/luni/src/main/java/libcore/util/ZoneInfo.java
index 54ee667..4d58d93 100644
--- a/luni/src/main/java/libcore/util/ZoneInfo.java
+++ b/luni/src/main/java/libcore/util/ZoneInfo.java
@@ -13,11 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+/*
+ * Elements of the WallTime class are a port of Bionic's localtime.c to Java. That code had the
+ * following header:
+ *
+ * This file is in the public domain, so clarified as of
+ * 1996-06-05 by Arthur David Olson.
+ */
package libcore.util;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Date;
+import java.util.GregorianCalendar;
import java.util.TimeZone;
import libcore.io.BufferIterator;
@@ -51,7 +59,7 @@ public final class ZoneInfo extends TimeZone {
private final byte[] mTypes;
private final byte[] mIsDsts;
- public static TimeZone makeTimeZone(String id, BufferIterator it) {
+ public static ZoneInfo makeTimeZone(String id, BufferIterator it) {
// Variable names beginning tzh_ correspond to those in "tzfile.h".
// Check tzh_magic.
@@ -148,22 +156,21 @@ public final class ZoneInfo extends TimeZone {
mOffsets[i] -= mRawOffset;
}
- // Is this zone still observing DST?
+ // Is this zone observing DST currently or in the future?
// We don't care if they've historically used it: most places have at least once.
- // We want to know whether the last "schedule info" (the unix times in the mTransitions
- // array) is in the future. If it is, DST is still relevant.
// See http://code.google.com/p/android/issues/detail?id=877.
// This test means that for somewhere like Morocco, which tried DST in 2009 but has
// no future plans (and thus no future schedule info) will report "true" from
// useDaylightTime at the start of 2009 but "false" at the end. This seems appropriate.
boolean usesDst = false;
- long currentUnixTime = System.currentTimeMillis() / 1000;
- if (mTransitions.length > 0) {
- // (We're really dealing with uint32_t values, so long is most convenient in Java.)
- long latestScheduleTime = ((long) mTransitions[mTransitions.length - 1]) & 0xffffffff;
- if (currentUnixTime < latestScheduleTime) {
+ int currentUnixTimeSeconds = (int) (System.currentTimeMillis() / 1000);
+ int i = mTransitions.length - 1;
+ while (i >= 0 && mTransitions[i] >= currentUnixTimeSeconds) {
+ if (mIsDsts[mTypes[i]] > 0) {
usesDst = true;
+ break;
}
+ i--;
}
mUseDst = usesDst;
@@ -301,4 +308,670 @@ public final class ZoneInfo extends TimeZone {
",transitions=" + mTransitions.length +
"]";
}
+
+ @Override
+ public Object clone() {
+ // Overridden for documentation. The default clone() behavior is exactly what we want.
+ // Though mutable, the arrays of offset data are treated as immutable. Only ID and
+ // mRawOffset are mutable in this class, and those are an immutable object and a primitive
+ // respectively.
+ return super.clone();
+ }
+
+ /**
+ * A class that represents a "wall time". This class is modeled on the C tm struct and
+ * is used to support android.text.format.Time behavior. Unlike the tm struct the year is
+ * represented as the full year, not the years since 1900.
+ *
+ * <p>This class contains a rewrite of various native functions that android.text.format.Time
+ * once relied on such as mktime_tz and localtime_tz. This replacement does not support leap
+ * seconds but does try to preserve behavior around ambiguous date/times found in the BSD
+ * version of mktime that was previously used.
+ *
+ * <p>The original native code used a 32-bit value for time_t on 32-bit Android, which
+ * was the only variant of Android available at the time. To preserve old behavior this code
+ * deliberately uses {@code int} rather than {@code long} for most things and performs
+ * calculations in seconds. This creates deliberate truncation issues for date / times before
+ * 1901 and after 2038. This is intentional but might be fixed in future if all the knock-ons
+ * can be resolved: Application code may have come to rely on the range so previously values
+ * like zero for year could indicate an invalid date but if we move to long the year zero would
+ * be valid.
+ *
+ * <p>All offsets are considered to be safe for addition / subtraction / multiplication without
+ * worrying about overflow. All absolute time arithmetic is checked for overflow / underflow.
+ */
+ public static class WallTime {
+
+ // We use a GregorianCalendar (set to UTC) to handle all the date/time normalization logic
+ // and to convert from a broken-down date/time to a millis value.
+ // Unfortunately, it cannot represent an initial state with a zero day and would
+ // automatically normalize it, so we must copy values into and out of it as needed.
+ private final GregorianCalendar calendar;
+
+ private int year;
+ private int month;
+ private int monthDay;
+ private int hour;
+ private int minute;
+ private int second;
+ private int weekDay;
+ private int yearDay;
+ private int isDst;
+ private int gmtOffsetSeconds;
+
+ public WallTime() {
+ this.calendar = createGregorianCalendar();
+ calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+ // LayoutLib replaces this method via bytecode manipulation, since the
+ // minimum-cost constructor is not available on host machines.
+ private static GregorianCalendar createGregorianCalendar() {
+ return new GregorianCalendar(false);
+ }
+
+ /**
+ * Sets the wall time to a point in time using the time zone information provided. This
+ * is a replacement for the old native localtime_tz() function.
+ *
+ * <p>When going from an instant to a wall time it is always unambiguous because there
+ * is only one offset rule acting at any given instant. We do not consider leap seconds.
+ */
+ public void localtime(int timeSeconds, ZoneInfo zoneInfo) {
+ try {
+ int offsetSeconds = zoneInfo.mRawOffset / 1000;
+
+ // Find out the timezone DST state and adjustment.
+ byte isDst;
+ if (zoneInfo.mTransitions.length == 0) {
+ isDst = 0;
+ } else {
+ // transitionIndex can be in the range -1..zoneInfo.mTransitions.length - 1
+ int transitionIndex = findTransitionIndex(zoneInfo, timeSeconds);
+ if (transitionIndex < 0) {
+ // -1 means timeSeconds is "before the first recorded transition". The first
+ // recorded transition is treated as a transition from non-DST and the raw
+ // offset.
+ isDst = 0;
+ } else {
+ byte transitionType = zoneInfo.mTypes[transitionIndex];
+ offsetSeconds += zoneInfo.mOffsets[transitionType];
+ isDst = zoneInfo.mIsDsts[transitionType];
+ }
+ }
+
+ // Perform arithmetic that might underflow before setting fields.
+ int wallTimeSeconds = checkedAdd(timeSeconds, offsetSeconds);
+
+ // Set fields.
+ calendar.setTimeInMillis(wallTimeSeconds * 1000L);
+ copyFieldsFromCalendar();
+ this.isDst = isDst;
+ this.gmtOffsetSeconds = offsetSeconds;
+ } catch (CheckedArithmeticException e) {
+ // Just stop, leaving fields untouched.
+ }
+ }
+
+ /**
+ * Returns the time in seconds since beginning of the Unix epoch for the wall time using the
+ * time zone information provided. This is a replacement for an old native mktime_tz() C
+ * function.
+ *
+ * <p>When going from a wall time to an instant the answer can be ambiguous. A wall
+ * time can map to zero, one or two instants given sane date/time transitions. Sane
+ * in this case means that transitions occur less frequently than the offset
+ * differences between them (which could cause all sorts of craziness like the
+ * skipping out of transitions).
+ *
+ * <p>For example, this is not fully supported:
+ * <ul>
+ * <li>t1 { time = 1, offset = 0 }
+ * <li>t2 { time = 2, offset = -1 }
+ * <li>t3 { time = 3, offset = -2 }
+ * </ul>
+ * A wall time in this case might map to t1, t2 or t3.
+ *
+ * <p>We do not handle leap seconds.
+ * <p>We assume that no timezone offset transition has an absolute offset > 24 hours.
+ * <p>We do not assume that adjacent transitions modify the DST state; adjustments can
+ * occur for other reasons such as when a zone changes its raw offset.
+ */
+ public int mktime(ZoneInfo zoneInfo) {
+ // Normalize isDst to -1, 0 or 1 to simplify isDst equality checks below.
+ this.isDst = this.isDst > 0 ? this.isDst = 1 : this.isDst < 0 ? this.isDst = -1 : 0;
+
+ copyFieldsToCalendar();
+ final long longWallTimeSeconds = calendar.getTimeInMillis() / 1000;
+ if (Integer.MIN_VALUE > longWallTimeSeconds
+ || longWallTimeSeconds > Integer.MAX_VALUE) {
+ // For compatibility with the old native 32-bit implementation we must treat
+ // this as an error. Note: -1 could be confused with a real time.
+ return -1;
+ }
+
+ try {
+ final int wallTimeSeconds = (int) longWallTimeSeconds;
+ final int rawOffsetSeconds = zoneInfo.mRawOffset / 1000;
+ final int rawTimeSeconds = checkedSubtract(wallTimeSeconds, rawOffsetSeconds);
+
+ if (zoneInfo.mTransitions.length == 0) {
+ // There is no transition information. There is just a raw offset for all time.
+ if (this.isDst > 0) {
+ // Caller has asserted DST, but there is no DST information available.
+ return -1;
+ }
+ copyFieldsFromCalendar();
+ this.isDst = 0;
+ this.gmtOffsetSeconds = rawOffsetSeconds;
+ return rawTimeSeconds;
+ }
+
+ // We cannot know for sure what instant the wall time will map to. Unfortunately, in
+ // order to know for sure we need the timezone information, but to get the timezone
+ // information we need an instant. To resolve this we use the raw offset to find an
+ // OffsetInterval; this will get us the OffsetInterval we need or very close.
+
+ // The initialTransition can be between -1 and (zoneInfo.mTransitions - 1). -1
+ // indicates the rawTime is before the first transition and is handled gracefully by
+ // createOffsetInterval().
+ final int initialTransitionIndex = findTransitionIndex(zoneInfo, rawTimeSeconds);
+
+ if (isDst < 0) {
+ // This is treated as a special case to get it out of the way:
+ // When a caller has set isDst == -1 it means we can return the first match for
+ // the wall time we find. If the caller has specified a wall time that cannot
+ // exist this always returns -1.
+
+ Integer result = doWallTimeSearch(zoneInfo, initialTransitionIndex,
+ wallTimeSeconds, true /* mustMatchDst */);
+ return result == null ? -1 : result;
+ }
+
+ // If the wall time asserts a DST (isDst == 0 or 1) the search is performed twice:
+ // 1) The first attempts to find a DST offset that matches isDst exactly.
+ // 2) If it fails, isDst is assumed to be incorrect and adjustments are made to see
+ // if a valid wall time can be created. The result can be somewhat arbitrary.
+
+ Integer result = doWallTimeSearch(zoneInfo, initialTransitionIndex, wallTimeSeconds,
+ true /* mustMatchDst */);
+ if (result == null) {
+ result = doWallTimeSearch(zoneInfo, initialTransitionIndex, wallTimeSeconds,
+ false /* mustMatchDst */);
+ }
+ if (result == null) {
+ result = -1;
+ }
+ return result;
+ } catch (CheckedArithmeticException e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Attempt to apply DST adjustments to {@code oldWallTimeSeconds} to create a wall time in
+ * {@code targetInterval}.
+ *
+ * <p>This is used when a caller has made an assertion about standard time / DST that cannot
+ * be matched to any offset interval that exists. We must therefore assume that the isDst
+ * assertion is incorrect and the invalid wall time is the result of some modification the
+ * caller made to a valid wall time that pushed them outside of the offset interval they
+ * were in. We must correct for any DST change that should have been applied when they did
+ * so.
+ *
+ * <p>Unfortunately, we have no information about what adjustment they made and so cannot
+ * know which offset interval they were previously in. For example, they may have added a
+ * second or a year to a valid time to arrive at what they have.
+ *
+ * <p>We try all offset types that are not the same as the isDst the caller asserted. For
+ * each possible offset we work out the offset difference between that and
+ * {@code targetInterval}, apply it, and see if we are still in {@code targetInterval}. If
+ * we are, then we have found an adjustment.
+ */
+ private Integer tryOffsetAdjustments(ZoneInfo zoneInfo, int oldWallTimeSeconds,
+ OffsetInterval targetInterval, int transitionIndex, int isDstToFind)
+ throws CheckedArithmeticException {
+
+ int[] offsetsToTry = getOffsetsOfType(zoneInfo, transitionIndex, isDstToFind);
+ for (int j = 0; j < offsetsToTry.length; j++) {
+ int rawOffsetSeconds = zoneInfo.mRawOffset / 1000;
+ int jOffsetSeconds = rawOffsetSeconds + offsetsToTry[j];
+ int targetIntervalOffsetSeconds = targetInterval.getTotalOffsetSeconds();
+ int adjustmentSeconds = targetIntervalOffsetSeconds - jOffsetSeconds;
+ int adjustedWallTimeSeconds = checkedAdd(oldWallTimeSeconds, adjustmentSeconds);
+ if (targetInterval.containsWallTime(adjustedWallTimeSeconds)) {
+ // Perform any arithmetic that might overflow.
+ int returnValue = checkedSubtract(adjustedWallTimeSeconds,
+ targetIntervalOffsetSeconds);
+
+ // Modify field state and return the result.
+ calendar.setTimeInMillis(adjustedWallTimeSeconds * 1000L);
+ copyFieldsFromCalendar();
+ this.isDst = targetInterval.getIsDst();
+ this.gmtOffsetSeconds = targetIntervalOffsetSeconds;
+ return returnValue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return an array of offsets that have the requested {@code isDst} value.
+ * The {@code startIndex} is used as a starting point so transitions nearest
+ * to that index are returned first.
+ */
+ private static int[] getOffsetsOfType(ZoneInfo zoneInfo, int startIndex, int isDst) {
+ // +1 to account for the synthetic transition we invent before the first recorded one.
+ int[] offsets = new int[zoneInfo.mOffsets.length + 1];
+ boolean[] seen = new boolean[zoneInfo.mOffsets.length];
+ int numFound = 0;
+
+ int delta = 0;
+ boolean clampTop = false;
+ boolean clampBottom = false;
+ do {
+ // delta = { 1, -1, 2, -2, 3, -3...}
+ delta *= -1;
+ if (delta >= 0) {
+ delta++;
+ }
+
+ int transitionIndex = startIndex + delta;
+ if (delta < 0 && transitionIndex < -1) {
+ clampBottom = true;
+ continue;
+ } else if (delta > 0 && transitionIndex >= zoneInfo.mTypes.length) {
+ clampTop = true;
+ continue;
+ }
+
+ if (transitionIndex == -1) {
+ if (isDst == 0) {
+ // Synthesize a non-DST transition before the first transition we have
+ // data for.
+ offsets[numFound++] = 0; // offset of 0 from raw offset
+ }
+ continue;
+ }
+ byte type = zoneInfo.mTypes[transitionIndex];
+ if (!seen[type]) {
+ if (zoneInfo.mIsDsts[type] == isDst) {
+ offsets[numFound++] = zoneInfo.mOffsets[type];
+ }
+ seen[type] = true;
+ }
+ } while (!(clampTop && clampBottom));
+
+ int[] toReturn = new int[numFound];
+ System.arraycopy(offsets, 0, toReturn, 0, numFound);
+ return toReturn;
+ }
+
+ /**
+ * Find a time <em>in seconds</em> the same or close to {@code wallTimeSeconds} that
+ * satisfies {@code mustMatchDst}. The search begins around the timezone offset transition
+ * with {@code initialTransitionIndex}.
+ *
+ * <p>If {@code mustMatchDst} is {@code true} the method can only return times that
+ * use timezone offsets that satisfy the {@code this.isDst} requirements.
+ * If {@code this.isDst == -1} it means that any offset can be used.
+ *
+ * <p>If {@code mustMatchDst} is {@code false} any offset that covers the
+ * currently set time is acceptable. That is: if {@code this.isDst} == -1, any offset
+ * transition can be used, if it is 0 or 1 the offset used must match {@code this.isDst}.
+ *
+ * <p>Note: This method both uses and can modify field state. It returns the matching time
+ * in seconds if a match has been found and modifies fields, or it returns {@code null} and
+ * leaves the field state unmodified.
+ */
+ private Integer doWallTimeSearch(ZoneInfo zoneInfo, int initialTransitionIndex,
+ int wallTimeSeconds, boolean mustMatchDst) throws CheckedArithmeticException {
+
+ // The loop below starts at the initialTransitionIndex and radiates out from that point
+ // up to 24 hours in either direction by applying transitionIndexDelta to inspect
+ // adjacent transitions (0, -1, +1, -2, +2). 24 hours is used because we assume that no
+ // total offset from UTC is ever > 24 hours. clampTop and clampBottom are used to
+ // indicate whether the search has either searched > 24 hours or exhausted the
+ // transition data in that direction. The search stops when a match is found or if
+ // clampTop and clampBottom are both true.
+ // The match logic employed is determined by the mustMatchDst parameter.
+ final int MAX_SEARCH_SECONDS = 24 * 60 * 60;
+ boolean clampTop = false, clampBottom = false;
+ int loop = 0;
+ do {
+ // transitionIndexDelta = { 0, -1, 1, -2, 2,..}
+ int transitionIndexDelta = (loop + 1) / 2;
+ if (loop % 2 == 1) {
+ transitionIndexDelta *= -1;
+ }
+ loop++;
+
+ // Only do any work in this iteration if we need to.
+ if (transitionIndexDelta > 0 && clampTop
+ || transitionIndexDelta < 0 && clampBottom) {
+ continue;
+ }
+
+ // Obtain the OffsetInterval to use.
+ int currentTransitionIndex = initialTransitionIndex + transitionIndexDelta;
+ OffsetInterval offsetInterval =
+ OffsetInterval.create(zoneInfo, currentTransitionIndex);
+ if (offsetInterval == null) {
+ // No transition exists with the index we tried: Stop searching in the
+ // current direction.
+ clampTop |= (transitionIndexDelta > 0);
+ clampBottom |= (transitionIndexDelta < 0);
+ continue;
+ }
+
+ // Match the wallTimeSeconds against the OffsetInterval.
+ if (mustMatchDst) {
+ // Work out if the interval contains the wall time the caller specified and
+ // matches their isDst value.
+ if (offsetInterval.containsWallTime(wallTimeSeconds)) {
+ if (this.isDst == -1 || offsetInterval.getIsDst() == this.isDst) {
+ // This always returns the first OffsetInterval it finds that matches
+ // the wall time and isDst requirements. If this.isDst == -1 this means
+ // the result might be a DST or a non-DST answer for wall times that can
+ // exist in two OffsetIntervals.
+ int totalOffsetSeconds = offsetInterval.getTotalOffsetSeconds();
+ int returnValue = checkedSubtract(wallTimeSeconds,
+ totalOffsetSeconds);
+
+ copyFieldsFromCalendar();
+ this.isDst = offsetInterval.getIsDst();
+ this.gmtOffsetSeconds = totalOffsetSeconds;
+ return returnValue;
+ }
+ }
+ } else {
+ // To retain similar behavior to the old native implementation: if the caller is
+ // asserting the same isDst value as the OffsetInterval we are looking at we do
+ // not try to find an adjustment from another OffsetInterval of the same isDst
+ // type. If you remove this you get different results in situations like a
+ // DST -> DST transition or STD -> STD transition that results in an interval of
+ // "skipped" wall time. For example: if 01:30 (DST) is invalid and between two
+ // DST intervals, and the caller has passed isDst == 1, this results in a -1
+ // being returned.
+ if (isDst != offsetInterval.getIsDst()) {
+ final int isDstToFind = isDst;
+ Integer returnValue = tryOffsetAdjustments(zoneInfo, wallTimeSeconds,
+ offsetInterval, currentTransitionIndex, isDstToFind);
+ if (returnValue != null) {
+ return returnValue;
+ }
+ }
+ }
+
+ // See if we can avoid another loop in the current direction.
+ if (transitionIndexDelta > 0) {
+ // If we are searching forward and the OffsetInterval we have ends
+ // > MAX_SEARCH_SECONDS after the wall time, we don't need to look any further
+ // forward.
+ boolean endSearch = offsetInterval.getEndWallTimeSeconds() - wallTimeSeconds
+ > MAX_SEARCH_SECONDS;
+ if (endSearch) {
+ clampTop = true;
+ }
+ } else if (transitionIndexDelta < 0) {
+ boolean endSearch = wallTimeSeconds - offsetInterval.getStartWallTimeSeconds()
+ >= MAX_SEARCH_SECONDS;
+ if (endSearch) {
+ // If we are searching backward and the OffsetInterval starts
+ // > MAX_SEARCH_SECONDS before the wall time, we don't need to look any
+ // further backwards.
+ clampBottom = true;
+ }
+ }
+ } while (!(clampTop && clampBottom));
+ return null;
+ }
+
+ public void setYear(int year) {
+ this.year = year;
+ }
+
+ public void setMonth(int month) {
+ this.month = month;
+ }
+
+ public void setMonthDay(int monthDay) {
+ this.monthDay = monthDay;
+ }
+
+ public void setHour(int hour) {
+ this.hour = hour;
+ }
+
+ public void setMinute(int minute) {
+ this.minute = minute;
+ }
+
+ public void setSecond(int second) {
+ this.second = second;
+ }
+
+ public void setWeekDay(int weekDay) {
+ this.weekDay = weekDay;
+ }
+
+ public void setYearDay(int yearDay) {
+ this.yearDay = yearDay;
+ }
+
+ public void setIsDst(int isDst) {
+ this.isDst = isDst;
+ }
+
+ public void setGmtOffset(int gmtoff) {
+ this.gmtOffsetSeconds = gmtoff;
+ }
+
+ public int getYear() {
+ return year;
+ }
+
+ public int getMonth() {
+ return month;
+ }
+
+ public int getMonthDay() {
+ return monthDay;
+ }
+
+ public int getHour() {
+ return hour;
+ }
+
+ public int getMinute() {
+ return minute;
+ }
+
+ public int getSecond() {
+ return second;
+ }
+
+ public int getWeekDay() {
+ return weekDay;
+ }
+
+ public int getYearDay() {
+ return yearDay;
+ }
+
+ public int getGmtOffset() {
+ return gmtOffsetSeconds;
+ }
+
+ public int getIsDst() {
+ return isDst;
+ }
+
+ private void copyFieldsToCalendar() {
+ calendar.set(Calendar.YEAR, year);
+ calendar.set(Calendar.MONTH, month);
+ calendar.set(Calendar.DAY_OF_MONTH, monthDay);
+ calendar.set(Calendar.HOUR_OF_DAY, hour);
+ calendar.set(Calendar.MINUTE, minute);
+ calendar.set(Calendar.SECOND, second);
+ }
+
+ private void copyFieldsFromCalendar() {
+ year = calendar.get(Calendar.YEAR);
+ month = calendar.get(Calendar.MONTH);
+ monthDay = calendar.get(Calendar.DAY_OF_MONTH);
+ hour = calendar.get(Calendar.HOUR_OF_DAY);
+ minute = calendar.get(Calendar.MINUTE);
+ second = calendar.get(Calendar.SECOND);
+
+ // Calendar uses Sunday == 1. Android Time uses Sunday = 0.
+ weekDay = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+ // Calendar enumerates from 1, Android Time enumerates from 0.
+ yearDay = calendar.get(Calendar.DAY_OF_YEAR) - 1;
+ }
+
+ /**
+ * Find the transition in the {@code timezone} in effect at {@code timeSeconds}.
+ *
+ * <p>Returns an index in the range -1..timeZone.mTransitions.length - 1. -1 is used to
+ * indicate the time is before the first transition. Other values are an index into
+ * timeZone.mTransitions.
+ */
+ private static int findTransitionIndex(ZoneInfo timeZone, int timeSeconds) {
+ int matchingRawTransition = Arrays.binarySearch(timeZone.mTransitions, timeSeconds);
+ if (matchingRawTransition < 0) {
+ matchingRawTransition = ~matchingRawTransition - 1;
+ }
+ return matchingRawTransition;
+ }
+ }
+
+ /**
+ * A wall-time representation of a timezone offset interval.
+ *
+ * <p>Wall-time means "as it would appear locally in the timezone in which it applies".
+ * For example in 2007:
+ * PST was a -8:00 offset that ran until Mar 11, 2:00 AM.
+ * PDT was a -7:00 offset and ran from Mar 11, 3:00 AM to Nov 4, 2:00 AM.
+ * PST was a -8:00 offset and ran from Nov 4, 1:00 AM.
+ * Crucially this means that there was a "gap" after PST when PDT started, and an overlap when
+ * PDT ended and PST began.
+ *
+ * <p>For convenience all wall-time values are represented as the number of seconds since the
+ * beginning of the Unix epoch <em>in UTC</em>. To convert from a wall-time to the actual time
+ * in the offset it is necessary to <em>subtract</em> the {@code totalOffsetSeconds}.
+ * For example: If the offset in PST is -07:00 hours, then:
+ * timeInPstSeconds = wallTimeUtcSeconds - offsetSeconds
+ * i.e. 13:00 UTC - (-07:00) = 20:00 UTC = 13:00 PST
+ */
+ static class OffsetInterval {
+
+ private final int startWallTimeSeconds;
+ private final int endWallTimeSeconds;
+ private final int isDst;
+ private final int totalOffsetSeconds;
+
+ /**
+ * Creates an {@link OffsetInterval}.
+ *
+ * <p>If {@code transitionIndex} is -1, the transition is synthesized to be a non-DST offset
+ * that runs from the beginning of time until the first transition in {@code timeZone} and
+ * has an offset of {@code timezone.mRawOffset}. If {@code transitionIndex} is the last
+ * transition that transition is considered to run until the end of representable time.
+ * Otherwise, the information is extracted from {@code timeZone.mTransitions},
+ * {@code timeZone.mOffsets} an {@code timeZone.mIsDsts}.
+ */
+ public static OffsetInterval create(ZoneInfo timeZone, int transitionIndex)
+ throws CheckedArithmeticException {
+
+ if (transitionIndex < -1 || transitionIndex >= timeZone.mTransitions.length) {
+ return null;
+ }
+
+ int rawOffsetSeconds = timeZone.mRawOffset / 1000;
+ if (transitionIndex == -1) {
+ int endWallTimeSeconds = checkedAdd(timeZone.mTransitions[0], rawOffsetSeconds);
+ return new OffsetInterval(Integer.MIN_VALUE, endWallTimeSeconds, 0 /* isDst */,
+ rawOffsetSeconds);
+ }
+
+ byte type = timeZone.mTypes[transitionIndex];
+ int totalOffsetSeconds = timeZone.mOffsets[type] + rawOffsetSeconds;
+ int endWallTimeSeconds;
+ if (transitionIndex == timeZone.mTransitions.length - 1) {
+ // If this is the last transition, make up the end time.
+ endWallTimeSeconds = Integer.MAX_VALUE;
+ } else {
+ endWallTimeSeconds = checkedAdd(timeZone.mTransitions[transitionIndex + 1],
+ totalOffsetSeconds);
+ }
+ int isDst = timeZone.mIsDsts[type];
+ int startWallTimeSeconds =
+ checkedAdd(timeZone.mTransitions[transitionIndex], totalOffsetSeconds);
+ return new OffsetInterval(
+ startWallTimeSeconds, endWallTimeSeconds, isDst, totalOffsetSeconds);
+ }
+
+ private OffsetInterval(int startWallTimeSeconds, int endWallTimeSeconds, int isDst,
+ int totalOffsetSeconds) {
+ this.startWallTimeSeconds = startWallTimeSeconds;
+ this.endWallTimeSeconds = endWallTimeSeconds;
+ this.isDst = isDst;
+ this.totalOffsetSeconds = totalOffsetSeconds;
+ }
+
+ public boolean containsWallTime(long wallTimeSeconds) {
+ return wallTimeSeconds >= startWallTimeSeconds && wallTimeSeconds < endWallTimeSeconds;
+ }
+
+ public int getIsDst() {
+ return isDst;
+ }
+
+ public int getTotalOffsetSeconds() {
+ return totalOffsetSeconds;
+ }
+
+ public long getEndWallTimeSeconds() {
+ return endWallTimeSeconds;
+ }
+
+ public long getStartWallTimeSeconds() {
+ return startWallTimeSeconds;
+ }
+ }
+
+ /**
+ * An exception used to indicate an arithmetic overflow or underflow.
+ */
+ private static class CheckedArithmeticException extends Exception {
+ }
+
+ /**
+ * Calculate (a + b).
+ *
+ * @throws CheckedArithmeticException if overflow or underflow occurs
+ */
+ private static int checkedAdd(int a, int b) throws CheckedArithmeticException {
+ // Adapted from Guava IntMath.checkedAdd();
+ long result = (long) a + b;
+ if (result != (int) result) {
+ throw new CheckedArithmeticException();
+ }
+ return (int) result;
+ }
+
+ /**
+ * Calculate (a - b).
+ *
+ * @throws CheckedArithmeticException if overflow or underflow occurs
+ */
+ private static int checkedSubtract(int a, int b) throws CheckedArithmeticException {
+ // Adapted from Guava IntMath.checkedSubtract();
+ long result = (long) a - b;
+ if (result != (int) result) {
+ throw new CheckedArithmeticException();
+ }
+ return (int) result;
+ }
}
diff --git a/luni/src/main/java/libcore/util/ZoneInfoDB.java b/luni/src/main/java/libcore/util/ZoneInfoDB.java
index 10e3900..a9d06a4 100644
--- a/luni/src/main/java/libcore/util/ZoneInfoDB.java
+++ b/luni/src/main/java/libcore/util/ZoneInfoDB.java
@@ -16,6 +16,7 @@
package libcore.util;
+import android.system.ErrnoException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
@@ -27,7 +28,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.TimeZone;
import libcore.io.BufferIterator;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.MemoryMappedFile;
@@ -62,11 +62,33 @@ public final class ZoneInfoDB {
/**
* The 'ids' array contains time zone ids sorted alphabetically, for binary searching.
* The other two arrays are in the same order. 'byteOffsets' gives the byte offset
- * of each time zone, and 'rawUtcOffsets' gives the time zone's raw UTC offset.
+ * of each time zone, and 'rawUtcOffsetsCache' gives the time zone's raw UTC offset.
*/
private String[] ids;
private int[] byteOffsets;
- private int[] rawUtcOffsets;
+ private int[] rawUtcOffsetsCache; // Access this via getRawUtcOffsets instead.
+
+ /**
+ * ZoneInfo objects are worth caching because they are expensive to create.
+ * See http://b/8270865 for context.
+ */
+ private final static int CACHE_SIZE = 1;
+ private final BasicLruCache<String, ZoneInfo> cache =
+ new BasicLruCache<String, ZoneInfo>(CACHE_SIZE) {
+ @Override
+ protected ZoneInfo create(String id) {
+ // Work out where in the big data file this time zone is.
+ int index = Arrays.binarySearch(ids, id);
+ if (index < 0) {
+ return null;
+ }
+
+ BufferIterator it = mappedFile.bigEndianIterator();
+ it.skip(byteOffsets[index]);
+
+ return ZoneInfo.makeTimeZone(id, it);
+ }
+ };
public TzData(String... paths) {
for (String path : paths) {
@@ -82,7 +104,7 @@ public final class ZoneInfoDB {
version = "missing";
zoneTab = "# Emergency fallback data.\n";
ids = new String[] { "GMT" };
- byteOffsets = rawUtcOffsets = new int[1];
+ byteOffsets = rawUtcOffsetsCache = new int[1];
}
private boolean loadData(String path) {
@@ -149,7 +171,6 @@ public final class ZoneInfoDB {
int idOffset = 0;
byteOffsets = new int[entryCount];
- rawUtcOffsets = new int[entryCount];
for (int i = 0; i < entryCount; i++) {
it.readByteArray(idBytes, 0, idBytes.length);
@@ -161,7 +182,7 @@ public final class ZoneInfoDB {
if (length < 44) {
throw new AssertionError("length in index file < sizeof(tzhead)");
}
- rawUtcOffsets[i] = it.readInt();
+ it.skip(4); // Skip the unused 4 bytes that used to be the raw offset.
// Don't include null chars in the String
int len = idBytes.length;
@@ -188,16 +209,33 @@ public final class ZoneInfoDB {
return ids.clone();
}
- public String[] getAvailableIDs(int rawOffset) {
+ public String[] getAvailableIDs(int rawUtcOffset) {
List<String> matches = new ArrayList<String>();
- for (int i = 0, end = rawUtcOffsets.length; i < end; ++i) {
- if (rawUtcOffsets[i] == rawOffset) {
+ int[] rawUtcOffsets = getRawUtcOffsets();
+ for (int i = 0; i < rawUtcOffsets.length; ++i) {
+ if (rawUtcOffsets[i] == rawUtcOffset) {
matches.add(ids[i]);
}
}
return matches.toArray(new String[matches.size()]);
}
+ private synchronized int[] getRawUtcOffsets() {
+ if (rawUtcOffsetsCache != null) {
+ return rawUtcOffsetsCache;
+ }
+ rawUtcOffsetsCache = new int[ids.length];
+ for (int i = 0; i < ids.length; ++i) {
+ // This creates a TimeZone, which is quite expensive. Hence the cache.
+ // Note that icu4c does the same (without the cache), so if you're
+ // switching this code over to icu4j you should check its performance.
+ // Telephony shouldn't care, but someone converting a bunch of calendar
+ // events might.
+ rawUtcOffsetsCache[i] = cache.get(ids[i]).getRawOffset();
+ }
+ return rawUtcOffsetsCache;
+ }
+
public String getVersion() {
return version;
}
@@ -206,17 +244,10 @@ public final class ZoneInfoDB {
return zoneTab;
}
- public TimeZone makeTimeZone(String id) throws IOException {
- // Work out where in the big data file this time zone is.
- int index = Arrays.binarySearch(ids, id);
- if (index < 0) {
- return null;
- }
-
- BufferIterator it = mappedFile.bigEndianIterator();
- it.skip(byteOffsets[index]);
-
- return ZoneInfo.makeTimeZone(id, it);
+ public ZoneInfo makeTimeZone(String id) throws IOException {
+ ZoneInfo zoneInfo = cache.get(id);
+ // The object from the cache is cloned because TimeZone / ZoneInfo are mutable.
+ return zoneInfo == null ? null : (ZoneInfo) zoneInfo.clone();
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/DeleteOnExit.java b/luni/src/main/java/org/apache/harmony/luni/util/DeleteOnExit.java
deleted file mode 100644
index 8fa04fd..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/util/DeleteOnExit.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.util;
-
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Implements the actual DeleteOnExit mechanism. Is registered as a shutdown
- * hook in the Runtime, once it is actually being used.
- */
-public class DeleteOnExit extends Thread {
-
- /**
- * Our singleton instance.
- */
- private static DeleteOnExit instance;
-
- /**
- * Our list of files scheduled for deletion.
- */
- private ArrayList<String> files = new ArrayList<String>();
-
- /**
- * Returns our singleton instance, creating it if necessary.
- */
- public static synchronized DeleteOnExit getInstance() {
- if (instance == null) {
- instance = new DeleteOnExit();
- Runtime.getRuntime().addShutdownHook(instance);
- }
-
- return instance;
- }
-
- /**
- * Schedules a file for deletion.
- *
- * @param filename The file to delete.
- */
- public void addFile(String filename) {
- synchronized(files) {
- if (!files.contains(filename)) {
- files.add(filename);
- }
- }
- }
-
- /**
- * Does the actual work. Note we (a) first sort the files lexicographically
- * and then (b) delete them in reverse order. This is to make sure files
- * get deleted before their parent directories.
- */
- @Override
- public void run() {
- Collections.sort(files);
- for (int i = files.size() - 1; i >= 0; i--) {
- new File(files.get(i)).delete();
- }
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java b/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java
index f1dd43c..855a8c7 100644
--- a/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java
+++ b/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java
@@ -24,15 +24,15 @@ package org.apache.harmony.security.fortress;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
+import java.util.ArrayList;
import java.util.Locale;
-
/**
* This class implements common functionality for Provider supplied
* classes. The usage pattern is to allocate static Engine instance
* per service type and synchronize on that instance during calls to
- * {@code getInstance} and retreival of the selected {@code Provider}
- * and Service Provider Interface (SPI) results. Retreiving the
+ * {@code getInstance} and retrieval of the selected {@code Provider}
+ * and Service Provider Interface (SPI) results. Retrieving the
* results with {@code getProvider} and {@code getSpi} sets the
* internal {@code Engine} values to null to prevent memory leaks.
*
@@ -69,7 +69,7 @@ import java.util.Locale;
*
* }</pre>
*/
-public class Engine {
+public final class Engine {
/**
* Access to package visible api in java.security
@@ -95,14 +95,14 @@ public class Engine {
/** used to test for cache validity */
private final int cacheVersion;
/** cached result */
- private final Provider.Service service;
+ private final ArrayList<Provider.Service> services;
private ServiceCacheEntry(String algorithm,
int cacheVersion,
- Provider.Service service) {
+ ArrayList<Provider.Service> services) {
this.algorithm = algorithm;
this.cacheVersion = cacheVersion;
- this.service = service;
+ this.services = services;
}
}
@@ -118,47 +118,60 @@ public class Engine {
/**
* Creates a Engine object
*
- * @param service
+ * @param serviceName
*/
- public Engine(String service) {
- this.serviceName = service;
+ public Engine(String serviceName) {
+ this.serviceName = serviceName;
}
/**
* Finds the appropriate service implementation and returns an
- * {@code SpiAndProvider} instance containing a reference to SPI
- * and its {@code Provider}
+ * {@code SpiAndProvider} instance containing a reference to the first
+ * matching SPI and its {@code Provider}
*/
public SpiAndProvider getInstance(String algorithm, Object param)
throws NoSuchAlgorithmException {
if (algorithm == null) {
throw new NoSuchAlgorithmException("Null algorithm name");
}
+ ArrayList<Provider.Service> services = getServices(algorithm);
+ if (services == null) {
+ throw notFound(this.serviceName, algorithm);
+ }
+ return new SpiAndProvider(services.get(0).newInstance(param), services.get(0).getProvider());
+ }
+
+ /**
+ * Finds the appropriate service implementation and returns an
+ * {@code SpiAndProvider} instance containing a reference to SPI
+ * and its {@code Provider}
+ */
+ public SpiAndProvider getInstance(Provider.Service service, String param)
+ throws NoSuchAlgorithmException {
+ return new SpiAndProvider(service.newInstance(param), service.getProvider());
+ }
+
+ /**
+ * Returns a list of all possible matches for a given algorithm.
+ */
+ public ArrayList<Provider.Service> getServices(String algorithm) {
int newCacheVersion = Services.getCacheVersion();
- Provider.Service service;
ServiceCacheEntry cacheEntry = this.serviceCache;
+ final String algoUC = algorithm.toUpperCase(Locale.US);
if (cacheEntry != null
- && cacheEntry.algorithm.equalsIgnoreCase(algorithm)
+ && cacheEntry.algorithm.equalsIgnoreCase(algoUC)
&& newCacheVersion == cacheEntry.cacheVersion) {
- service = cacheEntry.service;
- } else {
- if (Services.isEmpty()) {
- throw notFound(serviceName, algorithm);
- }
- String name = this.serviceName + "." + algorithm.toUpperCase(Locale.US);
- service = Services.getService(name);
- if (service == null) {
- throw notFound(serviceName, algorithm);
- }
- this.serviceCache = new ServiceCacheEntry(algorithm, newCacheVersion, service);
+ return cacheEntry.services;
}
- return new SpiAndProvider(service.newInstance(param), service.getProvider());
+ String name = this.serviceName + "." + algoUC;
+ ArrayList<Provider.Service> services = Services.getServices(name);
+ this.serviceCache = new ServiceCacheEntry(algoUC, newCacheVersion, services);
+ return services;
}
/**
- * Finds the appropriate service implementation and returns and
- * instance of the class that implements corresponding Service
- * Provider Interface.
+ * Finds the appropriate service implementation and returns and instance of
+ * the class that implements corresponding Service Provider Interface.
*/
public Object getInstance(String algorithm, Provider provider, Object param)
throws NoSuchAlgorithmException {
diff --git a/luni/src/main/java/org/apache/harmony/security/fortress/Services.java b/luni/src/main/java/org/apache/harmony/security/fortress/Services.java
index 4fe0d44..30f4839 100644
--- a/luni/src/main/java/org/apache/harmony/security/fortress/Services.java
+++ b/luni/src/main/java/org/apache/harmony/security/fortress/Services.java
@@ -21,9 +21,7 @@ import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Locale;
-import java.util.Map;
/**
@@ -38,8 +36,8 @@ public class Services {
* Set the initial size to 600 so we don't grow to 1024 by default because
* initialization adds a few entries more than the growth threshold.
*/
- private static final Map<String, Provider.Service> services
- = new HashMap<String, Provider.Service>(600);
+ private static final HashMap<String, ArrayList<Provider.Service>> services
+ = new HashMap<String, ArrayList<Provider.Service>>(600);
/**
* Save default SecureRandom service as well.
@@ -62,12 +60,13 @@ public class Services {
/**
* Registered providers.
*/
- private static final List<Provider> providers = new ArrayList<Provider>(20);
+ private static final ArrayList<Provider> providers = new ArrayList<Provider>(20);
/**
* Hash for quick provider access by name.
*/
- private static final Map<String, Provider> providersNames = new HashMap<String, Provider>(20);
+ private static final HashMap<String, Provider> providersNames
+ = new HashMap<String, Provider>(20);
static {
String providerClassName = null;
int i = 1;
@@ -75,7 +74,7 @@ public class Services {
while ((providerClassName = Security.getProperty("security.provider." + i++)) != null) {
try {
- Class providerClass = Class.forName(providerClassName.trim(), true, cl);
+ Class<?> providerClass = Class.forName(providerClassName.trim(), true, cl);
Provider p = (Provider) providerClass.newInstance();
providers.add(p);
providersNames.put(p.getName(), p);
@@ -91,15 +90,8 @@ public class Services {
/**
* Returns a copy of the registered providers as an array.
*/
- public static synchronized Provider[] getProviders() {
- return providers.toArray(new Provider[providers.size()]);
- }
-
- /**
- * Returns a copy of the registered providers as a list.
- */
- public static synchronized List<Provider> getProvidersList() {
- return new ArrayList<Provider>(providers);
+ public static synchronized ArrayList<Provider> getProviders() {
+ return providers;
}
/**
@@ -145,20 +137,28 @@ public class Services {
cachedSecureRandomService = service;
}
String key = type + "." + service.getAlgorithm().toUpperCase(Locale.US);
- if (!services.containsKey(key)) {
- services.put(key, service);
- }
+ appendServiceLocked(key, service);
for (String alias : Engine.door.getAliases(service)) {
key = type + "." + alias.toUpperCase(Locale.US);
- if (!services.containsKey(key)) {
- services.put(key, service);
- }
+ appendServiceLocked(key, service);
}
}
}
/**
- * Returns true if services contain any provider information.
+ * Add or append the service to the key.
+ */
+ private static void appendServiceLocked(String key, Provider.Service service) {
+ ArrayList<Provider.Service> serviceList = services.get(key);
+ if (serviceList == null) {
+ serviceList = new ArrayList<Provider.Service>(1);
+ services.put(key, serviceList);
+ }
+ serviceList.add(service);
+ }
+
+ /**
+ * Returns true if services does not contain any provider information.
*/
public static synchronized boolean isEmpty() {
return services.isEmpty();
@@ -174,7 +174,7 @@ public class Services {
* caches should be validated against the result of
* Service.getCacheVersion() before use.
*/
- public static synchronized Provider.Service getService(String key) {
+ public static synchronized ArrayList<Provider.Service> getServices(String key) {
return services.get(key);
}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/cert/Cache.java b/luni/src/main/java/org/apache/harmony/security/provider/cert/Cache.java
deleted file mode 100644
index a2c5b4c..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/cert/Cache.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @author Alexander Y. Kleymenov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.provider.cert;
-
-import java.util.Arrays;
-
-/**
- * The caching mechanism designed to speed up the process
- * of Certificates/CRLs generation in the case of their repeated
- * generation.
- *
- * It keeps correspondences between Objects (Certificates or CLRs)
- * and arrays of bytes on the base of which the Objects have been generated,
- * and provides the means to determine whether it contains the object built on
- * the base of particular encoded form or not. If there are such
- * objects they are returned from the cache, if not - newly generated
- * objects can be saved in the cache.<br>
- *
- * The process of Certificate/CRL generation
- * (implemented in <code>X509CertFactoryImpl</code>) is accompanied with
- * prereading of the beginning of encoded form. This prefix is used to determine
- * whether provided form is PEM encoding or not.<br>
- *
- * So the use of the prefix is the first point to (approximately)
- * determine whether object to be generated is in the cache or not.
- *
- * The failure of the predetermination process tells us that there were not
- * object generated from the encoded form with such prefix and we should
- * generate (decode) the object. If predetermination is successful,
- * we conduct the accurate search on the base of whole encoded form. <br>
- *
- * So to speed up the object generation process this caching mechanism provides
- * the following functionality:<br>
- *
- * 1. With having of the beginning of the encoded form (prefix)
- * it is possible to predetermine whether object has already been
- * generated on the base of the encoding with the SIMILAR prefix or not.
- * This process is not computationally expensive and takes a little time.
- * But it prevents us from use of expensive full encoding
- * search in the case of its failure.<br>
- *
- * 2. If predetermination ends with success, the whole encoding
- * form should be provided to make the final answer: whether object has
- * already been generated on the base of this PARTICULAR encoded form or not.
- * If it is so - the cached object is returned from the cache,
- * if not - new object should be generated and saved in the cache.<br>
- *
- * Note: The length of the prefixes of the encoded forms should not be
- * less than correspondence (default value is 28).
- */
-public class Cache {
-
- // Hash code consist of 6 bytes: AABB00
- // where:
- // AA - 2 bytes for prefix hash
- // value generated on the base of the prefix of encoding
- // BB - 2 bytes for tail hash
- // value generated on the base of the tail of encoding
- // 00 - 2 reserved bytes equals to 0
- //
- // Note, that it is possible for 2 different arrays to have
- // the similar hash codes.
-
- // The masks to work with hash codes:
- // the hash code without the reserved bytes
- private static final long HASH_MASK = 0xFFFFFFFFFFFF0000L;
- // the hash code of the prefix
- private static final long PREFIX_HASH_MASK = 0xFFFFFFFF00000000L;
- // the index value contained in reserved bytes
- private static final int INDEX_MASK = 0x00FFFF;
-
- // size of the cache
- private final int cache_size;
- // the number of bytes which will be used for array hash generation.
- private final int prefix_size;
-
- // The following 3 arrays contain the information about cached objects.
- // This information includes: hash of the array, encoded form of the object,
- // and the object itself.
- // The hash-encoding-object correspondence is made by means of index
- // in the particular array. I.e. for index N hash contained in hashes[N]
- // corresponds to the encoding contained in encodings[N] which corresponds
- // to the object cached at cache[N]
-
- // array containing the hash codes of encodings
- private final long[] hashes;
- // array containing the encodings of the cached objects
- private final byte[][] encodings;
- // array containing the cached objects
- private final Object[] cache;
-
- // This array is used to speed up the process of the search in the cache.
- // This is an ordered array of the hash codes from 'hashes' array (described
- // above) with last 2 (reserved) bytes equals to the index of
- // the hash in the 'hashes' array. I.e. hash code ABCD00 with index 10 in
- // the hashes array will be represented in this array as ABCD0A (10==0x0A)
- // So this array contains ordered <hash to index> correspondences.
- // Note, that every item in this array is unique.
- private final long[] hashes_idx;
-
- // the index of the last cached object
- private int last_cached = 0;
- // cache population indicator
- private boolean cache_is_full = false;
-
- /**
- * Creates the Cache object.
- * @param pref_size specifies how many leading/trailing bytes of object's
- * encoded form will be used for hash computation
- * @param size capacity of the cache to be created.
- */
- public Cache(int pref_size, int size) {
- cache_size = size;
- prefix_size = pref_size;
- hashes = new long[cache_size];
- hashes_idx = new long[cache_size];
- encodings = new byte[cache_size][];
- cache = new Object[cache_size];
- }
-
- /**
- * Creates the Cache object of size of 9.
- * @param pref_size specifies how many leading/trailing bytes of object's
- * encoded form will be used for hash computation
- */
- public Cache(int pref_size) {
- this(pref_size, 9);
- }
-
- /**
- * Creates the Cache object of size of 9.
- */
- public Cache() {
- this(28, 9);
- }
-
- /**
- * Returns the hash code for the array. This code is used to
- * predetermine whether the object was built on the base of the
- * similar encoding or not (by means of <code>contains(long)</code> method),
- * to exactly determine whether object is contained in the cache or not,
- * and to put the object in the cache.
- * Note: parameter array should be of length not less than
- * specified by <code>prefix_size</code> (default 28)
- * @param arr the byte array containing at least prefix_size leading bytes
- * of the encoding.
- * @return hash code for specified encoding prefix
- */
- public long getHash(byte[] arr) {
- long hash = 0;
- for (int i=1; i<prefix_size; i++) {
- hash += (arr[i] & 0xFF);
- } // it takes about 2 bytes for prefix_size == 28
-
- // shift to the correct place
- hash = hash << 32;
- return hash;
- }
-
- /**
- * Checks if there are any object in the cache generated
- * on the base of encoding with prefix corresponding
- * to the specified hash code.
- * @param prefix_hash the hash code for the prefix
- * of the encoding (retrieved by method <code>getHash(byte[]))</code>
- * @return false if there were not any object generated
- * on the base of encoding with specified hash code, true
- * otherwise.
- */
- public boolean contains(long prefix_hash) {
- if (prefix_hash == 0) {
- return false;
- }
- int idx = -1*Arrays.binarySearch(hashes_idx, prefix_hash)-1;
- if (idx == cache_size) {
- return false;
- } else {
- return (hashes_idx[idx] & PREFIX_HASH_MASK) == prefix_hash;
- }
- }
-
- /**
- * Returns the object built on the base on the specified encoded
- * form if it is contained in the cache and null otherwise.
- * This method is computationally expensive and should be called only if
- * the method <code>contains(long)</code> for the hash code returned true.
- * @param hash the hash code for the prefix of the encoding
- * (retrieved by method <code>getHash(byte[])</code>)
- * @param encoding encoded form of the required object.
- * @return the object corresponding to specified encoding or null if
- * there is no such correspondence.
- */
- public Object get(long hash, byte[] encoding) {
- hash |= getSuffHash(encoding);
- if (hash == 0) {
- return null;
- }
- int idx = -1*Arrays.binarySearch(hashes_idx, hash)-1;
- if (idx == cache_size) {
- return null;
- }
- while ((hashes_idx[idx] & HASH_MASK) == hash) {
- int i = (int) (hashes_idx[idx] & INDEX_MASK) - 1;
- if (Arrays.equals(encoding, encodings[i])) {
- return cache[i];
- }
- idx++;
- if (idx == cache_size) {
- return null;
- }
- }
- return null;
- }
-
- /**
- * Puts the object into the cache.
- * @param hash hash code for the prefix of the encoding
- * @param encoding the encoded form of the object
- * @param object the object to be saved in the cache
- */
- public void put(long hash, byte[] encoding, Object object) {
- // check for empty space in the cache
- if (last_cached == cache_size) {
- // so cache is full, will erase the first entry in the
- // cache (oldest entry). it could be better to throw out
- // rarely used value instead of oldest one..
- last_cached = 0;
- cache_is_full = true;
- }
- // index pointing to the item of the table to be overwritten
- int index = last_cached++;
-
- // improve the hash value with info from the tail of encoding
- hash |= getSuffHash(encoding);
-
- if (cache_is_full) {
- // indexing hash value to be overwritten:
- long idx_hash = (hashes[index] | (index+1));
- int idx = Arrays.binarySearch(hashes_idx, idx_hash);
- if (idx < 0) {
- // it will never happen because we use saved hash value
- // (hashes[index])
- System.out.println("WARNING! "+idx);
- idx = -(idx + 1);
- }
- long new_hash_idx = (hash | (index + 1));
- int new_idx = Arrays.binarySearch(hashes_idx, new_hash_idx);
- if (new_idx >= 0) {
- // it's possible when we write the same hash in the same cell
- if (idx != new_idx) {
- // it will never happen because we use the same
- // hash and the same index in hash table
- System.out.println("WARNING: ");
- System.out.println(">> idx: "+idx+" new_idx: "+new_idx);
- }
- } else {
- new_idx = -(new_idx + 1);
- // replace in sorted array
- if (new_idx > idx) {
- System.arraycopy(hashes_idx, idx+1, hashes_idx, idx,
- new_idx - idx - 1);
- hashes_idx[new_idx-1] = new_hash_idx;
- } else if (idx > new_idx) {
- System.arraycopy(hashes_idx, new_idx, hashes_idx, new_idx+1,
- idx - new_idx);
- hashes_idx[new_idx] = new_hash_idx;
- } else { // idx == new_idx
- hashes_idx[new_idx] = new_hash_idx;
- }
- }
- } else {
- long idx_hash = (hash | (index + 1));
- int idx = Arrays.binarySearch(hashes_idx, idx_hash);
- if (idx < 0) {
- // it will always be true because idx_hash depends on index
- idx = -(idx + 1);
- }
- idx = idx - 1;
- if (idx != cache_size - index - 1) {
- // if not in the cell containing 0 (free cell), do copy:
- System.arraycopy(hashes_idx, cache_size - index,
- hashes_idx, cache_size - index - 1,
- idx - (cache_size - index) + 1);
- }
- hashes_idx[idx] = idx_hash;
- }
- // overwrite the values in the tables:
- hashes[index] = hash;
- encodings[index] = encoding;
- cache[index] = object;
- }
-
- // Returns the hash code built on the base of the tail of the encoded form
- // @param arr - the array containing at least prefix_size trailing bytes
- // of encoded form
- private long getSuffHash(byte[] arr) {
- long hash_addon = 0;
- for (int i=arr.length-1; i>arr.length - prefix_size; i--) {
- hash_addon += (arr[i] & 0xFF);
- }
- return hash_addon << 16;
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/cert/DRLCertFactory.java b/luni/src/main/java/org/apache/harmony/security/provider/cert/DRLCertFactory.java
deleted file mode 100644
index 790be67..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/cert/DRLCertFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @author Alexander Y. Kleymenov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.provider.cert;
-
-import java.security.Provider;
-
-public final class DRLCertFactory extends Provider {
- /**
- * @serial
- */
- private static final long serialVersionUID = -7269650779605195879L;
-
- /**
- * Constructs the instance of the certificate factory provider.
- */
- public DRLCertFactory() {
- // specification of the provider name, version, and description.
- super("DRLCertFactory", 1.0, "ASN.1, DER, PkiPath, PKCS7");
- // register the service
- put("CertificateFactory.X509", "org.apache.harmony.security.provider.cert.X509CertFactoryImpl");
- // mapping the alias
- put("Alg.Alias.CertificateFactory.X.509", "X509");
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CRLEntryImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CRLEntryImpl.java
deleted file mode 100644
index 38500e5..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CRLEntryImpl.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @author Alexander Y. Kleymenov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.provider.cert;
-
-import java.math.BigInteger;
-import java.security.cert.CRLException;
-import java.security.cert.X509CRLEntry;
-import java.util.Date;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-import org.apache.harmony.security.x509.Extension;
-import org.apache.harmony.security.x509.Extensions;
-import org.apache.harmony.security.x509.TBSCertList;
-
-/**
- * Implementation of X509CRLEntry. It wraps the instance
- * of org.apache.harmony.security.x509.TBSCertList.RevokedCertificate
- * obtained during the decoding of TBSCertList substructure
- * of the CertificateList structure which is an X.509 form of CRL.
- * (see RFC 3280 at http://www.ietf.org/rfc/rfc3280.txt)
- * Normally the instances of this class are constructed by involving
- * X509CRLImpl object.
- * @see org.apache.harmony.security.x509.TBSCertList
- * @see org.apache.harmony.security.provider.cert.X509CRLImpl
- * @see java.security.cert.X509CRLEntry
- */
-public class X509CRLEntryImpl extends X509CRLEntry {
-
- // the crl entry object to be wrapped in X509CRLEntry
- private final TBSCertList.RevokedCertificate rcert;
- // the extensions of the entry
- private final Extensions extensions;
- // issuer of the revoked certificate described by this crl entry
- private final X500Principal issuer;
-
- // encoded form of this revoked certificate entry
- private byte[] encoding;
-
- /**
- * Creates an instance on the base of existing
- * <code>TBSCertList.RevokedCertificate</code> object and
- * information about the issuer of revoked certificate.
- * If specified issuer is null, it is supposed that issuer
- * of the revoked certificate is the same as for involving CRL.
- */
- public X509CRLEntryImpl(TBSCertList.RevokedCertificate rcert,
- X500Principal issuer) {
- this.rcert = rcert;
- this.extensions = rcert.getCrlEntryExtensions();
- this.issuer = issuer;
- }
-
- // ---------------------------------------------------------------------
- // ------ java.security.cert.X509CRLEntry method implementations -------
- // ---------------------------------------------------------------------
-
- /**
- * @see java.security.cert.X509CRLEntry#getEncoded()
- * method documentation for more info
- */
- public byte[] getEncoded() throws CRLException {
- if (encoding == null) {
- encoding = rcert.getEncoded();
- }
- byte[] result = new byte[encoding.length];
- System.arraycopy(encoding, 0, result, 0, encoding.length);
- return result;
- }
-
- /**
- * @see java.security.cert.X509CRLEntry#getSerialNumber()
- * method documentation for more info
- */
- public BigInteger getSerialNumber() {
- return rcert.getUserCertificate();
- }
-
- /**
- * @see java.security.cert.X509CRLEntry#getCertificateIssuer()
- * method documentation for more info
- */
- public X500Principal getCertificateIssuer() {
- return issuer;
- }
-
- /**
- * @see java.security.cert.X509CRLEntry#getRevocationDate()
- * method documentation for more info
- */
- public Date getRevocationDate() {
- return rcert.getRevocationDate();
- }
-
- /**
- * @see java.security.cert.X509CRLEntry#hasExtensions()
- * method documentation for more info
- */
- public boolean hasExtensions() {
- return (extensions != null) && (extensions.size() != 0);
- }
-
- /**
- * @see java.security.cert.X509CRLEntry#toString()
- * method documentation for more info
- */
- public String toString() {
- return "X509CRLEntryImpl: "+rcert.toString();
- }
-
- // ---------------------------------------------------------------------
- // ------ java.security.cert.X509Extension method implementations ------
- // ---------------------------------------------------------------------
-
- /**
- * @see java.security.cert.X509Extension#getNonCriticalExtensionOIDs()
- * method documentation for more info
- */
- public Set getNonCriticalExtensionOIDs() {
- if (extensions == null) {
- return null;
- }
- return extensions.getNonCriticalExtensions();
- }
-
- /**
- * @see java.security.cert.X509Extension#getCriticalExtensionOIDs()
- * method documentation for more info
- */
- public Set getCriticalExtensionOIDs() {
- if (extensions == null) {
- return null;
- }
- return extensions.getCriticalExtensions();
- }
-
- /**
- * @see java.security.cert.X509Extension#getExtensionValue(String)
- * method documentation for more info
- */
- public byte[] getExtensionValue(String oid) {
- if (extensions == null) {
- return null;
- }
- Extension ext = extensions.getExtensionByOID(oid);
- return (ext == null) ? null : ext.getRawExtnValue();
- }
-
- /**
- * @see java.security.cert.X509Extension#hasUnsupportedCriticalExtension()
- * method documentation for more info
- */
- public boolean hasUnsupportedCriticalExtension() {
- if (extensions == null) {
- return false;
- }
- return extensions.hasUnsupportedCritical();
- }
-}
-
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CRLImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CRLImpl.java
deleted file mode 100644
index 68ec38a..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CRLImpl.java
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @author Alexander Y. Kleymenov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.provider.cert;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CRLException;
-import java.security.cert.Certificate;
-import java.security.cert.X509CRL;
-import java.security.cert.X509CRLEntry;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.apache.harmony.security.x509.CertificateList;
-import org.apache.harmony.security.x509.Extension;
-import org.apache.harmony.security.x509.Extensions;
-import org.apache.harmony.security.x509.TBSCertList;
-
-/**
- * This class is an implementation of X509CRL. It wraps
- * the instance of org.apache.harmony.security.x509.CertificateList
- * built on the base of provided ASN.1 DER encoded form of
- * CertificateList structure (as specified in RFC 3280
- * http://www.ietf.org/rfc/rfc3280.txt).
- * Implementation supports work with indirect CRLs.
- * @see org.apache.harmony.security.x509.CertificateList
- * @see java.security.cert.X509CRL
- */
-public class X509CRLImpl extends X509CRL {
-
- // the core object to be wrapped in X509CRL
- private final CertificateList crl;
-
- // To speed up access to the info, the following fields
- // cache values retrieved from the CertificateList object
- private final TBSCertList tbsCertList;
- private byte[] tbsCertListEncoding;
- private final Extensions extensions;
- private X500Principal issuer;
- private ArrayList entries;
- private int entriesSize;
- private byte[] signature;
- private String sigAlgOID;
- private String sigAlgName;
- private byte[] sigAlgParams;
-
- // encoded form of crl
- private byte[] encoding;
-
- // indicates whether the signature algorithm parameters are null
- private boolean nullSigAlgParams;
- // indicates whether the crl entries have already been retrieved
- // from CertificateList object (crl)
- private boolean entriesRetrieved;
-
- // indicates whether this X.509 CRL is direct or indirect
- // (see rfc 3280 http://www.ietf.org/rfc/rfc3280.txt, p 5.)
- private boolean isIndirectCRL;
- // if crl is indirect, this field holds an info about how
- // many of the leading certificates in the list are issued
- // by the same issuer as CRL.
- private int nonIndirectEntriesSize;
-
- /**
- * Creates X.509 CRL by wrapping of the specified CertificateList object.
- */
- public X509CRLImpl(CertificateList crl) {
- this.crl = crl;
- this.tbsCertList = crl.getTbsCertList();
- this.extensions = tbsCertList.getCrlExtensions();
- }
-
- /**
- * Creates X.509 CRL on the base of ASN.1 DER encoded form of
- * the CRL (CertificateList structure described in RFC 3280)
- * provided via input stream.
- * @throws CRLException if decoding errors occur.
- */
- public X509CRLImpl(InputStream in) throws CRLException {
- try {
- // decode CertificateList structure
- this.crl = (CertificateList) CertificateList.ASN1.decode(in);
- this.tbsCertList = crl.getTbsCertList();
- this.extensions = tbsCertList.getCrlExtensions();
- } catch (IOException e) {
- throw new CRLException(e);
- }
- }
-
- /**
- * Creates X.509 CRL on the base of ASN.1 DER encoded form of
- * the CRL (CertificateList structure described in RFC 3280)
- * provided via array of bytes.
- * @throws IOException if decoding errors occur.
- */
- public X509CRLImpl(byte[] encoding) throws IOException {
- this((CertificateList) CertificateList.ASN1.decode(encoding));
- }
-
- // ---------------------------------------------------------------------
- // ----- java.security.cert.X509CRL abstract method implementations ----
- // ---------------------------------------------------------------------
-
- /**
- * @see java.security.cert.X509CRL#getEncoded()
- * method documentation for more info
- */
- public byte[] getEncoded() throws CRLException {
- if (encoding == null) {
- encoding = crl.getEncoded();
- }
- byte[] result = new byte[encoding.length];
- System.arraycopy(encoding, 0, result, 0, encoding.length);
- return result;
- }
-
- /**
- * @see java.security.cert.X509CRL#getVersion()
- * method documentation for more info
- */
- public int getVersion() {
- return tbsCertList.getVersion();
- }
-
- /**
- * @see java.security.cert.X509CRL#getIssuerDN()
- * method documentation for more info
- */
- public Principal getIssuerDN() {
- if (issuer == null) {
- issuer = tbsCertList.getIssuer().getX500Principal();
- }
- return issuer;
- }
-
- /**
- * @see java.security.cert.X509CRL#getIssuerX500Principal()
- * method documentation for more info
- */
- public X500Principal getIssuerX500Principal() {
- if (issuer == null) {
- issuer = tbsCertList.getIssuer().getX500Principal();
- }
- return issuer;
- }
-
- /**
- * @see java.security.cert.X509CRL#getThisUpdate()
- * method documentation for more info
- */
- public Date getThisUpdate() {
- return tbsCertList.getThisUpdate();
- }
-
- /**
- * @see java.security.cert.X509CRL#getNextUpdate()
- * method documentation for more info
- */
- public Date getNextUpdate() {
- return tbsCertList.getNextUpdate();
- }
-
- /*
- * Retrieves the crl entries (TBSCertList.RevokedCertificate objects)
- * from the TBSCertList structure and converts them to the
- * X509CRLEntryImpl objects
- */
- private void retrieveEntries() {
- entriesRetrieved = true;
- List rcerts = tbsCertList.getRevokedCertificates();
- if (rcerts == null) {
- return;
- }
- entriesSize = rcerts.size();
- entries = new ArrayList(entriesSize);
- // null means that revoked certificate issuer is the same as CRL issuer
- X500Principal rcertIssuer = null;
- for (int i=0; i<entriesSize; i++) {
- TBSCertList.RevokedCertificate rcert =
- (TBSCertList.RevokedCertificate) rcerts.get(i);
- X500Principal iss = rcert.getIssuer();
- if (iss != null) {
- // certificate issuer differs from CRL issuer
- // and CRL is indirect.
- rcertIssuer = iss;
- isIndirectCRL = true;
- // remember how many leading revoked certificates in the
- // list are issued by the same issuer as issuer of CRL
- // (these certificates are first in the list)
- nonIndirectEntriesSize = i;
- }
- entries.add(new X509CRLEntryImpl(rcert, rcertIssuer));
- }
- }
-
- /**
- * Searches for certificate in CRL.
- * This method supports indirect CRLs: if CRL is indirect method takes
- * into account serial number and issuer of the certificate,
- * if CRL issued by CA (i.e. it is not indirect) search is done only
- * by serial number of the specified certificate.
- * @see java.security.cert.X509CRL#getRevokedCertificate(X509Certificate)
- * method documentation for more info
- */
- public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
- if (certificate == null) {
- throw new NullPointerException("certificate == null");
- }
- if (!entriesRetrieved) {
- retrieveEntries();
- }
- if (entries == null) {
- return null;
- }
- BigInteger serialN = certificate.getSerialNumber();
- if (isIndirectCRL) {
- // search in indirect crl
- X500Principal certIssuer = certificate.getIssuerX500Principal();
- if (certIssuer.equals(getIssuerX500Principal())) {
- // certificate issuer is CRL issuer
- certIssuer = null;
- }
- for (int i=0; i<entriesSize; i++) {
- X509CRLEntry entry = (X509CRLEntry) entries.get(i);
- // check the serial number of revoked certificate
- if (serialN.equals(entry.getSerialNumber())) {
- // revoked certificate issuer
- X500Principal iss = entry.getCertificateIssuer();
- // check the issuer of revoked certificate
- if (certIssuer != null) {
- // certificate issuer is not a CRL issuer, so
- // check issuers for equality
- if (certIssuer.equals(iss)) {
- return entry;
- }
- } else if (iss == null) {
- // both certificates was issued by CRL issuer
- return entry;
- }
- }
- }
- } else {
- // search in CA's (non indirect) crl: just look up the serial number
- for (int i=0; i<entriesSize; i++) {
- X509CRLEntry entry = (X509CRLEntry) entries.get(i);
- if (serialN.equals(entry.getSerialNumber())) {
- return entry;
- }
- }
- }
- return null;
- }
-
- /**
- * Method searches for CRL entry with specified serial number.
- * The method will search only certificate issued by CRL's issuer.
- * @see java.security.cert.X509CRL#getRevokedCertificate(BigInteger)
- * method documentation for more info
- */
- public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) {
- if (!entriesRetrieved) {
- retrieveEntries();
- }
- if (entries == null) {
- return null;
- }
- for (int i=0; i<nonIndirectEntriesSize; i++) {
- X509CRLEntry entry = (X509CRLEntry) entries.get(i);
- if (serialNumber.equals(entry.getSerialNumber())) {
- return entry;
- }
- }
- return null;
- }
-
- /**
- * @see java.security.cert.X509CRL#getRevokedCertificates()
- * method documentation for more info
- */
- public Set<? extends X509CRLEntry> getRevokedCertificates() {
- if (!entriesRetrieved) {
- retrieveEntries();
- }
- if (entries == null) {
- return null;
- }
- return new HashSet(entries);
- }
-
- /**
- * @see java.security.cert.X509CRL#getTBSCertList()
- * method documentation for more info
- */
- public byte[] getTBSCertList() throws CRLException {
- if (tbsCertListEncoding == null) {
- tbsCertListEncoding = tbsCertList.getEncoded();
- }
- byte[] result = new byte[tbsCertListEncoding.length];
- System.arraycopy(tbsCertListEncoding, 0,
- result, 0, tbsCertListEncoding.length);
- return result;
- }
-
- /**
- * @see java.security.cert.X509CRL#getSignature()
- * method documentation for more info
- */
- public byte[] getSignature() {
- if (signature == null) {
- signature = crl.getSignatureValue();
- }
- byte[] result = new byte[signature.length];
- System.arraycopy(signature, 0, result, 0, signature.length);
- return result;
- }
-
- /**
- * @see java.security.cert.X509CRL#getSigAlgName()
- * method documentation for more info
- */
- public String getSigAlgName() {
- if (sigAlgOID == null) {
- sigAlgOID = tbsCertList.getSignature().getAlgorithm();
- sigAlgName = AlgNameMapper.map2AlgName(sigAlgOID);
- if (sigAlgName == null) {
- sigAlgName = sigAlgOID;
- }
- }
- return sigAlgName;
- }
-
- /**
- * @see java.security.cert.X509CRL#getSigAlgOID()
- * method documentation for more info
- */
- public String getSigAlgOID() {
- if (sigAlgOID == null) {
- sigAlgOID = tbsCertList.getSignature().getAlgorithm();
- sigAlgName = AlgNameMapper.map2AlgName(sigAlgOID);
- if (sigAlgName == null) {
- sigAlgName = sigAlgOID;
- }
- }
- return sigAlgOID;
- }
-
- /**
- * @see java.security.cert.X509CRL#getSigAlgParams()
- * method documentation for more info
- */
- public byte[] getSigAlgParams() {
- if (nullSigAlgParams) {
- return null;
- }
- if (sigAlgParams == null) {
- sigAlgParams = tbsCertList.getSignature().getParameters();
- if (sigAlgParams == null) {
- nullSigAlgParams = true;
- return null;
- }
- }
- return sigAlgParams;
- }
-
- /**
- * @see java.security.cert.X509CRL#verify(PublicKey key)
- * method documentation for more info
- */
- public void verify(PublicKey key)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException,
- SignatureException {
- Signature signature = Signature.getInstance(getSigAlgName());
- signature.initVerify(key);
- byte[] tbsEncoding = tbsCertList.getEncoded();
- signature.update(tbsEncoding, 0, tbsEncoding.length);
- if (!signature.verify(crl.getSignatureValue())) {
- throw new SignatureException("Signature was not verified");
- }
- }
-
- /**
- * @see java.security.cert.X509CRL#verify(PublicKey key, String sigProvider)
- * method documentation for more info
- */
- public void verify(PublicKey key, String sigProvider)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException,
- SignatureException {
- Signature signature = Signature.getInstance(
- getSigAlgName(), sigProvider);
- signature.initVerify(key);
- byte[] tbsEncoding = tbsCertList.getEncoded();
- signature.update(tbsEncoding, 0, tbsEncoding.length);
- if (!signature.verify(crl.getSignatureValue())) {
- throw new SignatureException("Signature was not verified");
- }
- }
-
- // ---------------------------------------------------------------------
- // ------ java.security.cert.CRL abstract method implementations -------
- // ---------------------------------------------------------------------
-
- /**
- * @see java.security.cert.CRL#isRevoked(Certificate)
- * method documentation for more info
- */
- public boolean isRevoked(Certificate cert) {
- if (!(cert instanceof X509Certificate)) {
- return false;
- }
- return getRevokedCertificate((X509Certificate) cert) != null;
- }
-
- /**
- * @see java.security.cert.CRL#toString()
- * method documentation for more info
- */
- public String toString() {
- return crl.toString();
- }
-
- // ---------------------------------------------------------------------
- // ------ java.security.cert.X509Extension method implementations ------
- // ---------------------------------------------------------------------
-
- /**
- * @see java.security.cert.X509Extension#getNonCriticalExtensionOIDs()
- * method documentation for more info
- */
- public Set getNonCriticalExtensionOIDs() {
- if (extensions == null) {
- return null;
- }
- return extensions.getNonCriticalExtensions();
- }
-
- /**
- * @see java.security.cert.X509Extension#getCriticalExtensionOIDs()
- * method documentation for more info
- */
- public Set getCriticalExtensionOIDs() {
- if (extensions == null) {
- return null;
- }
- return extensions.getCriticalExtensions();
- }
-
- /**
- * @see java.security.cert.X509Extension#getExtensionValue(String)
- * method documentation for more info
- */
- public byte[] getExtensionValue(String oid) {
- if (extensions == null) {
- return null;
- }
- Extension ext = extensions.getExtensionByOID(oid);
- return (ext == null) ? null : ext.getRawExtnValue();
- }
-
- /**
- * @see java.security.cert.X509Extension#hasUnsupportedCriticalExtension()
- * method documentation for more info
- */
- public boolean hasUnsupportedCriticalExtension() {
- if (extensions == null) {
- return false;
- }
- return extensions.hasUnsupportedCritical();
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertFactoryImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertFactoryImpl.java
deleted file mode 100644
index 9129ec2..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertFactoryImpl.java
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @author Alexander Y. Kleymenov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.provider.cert;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.security.cert.CRL;
-import java.security.cert.CRLException;
-import java.security.cert.CertPath;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactorySpi;
-import java.security.cert.X509CRL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import libcore.io.Base64;
-import libcore.io.Streams;
-import org.apache.harmony.security.asn1.ASN1Constants;
-import org.apache.harmony.security.asn1.BerInputStream;
-import org.apache.harmony.security.pkcs7.ContentInfo;
-import org.apache.harmony.security.pkcs7.SignedData;
-import org.apache.harmony.security.x509.CertificateList;
-
-/**
- * X509 Certificate Factory Service Provider Interface Implementation.
- * It supports CRLs and Certificates in (PEM) ASN.1 DER encoded form,
- * and Certification Paths in PkiPath and PKCS7 formats.
- * For Certificates and CRLs factory maintains the caching
- * mechanisms allowing to speed up repeated Certificate/CRL
- * generation.
- * @see Cache
- */
-public class X509CertFactoryImpl extends CertificateFactorySpi {
-
- // number of leading/trailing bytes used for cert hash computation
- private static final int CERT_CACHE_SEED_LENGTH = 28;
- // certificate cache
- private static final Cache CERT_CACHE = new Cache(CERT_CACHE_SEED_LENGTH);
- // number of leading/trailing bytes used for crl hash computation
- private static final int CRL_CACHE_SEED_LENGTH = 24;
- // crl cache
- private static final Cache CRL_CACHE = new Cache(CRL_CACHE_SEED_LENGTH);
-
- /**
- * Default constructor.
- * Creates the instance of Certificate Factory SPI ready for use.
- */
- public X509CertFactoryImpl() { }
-
- /**
- * Generates the X.509 certificate from the data in the stream.
- * The data in the stream can be either in ASN.1 DER encoded X.509
- * certificate, or PEM (Base64 encoding bounded by
- * <code>"-----BEGIN CERTIFICATE-----"</code> at the beginning and
- * <code>"-----END CERTIFICATE-----"</code> at the end) representation
- * of the former encoded form.
- *
- * Before the generation the encoded form is looked up in
- * the cache. If the cache contains the certificate with requested encoded
- * form it is returned from it, otherwise it is generated by ASN.1
- * decoder.
- *
- * @see java.security.cert.CertificateFactorySpi#engineGenerateCertificate(InputStream)
- * method documentation for more info
- */
- public Certificate engineGenerateCertificate(InputStream inStream)
- throws CertificateException {
- if (inStream == null) {
- throw new CertificateException("inStream == null");
- }
- try {
- if (!inStream.markSupported()) {
- // create the mark supporting wrapper
- inStream = new RestoringInputStream(inStream);
- }
- // mark is needed to recognize the format of the provided encoding
- // (ASN.1 or PEM)
- inStream.mark(1);
- // check whether the provided certificate is in PEM encoded form
- if (inStream.read() == '-') {
- // decode PEM, retrieve CRL
- return getCertificate(decodePEM(inStream, CERT_BOUND_SUFFIX));
- } else {
- inStream.reset();
- // retrieve CRL
- return getCertificate(inStream);
- }
- } catch (IOException e) {
- throw new CertificateException(e);
- }
- }
-
- /**
- * Generates the collection of the certificates on the base of provided
- * via input stream encodings.
- * @see java.security.cert.CertificateFactorySpi#engineGenerateCertificates(InputStream)
- * method documentation for more info
- */
- public Collection<? extends Certificate>
- engineGenerateCertificates(InputStream inStream)
- throws CertificateException {
- if (inStream == null) {
- throw new CertificateException("inStream == null");
- }
- ArrayList<Certificate> result = new ArrayList<Certificate>();
- try {
- if (!inStream.markSupported()) {
- // create the mark supporting wrapper
- inStream = new RestoringInputStream(inStream);
- }
- // if it is PEM encoded form this array will contain the encoding
- // so ((it is PEM) <-> (encoding != null))
- byte[] encoding = null;
- // The following by SEQUENCE ASN.1 tag, used for
- // recognizing the data format
- // (is it PKCS7 ContentInfo structure, X.509 Certificate, or
- // unsupported encoding)
- int second_asn1_tag = -1;
- inStream.mark(1);
- int ch;
- while ((ch = inStream.read()) != -1) {
- // check if it is PEM encoded form
- if (ch == '-') { // beginning of PEM encoding ('-' char)
- // decode PEM chunk and store its content (ASN.1 encoding)
- encoding = decodePEM(inStream, FREE_BOUND_SUFFIX);
- } else if (ch == 0x30) { // beginning of ASN.1 sequence (0x30)
- encoding = null;
- inStream.reset();
- // prepare for data format determination
- inStream.mark(CERT_CACHE_SEED_LENGTH);
- } else { // unsupported data
- if (result.size() == 0) {
- throw new CertificateException("Unsupported encoding");
- } else {
- // it can be trailing user data,
- // so keep it in the stream
- inStream.reset();
- return result;
- }
- }
- // Check the data format
- BerInputStream in = (encoding == null)
- ? new BerInputStream(inStream)
- : new BerInputStream(encoding);
- // read the next ASN.1 tag
- second_asn1_tag = in.next(); // inStream position changed
- if (encoding == null) {
- // keep whole structure in the stream
- inStream.reset();
- }
- // check if it is a TBSCertificate structure
- if (second_asn1_tag != ASN1Constants.TAG_C_SEQUENCE) {
- if (result.size() == 0) {
- // there were not read X.509 Certificates, so
- // break the cycle and check
- // whether it is PKCS7 structure
- break;
- } else {
- // it can be trailing user data,
- // so return what we already read
- return result;
- }
- } else {
- if (encoding == null) {
- result.add(getCertificate(inStream));
- } else {
- result.add(getCertificate(encoding));
- }
- }
- // mark for the next iteration
- inStream.mark(1);
- }
- if (result.size() != 0) {
- // some Certificates have been read
- return result;
- } else if (ch == -1) {
- /* No data in the stream, so return the empty collection. */
- return result;
- }
- // else: check if it is PKCS7
- if (second_asn1_tag == ASN1Constants.TAG_OID) {
- // it is PKCS7 ContentInfo structure, so decode it
- ContentInfo info = (ContentInfo)
- ((encoding != null)
- ? ContentInfo.ASN1.decode(encoding)
- : ContentInfo.ASN1.decode(inStream));
- // retrieve SignedData
- SignedData data = info.getSignedData();
- if (data == null) {
- throw new CertificateException("Invalid PKCS7 data provided");
- }
- List<org.apache.harmony.security.x509.Certificate> certs = data.getCertificates();
- if (certs != null) {
- for (org.apache.harmony.security.x509.Certificate cert : certs) {
- result.add(new X509CertImpl(cert));
- }
- }
- return result;
- }
- // else: Unknown data format
- throw new CertificateException("Unsupported encoding");
- } catch (IOException e) {
- throw new CertificateException(e);
- }
- }
-
- /**
- * @see java.security.cert.CertificateFactorySpi#engineGenerateCRL(InputStream)
- * method documentation for more info
- */
- public CRL engineGenerateCRL(InputStream inStream)
- throws CRLException {
- if (inStream == null) {
- throw new CRLException("inStream == null");
- }
- try {
- if (!inStream.markSupported()) {
- // Create the mark supporting wrapper
- // Mark is needed to recognize the format
- // of provided encoding form (ASN.1 or PEM)
- inStream = new RestoringInputStream(inStream);
- }
- inStream.mark(1);
- // check whether the provided crl is in PEM encoded form
- if (inStream.read() == '-') {
- // decode PEM, retrieve CRL
- return getCRL(decodePEM(inStream, FREE_BOUND_SUFFIX));
- } else {
- inStream.reset();
- // retrieve CRL
- return getCRL(inStream);
- }
- } catch (IOException e) {
- throw new CRLException(e);
- }
- }
-
- /**
- * @see java.security.cert.CertificateFactorySpi#engineGenerateCRLs(InputStream)
- * method documentation for more info
- */
- public Collection<? extends CRL> engineGenerateCRLs(InputStream inStream)
- throws CRLException {
- if (inStream == null) {
- throw new CRLException("inStream == null");
- }
- ArrayList<CRL> result = new ArrayList<CRL>();
- try {
- if (!inStream.markSupported()) {
- inStream = new RestoringInputStream(inStream);
- }
- // if it is PEM encoded form this array will contain the encoding
- // so ((it is PEM) <-> (encoding != null))
- byte[] encoding = null;
- // The following by SEQUENCE ASN.1 tag, used for
- // recognizing the data format
- // (is it PKCS7 ContentInfo structure, X.509 CRL, or
- // unsupported encoding)
- int second_asn1_tag = -1;
- inStream.mark(1);
- int ch;
- while ((ch = inStream.read()) != -1) {
- // check if it is PEM encoded form
- if (ch == '-') { // beginning of PEM encoding ('-' char)
- // decode PEM chunk and store its content (ASN.1 encoding)
- encoding = decodePEM(inStream, FREE_BOUND_SUFFIX);
- } else if (ch == 0x30) { // beginning of ASN.1 sequence (0x30)
- encoding = null;
- inStream.reset();
- // prepare for data format determination
- inStream.mark(CRL_CACHE_SEED_LENGTH);
- } else { // unsupported data
- if (result.size() == 0) {
- throw new CRLException("Unsupported encoding");
- } else {
- // it can be trailing user data,
- // so keep it in the stream
- inStream.reset();
- return result;
- }
- }
- // Check the data format
- BerInputStream in = (encoding == null)
- ? new BerInputStream(inStream)
- : new BerInputStream(encoding);
- // read the next ASN.1 tag
- second_asn1_tag = in.next();
- if (encoding == null) {
- // keep whole structure in the stream
- inStream.reset();
- }
- // check if it is a TBSCertList structure
- if (second_asn1_tag != ASN1Constants.TAG_C_SEQUENCE) {
- if (result.size() == 0) {
- // there were not read X.509 CRLs, so
- // break the cycle and check
- // whether it is PKCS7 structure
- break;
- } else {
- // it can be trailing user data,
- // so return what we already read
- return result;
- }
- } else {
- if (encoding == null) {
- result.add(getCRL(inStream));
- } else {
- result.add(getCRL(encoding));
- }
- }
- inStream.mark(1);
- }
- if (result.size() != 0) {
- // the stream was read out
- return result;
- } else if (ch == -1) {
- throw new CRLException("There is no data in the stream");
- }
- // else: check if it is PKCS7
- if (second_asn1_tag == ASN1Constants.TAG_OID) {
- // it is PKCS7 ContentInfo structure, so decode it
- ContentInfo info = (ContentInfo)
- ((encoding != null)
- ? ContentInfo.ASN1.decode(encoding)
- : ContentInfo.ASN1.decode(inStream));
- // retrieve SignedData
- SignedData data = info.getSignedData();
- if (data == null) {
- throw new CRLException("Invalid PKCS7 data provided");
- }
- List<CertificateList> crls = data.getCRLs();
- if (crls != null) {
- for (CertificateList crl : crls) {
- result.add(new X509CRLImpl(crl));
- }
- }
- return result;
- }
- // else: Unknown data format
- throw new CRLException("Unsupported encoding");
- } catch (IOException e) {
- throw new CRLException(e);
- }
- }
-
- /**
- * @see java.security.cert.CertificateFactorySpi#engineGenerateCertPath(InputStream)
- * method documentation for more info
- */
- public CertPath engineGenerateCertPath(InputStream inStream)
- throws CertificateException {
- if (inStream == null) {
- throw new CertificateException("inStream == null");
- }
- return engineGenerateCertPath(inStream, "PkiPath");
- }
-
- /**
- * @see java.security.cert.CertificateFactorySpi#engineGenerateCertPath(InputStream,String)
- * method documentation for more info
- */
- public CertPath engineGenerateCertPath(
- InputStream inStream, String encoding) throws CertificateException {
- if (inStream == null) {
- throw new CertificateException("inStream == null");
- }
- if (!inStream.markSupported()) {
- inStream = new RestoringInputStream(inStream);
- }
- try {
- inStream.mark(1);
- int ch;
-
- // check if it is PEM encoded form
- if ((ch = inStream.read()) == '-') {
- // decode PEM chunk into ASN.1 form and decode CertPath object
- return X509CertPathImpl.getInstance(
- decodePEM(inStream, FREE_BOUND_SUFFIX), encoding);
- } else if (ch == 0x30) { // ASN.1 Sequence
- inStream.reset();
- // decode ASN.1 form
- return X509CertPathImpl.getInstance(inStream, encoding);
- } else {
- throw new CertificateException("Unsupported encoding");
- }
- } catch (IOException e) {
- throw new CertificateException(e);
- }
- }
-
- /**
- * @see java.security.cert.CertificateFactorySpi#engineGenerateCertPath(List)
- * method documentation for more info
- */
- public CertPath engineGenerateCertPath(List<? extends Certificate> certificates)
- throws CertificateException {
- return new X509CertPathImpl(certificates);
- }
-
- /**
- * @see java.security.cert.CertificateFactorySpi#engineGetCertPathEncodings()
- * method documentation for more info
- */
- public Iterator<String> engineGetCertPathEncodings() {
- return X509CertPathImpl.encodings.iterator();
- }
-
- // ---------------------------------------------------------------------
- // ------------------------ Staff methods ------------------------------
- // ---------------------------------------------------------------------
-
- private static final byte[] PEM_BEGIN = "-----BEGIN".getBytes(StandardCharsets.UTF_8);
- private static final byte[] PEM_END = "-----END".getBytes(StandardCharsets.UTF_8);
- /**
- * Code describing free format for PEM boundary suffix:
- * "^-----BEGIN.*\n" at the beginning, and<br>
- * "\n-----END.*(EOF|\n)$" at the end.
- */
- private static final byte[] FREE_BOUND_SUFFIX = null;
- /**
- * Code describing PEM boundary suffix for X.509 certificate:
- * "^-----BEGIN CERTIFICATE-----\n" at the beginning, and<br>
- * "\n-----END CERTIFICATE-----" at the end.
- */
- private static final byte[] CERT_BOUND_SUFFIX = " CERTIFICATE-----".getBytes(StandardCharsets.UTF_8);
-
- /**
- * Method retrieves the PEM encoded data from the stream
- * and returns its decoded representation.
- * Method checks correctness of PEM boundaries. It supposes that
- * the first '-' of the opening boundary has already been read from
- * the stream. So first of all it checks that the leading bytes
- * are equal to "-----BEGIN" boundary prefix. Than if boundary_suffix
- * is not null, it checks that next bytes equal to boundary_suffix
- * + new line char[s] ([CR]LF).
- * If boundary_suffix parameter is null, method supposes free suffix
- * format and skips any bytes until the new line.<br>
- * After the opening boundary has been read and checked, the method
- * read Base64 encoded data until closing PEM boundary is not reached.<br>
- * Than it checks closing boundary - it should start with new line +
- * "-----END" + boundary_suffix. If boundary_suffix is null,
- * any characters are skipped until the new line.<br>
- * After this any trailing new line characters are skipped from the stream,
- * Base64 encoding is decoded and returned.
- * @param inStream the stream containing the PEM encoding.
- * @param boundary_suffix the suffix of expected PEM multipart
- * boundary delimiter.<br>
- * If it is null, that any character sequences are accepted.
- * @throws IOException If PEM boundary delimiter does not comply
- * with expected or some I/O or decoding problems occur.
- */
- private byte[] decodePEM(InputStream inStream, byte[] boundary_suffix)
- throws IOException {
- int ch; // the char to be read
- // check and skip opening boundary delimiter
- // (first '-' is supposed as already read)
- for (int i = 1; i < PEM_BEGIN.length; ++i) {
- if (PEM_BEGIN[i] != (ch = inStream.read())) {
- throw new IOException(
- "Incorrect PEM encoding: '-----BEGIN"
- + ((boundary_suffix == null)
- ? "" : new String(boundary_suffix))
- + "' is expected as opening delimiter boundary.");
- }
- }
- if (boundary_suffix == null) {
- // read (skip) the trailing characters of
- // the beginning PEM boundary delimiter
- while ((ch = inStream.read()) != '\n') {
- if (ch == -1) {
- throw new IOException("Incorrect PEM encoding: EOF before content");
- }
- }
- } else {
- for (int i=0; i<boundary_suffix.length; i++) {
- if (boundary_suffix[i] != inStream.read()) {
- throw new IOException("Incorrect PEM encoding: '-----BEGIN" +
- new String(boundary_suffix) + "' is expected as opening delimiter boundary.");
- }
- }
- // read new line characters
- if ((ch = inStream.read()) == '\r') {
- // CR has been read, now read LF character
- ch = inStream.read();
- }
- if (ch != '\n') {
- throw new IOException("Incorrect PEM encoding: newline expected after " +
- "opening delimiter boundary");
- }
- }
- int size = 1024; // the size of the buffer containing Base64 data
- byte[] buff = new byte[size];
- int index = 0;
- // read bytes while ending boundary delimiter is not reached
- while ((ch = inStream.read()) != '-') {
- if (ch == -1) {
- throw new IOException("Incorrect Base64 encoding: EOF without closing delimiter");
- }
- buff[index++] = (byte) ch;
- if (index == size) {
- // enlarge the buffer
- byte[] newbuff = new byte[size+1024];
- System.arraycopy(buff, 0, newbuff, 0, size);
- buff = newbuff;
- size += 1024;
- }
- }
- if (buff[index-1] != '\n') {
- throw new IOException("Incorrect Base64 encoding: newline expected before " +
- "closing boundary delimiter");
- }
- // check and skip closing boundary delimiter prefix
- // (first '-' was read)
- for (int i = 1; i < PEM_END.length; ++i) {
- if (PEM_END[i] != inStream.read()) {
- throw badEnd(boundary_suffix);
- }
- }
- if (boundary_suffix == null) {
- // read (skip) the trailing characters of
- // the closing PEM boundary delimiter
- while (((ch = inStream.read()) != -1) && (ch != '\n') && (ch != '\r')) {
- }
- } else {
- for (int i=0; i<boundary_suffix.length; i++) {
- if (boundary_suffix[i] != inStream.read()) {
- throw badEnd(boundary_suffix);
- }
- }
- }
- // skip trailing line breaks
- inStream.mark(1);
- while (((ch = inStream.read()) != -1) && (ch == '\n' || ch == '\r')) {
- inStream.mark(1);
- }
- inStream.reset();
- buff = Base64.decode(buff, index);
- if (buff == null) {
- throw new IOException("Incorrect Base64 encoding");
- }
- return buff;
- }
-
- private IOException badEnd(byte[] boundary_suffix) throws IOException {
- String s = (boundary_suffix == null) ? "" : new String(boundary_suffix);
- throw new IOException("Incorrect PEM encoding: '-----END" + s + "' is expected as closing delimiter boundary.");
- }
-
- /**
- * Reads the data of specified length from source
- * and returns it as an array.
- * @return the byte array contained read data or
- * null if the stream contains not enough data
- * @throws IOException if some I/O error has been occurred.
- */
- private static byte[] readBytes(InputStream source, int length)
- throws IOException {
- byte[] result = new byte[length];
- for (int i=0; i<length; i++) {
- int bytik = source.read();
- if (bytik == -1) {
- return null;
- }
- result[i] = (byte) bytik;
- }
- return result;
- }
-
- /**
- * Returns the Certificate object corresponding to the provided encoding.
- * Resulting object is retrieved from the cache
- * if it contains such correspondence
- * and is constructed on the base of encoding
- * and stored in the cache otherwise.
- * @throws IOException if some decoding errors occur
- * (in the case of cache miss).
- */
- private static Certificate getCertificate(byte[] encoding)
- throws CertificateException, IOException {
- if (encoding.length < CERT_CACHE_SEED_LENGTH) {
- throw new CertificateException("encoding.length < CERT_CACHE_SEED_LENGTH");
- }
- synchronized (CERT_CACHE) {
- long hash = CERT_CACHE.getHash(encoding);
- if (CERT_CACHE.contains(hash)) {
- Certificate res =
- (Certificate) CERT_CACHE.get(hash, encoding);
- if (res != null) {
- return res;
- }
- }
- Certificate res = new X509CertImpl(encoding);
- CERT_CACHE.put(hash, encoding, res);
- return res;
- }
- }
-
- /**
- * Returns the Certificate object corresponding to the encoding provided
- * by the stream.
- * Resulting object is retrieved from the cache
- * if it contains such correspondence
- * and is constructed on the base of encoding
- * and stored in the cache otherwise.
- * @throws IOException if some decoding errors occur
- * (in the case of cache miss).
- */
- private static Certificate getCertificate(InputStream inStream)
- throws CertificateException, IOException {
- synchronized (CERT_CACHE) {
- inStream.mark(CERT_CACHE_SEED_LENGTH);
- // read the prefix of the encoding
- byte[] buff = readBytes(inStream, CERT_CACHE_SEED_LENGTH);
- inStream.reset();
- if (buff == null) {
- throw new CertificateException("InputStream doesn't contain enough data");
- }
- long hash = CERT_CACHE.getHash(buff);
- if (CERT_CACHE.contains(hash)) {
- byte[] encoding = new byte[BerInputStream.getLength(buff)];
- if (encoding.length < CERT_CACHE_SEED_LENGTH) {
- throw new CertificateException("Bad Certificate encoding");
- }
- Streams.readFully(inStream, encoding);
- Certificate res = (Certificate) CERT_CACHE.get(hash, encoding);
- if (res != null) {
- return res;
- }
- res = new X509CertImpl(encoding);
- CERT_CACHE.put(hash, encoding, res);
- return res;
- } else {
- inStream.reset();
- Certificate res = new X509CertImpl(inStream);
- CERT_CACHE.put(hash, res.getEncoded(), res);
- return res;
- }
- }
- }
-
- /**
- * Returns the CRL object corresponding to the provided encoding.
- * Resulting object is retrieved from the cache
- * if it contains such correspondence
- * and is constructed on the base of encoding
- * and stored in the cache otherwise.
- * @throws IOException if some decoding errors occur
- * (in the case of cache miss).
- */
- private static CRL getCRL(byte[] encoding)
- throws CRLException, IOException {
- if (encoding.length < CRL_CACHE_SEED_LENGTH) {
- throw new CRLException("encoding.length < CRL_CACHE_SEED_LENGTH");
- }
- synchronized (CRL_CACHE) {
- long hash = CRL_CACHE.getHash(encoding);
- if (CRL_CACHE.contains(hash)) {
- X509CRL res = (X509CRL) CRL_CACHE.get(hash, encoding);
- if (res != null) {
- return res;
- }
- }
- X509CRL res = new X509CRLImpl(encoding);
- CRL_CACHE.put(hash, encoding, res);
- return res;
- }
- }
-
- /**
- * Returns the CRL object corresponding to the encoding provided
- * by the stream.
- * Resulting object is retrieved from the cache
- * if it contains such correspondence
- * and is constructed on the base of encoding
- * and stored in the cache otherwise.
- * @throws IOException if some decoding errors occur
- * (in the case of cache miss).
- */
- private static CRL getCRL(InputStream inStream)
- throws CRLException, IOException {
- synchronized (CRL_CACHE) {
- inStream.mark(CRL_CACHE_SEED_LENGTH);
- byte[] buff = readBytes(inStream, CRL_CACHE_SEED_LENGTH);
- // read the prefix of the encoding
- inStream.reset();
- if (buff == null) {
- throw new CRLException("InputStream doesn't contain enough data");
- }
- long hash = CRL_CACHE.getHash(buff);
- if (CRL_CACHE.contains(hash)) {
- byte[] encoding = new byte[BerInputStream.getLength(buff)];
- if (encoding.length < CRL_CACHE_SEED_LENGTH) {
- throw new CRLException("Bad CRL encoding");
- }
- Streams.readFully(inStream, encoding);
- CRL res = (CRL) CRL_CACHE.get(hash, encoding);
- if (res != null) {
- return res;
- }
- res = new X509CRLImpl(encoding);
- CRL_CACHE.put(hash, encoding, res);
- return res;
- } else {
- X509CRL res = new X509CRLImpl(inStream);
- CRL_CACHE.put(hash, res.getEncoded(), res);
- return res;
- }
- }
- }
-
- /*
- * This class extends any existing input stream with
- * mark functionality. It acts as a wrapper over the
- * stream and supports reset to the
- * marked state with readlimit no more than BUFF_SIZE.
- */
- private static class RestoringInputStream extends InputStream {
-
- // wrapped input stream
- private final InputStream inStream;
- // specifies how much of the read data is buffered
- // after the mark has been set up
- private static final int BUFF_SIZE = 32;
- // buffer to keep the bytes read after the mark has been set up
- private final int[] buff = new int[BUFF_SIZE*2];
- // position of the next byte to read,
- // the value of -1 indicates that the buffer is not used
- // (mark was not set up or was invalidated, or reset to the marked
- // position has been done and all the buffered data was read out)
- private int pos = -1;
- // position of the last buffered byte
- private int bar = 0;
- // position in the buffer where the mark becomes invalidated
- private int end = 0;
-
- /**
- * Creates the mark supporting wrapper over the stream.
- */
- public RestoringInputStream(InputStream inStream) {
- this.inStream = inStream;
- }
-
- @Override
- public int available() throws IOException {
- return (bar - pos) + inStream.available();
- }
-
- @Override
- public void close() throws IOException {
- inStream.close();
- }
-
- @Override
- public void mark(int readlimit) {
- if (pos < 0) {
- pos = 0;
- bar = 0;
- end = BUFF_SIZE - 1;
- } else {
- end = (pos + BUFF_SIZE - 1) % BUFF_SIZE;
- }
- }
-
- @Override
- public boolean markSupported() {
- return true;
- }
-
- /**
- * Reads the byte from the stream. If mark has been set up
- * and was not invalidated byte is read from the underlying
- * stream and saved into the buffer. If the current read position
- * has been reset to the marked position and there are remaining
- * bytes in the buffer, the byte is taken from it. In the other cases
- * (if mark has been invalidated, or there are no buffered bytes)
- * the byte is taken directly from the underlying stream and it is
- * returned without saving to the buffer.
- *
- * @see java.io.InputStream#read()
- * method documentation for more info
- */
- public int read() throws IOException {
- // if buffer is currently used
- if (pos >= 0) {
- // current position in the buffer
- int cur = pos % BUFF_SIZE;
- // check whether the buffer contains the data to be read
- if (cur < bar) {
- // return the data from the buffer
- pos++;
- return buff[cur];
- }
- // check whether buffer has free space
- if (cur != end) {
- // it has, so read the data from the wrapped stream
- // and place it in the buffer
- buff[cur] = inStream.read();
- bar = cur+1;
- pos++;
- return buff[cur];
- } else {
- // buffer if full and can not operate
- // any more, so invalidate the mark position
- // and turn off the using of buffer
- pos = -1;
- }
- }
- // buffer is not used, so return the data from the wrapped stream
- return inStream.read();
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- int read_b;
- int i;
- for (i=0; i<len; i++) {
- if ((read_b = read()) == -1) {
- return (i == 0) ? -1 : i;
- }
- b[off+i] = (byte) read_b;
- }
- return i;
- }
-
- @Override
- public void reset() throws IOException {
- if (pos >= 0) {
- pos = (end + 1) % BUFF_SIZE;
- } else {
- throw new IOException("Could not reset the stream: " +
- "position became invalid or stream has not been marked");
- }
- }
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertImpl.java
deleted file mode 100644
index 4600bdc..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertImpl.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @author Alexander Y. Kleymenov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.provider.cert;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.apache.harmony.security.x509.Certificate;
-import org.apache.harmony.security.x509.Extension;
-import org.apache.harmony.security.x509.Extensions;
-import org.apache.harmony.security.x509.TBSCertificate;
-
-/**
- * This class is an implementation of X509Certificate. It wraps
- * the instance of org.apache.harmony.security.x509.Certificate
- * built on the base of provided ASN.1 DER encoded form of
- * Certificate structure (as specified in RFC 3280
- * http://www.ietf.org/rfc/rfc3280.txt).
- * @see org.apache.harmony.security.x509.Certificate
- * @see java.security.cert.X509Certificate
- */
-public final class X509CertImpl extends X509Certificate {
-
- /** @serial */
- private static final long serialVersionUID = 2972248729446736154L;
-
- /** the core object to be wrapped in X509Certificate */
- private final Certificate certificate;
-
- private final TBSCertificate tbsCert;
- private final Extensions extensions;
- // to speed up access to the info, the following fields
- // cache values retrieved from the certificate object,
- // initialized using the "single-check idiom".
- private volatile long notBefore = -1;
- private volatile long notAfter = -1;
- private volatile BigInteger serialNumber;
- private volatile X500Principal issuer;
- private volatile X500Principal subject;
- private volatile byte[] tbsCertificate;
- private volatile byte[] signature;
- private volatile String sigAlgName;
- private volatile String sigAlgOID;
- private volatile byte[] sigAlgParams;
- // indicates whether the signature algorithm parameters are null
- private volatile boolean nullSigAlgParams;
- private volatile PublicKey publicKey;
-
- // encoding of the certificate
- private volatile byte[] encoding;
-
- /**
- * Constructs the instance on the base of ASN.1 encoded
- * form of X.509 certificate provided via stream parameter.
- * @param in input stream containing ASN.1 encoded form of certificate.
- * @throws CertificateException if some decoding problems occur.
- */
- public X509CertImpl(InputStream in) throws CertificateException {
- try {
- // decode the Certificate object
- this.certificate = (Certificate) Certificate.ASN1.decode(in);
- // cache the values of TBSCertificate and Extensions
- this.tbsCert = certificate.getTbsCertificate();
- this.extensions = tbsCert.getExtensions();
- } catch (IOException e) {
- throw new CertificateException(e);
- }
- }
-
- /**
- * Constructs the instance on the base of existing Certificate object to
- * be wrapped.
- */
- public X509CertImpl(Certificate certificate) {
- this.certificate = certificate;
- // cache the values of TBSCertificate and Extensions
- this.tbsCert = certificate.getTbsCertificate();
- this.extensions = tbsCert.getExtensions();
- }
-
- /**
- * Constructs the instance on the base of ASN.1 encoded
- * form of X.509 certificate provided via array of bytes.
- * @param encoding byte array containing ASN.1 encoded form of certificate.
- * @throws IOException if some decoding problems occur.
- */
- public X509CertImpl(byte[] encoding) throws IOException {
- this((Certificate) Certificate.ASN1.decode(encoding));
- }
-
- public void checkValidity()
- throws CertificateExpiredException, CertificateNotYetValidException {
- checkValidity(System.currentTimeMillis());
- }
-
- public void checkValidity(Date date)
- throws CertificateExpiredException, CertificateNotYetValidException {
- checkValidity(date.getTime());
- }
-
- private void checkValidity(long time)
- throws CertificateExpiredException, CertificateNotYetValidException {
- if (time < getNotBeforeInternal()) {
- throw new CertificateNotYetValidException("current time: " + new Date(time)
- + ", validation time: " + new Date(getNotBeforeInternal()));
- }
- if (time > getNotAfterInternal()) {
- throw new CertificateExpiredException("current time: " + new Date(time)
- + ", expiration time: " + new Date(getNotAfterInternal()));
- }
- }
-
- public int getVersion() {
- return tbsCert.getVersion() + 1;
- }
-
- public BigInteger getSerialNumber() {
- BigInteger result = serialNumber;
- if (result == null) {
- serialNumber = result = tbsCert.getSerialNumber();
- }
- return result;
- }
-
- public Principal getIssuerDN() {
- return getIssuerX500Principal();
- }
-
- public X500Principal getIssuerX500Principal() {
- X500Principal result = issuer;
- if (result == null) {
- // retrieve the issuer's principal
- issuer = result = tbsCert.getIssuer().getX500Principal();
- }
- return result;
- }
-
- public Principal getSubjectDN() {
- return getSubjectX500Principal();
- }
-
- public X500Principal getSubjectX500Principal() {
- X500Principal result = subject;
- if (result == null) {
- // retrieve the subject's principal
- subject = result = tbsCert.getSubject().getX500Principal();
- }
- return result;
- }
-
- public Date getNotBefore() {
- return new Date(getNotBeforeInternal());
- }
-
- private long getNotBeforeInternal() {
- long result = notBefore;
- if (result == -1) {
- notBefore = result = tbsCert.getValidity().getNotBefore().getTime();
- }
- return result;
- }
-
- public Date getNotAfter() {
- return new Date(getNotAfterInternal());
- }
-
- private long getNotAfterInternal() {
- long result = notAfter;
- if (result == -1) {
- notAfter = result = tbsCert.getValidity().getNotAfter().getTime();
- }
- return result;
- }
-
- public byte[] getTBSCertificate() throws CertificateEncodingException {
- return getTbsCertificateInternal().clone();
- }
-
- private byte[] getTbsCertificateInternal() {
- byte[] result = tbsCertificate;
- if (result == null) {
- tbsCertificate = result = tbsCert.getEncoded();
- }
- return result;
- }
-
- public byte[] getSignature() {
- return getSignatureInternal().clone();
- }
-
- private byte[] getSignatureInternal() {
- byte[] result = signature;
- if (result == null) {
- signature = result = certificate.getSignatureValue();
- }
- return result;
- }
-
- public String getSigAlgName() {
- String result = sigAlgName;
- if (result == null) {
- String sigAlgOIDLocal = getSigAlgOID();
- // retrieve the name of the signing algorithm
- result = AlgNameMapper.map2AlgName(sigAlgOIDLocal);
- if (result == null) {
- // if could not be found, use OID as a name
- result = sigAlgOIDLocal;
- }
- sigAlgName = result;
- }
- return result;
- }
-
- public String getSigAlgOID() {
- String result = sigAlgOID;
- if (result == null) {
- // if info was not retrieved (and cached), do it:
- sigAlgOID = result = tbsCert.getSignature().getAlgorithm();
- }
- return result;
- }
-
- public byte[] getSigAlgParams() {
- if (nullSigAlgParams) {
- return null;
- }
- byte[] result = sigAlgParams;
- if (result == null) {
- result = tbsCert.getSignature().getParameters();
- if (result == null) {
- nullSigAlgParams = true;
- return null;
- }
- sigAlgParams = result;
- }
- return result;
- }
-
- public boolean[] getIssuerUniqueID() {
- return tbsCert.getIssuerUniqueID();
- }
-
- public boolean[] getSubjectUniqueID() {
- return tbsCert.getSubjectUniqueID();
- }
-
- public boolean[] getKeyUsage() {
- if (extensions == null) {
- return null;
- }
- return extensions.valueOfKeyUsage();
- }
-
- public List<String> getExtendedKeyUsage()
- throws CertificateParsingException {
- if (extensions == null) {
- return null;
- }
- try {
- return extensions.valueOfExtendedKeyUsage();
- } catch (IOException e) {
- throw new CertificateParsingException(e);
- }
- }
-
- public int getBasicConstraints() {
- if (extensions == null) {
- return -1;
- }
- return extensions.valueOfBasicConstraints();
- }
-
- public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
- if (extensions == null) {
- return null;
- }
- try {
- // Retrieve the extension value from the cached extensions object
- // This extension is not checked for correctness during
- // certificate generation, so now it can throw exception
- return extensions.valueOfSubjectAlternativeName();
- } catch (IOException e) {
- throw new CertificateParsingException(e);
- }
- }
-
- /**
- * @see java.security.cert.X509Certificate#getIssuerAlternativeNames()
- * method documentation for more information.
- */
- public Collection<List<?>> getIssuerAlternativeNames() throws CertificateParsingException {
- if (extensions == null) {
- return null;
- }
- try {
- // Retrieve the extension value from the cached extensions object
- // This extension is not checked for correctness during
- // certificate generation, so now it can throw exception
- return extensions.valueOfIssuerAlternativeName();
- } catch (IOException e) {
- throw new CertificateParsingException(e);
- }
- }
-
- @Override public byte[] getEncoded() throws CertificateEncodingException {
- return getEncodedInternal().clone();
- }
- private byte[] getEncodedInternal() throws CertificateEncodingException {
- byte[] result = encoding;
- if (encoding == null) {
- encoding = result = certificate.getEncoded();
- }
- return result;
- }
-
- @Override public PublicKey getPublicKey() {
- PublicKey result = publicKey;
- if (result == null) {
- publicKey = result = tbsCert.getSubjectPublicKeyInfo().getPublicKey();
- }
- return result;
- }
-
- @Override public String toString() {
- return certificate.toString();
- }
-
- @Override public void verify(PublicKey key)
- throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
- NoSuchProviderException, SignatureException {
-
- Signature signature = Signature.getInstance(getSigAlgName());
- signature.initVerify(key);
- // retrieve the encoding of the TBSCertificate structure
- byte[] tbsCertificateLocal = getTbsCertificateInternal();
- // compute and verify the signature
- signature.update(tbsCertificateLocal, 0, tbsCertificateLocal.length);
- if (!signature.verify(certificate.getSignatureValue())) {
- throw new SignatureException("Signature was not verified");
- }
- }
-
- @Override public void verify(PublicKey key, String sigProvider)
- throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
- NoSuchProviderException, SignatureException {
-
- Signature signature = Signature.getInstance(getSigAlgName(), sigProvider);
- signature.initVerify(key);
- // retrieve the encoding of the TBSCertificate structure
- byte[] tbsCertificateLocal = getTbsCertificateInternal();
- // compute and verify the signature
- signature.update(tbsCertificateLocal, 0, tbsCertificateLocal.length);
- if (!signature.verify(certificate.getSignatureValue())) {
- throw new SignatureException("Signature was not verified");
- }
- }
-
- @Override public Set<String> getNonCriticalExtensionOIDs() {
- if (extensions == null) {
- return null;
- }
- // retrieve the info from the cached extensions object
- return extensions.getNonCriticalExtensions();
- }
-
- @Override public Set<String> getCriticalExtensionOIDs() {
- if (extensions == null) {
- return null;
- }
- // retrieve the info from the cached extensions object
- return extensions.getCriticalExtensions();
- }
-
- @Override public byte[] getExtensionValue(String oid) {
- if (extensions == null) {
- return null;
- }
- // retrieve the info from the cached extensions object
- Extension ext = extensions.getExtensionByOID(oid);
- return (ext == null) ? null : ext.getRawExtnValue();
- }
-
- @Override public boolean hasUnsupportedCriticalExtension() {
- if (extensions == null) {
- return false;
- }
- // retrieve the info from the cached extensions object
- return extensions.hasUnsupportedCritical();
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertPathImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertPathImpl.java
deleted file mode 100644
index 3699700..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/cert/X509CertPathImpl.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @author Alexander Y. Kleymenov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.provider.cert;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.cert.CertPath;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.harmony.security.asn1.ASN1Any;
-import org.apache.harmony.security.asn1.ASN1Explicit;
-import org.apache.harmony.security.asn1.ASN1Implicit;
-import org.apache.harmony.security.asn1.ASN1Oid;
-import org.apache.harmony.security.asn1.ASN1Sequence;
-import org.apache.harmony.security.asn1.ASN1SequenceOf;
-import org.apache.harmony.security.asn1.ASN1Type;
-import org.apache.harmony.security.asn1.BerInputStream;
-import org.apache.harmony.security.pkcs7.ContentInfo;
-import org.apache.harmony.security.pkcs7.SignedData;
-import org.apache.harmony.security.x509.Certificate;
-
-/**
- * This class is an implementation of X.509 CertPath. This implementation
- * provides ability to create the instance of X.509 Certification Path
- * by several means:<br>
- *
- * &nbsp; 1. It can be created over the list of X.509 certificates
- * (implementations of X509Certificate class) provided in constructor.<br>
- *
- * &nbsp; 2. It can be created by means of <code>getInstance</code> methods
- * on the base of the following ASN.1 DER encoded forms:<br>
- *
- * &nbsp;&nbsp; - PkiPath as defined in
- * ITU-T Recommendation X.509(2000) Corrigendum 1(2001)
- * (can be seen at
- * ftp://ftp.bull.com/pub/OSIdirectory/DefectResolution/TechnicalCorrigenda/ApprovedTechnicalCorrigendaToX.509/8%7CX.509-TC1(4th).pdf)
- * <br>
- * &nbsp;&nbsp; - PKCS #7 SignedData object provided in the form of
- * ContentInfo structure. CertPath object is generated on the base of
- * certificates presented in <code>certificates</code> field of the SignedData
- * object which in its turn is retrieved from ContentInfo structure.
- * (see http://www.ietf.org/rfc/rfc2315.txt
- * for more info on PKCS #7)
- * <br>
- * &nbsp;
- */
-public class X509CertPathImpl extends CertPath {
- /**
- * @serial
- */
- private static final long serialVersionUID = 7989755106209515436L;
-
- /**
- * Supported encoding types for CerthPath. Used by the various APIs that
- * encode this into bytes such as {@link #getEncoded()}.
- */
- private enum Encoding {
- PKI_PATH("PkiPath"),
- PKCS7("PKCS7");
-
- private final String apiName;
-
- Encoding(String apiName) {
- this.apiName = apiName;
- }
-
- static Encoding findByApiName(String apiName) throws CertificateEncodingException {
- for (Encoding element : values()) {
- if (element.apiName.equals(apiName)) {
- return element;
- }
- }
-
- return null;
- }
- }
-
- /** Unmodifiable list of encodings for the API. */
- static final List<String> encodings = Collections.unmodifiableList(Arrays.asList(new String[] {
- Encoding.PKI_PATH.apiName,
- Encoding.PKCS7.apiName,
- }));
-
- /** The list of certificates in the order of target toward trust anchor. */
- private final List<X509Certificate> certificates;
-
- /** PkiPath encoding of the certification path. */
- private byte[] pkiPathEncoding;
-
- /** PKCS7 encoding of the certification path. */
- private byte[] pkcs7Encoding;
-
- /**
- * Creates an instance of X.509 CertPath over the specified list of
- * certificates.
- *
- * @throws CertificateException if some of the object in the list is not an
- * instance of subclass of X509Certificate.
- */
- public X509CertPathImpl(List<? extends java.security.cert.Certificate> certs)
- throws CertificateException {
- super("X.509");
-
- final int size = certs.size();
- certificates = new ArrayList<X509Certificate>(size);
-
- for (int i = 0; i < size; i++) {
- final java.security.cert.Certificate cert = certs.get(i);
- if (!(cert instanceof X509Certificate)) {
- throw new CertificateException("Certificate " + i + " is not an X.509 certificate");
- }
-
- certificates.add((X509Certificate) cert);
- }
- }
-
- /**
- * Creates an X.509 CertPath over the specified {@code certs}. The
- * {@code certs} should be sorted correctly when calling into the
- * constructor. Additionally, the {@code encodedPath} should match the
- * expected output for the {@code type} of encoding.
- */
- private X509CertPathImpl(List<X509Certificate> certs, Encoding type) {
- super("X.509");
-
- certificates = certs;
- }
-
- /**
- * Extract a CertPath from a PKCS#7 {@code contentInfo} object.
- */
- private static X509CertPathImpl getCertPathFromContentInfo(ContentInfo contentInfo)
- throws CertificateException {
- final SignedData sd = contentInfo.getSignedData();
- if (sd == null) {
- throw new CertificateException("Incorrect PKCS7 encoded form: missing signed data");
- }
-
- List<Certificate> certs = sd.getCertificates();
- if (certs == null) {
- certs = Collections.emptyList();
- }
-
- final List<X509Certificate> result = new ArrayList<X509Certificate>(certs.size());
- for (Certificate cert : certs) {
- result.add(new X509CertImpl(cert));
- }
-
- return new X509CertPathImpl(result, Encoding.PKCS7);
- }
-
- /**
- * Generates certification path object on the base of PkiPath encoded form
- * provided via input stream.
- *
- * @throws CertificateException if some problems occurred during the
- * decoding.
- */
- public static X509CertPathImpl getInstance(InputStream in) throws CertificateException {
- try {
- return (X509CertPathImpl) ASN1.decode(in);
- } catch (IOException e) {
- throw new CertificateException("Failed to decode CertPath", e);
- }
- }
-
- /**
- * Generates certification path object on the basis of encoding provided via
- * input stream. The format of provided encoded form is specified by
- * parameter <code>encoding</code>.
- *
- * @throws CertificateException if specified encoding form is not supported,
- * or some problems occurred during the decoding.
- */
- public static X509CertPathImpl getInstance(InputStream in, String encoding)
- throws CertificateException {
- try {
- final Encoding encType = Encoding.findByApiName(encoding);
- if (encType == null) {
- throw new CertificateException("Unsupported encoding: " + encoding);
- }
-
- switch (encType) {
- case PKI_PATH:
- return (X509CertPathImpl) ASN1.decode(in);
- case PKCS7:
- return getCertPathFromContentInfo((ContentInfo) ContentInfo.ASN1.decode(in));
- default:
- throw new CertificateException("Unsupported encoding: " + encoding);
- }
- } catch (IOException e) {
- throw new CertificateException("Failed to decode CertPath", e);
- }
- }
-
- /**
- * Generates certification path object on the base of PkiPath
- * encoded form provided via array of bytes.
- * @throws CertificateException if some problems occurred during
- * the decoding.
- */
- public static X509CertPathImpl getInstance(byte[] in) throws CertificateException {
- try {
- return (X509CertPathImpl) ASN1.decode(in);
- } catch (IOException e) {
- throw new CertificateException("Failed to decode CertPath", e);
- }
- }
-
- /**
- * Generates certification path object on the base of encoding provided via
- * array of bytes. The format of provided encoded form is specified by
- * parameter {@code encoding}.
- *
- * @throws CertificateException if specified encoding form is not supported,
- * or some problems occurred during the decoding.
- */
- public static X509CertPathImpl getInstance(byte[] in, String encoding)
- throws CertificateException {
- try {
- final Encoding encType = Encoding.findByApiName(encoding);
- if (encType == null) {
- throw new CertificateException("Unsupported encoding: " + encoding);
- }
-
- switch (encType) {
- case PKI_PATH:
- return (X509CertPathImpl) ASN1.decode(in);
- case PKCS7:
- return getCertPathFromContentInfo((ContentInfo) ContentInfo.ASN1.decode(in));
- default:
- throw new CertificateException("Unsupported encoding: " + encoding);
- }
- } catch (IOException e) {
- throw new CertificateException("Failed to decode CertPath", e);
- }
- }
-
- // ---------------------------------------------------------------------
- // ---- java.security.cert.CertPath abstract method implementations ----
- // ---------------------------------------------------------------------
-
- /**
- * @see java.security.cert.CertPath#getCertificates()
- * method documentation for more info
- */
- @Override
- public List<X509Certificate> getCertificates() {
- return Collections.unmodifiableList(certificates);
- }
-
- /**
- * Returns in PkiPath format which is our default encoding.
- *
- * @see java.security.cert.CertPath#getEncoded()
- */
- @Override
- public byte[] getEncoded() throws CertificateEncodingException {
- return getEncoded(Encoding.PKI_PATH);
- }
-
- /**
- * @see #getEncoded(String)
- */
- private byte[] getEncoded(Encoding encoding) throws CertificateEncodingException {
- switch (encoding) {
- case PKI_PATH:
- if (pkiPathEncoding == null) {
- pkiPathEncoding = ASN1.encode(this);
- }
-
- return pkiPathEncoding.clone();
- case PKCS7:
- if (pkcs7Encoding == null) {
- pkcs7Encoding = PKCS7_SIGNED_DATA_OBJECT.encode(this);
- }
-
- return pkcs7Encoding.clone();
- default:
- throw new CertificateEncodingException("Unsupported encoding: " + encoding);
- }
- }
-
- /**
- * @see java.security.cert.CertPath#getEncoded(String)
- */
- @Override
- public byte[] getEncoded(String encoding) throws CertificateEncodingException {
- final Encoding encType = Encoding.findByApiName(encoding);
- if (encType == null) {
- throw new CertificateEncodingException("Unsupported encoding: " + encoding);
- }
-
- return getEncoded(encType);
- }
-
- /**
- * @see java.security.cert.CertPath#getEncodings()
- * method documentation for more info
- */
- @Override
- public Iterator<String> getEncodings() {
- return encodings.iterator();
- }
-
- /**
- * ASN.1 DER Encoder/Decoder for PkiPath structure.
- */
- public static final ASN1SequenceOf ASN1 = new ASN1SequenceOf(ASN1Any.getInstance()) {
- /**
- * Builds the instance of X509CertPathImpl on the base of the list of
- * ASN.1 encodings of X.509 certificates provided via PkiPath structure.
- * This method participates in decoding process.
- */
- public Object getDecodedObject(BerInputStream in) throws IOException {
- // retrieve the decoded content
- final List<byte[]> encodedCerts = (List<byte[]>) in.content;
-
- final int size = encodedCerts.size();
- final List<X509Certificate> certificates = new ArrayList<X509Certificate>(size);
-
- for (int i = size - 1; i >= 0; i--) {
- // create the X.509 certificate on the base of its encoded form
- // and add it to the list.
- certificates.add(new X509CertImpl((Certificate) Certificate.ASN1
- .decode(encodedCerts.get(i))));
- }
-
- // create and return the resulting object
- return new X509CertPathImpl(certificates, Encoding.PKI_PATH);
- }
-
- /**
- * Returns the Collection of the encoded form of certificates contained
- * in the X509CertPathImpl object to be encoded.
- * This method participates in encoding process.
- */
- public Collection<byte[]> getValues(Object object) {
- // object to be encoded
- final X509CertPathImpl cp = (X509CertPathImpl) object;
-
- // if it has no certificates in it - create the sequence of size 0
- if (cp.certificates == null) {
- return Collections.emptyList();
- }
-
- final int size = cp.certificates.size();
- final List<byte[]> encodings = new ArrayList<byte[]>(size);
-
- try {
- for (int i = size - 1; i >= 0; i--) {
- // get the encoded form of certificate and place it into the
- // list to be encoded in PkiPath format
- encodings.add(cp.certificates.get(i).getEncoded());
- }
- } catch (CertificateEncodingException e) {
- throw new IllegalArgumentException("Encoding error occurred", e);
- }
-
- return encodings;
- }
- };
-
-
- /**
- * Encoder for PKCS#7 SignedData. It is assumed that only certificate field
- * is important all other fields contain pre-calculated encodings.
- */
- private static final ASN1Sequence ASN1_SIGNED_DATA = new ASN1Sequence(
- new ASN1Type[] {
- // version ,digestAlgorithms, content info
- ASN1Any.getInstance(),
- // certificates
- new ASN1Implicit(0, ASN1),
- // set of crls is optional and is missed here
- ASN1Any.getInstance(),// signers info
- }) {
-
- // precalculated ASN.1 encodings for
- // version ,digestAlgorithms, content info field of SignedData
- private final byte[] PRECALCULATED_HEAD = new byte[] { 0x02, 0x01,
- 0x01,// version (v1)
- 0x31, 0x00,// empty set of DigestAlgorithms
- 0x30, 0x03, 0x06, 0x01, 0x00 // empty ContentInfo with oid=0
- };
-
- // precalculated empty set of SignerInfos
- private final byte[] SIGNERS_INFO = new byte[] { 0x31, 0x00 };
-
- protected void getValues(Object object, Object[] values) {
- values[0] = PRECALCULATED_HEAD;
- values[1] = object; // pass X509CertPathImpl object
- values[2] = SIGNERS_INFO;
- }
-
- // stub to prevent using the instance as decoder
- public Object decode(BerInputStream in) throws IOException {
- throw new RuntimeException(
- "Invalid use of encoder for PKCS#7 SignedData object");
- }
- };
-
- private static final ASN1Sequence PKCS7_SIGNED_DATA_OBJECT = new ASN1Sequence(
- new ASN1Type[] { ASN1Any.getInstance(), // contentType
- new ASN1Explicit(0, ASN1_SIGNED_DATA) // SignedData
- }) {
-
- // precalculated ASN.1 encoding for SignedData object oid
- private final byte[] SIGNED_DATA_OID = ASN1Oid.getInstance().encode(
- ContentInfo.SIGNED_DATA);
-
- protected void getValues(Object object, Object[] values) {
- values[0] = SIGNED_DATA_OID;
- values[1] = object; // pass X509CertPathImpl object
- }
-
- // stub to prevent using the instance as decoder
- public Object decode(BerInputStream in) throws IOException {
- throw new RuntimeException(
- "Invalid use of encoder for PKCS#7 SignedData object");
- }
- };
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java
index 7c2785a..ad5ac7d 100644
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java
+++ b/luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java
@@ -20,12 +20,9 @@ package org.apache.harmony.security.provider.crypto;
import java.security.Provider;
/**
- * Implementation of Provider for SecureRandom, MessageDigest and Signature
- * using a Secure Hash Algorithm, SHA-1;
- * see SECURE HASH STANDARD, FIPS PUB 180-1 (http://www.itl.nist.gov/fipspubs/fip180-1.htm) <BR>
- * <BR>
- * The implementation supports "SHA1PRNG", "SHA-1" and "SHA1withDSA" algorithms described in
- * JavaTM Cryptography Architecture, API Specification & Reference
+ * Implementation of Provider for SecureRandom. The implementation supports the
+ * "SHA1PRNG" algorithm described in JavaTM Cryptography Architecture, API
+ * Specification & Reference
*/
public final class CryptoProvider extends Provider {
@@ -36,46 +33,10 @@ public final class CryptoProvider extends Provider {
* Creates a Provider and puts parameters
*/
public CryptoProvider() {
-
super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
- // names of classes implementing services
- final String MD_NAME = "org.apache.harmony.security.provider.crypto.SHA1_MessageDigestImpl";
- final String SR_NAME = "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl";
-
- final String SIGN_NAME = "org.apache.harmony.security.provider.crypto.SHA1withDSA_SignatureImpl";
-
- final String SIGN_ALIAS = "SHA1withDSA";
-
-
- final String KEYF_NAME = "org.apache.harmony.security.provider.crypto.DSAKeyFactoryImpl";
-
- put("MessageDigest.SHA-1", MD_NAME);
- put("MessageDigest.SHA-1 ImplementedIn", "Software");
- put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
- put("Alg.Alias.MessageDigest.SHA", "SHA-1");
-
- put("SecureRandom.SHA1PRNG", SR_NAME);
+ put("SecureRandom.SHA1PRNG",
+ "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
-
- put("Signature.SHA1withDSA", SIGN_NAME);
- put("Signature.SHA1withDSA ImplementedIn", "Software");
- put("Alg.Alias.Signature.SHAwithDSA", SIGN_ALIAS);
- put("Alg.Alias.Signature.DSAwithSHA1", SIGN_ALIAS);
- put("Alg.Alias.Signature.SHA1/DSA", SIGN_ALIAS);
- put("Alg.Alias.Signature.SHA/DSA", SIGN_ALIAS);
- put("Alg.Alias.Signature.SHA-1/DSA", SIGN_ALIAS);
- put("Alg.Alias.Signature.DSA", SIGN_ALIAS);
- put("Alg.Alias.Signature.DSS", SIGN_ALIAS);
-
- put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", SIGN_ALIAS);
- put("Alg.Alias.Signature.1.2.840.10040.4.3", SIGN_ALIAS);
- put("Alg.Alias.Signature.1.3.14.3.2.13", SIGN_ALIAS);
- put("Alg.Alias.Signature.1.3.14.3.2.27", SIGN_ALIAS);
-
- put("KeyFactory.DSA", KEYF_NAME);
- put("KeyFactory.DSA ImplementedIn", "Software");
- put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
- put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
}
}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java
deleted file mode 100644
index 690d16e..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.provider.crypto;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactorySpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-public class DSAKeyFactoryImpl extends KeyFactorySpi {
-
- /**
- * This method generates a DSAPrivateKey object from the provided key specification.
- *
- * @param
- * keySpec - the specification (key material) for the DSAPrivateKey.
- *
- * @return
- * a DSAPrivateKey object
- *
- * @throws InvalidKeySpecException
- * if "keySpec" is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec
- */
- protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
- throws InvalidKeySpecException {
-
- if (keySpec != null) {
- if (keySpec instanceof DSAPrivateKeySpec) {
-
- return new DSAPrivateKeyImpl((DSAPrivateKeySpec) keySpec);
- }
- if (keySpec instanceof PKCS8EncodedKeySpec) {
-
- return new DSAPrivateKeyImpl((PKCS8EncodedKeySpec) keySpec);
- }
- }
- throw new InvalidKeySpecException("'keySpec' is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec");
- }
-
- /**
- * This method generates a DSAPublicKey object from the provided key specification.
- *
- * @param
- * keySpec - the specification (key material) for the DSAPublicKey.
- *
- * @return
- * a DSAPublicKey object
- *
- * @throws InvalidKeySpecException
- * if "keySpec" is neither DSAPublicKeySpec nor X509EncodedKeySpec
- */
- protected PublicKey engineGeneratePublic(KeySpec keySpec)
- throws InvalidKeySpecException {
-
- if (keySpec != null) {
- if (keySpec instanceof DSAPublicKeySpec) {
-
- return new DSAPublicKeyImpl((DSAPublicKeySpec) keySpec);
- }
- if (keySpec instanceof X509EncodedKeySpec) {
-
- return new DSAPublicKeyImpl((X509EncodedKeySpec) keySpec);
- }
- }
- throw new InvalidKeySpecException("'keySpec' is neither DSAPublicKeySpec nor X509EncodedKeySpec");
- }
-
- /**
- * This method returns a specification for the supplied key.
- *
- * The specification will be returned in the form of an object of the type
- * specified by keySpec.
- *
- * @param key -
- * either DSAPrivateKey or DSAPublicKey
- * @param keySpec -
- * either DSAPrivateKeySpec.class or DSAPublicKeySpec.class
- *
- * @return either a DSAPrivateKeySpec or a DSAPublicKeySpec
- *
- * @throws InvalidKeySpecException
- * if "keySpec" is not a specification for DSAPublicKey or
- * DSAPrivateKey
- */
- protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
- throws InvalidKeySpecException {
-
- BigInteger p, q, g, x, y;
-
- if (key != null) {
- if (keySpec == null) {
- throw new NullPointerException("keySpec == null");
- }
- if (key instanceof DSAPrivateKey) {
- DSAPrivateKey privateKey = (DSAPrivateKey) key;
-
- if (keySpec.equals(DSAPrivateKeySpec.class)) {
-
- x = privateKey.getX();
-
- DSAParams params = privateKey.getParams();
-
- p = params.getP();
- q = params.getQ();
- g = params.getG();
-
- return (T) (new DSAPrivateKeySpec(x, p, q, g));
- }
-
- if (keySpec.equals(PKCS8EncodedKeySpec.class)) {
- return (T) (new PKCS8EncodedKeySpec(key.getEncoded()));
- }
-
- throw new InvalidKeySpecException("'keySpec' is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec");
- }
-
- if (key instanceof DSAPublicKey) {
- DSAPublicKey publicKey = (DSAPublicKey) key;
-
- if (keySpec.equals(DSAPublicKeySpec.class)) {
-
- y = publicKey.getY();
-
- DSAParams params = publicKey.getParams();
-
- p = params.getP();
- q = params.getQ();
- g = params.getG();
-
- return (T) (new DSAPublicKeySpec(y, p, q, g));
- }
-
- if (keySpec.equals(X509EncodedKeySpec.class)) {
- return (T) (new X509EncodedKeySpec(key.getEncoded()));
- }
-
- throw new InvalidKeySpecException("'keySpec' is neither DSAPublicKeySpec nor X509EncodedKeySpec");
- }
- }
- throw new InvalidKeySpecException("'key' is neither DSAPublicKey nor DSAPrivateKey");
- }
-
- /**
- * The method generates a DSAPublicKey object from the provided key.
- *
- * @param
- * key - a DSAPublicKey object or DSAPrivateKey object.
- *
- * @return
- * object of the same type as the "key" argument
- *
- * @throws InvalidKeyException
- * if "key" is neither DSAPublicKey nor DSAPrivateKey
- */
- protected Key engineTranslateKey(Key key) throws InvalidKeyException {
-
- if (key != null) {
- if (key instanceof DSAPrivateKey) {
-
- DSAPrivateKey privateKey = (DSAPrivateKey) key;
- DSAParams params = privateKey.getParams();
-
- try {
- return engineGeneratePrivate(new DSAPrivateKeySpec(
- privateKey.getX(), params.getP(), params.getQ(),
- params.getG()));
- } catch (InvalidKeySpecException e) {
- // Actually this exception shouldn't be thrown
- throw new InvalidKeyException("ATTENTION: InvalidKeySpecException: " + e);
- }
- }
-
- if (key instanceof DSAPublicKey) {
-
- DSAPublicKey publicKey = (DSAPublicKey) key;
- DSAParams params = publicKey.getParams();
-
- try {
- return engineGeneratePublic(new DSAPublicKeySpec(publicKey
- .getY(), params.getP(), params.getQ(), params
- .getG()));
- } catch (InvalidKeySpecException e) {
- // Actually this exception shouldn't be thrown
- throw new InvalidKeyException("ATTENTION: InvalidKeySpecException: " + e);
- }
- }
- }
- throw new InvalidKeyException("'key' is neither DSAPublicKey nor DSAPrivateKey");
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java
deleted file mode 100644
index c0fc766..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * TODO
- * 1. The class extends the PrivateKeyImpl class in "org.apache.harmony.security" package.
- *
- * 2. See a compatibility with RI comments
- * in the below "DSAPrivateKeyImpl(PKCS8EncodedKeySpec keySpec)" constructor.
- */
-
-
-package org.apache.harmony.security.provider.crypto;
-
-import java.io.IOException;
-import java.io.NotActiveException;
-import java.math.BigInteger;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.spec.DSAParameterSpec;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import org.apache.harmony.security.PrivateKeyImpl;
-import org.apache.harmony.security.asn1.ASN1Integer;
-import org.apache.harmony.security.pkcs8.PrivateKeyInfo;
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.apache.harmony.security.x509.AlgorithmIdentifier;
-
-/**
- * The class provides DSAPrivateKey functionality by extending a class implementing PrivateKey
- * and implementing methods defined in both interfaces, DSAKey and DSAPrivateKey
- */
-public class DSAPrivateKeyImpl extends PrivateKeyImpl implements DSAPrivateKey {
-
- /**
- * @serial
- */
- private static final long serialVersionUID = -4716227614104950081L;
-
- private BigInteger x, g, p, q;
-
- private transient DSAParams params;
-
- /**
- * Creates object from DSAPrivateKeySpec.
- *
- * @param keySpec - a DSAPrivateKeySpec object
- */
- public DSAPrivateKeyImpl(DSAPrivateKeySpec keySpec) {
-
- super("DSA");
-
- PrivateKeyInfo pki;
-
- g = keySpec.getG();
- p = keySpec.getP();
- q = keySpec.getQ();
-
- ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p
- .toByteArray(), q.toByteArray(), g.toByteArray());
-
- AlgorithmIdentifier ai = new AlgorithmIdentifier(AlgNameMapper
- .map2OID("DSA"),
- threeInts.getEncoded());
- x = keySpec.getX();
-
- pki = new PrivateKeyInfo(0, ai, ASN1Integer.getInstance().encode(
- x.toByteArray()), null);
-
- setEncoding(pki.getEncoded());
-
- params = new DSAParameterSpec(p, q, g);
- }
-
- /**
- * Creates object from PKCS8EncodedKeySpec.
- *
- * @param keySpec - a XPKCS8EncodedKeySpec object
- *
- * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format
- */
- public DSAPrivateKeyImpl(PKCS8EncodedKeySpec keySpec)
- throws InvalidKeySpecException {
-
- super("DSA");
-
- AlgorithmIdentifier ai;
- ThreeIntegerSequence threeInts = null;
-
- String alg, algName;
-
- byte[] encoding = keySpec.getEncoded();
-
- PrivateKeyInfo privateKeyInfo = null;
-
- try {
- privateKeyInfo = (PrivateKeyInfo) PrivateKeyInfo.ASN1
- .decode(encoding);
- } catch (IOException e) {
- throw new InvalidKeySpecException("Failed to decode keySpec encoding: " + e);
- }
-
- try {
- x = new BigInteger((byte[]) ASN1Integer.getInstance().decode(
- privateKeyInfo.getPrivateKey()));
- } catch (IOException e) {
- throw new InvalidKeySpecException("Failed to decode parameters: " + e);
- }
-
- ai = privateKeyInfo.getAlgorithmIdentifier();
- try {
- threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1
- .decode(ai.getParameters());
- } catch (IOException e) {
- throw new InvalidKeySpecException("Failed to decode parameters: " + e);
- }
- p = new BigInteger(threeInts.p);
- q = new BigInteger(threeInts.q);
- g = new BigInteger(threeInts.g);
- params = new DSAParameterSpec(p, q, g);
- setEncoding(encoding);
-
- /*
- * the following code implements RI behavior
- */
- alg = ai.getAlgorithm();
- algName = AlgNameMapper.map2AlgName(alg);
- setAlgorithm(algName == null ? alg : algName);
- }
-
- public BigInteger getX() {
- return x;
- }
-
- public DSAParams getParams() {
- return params;
- }
-
- private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException {
- in.defaultReadObject();
- params = new DSAParameterSpec(p, q, g);
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java
deleted file mode 100644
index 6b35970..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * TODO
- * 1. The class extends the PublicKeyImpl class in "org.apache.harmony.security" package.
- *
- * 2. The class uses methods in the auxiliary non-public "ThreeIntegerSequence" class
- * defined along with the "DSAPrivateKeyImpl" class.
- *
- * 3. See a compatibility with RI comments
- * in the below "DSAPublicKeyImpl(X509EncodedKeySpec keySpec)" constructor.
- */
-
-package org.apache.harmony.security.provider.crypto;
-
-import java.io.IOException;
-import java.io.NotActiveException;
-import java.math.BigInteger;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAParameterSpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import org.apache.harmony.security.PublicKeyImpl;
-import org.apache.harmony.security.asn1.ASN1Integer;
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.apache.harmony.security.x509.AlgorithmIdentifier;
-import org.apache.harmony.security.x509.SubjectPublicKeyInfo;
-
-/**
- * The class provides DSAPublicKey functionality by extending a class implementing PublicKey
- * and implementing methods defined in both interfaces, DSAKey and DSAPublicKey
- */
-public class DSAPublicKeyImpl extends PublicKeyImpl implements DSAPublicKey {
-
- /**
- * @serial
- */
- private static final long serialVersionUID = -2279672131310978336L;
-
- private BigInteger y, g, p, q;
-
- private transient DSAParams params;
-
- /**
- * Creates object from DSAPublicKeySpec.
- *
- * @param keySpec - a DSAPublicKeySpec object
- */
- public DSAPublicKeyImpl(DSAPublicKeySpec keySpec) {
-
- super("DSA");
-
- SubjectPublicKeyInfo spki;
-
- p = keySpec.getP();
- q = keySpec.getQ();
- g = keySpec.getG();
-
- ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p
- .toByteArray(), q.toByteArray(), g.toByteArray());
-
- AlgorithmIdentifier ai = new AlgorithmIdentifier(AlgNameMapper
- .map2OID("DSA"),
- threeInts.getEncoded());
-
- y = keySpec.getY();
-
- spki = new SubjectPublicKeyInfo(ai, ASN1Integer.getInstance().encode(
- y.toByteArray()));
- setEncoding(spki.getEncoded());
-
- params = (DSAParams) (new DSAParameterSpec(p, q, g));
- }
-
- /**
- * Creates object from X509EncodedKeySpec.
- *
- * @param keySpec - a X509EncodedKeySpec object
- *
- * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format
- */
- public DSAPublicKeyImpl(X509EncodedKeySpec keySpec)
- throws InvalidKeySpecException {
-
- super("DSA");
-
- AlgorithmIdentifier ai;
- ThreeIntegerSequence threeInts = null;
-
- SubjectPublicKeyInfo subjectPublicKeyInfo = null;
-
- byte[] encoding = keySpec.getEncoded();
-
- String alg, algName;
-
- try {
- subjectPublicKeyInfo = (SubjectPublicKeyInfo) SubjectPublicKeyInfo.ASN1
- .decode(encoding);
- } catch (IOException e) {
- throw new InvalidKeySpecException("Failed to decode keySpec encoding: " + e);
- }
-
- try {
- y = new BigInteger((byte[]) ASN1Integer.getInstance().decode(
- subjectPublicKeyInfo.getSubjectPublicKey()));
- } catch (IOException e) {
- throw new InvalidKeySpecException("Failed to decode parameters: " + e);
- }
-
- ai = subjectPublicKeyInfo.getAlgorithmIdentifier();
-
- try {
- threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1
- .decode(ai.getParameters());
- } catch (IOException e) {
- throw new InvalidKeySpecException("Failed to decode parameters: " + e);
- }
- p = new BigInteger(threeInts.p);
- q = new BigInteger(threeInts.q);
- g = new BigInteger(threeInts.g);
- params = (DSAParams) (new DSAParameterSpec(p, q, g));
-
- setEncoding(encoding);
-
- /*
- * the following code implements RI behavior
- */
- alg = ai.getAlgorithm();
- algName = AlgNameMapper.map2AlgName(alg);
- setAlgorithm(algName == null ? alg : algName);
- }
-
- /**
- * @return
- * a value of a public key (y).
- */
- public BigInteger getY() {
- return y;
- }
-
- /**
- * @return
- * DSA key parameters (p, q, g).
- */
- public DSAParams getParams() {
- return params;
- }
-
- private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException {
- in.defaultReadObject();
- params = new DSAParameterSpec(p, q, g);
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1_MessageDigestImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1_MessageDigestImpl.java
deleted file mode 100644
index 3f41f18..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1_MessageDigestImpl.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.harmony.security.provider.crypto;
-
-import java.security.DigestException;
-import java.security.MessageDigestSpi;
-import java.util.Arrays;
-
-import static org.apache.harmony.security.provider.crypto.SHA1Constants.*;
-
-/**
- * This class extends the MessageDigestSpi class implementing all its abstract methods;
- * it overrides the "Object clone()" and "int engineGetDigestLength()" methods. <BR>
- * The class implements the Cloneable interface.
- */
-public class SHA1_MessageDigestImpl extends MessageDigestSpi implements Cloneable {
- private int[] buffer; // buffer has the following structure:
- // - 0-16 - frame for accumulating a message
- // - 17-79 - for SHA1Impl methods
- // - 80 - unused
- // - 81 - to store length of the message
- // - 82-86 - frame for current message digest
-
- private byte[] oneByte; // one byte buffer needed to use in engineUpdate(byte)
- // having buffer as private field is just optimization
-
- private long messageLength; // total length of bytes supplied by user
-
-
- /**
- * The constructor creates needed buffers and sets the engine at initial state
- */
- public SHA1_MessageDigestImpl() {
-
- // BYTES_OFFSET +6 is minimal length required by methods in SHA1Impl
- buffer = new int[BYTES_OFFSET +6];
-
- oneByte = new byte[1];
-
- engineReset();
- }
-
-
- /**
- * The method performs final actions and invokes the "computeHash(int[])" method.
- * In case if there is no enough words in current frame
- * after processing its data, extra frame is prepared and
- * the "computeHash(int[])" method is invoked second time. <BR>
- *
- * After processing, the method resets engine's state
- *
- * @param
- * digest - byte array
- * @param
- * offset - offset in digest
- */
- private void processDigest(byte[] digest, int offset) {
-
- int i, j; // implementation variables
- int lastWord; //
-
- long nBits = messageLength <<3 ; // length has to be calculated before padding
-
- engineUpdate( (byte) 0x80 ); // beginning byte in padding
-
- i = 0; // i contains number of beginning word for following loop
-
- lastWord = (buffer[BYTES_OFFSET] + 3)>>2 ; // computing of # of full words by shifting
- // # of bytes
-
- // possible cases:
- //
- // - buffer[BYTES_OFFSET] == 0 - buffer frame is empty,
- // padding byte was 64th in previous frame
- // current frame should contain only message's length
- //
- // - lastWord < 14 - two last, these are 14 & 15, words in 16 word frame are free;
- // no extra frame needed
- // - lastWord = 14 - only one last, namely 15-th, word in frame doesn't contain bytes;
- // extra frame is needed
- // - lastWord > 14 - last word in frame is not full;
- // extra frame is needed
-
- if ( buffer[BYTES_OFFSET] != 0 ) {
-
- if ( lastWord < 15 ) {
- i = lastWord;
- } else {
- if ( lastWord == 15 ) {
- buffer[15] = 0; // last word in frame is set to "0"
- }
- SHA1Impl.computeHash(buffer);
- i = 0;
- }
- }
- Arrays.fill(buffer, i, 14, 0);
-
- buffer[14] = (int)( nBits >>>32 );
- buffer[15] = (int)( nBits & 0xFFFFFFFF );
- SHA1Impl.computeHash(buffer);
-
- // converting 5-word frame into 20 bytes
- j = offset;
- for ( i = HASH_OFFSET; i < HASH_OFFSET +5; i++ ) {
- int k = buffer[i];
- digest[j ] = (byte) ( k >>>24 ); // getting first byte from left
- digest[j+1] = (byte) ( k >>>16 ); // getting second byte from left
- digest[j+2] = (byte) ( k >>> 8 ); // getting third byte from left
- digest[j+3] = (byte) ( k ); // getting fourth byte from left
- j += 4;
- }
-
- engineReset();
- }
-
- // methods specified in java.security.MessageDigestSpi
-
- /**
- * Returns a "deep" copy of this SHA1MDImpl object. <BR>
- *
- * The method overrides "clone()" in class Object. <BR>
- *
- * @return
- * a clone of this object
- */
- public Object clone() throws CloneNotSupportedException {
- SHA1_MessageDigestImpl cloneObj = (SHA1_MessageDigestImpl) super.clone();
- cloneObj.buffer = buffer.clone();
- cloneObj.oneByte = oneByte.clone();
- return cloneObj;
- }
-
-
- /**
- * Computes a message digest value. <BR>
- *
- * The method resets the engine. <BR>
- *
- * The method overrides "engineDigest()" in class MessageDigestSpi. <BR>
- *
- * @return
- * byte array containing message digest value
- */
- protected byte[] engineDigest() {
- byte[] hash = new byte[DIGEST_LENGTH];
- processDigest(hash, 0);
- return hash;
- }
-
-
- /**
- * Computes message digest value.
- * Upon return, the value is stored in "buf" buffer beginning "offset" byte. <BR>
- *
- * The method resets the engine. <BR>
- *
- * The method overrides "engineDigest(byte[],int,int) in class MessageDigestSpi.
- *
- * @param
- * buf byte array to store a message digest returned
- * @param
- * offset a position in the array for first byte of the message digest
- * @param
- * len number of bytes within buffer allotted for the message digest;
- * as this implementation doesn't provide partial digests,
- * len should be >= 20, DigestException is thrown otherwise
- * @return
- * the length of the message digest stored in the "buf" buffer;
- * in this implementation the length=20
- *
- * @throws IllegalArgumentException
- * if null is passed to the "buf" argument <BR>
- * if offset + len > buf.length <BR>
- * if offset > buf.length or len > buf.length
- *
- * @throws DigestException
- * if len < 20
- *
- * @throws ArrayIndexOutOfBoundsException
- * if offset < 0
- */
- protected int engineDigest(byte[] buf, int offset, int len) throws DigestException {
- if (buf == null) {
- throw new IllegalArgumentException("buf == null");
- }
- if (offset > buf.length || len > buf.length || (len + offset) > buf.length) {
- throw new IllegalArgumentException();
- }
- if (len < DIGEST_LENGTH) {
- throw new DigestException("len < DIGEST_LENGTH");
- }
- if (offset < 0) {
- throw new ArrayIndexOutOfBoundsException(offset);
- }
-
- processDigest(buf, offset);
-
- return DIGEST_LENGTH;
- }
-
-
- /**
- * Returns a message digest length. <BR>
- *
- * The method overrides "engineGetDigestLength()" in class MessageDigestSpi. <BR>
- *
- * @return
- * total length of current message digest as an int value
- */
- protected int engineGetDigestLength() {
- return DIGEST_LENGTH;
- }
-
-
- /**
- * Resets the engine. <BR>
- *
- * The method overrides "engineReset()" in class MessageDigestSpi. <BR>
- */
- protected void engineReset() {
-
- messageLength = 0;
-
- buffer[BYTES_OFFSET] = 0;
- buffer[HASH_OFFSET ] = H0;
- buffer[HASH_OFFSET +1] = H1;
- buffer[HASH_OFFSET +2] = H2;
- buffer[HASH_OFFSET +3] = H3;
- buffer[HASH_OFFSET +4] = H4;
- }
-
-
- /**
- * Supplements a byte to current message. <BR>
- *
- * The method overrides "engineUpdate(byte)" in class MessageDigestSpi. <BR>
- *
- * @param
- * input byte to add to current message
- */
- protected void engineUpdate(byte input) {
-
- oneByte[0] = input;
- SHA1Impl.updateHash( buffer, oneByte, 0, 0 );
- messageLength++;
- }
-
-
- /**
- * Updates current message. <BR>
- *
- * The method overrides "engineUpdate(byte[],int,int)" in class MessageDigestSpi. <BR>
- *
- * The method silently returns if "len" <= 0.
- *
- * @param
- * input a byte array
- * @param
- * offset a number of first byte in the "input" array to use for updating
- * @param
- * len a number of bytes to use
- *
- * @throws NullPointerException
- * if null is passed to the "buf" argument
- *
- * @throws IllegalArgumentException
- * if offset > buf.length or len > buf.length or
- * (len + offset) > buf.length
- * @throws ArrayIndexOutOfBoundsException
- * offset < 0
- */
- protected void engineUpdate(byte[] input, int offset, int len) {
- if (input == null) {
- throw new IllegalArgumentException("input == null");
- }
- if (len <= 0) {
- return;
- }
- if (offset < 0) {
- throw new ArrayIndexOutOfBoundsException(offset);
- }
- if (offset > input.length || len > input.length || (len + offset) > input.length) {
- throw new IllegalArgumentException();
- }
-
- SHA1Impl.updateHash(buffer, input, offset, offset + len -1 );
- messageLength += len;
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1withDSA_SignatureImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1withDSA_SignatureImpl.java
deleted file mode 100644
index 2958e00..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1withDSA_SignatureImpl.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.provider.crypto;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.interfaces.DSAKey;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-
-public class SHA1withDSA_SignatureImpl extends Signature {
-
- private MessageDigest msgDigest;
-
- private DSAKey dsaKey;
-
- /**
- * The solo constructor.
- */
- public SHA1withDSA_SignatureImpl() throws NoSuchAlgorithmException {
-
- super("SHA1withDSA");
-
- msgDigest = MessageDigest.getInstance("SHA1");
- }
-
- /**
- * Deprecated method.
- *
- * @return
- * null
- */
- protected Object engineGetParameter(String param)
- throws InvalidParameterException {
- if (param == null) {
- throw new NullPointerException("param == null");
- }
- return null;
- }
-
- /**
- * Initializes this signature object with PrivateKey object
- * passed as argument to the method.
- *
- * @params
- * privateKey DSAPrivateKey object
- * @throws
- * InvalidKeyException if privateKey is not DSAPrivateKey object
- */
- protected void engineInitSign(PrivateKey privateKey)
- throws InvalidKeyException {
-
- DSAParams params;
-
- // parameters and private key
- BigInteger p, q, x;
-
- int n;
-
- if (privateKey == null || !(privateKey instanceof DSAPrivateKey)) {
- throw new InvalidKeyException();
- }
-
- params = ((DSAPrivateKey) privateKey).getParams();
- p = params.getP();
- q = params.getQ();
- x = ((DSAPrivateKey) privateKey).getX();
-
- // checks described in DSA standard
- n = p.bitLength();
- if (p.compareTo(BigInteger.valueOf(1)) != 1 || n < 512 || n > 1024 || (n & 077) != 0) {
- throw new InvalidKeyException("bad p");
- }
- if (q.signum() != 1 && q.bitLength() != 160) {
- throw new InvalidKeyException("bad q");
- }
- if (x.signum() != 1 || x.compareTo(q) != -1) {
- throw new InvalidKeyException("x <= 0 || x >= q");
- }
-
- dsaKey = (DSAKey) privateKey;
-
- msgDigest.reset();
- }
-
- /**
- * Initializes this signature object with PublicKey object
- * passed as argument to the method.
- *
- * @params
- * publicKey DSAPublicKey object
- * @throws
- * InvalidKeyException if publicKey is not DSAPublicKey object
- */
- protected void engineInitVerify(PublicKey publicKey)
- throws InvalidKeyException {
-
- // parameters and public key
- BigInteger p, q, y;
-
- int n1;
-
- if (publicKey == null || !(publicKey instanceof DSAPublicKey)) {
- throw new InvalidKeyException("publicKey is not an instance of DSAPublicKey");
- }
-
- DSAParams params = ((DSAPublicKey) publicKey).getParams();
- p = params.getP();
- q = params.getQ();
- y = ((DSAPublicKey) publicKey).getY();
-
- // checks described in DSA standard
- n1 = p.bitLength();
- if (p.compareTo(BigInteger.valueOf(1)) != 1 || n1 < 512 || n1 > 1024 || (n1 & 077) != 0) {
- throw new InvalidKeyException("bad p");
- }
- if (q.signum() != 1 || q.bitLength() != 160) {
- throw new InvalidKeyException("bad q");
- }
- if (y.signum() != 1) {
- throw new InvalidKeyException("y <= 0");
- }
-
- dsaKey = (DSAKey) publicKey;
-
- msgDigest.reset();
- }
-
- /*
- * Deprecated method.
- *
- * @throws
- * InvalidParameterException
- */
- protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
- if (param == null) {
- throw new NullPointerException("param == null");
- }
- throw new InvalidParameterException("invalid parameter for this engine");
- }
-
- /**
- * Returns signature bytes as byte array containing
- * ASN1 representation for two BigInteger objects
- * which is SEQUENCE of two INTEGERS.
- * Length of sequence varies from less than 46 to 48.
- *
- * Resets object to the state it was in
- * when previous call to either "initSign" method was called.
- *
- * @return
- * byte array containing signature in ASN1 representation
- * @throws
- * SignatureException if object's state is not SIGN or
- * signature algorithm cannot process data
- */
-
- protected byte[] engineSign() throws SignatureException {
-
- // names of below BigIntegers are the same as they are defined in DSA standard
- BigInteger r = null;
- BigInteger s = null;
- BigInteger k = null;
-
- // parameters and private key
- BigInteger p, q, g, x;
-
- // BigInteger for message digest
- BigInteger digestBI;
-
- // various byte array being used in computing signature
- byte[] randomBytes;
- byte[] rBytes;
- byte[] sBytes;
- byte[] signature;
-
- int n, n1, n2;
-
- DSAParams params;
-
- if (appRandom == null) {
- appRandom = new SecureRandom();
- }
-
- params = dsaKey.getParams();
- p = params.getP();
- q = params.getQ();
- g = params.getG();
- x = ((DSAPrivateKey) dsaKey).getX();
-
- // forming signature according algorithm described in chapter 5 of DSA standard
-
- digestBI = new BigInteger(1, msgDigest.digest());
-
- randomBytes = new byte[20];
-
- for (;;) {
-
- appRandom.nextBytes(randomBytes);
-
- k = new BigInteger(1, randomBytes);
- if (k.compareTo(q) != -1) {
- continue;
- }
- r = g.modPow(k, p).mod(q);
- if (r.signum() == 0) {
- continue;
- }
-
- s = k.modInverse(q).multiply(digestBI.add(x.multiply(r)).mod(q))
- .mod(q);
-
- if (s.signum() != 0) {
- break;
- }
- }
-
- // forming signature's ASN1 representation which is SEQUENCE of two INTEGERs
- //
- rBytes = r.toByteArray();
- n1 = rBytes.length;
- if ((rBytes[0] & 0x80) != 0) {
- n1++;
- }
- sBytes = s.toByteArray();
- n2 = sBytes.length;
- if ((sBytes[0] & 0x80) != 0) {
- n2++;
- }
-
- signature = new byte[6 + n1 + n2]; // 48 is max. possible length of signature
- signature[0] = (byte) 0x30; // ASN1 SEQUENCE tag
- signature[1] = (byte) (4 + n1 + n2); // total length of two INTEGERs
- signature[2] = (byte) 0x02; // ASN1 INTEGER tag
- signature[3] = (byte) n1; // length of r
- signature[4 + n1] = (byte) 0x02; // ASN1 INTEGER tag
- signature[5 + n1] = (byte) n2; // length of s
-
- if (n1 == rBytes.length) {
- n = 4;
- } else {
- n = 5;
- }
- System.arraycopy(rBytes, 0, signature, n, rBytes.length);
-
- if (n2 == sBytes.length) {
- n = 6 + n1;
- } else {
- n = 7 + n1;
- }
- System.arraycopy(sBytes, 0, signature, n, sBytes.length);
-
- return signature;
- }
-
- /**
- * Updates data to sign or to verify.
- *
- * @params
- * b byte to update
- * @throws
- * SignatureException if object was not initialized for signing or verifying
- */
- protected void engineUpdate(byte b) throws SignatureException {
-
- msgDigest.update(b);
- }
-
- /**
- * Updates data to sign or to verify.
- *
- * @params
- * b byte array containing bytes to update
- * @params
- * off offset in byte array to start from
- * @params
- * len number of bytes to use for updating
- * @throws
- * SignatureException if object was not initialized for signing or verifying
- */
- protected void engineUpdate(byte[] b, int off, int len)
- throws SignatureException {
-
- msgDigest.update(b, off, len);
- }
-
- private boolean checkSignature(byte[] sigBytes, int offset, int length)
- throws SignatureException {
-
- // names of below BigIntegers are the same as they are defined in DSA standard
- BigInteger r, s, w;
- BigInteger u1, u2, v;
-
- // parameters and public key
- BigInteger p, q, g, y;
-
- DSAParams params;
-
- int n1, n2;
-
- byte[] bytes;
- byte[] digest;
-
- // checking up on signature's ASN1
- try {
- byte dummy;
- n1 = sigBytes[offset + 3];
- n2 = sigBytes[offset + n1 + 5];
-
- if (sigBytes[offset + 0] != 0x30 || sigBytes[offset + 2] != 2
- || sigBytes[offset + n1 + 4] != 2
- || sigBytes[offset + 1] != (n1 + n2 + 4) || n1 > 21
- || n2 > 21
- || (length != 0 && (sigBytes[offset + 1] + 2) > length)) {
- throw new SignatureException("signature bytes have invalid encoding");
- }
-
- dummy = sigBytes[5 + n1 + n2]; // to check length of sigBytes
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new SignatureException("bad argument: byte[] is too small");
- }
-
- digest = msgDigest.digest();
-
- bytes = new byte[n1];
- System.arraycopy(sigBytes, offset + 4, bytes, 0, n1);
- r = new BigInteger(bytes);
-
- bytes = new byte[n2];
- System.arraycopy(sigBytes, offset + 6 + n1, bytes, 0, n2);
- s = new BigInteger(bytes);
-
- params = dsaKey.getParams();
- p = params.getP();
- q = params.getQ();
- g = params.getG();
- y = ((DSAPublicKey) dsaKey).getY();
-
- // forming signature according algorithm described in chapter 6 of DSA standard
-
- if (r.signum() != 1 || r.compareTo(q) != -1 || s.signum() != 1
- || s.compareTo(q) != -1) {
- return false;
- }
-
- w = s.modInverse(q);
-
- u1 = (new BigInteger(1, digest)).multiply(w).mod(q);
- u2 = r.multiply(w).mod(q);
-
- v = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q);
-
- if (v.compareTo(r) != 0) {
- return false;
- }
- return true;
- }
-
- /**
- * Verifies the signature bytes.
- *
- * @params
- * sigBytes byte array with signature bytes to verify.
- * @return
- * true if signature bytes were verified, false otherwise
- * @throws
- * SignatureException if object's state is not VERIFY or
- * signature format is not ASN1 representation or
- * signature algorithm cannot process data
- */
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- if (sigBytes == null) {
- throw new NullPointerException("sigBytes == null");
- }
-
- return checkSignature(sigBytes, 0, 0);
- }
-
- /**
- * Verifies the signature bytes.
- *
- * @params
- * sigBytes byte array with signature bytes to verify.
- * @params
- * offset index in sigBytes to start from
- * @params
- * length number of bytes allotted for signature
- * @return
- * true if signature bytes were verified, false otherwise
- * @throws
- * SignatureException if object's state is not VERIFY or
- * signature format is not ASN1 representation or
- * signature algorithm cannot process data
- */
- protected boolean engineVerify(byte[] sigBytes, int offset, int length)
- throws SignatureException {
- return checkSignature(sigBytes, offset, length);
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/ThreeIntegerSequence.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/ThreeIntegerSequence.java
deleted file mode 100644
index 4f4232a..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/ThreeIntegerSequence.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.harmony.security.provider.crypto;
-
-import org.apache.harmony.security.asn1.ASN1Integer;
-import org.apache.harmony.security.asn1.ASN1Sequence;
-import org.apache.harmony.security.asn1.ASN1Type;
-import org.apache.harmony.security.asn1.BerInputStream;
-
-
-/**
- * The auxiliary class providing means to process ASN1Sequence of three Integers.
- * Such sequences are parts of ASN1 encoded formats for DSA private and public keys.
- */
-class ThreeIntegerSequence {
-
- byte[] p, q, g;
-
- private byte[] encoding;
-
- ThreeIntegerSequence(byte[] p, byte[] q, byte[] g) {
-
- this.p = p;
- this.q = q;
- this.g = g;
- encoding = null;
- }
-
- public byte[] getEncoded() {
- if (encoding == null) {
- encoding = ASN1.encode(this);
- }
- return encoding;
- }
-
- public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
- ASN1Integer.getInstance(), ASN1Integer.getInstance(),
- ASN1Integer.getInstance() }) {
-
- protected Object getDecodedObject(BerInputStream in) {
-
- Object[] values = (Object[]) in.content;
-
- return new ThreeIntegerSequence((byte[]) values[0],
- (byte[]) values[1], (byte[]) values[2]);
- }
-
- protected void getValues(Object object, Object[] values) {
-
- ThreeIntegerSequence mySeq = (ThreeIntegerSequence) object;
-
- values[0] = mySeq.p;
- values[1] = mySeq.q;
- values[2] = mySeq.g;
- }
- };
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java b/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java
index 135394d..e7f3596 100644
--- a/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java
+++ b/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java
@@ -21,6 +21,7 @@
*/
package org.apache.harmony.security.utils;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
@@ -30,10 +31,12 @@ import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.Signature;
import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.LinkedList;
import java.util.List;
import javax.security.auth.x500.X500Principal;
@@ -42,7 +45,6 @@ import org.apache.harmony.security.asn1.BerInputStream;
import org.apache.harmony.security.pkcs7.ContentInfo;
import org.apache.harmony.security.pkcs7.SignedData;
import org.apache.harmony.security.pkcs7.SignerInfo;
-import org.apache.harmony.security.provider.cert.X509CertImpl;
import org.apache.harmony.security.x501.AttributeTypeAndValue;
public class JarUtils {
@@ -53,27 +55,18 @@ public class JarUtils {
new int[] {1, 2, 840, 113549, 1, 9, 4};
/**
- * @see #verifySignature(InputStream, InputStream, boolean)
- */
- public static Certificate[] verifySignature(InputStream signature, InputStream signatureBlock)
- throws IOException, GeneralSecurityException {
- return verifySignature(signature, signatureBlock, false);
- }
-
- /**
* This method handle all the work with PKCS7, ASN1 encoding, signature verifying,
* and certification path building.
* See also PKCS #7: Cryptographic Message Syntax Standard:
* http://www.ietf.org/rfc/rfc2315.txt
* @param signature - the input stream of signature file to be verified
* @param signatureBlock - the input stream of corresponding signature block file
- * @param chainCheck - whether to validate certificate chain signatures
* @return array of certificates used to verify the signature file
* @throws IOException - if some errors occurs during reading from the stream
* @throws GeneralSecurityException - if signature verification process fails
*/
public static Certificate[] verifySignature(InputStream signature, InputStream
- signatureBlock, boolean chainCheck) throws IOException, GeneralSecurityException {
+ signatureBlock) throws IOException, GeneralSecurityException {
BerInputStream bis = new BerInputStream(signatureBlock);
ContentInfo info = (ContentInfo)ContentInfo.ASN1.decode(bis);
@@ -87,9 +80,13 @@ public class JarUtils {
return null;
}
X509Certificate[] certs = new X509Certificate[encCerts.size()];
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
int i = 0;
for (org.apache.harmony.security.x509.Certificate encCert : encCerts) {
- certs[i++] = new X509CertImpl(encCert);
+ final byte[] encoded = encCert.getEncoded();
+ final InputStream is = new ByteArrayInputStream(encoded);
+ certs[i++] = new VerbatimX509Certificate((X509Certificate) cf.generateCertificate(is),
+ encoded);
}
List<SignerInfo> sigInfos = signedData.getSignerInfos();
@@ -131,17 +128,16 @@ public class JarUtils {
String alg = null;
Signature sig = null;
- if (daOid != null && deaOid != null) {
- alg = daOid + "with" + deaOid;
+ if (deaOid != null) {
+ alg = deaOid;
try {
sig = Signature.getInstance(alg);
} catch (NoSuchAlgorithmException e) {
}
- // Try to convert to names instead of OID.
- if (sig == null) {
- final String deaName = sigInfo.getDigestEncryptionAlgorithmName();
- alg = daName + "with" + deaName;
+ final String deaName = sigInfo.getDigestEncryptionAlgorithmName();
+ if (sig == null && deaName != null) {
+ alg = deaName;
try {
sig = Signature.getInstance(alg);
} catch (NoSuchAlgorithmException e) {
@@ -149,19 +145,17 @@ public class JarUtils {
}
}
- /*
- * TODO figure out the case in which we'd only use digestAlgorithm and
- * add a test for it.
- */
- if (sig == null && daOid != null) {
- alg = daOid;
+ if (sig == null && daOid != null && deaOid != null) {
+ alg = daOid + "with" + deaOid;
try {
sig = Signature.getInstance(alg);
} catch (NoSuchAlgorithmException e) {
}
- if (sig == null && daName != null) {
- alg = daName;
+ // Try to convert to names instead of OID.
+ if (sig == null) {
+ final String deaName = sigInfo.getDigestEncryptionAlgorithmName();
+ alg = daName + "with" + deaName;
try {
sig = Signature.getInstance(alg);
} catch (NoSuchAlgorithmException e) {
@@ -232,54 +226,63 @@ public class JarUtils {
throw new SecurityException("Incorrect signature");
}
- return createChain(certs[issuerSertIndex], certs, chainCheck);
+ return createChain(certs[issuerSertIndex], certs);
}
- private static X509Certificate[] createChain(X509Certificate signer,
- X509Certificate[] candidates, boolean chainCheck) {
- LinkedList chain = new LinkedList();
- chain.add(0, signer);
+ private static X509Certificate[] createChain(X509Certificate signer,
+ X509Certificate[] candidates) {
+ Principal issuer = signer.getIssuerDN();
// Signer is self-signed
- if (signer.getSubjectDN().equals(signer.getIssuerDN())){
- return (X509Certificate[])chain.toArray(new X509Certificate[1]);
+ if (signer.getSubjectDN().equals(issuer)) {
+ return new X509Certificate[] { signer };
}
- Principal issuer = signer.getIssuerDN();
+ ArrayList<X509Certificate> chain = new ArrayList<X509Certificate>(candidates.length + 1);
+ chain.add(0, signer);
+
X509Certificate issuerCert;
- X509Certificate subjectCert = signer;
int count = 1;
while (true) {
- issuerCert = findCert(issuer, candidates, subjectCert, chainCheck);
- if( issuerCert == null) {
+ issuerCert = findCert(issuer, candidates);
+ if (issuerCert == null) {
break;
}
chain.add(issuerCert);
count++;
- if (issuerCert.getSubjectDN().equals(issuerCert.getIssuerDN())) {
+ issuer = issuerCert.getIssuerDN();
+ if (issuerCert.getSubjectDN().equals(issuer)) {
break;
}
- issuer = issuerCert.getIssuerDN();
- subjectCert = issuerCert;
}
- return (X509Certificate[])chain.toArray(new X509Certificate[count]);
+ return chain.toArray(new X509Certificate[count]);
}
- private static X509Certificate findCert(Principal issuer, X509Certificate[] candidates,
- X509Certificate subjectCert, boolean chainCheck) {
+ private static X509Certificate findCert(Principal issuer, X509Certificate[] candidates) {
for (int i = 0; i < candidates.length; i++) {
if (issuer.equals(candidates[i].getSubjectDN())) {
- if (chainCheck) {
- try {
- subjectCert.verify(candidates[i].getPublicKey());
- } catch (Exception e) {
- continue;
- }
- }
return candidates[i];
}
}
return null;
}
+ /**
+ * For legacy reasons we need to return exactly the original encoded
+ * certificate bytes, instead of letting the underlying implementation have
+ * a shot at re-encoding the data.
+ */
+ private static class VerbatimX509Certificate extends WrappedX509Certificate {
+ private byte[] encodedVerbatim;
+
+ public VerbatimX509Certificate(X509Certificate wrapped, byte[] encodedVerbatim) {
+ super(wrapped);
+ this.encodedVerbatim = encodedVerbatim;
+ }
+
+ @Override
+ public byte[] getEncoded() throws CertificateEncodingException {
+ return encodedVerbatim;
+ }
+ }
}
diff --git a/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java b/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java
new file mode 100644
index 0000000..2b09309
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.security.utils;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Set;
+
+public class WrappedX509Certificate extends X509Certificate {
+ private final X509Certificate wrapped;
+
+ public WrappedX509Certificate(X509Certificate wrapped) {
+ this.wrapped = wrapped;
+ }
+
+ @Override
+ public Set<String> getCriticalExtensionOIDs() {
+ return wrapped.getCriticalExtensionOIDs();
+ }
+
+ @Override
+ public byte[] getExtensionValue(String oid) {
+ return wrapped.getExtensionValue(oid);
+ }
+
+ @Override
+ public Set<String> getNonCriticalExtensionOIDs() {
+ return wrapped.getNonCriticalExtensionOIDs();
+ }
+
+ @Override
+ public boolean hasUnsupportedCriticalExtension() {
+ return wrapped.hasUnsupportedCriticalExtension();
+ }
+
+ @Override
+ public void checkValidity() throws CertificateExpiredException,
+ CertificateNotYetValidException {
+ wrapped.checkValidity();
+ }
+
+ @Override
+ public void checkValidity(Date date) throws CertificateExpiredException,
+ CertificateNotYetValidException {
+ wrapped.checkValidity(date);
+ }
+
+ @Override
+ public int getVersion() {
+ return wrapped.getVersion();
+ }
+
+ @Override
+ public BigInteger getSerialNumber() {
+ return wrapped.getSerialNumber();
+ }
+
+ @Override
+ public Principal getIssuerDN() {
+ return wrapped.getIssuerDN();
+ }
+
+ @Override
+ public Principal getSubjectDN() {
+ return wrapped.getSubjectDN();
+ }
+
+ @Override
+ public Date getNotBefore() {
+ return wrapped.getNotBefore();
+ }
+
+ @Override
+ public Date getNotAfter() {
+ return wrapped.getNotAfter();
+ }
+
+ @Override
+ public byte[] getTBSCertificate() throws CertificateEncodingException {
+ return wrapped.getTBSCertificate();
+ }
+
+ @Override
+ public byte[] getSignature() {
+ return wrapped.getSignature();
+ }
+
+ @Override
+ public String getSigAlgName() {
+ return wrapped.getSigAlgName();
+ }
+
+ @Override
+ public String getSigAlgOID() {
+ return wrapped.getSigAlgOID();
+ }
+
+ @Override
+ public byte[] getSigAlgParams() {
+ return wrapped.getSigAlgParams();
+ }
+
+ @Override
+ public boolean[] getIssuerUniqueID() {
+ return wrapped.getIssuerUniqueID();
+ }
+
+ @Override
+ public boolean[] getSubjectUniqueID() {
+ return wrapped.getSubjectUniqueID();
+ }
+
+ @Override
+ public boolean[] getKeyUsage() {
+ return wrapped.getKeyUsage();
+ }
+
+ @Override
+ public int getBasicConstraints() {
+ return wrapped.getBasicConstraints();
+ }
+
+ @Override
+ public byte[] getEncoded() throws CertificateEncodingException {
+ return wrapped.getEncoded();
+ }
+
+ @Override
+ public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException {
+ wrapped.verify(key);
+ }
+
+ @Override
+ public void verify(PublicKey key, String sigProvider) throws CertificateException,
+ NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
+ SignatureException {
+ verify(key, sigProvider);
+ }
+
+ @Override
+ public String toString() {
+ return wrapped.toString();
+ }
+
+ @Override
+ public PublicKey getPublicKey() {
+ return wrapped.getPublicKey();
+ }
+}
diff --git a/luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java b/luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java
index 3b5f622..171d9c2 100644
--- a/luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java
+++ b/luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java
@@ -287,6 +287,8 @@ public final class AttributeTypeAndValue {
} else {
if (X500Principal.CANONICAL.equals(attrFormat)) {
sb.append(value.makeCanonical());
+ } else if (X500Principal.RFC2253.equals(attrFormat)) {
+ sb.append(value.getRFC2253String());
} else {
sb.append(value.escapedString);
}
diff --git a/luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java b/luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java
index 160c62d..bdc3c84 100644
--- a/luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java
+++ b/luni/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java
@@ -30,27 +30,26 @@ import org.apache.harmony.security.utils.ObjectIdentifier;
* AttributeTypeAndValue comparator
*
*/
-public class AttributeTypeAndValueComparator implements Comparator, Serializable {
+public class AttributeTypeAndValueComparator implements Comparator<AttributeTypeAndValue>,
+ Serializable {
private static final long serialVersionUID = -1286471842007103132L;
/**
* compares two AttributeTypeAndValues
*
- * @param obj1
+ * @param atav1
* first AttributeTypeAndValue
- * @param obj2
+ * @param atav2
* second AttributeTypeAndValue
* @return -1 of first AttributeTypeAndValue "less" than second
* AttributeTypeAndValue 1 otherwise, 0 if they are equal
*/
- public int compare(Object obj1, Object obj2) {
- if (obj1 == obj2) {
+ public int compare(AttributeTypeAndValue atav1, AttributeTypeAndValue atav2) {
+ if (atav1 == atav2) {
return 0;
}
- AttributeTypeAndValue atav1 = (AttributeTypeAndValue) obj1;
- AttributeTypeAndValue atav2 = (AttributeTypeAndValue) obj2;
String kw1 = atav1.getType().getName();
String kw2 = atav2.getType().getName();
if (kw1 != null && kw2 == null) {
diff --git a/luni/src/main/java/org/apache/harmony/security/x501/AttributeValue.java b/luni/src/main/java/org/apache/harmony/security/x501/AttributeValue.java
index 63be3f1..b3eb200 100644
--- a/luni/src/main/java/org/apache/harmony/security/x501/AttributeValue.java
+++ b/luni/src/main/java/org/apache/harmony/security/x501/AttributeValue.java
@@ -37,8 +37,12 @@ public final class AttributeValue {
public boolean wasEncoded;
+ private boolean hasConsecutiveSpaces;
+
public final String escapedString;
+ private String rfc2253String;
+
private String hexString;
private final int tag;
@@ -197,8 +201,9 @@ public final class AttributeValue {
* Escapes:
* 1) chars ",", "+", """, "\", "<", ">", ";" (RFC 2253)
* 2) chars "#", "=" (required by RFC 1779)
- * 3) a space char at the beginning or end
- * 4) according to the requirement to be RFC 1779 compatible:
+ * 3) leading or trailing spaces
+ * 4) consecutive spaces (RFC 1779)
+ * 5) according to the requirement to be RFC 1779 compatible:
* '#' char is escaped in any position
*/
private String makeEscaped(String name) {
@@ -208,14 +213,35 @@ public final class AttributeValue {
}
StringBuilder buf = new StringBuilder(length * 2);
+ // Keeps track of whether we are escaping spaces.
+ boolean escapeSpaces = false;
+
for (int index = 0; index < length; index++) {
char ch = name.charAt(index);
switch (ch) {
case ' ':
- if (index == 0 || index == (length - 1)) {
- // escape first or last space
+ /*
+ * We should escape spaces in the following cases:
+ * 1) at the beginning
+ * 2) at the end
+ * 3) consecutive spaces
+ * Since multiple spaces at the beginning or end will be covered by
+ * 3, we don't need a special case to check for that. Note that RFC 2253
+ * doesn't escape consecutive spaces, so they are removed in
+ * getRFC2253String instead of making two different strings here.
+ */
+ if (index < (length - 1)) {
+ boolean nextIsSpace = name.charAt(index + 1) == ' ';
+ escapeSpaces = escapeSpaces || nextIsSpace || index == 0;
+ hasConsecutiveSpaces |= nextIsSpace;
+ } else {
+ escapeSpaces = true;
+ }
+
+ if (escapeSpaces) {
buf.append('\\');
}
+
buf.append(' ');
break;
@@ -241,6 +267,10 @@ public final class AttributeValue {
buf.append(ch);
break;
}
+
+ if (escapeSpaces && ch != ' ') {
+ escapeSpaces = false;
+ }
}
return buf.toString();
@@ -295,4 +325,50 @@ public final class AttributeValue {
return buf.toString();
}
+
+ /**
+ * Removes escape sequences used in RFC1779 escaping but not in RFC2253 and
+ * returns the RFC2253 string to the caller..
+ */
+ public String getRFC2253String() {
+ if (!hasConsecutiveSpaces) {
+ return escapedString;
+ }
+
+ if (rfc2253String == null) {
+ // Scan backwards first since runs of spaces at the end are escaped.
+ int lastIndex = escapedString.length() - 2;
+ for (int i = lastIndex; i > 0; i -= 2) {
+ if (escapedString.charAt(i) == '\\' && escapedString.charAt(i + 1) == ' ') {
+ lastIndex = i - 1;
+ }
+ }
+
+ boolean beginning = true;
+ StringBuilder sb = new StringBuilder(escapedString.length());
+ for (int i = 0; i < escapedString.length(); i++) {
+ char ch = escapedString.charAt(i);
+ if (ch != '\\') {
+ sb.append(ch);
+ beginning = false;
+ } else {
+ char nextCh = escapedString.charAt(i + 1);
+ if (nextCh == ' ') {
+ if (beginning || i > lastIndex) {
+ sb.append(ch);
+ }
+ sb.append(nextCh);
+ } else {
+ sb.append(ch);
+ sb.append(nextCh);
+ beginning = false;
+ }
+
+ i++;
+ }
+ }
+ rfc2253String = sb.toString();
+ }
+ return rfc2253String;
+ }
}
diff --git a/luni/src/main/java/org/apache/harmony/security/x509/Extension.java b/luni/src/main/java/org/apache/harmony/security/x509/Extension.java
index d9b02f9..d5d8015 100644
--- a/luni/src/main/java/org/apache/harmony/security/x509/Extension.java
+++ b/luni/src/main/java/org/apache/harmony/security/x509/Extension.java
@@ -23,6 +23,7 @@
package org.apache.harmony.security.x509;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.Arrays;
import org.apache.harmony.security.asn1.ASN1Boolean;
import org.apache.harmony.security.asn1.ASN1OctetString;
@@ -49,7 +50,7 @@ import org.apache.harmony.security.utils.Array;
* }
* </pre>
*/
-public final class Extension {
+public final class Extension implements java.security.cert.Extension {
// critical constants
public static final boolean CRITICAL = true;
public static final boolean NON_CRITICAL = false;
@@ -145,7 +146,8 @@ public final class Extension {
/**
* Returns the value of extnID field of the structure.
*/
- public String getExtnID() {
+ @Override
+ public String getId() {
if (extnID_str == null) {
extnID_str = ObjectIdentifier.toString(extnID);
}
@@ -155,14 +157,16 @@ public final class Extension {
/**
* Returns the value of critical field of the structure.
*/
- public boolean getCritical() {
+ @Override
+ public boolean isCritical() {
return critical;
}
/**
* Returns the value of extnValue field of the structure.
*/
- public byte[] getExtnValue() {
+ @Override
+ public byte[] getValue() {
return extnValue;
}
@@ -187,6 +191,11 @@ public final class Extension {
return encoding;
}
+ @Override
+ public void encode(OutputStream out) throws IOException {
+ out.write(getEncoded());
+ }
+
@Override public boolean equals(Object ext) {
if (!(ext instanceof Extension)) {
return false;
@@ -287,7 +296,7 @@ public final class Extension {
}
public void dumpValue(StringBuilder sb, String prefix) {
- sb.append("OID: ").append(getExtnID()).append(", Critical: ").append(critical).append('\n');
+ sb.append("OID: ").append(getId()).append(", Critical: ").append(critical).append('\n');
if (!valueDecoded) {
try {
decodeExtensionValue();
diff --git a/luni/src/main/java/org/apache/harmony/security/x509/Extensions.java b/luni/src/main/java/org/apache/harmony/security/x509/Extensions.java
index 92ff3a9..7a10ebc 100644
--- a/luni/src/main/java/org/apache/harmony/security/x509/Extensions.java
+++ b/luni/src/main/java/org/apache/harmony/security/x509/Extensions.java
@@ -136,8 +136,8 @@ public final class Extensions {
Set<String> localNoncritical = new HashSet<String>(size);
Boolean localHasUnsupported = Boolean.FALSE;
for (Extension extension : extensions) {
- String oid = extension.getExtnID();
- if (extension.getCritical()) {
+ String oid = extension.getId();
+ if (extension.isCritical()) {
if (!SUPPORTED_CRITICAL.contains(oid)) {
localHasUnsupported = Boolean.TRUE;
}
@@ -162,7 +162,7 @@ public final class Extensions {
if (localOidMap == null) {
localOidMap = new HashMap<String, Extension>();
for (Extension extension : extensions) {
- localOidMap.put(extension.getExtnID(), extension);
+ localOidMap.put(extension.getId(), extension);
}
this.oidMap = localOidMap;
}
@@ -311,7 +311,7 @@ public final class Extensions {
}
Collection<List<?>> collection = ((GeneralNames) GeneralNames.ASN1.decode(extension
- .getExtnValue())).getPairsList();
+ .getValue())).getPairsList();
/*
* If the extension had any invalid entries, we may have an empty
diff --git a/luni/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java b/luni/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java
index b7c1847..533c79c 100644
--- a/luni/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java
+++ b/luni/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java
@@ -44,6 +44,13 @@ public final class InvalidityDate extends ExtensionValue {
}
/**
+ * Constructs the object from a date instance.
+ */
+ public InvalidityDate(Date date) {
+ this.date = (Date) date.clone();
+ }
+
+ /**
* Returns the invalidity date.
*/
public Date getDate() {
diff --git a/luni/src/main/java/org/apache/harmony/security/x509/ReasonCode.java b/luni/src/main/java/org/apache/harmony/security/x509/ReasonCode.java
index 183ecde..2c9d6aa 100644
--- a/luni/src/main/java/org/apache/harmony/security/x509/ReasonCode.java
+++ b/luni/src/main/java/org/apache/harmony/security/x509/ReasonCode.java
@@ -18,6 +18,7 @@
package org.apache.harmony.security.x509;
import java.io.IOException;
+import java.security.cert.CRLReason;
import org.apache.harmony.security.asn1.ASN1Enumerated;
import org.apache.harmony.security.asn1.ASN1Type;
@@ -71,6 +72,14 @@ public final class ReasonCode extends ExtensionValue {
return encoding;
}
+ public CRLReason getReason() {
+ CRLReason[] values = CRLReason.values();
+ if (code < 0 || code > values.length) {
+ return null;
+ }
+ return values[code];
+ }
+
@Override public void dumpValue(StringBuilder sb, String prefix) {
sb.append(prefix).append("Reason Code: [ ");
switch (code) {
diff --git a/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java b/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java
index db6f4ef..fa6308e 100644
--- a/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java
+++ b/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java
@@ -48,7 +48,7 @@ class ExpatParser {
private boolean inStartElement = false;
private int attributeCount = -1;
- private int attributePointer = 0;
+ private long attributePointer = 0;
private final Locator locator = new ExpatLocator();
@@ -129,7 +129,7 @@ class ExpatParser {
* @param attributeCount number of attributes
*/
/*package*/ void startElement(String uri, String localName, String qName,
- int attributePointer, int attributeCount) throws SAXException {
+ long attributePointer, int attributeCount) throws SAXException {
ContentHandler contentHandler = xmlReader.contentHandler;
if (contentHandler == null) {
return;
@@ -772,7 +772,7 @@ class ExpatParser {
@Override
void startElement(String uri, String localName, String qName,
- int attributePointer, int attributeCount) throws SAXException {
+ long attributePointer, int attributeCount) throws SAXException {
/*
* Skip topmost element generated by our workaround in
* {@link #handleExternalEntity}.
diff --git a/luni/src/main/native/AsynchronousCloseMonitor.cpp b/luni/src/main/native/AsynchronousCloseMonitor.cpp
new file mode 100644
index 0000000..31cde00
--- /dev/null
+++ b/luni/src/main/native/AsynchronousCloseMonitor.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AsynchronousCloseMonitor"
+
+#include "AsynchronousCloseMonitor.h"
+#include "cutils/log.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+/**
+ * We use an intrusive doubly-linked list to keep track of blocked threads.
+ * This gives us O(1) insertion and removal, and means we don't need to do any allocation.
+ * (The objects themselves are stack-allocated.)
+ * Waking potentially-blocked threads when a file descriptor is closed is O(n) in the total number
+ * of blocked threads (not the number of threads actually blocked on the file descriptor in
+ * question). For now at least, this seems like a good compromise for Android.
+ */
+static pthread_mutex_t blockedThreadListMutex = PTHREAD_MUTEX_INITIALIZER;
+static AsynchronousCloseMonitor* blockedThreadList = NULL;
+
+/**
+ * The specific signal chosen here is arbitrary, but bionic needs to know so that SIGRTMIN
+ * starts at a higher value.
+ */
+#if defined(__APPLE__)
+static const int BLOCKED_THREAD_SIGNAL = SIGUSR2;
+#else
+static const int BLOCKED_THREAD_SIGNAL = __SIGRTMIN + 2;
+#endif
+
+static void blockedThreadSignalHandler(int /*signal*/) {
+ // Do nothing. We only sent this signal for its side-effect of interrupting syscalls.
+}
+
+void AsynchronousCloseMonitor::init() {
+ // Ensure that the signal we send interrupts system calls but doesn't kill threads.
+ // Using sigaction(2) lets us ensure that the SA_RESTART flag is not set.
+ // (The whole reason we're sending this signal is to unblock system calls!)
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = blockedThreadSignalHandler;
+ sa.sa_flags = 0;
+ int rc = sigaction(BLOCKED_THREAD_SIGNAL, &sa, NULL);
+ if (rc == -1) {
+ ALOGE("setting blocked thread signal handler failed: %s", strerror(errno));
+ }
+}
+
+void AsynchronousCloseMonitor::signalBlockedThreads(int fd) {
+ ScopedPthreadMutexLock lock(&blockedThreadListMutex);
+ for (AsynchronousCloseMonitor* it = blockedThreadList; it != NULL; it = it->mNext) {
+ if (it->mFd == fd) {
+ it->mSignaled = true;
+ pthread_kill(it->mThread, BLOCKED_THREAD_SIGNAL);
+ // Keep going, because there may be more than one thread...
+ }
+ }
+}
+
+bool AsynchronousCloseMonitor::wasSignaled() const {
+ return mSignaled;
+}
+
+AsynchronousCloseMonitor::AsynchronousCloseMonitor(int fd) {
+ ScopedPthreadMutexLock lock(&blockedThreadListMutex);
+ // Who are we, and what are we waiting for?
+ mThread = pthread_self();
+ mFd = fd;
+ mSignaled = false;
+ // Insert ourselves at the head of the intrusive doubly-linked list...
+ mPrev = NULL;
+ mNext = blockedThreadList;
+ if (mNext != NULL) {
+ mNext->mPrev = this;
+ }
+ blockedThreadList = this;
+}
+
+AsynchronousCloseMonitor::~AsynchronousCloseMonitor() {
+ ScopedPthreadMutexLock lock(&blockedThreadListMutex);
+ // Unlink ourselves from the intrusive doubly-linked list...
+ if (mNext != NULL) {
+ mNext->mPrev = mPrev;
+ }
+ if (mPrev == NULL) {
+ blockedThreadList = mNext;
+ } else {
+ mPrev->mNext = mNext;
+ }
+}
diff --git a/luni/src/main/native/AsynchronousCloseMonitor.h b/luni/src/main/native/AsynchronousCloseMonitor.h
new file mode 100644
index 0000000..eefbbdf
--- /dev/null
+++ b/luni/src/main/native/AsynchronousCloseMonitor.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ASYNCHRONOUS_CLOSE_MONITOR_H_included
+#define ASYNCHRONOUS_CLOSE_MONITOR_H_included
+
+#include "ScopedPthreadMutexLock.h"
+#include <pthread.h>
+
+/**
+ * AsynchronousCloseMonitor helps implement Java's asynchronous close semantics.
+ *
+ * AsynchronousCloseMonitor::init must be called before anything else.
+ *
+ * Every blocking I/O operation must be surrounded by an AsynchronousCloseMonitor
+ * instance. For example:
+ *
+ * {
+ * AsynchronousCloseMonitor monitor(fd);
+ * byteCount = ::read(fd, buf, sizeof(buf));
+ * }
+ *
+ * To interrupt all threads currently blocked on file descriptor 'fd', call signalBlockedThreads:
+ *
+ * AsynchronousCloseMonitor::signalBlockedThreads(fd);
+ *
+ * To test to see if the interruption was due to the signalBlockedThreads call:
+ *
+ * monitor.wasSignaled();
+ */
+class AsynchronousCloseMonitor {
+public:
+ AsynchronousCloseMonitor(int fd);
+ ~AsynchronousCloseMonitor();
+ bool wasSignaled() const;
+
+ static void init();
+
+ static void signalBlockedThreads(int fd);
+
+private:
+ AsynchronousCloseMonitor* mPrev;
+ AsynchronousCloseMonitor* mNext;
+ pthread_t mThread;
+ int mFd;
+ bool mSignaled;
+
+ // Disallow copy and assignment.
+ AsynchronousCloseMonitor(const AsynchronousCloseMonitor&);
+ void operator=(const AsynchronousCloseMonitor&);
+};
+
+#endif // ASYNCHRONOUS_CLOSE_MONITOR_H_included
diff --git a/luni/src/main/native/AsynchronousSocketCloseMonitor.cpp b/luni/src/main/native/AsynchronousSocketCloseMonitor.cpp
deleted file mode 100644
index 9617e9d..0000000
--- a/luni/src/main/native/AsynchronousSocketCloseMonitor.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AsynchronousSocketCloseMonitor"
-
-#include "AsynchronousSocketCloseMonitor.h"
-#include "cutils/log.h"
-
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-
-/**
- * We use an intrusive doubly-linked list to keep track of blocked threads.
- * This gives us O(1) insertion and removal, and means we don't need to do any allocation.
- * (The objects themselves are stack-allocated.)
- * Waking potentially-blocked threads when a socket is closed is O(n) in the total number of
- * blocked threads (not the number of threads actually blocked on the socket in question).
- * For now at least, this seems like a good compromise for Android.
- */
-static pthread_mutex_t blockedThreadListMutex = PTHREAD_MUTEX_INITIALIZER;
-static AsynchronousSocketCloseMonitor* blockedThreadList = NULL;
-
-/**
- * The specific signal chosen here is arbitrary.
- */
-#if defined(__APPLE__)
-static const int BLOCKED_THREAD_SIGNAL = SIGUSR2;
-#else
-static const int BLOCKED_THREAD_SIGNAL = SIGRTMIN + 2;
-#endif
-
-static void blockedThreadSignalHandler(int /*signal*/) {
- // Do nothing. We only sent this signal for its side-effect of interrupting syscalls.
-}
-
-void AsynchronousSocketCloseMonitor::init() {
- // Ensure that the signal we send interrupts system calls but doesn't kill threads.
- // Using sigaction(2) lets us ensure that the SA_RESTART flag is not set.
- // (The whole reason we're sending this signal is to unblock system calls!)
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = blockedThreadSignalHandler;
- sa.sa_flags = 0;
- int rc = sigaction(BLOCKED_THREAD_SIGNAL, &sa, NULL);
- if (rc == -1) {
- ALOGE("setting blocked thread signal handler failed: %s", strerror(errno));
- }
-}
-
-void AsynchronousSocketCloseMonitor::signalBlockedThreads(int fd) {
- ScopedPthreadMutexLock lock(&blockedThreadListMutex);
- for (AsynchronousSocketCloseMonitor* it = blockedThreadList; it != NULL; it = it->mNext) {
- if (it->mFd == fd) {
- pthread_kill(it->mThread, BLOCKED_THREAD_SIGNAL);
- // Keep going, because there may be more than one thread...
- }
- }
-}
-
-AsynchronousSocketCloseMonitor::AsynchronousSocketCloseMonitor(int fd) {
- ScopedPthreadMutexLock lock(&blockedThreadListMutex);
- // Who are we, and what are we waiting for?
- mThread = pthread_self();
- mFd = fd;
- // Insert ourselves at the head of the intrusive doubly-linked list...
- mPrev = NULL;
- mNext = blockedThreadList;
- if (mNext != NULL) {
- mNext->mPrev = this;
- }
- blockedThreadList = this;
-}
-
-AsynchronousSocketCloseMonitor::~AsynchronousSocketCloseMonitor() {
- ScopedPthreadMutexLock lock(&blockedThreadListMutex);
- // Unlink ourselves from the intrusive doubly-linked list...
- if (mNext != NULL) {
- mNext->mPrev = mPrev;
- }
- if (mPrev == NULL) {
- blockedThreadList = mNext;
- } else {
- mPrev->mNext = mNext;
- }
-}
diff --git a/luni/src/main/native/AsynchronousSocketCloseMonitor.h b/luni/src/main/native/AsynchronousSocketCloseMonitor.h
deleted file mode 100644
index 3370e22..0000000
--- a/luni/src/main/native/AsynchronousSocketCloseMonitor.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ASYNCHRONOUS_SOCKET_CLOSE_MONITOR_H_included
-#define ASYNCHRONOUS_SOCKET_CLOSE_MONITOR_H_included
-
-#include "ScopedPthreadMutexLock.h"
-#include <pthread.h>
-
-/**
- * AsynchronousSocketCloseMonitor helps implement Java's asynchronous Socket.close semantics.
- *
- * AsynchronousSocketCloseMonitor::init must be called before anything else.
- *
- * Every blocking network I/O operation must be surrounded by an AsynchronousSocketCloseMonitor
- * instance. For example:
- *
- * {
- * AsynchronousSocketCloseMonitor monitor(fd);
- * byteCount = ::read(fd, buf, sizeof(buf));
- * }
- *
- * To interrupt all threads currently blocked on file descriptor 'fd', call signalBlockedThreads:
- *
- * AsynchronousSocketCloseMonitor::signalBlockedThreads(fd);
- */
-class AsynchronousSocketCloseMonitor {
-public:
- AsynchronousSocketCloseMonitor(int fd);
- ~AsynchronousSocketCloseMonitor();
-
- static void init();
-
- static void signalBlockedThreads(int fd);
-
-private:
- AsynchronousSocketCloseMonitor* mPrev;
- AsynchronousSocketCloseMonitor* mNext;
- pthread_t mThread;
- int mFd;
-
- // Disallow copy and assignment.
- AsynchronousSocketCloseMonitor(const AsynchronousSocketCloseMonitor&);
- void operator=(const AsynchronousSocketCloseMonitor&);
-};
-
-#endif // ASYNCHRONOUS_SOCKET_CLOSE_MONITOR_H_included
diff --git a/luni/src/main/native/IcuUtilities.cpp b/luni/src/main/native/IcuUtilities.cpp
index c1bdd0f..7ce2168 100644
--- a/luni/src/main/native/IcuUtilities.cpp
+++ b/luni/src/main/native/IcuUtilities.cpp
@@ -28,10 +28,6 @@
#include "unicode/uloc.h"
#include "unicode/ustring.h"
-Locale getLocale(JNIEnv* env, jstring localeName) {
- return Locale::createFromName(ScopedUtfChars(env, localeName).c_str());
-}
-
jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, StringEnumeration* se) {
if (maybeThrowIcuException(env, provider, status)) {
return NULL;
@@ -65,6 +61,8 @@ bool maybeThrowIcuException(JNIEnv* env, const char* function, UErrorCode error)
exceptionClass = "java/lang/ArrayIndexOutOfBoundsException";
} else if (error == U_UNSUPPORTED_ERROR) {
exceptionClass = "java/lang/UnsupportedOperationException";
+ } else if (error == U_FORMAT_INEXACT_ERROR) {
+ exceptionClass = "java/lang/ArithmeticException";
}
jniThrowExceptionFmt(env, exceptionClass, "%s failed: %s", function, u_errorName(error));
return true;
diff --git a/luni/src/main/native/IcuUtilities.h b/luni/src/main/native/IcuUtilities.h
index cff1e0d..737379e 100644
--- a/luni/src/main/native/IcuUtilities.h
+++ b/luni/src/main/native/IcuUtilities.h
@@ -17,14 +17,13 @@
#ifndef ICU_UTILITIES_H_included
#define ICU_UTILITIES_H_included
+#undef U_HAVE_STD_STRING
#define U_HAVE_STD_STRING 1 // For UnicodeString::toUTF8String(std::string&).
#include "jni.h"
#include "ustrenum.h" // For UStringEnumeration.
#include "unicode/utypes.h" // For UErrorCode.
-#include "unicode/locid.h" // For Locale.
-extern Locale getLocale(JNIEnv* env, jstring localeName);
extern jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, StringEnumeration*);
bool maybeThrowIcuException(JNIEnv* env, const char* function, UErrorCode error);
diff --git a/luni/src/main/native/NetworkUtilities.h b/luni/src/main/native/NetworkUtilities.h
index 28e9fa5..6b720d4 100644
--- a/luni/src/main/native/NetworkUtilities.h
+++ b/luni/src/main/native/NetworkUtilities.h
@@ -35,7 +35,7 @@ bool inetAddressToSockaddr(JNIEnv* env, jobject inetAddress, int port,
// An Inet4Address will be converted to a sockaddr_in. This is probably only useful for
// getnameinfo(2), where we'll be presenting the result to the user and the user may actually
// care whether the original address was pure IPv4 or an IPv4-mapped IPv6 address, and
-// for the MCAST_JOIN_GROUP socket option.
+// for the MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP, and other multicast socket options.
bool inetAddressToSockaddrVerbatim(JNIEnv* env, jobject inetAddress, int port,
sockaddr_storage& ss, socklen_t& sa_len);
diff --git a/luni/src/main/native/Portability.h b/luni/src/main/native/Portability.h
index 60b7062..1520311 100644
--- a/luni/src/main/native/Portability.h
+++ b/luni/src/main/native/Portability.h
@@ -64,9 +64,8 @@ static inline int mincore(void* addr, size_t length, unsigned char* vec) {
// For statfs(3).
#include <sys/param.h>
#include <sys/mount.h>
-#define f_frsize f_bsize // TODO: close enough?
-#else
+#else // defined(__APPLE__)
// Bionic or glibc.
@@ -74,6 +73,15 @@ static inline int mincore(void* addr, size_t length, unsigned char* vec) {
#include <sys/sendfile.h>
#include <sys/statvfs.h>
-#endif
+#endif // defined(__APPLE__)
+
+#if !defined(__BIONIC__)
+#include <netdb.h>
+#include "../../bionic/libc/dns/include/resolv_netid.h"
+inline int android_getaddrinfofornet(const char *hostname, const char *servname,
+ const struct addrinfo *hints, unsigned /*netid*/, unsigned /*mark*/, struct addrinfo **res) {
+ return getaddrinfo(hostname, servname, hints, res);
+}
+#endif // !defined(__BIONIC__)
#endif // PORTABILITY_H_included
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 6b24a36..6a2c939 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -23,7 +23,7 @@
#include <stdlib.h>
// DalvikVM calls this on startup, so we can statically register all our native methods.
-int JNI_OnLoad(JavaVM* vm, void*) {
+jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
ALOGE("JavaVM::GetEnv() failed");
@@ -33,8 +33,9 @@ int JNI_OnLoad(JavaVM* vm, void*) {
ScopedLocalFrame localFrame(env);
#define REGISTER(FN) extern void FN(JNIEnv*); FN(env)
- REGISTER(register_java_io_Console);
+ REGISTER(register_android_system_OsConstants);
REGISTER(register_java_io_File);
+ REGISTER(register_java_io_FileDescriptor);
REGISTER(register_java_io_ObjectStreamClass);
REGISTER(register_java_lang_Character);
REGISTER(register_java_lang_Double);
@@ -49,6 +50,7 @@ int JNI_OnLoad(JavaVM* vm, void*) {
REGISTER(register_java_nio_ByteOrder);
REGISTER(register_java_nio_charset_Charsets);
REGISTER(register_java_text_Bidi);
+ REGISTER(register_java_util_jar_StrictJarFile);
REGISTER(register_java_util_regex_Matcher);
REGISTER(register_java_util_regex_Pattern);
REGISTER(register_java_util_zip_Adler32);
@@ -69,12 +71,11 @@ int JNI_OnLoad(JavaVM* vm, void*) {
REGISTER(register_libcore_icu_Transliterator);
REGISTER(register_libcore_io_AsynchronousCloseMonitor);
REGISTER(register_libcore_io_Memory);
- REGISTER(register_libcore_io_OsConstants);
REGISTER(register_libcore_io_Posix);
- REGISTER(register_libcore_net_RawSocket);
REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget);
REGISTER(register_org_apache_harmony_xml_ExpatParser);
REGISTER(register_sun_misc_Unsafe);
#undef REGISTER
+
return JNI_VERSION_1_6;
}
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
new file mode 100644
index 0000000..92212b9
--- /dev/null
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OsConstants"
+
+#include "JNIHelp.h"
+#include "JniConstants.h"
+#include "Portability.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#ifndef __APPLE__
+#include <sys/prctl.h>
+#endif
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+// After the others because these are not necessarily self-contained in glibc.
+#ifndef __APPLE__
+#include <linux/if_addr.h>
+#include <linux/rtnetlink.h>
+#endif
+
+#include <net/if.h> // After <sys/socket.h> to work around a Mac header file bug.
+
+#if defined(__BIONIC__)
+#include <linux/capability.h>
+#endif
+
+static void initConstant(JNIEnv* env, jclass c, const char* fieldName, int value) {
+ jfieldID field = env->GetStaticFieldID(c, fieldName, "I");
+ env->SetStaticIntField(c, field, value);
+}
+
+static void OsConstants_initConstants(JNIEnv* env, jclass c) {
+ initConstant(env, c, "AF_INET", AF_INET);
+ initConstant(env, c, "AF_INET6", AF_INET6);
+ initConstant(env, c, "AF_UNIX", AF_UNIX);
+ initConstant(env, c, "AF_UNSPEC", AF_UNSPEC);
+ initConstant(env, c, "AI_ADDRCONFIG", AI_ADDRCONFIG);
+ initConstant(env, c, "AI_ALL", AI_ALL);
+ initConstant(env, c, "AI_CANONNAME", AI_CANONNAME);
+ initConstant(env, c, "AI_NUMERICHOST", AI_NUMERICHOST);
+#if defined(AI_NUMERICSERV)
+ initConstant(env, c, "AI_NUMERICSERV", AI_NUMERICSERV);
+#endif
+ initConstant(env, c, "AI_PASSIVE", AI_PASSIVE);
+ initConstant(env, c, "AI_V4MAPPED", AI_V4MAPPED);
+#if defined(CAP_LAST_CAP)
+ initConstant(env, c, "CAP_AUDIT_CONTROL", CAP_AUDIT_CONTROL);
+ initConstant(env, c, "CAP_AUDIT_WRITE", CAP_AUDIT_WRITE);
+ initConstant(env, c, "CAP_BLOCK_SUSPEND", CAP_BLOCK_SUSPEND);
+ initConstant(env, c, "CAP_CHOWN", CAP_CHOWN);
+ initConstant(env, c, "CAP_DAC_OVERRIDE", CAP_DAC_OVERRIDE);
+ initConstant(env, c, "CAP_DAC_READ_SEARCH", CAP_DAC_READ_SEARCH);
+ initConstant(env, c, "CAP_FOWNER", CAP_FOWNER);
+ initConstant(env, c, "CAP_FSETID", CAP_FSETID);
+ initConstant(env, c, "CAP_IPC_LOCK", CAP_IPC_LOCK);
+ initConstant(env, c, "CAP_IPC_OWNER", CAP_IPC_OWNER);
+ initConstant(env, c, "CAP_KILL", CAP_KILL);
+ initConstant(env, c, "CAP_LAST_CAP", CAP_LAST_CAP);
+ initConstant(env, c, "CAP_LEASE", CAP_LEASE);
+ initConstant(env, c, "CAP_LINUX_IMMUTABLE", CAP_LINUX_IMMUTABLE);
+ initConstant(env, c, "CAP_MAC_ADMIN", CAP_MAC_ADMIN);
+ initConstant(env, c, "CAP_MAC_OVERRIDE", CAP_MAC_OVERRIDE);
+ initConstant(env, c, "CAP_MKNOD", CAP_MKNOD);
+ initConstant(env, c, "CAP_NET_ADMIN", CAP_NET_ADMIN);
+ initConstant(env, c, "CAP_NET_BIND_SERVICE", CAP_NET_BIND_SERVICE);
+ initConstant(env, c, "CAP_NET_BROADCAST", CAP_NET_BROADCAST);
+ initConstant(env, c, "CAP_NET_RAW", CAP_NET_RAW);
+ initConstant(env, c, "CAP_SETFCAP", CAP_SETFCAP);
+ initConstant(env, c, "CAP_SETGID", CAP_SETGID);
+ initConstant(env, c, "CAP_SETPCAP", CAP_SETPCAP);
+ initConstant(env, c, "CAP_SETUID", CAP_SETUID);
+ initConstant(env, c, "CAP_SYS_ADMIN", CAP_SYS_ADMIN);
+ initConstant(env, c, "CAP_SYS_BOOT", CAP_SYS_BOOT);
+ initConstant(env, c, "CAP_SYS_CHROOT", CAP_SYS_CHROOT);
+ initConstant(env, c, "CAP_SYSLOG", CAP_SYSLOG);
+ initConstant(env, c, "CAP_SYS_MODULE", CAP_SYS_MODULE);
+ initConstant(env, c, "CAP_SYS_NICE", CAP_SYS_NICE);
+ initConstant(env, c, "CAP_SYS_PACCT", CAP_SYS_PACCT);
+ initConstant(env, c, "CAP_SYS_PTRACE", CAP_SYS_PTRACE);
+ initConstant(env, c, "CAP_SYS_RAWIO", CAP_SYS_RAWIO);
+ initConstant(env, c, "CAP_SYS_RESOURCE", CAP_SYS_RESOURCE);
+ initConstant(env, c, "CAP_SYS_TIME", CAP_SYS_TIME);
+ initConstant(env, c, "CAP_SYS_TTY_CONFIG", CAP_SYS_TTY_CONFIG);
+ initConstant(env, c, "CAP_WAKE_ALARM", CAP_WAKE_ALARM);
+#endif
+ initConstant(env, c, "E2BIG", E2BIG);
+ initConstant(env, c, "EACCES", EACCES);
+ initConstant(env, c, "EADDRINUSE", EADDRINUSE);
+ initConstant(env, c, "EADDRNOTAVAIL", EADDRNOTAVAIL);
+ initConstant(env, c, "EAFNOSUPPORT", EAFNOSUPPORT);
+ initConstant(env, c, "EAGAIN", EAGAIN);
+ initConstant(env, c, "EAI_AGAIN", EAI_AGAIN);
+ initConstant(env, c, "EAI_BADFLAGS", EAI_BADFLAGS);
+ initConstant(env, c, "EAI_FAIL", EAI_FAIL);
+ initConstant(env, c, "EAI_FAMILY", EAI_FAMILY);
+ initConstant(env, c, "EAI_MEMORY", EAI_MEMORY);
+ initConstant(env, c, "EAI_NODATA", EAI_NODATA);
+ initConstant(env, c, "EAI_NONAME", EAI_NONAME);
+#if defined(EAI_OVERFLOW)
+ initConstant(env, c, "EAI_OVERFLOW", EAI_OVERFLOW);
+#endif
+ initConstant(env, c, "EAI_SERVICE", EAI_SERVICE);
+ initConstant(env, c, "EAI_SOCKTYPE", EAI_SOCKTYPE);
+ initConstant(env, c, "EAI_SYSTEM", EAI_SYSTEM);
+ initConstant(env, c, "EALREADY", EALREADY);
+ initConstant(env, c, "EBADF", EBADF);
+ initConstant(env, c, "EBADMSG", EBADMSG);
+ initConstant(env, c, "EBUSY", EBUSY);
+ initConstant(env, c, "ECANCELED", ECANCELED);
+ initConstant(env, c, "ECHILD", ECHILD);
+ initConstant(env, c, "ECONNABORTED", ECONNABORTED);
+ initConstant(env, c, "ECONNREFUSED", ECONNREFUSED);
+ initConstant(env, c, "ECONNRESET", ECONNRESET);
+ initConstant(env, c, "EDEADLK", EDEADLK);
+ initConstant(env, c, "EDESTADDRREQ", EDESTADDRREQ);
+ initConstant(env, c, "EDOM", EDOM);
+ initConstant(env, c, "EDQUOT", EDQUOT);
+ initConstant(env, c, "EEXIST", EEXIST);
+ initConstant(env, c, "EFAULT", EFAULT);
+ initConstant(env, c, "EFBIG", EFBIG);
+ initConstant(env, c, "EHOSTUNREACH", EHOSTUNREACH);
+ initConstant(env, c, "EIDRM", EIDRM);
+ initConstant(env, c, "EILSEQ", EILSEQ);
+ initConstant(env, c, "EINPROGRESS", EINPROGRESS);
+ initConstant(env, c, "EINTR", EINTR);
+ initConstant(env, c, "EINVAL", EINVAL);
+ initConstant(env, c, "EIO", EIO);
+ initConstant(env, c, "EISCONN", EISCONN);
+ initConstant(env, c, "EISDIR", EISDIR);
+ initConstant(env, c, "ELOOP", ELOOP);
+ initConstant(env, c, "EMFILE", EMFILE);
+ initConstant(env, c, "EMLINK", EMLINK);
+ initConstant(env, c, "EMSGSIZE", EMSGSIZE);
+ initConstant(env, c, "EMULTIHOP", EMULTIHOP);
+ initConstant(env, c, "ENAMETOOLONG", ENAMETOOLONG);
+ initConstant(env, c, "ENETDOWN", ENETDOWN);
+ initConstant(env, c, "ENETRESET", ENETRESET);
+ initConstant(env, c, "ENETUNREACH", ENETUNREACH);
+ initConstant(env, c, "ENFILE", ENFILE);
+ initConstant(env, c, "ENOBUFS", ENOBUFS);
+ initConstant(env, c, "ENODATA", ENODATA);
+ initConstant(env, c, "ENODEV", ENODEV);
+ initConstant(env, c, "ENOENT", ENOENT);
+ initConstant(env, c, "ENOEXEC", ENOEXEC);
+ initConstant(env, c, "ENOLCK", ENOLCK);
+ initConstant(env, c, "ENOLINK", ENOLINK);
+ initConstant(env, c, "ENOMEM", ENOMEM);
+ initConstant(env, c, "ENOMSG", ENOMSG);
+ initConstant(env, c, "ENOPROTOOPT", ENOPROTOOPT);
+ initConstant(env, c, "ENOSPC", ENOSPC);
+ initConstant(env, c, "ENOSR", ENOSR);
+ initConstant(env, c, "ENOSTR", ENOSTR);
+ initConstant(env, c, "ENOSYS", ENOSYS);
+ initConstant(env, c, "ENOTCONN", ENOTCONN);
+ initConstant(env, c, "ENOTDIR", ENOTDIR);
+ initConstant(env, c, "ENOTEMPTY", ENOTEMPTY);
+ initConstant(env, c, "ENOTSOCK", ENOTSOCK);
+ initConstant(env, c, "ENOTSUP", ENOTSUP);
+ initConstant(env, c, "ENOTTY", ENOTTY);
+ initConstant(env, c, "ENXIO", ENXIO);
+ initConstant(env, c, "EOPNOTSUPP", EOPNOTSUPP);
+ initConstant(env, c, "EOVERFLOW", EOVERFLOW);
+ initConstant(env, c, "EPERM", EPERM);
+ initConstant(env, c, "EPIPE", EPIPE);
+ initConstant(env, c, "EPROTO", EPROTO);
+ initConstant(env, c, "EPROTONOSUPPORT", EPROTONOSUPPORT);
+ initConstant(env, c, "EPROTOTYPE", EPROTOTYPE);
+ initConstant(env, c, "ERANGE", ERANGE);
+ initConstant(env, c, "EROFS", EROFS);
+ initConstant(env, c, "ESPIPE", ESPIPE);
+ initConstant(env, c, "ESRCH", ESRCH);
+ initConstant(env, c, "ESTALE", ESTALE);
+ initConstant(env, c, "ETIME", ETIME);
+ initConstant(env, c, "ETIMEDOUT", ETIMEDOUT);
+ initConstant(env, c, "ETXTBSY", ETXTBSY);
+#if EWOULDBLOCK != EAGAIN
+#error EWOULDBLOCK != EAGAIN
+#endif
+ initConstant(env, c, "EXDEV", EXDEV);
+ initConstant(env, c, "EXIT_FAILURE", EXIT_FAILURE);
+ initConstant(env, c, "EXIT_SUCCESS", EXIT_SUCCESS);
+ initConstant(env, c, "FD_CLOEXEC", FD_CLOEXEC);
+ initConstant(env, c, "FIONREAD", FIONREAD);
+ initConstant(env, c, "F_DUPFD", F_DUPFD);
+ initConstant(env, c, "F_GETFD", F_GETFD);
+ initConstant(env, c, "F_GETFL", F_GETFL);
+ initConstant(env, c, "F_GETLK", F_GETLK);
+#if defined(F_GETLK64)
+ initConstant(env, c, "F_GETLK64", F_GETLK64);
+#endif
+ initConstant(env, c, "F_GETOWN", F_GETOWN);
+ initConstant(env, c, "F_OK", F_OK);
+ initConstant(env, c, "F_RDLCK", F_RDLCK);
+ initConstant(env, c, "F_SETFD", F_SETFD);
+ initConstant(env, c, "F_SETFL", F_SETFL);
+ initConstant(env, c, "F_SETLK", F_SETLK);
+#if defined(F_SETLK64)
+ initConstant(env, c, "F_SETLK64", F_SETLK64);
+#endif
+ initConstant(env, c, "F_SETLKW", F_SETLKW);
+#if defined(F_SETLKW64)
+ initConstant(env, c, "F_SETLKW64", F_SETLKW64);
+#endif
+ initConstant(env, c, "F_SETOWN", F_SETOWN);
+ initConstant(env, c, "F_UNLCK", F_UNLCK);
+ initConstant(env, c, "F_WRLCK", F_WRLCK);
+#if defined(IFA_F_DADFAILED)
+ initConstant(env, c, "IFA_F_DADFAILED", IFA_F_DADFAILED);
+#endif
+#if defined(IFA_F_DEPRECATED)
+ initConstant(env, c, "IFA_F_DEPRECATED", IFA_F_DEPRECATED);
+#endif
+#if defined(IFA_F_HOMEADDRESS)
+ initConstant(env, c, "IFA_F_HOMEADDRESS", IFA_F_HOMEADDRESS);
+#endif
+#if defined(IFA_F_NODAD)
+ initConstant(env, c, "IFA_F_NODAD", IFA_F_NODAD);
+#endif
+#if defined(IFA_F_OPTIMISTIC)
+ initConstant(env, c, "IFA_F_OPTIMISTIC", IFA_F_OPTIMISTIC);
+#endif
+#if defined(IFA_F_PERMANENT)
+ initConstant(env, c, "IFA_F_PERMANENT", IFA_F_PERMANENT);
+#endif
+#if defined(IFA_F_SECONDARY)
+ initConstant(env, c, "IFA_F_SECONDARY", IFA_F_SECONDARY);
+#endif
+#if defined(IFA_F_TEMPORARY)
+ initConstant(env, c, "IFA_F_TEMPORARY", IFA_F_TEMPORARY);
+#endif
+#if defined(IFA_F_TENTATIVE)
+ initConstant(env, c, "IFA_F_TENTATIVE", IFA_F_TENTATIVE);
+#endif
+ initConstant(env, c, "IFF_ALLMULTI", IFF_ALLMULTI);
+#if defined(IFF_AUTOMEDIA)
+ initConstant(env, c, "IFF_AUTOMEDIA", IFF_AUTOMEDIA);
+#endif
+ initConstant(env, c, "IFF_BROADCAST", IFF_BROADCAST);
+ initConstant(env, c, "IFF_DEBUG", IFF_DEBUG);
+#if defined(IFF_DYNAMIC)
+ initConstant(env, c, "IFF_DYNAMIC", IFF_DYNAMIC);
+#endif
+ initConstant(env, c, "IFF_LOOPBACK", IFF_LOOPBACK);
+#if defined(IFF_MASTER)
+ initConstant(env, c, "IFF_MASTER", IFF_MASTER);
+#endif
+ initConstant(env, c, "IFF_MULTICAST", IFF_MULTICAST);
+ initConstant(env, c, "IFF_NOARP", IFF_NOARP);
+ initConstant(env, c, "IFF_NOTRAILERS", IFF_NOTRAILERS);
+ initConstant(env, c, "IFF_POINTOPOINT", IFF_POINTOPOINT);
+#if defined(IFF_PORTSEL)
+ initConstant(env, c, "IFF_PORTSEL", IFF_PORTSEL);
+#endif
+ initConstant(env, c, "IFF_PROMISC", IFF_PROMISC);
+ initConstant(env, c, "IFF_RUNNING", IFF_RUNNING);
+#if defined(IFF_SLAVE)
+ initConstant(env, c, "IFF_SLAVE", IFF_SLAVE);
+#endif
+ initConstant(env, c, "IFF_UP", IFF_UP);
+ initConstant(env, c, "IPPROTO_ICMP", IPPROTO_ICMP);
+ initConstant(env, c, "IPPROTO_ICMPV6", IPPROTO_ICMPV6);
+ initConstant(env, c, "IPPROTO_IP", IPPROTO_IP);
+ initConstant(env, c, "IPPROTO_IPV6", IPPROTO_IPV6);
+ initConstant(env, c, "IPPROTO_RAW", IPPROTO_RAW);
+ initConstant(env, c, "IPPROTO_TCP", IPPROTO_TCP);
+ initConstant(env, c, "IPPROTO_UDP", IPPROTO_UDP);
+ initConstant(env, c, "IPV6_CHECKSUM", IPV6_CHECKSUM);
+ initConstant(env, c, "IPV6_MULTICAST_HOPS", IPV6_MULTICAST_HOPS);
+ initConstant(env, c, "IPV6_MULTICAST_IF", IPV6_MULTICAST_IF);
+ initConstant(env, c, "IPV6_MULTICAST_LOOP", IPV6_MULTICAST_LOOP);
+#if defined(IPV6_RECVDSTOPTS)
+ initConstant(env, c, "IPV6_RECVDSTOPTS", IPV6_RECVDSTOPTS);
+#endif
+#if defined(IPV6_RECVHOPLIMIT)
+ initConstant(env, c, "IPV6_RECVHOPLIMIT", IPV6_RECVHOPLIMIT);
+#endif
+#if defined(IPV6_RECVHOPOPTS)
+ initConstant(env, c, "IPV6_RECVHOPOPTS", IPV6_RECVHOPOPTS);
+#endif
+#if defined(IPV6_RECVPKTINFO)
+ initConstant(env, c, "IPV6_RECVPKTINFO", IPV6_RECVPKTINFO);
+#endif
+#if defined(IPV6_RECVRTHDR)
+ initConstant(env, c, "IPV6_RECVRTHDR", IPV6_RECVRTHDR);
+#endif
+#if defined(IPV6_RECVTCLASS)
+ initConstant(env, c, "IPV6_RECVTCLASS", IPV6_RECVTCLASS);
+#endif
+#if defined(IPV6_TCLASS)
+ initConstant(env, c, "IPV6_TCLASS", IPV6_TCLASS);
+#endif
+ initConstant(env, c, "IPV6_UNICAST_HOPS", IPV6_UNICAST_HOPS);
+ initConstant(env, c, "IPV6_V6ONLY", IPV6_V6ONLY);
+ initConstant(env, c, "IP_MULTICAST_IF", IP_MULTICAST_IF);
+ initConstant(env, c, "IP_MULTICAST_LOOP", IP_MULTICAST_LOOP);
+ initConstant(env, c, "IP_MULTICAST_TTL", IP_MULTICAST_TTL);
+ initConstant(env, c, "IP_TOS", IP_TOS);
+ initConstant(env, c, "IP_TTL", IP_TTL);
+ initConstant(env, c, "MAP_FIXED", MAP_FIXED);
+ initConstant(env, c, "MAP_PRIVATE", MAP_PRIVATE);
+ initConstant(env, c, "MAP_SHARED", MAP_SHARED);
+#if defined(MCAST_JOIN_GROUP)
+ initConstant(env, c, "MCAST_JOIN_GROUP", MCAST_JOIN_GROUP);
+#endif
+#if defined(MCAST_LEAVE_GROUP)
+ initConstant(env, c, "MCAST_LEAVE_GROUP", MCAST_LEAVE_GROUP);
+#endif
+#if defined(MCAST_JOIN_SOURCE_GROUP)
+ initConstant(env, c, "MCAST_JOIN_SOURCE_GROUP", MCAST_JOIN_SOURCE_GROUP);
+#endif
+#if defined(MCAST_LEAVE_SOURCE_GROUP)
+ initConstant(env, c, "MCAST_LEAVE_SOURCE_GROUP", MCAST_LEAVE_SOURCE_GROUP);
+#endif
+#if defined(MCAST_BLOCK_SOURCE)
+ initConstant(env, c, "MCAST_BLOCK_SOURCE", MCAST_BLOCK_SOURCE);
+#endif
+#if defined(MCAST_UNBLOCK_SOURCE)
+ initConstant(env, c, "MCAST_UNBLOCK_SOURCE", MCAST_UNBLOCK_SOURCE);
+#endif
+ initConstant(env, c, "MCL_CURRENT", MCL_CURRENT);
+ initConstant(env, c, "MCL_FUTURE", MCL_FUTURE);
+ initConstant(env, c, "MSG_CTRUNC", MSG_CTRUNC);
+ initConstant(env, c, "MSG_DONTROUTE", MSG_DONTROUTE);
+ initConstant(env, c, "MSG_EOR", MSG_EOR);
+ initConstant(env, c, "MSG_OOB", MSG_OOB);
+ initConstant(env, c, "MSG_PEEK", MSG_PEEK);
+ initConstant(env, c, "MSG_TRUNC", MSG_TRUNC);
+ initConstant(env, c, "MSG_WAITALL", MSG_WAITALL);
+ initConstant(env, c, "MS_ASYNC", MS_ASYNC);
+ initConstant(env, c, "MS_INVALIDATE", MS_INVALIDATE);
+ initConstant(env, c, "MS_SYNC", MS_SYNC);
+ initConstant(env, c, "NI_DGRAM", NI_DGRAM);
+ initConstant(env, c, "NI_NAMEREQD", NI_NAMEREQD);
+ initConstant(env, c, "NI_NOFQDN", NI_NOFQDN);
+ initConstant(env, c, "NI_NUMERICHOST", NI_NUMERICHOST);
+ initConstant(env, c, "NI_NUMERICSERV", NI_NUMERICSERV);
+ initConstant(env, c, "O_ACCMODE", O_ACCMODE);
+ initConstant(env, c, "O_APPEND", O_APPEND);
+ initConstant(env, c, "O_CREAT", O_CREAT);
+ initConstant(env, c, "O_EXCL", O_EXCL);
+ initConstant(env, c, "O_NOCTTY", O_NOCTTY);
+ initConstant(env, c, "O_NOFOLLOW", O_NOFOLLOW);
+ initConstant(env, c, "O_NONBLOCK", O_NONBLOCK);
+ initConstant(env, c, "O_RDONLY", O_RDONLY);
+ initConstant(env, c, "O_RDWR", O_RDWR);
+ initConstant(env, c, "O_SYNC", O_SYNC);
+ initConstant(env, c, "O_TRUNC", O_TRUNC);
+ initConstant(env, c, "O_WRONLY", O_WRONLY);
+ initConstant(env, c, "POLLERR", POLLERR);
+ initConstant(env, c, "POLLHUP", POLLHUP);
+ initConstant(env, c, "POLLIN", POLLIN);
+ initConstant(env, c, "POLLNVAL", POLLNVAL);
+ initConstant(env, c, "POLLOUT", POLLOUT);
+ initConstant(env, c, "POLLPRI", POLLPRI);
+ initConstant(env, c, "POLLRDBAND", POLLRDBAND);
+ initConstant(env, c, "POLLRDNORM", POLLRDNORM);
+ initConstant(env, c, "POLLWRBAND", POLLWRBAND);
+ initConstant(env, c, "POLLWRNORM", POLLWRNORM);
+#if defined(PR_GET_DUMPABLE)
+ initConstant(env, c, "PR_GET_DUMPABLE", PR_GET_DUMPABLE);
+#endif
+#if defined(PR_SET_DUMPABLE)
+ initConstant(env, c, "PR_SET_DUMPABLE", PR_SET_DUMPABLE);
+#endif
+#if defined(PR_SET_NO_NEW_PRIVS)
+ initConstant(env, c, "PR_SET_NO_NEW_PRIVS", PR_SET_NO_NEW_PRIVS);
+#endif
+ initConstant(env, c, "PROT_EXEC", PROT_EXEC);
+ initConstant(env, c, "PROT_NONE", PROT_NONE);
+ initConstant(env, c, "PROT_READ", PROT_READ);
+ initConstant(env, c, "PROT_WRITE", PROT_WRITE);
+ initConstant(env, c, "R_OK", R_OK);
+// NOTE: The RT_* constants are not preprocessor defines, they're enum
+// members. The best we can do (barring UAPI / kernel version checks) is
+// to hope they exist on all host linuxes we're building on. These
+// constants have been around since 2.6.35 at least, so we should be ok.
+#if !defined(__APPLE__)
+ initConstant(env, c, "RT_SCOPE_HOST", RT_SCOPE_HOST);
+ initConstant(env, c, "RT_SCOPE_LINK", RT_SCOPE_LINK);
+ initConstant(env, c, "RT_SCOPE_NOWHERE", RT_SCOPE_NOWHERE);
+ initConstant(env, c, "RT_SCOPE_SITE", RT_SCOPE_SITE);
+ initConstant(env, c, "RT_SCOPE_UNIVERSE", RT_SCOPE_UNIVERSE);
+#endif
+ initConstant(env, c, "SEEK_CUR", SEEK_CUR);
+ initConstant(env, c, "SEEK_END", SEEK_END);
+ initConstant(env, c, "SEEK_SET", SEEK_SET);
+ initConstant(env, c, "SHUT_RD", SHUT_RD);
+ initConstant(env, c, "SHUT_RDWR", SHUT_RDWR);
+ initConstant(env, c, "SHUT_WR", SHUT_WR);
+ initConstant(env, c, "SIGABRT", SIGABRT);
+ initConstant(env, c, "SIGALRM", SIGALRM);
+ initConstant(env, c, "SIGBUS", SIGBUS);
+ initConstant(env, c, "SIGCHLD", SIGCHLD);
+ initConstant(env, c, "SIGCONT", SIGCONT);
+ initConstant(env, c, "SIGFPE", SIGFPE);
+ initConstant(env, c, "SIGHUP", SIGHUP);
+ initConstant(env, c, "SIGILL", SIGILL);
+ initConstant(env, c, "SIGINT", SIGINT);
+ initConstant(env, c, "SIGIO", SIGIO);
+ initConstant(env, c, "SIGKILL", SIGKILL);
+ initConstant(env, c, "SIGPIPE", SIGPIPE);
+ initConstant(env, c, "SIGPROF", SIGPROF);
+#if defined(SIGPWR)
+ initConstant(env, c, "SIGPWR", SIGPWR);
+#endif
+ initConstant(env, c, "SIGQUIT", SIGQUIT);
+#if defined(SIGRTMAX)
+ initConstant(env, c, "SIGRTMAX", SIGRTMAX);
+#endif
+#if defined(SIGRTMIN)
+ initConstant(env, c, "SIGRTMIN", SIGRTMIN);
+#endif
+ initConstant(env, c, "SIGSEGV", SIGSEGV);
+#if defined(SIGSTKFLT)
+ initConstant(env, c, "SIGSTKFLT", SIGSTKFLT);
+#endif
+ initConstant(env, c, "SIGSTOP", SIGSTOP);
+ initConstant(env, c, "SIGSYS", SIGSYS);
+ initConstant(env, c, "SIGTERM", SIGTERM);
+ initConstant(env, c, "SIGTRAP", SIGTRAP);
+ initConstant(env, c, "SIGTSTP", SIGTSTP);
+ initConstant(env, c, "SIGTTIN", SIGTTIN);
+ initConstant(env, c, "SIGTTOU", SIGTTOU);
+ initConstant(env, c, "SIGURG", SIGURG);
+ initConstant(env, c, "SIGUSR1", SIGUSR1);
+ initConstant(env, c, "SIGUSR2", SIGUSR2);
+ initConstant(env, c, "SIGVTALRM", SIGVTALRM);
+ initConstant(env, c, "SIGWINCH", SIGWINCH);
+ initConstant(env, c, "SIGXCPU", SIGXCPU);
+ initConstant(env, c, "SIGXFSZ", SIGXFSZ);
+ initConstant(env, c, "SIOCGIFADDR", SIOCGIFADDR);
+ initConstant(env, c, "SIOCGIFBRDADDR", SIOCGIFBRDADDR);
+ initConstant(env, c, "SIOCGIFDSTADDR", SIOCGIFDSTADDR);
+ initConstant(env, c, "SIOCGIFNETMASK", SIOCGIFNETMASK);
+ initConstant(env, c, "SOCK_DGRAM", SOCK_DGRAM);
+ initConstant(env, c, "SOCK_RAW", SOCK_RAW);
+ initConstant(env, c, "SOCK_SEQPACKET", SOCK_SEQPACKET);
+ initConstant(env, c, "SOCK_STREAM", SOCK_STREAM);
+ initConstant(env, c, "SOL_SOCKET", SOL_SOCKET);
+#if defined(SO_BINDTODEVICE)
+ initConstant(env, c, "SO_BINDTODEVICE", SO_BINDTODEVICE);
+#endif
+ initConstant(env, c, "SO_BROADCAST", SO_BROADCAST);
+ initConstant(env, c, "SO_DEBUG", SO_DEBUG);
+ initConstant(env, c, "SO_DONTROUTE", SO_DONTROUTE);
+ initConstant(env, c, "SO_ERROR", SO_ERROR);
+ initConstant(env, c, "SO_KEEPALIVE", SO_KEEPALIVE);
+ initConstant(env, c, "SO_LINGER", SO_LINGER);
+ initConstant(env, c, "SO_OOBINLINE", SO_OOBINLINE);
+#if defined(SO_PASSCRED)
+ initConstant(env, c, "SO_PASSCRED", SO_PASSCRED);
+#endif
+#if defined(SO_PEERCRED)
+ initConstant(env, c, "SO_PEERCRED", SO_PEERCRED);
+#endif
+ initConstant(env, c, "SO_RCVBUF", SO_RCVBUF);
+ initConstant(env, c, "SO_RCVLOWAT", SO_RCVLOWAT);
+ initConstant(env, c, "SO_RCVTIMEO", SO_RCVTIMEO);
+ initConstant(env, c, "SO_REUSEADDR", SO_REUSEADDR);
+ initConstant(env, c, "SO_SNDBUF", SO_SNDBUF);
+ initConstant(env, c, "SO_SNDLOWAT", SO_SNDLOWAT);
+ initConstant(env, c, "SO_SNDTIMEO", SO_SNDTIMEO);
+ initConstant(env, c, "SO_TYPE", SO_TYPE);
+ initConstant(env, c, "STDERR_FILENO", STDERR_FILENO);
+ initConstant(env, c, "STDIN_FILENO", STDIN_FILENO);
+ initConstant(env, c, "STDOUT_FILENO", STDOUT_FILENO);
+ initConstant(env, c, "S_IFBLK", S_IFBLK);
+ initConstant(env, c, "S_IFCHR", S_IFCHR);
+ initConstant(env, c, "S_IFDIR", S_IFDIR);
+ initConstant(env, c, "S_IFIFO", S_IFIFO);
+ initConstant(env, c, "S_IFLNK", S_IFLNK);
+ initConstant(env, c, "S_IFMT", S_IFMT);
+ initConstant(env, c, "S_IFREG", S_IFREG);
+ initConstant(env, c, "S_IFSOCK", S_IFSOCK);
+ initConstant(env, c, "S_IRGRP", S_IRGRP);
+ initConstant(env, c, "S_IROTH", S_IROTH);
+ initConstant(env, c, "S_IRUSR", S_IRUSR);
+ initConstant(env, c, "S_IRWXG", S_IRWXG);
+ initConstant(env, c, "S_IRWXO", S_IRWXO);
+ initConstant(env, c, "S_IRWXU", S_IRWXU);
+ initConstant(env, c, "S_ISGID", S_ISGID);
+ initConstant(env, c, "S_ISUID", S_ISUID);
+ initConstant(env, c, "S_ISVTX", S_ISVTX);
+ initConstant(env, c, "S_IWGRP", S_IWGRP);
+ initConstant(env, c, "S_IWOTH", S_IWOTH);
+ initConstant(env, c, "S_IWUSR", S_IWUSR);
+ initConstant(env, c, "S_IXGRP", S_IXGRP);
+ initConstant(env, c, "S_IXOTH", S_IXOTH);
+ initConstant(env, c, "S_IXUSR", S_IXUSR);
+ initConstant(env, c, "TCP_NODELAY", TCP_NODELAY);
+ initConstant(env, c, "WCONTINUED", WCONTINUED);
+ initConstant(env, c, "WEXITED", WEXITED);
+ initConstant(env, c, "WNOHANG", WNOHANG);
+ initConstant(env, c, "WNOWAIT", WNOWAIT);
+ initConstant(env, c, "WSTOPPED", WSTOPPED);
+ initConstant(env, c, "WUNTRACED", WUNTRACED);
+ initConstant(env, c, "W_OK", W_OK);
+ initConstant(env, c, "X_OK", X_OK);
+ initConstant(env, c, "_SC_2_CHAR_TERM", _SC_2_CHAR_TERM);
+ initConstant(env, c, "_SC_2_C_BIND", _SC_2_C_BIND);
+ initConstant(env, c, "_SC_2_C_DEV", _SC_2_C_DEV);
+#if defined(_SC_2_C_VERSION)
+ initConstant(env, c, "_SC_2_C_VERSION", _SC_2_C_VERSION);
+#endif
+ initConstant(env, c, "_SC_2_FORT_DEV", _SC_2_FORT_DEV);
+ initConstant(env, c, "_SC_2_FORT_RUN", _SC_2_FORT_RUN);
+ initConstant(env, c, "_SC_2_LOCALEDEF", _SC_2_LOCALEDEF);
+ initConstant(env, c, "_SC_2_SW_DEV", _SC_2_SW_DEV);
+ initConstant(env, c, "_SC_2_UPE", _SC_2_UPE);
+ initConstant(env, c, "_SC_2_VERSION", _SC_2_VERSION);
+ initConstant(env, c, "_SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX);
+ initConstant(env, c, "_SC_AIO_MAX", _SC_AIO_MAX);
+ initConstant(env, c, "_SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX);
+ initConstant(env, c, "_SC_ARG_MAX", _SC_ARG_MAX);
+ initConstant(env, c, "_SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO);
+ initConstant(env, c, "_SC_ATEXIT_MAX", _SC_ATEXIT_MAX);
+#if defined(_SC_AVPHYS_PAGES)
+ initConstant(env, c, "_SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES);
+#endif
+ initConstant(env, c, "_SC_BC_BASE_MAX", _SC_BC_BASE_MAX);
+ initConstant(env, c, "_SC_BC_DIM_MAX", _SC_BC_DIM_MAX);
+ initConstant(env, c, "_SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX);
+ initConstant(env, c, "_SC_BC_STRING_MAX", _SC_BC_STRING_MAX);
+ initConstant(env, c, "_SC_CHILD_MAX", _SC_CHILD_MAX);
+ initConstant(env, c, "_SC_CLK_TCK", _SC_CLK_TCK);
+ initConstant(env, c, "_SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX);
+ initConstant(env, c, "_SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX);
+ initConstant(env, c, "_SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX);
+ initConstant(env, c, "_SC_FSYNC", _SC_FSYNC);
+ initConstant(env, c, "_SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX);
+ initConstant(env, c, "_SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX);
+ initConstant(env, c, "_SC_IOV_MAX", _SC_IOV_MAX);
+ initConstant(env, c, "_SC_JOB_CONTROL", _SC_JOB_CONTROL);
+ initConstant(env, c, "_SC_LINE_MAX", _SC_LINE_MAX);
+ initConstant(env, c, "_SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX);
+ initConstant(env, c, "_SC_MAPPED_FILES", _SC_MAPPED_FILES);
+ initConstant(env, c, "_SC_MEMLOCK", _SC_MEMLOCK);
+ initConstant(env, c, "_SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE);
+ initConstant(env, c, "_SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION);
+ initConstant(env, c, "_SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING);
+ initConstant(env, c, "_SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX);
+ initConstant(env, c, "_SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX);
+ initConstant(env, c, "_SC_NGROUPS_MAX", _SC_NGROUPS_MAX);
+ initConstant(env, c, "_SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF);
+ initConstant(env, c, "_SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN);
+ initConstant(env, c, "_SC_OPEN_MAX", _SC_OPEN_MAX);
+ initConstant(env, c, "_SC_PAGESIZE", _SC_PAGESIZE);
+ initConstant(env, c, "_SC_PAGE_SIZE", _SC_PAGE_SIZE);
+ initConstant(env, c, "_SC_PASS_MAX", _SC_PASS_MAX);
+#if defined(_SC_PHYS_PAGES)
+ initConstant(env, c, "_SC_PHYS_PAGES", _SC_PHYS_PAGES);
+#endif
+ initConstant(env, c, "_SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO);
+ initConstant(env, c, "_SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING);
+ initConstant(env, c, "_SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS);
+ initConstant(env, c, "_SC_RE_DUP_MAX", _SC_RE_DUP_MAX);
+ initConstant(env, c, "_SC_RTSIG_MAX", _SC_RTSIG_MAX);
+ initConstant(env, c, "_SC_SAVED_IDS", _SC_SAVED_IDS);
+ initConstant(env, c, "_SC_SEMAPHORES", _SC_SEMAPHORES);
+ initConstant(env, c, "_SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX);
+ initConstant(env, c, "_SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX);
+ initConstant(env, c, "_SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS);
+ initConstant(env, c, "_SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX);
+ initConstant(env, c, "_SC_STREAM_MAX", _SC_STREAM_MAX);
+ initConstant(env, c, "_SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO);
+ initConstant(env, c, "_SC_THREADS", _SC_THREADS);
+ initConstant(env, c, "_SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR);
+ initConstant(env, c, "_SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE);
+ initConstant(env, c, "_SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS);
+ initConstant(env, c, "_SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX);
+ initConstant(env, c, "_SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING);
+ initConstant(env, c, "_SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT);
+ initConstant(env, c, "_SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT);
+ initConstant(env, c, "_SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS);
+ initConstant(env, c, "_SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN);
+ initConstant(env, c, "_SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX);
+ initConstant(env, c, "_SC_TIMERS", _SC_TIMERS);
+ initConstant(env, c, "_SC_TIMER_MAX", _SC_TIMER_MAX);
+ initConstant(env, c, "_SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX);
+ initConstant(env, c, "_SC_TZNAME_MAX", _SC_TZNAME_MAX);
+ initConstant(env, c, "_SC_VERSION", _SC_VERSION);
+ initConstant(env, c, "_SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32);
+ initConstant(env, c, "_SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG);
+ initConstant(env, c, "_SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64);
+ initConstant(env, c, "_SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG);
+ initConstant(env, c, "_SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT);
+ initConstant(env, c, "_SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N);
+ initConstant(env, c, "_SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY);
+ initConstant(env, c, "_SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME);
+ initConstant(env, c, "_SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS);
+ initConstant(env, c, "_SC_XOPEN_SHM", _SC_XOPEN_SHM);
+ initConstant(env, c, "_SC_XOPEN_UNIX", _SC_XOPEN_UNIX);
+ initConstant(env, c, "_SC_XOPEN_VERSION", _SC_XOPEN_VERSION);
+ initConstant(env, c, "_SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION);
+}
+
+static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(OsConstants, initConstants, "()V"),
+};
+void register_android_system_OsConstants(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "android/system/OsConstants", gMethods, NELEM(gMethods));
+}
diff --git a/luni/src/main/native/canonicalize_path.cpp b/luni/src/main/native/canonicalize_path.cpp
new file mode 100644
index 0000000..b2a2a01
--- /dev/null
+++ b/luni/src/main/native/canonicalize_path.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "readlink.h"
+
+#include <string>
+
+#include <errno.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+/**
+ * This differs from realpath(3) mainly in its behavior when a path element does not exist or can
+ * not be searched. realpath(3) treats that as an error and gives up, but we have Java-compatible
+ * behavior where we just assume the path element was not a symbolic link. This leads to a textual
+ * treatment of ".." from that point in the path, which may actually lead us back to a path we
+ * can resolve (as in "/tmp/does-not-exist/../blah.txt" which would be an error for realpath(3)
+ * but "/tmp/blah.txt" under the traditional Java interpretation).
+ *
+ * This implementation also removes all the fixed-length buffers of the C original.
+ */
+bool canonicalize_path(const char* path, std::string& resolved) {
+ // 'path' must be an absolute path.
+ if (path[0] != '/') {
+ errno = EINVAL;
+ return false;
+ }
+
+ resolved = "/";
+ if (path[1] == '\0') {
+ return true;
+ }
+
+ // Iterate over path components in 'left'.
+ int symlinkCount = 0;
+ std::string left(path + 1);
+ while (!left.empty()) {
+ // Extract the next path component.
+ size_t nextSlash = left.find('/');
+ std::string nextPathComponent = left.substr(0, nextSlash);
+ if (nextSlash != std::string::npos) {
+ left.erase(0, nextSlash + 1);
+ } else {
+ left.clear();
+ }
+ if (nextPathComponent.empty()) {
+ continue;
+ } else if (nextPathComponent == ".") {
+ continue;
+ } else if (nextPathComponent == "..") {
+ // Strip the last path component except when we have single "/".
+ if (resolved.size() > 1) {
+ resolved.erase(resolved.rfind('/'));
+ }
+ continue;
+ }
+
+ // Append the next path component.
+ if (resolved[resolved.size() - 1] != '/') {
+ resolved += '/';
+ }
+ resolved += nextPathComponent;
+
+ // See if we've got a symbolic link, and resolve it if so.
+ struct stat sb;
+ if (lstat(resolved.c_str(), &sb) == 0 && S_ISLNK(sb.st_mode)) {
+ if (symlinkCount++ > MAXSYMLINKS) {
+ errno = ELOOP;
+ return false;
+ }
+
+ std::string symlink;
+ if (!readlink(resolved.c_str(), symlink)) {
+ return false;
+ }
+ if (symlink[0] == '/') {
+ // The symbolic link is absolute, so we need to start from scratch.
+ resolved = "/";
+ } else if (resolved.size() > 1) {
+ // The symbolic link is relative, so we just lose the last path component (which
+ // was the link).
+ resolved.erase(resolved.rfind('/'));
+ }
+
+ if (!left.empty()) {
+ const char* maybeSlash = (symlink[symlink.size() - 1] != '/') ? "/" : "";
+ left = symlink + maybeSlash + left;
+ } else {
+ left = symlink;
+ }
+ }
+ }
+
+ // Remove trailing slash except when the resolved pathname is a single "/".
+ if (resolved.size() > 1 && resolved[resolved.size() - 1] == '/') {
+ resolved.erase(resolved.size() - 1, 1);
+ }
+ return true;
+}
diff --git a/luni/src/main/native/java_io_Console.cpp b/luni/src/main/native/java_io_Console.cpp
deleted file mode 100644
index 512bc72..0000000
--- a/luni/src/main/native/java_io_Console.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Console"
-
-#include "JNIHelp.h"
-#include "JniConstants.h"
-
-#include <errno.h>
-#include <termios.h>
-#include <unistd.h>
-
-static jint Console_setEchoImpl(JNIEnv* env, jclass, jboolean on, jint previousState) {
- termios state;
- if (TEMP_FAILURE_RETRY(tcgetattr(STDIN_FILENO, &state)) == -1) {
- jniThrowIOException(env, errno);
- return 0;
- }
- if (on) {
- state.c_lflag = previousState;
- } else {
- previousState = state.c_lflag;
- state.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
- }
- if (TEMP_FAILURE_RETRY(tcsetattr(STDIN_FILENO, TCSAFLUSH, &state)) == -1){
- jniThrowIOException(env, errno);
- return 0;
- }
- return previousState;
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Console, setEchoImpl, "(ZI)I"),
-};
-void register_java_io_Console(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/io/Console", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/java_io_File.cpp b/luni/src/main/native/java_io_File.cpp
index c217ea2..046fc4f 100644
--- a/luni/src/main/native/java_io_File.cpp
+++ b/luni/src/main/native/java_io_File.cpp
@@ -22,7 +22,6 @@
#include "JniException.h"
#include "ScopedPrimitiveArray.h"
#include "ScopedUtfChars.h"
-#include "readlink.h"
#include "toStringArray.h"
#include <string>
@@ -39,96 +38,82 @@
#include <unistd.h>
#include <utime.h>
-static jstring File_readlink(JNIEnv* env, jclass, jstring javaPath) {
- ScopedUtfChars path(env, javaPath);
- if (path.c_str() == NULL) {
- return NULL;
- }
-
- std::string result;
- if (!readlink(path.c_str(), result)) {
- jniThrowIOException(env, errno);
- return NULL;
- }
- return env->NewStringUTF(result.c_str());
-}
-
-static jstring File_realpath(JNIEnv* env, jclass, jstring javaPath) {
- ScopedUtfChars path(env, javaPath);
- if (path.c_str() == NULL) {
- return NULL;
- }
-
- extern bool realpath(const char* path, std::string& resolved);
- std::string result;
- if (!realpath(path.c_str(), result)) {
- jniThrowIOException(env, errno);
- return NULL;
- }
- return env->NewStringUTF(result.c_str());
+static jstring File_canonicalizePath(JNIEnv* env, jclass, jstring javaPath) {
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return NULL;
+ }
+
+ extern bool canonicalize_path(const char* path, std::string& resolved);
+ std::string result;
+ if (!canonicalize_path(path.c_str(), result)) {
+ jniThrowIOException(env, errno);
+ return NULL;
+ }
+ return env->NewStringUTF(result.c_str());
}
static jboolean File_setLastModifiedImpl(JNIEnv* env, jclass, jstring javaPath, jlong ms) {
- ScopedUtfChars path(env, javaPath);
- if (path.c_str() == NULL) {
- return JNI_FALSE;
- }
-
- // We want to preserve the access time.
- struct stat sb;
- if (stat(path.c_str(), &sb) == -1) {
- return JNI_FALSE;
- }
-
- // TODO: we could get microsecond resolution with utimes(3), "legacy" though it is.
- utimbuf times;
- times.actime = sb.st_atime;
- times.modtime = static_cast<time_t>(ms / 1000);
- return (utime(path.c_str(), &times) == 0);
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return JNI_FALSE;
+ }
+
+ // We want to preserve the access time.
+ struct stat sb;
+ if (stat(path.c_str(), &sb) == -1) {
+ return JNI_FALSE;
+ }
+
+ // TODO: we could get microsecond resolution with utimes(3), "legacy" though it is.
+ utimbuf times;
+ times.actime = sb.st_atime;
+ times.modtime = static_cast<time_t>(ms / 1000);
+ return (utime(path.c_str(), &times) == 0);
}
// Iterates over the filenames in the given directory.
class ScopedReaddir {
-public:
- ScopedReaddir(const char* path) {
- mDirStream = opendir(path);
- mIsBad = (mDirStream == NULL);
+ public:
+ ScopedReaddir(const char* path) {
+ mDirStream = opendir(path);
+ mIsBad = (mDirStream == NULL);
+ }
+
+ ~ScopedReaddir() {
+ if (mDirStream != NULL) {
+ closedir(mDirStream);
}
+ }
- ~ScopedReaddir() {
- if (mDirStream != NULL) {
- closedir(mDirStream);
- }
+ // Returns the next filename, or NULL.
+ const char* next() {
+ if (mIsBad) {
+ return NULL;
}
-
- // Returns the next filename, or NULL.
- const char* next() {
- if (mIsBad) {
- return NULL;
- }
- errno = 0;
- dirent* result = readdir(mDirStream);
- if (result != NULL) {
- return result->d_name;
- }
- if (errno != 0) {
- mIsBad = true;
- }
- return NULL;
+ errno = 0;
+ dirent* result = readdir(mDirStream);
+ if (result != NULL) {
+ return result->d_name;
}
-
- // Has an error occurred on this stream?
- bool isBad() const {
- return mIsBad;
+ if (errno != 0) {
+ mIsBad = true;
}
+ return NULL;
+ }
-private:
- DIR* mDirStream;
- bool mIsBad;
+ // Has an error occurred on this stream?
+ bool isBad() const {
+ return mIsBad;
+ }
- // Disallow copy and assignment.
- ScopedReaddir(const ScopedReaddir&);
- void operator=(const ScopedReaddir&);
+ private:
+ DIR* mDirStream;
+ bool mIsBad;
+
+ // Disallow copy and assignment.
+ ScopedReaddir(const ScopedReaddir&);
+ void operator=(const ScopedReaddir&);
};
typedef std::vector<std::string> DirEntries;
@@ -136,38 +121,37 @@ typedef std::vector<std::string> DirEntries;
// Reads the directory referred to by 'pathBytes', adding each directory entry
// to 'entries'.
static bool readDirectory(JNIEnv* env, jstring javaPath, DirEntries& entries) {
- ScopedUtfChars path(env, javaPath);
- if (path.c_str() == NULL) {
- return false;
- }
-
- ScopedReaddir dir(path.c_str());
- const char* filename;
- while ((filename = dir.next()) != NULL) {
- if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0) {
- // TODO: this hides allocation failures from us. Push directory iteration up into Java?
- entries.push_back(filename);
- }
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return false;
+ }
+
+ ScopedReaddir dir(path.c_str());
+ const char* filename;
+ while ((filename = dir.next()) != NULL) {
+ if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0) {
+ // TODO: this hides allocation failures from us. Push directory iteration up into Java?
+ entries.push_back(filename);
}
- return !dir.isBad();
+ }
+ return !dir.isBad();
}
static jobjectArray File_listImpl(JNIEnv* env, jclass, jstring javaPath) {
- // Read the directory entries into an intermediate form.
- DirEntries entries;
- if (!readDirectory(env, javaPath, entries)) {
- return NULL;
- }
- // Translate the intermediate form into a Java String[].
- return toStringArray(env, entries);
+ // Read the directory entries into an intermediate form.
+ DirEntries entries;
+ if (!readDirectory(env, javaPath, entries)) {
+ return NULL;
+ }
+ // Translate the intermediate form into a Java String[].
+ return toStringArray(env, entries);
}
static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(File, listImpl, "(Ljava/lang/String;)[Ljava/lang/String;"),
- NATIVE_METHOD(File, readlink, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(File, realpath, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(File, setLastModifiedImpl, "(Ljava/lang/String;J)Z"),
+ NATIVE_METHOD(File, canonicalizePath, "(Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(File, listImpl, "(Ljava/lang/String;)[Ljava/lang/String;"),
+ NATIVE_METHOD(File, setLastModifiedImpl, "(Ljava/lang/String;J)Z"),
};
void register_java_io_File(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/io/File", gMethods, NELEM(gMethods));
+ jniRegisterNativeMethods(env, "java/io/File", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/main/native/java_io_FileDescriptor.cpp b/luni/src/main/native/java_io_FileDescriptor.cpp
new file mode 100644
index 0000000..fe7e07e
--- /dev/null
+++ b/luni/src/main/native/java_io_FileDescriptor.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "FileDescriptor"
+
+#include "JniConstants.h"
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+static jboolean FileDescriptor_isSocket(JNIEnv*, jclass, jint fd) {
+ int error;
+ socklen_t error_length = sizeof(error);
+ return TEMP_FAILURE_RETRY(getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &error_length));
+}
+
+static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(FileDescriptor, isSocket, "(I)Z"),
+};
+void register_java_io_FileDescriptor(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "java/io/FileDescriptor", gMethods, NELEM(gMethods));
+}
diff --git a/luni/src/main/native/java_lang_Character.cpp b/luni/src/main/native/java_lang_Character.cpp
index 14eef64..4022f4b 100644
--- a/luni/src/main/native/java_lang_Character.cpp
+++ b/luni/src/main/native/java_lang_Character.cpp
@@ -20,6 +20,7 @@
#include "JniConstants.h"
#include "ScopedUtfChars.h"
#include "unicode/uchar.h"
+#include "unicode/uscript.h"
#include <math.h>
#include <stdio.h> // For BUFSIZ
#include <stdlib.h>
@@ -32,7 +33,7 @@ static jint Character_getTypeImpl(JNIEnv*, jclass, jint codePoint) {
return u_charType(codePoint);
}
-static jbyte Character_getDirectionalityImpl(JNIEnv*, jclass, jint codePoint) {
+static jbyte Character_getIcuDirectionality(JNIEnv*, jclass, jint codePoint) {
return u_charDirection(codePoint);
}
@@ -124,7 +125,7 @@ static jboolean Character_isLowerCaseImpl(JNIEnv*, jclass, jint codePoint) {
return u_islower(codePoint);
}
-static int Character_forNameImpl(JNIEnv* env, jclass, jstring javaBlockName) {
+static int Character_unicodeBlockForName(JNIEnv* env, jclass, jstring javaBlockName) {
ScopedUtfChars blockName(env, javaBlockName);
if (blockName.c_str() == NULL) {
return 0;
@@ -132,10 +133,29 @@ static int Character_forNameImpl(JNIEnv* env, jclass, jstring javaBlockName) {
return u_getPropertyValueEnum(UCHAR_BLOCK, blockName.c_str());
}
-static int Character_ofImpl(JNIEnv*, jclass, jint codePoint) {
+static int Character_unicodeBlockForCodePoint(JNIEnv*, jclass, jint codePoint) {
return ublock_getCode(codePoint);
}
+static int Character_unicodeScriptForName(JNIEnv* env, jclass, jstring javaScriptName) {
+ ScopedUtfChars scriptName(env, javaScriptName);
+ if (scriptName.c_str() == NULL) {
+ return -1;
+ }
+
+ return u_getPropertyValueEnum(UCHAR_SCRIPT, scriptName.c_str());
+}
+
+static int Character_unicodeScriptForCodePoint(JNIEnv*, jclass, jint codePoint) {
+ UErrorCode status = U_ZERO_ERROR;
+ const UScriptCode script = uscript_getScript(codePoint, &status);
+ if (status != U_ZERO_ERROR) {
+ return -1;
+ }
+
+ return script;
+}
+
static jboolean Character_isAlphabetic(JNIEnv*, jclass, jint codePoint) {
return u_hasBinaryProperty(codePoint, UCHAR_ALPHABETIC);
}
@@ -146,8 +166,7 @@ static jboolean Character_isIdeographic(JNIEnv*, jclass, jint codePoint) {
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Character, digitImpl, "!(II)I"),
- NATIVE_METHOD(Character, forNameImpl, "(Ljava/lang/String;)I"),
- NATIVE_METHOD(Character, getDirectionalityImpl, "!(I)B"),
+ NATIVE_METHOD(Character, getIcuDirectionality, "!(I)B"),
NATIVE_METHOD(Character, getNameImpl, "(I)Ljava/lang/String;"),
NATIVE_METHOD(Character, getNumericValueImpl, "!(I)I"),
NATIVE_METHOD(Character, getTypeImpl, "!(I)I"),
@@ -166,10 +185,13 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Character, isUnicodeIdentifierStartImpl, "!(I)Z"),
NATIVE_METHOD(Character, isUpperCaseImpl, "!(I)Z"),
NATIVE_METHOD(Character, isWhitespaceImpl, "!(I)Z"),
- NATIVE_METHOD(Character, ofImpl, "!(I)I"),
NATIVE_METHOD(Character, toLowerCaseImpl, "!(I)I"),
NATIVE_METHOD(Character, toTitleCaseImpl, "!(I)I"),
NATIVE_METHOD(Character, toUpperCaseImpl, "!(I)I"),
+ NATIVE_METHOD(Character, unicodeBlockForName, "(Ljava/lang/String;)I"),
+ NATIVE_METHOD(Character, unicodeBlockForCodePoint, "!(I)I"),
+ NATIVE_METHOD(Character, unicodeScriptForName, "(Ljava/lang/String;)I"),
+ NATIVE_METHOD(Character, unicodeScriptForCodePoint, "!(I)I"),
};
void register_java_lang_Character(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/Character", gMethods, NELEM(gMethods));
diff --git a/luni/src/main/native/java_lang_Double.cpp b/luni/src/main/native/java_lang_Double.cpp
index 259be30..186bd26 100644
--- a/luni/src/main/native/java_lang_Double.cpp
+++ b/luni/src/main/native/java_lang_Double.cpp
@@ -29,15 +29,6 @@ union Double {
double d;
};
-static const jlong NaN = 0x7ff8000000000000ULL;
-
-static jlong Double_doubleToLongBits(JNIEnv*, jclass, jdouble val) {
- Double d;
- d.d = val;
- // For this method all values in the NaN range are normalized to the canonical NaN value.
- return isnan(d.d) ? NaN : d.bits;
-}
-
static jlong Double_doubleToRawLongBits(JNIEnv*, jclass, jdouble val) {
Double d;
d.d = val;
@@ -51,10 +42,9 @@ static jdouble Double_longBitsToDouble(JNIEnv*, jclass, jlong val) {
}
static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Double, doubleToLongBits, "(D)J"),
NATIVE_METHOD(Double, doubleToRawLongBits, "(D)J"),
NATIVE_METHOD(Double, longBitsToDouble, "(J)D"),
};
-int register_java_lang_Double(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "java/lang/Double", gMethods, NELEM(gMethods));
+void register_java_lang_Double(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "java/lang/Double", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/main/native/java_lang_Float.cpp b/luni/src/main/native/java_lang_Float.cpp
index 59544db..3852516 100644
--- a/luni/src/main/native/java_lang_Float.cpp
+++ b/luni/src/main/native/java_lang_Float.cpp
@@ -18,6 +18,7 @@
#include "JNIHelp.h"
#include "JniConstants.h"
+#include "Portability.h"
#include <math.h>
#include <stdlib.h>
@@ -28,15 +29,6 @@ union Float {
float f;
};
-static const jint NaN = 0x7fc00000;
-
-static jint Float_floatToIntBits(JNIEnv*, jclass, jfloat val) {
- Float f;
- f.f = val;
- // For this method all values in the NaN range are normalized to the canonical NaN value.
- return isnanf(f.f) ? NaN : f.bits;
-}
-
jint Float_floatToRawIntBits(JNIEnv*, jclass, jfloat val) {
Float f;
f.f = val;
@@ -50,10 +42,9 @@ jfloat Float_intBitsToFloat(JNIEnv*, jclass, jint val) {
}
static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Float, floatToIntBits, "(F)I"),
NATIVE_METHOD(Float, floatToRawIntBits, "(F)I"),
NATIVE_METHOD(Float, intBitsToFloat, "(I)F"),
};
-int register_java_lang_Float(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "java/lang/Float", gMethods, NELEM(gMethods));
+void register_java_lang_Float(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "java/lang/Float", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/main/native/java_lang_Math.cpp b/luni/src/main/native/java_lang_Math.cpp
index 784b84d..83c39bd 100644
--- a/luni/src/main/native/java_lang_Math.cpp
+++ b/luni/src/main/native/java_lang_Math.cpp
@@ -145,7 +145,6 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Math, tan, "!(D)D"),
NATIVE_METHOD(Math, tanh, "!(D)D"),
};
-
void register_java_lang_Math(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/Math", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/main/native/java_lang_ProcessManager.cpp b/luni/src/main/native/java_lang_ProcessManager.cpp
index a74ba8b..3a97ac6 100644
--- a/luni/src/main/native/java_lang_ProcessManager.cpp
+++ b/luni/src/main/native/java_lang_ProcessManager.cpp
@@ -38,7 +38,7 @@
static void CloseNonStandardFds(int status_pipe_fd) {
// On Cygwin, Linux, and Solaris, the best way to close iterates over "/proc/self/fd/".
const char* fd_path = "/proc/self/fd";
-#ifdef __APPLE__
+#if defined(__APPLE__)
// On Mac OS, there's "/dev/fd/" which Linux seems to link to "/proc/self/fd/",
// but which on Solaris appears to be something quite different.
fd_path = "/dev/fd";
diff --git a/luni/src/main/native/java_lang_System.cpp b/luni/src/main/native/java_lang_System.cpp
index 0686310..944c0c3 100644
--- a/luni/src/main/native/java_lang_System.cpp
+++ b/luni/src/main/native/java_lang_System.cpp
@@ -34,6 +34,10 @@
#include <time.h>
#include <unistd.h>
+#if defined(HAVE_ANDROID_OS)
+extern "C" void android_get_LD_LIBRARY_PATH(char*, size_t);
+#endif
+
static void System_log(JNIEnv* env, jclass, jchar type, jstring javaMessage, jthrowable exception) {
ScopedUtfChars message(env, javaMessage);
if (message.c_str() == NULL) {
@@ -82,6 +86,18 @@ static jobjectArray System_specialProperties(JNIEnv* env, jclass) {
properties.push_back("android.zlib.version=" ZLIB_VERSION);
properties.push_back("android.openssl.version=" OPENSSL_VERSION_TEXT);
+ const char* library_path = getenv("LD_LIBRARY_PATH");
+#if defined(HAVE_ANDROID_OS)
+ if (library_path == NULL) {
+ android_get_LD_LIBRARY_PATH(path, sizeof(path));
+ library_path = path;
+ }
+#endif
+ if (library_path == NULL) {
+ library_path = "";
+ }
+ properties.push_back(std::string("java.library.path=") + library_path);
+
return toStringArray(env, properties);
}
@@ -93,9 +109,15 @@ static jlong System_currentTimeMillis(JNIEnv*, jclass) {
}
static jlong System_nanoTime(JNIEnv*, jclass) {
+#if defined(HAVE_POSIX_CLOCKS)
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return now.tv_sec * 1000000000LL + now.tv_nsec;
+#else
+ timeval now;
+ gettimeofday(&now, NULL);
+ return static_cast<jlong>(now.tv_sec) * 1000000000LL + now.tv_usec * 1000LL;
+#endif
}
static jstring System_mapLibraryName(JNIEnv* env, jclass, jstring javaName) {
@@ -111,10 +133,10 @@ static jstring System_mapLibraryName(JNIEnv* env, jclass, jstring javaName) {
}
static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(System, currentTimeMillis, "()J"),
+ NATIVE_METHOD(System, currentTimeMillis, "!()J"),
NATIVE_METHOD(System, log, "(CLjava/lang/String;Ljava/lang/Throwable;)V"),
NATIVE_METHOD(System, mapLibraryName, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(System, nanoTime, "()J"),
+ NATIVE_METHOD(System, nanoTime, "!()J"),
NATIVE_METHOD(System, setFieldImpl, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"),
NATIVE_METHOD(System, specialProperties, "()[Ljava/lang/String;"),
};
diff --git a/luni/src/main/native/java_math_NativeBN.cpp b/luni/src/main/native/java_math_NativeBN.cpp
index 158dfac..be87ea6 100644
--- a/luni/src/main/native/java_math_NativeBN.cpp
+++ b/luni/src/main/native/java_math_NativeBN.cpp
@@ -21,7 +21,6 @@
#include "JniException.h"
#include "ScopedPrimitiveArray.h"
#include "ScopedUtfChars.h"
-#include "StaticAssert.h"
#include "UniquePtr.h"
#include "jni.h"
#include <openssl/bn.h>
@@ -109,18 +108,24 @@ static void NativeBN_BN_copy(JNIEnv* env, jclass, jlong to, jlong from) {
throwExceptionIfNecessary(env);
}
-static void NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, unsigned long long dw, jboolean neg) {
+static void NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, jlong java_dw, jboolean neg) {
if (!oneValidHandle(env, a0)) return;
- unsigned int hi = dw >> 32; // This shifts without sign extension.
- int lo = (int)dw; // This truncates implicitly.
+
+ uint64_t dw = java_dw;
// cf. litEndInts2bn:
BIGNUM* a = toBigNum(a0);
bn_check_top(a);
- if (bn_wexpand(a, 2) != NULL) {
+ if (bn_wexpand(a, 8/BN_BYTES) != NULL) {
+#ifdef __LP64__
+ a->d[0] = dw;
+#else
+ unsigned int hi = dw >> 32; // This shifts without sign extension.
+ int lo = (int)dw; // This truncates implicitly.
a->d[0] = lo;
a->d[1] = hi;
- a->top = 2;
+#endif
+ a->top = 8 / BN_BYTES;
a->neg = neg;
bn_correct_top(a);
} else {
@@ -128,7 +133,7 @@ static void NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, unsigned long lo
}
}
-static void NativeBN_putLongInt(JNIEnv* env, jclass cls, jlong a, long long dw) {
+static void NativeBN_putLongInt(JNIEnv* env, jclass cls, jlong a, jlong dw) {
if (dw >= 0) {
NativeBN_putULongInt(env, cls, a, dw, JNI_FALSE);
} else {
@@ -188,12 +193,26 @@ static void NativeBN_litEndInts2bn(JNIEnv* env, jclass, jintArray arr, int len,
if (scopedArray.get() == NULL) {
return;
}
-
- STATIC_ASSERT(sizeof(BN_ULONG) == sizeof(jint), BN_ULONG_not_32_bit);
- const BN_ULONG* tmpInts = reinterpret_cast<const BN_ULONG*>(scopedArray.get());
- if ((tmpInts != NULL) && (bn_wexpand(ret, len) != NULL)) {
+#ifdef __LP64__
+ const int wlen = (len + 1) / 2;
+#else
+ const int wlen = len;
+#endif
+ const unsigned int* tmpInts = reinterpret_cast<const unsigned int*>(scopedArray.get());
+ if ((tmpInts != NULL) && (bn_wexpand(ret, wlen) != NULL)) {
+#ifdef __LP64__
+ if (len % 2) {
+ ret->d[wlen - 1] = tmpInts[--len];
+ }
+ if (len > 0) {
+ for (int i = len - 2; i >= 0; i -= 2) {
+ ret->d[i/2] = ((unsigned long long)tmpInts[i+1] << 32) | tmpInts[i];
+ }
+ }
+#else
int i = len; do { i--; ret->d[i] = tmpInts[i]; } while (i > 0);
- ret->top = len;
+#endif
+ ret->top = wlen;
ret->neg = neg;
// need to call this due to clear byte at top if avoiding
// having the top bit set (-ve number)
@@ -208,35 +227,39 @@ static void NativeBN_litEndInts2bn(JNIEnv* env, jclass, jintArray arr, int len,
}
-#define BYTES2INT(bytes, k) \
+#ifdef __LP64__
+#define BYTES2ULONG(bytes, k) \
+ ((bytes[k + 7] & 0xffULL) | (bytes[k + 6] & 0xffULL) << 8 | (bytes[k + 5] & 0xffULL) << 16 | (bytes[k + 4] & 0xffULL) << 24 | \
+ (bytes[k + 3] & 0xffULL) << 32 | (bytes[k + 2] & 0xffULL) << 40 | (bytes[k + 1] & 0xffULL) << 48 | (bytes[k + 0] & 0xffULL) << 56)
+#else
+#define BYTES2ULONG(bytes, k) \
((bytes[k + 3] & 0xff) | (bytes[k + 2] & 0xff) << 8 | (bytes[k + 1] & 0xff) << 16 | (bytes[k + 0] & 0xff) << 24)
-
+#endif
static void negBigEndianBytes2bn(JNIEnv*, jclass, const unsigned char* bytes, int bytesLen, jlong ret0) {
BIGNUM* ret = toBigNum(ret0);
- // We rely on: (BN_BITS2 == 32), i.e. BN_ULONG is unsigned int and has 4 bytes:
bn_check_top(ret);
// FIXME: assert bytesLen > 0
- int intLen = (bytesLen + 3) / 4;
+ int wLen = (bytesLen + BN_BYTES - 1) / BN_BYTES;
int firstNonzeroDigit = -2;
- if (bn_wexpand(ret, intLen) != NULL) {
+ if (bn_wexpand(ret, wLen) != NULL) {
BN_ULONG* d = ret->d;
BN_ULONG di;
- ret->top = intLen;
- int highBytes = bytesLen % 4;
+ ret->top = wLen;
+ int highBytes = bytesLen % BN_BYTES;
int k = bytesLen;
// Put bytes to the int array starting from the end of the byte array
int i = 0;
while (k > highBytes) {
- k -= 4;
- di = BYTES2INT(bytes, k);
+ k -= BN_BYTES;
+ di = BYTES2ULONG(bytes, k);
if (di != 0) {
d[i] = -di;
firstNonzeroDigit = i;
i++;
while (k > highBytes) {
- k -= 4;
- d[i] = ~BYTES2INT(bytes, k);
+ k -= BN_BYTES;
+ d[i] = ~BYTES2ULONG(bytes, k);
i++;
}
break;
@@ -260,6 +283,8 @@ static void negBigEndianBytes2bn(JNIEnv*, jclass, const unsigned char* bytes, in
d[i] = -di;
}
}
+ // The top may have superfluous zeros, so fix it.
+ bn_correct_top(ret);
}
}
@@ -288,28 +313,25 @@ static void NativeBN_twosComp2bn(JNIEnv* env, jclass cls, jbyteArray arr, int by
throwExceptionIfNecessary(env);
}
-static long long NativeBN_longInt(JNIEnv* env, jclass, jlong a0) {
+static jlong NativeBN_longInt(JNIEnv* env, jclass, jlong a0) {
if (!oneValidHandle(env, a0)) return -1;
+
BIGNUM* a = toBigNum(a0);
bn_check_top(a);
- int intLen = a->top;
- BN_ULONG* d = a->d;
- switch (intLen) {
- case 0:
- return 0;
- case 1:
- if (!a->neg) {
- return d[0] & 0X00000000FFFFFFFFLL;
- } else {
- return -(d[0] & 0X00000000FFFFFFFFLL);
- }
- default:
- if (!a->neg) {
- return ((long long)d[1] << 32) | (d[0] & 0XFFFFFFFFLL);
- } else {
- return -(((long long)d[1] << 32) | (d[0] & 0XFFFFFFFFLL));
- }
+ int wLen = a->top;
+ if (wLen == 0) {
+ return 0;
+ }
+
+#ifdef __LP64__
+ jlong result = a->d[0];
+#else
+ jlong result = static_cast<jlong>(a->d[0]) & 0xffffffff;
+ if (wLen > 1) {
+ result |= static_cast<jlong>(a->d[1]) << 32;
}
+#endif
+ return a->neg ? -result : result;
}
static char* leadingZerosTrimmed(char* s) {
@@ -368,11 +390,11 @@ static jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass, jlong a0) {
if (!oneValidHandle(env, a0)) return NULL;
BIGNUM* a = toBigNum(a0);
bn_check_top(a);
- int len = a->top;
- if (len == 0) {
+ int wLen = a->top;
+ if (wLen == 0) {
return NULL;
}
- jintArray result = env->NewIntArray(len);
+ jintArray result = env->NewIntArray(wLen * BN_BYTES/sizeof(unsigned int));
if (result == NULL) {
return NULL;
}
@@ -380,11 +402,15 @@ static jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass, jlong a0) {
if (ints.get() == NULL) {
return NULL;
}
- BN_ULONG* ulongs = reinterpret_cast<BN_ULONG*>(ints.get());
- if (ulongs == NULL) {
+ unsigned int* uints = reinterpret_cast<unsigned int*>(ints.get());
+ if (uints == NULL) {
return NULL;
}
- int i = len; do { i--; ulongs[i] = a->d[i]; } while (i > 0);
+#ifdef __LP64__
+ int i = wLen; do { i--; uints[i*2+1] = a->d[i] >> 32; uints[i*2] = a->d[i]; } while (i > 0);
+#else
+ int i = wLen; do { i--; uints[i] = a->d[i]; } while (i > 0);
+#endif
return result;
}
@@ -404,15 +430,13 @@ static void NativeBN_BN_set_negative(JNIEnv* env, jclass, jlong b, int n) {
}
static int NativeBN_bitLength(JNIEnv* env, jclass, jlong a0) {
-// We rely on: (BN_BITS2 == 32), i.e. BN_ULONG is unsigned int and has 4 bytes:
-//
if (!oneValidHandle(env, a0)) return JNI_FALSE;
BIGNUM* a = toBigNum(a0);
bn_check_top(a);
- int intLen = a->top;
- if (intLen == 0) return 0;
+ int wLen = a->top;
+ if (wLen == 0) return 0;
BN_ULONG* d = a->d;
- int i = intLen - 1;
+ int i = wLen - 1;
BN_ULONG msd = d[i]; // most significant digit
if (a->neg) {
// Handle negative values correctly:
@@ -421,7 +445,7 @@ static int NativeBN_bitLength(JNIEnv* env, jclass, jlong a0) {
do { i--; } while (!((i < 0) || (d[i] != 0)));
if (i < 0) msd--; // Only if all lower significant digits are 0 we decrement the most significant one.
}
- return (intLen - 1) * 32 + BN_num_bits_word(msd);
+ return (wLen - 1) * BN_BYTES * 8 + BN_num_bits_word(msd);
}
static jboolean NativeBN_BN_is_bit_set(JNIEnv* env, jclass, jlong a, int n) {
diff --git a/luni/src/main/native/java_util_jar_StrictJarFile.cpp b/luni/src/main/native/java_util_jar_StrictJarFile.cpp
new file mode 100644
index 0000000..7611749
--- /dev/null
+++ b/luni/src/main/native/java_util_jar_StrictJarFile.cpp
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "StrictJarFile"
+
+#include <string>
+
+#include "JNIHelp.h"
+#include "JniConstants.h"
+#include "ScopedLocalRef.h"
+#include "ScopedUtfChars.h"
+#include "UniquePtr.h"
+#include "jni.h"
+#include "ziparchive/zip_archive.h"
+#include "cutils/log.h"
+
+static void throwIoException(JNIEnv* env, const int32_t errorCode) {
+ jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode));
+}
+
+static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName,
+ const uint16_t nameLength) {
+ ScopedLocalRef<jclass> zipEntryClass(env, env->FindClass("java/util/zip/ZipEntry"));
+ const jmethodID zipEntryCtor = env->GetMethodID(zipEntryClass.get(), "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;JJJIII[BIJJ)V");
+
+ return env->NewObject(zipEntryClass.get(),
+ zipEntryCtor,
+ entryName,
+ NULL, // comment
+ static_cast<jlong>(entry.crc32),
+ static_cast<jlong>(entry.compressed_length),
+ static_cast<jlong>(entry.uncompressed_length),
+ static_cast<jint>(entry.method),
+ static_cast<jint>(0), // time
+ static_cast<jint>(0), // modData
+ NULL, // byte[] extra
+ static_cast<jint>(nameLength),
+ static_cast<jlong>(-1), // local header offset
+ static_cast<jlong>(entry.offset));
+}
+
+static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileName) {
+ ScopedUtfChars fileChars(env, fileName);
+ if (fileChars.c_str() == NULL) {
+ return static_cast<jlong>(-1);
+ }
+
+ ZipArchiveHandle handle;
+ int32_t error = OpenArchive(fileChars.c_str(), &handle);
+ if (error) {
+ throwIoException(env, error);
+ return static_cast<jlong>(-1);
+ }
+
+ return reinterpret_cast<jlong>(handle);
+}
+
+class IterationHandle {
+ public:
+ IterationHandle(const char* prefix) :
+ cookie_(NULL), prefix_(strdup(prefix)) {
+ }
+
+ void** CookieAddress() {
+ return &cookie_;
+ }
+
+ const char* Prefix() const {
+ return prefix_;
+ }
+
+ ~IterationHandle() {
+ free(prefix_);
+ }
+
+ private:
+ void* cookie_;
+ char* prefix_;
+};
+
+
+static jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nativeHandle,
+ jstring prefix) {
+ ScopedUtfChars prefixChars(env, prefix);
+ if (prefixChars.c_str() == NULL) {
+ return static_cast<jlong>(-1);
+ }
+
+ IterationHandle* handle = new IterationHandle(prefixChars.c_str());
+ int32_t error = 0;
+ if (prefixChars.size() == 0) {
+ error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
+ handle->CookieAddress(), NULL);
+ } else {
+ error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
+ handle->CookieAddress(), handle->Prefix());
+ }
+
+ if (error) {
+ throwIoException(env, error);
+ return static_cast<jlong>(-1);
+ }
+
+ return reinterpret_cast<jlong>(handle);
+}
+
+static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterationHandle) {
+ ZipEntry data;
+ ZipEntryName entryName;
+
+ IterationHandle* handle = reinterpret_cast<IterationHandle*>(iterationHandle);
+ const int32_t error = Next(*handle->CookieAddress(), &data, &entryName);
+ if (error) {
+ delete handle;
+ return NULL;
+ }
+
+ UniquePtr<char[]> entryNameCString(new char[entryName.name_length + 1]);
+ memcpy(entryNameCString.get(), entryName.name, entryName.name_length);
+ entryNameCString[entryName.name_length] = '\0';
+ ScopedLocalRef<jstring> entryNameString(env, env->NewStringUTF(entryNameCString.get()));
+
+ return newZipEntry(env, data, entryNameString.get(), entryName.name_length);
+}
+
+static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle,
+ jstring entryName) {
+ ScopedUtfChars entryNameChars(env, entryName);
+ if (entryNameChars.c_str() == NULL) {
+ return NULL;
+ }
+
+ ZipEntry data;
+ const int32_t error = FindEntry(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
+ entryNameChars.c_str(), &data);
+ if (error) {
+ return NULL;
+ }
+
+ return newZipEntry(env, data, entryName, entryNameChars.size());
+}
+
+static void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) {
+ CloseArchive(reinterpret_cast<ZipArchiveHandle>(nativeHandle));
+}
+
+static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(StrictJarFile, nativeOpenJarFile, "(Ljava/lang/String;)J"),
+ NATIVE_METHOD(StrictJarFile, nativeStartIteration, "(JLjava/lang/String;)J"),
+ NATIVE_METHOD(StrictJarFile, nativeNextEntry, "(J)Ljava/util/zip/ZipEntry;"),
+ NATIVE_METHOD(StrictJarFile, nativeFindEntry, "(JLjava/lang/String;)Ljava/util/zip/ZipEntry;"),
+ NATIVE_METHOD(StrictJarFile, nativeClose, "(J)V"),
+};
+
+void register_java_util_jar_StrictJarFile(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "java/util/jar/StrictJarFile", gMethods, NELEM(gMethods));
+
+}
diff --git a/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp b/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp
index bb05193..e0638bd 100644
--- a/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp
+++ b/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp
@@ -20,6 +20,7 @@
#include "JNIHelp.h"
#include "JniConstants.h"
#include "JniException.h"
+#include "ScopedIcuLocale.h"
#include "ScopedJavaUnicodeString.h"
#include "unicode/alphaindex.h"
#include "unicode/uniset.h"
@@ -28,9 +29,13 @@ static AlphabeticIndex* fromPeer(jlong peer) {
return reinterpret_cast<AlphabeticIndex*>(static_cast<uintptr_t>(peer));
}
-static jlong AlphabeticIndex_create(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong AlphabeticIndex_create(JNIEnv* env, jclass, jstring javaLocaleName) {
UErrorCode status = U_ZERO_ERROR;
- AlphabeticIndex* ai = new AlphabeticIndex(getLocale(env, javaLocale), status);
+ ScopedIcuLocale icuLocale(env, javaLocaleName);
+ if (!icuLocale.valid()) {
+ return 0;
+ }
+ AlphabeticIndex* ai = new AlphabeticIndex(icuLocale.locale(), status);
if (maybeThrowIcuException(env, "AlphabeticIndex", status)) {
return 0;
}
@@ -53,10 +58,14 @@ static void AlphabeticIndex_setMaxLabelCount(JNIEnv* env, jclass, jlong peer, ji
maybeThrowIcuException(env, "AlphabeticIndex::setMaxLabelCount", status);
}
-static void AlphabeticIndex_addLabels(JNIEnv* env, jclass, jlong peer, jstring javaLocale) {
+static void AlphabeticIndex_addLabels(JNIEnv* env, jclass, jlong peer, jstring javaLocaleName) {
AlphabeticIndex* ai = fromPeer(peer);
+ ScopedIcuLocale icuLocale(env, javaLocaleName);
+ if (!icuLocale.valid()) {
+ return;
+ }
UErrorCode status = U_ZERO_ERROR;
- ai->addLabels(getLocale(env, javaLocale), status);
+ ai->addLabels(icuLocale.locale(), status);
maybeThrowIcuException(env, "AlphabeticIndex::addLabels", status);
}
diff --git a/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp b/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp
index 72bc631..a3258c1 100644
--- a/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp
+++ b/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp
@@ -18,13 +18,17 @@
#include "IcuUtilities.h"
#include "JniConstants.h"
+#include "ScopedIcuLocale.h"
#include "ScopedJavaUnicodeString.h"
#include "UniquePtr.h"
#include "cutils/log.h"
#include "unicode/dtitvfmt.h"
static jlong DateIntervalFormat_createDateIntervalFormat(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLocaleName, jstring javaTzName) {
- Locale locale = getLocale(env, javaLocaleName);
+ ScopedIcuLocale icuLocale(env, javaLocaleName);
+ if (!icuLocale.valid()) {
+ return 0;
+ }
ScopedJavaUnicodeString skeletonHolder(env, javaSkeleton);
if (!skeletonHolder.valid()) {
@@ -32,7 +36,7 @@ static jlong DateIntervalFormat_createDateIntervalFormat(JNIEnv* env, jclass, js
}
UErrorCode status = U_ZERO_ERROR;
- DateIntervalFormat* formatter(DateIntervalFormat::createInstance(skeletonHolder.unicodeString(), locale, status));
+ DateIntervalFormat* formatter(DateIntervalFormat::createInstance(skeletonHolder.unicodeString(), icuLocale.locale(), status));
if (maybeThrowIcuException(env, "DateIntervalFormat::createInstance", status)) {
return 0;
}
diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp
index 5bbb506..1528a2d 100644
--- a/luni/src/main/native/libcore_icu_ICU.cpp
+++ b/luni/src/main/native/libcore_icu_ICU.cpp
@@ -21,12 +21,14 @@
#include "JniConstants.h"
#include "JniException.h"
#include "ScopedFd.h"
+#include "ScopedIcuLocale.h"
#include "ScopedJavaUnicodeString.h"
#include "ScopedLocalRef.h"
#include "ScopedUtfChars.h"
#include "UniquePtr.h"
#include "cutils/log.h"
#include "toStringArray.h"
+#include "unicode/brkiter.h"
#include "unicode/calendar.h"
#include "unicode/datefmt.h"
#include "unicode/dcfmtsym.h"
@@ -60,6 +62,7 @@
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
+#include <vector>
// TODO: put this in a header file and use it everywhere!
// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions.
@@ -94,26 +97,23 @@ class ScopedResourceBundle {
DISALLOW_COPY_AND_ASSIGN(ScopedResourceBundle);
};
-static jstring ICU_addLikelySubtags(JNIEnv* env, jclass, jstring javaLocale) {
+static jstring ICU_addLikelySubtags(JNIEnv* env, jclass, jstring javaLocaleName) {
UErrorCode status = U_ZERO_ERROR;
- ScopedUtfChars localeID(env, javaLocale);
+ ScopedUtfChars localeID(env, javaLocaleName);
char maximizedLocaleID[ULOC_FULLNAME_CAPACITY];
uloc_addLikelySubtags(localeID.c_str(), maximizedLocaleID, sizeof(maximizedLocaleID), &status);
if (U_FAILURE(status)) {
- return javaLocale;
+ return javaLocaleName;
}
return env->NewStringUTF(maximizedLocaleID);
}
-static jstring ICU_getScript(JNIEnv* env, jclass, jstring javaLocale) {
- UErrorCode status = U_ZERO_ERROR;
- ScopedUtfChars localeID(env, javaLocale);
- char script[ULOC_SCRIPT_CAPACITY];
- uloc_getScript(localeID.c_str(), script, sizeof(script), &status);
- if (U_FAILURE(status)) {
- return NULL;
- }
- return env->NewStringUTF(script);
+static jstring ICU_getScript(JNIEnv* env, jclass, jstring javaLocaleName) {
+ ScopedIcuLocale icuLocale(env, javaLocaleName);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
+ return env->NewStringUTF(icuLocale.locale().getScript());
}
static jint ICU_getCurrencyFractionDigits(JNIEnv* env, jclass, jstring javaCurrencyCode) {
@@ -126,6 +126,15 @@ static jint ICU_getCurrencyFractionDigits(JNIEnv* env, jclass, jstring javaCurre
return ucurr_getDefaultFractionDigits(icuCurrencyCode.getTerminatedBuffer(), &status);
}
+static jint ICU_getCurrencyNumericCode(JNIEnv* env, jclass, jstring javaCurrencyCode) {
+ ScopedJavaUnicodeString currencyCode(env, javaCurrencyCode);
+ if (!currencyCode.valid()) {
+ return 0;
+ }
+ UnicodeString icuCurrencyCode(currencyCode.unicodeString());
+ return ucurr_getNumericCode(icuCurrencyCode.getTerminatedBuffer());
+}
+
// TODO: rewrite this with int32_t ucurr_forLocale(const char* locale, UChar* buff, int32_t buffCapacity, UErrorCode* ec)...
static jstring ICU_getCurrencyCode(JNIEnv* env, jclass, jstring javaCountryCode) {
UErrorCode status = U_ZERO_ERROR;
@@ -169,9 +178,9 @@ static jstring ICU_getCurrencyCode(JNIEnv* env, jclass, jstring javaCountryCode)
return (charCount == 0) ? env->NewStringUTF("XXX") : env->NewString(chars, charCount);
}
-static jstring getCurrencyName(JNIEnv* env, jstring javaLocaleName, jstring javaCurrencyCode, UCurrNameStyle nameStyle) {
- ScopedUtfChars localeName(env, javaLocaleName);
- if (localeName.c_str() == NULL) {
+static jstring getCurrencyName(JNIEnv* env, jstring javaLanguageTag, jstring javaCurrencyCode, UCurrNameStyle nameStyle) {
+ ScopedUtfChars languageTag(env, javaLanguageTag);
+ if (languageTag.c_str() == NULL) {
return NULL;
}
ScopedJavaUnicodeString currencyCode(env, javaCurrencyCode);
@@ -182,7 +191,7 @@ static jstring getCurrencyName(JNIEnv* env, jstring javaLocaleName, jstring java
UErrorCode status = U_ZERO_ERROR;
UBool isChoiceFormat = false;
int32_t charCount;
- const UChar* chars = ucurr_getName(icuCurrencyCode.getTerminatedBuffer(), localeName.c_str(),
+ const UChar* chars = ucurr_getName(icuCurrencyCode.getTerminatedBuffer(), languageTag.c_str(),
nameStyle, &isChoiceFormat, &charCount, &status);
if (status == U_USING_DEFAULT_WARNING) {
if (nameStyle == UCURR_SYMBOL_NAME) {
@@ -201,46 +210,88 @@ static jstring getCurrencyName(JNIEnv* env, jstring javaLocaleName, jstring java
return (charCount == 0) ? NULL : env->NewString(chars, charCount);
}
-static jstring ICU_getCurrencyDisplayName(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaCurrencyCode) {
- return getCurrencyName(env, javaLocaleName, javaCurrencyCode, UCURR_LONG_NAME);
+static jstring ICU_getCurrencyDisplayName(JNIEnv* env, jclass, jstring javaLanguageTag, jstring javaCurrencyCode) {
+ return getCurrencyName(env, javaLanguageTag, javaCurrencyCode, UCURR_LONG_NAME);
}
-static jstring ICU_getCurrencySymbol(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaCurrencyCode) {
- return getCurrencyName(env, javaLocaleName, javaCurrencyCode, UCURR_SYMBOL_NAME);
+static jstring ICU_getCurrencySymbol(JNIEnv* env, jclass, jstring javaLanguageTag, jstring javaCurrencyCode) {
+ return getCurrencyName(env, javaLanguageTag, javaCurrencyCode, UCURR_SYMBOL_NAME);
}
-static jstring ICU_getDisplayCountryNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
- Locale loc = getLocale(env, locale);
- Locale targetLoc = getLocale(env, targetLocale);
- UnicodeString str;
- targetLoc.getDisplayCountry(loc, str);
- return env->NewString(str.getBuffer(), str.length());
+static jstring ICU_getDisplayCountryNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) {
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
+ ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag);
+ if (!icuTargetLocale.valid()) {
+ return NULL;
+ }
+
+ UnicodeString str;
+ icuTargetLocale.locale().getDisplayCountry(icuLocale.locale(), str);
+ return env->NewString(str.getBuffer(), str.length());
}
-static jstring ICU_getDisplayLanguageNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
- Locale loc = getLocale(env, locale);
- Locale targetLoc = getLocale(env, targetLocale);
- UnicodeString str;
- targetLoc.getDisplayLanguage(loc, str);
- return env->NewString(str.getBuffer(), str.length());
+static jstring ICU_getDisplayLanguageNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) {
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
+ ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag);
+ if (!icuTargetLocale.valid()) {
+ return NULL;
+ }
+
+ UnicodeString str;
+ icuTargetLocale.locale().getDisplayLanguage(icuLocale.locale(), str);
+ return env->NewString(str.getBuffer(), str.length());
}
-static jstring ICU_getDisplayVariantNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
- Locale loc = getLocale(env, locale);
- Locale targetLoc = getLocale(env, targetLocale);
- UnicodeString str;
- targetLoc.getDisplayVariant(loc, str);
- return env->NewString(str.getBuffer(), str.length());
+static jstring ICU_getDisplayScriptNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) {
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
+ ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag);
+ if (!icuTargetLocale.valid()) {
+ return NULL;
+ }
+
+ UnicodeString str;
+ icuTargetLocale.locale().getDisplayScript(icuLocale.locale(), str);
+ return env->NewString(str.getBuffer(), str.length());
}
-static jstring ICU_getISO3CountryNative(JNIEnv* env, jclass, jstring locale) {
- Locale loc = getLocale(env, locale);
- return env->NewStringUTF(loc.getISO3Country());
+static jstring ICU_getDisplayVariantNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) {
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
+ ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag);
+ if (!icuTargetLocale.valid()) {
+ return NULL;
+ }
+
+ UnicodeString str;
+ icuTargetLocale.locale().getDisplayVariant(icuLocale.locale(), str);
+ return env->NewString(str.getBuffer(), str.length());
}
-static jstring ICU_getISO3LanguageNative(JNIEnv* env, jclass, jstring locale) {
- Locale loc = getLocale(env, locale);
- return env->NewStringUTF(loc.getISO3Language());
+static jstring ICU_getISO3Country(JNIEnv* env, jclass, jstring javaLanguageTag) {
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
+ return env->NewStringUTF(icuLocale.locale().getISO3Country());
+}
+
+static jstring ICU_getISO3Language(JNIEnv* env, jclass, jstring javaLanguageTag) {
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
+ return env->NewStringUTF(icuLocale.locale().getISO3Language());
}
static jobjectArray ICU_getISOCountriesNative(JNIEnv* env, jclass) {
@@ -318,17 +369,6 @@ static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, URes
}
}
-static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, UResourceBundle* bundle, const char* key) {
- UErrorCode status = U_ZERO_ERROR;
- int charCount;
- const UChar* chars = ures_getStringByKey(bundle, key, &charCount, &status);
- if (U_SUCCESS(status)) {
- setStringField(env, obj, fieldName, env->NewString(chars, charCount));
- } else {
- ALOGE("Error setting String field %s from ICU resource (key %s): %s", fieldName, key, u_errorName(status));
- }
-}
-
static void setCharField(JNIEnv* env, jobject obj, const char* fieldName, const UnicodeString& value) {
if (value.length() == 0) {
return;
@@ -369,7 +409,7 @@ static void setDecimalFormatSymbolsData(JNIEnv* env, jobject obj, Locale& locale
setCharField(env, obj, "percent", dfs.getSymbol(DecimalFormatSymbols::kPercentSymbol));
setCharField(env, obj, "perMill", dfs.getSymbol(DecimalFormatSymbols::kPerMillSymbol));
setCharField(env, obj, "monetarySeparator", dfs.getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
- setCharField(env, obj, "minusSign", dfs.getSymbol(DecimalFormatSymbols:: kMinusSignSymbol));
+ setStringField(env, obj, "minusSign", dfs.getSymbol(DecimalFormatSymbols:: kMinusSignSymbol));
setStringField(env, obj, "exponentSeparator", dfs.getSymbol(DecimalFormatSymbols::kExponentialSymbol));
setStringField(env, obj, "infinity", dfs.getSymbol(DecimalFormatSymbols::kInfinitySymbol));
setStringField(env, obj, "NaN", dfs.getSymbol(DecimalFormatSymbols::kNaNSymbol));
@@ -410,6 +450,29 @@ class LocaleNameIterator {
DISALLOW_COPY_AND_ASSIGN(LocaleNameIterator);
};
+static bool getAmPmMarkersNarrow(JNIEnv* env, jobject localeData, const char* locale_name) {
+ UErrorCode status = U_ZERO_ERROR;
+ ScopedResourceBundle root(ures_open(NULL, locale_name, &status));
+ if (U_FAILURE(status)) {
+ return false;
+ }
+ ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status));
+ if (U_FAILURE(status)) {
+ return false;
+ }
+ ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status));
+ if (U_FAILURE(status)) {
+ return false;
+ }
+ ScopedResourceBundle amPmMarkersNarrow(ures_getByKey(gregorian.get(), "AmPmMarkersNarrow", NULL, &status));
+ if (U_FAILURE(status)) {
+ return false;
+ }
+ setStringField(env, localeData, "narrowAm", amPmMarkersNarrow.get(), 0);
+ setStringField(env, localeData, "narrowPm", amPmMarkersNarrow.get(), 1);
+ return true;
+}
+
static bool getDateTimePatterns(JNIEnv* env, jobject localeData, const char* locale_name) {
UErrorCode status = U_ZERO_ERROR;
ScopedResourceBundle root(ures_open(NULL, locale_name, &status));
@@ -439,73 +502,96 @@ static bool getDateTimePatterns(JNIEnv* env, jobject localeData, const char* loc
return true;
}
-static bool getYesterdayTodayAndTomorrow(JNIEnv* env, jobject localeData, const char* locale_name) {
+static bool getYesterdayTodayAndTomorrow(JNIEnv* env, jobject localeData, const Locale& locale, const char* locale_name) {
UErrorCode status = U_ZERO_ERROR;
ScopedResourceBundle root(ures_open(NULL, locale_name, &status));
- if (U_FAILURE(status)) {
- return false;
- }
ScopedResourceBundle fields(ures_getByKey(root.get(), "fields", NULL, &status));
+ ScopedResourceBundle day(ures_getByKey(fields.get(), "day", NULL, &status));
+ ScopedResourceBundle relative(ures_getByKey(day.get(), "relative", NULL, &status));
if (U_FAILURE(status)) {
return false;
}
- ScopedResourceBundle day(ures_getByKey(fields.get(), "day", NULL, &status));
+
+ UnicodeString yesterday(ures_getUnicodeStringByKey(relative.get(), "-1", &status));
+ UnicodeString today(ures_getUnicodeStringByKey(relative.get(), "0", &status));
+ UnicodeString tomorrow(ures_getUnicodeStringByKey(relative.get(), "1", &status));
if (U_FAILURE(status)) {
+ ALOGE("Error getting yesterday/today/tomorrow for %s: %s", locale_name, u_errorName(status));
return false;
}
- ScopedResourceBundle relative(ures_getByKey(day.get(), "relative", NULL, &status));
+
+ // We title-case the strings so they have consistent capitalization (http://b/14493853).
+ UniquePtr<BreakIterator> brk(BreakIterator::createSentenceInstance(locale, status));
if (U_FAILURE(status)) {
+ ALOGE("Error getting yesterday/today/tomorrow break iterator for %s: %s", locale_name, u_errorName(status));
return false;
}
- // bn_BD only has a "-2" entry.
- if (relative.hasKey("-1") && relative.hasKey("0") && relative.hasKey("1")) {
- setStringField(env, localeData, "yesterday", relative.get(), "-1");
- setStringField(env, localeData, "today", relative.get(), "0");
- setStringField(env, localeData, "tomorrow", relative.get(), "1");
- return true;
- }
- return false;
+ yesterday.toTitle(brk.get(), locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
+ today.toTitle(brk.get(), locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
+ tomorrow.toTitle(brk.get(), locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
+
+ setStringField(env, localeData, "yesterday", yesterday);
+ setStringField(env, localeData, "today", today);
+ setStringField(env, localeData, "tomorrow", tomorrow);
+ return true;
}
-static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLocaleName, jobject localeData) {
- ScopedUtfChars localeName(env, javaLocaleName);
- if (localeName.c_str() == NULL) {
+static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLanguageTag, jobject localeData) {
+ ScopedUtfChars languageTag(env, javaLanguageTag);
+ if (languageTag.c_str() == NULL) {
return JNI_FALSE;
}
- if (localeName.size() >= ULOC_FULLNAME_CAPACITY) {
+ if (languageTag.size() >= ULOC_FULLNAME_CAPACITY) {
return JNI_FALSE; // ICU has a fixed-length limit.
}
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return JNI_FALSE;
+ }
+
// Get the DateTimePatterns.
UErrorCode status = U_ZERO_ERROR;
bool foundDateTimePatterns = false;
- for (LocaleNameIterator it(localeName.c_str(), status); it.HasNext(); it.Up()) {
+ for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
if (getDateTimePatterns(env, localeData, it.Get())) {
foundDateTimePatterns = true;
break;
}
}
if (!foundDateTimePatterns) {
- ALOGE("Couldn't find ICU DateTimePatterns for %s", localeName.c_str());
+ ALOGE("Couldn't find ICU DateTimePatterns for %s", languageTag.c_str());
return JNI_FALSE;
}
// Get the "Yesterday", "Today", and "Tomorrow" strings.
bool foundYesterdayTodayAndTomorrow = false;
- for (LocaleNameIterator it(localeName.c_str(), status); it.HasNext(); it.Up()) {
- if (getYesterdayTodayAndTomorrow(env, localeData, it.Get())) {
+ for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
+ if (getYesterdayTodayAndTomorrow(env, localeData, icuLocale.locale(), it.Get())) {
foundYesterdayTodayAndTomorrow = true;
break;
}
}
if (!foundYesterdayTodayAndTomorrow) {
- ALOGE("Couldn't find ICU yesterday/today/tomorrow for %s", localeName.c_str());
+ ALOGE("Couldn't find ICU yesterday/today/tomorrow for %s", languageTag.c_str());
+ return JNI_FALSE;
+ }
+
+ // Get the narrow "AM" and "PM" strings.
+ bool foundAmPmMarkersNarrow = false;
+ for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
+ if (getAmPmMarkersNarrow(env, localeData, it.Get())) {
+ foundAmPmMarkersNarrow = true;
+ break;
+ }
+ }
+ if (!foundAmPmMarkersNarrow) {
+ ALOGE("Couldn't find ICU AmPmMarkersNarrow for %s", languageTag.c_str());
return JNI_FALSE;
}
status = U_ZERO_ERROR;
- Locale locale = getLocale(env, javaLocaleName);
- UniquePtr<Calendar> cal(Calendar::createInstance(locale, status));
+ UniquePtr<Calendar> cal(Calendar::createInstance(icuLocale.locale(), status));
if (U_FAILURE(status)) {
return JNI_FALSE;
}
@@ -515,7 +601,7 @@ static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLocale
// Get DateFormatSymbols.
status = U_ZERO_ERROR;
- DateFormatSymbols dateFormatSym(locale, status);
+ DateFormatSymbols dateFormatSym(icuLocale.locale(), status);
if (U_FAILURE(status)) {
return JNI_FALSE;
}
@@ -568,17 +654,17 @@ static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLocale
status = U_ZERO_ERROR;
// For numberPatterns and symbols.
- setNumberPatterns(env, localeData, locale);
- setDecimalFormatSymbolsData(env, localeData, locale);
+ setNumberPatterns(env, localeData, icuLocale.locale());
+ setDecimalFormatSymbolsData(env, localeData, icuLocale.locale());
- jstring countryCode = env->NewStringUTF(Locale::createFromName(localeName.c_str()).getCountry());
+ jstring countryCode = env->NewStringUTF(icuLocale.locale().getCountry());
jstring internationalCurrencySymbol = ICU_getCurrencyCode(env, NULL, countryCode);
env->DeleteLocalRef(countryCode);
countryCode = NULL;
jstring currencySymbol = NULL;
if (internationalCurrencySymbol != NULL) {
- currencySymbol = ICU_getCurrencySymbol(env, NULL, javaLocaleName, internationalCurrencySymbol);
+ currencySymbol = ICU_getCurrencySymbol(env, NULL, javaLanguageTag, internationalCurrencySymbol);
} else {
internationalCurrencySymbol = env->NewStringUTF("XXX");
}
@@ -592,25 +678,33 @@ static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLocale
return JNI_TRUE;
}
-static jstring ICU_toLowerCase(JNIEnv* env, jclass, jstring javaString, jstring localeName) {
+static jstring ICU_toLowerCase(JNIEnv* env, jclass, jstring javaString, jstring javaLanguageTag) {
ScopedJavaUnicodeString scopedString(env, javaString);
if (!scopedString.valid()) {
return NULL;
}
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
UnicodeString& s(scopedString.unicodeString());
UnicodeString original(s);
- s.toLower(Locale::createFromName(ScopedUtfChars(env, localeName).c_str()));
+ s.toLower(icuLocale.locale());
return s == original ? javaString : env->NewString(s.getBuffer(), s.length());
}
-static jstring ICU_toUpperCase(JNIEnv* env, jclass, jstring javaString, jstring localeName) {
+static jstring ICU_toUpperCase(JNIEnv* env, jclass, jstring javaString, jstring javaLanguageTag) {
ScopedJavaUnicodeString scopedString(env, javaString);
if (!scopedString.valid()) {
return NULL;
}
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
UnicodeString& s(scopedString.unicodeString());
UnicodeString original(s);
- s.toUpper(Locale::createFromName(ScopedUtfChars(env, localeName).c_str()));
+ s.toUpper(icuLocale.locale());
return s == original ? javaString : env->NewString(s.getBuffer(), s.length());
}
@@ -645,10 +739,14 @@ static jobject ICU_getAvailableCurrencyCodes(JNIEnv* env, jclass) {
return fromStringEnumeration(env, status, "ucurr_openISOCurrencies", &e);
}
-static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLocaleName) {
- Locale locale = getLocale(env, javaLocaleName);
+static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLanguageTag) {
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return NULL;
+ }
+
UErrorCode status = U_ZERO_ERROR;
- UniquePtr<DateTimePatternGenerator> generator(DateTimePatternGenerator::createInstance(locale, status));
+ UniquePtr<DateTimePatternGenerator> generator(DateTimePatternGenerator::createInstance(icuLocale.locale(), status));
if (maybeThrowIcuException(env, "DateTimePatternGenerator::createInstance", status)) {
return NULL;
}
@@ -665,6 +763,21 @@ static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring jav
return env->NewString(result.getBuffer(), result.length());
}
+static void ICU_setDefaultLocale(JNIEnv* env, jclass, jstring javaLanguageTag) {
+ ScopedIcuLocale icuLocale(env, javaLanguageTag);
+ if (!icuLocale.valid()) {
+ return;
+ }
+
+ UErrorCode status = U_ZERO_ERROR;
+ Locale::setDefault(icuLocale.locale(), status);
+ maybeThrowIcuException(env, "Locale::setDefault", status);
+}
+
+static jstring ICU_getDefaultLocale(JNIEnv* env, jclass) {
+ return env->NewStringUTF(Locale::getDefault().getName());
+}
+
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(ICU, addLikelySubtags, "(Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(ICU, getAvailableBreakIteratorLocalesNative, "()[Ljava/lang/String;"),
@@ -679,18 +792,22 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(ICU, getCurrencyCode, "(Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(ICU, getCurrencyDisplayName, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(ICU, getCurrencyFractionDigits, "(Ljava/lang/String;)I"),
+ NATIVE_METHOD(ICU, getCurrencyNumericCode, "(Ljava/lang/String;)I"),
NATIVE_METHOD(ICU, getCurrencySymbol, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(ICU, getDefaultLocale, "()Ljava/lang/String;"),
NATIVE_METHOD(ICU, getDisplayCountryNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(ICU, getDisplayLanguageNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(ICU, getDisplayScriptNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(ICU, getDisplayVariantNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(ICU, getISO3CountryNative, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(ICU, getISO3LanguageNative, "(Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(ICU, getISO3Country, "(Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(ICU, getISO3Language, "(Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(ICU, getISOCountriesNative, "()[Ljava/lang/String;"),
NATIVE_METHOD(ICU, getISOLanguagesNative, "()[Ljava/lang/String;"),
NATIVE_METHOD(ICU, getIcuVersion, "()Ljava/lang/String;"),
NATIVE_METHOD(ICU, getScript, "(Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(ICU, getUnicodeVersion, "()Ljava/lang/String;"),
NATIVE_METHOD(ICU, initLocaleDataNative, "(Ljava/lang/String;Llibcore/icu/LocaleData;)Z"),
+ NATIVE_METHOD(ICU, setDefaultLocale, "(Ljava/lang/String;)V"),
NATIVE_METHOD(ICU, toLowerCase, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(ICU, toUpperCase, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
};
diff --git a/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp b/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp
index 5d715c9..ef0c2a9 100644
--- a/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp
+++ b/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp
@@ -20,6 +20,7 @@
#include "JNIHelp.h"
#include "JniConstants.h"
#include "JniException.h"
+#include "ScopedIcuLocale.h"
#include "ScopedUtfChars.h"
#include "unicode/brkiter.h"
#include "unicode/putil.h"
@@ -107,19 +108,18 @@ class BreakIteratorAccessor {
};
#define MAKE_BREAK_ITERATOR_INSTANCE(F) \
- UErrorCode status = U_ZERO_ERROR; \
- const ScopedUtfChars localeChars(env, javaLocale); \
- if (localeChars.c_str() == NULL) { \
+ ScopedIcuLocale icuLocale(env, javaLocaleName); \
+ if (!icuLocale.valid()) { \
return 0; \
} \
- Locale locale(Locale::createFromName(localeChars.c_str())); \
- BreakIterator* it = F(locale, status); \
+ UErrorCode status = U_ZERO_ERROR; \
+ BreakIterator* it = F(icuLocale.locale(), status); \
if (maybeThrowIcuException(env, "ubrk_open", status)) { \
return 0; \
} \
return reinterpret_cast<uintptr_t>(it)
-static jint NativeBreakIterator_cloneImpl(JNIEnv* env, jclass, jlong address) {
+static jlong NativeBreakIterator_cloneImpl(JNIEnv* env, jclass, jlong address) {
BreakIteratorAccessor it(env, address);
return reinterpret_cast<uintptr_t>(it->clone());
}
@@ -143,19 +143,19 @@ static jint NativeBreakIterator_followingImpl(JNIEnv* env, jclass, jlong address
return it->following(offset);
}
-static jint NativeBreakIterator_getCharacterInstanceImpl(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong NativeBreakIterator_getCharacterInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createCharacterInstance);
}
-static jint NativeBreakIterator_getLineInstanceImpl(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong NativeBreakIterator_getLineInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createLineInstance);
}
-static jint NativeBreakIterator_getSentenceInstanceImpl(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong NativeBreakIterator_getSentenceInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createSentenceInstance);
}
-static jint NativeBreakIterator_getWordInstanceImpl(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong NativeBreakIterator_getWordInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createWordInstance);
}
diff --git a/luni/src/main/native/libcore_icu_NativeCollation.cpp b/luni/src/main/native/libcore_icu_NativeCollation.cpp
index 9ac7745..4ce42ec 100644
--- a/luni/src/main/native/libcore_icu_NativeCollation.cpp
+++ b/luni/src/main/native/libcore_icu_NativeCollation.cpp
@@ -16,24 +16,87 @@
#include "ScopedStringChars.h"
#include "ScopedUtfChars.h"
#include "UniquePtr.h"
-#include "ucol_imp.h"
#include "unicode/ucol.h"
#include "unicode/ucoleitr.h"
+#include <cutils/log.h>
+
+// Manages a UCollationElements instance along with the jchar
+// array it is iterating over. The associated array can be unpinned
+// only after a call to ucol_closeElements. This means we have to
+// keep a reference to the string (so that it isn't collected) and
+// make a call to GetStringChars to ensure the underlying array is
+// pinned.
+class CollationElements {
+public:
+ CollationElements()
+ : mElements(NULL), mString(NULL), mChars(NULL) {
+ }
+
+ UCollationElements* get() const {
+ return mElements;
+ }
+
+ // Starts a new iteration sequence over the string |string|. If
+ // we have a valid UCollationElements object, we call ucol_setText
+ // on it. Otherwise, we create a new object with the specified
+ // collator.
+ UErrorCode start(JNIEnv* env, jstring string, UCollator* collator) {
+ release(env, false /* don't close the collator */);
+ mChars = env->GetStringChars(string, NULL);
+ if (mChars != NULL) {
+ mString = static_cast<jstring>(env->NewGlobalRef(string));
+ const size_t size = env->GetStringLength(string);
+
+ UErrorCode status = U_ZERO_ERROR;
+ // If we don't have a UCollationElements object yet, create
+ // a new one. If we do, reset it.
+ if (mElements == NULL) {
+ mElements = ucol_openElements(collator, mChars, size, &status);
+ } else {
+ ucol_setText(mElements, mChars, size, &status);
+ }
+
+ return status;
+ }
+
+ return U_ILLEGAL_ARGUMENT_ERROR;
+ }
+
+ void release(JNIEnv* env, bool closeCollator) {
+ if (mElements != NULL && closeCollator) {
+ ucol_closeElements(mElements);
+ }
+
+ if (mChars != NULL) {
+ env->ReleaseStringChars(mString, mChars);
+ env->DeleteGlobalRef(mString);
+ mChars = NULL;
+ mString = NULL;
+ }
+ }
+
+private:
+ UCollationElements* mElements;
+ jstring mString;
+ const jchar* mChars;
+};
static UCollator* toCollator(jlong address) {
return reinterpret_cast<UCollator*>(static_cast<uintptr_t>(address));
}
-static UCollationElements* toCollationElements(jlong address) {
- return reinterpret_cast<UCollationElements*>(static_cast<uintptr_t>(address));
+static CollationElements* toCollationElements(jlong address) {
+ return reinterpret_cast<CollationElements*>(static_cast<uintptr_t>(address));
}
static void NativeCollation_closeCollator(JNIEnv*, jclass, jlong address) {
ucol_close(toCollator(address));
}
-static void NativeCollation_closeElements(JNIEnv*, jclass, jlong address) {
- ucol_closeElements(toCollationElements(address));
+static void NativeCollation_closeElements(JNIEnv* env, jclass, jlong address) {
+ CollationElements* elements = toCollationElements(address);
+ elements->release(env, true /* close collator */);
+ delete elements;
}
static jint NativeCollation_compare(JNIEnv* env, jclass, jlong address, jstring javaLhs, jstring javaRhs) {
@@ -60,18 +123,23 @@ static jlong NativeCollation_getCollationElementIterator(JNIEnv* env, jclass, jl
if (source.get() == NULL) {
return -1;
}
- UErrorCode status = U_ZERO_ERROR;
- UCollationElements* result = ucol_openElements(toCollator(address), source.get(), source.size(), &status);
+
+ UniquePtr<CollationElements> ce(new CollationElements);
+ UErrorCode status = ce->start(env, javaSource, toCollator(address));
maybeThrowIcuException(env, "ucol_openElements", status);
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(result));
+ if (status == U_ZERO_ERROR) {
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(ce.release()));
+ }
+
+ return 0L;
}
static jint NativeCollation_getMaxExpansion(JNIEnv*, jclass, jlong address, jint order) {
- return ucol_getMaxExpansion(toCollationElements(address), order);
+ return ucol_getMaxExpansion(toCollationElements(address)->get(), order);
}
static jint NativeCollation_getOffset(JNIEnv*, jclass, jlong address) {
- return ucol_getOffset(toCollationElements(address));
+ return ucol_getOffset(toCollationElements(address)->get());
}
static jstring NativeCollation_getRules(JNIEnv* env, jclass, jlong address) {
@@ -86,7 +154,8 @@ static jbyteArray NativeCollation_getSortKey(JNIEnv* env, jclass, jlong address,
return NULL;
}
const UCollator* collator = toCollator(address);
- uint8_t byteArray[UCOL_MAX_BUFFER * 2];
+ // The buffer size prevents reallocation for most strings.
+ uint8_t byteArray[128];
UniquePtr<uint8_t[]> largerByteArray;
uint8_t* usedByteArray = byteArray;
size_t byteArraySize = ucol_getSortKey(collator, source.get(), source.size(), usedByteArray, sizeof(byteArray) - 1);
@@ -106,16 +175,17 @@ static jbyteArray NativeCollation_getSortKey(JNIEnv* env, jclass, jlong address,
static jint NativeCollation_next(JNIEnv* env, jclass, jlong address) {
UErrorCode status = U_ZERO_ERROR;
- jint result = ucol_next(toCollationElements(address), &status);
+ jint result = ucol_next(toCollationElements(address)->get(), &status);
maybeThrowIcuException(env, "ucol_next", status);
return result;
}
-static jlong NativeCollation_openCollator(JNIEnv* env, jclass, jstring localeName) {
- ScopedUtfChars localeChars(env, localeName);
+static jlong NativeCollation_openCollator(JNIEnv* env, jclass, jstring javaLocaleName) {
+ ScopedUtfChars localeChars(env, javaLocaleName);
if (localeChars.c_str() == NULL) {
return 0;
}
+
UErrorCode status = U_ZERO_ERROR;
UCollator* c = ucol_open(localeChars.c_str(), &status);
maybeThrowIcuException(env, "ucol_open", status);
@@ -136,19 +206,18 @@ static jlong NativeCollation_openCollatorFromRules(JNIEnv* env, jclass, jstring
static jint NativeCollation_previous(JNIEnv* env, jclass, jlong address) {
UErrorCode status = U_ZERO_ERROR;
- jint result = ucol_previous(toCollationElements(address), &status);
+ jint result = ucol_previous(toCollationElements(address)->get(), &status);
maybeThrowIcuException(env, "ucol_previous", status);
return result;
}
static void NativeCollation_reset(JNIEnv*, jclass, jlong address) {
- ucol_reset(toCollationElements(address));
+ ucol_reset(toCollationElements(address)->get());
}
static jlong NativeCollation_safeClone(JNIEnv* env, jclass, jlong address) {
UErrorCode status = U_ZERO_ERROR;
- jint bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
- UCollator* c = ucol_safeClone(toCollator(address), NULL, &bufferSize, &status);
+ UCollator* c = ucol_safeClone(toCollator(address), NULL, NULL, &status);
maybeThrowIcuException(env, "ucol_safeClone", status);
return static_cast<jlong>(reinterpret_cast<uintptr_t>(c));
}
@@ -161,7 +230,7 @@ static void NativeCollation_setAttribute(JNIEnv* env, jclass, jlong address, jin
static void NativeCollation_setOffset(JNIEnv* env, jclass, jlong address, jint offset) {
UErrorCode status = U_ZERO_ERROR;
- ucol_setOffset(toCollationElements(address), offset, &status);
+ ucol_setOffset(toCollationElements(address)->get(), offset, &status);
maybeThrowIcuException(env, "ucol_setOffset", status);
}
@@ -170,8 +239,7 @@ static void NativeCollation_setText(JNIEnv* env, jclass, jlong address, jstring
if (source.get() == NULL) {
return;
}
- UErrorCode status = U_ZERO_ERROR;
- ucol_setText(toCollationElements(address), source.get(), source.size(), &status);
+ UErrorCode status = toCollationElements(address)->start(env, javaSource, NULL);
maybeThrowIcuException(env, "ucol_setText", status);
}
@@ -180,7 +248,7 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(NativeCollation, closeElements, "(J)V"),
NATIVE_METHOD(NativeCollation, compare, "(JLjava/lang/String;Ljava/lang/String;)I"),
NATIVE_METHOD(NativeCollation, getAttribute, "(JI)I"),
- NATIVE_METHOD(NativeCollation, getCollationElementIterator, "(JLjava/lang/String;)I"),
+ NATIVE_METHOD(NativeCollation, getCollationElementIterator, "(JLjava/lang/String;)J"),
NATIVE_METHOD(NativeCollation, getMaxExpansion, "(JI)I"),
NATIVE_METHOD(NativeCollation, getOffset, "(J)I"),
NATIVE_METHOD(NativeCollation, getRules, "(J)Ljava/lang/String;"),
diff --git a/luni/src/main/native/libcore_icu_NativeConverter.cpp b/luni/src/main/native/libcore_icu_NativeConverter.cpp
index 137e172..8dd439a 100644
--- a/luni/src/main/native/libcore_icu_NativeConverter.cpp
+++ b/luni/src/main/native/libcore_icu_NativeConverter.cpp
@@ -214,10 +214,11 @@ static jint NativeConverter_encode(JNIEnv* env, jclass, jlong address,
UErrorCode errorCode = U_ZERO_ERROR;
ucnv_fromUnicode(cnv , &cTarget, cTargetLimit, &mySource, mySourceLimit, NULL, (UBool) flush, &errorCode);
*sourceOffset = (mySource - uSource.get()) - *sourceOffset;
- *targetOffset = (reinterpret_cast<jbyte*>(cTarget) - uTarget.get()) - *targetOffset;
+ *targetOffset = (reinterpret_cast<jbyte*>(cTarget) - uTarget.get());
// If there was an error, count the problematic characters.
- if (errorCode == U_ILLEGAL_CHAR_FOUND || errorCode == U_INVALID_CHAR_FOUND) {
+ if (errorCode == U_ILLEGAL_CHAR_FOUND || errorCode == U_INVALID_CHAR_FOUND ||
+ errorCode == U_TRUNCATED_CHAR_FOUND) {
int8_t invalidUCharCount = 32;
UChar invalidUChars[32];
UErrorCode minorErrorCode = U_ZERO_ERROR;
@@ -272,7 +273,8 @@ static jint NativeConverter_decode(JNIEnv* env, jclass, jlong address,
*targetOffset = cTarget - uTarget.get() - *targetOffset;
// If there was an error, count the problematic bytes.
- if (errorCode == U_ILLEGAL_CHAR_FOUND || errorCode == U_INVALID_CHAR_FOUND) {
+ if (errorCode == U_ILLEGAL_CHAR_FOUND || errorCode == U_INVALID_CHAR_FOUND ||
+ errorCode == U_TRUNCATED_CHAR_FOUND) {
int8_t invalidByteCount = 32;
char invalidBytes[32] = {'\0'};
UErrorCode minorErrorCode = U_ZERO_ERROR;
diff --git a/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp b/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp
index 88e6780..c0fd42b 100644
--- a/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp
+++ b/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp
@@ -16,25 +16,28 @@
#define LOG_TAG "NativeDecimalFormat"
+#include <stdlib.h>
+#include <string.h>
+
+#include <vector>
+
+#include "cutils/log.h"
+#include "digitlst.h"
#include "IcuUtilities.h"
-#include "JNIHelp.h"
#include "JniConstants.h"
#include "JniException.h"
+#include "JNIHelp.h"
#include "ScopedJavaUnicodeString.h"
#include "ScopedPrimitiveArray.h"
#include "ScopedStringChars.h"
#include "ScopedUtfChars.h"
-#include "UniquePtr.h"
-#include "cutils/log.h"
-#include "digitlst.h"
#include "unicode/decimfmt.h"
#include "unicode/fmtable.h"
#include "unicode/numfmt.h"
#include "unicode/unum.h"
#include "unicode/ustring.h"
+#include "UniquePtr.h"
#include "valueOf.h"
-#include <stdlib.h>
-#include <string.h>
static DecimalFormat* toDecimalFormat(jlong addr) {
return reinterpret_cast<DecimalFormat*>(static_cast<uintptr_t>(addr));
@@ -47,7 +50,7 @@ static UNumberFormat* toUNumberFormat(jlong addr) {
static DecimalFormatSymbols* makeDecimalFormatSymbols(JNIEnv* env,
jstring currencySymbol0, jchar decimalSeparator, jchar digit, jstring exponentSeparator0,
jchar groupingSeparator0, jstring infinity0,
- jstring internationalCurrencySymbol0, jchar minusSign,
+ jstring internationalCurrencySymbol0, jstring minusSign0,
jchar monetaryDecimalSeparator, jstring nan0, jchar patternSeparator,
jchar percent, jchar perMill, jchar zeroDigit) {
ScopedJavaUnicodeString currencySymbol(env, currencySymbol0);
@@ -55,6 +58,7 @@ static DecimalFormatSymbols* makeDecimalFormatSymbols(JNIEnv* env,
ScopedJavaUnicodeString infinity(env, infinity0);
ScopedJavaUnicodeString internationalCurrencySymbol(env, internationalCurrencySymbol0);
ScopedJavaUnicodeString nan(env, nan0);
+ ScopedJavaUnicodeString minusSign(env, minusSign0);
UnicodeString groupingSeparator(groupingSeparator0);
DecimalFormatSymbols* result = new DecimalFormatSymbols;
@@ -66,7 +70,7 @@ static DecimalFormatSymbols* makeDecimalFormatSymbols(JNIEnv* env,
result->setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, groupingSeparator);
result->setSymbol(DecimalFormatSymbols::kInfinitySymbol, infinity.unicodeString());
result->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, internationalCurrencySymbol.unicodeString());
- result->setSymbol(DecimalFormatSymbols::kMinusSignSymbol, UnicodeString(minusSign));
+ result->setSymbol(DecimalFormatSymbols::kMinusSignSymbol, minusSign.unicodeString());
result->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, UnicodeString(monetaryDecimalSeparator));
result->setSymbol(DecimalFormatSymbols::kNaNSymbol, nan.unicodeString());
result->setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, UnicodeString(patternSeparator));
@@ -90,7 +94,7 @@ static DecimalFormatSymbols* makeDecimalFormatSymbols(JNIEnv* env,
static void NativeDecimalFormat_setDecimalFormatSymbols(JNIEnv* env, jclass, jlong addr,
jstring currencySymbol, jchar decimalSeparator, jchar digit, jstring exponentSeparator,
jchar groupingSeparator, jstring infinity,
- jstring internationalCurrencySymbol, jchar minusSign,
+ jstring internationalCurrencySymbol, jstring minusSign,
jchar monetaryDecimalSeparator, jstring nan, jchar patternSeparator,
jchar percent, jchar perMill, jchar zeroDigit) {
DecimalFormatSymbols* symbols = makeDecimalFormatSymbols(env,
@@ -104,7 +108,7 @@ static void NativeDecimalFormat_setDecimalFormatSymbols(JNIEnv* env, jclass, jlo
static jlong NativeDecimalFormat_open(JNIEnv* env, jclass, jstring pattern0,
jstring currencySymbol, jchar decimalSeparator, jchar digit, jstring exponentSeparator,
jchar groupingSeparator, jstring infinity,
- jstring internationalCurrencySymbol, jchar minusSign,
+ jstring internationalCurrencySymbol, jstring minusSign,
jchar monetaryDecimalSeparator, jstring nan, jchar patternSeparator,
jchar percent, jchar perMill, jchar zeroDigit) {
UErrorCode status = U_ZERO_ERROR;
@@ -216,56 +220,69 @@ static jstring NativeDecimalFormat_toPatternImpl(JNIEnv* env, jclass, jlong addr
return env->NewString(pattern.getBuffer(), pattern.length());
}
-static jcharArray formatResult(JNIEnv* env, const UnicodeString &str, FieldPositionIterator* fpi, jobject fpIter) {
+static jcharArray formatResult(JNIEnv* env, const UnicodeString& s, FieldPositionIterator* fpi, jobject javaFieldPositionIterator) {
static jmethodID gFPI_setData = env->GetMethodID(JniConstants::fieldPositionIteratorClass, "setData", "([I)V");
if (fpi != NULL) {
- int len = fpi->getData(NULL, 0);
- jintArray data = NULL;
- if (len) {
- data = env->NewIntArray(len);
- ScopedIntArrayRW ints(env, data);
+ std::vector<int32_t> data;
+ FieldPosition fp;
+ while (fpi->next(fp)) {
+ data.push_back(fp.getField());
+ data.push_back(fp.getBeginIndex());
+ data.push_back(fp.getEndIndex());
+ }
+
+ jintArray javaData = NULL;
+ if (!data.empty()) {
+ javaData = env->NewIntArray(data.size());
+ if (javaData == NULL) {
+ return NULL;
+ }
+ ScopedIntArrayRW ints(env, javaData);
if (ints.get() == NULL) {
return NULL;
}
- fpi->getData(ints.get(), len);
+ memcpy(ints.get(), &data[0], data.size() * sizeof(int32_t));
}
- env->CallVoidMethod(fpIter, gFPI_setData, data);
+ env->CallVoidMethod(javaFieldPositionIterator, gFPI_setData, javaData);
}
- jcharArray result = env->NewCharArray(str.length());
+ jcharArray result = env->NewCharArray(s.length());
if (result != NULL) {
- env->SetCharArrayRegion(result, 0, str.length(), str.getBuffer());
+ env->SetCharArrayRegion(result, 0, s.length(), s.getBuffer());
}
return result;
}
template <typename T>
-static jcharArray format(JNIEnv* env, jlong addr, jobject fpIter, T val) {
+static jcharArray format(JNIEnv* env, jlong addr, jobject javaFieldPositionIterator, T value) {
UErrorCode status = U_ZERO_ERROR;
- UnicodeString str;
+ UnicodeString s;
DecimalFormat* fmt = toDecimalFormat(addr);
- FieldPositionIterator fpi;
- FieldPositionIterator* pfpi = fpIter ? &fpi : NULL;
- fmt->format(val, str, pfpi, status);
- return formatResult(env, str, pfpi, fpIter);
+ FieldPositionIterator nativeFieldPositionIterator;
+ FieldPositionIterator* fpi = javaFieldPositionIterator ? &nativeFieldPositionIterator : NULL;
+ fmt->format(value, s, fpi, status);
+ if (maybeThrowIcuException(env, "DecimalFormat::format", status)) {
+ return NULL;
+ }
+ return formatResult(env, s, fpi, javaFieldPositionIterator);
}
-static jcharArray NativeDecimalFormat_formatLong(JNIEnv* env, jclass, jlong addr, jlong value, jobject fpIter) {
- return format(env, addr, fpIter, value);
+static jcharArray NativeDecimalFormat_formatLong(JNIEnv* env, jclass, jlong addr, jlong value, jobject javaFieldPositionIterator) {
+ return format<int64_t>(env, addr, javaFieldPositionIterator, value);
}
-static jcharArray NativeDecimalFormat_formatDouble(JNIEnv* env, jclass, jlong addr, jdouble value, jobject fpIter) {
- return format(env, addr, fpIter, value);
+static jcharArray NativeDecimalFormat_formatDouble(JNIEnv* env, jclass, jlong addr, jdouble value, jobject javaFieldPositionIterator) {
+ return format<double>(env, addr, javaFieldPositionIterator, value);
}
-static jcharArray NativeDecimalFormat_formatDigitList(JNIEnv* env, jclass, jlong addr, jstring value, jobject fpIter) {
+static jcharArray NativeDecimalFormat_formatDigitList(JNIEnv* env, jclass, jlong addr, jstring value, jobject javaFieldPositionIterator) {
ScopedUtfChars chars(env, value);
if (chars.c_str() == NULL) {
return NULL;
}
StringPiece sp(chars.c_str());
- return format(env, addr, fpIter, sp);
+ return format(env, addr, javaFieldPositionIterator, sp);
}
static jobject newBigDecimal(JNIEnv* env, const char* value, jsize len) {
@@ -287,6 +304,11 @@ static jobject NativeDecimalFormat_parse(JNIEnv* env, jclass, jlong addr, jstrin
static jmethodID gPP_setIndex = env->GetMethodID(JniConstants::parsePositionClass, "setIndex", "(I)V");
static jmethodID gPP_setErrorIndex = env->GetMethodID(JniConstants::parsePositionClass, "setErrorIndex", "(I)V");
+ ScopedJavaUnicodeString src(env, text);
+ if (!src.valid()) {
+ return NULL;
+ }
+
// make sure the ParsePosition is valid. Actually icu4c would parse a number
// correctly even if the parsePosition is set to -1, but since the RI fails
// for that case we have to fail too
@@ -297,10 +319,6 @@ static jobject NativeDecimalFormat_parse(JNIEnv* env, jclass, jlong addr, jstrin
Formattable res;
ParsePosition pp(parsePos);
- ScopedJavaUnicodeString src(env, text);
- if (!src.valid()) {
- return NULL;
- }
DecimalFormat* fmt = toDecimalFormat(addr);
fmt->parse(src.unicodeString(), res, pp);
@@ -350,10 +368,10 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(NativeDecimalFormat, formatDigitList, "(JLjava/lang/String;Llibcore/icu/NativeDecimalFormat$FieldPositionIterator;)[C"),
NATIVE_METHOD(NativeDecimalFormat, getAttribute, "(JI)I"),
NATIVE_METHOD(NativeDecimalFormat, getTextAttribute, "(JI)Ljava/lang/String;"),
- NATIVE_METHOD(NativeDecimalFormat, open, "(Ljava/lang/String;Ljava/lang/String;CCLjava/lang/String;CLjava/lang/String;Ljava/lang/String;CCLjava/lang/String;CCCC)J"),
+ NATIVE_METHOD(NativeDecimalFormat, open, "(Ljava/lang/String;Ljava/lang/String;CCLjava/lang/String;CLjava/lang/String;Ljava/lang/String;Ljava/lang/String;CLjava/lang/String;CCCC)J"),
NATIVE_METHOD(NativeDecimalFormat, parse, "(JLjava/lang/String;Ljava/text/ParsePosition;Z)Ljava/lang/Number;"),
NATIVE_METHOD(NativeDecimalFormat, setAttribute, "(JII)V"),
- NATIVE_METHOD(NativeDecimalFormat, setDecimalFormatSymbols, "(JLjava/lang/String;CCLjava/lang/String;CLjava/lang/String;Ljava/lang/String;CCLjava/lang/String;CCCC)V"),
+ NATIVE_METHOD(NativeDecimalFormat, setDecimalFormatSymbols, "(JLjava/lang/String;CCLjava/lang/String;CLjava/lang/String;Ljava/lang/String;Ljava/lang/String;CLjava/lang/String;CCCC)V"),
NATIVE_METHOD(NativeDecimalFormat, setRoundingMode, "(JID)V"),
NATIVE_METHOD(NativeDecimalFormat, setSymbol, "(JILjava/lang/String;)V"),
NATIVE_METHOD(NativeDecimalFormat, setTextAttribute, "(JILjava/lang/String;)V"),
diff --git a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
index 8c8682a..a7c9098 100644
--- a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
+++ b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
@@ -20,6 +20,7 @@
#include "JNIHelp.h"
#include "JniConstants.h"
#include "JniException.h"
+#include "ScopedIcuLocale.h"
#include "ScopedJavaUnicodeString.h"
#include "ScopedLocalRef.h"
#include "ScopedUtfChars.h"
@@ -43,7 +44,7 @@ static bool isUtc(const UnicodeString& id) {
id == kUct || id == kUtc || id == kUniversal || id == kZulu;
}
-static void setStringArrayElement(JNIEnv* env, jobjectArray array, int i, const UnicodeString& s) {
+static bool setStringArrayElement(JNIEnv* env, jobjectArray array, int i, const UnicodeString& s) {
// Fill in whatever we got. We don't use the display names if they're "GMT[+-]xx:xx"
// because icu4c doesn't use the up-to-date time zone transition data, so it gets these
// wrong. TimeZone.getDisplayName creates accurate names on demand.
@@ -51,15 +52,22 @@ static void setStringArrayElement(JNIEnv* env, jobjectArray array, int i, const
static const UnicodeString kGmt("GMT", 3, US_INV);
if (!s.isBogus() && !s.startsWith(kGmt)) {
ScopedLocalRef<jstring> javaString(env, env->NewString(s.getBuffer(), s.length()));
+ if (javaString.get() == NULL) {
+ return false;
+ }
env->SetObjectArrayElement(array, i, javaString.get());
}
+ return true;
}
-static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring localeName, jobjectArray result) {
- Locale locale = getLocale(env, localeName);
+static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring javaLocaleName, jobjectArray result) {
+ ScopedIcuLocale icuLocale(env, javaLocaleName);
+ if (!icuLocale.valid()) {
+ return;
+ }
UErrorCode status = U_ZERO_ERROR;
- UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(locale, status));
+ UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(icuLocale.locale(), status));
if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) {
return;
}
@@ -67,7 +75,6 @@ static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring localeNam
const UDate now(Calendar::getNow());
static const UnicodeString kUtc("UTC", 3, US_INV);
- static const UnicodeString pacific_apia("Pacific/Apia", 12, US_INV);
size_t id_count = env->GetArrayLength(result);
for (size_t i = 0; i < id_count; ++i) {
@@ -96,22 +103,45 @@ static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring localeNam
// every language).
// TODO: check CLDR doesn't actually have this somewhere.
long_std = short_std = long_dst = short_dst = kUtc;
- } else if (zone_id.unicodeString() == pacific_apia) {
- // icu4c 50 doesn't know Samoa has DST yet. http://b/7955614
- if (long_dst.isBogus()) {
- long_dst = "Samoa Daylight Time";
- }
}
- setStringArrayElement(env, java_row.get(), 1, long_std);
- setStringArrayElement(env, java_row.get(), 2, short_std);
- setStringArrayElement(env, java_row.get(), 3, long_dst);
- setStringArrayElement(env, java_row.get(), 4, short_dst);
+ bool okay =
+ setStringArrayElement(env, java_row.get(), 1, long_std) &&
+ setStringArrayElement(env, java_row.get(), 2, short_std) &&
+ setStringArrayElement(env, java_row.get(), 3, long_dst) &&
+ setStringArrayElement(env, java_row.get(), 4, short_dst);
+ if (!okay) {
+ return;
+ }
+ }
+}
+
+static jstring TimeZoneNames_getExemplarLocation(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaTz) {
+ ScopedIcuLocale icuLocale(env, javaLocaleName);
+ if (!icuLocale.valid()) {
+ return NULL;
}
+
+ UErrorCode status = U_ZERO_ERROR;
+ UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(icuLocale.locale(), status));
+ if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) {
+ return NULL;
+ }
+
+ ScopedJavaUnicodeString tz(env, javaTz);
+ if (!tz.valid()) {
+ return NULL;
+ }
+
+ UnicodeString s;
+ const UDate now(Calendar::getNow());
+ names->getDisplayName(tz.unicodeString(), UTZNM_EXEMPLAR_LOCATION, now, s);
+ return env->NewString(s.getBuffer(), s.length());
}
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(TimeZoneNames, fillZoneStrings, "(Ljava/lang/String;[[Ljava/lang/String;)V"),
+ NATIVE_METHOD(TimeZoneNames, getExemplarLocation, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
};
void register_libcore_icu_TimeZoneNames(JNIEnv* env) {
jniRegisterNativeMethods(env, "libcore/icu/TimeZoneNames", gMethods, NELEM(gMethods));
diff --git a/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp b/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
index 4f50ce5..a27e7b8 100644
--- a/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
+++ b/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
@@ -16,20 +16,20 @@
#define LOG_TAG "AsynchronousCloseMonitor"
-#include "AsynchronousSocketCloseMonitor.h"
+#include "AsynchronousCloseMonitor.h"
#include "JNIHelp.h"
#include "JniConstants.h"
#include "jni.h"
static void AsynchronousCloseMonitor_signalBlockedThreads(JNIEnv* env, jclass, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
- AsynchronousSocketCloseMonitor::signalBlockedThreads(fd);
+ AsynchronousCloseMonitor::signalBlockedThreads(fd);
}
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(AsynchronousCloseMonitor, signalBlockedThreads, "(Ljava/io/FileDescriptor;)V"),
};
void register_libcore_io_AsynchronousCloseMonitor(JNIEnv* env) {
- AsynchronousSocketCloseMonitor::init();
+ AsynchronousCloseMonitor::init();
jniRegisterNativeMethods(env, "libcore/io/AsynchronousCloseMonitor", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/main/native/libcore_io_Memory.cpp b/luni/src/main/native/libcore_io_Memory.cpp
index 77aef5b..9edbfb8 100644
--- a/luni/src/main/native/libcore_io_Memory.cpp
+++ b/luni/src/main/native/libcore_io_Memory.cpp
@@ -38,8 +38,8 @@
#define LONG_ALIGNMENT_MASK 0x7
#define INT_ALIGNMENT_MASK 0x3
#define SHORT_ALIGNMENT_MASK 0x1
-#elif defined(__i386__) || defined(__x86_64__)
-// x86 can load anything at any alignment.
+#elif defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+// These architectures can load anything at any alignment.
#define LONG_ALIGNMENT_MASK 0x0
#define INT_ALIGNMENT_MASK 0x0
#define SHORT_ALIGNMENT_MASK 0x0
@@ -259,37 +259,23 @@ static void Memory_pokeShortArray(JNIEnv* env, jclass, jlong dstAddress, jshortA
POKER(jshort, Short, jshort, swapShorts);
}
-static jshort Memory_peekShort(JNIEnv*, jclass, jlong srcAddress, jboolean swap) {
- jshort result = *cast<const jshort*>(srcAddress);
- if (swap) {
- result = bswap_16(result);
- }
- return result;
+static jshort Memory_peekShortNative(JNIEnv*, jclass, jlong srcAddress) {
+ return *cast<const jshort*>(srcAddress);
}
-static void Memory_pokeShort(JNIEnv*, jclass, jlong dstAddress, jshort value, jboolean swap) {
- if (swap) {
- value = bswap_16(value);
- }
+static void Memory_pokeShortNative(JNIEnv*, jclass, jlong dstAddress, jshort value) {
*cast<jshort*>(dstAddress) = value;
}
-static jint Memory_peekInt(JNIEnv*, jclass, jlong srcAddress, jboolean swap) {
- jint result = *cast<const jint*>(srcAddress);
- if (swap) {
- result = bswap_32(result);
- }
- return result;
+static jint Memory_peekIntNative(JNIEnv*, jclass, jlong srcAddress) {
+ return *cast<const jint*>(srcAddress);
}
-static void Memory_pokeInt(JNIEnv*, jclass, jlong dstAddress, jint value, jboolean swap) {
- if (swap) {
- value = bswap_32(value);
- }
+static void Memory_pokeIntNative(JNIEnv*, jclass, jlong dstAddress, jint value) {
*cast<jint*>(dstAddress) = value;
}
-static jlong Memory_peekLong(JNIEnv*, jclass, jlong srcAddress, jboolean swap) {
+static jlong Memory_peekLongNative(JNIEnv*, jclass, jlong srcAddress) {
jlong result;
const jlong* src = cast<const jlong*>(srcAddress);
if ((srcAddress & LONG_ALIGNMENT_MASK) == 0) {
@@ -297,17 +283,11 @@ static jlong Memory_peekLong(JNIEnv*, jclass, jlong srcAddress, jboolean swap) {
} else {
result = get_unaligned<jlong>(src);
}
- if (swap) {
- result = bswap_64(result);
- }
return result;
}
-static void Memory_pokeLong(JNIEnv*, jclass, jlong dstAddress, jlong value, jboolean swap) {
+static void Memory_pokeLongNative(JNIEnv*, jclass, jlong dstAddress, jlong value) {
jlong* dst = cast<jlong*>(dstAddress);
- if (swap) {
- value = bswap_64(value);
- }
if ((dstAddress & LONG_ALIGNMENT_MASK) == 0) {
*dst = value;
} else {
@@ -378,22 +358,22 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Memory, peekCharArray, "(J[CIIZ)V"),
NATIVE_METHOD(Memory, peekDoubleArray, "(J[DIIZ)V"),
NATIVE_METHOD(Memory, peekFloatArray, "(J[FIIZ)V"),
- NATIVE_METHOD(Memory, peekInt, "!(JZ)I"),
+ NATIVE_METHOD(Memory, peekIntNative, "!(J)I"),
NATIVE_METHOD(Memory, peekIntArray, "(J[IIIZ)V"),
- NATIVE_METHOD(Memory, peekLong, "!(JZ)J"),
+ NATIVE_METHOD(Memory, peekLongNative, "!(J)J"),
NATIVE_METHOD(Memory, peekLongArray, "(J[JIIZ)V"),
- NATIVE_METHOD(Memory, peekShort, "!(JZ)S"),
+ NATIVE_METHOD(Memory, peekShortNative, "!(J)S"),
NATIVE_METHOD(Memory, peekShortArray, "(J[SIIZ)V"),
NATIVE_METHOD(Memory, pokeByte, "!(JB)V"),
NATIVE_METHOD(Memory, pokeByteArray, "(J[BII)V"),
NATIVE_METHOD(Memory, pokeCharArray, "(J[CIIZ)V"),
NATIVE_METHOD(Memory, pokeDoubleArray, "(J[DIIZ)V"),
NATIVE_METHOD(Memory, pokeFloatArray, "(J[FIIZ)V"),
- NATIVE_METHOD(Memory, pokeInt, "!(JIZ)V"),
+ NATIVE_METHOD(Memory, pokeIntNative, "!(JI)V"),
NATIVE_METHOD(Memory, pokeIntArray, "(J[IIIZ)V"),
- NATIVE_METHOD(Memory, pokeLong, "!(JJZ)V"),
+ NATIVE_METHOD(Memory, pokeLongNative, "!(JJ)V"),
NATIVE_METHOD(Memory, pokeLongArray, "(J[JIIZ)V"),
- NATIVE_METHOD(Memory, pokeShort, "!(JSZ)V"),
+ NATIVE_METHOD(Memory, pokeShortNative, "!(JS)V"),
NATIVE_METHOD(Memory, pokeShortArray, "(J[SIIZ)V"),
NATIVE_METHOD(Memory, unsafeBulkGet, "(Ljava/lang/Object;II[BIIZ)V"),
NATIVE_METHOD(Memory, unsafeBulkPut, "([BIILjava/lang/Object;IIZ)V"),
diff --git a/luni/src/main/native/libcore_io_OsConstants.cpp b/luni/src/main/native/libcore_io_OsConstants.cpp
deleted file mode 100644
index 8f1f506..0000000
--- a/luni/src/main/native/libcore_io_OsConstants.cpp
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "OsConstants"
-
-#include "JNIHelp.h"
-#include "JniConstants.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <sys/capability.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <net/if.h> // After <sys/socket.h> to work around a Mac header file bug.
-
-static void initConstant(JNIEnv* env, jclass c, const char* fieldName, int value) {
- jfieldID field = env->GetStaticFieldID(c, fieldName, "I");
- env->SetStaticIntField(c, field, value);
-}
-
-static void OsConstants_initConstants(JNIEnv* env, jclass c) {
- initConstant(env, c, "AF_INET", AF_INET);
- initConstant(env, c, "AF_INET6", AF_INET6);
- initConstant(env, c, "AF_UNIX", AF_UNIX);
- initConstant(env, c, "AF_UNSPEC", AF_UNSPEC);
- initConstant(env, c, "AI_ADDRCONFIG", AI_ADDRCONFIG);
- initConstant(env, c, "AI_ALL", AI_ALL);
- initConstant(env, c, "AI_CANONNAME", AI_CANONNAME);
- initConstant(env, c, "AI_NUMERICHOST", AI_NUMERICHOST);
-#if defined(AI_NUMERICSERV)
- initConstant(env, c, "AI_NUMERICSERV", AI_NUMERICSERV);
-#endif
- initConstant(env, c, "AI_PASSIVE", AI_PASSIVE);
- initConstant(env, c, "AI_V4MAPPED", AI_V4MAPPED);
- initConstant(env, c, "CAP_AUDIT_CONTROL", CAP_AUDIT_CONTROL);
- initConstant(env, c, "CAP_AUDIT_WRITE", CAP_AUDIT_WRITE);
- initConstant(env, c, "CAP_CHOWN", CAP_CHOWN);
- initConstant(env, c, "CAP_DAC_OVERRIDE", CAP_DAC_OVERRIDE);
- initConstant(env, c, "CAP_DAC_READ_SEARCH", CAP_DAC_READ_SEARCH);
- initConstant(env, c, "CAP_FOWNER", CAP_FOWNER);
- initConstant(env, c, "CAP_FSETID", CAP_FSETID);
- initConstant(env, c, "CAP_IPC_LOCK", CAP_IPC_LOCK);
- initConstant(env, c, "CAP_IPC_OWNER", CAP_IPC_OWNER);
- initConstant(env, c, "CAP_KILL", CAP_KILL);
- initConstant(env, c, "CAP_LAST_CAP", CAP_LAST_CAP);
- initConstant(env, c, "CAP_LEASE", CAP_LEASE);
- initConstant(env, c, "CAP_LINUX_IMMUTABLE", CAP_LINUX_IMMUTABLE);
- initConstant(env, c, "CAP_MAC_ADMIN", CAP_MAC_ADMIN);
- initConstant(env, c, "CAP_MAC_OVERRIDE", CAP_MAC_OVERRIDE);
- initConstant(env, c, "CAP_MKNOD", CAP_MKNOD);
- initConstant(env, c, "CAP_NET_ADMIN", CAP_NET_ADMIN);
- initConstant(env, c, "CAP_NET_BIND_SERVICE", CAP_NET_BIND_SERVICE);
- initConstant(env, c, "CAP_NET_BROADCAST", CAP_NET_BROADCAST);
- initConstant(env, c, "CAP_NET_RAW", CAP_NET_RAW);
- initConstant(env, c, "CAP_SETFCAP", CAP_SETFCAP);
- initConstant(env, c, "CAP_SETGID", CAP_SETGID);
- initConstant(env, c, "CAP_SETPCAP", CAP_SETPCAP);
- initConstant(env, c, "CAP_SETUID", CAP_SETUID);
- initConstant(env, c, "CAP_SYS_ADMIN", CAP_SYS_ADMIN);
- initConstant(env, c, "CAP_SYS_BOOT", CAP_SYS_BOOT);
- initConstant(env, c, "CAP_SYS_CHROOT", CAP_SYS_CHROOT);
- initConstant(env, c, "CAP_SYSLOG", CAP_SYSLOG);
- initConstant(env, c, "CAP_SYS_MODULE", CAP_SYS_MODULE);
- initConstant(env, c, "CAP_SYS_NICE", CAP_SYS_NICE);
- initConstant(env, c, "CAP_SYS_PACCT", CAP_SYS_PACCT);
- initConstant(env, c, "CAP_SYS_PTRACE", CAP_SYS_PTRACE);
- initConstant(env, c, "CAP_SYS_RAWIO", CAP_SYS_RAWIO);
- initConstant(env, c, "CAP_SYS_RESOURCE", CAP_SYS_RESOURCE);
- initConstant(env, c, "CAP_SYS_TIME", CAP_SYS_TIME);
- initConstant(env, c, "CAP_SYS_TTY_CONFIG", CAP_SYS_TTY_CONFIG);
- initConstant(env, c, "CAP_WAKE_ALARM", CAP_WAKE_ALARM);
- initConstant(env, c, "E2BIG", E2BIG);
- initConstant(env, c, "EACCES", EACCES);
- initConstant(env, c, "EADDRINUSE", EADDRINUSE);
- initConstant(env, c, "EADDRNOTAVAIL", EADDRNOTAVAIL);
- initConstant(env, c, "EAFNOSUPPORT", EAFNOSUPPORT);
- initConstant(env, c, "EAGAIN", EAGAIN);
- initConstant(env, c, "EAI_AGAIN", EAI_AGAIN);
- initConstant(env, c, "EAI_BADFLAGS", EAI_BADFLAGS);
- initConstant(env, c, "EAI_FAIL", EAI_FAIL);
- initConstant(env, c, "EAI_FAMILY", EAI_FAMILY);
- initConstant(env, c, "EAI_MEMORY", EAI_MEMORY);
- initConstant(env, c, "EAI_NODATA", EAI_NODATA);
- initConstant(env, c, "EAI_NONAME", EAI_NONAME);
-#if defined(EAI_OVERFLOW)
- initConstant(env, c, "EAI_OVERFLOW", EAI_OVERFLOW);
-#endif
- initConstant(env, c, "EAI_SERVICE", EAI_SERVICE);
- initConstant(env, c, "EAI_SOCKTYPE", EAI_SOCKTYPE);
- initConstant(env, c, "EAI_SYSTEM", EAI_SYSTEM);
- initConstant(env, c, "EALREADY", EALREADY);
- initConstant(env, c, "EBADF", EBADF);
- initConstant(env, c, "EBADMSG", EBADMSG);
- initConstant(env, c, "EBUSY", EBUSY);
- initConstant(env, c, "ECANCELED", ECANCELED);
- initConstant(env, c, "ECHILD", ECHILD);
- initConstant(env, c, "ECONNABORTED", ECONNABORTED);
- initConstant(env, c, "ECONNREFUSED", ECONNREFUSED);
- initConstant(env, c, "ECONNRESET", ECONNRESET);
- initConstant(env, c, "EDEADLK", EDEADLK);
- initConstant(env, c, "EDESTADDRREQ", EDESTADDRREQ);
- initConstant(env, c, "EDOM", EDOM);
- initConstant(env, c, "EDQUOT", EDQUOT);
- initConstant(env, c, "EEXIST", EEXIST);
- initConstant(env, c, "EFAULT", EFAULT);
- initConstant(env, c, "EFBIG", EFBIG);
- initConstant(env, c, "EHOSTUNREACH", EHOSTUNREACH);
- initConstant(env, c, "EIDRM", EIDRM);
- initConstant(env, c, "EILSEQ", EILSEQ);
- initConstant(env, c, "EINPROGRESS", EINPROGRESS);
- initConstant(env, c, "EINTR", EINTR);
- initConstant(env, c, "EINVAL", EINVAL);
- initConstant(env, c, "EIO", EIO);
- initConstant(env, c, "EISCONN", EISCONN);
- initConstant(env, c, "EISDIR", EISDIR);
- initConstant(env, c, "ELOOP", ELOOP);
- initConstant(env, c, "EMFILE", EMFILE);
- initConstant(env, c, "EMLINK", EMLINK);
- initConstant(env, c, "EMSGSIZE", EMSGSIZE);
- initConstant(env, c, "EMULTIHOP", EMULTIHOP);
- initConstant(env, c, "ENAMETOOLONG", ENAMETOOLONG);
- initConstant(env, c, "ENETDOWN", ENETDOWN);
- initConstant(env, c, "ENETRESET", ENETRESET);
- initConstant(env, c, "ENETUNREACH", ENETUNREACH);
- initConstant(env, c, "ENFILE", ENFILE);
- initConstant(env, c, "ENOBUFS", ENOBUFS);
- initConstant(env, c, "ENODATA", ENODATA);
- initConstant(env, c, "ENODEV", ENODEV);
- initConstant(env, c, "ENOENT", ENOENT);
- initConstant(env, c, "ENOEXEC", ENOEXEC);
- initConstant(env, c, "ENOLCK", ENOLCK);
- initConstant(env, c, "ENOLINK", ENOLINK);
- initConstant(env, c, "ENOMEM", ENOMEM);
- initConstant(env, c, "ENOMSG", ENOMSG);
- initConstant(env, c, "ENOPROTOOPT", ENOPROTOOPT);
- initConstant(env, c, "ENOSPC", ENOSPC);
- initConstant(env, c, "ENOSR", ENOSR);
- initConstant(env, c, "ENOSTR", ENOSTR);
- initConstant(env, c, "ENOSYS", ENOSYS);
- initConstant(env, c, "ENOTCONN", ENOTCONN);
- initConstant(env, c, "ENOTDIR", ENOTDIR);
- initConstant(env, c, "ENOTEMPTY", ENOTEMPTY);
- initConstant(env, c, "ENOTSOCK", ENOTSOCK);
- initConstant(env, c, "ENOTSUP", ENOTSUP);
- initConstant(env, c, "ENOTTY", ENOTTY);
- initConstant(env, c, "ENXIO", ENXIO);
- initConstant(env, c, "EOPNOTSUPP", EOPNOTSUPP);
- initConstant(env, c, "EOVERFLOW", EOVERFLOW);
- initConstant(env, c, "EPERM", EPERM);
- initConstant(env, c, "EPIPE", EPIPE);
- initConstant(env, c, "EPROTO", EPROTO);
- initConstant(env, c, "EPROTONOSUPPORT", EPROTONOSUPPORT);
- initConstant(env, c, "EPROTOTYPE", EPROTOTYPE);
- initConstant(env, c, "ERANGE", ERANGE);
- initConstant(env, c, "EROFS", EROFS);
- initConstant(env, c, "ESPIPE", ESPIPE);
- initConstant(env, c, "ESRCH", ESRCH);
- initConstant(env, c, "ESTALE", ESTALE);
- initConstant(env, c, "ETIME", ETIME);
- initConstant(env, c, "ETIMEDOUT", ETIMEDOUT);
- initConstant(env, c, "ETXTBSY", ETXTBSY);
-#if EWOULDBLOCK != EAGAIN
-#error EWOULDBLOCK != EAGAIN
-#endif
- initConstant(env, c, "EXDEV", EXDEV);
- initConstant(env, c, "EXIT_FAILURE", EXIT_FAILURE);
- initConstant(env, c, "EXIT_SUCCESS", EXIT_SUCCESS);
- initConstant(env, c, "FD_CLOEXEC", FD_CLOEXEC);
- initConstant(env, c, "FIONREAD", FIONREAD);
- initConstant(env, c, "F_DUPFD", F_DUPFD);
- initConstant(env, c, "F_GETFD", F_GETFD);
- initConstant(env, c, "F_GETFL", F_GETFL);
- initConstant(env, c, "F_GETLK", F_GETLK);
-#if defined(F_GETLK64)
- initConstant(env, c, "F_GETLK64", F_GETLK64);
-#endif
- initConstant(env, c, "F_GETOWN", F_GETOWN);
- initConstant(env, c, "F_OK", F_OK);
- initConstant(env, c, "F_RDLCK", F_RDLCK);
- initConstant(env, c, "F_SETFD", F_SETFD);
- initConstant(env, c, "F_SETFL", F_SETFL);
- initConstant(env, c, "F_SETLK", F_SETLK);
-#if defined(F_SETLK64)
- initConstant(env, c, "F_SETLK64", F_SETLK64);
-#endif
- initConstant(env, c, "F_SETLKW", F_SETLKW);
-#if defined(F_SETLKW64)
- initConstant(env, c, "F_SETLKW64", F_SETLKW64);
-#endif
- initConstant(env, c, "F_SETOWN", F_SETOWN);
- initConstant(env, c, "F_UNLCK", F_UNLCK);
- initConstant(env, c, "F_WRLCK", F_WRLCK);
- initConstant(env, c, "IFF_ALLMULTI", IFF_ALLMULTI);
-#if defined(IFF_AUTOMEDIA)
- initConstant(env, c, "IFF_AUTOMEDIA", IFF_AUTOMEDIA);
-#endif
- initConstant(env, c, "IFF_BROADCAST", IFF_BROADCAST);
- initConstant(env, c, "IFF_DEBUG", IFF_DEBUG);
-#if defined(IFF_DYNAMIC)
- initConstant(env, c, "IFF_DYNAMIC", IFF_DYNAMIC);
-#endif
- initConstant(env, c, "IFF_LOOPBACK", IFF_LOOPBACK);
-#if defined(IFF_MASTER)
- initConstant(env, c, "IFF_MASTER", IFF_MASTER);
-#endif
- initConstant(env, c, "IFF_MULTICAST", IFF_MULTICAST);
- initConstant(env, c, "IFF_NOARP", IFF_NOARP);
- initConstant(env, c, "IFF_NOTRAILERS", IFF_NOTRAILERS);
- initConstant(env, c, "IFF_POINTOPOINT", IFF_POINTOPOINT);
-#if defined(IFF_PORTSEL)
- initConstant(env, c, "IFF_PORTSEL", IFF_PORTSEL);
-#endif
- initConstant(env, c, "IFF_PROMISC", IFF_PROMISC);
- initConstant(env, c, "IFF_RUNNING", IFF_RUNNING);
-#if defined(IFF_SLAVE)
- initConstant(env, c, "IFF_SLAVE", IFF_SLAVE);
-#endif
- initConstant(env, c, "IFF_UP", IFF_UP);
- initConstant(env, c, "IPPROTO_ICMP", IPPROTO_ICMP);
- initConstant(env, c, "IPPROTO_ICMPV6", IPPROTO_ICMPV6);
- initConstant(env, c, "IPPROTO_IP", IPPROTO_IP);
- initConstant(env, c, "IPPROTO_IPV6", IPPROTO_IPV6);
- initConstant(env, c, "IPPROTO_RAW", IPPROTO_RAW);
- initConstant(env, c, "IPPROTO_TCP", IPPROTO_TCP);
- initConstant(env, c, "IPPROTO_UDP", IPPROTO_UDP);
- initConstant(env, c, "IPV6_CHECKSUM", IPV6_CHECKSUM);
- initConstant(env, c, "IPV6_MULTICAST_HOPS", IPV6_MULTICAST_HOPS);
- initConstant(env, c, "IPV6_MULTICAST_IF", IPV6_MULTICAST_IF);
- initConstant(env, c, "IPV6_MULTICAST_LOOP", IPV6_MULTICAST_LOOP);
-#if defined(IPV6_RECVDSTOPTS)
- initConstant(env, c, "IPV6_RECVDSTOPTS", IPV6_RECVDSTOPTS);
-#endif
-#if defined(IPV6_RECVHOPLIMIT)
- initConstant(env, c, "IPV6_RECVHOPLIMIT", IPV6_RECVHOPLIMIT);
-#endif
-#if defined(IPV6_RECVHOPOPTS)
- initConstant(env, c, "IPV6_RECVHOPOPTS", IPV6_RECVHOPOPTS);
-#endif
-#if defined(IPV6_RECVPKTINFO)
- initConstant(env, c, "IPV6_RECVPKTINFO", IPV6_RECVPKTINFO);
-#endif
-#if defined(IPV6_RECVRTHDR)
- initConstant(env, c, "IPV6_RECVRTHDR", IPV6_RECVRTHDR);
-#endif
-#if defined(IPV6_RECVTCLASS)
- initConstant(env, c, "IPV6_RECVTCLASS", IPV6_RECVTCLASS);
-#endif
-#if defined(IPV6_TCLASS)
- initConstant(env, c, "IPV6_TCLASS", IPV6_TCLASS);
-#endif
- initConstant(env, c, "IPV6_UNICAST_HOPS", IPV6_UNICAST_HOPS);
- initConstant(env, c, "IPV6_V6ONLY", IPV6_V6ONLY);
- initConstant(env, c, "IP_MULTICAST_IF", IP_MULTICAST_IF);
- initConstant(env, c, "IP_MULTICAST_LOOP", IP_MULTICAST_LOOP);
- initConstant(env, c, "IP_MULTICAST_TTL", IP_MULTICAST_TTL);
- initConstant(env, c, "IP_TOS", IP_TOS);
- initConstant(env, c, "IP_TTL", IP_TTL);
- initConstant(env, c, "MAP_FIXED", MAP_FIXED);
- initConstant(env, c, "MAP_PRIVATE", MAP_PRIVATE);
- initConstant(env, c, "MAP_SHARED", MAP_SHARED);
-#if defined(MCAST_JOIN_GROUP)
- initConstant(env, c, "MCAST_JOIN_GROUP", MCAST_JOIN_GROUP);
-#endif
-#if defined(MCAST_LEAVE_GROUP)
- initConstant(env, c, "MCAST_LEAVE_GROUP", MCAST_LEAVE_GROUP);
-#endif
- initConstant(env, c, "MCL_CURRENT", MCL_CURRENT);
- initConstant(env, c, "MCL_FUTURE", MCL_FUTURE);
- initConstant(env, c, "MSG_CTRUNC", MSG_CTRUNC);
- initConstant(env, c, "MSG_DONTROUTE", MSG_DONTROUTE);
- initConstant(env, c, "MSG_EOR", MSG_EOR);
- initConstant(env, c, "MSG_OOB", MSG_OOB);
- initConstant(env, c, "MSG_PEEK", MSG_PEEK);
- initConstant(env, c, "MSG_TRUNC", MSG_TRUNC);
- initConstant(env, c, "MSG_WAITALL", MSG_WAITALL);
- initConstant(env, c, "MS_ASYNC", MS_ASYNC);
- initConstant(env, c, "MS_INVALIDATE", MS_INVALIDATE);
- initConstant(env, c, "MS_SYNC", MS_SYNC);
- initConstant(env, c, "NI_DGRAM", NI_DGRAM);
- initConstant(env, c, "NI_NAMEREQD", NI_NAMEREQD);
- initConstant(env, c, "NI_NOFQDN", NI_NOFQDN);
- initConstant(env, c, "NI_NUMERICHOST", NI_NUMERICHOST);
- initConstant(env, c, "NI_NUMERICSERV", NI_NUMERICSERV);
- initConstant(env, c, "O_ACCMODE", O_ACCMODE);
- initConstant(env, c, "O_APPEND", O_APPEND);
- initConstant(env, c, "O_CREAT", O_CREAT);
- initConstant(env, c, "O_EXCL", O_EXCL);
- initConstant(env, c, "O_NOCTTY", O_NOCTTY);
- initConstant(env, c, "O_NOFOLLOW", O_NOFOLLOW);
- initConstant(env, c, "O_NONBLOCK", O_NONBLOCK);
- initConstant(env, c, "O_RDONLY", O_RDONLY);
- initConstant(env, c, "O_RDWR", O_RDWR);
- initConstant(env, c, "O_SYNC", O_SYNC);
- initConstant(env, c, "O_TRUNC", O_TRUNC);
- initConstant(env, c, "O_WRONLY", O_WRONLY);
- initConstant(env, c, "POLLERR", POLLERR);
- initConstant(env, c, "POLLHUP", POLLHUP);
- initConstant(env, c, "POLLIN", POLLIN);
- initConstant(env, c, "POLLNVAL", POLLNVAL);
- initConstant(env, c, "POLLOUT", POLLOUT);
- initConstant(env, c, "POLLPRI", POLLPRI);
- initConstant(env, c, "POLLRDBAND", POLLRDBAND);
- initConstant(env, c, "POLLRDNORM", POLLRDNORM);
- initConstant(env, c, "POLLWRBAND", POLLWRBAND);
- initConstant(env, c, "POLLWRNORM", POLLWRNORM);
- initConstant(env, c, "PROT_EXEC", PROT_EXEC);
- initConstant(env, c, "PROT_NONE", PROT_NONE);
- initConstant(env, c, "PROT_READ", PROT_READ);
- initConstant(env, c, "PROT_WRITE", PROT_WRITE);
- initConstant(env, c, "R_OK", R_OK);
- initConstant(env, c, "SEEK_CUR", SEEK_CUR);
- initConstant(env, c, "SEEK_END", SEEK_END);
- initConstant(env, c, "SEEK_SET", SEEK_SET);
- initConstant(env, c, "SHUT_RD", SHUT_RD);
- initConstant(env, c, "SHUT_RDWR", SHUT_RDWR);
- initConstant(env, c, "SHUT_WR", SHUT_WR);
- initConstant(env, c, "SIGABRT", SIGABRT);
- initConstant(env, c, "SIGALRM", SIGALRM);
- initConstant(env, c, "SIGBUS", SIGBUS);
- initConstant(env, c, "SIGCHLD", SIGCHLD);
- initConstant(env, c, "SIGCONT", SIGCONT);
- initConstant(env, c, "SIGFPE", SIGFPE);
- initConstant(env, c, "SIGHUP", SIGHUP);
- initConstant(env, c, "SIGILL", SIGILL);
- initConstant(env, c, "SIGINT", SIGINT);
- initConstant(env, c, "SIGIO", SIGIO);
- initConstant(env, c, "SIGKILL", SIGKILL);
- initConstant(env, c, "SIGPIPE", SIGPIPE);
- initConstant(env, c, "SIGPROF", SIGPROF);
-#if defined(SIGPWR)
- initConstant(env, c, "SIGPWR", SIGPWR);
-#endif
- initConstant(env, c, "SIGQUIT", SIGQUIT);
-#if defined(SIGRTMAX)
- initConstant(env, c, "SIGRTMAX", SIGRTMAX);
-#endif
-#if defined(SIGRTMIN)
- initConstant(env, c, "SIGRTMIN", SIGRTMIN);
-#endif
- initConstant(env, c, "SIGSEGV", SIGSEGV);
-#if defined(SIGSTKFLT)
- initConstant(env, c, "SIGSTKFLT", SIGSTKFLT);
-#endif
- initConstant(env, c, "SIGSTOP", SIGSTOP);
- initConstant(env, c, "SIGSYS", SIGSYS);
- initConstant(env, c, "SIGTERM", SIGTERM);
- initConstant(env, c, "SIGTRAP", SIGTRAP);
- initConstant(env, c, "SIGTSTP", SIGTSTP);
- initConstant(env, c, "SIGTTIN", SIGTTIN);
- initConstant(env, c, "SIGTTOU", SIGTTOU);
- initConstant(env, c, "SIGURG", SIGURG);
- initConstant(env, c, "SIGUSR1", SIGUSR1);
- initConstant(env, c, "SIGUSR2", SIGUSR2);
- initConstant(env, c, "SIGVTALRM", SIGVTALRM);
- initConstant(env, c, "SIGWINCH", SIGWINCH);
- initConstant(env, c, "SIGXCPU", SIGXCPU);
- initConstant(env, c, "SIGXFSZ", SIGXFSZ);
- initConstant(env, c, "SIOCGIFADDR", SIOCGIFADDR);
- initConstant(env, c, "SIOCGIFBRDADDR", SIOCGIFBRDADDR);
- initConstant(env, c, "SIOCGIFDSTADDR", SIOCGIFDSTADDR);
- initConstant(env, c, "SIOCGIFNETMASK", SIOCGIFNETMASK);
- initConstant(env, c, "SOCK_DGRAM", SOCK_DGRAM);
- initConstant(env, c, "SOCK_RAW", SOCK_RAW);
- initConstant(env, c, "SOCK_SEQPACKET", SOCK_SEQPACKET);
- initConstant(env, c, "SOCK_STREAM", SOCK_STREAM);
- initConstant(env, c, "SOL_SOCKET", SOL_SOCKET);
-#if defined(SO_BINDTODEVICE)
- initConstant(env, c, "SO_BINDTODEVICE", SO_BINDTODEVICE);
-#endif
- initConstant(env, c, "SO_BROADCAST", SO_BROADCAST);
- initConstant(env, c, "SO_DEBUG", SO_DEBUG);
- initConstant(env, c, "SO_DONTROUTE", SO_DONTROUTE);
- initConstant(env, c, "SO_ERROR", SO_ERROR);
- initConstant(env, c, "SO_KEEPALIVE", SO_KEEPALIVE);
- initConstant(env, c, "SO_LINGER", SO_LINGER);
- initConstant(env, c, "SO_OOBINLINE", SO_OOBINLINE);
- initConstant(env, c, "SO_PASSCRED", SO_PASSCRED);
- initConstant(env, c, "SO_PEERCRED", SO_PEERCRED);
- initConstant(env, c, "SO_RCVBUF", SO_RCVBUF);
- initConstant(env, c, "SO_RCVLOWAT", SO_RCVLOWAT);
- initConstant(env, c, "SO_RCVTIMEO", SO_RCVTIMEO);
- initConstant(env, c, "SO_REUSEADDR", SO_REUSEADDR);
- initConstant(env, c, "SO_SNDBUF", SO_SNDBUF);
- initConstant(env, c, "SO_SNDLOWAT", SO_SNDLOWAT);
- initConstant(env, c, "SO_SNDTIMEO", SO_SNDTIMEO);
- initConstant(env, c, "SO_TYPE", SO_TYPE);
- initConstant(env, c, "STDERR_FILENO", STDERR_FILENO);
- initConstant(env, c, "STDIN_FILENO", STDIN_FILENO);
- initConstant(env, c, "STDOUT_FILENO", STDOUT_FILENO);
- initConstant(env, c, "S_IFBLK", S_IFBLK);
- initConstant(env, c, "S_IFCHR", S_IFCHR);
- initConstant(env, c, "S_IFDIR", S_IFDIR);
- initConstant(env, c, "S_IFIFO", S_IFIFO);
- initConstant(env, c, "S_IFLNK", S_IFLNK);
- initConstant(env, c, "S_IFMT", S_IFMT);
- initConstant(env, c, "S_IFREG", S_IFREG);
- initConstant(env, c, "S_IFSOCK", S_IFSOCK);
- initConstant(env, c, "S_IRGRP", S_IRGRP);
- initConstant(env, c, "S_IROTH", S_IROTH);
- initConstant(env, c, "S_IRUSR", S_IRUSR);
- initConstant(env, c, "S_IRWXG", S_IRWXG);
- initConstant(env, c, "S_IRWXO", S_IRWXO);
- initConstant(env, c, "S_IRWXU", S_IRWXU);
- initConstant(env, c, "S_ISGID", S_ISGID);
- initConstant(env, c, "S_ISUID", S_ISUID);
- initConstant(env, c, "S_ISVTX", S_ISVTX);
- initConstant(env, c, "S_IWGRP", S_IWGRP);
- initConstant(env, c, "S_IWOTH", S_IWOTH);
- initConstant(env, c, "S_IWUSR", S_IWUSR);
- initConstant(env, c, "S_IXGRP", S_IXGRP);
- initConstant(env, c, "S_IXOTH", S_IXOTH);
- initConstant(env, c, "S_IXUSR", S_IXUSR);
- initConstant(env, c, "TCP_NODELAY", TCP_NODELAY);
- initConstant(env, c, "WCONTINUED", WCONTINUED);
- initConstant(env, c, "WEXITED", WEXITED);
- initConstant(env, c, "WNOHANG", WNOHANG);
- initConstant(env, c, "WNOWAIT", WNOWAIT);
- initConstant(env, c, "WSTOPPED", WSTOPPED);
- initConstant(env, c, "WUNTRACED", WUNTRACED);
- initConstant(env, c, "W_OK", W_OK);
- initConstant(env, c, "X_OK", X_OK);
- initConstant(env, c, "_SC_2_CHAR_TERM", _SC_2_CHAR_TERM);
- initConstant(env, c, "_SC_2_C_BIND", _SC_2_C_BIND);
- initConstant(env, c, "_SC_2_C_DEV", _SC_2_C_DEV);
-#if defined(_SC_2_C_VERSION)
- initConstant(env, c, "_SC_2_C_VERSION", _SC_2_C_VERSION);
-#endif
- initConstant(env, c, "_SC_2_FORT_DEV", _SC_2_FORT_DEV);
- initConstant(env, c, "_SC_2_FORT_RUN", _SC_2_FORT_RUN);
- initConstant(env, c, "_SC_2_LOCALEDEF", _SC_2_LOCALEDEF);
- initConstant(env, c, "_SC_2_SW_DEV", _SC_2_SW_DEV);
- initConstant(env, c, "_SC_2_UPE", _SC_2_UPE);
- initConstant(env, c, "_SC_2_VERSION", _SC_2_VERSION);
- initConstant(env, c, "_SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX);
- initConstant(env, c, "_SC_AIO_MAX", _SC_AIO_MAX);
- initConstant(env, c, "_SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX);
- initConstant(env, c, "_SC_ARG_MAX", _SC_ARG_MAX);
- initConstant(env, c, "_SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO);
- initConstant(env, c, "_SC_ATEXIT_MAX", _SC_ATEXIT_MAX);
-#if defined(_SC_AVPHYS_PAGES)
- initConstant(env, c, "_SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES);
-#endif
- initConstant(env, c, "_SC_BC_BASE_MAX", _SC_BC_BASE_MAX);
- initConstant(env, c, "_SC_BC_DIM_MAX", _SC_BC_DIM_MAX);
- initConstant(env, c, "_SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX);
- initConstant(env, c, "_SC_BC_STRING_MAX", _SC_BC_STRING_MAX);
- initConstant(env, c, "_SC_CHILD_MAX", _SC_CHILD_MAX);
- initConstant(env, c, "_SC_CLK_TCK", _SC_CLK_TCK);
- initConstant(env, c, "_SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX);
- initConstant(env, c, "_SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX);
- initConstant(env, c, "_SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX);
- initConstant(env, c, "_SC_FSYNC", _SC_FSYNC);
- initConstant(env, c, "_SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX);
- initConstant(env, c, "_SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX);
- initConstant(env, c, "_SC_IOV_MAX", _SC_IOV_MAX);
- initConstant(env, c, "_SC_JOB_CONTROL", _SC_JOB_CONTROL);
- initConstant(env, c, "_SC_LINE_MAX", _SC_LINE_MAX);
- initConstant(env, c, "_SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX);
- initConstant(env, c, "_SC_MAPPED_FILES", _SC_MAPPED_FILES);
- initConstant(env, c, "_SC_MEMLOCK", _SC_MEMLOCK);
- initConstant(env, c, "_SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE);
- initConstant(env, c, "_SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION);
- initConstant(env, c, "_SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING);
- initConstant(env, c, "_SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX);
- initConstant(env, c, "_SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX);
- initConstant(env, c, "_SC_NGROUPS_MAX", _SC_NGROUPS_MAX);
- initConstant(env, c, "_SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF);
- initConstant(env, c, "_SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN);
- initConstant(env, c, "_SC_OPEN_MAX", _SC_OPEN_MAX);
- initConstant(env, c, "_SC_PAGESIZE", _SC_PAGESIZE);
- initConstant(env, c, "_SC_PAGE_SIZE", _SC_PAGE_SIZE);
- initConstant(env, c, "_SC_PASS_MAX", _SC_PASS_MAX);
-#if defined(_SC_PHYS_PAGES)
- initConstant(env, c, "_SC_PHYS_PAGES", _SC_PHYS_PAGES);
-#endif
- initConstant(env, c, "_SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO);
- initConstant(env, c, "_SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING);
- initConstant(env, c, "_SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS);
- initConstant(env, c, "_SC_RE_DUP_MAX", _SC_RE_DUP_MAX);
- initConstant(env, c, "_SC_RTSIG_MAX", _SC_RTSIG_MAX);
- initConstant(env, c, "_SC_SAVED_IDS", _SC_SAVED_IDS);
- initConstant(env, c, "_SC_SEMAPHORES", _SC_SEMAPHORES);
- initConstant(env, c, "_SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX);
- initConstant(env, c, "_SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX);
- initConstant(env, c, "_SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS);
- initConstant(env, c, "_SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX);
- initConstant(env, c, "_SC_STREAM_MAX", _SC_STREAM_MAX);
- initConstant(env, c, "_SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO);
- initConstant(env, c, "_SC_THREADS", _SC_THREADS);
- initConstant(env, c, "_SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR);
- initConstant(env, c, "_SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE);
- initConstant(env, c, "_SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS);
- initConstant(env, c, "_SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX);
- initConstant(env, c, "_SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING);
- initConstant(env, c, "_SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT);
- initConstant(env, c, "_SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT);
- initConstant(env, c, "_SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS);
- initConstant(env, c, "_SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN);
- initConstant(env, c, "_SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX);
- initConstant(env, c, "_SC_TIMERS", _SC_TIMERS);
- initConstant(env, c, "_SC_TIMER_MAX", _SC_TIMER_MAX);
- initConstant(env, c, "_SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX);
- initConstant(env, c, "_SC_TZNAME_MAX", _SC_TZNAME_MAX);
- initConstant(env, c, "_SC_VERSION", _SC_VERSION);
- initConstant(env, c, "_SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32);
- initConstant(env, c, "_SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG);
- initConstant(env, c, "_SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64);
- initConstant(env, c, "_SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG);
- initConstant(env, c, "_SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT);
- initConstant(env, c, "_SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N);
- initConstant(env, c, "_SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY);
- initConstant(env, c, "_SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME);
- initConstant(env, c, "_SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS);
- initConstant(env, c, "_SC_XOPEN_SHM", _SC_XOPEN_SHM);
- initConstant(env, c, "_SC_XOPEN_UNIX", _SC_XOPEN_UNIX);
- initConstant(env, c, "_SC_XOPEN_VERSION", _SC_XOPEN_VERSION);
- initConstant(env, c, "_SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION);
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(OsConstants, initConstants, "()V"),
-};
-void register_libcore_io_OsConstants(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/io/OsConstants", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index cf1b714..e8e8efb 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "Posix"
-#include "AsynchronousSocketCloseMonitor.h"
+#include "AsynchronousCloseMonitor.h"
#include "cutils/log.h"
#include "ExecStrings.h"
#include "JNIHelp.h"
@@ -24,13 +24,14 @@
#include "JniException.h"
#include "NetworkUtilities.h"
#include "Portability.h"
+#include "readlink.h"
+#include "../../bionic/libc/dns/include/resolv_netid.h" // For android_getaddrinfofornet.
#include "ScopedBytes.h"
#include "ScopedLocalRef.h"
#include "ScopedPrimitiveArray.h"
#include "ScopedUtfChars.h"
-#include "StaticAssert.h"
-#include "UniquePtr.h"
#include "toStringArray.h"
+#include "UniquePtr.h"
#include <arpa/inet.h>
#include <errno.h>
@@ -44,8 +45,14 @@
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
+#ifndef __APPLE__
+#include <sys/prctl.h>
+#endif
#include <sys/socket.h>
#include <sys/stat.h>
+#ifdef __APPLE__
+#include <sys/statvfs.h>
+#endif
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -55,6 +62,11 @@
#include <termios.h>
#include <unistd.h>
+
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+
#define TO_JAVA_STRING(NAME, EXP) \
jstring NAME = env->NewStringUTF(EXP); \
if (NAME == NULL) return NULL;
@@ -68,31 +80,79 @@ struct addrinfo_deleter {
};
/**
- * Used to retry networking system calls that can return EINTR. Unlike TEMP_FAILURE_RETRY,
- * this also handles the case where the reason for failure is that another thread called
- * Socket.close. This macro also throws exceptions on failure.
+ * Used to retry networking system calls that can be interrupted with a signal. Unlike
+ * TEMP_FAILURE_RETRY, this also handles the case where
+ * AsynchronousCloseMonitor::signalBlockedThreads(fd) is used to signal a close() or
+ * Thread.interrupt(). Other signals that result in an EINTR result are ignored and the system call
+ * is retried.
*
- * Returns the result of 'exp', though a Java exception will be pending if the result is -1.
+ * Returns the result of the system call though a Java exception will be pending if the result is
+ * -1: a SocketException if signaled via AsynchronousCloseMonitor, or ErrnoException for other
+ * failures.
*/
#define NET_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ...) ({ \
return_type _rc = -1; \
do { \
+ bool _wasSignaled; \
+ int _syscallErrno; \
{ \
int _fd = jniGetFDFromFileDescriptor(jni_env, java_fd); \
- AsynchronousSocketCloseMonitor _monitor(_fd); \
+ AsynchronousCloseMonitor _monitor(_fd); \
_rc = syscall_name(_fd, __VA_ARGS__); \
+ _syscallErrno = errno; \
+ _wasSignaled = _monitor.wasSignaled(); \
+ } \
+ if (_wasSignaled) { \
+ jniThrowException(jni_env, "java/net/SocketException", "Socket closed"); \
+ _rc = -1; \
+ break; \
+ } \
+ if (_rc == -1 && _syscallErrno != EINTR) { \
+ /* TODO: with a format string we could show the arguments too, like strace(1). */ \
+ throwErrnoException(jni_env, # syscall_name); \
+ break; \
} \
- if (_rc == -1) { \
- if (jniGetFDFromFileDescriptor(jni_env, java_fd) == -1) { \
- jniThrowException(jni_env, "java/net/SocketException", "Socket closed"); \
+ } while (_rc == -1); /* _syscallErrno == EINTR && !_wasSignaled */ \
+ _rc; })
+
+/**
+ * Used to retry system calls that can be interrupted with a signal. Unlike TEMP_FAILURE_RETRY, this
+ * also handles the case where AsynchronousCloseMonitor::signalBlockedThreads(fd) is used to signal
+ * a close() or Thread.interrupt(). Other signals that result in an EINTR result are ignored and the
+ * system call is retried.
+ *
+ * Returns the result of the system call though a Java exception will be pending if the result is
+ * -1: an IOException if the file descriptor is already closed, a InterruptedIOException if signaled
+ * via AsynchronousCloseMonitor, or ErrnoException for other failures.
+ */
+#define IO_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ...) ({ \
+ return_type _rc = -1; \
+ int _fd = jniGetFDFromFileDescriptor(jni_env, java_fd); \
+ if (_fd == -1) { \
+ jniThrowException(jni_env, "java/io/IOException", "File descriptor closed"); \
+ } else { \
+ do { \
+ bool _wasSignaled; \
+ int _syscallErrno; \
+ { \
+ int _fd = jniGetFDFromFileDescriptor(jni_env, java_fd); \
+ AsynchronousCloseMonitor _monitor(_fd); \
+ _rc = syscall_name(_fd, __VA_ARGS__); \
+ _syscallErrno = errno; \
+ _wasSignaled = _monitor.wasSignaled(); \
+ } \
+ if (_wasSignaled) { \
+ jniThrowException(jni_env, "java/io/InterruptedIOException", # syscall_name " interrupted"); \
+ _rc = -1; \
break; \
- } else if (errno != EINTR) { \
+ } \
+ if (_rc == -1 && _syscallErrno != EINTR) { \
/* TODO: with a format string we could show the arguments too, like strace(1). */ \
throwErrnoException(jni_env, # syscall_name); \
break; \
} \
- } \
- } while (_rc == -1); \
+ } while (_rc == -1); /* && _syscallErrno == EINTR && !_wasSignaled */ \
+ } \
_rc; })
static void throwException(JNIEnv* env, jclass exceptionClass, jmethodID ctor3, jmethodID ctor2,
@@ -281,9 +341,14 @@ static jobject makeStructTimeval(JNIEnv* env, const struct timeval& tv) {
static_cast<jlong>(tv.tv_sec), static_cast<jlong>(tv.tv_usec));
}
-static jobject makeStructUcred(JNIEnv* env, const struct ucred& u) {
+static jobject makeStructUcred(JNIEnv* env, const struct ucred& u __unused) {
+#ifdef __APPLE__
+ jniThrowException(env, "java/lang/UnsupportedOperationException", "unimplemented support for ucred on a Mac");
+ return NULL;
+#else
static jmethodID ctor = env->GetMethodID(JniConstants::structUcredClass, "<init>", "(III)V");
return env->NewObject(JniConstants::structUcredClass, ctor, u.pid, u.uid, u.gid);
+#endif
}
static jobject makeStructUtsname(JNIEnv* env, const struct utsname& buf) {
@@ -545,8 +610,7 @@ static jint Posix_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, job
lock.l_len = env->GetLongField(javaFlock, lenFid);
lock.l_pid = env->GetIntField(javaFlock, pidFid);
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
- int rc = throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd, &lock)));
+ int rc = IO_FAILURE_RETRY(env, int, fcntl, javaFd, cmd, &lock);
if (rc != -1) {
env->SetShortField(javaFlock, typeFid, lock.l_type);
env->SetShortField(javaFlock, whenceFid, lock.l_whence);
@@ -598,7 +662,8 @@ static jstring Posix_gai_strerror(JNIEnv* env, jobject, jint error) {
return env->NewStringUTF(gai_strerror(error));
}
-static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jobject javaHints) {
+static jobjectArray Posix_android_getaddrinfo(JNIEnv* env, jobject, jstring javaNode,
+ jobject javaHints, jint netId) {
ScopedUtfChars node(env, javaNode);
if (node.c_str() == NULL) {
return NULL;
@@ -618,10 +683,10 @@ static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jo
addrinfo* addressList = NULL;
errno = 0;
- int rc = getaddrinfo(node.c_str(), NULL, &hints, &addressList);
+ int rc = android_getaddrinfofornet(node.c_str(), NULL, &hints, netId, 0, &addressList);
UniquePtr<addrinfo, addrinfo_deleter> addressListDeleter(addressList);
if (rc != 0) {
- throwGaiException(env, "getaddrinfo", rc);
+ throwGaiException(env, "android_getaddrinfo", rc);
return NULL;
}
@@ -631,7 +696,7 @@ static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jo
if (ai->ai_family == AF_INET || ai->ai_family == AF_INET6) {
++addressCount;
} else {
- ALOGE("getaddrinfo unexpected ai_family %i", ai->ai_family);
+ ALOGE("android_getaddrinfo unexpected ai_family %i", ai->ai_family);
}
}
if (addressCount == 0) {
@@ -649,7 +714,7 @@ static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jo
for (addrinfo* ai = addressList; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
// Unknown address family. Skip this address.
- ALOGE("getaddrinfo unexpected ai_family %i", ai->ai_family);
+ ALOGE("android_getaddrinfo unexpected ai_family %i", ai->ai_family);
continue;
}
@@ -799,9 +864,19 @@ static jobject Posix_getsockoptUcred(JNIEnv* env, jobject, jobject javaFd, jint
return makeStructUcred(env, u);
}
-static jint Posix_gettid(JNIEnv*, jobject) {
+static jint Posix_gettid(JNIEnv* env __unused, jobject) {
+#if defined(__APPLE__)
+ uint64_t owner;
+ int rc = pthread_threadid_np(NULL, &owner); // Requires Mac OS 10.6
+ if (rc != 0) {
+ throwErrnoException(env, "gettid");
+ return 0;
+ }
+ return static_cast<jint>(owner);
+#else
// Neither bionic nor glibc exposes gettid(2).
return syscall(__NR_gettid);
+#endif
}
static jint Posix_getuid(JNIEnv*, jobject) {
@@ -875,6 +950,18 @@ static void Posix_lchown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint
throwIfMinusOne(env, "lchown", TEMP_FAILURE_RETRY(lchown(path.c_str(), uid, gid)));
}
+static void Posix_link(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
+ ScopedUtfChars oldPath(env, javaOldPath);
+ if (oldPath.c_str() == NULL) {
+ return;
+ }
+ ScopedUtfChars newPath(env, javaNewPath);
+ if (newPath.c_str() == NULL) {
+ return;
+ }
+ throwIfMinusOne(env, "link", TEMP_FAILURE_RETRY(link(oldPath.c_str(), newPath.c_str())));
+}
+
static void Posix_listen(JNIEnv* env, jobject, jobject javaFd, jint backlog) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "listen", TEMP_FAILURE_RETRY(listen(fd, backlog)));
@@ -907,6 +994,14 @@ static void Posix_mkdir(JNIEnv* env, jobject, jstring javaPath, jint mode) {
throwIfMinusOne(env, "mkdir", TEMP_FAILURE_RETRY(mkdir(path.c_str(), mode)));
}
+static void Posix_mkfifo(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return;
+ }
+ throwIfMinusOne(env, "mkfifo", TEMP_FAILURE_RETRY(mkfifo(path.c_str(), mode)));
+}
+
static void Posix_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
throwIfMinusOne(env, "mlock", TEMP_FAILURE_RETRY(mlock(ptr, byteCount)));
@@ -971,7 +1066,7 @@ static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint time
static jfieldID eventsFid = env->GetFieldID(JniConstants::structPollfdClass, "events", "S");
static jfieldID reventsFid = env->GetFieldID(JniConstants::structPollfdClass, "revents", "S");
- // Turn the Java libcore.io.StructPollfd[] into a C++ struct pollfd[].
+ // Turn the Java android.system.StructPollfd[] into a C++ struct pollfd[].
size_t arrayLength = env->GetArrayLength(javaStructs);
UniquePtr<struct pollfd[]> fds(new struct pollfd[arrayLength]);
memset(fds.get(), 0, sizeof(struct pollfd) * arrayLength);
@@ -990,11 +1085,9 @@ static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint time
++count;
}
- // Since we don't know which fds -- if any -- are sockets, be conservative and register
- // all fds for asynchronous socket close monitoring.
- std::vector<AsynchronousSocketCloseMonitor*> monitors;
+ std::vector<AsynchronousCloseMonitor*> monitors;
for (size_t i = 0; i < count; ++i) {
- monitors.push_back(new AsynchronousSocketCloseMonitor(fds[i].fd));
+ monitors.push_back(new AsynchronousCloseMonitor(fds[i].fd));
}
int rc = poll(fds.get(), count, timeoutMs);
for (size_t i = 0; i < monitors.size(); ++i) {
@@ -1005,7 +1098,7 @@ static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint time
return -1;
}
- // Update the revents fields in the Java libcore.io.StructPollfd[].
+ // Update the revents fields in the Java android.system.StructPollfd[].
for (size_t i = 0; i < count; ++i) {
ScopedLocalRef<jobject> javaStruct(env, env->GetObjectArrayElement(javaStructs, i));
if (javaStruct.get() == NULL) {
@@ -1016,13 +1109,39 @@ static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint time
return rc;
}
+static void Posix_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused,
+ jlong offset __unused, jlong length __unused) {
+#ifdef __APPLE__
+ jniThrowException(env, "java/lang/UnsupportedOperationException",
+ "fallocate doesn't exist on a Mac");
+#else
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ errno = TEMP_FAILURE_RETRY(posix_fallocate64(fd, offset, length));
+ if (errno != 0) {
+ throwErrnoException(env, "posix_fallocate");
+ }
+#endif
+}
+
+static jint Posix_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 __unused,
+ jlong arg3 __unused, jlong arg4 __unused, jlong arg5 __unused) {
+#ifdef __APPLE__
+ jniThrowException(env, "java/lang/UnsupportedOperationException", "prctl doesn't exist on a Mac");
+ return 0;
+#else
+ int result = prctl(static_cast<int>(option),
+ static_cast<unsigned long>(arg2), static_cast<unsigned long>(arg3),
+ static_cast<unsigned long>(arg4), static_cast<unsigned long>(arg5));
+ return throwIfMinusOne(env, "prctl", result);
+#endif
+}
+
static jint Posix_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
ScopedBytesRW bytes(env, javaBytes);
if (bytes.get() == NULL) {
return -1;
}
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
- return throwIfMinusOne(env, "pread", TEMP_FAILURE_RETRY(pread64(fd, bytes.get() + byteOffset, byteCount, offset)));
+ return IO_FAILURE_RETRY(env, ssize_t, pread64, javaFd, bytes.get() + byteOffset, byteCount, offset);
}
static jint Posix_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) {
@@ -1030,8 +1149,7 @@ static jint Posix_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray j
if (bytes.get() == NULL) {
return -1;
}
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
- return throwIfMinusOne(env, "pwrite", TEMP_FAILURE_RETRY(pwrite64(fd, bytes.get() + byteOffset, byteCount, offset)));
+ return IO_FAILURE_RETRY(env, ssize_t, pwrite64, javaFd, bytes.get() + byteOffset, byteCount, offset);
}
static jint Posix_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) {
@@ -1039,8 +1157,21 @@ static jint Posix_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBy
if (bytes.get() == NULL) {
return -1;
}
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
- return throwIfMinusOne(env, "read", TEMP_FAILURE_RETRY(read(fd, bytes.get() + byteOffset, byteCount)));
+ return IO_FAILURE_RETRY(env, ssize_t, read, javaFd, bytes.get() + byteOffset, byteCount);
+}
+
+static jstring Posix_readlink(JNIEnv* env, jobject, jstring javaPath) {
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return NULL;
+ }
+
+ std::string result;
+ if (!readlink(path.c_str(), result)) {
+ throwErrnoException(env, "readlink");
+ return NULL;
+ }
+ return env->NewStringUTF(result.c_str());
}
static jint Posix_readv(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
@@ -1048,8 +1179,7 @@ static jint Posix_readv(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffe
if (!ioVec.init(buffers, offsets, byteCounts)) {
return -1;
}
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
- return throwIfMinusOne(env, "readv", TEMP_FAILURE_RETRY(readv(fd, ioVec.get(), ioVec.size())));
+ return IO_FAILURE_RETRY(env, ssize_t, readv, javaFd, ioVec.get(), ioVec.size());
}
static jint Posix_recvfromBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetSocketAddress) {
@@ -1171,6 +1301,7 @@ static void Posix_setsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level
// Mac OS didn't support modern multicast APIs until 10.7.
static void Posix_setsockoptIpMreqn(JNIEnv*, jobject, jobject, jint, jint, jint) { abort(); }
static void Posix_setsockoptGroupReq(JNIEnv*, jobject, jobject, jint, jint, jobject) { abort(); }
+static void Posix_setsockoptGroupSourceReq(JNIEnv*, jobject, jobject, jint, jint, jobject) { abort(); }
#else
static void Posix_setsockoptIpMreqn(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
ip_mreqn req;
@@ -1199,6 +1330,7 @@ static void Posix_setsockoptGroupReq(JNIEnv* env, jobject, jobject javaFd, jint
if (rc == -1 && errno == EINVAL) {
// Maybe we're a 32-bit binary talking to a 64-bit kernel?
// glibc doesn't automatically handle this.
+ // http://sourceware.org/bugzilla/show_bug.cgi?id=12080
struct group_req64 {
uint32_t gr_interface;
uint32_t my_padding;
@@ -1211,6 +1343,48 @@ static void Posix_setsockoptGroupReq(JNIEnv* env, jobject, jobject javaFd, jint
}
throwIfMinusOne(env, "setsockopt", rc);
}
+
+static void Posix_setsockoptGroupSourceReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupSourceReq) {
+ socklen_t sa_len;
+ struct group_source_req req;
+ memset(&req, 0, sizeof(req));
+
+ static jfieldID gsrInterfaceFid = env->GetFieldID(JniConstants::structGroupSourceReqClass, "gsr_interface", "I");
+ req.gsr_interface = env->GetIntField(javaGroupSourceReq, gsrInterfaceFid);
+ // Get the IPv4 or IPv6 multicast address to join or leave.
+ static jfieldID gsrGroupFid = env->GetFieldID(JniConstants::structGroupSourceReqClass, "gsr_group", "Ljava/net/InetAddress;");
+ ScopedLocalRef<jobject> javaGroup(env, env->GetObjectField(javaGroupSourceReq, gsrGroupFid));
+ if (!inetAddressToSockaddrVerbatim(env, javaGroup.get(), 0, req.gsr_group, sa_len)) {
+ return;
+ }
+
+ // Get the IPv4 or IPv6 multicast address to add to the filter.
+ static jfieldID gsrSourceFid = env->GetFieldID(JniConstants::structGroupSourceReqClass, "gsr_source", "Ljava/net/InetAddress;");
+ ScopedLocalRef<jobject> javaSource(env, env->GetObjectField(javaGroupSourceReq, gsrSourceFid));
+ if (!inetAddressToSockaddrVerbatim(env, javaSource.get(), 0, req.gsr_source, sa_len)) {
+ return;
+ }
+
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ int rc = TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req)));
+ if (rc == -1 && errno == EINVAL) {
+ // Maybe we're a 32-bit binary talking to a 64-bit kernel?
+ // glibc doesn't automatically handle this.
+ // http://sourceware.org/bugzilla/show_bug.cgi?id=12080
+ struct group_source_req64 {
+ uint32_t gsr_interface;
+ uint32_t my_padding;
+ sockaddr_storage gsr_group;
+ sockaddr_storage gsr_source;
+ };
+ group_source_req64 req64;
+ req64.gsr_interface = req.gsr_interface;
+ memcpy(&req64.gsr_group, &req.gsr_group, sizeof(req.gsr_group));
+ memcpy(&req64.gsr_source, &req.gsr_source, sizeof(req.gsr_source));
+ rc = TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req64, sizeof(req64)));
+ }
+ throwIfMinusOne(env, "setsockopt", rc);
+}
#endif
static void Posix_setsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaLinger) {
@@ -1351,8 +1525,7 @@ static jint Posix_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray ja
if (bytes.get() == NULL) {
return -1;
}
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
- return throwIfMinusOne(env, "write", TEMP_FAILURE_RETRY(write(fd, bytes.get() + byteOffset, byteCount)));
+ return IO_FAILURE_RETRY(env, ssize_t, write, javaFd, bytes.get() + byteOffset, byteCount);
}
static jint Posix_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
@@ -1360,13 +1533,13 @@ static jint Posix_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buff
if (!ioVec.init(buffers, offsets, byteCounts)) {
return -1;
}
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
- return throwIfMinusOne(env, "writev", TEMP_FAILURE_RETRY(writev(fd, ioVec.get(), ioVec.size())));
+ return IO_FAILURE_RETRY(env, ssize_t, writev, javaFd, ioVec.get(), ioVec.size());
}
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, accept, "(Ljava/io/FileDescriptor;Ljava/net/InetSocketAddress;)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"),
+ NATIVE_METHOD(Posix, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
NATIVE_METHOD(Posix, chmod, "(Ljava/lang/String;I)V"),
NATIVE_METHOD(Posix, chown, "(Ljava/lang/String;II)V"),
@@ -1381,14 +1554,13 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, fchown, "(Ljava/io/FileDescriptor;II)V"),
NATIVE_METHOD(Posix, fcntlVoid, "(Ljava/io/FileDescriptor;I)I"),
NATIVE_METHOD(Posix, fcntlLong, "(Ljava/io/FileDescriptor;IJ)I"),
- NATIVE_METHOD(Posix, fcntlFlock, "(Ljava/io/FileDescriptor;ILlibcore/io/StructFlock;)I"),
+ NATIVE_METHOD(Posix, fcntlFlock, "(Ljava/io/FileDescriptor;ILandroid/system/StructFlock;)I"),
NATIVE_METHOD(Posix, fdatasync, "(Ljava/io/FileDescriptor;)V"),
- NATIVE_METHOD(Posix, fstat, "(Ljava/io/FileDescriptor;)Llibcore/io/StructStat;"),
- NATIVE_METHOD(Posix, fstatvfs, "(Ljava/io/FileDescriptor;)Llibcore/io/StructStatVfs;"),
+ NATIVE_METHOD(Posix, fstat, "(Ljava/io/FileDescriptor;)Landroid/system/StructStat;"),
+ NATIVE_METHOD(Posix, fstatvfs, "(Ljava/io/FileDescriptor;)Landroid/system/StructStatVfs;"),
NATIVE_METHOD(Posix, fsync, "(Ljava/io/FileDescriptor;)V"),
NATIVE_METHOD(Posix, ftruncate, "(Ljava/io/FileDescriptor;J)V"),
NATIVE_METHOD(Posix, gai_strerror, "(I)Ljava/lang/String;"),
- NATIVE_METHOD(Posix, getaddrinfo, "(Ljava/lang/String;Llibcore/io/StructAddrinfo;)[Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, getegid, "()I"),
NATIVE_METHOD(Posix, geteuid, "()I"),
NATIVE_METHOD(Posix, getgid, "()I"),
@@ -1397,29 +1569,31 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, getpeername, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
NATIVE_METHOD(Posix, getpid, "()I"),
NATIVE_METHOD(Posix, getppid, "()I"),
- NATIVE_METHOD(Posix, getpwnam, "(Ljava/lang/String;)Llibcore/io/StructPasswd;"),
- NATIVE_METHOD(Posix, getpwuid, "(I)Llibcore/io/StructPasswd;"),
+ NATIVE_METHOD(Posix, getpwnam, "(Ljava/lang/String;)Landroid/system/StructPasswd;"),
+ NATIVE_METHOD(Posix, getpwuid, "(I)Landroid/system/StructPasswd;"),
NATIVE_METHOD(Posix, getsockname, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
NATIVE_METHOD(Posix, getsockoptByte, "(Ljava/io/FileDescriptor;II)I"),
NATIVE_METHOD(Posix, getsockoptInAddr, "(Ljava/io/FileDescriptor;II)Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, getsockoptInt, "(Ljava/io/FileDescriptor;II)I"),
- NATIVE_METHOD(Posix, getsockoptLinger, "(Ljava/io/FileDescriptor;II)Llibcore/io/StructLinger;"),
- NATIVE_METHOD(Posix, getsockoptTimeval, "(Ljava/io/FileDescriptor;II)Llibcore/io/StructTimeval;"),
- NATIVE_METHOD(Posix, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Llibcore/io/StructUcred;"),
+ NATIVE_METHOD(Posix, getsockoptLinger, "(Ljava/io/FileDescriptor;II)Landroid/system/StructLinger;"),
+ NATIVE_METHOD(Posix, getsockoptTimeval, "(Ljava/io/FileDescriptor;II)Landroid/system/StructTimeval;"),
+ NATIVE_METHOD(Posix, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Landroid/system/StructUcred;"),
NATIVE_METHOD(Posix, gettid, "()I"),
NATIVE_METHOD(Posix, getuid, "()I"),
NATIVE_METHOD(Posix, if_indextoname, "(I)Ljava/lang/String;"),
NATIVE_METHOD(Posix, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
- NATIVE_METHOD(Posix, ioctlInt, "(Ljava/io/FileDescriptor;ILlibcore/util/MutableInt;)I"),
+ NATIVE_METHOD(Posix, ioctlInt, "(Ljava/io/FileDescriptor;ILandroid/util/MutableInt;)I"),
NATIVE_METHOD(Posix, isatty, "(Ljava/io/FileDescriptor;)Z"),
NATIVE_METHOD(Posix, kill, "(II)V"),
NATIVE_METHOD(Posix, lchown, "(Ljava/lang/String;II)V"),
+ NATIVE_METHOD(Posix, link, "(Ljava/lang/String;Ljava/lang/String;)V"),
NATIVE_METHOD(Posix, listen, "(Ljava/io/FileDescriptor;I)V"),
NATIVE_METHOD(Posix, lseek, "(Ljava/io/FileDescriptor;JI)J"),
- NATIVE_METHOD(Posix, lstat, "(Ljava/lang/String;)Llibcore/io/StructStat;"),
+ NATIVE_METHOD(Posix, lstat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
NATIVE_METHOD(Posix, mincore, "(JJ[B)V"),
NATIVE_METHOD(Posix, mkdir, "(Ljava/lang/String;I)V"),
+ NATIVE_METHOD(Posix, mkfifo, "(Ljava/lang/String;I)V"),
NATIVE_METHOD(Posix, mlock, "(JJ)V"),
NATIVE_METHOD(Posix, mmap, "(JJIILjava/io/FileDescriptor;J)J"),
NATIVE_METHOD(Posix, msync, "(JJI)V"),
@@ -1427,15 +1601,18 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, munmap, "(JJ)V"),
NATIVE_METHOD(Posix, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, pipe, "()[Ljava/io/FileDescriptor;"),
- NATIVE_METHOD(Posix, poll, "([Llibcore/io/StructPollfd;I)I"),
+ NATIVE_METHOD(Posix, poll, "([Landroid/system/StructPollfd;I)I"),
+ NATIVE_METHOD(Posix, posix_fallocate, "(Ljava/io/FileDescriptor;JJ)V"),
+ NATIVE_METHOD(Posix, prctl, "(IJJJJ)I"),
NATIVE_METHOD(Posix, preadBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
NATIVE_METHOD(Posix, pwriteBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
NATIVE_METHOD(Posix, readBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
+ NATIVE_METHOD(Posix, readlink, "(Ljava/lang/String;)Ljava/lang/String;"),
NATIVE_METHOD(Posix, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
NATIVE_METHOD(Posix, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"),
NATIVE_METHOD(Posix, remove, "(Ljava/lang/String;)V"),
NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Llibcore/util/MutableLong;J)J"),
+ NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/util/MutableLong;J)J"),
NATIVE_METHOD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
NATIVE_METHOD(Posix, setegid, "(I)V"),
NATIVE_METHOD(Posix, setenv, "(Ljava/lang/String;Ljava/lang/String;Z)V"),
@@ -1446,15 +1623,16 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, setsockoptIfreq, "(Ljava/io/FileDescriptor;IILjava/lang/String;)V"),
NATIVE_METHOD(Posix, setsockoptInt, "(Ljava/io/FileDescriptor;III)V"),
NATIVE_METHOD(Posix, setsockoptIpMreqn, "(Ljava/io/FileDescriptor;III)V"),
- NATIVE_METHOD(Posix, setsockoptGroupReq, "(Ljava/io/FileDescriptor;IILlibcore/io/StructGroupReq;)V"),
- NATIVE_METHOD(Posix, setsockoptLinger, "(Ljava/io/FileDescriptor;IILlibcore/io/StructLinger;)V"),
- NATIVE_METHOD(Posix, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILlibcore/io/StructTimeval;)V"),
+ NATIVE_METHOD(Posix, setsockoptGroupReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupReq;)V"),
+ NATIVE_METHOD(Posix, setsockoptGroupSourceReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupSourceReq;)V"),
+ NATIVE_METHOD(Posix, setsockoptLinger, "(Ljava/io/FileDescriptor;IILandroid/system/StructLinger;)V"),
+ NATIVE_METHOD(Posix, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V"),
NATIVE_METHOD(Posix, setuid, "(I)V"),
NATIVE_METHOD(Posix, shutdown, "(Ljava/io/FileDescriptor;I)V"),
NATIVE_METHOD(Posix, socket, "(III)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, socketpair, "(IIILjava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"),
- NATIVE_METHOD(Posix, stat, "(Ljava/lang/String;)Llibcore/io/StructStat;"),
- NATIVE_METHOD(Posix, statvfs, "(Ljava/lang/String;)Llibcore/io/StructStatVfs;"),
+ NATIVE_METHOD(Posix, stat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
+ NATIVE_METHOD(Posix, statvfs, "(Ljava/lang/String;)Landroid/system/StructStatVfs;"),
NATIVE_METHOD(Posix, strerror, "(I)Ljava/lang/String;"),
NATIVE_METHOD(Posix, strsignal, "(I)Ljava/lang/String;"),
NATIVE_METHOD(Posix, symlink, "(Ljava/lang/String;Ljava/lang/String;)V"),
@@ -1462,9 +1640,9 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, tcdrain, "(Ljava/io/FileDescriptor;)V"),
NATIVE_METHOD(Posix, tcsendbreak, "(Ljava/io/FileDescriptor;I)V"),
NATIVE_METHOD(Posix, umaskImpl, "(I)I"),
- NATIVE_METHOD(Posix, uname, "()Llibcore/io/StructUtsname;"),
+ NATIVE_METHOD(Posix, uname, "()Landroid/system/StructUtsname;"),
NATIVE_METHOD(Posix, unsetenv, "(Ljava/lang/String;)V"),
- NATIVE_METHOD(Posix, waitpid, "(ILlibcore/util/MutableInt;I)I"),
+ NATIVE_METHOD(Posix, waitpid, "(ILandroid/util/MutableInt;I)I"),
NATIVE_METHOD(Posix, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
NATIVE_METHOD(Posix, writev, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
};
diff --git a/luni/src/main/native/libcore_net_RawSocket.cpp b/luni/src/main/native/libcore_net_RawSocket.cpp
deleted file mode 100644
index f8a8506..0000000
--- a/luni/src/main/native/libcore_net_RawSocket.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "RawSocket"
-
-#include "AsynchronousSocketCloseMonitor.h"
-#include "cutils/log.h"
-#include "JNIHelp.h"
-#include "JniException.h"
-#include "JniConstants.h"
-#include "NetFd.h"
-#include "NetworkUtilities.h"
-#include "ScopedUtfChars.h"
-#include "ScopedPrimitiveArray.h"
-
-#include "jni.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <linux/rtnetlink.h>
-#include <net/if.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <netinet/ip.h>
-#include <linux/udp.h>
-
-union sockunion {
- sockaddr sa;
- sockaddr_ll sll;
-};
-
-/*
- * Creates a socket suitable for raw socket operations. The socket is
- * bound to the interface specified by the supplied name. The socket
- * value is placed into the supplied FileDescriptor instance.
- *
- * TODO(chesnutt): consider breaking this into pieces: create a
- * variety of constructors for different socket types, then a generic
- * setBlocking() method followed by polymorphic bind().
- */
-static void RawSocket_create(JNIEnv* env, jclass, jobject fileDescriptor,
- jshort protocolType, jstring interfaceName)
-{
-
- ScopedUtfChars ifname(env, interfaceName);
- if (ifname.c_str() == NULL) {
- return;
- }
-
- sockunion su;
- memset(&su, 0, sizeof(su));
- su.sll.sll_family = PF_PACKET;
- su.sll.sll_protocol = htons(protocolType);
- su.sll.sll_ifindex = if_nametoindex(ifname.c_str());
- int sock = socket(PF_PACKET, SOCK_DGRAM, htons(protocolType));
-
- if (sock == -1) {
- ALOGE("Can't create socket %s", strerror(errno));
- jniThrowSocketException(env, errno);
- return;
- }
-
- jniSetFileDescriptorOfFD(env, fileDescriptor, sock);
- if (!setBlocking(sock, false)) {
- ALOGE("Can't set non-blocking mode on socket %s", strerror(errno));
- jniThrowSocketException(env, errno);
- return;
- }
-
- int err = bind(sock, &su.sa, sizeof(su));
- if (err != 0) {
- ALOGE("Socket bind error %s", strerror(errno));
- jniThrowSocketException(env, errno);
- return;
- }
-}
-
-/*
- * Writes the L3 (IP) packet to the raw socket supplied in the
- * FileDescriptor instance.
- *
- * Assumes that the caller has validated the offset & byteCount values.
- */
-static int RawSocket_sendPacket(JNIEnv* env, jclass, jobject fileDescriptor,
- jstring interfaceName, jshort protocolType, jbyteArray destMac,
- jbyteArray packet, jint offset, jint byteCount)
-{
- NetFd fd(env, fileDescriptor);
-
- if (fd.isClosed()) {
- return 0;
- }
-
- ScopedUtfChars ifname(env, interfaceName);
- if (ifname.c_str() == NULL) {
- return 0;
- }
-
- ScopedByteArrayRO byteArray(env, packet);
- if (byteArray.get() == NULL) {
- return 0;
- }
-
- ScopedByteArrayRO mac(env, destMac);
- if (mac.get() == NULL) {
- return 0;
- }
-
- sockunion su;
- memset(&su, 0, sizeof(su));
- su.sll.sll_hatype = htons(1); // ARPHRD_ETHER
- su.sll.sll_halen = mac.size();
- memcpy(&su.sll.sll_addr, mac.get(), mac.size());
- su.sll.sll_family = AF_PACKET;
- su.sll.sll_protocol = htons(protocolType);
- su.sll.sll_ifindex = if_nametoindex(ifname.c_str());
-
- int err;
- {
- int intFd = fd.get();
- AsynchronousSocketCloseMonitor monitor(intFd);
- err = NET_FAILURE_RETRY(fd, sendto(intFd, byteArray.get() + offset,
- byteCount, 0, &su.sa, sizeof(su)));
- }
-
- return err;
-}
-
-/*
- * Reads a network packet into the user-supplied buffer. Return the
- * length of the packet, or a 0 if there was a timeout or an
- * unacceptable packet was acquired.
- *
- * Assumes that the caller has validated the offset & byteCount values.
- */
-static jint RawSocket_recvPacket(JNIEnv* env, jclass, jobject fileDescriptor,
- jbyteArray packet, jint offset, jint byteCount, jint port,
- jint timeout_millis)
-{
- NetFd fd(env, fileDescriptor);
- if (fd.isClosed()) {
- return 0;
- }
-
- ScopedByteArrayRW body(env, packet);
- jbyte* packetData = body.get();
- if (packetData == NULL) {
- return 0;
- }
-
- packetData += offset;
-
- pollfd fds[1];
- fds[0].fd = fd.get();
- fds[0].events = POLLIN;
- int retval = poll(fds, 1, timeout_millis);
- if (retval <= 0) {
- return 0;
- }
-
- unsigned int size = 0;
- {
- int packetSize = byteCount;
- int intFd = fd.get();
- AsynchronousSocketCloseMonitor monitor(intFd);
- size = NET_FAILURE_RETRY(fd, read(intFd, packetData, packetSize));
- }
-
- if (env->ExceptionOccurred()) {
- return 0;
- }
-
- if (port != -1) {
- // quick check for UDP type & UDP port
- // the packet is an IP header, UDP header, and UDP payload
- if ((size < (sizeof(struct iphdr) + sizeof(struct udphdr)))) {
- return 0; // runt packet
- }
-
- u_int8_t ip_proto = ((iphdr *) packetData)->protocol;
- if (ip_proto != IPPROTO_UDP) {
- return 0; // something other than UDP
- }
-
- __be16 destPort = htons((reinterpret_cast<udphdr*>(packetData + sizeof(iphdr)))->dest);
- if (destPort != port) {
- return 0; // something other than requested port
- }
- }
-
- return size;
-}
-
-static JNINativeMethod gRawMethods[] = {
- NATIVE_METHOD(RawSocket, create, "(Ljava/io/FileDescriptor;SLjava/lang/String;)V"),
- NATIVE_METHOD(RawSocket, sendPacket, "(Ljava/io/FileDescriptor;Ljava/lang/String;S[B[BII)I"),
- NATIVE_METHOD(RawSocket, recvPacket, "(Ljava/io/FileDescriptor;[BIIII)I"),
-};
-
-void register_libcore_net_RawSocket(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/net/RawSocket", gRawMethods, NELEM(gRawMethods));
-}
diff --git a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
index 6ba055a..2ea8806 100644
--- a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
+++ b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -632,7 +632,8 @@ static void startElement(void* data, const char* elementName, const char** attri
parsingContext->stringStack.push(env, uri);
parsingContext->stringStack.push(env, localName);
- env->CallVoidMethod(javaParser, startElementMethod, uri, localName, qName, attributes, count);
+ jlong attributesAddress = reinterpret_cast<jlong>(attributes);
+ env->CallVoidMethod(javaParser, startElementMethod, uri, localName, qName, attributesAddress, count);
parsingContext->attributes = NULL;
parsingContext->attributeCount = -1;
@@ -1291,7 +1292,7 @@ static void ExpatAttributes_freeAttributes(JNIEnv*, jobject, jlong pointer) {
static void ExpatParser_staticInitialize(JNIEnv* env, jobject classObject, jstring empty) {
jclass clazz = reinterpret_cast<jclass>(classObject);
startElementMethod = env->GetMethodID(clazz, "startElement",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V");
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JI)V");
if (startElementMethod == NULL) return;
endElementMethod = env->GetMethodID(clazz, "endElement",
diff --git a/luni/src/main/native/realpath.cpp b/luni/src/main/native/realpath.cpp
deleted file mode 100644
index d1960a4..0000000
--- a/luni/src/main/native/realpath.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The names of the authors may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "readlink.h"
-
-#include <string>
-
-#include <errno.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-/**
- * This differs from realpath(3) mainly in its behavior when a path element does not exist or can
- * not be searched. realpath(3) treats that as an error and gives up, but we have Java-compatible
- * behavior where we just assume the path element was not a symbolic link. This leads to a textual
- * treatment of ".." from that point in the path, which may actually lead us back to a path we
- * can resolve (as in "/tmp/does-not-exist/../blah.txt" which would be an error for realpath(3)
- * but "/tmp/blah.txt" under the traditional Java interpretation).
- *
- * This implementation also removes all the fixed-length buffers of the C original.
- */
-bool realpath(const char* path, std::string& resolved) {
- // 'path' must be an absolute path.
- if (path[0] != '/') {
- errno = EINVAL;
- return false;
- }
-
- resolved = "/";
- if (path[1] == '\0') {
- return true;
- }
-
- // Iterate over path components in 'left'.
- int symlinkCount = 0;
- std::string left(path + 1);
- while (!left.empty()) {
- // Extract the next path component.
- size_t nextSlash = left.find('/');
- std::string nextPathComponent = left.substr(0, nextSlash);
- if (nextSlash != std::string::npos) {
- left.erase(0, nextSlash + 1);
- } else {
- left.clear();
- }
- if (nextPathComponent.empty()) {
- continue;
- } else if (nextPathComponent == ".") {
- continue;
- } else if (nextPathComponent == "..") {
- // Strip the last path component except when we have single "/".
- if (resolved.size() > 1) {
- resolved.erase(resolved.rfind('/'));
- }
- continue;
- }
-
- // Append the next path component.
- if (resolved[resolved.size() - 1] != '/') {
- resolved += '/';
- }
- resolved += nextPathComponent;
-
- // See if we've got a symbolic link, and resolve it if so.
- struct stat sb;
- if (lstat(resolved.c_str(), &sb) == 0 && S_ISLNK(sb.st_mode)) {
- if (symlinkCount++ > MAXSYMLINKS) {
- errno = ELOOP;
- return false;
- }
-
- std::string symlink;
- if (!readlink(resolved.c_str(), symlink)) {
- return false;
- }
- if (symlink[0] == '/') {
- // The symbolic link is absolute, so we need to start from scratch.
- resolved = "/";
- } else if (resolved.size() > 1) {
- // The symbolic link is relative, so we just lose the last path component (which
- // was the link).
- resolved.erase(resolved.rfind('/'));
- }
-
- if (!left.empty()) {
- const char* maybeSlash = (symlink[symlink.size() - 1] != '/') ? "/" : "";
- left = symlink + maybeSlash + left;
- } else {
- left = symlink;
- }
- }
- }
-
- // Remove trailing slash except when the resolved pathname is a single "/".
- if (resolved.size() > 1 && resolved[resolved.size() - 1] == '/') {
- resolved.erase(resolved.size() - 1, 1);
- }
- return true;
-}
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 8a1d7c5..079ecd2 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -4,68 +4,69 @@
# or BUILD_*_LIBRARY.
LOCAL_SRC_FILES := \
- AsynchronousSocketCloseMonitor.cpp \
- ExecStrings.cpp \
- IcuUtilities.cpp \
- JniException.cpp \
- NetworkUtilities.cpp \
- Register.cpp \
- ZipUtilities.cpp \
- cbigint.cpp \
- java_io_Console.cpp \
- java_io_File.cpp \
- java_io_ObjectStreamClass.cpp \
- java_lang_Character.cpp \
- java_lang_Double.cpp \
- java_lang_Float.cpp \
- java_lang_Math.cpp \
- java_lang_ProcessManager.cpp \
- java_lang_RealToString.cpp \
- java_lang_StrictMath.cpp \
- java_lang_StringToReal.cpp \
- java_lang_System.cpp \
- java_math_NativeBN.cpp \
- java_nio_ByteOrder.cpp \
- java_nio_charset_Charsets.cpp \
- java_text_Bidi.cpp \
- java_util_regex_Matcher.cpp \
- java_util_regex_Pattern.cpp \
- java_util_zip_Adler32.cpp \
- java_util_zip_CRC32.cpp \
- java_util_zip_Deflater.cpp \
- java_util_zip_Inflater.cpp \
- libcore_icu_AlphabeticIndex.cpp \
- libcore_icu_DateIntervalFormat.cpp \
- libcore_icu_ICU.cpp \
- libcore_icu_NativeBreakIterator.cpp \
- libcore_icu_NativeCollation.cpp \
- libcore_icu_NativeConverter.cpp \
- libcore_icu_NativeDecimalFormat.cpp \
- libcore_icu_NativeIDN.cpp \
- libcore_icu_NativeNormalizer.cpp \
- libcore_icu_NativePluralRules.cpp \
- libcore_icu_TimeZoneNames.cpp \
- libcore_icu_Transliterator.cpp \
- libcore_io_AsynchronousCloseMonitor.cpp \
- libcore_io_Memory.cpp \
- libcore_io_OsConstants.cpp \
- libcore_io_Posix.cpp \
- libcore_net_RawSocket.cpp \
- org_apache_harmony_xml_ExpatParser.cpp \
- readlink.cpp \
- realpath.cpp \
- sun_misc_Unsafe.cpp \
- valueOf.cpp
+ AsynchronousCloseMonitor.cpp \
+ ExecStrings.cpp \
+ IcuUtilities.cpp \
+ JniException.cpp \
+ NetworkUtilities.cpp \
+ Register.cpp \
+ ZipUtilities.cpp \
+ android_system_OsConstants.cpp \
+ canonicalize_path.cpp \
+ cbigint.cpp \
+ java_io_File.cpp \
+ java_io_FileDescriptor.cpp \
+ java_io_ObjectStreamClass.cpp \
+ java_lang_Character.cpp \
+ java_lang_Double.cpp \
+ java_lang_Float.cpp \
+ java_lang_Math.cpp \
+ java_lang_ProcessManager.cpp \
+ java_lang_RealToString.cpp \
+ java_lang_StrictMath.cpp \
+ java_lang_StringToReal.cpp \
+ java_lang_System.cpp \
+ java_math_NativeBN.cpp \
+ java_nio_ByteOrder.cpp \
+ java_nio_charset_Charsets.cpp \
+ java_text_Bidi.cpp \
+ java_util_jar_StrictJarFile.cpp \
+ java_util_regex_Matcher.cpp \
+ java_util_regex_Pattern.cpp \
+ java_util_zip_Adler32.cpp \
+ java_util_zip_CRC32.cpp \
+ java_util_zip_Deflater.cpp \
+ java_util_zip_Inflater.cpp \
+ libcore_icu_AlphabeticIndex.cpp \
+ libcore_icu_DateIntervalFormat.cpp \
+ libcore_icu_ICU.cpp \
+ libcore_icu_NativeBreakIterator.cpp \
+ libcore_icu_NativeCollation.cpp \
+ libcore_icu_NativeConverter.cpp \
+ libcore_icu_NativeDecimalFormat.cpp \
+ libcore_icu_NativeIDN.cpp \
+ libcore_icu_NativeNormalizer.cpp \
+ libcore_icu_NativePluralRules.cpp \
+ libcore_icu_TimeZoneNames.cpp \
+ libcore_icu_Transliterator.cpp \
+ libcore_io_AsynchronousCloseMonitor.cpp \
+ libcore_io_Memory.cpp \
+ libcore_io_Posix.cpp \
+ org_apache_harmony_xml_ExpatParser.cpp \
+ readlink.cpp \
+ sun_misc_Unsafe.cpp \
+ valueOf.cpp \
LOCAL_C_INCLUDES += \
- external/icu4c/common \
- external/icu4c/i18n \
- external/openssl/include \
- external/zlib
-
-LOCAL_SHARED_LIBRARIES += \
- liblog \
- libnativehelper
+ external/icu/icu4c/source/common \
+ external/icu/icu4c/source/i18n \
+ external/openssl/include \
+ external/zlib \
+ system/core/include \
LOCAL_STATIC_LIBRARIES += \
- libfdlibm
+ libfdlibm \
+
+LOCAL_SHARED_LIBRARIES += \
+ liblog \
+ libnativehelper \
diff --git a/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java b/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java
index d2247cf..8708214 100644
--- a/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java
+++ b/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java
@@ -36,7 +36,7 @@ public class DigestTest extends TestCase {
* @param newDigest The new digest implementation, provided by OpenSSL
*/
public void doTestMessageDigest(Digest oldDigest, Digest newDigest) {
- final int ITERATIONS = 10;
+ final int ITERATIONS = 100;
byte[] data = new byte[1024];
diff --git a/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java b/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java
index 6d033d3..1475a63 100644
--- a/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java
+++ b/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java
@@ -109,6 +109,24 @@ public class CertBlacklistTest extends TestCase {
"3xQAyMuOHm72exJljYFqIsiNvGE0KufCqCuH1PD97IXMrLlwGmKKg5jP349lySBpJjm6RDqCTT+6" +
"dUl2jkVbeNmco99Y7AOdtLsOdXBMCo5x8lK8zwQWFrzEms0joHXCpWfGWA==";
+ public static final String ANSSI = "" +
+ "MIIDbDCCAlSgAwIBAgIDAx2nMA0GCSqGSIb3DQEBBQUAMEsxCzAJBgNVBAYTAkZSMQ4wDAYDVQQK" +
+ "EwVER1RQRTEsMCoGA1UEAxMjQUMgREdUUEUgU2lnbmF0dXJlIEF1dGhlbnRpZmljYXRpb24wHhcN" +
+ "MTMwNzE4MTAwNTI4WhcNMTQwNzE4MTAwNTI4WjA+MQswCQYDVQQGEwJGUjETMBEGA1UECgwKREcg" +
+ "VHLDqXNvcjEaMBgGA1UEAwwRQUMgREcgVHLDqXNvciBTU0wwggEiMA0GCSqGSIb3DQEBAQUAA4IB" +
+ "DwAwggEKAoIBAQDI0WFSUyY+MmtFkqFjTefoFyDgh9b1C/2YvSIvT8oCH62JWT5rpeTCZwaXbqWc" +
+ "jaNfzggqaFsokqfhBif43HNHNtNJmvKE32VcuLB0SpsLR/1VeTd9F99C1JeHVa+nelumOHEfouX8" +
+ "rRFrxNXNIYTVeiENT8Y2YqRb/XAril9g7i674uFzLiNR/t/N/F8Exujv9U8m8rmgud/+tG9WDRaD" +
+ "Jwoj3ZFCOnL5qLnSUEcS6TzWpozLmC2JVO5GZKGGd7qC9FjdBkVilkbVIEGSrYvz2Uz2v5IGqMBI" +
+ "QaFL/kSYWxGTaedTOk2drFEApp9AEPTfv1NwCWBfegsGQrHUROM3AgMBAAGjZjBkMBIGA1UdEwEB" +
+ "/wQIMAYBAf8CAQQwHQYDVR0OBBYEFAAMW8lJqJW0DtAv5p3Mjogxvh9lMB8GA1UdIwQYMBaAFOnb" +
+ "kI/9W5nkFTvwYlyn5A1Y6IeZMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAtDfG" +
+ "HkHOLW2d9fiMtwtkEwDauISJLJyCjoRmawzmQbIZXq7HaLliVfE0sdfKUm0iQ0im1/CpnJLPoTeK" +
+ "yBHvNu1ubLc2m+9dabAYhF3pVdKC+gNaAzBXZ9Gt0p1CLk1lf8Hg+R10HN2IPCv7V/crz2Ga+c23" +
+ "4P3pfwYW8+Nd7alGCuvqot6UYXOlheF7zWUkHn6z6tvY+9oMDHKSUAthhA/FB50JgJU89zyTv1eg" +
+ "Y3ldKwvYBW3W3yNZdTHbPyNsPJdhqA55mDNsteE5YTp1PyySDb1MSVrbxDEruoH6ZE99Hob4Ih8A" +
+ "mn7MHZatGClECgjXWFZ2Gxa7OUCaQpcH8g==";
+
public CertBlacklistTest() throws IOException {
tmpFile = File.createTempFile("test", "");
DEFAULT_PUBKEYS = getDefaultPubkeys();
@@ -415,6 +433,20 @@ public class CertBlacklistTest extends TestCase {
assertEquals(bl.isPublicKeyBlackListed(pk), true);
}
+ public void testANSSISerialBlacklist() throws Exception {
+ CertBlacklist bl = new CertBlacklist();
+ assertEquals(bl.isSerialNumberBlackListed(createSerialNumber(ANSSI)), true);
+ }
+
+ public void testANSSIIntermediatePubkeyBlacklist() throws Exception {
+ // build the public key
+ PublicKey pk = createPublicKey(ANSSI);
+ // set our blacklist path
+ CertBlacklist bl = new CertBlacklist();
+ // check to make sure it isn't blacklisted
+ assertEquals(bl.isPublicKeyBlackListed(pk), true);
+ }
+
private static void printHash(String cert) throws Exception {
System.out.println("CERTIFICATE PUBLIC KEY HASH: " + getHash(createPublicKey(cert)));
}
diff --git a/luni/src/test/java/dalvik/system/DexClassLoaderTest.java b/luni/src/test/java/dalvik/system/DexClassLoaderTest.java
index 5133ea0..c57db71 100644
--- a/luni/src/test/java/dalvik/system/DexClassLoaderTest.java
+++ b/luni/src/test/java/dalvik/system/DexClassLoaderTest.java
@@ -16,6 +16,7 @@
package dalvik.system;
+import java.io.FilenameFilter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.io.File;
@@ -29,121 +30,131 @@ import junit.framework.TestCase;
* Tests for the class {@link DexClassLoader}.
*/
public class DexClassLoaderTest extends TestCase {
- private static final File TMP_DIR =
- new File(System.getProperty("java.io.tmpdir"), "loading-test");
private static final String PACKAGE_PATH = "dalvik/system/";
- private static final String JAR_NAME = "loading-test.jar";
- private static final String DEX_NAME = "loading-test.dex";
- private static final String JAR2_NAME = "loading-test2.jar";
- private static final String DEX2_NAME = "loading-test2.dex";
- private static final File JAR_FILE = new File(TMP_DIR, JAR_NAME);
- private static final File DEX_FILE = new File(TMP_DIR, DEX_NAME);
- private static final File JAR2_FILE = new File(TMP_DIR, JAR2_NAME);
- private static final File DEX2_FILE = new File(TMP_DIR, DEX2_NAME);
- private static final File OPTIMIZED_DIR = new File(TMP_DIR, "optimized");
- private static enum Configuration {
- /** just one classpath element, a raw dex file */
- ONE_DEX(1),
+ private File srcDir;
+ private File dex1;
+ private File dex2;
+ private File jar1;
+ private File jar2;
+ private File optimizedDir;
- /** just one classpath element, a jar file */
- ONE_JAR(1),
+ protected void setUp() throws Exception {
+ srcDir = File.createTempFile("src", "");
+ assertTrue(srcDir.delete());
+ assertTrue(srcDir.mkdirs());
- /** two classpath elements, both raw dex files */
- TWO_DEX(2),
+ dex1 = new File(srcDir, "loading-test.dex");
+ dex2 = new File(srcDir, "loading-test2.dex");
+ jar1 = new File(srcDir, "loading-test.jar");
+ jar2 = new File(srcDir, "loading-test2.jar");
- /** two classpath elements, both jar files */
- TWO_JAR(2);
+ copyResource("loading-test.dex", dex1);
+ copyResource("loading-test2.dex", dex2);
+ copyResource("loading-test.jar", jar1);
+ copyResource("loading-test2.jar", jar2);
- public final int expectedFiles;
-
- Configuration(int expectedFiles) {
- this.expectedFiles = expectedFiles;
- }
+ optimizedDir = File.createTempFile("optimized", "");
+ assertTrue(optimizedDir.delete());
+ assertTrue(optimizedDir.mkdirs());
}
- protected void setUp() throws IOException {
- TMP_DIR.mkdirs();
-
- ClassLoader cl = DexClassLoaderTest.class.getClassLoader();
- copyResource(cl, JAR_NAME, JAR_FILE);
- copyResource(cl, DEX_NAME, DEX_FILE);
- copyResource(cl, JAR2_NAME, JAR2_FILE);
- copyResource(cl, DEX2_NAME, DEX2_FILE);
+ protected void tearDown() {
+ cleanUpDir(srcDir);
+ cleanUpDir(optimizedDir);
+ }
- OPTIMIZED_DIR.mkdirs();
- File[] files = OPTIMIZED_DIR.listFiles();
+ private static void cleanUpDir(File dir) {
+ if (!dir.isDirectory()) {
+ return;
+ }
+ File[] files = dir.listFiles();
for (File file : files) {
- file.delete();
+ assertTrue(file.delete());
}
}
/**
* Copy a resource in the package directory to the indicated
- * target file, but only if the target file doesn't exist.
+ * target file.
*/
- private static void copyResource(ClassLoader loader, String resourceName,
+ private static void copyResource(String resourceName,
File destination) throws IOException {
- if (destination.exists()) {
- return;
+ ClassLoader loader = DexClassLoaderTest.class.getClassLoader();
+ assertFalse(destination.exists());
+ InputStream in = loader.getResourceAsStream(PACKAGE_PATH + resourceName);
+ if (in == null) {
+ throw new IllegalStateException("Resource not found: " + PACKAGE_PATH + resourceName);
}
- InputStream in =
- loader.getResourceAsStream(PACKAGE_PATH + resourceName);
- FileOutputStream out = new FileOutputStream(destination);
- Streams.copy(in, out);
- in.close();
- out.close();
+ try (FileOutputStream out = new FileOutputStream(destination)) {
+ Streams.copy(in, out);
+ } finally {
+ in.close();
+ }
}
+ static final FilenameFilter DEX_FILE_NAME_FILTER = new FilenameFilter() {
+ @Override
+ public boolean accept(File file, String s) {
+ return s.endsWith(".dex");
+ }
+ };
+
/**
- * Helper to construct an instance to test.
+ * Helper to construct a DexClassLoader instance to test.
*
- * @param config how to configure the classpath
+ * @param files The .dex or .jar files to use for the class path.
*/
- private static DexClassLoader createInstance(Configuration config) {
- File file1;
- File file2;
-
- switch (config) {
- case ONE_DEX: file1 = DEX_FILE; file2 = null; break;
- case ONE_JAR: file1 = JAR_FILE; file2 = null; break;
- case TWO_DEX: file1 = DEX_FILE; file2 = DEX2_FILE; break;
- case TWO_JAR: file1 = JAR_FILE; file2 = JAR2_FILE; break;
- default: throw new AssertionError("shouldn't happen");
+ private ClassLoader createLoader(File... files) {
+ assertNotNull(files);
+ assertTrue(files.length > 0);
+ String path = files[0].getAbsolutePath();
+ for (int i = 1; i < files.length; i++) {
+ path += File.pathSeparator + files[i].getAbsolutePath();
}
-
- String path = file1.getAbsolutePath();
- if (file2 != null) {
- path += File.pathSeparator + file2.getAbsolutePath();
- }
-
- return new DexClassLoader(
- path, OPTIMIZED_DIR.getAbsolutePath(), null,
+ return new DexClassLoader(path, optimizedDir.getAbsolutePath(), null,
ClassLoader.getSystemClassLoader());
}
/**
- * Helper to construct an instance to test, using the jar file as
- * the source, and call a named no-argument static method on a
- * named class.
+ * Helper to construct a new DexClassLoader instance to test, using the
+ * given files as the class path, and call a named no-argument static
+ * method on a named class.
*
- * @param config how to configure the classpath
+ * @param className The name of the class of the method to call.
+ * @param methodName The name of the method to call.
+ * @param files The .dex or .jar files to use for the class path.
*/
- public static Object createInstanceAndCallStaticMethod(
- Configuration config, String className, String methodName)
- throws ClassNotFoundException, NoSuchMethodException,
- IllegalAccessException, InvocationTargetException {
- DexClassLoader dcl = createInstance(config);
- Class c = dcl.loadClass(className);
+ public Object createLoaderAndCallMethod(
+ String className, String methodName, File... files)
+ throws ReflectiveOperationException {
+ ClassLoader cl = createLoader(files);
+ Class c = cl.loadClass(className);
Method m = c.getMethod(methodName, (Class[]) null);
return m.invoke(null, (Object[]) null);
}
- /*
- * Tests that are parametric with respect to whether to use a jar
- * file or a dex file as the source of the code
+ /**
+ * Helper to construct a new DexClassLoader instance to test, using the
+ * given files as the class path, and read the contents of the named
+ * resource as a String.
+ *
+ * @param resourceName The name of the resource to get.
+ * @param files The .dex or .jar files to use for the class path.
*/
+ private String createLoaderAndGetResource(String resourceName, File... files) throws Exception {
+ ClassLoader cl = createLoader(files);
+ InputStream in = cl.getResourceAsStream(resourceName);
+ if (in == null) {
+ throw new IllegalStateException("Resource not found: " + resourceName);
+ }
+
+ byte[] contents = Streams.readFully(in);
+ return new String(contents, "UTF-8");
+ }
+
+ // ONE_JAR
/**
* Just a trivial test of construction. This one merely makes
@@ -151,23 +162,19 @@ public class DexClassLoaderTest extends TestCase {
* to verify anything about the constructed instance, other than
* checking for the existence of optimized dex files.
*/
- private static void test_init(Configuration config) {
- createInstance(config);
-
- int expectedFiles = config.expectedFiles;
- int actualFiles = OPTIMIZED_DIR.listFiles().length;
-
- assertEquals(expectedFiles, actualFiles);
+ public void test_oneJar_init() throws Exception {
+ ClassLoader cl = createLoader(jar1);
+ File[] files = optimizedDir.listFiles(DEX_FILE_NAME_FILTER);
+ assertNotNull(files);
+ assertEquals(1, files.length);
}
/**
* Check that a class in the jar/dex file may be used successfully. In this
* case, a trivial static method is called.
*/
- private static void test_simpleUse(Configuration config) throws Exception {
- String result = (String)
- createInstanceAndCallStaticMethod(config, "test.Test1", "test");
-
+ public void test_oneJar_simpleUse() throws Exception {
+ String result = (String) createLoaderAndCallMethod("test.Test1", "test", jar1);
assertSame("blort", result);
}
@@ -176,312 +183,214 @@ public class DexClassLoaderTest extends TestCase {
* that lives inside the loading-test dex/jar file.
*/
- private static void test_constructor(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_constructor");
- }
-
- private static void test_callStaticMethod(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_callStaticMethod");
- }
-
- private static void test_getStaticVariable(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_getStaticVariable");
- }
-
- private static void test_callInstanceMethod(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_callInstanceMethod");
- }
-
- private static void test_getInstanceVariable(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_getInstanceVariable");
- }
-
- private static void test_diff_constructor(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_diff_constructor");
- }
-
- private static void test_diff_callStaticMethod(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_diff_callStaticMethod");
- }
-
- private static void test_diff_getStaticVariable(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_diff_getStaticVariable");
- }
-
- private static void test_diff_callInstanceMethod(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_diff_callInstanceMethod");
- }
-
- private static void test_diff_getInstanceVariable(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_diff_getInstanceVariable");
- }
-
- /*
- * These methods are all essentially just calls to the
- * parametrically-defined tests above.
- */
-
- // ONE_JAR
-
- public void test_oneJar_init() throws Exception {
- test_init(Configuration.ONE_JAR);
- }
-
- public void test_oneJar_simpleUse() throws Exception {
- test_simpleUse(Configuration.ONE_JAR);
- }
-
public void test_oneJar_constructor() throws Exception {
- test_constructor(Configuration.ONE_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_constructor", jar1);
}
public void test_oneJar_callStaticMethod() throws Exception {
- test_callStaticMethod(Configuration.ONE_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_callStaticMethod", jar1);
}
public void test_oneJar_getStaticVariable() throws Exception {
- test_getStaticVariable(Configuration.ONE_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_getStaticVariable", jar1);
}
public void test_oneJar_callInstanceMethod() throws Exception {
- test_callInstanceMethod(Configuration.ONE_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_callInstanceMethod", jar1);
}
public void test_oneJar_getInstanceVariable() throws Exception {
- test_getInstanceVariable(Configuration.ONE_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_getInstanceVariable", jar1);
}
// ONE_DEX
public void test_oneDex_init() throws Exception {
- test_init(Configuration.ONE_DEX);
+ ClassLoader cl = createLoader(dex1);
+ File[] files = optimizedDir.listFiles(DEX_FILE_NAME_FILTER);
+ assertNotNull(files);
+ assertEquals(1, files.length);
}
public void test_oneDex_simpleUse() throws Exception {
- test_simpleUse(Configuration.ONE_DEX);
+ String result = (String) createLoaderAndCallMethod("test.Test1", "test", dex1);
+ assertSame("blort", result);
}
public void test_oneDex_constructor() throws Exception {
- test_constructor(Configuration.ONE_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_constructor", dex1);
}
public void test_oneDex_callStaticMethod() throws Exception {
- test_callStaticMethod(Configuration.ONE_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_callStaticMethod", dex1);
}
public void test_oneDex_getStaticVariable() throws Exception {
- test_getStaticVariable(Configuration.ONE_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_getStaticVariable", dex1);
}
public void test_oneDex_callInstanceMethod() throws Exception {
- test_callInstanceMethod(Configuration.ONE_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_callInstanceMethod", dex1);
}
public void test_oneDex_getInstanceVariable() throws Exception {
- test_getInstanceVariable(Configuration.ONE_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_getInstanceVariable", dex1);
}
// TWO_JAR
public void test_twoJar_init() throws Exception {
- test_init(Configuration.TWO_JAR);
+ ClassLoader cl = createLoader(jar1, jar2);
+ File[] files = optimizedDir.listFiles(DEX_FILE_NAME_FILTER);
+ assertNotNull(files);
+ assertEquals(2, files.length);
}
public void test_twoJar_simpleUse() throws Exception {
- test_simpleUse(Configuration.TWO_JAR);
+ String result = (String) createLoaderAndCallMethod("test.Test1", "test", jar1, jar2);
+ assertSame("blort", result);
}
public void test_twoJar_constructor() throws Exception {
- test_constructor(Configuration.TWO_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_constructor", jar1, jar2);
}
public void test_twoJar_callStaticMethod() throws Exception {
- test_callStaticMethod(Configuration.TWO_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_callStaticMethod", jar1, jar2);
}
public void test_twoJar_getStaticVariable() throws Exception {
- test_getStaticVariable(Configuration.TWO_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_getStaticVariable", jar1, jar2);
}
public void test_twoJar_callInstanceMethod() throws Exception {
- test_callInstanceMethod(Configuration.TWO_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_callInstanceMethod", jar1, jar2);
}
public void test_twoJar_getInstanceVariable() throws Exception {
- test_getInstanceVariable(Configuration.TWO_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_getInstanceVariable", jar1, jar2);
}
- public static void test_twoJar_diff_constructor() throws Exception {
- test_diff_constructor(Configuration.TWO_JAR);
+ public void test_twoJar_diff_constructor() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_constructor", jar1, jar2);
}
- public static void test_twoJar_diff_callStaticMethod() throws Exception {
- test_diff_callStaticMethod(Configuration.TWO_JAR);
+ public void test_twoJar_diff_callStaticMethod() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_callStaticMethod", jar1, jar2);
}
- public static void test_twoJar_diff_getStaticVariable() throws Exception {
- test_diff_getStaticVariable(Configuration.TWO_JAR);
+ public void test_twoJar_diff_getStaticVariable() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_getStaticVariable", jar1, jar2);
}
- public static void test_twoJar_diff_callInstanceMethod()
- throws Exception {
- test_diff_callInstanceMethod(Configuration.TWO_JAR);
+ public void test_twoJar_diff_callInstanceMethod() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_callInstanceMethod", jar1, jar2);
}
- public static void test_twoJar_diff_getInstanceVariable()
- throws Exception {
- test_diff_getInstanceVariable(Configuration.TWO_JAR);
+ public void test_twoJar_diff_getInstanceVariable() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_getInstanceVariable", jar1, jar2);
}
// TWO_DEX
public void test_twoDex_init() throws Exception {
- test_init(Configuration.TWO_DEX);
+ ClassLoader cl = createLoader(dex1, dex2);
+ File[] files = optimizedDir.listFiles(DEX_FILE_NAME_FILTER);
+ assertNotNull(files);
+ assertEquals(2, files.length);
}
public void test_twoDex_simpleUse() throws Exception {
- test_simpleUse(Configuration.TWO_DEX);
+ String result = (String) createLoaderAndCallMethod("test.Test1", "test", dex1, dex2);
+ assertSame("blort", result);
}
public void test_twoDex_constructor() throws Exception {
- test_constructor(Configuration.TWO_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_constructor", dex1, dex2);
}
public void test_twoDex_callStaticMethod() throws Exception {
- test_callStaticMethod(Configuration.TWO_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_callStaticMethod", dex1, dex2);
}
public void test_twoDex_getStaticVariable() throws Exception {
- test_getStaticVariable(Configuration.TWO_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_getStaticVariable", dex1, dex2);
}
public void test_twoDex_callInstanceMethod() throws Exception {
- test_callInstanceMethod(Configuration.TWO_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_callInstanceMethod", dex1, dex2);
}
public void test_twoDex_getInstanceVariable() throws Exception {
- test_getInstanceVariable(Configuration.TWO_DEX);
+ createLoaderAndCallMethod("test.TestMethods", "test_getInstanceVariable", dex1, dex2);
}
- public static void test_twoDex_diff_constructor() throws Exception {
- test_diff_constructor(Configuration.TWO_DEX);
+ public void test_twoDex_diff_constructor() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_constructor", dex1, dex2);
}
- public static void test_twoDex_diff_callStaticMethod() throws Exception {
- test_diff_callStaticMethod(Configuration.TWO_DEX);
+ public void test_twoDex_diff_callStaticMethod() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_callStaticMethod", dex1, dex2);
}
- public static void test_twoDex_diff_getStaticVariable() throws Exception {
- test_diff_getStaticVariable(Configuration.TWO_DEX);
+ public void test_twoDex_diff_getStaticVariable() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_getStaticVariable", dex1, dex2);
}
- public static void test_twoDex_diff_callInstanceMethod()
- throws Exception {
- test_diff_callInstanceMethod(Configuration.TWO_DEX);
+ public void test_twoDex_diff_callInstanceMethod() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_callInstanceMethod", dex1, dex2);
}
- public static void test_twoDex_diff_getInstanceVariable()
- throws Exception {
- test_diff_getInstanceVariable(Configuration.TWO_DEX);
+ public void test_twoDex_diff_getInstanceVariable() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_getInstanceVariable", dex1, dex2);
}
/*
* Tests specifically for resource-related functionality. Since
* raw dex files don't contain resources, these test only work
- * with jar files. The first couple methods here are helpers,
- * and they are followed by the tests per se.
- */
-
- /**
- * Check that a given resource (by name) is retrievable and contains
- * the given expected contents.
+ * with jar files.
*/
- private static void test_directGetResourceAsStream(Configuration config,
- String resourceName, String expectedContents)
- throws Exception {
- DexClassLoader dcl = createInstance(config);
- InputStream in = dcl.getResourceAsStream(resourceName);
- byte[] contents = Streams.readFully(in);
- String s = new String(contents, "UTF-8");
-
- assertEquals(expectedContents, s);
- }
/**
* Check that a resource in the jar file is retrievable and contains
* the expected contents.
*/
- private static void test_directGetResourceAsStream(Configuration config)
- throws Exception {
- test_directGetResourceAsStream(
- config, "test/Resource1.txt", "Muffins are tasty!\n");
+ public void test_oneJar_directGetResourceAsStream() throws Exception {
+ String result = createLoaderAndGetResource("test/Resource1.txt", jar1);
+ assertEquals("Muffins are tasty!\n", result);
}
/**
* Check that a resource in the jar file can be retrieved from
* a class within that jar file.
*/
- private static void test_getResourceAsStream(Configuration config)
- throws Exception {
- createInstanceAndCallStaticMethod(
- config, "test.TestMethods", "test_getResourceAsStream");
- }
-
- public void test_oneJar_directGetResourceAsStream() throws Exception {
- test_directGetResourceAsStream(Configuration.ONE_JAR);
- }
-
public void test_oneJar_getResourceAsStream() throws Exception {
- test_getResourceAsStream(Configuration.ONE_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_getResourceAsStream", jar1);
}
public void test_twoJar_directGetResourceAsStream() throws Exception {
- test_directGetResourceAsStream(Configuration.TWO_JAR);
+ String result = createLoaderAndGetResource("test/Resource1.txt", jar1, jar2);
+ assertEquals("Muffins are tasty!\n", result);
}
public void test_twoJar_getResourceAsStream() throws Exception {
- test_getResourceAsStream(Configuration.TWO_JAR);
+ createLoaderAndCallMethod("test.TestMethods", "test_getResourceAsStream", jar1, jar2);
}
/**
* Check that a resource in the second jar file is retrievable and
* contains the expected contents.
*/
- public void test_twoJar_diff_directGetResourceAsStream()
- throws Exception {
- test_directGetResourceAsStream(
- Configuration.TWO_JAR, "test2/Resource2.txt",
- "Who doesn't like a good biscuit?\n");
+ public void test_twoJar_diff_directGetResourceAsStream() throws Exception {
+ String result = createLoaderAndGetResource("test2/Resource2.txt", jar1, jar2);
+ assertEquals("Who doesn't like a good biscuit?\n", result);
}
/**
* Check that a resource in a jar file can be retrieved from
* a class within the other jar file.
*/
- public void test_twoJar_diff_getResourceAsStream()
- throws Exception {
- createInstanceAndCallStaticMethod(
- Configuration.TWO_JAR, "test.TestMethods",
- "test_diff_getResourceAsStream");
+ public void test_twoJar_diff_getResourceAsStream() throws Exception {
+ createLoaderAndCallMethod("test.TestMethods", "test_diff_getResourceAsStream", jar1, jar2);
}
}
diff --git a/luni/src/test/java/dalvik/system/JniTest.java b/luni/src/test/java/dalvik/system/JniTest.java
new file mode 100644
index 0000000..37e687d
--- /dev/null
+++ b/luni/src/test/java/dalvik/system/JniTest.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+import junit.framework.TestCase;
+
+/**
+ * Test JNI behavior
+ */
+public final class JniTest extends TestCase {
+
+ static {
+ System.loadLibrary("javacoretests");
+ }
+
+ /** @return this argument of method */
+ private native JniTest returnThis();
+ /** @return class argument of method */
+ private static native Class<JniTest> returnClass();
+
+ private native Object returnObjectArgFrom16(int arg_no,
+ Object o1, Object o2, Object o3, Object o4, Object o5,
+ Object o6, Object o7, Object o8, Object o9, Object o10,
+ Object o11, Object o12, Object o13, Object o14, Object o15,
+ Object o16);
+ private native boolean returnBooleanArgFrom16(int arg_no,
+ boolean o1, boolean o2, boolean o3, boolean o4, boolean o5,
+ boolean o6, boolean o7, boolean o8, boolean o9, boolean o10,
+ boolean o11, boolean o12, boolean o13, boolean o14, boolean o15,
+ boolean o16);
+ private native char returnCharArgFrom16(int arg_no,
+ char o1, char o2, char o3, char o4, char o5,
+ char o6, char o7, char o8, char o9, char o10,
+ char o11, char o12, char o13, char o14, char o15,
+ char o16);
+ private native byte returnByteArgFrom16(int arg_no,
+ byte o1, byte o2, byte o3, byte o4, byte o5,
+ byte o6, byte o7, byte o8, byte o9, byte o10,
+ byte o11, byte o12, byte o13, byte o14, byte o15,
+ byte o16);
+ private native short returnShortArgFrom16(int arg_no,
+ short o1, short o2, short o3, short o4, short o5,
+ short o6, short o7, short o8, short o9, short o10,
+ short o11, short o12, short o13, short o14, short o15,
+ short o16);
+ private native int returnIntArgFrom16(int arg_no,
+ int o1, int o2, int o3, int o4, int o5,
+ int o6, int o7, int o8, int o9, int o10,
+ int o11, int o12, int o13, int o14, int o15,
+ int o16);
+ private native long returnLongArgFrom16(int arg_no,
+ long o1, long o2, long o3, long o4, long o5,
+ long o6, long o7, long o8, long o9, long o10,
+ long o11, long o12, long o13, long o14, long o15,
+ long o16);
+ private native float returnFloatArgFrom16(int arg_no,
+ float o1, float o2, float o3, float o4, float o5,
+ float o6, float o7, float o8, float o9, float o10,
+ float o11, float o12, float o13, float o14, float o15,
+ float o16);
+ private native double returnDoubleArgFrom16(int arg_no,
+ double o1, double o2, double o3, double o4, double o5,
+ double o6, double o7, double o8, double o9, double o10,
+ double o11, double o12, double o13, double o14, double o15,
+ double o16);
+
+ /** Test cases for implicit this argument */
+ public void testPassingThis() {
+ assertEquals(this, returnThis());
+ }
+
+ /** Test cases for implicit class argument */
+ public void testPassingClass() {
+ assertEquals(JniTest.class, returnClass());
+ }
+
+ /** Test passing object references as arguments to a native method */
+ public void testPassingObjectReferences() {
+ final Object[] literals = {"Bradshaw", "Isherwood", "Oldknow", "Mallet",
+ JniTest.class, null, Integer.valueOf(0)};
+ final Object[] a = new Object[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(Object literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnObjectArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnObjectArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ /** Test passing booleans as arguments to a native method */
+ public void testPassingBooleans() {
+ final boolean[] literals = {true, false, false, true};
+ final boolean[] a = new boolean[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(boolean literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnBooleanArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnBooleanArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ /** Test passing characters as arguments to a native method */
+ public void testPassingChars() {
+ final char[] literals = {Character.MAX_VALUE, Character.MIN_VALUE,
+ Character.MAX_HIGH_SURROGATE, Character.MAX_LOW_SURROGATE,
+ Character.MIN_HIGH_SURROGATE, Character.MIN_LOW_SURROGATE,
+ 'a', 'z', 'A', 'Z', '0', '9'};
+ final char[] a = new char[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(char literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnCharArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnCharArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ /** Test passing bytes as arguments to a native method */
+ public void testPassingBytes() {
+ final byte[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, 0, -1};
+ final byte[] a = new byte[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(byte literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnByteArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnByteArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ /** Test passing shorts as arguments to a native method */
+ public void testPassingShorts() {
+ final short[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE, 0, -1};
+ final short[] a = new short[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(short literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnShortArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnShortArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ /** Test passing ints as arguments to a native method */
+ public void testPassingInts() {
+ final int[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE,
+ Integer.MAX_VALUE, Integer.MIN_VALUE, 0, -1};
+ final int[] a = new int[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(int literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnIntArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnIntArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ /** Test passing longs as arguments to a native method */
+ public void testPassingLongs() {
+ final long[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE,
+ Integer.MAX_VALUE, Integer.MIN_VALUE, Long.MAX_VALUE, Long.MIN_VALUE, 0, -1};
+ final long[] a = new long[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(long literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnLongArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnLongArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ /** Test passing floats as arguments to a native method */
+ public void testPassingFloats() {
+ final float[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE,
+ Integer.MAX_VALUE, Integer.MIN_VALUE, Long.MAX_VALUE, Long.MIN_VALUE,
+ Float.MAX_VALUE, Float.MIN_VALUE, Float.MIN_NORMAL, Float.NaN,
+ Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, (float)Math.E, (float)Math.PI, 0, -1};
+ final float[] a = new float[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(float literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnFloatArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnFloatArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ /** Test passing doubles as arguments to a native method */
+ public void testPassingDoubles() {
+ final double[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE,
+ Integer.MAX_VALUE, Integer.MIN_VALUE, Long.MAX_VALUE, Long.MIN_VALUE,
+ Float.MAX_VALUE, Float.MIN_VALUE, Float.MIN_NORMAL, Float.NaN,
+ Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY,
+ Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_NORMAL, Double.NaN,
+ Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
+ Math.E, Math.PI, 0, -1};
+ final double[] a = new double[16];
+ // test selection from a list of object literals where the literals are all the same
+ for(double literal : literals) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literal;
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnDoubleArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ // test selection from a list of object literals where the literals are shuffled
+ for(int j = 0; j < literals.length; j++) {
+ for(int i = 0; i < 16; i++) {
+ a[i] = literals[(i + j) % literals.length];
+ }
+ for(int i = 0; i < 16; i++) {
+ assertEquals(a[i], returnDoubleArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+ a[5], a[6], a[7], a[8], a[9], a[10],
+ a[11], a[12], a[13], a[14], a[15]));
+ }
+ }
+ }
+
+ private static native Class<?> envGetSuperclass(Class<?> clazz);
+
+ public void testGetSuperclass() {
+ assertEquals(Object.class, envGetSuperclass(String.class));
+ assertEquals(null, envGetSuperclass(Object.class));
+ assertEquals(null, envGetSuperclass(int.class));
+
+ // incorrect! the spec says this should be null. http://b/5652725
+ assertEquals(Object.class, envGetSuperclass(Runnable.class));
+ }
+}
diff --git a/luni/src/test/java/dalvik/system/VMRuntimeTest.java b/luni/src/test/java/dalvik/system/VMRuntimeTest.java
new file mode 100644
index 0000000..251ecd8
--- /dev/null
+++ b/luni/src/test/java/dalvik/system/VMRuntimeTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+import java.lang.reflect.Array;
+import junit.framework.TestCase;
+
+/**
+ * Test VMRuntime behavior.
+ */
+public final class VMRuntimeTest extends TestCase {
+
+ private void doTestNewNonMovableArray(Class<?> componentType, int step, int maxLength) {
+ // Can't create negative sized arrays.
+ try {
+ Object array = VMRuntime.getRuntime().newNonMovableArray(componentType, -1);
+ assertTrue(false);
+ } catch (NegativeArraySizeException expected) {
+ }
+
+ try {
+ Object array = VMRuntime.getRuntime().newNonMovableArray(componentType, Integer.MIN_VALUE);
+ assertTrue(false);
+ } catch (NegativeArraySizeException expected) {
+ }
+
+ // Allocate arrays in a loop and check their properties.
+ for (int i = 0; i <= maxLength; i += step) {
+ Object array = VMRuntime.getRuntime().newNonMovableArray(componentType, i);
+ assertTrue(array.getClass().isArray());
+ assertEquals(array.getClass().getComponentType(), componentType);
+ assertEquals(Array.getLength(array), i);
+ }
+ }
+
+ public void testNewNonMovableArray() {
+ // Can't create arrays with no component type.
+ try {
+ Object array = VMRuntime.getRuntime().newNonMovableArray(null, 0);
+ assertTrue(false);
+ } catch (NullPointerException expected) {
+ }
+
+ // Can't create arrays of void.
+ try {
+ Object array = VMRuntime.getRuntime().newNonMovableArray(void.class, 0);
+ assertTrue(false);
+ } catch (NoClassDefFoundError expected) {
+ }
+
+ int maxLengthForLoop = 16 * 1024;
+ int step = 67;
+ doTestNewNonMovableArray(boolean.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(byte.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(char.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(short.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(int.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(long.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(float.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(double.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(Object.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(Number.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(String.class, step, maxLengthForLoop);
+ doTestNewNonMovableArray(Runnable.class, step, maxLengthForLoop);
+ }
+
+ private void doTestNewUnpaddedArray(Class<?> componentType, int step, int maxLength) {
+ // Can't create negative sized arrays.
+ try {
+ Object array = VMRuntime.getRuntime().newUnpaddedArray(componentType, -1);
+ assertTrue(false);
+ } catch (NegativeArraySizeException expected) {
+ }
+
+ try {
+ Object array = VMRuntime.getRuntime().newUnpaddedArray(componentType, Integer.MIN_VALUE);
+ assertTrue(false);
+ } catch (NegativeArraySizeException expected) {
+ }
+
+ // Allocate arrays in a loop and check their properties.
+ for (int i = 0; i <= maxLength; i += step) {
+ Object array = VMRuntime.getRuntime().newUnpaddedArray(componentType, i);
+ assertTrue(array.getClass().isArray());
+ assertEquals(array.getClass().getComponentType(), componentType);
+ assertTrue(Array.getLength(array) >= i);
+ }
+ }
+
+ public void testNewUnpaddedArray() {
+ // Can't create arrays with no component type.
+ try {
+ Object array = VMRuntime.getRuntime().newUnpaddedArray(null, 0);
+ assertTrue(false);
+ } catch (NullPointerException expected) {
+ }
+
+ // Can't create arrays of void.
+ try {
+ Object array = VMRuntime.getRuntime().newUnpaddedArray(void.class, 0);
+ assertTrue(false);
+ } catch (NoClassDefFoundError expected) {
+ }
+
+ int maxLengthForLoop = 16 * 1024;
+ int step = 67;
+ doTestNewUnpaddedArray(boolean.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(byte.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(char.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(short.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(int.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(long.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(float.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(double.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(Object.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(Number.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(String.class, step, maxLengthForLoop);
+ doTestNewUnpaddedArray(Runnable.class, step, maxLengthForLoop);
+ }
+}
+
diff --git a/luni/src/test/java/libcore/android/system/OsConstantsTest.java b/luni/src/test/java/libcore/android/system/OsConstantsTest.java
new file mode 100644
index 0000000..681d68c
--- /dev/null
+++ b/luni/src/test/java/libcore/android/system/OsConstantsTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import junit.framework.TestCase;
+
+public class OsConstantsTest extends TestCase {
+
+ // http://b/15602893
+ public void testBug15602893() {
+ assertTrue(OsConstants.RT_SCOPE_HOST > 0);
+ assertTrue(OsConstants.RT_SCOPE_LINK > 0);
+ assertTrue(OsConstants.RT_SCOPE_SITE > 0);
+
+ assertTrue(OsConstants.IFA_F_TENTATIVE > 0);
+ }
+}
diff --git a/luni/src/test/java/libcore/icu/AlphabeticIndexTest.java b/luni/src/test/java/libcore/icu/AlphabeticIndexTest.java
index 801db4b..6c7452d 100644
--- a/luni/src/test/java/libcore/icu/AlphabeticIndexTest.java
+++ b/luni/src/test/java/libcore/icu/AlphabeticIndexTest.java
@@ -20,8 +20,7 @@ import java.util.Locale;
public class AlphabeticIndexTest extends junit.framework.TestCase {
private static AlphabeticIndex.ImmutableIndex createIndex(Locale locale) {
- return new AlphabeticIndex(locale).addLabels(Locale.US)
- .getImmutableIndex();
+ return new AlphabeticIndex(locale).addLabels(Locale.US).getImmutableIndex();
}
private static void assertHasLabel(AlphabeticIndex.ImmutableIndex ii, String string, String expectedLabel) {
@@ -51,8 +50,10 @@ public class AlphabeticIndexTest extends junit.framework.TestCase {
// Kanji (sorts to inflow section)
assertHasLabel(ja, "\u65e5", "");
+
// http://bugs.icu-project.org/trac/ticket/10423 / http://b/10809397
assertHasLabel(ja, "\u95c7", "");
+ assertHasLabel(ja, "\u308f", "ã‚");
// English
assertHasLabel(ja, "Smith", "S");
@@ -106,12 +107,13 @@ public class AlphabeticIndexTest extends junit.framework.TestCase {
}
public void test_de() throws Exception {
- // German: [A-S,Sch,St,T-Z] (no ß or umlauted characters in standard alphabet)
+ // German: [A-Z] (no ß or umlauted characters in standard alphabet)
AlphabeticIndex.ImmutableIndex de = createIndex(Locale.GERMAN);
assertHasLabel(de, "ßind", "S");
+ // We no longer split out "S", "Sch", and "St".
assertHasLabel(de, "Sacher", "S");
- assertHasLabel(de, "Schiller", "Sch");
- assertHasLabel(de, "Steiff", "St");
+ assertHasLabel(de, "Schiller", "S");
+ assertHasLabel(de, "Steiff", "S");
}
public void test_th() throws Exception {
@@ -138,14 +140,19 @@ public class AlphabeticIndexTest extends junit.framework.TestCase {
public void test_zh_CN() throws Exception {
// Simplified Chinese (default collator Pinyin): [A-Z]
- // Shen/Chen (simplified): should be, usually, 'S' for name collator and 'C' for apps/other
AlphabeticIndex.ImmutableIndex zh_CN = createIndex(new Locale("zh", "CN"));
// Jia/Gu: should be, usually, 'J' for name collator and 'G' for apps/other
assertHasLabel(zh_CN, "\u8d3e", "J");
- // Shen/Chen
- assertHasLabel(zh_CN, "\u6c88", "C"); // icu4c 50 does not specialize for names.
+ // Shen/Chen (simplified): should usually be 'S' for names and 'C' for apps/other.
+ // icu4c does not specialize for names and defaults to 'C'.
+ // Some OEMs prefer to default to 'S'.
+ // We allow either to pass CTS since neither choice is right all the time.
+ // assertHasLabel(zh_CN, "\u6c88", "C");
+ String shenChenLabel = zh_CN.getBucketLabel(zh_CN.getBucketIndex("\u6c88"));
+ assertTrue(shenChenLabel.equals("C") || shenChenLabel.equals("S"));
+
// Shen/Chen (traditional)
assertHasLabel(zh_CN, "\u700b", "S");
}
diff --git a/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java b/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
index c8cf572..bac8138 100644
--- a/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
+++ b/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
@@ -16,13 +16,9 @@
package libcore.icu;
-import java.util.Arrays;
-import java.util.Locale;
-
import java.util.Calendar;
-import java.util.Date;
+import java.util.Locale;
import java.util.TimeZone;
-
import static libcore.icu.DateIntervalFormat.*;
public class DateIntervalFormatTest extends junit.framework.TestCase {
@@ -42,6 +38,7 @@ public class DateIntervalFormatTest extends junit.framework.TestCase {
c.set(Calendar.HOUR_OF_DAY, 3);
c.set(Calendar.MINUTE, 30);
c.set(Calendar.SECOND, 15);
+ c.set(Calendar.MILLISECOND, 0);
long timeWithCurrentYear = c.getTimeInMillis();
c.set(Calendar.YEAR, 2009);
@@ -89,26 +86,26 @@ public class DateIntervalFormatTest extends junit.framework.TestCase {
assertEquals("19.01.2009 - 09.02.2012", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
assertEquals("1/19/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
- assertEquals("19/1/2009 – 22/1/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
- assertEquals("19/1/2009 – 22/4/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
- assertEquals("19/1/2009 – 9/2/2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
+ assertEquals("19/1/2009–22/1/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
+ assertEquals("19/1/2009–22/4/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
+ assertEquals("19/1/2009–9/2/2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
assertEquals("19/1/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
- assertEquals("19/1/2009 – 22/1/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
- assertEquals("19/1/2009 – 22/4/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
- assertEquals("19/1/2009 – 9/2/2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
+ assertEquals("19/1/2009–22/1/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
+ assertEquals("19/1/2009–22/4/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
+ assertEquals("19/1/2009–9/2/2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
// These are some random other test cases I came up with.
- assertEquals("January 19–22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, 0));
- assertEquals("Jan 19–22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+ assertEquals("January 19 – 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, 0));
+ assertEquals("Jan 19 – 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
assertEquals("Mon, Jan 19 – Thu, Jan 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
assertEquals("Monday, January 19 – Thursday, January 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
assertEquals("January 19 – April 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, 0));
assertEquals("Jan 19 – Apr 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
assertEquals("Mon, Jan 19 – Wed, Apr 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
- assertEquals("January–April 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
+ assertEquals("January – April 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
assertEquals("Jan 19, 2009 – Feb 9, 2012", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
assertEquals("Jan 2009 – Feb 2012", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL));
@@ -135,36 +132,36 @@ public class DateIntervalFormatTest extends junit.framework.TestCase {
// The same tests but for es_US.
assertEquals("19–22 enero 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, 0));
- assertEquals("19–22 ene 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
- assertEquals("lun 19 ene – jue 22 ene 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
- assertEquals("lunes 19 enero – jueves 22 enero 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
+ assertEquals("19–22 ene. 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+ assertEquals("lun., 19 ene.–jue., 22 ene. de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
+ assertEquals("lunes, 19 enero–jueves, 22 enero de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
- assertEquals("19 enero – 22 abril 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, 0));
- assertEquals("19 ene – 22 abr 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
- assertEquals("lun 19 ene – mié 22 abr 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
- assertEquals("enero–abril 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
+ assertEquals("19 enero–22 abril de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, 0));
+ assertEquals("19 ene.–22 abr. de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+ assertEquals("lun., 19 ene.–mié., 22 abr. de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
+ assertEquals("enero–abril de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
- assertEquals("19 ene 2009 – 9 feb 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
- assertEquals("ene 2009 – feb 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL));
- assertEquals("19 enero 2009 – 9 febrero 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, 0));
- assertEquals("lunes 19 enero 2009 – jueves 9 febrero 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY));
+ assertEquals("19 ene. de 2009–9 feb. de 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+ assertEquals("ene. 2009–feb. 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL));
+ assertEquals("19 enero de 2009–9 febrero de 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, 0));
+ assertEquals("lunes, 19 enero de 2009–jueves, 9 febrero de 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY));
// The same tests but for es_ES.
assertEquals("19–22 enero 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, 0));
- assertEquals("19–22 ene 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
- assertEquals("lun 19 ene – jue 22 ene 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
- assertEquals("lunes 19 enero – jueves 22 enero 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
-
- assertEquals("19 enero – 22 abril 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, 0));
- assertEquals("19 ene – 22 abr 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
- assertEquals("lun 19 ene – mié 22 abr 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
- assertEquals("enero–abril 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
-
- assertEquals("19 ene 2009 – 9 feb 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
- assertEquals("ene 2009 – feb 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL));
- assertEquals("19 enero 2009 – 9 febrero 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, 0));
- assertEquals("lunes 19 enero 2009 – jueves 9 febrero 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY));
+ assertEquals("19–22 ene. 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+ assertEquals("lun., 19 ene.–jue., 22 ene. de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
+ assertEquals("lunes, 19 enero–jueves, 22 enero de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
+
+ assertEquals("19 enero–22 abril de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, 0));
+ assertEquals("19 ene.–22 abr. de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+ assertEquals("lun., 19 ene.–mié., 22 abr. de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
+ assertEquals("enero–abril de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
+
+ assertEquals("19 ene. de 2009–9 feb. de 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+ assertEquals("ene. 2009–feb. 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL));
+ assertEquals("19 enero de 2009–9 febrero de 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, 0));
+ assertEquals("lunes, 19 enero de 2009–jueves, 9 febrero de 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY));
}
// http://b/8862241 - we should be able to format dates past 2038.
@@ -173,6 +170,7 @@ public class DateIntervalFormatTest extends junit.framework.TestCase {
Locale l = Locale.US;
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
Calendar c = Calendar.getInstance(tz, l);
+ c.clear();
c.set(2042, Calendar.JANUARY, 19, 3, 30);
long jan_19_2042 = c.getTimeInMillis();
c.set(2046, Calendar.OCTOBER, 4, 3, 30);
@@ -221,11 +219,11 @@ public class DateIntervalFormatTest extends junit.framework.TestCase {
assertEquals("4 PM", formatDateRange(l, utc, teaTime, teaTime, abbr12));
// Abbreviated on-the-hour ranges.
- assertEquals("00:00–16:00", formatDateRange(l, utc, midnight, teaTime, abbr24));
+ assertEquals("00:00 – 16:00", formatDateRange(l, utc, midnight, teaTime, abbr24));
assertEquals("12 AM – 4 PM", formatDateRange(l, utc, midnight, teaTime, abbr12));
// Abbreviated mixed ranges.
- assertEquals("00:00–16:01", formatDateRange(l, utc, midnight, teaTime + MINUTE, abbr24));
+ assertEquals("00:00 – 16:01", formatDateRange(l, utc, midnight, teaTime + MINUTE, abbr24));
assertEquals("12:00 AM – 4:01 PM", formatDateRange(l, utc, midnight, teaTime + MINUTE, abbr12));
}
@@ -261,10 +259,49 @@ public class DateIntervalFormatTest extends junit.framework.TestCase {
int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE;
- assertEquals("January 1, 1970, 22:00–00:00", formatDateRange(l, utc, 22 * HOUR, 24 * HOUR, flags));
+ assertEquals("January 1, 1970, 22:00 – 00:00", formatDateRange(l, utc, 22 * HOUR, 24 * HOUR, flags));
assertEquals("January 1, 1970, 22:00 – January 2, 1970, 00:30", formatDateRange(l, utc, 22 * HOUR, 24 * HOUR + 30 * MINUTE, flags));
}
+ // The fix for http://b/10560853 didn't work except for the day around the epoch, which was
+ // all the unit test checked!
+ public void test_single_day_events_later_than_epoch() throws Exception {
+ Locale l = Locale.US;
+ TimeZone utc = TimeZone.getTimeZone("UTC");
+
+ int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE;
+
+ Calendar c = Calendar.getInstance(utc, l);
+ c.clear();
+ c.set(1980, Calendar.JANUARY, 1, 0, 0);
+ long jan_1_1980 = c.getTimeInMillis();
+ assertEquals("January 1, 1980, 22:00 – 00:00",
+ formatDateRange(l, utc, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR, flags));
+ assertEquals("January 1, 1980, 22:00 – January 2, 1980, 00:30",
+ formatDateRange(l, utc, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR + 30 * MINUTE, flags));
+ }
+
+ // The fix for http://b/10560853 didn't work except for UTC, which was
+ // all the unit test checked!
+ public void test_single_day_events_not_in_UTC() throws Exception {
+ Locale l = Locale.US;
+ TimeZone pacific = TimeZone.getTimeZone("America/Los_Angeles");
+
+ int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE;
+
+ Calendar c = Calendar.getInstance(pacific, l);
+ c.clear();
+ c.set(1980, Calendar.JANUARY, 1, 0, 0);
+ long jan_1_1980 = c.getTimeInMillis();
+ assertEquals("January 1, 1980, 22:00 – 00:00",
+ formatDateRange(l, pacific, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR, flags));
+
+ c.set(1980, Calendar.JULY, 1, 0, 0);
+ long jul_1_1980 = c.getTimeInMillis();
+ assertEquals("July 1, 1980, 22:00 – 00:00",
+ formatDateRange(l, pacific, jul_1_1980 + 22 * HOUR, jul_1_1980 + 24 * HOUR, flags));
+ }
+
// http://b/10209343 - even if the caller didn't explicitly ask us to include the year,
// we should do so for years other than the current year.
public void test10209343_when_not_this_year() {
@@ -347,6 +384,7 @@ public class DateIntervalFormatTest extends junit.framework.TestCase {
public void test12004664() throws Exception {
TimeZone utc = TimeZone.getTimeZone("UTC");
Calendar c = Calendar.getInstance(utc, Locale.US);
+ c.clear();
c.set(Calendar.YEAR, 1980);
c.set(Calendar.MONTH, Calendar.FEBRUARY);
c.set(Calendar.DAY_OF_MONTH, 10);
@@ -361,9 +399,9 @@ public class DateIntervalFormatTest extends junit.framework.TestCase {
// the Gregorian calendar, we want to deliberately force icu4c to agree, otherwise we'd have
// a mix of calendars throughout an app's UI depending on whether Java or native code formatted
// the date.
- //assertEquals("یکشنبه Û²Û± بهمن Û±Û³ÛµÛ¸ Ù‡â€.Ø´.", formatDateRange(new Locale("fa"), utc, thisYear, thisYear, flags));
- //assertEquals("AP ۱۳۵۸ سلواغه ۲۱, یکشنبه", formatDateRange(new Locale("ps"), utc, thisYear, thisYear, flags));
- //assertEquals("วันอาทิตย์ 10 à¸à¸¸à¸¡à¸ à¸²à¸žà¸±à¸™à¸˜à¹Œ 2523", formatDateRange(new Locale("th"), utc, thisYear, thisYear, flags));
+ // assertEquals("یکشنبه Û²Û± بهمن Û±Û³ÛµÛ¸ Ù‡â€.Ø´.", formatDateRange(new Locale("fa"), utc, thisYear, thisYear, flags));
+ // assertEquals("AP ۱۳۵۸ سلواغه ۲۱, یکشنبه", formatDateRange(new Locale("ps"), utc, thisYear, thisYear, flags));
+ // assertEquals("วันอาทิตย์ 10 à¸à¸¸à¸¡à¸ à¸²à¸žà¸±à¸™à¸˜à¹Œ 2523", formatDateRange(new Locale("th"), utc, thisYear, thisYear, flags));
// For now, here are the localized Gregorian strings instead...
assertEquals("یکشنبه Û±Û° Ùوریهٔ Û±Û¹Û¸Û°", formatDateRange(new Locale("fa"), utc, thisYear, thisYear, flags));
diff --git a/luni/src/test/java/libcore/icu/ICUTest.java b/luni/src/test/java/libcore/icu/ICUTest.java
index b3d16f9..a7cc7a0 100644
--- a/luni/src/test/java/libcore/icu/ICUTest.java
+++ b/luni/src/test/java/libcore/icu/ICUTest.java
@@ -16,6 +16,8 @@
package libcore.icu;
+import java.text.BreakIterator;
+import java.text.Collator;
import java.util.Arrays;
import java.util.Locale;
@@ -42,26 +44,26 @@ public class ICUTest extends junit.framework.TestCase {
}
public void test_getBestDateTimePattern() throws Exception {
- assertEquals("d MMMM", ICU.getBestDateTimePattern("MMMMd", "ca_ES"));
- assertEquals("d 'de' MMMM", ICU.getBestDateTimePattern("MMMMd", "es_ES"));
- assertEquals("d. MMMM", ICU.getBestDateTimePattern("MMMMd", "de_CH"));
- assertEquals("MMMM d", ICU.getBestDateTimePattern("MMMMd", "en_US"));
- assertEquals("d LLLL", ICU.getBestDateTimePattern("MMMMd", "fa_IR"));
- assertEquals("M月d日", ICU.getBestDateTimePattern("MMMMd", "ja_JP"));
+ assertEquals("d MMMM", ICU.getBestDateTimePattern("MMMMd", new Locale("ca", "ES")));
+ assertEquals("d 'de' MMMM", ICU.getBestDateTimePattern("MMMMd", new Locale("es", "ES")));
+ assertEquals("d. MMMM", ICU.getBestDateTimePattern("MMMMd", new Locale("de", "CH")));
+ assertEquals("MMMM d", ICU.getBestDateTimePattern("MMMMd", new Locale("en", "US")));
+ assertEquals("d LLLL", ICU.getBestDateTimePattern("MMMMd", new Locale("fa", "IR")));
+ assertEquals("M月d日", ICU.getBestDateTimePattern("MMMMd", new Locale("ja", "JP")));
}
public void test_localeFromString() throws Exception {
// localeFromString is pretty lenient. Some of these can't be round-tripped
// through Locale.toString.
- assertEquals(Locale.ENGLISH, ICU.localeFromString("en"));
- assertEquals(Locale.ENGLISH, ICU.localeFromString("en_"));
- assertEquals(Locale.ENGLISH, ICU.localeFromString("en__"));
- assertEquals(Locale.US, ICU.localeFromString("en_US"));
- assertEquals(Locale.US, ICU.localeFromString("en_US_"));
- assertEquals(new Locale("", "US", ""), ICU.localeFromString("_US"));
- assertEquals(new Locale("", "US", ""), ICU.localeFromString("_US_"));
- assertEquals(new Locale("", "", "POSIX"), ICU.localeFromString("__POSIX"));
- assertEquals(new Locale("aa", "BB", "CC"), ICU.localeFromString("aa_BB_CC"));
+ assertEquals(Locale.ENGLISH, ICU.localeFromIcuLocaleId("en"));
+ assertEquals(Locale.ENGLISH, ICU.localeFromIcuLocaleId("en_"));
+ assertEquals(Locale.ENGLISH, ICU.localeFromIcuLocaleId("en__"));
+ assertEquals(Locale.US, ICU.localeFromIcuLocaleId("en_US"));
+ assertEquals(Locale.US, ICU.localeFromIcuLocaleId("en_US_"));
+ assertEquals(new Locale("", "US", ""), ICU.localeFromIcuLocaleId("_US"));
+ assertEquals(new Locale("", "US", ""), ICU.localeFromIcuLocaleId("_US_"));
+ assertEquals(new Locale("", "", "POSIX"), ICU.localeFromIcuLocaleId("__POSIX"));
+ assertEquals(new Locale("aa", "BB", "CC"), ICU.localeFromIcuLocaleId("aa_BB_CC"));
}
public void test_getScript_addLikelySubtags() throws Exception {
@@ -72,8 +74,16 @@ public class ICUTest extends junit.framework.TestCase {
assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("iw_IL")));
}
+ public void test_addLikelySubtags() throws Exception {
+ assertEquals("Latn", ICU.addLikelySubtags(new Locale("en", "US")).getScript());
+ assertEquals("Hebr", ICU.addLikelySubtags(new Locale("he")).getScript());
+ assertEquals("Hebr", ICU.addLikelySubtags(new Locale("he", "IL")).getScript());
+ assertEquals("Hebr", ICU.addLikelySubtags(new Locale("iw")).getScript());
+ assertEquals("Hebr", ICU.addLikelySubtags(new Locale("iw", "IL")).getScript());
+ }
+
private String best(Locale l, String skeleton) {
- return ICU.getBestDateTimePattern(skeleton, l.toString());
+ return ICU.getBestDateTimePattern(skeleton, l);
}
public void test_getDateFormatOrder() throws Exception {
@@ -123,4 +133,124 @@ public class ICUTest extends junit.framework.TestCase {
} catch (IllegalArgumentException expected) {
}
}
+
+ public void testScriptsPassedToIcu() throws Exception {
+ Locale sr_Cyrl_BA = Locale.forLanguageTag("sr-Cyrl-BA");
+ Locale sr_Cyrl_ME = Locale.forLanguageTag("sr-Cyrl-ME");
+ Locale sr_Latn_BA = Locale.forLanguageTag("sr-Latn-BA");
+ Locale sr_Latn_ME = Locale.forLanguageTag("sr-Latn-ME");
+
+ assertEquals("sr_BA_#Cyrl", sr_Cyrl_BA.toString());
+ assertEquals("Cyrl", sr_Cyrl_BA.getScript());
+
+ assertEquals("sr_ME_#Cyrl", sr_Cyrl_ME.toString());
+ assertEquals("Cyrl", sr_Cyrl_ME.getScript());
+
+ assertEquals("sr_BA_#Latn", sr_Latn_BA.toString());
+ assertEquals("Latn", sr_Latn_BA.getScript());
+
+ assertEquals("sr_ME_#Latn", sr_Latn_ME.toString());
+ assertEquals("Latn", sr_Latn_ME.getScript());
+
+ assertEquals("СрпÑки", sr_Cyrl_BA.getDisplayLanguage(sr_Cyrl_BA));
+ assertEquals("БоÑна и Херцеговина", sr_Cyrl_BA.getDisplayCountry(sr_Cyrl_BA));
+ assertEquals("Ћирилица", sr_Cyrl_BA.getDisplayScript(sr_Cyrl_BA));
+ assertEquals("", sr_Cyrl_BA.getDisplayVariant(sr_Cyrl_BA));
+
+ assertEquals("СрпÑки", sr_Cyrl_ME.getDisplayLanguage(sr_Cyrl_ME));
+ assertEquals("Црна Гора", sr_Cyrl_ME.getDisplayCountry(sr_Cyrl_ME));
+ assertEquals("Ћирилица", sr_Cyrl_ME.getDisplayScript(sr_Cyrl_ME));
+ assertEquals("", sr_Cyrl_ME.getDisplayVariant(sr_Cyrl_ME));
+
+ assertEquals("Srpski", sr_Latn_BA.getDisplayLanguage(sr_Latn_BA));
+ assertEquals("Bosna i Hercegovina", sr_Latn_BA.getDisplayCountry(sr_Latn_BA));
+ assertEquals("Latinica", sr_Latn_BA.getDisplayScript(sr_Latn_BA));
+ assertEquals("", sr_Latn_BA.getDisplayVariant(sr_Latn_BA));
+
+ assertEquals("Srpski", sr_Latn_ME.getDisplayLanguage(sr_Latn_ME));
+ assertEquals("Crna Gora", sr_Latn_ME.getDisplayCountry(sr_Latn_ME));
+ assertEquals("Latinica", sr_Latn_ME.getDisplayScript(sr_Latn_ME));
+ assertEquals("", sr_Latn_ME.getDisplayVariant(sr_Latn_ME));
+
+ assertEquals("BIH", sr_Cyrl_BA.getISO3Country());
+ assertEquals("srp", sr_Cyrl_BA.getISO3Language());
+ assertEquals("MNE", sr_Cyrl_ME.getISO3Country());
+ assertEquals("srp", sr_Cyrl_ME.getISO3Language());
+ assertEquals("BIH", sr_Latn_BA.getISO3Country());
+ assertEquals("srp", sr_Latn_BA.getISO3Language());
+ assertEquals("MNE", sr_Latn_ME.getISO3Country());
+ assertEquals("srp", sr_Latn_ME.getISO3Language());
+
+ BreakIterator.getCharacterInstance(sr_Cyrl_BA);
+ BreakIterator.getCharacterInstance(sr_Cyrl_ME);
+ BreakIterator.getCharacterInstance(sr_Latn_BA);
+ BreakIterator.getCharacterInstance(sr_Latn_ME);
+
+ BreakIterator.getLineInstance(sr_Cyrl_BA);
+ BreakIterator.getLineInstance(sr_Cyrl_ME);
+ BreakIterator.getLineInstance(sr_Latn_BA);
+ BreakIterator.getLineInstance(sr_Latn_ME);
+
+ BreakIterator.getSentenceInstance(sr_Cyrl_BA);
+ BreakIterator.getSentenceInstance(sr_Cyrl_ME);
+ BreakIterator.getSentenceInstance(sr_Latn_BA);
+ BreakIterator.getSentenceInstance(sr_Latn_ME);
+
+ BreakIterator.getWordInstance(sr_Cyrl_BA);
+ BreakIterator.getWordInstance(sr_Cyrl_ME);
+ BreakIterator.getWordInstance(sr_Latn_BA);
+ BreakIterator.getWordInstance(sr_Latn_ME);
+
+ Collator.getInstance(sr_Cyrl_BA);
+ Collator.getInstance(sr_Cyrl_ME);
+ Collator.getInstance(sr_Latn_BA);
+ Collator.getInstance(sr_Latn_ME);
+
+ Locale l = Locale.forLanguageTag("de-u-co-phonebk-kf-upper-kn");
+ assertEquals("de__#u-co-phonebk-kf-upper-kn", l.toString());
+ assertEquals("de-u-co-phonebk-kf-upper-kn", l.toLanguageTag());
+
+ Collator c = Collator.getInstance(l);
+ assertTrue(c.compare("2", "11") < 0);
+ assertTrue(c.compare("11", "ae") < 0);
+ assertTrue(c.compare("ae", "Ä") < 0);
+ assertTrue(c.compare("Ä", "ä") < 0);
+ assertTrue(c.compare("ä", "AF") < 0);
+ assertTrue(c.compare("AF", "af") < 0);
+ }
+
+ // Test for the behavior of currency symbol lookup when an unrecognized locale has been set as the
+ // default.
+ public void testIcuDefaultAffectsCurrencySymbol() {
+ // A locale that is not going to be recognized by ICU and should fallback to "root" for the
+ // currency symbol.
+ final Locale unrecognizedLocale = new Locale("xy", "KR");
+
+ // A known locale with a relatively stable representation for its currency symbol.
+ final Locale enUsLocale = new Locale("en", "US");
+ final String usDollar = "USD";
+
+ String initialDefaultLocale = ICU.getDefaultLocale();
+ try {
+ // Confirm the "$" symbol for USD in en-US.
+ assertEquals("$", ICU.getCurrencySymbol(enUsLocale, usDollar));
+
+ // Set the default so this will be used as fallback for the unrecognized locale symbol lookup.
+ ICU.setDefaultLocale(enUsLocale.toLanguageTag());
+
+ // Demonstrate the USD symbol is reported as "$" for the unrecognized locale (which is using
+ // the default).
+ assertEquals("$", ICU.getCurrencySymbol(unrecognizedLocale, usDollar));
+
+ // Change the default.
+ ICU.setDefaultLocale(unrecognizedLocale.toLanguageTag());
+
+ String currencySymbolAfterDefaultChange = ICU.getCurrencySymbol(unrecognizedLocale, usDollar);
+ // "$US" is the value from root. With an unrecognized locale argument, and an unrecognized
+ // locale as the default, ICU has returns the value in root.
+ assertEquals("US$", currencySymbolAfterDefaultChange);
+ } finally {
+ ICU.setDefaultLocale(initialDefaultLocale);
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/icu/LocaleDataTest.java b/luni/src/test/java/libcore/icu/LocaleDataTest.java
index 27eda86..0a83c53 100644
--- a/luni/src/test/java/libcore/icu/LocaleDataTest.java
+++ b/luni/src/test/java/libcore/icu/LocaleDataTest.java
@@ -19,104 +19,116 @@ package libcore.icu;
import java.util.Locale;
public class LocaleDataTest extends junit.framework.TestCase {
- public void testAll() throws Exception {
- // Test that we can get the locale data for all known locales.
- for (Locale l : Locale.getAvailableLocales()) {
- LocaleData d = LocaleData.get(l);
- // System.err.format("%10s %10s %10s\n", l, d.timeFormat12, d.timeFormat24);
- }
- }
-
- public void test_en_US() throws Exception {
- LocaleData l = LocaleData.get(Locale.US);
- assertEquals("AM", l.amPm[0]);
- assertEquals("BC", l.eras[0]);
-
- assertEquals("January", l.longMonthNames[0]);
- assertEquals("Jan", l.shortMonthNames[0]);
- assertEquals("J", l.tinyMonthNames[0]);
-
- assertEquals("January", l.longStandAloneMonthNames[0]);
- assertEquals("Jan", l.shortStandAloneMonthNames[0]);
- assertEquals("J", l.tinyStandAloneMonthNames[0]);
-
- assertEquals("Sunday", l.longWeekdayNames[1]);
- assertEquals("Sun", l.shortWeekdayNames[1]);
- assertEquals("S", l.tinyWeekdayNames[1]);
-
- assertEquals("Sunday", l.longStandAloneWeekdayNames[1]);
- assertEquals("Sun", l.shortStandAloneWeekdayNames[1]);
- assertEquals("S", l.tinyStandAloneWeekdayNames[1]);
-
- assertEquals("Yesterday", l.yesterday);
- assertEquals("Today", l.today);
- assertEquals("Tomorrow", l.tomorrow);
- }
-
- public void test_de_DE() throws Exception {
- LocaleData l = LocaleData.get(new Locale("de", "DE"));
-
- assertEquals("Gestern", l.yesterday);
- assertEquals("Heute", l.today);
- assertEquals("Morgen", l.tomorrow);
- }
-
- public void test_cs_CZ() throws Exception {
- LocaleData l = LocaleData.get(new Locale("cs", "CZ"));
-
- assertEquals("ledna", l.longMonthNames[0]);
- assertEquals("led", l.shortMonthNames[0]);
- assertEquals("1", l.tinyMonthNames[0]);
-
- assertEquals("leden", l.longStandAloneMonthNames[0]);
- assertEquals("led", l.shortStandAloneMonthNames[0]);
- assertEquals("l", l.tinyStandAloneMonthNames[0]);
- }
-
- public void test_ru_RU() throws Exception {
- LocaleData l = LocaleData.get(new Locale("ru", "RU"));
-
- assertEquals("воÑкреÑенье", l.longWeekdayNames[1]);
- assertEquals("вÑ", l.shortWeekdayNames[1]);
- assertEquals("вÑ", l.tinyWeekdayNames[1]);
-
- // Russian stand-alone weekday names get an initial capital.
- assertEquals("ВоÑкреÑенье", l.longStandAloneWeekdayNames[1]);
- assertEquals("Ð’Ñ", l.shortStandAloneWeekdayNames[1]);
- assertEquals("Ð’", l.tinyStandAloneWeekdayNames[1]);
- }
-
- // http://code.google.com/p/android/issues/detail?id=38844
- public void testDecimalFormatSymbols_es() throws Exception {
- LocaleData es = LocaleData.get(new Locale("es"));
- assertEquals(',', es.decimalSeparator);
- assertEquals('.', es.groupingSeparator);
-
- LocaleData es_419 = LocaleData.get(new Locale("es", "419"));
- assertEquals('.', es_419.decimalSeparator);
- assertEquals(',', es_419.groupingSeparator);
-
- LocaleData es_US = LocaleData.get(new Locale("es", "US"));
- assertEquals('.', es_US.decimalSeparator);
- assertEquals(',', es_US.groupingSeparator);
-
- LocaleData es_MX = LocaleData.get(new Locale("es", "MX"));
- assertEquals('.', es_MX.decimalSeparator);
- assertEquals(',', es_MX.groupingSeparator);
-
- LocaleData es_AR = LocaleData.get(new Locale("es", "AR"));
- assertEquals(',', es_AR.decimalSeparator);
- assertEquals('.', es_AR.groupingSeparator);
- }
-
- // http://b/7924970
- public void testTimeFormat12And24() throws Exception {
- LocaleData en_US = LocaleData.get(Locale.US);
- assertEquals("h:mm a", en_US.timeFormat12);
- assertEquals("HH:mm", en_US.timeFormat24);
-
- LocaleData ja_JP = LocaleData.get(Locale.JAPAN);
- assertEquals("aK:mm", ja_JP.timeFormat12);
- assertEquals("H:mm", ja_JP.timeFormat24);
+ public void testAll() throws Exception {
+ // Test that we can get the locale data for all known locales.
+ for (Locale l : Locale.getAvailableLocales()) {
+ LocaleData d = LocaleData.get(l);
+ // System.err.format("%20s %s %s %s\n", l, d.yesterday, d.today, d.tomorrow);
+ // System.err.format("%20s %10s %10s\n", l, d.timeFormat12, d.timeFormat24);
}
+ }
+
+ public void test_en_US() throws Exception {
+ LocaleData l = LocaleData.get(Locale.US);
+ assertEquals("AM", l.amPm[0]);
+ assertEquals("a", l.narrowAm);
+
+ assertEquals("BC", l.eras[0]);
+
+ assertEquals("January", l.longMonthNames[0]);
+ assertEquals("Jan", l.shortMonthNames[0]);
+ assertEquals("J", l.tinyMonthNames[0]);
+
+ assertEquals("January", l.longStandAloneMonthNames[0]);
+ assertEquals("Jan", l.shortStandAloneMonthNames[0]);
+ assertEquals("J", l.tinyStandAloneMonthNames[0]);
+
+ assertEquals("Sunday", l.longWeekdayNames[1]);
+ assertEquals("Sun", l.shortWeekdayNames[1]);
+ assertEquals("S", l.tinyWeekdayNames[1]);
+
+ assertEquals("Sunday", l.longStandAloneWeekdayNames[1]);
+ assertEquals("Sun", l.shortStandAloneWeekdayNames[1]);
+ assertEquals("S", l.tinyStandAloneWeekdayNames[1]);
+
+ assertEquals("Yesterday", l.yesterday);
+ assertEquals("Today", l.today);
+ assertEquals("Tomorrow", l.tomorrow);
+ }
+
+ public void test_de_DE() throws Exception {
+ LocaleData l = LocaleData.get(new Locale("de", "DE"));
+
+ assertEquals("Gestern", l.yesterday);
+ assertEquals("Heute", l.today);
+ assertEquals("Morgen", l.tomorrow);
+ }
+
+ public void test_cs_CZ() throws Exception {
+ LocaleData l = LocaleData.get(new Locale("cs", "CZ"));
+
+ assertEquals("ledna", l.longMonthNames[0]);
+ assertEquals("led", l.shortMonthNames[0]);
+ assertEquals("1", l.tinyMonthNames[0]);
+
+ assertEquals("leden", l.longStandAloneMonthNames[0]);
+ assertEquals("led", l.shortStandAloneMonthNames[0]);
+ assertEquals("l", l.tinyStandAloneMonthNames[0]);
+ }
+
+ public void test_ko_KR() throws Exception {
+ LocaleData l = LocaleData.get(new Locale("ko", "KR"));
+
+ // Ensure the fix for http://b/14493853 doesn't mangle Hangul.
+ assertEquals("어제", l.yesterday);
+ assertEquals("오늘", l.today);
+ assertEquals("ë‚´ì¼", l.tomorrow);
+ }
+
+ public void test_ru_RU() throws Exception {
+ LocaleData l = LocaleData.get(new Locale("ru", "RU"));
+
+ assertEquals("воÑкреÑенье", l.longWeekdayNames[1]);
+ assertEquals("вÑ", l.shortWeekdayNames[1]);
+ assertEquals("вÑ", l.tinyWeekdayNames[1]);
+
+ // Russian stand-alone weekday names get an initial capital.
+ assertEquals("ВоÑкреÑенье", l.longStandAloneWeekdayNames[1]);
+ assertEquals("Ð’Ñ", l.shortStandAloneWeekdayNames[1]);
+ assertEquals("Ð’", l.tinyStandAloneWeekdayNames[1]);
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=38844
+ public void testDecimalFormatSymbols_es() throws Exception {
+ LocaleData es = LocaleData.get(new Locale("es"));
+ assertEquals(',', es.decimalSeparator);
+ assertEquals('.', es.groupingSeparator);
+
+ LocaleData es_419 = LocaleData.get(new Locale("es", "419"));
+ assertEquals('.', es_419.decimalSeparator);
+ assertEquals(',', es_419.groupingSeparator);
+
+ LocaleData es_US = LocaleData.get(new Locale("es", "US"));
+ assertEquals('.', es_US.decimalSeparator);
+ assertEquals(',', es_US.groupingSeparator);
+
+ LocaleData es_MX = LocaleData.get(new Locale("es", "MX"));
+ assertEquals('.', es_MX.decimalSeparator);
+ assertEquals(',', es_MX.groupingSeparator);
+
+ LocaleData es_AR = LocaleData.get(new Locale("es", "AR"));
+ assertEquals(',', es_AR.decimalSeparator);
+ assertEquals('.', es_AR.groupingSeparator);
+ }
+
+ // http://b/7924970
+ public void testTimeFormat12And24() throws Exception {
+ LocaleData en_US = LocaleData.get(Locale.US);
+ assertEquals("h:mm a", en_US.timeFormat12);
+ assertEquals("HH:mm", en_US.timeFormat24);
+
+ LocaleData ja_JP = LocaleData.get(Locale.JAPAN);
+ assertEquals("aK:mm", ja_JP.timeFormat12);
+ assertEquals("H:mm", ja_JP.timeFormat24);
+ }
}
diff --git a/luni/src/test/java/libcore/icu/NativePluralRulesTest.java b/luni/src/test/java/libcore/icu/NativePluralRulesTest.java
index 73699ff..703a94a 100644
--- a/luni/src/test/java/libcore/icu/NativePluralRulesTest.java
+++ b/luni/src/test/java/libcore/icu/NativePluralRulesTest.java
@@ -21,7 +21,6 @@ import java.util.Locale;
public class NativePluralRulesTest extends junit.framework.TestCase {
public void testEnglish() throws Exception {
NativePluralRules npr = NativePluralRules.forLocale(new Locale("en", "US"));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(-1));
assertEquals(NativePluralRules.OTHER, npr.quantityForInt(0));
assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
assertEquals(NativePluralRules.OTHER, npr.quantityForInt(2));
@@ -29,7 +28,6 @@ public class NativePluralRulesTest extends junit.framework.TestCase {
public void testCzech() throws Exception {
NativePluralRules npr = NativePluralRules.forLocale(new Locale("cs", "CZ"));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(-1));
assertEquals(NativePluralRules.OTHER, npr.quantityForInt(0));
assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
assertEquals(NativePluralRules.FEW, npr.quantityForInt(2));
@@ -40,7 +38,6 @@ public class NativePluralRulesTest extends junit.framework.TestCase {
public void testArabic() throws Exception {
NativePluralRules npr = NativePluralRules.forLocale(new Locale("ar"));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(-1));
assertEquals(NativePluralRules.ZERO, npr.quantityForInt(0));
assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
assertEquals(NativePluralRules.TWO, npr.quantityForInt(2));
@@ -62,6 +59,7 @@ public class NativePluralRulesTest extends junit.framework.TestCase {
assertEquals(NativePluralRules.ONE, he.quantityForInt(1));
assertEquals(NativePluralRules.TWO, he.quantityForInt(2));
assertEquals(NativePluralRules.OTHER, he.quantityForInt(3));
- assertEquals(NativePluralRules.MANY, he.quantityForInt(10));
+ assertEquals(NativePluralRules.OTHER, he.quantityForInt(10));
}
}
+
diff --git a/luni/src/test/java/libcore/icu/TimeZoneNamesTest.java b/luni/src/test/java/libcore/icu/TimeZoneNamesTest.java
index c2f8312..57943b0 100644
--- a/luni/src/test/java/libcore/icu/TimeZoneNamesTest.java
+++ b/luni/src/test/java/libcore/icu/TimeZoneNamesTest.java
@@ -59,4 +59,11 @@ public class TimeZoneNamesTest extends junit.framework.TestCase {
assertTrue(TimeZoneNames.forLocale(l) != null);
}
}
+
+ public void test_getExemplarLocation() throws Exception {
+ assertEquals("Moscow", TimeZoneNames.getExemplarLocation("en_US", "Europe/Moscow"));
+ assertEquals("Moskau", TimeZoneNames.getExemplarLocation("de_DE", "Europe/Moscow"));
+ assertEquals("Seoul", TimeZoneNames.getExemplarLocation("en_US", "Asia/Seoul"));
+ assertEquals("서울", TimeZoneNames.getExemplarLocation("ko_KR", "Asia/Seoul"));
+ }
}
diff --git a/luni/src/test/java/libcore/io/MemoryTest.java b/luni/src/test/java/libcore/io/MemoryTest.java
index 9a596fb..c817b20 100644
--- a/luni/src/test/java/libcore/io/MemoryTest.java
+++ b/luni/src/test/java/libcore/io/MemoryTest.java
@@ -32,10 +32,10 @@ public class MemoryTest extends TestCase {
int scale = SizeOf.INT;
VMRuntime runtime = VMRuntime.getRuntime();
byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1);
- int base_ptr = (int) runtime.addressOf(array);
+ long base_ptr = runtime.addressOf(array);
for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) {
- int ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses.
+ long ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses.
Arrays.fill(array, (byte) 0);
// Regular copy.
@@ -57,7 +57,7 @@ public class MemoryTest extends TestCase {
}
}
- private void assertIntsEqual(int[] expectedValues, int ptr, boolean swap) {
+ private void assertIntsEqual(int[] expectedValues, long ptr, boolean swap) {
for (int i = 0; i < expectedValues.length; ++i) {
assertEquals(expectedValues[i], Memory.peekInt(ptr + SizeOf.INT * i, swap));
}
@@ -73,10 +73,10 @@ public class MemoryTest extends TestCase {
int scale = SizeOf.LONG;
VMRuntime runtime = VMRuntime.getRuntime();
byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1);
- int base_ptr = (int) runtime.addressOf(array);
+ long base_ptr = runtime.addressOf(array);
for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) {
- int ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses.
+ long ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses.
Arrays.fill(array, (byte) 0);
// Regular copy.
@@ -98,7 +98,7 @@ public class MemoryTest extends TestCase {
}
}
- private void assertLongsEqual(long[] expectedValues, int ptr, boolean swap) {
+ private void assertLongsEqual(long[] expectedValues, long ptr, boolean swap) {
for (int i = 0; i < expectedValues.length; ++i) {
assertEquals(expectedValues[i], Memory.peekLong(ptr + SizeOf.LONG * i, swap));
}
@@ -111,10 +111,10 @@ public class MemoryTest extends TestCase {
int scale = SizeOf.SHORT;
VMRuntime runtime = VMRuntime.getRuntime();
byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1);
- int base_ptr = (int) runtime.addressOf(array);
+ long base_ptr = runtime.addressOf(array);
for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) {
- int ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses.
+ long ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses.
Arrays.fill(array, (byte) 0);
// Regular copy.
@@ -136,7 +136,7 @@ public class MemoryTest extends TestCase {
}
}
- private void assertShortsEqual(short[] expectedValues, int ptr, boolean swap) {
+ private void assertShortsEqual(short[] expectedValues, long ptr, boolean swap) {
for (int i = 0; i < expectedValues.length; ++i) {
assertEquals(expectedValues[i], Memory.peekShort(ptr + SizeOf.SHORT * i, swap));
}
diff --git a/luni/src/test/java/libcore/io/OsTest.java b/luni/src/test/java/libcore/io/OsTest.java
index 624c119..cf28122 100644
--- a/luni/src/test/java/libcore/io/OsTest.java
+++ b/luni/src/test/java/libcore/io/OsTest.java
@@ -16,6 +16,7 @@
package libcore.io;
+import android.system.StructUcred;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -26,8 +27,7 @@ import java.net.ServerSocket;
import java.net.SocketAddress;
import java.util.Locale;
import junit.framework.TestCase;
-
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
public class OsTest extends TestCase {
public void testIsSocket() throws Exception {
diff --git a/luni/src/test/java/libcore/java/io/FileTest.java b/luni/src/test/java/libcore/java/io/FileTest.java
index b2391ac..b4101f9 100644
--- a/luni/src/test/java/libcore/java/io/FileTest.java
+++ b/luni/src/test/java/libcore/java/io/FileTest.java
@@ -16,11 +16,9 @@
package libcore.java.io;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
-import java.io.InputStreamReader;
import java.io.IOException;
import java.util.UUID;
import libcore.io.Libcore;
@@ -62,7 +60,13 @@ public class FileTest extends junit.framework.TestCase {
assertTrue(createDeepStructure(base).exists());
}
- // readlink(2) is a special case,.
+ /*
+ * readlink(2) is a special case,.
+ *
+ * This test assumes you can create symbolic links in the temporary directory. This
+ * isn't true on Android if you're using /sdcard (which is used if this test is
+ * run using vogar). It will work in /data/data/ though.
+ */
public void test_longReadlink() throws Exception {
File base = createTemporaryDirectory();
File target = createDeepStructure(base);
@@ -144,10 +148,14 @@ public class FileTest extends junit.framework.TestCase {
new MyFile("");
}
- // http://b/3047893 - getCanonicalPath wasn't actually resolving symbolic links.
+ /*
+ * http://b/3047893 - getCanonicalPath wasn't actually resolving symbolic links.
+ *
+ * This test assumes you can create symbolic links in the temporary directory. This
+ * isn't true on Android if you're using /sdcard (which is used if this test is
+ * run using vogar). It will work in /data/data/ though.
+ */
public void test_getCanonicalPath() throws Exception {
- // This assumes you can create symbolic links in the temporary directory. This isn't
- // true on Android if you're using /sdcard. It will work in /data/local though.
File base = createTemporaryDirectory();
File target = new File(base, "target");
target.createNewFile(); // The RI won't follow a dangling symlink, which seems like a bug!
@@ -208,16 +216,13 @@ public class FileTest extends junit.framework.TestCase {
}
public void test_getAbsolutePath() throws Exception {
- String originalUserDir = System.getProperty("user.dir");
- try {
- File f = new File("poop");
- System.setProperty("user.dir", "/a");
- assertEquals("/a/poop", f.getAbsolutePath());
- System.setProperty("user.dir", "/b");
- assertEquals("/b/poop", f.getAbsolutePath());
- } finally {
- System.setProperty("user.dir", originalUserDir);
+ String userDir = System.getProperty("user.dir");
+ if (!userDir.endsWith(File.separator)) {
+ userDir = userDir + File.separator;
}
+
+ File f = new File("poop");
+ assertEquals(userDir + "poop", f.getAbsolutePath());
}
public void test_getSpace() throws Exception {
diff --git a/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java b/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java
index e5fd39f..30ae7eb 100755
--- a/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java
+++ b/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java
@@ -207,7 +207,10 @@ public final class InterruptedStreamTest extends TestCase {
private static void confirmInterrupted(Thread thread) throws InterruptedException {
// validate and clear interrupted bit before join
- assertTrue(Thread.interrupted());
- thread.join();
+ try {
+ assertTrue(Thread.interrupted());
+ } finally {
+ thread.join();
+ }
}
}
diff --git a/luni/src/test/java/libcore/java/io/OldBufferedInputStreamTest.java b/luni/src/test/java/libcore/java/io/OldBufferedInputStreamTest.java
deleted file mode 100644
index a3ef4e4..0000000
--- a/luni/src/test/java/libcore/java/io/OldBufferedInputStreamTest.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.io;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import junit.framework.TestCase;
-import tests.support.Support_ASimpleInputStream;
-import tests.support.Support_PlatformFile;
-
-public class OldBufferedInputStreamTest extends TestCase {
-
- public String fileName;
- private BufferedInputStream is;
- private FileInputStream isFile;
- public String fileString = "Test_All_Tests\nTest_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
-
- public void test_ConstructorLjava_io_InputStream() {
- is = new BufferedInputStream(isFile);
-
- try {
- is.read();
- } catch (Exception e) {
- fail("Test 1: Read failed on a freshly constructed buffer.");
- }
- }
-
- public void test_ConstructorLjava_io_InputStreamI() throws IOException {
- // regression test for harmony-2407
- new testBufferedInputStream(null);
- assertNotNull(testBufferedInputStream.buf);
- testBufferedInputStream.buf = null;
- new testBufferedInputStream(null, 100);
- assertNotNull(testBufferedInputStream.buf);
- }
-
- static class testBufferedInputStream extends BufferedInputStream {
- static byte[] buf;
- testBufferedInputStream(InputStream is) throws IOException {
- super(is);
- buf = super.buf;
- }
-
- testBufferedInputStream(InputStream is, int size) throws IOException {
- super(is, size);
- buf = super.buf;
- }
- }
-
- public void test_available() {
- // Test for method int java.io.BufferedInputStream.available()
- try {
- assertTrue("Returned incorrect number of available bytes", is
- .available() == fileString.length());
- } catch (IOException e) {
- fail("Exception during available test");
- }
-
- // Test that a closed stream throws an IOE for available()
- BufferedInputStream bis = new BufferedInputStream(
- new ByteArrayInputStream(new byte[] { 'h', 'e', 'l', 'l', 'o',
- ' ', 't', 'i', 'm' }));
- int available = 0;
- try {
- available = bis.available();
- bis.close();
- } catch (IOException ex) {
- fail();
- }
- assertTrue(available != 0);
-
- try {
- bis.available();
- fail("Expected test to throw IOE.");
- } catch (IOException ex) {
- // expected
- } catch (Throwable ex) {
- fail("Expected test to throw IOE not "
- + ex.getClass().getName());
- }
- }
-
- public void test_close() throws IOException {
- is.close();
-
- try {
- is.read();
- fail("Test 1: IOException expected when reading after closing " +
- "the stream.");
- } catch (IOException e) {
- // Expected.
- }
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(true);
- is = new BufferedInputStream(sis);
- try {
- is.close();
- fail("Test 2: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- }
-
- public void test_markI_reset() throws IOException {
- byte[] buf1 = new byte[100];
- byte[] buf2 = new byte[100];
-
- // Test 1: Check that reset fails if no mark has been set.
- try {
- is.reset();
- fail("Test 1: IOException expected if no mark has been set.");
- } catch (IOException e) {
- // Expected.
- }
-
- // Test 2: Check that mark / reset works when the mark is not invalidated.
- is.skip(10);
- is.mark(100);
- is.read(buf1, 0, buf1.length);
- is.reset();
- is.read(buf2, 0, buf2.length);
- is.reset();
- assertTrue("Test 2: Failed to mark correct position or reset failed.",
- new String(buf1, 0, buf1.length).equals(new String(buf2, 0, buf2.length)));
-
- // Tests 3 and 4: Check that skipping less than readlimit bytes does
- // not invalidate the mark.
- is.skip(10);
- try {
- is.reset();
- } catch (IOException e) {
- fail("Test 3: Unexpected IOException " + e.getMessage());
- }
- is.read(buf2, 0, buf2.length);
- is.reset();
- assertTrue("Test 4: Failed to mark correct position, or reset failed.",
- new String(buf1, 0, buf1.length).equals(new String(buf2, 0, buf2.length)));
-
- // Test 8: Check that reset fails for a closed input stream.
- is.close();
- try {
- is.reset();
- fail("Test 8: IOException expected because the input stream is closed.");
- } catch (IOException e) {
- // Expected.
- }
- }
-
- public void test_read() throws IOException {
- int c = is.read();
- assertTrue("Test 1: Incorrect character read.",
- c == fileString.charAt(0));
-
- byte[] bytes = new byte[256];
- for (int i = 0; i < 256; i++) {
- bytes[i] = (byte) i;
- }
-
- BufferedInputStream in = new BufferedInputStream(
- new ByteArrayInputStream(bytes), 5);
-
- // Read more bytes than are buffered.
- for (int i = 0; i < 10; i++) {
- assertEquals("Test 2: Incorrect byte read;", bytes[i], in.read());
- }
-
- in.close();
- try {
- in.read();
- fail("Test 3: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- }
-
- @Override
- protected void setUp() throws IOException {
- fileName = System.getProperty("user.dir");
- String separator = System.getProperty("file.separator");
- if (fileName.charAt(fileName.length() - 1) == separator.charAt(0)) {
- fileName = Support_PlatformFile.getNewPlatformFile(fileName,
- "input.tst");
- } else {
- fileName = Support_PlatformFile.getNewPlatformFile(fileName
- + separator, "input.tst");
- }
- OutputStream fos = new FileOutputStream(fileName);
- fos.write(fileString.getBytes());
- fos.close();
- isFile = new FileInputStream(fileName);
- is = new BufferedInputStream(isFile);
- }
-
- @Override
- protected void tearDown() {
- try {
- is.close();
- } catch (Exception e) {
- }
- try {
- File f = new File(fileName);
- f.delete();
- } catch (Exception e) {
- }
- }
-}
diff --git a/luni/src/test/java/libcore/java/io/OldFileInputStreamTest.java b/luni/src/test/java/libcore/java/io/OldFileInputStreamTest.java
deleted file mode 100644
index 894849a..0000000
--- a/luni/src/test/java/libcore/java/io/OldFileInputStreamTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.io;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import junit.framework.TestCase;
-import tests.support.Support_PlatformFile;
-
-public class OldFileInputStreamTest extends TestCase {
-
- public String fileName;
- private FileInputStream is;
- public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
-
- public void test_ConstructorLjava_io_File() {
- // Test for method FileInputStream(File)
- try {
- File f = new File(fileName);
- is = new FileInputStream(f);
- is.close();
- } catch (Exception e) {
- fail("Failed to create FileInputStream : " + e.getMessage());
- }
- File f2 = new File("ImprobableFile.42");
- try {
- is = new FileInputStream(f2);
- is.close();
- f2.delete();
- fail("FileNotFoundException expected.");
- } catch (FileNotFoundException e) {
- // Expected.
- } catch (IOException e) {
- fail("Unexpected IOException: " + e.getMessage());
- }
- }
-
- public void test_ConstructorLjava_io_FileDescriptor() {
- try {
- FileInputStream fis = new FileInputStream((FileDescriptor) null);
- fis.close();
- fail("NullPointerException expected.");
- } catch (NullPointerException e) {
- // Expected.
- } catch (IOException e) {
- fail("Unexpected IOException: " + e.getMessage());
- }
- }
-
- public void test_ConstructorLjava_lang_String() {
- // Test for method FileInputStream(java.lang.String)
- try {
- is = new FileInputStream(fileName);
- is.close();
- } catch (Exception e) {
- fail("Failed to create FileInputStream : " + e.getMessage());
- }
- try {
- is = new FileInputStream("ImprobableFile.42");
- is.close();
- new File("ImprobableFile.42").delete();
- fail("FileNotFoundException expected.");
- } catch (FileNotFoundException e) {
- // Expected.
- } catch (IOException e) {
- fail("Unexpected IOException: " + e.getMessage());
- }
- }
-
- public void test_available() throws IOException {
- is = new FileInputStream(fileName);
- assertEquals("Test 1: Returned incorrect number of available bytes;",
- fileString.length(), is.available());
- is.close();
- try {
- is.available();
- fail("Test 2: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- }
-
- public void test_getChannel() {
- // Test for method FileChannel FileInputStream.getChannel()
- FileChannel channel;
- byte[] buffer = new byte[100];
- byte[] stringBytes;
- final int offset = 5;
- boolean equal = true;
-
- try {
- FileInputStream fis = new FileInputStream(fileName);
- channel = fis.getChannel();
- assertNotNull(channel);
- assertTrue("Channel is closed.", channel.isOpen());
-
- // Check that the channel is associated with the input stream.
- channel.position(offset);
- fis.read(buffer, 0, 10);
- stringBytes = fileString.getBytes();
- for (int i = 0; i < 10; i++) {
- equal &= (buffer[i] == stringBytes[i + offset]);
- }
- assertTrue("Channel is not associated with this stream.", equal);
-
- fis.close();
- assertFalse("Channel has not been closed.", channel.isOpen());
- } catch (FileNotFoundException e) {
- fail("Could not find : " + fileName);
- }
-
- catch (IOException e) {
- fail("Exception during test : " + e.getMessage());
- }
- }
-
- public void test_read() throws IOException {
- is = new FileInputStream(fileName);
- int c = is.read();
- assertEquals("Test 1: Read returned incorrect char;",
- fileString.charAt(0), c);
-
- is.close();
- try {
- is.read();
- fail("Test 2: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- }
-
- public void test_read$B() throws IOException {
- byte[] buf1 = new byte[100];
- is = new FileInputStream(fileName);
- is.skip(3000);
- is.read(buf1);
- is.close();
- assertTrue("Test 1: Failed to read correct data.",
- new String(buf1, 0, buf1.length).equals(
- fileString.substring(3000, 3100)));
-
- is.close();
- try {
- is.read(buf1);
- fail("Test 2: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- }
-
- public void test_skipJ() throws IOException {
- byte[] buf1 = new byte[10];
- is = new FileInputStream(fileName);
- is.skip(1000);
- is.read(buf1, 0, buf1.length);
- assertTrue("Test 1: Failed to skip to correct position.",
- new String(buf1, 0, buf1.length).equals(
- fileString.substring(1000, 1010)));
-
- is.close();
- try {
- is.read();
- fail("Test 2: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- }
-
- protected void setUp() throws Exception {
- fileName = System.getProperty("java.io.tmpdir");
- String separator = System.getProperty("file.separator");
- if (fileName.charAt(fileName.length() - 1) == separator.charAt(0))
- fileName = Support_PlatformFile.getNewPlatformFile(fileName,
- "input.tst");
- else
- fileName = Support_PlatformFile.getNewPlatformFile(fileName
- + separator, "input.tst");
- java.io.OutputStream fos = new FileOutputStream(fileName);
- fos.write(fileString.getBytes());
- fos.close();
- }
-
- protected void tearDown() throws Exception {
- if (is != null) {
- is.close();
- }
- new File(fileName).delete();
- }
-}
diff --git a/luni/src/test/java/libcore/java/io/OldFileTest.java b/luni/src/test/java/libcore/java/io/OldFileTest.java
index 8265d20..07ca161 100644
--- a/luni/src/test/java/libcore/java/io/OldFileTest.java
+++ b/luni/src/test/java/libcore/java/io/OldFileTest.java
@@ -18,7 +18,6 @@
package libcore.java.io;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
@@ -27,16 +26,6 @@ import static tests.support.Support_Exec.execAndGetOutput;
import static tests.support.Support_Exec.javaProcessBuilder;
public class OldFileTest extends TestCase {
-
- /** Location to store tests in */
- private File tempDirectory;
-
- /** Temp file that does exist */
- private File tempFile;
-
- /** File separator */
- private String slash = File.separator;
-
public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_File\nTest_FileDescriptor\nTest_FileInputStream\nTest_FileNotFoundException\nTest_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
private static String platformId = "Android"
@@ -72,76 +61,66 @@ public class OldFileTest extends TestCase {
}
public void test_ConstructorLjava_io_FileLjava_lang_String() throws Exception {
- String error;
- String dirName = System.getProperty("java.io.tmpdir");
- System.setProperty("user.dir", dirName);
+ String tmpDirName = System.getProperty("java.io.tmpdir");
- File d = new File(dirName);
+ File d = new File(tmpDirName);
File f = new File(d, "input.tst");
- if (!dirName.regionMatches((dirName.length() - 1), slash, 0, 1))
- dirName += slash;
- dirName += "input.tst";
- error = String.format("Test 1: Incorrect file created: %s; %s expected.", f.getPath(), dirName);
- assertTrue(error, f.getPath().equals(dirName));
+
+ if (!tmpDirName.endsWith(File.separator)) {
+ tmpDirName += File.separator;
+ }
+ tmpDirName += "input.tst";
+
+ assertEquals(tmpDirName, f.getPath());
String fileName = null;
try {
f = new File(d, fileName);
- fail("Test 2: NullPointerException expected.");
- } catch (NullPointerException e) {
+ fail();
+ } catch (NullPointerException expected) {
}
- d = null;
f = new File(d, "input.tst");
- error = String.format("Test 3: Incorrect file created: %s; %s expected.",
- f.getAbsolutePath(), dirName);
- assertTrue(error, f.getAbsolutePath().equals(dirName));
+ assertEquals(tmpDirName, f.getAbsolutePath());
// Regression test for Harmony-382
File s = null;
f = new File("/abc");
d = new File(s, "/abc");
- assertEquals("Test 4: Incorrect file created;",
- f.getAbsolutePath(), d.getAbsolutePath());
+ assertEquals(f.getAbsolutePath(), d.getAbsolutePath());
}
public void test_ConstructorLjava_lang_StringLjava_lang_String() throws IOException {
- String dirName = null;
- String fileName = "input.tst";
-
- String userDir = System.getProperty("java.io.tmpdir");
- System.setProperty("user.dir", userDir);
+ String tmpDir = System.getProperty("java.io.tmpdir");
+ if (!tmpDir.endsWith(File.separator)) {
+ tmpDir += File.separator;
+ }
- File f = new File(dirName, fileName);
- if (!userDir.regionMatches((userDir.length() - 1), slash, 0, 1))
- userDir += slash;
- userDir += "input.tst";
- String error = String.format("Test 1: Incorrect file created: %s; %s expected.",
- f.getAbsolutePath(), userDir);
- assertTrue(error, f.getAbsolutePath().equals(userDir));
+ String dirName = tmpDir;
+ String fileName = "input.tst";
+ File f = new File(tmpDir, fileName);
+ tmpDir += "input.tst";
+ assertEquals(tmpDir, f.getAbsolutePath());
dirName = System.getProperty("java.io.tmpdir");
fileName = null;
try {
f = new File(dirName, fileName);
- fail("Test 2: NullPointerException expected.");
- } catch (NullPointerException e) {
+ fail();
+ } catch (NullPointerException expected) {
// Expected.
}
fileName = "input.tst";
f = new File(dirName, fileName);
- assertTrue("Test 3: Incorrect file created.", f.getPath()
- .equals(userDir));
+ assertEquals(tmpDir, f.getPath());
// Regression test for Harmony-382
String s = null;
f = new File("/abc");
File d = new File(s, "/abc");
- assertEquals("Test 4: Incorrect file created;", d.getAbsolutePath(), f
- .getAbsolutePath());
- assertEquals("Test3: Created Incorrect File", "/abc", f
- .getAbsolutePath());
+ assertEquals(d.getAbsolutePath(), f.getAbsolutePath());
+ assertEquals("/abc", f.getAbsolutePath());
}
public void test_createTempFileLjava_lang_StringLjava_lang_String() {
@@ -170,8 +149,7 @@ public class OldFileTest extends TestCase {
public void test_toURL3() throws MalformedURLException {
File dir = new File(""); // current directory
String newDirURL = dir.toURL().toString();
- assertTrue("Test 1: URL does not end with slash.",
- newDirURL.endsWith("/"));
+ assertTrue("Test 1: URL does not end with slash.", newDirURL.endsWith(File.separator));
}
public void test_deleteOnExit() throws IOException, InterruptedException {
@@ -200,42 +178,4 @@ public class OldFileTest extends TestCase {
assertFalse(dir.exists());
assertFalse(subDir.exists());
}
-
- protected void setUp() throws Exception {
- super.setUp();
-
- // Make sure that system properties are set correctly
- String userDir = System.getProperty("java.io.tmpdir");
- if (userDir == null)
- throw new Exception("System property java.io.tmpdir not defined.");
- System.setProperty("java.io.tmpdir", userDir);
-
- /** Setup the temporary directory */
- if (!userDir.regionMatches((userDir.length() - 1), slash, 0, 1))
- userDir += slash;
- tempDirectory = new File(userDir + "tempDir"
- + String.valueOf(System.currentTimeMillis()));
- if (!tempDirectory.mkdir())
- System.out.println("Setup for OldFileTest failed (1).");
-
- /** Setup the temporary file */
- tempFile = new File(tempDirectory, "tempfile");
- FileOutputStream tempStream;
- try {
- tempStream = new FileOutputStream(tempFile.getPath(), false);
- tempStream.close();
- } catch (IOException e) {
- System.out.println("Setup for OldFileTest failed (2).");
- return;
- }
- }
-
- protected void tearDown() {
- if (tempFile.exists() && !tempFile.delete())
- System.out
- .println("OldFileTest.tearDown() failed, could not delete file!");
- if (!tempDirectory.delete())
- System.out
- .println("OldFileTest.tearDown() failed, could not delete directory!");
- }
}
diff --git a/luni/src/test/java/libcore/java/io/OldFilterInputStreamTest.java b/luni/src/test/java/libcore/java/io/OldFilterInputStreamTest.java
index 848b1bf..11c0279 100644
--- a/luni/src/test/java/libcore/java/io/OldFilterInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/io/OldFilterInputStreamTest.java
@@ -18,11 +18,11 @@
package libcore.java.io;
import java.io.BufferedInputStream;
+import java.io.File;
import java.io.FilterInputStream;
import java.io.IOException;
import java.util.Arrays;
import tests.support.Support_ASimpleInputStream;
-import tests.support.Support_PlatformFile;
public class OldFilterInputStreamTest extends junit.framework.TestCase {
@@ -36,13 +36,11 @@ public class OldFilterInputStreamTest extends junit.framework.TestCase {
private FilterInputStream is;
- byte[] ibuf = new byte[4096];
-
- private static final String testString = "Lorem ipsum dolor sit amet,\n" +
+ private static final String INPUT = "Lorem ipsum dolor sit amet,\n" +
"consectetur adipisicing elit,\nsed do eiusmod tempor incididunt ut" +
"labore et dolore magna aliqua.\n";
- private static final int testLength = testString.length();
+ private static final int INPUT_LENGTH = INPUT.length();
public void test_Constructor() {
// The FilterInputStream object has already been created in setUp().
@@ -59,7 +57,7 @@ public class OldFilterInputStreamTest extends junit.framework.TestCase {
public void test_available() throws IOException {
assertEquals("Test 1: Returned incorrect number of available bytes;",
- testLength, is.available());
+ INPUT_LENGTH, is.available());
is.close();
try {
@@ -144,7 +142,7 @@ public class OldFilterInputStreamTest extends junit.framework.TestCase {
public void test_read() throws IOException {
int c = is.read();
assertEquals("Test 1: Read returned incorrect char;",
- testString.charAt(0), c);
+ INPUT.charAt(0), c);
is.close();
try {
@@ -161,7 +159,7 @@ public class OldFilterInputStreamTest extends junit.framework.TestCase {
is.read(buf1);
assertTrue("Test 1: Failed to read correct data.",
new String(buf1, 0, buf1.length).equals(
- testString.substring(0, 100)));
+ INPUT.substring(0, 100)));
is.close();
try {
@@ -281,7 +279,7 @@ public class OldFilterInputStreamTest extends junit.framework.TestCase {
is.read(buf1, 0, buf1.length);
assertTrue("Test 1: Failed to skip to the correct position.",
new String(buf1, 0, buf1.length).equals(
- testString.substring(10, 20)));
+ INPUT.substring(10, 20)));
is.close();
try {
@@ -292,32 +290,19 @@ public class OldFilterInputStreamTest extends junit.framework.TestCase {
}
}
- protected void setUp() {
- try {
- fileName = System.getProperty("java.io.tmpdir");
- String separator = System.getProperty("file.separator");
- if (fileName.charAt(fileName.length() - 1) == separator.charAt(0))
- fileName = Support_PlatformFile.getNewPlatformFile(fileName,
- "input.tst");
- else
- fileName = Support_PlatformFile.getNewPlatformFile(fileName
- + separator, "input.tst");
- java.io.OutputStream fos = new java.io.FileOutputStream(fileName);
- fos.write(testString.getBytes());
- fos.close();
- is = new MyFilterInputStream(new java.io.FileInputStream(fileName));
- } catch (java.io.IOException e) {
- System.out.println("Exception during setup");
- e.printStackTrace();
- }
+ protected void setUp() throws Exception {
+ File f = File.createTempFile("OldFilterInputStreamTest", "tst");
+ fileName = f.getAbsolutePath();
+ java.io.OutputStream fos = new java.io.FileOutputStream(fileName);
+ fos.write(INPUT.getBytes());
+ fos.close();
+ is = new MyFilterInputStream(new java.io.FileInputStream(fileName));
}
protected void tearDown() {
try {
is.close();
- } catch (Exception e) {
- System.out.println("Unexpected exception in tearDown().");
+ } catch (Exception ignored) {
}
- new java.io.File(fileName).delete();
}
}
diff --git a/luni/src/test/java/libcore/java/io/SerializationTest.java b/luni/src/test/java/libcore/java/io/SerializationTest.java
index 32bc402..03e7d94 100644
--- a/luni/src/test/java/libcore/java/io/SerializationTest.java
+++ b/luni/src/test/java/libcore/java/io/SerializationTest.java
@@ -49,7 +49,9 @@ public final class SerializationTest extends TestCase {
static class FieldMadeTransient implements Serializable {
private static final long serialVersionUID = 0L;
+ @SuppressWarnings("unused")
private transient int transientInt;
+ @SuppressWarnings("unused")
private int nonTransientInt;
}
@@ -64,7 +66,7 @@ public final class SerializationTest extends TestCase {
+ "374244669656c644d6164655374617469630000000000000000020001490009737461746963496e7"
+ "47870000022b8";
FieldMadeStatic deserialized = (FieldMadeStatic) SerializationTester.deserializeHex(s);
- // The field data is simply ignored if it is static.
+ // The field data must be ignored if it is static.
assertEquals(9999, deserialized.staticInt);
}
@@ -74,73 +76,101 @@ public final class SerializationTest extends TestCase {
private static int staticInt = 9999;
}
+ public static boolean serializableContainer1InitializedFlag = false;
+ public static boolean unserializable1InitializedFlag = false;
+
+ public static class Unserializable1 {
+ static {
+ SerializationTest.unserializable1InitializedFlag = true;
+ }
+ }
+
+ static class SerializableContainer1 implements Serializable {
+ private static final long serialVersionUID = 0L;
+ private Unserializable1 unserializable = null;
+
+ static {
+ serializableContainer1InitializedFlag = true;
+ }
+ }
+
// We can serialize an object that has an unserializable field providing it is null.
public void testDeserializeNullUnserializableField() throws Exception {
// This was created by creating a new SerializableContainer and not setting the
// unserializable field. A canned serialized form is used so we can tell if the static
// initializers were executed during deserialization.
- // SerializationTester.serializeHex(new SerializableContainer());
- String s = "aced0005737200376c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657"
- + "3742453657269616c697a61626c65436f6e7461696e657200000000000000000200014c000e756e7"
- + "3657269616c697a61626c657400334c6c6962636f72652f6a6176612f696f2f53657269616c697a6"
- + "174696f6e546573742457617353657269616c697a61626c653b787070";
+ // SerializationTester.serializeHex(new SerializableContainer1());
+ String s = "aced0005737200386c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657"
+ + "3742453657269616c697a61626c65436f6e7461696e65723100000000000000000200014c000e7"
+ + "56e73657269616c697a61626c657400124c6a6176612f6c616e672f4f626a6563743b787070";
- serializableContainerInitializedFlag = false;
- wasSerializableInitializedFlag = false;
+ assertFalse(serializableContainer1InitializedFlag);
+ assertFalse(unserializable1InitializedFlag);
- SerializableContainer sc = (SerializableContainer) SerializationTester.deserializeHex(s);
+ SerializableContainer1 sc = (SerializableContainer1) SerializationTester.deserializeHex(s);
assertNull(sc.unserializable);
// Confirm the container was initialized, but the class for the null field was not.
- assertTrue(serializableContainerInitializedFlag);
- assertFalse(wasSerializableInitializedFlag);
+ assertTrue(serializableContainer1InitializedFlag);
+ assertFalse(unserializable1InitializedFlag);
}
- public static boolean serializableContainerInitializedFlag = false;
+ static class Unserializable2 {
+ }
- static class SerializableContainer implements Serializable {
+ static class HasUnserializableField implements Serializable {
private static final long serialVersionUID = 0L;
- private Object unserializable = null;
-
- static {
- serializableContainerInitializedFlag = true;
- }
+ @SuppressWarnings("unused") // Required to make objects unserializable.
+ private Unserializable2 unserializable = new Unserializable2();
}
// We must not serialize an object that has a non-null unserializable field.
public void testSerializeUnserializableField() throws Exception {
- SerializableContainer sc = new SerializableContainer();
- sc.unserializable = new WasSerializable();
+ HasUnserializableField uf = new HasUnserializableField();
try {
- SerializationTester.serializeHex(sc);
+ SerializationTester.serializeHex(uf);
fail();
} catch (NotSerializableException expected) {
}
}
+ public static boolean serializableContainer2InitializedFlag = false;
+
+ @SuppressWarnings("unused") // Required for deserialization test
+ static class SerializableContainer2 implements Serializable {
+ private static final long serialVersionUID = 0L;
+ private WasSerializable unserializable = null;
+
+ static {
+ serializableContainer2InitializedFlag = true;
+ }
+ }
+
// It must not be possible to deserialize an object if a field is no longer serializable.
public void testDeserializeUnserializableField() throws Exception {
- // This was generated by creating a SerializableContainer and setting the unserializable
+ // This was generated by creating a SerializableContainer2 and setting the unserializable
// field to a WasSerializable when it was still Serializable. A canned serialized form is
// used so we can tell if the static initializers were executed during deserialization.
- // SerializableContainer sc = new SerializableContainer();
+ // SerializableContainer2 sc = new SerializableContainer2();
// sc.unserializable = new WasSerializable();
// SerializationTester.serializeHex(sc);
- String s = "aced0005737200376c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657"
- + "3742453657269616c697a61626c65436f6e7461696e657200000000000000000200014c000e756e7"
- + "3657269616c697a61626c657400124c6a6176612f6c616e672f4f626a6563743b7870737200316c6"
- + "962636f72652e6a6176612e696f2e53657269616c697a6174696f6e5465737424576173536572696"
- + "16c697a61626c65000000000000000002000149000169787000000000";
-
- serializableContainerInitializedFlag = false;
- wasSerializableInitializedFlag = false;
+ String s = "aced0005737200386c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657"
+ + "3742453657269616c697a61626c65436f6e7461696e65723200000000000000000200014c000e7"
+ + "56e73657269616c697a61626c657400334c6c6962636f72652f6a6176612f696f2f53657269616"
+ + "c697a6174696f6e546573742457617353657269616c697a61626c653b7870737200316c6962636"
+ + "f72652e6a6176612e696f2e53657269616c697a6174696f6e546573742457617353657269616c6"
+ + "97a61626c65000000000000000002000149000169787000000000";
+
+ assertFalse(serializableContainer2InitializedFlag);
+ assertFalse(wasSerializableInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
} catch (InvalidClassException expected) {
}
- // Confirm neither the container nor the contained class was initialized.
- assertFalse(serializableContainerInitializedFlag);
+ // The container class will be initialized to establish the serialVersionUID.
+ assertTrue(serializableContainer2InitializedFlag);
+ // Confirm the contained class was initialized.
assertFalse(wasSerializableInitializedFlag);
}
@@ -196,7 +226,7 @@ public final class SerializationTest extends TestCase {
+ "e546573742457617353657269616c697a61626c65000000000000000002000149000169787000000"
+ "000";
- wasSerializableInitializedFlag = false;
+ assertFalse(wasSerializableInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
@@ -239,7 +269,7 @@ public final class SerializationTest extends TestCase {
final String s = "aced0005737200336c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6"
+ "e546573742457617345787465726e616c697a61626c6500000000000000000c0000787078";
- wasExternalizableInitializedFlag = false;
+ assertFalse(wasExternalizableInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
@@ -275,7 +305,7 @@ public final class SerializationTest extends TestCase {
+ "e5465737424576173456e756d00000000000000001200007872000e6a6176612e6c616e672e456e7"
+ "56d0000000000000000120000787074000556414c5545";
- wasEnumInitializedFlag = false;
+ assertFalse(wasEnumInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
@@ -309,7 +339,7 @@ public final class SerializationTest extends TestCase {
final String s = "aced00057372002b6c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6"
+ "e54657374245761734f626a656374000000000000000002000149000169787000000000";
- wasObjectInitializedFlag = false;
+ assertFalse(wasObjectInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
diff --git a/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
deleted file mode 100644
index 98e497d..0000000
--- a/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-public final class ArrayIndexOutOfBoundsExceptionTest extends TestCase {
- public void testAput() throws Exception {
- byte[] bs = new byte[1];
- try {
- bs[2] = 0;
- fail();
- } catch (ArrayIndexOutOfBoundsException ex) {
- assertEquals("length=1; index=2", ex.getMessage());
- }
- }
-
- public void testAget() throws Exception {
- byte[] bs = new byte[1];
- try {
- byte b = bs[2];
- fail();
- } catch (ArrayIndexOutOfBoundsException ex) {
- assertEquals("length=1; index=2", ex.getMessage());
- }
- }
-
- public void testAputWide() throws Exception {
- double[] ds = new double[1];
- try {
- ds[2] = 0.0;
- fail();
- } catch (ArrayIndexOutOfBoundsException ex) {
- assertEquals("length=1; index=2", ex.getMessage());
- }
- }
-
- public void testAgetWide() throws Exception {
- double[] ds = new double[1];
- try {
- double d = ds[2];
- fail();
- } catch (ArrayIndexOutOfBoundsException ex) {
- assertEquals("length=1; index=2", ex.getMessage());
- }
- }
-
- public void testAputObject() throws Exception {
- Object[] os = new Object[1];
- try {
- os[2] = null;
- fail();
- } catch (ArrayIndexOutOfBoundsException ex) {
- assertEquals("length=1; index=2", ex.getMessage());
- }
- }
-
- public void testAgetObject() throws Exception {
- Object[] os = new Object[1];
- try {
- Object o = os[2];
- fail();
- } catch (ArrayIndexOutOfBoundsException ex) {
- assertEquals("length=1; index=2", ex.getMessage());
- }
- }
-}
diff --git a/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java b/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java
deleted file mode 100644
index c25245f..0000000
--- a/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-public final class ArrayStoreExceptionTest extends TestCase {
- public void testArrayStoreException_store1() throws Exception {
- Object[] array = new String[10];
- Object o = new Exception();
- try {
- array[0] = o;
- fail();
- } catch (ArrayStoreException ex) {
- ex.printStackTrace();
- assertEquals("java.lang.Exception cannot be stored in an array of type "
- + "java.lang.String[]",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_store2() throws Exception {
- Object[] array = new Nonce[10][];
- Object o = new Integer(5);
- try {
- array[0] = o;
- fail();
- } catch (ArrayStoreException ex) {
- assertEquals("java.lang.Integer cannot be stored in an array of type "
- + "libcore.java.lang.ArrayStoreExceptionTest$Nonce[][]",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_store3() throws Exception {
- Object[] array = new Float[10][];
- Object o = new Nonce[1];
- try {
- array[0] = o;
- fail();
- } catch (ArrayStoreException ex) {
- assertEquals("libcore.java.lang.ArrayStoreExceptionTest$Nonce[] cannot be stored "
- + "in an array of type java.lang.Float[][]",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_arraycopy1() throws Exception {
- String[] src = new String[] { null, null, null, null, "hello", "goodbye" };
- Integer[] dest = new Integer[10];
- try {
- System.arraycopy(src, 1, dest, 0, 5);
- } catch (ArrayStoreException ex) {
- ex.printStackTrace();
- assertEquals("source[4] of type java.lang.String cannot be stored in destination "
- + "array of type java.lang.Integer[]",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_arraycopy2() throws Exception {
- String[] src = new String[1];
- int[] dest = new int[1];
- try {
- System.arraycopy(src, 0, dest, 0, 1);
- } catch (ArrayStoreException ex) {
- assertEquals("java.lang.String[] and int[] are incompatible array types",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_arraycopy3() throws Exception {
- float[] src = new float[1];
- Runnable[] dest = new Runnable[1];
- try {
- System.arraycopy(src, 0, dest, 0, 1);
- } catch (ArrayStoreException ex) {
- assertEquals("float[] and java.lang.Runnable[] are incompatible array types",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_arraycopy4() throws Exception {
- boolean[] src = new boolean[1];
- double[][] dest = new double[1][];
- try {
- System.arraycopy(src, 0, dest, 0, 1);
- } catch (ArrayStoreException ex) {
- assertEquals("boolean[] and double[][] are incompatible array types",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_arraycopy5() throws Exception {
- String src = "blort";
- Object[] dest = new Object[1];
- try {
- System.arraycopy(src, 0, dest, 0, 1);
- } catch (ArrayStoreException ex) {
- assertEquals("source of type java.lang.String is not an array",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_arraycopy6() throws Exception {
- Object[] src = new Object[1];
- Integer dest = new Integer(5);
- try {
- System.arraycopy(src, 0, dest, 0, 1);
- } catch (ArrayStoreException ex) {
- assertEquals("destination of type java.lang.Integer is not an array",
- ex.getMessage());
- }
- }
-
- public void testArrayStoreException_arraycopy7() throws Exception {
- /*
- * This test demonstrates that the exception message complains
- * about the source in cases where neither source nor
- * destination is an array.
- */
- Nonce src = new Nonce();
- String dest = "blort";
- try {
- System.arraycopy(src, 0, dest, 0, 1);
- } catch (ArrayStoreException ex) {
- assertEquals("source of type libcore.java.lang.ArrayStoreExceptionTest$Nonce "
- + "is not an array",
- ex.getMessage());
- }
- }
-
- /**
- * This class is just used so that we have an example of getting a
- * message that includes an inner class.
- */
- private static class Nonce {
- // This space intentionally left blank.
- }
-}
diff --git a/luni/src/test/java/libcore/java/lang/CharacterTest.java b/luni/src/test/java/libcore/java/lang/CharacterTest.java
index 48284d6..8c6f06f 100644
--- a/luni/src/test/java/libcore/java/lang/CharacterTest.java
+++ b/luni/src/test/java/libcore/java/lang/CharacterTest.java
@@ -242,7 +242,14 @@ public class CharacterTest extends junit.framework.TestCase {
Method m = Character.class.getDeclaredMethod("isSpaceChar" + "Impl", int.class);
m.setAccessible(true);
for (int i = 0; i <= 0xffff; ++i) {
- if((Boolean) m.invoke(null, i) != Character.isSpaceChar(i)) System.out.println(i);
+ // ICU and the RI disagree about character 0x180e. Remove this special case if this changes
+ // or Android decides to follow ICU exactly.
+ if (i == 0x180e) {
+ assertTrue(Character.isSpaceChar(i));
+ assertFalse((Boolean) m.invoke(null, i));
+ } else {
+ assertEquals("Failed for character " + i, m.invoke(null, i), Character.isSpaceChar(i));
+ }
}
}
@@ -260,7 +267,26 @@ public class CharacterTest extends junit.framework.TestCase {
Method m = Character.class.getDeclaredMethod("isWhitespace" + "Impl", int.class);
m.setAccessible(true);
for (int i = 0; i <= 0xffff; ++i) {
- assertEquals(m.invoke(null, i), Character.isWhitespace(i));
+ // ICU and the RI disagree about character 0x180e. Remove this special case if this changes
+ // or Android decides to follow ICU exactly.
+ if (i == 0x180e) {
+ assertTrue(Character.isWhitespace(i));
+ assertFalse((Boolean) m.invoke(null, i));
+ } else {
+ assertEquals("Failed for character " + i, m.invoke(null, i), Character.isWhitespace(i));
+ }
}
}
+
+ // http://b/15492712
+ public void test_getDirectionality() throws Exception {
+ // We shouldn't throw an exception for any code point.
+ for (int c = '\u0000'; c <= Character.MAX_VALUE; ++c) {
+ Character.getDirectionality(c);
+ }
+ assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character.getDirectionality(0x2066));
+ assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character.getDirectionality(0x2067));
+ assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character.getDirectionality(0x2068));
+ assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character.getDirectionality(0x2069));
+ }
}
diff --git a/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java b/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java
index ec3aa46..3c10aa8 100644
--- a/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java
+++ b/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java
@@ -23,16 +23,6 @@ import java.util.EnumSet;
import junit.framework.TestCase;
public final class ClassCastExceptionTest extends TestCase {
- public void testCast() throws Exception {
- Object o = new Exception();
- try {
- String s = (String) o;
- fail();
- } catch (ClassCastException ex) {
- assertEquals("java.lang.Exception cannot be cast to java.lang.String", ex.getMessage());
- }
- }
-
public void testClassCast() throws Exception {
Object o = new Exception();
try {
@@ -53,69 +43,6 @@ public final class ClassCastExceptionTest extends TestCase {
}
}
- public void testCastOperator() throws Exception {
- try {
- Object o = (InputStream) makeInteger();
- fail();
- } catch (ClassCastException ex) {
- assertEquals("java.lang.Integer cannot be cast to java.io.InputStream",
- ex.getMessage());
- }
- }
-
- public void testCastOperatorWithArrays() throws Exception {
- try {
- Object o = (E) makeArray(String.class);
- fail();
- } catch (ClassCastException ex) {
- assertEquals("java.lang.String[] cannot be cast to "
- + "libcore.java.lang.ClassCastExceptionTest$E",
- ex.getMessage());
- }
-
- try {
- Object o = (E) makeArray(float.class);
- fail();
- } catch (ClassCastException ex) {
- assertEquals("float[] cannot be cast to libcore.java.lang.ClassCastExceptionTest$E",
- ex.getMessage());
- }
-
- try {
- Object o = (E) makeArray(char[].class);
- fail();
- } catch (ClassCastException ex) {
- assertEquals("char[][] cannot be cast to libcore.java.lang.ClassCastExceptionTest$E",
- ex.getMessage());
- }
-
- try {
- Object o = (Object[][][]) makeInteger();
- fail();
- } catch (ClassCastException ex) {
- assertEquals("java.lang.Integer cannot be cast to java.lang.Object[][][]",
- ex.getMessage());
- }
- }
-
- /**
- * Helper for {@link #testCastOperator} and {@link
- * #testCastOperatorWithArrays}, above. It's important that the
- * return type is {@code Object}, since otherwise the compiler
- * will just reject the code.
- */
- private static Object makeInteger() {
- return new Integer(5);
- }
-
- /**
- * Helper for {@link #testCastOperatorWithArrays} above. It's important that
- * the return type is {@code Object}.
- */
- private static Object makeArray(Class clazz) {
- return Array.newInstance(clazz, 1);
- }
-
enum E { A, B, C };
enum F { A, B, C };
@@ -125,7 +52,6 @@ public final class ClassCastExceptionTest extends TestCase {
m.put(F.A, "world");
fail();
} catch (ClassCastException ex) {
- ex.printStackTrace();
assertNotNull(ex.getMessage());
}
}
@@ -136,7 +62,6 @@ public final class ClassCastExceptionTest extends TestCase {
m.add(F.A);
fail();
} catch (ClassCastException ex) {
- ex.printStackTrace();
assertNotNull(ex.getMessage());
}
}
@@ -148,7 +73,6 @@ public final class ClassCastExceptionTest extends TestCase {
m.addAll(n);
fail();
} catch (ClassCastException ex) {
- ex.printStackTrace();
assertNotNull(ex.getMessage());
}
}
@@ -170,7 +94,6 @@ public final class ClassCastExceptionTest extends TestCase {
m.add(HugeF.A0);
fail();
} catch (ClassCastException ex) {
- ex.printStackTrace();
assertNotNull(ex.getMessage());
}
}
@@ -182,7 +105,6 @@ public final class ClassCastExceptionTest extends TestCase {
m.addAll(n);
fail();
} catch (ClassCastException ex) {
- ex.printStackTrace();
assertNotNull(ex.getMessage());
}
}
diff --git a/luni/src/test/java/libcore/java/lang/ClassNotFoundExceptionTest.java b/luni/src/test/java/libcore/java/lang/ClassNotFoundExceptionTest.java
deleted file mode 100644
index 6eb97c2..0000000
--- a/luni/src/test/java/libcore/java/lang/ClassNotFoundExceptionTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-public final class ClassNotFoundExceptionTest extends TestCase {
- public void testIllegalName() throws Exception {
- try {
- // There is no such thing as an array of void.
- Class.forName("[V");
- fail();
- } catch (ClassNotFoundException ex) {
- assertEquals("[V", ex.getMessage());
- }
- }
-
- public void testValidName() throws Exception {
- try {
- Class.forName("blort.Zorch");
- fail();
- } catch (ClassNotFoundException ex) {
- assertEquals("blort.Zorch", ex.getMessage());
- }
- }
-
- public void testValidArrayName() throws Exception {
- try {
- Class.forName("[[Lblort.Zorch;");
- fail();
- } catch (ClassNotFoundException ex) {
- assertEquals("[[Lblort.Zorch;", ex.getMessage());
- }
- }
-}
diff --git a/luni/src/test/java/libcore/java/lang/ClassTest.java b/luni/src/test/java/libcore/java/lang/ClassTest.java
new file mode 100644
index 0000000..15298ea
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/ClassTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.java.lang;
+
+import junit.framework.TestCase;
+
+public class ClassTest extends TestCase {
+
+ interface Foo {
+ public void foo();
+ }
+
+ interface ParameterizedFoo<T> {
+ public void foo(T param);
+ }
+
+ interface ParameterizedBar<T> extends ParameterizedFoo<T> {
+ public void bar(T param);
+ }
+
+ interface ParameterizedBaz extends ParameterizedFoo<String> {
+
+ }
+
+ public void test_getGenericSuperclass_nullReturnCases() {
+ // Should always return null for interfaces.
+ assertNull(Foo.class.getGenericSuperclass());
+ assertNull(ParameterizedFoo.class.getGenericSuperclass());
+ assertNull(ParameterizedBar.class.getGenericSuperclass());
+ assertNull(ParameterizedBaz.class.getGenericSuperclass());
+
+ assertNull(Object.class.getGenericSuperclass());
+ assertNull(void.class.getGenericSuperclass());
+ assertNull(int.class.getGenericSuperclass());
+ }
+
+ public void test_getGenericSuperclass_returnsObjectForArrays() {
+ assertSame(Object.class, (new Integer[0]).getClass().getGenericSuperclass());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/DoubleTest.java b/luni/src/test/java/libcore/java/lang/DoubleTest.java
index 687d3e3..85281ba 100644
--- a/luni/src/test/java/libcore/java/lang/DoubleTest.java
+++ b/luni/src/test/java/libcore/java/lang/DoubleTest.java
@@ -127,4 +127,19 @@ public class DoubleTest extends TestCase {
assertEquals(2.2250738585072014E-308, Double.parseDouble("2.22507385850720129978001e-308"));
assertEquals(-2.2250738585072014E-308, Double.parseDouble("-2.2250738585072012e-308"));
}
+
+ // https://code.google.com/p/android/issues/detail?id=71216
+ public void testParse_bug71216() {
+ try {
+ Double.parseDouble("73706943-9580-4406-a02f-0304e4324844");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ try {
+ Double.parseDouble("bade999999999999999999999999999999");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/lang/IntegerTest.java b/luni/src/test/java/libcore/java/lang/IntegerTest.java
index 2d8c082..b54b322 100644
--- a/luni/src/test/java/libcore/java/lang/IntegerTest.java
+++ b/luni/src/test/java/libcore/java/lang/IntegerTest.java
@@ -16,19 +16,118 @@
package libcore.java.lang;
+import java.util.Properties;
+
public class IntegerTest extends junit.framework.TestCase {
- public void test_compare() throws Exception {
- final int min = Integer.MIN_VALUE;
- final int zero = 0;
- final int max = Integer.MAX_VALUE;
- assertTrue(Integer.compare(max, max) == 0);
- assertTrue(Integer.compare(min, min) == 0);
- assertTrue(Integer.compare(zero, zero) == 0);
- assertTrue(Integer.compare(max, zero) > 0);
- assertTrue(Integer.compare(max, min) > 0);
- assertTrue(Integer.compare(zero, max) < 0);
- assertTrue(Integer.compare(zero, min) > 0);
- assertTrue(Integer.compare(min, zero) < 0);
- assertTrue(Integer.compare(min, max) < 0);
+
+ public void testSystemProperties() {
+ Properties originalProperties = System.getProperties();
+ try {
+ Properties testProperties = new Properties();
+ testProperties.put("testIncInt", "notInt");
+ System.setProperties(testProperties);
+ assertNull("returned incorrect default Integer",
+ Integer.getInteger("testIncInt"));
+ assertEquals(new Integer(4), Integer.getInteger("testIncInt", 4));
+ assertEquals(new Integer(4),
+ Integer.getInteger("testIncInt", new Integer(4)));
+ } finally {
+ System.setProperties(originalProperties);
}
+ }
+
+ public void testCompare() throws Exception {
+ final int min = Integer.MIN_VALUE;
+ final int zero = 0;
+ final int max = Integer.MAX_VALUE;
+ assertTrue(Integer.compare(max, max) == 0);
+ assertTrue(Integer.compare(min, min) == 0);
+ assertTrue(Integer.compare(zero, zero) == 0);
+ assertTrue(Integer.compare(max, zero) > 0);
+ assertTrue(Integer.compare(max, min) > 0);
+ assertTrue(Integer.compare(zero, max) < 0);
+ assertTrue(Integer.compare(zero, min) > 0);
+ assertTrue(Integer.compare(min, zero) < 0);
+ assertTrue(Integer.compare(min, max) < 0);
+ }
+
+ public void testParseInt() throws Exception {
+ assertEquals(0, Integer.parseInt("+0", 10));
+ assertEquals(473, Integer.parseInt("+473", 10));
+ assertEquals(255, Integer.parseInt("+FF", 16));
+ assertEquals(102, Integer.parseInt("+1100110", 2));
+ assertEquals(2147483647, Integer.parseInt("+2147483647", 10));
+ assertEquals(411787, Integer.parseInt("Kona", 27));
+ assertEquals(411787, Integer.parseInt("+Kona", 27));
+ assertEquals(-145, Integer.parseInt("-145", 10));
+
+ try {
+ Integer.parseInt("--1", 10); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Integer.parseInt("++1", 10); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Integer.parseInt("Kona", 10); // base too small
+ fail();
+ } catch (NumberFormatException expected) {}
+ }
+
+ public void testDecodeInt() throws Exception {
+ assertEquals(0, Integer.decode("+0").intValue());
+ assertEquals(473, Integer.decode("+473").intValue());
+ assertEquals(255, Integer.decode("+0xFF").intValue());
+ assertEquals(16, Integer.decode("+020").intValue());
+ assertEquals(2147483647, Integer.decode("+2147483647").intValue());
+ assertEquals(-73, Integer.decode("-73").intValue());
+ assertEquals(-255, Integer.decode("-0xFF").intValue());
+ assertEquals(255, Integer.decode("+#FF").intValue());
+ assertEquals(-255, Integer.decode("-#FF").intValue());
+
+ try {
+ Integer.decode("--1"); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Integer.decode("++1"); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Integer.decode("-+1"); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Integer.decode("Kona"); // invalid number
+ fail();
+ } catch (NumberFormatException expected) {}
+ }
+
+ public void testParsePositiveInt() throws Exception {
+ assertEquals(0, Integer.parsePositiveInt("0", 10));
+ assertEquals(473, Integer.parsePositiveInt("473", 10));
+ assertEquals(255, Integer.parsePositiveInt("FF", 16));
+
+ try {
+ Integer.parsePositiveInt("-1", 10);
+ fail();
+ } catch (NumberFormatException e) {}
+
+ try {
+ Integer.parsePositiveInt("+1", 10);
+ fail();
+ } catch (NumberFormatException e) {}
+
+ try {
+ Integer.parsePositiveInt("+0", 16);
+ fail();
+ } catch (NumberFormatException e) {}
+ }
+
}
diff --git a/luni/src/test/java/libcore/java/lang/LongTest.java b/luni/src/test/java/libcore/java/lang/LongTest.java
index 9e143da..0d1741a 100644
--- a/luni/src/test/java/libcore/java/lang/LongTest.java
+++ b/luni/src/test/java/libcore/java/lang/LongTest.java
@@ -16,8 +16,25 @@
package libcore.java.lang;
+import java.util.Properties;
+
public class LongTest extends junit.framework.TestCase {
- public void test_compare() throws Exception {
+
+ public void testSystemProperties() {
+ Properties originalProperties = System.getProperties();
+ try {
+ Properties testProperties = new Properties();
+ testProperties.put("testIncLong", "string");
+ System.setProperties(testProperties);
+ assertNull(Long.getLong("testIncLong"));
+ assertEquals(new Long(4), Long.getLong("testIncLong", 4L));
+ assertEquals(new Long(4), Long.getLong("testIncLong", new Long(4)));
+ } finally {
+ System.setProperties(originalProperties);
+ }
+ }
+
+ public void testCompare() throws Exception {
final long min = Long.MIN_VALUE;
final long zero = 0L;
final long max = Long.MAX_VALUE;
@@ -32,11 +49,91 @@ public class LongTest extends junit.framework.TestCase {
assertTrue(Long.compare(min, max) < 0);
}
- public void test_signum() throws Exception {
+ public void testSignum() throws Exception {
assertEquals(0, Long.signum(0));
assertEquals(1, Long.signum(1));
assertEquals(-1, Long.signum(-1));
assertEquals(1, Long.signum(Long.MAX_VALUE));
assertEquals(-1, Long.signum(Long.MIN_VALUE));
}
+
+ public void testParsePositiveLong() throws Exception {
+ assertEquals(0, Long.parsePositiveLong("0", 10));
+ assertEquals(473, Long.parsePositiveLong("473", 10));
+ assertEquals(255, Long.parsePositiveLong("FF", 16));
+
+ try {
+ Long.parsePositiveLong("-1", 10);
+ fail();
+ } catch (NumberFormatException e) {}
+
+ try {
+ Long.parsePositiveLong("+1", 10);
+ fail();
+ } catch (NumberFormatException e) {}
+
+ try {
+ Long.parsePositiveLong("+0", 16);
+ fail();
+ } catch (NumberFormatException e) {}
+ }
+
+ public void testParseLong() throws Exception {
+ assertEquals(0, Long.parseLong("+0", 10));
+ assertEquals(473, Long.parseLong("+473", 10));
+ assertEquals(255, Long.parseLong("+FF", 16));
+ assertEquals(102, Long.parseLong("+1100110", 2));
+ assertEquals(Long.MAX_VALUE, Long.parseLong("+" + Long.MAX_VALUE, 10));
+ assertEquals(411787, Long.parseLong("Kona", 27));
+ assertEquals(411787, Long.parseLong("+Kona", 27));
+ assertEquals(-145, Long.parseLong("-145", 10));
+
+ try {
+ Long.parseLong("--1", 10); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Long.parseLong("++1", 10); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Long.parseLong("Kona", 10); // base to small
+ fail();
+ } catch (NumberFormatException expected) {}
+ }
+
+ public void testDecodeLong() throws Exception {
+ assertEquals(0, Long.decode("+0").longValue());
+ assertEquals(473, Long.decode("+473").longValue());
+ assertEquals(255, Long.decode("+0xFF").longValue());
+ assertEquals(16, Long.decode("+020").longValue());
+ assertEquals(Long.MAX_VALUE, Long.decode("+" + Long.MAX_VALUE).longValue());
+ assertEquals(-73, Long.decode("-73").longValue());
+ assertEquals(-255, Long.decode("-0xFF").longValue());
+ assertEquals(255, Long.decode("+#FF").longValue());
+ assertEquals(-255, Long.decode("-#FF").longValue());
+
+ try {
+ Long.decode("--1"); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Long.decode("++1"); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Long.decode("+-1"); // multiple sign chars
+ fail();
+ } catch (NumberFormatException expected) {}
+
+ try {
+ Long.decode("Kona"); // invalid number
+ fail();
+ } catch (NumberFormatException expected) {}
+ }
+
}
diff --git a/luni/src/test/java/libcore/java/lang/OldAndroidParseIntTest.java b/luni/src/test/java/libcore/java/lang/OldAndroidParseIntTest.java
deleted file mode 100644
index 08351d6..0000000
--- a/luni/src/test/java/libcore/java/lang/OldAndroidParseIntTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for functionality of class Integer to parse integers.
- */
-public class OldAndroidParseIntTest extends TestCase {
-
- public void testParseInt() throws Exception {
- assertEquals(0, Integer.parseInt("0", 10));
- assertEquals(473, Integer.parseInt("473", 10));
- assertEquals(0, Integer.parseInt("-0", 10));
- assertEquals(-255, Integer.parseInt("-FF", 16));
- assertEquals(102, Integer.parseInt("1100110", 2));
- assertEquals(2147483647, Integer.parseInt("2147483647", 10));
- assertEquals(-2147483648, Integer.parseInt("-2147483648", 10));
-
- try {
- Integer.parseInt("2147483648", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- try {
- Integer.parseInt("-2147483649", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- // One digit too many
- try {
- Integer.parseInt("21474836470", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- try {
- Integer.parseInt("-21474836480", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- try {
- Integer.parseInt("21474836471", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- try {
- Integer.parseInt("-21474836481", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- try {
- Integer.parseInt("214748364710", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- try {
- Integer.parseInt("-214748364811", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- try {
- Integer.parseInt("99", 8);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- try {
- Integer.parseInt("Kona", 10);
- fail();
- } catch (NumberFormatException e) {
- // ok
- }
-
- assertEquals(411787, Integer.parseInt("Kona", 27));
- }
-}
diff --git a/luni/src/test/java/libcore/java/lang/OldClassTest.java b/luni/src/test/java/libcore/java/lang/OldClassTest.java
index 0f7ce42..23a42bd 100644
--- a/luni/src/test/java/libcore/java/lang/OldClassTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldClassTest.java
@@ -720,8 +720,20 @@ public class OldClassTest extends junit.framework.TestCase {
}
public void test_getDeclaringClass() {
- assertNull(OldClassTest.class.getDeclaringClass());
- assertNotNull(PublicTestClass.class.getDeclaringClass());
+ assertEquals(OldClassTest.class, Intf1.class.getDeclaringClass());
+ assertEquals(null, Serializable.class.getDeclaringClass());
+ assertEquals(null, OldClassTest.class.getDeclaringClass());
+
+ assertEquals(OldClassTest.class, PublicTestClass.class.getDeclaringClass());
+
+ // https://code.google.com/p/android/issues/detail?id=61003
+ assertEquals(null, new Object() {}.getClass().getDeclaringClass());
+ assertEquals(null, new AnonymousMemberFixture().instanceOfAnonymousClass.getClass().getDeclaringClass());
+
+ // Arrays, primitive types, and void all return null.
+ assertEquals(null, char[].class.getDeclaringClass());
+ assertEquals(null, int.class.getDeclaringClass());
+ assertEquals(null, void.class.getDeclaringClass());
}
public void test_getFieldLjava_lang_String() throws Exception {
@@ -1022,3 +1034,7 @@ public class OldClassTest extends junit.framework.TestCase {
assertNull(clazz.getResourceAsStream("libcore/java/lang/HelloWorld.txt"));
}
}
+
+class AnonymousMemberFixture {
+ Object instanceOfAnonymousClass = new Object() {};
+}
diff --git a/luni/src/test/java/libcore/java/lang/OldIntegerTest.java b/luni/src/test/java/libcore/java/lang/OldIntegerTest.java
deleted file mode 100644
index 462ee19..0000000
--- a/luni/src/test/java/libcore/java/lang/OldIntegerTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import java.util.Properties;
-import junit.framework.TestCase;
-
-public class OldIntegerTest extends TestCase {
- private Properties orgProps;
-
- @Override
- protected void setUp() {
- orgProps = System.getProperties();
- }
-
- @Override
- protected void tearDown() {
- System.setProperties(orgProps);
- }
-
- public void test_getIntegerLjava_lang_StringI() {
- // Test for method java.lang.Integer
- // java.lang.Integer.getInteger(java.lang.String, int)
- Properties tProps = new Properties();
- tProps.put("testIncInt", "notInt");
- System.setProperties(tProps);
- assertTrue("returned incorrect default Integer", Integer.getInteger(
- "testIncInt", 4).equals(new Integer(4)));
- }
-
- public void test_getIntegerLjava_lang_StringLjava_lang_Integer() {
- // Test for method java.lang.Integer
- // java.lang.Integer.getInteger(java.lang.String, java.lang.Integer)
- Properties tProps = new Properties();
- tProps.put("testIncInt", "notInt");
- System.setProperties(tProps);
- assertTrue("returned incorrect default Integer", Integer.getInteger(
- "testIncInt", new Integer(4)).equals(new Integer(4)));
- }
-
- public void test_intValue() {
- assertEquals(Integer.MAX_VALUE, new Integer(Integer.MAX_VALUE).intValue());
- assertEquals(Integer.MIN_VALUE, new Integer(Integer.MIN_VALUE).intValue());
- }
-
- public void test_longValue() {
- assertEquals(Integer.MAX_VALUE, new Integer(Integer.MAX_VALUE).longValue());
- assertEquals(Integer.MIN_VALUE, new Integer(Integer.MIN_VALUE).longValue());
- }
-
- public void test_shortValue() {
- assertEquals(-1, new Integer(Integer.MAX_VALUE).shortValue());
- assertEquals(0, new Integer(Integer.MIN_VALUE).shortValue());
- }
-}
diff --git a/luni/src/test/java/libcore/java/lang/OldLongTest.java b/luni/src/test/java/libcore/java/lang/OldLongTest.java
deleted file mode 100644
index 6fb7d49..0000000
--- a/luni/src/test/java/libcore/java/lang/OldLongTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import java.util.Properties;
-import junit.framework.TestCase;
-
-public class OldLongTest extends TestCase {
- private Properties orgProps;
-
- @Override
- protected void setUp() {
- orgProps = System.getProperties();
- }
-
- @Override
- protected void tearDown() {
- System.setProperties(orgProps);
- }
-
- public void test_getLongLjava_lang_String() {
- Properties tProps = new Properties();
- tProps.put("testLong", "99");
- tProps.put("testIncLong", "string");
- System.setProperties(tProps);
- assertNull("returned incorrect default Long",
- Long.getLong("testIncLong"));
- }
-
- public void test_getLongLjava_lang_StringJ() {
- // Test for method java.lang.Long
- // java.lang.Long.getLong(java.lang.String, long)
- Properties tProps = new Properties();
- tProps.put("testIncLong", "string");
- System.setProperties(tProps);
- assertTrue("returned incorrect default Long", Long.getLong("testIncLong", 4L)
- .equals(new Long(4)));
- }
-
- public void test_getLongLjava_lang_StringLjava_lang_Long() {
- // Test for method java.lang.Long
- // java.lang.Long.getLong(java.lang.String, java.lang.Long)
- Properties tProps = new Properties();
- tProps.put("testIncLong", "string");
- System.setProperties(tProps);
- assertTrue("returned incorrect default Long", Long.getLong("testIncLong",
- new Long(4)).equals(new Long(4)));
- }
-
- public void test_floatValue() {
- assertEquals(Long.MAX_VALUE, new Long(Long.MAX_VALUE).floatValue(), 0F);
- assertEquals(Long.MIN_VALUE, new Long(Long.MIN_VALUE).floatValue(), 0F);
- }
-
- public void test_intValue() {
- assertEquals(-1, new Long(Long.MAX_VALUE).intValue());
- assertEquals(0, new Long(Long.MIN_VALUE).intValue());
- }
-
- public void test_longValue() {
- assertEquals(Long.MAX_VALUE, new Long(Long.MAX_VALUE).longValue());
- assertEquals(Long.MIN_VALUE, new Long(Long.MIN_VALUE).longValue());
- }
-
- public void test_shortValue() {
- assertEquals(-1, new Long(Long.MAX_VALUE).shortValue());
- assertEquals(0, new Long(Long.MIN_VALUE).shortValue());
- }
-}
diff --git a/luni/src/test/java/libcore/java/lang/OldObjectTest.java b/luni/src/test/java/libcore/java/lang/OldObjectTest.java
index 3ab0327..f7a3781 100644
--- a/luni/src/test/java/libcore/java/lang/OldObjectTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldObjectTest.java
@@ -36,6 +36,16 @@ public class OldObjectTest extends TestCase {
TestThread1 thr1;
TestThread2 thr2;
+ public void test_hashCode() {
+ Object o1 = new Object();
+ Object o2 = new Object();
+ int h1 = System.identityHashCode(o1);
+ int h2 = System.identityHashCode(o2);
+ assertEquals(h1, o1.hashCode());
+ assertEquals(h2, o2.hashCode());
+ assertTrue(h1 != h2);
+ }
+
public void test_clone() {
MockCloneableObject mco = new MockCloneableObject();
try {
diff --git a/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java b/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
index 0926569..294cea2 100644
--- a/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
@@ -34,28 +34,6 @@ public class OldRuntimeTest extends junit.framework.TestCase {
InputStream is;
- public void test_freeMemory() {
- // Heap might grow or do GC at any time,
- // so we can't really test a lot. Hence
- // we are just doing some basic sanity
- // checks here.
- assertTrue("must have some free memory",
- r.freeMemory() > 0);
-
- assertTrue("must not exceed total memory",
- r.freeMemory() < r.totalMemory());
-
- long before = r.totalMemory() - r.freeMemory();
- Vector<byte[]> v = new Vector<byte[]>();
- for (int i = 1; i < 10; i++) {
- v.addElement(new byte[10000]);
- }
- long after = r.totalMemory() - r.freeMemory();
-
- assertTrue("free memory must change with allocations",
- after != before);
- }
-
public void test_getRuntime() {
// Test for method java.lang.Runtime java.lang.Runtime.getRuntime()
assertNotNull(Runtime.getRuntime());
@@ -451,10 +429,6 @@ public class OldRuntimeTest extends junit.framework.TestCase {
}
}
- public void test_maxMemory() {
- assertTrue(Runtime.getRuntime().maxMemory() < Long.MAX_VALUE);
- }
-
public void test_traceInstructions() {
Runtime.getRuntime().traceInstructions(false);
Runtime.getRuntime().traceInstructions(true);
diff --git a/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java b/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
index d03ae65..9766cef 100644
--- a/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
+++ b/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
@@ -22,10 +22,10 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
-import libcore.dalvik.system.CloseGuardTester;
+import libcore.java.util.AbstractResourceLeakageDetectorTestCase;
import static tests.support.Support_Exec.execAndCheckOutput;
-public class ProcessBuilderTest extends junit.framework.TestCase {
+public class ProcessBuilderTest extends AbstractResourceLeakageDetectorTestCase {
private static String shell() {
String deviceSh = "/system/bin/sh";
@@ -84,14 +84,8 @@ public class ProcessBuilderTest extends junit.framework.TestCase {
}
public void testDestroyDoesNotLeak() throws IOException {
- CloseGuardTester closeGuardTester = new CloseGuardTester();
- try {
- Process process = new ProcessBuilder(shell(), "-c", "echo out; echo err 1>&2").start();
- process.destroy();
- closeGuardTester.assertEverythingWasClosed();
- } finally {
- closeGuardTester.close();
- }
+ Process process = new ProcessBuilder(shell(), "-c", "echo out; echo err 1>&2").start();
+ process.destroy();
}
public void testEnvironmentMapForbidsNulls() throws Exception {
diff --git a/luni/src/test/java/libcore/java/lang/StringBuilderTest.java b/luni/src/test/java/libcore/java/lang/StringBuilderTest.java
new file mode 100644
index 0000000..1f9abbf
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/StringBuilderTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.lang;
+
+public class StringBuilderTest extends junit.framework.TestCase {
+ // See https://code.google.com/p/android/issues/detail?id=60639
+ public void test_deleteChatAt_lastRange() {
+ StringBuilder sb = new StringBuilder("oarFish_");
+ sb.append('a');
+ String oarFishA = sb.toString();
+
+ sb.deleteCharAt(sb.length() - 1);
+ sb.append('b');
+ String oarFishB = sb.toString();
+
+ assertEquals("oarFish_a", oarFishA);
+ assertEquals("oarFish_b", oarFishB);
+ }
+
+ // See https://code.google.com/p/android/issues/detail?id=60639
+ public void test_deleteCharAt_lastChar() {
+ StringBuilder sb = new StringBuilder();
+ sb.append('a');
+ String a = sb.toString();
+
+ sb.deleteCharAt(0);
+ sb.append('b');
+ String b = sb.toString();
+
+ assertEquals("a", a);
+ assertEquals("b", b);
+ }
+
+ // See https://code.google.com/p/android/issues/detail?id=60639
+ public void test_delete_endsAtLastChar() {
+ StringBuilder sb = new StringBuilder("newGuineaSinging");
+ sb.append("Dog");
+ String dog = sb.toString();
+
+ sb.delete(sb.length() - 3, sb.length());
+ sb.append("Cat");
+ String cat = sb.toString();
+
+ // NOTE: It's important that these asserts stay at the end of this test.
+ // We're trying to make sure that replacing chars in the builder does not
+ // change strings that have already been returned from it.
+ assertEquals("newGuineaSingingDog", dog);
+ assertEquals("newGuineaSingingCat", cat);
+ }
+
+ public void test_deleteCharAt_boundsChecks() {
+ StringBuilder sb = new StringBuilder("yeti");
+
+ try {
+ sb.deleteCharAt(sb.length());
+ fail();
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+
+ try {
+ sb.deleteCharAt(-1);
+ fail();
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+ }
+
+ public void test_delete_boundsChecks() throws Exception {
+ StringBuilder sb = new StringBuilder("yeti");
+
+ // The cases below ahould not throw (even though they are clearly invalid
+ // ranges), because we promise not to throw if start == count as long as
+ // end >= start.
+ sb.delete(sb.length(), sb.length() + 2);
+ sb.delete(sb.length(), sb.length());
+
+ sb.delete(2, 2);
+ assertEquals("yeti", sb.toString());
+
+ // We must throw if start > count....
+ try {
+ sb.delete(sb.length() + 2, sb.length() + 3);
+ fail();
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+
+ // ... even if the length of the range is 0.
+ try {
+ sb.delete(sb.length() + 2, sb.length() + 2);
+ fail();
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+
+ // Must throw if start < 0.
+ try {
+ sb.delete(-1, sb.length() -1);
+ fail();
+ } catch (StringIndexOutOfBoundsException expected) {
+ }
+
+ // A few commonly used specializations: sb.delete(0, 0) on an empty
+ // builder is a particularly common pattern.
+ StringBuilder sb2 = new StringBuilder();
+ sb2.delete(0, sb2.length());
+ sb2.delete(0, 12);
+ }
+
+ // We shouldn't throw if the end index is > count, we should clamp it
+ // instead.
+ public void test_delete_clampsEnd() throws Exception {
+ StringBuilder sb = new StringBuilder("mogwai");
+
+ sb.delete(sb.length() - 1 , sb.length() + 2);
+ assertEquals("mogwa", sb.toString());
+
+ sb.delete(sb.length() - 1, sb.length());
+ assertEquals("mogw", sb.toString());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/lang/StringIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/libcore/java/lang/StringIndexOutOfBoundsExceptionTest.java
deleted file mode 100644
index 822e37f..0000000
--- a/luni/src/test/java/libcore/java/lang/StringIndexOutOfBoundsExceptionTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-public final class StringIndexOutOfBoundsExceptionTest extends TestCase {
- public void testCharAt() throws Exception {
- try {
- "hello".charAt(-1);
- fail();
- } catch (StringIndexOutOfBoundsException ex) {
- assertEquals("length=5; index=-1", ex.getMessage());
- }
-
- try {
- "hello".charAt(7);
- fail();
- } catch (StringIndexOutOfBoundsException ex) {
- assertEquals("length=5; index=7", ex.getMessage());
- }
- }
-
- public void testSubstring() throws Exception {
- try {
- "hello there".substring(9,14);
- fail();
- } catch (StringIndexOutOfBoundsException ex) {
- assertEquals("length=11; regionStart=9; regionLength=5",
- ex.getMessage());
- }
- }
-}
diff --git a/luni/src/test/java/libcore/java/lang/StringTest.java b/luni/src/test/java/libcore/java/lang/StringTest.java
index e16496b..bf162e5 100644
--- a/luni/src/test/java/libcore/java/lang/StringTest.java
+++ b/luni/src/test/java/libcore/java/lang/StringTest.java
@@ -174,7 +174,7 @@ public class StringTest extends TestCase {
/**
* Tests a widely assumed performance characteristic of String.substring():
- * that it reuses the original's backing array. Although behaviour should be
+ * that it reuses the original's backing array. Although behavior should be
* correct even if this test fails, many applications may suffer
* significant performance degradation.
*/
@@ -187,7 +187,7 @@ public class StringTest extends TestCase {
/**
* Tests a widely assumed performance characteristic of string's copy
* constructor: that it ensures the backing array is the same length as the
- * string. Although behaviour should be correct even if this test fails,
+ * string. Although behavior should be correct even if this test fails,
* many applications may suffer significant performance degradation.
*/
public void testStringCopiesAvoidHeapRetention() throws IllegalAccessException {
@@ -243,33 +243,43 @@ public class StringTest extends TestCase {
};
public void testCaseMapping_tr_TR() {
- Locale trTR = new Locale("tr", "TR");
- assertEquals(LATIN_SMALL_I, LATIN_SMALL_I.toLowerCase(trTR));
- assertEquals(LATIN_SMALL_I, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toLowerCase(trTR));
- assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_SMALL_DOTLESS_I.toLowerCase(trTR));
+ Locale tr_TR = new Locale("tr", "TR");
+ assertEquals(LATIN_SMALL_I, LATIN_SMALL_I.toLowerCase(tr_TR));
+ assertEquals(LATIN_SMALL_I, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toLowerCase(tr_TR));
+ assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_SMALL_DOTLESS_I.toLowerCase(tr_TR));
- assertEquals(LATIN_CAPITAL_I, LATIN_CAPITAL_I.toUpperCase(trTR));
- assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toUpperCase(trTR));
- assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_SMALL_I.toUpperCase(trTR));
+ assertEquals(LATIN_CAPITAL_I, LATIN_CAPITAL_I.toUpperCase(tr_TR));
+ assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toUpperCase(tr_TR));
+ assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_SMALL_I.toUpperCase(tr_TR));
- assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_DOTLESS_I.toUpperCase(trTR));
- assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_CAPITAL_I.toLowerCase(trTR));
+ assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_DOTLESS_I.toUpperCase(tr_TR));
+ assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_CAPITAL_I.toLowerCase(tr_TR));
}
public void testCaseMapping_en_US() {
- Locale enUs = new Locale("en", "US");
- assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_I.toUpperCase(enUs));
- assertEquals(LATIN_CAPITAL_I, LATIN_CAPITAL_I.toUpperCase(enUs));
- assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toUpperCase(enUs));
+ Locale en_US = new Locale("en", "US");
+ assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_I.toUpperCase(en_US));
+ assertEquals(LATIN_CAPITAL_I, LATIN_CAPITAL_I.toUpperCase(en_US));
+ assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toUpperCase(en_US));
- assertEquals(LATIN_SMALL_I, LATIN_SMALL_I.toLowerCase(enUs));
- assertEquals(LATIN_SMALL_I, LATIN_CAPITAL_I.toLowerCase(enUs));
- assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_SMALL_DOTLESS_I.toLowerCase(enUs));
+ assertEquals(LATIN_SMALL_I, LATIN_SMALL_I.toLowerCase(en_US));
+ assertEquals(LATIN_SMALL_I, LATIN_CAPITAL_I.toLowerCase(en_US));
+ assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_SMALL_DOTLESS_I.toLowerCase(en_US));
- assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_DOTLESS_I.toUpperCase(enUs));
+ assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_DOTLESS_I.toUpperCase(en_US));
// http://b/3325799: the RI fails this because it's using an obsolete version of the Unicode rules.
// Android correctly preserves canonical equivalence. (See the separate test for tr_TR.)
- assertEquals(LATIN_SMALL_I + COMBINING_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toLowerCase(enUs));
+ assertEquals(LATIN_SMALL_I + COMBINING_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toLowerCase(en_US));
+ }
+
+ public void testCaseMapping_el() {
+ Locale el_GR = new Locale("el", "GR");
+ assertEquals("ΟΔΟΣ ΟΔΟΣ ΣΟ ΣΟ OΣ ΟΣ Σ ΕΞ", "ΟΔΌΣ Οδός Σο ΣΟ oΣ ΟΣ σ ἕξ".toUpperCase(el_GR));
+ assertEquals("ΟΔΟΣ ΟΔΟΣ ΣΟ ΣΟ OΣ ΟΣ Σ ΕΞ", "ΟΔΌΣ Οδός Σο ΣΟ oΣ ΟΣ σ ἕξ".toUpperCase(el_GR));
+ assertEquals("ΟΔΟΣ ΟΔΟΣ ΣΟ ΣΟ OΣ ΟΣ Σ ΕΞ", "ΟΔΌΣ Οδός Σο ΣΟ oΣ ΟΣ σ ἕξ".toUpperCase(el_GR));
+
+ Locale en_US = new Locale("en", "US");
+ assertEquals("ΟΔΌΣ ΟΔΌΣ ΣΟ ΣΟ OΣ ΟΣ Σ á¼Îž", "ΟΔΌΣ Οδός Σο ΣΟ oΣ ΟΣ σ ἕξ".toUpperCase(en_US));
}
public void testEqualsIgnoreCase_tr_TR() {
@@ -349,12 +359,88 @@ public class StringTest extends TestCase {
assertEquals("-*-w-*-o-*-r-*-l-*-d-*-", "hello world".substring(6).replace("", "-*-"));
}
- // http://b/11571917
public void test_String_getBytes() throws Exception {
+ // http://b/11571917
assertEquals("[-126, -96]", Arrays.toString("ã‚".getBytes("Shift_JIS")));
assertEquals("[-126, -87]", Arrays.toString("ã‹".getBytes("Shift_JIS")));
assertEquals("[-105, 67]", Arrays.toString("佑".getBytes("Shift_JIS")));
assertEquals("[36]", Arrays.toString("$".getBytes("Shift_JIS")));
assertEquals("[-29, -127, -117]", Arrays.toString("ã‹".getBytes("UTF-8")));
+
+ // http://b/11639117
+ assertEquals("[-79, -72, -70, -48]", Arrays.toString("구분".getBytes("EUC-KR")));
+
+
+ // https://code.google.com/p/android/issues/detail?id=63188
+ assertEquals("[-77, -10, -64, -76, -63, -53]", Arrays.toString("出æ¥äº†".getBytes("gbk")));
+ assertEquals("[-77, -10, -64, -76]", Arrays.toString("出æ¥".getBytes("gbk")));
+ assertEquals("[-77, -10]", Arrays.toString("出".getBytes("gbk")));
+ }
+
+ public void test_compareTo() throws Exception {
+ // For strings where a character differs, the result is
+ // the difference between the characters.
+ assertEquals(-1, "a".compareTo("b"));
+ assertEquals(-2, "a".compareTo("c"));
+ assertEquals(1, "b".compareTo("a"));
+ assertEquals(2, "c".compareTo("a"));
+
+ // For strings where the characters match up to the length of the shorter,
+ // the result is the difference between the strings' lengths.
+ assertEquals(0, "a".compareTo("a"));
+ assertEquals(-1, "a".compareTo("aa"));
+ assertEquals(-1, "a".compareTo("az"));
+ assertEquals(-2, "a".compareTo("aaa"));
+ assertEquals(-2, "a".compareTo("azz"));
+ assertEquals(-3, "a".compareTo("aaaa"));
+ assertEquals(-3, "a".compareTo("azzz"));
+ assertEquals(0, "a".compareTo("a"));
+ assertEquals(1, "aa".compareTo("a"));
+ assertEquals(1, "az".compareTo("a"));
+ assertEquals(2, "aaa".compareTo("a"));
+ assertEquals(2, "azz".compareTo("a"));
+ assertEquals(3, "aaaa".compareTo("a"));
+ assertEquals(3, "azzz".compareTo("a"));
+ }
+
+ public void test_compareToIgnoreCase() throws Exception {
+ // For strings where a character differs, the result is
+ // the difference between the characters.
+ assertEquals(-1, "a".compareToIgnoreCase("b"));
+ assertEquals(-1, "a".compareToIgnoreCase("B"));
+ assertEquals(-2, "a".compareToIgnoreCase("c"));
+ assertEquals(-2, "a".compareToIgnoreCase("C"));
+ assertEquals(1, "b".compareToIgnoreCase("a"));
+ assertEquals(1, "B".compareToIgnoreCase("a"));
+ assertEquals(2, "c".compareToIgnoreCase("a"));
+ assertEquals(2, "C".compareToIgnoreCase("a"));
+
+ // For strings where the characters match up to the length of the shorter,
+ // the result is the difference between the strings' lengths.
+ assertEquals(0, "a".compareToIgnoreCase("a"));
+ assertEquals(0, "a".compareToIgnoreCase("A"));
+ assertEquals(0, "A".compareToIgnoreCase("a"));
+ assertEquals(0, "A".compareToIgnoreCase("A"));
+ assertEquals(-1, "a".compareToIgnoreCase("aa"));
+ assertEquals(-1, "a".compareToIgnoreCase("aA"));
+ assertEquals(-1, "a".compareToIgnoreCase("Aa"));
+ assertEquals(-1, "a".compareToIgnoreCase("az"));
+ assertEquals(-1, "a".compareToIgnoreCase("aZ"));
+ assertEquals(-2, "a".compareToIgnoreCase("aaa"));
+ assertEquals(-2, "a".compareToIgnoreCase("AAA"));
+ assertEquals(-2, "a".compareToIgnoreCase("azz"));
+ assertEquals(-2, "a".compareToIgnoreCase("AZZ"));
+ assertEquals(-3, "a".compareToIgnoreCase("aaaa"));
+ assertEquals(-3, "a".compareToIgnoreCase("AAAA"));
+ assertEquals(-3, "a".compareToIgnoreCase("azzz"));
+ assertEquals(-3, "a".compareToIgnoreCase("AZZZ"));
+ assertEquals(1, "aa".compareToIgnoreCase("a"));
+ assertEquals(1, "aA".compareToIgnoreCase("a"));
+ assertEquals(1, "Aa".compareToIgnoreCase("a"));
+ assertEquals(1, "az".compareToIgnoreCase("a"));
+ assertEquals(2, "aaa".compareToIgnoreCase("a"));
+ assertEquals(2, "azz".compareToIgnoreCase("a"));
+ assertEquals(3, "aaaa".compareToIgnoreCase("a"));
+ assertEquals(3, "azzz".compareToIgnoreCase("a"));
}
}
diff --git a/luni/src/test/java/libcore/java/lang/SystemTest.java b/luni/src/test/java/libcore/java/lang/SystemTest.java
index f995954..ff155d3 100644
--- a/luni/src/test/java/libcore/java/lang/SystemTest.java
+++ b/luni/src/test/java/libcore/java/lang/SystemTest.java
@@ -16,14 +16,15 @@
package libcore.java.lang;
-import junit.framework.TestCase;
-
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Formatter;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+import junit.framework.TestCase;
public class SystemTest extends TestCase {
@@ -33,11 +34,11 @@ public class SystemTest extends TestCase {
// use System.getProperty. Now they should use System.lineSeparator instead, and the
// "line.separator" property has no effect after the VM has started.
- // Test System.lineSeparator directly.
+ // Test that System.lineSeparator is not changed when the corresponding
+ // system property is changed.
assertEquals("\n", System.lineSeparator());
System.setProperty("line.separator", "poop");
assertEquals("\n", System.lineSeparator());
- assertFalse(System.lineSeparator().equals(System.getProperty("line.separator")));
// java.io.BufferedWriter --- uses System.lineSeparator on Android but not on RI.
StringWriter sw = new StringWriter();
@@ -45,23 +46,19 @@ public class SystemTest extends TestCase {
bw.newLine();
bw.flush();
assertEquals(System.lineSeparator(), sw.toString());
- assertFalse(System.lineSeparator().equals(System.getProperty("line.separator")));
// java.io.PrintStream --- uses System.lineSeparator on Android but not on RI.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new PrintStream(baos).println();
assertEquals(System.lineSeparator(), new String(baos.toByteArray(), "UTF-8"));
- assertFalse(System.lineSeparator().equals(System.getProperty("line.separator")));
// java.io.PrintWriter --- uses System.lineSeparator on Android but not on RI.
sw = new StringWriter();
new PrintWriter(sw).println();
assertEquals(System.lineSeparator(), sw.toString());
- assertFalse(System.lineSeparator().equals(System.getProperty("line.separator")));
// java.util.Formatter --- uses System.lineSeparator on both.
assertEquals(System.lineSeparator(), new Formatter().format("%n").toString());
- assertFalse(System.lineSeparator().equals(System.getProperty("line.separator")));
} finally {
System.setProperty("line.separator", "\n");
}
@@ -90,7 +87,7 @@ public class SystemTest extends TestCase {
System.arraycopy(new char[5], 0, new Object[5], 0, 3);
fail();
} catch (ArrayStoreException e) {
- assertEquals("char[] and java.lang.Object[] are incompatible array types", e.getMessage());
+ assertEquals("Incompatible types: src=char[], dst=java.lang.Object[]", e.getMessage());
}
}
@@ -118,4 +115,125 @@ public class SystemTest extends TestCase {
assertEquals("dst == null", e.getMessage());
}
}
+
+ /**
+ * System.arraycopy() must never copy objects into arrays that can't store
+ * them. We've had bugs where type checks and copying were done separately
+ * and racy code could defeat the type checks. http://b/5247258
+ */
+ public void testArrayCopyConcurrentModification() {
+ final AtomicBoolean done = new AtomicBoolean();
+
+ final Object[] source = new Object[1024 * 1024];
+ String[] target = new String[1024 * 1024];
+
+ new Thread() {
+ @Override public void run() {
+ // the last array element alternates between being a Thread and being null. When
+ // it's a Thread it isn't safe for arrayCopy; when its null it is!
+ while (!done.get()) {
+ source[source.length - 1] = this;
+ source[source.length - 1] = null;
+ }
+ }
+ }.start();
+
+ for (int i = 0; i < 8192; i++) {
+ try {
+ System.arraycopy(source, 0, target, 0, source.length);
+ assertNull(target[source.length - 1]); // make sure the wrong type didn't sneak in
+ } catch (ArrayStoreException ignored) {
+ }
+ }
+
+ done.set(true);
+ }
+
+ public void testSystemProperties_immutable() {
+ // Android-specific: The RI does not have a concept of immutable properties.
+
+ // user.dir is an immutable property
+ String userDir = System.getProperty("user.dir");
+ assertNotNull(userDir);
+ System.setProperty("user.dir", "not poop");
+ assertEquals(userDir, System.getProperty("user.dir"));
+
+ System.getProperties().setProperty("user.dir", "hmmph");
+ assertEquals(userDir, System.getProperty("user.dir"));
+
+ System.getProperties().clear();
+ assertEquals(userDir, System.getProperty("user.dir"));
+
+ Properties p = new Properties();
+ p.setProperty("user.dir", "meh");
+ System.setProperties(p);
+
+ assertEquals(userDir, System.getProperty("user.dir"));
+ }
+
+ public void testSystemProperties_mutable() {
+ // We allow "java.io.tmpdir" and "user.home" to be changed however
+ // we can't test for "java.io.tmpdir" consistently across test runners because
+ // it will be immutable if set on the dalvikvm command line "-Djava.io.tmpdir="
+ // like vogar does.
+ String oldUserHome = System.getProperty("user.home");
+ try {
+ System.setProperty("user.home", "/user/home");
+ assertEquals("/user/home", System.getProperty("user.home"));
+ } finally {
+ System.setProperty("user.home", oldUserHome);
+ }
+ }
+
+ public void testSystemProperties_setProperties_null() {
+ // user.dir is an immutable property
+ String userDir = System.getProperty("user.dir");
+ assertNotNull(userDir);
+
+ // Add a non-standard property
+ System.setProperty("p1", "v1");
+
+ // Reset using setProperties(null)
+ System.setProperties(null);
+
+ // All the immutable properties should be reset.
+ assertEquals(userDir, System.getProperty("user.dir"));
+ // Non-standard properties are cleared.
+ assertNull(System.getProperty("p1"));
+ }
+
+ public void testSystemProperties_setProperties_nonNull() {
+ String userDir = System.getProperty("user.dir");
+
+ Properties newProperties = new Properties();
+ // Immutable property
+ newProperties.setProperty("user.dir", "v1");
+ // Non-standard property
+ newProperties.setProperty("p1", "v2");
+
+ System.setProperties(newProperties);
+
+ // Android-specific: The RI makes the setProperties() argument the system properties object,
+ // Android makes a new Properties object and copies the properties.
+ assertNotSame(newProperties, System.getProperties());
+ // Android-specific: The RI does not have a concept of immutable properties.
+ assertEquals(userDir, System.getProperty("user.dir"));
+
+ assertEquals("v2", System.getProperty("p1"));
+ }
+
+ public void testSystemProperties_getProperties_clear() {
+ String userDir = System.getProperty("user.dir");
+ assertNotNull(userDir);
+ System.setProperty("p1", "v1");
+
+ Properties properties = System.getProperties();
+ assertEquals("v1", properties.getProperty("p1"));
+
+ properties.clear();
+
+ // Android-specific: The RI clears everything, Android resets to immutable defaults.
+ assertEquals(userDir, System.getProperty("user.dir"));
+ assertNull(System.getProperty("p1"));
+ }
}
diff --git a/luni/src/test/java/libcore/java/lang/ThreadTest.java b/luni/src/test/java/libcore/java/lang/ThreadTest.java
index 998afdb..8545a20 100644
--- a/luni/src/test/java/libcore/java/lang/ThreadTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThreadTest.java
@@ -58,14 +58,71 @@ public final class ThreadTest extends TestCase {
assertTrue("Unstarted threads were never finalized!", finalizedThreadsCount.get() > 0);
}
- private Thread newThread(final AtomicInteger finalizedThreadsCount, final int size) {
- return new Thread() {
- byte[] memoryPressure = new byte[size];
- @Override protected void finalize() throws Throwable {
- super.finalize();
- finalizedThreadsCount.incrementAndGet();
- }
- };
+ public void testThreadSleep() throws Exception {
+ int millis = 1000;
+ long start = System.currentTimeMillis();
+
+ Thread.sleep(millis);
+
+ long elapsed = System.currentTimeMillis() - start;
+ long offBy = Math.abs(elapsed - millis);
+
+ assertTrue("Actual sleep off by " + offBy + " ms", offBy <= 250);
+ }
+
+ public void testThreadInterrupted() throws Exception {
+ Thread.currentThread().interrupt();
+ try {
+ Thread.sleep(0);
+ fail();
+ } catch (InterruptedException e) {
+ assertFalse(Thread.currentThread().isInterrupted());
+ }
+ }
+
+ public void testThreadSleepIllegalArguments() throws Exception {
+
+ try {
+ Thread.sleep(-1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ Thread.sleep(0, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ Thread.sleep(0, 1000000);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testThreadWakeup() throws Exception {
+ WakeupTestThread t1 = new WakeupTestThread();
+ WakeupTestThread t2 = new WakeupTestThread();
+
+ t1.start();
+ t2.start();
+ assertTrue("Threads already finished", !t1.done && !t2.done);
+
+ t1.interrupt();
+ t2.interrupt();
+
+ Thread.sleep(1000);
+ assertTrue("Threads did not finish", t1.done && t2.done);
+ }
+
+ public void testContextClassLoaderIsNotNull() {
+ assertNotNull(Thread.currentThread().getContextClassLoader());
+ }
+
+ public void testContextClassLoaderIsInherited() {
+ Thread other = new Thread();
+ assertSame(Thread.currentThread().getContextClassLoader(), other.getContextClassLoader());
}
/**
@@ -109,4 +166,30 @@ public final class ThreadTest extends TestCase {
// Expect to see the traces of all threads (not just t2)
assertTrue("Must have traces for all threads", visibleTraces.get() > 1);
}
+
+ private Thread newThread(final AtomicInteger finalizedThreadsCount, final int size) {
+ return new Thread() {
+ long[] memoryPressure = new long[size];
+ @Override protected void finalize() throws Throwable {
+ super.finalize();
+ finalizedThreadsCount.incrementAndGet();
+ }
+ };
+ }
+
+ private class WakeupTestThread extends Thread {
+ public boolean done;
+
+ public void run() {
+ done = false;
+
+ // Sleep for a while (1 min)
+ try {
+ Thread.sleep(60000);
+ } catch (InterruptedException ignored) {
+ }
+
+ done = true;
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java b/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
index c23775e..4cc69ba 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
@@ -16,6 +16,7 @@
package libcore.java.lang.reflect;
+import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
@@ -23,7 +24,11 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -56,7 +61,13 @@ public final class AnnotationsTest extends TestCase {
public void testParameterAnnotations() throws Exception {
Method method = Type.class.getMethod("method", String.class, String.class);
- Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+ Annotation[][] noParameterAnnotations = method.getParameterAnnotations();
+ assertEquals(2, noParameterAnnotations.length);
+ assertEquals(set(), annotationsToTypes(noParameterAnnotations[0]));
+ assertEquals(set(), annotationsToTypes(noParameterAnnotations[1]));
+
+ Method parameters = Type.class.getMethod("parameters", String.class, String.class);
+ Annotation[][] parameterAnnotations = parameters.getParameterAnnotations();
assertEquals(2, parameterAnnotations.length);
assertEquals(set(AnnotationB.class, AnnotationD.class),
annotationsToTypes(parameterAnnotations[0]));
@@ -64,6 +75,206 @@ public final class AnnotationsTest extends TestCase {
annotationsToTypes(parameterAnnotations[1]));
}
+ public void testAnnotationDefaults() throws Exception {
+ assertEquals((byte) 5, defaultValue("a"));
+ assertEquals((short) 6, defaultValue("b"));
+ assertEquals(7, defaultValue("c"));
+ assertEquals(8L, defaultValue("d"));
+ assertEquals(9.0f, defaultValue("e"));
+ assertEquals(10.0, defaultValue("f"));
+ assertEquals('k', defaultValue("g"));
+ assertEquals(true, defaultValue("h"));
+ assertEquals(Breakfast.WAFFLES, defaultValue("i"));
+ assertEquals("@" + AnnotationA.class.getName() + "()", defaultValue("j").toString());
+ assertEquals("maple", defaultValue("k"));
+ assertEquals(AnnotationB.class, defaultValue("l"));
+ assertEquals("[1, 2, 3]", Arrays.toString((int[]) defaultValue("m")));
+ assertEquals("[WAFFLES, PANCAKES]", Arrays.toString((Breakfast[]) defaultValue("n")));
+ assertEquals(null, defaultValue("o"));
+ assertEquals(null, defaultValue("p"));
+ }
+
+ private Object defaultValue(String name) throws NoSuchMethodException {
+ return HasDefaultsAnnotation.class.getMethod(name).getDefaultValue();
+ }
+
+ public void testGetEnclosingClass() {
+ assertNull(AnnotationsTest.class.getEnclosingClass());
+ assertEquals(AnnotationsTest.class, Foo.class.getEnclosingClass());
+ assertEquals(AnnotationsTest.class, HasMemberClassesInterface.class.getEnclosingClass());
+ assertEquals(HasMemberClassesInterface.class,
+ HasMemberClassesInterface.D.class.getEnclosingClass());
+ assertEquals(AnnotationsTest.class, Foo.class.getEnclosingClass());
+ }
+
+ public void testGetDeclaringClass() {
+ assertNull(AnnotationsTest.class.getDeclaringClass());
+ assertEquals(AnnotationsTest.class, Foo.class.getDeclaringClass());
+ assertEquals(AnnotationsTest.class, HasMemberClassesInterface.class.getDeclaringClass());
+ assertEquals(HasMemberClassesInterface.class,
+ HasMemberClassesInterface.D.class.getDeclaringClass());
+ }
+
+ public void testGetEnclosingClassIsTransitiveForClassesDefinedInAMethod() {
+ class C {}
+ assertEquals(AnnotationsTest.class, C.class.getEnclosingClass());
+ }
+
+ public void testGetDeclaringClassIsNotTransitiveForClassesDefinedInAMethod() {
+ class C {}
+ assertEquals(null, C.class.getDeclaringClass());
+ }
+
+ public void testGetEnclosingMethodIsNotTransitive() {
+ class C {
+ class D {}
+ }
+ assertEquals(null, C.D.class.getEnclosingMethod());
+ }
+
+ public void testStaticFieldAnonymousClass() {
+ // The class declared in the <clinit> is enclosed by the <clinit>'s class.
+ // http://b/11245138
+ assertEquals(AnnotationsTest.class, staticAnonymous.getClass().getEnclosingClass());
+ // However, because it is anonymous, it has no declaring class.
+ // https://code.google.com/p/android/issues/detail?id=61003
+ assertNull(staticAnonymous.getClass().getDeclaringClass());
+ // Because the class is declared in <clinit> which is not exposed through reflection,
+ // it has no enclosing method or constructor.
+ assertNull(staticAnonymous.getClass().getEnclosingMethod());
+ assertNull(staticAnonymous.getClass().getEnclosingConstructor());
+ }
+
+ public void testGetEnclosingMethodOfTopLevelClass() {
+ assertNull(AnnotationsTest.class.getEnclosingMethod());
+ }
+
+ public void testGetEnclosingConstructorOfTopLevelClass() {
+ assertNull(AnnotationsTest.class.getEnclosingConstructor());
+ }
+
+ public void testClassEnclosedByConstructor() throws Exception {
+ Foo foo = new Foo("string");
+ assertEquals(Foo.class, foo.c.getEnclosingClass());
+ assertEquals(Foo.class.getDeclaredConstructor(String.class),
+ foo.c.getEnclosingConstructor());
+ assertNull(foo.c.getEnclosingMethod());
+ assertNull(foo.c.getDeclaringClass());
+ }
+
+ public void testClassEnclosedByMethod() throws Exception {
+ Foo foo = new Foo();
+ foo.foo("string");
+ assertEquals(Foo.class, foo.c.getEnclosingClass());
+ assertNull(foo.c.getEnclosingConstructor());
+ assertEquals(Foo.class.getDeclaredMethod("foo", String.class),
+ foo.c.getEnclosingMethod());
+ assertNull(foo.c.getDeclaringClass());
+ }
+
+ public void testGetClasses() throws Exception {
+ // getClasses() doesn't include classes inherited from interfaces!
+ assertSetEquals(HasMemberClasses.class.getClasses(),
+ HasMemberClassesSuperclass.B.class, HasMemberClasses.H.class);
+ }
+
+ public void testGetDeclaredClasses() throws Exception {
+ assertSetEquals(HasMemberClasses.class.getDeclaredClasses(),
+ HasMemberClasses.G.class, HasMemberClasses.H.class, HasMemberClasses.I.class,
+ HasMemberClasses.J.class, HasMemberClasses.K.class, HasMemberClasses.L.class);
+ }
+
+ public void testConstructorGetExceptions() throws Exception {
+ assertSetEquals(HasThrows.class.getConstructor().getExceptionTypes(),
+ IOException.class, InvocationTargetException.class, IllegalStateException.class);
+ assertSetEquals(HasThrows.class.getConstructor(Void.class).getExceptionTypes());
+ }
+
+ public void testClassMethodGetExceptions() throws Exception {
+ assertSetEquals(HasThrows.class.getMethod("foo").getExceptionTypes(),
+ IOException.class, InvocationTargetException.class, IllegalStateException.class);
+ assertSetEquals(HasThrows.class.getMethod("foo", Void.class).getExceptionTypes());
+ }
+
+ public void testProxyMethodGetExceptions() throws Exception {
+ InvocationHandler emptyInvocationHandler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ return null;
+ }
+ };
+
+ Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(),
+ new Class[] { ThrowsInterface.class }, emptyInvocationHandler);
+ assertSetEquals(proxy.getClass().getMethod("foo").getExceptionTypes(),
+ IOException.class, InvocationTargetException.class, IllegalStateException.class);
+ assertSetEquals(proxy.getClass().getMethod("foo", Void.class).getExceptionTypes());
+ }
+
+ public void testClassModifiers() {
+ int modifiers = AnnotationsTest.class.getModifiers();
+ assertTrue(Modifier.isPublic(modifiers));
+ assertFalse(Modifier.isProtected(modifiers));
+ assertFalse(Modifier.isPrivate(modifiers));
+ assertFalse(Modifier.isAbstract(modifiers));
+ assertFalse(Modifier.isStatic(modifiers));
+ assertTrue(Modifier.isFinal(modifiers));
+ assertFalse(Modifier.isStrict(modifiers));
+ }
+
+ public void testInnerClassModifiers() {
+ int modifiers = Foo.class.getModifiers();
+ assertFalse(Modifier.isPublic(modifiers));
+ assertFalse(Modifier.isProtected(modifiers));
+ assertTrue(Modifier.isPrivate(modifiers));
+ assertFalse(Modifier.isAbstract(modifiers));
+ assertTrue(Modifier.isStatic(modifiers));
+ assertFalse(Modifier.isFinal(modifiers));
+ assertFalse(Modifier.isStrict(modifiers));
+ }
+
+ public void testAnonymousClassModifiers() {
+ int modifiers = staticAnonymous.getClass().getModifiers();
+ assertFalse(Modifier.isPublic(modifiers));
+ assertFalse(Modifier.isProtected(modifiers));
+ assertFalse(Modifier.isPrivate(modifiers));
+ assertFalse(Modifier.isAbstract(modifiers));
+ assertTrue(Modifier.isStatic(modifiers));
+ assertFalse(Modifier.isFinal(modifiers));
+ assertFalse(Modifier.isStrict(modifiers));
+ }
+
+ public void testInnerClassName() {
+ assertEquals("AnnotationsTest", AnnotationsTest.class.getSimpleName());
+ assertEquals("Foo", Foo.class.getSimpleName());
+ assertEquals("", staticAnonymous.getClass().getSimpleName());
+ }
+
+ public void testIsAnonymousClass() {
+ assertFalse(AnnotationsTest.class.isAnonymousClass());
+ assertFalse(Foo.class.isAnonymousClass());
+ assertTrue(staticAnonymous.getClass().isAnonymousClass());
+ }
+
+ private static final Object staticAnonymous = new Object() {};
+
+ private static class Foo {
+ Class<?> c;
+ private Foo() {
+ }
+ private Foo(String s) {
+ c = new Object() {}.getClass();
+ }
+ private Foo(int i) {
+ c = new Object() {}.getClass();
+ }
+ private void foo(String s) {
+ c = new Object() {}.getClass();
+ }
+ private void foo(int i) {
+ c = new Object() {}.getClass();
+ }
+ }
+
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationA {}
@@ -81,12 +292,68 @@ public final class AnnotationsTest extends TestCase {
public static class Type {
@AnnotationA @AnnotationC public Type() {}
@AnnotationA @AnnotationD public String field;
- @AnnotationB @AnnotationC public void method(@AnnotationB @AnnotationD String parameter1,
+ @AnnotationB @AnnotationC public void method(String parameter1, String parameter2) {}
+ @AnnotationB @AnnotationC public void parameters(@AnnotationB @AnnotationD String parameter1,
@AnnotationC @AnnotationD String parameter2) {}
}
public static class ExtendsType extends Type {}
+ static enum Breakfast { WAFFLES, PANCAKES }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface HasDefaultsAnnotation {
+ byte a() default 5;
+ short b() default 6;
+ int c() default 7;
+ long d() default 8;
+ float e() default 9.0f;
+ double f() default 10.0;
+ char g() default 'k';
+ boolean h() default true;
+ Breakfast i() default Breakfast.WAFFLES;
+ AnnotationA j() default @AnnotationA();
+ String k() default "maple";
+ Class l() default AnnotationB.class;
+ int[] m() default { 1, 2, 3 };
+ Breakfast[] n() default { Breakfast.WAFFLES, Breakfast.PANCAKES };
+ Breakfast o();
+ int p();
+ }
+
+ static class HasMemberClassesSuperclass {
+ class A {}
+ public class B {}
+ static class C {}
+ }
+
+ public interface HasMemberClassesInterface {
+ class D {}
+ public class E {}
+ static class F {}
+ }
+
+ public static class HasMemberClasses extends HasMemberClassesSuperclass
+ implements HasMemberClassesInterface {
+ class G {}
+ public class H {}
+ static class I {}
+ enum J {}
+ interface K {}
+ @interface L {}
+ }
+
+ public static class HasThrows {
+ public HasThrows() throws IOException, InvocationTargetException, IllegalStateException {}
+ public HasThrows(Void v) {}
+ public void foo() throws IOException, InvocationTargetException, IllegalStateException {}
+ public void foo(Void v) {}
+ }
+
+ public static interface ThrowsInterface {
+ void foo() throws IOException, InvocationTargetException, IllegalStateException;
+ void foo(Void v);
+ }
private void assertAnnotatedElement(
AnnotatedElement element, Class<? extends Annotation>... expectedAnnotations) {
@@ -134,4 +401,10 @@ public final class AnnotationsTest extends TestCase {
private <T> Set<T> set(T... instances) {
return new HashSet<T>(Arrays.asList(instances));
}
+
+ private void assertSetEquals(Object[] actual, Object... expected) {
+ Set<Object> actualSet = new HashSet<Object>(Arrays.asList(actual));
+ Set<Object> expectedSet = new HashSet<Object>(Arrays.asList(expected));
+ assertEquals(expectedSet, actualSet);
+ }
}
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java b/luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java
index 2e15de2..28fd7e9 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java
@@ -124,6 +124,28 @@ public final class ClassLoaderReflectionTest extends TestCase {
assertParameterizedType(types[1], List.class, aClass);
}
+ public void testClassesOfDifferentClassLoadersAreNotEqual() throws Exception {
+ assertFalse(A.class.equals(aClass));
+ }
+
+ public void testConstructorsOfDifferentClassLoadersAreNotEqual() throws Exception {
+ Constructor<?> c1 = A.class.getDeclaredConstructor();
+ Constructor<?> c2 = aClass.getDeclaredConstructor();
+ assertFalse(c1.equals(c2));
+ }
+
+ public void testMethodsOfDifferentClassLoadersAreNotEqual() throws Exception {
+ Method m1 = E.class.getMethod("call");
+ Method m2 = eClass.getMethod("call");
+ assertFalse(m1.equals(m2));
+ }
+
+ public void testFieldsOfDifferentClassLoadersAreNotEqual() throws Exception {
+ Field f1 = B.class.getDeclaredField("field");
+ Field f2 = bClass.getDeclaredField("field");
+ assertFalse(f1.equals(f2));
+ }
+
static class A {}
static class B<T> {
T field;
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java b/luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java
index ed98794..51ddfc0 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java
@@ -72,6 +72,24 @@ public final class ConstructorTest extends TestCase {
assertEquals(2, constructor.getParameterTypes().length);
}
+ public void testEqualConstructorEqualsAndHashCode() throws Exception {
+ Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
+ Constructor<?> c2 = ConstructorTestHelper.class.getConstructor();
+ assertEquals(c1, c2);
+ assertEquals(c1.hashCode(), c2.hashCode());
+ }
+
+ public void testHashCodeSpec() throws Exception {
+ Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
+ assertEquals(ConstructorTestHelper.class.getName().hashCode(), c1.hashCode());
+ }
+
+ public void testDifferentConstructorEqualsAndHashCode() throws Exception {
+ Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
+ Constructor<?> c2 = ConstructorTestHelper.class.getConstructor(Object.class);
+ assertFalse(c1.equals(c2));
+ }
+
static class ConstructorTestHelper {
public ConstructorTestHelper() throws IndexOutOfBoundsException { }
public ConstructorTestHelper(Object o) { }
diff --git a/luni/src/test/java/libcore/java/lang/reflect/FieldTest.java b/luni/src/test/java/libcore/java/lang/reflect/FieldTest.java
index eb3d034..b60d984 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/FieldTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/FieldTest.java
@@ -27,4 +27,27 @@ public final class FieldTest extends TestCase {
Field field = getClass().getDeclaredField("MY_LONG");
assertEquals(5073258162644648461L, field.getLong(null));
}
+
+ public void testEqualConstructorEqualsAndHashCode() throws Exception {
+ Field f1 = FieldTestHelper.class.getField("a");
+ Field f2 = FieldTestHelper.class.getField("a");
+ assertEquals(f1, f2);
+ assertEquals(f1.hashCode(), f2.hashCode());
+ }
+
+ public void testHashCodeSpec() throws Exception {
+ Field f1 = FieldTestHelper.class.getField("a");
+ assertEquals(FieldTestHelper.class.getName().hashCode() ^ "a".hashCode(), f1.hashCode());
+ }
+
+ public void testDifferentConstructorEqualsAndHashCode() throws Exception {
+ Field f1 = FieldTestHelper.class.getField("a");
+ Field f2 = FieldTestHelper.class.getField("b");
+ assertFalse(f1.equals(f2));
+ }
+
+ static class FieldTestHelper {
+ public String a;
+ public Object b;
+ }
}
diff --git a/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java b/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java
index ef30eb8..c3a436c 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java
@@ -20,42 +20,6 @@ import java.lang.reflect.Method;
import junit.framework.TestCase;
public final class MethodTest extends TestCase {
- // Check that the VM gives useful detail messages.
- public void test_invokeExceptions() throws Exception {
- Method m = String.class.getMethod("charAt", int.class);
- try {
- m.invoke("hello"); // Wrong number of arguments.
- fail();
- } catch (IllegalArgumentException iae) {
- assertEquals("wrong number of arguments; expected 1, got 0", iae.getMessage());
- }
- try {
- m.invoke("hello", "world"); // Wrong type.
- fail();
- } catch (IllegalArgumentException iae) {
- assertEquals("argument 1 should have type int, got java.lang.String", iae.getMessage());
- }
- try {
- m.invoke("hello", (Object) null); // Null for a primitive argument.
- fail();
- } catch (IllegalArgumentException iae) {
- assertEquals("argument 1 should have type int, got null", iae.getMessage());
- }
- try {
- m.invoke(new Integer(5)); // Wrong type for 'this'.
- fail();
- } catch (IllegalArgumentException iae) {
- assertEquals("expected receiver of type java.lang.String, but got java.lang.Integer", iae.getMessage());
- }
- try {
- m.invoke(null); // Null for 'this'.
- fail();
- } catch (NullPointerException npe) {
- assertEquals("expected receiver of type java.lang.String, but got null",
- npe.getMessage());
- }
- }
-
public void test_getExceptionTypes() throws Exception {
Method method = MethodTestHelper.class.getMethod("m1", new Class[0]);
Class[] exceptions = method.getExceptionTypes();
@@ -197,6 +161,26 @@ public final class MethodTest extends TestCase {
assertEquals(anonymous.getClass(), method.getDeclaringClass());
}
+ public void testEqualMethodEqualsAndHashCode() throws Exception {
+ Method m1 = MethodTestHelper.class.getMethod("m1");
+ Method m2 = MethodTestHelper.class.getMethod("m1");
+ assertEquals(m1, m2);
+ assertEquals(m1.hashCode(), m2.hashCode());
+ assertEquals(MethodTestHelper.class.getName().hashCode() ^ "m1".hashCode(), m1.hashCode());
+ }
+
+ public void testHashCodeSpec() throws Exception {
+ Method m1 = MethodTestHelper.class.getMethod("m1");
+ assertEquals(MethodTestHelper.class.getName().hashCode() ^ "m1".hashCode(), m1.hashCode());
+ }
+
+ public void testDifferentMethodEqualsAndHashCode() throws Exception {
+ Method m1 = MethodTestHelper.class.getMethod("m1");
+ Method m2 = MethodTestHelper.class.getMethod("m2", Object.class);
+ assertFalse(m1.equals(m2));
+ assertFalse(m1.hashCode() == m2.hashCode());
+ }
+
// http://b/1045939
public void testMethodToString() throws Exception {
assertEquals("public final native void java.lang.Object.notify()",
diff --git a/luni/src/test/java/libcore/java/lang/reflect/OldGenericReflectionCornerCases.java b/luni/src/test/java/libcore/java/lang/reflect/OldGenericReflectionCornerCases.java
index 168a00d..ad3cc06 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/OldGenericReflectionCornerCases.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/OldGenericReflectionCornerCases.java
@@ -16,12 +16,12 @@
package libcore.java.lang.reflect;
+import org.apache.harmony.tests.java.lang.reflect.GenericReflectionTestsBase;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
-import tests.api.java.lang.reflect.GenericReflectionTestsBase;
/**
* Tests generic reflection in more complicated cases. In particular: Scoping of
diff --git a/luni/src/test/java/libcore/java/lang/reflect/OldGenericTypesTest.java b/luni/src/test/java/libcore/java/lang/reflect/OldGenericTypesTest.java
index 69eff4f..9dec794 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/OldGenericTypesTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/OldGenericTypesTest.java
@@ -21,7 +21,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
-import tests.api.java.lang.reflect.GenericReflectionTestsBase;
+import org.apache.harmony.tests.java.lang.reflect.GenericReflectionTestsBase;
/**
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java b/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
index 30d47fb..abd5851 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
@@ -16,14 +16,25 @@
package libcore.java.lang.reflect;
+import java.io.EOFException;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.net.SocketException;
import junit.framework.TestCase;
import tests.util.ClassLoaderBuilder;
public final class ProxyTest extends TestCase {
+ private final ClassLoader loader = getClass().getClassLoader();
+ private final InvocationHandler returnHandler = new TestInvocationHandler();
+ private final InvocationHandler throwHandler = new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ throw (Throwable) args[0];
+ }
+ };
/**
* Make sure the proxy's class loader fails if it cannot see the class
@@ -36,7 +47,7 @@ public final class ProxyTest extends TestCase {
Class[] interfacesA = { loaderA.loadClass(prefix + "$Echo") };
try {
- Proxy.newProxyInstance(loaderB, interfacesA, new TestInvocationHandler());
+ Proxy.newProxyInstance(loaderB, interfacesA, returnHandler);
fail();
} catch (IllegalArgumentException expected) {
}
@@ -55,10 +66,331 @@ public final class ProxyTest extends TestCase {
assertEquals("foo", proxy.getClass().getMethod("echo", String.class).invoke(proxy, "foo"));
}
+ public void testIncompatibleReturnTypesPrimitiveAndPrimitive() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsFloat.class},
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIncompatibleReturnTypesPrimitiveAndWrapper() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsInteger.class},
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIncompatibleReturnTypesPrimitiveAndVoid() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsVoid.class},
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIncompatibleReturnTypesIncompatibleObjects() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsInteger.class, ReturnsString.class },
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testCompatibleReturnTypesImplementedInterface() {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsCharSequence.class},
+ returnHandler);
+ Proxy.newProxyInstance(loader, new Class[]{ReturnsObject.class, ReturnsCharSequence.class,
+ ReturnsString.class}, returnHandler);
+ Proxy.newProxyInstance(loader, new Class[]{ReturnsObject.class, ReturnsCharSequence.class,
+ ReturnsString.class, ReturnsSerializable.class, ReturnsComparable.class},
+ returnHandler);
+ }
+
+
+ public void testCompatibleReturnTypesSuperclass() {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsObject.class},
+ returnHandler);
+ }
+
+ public void testDeclaredExceptionIntersectionIsSubtype() throws Exception {
+ ThrowsIOException instance = (ThrowsIOException) Proxy.newProxyInstance(loader,
+ new Class[] {ThrowsIOException.class, ThrowsEOFException.class},
+ throwHandler);
+ try {
+ instance.run(new EOFException());
+ fail();
+ } catch (EOFException expected) {
+ }
+ try {
+ instance.run(new IOException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ try {
+ instance.run(new Exception());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ }
+
+ public void testDeclaredExceptionIntersectionIsEmpty() throws Exception {
+ ThrowsEOFException instance = (ThrowsEOFException) Proxy.newProxyInstance(loader,
+ new Class[] {ThrowsSocketException.class, ThrowsEOFException.class},
+ throwHandler);
+ try {
+ instance.run(new EOFException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ try {
+ instance.run(new SocketException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ }
+
+ public void testDeclaredExceptionIntersectionIsSubset() throws Exception {
+ ThrowsEOFException instance = (ThrowsEOFException) Proxy.newProxyInstance(loader,
+ new Class[] {ThrowsEOFException.class, ThrowsSocketExceptionAndEOFException.class},
+ throwHandler);
+ try {
+ instance.run(new EOFException());
+ fail();
+ } catch (EOFException expected) {
+ }
+ try {
+ instance.run(new SocketException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ try {
+ instance.run(new IOException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ }
+
+ public void testDeclaredExceptionIntersectedByExactReturnTypes() throws Exception {
+ ThrowsIOException instance = (ThrowsIOException) Proxy.newProxyInstance(loader,
+ new Class[] {ThrowsIOException.class, ThrowsEOFExceptionReturnsString.class},
+ throwHandler);
+ try {
+ instance.run(new EOFException());
+ fail();
+ } catch (EOFException expected) {
+ }
+ try {
+ instance.run(new IOException());
+ fail();
+ } catch (IOException expected) {
+ }
+ try {
+ ((ThrowsEOFExceptionReturnsString) instance).run(new EOFException());
+ fail();
+ } catch (EOFException expected) {
+ }
+ try {
+ ((ThrowsEOFExceptionReturnsString) instance).run(new IOException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ }
+
+ public void test_getProxyClass_nullInterfaces() {
+ try {
+ Proxy.getProxyClass(loader, new Class<?>[] { null });
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ Proxy.getProxyClass(loader, Echo.class, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_getProxyClass_duplicateInterfaces() {
+ try {
+ Proxy.getProxyClass(loader, Echo.class, Echo.class);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_getProxyClass_caching() throws Exception {
+ Class<?> proxy1 = Proxy.getProxyClass(loader, Echo.class, ReturnsInt.class);
+ Class<?> proxy2 = Proxy.getProxyClass(loader, Echo.class, ReturnsInt.class);
+ Class<?> proxy3 = Proxy.getProxyClass(loader, ReturnsInt.class, Echo.class);
+
+ assertSame(proxy1, proxy2);
+ assertTrue(!proxy2.equals(proxy3));
+ }
+
+ public void testMethodsImplementedByFarIndirectInterface() {
+ ExtendsExtendsDeclaresFiveMethods instance = (ExtendsExtendsDeclaresFiveMethods)
+ Proxy.newProxyInstance(loader, new Class[]{ExtendsExtendsDeclaresFiveMethods.class},
+ returnHandler);
+ assertEquals("foo", instance.a("foo"));
+ assertEquals(0x12345678, instance.b(0x12345678));
+ assertEquals(Double.MIN_VALUE, instance.c(Double.MIN_VALUE));
+ assertEquals(null, instance.d(null));
+ assertEquals(0x1234567890abcdefL, instance.e(0x1234567890abcdefL));
+ }
+
+ public void testEquals() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ return args[0] == ProxyTest.class; // bogus as equals(), but good for testing
+ }
+ };
+ Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+ assertTrue(instance.equals(ProxyTest.class));
+ assertFalse(instance.equals(new Object()));
+ assertFalse(instance.equals(instance));
+ assertFalse(instance.equals(null));
+ }
+
+ public void testHashCode() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ return 0x12345678;
+ }
+ };
+ Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+ assertEquals(0x12345678, instance.hashCode());
+ }
+
+ public void testToString() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ return "foo";
+ }
+ };
+ Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+ assertEquals("foo", instance.toString());
+ }
+
+ public void testReturnTypeDoesNotSatisfyAllConstraintsWithLenientCaller() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ assertEquals(Object.class, method.getReturnType());
+ return Boolean.TRUE; // not the right type for 'ReturnsString' callers
+ }
+ };
+ ReturnsObject returnsObject = (ReturnsObject) Proxy.newProxyInstance(loader,
+ new Class[] {ReturnsString.class, ReturnsObject.class}, handler);
+ assertEquals(true, returnsObject.foo());
+ }
+
+ public void testReturnTypeDoesNotSatisfyAllConstraintsWithStrictCaller() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ assertEquals(String.class, method.getReturnType());
+ return Boolean.TRUE; // not the right type for 'ReturnsString' callers
+ }
+ };
+ ReturnsString returnsString = (ReturnsString) Proxy.newProxyInstance(loader,
+ new Class[] {ReturnsString.class, ReturnsObject.class}, handler);
+ try {
+ returnsString.foo();
+ fail();
+ } catch (ClassCastException expected) {
+ }
+ }
+
+ public void testReturnsTypeAndInterfaceNotImplementedByThatType() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsEcho.class},
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
public interface Echo {
String echo(String s);
}
+ public interface ReturnsInt {
+ int foo();
+ }
+
+ public interface ReturnsFloat {
+ float foo();
+ }
+
+ public interface ReturnsInteger {
+ Integer foo();
+ }
+
+ public interface ReturnsString {
+ String foo();
+ }
+
+ public interface ReturnsCharSequence {
+ CharSequence foo();
+ }
+
+ public interface ReturnsSerializable {
+ CharSequence foo();
+ }
+
+ public interface ReturnsComparable {
+ CharSequence foo();
+ }
+
+ public interface ReturnsObject {
+ Object foo();
+ }
+
+ public interface ReturnsVoid {
+ void foo();
+ }
+
+ public interface ReturnsEcho {
+ Echo foo();
+ }
+
+ public interface ThrowsIOException {
+ Object run(Throwable toThrow) throws IOException;
+ }
+
+ public interface ThrowsEOFException {
+ Object run(Throwable toThrow) throws EOFException;
+ }
+
+ public interface ThrowsEOFExceptionReturnsString {
+ String run(Throwable toThrow) throws EOFException;
+ }
+
+ public interface ThrowsSocketException {
+ Object run(Throwable toThrow) throws SocketException;
+
+ }
+ public interface ThrowsSocketExceptionAndEOFException {
+ Object run(Throwable toThrow) throws SocketException, EOFException;
+
+ }
+
+ public interface DeclaresFiveMethods {
+ String a(String a);
+ int b(int b);
+ double c(double c);
+ Object d(Object d);
+ long e(long e);
+ }
+ public interface ExtendsDeclaresFiveMethods extends DeclaresFiveMethods {
+ }
+ public interface ExtendsExtendsDeclaresFiveMethods extends ExtendsDeclaresFiveMethods {
+ }
+
public static class TestInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return args[0];
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java b/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java
index cdce405..1950bf3 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java
@@ -24,6 +24,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
+import java.util.AbstractCollection;
+import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -37,6 +39,27 @@ public final class ReflectionTest extends TestCase {
String classB = "libcore.java.lang.reflect.ReflectionTest$B";
String classC = "libcore.java.lang.reflect.ReflectionTest$C";
+ public void testClassGetSuperclass() {
+ assertEquals(AbstractList.class, ArrayList.class.getSuperclass());
+ assertEquals(AbstractCollection.class, AbstractList.class.getSuperclass());
+ assertEquals(AbstractCollection.class, AbstractList.class.getSuperclass());
+ assertEquals(Object.class, AbstractCollection.class.getSuperclass());
+ assertNull(Object.class.getSuperclass());
+ }
+
+ public void testPrimitiveGetSuperclass() {
+ assertNull(boolean.class.getSuperclass());
+ assertNull(int.class.getSuperclass());
+ assertNull(double.class.getSuperclass());
+ assertNull(void.class.getSuperclass());
+ }
+
+ public void testInterfaceGetSuperclass() {
+ assertNull(Comparable.class.getSuperclass());
+ assertNull(DefinesMember.class.getSuperclass());
+ assertNull(ExtendsDefinesMember.class.getSuperclass());
+ }
+
/**
* http://code.google.com/p/android/issues/detail?id=6636
*/
@@ -277,6 +300,36 @@ public final class ReflectionTest extends TestCase {
assertEquals(1, count(names(fields), "field"));
}
+ public void testIsLocalClass() {
+ A methodLevelAnonymous = new A() {};
+ class Local {}
+ class $Local$1 {}
+ assertFalse(ReflectionTest.class.isLocalClass());
+ assertFalse(A.class.isLocalClass());
+ assertFalse($Dollar$1.class.isLocalClass());
+ assertFalse(CLASS_LEVEL_ANONYMOUS.getClass().isLocalClass());
+ assertFalse(methodLevelAnonymous.getClass().isLocalClass());
+ assertTrue(Local.class.isLocalClass());
+ assertTrue($Local$1.class.isLocalClass());
+ assertFalse(int.class.isLocalClass());
+ assertFalse(Object.class.isLocalClass());
+ }
+
+ public void testIsAnonymousClass() {
+ A methodLevelAnonymous = new A() {};
+ class Local {}
+ class $Local$1 {}
+ assertFalse(ReflectionTest.class.isAnonymousClass());
+ assertFalse(A.class.isAnonymousClass());
+ assertFalse($Dollar$1.class.isAnonymousClass());
+ assertTrue(CLASS_LEVEL_ANONYMOUS.getClass().isAnonymousClass());
+ assertTrue(methodLevelAnonymous.getClass().isAnonymousClass());
+ assertFalse(Local.class.isAnonymousClass());
+ assertFalse($Local$1.class.isAnonymousClass());
+ assertFalse(int.class.isAnonymousClass());
+ assertFalse(Object.class.isAnonymousClass());
+ }
+
/**
* Class.isEnum() erroneously returned true for indirect descendants of
* Enum. http://b/1062200.
@@ -299,8 +352,10 @@ public final class ReflectionTest extends TestCase {
assertNull(greenClass.getEnumConstants());
}
+ static class $Dollar$1 {}
static class A {}
static class AList extends ArrayList<A> {}
+ static A CLASS_LEVEL_ANONYMOUS = new A() {};
static class B extends Exception {}
diff --git a/luni/src/test/java/libcore/java/math/BigIntegerTest.java b/luni/src/test/java/libcore/java/math/BigIntegerTest.java
index 15a0dad..58c68a1 100644
--- a/luni/src/test/java/libcore/java/math/BigIntegerTest.java
+++ b/luni/src/test/java/libcore/java/math/BigIntegerTest.java
@@ -156,4 +156,32 @@ public class BigIntegerTest extends junit.framework.TestCase {
assertTrue(b.isProbablePrime(100));
}
}
+
+ public void test_negativeValues_superfluousZeros() throws Exception {
+ byte[] trimmedBytes = new byte[] {
+ (byte) 0xae, (byte) 0x0f, (byte) 0xa1, (byte) 0x93
+ };
+ byte[] extraZeroesBytes = new byte[] {
+ (byte) 0xff, (byte) 0xae, (byte) 0x0f, (byte) 0xa1, (byte) 0x93
+ };
+
+ BigInteger trimmed = new BigInteger(trimmedBytes);
+ BigInteger extraZeroes = new BigInteger(extraZeroesBytes);
+
+ assertEquals(trimmed, extraZeroes);
+ }
+
+ public void test_positiveValues_superfluousZeros() throws Exception {
+ byte[] trimmedBytes = new byte[] {
+ (byte) 0x2e, (byte) 0x0f, (byte) 0xa1, (byte) 0x93
+ };
+ byte[] extraZeroesBytes = new byte[] {
+ (byte) 0x00, (byte) 0x2e, (byte) 0x0f, (byte) 0xa1, (byte) 0x93
+ };
+
+ BigInteger trimmed = new BigInteger(trimmedBytes);
+ BigInteger extraZeroes = new BigInteger(extraZeroesBytes);
+
+ assertEquals(trimmed, extraZeroes);
+ }
}
diff --git a/luni/src/test/java/libcore/java/math/CSVTest.java b/luni/src/test/java/libcore/java/math/CSVTest.java
new file mode 100644
index 0000000..9e151c3
--- /dev/null
+++ b/luni/src/test/java/libcore/java/math/CSVTest.java
@@ -0,0 +1,88 @@
+package libcore.java.math;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Standard single-input test framework for csv math tests
+ */
+public abstract class CSVTest extends junit.framework.TestCase {
+ /*
+ * csv file should have the following format:
+ * function,expected_output,input,extra_info
+ * e.g. cos,-0x1.0000000000000p+0,0x1.921fb54442d18p+1,cos(pi)
+ * for two input: function,expected_output,input1,input2,extra
+ * vogar classpath: obj/JAVA_LIBRARIES/core-tests-support_intermediates/javalib.jar
+ */
+
+ /**
+ * This is a set of functions in java.Math/StrictMath that take two inputs.
+ * These functions will call run2InputTest; others will call runTest.
+ */
+ protected static final Set<String> twoInputFunctions;
+ static {
+ Set<String> twoInFunc = new HashSet<String>();
+ twoInFunc.add("atan2");
+ twoInFunc.add("copySign");
+ twoInFunc.add("hypot");
+ twoInFunc.add("IEEEremainder");
+ twoInFunc.add("max");
+ twoInFunc.add("min");
+ twoInFunc.add("nextAfter");
+ twoInFunc.add("pow");
+ twoInFunc.add("scalb");
+ twoInputFunctions = Collections.unmodifiableSet(twoInFunc);
+ }
+
+ void TestCSVInputs(String[] csvFileNames) throws Exception {
+ int totalTests = 0;
+ for (String csvFileName : csvFileNames) {
+ String line = "";
+ BufferedReader br = null;
+
+ try {
+ br = new BufferedReader(new InputStreamReader(
+ getClass().getResourceAsStream(csvFileName)));
+ while ((line = br.readLine()) != null) {
+ if (line.charAt(0) != '#') {
+ String[] testCase = line.split(",");
+ runTest(testCase);
+ totalTests++;
+ }
+ }
+ } finally {
+ if (br != null) {
+ br.close();
+ }
+ }
+ }
+ System.out.println("Completed running " + totalTests + " tests");
+ }
+
+ protected void runTest(String[] testCase) throws Exception {
+ String function = testCase[0];
+ double expectedOutput = Double.parseDouble(testCase[1]);
+ double input = Double.parseDouble(testCase[2]);
+ String extra = "";
+ if (twoInputFunctions.contains(function)) {
+ double input2 = Double.parseDouble(testCase[3]);
+ if (testCase.length > 4) {
+ extra = testCase[4];
+ }
+ run2InputTest(function, expectedOutput, input, input2, extra);
+ } else {
+ if (testCase.length > 3) {
+ extra = testCase[3];
+ }
+ runTest(function, expectedOutput, input, extra);
+ }
+ }
+
+ abstract void runTest(String func, double expectedOutput, double input,
+ String extra) throws Exception;
+
+ abstract void run2InputTest(String func, double expectedOutput, double input1, double input2, String extra) throws Exception;
+} \ No newline at end of file
diff --git a/luni/src/test/java/libcore/java/math/OldBigDecimalConvertTest.java b/luni/src/test/java/libcore/java/math/OldBigDecimalConvertTest.java
index 8f01a17..4823798 100644
--- a/luni/src/test/java/libcore/java/math/OldBigDecimalConvertTest.java
+++ b/luni/src/test/java/libcore/java/math/OldBigDecimalConvertTest.java
@@ -251,10 +251,6 @@ public class OldBigDecimalConvertTest extends TestCase {
assertTrue("incorrect byteValue", i == bNumber);
}
- /**
- * @test java.math.BigDecimal#byteValue() Convert negative BigDesimal to
- * byte type
- */
public void test_ByteValueNeg() {
String sNumber = "-127.56789";
int iNumber = -128;
diff --git a/luni/src/test/java/libcore/java/math/RunCSVTests.java b/luni/src/test/java/libcore/java/math/RunCSVTests.java
new file mode 100644
index 0000000..0c107f1
--- /dev/null
+++ b/luni/src/test/java/libcore/java/math/RunCSVTests.java
@@ -0,0 +1,109 @@
+package libcore.java.math;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests functions in java.lang.Math
+ * Looks for the filenames in csvFileNames in tests/resources
+ * Tests functions and numbers found in those files.
+ * Run: vogar --classpath out/target/common/obj/JAVA_LIBRARIES/core-tests-support_intermediates/javalib.jar
+ * libcore/luni/src/test/java/libcore/java/math/RunCSVTests.java
+ */
+public class RunCSVTests extends CSVTest {
+ /** Stores ulps of error allowed for each function, if not 1 ulp.*/
+ private static final Map<String, Double> UlpMap;
+ static {
+ final HashMap<String, Double> funcUlps = new HashMap<String, Double>();
+ funcUlps.put("sinh", 2.5);
+ funcUlps.put("cosh", 2.5);
+ funcUlps.put("tanh", 2.5);
+ funcUlps.put("abs", 0.0);
+ funcUlps.put("signum", 0.0);
+ funcUlps.put("getExponent", 0.0);
+ funcUlps.put("toRadians", 0.0);
+ funcUlps.put("toDegrees", 0.0);
+ funcUlps.put("sqrt", 0.0);
+ funcUlps.put("ceil", 0.0);
+ funcUlps.put("floor", 0.0);
+ funcUlps.put("rint", 0.0);
+ funcUlps.put("atan2", 2.0);
+ funcUlps.put("round", 0.0);
+ funcUlps.put("max", 0.0);
+ funcUlps.put("min", 0.0);
+ funcUlps.put("copySign", 0.0);
+ funcUlps.put("nextAfter", 0.0);
+ funcUlps.put("scalb", 0.0);
+ UlpMap = Collections.unmodifiableMap(funcUlps);
+ }
+
+ public static final String[] csvFileNames = { "/math_tests.csv",
+ "/math_important_numbers.csv", "/math_java_only.csv" };
+
+ public void test_csv() throws Exception {
+ this.TestCSVInputs(csvFileNames);
+ }
+
+ /**
+ * Runs a standard single-input test using assertEquals.
+ * Allows error based on UlpMap, but defaults to 1 ulp.
+ */
+ @Override
+ void runTest(String func, double expectedOutput, double input, String extra)
+ throws Exception {
+ Class<Math> mathClass = Math.class;
+ Method m = mathClass.getMethod(func, new Class[] { Double.TYPE });
+ Object returnValue = m.invoke(null, input);
+
+ double allowedError;
+ if (UlpMap.containsKey(func)) {
+ allowedError = UlpMap.get(func)*Math.ulp(expectedOutput);
+ } else {
+ allowedError = Math.ulp(expectedOutput);
+ }
+
+ try {
+ assertEquals(extra + ": " + m + ": " + input + ": ", expectedOutput,
+ (double) returnValue, allowedError);
+ } catch (ClassCastException e) {
+ assertEquals(extra + ": " + m + ": " + input + ": ", (int) expectedOutput,
+ (int) returnValue, allowedError);
+ }
+ }
+
+ /**
+ * Runs a 2-input test using assertEquals.
+ * Allows error based on UlpMap, but defaults to 1 ulp.
+ */
+ @Override
+ void run2InputTest(String func, double expectedOutput, double input1,
+ double input2, String extra) throws Exception {
+ Class<Math> mathClass = Math.class;
+ Method m;
+ Object returnValue;
+ if (func.equals("scalb")) {
+ m = mathClass.getMethod(func, new Class[] { Double.TYPE, Integer.TYPE });
+ returnValue = m.invoke(null, input1, (int) input2);
+ } else {
+ m = mathClass.getMethod(func, new Class[] { Double.TYPE, Double.TYPE });
+ returnValue = m.invoke(null, input1, input2);
+ }
+
+ double allowedError;
+ if (UlpMap.containsKey(func)) {
+ allowedError = UlpMap.get(func)*Math.ulp(expectedOutput);
+ } else {
+ allowedError = Math.ulp(expectedOutput);
+ }
+
+ try {
+ assertEquals(extra + ": " + m + ": ", expectedOutput, (double) returnValue,
+ allowedError);
+ } catch (ClassCastException e) {
+ assertEquals(extra + ": " + m + ": ", (int) expectedOutput, (int) returnValue,
+ allowedError);
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java b/luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java
new file mode 100644
index 0000000..0443eb0
--- /dev/null
+++ b/luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java
@@ -0,0 +1,62 @@
+package libcore.java.math;
+
+import java.lang.reflect.Method;
+
+/**
+ * Tests java.lang.StrictMath
+ * Looks for the filenames in csvFileNames in tests/resources
+ * Tests functions and numbers found in those files.
+ * Run: vogar --classpath out/target/common/obj/JAVA_LIBRARIES/core-tests-support_intermediates/javalib.jar
+ * libcore/luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java
+ */
+public class RunCSVTestsStrict extends CSVTest {
+ public static final String[] csvFileNames = { "/math_tests.csv",
+ "/math_important_numbers.csv", "/math_java_only.csv" };
+
+ public void test_csv() throws Exception {
+ this.TestCSVInputs(csvFileNames);
+ }
+
+ /**
+ * Runs single-input test using assertEquals.
+ */
+ @Override
+ void runTest(String func, double expectedOutput, double input, String extra)
+ throws Exception {
+ Class<StrictMath> mathClass = StrictMath.class;
+ Method m = mathClass.getMethod(func, new Class[] { Double.TYPE });
+ Object returnValue = m.invoke(null, input);
+
+ try {
+ assertEquals(extra + ": " + m + ": " + input + ": ", expectedOutput,
+ (double) returnValue, 0D);
+ } catch (ClassCastException e) {
+ assertEquals(extra + ": " + m + ": " + input + ": ", (int) expectedOutput,
+ (int) returnValue, 0D);
+ }
+ }
+
+ /**
+ * Runs 2-input test using assertEquals.
+ */
+ @Override
+ void run2InputTest(String func, double expectedOutput, double input1,
+ double input2, String extra) throws Exception {
+ Class<StrictMath> mathClass = StrictMath.class;
+ Method m;
+ Object returnValue;
+ if (func.equals("scalb")) {
+ m = mathClass.getMethod(func, new Class[] { Double.TYPE, Integer.TYPE });
+ returnValue = m.invoke(null, input1, (int) input2);
+ } else {
+ m = mathClass.getMethod(func, new Class[] { Double.TYPE, Double.TYPE });
+ returnValue = m.invoke(null, input1, input2);
+ }
+
+ try {
+ assertEquals(extra + ": " + m + ": " , expectedOutput, (double) returnValue, 0D);
+ } catch (ClassCastException e) {
+ assertEquals(extra + ": " + m + ": ", (int) expectedOutput, (int) returnValue, 0D);
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/net/DatagramSocketTest.java b/luni/src/test/java/libcore/java/net/DatagramSocketTest.java
new file mode 100644
index 0000000..86e47ec
--- /dev/null
+++ b/luni/src/test/java/libcore/java/net/DatagramSocketTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.net;
+
+import junit.framework.TestCase;
+
+import java.net.DatagramSocket;
+import java.net.InetSocketAddress;
+
+public class DatagramSocketTest extends TestCase {
+
+ public void testInitialState() throws Exception {
+ DatagramSocket ds = new DatagramSocket();
+ try {
+ assertTrue(ds.isBound());
+ assertTrue(ds.getBroadcast()); // The RI starts DatagramSocket in broadcast mode.
+ assertFalse(ds.isClosed());
+ assertFalse(ds.isConnected());
+ assertTrue(ds.getLocalPort() > 0);
+ assertTrue(ds.getLocalAddress().isAnyLocalAddress());
+ InetSocketAddress socketAddress = (InetSocketAddress) ds.getLocalSocketAddress();
+ assertEquals(ds.getLocalPort(), socketAddress.getPort());
+ assertEquals(ds.getLocalAddress(), socketAddress.getAddress());
+ assertNull(ds.getInetAddress());
+ assertEquals(-1, ds.getPort());
+ assertNull(ds.getRemoteSocketAddress());
+ assertFalse(ds.getReuseAddress());
+ assertNull(ds.getChannel());
+ } finally {
+ ds.close();
+ }
+ }
+
+ public void testStateAfterClose() throws Exception {
+ DatagramSocket ds = new DatagramSocket();
+ ds.close();
+ assertTrue(ds.isBound());
+ assertTrue(ds.isClosed());
+ assertFalse(ds.isConnected());
+ assertNull(ds.getLocalAddress());
+ assertEquals(-1, ds.getLocalPort());
+ assertNull(ds.getLocalSocketAddress());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/net/InetAddressTest.java b/luni/src/test/java/libcore/java/net/InetAddressTest.java
index c7617ab..4b656cc 100644
--- a/luni/src/test/java/libcore/java/net/InetAddressTest.java
+++ b/luni/src/test/java/libcore/java/net/InetAddressTest.java
@@ -49,13 +49,16 @@ public class InetAddressTest extends junit.framework.TestCase {
"1234",
"0", // Single out the deprecated form of the ANY address.
- // Hex.
+ // Hex. Not supported by Android but supported by the RI.
"0x1.0x2.0x3.0x4",
"0x7f.0x00.0x00.0x01",
"7f.0.0.1",
- // Octal.
- "0177.00.00.01", // Historically, this would have been interpreted as 127.0.0.1.
+ // Octal. Not supported by Android but supported by the RI. In the RI, if any of the numbers
+ // cannot be treated as a decimal the entire IP is interpreted differently, leading to
+ // "0177.00.00.01" -> 177.0.0.1, but "0177.0x0.00.01" -> 127.0.0.1.
+ // Android does not do this.
+ "0256.00.00.01", // Historically, this could have been interpreted as 174.0.0.1.
// Negative numbers.
"-1.0.0.1",
@@ -89,6 +92,9 @@ public class InetAddressTest extends junit.framework.TestCase {
} catch (IllegalArgumentException expected) {
}
+ // Android does not recognize Octal (leading 0) cases: they are treated as decimal.
+ assertEquals("/177.0.0.1", InetAddress.parseNumericAddress("0177.00.00.01").toString());
+
for (String invalid : INVALID_IPv4_NUMERIC_ADDRESSES) {
try {
InetAddress.parseNumericAddress(invalid);
@@ -121,6 +127,9 @@ public class InetAddressTest extends junit.framework.TestCase {
// Negative test
assertFalse(InetAddress.isNumeric("example.com"));
+ // Android does not handle Octal (leading 0) cases: they are treated as decimal.
+ assertTrue(InetAddress.isNumeric("0177.00.00.01")); // Interpreted as 177.0.0.1
+
for (String invalid : INVALID_IPv4_NUMERIC_ADDRESSES) {
assertFalse(invalid, InetAddress.isNumeric(invalid));
}
diff --git a/luni/src/test/java/libcore/java/net/InetSocketAddressTest.java b/luni/src/test/java/libcore/java/net/InetSocketAddressTest.java
index 1cbcd1a..3bca8dc 100644
--- a/luni/src/test/java/libcore/java/net/InetSocketAddressTest.java
+++ b/luni/src/test/java/libcore/java/net/InetSocketAddressTest.java
@@ -140,13 +140,14 @@ public class InetSocketAddressTest extends TestCase {
InetSocketAddress isa1 = new InetSocketAddress("localhost", 80);
assertFalse(isa1.isUnresolved());
- InetSocketAddress sockAddr = new InetSocketAddress("unknown.host", 1000);
+ InetSocketAddress sockAddr = new InetSocketAddress("unknown.host.google.com", 1000);
assertTrue(sockAddr.isUnresolved());
}
public void test_getHostString() throws Exception {
// When we have a hostname, we'll get it back because that doesn't cost a DNS lookup...
InetSocketAddress hasHostname = InetSocketAddress.createUnresolved("some host", 1234);
+ assertTrue(hasHostname.isUnresolved());
assertEquals("some host", hasHostname.getHostString());
assertEquals("some host", hasHostname.getHostName());
// When we don't have a hostname, whether or not we do the reverse lookup is the difference
diff --git a/luni/src/test/java/libcore/java/net/OldCookieHandlerTest.java b/luni/src/test/java/libcore/java/net/OldCookieHandlerTest.java
index 249c326..0e11d50 100644
--- a/luni/src/test/java/libcore/java/net/OldCookieHandlerTest.java
+++ b/luni/src/test/java/libcore/java/net/OldCookieHandlerTest.java
@@ -16,6 +16,9 @@
package libcore.java.net;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+
import java.io.IOException;
import java.net.CookieHandler;
import java.net.URI;
@@ -27,65 +30,57 @@ import tests.support.Support_Configuration;
public class OldCookieHandlerTest extends TestCase {
- URI getURI, putURI;
- String link = "http://" + Support_Configuration.SpecialInetTestAddress + "/";
- boolean isGetCalled = false;
- boolean isPutCalled = false;
- boolean completedSuccessfully = false;
-
public void test_CookieHandler() {
assertNull(CookieHandler.getDefault());
}
- public void test_get_put() {
+ public void test_get_put() throws Exception {
MockCookieHandler mch = new MockCookieHandler();
CookieHandler defaultHandler = CookieHandler.getDefault();
- CookieHandler.setDefault(mch);
-
- class TestThread extends Thread {
- public void run() {
- try {
- URL url = new URL(link);
- URLConnection conn = url.openConnection();
- conn.getContent();
- url = new URL(link);
- conn = url.openConnection();
- conn.getContent();
- completedSuccessfully = true;
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
try {
- TestThread thread = new TestThread();
+ CookieHandler.setDefault(mch);
- thread.start();
- try {
- thread.join();
- } catch (InterruptedException e) {
- fail("InterruptedException was thrown.");
- }
+ MockWebServer server = new MockWebServer();
+ server.play();
+ server.enqueue(new MockResponse().addHeader("Set-Cookie2: a=\"android\"; "
+ + "Comment=\"this cookie is delicious\"; "
+ + "CommentURL=\"http://google.com/\"; "
+ + "Discard; "
+ + "Domain=\"" + server.getCookieDomain() + "\"; "
+ + "Max-Age=\"60\"; "
+ + "Path=\"/path\"; "
+ + "Port=\"80,443," + server.getPort() + "\"; "
+ + "Secure; "
+ + "Version=\"1\""));
- assertTrue(isGetCalled);
- assertTrue(isPutCalled);
- assertTrue(completedSuccessfully);
+ URLConnection connection = server.getUrl("/path/foo").openConnection();
+ connection.getContent();
+
+ assertTrue(mch.wasGetCalled());
+ assertTrue(mch.wasPutCalled());
} finally {
CookieHandler.setDefault(defaultHandler);
}
}
- class MockCookieHandler extends CookieHandler {
+ private static class MockCookieHandler extends CookieHandler {
+ private boolean getCalled = false;
+ private boolean putCalled = false;
public Map get(URI uri, Map requestHeaders) throws IOException {
- getURI = uri;
- isGetCalled = true;
+ getCalled = true;
return requestHeaders;
}
public void put(URI uri, Map responseHeaders) throws IOException {
- putURI = uri;
- isPutCalled = true;
+ putCalled = true;
+ }
+
+ public boolean wasGetCalled() {
+ return getCalled;
+ }
+ public boolean wasPutCalled() {
+ return putCalled;
}
}
}
diff --git a/luni/src/test/java/libcore/java/net/OldDatagramSocketTest.java b/luni/src/test/java/libcore/java/net/OldDatagramSocketTest.java
deleted file mode 100644
index d51d461..0000000
--- a/luni/src/test/java/libcore/java/net/OldDatagramSocketTest.java
+++ /dev/null
@@ -1,2183 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.net;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.BindException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.DatagramSocketImpl;
-import java.net.DatagramSocketImplFactory;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.PortUnreachableException;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.net.UnknownHostException;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.IllegalBlockingModeException;
-import java.util.Date;
-import java.util.Vector;
-import tests.support.Support_Configuration;
-import tests.support.Support_PortManager;
-
-public class OldDatagramSocketTest extends junit.framework./*Socket*/TestCase {
-
- java.net.DatagramSocket ds;
-
- java.net.DatagramPacket dp;
-
- DatagramSocket sds = null;
-
- String retval;
-
- String testString = "Test String";
-
- boolean interrupted;
-
- class DatagramServer extends Thread {
-
- public DatagramSocket ms;
-
- boolean running = true;
-
- public volatile byte[] rbuf = new byte[512];
-
- volatile DatagramPacket rdp = null;
-
- public void run() {
- try {
- while (running) {
- try {
- ms.receive(rdp);
- // echo the packet back
- ms.send(rdp);
- } catch (java.io.InterruptedIOException e) {
- Thread.yield();
- }
- ;
- }
- ;
- } catch (java.io.IOException e) {
- System.out.println("DatagramServer server failed: " + e);
- } finally {
- ms.close();
- }
- }
-
- public void stopServer() {
- running = false;
- }
-
- public DatagramServer(int aPort, InetAddress address)
- throws java.io.IOException {
- rbuf = new byte[512];
- rbuf[0] = -1;
- rdp = new DatagramPacket(rbuf, rbuf.length);
- ms = new DatagramSocket(aPort, address);
- ms.setSoTimeout(2000);
- }
- }
-
- public void test_Constructor() {
- // Test for method java.net.DatagramSocket()
- try {
- ds = new java.net.DatagramSocket();
- } catch (Exception e) {
- fail("Could not create DatagramSocket : " + e.getMessage());
- }
-
- /*
- SecurityManager sm = new SecurityManager() {
-
- public void checkPermission(Permission perm) {
- }
-
- public void checkListen(int port) {
- throw new SecurityException();
- }
- };
-
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- new DatagramSocket();
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } finally {
- System.setSecurityManager(oldSm);
- }
- */
- }
-
- public void test_ConstructorI() {
- // Test for method java.net.DatagramSocket(int)
- try {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(portNumber);
- assertTrue("Created socket with incorrect port",
- ds.getLocalPort() == portNumber);
- } catch (Exception e) {
- fail("Could not create DatagramSocket : " + e.getMessage());
- }
-
- /*
- SecurityManager sm = new SecurityManager() {
-
- public void checkPermission(Permission perm) {
- }
-
- public void checkListen(int port) {
- throw new SecurityException();
- }
- };
-
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- new DatagramSocket(8080);
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } finally {
- System.setSecurityManager(oldSm);
- }
- */
-
- try {
- DatagramSocket ds = new java.net.DatagramSocket(1);
- if (!("root".equals(System.getProperty("user.name")))) {
- fail("SocketException was not thrown.");
- }
- } catch (SocketException e) {
- //expected
- }
-
- }
-
- public void test_ConstructorILjava_net_InetAddress() {
- // Test for method java.net.DatagramSocket(int, java.net.InetAddress)
- try {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(portNumber, InetAddress
- .getLocalHost());
- assertTrue("Created socket with incorrect port",
- ds.getLocalPort() == portNumber);
- assertTrue("Created socket with incorrect address", ds
- .getLocalAddress().equals(InetAddress.getLocalHost()));
- } catch (Exception e) {
- fail("Could not create DatagramSocket : " + e.getMessage());
- }
-
- /*
- SecurityManager sm = new SecurityManager() {
-
- public void checkPermission(Permission perm) {
- }
-
- public void checkListen(int port) {
- throw new SecurityException();
- }
- };
-
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- new java.net.DatagramSocket(8080, InetAddress
- .getLocalHost());
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } catch (UnknownHostException e) {
- fail("UnknownHostException was thrown.");
- } finally {
- System.setSecurityManager(oldSm);
- }
- */
-
- try {
- new java.net.DatagramSocket(1, InetAddress
- .getLocalHost());
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- } catch (UnknownHostException e) {
- fail("UnknownHostException was thrown.");
- }
- }
-
- public void test_close() {
- // Test for method void java.net.DatagramSocket.close()
- try {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(portNumber);
- dp = new DatagramPacket("Test String".getBytes(), 11, InetAddress
- .getLocalHost(), 0);
- ds.close();
- try {
- ds.send(dp);
- fail("IOException was not thrown.");
- } catch(IOException ioe) {
- //expected
- }
- } catch (Exception e) {
- fail("Unexpected exception: " + e.getMessage());
- }
- }
-
- public void test_connectLjava_net_InetAddressI() throws
- UnknownHostException, SocketException {
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- assertTrue("Incorrect InetAddress", ds.getInetAddress().equals(
- inetAddress));
- assertTrue("Incorrect Port", ds.getPort() == portNumber);
- ds.disconnect();
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
-
- System.out
- .println("Running test_connectLjava_net_InetAddressI" +
- "(DatagramSocketTest) with IPv6GlobalAddressJcl4: "
- + Support_Configuration.IPv6GlobalAddressJcl4);
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress
- .getByName(Support_Configuration.IPv6GlobalAddressJcl4);
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- assertTrue("Incorrect InetAddress", ds.getInetAddress().equals(
- inetAddress));
- assertTrue("Incorrect Port", ds.getPort() == portNumber);
- ds.disconnect();
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
-
- try {
- // Create a connected datagram socket to test
- // PlainDatagramSocketImpl.peek()
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket();
- int port = ds.getLocalPort();
- ds.connect(localHost, port);
- DatagramPacket send = new DatagramPacket(new byte[10], 10,
- localHost, port);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue("Wrong size: " + receive.getLength(), receive
- .getLength() == 10);
- assertTrue("Wrong receiver", receive.getAddress().equals(localHost));
- } catch (IOException e) {
- fail("Unexpected IOException : " + e.getMessage());
- }
-
- class DatagramServer extends Thread {
-
- public DatagramSocket ms;
-
- boolean running = true;
-
- public byte[] rbuf = new byte[512];
-
- DatagramPacket rdp = null;
-
- public void run() {
- try {
- while (running) {
- try {
- ms.receive(rdp);
- // echo the packet back
- ms.send(rdp);
- } catch (java.io.InterruptedIOException e) {
- Thread.yield();
- }
-
- }
-
- } catch (java.io.IOException e) {
- System.out.println("Multicast server failed: " + e);
- } finally {
- ms.close();
- }
- }
-
- public void stopServer() {
- running = false;
- }
-
- public DatagramServer(int aPort, InetAddress address)
- throws java.io.IOException {
- rbuf = new byte[512];
- rbuf[0] = -1;
- rdp = new DatagramPacket(rbuf, rbuf.length);
- ms = new DatagramSocket(aPort, address);
- ms.setSoTimeout(2000);
- }
- }
-
- // validate that we get the PortUnreachable exception if we try to
- // send a dgram to a server that is not running and then do a recv
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- DatagramPacket send = new DatagramPacket(new byte[10], 10);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(10000);
- ds.receive(receive);
- ds.close();
- fail(
- "No PortUnreachableException when connected at native level on recv ");
- } catch (Exception e) {
- assertTrue(
- "Wrong exception when trying to connect at native level on recv: "
- + e.toString(),
- (e instanceof PortUnreachableException));
- }
-
- // validate that we can send/receive with datagram sockets connected at
- // the native level
- DatagramServer server = null;
- int[] ports = Support_PortManager.getNextPortsForUDP(3);
- int serverPortNumber = ports[0];
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket(ports[1]);
- DatagramSocket ds2 = new DatagramSocket(ports[2]);
-
- try {
- server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
- } catch (Exception e) {
- fail(
- "Failed to set up datagram server for native connected Dgram socket test ");
- }
-
- int port = ds.getLocalPort();
- ds.connect(localHost, serverPortNumber);
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue("Wrong size data received: " + receive.getLength(),
- receive.getLength() == sendBytes.length);
- assertTrue("Wrong data received"
- + new String(receive.getData(), 0, receive.getLength())
- + ":" + new String(sendBytes), new String(
- receive.getData(), 0, receive.getLength())
- .equals(new String(sendBytes)));
- assertTrue("Wrong receiver:" + receive.getAddress() + ":"
- + localHost, receive.getAddress().equals(localHost));
- } catch (Exception e) {
- fail(
- "Unexpected exception when sending data on dgram connected at native level:"
- + e.toString());
- }
-
- if (server != null) {
- server.stopServer();
- }
-
- // validate that we can disconnect
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- ds.disconnect();
- ds.close();
- } catch (Exception e) {
- assertTrue("Unexpected exception when trying to connect at native"
- + e.toString(), (e instanceof PortUnreachableException));
- }
-
- // validate that once connected we cannot send to another address
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- DatagramPacket send = new DatagramPacket(new byte[10], 10,
- inetAddress, portNumber + 1);
- ds.send(send);
- ds.close();
- fail(
- "No Exception when trying to send to a different address on a connected socket ");
- } catch (Exception e) {
- assertTrue(
- "Wrong exception when trying to send to a different address on a connected socket: "
- + e.toString(),
- (e instanceof IllegalArgumentException));
- }
-
- // validate that we can connect, then disconnect, then connect then
- // send/recv
- server = null;
- ports = Support_PortManager.getNextPortsForUDP(3);
- serverPortNumber = ports[0];
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket(ports[1]);
- DatagramSocket ds2 = new DatagramSocket(ports[2]);
-
- try {
- server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
- } catch (Exception e) {
- fail(
- "Failed to set up datagram server for native connected Dgram socket test ");
- }
-
- int port = ds.getLocalPort();
- ds.connect(localHost, serverPortNumber + 1);
- ds.disconnect();
- ds.connect(localHost, serverPortNumber);
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue(
- "connect/disconnect/connect - Wrong size data received: "
- + receive.getLength(),
- receive.getLength() == sendBytes.length);
- assertTrue("connect/disconnect/connect - Wrong data received"
- + new String(receive.getData(), 0, receive.getLength())
- + ":" + new String(sendBytes), new String(
- receive.getData(), 0, receive.getLength())
- .equals(new String(sendBytes)));
- assertTrue("connect/disconnect/connect - Wrong receiver:"
- + receive.getAddress() + ":" + localHost, receive
- .getAddress().equals(localHost));
- } catch (Exception e) {
- fail(
- "Unexpected exception when sending data on dgram connected at native level after connect/disconnect/connect:"
- + e.toString());
- }
-
- if (server != null) {
- server.stopServer();
- }
-
- // validate that we can connect/disconnect then send/recv to any address
- server = null;
- ports = Support_PortManager.getNextPortsForUDP(3);
- serverPortNumber = ports[0];
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket(ports[1]);
- DatagramSocket ds2 = new DatagramSocket(ports[2]);
-
- try {
- server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
- } catch (Exception e) {
- fail(
- "Failed to set up datagram server for native connected Dgram socket test ");
- }
-
- int port = ds.getLocalPort();
- ds.connect(localHost, serverPortNumber + 1);
- ds.disconnect();
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length, localHost, serverPortNumber);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue("connect/disconnect - Wrong size data received: "
- + receive.getLength(),
- receive.getLength() == sendBytes.length);
- assertTrue("connect/disconnect - Wrong data received"
- + new String(receive.getData(), 0, receive.getLength())
- + ":" + new String(sendBytes), new String(
- receive.getData(), 0, receive.getLength())
- .equals(new String(sendBytes)));
- assertTrue("connect/disconnect - Wrong receiver:"
- + receive.getAddress() + ":" + localHost, receive
- .getAddress().equals(localHost));
- } catch (Exception e) {
- fail(
- "Unexpected exception when sending data on dgram connected at native level after connect/disconnect:"
- + e.toString());
- }
-
- if (server != null) {
- server.stopServer();
- }
-
- // validate that we can connect on an allready connected socket and then
- // send/recv
- server = null;
- ports = Support_PortManager.getNextPortsForUDP(3);
- serverPortNumber = ports[0];
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket(ports[1]);
- DatagramSocket ds2 = new DatagramSocket(ports[2]);
-
- try {
- server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
- } catch (Exception e) {
- fail(
- "Failed to set up datagram server for native connected Dgram socket test ");
- }
-
- int port = ds.getLocalPort();
- ds.connect(localHost, serverPortNumber + 1);
- ds.connect(localHost, serverPortNumber);
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue("connect/connect - Wrong size data received: "
- + receive.getLength(),
- receive.getLength() == sendBytes.length);
- assertTrue("connect/connect - Wrong data received"
- + new String(receive.getData(), 0, receive.getLength())
- + ":" + new String(sendBytes), new String(
- receive.getData(), 0, receive.getLength())
- .equals(new String(sendBytes)));
- assertTrue("connect/connect - Wrong receiver:"
- + receive.getAddress() + ":" + localHost, receive
- .getAddress().equals(localHost));
- } catch (Exception e) {
- fail(
- "Unexpected exception when sending data on dgram connected at native level after connect/connect: "
- + e.toString());
- }
-
- if (server != null) {
- server.stopServer();
- }
-
- // test for when we fail to connect at the native level. Even though we
- // fail at the native level there is no way to return an exception so
- // there should be no exception
- try {
- ds = new java.net.DatagramSocket();
- byte[] addressBytes = { 0, 0, 0, 0 };
- InetAddress inetAddress = InetAddress.getByAddress(addressBytes);
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- } catch (Exception e) {
- fail(
- "Unexcpected exception when trying to connect at native level with bad address for signature with no exception to be returned: "
- + e.toString());
- }
-
- System.out
- .println("Running test_connectLjava_net_InetAddressI(DatagramSocketTest) with IPv6 address");
- try {
- ds = new java.net.DatagramSocket();
- byte[] addressBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0 };
- InetAddress inetAddress = InetAddress
- .getByAddress(addressBytes);
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- } catch (Exception e) {
- fail(
- "Unexcpected exception when trying to connect at native level with bad IPv6 address for signature with no exception to be returned: "
- + e.toString());
- }
- }
-
- public void test_disconnect() {
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- ds.disconnect();
- assertNull("Incorrect InetAddress", ds.getInetAddress());
- assertEquals("Incorrect Port", -1, ds.getPort());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
-
- System.out
- .println("Running test_disconnect(DatagramSocketTest) with IPv6GlobalAddressJcl4: "
- + Support_Configuration.IPv6GlobalAddressJcl4);
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress
- .getByName(Support_Configuration.IPv6GlobalAddressJcl4);
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(inetAddress, portNumber);
- ds.disconnect();
- assertNull("Incorrect InetAddress", ds.getInetAddress());
- assertEquals("Incorrect Port", -1, ds.getPort());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- }
-
- public void test_getInetAddress() {
- Vector<InetAddress> ias = new Vector<InetAddress>();
- try {
- ias.add(InetAddress.getLocalHost());
- ias.add(InetAddress
- .getByName(Support_Configuration.IPv6GlobalAddressJcl4));
- ias.add(InetAddress
- .getByName(Support_Configuration.InetTestAddress2));
- ias.add(InetAddress
- .getByName(Support_Configuration.InetTestAddress2));
- ias.add(InetAddress
- .getByName(Support_Configuration.InetTestIP));
- } catch(Exception e) {
- fail("Unexpected exception was thrown: " + e.toString());
- }
-
- for(InetAddress ia:ias) {
- int portNumber = Support_PortManager.getNextPortForUDP();
- DatagramSocket ds = null;
- try {
- ds = new DatagramSocket();
- ds.connect(ia, portNumber);
- assertEquals(ia, ds.getInetAddress());
- assertEquals("" + ia, ia, ds.getInetAddress());
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } finally {
- ds.disconnect();
- ds.close();
- }
- }
-
- try {
- assertNull(new DatagramSocket().getInetAddress());
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- }
-
- }
-
- public void test_getLocalPort() {
- // Test for method int java.net.DatagramSocket.getLocalPort()
- try {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(portNumber);
- assertTrue("Returned incorrect port",
- ds.getLocalPort() == portNumber);
- } catch (Exception e) {
- fail("Exception during getLocalAddress : " + e.getMessage());
- }
- }
-
- public void test_getPort() {
- try {
- int portNumber = Support_PortManager.getNextPortForUDP();
- DatagramSocket theSocket = new DatagramSocket(portNumber);
- assertEquals("Expected -1 for remote port as not connected",
- -1, theSocket.getPort());
-
- // now connect the socket and validate that we get the right port
- theSocket.connect(InetAddress.getLocalHost(), portNumber);
- assertTrue("getPort returned wrong value:" + theSocket.getPort()
- + ":Expected:" + portNumber,
- theSocket.getPort() == portNumber);
- } catch (Exception e) {
- fail("unexpected exception during getPort test : " + e.getMessage());
- }
- }
-
- public void test_getReceiveBufferSize() throws Exception {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(portNumber);
- ds.setReceiveBufferSize(130);
- assertTrue("Incorrect buffer size", ds.getReceiveBufferSize() >= 130);
- ds.close();
- try {
- ds.getReceiveBufferSize();
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_getSendBufferSize() throws Exception {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(portNumber);
- ds.setSendBufferSize(134);
- assertTrue("Incorrect buffer size", ds.getSendBufferSize() >= 134);
- ds.close();
- try {
- ds.getSendBufferSize();
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_getSoTimeout_setSoTimeout() throws Exception {
- // TODO: a useful test would check that setSoTimeout actually causes timeouts!
- DatagramSocket s = new DatagramSocket();
- s.setSoTimeout(1500);
- int ms = s.getSoTimeout();
- if (ms < 1500-10 || ms > 1500+10) {
- fail("suspicious timeout: " + ms);
- }
- s.close();
- try {
- s.getSoTimeout();
- fail("SocketException was not thrown.");
- } catch (SocketException expected) {
- }
- try {
- s.setSoTimeout(1000);
- fail("SocketException was not thrown.");
- } catch (SocketException expected) {
- }
- }
-
- public void test_receiveLjava_net_DatagramPacket() throws Exception {
- // Test for method void
- // java.net.DatagramSocket.receive(java.net.DatagramPacket)
-
- receive_oversize_java_net_DatagramPacket();
- final int[] ports = Support_PortManager.getNextPortsForUDP(2);
- final int portNumber = ports[0];
-
- class TestDGRcv implements Runnable {
- public void run() {
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- Thread.sleep(1000);
- DatagramSocket sds = new DatagramSocket(ports[1]);
- sds.send(new DatagramPacket("Test".getBytes("UTF-8"), "Test".length(), localHost, portNumber));
- sds.send(new DatagramPacket("Longer test".getBytes("UTF-8"), "Longer test".length(), localHost, portNumber));
- sds.send(new DatagramPacket("3 Test".getBytes("UTF-8"), "3 Test".length(), localHost, portNumber));
- sds.send(new DatagramPacket("4 Test".getBytes("UTF-8"), "4 Test".length(), localHost, portNumber));
- sds.send(new DatagramPacket("5".getBytes("UTF-8"), "5".length(), localHost, portNumber));
- sds.close();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- try {
- new Thread(new TestDGRcv(), "datagram receiver").start();
- ds = new java.net.DatagramSocket(portNumber);
- ds.setSoTimeout(6000);
- byte[] rbuf = new byte[1000];
- DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
-
- // Receive the first packet.
- ds.receive(rdp);
- assertEquals("Test", new String(rbuf, 0, rdp.getLength()));
- // Check that we can still receive a longer packet (http://code.google.com/p/android/issues/detail?id=24748).
- ds.receive(rdp);
- assertEquals("Longer test", new String(rbuf, 0, rdp.getLength()));
- // See what happens if we manually call DatagramPacket.setLength.
- rdp.setLength(4);
- ds.receive(rdp);
- assertEquals("3 Te", new String(rbuf, 0, rdp.getLength()));
- // And then another.
- ds.receive(rdp);
- assertEquals("4 Te", new String(rbuf, 0, rdp.getLength()));
- // And then a packet shorter than the user-supplied length.
- ds.receive(rdp);
- assertEquals("5", new String(rbuf, 0, rdp.getLength()));
-
- ds.close();
- } finally {
- ds.close();
- }
- DatagramSocket socket = null;
- try {
- byte rbuf[] = new byte[1000];
- DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
- DatagramChannel channel = DatagramChannel.open();
- channel.configureBlocking(false);
- socket = channel.socket();
- socket.receive(rdp);
- fail("IllegalBlockingModeException was not thrown.");
- } catch(IllegalBlockingModeException expected) {
- } finally {
- socket.close();
- }
-
- try {
- ds = new java.net.DatagramSocket(portNumber);
- ds.setSoTimeout(1000);
- byte rbuf[] = new byte[1000];
- DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
- ds.receive(rdp);
- fail("SocketTimeoutException was not thrown.");
- } catch(SocketTimeoutException expected) {
- } finally {
- ds.close();
- }
-
- interrupted = false;
- final DatagramSocket ds = new DatagramSocket();
- ds.setSoTimeout(12000);
- Runnable runnable = new Runnable() {
- public void run() {
- try {
- ds.receive(new DatagramPacket(new byte[1], 1));
- } catch (InterruptedIOException e) {
- interrupted = true;
- } catch (IOException ignored) {
- }
- }
- };
- Thread thread = new Thread(runnable, "DatagramSocket.receive1");
- thread.start();
- do {
- Thread.sleep(500);
- } while (!thread.isAlive());
- ds.close();
- int c = 0;
- do {
- Thread.sleep(500);
- if (interrupted) {
- fail("received interrupt");
- }
- if (++c > 4) {
- fail("read call did not exit");
- }
- } while (thread.isAlive());
-
- interrupted = false;
- final int portNum = ports[0];
- final DatagramSocket ds2 = new DatagramSocket(ports[1]);
- ds2.setSoTimeout(12000);
- Runnable runnable2 = new Runnable() {
- public void run() {
- try {
- ds2.receive(new DatagramPacket(new byte[1], 1,
- InetAddress.getLocalHost(), portNum));
- } catch (InterruptedIOException e) {
- interrupted = true;
- } catch (IOException ignored) {
- }
- }
- };
- Thread thread2 = new Thread(runnable2, "DatagramSocket.receive2");
- thread2.start();
- try {
- do {
- Thread.sleep(500);
- } while (!thread2.isAlive());
- } catch (InterruptedException ignored) {
- }
- ds2.close();
- int c2 = 0;
- do {
- Thread.sleep(500);
- if (interrupted) {
- fail("receive2 was interrupted");
- }
- if (++c2 > 4) {
- fail("read2 call did not exit");
- }
- } while (thread2.isAlive());
-
- interrupted = false;
- DatagramSocket ds3 = new DatagramSocket();
- ds3.setSoTimeout(500);
- Date start = new Date();
- try {
- ds3.receive(new DatagramPacket(new byte[1], 1));
- } catch (InterruptedIOException e) {
- interrupted = true;
- }
- ds3.close();
- assertTrue("receive not interrupted", interrupted);
- int delay = (int) (new Date().getTime() - start.getTime());
- assertTrue("timeout too soon: " + delay, delay >= 490);
- }
-
- public void test_sendLjava_net_DatagramPacket() throws Exception {
- // Test for method void
- // java.net.DatagramSocket.send(java.net.DatagramPacket)
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
- final int portNumber = ports[0];
-
- class TestDGSend implements Runnable {
- Thread pThread;
-
- public TestDGSend(Thread t) {
- pThread = t;
- }
-
- public void run() {
- try {
- byte[] rbuf = new byte[1000];
-
- sds = new DatagramSocket(portNumber);
- DatagramPacket sdp = new DatagramPacket(rbuf, rbuf.length);
- sds.setSoTimeout(6000);
- sds.receive(sdp);
- retval = new String(rbuf, 0, testString.length());
- pThread.interrupt();
- } catch (java.io.InterruptedIOException e) {
- System.out.println("Recv operation timed out");
- pThread.interrupt();
- ds.close();
- } catch (Exception e) {
- System.out.println("Failed to establish Dgram server: " + e);
- }
- }
- }
- try {
- new Thread(new TestDGSend(Thread.currentThread()), "DGServer")
- .start();
- ds = new java.net.DatagramSocket(ports[1]);
- dp = new DatagramPacket(testString.getBytes(), testString.length(),
- InetAddress.getLocalHost(), portNumber);
- // Wait to allow send to occur
- try {
- Thread.sleep(500);
- ds.send(dp);
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- ds.close();
- assertTrue("Incorrect data sent: " + retval, retval
- .equals(testString));
- }
- } catch (Exception e) {
- fail("Exception during send test : " + e.getMessage());
- } finally {
- ds.close();
- }
-
- /*
- SecurityManager sm = new SecurityManager() {
-
- public void checkPermission(Permission perm) {
- }
-
- public void checkMulticast(InetAddress maddr) {
- throw new SecurityException();
- }
-
- public void checkConnect(String host,
- int port) {
- throw new SecurityException();
- }
- };
- try {
-
- ds = new java.net.DatagramSocket(ports[1]);
- dp = new DatagramPacket(testString.getBytes(), testString.length(),
- InetAddress.getLocalHost(), portNumber);
-
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- ds.send(dp);
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } finally {
- System.setSecurityManager(oldSm);
- }
- } catch(Exception e) {
- fail("Unexpected exception was thrown: " + e.getMessage());
- }
- */
-
- DatagramSocket socket = null;
- try {
- byte rbuf[] = new byte[1000];
- DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
- SocketAddress address = new InetSocketAddress(portNumber);
- DatagramChannel channel = DatagramChannel.open();
- channel.configureBlocking(false);
- socket = channel.socket();
- socket.send(rdp);
- fail("IllegalBlockingModeException was not thrown.");
- } catch(IllegalBlockingModeException ibme) {
- //expected
- } catch(IOException ioe) {
- fail("IOException was thrown: " + ioe.getMessage());
- } finally {
- socket.close();
- }
-
- //Regression for HARMONY-1118
- class testDatagramSocket extends DatagramSocket {
- public testDatagramSocket(DatagramSocketImpl impl){
- super(impl);
- }
- }
- class testDatagramSocketImpl extends DatagramSocketImpl {
- protected void create() throws SocketException {}
- protected void bind(int arg0, InetAddress arg1) throws SocketException {}
- protected void send(DatagramPacket arg0) throws IOException {}
- protected int peek(InetAddress arg0) throws IOException {
- return 0;
- }
- protected int peekData(DatagramPacket arg0) throws IOException {
- return 0;
- }
- protected void receive(DatagramPacket arg0) throws IOException {}
- protected void setTTL(byte arg0) throws IOException {}
- protected byte getTTL() throws IOException {
- return 0;
- }
- protected void setTimeToLive(int arg0) throws IOException {}
- protected int getTimeToLive() throws IOException {
- return 0;
- }
- protected void join(InetAddress arg0) throws IOException {}
- protected void leave(InetAddress arg0) throws IOException {}
- protected void joinGroup(SocketAddress arg0, NetworkInterface arg1) throws IOException {}
- protected void leaveGroup(SocketAddress arg0, NetworkInterface arg1) throws IOException {}
- protected void close() {}
- public void setOption(int arg0, Object arg1) throws SocketException {}
- public Object getOption(int arg0) throws SocketException {
- return null;
- }
- }
- InetSocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), 0);
- //no exception expected for next line
- new testDatagramSocket(new testDatagramSocketImpl()).send(new DatagramPacket(new byte[272], 3, sa));
-
- // Regression test for Harmony-2938
- InetAddress i = InetAddress.getByName("127.0.0.1");
- DatagramSocket d = new DatagramSocket(0, i);
- try {
- d.send(new DatagramPacket(new byte[] { 1 }, 1));
- fail("should throw NPE.");
- } catch (NullPointerException e) {
- // expected;
- } finally {
- d.close();
- }
- }
-
- public void test_setSendBufferSizeI() throws Exception {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(portNumber);
- ds.setSendBufferSize(134);
- assertTrue("Incorrect buffer size", ds.getSendBufferSize() >= 134);
- ds.close();
- try {
- ds.setSendBufferSize(1);
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_setReceiveBufferSizeI() throws Exception {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(portNumber);
- ds.setReceiveBufferSize(130);
- assertTrue("Incorrect buffer size", ds.getReceiveBufferSize() >= 130);
-
- try {
- ds.setReceiveBufferSize(0);
- fail("IllegalArgumentException was not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- ds.setReceiveBufferSize(-1);
- fail("IllegalArgumentException was not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- ds.close();
-
- try {
- ds.setReceiveBufferSize(1);
- fail("SocketException was not thrown.");
- } catch (SocketException e) {
- //expected
- }
- }
-
- public void test_ConstructorLjava_net_DatagramSocketImpl() {
- class testDatagramSocket extends DatagramSocket {
- public testDatagramSocket(DatagramSocketImpl impl){
- super(impl);
- }
- }
-
- try {
- new testDatagramSocket((DatagramSocketImpl) null);
- fail("exception expected");
- } catch (NullPointerException ex) {
- //expected
- }
- }
-
- public void test_ConstructorLjava_net_SocketAddress() {
- class mySocketAddress extends SocketAddress {
-
- public mySocketAddress() {
- }
- }
-
- try {
- try {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(new InetSocketAddress(
- InetAddress.getLocalHost(), portNumber));
- assertTrue(ds.getBroadcast());
- assertTrue("Created socket with incorrect port", ds
- .getLocalPort() == portNumber);
- assertTrue("Created socket with incorrect address", ds
- .getLocalAddress().equals(InetAddress.getLocalHost()));
- } catch (Exception e) {
- fail("Could not create DatagramSocket : " + e.getMessage());
- }
-
- try {
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds = new java.net.DatagramSocket(new mySocketAddress());
- fail(
- "No exception when constucting datagramSocket with unsupported SocketAddress type");
- } catch (IllegalArgumentException e) {
-
- }
- //regression for Harmony-894
- ds = new DatagramSocket((SocketAddress)null);
- assertTrue(ds.getBroadcast());
- } catch (Exception ex) {
- fail(
- "unexpected exception when datagramSocket SocketAddress constructor test");
- }
-
- /*
- SecurityManager sm = new SecurityManager() {
-
- public void checkPermission(Permission perm) {
- }
-
- public void checkListen(int port) {
- throw new SecurityException();
- }
- };
-
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- new DatagramSocket(new InetSocketAddress(
- InetAddress.getLocalHost(), 1));
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } catch (UnknownHostException e) {
- fail("UnknownHostException was thrown.");
- } finally {
- System.setSecurityManager(oldSm);
- }
- */
-
- InetSocketAddress isa = null;
- try {
- isa = new InetSocketAddress(
- InetAddress.getLocalHost(), 1);
- } catch (UnknownHostException e) {
- fail("UnknownHostException was thrown.");
- }
- }
-
- public void test_bindLjava_net_SocketAddress() throws Exception {
- int[] ports = Support_PortManager.getNextPortsForUDP(3);
- int serverPortNumber = ports[1];
-
- // now create a socket that is not bound and then bind it
- InetAddress localHost = InetAddress.getLocalHost();
- InetSocketAddress localAddress1 = new InetSocketAddress(localHost, ports[0]);
- DatagramSocket theSocket = new DatagramSocket(localAddress1);
-
- // validate that the localSocketAddress reflects the address we bound to
- assertEquals(localAddress1, theSocket.getLocalSocketAddress());
-
- // now make sure that datagrams sent from this socket appear to come
- // from the address we bound to
- InetSocketAddress localAddress2 = new InetSocketAddress(localHost, ports[2]);
- DatagramSocket ds = new DatagramSocket((SocketAddress) null);
- ds.bind(localAddress2);
-
- DatagramServer server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
-
- ds.connect(new InetSocketAddress(localHost, serverPortNumber));
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes, sendBytes.length);
- ds.send(send);
- Thread.sleep(1000);
- ds.close();
- // Check that the address in the packet matches the bound address.
- assertEquals(localAddress2, server.rdp.getSocketAddress());
-
- if (server != null) {
- server.stopServer();
- }
- }
-
- public void test_bindLjava_net_SocketAddress_null() throws Exception {
- // validate if we pass in null that it picks an address for us.
- DatagramSocket theSocket = new DatagramSocket((SocketAddress) null);
- theSocket.bind(null);
- assertNotNull(theSocket.getLocalSocketAddress());
- theSocket.close();
- }
-
- public void test_bindLjava_net_SocketAddress_bad_address() throws Exception {
- // Address we cannot bind to
- DatagramSocket theSocket = new DatagramSocket((SocketAddress) null);
- try {
- InetAddress badAddress = InetAddress.getByAddress(Support_Configuration.nonLocalAddressBytes);
- theSocket.bind(new InetSocketAddress(badAddress, Support_PortManager.getNextPortForUDP()));
- fail("No exception when binding to bad address");
- } catch (SocketException expected) {
- }
- theSocket.close();
- }
-
- public void test_bindLjava_net_SocketAddress_address_in_use() throws Exception {
- // Address that we have already bound to
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
- DatagramSocket theSocket1 = new DatagramSocket((SocketAddress) null);
- DatagramSocket theSocket2 = new DatagramSocket(ports[0]);
- try {
- InetSocketAddress theAddress = new InetSocketAddress(InetAddress.getLocalHost(), ports[1]);
- theSocket1.bind(theAddress);
- theSocket2.bind(theAddress);
- fail("No exception binding to address that is not available");
- } catch (SocketException expected) {
- }
- theSocket1.close();
- theSocket2.close();
- }
-
- public void test_bindLjava_net_SocketAddress_unsupported_address_type() throws Exception {
- class mySocketAddress extends SocketAddress {
- public mySocketAddress() {
- }
- }
-
- // unsupported SocketAddress subclass
- DatagramSocket theSocket = new DatagramSocket((SocketAddress) null);
- try {
- theSocket.bind(new mySocketAddress());
- fail("No exception when binding using unsupported SocketAddress subclass");
- } catch (IllegalArgumentException expected) {
- }
- theSocket.close();
- }
-
- public void test_connectLjava_net_SocketAddress() {
-
- // validate that we get the PortUnreachable exception if we try to
- // send a dgram to a server that is not running and then do a recv
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(new InetSocketAddress(inetAddress, portNumber));
- DatagramPacket send = new DatagramPacket(new byte[10], 10);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(10000);
- ds.receive(receive);
- ds.close();
- fail(
- "No PortUnreachableException when connected at native level on recv ");
- } catch (Exception e) {
- assertTrue(
- "Wrong exception when trying to connect at native level on recv: "
- + e.toString(),
- (e instanceof PortUnreachableException));
- }
-
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
-
- ds.connect(new InetSocketAddress("asdfasdf", 1));
- ds.close();
- fail("SocketException was not thrown.");
- } catch (Exception e) {
- assertTrue(
- "Wrong exception when trying to connect to unknown host: "
- + e.toString(),
- (e instanceof SocketException));
- }
-
- // validate that we can send/receive with datagram sockets connected at
- // the native level
- DatagramServer server = null;
- int[] ports = Support_PortManager.getNextPortsForUDP(3);
- int serverPortNumber = ports[0];
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket(ports[1]);
- DatagramSocket ds2 = new DatagramSocket(ports[2]);
-
- try {
- server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
- } catch (Exception e) {
- fail(
- "Failed to set up datagram server for native connected Dgram socket test ");
- }
-
- int port = ds.getLocalPort();
- ds.connect(new InetSocketAddress(localHost, serverPortNumber));
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue("Wrong size data received: " + receive.getLength(),
- receive.getLength() == sendBytes.length);
- assertTrue("Wrong data received"
- + new String(receive.getData(), 0, receive.getLength())
- + ":" + new String(sendBytes), new String(
- receive.getData(), 0, receive.getLength())
- .equals(new String(sendBytes)));
- assertTrue("Wrong receiver:" + receive.getAddress() + ":"
- + localHost, receive.getAddress().equals(localHost));
- } catch (Exception e) {
- fail(
- "Unexpected exception when sending data on dgram connected at native level:"
- + e.toString());
- }
-
- if (server != null) {
- server.stopServer();
- }
-
- // validate that we can disconnect
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(new InetSocketAddress(inetAddress, portNumber));
- ds.disconnect();
- ds.close();
- } catch (Exception e) {
- assertTrue("Unexpected exception when trying to connect at native"
- + e.toString(), (e instanceof PortUnreachableException));
- }
-
- // validate that once connected we cannot send to another address
- try {
- ds = new java.net.DatagramSocket();
- InetAddress inetAddress = InetAddress.getLocalHost();
- int portNumber = Support_PortManager.getNextPortForUDP();
- ds.connect(new InetSocketAddress(inetAddress, portNumber));
- DatagramPacket send = new DatagramPacket(new byte[10], 10,
- inetAddress, portNumber + 1);
- ds.send(send);
- ds.close();
- fail(
- "No Exception when trying to send to a different address on a connected socket ");
- } catch (Exception e) {
- assertTrue(
- "Wrong exception when trying to send to a different address on a connected socket: "
- + e.toString(),
- (e instanceof IllegalArgumentException));
- }
-
- // validate that we can connect, then disconnect, then connect then
- // send/recv
- server = null;
- ports = Support_PortManager.getNextPortsForUDP(3);
- serverPortNumber = ports[0];
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket(ports[1]);
- DatagramSocket ds2 = new DatagramSocket(ports[2]);
-
- try {
- server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
- } catch (Exception e) {
- fail(
- "Failed to set up datagram server for native connected Dgram socket test ");
- }
-
- int port = ds.getLocalPort();
- ds.connect(new InetSocketAddress(localHost, serverPortNumber + 1));
- ds.disconnect();
- ds.connect(new InetSocketAddress(localHost, serverPortNumber));
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue(
- "connect/disconnect/connect - Wrong size data received: "
- + receive.getLength(),
- receive.getLength() == sendBytes.length);
- assertTrue("connect/disconnect/connect - Wrong data received"
- + new String(receive.getData(), 0, receive.getLength())
- + ":" + new String(sendBytes), new String(
- receive.getData(), 0, receive.getLength())
- .equals(new String(sendBytes)));
- assertTrue("connect/disconnect/connect - Wrong receiver:"
- + receive.getAddress() + ":" + localHost, receive
- .getAddress().equals(localHost));
- } catch (Exception e) {
- fail(
- "Unexpected exception when sending data on dgram connected at native level after connect/disconnect/connect:"
- + e.toString());
- }
-
- if (server != null) {
- server.stopServer();
- }
-
- // validate that we can connect/disconnect then send/recv to any address
- server = null;
- ports = Support_PortManager.getNextPortsForUDP(3);
- serverPortNumber = ports[0];
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket(ports[1]);
- DatagramSocket ds2 = new DatagramSocket(ports[2]);
-
- try {
- server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
- } catch (Exception e) {
- fail(
- "Failed to set up datagram server for native connected Dgram socket test ");
- }
-
- int port = ds.getLocalPort();
- ds.connect(new InetSocketAddress(localHost, serverPortNumber + 1));
- ds.disconnect();
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length, localHost, serverPortNumber);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue("connect/disconnect - Wrong size data received: "
- + receive.getLength(),
- receive.getLength() == sendBytes.length);
- assertTrue("connect/disconnect - Wrong data received"
- + new String(receive.getData(), 0, receive.getLength())
- + ":" + new String(sendBytes), new String(
- receive.getData(), 0, receive.getLength())
- .equals(new String(sendBytes)));
- assertTrue("connect/disconnect - Wrong receiver:"
- + receive.getAddress() + ":" + localHost, receive
- .getAddress().equals(localHost));
- } catch (Exception e) {
- fail(
- "Unexpected exception when sending data on dgram connected at native level after connect/disconnect:"
- + e.toString());
- }
-
- if (server != null) {
- server.stopServer();
- }
-
- // validate that we can connect on an allready connected socket and then
- // send/recv
- server = null;
- ports = Support_PortManager.getNextPortsForUDP(3);
- serverPortNumber = ports[0];
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- DatagramSocket ds = new DatagramSocket(ports[1]);
- DatagramSocket ds2 = new DatagramSocket(ports[2]);
-
- try {
- server = new DatagramServer(serverPortNumber, localHost);
- server.start();
- Thread.sleep(1000);
- } catch (Exception e) {
- fail(
- "Failed to set up datagram server for native connected Dgram socket test ");
- }
-
- int port = ds.getLocalPort();
- ds.connect(new InetSocketAddress(localHost, serverPortNumber + 1));
- ds.connect(new InetSocketAddress(localHost, serverPortNumber));
-
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length);
- ds.send(send);
- DatagramPacket receive = new DatagramPacket(new byte[20], 20);
- ds.setSoTimeout(2000);
- ds.receive(receive);
- ds.close();
- assertTrue("connect/connect - Wrong size data received: "
- + receive.getLength(),
- receive.getLength() == sendBytes.length);
- assertTrue("connect/connect - Wrong data received"
- + new String(receive.getData(), 0, receive.getLength())
- + ":" + new String(sendBytes), new String(
- receive.getData(), 0, receive.getLength())
- .equals(new String(sendBytes)));
- assertTrue("connect/connect - Wrong receiver:"
- + receive.getAddress() + ":" + localHost, receive
- .getAddress().equals(localHost));
- } catch (Exception e) {
- fail(
- "Unexpected exception when sending data on dgram connected at native level after connect/connect: "
- + e.toString());
- }
-
- if (server != null) {
- server.stopServer();
- }
-
- // test for when we fail to connect at the native level. It seems to
- // fail for the any address so we use this. Now to be compatible we
- // don't throw the exception but eat it and then act as if we were
- // connected at the Java level.
- try {
- ds = new java.net.DatagramSocket();
- byte[] addressBytes = { 0, 0, 0, 0 };
- InetAddress inetAddress = InetAddress.getByAddress(addressBytes);
- int portNumber = Support_PortManager.getNextPortForUDP();
- InetAddress localHost = InetAddress.getLocalHost();
- ds.connect(new InetSocketAddress(inetAddress, portNumber));
- assertTrue("Is not connected after connect to inaddr any", ds
- .isConnected());
- byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
- DatagramPacket send = new DatagramPacket(sendBytes,
- sendBytes.length, localHost, portNumber);
- ds.send(send);
- fail(
- "No exception when trying to connect at native level with bad address (exception from send) ");
- } catch (Exception e) {
- assertTrue(
- "Wrong exception when trying to connect at native level with bad address (exception from send): "
- + e.toString(),
- (e instanceof IllegalArgumentException));
- }
- }
-
- public void test_isBound() {
- try {
- InetAddress addr = InetAddress.getLocalHost();
- int[] ports = Support_PortManager.getNextPortsForUDP(3);
- int port = ports[0];
-
- DatagramSocket theSocket = new DatagramSocket(ports[1]);
- assertTrue("Socket indicated not bound when it should be (1)",
- theSocket.isBound());
- theSocket.close();
-
- theSocket = new DatagramSocket(new InetSocketAddress(addr, port));
- assertTrue("Socket indicated not bound when it should be (2)",
- theSocket.isBound());
- theSocket.close();
-
- theSocket = new DatagramSocket((SocketAddress) null);
- assertFalse("Socket indicated bound when it should not be (1)",
- theSocket.isBound());
- theSocket.close();
-
- // connect causes implicit bind
- theSocket = new DatagramSocket((SocketAddress) null);
- theSocket.connect(new InetSocketAddress(addr, port));
- assertTrue("Socket indicated not bound when it should be (3)",
- theSocket.isBound());
- theSocket.close();
-
- // now test when we bind explicitely
- InetSocketAddress theLocalAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), ports[2]);
- theSocket = new DatagramSocket((SocketAddress) null);
- assertFalse("Socket indicated bound when it should not be (2)",
- theSocket.isBound());
- theSocket.bind(theLocalAddress);
- assertTrue("Socket indicated not bound when it should be (4)",
- theSocket.isBound());
- theSocket.close();
- assertTrue("Socket indicated not bound when it should be (5)",
- theSocket.isBound());
- } catch (Exception e) {
- fail("Got exception during isBound tests" + e.toString());
- }
- }
-
- public void test_isConnected() {
- try {
- InetAddress addr = InetAddress.getLocalHost();
- int[] ports = Support_PortManager.getNextPortsForUDP(4);
- int port = ports[0];
-
- // base test
- DatagramSocket theSocket = new DatagramSocket(ports[1]);
- assertFalse("Socket indicated connected when it should not be",
- theSocket.isConnected());
- theSocket.connect(new InetSocketAddress(addr, port));
- assertTrue("Socket indicated not connected when it should be",
- theSocket.isConnected());
-
- // reconnect the socket and make sure we get the right answer
- theSocket.connect(new InetSocketAddress(addr, ports[2]));
- assertTrue("Socket indicated not connected when it should be",
- theSocket.isConnected());
-
- // now disconnect the socket and make sure we get the right answer
- theSocket.disconnect();
- assertFalse("Socket indicated connected when it should not be",
- theSocket.isConnected());
- theSocket.close();
-
- // now check behavior when socket is closed when connected
- theSocket = new DatagramSocket(ports[3]);
- theSocket.connect(new InetSocketAddress(addr, port));
- theSocket.close();
- assertTrue("Socket indicated not connected when it should be",
- theSocket.isConnected());
- } catch (Exception e) {
- fail("Got exception during isConnected tests" + e.toString());
- }
- }
-
- public void test_getRemoteSocketAddress() {
- try {
- int[] ports = Support_PortManager.getNextPortsForUDP(3);
- int sport = ports[0];
- int portNumber = ports[1];
- DatagramSocket s = new DatagramSocket(new InetSocketAddress(
- InetAddress.getLocalHost(), portNumber));
- s.connect(new InetSocketAddress(InetAddress.getLocalHost(), sport));
- assertTrue("Returned incorrect InetSocketAddress(1):"
- + s.getLocalSocketAddress().toString(), s
- .getRemoteSocketAddress().equals(
- new InetSocketAddress(InetAddress.getLocalHost(),
- sport)));
- s.close();
-
- // now create one that is not connected and validate that we get the
- // right answer
- DatagramSocket theSocket = new DatagramSocket((SocketAddress) null);
- portNumber = ports[2];
- theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber));
- assertNull(
- "Returned incorrect InetSocketAddress -unconnected socket:"
- + "Expected: NULL", theSocket
- .getRemoteSocketAddress());
-
- // now connect and validate we get the right answer
- theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
- sport));
- assertTrue("Returned incorrect InetSocketAddress(2):"
- + theSocket.getRemoteSocketAddress().toString(), theSocket
- .getRemoteSocketAddress().equals(
- new InetSocketAddress(InetAddress.getLocalHost(),
- sport)));
- theSocket.close();
-
- } catch (Exception e) {
- fail("Exception during getRemoteSocketAddress test: " + e);
- }
- }
-
- public void test_setReuseAddressZ() throws Exception {
- // test case were we set it to false
- DatagramSocket theSocket1 = null;
- DatagramSocket theSocket2 = null;
- try {
- InetSocketAddress theAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), Support_PortManager
- .getNextPortForUDP());
- theSocket1 = new DatagramSocket((SocketAddress) null);
- theSocket2 = new DatagramSocket((SocketAddress) null);
- theSocket1.setReuseAddress(false);
- theSocket2.setReuseAddress(false);
- theSocket1.bind(theAddress);
- theSocket2.bind(theAddress);
- fail(
- "No exception when trying to connect to do duplicate socket bind with re-useaddr set to false");
- } catch (BindException e) {
-
- }
- if (theSocket1 != null)
- theSocket1.close();
- if (theSocket2 != null)
- theSocket2.close();
-
- // test case were we set it to true
- try {
- InetSocketAddress theAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), Support_PortManager
- .getNextPortForUDP());
- theSocket1 = new DatagramSocket((SocketAddress) null);
- theSocket2 = new DatagramSocket((SocketAddress) null);
- theSocket1.setReuseAddress(true);
- theSocket2.setReuseAddress(true);
- theSocket1.bind(theAddress);
- theSocket2.bind(theAddress);
- } catch (Exception e) {
- fail(
- "unexpected exception when trying to connect to do duplicate socket bind with re-useaddr set to true");
- }
- if (theSocket1 != null)
- theSocket1.close();
- if (theSocket2 != null)
- theSocket2.close();
-
- // test the default case which we expect to be the same on all
- // platforms
- try {
- InetSocketAddress theAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), Support_PortManager
- .getNextPortForUDP());
- theSocket1 = new DatagramSocket((SocketAddress) null);
- theSocket2 = new DatagramSocket((SocketAddress) null);
- theSocket1.bind(theAddress);
- theSocket2.bind(theAddress);
- fail(
- "No exception when trying to connect to do duplicate socket bind with re-useaddr left as default");
- } catch (BindException e) {
-
- }
- if (theSocket1 != null)
- theSocket1.close();
- if (theSocket2 != null)
- theSocket2.close();
-
- try {
- theSocket1.setReuseAddress(true);
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_getReuseAddress() throws Exception {
- DatagramSocket theSocket = new DatagramSocket();
- theSocket.setReuseAddress(true);
- assertTrue("getReuseAddress false when it should be true",
- theSocket.getReuseAddress());
- theSocket.setReuseAddress(false);
- assertFalse("getReuseAddress true when it should be false",
- theSocket.getReuseAddress());
- theSocket.close();
- try {
- theSocket.getReuseAddress();
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_setBroadcastZ() throws Exception {
- int[] ports = Support_PortManager.getNextPortsForUDP(3);
- DatagramSocket theSocket = new DatagramSocket(ports[0]);
- theSocket.setBroadcast(false);
- byte theBytes[] = { -1, -1, -1, -1 };
-
- // validate we cannot connect to the broadcast address when
- // setBroadcast is false
- try {
- theSocket.connect(new InetSocketAddress(InetAddress
- .getByAddress(theBytes), ports[1]));
- assertFalse(
- "No exception when connecting to broadcast address with setBroadcast(false)",
- theSocket.getBroadcast());
- } catch (SocketException ex) {
- //expected
- }
-
- // now validate that we can connect to the broadcast address when
- // setBroadcast is true
- theSocket.setBroadcast(true);
- theSocket.connect(new InetSocketAddress(InetAddress
- .getByAddress(theBytes), ports[2]));
-
- theSocket.close();
- try {
- theSocket.setBroadcast(false);
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_getBroadcast() throws Exception {
- DatagramSocket theSocket = new DatagramSocket();
- theSocket.setBroadcast(true);
- assertTrue("getBroadcast false when it should be true", theSocket
- .getBroadcast());
- theSocket.setBroadcast(false);
- assertFalse("getBroadcast true when it should be False", theSocket
- .getBroadcast());
- theSocket.close();
- try {
- theSocket.getBroadcast();
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_setTrafficClassI() throws Exception {
- int IPTOS_LOWCOST = 0x2;
- int IPTOS_RELIABILTY = 0x4;
- int IPTOS_THROUGHPUT = 0x8;
- int IPTOS_LOWDELAY = 0x10;
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
-
- new InetSocketAddress(InetAddress.getLocalHost(),
- ports[0]);
- DatagramSocket theSocket = new DatagramSocket(ports[1]);
-
- // validate that value set must be between 0 and 255
- try {
- theSocket.setTrafficClass(256);
- fail("No exception when traffic class set to 256");
- } catch (IllegalArgumentException e) {
- }
-
- try {
- theSocket.setTrafficClass(-1);
- fail("No exception when traffic class set to -1");
- } catch (IllegalArgumentException e) {
- }
-
- // now validate that we can set it to some good values
- theSocket.setTrafficClass(IPTOS_LOWCOST);
- theSocket.setTrafficClass(IPTOS_THROUGHPUT);
-
- theSocket.close();
- try {
- theSocket.setTrafficClass(1);
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_getTrafficClass() throws Exception {
- int IPTOS_LOWCOST = 0x2;
- int IPTOS_RELIABILTY = 0x4;
- int IPTOS_THROUGHPUT = 0x8;
- int IPTOS_LOWDELAY = 0x10;
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
-
- new InetSocketAddress(InetAddress.getLocalHost(),
- ports[0]);
- DatagramSocket theSocket = new DatagramSocket(ports[1]);
-
- /*
- * we cannot actually check that the values are set as if a platform
- * does not support the option then it may come back unset even
- * though we set it so just get the value to make sure we can get it
- */
- int trafficClass = theSocket.getTrafficClass();
-
- theSocket.close();
- try {
- theSocket.getTrafficClass();
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
- }
-
- public void test_isClosed() {
- try {
- DatagramSocket theSocket = new DatagramSocket();
-
- // validate isClosed returns expected values
- assertFalse("Socket should indicate it is not closed(1):",
- theSocket.isClosed());
- theSocket.close();
- assertTrue("Socket should indicate it is not closed(1):", theSocket
- .isClosed());
-
- InetSocketAddress theAddress = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPortForUDP());
- theSocket = new DatagramSocket(theAddress);
- assertFalse("Socket should indicate it is not closed(2):",
- theSocket.isClosed());
- theSocket.close();
- assertTrue("Socket should indicate it is not closed(2):", theSocket
- .isClosed());
- } catch (Exception e) {
- fail("Got exception during isClosed tests" + e.toString());
- }
- }
-
- public void test_getChannel() throws Exception {
- assertNull(new DatagramSocket().getChannel());
-
- int portNumber = Support_PortManager.getNextPortForUDP();
- DatagramSocket ds = null;
- try {
- InetAddress ia = InetAddress
- .getByName(Support_Configuration.IPv6GlobalAddressJcl4);
- ds = new DatagramSocket();
- assertNull(ds.getChannel());
- ds.connect(ia, portNumber);
- assertNull(ds.getChannel());
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } finally {
- ds.disconnect();
- ds.close();
- }
- portNumber = Support_PortManager.getNextPortForUDP();
- SocketAddress address = new InetSocketAddress(portNumber);
- DatagramChannel channel = DatagramChannel.open();
- DatagramSocket socket = channel.socket();
- assertEquals(channel, socket.getChannel());
- socket.close();
- }
-
- class TestDatagramSocketImplFactory implements DatagramSocketImplFactory {
- public DatagramSocketImpl createDatagramSocketImpl() {
- return new TestDatagramSocketImpl();
- }
- }
-
- class TestDatagramSocketImpl extends DatagramSocketImpl {
-
- @Override
- protected void bind(int arg0, InetAddress arg1) throws SocketException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void close() {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void create() throws SocketException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected byte getTTL() throws IOException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- protected int getTimeToLive() throws IOException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- protected void join(InetAddress arg0) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void joinGroup(SocketAddress arg0, NetworkInterface arg1) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void leave(InetAddress arg0) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void leaveGroup(SocketAddress arg0, NetworkInterface arg1) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected int peek(InetAddress arg0) throws IOException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- protected int peekData(DatagramPacket arg0) throws IOException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- protected void receive(DatagramPacket arg0) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void send(DatagramPacket arg0) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void setTTL(byte arg0) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- protected void setTimeToLive(int arg0) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- public Object getOption(int arg0) throws SocketException {
- // TODO Auto-generated method stub
- return null;
- }
-
- public void setOption(int arg0, Object arg1) throws SocketException {
- // TODO Auto-generated method stub
-
- }
-
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- retval = "Bogus retval";
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- try {
- ds.close();
- sds.close();
- } catch (Exception e) {
- }
- }
-
- protected void receive_oversize_java_net_DatagramPacket() throws Exception {
- final int[] ports = Support_PortManager.getNextPortsForUDP(2);
- final int portNumber = ports[0];
-
- class TestDGRcvOver implements Runnable {
- public void run() {
- InetAddress localHost = null;
- try {
- localHost = InetAddress.getLocalHost();
- Thread.sleep(1000);
- DatagramSocket sds = new DatagramSocket(ports[1]);
- DatagramPacket rdp = new DatagramPacket("0123456789"
- .getBytes(), 10, localHost, portNumber);
- sds.send(rdp);
- sds.close();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- try {
- new Thread(new TestDGRcvOver(), "DGSenderOver").start();
- ds = new java.net.DatagramSocket(portNumber);
- ds.setSoTimeout(6000);
- byte rbuf[] = new byte[5];
- DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
- ;
- ds.receive(rdp);
- ds.close();
- assertTrue("Send/Receive oversize failed to return correct data: "
- + new String(rbuf, 0, 5), new String(rbuf, 0, 5)
- .equals("01234"));
- } finally {
- ds.close();
- }
- }
-}
diff --git a/luni/src/test/java/libcore/java/net/OldFileNameMapTest.java b/luni/src/test/java/libcore/java/net/OldFileNameMapTest.java
index de9caa9..4fe3ef4 100644
--- a/luni/src/test/java/libcore/java/net/OldFileNameMapTest.java
+++ b/luni/src/test/java/libcore/java/net/OldFileNameMapTest.java
@@ -22,19 +22,11 @@ import java.net.FileNameMap;
import java.net.URLConnection;
public class OldFileNameMapTest extends TestCase {
-
- public void test_getContentTypeFor() {
- String [] files = {"text", "txt", "htm", "html"};
-
- String [] mimeTypes = {"text/plain", "text/plain",
- "text/html", "text/html"};
-
- FileNameMap fileNameMap = URLConnection.getFileNameMap();
-
- for(int i = 0; i < files.length; i++) {
- String mimeType = fileNameMap.getContentTypeFor("test." + files[i]);
- assertEquals("getContentTypeFor returns incorrect MIME type for " +
- files[i], mimeTypes[i], mimeType);
- }
- }
+ public void test_getContentTypeFor() {
+ FileNameMap map = URLConnection.getFileNameMap();
+ assertEquals("text/plain", map.getContentTypeFor("test.text"));
+ assertEquals("text/plain", map.getContentTypeFor("test.txt"));
+ assertEquals("text/html", map.getContentTypeFor("test.htm"));
+ assertEquals("text/html", map.getContentTypeFor("test.html"));
+ }
}
diff --git a/luni/src/test/java/libcore/java/net/OldSocketTest.java b/luni/src/test/java/libcore/java/net/OldSocketTest.java
index 033a7bf..7973965 100644
--- a/luni/src/test/java/libcore/java/net/OldSocketTest.java
+++ b/luni/src/test/java/libcore/java/net/OldSocketTest.java
@@ -95,10 +95,9 @@ public class OldSocketTest extends OldSocketTestCase {
}
try {
- new Socket("unknown.host", 0);
+ new Socket("unknown.host.google.com", 0);
fail("UnknownHostException was not thrown.");
- } catch(UnknownHostException uhe) {
- //expected
+ } catch (UnknownHostException expected) {
}
Socket socket = null;
try {
@@ -120,9 +119,10 @@ public class OldSocketTest extends OldSocketTestCase {
}
public void test_ConstructorLjava_lang_StringILjava_net_InetAddressI2() throws IOException {
- Socket s1 = new Socket("www.google.com", 80, null, 0);
+ int sport = startServer("Cons String,I,InetAddress,I");
+ Socket s1 = new Socket(InetAddress.getLocalHost(), sport, null, 0);
try {
- Socket s2 = new Socket("www.google.com", 80, null, s1.getLocalPort());
+ Socket s2 = new Socket(InetAddress.getLocalHost(), sport, null, s1.getLocalPort());
try {
s2.close();
} catch (IOException ignored) {
@@ -1251,6 +1251,12 @@ public class OldSocketTest extends OldSocketTestCase {
theSocket.connect(nonReachableAddress, 200);
theSocket.close();
fail("No interrupted exception when connecting to address nobody listening on with short timeout 200: ");
+ } catch (ConnectException ce) {
+ // some networks will quickly reset the TCP connection attempt to this fake IP
+ assertTrue(
+ "Wrong exception when connecting to address nobody listening on with short timeout 200: "
+ + ce.toString(),
+ (ce.getMessage() != null && ce.getMessage().contains("ECONNREFUSED")));
} catch (Exception e) {
assertTrue(
"Wrong exception when connecting to address nobody listening on with short timeout 200: "
@@ -1266,6 +1272,12 @@ public class OldSocketTest extends OldSocketTestCase {
theSocket.connect(nonReachableAddress, 40);
theSocket.close();
fail("No interrupted exception when connecting to address nobody listening on with short timeout 40: ");
+ } catch (ConnectException ce) {
+ // some networks will quickly reset the TCP connection attempt to this fake IP
+ assertTrue(
+ "Wrong exception when connecting to address nobody listening on with short timeout 40: "
+ + ce.toString(),
+ (ce.getMessage() != null && ce.getMessage().contains("ECONNREFUSED")));
} catch (Exception e) {
assertTrue(
"Wrong exception when connecting to address nobody listening on with short timeout 40: "
diff --git a/luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java b/luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java
index 3a5608c..c076f1d 100644
--- a/luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java
+++ b/luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java
@@ -17,7 +17,6 @@
package libcore.java.net;
-import dalvik.annotation.SideEffect;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -26,15 +25,11 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSource;
-import java.security.Permission;
import java.security.PermissionCollection;
-import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.Manifest;
-import org.apache.harmony.security.tests.support.TestCertUtils;
-import tests.support.Support_Configuration;
import tests.support.Support_TestWebData;
import tests.support.Support_TestWebServer;
import tests.support.resource.Support_Resources;
@@ -42,15 +37,6 @@ import tests.support.resource.Support_Resources;
public class OldURLClassLoaderTest extends junit.framework.TestCase {
URLClassLoader ucl;
- SecurityManager sm = new SecurityManager() {
-
- public void checkPermission(Permission perm) {
- }
-
- public void checkCreateClassLoader() {
- throw new SecurityException();
- }
- };
/**
* java.net.URLClassLoader#URLClassLoader(java.net.URL[])
@@ -58,8 +44,8 @@ public class OldURLClassLoaderTest extends junit.framework.TestCase {
public void test_Constructor$Ljava_net_URL() throws MalformedURLException {
URL[] u = new URL[0];
ucl = new URLClassLoader(u);
- assertTrue("Failed to set parent", ucl != null
- && ucl.getParent() == URLClassLoader.getSystemClassLoader());
+ assertTrue("Failed to set parent",
+ ucl.getParent() == URLClassLoader.getSystemClassLoader());
URL [] urls = {new URL("http://foo.com/foo"),
@@ -87,7 +73,6 @@ public class OldURLClassLoaderTest extends junit.framework.TestCase {
* java.net.URLClassLoader#findResources(java.lang.String)
*/
public void test_findResourcesLjava_lang_String() throws Exception {
- Enumeration<URL> res = null;
String[] resValues = { "This is a test resource file.",
"This is a resource from a subdir"};
@@ -115,7 +100,7 @@ public class OldURLClassLoaderTest extends junit.framework.TestCase {
urls[1] = new URL("file://" + subDir.getAbsolutePath() + "/");
ucl = new URLClassLoader(urls);
- res = ucl.findResources("test0");
+ Enumeration<URL> res = ucl.findResources("test0");
assertNotNull("Failed to locate resources", res);
int i = 0;
@@ -207,7 +192,7 @@ public class OldURLClassLoaderTest extends junit.framework.TestCase {
}
}
- @SideEffect("Support_TestWebServer requires isolation.")
+ // SideEffect: Support_TestWebServer requires isolation.
public void test_findResourceLjava_lang_String() throws Exception {
File tmp = File.createTempFile("test", ".txt");
@@ -232,7 +217,7 @@ public class OldURLClassLoaderTest extends junit.framework.TestCase {
/**
* Regression for Harmony-2237
*/
- @SideEffect("Support_TestWebServer requires isolation.")
+ // SideEffect: Support_TestWebServer requires isolation.
public void test_findResource_String() throws Exception {
File tempFile1 = File.createTempFile("textFile", ".txt");
tempFile1.createNewFile();
@@ -250,19 +235,17 @@ public class OldURLClassLoaderTest extends junit.framework.TestCase {
"/tests/resources/hyts_patch.jar");
Support_Resources.copyLocalFileto(tempFile2, is);
String tempPath2 = tempFile2.getAbsolutePath();
- String tempPath3 = "http://localhost:" + port + "/";
URLClassLoader urlLoader = getURLClassLoader(tempPath1, tempPath2);
- assertNull("Found inexistant resource",
- urlLoader.findResource("XXX"));
+ assertNull("Found nonexistent resource", urlLoader.findResource("XXX"));
assertNotNull("Couldn't find resource from directory",
urlLoader.findResource(tempFile1.getName()));
- assertNotNull("Couldn't find resource from jar",
- urlLoader.findResource("Blah.txt"));
+ assertNotNull("Couldn't find resource from jar", urlLoader.findResource("Blah.txt"));
+
+ String tempPath3 = "http://localhost:" + port + "/";
urlLoader = getURLClassLoader(tempPath1, tempPath2, tempPath3);
- assertNotNull("Couldn't find resource from web",
- urlLoader.findResource("test1"));
- assertNull("Found inexistant resource from web",
- urlLoader.findResource("test3"));
+ assertNotNull("Couldn't find resource from web", urlLoader.findResource("test1"));
+ // Attempt to find a resource using a URL that will produce a 404.
+ assertNull("Found nonexistent resource from web", urlLoader.findResource("test9999"));
} finally {
server.close();
}
diff --git a/luni/src/test/java/libcore/java/net/ServerSocketTest.java b/luni/src/test/java/libcore/java/net/ServerSocketTest.java
index fe9d423..d82e934 100644
--- a/luni/src/test/java/libcore/java/net/ServerSocketTest.java
+++ b/luni/src/test/java/libcore/java/net/ServerSocketTest.java
@@ -17,6 +17,8 @@
package libcore.java.net;
import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
@@ -43,4 +45,34 @@ public class ServerSocketTest extends junit.framework.TestCase {
t.join();
assertEquals(0, result[0].getSoTimeout());
}
+
+ public void testInitialState() throws Exception {
+ ServerSocket ss = new ServerSocket();
+ try {
+ assertFalse(ss.isBound());
+ assertFalse(ss.isClosed());
+ assertEquals(-1, ss.getLocalPort());
+ assertNull(ss.getLocalSocketAddress());
+ assertNull(ss.getInetAddress());
+ assertTrue(ss.getReuseAddress());
+ assertNull(ss.getChannel());
+ } finally {
+ ss.close();
+ }
+ }
+
+ public void testStateAfterClose() throws Exception {
+ ServerSocket ss = new ServerSocket();
+ ss.bind(new InetSocketAddress(Inet4Address.getLocalHost(), 0));
+ InetSocketAddress boundAddress = (InetSocketAddress) ss.getLocalSocketAddress();
+ ss.close();
+
+ assertTrue(ss.isBound());
+ assertTrue(ss.isClosed());
+ assertEquals(boundAddress.getAddress(), ss.getInetAddress());
+ assertEquals(boundAddress.getPort(), ss.getLocalPort());
+
+ InetSocketAddress localAddressAfterClose = (InetSocketAddress) ss.getLocalSocketAddress();
+ assertEquals(boundAddress, localAddressAfterClose);
+ }
}
diff --git a/luni/src/test/java/libcore/java/net/SocketTest.java b/luni/src/test/java/libcore/java/net/SocketTest.java
index 42b7250..fb09be0 100644
--- a/luni/src/test/java/libcore/java/net/SocketTest.java
+++ b/luni/src/test/java/libcore/java/net/SocketTest.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
+import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
@@ -109,10 +110,12 @@ public class SocketTest extends junit.framework.TestCase {
in.socket().setTcpNoDelay(false);
}
+ InetSocketAddress listenAddress = (InetSocketAddress) in.socket().getLocalSocketAddress();
InetSocketAddress outRemoteAddress = (InetSocketAddress) out.socket().getRemoteSocketAddress();
InetSocketAddress outLocalAddress = (InetSocketAddress) out.socket().getLocalSocketAddress();
InetSocketAddress inLocalAddress = (InetSocketAddress) in.socket().getLocalSocketAddress();
InetSocketAddress inRemoteAddress = (InetSocketAddress) in.socket().getRemoteSocketAddress();
+ System.err.println("listenAddress: " + listenAddr);
System.err.println("inLocalAddress: " + inLocalAddress);
System.err.println("inRemoteAddress: " + inRemoteAddress);
System.err.println("outLocalAddress: " + outLocalAddress);
@@ -127,14 +130,42 @@ public class SocketTest extends junit.framework.TestCase {
assertEquals(outLocalAddress.getAddress(), ss.getInetAddress());
assertEquals(outRemoteAddress.getAddress(), ss.getInetAddress());
+ assertFalse(ssc.socket().isClosed());
+ assertTrue(ssc.socket().isBound());
+ assertTrue(in.isConnected());
+ assertTrue(in.socket().isConnected());
+ assertTrue(out.socket().isConnected());
+ assertTrue(out.isConnected());
+
in.close();
out.close();
ssc.close();
+ assertTrue(ssc.socket().isClosed());
+ assertTrue(ssc.socket().isBound());
+ assertFalse(in.isConnected());
+ assertFalse(in.socket().isConnected());
+ assertFalse(out.socket().isConnected());
+ assertFalse(out.isConnected());
+
assertNull(in.socket().getRemoteSocketAddress());
assertNull(out.socket().getRemoteSocketAddress());
- assertEquals(in.socket().getLocalSocketAddress(), ss.getLocalSocketAddress());
+ // As per docs and RI - server socket local address methods continue to return the bind()
+ // addresses even after close().
+ assertEquals(listenAddress, ssc.socket().getLocalSocketAddress());
+
+ // As per docs and RI - socket local address methods return the wildcard address before
+ // bind() and after close(), but the port will be the same as it was before close().
+ InetSocketAddress inLocalAddressAfterClose =
+ (InetSocketAddress) in.socket().getLocalSocketAddress();
+ assertTrue(inLocalAddressAfterClose.getAddress().isAnyLocalAddress());
+ assertEquals(inLocalAddress.getPort(), inLocalAddressAfterClose.getPort());
+
+ InetSocketAddress outLocalAddressAfterClose =
+ (InetSocketAddress) out.socket().getLocalSocketAddress();
+ assertTrue(outLocalAddressAfterClose.getAddress().isAnyLocalAddress());
+ assertEquals(outLocalAddress.getPort(), outLocalAddressAfterClose.getPort());
}
// SocketOptions.setOption has weird behavior for setSoLinger/SO_LINGER.
@@ -286,6 +317,42 @@ public class SocketTest extends junit.framework.TestCase {
serverSocket.close();
}
+ public void testInitialState() throws Exception {
+ Socket s = new Socket();
+ try {
+ assertFalse(s.isBound());
+ assertFalse(s.isClosed());
+ assertFalse(s.isConnected());
+ assertEquals(-1, s.getLocalPort());
+ assertTrue(s.getLocalAddress().isAnyLocalAddress());
+ assertNull(s.getLocalSocketAddress());
+ assertNull(s.getInetAddress());
+ assertEquals(0, s.getPort());
+ assertNull(s.getRemoteSocketAddress());
+ assertFalse(s.getReuseAddress());
+ assertNull(s.getChannel());
+ } finally {
+ s.close();
+ }
+ }
+
+ public void testStateAfterClose() throws Exception {
+ Socket s = new Socket();
+ s.bind(new InetSocketAddress(Inet4Address.getLocalHost(), 0));
+ InetSocketAddress boundAddress = (InetSocketAddress) s.getLocalSocketAddress();
+ s.close();
+
+ assertTrue(s.isBound());
+ assertTrue(s.isClosed());
+ assertFalse(s.isConnected());
+ assertTrue(s.getLocalAddress().isAnyLocalAddress());
+ assertEquals(boundAddress.getPort(), s.getLocalPort());
+
+ InetSocketAddress localAddressAfterClose = (InetSocketAddress) s.getLocalSocketAddress();
+ assertTrue(localAddressAfterClose.getAddress().isAnyLocalAddress());
+ assertEquals(boundAddress.getPort(), localAddressAfterClose.getPort());
+ }
+
static class MockServer {
private ExecutorService executor;
private ServerSocket serverSocket;
diff --git a/luni/src/test/java/libcore/java/net/URITest.java b/luni/src/test/java/libcore/java/net/URITest.java
index 04a7d2e..7f4c086 100644
--- a/luni/src/test/java/libcore/java/net/URITest.java
+++ b/luni/src/test/java/libcore/java/net/URITest.java
@@ -16,9 +16,9 @@
package libcore.java.net;
+import junit.framework.TestCase;
import java.net.URI;
import java.net.URISyntaxException;
-import junit.framework.TestCase;
import libcore.util.SerializationTester;
public final class URITest extends TestCase {
@@ -57,6 +57,24 @@ public final class URITest extends TestCase {
.equals(new URI("http://localhost/foo?bar=baz#QUUX")));
}
+ public void testEqualsEscaping() throws Exception {
+ // Case insensitive when comparing escaped values, but not when
+ // comparing unescaped values.
+ assertEquals(new URI("http://localhost/foo?bar=fooobar%E0%AE%A8%E0bar"),
+ new URI("http://localhost/foo?bar=fooobar%E0%AE%a8%e0bar"));
+ assertFalse(new URI("http://localhost/foo?bar=fooobar%E0%AE%A8%E0bar").equals(
+ new URI("http://localhost/foo?bar=FoooBar%E0%AE%a8%e0bar")));
+ assertFalse(new URI("http://localhost/foo?bar=fooobar%E0%AE%A8%E0bar").equals(
+ new URI("http://localhost/foo?bar=fooobar%E0%AE%a8%e0BaR")));
+
+ // Last byte replaced by an unescaped value.
+ assertFalse(new URI("http://localhost/foo?bar=%E0%AE%A8%E0").equals(
+ new URI("http://localhost/foo?bar=%E0%AE%a8xxx")));
+ // Missing byte.
+ assertFalse(new URI("http://localhost/foo?bar=%E0%AE%A8%E0").equals(
+ new URI("http://localhost/foo?bar=%E0%AE%a8")));
+ }
+
public void testFileEqualsWithEmptyHost() throws Exception {
assertEquals(new URI("file", "", "/a/", null), new URI("file:/a/"));
assertEquals(new URI("file", null, "/a/", null), new URI("file:/a/"));
@@ -511,7 +529,7 @@ public final class URITest extends TestCase {
assertEquals("b/c", a.relativize(b).toString()); // RI assumes a directory
}
- public void testParseServerAuthorityInvalidAuthority() throws Exception {
+ public void testParseServerAuthorityInvalidPortMinus() throws Exception {
URI uri = new URI("http://host:-2/");
assertEquals("host:-2", uri.getAuthority());
assertNull(uri.getHost());
@@ -523,6 +541,30 @@ public final class URITest extends TestCase {
}
}
+ public void testParseServerAuthorityInvalidPortPlus() throws Exception {
+ URI uri = new URI("http://host:+2/");
+ assertEquals("host:+2", uri.getAuthority());
+ assertNull(uri.getHost());
+ assertEquals(-1, uri.getPort());
+ try {
+ uri.parseServerAuthority();
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ }
+
+ public void testParseServerAuthorityInvalidPortNonASCII() throws Exception {
+ URI uri = new URI("http://host:١٢٣/"); // 123 in arabic
+ assertEquals("host:١٢٣", uri.getAuthority());
+ assertNull(uri.getHost());
+ assertEquals(-1, uri.getPort());
+ try {
+ uri.parseServerAuthority();
+ fail();
+ } catch (URISyntaxException expected) {
+ }
+ }
+
public void testParseServerAuthorityOmittedAuthority() throws Exception {
URI uri = new URI("http:file");
uri.parseServerAuthority(); // does nothing!
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index 4ed7f0e..f438d1b 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -21,9 +21,7 @@ import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.MockWebServer;
import com.google.mockwebserver.RecordedRequest;
import com.google.mockwebserver.SocketPolicy;
-import dalvik.system.CloseGuard;
import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -31,7 +29,6 @@ import java.io.OutputStream;
import java.net.Authenticator;
import java.net.CacheRequest;
import java.net.CacheResponse;
-import java.net.ConnectException;
import java.net.HttpRetryException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
@@ -71,20 +68,20 @@ import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
-import junit.framework.TestCase;
-import libcore.java.lang.ref.FinalizationTester;
import libcore.java.security.StandardNames;
import libcore.java.security.TestKeyStore;
+import libcore.java.util.AbstractResourceLeakageDetectorTestCase;
import libcore.javax.net.ssl.TestSSLContext;
import tests.net.StuckServer;
-import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AFTER_READING_REQUEST;
import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_END;
import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_START;
+import static com.google.mockwebserver.SocketPolicy.FAIL_HANDSHAKE;
import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_INPUT_AT_END;
import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_OUTPUT_AT_END;
-public final class URLConnectionTest extends TestCase {
+public final class URLConnectionTest extends AbstractResourceLeakageDetectorTestCase {
+
private MockWebServer server;
private HttpResponseCache cache;
private String hostName;
@@ -105,8 +102,10 @@ public final class URLConnectionTest extends TestCase {
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
server.shutdown();
+ server = null;
if (cache != null) {
cache.delete();
+ cache = null;
}
super.tearDown();
}
@@ -325,6 +324,12 @@ public final class URLConnectionTest extends TestCase {
public void testServerShutdownOutput() throws Exception {
// This test causes MockWebServer to log a "connection failed" stack trace
+
+ // Setting the server workerThreads to 1 ensures the responses are generated in the order
+ // the requests are accepted by the server. Without this the second and third requests made
+ // by the client (the request for "/b" and the retry for "/b" when the bad socket is
+ // detected) can be handled by the server out of order leading to test failure.
+ server.setWorkerThreads(1);
server.enqueue(new MockResponse()
.setBody("Output shutdown after this response")
.setSocketPolicy(SHUTDOWN_OUTPUT_AT_END));
@@ -433,7 +438,7 @@ public final class URLConnectionTest extends TestCase {
RecordedRequest request = server.takeRequest();
assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
- assertEquals("TLSv1", request.getSslProtocol());
+ assertEquals("TLSv1.2", request.getSslProtocol());
}
public void testConnectViaHttpsReusingConnections() throws IOException, InterruptedException {
@@ -801,47 +806,17 @@ public final class URLConnectionTest extends TestCase {
}
public void testDisconnectAfterOnlyResponseCodeCausesNoCloseGuardWarning() throws IOException {
- CloseGuardGuard guard = new CloseGuardGuard();
- try {
- server.enqueue(new MockResponse()
- .setBody(gzip("ABCABCABC".getBytes("UTF-8")))
- .addHeader("Content-Encoding: gzip"));
- server.play();
+ server.enqueue(new MockResponse()
+ .setBody(gzip("ABCABCABC".getBytes("UTF-8")))
+ .addHeader("Content-Encoding: gzip"));
+ server.play();
- HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
+ HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
+ try {
assertEquals(200, connection.getResponseCode());
- connection.disconnect();
- connection = null;
- assertFalse(guard.wasCloseGuardCalled());
} finally {
- guard.close();
- }
- }
-
- public static class CloseGuardGuard implements Closeable, CloseGuard.Reporter {
- private final CloseGuard.Reporter oldReporter = CloseGuard.getReporter();
-
- private AtomicBoolean closeGuardCalled = new AtomicBoolean();
-
- public CloseGuardGuard() {
- CloseGuard.setReporter(this);
- }
-
- @Override public void report(String message, Throwable allocationSite) {
- oldReporter.report(message, allocationSite);
- closeGuardCalled.set(true);
- }
-
- public boolean wasCloseGuardCalled() {
- FinalizationTester.induceFinalization();
- close();
- return closeGuardCalled.get();
- }
-
- @Override public void close() {
- CloseGuard.setReporter(oldReporter);
+ connection.disconnect();
}
-
}
public void testDefaultRequestProperty() throws Exception {
@@ -990,6 +965,7 @@ public final class URLConnectionTest extends TestCase {
RecordedRequest request = server.takeRequest();
assertContains(request.getHeaders(), "Accept-Encoding: gzip");
+ assertEquals("gzip", connection.getContentEncoding());
}
public void testGzipAndConnectionReuseWithFixedLength() throws Exception {
@@ -1065,25 +1041,37 @@ public final class URLConnectionTest extends TestCase {
}
/**
- * Obnoxiously test that the chunk sizes transmitted exactly equal the
- * requested data+chunk header size. Although setChunkedStreamingMode()
- * isn't specific about whether the size applies to the data or the
- * complete chunk, the RI interprets it as a complete chunk.
+ * Test that request body chunking works. This test has been relaxed from treating
+ * the {@link java.net.HttpURLConnection#setChunkedStreamingMode(int)}
+ * chunk length as being fixed because OkHttp no longer guarantees
+ * the fixed chunk size. Instead, we check that chunking takes place
+ * and we force the chunk size with flushes.
*/
public void testSetChunkedStreamingMode() throws IOException, InterruptedException {
server.enqueue(new MockResponse());
server.play();
HttpURLConnection urlConnection = (HttpURLConnection) server.getUrl("/").openConnection();
- urlConnection.setChunkedStreamingMode(8);
+ // Later releases of Android ignore the value for chunkLength if it is > 0 and default to
+ // a fixed chunkLength. During the change-over period while the chunkLength indicates the
+ // chunk buffer size (inc. header) the chunkLength has to be >= 8. This enables the flush()
+ // to dictate the size of the chunks.
+ urlConnection.setChunkedStreamingMode(50 /* chunkLength */);
urlConnection.setDoOutput(true);
OutputStream outputStream = urlConnection.getOutputStream();
- outputStream.write("ABCDEFGHIJKLMNOPQ".getBytes("US-ASCII"));
+ String outputString = "ABCDEFGH";
+ byte[] outputBytes = outputString.getBytes("US-ASCII");
+ int targetChunkSize = 3;
+ for (int i = 0; i < outputBytes.length; i += targetChunkSize) {
+ int count = i + targetChunkSize < outputBytes.length ? 3 : outputBytes.length - i;
+ outputStream.write(outputBytes, i, count);
+ outputStream.flush();
+ }
assertEquals(200, urlConnection.getResponseCode());
RecordedRequest request = server.takeRequest();
- assertEquals("ABCDEFGHIJKLMNOPQ", new String(request.getBody(), "US-ASCII"));
- assertEquals(Arrays.asList(3, 3, 3, 3, 3, 2), request.getChunkSizes());
+ assertEquals(outputString, new String(request.getBody(), "US-ASCII"));
+ assertEquals(Arrays.asList(3, 3, 2), request.getChunkSizes());
}
public void testAuthenticateWithFixedLengthStreaming() throws Exception {
@@ -1615,7 +1603,7 @@ public final class URLConnectionTest extends TestCase {
+ "CN=" + hostName + " 1, "
+ "CN=Test Intermediate Certificate Authority 1, "
+ "CN=Test Root Certificate Authority 1"
- + "] RSA"),
+ + "] ECDHE_RSA"),
trustManager.calls);
} finally {
HttpsURLConnection.setDefaultHostnameVerifier(defaultHostnameVerifier);
@@ -2190,16 +2178,15 @@ public final class URLConnectionTest extends TestCase {
}
}
+ // http://code.google.com/p/android/issues/detail?id=16895
public void testUrlWithSpaceInHostViaHttpProxy() throws Exception {
server.enqueue(new MockResponse());
server.play();
URLConnection urlConnection = new URL("http://and roid.com/")
.openConnection(server.toProxyAddress());
- try {
- urlConnection.getInputStream();
- fail(); // the RI makes a bogus proxy request for "GET http://and roid.com/ HTTP/1.1"
- } catch (UnknownHostException expected) {
- }
+
+ // This test is to check that a NullPointerException is not thrown.
+ urlConnection.getInputStream();
}
public void testSslFallback() throws Exception {
@@ -2213,7 +2200,7 @@ public final class URLConnectionTest extends TestCase {
"SSLv3");
server.useHttps(serverSocketFactory, false);
- server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
+ server.enqueue(new MockResponse().setSocketPolicy(FAIL_HANDSHAKE));
server.enqueue(new MockResponse().setBody("This required a 2nd handshake"));
server.play();
@@ -2237,7 +2224,7 @@ public final class URLConnectionTest extends TestCase {
SSLSocket clientSocket1 = createdSockets.get(0);
List<String> clientSocket1EnabledProtocols = Arrays.asList(
clientSocket1.getEnabledProtocols());
- assertContains(clientSocket1EnabledProtocols, "TLSv1");
+ assertContains(clientSocket1EnabledProtocols, "TLSv1.2");
List<String> clientSocket1EnabledCiphers =
Arrays.asList(clientSocket1.getEnabledCipherSuites());
assertContainsNoneMatching(
@@ -2246,7 +2233,7 @@ public final class URLConnectionTest extends TestCase {
SSLSocket clientSocket2 = createdSockets.get(1);
List<String> clientSocket2EnabledProtocols =
Arrays.asList(clientSocket2.getEnabledProtocols());
- assertContainsNoneMatching(clientSocket2EnabledProtocols, "TLSv1");
+ assertContainsNoneMatching(clientSocket2EnabledProtocols, "TLSv1.2");
List<String> clientSocket2EnabledCiphers =
Arrays.asList(clientSocket2.getEnabledCipherSuites());
assertContains(clientSocket2EnabledCiphers, StandardNames.CIPHER_SUITE_FALLBACK);
@@ -2296,11 +2283,15 @@ public final class URLConnectionTest extends TestCase {
HttpsURLConnection connection = (HttpsURLConnection) server.getUrl("/").openConnection();
connection.setSSLSocketFactory(testSSLContext.clientContext.getSocketFactory());
connection.connect();
- assertNotNull(connection.getHostnameVerifier());
- assertNull(connection.getLocalCertificates());
- assertNotNull(connection.getServerCertificates());
- assertNotNull(connection.getCipherSuite());
- assertNotNull(connection.getPeerPrincipal());
+ try {
+ assertNotNull(connection.getHostnameVerifier());
+ assertNull(connection.getLocalCertificates());
+ assertNotNull(connection.getServerCertificates());
+ assertNotNull(connection.getCipherSuite());
+ assertNotNull(connection.getPeerPrincipal());
+ } finally {
+ connection.disconnect();
+ }
}
/**
diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java
index a18816b..07e651c 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -350,7 +350,7 @@ public final class URLTest extends TestCase {
}
}
- public void testNegativePort() throws Exception {
+ public void testPortWithMinusSign() throws Exception {
try {
new URL("http://host:-2/");
fail();
@@ -358,6 +358,22 @@ public final class URLTest extends TestCase {
}
}
+ public void testPortWithPlusSign() throws Exception {
+ try {
+ new URL("http://host:+2/");
+ fail();
+ } catch (MalformedURLException expected) {
+ }
+ }
+
+ public void testPortNonASCII() throws Exception {
+ try {
+ new URL("http://host:١٢٣/"); // 123 in arabic
+ fail();
+ } catch (MalformedURLException expected) {
+ }
+ }
+
public void testNegativePortEqualsPlaceholder() throws Exception {
try {
new URL("http://host:-1/");
diff --git a/luni/src/test/java/libcore/java/nio/BufferTest.java b/luni/src/test/java/libcore/java/nio/BufferTest.java
index ae90d49..c936cdf 100644
--- a/luni/src/test/java/libcore/java/nio/BufferTest.java
+++ b/luni/src/test/java/libcore/java/nio/BufferTest.java
@@ -16,12 +16,28 @@
package libcore.java.nio;
-import java.io.*;
-import java.lang.reflect.*;
-import java.nio.*;
-import java.nio.channels.*;
-import java.util.Arrays;
import junit.framework.TestCase;
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.nio.Buffer;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.NioUtils;
+import java.nio.ReadOnlyBufferException;
+import java.nio.ShortBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+import libcore.io.SizeOf;
public class BufferTest extends TestCase {
private static ByteBuffer allocateMapped(int size) throws Exception {
@@ -586,17 +602,31 @@ public class BufferTest extends TestCase {
assertTrue(b.isDirect());
// Check the buffer has an array of the right size.
assertTrue(b.hasArray());
- assertEquals(0, b.arrayOffset());
byte[] array = b.array();
- assertEquals(10, array.length);
+ assertTrue(array.length >= b.capacity());
+ assertEquals(10, b.capacity());
// Check that writes to the array show up in the buffer.
assertEquals(0, b.get(0));
- array[0] = 1;
+ array[b.arrayOffset()] = 1;
assertEquals(1, b.get(0));
// Check that writes to the buffer show up in the array.
- assertEquals(1, array[0]);
+ assertEquals(1, array[b.arrayOffset()]);
b.put(0, (byte) 0);
- assertEquals(0, array[0]);
+ assertEquals(0, array[b.arrayOffset()]);
+ }
+
+ // Test that direct byte buffers are 8 byte aligned.
+ // http://b/16449607
+ public void testDirectByteBufferAlignment() throws Exception {
+ ByteBuffer b = ByteBuffer.allocateDirect(10);
+ Field addressField = Buffer.class.getDeclaredField("effectiveDirectAddress");
+ assertTrue(addressField != null);
+ addressField.setAccessible(true);
+ long address = addressField.getLong(b);
+ // Check that the address field is aligned by 8.
+ // Normally reading this field happens in native code by calling
+ // GetDirectBufferAddress.
+ assertEquals(0, address % 8);
}
public void testSliceOffset() throws Exception {
@@ -604,14 +634,12 @@ public class BufferTest extends TestCase {
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.get();
ByteBuffer slice = buffer.slice();
- assertEquals(0, buffer.arrayOffset());
- assertEquals(1, slice.arrayOffset());
+ assertEquals(buffer.arrayOffset() + 1, slice.arrayOffset());
ByteBuffer directBuffer = ByteBuffer.allocateDirect(10);
directBuffer.get();
ByteBuffer directSlice = directBuffer.slice();
- assertEquals(0, directBuffer.arrayOffset());
- assertEquals(1, directSlice.arrayOffset());
+ assertEquals(directBuffer.arrayOffset() + 1, directSlice.arrayOffset());
}
// http://code.google.com/p/android/issues/detail?id=16184
@@ -855,4 +883,396 @@ public class BufferTest extends TestCase {
mapped.flip();
mapped.get();
}
+
+ public void testElementSizeShifts() {
+ // Element size shifts are the log base 2 of the element size
+ // of this buffer.
+ assertEquals(1, 1 << ByteBuffer.allocate(0).getElementSizeShift());
+
+ assertEquals(SizeOf.CHAR, 1 << CharBuffer.allocate(0).getElementSizeShift());
+ assertEquals(SizeOf.SHORT, 1 << ShortBuffer.allocate(0).getElementSizeShift());
+
+ assertEquals(SizeOf.INT, 1 << IntBuffer.allocate(0).getElementSizeShift());
+ assertEquals(SizeOf.FLOAT, 1 << FloatBuffer.allocate(0).getElementSizeShift());
+
+ assertEquals(SizeOf.LONG, 1 << LongBuffer.allocate(0).getElementSizeShift());
+ assertEquals(SizeOf.DOUBLE, 1 << DoubleBuffer.allocate(0).getElementSizeShift());
+ }
+
+ public void testFreed() {
+ ByteBuffer b1 = ByteBuffer.allocateDirect(1);
+ ByteBuffer b2 = b1.duplicate();
+ NioUtils.freeDirectBuffer(b1);
+ for (ByteBuffer b: new ByteBuffer[] { b1, b2 }) {
+ assertFalse(b.isAccessible());
+ try {
+ b.compact();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.duplicate();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ testFailForPutMethods(b);
+ testFailForAsMethods(b);
+ testFailForGetMethods(b);
+ NioUtils.freeDirectBuffer(b); // should be able to free twice
+ }
+ }
+
+ public void testAccess() {
+ ByteBuffer b1 = ByteBuffer.allocate(1);
+ ByteBuffer b2 = b1.duplicate();
+ for (ByteBuffer b: new ByteBuffer[] { b1, b2 }) {
+ try {
+ b.setAccessible(true);
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ b.setAccessible(false);
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+ b1 = ByteBuffer.allocateDirect(8);
+ b2 = b1.duplicate();
+ b1.setAccessible(false);
+ ByteBuffer b3 = b1.asReadOnlyBuffer();
+ for (ByteBuffer b: new ByteBuffer[] { b1, b2, b3 }) {
+ b.duplicate();
+ assertFalse(b.isAccessible());
+ // even read-only buffers should fail with IllegalStateException
+ testFailForPutMethods(b);
+ testAsMethods(b);
+ testFailForGetMethods(b);
+ b.position(0);
+ b.limit(8);
+ try {
+ b.asCharBuffer().get(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asShortBuffer().get(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asIntBuffer().get(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asLongBuffer().get(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asFloatBuffer().get(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asDoubleBuffer().get(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+ b2.setAccessible(true);
+ for (ByteBuffer b: new ByteBuffer[] { b1, b2, b3 }) {
+ assertTrue(b.isAccessible());
+ b.position(0);
+ b.limit(8);
+ b.asCharBuffer().get(0);
+ b.asShortBuffer().get(0);
+ b.asIntBuffer().get(0);
+ b.asLongBuffer().get(0);
+ b.asFloatBuffer().get(0);
+ b.asDoubleBuffer().get(0);
+ if (!b.isReadOnly()) {
+ testPutMethods(b);
+ b.compact();
+ } else {
+ try {
+ b.put(0, (byte) 0);
+ fail();
+ } catch (ReadOnlyBufferException expected) {
+ }
+ }
+ testAsMethods(b);
+ testGetMethods(b);
+ }
+ }
+
+ private void testPutMethods(ByteBuffer b) {
+ b.position(0);
+ b.put((byte) 0);
+ b.put(0, (byte) 0);
+ b.put(new byte[1]);
+ b.put(new byte[1], 0, 1);
+ b.put(ByteBuffer.allocate(1));
+ b.putChar('a');
+ b.putChar(0, 'a');
+ b.position(0);
+ b.putDouble(0);
+ b.putDouble(0, 0);
+ b.position(0);
+ b.putFloat(0);
+ b.putFloat(0, 0);
+ b.putInt(0);
+ b.putInt(0, 0);
+ b.position(0);
+ b.putLong(0);
+ b.putLong(0, 0);
+ b.position(0);
+ b.putShort((short) 0);
+ b.putShort(0, (short) 0);
+ }
+
+ private void testFailForPutMethods(ByteBuffer b) {
+ try {
+ b.put((byte) 0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.put(0, (byte) 0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.put(new byte[1]);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.put(new byte[1], 0, 1);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.put(ByteBuffer.allocate(1));
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putChar('a');
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putChar(0, 'a');
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putDouble(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putDouble(0, 0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putFloat(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putFloat(0, 0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putInt(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putInt(0, 0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putLong(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putLong(0, 0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putShort((short) 0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.putShort(0, (short) 0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ private void testGetMethods(ByteBuffer b) {
+ b.position(0);
+ b.get();
+ b.get(0);
+ b.get(new byte[1]);
+ b.get(new byte[1], 0, 1);
+ b.getChar();
+ b.getChar(0);
+ b.position(0);
+ b.getDouble();
+ b.getDouble(0);
+ b.position(0);
+ b.getFloat();
+ b.getFloat(0);
+ b.getInt();
+ b.getInt(0);
+ b.position(0);
+ b.getLong();
+ b.getLong(0);
+ b.position(0);
+ b.getShort();
+ b.getShort(0);
+ }
+
+ private void testFailForGetMethods(ByteBuffer b) {
+ try {
+ b.get();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.get(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.get(new byte[1]);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.get(new byte[1], 0, 1);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getChar();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getChar(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getDouble();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getDouble(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getFloat();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getFloat(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getInt();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getInt(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getLong();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getLong(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getShort();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.getShort(0);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ private void testAsMethods(ByteBuffer b) {
+ b.asCharBuffer();
+ b.asDoubleBuffer();
+ b.asFloatBuffer();
+ b.asIntBuffer();
+ b.asLongBuffer();
+ b.asReadOnlyBuffer();
+ b.asShortBuffer();
+ }
+
+ private void testFailForAsMethods(ByteBuffer b) {
+ try {
+ b.asCharBuffer();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asDoubleBuffer();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asFloatBuffer();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asIntBuffer();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asLongBuffer();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asReadOnlyBuffer();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ try {
+ b.asShortBuffer();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
}
diff --git a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java
index 13757d2..efcfece 100644
--- a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java
@@ -16,9 +16,19 @@
package libcore.java.nio.channels;
+import java.io.IOException;
import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
import java.nio.channels.DatagramChannel;
+import java.nio.channels.UnresolvedAddressException;
+import java.util.Enumeration;
+import java.util.Set;
public class DatagramChannelTest extends junit.framework.TestCase {
public void test_read_intoReadOnlyByteArrays() throws Exception {
@@ -55,4 +65,110 @@ public class DatagramChannelTest extends junit.framework.TestCase {
dc.close();
}
}
+
+ public void testInitialState() throws Exception {
+ DatagramChannel dc = DatagramChannel.open();
+ try {
+ DatagramSocket socket = dc.socket();
+ assertFalse(socket.isBound());
+ assertFalse(socket.getBroadcast());
+ assertFalse(socket.isClosed());
+ assertFalse(socket.isConnected());
+ assertEquals(0, socket.getLocalPort());
+ assertTrue(socket.getLocalAddress().isAnyLocalAddress());
+ assertNull(socket.getLocalSocketAddress());
+ assertNull(socket.getInetAddress());
+ assertEquals(-1, socket.getPort());
+ assertNull(socket.getRemoteSocketAddress());
+ assertFalse(socket.getReuseAddress());
+
+ assertSame(dc, socket.getChannel());
+ } finally {
+ dc.close();
+ }
+ }
+
+ public void test_bind_unresolvedAddress() throws IOException {
+ DatagramChannel dc = DatagramChannel.open();
+ try {
+ dc.socket().bind(new InetSocketAddress("unresolvedname", 31415));
+ fail();
+ } catch (IOException expected) {
+ }
+
+ assertTrue(dc.isOpen());
+ assertFalse(dc.isConnected());
+
+ dc.close();
+ }
+
+ public void test_bind_any_IPv4() throws Exception {
+ test_bind_any(InetAddress.getByName("0.0.0.0"));
+ }
+
+ public void test_bind_any_IPv6() throws Exception {
+ test_bind_any(InetAddress.getByName("::"));
+ }
+
+ private void test_bind_any(InetAddress bindAddress) throws Exception {
+ DatagramChannel dc = DatagramChannel.open();
+ dc.socket().bind(new InetSocketAddress(bindAddress, 0));
+
+ assertTrue(dc.isOpen());
+ assertFalse(dc.isConnected());
+
+ InetSocketAddress actualAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
+ assertTrue(actualAddress.getAddress().isAnyLocalAddress());
+ assertTrue(actualAddress.getPort() > 0);
+
+ dc.close();
+ }
+
+ public void test_bind_loopback_IPv4() throws Exception {
+ test_bind(InetAddress.getByName("127.0.0.1"));
+ }
+
+ public void test_bind_loopback_IPv6() throws Exception {
+ test_bind(InetAddress.getByName("::1"));
+ }
+
+ public void test_bind_IPv4() throws Exception {
+ InetAddress bindAddress = getNonLoopbackNetworkInterfaceAddress(true /* ipv4 */);
+ test_bind(bindAddress);
+ }
+
+ public void test_bind_IPv6() throws Exception {
+ InetAddress bindAddress = getNonLoopbackNetworkInterfaceAddress(false /* ipv4 */);
+ test_bind(bindAddress);
+ }
+
+ private void test_bind(InetAddress bindAddress) throws IOException {
+ DatagramChannel dc = DatagramChannel.open();
+ dc.socket().bind(new InetSocketAddress(bindAddress, 0));
+
+ InetSocketAddress actualAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
+ assertEquals(bindAddress, actualAddress.getAddress());
+ assertTrue(actualAddress.getPort() > 0);
+
+ dc.close();
+ }
+
+ private static InetAddress getNonLoopbackNetworkInterfaceAddress(boolean ipv4) throws IOException {
+ Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+ while (networkInterfaces.hasMoreElements()) {
+ NetworkInterface networkInterface = networkInterfaces.nextElement();
+ if (networkInterface.isLoopback() || !networkInterface.isUp()) {
+ continue;
+ }
+ Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
+ while (inetAddresses.hasMoreElements()) {
+ InetAddress inetAddress = inetAddresses.nextElement();
+ if ( (ipv4 && inetAddress instanceof Inet4Address)
+ || (!ipv4 && inetAddress instanceof Inet6Address)) {
+ return inetAddress;
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/luni/src/test/java/libcore/java/nio/channels/FileChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/FileChannelTest.java
index 415ae0a..babbf41 100644
--- a/luni/src/test/java/libcore/java/nio/channels/FileChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/FileChannelTest.java
@@ -19,6 +19,8 @@ package libcore.java.nio.channels;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import libcore.io.IoUtils;
@@ -110,4 +112,121 @@ public class FileChannelTest extends junit.framework.TestCase {
assertEquals("hello world", new String(IoUtils.readFileAsString(tmp.getPath())));
}
+
+ public void test_position_writeAddsPadding() throws Exception {
+ byte[] initialBytes = "12345".getBytes("US-ASCII");
+ int initialFileSize = initialBytes.length; // 5
+ FileChannel fc = createFileContainingBytes(initialBytes);
+
+ int positionBeyondSize = 10;
+ fc.position(positionBeyondSize);
+ assertEquals(positionBeyondSize, fc.position());
+ assertEquals(initialFileSize, fc.size());
+
+ byte[] newBytes = "6789A".getBytes("US-ASCII");
+ fc.write(ByteBuffer.wrap(newBytes));
+
+ int expectedNewLength = positionBeyondSize + newBytes.length;
+ assertEquals(expectedNewLength, fc.position());
+ assertEquals(expectedNewLength, fc.size());
+
+ fc.close();
+ }
+
+ public void test_truncate_greaterThanSizeWithPositionChange() throws Exception {
+ byte[] initialBytes = "12345".getBytes("US-ASCII");
+ int initialFileSize = initialBytes.length; // 5
+ FileChannel fc = createFileContainingBytes(initialBytes);
+
+ int initialPosition = 40;
+ fc.position(initialPosition); // Should not affect the file size
+ assertEquals(initialPosition, fc.position());
+ assertEquals(initialFileSize, fc.size());
+
+ // truncateArg < position, truncateArg > initialFileSize: Should not affect the file size
+ // and should move the position.
+ int truncateArg = 10;
+ fc.truncate(truncateArg); // Should not affect the file size, but should move the position.
+ assertEquals(initialFileSize, fc.size());
+ // The RI does not behave properly here, according to the docs for truncate(), position()
+ // should now be the same as truncateArg.
+ assertEquals(truncateArg, fc.position());
+
+ fc.close();
+ }
+
+ public void test_truncate_greaterThanSizeWithoutPositionChange() throws Exception {
+ byte[] initialBytes = "123456789A".getBytes("US-ASCII");
+ int initialFileSize = initialBytes.length; // 10
+ FileChannel fc = createFileContainingBytes(initialBytes);
+
+ int initialPosition = 5;
+ fc.position(initialPosition);
+ assertEquals(initialPosition, fc.position());
+ assertEquals(initialFileSize, fc.size());
+
+ // truncateArg > position, truncateArg > initialFileSize: Should not affect the file size
+ // and should not move the position.
+ int truncateArg = 15;
+ fc.truncate(truncateArg);
+ assertEquals(initialFileSize, fc.size());
+ assertEquals(initialPosition, fc.position());
+
+ fc.close();
+ }
+
+ public void test_truncate_lessThanSizeWithPositionChange() throws Exception {
+ byte[] initialBytes = "123456789A".getBytes("US-ASCII");
+ int initialFileSize = initialBytes.length; // 10
+ FileChannel fc = createFileContainingBytes(initialBytes);
+
+ int initialPosition = initialFileSize;
+ fc.position(initialPosition);
+ assertEquals(initialPosition, fc.position());
+ assertEquals(initialFileSize, fc.size());
+
+ int truncateArg = 5;
+ // truncateArg < initialPosition, truncateArg < initialFileSize: Should affect the file size
+ // and should move the position.
+ fc.truncate(truncateArg);
+ assertEquals(truncateArg, fc.size());
+ assertEquals(truncateArg, fc.position());
+
+ fc.close();
+ }
+
+ public void test_truncate_lessThanSizeWithoutPositionChange() throws Exception {
+ byte[] initialBytes = "123456789A".getBytes("US-ASCII");
+ int initialFileSize = initialBytes.length; // 10
+ FileChannel fc = createFileContainingBytes(initialBytes);
+
+ int initialPosition = 4;
+ fc.position(initialPosition);
+ assertEquals(initialPosition, fc.position());
+ assertEquals(initialFileSize, fc.size());
+
+ int truncateArg = 5;
+ // truncateArg > initialPosition, truncateArg < initialFileSize: Should affect the file size
+ // and should not move the position.
+ fc.truncate(truncateArg);
+ assertEquals(truncateArg, fc.size());
+ assertEquals(initialPosition, fc.position());
+
+ fc.close();
+ }
+
+ private static FileChannel createFileContainingBytes(byte[] bytes) throws IOException {
+ File tmp = File.createTempFile("FileChannelTest", "tmp");
+ FileOutputStream fos = new FileOutputStream(tmp, true);
+ FileChannel fc = fos.getChannel();
+ fc.write(ByteBuffer.wrap(bytes));
+ fc.close();
+
+ assertEquals(bytes.length, tmp.length());
+
+ fc = new RandomAccessFile(tmp, "rw").getChannel();
+ assertEquals(bytes.length, fc.size());
+
+ return fc;
+ }
}
diff --git a/luni/src/test/java/libcore/java/nio/channels/FileIOInterruptTest.java b/luni/src/test/java/libcore/java/nio/channels/FileIOInterruptTest.java
new file mode 100644
index 0000000..02c6f3b
--- /dev/null
+++ b/luni/src/test/java/libcore/java/nio/channels/FileIOInterruptTest.java
@@ -0,0 +1,709 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.java.nio.channels;
+
+import junit.framework.TestCase;
+
+import android.system.OsConstants;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InterruptedIOException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousCloseException;
+import java.nio.channels.ClosedByInterruptException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import libcore.io.Libcore;
+
+import static libcore.io.IoUtils.closeQuietly;
+
+/**
+ * A test for file interrupt behavior. Because forcing a real file to block on read or write is
+ * difficult this test uses Unix FIFO / Named Pipes. FIFOs appear to Java as files but the test
+ * has more control over the available data. Reader will block until the other end writes, and
+ * writers can also be made to block.
+ *
+ * <p>Using FIFOs has a few drawbacks:
+ * <ol>
+ * <li>FIFOs are not supported from Java or the command-line on Android, so this test includes
+ * native code to create the FIFO.
+ * <li>FIFOs will not open() until there is both a reader and a writer of the FIFO; each test must
+ * always attach both ends or experience a blocked test.
+ * <li>FIFOs are not supported on some file systems. e.g. VFAT, so the test has to be particular
+ * about the temporary directory it uses to hold the FIFO.
+ * <li>Writes to FIFOs are buffered by the OS which makes blocking behavior more difficult to
+ * induce. See {@link ChannelWriter} and {@link StreamWriter}.
+ * </ol>
+ */
+public class FileIOInterruptTest extends TestCase {
+
+ private static File VOGAR_DEVICE_TEMP_DIR = new File("/data/data/file_io_interrupt_test");
+
+ private File fifoFile;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // This test relies on a FIFO file. The file system must support FIFOs, so we check the path.
+ String tmpDirName = System.getProperty("java.io.tmpdir");
+ File tmpDir;
+ if (tmpDirName.startsWith("/sdcard")) {
+ // Vogar execution on device runs in /sdcard. Unfortunately the file system used does not
+ // support FIFOs so the test must use one that is more likely to work.
+ if (!VOGAR_DEVICE_TEMP_DIR.exists()) {
+ assertTrue(VOGAR_DEVICE_TEMP_DIR.mkdir());
+ }
+ VOGAR_DEVICE_TEMP_DIR.deleteOnExit();
+ tmpDir = VOGAR_DEVICE_TEMP_DIR;
+ } else {
+ tmpDir = new File(tmpDirName);
+ }
+ fifoFile = new File(tmpDir, "fifo_file.tmp");
+ if (fifoFile.exists()) {
+ fifoFile.delete();
+ }
+ fifoFile.deleteOnExit();
+
+ // Create the fifo. This will throw an exception if the file system does not support it.
+ Libcore.os.mkfifo(fifoFile.getAbsolutePath(), OsConstants.S_IRWXU);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ fifoFile.delete();
+ VOGAR_DEVICE_TEMP_DIR.delete();
+
+ // Clear the interrupted state, if set.
+ Thread.interrupted();
+ }
+
+ public void testStreamRead_exceptionWhenAlreadyClosed() throws Exception {
+ FifoWriter fifoWriter = new FifoWriter(fifoFile);
+ fifoWriter.start();
+
+ FileInputStream fis = new FileInputStream(fifoFile);
+ fis.close();
+
+ byte[] buffer = new byte[10];
+ try {
+ fis.read(buffer);
+ fail();
+ } catch (IOException expected) {
+ assertSame(IOException.class, expected.getClass());
+ }
+
+ fifoWriter.tidyUp();
+ }
+
+ // This test fails on the RI: close() does not wake up a blocking FileInputStream.read() call.
+ public void testStreamRead_exceptionOnCloseWhenBlocked() throws Exception {
+ FifoWriter fifoWriter = new FifoWriter(fifoFile);
+ fifoWriter.start();
+
+ FileInputStream fis = new FileInputStream(fifoFile);
+ StreamReader streamReader = new StreamReader(fis);
+ Thread streamReaderThread = createAndStartThread("StreamReader", streamReader);
+
+ // Delay until we can be fairly sure the reader thread is blocking.
+ streamReader.waitForThreadToBlock();
+
+ // Now close the OutputStream to see what happens.
+ fis.close();
+
+ // Test for expected behavior in the reader thread.
+ waitToDie(streamReaderThread);
+ assertSame(InterruptedIOException.class, streamReader.ioe.getClass());
+ assertFalse(streamReader.wasInterrupted);
+
+ // Tidy up the writer thread.
+ fifoWriter.tidyUp();
+ }
+
+ public void testStreamWrite_exceptionWhenAlreadyClosed() throws Exception {
+ FifoReader fifoReader = new FifoReader(fifoFile);
+ fifoReader.start();
+
+ FileOutputStream fos = new FileOutputStream(fifoFile);
+ byte[] buffer = new byte[10];
+ fos.close();
+
+ try {
+ fos.write(buffer);
+ fail();
+ } catch (IOException expected) {
+ assertSame(IOException.class, expected.getClass());
+ }
+
+ fifoReader.tidyUp();
+ }
+
+ // This test fails on the RI: close() does not wake up a blocking FileInputStream.write() call.
+ public void testStreamWrite_exceptionOnCloseWhenBlocked() throws Exception {
+ FifoReader fifoReader = new FifoReader(fifoFile);
+ fifoReader.start();
+
+ FileOutputStream fos = new FileOutputStream(fifoFile);
+ StreamWriter streamWriter = new StreamWriter(fos);
+ Thread streamWriterThread = createAndStartThread("StreamWriter", streamWriter);
+
+ // Delay until we can be fairly sure the writer thread is blocking.
+ streamWriter.waitForThreadToBlock();
+
+ // Now close the OutputStream to see what happens.
+ fos.close();
+
+ // Test for expected behavior in the writer thread.
+ waitToDie(streamWriterThread);
+ assertSame(InterruptedIOException.class, streamWriter.ioe.getClass());
+ assertFalse(streamWriter.wasInterrupted);
+
+ // Tidy up the reader thread.
+ fifoReader.tidyUp();
+ }
+
+ public void testChannelRead_exceptionWhenAlreadyClosed() throws Exception {
+ testChannelRead_exceptionWhenAlreadyClosed(ChannelReader.Method.READ);
+ }
+
+ public void testChannelReadV_exceptionWhenAlreadyClosed() throws Exception {
+ testChannelRead_exceptionWhenAlreadyClosed(ChannelReader.Method.READV);
+ }
+
+ private void testChannelRead_exceptionWhenAlreadyClosed(ChannelReader.Method method)
+ throws Exception {
+ FifoWriter fifoWriter = new FifoWriter(fifoFile);
+ fifoWriter.start();
+ FileInputStream fis = new FileInputStream(fifoFile);
+ FileChannel fileInputChannel = fis.getChannel();
+ fileInputChannel.close();
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(10);
+ try {
+ if (method == ChannelReader.Method.READ) {
+ fileInputChannel.read(buffer);
+ } else {
+ ByteBuffer buffer2 = ByteBuffer.allocateDirect(10);
+ fileInputChannel.read(new ByteBuffer[] { buffer, buffer2});
+ }
+ fail();
+ } catch (IOException expected) {
+ assertSame(ClosedChannelException.class, expected.getClass());
+ }
+
+ fifoWriter.tidyUp();
+ }
+
+ public void testChannelRead_exceptionWhenAlreadyInterrupted() throws Exception {
+ testChannelRead_exceptionWhenAlreadyInterrupted(ChannelReader.Method.READ);
+ }
+
+ public void testChannelReadV_exceptionWhenAlreadyInterrupted() throws Exception {
+ testChannelRead_exceptionWhenAlreadyInterrupted(ChannelReader.Method.READV);
+ }
+
+ private void testChannelRead_exceptionWhenAlreadyInterrupted(ChannelReader.Method method)
+ throws Exception {
+ FifoWriter fifoWriter = new FifoWriter(fifoFile);
+ fifoWriter.start();
+ FileInputStream fis = new FileInputStream(fifoFile);
+ FileChannel fileInputChannel = fis.getChannel();
+
+ Thread.currentThread().interrupt();
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(10);
+ try {
+ if (method == ChannelReader.Method.READ) {
+ fileInputChannel.read(buffer);
+ } else {
+ ByteBuffer buffer2 = ByteBuffer.allocateDirect(10);
+ fileInputChannel.read(new ByteBuffer[] { buffer, buffer2});
+ }
+ fail();
+ } catch (IOException expected) {
+ assertSame(ClosedByInterruptException.class, expected.getClass());
+ }
+
+ // Check but also clear the interrupted status, so we can wait for the FifoWriter thread in
+ // tidyUp().
+ assertTrue(Thread.interrupted());
+
+ fifoWriter.tidyUp();
+ }
+
+ public void testChannelRead_exceptionOnCloseWhenBlocked() throws Exception {
+ testChannelRead_exceptionOnCloseWhenBlocked(ChannelReader.Method.READ);
+ }
+
+ public void testChannelReadV_exceptionOnCloseWhenBlocked() throws Exception {
+ testChannelRead_exceptionOnCloseWhenBlocked(ChannelReader.Method.READV);
+ }
+
+ private void testChannelRead_exceptionOnCloseWhenBlocked(ChannelReader.Method method)
+ throws Exception {
+ FifoWriter fifoWriter = new FifoWriter(fifoFile);
+ fifoWriter.start();
+ FileInputStream fis = new FileInputStream(fifoFile);
+ FileChannel fileInputChannel = fis.getChannel();
+
+ ChannelReader channelReader = new ChannelReader(fileInputChannel, method);
+ Thread channelReaderThread = createAndStartThread("ChannelReader", channelReader);
+
+ // Delay until we can be fairly sure the reader thread is blocking.
+ channelReader.waitForThreadToBlock();
+
+ // Now close the FileChannel to see what happens.
+ fileInputChannel.close();
+
+ // Test for expected behavior in the reader thread.
+ waitToDie(channelReaderThread);
+ assertSame(AsynchronousCloseException.class, channelReader.ioe.getClass());
+ assertFalse(channelReader.wasInterrupted);
+
+ // Tidy up the writer thread.
+ fifoWriter.tidyUp();
+ }
+
+ public void testChannelRead_exceptionOnInterrupt() throws Exception {
+ testChannelRead_exceptionOnInterrupt(ChannelReader.Method.READ);
+ }
+
+ public void testChannelReadV_exceptionOnInterrupt() throws Exception {
+ testChannelRead_exceptionOnInterrupt(ChannelReader.Method.READV);
+ }
+
+ private void testChannelRead_exceptionOnInterrupt(ChannelReader.Method method) throws Exception {
+ FifoWriter fifoWriter = new FifoWriter(fifoFile);
+ fifoWriter.start();
+ FileChannel fileChannel = new FileInputStream(fifoFile).getChannel();
+
+ ChannelReader channelReader = new ChannelReader(fileChannel, method);
+ Thread channelReaderThread = createAndStartThread("ChannelReader", channelReader);
+
+ // Delay until we can be fairly sure the reader thread is blocking.
+ channelReader.waitForThreadToBlock();
+
+ // Now interrupt the reader thread to see what happens.
+ channelReaderThread.interrupt();
+
+ // Test for expected behavior in the reader thread.
+ waitToDie(channelReaderThread);
+ assertSame(ClosedByInterruptException.class, channelReader.ioe.getClass());
+ assertTrue(channelReader.wasInterrupted);
+
+ // Tidy up the writer thread.
+ fifoWriter.tidyUp();
+ }
+
+ public void testChannelWrite_exceptionWhenAlreadyClosed() throws Exception {
+ testChannelWrite_exceptionWhenAlreadyClosed(ChannelWriter.Method.WRITE);
+ }
+
+ public void testChannelWriteV_exceptionWhenAlreadyClosed() throws Exception {
+ testChannelWrite_exceptionWhenAlreadyClosed(ChannelWriter.Method.WRITEV);
+ }
+
+ private void testChannelWrite_exceptionWhenAlreadyClosed(ChannelWriter.Method method)
+ throws Exception {
+ FifoReader fifoReader = new FifoReader(fifoFile);
+ fifoReader.start();
+ FileChannel fileOutputChannel = new FileOutputStream(fifoFile).getChannel();
+ fileOutputChannel.close();
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(10);
+ try {
+ if (method == ChannelWriter.Method.WRITE) {
+ fileOutputChannel.write(buffer);
+ } else {
+ ByteBuffer buffer2 = ByteBuffer.allocateDirect(10);
+ fileOutputChannel.write(new ByteBuffer[] { buffer, buffer2 });
+ }
+ fail();
+ } catch (IOException expected) {
+ assertSame(ClosedChannelException.class, expected.getClass());
+ }
+
+ fifoReader.tidyUp();
+ }
+
+ public void testChannelWrite_exceptionWhenAlreadyInterrupted() throws Exception {
+ testChannelWrite_exceptionWhenAlreadyInterrupted(ChannelWriter.Method.WRITE);
+ }
+
+ public void testChannelWriteV_exceptionWhenAlreadyInterrupted() throws Exception {
+ testChannelWrite_exceptionWhenAlreadyInterrupted(ChannelWriter.Method.WRITEV);
+ }
+
+ private void testChannelWrite_exceptionWhenAlreadyInterrupted(ChannelWriter.Method method)
+ throws Exception {
+ FifoReader fifoReader = new FifoReader(fifoFile);
+ fifoReader.start();
+ FileOutputStream fos = new FileOutputStream(fifoFile);
+ FileChannel fileInputChannel = fos.getChannel();
+
+ Thread.currentThread().interrupt();
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(10);
+ try {
+ if (method == ChannelWriter.Method.WRITE) {
+ fileInputChannel.write(buffer);
+ } else {
+ ByteBuffer buffer2 = ByteBuffer.allocateDirect(10);
+ fileInputChannel.write(new ByteBuffer[] { buffer, buffer2 });
+ }
+ fail();
+ } catch (IOException expected) {
+ assertSame(ClosedByInterruptException.class, expected.getClass());
+ }
+
+ // Check but also clear the interrupted status, so we can wait for the FifoReader thread in
+ // tidyUp().
+ assertTrue(Thread.interrupted());
+
+ fifoReader.tidyUp();
+ }
+
+ public void testChannelWrite_exceptionOnCloseWhenBlocked() throws Exception {
+ testChannelWrite_exceptionOnCloseWhenBlocked(ChannelWriter.Method.WRITE);
+ }
+
+ public void testChannelWriteV_exceptionOnCloseWhenBlocked() throws Exception {
+ testChannelWrite_exceptionOnCloseWhenBlocked(ChannelWriter.Method.WRITEV);
+ }
+
+ private void testChannelWrite_exceptionOnCloseWhenBlocked(ChannelWriter.Method method)
+ throws Exception {
+ FifoReader fifoReader = new FifoReader(fifoFile);
+ fifoReader.start();
+ FileChannel fileOutputChannel = new FileOutputStream(fifoFile).getChannel();
+
+ ChannelWriter channelWriter = new ChannelWriter(fileOutputChannel, method);
+ Thread channelWriterThread = createAndStartThread("ChannelWriter", channelWriter);
+
+ // Delay until we can be fairly sure the writer thread is blocking.
+ channelWriter.waitForThreadToBlock();
+
+ // Now close the channel to see what happens.
+ fileOutputChannel.close();
+
+ // Test for expected behavior in the writer thread.
+ waitToDie(channelWriterThread);
+ // The RI throws ChannelClosedException. AsynchronousCloseException is more correct according to
+ // the docs.
+ assertSame(AsynchronousCloseException.class, channelWriter.ioe.getClass());
+ assertFalse(channelWriter.wasInterrupted);
+
+ // Tidy up the writer thread.
+ fifoReader.tidyUp();
+ }
+
+ public void testChannelWrite_exceptionOnInterrupt() throws Exception {
+ testChannelWrite_exceptionOnInterrupt(ChannelWriter.Method.WRITE);
+ }
+
+ public void testChannelWriteV_exceptionOnInterrupt() throws Exception {
+ testChannelWrite_exceptionOnInterrupt(ChannelWriter.Method.WRITEV);
+ }
+
+ private void testChannelWrite_exceptionOnInterrupt(ChannelWriter.Method method) throws Exception {
+ FifoReader fifoReader = new FifoReader(fifoFile);
+ fifoReader.start();
+
+ FileChannel fileChannel = new FileOutputStream(fifoFile).getChannel();
+ ChannelWriter channelWriter = new ChannelWriter(fileChannel, method);
+ Thread channelWriterThread = createAndStartThread("ChannelWriter", channelWriter);
+
+ // Delay until we can be fairly sure the writer thread is blocking.
+ channelWriter.waitForThreadToBlock();
+
+ // Now interrupt the writer thread to see what happens.
+ channelWriterThread.interrupt();
+
+ // Test for expected behavior in the writer thread.
+ waitToDie(channelWriterThread);
+ assertSame(ClosedByInterruptException.class, channelWriter.ioe.getClass());
+ assertTrue(channelWriter.wasInterrupted);
+
+ // Tidy up the reader thread.
+ fifoReader.tidyUp();
+ }
+
+ private static class StreamReader implements Runnable {
+
+ private final FileInputStream inputStream;
+ volatile boolean started;
+ volatile IOException ioe;
+ volatile boolean wasInterrupted;
+
+ StreamReader(FileInputStream inputStream) {
+ this.inputStream = inputStream;
+ }
+
+ @Override
+ public void run() {
+ byte[] buffer = new byte[10];
+ try {
+ started = true;
+ int bytesRead = inputStream.read(buffer);
+ fail("This isn't supposed to happen: read() returned: " + bytesRead);
+ } catch (IOException e) {
+ this.ioe = e;
+ }
+ wasInterrupted = Thread.interrupted();
+ }
+
+ public void waitForThreadToBlock() {
+ for (int i = 0; i < 10 && !started; i++) {
+ delay(100);
+ }
+ assertTrue(started);
+ // Just give it some more time to start blocking.
+ delay(100);
+ }
+ }
+
+ private static class StreamWriter implements Runnable {
+
+ private final FileOutputStream outputStream;
+ volatile int bytesWritten;
+ volatile IOException ioe;
+ volatile boolean wasInterrupted;
+
+ StreamWriter(FileOutputStream outputStream) {
+ this.outputStream = outputStream;
+ }
+
+ @Override
+ public void run() {
+ // Writes to FIFOs are buffered. We try to fill the buffer and induce blocking (the
+ // buffer is typically 64k).
+ byte[] buffer = new byte[10000];
+ while (true) {
+ try {
+ outputStream.write(buffer);
+ bytesWritten += buffer.length;
+ } catch (IOException e) {
+ this.ioe = e;
+ break;
+ }
+ wasInterrupted = Thread.interrupted();
+ }
+ }
+
+ public void waitForThreadToBlock() {
+ int lastCount = bytesWritten;
+ for (int i = 0; i < 10; i++) {
+ delay(500);
+ int newBytesWritten = bytesWritten;
+ if (newBytesWritten > 0 && lastCount == newBytesWritten) {
+ // The thread is probably blocking.
+ return;
+ }
+ lastCount = bytesWritten;
+ }
+ fail("Writer never started blocking. Bytes written: " + bytesWritten);
+ }
+ }
+
+ private static class ChannelReader implements Runnable {
+ enum Method {
+ READ,
+ READV,
+ }
+
+ private final FileChannel channel;
+ private final Method method;
+ volatile boolean started;
+ volatile IOException ioe;
+ volatile boolean wasInterrupted;
+
+ ChannelReader(FileChannel channel, Method method) {
+ this.channel = channel;
+ this.method = method;
+ }
+
+ @Override
+ public void run() {
+ ByteBuffer buffer = ByteBuffer.allocateDirect(10);
+ try {
+ started = true;
+ if (method == Method.READ) {
+ channel.read(buffer);
+ } else {
+ ByteBuffer buffer2 = ByteBuffer.allocateDirect(10);
+ channel.read(new ByteBuffer[] { buffer, buffer2 });
+ }
+ fail("All tests should block until an exception");
+ } catch (IOException e) {
+ this.ioe = e;
+ }
+ wasInterrupted = Thread.interrupted();
+ }
+
+ public void waitForThreadToBlock() {
+ for (int i = 0; i < 10 && !started; i++) {
+ delay(100);
+ }
+ assertTrue(started);
+ // Just give it some more time to start blocking.
+ delay(100);
+ }
+ }
+
+ private static class ChannelWriter implements Runnable {
+ enum Method {
+ WRITE,
+ WRITEV,
+ }
+
+ private final FileChannel channel;
+ private final Method method;
+ volatile int bytesWritten;
+ volatile IOException ioe;
+ volatile boolean wasInterrupted;
+
+ ChannelWriter(FileChannel channel, Method method) {
+ this.channel = channel;
+ this.method = method;
+ }
+
+ @Override
+ public void run() {
+ ByteBuffer buffer1 = ByteBuffer.allocateDirect(10000);
+ ByteBuffer buffer2 = ByteBuffer.allocateDirect(10000);
+ // Writes to FIFOs are buffered. We try to fill the buffer and induce blocking (the
+ // buffer is typically 64k).
+ while (true) {
+ // Make the buffers look non-empty.
+ buffer1.position(0).limit(buffer1.capacity());
+ buffer2.position(0).limit(buffer2.capacity());
+ try {
+ if (method == Method.WRITE) {
+ bytesWritten += channel.write(buffer1);
+ } else {
+ bytesWritten += channel.write(new ByteBuffer[]{ buffer1, buffer2 });
+ }
+ } catch (IOException e) {
+ this.ioe = e;
+ break;
+ }
+ }
+ wasInterrupted = Thread.interrupted();
+ }
+
+ public void waitForThreadToBlock() {
+ int lastCount = bytesWritten;
+ for (int i = 0; i < 10; i++) {
+ delay(500);
+ int newBytesWritten = bytesWritten;
+ if (newBytesWritten > 0 && lastCount == newBytesWritten) {
+ // The thread is probably blocking.
+ return;
+ }
+ lastCount = bytesWritten;
+ }
+ fail("Writer never started blocking. Bytes written: " + bytesWritten);
+ }
+ }
+
+ /**
+ * Opens a FIFO for writing. Exists to unblock the other end of the FIFO.
+ */
+ private static class FifoWriter extends Thread {
+
+ private final File file;
+ private FileOutputStream fos;
+
+ public FifoWriter(File file) {
+ super("FifoWriter");
+ this.file = file;
+ }
+
+ @Override
+ public void run() {
+ try {
+ fos = new FileOutputStream(file);
+ } catch (IOException ignored) {
+ }
+ }
+
+ public void tidyUp() {
+ FileIOInterruptTest.waitToDie(this);
+ closeQuietly(fos);
+ }
+ }
+
+ /**
+ * Opens a FIFO for reading. Exists to unblock the other end of the FIFO.
+ */
+ private static class FifoReader extends Thread {
+
+ private final File file;
+ private FileInputStream fis;
+
+ public FifoReader(File file) {
+ super("FifoReader");
+ this.file = file;
+ }
+
+ @Override
+ public void run() {
+ try {
+ fis = new FileInputStream(file);
+ } catch (IOException ignored) {
+ }
+ }
+
+ public void tidyUp() {
+ FileIOInterruptTest.waitToDie(this);
+ closeQuietly(fis);
+ }
+ }
+
+ private static Thread createAndStartThread(String name, Runnable runnable) {
+ Thread t = new Thread(runnable, name);
+ t.setDaemon(true);
+ t.start();
+ return t;
+ }
+
+ private static void waitToDie(Thread thread) {
+ // Protect against this thread already being interrupted, which would prevent the test waiting
+ // for the requested time.
+ assertFalse(Thread.currentThread().isInterrupted());
+ try {
+ thread.join(5000);
+ } catch (InterruptedException ignored) {
+ }
+
+ if (thread.isAlive()) {
+ fail("Thread \"" + thread.getName() + "\" did not exit.");
+ }
+ }
+
+ private static void delay(int millis) {
+ // Protect against this thread being interrupted, which would prevent us waiting.
+ assertFalse(Thread.currentThread().isInterrupted());
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException ignored) {
+ }
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java
index 6560a7b..f849c33 100644
--- a/luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java
@@ -17,9 +17,7 @@
package libcore.java.nio.channels;
-import dalvik.annotation.BrokenTest;
import java.io.IOException;
-import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
@@ -198,14 +196,12 @@ public class OldSocketChannelTest extends TestCase {
// expected
}
- SocketChannel channel1IP = null;
try {
- channel1IP = SocketChannel.open(null);
+ SocketChannel.open(null);
fail("Should throw an IllegalArgumentException");
} catch (IllegalArgumentException e) {
// correct
}
- assertNull(channel1IP);
}
private void ensureServerClosed() throws IOException {
@@ -238,7 +234,7 @@ public class OldSocketChannelTest extends TestCase {
return connected;
}
- @BrokenTest("Occasionally fail in CTS, but works in CoreTestRunner")
+ // Broken Test: Occasionally fail in CTS, but works in CoreTestRunner
public void test_writeLjava_nio_ByteBuffer_Nonblocking_HugeData() throws IOException {
// initialize write content
ByteBuffer writeContent = ByteBuffer.allocate(CAPACITY_HUGE);
@@ -355,48 +351,59 @@ public class OldSocketChannelTest extends TestCase {
isConstructorCalled = true;
}
+ @Override
public Socket socket() {
return null;
}
+ @Override
public boolean isConnected() {
return false;
}
+ @Override
public boolean isConnectionPending() {
return false;
}
+ @Override
public boolean connect(SocketAddress address) throws IOException {
return false;
}
+ @Override
public boolean finishConnect() throws IOException {
return false;
}
+ @Override
public int read(ByteBuffer target) throws IOException {
return 0;
}
+ @Override
public long read(ByteBuffer[] targets, int offset, int length)
throws IOException {
return 0;
}
+ @Override
public int write(ByteBuffer source) throws IOException {
return 0;
}
+ @Override
public long write(ByteBuffer[] sources, int offset, int length)
throws IOException {
return 0;
}
+ @Override
protected void implCloseSelectableChannel() throws IOException {
// empty
}
+ @Override
protected void implConfigureBlocking(boolean blockingMode)
throws IOException {
// empty
diff --git a/luni/src/test/java/libcore/java/nio/channels/SelectorTest.java b/luni/src/test/java/libcore/java/nio/channels/SelectorTest.java
index b45f8e1..c5f449e 100644
--- a/luni/src/test/java/libcore/java/nio/channels/SelectorTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/SelectorTest.java
@@ -15,6 +15,7 @@
*/
package libcore.java.nio.channels;
+import android.system.OsConstants;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
@@ -26,9 +27,8 @@ import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import libcore.io.Libcore;
-import libcore.io.OsConstants;
import junit.framework.TestCase;
+import libcore.io.Libcore;
import tests.net.StuckServer;
public class SelectorTest extends TestCase {
@@ -93,11 +93,15 @@ public class SelectorTest extends TestCase {
// http://code.google.com/p/android/issues/detail?id=15388
public void testInterrupted() throws IOException {
Selector selector = Selector.open();
+ Thread.currentThread().interrupt();
try {
- Thread.currentThread().interrupt();
int count = selector.select();
assertEquals(0, count);
+ assertTrue(Thread.currentThread().isInterrupted());
} finally {
+ // Clear the interrupted thread state so that it does not interfere with later tests.
+ Thread.interrupted();
+
selector.close();
}
}
diff --git a/luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java
index e66096c..1178b70 100644
--- a/luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java
@@ -16,7 +16,18 @@
package libcore.java.nio.channels;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.ServerSocket;
+import java.net.SocketException;
+import java.nio.channels.ClosedChannelException;
import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.UnresolvedAddressException;
+import java.util.Enumeration;
+import java.util.Set;
public class ServerSocketChannelTest extends junit.framework.TestCase {
// http://code.google.com/p/android/issues/detail?id=16579
@@ -31,4 +42,107 @@ public class ServerSocketChannelTest extends junit.framework.TestCase {
ssc.close();
}
}
+
+ /** Checks the state of the ServerSocketChannel and associated ServerSocket after open() */
+ public void test_open_initialState() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ try {
+ assertNull(ssc.socket().getLocalSocketAddress());
+
+ ServerSocket socket = ssc.socket();
+ assertFalse(socket.isBound());
+ assertFalse(socket.isClosed());
+ assertEquals(-1, socket.getLocalPort());
+ assertNull(socket.getLocalSocketAddress());
+ assertNull(socket.getInetAddress());
+ assertTrue(socket.getReuseAddress());
+
+ assertSame(ssc, socket.getChannel());
+ } finally {
+ ssc.close();
+ }
+ }
+
+ public void test_bind_unresolvedAddress() throws IOException {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ try {
+ ssc.socket().bind(new InetSocketAddress("unresolvedname", 31415));
+ fail();
+ } catch (SocketException expected) {
+ }
+
+ assertNull(ssc.socket().getLocalSocketAddress());
+ assertTrue(ssc.isOpen());
+
+ ssc.close();
+ }
+
+ public void test_bind_nullBindsToAll() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(null);
+ InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
+ assertTrue(boundAddress.getAddress().isAnyLocalAddress());
+ assertFalse(boundAddress.getAddress().isLinkLocalAddress());
+ assertFalse(boundAddress.getAddress().isLoopbackAddress());
+
+ // Attempt to connect to the "any" address.
+ assertTrue(canConnect(boundAddress));
+
+ // Go through all local IPs and try to connect to each in turn - all should succeed.
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface nic = interfaces.nextElement();
+ Enumeration<InetAddress> inetAddresses = nic.getInetAddresses();
+ while (inetAddresses.hasMoreElements()) {
+ InetSocketAddress address =
+ new InetSocketAddress(inetAddresses.nextElement(), boundAddress.getPort());
+ assertTrue(canConnect(address));
+ }
+ }
+
+ ssc.close();
+ }
+
+ public void test_bind_loopback() throws Exception {
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ ssc.socket().bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+ InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
+ assertFalse(boundAddress.getAddress().isAnyLocalAddress());
+ assertFalse(boundAddress.getAddress().isLinkLocalAddress());
+ assertTrue(boundAddress.getAddress().isLoopbackAddress());
+
+ // Attempt to connect to the "loopback" address. Note: There can be several loopback
+ // addresses, such as 127.0.0.1 (IPv4) and 0:0:0:0:0:0:0:1 (IPv6) and only one will be
+ // bound.
+ InetSocketAddress loopbackAddress =
+ new InetSocketAddress(InetAddress.getLoopbackAddress(), boundAddress.getPort());
+ assertTrue(canConnect(loopbackAddress));
+
+ // Go through all local IPs and try to connect to each in turn - all should fail except
+ // for the loopback.
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface nic = interfaces.nextElement();
+ Enumeration<InetAddress> inetAddresses = nic.getInetAddresses();
+ while (inetAddresses.hasMoreElements()) {
+ InetSocketAddress address =
+ new InetSocketAddress(inetAddresses.nextElement(), boundAddress.getPort());
+ if (!address.equals(loopbackAddress)) {
+ assertFalse(canConnect(address));
+ }
+ }
+ }
+
+ ssc.close();
+ }
+
+ private static boolean canConnect(InetSocketAddress address) {
+ try {
+ SocketChannel socketChannel = SocketChannel.open(address);
+ socketChannel.close();
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
index 6ab91ab..a54b30a 100644
--- a/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
@@ -16,26 +16,37 @@
package libcore.java.nio.channels;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.net.ConnectException;
+import java.net.Socket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SocketChannel;
import java.nio.channels.Selector;
import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
+import java.nio.channels.UnresolvedAddressException;
+import java.util.Set;
+
import tests.io.MockOs;
-import static libcore.io.OsConstants.*;
+
+import static android.system.OsConstants.*;
public class SocketChannelTest extends junit.framework.TestCase {
+
private final MockOs mockOs = new MockOs();
- @Override public void setUp() throws Exception {
+ @Override
+ public void setUp() throws Exception {
mockOs.install();
}
- @Override protected void tearDown() throws Exception {
+ @Override
+ protected void tearDown() throws Exception {
mockOs.uninstall();
}
@@ -61,6 +72,7 @@ public class SocketChannelTest extends junit.framework.TestCase {
}
}
+ // https://code.google.com/p/android/issues/detail?id=56684
public void test_56684() throws Exception {
mockOs.enqueueFault("connect", ENETUNREACH);
@@ -78,7 +90,188 @@ public class SocketChannelTest extends junit.framework.TestCase {
try {
sc.finishConnect();
+ fail();
} catch (ClosedChannelException expected) {
}
}
+
+ /** Checks that closing a Socket's output stream also closes the Socket and SocketChannel. */
+ public void test_channelSocketOutputStreamClosureState() throws Exception {
+ ServerSocket ss = new ServerSocket(0);
+
+ SocketChannel sc = SocketChannel.open(ss.getLocalSocketAddress());
+ sc.configureBlocking(true);
+
+ Socket scSocket = sc.socket();
+ OutputStream os = scSocket.getOutputStream();
+
+ assertTrue(sc.isOpen());
+ assertFalse(scSocket.isClosed());
+
+ os.close();
+
+ assertFalse(sc.isOpen());
+ assertTrue(scSocket.isClosed());
+
+ ss.close();
+ }
+
+ /** Checks that closing a Socket's input stream also closes the Socket and SocketChannel. */
+ public void test_channelSocketInputStreamClosureState() throws Exception {
+ ServerSocket ss = new ServerSocket(0);
+
+ SocketChannel sc = SocketChannel.open(ss.getLocalSocketAddress());
+ sc.configureBlocking(true);
+
+ Socket scSocket = sc.socket();
+ InputStream is = scSocket.getInputStream();
+
+ assertTrue(sc.isOpen());
+ assertFalse(scSocket.isClosed());
+
+ is.close();
+
+ assertFalse(sc.isOpen());
+ assertTrue(scSocket.isClosed());
+
+ ss.close();
+ }
+
+ /** Checks the state of the SocketChannel and associated Socket after open() */
+ public void test_open_initialState() throws Exception {
+ SocketChannel sc = SocketChannel.open();
+ try {
+ assertNull(sc.socket().getLocalSocketAddress());
+
+ Socket socket = sc.socket();
+ assertFalse(socket.isBound());
+ assertFalse(socket.isClosed());
+ assertFalse(socket.isConnected());
+ assertEquals(-1, socket.getLocalPort());
+ assertTrue(socket.getLocalAddress().isAnyLocalAddress());
+ assertNull(socket.getLocalSocketAddress());
+ assertNull(socket.getInetAddress());
+ assertEquals(0, socket.getPort());
+ assertNull(socket.getRemoteSocketAddress());
+ assertFalse(socket.getReuseAddress());
+
+ assertSame(sc, socket.getChannel());
+ } finally {
+ sc.close();
+ }
+ }
+
+ public void test_bind_unresolvedAddress() throws IOException {
+ SocketChannel sc = SocketChannel.open();
+ try {
+ sc.socket().bind(new InetSocketAddress("unresolvedname", 31415));
+ fail();
+ } catch (IOException expected) {
+ }
+
+ assertNull(sc.socket().getLocalSocketAddress());
+ assertTrue(sc.isOpen());
+ assertFalse(sc.isConnected());
+
+ sc.close();
+ }
+
+ /** Checks that the SocketChannel and associated Socket agree on the socket state. */
+ public void test_bind_socketStateSync() throws IOException {
+ SocketChannel sc = SocketChannel.open();
+ assertNull(sc.socket().getLocalSocketAddress());
+
+ Socket socket = sc.socket();
+ assertNull(socket.getLocalSocketAddress());
+ assertFalse(socket.isBound());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ sc.socket().bind(bindAddr);
+
+ InetSocketAddress actualAddr = (InetSocketAddress) sc.socket().getLocalSocketAddress();
+ assertEquals(actualAddr, socket.getLocalSocketAddress());
+ assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
+ assertTrue(socket.isBound());
+ assertFalse(socket.isConnected());
+ assertFalse(socket.isClosed());
+
+ sc.close();
+
+ assertFalse(sc.isOpen());
+ assertTrue(socket.isClosed());
+ }
+
+ /**
+ * Checks that the SocketChannel and associated Socket agree on the socket state, even if
+ * the Socket object is requested/created after bind().
+ */
+ public void test_bind_socketObjectCreationAfterBind() throws IOException {
+ SocketChannel sc = SocketChannel.open();
+ assertNull(sc.socket().getLocalSocketAddress());
+
+ InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
+ sc.socket().bind(bindAddr);
+
+ // Socket object creation after bind().
+ Socket socket = sc.socket();
+ InetSocketAddress actualAddr = (InetSocketAddress) sc.socket().getLocalSocketAddress();
+ assertEquals(actualAddr, socket.getLocalSocketAddress());
+ assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
+ assertTrue(socket.isBound());
+ assertFalse(socket.isConnected());
+ assertFalse(socket.isClosed());
+
+ sc.close();
+
+ assertFalse(sc.isOpen());
+ assertTrue(socket.isClosed());
+ }
+
+ /**
+ * Tests connect() and object state for a blocking SocketChannel. Blocking mode is the default.
+ */
+ public void test_connect_blocking() throws Exception {
+ ServerSocket ss = new ServerSocket(0);
+
+ SocketChannel sc = SocketChannel.open();
+ assertTrue(sc.isBlocking());
+
+ assertTrue(sc.connect(ss.getLocalSocketAddress()));
+
+ assertTrue(sc.socket().isBound());
+ assertTrue(sc.isConnected());
+ assertTrue(sc.socket().isConnected());
+ assertFalse(sc.socket().isClosed());
+ assertTrue(sc.isBlocking());
+
+ ss.close();
+ sc.close();
+ }
+
+ /** Tests connect() and object state for a non-blocking SocketChannel. */
+ public void test_connect_nonBlocking() throws Exception {
+ ServerSocket ss = new ServerSocket(0);
+
+ SocketChannel sc = SocketChannel.open();
+ assertTrue(sc.isBlocking());
+ sc.configureBlocking(false);
+ assertFalse(sc.isBlocking());
+
+ if (!sc.connect(ss.getLocalSocketAddress())) {
+ do {
+ assertTrue(sc.socket().isBound());
+ assertFalse(sc.isConnected());
+ assertFalse(sc.socket().isConnected());
+ assertFalse(sc.socket().isClosed());
+ } while (!sc.finishConnect());
+ }
+ assertTrue(sc.socket().isBound());
+ assertTrue(sc.isConnected());
+ assertTrue(sc.socket().isConnected());
+ assertFalse(sc.socket().isClosed());
+ assertFalse(sc.isBlocking());
+
+ ss.close();
+ sc.close();
+ }
}
diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
index d0b46ed..e7fdb1f 100644
--- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
+++ b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
@@ -47,65 +47,120 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import junit.framework.TestCase;
public class KeyPairGeneratorTest extends TestCase {
- public void test_getInstance() throws Exception {
+ public void test_providerCount() {
Provider[] providers = Security.getProviders();
- for (Provider provider : providers) {
- Set<Provider.Service> services = provider.getServices();
- for (Provider.Service service : services) {
- String type = service.getType();
- if (!type.equals("KeyPairGenerator")) {
- continue;
- }
- String algorithm = service.getAlgorithm();
+ // We expect there to be at least one provider.
+ assertTrue(providers.length > 0);
+ // If this fails remember to add _provider methods below. This test is sharded because it
+ // takes a long time to execute.
+ assertTrue(providers.length < 10);
+ }
- // AndroidKeyStore is tested in CTS.
- if ("AndroidKeyStore".equals(provider.getName())) {
- continue;
- }
+ public void test_getInstance_provider0() throws Exception {
+ test_getInstance(0);
+ }
- AlgorithmParameterSpec params = null;
+ public void test_getInstance_provider1() throws Exception {
+ test_getInstance(1);
+ }
- // TODO: detect if we're running in vogar and run the full test
- if ("DH".equals(algorithm)) {
- params = getDHParams();
- }
+ public void test_getInstance_provider2() throws Exception {
+ test_getInstance(2);
+ }
- try {
- // KeyPairGenerator.getInstance(String)
- KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(algorithm);
- assertEquals(algorithm, kpg1.getAlgorithm());
- if (params != null) {
- kpg1.initialize(params);
- }
- test_KeyPairGenerator(kpg1);
-
- // KeyPairGenerator.getInstance(String, Provider)
- KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(algorithm, provider);
- assertEquals(algorithm, kpg2.getAlgorithm());
- assertEquals(provider, kpg2.getProvider());
- if (params != null) {
- kpg2.initialize(params);
- }
- test_KeyPairGenerator(kpg2);
-
- // KeyPairGenerator.getInstance(String, String)
- KeyPairGenerator kpg3 = KeyPairGenerator.getInstance(algorithm,
- provider.getName());
- assertEquals(algorithm, kpg3.getAlgorithm());
- assertEquals(provider, kpg3.getProvider());
- if (params != null) {
- kpg3.initialize(params);
- }
- test_KeyPairGenerator(kpg3);
- } catch (Exception e) {
- throw new Exception("Problem testing KeyPairGenerator." + algorithm, e);
+ public void test_getInstance_provider3() throws Exception {
+ test_getInstance(3);
+ }
+
+ public void test_getInstance_provider4() throws Exception {
+ test_getInstance(4);
+ }
+
+ public void test_getInstance_provider5() throws Exception {
+ test_getInstance(5);
+ }
+
+ public void test_getInstance_provider6() throws Exception {
+ test_getInstance(6);
+ }
+
+ public void test_getInstance_provider7() throws Exception {
+ test_getInstance(7);
+ }
+
+ public void test_getInstance_provider8() throws Exception {
+ test_getInstance(8);
+ }
+
+ public void test_getInstance_provider9() throws Exception {
+ test_getInstance(9);
+ }
+
+ private void test_getInstance(int providerIndex) throws Exception {
+ Provider[] providers = Security.getProviders();
+ if (providerIndex >= providers.length) {
+ // Providers can be added by vendors and other tests. We do not
+ // specify a fixed number and silenty pass if the provider at the
+ // specified index does not exist.
+ return;
+ }
+ Provider provider = providers[providerIndex];
+ Set<Provider.Service> services = provider.getServices();
+ for (Provider.Service service : services) {
+ String type = service.getType();
+ if (!type.equals("KeyPairGenerator")) {
+ continue;
+ }
+ String algorithm = service.getAlgorithm();
+
+ // AndroidKeyStore is tested in CTS.
+ if ("AndroidKeyStore".equals(provider.getName())) {
+ continue;
+ }
+
+ AlgorithmParameterSpec params = null;
+
+ if ("DH".equals(algorithm)) {
+ params = getDHParams();
+ }
+
+ try {
+ // KeyPairGenerator.getInstance(String)
+ KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(algorithm);
+ assertEquals(algorithm, kpg1.getAlgorithm());
+ if (params != null) {
+ kpg1.initialize(params);
}
+ test_KeyPairGenerator(kpg1);
+
+ // KeyPairGenerator.getInstance(String, Provider)
+ KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(algorithm, provider);
+ assertEquals(algorithm, kpg2.getAlgorithm());
+ assertEquals(provider, kpg2.getProvider());
+ if (params != null) {
+ kpg2.initialize(params);
+ }
+ test_KeyPairGenerator(kpg2);
+
+ // KeyPairGenerator.getInstance(String, String)
+ KeyPairGenerator kpg3 = KeyPairGenerator.getInstance(algorithm,
+ provider.getName());
+ assertEquals(algorithm, kpg3.getAlgorithm());
+ assertEquals(provider, kpg3.getProvider());
+ if (params != null) {
+ kpg3.initialize(params);
+ }
+ test_KeyPairGenerator(kpg3);
+ } catch (Exception e) {
+ throw new Exception("Problem testing KeyPairGenerator." + algorithm, e);
}
}
}
@@ -161,6 +216,14 @@ public class KeyPairGeneratorTest extends TestCase {
test_KeyPair(kpg, kpg.generateKeyPair());
String algorithm = kpg.getAlgorithm();
+
+ // TODO: detect if we're running in vogar and run the full test
+ if ("DH".equals(algorithm)) {
+ // Disabled because this takes too long on devices.
+ // TODO: Re-enable DH test. http://b/5513723.
+ return;
+ }
+
List<Integer> keySizes = getKeySizes(algorithm);
for (int keySize : keySizes) {
kpg.initialize(keySize);
@@ -206,6 +269,17 @@ public class KeyPairGeneratorTest extends TestCase {
expectedAlgorithm = "DH";
}
assertEquals(expectedAlgorithm, k.getAlgorithm().toUpperCase());
+ if (expectedAlgorithm.equals("DH")) {
+ if (k instanceof DHPublicKey) {
+ DHPublicKey dhPub = (DHPublicKey) k;
+ assertEquals(dhPub.getParams().getP(), getDHParams().getP());
+ } else if (k instanceof DHPrivateKey) {
+ DHPrivateKey dhPriv = (DHPrivateKey) k;
+ assertEquals(dhPriv.getParams().getP(), getDHParams().getP());
+ } else {
+ fail("not a public or private key!?");
+ }
+ }
assertNotNull(k.getEncoded());
assertNotNull(k.getFormat());
@@ -287,7 +361,7 @@ public class KeyPairGeneratorTest extends TestCase {
*
* openssl gendh 512 | openssl dhparams -C
*/
- private static AlgorithmParameterSpec getDHParams() {
+ private static DHParameterSpec getDHParams() {
BigInteger p = new BigInteger("E7AB1768BD75CD24700960FFA32D3F1557344E587101237532CC641646ED7A7C104743377F6D46251698B665CE2A6CBAB6714C2569A7D2CA22C0CF03FA40AC93", 16);
BigInteger g = new BigInteger("02", 16);
return new DHParameterSpec(p, g, 512);
@@ -341,8 +415,6 @@ public class KeyPairGeneratorTest extends TestCase {
public void testDSAGeneratorWithParams() throws Exception {
final DSAParameterSpec dsaSpec = new DSAParameterSpec(DSA_P, DSA_Q, DSA_G);
- boolean failure = false;
-
final Provider[] providers = Security.getProviders();
for (final Provider p : providers) {
Service s = p.getService("KeyPairGenerator", "DSA");
diff --git a/luni/src/test/java/libcore/java/security/KeyStoreTest.java b/luni/src/test/java/libcore/java/security/KeyStoreTest.java
index 47aa72a..9185ea8 100644
--- a/luni/src/test/java/libcore/java/security/KeyStoreTest.java
+++ b/luni/src/test/java/libcore/java/security/KeyStoreTest.java
@@ -46,6 +46,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -55,11 +56,17 @@ import junit.framework.TestCase;
public class KeyStoreTest extends TestCase {
- private static PrivateKeyEntry PRIVATE_KEY;
- private static PrivateKeyEntry PRIVATE_KEY_2;
+ private static final HashMap<String, PrivateKeyEntry> sPrivateKeys
+ = new HashMap<String, PrivateKeyEntry>();
- private static SecretKey SECRET_KEY;
- private static SecretKey SECRET_KEY_2;
+ private static TestKeyStore sTestKeyStore;
+
+ private static final String[] KEY_TYPES = new String[] { "DH", "DSA", "RSA", "EC" };
+
+ private static PrivateKeyEntry sPrivateKey2;
+
+ private static SecretKey sSecretKey;
+ private static SecretKey sSecretKey2;
private static final String ALIAS_PRIVATE = "private";
private static final String ALIAS_CERTIFICATE = "certificate";
@@ -87,31 +94,56 @@ public class KeyStoreTest extends TestCase {
private static final ProtectionParameter PARAM_BAD = new PasswordProtection(PASSWORD_BAD);
private static PrivateKeyEntry getPrivateKey() {
- if (PRIVATE_KEY == null) {
- PRIVATE_KEY = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+ return getPrivateKey("RSA");
+ }
+
+ private static PrivateKeyEntry getPrivateKey(String keyType) {
+ // Avoiding initialization of TestKeyStore in the static initializer: it breaks CTS tests
+ // by causing a NetworkOnMainThreadException.
+ if (sTestKeyStore == null) {
+ sTestKeyStore = new TestKeyStore.Builder()
+ .keyAlgorithms("RSA", "DH_RSA", "DSA", "EC")
+ .aliasPrefix("rsa-dsa-ec-dh")
+ .build();
+ }
+
+ PrivateKeyEntry entry = sPrivateKeys.get(keyType);
+ if (entry == null) {
+ if ("RSA".equals(keyType)) {
+ entry = sTestKeyStore.getPrivateKey("RSA", "RSA");
+ } else if ("DH".equals(keyType)) {
+ entry = sTestKeyStore.getPrivateKey("DH", "RSA");
+ } else if ("DSA".equals(keyType)) {
+ entry = sTestKeyStore.getPrivateKey("DSA", "DSA");
+ } else if ("EC".equals(keyType)) {
+ entry = sTestKeyStore.getPrivateKey("EC", "EC");
+ } else {
+ throw new IllegalArgumentException("Unexpected key type " + keyType);
+ }
+ sPrivateKeys.put(keyType, entry);
}
- return PRIVATE_KEY;
+ return entry;
}
private static PrivateKeyEntry getPrivateKey2() {
- if (PRIVATE_KEY_2 == null) {
- PRIVATE_KEY_2 = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
+ if (sPrivateKey2 == null) {
+ sPrivateKey2 = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
}
- return PRIVATE_KEY_2;
+ return sPrivateKey2;
}
private static SecretKey getSecretKey() {
- if (SECRET_KEY == null) {
- SECRET_KEY = generateSecretKey();
+ if (sSecretKey == null) {
+ sSecretKey = generateSecretKey();
}
- return SECRET_KEY;
+ return sSecretKey;
}
private static SecretKey getSecretKey2() {
- if (SECRET_KEY_2 == null) {
- SECRET_KEY_2 = generateSecretKey();
+ if (sSecretKey2 == null) {
+ sSecretKey2 = generateSecretKey();
}
- return SECRET_KEY_2;
+ return sSecretKey2;
}
private static SecretKey generateSecretKey() {
@@ -341,10 +373,15 @@ public class KeyStoreTest extends TestCase {
ks.setCertificateEntry(alias, certificate);
}
+
public static void assertPrivateKey(Key actual)
throws Exception {
assertEquals(getPrivateKey().getPrivateKey(), actual);
}
+ public static void assertPrivateKey(String keyType, Key actual)
+ throws Exception {
+ assertEquals(getPrivateKey(keyType).getPrivateKey(), actual);
+ }
public static void assertPrivateKey2(Key actual)
throws Exception {
assertEquals(getPrivateKey2().getPrivateKey(), actual);
@@ -2183,8 +2220,10 @@ public class KeyStoreTest extends TestCase {
continue;
}
if (isNullPasswordAllowed(keyStore) || isKeyPasswordIgnored(keyStore)) {
- keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), null);
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
+ for (String keyType : KEY_TYPES) {
+ keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(keyType), null);
+ assertPrivateKey(keyType, keyStore.getKey(ALIAS_PRIVATE, null));
+ }
} else {
try {
keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), null);
diff --git a/luni/src/test/java/libcore/java/security/MessageDigestTest.java b/luni/src/test/java/libcore/java/security/MessageDigestTest.java
index 3646a7a..ad410e4 100644
--- a/luni/src/test/java/libcore/java/security/MessageDigestTest.java
+++ b/luni/src/test/java/libcore/java/security/MessageDigestTest.java
@@ -24,6 +24,11 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
public final class MessageDigestTest extends TestCase {
@@ -116,6 +121,12 @@ public final class MessageDigestTest extends TestCase {
new byte[] { -38, 57, -93, -18, 94, 107, 75, 13,
50, 85, -65, -17, -107, 96, 24, -112,
-81, -40, 7, 9});
+ putExpectation("SHA-224",
+ INPUT_EMPTY,
+ new byte[] { -47, 74, 2, -116, 42, 58, 43, -55, 71,
+ 97, 2, -69, 40, -126, 52, -60, 21,
+ -94, -80, 31, -126, -114, -90, 42,
+ -59, -77, -28, 47});
putExpectation("SHA-256",
INPUT_EMPTY,
new byte[] { -29, -80, -60, 66, -104, -4, 28, 20,
@@ -163,6 +174,12 @@ public final class MessageDigestTest extends TestCase {
new byte[] { 123, -111, -37, -36, 86, -59, 120, 30,
-33, 108, -120, 71, -76, -86, 105, 101,
86, 108, 92, 117 });
+ putExpectation("SHA-224",
+ INPUT_256MB,
+ new byte[] { -78, 82, 5, -71, 57, 119, 77, -32,
+ -62, -74, -40, 64, -57, 79, 40, 116,
+ -18, 48, -69, 45, 18, -94, 111, 114,
+ -45, -93, 43, -11 });
putExpectation("SHA-256",
INPUT_256MB,
new byte[] { -90, -41, 42, -57, 105, 15, 83, -66,
@@ -227,4 +244,33 @@ public final class MessageDigestTest extends TestCase {
return buf.toString();
}
+ private final int THREAD_COUNT = 10;
+
+ public void testMessageDigest_MultipleThreads_Misuse() throws Exception {
+ ExecutorService es = Executors.newFixedThreadPool(THREAD_COUNT);
+
+ final CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
+ final MessageDigest md = MessageDigest.getInstance("SHA-256");
+ final byte[] message = new byte[64];
+
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ es.submit(new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ // Try to make sure all the threads are ready first.
+ latch.countDown();
+ latch.await();
+
+ for (int j = 0; j < 100; j++) {
+ md.update(message);
+ md.digest();
+ }
+
+ return null;
+ }
+ });
+ }
+ es.shutdown();
+ assertTrue("Test should not timeout", es.awaitTermination(1, TimeUnit.MINUTES));
+ }
}
diff --git a/luni/src/test/java/libcore/java/security/MockPrivateKey.java b/luni/src/test/java/libcore/java/security/MockPrivateKey.java
new file mode 100644
index 0000000..e5ac797
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/MockPrivateKey.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.security;
+
+import java.security.PrivateKey;
+
+/**
+ * A mock PrivateKey class used for testing.
+ */
+@SuppressWarnings("serial")
+public class MockPrivateKey implements PrivateKey {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ return "MOCK";
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/luni/src/test/java/libcore/java/security/MockPrivateKey2.java b/luni/src/test/java/libcore/java/security/MockPrivateKey2.java
new file mode 100644
index 0000000..a1c02c9
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/MockPrivateKey2.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.security;
+
+import java.security.PrivateKey;
+
+/**
+ * A mock PrivateKey class used for testing.
+ */
+@SuppressWarnings("serial")
+public class MockPrivateKey2 implements PrivateKey {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ return "MOCK";
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/luni/src/test/java/libcore/java/security/MockPublicKey.java b/luni/src/test/java/libcore/java/security/MockPublicKey.java
new file mode 100644
index 0000000..130b461
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/MockPublicKey.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.security;
+
+import java.security.PublicKey;
+
+/**
+ * A mock PublicKey class used for testing.
+ */
+@SuppressWarnings("serial")
+public class MockPublicKey implements PublicKey {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ return "MOCK";
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/luni/src/test/java/libcore/java/security/MockSignatureSpi.java b/luni/src/test/java/libcore/java/security/MockSignatureSpi.java
new file mode 100644
index 0000000..6017547
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/MockSignatureSpi.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.security;
+
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+
+/**
+ * Mock SignatureSpi used by {@link SignatureTest}.
+ */
+public class MockSignatureSpi extends SignatureSpi {
+ public static class SpecificKeyTypes extends MockSignatureSpi {
+ @Override
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ if (!(key instanceof MockPrivateKey)) {
+ throw new InvalidKeyException("Must be MockPrivateKey!");
+ }
+ }
+ }
+
+ public static class SpecificKeyTypes2 extends MockSignatureSpi {
+ @Override
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ if (!(key instanceof MockPrivateKey2)) {
+ throw new InvalidKeyException("Must be MockPrivateKey2!");
+ }
+ }
+ }
+
+ public static class AllKeyTypes extends MockSignatureSpi {
+ }
+
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineInitVerify(java.security.PublicKey)
+ */
+ @Override
+ protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineInitSign(java.security.PrivateKey)
+ */
+ @Override
+ protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+ checkKeyType(privateKey);
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineUpdate(byte)
+ */
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineSign()
+ */
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineVerify(byte[])
+ */
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineSetParameter(java.lang.String, java.lang.Object)
+ */
+ @Override
+ protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineGetParameter(java.lang.String)
+ */
+ @Override
+ protected Object engineGetParameter(String param) throws InvalidParameterException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineUpdate(byte[], int, int)
+ */
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/luni/src/test/java/libcore/java/security/OldDHTest.java b/luni/src/test/java/libcore/java/security/OldDHTest.java
index 421d153..58d96ed 100644
--- a/luni/src/test/java/libcore/java/security/OldDHTest.java
+++ b/luni/src/test/java/libcore/java/security/OldDHTest.java
@@ -15,7 +15,6 @@
*/
package libcore.java.security;
-import dalvik.annotation.BrokenTest;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.KeyPair;
@@ -27,7 +26,7 @@ import junit.framework.TestCase;
public class OldDHTest extends TestCase {
- @BrokenTest("Suffers from DH slowness, disabling for now")
+ // BrokenTest Suffers from DH slowness, disabling for now
public void testDHGen() throws Exception {
KeyPairGenerator gen = null;
try {
diff --git a/luni/src/test/java/libcore/java/security/OldKeyPairGeneratorTestDH.java b/luni/src/test/java/libcore/java/security/OldKeyPairGeneratorTestDH.java
index f39705b..9be282d 100644
--- a/luni/src/test/java/libcore/java/security/OldKeyPairGeneratorTestDH.java
+++ b/luni/src/test/java/libcore/java/security/OldKeyPairGeneratorTestDH.java
@@ -15,7 +15,6 @@
*/
package libcore.java.security;
-import dalvik.annotation.BrokenTest;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
@@ -24,7 +23,7 @@ import tests.security.KeyAgreementHelper;
public class OldKeyPairGeneratorTestDH extends TestCase {
- @BrokenTest("Takes ages due to DH computations. Disabling for now.")
+ // Broken Test: Takes ages due to DH computations. Disabling for now.
public void testKeyPairGenerator() throws NoSuchAlgorithmException {
KeyPairGenerator generator = KeyPairGenerator.getInstance("DH");
diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java
index 97a80a9..994214b 100644
--- a/luni/src/test/java/libcore/java/security/ProviderTest.java
+++ b/luni/src/test/java/libcore/java/security/ProviderTest.java
@@ -16,27 +16,40 @@
package libcore.java.security;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.SecureRandomSpi;
import java.security.Security;
-import java.security.Provider;
-import java.security.SecureRandom;
-import java.security.SecureRandomSpi;
-import java.security.Security;
+import java.security.cert.CRL;
+import java.security.cert.CRLSelector;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStoreException;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertStoreSpi;
+import java.security.cert.Certificate;
+import java.security.interfaces.RSAPrivateKey;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map.Entry;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
import junit.framework.TestCase;
+import libcore.javax.crypto.MockKey;
public class ProviderTest extends TestCase {
+ private static final boolean LOG_DEBUG = false;
/**
* Makes sure all all expected implementations (but not aliases)
@@ -44,16 +57,15 @@ public class ProviderTest extends TestCase {
* StandardNames
*/
public void test_Provider_getServices() throws Exception {
-
// build set of expected algorithms
- Map<String,Set<String>> remaining
+ Map<String,Set<String>> remainingExpected
= new HashMap<String,Set<String>>(StandardNames.PROVIDER_ALGORITHMS);
- for (Entry<String,Set<String>> entry : remaining.entrySet()) {
+ for (Entry<String,Set<String>> entry : remainingExpected.entrySet()) {
entry.setValue(new HashSet<String>(entry.getValue()));
}
- List<String> extra = new ArrayList();
- List<String> missing = new ArrayList();
+ List<String> extra = new ArrayList<String>();
+ List<String> missing = new ArrayList<String>();
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
@@ -70,7 +82,7 @@ public class ProviderTest extends TestCase {
String type = service.getType();
String algorithm = service.getAlgorithm().toUpperCase();
String className = service.getClassName();
- if (false) {
+ if (LOG_DEBUG) {
System.out.println(providerName
+ " " + type
+ " " + algorithm
@@ -78,8 +90,8 @@ public class ProviderTest extends TestCase {
}
// remove from remaining, assert unknown if missing
- Set<String> algorithms = remaining.get(type);
- if (algorithms == null || !algorithms.remove(algorithm)) {
+ Set<String> remainingAlgorithms = remainingExpected.get(type);
+ if (remainingAlgorithms == null || !remainingAlgorithms.remove(algorithm)) {
// seems to be missing, but sometimes the same
// algorithm is available from multiple providers
// (e.g. KeyFactory RSA is available from
@@ -89,9 +101,28 @@ public class ProviderTest extends TestCase {
&& StandardNames.PROVIDER_ALGORITHMS.get(type).contains(algorithm))) {
extra.add("Unknown " + type + " " + algorithm + " " + providerName + "\n");
}
+ } else if ("Cipher".equals(type) && !algorithm.contains("/")) {
+ /*
+ * Cipher selection follows special rules where you can
+ * specify the mode and padding during the getInstance call.
+ * Try to see if the service supports this.
+ */
+ Set<String> toRemove = new HashSet<String>();
+ for (String remainingAlgo : remainingAlgorithms) {
+ String[] parts = remainingAlgo.split("/");
+ if (parts.length == 3 && algorithm.equals(parts[0])) {
+ try {
+ Cipher.getInstance(remainingAlgo, provider);
+ toRemove.add(remainingAlgo);
+ } catch (NoSuchAlgorithmException ignored) {
+ } catch (NoSuchPaddingException ignored) {
+ }
+ }
+ }
+ remainingAlgorithms.removeAll(toRemove);
}
- if (algorithms != null && algorithms.isEmpty()) {
- remaining.remove(type);
+ if (remainingAlgorithms != null && remainingAlgorithms.isEmpty()) {
+ remainingExpected.remove(type);
}
// make sure class exists and can be initialized
@@ -113,7 +144,7 @@ public class ProviderTest extends TestCase {
assertEquals("Extra algorithms", Collections.EMPTY_LIST, extra);
// assert that we don't have any missing in the implementation
- assertEquals("Missing algorithms", Collections.EMPTY_MAP, remaining);
+ assertEquals("Missing algorithms", Collections.EMPTY_MAP, remainingExpected);
// assert that we don't have any missing classes
Collections.sort(missing); // sort it for readability
@@ -202,11 +233,356 @@ public class ProviderTest extends TestCase {
}
}
+ private static final String[] TYPES_SERVICES_CHECKED = new String[] {
+ "KeyFactory", "CertPathBuilder", "Cipher", "SecureRandom",
+ "AlgorithmParameterGenerator", "Signature", "KeyPairGenerator", "CertificateFactory",
+ "MessageDigest", "KeyAgreement", "CertStore", "SSLContext", "AlgorithmParameters",
+ "TrustManagerFactory", "KeyGenerator", "Mac", "CertPathValidator", "SecretKeyFactory",
+ "KeyManagerFactory", "KeyStore",
+ };
+
+ private static final HashSet<String> TYPES_SUPPORTS_PARAMETER = new HashSet<String>(
+ Arrays.asList(new String[] {
+ "Mac", "KeyAgreement", "Cipher", "Signature",
+ }));
+
+ private static final HashSet<String> TYPES_NOT_SUPPORTS_PARAMETER = new HashSet<String>(
+ Arrays.asList(TYPES_SERVICES_CHECKED));
+ static {
+ TYPES_NOT_SUPPORTS_PARAMETER.removeAll(TYPES_SUPPORTS_PARAMETER);
+ }
+
+ public void test_Provider_getServices_supportsParameter() throws Exception {
+ HashSet<String> remainingTypes = new HashSet<String>(Arrays.asList(TYPES_SERVICES_CHECKED));
+
+ HashSet<String> supportsParameterTypes = new HashSet<String>();
+ HashSet<String> noSupportsParameterTypes = new HashSet<String>();
+
+ Provider[] providers = Security.getProviders();
+ for (Provider provider : providers) {
+ Set<Provider.Service> services = provider.getServices();
+ assertNotNull(services);
+ assertFalse(services.isEmpty());
+
+ for (Provider.Service service : services) {
+ final String type = service.getType();
+ remainingTypes.remove(type);
+ try {
+ service.supportsParameter(new MockKey());
+ supportsParameterTypes.add(type);
+ } catch (InvalidParameterException e) {
+ noSupportsParameterTypes.add(type);
+ try {
+ service.supportsParameter(new Object());
+ fail("Should throw on non-Key parameter");
+ } catch (InvalidParameterException expected) {
+ }
+ }
+ }
+ }
+
+ supportsParameterTypes.retainAll(TYPES_SUPPORTS_PARAMETER);
+ assertEquals("Types that should support parameters", TYPES_SUPPORTS_PARAMETER,
+ supportsParameterTypes);
+
+ noSupportsParameterTypes.retainAll(TYPES_NOT_SUPPORTS_PARAMETER);
+ assertEquals("Types that should not support parameters", TYPES_NOT_SUPPORTS_PARAMETER,
+ noSupportsParameterTypes);
+
+ assertEquals("Types that should be checked", Collections.EMPTY_SET, remainingTypes);
+ }
+
+ public static class MockSpi {
+ public Object parameter;
+
+ public MockSpi(MockKey parameter) {
+ this.parameter = parameter;
+ }
+ };
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_UnknownService_Success() throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Fake.FOO", MockSpi.class.getName());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Fake", "FOO");
+ assertTrue(service.supportsParameter(new Object()));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_KnownService_NoClassInitialization_Success()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Signature.FOO SupportedKeyClasses", getClass().getName()
+ + ".UninitializedMockKey");
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ assertFalse(service.supportsParameter(new MockKey()));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public static class UninitializedMockKey extends MockKey {
+ static {
+ fail("This should not be initialized");
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_TypeDoesNotSupportParameter_Failure()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("KeyFactory.FOO", MockSpi.class.getName());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("KeyFactory", "FOO");
+ try {
+ service.supportsParameter(new MockKey());
+ fail("Should always throw exception");
+ } catch (InvalidParameterException expected) {
+ }
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_SupportedKeyClasses_NonKeyClass_Success()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Signature.FOO SupportedKeyClasses", MockSpi.class.getName());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ assertFalse(service.supportsParameter(new MockKey()));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_KnownService_NonKey_Failure()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ try {
+ service.supportsParameter(new Object());
+ fail("Should throw when non-Key passed in");
+ } catch (InvalidParameterException expected) {
+ }
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_KnownService_SupportedKeyClasses_NonKey_Failure()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Signature.FOO SupportedKeyClasses", RSAPrivateKey.class.getName());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ try {
+ service.supportsParameter(new Object());
+ fail("Should throw on non-Key instance passed in");
+ } catch (InvalidParameterException expected) {
+ }
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_KnownService_Null_Failure() throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Signature.FOO SupportedKeyClasses", RSAPrivateKey.class.getName());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ assertFalse(service.supportsParameter(null));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_SupportedKeyClasses_Success()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Signature.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ assertTrue(service.supportsParameter(new MockKey()));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_SupportedKeyClasses_Failure()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Signature.FOO SupportedKeyClasses", RSAPrivateKey.class.getName());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ assertFalse(service.supportsParameter(new MockKey()));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_SupportedKeyFormats_Success()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Signature.FOO SupportedKeyFormats", new MockKey().getFormat());
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ assertTrue(service.supportsParameter(new MockKey()));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_supportsParameter_SupportedKeyFormats_Failure()
+ throws Exception {
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Signature.FOO SupportedKeyFormats", "Invalid");
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("Signature", "FOO");
+ assertFalse(service.supportsParameter(new MockKey()));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public void testProviderService_newInstance_DoesNotCallSupportsParameter_Success()
+ throws Exception {
+ MockProvider provider = new MockProvider("MockProvider");
+
+ provider.putServiceForTest(new Provider.Service(provider, "CertStore", "FOO",
+ MyCertStoreSpi.class.getName(), null, null) {
+ @Override
+ public boolean supportsParameter(Object parameter) {
+ fail("This should not be called");
+ return false;
+ }
+ });
+
+ Security.addProvider(provider);
+ try {
+ Provider.Service service = provider.getService("CertStore", "FOO");
+ assertNotNull(service.newInstance(new MyCertStoreParameters()));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
+ public static class MyCertStoreSpi extends CertStoreSpi {
+ public MyCertStoreSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException {
+ super(params);
+ }
+
+ @Override
+ public Collection<? extends Certificate> engineGetCertificates(CertSelector selector)
+ throws CertStoreException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection<? extends CRL> engineGetCRLs(CRLSelector selector)
+ throws CertStoreException {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public static class MyCertStoreParameters implements CertStoreParameters {
+ public Object clone() {
+ return new MyCertStoreParameters();
+ }
+ }
+
/**
* http://code.google.com/p/android/issues/detail?id=21449
*/
public void testSecureRandomImplementationOrder() {
- Provider srp = new SRProvider();
+ @SuppressWarnings("serial")
+ Provider srp = new MockProvider("SRProvider") {
+ public void setup() {
+ put("SecureRandom.SecureRandom1", SecureRandom1.class.getName());
+ put("SecureRandom.SecureRandom2", SecureRandom2.class.getName());
+ put("SecureRandom.SecureRandom3", SecureRandom3.class.getName());
+ }
+ };
try {
int position = Security.insertProviderAt(srp, 1); // first is one, not zero
assertEquals(1, position);
@@ -219,16 +595,22 @@ public class ProviderTest extends TestCase {
}
}
- public static class SRProvider extends Provider {
+ @SuppressWarnings("serial")
+ private static class MockProvider extends Provider {
+ public MockProvider(String name) {
+ super(name, 1.0, "Mock provider used for testing");
+ setup();
+ }
+
+ public void setup() {
+ }
- SRProvider() {
- super("SRProvider", 1.42, "SecureRandom Provider");
- put("SecureRandom.SecureRandom1", SecureRandom1.class.getName());
- put("SecureRandom.SecureRandom2", SecureRandom2.class.getName());
- put("SecureRandom.SecureRandom3", SecureRandom3.class.getName());
+ public void putServiceForTest(Provider.Service service) {
+ putService(service);
}
}
+ @SuppressWarnings("serial")
public static abstract class AbstractSecureRandom extends SecureRandomSpi {
protected void engineSetSeed(byte[] seed) {
throw new UnsupportedOperationException();
@@ -241,8 +623,13 @@ public class ProviderTest extends TestCase {
}
}
+ @SuppressWarnings("serial")
public static class SecureRandom1 extends AbstractSecureRandom {}
+
+ @SuppressWarnings("serial")
public static class SecureRandom2 extends AbstractSecureRandom {}
+
+ @SuppressWarnings("serial")
public static class SecureRandom3 extends AbstractSecureRandom {}
}
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index 7f8b4f4..5e02f10 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -18,9 +18,11 @@ package libcore.java.security;
import java.math.BigInteger;
import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
@@ -38,10 +40,197 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
public class SignatureTest extends TestCase {
+ private static abstract class MockProvider extends Provider {
+ public MockProvider(String name) {
+ super(name, 1.0, "Mock provider used for testing");
+ setup();
+ }
+
+ public abstract void setup();
+ }
+
+ public void testSignature_getInstance_SuppliedProviderNotRegistered_Success() throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ {
+ Signature s = Signature.getInstance("FOO", mockProvider);
+ s.initSign(new MockPrivateKey());
+ assertEquals(mockProvider, s.getProvider());
+ }
+ }
+
+ public void testSignature_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
+ throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProvider);
+ try {
+ {
+ Provider mockProvider2 = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
+ }
+ };
+ Signature s = Signature.getInstance("FOO", mockProvider2);
+ assertEquals(mockProvider2, s.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProvider.getName());
+ }
+ }
+
+ public void testSignature_getInstance_DelayedInitialization_KeyType() throws Exception {
+ Provider mockProviderSpecific = new MockProvider("MockProviderSpecific") {
+ public void setup() {
+ put("Signature.FOO", MockSignatureSpi.SpecificKeyTypes.class.getName());
+ put("Signature.FOO SupportedKeyClasses", MockPrivateKey.class.getName());
+ }
+ };
+ Provider mockProviderSpecific2 = new MockProvider("MockProviderSpecific2") {
+ public void setup() {
+ put("Signature.FOO", MockSignatureSpi.SpecificKeyTypes2.class.getName());
+ put("Signature.FOO SupportedKeyClasses", MockPrivateKey2.class.getName());
+ }
+ };
+ Provider mockProviderAll = new MockProvider("MockProviderAll") {
+ public void setup() {
+ put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderSpecific);
+ Security.addProvider(mockProviderSpecific2);
+ Security.addProvider(mockProviderAll);
+
+ try {
+ {
+ Signature s = Signature.getInstance("FOO");
+ s.initSign(new MockPrivateKey());
+ assertEquals(mockProviderSpecific, s.getProvider());
+
+ try {
+ s.initSign(new MockPrivateKey2());
+ assertEquals(mockProviderSpecific2, s.getProvider());
+ if (StandardNames.IS_RI) {
+ fail("RI was broken before; fix tests now that it works!");
+ }
+ } catch (InvalidKeyException e) {
+ if (!StandardNames.IS_RI) {
+ fail("Non-RI should select the right provider");
+ }
+ }
+ }
+
+ {
+ Signature s = Signature.getInstance("FOO");
+ s.initSign(new PrivateKey() {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+ });
+ assertEquals(mockProviderAll, s.getProvider());
+ }
+
+ {
+ Signature s = Signature.getInstance("FOO");
+ assertEquals(mockProviderSpecific, s.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProviderSpecific.getName());
+ Security.removeProvider(mockProviderSpecific2.getName());
+ Security.removeProvider(mockProviderAll.getName());
+ }
+ }
+
+ private static class MySignature extends Signature {
+ protected MySignature(String algorithm) {
+ super(algorithm);
+ }
+
+ @Override
+ protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void engineSetParameter(String param, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected Object engineGetParameter(String param) throws InvalidParameterException {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public void testSignature_getProvider_Subclass() throws Exception {
+ Provider mockProviderNonSpi = new MockProvider("MockProviderNonSpi") {
+ public void setup() {
+ put("Signature.FOO", MySignature.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderNonSpi);
+
+ try {
+ Signature s = new MySignature("FOO");
+ assertNull(s.getProvider());
+ } finally {
+ Security.removeProvider(mockProviderNonSpi.getName());
+ }
+ }
// 20 bytes for DSA
private final byte[] DATA = new byte[20];
@@ -140,6 +329,8 @@ public class SignatureTest extends TestCase {
// http://code.google.com/p/android/issues/detail?id=34933
sig.verify(signature);
}
+
+ testSignature_MultipleThreads_Misuse(sig);
}
private static final byte[] PK_BYTES = hexToBytes(
@@ -425,6 +616,44 @@ public class SignatureTest extends TestCase {
(byte) 0xc0, (byte) 0x09, (byte) 0x15, (byte) 0x7d, (byte) 0x8a, (byte) 0x21, (byte) 0xbc, (byte) 0xa3,
};
+ /*
+ * echo 'Android.' | openssl dgst -sha224 -binary -sign privkey.pem | recode ../x1 | sed 's/0x/(byte) 0x/g'
+ */
+ private static final byte[] SHA224withRSA_Vector2Signature = new byte[] {
+ (byte) 0xBD, (byte) 0x3F, (byte) 0xD4, (byte) 0x20, (byte) 0x5B, (byte) 0xC0, (byte) 0x89, (byte) 0x4F,
+ (byte) 0x99, (byte) 0x6C, (byte) 0xF4, (byte) 0xA4, (byte) 0x70, (byte) 0xE3, (byte) 0x5B, (byte) 0x33,
+ (byte) 0xB3, (byte) 0xCA, (byte) 0xFE, (byte) 0x1F, (byte) 0xB9, (byte) 0x3A, (byte) 0xD6, (byte) 0x9B,
+ (byte) 0x1E, (byte) 0xDA, (byte) 0x65, (byte) 0x06, (byte) 0xBD, (byte) 0xC3, (byte) 0x2B, (byte) 0xF8,
+ (byte) 0x0E, (byte) 0xA0, (byte) 0xB5, (byte) 0x33, (byte) 0x7F, (byte) 0x15, (byte) 0xDC, (byte) 0xBB,
+ (byte) 0xDC, (byte) 0x98, (byte) 0x96, (byte) 0xF5, (byte) 0xF8, (byte) 0xE5, (byte) 0x55, (byte) 0x7D,
+ (byte) 0x48, (byte) 0x51, (byte) 0xC5, (byte) 0xAE, (byte) 0x12, (byte) 0xA2, (byte) 0x61, (byte) 0xC7,
+ (byte) 0xA2, (byte) 0x00, (byte) 0x0F, (byte) 0x35, (byte) 0x54, (byte) 0x3C, (byte) 0x7E, (byte) 0x97,
+ (byte) 0x19, (byte) 0x2D, (byte) 0x8F, (byte) 0xFD, (byte) 0x51, (byte) 0x04, (byte) 0x72, (byte) 0x23,
+ (byte) 0x65, (byte) 0x16, (byte) 0x41, (byte) 0x12, (byte) 0x46, (byte) 0xD6, (byte) 0x20, (byte) 0xB6,
+ (byte) 0x4E, (byte) 0xD6, (byte) 0xE8, (byte) 0x60, (byte) 0x91, (byte) 0x05, (byte) 0xCA, (byte) 0x57,
+ (byte) 0x6F, (byte) 0x53, (byte) 0xA4, (byte) 0x05, (byte) 0x2A, (byte) 0x37, (byte) 0xDD, (byte) 0x2E,
+ (byte) 0xA4, (byte) 0xC7, (byte) 0xBF, (byte) 0x9E, (byte) 0xF6, (byte) 0xD5, (byte) 0xD4, (byte) 0x34,
+ (byte) 0xB8, (byte) 0xB3, (byte) 0x8B, (byte) 0x66, (byte) 0x2C, (byte) 0xB6, (byte) 0x5F, (byte) 0xA4,
+ (byte) 0xB7, (byte) 0x77, (byte) 0xF8, (byte) 0x9A, (byte) 0x9C, (byte) 0x44, (byte) 0x9F, (byte) 0xF0,
+ (byte) 0xCA, (byte) 0x53, (byte) 0x56, (byte) 0x2F, (byte) 0x99, (byte) 0x2E, (byte) 0x4B, (byte) 0xA2,
+ (byte) 0x26, (byte) 0x50, (byte) 0x30, (byte) 0x97, (byte) 0x2B, (byte) 0x4B, (byte) 0x0C, (byte) 0x3E,
+ (byte) 0x28, (byte) 0x0B, (byte) 0x88, (byte) 0x87, (byte) 0x9E, (byte) 0xCE, (byte) 0xCB, (byte) 0x57,
+ (byte) 0x72, (byte) 0x6B, (byte) 0xF6, (byte) 0xD6, (byte) 0xAA, (byte) 0x4D, (byte) 0x5F, (byte) 0x19,
+ (byte) 0x7A, (byte) 0xAD, (byte) 0x44, (byte) 0x09, (byte) 0x33, (byte) 0x62, (byte) 0xC8, (byte) 0x56,
+ (byte) 0x82, (byte) 0x84, (byte) 0xBF, (byte) 0x52, (byte) 0xC6, (byte) 0xA2, (byte) 0x2B, (byte) 0xE3,
+ (byte) 0xC2, (byte) 0x7F, (byte) 0xE3, (byte) 0x06, (byte) 0xC3, (byte) 0x30, (byte) 0xB8, (byte) 0xD4,
+ (byte) 0x01, (byte) 0xE6, (byte) 0x3D, (byte) 0xDB, (byte) 0xCA, (byte) 0xE4, (byte) 0xFB, (byte) 0xA8,
+ (byte) 0x7B, (byte) 0x2D, (byte) 0x8F, (byte) 0x39, (byte) 0x7A, (byte) 0x63, (byte) 0x9F, (byte) 0x02,
+ (byte) 0xE8, (byte) 0x91, (byte) 0xD1, (byte) 0xEE, (byte) 0x60, (byte) 0xEE, (byte) 0xCA, (byte) 0xF2,
+ (byte) 0x33, (byte) 0x7D, (byte) 0xF2, (byte) 0x41, (byte) 0x52, (byte) 0x0B, (byte) 0x9B, (byte) 0x1B,
+ (byte) 0x2D, (byte) 0x89, (byte) 0x38, (byte) 0xEC, (byte) 0x24, (byte) 0x60, (byte) 0x40, (byte) 0x40,
+ (byte) 0x6F, (byte) 0xB6, (byte) 0x6F, (byte) 0x86, (byte) 0xB5, (byte) 0x0A, (byte) 0x3D, (byte) 0x98,
+ (byte) 0x77, (byte) 0x3F, (byte) 0x59, (byte) 0x41, (byte) 0x3E, (byte) 0x4D, (byte) 0xE4, (byte) 0x4E,
+ (byte) 0x91, (byte) 0xCD, (byte) 0x8E, (byte) 0x33, (byte) 0x60, (byte) 0x16, (byte) 0x8D, (byte) 0xAB,
+ (byte) 0x04, (byte) 0x14, (byte) 0xE8, (byte) 0x76, (byte) 0xF1, (byte) 0x06, (byte) 0xCD, (byte) 0x4A,
+ (byte) 0x88, (byte) 0xC7, (byte) 0x69, (byte) 0x6B, (byte) 0xC6, (byte) 0xDA, (byte) 0x9E, (byte) 0x09
+ };
+
private static final byte[] SHA256withRSA_Vector2Signature = new byte[] {
(byte) 0x18, (byte) 0x6e, (byte) 0x31, (byte) 0x1f, (byte) 0x1d, (byte) 0x44, (byte) 0x09, (byte) 0x3e,
(byte) 0xa0, (byte) 0xc4, (byte) 0x3d, (byte) 0xb4, (byte) 0x1b, (byte) 0xf2, (byte) 0xd8, (byte) 0xa4,
@@ -871,6 +1100,30 @@ public class SignatureTest extends TestCase {
assertTrue("Signature must verify correctly", sig.verify(signature));
}
+ public void testSign_SHA224withRSA_Key_Success() throws Exception {
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+ RSA_2048_privateExponent);
+
+ final PrivateKey privKey = kf.generatePrivate(keySpec);
+
+ Signature sig = Signature.getInstance("SHA224withRSA");
+ sig.initSign(privKey);
+ sig.update(Vector2Data);
+
+ byte[] signature = sig.sign();
+ assertNotNull("Signature must not be null", signature);
+ assertTrue("Signature should match expected",
+ Arrays.equals(signature, SHA224withRSA_Vector2Signature));
+
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+ RSA_2048_publicExponent);
+ PublicKey pubKey = kf.generatePublic(pubKeySpec);
+ sig.initVerify(pubKey);
+ sig.update(Vector2Data);
+ assertTrue("Signature must verify correctly", sig.verify(signature));
+ }
+
public void testSign_SHA256withRSA_Key_Success() throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
@@ -1225,6 +1478,34 @@ public class SignatureTest extends TestCase {
(byte) 0xdc, (byte) 0x73, (byte) 0x3d, (byte) 0xf3, (byte) 0x51, (byte) 0xc0, (byte) 0x57,
};
+ /**
+ * A possible signature using SHA224withDSA of Vector2Data. Note that DSS is
+ * randomized, so this won't be the exact signature you'll get out of
+ * another signing operation unless you use a fixed RNG.
+ */
+ public static final byte[] SHA224withDSA_Vector2Signature = new byte[] {
+ (byte) 0x30, (byte) 0x2D, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xAD, (byte) 0xE5, (byte) 0x6D,
+ (byte) 0xF5, (byte) 0x11, (byte) 0x8D, (byte) 0x2E, (byte) 0x62, (byte) 0x5D, (byte) 0x98, (byte) 0x8A,
+ (byte) 0xC4, (byte) 0x88, (byte) 0x7E, (byte) 0xE6, (byte) 0xA3, (byte) 0x44, (byte) 0x99, (byte) 0xEF,
+ (byte) 0x49, (byte) 0x02, (byte) 0x14, (byte) 0x15, (byte) 0x3E, (byte) 0x32, (byte) 0xD6, (byte) 0xF9,
+ (byte) 0x79, (byte) 0x2C, (byte) 0x60, (byte) 0x6E, (byte) 0xF9, (byte) 0xA9, (byte) 0x78, (byte) 0xE7,
+ (byte) 0x4B, (byte) 0x87, (byte) 0x08, (byte) 0x96, (byte) 0x60, (byte) 0xDE, (byte) 0xB5
+ };
+
+ /**
+ * A possible signature using SHA256withDSA of Vector2Data. Note that DSS is
+ * randomized, so this won't be the exact signature you'll get out of
+ * another signing operation unless you use a fixed RNG.
+ */
+ public static final byte[] SHA256withDSA_Vector2Signature = new byte[] {
+ (byte) 0x30, (byte) 0x2D, (byte) 0x02, (byte) 0x14, (byte) 0x0A, (byte) 0xB1, (byte) 0x74, (byte) 0x45,
+ (byte) 0xE1, (byte) 0x63, (byte) 0x43, (byte) 0x68, (byte) 0x65, (byte) 0xBC, (byte) 0xCA, (byte) 0x45,
+ (byte) 0x27, (byte) 0x11, (byte) 0x4D, (byte) 0x52, (byte) 0xFB, (byte) 0x22, (byte) 0x93, (byte) 0xDD,
+ (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x98, (byte) 0x32, (byte) 0x1A, (byte) 0x16, (byte) 0x77,
+ (byte) 0x49, (byte) 0xA7, (byte) 0x78, (byte) 0xFD, (byte) 0xE0, (byte) 0xF7, (byte) 0x71, (byte) 0xD4,
+ (byte) 0x80, (byte) 0x50, (byte) 0xA7, (byte) 0xDD, (byte) 0x94, (byte) 0xD1, (byte) 0x6C
+ };
+
public void testSign_SHA1withDSA_Key_Success() throws Exception {
KeyFactory kf = KeyFactory.getInstance("DSA");
DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
@@ -1255,10 +1536,73 @@ public class SignatureTest extends TestCase {
assertTrue("Signature must verify correctly", sig.verify(SHA1withDSA_Vector2Signature));
}
+ public void testSign_SHA224withDSA_Key_Success() throws Exception {
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
+ PrivateKey privKey = kf.generatePrivate(keySpec);
+
+ Signature sig = Signature.getInstance("SHA224withDSA");
+ sig.initSign(privKey);
+ sig.update(Vector2Data);
+
+ byte[] signature = sig.sign();
+ assertNotNull("Signature must not be null", signature);
+
+ DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+ PublicKey pubKey = kf.generatePublic(pubKeySpec);
+ sig.initVerify(pubKey);
+ sig.update(Vector2Data);
+ assertTrue("Signature must verify correctly", sig.verify(signature));
+ }
+
+ public void testVerify_SHA224withDSA_Key_Success() throws Exception {
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+ PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+ Signature sig = Signature.getInstance("SHA224withDSA");
+ sig.initVerify(pubKey);
+ sig.update(Vector2Data);
+ assertTrue("Signature must verify correctly", sig.verify(SHA224withDSA_Vector2Signature));
+ }
+
+ public void testSign_SHA256withDSA_Key_Success() throws Exception {
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
+ PrivateKey privKey = kf.generatePrivate(keySpec);
+
+ Signature sig = Signature.getInstance("SHA256withDSA");
+ sig.initSign(privKey);
+ sig.update(Vector2Data);
+
+ byte[] signature = sig.sign();
+ assertNotNull("Signature must not be null", signature);
+
+ DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+ PublicKey pubKey = kf.generatePublic(pubKeySpec);
+ sig.initVerify(pubKey);
+ sig.update(Vector2Data);
+ assertTrue("Signature must verify correctly", sig.verify(signature));
+ }
+
+ public void testVerify_SHA256withDSA_Key_Success() throws Exception {
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+ PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+ Signature sig = Signature.getInstance("SHA256withDSA");
+ sig.initVerify(pubKey);
+ sig.update(Vector2Data);
+ assertTrue("Signature must verify correctly", sig.verify(SHA256withDSA_Vector2Signature));
+ }
+
// NetscapeCertRequest looks up Signature algorithms by OID from
// BC but BC version 1.47 had registration bugs and MD5withRSA was
// overlooked. http://b/7453821
public void testGetInstanceFromOID() throws Exception {
+ if (StandardNames.IS_RI) {
+ return;
+ }
assertBouncyCastleSignatureFromOID("1.2.840.113549.1.1.4"); // MD5withRSA
assertBouncyCastleSignatureFromOID("1.2.840.113549.1.1.5"); // SHA1withRSA
assertBouncyCastleSignatureFromOID("1.3.14.3.2.29"); // SHA1withRSA
@@ -1273,4 +1617,33 @@ public class SignatureTest extends TestCase {
assertNotNull(oid, signature);
assertEquals(oid, signature.getAlgorithm());
}
+
+ private final int THREAD_COUNT = 10;
+
+ private void testSignature_MultipleThreads_Misuse(final Signature s) throws Exception {
+ ExecutorService es = Executors.newFixedThreadPool(THREAD_COUNT);
+
+ final CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
+ final byte[] message = new byte[64];
+
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ es.submit(new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ // Try to make sure all the threads are ready first.
+ latch.countDown();
+ latch.await();
+
+ for (int j = 0; j < 100; j++) {
+ s.update(message);
+ s.sign();
+ }
+
+ return null;
+ }
+ });
+ }
+ es.shutdown();
+ assertTrue("Test should not timeout", es.awaitTermination(1, TimeUnit.MINUTES));
+ }
}
diff --git a/luni/src/test/java/libcore/java/security/cert/CRLReasonTest.java b/luni/src/test/java/libcore/java/security/cert/CRLReasonTest.java
new file mode 100644
index 0000000..8030de1
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/cert/CRLReasonTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.security.cert;
+
+import java.security.cert.CRLReason;
+
+import junit.framework.TestCase;
+
+public class CRLReasonTest extends TestCase {
+ public void testCryptoPrimitive_ordinal_ExpectedValues() throws Exception {
+ assertEquals("UNSPECIFIED", 0, CRLReason.UNSPECIFIED.ordinal());
+ assertEquals("KEY_COMPROMISE", 1, CRLReason.KEY_COMPROMISE.ordinal());
+ assertEquals("CA_COMPROMISE", 2, CRLReason.CA_COMPROMISE.ordinal());
+ assertEquals("AFFILIATION_CHANGED", 3, CRLReason.AFFILIATION_CHANGED.ordinal());
+ assertEquals("SUPERSEDED", 4, CRLReason.SUPERSEDED.ordinal());
+ assertEquals("CESSATION_OF_OPERATION", 5, CRLReason.CESSATION_OF_OPERATION.ordinal());
+ assertEquals("CERTIFICATE_HOLD", 6, CRLReason.CERTIFICATE_HOLD.ordinal());
+ assertEquals("UNUSED", 7, CRLReason.UNUSED.ordinal());
+ assertEquals("REMOVE_FROM_CRL", 8, CRLReason.REMOVE_FROM_CRL.ordinal());
+ assertEquals("PRIVILEGE_WITHDRAWN", 9, CRLReason.PRIVILEGE_WITHDRAWN.ordinal());
+ assertEquals("AA_COMPROMISE", 10, CRLReason.AA_COMPROMISE.ordinal());
+ }
+
+ public void testCRLReason_values_ExpectedValues() throws Exception {
+ CRLReason[] reasons = CRLReason.values();
+ assertEquals(11, reasons.length);
+ assertEquals(CRLReason.UNSPECIFIED, reasons[0]);
+ assertEquals(CRLReason.KEY_COMPROMISE, reasons[1]);
+ assertEquals(CRLReason.CA_COMPROMISE, reasons[2]);
+ assertEquals(CRLReason.AFFILIATION_CHANGED, reasons[3]);
+ assertEquals(CRLReason.SUPERSEDED, reasons[4]);
+ assertEquals(CRLReason.CESSATION_OF_OPERATION, reasons[5]);
+ assertEquals(CRLReason.CERTIFICATE_HOLD, reasons[6]);
+ assertEquals(CRLReason.UNUSED, reasons[7]);
+ assertEquals(CRLReason.REMOVE_FROM_CRL, reasons[8]);
+ assertEquals(CRLReason.PRIVILEGE_WITHDRAWN, reasons[9]);
+ assertEquals(CRLReason.AA_COMPROMISE, reasons[10]);
+ }
+
+ public void testCRLReason_valueOf_ExpectedValues() throws Exception {
+ assertEquals(CRLReason.UNSPECIFIED, CRLReason.valueOf("UNSPECIFIED"));
+ assertEquals(CRLReason.KEY_COMPROMISE, CRLReason.valueOf("KEY_COMPROMISE"));
+ assertEquals(CRLReason.CA_COMPROMISE, CRLReason.valueOf("CA_COMPROMISE"));
+ assertEquals(CRLReason.AFFILIATION_CHANGED, CRLReason.valueOf("AFFILIATION_CHANGED"));
+ assertEquals(CRLReason.SUPERSEDED, CRLReason.valueOf("SUPERSEDED"));
+ assertEquals(CRLReason.CESSATION_OF_OPERATION, CRLReason.valueOf("CESSATION_OF_OPERATION"));
+ assertEquals(CRLReason.CERTIFICATE_HOLD, CRLReason.valueOf("CERTIFICATE_HOLD"));
+ assertEquals(CRLReason.UNUSED, CRLReason.valueOf("UNUSED"));
+ assertEquals(CRLReason.REMOVE_FROM_CRL, CRLReason.valueOf("REMOVE_FROM_CRL"));
+ assertEquals(CRLReason.PRIVILEGE_WITHDRAWN, CRLReason.valueOf("PRIVILEGE_WITHDRAWN"));
+ assertEquals(CRLReason.AA_COMPROMISE, CRLReason.valueOf("AA_COMPROMISE"));
+ }
+}
diff --git a/luni/src/test/java/libcore/java/security/cert/OldPKIXParametersTest.java b/luni/src/test/java/libcore/java/security/cert/OldPKIXParametersTest.java
index d69e0e2..0832dae 100644
--- a/luni/src/test/java/libcore/java/security/cert/OldPKIXParametersTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/OldPKIXParametersTest.java
@@ -22,7 +22,6 @@
package libcore.java.security.cert;
-import dalvik.annotation.BrokenTest;
import java.io.ByteArrayInputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
@@ -176,7 +175,7 @@ public class OldPKIXParametersTest extends TestCase {
* @throws InvalidAlgorithmParameterException
* @throws KeyStoreException
*/
- @BrokenTest("Fails in CTS environment, but passes in CoreTestRunner")
+ // Broken Test: Fails in CTS environment, but passes in CoreTestRunner
public final void testPKIXParametersKeyStore04() throws Exception {
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
index fa920ce..42de50a 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
@@ -30,12 +30,14 @@ import java.security.Provider;
import java.security.Security;
import java.security.SignatureException;
import java.security.cert.CRL;
+import java.security.cert.CRLReason;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
@@ -120,7 +122,7 @@ public class X509CRLTest extends TestCase {
private Map<String, Date> getCrlDates(String name) throws Exception {
Map<String, Date> dates = new HashMap<String, Date>();
- final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
+ final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz", Locale.US);
final InputStream ris = Support_Resources.getStream(name);
try {
@@ -316,6 +318,22 @@ public class X509CRLTest extends TestCase {
assertEquals(result1, result2);
}
+ /*
+ * This is needed because the certificate revocation in our CRL can be a
+ * couple seconds ahead of the lastUpdate time in the CRL.
+ */
+ private static void assertDateSlightlyBefore(Date expected, Date actual) throws Exception {
+ Calendar c = Calendar.getInstance();
+
+ // Make sure it's within 2 seconds of expected.
+ c.setTime(expected);
+ c.add(Calendar.SECOND, -2);
+ assertTrue(actual.after(c.getTime()));
+
+ // Before or equal...
+ assertTrue(actual.before(expected) || actual.equals(expected));
+ }
+
private void assertRsaCrlEntry(CertificateFactory f, X509CRLEntry rsaEntry) throws Exception {
assertNotNull(rsaEntry);
@@ -324,7 +342,8 @@ public class X509CRLTest extends TestCase {
Date expectedDate = dates.get("lastUpdate");
assertEquals(rsaCert.getSerialNumber(), rsaEntry.getSerialNumber());
- assertDateEquals(expectedDate, rsaEntry.getRevocationDate());
+ assertDateSlightlyBefore(expectedDate, rsaEntry.getRevocationDate());
+ assertNull(rsaEntry.getRevocationReason());
assertNull(rsaEntry.getCertificateIssuer());
assertFalse(rsaEntry.hasExtensions());
assertNull(rsaEntry.getCriticalExtensionOIDs());
@@ -334,18 +353,24 @@ public class X509CRLTest extends TestCase {
}
private void assertDsaCrlEntry(CertificateFactory f, X509CRLEntry dsaEntry) throws Exception {
+ assertNotNull(dsaEntry);
+
X509Certificate dsaCert = getCertificate(f, CERT_DSA);
Map<String, Date> dates = getCrlDates(CRL_RSA_DSA_DATES);
Date expectedDate = dates.get("lastUpdate");
assertEquals(dsaCert.getSerialNumber(), dsaEntry.getSerialNumber());
- assertDateEquals(expectedDate, dsaEntry.getRevocationDate());
+ assertDateSlightlyBefore(expectedDate, dsaEntry.getRevocationDate());
+ assertEquals(CRLReason.CESSATION_OF_OPERATION, dsaEntry.getRevocationReason());
assertNull(dsaEntry.getCertificateIssuer());
assertTrue(dsaEntry.hasExtensions());
- /* TODO: get the OID */
assertNotNull(dsaEntry.getCriticalExtensionOIDs());
- /* TODO: get the OID */
+ assertEquals(0, dsaEntry.getCriticalExtensionOIDs().size());
assertNotNull(dsaEntry.getNonCriticalExtensionOIDs());
+ assertEquals(1, dsaEntry.getNonCriticalExtensionOIDs().size());
+ assertTrue(Arrays.toString(dsaEntry.getNonCriticalExtensionOIDs().toArray()),
+ dsaEntry.getNonCriticalExtensionOIDs().contains("2.5.29.21"));
+ System.out.println(Arrays.toString(dsaEntry.getExtensionValue("2.5.29.21")));
assertNotNull(dsaEntry.toString());
}
@@ -362,13 +387,16 @@ public class X509CRLTest extends TestCase {
assertEquals(1, entries.size());
for (X509CRLEntry e : entries) {
assertRsaCrlEntry(f, e);
+ assertRsaCrlEntry(f, crlRsa.getRevokedCertificate(e.getSerialNumber()));
}
X509CRL crlRsaDsa = getCRL(f, CRL_RSA_DSA);
Set<? extends X509CRLEntry> entries2 = crlRsaDsa.getRevokedCertificates();
assertEquals(2, entries2.size());
assertRsaCrlEntry(f, crlRsaDsa.getRevokedCertificate(rsaCert));
+ assertRsaCrlEntry(f, crlRsaDsa.getRevokedCertificate(rsaCert.getSerialNumber()));
assertDsaCrlEntry(f, crlRsaDsa.getRevokedCertificate(dsaCert));
+ assertDsaCrlEntry(f, crlRsaDsa.getRevokedCertificate(dsaCert.getSerialNumber()));
}
private void getSigAlgParams(CertificateFactory f) throws Exception {
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
index ffddcbe..c35f8e6 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
@@ -170,7 +170,8 @@ public class X509CertificateTest extends TestCase {
final InputStream ris = Support_Resources.getStream("x509/cert-rsa-dates.txt");
try {
// notBefore=Dec 26 00:19:14 2012 GMT
- final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
+ final SimpleDateFormat sdf =
+ new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz", Locale.US);
final BufferedReader buf = new BufferedReader(new InputStreamReader(ris));
String line = buf.readLine();
diff --git a/luni/src/test/java/libcore/java/sql/ConnectionTest.java b/luni/src/test/java/libcore/java/sql/ConnectionTest.java
new file mode 100644
index 0000000..02046fc
--- /dev/null
+++ b/luni/src/test/java/libcore/java/sql/ConnectionTest.java
@@ -0,0 +1,69 @@
+package libcore.java.sql;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+
+public class ConnectionTest extends TestCase {
+
+ private File dbFile = null;
+ private String connectionURL = null;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // Trigger the static initializer that will cause the driver to register itself with
+ // DriverManager.
+ Class.forName("SQLite.JDBCDriver");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (dbFile != null) {
+ dbFile.delete();
+ }
+ }
+
+ public void testDriverManager_getConnection() throws Exception {
+ Connection c = DriverManager.getConnection(getConnectionURL());
+ assertFalse(c.isClosed());
+ c.close();
+ assertTrue(c.isClosed());
+ }
+
+ public void testConnect() throws Exception {
+ Driver driver = DriverManager.getDriver(getConnectionURL());
+ assertNotNull(driver);
+ Connection c = driver.connect(getConnectionURL(), null);
+ assertFalse(c.isClosed());
+ c.close();
+ assertTrue(c.isClosed());
+ }
+
+ private String getConnectionURL() {
+ if (connectionURL == null) {
+ String tmp = System.getProperty("java.io.tmpdir");
+ File tmpDir = new File(tmp);
+ if (tmpDir.isDirectory()) {
+ try {
+ dbFile = File.createTempFile("OldJDBCDriverTest", ".db", tmpDir);
+ } catch (IOException e) {
+ System.err.println("error creating temporary DB file.");
+ }
+ dbFile.deleteOnExit();
+ } else {
+ System.err.println("java.io.tmpdir does not exist");
+ }
+
+ connectionURL = "jdbc:sqlite:/" + dbFile.getPath();
+ }
+
+ return connectionURL;
+ }
+}
diff --git a/luni/src/test/java/libcore/java/sql/DriverTest.java b/luni/src/test/java/libcore/java/sql/DriverTest.java
new file mode 100644
index 0000000..59d13bd
--- /dev/null
+++ b/luni/src/test/java/libcore/java/sql/DriverTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.sql;
+
+import junit.framework.TestCase;
+
+import SQLite.JDBCDriver;
+
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+
+public final class DriverTest extends TestCase {
+
+ public static final String SQLITE_JDBC_URL = "jdbc:sqlite:/only_used_at_connect_time";
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // Trigger the static initializer that will cause the driver to register itself with
+ // DriverManager.
+ Class.forName("SQLite.JDBCDriver");
+ }
+
+ public void testDriverImplementation() throws Exception {
+ Driver driver = getDriver();
+ assertTrue(driver instanceof JDBCDriver);
+ }
+
+ public void testAcceptsURL() throws Exception {
+ Driver driver = getDriver();
+ assertTrue(driver.acceptsURL(SQLITE_JDBC_URL));
+ }
+
+ public void testGetMajorVersion() throws Exception {
+ assertTrue(getDriver().getMajorVersion() > 0);
+ }
+
+ public void testGetMinorVersion() throws Exception {
+ assertTrue(getDriver().getMinorVersion() > 0);
+ }
+
+ public void testGetPropertyInfo() throws Exception {
+ Driver driver = getDriver();
+ DriverPropertyInfo[] info = driver.getPropertyInfo(SQLITE_JDBC_URL, null);
+ assertNotNull(info);
+ assertTrue(info.length > 0);
+ }
+
+ public void testJdbcCompliant() throws Exception {
+ // The SQLite JDBC driver used by these tests is not actually JDBC compliant.
+ assertFalse(getDriver().jdbcCompliant());
+ }
+
+ private Driver getDriver() throws SQLException {
+ Driver driver = DriverManager.getDriver(SQLITE_JDBC_URL);
+ assertNotNull(driver);
+ return driver;
+ }
+}
diff --git a/luni/src/test/java/libcore/java/sql/OldResultSetTest.java b/luni/src/test/java/libcore/java/sql/OldResultSetTest.java
index ea18db6..a1654cf 100644
--- a/luni/src/test/java/libcore/java/sql/OldResultSetTest.java
+++ b/luni/src/test/java/libcore/java/sql/OldResultSetTest.java
@@ -80,7 +80,7 @@ public final class OldResultSetTest extends OldSQLTest {
try {
target.close();
- target.beforeFirst();
+ target.afterLast();
fail("Should get SQLException");
} catch (SQLException e) {
}
diff --git a/luni/src/test/java/libcore/java/sql/OldTimestampTest.java b/luni/src/test/java/libcore/java/sql/OldTimestampTest.java
deleted file mode 100644
index ab2034b..0000000
--- a/luni/src/test/java/libcore/java/sql/OldTimestampTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.sql;
-
-import java.sql.Timestamp;
-import java.util.TimeZone;
-import junit.framework.TestCase;
-
-public final class OldTimestampTest extends TestCase {
-
- public void test_toString() {
- TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-
- Timestamp t1 = new Timestamp(Long.MIN_VALUE);
- assertEquals("292278994-08-17 07:12:55.192", t1.toString());
-
- Timestamp t2 = new Timestamp(Long.MIN_VALUE + 1);
- assertEquals("292278994-08-17 07:12:55.193", t2.toString());
-
- Timestamp t3 = new Timestamp(Long.MIN_VALUE + 807);
- assertEquals("292278994-08-17 07:12:55.999", t3.toString());
-
- Timestamp t4 = new Timestamp(Long.MIN_VALUE + 808);
- assertEquals("292269055-12-02 16:47:05.0", t4.toString());
- }
-}
diff --git a/luni/src/test/java/libcore/java/sql/TimestampTest.java b/luni/src/test/java/libcore/java/sql/TimestampTest.java
new file mode 100644
index 0000000..2985848
--- /dev/null
+++ b/luni/src/test/java/libcore/java/sql/TimestampTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.sql;
+
+import java.sql.Timestamp;
+import java.util.TimeZone;
+import junit.framework.TestCase;
+
+public final class TimestampTest extends TestCase {
+
+ public void testToString() {
+ // Timestamp uses the current default timezone in toString() to convert to
+ // human-readable strings.
+ TimeZone defaultTimeZone = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+ try {
+ Timestamp t1 = new Timestamp(Long.MIN_VALUE);
+ assertEquals("292278994-08-17 07:12:55.192", t1.toString());
+
+ Timestamp t2 = new Timestamp(Long.MIN_VALUE + 1);
+ assertEquals("292278994-08-17 07:12:55.193", t2.toString());
+
+ Timestamp t3 = new Timestamp(Long.MIN_VALUE + 807);
+ assertEquals("292278994-08-17 07:12:55.999", t3.toString());
+
+ Timestamp t4 = new Timestamp(Long.MIN_VALUE + 808);
+ assertEquals("292269055-12-02 16:47:05.0", t4.toString());
+ } finally {
+ TimeZone.setDefault(defaultTimeZone);
+ }
+ }
+
+ public void testValueOf() {
+ // Timestamp uses the current default timezone in valueOf(String) to convert
+ // from human-readable strings.
+ TimeZone defaultTimeZone = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ try {
+ Timestamp t1 = Timestamp.valueOf("2001-12-31 21:45:57.123456789");
+ assertEquals(1009835157000L + 123456789 / 1000000, t1.getTime());
+ assertEquals(123456789, t1.getNanos());
+
+ Timestamp t2 = Timestamp.valueOf("2001-01-02 01:05:07.123");
+ assertEquals(978397507000L + 123000000 / 1000000, t2.getTime());
+ assertEquals(123000000, t2.getNanos());
+
+ Timestamp t3 = Timestamp.valueOf("2001-01-02 01:05:07");
+ assertEquals(978397507000L, t3.getTime());
+ assertEquals(0, t3.getNanos());
+ } finally {
+ TimeZone.setDefault(defaultTimeZone);
+ }
+ }
+
+ public void testValueOfInvalid() {
+ try {
+ Timestamp.valueOf("");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("+2001-12-31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001-+12-31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001-12-+31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("-2001-12-31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001--12-31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001-12--31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001--");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001--31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("-12-31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("-12-");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("--31");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001-12-31 21:45:57.+12345678");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001-12-31 21:45:57.-12345678");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ Timestamp.valueOf("2001-12-31 21:45:57.1234567891");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/text/CollatorTest.java b/luni/src/test/java/libcore/java/text/CollatorTest.java
index 0a61f04..0f65b20 100644
--- a/luni/src/test/java/libcore/java/text/CollatorTest.java
+++ b/luni/src/test/java/libcore/java/text/CollatorTest.java
@@ -88,7 +88,7 @@ public class CollatorTest extends junit.framework.TestCase {
}
public void testEqualsObject() throws ParseException {
- String rule = "< a < b < c < d < e";
+ String rule = "&9 < a < b < c < d < e";
RuleBasedCollator coll = new RuleBasedCollator(rule);
assertEquals(Collator.TERTIARY, coll.getStrength());
@@ -109,7 +109,7 @@ public class CollatorTest extends junit.framework.TestCase {
// Regression test for HARMONY-1352, that doesn't get run in the harmony test suite because
// of an earlier failure.
try {
- new RuleBasedCollator("< a< b< c< d").getCollationElementIterator((CharacterIterator) null);
+ new RuleBasedCollator("&9 < a< b< c< d").getCollationElementIterator((CharacterIterator) null);
fail("NullPointerException expected");
} catch (NullPointerException expected) {
}
@@ -139,7 +139,7 @@ public class CollatorTest extends junit.framework.TestCase {
}
public void testGetCollationElementIteratorString_de_DE() throws Exception {
- assertGetCollationElementIteratorString(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 1, 1, 2);
+ assertGetCollationElementIteratorString(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 2);
}
public void testGetCollationElementIteratorCharacterIterator_es() throws Exception {
@@ -147,6 +147,6 @@ public class CollatorTest extends junit.framework.TestCase {
}
public void testGetCollationElementIteratorCharacterIterator_de_DE() throws Exception {
- assertGetCollationElementIteratorCharacterIterator(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 1, 1, 2);
+ assertGetCollationElementIteratorCharacterIterator(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 2);
}
}
diff --git a/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java b/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java
index e13e4df..057cd17 100644
--- a/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java
+++ b/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java
@@ -46,6 +46,10 @@ public class DateFormatSymbolsTest extends junit.framework.TestCase {
}
public void testSerialization() throws Exception {
+ // Set the default locale. The default locale used to determine what strings were used by
+ // the DateFormatSymbols after deserialization. See http://b/16502916
+ Locale.setDefault(Locale.US);
+
// The Polish language needs stand-alone month and weekday names.
Locale pl = new Locale("pl");
DateFormatSymbols originalDfs = new DateFormatSymbols(pl);
@@ -60,17 +64,16 @@ public class DateFormatSymbolsTest extends junit.framework.TestCase {
DateFormatSymbols deserializedDfs = (DateFormatSymbols) in.readObject();
assertEquals(-1, in.read());
- // The two objects should claim to be equal, even though they aren't really.
+ // The two objects be equal.
assertEquals(originalDfs, deserializedDfs);
// The original differentiates between regular month names and stand-alone month names...
assertEquals("stycznia", formatDate(pl, "MMMM", originalDfs));
assertEquals("stycze\u0144", formatDate(pl, "LLLL", originalDfs));
- // But the deserialized object is screwed because the RI's serialized form doesn't
- // contain the locale or the necessary strings. Don't serialize DateFormatSymbols, folks!
+ // And so does the deserialized version.
assertEquals("stycznia", formatDate(pl, "MMMM", deserializedDfs));
- assertEquals("January", formatDate(pl, "LLLL", deserializedDfs));
+ assertEquals("stycze\u0144", formatDate(pl, "LLLL", deserializedDfs));
}
private String formatDate(Locale l, String fmt, DateFormatSymbols dfs) {
diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java
index 8b24c6d..619c38e 100644
--- a/luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java
+++ b/luni/src/test/java/libcore/java/text/DecimalFormatSymbolsTest.java
@@ -24,18 +24,21 @@ import java.text.DecimalFormatSymbols;
import java.util.Locale;
public class DecimalFormatSymbolsTest extends junit.framework.TestCase {
- private void checkLocaleIsEquivalentToRoot(Locale locale) {
- DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
- assertEquals(DecimalFormatSymbols.getInstance(Locale.ROOT), dfs);
- }
public void test_getInstance_unknown_or_invalid_locale() throws Exception {
- // TODO: we fail these tests because ROOT has "INF" for infinity but 'dfs' has "\u221e".
- // On the RI, ROOT has "\u221e" too, but DecimalFormatSymbols.equals appears to be broken;
- // it returns false for objects that -- if you compare their externally visible state --
- // are equal. It could be that they're accidentally checking the Locale.
+ // http://b/17374604: this test passes on the host but fails on the target.
+ // ICU uses setlocale(3) to determine its default locale, and glibc (on my box at least)
+ // returns "en_US.UTF-8". bionic before L returned NULL and in L returns "C.UTF-8", both
+ // of which get treated as "en_US_POSIX". What that means for this test is that you get
+ // "INF" for infinity instead of "\u221e".
+ // On the RI, this test fails for a different reason: their DecimalFormatSymbols.equals
+ // appears to be broken. It could be that they're accidentally checking the Locale field?
checkLocaleIsEquivalentToRoot(new Locale("xx", "XX"));
checkLocaleIsEquivalentToRoot(new Locale("not exist language", "not exist country"));
}
+ private void checkLocaleIsEquivalentToRoot(Locale locale) {
+ DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
+ assertEquals(DecimalFormatSymbols.getInstance(Locale.ROOT), dfs);
+ }
// http://code.google.com/p/android/issues/detail?id=14495
public void testSerialization() throws Exception {
diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
index 1e40f8a..0eae20a 100644
--- a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
@@ -21,7 +21,9 @@ import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
+import java.text.FieldPosition;
import java.text.NumberFormat;
+import java.text.ParsePosition;
import java.util.Currency;
import java.util.Locale;
@@ -122,21 +124,21 @@ public class DecimalFormatTest extends junit.framework.TestCase {
df.setMaximumFractionDigits(2);
df.setMultiplier(2);
assertEquals(df.format(BigDecimal.valueOf(0.16)),
- df.format(BigDecimal.valueOf(0.16).doubleValue()));
+ df.format(BigDecimal.valueOf(0.16).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(0.0293)),
- df.format(BigDecimal.valueOf(0.0293).doubleValue()));
+ df.format(BigDecimal.valueOf(0.0293).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(0.006)),
- df.format(BigDecimal.valueOf(0.006).doubleValue()));
+ df.format(BigDecimal.valueOf(0.006).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(0.00283)),
- df.format(BigDecimal.valueOf(0.00283).doubleValue()));
+ df.format(BigDecimal.valueOf(0.00283).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(1.60)),
df.format(BigDecimal.valueOf(1.60).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(15)),
- df.format(BigDecimal.valueOf(15).doubleValue()));
+ df.format(BigDecimal.valueOf(15).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(170)),
- df.format(BigDecimal.valueOf(170).doubleValue()));
+ df.format(BigDecimal.valueOf(170).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(234.56)),
- df.format(BigDecimal.valueOf(234.56).doubleValue()));
+ df.format(BigDecimal.valueOf(234.56).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(0)),
df.format(BigDecimal.valueOf(0).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(-1)),
@@ -144,11 +146,11 @@ public class DecimalFormatTest extends junit.framework.TestCase {
assertEquals(df.format(BigDecimal.valueOf(-10000)),
df.format(BigDecimal.valueOf(-10000).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(-0.001)),
- df.format(BigDecimal.valueOf(-0.001).doubleValue()));
+ df.format(BigDecimal.valueOf(-0.001).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
- df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
+ df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
- df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+ df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
}
private void assertBigDecimalWithFraction(BigDecimal bd, String expectedResult, int fraction) {
@@ -197,4 +199,123 @@ public class DecimalFormatTest extends junit.framework.TestCase {
df.setCurrency(Currency.getInstance("CHF"));
df.setCurrency(Currency.getInstance("GBP"));
}
+
+ // Check we don't crash on null inputs.
+ public void testBug15081434() throws Exception {
+ DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.US);
+ try {
+ df.parse(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ df.applyLocalizedPattern(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ df.applyPattern(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ df.applyPattern(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ df.format(null, new StringBuffer(), new FieldPosition(0));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ df.parse(null, new ParsePosition(0));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // This just ignores null.
+ df.setDecimalFormatSymbols(null);
+
+ try {
+ df.setCurrency(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ // These just ignore null.
+ df.setNegativePrefix(null);
+ df.setNegativeSuffix(null);
+ df.setPositivePrefix(null);
+ df.setPositiveSuffix(null);
+
+ try {
+ df.setRoundingMode(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ // Confirm the fraction digits do not change when the currency is changed.
+ public void testBug71369() {
+ final String nonBreakingSpace = "\u00A0";
+
+ NumberFormat numberFormat = NumberFormat.getCurrencyInstance(Locale.GERMAN);
+ numberFormat.setCurrency(Currency.getInstance("USD"));
+
+ assertEquals("2,01" + nonBreakingSpace + "$", numberFormat.format(2.01));
+
+ numberFormat.setMinimumFractionDigits(0);
+ numberFormat.setMaximumFractionDigits(0);
+
+ String expected = "2" + nonBreakingSpace + "$";
+ assertEquals(expected, numberFormat.format(2.01));
+
+ // Changing the currency must not reset the digits.
+ numberFormat.setCurrency(Currency.getInstance("EUR"));
+ numberFormat.setCurrency(Currency.getInstance("USD"));
+
+ assertEquals(expected, numberFormat.format(2.01));
+ }
+
+ // Confirm the currency symbol used by a format is determined by the locale of the format
+ // not the current default Locale.
+ public void testSetCurrency_symbolOrigin() {
+ Currency currency = Currency.getInstance("CNY");
+ Locale locale1 = Locale.CHINA;
+ Locale locale2 = Locale.US;
+ String locale1Symbol = currency.getSymbol(locale1);
+ String locale2Symbol = currency.getSymbol(locale2);
+ // This test only works if we can tell where the symbol came from, which requires they are
+ // different across the two locales chosen.
+ assertFalse(locale1Symbol.equals(locale2Symbol));
+
+ Locale originalLocale = Locale.getDefault();
+ try {
+ Locale.setDefault(locale1);
+ String amountDefaultLocale1 =
+ formatArbitraryCurrencyAmountInLocale(currency, locale2);
+
+ Locale.setDefault(locale2);
+ String amountDefaultLocale2 =
+ formatArbitraryCurrencyAmountInLocale(currency, locale2);
+
+ // This used to fail because Currency.getSymbol() was used without providing the
+ // format's locale.
+ assertEquals(amountDefaultLocale1, amountDefaultLocale2);
+ } finally {
+ Locale.setDefault(originalLocale);
+ }
+ }
+
+ private String formatArbitraryCurrencyAmountInLocale(Currency currency, Locale locale) {
+ NumberFormat localeCurrencyFormat = NumberFormat.getCurrencyInstance(locale);
+ localeCurrencyFormat.setCurrency(currency);
+ return localeCurrencyFormat.format(1000);
+ }
}
diff --git a/luni/src/test/java/libcore/java/text/NumberFormatTest.java b/luni/src/test/java/libcore/java/text/NumberFormatTest.java
index 1a14462..4ff063b 100644
--- a/luni/src/test/java/libcore/java/text/NumberFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/NumberFormatTest.java
@@ -66,16 +66,16 @@ public class NumberFormatTest extends junit.framework.TestCase {
public void test_getIntegerInstance_ar() throws Exception {
NumberFormat numberFormat = NumberFormat.getNumberInstance(new Locale("ar"));
- assertEquals("#0.###;#0.###-", ((DecimalFormat) numberFormat).toPattern());
+ assertEquals("#,##0.###", ((DecimalFormat) numberFormat).toPattern());
NumberFormat integerFormat = NumberFormat.getIntegerInstance(new Locale("ar"));
- assertEquals("#0;#0-", ((DecimalFormat) integerFormat).toPattern());
+ assertEquals("#,##0", ((DecimalFormat) integerFormat).toPattern());
}
public void test_numberLocalization() throws Exception {
Locale arabic = new Locale("ar");
NumberFormat nf = NumberFormat.getNumberInstance(arabic);
assertEquals('\u0660', new DecimalFormatSymbols(arabic).getZeroDigit());
- assertEquals("١٢٣٤٥٦٧٨٩٠", nf.format(1234567890));
+ assertEquals("١٬٢٣٤٬٥٦٧٬٨٩٠", nf.format(1234567890));
}
// Formatting percentages is confusing but deliberate.
@@ -90,4 +90,40 @@ public class NumberFormatTest extends junit.framework.TestCase {
} catch (IllegalArgumentException expected) {
}
}
+
+ public void test_62269() throws Exception {
+ NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
+ try {
+ nf.parse(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_nullLocales() {
+ try {
+ NumberFormat.getInstance(null);
+ fail();
+ } catch (NullPointerException expected) {}
+
+ try {
+ NumberFormat.getIntegerInstance(null);
+ fail();
+ } catch (NullPointerException expected) {}
+
+ try {
+ NumberFormat.getCurrencyInstance(null);
+ fail();
+ } catch (NullPointerException expected) {}
+
+ try {
+ NumberFormat.getPercentInstance(null);
+ fail();
+ } catch (NullPointerException expected) {}
+
+ try {
+ NumberFormat.getNumberInstance(null);
+ fail();
+ } catch (NullPointerException expected) {}
+ }
}
diff --git a/luni/src/test/java/libcore/java/text/OldBidiTest.java b/luni/src/test/java/libcore/java/text/OldBidiTest.java
index 2e5fd21..45fe258 100644
--- a/luni/src/test/java/libcore/java/text/OldBidiTest.java
+++ b/luni/src/test/java/libcore/java/text/OldBidiTest.java
@@ -22,11 +22,9 @@ import junit.framework.TestCase;
public class OldBidiTest extends TestCase {
- Bidi bd;
-
public void testToString() {
try {
- bd = new Bidi("bidi", 173);
+ Bidi bd = new Bidi("bidi", 173);
assertNotNull("Bidi representation is null", bd.toString());
} catch (Exception e) {
fail("Unexpected exception " + e.toString());
@@ -41,7 +39,7 @@ public class OldBidiTest extends TestCase {
}
public void testGetRunLevelLInt() {
- bd = new Bidi("text", Bidi.DIRECTION_LEFT_TO_RIGHT);
+ Bidi bd = new Bidi("text", Bidi.DIRECTION_LEFT_TO_RIGHT);
try {
assertEquals(0, bd.getRunLevel(0));
assertEquals(0, bd.getRunLevel(bd.getRunCount()));
@@ -65,25 +63,11 @@ public class OldBidiTest extends TestCase {
}
public void testGetRunStart() {
- bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -7,
+ Bidi bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -7,
(byte) -2, (byte) 3 }, 0, 3,
Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
assertEquals(0, bd.getRunStart(0));
assertEquals(1, bd.getRunStart(1));
assertEquals(2, bd.getRunStart(2));
-
- String LTR = "\u0061\u0062";
- String RTL = "\u05DC\u05DD";
- String newLine = "\n";
- String defText = LTR + newLine + RTL + LTR + RTL;
-
- int[][] expectedRuns = { { 0, 3 }, { 3, 5 }, { 5, 7 }, { 7, 9 }, };
-
- Bidi bi = new Bidi(defText, 0);
-
- final int count = bi.getRunCount();
- for (int i = 0; i < count; i++) {
- assertEquals(expectedRuns[i][0], bi.getRunStart(i));
- }
}
}
diff --git a/luni/src/test/java/libcore/java/text/OldCollationElementIteratorTest.java b/luni/src/test/java/libcore/java/text/OldCollationElementIteratorTest.java
deleted file mode 100644
index 9e98a56..0000000
--- a/luni/src/test/java/libcore/java/text/OldCollationElementIteratorTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.text;
-
-import java.text.CollationElementIterator;
-import java.text.Collator;
-import java.text.RuleBasedCollator;
-import java.util.Locale;
-import junit.framework.TestCase;
-
-public class OldCollationElementIteratorTest extends TestCase {
-
- public void testPrevious() {
- RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(Locale.US);
- String text = "abc";
- CollationElementIterator iterator = coll
- .getCollationElementIterator(text);
- int[] orders = new int[text.length()];
- int order = iterator.next();
- int i = 0;
- while (order != CollationElementIterator.NULLORDER) {
- orders[i++] = order;
- order = iterator.next();
- }
-
- int offset = iterator.getOffset();
- assertEquals(text.length(), offset);
- order = iterator.previous();
-
- while (order != CollationElementIterator.NULLORDER) {
- assertEquals(orders[--i], order);
- order = iterator.previous();
- }
-
- assertEquals(0, iterator.getOffset());
- }
-}
diff --git a/luni/src/test/java/libcore/java/text/OldCollationKeyTest.java b/luni/src/test/java/libcore/java/text/OldCollationKeyTest.java
index 1fc8264..eea5246 100644
--- a/luni/src/test/java/libcore/java/text/OldCollationKeyTest.java
+++ b/luni/src/test/java/libcore/java/text/OldCollationKeyTest.java
@@ -24,7 +24,7 @@ import java.text.RuleBasedCollator;
public class OldCollationKeyTest extends junit.framework.TestCase {
- public void test_toByteArray() {
+ public void test_toByteArray() throws ParseException {
// Test for method byte [] java.text.CollationKey.toByteArray()
Collator collator = Collator.getInstance();
collator.setStrength(Collator.PRIMARY);
@@ -32,12 +32,7 @@ public class OldCollationKeyTest extends junit.framework.TestCase {
byte[] bytes = key1.toByteArray();
assertTrue("Not enough bytes", bytes.length >= 3);
- try {
- collator = new RuleBasedCollator("= 1 , 2 ; 3 , 4 < 5 ; 6 , 7");
- } catch (ParseException e) {
- fail("ParseException");
- return;
- }
+ collator = new RuleBasedCollator("&0 = 1 , 2 ; 3 , 4 < 5 ; 6 , 7");
/*
* CollationElementIterator it =
* ((RuleBasedCollator)collator).getCollationElementIterator("1234567");
diff --git a/luni/src/test/java/libcore/java/text/OldDecimalFormatTest.java b/luni/src/test/java/libcore/java/text/OldDecimalFormatTest.java
deleted file mode 100644
index f3e016e..0000000
--- a/luni/src/test/java/libcore/java/text/OldDecimalFormatTest.java
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.text;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.text.AttributedCharacterIterator;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.FieldPosition;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.BitSet;
-import java.util.Locale;
-import junit.framework.TestCase;
-import tests.support.Support_DecimalFormat;
-
-public class OldDecimalFormatTest extends TestCase {
-
- public void test_formatToCharacterIterator() throws Exception {
- AttributedCharacterIterator iterator;
- int[] runStarts;
- int[] runLimits;
- String result;
- char current;
-
- // For BigDecimal with multiplier test.
- DecimalFormat df = new DecimalFormat();
- df.setMultiplier(10);
- iterator = df.formatToCharacterIterator(new BigDecimal("12345678901234567890"));
- result = "123,456,789,012,345,678,900";
- current = iterator.current();
- for (int i = 0; i < result.length(); i++) {
- assertEquals("wrong char @" + i, result.charAt(i), current);
- current = iterator.next();
- }
-
- // For BigDecimal with multiplier test.
- df = new DecimalFormat();
- df.setMultiplier(-1);
- df.setMaximumFractionDigits(20);
- iterator = df.formatToCharacterIterator(new BigDecimal("1.23456789012345678901"));
- result = "-1.23456789012345678901";
- current = iterator.current();
- for (int i = 0; i < result.length(); i++) {
- assertEquals("wrong char @" + i, result.charAt(i), current);
- current = iterator.next();
- }
-
- iterator = new DecimalFormat()
- .formatToCharacterIterator(new BigDecimal("1.23456789E1234"));
- runStarts = new int[] {0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14};
- runLimits = new int[] {2, 2, 3, 6, 6, 6, 7, 10, 10, 10, 11, 14, 14, 14, 15};
- result = "12,345,678,900,"; // 000,000,000,000....
- current = iterator.current();
- for (int i = 0; i < runStarts.length; i++) {
- assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
- assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
- assertEquals("wrong char @" + i, result.charAt(i), current);
- current = iterator.next();
- }
- assertEquals(0, iterator.getBeginIndex());
- assertEquals(1646, iterator.getEndIndex());
-
- iterator = new DecimalFormat()
- .formatToCharacterIterator(new BigDecimal("1.23456789E301"));
- runStarts = new int[] {0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14};
- runLimits = new int[] {2, 2, 3, 6, 6, 6, 7, 10, 10, 10, 11, 14, 14, 14, 15};
- result = "12,345,678,900,"; // 000,000,000,000....
- current = iterator.current();
- for (int i = 0; i < runStarts.length; i++) {
- assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
- assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
- assertEquals("wrong char @" + i, result.charAt(i), current);
- current = iterator.next();
- }
- assertEquals(0, iterator.getBeginIndex());
- assertEquals(402, iterator.getEndIndex());
-
- iterator = new DecimalFormat()
- .formatToCharacterIterator(new BigDecimal("1.2345678E4"));
- runStarts = new int[] {0, 0, 2, 3, 3, 3, 6, 7, 7, 7};
- runLimits = new int[] {2, 2, 3, 6, 6, 6, 7, 10, 10, 10};
- result = "12,345.678";
- current = iterator.current();
- for (int i = 0; i < runStarts.length; i++) {
- assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
- assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
- assertEquals("wrong char @" + i, result.charAt(i), current);
- current = iterator.next();
- }
- assertEquals(0, iterator.getBeginIndex());
- assertEquals(10, iterator.getEndIndex());
-
- iterator = new DecimalFormat()
- .formatToCharacterIterator(new BigInteger("123456789"));
- runStarts = new int[] {0, 0, 0, 3, 4, 4, 4, 7, 8, 8, 8};
- runLimits = new int[] {3, 3, 3, 4, 7, 7, 7, 8, 11, 11, 11};
- result = "123,456,789";
- current = iterator.current();
- for (int i = 0; i < runStarts.length; i++) {
- assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
- assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
- assertEquals("wrong char @" + i, result.charAt(i), current);
- current = iterator.next();
- }
- assertEquals(0, iterator.getBeginIndex());
- assertEquals(11, iterator.getEndIndex());
- }
-
- /*
- * Test the getter and setter of parseBigDecimal and parseIntegerOnly and
- * test the default value of them.
- */
- public void test_isParseBigDecimalLjava_lang_Boolean_isParseIntegerOnlyLjava_lang_Boolean() {
-
- // parseBigDecimal default to false
- DecimalFormat form = (DecimalFormat) DecimalFormat
- .getInstance(Locale.US);
- assertFalse(form.isParseBigDecimal());
- form.setParseBigDecimal(true);
- assertTrue(form.isParseBigDecimal());
-
- try {
- Number result = form.parse("123.123");
- assertEquals(new BigDecimal("123.123"), result);
- } catch (ParseException e) {
- fail("ParseException was thrown.");
- }
-
- form.setParseBigDecimal(false);
- assertFalse(form.isParseBigDecimal());
-
- try {
- Number result = form.parse("123.123");
- assertFalse(result instanceof BigDecimal);
- } catch (ParseException e) {
- fail("ParseException was thrown.");
- }
-
- // parseIntegerOnly default to false
- assertFalse(form.isParseIntegerOnly());
- }
-
- public void test_isParseIntegerOnly() {
-
- DecimalFormat format = new DecimalFormat();
- assertFalse("Default value of isParseIntegerOnly is true",
- format.isParseIntegerOnly());
-
- format.setParseIntegerOnly(true);
- assertTrue(format.isParseIntegerOnly());
- try {
- Number result = format.parse("123.123");
- assertEquals(new Long("123"), result);
- } catch (ParseException e) {
- fail("ParseException was thrown.");
- }
-
- format.setParseIntegerOnly(false);
- assertFalse(format.isParseIntegerOnly());
- try {
- Number result = format.parse("123.123");
- assertEquals(new Double("123.123"), result);
- } catch (ParseException e) {
- fail("ParseException was thrown.");
- }
- }
-
- public void test_isGroupingUsed() {
- String [] patterns = {"####.##", "######.######", "000000.000000",
- "######.000000", "000000.######", " ###.###", "$#####.######",
- "$$####.######"};
-
- for(String pattern:patterns) {
- DecimalFormat format = new DecimalFormat(pattern);
- assertFalse(format.isGroupingUsed());
- }
-
- DecimalFormat format = new DecimalFormat("###,####");
- assertTrue(format.isGroupingUsed());
- }
-
- // Test the type of the returned object
- public void test_parseLjava_lang_String_Ljava_text_ParsePosition() {
- DecimalFormat form = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
- form.setParseIntegerOnly(true);
- form.setParseBigDecimal(true);
-
- final String doubleMax2 = "359,538,626,972,463,141,629,054,847,463,408,"
- + "713,596,141,135,051,689,993,197,834,953,606,314,521,560,057,077,"
- + "521,179,117,265,533,756,343,080,917,907,028,764,928,468,642,653,"
- + "778,928,365,536,935,093,407,075,033,972,099,821,153,102,564,152,"
- + "490,980,180,778,657,888,151,737,016,910,267,884,609,166,473,806,"
- + "445,896,331,617,118,664,246,696,549,595,652,408,289,446,337,476,"
- + "354,361,838,599,762,500,808,052,368,249,716,736";
- Number number = form.parse(doubleMax2, new ParsePosition(0));
- assertTrue(number instanceof BigDecimal);
- BigDecimal result = (BigDecimal)number;
- assertEquals(new BigDecimal(Double.MAX_VALUE).add(new BigDecimal(
- Double.MAX_VALUE)), result);
- }
-
- // AndroidOnly: Difference to RI
- public void test_getMaximumIntegerDigits_AndroidOnly() {
- final int maxIntDigit = 309;
-
- // When use default locale, in this case zh_CN
- // the returned instance of NumberFormat is a DecimalFormat
- DecimalFormat form = new DecimalFormat("00.###E0");
- NumberFormat nform = DecimalFormat.getInstance(Locale.US);
- nform = DecimalFormat.getInstance(Locale.US);
- form = null;
- if (nform instanceof DecimalFormat) {
- form = (DecimalFormat) nform;
- }
- // getMaximumIntegerDigits from NumberFormat default to 309
- // getMaximumIntegerDigits from DecimalFormat default to 309
- // the following 2 assertions will fail on RI implementation, since the
- // implementation of ICU and RI are not identical. RI does not give
- // DecimalFormat an initial bound about its maximumIntegerDigits
- // (default to Integer.MAX_VALUE: 2147483647 )
- assertEquals(maxIntDigit, nform.getMaximumIntegerDigits());
- assertEquals(maxIntDigit, form.getMaximumIntegerDigits());
- }
-
- // AndroidOnly: second 0 needs to be quoted in icu.
- // (quoting special characters in prefix and suffix necessary)
- public void test_getMaximumIntegerDigits2() {
- // regression test for HARMONY-878
- assertTrue(new DecimalFormat("0\t'0'").getMaximumIntegerDigits() > 0);
- }
-
- public void test_setPositivePrefixLjava_lang_String() {
- DecimalFormat format = new DecimalFormat();
- assertEquals("", format.getPositivePrefix());
-
- format.setPositivePrefix("PosPrf");
- assertEquals("PosPrf", format.getPositivePrefix());
- try {
- assertTrue(format.parse("PosPrf123.45").doubleValue() == 123.45);
- } catch(java.text.ParseException pe) {
- fail("ParseException was thrown.");
- }
-
- format.setPositivePrefix("");
- assertEquals("", format.getPositivePrefix());
-
- format.setPositivePrefix(null);
- assertNull(format.getPositivePrefix());
- }
- public void test_setPositiveSuffixLjava_lang_String() {
- DecimalFormat format = new DecimalFormat();
- assertEquals("", format.getPositiveSuffix());
-
- format.setPositiveSuffix("PosSfx");
- assertEquals("PosSfx", format.getPositiveSuffix());
- try {
- assertTrue(format.parse("123.45PosSfx").doubleValue() == 123.45);
- } catch(java.text.ParseException pe) {
- fail("ParseException was thrown.");
- }
-
- format.setPositiveSuffix("");
- assertEquals("", format.getPositiveSuffix());
-
- format.setPositiveSuffix(null);
- assertNull(format.getPositiveSuffix());
- }
- public void test_setNegativePrefixLjava_lang_String() {
- DecimalFormat format = new DecimalFormat();
- assertEquals("-", format.getNegativePrefix());
-
- format.setNegativePrefix("NegPrf");
- assertEquals("NegPrf", format.getNegativePrefix());
- try {
- assertTrue(format.parse("NegPrf123.45").doubleValue() == -123.45);
- } catch(java.text.ParseException pe) {
- fail("ParseException was thrown.");
- }
- format.setNegativePrefix("");
- assertEquals("", format.getNegativePrefix());
-
- format.setNegativePrefix(null);
- assertNull(format.getNegativePrefix());
- }
- public void test_setNegativeSuffixLjava_lang_String() {
- DecimalFormat format = new DecimalFormat();
- assertEquals("", format.getNegativeSuffix());
-
- format.setNegativeSuffix("NegSfx");
- assertEquals("NegSfx", format.getNegativeSuffix());
- try {
- assertTrue(format.parse("123.45NegPfx").doubleValue() == 123.45);
- } catch(java.text.ParseException pe) {
- fail("ParseException was thrown.");
- }
-
- format.setNegativeSuffix("");
- assertEquals("", format.getNegativeSuffix());
-
- format.setNegativeSuffix(null);
- assertNull(format.getNegativeSuffix());
- }
-
- public void test_toLocalizedPattern() {
- DecimalFormat format = new DecimalFormat();
- format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
- try {
- format.applyLocalizedPattern("#.#");
- assertEquals("Wrong pattern 1", "#0.#", format.toLocalizedPattern());
- format.applyLocalizedPattern("#.");
- assertEquals("Wrong pattern 2", "#0.", format.toLocalizedPattern());
- format.applyLocalizedPattern("#");
- assertEquals("Wrong pattern 3", "#", format.toLocalizedPattern());
- format.applyLocalizedPattern(".#");
- assertEquals("Wrong pattern 4", "#.0", format.toLocalizedPattern());
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_toPattern() {
- DecimalFormat format = new DecimalFormat();
- try {
- format.applyPattern("#.#");
- assertEquals("Wrong pattern 1", "#0.#", format.toPattern());
- format.applyPattern("#.");
- assertEquals("Wrong pattern 2", "#0.", format.toPattern());
- format.applyPattern("#");
- assertEquals("Wrong pattern 3", "#", format.toPattern());
- format.applyPattern(".#");
- assertEquals("Wrong pattern 4", "#.0", format.toPattern());
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
- public void test_setGroupingUse() {
- DecimalFormat format = new DecimalFormat();
-
- StringBuffer buf = new StringBuffer();
- format.setGroupingUsed(false);
- format.format(new Long(1970), buf, new FieldPosition(0));
- assertEquals("1970", buf.toString());
- assertFalse(format.isGroupingUsed());
- format.format(new Long(1970), buf, new FieldPosition(0));
- assertEquals("19701970", buf.toString());
- assertFalse(format.isGroupingUsed());
-
- format.setGroupingUsed(true);
- format.format(new Long(1970), buf, new FieldPosition(0));
- assertEquals("197019701,970", buf.toString());
- assertTrue(format.isGroupingUsed());
- }
-
- public void test_Constructor() {
- // Test for method java.text.DecimalFormat()
- // the constructor form that specifies a pattern is equal to the form
- // constructed with no pattern and applying that pattern using the
- // applyPattern call
- try {
- DecimalFormat format1 = new DecimalFormat();
- format1.applyPattern("'$'1000.0000");
- DecimalFormat format2 = new DecimalFormat();
- format2.applyPattern("'$'1000.0000");
- assertTrue(
- "Constructed format did not match applied format object",
- format2.equals(format1));
- DecimalFormat format3 = new DecimalFormat("'$'1000.0000");
- assertTrue(
- "Constructed format did not match applied format object",
- format3.equals(format1));
- DecimalFormat format4 = new DecimalFormat("'$'8000.0000");
- assertTrue(
- "Constructed format did not match applied format object",
- !format4.equals(format1));
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.text.DecimalFormat(java.lang.String)
- // the constructor form that specifies a pattern is equal to the form
- // constructed with no pattern and applying that pattern using the
- // applyPattern call
- DecimalFormat format = new DecimalFormat("'$'0000.0000");
- DecimalFormat format1 = new DecimalFormat();
- format1.applyPattern("'$'0000.0000");
- assertTrue("Constructed format did not match applied format object",
- format.equals(format1));
-
- String [] patterns = {"####.##", "######.######", "000000.000000",
- "######.000000", "000000.######", " ###.###", "$#####.######",
- "$$####.######", "%#,##,###,####", "#,##0.00;(#,##0.00)"};
-
- for(String str:patterns) {
- new DecimalFormat(str);
- }
-
- try {
- new DecimalFormat(null);
- fail("NullPointerException wasn't thrown.");
- } catch(NullPointerException npe){
- //expected
- }
-
- String [] incPatterns = {"%#,##,###,####'", "#.##0.00"};
- for(String str:incPatterns) {
- try {
- new DecimalFormat(str);
- fail("IllegalArgumentException wasn't thrown for pattern: " + str);
- } catch(IllegalArgumentException iae){
- //expected
- }
- }
- }
-
- /**
- * Case 1: Try to construct object using correct pattern and fromat symbols.
- * Case 2: Try to construct object using null arguments.
- * Case 3: Try to construct object using incorrect pattern.
- */
- public void test_ConstructorLjava_lang_StringLjava_text_DecimalFormatSymbols() {
- try {
- // case 1: Try to construct object using correct pattern and fromat
- // symbols.
- DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.CANADA);
- DecimalFormat format1 = new DecimalFormat("'$'1000.0000", dfs);
- DecimalFormat format2 = new DecimalFormat();
- format2.applyPattern("'$'1000.0000");
- format2.setDecimalFormatSymbols(dfs);
- assertTrue(
- "Constructed format did not match applied format object",
- format2.equals(format1));
- assertTrue(
- "Constructed format did not match applied format object",
- !format1.equals(new DecimalFormat("'$'1000.0000",
- new DecimalFormatSymbols(Locale.CHINA))));
-
- // case 2: Try to construct object using null arguments.
- try {
- new DecimalFormat("'$'1000.0000", (DecimalFormatSymbols) null);
- fail("Expected NullPointerException was not thrown");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- new DecimalFormat(null, new DecimalFormatSymbols());
- fail("Expected NullPointerException was not thrown");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- new DecimalFormat(null, (DecimalFormatSymbols) null);
- fail("Expected NullPointerException was not thrown");
- } catch (NullPointerException e) {
- // expected
- }
-
- // case 3: Try to construct object using incorrect pattern.
- try {
- new DecimalFormat("$'", new DecimalFormatSymbols());
- fail("Expected IllegalArgumentException was not thrown");
- } catch (IllegalArgumentException e) {
- // expected
- }
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- /**
- * Case 1: Try to apply correct variants of pattern.
- * Case 2: Try to apply malformed patten. Case 3: Try to apply null pattern.
- */
- public void test_applyLocalizedPatternLjava_lang_String() {
- DecimalFormat format = new DecimalFormat();
- try {
- // case 1: Try to apply correct variants of pattern.
- format.applyLocalizedPattern("#.#");
- assertEquals("Wrong pattern 1", "#0.#", format.toLocalizedPattern());
- format.applyLocalizedPattern("#.");
- assertEquals("Wrong pattern 2", "#0.", format.toLocalizedPattern());
- format.applyLocalizedPattern("#");
- assertEquals("Wrong pattern 3", "#", format.toLocalizedPattern());
- format.applyLocalizedPattern(".#");
- assertEquals("Wrong pattern 4", "#.0", format.toLocalizedPattern());
-
- // case 2: Try to apply malformed patten.
- try {
- format.applyLocalizedPattern("'#,#:#0.0#;(#)");
- fail("Expected IllegalArgumentException was not thrown");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- // case 3: Try to apply null patern.
- try {
- format.applyLocalizedPattern((String) null);
- fail("Expected NullPointerException was not thrown");
- } catch (NullPointerException e) {
- // expected
- }
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_applyPatternLjava_lang_String() {
- DecimalFormat format = new DecimalFormat("#.#");
- assertEquals("Wrong pattern 1", "#0.#", format.toPattern());
- format = new DecimalFormat("#.");
- assertEquals("Wrong pattern 2", "#0.", format.toPattern());
- format = new DecimalFormat("#");
- assertEquals("Wrong pattern 3", "#", format.toPattern());
- format = new DecimalFormat(".#");
- assertEquals("Wrong pattern 4", "#.0", format.toPattern());
-
- DecimalFormat decFormat = new DecimalFormat("#.#");
-
- try {
- decFormat.applyPattern(null);
- fail("NullPointerException was not thrown.");
- } catch(NullPointerException npe) {
- //expected
- }
-
- String [] incPatterns = {"%#,##,###,####'", "#.##0.00"};
- for(String str:incPatterns) {
- try {
- decFormat.applyPattern(str);
- fail("IllegalArgumentException was not thrown for pattern: " +
- str);
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
- }
-
- // AndroidOnly: icu supports 2 grouping sizes
- public void test_applyPatternLjava_lang_String2() {
- DecimalFormat decFormat = new DecimalFormat("#.#");
- String [] patterns = {"####.##", "######.######", "000000.000000",
- "######.000000", "000000.######", " ###.###", "$#####.######",
- "$$####.######", "%#,##,###,####", "#,##0.00;(#,##0.00)",
- "##.##-E"};
-
- String [] expResult = {"#0.##", "#0.######", "#000000.000000",
- "#.000000", "#000000.######", " #0.###", "$#0.######",
- "$$#0.######",
- "%#,###,####", // icu only. icu supports two grouping sizes
- "#,##0.00;(#,##0.00)",
- "#0.##-'E'"}; // icu only. E in the suffix does not need to be
- // quoted. This is done automatically.
-
- for (int i = 0; i < patterns.length; i++) {
- decFormat.applyPattern(patterns[i]);
- String result = decFormat.toPattern();
- assertEquals("Failed to apply following pattern: " + patterns[i] +
- " expected: " + expResult[i] + " returned: " + result,
- expResult[i], result);
- }
- }
-
- public void test_clone() {
- DecimalFormat format = (DecimalFormat) DecimalFormat
- .getInstance(Locale.US);
- DecimalFormat cloned = (DecimalFormat) format.clone();
- assertEquals(cloned.getDecimalFormatSymbols(), format
- .getDecimalFormatSymbols());
-
- format = new DecimalFormat("'$'0000.0000");
- DecimalFormat format1 = (DecimalFormat) (format.clone());
- // make sure the objects are equal
- assertTrue("Object's clone isn't equal!", format.equals(format1));
- // change the content of the clone and make sure it's not equal anymore
- // verifies that it's data is now distinct from the original
- format1.applyPattern("'$'0000.####");
- assertTrue("Object's changed clone should not be equal!", !format
- .equals(format1));
- }
-
- private void compare(String testName, String format, String expected) {
- assertTrue(testName + " got: " + format + " expected: " + expected,
- format.equals(expected));
- }
-
- private boolean compare(int count, String format, String expected) {
- boolean result = format.equals(expected);
- if (!result)
- System.out.println("Failure test: " + count + " got: " + format
- + " expected: " + expected);
- return result;
- }
-
- public void test_formatDLjava_lang_StringBufferLjava_text_FieldPosition() {
- new Support_DecimalFormat(
- "test_formatDLjava_lang_StringBufferLjava_text_FieldPosition")
- .t_format_with_FieldPosition();
-
- int failCount = 0;
- BitSet failures = new BitSet();
-
- final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
-
- DecimalFormat df = new DecimalFormat("00.0#E0", dfs);
- compare("00.0#E0: 0.0", df.format(0.0), "00.0E0");
- compare("00.0#E0: 1.0", df.format(1.0), "10.0E-1");
- compare("00.0#E0: 12.0", df.format(12.0), "12.0E0");
- compare("00.0#E0: 123.0", df.format(123.0), "12.3E1");
- compare("00.0#E0: 1234.0", df.format(1234.0), "12.34E2");
- compare("00.0#E0: 12346.0", df.format(12346.0), "12.35E3");
- compare("00.0#E0: 99999.0", df.format(99999.0), "10.0E4");
- compare("00.0#E0: 1.2", df.format(1.2), "12.0E-1");
- compare("00.0#E0: 12.3", df.format(12.3), "12.3E0");
- compare("00.0#E0: 123.4", df.format(123.4), "12.34E1");
- compare("00.0#E0: 1234.6", df.format(1234.6), "12.35E2");
- compare("00.0#E0: 9999.9", df.format(9999.9), "10.0E3");
- compare("00.0#E0: 0.1", df.format(0.1), "10.0E-2");
- compare("00.0#E0: 0.12", df.format(0.12), "12.0E-2");
- compare("00.0#E0: 0.123", df.format(0.123), "12.3E-2");
- compare("00.0#E0: 0.1234", df.format(0.1234), "12.34E-2");
- compare("00.0#E0: 0.12346", df.format(0.12346), "12.35E-2");
- compare("00.0#E0: 0.99999", df.format(0.99999), "10.0E-1");
- compare("00.0#E0: -0.0", df.format(-0.0), "-00.0E0");
- compare("00.0#E0: -1.0", df.format(-1.0), "-10.0E-1");
- compare("00.0#E0: -12.0", df.format(-12.0), "-12.0E0");
- compare("00.0#E0: -123.0", df.format(-123.0), "-12.3E1");
- compare("00.0#E0: -1234.0", df.format(-1234.0), "-12.34E2");
- compare("00.0#E0: -12346.0", df.format(-12346.0), "-12.35E3");
- compare("00.0#E0: -99999.0", df.format(-99999.0), "-10.0E4");
-
- df = new DecimalFormat("##0.0E0", dfs);
- compare("##0.0E0: -0.0", df.format(-0.0), "-0.0E0");
- compare("##0.0E0: 0.0", df.format(0.0), "0.0E0");
- compare("##0.0E0: 1.0", df.format(1.0), "1.0E0");
- compare("##0.0E0: 12.0", df.format(12.0), "12E0");
- compare("##0.0E0: 123.0", df.format(123.0), "123E0"); // Android fails, here!
- compare("##0.0E0: 1234.0", df.format(1234.0), "1.234E3");
- compare("##0.0E0: 12346.0", df.format(12346.0), "12.35E3");
- // Fails in JDK 1.2.2
- if (!compare(failCount, df.format(99999.0), "100E3"))
- failures.set(failCount);
- failCount++;
- compare("##0.0E0: 999999.0", df.format(999999.0), "1.0E6");
-
- df = new DecimalFormat("#00.0##E0", dfs);
- compare("#00.0##E0: 0.1", df.format(0.1), "100E-3");
- compare("#00.0##E0: 0.12", df.format(0.12), "120E-3");
- compare("#00.0##E0: 0.123", df.format(0.123), "123E-3");
- compare("#00.0##E0: 0.1234", df.format(0.1234), "123.4E-3");
- compare("#00.0##E0: 0.1234567", df.format(0.1234567), "123.457E-3");
- compare("#00.0##E0: 0.01", df.format(0.01), "10.0E-3");
- compare("#00.0##E0: 0.012", df.format(0.012), "12.0E-3");
- compare("#00.0##E0: 0.0123", df.format(0.0123), "12.3E-3");
- compare("#00.0##E0: 0.01234", df.format(0.01234), "12.34E-3");
- compare("#00.0##E0: 0.01234567", df.format(0.01234567), "12.3457E-3");
- compare("#00.0##E0: 0.001", df.format(0.001), "1.00E-3");
- compare("#00.0##E0: 0.0012", df.format(0.0012), "1.20E-3");
- compare("#00.0##E0: 0.00123", df.format(0.00123), "1.23E-3");
- compare("#00.0##E0: 0.001234", df.format(0.001234), "1.234E-3");
- compare("#00.0##E0: 0.001234567", df.format(0.001234567), "1.23457E-3");
- compare("#00.0##E0: 0.0001", df.format(0.0001), "100E-6");
- compare("#00.0##E0: 0.00012", df.format(0.00012), "120E-6");
- compare("#00.0##E0: 0.000123", df.format(0.000123), "123E-6");
- compare("#00.0##E0: 0.0001234", df.format(0.0001234), "123.4E-6");
- compare("#00.0##E0: 0.0001234567", df.format(0.0001234567),
- "123.457E-6");
-
- // Fails in JDK 1.2.2
- if (!compare(failCount, df.format(0.0), "0.00E0"))
- failures.set(failCount);
- failCount++;
- compare("#00.0##E0: 1.0", df.format(1.0), "1.00E0");
- compare("#00.0##E0: 12.0", df.format(12.0), "12.0E0");
- compare("#00.0##E0: 123.0", df.format(123.0), "123E0");
- compare("#00.0##E0: 1234.0", df.format(1234.0), "1.234E3");
- compare("#00.0##E0: 12345.0", df.format(12345.0), "12.345E3");
- compare("#00.0##E0: 123456.0", df.format(123456.0), "123.456E3");
- compare("#00.0##E0: 1234567.0", df.format(1234567.0), "1.23457E6");
- compare("#00.0##E0: 12345678.0", df.format(12345678.0), "12.3457E6");
- compare("#00.0##E0: 99999999.0", df.format(99999999.0), "100E6");
-
- df = new DecimalFormat("#.0E0", dfs);
- compare("#.0E0: -0.0", df.format(-0.0), "-.0E0");
- compare("#.0E0: 0.0", df.format(0.0), ".0E0");
- compare("#.0E0: 1.0", df.format(1.0), ".1E1");
- compare("#.0E0: 12.0", df.format(12.0), ".12E2");
- compare("#.0E0: 123.0", df.format(123.0), ".12E3");
- compare("#.0E0: 1234.0", df.format(1234.0), ".12E4");
- compare("#.0E0: 9999.0", df.format(9999.0), ".1E5");
-
- df = new DecimalFormat("0.#E0", dfs);
- compare("0.#E0: -0.0", df.format(-0.0), "-0E0");
- compare("0.#E0: 0.0", df.format(0.0), "0E0");
- compare("0.#E0: 1.0", df.format(1.0), "1E0");
- compare("0.#E0: 12.0", df.format(12.0), "1.2E1");
- compare("0.#E0: 123.0", df.format(123.0), "1.2E2");
- compare("0.#E0: 1234.0", df.format(1234.0), "1.2E3");
- compare("0.#E0: 9999.0", df.format(9999.0), "1E4");
-
- df = new DecimalFormat(".0E0", dfs);
- compare(".0E0: -0.0", df.format(-0.0), "-.0E0");
- compare(".0E0: 0.0", df.format(0.0), ".0E0");
- compare(".0E0: 1.0", df.format(1.0), ".1E1");
- compare(".0E0: 12.0", df.format(12.0), ".1E2");
- compare(".0E0: 123.0", df.format(123.0), ".1E3");
- compare(".0E0: 1234.0", df.format(1234.0), ".1E4");
- compare(".0E0: 9999.0", df.format(9999.0), ".1E5");
-
- df = new DecimalFormat("0.E0", dfs);
- // Fails in JDK 1.2.2
- if (!compare(failCount, df.format(0.0), "0.E0"))
- failures.set(failCount);
- failCount++;
- if (!compare(failCount, df.format(1.0), "1.E0"))
- failures.set(failCount);
- failCount++;
- if (!compare(failCount, df.format(12.0), "1.E1"))
- failures.set(failCount);
- failCount++;
- if (!compare(failCount, df.format(123.0), "1.E2"))
- failures.set(failCount);
- failCount++;
- if (!compare(failCount, df.format(1234.0), "1.E3"))
- failures.set(failCount);
- failCount++;
- if (!compare(failCount, df.format(9999.0), "1.E4"))
- failures.set(failCount);
- failCount++;
-
- df = new DecimalFormat("##0.00#E0", dfs);
- compare("##0.00#E0: 0.1", df.format(0.1), "100E-3");
- compare("##0.00#E0: 0.1234567", df.format(0.1234567), "123.457E-3");
- compare("##0.00#E0: 0.9999999", df.format(0.9999999), "1.00E0");
- compare("##0.00#E0: 0.01", df.format(0.01), "10.0E-3");
- compare("##0.00#E0: 0.01234567", df.format(0.01234567), "12.3457E-3");
- compare("##0.00#E0: 0.09999999", df.format(0.09999999), "100E-3");
- compare("##0.00#E0: 0.001", df.format(0.001), "1.00E-3");
- compare("##0.00#E0: 0.001234567", df.format(0.001234567), "1.23457E-3");
- compare("##0.00#E0: 0.009999999", df.format(0.009999999), "10.0E-3");
- compare("##0.00#E0: 0.0001", df.format(0.0001), "100E-6");
- compare("##0.00#E0: 0.0001234567", df.format(0.0001234567),
- "123.457E-6");
- compare("##0.00#E0: 0.0009999999", df.format(0.0009999999), "1.00E-3");
-
- df = new DecimalFormat("###0.00#E0", dfs);
- compare("###0.00#E0: 0.1", df.format(0.1), "1000E-4");
- compare("###0.00#E0: 0.12345678", df.format(0.12345678), "1234.568E-4");
- compare("###0.00#E0: 0.99999999", df.format(0.99999999), "1.00E0");
- compare("###0.00#E0: 0.01", df.format(0.01), "100E-4");
- compare("###0.00#E0: 0.012345678", df.format(0.012345678),
- "123.4568E-4");
- compare("###0.00#E0: 0.099999999", df.format(0.099999999), "1000E-4");
- compare("###0.00#E0: 0.001", df.format(0.001), "10.0E-4");
- compare("###0.00#E0: 0.0012345678", df.format(0.0012345678),
- "12.34568E-4");
- compare("###0.00#E0: 0.0099999999", df.format(0.0099999999), "100E-4");
- compare("###0.00#E0: 0.0001", df.format(0.0001), "1.00E-4");
- compare("###0.00#E0: 0.00012345678", df.format(0.00012345678),
- "1.234568E-4");
- compare("###0.00#E0: 0.00099999999", df.format(0.00099999999),
- "10.0E-4");
- // Fails in JDK 1.2.2
- if (!compare(failCount, df.format(0.00001), "1000E-8"))
- failures.set(failCount);
- failCount++;
- compare("###0.00#E0: 0.000012345678", df.format(0.000012345678),
- "1234.568E-8");
- compare("###0.00#E0: 0.000099999999", df.format(0.000099999999),
- "1.00E-4");
-
- df = new DecimalFormat("###0.0#E0", dfs);
- compare("###0.0#E0: 0.1", df.format(0.1), "1000E-4");
- compare("###0.0#E0: 0.1234567", df.format(0.1234567), "1234.57E-4");
- compare("###0.0#E0: 0.9999999", df.format(0.9999999), "1.0E0");
- // Fails in JDK 1.2.2
- if (!compare(failCount, df.format(0.01), "100E-4"))
- failures.set(failCount);
- failCount++;
- compare("###0.0#E0: 0.01234567", df.format(0.01234567), "123.457E-4");
- compare("###0.0#E0: 0.09999999", df.format(0.09999999), "1000E-4");
- compare("###0.0#E0: 0.001", df.format(0.001), "10E-4");
- compare("###0.0#E0: 0.001234567", df.format(0.001234567), "12.3457E-4");
- // Fails in JDK 1.2.2
- if (!compare(failCount, df.format(0.009999999), "100E-4"))
- failures.set(failCount);
- failCount++;
- compare("###0.0#E0: 0.0001", df.format(0.0001), "1.0E-4");
- compare("###0.0#E0: 0.0001234567", df.format(0.0001234567),
- "1.23457E-4");
- compare("###0.0#E0: 0.0009999999", df.format(0.0009999999), "10E-4");
- // Fails in JDK 1.2.2
- if (!compare(failCount, df.format(0.00001), "1000E-8"))
- failures.set(failCount);
- failCount++;
- compare("###0.0#E0: 0.00001234567", df.format(0.00001234567),
- "1234.57E-8");
- compare("###0.0#E0: 0.00009999999", df.format(0.00009999999), "1.0E-4");
-
- assertTrue("Failed " + failures + " of " + failCount,
- failures.length() == 0);
-
- String formatString = "##0.#";
- df = new DecimalFormat(formatString, dfs);
- df.setMinimumFractionDigits(30);
- compare(formatString + ": 0.000000000000000000000000000000", df
- .format(0.0), "0.000000000000000000000000000000");
- compare(formatString + ": -0.000000000000000000000000000000", df
- .format(-0.0), "-0.000000000000000000000000000000");
- compare(formatString + ": 1.000000000000000000000000000000", df
- .format(1.0), "1.000000000000000000000000000000");
- compare(formatString + ": -1.000000000000000000000000000000", df
- .format(-1.0), "-1.000000000000000000000000000000");
-
- df = new DecimalFormat(formatString);
- df.setMaximumFractionDigits(30);
- compare(formatString + ": 0", df.format(0.0), "0");
- compare(formatString + ": -0", df.format(-0.0), "-0");
- compare(formatString + ": 1", df.format(1.0), "1");
- compare(formatString + ": -1", df.format(-1.0), "-1");
- }
-
- public void test_formatD() {
- DecimalFormat format = (DecimalFormat) NumberFormat
- .getInstance(Locale.ENGLISH);
- format.setGroupingUsed(false);
- format.setMaximumFractionDigits(400);
- assertEquals("123456789012345", format.format(123456789012345.));
- assertEquals("1", "12345678901234.5", format.format(12345678901234.5));
- assertEquals("2", "1234567890123.25", format.format(1234567890123.25));
- assertEquals("3", "999999999999.375", format.format(999999999999.375));
- assertEquals("4", "99999999999.0625", format.format(99999999999.0625));
- assertEquals("5", "9999999999.03125", format.format(9999999999.03125));
- assertEquals("6", "999999999.015625", format.format(999999999.015625));
- assertEquals("7", "99999999.0078125", format.format(99999999.0078125));
- assertEquals("8", "9999999.00390625", format.format(9999999.00390625));
- assertEquals("9", "999999.001953125", format.format(999999.001953125));
- assertEquals("10", "9999.00048828125", format.format(9999.00048828125));
- assertEquals("11", "999.000244140625", format.format(999.000244140625));
- assertEquals("12", "99.0001220703125", format.format(99.0001220703125));
- assertEquals("13", "9.00006103515625", format.format(9.00006103515625));
- assertEquals("14", "0.000030517578125", format.format(0.000030517578125));
- }
-
-
- public void test_getNegativePrefix() {
- DecimalFormat df = new DecimalFormat();
- try {
- df.setNegativePrefix("--");
- assertTrue("Incorrect negative prefix", df.getNegativePrefix()
- .equals("--"));
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_getNegativeSuffix() {
- DecimalFormat df = new DecimalFormat();
- try {
- df.setNegativeSuffix("&");
- assertTrue("Incorrect negative suffix", df.getNegativeSuffix()
- .equals("&"));
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_getPositivePrefix() {
- DecimalFormat df = new DecimalFormat();
- try {
- df.setPositivePrefix("++");
- assertTrue("Incorrect positive prefix", df.getPositivePrefix()
- .equals("++"));
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_getPositiveSuffix() {
- DecimalFormat df = new DecimalFormat();
- try {
- df.setPositiveSuffix("%");
- assertTrue("Incorrect positive prefix", df.getPositiveSuffix()
- .equals("%"));
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_hashCode() {
- try {
- DecimalFormat df1 = new DecimalFormat();
- DecimalFormat df2 = (DecimalFormat) df1.clone();
- assertTrue("Hash codes of equals object are not equal", df2
- .hashCode() == df1.hashCode());
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_parseLjava_lang_StringLjava_text_ParsePosition() {
- DecimalFormat format = (DecimalFormat) NumberFormat
- .getNumberInstance(Locale.ENGLISH);
- ParsePosition pos = new ParsePosition(0);
- Number result = format.parse("9223372036854775807", pos);
- assertTrue("Wrong result type for Long.MAX_VALUE",
- result.getClass() == Long.class);
- assertEquals("Wrong result Long.MAX_VALUE",
- Long.MAX_VALUE, result.longValue());
- pos = new ParsePosition(0);
- result = format.parse("-9223372036854775808", pos);
- assertTrue("Wrong result type for Long.MIN_VALUE",
- result.getClass() == Long.class);
- assertTrue("Wrong result Long.MIN_VALUE: " + result.longValue(), result
- .longValue() == Long.MIN_VALUE);
- pos = new ParsePosition(0);
- result = format.parse("9223372036854775808", pos);
- assertTrue("Wrong result type for Long.MAX_VALUE+1",
- result.getClass() == Double.class);
- assertEquals("Wrong result Long.MAX_VALUE + 1",
- (double) Long.MAX_VALUE + 1, result.doubleValue());
- pos = new ParsePosition(0);
- result = format.parse("-9223372036854775809", pos);
- assertTrue("Wrong result type for Long.MIN_VALUE - 1",
- result.getClass() == Double.class);
- assertEquals("Wrong result Long.MIN_VALUE - 1",
- (double) Long.MIN_VALUE - 1, result.doubleValue());
-
- pos = new ParsePosition(0);
- result = format.parse("18446744073709551629", pos);
- assertTrue("Wrong result type for overflow",
- result.getClass() == Double.class);
- assertEquals("Wrong result for overflow",
- 18446744073709551629d, result.doubleValue());
-
- pos = new ParsePosition(0);
- result = format.parse("42325917317067571199", pos);
- assertTrue("Wrong result type for overflow a: " + result, result
- .getClass() == Double.class);
- assertTrue("Wrong result for overflow a: " + result, result
- .doubleValue() == 42325917317067571199d);
- pos = new ParsePosition(0);
- result = format.parse("4232591731706757119E1", pos);
- assertTrue("Wrong result type for overflow b: " + result, result
- .getClass() == Double.class);
- assertEquals("Wrong result for overflow b: " + result,
- 42325917317067571190d, result.doubleValue());
- pos = new ParsePosition(0);
- result = format.parse(".42325917317067571199E20", pos);
- assertTrue("Wrong result type for overflow c: " + result, result
- .getClass() == Double.class);
- assertTrue("Wrong result for overflow c: " + result, result
- .doubleValue() == 42325917317067571199d);
- pos = new ParsePosition(0);
- result = format.parse("922337203685477580.9E1", pos);
- assertTrue("Wrong result type for overflow d: " + result, result
- .getClass() == Double.class);
- assertTrue("Wrong result for overflow d: " + result, result
- .doubleValue() == 9223372036854775809d);
- pos = new ParsePosition(0);
- result = format.parse("9.223372036854775809E18", pos);
- assertTrue("Wrong result type for overflow e: " + result, result
- .getClass() == Double.class);
- assertTrue("Wrong result for overflow e: " + result, result
- .doubleValue() == 9223372036854775809d);
-
- // test parse with multipliers
- format.setMultiplier(100);
- result = format.parse("9223372036854775807", new ParsePosition(0));
- assertEquals("Wrong result type multiplier 100: " + result, Long.class, result.getClass());
- // RI on windows and linux both answer with a slightly rounded result
- assertTrue("Wrong result for multiplier 100: " + result, result
- .longValue() == 92233720368547760L);
- format.setMultiplier(1000);
- result = format.parse("9223372036854775807", new ParsePosition(0));
- assertTrue("Wrong result type multiplier 1000: " + result, result
- .getClass() == Long.class);
- assertTrue("Wrong result for multiplier 1000: " + result, result
- .longValue() == 9223372036854776L);
-
- format.setMultiplier(10000);
- result = format.parse("9223372036854775807", new ParsePosition(0));
- assertTrue("Wrong result type multiplier 10000: " + result, result
- .getClass() == Double.class);
- assertTrue("Wrong result for multiplier 10000: " + result, result
- .doubleValue() == 922337203685477.5807d);
-
- }
-}
diff --git a/luni/src/test/java/libcore/java/text/OldFieldPositionTest.java b/luni/src/test/java/libcore/java/text/OldFieldPositionTest.java
deleted file mode 100644
index b6fbd98..0000000
--- a/luni/src/test/java/libcore/java/text/OldFieldPositionTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.java.text;
-
-import java.text.DateFormat;
-import java.text.FieldPosition;
-
-public class OldFieldPositionTest extends junit.framework.TestCase {
-
- public void test_hashCode() {
- // Test for method int java.text.FieldPosition.hashCode()
- FieldPosition fpos1 = new FieldPosition(1);
- FieldPosition fpos2 = new FieldPosition(1);
- assertTrue("test 1: hash codes are not equal for equal objects.",
- fpos1.hashCode() == fpos2.hashCode());
- fpos1.setBeginIndex(5);
- fpos1.setEndIndex(110);
- assertTrue("test 2: hash codes are equal for non equal objects.",
- fpos1.hashCode() != fpos2.hashCode());
- fpos2.setBeginIndex(5);
- fpos2.setEndIndex(110);
- assertTrue("test 3: hash codes are not equal for equal objects.",
- fpos1.hashCode() == fpos2.hashCode());
-
- FieldPosition fpos3 = new FieldPosition(
- DateFormat.Field.DAY_OF_WEEK_IN_MONTH);
-
- assertTrue("test 4: hash codes are equal for non equal objects.",
- fpos2.hashCode() != fpos3.hashCode());
- }
-
- public void test_setBeginIndexI() {
- // Test for method void java.text.FieldPosition.setBeginIndex(int)
- FieldPosition fpos = new FieldPosition(1);
- fpos.setBeginIndex(2);
- fpos.setEndIndex(3);
- assertEquals("beginIndex should have been set to 2", 2, fpos
- .getBeginIndex());
-
- fpos.setBeginIndex(Integer.MAX_VALUE);
- assertEquals("beginIndex should have been set to Integer.MAX_VALUE",
- Integer.MAX_VALUE, fpos.getBeginIndex());
-
- fpos.setBeginIndex(-1);
- assertEquals("beginIndex should have been set to -1",
- -1, fpos.getBeginIndex());
- }
-
- public void test_setEndIndexI() {
- // Test for method void java.text.FieldPosition.setEndIndex(int)
- FieldPosition fpos = new FieldPosition(1);
- fpos.setEndIndex(3);
- fpos.setBeginIndex(2);
- assertEquals("EndIndex should have been set to 3", 3, fpos
- .getEndIndex());
-
- fpos.setEndIndex(Integer.MAX_VALUE);
- assertEquals("endIndex should have been set to Integer.MAX_VALUE",
- Integer.MAX_VALUE, fpos.getEndIndex());
-
- fpos.setEndIndex(-1);
- assertEquals("endIndex should have been set to -1",
- -1, fpos.getEndIndex());
- }
-}
diff --git a/luni/src/test/java/libcore/java/text/OldMessageFormatTest.java b/luni/src/test/java/libcore/java/text/OldMessageFormatTest.java
deleted file mode 100644
index 2701d0e..0000000
--- a/luni/src/test/java/libcore/java/text/OldMessageFormatTest.java
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.text;
-
-import java.text.ChoiceFormat;
-import java.text.DateFormat;
-import java.text.FieldPosition;
-import java.text.Format;
-import java.text.MessageFormat;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-import junit.framework.TestCase;
-import tests.support.Support_MessageFormat;
-
-public class OldMessageFormatTest extends TestCase {
-
- private MessageFormat format1;
-
- protected void setUp() {
- Locale.setDefault(Locale.US);
-
- // test with repeating formats and max argument index < max offset
- String pattern = "A {3, number, currency} B {2, time} C {0, number, percent} D {4} E {1,choice,0#off|1#on} F {0, date}";
- format1 = new MessageFormat(pattern);
- }
-
- public void test_applyPatternLjava_lang_String_AndroidFailure() {
- MessageFormat format = new MessageFormat("test");
- format.setLocale(Locale.FRENCH); // use French since English has the
- // same LONG and FULL time patterns
- format.applyPattern("{0,time, Full}");
- assertEquals("Wrong full time pattern", "{0,time,full}", format
- .toPattern());
- }
-
- public void test_formatToCharacterIteratorLjava_lang_Object() {
- // Test for method formatToCharacterIterator(java.lang.Object)
- new Support_MessageFormat(
- "test_formatToCharacterIteratorLjava_lang_Object")
- .t_formatToCharacterIterator();
-
- try {
- new MessageFormat("{1, number}").formatToCharacterIterator(null);
- fail("NullPointerException was not thrown.");
- } catch(NullPointerException npe) {
- //expected
- }
-
- try {
- new MessageFormat("{0, time}").formatToCharacterIterator(new Object[]{""});
- fail("IllegalArgumentException was not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- public void test_getLocale() {
- try {
- Locale[] l = {
- Locale.FRANCE,
- Locale.KOREA,
- new Locale(Locale.FRANCE.getCountry(), Locale.FRANCE
- .getLanguage()), new Locale("mk"),
- new Locale("mk", "MK"), Locale.US,
- new Locale("#ru", "@31230") };
-
- String pattern = "getLocale test {0,number,#,####}";
- MessageFormat mf;
-
- for (int i = 0; i < 0; i++) {
- mf = new MessageFormat(pattern, l[i]);
- Locale result = mf.getLocale();
- assertEquals("Returned local: " + result + " instead of "
- + l[i], l[i], result);
- assertEquals("Returned language: " + result.getLanguage()
- + " instead of " + l[i].getLanguage(), l[i]
- .getLanguage(), result.getLanguage());
- assertEquals("Returned country: " + result.getCountry()
- + " instead of " + l[i].getCountry(),
- l[i].getCountry(), result.getCountry());
- }
-
- mf = new MessageFormat(pattern);
- mf.setLocale(null);
- Locale result = mf.getLocale();
- assertEquals("Returned local: " + result + " instead of null",
- null, result);
- } catch (Exception e) {
- fail("unexpected exception " + e.toString());
- }
- }
-
- /**
- * java.text.MessageFormat#setFormat(int, Format) Test of method
- * java.text.MessageFormat#setFormat(int, Format). Case 1: Compare
- * getFormats() results after calls to setFormat(). Case 2: Try to
- * call setFormat() using incorrect index.
- */
- public void test_setFormatILjava_text_Format() {
- try {
- // case 1: Compare getFormats() results after calls to setFormat()
- MessageFormat f1 = (MessageFormat) format1.clone();
- f1.setFormat(0, DateFormat.getTimeInstance());
- f1.setFormat(1, DateFormat.getTimeInstance());
- f1.setFormat(2, NumberFormat.getInstance());
- f1.setFormat(3, new ChoiceFormat("0#off|1#on"));
- f1.setFormat(4, new ChoiceFormat("1#few|2#ok|3#a lot"));
- f1.setFormat(5, DateFormat.getTimeInstance());
-
- Format[] formats = f1.getFormats();
- formats = f1.getFormats();
-
- Format[] correctFormats = new Format[] {
- DateFormat.getTimeInstance(), DateFormat.getTimeInstance(),
- NumberFormat.getInstance(), new ChoiceFormat("0#off|1#on"),
- new ChoiceFormat("1#few|2#ok|3#a lot"),
- DateFormat.getTimeInstance() };
-
- assertEquals("Test1A:Returned wrong number of formats:",
- correctFormats.length, formats.length);
- for (int i = 0; i < correctFormats.length; i++) {
- assertEquals(
- "Test1B:wrong format for pattern index " + i + ":",
- correctFormats[i], formats[i]);
- }
-
- // case 2: Try to setFormat using incorrect index
- try {
- f1.setFormat(-1, DateFormat.getDateInstance());
- fail("Expected ArrayIndexOutOfBoundsException was not thrown");
- f1.setFormat(f1.getFormats().length, DateFormat
- .getDateInstance());
- fail("Expected ArrayIndexOutOfBoundsException was not thrown");
- } catch (ArrayIndexOutOfBoundsException e) {
- // expected
- }
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_format$Ljava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
- // Test for method java.lang.StringBuffer
- // java.text.MessageFormat.format(java.lang.Object [],
- // java.lang.StringBuffer, java.text.FieldPosition)
- MessageFormat format = new MessageFormat("{1,number,integer}");
- StringBuffer buffer = new StringBuffer();
- format.format(new Object[] { "0", new Double(53.863) }, buffer,
- new FieldPosition(MessageFormat.Field.ARGUMENT));
- assertEquals("Wrong result", "54", buffer.toString());
-
- format.format(new Object[] { "0", new Double(53.863) }, buffer,
- new FieldPosition(MessageFormat.Field.ARGUMENT));
-
- assertEquals("Wrong result", "5454", buffer.toString());
-
- buffer = new StringBuffer();
- format
- .applyPattern("{0,choice,0#zero|1#one '{1,choice,2#two {2,time}}'}");
- Date date = new Date();
- String expected = "one two "
- + DateFormat.getTimeInstance().format(date);
- format.format(new Object[] { new Double(1.6),
- new Integer(3), date }, buffer, new FieldPosition(MessageFormat
- .Field.ARGUMENT));
- assertEquals("Choice not recursive:\n" + expected + "\n" + buffer,
- expected, buffer.toString());
-
- StringBuffer str = format.format(new Object[] { new Double(0.6),
- new Integer(3)}, buffer, null);
-
- assertEquals(expected + "zero", str.toString());
- assertEquals(expected + "zero", buffer.toString());
-
- try {
- format.format(new Object[] { "0", new Double(1), "" }, buffer,
- new FieldPosition(MessageFormat.Field.ARGUMENT));
- fail("IllegalArgumentException was not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- format.format(new Object[] { "", new Integer(3)}, buffer,
- new FieldPosition(MessageFormat.Field.ARGUMENT));
- fail("IllegalArgumentException was not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- public void test_formatLjava_lang_StringLjava_lang_Object() {
- TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
- int iCurrency = 123;
- int iInteger = Integer.MIN_VALUE;
-
- Date date = new Date(12345678);
- Object[] args = { date, iCurrency, iInteger };
- String resStr = "Date: Jan 1, 1970 Currency: $" + iCurrency
- + ".00 Integer: -2,147,483,648";
- String pattern = "Date: {0,date} Currency: {1, number, currency} Integer: {2, number, integer}";
- String sFormat = MessageFormat.format(pattern, (Object[]) args);
- assertEquals(
- "format(String, Object[]) with valid parameters returns incorrect string: case 1",
- sFormat, resStr);
-
- pattern = "abc {4, number, integer} def {3,date} ghi {2,number} jkl {1,choice,0#low|1#high} mnop {0}";
- resStr = "abc -2,147,483,648 def Jan 1, 1970 ghi -2,147,483,648 jkl high mnop -2,147,483,648";
- Object[] args_ = { iInteger, 1, iInteger, date, iInteger };
- sFormat = MessageFormat.format(pattern, args_);
- assertEquals(
- "format(String, Object[]) with valid parameters returns incorrect string: case 1",
- sFormat, resStr);
-
- try {
- args = null;
- MessageFormat.format(null, args);
- fail("Doesn't throw IllegalArgumentException: null, null");
- } catch (Exception e) {
- // expected
- }
-
- try {
- MessageFormat.format("Invalid {1,foobar} format descriptor!",
- new Object[] {iInteger} );
- fail("Doesn't throw IllegalArgumentException with invalid pattern as a parameter: case 1");
- } catch (IllegalArgumentException ex) {
- // expected
- }
-
- try {
- MessageFormat.format(
- "Invalid {1,date,invalid-spec} format descriptor!", new Object[]{""});
- fail("Doesn't throw IllegalArgumentException with invalid pattern as a parameter: case 2");
- } catch (IllegalArgumentException ex) {
- // expected
- }
-
- try {
- MessageFormat.format("{0,number,integer", new Object[] {iInteger});
- fail("Doesn't throw IllegalArgumentException, doesn't detect unmatched brackets");
- } catch (IllegalArgumentException ex) {
- // expected
- }
-
- try {
- MessageFormat.format(
- "Valid {1, date} format {0, number} descriptor!", new Object[]{ "" } );
- fail("Doesn't throw IllegalArgumentException with invalid Object array");
- } catch (IllegalArgumentException ex) {
- // expected
- }
- }
-
- public void test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition() {
- // Test for method java.lang.StringBuffer
- // java.text.MessageFormat.format(java.lang.Object,
- // java.lang.StringBuffer, java.text.FieldPosition)
- new Support_MessageFormat(
- "test_formatLjava_lang_ObjectLjava_lang_StringBufferLjava_text_FieldPosition")
- .t_format_with_FieldPosition();
-
- String pattern = "On {4,date} at {3,time}, he ate {2,number, integer} " +
- "hamburger{2,choice,1#|1<s}.";
- MessageFormat format = new MessageFormat(pattern, Locale.US);
-
- Object[] objects = new Object[] { "", new Integer(3), 8, ""};
-
- try {
- format.format(objects, new StringBuffer(),
- new FieldPosition(DateFormat.Field.AM_PM));
- fail("IllegalArgumentException was not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- public void test_setFormats$Ljava_text_Format() {
- try {
- MessageFormat f1 = (MessageFormat) format1.clone();
-
- // case 1: Test with repeating formats and max argument index < max
- // offset
- // compare getFormats() results after calls to setFormats(Format[])
- Format[] correctFormats = new Format[] {
- DateFormat.getTimeInstance(),
- new ChoiceFormat("0#off|1#on"),
- DateFormat.getTimeInstance(),
- NumberFormat.getCurrencyInstance(),
- new ChoiceFormat("1#few|2#ok|3#a lot") };
-
- f1.setFormats(correctFormats);
- Format[] formats = f1.getFormats();
-
- assertTrue("Test1A:Returned wrong number of formats:",
- correctFormats.length <= formats.length);
- for (int i = 0; i < correctFormats.length; i++) {
- assertEquals("Test1B:wrong format for argument index " + i
- + ":", correctFormats[i], formats[i]);
- }
-
- // case 2: Try to pass null argument to setFormats().
- try {
- f1.setFormats(null);
- fail("Expected exception NullPointerException was not thrown");
- } catch (NullPointerException e) {
- // expected
- }
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_parseLjava_lang_String() throws ParseException {
- String pattern = "A {3, number, currency} B {2, time} C {0, number, percent} D {4} E {1,choice,0#off|1#on} F {0, date}";
- MessageFormat mf = new MessageFormat(pattern);
- String sToParse = "A $12,345.00 B 9:56:07 AM C 3,200% D 1/15/70 9:56 AM E on F Jan 1, 1970";
- Object[] result;
- try {
- result = mf.parse(sToParse);
-
- assertTrue("No result: " + result.length, result.length == 5);
- assertTrue("Object 0 is not date", result[0] instanceof Date);
- assertEquals("Object 1 is not stringr", result[1].toString(), "1.0");
- assertTrue("Object 2 is not date", result[2] instanceof Date);
- assertEquals("Object 3 is not number", result[3].toString(),
- "12345");
- assertEquals("Object 4 is not string", result[4].toString(),
- "1/15/70 9:56 AM");
-
- } catch (java.text.ParseException pe) {
- fail("ParseException is thrown for incorrect string " + sToParse);
- }
-
- sToParse = "xxdate is Feb 28, 1999";
- try {
- result = format1.parse(sToParse);
- fail("ParseException is thrown for incorrect string " + sToParse);
- } catch (java.text.ParseException pe) {
- // expected
- }
-
- sToParse = "vm=Test, @3 4 6, 3 ";
- mf = new MessageFormat("vm={0},{1},{2}");
- try {
- result = mf.parse(sToParse);
- assertTrue("No result: " + result.length, result.length == 3);
- assertEquals("Object 0 is not string", result[0].toString(), "Test");
- assertEquals("Object 1 is not string", result[1].toString(),
- " @3 4 6");
- assertEquals("Object 2 is not string", result[2].toString(),
- " 3 ");
- } catch (java.text.ParseException pe) {
- fail("ParseException is thrown for correct string " + sToParse);
- }
-
- try {
- result = mf.parse(null);
- fail("ParseException is not thrown for null " + sToParse);
- } catch (java.text.ParseException pe) {
- // expected
- }
- }
-
- /**
- * java.text.MessageFormat#parseObject(java.lang.String,
- * java.text.ParsePosition) Test of method
- * java.text.MessageFormat#parseObject(java.lang.String,
- * java.text.ParsePosition). Case 1: Parsing of correct data string.
- * Case 2: Parsing of partial correct data string. Case 3: Try to use
- * argument ParsePosition as null.
- */
- public void test_parseObjectLjava_lang_StringLjavajava_text_ParsePosition() {
- MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
- try {
- // case 1: Try to parse correct data string.
- Object[] objs = { new Double(3.1415) };
- String result = mf.format(objs);
- // result now equals "3.14, 3.1"
- Object[] res = null;
- ParsePosition pp = new ParsePosition(0);
- int parseIndex = pp.getIndex();
- res = (Object[]) mf.parseObject(result, pp);
- assertTrue("Parse operation return null", res != null);
- assertTrue("parse operation return array with incorrect length",
- 1 == res.length);
- assertTrue("ParseIndex is incorrect", pp.getIndex() != parseIndex);
- assertTrue("Result object is incorrect", new Double(3.1)
- .equals(res[0]));
-
- // case 2: Try to parse partially correct data string.
- pp.setIndex(0);
- char[] cur = result.toCharArray();
- cur[cur.length / 2] = 'Z';
- String partialCorrect = new String(cur);
- res = (Object[]) mf.parseObject(partialCorrect, pp);
- assertTrue("Parse operation return null", res == null);
- assertTrue("ParseIndex is incorrect", pp.getIndex() == 0);
- assertTrue("ParseErrorIndex is incorrect",
- pp.getErrorIndex() == cur.length / 2);
-
- // case 3: Try to use argument ParsePosition as null.
- try {
- mf.parseObject(result, null);
- fail("Expected NullPointerException was not thrown");
- } catch (NullPointerException e) {
- // expected
- }
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- public void test_format_Object() {
- // Regression for HARMONY-1875
- Locale.setDefault(Locale.CANADA);
- TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
- String pat = "text here {0,date,yyyyyyyyy} and here";
- Calendar c = Calendar.getInstance();
- String etalon = "text here 00000" + c.get(Calendar.YEAR) + " and here";
- MessageFormat obj = new MessageFormat(pat);
- assertEquals(etalon, obj.format(new Object[] { new Date() }));
- }
-
- public void test_parseLjava_lang_StringLjava_text_ParsePosition() {
- ParsePosition pos = new ParsePosition(2);
-
- MessageFormat mf = new MessageFormat("{0}; {0}; {0}");
- String parse = "a; b; c";
- try {
- mf.parse(parse, null);
- fail("NullPointerException was not thrown.");
- } catch(NullPointerException npe) {
- //expected
- }
-
- try {
- mf.parse(null, pos);
- } catch(NullPointerException npe) {
- fail("NullPointerException was thrown.");
- }
- }
-}
diff --git a/luni/src/test/java/libcore/java/text/OldNumberFormatTest.java b/luni/src/test/java/libcore/java/text/OldNumberFormatTest.java
index b7ae098..d281a91 100644
--- a/luni/src/test/java/libcore/java/text/OldNumberFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/OldNumberFormatTest.java
@@ -16,7 +16,6 @@
*/
package libcore.java.text;
-import dalvik.annotation.BrokenTest;
import java.text.ChoiceFormat;
import java.text.DecimalFormat;
import java.text.FieldPosition;
@@ -50,10 +49,14 @@ public class OldNumberFormatTest extends TestCase {
Locale arLocale = new Locale("ar", "AE");
format = (DecimalFormat) NumberFormat.getIntegerInstance(arLocale);
- assertEquals("#0;#0-", format.toPattern());
- assertEquals("\u0666-", format.format(-6));
- assertEquals(new Long(-36), format.parse("36-"));
- assertEquals(new Long(-36), format.parseObject("36-"));
+ assertEquals("#,##0", format.toPattern());
+ assertEquals("\u0666\u0667", format.format(67));
+
+ assertEquals("\u200f-\u0666", format.format(-6));
+ assertEquals(-36L, format.parse("-36"));
+
+ // New Arabic formats do not support '-' to right of digits.
+ assertEquals(36L, format.parseObject("36-"));
assertEquals(0, format.getMaximumFractionDigits());
assertTrue(format.isParseIntegerOnly());
}
@@ -729,7 +732,7 @@ public class OldNumberFormatTest extends TestCase {
+ " instead of Integer.MIN_VALUE", result == 0);
}
- @BrokenTest("Fails in CTS, passes in CoreTestRunner")
+ // Broken Test: Fails in CTS, passes in CoreTestRunner
public void test_parseLjava_lang_String() {
NumberFormat nf1 = NumberFormat.getInstance();
try {
diff --git a/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java
deleted file mode 100644
index 1cc7554..0000000
--- a/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.java.text;
-
-import java.text.DateFormat;
-import java.text.DateFormatSymbols;
-import java.text.FieldPosition;
-import java.text.ParsePosition;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.SimpleTimeZone;
-import java.util.TimeZone;
-
-public class OldSimpleDateFormatTest extends junit.framework.TestCase {
-
- SimpleDateFormat format = null;
- SimpleDateFormat pFormat = null;
-
- @Override
- protected void setUp() throws Exception {
- TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
- format = new SimpleDateFormat("", Locale.ENGLISH);
- pFormat = new SimpleDateFormat("", Locale.ENGLISH);
- }
-
- @Override
- protected void tearDown() throws Exception {
- format = null;
- pFormat = null;
- }
-
- class FormatTester {
- boolean testsFailed = false;
-
- public void test(String pattern, Calendar cal, String expected, int field) {
- StringBuffer buffer = new StringBuffer();
- FieldPosition position = new FieldPosition(field);
- format.applyPattern(pattern);
- format.format(cal.getTime(), buffer, position);
- String result = buffer.toString();
- if (!result.equals(expected)) {
- System.out.println("Wrong format: \"" + pattern
- + "\" expected: " + expected + " result: "
- + result);
- testsFailed = true;
- }
- }
-
- public void parse(String pattern, String input, Date expected, int start, int end) {
- pFormat.applyPattern(pattern);
- ParsePosition position = new ParsePosition(start);
- Date result = pFormat.parse(input, position);
- assertTrue("Wrong result: " + pattern + " input: " + input
- + " expected: " + expected + " result: " + result, expected
- .equals(result));
- assertTrue("Wrong end position: " + pattern + " input: " + input,
- position.getIndex() == end);
- }
-
- public void verifyFormatTimezone(String timeZoneId, String expected1,
- String expected2, Date date) {
- format.setTimeZone(SimpleTimeZone.getTimeZone(timeZoneId));
- format.applyPattern("z, zzzz");
- assertEquals("Test z for TimeZone : " + timeZoneId, expected1,
- format.format(date));
-
- format.applyPattern("Z, ZZZZ");
- assertEquals("Test Z for TimeZone : " + timeZoneId, expected2,
- format.format(date));
- }
- }
-
- /**
- * java.text.SimpleDateFormat#SimpleDateFormat(java.lang.String,
- * java.text.DateFormatSymbols)
- */
- public void test_ConstructorLjava_lang_StringLjava_text_DateFormatSymbols() {
- // Test for method java.text.SimpleDateFormat(java.lang.String,
- // java.text.DateFormatSymbols)
- DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH);
- symbols.setEras(new String[] { "Before", "After" });
- SimpleDateFormat f2 = new SimpleDateFormat("y'y'yy", symbols);
- assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
- assertEquals("Wrong pattern", "y'y'yy", f2.toPattern());
- assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(symbols));
- assertTrue("Doesn't work",
- f2.format(new Date()).getClass() == String.class);
-
- try {
- new SimpleDateFormat(null, symbols);
- fail("NullPointerException was not thrown.");
- } catch(NullPointerException npe) {
- //expected
- }
-
- try {
- new SimpleDateFormat("eee", symbols);
- fail("IllegalArgumentException was not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- public void test_ConstructorLjava_lang_StringLjava_util_Locale() {
- // Test for method java.text.SimpleDateFormat(java.lang.String,
- // java.util.Locale)
- SimpleDateFormat f2 = new SimpleDateFormat("'yyyy' MM yy",
- Locale.GERMAN);
- assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
- assertEquals("Wrong pattern", "'yyyy' MM yy", f2.toPattern());
- assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
- new DateFormatSymbols(Locale.GERMAN)));
- assertTrue("Doesn't work",
- f2.format(new Date()).getClass() == String.class);
-
- try {
- new SimpleDateFormat(null, Locale.GERMAN);
- fail("NullPointerException was not thrown.");
- } catch(NullPointerException npe) {
- //expected
- }
- try {
- new SimpleDateFormat("eee", Locale.GERMAN);
- fail("IllegalArgumentException was not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- public void test_applyLocalizedPatternLjava_lang_String() {
- // Test for method void
- // java.text.SimpleDateFormat.applyLocalizedPattern(java.lang.String)
- SimpleDateFormat f2 = new SimpleDateFormat("y", new Locale("de", "CH"));
- // BEGIN android-removed
- // This test doesn't work like this. The cause lies inside of icu
- // that doesn't support localized pattern characters anymore. So this
- // test fails because the pattern template contains characters that are
- // not part of the standard pattern returned for every locale.
- // The default pattern characters are: GyMdkHmsSEDFwWahKzZ
- //
- // f2.applyLocalizedPattern("GuMtkHmsSEDFwWahKz");
- // String pattern = f2.toPattern();
- // assertTrue("Wrong pattern: " + pattern, pattern
- // .equals("GyMdkHmsSEDFwWahKz"));
- //
- // test the new "Z" pattern char
- // f2 = new SimpleDateFormat("y", new Locale("de", "CH"));
- // f2.applyLocalizedPattern("G u M t Z");
- // pattern = f2.toPattern();
- // assertTrue("Wrong pattern: " + pattern, pattern.equals("G y M d Z"));
- // END android-removed
-
- // test invalid patterns
- try {
- f2.applyLocalizedPattern("b");
- fail("Expected IllegalArgumentException for pattern with invalid pattern letter: b");
- } catch (IllegalArgumentException e) {
- }
-
- try {
- // ICU only! this fails on the RI
- f2.applyLocalizedPattern("u");
- fail("Expected IllegalArgumentException for pattern with invalid pattern letter: u");
- } catch (IllegalArgumentException e) {
- }
-
- try {
- f2.applyLocalizedPattern("a '");
- fail("Expected IllegalArgumentException for pattern with unterminated quote: a '");
- } catch (IllegalArgumentException e) {
- }
-
- try {
- f2.applyLocalizedPattern(null);
- fail("Expected NullPointerException for null pattern");
- } catch (NullPointerException e) {
- }
- }
-
- /**
- * java.text.SimpleDateFormat#applyPattern(java.lang.String)
- */
- public void test_applyPatternLjava_lang_String() {
- // Test for method void
- // java.text.SimpleDateFormat.applyPattern(java.lang.String)
- SimpleDateFormat f2 = new SimpleDateFormat("y", new Locale("de", "CH"));
- // BEGIN android-changed
- f2.applyPattern("GyMdkHmsSEDFwWahKzZ");
- assertEquals("Wrong pattern", "GyMdkHmsSEDFwWahKzZ", f2.toPattern());
- // END android-changed
-
- // test invalid patterns
- try {
- f2.applyPattern("u");
- fail("Expected IllegalArgumentException for pattern with invalid patter letter: u");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void test_hashCode() {
- SimpleDateFormat format = (SimpleDateFormat) DateFormat.getInstance();
- SimpleDateFormat clone = (SimpleDateFormat) format.clone();
- assertTrue("clone has not equal hash code", clone.hashCode() == format
- .hashCode());
- format.format(new Date());
- assertTrue("clone has not equal hash code after format", clone
- .hashCode() == format.hashCode());
- DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH);
- symbols.setEras(new String[] { "Before", "After" });
- SimpleDateFormat format2 = new SimpleDateFormat("y'y'yy", symbols);
- assertFalse("objects has equal hash code", format2.hashCode() == format
- .hashCode());
- }
-
- public void test_formatLjava_util_DateLjava_lang_StringBufferLjava_text_FieldPosition() {
- FormatTester test = new FormatTester();
-
- Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6);
- test.test(" G", cal, " AD", DateFormat.ERA_FIELD);
- test.test(" GG", cal, " AD", DateFormat.ERA_FIELD);
- test.test(" GGG", cal, " AD", DateFormat.ERA_FIELD);
- test.test(" G", new GregorianCalendar(-1999, Calendar.JUNE, 2), " BC",
- DateFormat.ERA_FIELD);
-
- test.test(" M", cal, " 6", DateFormat.MONTH_FIELD);
- test.test(" M", new GregorianCalendar(1999, Calendar.NOVEMBER, 2),
- " 11", DateFormat.MONTH_FIELD);
- test.test(" MM", cal, " 06", DateFormat.MONTH_FIELD);
- test.test(" MMM", cal, " Jun", DateFormat.MONTH_FIELD);
- test.test(" MMMM", cal, " June", DateFormat.MONTH_FIELD);
- test.test(" MMMMM", cal, " J", DateFormat.MONTH_FIELD);
-
- test.test(" d", cal, " 2", DateFormat.DATE_FIELD);
- test.test(" d", new GregorianCalendar(1999, Calendar.NOVEMBER, 12),
- " 12", DateFormat.DATE_FIELD);
- test.test(" dd", cal, " 02", DateFormat.DATE_FIELD);
- test.test(" dddd", cal, " 0002", DateFormat.DATE_FIELD);
-
- test.test(" h", cal, " 3", DateFormat.HOUR1_FIELD);
- test.test(" h", new GregorianCalendar(1999, Calendar.NOVEMBER, 12),
- " 12", DateFormat.HOUR1_FIELD);
- test.test(" hh", cal, " 03", DateFormat.HOUR1_FIELD);
- test.test(" hhhh", cal, " 0003", DateFormat.HOUR1_FIELD);
-
- test.test(" H", cal, " 15", DateFormat.HOUR_OF_DAY0_FIELD);
- test.test(" H",
- new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 0), " 4",
- DateFormat.HOUR_OF_DAY0_FIELD);
- test.test(" H", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 12,
- 0), " 12", DateFormat.HOUR_OF_DAY0_FIELD);
- test.test(" H", new GregorianCalendar(1999, Calendar.NOVEMBER, 12),
- " 0", DateFormat.HOUR_OF_DAY0_FIELD);
- test.test(" HH", cal, " 15", DateFormat.HOUR_OF_DAY0_FIELD);
- test.test(" HHHH", cal, " 0015", DateFormat.HOUR_OF_DAY0_FIELD);
-
- test.test(" m", cal, " 3", DateFormat.MINUTE_FIELD);
- test.test(" m", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4,
- 47), " 47", DateFormat.MINUTE_FIELD);
- test.test(" mm", cal, " 03", DateFormat.MINUTE_FIELD);
- test.test(" mmmm", cal, " 0003", DateFormat.MINUTE_FIELD);
-
- test.test(" s", cal, " 6", DateFormat.SECOND_FIELD);
- test.test(" s", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4,
- 47, 13), " 13", DateFormat.SECOND_FIELD);
- test.test(" ss", cal, " 06", DateFormat.SECOND_FIELD);
- test.test(" ssss", cal, " 0006", DateFormat.SECOND_FIELD);
-
- test.test(" S", cal, " 0", DateFormat.MILLISECOND_FIELD);
- Calendar temp = new GregorianCalendar();
- temp.set(Calendar.MILLISECOND, 961);
-
- test.test(" SS", temp, " 961", DateFormat.MILLISECOND_FIELD);
- test.test(" SSSS", cal, " 0000", DateFormat.MILLISECOND_FIELD);
-
- test.test(" SS", cal, " 00", DateFormat.MILLISECOND_FIELD);
-
- test.test(" E", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
- test.test(" EE", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
- test.test(" EEE", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
- test.test(" EEEE", cal, " Wednesday", DateFormat.DAY_OF_WEEK_FIELD);
- test.test(" EEEEE", cal, " W", DateFormat.DAY_OF_WEEK_FIELD);
-
- test.test(" D", cal, " 153", DateFormat.DAY_OF_YEAR_FIELD);
- test.test(" DD", cal, " 153", DateFormat.DAY_OF_YEAR_FIELD);
- test.test(" DDDD", cal, " 0153", DateFormat.DAY_OF_YEAR_FIELD);
-
- test.test(" F", cal, " 1", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
- test.test(" F", new GregorianCalendar(1999, Calendar.NOVEMBER, 14),
- " 2", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
- test.test(" FF", cal, " 01", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
- test.test(" FFFF", cal, " 0001", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
-
- test.test(" a", cal, " PM", DateFormat.AM_PM_FIELD);
- test.test(" a", new GregorianCalendar(1999, Calendar.NOVEMBER, 14),
- " AM", DateFormat.AM_PM_FIELD);
- test.test(" a", new GregorianCalendar(1999, Calendar.NOVEMBER, 14, 12,
- 0), " PM", DateFormat.AM_PM_FIELD);
- test.test(" aa", cal, " PM", DateFormat.AM_PM_FIELD);
- test.test(" aaa", cal, " PM", DateFormat.AM_PM_FIELD);
- test.test(" aaaa", cal, " PM", DateFormat.AM_PM_FIELD);
- test.test(" aaaaa", cal, " PM", DateFormat.AM_PM_FIELD);
-
- test.test(" k", cal, " 15", DateFormat.HOUR_OF_DAY1_FIELD);
- test.test(" k",
- new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 0), " 4",
- DateFormat.HOUR_OF_DAY1_FIELD);
- test.test(" k", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 12,
- 0), " 12", DateFormat.HOUR_OF_DAY1_FIELD);
- test.test(" k", new GregorianCalendar(1999, Calendar.NOVEMBER, 12),
- " 24", DateFormat.HOUR_OF_DAY1_FIELD);
- test.test(" kk", cal, " 15", DateFormat.HOUR_OF_DAY1_FIELD);
- test.test(" kkkk", cal, " 0015", DateFormat.HOUR_OF_DAY1_FIELD);
-
- test.test(" K", cal, " 3", DateFormat.HOUR0_FIELD);
- test.test(" K", new GregorianCalendar(1999, Calendar.NOVEMBER, 12),
- " 0", DateFormat.HOUR0_FIELD);
- test.test(" KK", cal, " 03", DateFormat.HOUR0_FIELD);
- test.test(" KKKK", cal, " 0003", DateFormat.HOUR0_FIELD);
-
- format.applyPattern("'Mkz''':.@5");
- assertEquals("Wrong output", "Mkz':.@5", format.format(new Date()));
-
- //assertTrue("Tests failed", !test.testsFailed());
-
- // Test invalid args to format.
- SimpleDateFormat dateFormat = new SimpleDateFormat();
- try {
- dateFormat.format(null, new StringBuffer(), new FieldPosition(1));
- fail("Expected test to throw NPE.");
- } catch (NullPointerException ex) {
- // expected
- } catch (Throwable ex) {
- fail("Expected test to throw NPE, not " + ex.getClass().getName());
- }
-
- assertFalse(test.testsFailed);
- }
-
- /**
- * This test assumes Unicode behavior where 'y' and 'yyy' don't truncate,
- * which means that it will fail on the RI.
- */
- public void testFormattingYear() {
- FormatTester test = new FormatTester();
-
- Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6);
- test.test(" y", cal, " 1999", DateFormat.YEAR_FIELD);
- test.test(" yy", cal, " 99", DateFormat.YEAR_FIELD);
- test.test(" yy", new GregorianCalendar(2001, Calendar.JUNE, 2), " 01",
- DateFormat.YEAR_FIELD);
- test.test(" yy", new GregorianCalendar(2000, Calendar.JUNE, 2), " 00",
- DateFormat.YEAR_FIELD);
- test.test(" yyy", new GregorianCalendar(2000, Calendar.JUNE, 2), " 2000",
- DateFormat.YEAR_FIELD);
- test.test(" yyy", cal, " 1999", DateFormat.YEAR_FIELD);
- test.test(" yyyy", cal, " 1999", DateFormat.YEAR_FIELD);
- test.test(" yyyyy", cal, " 01999", DateFormat.YEAR_FIELD);
-
- assertFalse(test.testsFailed);
- }
-
- public void testFormattingWeekOfYear() {
- FormatTester test = new FormatTester();
- Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6);
- cal.setMinimalDaysInFirstWeek(1);
- cal.setFirstDayOfWeek(1);
-
- test.test(" w", cal, " 23", DateFormat.WEEK_OF_YEAR_FIELD);
- test.test(" ww", cal, " 23", DateFormat.WEEK_OF_YEAR_FIELD);
- test.test(" wwww", cal, " 0023", DateFormat.WEEK_OF_YEAR_FIELD);
-
- test.test(" W", cal, " 1", DateFormat.WEEK_OF_MONTH_FIELD);
- test.test(" W", new GregorianCalendar(1999, Calendar.NOVEMBER, 14),
- " 3", DateFormat.WEEK_OF_MONTH_FIELD);
- test.test(" WW", cal, " 01", DateFormat.WEEK_OF_MONTH_FIELD);
- test.test(" WWWW", cal, " 0001", DateFormat.WEEK_OF_MONTH_FIELD);
-
- assertFalse(test.testsFailed);
- }
-
- public void testFormattingTimezones() {
- FormatTester test = new FormatTester();
- Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6);
-
- TimeZone tz0001 = new SimpleTimeZone(60000, "ONE MINUTE");
- TimeZone tz0130 = new SimpleTimeZone(5400000, "ONE HOUR, THIRTY");
- TimeZone tzMinus0130 = new SimpleTimeZone(-5400000, "NEG ONE HOUR, THIRTY");
-
- format.setTimeZone(tz0001);
- test.test(" Z", cal, " +0001", DateFormat.TIMEZONE_FIELD);
- test.test(" ZZZZ", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
- test.test(" ZZZZZ", cal, " +00:01", DateFormat.TIMEZONE_FIELD);
- format.setTimeZone(tz0130);
- test.test(" Z", cal, " +0130", DateFormat.TIMEZONE_FIELD);
- format.setTimeZone(tzMinus0130);
- test.test(" Z", cal, " -0130", DateFormat.TIMEZONE_FIELD);
-
- format.setTimeZone(tz0001);
- test.test(" z", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
- test.test(" zzzz", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
- format.setTimeZone(tz0130);
- test.test(" z", cal, " GMT+01:30", DateFormat.TIMEZONE_FIELD);
- format.setTimeZone(tzMinus0130);
- test.test(" z", cal, " GMT-01:30", DateFormat.TIMEZONE_FIELD);
-
- format.setTimeZone(TimeZone.getTimeZone("America/New_York"));
- test.test(" z", cal, " EDT", DateFormat.TIMEZONE_FIELD);
- Calendar temp2 = new GregorianCalendar(1999, Calendar.JANUARY, 12);
- test.test(" z", temp2, " EST", DateFormat.TIMEZONE_FIELD);
- test.test(" zz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
- test.test(" zzz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
- test.test(" zzzz", cal, " Eastern Daylight Time", DateFormat.TIMEZONE_FIELD);
- test.test(" zzzz", temp2, " Eastern Standard Time", DateFormat.TIMEZONE_FIELD);
- test.test(" zzzzz", cal, " Eastern Daylight Time", DateFormat.TIMEZONE_FIELD);
-
- assertFalse(test.testsFailed);
- }
-
- /**
- * java.text.SimpleDateFormat#format(java.util.Date)
- */
- public void test_timeZoneFormatting() {
- // tests specific to formatting of timezones
- Date summerDate = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6).getTime();
- Date winterDate = new GregorianCalendar(1999, Calendar.JANUARY, 12).getTime();
-
- FormatTester test = new FormatTester();
- test.verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, GMT-07:00", summerDate);
- test.verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, GMT-07:00", winterDate);
-
- test.verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", summerDate);
- test.verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", winterDate);
-
- test.verifyFormatTimezone("America/Los_Angeles", "PDT, Pacific Daylight Time", "-0700, GMT-07:00", summerDate);
- test.verifyFormatTimezone("America/Los_Angeles", "PST, Pacific Standard Time", "-0800, GMT-08:00", winterDate);
-
- // this fails on the RI!
- test.verifyFormatTimezone("America/Detroit", "EDT, Eastern Daylight Time", "-0400, GMT-04:00", summerDate);
- test.verifyFormatTimezone("America/Detroit", "EST, Eastern Standard Time", "-0500, GMT-05:00", winterDate);
-
- assertFalse(test.testsFailed);
- }
-
- public void test_parseLjava_lang_StringLjava_text_ParsePosition_2() {
- try {
- format.parse("240 11 2002 March", null);
- fail("ParsePosition is null: NullPointerException was not thrown.");
- } catch(NullPointerException pe) {
- //expected
- }
-
- try {
- format.parse(null, new ParsePosition(0));
- fail("String is null: NullPointerException was not thrown.");
- } catch(NullPointerException pe) {
- //expected
- }
- }
-
- public void test_setDateFormatSymbolsLjava_text_DateFormatSymbols() {
- // Test for method void
- // java.text.SimpleDateFormat.setDateFormatSymbols(java.text.DateFormatSymbols)
- SimpleDateFormat f1 = new SimpleDateFormat("a");
- DateFormatSymbols symbols = new DateFormatSymbols();
- symbols.setAmPmStrings(new String[] { "morning", "night" });
- f1.setDateFormatSymbols(symbols);
- DateFormatSymbols newSym = f1.getDateFormatSymbols();
- assertTrue("Set incorrectly", newSym.equals(symbols));
- assertTrue("Not a clone", f1.getDateFormatSymbols() != symbols);
- String result = f1.format(new GregorianCalendar(1999, Calendar.JUNE,
- 12, 3, 0).getTime());
- assertEquals("Incorrect symbols used", "morning", result);
- symbols.setEras(new String[] { "before", "after" });
- assertTrue("Identical symbols", !f1.getDateFormatSymbols().equals(
- symbols));
-
- try {
- f1.setDateFormatSymbols(null);
- fail("NullPointerException was not thrown.");
- } catch(NullPointerException npe) {
- //expected
- }
- }
-
- public void test_toLocalizedPattern() {
- // BEGIN android-changed
- // Test for method java.lang.String
- // java.text.SimpleDateFormat.toLocalizedPattern()
- SimpleDateFormat f2 = new SimpleDateFormat("GyMdkHmsSEDFwWahKzZ",
- new Locale("de", "CH"));
- String pattern = f2.toLocalizedPattern();
- // the default localized pattern characters are the same for all locales
- // since icu has dropped support for this. the default pattern characters
- // are these: GyMdkHmsSEDFwWahKz
- // ICU only! this fails on the RI
- assertTrue("Wrong pattern: " + pattern, pattern
- .equals("GyMdkHmsSEDFwWahKzZ"));
-
-
- // test the new "Z" pattern char
- f2 = new SimpleDateFormat("G y M d Z", new Locale("de", "CH"));
- pattern = f2.toLocalizedPattern();
- // assertTrue("Wrong pattern: " + pattern, pattern.equals("G u M t Z"));
- assertTrue("Wrong pattern: " + pattern, pattern.equals("G y M d Z"));
- // END android-changed
- }
-
- public void test_toPattern() {
- String pattern = "yyyy mm dd";
- SimpleDateFormat f = new SimpleDateFormat(pattern);
- assertEquals("Wrong pattern: " + pattern, pattern, f.toPattern());
-
- pattern = "GyMdkHmsSEDFwWahKz";
- f = new SimpleDateFormat("GyMdkHmsSEDFwWahKz", new Locale("de", "CH"));
- assertTrue("Wrong pattern: " + pattern, f.toPattern().equals(pattern));
-
- pattern = "G y M d Z";
- f = new SimpleDateFormat(pattern, new Locale("de", "CH"));
- pattern = f.toPattern();
- assertTrue("Wrong pattern: " + pattern, f.toPattern().equals(pattern));
- }
-}
diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
index 2813cee..e73104d 100644
--- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
@@ -80,27 +80,12 @@ public class SimpleDateFormatTest extends junit.framework.TestCase {
// The RI fails this test because it doesn't fully support UTS #35.
// https://code.google.com/p/android/issues/detail?id=39616
public void testFiveCount_parsing() throws Exception {
- // It's pretty silly to try to parse the shortest names, because they're almost always ambiguous.
- try {
- parseDate(Locale.ENGLISH, "MMMMM", "J");
- fail();
- } catch (junit.framework.AssertionFailedError expected) {
- }
- try {
- parseDate(Locale.ENGLISH, "LLLLL", "J");
- fail();
- } catch (junit.framework.AssertionFailedError expected) {
- }
- try {
- parseDate(Locale.ENGLISH, "EEEEE", "T");
- fail();
- } catch (junit.framework.AssertionFailedError expected) {
- }
- try {
- parseDate(Locale.ENGLISH, "ccccc", "T");
- fail();
- } catch (junit.framework.AssertionFailedError expected) {
- }
+ // It's pretty silly to try to parse the shortest names, because they're almost always
+ // ambiguous.
+ assertCannotParse(Locale.ENGLISH, "MMMMM", "J");
+ assertCannotParse(Locale.ENGLISH, "LLLLL", "J");
+ assertCannotParse(Locale.ENGLISH, "EEEEE", "T");
+ assertCannotParse(Locale.ENGLISH, "ccccc", "T");
}
// The RI fails this test because it doesn't fully support UTS #35.
@@ -197,6 +182,13 @@ public class SimpleDateFormatTest extends junit.framework.TestCase {
return dateFormat.format(new Date(0));
}
+ private static void assertCannotParse(Locale l, String fmt, String value) {
+ SimpleDateFormat sdf = new SimpleDateFormat(fmt, l);
+ ParsePosition pp = new ParsePosition(0);
+ Date d = sdf.parse(value, pp);
+ assertNull("Value " + value + " must not parse in locale " + l + " with format " + fmt, d);
+ }
+
private static Calendar parseDate(Locale l, String fmt, String value) {
SimpleDateFormat sdf = new SimpleDateFormat(fmt, l);
ParsePosition pp = new ParsePosition(0);
@@ -215,21 +207,37 @@ public class SimpleDateFormatTest extends junit.framework.TestCase {
String date = "2010-12-23 12:44:57.0 CET";
// ICU considers "CET" (Central European Time) to be common in Britain...
assertEquals(1293104697000L, parseDate(Locale.UK, fmt, date).getTimeInMillis());
- // ...but not in the US. Check we can parse such a date anyway.
- assertEquals(1293104697000L, parseDate(Locale.US, fmt, date).getTimeInMillis());
+ // ...but not in the US.
+ assertCannotParse(Locale.US, fmt, date);
}
+ // In Honeycomb, only one Olson id was associated with CET (or any other "uncommon"
+ // abbreviation). This was changed after KitKat to avoid Java hacks on top of ICU data.
+ // ICU data only provides abbreviations for timezones in the locales where they would
+ // not be ambiguous to most people of that locale.
public void testFormattingUncommonTimeZoneAbbreviations() {
- // In Honeycomb, only one Olson id was associated with CET (or any
- // other "uncommon" abbreviation).
String fmt = "yyyy-MM-dd HH:mm:ss.SSS z";
- String date = "1970-01-01 01:00:00.000 CET";
- SimpleDateFormat sdf = new SimpleDateFormat(fmt, Locale.US);
+ String unambiguousDate = "1970-01-01 01:00:00.000 CET";
+ String ambiguousDate = "1970-01-01 01:00:00.000 GMT+01:00";
+
+ // The locale to use when formatting. Not every Locale renders "Europe/Berlin" as "CET". The
+ // UK is one that does, the US is one that does not.
+ Locale cetUnambiguousLocale = Locale.UK;
+ Locale cetAmbiguousLocale = Locale.US;
+
+ SimpleDateFormat sdf = new SimpleDateFormat(fmt, cetUnambiguousLocale);
+ sdf.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
+ assertEquals(unambiguousDate, sdf.format(new Date(0)));
+ sdf = new SimpleDateFormat(fmt, cetUnambiguousLocale);
+ sdf.setTimeZone(TimeZone.getTimeZone("Europe/Zurich"));
+ assertEquals(unambiguousDate, sdf.format(new Date(0)));
+
+ sdf = new SimpleDateFormat(fmt, cetAmbiguousLocale);
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
- assertEquals(date, sdf.format(new Date(0)));
- sdf = new SimpleDateFormat(fmt, Locale.US);
+ assertEquals(ambiguousDate, sdf.format(new Date(0)));
+ sdf = new SimpleDateFormat(fmt, cetAmbiguousLocale);
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Zurich"));
- assertEquals(date, sdf.format(new Date(0)));
+ assertEquals(ambiguousDate, sdf.format(new Date(0)));
}
// http://code.google.com/p/android/issues/detail?id=8258
@@ -270,17 +278,6 @@ public class SimpleDateFormatTest extends junit.framework.TestCase {
assertEquals("2010-07-08T02:44:48+0000", sdf.format(date));
}
- /**
- * Africa/Cairo standard time is EET and daylight time is EEST. They no
- * longer use their DST zone but we should continue to parse it properly.
- */
- public void testObsoleteDstZoneName() throws Exception {
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz", Locale.US);
- Date normal = format.parse("1970-01-01T00:00 EET");
- Date dst = format.parse("1970-01-01T00:00 EEST");
- assertEquals(60 * 60 * 1000, normal.getTime() - dst.getTime());
- }
-
public void testDstZoneNameWithNonDstTimestamp() throws Exception {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz", Locale.US);
Calendar calendar = new GregorianCalendar(AMERICA_LOS_ANGELES);
@@ -353,4 +350,32 @@ public class SimpleDateFormatTest extends junit.framework.TestCase {
assertEquals(1376927400000L, sdf.parse("19. Aug 2013 8:50").getTime());
assertEquals(1376927400000L, sdf.parse("19. Aug. 2013 8:50").getTime());
}
+
+ // http://b/16969112
+ public void test_fractionalSeconds() throws Exception {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
+ assertEquals("1970-01-02 02:17:36.7", sdf.format(sdf.parse("1970-01-02 02:17:36.7")));
+
+ // We only have millisecond precision for Date objects, so we'll lose
+ // information from the fractional seconds section of the string presentation.
+ sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
+ assertEquals("1970-01-02 02:17:36.789000", sdf.format(sdf.parse("1970-01-02 02:17:36.789564")));
+ }
+
+ public void test_nullLocales() {
+ try {
+ SimpleDateFormat.getDateInstance(DateFormat.SHORT, null);
+ fail();
+ } catch (NullPointerException expected) {}
+
+ try {
+ SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, null);
+ fail();
+ } catch (NullPointerException expected) {}
+
+ try {
+ SimpleDateFormat.getTimeInstance(DateFormat.SHORT, null);
+ fail();
+ } catch (NullPointerException expected) {}
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/AbstractResourceLeakageDetectorTestCase.java b/luni/src/test/java/libcore/java/util/AbstractResourceLeakageDetectorTestCase.java
new file mode 100644
index 0000000..5ea67d3
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/AbstractResourceLeakageDetectorTestCase.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.java.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Ensures that resources used within a test are cleaned up; will detect problems with tests and
+ * also with runtime.
+ */
+public abstract class AbstractResourceLeakageDetectorTestCase extends TestCase {
+ /**
+ * The leakage detector.
+ */
+ private ResourceLeakageDetector detector;
+
+ @Override
+ protected void setUp() throws Exception {
+ detector = ResourceLeakageDetector.newDetector();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // If available check for resource leakage. At this point it is impossible to determine
+ // whether the test has thrown an exception. If it has then the exception thrown by this
+ // could hide that test failure; it largely depends on the test runner.
+ if (detector != null) {
+ detector.checkForLeaks();
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/CalendarTest.java b/luni/src/test/java/libcore/java/util/CalendarTest.java
index dd44789..e0e1a35 100644
--- a/luni/src/test/java/libcore/java/util/CalendarTest.java
+++ b/luni/src/test/java/libcore/java/util/CalendarTest.java
@@ -17,6 +17,7 @@
package libcore.java.util;
import java.util.Calendar;
+import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
@@ -187,8 +188,10 @@ public class CalendarTest extends junit.framework.TestCase {
+ "10000000500000001000000200000000178";
Calendar calendar = new GregorianCalendar(1970, 1, 1, 0, 0, 0);
calendar.setTimeZone(TimeZone.getTimeZone("GMT-08:00"));
- // Starting from ICU4.8 release, the default minimalDaysInFirstWeek changed from 4 to 1.
+ // Calendar fields firstDayOfWeek and minimalDaysInFirstWeek are are sensitive to the Locale
+ // and ICU data. Specifying the values here makes the serialized form stable.
calendar.setMinimalDaysInFirstWeek(4);
+ calendar.setFirstDayOfWeek(Calendar.SUNDAY);
new SerializationTester<Calendar>(calendar, s).test();
}
@@ -236,4 +239,28 @@ public class CalendarTest extends junit.framework.TestCase {
cal.set(Calendar.HOUR_OF_DAY, 1);
assertEquals(32400000, cal.getTimeInMillis());
}
+
+ // http://b/16938922.
+ //
+ // TODO: This is for backwards compatibility only. Seems like a better idea to throw
+ // here. We should add a targetSdkVersion based check and throw for each of these
+ // cases.
+ public void test_nullLocale() {
+ assertCalendarConfigEquals(
+ Calendar.getInstance(Locale.getDefault()),
+ Calendar.getInstance((Locale) null));
+ assertCalendarConfigEquals(
+ Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault()),
+ Calendar.getInstance(TimeZone.getDefault(), null));
+ assertCalendarConfigEquals(
+ new GregorianCalendar(Locale.getDefault()),
+ new GregorianCalendar((Locale) null));
+ }
+
+ public void assertCalendarConfigEquals(Calendar a, Calendar b) {
+ Date d = new Date();
+ a.setTime(d);
+ b.setTime(d);
+ assertEquals(a, b);
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/CurrencyTest.java b/luni/src/test/java/libcore/java/util/CurrencyTest.java
index 61a22fd..cf2a1b6 100644
--- a/luni/src/test/java/libcore/java/util/CurrencyTest.java
+++ b/luni/src/test/java/libcore/java/util/CurrencyTest.java
@@ -79,4 +79,12 @@ public class CurrencyTest extends junit.framework.TestCase {
assertEquals("€", Currency.getInstance(pt_PT).getSymbol(pt_BR));
assertEquals("€", Currency.getInstance(pt_PT).getSymbol(pt_PT));
}
+
+ public void test_nullLocales() {
+ Currency currency = Currency.getInstance(Locale.getDefault());
+ try {
+ currency.getSymbol(null);
+ fail();
+ } catch (NullPointerException expected) {}
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/DateTest.java b/luni/src/test/java/libcore/java/util/DateTest.java
index ddcc3e5..3ed0952 100644
--- a/luni/src/test/java/libcore/java/util/DateTest.java
+++ b/luni/src/test/java/libcore/java/util/DateTest.java
@@ -24,16 +24,26 @@ import junit.framework.TestCase;
public class DateTest extends TestCase {
// http://code.google.com/p/android/issues/detail?id=6013
- public void test_toString() throws Exception {
- // Ensure that no matter where this is run, we know what time zone
- // to expect. (Though we still assume an "en" locale.)
+ public void test_toString_us() throws Exception {
+ // Ensure that no matter where this is run, we know what time zone to expect.
+ Locale.setDefault(Locale.US);
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
assertEquals("Wed Dec 31 18:00:00 CST 1969", new Date(0).toString());
}
- public void test_toGMTString() throws Exception {
+ public void test_toString_nonUs() {
+ // The string for the timezone depends on what the default locale is. Not every locale
+ // has a short-name for America/Chicago -> PST.
+ Locale.setDefault(Locale.UK);
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
+ assertEquals("Wed Dec 31 18:00:00 GMT-06:00 1969", new Date(0).toString());
+ }
+
+ public void test_toGMTString_us() throws Exception {
// Based on https://issues.apache.org/jira/browse/HARMONY-501
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+ Locale.setDefault(Locale.US);
+
Calendar c = Calendar.getInstance();
c.clear();
c.set(Calendar.YEAR, 21);
@@ -43,4 +53,18 @@ public class DateTest extends TestCase {
assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString());
assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString());
}
+
+ public void test_toGMTString_nonUs() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+ Locale.setDefault(Locale.UK);
+
+ Calendar c = Calendar.getInstance();
+ c.clear();
+ c.set(Calendar.YEAR, 21);
+ assertEquals("Wed Jan 01 00:00:00 GMT-08:00 21", c.getTime().toString());
+ assertEquals("1 Jan 21 08:00:00 GMT", c.getTime().toGMTString());
+ c.set(Calendar.YEAR, 321);
+ assertEquals("Sun Jan 01 00:00:00 GMT-08:00 321", c.getTime().toString());
+ assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString());
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/GregorianCalendarTest.java b/luni/src/test/java/libcore/java/util/GregorianCalendarTest.java
new file mode 100644
index 0000000..b2c50b2
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/GregorianCalendarTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package libcore.java.util;
+
+
+import junit.framework.TestCase;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+public class GregorianCalendarTest extends TestCase {
+
+ // https://code.google.com/p/android/issues/detail?id=61993
+ public void test_computeFields_dayOfWeekAndWeekOfYearSet() {
+ Calendar greg = GregorianCalendar.getInstance();
+
+ // Setting WEEK_OF_YEAR and DAY_OF_WEEK with an intervening
+ // call to computeFields will work.
+ greg.set(Calendar.WEEK_OF_YEAR, 1);
+ assertEquals(1, greg.get(Calendar.WEEK_OF_YEAR));
+ greg.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ assertEquals(1, greg.get(Calendar.WEEK_OF_YEAR));
+
+ // Setting WEEK_OF_YEAR after DAY_OF_WEEK with no intervening
+ // call to computeFields will work.
+ greg = GregorianCalendar.getInstance();
+ greg.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ greg.set(Calendar.WEEK_OF_YEAR, 1);
+ assertEquals(1, greg.get(Calendar.WEEK_OF_YEAR));
+ assertEquals(Calendar.MONDAY, greg.get(Calendar.DAY_OF_WEEK));
+
+ // Setting DAY_OF_WEEK *after* WEEK_OF_YEAR with no intervening computeFields
+ // will make WEEK_OF_YEAR have no effect. This is a limitation of the API.
+ // Combinations are chosen based *only* on the value of the last field set,
+ // which in this case is DAY_OF_WEEK.
+ greg = GregorianCalendar.getInstance();
+ int weekOfYear = greg.get(Calendar.WEEK_OF_YEAR);
+ greg.set(Calendar.WEEK_OF_YEAR, 1);
+ greg.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ // Unchanged WEEK_OF_YEAR.
+ assertEquals(weekOfYear, greg.get(Calendar.WEEK_OF_YEAR));
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/LocaleInternalsTest.java b/luni/src/test/java/libcore/java/util/LocaleInternalsTest.java
new file mode 100644
index 0000000..5344f08
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/LocaleInternalsTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package libcore.java.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import junit.framework.TestCase;
+import libcore.icu.ICU;
+
+public class LocaleInternalsTest extends TestCase {
+
+ public void test_serializeExtensions() {
+ Map<Character, String> extensions = new TreeMap<Character, String>();
+
+ extensions.put('x', "fooo-baar-baaz");
+ assertEquals("x-fooo-baar-baaz", Locale.serializeExtensions(extensions));
+
+ extensions.put('y', "gaaa-caar-caaz");
+ // Must show up in lexical order.
+ assertEquals("x-fooo-baar-baaz-y-gaaa-caar-caaz",
+ Locale.serializeExtensions(extensions));
+ }
+
+ public void test_parseSerializedExtensions() {
+ Map<Character, String> extensions = new HashMap<Character, String>();
+
+ Locale.parseSerializedExtensions("x-foo", extensions);
+ assertEquals("foo", extensions.get('x'));
+
+ extensions.clear();
+ Locale.parseSerializedExtensions("x-foo-y-bar-z-baz", extensions);
+ assertEquals("foo", extensions.get('x'));
+ assertEquals("bar", extensions.get('y'));
+ assertEquals("baz", extensions.get('z'));
+
+ extensions.clear();
+ Locale.parseSerializedExtensions("x-fooo-baar-baaz", extensions);
+ assertEquals("fooo-baar-baaz", extensions.get('x'));
+
+ extensions.clear();
+ Locale.parseSerializedExtensions("x-fooo-baar-baaz-y-gaaa-caar-caaz", extensions);
+ assertEquals("fooo-baar-baaz", extensions.get('x'));
+ assertEquals("gaaa-caar-caaz", extensions.get('y'));
+ }
+
+ public void test_parseUnicodeExtension() {
+ Map<String, String> keywords = new HashMap<String, String>();
+ Set<String> attributes = new HashSet<String>();
+
+ // Only attributes.
+ Locale.parseUnicodeExtension("foooo".split("-"), keywords, attributes);
+ assertTrue(attributes.contains("foooo"));
+ assertEquals(Collections.EMPTY_SET, keywords.keySet());
+
+ attributes.clear();
+ keywords.clear();
+ Locale.parseUnicodeExtension("foooo-baa-baaabaaa".split("-"),
+ keywords, attributes);
+ assertTrue(attributes.contains("foooo"));
+ assertTrue(attributes.contains("baa"));
+ assertTrue(attributes.contains("baaabaaa"));
+ assertEquals(Collections.EMPTY_SET, keywords.keySet());
+
+ // Only keywords
+ attributes.clear();
+ keywords.clear();
+ Locale.parseUnicodeExtension("ko-koko".split("-"), keywords, attributes);
+ assertTrue(attributes.isEmpty());
+ assertEquals("koko", keywords.get("ko"));
+
+ attributes.clear();
+ keywords.clear();
+ Locale.parseUnicodeExtension("ko-koko-kokoko".split("-"), keywords, attributes);
+ assertTrue(attributes.isEmpty());
+ assertEquals("koko-kokoko", keywords.get("ko"));
+
+ attributes.clear();
+ keywords.clear();
+ Locale.parseUnicodeExtension("ko-koko-kokoko-ba-baba-bababa".split("-"),
+ keywords, attributes);
+ assertTrue(attributes.isEmpty());
+ assertEquals("koko-kokoko", keywords.get("ko"));
+ assertEquals("baba-bababa", keywords.get("ba"));
+
+ // A mixture of attributes and keywords.
+ attributes.clear();
+ keywords.clear();
+ Locale.parseUnicodeExtension("attri1-attri2-k1-type1-type1-k2-type2".split("-"),
+ keywords, attributes);
+ assertTrue(attributes.contains("attri1"));
+ assertTrue(attributes.contains("attri2"));
+ assertEquals("type1-type1", keywords.get("k1"));
+ assertEquals("type2", keywords.get("k2"));
+ }
+
+ public void test_setDefault_setsICUDefaultLocale() {
+ Locale.setDefault(Locale.GERMANY);
+ assertEquals("de_DE", ICU.getDefaultLocale());
+
+ try {
+ Locale.setDefault(null);
+ fail();
+ } catch (NullPointerException expected) {
+ assertEquals(Locale.GERMANY, Locale.getDefault());
+ }
+
+ Locale.setDefault(new Locale("bogus", "LOCALE"));
+ assertEquals("und", ICU.getDefaultLocale());
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index dee529f..c72ecd7 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -20,10 +20,9 @@ import java.text.BreakIterator;
import java.text.Collator;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
-import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
-import java.util.Arrays;
import java.util.Calendar;
+import java.util.IllformedLocaleException;
import java.util.Locale;
import java.util.MissingResourceException;
@@ -40,9 +39,22 @@ public class LocaleTest extends junit.framework.TestCase {
// and variant, but a display name made up of the raw strings.
// Newer releases return slightly different results, but no less unreasonable.
assertEquals("aabbcc", invalid.getDisplayLanguage());
- assertEquals("", invalid.getDisplayCountry());
- assertEquals("DDEEFF_GGHHII", invalid.getDisplayVariant());
- assertEquals("aabbcc (DDEEFF,DDEEFF_GGHHII)", invalid.getDisplayName());
+ assertEquals("DDEEFF", invalid.getDisplayCountry());
+ assertEquals("GGHHII", invalid.getDisplayVariant());
+ assertEquals("aabbcc (DDEEFF,GGHHII)", invalid.getDisplayName());
+ }
+
+ public void test_getDisplayName_emptyCodes() {
+ Locale emptyLanguage = new Locale("", "DdeEFf");
+ assertEquals("", emptyLanguage.getDisplayLanguage());
+
+ Locale emptyCountry = new Locale("AaBbCc", "");
+ assertEquals("", emptyCountry.getDisplayCountry());
+
+ Locale emptyCountryAndLanguage = new Locale("", "", "Farl");
+ assertEquals("", emptyCountryAndLanguage.getDisplayLanguage());
+ assertEquals("", emptyCountryAndLanguage.getDisplayCountry());
+ assertEquals("Farl", emptyCountryAndLanguage.getDisplayVariant());
}
// http://b/2611311; if there's no display language/country/variant, use the raw codes.
@@ -54,8 +66,8 @@ public class LocaleTest extends junit.framework.TestCase {
assertEquals("xx", unknown.getDisplayLanguage());
assertEquals("YY", unknown.getDisplayCountry());
- assertEquals("TRADITIONAL", unknown.getDisplayVariant());
- assertEquals("xx (YY,TRADITIONAL)", unknown.getDisplayName());
+ assertEquals("Traditional", unknown.getDisplayVariant());
+ assertEquals("xx (YY,Traditional)", unknown.getDisplayName());
}
public void test_getDisplayName_easy() throws Exception {
@@ -65,36 +77,68 @@ public class LocaleTest extends junit.framework.TestCase {
assertEquals("Deutsch", Locale.GERMAN.getDisplayLanguage(Locale.GERMAN));
}
+ // https://b/issue?id=13790528
+ public void test_getDisplayName_withScriptsAndVariants() throws Exception {
+ // Script + Country.
+ assertEquals("Chinese (Traditional Han,China)",
+ Locale.forLanguageTag("zh-Hant-CN").getDisplayName(Locale.US));
+ // Script + Variant.
+ assertEquals("Chinese (Traditional Han,VARIANT)",
+ Locale.forLanguageTag("zh-Hant-VARIANT").getDisplayName(Locale.US));
+ // Country + Variant.
+ assertEquals("Chinese (China,VARIANT)",
+ Locale.forLanguageTag("zh-CN-VARIANT").getDisplayName(Locale.US));
+ // Script + Country + variant.
+ assertEquals("Chinese (Traditional Han,China,VARIANT)",
+ Locale.forLanguageTag("zh-Hant-CN-VARIANT").getDisplayName(Locale.US));
+ }
+
public void test_getDisplayCountry_8870289() throws Exception {
assertEquals("Hong Kong", new Locale("", "HK").getDisplayCountry(Locale.US));
assertEquals("Macau", new Locale("", "MO").getDisplayCountry(Locale.US));
assertEquals("Palestine", new Locale("", "PS").getDisplayCountry(Locale.US));
- assertEquals("Cocos [Keeling] Islands", new Locale("", "CC").getDisplayCountry(Locale.US));
- assertEquals("Congo [DRC]", new Locale("", "CD").getDisplayCountry(Locale.US));
- assertEquals("Congo [Republic]", new Locale("", "CG").getDisplayCountry(Locale.US));
- assertEquals("Falkland Islands [Islas Malvinas]", new Locale("", "FK").getDisplayCountry(Locale.US));
- assertEquals("Macedonia [FYROM]", new Locale("", "MK").getDisplayCountry(Locale.US));
- assertEquals("Myanmar [Burma]", new Locale("", "MM").getDisplayCountry(Locale.US));
+ assertEquals("Cocos (Keeling) Islands", new Locale("", "CC").getDisplayCountry(Locale.US));
+ assertEquals("Congo (DRC)", new Locale("", "CD").getDisplayCountry(Locale.US));
+ assertEquals("Congo (Republic)", new Locale("", "CG").getDisplayCountry(Locale.US));
+ assertEquals("Falkland Islands (Islas Malvinas)", new Locale("", "FK").getDisplayCountry(Locale.US));
+ assertEquals("Macedonia (FYROM)", new Locale("", "MK").getDisplayCountry(Locale.US));
+ assertEquals("Myanmar (Burma)", new Locale("", "MM").getDisplayCountry(Locale.US));
assertEquals("Taiwan", new Locale("", "TW").getDisplayCountry(Locale.US));
}
- public void test_tl() throws Exception {
+ public void test_tl_and_fil() throws Exception {
// In jb-mr1, we had a last-minute hack to always return "Filipino" because
- // icu4c 4.8 didn't have any localizations for fil. (http://b/7291355)
+ // icu4c 4.8 didn't have any localizations for fil. (http://b/7291355).
+ //
+ // After the icu4c 4.9 upgrade, we could localize "fil" correctly, though we
+ // needed another hack to supply "fil" instead of "tl" to icu4c. (http://b/8023288).
+ //
+ // These hacks have now been reverted, so "tl" really does represent
+ // tagalog and not filipino.
Locale tl = new Locale("tl");
Locale tl_PH = new Locale("tl", "PH");
- assertEquals("Filipino", tl.getDisplayLanguage(Locale.ENGLISH));
- assertEquals("Filipino", tl_PH.getDisplayLanguage(Locale.ENGLISH));
- assertEquals("Filipino", tl.getDisplayLanguage(tl));
- assertEquals("Filipino", tl_PH.getDisplayLanguage(tl_PH));
+ assertEquals("Tagalog", tl.getDisplayLanguage(Locale.ENGLISH));
+ assertEquals("Tagalog", tl_PH.getDisplayLanguage(Locale.ENGLISH));
+ assertEquals("tl", tl.getDisplayLanguage(tl));
+ assertEquals("tl", tl_PH.getDisplayLanguage(tl_PH));
- // After the icu4c 4.9 upgrade, we could localize "fil" correctly, though we
- // needed another hack to supply "fil" instead of "tl" to icu4c. (http://b/8023288)
Locale es_MX = new Locale("es", "MX");
- assertEquals("filipino", tl.getDisplayLanguage(es_MX));
- assertEquals("filipino", tl_PH.getDisplayLanguage(es_MX));
- }
+ assertEquals("tagalo", tl.getDisplayLanguage(es_MX));
+ assertEquals("tagalo", tl_PH.getDisplayLanguage(es_MX));
+
+ // Assert that we can deal with "fil" correctly, since we've switched
+ // to using "fil" for Filipino, and not "tl". (http://b/15873165).
+ Locale fil = new Locale("fil");
+ Locale fil_PH = new Locale("fil", "PH");
+ assertEquals("Filipino", fil.getDisplayLanguage(Locale.ENGLISH));
+ assertEquals("Filipino", fil_PH.getDisplayLanguage(Locale.ENGLISH));
+ assertEquals("Filipino", fil.getDisplayLanguage(fil));
+ assertEquals("Filipino", fil_PH.getDisplayLanguage(fil_PH));
+
+ assertEquals("filipino", fil.getDisplayLanguage(es_MX));
+ assertEquals("filipino", fil_PH.getDisplayLanguage(es_MX));
+ }
// http://b/3452611; Locale.getDisplayLanguage fails for the obsolete language codes.
public void test_getDisplayName_obsolete() throws Exception {
@@ -158,6 +202,10 @@ public class LocaleTest extends junit.framework.TestCase {
assertEquals("CAN", new Locale("", "CA").getISO3Country());
assertEquals("CAN", new Locale("en", "CA").getISO3Country());
assertEquals("CAN", new Locale("xx", "CA").getISO3Country());
+
+ // 3 letter country codes.
+ assertEquals("CAN", new Locale("en", "CAN").getISO3Country());
+ assertEquals("CAN", new Locale("frankenderp", "CAN").getISO3Country());
}
public void test_getISO3Language() {
@@ -177,5 +225,925 @@ public class LocaleTest extends junit.framework.TestCase {
assertEquals("eng", new Locale("en", "").getISO3Language());
assertEquals("eng", new Locale("en", "CA").getISO3Language());
assertEquals("eng", new Locale("en", "XX").getISO3Language());
+
+ // 3 letter language code.
+ assertEquals("eng", new Locale("eng", "USA").getISO3Language());
+ assertEquals("eng", new Locale("eng", "US").getISO3Language());
+ }
+
+ public void test_Builder_setLanguage() {
+ Locale.Builder b = new Locale.Builder();
+
+ // Should normalize to lower case.
+ b.setLanguage("EN");
+ assertEquals("en", b.build().getLanguage());
+
+ b = new Locale.Builder();
+
+ // Too short.
+ try {
+ b.setLanguage("e");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Too long
+ try {
+ b.setLanguage("engl");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Contains non ASCII characters
+ try {
+ b.setLanguage("தமிழà¯");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Null or empty languages must clear state.
+ b = new Locale.Builder();
+ b.setLanguage("en");
+ b.setLanguage(null);
+ assertEquals("", b.build().getLanguage());
+
+ b = new Locale.Builder();
+ b.setLanguage("en");
+ b.setLanguage("");
+ assertEquals("", b.build().getLanguage());
+ }
+
+ public void test_Builder_setRegion() {
+ Locale.Builder b = new Locale.Builder();
+
+ // Should normalize to upper case.
+ b.setRegion("us");
+ assertEquals("US", b.build().getCountry());
+
+ b = new Locale.Builder();
+
+ // Too short.
+ try {
+ b.setRegion("e");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Too long
+ try {
+ b.setRegion("USA");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Contains non ASCII characters
+ try {
+ b.setLanguage("திழà¯");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Null or empty regions must clear state.
+ b = new Locale.Builder();
+ b.setRegion("US");
+ b.setRegion(null);
+ assertEquals("", b.build().getCountry());
+
+ b = new Locale.Builder();
+ b.setRegion("US");
+ b.setRegion("");
+ assertEquals("", b.build().getCountry());
+ }
+
+ public void test_Builder_setVariant() {
+ Locale.Builder b = new Locale.Builder();
+
+ // Should normalize "_" to "-"
+ b = new Locale.Builder();
+ b.setVariant("vArIaNt-VaRiAnT-VARIANT");
+ assertEquals("vArIaNt_VaRiAnT_VARIANT", b.build().getVariant());
+
+ b = new Locale.Builder();
+ // Too short
+ try {
+ b.setVariant("shor");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Too long
+ try {
+ b.setVariant("waytoolong");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ try {
+ b.setVariant("foooo-foooo-fo");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Special case. Variants of length 4 are allowed when the first
+ // character is a digit.
+ b.setVariant("0ABC");
+ assertEquals("0ABC", b.build().getVariant());
+
+ b = new Locale.Builder();
+ b.setVariant("variant");
+ b.setVariant(null);
+ assertEquals("", b.build().getVariant());
+
+ b = new Locale.Builder();
+ b.setVariant("variant");
+ b.setVariant("");
+ assertEquals("", b.build().getVariant());
+ }
+
+ public void test_Builder_setLocale() {
+ // Default case.
+ Locale.Builder b = new Locale.Builder();
+ b.setLocale(Locale.US);
+ assertEquals("en", b.build().getLanguage());
+ assertEquals("US", b.build().getCountry());
+
+ // Should throw when locale is malformed.
+ // - Bad language
+ Locale bad = new Locale("e", "US");
+ b = new Locale.Builder();
+ try {
+ b.setLocale(bad);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+ // - Bad country
+ bad = new Locale("en", "USA");
+ try {
+ b.setLocale(bad);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // - Bad variant
+ bad = new Locale("en", "US", "c");
+ try {
+ b.setLocale(bad);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Test values are normalized as they should be
+ b = new Locale.Builder();
+ Locale good = new Locale("EN", "us", "variant-VARIANT");
+ b.setLocale(good);
+ Locale l = b.build();
+ assertEquals("en", l.getLanguage());
+ assertEquals("US", l.getCountry());
+ assertEquals("variant_VARIANT", l.getVariant());
+
+ // Test that none of the existing fields are messed with
+ // if the locale update fails.
+ b = new Locale.Builder();
+ b.setLanguage("fr").setRegion("FR");
+
+ try {
+ b.setLocale(bad);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ l = b.build();
+ assertEquals("fr", l.getLanguage());
+ assertEquals("FR", l.getCountry());
+ }
+
+ public void test_Builder_setScript() {
+ Locale.Builder b = new Locale.Builder();
+
+ // Should normalize variants to lower case.
+ b.setScript("lAtN");
+ assertEquals("Latn", b.build().getScript());
+
+ b = new Locale.Builder();
+ // Too short
+ try {
+ b.setScript("lat");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Too long
+ try {
+ b.setScript("latin");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ b = new Locale.Builder();
+ b.setScript("Latn");
+ b.setScript(null);
+ assertEquals("", b.build().getScript());
+
+ b = new Locale.Builder();
+ b.setScript("Latn");
+ b.setScript("");
+ assertEquals("", b.build().getScript());
+ }
+
+ public void test_Builder_clear() {
+ Locale.Builder b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn").setRegion("US")
+ .setVariant("POSIX").setExtension('g', "foo")
+ .setUnicodeLocaleKeyword("fo", "baar")
+ .addUnicodeLocaleAttribute("baaaaz");
+
+ Locale l = b.clear().build();
+ assertEquals("", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("", l.getVariant());
+ assertEquals("", l.getScript());
+ assertTrue(l.getExtensionKeys().isEmpty());
+ }
+
+ public void test_Builder_setExtension() {
+ Locale.Builder b = new Locale.Builder();
+ b.setExtension('g', "FO_ba-BR_bg");
+
+ Locale l = b.build();
+ assertEquals("fo-ba-br-bg", l.getExtension('g'));
+
+ b = new Locale.Builder();
+
+ // Too short
+ try {
+ b.setExtension('g', "fo-ba-br-x");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Too long
+ try {
+ b.setExtension('g', "fo-ba-br-extension");
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Special case, the private use extension allows single char subtags.
+ b.setExtension(Locale.PRIVATE_USE_EXTENSION, "fo-ba-br-m");
+ l = b.build();
+ assertEquals("fo-ba-br-m", l.getExtension('x'));
+
+ // Special case, the unicode locale extension must be parsed into
+ // its individual components. The correctness of the parse is tested
+ // in test_parseUnicodeExtension.
+ b.setExtension(Locale.UNICODE_LOCALE_EXTENSION, "foooo_BaaaR-BA_Baz-bI_BIZ");
+ l = b.build();
+ // Note that attributes and keywords are sorted alphabetically.
+ assertEquals("baaar-foooo-ba-baz-bi-biz", l.getExtension('u'));
+
+ assertTrue(l.getUnicodeLocaleAttributes().contains("foooo"));
+ assertTrue(l.getUnicodeLocaleAttributes().contains("baaar"));
+ assertEquals("baz", l.getUnicodeLocaleType("ba"));
+ assertEquals("biz", l.getUnicodeLocaleType("bi"));
+ }
+
+ public void test_Builder_clearExtensions() {
+ Locale.Builder b = new Locale.Builder();
+ b.setExtension('g', "FO_ba-BR_bg");
+ b.setExtension(Locale.PRIVATE_USE_EXTENSION, "fo-ba-br-m");
+ b.clearExtensions();
+
+ assertTrue(b.build().getExtensionKeys().isEmpty());
+ }
+
+ private static Locale fromLanguageTag(String languageTag, boolean useBuilder) {
+ if (useBuilder) {
+ return (new Locale.Builder().setLanguageTag(languageTag).build());
+ } else {
+ return Locale.forLanguageTag(languageTag);
+ }
+ }
+
+ private void test_setLanguageTag_wellFormedsingleSubtag(boolean useBuilder) {
+ Locale l = fromLanguageTag("en", useBuilder);
+ assertEquals("en", l.getLanguage());
+
+ l = fromLanguageTag("eng", useBuilder);
+ assertEquals("eng", l.getLanguage());
+ }
+
+ private void test_setLanguageTag_twoWellFormedSubtags(boolean useBuilder) {
+ Locale l = fromLanguageTag("en-US", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("US", l.getCountry());
+
+ l = fromLanguageTag("eng-419", useBuilder);
+ assertEquals("eng", l.getLanguage());
+ assertEquals("419", l.getCountry());
+
+ // Script tags shouldn't be mis-recognized as regions.
+ l = fromLanguageTag("en-Latn", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("Latn", l.getScript());
+
+ // Neither should variant tags.
+ l = fromLanguageTag("en-POSIX", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("", l.getScript());
+ assertEquals("POSIX", l.getVariant());
+ }
+
+ public void test_Builder_setLanguageTag_malformedTags() {
+ try {
+ fromLanguageTag("a", true);
+ fail();
+ } catch (IllformedLocaleException ifle) {
+ }
+
+ // Three subtags
+ // lang-region-illformedvariant
+ try {
+ fromLanguageTag("en-US-BA", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // lang-variant-illformedvariant
+ try {
+ fromLanguageTag("en-FOOOO-BA", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Four or more sub tags
+ try {
+ fromLanguageTag("en-US-POSIX-P2", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ try {
+ fromLanguageTag("en-Latn-US-P2", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Extensions
+ // Ill-formed empty extension.
+ try {
+ fromLanguageTag("en-f-f", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Ill-formed empty extension.
+ try {
+ fromLanguageTag("en-f", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Two extension keys in a row (i.e, another case of an ill-formed
+ // empty exception).
+ try {
+ fromLanguageTag("en-f-g-fo-baar", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Dangling empty key after a well formed extension.
+ try {
+ fromLanguageTag("en-f-fo-baar-g", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+
+ // Ill-formed extension with long subtag.
+ try {
+ fromLanguageTag("en-f-fooobaaaz", true);
+ fail();
+ } catch (IllformedLocaleException expected) {
+ }
+ }
+
+ private void test_setLanguageTag_threeWellFormedSubtags(boolean useBuilder) {
+ // lang-region-variant
+ Locale l = fromLanguageTag("en-US-FOOOO", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("US", l.getCountry());
+ assertEquals("", l.getScript());
+ assertEquals("FOOOO", l.getVariant());
+
+ // lang-script-variant
+ l = fromLanguageTag("en-Latn-FOOOO", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("Latn", l.getScript());
+ assertEquals("FOOOO", l.getVariant());
+
+ // lang-script-region
+ l = fromLanguageTag("en-Latn-US", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("US", l.getCountry());
+ assertEquals("Latn", l.getScript());
+ assertEquals("", l.getVariant());
+
+ // lang-variant-variant
+ l = fromLanguageTag("en-FOOOO-BAAAR", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("", l.getScript());
+ assertEquals("FOOOO_BAAAR", l.getVariant());
+ }
+
+ private void test_setLanguageTag_fourOrMoreWellFormedSubtags(boolean useBuilder) {
+ // lang-script-region-variant.
+ Locale l = fromLanguageTag("en-Latn-US-foooo", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("Latn", l.getScript());
+ assertEquals("US", l.getCountry());
+ assertEquals("foooo", l.getVariant());
+
+ // Variant with multiple subtags.
+ l = fromLanguageTag("en-Latn-US-foooo-gfffh", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("Latn", l.getScript());
+ assertEquals("US", l.getCountry());
+ assertEquals("foooo_gfffh", l.getVariant());
+
+ // Variant with 3 subtags. POSIX shouldn't be recognized
+ // as a region or a script.
+ l = fromLanguageTag("en-POSIX-P2003-P2004", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getScript());
+ assertEquals("", l.getCountry());
+ assertEquals("POSIX_P2003_P2004", l.getVariant());
+
+ // lang-script-variant-variant.
+ l = fromLanguageTag("en-Latn-POSIX-P2003", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("Latn", l.getScript());
+ assertEquals("", l.getCountry());
+ assertEquals("POSIX_P2003", l.getVariant());
+
+ // lang-region-variant-variant
+ l = fromLanguageTag("en-US-POSIX-P2003", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getScript());
+ assertEquals("US", l.getCountry());
+ assertEquals("POSIX_P2003", l.getVariant());
+ }
+
+ private void test_setLanguageTag_withWellFormedExtensions(boolean useBuilder) {
+ Locale l = fromLanguageTag("en-Latn-GB-foooo-g-fo-bar-baaz", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("Latn", l.getScript());
+ assertEquals("GB", l.getCountry());
+ assertEquals("foooo", l.getVariant());
+ assertEquals("fo-bar-baaz", l.getExtension('g'));
+
+ // Multiple extensions
+ l = fromLanguageTag("en-Latn-US-foooo-g-fo-bar-h-go-gaz", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("Latn", l.getScript());
+ assertEquals("US", l.getCountry());
+ assertEquals("foooo", l.getVariant());
+ assertEquals("fo-bar", l.getExtension('g'));
+ assertEquals("go-gaz", l.getExtension('h'));
+
+ // Unicode locale extension.
+ l = fromLanguageTag("en-Latn-US-foooo-u-koooo-fo-bar", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("Latn", l.getScript());
+ assertEquals("US", l.getCountry());
+ assertEquals("koooo-fo-bar", l.getExtension('u'));
+ assertTrue(l.getUnicodeLocaleAttributes().contains("koooo"));
+ assertEquals("bar", l.getUnicodeLocaleType("fo"));
+
+ // Extensions without variants
+ l = fromLanguageTag("en-Latn-US-f-fo", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("Latn", l.getScript());
+ assertEquals("US", l.getCountry());
+ assertEquals("fo", l.getExtension('f'));
+
+ l = fromLanguageTag("en-Latn-f-fo", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("Latn", l.getScript());
+ assertEquals("fo", l.getExtension('f'));
+
+ l = fromLanguageTag("en-f-fo", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getScript());
+ assertEquals("", l.getCountry());
+ assertEquals("fo", l.getExtension('f'));
+
+ l = fromLanguageTag("en-f-fo-x-a-b-c-d-e-fo", useBuilder);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getScript());
+ assertEquals("", l.getCountry());
+ assertEquals("fo", l.getExtension('f'));
+ assertEquals("a-b-c-d-e-fo", l.getExtension('x'));
+ }
+
+ public void test_forLanguageTag() {
+ test_setLanguageTag_wellFormedsingleSubtag(false);
+ test_setLanguageTag_twoWellFormedSubtags(false);
+ test_setLanguageTag_threeWellFormedSubtags(false);
+ test_setLanguageTag_fourOrMoreWellFormedSubtags(false);
+ test_setLanguageTag_withWellFormedExtensions(false);
+ }
+
+ public void test_Builder_setLanguageTag() {
+ test_setLanguageTag_wellFormedsingleSubtag(true);
+ test_setLanguageTag_twoWellFormedSubtags(true);
+ test_setLanguageTag_threeWellFormedSubtags(true);
+ test_setLanguageTag_fourOrMoreWellFormedSubtags(true);
+ test_setLanguageTag_withWellFormedExtensions(true);
+ }
+
+ public void test_getDisplayScript() {
+ Locale.Builder b = new Locale.Builder();
+ b.setLanguage("en").setRegion("US").setScript("Latn");
+
+ Locale l = b.build();
+
+ // getDisplayScript() test relies on the default locale. We set it here to avoid test
+ // failures if the test device is set to a non-English locale.
+ Locale.setDefault(Locale.US);
+ assertEquals("Latin", l.getDisplayScript());
+
+ assertEquals("Lateinisch", l.getDisplayScript(Locale.GERMAN));
+ // Fallback for navajo, a language for which we don't have data.
+ assertEquals("Latin", l.getDisplayScript(new Locale("nv", "US")));
+
+ b= new Locale.Builder();
+ b.setLanguage("en").setRegion("US").setScript("Fooo");
+
+ // Will be equivalent to getScriptCode for scripts that aren't
+ // registered with ISO-15429 (but are otherwise well formed).
+ l = b.build();
+ assertEquals("Fooo", l.getDisplayScript());
+ }
+
+ public void test_setLanguageTag_malformedTags() {
+ Locale l = fromLanguageTag("a", false);
+ assertEquals("und", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("", l.getVariant());
+ assertEquals("", l.getScript());
+
+ l = fromLanguageTag("en-US-BA", false);
+ assertEquals("en", l.getLanguage());
+ assertEquals("US", l.getCountry());
+ assertEquals("", l.getVariant());
+ assertEquals("", l.getScript());
+
+ l = fromLanguageTag("en-FOOOO-BA", false);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("FOOOO", l.getVariant());
+ assertEquals("", l.getScript());
+
+ l = fromLanguageTag("en-US-POSIX-P2", false);
+ assertEquals("en", l.getLanguage());
+ assertEquals("US", l.getCountry());
+ assertEquals("POSIX", l.getVariant());
+ assertEquals("", l.getScript());
+
+ l = fromLanguageTag("en-Latn-US-P2", false);
+ assertEquals("en", l.getLanguage());
+ assertEquals("US", l.getCountry());
+ assertEquals("Latn", l.getScript());
+
+ l = fromLanguageTag("en-f-f", false);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("", l.getVariant());
+ assertEquals("", l.getScript());
+
+ l = fromLanguageTag("en-f", false);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("", l.getVariant());
+ assertEquals("", l.getScript());
+
+ l = fromLanguageTag("en-f-fooobaaaz", false);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("", l.getVariant());
+ assertEquals("", l.getScript());
+
+ l = fromLanguageTag("en-9-baa", false);
+ assertEquals("en", l.getLanguage());
+ assertEquals("", l.getCountry());
+ assertEquals("", l.getVariant());
+ assertEquals("", l.getScript());
+ }
+
+ public void test_Builder_unicodeAttributes() {
+ // Adding and removing attributes
+ Locale.Builder b = new Locale.Builder();
+ b.setLanguage("en");
+
+ // Well formed attribute.
+ b.addUnicodeLocaleAttribute("foooo");
+
+ try {
+ b.addUnicodeLocaleAttribute("fo");
+ fail();
+ } catch (IllformedLocaleException ifle) {
+ }
+
+ try {
+ b.removeUnicodeLocaleAttribute("fo");
+ fail();
+ } catch (IllformedLocaleException ifle) {
+ }
+
+ try {
+ b.addUnicodeLocaleAttribute("greaterthaneightchars");
+ fail();
+ } catch (IllformedLocaleException ifle) {
+ }
+
+ try {
+ b.removeUnicodeLocaleAttribute("greaterthaneightchars");
+ fail();
+ } catch (IllformedLocaleException ifle) {
+ }
+
+ try {
+ b.addUnicodeLocaleAttribute(null);
+ fail();
+ } catch (NullPointerException npe) {
+ }
+
+ try {
+ b.removeUnicodeLocaleAttribute(null);
+ fail();
+ } catch (NullPointerException npe) {
+ }
+
+ Locale l = b.build();
+ assertEquals("en-u-foooo", l.toLanguageTag());
+ assertTrue(l.getUnicodeLocaleAttributes().contains("foooo"));
+
+ b.addUnicodeLocaleAttribute("dAtA");
+ l = b.build();
+ assertEquals("data-foooo", l.getExtension('u'));
+ assertTrue(l.getUnicodeLocaleAttributes().contains("data"));
+ assertTrue(l.getUnicodeLocaleAttributes().contains("foooo"));
+ }
+
+ public void test_Builder_unicodeKeywords() {
+ // Adding and removing attributes
+ Locale.Builder b = new Locale.Builder();
+ b.setLanguage("en");
+
+ // Key not of length 2.
+ try {
+ b.setUnicodeLocaleKeyword("k", "fooo");
+ fail();
+ } catch (IllformedLocaleException ifle) {
+ }
+
+ // Value too short
+ try {
+ b.setUnicodeLocaleKeyword("k", "fo");
+ fail();
+ } catch (IllformedLocaleException ifle) {
+ }
+
+ // Value too long
+ try {
+ b.setUnicodeLocaleKeyword("k", "foooooooo");
+ fail();
+ } catch (IllformedLocaleException ifle) {
+ }
+
+
+ // Null should clear the key.
+ b.setUnicodeLocaleKeyword("bo", "baaz");
+ Locale l = b.build();
+ assertEquals("bo-baaz", l.getExtension('u'));
+ assertEquals("baaz", l.getUnicodeLocaleType("bo"));
+
+ b = new Locale.Builder();
+ b.setUnicodeLocaleKeyword("bo", "baaz");
+ b.setUnicodeLocaleKeyword("bo", null);
+ l = b.build();
+ assertNull(l.getExtension('u'));
+ assertNull(l.getUnicodeLocaleType("bo"));
+
+ // When we set attributes, they should show up before extensions.
+ b = new Locale.Builder();
+ b.addUnicodeLocaleAttribute("fooo");
+ b.addUnicodeLocaleAttribute("gooo");
+ b.setUnicodeLocaleKeyword("fo", "baz");
+ b.setUnicodeLocaleKeyword("ka", "kaz");
+ l = b.build();
+ assertEquals("fooo-gooo-fo-baz-ka-kaz", l.getExtension('u'));
+ assertEquals("baz", l.getUnicodeLocaleType("fo"));
+ assertEquals("kaz", l.getUnicodeLocaleType("ka"));
+ assertTrue(l.getUnicodeLocaleAttributes().contains("fooo"));
+ assertTrue(l.getUnicodeLocaleAttributes().contains("gooo"));
+ }
+
+ public void test_multipleExtensions() {
+ Locale.Builder b = new Locale.Builder();
+ b.setLanguage("en");
+ b.addUnicodeLocaleAttribute("attrib");
+ b.addUnicodeLocaleAttribute("attrib2");
+ b.setExtension('f', "fo-baaz-ga-gaaz");
+ b.setExtension('x', "xo-baaz-ga-gaaz");
+ b.setExtension('z', "zo-baaz-ga-gaaz");
+
+ Locale l = b.build();
+ // Implicitly added because we added unicode locale attributes.
+ assertEquals("attrib-attrib2", l.getExtension('u'));
+ assertEquals("fo-baaz-ga-gaaz", l.getExtension('f'));
+ assertEquals("xo-baaz-ga-gaaz", l.getExtension('x'));
+ assertEquals("zo-baaz-ga-gaaz", l.getExtension('z'));
+ }
+
+ public void test_immutability() {
+ Locale.Builder b = new Locale.Builder();
+ b.setExtension('g', "fooo-baaz-baar");
+ b.setExtension('u', "foooo-baaar-ba-baaz-ka-kaaz");
+
+ Locale l = b.build();
+ try {
+ l.getExtensionKeys().add('g');
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ l.getUnicodeLocaleAttributes().add("fooo");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ public void test_toLanguageTag() {
+ Locale.Builder b = new Locale.Builder();
+
+ // Empty builder.
+ Locale l = b.build();
+ // TODO: Fix this. We should return "und" and not NULL.
+ // assertEquals("und", l.toLanguageTag());
+
+ // Only language.
+ b = new Locale.Builder();
+ b.setLanguage("en");
+ assertEquals("en", b.build().toLanguageTag());
+
+ // Language & Region
+ b = new Locale.Builder();
+ b.setLanguage("en").setRegion("US");
+ assertEquals("en-US", b.build().toLanguageTag());
+
+ // Language & Script
+ b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn");
+ assertEquals("en-Latn", b.build().toLanguageTag());
+
+ // Language & Variant
+ b = new Locale.Builder();
+ b.setLanguage("en").setVariant("foooo");
+ assertEquals("en-foooo", b.build().toLanguageTag());
+
+ // Language / script & country
+ b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn").setRegion("US");
+ assertEquals("en-Latn-US", b.build().toLanguageTag());
+
+ // Language / script & variant
+ b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn").setVariant("foooo");
+ assertEquals("en-Latn-foooo", b.build().toLanguageTag());
+
+ // Language / script / country / variant.
+ b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn").setVariant("foooo").setRegion("US");
+ assertEquals("en-Latn-US-foooo", b.build().toLanguageTag());
+
+ // Language / extension
+ b = new Locale.Builder();
+ b.setLanguage("en").setExtension('x', "fooo-baar");
+ assertEquals("en-x-fooo-baar", b.build().toLanguageTag());
+
+ // Language & multiple extensions (including unicode).
+ b = new Locale.Builder();
+ b.setLanguage("en");
+ b.addUnicodeLocaleAttribute("attrib");
+ b.addUnicodeLocaleAttribute("attrib2");
+ b.setExtension('f', "fo-baaz-ga-gaaz");
+ b.setExtension('x', "xo-baaz-ga-gaaz");
+ b.setExtension('z', "zo-baaz-ga-gaaz");
+
+ l = b.build();
+ // Implicitly added because we added unicode locale attributes.
+ assertEquals("attrib-attrib2", l.getExtension('u'));
+ assertEquals("fo-baaz-ga-gaaz", l.getExtension('f'));
+ assertEquals("xo-baaz-ga-gaaz", l.getExtension('x'));
+ assertEquals("zo-baaz-ga-gaaz", l.getExtension('z'));
+
+ assertEquals("en-" +
+ "f-fo-baaz-ga-gaaz-" + // extension tags in lexical order
+ "u-attrib-attrib2-z-zo-baaz-ga-gaaz-" + // unicode attribs & keywords in lex order
+ "x-xo-baaz-ga-gaaz", // private use extension unmodified.
+ l.toLanguageTag());
+ }
+
+ public void test_toString() {
+ Locale.Builder b = new Locale.Builder();
+
+ // Empty builder.
+ Locale l = b.build();
+ assertEquals("", l.toString());
+
+ // Only language.
+ b = new Locale.Builder();
+ b.setLanguage("en");
+ assertEquals("en", b.build().toString());
+
+ // Only region
+ b = new Locale.Builder();
+ b.setRegion("US");
+ assertEquals("_US", b.build().toString());
+
+ // Language & Region
+ b = new Locale.Builder();
+ b.setLanguage("en").setRegion("US");
+ assertEquals("en_US", b.build().toString());
+
+ // Language & Script
+ b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn");
+ assertEquals("en__#Latn", b.build().toString());
+
+ // Language & Variant
+ b = new Locale.Builder();
+ b.setLanguage("en").setVariant("foooo");
+ assertEquals("en__foooo", b.build().toString());
+
+ // Language / script & country
+ b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn").setRegion("US");
+ assertEquals("en_US_#Latn", b.build().toString());
+
+ // Language / script & variant
+ b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn").setVariant("foooo");
+ assertEquals("en__foooo_#Latn", b.build().toString());
+
+ // Language / script / country / variant.
+ b = new Locale.Builder();
+ b.setLanguage("en").setScript("Latn").setVariant("foooo").setRegion("US");
+ assertEquals("en_US_foooo_#Latn", b.build().toString());
+
+ // Language / extension
+ b = new Locale.Builder();
+ b.setLanguage("en").setExtension('x', "fooo-baar");
+ assertEquals("en__#x-fooo-baar", b.build().toString());
+ }
+
+ // Tests cases where our "guess" for the output size is incorrect.
+ //
+ // https://b.corp.google.com/issue?id=13414549
+ public void test_toLanguageTag_largerTag() {
+ Locale posix = new Locale.Builder()
+ .setLanguage("en").setRegion("US").setVariant("POSIX")
+ .build();
+ assertEquals("en-US-POSIX", posix.toLanguageTag());
+ }
+
+ public void test_forLanguageTag_grandFatheredLocale() {
+ // Regular grandfathered locale.
+ Locale gaulish = Locale.forLanguageTag("cel-gaulish");
+ assertEquals("xtg", gaulish.getLanguage());
+ assertEquals("cel-gaulish", gaulish.getExtension(Locale.PRIVATE_USE_EXTENSION));
+ assertEquals("", gaulish.getCountry());
+ assertEquals("", gaulish.getScript());
+ assertEquals("", gaulish.getVariant());
+
+ // Irregular grandfathered locale.
+ Locale enochian = Locale.forLanguageTag("i-enochian");
+ assertEquals("und", enochian.getLanguage());
+ assertEquals("i-enochian", enochian.getExtension(Locale.PRIVATE_USE_EXTENSION));
+ assertEquals("", enochian.getCountry());
+ assertEquals("", enochian.getScript());
+ assertEquals("", enochian.getVariant());
+ }
+
+ // Test case from http://b/16811867
+ public void testVariantsCaseSensitive() {
+ final Locale locale = new Locale("en", "US", "variant");
+ assertEquals("variant", locale.getVariant());
+ assertEquals(locale, Locale.forLanguageTag(locale.toLanguageTag()));
}
- }
+}
diff --git a/luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java b/luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java
index fa761d3..87f2f9d 100644
--- a/luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java
@@ -76,9 +76,16 @@ public class OldAndroidLocaleTest extends TestCase {
// This one makes sure we have all necessary locales installed.
public void testICULocales() {
- String[] locales = new String[] {
- // List of locales currently required for Android.
- "en_US", "es_US", "en_GB", "fr_FR", "de_DE", "de_AT", "cs_CZ", "nl_NL" };
+ // List of locales currently required for Android.
+ Locale[] locales = new Locale[] {
+ new Locale("en", "US"),
+ new Locale("es", "US"),
+ new Locale("en", "GB"),
+ new Locale("fr", "FR"),
+ new Locale("de", "DE"),
+ new Locale("de", "AT"),
+ new Locale("cs", "CZ"),
+ new Locale("nl", "NL") };
String[] mondays = new String[] {
"Monday", "lunes", "Monday", "lundi", "Montag", "Montag", "pond\u011bl\u00ed", "maandag" };
@@ -87,14 +94,12 @@ public class OldAndroidLocaleTest extends TestCase {
"USD", "USD", "GBP", "EUR", "EUR", "EUR", "CZK", "EUR"};
for (int i = 0; i < locales.length; i++) {
- Locale l = new Locale(locales[i].substring(0, 2), locales[i].substring(3));
+ final Locale l = locales[i];
- // Check language part of locale.
DateFormatSymbols d = new DateFormatSymbols(l);
assertEquals("Monday name for " + locales[i] + " must match",
mondays[i], d.getWeekdays()[2]);
- // Check country part of locale.
Currency c = Currency.getInstance(l);
assertEquals("Currency code for " + locales[i] + " must match",
currencies[i], c.getCurrencyCode());
diff --git a/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java b/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java
index 713e1b5..ecf2e5f 100644
--- a/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java
@@ -25,7 +25,7 @@ import junit.framework.TestCase;
public class OldTimeZoneTest extends TestCase {
- class Mock_TimeZone extends TimeZone {
+ static class Mock_TimeZone extends TimeZone {
@Override
public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {
return 0;
@@ -91,29 +91,50 @@ public class OldTimeZoneTest extends TestCase {
public void test_getDisplayNameLjava_util_Locale() {
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
- assertEquals("Pacific Standard Time", tz.getDisplayName(new Locale("US")));
- assertEquals("heure normale du Pacifique", tz.getDisplayName(Locale.FRANCE));
+ assertEquals("Pacific Standard Time", tz.getDisplayName(Locale.US));
+ assertEquals("heure normale du Pacifique nord-américain", tz.getDisplayName(Locale.FRANCE));
}
public void test_getDisplayNameZI() {
Locale.setDefault(Locale.US);
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
- assertEquals("PST", tz.getDisplayName(false, 0));
- assertEquals("Pacific Daylight Time", tz.getDisplayName(true, 1));
- assertEquals("Pacific Standard Time", tz.getDisplayName(false, 1));
+ assertEquals("PST", tz.getDisplayName(false, TimeZone.SHORT));
+ assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG));
+ assertEquals("Pacific Standard Time", tz.getDisplayName(false, TimeZone.LONG));
}
@AndroidOnly("fail on RI. See comment below")
public void test_getDisplayNameZILjava_util_Locale() {
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
- assertEquals("PST", tz.getDisplayName(false, 0, Locale.US));
- assertEquals("Pacific Daylight Time", tz.getDisplayName(true, 1, Locale.US));
- assertEquals("Pacific Standard Time", tz.getDisplayName(false, 1, Locale.UK));
- // RI always returns short time zone name as "PST"
- // ICU zone/root.txt patched to allow metazone names.
- assertEquals("PST", tz.getDisplayName(false, 0, Locale.FRANCE));
- assertEquals("heure avanc\u00e9e du Pacifique", tz.getDisplayName(true, 1, Locale.FRANCE));
- assertEquals("heure normale du Pacifique", tz.getDisplayName(false, 1, Locale.FRANCE));
+ assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, Locale.US));
+ assertEquals("Pacific Standard Time", tz.getDisplayName(false, TimeZone.LONG, Locale.UK));
+ assertEquals("heure avanc\u00e9e du Pacifique",
+ tz.getDisplayName(true, TimeZone.LONG, Locale.FRANCE));
+ assertEquals("heure normale du Pacifique nord-américain",
+ tz.getDisplayName(false, TimeZone.LONG, Locale.FRANCE));
+
+ assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT, Locale.US));
+ assertEquals("PST", tz.getDisplayName(false, TimeZone.SHORT, Locale.US));
+ // RI fails on following lines. RI always returns short time zone name for
+ // "America/Los_Angeles" as "PST", Android only returns a string if ICU has a translation.
+ // There is no short time zone name for America/Los_Angeles in French or British English in
+ // ICU data so an offset is returned instead.
+ assertEquals("GMT-08:00", tz.getDisplayName(false, TimeZone.SHORT, Locale.FRANCE));
+ assertEquals("GMT-07:00", tz.getDisplayName(true, TimeZone.SHORT, Locale.FRANCE));
+ assertEquals("GMT-08:00", tz.getDisplayName(false, TimeZone.SHORT, Locale.UK));
+ assertEquals("GMT-07:00", tz.getDisplayName(true, TimeZone.SHORT, Locale.UK));
+
+ // The RI behavior mentioned above does not appear to be because "PST" is a legacy
+ // three-character timezone supported by the RI: it happens for "Asia/Tehran"/"IRST" too
+ // (IRST is not a legacy code). The RI may just use a different dataset that has "PST" /
+ // "IRST" as valid translations (even for scripts like Chinese).
+ TimeZone iranTz = TimeZone.getTimeZone("Asia/Tehran");
+ assertEquals("Iran Summer Time", iranTz.getDisplayName(true, TimeZone.LONG, Locale.UK));
+ assertEquals("Iran Daylight Time", iranTz.getDisplayName(true, TimeZone.LONG, Locale.US));
+ assertEquals("Iran Standard Time", iranTz.getDisplayName(false, TimeZone.LONG, Locale.UK));
+ assertEquals("Iran Standard Time", iranTz.getDisplayName(false, TimeZone.LONG, Locale.US));
+ assertEquals("GMT+03:30", iranTz.getDisplayName(false, TimeZone.SHORT, Locale.UK));
+ assertEquals("GMT+04:30", iranTz.getDisplayName(true, TimeZone.SHORT, Locale.UK));
}
public void test_getID() {
diff --git a/luni/src/test/java/libcore/java/util/ResourceLeakageDetector.java b/luni/src/test/java/libcore/java/util/ResourceLeakageDetector.java
new file mode 100644
index 0000000..954665a
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/ResourceLeakageDetector.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.java.util;
+
+/**
+ * Detects resource leakages for resources that are protected by <code>CloseGuard</code> mechanism.
+ *
+ * <p>If multiple instances of this are active at the same time, i.e. have been created but not yet
+ * had their {@link #checkForLeaks()} method called then while they will report all the leakages
+ * detected they may report the leakages caused by the code being tested by another detector.
+ *
+ * <p>The underlying CloseGuardMonitor is loaded using reflection to ensure that this will run,
+ * albeit doing nothing, on the reference implementation.
+ */
+public class ResourceLeakageDetector {
+ /** The class for the CloseGuardMonitor, null if not supported. */
+ private static final Class<?> CLOSE_GUARD_MONITOR_CLASS;
+
+ static {
+ ClassLoader classLoader = ResourceLeakageDetector.class.getClassLoader();
+ Class<?> clazz;
+ try {
+ // Make sure that the CloseGuard class exists; this ensures that this is not running
+ // on a RI JVM.
+ classLoader.loadClass("dalvik.system.CloseGuard");
+
+ // Load the monitor class for later instantiation.
+ clazz = classLoader.loadClass("dalvik.system.CloseGuardMonitor");
+
+ } catch (ClassNotFoundException e) {
+ System.err.println("Resource leakage will not be detected; "
+ + "this is expected in the reference implementation");
+ e.printStackTrace(System.err);
+
+ // Ignore, probably running in reference implementation.
+ clazz = null;
+ }
+
+ CLOSE_GUARD_MONITOR_CLASS = clazz;
+ }
+
+ /**
+ * The underlying CloseGuardMonitor that will perform the post test checks for resource
+ * leakage.
+ */
+ private Runnable postTestChecker;
+
+ /**
+ * Create a new detector.
+ *
+ * @return The new {@link ResourceLeakageDetector}, its {@link #checkForLeaks()} method must be
+ * called otherwise it will not clean up properly after itself.
+ */
+ public static ResourceLeakageDetector newDetector()
+ throws Exception {
+ return new ResourceLeakageDetector();
+ }
+
+ private ResourceLeakageDetector()
+ throws Exception {
+ if (CLOSE_GUARD_MONITOR_CLASS != null) {
+ postTestChecker = (Runnable) CLOSE_GUARD_MONITOR_CLASS.newInstance();
+ }
+ }
+
+ /**
+ * Detect any leaks that have arisen since this was created.
+ *
+ * @throws Exception If any leaks were detected.
+ */
+ public void checkForLeaks() throws Exception {
+ // If available check for resource leakage.
+ if (postTestChecker != null) {
+ postTestChecker.run();
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/ResourceLeakageDetectorTest.java b/luni/src/test/java/libcore/java/util/ResourceLeakageDetectorTest.java
new file mode 100644
index 0000000..d86c9f2
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/ResourceLeakageDetectorTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.java.util;
+
+import dalvik.system.CloseGuard;
+import junit.framework.TestCase;
+
+/**
+ * Test for {@link ResourceLeakageDetector}
+ */
+public class ResourceLeakageDetectorTest extends TestCase {
+ /**
+ * This test will not work on RI as it does not support the <code>CloseGuard</code> or similar
+ * mechanism.
+ */
+ public void testDetectsUnclosedCloseGuard() throws Exception {
+ ResourceLeakageDetector detector = ResourceLeakageDetector.newDetector();
+ try {
+ CloseGuard closeGuard = createCloseGuard();
+ closeGuard.open("open");
+ } finally {
+ try {
+ System.logI("Checking for leaks");
+ detector.checkForLeaks();
+ fail();
+ } catch (AssertionError expected) {
+ }
+ }
+ }
+
+ public void testIgnoresClosedCloseGuard() throws Exception {
+ ResourceLeakageDetector detector = ResourceLeakageDetector.newDetector();
+ try {
+ CloseGuard closeGuard = createCloseGuard();
+ closeGuard.open("open");
+ closeGuard.close();
+ } finally {
+ detector.checkForLeaks();
+ }
+ }
+
+ /**
+ * Private method to ensure that the CloseGuard object is garbage collected.
+ */
+ private CloseGuard createCloseGuard() {
+ final CloseGuard closeGuard = CloseGuard.get();
+ new Object() {
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ closeGuard.warnIfOpen();
+ } finally {
+ super.finalize();
+ }
+ }
+ };
+
+ return closeGuard;
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index 08d1e69..0bc02b0 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -57,6 +57,7 @@ public class TimeZoneTest extends TestCase {
// http://code.google.com/p/android/issues/detail?id=14395
public void testPreHistoricInDaylightTime() throws Exception {
+ Locale.setDefault(Locale.US);
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
TimeZone.setDefault(tz);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
@@ -275,14 +276,6 @@ public class TimeZoneTest extends TestCase {
assertEquals("", failures.toString());
}
- public void testSantiago() throws Exception {
- TimeZone tz = TimeZone.getTimeZone("America/Santiago");
- assertEquals("Chile Summer Time", tz.getDisplayName(true, TimeZone.LONG, Locale.US));
- assertEquals("Chile Standard Time", tz.getDisplayName(false, TimeZone.LONG, Locale.US));
- assertEquals("GMT-03:00", tz.getDisplayName(true, TimeZone.SHORT, Locale.US));
- assertEquals("GMT-04:00", tz.getDisplayName(false, TimeZone.SHORT, Locale.US));
- }
-
// http://b/7955614
public void testApia() throws Exception {
TimeZone tz = TimeZone.getTimeZone("Pacific/Apia");
diff --git a/luni/src/test/java/libcore/java/util/UUIDTest.java b/luni/src/test/java/libcore/java/util/UUIDTest.java
new file mode 100644
index 0000000..61e4ae0
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/UUIDTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.java.util;
+
+import java.util.UUID;
+import junit.framework.TestCase;
+
+// There are more tests in the harmony suite:
+// harmony-tests/src/test/java/org/apache/harmony/tests/java/util/UUIDTest.java
+public class UUIDTest extends TestCase {
+
+ public void testFromStringInvalidValues() {
+ try {
+ UUID.fromString("+f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ UUID.fromString("f81d4fae-+7dec-11d0-a765-00a0c91e6bf6");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ UUID.fromString("f81d4fae-7dec-+11d0-a765-00a0c91e6bf6");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ UUID.fromString("f81d4fae-7dec-11d0-+a765-00a0c91e6bf6");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+
+ try {
+ UUID.fromString("f81d4fae-7dec-11d0-a765-+00a0c91e6bf6");
+ fail();
+ } catch (IllegalArgumentException expected) { }
+ }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java b/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java
deleted file mode 100644
index 021cd3f..0000000
--- a/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.util.jar;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import junit.framework.TestCase;
-import libcore.io.Streams;
-import static tests.support.Support_Exec.execAndGetOutput;
-import tests.support.resource.Support_Resources;
-
-
-public class DalvikExecTest extends TestCase {
-
- String execDalvik1(String classpath, String mainClass, String arg1)
- throws IOException, InterruptedException {
- ProcessBuilder builder = new ProcessBuilder();
-
- File dalvikvm = new File("/system/bin/dalvikvm");
- if (dalvikvm.exists()) {
- builder.command().add(dalvikvm.getPath());
- } else {
- builder.command().add("dalvikvm"); // for host mode, assume dalvikvm is on the path
- }
-
- builder.command().add("-Duser.language=en");
- builder.command().add("-Duser.region=US");
- builder.command().add("-Xbootclasspath:" + System.getProperty("java.boot.class.path"));
- builder.command().add("-classpath");
- builder.command().add(classpath);
- builder.command().add(mainClass);
-
- if (arg1 != null) {
- builder.command().add(arg1);
- }
-
- // Create a writable dalvik-cache under ANDROID_DATA.
- // The default dalvik-cache is only writable by the system user (and root).
- String tmp = System.getProperty("java.io.tmpdir");
- builder.environment().put("ANDROID_DATA", tmp);
- new File(tmp, "dalvik-cache").mkdir();
-
- return execAndGetOutput(builder);
- }
-
- String execDalvik (String classpath, String mainClass)
- throws IOException, InterruptedException {
- return execDalvik1(classpath, mainClass, null);
- }
-
- // Execute an existing JAR on dalvikvm using -classpath option.",
- public void test_execExistingJar () throws IOException, InterruptedException {
- String res;
- File jarFile;
- if (System.getProperty("java.vendor").contains("Android")) {
- //
- // Test against Android:
- //
- File tempDir = Support_Resources.createTempFolder();
- jarFile = Support_Resources.copyFile(
- tempDir, null, "cts_dalvikExecTest.jar" );
- res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.HelloWorld");
- assertEquals("Hello Android World!", "Hello Android World!\n", res);
-
- res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.ResourceDumper");
- assertTrue("Android Resource Dumper started",
- res.contains("Android Resource Dumper started"));
- assertTrue("This Resource contains some text.",
- res.contains("This Resource contains some text."));
- } else {
- //
- // Test against RI:
- //
- // Do nothing!
- }
- }
-
- // Create a temp file, fill it with contents according to Dalvik JAR format, and execute it on dalvikvm using -classpath option.",
- public void test_execCreatedJar () throws IOException, InterruptedException {
- File jarFile = File.createTempFile("cts_dalvikExecTest_", ".jar");
- jarFile.deleteOnExit();
-
- // Create a JAR output stream on the temp file:
- JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(jarFile));
-
- // Define the entry for the classes.dex:
- jarOut.putNextEntry(new JarEntry("classes.dex"));
-
- // Fill in the classes.dex contents, i.e. the Dalvik executable code:
- // (See below for the detailed source code contents.)
- Streams.copy(Support_Resources.getResourceStream("cts_dalvikExecTest_classes.dex"), jarOut);
-
- // Now add a resource file:
- //
- jarOut.putNextEntry(new JarEntry("dalvikExecTest/myResource"));
- jarOut.write("This Resource contains some text.".getBytes());
-
- // Close the stream to the completed JAR file.
- jarOut.close();
-
- // The resulting JAR file contains the classes listed at the end of this text,
- // like the 'cts_dalvikExecTest.jar' as part of the resources, too.
-
- String res;
-
- res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.HelloWorld");
- assertEquals("Hello Android World!", "Hello Android World!\n", res);
-
- res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.ResourceDumper");
- assertTrue("Android Resource Dumper started",
- res.contains("Android Resource Dumper started"));
- assertTrue("This Resource contains some text.",
- res.contains("This Resource contains some text."));
- }
-
-
- /**
- * This test does quite the same as test_execCreatedJar, but includes a manifest.
- * Note however that the Dalvik JAR format does not require this manifest.
- * We just test whether the manifest is placed correctly within the JAR by
- * dumping its contents read as a simple text resource.
- * No! We can't do that so easily either, as there are other (parent) JARs
- * with a manifest inside, taken with precedence.
- * So we will reopen the JAR as a JarFile and check the manifest
- * with a top level end-to-end approach.
- */
- public void test_execCreatedJarWithManifest () throws IOException, InterruptedException {
- File jarFile = File.createTempFile("cts_dalvikExecTest_", ".jar");
- jarFile.deleteOnExit();
-
- // Create the manifest:
- Manifest manifest = new Manifest();
- Attributes attrs = manifest.getMainAttributes();
- attrs.put(Attributes.Name.MANIFEST_VERSION, "3.1415962");
- attrs.put(Attributes.Name.MAIN_CLASS, "dalvikExecTest.HelloWorld");
- attrs.put(Attributes.Name.CLASS_PATH, jarFile.getName());
-
- // Create a JAR output stream on the temp file using the manifest:
- JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(jarFile), manifest);
-
- // Define the entry for the classes.dex:
- jarOut.putNextEntry(new JarEntry("classes.dex"));
-
- // Fill in the classes.dex contents, i.e. the Dalvik executable code:
- // (See below for the detailed source code contents.)
- Streams.copy(Support_Resources.getResourceStream("cts_dalvikExecTest_classes.dex"), jarOut);
-
- // Now add a resource file:
- //
- jarOut.putNextEntry(new JarEntry("dalvikExecTest/myResource"));
- jarOut.write("This Resource contains some text.".getBytes());
-
- // Close the stream to the completed JAR file.
- jarOut.close();
-
- // The resulting JAR file contains the classes listed at the end of this text,
- // like the 'cts_dalvikExecTest.jar' as part of the resources, too.
-
- String res;
-
- res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.HelloWorld");
- assertEquals("Hello Android World!", "Hello Android World!\n", res);
-
- res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.ResourceDumper");
- assertTrue("Android Resource Dumper started",
- res.contains("Android Resource Dumper started"));
- assertTrue("This Resource contains some text.",
- res.contains("This Resource contains some text."));
-
- // And now reread the manifest:
- //
- JarFile jarIn = new JarFile(jarFile);
- manifest = jarIn.getManifest();
- attrs = manifest.getMainAttributes();
- assertEquals("MANIFEST_VERSION must match!", "3.1415962",
- attrs.get(Attributes.Name.MANIFEST_VERSION));
- assertEquals("MAIN_CLASS must match!", "dalvikExecTest.HelloWorld",
- attrs.get(Attributes.Name.MAIN_CLASS));
- assertEquals("CLASS_PATH must match!", jarFile.getName(),
- attrs.get(Attributes.Name.CLASS_PATH));
- }
-
-
- /*
- * The following two classes are added, here, only for completeness.
- * They form the contents of the dalvikExecTest package contained
- * in the 'cts_dalvikExecTest_classes.dex' resource file.
- */
- /**
- * @hide
- */
- public static class HelloWorld {
-
- public static void main(String[] args) {
- System.out.println("Hello Android World!");
- }
-
- }
-
- public static class ResourceDumper {
-
- static ByteArrayOutputStream outputFrom (InputStream input) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] buffer = new byte[512];
- int total = 0;
- int count;
- count = input.read(buffer);
- while (count != -1) {
- out.write(buffer, 0, count);
- total = total + count;
- count = input.read(buffer);
- }
- return out;
- }
-
- public static void main(String[] args) throws IOException {
- System.out.print("Android Resource Dumper started ");
- String fileName;
- if (args.length >= 1) {
- fileName = args[0];
- System.out.format("for argument '%s'.\n", fileName);
- } else {
- System.out.print("standard ");
- fileName = "myResource";
- System.out.println("for standard 'myResource'.");
- }
- InputStream is = ResourceDumper.class.getResourceAsStream(fileName);
- if (is != null) {
- System.out.println("Resource obtained and being dumped:");
- System.out.println(outputFrom(is).toString());
- }
- }
-
- }
-
-}
diff --git a/luni/src/test/java/libcore/java/util/jar/StrictJarFileTest.java b/luni/src/test/java/libcore/java/util/jar/StrictJarFileTest.java
new file mode 100644
index 0000000..e5a6cd8
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/jar/StrictJarFileTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package libcore.java.util.jar;
+
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.jar.StrictJarFile;
+import java.util.zip.ZipEntry;
+import libcore.io.Streams;
+
+public class StrictJarFileTest extends TestCase {
+
+ // A well formed jar file with 6 entries.
+ private static final String JAR_1 = "hyts_patch.jar";
+
+ private File resources;
+
+ @Override
+ protected void setUp() {
+ resources = Support_Resources.createTempFolder();
+ }
+
+ public void testConstructor() throws Exception {
+ try {
+ StrictJarFile jarFile = new StrictJarFile("Wrong.file");
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ Support_Resources.copyFile(resources, null, JAR_1);
+ String fileName = (new File(resources, JAR_1)).getCanonicalPath();
+ StrictJarFile jarFile = new StrictJarFile(fileName);
+ jarFile.close();
+ }
+
+ public void testIteration() throws Exception {
+ Support_Resources.copyFile(resources, null, JAR_1);
+ StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+ Iterator<ZipEntry> it = jarFile.iterator();
+ HashMap<String, ZipEntry> entries = new HashMap<String, ZipEntry>();
+ while (it.hasNext()) {
+ final ZipEntry ze = it.next();
+ entries.put(ze.getName(), ze);
+ }
+
+ assertEquals(6, entries.size());
+ assertTrue(entries.containsKey("META-INF/"));
+
+ assertTrue(entries.containsKey("META-INF/MANIFEST.MF"));
+ ZipEntry ze = entries.get("META-INF/MANIFEST.MF");
+ assertEquals(62, ze.getSize());
+ assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+ assertEquals(61, ze.getCompressedSize());
+
+ assertTrue(entries.containsKey("Blah.txt"));
+ ze = entries.get("Blah.txt");
+ assertEquals(4, ze.getSize());
+ assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+ assertEquals(6, ze.getCompressedSize());
+ assertEquals("Blah", new String(Streams.readFully(jarFile.getInputStream(ze)),
+ Charset.forName("UTF-8")));
+
+ assertTrue(entries.containsKey("foo/"));
+ assertTrue(entries.containsKey("foo/bar/"));
+ assertTrue(entries.containsKey("foo/bar/A.class"));
+ ze = entries.get("foo/bar/A.class");
+ assertEquals(311, ze.getSize());
+ assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+ assertEquals(225, ze.getCompressedSize());
+ }
+
+ public void testFindEntry() throws Exception {
+ Support_Resources.copyFile(resources, null, JAR_1);
+ StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+ assertNull(jarFile.findEntry("foobar"));
+ assertNull(jarFile.findEntry("blah.txt"));
+ assertNotNull(jarFile.findEntry("Blah.txt"));
+ final ZipEntry ze = jarFile.findEntry("Blah.txt");
+ assertEquals(4, ze.getSize());
+ assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+ assertEquals(6, ze.getCompressedSize());
+ assertEquals("Blah", new String(Streams.readFully(jarFile.getInputStream(ze)),
+ Charset.forName("UTF-8")));
+ }
+
+ public void testGetManifest() throws Exception {
+ Support_Resources.copyFile(resources, null, JAR_1);
+ StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+ assertNotNull(jarFile.getManifest());
+ assertEquals("1.4.2 (IBM Corporation)", jarFile.getManifest().getMainAttributes().getValue("Created-By"));
+ }
+
+ public void testJarSigning_wellFormed() throws IOException {
+ Support_Resources.copyFile(resources, null, "Integrate.jar");
+ StrictJarFile jarFile = new StrictJarFile(new File(resources, "Integrate.jar").getAbsolutePath());
+ Iterator<ZipEntry> entries = jarFile.iterator();
+ while (entries.hasNext()) {
+ ZipEntry zipEntry = entries.next();
+ jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
+ if ("Test.class".equals(zipEntry.getName())) {
+ assertNotNull(jarFile.getCertificates(zipEntry));
+ assertNotNull(jarFile.getCertificateChains(zipEntry));
+ }
+ }
+ }
+
+ public void testJarSigning_fudgedEntry() throws IOException {
+ Support_Resources.copyFile(resources, null, "Integrate.jar");
+ StrictJarFile jarFile = new StrictJarFile(
+ new File(resources, "Integrate.jar").getAbsolutePath());
+
+ ZipEntry ze = jarFile.findEntry("Test.class");
+ jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+
+ // Fudge the size so that certificates do not match.
+ ze.setSize(ze.getSize() - 1);
+ try {
+ jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+ fail();
+ } catch (SecurityException expected) {
+ }
+ }
+
+ public void testJarSigning_modifiedClass() throws IOException {
+ Support_Resources.copyFile(resources, null, "Modified_Class.jar");
+ StrictJarFile jarFile = new StrictJarFile(
+ new File(resources, "Modified_Class.jar").getAbsolutePath());
+
+ ZipEntry ze = jarFile.findEntry("Test.class");
+ try {
+ jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+ fail();
+ } catch (SecurityException expected) {
+ }
+ }
+
+ public void testJarSigning_brokenMainAttributes() throws Exception {
+ assertThrowsOnInit("Modified_Manifest_MainAttributes.jar");
+ }
+
+ public void testJarSigning_brokenEntryAttributes() throws Exception {
+ assertThrowsOnInit("Modified_Manifest_EntryAttributes.jar");
+ }
+
+ public void testJarSigning_brokenSignatureFile() throws Exception {
+ assertThrowsOnInit("Modified_SF_EntryAttributes.jar");
+ }
+
+ private void assertThrowsOnInit(String name) throws Exception {
+ Support_Resources.copyFile(resources, null, name);
+ try {
+ StrictJarFile jarFile = new StrictJarFile(
+ new File(resources, name).getAbsolutePath());
+ fail();
+ } catch (SecurityException expected) {
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldAbstractPreferencesTest.java b/luni/src/test/java/libcore/java/util/prefs/OldAbstractPreferencesTest.java
index b9d3f1d..693f0c2 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldAbstractPreferencesTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldAbstractPreferencesTest.java
@@ -18,6 +18,7 @@ package libcore.java.util.prefs;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;
@@ -27,12 +28,17 @@ import java.util.prefs.NodeChangeListener;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+
import junit.framework.TestCase;
+import libcore.io.IoUtils;
public final class OldAbstractPreferencesTest extends TestCase {
static final String nodeName = "mock";
+ private PreferencesFactory defaultFactory;
+
AbstractPreferences pref;
AbstractPreferences root;
AbstractPreferences parent = null;
@@ -40,16 +46,24 @@ public final class OldAbstractPreferencesTest extends TestCase {
protected void setUp() throws Exception {
super.setUp();
+ File tmpDir = IoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
+ defaultFactory = Preferences.setPreferencesFactory(
+ new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
+
root = (AbstractPreferences) Preferences.userRoot();
- for (String child : root.childrenNames()) {
- root.node(child).removeNode();
- }
- root.clear();
+ assertEquals(0, root.childrenNames().length);
+ assertEquals(0, root.keys().length);
parent = (AbstractPreferences) Preferences.userNodeForPackage(getClass());
pref = (AbstractPreferences) parent.node(nodeName);
}
+ @Override
+ public void tearDown() throws Exception {
+ Preferences.setPreferencesFactory(defaultFactory);
+ super.tearDown();
+ }
+
public void testToString() {
assertTrue(pref.toString().contains(nodeName));
}
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java b/luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java
index 93ba485..ea8cb39 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java
@@ -16,11 +16,32 @@
package libcore.java.util.prefs;
+import java.io.File;
import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+
import junit.framework.TestCase;
+import libcore.io.IoUtils;
+
public final class OldFilePreferencesImplTest extends TestCase {
+ private PreferencesFactory defaultFactory;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ File tmpDir = IoUtils.createTemporaryDirectory("OldFilePreferencesImplTest");
+ defaultFactory = Preferences.setPreferencesFactory(
+ new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ Preferences.setPreferencesFactory(defaultFactory);
+ super.tearDown();
+ }
+
// AndroidOnly: the RI can't remove nodes created in the system root.
public void testSystemChildNodes() throws Exception {
Preferences sroot = Preferences.systemRoot().node("test");
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java b/luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java
index f2d483e..7ba1dfe 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java
@@ -16,15 +16,36 @@
package libcore.java.util.prefs;
+import java.io.File;
import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;
import java.util.prefs.NodeChangeEvent;
import java.util.prefs.NodeChangeListener;
import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+
import junit.framework.TestCase;
+import libcore.io.IoUtils;
+
public final class OldNodeChangeEventTest extends TestCase {
+ private PreferencesFactory defaultFactory;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ File tmpDir = IoUtils.createTemporaryDirectory("OldNodeChangeEventTest");
+ defaultFactory = Preferences.setPreferencesFactory(
+ new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ Preferences.setPreferencesFactory(defaultFactory);
+ super.tearDown();
+ }
+
public void testGetChild() throws BackingStoreException {
AbstractPreferences parent = (AbstractPreferences) Preferences
.userNodeForPackage(Preferences.class);
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java b/luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java
index acdbd69..d77a11c 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java
@@ -16,14 +16,35 @@
package libcore.java.util.prefs;
+import java.io.File;
import java.util.prefs.AbstractPreferences;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
+
import junit.framework.TestCase;
+import libcore.io.IoUtils;
+
public final class OldPreferenceChangeEventTest extends TestCase {
+ private PreferencesFactory defaultFactory;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ File tmpDir = IoUtils.createTemporaryDirectory("OldPreferenceChangeEventTest");
+ defaultFactory = Preferences.setPreferencesFactory(
+ new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ Preferences.setPreferencesFactory(defaultFactory);
+ super.tearDown();
+ }
+
public void testGetKey() {
AbstractPreferences parent = (AbstractPreferences) Preferences
.userNodeForPackage(Preferences.class);
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java b/luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java
index f8a8154..7245af7 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java
@@ -16,6 +16,7 @@
package libcore.java.util.prefs;
+import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
@@ -25,7 +26,9 @@ import java.util.prefs.NodeChangeListener;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
import junit.framework.TestCase;
+import libcore.io.IoUtils;
public final class OldPreferencesTest extends TestCase {
@@ -48,8 +51,14 @@ public final class OldPreferencesTest extends TestCase {
longValue = value.toString();
}
- @Override protected void setUp() throws Exception {
+ private PreferencesFactory defaultFactory;
+
+ @Override
+ protected void setUp() throws Exception {
super.setUp();
+ final File tmpDir = IoUtils.createTemporaryDirectory("OldPreferenceTest");
+ defaultFactory = Preferences.setPreferencesFactory(
+ new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
Preferences pref = Preferences.userNodeForPackage(Preferences.class);
for (String child : pref.childrenNames()) {
@@ -58,6 +67,11 @@ public final class OldPreferencesTest extends TestCase {
pref.clear();
}
+ @Override
+ protected void tearDown() throws Exception {
+ Preferences.setPreferencesFactory(defaultFactory);
+ }
+
public void testAbstractMethods() throws IOException, BackingStoreException {
Preferences p = new MockPreferences();
p.absolutePath();
diff --git a/luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java b/luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java
index 1560fbe..6c57ef9 100644
--- a/luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java
@@ -19,17 +19,58 @@ package libcore.java.util.prefs;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
+import java.util.prefs.FilePreferencesImpl;
import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
import junit.framework.TestCase;
+import libcore.io.IoUtils;
public final class PreferencesTest extends TestCase {
/**
+ * A preferences factory rooted at a given path.
+ */
+ public static final class TestPreferencesFactory implements PreferencesFactory {
+ private final Preferences userPrefs;
+ private final Preferences systemPrefs;
+
+ public TestPreferencesFactory(String root) {
+ userPrefs = new FilePreferencesImpl(root + "/user", true);
+ systemPrefs = new FilePreferencesImpl(root + "/system", false);
+ }
+
+ public Preferences userRoot() {
+ return userPrefs;
+ }
+
+ public Preferences systemRoot() {
+ return systemPrefs;
+ }
+ }
+
+ private PreferencesFactory defaultFactory;
+ private File temporaryDirectory;
+
+ @Override
+ public void setUp() throws Exception {
+ temporaryDirectory = IoUtils.createTemporaryDirectory("PreferencesTest");
+ defaultFactory = Preferences.setPreferencesFactory(
+ new TestPreferencesFactory(temporaryDirectory.getAbsolutePath()));
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ Preferences.setPreferencesFactory(defaultFactory);
+ }
+
+ /**
* The preferences API is designed to be hostile towards files that exist
* where it wants to store its XML data. http://b/3431233
*/
public void testPreferencesClobbersExistingFiles() throws Exception {
- File userPrefs = new File(System.getProperty("user.home") + "/.java/.userPrefs/prefs.xml");
+ final File userPrefsDir = new File(temporaryDirectory + "/user");
+ final File userPrefs = new File(userPrefsDir, "prefs.xml");
+ assertTrue(userPrefs.createNewFile());
FileWriter writer = new FileWriter(userPrefs);
writer.write("lamb");
writer.close();
diff --git a/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
index a28fae5..494520a 100644
--- a/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
@@ -18,22 +18,29 @@ package libcore.java.util.zip;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import junit.framework.TestCase;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
public final class GZIPInputStreamTest extends TestCase {
+
+ private static final byte[] HELLO_WORLD_GZIPPED = new byte[] {
+ 31, -117, 8, 0, 0, 0, 0, 0, 0, 0, -13, 72, -51, -55, -55, 87, 8, -49,
+ 47, -54, 73, 1, 0, 86, -79, 23, 74, 11, 0, 0, 0
+ };
+
public void testShortMessage() throws IOException {
- byte[] data = new byte[] {
- 31, -117, 8, 0, 0, 0, 0, 0, 0, 0, -13, 72, -51, -55, -55, 87, 8, -49,
- 47, -54, 73, 1, 0, 86, -79, 23, 74, 11, 0, 0, 0
- };
- assertEquals("Hello World", new String(gunzip(data), "UTF-8"));
+ assertEquals("Hello World", new String(gunzip(HELLO_WORLD_GZIPPED), "UTF-8"));
}
public void testLongMessage() throws IOException {
@@ -59,15 +66,114 @@ public final class GZIPInputStreamTest extends TestCase {
in.close();
}
+ // https://code.google.com/p/android/issues/detail?id=63873
+ public void testMultipleMembers() throws Exception {
+ final int length = HELLO_WORLD_GZIPPED.length;
+ byte[] data = new byte[length * 2];
+ System.arraycopy(HELLO_WORLD_GZIPPED, 0, data, 0, length);
+ System.arraycopy(HELLO_WORLD_GZIPPED, 0, data, length, length);
+
+ assertEquals("Hello WorldHello World", new String(gunzip(data), "UTF-8"));
+ }
+
+ // https://code.google.com/p/android/issues/detail?id=63873
+ public void testTrailingNonGzipData() throws Exception {
+ final int length = HELLO_WORLD_GZIPPED.length;
+ // 50 bytes of 0s at the end of the first message.
+ byte[] data = new byte[length + 50];
+ System.arraycopy(HELLO_WORLD_GZIPPED, 0, data, 0, length);
+ assertEquals("Hello World", new String(gunzip(data), "UTF-8"));
+ }
+
+ // https://code.google.com/p/android/issues/detail?id=63873
+ //
+ // Differences from the RI: Tests show the RI ignores *some* types of partial
+ // data but not others and this test case fails as a result. Our implementation
+ // will throw if it sees the gzip magic sequence at the end of a member
+ // but malformed / invalid data after.
+ public void testTrailingHeaderAndPartialMember() throws Exception {
+ final int length = HELLO_WORLD_GZIPPED.length;
+ // Copy just the header from HELLO_WORLD_GZIPPED so that our input
+ // stream becomes one complete member + a header member.
+ byte[] data = new byte[length + 10];
+ System.arraycopy(HELLO_WORLD_GZIPPED, 0, data, 0, length);
+ System.arraycopy(HELLO_WORLD_GZIPPED, 0, data, length, 10);
+
+ try {
+ gunzip(data);
+ fail();
+ } catch (EOFException expected) {
+ }
+
+ // Copy just the header from HELLO_WORLD_GZIPPED so that our input
+ // stream becomes one complete member + a header member.
+ data = new byte[length + 18];
+ System.arraycopy(HELLO_WORLD_GZIPPED, 0, data, 0, length);
+ System.arraycopy(HELLO_WORLD_GZIPPED, 0, data, length, 18);
+
+ try {
+ gunzip(data);
+ fail();
+ } catch (EOFException expected) {
+ }
+ }
+
+ // https://code.google.com/p/android/issues/detail?id=66409
+ public void testMultipleMembersWithCustomBufferSize() throws Exception {
+ final int[] memberSizes = new int[] { 1000, 2000 };
+
+ // We don't care what the exact contents of this file is, as long
+ // as the file has multiple members, and that the (compressed) size of
+ // the second member is larger than the size of the input buffer.
+ //
+ // There's no way to achieve this for a GZIPOutputStream so we generate
+ // pseudo-random sequence of bytes and assert that they don't compress
+ // well.
+ final Random r = new Random(10);
+ byte[] bytes = new byte[3000];
+ r.nextBytes(bytes);
+
+ File f = File.createTempFile("GZIPInputStreamTest", ".gzip");
+ int offset = 0;
+ for (int size : memberSizes) {
+ GZIPOutputStream gzos = null;
+ try {
+ FileOutputStream fos = new FileOutputStream(f, true /* append */);
+ gzos = new GZIPOutputStream(fos, size + 1);
+ gzos.write(bytes, offset, size);
+ offset += size;
+ gzos.finish();
+ } finally {
+ IoUtils.closeQuietly(gzos);
+ }
+ }
+
+ assertTrue(f.length() > 2048);
+
+ FileInputStream fis = new FileInputStream(f);
+ GZIPInputStream gzip = null;
+ try {
+ gzip = new GZIPInputStream(fis, memberSizes[0]);
+ byte[] unzipped = Streams.readFully(gzip);
+ assertTrue(Arrays.equals(bytes, unzipped));
+ } finally {
+ IoUtils.closeQuietly(gzip);
+ }
+ }
+
public static byte[] gunzip(byte[] bytes) throws IOException {
- InputStream in = new GZIPInputStream(new ByteArrayInputStream(bytes));
+ ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+ InputStream in = new GZIPInputStream(bis);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
while ((count = in.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
+
+ byte[] outArray = out.toByteArray();
in.close();
- return out.toByteArray();
+
+ return outArray;
}
}
diff --git a/luni/src/test/java/libcore/java/util/zip/GZIPOutputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/GZIPOutputStreamTest.java
index 55e45bc..3b785c9 100644
--- a/luni/src/test/java/libcore/java/util/zip/GZIPOutputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/GZIPOutputStreamTest.java
@@ -16,17 +16,14 @@
package libcore.java.util.zip;
-import java.io.ByteArrayInputStream;
+import junit.framework.TestCase;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
-import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
-import java.util.zip.InflaterInputStream;
-import junit.framework.TestCase;
public final class GZIPOutputStreamTest extends TestCase {
public void testShortMessage() throws IOException {
@@ -67,4 +64,15 @@ public final class GZIPOutputStreamTest extends TestCase {
in.close();
}
+ // https://code.google.com/p/android/issues/detail?id=62589
+ public void testFlushAfterFinish() throws Exception {
+ byte[] responseBytes = "Some data to gzip".getBytes();
+ ByteArrayOutputStream output = new ByteArrayOutputStream(responseBytes.length);
+ GZIPOutputStream gzipOutputStream = new GZIPOutputStream(output, true);
+ gzipOutputStream.write(responseBytes);
+ gzipOutputStream.finish();
+ // Calling flush() after finish() shouldn't throw.
+ gzipOutputStream.flush();
+ gzipOutputStream.close();
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/zip/OldZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/OldZipFileTest.java
index 9f2864b..2104655 100644
--- a/luni/src/test/java/libcore/java/util/zip/OldZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/OldZipFileTest.java
@@ -17,21 +17,14 @@
package libcore.java.util.zip;
-import tests.support.Support_PlatformFile;
-import tests.support.resource.Support_Resources;
-
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
-import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.Permission;
-import java.util.Enumeration;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
import java.util.zip.ZipFile;
+import tests.support.resource.Support_Resources;
public class OldZipFileTest extends junit.framework.TestCase {
@@ -150,24 +143,15 @@ public class OldZipFileTest extends junit.framework.TestCase {
@Override
protected void setUp() throws IOException {
// Create a local copy of the file since some tests want to alter information.
- tempFileName = System.getProperty("java.io.tmpdir");
- String separator = System.getProperty("file.separator");
- if (tempFileName.charAt(tempFileName.length() - 1) == separator.charAt(0)) {
- tempFileName = Support_PlatformFile.getNewPlatformFile(tempFileName, "gabba.zip");
- } else {
- tempFileName = Support_PlatformFile.getNewPlatformFile(
- tempFileName + separator, "gabba.zip");
- }
-
- File f = new File(tempFileName);
- f.delete();
+ File tempFile = File.createTempFile("OldZipFileTest", "zip");
+ tempFileName = tempFile.getAbsolutePath();
InputStream is = Support_Resources.getStream("hyts_ZipFile.zip");
- FileOutputStream fos = new FileOutputStream(f);
+ FileOutputStream fos = new FileOutputStream(tempFile);
byte[] rbuf = getAllBytesFromStream(is);
fos.write(rbuf, 0, rbuf.length);
is.close();
fos.close();
- zfile = new ZipFile(f);
+ zfile = new ZipFile(tempFile);
}
/**
@@ -179,18 +163,5 @@ public class OldZipFileTest extends junit.framework.TestCase {
// Note zfile is a user-defined zip file used by other tests and
// should not be deleted
zfile.close();
- tempFileName = System.getProperty("java.io.tmpdir");
- String separator = System.getProperty("file.separator");
- if (tempFileName.charAt(tempFileName.length() - 1) == separator
- .charAt(0)) {
- tempFileName = Support_PlatformFile.getNewPlatformFile(
- tempFileName, "gabba.zip");
- } else {
- tempFileName = Support_PlatformFile.getNewPlatformFile(
- tempFileName + separator, "gabba.zip");
- }
-
- File f = new File(tempFileName);
- f.delete();
}
}
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
index 60af4d0..a9ff56f 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
@@ -21,11 +21,17 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
import java.util.Random;
+import java.util.Set;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
@@ -34,6 +40,8 @@ import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
public final class ZipFileTest extends TestCase {
/**
* Exercise Inflater's ability to refill the zlib's input buffer. As of this
@@ -160,7 +168,7 @@ public final class ZipFileTest extends TestCase {
}
assertEquals(expectedLength, count);
-
+ zip.close();
}
public void testInflatingStreamsRequiringZipRefill() throws IOException {
@@ -218,21 +226,23 @@ public final class ZipFileTest extends TestCase {
byte[] writeBuffer = new byte[8192];
Random random = new Random();
- ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(result)));
- for (int entry = 0; entry < entryCount; ++entry) {
- ZipEntry ze = new ZipEntry(Integer.toHexString(entry));
- out.putNextEntry(ze);
+ ZipOutputStream out = createZipOutputStream(result);
+ try {
+ for (int entry = 0; entry < entryCount; ++entry) {
+ ZipEntry ze = new ZipEntry(Integer.toHexString(entry));
+ out.putNextEntry(ze);
+
+ for (int i = 0; i < entrySize; i += writeBuffer.length) {
+ random.nextBytes(writeBuffer);
+ int byteCount = Math.min(writeBuffer.length, entrySize - i);
+ out.write(writeBuffer, 0, byteCount);
+ }
- for (int i = 0; i < entrySize; i += writeBuffer.length) {
- random.nextBytes(writeBuffer);
- int byteCount = Math.min(writeBuffer.length, entrySize - i);
- out.write(writeBuffer, 0, byteCount);
+ out.closeEntry();
}
-
- out.closeEntry();
+ } finally {
+ out.close();
}
-
- out.close();
return result;
}
@@ -468,4 +478,30 @@ public final class ZipFileTest extends TestCase {
out.closeEntry();
out.close();
}
+
+ /**
+ * RI does not allow reading of an empty zip using a {@link ZipFile}.
+ */
+ public void testConstructorFailsWhenReadingEmptyZipArchive() throws IOException {
+
+ File resources = Support_Resources.createTempFolder();
+ File emptyZip = Support_Resources.copyFile(
+ resources, "java/util/zip", "EmptyArchive.zip");
+
+ try {
+ // The following should fail with an exception but if it doesn't then we need to clean
+ // up the resource so we need a reference to it.
+ ZipFile zipFile = new ZipFile(emptyZip);
+
+ // Clean up the resource.
+ try {
+ zipFile.close();
+ } catch (Exception e) {
+ // Ignore
+ }
+ fail();
+ } catch (ZipException expected) {
+ // expected
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
index cb98322..49990a3 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
@@ -20,15 +20,24 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
import java.util.Random;
+import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
+
import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
public final class ZipInputStreamTest extends TestCase {
+
public void testShortMessage() throws IOException {
byte[] data = "Hello World".getBytes("UTF-8");
byte[] zipped = ZipOutputStreamTest.zip("short", data);
@@ -59,4 +68,18 @@ public final class ZipInputStreamTest extends TestCase {
in.close();
return out.toByteArray();
}
+
+ /**
+ * Reference implementation allows reading of empty zip using a {@link ZipInputStream}.
+ */
+ public void testReadEmpty() throws IOException {
+ InputStream emptyZipIn = Support_Resources.getStream("java/util/zip/EmptyArchive.zip");
+ ZipInputStream in = new ZipInputStream(emptyZipIn);
+ try {
+ ZipEntry entry = in.getNextEntry();
+ assertNull("An empty zip has no entries", entry);
+ } finally {
+ in.close();
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
index e7c518f..e69f010 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
@@ -16,15 +16,16 @@
package libcore.java.util.zip;
-import java.io.ByteArrayInputStream;
+import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Random;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
+import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import junit.framework.TestCase;
@@ -60,4 +61,30 @@ public final class ZipOutputStreamTest extends TestCase {
zippedOut.close();
return bytesOut.toByteArray();
}
+
+ /**
+ * Reference implementation does NOT allow writing of an empty zip using a
+ * {@link ZipOutputStream}.
+ */
+ public void testCreateEmpty() throws IOException {
+ File result = File.createTempFile("ZipFileTest", "zip");
+ ZipOutputStream out =
+ new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(result)));
+ try {
+ out.close();
+ fail("Close on empty stream failed to throw exception");
+ } catch (ZipException e) {
+ // expected
+ }
+ }
+
+ /** Regression test for null comment causing a NullPointerException during write. */
+ public void testNullComment() throws IOException {
+ ZipOutputStream out = new ZipOutputStream(new ByteArrayOutputStream());
+ out.setComment(null);
+ out.putNextEntry(new ZipEntry("name"));
+ out.write(new byte[1]);
+ out.closeEntry();
+ out.finish();
+ }
}
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherInputStreamTest.java b/luni/src/test/java/libcore/javax/crypto/CipherInputStreamTest.java
index 28d95f2..67ed36c 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherInputStreamTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherInputStreamTest.java
@@ -18,8 +18,10 @@ package libcore.javax.crypto;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
@@ -30,37 +32,134 @@ import junit.framework.TestCase;
public final class CipherInputStreamTest extends TestCase {
- private final byte[] keyBytes = { 127, -2, -95, -39, 35, 118, 121, -92 };
+ private final byte[] aesKeyBytes = {
+ (byte) 0x50, (byte) 0x98, (byte) 0xF2, (byte) 0xC3, (byte) 0x85, (byte) 0x23,
+ (byte) 0xA3, (byte) 0x33, (byte) 0x50, (byte) 0x98, (byte) 0xF2, (byte) 0xC3,
+ (byte) 0x85, (byte) 0x23, (byte) 0xA3, (byte) 0x33,
+ };
+
+ private final byte[] aesIvBytes = {
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ };
+
+ private final byte[] aesCipherText = {
+ (byte) 0x2F, (byte) 0x2C, (byte) 0x74, (byte) 0x31, (byte) 0xFF, (byte) 0xCC,
+ (byte) 0x28, (byte) 0x7D, (byte) 0x59, (byte) 0xBD, (byte) 0xE5, (byte) 0x0A,
+ (byte) 0x30, (byte) 0x7E, (byte) 0x6A, (byte) 0x4A
+ };
+
+ private final byte[] rc4CipherText = {
+ (byte) 0x88, (byte) 0x01, (byte) 0xE3, (byte) 0x52, (byte) 0x7B
+ };
+
private final String plainText = "abcde";
- private final byte[] cipherText = { 121, -124, -106, 43, -55, -67, -105, -75 };
private SecretKey key;
+ private SecretKey rc4Key;
+ private AlgorithmParameterSpec iv;
@Override protected void setUp() throws Exception {
- key = new SecretKeySpec(keyBytes, "DES");
+ key = new SecretKeySpec(aesKeyBytes, "AES");
+ rc4Key = new SecretKeySpec(aesKeyBytes, "RC4");
+ iv = new IvParameterSpec(aesIvBytes);
+ }
+
+ private static class MeasuringInputStream extends FilterInputStream {
+ private int totalRead;
+
+ protected MeasuringInputStream(InputStream in) {
+ super(in);
+ }
+
+ @Override
+ public int read() throws IOException {
+ int c = super.read();
+ totalRead++;
+ return c;
+ }
+
+ @Override
+ public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
+ int numRead = super.read(buffer, byteOffset, byteCount);
+ if (numRead != -1) {
+ totalRead += numRead;
+ }
+ return numRead;
+ }
+
+ public int getTotalRead() {
+ return totalRead;
+ }
+ }
+
+ public void testAvailable() throws Exception {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ MeasuringInputStream in = new MeasuringInputStream(new ByteArrayInputStream(aesCipherText));
+ InputStream cin = new CipherInputStream(in, cipher);
+ assertTrue(cin.read() != -1);
+ assertEquals(aesCipherText.length, in.getTotalRead());
+ }
+
+ public void testDecrypt_NullInput_Discarded() throws Exception {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ InputStream in = new CipherInputStream(new ByteArrayInputStream(aesCipherText), cipher);
+ int discard = 3;
+ while (discard != 0) {
+ discard -= in.read(null, 0, discard);
+ }
+ byte[] bytes = readAll(in);
+ assertEquals(Arrays.toString(plainText.substring(3).getBytes("UTF-8")),
+ Arrays.toString(bytes));
}
public void testEncrypt() throws Exception {
- Cipher cipher = Cipher.getInstance("DES");
- cipher.init(Cipher.ENCRYPT_MODE, key);
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, key, iv);
InputStream in = new CipherInputStream(
new ByteArrayInputStream(plainText.getBytes("UTF-8")), cipher);
byte[] bytes = readAll(in);
- assertEquals(Arrays.toString(cipherText), Arrays.toString(bytes));
+ assertEquals(Arrays.toString(aesCipherText), Arrays.toString(bytes));
+
+ // Reading again shouldn't throw an exception.
+ assertEquals(-1, in.read());
+ }
+
+ public void testEncrypt_RC4() throws Exception {
+ Cipher cipher = Cipher.getInstance("RC4");
+ cipher.init(Cipher.ENCRYPT_MODE, rc4Key);
+ InputStream in = new CipherInputStream(
+ new ByteArrayInputStream(plainText.getBytes("UTF-8")), cipher);
+ byte[] bytes = readAll(in);
+ assertEquals(Arrays.toString(rc4CipherText), Arrays.toString(bytes));
+
+ // Reading again shouldn't throw an exception.
+ assertEquals(-1, in.read());
}
public void testDecrypt() throws Exception {
- Cipher cipher = Cipher.getInstance("DES");
- cipher.init(Cipher.DECRYPT_MODE, key);
- InputStream in = new CipherInputStream(new ByteArrayInputStream(cipherText), cipher);
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ InputStream in = new CipherInputStream(new ByteArrayInputStream(aesCipherText), cipher);
byte[] bytes = readAll(in);
- assertEquals(plainText, new String(bytes, "UTF-8"));
+ assertEquals(Arrays.toString(plainText.getBytes("UTF-8")), Arrays.toString(bytes));
+ }
+
+ public void testDecrypt_RC4() throws Exception {
+ Cipher cipher = Cipher.getInstance("RC4");
+ cipher.init(Cipher.DECRYPT_MODE, rc4Key);
+ InputStream in = new CipherInputStream(new ByteArrayInputStream(rc4CipherText), cipher);
+ byte[] bytes = readAll(in);
+ assertEquals(Arrays.toString(plainText.getBytes("UTF-8")), Arrays.toString(bytes));
}
public void testSkip() throws Exception {
- Cipher cipher = Cipher.getInstance("DES");
- cipher.init(Cipher.DECRYPT_MODE, key);
- InputStream in = new CipherInputStream(new ByteArrayInputStream(cipherText), cipher);
- assertTrue(in.skip(5) > 0);
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ InputStream in = new CipherInputStream(new ByteArrayInputStream(aesCipherText), cipher);
+ assertTrue(in.skip(5) >= 0);
}
private byte[] readAll(InputStream in) throws IOException {
@@ -75,10 +174,33 @@ public final class CipherInputStreamTest extends TestCase {
public void testCipherInputStream_TruncatedInput_Failure() throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(new byte[16], "AES"),
- new IvParameterSpec(new byte[16]));
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
InputStream is = new CipherInputStream(new ByteArrayInputStream(new byte[31]), cipher);
is.read(new byte[4]);
is.close();
}
+
+ public void testCipherInputStream_NullInputStream_Failure() throws Exception {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ InputStream is = new CipherInputStream(null, cipher);
+ try {
+ is.read();
+ fail("Expected NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ byte[] buffer = new byte[128];
+ try {
+ is.read(buffer);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ is.read(buffer, 0, buffer.length);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
index 7922a04..c89886c 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
@@ -26,14 +26,13 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.Certificate;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
@@ -53,6 +52,7 @@ import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.ShortBufferException;
+import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
@@ -60,10 +60,12 @@ import javax.crypto.spec.SecretKeySpec;
import junit.framework.TestCase;
import libcore.java.security.StandardNames;
import libcore.java.security.TestKeyStore;
-import libcore.util.EmptyArray;
public final class CipherTest extends TestCase {
+ /** GCM tag size used for tests. */
+ private static final int GCM_TAG_SIZE_BITS = 96;
+
private static final String[] RSA_PROVIDERS = ((StandardNames.IS_RI)
? new String[] { "SunJCE" }
: new String[] { "BC" , "AndroidOpenSSL" });
@@ -72,27 +74,6 @@ public final class CipherTest extends TestCase {
? new String[] { "SunJCE" }
: new String[] { "BC", "AndroidOpenSSL" });
- private static final boolean IS_UNLIMITED;
- static {
- boolean is_unlimited;
- if (StandardNames.IS_RI) {
- try {
- String algorithm = "PBEWITHMD5ANDTRIPLEDES";
- Cipher.getInstance(algorithm).init(getEncryptMode(algorithm),
- getEncryptKey(algorithm),
- getEncryptAlgorithmParameterSpec(algorithm));
- is_unlimited = true;
- } catch (Exception e) {
- is_unlimited = false;
- System.out.println("WARNING: Some tests disabled due to lack of "
- + "'Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files'");
- }
- } else {
- is_unlimited = true;
- }
- IS_UNLIMITED = is_unlimited;
- }
-
private static boolean isSupported(String algorithm, String provider) {
if (algorithm.equals("RC2")) {
return false;
@@ -117,12 +98,16 @@ public final class CipherTest extends TestCase {
return false;
}
}
- // stream modes CFB, CTR, CTS, OFB with PKCS5Padding don't really make sense
+ // stream modes CFB, CTR, CTS, OFB with PKCS5Padding or PKCS7Padding don't really make sense
if (!provider.equals("AndroidOpenSSL") &&
(algorithm.equals("AES/CFB/PKCS5PADDING")
+ || algorithm.equals("AES/CFB/PKCS7PADDING")
|| algorithm.equals("AES/CTR/PKCS5PADDING")
+ || algorithm.equals("AES/CTR/PKCS7PADDING")
|| algorithm.equals("AES/CTS/PKCS5PADDING")
- || algorithm.equals("AES/OFB/PKCS5PADDING"))) {
+ || algorithm.equals("AES/CTS/PKCS7PADDING")
+ || algorithm.equals("AES/OFB/PKCS5PADDING")
+ || algorithm.equals("AES/OFB/PKCS7PADDING"))) {
return false;
}
return true;
@@ -138,7 +123,7 @@ public final class CipherTest extends TestCase {
return false;
}
// AESWRAP should be used instead, fails with BC and SunJCE otherwise.
- if (algorithm.startsWith("AES")) {
+ if (algorithm.startsWith("AES") || algorithm.startsWith("DESEDE")) {
return false;
}
return true;
@@ -165,6 +150,12 @@ public final class CipherTest extends TestCase {
if (algorithm.startsWith("AES/")) {
return "AES";
}
+ if (algorithm.equals("GCM")) {
+ return "AES";
+ }
+ if (algorithm.startsWith("DESEDE/")) {
+ return "DESEDE";
+ }
if (algorithm.equals("PBEWITHMD5AND128BITAES-CBC-OPENSSL")) {
return "AES";
}
@@ -240,6 +231,11 @@ public final class CipherTest extends TestCase {
return algorithm.startsWith("PBE");
}
+ private static boolean isStreamMode(String algorithm) {
+ return algorithm.contains("/CTR/") || algorithm.contains("/OFB")
+ || algorithm.contains("/CFB");
+ }
+
private static Map<String, Key> ENCRYPT_KEYS = new HashMap<String, Key>();
private synchronized static Key getEncryptKey(String algorithm) throws Exception {
Key key = ENCRYPT_KEYS.get(algorithm);
@@ -285,17 +281,24 @@ public final class CipherTest extends TestCase {
static {
setExpectedBlockSize("AES", 16);
setExpectedBlockSize("AES/CBC/PKCS5PADDING", 16);
+ setExpectedBlockSize("AES/CBC/PKCS7PADDING", 16);
setExpectedBlockSize("AES/CBC/NOPADDING", 16);
setExpectedBlockSize("AES/CFB/PKCS5PADDING", 16);
+ setExpectedBlockSize("AES/CFB/PKCS7PADDING", 16);
setExpectedBlockSize("AES/CFB/NOPADDING", 16);
setExpectedBlockSize("AES/CTR/PKCS5PADDING", 16);
+ setExpectedBlockSize("AES/CTR/PKCS7PADDING", 16);
setExpectedBlockSize("AES/CTR/NOPADDING", 16);
setExpectedBlockSize("AES/CTS/PKCS5PADDING", 16);
+ setExpectedBlockSize("AES/CTS/PKCS7PADDING", 16);
setExpectedBlockSize("AES/CTS/NOPADDING", 16);
setExpectedBlockSize("AES/ECB/PKCS5PADDING", 16);
+ setExpectedBlockSize("AES/ECB/PKCS7PADDING", 16);
setExpectedBlockSize("AES/ECB/NOPADDING", 16);
setExpectedBlockSize("AES/OFB/PKCS5PADDING", 16);
+ setExpectedBlockSize("AES/OFB/PKCS7PADDING", 16);
setExpectedBlockSize("AES/OFB/NOPADDING", 16);
+ setExpectedBlockSize("GCM", 16);
setExpectedBlockSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
setExpectedBlockSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
setExpectedBlockSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
@@ -324,6 +327,24 @@ public final class CipherTest extends TestCase {
setExpectedBlockSize("PBEWITHSHA1ANDDES", 8);
setExpectedBlockSize("DESEDE", 8);
+ setExpectedBlockSize("DESEDE/CBC/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/CBC/PKCS7PADDING", 8);
+ setExpectedBlockSize("DESEDE/CBC/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/CFB/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/CFB/PKCS7PADDING", 8);
+ setExpectedBlockSize("DESEDE/CFB/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/CTR/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/CTR/PKCS7PADDING", 8);
+ setExpectedBlockSize("DESEDE/CTR/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/CTS/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/CTS/PKCS7PADDING", 8);
+ setExpectedBlockSize("DESEDE/CTS/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/ECB/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/ECB/PKCS7PADDING", 8);
+ setExpectedBlockSize("DESEDE/ECB/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/OFB/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/OFB/PKCS7PADDING", 8);
+ setExpectedBlockSize("DESEDE/OFB/NOPADDING", 8);
setExpectedBlockSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", 8);
setExpectedBlockSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", 8);
setExpectedBlockSize("PBEWITHMD5ANDTRIPLEDES", 8);
@@ -423,11 +444,18 @@ public final class CipherTest extends TestCase {
setExpectedOutputSize("AES", Cipher.ENCRYPT_MODE, 16);
setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+ setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+ setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+ setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+ setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+ setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+ setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+ setExpectedOutputSize("GCM", Cipher.ENCRYPT_MODE, GCM_TAG_SIZE_BITS / 8);
setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
@@ -439,17 +467,28 @@ public final class CipherTest extends TestCase {
setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", 16);
// AndroidOpenSSL returns zero for the non-block ciphers
setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+ setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+ setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+ setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+ setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
setExpectedOutputSize("AES", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("GCM", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
@@ -461,7 +500,13 @@ public final class CipherTest extends TestCase {
setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
// AndroidOpenSSL returns the block size for the block ciphers
setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
+ setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
+ setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
+ setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
+ setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
+ setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
+ setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
if (StandardNames.IS_RI) {
setExpectedOutputSize("AESWRAP", Cipher.WRAP_MODE, 8);
@@ -486,13 +531,44 @@ public final class CipherTest extends TestCase {
setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CBC/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/CFB/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/CTR/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/CTS/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/ECB/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/OFB/NOPADDING", 0);
+
setExpectedOutputSize("DESEDE", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("PBEWITHSHA1ANDDESEDE", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("DESEDE", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CTR/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CTR/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CTS/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CTS/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/OFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/OFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.DECRYPT_MODE, 0);
@@ -542,6 +618,8 @@ public final class CipherTest extends TestCase {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
+ private static byte[] EIGHT_BYTE_BLOCK_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
private static byte[] PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT = new byte[] {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -638,6 +716,11 @@ public final class CipherTest extends TestCase {
|| algorithm.equals("AES/ECB/NOPADDING")) {
return SIXTEEN_BYTE_BLOCK_PLAIN_TEXT;
}
+ if (algorithm.equals("DESEDE")
+ || algorithm.equals("DESEDE/CBC/NOPADDING")
+ || algorithm.equals("DESEDE/ECB/NOPADDING")) {
+ return EIGHT_BYTE_BLOCK_PLAIN_TEXT;
+ }
return ORIGINAL_PLAIN_TEXT;
}
@@ -649,6 +732,11 @@ public final class CipherTest extends TestCase {
|| algorithm.equals("AES/ECB/NOPADDING")) {
return SIXTEEN_BYTE_BLOCK_PLAIN_TEXT;
}
+ if (algorithm.equals("DESEDE")
+ || algorithm.equals("DESEDE/CBC/NOPADDING")
+ || algorithm.equals("DESEDE/ECB/NOPADDING")) {
+ return EIGHT_BYTE_BLOCK_PLAIN_TEXT;
+ }
// BC strips the leading 0 for us even when NoPadding is specified
if (!provider.equals("BC") && algorithm.equals("RSA/ECB/NOPADDING")) {
return PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT;
@@ -662,8 +750,14 @@ public final class CipherTest extends TestCase {
new SecureRandom().nextBytes(salt);
return new PBEParameterSpec(salt, 1024);
}
+ if (algorithm.equals("GCM")) {
+ final byte[] iv = new byte[8];
+ new SecureRandom().nextBytes(iv);
+ return new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
+ }
if (algorithm.equals("AES/CBC/NOPADDING")
|| algorithm.equals("AES/CBC/PKCS5PADDING")
+ || algorithm.equals("AES/CBC/PKCS7PADDING")
|| algorithm.equals("AES/CFB/NOPADDING")
|| algorithm.equals("AES/CTR/NOPADDING")
|| algorithm.equals("AES/CTS/NOPADDING")
@@ -672,6 +766,17 @@ public final class CipherTest extends TestCase {
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
+ if (algorithm.equals("DESEDE/CBC/NOPADDING")
+ || algorithm.equals("DESEDE/CBC/PKCS5PADDING")
+ || algorithm.equals("DESEDE/CBC/PKCS7PADDING")
+ || algorithm.equals("DESEDE/CFB/NOPADDING")
+ || algorithm.equals("DESEDE/CTR/NOPADDING")
+ || algorithm.equals("DESEDE/CTS/NOPADDING")
+ || algorithm.equals("DESEDE/OFB/NOPADDING")) {
+ final byte[] iv = new byte[8];
+ new SecureRandom().nextBytes(iv);
+ return new IvParameterSpec(iv);
+ }
return null;
}
@@ -686,11 +791,193 @@ public final class CipherTest extends TestCase {
}
byte[] iv = encryptCipher.getIV();
if (iv != null) {
+ if ("GCM".equals(algorithm)) {
+ return new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
+ }
return new IvParameterSpec(iv);
}
return null;
}
+ /*
+ * This must be below everything else to make sure the other static blocks
+ * have run first.
+ */
+ private static final boolean IS_UNLIMITED;
+ static {
+ boolean is_unlimited;
+ if (StandardNames.IS_RI) {
+ try {
+ String algorithm = "PBEWITHMD5ANDTRIPLEDES";
+ Cipher.getInstance(algorithm).init(getEncryptMode(algorithm),
+ getEncryptKey(algorithm),
+ getEncryptAlgorithmParameterSpec(algorithm));
+ is_unlimited = true;
+ } catch (Exception e) {
+ is_unlimited = false;
+ System.out.println("WARNING: Some tests disabled due to lack of "
+ + "'Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files'");
+ }
+ } else {
+ is_unlimited = true;
+ }
+ IS_UNLIMITED = is_unlimited;
+ }
+
+ private static abstract class MockProvider extends Provider {
+ public MockProvider(String name) {
+ super(name, 1.0, "Mock provider used for testing");
+ setup();
+ }
+
+ public abstract void setup();
+ }
+
+ public void testCipher_getInstance_SuppliedProviderNotRegistered_Success() throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ {
+ Cipher c = Cipher.getInstance("FOO", mockProvider);
+ c.init(Cipher.ENCRYPT_MODE, new MockKey());
+ assertEquals(mockProvider, c.getProvider());
+ }
+ }
+
+ public void testCipher_getInstance_SuppliedProviderNotRegistered_MultipartTransform_Success()
+ throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ {
+ Cipher c = Cipher.getInstance("FOO/FOO/FOO", mockProvider);
+ c.init(Cipher.ENCRYPT_MODE, new MockKey());
+ assertEquals(mockProvider, c.getProvider());
+ }
+ }
+
+ public void testCipher_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
+ throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProvider);
+ try {
+ {
+ Provider mockProvider2 = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ }
+ };
+ Cipher c = Cipher.getInstance("FOO", mockProvider2);
+ assertEquals(mockProvider2, c.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProvider.getName());
+ }
+ }
+
+ public void testCipher_getInstance_DelayedInitialization_KeyType() throws Exception {
+ Provider mockProviderSpecific = new MockProvider("MockProviderSpecific") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.SpecificKeyTypes.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+ Provider mockProviderSpecific2 = new MockProvider("MockProviderSpecific2") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.SpecificKeyTypes2.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey2.class.getName());
+ }
+ };
+ Provider mockProviderAll = new MockProvider("MockProviderAll") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderSpecific);
+ Security.addProvider(mockProviderSpecific2);
+ Security.addProvider(mockProviderAll);
+
+ try {
+ {
+ System.out.println(Arrays.deepToString(Security.getProviders("Cipher.FOO")));
+ Cipher c = Cipher.getInstance("FOO");
+ c.init(Cipher.ENCRYPT_MODE, new MockKey());
+ assertEquals(mockProviderSpecific, c.getProvider());
+
+ try {
+ c.init(Cipher.ENCRYPT_MODE, new MockKey2());
+ assertEquals(mockProviderSpecific2, c.getProvider());
+ if (StandardNames.IS_RI) {
+ fail("RI was broken before; fix tests now that it works!");
+ }
+ } catch (InvalidKeyException e) {
+ if (!StandardNames.IS_RI) {
+ fail("Non-RI should select the right provider");
+ }
+ }
+ }
+
+ {
+ Cipher c = Cipher.getInstance("FOO");
+ c.init(Cipher.ENCRYPT_MODE, new Key() {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+ });
+ assertEquals(mockProviderAll, c.getProvider());
+ }
+
+ {
+ Cipher c = Cipher.getInstance("FOO");
+ assertEquals(mockProviderSpecific, c.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProviderSpecific.getName());
+ Security.removeProvider(mockProviderSpecific2.getName());
+ Security.removeProvider(mockProviderAll.getName());
+ }
+ }
+
+ public void testCipher_getInstance_WrongType_Failure() throws Exception {
+ Provider mockProviderInvalid = new MockProvider("MockProviderInvalid") {
+ public void setup() {
+ put("Cipher.FOO", Object.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderInvalid);
+ try {
+ Cipher.getInstance("FOO");
+ fail("Should not find any matching providers");
+ } catch (NoSuchAlgorithmException expected) {
+ } finally {
+ Security.removeProvider(mockProviderInvalid.getName());
+ }
+ }
+
public void test_getInstance() throws Exception {
final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(errBuffer);
@@ -723,7 +1010,9 @@ public final class CipherTest extends TestCase {
if (!seenBaseCipherNames.contains(baseCipherName)) {
seenCiphersWithModeAndPadding.add(baseCipherName);
}
- continue;
+ if (!"AndroidOpenSSL".equals(provider.getName())) {
+ continue;
+ }
}
try {
@@ -832,11 +1121,18 @@ public final class CipherTest extends TestCase {
}
}
+ test_Cipher_init_NullParameters(c, encryptMode, encryptKey);
+
c.init(encryptMode, encryptKey, encryptSpec);
assertEquals(cipherID + " getBlockSize() encryptMode",
getExpectedBlockSize(algorithm, encryptMode, providerName), c.getBlockSize());
assertEquals(cipherID + " getOutputSize(0) encryptMode",
getExpectedOutputSize(algorithm, encryptMode, providerName), c.getOutputSize(0));
+ if ((algorithm.endsWith("/PKCS5PADDING") || algorithm.endsWith("/PKCS7PADDING"))
+ && isStreamMode(algorithm)) {
+ assertEquals(getExpectedOutputSize(algorithm, encryptMode, providerName),
+ c.doFinal(new byte[1]).length);
+ }
final AlgorithmParameterSpec decryptSpec = getDecryptAlgorithmParameterSpec(encryptSpec, c);
int decryptMode = getDecryptMode(algorithm);
@@ -856,6 +1152,11 @@ public final class CipherTest extends TestCase {
assertEquals(cipherID + " getIV()",
Arrays.toString(((IvParameterSpec) decryptSpec).getIV()),
Arrays.toString(c.getIV()));
+ } else if (decryptSpec instanceof GCMParameterSpec) {
+ assertNotNull(c.getIV());
+ assertEquals(cipherID + " getIV()",
+ Arrays.toString(((GCMParameterSpec) decryptSpec).getIV()),
+ Arrays.toString(c.getIV()));
} else {
try {
assertNull(cipherID + " getIV()", c.getIV());
@@ -885,7 +1186,9 @@ public final class CipherTest extends TestCase {
assertNull(cipherID, c.getExemptionMechanism());
// Test wrapping a key. Every cipher should be able to wrap. Except those that can't.
- if (isSupportedForWrapping(algorithm)) {
+ /* Bouncycastle is broken for wrapping because getIV() fails. */
+ if (isSupportedForWrapping(algorithm)
+ && !algorithm.equals("GCM") && !providerName.equals("BC")) {
// Generate a small SecretKey for AES.
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128);
@@ -910,11 +1213,58 @@ public final class CipherTest extends TestCase {
if (!isOnlyWrappingAlgorithm(algorithm)) {
c.init(Cipher.ENCRYPT_MODE, encryptKey, encryptSpec);
byte[] cipherText = c.doFinal(getActualPlainText(algorithm));
+ byte[] cipherText2 = c.doFinal(getActualPlainText(algorithm));
+ assertEquals(cipherID,
+ Arrays.toString(cipherText),
+ Arrays.toString(cipherText2));
c.init(Cipher.DECRYPT_MODE, getDecryptKey(algorithm), decryptSpec);
byte[] decryptedPlainText = c.doFinal(cipherText);
assertEquals(cipherID,
Arrays.toString(getExpectedPlainText(algorithm, providerName)),
Arrays.toString(decryptedPlainText));
+ byte[] decryptedPlainText2 = c.doFinal(cipherText);
+ assertEquals(cipherID,
+ Arrays.toString(decryptedPlainText),
+ Arrays.toString(decryptedPlainText2));
+ }
+ }
+
+ /**
+ * Try various .init(...) calls with null parameters to make sure it is
+ * handled.
+ */
+ private void test_Cipher_init_NullParameters(Cipher c, int encryptMode, Key encryptKey)
+ throws Exception {
+ try {
+ c.init(encryptMode, encryptKey, (AlgorithmParameterSpec) null);
+ } catch (InvalidAlgorithmParameterException e) {
+ if (!isPBE(c.getAlgorithm())) {
+ throw e;
+ }
+ }
+
+ try {
+ c.init(encryptMode, encryptKey, (AlgorithmParameterSpec) null, (SecureRandom) null);
+ } catch (InvalidAlgorithmParameterException e) {
+ if (!isPBE(c.getAlgorithm())) {
+ throw e;
+ }
+ }
+
+ try {
+ c.init(encryptMode, encryptKey, (AlgorithmParameters) null);
+ } catch (InvalidAlgorithmParameterException e) {
+ if (!isPBE(c.getAlgorithm())) {
+ throw e;
+ }
+ }
+
+ try {
+ c.init(encryptMode, encryptKey, (AlgorithmParameters) null, (SecureRandom) null);
+ } catch (InvalidAlgorithmParameterException e) {
+ if (!isPBE(c.getAlgorithm())) {
+ throw e;
+ }
}
}
@@ -2135,7 +2485,7 @@ public final class CipherTest extends TestCase {
};
private static class CipherTestParam {
- public final String mode;
+ public final String transformation;
public final byte[] key;
@@ -2147,9 +2497,9 @@ public final class CipherTest extends TestCase {
public final byte[] plaintextPadded;
- public CipherTestParam(String mode, byte[] key, byte[] iv, byte[] plaintext,
+ public CipherTestParam(String transformation, byte[] key, byte[] iv, byte[] plaintext,
byte[] plaintextPadded, byte[] ciphertext) {
- this.mode = mode;
+ this.transformation = transformation;
this.key = key;
this.iv = iv;
this.plaintext = plaintext;
@@ -2160,13 +2510,24 @@ public final class CipherTest extends TestCase {
private static List<CipherTestParam> CIPHER_TEST_PARAMS = new ArrayList<CipherTestParam>();
static {
- CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/ECB", AES_128_KEY,
+ CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/ECB/PKCS5Padding", AES_128_KEY,
+ null,
+ AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext,
+ AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
+ AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted));
+ // PKCS#5 is assumed to be equivalent to PKCS#7 -- same test vectors are thus used for both.
+ CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/ECB/PKCS7Padding", AES_128_KEY,
null,
AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext,
AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted));
if (IS_UNLIMITED) {
- CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC", AES_256_KEY,
+ CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC/PKCS5Padding", AES_256_KEY,
+ AES_256_CBC_PKCS5Padding_TestVector_1_IV,
+ AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext,
+ AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded,
+ AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext));
+ CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC/PKCS7Padding", AES_256_KEY,
AES_256_CBC_PKCS5Padding_TestVector_1_IV,
AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext,
AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded,
@@ -2187,7 +2548,7 @@ public final class CipherTest extends TestCase {
try {
checkCipher(p, provider);
} catch (Exception e) {
- out.append("Error encountered checking " + p.mode + ", keySize="
+ out.append("Error encountered checking " + p.transformation + ", keySize="
+ (p.key.length * 8)
+ " with provider " + provider + "\n");
@@ -2202,7 +2563,7 @@ public final class CipherTest extends TestCase {
private void checkCipher(CipherTestParam p, String provider) throws Exception {
SecretKey key = new SecretKeySpec(p.key, "AES");
- Cipher c = Cipher.getInstance(p.mode + "/PKCS5Padding", provider);
+ Cipher c = Cipher.getInstance(p.transformation, provider);
AlgorithmParameterSpec spec = null;
if (p.iv != null) {
spec = new IvParameterSpec(p.iv);
@@ -2224,16 +2585,16 @@ public final class CipherTest extends TestCase {
}
byte[] emptyPlainText = c.doFinal(emptyCipherText);
- assertEquals(Arrays.toString(EmptyArray.BYTE), Arrays.toString(emptyPlainText));
+ assertEquals(Arrays.toString(new byte[0]), Arrays.toString(emptyPlainText));
// empty decrypt
{
if (StandardNames.IS_RI) {
- assertEquals(Arrays.toString(EmptyArray.BYTE),
+ assertEquals(Arrays.toString(new byte[0]),
Arrays.toString(c.doFinal()));
- c.update(EmptyArray.BYTE);
- assertEquals(Arrays.toString(EmptyArray.BYTE),
+ c.update(new byte[0]);
+ assertEquals(Arrays.toString(new byte[0]),
Arrays.toString(c.doFinal()));
} else if (provider.equals("BC")) {
try {
@@ -2242,7 +2603,7 @@ public final class CipherTest extends TestCase {
} catch (IllegalBlockSizeException expected) {
}
try {
- c.update(EmptyArray.BYTE);
+ c.update(new byte[0]);
c.doFinal();
fail();
} catch (IllegalBlockSizeException expected) {
@@ -2250,7 +2611,7 @@ public final class CipherTest extends TestCase {
} else if (provider.equals("AndroidOpenSSL")) {
assertNull(c.doFinal());
- c.update(EmptyArray.BYTE);
+ c.update(new byte[0]);
assertNull(c.doFinal());
} else {
throw new AssertionError("Define your behavior here for " + provider);
@@ -2287,11 +2648,13 @@ public final class CipherTest extends TestCase {
Arrays.toString(Arrays.copyOfRange(actualPlaintext, 1, p.plaintext.length + 1)));
}
- Cipher cNoPad = Cipher.getInstance(p.mode + "/NoPadding", provider);
+ Cipher cNoPad = Cipher.getInstance(
+ getCipherTransformationWithNoPadding(p.transformation), provider);
cNoPad.init(Cipher.DECRYPT_MODE, key, spec);
final byte[] actualPlaintextPadded = cNoPad.doFinal(p.ciphertext);
- assertEquals(Arrays.toString(p.plaintextPadded), Arrays.toString(actualPlaintextPadded));
+ assertEquals(provider + ":" + cNoPad.getAlgorithm(), Arrays.toString(p.plaintextPadded),
+ Arrays.toString(actualPlaintextPadded));
// Test wrapping a key. Every cipher should be able to wrap.
{
@@ -2316,6 +2679,23 @@ public final class CipherTest extends TestCase {
}
}
+ /**
+ * Gets the Cipher transformation with the same algorithm and mode as the provided one but
+ * which uses no padding.
+ */
+ private static String getCipherTransformationWithNoPadding(String transformation) {
+ // The transformation is assumed to be in the Algorithm/Mode/Padding format.
+ int paddingModeDelimiterIndex = transformation.lastIndexOf('/');
+ if (paddingModeDelimiterIndex == -1) {
+ fail("No padding mode delimiter: " + transformation);
+ }
+ String paddingMode = transformation.substring(paddingModeDelimiterIndex + 1);
+ if (!paddingMode.toLowerCase().endsWith("padding")) {
+ fail("No padding mode specified:" + transformation);
+ }
+ return transformation.substring(0, paddingModeDelimiterIndex) + "/NoPadding";
+ }
+
public void testCipher_updateAAD_BeforeInit_Failure() throws Exception {
Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
@@ -2405,7 +2785,7 @@ public final class CipherTest extends TestCase {
try {
checkCipher_ShortBlock_Failure(p, provider);
} catch (Exception e) {
- out.append("Error encountered checking " + p.mode + ", keySize="
+ out.append("Error encountered checking " + p.transformation + ", keySize="
+ (p.key.length * 8)
+ " with provider " + provider + "\n");
e.printStackTrace(out);
@@ -2419,7 +2799,8 @@ public final class CipherTest extends TestCase {
private void checkCipher_ShortBlock_Failure(CipherTestParam p, String provider) throws Exception {
SecretKey key = new SecretKeySpec(p.key, "AES");
- Cipher c = Cipher.getInstance(p.mode + "/NoPadding", provider);
+ Cipher c = Cipher.getInstance(
+ getCipherTransformationWithNoPadding(p.transformation), provider);
if (c.getBlockSize() == 0) {
return;
}
@@ -2427,7 +2808,8 @@ public final class CipherTest extends TestCase {
c.init(Cipher.ENCRYPT_MODE, key);
try {
c.doFinal(new byte[] { 0x01, 0x02, 0x03 });
- fail("Should throw IllegalBlockSizeException on wrong-sized block");
+ fail("Should throw IllegalBlockSizeException on wrong-sized block; provider="
+ + provider);
} catch (IllegalBlockSizeException expected) {
}
}
@@ -2495,6 +2877,7 @@ public final class CipherTest extends TestCase {
private void testAES_ECB_NoPadding_IncrementalUpdate_Success(String provider) throws Exception {
SecretKey key = new SecretKeySpec(AES_128_KEY, "AES");
Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
+ assertEquals(provider, c.getProvider().getName());
c.init(Cipher.ENCRYPT_MODE, key);
for (int i = 0; i < AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length - 1; i++) {
@@ -2506,10 +2889,11 @@ public final class CipherTest extends TestCase {
final byte[] output = c.doFinal(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length - 1, 1);
- assertNotNull(output);
- assertEquals(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length, output.length);
+ assertNotNull(provider, output);
+ assertEquals(provider, AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length,
+ output.length);
- assertTrue(Arrays.equals(AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted, output));
+ assertTrue(provider, Arrays.equals(AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted, output));
}
private static final byte[] AES_IV_ZEROES = new byte[] {
@@ -2531,7 +2915,7 @@ public final class CipherTest extends TestCase {
AlgorithmParameterSpec spec = new IvParameterSpec(AES_IV_ZEROES);
try {
c.init(Cipher.ENCRYPT_MODE, key, spec);
- fail("Should not accept an IV in ECB mode");
+ fail("Should not accept an IV in ECB mode; provider=" + provider);
} catch (InvalidAlgorithmParameterException expected) {
}
}
diff --git a/luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java b/luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java
index 29efd3a..8bbd548 100644
--- a/luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java
@@ -114,6 +114,8 @@ public class KeyGeneratorTest extends TestCase {
putKeySize("HmacMD5", 1025);
putKeySize("HmacSHA1", 1);
putKeySize("HmacSHA1", 1025);
+ putKeySize("HmacSHA224", 40);
+ putKeySize("HmacSHA224", 1025);
putKeySize("HmacSHA256", 40);
putKeySize("HmacSHA256", 1025);
putKeySize("HmacSHA384", 40);
diff --git a/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java b/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java
new file mode 100644
index 0000000..6742cf3
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+/**
+ * Mock CipherSpi used by {@link CipherTest}.
+ */
+public class MockCipherSpi extends CipherSpi {
+ public static class SpecificKeyTypes extends MockCipherSpi {
+ @Override
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ if (!(key instanceof MockKey)) {
+ throw new InvalidKeyException("Must be MockKey!");
+ }
+ }
+ }
+
+ public static class SpecificKeyTypes2 extends MockCipherSpi {
+ @Override
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ System.err.println("Checking key of type " + key.getClass().getName());
+ if (!(key instanceof MockKey2)) {
+ throw new InvalidKeyException("Must be MockKey2!");
+ }
+ }
+ }
+
+ public static class AllKeyTypes extends MockCipherSpi {
+ }
+
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ }
+
+ @Override
+ protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+ if (!"FOO".equals(mode)) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+ }
+
+ @Override
+ protected void engineSetPadding(String padding) throws NoSuchPaddingException {
+ if (!"FOO".equals(padding)) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+ }
+
+ @Override
+ protected int engineGetBlockSize() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected int engineGetOutputSize(int inputLen) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected byte[] engineGetIV() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
+ checkKeyType(key);
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ checkKeyType(key);
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ checkKeyType(key);
+ }
+
+ @Override
+ protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
+ int outputOffset) throws ShortBufferException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+ int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/luni/src/test/java/libcore/javax/crypto/MockKey.java b/luni/src/test/java/libcore/javax/crypto/MockKey.java
new file mode 100644
index 0000000..248e2de
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/MockKey.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.crypto;
+
+import java.security.Key;
+
+/**
+ * A mock Key class used for testing.
+ */
+@SuppressWarnings("serial")
+public class MockKey implements Key {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ return "MOCK";
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/luni/src/test/java/libcore/javax/crypto/MockKey2.java b/luni/src/test/java/libcore/javax/crypto/MockKey2.java
new file mode 100644
index 0000000..44ac0cc
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/MockKey2.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.crypto;
+
+import java.security.Key;
+
+/**
+ * A mock Key class used for testing.
+ */
+@SuppressWarnings("serial")
+public class MockKey2 implements Key {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ return "MOCK";
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
index 578ee6b..e64fb9e 100644
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
+++ b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
@@ -26,7 +26,7 @@ public class AlgorithmParameterGeneratorTestDH extends
super("DH", new AlgorithmParameterKeyAgreementHelper("DH"));
}
- @BrokenTest("Suffers from DH slowness, disabling for now")
+ // Broken Test: Suffers from DH slowness, disabling for now
public void testAlgorithmParameterGenerator() {
super.testAlgorithmParameterGenerator();
}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
index 165daa1..897e62b 100644
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
+++ b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
@@ -15,7 +15,6 @@
*/
package libcore.javax.crypto.spec;
-import dalvik.annotation.BrokenTest;
import java.math.BigInteger;
import javax.crypto.spec.DHParameterSpec;
import tests.security.AlgorithmParameterKeyAgreementHelper;
@@ -61,7 +60,7 @@ public class AlgorithmParametersTestDH extends AlgorithmParametersTest {
}
- @BrokenTest("Suffers from DH slowness, disabling for now")
+ // Broken Test: Suffers from DH slowness, disabling for now
public void testAlgorithmParameters() {
super.testAlgorithmParameters();
}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
index c4322ff..8e500e1 100644
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
+++ b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
@@ -15,7 +15,6 @@
*/
package libcore.javax.crypto.spec;
-import dalvik.annotation.BrokenTest;
import java.security.NoSuchAlgorithmException;
import tests.security.KeyAgreementHelper;
import tests.security.KeyPairGeneratorTest;
@@ -26,7 +25,7 @@ public class KeyPairGeneratorTestDH extends KeyPairGeneratorTest {
super("DH", new KeyAgreementHelper("DH"));
}
- @BrokenTest("Takes ages due to DH computations. Disabling for now.")
+ // Broken Test: Takes ages due to DH computations. Disabling for now.
public void testKeyPairGenerator() throws NoSuchAlgorithmException {
super.testKeyPairGenerator();
}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java b/luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java
index e1c9fe3..feecebe 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java
@@ -114,15 +114,18 @@ public final class DefaultHostnameVerifierTest extends TestCase {
public void testWildcardMatchesWildcardSuffix() {
assertTrue(verifier.verifyHostName("b.c.d", "*.b.c.d"));
assertTrue(verifier.verifyHostName("imap.google.com", "*.imap.google.com"));
+ assertFalse(verifier.verifyHostName("imap.google.com.au", "*.imap.google.com"));
}
public void testWildcardMatchingSubstring() {
assertTrue(verifier.verifyHostName("b.c.d", "b*.c.d"));
assertTrue(verifier.verifyHostName("imap.google.com", "ima*.google.com"));
+ assertFalse(verifier.verifyHostName("imap.google.com.au", "ima*.google.com"));
}
public void testWildcardMatchingEmptySubstring() {
assertTrue(verifier.verifyHostName("imap.google.com", "imap*.google.com"));
+ assertFalse(verifier.verifyHostName("imap.google.com.au", "imap*.google.com"));
}
public void testWildcardMatchesChildDomain() {
diff --git a/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
index f2d36c8..0657f18 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
@@ -45,8 +45,8 @@ public class KeyManagerFactoryTest extends TestCase {
private static TestKeyStore getTestKeyStore() throws Exception {
if (TEST_KEY_STORE == null) {
TEST_KEY_STORE = new TestKeyStore.Builder()
- .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
- .aliasPrefix("rsa-dsa-ec")
+ .keyAlgorithms("RSA", "DH_RSA", "DSA", "DH_DSA", "EC", "EC_RSA")
+ .aliasPrefix("rsa-dsa-ec-dh")
.build();
}
return TEST_KEY_STORE;
diff --git a/luni/src/test/java/libcore/javax/net/ssl/PSKKeyManagerProxy.java b/luni/src/test/java/libcore/javax/net/ssl/PSKKeyManagerProxy.java
new file mode 100644
index 0000000..1daa346
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/PSKKeyManagerProxy.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.Socket;
+import javax.crypto.SecretKey;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLEngine;
+
+/**
+ * Reflection-based implementation of {@code PSKKeyManager} from Conscrypt on which these tests
+ * cannot depend directly.
+ */
+class PSKKeyManagerProxy implements InvocationHandler {
+
+ static KeyManager getConscryptPSKKeyManager(PSKKeyManagerProxy delegate) {
+ Class<?> pskKeyManagerInterface;
+ try {
+ pskKeyManagerInterface = Class.forName("com.android.org.conscrypt.PSKKeyManager");
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ return (KeyManager) Proxy.newProxyInstance(
+ PSKKeyManagerProxy.class.getClassLoader(),
+ new Class[] {pskKeyManagerInterface},
+ delegate);
+ }
+
+ @SuppressWarnings("unused")
+ protected SecretKey getKey(String identityHint, String identity, Socket socket) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ protected SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ protected String chooseServerKeyIdentityHint(Socket socket) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ protected String chooseServerKeyIdentityHint(SSLEngine engine) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ protected String chooseClientKeyIdentity(String identityHint, Socket socket) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ protected String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
+ return null;
+ }
+
+ @Override
+ public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ String methodName = method.getName();
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ boolean sslEngineVariant = (parameterTypes.length > 0)
+ && (SSLEngine.class.equals(parameterTypes[parameterTypes.length - 1]));
+ if ("getKey".equals(methodName)) {
+ if (sslEngineVariant) {
+ return getKey((String) args[0], (String) args[1], (SSLEngine) args[2]);
+ } else {
+ return getKey((String) args[0], (String) args[1], (Socket) args[2]);
+ }
+ } else if ("chooseServerKeyIdentityHint".equals(methodName)) {
+ if (sslEngineVariant) {
+ return chooseServerKeyIdentityHint((SSLEngine) args[0]);
+ } else {
+ return chooseServerKeyIdentityHint((Socket) args[0]);
+ }
+ } else if ("chooseClientKeyIdentity".equals(methodName)) {
+ if (sslEngineVariant) {
+ return chooseClientKeyIdentity((String) args[0], (SSLEngine) args[1]);
+ } else {
+ return chooseClientKeyIdentity((String) args[0], (Socket) args[1]);
+ }
+ } else {
+ throw new IllegalArgumentException("Unexpected method: " + method);
+ }
+ }
+} \ No newline at end of file
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
index 900d950..dccadbd 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
@@ -16,17 +16,39 @@
package libcore.javax.net.ssl;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
import java.security.Provider;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import libcore.io.IoUtils;
import libcore.java.security.StandardNames;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.KeyManagerFactorySpi;
+import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.TrustManagerFactorySpi;
+import javax.net.ssl.X509KeyManager;
+import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
public class SSLContextTest extends TestCase {
@@ -59,6 +81,106 @@ public class SSLContextTest extends TestCase {
SSLContext.setDefault(defaultContext);
}
+ public void test_SSLContext_defaultConfiguration() throws Exception {
+ SSLDefaultConfigurationAsserts.assertSSLContext(SSLContext.getDefault());
+
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ sslContext.init(null, null, null);
+ }
+ SSLDefaultConfigurationAsserts.assertSSLContext(sslContext);
+ }
+ }
+
+ public void test_SSLContext_pskOnlyConfiguration_defaultProviderOnly() throws Exception {
+ // Test the scenario where only a PSKKeyManager is provided and no TrustManagers are
+ // provided.
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(
+ new KeyManager[] {
+ PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
+ },
+ new TrustManager[0],
+ null);
+ List<String> expectedCipherSuites =
+ new ArrayList<String>(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
+ expectedCipherSuites.add(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION);
+ assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+ }
+
+ public void test_SSLContext_x509AndPskConfiguration_defaultProviderOnly() throws Exception {
+ // Test the scenario where an X509TrustManager and PSKKeyManager are provided.
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(
+ new KeyManager[] {
+ PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
+ },
+ null, // Use default trust managers, one of which is an X.509 one.
+ null);
+ List<String> expectedCipherSuites =
+ new ArrayList<String>(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
+ expectedCipherSuites.addAll(StandardNames.CIPHER_SUITES_DEFAULT);
+ assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+
+ // Test the scenario where an X509KeyManager and PSKKeyManager are provided.
+ sslContext = SSLContext.getInstance("TLS");
+ // Just an arbitrary X509KeyManager -- it won't be invoked in this test.
+ X509KeyManager x509KeyManager = new RandomPrivateKeyX509ExtendedKeyManager(null);
+ sslContext.init(
+ new KeyManager[] {
+ x509KeyManager,
+ PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
+ },
+ new TrustManager[0],
+ null);
+ assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+ }
+
+ public void test_SSLContext_emptyConfiguration_defaultProviderOnly() throws Exception {
+ // Test the scenario where neither X.509 nor PSK KeyManagers or TrustManagers are provided.
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(
+ new KeyManager[0],
+ new TrustManager[0],
+ null);
+ assertEnabledCipherSuites(
+ Arrays.asList(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION),
+ sslContext);
+ }
+
+ private static void assertEnabledCipherSuites(
+ List<String> expectedCipherSuites, SSLContext sslContext) throws Exception {
+ assertContentsInOrder(
+ expectedCipherSuites, sslContext.createSSLEngine().getEnabledCipherSuites());
+ assertContentsInOrder(
+ expectedCipherSuites,
+ sslContext.createSSLEngine().getSSLParameters().getCipherSuites());
+ assertContentsInOrder(
+ expectedCipherSuites, sslContext.getSocketFactory().getDefaultCipherSuites());
+ assertContentsInOrder(
+ expectedCipherSuites, sslContext.getServerSocketFactory().getDefaultCipherSuites());
+
+ SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket();
+ try {
+ assertContentsInOrder(
+ expectedCipherSuites, sslSocket.getEnabledCipherSuites());
+ assertContentsInOrder(
+ expectedCipherSuites, sslSocket.getSSLParameters().getCipherSuites());
+ } finally {
+ IoUtils.closeQuietly(sslSocket);
+ }
+
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket();
+ try {
+ assertContentsInOrder(
+ expectedCipherSuites, sslServerSocket.getEnabledCipherSuites());
+ } finally {
+ IoUtils.closeQuietly(sslSocket);
+ }
+ }
+
public void test_SSLContext_getInstance() throws Exception {
try {
SSLContext.getInstance(null);
@@ -109,16 +231,183 @@ public class SSLContextTest extends TestCase {
assertEquals(StandardNames.JSSE_PROVIDER_NAME, provider.getName());
}
- public void test_SSLContext_init() throws Exception {
+ public void test_SSLContext_init_Default() throws Exception {
+ // Assert that initializing a default SSLContext fails because it's supposed to be
+ // initialized already.
+ SSLContext sslContext = SSLContext.getInstance(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT);
+ try {
+ sslContext.init(null, null, null);
+ fail();
+ } catch (KeyManagementException expected) {}
+ try {
+ sslContext.init(new KeyManager[0], new TrustManager[0], null);
+ fail();
+ } catch (KeyManagementException expected) {}
+ try {
+ sslContext.init(
+ new KeyManager[] {new KeyManager() {}},
+ new TrustManager[] {new TrustManager() {}},
+ null);
+ fail();
+ } catch (KeyManagementException expected) {}
+ }
+
+ public void test_SSLContext_init_withNullManagerArrays() throws Exception {
+ // Assert that SSLContext.init works fine even when provided with null arrays of
+ // KeyManagers and TrustManagers.
+ // The contract of SSLContext.init is that it will for default X.509 KeyManager and
+ // TrustManager from the highest priority KeyManagerFactory and TrustManagerFactory.
for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- SSLContext sslContext = SSLContext.getInstance(protocol);
if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- try {
- sslContext.init(null, null, null);
- } catch (KeyManagementException expected) {
+ // Default SSLContext is provided in an already initialized state
+ continue;
+ }
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ sslContext.init(null, null, null);
+ }
+ }
+
+ public void test_SSLContext_init_withEmptyManagerArrays() throws Exception {
+ // Assert that SSLContext.init works fine even when provided with empty arrays of
+ // KeyManagers and TrustManagers.
+ // The contract of SSLContext.init is that it will not look for default X.509 KeyManager and
+ // TrustManager.
+ // This test thus installs a Provider of KeyManagerFactory and TrustManagerFactory whose
+ // factories throw exceptions which will make this test fail if the factories are used.
+ Provider provider = new ThrowExceptionKeyAndTrustManagerFactoryProvider();
+ invokeWithHighestPrioritySecurityProvider(provider, new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ assertEquals(
+ ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
+ TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
+ .getProvider().getClass());
+ assertEquals(
+ ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
+ KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
+ .getProvider().getClass());
+
+ KeyManager[] keyManagers = new KeyManager[0];
+ TrustManager[] trustManagers = new TrustManager[0];
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ // Default SSLContext is provided in an already initialized state
+ continue;
+ }
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ sslContext.init(keyManagers, trustManagers, null);
}
- } else {
- sslContext.init(null, null, null);
+
+ return null;
+ }
+ });
+ }
+
+ public void test_SSLContext_init_withoutX509() throws Exception {
+ // Assert that SSLContext.init works fine even when provided with KeyManagers and
+ // TrustManagers which don't include the X.509 ones.
+ // The contract of SSLContext.init is that it will not look for default X.509 KeyManager and
+ // TrustManager.
+ // This test thus installs a Provider of KeyManagerFactory and TrustManagerFactory whose
+ // factories throw exceptions which will make this test fail if the factories are used.
+ Provider provider = new ThrowExceptionKeyAndTrustManagerFactoryProvider();
+ invokeWithHighestPrioritySecurityProvider(provider, new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ assertEquals(
+ ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
+ TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
+ .getProvider().getClass());
+ assertEquals(
+ ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
+ KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
+ .getProvider().getClass());
+
+ KeyManager[] keyManagers = new KeyManager[] {new KeyManager() {}};
+ TrustManager[] trustManagers = new TrustManager[] {new TrustManager() {}};
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ // Default SSLContext is provided in an already initialized state
+ continue;
+ }
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ sslContext.init(keyManagers, trustManagers, null);
+ }
+
+ return null;
+ }
+ });
+ }
+
+ public static class ThrowExceptionKeyAndTrustManagerFactoryProvider extends Provider {
+ public ThrowExceptionKeyAndTrustManagerFactoryProvider() {
+ super("ThrowExceptionKeyAndTrustManagerProvider",
+ 1.0,
+ "SSLContextTest fake KeyManagerFactory and TrustManagerFactory provider");
+
+ put("TrustManagerFactory." + TrustManagerFactory.getDefaultAlgorithm(),
+ ThrowExceptionTrustManagagerFactorySpi.class.getName());
+ put("TrustManagerFactory.PKIX", ThrowExceptionTrustManagagerFactorySpi.class.getName());
+
+ put("KeyManagerFactory." + KeyManagerFactory.getDefaultAlgorithm(),
+ ThrowExceptionKeyManagagerFactorySpi.class.getName());
+ put("KeyManagerFactory.PKIX", ThrowExceptionKeyManagagerFactorySpi.class.getName());
+ }
+ }
+
+ public static class ThrowExceptionTrustManagagerFactorySpi extends TrustManagerFactorySpi {
+ @Override
+ protected void engineInit(KeyStore ks) throws KeyStoreException {
+ fail();
+ }
+
+ @Override
+ protected void engineInit(ManagerFactoryParameters spec)
+ throws InvalidAlgorithmParameterException {
+ fail();
+ }
+
+ @Override
+ protected TrustManager[] engineGetTrustManagers() {
+ throw new AssertionFailedError();
+ }
+ }
+
+ public static class ThrowExceptionKeyManagagerFactorySpi extends KeyManagerFactorySpi {
+ @Override
+ protected void engineInit(KeyStore ks, char[] password) throws KeyStoreException,
+ NoSuchAlgorithmException, UnrecoverableKeyException {
+ fail();
+ }
+
+ @Override
+ protected void engineInit(ManagerFactoryParameters spec)
+ throws InvalidAlgorithmParameterException {
+ fail();
+ }
+
+ @Override
+ protected KeyManager[] engineGetKeyManagers() {
+ throw new AssertionFailedError();
+ }
+ }
+
+ /**
+ * Installs the specified security provider as the highest provider, invokes the provided
+ * {@link Callable}, and removes the provider.
+ *
+ * @return result returned by the {@code callable}.
+ */
+ private static <T> T invokeWithHighestPrioritySecurityProvider(
+ Provider provider, Callable<T> callable) throws Exception {
+ int providerPosition = -1;
+ try {
+ providerPosition = Security.insertProviderAt(provider, 1);
+ assertEquals(1, providerPosition);
+ return callable.call();
+ } finally {
+ if (providerPosition != -1) {
+ Security.removeProvider(provider.getName());
}
}
}
@@ -244,53 +533,6 @@ public class SSLContextTest extends TestCase {
}
}
- public void test_SSLContext_getDefaultSSLParameters() throws Exception {
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- SSLContext sslContext = SSLContext.getInstance(protocol);
- if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- sslContext.init(null, null, null);
- }
-
- SSLParameters p = sslContext.getDefaultSSLParameters();
- assertNotNull(p);
-
- String[] cipherSuites = p.getCipherSuites();
- assertNotNull(cipherSuites);
- StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
-
- String[] protocols = p.getProtocols();
- assertNotNull(protocols);
- StandardNames.assertValidCipherSuites(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
-
- assertFalse(p.getWantClientAuth());
- assertFalse(p.getNeedClientAuth());
- }
- }
-
- public void test_SSLContext_getSupportedSSLParameters() throws Exception {
- for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
- SSLContext sslContext = SSLContext.getInstance(protocol);
- if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
- sslContext.init(null, null, null);
- }
-
- SSLParameters p = sslContext.getSupportedSSLParameters();
- assertNotNull(p);
-
- String[] cipherSuites = p.getCipherSuites();
- assertNotNull(cipherSuites);
- StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
-
- String[] protocols = p.getProtocols();
- assertNotNull(protocols);
- StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS,
- protocols);
-
- assertFalse(p.getWantClientAuth());
- assertFalse(p.getNeedClientAuth());
- }
- }
-
public void test_SSLContextTest_TestSSLContext_create() {
TestSSLContext testContext = TestSSLContext.create();
assertNotNull(testContext);
@@ -298,8 +540,16 @@ public class SSLContextTest extends TestCase {
assertNull(testContext.clientStorePassword);
assertNotNull(testContext.serverKeyStore);
assertEquals(StandardNames.IS_RI, testContext.serverStorePassword != null);
- assertNotNull(testContext.clientKeyManager);
- assertNotNull(testContext.serverKeyManager);
+ assertNotNull(testContext.clientKeyManagers);
+ assertNotNull(testContext.serverKeyManagers);
+ if (testContext.clientKeyManagers.length == 0) {
+ fail("No client KeyManagers");
+ }
+ if (testContext.serverKeyManagers.length == 0) {
+ fail("No server KeyManagers");
+ }
+ assertNotNull(testContext.clientKeyManagers[0]);
+ assertNotNull(testContext.serverKeyManagers[0]);
assertNotNull(testContext.clientTrustManager);
assertNotNull(testContext.serverTrustManager);
assertNotNull(testContext.clientContext);
@@ -309,4 +559,16 @@ public class SSLContextTest extends TestCase {
assertTrue(testContext.port != 0);
testContext.close();
}
+
+ private static void assertContentsInOrder(List<String> expected, String... actual) {
+ if (expected.size() != actual.length) {
+ fail("Unexpected length. Expected len <" + expected.size()
+ + ">, actual len <" + actual.length + ">, expected <" + expected
+ + ">, actual <" + Arrays.asList(actual) + ">");
+ }
+ if (!expected.equals(Arrays.asList(actual))) {
+ fail("Unexpected element(s). Expected <" + expected
+ + ">, actual <" + Arrays.asList(actual) + ">" );
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
index 33a8923..fb7e0c9 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
@@ -17,15 +17,20 @@
package libcore.javax.net.ssl;
import java.io.IOException;
+import java.nio.ByteBuffer;
import java.util.Arrays;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509ExtendedKeyManager;
import junit.framework.TestCase;
import libcore.java.security.StandardNames;
import libcore.java.security.TestKeyStore;
@@ -59,13 +64,15 @@ public class SSLEngineTest extends TestCase {
&& !b.isOutboundDone());
}
- public void test_SSLEngine_getSupportedCipherSuites_names() throws Exception {
+ public void test_SSLEngine_defaultConfiguration() throws Exception {
+ SSLDefaultConfigurationAsserts.assertSSLEngine(
+ TestSSLContext.create().clientContext.createSSLEngine());
+ }
+
+ public void test_SSLEngine_getSupportedCipherSuites_returnsCopies() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLEngine e = c.clientContext.createSSLEngine();
- String[] cipherSuites = e.getSupportedCipherSuites();
- StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES_SSLENGINE,
- cipherSuites);
- assertNotSame(cipherSuites, e.getSupportedCipherSuites());
+ assertNotSame(e.getSupportedCipherSuites(), e.getSupportedCipherSuites());
c.close();
}
@@ -77,105 +84,214 @@ public class SSLEngineTest extends TestCase {
.ca(true)
.build();
test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, false);
- if (StandardNames.IS_RI) {
- test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, true);
- }
+ test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, true);
}
private void test_SSLEngine_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
boolean secureRenegotiation)
throws Exception {
- TestSSLContext c = TestSSLContext.create(testKeyStore, testKeyStore);
+ KeyManager pskKeyManager = PSKKeyManagerProxy.getConscryptPSKKeyManager(
+ new PSKKeyManagerProxy() {
+ @Override
+ protected SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
+ return new SecretKeySpec("Just an arbitrary key".getBytes(), "RAW");
+ }
+ });
+ TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers(
+ testKeyStore, testKeyStore,
+ new KeyManager[] {pskKeyManager}, new KeyManager[] {pskKeyManager});
// Create a TestSSLContext where the KeyManager returns wrong (randomly generated) private
// keys, matching the algorithm and parameters of the correct keys.
// I couldn't find a more elegant way to achieve this other than temporarily replacing the
- // first element of TestKeyStore.keyManagers while invoking TestSSLContext.create.
+ // first X509ExtendedKeyManager element of TestKeyStore.keyManagers while invoking
+ // TestSSLContext.create.
TestSSLContext cWithWrongPrivateKeys;
{
- KeyManager originalKeyManager = testKeyStore.keyManagers[0];
- testKeyStore.keyManagers[0] =
- new RandomPrivateKeyX509ExtendedKeyManager(c.serverKeyManager);
+ // Create a RandomPrivateKeyX509ExtendedKeyManager based on the first
+ // X509ExtendedKeyManager in c.serverKeyManagers.
+ KeyManager randomPrivateKeyX509ExtendedKeyManager = null;
+ for (KeyManager keyManager : c.serverKeyManagers) {
+ if (keyManager instanceof X509ExtendedKeyManager) {
+ randomPrivateKeyX509ExtendedKeyManager =
+ new RandomPrivateKeyX509ExtendedKeyManager((X509ExtendedKeyManager) keyManager);
+ break;
+ }
+ }
+ if (randomPrivateKeyX509ExtendedKeyManager == null) {
+ fail("No X509ExtendedKeyManager in c.serverKeyManagers");
+ }
+
+ // Find the first X509ExtendedKeyManager in testKeyStore.keyManagers
+ int replaceIndex = -1;
+ for (int i = 0; i < testKeyStore.keyManagers.length; i++) {
+ KeyManager keyManager = testKeyStore.keyManagers[i];
+ if (keyManager instanceof X509ExtendedKeyManager) {
+ replaceIndex = i;
+ break;
+ }
+ }
+ if (replaceIndex == -1) {
+ fail("No X509ExtendedKeyManager in testKeyStore.keyManagers");
+ }
+
+ // Temporarily substitute the RandomPrivateKeyX509ExtendedKeyManager in place of the
+ // original X509ExtendedKeyManager.
+ KeyManager originalKeyManager = testKeyStore.keyManagers[replaceIndex];
+ testKeyStore.keyManagers[replaceIndex] = randomPrivateKeyX509ExtendedKeyManager;
cWithWrongPrivateKeys = TestSSLContext.create(testKeyStore, testKeyStore);
- testKeyStore.keyManagers[0] = originalKeyManager;
+ testKeyStore.keyManagers[replaceIndex] = originalKeyManager;
}
+ // To catch all the errors.
+ StringBuilder error = new StringBuilder();
+
String[] cipherSuites = c.clientContext.createSSLEngine().getSupportedCipherSuites();
for (String cipherSuite : cipherSuites) {
- boolean errorExpected = StandardNames.IS_RI && cipherSuite.endsWith("_SHA256");
try {
- /*
- * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on
- * its own, but instead in conjunction with other
- * cipher suites.
- */
- if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)
- || cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
- continue;
- }
- /*
- * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
- * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
- * #KRBRequire
- */
- if (cipherSuite.startsWith("TLS_KRB5_")) {
- continue;
- }
+ // Skip cipher suites that are obsoleted.
+ if (StandardNames.IS_RI && "TLSv1.2".equals(c.clientContext.getProtocol())
+ && StandardNames.CIPHER_SUITES_OBSOLETE_TLS12.contains(cipherSuite)) {
+ continue;
+ }
+ /*
+ * Signaling Cipher Suite Values (SCSV) cannot be used on their own, but instead in
+ * conjunction with other cipher suites.
+ */
+ if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)
+ || cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
+ continue;
+ }
+ /*
+ * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
+ * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
+ * #KRBRequire
+ */
+ if (cipherSuite.startsWith("TLS_KRB5_")) {
+ continue;
+ }
- final String[] cipherSuiteArray
- = (secureRenegotiation
- ? new String[] { cipherSuite,
- StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
- : new String[] { cipherSuite });
+ final String[] cipherSuiteArray
+ = (secureRenegotiation
+ ? new String[] { cipherSuite,
+ StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
+ : new String[] { cipherSuite });
- // Check that handshake succeeds.
- assertConnected(TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
+ // Check that handshake succeeds.
+ TestSSLEnginePair pair = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ client.setEnabledCipherSuites(cipherSuiteArray);
+ server.setEnabledCipherSuites(cipherSuiteArray);
+ }
+ });
+ assertConnected(pair);
+
+ boolean needsRecordSplit =
+ ("TLS".equalsIgnoreCase(c.clientContext.getProtocol())
+ || "SSLv3".equalsIgnoreCase(c.clientContext.getProtocol()))
+ && cipherSuite.contains("_CBC_");
+
+ assertSendsCorrectly("This is the client. Hello!".getBytes(),
+ pair.client, pair.server, needsRecordSplit);
+ assertSendsCorrectly("This is the server. Hi!".getBytes(),
+ pair.server, pair.client, needsRecordSplit);
+
+ // Check that handshake fails when the server does not possess the private key
+ // corresponding to the server's certificate. This is achieved by using SSLContext
+ // cWithWrongPrivateKeys whose KeyManager returns wrong private keys that match
+ // the algorithm (and parameters) of the correct keys.
+ boolean serverAuthenticatedUsingPublicKey = true;
+ if (cipherSuite.contains("_anon_")) {
+ serverAuthenticatedUsingPublicKey = false;
+ } else if ((cipherSuite.startsWith("TLS_PSK_"))
+ || (cipherSuite.startsWith("TLS_ECDHE_PSK_"))) {
+ serverAuthenticatedUsingPublicKey = false;
+ }
+ if (serverAuthenticatedUsingPublicKey) {
+ try {
+ TestSSLEnginePair p = TestSSLEnginePair.create(
+ cWithWrongPrivateKeys, new TestSSLEnginePair.Hooks() {
@Override
void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
client.setEnabledCipherSuites(cipherSuiteArray);
server.setEnabledCipherSuites(cipherSuiteArray);
}
- }));
- assertFalse(errorExpected);
-
- // Check that handshake fails when the server does not possess the private key
- // corresponding to the server's certificate. This is achieved by using SSLContext
- // cWithWrongPrivateKeys whose KeyManager returns wrong private keys that match
- // the algorithm (and parameters) of the correct keys.
- if (!cipherSuite.contains("_anon_")) {
- // The identity of the server is verified only in non-anonymous key exchanges.
- try {
- TestSSLEnginePair p = TestSSLEnginePair.create(
- cWithWrongPrivateKeys, new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- client.setEnabledCipherSuites(cipherSuiteArray);
- server.setEnabledCipherSuites(cipherSuiteArray);
- }
- });
- assertConnected(p);
- fail("Handshake succeeded for " + cipherSuite
- + " despite server not having the correct private key");
- } catch (IOException expected) {}
- }
- } catch (Exception maybeExpected) {
- if (!errorExpected) {
- throw new Exception("Problem trying to connect cipher suite " + cipherSuite,
- maybeExpected);
- }
+ });
+ assertNotConnected(p);
+ } catch (IOException expected) {}
+ }
+ } catch (Exception e) {
+ String message = ("Problem trying to connect cipher suite " + cipherSuite);
+ System.out.println(message);
+ e.printStackTrace();
+ error.append(message);
+ error.append('\n');
}
}
c.close();
+
+ if (error.length() > 0) {
+ throw new Exception("One or more problems in "
+ + "test_SSLEngine_getSupportedCipherSuites_connect:\n" + error);
+ }
+ }
+
+ private static void assertSendsCorrectly(final byte[] sourceBytes, SSLEngine source,
+ SSLEngine dest, boolean needsRecordSplit) throws SSLException {
+ ByteBuffer sourceOut = ByteBuffer.wrap(sourceBytes);
+ SSLSession sourceSession = source.getSession();
+ ByteBuffer sourceToDest = ByteBuffer.allocate(sourceSession.getPacketBufferSize());
+ SSLEngineResult sourceOutRes = source.wrap(sourceOut, sourceToDest);
+ sourceToDest.flip();
+
+ String sourceCipherSuite = source.getSession().getCipherSuite();
+ assertEquals(sourceCipherSuite, sourceBytes.length, sourceOutRes.bytesConsumed());
+ assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+ sourceOutRes.getHandshakeStatus());
+
+ SSLSession destSession = dest.getSession();
+ ByteBuffer destIn = ByteBuffer.allocate(destSession.getApplicationBufferSize());
+
+ int numUnwrapCalls = 0;
+ while (destIn.position() != sourceOut.limit()) {
+ SSLEngineResult destRes = dest.unwrap(sourceToDest, destIn);
+ assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+ destRes.getHandshakeStatus());
+ if (needsRecordSplit && numUnwrapCalls == 0) {
+ assertEquals(sourceCipherSuite, 1, destRes.bytesProduced());
+ }
+ numUnwrapCalls++;
+ }
+
+ destIn.flip();
+ byte[] actual = new byte[destIn.remaining()];
+ destIn.get(actual);
+ assertEquals(sourceCipherSuite, Arrays.toString(sourceBytes), Arrays.toString(actual));
+
+ if (needsRecordSplit) {
+ assertEquals(sourceCipherSuite, 2, numUnwrapCalls);
+ } else {
+ assertEquals(sourceCipherSuite, 1, numUnwrapCalls);
+ }
}
- public void test_SSLEngine_getEnabledCipherSuites() throws Exception {
+ public void test_SSLEngine_getEnabledCipherSuites_returnsCopies() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLEngine e = c.clientContext.createSSLEngine();
- String[] cipherSuites = e.getEnabledCipherSuites();
- StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
- assertNotSame(cipherSuites, e.getEnabledCipherSuites());
+ assertNotSame(e.getEnabledCipherSuites(), e.getEnabledCipherSuites());
c.close();
}
+ public void test_SSLEngine_setEnabledCipherSuites_storesCopy() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.clientContext.createSSLEngine();
+ String[] array = new String[] {e.getEnabledCipherSuites()[0]};
+ String originalFirstElement = array[0];
+ e.setEnabledCipherSuites(array);
+ array[0] = "Modified after having been set";
+ assertEquals(originalFirstElement, e.getEnabledCipherSuites()[0]);
+ }
+
public void test_SSLEngine_setEnabledCipherSuites() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLEngine e = c.clientContext.createSSLEngine();
@@ -199,28 +315,39 @@ public class SSLEngineTest extends TestCase {
e.setEnabledCipherSuites(new String[0]);
e.setEnabledCipherSuites(e.getEnabledCipherSuites());
e.setEnabledCipherSuites(e.getSupportedCipherSuites());
+
+ // Check that setEnabledCipherSuites affects getEnabledCipherSuites
+ String[] cipherSuites = new String[] { e.getSupportedCipherSuites()[0] };
+ e.setEnabledCipherSuites(cipherSuites);
+ assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
+
c.close();
}
- public void test_SSLEngine_getSupportedProtocols() throws Exception {
+ public void test_SSLEngine_getSupportedProtocols_returnsCopies() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLEngine e = c.clientContext.createSSLEngine();
- String[] protocols = e.getSupportedProtocols();
- StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS_SSLENGINE,
- protocols);
- assertNotSame(protocols, e.getSupportedProtocols());
+ assertNotSame(e.getSupportedProtocols(), e.getSupportedProtocols());
c.close();
}
- public void test_SSLEngine_getEnabledProtocols() throws Exception {
+ public void test_SSLEngine_getEnabledProtocols_returnsCopies() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLEngine e = c.clientContext.createSSLEngine();
- String[] protocols = e.getEnabledProtocols();
- StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
- assertNotSame(protocols, e.getEnabledProtocols());
+ assertNotSame(e.getEnabledProtocols(), e.getEnabledProtocols());
c.close();
}
+ public void test_SSLEngine_setEnabledProtocols_storesCopy() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.clientContext.createSSLEngine();
+ String[] array = new String[] {e.getEnabledProtocols()[0]};
+ String originalFirstElement = array[0];
+ e.setEnabledProtocols(array);
+ array[0] = "Modified after having been set";
+ assertEquals(originalFirstElement, e.getEnabledProtocols()[0]);
+ }
+
public void test_SSLEngine_setEnabledProtocols() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLEngine e = c.clientContext.createSSLEngine();
@@ -243,6 +370,22 @@ public class SSLEngineTest extends TestCase {
e.setEnabledProtocols(new String[0]);
e.setEnabledProtocols(e.getEnabledProtocols());
e.setEnabledProtocols(e.getSupportedProtocols());
+
+ // Check that setEnabledProtocols affects getEnabledProtocols
+ for (String protocol : e.getSupportedProtocols()) {
+ if ("SSLv2Hello".equals(protocol)) {
+ try {
+ e.setEnabledProtocols(new String[] { protocol });
+ fail("Should fail when SSLv2Hello is set by itself");
+ } catch (IllegalArgumentException expected) {}
+ } else {
+ String[] protocols = new String[] { protocol };
+ e.setEnabledProtocols(protocols);
+ assertEquals(Arrays.deepToString(protocols),
+ Arrays.deepToString(e.getEnabledProtocols()));
+ }
+ }
+
c.close();
}
@@ -297,17 +440,34 @@ public class SSLEngineTest extends TestCase {
}
public void test_SSLEngine_setUseClientMode() throws Exception {
+ boolean[] finished;
+
// client is client, server is server
- assertConnected(test_SSLEngine_setUseClientMode(true, false));
+ finished = new boolean[2];
+ assertConnected(test_SSLEngine_setUseClientMode(true, false, finished));
+ assertTrue(finished[0]);
+ assertTrue(finished[1]);
// client is server, server is client
- assertConnected(test_SSLEngine_setUseClientMode(false, true));
+ finished = new boolean[2];
+ assertConnected(test_SSLEngine_setUseClientMode(false, true, finished));
+ assertTrue(finished[0]);
+ assertTrue(finished[1]);
// both are client
- assertNotConnected(test_SSLEngine_setUseClientMode(true, true));
+ /*
+ * Our implementation throws an SSLHandshakeException, but RI just
+ * stalls forever
+ */
+ try {
+ assertNotConnected(test_SSLEngine_setUseClientMode(true, true, null));
+ assertTrue(StandardNames.IS_RI);
+ } catch (SSLHandshakeException maybeExpected) {
+ assertFalse(StandardNames.IS_RI);
+ }
// both are server
- assertNotConnected(test_SSLEngine_setUseClientMode(false, false));
+ assertNotConnected(test_SSLEngine_setUseClientMode(false, false, null));
}
public void test_SSLEngine_setUseClientMode_afterHandshake() throws Exception {
@@ -327,7 +487,8 @@ public class SSLEngineTest extends TestCase {
}
private TestSSLEnginePair test_SSLEngine_setUseClientMode(final boolean clientClientMode,
- final boolean serverClientMode)
+ final boolean serverClientMode,
+ final boolean[] finished)
throws Exception {
TestSSLContext c;
if (!clientClientMode && serverClientMode) {
@@ -342,7 +503,7 @@ public class SSLEngineTest extends TestCase {
client.setUseClientMode(clientClientMode);
server.setUseClientMode(serverClientMode);
}
- });
+ }, finished);
}
public void test_SSLEngine_clientAuth() throws Exception {
@@ -440,13 +601,19 @@ public class SSLEngineTest extends TestCase {
}
public void test_SSLEngine_setEnableSessionCreation_server() throws Exception {
- TestSSLEnginePair p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- server.setEnableSessionCreation(false);
- }
- });
- assertNotConnected(p);
+ try {
+ TestSSLEnginePair p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ server.setEnableSessionCreation(false);
+ }
+ });
+ // For some reason, the RI doesn't throw an SSLException.
+ assertTrue(StandardNames.IS_RI);
+ assertNotConnected(p);
+ } catch (SSLException maybeExpected) {
+ assertFalse(StandardNames.IS_RI);
+ }
}
public void test_SSLEngine_setEnableSessionCreation_client() throws Exception {
@@ -470,12 +637,10 @@ public class SSLEngineTest extends TestCase {
assertNotNull(p);
String[] cipherSuites = p.getCipherSuites();
- StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
assertNotSame(cipherSuites, e.getEnabledCipherSuites());
assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
String[] protocols = p.getProtocols();
- StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
assertNotSame(protocols, e.getEnabledProtocols());
assertEquals(Arrays.asList(protocols), Arrays.asList(e.getEnabledProtocols()));
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
new file mode 100644
index 0000000..ea9c3f0
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import javax.net.ssl.SSLServerSocketFactory;
+import junit.framework.TestCase;
+
+public class SSLServerSocketFactoryTest extends TestCase {
+
+ public void testDefaultConfiguration() throws Exception {
+ SSLDefaultConfigurationAsserts.assertSSLServerSocketFactory(
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault());
+ }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
new file mode 100644
index 0000000..59c44c1
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import junit.framework.TestCase;
+import java.util.Arrays;
+
+public class SSLServerSocketTest extends TestCase {
+
+ public void testDefaultConfiguration() throws Exception {
+ SSLDefaultConfigurationAsserts.assertSSLServerSocket(
+ (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket());
+ }
+
+ public void testSetEnabledCipherSuitesAffectsGetter() throws Exception {
+ SSLServerSocket socket =
+ (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+ String[] cipherSuites = new String[] {socket.getSupportedCipherSuites()[0]};
+ socket.setEnabledCipherSuites(cipherSuites);
+ assertEquals(Arrays.asList(cipherSuites), Arrays.asList(socket.getEnabledCipherSuites()));
+ }
+
+ public void testSetEnabledCipherSuitesStoresCopy() throws Exception {
+ SSLServerSocket socket =
+ (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+ String[] array = new String[] {socket.getEnabledCipherSuites()[0]};
+ String originalFirstElement = array[0];
+ socket.setEnabledCipherSuites(array);
+ array[0] = "Modified after having been set";
+ assertEquals(originalFirstElement, socket.getEnabledCipherSuites()[0]);
+ }
+
+ public void testSetEnabledProtocolsAffectsGetter() throws Exception {
+ SSLServerSocket socket =
+ (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+ String[] protocols = new String[] {socket.getSupportedProtocols()[0]};
+ socket.setEnabledProtocols(protocols);
+ assertEquals(Arrays.asList(protocols), Arrays.asList(socket.getEnabledProtocols()));
+ }
+
+ public void testSetEnabledProtocolsStoresCopy() throws Exception {
+ SSLServerSocket socket =
+ (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+ String[] array = new String[] {socket.getEnabledProtocols()[0]};
+ String originalFirstElement = array[0];
+ socket.setEnabledProtocols(array);
+ array[0] = "Modified after having been set";
+ assertEquals(originalFirstElement, socket.getEnabledProtocols()[0]);
+ }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java
index ba048a8..a434d94 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java
@@ -49,7 +49,7 @@ public class SSLSessionTest extends TestCase {
assertNotNull(s.client.getCipherSuite());
assertEquals(s.server.getCipherSuite(),
s.client.getCipherSuite());
- assertTrue(StandardNames.CIPHER_SUITES.contains(s.server.getCipherSuite()));
+ StandardNames.assertValidCipherSuites(new String[] {s.server.getCipherSuite()});
s.close();
}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
index 14a54fd..acf69c0 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
@@ -16,37 +16,212 @@
package libcore.javax.net.ssl;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
-import libcore.java.security.StandardNames;
+import java.security.KeyManagementException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.util.Properties;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
import junit.framework.TestCase;
+import libcore.java.security.StandardNames;
public class SSLSocketFactoryTest extends TestCase {
+ private static final String SSL_PROPERTY = "ssl.SocketFactory.provider";
+
public void test_SSLSocketFactory_getDefault() {
SocketFactory sf = SSLSocketFactory.getDefault();
assertNotNull(sf);
assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
}
- public void test_SSLSocketFactory_getDefaultCipherSuites() {
+ public static class FakeSSLSocketProvider extends Provider {
+ public FakeSSLSocketProvider() {
+ super("FakeSSLSocketProvider", 1.0, "Testing provider");
+ put("SSLContext.Default", FakeSSLContextSpi.class.getName());
+ }
+ }
+
+ public static final class FakeSSLContextSpi extends SSLContextSpi {
+ @Override
+ protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers,
+ SecureRandom secureRandom) throws KeyManagementException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected SSLSocketFactory engineGetSocketFactory() {
+ return new FakeSSLSocketFactory();
+ }
+
+ @Override
+ protected SSLServerSocketFactory engineGetServerSocketFactory() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected SSLEngine engineCreateSSLEngine(String s, int i) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected SSLEngine engineCreateSSLEngine() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected SSLSessionContext engineGetServerSessionContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected SSLSessionContext engineGetClientSessionContext() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public static class FakeSSLSocketFactory extends SSLSocketFactory {
+ public FakeSSLSocketFactory() {
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Socket createSocket(Socket s, String host, int port, boolean autoClose) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+ int localPort) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localHost, int localPort) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public void test_SSLSocketFactory_getDefault_cacheInvalidate() throws Exception {
+ String origProvider = resetSslProvider();
+ try {
+ SocketFactory sf1 = SSLSocketFactory.getDefault();
+ assertNotNull(sf1);
+ assertTrue(SSLSocketFactory.class.isAssignableFrom(sf1.getClass()));
+
+ Provider fakeProvider = new FakeSSLSocketProvider();
+ SocketFactory sf4 = null;
+ SSLContext origContext = null;
+ try {
+ origContext = SSLContext.getDefault();
+ Security.insertProviderAt(fakeProvider, 1);
+ SSLContext.setDefault(SSLContext.getInstance("Default", fakeProvider));
+
+ sf4 = SSLSocketFactory.getDefault();
+ assertNotNull(sf4);
+ assertTrue(SSLSocketFactory.class.isAssignableFrom(sf4.getClass()));
+
+ assertFalse(sf1.getClass() + " should not be " + sf4.getClass(),
+ sf1.getClass().equals(sf4.getClass()));
+ } finally {
+ SSLContext.setDefault(origContext);
+ Security.removeProvider(fakeProvider.getName());
+ }
+
+ SocketFactory sf3 = SSLSocketFactory.getDefault();
+ assertNotNull(sf3);
+ assertTrue(SSLSocketFactory.class.isAssignableFrom(sf3.getClass()));
+
+ assertTrue(sf1.getClass() + " should be " + sf3.getClass(),
+ sf1.getClass().equals(sf3.getClass()));
+
+ if (!StandardNames.IS_RI) {
+ Security.setProperty(SSL_PROPERTY, FakeSSLSocketFactory.class.getName());
+ SocketFactory sf2 = SSLSocketFactory.getDefault();
+ assertNotNull(sf2);
+ assertTrue(SSLSocketFactory.class.isAssignableFrom(sf2.getClass()));
+
+ assertFalse(sf2.getClass().getName() + " should not be " + Security.getProperty(SSL_PROPERTY),
+ sf1.getClass().equals(sf2.getClass()));
+ assertTrue(sf2.getClass().equals(sf4.getClass()));
+
+ resetSslProvider();
+ }
+ } finally {
+ Security.setProperty(SSL_PROPERTY, origProvider);
+ }
+ }
+
+ private String resetSslProvider() {
+ String origProvider = Security.getProperty(SSL_PROPERTY);
+
+ try {
+ Field field_secprops = Security.class.getDeclaredField("secprops");
+ field_secprops.setAccessible(true);
+ Properties secprops = (Properties) field_secprops.get(null);
+ secprops.remove(SSL_PROPERTY);
+
+ Class<?> class_services =
+ Class.forName("org.apache.harmony.security.fortress.Services");
+ Method m_setNeedRefresh = class_services.getMethod("setNeedRefresh");
+ m_setNeedRefresh.invoke(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Cannot find a way to clear out the SocketFactory provider");
+ }
+
+ assertNull(Security.getProperty(SSL_PROPERTY));
+ return origProvider;
+ }
+
+ public void test_SSLSocketFactory_defaultConfiguration() throws Exception {
+ SSLDefaultConfigurationAsserts.assertSSLSocketFactory(
+ (SSLSocketFactory) SSLSocketFactory.getDefault());
+ }
+
+ public void test_SSLSocketFactory_getDefaultCipherSuitesReturnsCopies() {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- String[] cipherSuites = sf.getDefaultCipherSuites();
- StandardNames.assertDefaultCipherSuites(cipherSuites);
- assertNotSame(cipherSuites, sf.getDefaultCipherSuites());
+ assertNotSame(sf.getDefaultCipherSuites(), sf.getDefaultCipherSuites());
}
- public void test_SSLSocketFactory_getSupportedCipherSuites() {
+ public void test_SSLSocketFactory_getSupportedCipherSuitesReturnsCopies() {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- String[] cipherSuites = sf.getSupportedCipherSuites();
- StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
- assertNotSame(cipherSuites, sf.getSupportedCipherSuites());
+ assertNotSame(sf.getSupportedCipherSuites(), sf.getSupportedCipherSuites());
}
public void test_SSLSocketFactory_createSocket() throws Exception {
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index 8e009bd..4681877 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -16,6 +16,7 @@
package libcore.javax.net.ssl;
+import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -33,12 +34,15 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ServerSocketFactory;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.KeyManager;
@@ -56,17 +60,22 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
import junit.framework.TestCase;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
import libcore.java.security.StandardNames;
import libcore.java.security.TestKeyStore;
public class SSLSocketTest extends TestCase {
- public void test_SSLSocket_getSupportedCipherSuites_names() throws Exception {
+ public void test_SSLSocket_defaultConfiguration() throws Exception {
+ SSLDefaultConfigurationAsserts.assertSSLSocket(
+ (SSLSocket) SSLSocketFactory.getDefault().createSocket());
+ }
+
+ public void test_SSLSocket_getSupportedCipherSuites_returnsCopies() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
- String[] cipherSuites = ssl.getSupportedCipherSuites();
- StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
- assertNotSame(cipherSuites, ssl.getSupportedCipherSuites());
+ assertNotSame(ssl.getSupportedCipherSuites(), ssl.getSupportedCipherSuites());
}
public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception {
@@ -77,49 +86,13 @@ public class SSLSocketTest extends TestCase {
.ca(true)
.build();
StringBuilder error = new StringBuilder();
- if (StandardNames.IS_RI) {
- test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
- StandardNames.JSSE_PROVIDER_NAME,
- StandardNames.JSSE_PROVIDER_NAME,
- true,
- true,
- error);
- } else {
- test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
- "HarmonyJSSE",
- "HarmonyJSSE",
- false,
- false,
- error);
- test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
- "AndroidOpenSSL",
- "AndroidOpenSSL",
- true,
- true,
- error);
- test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
- "HarmonyJSSE",
- "AndroidOpenSSL",
- false,
- true,
- error);
- test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
- "AndroidOpenSSL",
- "HarmonyJSSE",
- true,
- false,
- error);
- }
+ test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore, error);
if (error.length() > 0) {
throw new Exception("One or more problems in "
+ "test_SSLSocket_getSupportedCipherSuites_connect:\n" + error);
}
}
private void test_SSLSocket_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
- String clientProvider,
- String serverProvider,
- boolean clientSecureRenegotiation,
- boolean serverSecureRenegotiation,
StringBuilder error)
throws Exception {
@@ -128,20 +101,18 @@ public class SSLSocketTest extends TestCase {
byte[] clientToServer = clientToServerString.getBytes();
byte[] serverToClient = serverToClientString.getBytes();
- TestSSLContext c = TestSSLContext.create(testKeyStore, testKeyStore,
- clientProvider, serverProvider);
- String[] cipherSuites;
- if (clientProvider.equals(serverProvider)) {
- cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
- } else {
- String[] clientSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
- String[] serverSuites = c.serverContext.getSocketFactory().getSupportedCipherSuites();
- Set<String> ccs = new HashSet<String>(Arrays.asList(clientSuites));
- Set<String> scs = new HashSet<String>(Arrays.asList(serverSuites));
- Set<String> cs = new HashSet<String>(ccs);
- cs.retainAll(scs);
- cipherSuites = cs.toArray(new String[cs.size()]);
- }
+ KeyManager pskKeyManager = PSKKeyManagerProxy.getConscryptPSKKeyManager(
+ new PSKKeyManagerProxy() {
+ @Override
+ protected SecretKey getKey(String identityHint, String identity, Socket socket) {
+ return new SecretKeySpec("Just an arbitrary key".getBytes(), "RAW");
+ }
+ });
+ TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers(
+ testKeyStore, testKeyStore,
+ new KeyManager[] {pskKeyManager}, new KeyManager[] {pskKeyManager});
+
+ String[] cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
for (String cipherSuite : cipherSuites) {
boolean errorExpected = StandardNames.IS_RI && cipherSuite.endsWith("_SHA256");
@@ -171,41 +142,48 @@ public class SSLSocketTest extends TestCase {
continue;
}
- String[] clientCipherSuiteArray
- = (clientSecureRenegotiation
- ? new String[] { cipherSuite,
- StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
- : new String[] { cipherSuite });
- String[] serverCipherSuiteArray
- = (serverSecureRenegotiation
- ? new String[] { cipherSuite,
- StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
- : new String[] { cipherSuite });
+ String[] clientCipherSuiteArray = new String[] {
+ cipherSuite,
+ StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION };
+ String[] serverCipherSuiteArray = clientCipherSuiteArray;
SSLSocket[] pair = TestSSLSocketPair.connect(c,
clientCipherSuiteArray,
serverCipherSuiteArray);
SSLSocket server = pair[0];
SSLSocket client = pair[1];
+
+ // Check that the client can read the message sent by the server
server.getOutputStream().write(serverToClient);
+ byte[] clientFromServer = new byte[serverToClient.length];
+ Streams.readFully(client.getInputStream(), clientFromServer);
+ assertEquals(serverToClientString, new String(clientFromServer));
+
+ // Check that the server can read the message sent by the client
client.getOutputStream().write(clientToServer);
- // arrays are too big to make sure we get back only what we expect
- byte[] clientFromServer = new byte[serverToClient.length+1];
- byte[] serverFromClient = new byte[clientToServer.length+1];
- int readFromServer = client.getInputStream().read(clientFromServer);
- int readFromClient = server.getInputStream().read(serverFromClient);
- assertEquals(serverToClient.length, readFromServer);
- assertEquals(clientToServer.length, readFromClient);
- assertEquals(clientToServerString, new String(serverFromClient, 0, readFromClient));
- assertEquals(serverToClientString, new String(clientFromServer, 0, readFromServer));
+ byte[] serverFromClient = new byte[clientToServer.length];
+ Streams.readFully(server.getInputStream(), serverFromClient);
+ assertEquals(clientToServerString, new String(serverFromClient));
+
+ // Check that the server and the client cannot read anything else
+ // (reads should time out)
+ server.setSoTimeout(10);
+ try {
+ server.getInputStream().read();
+ fail();
+ } catch (IOException expected) {}
+ client.setSoTimeout(10);
+ try {
+ client.getInputStream().read();
+ fail();
+ } catch (IOException expected) {}
+
client.close();
server.close();
assertFalse(errorExpected);
} catch (Exception maybeExpected) {
if (!errorExpected) {
- String message = ("Problem trying to connect cipher suite " + cipherSuite
- + " client=" + clientProvider
- + " server=" + serverProvider);
+ String message = ("Problem trying to connect cipher suite " + cipherSuite);
System.out.println(message);
maybeExpected.printStackTrace();
error.append(message);
@@ -216,12 +194,20 @@ public class SSLSocketTest extends TestCase {
c.close();
}
- public void test_SSLSocket_getEnabledCipherSuites() throws Exception {
+ public void test_SSLSocket_getEnabledCipherSuites_returnsCopies() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
- String[] cipherSuites = ssl.getEnabledCipherSuites();
- StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
- assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
+ assertNotSame(ssl.getEnabledCipherSuites(), ssl.getEnabledCipherSuites());
+ }
+
+ public void test_SSLSocket_setEnabledCipherSuites_storesCopy() throws Exception {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket ssl = (SSLSocket) sf.createSocket();
+ String[] array = new String[] {ssl.getEnabledCipherSuites()[0]};
+ String originalFirstElement = array[0];
+ ssl.setEnabledCipherSuites(array);
+ array[0] = "Modified after having been set";
+ assertEquals(originalFirstElement, ssl.getEnabledCipherSuites()[0]);
}
public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
@@ -247,22 +233,33 @@ public class SSLSocketTest extends TestCase {
ssl.setEnabledCipherSuites(new String[0]);
ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
+
+ // Check that setEnabledCipherSuites affects getEnabledCipherSuites
+ String[] cipherSuites = new String[] { ssl.getSupportedCipherSuites()[0] };
+ ssl.setEnabledCipherSuites(cipherSuites);
+ assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
}
- public void test_SSLSocket_getSupportedProtocols() throws Exception {
+ public void test_SSLSocket_getSupportedProtocols_returnsCopies() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
- String[] protocols = ssl.getSupportedProtocols();
- StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
- assertNotSame(protocols, ssl.getSupportedProtocols());
+ assertNotSame(ssl.getSupportedProtocols(), ssl.getSupportedProtocols());
}
- public void test_SSLSocket_getEnabledProtocols() throws Exception {
+ public void test_SSLSocket_getEnabledProtocols_returnsCopies() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
- String[] protocols = ssl.getEnabledProtocols();
- StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
- assertNotSame(protocols, ssl.getEnabledProtocols());
+ assertNotSame(ssl.getEnabledProtocols(), ssl.getEnabledProtocols());
+ }
+
+ public void test_SSLSocket_setEnabledProtocols_storesCopy() throws Exception {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket ssl = (SSLSocket) sf.createSocket();
+ String[] array = new String[] {ssl.getEnabledProtocols()[0]};
+ String originalFirstElement = array[0];
+ ssl.setEnabledProtocols(array);
+ array[0] = "Modified after having been set";
+ assertEquals(originalFirstElement, ssl.getEnabledProtocols()[0]);
}
public void test_SSLSocket_setEnabledProtocols() throws Exception {
@@ -287,6 +284,21 @@ public class SSLSocketTest extends TestCase {
ssl.setEnabledProtocols(new String[0]);
ssl.setEnabledProtocols(ssl.getEnabledProtocols());
ssl.setEnabledProtocols(ssl.getSupportedProtocols());
+
+ // Check that setEnabledProtocols affects getEnabledProtocols
+ for (String protocol : ssl.getSupportedProtocols()) {
+ if ("SSLv2Hello".equals(protocol)) {
+ try {
+ ssl.setEnabledProtocols(new String[] { protocol });
+ fail("Should fail when SSLv2Hello is set by itself");
+ } catch (IllegalArgumentException expected) {}
+ } else {
+ String[] protocols = new String[] { protocol };
+ ssl.setEnabledProtocols(protocols);
+ assertEquals(Arrays.deepToString(protocols),
+ Arrays.deepToString(ssl.getEnabledProtocols()));
+ }
+ }
}
public void test_SSLSocket_getSession() throws Exception {
@@ -394,35 +406,26 @@ public class SSLSocketTest extends TestCase {
SSLContext.getDefault(), SSLContext.getDefault());
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
- // RI used to throw SSLException on accept, now throws on startHandshake
- if (StandardNames.IS_RI) {
- final SSLSocket server = (SSLSocket) c.serverSocket.accept();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Void> future = executor.submit(new Callable<Void>() {
- @Override public Void call() throws Exception {
- try {
- server.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- return null;
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ Future<Void> future = executor.submit(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ try {
+ server.startHandshake();
+ fail();
+ } catch (SSLHandshakeException expected) {
}
- });
- executor.shutdown();
- try {
- client.startHandshake();
- fail();
- } catch (SSLHandshakeException expected) {
- }
- future.get();
- server.close();
- } else {
- try {
- c.serverSocket.accept();
- fail();
- } catch (SSLException expected) {
+ return null;
}
+ });
+ executor.shutdown();
+ try {
+ client.startHandshake();
+ fail();
+ } catch (SSLHandshakeException expected) {
}
+ future.get();
+ server.close();
client.close();
c.close();
}
@@ -526,6 +529,8 @@ public class SSLSocketTest extends TestCase {
assertNotNull(socket);
assertSame(client, socket);
+ assertTrue(socket instanceof SSLSocket);
+
synchronized (handshakeCompletedListenerCalled) {
handshakeCompletedListenerCalled[0] = true;
handshakeCompletedListenerCalled.notify();
@@ -675,7 +680,7 @@ public class SSLSocketTest extends TestCase {
public void test_SSLSocket_setUseClientMode_afterHandshake() throws Exception {
// can't set after handshake
- TestSSLEnginePair pair = TestSSLEnginePair.create(null);
+ TestSSLSocketPair pair = TestSSLSocketPair.create();
try {
pair.server.setUseClientMode(false);
fail();
@@ -699,9 +704,8 @@ public class SSLSocketTest extends TestCase {
@Override public Void call() throws Exception {
try {
server.startHandshake();
- assertFalse(StandardNames.IS_RI);
+ fail();
} catch (SSLHandshakeException expected) {
- assertTrue(StandardNames.IS_RI);
}
return null;
}
@@ -713,9 +717,10 @@ public class SSLSocketTest extends TestCase {
} catch (SSLHandshakeException expected) {
assertTrue(expected.getCause() instanceof CertificateException);
}
+ future.get();
client.close();
server.close();
- future.get();
+ c.close();
}
public void test_SSLSocket_clientAuth() throws Exception {
@@ -846,7 +851,11 @@ public class SSLSocketTest extends TestCase {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(new Callable<Void>() {
@Override public Void call() throws Exception {
- server.startHandshake();
+ try {
+ server.startHandshake();
+ fail();
+ } catch (SSLHandshakeException expected) {
+ }
return null;
}
});
@@ -942,12 +951,10 @@ public class SSLSocketTest extends TestCase {
assertNotNull(p);
String[] cipherSuites = p.getCipherSuites();
- StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
String[] protocols = p.getProtocols();
- StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
assertNotSame(protocols, ssl.getEnabledProtocols());
assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
@@ -1327,10 +1334,7 @@ public class SSLSocketTest extends TestCase {
test_SSLSocket_interrupt_case(true, true);
test_SSLSocket_interrupt_case(true, false);
test_SSLSocket_interrupt_case(false, true);
- // Currently failing due to reader blocking closing thread http://b/10681815
- if (StandardNames.IS_RI) {
- test_SSLSocket_interrupt_case(false, false);
- }
+ test_SSLSocket_interrupt_case(false, false);
}
private void test_SSLSocket_interrupt_case(boolean readUnderlying, boolean closeUnderlying)
@@ -1373,7 +1377,7 @@ public class SSLSocketTest extends TestCase {
/**
* b/7014266 Test to confirm that an SSLSocket.close() on one
- * thread will interupt another thread blocked reading on the same
+ * thread will interrupt another thread blocked reading on the same
* socket.
*/
public void test_SSLSocket_interrupt_read() throws Exception {
@@ -1384,7 +1388,16 @@ public class SSLSocketTest extends TestCase {
c.host.getHostName(),
c.port,
false);
- ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ // Create our own thread group so we can inspect the stack state later.
+ final ThreadGroup clientGroup = new ThreadGroup("client");
+ ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(clientGroup, r);
+ }
+ });
+
Future<Void> clientFuture = executor.submit(new Callable<Void>() {
@Override public Void call() throws Exception {
try {
@@ -1402,6 +1415,26 @@ public class SSLSocketTest extends TestCase {
SSLSocket server = (SSLSocket) c.serverSocket.accept();
server.startHandshake();
+
+ /*
+ * Wait for the client to at least be in the "read" method before
+ * calling close()
+ */
+ Thread[] threads = new Thread[1];
+ clientGroup.enumerate(threads);
+ if (threads[0] != null) {
+ boolean clientInRead = false;
+ while (!clientInRead) {
+ StackTraceElement[] elements = threads[0].getStackTrace();
+ for (StackTraceElement element : elements) {
+ if ("read".equals(element.getMethodName())) {
+ clientInRead = true;
+ break;
+ }
+ }
+ }
+ }
+
wrapping.close();
clientFuture.get();
server.close();
@@ -1423,6 +1456,120 @@ public class SSLSocketTest extends TestCase {
test.close();
}
+ public void test_SSLSocket_ClientHello_size() throws Exception {
+ // This test checks the size of ClientHello of the default SSLSocket. TLS/SSL handshakes
+ // with older/unpatched F5/BIG-IP appliances are known to stall and time out when
+ // the fragment containing ClientHello is between 256 and 511 (inclusive) bytes long.
+ //
+ // Since there's no straightforward way to obtain a ClientHello from SSLSocket, this test
+ // does the following:
+ // 1. Creates a listening server socket (a plain one rather than a TLS/SSL one).
+ // 2. Creates a client SSLSocket, which connects to the server socket and initiates the
+ // TLS/SSL handshake.
+ // 3. Makes the server socket accept an incoming connection on the server socket, and reads
+ // the first chunk of data received. This chunk is assumed to be the ClientHello.
+ // NOTE: Steps 2 and 3 run concurrently.
+ ServerSocket listeningSocket = null;
+ ExecutorService executorService = Executors.newFixedThreadPool(2);
+
+ // Some Socket operations are not interruptible via Thread.interrupt for some reason. To
+ // work around, we unblock these sockets using Socket.close.
+ final Socket[] sockets = new Socket[2];
+ try {
+ // 1. Create the listening server socket.
+ listeningSocket = ServerSocketFactory.getDefault().createServerSocket(0);
+ final ServerSocket finalListeningSocket = listeningSocket;
+ // 2. (in background) Wait for an incoming connection and read its first chunk.
+ final Future<byte[]> readFirstReceivedChunkFuture =
+ executorService.submit(new Callable<byte[]>() {
+ @Override
+ public byte[] call() throws Exception {
+ Socket socket = finalListeningSocket.accept();
+ sockets[1] = socket;
+ try {
+ byte[] buffer = new byte[64 * 1024];
+ int bytesRead = socket.getInputStream().read(buffer);
+ if (bytesRead == -1) {
+ throw new EOFException("Failed to read anything");
+ }
+ return Arrays.copyOf(buffer, bytesRead);
+ } finally {
+ IoUtils.closeQuietly(socket);
+ }
+ }
+ });
+
+ // 3. Create a client socket, connect it to the server socket, and start the TLS/SSL
+ // handshake.
+ executorService.submit(new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, null);
+ SSLSocket client = (SSLSocket) sslContext.getSocketFactory().createSocket();
+ sockets[0] = client;
+ try {
+ // Enable SNI extension on the socket (this is typically enabled by default)
+ // to increase the size of ClientHello.
+ try {
+ Method setHostname =
+ client.getClass().getMethod("setHostname", String.class);
+ setHostname.invoke(client, "sslsockettest.androidcts.google.com");
+ } catch (NoSuchMethodException ignored) {}
+
+ // Enable Session Tickets extension on the socket (this is typically enabled
+ // by default) to increase the size of ClientHello.
+ try {
+ Method setUseSessionTickets =
+ client.getClass().getMethod(
+ "setUseSessionTickets", boolean.class);
+ setUseSessionTickets.invoke(client, true);
+ } catch (NoSuchMethodException ignored) {}
+
+ client.connect(finalListeningSocket.getLocalSocketAddress());
+ // Initiate the TLS/SSL handshake which is expected to fail as soon as the
+ // server socket receives a ClientHello.
+ try {
+ client.startHandshake();
+ fail();
+ return null;
+ } catch (IOException expected) {}
+ return null;
+ } finally {
+ IoUtils.closeQuietly(client);
+
+ // Cancel the reading task. If this task succeeded, then the reading task
+ // is done and this will have no effect. If this task failed prematurely,
+ // then the reading task might get unblocked (we're interrupting the thread
+ // it's running on), will fail early, and we'll thus save some time in this
+ // test.
+ readFirstReceivedChunkFuture.cancel(true);
+ }
+ }
+ });
+
+ // Wait for the ClientHello to arrive
+ byte[] clientHello = readFirstReceivedChunkFuture.get(10, TimeUnit.SECONDS);
+
+ // Check for ClientHello length that may cause handshake to fail/time out with older
+ // F5/BIG-IP appliances.
+ assertEquals("TLS record type: handshake", 22, clientHello[0]);
+ int fragmentLength = ((clientHello[3] & 0xff) << 8) | (clientHello[4] & 0xff);
+ if ((fragmentLength >= 256) && (fragmentLength <= 511)) {
+ fail("Fragment containing ClientHello is of dangerous length: "
+ + fragmentLength + " bytes");
+ }
+ } finally {
+ executorService.shutdownNow();
+ IoUtils.closeQuietly(listeningSocket);
+ IoUtils.closeQuietly(sockets[0]);
+ IoUtils.closeQuietly(sockets[1]);
+ if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
+ fail("Timed out while waiting for the test to shut down");
+ }
+ }
+ }
+
public void test_SSLSocket_sendsTlsFallbackScsv_Fallback_Success() throws Exception {
TestSSLContext context = TestSSLContext.create();
@@ -1461,6 +1608,42 @@ public class SSLSocketTest extends TestCase {
context.close();
}
+ // Confirms that communication without the TLS_FALLBACK_SCSV cipher works as it always did.
+ public void test_SSLSocket_sendsNoTlsFallbackScsv_Fallback_Success() throws Exception {
+ TestSSLContext context = TestSSLContext.create();
+
+ final SSLSocket client = (SSLSocket)
+ context.clientContext.getSocketFactory().createSocket(context.host, context.port);
+ final SSLSocket server = (SSLSocket) context.serverSocket.accept();
+
+ // Confirm absence of TLS_FALLBACK_SCSV.
+ assertFalse(Arrays.asList(client.getEnabledCipherSuites())
+ .contains(StandardNames.CIPHER_SUITE_FALLBACK));
+
+ ExecutorService executor = Executors.newFixedThreadPool(2);
+ Future<Void> s = executor.submit(new Callable<Void>() {
+ public Void call() throws Exception {
+ server.setEnabledProtocols(new String[] { "TLSv1", "SSLv3" });
+ server.startHandshake();
+ return null;
+ }
+ });
+ Future<Void> c = executor.submit(new Callable<Void>() {
+ public Void call() throws Exception {
+ client.setEnabledProtocols(new String[] { "SSLv3" });
+ client.startHandshake();
+ return null;
+ }
+ });
+ executor.shutdown();
+
+ s.get();
+ c.get();
+ client.close();
+ server.close();
+ context.close();
+ }
+
public void test_SSLSocket_sendsTlsFallbackScsv_InappropriateFallback_Failure() throws Exception {
TestSSLContext context = TestSSLContext.create();
@@ -1469,6 +1652,8 @@ public class SSLSocketTest extends TestCase {
final SSLSocket server = (SSLSocket) context.serverSocket.accept();
final String[] serverCipherSuites = server.getEnabledCipherSuites();
+
+ // Add TLS_FALLBACK_SCSV
final String[] clientCipherSuites = new String[serverCipherSuites.length + 1];
System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length);
clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK;
diff --git a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
index 7ee5778..571aa9c 100644
--- a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
+++ b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
@@ -57,20 +57,21 @@ public class X500PrincipalTest extends TestCase {
*/
public void testGetName() throws Exception {
CertificateFactory certFactBC = CertificateFactory.getInstance("X.509", "BC");
- CertificateFactory certFactDRL = CertificateFactory.getInstance("X.509", "DRLCertFactory");
+ CertificateFactory certFactOpenSSL = CertificateFactory.getInstance("X.509",
+ "AndroidOpenSSL");
X509Certificate certBC = (X509Certificate)
certFactBC.generateCertificate(new ByteArrayInputStream(T61STRING_CERT));
- X509Certificate certDRL = (X509Certificate)
- certFactDRL.generateCertificate(new ByteArrayInputStream(T61STRING_CERT));
+ X509Certificate certOpenSSL = (X509Certificate)
+ certFactOpenSSL.generateCertificate(new ByteArrayInputStream(T61STRING_CERT));
- assertEquals(certBC, certDRL);
+ assertEquals(certBC, certOpenSSL);
assertEquals(certBC.getSubjectX500Principal(), certBC.getSubjectX500Principal());
- assertEquals(certDRL.getIssuerX500Principal(), certDRL.getIssuerX500Principal());
+ assertEquals(certOpenSSL.getIssuerX500Principal(), certOpenSSL.getIssuerX500Principal());
- assertEquals(certBC.getSubjectX500Principal(), certDRL.getSubjectX500Principal());
- assertEquals(certBC.getIssuerX500Principal(), certDRL.getIssuerX500Principal());
+ assertEquals(certBC.getSubjectX500Principal(), certOpenSSL.getSubjectX500Principal());
+ assertEquals(certBC.getIssuerX500Principal(), certOpenSSL.getIssuerX500Principal());
String[] formats = {
X500Principal.CANONICAL,
@@ -79,9 +80,9 @@ public class X500PrincipalTest extends TestCase {
};
for (String format : formats) {
assertEquals(certBC.getSubjectX500Principal().getName(format),
- certDRL.getSubjectX500Principal().getName(format));
+ certOpenSSL.getSubjectX500Principal().getName(format));
assertEquals(certBC.getIssuerX500Principal().getName(format),
- certDRL.getIssuerX500Principal().getName(format));
+ certOpenSSL.getIssuerX500Principal().getName(format));
}
String expected = ""
+ "cn=entrust.net certification authority (2048),"
diff --git a/luni/src/test/java/libcore/net/MimeUtilsTest.java b/luni/src/test/java/libcore/net/MimeUtilsTest.java
new file mode 100644
index 0000000..36476e9
--- /dev/null
+++ b/luni/src/test/java/libcore/net/MimeUtilsTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net;
+
+import junit.framework.TestCase;
+
+import libcore.net.MimeUtils;
+
+public class MimeUtilsTest extends TestCase {
+ public void test_15715370() {
+ assertEquals("audio/flac", MimeUtils.guessMimeTypeFromExtension("flac"));
+ assertEquals("flac", MimeUtils.guessExtensionFromMimeType("audio/flac"));
+ assertEquals("flac", MimeUtils.guessExtensionFromMimeType("application/x-flac"));
+ }
+
+ public void test_16978217() {
+ assertEquals("image/x-ms-bmp", MimeUtils.guessMimeTypeFromExtension("bmp"));
+ assertEquals("image/x-icon", MimeUtils.guessMimeTypeFromExtension("ico"));
+ assertEquals("video/mp2ts", MimeUtils.guessMimeTypeFromExtension("ts"));
+ }
+
+ public void testCommon() {
+ assertEquals("audio/mpeg", MimeUtils.guessMimeTypeFromExtension("mp3"));
+ assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("png"));
+ assertEquals("application/zip", MimeUtils.guessMimeTypeFromExtension("zip"));
+
+ assertEquals("mp3", MimeUtils.guessExtensionFromMimeType("audio/mpeg"));
+ assertEquals("png", MimeUtils.guessExtensionFromMimeType("image/png"));
+ assertEquals("zip", MimeUtils.guessExtensionFromMimeType("application/zip"));
+ }
+}
diff --git a/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java b/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java
new file mode 100644
index 0000000..dc32da6
--- /dev/null
+++ b/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.event;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link NetworkEventDispatcher}.
+ */
+public class NetworkEventDispatcherTest extends TestCase {
+
+ public void testGetInstance_isSingleton() {
+ assertSame(NetworkEventDispatcher.getInstance(), NetworkEventDispatcher.getInstance());
+ }
+
+ public void testAddListener_null() throws Exception {
+ NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+ try {
+ networkEventDispatcher.addListener(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testOnNetworkConfigurationChanged_noListeners() throws Exception {
+ NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+ networkEventDispatcher.onNetworkConfigurationChanged();
+ }
+
+ public void testFireNetworkEvent_oneListener() throws Exception {
+ FakeNetworkEventListener listener = new FakeNetworkEventListener();
+ NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+ networkEventDispatcher.addListener(listener);
+
+ networkEventDispatcher.onNetworkConfigurationChanged();
+
+ listener.assertNetworkConfigurationChangedEvent(1);
+ }
+
+ public void testRemoveEventListener() throws Exception {
+ FakeNetworkEventListener listener = new FakeNetworkEventListener();
+ NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+ networkEventDispatcher.addListener(listener);
+ networkEventDispatcher.removeListener(listener);
+
+ networkEventDispatcher.onNetworkConfigurationChanged();
+
+ listener.assertNetworkConfigurationChangedEvent(0);
+ }
+
+ private static class FakeNetworkEventListener extends NetworkEventListener {
+
+ private int networkConfigurationChangedCount;
+
+ @Override
+ public void onNetworkConfigurationChanged() {
+ networkConfigurationChangedCount++;
+ }
+
+ public void assertNetworkConfigurationChangedEvent(int expectedCount) {
+ assertEquals(expectedCount, networkConfigurationChangedCount);
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/reflect/InternalNamesTest.java b/luni/src/test/java/libcore/reflect/InternalNamesTest.java
new file mode 100644
index 0000000..bb305ff
--- /dev/null
+++ b/luni/src/test/java/libcore/reflect/InternalNamesTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.reflect;
+
+import junit.framework.TestCase;
+
+public final class InternalNamesTest extends TestCase {
+ private final ClassLoader loader = InternalNames.class.getClassLoader();
+
+ public void testGetClassNull() {
+ try {
+ InternalNames.getClass(loader, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testGetInternalNameNull() {
+ try {
+ InternalNames.getInternalName(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testInternalNameToPrimitive() {
+ assertEquals(byte.class, InternalNames.getClass(loader, "B"));
+ assertEquals(char.class, InternalNames.getClass(loader, "C"));
+ assertEquals(double.class, InternalNames.getClass(loader, "D"));
+ assertEquals(float.class, InternalNames.getClass(loader, "F"));
+ assertEquals(int.class, InternalNames.getClass(loader, "I"));
+ assertEquals(long.class, InternalNames.getClass(loader, "J"));
+ assertEquals(short.class, InternalNames.getClass(loader, "S"));
+ assertEquals(boolean.class, InternalNames.getClass(loader, "Z"));
+ assertEquals(void.class, InternalNames.getClass(loader, "V"));
+ }
+
+ public void testPrimitiveToInternalName() {
+ assertEquals("B", InternalNames.getInternalName(byte.class));
+ assertEquals("C", InternalNames.getInternalName(char.class));
+ assertEquals("D", InternalNames.getInternalName(double.class));
+ assertEquals("F", InternalNames.getInternalName(float.class));
+ assertEquals("I", InternalNames.getInternalName(int.class));
+ assertEquals("J", InternalNames.getInternalName(long.class));
+ assertEquals("S", InternalNames.getInternalName(short.class));
+ assertEquals("Z", InternalNames.getInternalName(boolean.class));
+ assertEquals("V", InternalNames.getInternalName(void.class));
+ }
+
+ public void testInternalNameToClass() {
+ assertEquals(String.class, InternalNames.getClass(loader, "Ljava/lang/String;"));
+ }
+
+ public void testClassToInternalName() {
+ assertEquals("Ljava/lang/String;", InternalNames.getInternalName(String.class));
+ }
+
+ public void testInternalNameToPrimitiveArray() {
+ assertEquals(int[].class, InternalNames.getClass(loader, "[I"));
+ assertEquals(int[][][][].class, InternalNames.getClass(loader, "[[[[I"));
+ }
+
+ public void testInternalNameToObjectArray() {
+ assertEquals(String[].class, InternalNames.getClass(loader, "[Ljava/lang/String;"));
+ assertEquals(String[][][][].class,
+ InternalNames.getClass(loader, "[[[[Ljava/lang/String;"));
+ }
+}
diff --git a/luni/src/test/java/libcore/sqlite/AbstractSqlTest.java b/luni/src/test/java/libcore/sqlite/AbstractSqlTest.java
deleted file mode 100644
index d194548..0000000
--- a/luni/src/test/java/libcore/sqlite/AbstractSqlTest.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import SQLite.Exception;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import junit.framework.TestCase;
-
-
-/**
- * This class provides SQL unit test, which can be used by subclasses eg. to
- * test JDBC drivers.
- */
-abstract class AbstractSqlTest extends TestCase {
-
- /**
- * The first connection.
- */
- private Connection firstConnection;
-
- /**
- * The second connection.
- */
- private Connection secondConnection;
-
- /**
- * The statement from the first connection.
- */
- private Statement firstStmt;
-
- /**
- * The statement from the second connection.
- */
- private Statement secondStmt;
-
- /**
- * The values of the first column "one".
- */
- private final String[] ones = {"hello!", "goodbye"};
-
- /**
- * The values of the second column "two".
- */
- private final short[] twos = {10, 20};
-
- /**
- * The updated values of the first column "one".
- */
- private final String[] ones_updated;
-
- /** Creates a new instance of this class */
- public AbstractSqlTest() {
- super();
- ones_updated = new String[ones.length];
- for (int i = 0; i < ones.length; i++) {
- ones_updated[i] = ones[i] + twos[i];
- }
- }
-
- /**
- * Sets up a unit test, by creating two statements from two connections and
- * creating a test table.
- *
- * @exception SQLException if there is a problem accessing the database
- * @throws Exception
- * @exception Exception may be thrown by subclasses
- */
- @Override
- protected void setUp() throws java.lang.Exception {
- Class.forName(getDriverClassName()).newInstance();
- firstConnection = DriverManager.getConnection(getConnectionURL());
- firstConnection.setTransactionIsolation(getTransactionIsolation());
- secondConnection = DriverManager.getConnection(getConnectionURL());
- secondConnection.setTransactionIsolation(getTransactionIsolation());
- firstStmt = firstConnection.createStatement();
- firstStmt.execute("create table tbl1(one varchar(10), two smallint)");
- secondStmt = secondConnection.createStatement();
- }
-
- /**
- * Tears down a unit test, by setting the auto commit property of the first
- * connection back to true, dropping the test table and closing the two
- * connections.
- */
- @Override
- protected void tearDown() throws SQLException {
- firstStmt.close();
- secondStmt.close();
- firstConnection.setAutoCommit(true);
- firstStmt = firstConnection.createStatement();
- firstStmt.execute("drop table tbl1");
- firstStmt.close();
- firstConnection.close();
- secondConnection.close();
- }
-
- /**
- * Adds some rows to the test table and asserts that the rows can be
- * retrieved again.
- *
- * @throws SQLException if there is a problem accessing the database
- */
- private void autoCommitInsertSelect() throws SQLException {
- firstStmt.getConnection().setAutoCommit(true);
- for (int i = 0; i < ones.length; i++) {
- firstStmt.execute("insert into tbl1 values('" + ones[i] + "',"
- + twos[i] + ")");
- }
- assertAllFromTbl1(firstStmt, ones, twos);
- }
-
- /**
- * Asserts that the expected values can be selected from the test table.
- *
- * @param stmt the statement to be used for the selection of the data
- * @param ones the expected values of the column 'one'
- * @param twos the expected values of the column 'two'
- * @throws SQLException if there is a problem accessing the database
- */
- private void assertAllFromTbl1(Statement stmt, String[] ones, short[] twos)
- throws SQLException {
- ResultSet rs = stmt.executeQuery("select * from tbl1");
- int i = 0;
- for (; rs.next(); i++) {
- assertTrue(i < ones.length);
- assertEquals(ones[i], rs.getString("one"));
- assertEquals(twos[i], rs.getShort("two"));
- }
- assertTrue(i == ones.length);
- }
-
- public void testAutoCommitInsertSelect() throws SQLException{
- autoCommitInsertSelect();
- }
-
- /**
- * Tests the following sequence after successful insertion of some test
- * data:
- * - update data from connection one
- * - select data from connection two (-> should have the old values)
- * - commit data from connection one
- * - select data from connection two (-> should have the new values)
- *
- * @throws SQLException if there is a problem accessing the database
- */
- public void testUpdateSelectCommitSelect() throws SQLException {
- autoCommitInsertSelect();
- firstStmt.getConnection().setAutoCommit(false);
- updateOnes(firstStmt, ones_updated, twos);
- assertAllFromTbl1(secondStmt, ones, twos);
- firstStmt.getConnection().commit();
- assertAllFromTbl1(secondStmt, ones_updated, twos);
- }
-
- /**
- * Tests the following sequence after successful insertion of some test
- * data:
- * - update data from connection one
- * - select data from connection two (-> should have the old values)
- * - rollback data from connection one
- * - select data from connection two (-> should still have the old values)
- *
- * @throws SQLException if there is a problem accessing the database
- */
- public void testUpdateSelectRollbackSelect() throws SQLException {
- autoCommitInsertSelect();
- firstStmt.getConnection().setAutoCommit(false);
- updateOnes(firstStmt, ones_updated, twos);
- assertAllFromTbl1(secondStmt, ones, twos);
- firstStmt.getConnection().rollback();
- assertAllFromTbl1(secondStmt, ones, twos);
- }
-
- /**
- * Updates the values in column 'one'
- * @param stmt the statement to be used to update the data
- * @param ones_updated the updated valus of column 'one'
- * @param twos the reference values of column 'two'
- * @throws SQLException if there is a problem accessing the database
- */
- private void updateOnes(Statement stmt, String[] ones_updated, short[] twos)
- throws SQLException {
- for (int i = 0; i < ones_updated.length; i++) {
- stmt.execute("UPDATE tbl1 SET one = '" + ones_updated[i]
- + "' WHERE two = " + twos[i]);
- }
- }
-
- protected abstract String getConnectionURL();
-
- protected abstract String getDriverClassName();
-
- protected abstract int getTransactionIsolation();
-
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldBlobTest.java b/luni/src/test/java/libcore/sqlite/OldBlobTest.java
deleted file mode 100644
index 3289d38..0000000
--- a/luni/src/test/java/libcore/sqlite/OldBlobTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import SQLite.Blob;
-import SQLite.Database;
-import SQLite.Exception;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import tests.support.Support_SQL;
-
-public final class OldBlobTest extends OldSQLiteTest {
-
- private static Blob testBlob = null;
-
- private static Database db = null;
-
- public void setUp() throws java.lang.Exception {
- super.setUp();
- testBlob = new Blob();
-
- super.setUp();
- Support_SQL.loadDriver();
- db = new Database();
- db.open(dbFile.getPath(), 0);
-
- db.exec("create table B(id integer primary key, val blob)",null);
- db.exec("insert into B values(1, zeroblob(128))", null);
- db.exec("insert into B values(2, zeroblob(128))", null);
- db.exec("insert into B values(3, zeroblob(128))", null);
-
- // can not fill Blob with data at this point...
- /*
- File resources = Support_Resources.createTempFolder();
- BufferedReader r = null;
- try {
- Class c = Class.forName(this.getClass().getName());
- assertNotNull(c);
- file = Class.forName(this.getClass().getName())
- .getResourceAsStream("/blob.c");
- r = new BufferedReader(new InputStreamReader(file));
- } catch (NullPointerException e) {
- fail("Should not throw NullPointerException reading file"
- + e.getMessage());
- }
- OutputStream out = testBlob.getOutputStream();
- String s = null;
- while ((s = r.readLine()) != null) {
- out.write(r.readLine().getBytes());
- }
- out.flush();
- out.close();
- testBlob.close();
- */
- }
-
- @Override public void tearDown() throws java.lang.Exception {
- testBlob.close();
- super.tearDown();
- }
-
- /**
- * db.open_blob is not supported.
- */
- public void testBlob() throws Exception, IOException {
- byte[] b = new byte[4];
- byte[] b128 = new byte[128];
- for (int i = 0; i < b128.length; i++) {
- b128[i] = (byte) i;
- }
- Blob blob = db.open_blob(dbFile.getPath(), "B", "val", 1, true);
- try {
-
- OutputStream os = blob.getOutputStream();
- os.write(b128);
- os.close();
-
- InputStream is = blob.getInputStream();
- is.skip(96);
- assertEquals(4,is.read(b));
- is.close();
- } finally {
- blob.close();
- }
- }
-
- public void testGetInputStream() {
- InputStream in = testBlob.getInputStream();
- try {
- in.read();
- fail("Exception not thrown for invalid Blob.");
- } catch (Throwable e) {
- //ok
- }
- }
-
- public void testGetOutputStream() {
- OutputStream out = testBlob.getOutputStream();
-
- try {
- out.write(null);
- fail("Write operation unsupported");
- } catch (Throwable e) {
- assertEquals("Write operation unsupported", e.getMessage());
- }
- }
-
- public void testClose() {
- assertNotNull(testBlob);
-
- testBlob.close();
- // inputStream either null or some error occurs
- try {
- // TODO This does look a bit weird. Revisit later.
- assertNull(testBlob.getInputStream());
- } catch (Throwable e) {
- //ok
- }
- }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldDatabaseTest.java b/luni/src/test/java/libcore/sqlite/OldDatabaseTest.java
deleted file mode 100644
index f2cbc57..0000000
--- a/luni/src/test/java/libcore/sqlite/OldDatabaseTest.java
+++ /dev/null
@@ -1,1224 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import SQLite.Authorizer;
-import SQLite.Blob;
-import SQLite.BusyHandler;
-import SQLite.Callback;
-import SQLite.Constants;
-import SQLite.Database;
-import SQLite.Exception;
-import SQLite.Function;
-import SQLite.FunctionContext;
-import SQLite.ProgressHandler;
-import SQLite.Stmt;
-import SQLite.TableResult;
-import SQLite.Trace;
-import SQLite.Vm;
-import java.io.File;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.logging.Logger;
-import tests.support.DatabaseCreator;
-import tests.support.MockFunction;
-import tests.support.ThreadPool;
-
-public final class OldDatabaseTest extends OldSQLiteTest {
-
- private static ErrorTracker tracker = null;
-
- private Statement statement;
-
- private Database db = null;
-
- private static final int numThreads = 10;
-
- private static final int numOfRecords = 30;
-
- @Override public void setUp() throws java.lang.Exception {
- super.setUp();
- assertNotNull("Could not establish DB connection",conn);
- tracker = new ErrorTracker();
-
- statement = conn.createStatement();
-
- // Cleanup tables if necessary
-
- DatabaseMetaData meta = conn.getMetaData();
- assertNotNull(meta);
- ResultSet userTab = meta.getTables(null, null, null, null);
- while (userTab.next()) {
- String tableName = userTab.getString("TABLE_NAME");
- this.statement.execute("drop table " + tableName);
- }
-
- // Create default test table
- statement.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1);
- statement.close();
-
- db = new Database();
- db.open(dbFile.getPath(), 0);
- db.busy_handler(null);
- }
-
- public void tearDown() throws java.lang.Exception {
- try {
- db.close();
- } catch (Exception e) {
- if (!(e.getMessage().equals("database already closed"))) {
- System.err.println("Error closing DB " + dbFile.getPath());
- }
- }
- tracker.reset();
- super.tearDown();
- }
-
- public void testDatabase() throws Exception {
- // db closed
- Database db2 = new Database();
- db.close();
- db2 = new Database();
- db2.open(dbFile.getPath(), 0);
- db2.close();
- db.open(dbFile.getPath(), 0);
- //db is open
- db2.open(dbFile.getPath(), 0);
- db2.close();
- }
-
- public void testOpen() throws Exception {
- db.close();
- db.open(dbFile.getPath(), 0);
- // open second db while db1 still open
- Database db2 = new Database();
- db2.open(dbFile.getPath(), 0);
- db2.open(dbFile.getPath(), 0);
- db2.close();
- // open non db file
- try {
- URL file = OldDatabaseTest.class.getResource("/blob.c");
- db2.open(file.getPath(), 0);
- fail("Should not be able to open non db file");
- } catch (SQLite.Exception e) {
- assertEquals("unknown error in open", e.getMessage());
- }
- }
-
- public void testOpen_aux_file() {
- File temp = null;
- try {
- db.open_aux_file("");
- fail("open should fail");
- } catch (Exception e) {
- assertEquals("unsupported", e.getMessage());
- }
-
- /*
- try {
- temp = File.createTempFile("openAuxMethod", ".db");
- db.open_aux_file("");
- db.exec("create table AUX_TABLE", null);
- db.close();
- } catch (Exception e) {
- temp.delete();
- fail("Error handling temporary file "+e.getMessage());
- e.printStackTrace();
- } catch (IOException e) {
- temp.delete();
- fail("Could not create temporary File");
- e.printStackTrace();
- }
- try {
- db.open(dbFile.getPath(),0);
- db.exec("select * from AUX_TABLE", null);
- fail("Statement should fail");
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- temp.delete();
- */
- }
-
- public void testClose() throws Exception {
- try {
- db.close();
- db.get_table("test");
- fail();
- } catch (Exception e) {
- assertTrue(e.getMessage().equals("database already closed"));
- try {
- db.open(dbFile.getPath(), 0);
- } catch (Exception e1) {
- fail("Database object could not be reopened after 'close': "
- + e.getMessage());
- e1.printStackTrace();
- }
- }
-
- try {
- db.close();
- db.close();
- fail();
- } catch (Exception e) {
- assertTrue(e.getMessage().equals("database already closed"));
- db.open(dbFile.getPath(), 0);
- }
- }
-
- public void testExecStringCallback() throws Exception {
- TableResult res = new TableResult();
- db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " VALUES(1, 10, 20)", null);
- db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
- db.exec("delete from " + DatabaseCreator.SIMPLE_TABLE1 + " where 1", null);
- String row[] = (String[]) res.rows.elementAt(0);
- assertEquals(Integer.parseInt(row[0]), 1);
- assertEquals(Integer.parseInt(row[1]), 10);
- assertEquals(Integer.parseInt(row[2]), 20);
- }
-
- public void testExecStringCallbackStringArray() throws Exception {
- TableResult res = new TableResult();
- String args[] = new String[1];
- args[0] = "table";
- db.exec("select name from sqlite_master where type = '%q';", res, args);
- String[] s = (String[]) res.rows.elementAt(0);
- assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
-
- try {
- db.exec("select name from sqlite_master where type = ", res, args);
- fail("Testmethod should fail");
- } catch (Exception e) {
- // Ok
- }
- }
-
- public void testLast_insert_rowid() throws Exception {
- assertEquals(0, db.last_insert_rowid());
- db.exec("create table TEST5(id integer, firstname text, lastname text);", null);
- db.exec("insert into TEST5 values (1,'James','Bond');", null);
- db.exec("insert into TEST5 values (2,'Fiona','Apple');", null);
- assertEquals(2, db.last_insert_rowid());
- assertEquals(db.last_insert_rowid(), db.last_insert_rowid());
-
- db.exec("drop table TEST5;", null);
- assertEquals(2, db.last_insert_rowid());
- }
-
- /**
- * Reason for failure unknown: Database should be locked. Specification
- * of interrupt is scarce.
- */
- public void testInterrupt() throws Exception, SQLException {
- ThreadPool threadPool = new ThreadPool(numThreads);
-
- // initialization
- ResultSet userTabs;
- userTabs = conn.getMetaData().getTables(null, null, null, null);
- while (userTabs.next()) {
- String tableName = userTabs.getString("TABLE_NAME");
- if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
- statement.execute(DatabaseCreator.DROP_TABLE1);
- }
- }
- db.exec(DatabaseCreator.CREATE_TABLE3, null);
- db.exec(DatabaseCreator.CREATE_TABLE1, null);
-
- int id1 = numOfRecords - 3;
- threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
- // should not be able to do any other insertions since task 1 holds lock
- int id2 = numOfRecords + 3;
- threadPool
- .runTask(createTask2Interrupt(id2, dbFile.getPath(), tracker));
-
- threadPool.join();
-
- List<String> errors = tracker.getErrors();
- System.out.println("Last error: " + db.error_message());
- if (errors.size() > 0) {
- assertEquals(errors.get(0), db.error_string(Constants.SQLITE_LOCKED));
- for (String s : errors) {
- Logger.global.info("INTERRUPT Error: " + s);
- }
-
- } else {
- fail("Should have one exception: database should be locked.");
- }
-
- // reset
- db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1", null);
- db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1", null);
- }
-
- /**
- * Returns wrong number for updates: returns value > 1 for select.
- */
- public void testChanges() throws Exception {
- TableResult res = new TableResult();
- assertTrue(db.changes() == 0);
- db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
- + " VALUES(2, 5, 7);", null);
- int rows = (int) db.changes();
- assertEquals(1,db.changes());
- db.exec("update " + DatabaseCreator.SIMPLE_TABLE1
- + " set speed = 7, size= 5 where id = 2;", null);
- assertEquals(1,db.changes());
- db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
- assertEquals(0,db.changes());
- db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
- + " VALUES(8, 5, 7);", null);
- db.exec("Update "+DatabaseCreator.SIMPLE_TABLE1+" set speed = 10;",null);
- assertTrue(db.changes() > 2);
- }
-
- /**
- * method test fails once in a while. Cannot be sure that exception is
- * thrown in every test execution.
- */
- public void testBusy_handler() throws SQLException, Exception {
- TestBusyHandler bh = new TestBusyHandler();
- db.busy_handler(bh);
- int counter = 0;
- ThreadPool threadPool = new ThreadPool(numThreads);
-
- // initialization
- ResultSet userTabs;
- userTabs = conn.getMetaData().getTables(null, null, null, null);
- while (userTabs.next()) {
- String tableName = userTabs.getString("TABLE_NAME");
- if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
- statement.execute(DatabaseCreator.DROP_TABLE1);
- }
- }
- db.exec(DatabaseCreator.CREATE_TABLE3, null);
- db.exec(DatabaseCreator.CREATE_TABLE1, null);
-
-
- try {
- conn.setAutoCommit(false);
- int id1 = numOfRecords - 3;
- threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
- int id2 = numOfRecords + 3;
- threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
- int oldID = 5;
- int newID = 100;
- threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
- tracker));
-
- threadPool.join();
-
- List<String> errors = tracker.getErrors();
- if (errors.size() > 0) {
-// assertEquals(errors.get(0),
-// db.error_string(Constants.SQLITE_LOCKED));
- for (String s: errors) {
- System.out.println("Round 2 Error: "+s);
- }
- } else {
- fail("No error happened");
- }
-
- // reset
-
-
- db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
- null);
- db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
- null);
-//
-// // increase timeout for retry
-// db.busy_timeout(1000);
-// db.busy_handler(bh);
-// tracker.reset();
-
-// threadPool = new ThreadPool(numThreads);
-//
-// threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
-// threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
-//
-// threadPool.join();
-//
-// errors = tracker.getErrors();
-// if (errors.size() > 0) {
-// // assertEquals(errors.get(0),
-// // db.error_string(Constants.SQLITE_LOCKED));
-// for (String s: errors) {
-// System.out.println("Round 2 Error"+s);
-// }
-// } else {
-// // ok
-// System.out.println("BUSY: No Error!");
-// }
-//
-//
- } finally {
- conn.setAutoCommit(true);
- db.exec(DatabaseCreator.DROP_TABLE1, null);
- db.exec(DatabaseCreator.DROP_TABLE3, null);
- }
- }
-
- /**
- * test fails. Cannot be sure that exception is thrown every time.
- * Database does not lock values.
- */
- public void testBusy_timeout() throws Exception, SQLException {
- int counter = 0;
- ThreadPool threadPool = new ThreadPool(numThreads);
-
- // initialization
- ResultSet userTabs = conn.getMetaData().getTables(null, null, null, null);
- while (userTabs.next()) {
- String tableName = userTabs.getString("TABLE_NAME");
- if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
- statement.execute(DatabaseCreator.DROP_TABLE1);
- }
- }
- db.exec(DatabaseCreator.CREATE_TABLE3, null);
- db.exec(DatabaseCreator.CREATE_TABLE1, null);
-
- // test run
- try {
- conn.setAutoCommit(false);
-
-// DatabaseCreator.fillTestTable1(conn, numOfRecords);
- // set to fail immediately if table is locked.
- db.busy_handler(null);
- db.busy_timeout(0);
- int id1 = numOfRecords - 3;
-
- threadPool.runTask(createTask2(id1, dbFile.getPath(), tracker));
- int id2 = numOfRecords + 3;
- threadPool.runTask(createTask1(id2, dbFile.getPath(), tracker));
- int oldID = 5;
- int newID = 100;
- threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
- tracker));
-
- threadPool.join();
-
- List<String> errors = tracker.getErrors();
- assertTrue("No error occurred on DB but should have",errors.size() > 0);
-
- assertEquals(errors.get(0),
- db.error_string(Constants.SQLITE_LOCKED));
- assertEquals(errors.get(0), "database is locked");
-
- // reset
-
- db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
- null);
- db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
- null);
-
- // increase timeout for retry
- db.busy_timeout(10000);
- db.busy_handler(null);
- tracker.reset();
- threadPool = new ThreadPool(numThreads);
-
- threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
- threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
-
- threadPool.join();
-
- errors = tracker.getErrors();
- if (errors.size() > 0) {
- fail("busy timeout should prevent from lock exception!");
- for (String s: errors) {
- System.out.println("Round 2 Error"+s);
- }
- } else {
- // ok
- }
- } finally {
- conn.setAutoCommit(true);
- // cleanup
- db.exec(DatabaseCreator.DROP_TABLE1, null);
- db.exec(DatabaseCreator.DROP_TABLE3, null);
- }
- }
-
- public void testGet_tableString() throws Exception {
- TableResult emptyTable = new TableResult();
- //select from empty table
- TableResult res = db.get_table("select * from " + DatabaseCreator.SIMPLE_TABLE1);
- assertEquals(res.toString(), emptyTable.toString());
- //fill table-> t
-// DatabaseCreator.fillSimpleTable1(conn);
-// res = db.get_table("select * from "
-// + DatabaseCreator.SIMPLE_TABLE1);
-// assertFalse(emptyTable.toString().equals(res.toString()));
-
- db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1 + " VALUES(1, 10, 20)", null);
- res = db.get_table("select * from " + DatabaseCreator.SIMPLE_TABLE1);
- db.exec("delete from " + DatabaseCreator.SIMPLE_TABLE1
- + " where 1", null);
- String row[] = (String[]) res.rows.elementAt(0);
- assertEquals(Integer.parseInt(row[0]), 1);
- assertEquals(Integer.parseInt(row[1]), 10);
- assertEquals(Integer.parseInt(row[2]), 20);
- }
-
- public void testGet_tableStringStringArray() throws Exception {
- String args[] = new String[1];
- args[0] = "table";
- String argsFail[] = new String[1];
- try {
- db.get_table("select name from sqlite_master where type = ", argsFail);
- fail("Testmethod should fail");
- } catch (Exception e) {
- }
-
- TableResult res = db.get_table(
- "select name from sqlite_master where type = '%q'",
- args);
- String[] s = (String[]) res.rows.elementAt(0);
- assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
- }
-
- public void testGet_tableStringStringArrayTableResult() throws Exception {
- String args[] = new String[1];
- String argsFail[] = new String[1];
- TableResult res = new TableResult();
- TableResult defaultTableRes = new TableResult();
- args[0] = "table";
-
- try {
- db.get_table("select name from sqlite_master where type = '%q'", argsFail, res);
- assertEquals(defaultTableRes.toString(), res.toString());
- } catch (Exception e) {
- db.get_table("select name from sqlite_master where type = '%q'", args, res);
- String[] s = (String[]) res.rows.elementAt(0);
- assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
- System.out.println("DatabaseTest.testGet_tableStringStringArrayTableResult() "
- + Arrays.toString(res.types));
- }
- }
-
- public void testComplete() {
- assertFalse(db.complete("create"));
- assertTrue(db.complete("create table TEST (res double);"));
- }
-
- public void testVersion() {
- String version = db.version();
- if (version != null) {
- assertTrue(Integer.parseInt(db.version().substring(0, 1)) > 0);
- assertEquals(db.version(), db.version());
- } else {
- fail("DB version info missing");
- }
- }
-
- public void testDbversion() throws Exception {
- String verNo = "";
- try {
- verNo = db.dbversion();
- db.close();
- assertEquals(db.dbversion(),"unknown");
- db.open(dbFile.getPath(), 0);
- assertEquals(verNo, db.dbversion());
- } catch (Exception e) {
- db.open(dbFile.getPath(), 0);
- }
-
- assertTrue(Integer.parseInt(verNo.substring(0, 1))>= 3 );
-
- }
-
- public void testCreate_function() throws Exception {
- double input = 1.0;
- db.exec("create table TEST (res double)", null);
- db.exec("insert into TEST values (" + Double.toString(input) + ")",
- null);
- TableResult res = new TableResult();
- Function sinFunc = (Function) new SinFunc();
- db.create_function("sin", 1, sinFunc);
- db.exec("select sin(res) from TEST WHERE res = "
- + Double.toString(input), res);
- String row[] = (String[]) res.rows.elementAt(0);
- String val = row[0];
- double sinusVal = Double.parseDouble(val);
- double funcVal = Math.sin(input);
-
- assertTrue(Math.round(funcVal) == Math.round(sinusVal));
- }
-
- /**
- * Aggregation function not called.
- */
- public void testCreate_aggregate() throws Exception {
- TestTrace t = new TestTrace();
- MockFunction aggFunction = new MockFunction();
- db.exec("create table TEST(id integer, firstname text, lastname text)", null);
- db.exec("insert into TEST values(3, 'James', 'Bond'); ", null);
- db.exec("insert into TEST values(4, 'Fiona', 'Apple'); ", null);
- db.trace((Trace) t);
- db.create_aggregate("myaggfunc", 1, aggFunction);
- db.function_type("myaggfunc", Constants.SQLITE3_TEXT);
- db.exec("PRAGMA show_datatypes = on", null);
-
- assertFalse(aggFunction.functionCalled);
- assertFalse(aggFunction.stepCalled);
- assertFalse(aggFunction.lastStepCalled);
- db.exec("select myaggfunc(TEST.firstname) from TEST", t);
- assertTrue(aggFunction.stepCalled);
- assertTrue(aggFunction.lastStepCalled);
- assertTrue(aggFunction.functionCalled);
-
- assertEquals("James Fiona ",aggFunction.getAggValue());
- db.exec("drop table TEST", null);
-
- try {
- db.create_aggregate("myaggfunc", 0, null);
- } catch (Throwable e) {
- assertEquals("null SQLite.Function not allowed",e.getMessage());
- }
-
- try {
- db.create_aggregate("myaggfunc", 0, aggFunction);
- } catch (Throwable e) {
- assertEquals("wrong number of arguments to function myaggfunc()",e.getMessage());
- }
- }
-
- public void testFunction_type() throws Exception {
- double input = 1.0;
- TableResult res = new TableResult();
- Function sinFunc = (Function) new SinFunc();
-
- db.exec("PRAGMA show_datatypes = on", null);
- db.exec("create table TEST (res double)", null);
- db.exec("insert into TEST values (" + Double.toString(input) + ")",
- null);
-
- db.create_function("sin", 1, sinFunc);
- db.function_type("sin", Constants.SQLITE_FLOAT);
- res = db.get_table("select sin(res) from TEST WHERE res = "
- + Double.toString(input));
-
- String row[] = (String[]) res.rows.elementAt(0);
- String val = row[0];
- assertTrue("double".equalsIgnoreCase(res.types[0]));
- assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
-
- // function determines return type: test that Double type is returned.
- db.function_type("sin", Constants.SQLITE_BLOB);
- Stmt s = db.prepare("select sin(res) from TEST WHERE res = ?");
- s.bind(1, input);
- s.step();
-
- res = db.get_table("select sin(res) from TEST WHERE res = "
- + Double.toString(input));
- assertTrue("double".equalsIgnoreCase(res.types[0]));
- row = (String[]) res.rows.elementAt(0);
- val = row[0];
- assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
- }
-
- public void testLast_error() {
- assertEquals(db.last_error(), Constants.SQLITE_OK);
- try {
- db.exec("create table TEST (res double)",null);
- db.exec("create table TEST (res double)",null);
- fail("Error should have happened");
- } catch (Exception e) {
- assertEquals(db.last_error(),db.last_error());
- assertEquals(db.last_error(),Constants.SQLITE_ERROR);
- }
- }
-
- public void testSet_last_error() {
- assertEquals(db.last_error(), Constants.SQLITE_OK);
- try {
- db.exec("sel from test;", null);
- } catch (Exception e) {
- assertEquals(Constants.SQLITE_ERROR,db.last_error());
- }
- }
-
- public void testError_message() {
- String statement = "create table TEST (res double)";
- try {
- db.exec(statement,null);
- db.exec(statement,null);
- fail("DB Error expected");
- } catch (Exception e) {
- String dbError = db.error_message();
- assertTrue(e.getMessage().equals(dbError));
-
- }
- }
-
- public void testError_string() {
- TestTrace t = new TestTrace();
- assertEquals(db.last_error(), Constants.SQLITE_OK);
- String errorString = db.error_string(Constants.SQLITE_ERROR);
- try {
- db.trace((Trace) t);
- db.exec("create table TEST (res double)", t);
- db.exec("create table TEST (res double)", t);
- } catch (Exception e) {
- assertEquals(db.last_error(), Constants.SQLITE_ERROR);
- if (db.is3()) {
- assertEquals("Unsupported Method (sqlite 3): error_string", db
- .error_string(db.last_error()), errorString);
- }
- }
- }
-
- /**
- * ASCII encoding does not work: a UTF encoded val is returned. Spec is not
- * sufficient. Might be that test impl is wrong or String constructor for
- * the ASCII encoding.
- */
- public void testSet_encoding() throws UnsupportedEncodingException, Exception {
- String input = "\u00bfMa\u00f1ana\u003f"; // ?Manana?
- TableResult res = new TableResult();
- String refOutput = null;
- Stmt stat = null;
-
- // DB setup
- db.exec("create table encodingTest (encoded text DEFAULT NULL);",
- null);
- stat = db
- .prepare("insert into encodingTest(encoded) values(:one);");
- stat.bind(1, input);
- stat.step();
- // stat.close();
- db.exec("select * from encodingTest;", res);
- String[] encInput = (String[]) res.rows.elementAt(0);
- String output = encInput[0];
- assertEquals(input, output);
- // db.exec("delete from encodingTest where 1", null);
-
- // tests for different encoding schemes
- String[] charsetNames = {"UTF-8", "UTF-16", "UTF-16BE", "UTF-16LE"};
- for (int i = 0; i < charsetNames.length; i++) {
- byte[] encInputBytes = input.getBytes(charsetNames[i]);
- db.set_encoding(charsetNames[i]);
- db.exec("select * from encodingTest;", res);
- String[] encOutput = (String[]) res.rows.elementAt(0);
- String inputAsString = new String(encInputBytes,charsetNames[i]);
- assertEquals(inputAsString, encOutput[0]);
- }
-
- // Default tests
- db.set_encoding("UTF-16");
- db.exec("select * from encodingTest;", res);
- String[] encOutput1 = (String[]) res.rows.elementAt(0);
- assertEquals("Got "+encOutput1[0]+" as UTF-16",input,encOutput1[0]);
-
- db.set_encoding("US-ASCII");
- db.exec("select * from encodingTest;", res);
- String[] encOutput2 = (String[]) res.rows.elementAt(0);
- assertEquals(new String(input.getBytes(),"US-ASCII"),encOutput2[0]);
-
- // DB teardown
- stat.close();
- db.exec("delete from encodingTest", null);
-
- // Default tests
- try {
- db.set_encoding("");
- fail("invalid input should fail");
- } catch (Exception e) {
- //ok
- }
- }
-
- /**
- * Callback never made for authorization. Results of private table are
- * returned withouth furhter checks.
- *
- * Test fails -> implemented correctly?
- */
- public void testSet_authorizer() throws Exception {
- TableResult resPriv = null;
- TableResult resPub = null;
- TableResult emptyTable = new TableResult();
- String insertPublic = "insert into public_table values(1,2)";
- String insertPrivate = "insert into private_table values(1,2)";
- // prepare, authorizer is not activated yet
- db.exec("create table public_table(c1 integer, c2 integer);", null);
- db.exec("create table private_table(c1 integer, c2 integer);", null);
- // inserts
- db.exec(insertPublic, null);
- db.exec(insertPrivate, null);
- // selects
- resPriv = db.get_table("select * from private_table");
- resPub = db.get_table("select * from public_table");
-
-// db.exec("delete from public_table where 1", null);
-// TableResult emptyPubTable = db.exec("select * from public");
-
- // set Authorizer (positive case): denies private table
- AuthorizerCallback cb = new AuthorizerCallback();
- db.set_authorizer(cb);
- //select
-
- db.exec("select * from private_table", cb);
- assertTrue(cb.wasCalled());
-
- /*
- TableResult res = db.get_table("select * from private_table");
- assertEquals(emptyTable.toString(),res.toString());
- assertFalse(emptyTable.equals(resPriv));
-
- res = db.get_table("select * from public_table");
- assertEquals(resPub,res);
- */
-
- // Try insert
- try {
- db.exec(insertPublic, null);
- fail("authorization failed");
- } catch (Exception e) {
- }
-
- try {
- db.exec(insertPrivate, null);
- fail("authorization failed");
- } catch (Exception e1) {
- // ok
- }
- }
-
- public void testTrace() throws Exception {
- String stmt = "create table TEST (res double);";
- TestTrace t = new TestTrace();
- assertFalse(t.traceCalled);
- assertEquals(db.last_error(),Constants.SQLITE_OK);
- db.trace((Trace) t);
- db.exec(stmt,t);
- assertTrue(t.traceCalled);
- assertEquals(t.getTrace(),stmt);
-
- try {
- db.close();
- db.exec(stmt,t);
- fail("Exception Expected");
- } catch (Exception e) {
- //ok
- }
- }
-
- public void testCompileString() throws Exception {
- db.compile("select name from sqlite_master;");
- try {
- db.compile("test");
- fail("Compiling of inaccurate statement does not fail.");
- } catch (Exception e) {
- }
- }
-
- public void testCompileStringStringArray() throws Exception {
- String args[] = new String[1];
- args[0] = "table";
- db.compile("select name from sqlite_master where type = '%q';",args);
-
- try {
- db.compile("test",null);
- fail("Compiling of inaccurate statement does not fail.");
- } catch (Exception e) {
- }
- }
-
- public void testPrepare() throws Exception {
- Stmt st = null;
- Stmt st2 = null;
- // test empty statement
- try {
- st = db.prepare("");
- assertEquals(0, st.bind_parameter_count());
- st.step();
- fail("stmt should not be prepared");
- } catch (Exception e) {
- assertEquals("stmt already closed", e.getMessage());
- }
-
- // test statement with unbound arguments
- try {
- st2 = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- assertEquals(3, st2.bind_parameter_count());
- assertEquals(3, st2.bind_parameter_index(":three"));
- assertEquals(":two", st2.bind_parameter_name(2));
- } finally {
- st2.close();
- }
-
- try {
- db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values(:one,:two,:three,:four);");
- } catch (Exception e) {
- assertEquals("table " + DatabaseCreator.SIMPLE_TABLE1
- + " has 3 columns but 4 values were supplied", e
- .getMessage());
- }
-
- try {
- db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values(5, '10, 20);");
- } catch (Exception e) {
- assertEquals("unrecognized token: \"'10, 20);\"", e.getMessage());
- }
-
- try {
- db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values(5, 10 20);");
- } catch (Exception e) {
- assertEquals("near \"20\": syntax error", e.getMessage());
- }
-
- }
-
- /**
- * Not supported.
- */
- public void testOpen_blob() throws Exception, java.lang.Exception {
- Stmt statement2;
- Blob blobInput = new Blob();
-
- // Create test input Blob
- InputStream inStream = null;
- byte[] in = {(byte) 1, (byte) 2, (byte) 3, (byte) 4};
-
- // setup test input
- db.exec("create table TEST (res blob)",null);
- inStream = Class.forName(this.getClass().getName()).getResourceAsStream("/blob.c");
- assertNotNull(inStream);
-
- // insert byte array in db
- statement2 = db.prepare("insert into TEST(res) values (?)");
- statement2.bind(1, in);
- statement2.step();
- statement2.close();
-
- // read from db
- Blob blob = db.open_blob(dbFile.getPath(), "TEST", "res", 1, true);
- if (blob == null) {
- fail("Blob could not be retrieved");
- }
- //read from blob and compare values (positive case)
- InputStream is = blob.getInputStream();
-
- int i = 0;
- int outByte = 0;
- byte[] out = new byte[4];
- while ((outByte = is.read()) > -1) {
- out[i] = (byte) outByte;
- i++;
- }
- is.close();
-
- blob.close();
-
- assertTrue(Arrays.equals(in, out));
-
- //read from blob and compare values (default blob)
- db.exec("insert into TEST values(zeroblob(128))", null);
- Blob blob2 = db.open_blob(dbFile.getPath(), "TEST", "res", 2, true);
- is = blob2.getInputStream();
- for (i = 0; i < 128; i++) {
- assertEquals(0, is.read());
- }
- is.close();
- }
-
- public void testIs3() {
- int ver = Integer.parseInt(db.version().substring(0,1));
- if (db.is3()) {
- assertTrue( ver == 3);
- } else {
- assertTrue(ver != 3);
- }
- }
-
- public void testProgress_handler() throws Exception {
- int inputVal = 3;
- TestProgressHandler prog = new TestProgressHandler();
- db.exec("create table TEST5(id integer, firstname text, lastname text)",null);
- Vm vm = db.compile("select * from TEST5; "
- + "insert into TEST5 values(3, 'James', 'Bond'); "
- + "delete from TEST5 where id = 3; "
- + "select * from TEST5");
- int stmt = 0;
- do {
- ++stmt;
- if (stmt > inputVal) {
- db.progress_handler(inputVal, prog);
- } else {
- assertEquals(0, prog.getCounts());
- }
- while (vm.step(prog)) {
- }
- } while (vm.compile());
- assertEquals(inputVal,prog.getCounts());
-
- // Boundary value test
- inputVal = 0;
- TestProgressHandler progBoundary = new TestProgressHandler();
- db.progress_handler(inputVal, progBoundary);
- Vm vm2 = db.compile("select * from TEST5; "
- + "insert into TEST5 values(3, 'James', 'Bond'); "
- + "delete from TEST5 where id = 3; "
- + "select * from TEST5");
- do {
- vm2.step(progBoundary);
- } while (vm2.compile());
- assertEquals(inputVal, progBoundary.getCounts());
-
- try {
- db.exec("drop table TEST5",null);
- } catch (Exception e) {
- System.out.println(e.getMessage());
- e.printStackTrace();
- }
- }
-
- class SinFunc implements Function {
- public void function(FunctionContext fc, String args[]) {
- Double d = new Double(args[0]);
- fc.set_result(Math.sin(d.doubleValue()));
- }
- public void last_step(FunctionContext fc) {}
- public void step(FunctionContext fc, String[] args) {}
- }
-
- class TestTrace implements Trace,Callback {
-
- private StringBuffer buf = new StringBuffer();
-
- public boolean traceCalled = false;
-
- public String getTrace() {
- return buf.toString();
- }
-
- public void trace(String stmt) {
- traceCalled = true;
- buf.append(stmt);
- }
-
- public void columns(String[] coldata) {}
-
- public boolean newrow(String[] rowdata) {
- return false;
- }
-
- public void types(String[] types) {}
- }
-
- class AuthorizerCallback implements Authorizer, Callback {
-
- private boolean isAuthorizing = false;
-
- public boolean wasCalled() {
- return isAuthorizing;
- }
-
- public int authorize(int action, String arg1, String arg2, String arg3,
- String arg4) {
- Logger.global.info("DB authorization callback " + action + " " + arg1 + " " + arg2 + " "
- + arg3 + " " + arg4 + " ");
- this.isAuthorizing = true;
- if (action != Constants.SQLITE_SELECT || arg1.contains("private_table")) {
- return Constants.SQLITE_DENY;
- } else {
- return Constants.SQLITE_OK;
- }
- }
-
- public void columns(String[] coldata) {}
-
- public boolean newrow(String[] rowdata) {
- return false;
- }
-
- public void types(String[] types) {}
-
- }
-
- class TestBusyHandler implements BusyHandler, Callback {
-
- public boolean busy(String table, int count) {
- return true;
- }
-
- public void columns(String[] coldata) {}
-
- public boolean newrow(String[] rowdata) {
- return false;
- }
-
- public void types(String[] types) {}
- }
-
- class TestProgressHandler implements ProgressHandler, Callback {
-
- private boolean progressed = false;
-
- private int counter = 0;
-
- public int getCounts() {
- return counter;
- }
-
- public boolean progress() {
- this.progressed = true;
- counter++;
- return true;
- }
-
- public void columns(String[] coldata) {}
-
- public boolean newrow(String[] rowdata) {
- return false;
- }
-
- public void types(String[] types) {}
- }
-
- /**
- * This method creates a Runnable that executes insert operation for the first table
- */
- private static Runnable createTask2Interrupt(final int id,
- final String dbName, final ErrorTracker errorTracker) {
- return new Runnable() {
- public void run() {
- Database db = new Database();
- try {
- String value = DatabaseCreator.defaultString + id;
-
- db.open(dbName, 0);
- String insertQuery = "INSERT INTO "
- + DatabaseCreator.TEST_TABLE1
- + " (id, field1, field2, field3) VALUES(" + id
- + ", '" + value + "', " + id + ", " + id + ")";
- db.exec(insertQuery, null);
- } catch (Exception e) {
- errorTracker.registerException(this, e);
- try {
- db.interrupt();
- db.exec("DELETE FROM " + DatabaseCreator.SIMPLE_TABLE1
- + " WHERE id=" + id, null);
- } catch (Exception e1) {
- errorTracker.registerException(this, e1);
- }
- }
- }
- };
- }
-
- /**
- * This method creates a Runnable that executes delete operation for the first table
- */
- private static Runnable createTask1(final int id, final String dbName,
- final ErrorTracker errorTracker) {
- return new Runnable() {
- public void run() {
- try {
- Database db = new Database();
- db.open(dbName, 0);
- db.exec("DELETE FROM "
- + DatabaseCreator.SIMPLE_TABLE1 + " WHERE id=" + id, null);
- } catch (Exception e) {
- errorTracker.registerException(this, e);
- }
- }
- };
- }
-
- /**
- * This method creates a Runnable that executes insert operation for the first table
- */
- private static Runnable createTask2(final int id, final String dbName,
- final ErrorTracker errorTracker) {
- return new Runnable() {
- public void run() {
- try {
- String value = DatabaseCreator.defaultString + id;
- Database db = new Database();
- db.open(dbName, 0);
- String insertQuery = "INSERT INTO "
- + DatabaseCreator.TEST_TABLE1
- + " (id, field1, field2, field3) VALUES(" + id
- + ", '" + value + "', " + id + ", " + id + ")";
- db.exec(insertQuery, null);
- } catch (Exception e) {
- errorTracker.registerException(this, e);
-
- }
- }
- };
- }
-
- /**
- * This method creates a Runnable that executes update operation for the one record of the first
- * table
- */
- private static Runnable createTask3(final int oldID, final String dbName,
- final int newID, final ErrorTracker errorTracker) {
- return new Runnable() {
- public void run() {
- Database db = new Database();
- try {
- db.open(dbName, 0);
- String value = DatabaseCreator.defaultString + newID;
- String updateQuery = "UPDATE "
- + DatabaseCreator.TEST_TABLE1 + " SET id=" + newID
- + ", field1='" + value + "', field2=" + newID
- + ", field3=" + newID + " WHERE id=" + oldID;
- db.exec(updateQuery, null);
- } catch (Exception e) {
- errorTracker.registerException(this, e);
- }
- }
- };
- }
-
- private class ErrorTracker {
-
- private List<String> errors = new ArrayList<String>();
-
- public void registerException(Runnable runnable, Exception e) {
- System.out.println("Registered: " + e.getMessage());
- errors.add(e.getMessage());
- }
-
- public List<String> getErrors() {
- return errors;
- }
-
- public void reset() {
- errors.clear();
- }
- }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldExceptionTest.java b/luni/src/test/java/libcore/sqlite/OldExceptionTest.java
deleted file mode 100644
index dddfd6b..0000000
--- a/luni/src/test/java/libcore/sqlite/OldExceptionTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import SQLite.Database;
-import SQLite.Exception;
-
-public final class OldExceptionTest extends OldSQLiteTest {
-
- private Database db = null;
-
- @Override public void setUp() throws java.lang.Exception {
- super.setUp();
- db = new Database();
- }
-
- public void testException() {
- try {
- db.open(dbFile.getName(), 0);
- } catch (Exception e) {
- assertNotNull(e);
- assertNotNull(e.getMessage());
- }
- }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldFunctionContextTest.java b/luni/src/test/java/libcore/sqlite/OldFunctionContextTest.java
deleted file mode 100644
index 0924317..0000000
--- a/luni/src/test/java/libcore/sqlite/OldFunctionContextTest.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import SQLite.Database;
-import SQLite.Exception;
-import SQLite.Function;
-import SQLite.FunctionContext;
-import SQLite.Stmt;
-import SQLite.TableResult;
-import java.io.UnsupportedEncodingException;
-import java.sql.SQLException;
-import java.sql.Statement;
-import tests.support.DatabaseCreator;
-
-public final class OldFunctionContextTest extends OldSQLiteTest {
-
- private Database db = null;
-
- @Override public void setUp() throws java.lang.Exception {
- super.setUp();
- db = new Database();
- db.open(dbFile.getPath(), 0);
- Statement st = conn.createStatement();
- st.execute(DatabaseCreator.CREATE_TABLE2);
- st.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1);
- st.close();
- }
-
- public void testSet_resultString() throws Exception {
- TestFCString testString = new TestFCString();
- db.exec("insert into " + DatabaseCreator.TEST_TABLE2
- + " (ftext) values ('TestInput')", null);
- db.create_function("test", 1, testString);
- TableResult res = db.get_table("select test(ftext) from "
- + DatabaseCreator.TEST_TABLE2);
- String row[] = (String[]) res.rows.elementAt(0);
- String val = row[0];
-
- assertEquals("TestInput", val);
- }
-
- public void testSet_resultInt() throws Exception {
- TestFCInt testInt = new TestFCInt();
- db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (1,'" + testInt.intVal + "',3)", null);
- db.create_function("testInt", 1, testInt);
- TableResult res = db.get_table("select testInt(speed) from "
- + DatabaseCreator.SIMPLE_TABLE1);
- String row[] = (String[]) res.rows.elementAt(0);
- String val = row[0];
-
- assertEquals(testInt.intVal, Integer.parseInt(val));
- }
-
- public void testSet_resultDouble() throws Exception {
- SinFunc testD = new SinFunc();
- db.exec("insert into " + DatabaseCreator.TEST_TABLE2
- + " (fdouble) values (" + testD.testDouble + ")", null);
- db.create_function("testDouble", 1, testD);
- TableResult res = db.get_table("select testDouble(fdouble) from "
- + DatabaseCreator.TEST_TABLE2);
- String row[] = (String[]) res.rows.elementAt(0);
- String val = row[0];
-
- assertEquals(testD.testDouble, Double.parseDouble(val));
-
- assertTrue(testD.functionCalled);
- }
-
- public void testSet_error() throws Exception {
- TestFCError testError = new TestFCError();
- SinFunc testD = new SinFunc();
- db.exec("insert into " + DatabaseCreator.TEST_TABLE2
- + " (fdouble) values (" + testD.testDouble + ")", null);
- db.create_function("testError", 1, testError);
-
- try {
- TableResult res = db.get_table("select testError(fdouble) from "
- + DatabaseCreator.TEST_TABLE2);
- fail("Should get Exception");
- } catch (Exception e) {
- assertEquals("error in step", e.getMessage());
- }
-
- assertFalse(testD.functionCalled);
- }
-
- public void testSet_resultByteArray() throws Exception, UnsupportedEncodingException {
- Stmt st = null;
- TestFCByteArray testBinArrayFnc = new TestFCByteArray();
- String expected = "";
- expected = "X'" + getHexString(testBinArrayFnc.byteVal) + "'";
-
- // setup
- db.exec("create table testBinaryData (binVal BINARY) ;", null);
-
- try {
- st = db.prepare("insert into testBinaryData values (?)");
- st.bind(1, testBinArrayFnc.byteVal);
- st.step();
-
-
- db.create_function("testBinArray", 1, testBinArrayFnc);
- TableResult res = db
- .get_table("select testBinArray(binVal) from testBinaryData");
-
- String row[] = (String[]) res.rows.elementAt(0);
- String val = row[0];
-
- assertTrue(expected.equalsIgnoreCase(val));
-
- assertTrue(testBinArrayFnc.functionCalled);
-
- } finally {
- //teardown
- db.exec("drop table testBinaryData;", null);
- }
- }
-
- /**
- * ZeroBlob not supported
- */
- public void testSet_result_zeroblob() throws Exception,
- UnsupportedEncodingException {
- Stmt st = null;
- TestFCZeroBlob testZeroBlobFnc = new TestFCZeroBlob();
- byte[] byteVal = {(byte) 1, (byte) 2, (byte) 3};
-
-
- // setup
- db.exec("create table testBinaryData (binVal BINARY) ;", null);
-
- try {
- st = db.prepare("insert into testBinaryData values (?)");
- st.bind(1, byteVal);
- st.step();
-
-
- db.create_function("testZeroBlob", 0, testZeroBlobFnc);
- TableResult res = db
- .get_table("select testZeroBlob() from testBinaryData");
- TableResult res2 = db.get_table("select zeroblob("
- + testZeroBlobFnc.numBytes + ") from testBinaryData");
-
- String row[] = (String[]) res.rows.elementAt(0);
- String val = row[0];
-
- assertNotNull(val);
-
- assertEquals(((String[]) res2.rows.elementAt(0))[0], val);
- assertTrue(testZeroBlobFnc.functionCalled);
-
- } finally {
- // teardown
- db.exec("drop table if exists testBinaryData;", null);
- }
- }
-
- /**
- * Test Method results in a segmentation fault
- */
- public void testCount() throws SQLException, Exception {
- TestFCCount countTest = new TestFCCount();
- int inputCount = 10;
-
- assertFalse(countTest.functionCalled);
-
- DatabaseCreator.fillTestTable2(conn, inputCount);
- db.create_function("testCount", 0, countTest);
- // the invokation of testCount leads to a Segmentation fault
- /*
- TableResult res = db
- .get_table("select testCount() from "+DatabaseCreator.TEST_TABLE2);
-
- String row[] = (String[]) res.rows.elementAt(0);
- String val = row[0];
-
- assertTrue(countTest.functionCalled);
- assertEquals(inputCount,Integer.parseInt(val));
- */
-
- }
-
- class TestFCError implements Function {
- public boolean functionCalled = false;
- public String errorMsg = "FunctionError";
-
- public void function(FunctionContext fc, String args[]) {
- functionCalled = true;
- fc.set_error(errorMsg);
- }
-
- public void last_step(FunctionContext fc) {}
- public void step(FunctionContext fc, String[] args) {}
- }
-
- class TestFCCount implements Function {
- public boolean functionCalled = false;
- public int noOfRows = 0;
-
- public void function(FunctionContext fc, String args[]) {
- functionCalled = true;
- noOfRows = fc.count();
- fc.set_result(noOfRows);
- }
-
- public void last_step(FunctionContext fc) {}
- public void step(FunctionContext fc, String[] args) {}
- }
-
- class TestFCZeroBlob implements Function {
- public int numBytes = 16;
- public boolean functionCalled = false;
-
- public void function(FunctionContext fc, String args[]) {
- functionCalled = true;
- fc.set_result_zeroblob(numBytes);
- }
-
- public void last_step(FunctionContext fc) {}
- public void step(FunctionContext fc, String[] args) {}
- }
-
- class TestFCString implements Function {
- public String testString = "TestString";
- public boolean functionCalled;
-
- public void function(FunctionContext fc, String args[]) {
- assertNotNull(args);
- functionCalled = true;
- fc.set_result(args[0]);
- }
-
- public void last_step(FunctionContext fc) {}
- public void step(FunctionContext fc, String[] args) {}
- }
-
- class TestFCInt implements Function {
- public int intVal = Integer.MAX_VALUE;
- public boolean functionCalled;
-
- public void function(FunctionContext fc, String args[]) {
- assertNotNull(args);
- functionCalled = true;
- fc.set_result(Integer.parseInt(args[0]));
- }
-
- public void last_step(FunctionContext fc) {}
- public void step(FunctionContext fc, String[] args) {}
- }
-
- class TestFCByteArray implements Function {
- public byte[] byteVal = {(byte) 1, (byte) 2, (byte) 3};
- public boolean functionCalled;
-
- public void function(FunctionContext fc, String args[]) {
- assertNotNull(args);
- functionCalled = true;
- fc.set_result(args[0].getBytes());
- }
-
- public void last_step(FunctionContext fc) {}
- public void step(FunctionContext fc, String[] args) {}
- }
-
- class SinFunc implements Function {
- public Double testDouble = 3.0;
- public boolean functionCalled = false;
-
- public void function(FunctionContext fc, String args[]) {
- Double d = new Double(args[0]);
- functionCalled = true;
- fc.set_result(d.doubleValue());
- }
-
- public void last_step(FunctionContext fc) {}
- public void step(FunctionContext fc, String[] args) {}
- }
-
- static final byte[] HEX_CHAR_TABLE = {
- (byte)'0', (byte)'1', (byte)'2', (byte)'3',
- (byte)'4', (byte)'5', (byte)'6', (byte)'7',
- (byte)'8', (byte)'9', (byte)'a', (byte)'b',
- (byte)'c', (byte)'d', (byte)'e', (byte)'f'
- };
-
- public static String getHexString(byte[] raw)
- throws UnsupportedEncodingException {
- byte[] hex = new byte[2 * raw.length];
- int index = 0;
-
- for (byte b : raw) {
- int v = b & 0xFF;
- hex[index++] = HEX_CHAR_TABLE[v >>> 4];
- hex[index++] = HEX_CHAR_TABLE[v & 0xF];
- }
- return new String(hex, "ASCII");
- }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldJDBCDriverFunctionalTest.java b/luni/src/test/java/libcore/sqlite/OldJDBCDriverFunctionalTest.java
deleted file mode 100644
index 48eeab1..0000000
--- a/luni/src/test/java/libcore/sqlite/OldJDBCDriverFunctionalTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import java.io.File;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * Tests the SQLite.JDBCDriver.
- */
-public class OldJDBCDriverFunctionalTest extends AbstractSqlTest {
- private File dbFile = null;
- private String connectionURL = "empty";
-
- @Override protected void tearDown() throws SQLException {
- super.tearDown();
- dbFile.delete();
- }
-
- @Override protected String getConnectionURL() {
- if (connectionURL.equals("empty")) {
- String tmp = System.getProperty("java.io.tmpdir");
- File tmpDir = new File(tmp);
- if (tmpDir.isDirectory()) {
- try {
- dbFile = File.createTempFile("JDBCDriverFunctionalTest", ".db", tmpDir);
- } catch (IOException e) {
- System.err.println("error creating temporary DB file.");
- }
- dbFile.deleteOnExit();
- } else {
- System.err.println("java.io.tmpdir does not exist");
- }
-
- connectionURL = "jdbc:sqlite:/" + dbFile.getPath();
- }
-
- return connectionURL;
- }
-
- @Override protected String getDriverClassName() {
- return "SQLite.JDBCDriver";
- }
-
- @Override protected int getTransactionIsolation() {
- return Connection.TRANSACTION_SERIALIZABLE;
- }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldJDBCDriverTest.java b/luni/src/test/java/libcore/sqlite/OldJDBCDriverTest.java
deleted file mode 100644
index ae06dc6..0000000
--- a/luni/src/test/java/libcore/sqlite/OldJDBCDriverTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import SQLite.JDBCDriver;
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.DriverPropertyInfo;
-import java.sql.SQLException;
-
-
-public final class OldJDBCDriverTest extends OldJDBCDriverFunctionalTest {
-
- /**
- * The SQLite db file.
- */
- private JDBCDriver jDriver;
-
- private Driver returnedDriver;
-
- @Override public void setUp() throws java.lang.Exception {
- super.setUp();
- returnedDriver = DriverManager.getDriver(getConnectionURL());
- if (returnedDriver instanceof JDBCDriver) {
- this.jDriver = (JDBCDriver) returnedDriver;
- }
- }
-
- public void testJDBCDriver() {
- assertTrue(returnedDriver instanceof JDBCDriver);
- }
-
- public void testAcceptsURL() {
- try {
- if (this.jDriver != null) {
- assertTrue(jDriver.acceptsURL(getConnectionURL()));
- } else {
- fail("no Driver available");
- }
- } catch (SQLException e) {
- fail("Driver does not accept URL");
- e.printStackTrace();
- }
- }
-
- public void testConnect() {
- try {
- if (this.jDriver != null) {
- Connection c = jDriver.connect(getConnectionURL(), null);
- assertFalse(c.isClosed());
- DriverManager.getConnection(getConnectionURL());
- } else {
- fail("no Driver available");
- }
- } catch (SQLException e) {
- fail("Driver does not connect");
- e.printStackTrace();
- }
- }
-
- public void testGetMajorVersion() {
- if (this.jDriver != null) {
- assertTrue(jDriver.getMajorVersion() > 0);
- } else {
- fail("no Driver available");
- }
- }
-
- public void testGetMinorVersion() {
- if (this.jDriver != null) {
- assertTrue(jDriver.getMinorVersion() > 0);
- } else {
- fail("no version information available");
- }
- }
-
- public void testGetPropertyInfo() throws SQLException {
- DriverPropertyInfo[] info = null;
- if (this.jDriver != null) {
- info = jDriver.getPropertyInfo(getConnectionURL(), null);
- assertNotNull(info);
- assertTrue(info.length > 0);
- } else {
- fail("no Driver available");
- }
-
- assertNotNull(info);
-
- }
-
- public void testJdbcCompliant() {
- if (this.jDriver != null) {
- assertFalse(jDriver.jdbcCompliant());
- } else {
- fail("no version information available");
- }
- }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldSQLiteTest.java b/luni/src/test/java/libcore/sqlite/OldSQLiteTest.java
deleted file mode 100644
index e6b7f22..0000000
--- a/luni/src/test/java/libcore/sqlite/OldSQLiteTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import java.io.File;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.util.logging.Logger;
-import junit.framework.TestCase;
-
-public abstract class OldSQLiteTest extends TestCase {
-
- public static Connection conn;
-
- public static File dbFile = null;
-
- @Override public void setUp() throws Exception {
- String tmp = System.getProperty("java.io.tmpdir");
- File tmpDir = new File(tmp);
- try {
- if (tmpDir.isDirectory()) {
- dbFile = File.createTempFile("sqliteTest", ".db", tmpDir);
- dbFile.deleteOnExit();
- } else {
- System.out.println("ctsdir does not exist");
- }
-
- Class.forName("SQLite.JDBCDriver").newInstance();
-
- if (!dbFile.exists()) {
- Logger.global.severe("DB file could not be created. Tests can not be executed.");
- } else {
- conn = DriverManager.getConnection("jdbc:sqlite:/" + dbFile.getPath());
- }
- assertNotNull("Error creating connection", conn);
- } catch (IOException e) {
- System.out.println("Problem creating test file in " + tmp);
- }
- }
-
- @Override public void tearDown() throws java.lang.Exception {
- if (!conn.isClosed()) {
- conn.close();
- }
- super.tearDown();
- }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldStmtTest.java b/luni/src/test/java/libcore/sqlite/OldStmtTest.java
deleted file mode 100644
index 4d379ed..0000000
--- a/luni/src/test/java/libcore/sqlite/OldStmtTest.java
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.sqlite;
-
-import SQLite.Constants;
-import SQLite.Database;
-import SQLite.Stmt;
-import SQLite.TableResult;
-import java.sql.Connection;
-import tests.support.DatabaseCreator;
-import tests.support.Support_SQL;
-
-public class OldStmtTest extends OldSQLiteTest {
-
- private Database db;
- private Stmt st;
-
- private static final String CREATE_ALL_TYPES = "create table type ("
- + " BoolVal BOOLEAN,"
- + " IntVal INT,"
- + " LongVal LONG,"
- + " Bint BIGINT,"
- + " Tint TINYINT,"
- + " Sint SMALLINT,"
- + " Mint MEDIUMINT,"
- + " IntegerVal INTEGER,"
- + " RealVal REAL,"
- + " DoubleVal DOUBLE,"
- + " FloatVal FLOAT,"
- + " DecVal DECIMAL,"
- + " NumVal NUMERIC,"
- + " charStr CHAR(20),"
- + " dateVal DATE,"
- + " timeVal TIME,"
- + " TS TIMESTAMP,"
- + " DT DATETIME,"
- + " TBlob TINYBLOB,"
- + " BlobVal BLOB,"
- + " MBlob MEDIUMBLOB,"
- + " LBlob LONGBLOB,"
- + " TText TINYTEXT,"
- + " TextVal TEXT,"
- + " MText MEDIUMTEXT,"
- + " LText LONGTEXT,"
- + " MaxLongVal BIGINT,"
- + " MinLongVal BIGINT,"
- + " validURL URL,"
- + " invalidURL URL);";
-
- static final String INSERT_ALL_TYPES = "insert into type ("
- + "BoolVal, IntVal, LongVal, Bint, Tint, Sint, Mint,IntegerVal, RealVal, DoubleVal, "
- + "FloatVal, DecVal,NumVal, charStr, dateVal, timeVal, TS,DT, TBlob, BlobVal, MBlob, "
- + "LBlob,TText, TextVal, MText, LText, MaxLongVal, MinLongVal, validURL, invalidURL) "
- + "values (1, -1, 22, 2, 33,3, 1, 2, 3.9, 23.2, 33.3, 44,5, 'test string', '1799-05-26',"
- + "'12:35:45', '2007-10-09 14:28:02.0','1221-09-22 10:11:55', 1, 2, 3, 4,"
- + "'Test text message tiny', 'Test text', 'Test text message medium',"
- + "'Test text message long', " + Long.MAX_VALUE + ", " + Long.MIN_VALUE + ","
- + "null, null);";
-
- static final String ALL_TYPES_TABLE = "type";
-
- @Override public void setUp() throws Exception {
- super.setUp();
- Support_SQL.loadDriver();
- db = new Database();
- db.open(dbFile.getPath(), 0);
- db.exec(DatabaseCreator.CREATE_TABLE_SIMPLE1, null);
- DatabaseCreator.fillSimpleTable1(conn);
-
- st = new Stmt();
- }
-
- @Override public void tearDown() throws Exception {
- if (st != null) {
- try {
- st.close();
- } catch (Exception e) {
- }
- }
- db.close();
- Connection con = Support_SQL.getConnection();
- con.close();
- super.tearDown();
- }
-
- public void testStmt() throws Exception {
- db.prepare("");
-
- try {
- st.step();
- fail("Cannot execute non prepared Stmt");
- } catch (SQLite.Exception expected) {
- }
- }
-
- public void testPrepare() throws Exception {
- try {
- st = db.prepare("");
- st.prepare();
- fail("statement is closed");
- } catch (SQLite.Exception expected) {
- assertEquals("stmt already closed", expected.getMessage());
- }
-
- st = new Stmt();
- st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
- assertFalse(st.prepare());
- st = new Stmt();
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- assertFalse(st.prepare());
- st = new Stmt();
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- st.bind(1, 1);
- st.bind(2, 10);
- st.bind(3, 30);
- assertFalse(st.prepare());
- st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1
- + "; " + "delete from " + DatabaseCreator.SIMPLE_TABLE1
- + " where id = 5; " + "insert into "
- + DatabaseCreator.SIMPLE_TABLE1 + " values(5, 10, 20); "
- + "select * from " + DatabaseCreator.SIMPLE_TABLE1 + ";");
- assertTrue(st.prepare());
- assertTrue(st.prepare());
- assertTrue(st.prepare());
- assertFalse(st.prepare());
- }
-
- public void testStep() throws Exception {
- try {
- st.step();
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- assertEquals("stmt already closed", expected.getMessage());
- }
-
- st = new Stmt();
- st = db.prepare("select name from sqlite_master where type = 'table'");
- st.step();
- }
-
- public void testClose() throws Exception {
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- st.close();
-
- try {
- st.step();
- fail("Test fails");
- } catch (SQLite.Exception expected) {
- assertEquals("stmt already closed", expected.getMessage());
- }
- }
-
- public void testReset() throws Exception {
- db.exec("create table TEST (res integer not null)", null);
-
- st = db.prepare("insert into TEST values (:one);");
- st.bind(1, 1);
- st.step();
-
- // verify that parameter is still bound
- st.reset();
- assertEquals(1,st.bind_parameter_count());
- st.step();
-
- TableResult count = db.get_table("select count(*) from TEST where res=1", null);
-
- String[] row0 = (String[]) count.rows.elementAt(0);
- assertEquals(2, Integer.parseInt(row0[0]));
- }
-
- public void testClear_bindings() {
- try {
- st.clear_bindings();
- } catch (SQLite.Exception expected) {
- assertEquals("unsupported", expected.getMessage());
- }
- }
-
- public void testBindIntInt() throws Exception {
- int input = 0;
- int maxVal = Integer.MAX_VALUE;
- int minVal = Integer.MIN_VALUE;
-
- db.exec("create table TEST (res integer)", null);
- st = db.prepare("insert into TEST values (:one);");
- st.bind(1, input);
- st.step();
-
- st.reset();
- st.bind(1,maxVal);
- st.step();
-
- st.reset();
- st.bind(1,minVal);
- st.step();
-
- TableResult r = db.get_table("select * from TEST");
-
- String[] row0 = (String[]) r.rows.elementAt(0);
- assertEquals(input,Integer.parseInt(row0[0]));
-
- String[] row1 = (String[]) r.rows.elementAt(1);
- assertEquals(maxVal,Integer.parseInt(row1[0]));
-
- String[] row2 = (String[]) r.rows.elementAt(2);
- assertEquals(minVal,Integer.parseInt(row2[0]));
-
- try {
- st.close();
- st.bind(1,Integer.MIN_VALUE);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- }
- }
-
- public void testBindIntLong() throws Exception {
- long input = 0;
- long maxVal = Long.MAX_VALUE;
- long minVal = Long.MIN_VALUE;
-
- db.exec("create table TEST (res long)", null);
- st = db.prepare("insert into TEST values (:one);");
- st.bind(1, input);
- st.step();
-
- st.reset();
- st.bind(1,maxVal);
- st.step();
-
- st.reset();
- st.bind(1,minVal);
- st.step();
-
- TableResult r = db.get_table("select * from TEST");
-
- String[] row0 = (String[]) r.rows.elementAt(0);
- assertEquals(input,Long.parseLong(row0[0]));
-
- String[] row1 = (String[]) r.rows.elementAt(1);
- assertEquals(maxVal,Long.parseLong(row1[0]));
-
- String[] row2 = (String[]) r.rows.elementAt(2);
- assertEquals(minVal,Long.parseLong(row2[0]));
-
- try {
- st.close();
- st.bind(1,Long.MIN_VALUE);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- }
- }
-
- public void testBindIntDouble() throws Exception {
- double input = 0.0;
- double maxVal = Double.MAX_VALUE;
- double minVal = Double.MIN_VALUE;
- double negInf = Double.NEGATIVE_INFINITY;
- double posInf = Double.POSITIVE_INFINITY;
- double nan = Double.NaN;
-
- db.exec("create table TEST (res double)", null);
- st = db.prepare("insert into TEST values (:one);");
- st.bind(1, input);
- st.step();
-
- st.reset();
- st.bind(1, maxVal);
- st.step();
-
- st.reset();
- st.bind(1, minVal);
- st.step();
-
- st.reset();
- st.bind(1, negInf);
- st.step();
-
- st.reset();
- st.bind(1, posInf);
- st.step();
-
- st.reset();
- st.bind(1, nan);
- st.step();
-
-
- TableResult r = db.get_table("select * from TEST");
-
- String[] row0 = (String[]) r.rows.elementAt(0);
- assertTrue(Double.compare(input, Double.parseDouble(row0[0])) == 0);
-
- String[] row1 = (String[]) r.rows.elementAt(1);
- assertFalse(Double.compare(maxVal, Double.parseDouble(row1[0])) == 0);
- assertTrue(Double.compare(maxVal, Double.parseDouble(row1[0])) < 0);
- assertTrue(Double.isInfinite(Double.parseDouble(row1[0])));
-
- String[] row2 = (String[]) r.rows.elementAt(2);
- assertTrue(Double.compare(minVal, Double.parseDouble(row2[0])) == 0);
-
- String[] row3 = (String[]) r.rows.elementAt(3);
- assertEquals("Double.NEGATIVE_INFINITY SQLite representation",
- "-Inf", row3[0]);
-
- String[] row4 = (String[]) r.rows.elementAt(4);
- assertEquals("Double.POSITIVE_INFINITY SQLite representation",
- "Inf", row4[0]);
-
- String[] row5 = (String[]) r.rows.elementAt(4);
- assertEquals("Double.Nan SQLite representation", "Inf", row5[0]);
-
- try {
- st.close();
- st.bind(1,0.0);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- }
- }
-
- public void testBindIntByteArray() throws Exception {
- String name = "Hello World";
- byte[] b = name.getBytes();
- String stringInHex = "";
-
- db.exec(DatabaseCreator.CREATE_TABLE_PARENT, null);
- st = db.prepare("insert into " + DatabaseCreator.PARENT_TABLE
- + " values (:one, :two);");
- st.bind(1, 2);
- st.bind(2, b);
- st.step();
-
- //compare what was stored with input based on Hex representation
- // since type of column is CHAR
- TableResult r = db.get_table("select * from "
- + DatabaseCreator.PARENT_TABLE);
- String[] row = (String[]) r.rows.elementAt(0);
-
- for (byte aByte : b) {
- stringInHex += Integer.toHexString(aByte);
- }
- stringInHex = "X'" + stringInHex + "'";
- assertTrue(stringInHex.equalsIgnoreCase(row[1]));
-
- try {
- st.close();
- st.bind(1,name.getBytes());
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- }
- }
-
- public void testBindIntString() throws Exception {
- String name = "Hello World";
- db.exec(DatabaseCreator.CREATE_TABLE_PARENT, null);
- st = db.prepare("insert into " + DatabaseCreator.PARENT_TABLE
- + " values (:one, :two);");
- st.bind(1, 2);
- st.bind(2, name);
- st.step();
-
- TableResult r = db.get_table("select * from "
- + DatabaseCreator.PARENT_TABLE);
- String[] row = (String[]) r.rows.elementAt(0);
- assertEquals(name,row[1]);
-
- try {
- st.close();
- st.bind(1,name);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- }
- }
-
- public void testBindInt() throws Exception {
- try {
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- st.bind(4);
- st.bind(1, 4);
- st.bind(2, 10);
- st.bind(3, 30);
- st.step();
- fail();
- } catch (SQLite.Exception expected) {
- // What happens if null is bound to non existing variable position
- assertEquals("parameter position out of bounds", expected.getMessage());
- }
-
- // functional tests
-
- try {
- st.reset();
- st.bind(1);
- st.bind(2, 10);
- st.bind(3, 30);
- st.step();
- fail();
- } catch (SQLite.Exception expected) {
- // What happens if null is bound to NON NULL field
- assertEquals("SQL logic error or missing database", expected.getMessage());
- }
-
- st.reset();
- st.bind(1, 3);
- st.bind(2);
- st.bind(3, 30);
- st.step();
- }
-
- public void testBind_zeroblob() {
- try {
- st.bind_zeroblob(1, 128);
- fail();
- } catch (SQLite.Exception expected) {
- assertEquals("unsupported", expected.getMessage());
- }
- }
-
- public void testBind_parameter_count() throws Exception {
- try {
- st.bind_parameter_count();
- fail();
- } catch (SQLite.Exception expected) {
- assertEquals("stmt already closed", expected.getMessage());
- }
-
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- assertEquals(3, st.bind_parameter_count());
-
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (?, ?, ?)");
- assertEquals(3, st.bind_parameter_count());
-
- st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
- assertEquals(0, st.bind_parameter_count());
-
- try {
- st.close();
- st.bind_parameter_count();
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- }
-
- }
-
- public void testBind_parameter_name() {
- try {
- st.bind_parameter_name(1);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- assertEquals("stmt already closed", expected.getMessage());
- }
-
- try {
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- assertEquals(":one", st.bind_parameter_name(1));
- assertEquals(":two", st.bind_parameter_name(2));
- assertEquals(":three", st.bind_parameter_name(3));
- st.bind_parameter_name(4);
- fail();
- } catch (SQLite.Exception expected) {
- assertEquals("parameter position out of bounds", expected.getMessage());
- }
- }
-
- public void testBind_parameter_index() throws Exception {
- try {
- st.bind_parameter_index("");
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- assertEquals("stmt already closed", expected.getMessage());
- }
-
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- assertEquals(3, st.bind_parameter_index(":three"));
-
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- assertEquals(0, st.bind_parameter_index(":t"));
-
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (?, ?, ?)");
- assertEquals(0, st.bind_parameter_index("?"));
- }
-
- public void testColumn_int() throws Exception {
- db.exec(CREATE_ALL_TYPES, null);
- db.exec(INSERT_ALL_TYPES, null);
-
- Object columnObject;
- int intColumn;
- String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
-
- st = db.prepare(selectStmt);
- st.step();
- // select 'speed' value
- columnObject = st.column(1);
- intColumn = st.column_int(1);
- assertNotNull(intColumn);
-
- assertTrue("Integer".equalsIgnoreCase(st.column_decltype(1)));
- int stSpeed = Integer.parseInt(columnObject.toString());
- assertNotNull(stSpeed);
- assertEquals( intColumn, stSpeed);
- assertEquals(10,stSpeed);
-
- selectStmt = "select TextVal from "+ ALL_TYPES_TABLE;
-
- st = db.prepare(selectStmt);
- st.step();
- st.column_int(0);
- }
-
- public void testColumn_long() throws Exception {
- Object columnObject;
- long longColumn;
- String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
- st = db.prepare(selectStmt);
- st.step();
- columnObject = st.column(1);
- longColumn = st.column_long(1);
- assertNotNull(longColumn);
- // column declared as integer
- assertTrue("Integer".equalsIgnoreCase(st.column_decltype(1)));
- int stSpeed = Integer.parseInt(columnObject.toString());
- assertNotNull(stSpeed);
- assertEquals( longColumn, stSpeed);
-
- try {
- st.column_long(4);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- assertEquals("column out of bounds", expected.getMessage());
- }
-
- try {
- st.column_long(-1);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- assertEquals("column out of bounds", expected.getMessage());
- }
- }
-
- public void testColumn_double() throws Exception {
- db.exec(CREATE_ALL_TYPES, null);
- db.exec(INSERT_ALL_TYPES, null);
-
- double doubleColumn;
- double actualVal = 23.2;
- String selectStmt = "select DoubleVal from "+ ALL_TYPES_TABLE;
-
- st = db.prepare(selectStmt);
- st.step();
- // select double value
- doubleColumn = st.column_double(0);
- assertNotNull(doubleColumn);
-
- assertTrue("DOUBLE".equalsIgnoreCase(st.column_decltype(0)));
- assertNotNull(doubleColumn);
- assertEquals( actualVal, doubleColumn);
-
- // Exception test
- selectStmt = "select dateVal from "+ ALL_TYPES_TABLE;
-
- st = db.prepare(selectStmt);
- st.step();
- // select double value
- st.column_double(0);
- }
-
- public void testColumn_bytes() throws Exception {
- db.exec("create table B(id integer primary key, val blob)",null);
- db.exec("insert into B values(1, zeroblob(128))", null);
- st = db.prepare("select val from B where id = 1");
- assertTrue(st.step());
- st.column_bytes(0);
- }
-
- public void testColumn_string() throws Exception {
- db.exec(CREATE_ALL_TYPES, null);
- db.exec(INSERT_ALL_TYPES, null);
-
- String stringColumn;
- String actualVal = "test string";
- String selectStmt = "select charStr from "+ ALL_TYPES_TABLE;
-
- st = db.prepare(selectStmt);
- st.step();
- // select string value
- stringColumn = st.column_string(0);
- assertNotNull(stringColumn);
-
- assertTrue("CHAR(20)".equalsIgnoreCase(st.column_decltype(0)));
- assertNotNull(stringColumn);
- assertEquals( actualVal, stringColumn);
-
- // Exception test
- selectStmt = "select DoubleVal from "+ ALL_TYPES_TABLE;
-
- st = db.prepare(selectStmt);
- st.step();
- st.column_string(0);
- }
-
- public void testColumn_type() throws Exception {
- db.exec(CREATE_ALL_TYPES, null);
- db.exec(INSERT_ALL_TYPES, null);
- st = db.prepare("select * from " + ALL_TYPES_TABLE);
- st.step();
-
- // Exception test
- try {
- st.column_type(100);
- fail();
- } catch (SQLite.Exception expected) {
- }
-
- /*
- Dictionary
-
- public static final int SQLITE_INTEGER = 1;
- public static final int SQLITE_FLOAT = 2;
- public static final int SQLITE_BLOB = 4;
- public static final int SQLITE_NULL = 5;
- public static final int SQLITE3_TEXT = 3;
- public static final int SQLITE_NUMERIC = -1;
- */
-
- assertEquals(Constants.SQLITE3_TEXT, st.column_type(23)); // ok TEXT
- assertEquals(Constants.SQLITE3_TEXT, st.column_type(13)); // CHAR(20)
-
- assertEquals(Constants.SQLITE_FLOAT, st.column_type(8));
- assertEquals(Constants.SQLITE_FLOAT, st.column_type(9));
- assertEquals(Constants.SQLITE_FLOAT, st.column_type(10)); // FLOAT
-
- for (int i = 0; i < 8; i++) {
- assertEquals("Expected Integer at position " + i,
- Constants.SQLITE_INTEGER, st.column_type(i));
- }
-
- assertEquals(Constants.SQLITE_NULL, st.column_type(28));
- assertEquals(Constants.SQLITE_NULL, st.column_type(29));
-
- // Failing tests
- assertTrue("INTEGER".equalsIgnoreCase(st.column_decltype(12)));
- assertEquals(Constants.SQLITE_INTEGER, st.column_type(12));
-
- assertTrue("FLOAT".equalsIgnoreCase(st.column_decltype(11)));
- assertEquals(Constants.SQLITE_FLOAT, st.column_type(11)); // FLOAT ->
- // got INTEGER
- assertTrue("BLOB".equalsIgnoreCase(st.column_decltype(19)));
- assertEquals(Constants.SQLITE_BLOB, st.column_type(19)); // Blob got
- // INTEGER
-
- }
-
- /**
- * Wrong value is returned in case of a prepared statement to which a '*' bound
- */
- public void testColumn_count() throws Exception {
- String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
- st = db.prepare(selectStmt);
-
- assertEquals(3, st.column_count());
-
- st.step();
- int columnCount = st.column_count();
- assertNotNull(columnCount);
- assertEquals( 3, columnCount);
-
- // actual prepared statement
- selectStmt = "select ? from "+DatabaseCreator.SIMPLE_TABLE1;
- st = db.prepare(selectStmt);
-
- assertEquals(3, st.column_count());
-
- st.bind(1, "*");
- st.step();
- columnCount = st.column_count();
- assertNotNull(columnCount);
- assertEquals( 3, columnCount);
- }
-
- public void testColumn() throws Exception {
- Object columnObject;
- int intColumn;
- String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
- db.get_table(selectStmt);
- st = db.prepare(selectStmt);
- st.step();
- columnObject = st.column(1);
- intColumn = st.column_int(1);
- assertNotNull(intColumn);
- assertTrue("Integer".equalsIgnoreCase(st.column_decltype(1)));
- int stSpeed = Integer.parseInt(columnObject.toString());
- assertNotNull(stSpeed);
- assertEquals( intColumn, stSpeed);
-
- try {
- assertNotNull(columnObject);
- ((Integer) columnObject).intValue();
- fail("Cast to Integer should fail");
- } catch (ClassCastException expected) {
- }
-
- try {
- st.column(4);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- assertEquals("column out of bounds", expected.getMessage());
- }
-
- try {
- st.column(-1);
- fail("Exception expected");
- } catch (SQLite.Exception expected) {
- assertEquals("column out of bounds", expected.getMessage());
- }
- }
-
- public void testColumn_table_name() {
- try {
- st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
- st.column_table_name(1);
- fail("Function is now supported.");
- } catch (SQLite.Exception expected) {
- assertEquals("unsupported", expected.getMessage());
- }
- }
-
- public void testColumn_database_name() {
- try {
- st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
- + " values (:one,:two,:three)");
- st.column_database_name(1);
- fail("Function is now supported.");
- } catch (SQLite.Exception expected) {
- assertEquals("unsupported", expected.getMessage());
- }
- }
-
- public void testColumn_decltype() throws Exception {
- db.exec(CREATE_ALL_TYPES, null);
- db.exec(INSERT_ALL_TYPES, null);
- st = db.prepare("select * from " + ALL_TYPES_TABLE);
- st.step();
-
- // Exception test
- try {
- st.column_decltype(100);
- fail();
- } catch (SQLite.Exception expected) {
- }
-
- assertTrue(st.column_decltype(0), "BOOLEAN".equalsIgnoreCase(st
- .column_decltype(0)));
- assertTrue(st.column_decltype(1), "INT".equalsIgnoreCase(st
- .column_decltype(1)));
- assertTrue(st.column_decltype(2), "LONG".equalsIgnoreCase(st
- .column_decltype(2)));
- assertTrue(st.column_decltype(3), "BIGINT".equalsIgnoreCase(st
- .column_decltype(3)));
- assertTrue(st.column_decltype(4), "TINYINT".equalsIgnoreCase(st
- .column_decltype(4)));
- assertTrue(st.column_decltype(5), "SMALLINT".equalsIgnoreCase(st
- .column_decltype(5)));
- assertTrue(st.column_decltype(6), "MEDIUMINT".equalsIgnoreCase(st
- .column_decltype(6)));
- assertTrue(st.column_decltype(7), "INTEGER".equalsIgnoreCase(st
- .column_decltype(7)));
- assertTrue(st.column_decltype(8), "REAL".equalsIgnoreCase(st
- .column_decltype(8)));
- assertTrue(st.column_decltype(9), "DOUBLE".equalsIgnoreCase(st
- .column_decltype(9)));
- assertTrue(st.column_decltype(10), "FLOAT".equalsIgnoreCase(st
- .column_decltype(10)));
- assertTrue(st.column_decltype(11), "DECIMAL".equalsIgnoreCase(st
- .column_decltype(11)));
- assertTrue(st.column_decltype(12), "NUMERIC".equalsIgnoreCase(st
- .column_decltype(12)));
- assertTrue(st.column_decltype(13), "CHAR(20)".equalsIgnoreCase(st
- .column_decltype(13)));
-
- assertTrue(st.column_decltype(19), "BLOB".equalsIgnoreCase(st
- .column_decltype(19)));
-
- assertTrue(st.column_decltype(23), "TEXT".equalsIgnoreCase(st
- .column_decltype(23)));
- assertTrue(st.column_decltype(28), "URL".equalsIgnoreCase(st
- .column_decltype(28)));
- assertTrue(st.column_decltype(29), "URL".equalsIgnoreCase(st
- .column_decltype(29)));
- }
-
- public void testColumn_origin_name() {
- try {
- st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
- st.column_origin_name(1);
- fail("Function is now supported.");
- } catch (SQLite.Exception expected) {
- assertEquals("unsupported", expected.getMessage());
- }
- }
-}
diff --git a/luni/src/test/java/libcore/sqlite/QueryTimeoutTest.java b/luni/src/test/java/libcore/sqlite/QueryTimeoutTest.java
deleted file mode 100644
index 8febfff..0000000
--- a/luni/src/test/java/libcore/sqlite/QueryTimeoutTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package libcore.sqlite;
-
-import SQLite.Database;
-import SQLite.Function;
-import SQLite.FunctionContext;
-import SQLite.JDBC2z.JDBCConnection;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import junit.framework.TestCase;
-import tests.support.Support_SQL;
-
-
-/**
- * Test that statements honor their timeout.
- */
-public final class QueryTimeoutTest extends TestCase {
-
- private static final String EXEC_QUERY
- = "insert into t_copy select a from t_orig where DELAY(2,1)=1";
-
- private static final String FETCH_QUERY = "select a from t_orig where DELAY(2,1)=1";
-
- private Connection connection;
-
- @Override public void setUp() throws Exception {
- Support_SQL.loadDriver();
- connection = Support_SQL.getConnection();
-
- exec("drop table if exists t_orig;");
- exec("drop table if exists t_copy;");
- exec("create table t_orig (a int)");
- exec("create table t_copy (a int)");
-
- for (int i = 0; i < 7; i++) {
- exec("insert into t_orig values (" + i + ");");
- }
-
- Database database = ((JDBCConnection) connection).getSQLiteDatabase();
- database.create_function("DELAY", 2, new Function() {
- @Override public void function(FunctionContext functionContext, String[] args) {
- try {
- int seconds = Integer.parseInt(args[0]);
- Thread.sleep(seconds * 1000);
- } catch (InterruptedException ignored) {
- }
- functionContext.set_result(Integer.parseInt(args[1]));
- }
- @Override public void last_step(FunctionContext functionContext) {
- }
- @Override public void step(FunctionContext functionContext, String[] args) {
- }
- });
-
- connection.setAutoCommit(true);
- }
-
- @Override public void tearDown() throws Exception {
- connection.close();
- }
-
- private void exec(String queryString) throws Exception {
- System.out.println("Executing " + queryString);
- Statement statement = null;
- try {
- statement = connection.createStatement();
- statement.execute(queryString);
- } finally {
- if (statement != null) {
- statement.close();
- }
- }
- }
-
- public void testPreparedStatementFetch() throws Exception {
- PreparedStatement statement = connection.prepareStatement(FETCH_QUERY);
- statement.setQueryTimeout(1);
- ResultSet resultSet = null;
- try {
- resultSet = statement.executeQuery();
- while (resultSet.next()) {
- }
- fail();
- } catch (SQLException expected) {
- } finally {
- statement.close();
- if (resultSet != null) {
- resultSet.close();
- }
- }
- }
-
- public void testPreparedStatementUpdate() throws Exception {
- PreparedStatement statement = connection.prepareStatement(EXEC_QUERY);
- try {
- statement.setQueryTimeout(1);
- statement.execute();
- fail();
- } catch (SQLException expected) {
- } finally {
- statement.close();
- }
- }
-
- public void testInvalidTimeout() throws Exception {
- connection.setAutoCommit(true);
- PreparedStatement statement = connection.prepareStatement("select 'hello'");
-
- try {
- statement.setQueryTimeout(-1);
- fail();
- } catch (SQLException expected) {
- }
-
- ResultSet resultSet = statement.executeQuery();
- resultSet.close();
- statement.close();
- }
-
- public void testExecuteUpdate() throws Exception {
- Statement statement = connection.createStatement();
- try {
- statement.setQueryTimeout(1);
- statement.executeUpdate(EXEC_QUERY);
- fail();
- } catch (SQLException expected) {
- } finally {
- statement.close();
- }
- }
-
- public void testTimeoutAndStatementReuse() throws Exception {
- Statement statement = connection.createStatement();
- statement.setQueryTimeout(1);
- for (int i = 0; i < 3; i++) {
- try {
- ResultSet resultSet = statement.executeQuery(FETCH_QUERY);
- while (resultSet.next()) {
- }
- fail();
- } catch (SQLException expected) {
- }
- }
- statement.close();
- }
-}
diff --git a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
index 28ae416..9875647 100644
--- a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
+++ b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
@@ -22,25 +22,27 @@ import java.io.RandomAccessFile;
import java.util.TimeZone;
public class ZoneInfoDBTest extends junit.framework.TestCase {
- private static final String CURRENT_VERSION = ZoneInfoDB.getInstance().getVersion();
- // Any new file in /data...
- private static final String TZDATA_IN_DATA = System.getenv("ANDROID_DATA") + "/misc/zoneinfo/tzdata";
- // ...overrides any existing file in /system.
- private static final String TZDATA_IN_ROOT = System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata";
+ // The base tzdata file, always present on a device.
+ private static final String TZDATA_IN_ROOT =
+ System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata";
// An empty override file should fall back to the default file.
public void testEmptyOverrideFile() throws Exception {
- ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(makeEmptyFile(), TZDATA_IN_DATA, TZDATA_IN_ROOT);
- assertEquals(CURRENT_VERSION, data.getVersion());
- assertEquals(TimeZone.getAvailableIDs().length, data.getAvailableIDs().length);
+ ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData dataWithEmptyOverride =
+ new ZoneInfoDB.TzData(makeEmptyFile(), TZDATA_IN_ROOT);
+ assertEquals(data.getVersion(), dataWithEmptyOverride.getVersion());
+ assertEquals(data.getAvailableIDs().length, dataWithEmptyOverride.getAvailableIDs().length);
}
// A corrupt override file should fall back to the default file.
public void testCorruptOverrideFile() throws Exception {
- ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(makeCorruptFile(), TZDATA_IN_DATA, TZDATA_IN_ROOT);
- assertEquals(CURRENT_VERSION, data.getVersion());
- assertEquals(TimeZone.getAvailableIDs().length, data.getAvailableIDs().length);
+ ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+ ZoneInfoDB.TzData dataWithCorruptOverride =
+ new ZoneInfoDB.TzData(makeCorruptFile(), TZDATA_IN_ROOT);
+ assertEquals(data.getVersion(), dataWithCorruptOverride.getVersion());
+ assertEquals(data.getAvailableIDs().length, dataWithCorruptOverride.getAvailableIDs().length);
}
// Given no tzdata files we can use, we should fall back to built-in "GMT".
@@ -53,7 +55,6 @@ public class ZoneInfoDBTest extends junit.framework.TestCase {
// Given a valid override file, we should find ourselves using that.
public void testGoodOverrideFile() throws Exception {
- // We copy /system/usr/share/zoneinfo/tzdata because we know that always exists.
RandomAccessFile in = new RandomAccessFile(TZDATA_IN_ROOT, "r");
byte[] content = new byte[(int) in.length()];
in.readFully(content);
@@ -65,16 +66,40 @@ public class ZoneInfoDBTest extends junit.framework.TestCase {
content[10] = 'z';
in.close();
+ ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
String goodFile = makeTemporaryFile(content);
try {
- ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(goodFile, TZDATA_IN_DATA, TZDATA_IN_ROOT);
- assertEquals("9999z", data.getVersion());
- assertEquals(TimeZone.getAvailableIDs().length, data.getAvailableIDs().length);
+ ZoneInfoDB.TzData dataWithOverride = new ZoneInfoDB.TzData(goodFile, TZDATA_IN_ROOT);
+ assertEquals("9999z", dataWithOverride.getVersion());
+ assertEquals(data.getAvailableIDs().length, dataWithOverride.getAvailableIDs().length);
} finally {
new File(goodFile).delete();
}
}
+ // Confirms any caching that exists correctly handles TimeZone mutability.
+ public void testMakeTimeZone_timeZoneMutability() throws Exception {
+ ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+ String tzId = "Europe/London";
+ ZoneInfo first = data.makeTimeZone(tzId);
+ ZoneInfo second = data.makeTimeZone(tzId);
+ assertNotSame(first, second);
+
+ assertTrue(first.hasSameRules(second));
+
+ first.setID("Not Europe/London");
+
+ assertFalse(first.getID().equals(second.getID()));
+
+ first.setRawOffset(3600);
+ assertFalse(first.getRawOffset() == second.getRawOffset());
+ }
+
+ public void testMakeTimeZone_notFound() throws Exception {
+ ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+ assertNull(data.makeTimeZone("THIS_TZ_DOES_NOT_EXIST"));
+ }
+
private static String makeCorruptFile() throws Exception {
return makeTemporaryFile("invalid content".getBytes());
}
diff --git a/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java b/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java
new file mode 100644
index 0000000..7194414
--- /dev/null
+++ b/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import junit.framework.TestCase;
+import org.kxml2.io.KXmlParser;
+import org.kxml2.io.KXmlSerializer;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+public class XmlPullParserFactoryTest extends TestCase {
+
+ public void testDefaultNewInstance() throws Exception {
+ XmlPullParserFactory factory = XmlPullParserFactory.newInstance(null, null);
+ XmlPullParser parser = factory.newPullParser();
+ XmlSerializer serializer = factory.newSerializer();
+
+ assertNotNull(parser);
+ assertNotNull(serializer);
+ assertTrue(parser instanceof KXmlParser);
+ assertTrue(serializer instanceof KXmlSerializer);
+ }
+
+ /**
+ * Tests that trying to instantiate a parser with an empty list of
+ * parsers and serializers fails.
+ */
+ public void testOverriding_emptyClassList() {
+ TestXmlPullParserFactory tf = new TestXmlPullParserFactory(null, null);
+
+ try {
+ tf.newPullParser();
+ fail();
+ } catch (XmlPullParserException expected) {
+ }
+
+ try {
+ tf.newPullParser();
+ fail();
+ } catch (XmlPullParserException expected) {
+ }
+ }
+
+ public void testOverriding_customClassList() throws Exception {
+ TestXmlPullParserFactory tf = new TestXmlPullParserFactory(
+ new String[] { "libcore.xml.XmlPullParserFactoryTest$XmlPullParserStub" },
+ new String[] { "libcore.xml.XmlPullParserFactoryTest$XmlSerializerStub" });
+
+ assertTrue(tf.newPullParser() instanceof XmlPullParserStub);
+ assertTrue(tf.newSerializer() instanceof XmlSerializerStub);
+
+ // Also check that we ignore instantiation errors as long as
+ // at least one parser / serializer is instantiable.
+ tf = new TestXmlPullParserFactory(
+ new String[] {
+ "libcore.xml.XmlPullParserFactoryTest$InaccessibleXmlParser",
+ "libcore.xml.XmlPullParserFactoryTest$XmlPullParserStub" },
+ new String[] {
+ "libcore.xml.XmlPullParserFactoryTest$InaccessibleXmlSerializer",
+ "libcore.xml.XmlPullParserFactoryTest$XmlSerializerStub" });
+
+ assertTrue(tf.newPullParser() instanceof XmlPullParserStub);
+ assertTrue(tf.newSerializer() instanceof XmlSerializerStub);
+ }
+
+ // https://b/12956724
+ public void testSetFeature_setsFeatureOnlyIfTrue() throws Exception {
+ TestXmlPullParserFactory tf = new TestXmlPullParserFactory(
+ new String[] { "libcore.xml.XmlPullParserFactoryTest$XmlParserThatHatesAllFeatures" }, null);
+
+ tf.setFeature("foo", false);
+ tf.newPullParser();
+ }
+
+
+ /**
+ * A class that makes use of inherited XmlPullParserFactory fields to check they are
+ * supported.
+ */
+ static final class TestXmlPullParserFactory extends XmlPullParserFactory {
+ TestXmlPullParserFactory(String[] parserClassList, String[] serializerClassList) {
+ super();
+ parserClasses.remove(0);
+ serializerClasses.remove(0);
+
+ try {
+ if (parserClassList != null) {
+ for (String parserClass : parserClassList) {
+ parserClasses.add(Class.forName(parserClass));
+ }
+ }
+
+ if (serializerClassList != null) {
+ for (String serializerClass : serializerClassList) {
+ serializerClasses.add(Class.forName(serializerClass));
+ }
+ }
+ } catch (ClassNotFoundException ignored) {
+ throw new AssertionError(ignored);
+ }
+ }
+ }
+
+ public static final class XmlParserThatHatesAllFeatures extends XmlPullParserStub {
+ @Override
+ public void setFeature(String name, boolean state) {
+ fail();
+ }
+ }
+
+ static final class InaccessibleXmlSerializer extends XmlSerializerStub {
+ }
+
+ static final class InaccessibleXmlParser extends XmlPullParserStub {
+ }
+
+ public static class XmlSerializerStub implements XmlSerializer {
+
+ public void setFeature(String name, boolean state) throws IllegalArgumentException,
+ IllegalStateException {
+ }
+
+ public boolean getFeature(String name) {
+ return false;
+ }
+
+ public void setProperty(String name, Object value) {
+ }
+
+ public Object getProperty(String name) {
+ return null;
+ }
+
+ public void setOutput(OutputStream os, String encoding) throws IOException {
+ }
+
+ public void setOutput(Writer writer) throws IOException {
+ }
+
+ public void startDocument(String encoding, Boolean standalone) throws IOException {
+ }
+
+ public void endDocument() throws IOException {
+ }
+
+ public void setPrefix(String prefix, String namespace) throws IOException {
+ }
+
+ public String getPrefix(String namespace, boolean generatePrefix) throws IllegalArgumentException {
+ return null;
+ }
+
+ public int getDepth() {
+ return 0;
+ }
+
+ public String getNamespace() {
+ return null;
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ public XmlSerializer startTag(String namespace, String name) throws IOException {
+ return null;
+ }
+
+ public XmlSerializer attribute(String namespace, String name, String value) throws IOException {
+ return null;
+ }
+
+ public XmlSerializer endTag(String namespace, String name) throws IOException {
+ return null;
+ }
+
+ public XmlSerializer text(String text) throws IOException {
+ return null;
+ }
+
+ public XmlSerializer text(char[] buf, int start, int len) throws IOException {
+ return null;
+ }
+
+ public void cdsect(String text) throws IOException {
+ }
+
+ public void entityRef(String text) throws IOException {
+ }
+
+ public void processingInstruction(String text) throws IOException {
+ }
+
+ public void comment(String text) throws IOException {
+ }
+
+ public void docdecl(String text) throws IOException {
+ }
+
+ public void ignorableWhitespace(String text) throws IOException {
+ }
+
+ public void flush() throws IOException {
+ }
+ }
+
+ public static class XmlPullParserStub implements XmlPullParser {
+ public void setFeature(String name, boolean state) throws XmlPullParserException {
+ }
+
+ public boolean getFeature(String name) {
+ return false;
+ }
+
+ public void setProperty(String name, Object value) throws XmlPullParserException {
+ }
+
+ public Object getProperty(String name) {
+ return null;
+ }
+
+ public void setInput(Reader in) throws XmlPullParserException {
+ }
+
+ public void setInput(InputStream inputStream, String inputEncoding)
+ throws XmlPullParserException {
+ }
+
+ public String getInputEncoding() {
+ return null;
+ }
+
+ public void defineEntityReplacementText(String entityName, String replacementText)
+ throws XmlPullParserException {
+ }
+
+ public int getNamespaceCount(int depth) throws XmlPullParserException {
+ return 0;
+ }
+
+ public String getNamespacePrefix(int pos) throws XmlPullParserException {
+ return null;
+ }
+
+ public String getNamespaceUri(int pos) throws XmlPullParserException {
+ return null;
+ }
+
+ public String getNamespace(String prefix) {
+ return null;
+ }
+
+ public int getDepth() {
+ return 0;
+ }
+
+ public String getPositionDescription() {
+ return null;
+ }
+
+ public int getLineNumber() {
+ return 0;
+ }
+
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ public boolean isWhitespace() throws XmlPullParserException {
+ return false;
+ }
+
+ public String getText() {
+ return null;
+ }
+
+ public char[] getTextCharacters(int[] holderForStartAndLength) {
+ return null;
+ }
+
+ public String getNamespace() {
+ return null;
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ public String getPrefix() {
+ return null;
+ }
+
+ public boolean isEmptyElementTag() throws XmlPullParserException {
+ return false;
+ }
+
+ public int getAttributeCount() {
+ return 0;
+ }
+
+ public String getAttributeNamespace(int index) {
+ return null;
+ }
+
+ public String getAttributeName(int index) {
+ return null;
+ }
+
+ public String getAttributePrefix(int index) {
+ return null;
+ }
+
+ public String getAttributeType(int index) {
+ return null;
+ }
+
+ public boolean isAttributeDefault(int index) {
+ return false;
+ }
+
+ public String getAttributeValue(int index) {
+ return null;
+ }
+
+ public String getAttributeValue(String namespace, String name) {
+ return null;
+ }
+
+ public int getEventType() throws XmlPullParserException {
+ return 0;
+ }
+
+ public int next() throws XmlPullParserException, IOException {
+ return 0;
+ }
+
+ public int nextToken() throws XmlPullParserException, IOException {
+ return 0;
+ }
+
+ public void require(int type, String namespace, String name)
+ throws XmlPullParserException, IOException {
+ }
+
+ public String nextText() throws XmlPullParserException, IOException {
+ return null;
+ }
+
+ public int nextTag() throws XmlPullParserException, IOException {
+ return 0;
+ }
+ }
+}
diff --git a/luni/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java b/luni/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
deleted file mode 100644
index afdce5d..0000000
--- a/luni/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.archive.tests.java.util.jar;
-
-
-import junit.framework.TestCase;
-
-import tests.support.Support_PlatformFile;
-import tests.support.resource.Support_Resources;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.security.Permission;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Vector;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
-
-
-public class JarFileTest extends TestCase {
-
- // BEGIN android-added
- public byte[] getAllBytesFromStream(InputStream is) throws IOException {
- ByteArrayOutputStream bs = new ByteArrayOutputStream();
- byte[] buf = new byte[666];
- int iRead;
- int off;
- while (is.available() > 0) {
- iRead = is.read(buf, 0, buf.length);
- if (iRead > 0) bs.write(buf, 0, iRead);
- }
- return bs.toByteArray();
- }
-
- // END android-added
-
- private final String jarName = "hyts_patch.jar"; // a 'normal' jar file
-
- private final String jarName2 = "hyts_patch2.jar";
-
- private final String jarName3 = "hyts_manifest1.jar";
-
- private final String jarName4 = "hyts_signed.jar";
-
- private final String jarName5 = "hyts_signed_inc.jar";
-
- private final String jarName6 = "hyts_signed_sha256withrsa.jar";
-
- private final String jarName7 = "hyts_signed_sha256digest_sha256withrsa.jar";
-
- private final String jarName8 = "hyts_signed_sha512digest_sha512withecdsa.jar";
-
- private final String authAttrsJar = "hyts_signed_authAttrs.jar";
-
- private final String entryName = "foo/bar/A.class";
-
- private final String entryName3 = "coucou/FileAccess.class";
-
- private final String integrateJar = "Integrate.jar";
-
- private final String integrateJarEntry = "Test.class";
-
- private final String emptyEntryJar = "EmptyEntries_signed.jar";
-
- private final String emptyEntry1 = "subfolder/internalSubset01.js";
-
- private final String emptyEntry2 = "svgtest.js";
-
- private final String emptyEntry3 = "svgunit.js";
-
- private static final String VALID_CHAIN_JAR = "hyts_signed_validChain.jar";
-
- private static final String INVALID_CHAIN_JAR = "hyts_signed_invalidChain.jar";
-
- private File resources;
-
- // custom security manager
- SecurityManager sm = new SecurityManager() {
- final String forbidenPermissionName = "user.dir";
-
- public void checkPermission(Permission perm) {
- if (perm.getName().equals(forbidenPermissionName)) {
- throw new SecurityException();
- }
- }
- };
-
- @Override
- protected void setUp() {
- resources = Support_Resources.createTempFolder();
- }
-
- /**
- * java.util.jar.JarFile#JarFile(java.io.File)
- */
- public void test_ConstructorLjava_io_File() {
- try {
- JarFile jarFile = new JarFile(new File("Wrong.file"));
- fail("Should throw IOException");
- } catch (IOException e) {
- // expected
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- } catch (IOException e) {
- fail("Should not throw IOException");
- }
- }
-
- /**
- * java.util.jar.JarFile#JarFile(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() {
- try {
- JarFile jarFile = new JarFile("Wrong.file");
- fail("Should throw IOException");
- } catch (IOException e) {
- // expected
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName);
- String fileName = (new File(resources, jarName)).getCanonicalPath();
- JarFile jarFile = new JarFile(fileName);
- } catch (IOException e) {
- fail("Should not throw IOException");
- }
- }
-
- /**
- * java.util.jar.JarFile#JarFile(java.lang.String, boolean)
- */
- public void test_ConstructorLjava_lang_StringZ() {
- try {
- JarFile jarFile = new JarFile("Wrong.file", false);
- fail("Should throw IOException");
- } catch (IOException e) {
- // expected
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName);
- String fileName = (new File(resources, jarName)).getCanonicalPath();
- JarFile jarFile = new JarFile(fileName, true);
- } catch (IOException e) {
- fail("Should not throw IOException");
- }
- }
-
- /**
- * java.util.jar.JarFile#JarFile(java.io.File, boolean)
- */
- public void test_ConstructorLjava_io_FileZ() {
- try {
- JarFile jarFile = new JarFile(new File("Wrong.file"), true);
- fail("Should throw IOException");
- } catch (IOException e) {
- // expected
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName), false);
- } catch (IOException e) {
- fail("Should not throw IOException");
- }
- }
-
- /**
- * java.util.jar.JarFile#JarFile(java.io.File, boolean, int)
- */
- public void test_ConstructorLjava_io_FileZI() {
- try {
- JarFile jarFile = new JarFile(new File("Wrong.file"), true,
- ZipFile.OPEN_READ);
- fail("Should throw IOException");
- } catch (IOException e) {
- // expected
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName), false,
- ZipFile.OPEN_READ);
- } catch (IOException e) {
- fail("Should not throw IOException");
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName), false,
- ZipFile.OPEN_READ | ZipFile.OPEN_DELETE + 33);
- fail("Should throw IllegalArgumentException");
- } catch (IOException e) {
- fail("Should not throw IOException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * Constructs JarFile object.
- *
- * java.util.jar.JarFile#JarFile(java.io.File)
- * java.util.jar.JarFile#JarFile(java.lang.String)
- */
- public void testConstructor_file() throws IOException {
- File f = new File(resources, jarName);
- Support_Resources.copyFile(resources, null, jarName);
- assertTrue(new JarFile(f).getEntry(entryName).getName().equals(
- entryName));
- assertTrue(new JarFile(f.getPath()).getEntry(entryName).getName()
- .equals(entryName));
- }
-
- /**
- * java.util.jar.JarFile#entries()
- */
- public void test_entries() throws Exception {
- /*
- * Note only (and all of) the following should be contained in the file
- * META-INF/ META-INF/MANIFEST.MF foo/ foo/bar/ foo/bar/A.class Blah.txt
- */
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- Enumeration<JarEntry> e = jarFile.entries();
- int i;
- for (i = 0; e.hasMoreElements(); i++) {
- e.nextElement();
- }
- assertEquals(jarFile.size(), i);
- jarFile.close();
- assertEquals(6, i);
- }
-
- public void test_entries2() throws Exception {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- Enumeration<JarEntry> enumeration = jarFile.entries();
- jarFile.close();
- try {
- enumeration.hasMoreElements();
- fail("hasMoreElements() did not detect a closed jar file");
- } catch (IllegalStateException e) {
- }
- Support_Resources.copyFile(resources, null, jarName);
- jarFile = new JarFile(new File(resources, jarName));
- enumeration = jarFile.entries();
- jarFile.close();
- try {
- enumeration.nextElement();
- fail("nextElement() did not detect closed jar file");
- } catch (IllegalStateException e) {
- }
- }
-
- /**
- * @throws IOException
- * java.util.jar.JarFile#getJarEntry(java.lang.String)
- */
- public void test_getEntryLjava_lang_String() throws IOException {
- try {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- assertEquals("Error in returned entry", 311, jarFile.getEntry(
- entryName).getSize());
- jarFile.close();
- } catch (Exception e) {
- fail("Exception during test: " + e.toString());
- }
-
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- Enumeration<JarEntry> enumeration = jarFile.entries();
- assertTrue(enumeration.hasMoreElements());
- while (enumeration.hasMoreElements()) {
- JarEntry je = enumeration.nextElement();
- jarFile.getEntry(je.getName());
- }
-
- enumeration = jarFile.entries();
- assertTrue(enumeration.hasMoreElements());
- JarEntry je = enumeration.nextElement();
- try {
- jarFile.close();
- jarFile.getEntry(je.getName());
- // fail("IllegalStateException expected.");
- } catch (IllegalStateException ee) { // Per documentation exception
- // may be thrown.
- // expected
- }
- }
-
- /**
- * @throws IOException
- * java.util.jar.JarFile#getJarEntry(java.lang.String)
- */
- public void test_getJarEntryLjava_lang_String() throws IOException {
- try {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- assertEquals("Error in returned entry", 311, jarFile.getJarEntry(
- entryName).getSize());
- jarFile.close();
- } catch (Exception e) {
- fail("Exception during test: " + e.toString());
- }
-
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- Enumeration<JarEntry> enumeration = jarFile.entries();
- assertTrue(enumeration.hasMoreElements());
- while (enumeration.hasMoreElements()) {
- JarEntry je = enumeration.nextElement();
- jarFile.getJarEntry(je.getName());
- }
-
- enumeration = jarFile.entries();
- assertTrue(enumeration.hasMoreElements());
- JarEntry je = enumeration.nextElement();
- try {
- jarFile.close();
- jarFile.getJarEntry(je.getName());
- // fail("IllegalStateException expected.");
- } catch (IllegalStateException ee) { // Per documentation exception
- // may be thrown.
- // expected
- }
- }
-
-
- /**
- * java.util.jar.JarFile#getJarEntry(java.lang.String)
- */
- public void testGetJarEntry() throws Exception {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- assertEquals("Error in returned entry", 311, jarFile.getEntry(
- entryName).getSize());
- jarFile.close();
-
- // tests for signed jars
- // test all signed jars in the /Testres/Internal/SignedJars directory
- String jarDirUrl = Support_Resources
- .getResourceURL("/../internalres/signedjars");
- Vector<String> signedJars = new Vector<String>();
- try {
- InputStream is = new URL(jarDirUrl + "/jarlist.txt").openStream();
- while (is.available() > 0) {
- StringBuilder linebuff = new StringBuilder(80); // Typical line
- // length
- done: while (true) {
- int nextByte = is.read();
- switch (nextByte) {
- case -1:
- break done;
- case (byte) '\r':
- if (linebuff.length() == 0) {
- // ignore
- }
- break done;
- case (byte) '\n':
- if (linebuff.length() == 0) {
- // ignore
- }
- break done;
- default:
- linebuff.append((char) nextByte);
- }
- }
- if (linebuff.length() == 0) {
- break;
- }
- String line = linebuff.toString();
- signedJars.add(line);
- }
- is.close();
- } catch (IOException e) {
- // no list of jars found
- }
-
- for (int i = 0; i < signedJars.size(); i++) {
- String jarName = signedJars.get(i);
- try {
- File file = Support_Resources.getExternalLocalFile(jarDirUrl
- + "/" + jarName);
- jarFile = new JarFile(file, true);
- boolean foundCerts = false;
- Enumeration<JarEntry> e = jarFile.entries();
- while (e.hasMoreElements()) {
- JarEntry entry = e.nextElement();
- InputStream is = jarFile.getInputStream(entry);
- is.skip(100000);
- is.close();
- Certificate[] certs = entry.getCertificates();
- if (certs != null && certs.length > 0) {
- foundCerts = true;
- break;
- }
- }
- assertTrue(
- "No certificates found during signed jar test for jar \""
- + jarName + "\"", foundCerts);
- } catch (IOException e) {
- fail("Exception during signed jar test for jar \"" + jarName
- + "\": " + e.toString());
- }
- }
- }
-
- /**
- * java.util.jar.JarFile#getManifest()
- */
- public void test_getManifest() {
- // Test for method java.util.jar.Manifest
- // java.util.jar.JarFile.getManifest()
- try {
- Support_Resources.copyFile(resources, null, jarName);
- JarFile jarFile = new JarFile(new File(resources, jarName));
- assertNotNull("Error--Manifest not returned", jarFile.getManifest());
- jarFile.close();
- } catch (Exception e) {
- fail("Exception during 1st test: " + e.toString());
- }
- try {
- Support_Resources.copyFile(resources, null, jarName2);
- JarFile jarFile = new JarFile(new File(resources, jarName2));
- assertNull("Error--should have returned null", jarFile
- .getManifest());
- jarFile.close();
- } catch (Exception e) {
- fail("Exception during 2nd test: " + e.toString());
- }
-
- try {
- // jarName3 was created using the following test
- Support_Resources.copyFile(resources, null, jarName3);
- JarFile jarFile = new JarFile(new File(resources, jarName3));
- assertNotNull("Should find manifest without verifying", jarFile
- .getManifest());
- jarFile.close();
- } catch (Exception e) {
- fail("Exception during 3rd test: " + e.toString());
- }
-
- try {
- // this is used to create jarName3 used in the previous test
- Manifest manifest = new Manifest();
- Attributes attributes = manifest.getMainAttributes();
- attributes.put(new Attributes.Name("Manifest-Version"), "1.0");
- ByteArrayOutputStream manOut = new ByteArrayOutputStream();
- manifest.write(manOut);
- byte[] manBytes = manOut.toByteArray();
- File file = File.createTempFile(
- Support_PlatformFile.getNewPlatformFile("hyts_manifest1",
- ""), ".jar");
- JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(
- file.getAbsolutePath()));
- ZipEntry entry = new ZipEntry("META-INF/");
- entry.setSize(0);
- jarOut.putNextEntry(entry);
- entry = new ZipEntry(JarFile.MANIFEST_NAME);
- entry.setSize(manBytes.length);
- jarOut.putNextEntry(entry);
- jarOut.write(manBytes);
- entry = new ZipEntry("myfile");
- entry.setSize(1);
- jarOut.putNextEntry(entry);
- jarOut.write(65);
- jarOut.close();
- JarFile jar = new JarFile(file.getAbsolutePath(), false);
- assertNotNull("Should find manifest without verifying", jar
- .getManifest());
- jar.close();
- file.delete();
- } catch (IOException e) {
- fail("IOException 3");
- }
- try {
- Support_Resources.copyFile(resources, null, jarName2);
- JarFile jF = new JarFile(new File(resources, jarName2));
- jF.close();
- jF.getManifest();
- fail("FAILED: expected IllegalStateException");
- } catch (IllegalStateException ise) {
- // expected;
- } catch (Exception e) {
- fail("Exception during 4th test: " + e.toString());
- }
-
- Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
- JarFile jf;
- try {
- jf = new JarFile(new File(resources, "Broken_manifest.jar"));
- jf.getManifest();
- fail("IOException expected.");
- } catch (IOException e) {
- // expected.
- }
- }
-
- /**
- * java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
- */
- // This test doesn't pass on RI. If entry size is set up incorrectly,
- // SecurityException is thrown. But SecurityException is thrown on RI only
- // if jar file is signed incorrectly.
- public void test_getInputStreamLjava_util_jar_JarEntry_subtest0() throws Exception {
- File signedFile = null;
- try {
- Support_Resources.copyFile(resources, null, jarName4);
- signedFile = new File(resources, jarName4);
- } catch (Exception e) {
- fail("Failed to create local file 2: " + e);
- }
-
- try {
- JarFile jar = new JarFile(signedFile);
- JarEntry entry = new JarEntry(entryName3);
- InputStream in = jar.getInputStream(entry);
- in.read();
- } catch (Exception e) {
- fail("Exception during test 3: " + e);
- }
-
- try {
- JarFile jar = new JarFile(signedFile);
- JarEntry entry = new JarEntry(entryName3);
- InputStream in = jar.getInputStream(entry);
- // BEGIN android-added
- byte[] dummy = getAllBytesFromStream(in);
- // END android-added
- assertNull("found certificates", entry.getCertificates());
- } catch (Exception e) {
- fail("Exception during test 4: " + e);
- }
-
- try {
- JarFile jar = new JarFile(signedFile);
- JarEntry entry = new JarEntry(entryName3);
- entry.setSize(1076);
- InputStream in = jar.getInputStream(entry);
- // BEGIN android-added
- byte[] dummy = getAllBytesFromStream(in);
- // END android-added
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (Exception e) {
- fail("Exception during test 5: " + e);
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName5);
- signedFile = new File(resources, jarName5);
- } catch (Exception e) {
- fail("Failed to create local file 5: " + e);
- }
-
- try {
- JarFile jar = new JarFile(signedFile);
- JarEntry entry = new JarEntry(entryName3);
- InputStream in = jar.getInputStream(entry);
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (Exception e) {
- fail("Exception during test 5: " + e);
- }
-
- // SHA1 digest, SHA256withRSA signed JAR
- checkSignedJar(jarName6);
-
- // SHA-256 digest, SHA256withRSA signed JAR
- checkSignedJar(jarName7);
-
- // SHA-512 digest, SHA512withECDSA signed JAR
- checkSignedJar(jarName8);
-
- // JAR with a signature that has PKCS#7 Authenticated Attributes
- checkSignedJar(authAttrsJar);
- }
-
- private void checkSignedJar(String jarName) throws Exception {
- Support_Resources.copyFile(resources, null, jarName);
-
- File file = new File(resources, jarName);
-
- JarFile jarFile = new JarFile(file, true);
-
- boolean foundCerts = false;
-
- Enumeration<JarEntry> e = jarFile.entries();
- while (e.hasMoreElements()) {
- JarEntry entry = e.nextElement();
- InputStream is = jarFile.getInputStream(entry);
- is.skip(100000);
- is.close();
- Certificate[] certs = entry.getCertificates();
- if (certs != null && certs.length > 0) {
- foundCerts = true;
- break;
- }
- }
-
- assertTrue(
- "No certificates found during signed jar test for jar \""
- + jarName + "\"", foundCerts);
- }
-
- private Certificate[] getSignedJarCerts(String jarName, boolean chainCheck) throws Exception {
- Support_Resources.copyFile(resources, null, jarName);
-
- File file = new File(resources, jarName);
- Certificate[] foundCerts = null;
-
- JarFile jarFile = new JarFile(file, true, ZipFile.OPEN_READ, chainCheck);
- try {
-
- Enumeration<JarEntry> e = jarFile.entries();
- while (e.hasMoreElements()) {
- JarEntry entry = e.nextElement();
- InputStream is = jarFile.getInputStream(entry);
- // Skip bytes because we have to read the entire file for it to read signatures.
- is.skip(entry.getSize());
- is.close();
- Certificate[] certs = entry.getCertificates();
- if (certs != null && certs.length > 0) {
- foundCerts = certs;
- break;
- }
- }
- } finally {
- jarFile.close();
- }
-
- return foundCerts;
- }
-
- public void testJarFile_Signed_ValidChain_NoCheck() throws Exception {
- Certificate[] certs = getSignedJarCerts(VALID_CHAIN_JAR, false);
- assertNotNull(certs);
- assertEquals(Arrays.deepToString(certs), 3, certs.length);
- assertEquals("CN=fake-chain", ((X509Certificate) certs[0]).getSubjectDN().toString());
- assertEquals("CN=intermediate1", ((X509Certificate) certs[1]).getSubjectDN().toString());
- assertEquals("CN=root1", ((X509Certificate) certs[2]).getSubjectDN().toString());
- }
-
- public void testJarFile_Signed_ValidChain_Check() throws Exception {
- Certificate[] certs = getSignedJarCerts(VALID_CHAIN_JAR, true);
- assertNotNull(certs);
- assertEquals(Arrays.deepToString(certs), 3, certs.length);
- assertEquals("CN=fake-chain", ((X509Certificate) certs[0]).getSubjectDN().toString());
- assertEquals("CN=intermediate1", ((X509Certificate) certs[1]).getSubjectDN().toString());
- assertEquals("CN=root1", ((X509Certificate) certs[2]).getSubjectDN().toString());
- }
-
- public void testJarFile_Signed_InvalidChain_NoCheck() throws Exception {
- Certificate[] certs = getSignedJarCerts(INVALID_CHAIN_JAR, false);
- assertNotNull(certs);
- assertEquals(Arrays.deepToString(certs), 3, certs.length);
- assertEquals("CN=fake-chain", ((X509Certificate) certs[0]).getSubjectDN().toString());
- assertEquals("CN=intermediate1", ((X509Certificate) certs[1]).getSubjectDN().toString());
- assertEquals("CN=root1", ((X509Certificate) certs[2]).getSubjectDN().toString());
- }
-
- public void testJarFile_Signed_InvalidChain_Check() throws Exception {
- Certificate[] certs = getSignedJarCerts(INVALID_CHAIN_JAR, true);
- assertNotNull(certs);
- assertEquals(Arrays.deepToString(certs), 2, certs.length);
- assertEquals("CN=fake-chain", ((X509Certificate) certs[0]).getSubjectDN().toString());
- assertEquals("CN=intermediate1", ((X509Certificate) certs[1]).getSubjectDN().toString());
- }
-
- /*
- * The jar created by 1.4 which does not provide a
- * algorithm-Digest-Manifest-Main-Attributes entry in .SF file.
- */
- public void test_Jar_created_before_java_5() throws IOException {
- String modifiedJarName = "Created_by_1_4.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = entries.nextElement();
- jarFile.getInputStream(zipEntry);
- }
- }
-
- /* The jar is intact, then everything is all right. */
- public void test_JarFile_Integrate_Jar() throws IOException {
- String modifiedJarName = "Integrate.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = entries.nextElement();
- jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
- }
- }
-
- /**
- * The jar is intact, but the entry object is modified.
- */
- public void testJarVerificationModifiedEntry() throws IOException {
- Support_Resources.copyFile(resources, null, integrateJar);
- File f = new File(resources, integrateJar);
-
- JarFile jarFile = new JarFile(f);
- ZipEntry zipEntry = jarFile.getJarEntry(integrateJarEntry);
- zipEntry.setSize(zipEntry.getSize() + 1);
- jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
-
- jarFile = new JarFile(f);
- zipEntry = jarFile.getJarEntry(integrateJarEntry);
- zipEntry.setSize(zipEntry.getSize() - 1);
- try {
- //jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
- jarFile.getInputStream(zipEntry).read(new byte[5000], 0, 5000);
- fail("SecurityException expected");
- } catch (SecurityException e) {
- // desired
- }
- }
-
- /*
- * If another entry is inserted into Manifest, no security exception will be
- * thrown out.
- */
- public void test_JarFile_InsertEntry_in_Manifest_Jar() throws IOException {
- String modifiedJarName = "Inserted_Entry_Manifest.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
- int count = 0;
- while (entries.hasMoreElements()) {
-
- ZipEntry zipEntry = entries.nextElement();
- jarFile.getInputStream(zipEntry);
- count++;
- }
- assertEquals(5, count);
- }
-
- /*
- * If another entry is inserted into Manifest, no security exception will be
- * thrown out.
- */
- public void test_Inserted_Entry_Manifest_with_DigestCode()
- throws IOException {
- String modifiedJarName = "Inserted_Entry_Manifest_with_DigestCode.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
- int count = 0;
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = entries.nextElement();
- jarFile.getInputStream(zipEntry);
- count++;
- }
- assertEquals(5, count);
- }
-
- /*
- * The content of Test.class is modified, jarFile.getInputStream will not
- * throw security Exception, but it will anytime before the inputStream got
- * from getInputStream method has been read to end.
- */
- public void test_JarFile_Modified_Class() throws IOException {
- String modifiedJarName = "Modified_Class.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = entries.nextElement();
- jarFile.getInputStream(zipEntry);
- }
- /* The content of Test.class has been tampered. */
- ZipEntry zipEntry = jarFile.getEntry("Test.class");
- InputStream in = jarFile.getInputStream(zipEntry);
- byte[] buffer = new byte[1024];
- try {
- while (in.available() > 0) {
- in.read(buffer);
- }
- fail("SecurityException expected");
- } catch (SecurityException e) {
- // desired
- }
- }
-
- /*
- * In the Modified.jar, the main attributes of META-INF/MANIFEST.MF is
- * tampered manually. Hence the RI 5.0 JarFile.getInputStream of any
- * JarEntry will throw security exception.
- */
- public void test_JarFile_Modified_Manifest_MainAttributes()
- throws IOException {
- String modifiedJarName = "Modified_Manifest_MainAttributes.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = entries.nextElement();
- try {
- jarFile.getInputStream(zipEntry);
- fail("SecurityException expected");
- } catch (SecurityException e) {
- // desired
- }
- }
- }
-
- /*
- * It is all right in our original JarFile. If the Entry Attributes, for
- * example Test.class in our jar, the jarFile.getInputStream will throw
- * Security Exception.
- */
- public void test_JarFile_Modified_Manifest_EntryAttributes()
- throws IOException {
- String modifiedJarName = "Modified_Manifest_EntryAttributes.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = entries.nextElement();
- try {
- jarFile.getInputStream(zipEntry);
- fail("should throw Security Exception");
- } catch (SecurityException e) {
- // desired
- }
- }
- }
-
- /*
- * If the content of the .SA file is modified, no matter what it resides,
- * JarFile.getInputStream of any JarEntry will throw Security Exception.
- */
- public void test_JarFile_Modified_SF_EntryAttributes() throws IOException {
- String modifiedJarName = "Modified_SF_EntryAttributes.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = entries.nextElement();
- try {
- jarFile.getInputStream(zipEntry);
- fail("should throw Security Exception");
- } catch (SecurityException e) {
- // desired
- }
- }
- }
-
- public void test_close() throws IOException {
- String modifiedJarName = "Modified_SF_EntryAttributes.jar";
- Support_Resources.copyFile(resources, null, modifiedJarName);
- JarFile jarFile = new JarFile(new File(resources, modifiedJarName),
- true);
- Enumeration<JarEntry> entries = jarFile.entries();
-
- jarFile.close();
- jarFile.close();
-
- // Can not check IOException
- }
-
- /**
- * @throws IOException
- * java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
- */
- public void test_getInputStreamLjava_util_jar_JarEntry() throws IOException {
- File localFile = null;
- try {
- Support_Resources.copyFile(resources, null, jarName);
- localFile = new File(resources, jarName);
- } catch (Exception e) {
- fail("Failed to create local file: " + e);
- }
-
- byte[] b = new byte[1024];
- try {
- JarFile jf = new JarFile(localFile);
- java.io.InputStream is = jf.getInputStream(jf.getEntry(entryName));
- // BEGIN android-removed
- // jf.close();
- // END android-removed
- assertTrue("Returned invalid stream", is.available() > 0);
- int r = is.read(b, 0, 1024);
- is.close();
- StringBuffer sb = new StringBuffer(r);
- for (int i = 0; i < r; i++) {
- sb.append((char) (b[i] & 0xff));
- }
- String contents = sb.toString();
- assertTrue("Incorrect stream read", contents.indexOf("bar") > 0);
- // BEGIN android-added
- jf.close();
- // END android-added
- } catch (Exception e) {
- fail("Exception during test: " + e.toString());
- }
-
- try {
- JarFile jf = new JarFile(localFile);
- InputStream in = jf.getInputStream(new JarEntry("invalid"));
- assertNull("Got stream for non-existent entry", in);
- } catch (Exception e) {
- fail("Exception during test 2: " + e);
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName);
- File signedFile = new File(resources, jarName);
- JarFile jf = new JarFile(signedFile);
- JarEntry jre = new JarEntry("foo/bar/A.class");
- jf.getInputStream(jre);
- // InputStream returned in any way, exception can be thrown in case
- // of reading from this stream only.
- // fail("Should throw ZipException");
- } catch (ZipException ee) {
- // expected
- }
-
- try {
- Support_Resources.copyFile(resources, null, jarName);
- File signedFile = new File(resources, jarName);
- JarFile jf = new JarFile(signedFile);
- JarEntry jre = new JarEntry("foo/bar/A.class");
- jf.close();
- jf.getInputStream(jre);
- // InputStream returned in any way, exception can be thrown in case
- // of reading from this stream only.
- // The same for IOException
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException ee) {
- // expected
- }
- }
-
- /**
- * The jar is intact, but the entry object is modified.
- */
- // Regression test for issue introduced by HARMONY-4569: signed archives containing files with size 0 could not get verified.
- public void testJarVerificationEmptyEntry() throws IOException {
- Support_Resources.copyFile(resources, null, emptyEntryJar);
- File f = new File(resources, emptyEntryJar);
-
- JarFile jarFile = new JarFile(f);
-
- ZipEntry zipEntry = jarFile.getJarEntry(emptyEntry1);
- int res = jarFile.getInputStream(zipEntry).read(new byte[100], 0, 100);
- assertEquals("Wrong length of empty jar entry", -1, res);
-
- zipEntry = jarFile.getJarEntry(emptyEntry2);
- res = jarFile.getInputStream(zipEntry).read(new byte[100], 0, 100);
- assertEquals("Wrong length of empty jar entry", -1, res);
-
- zipEntry = jarFile.getJarEntry(emptyEntry3);
- res = jarFile.getInputStream(zipEntry).read();
- assertEquals("Wrong length of empty jar entry", -1, res);
- }
-}
diff --git a/luni/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java b/luni/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
deleted file mode 100644
index a423f22..0000000
--- a/luni/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.archive.tests.java.util.zip;
-
-import tests.support.Support_PlatformFile;
-import tests.support.resource.Support_Resources;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FilePermission;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.Permission;
-import java.util.Enumeration;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
-import libcore.java.lang.ref.FinalizationTester;
-
-public class ZipFileTest extends junit.framework.TestCase {
-
- public byte[] getAllBytesFromStream(InputStream is) throws IOException {
- ByteArrayOutputStream bs = new ByteArrayOutputStream();
- byte[] buf = new byte[512];
- int iRead;
- int off;
- while (is.available() > 0) {
- iRead = is.read(buf, 0, buf.length);
- if (iRead > 0) bs.write(buf, 0, iRead);
- }
- return bs.toByteArray();
- }
-
- // the file hyts_zipFile.zip in setup must be included as a resource
- private String tempFileName;
-
- private ZipFile zfile;
-
- // custom security manager
- SecurityManager sm = new SecurityManager() {
- final String forbidenPermissionAction = "read";
-
-
-
- public void checkPermission(Permission perm) {
- // only check if it's a FilePermission because Locale checks
- // for a PropertyPermission with action"read" to get system props.
- if (perm instanceof FilePermission
- && perm.getActions().equals(forbidenPermissionAction)) {
- throw new SecurityException();
- }
- }
- };
-
- /**
- * java.util.zip.ZipFile#ZipFile(java.io.File)
- */
- public void test_ConstructorLjava_io_File() {
- // Test for method java.util.zip.ZipFile(java.io.File)
- assertTrue("Used to test", true);
- }
-
- /**
- * java.util.zip.ZipFile#ZipFile(java.io.File, int)
- */
- public void test_ConstructorLjava_io_FileI() throws IOException {
- zfile.close(); // about to reopen the same temp file
- File file = new File(tempFileName);
- ZipFile zip = new ZipFile(file, ZipFile.OPEN_DELETE | ZipFile.OPEN_READ);
- zip.close();
- assertTrue("Zip should not exist", !file.exists());
- file = new File(tempFileName);
- file.delete();
- try {
- zip = new ZipFile(file, ZipFile.OPEN_READ);
- fail("IOException expected");
- } catch (IOException ee) {
- // expected
- }
- file = new File(tempFileName);
- try {
- zip = new ZipFile(file, -1);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ee) {
- // expected
- }
- }
-
- /**
- * @throws IOException
- * java.util.zip.ZipFile#ZipFile(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() throws IOException {
- System.setProperty("user.dir", System.getProperty("java.io.tmpdir"));
-
- zfile.close(); // about to reopen the same temp file
- ZipFile zip = new ZipFile(tempFileName);
- zip.close();
- File file = File.createTempFile("zip", "tmp");
- try {
- zip = new ZipFile(file.getName());
- fail("ZipException expected");
- } catch (ZipException ee) {
- // expected
- }
- file.delete();
- }
-
- protected ZipEntry test_finalize1(ZipFile zip) {
- return zip.getEntry("File1.txt");
- }
-
- protected ZipFile test_finalize2(File file) throws IOException {
- return new ZipFile(file);
- }
-
- /**
- * java.util.zip.ZipFile#finalize()
- */
- public void test_finalize() throws IOException {
- InputStream in = Support_Resources.getStream("hyts_ZipFile.zip");
- File file = Support_Resources.createTempFile(".jar");
- OutputStream out = new FileOutputStream(file);
- int result;
- byte[] buf = new byte[4096];
- while ((result = in.read(buf)) != -1) {
- out.write(buf, 0, result);
- }
- in.close();
- out.close();
- /*
- * ZipFile zip = new ZipFile(file); ZipEntry entry1 =
- * zip.getEntry("File1.txt"); assertNotNull("Did not find entry",
- * entry1); entry1 = null; zip = null;
- */
-
- assertNotNull("Did not find entry", test_finalize1(test_finalize2(file)));
- FinalizationTester.induceFinalization();
- file.delete();
- assertTrue("Zip should not exist", !file.exists());
- }
-
- /**
- * @throws IOException
- * java.util.zip.ZipFile#close()
- */
- public void test_close() throws IOException {
- // Test for method void java.util.zip.ZipFile.close()
- File fl = new File(tempFileName);
- ZipFile zf = new ZipFile(fl);
- InputStream is1 = zf.getInputStream(zf.getEntry("File1.txt"));
- InputStream is2 = zf.getInputStream(zf.getEntry("File2.txt"));
-
- is1.read();
- is2.read();
-
- zf.close();
-
- try {
- is1.read();
- fail("IOException expected");
- } catch (IOException ee) {
- // expected
- }
-
- try {
- is2.read();
- fail("IOException expected");
- } catch (IOException ee) {
- // expected
- }
- }
-
- /**
- * java.util.zip.ZipFile#entries()
- */
- public void test_entries() throws Exception {
- // Test for method java.util.Enumeration java.util.zip.ZipFile.entries()
- Enumeration<? extends ZipEntry> enumer = zfile.entries();
- int c = 0;
- while (enumer.hasMoreElements()) {
- ++c;
- enumer.nextElement();
- }
- assertTrue("Incorrect number of entries returned: " + c, c == 6);
-
- Enumeration<? extends ZipEntry> enumeration = zfile.entries();
- zfile.close();
- try {
- enumeration.nextElement();
- fail("did not detect closed file");
- } catch (IllegalStateException expected) {
- }
-
- try {
- enumeration.hasMoreElements();
- fail("did not detect closed file");
- } catch (IllegalStateException expected) {
- }
-
- try {
- zfile.entries();
- fail("did not detect closed file");
- } catch (IllegalStateException expected) {
- }
- }
-
- /**
- * java.util.zip.ZipFile#getEntry(java.lang.String)
- */
- public void test_getEntryLjava_lang_String() throws IOException {
- // Test for method java.util.zip.ZipEntry
- // java.util.zip.ZipFile.getEntry(java.lang.String)
- java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
- assertNotNull("Could not obtain ZipEntry", zentry);
- int r;
- InputStream in;
-
- zentry = zfile.getEntry("testdir1/File1.txt");
- assertNotNull("Could not obtain ZipEntry: testdir1/File1.txt", zentry);
- zentry = zfile.getEntry("testdir1/");
- assertNotNull("Could not obtain ZipEntry: testdir1/", zentry);
- in = zfile.getInputStream(zentry);
- assertNotNull("testdir1/ should not have null input stream", in);
- r = in.read();
- in.close();
- assertEquals("testdir1/ should not contain data", -1, r);
-
- zentry = zfile.getEntry("testdir1/testdir1");
- assertNotNull("Could not obtain ZipEntry: testdir1/testdir1", zentry);
- in = zfile.getInputStream(zentry);
- byte[] buf = new byte[256];
- r = in.read(buf);
- in.close();
- assertEquals("incorrect contents", "This is also text", new String(buf,
- 0, r));
- }
-
- public void test_getEntryLjava_lang_String_AndroidOnly() throws IOException {
- java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
- assertNotNull("Could not obtain ZipEntry", zentry);
- int r;
- InputStream in;
-
- zentry = zfile.getEntry("testdir1");
- assertNotNull("Must be able to obtain ZipEntry: testdir1", zentry);
- in = zfile.getInputStream(zentry);
- /*
- * Android delivers empty InputStream, RI no InputStream at all. The
- * spec doesn't clarify this, so we need to deal with both situations.
- */
- int data = -1;
- if (in != null) {
- data = in.read();
- in.close();
- }
- assertEquals("Must not be able to read directory data", -1, data);
- }
-
- public void test_getEntryLjava_lang_String_Ex() throws IOException {
- java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
- assertNotNull("Could not obtain ZipEntry", zentry);
-
- zfile.close();
- try {
- zfile.getEntry("File2.txt");
- fail("IllegalStateException expected");
- } catch (IllegalStateException ee) {
- }
- }
-
- /**
- * @throws IOException
- * java.util.zip.ZipFile#getInputStream(java.util.zip.ZipEntry)
- */
- public void test_getInputStreamLjava_util_zip_ZipEntry() throws IOException {
- // Test for method java.io.InputStream
- // java.util.zip.ZipFile.getInputStream(java.util.zip.ZipEntry)
- ZipEntry zentry = null;
- InputStream is = null;
- try {
- zentry = zfile.getEntry("File1.txt");
- is = zfile.getInputStream(zentry);
- byte[] rbuf = new byte[1000];
- int r;
- is.read(rbuf, 0, r = (int) zentry.getSize());
- assertEquals("getInputStream read incorrect data", "This is text",
- new String(rbuf, 0, r));
- } catch (java.io.IOException e) {
- fail("IOException during getInputStream");
- } finally {
- try {
- is.close();
- } catch (java.io.IOException e) {
- fail("Failed to close input stream");
- }
- }
-
- zentry = zfile.getEntry("File2.txt");
- zfile.close();
- try {
- is = zfile.getInputStream(zentry);
- fail("IllegalStateException expected");
- } catch (IllegalStateException ee) {
- // expected
- }
-
- // ZipException can not be checked. Stream object returned or null.
- }
-
- /**
- * java.util.zip.ZipFile#getName()
- */
- public void test_getName() {
- // Test for method java.lang.String java.util.zip.ZipFile.getName()
- assertTrue("Returned incorrect name: " + zfile.getName(), zfile
- .getName().equals(tempFileName));
- }
-
- /**
- * @throws IOException
- * java.util.zip.ZipFile#size()
- */
- public void test_size() throws IOException {
- assertEquals(6, zfile.size());
- zfile.close();
- try {
- zfile.size();
- fail("IllegalStateException expected");
- } catch (IllegalStateException expected) {
- }
- }
-
- /**
- * java.io.InputStream#reset()
- */
- public void test_reset() throws IOException {
- // read an uncompressed entry
- ZipEntry zentry = zfile.getEntry("File1.txt");
- InputStream is = zfile.getInputStream(zentry);
- byte[] rbuf1 = new byte[6];
- byte[] rbuf2 = new byte[6];
- int r1, r2;
- r1 = is.read(rbuf1);
- assertEquals(rbuf1.length, r1);
- r2 = is.read(rbuf2);
- assertEquals(rbuf2.length, r2);
-
- try {
- is.reset();
- fail();
- } catch (IOException expected) {
- }
- is.close();
-
- // read a compressed entry
- byte[] rbuf3 = new byte[4185];
- ZipEntry zentry2 = zfile.getEntry("File3.txt");
- is = zfile.getInputStream(zentry2);
- r1 = is.read(rbuf3);
- assertEquals(4183, r1);
- try {
- is.reset();
- fail();
- } catch (IOException expected) {
- }
- is.close();
-
- is = zfile.getInputStream(zentry2);
- r1 = is.read(rbuf3, 0, 3000);
- assertEquals(3000, r1);
- try {
- is.reset();
- fail();
- } catch (IOException expected) {
- }
- is.close();
- }
-
- /**
- * java.io.InputStream#reset()
- */
- public void test_reset_subtest0() throws IOException {
- // read an uncompressed entry
- ZipEntry zentry = zfile.getEntry("File1.txt");
- InputStream is = zfile.getInputStream(zentry);
- byte[] rbuf1 = new byte[12];
- byte[] rbuf2 = new byte[12];
- int r = is.read(rbuf1, 0, 4);
- assertEquals(4, r);
- is.mark(0);
- r = is.read(rbuf1);
- assertEquals(8, r);
- assertEquals(-1, is.read());
-
- try {
- is.reset();
- fail();
- } catch (IOException expected) {
- }
-
- is.close();
-
- // read a compressed entry
- byte[] rbuf3 = new byte[4185];
- ZipEntry zentry2 = zfile.getEntry("File3.txt");
- is = zfile.getInputStream(zentry2);
- r = is.read(rbuf3, 0, 3000);
- assertEquals(3000, r);
- is.mark(0);
- r = is.read(rbuf3);
- assertEquals(1183, r);
- assertEquals(-1, is.read());
-
- try {
- is.reset();
- fail();
- } catch (IOException expected) {
- }
-
- is.close();
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- @Override
- protected void setUp() {
- try {
- // Create a local copy of the file since some tests want to alter
- // information.
- tempFileName = System.getProperty("java.io.tmpdir");
- String separator = System.getProperty("file.separator");
- if (tempFileName.charAt(tempFileName.length() - 1) == separator
- .charAt(0)) {
- tempFileName = Support_PlatformFile.getNewPlatformFile(
- tempFileName, "gabba.zip");
- } else {
- tempFileName = Support_PlatformFile.getNewPlatformFile(
- tempFileName + separator, "gabba.zip");
- }
-
- File f = new File(tempFileName);
- f.delete();
- InputStream is = Support_Resources.getStream("hyts_ZipFile.zip");
- FileOutputStream fos = new FileOutputStream(f);
- byte[] rbuf = getAllBytesFromStream(is);
- fos.write(rbuf, 0, rbuf.length);
- is.close();
- fos.close();
- zfile = new ZipFile(f);
- } catch (Exception e) {
- System.out.println("Exception during ZipFile setup:");
- e.printStackTrace();
- }
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- @Override
- protected void tearDown() {
- try {
- if (zfile != null) {
- // Note zfile is a user-defined zip file used by other tests and
- // should not be deleted
- zfile.close();
- tempFileName = System.getProperty("java.io.tmpdir");
- String separator = System.getProperty("file.separator");
- if (tempFileName.charAt(tempFileName.length() - 1) == separator
- .charAt(0)) {
- tempFileName = Support_PlatformFile.getNewPlatformFile(
- tempFileName, "gabba.zip");
- } else {
- tempFileName = Support_PlatformFile.getNewPlatformFile(
- tempFileName + separator, "gabba.zip");
- }
-
- File f = new File(tempFileName);
- f.delete();
- }
- } catch (Exception e) {
- }
- }
-
-}
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java
index f617adb..87b2913 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java
@@ -17,8 +17,6 @@
package org.apache.harmony.crypto.tests.javax.crypto;
-import dalvik.annotation.SideEffect;
-
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
@@ -186,7 +184,7 @@ public class ExemptionMechanismTest extends TestCase {
}
}
- @SideEffect("Causes OutOfMemoryError to test finalization")
+ // Side Effect: Causes OutOfMemoryError to test finalization
public void test_finalize () {
Mock_ExemptionMechanism mem = new Mock_ExemptionMechanism(null, null, "Name");
assertNotNull(mem);
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
index 99d127a..0642229 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
@@ -22,6 +22,8 @@
package org.apache.harmony.crypto.tests.javax.crypto;
+import org.apache.harmony.security.tests.support.SpiEngUtils;
+import org.apache.harmony.security.tests.support.TestKeyPair;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
@@ -31,6 +33,7 @@ import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
+import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
@@ -40,12 +43,10 @@ import javax.crypto.KeyAgreementSpi;
import javax.crypto.ShortBufferException;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.spec.DHParameterSpec;
-
-import org.apache.harmony.crypto.tests.support.MyKeyAgreementSpi;
-import org.apache.harmony.security.tests.support.SpiEngUtils;
-import org.apache.harmony.security.tests.support.TestKeyPair;
-
import junit.framework.TestCase;
+import libcore.java.security.StandardNames;
+import libcore.javax.crypto.MockKey;
+import libcore.javax.crypto.MockKey2;
/**
@@ -676,4 +677,127 @@ public class KeyAgreementTest extends TestCase {
//expected
}
}
+
+ private static abstract class MockProvider extends Provider {
+ public MockProvider(String name) {
+ super(name, 1.0, "Mock provider used for testing");
+ setup();
+ }
+
+ public abstract void setup();
+ }
+
+ public void testKeyAgreement_getInstance_SuppliedProviderNotRegistered_Success()
+ throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ {
+ KeyAgreement s = KeyAgreement.getInstance("FOO", mockProvider);
+ s.init(new MockKey());
+ assertEquals(mockProvider, s.getProvider());
+ }
+ }
+
+ public void testKeyAgreement_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
+ throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProvider);
+ try {
+ {
+ Provider mockProvider2 = new MockProvider("MockProvider") {
+ public void setup() {
+ put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
+ }
+ };
+ KeyAgreement s = KeyAgreement.getInstance("FOO", mockProvider2);
+ assertEquals(mockProvider2, s.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProvider.getName());
+ }
+ }
+
+ public void testKeyAgreement_getInstance_DelayedInitialization_KeyType() throws Exception {
+ Provider mockProviderSpecific = new MockProvider("MockProviderSpecific") {
+ public void setup() {
+ put("KeyAgreement.FOO", MockKeyAgreementSpi.SpecificKeyTypes.class.getName());
+ put("KeyAgreement.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+ Provider mockProviderSpecific2 = new MockProvider("MockProviderSpecific2") {
+ public void setup() {
+ put("KeyAgreement.FOO", MockKeyAgreementSpi.SpecificKeyTypes2.class.getName());
+ put("KeyAgreement.FOO SupportedKeyClasses", MockKey2.class.getName());
+ }
+ };
+ Provider mockProviderAll = new MockProvider("MockProviderAll") {
+ public void setup() {
+ put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderSpecific);
+ Security.addProvider(mockProviderSpecific2);
+ Security.addProvider(mockProviderAll);
+
+ try {
+ {
+ KeyAgreement s = KeyAgreement.getInstance("FOO");
+ s.init(new MockKey());
+ assertEquals(mockProviderSpecific, s.getProvider());
+
+ try {
+ s.init(new MockKey2());
+ assertEquals(mockProviderSpecific2, s.getProvider());
+ if (StandardNames.IS_RI) {
+ fail("RI was broken before; fix tests now that it works!");
+ }
+ } catch (InvalidKeyException e) {
+ if (!StandardNames.IS_RI) {
+ fail("Non-RI should select the right provider");
+ }
+ }
+ }
+
+ {
+ KeyAgreement s = KeyAgreement.getInstance("FOO");
+ s.init(new PrivateKey() {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+ });
+ assertEquals(mockProviderAll, s.getProvider());
+ }
+
+ {
+ KeyAgreement s = KeyAgreement.getInstance("FOO");
+ assertEquals(mockProviderSpecific, s.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProviderSpecific.getName());
+ Security.removeProvider(mockProviderSpecific2.getName());
+ Security.removeProvider(mockProviderAll.getName());
+ }
+ }
+
}
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
index b1559f5..ddd0695 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
@@ -27,26 +27,26 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
import java.security.spec.PSSParameterSpec;
+import java.util.ArrayList;
import java.util.Arrays;
-
import javax.crypto.Mac;
import javax.crypto.MacSpi;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.DHGenParameterSpec;
-
import javax.crypto.spec.SecretKeySpec;
-
import org.apache.harmony.crypto.tests.support.MyMacSpi;
import org.apache.harmony.security.tests.support.SpiEngUtils;
-
import junit.framework.TestCase;
-
import junit.framework.Test;
import junit.framework.TestSuite;
+import libcore.java.security.StandardNames;
+import libcore.javax.crypto.MockKey;
+import libcore.javax.crypto.MockKey2;
/**
* Tests for Mac class constructors and methods
@@ -71,7 +71,7 @@ public class MacTest extends TestCase {
private static String[] validValues = new String[3];
public static final String validAlgorithmsMac [] =
- {"HmacSHA1", "HmacMD5", "HmacSHA256", "HmacSHA384", "HmacSHA512"};
+ {"HmacSHA1", "HmacMD5", "HmacSHA224", "HmacSHA256", "HmacSHA384", "HmacSHA512"};
static {
@@ -90,20 +90,19 @@ public class MacTest extends TestCase {
}
}
- private Mac [] createMacs() {
+ private Mac[] createMacs() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return null;
}
- try {
- Mac m [] = new Mac[3];
- m[0] = Mac.getInstance(defaultAlgorithm);
- m[1] = Mac.getInstance(defaultAlgorithm, defaultProvider);
- m[2] = Mac.getInstance(defaultAlgorithm, defaultProviderName);
- return m;
- } catch (Exception e) {
- return null;
+ ArrayList<Mac> macList = new ArrayList<Mac>();
+ macList.add(Mac.getInstance(defaultAlgorithm));
+ macList.add(Mac.getInstance(defaultAlgorithm, defaultProvider));
+ macList.add(Mac.getInstance(defaultAlgorithm, defaultProviderName));
+ for (Provider p : Security.getProviders("Mac." + defaultAlgorithm)) {
+ macList.add(Mac.getInstance(defaultAlgorithm, p));
}
+ return macList.toArray(new Mac[macList.size()]);
}
/**
@@ -356,9 +355,7 @@ public class MacTest extends TestCase {
* throws ShotBufferException when outOffset is negative or
* outOffset >= output.length or when given buffer is small
*/
- public void testMac10() throws NoSuchAlgorithmException,
- NoSuchProviderException, IllegalArgumentException,
- IllegalStateException, InvalidKeyException {
+ public void testMac10() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -404,9 +401,7 @@ public class MacTest extends TestCase {
* <code>doFinal()</code> methods Assertion: Mac result is stored in
* output buffer
*/
- public void testMac11() throws NoSuchAlgorithmException, NoSuchProviderException,
- IllegalArgumentException, IllegalStateException,
- InvalidKeyException, ShortBufferException {
+ public void testMac11() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -430,9 +425,7 @@ public class MacTest extends TestCase {
* Test for <code>doFinal(byte[] input)</code> method
* Assertion: update Mac and returns result
*/
- public void testMac12() throws NoSuchAlgorithmException, NoSuchProviderException,
- IllegalArgumentException, IllegalStateException,
- InvalidKeyException {
+ public void testMac12() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -447,15 +440,15 @@ public class MacTest extends TestCase {
byte[] res1 = macs[i].doFinal();
byte[] res2 = macs[i].doFinal();
assertEquals("Results are not the same",
- IntegralToString.bytesToHexString(res1, false),
- IntegralToString.bytesToHexString(res2, false));
+ Arrays.toString(res1),
+ Arrays.toString(res2));
res2 = macs[i].doFinal(upd);
macs[i].update(upd);
res1 = macs[i].doFinal();
assertEquals("Results are not the same",
- IntegralToString.bytesToHexString(res1, false),
- IntegralToString.bytesToHexString(res2, false));
+ Arrays.toString(res1),
+ Arrays.toString(res2));
}
}
@@ -464,9 +457,7 @@ public class MacTest extends TestCase {
* Assertion: throws IllegalArgumentException when offset or len is negative,
* offset + len >= input.length
*/
- public void testMac13() throws NoSuchAlgorithmException,
- NoSuchProviderException, IllegalArgumentException, IllegalStateException,
- InvalidKeyException {
+ public void testMac13() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -505,9 +496,7 @@ public class MacTest extends TestCase {
* methods
* Assertion: updates Mac
*/
- public void testMac14() throws NoSuchAlgorithmException,
- NoSuchProviderException, IllegalArgumentException, IllegalStateException,
- InvalidKeyException {
+ public void testMac14() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -547,7 +536,7 @@ public class MacTest extends TestCase {
* Test for <code>clone()</code> method
* Assertion: returns Mac object or throws CloneNotSupportedException
*/
- public void testMacClone() throws NoSuchAlgorithmException, CloneNotSupportedException {
+ public void testMacClone() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -572,9 +561,7 @@ public class MacTest extends TestCase {
* Assertion: throws InvalidKeyException and InvalidAlgorithmParameterException
* when parameters are not appropriate
*/
- public void testInit() throws NoSuchAlgorithmException, NoSuchProviderException,
- IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
- InvalidKeyException {
+ public void testInit() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -588,6 +575,7 @@ public class MacTest extends TestCase {
SecretKeySpec sks1 = new SecretKeySpec(b, "RSA");
for (int i = 0; i < macs.length; i++) {
+ macs[i].reset();
macs[i].init(sks);
try {
macs[i].init(sks1, algPSS);
@@ -621,9 +609,7 @@ public class MacTest extends TestCase {
* methods
* Assertion: processes Mac; if input is null then do nothing
*/
- public void testUpdateByteBuffer01() throws NoSuchAlgorithmException, NoSuchProviderException,
- IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
- InvalidKeyException {
+ public void testUpdateByteBuffer01() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -664,9 +650,7 @@ public class MacTest extends TestCase {
* methods
* Assertion: processes Mac
*/
- public void testUpdateByteBuffer02() throws NoSuchAlgorithmException, NoSuchProviderException,
- IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
- InvalidKeyException {
+ public void testUpdateByteBuffer02() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -699,7 +683,7 @@ public class MacTest extends TestCase {
* Test for <code>clone()</code> method
* Assertion: clone if provider is clo
*/
- public void testClone() {
+ public void testClone() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -720,7 +704,7 @@ public class MacTest extends TestCase {
* Test for <code>getMacLength()</code> method
* Assertion: return Mac length
*/
- public void testGetMacLength() {
+ public void testGetMacLength() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -736,7 +720,7 @@ public class MacTest extends TestCase {
* Test for <code>reset()</code> method
* Assertion: return Mac length
*/
- public void testReset() throws InvalidKeyException {
+ public void testReset() throws Exception {
if (!DEFSupported) {
fail(NotSupportedMsg);
return;
@@ -781,15 +765,14 @@ public class MacTest extends TestCase {
}
MacSpi spi = new MyMacSpi();
Mac mac = new myMac(spi, defaultProvider, defaultAlgorithm);
- assertEquals("Incorrect algorithm", mac.getAlgorithm(),
- defaultAlgorithm);
- assertEquals("Incorrect provider", mac.getProvider(), defaultProvider);
+ assertEquals("Incorrect algorithm", defaultAlgorithm, mac.getAlgorithm());
+ assertEquals("Incorrect provider", defaultProvider, mac.getProvider());
try {
mac.init(null, null);
fail("Exception should be thrown because init(..) uses incorrect parameters");
} catch (Exception e) {
}
- assertEquals("Invalid mac length", mac.getMacLength(), 0);
+ assertEquals("Invalid mac length", 0, mac.getMacLength());
mac = new myMac(null, null, null);
assertNull("Algorithm must be null", mac.getAlgorithm());
@@ -892,6 +875,127 @@ public class MacTest extends TestCase {
}
}
+ private static abstract class MockProvider extends Provider {
+ public MockProvider(String name) {
+ super(name, 1.0, "Mock provider used for testing");
+ setup();
+ }
+
+ public abstract void setup();
+ }
+
+ public void testMac_getInstance_SuppliedProviderNotRegistered_Success() throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ {
+ Mac s = Mac.getInstance("FOO", mockProvider);
+ s.init(new MockKey());
+ assertEquals(mockProvider, s.getProvider());
+ }
+ }
+
+ public void testMac_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
+ throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProvider);
+ try {
+ {
+ Provider mockProvider2 = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
+ }
+ };
+ Mac s = Mac.getInstance("FOO", mockProvider2);
+ assertEquals(mockProvider2, s.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProvider.getName());
+ }
+ }
+
+ public void testMac_getInstance_DelayedInitialization_KeyType() throws Exception {
+ Provider mockProviderSpecific = new MockProvider("MockProviderSpecific") {
+ public void setup() {
+ put("Mac.FOO", MockMacSpi.SpecificKeyTypes.class.getName());
+ put("Mac.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+ Provider mockProviderSpecific2 = new MockProvider("MockProviderSpecific2") {
+ public void setup() {
+ put("Mac.FOO", MockMacSpi.SpecificKeyTypes2.class.getName());
+ put("Mac.FOO SupportedKeyClasses", MockKey2.class.getName());
+ }
+ };
+ Provider mockProviderAll = new MockProvider("MockProviderAll") {
+ public void setup() {
+ put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderSpecific);
+ Security.addProvider(mockProviderSpecific2);
+ Security.addProvider(mockProviderAll);
+
+ try {
+ {
+ Mac s = Mac.getInstance("FOO");
+ s.init(new MockKey());
+ assertEquals(mockProviderSpecific, s.getProvider());
+
+ try {
+ s.init(new MockKey2());
+ assertEquals(mockProviderSpecific2, s.getProvider());
+ if (StandardNames.IS_RI) {
+ fail("RI was broken before; fix tests now that it works!");
+ }
+ } catch (InvalidKeyException e) {
+ if (!StandardNames.IS_RI) {
+ fail("Non-RI should select the right provider");
+ }
+ }
+ }
+
+ {
+ Mac s = Mac.getInstance("FOO");
+ s.init(new PrivateKey() {
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public String getFormat() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+ });
+ assertEquals(mockProviderAll, s.getProvider());
+ }
+
+ {
+ Mac s = Mac.getInstance("FOO");
+ assertEquals(mockProviderSpecific, s.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProviderSpecific.getName());
+ Security.removeProvider(mockProviderSpecific2.getName());
+ Security.removeProvider(mockProviderAll.getName());
+ }
+ }
+
public static Test suite() {
return new TestSuite(MacTest.class);
}
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MockKeyAgreementSpi.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MockKeyAgreementSpi.java
new file mode 100644
index 0000000..4b53a6b
--- /dev/null
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MockKeyAgreementSpi.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import libcore.javax.crypto.MockKey;
+import libcore.javax.crypto.MockKey2;
+
+public class MockKeyAgreementSpi extends KeyAgreementSpi {
+ public static class SpecificKeyTypes extends MockKeyAgreementSpi {
+ @Override
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ if (!(key instanceof MockKey)) {
+ throw new InvalidKeyException("Must be MockKey!");
+ }
+ }
+ }
+
+ public static class SpecificKeyTypes2 extends MockKeyAgreementSpi {
+ @Override
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ if (!(key instanceof MockKey2)) {
+ throw new InvalidKeyException("Must be MockKey2!");
+ }
+ }
+ }
+
+ public static class AllKeyTypes extends MockKeyAgreementSpi {
+ }
+
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ }
+
+ @Override
+ protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException,
+ IllegalStateException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected byte[] engineGenerateSecret() throws IllegalStateException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected int engineGenerateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
+ checkKeyType(key);
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ checkKeyType(key);
+ }
+}
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MockMacSpi.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MockMacSpi.java
new file mode 100644
index 0000000..6a28fb3
--- /dev/null
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MockMacSpi.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.MacSpi;
+import libcore.javax.crypto.MockKey;
+import libcore.javax.crypto.MockKey2;
+
+public class MockMacSpi extends MacSpi {
+ public static class SpecificKeyTypes extends MockMacSpi {
+ @Override
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ if (!(key instanceof MockKey)) {
+ throw new InvalidKeyException("Must be MockKey!");
+ }
+ }
+ }
+
+ public static class SpecificKeyTypes2 extends MockMacSpi {
+ @Override
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ if (!(key instanceof MockKey2)) {
+ throw new InvalidKeyException("Must be MockKey2!");
+ }
+ }
+ }
+
+ public static class AllKeyTypes extends MockMacSpi {
+ }
+
+ public void checkKeyType(Key key) throws InvalidKeyException {
+ }
+
+ @Override
+ protected int engineGetMacLength() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
+ InvalidParameterException {
+ checkKeyType(key);
+ }
+
+ @Override
+ protected void engineUpdate(byte input) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected byte[] engineDoFinal() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void engineReset() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java
index 3ea57bf..5cbdab3 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java
@@ -165,6 +165,34 @@ public class SealedObjectTest extends TestCase {
+ "in cipher.", algorithm, so.getAlgorithm());
}
+ // https://code.google.com/p/android/issues/detail?id=73235
+ public void testGetAlgorithmAfterSerialization() throws Exception {
+ String secret = "secret string";
+ String algorithm = "DES";
+ KeyGenerator kg = KeyGenerator.getInstance(algorithm);
+ Key key = kg.generateKey();
+
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ SealedObject so = new SealedObject(secret, cipher);
+
+ assertEquals("The algorithm name should be the same as used "
+ + "in cipher.", algorithm, so.getAlgorithm());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(so);
+ oos.close();
+
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
+ SealedObject readSo = (SealedObject) ois.readObject();
+ ois.close();
+
+ // Bug 73235 would swap the Cipher algorithm and parameters. Parameters is not public but
+ // algorithm is so we check that.
+ assertEquals(so.getAlgorithm(), readSo.getAlgorithm());
+ }
+
/**
* getObject(Key key) method testing. Tests if the object sealed with
* encryption algorithm and specified parameters can be retrieved by
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java
index 0b8f017..85c2438 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java
@@ -18,7 +18,7 @@ package org.apache.harmony.crypto.tests.javax.crypto.func;
import junit.framework.TestCase;
public class CipherAesTest extends TestCase {
-// 216 cases checked
+// 324 cases checked
public void test_AesNoISO() {
CipherSymmetricKeyThread aesNoISO = new CipherSymmetricKeyThread("AES",
new int[] {128, 192, 256}, // Keysize must be 128, 192, 256.
@@ -29,7 +29,8 @@ public class CipherAesTest extends TestCase {
"CFB128", "OFB", "OFB8", "OFB16", "OFB24", "OFB32",
"OFB40", "OFB48", "OFB56", "OFB64", "OFB72", "OFB80",
"OFB88", "OFB96", "OFB104", "OFB112", "OFB120",
- "OFB128"}, new String[] {"NoPadding", "PKCS5Padding"});
+ "OFB128"},
+ new String[] {"NoPadding", "PKCS5Padding", "PKCS7Padding"});
aesNoISO.launcher();
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java
index d8565f1..c7b4f20 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java
@@ -18,7 +18,7 @@ package org.apache.harmony.crypto.tests.javax.crypto.func;
import junit.framework.TestCase;
public class CipherDESedeTest extends TestCase {
-// 80 cases checked
+// 120 cases checked
public void test_DESedeNoISO() {
CipherSymmetricKeyThread DESedeNoISO = new CipherSymmetricKeyThread(
"DESede", new int[] {112, 168},// Keysize must be 112 or 168.
@@ -26,7 +26,8 @@ public class CipherDESedeTest extends TestCase {
"ECB", "CBC", "CFB", "CFB8", "CFB16", "CFB24", "CFB32",
"CFB40", "CFB48", "CFB56", "CFB64", "OFB", "OFB8",
"OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56",
- "OFB64"}, new String[] {"NoPadding", "PKCS5Padding"});
+ "OFB64"},
+ new String[] {"NoPadding", "PKCS5Padding", "PKCS7Padding"});
DESedeNoISO.launcher();
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java b/luni/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java
index c9eb26e..ff4babc 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java
@@ -52,7 +52,8 @@ public class MyCipher extends CipherSpi {
@Override
protected void engineSetPadding(String padding)
throws NoSuchPaddingException {
- if (!"PKCS5Padding".equals(padding)) {
+ if ((!"PKCS5Padding".equals(padding))
+ && (!"PKCS7Padding".equals(padding))) {
throw new NoSuchPaddingException(padding);
}
}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java
index 5d8c621..290ae9a 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java
@@ -17,8 +17,6 @@
package org.apache.harmony.luni.tests.internal.net.www.protocol.http;
-import dalvik.annotation.SideEffect;
-
import java.io.IOException;
import java.net.Authenticator;
import java.net.HttpURLConnection;
@@ -270,7 +268,7 @@ public class HttpURLConnectionTest extends TestCase {
ProxySelector.setDefault(defPS);
}
}
- @SideEffect("Suffers from side effect of other, currently unknown test")
+ // SideEffect: Suffers from side effect of other, currently unknown test
public void testProxyAuthorization() throws Exception {
// Set up test Authenticator
Authenticator.setDefault(new Authenticator() {
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
index c516f67..5258fd1 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
@@ -17,6 +17,12 @@
package org.apache.harmony.luni.tests.internal.net.www.protocol.https;
+import com.google.mockwebserver.Dispatcher;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+import com.google.mockwebserver.RecordedRequest;
+import com.google.mockwebserver.SocketPolicy;
+
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -25,7 +31,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.PrintStream;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
@@ -36,20 +41,15 @@ import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.Arrays;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
+import java.util.Collections;
+import java.util.LinkedList;
+
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
@@ -59,22 +59,26 @@ import libcore.javax.net.ssl.TestTrustManager;
/**
* Implementation independent test for HttpsURLConnection.
- * The test needs certstore file placed in system classpath
- * and named as "key_store." + the type of the
- * default KeyStore installed in the system in lower case.
- * <br>
- * For example: if default KeyStore type in the system is BKS
- * (i.e. java.security file sets up the property keystore.type=BKS),
- * thus classpath should point to the directory with "key_store.bks"
- * file.
- * <br>
- * This certstore file should contain self-signed certificate
- * generated by keytool utility in a usual way.
- * <br>
- * The password to the certstore should be "password" (without quotes).
*/
public class HttpsURLConnectionTest extends TestCase {
+ private static final String POST_METHOD = "POST";
+
+ private static final String GET_METHOD = "GET";
+
+ /**
+ * Data to be posted by client to the server when the method is POST.
+ */
+ private static final String POST_DATA = "_.-^ Client's Data ^-._";
+
+ /**
+ * The content of the response to be sent during HTTPS session.
+ */
+ private static final String RESPONSE_CONTENT
+ = "<HTML>\n"
+ + "<HEAD><TITLE>HTTPS Response Content</TITLE></HEAD>\n"
+ + "</HTML>";
+
// the password to the store
private static final String KS_PASSWORD = "password";
@@ -107,7 +111,7 @@ public class HttpsURLConnectionTest extends TestCase {
* Checks that HttpsURLConnection's default SSLSocketFactory is operable.
*/
public void testGetDefaultSSLSocketFactory() throws Exception {
- // set up the properties defining the default values needed by SSL stuff
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
SSLSocketFactory defaultSSLSF = HttpsURLConnection.getDefaultSSLSocketFactory();
@@ -119,55 +123,58 @@ public class HttpsURLConnectionTest extends TestCase {
}
public void testHttpsConnection() throws Throwable {
- // set up the properties defining the default values needed by SSL stuff
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSL server socket acting as a server
SSLContext ctx = getContext();
- ServerSocket ss = ctx.getServerSocketFactory().createServerSocket(0);
- // create the HostnameVerifier to check hostname verification
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
+
+ // create a webserver to check and respond to requests
+ SingleRequestDispatcher dispatcher = new SingleRequestDispatcher(GET_METHOD, OK_CODE);
+ MockWebServer webServer = createWebServer(ctx, dispatcher);
// create url connection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
+ URL url = webServer.getUrl("/");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(ctx.getSocketFactory());
// perform the interaction between the peers
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
+ executeClientRequest(connection, false /* doOutput */);
- // check the connection state
- checkConnectionStateParameters(connection, peerSocket);
+ checkConnectionStateParameters(connection, dispatcher.getLastRequest());
// should silently exit
connection.connect();
+
+ webServer.shutdown();
}
/**
- * Tests the behaviour of HTTPS connection in case of unavailability
- * of requested resource.
+ * Tests the behaviour of HTTPS connection in case of unavailability of requested resource.
*/
public void testHttpsConnection_Not_Found_Response() throws Throwable {
- // set up the properties defining the default values needed by SSL stuff
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSL server socket acting as a server
SSLContext ctx = getContext();
- ServerSocket ss = ctx.getServerSocketFactory().createServerSocket(0);
- // create the HostnameVerifier to check hostname verification
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
+
+ // create a webserver to check and respond to requests
+ SingleRequestDispatcher dispatcher =
+ new SingleRequestDispatcher(GET_METHOD, NOT_FOUND_CODE);
+ MockWebServer webServer = createWebServer(ctx, dispatcher);
// create url connection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
+ URL url = webServer.getUrl("/");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(ctx.getSocketFactory());
try {
- doInteraction(connection, ss, NOT_FOUND_CODE);
+ executeClientRequest(connection, false /* doOutput */);
fail("Expected exception was not thrown.");
} catch (FileNotFoundException e) {
if (DO_LOG) {
@@ -178,94 +185,100 @@ public class HttpsURLConnectionTest extends TestCase {
// should silently exit
connection.connect();
+
+ webServer.shutdown();
}
/**
- * Tests possibility to set up the default SSLSocketFactory
- * to be used by HttpsURLConnection.
+ * Tests possibility to set up the default SSLSocketFactory to be used by HttpsURLConnection.
*/
public void testSetDefaultSSLSocketFactory() throws Throwable {
- // create the SSLServerSocket which will be used by server side
+ // set up the properties pointing to the key/trust stores
+ setUpStoreProperties();
+
SSLContext ctx = getContext();
- SSLServerSocket ss = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(0);
- SSLSocketFactory socketFactory = (SSLSocketFactory) ctx.getSocketFactory();
+ SSLSocketFactory socketFactory = ctx.getSocketFactory();
// set up the factory as default
HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
// check the result
assertSame("Default SSLSocketFactory differs from expected",
- socketFactory, HttpsURLConnection.getDefaultSSLSocketFactory());
+ socketFactory, HttpsURLConnection.getDefaultSSLSocketFactory());
- // create the HostnameVerifier to check hostname verification
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // set the initial default host name verifier.
+ TestHostnameVerifier initialHostnameVerifier = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(initialHostnameVerifier);
+
+ // create a webserver to check and respond to requests
+ SingleRequestDispatcher dispatcher = new SingleRequestDispatcher(GET_METHOD, OK_CODE);
+ MockWebServer webServer = createWebServer(ctx, dispatcher);
// create HttpsURLConnection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
+ URL url = webServer.getUrl("/");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
- TestHostnameVerifier hnv_late = new TestHostnameVerifier();
- // late initialization: should not be used for created connection
- HttpsURLConnection.setDefaultHostnameVerifier(hnv_late);
+ // late initialization: this HostnameVerifier should not be used for created connection
+ TestHostnameVerifier lateHostnameVerifier = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(lateHostnameVerifier);
// perform the interaction between the peers
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- // check the connection state
- checkConnectionStateParameters(connection, peerSocket);
+ executeClientRequest(connection, false /* doOutput */);
+ checkConnectionStateParameters(connection, dispatcher.getLastRequest());
+
// check the verification process
- assertTrue("Hostname verification was not done", hnv.verified);
+ assertTrue("Hostname verification was not done", initialHostnameVerifier.verified);
assertFalse("Hostname verification should not be done by this verifier",
- hnv_late.verified);
+ lateHostnameVerifier.verified);
// check the used SSLSocketFactory
assertSame("Default SSLSocketFactory should be used",
- HttpsURLConnection.getDefaultSSLSocketFactory(),
- connection.getSSLSocketFactory());
+ HttpsURLConnection.getDefaultSSLSocketFactory(),
+ connection.getSSLSocketFactory());
- // should silently exit
- connection.connect();
+ webServer.shutdown();
}
/**
- * Tests possibility to set up the SSLSocketFactory
- * to be used by HttpsURLConnection.
+ * Tests
+ * {@link javax.net.ssl.HttpsURLConnection#setSSLSocketFactory(javax.net.ssl.SSLSocketFactory)}.
*/
public void testSetSSLSocketFactory() throws Throwable {
- // create the SSLServerSocket which will be used by server side
+ // set up the properties pointing to the key/trust stores
SSLContext ctx = getContext();
- SSLServerSocket ss = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(0);
- // create the HostnameVerifier to check hostname verification
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // set the initial default host name verifier.
+ TestHostnameVerifier hostnameVerifier = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
+
+ // create a webserver to check and respond to requests
+ SingleRequestDispatcher dispatcher = new SingleRequestDispatcher(GET_METHOD, OK_CODE);
+ MockWebServer webServer = createWebServer(ctx, dispatcher);
// create HttpsURLConnection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
+ URL url = webServer.getUrl("/");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
- SSLSocketFactory socketFactory = (SSLSocketFactory) ctx.getSocketFactory();
+ // late initialization: should not be used for the created connection.
+ SSLSocketFactory socketFactory = ctx.getSocketFactory();
connection.setSSLSocketFactory(socketFactory);
- TestHostnameVerifier hnv_late = new TestHostnameVerifier();
// late initialization: should not be used for created connection
- HttpsURLConnection.setDefaultHostnameVerifier(hnv_late);
+ TestHostnameVerifier lateHostnameVerifier = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(lateHostnameVerifier);
// perform the interaction between the peers
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- // check the connection state
- checkConnectionStateParameters(connection, peerSocket);
+ executeClientRequest(connection, false /* doOutput */);
+ checkConnectionStateParameters(connection, dispatcher.getLastRequest());
// check the verification process
- assertTrue("Hostname verification was not done", hnv.verified);
+ assertTrue("Hostname verification was not done", hostnameVerifier.verified);
assertFalse("Hostname verification should not be done by this verifier",
- hnv_late.verified);
+ lateHostnameVerifier.verified);
// check the used SSLSocketFactory
assertNotSame("Default SSLSocketFactory should not be used",
- HttpsURLConnection.getDefaultSSLSocketFactory(),
- connection.getSSLSocketFactory());
- assertSame("Result differs from expected",
- socketFactory, connection.getSSLSocketFactory());
+ HttpsURLConnection.getDefaultSSLSocketFactory(),
+ connection.getSSLSocketFactory());
+ assertSame("Result differs from expected", socketFactory, connection.getSSLSocketFactory());
- // should silently exit
- connection.connect();
+ webServer.shutdown();
}
/**
@@ -304,97 +317,107 @@ public class HttpsURLConnectionTest extends TestCase {
* Tests if setHostnameVerifier() method replaces default verifier.
*/
public void testSetHostnameVerifier() throws Throwable {
- // setting up the properties pointing to the key/trust stores
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSLServerSocket which will be used by server side
- SSLServerSocket ss = (SSLServerSocket)
- getContext().getServerSocketFactory().createServerSocket(0);
+ SSLContext ctx = getContext();
+
+ TestHostnameVerifier defaultHostnameVerifier = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(defaultHostnameVerifier);
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create a webserver to check and respond to requests
+ SingleRequestDispatcher dispatcher = new SingleRequestDispatcher(GET_METHOD, OK_CODE);
+ MockWebServer webServer = createWebServer(ctx, dispatcher);
// create HttpsURLConnection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
+ URL url = webServer.getUrl("/");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(getContext().getSocketFactory());
- TestHostnameVerifier hnv_late = new TestHostnameVerifier();
- // replace default verifier
- connection.setHostnameVerifier(hnv_late);
+ // replace the default verifier
+ TestHostnameVerifier connectionHostnameVerifier = new TestHostnameVerifier();
+ connection.setHostnameVerifier(connectionHostnameVerifier);
// perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- assertTrue("Hostname verification was not done", hnv_late.verified);
+ executeClientRequest(connection, false /* doOutput */);
+ assertTrue("Hostname verification was not done", connectionHostnameVerifier.verified);
assertFalse("Hostname verification should not be done by this verifier",
- hnv.verified);
- checkConnectionStateParameters(connection, peerSocket);
+ defaultHostnameVerifier.verified);
- // should silently exit
- connection.connect();
+ checkConnectionStateParameters(connection, dispatcher.getLastRequest());
+
+ webServer.shutdown();
}
/**
* Tests the behaviour in case of sending the data to the server.
*/
public void test_doOutput() throws Throwable {
- // setting up the properties pointing to the key/trust stores
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSLServerSocket which will be used by server side
- SSLServerSocket ss = (SSLServerSocket)
- getContext().getServerSocketFactory().createServerSocket(0);
+ SSLContext ctx = getContext();
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create a webserver to check and respond to requests
+ SingleRequestDispatcher dispatcher = new SingleRequestDispatcher(POST_METHOD, OK_CODE);
+ MockWebServer webServer = createWebServer(ctx, dispatcher);
+
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
// create HttpsURLConnection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
+ URL url = webServer.getUrl("/");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(getContext().getSocketFactory());
- connection.setDoOutput(true);
// perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ executeClientRequest(connection, true /* doOutput */);
+ checkConnectionStateParameters(connection, dispatcher.getLastRequest());
// should silently exit
connection.connect();
+
+ webServer.shutdown();
}
/**
* Tests HTTPS connection process made through the proxy server.
*/
public void testProxyConnection() throws Throwable {
- // setting up the properties pointing to the key/trust stores
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ SSLContext ctx = getContext();
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
+
+ // create a server that pretends to be both a proxy and then the webserver
+ // request 1: proxy CONNECT, respond with OK
+ ProxyConnectDispatcher proxyConnectDispatcher =
+ new ProxyConnectDispatcher(false /* authenticationRequired */);
+ // request 2: tunnelled GET, respond with OK
+ SingleRequestDispatcher getDispatcher = new SingleRequestDispatcher(GET_METHOD, OK_CODE);
+ DelegatingDispatcher delegatingDispatcher =
+ new DelegatingDispatcher(proxyConnectDispatcher, getDispatcher);
+ MockWebServer proxyAndWebServer = createProxyAndWebServer(ctx, delegatingDispatcher);
// create HttpsURLConnection to be tested
+ URL proxyUrl = proxyAndWebServer.getUrl("/");
+ InetSocketAddress proxyAddress = new InetSocketAddress("localhost", proxyUrl.getPort());
URL url = new URL("https://requested.host:55556/requested.data");
HttpsURLConnection connection = (HttpsURLConnection)
- url.openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost",
- ss.getLocalPort())));
+ url.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddress));
connection.setSSLSocketFactory(getContext().getSocketFactory());
// perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ executeClientRequest(connection, false /* doOutput */);
+ checkConnectionStateParameters(connection, getDispatcher.getLastRequest());
// should silently exit
connection.connect();
+
+ proxyAndWebServer.shutdown();
}
/**
@@ -402,81 +425,105 @@ public class HttpsURLConnectionTest extends TestCase {
* Proxy server needs authentication.
*/
public void testProxyAuthConnection() throws Throwable {
- // setting up the properties pointing to the key/trust stores
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ SSLContext ctx = getContext();
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
Authenticator.setDefault(new Authenticator() {
-
protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("user", "password"
- .toCharArray());
+ return new PasswordAuthentication("user", "password".toCharArray());
}
});
+ // create a server that pretends to be both a proxy and then the webserver
+ // request 1: proxy CONNECT, respond with auth challenge
+ ProxyConnectAuthFailDispatcher authFailDispatcher = new ProxyConnectAuthFailDispatcher();
+ // request 2: proxy CONNECT, respond with OK
+ ProxyConnectDispatcher proxyConnectDispatcher =
+ new ProxyConnectDispatcher(true /* authenticationRequired */);
+ // request 3: tunnelled GET, respond with OK
+ SingleRequestDispatcher getDispatcher = new SingleRequestDispatcher(GET_METHOD, OK_CODE);
+ DelegatingDispatcher delegatingDispatcher = new DelegatingDispatcher(
+ authFailDispatcher, proxyConnectDispatcher, getDispatcher);
+ MockWebServer proxyAndWebServer = createProxyAndWebServer(ctx, delegatingDispatcher);
+
// create HttpsURLConnection to be tested
+ URL proxyUrl = proxyAndWebServer.getUrl("/");
+ InetSocketAddress proxyAddress = new InetSocketAddress("localhost", proxyUrl.getPort());
URL url = new URL("https://requested.host:55555/requested.data");
HttpsURLConnection connection = (HttpsURLConnection)
- url.openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost",
- ss.getLocalPort())));
+ url.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddress));
connection.setSSLSocketFactory(getContext().getSocketFactory());
// perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ executeClientRequest(connection, false /* doOutput */);
+ checkConnectionStateParameters(connection, getDispatcher.getLastRequest());
// should silently exit
connection.connect();
+
+ proxyAndWebServer.shutdown();
}
/**
* Tests HTTPS connection process made through the proxy server.
- * 2 HTTPS connections are opened for one URL. For the first time
- * the connection is opened through one proxy,
- * for the second time through another.
+ * Two HTTPS connections are opened for one URL: the first time the connection is opened
+ * through one proxy, the second time it is opened through another.
*/
public void testConsequentProxyConnection() throws Throwable {
- // setting up the properties pointing to the key/trust stores
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create a server that pretends to be both a proxy and then the webserver
+ SingleRequestDispatcher getDispatcher1 = new SingleRequestDispatcher(GET_METHOD, OK_CODE);
+ MockWebServer proxyAndWebServer1 = createProxiedServer(getDispatcher1);
// create HttpsURLConnection to be tested
+ URL proxyUrl1 = proxyAndWebServer1.getUrl("/");
URL url = new URL("https://requested.host:55555/requested.data");
+ InetSocketAddress proxyAddress = new InetSocketAddress("localhost", proxyUrl1.getPort());
HttpsURLConnection connection = (HttpsURLConnection)
- url.openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost",
- ss.getLocalPort())));
+ url.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddress));
connection.setSSLSocketFactory(getContext().getSocketFactory());
+ executeClientRequest(connection, false /* doOutput */);
+ checkConnectionStateParameters(connection, getDispatcher1.getLastRequest());
- // perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ proxyAndWebServer1.shutdown();
- // create another SSLServerSocket which will be used by server side
- ss = new ServerSocket(0);
+ // create another server
+ SingleRequestDispatcher getDispatcher2 = new SingleRequestDispatcher(GET_METHOD, OK_CODE);
+ MockWebServer proxyAndWebServer2 = createProxiedServer(getDispatcher2);
- connection = (HttpsURLConnection) url.openConnection(new Proxy(
- Proxy.Type.HTTP, new InetSocketAddress("localhost", ss.getLocalPort())));
- connection.setSSLSocketFactory(getContext().getSocketFactory());
+ // create another HttpsURLConnection to be tested
+ URL proxyUrl2 = proxyAndWebServer2.getUrl("/");
+ InetSocketAddress proxyAddress2 = new InetSocketAddress("localhost", proxyUrl2.getPort());
+ HttpsURLConnection connection2 = (HttpsURLConnection) url.openConnection(
+ new Proxy(Proxy.Type.HTTP, proxyAddress2));
+ connection2.setSSLSocketFactory(getContext().getSocketFactory());
// perform the interaction between the peers and check the results
- peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ executeClientRequest(connection2, false /* doOutput */);
+ checkConnectionStateParameters(connection2, getDispatcher2.getLastRequest());
+
+ proxyAndWebServer2.shutdown();
+ }
+
+ private static MockWebServer createProxiedServer(Dispatcher getDispatcher)
+ throws Exception {
+ // request 1: proxy CONNECT, respond with OK
+ ProxyConnectDispatcher proxyConnectDispatcher =
+ new ProxyConnectDispatcher(false /* authenticationRequired */);
+ // request 2: The get dispatcher.
+ DelegatingDispatcher delegatingDispatcher1 =
+ new DelegatingDispatcher(proxyConnectDispatcher, getDispatcher);
+ return createProxyAndWebServer(getContext(), delegatingDispatcher1);
}
/**
@@ -485,37 +532,47 @@ public class HttpsURLConnectionTest extends TestCase {
* Client sends data to the server.
*/
public void testProxyAuthConnection_doOutput() throws Throwable {
- // setting up the properties pointing to the key/trust stores
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ SSLContext ctx = getContext();
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
Authenticator.setDefault(new Authenticator() {
-
protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("user", "password"
- .toCharArray());
+ return new PasswordAuthentication("user", "password".toCharArray());
}
});
+ // create a server that pretends to be both a proxy and then the webserver
+ // request 1: proxy CONNECT, respond with auth challenge
+ ProxyConnectAuthFailDispatcher authFailDispatcher = new ProxyConnectAuthFailDispatcher();
+ // request 2: proxy CONNECT, respond with OK
+ ProxyConnectDispatcher proxyConnectDispatcher =
+ new ProxyConnectDispatcher(true /* authenticationRequired */);
+ // request 3: tunnelled POST, respond with OK
+ SingleRequestDispatcher postDispatcher = new SingleRequestDispatcher(POST_METHOD, OK_CODE);
+ DelegatingDispatcher delegatingDispatcher = new DelegatingDispatcher(
+ authFailDispatcher, proxyConnectDispatcher, postDispatcher);
+ MockWebServer proxyAndWebServer = createProxyAndWebServer(ctx, delegatingDispatcher);
+ URL proxyUrl = proxyAndWebServer.getUrl("/");
+
// create HttpsURLConnection to be tested
- URL url = new URL("https://requested.host:55554/requested.data");
+ InetSocketAddress proxyAddress = new InetSocketAddress("localhost", proxyUrl.getPort());
HttpsURLConnection connection = (HttpsURLConnection)
- url.openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost",
- ss.getLocalPort())));
+ proxyUrl.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddress));
connection.setSSLSocketFactory(getContext().getSocketFactory());
- connection.setDoOutput(true);
// perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss, OK_CODE, true);
- checkConnectionStateParameters(connection, peerSocket);
+ executeClientRequest(connection, true /* doOutput */);
+ checkConnectionStateParameters(connection, postDispatcher.getLastRequest());
+
+ // should silently exit
+ connection.connect();
+
+ proxyAndWebServer.shutdown();
}
/**
@@ -524,79 +581,82 @@ public class HttpsURLConnectionTest extends TestCase {
* (Authenticator was not set up in the system).
*/
public void testProxyAuthConnectionFailed() throws Throwable {
- // setting up the properties pointing to the key/trust stores
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create a server that pretends to be both a proxy that requests authentication.
+ MockWebServer proxyAndWebServer = new MockWebServer();
+ ProxyConnectAuthFailDispatcher authFailDispatcher = new ProxyConnectAuthFailDispatcher();
+ proxyAndWebServer.setDispatcher(authFailDispatcher);
+ proxyAndWebServer.play();
// create HttpsURLConnection to be tested
+ URL proxyUrl = proxyAndWebServer.getUrl("/");
+ InetSocketAddress proxyAddress = new InetSocketAddress("localhost", proxyUrl.getPort());
URL url = new URL("https://requested.host:55555/requested.data");
HttpsURLConnection connection = (HttpsURLConnection)
- url.openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost",
- ss.getLocalPort())));
+ url.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddress));
connection.setSSLSocketFactory(getContext().getSocketFactory());
// perform the interaction between the peers and check the results
try {
- doInteraction(connection, ss, AUTHENTICATION_REQUIRED_CODE, true);
+ executeClientRequest(connection, false);
} catch (IOException e) {
// SSL Tunnelling failed
if (DO_LOG) {
- System.out.println("Got expected IOException: "
- + e.getMessage());
+ System.out.println("Got expected IOException: " + e.getMessage());
}
}
}
/**
- * Tests the behaviour of HTTPS connection in case of unavailability
- * of requested resource.
+ * Tests the behaviour of HTTPS connection in case of unavailability of requested resource (as
+ * reported by the target web server).
*/
public void testProxyConnection_Not_Found_Response() throws Throwable {
- // setting up the properties pointing to the key/trust stores
+ // set up the properties pointing to the key/trust stores
setUpStoreProperties();
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ SSLContext ctx = getContext();
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // set the HostnameVerifier required to satisfy SSL - always returns "verified".
+ HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
+
+ // create a server that pretends to be a proxy
+ ProxyConnectDispatcher proxyConnectDispatcher =
+ new ProxyConnectDispatcher(false /* authenticationRequired */);
+ SingleRequestDispatcher notFoundDispatcher =
+ new SingleRequestDispatcher(GET_METHOD, NOT_FOUND_CODE);
+ DelegatingDispatcher delegatingDispatcher =
+ new DelegatingDispatcher(proxyConnectDispatcher, notFoundDispatcher);
+ MockWebServer proxyAndWebServer = createProxyAndWebServer(ctx, delegatingDispatcher);
// create HttpsURLConnection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
+ URL proxyUrl = proxyAndWebServer.getUrl("/");
+ InetSocketAddress proxyAddress = new InetSocketAddress("localhost", proxyUrl.getPort());
+ URL url = new URL("https://requested.host:55555/requested.data");
HttpsURLConnection connection = (HttpsURLConnection)
- url.openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost",
- ss.getLocalPort())));
+ url.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddress));
connection.setSSLSocketFactory(getContext().getSocketFactory());
try {
- doInteraction(connection, ss, NOT_FOUND_CODE); // NOT FOUND
+ executeClientRequest(connection, false /* doOutput */);
fail("Expected exception was not thrown.");
} catch (FileNotFoundException e) {
if (DO_LOG) {
- System.out.println("Expected exception was thrown: "
- + e.getMessage());
+ System.out.println("Expected exception was thrown: " + e.getMessage());
}
}
}
- /**
- * Log the name of the test case to be executed.
- */
public void setUp() throws Exception {
super.setUp();
if (DO_LOG) {
+ // Log the name of the test case to be executed.
System.out.println();
System.out.println("------------------------");
System.out.println("------ " + getName());
@@ -604,8 +664,8 @@ public class HttpsURLConnectionTest extends TestCase {
}
if (store != null) {
- String ksFileName = ("org/apache/harmony/luni/tests/key_store."
- + KeyStore.getDefaultType().toLowerCase());
+ String ksFileName = "org/apache/harmony/luni/tests/key_store." +
+ KeyStore.getDefaultType().toLowerCase();
InputStream in = getClass().getClassLoader().getResourceAsStream(ksFileName);
FileOutputStream out = new FileOutputStream(store);
BufferedInputStream bufIn = new BufferedInputStream(in, 8192);
@@ -627,28 +687,21 @@ public class HttpsURLConnectionTest extends TestCase {
}
}
- /**
- * Checks the HttpsURLConnection getter's values and compares
- * them with actual corresponding values of remote peer.
- */
- public static void checkConnectionStateParameters(
- HttpsURLConnection clientConnection, SSLSocket serverPeer)
- throws Exception {
- SSLSession session = serverPeer.getSession();
-
- assertEquals(session.getCipherSuite(), clientConnection.getCipherSuite());
- assertEquals(session.getLocalPrincipal(), clientConnection.getPeerPrincipal());
- assertEquals(session.getPeerPrincipal(), clientConnection.getLocalPrincipal());
+ private static void checkConnectionStateParameters(
+ HttpsURLConnection connection, RecordedRequest request) throws Exception {
+ assertEquals(request.getSslCipherSuite(), connection.getCipherSuite());
+ assertEquals(request.getSslLocalPrincipal(), connection.getPeerPrincipal());
+ assertEquals(request.getSslPeerPrincipal(), connection.getLocalPrincipal());
- Certificate[] serverCertificates = clientConnection.getServerCertificates();
- Certificate[] localCertificates = session.getLocalCertificates();
+ Certificate[] serverCertificates = connection.getServerCertificates();
+ Certificate[] localCertificates = request.getSslLocalCertificates();
assertTrue("Server certificates differ from expected",
- Arrays.equals(serverCertificates, localCertificates));
+ Arrays.equals(serverCertificates, localCertificates));
- localCertificates = clientConnection.getLocalCertificates();
- serverCertificates = session.getPeerCertificates();
+ localCertificates = connection.getLocalCertificates();
+ serverCertificates = request.getSslPeerCertificates();
assertTrue("Local certificates differ from expected",
- Arrays.equals(serverCertificates, localCertificates));
+ Arrays.equals(serverCertificates, localCertificates));
}
/**
@@ -714,395 +767,233 @@ public class HttpsURLConnectionTest extends TestCase {
}
/**
- * Performs interaction between client's HttpsURLConnection and
- * servers side (ServerSocket).
+ * The host name verifier used in test.
*/
- public static Socket doInteraction(final HttpsURLConnection clientConnection,
- final ServerSocket serverSocket)
- throws Throwable {
- return doInteraction(clientConnection, serverSocket, OK_CODE, false);
+ static class TestHostnameVerifier implements HostnameVerifier {
+
+ boolean verified = false;
+
+ public boolean verify(String hostname, SSLSession session) {
+ if (DO_LOG) {
+ System.out.println("***> verification " + hostname + " "
+ + session.getPeerHost());
+ }
+ verified = true;
+ return true;
+ }
}
/**
- * Performs interaction between client's HttpsURLConnection and
- * servers side (ServerSocket). Server will response with specified
- * response code.
+ * Creates a {@link MockWebServer} that acts as both a proxy and then a web server with the
+ * supplied {@link SSLContext} and {@link Dispatcher}. The dispatcher provided must handle the
+ * CONNECT request/responses and {@link SocketPolicy} needed to simulate the hand-off from proxy
+ * to web server. See {@link HttpsURLConnectionTest.ProxyConnectDispatcher}.
*/
- public static Socket doInteraction(final HttpsURLConnection clientConnection,
- final ServerSocket serverSocket,
- final int responseCode)
- throws Throwable {
- return doInteraction(clientConnection, serverSocket, responseCode, false);
+ private static MockWebServer createProxyAndWebServer(SSLContext ctx, Dispatcher dispatcher)
+ throws IOException {
+ return createServer(ctx, dispatcher, true /* handleProxying */);
}
/**
- * Performs interaction between client's HttpsURLConnection and
- * servers side (ServerSocket). Server will response with specified
- * response code.
- * @param doAuthentication specifies
- * if the server needs client authentication.
+ * Creates a {@link MockWebServer} that acts as (only) a web server with the supplied
+ * {@link SSLContext} and {@link Dispatcher}.
*/
- public static Socket doInteraction(final HttpsURLConnection clientConnection,
- final ServerSocket serverSocket,
- final int responseCode,
- final boolean doAuthentication)
- throws Throwable {
- // set up the connection
- clientConnection.setDoInput(true);
- clientConnection.setConnectTimeout(TIMEOUT);
- clientConnection.setReadTimeout(TIMEOUT);
+ private static MockWebServer createWebServer(SSLContext ctx, Dispatcher dispatcher)
+ throws IOException {
+ return createServer(ctx, dispatcher, false /* handleProxying */);
+ }
- ServerWork server = new ServerWork(serverSocket, responseCode, doAuthentication);
+ private static MockWebServer createServer(
+ SSLContext ctx, Dispatcher dispatcher, boolean handleProxying)
+ throws IOException {
+ MockWebServer webServer = new MockWebServer();
+ webServer.useHttps(ctx.getSocketFactory(), handleProxying /* tunnelProxy */);
+ webServer.setDispatcher(dispatcher);
+ webServer.play();
+ return webServer;
+ }
- ClientConnectionWork client = new ClientConnectionWork(clientConnection);
+ /**
+ * A {@link Dispatcher} that has a list of dispatchers to delegate to, each of which will be
+ * used for one request and then discarded.
+ */
+ private static class DelegatingDispatcher extends Dispatcher {
+ private LinkedList<Dispatcher> delegates = new LinkedList<Dispatcher>();
- ExecutorService executorService = Executors.newFixedThreadPool(2);
- try {
- Future<Void> serverFuture = executorService.submit(server);
- Future<Void> clientFuture = executorService.submit(client);
-
- Throwable t = null;
- try {
- serverFuture.get(30, TimeUnit.SECONDS);
- } catch (ExecutionException e) {
- t = e.getCause();
- }
- try {
- clientFuture.get(30, TimeUnit.SECONDS);
- } catch (ExecutionException e) {
- // two problems? log the first before overwriting
- if (t != null) {
- t.printStackTrace();
- }
- t = e.getCause();
- }
- if (t != null) {
- throw t;
- }
- } catch (ExecutionException e) {
- throw e.getCause();
- } finally {
- executorService.shutdown();
+ public DelegatingDispatcher(Dispatcher... dispatchers) {
+ addAll(dispatchers);
+ }
+
+ private void addAll(Dispatcher... dispatchers) {
+ Collections.addAll(delegates, dispatchers);
+ }
+
+ @Override
+ public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
+ return delegates.removeFirst().dispatch(request);
}
- return server.peerSocket;
+ @Override
+ public SocketPolicy peekSocketPolicy() {
+ return delegates.getFirst().peekSocketPolicy();
+ }
}
- /**
- * The host name verifier used in test.
- */
- static class TestHostnameVerifier implements HostnameVerifier {
+ /** Handles a request for SSL tunnel: Answers with a request to authenticate. */
+ private static class ProxyConnectAuthFailDispatcher extends Dispatcher {
- boolean verified = false;
+ @Override
+ public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
+ assertEquals("CONNECT", request.getMethod());
- public boolean verify(String hostname, SSLSession session) {
- if (DO_LOG) {
- System.out.println("***> verification " + hostname + " "
- + session.getPeerHost());
- }
- verified = true;
- return true;
+ MockResponse response = new MockResponse();
+ response.setResponseCode(AUTHENTICATION_REQUIRED_CODE);
+ response.addHeader("Proxy-authenticate: Basic realm=\"localhost\"");
+ log("Authentication required. Sending response: " + response);
+ return response;
+ }
+
+ private void log(String msg) {
+ HttpsURLConnectionTest.log("ProxyConnectAuthFailDispatcher", msg);
}
}
/**
- * The base class for mock Client and Server.
+ * Handles a request for SSL tunnel: Answers with a success and the socket is upgraded to SSL.
*/
- static class Work {
-
- /**
- * The header of OK HTTP response.
- */
- static final String responseHead = "HTTP/1.1 200 OK\r\n";
-
- /**
- * The response message to be sent to the proxy CONNECT request.
- */
- static final String proxyResponse = responseHead + "\r\n";
-
- /**
- * The content of the response to be sent during HTTPS session.
- */
- static final String httpsResponseContent
- = "<HTML>\n"
- + "<HEAD><TITLE>HTTPS Response Content</TITLE></HEAD>\n"
- + "</HTML>";
-
- /**
- * The tail of the response to be sent during HTTPS session.
- */
- static final String httpsResponseTail
- = "Content-type: text/html\r\n"
- + "Content-length: " + httpsResponseContent.length() + "\r\n"
- + "\r\n"
- + httpsResponseContent;
-
- /**
- * The response requiring client's proxy authentication.
- */
- static final String respAuthenticationRequired
- = "HTTP/1.0 407 Proxy authentication required\r\n"
- + "Proxy-authenticate: Basic realm=\"localhost\"\r\n"
- + "\r\n";
-
- /**
- * The data to be posted by client to the server.
- */
- static final String clientsData = "_.-^ Client's Data ^-._";
-
- /**
- * The print stream used for debug log.
- * If it is null debug info will not be printed.
- */
- private PrintStream out = System.out;
-
- /**
- * Prints log message.
- */
- public synchronized void log(String message) {
- if (DO_LOG && (out != null)) {
- out.println("[" + this + "]: " + message);
+ private static class ProxyConnectDispatcher extends Dispatcher {
+
+ private final boolean authenticationRequired;
+
+ private ProxyConnectDispatcher(boolean authenticationRequired) {
+ this.authenticationRequired = authenticationRequired;
+ }
+
+ @Override
+ public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
+ if (authenticationRequired) {
+ // check provided authorization credentials
+ assertNotNull("no proxy-authorization credentials: " + request,
+ request.getHeader("proxy-authorization"));
+ log("Got authenticated request:\n" + request);
+ log("------------------");
}
+
+ assertEquals("CONNECT", request.getMethod());
+ log("Send proxy response");
+ MockResponse response = new MockResponse();
+ response.setResponseCode(200);
+ response.setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END);
+ return response;
+ }
+
+ @Override
+ public SocketPolicy peekSocketPolicy() {
+ return SocketPolicy.UPGRADE_TO_SSL_AT_END;
+ }
+
+ private void log(String msg) {
+ HttpsURLConnectionTest.log("ProxyConnectDispatcher", msg);
}
}
/**
- * The class used for server side works.
+ * Handles a request: Answers with a response with a specified status code.
+ * If the {@code expectedMethod} is {@code POST} a hardcoded response body {@link #POST_DATA}
+ * will be included in the response.
*/
- static class ServerWork extends Work implements Callable<Void> {
-
- // the server socket used for connection
- private final ServerSocket serverSocket;
+ private static class SingleRequestDispatcher extends Dispatcher {
- // indicates if the server acts as proxy server
- private final boolean actAsProxy;
-
- // indicates if the server needs proxy authentication
- private final boolean needProxyAuthentication;
-
- // response code to be send to the client peer
+ private final String expectedMethod;
private final int responseCode;
- // the socket connected with client peer
- private Socket peerSocket;
-
- /**
- * Creates the thread acting as a server side.
- * @param serverSocket the server socket to be used during connection
- * @param responseCode the response code to be sent to the client
- * @param needProxyAuthentication
- * indicates if the server needs proxy authentication
- */
- public ServerWork(ServerSocket serverSocket,
- int responseCode,
- boolean needProxyAuthentication) {
- this.serverSocket = serverSocket;
+ private RecordedRequest lastRequest;
+
+ private SingleRequestDispatcher(String expectedMethod, int responseCode) {
this.responseCode = responseCode;
- this.needProxyAuthentication = needProxyAuthentication;
- // will act as a proxy server if the specified server socket
- // is not a secure server socket
- this.actAsProxy = !(serverSocket instanceof SSLServerSocket);
- if (!actAsProxy) {
- // demand client to send its certificate
- ((SSLServerSocket) serverSocket).setNeedClientAuth(true);
- }
+ this.expectedMethod = expectedMethod;
}
- /**
- * Closes the connection.
- */
- public void closeSocket(Socket socket) {
- if (socket == null) {
- return;
+ @Override
+ public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
+ if (lastRequest != null) {
+ fail("More than one request received");
}
- try {
- socket.getInputStream().close();
- } catch (IOException e) {}
- try {
- socket.getOutputStream().close();
- } catch (IOException e) {}
- try {
- socket.close();
- } catch (IOException e) {}
+ log("Request received: " + request);
+ lastRequest = request;
+ assertEquals(expectedMethod, request.getMethod());
+ if (POST_METHOD.equals(expectedMethod)) {
+ assertEquals(POST_DATA, request.getUtf8Body());
+ }
+
+ MockResponse response = new MockResponse();
+ response.setResponseCode(responseCode);
+ response.setBody(RESPONSE_CONTENT);
+
+ log("Responding with: " + response);
+ return response;
}
- /**
- * Performs the actual server work.
- * If some exception occurs during the work it will be
- * stored in the <code>thrown</code> field.
- */
- public Void call() throws Exception {
- // the buffer used for reading the messages
- byte[] buff = new byte[2048];
- // the number of bytes read into the buffer
- try {
- // configure the server socket to avoid blocking
- serverSocket.setSoTimeout(TIMEOUT);
- // accept client connection
- peerSocket = serverSocket.accept();
- // configure the client connection to avoid blocking
- peerSocket.setSoTimeout(TIMEOUT);
- log("Client connection ACCEPTED");
-
- InputStream is = peerSocket.getInputStream();
- OutputStream os = peerSocket.getOutputStream();
-
- int num = is.read(buff);
- if (num == -1) {
- log("Unexpected EOF");
- return null;
- }
-
- String message = new String(buff, 0, num);
- log("Got request:\n" + message);
- log("------------------");
+ public RecordedRequest getLastRequest() {
+ return lastRequest;
+ }
- if (!actAsProxy) {
- // Act as Server (not Proxy) side
- if (message.startsWith("POST")) {
- // client connection sent some data
- log("try to read client data");
- String data = message.substring(message.indexOf("\r\n\r\n")+4);
- log("client's data: '" + data + "'");
- // check the received data
- assertEquals(clientsData, data);
- }
- } else {
- if (needProxyAuthentication) {
- // Do proxy work
- log("Authentication required...");
- // send Authentication Request
- os.write(respAuthenticationRequired.getBytes());
- // read request
- num = is.read(buff);
- if (num == -1) {
- // this connection was closed,
- // do clean up and create new one:
- closeSocket(peerSocket);
- peerSocket = serverSocket.accept();
- peerSocket.setSoTimeout(TIMEOUT);
- log("New client connection ACCEPTED");
- is = peerSocket.getInputStream();
- os = peerSocket.getOutputStream();
- num = is.read(buff);
- }
- message = new String(buff, 0, num);
- log("Got authenticated request:\n" + message);
- log("------------------");
- // check provided authorization credentials
- assertTrue("no proxy-authorization credentials: " + message,
- message.toLowerCase().indexOf("proxy-authorization:") != -1);
- }
-
- assertTrue(message.startsWith("CONNECT"));
- // request for SSL tunnel
- log("Send proxy response");
- os.write(proxyResponse.getBytes());
-
- log("Perform SSL Handshake...");
- // create sslSocket acting as a remote server peer
- SSLSocket sslSocket = (SSLSocket)
- getContext().getSocketFactory().createSocket(peerSocket,
- "localhost",
- peerSocket.getPort(),
- true); // do autoclose
- sslSocket.setUseClientMode(false);
- // demand client authentication
- sslSocket.setNeedClientAuth(true);
- sslSocket.startHandshake();
- peerSocket = sslSocket;
- is = peerSocket.getInputStream();
- os = peerSocket.getOutputStream();
-
- // read the HTTP request sent by secure connection
- // (HTTPS request)
- num = is.read(buff);
- message = new String(buff, 0, num);
- log("[Remote Server] Request from SSL tunnel:\n" + message);
- log("------------------");
-
- if (message.startsWith("POST")) {
- // client connection sent some data
- log("[Remote Server] try to read client data");
- String data = message.substring(message.indexOf("\r\n\r\n")+4);
- log("[Remote Server] client's data: '" + message + "'");
- // check the received data
- assertEquals(clientsData, data);
- }
-
- log("[Remote Server] Sending the response by SSL tunnel...");
- }
-
- // send the response with specified response code
- os.write(("HTTP/1.1 " + responseCode
- + " Message\r\n" + httpsResponseTail).getBytes());
- os.flush();
- os.close();
- log("Work is DONE actAsProxy=" + actAsProxy);
- return null;
- } finally {
- closeSocket(peerSocket);
- try {
- serverSocket.close();
- } catch (IOException e) {}
- }
+ @Override
+ public SocketPolicy peekSocketPolicy() {
+ return SocketPolicy.DISCONNECT_AT_END;
}
- @Override public String toString() {
- return actAsProxy ? "Proxy Server" : "Server";
+ private void log(String msg) {
+ HttpsURLConnectionTest.log("SingleRequestDispatcher", msg);
}
}
/**
- * The class used for client side work.
+ * Executes an HTTP request using the supplied connection. If {@code doOutput} is {@code true}
+ * the request made is a POST and the request body sent is {@link #POST_DATA}.
+ * If {@code doOutput} is {@code false} the request made is a GET. The response must be a
+ * success with a body {@link #RESPONSE_CONTENT}.
*/
- static class ClientConnectionWork extends Work implements Callable<Void> {
-
- // connection to be used to contact the server side
- private HttpsURLConnection connection;
-
- /**
- * Creates the thread acting as a client side.
- * @param connection connection to be used to contact the server side
- */
- public ClientConnectionWork(HttpsURLConnection connection) {
- this.connection = connection;
- log("Created over connection: " + connection.getClass());
- }
+ private static void executeClientRequest(
+ HttpsURLConnection connection, boolean doOutput) throws IOException {
- /**
- * Performs the actual client work.
- * If some exception occurs during the work it will be
- * stored in the <code>thrown<code> field.
- */
- public Void call() throws Exception {
- log("Opening the connection to " + connection.getURL());
- connection.connect();
- log("Connection has been ESTABLISHED, using proxy: " + connection.usingProxy());
- if (connection.getDoOutput()) {
- log("Posting data");
- // connection configured to post data, do so
- connection.getOutputStream().write(clientsData.getBytes());
- }
- // read the content of HTTP(s) response
- InputStream is = connection.getInputStream();
- log("Input Stream obtained");
- byte[] buff = new byte[2048];
- int num = 0;
- int byt = 0;
- while ((num < buff.length) && ((byt = is.read()) != -1)) {
- buff[num++] = (byte) byt;
- }
- String message = new String(buff, 0, num);
- log("Got content:\n" + message);
- log("------------------");
- log("Response code: " + connection.getResponseCode());
- assertEquals(httpsResponseContent, message);
- return null;
+ // set up the connection
+ connection.setDoInput(true);
+ connection.setConnectTimeout(TIMEOUT);
+ connection.setReadTimeout(TIMEOUT);
+ connection.setDoOutput(doOutput);
+
+ log("Client", "Opening the connection to " + connection.getURL());
+ connection.connect();
+ log("Client", "Connection has been ESTABLISHED, using proxy: " + connection.usingProxy());
+ if (doOutput) {
+ log("Client", "Posting data");
+ // connection configured to post data, do so
+ OutputStream os = connection.getOutputStream();
+ os.write(POST_DATA.getBytes());
+ }
+ // read the content of HTTP(s) response
+ InputStream is = connection.getInputStream();
+ log("Client", "Input Stream obtained");
+ byte[] buff = new byte[2048];
+ int num = 0;
+ int byt;
+ while ((num < buff.length) && ((byt = is.read()) != -1)) {
+ buff[num++] = (byte) byt;
}
+ String message = new String(buff, 0, num);
+ log("Client", "Got content:\n" + message);
+ log("Client", "------------------");
+ log("Client", "Response code: " + connection.getResponseCode());
+ assertEquals(RESPONSE_CONTENT, message);
+ }
- @Override public String toString() {
- return "Client Connection";
+ /**
+ * Prints log message.
+ */
+ public static synchronized void log(String origin, String message) {
+ if (DO_LOG) {
+ System.out.println("[" + origin + "]: " + message);
}
}
}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java
index 12406f3..d1f92ec 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java
@@ -17,13 +17,17 @@
package org.apache.harmony.luni.tests.java.io;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+import tests.support.Support_ASimpleInputStream;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -35,34 +39,22 @@ import java.io.ObjectInputValidation;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
+import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Serializable;
-import java.io.SerializablePermission;
import java.io.StreamCorruptedException;
import java.lang.reflect.Proxy;
-import java.security.Permission;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
-
@SuppressWarnings("serial")
public class ObjectInputStreamTest extends TestCase implements
Serializable {
- ObjectInputStream ois;
-
- ObjectOutputStream oos;
-
- ByteArrayOutputStream bao;
-
public class SerializableTestHelper implements Serializable {
public String aField1;
@@ -127,9 +119,306 @@ public class ObjectInputStreamTest extends TestCase implements
Hashtable h = new Hashtable();
}
- /**
- * java.io.ObjectInputStream#readObject()
- */
+ static final long serialVersionUID = 1L;
+
+ ObjectInputStream ois;
+
+ ObjectOutputStream oos;
+
+ ByteArrayOutputStream bao;
+
+ boolean readStreamHeaderCalled;
+
+ private final String testString = "Lorem ipsum...";
+
+ private final int testLength = testString.length();
+
+ public void test_ConstructorLjava_io_InputStream_IOException() throws IOException {
+ oos.writeObject(testString);
+ oos.close();
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois = new ObjectInputStream(sis);
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ }
+
+ public void test_ClassDescriptor() throws IOException,
+ ClassNotFoundException {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStreamWithWriteDesc oos = new ObjectOutputStreamWithWriteDesc(
+ baos);
+ oos.writeObject(String.class);
+ oos.close();
+ Class<?> cls = TestClassForSerialization.class;
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStreamWithReadDesc ois = new ObjectInputStreamWithReadDesc(
+ bais, cls);
+ Object obj = ois.readObject();
+ ois.close();
+ assertEquals(cls, obj);
+ }
+
+ public void test_available_IOException() throws IOException {
+ oos.writeObject(testString);
+ oos.close();
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ ois = new ObjectInputStream(sis);
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois.available();
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ ois.close();
+ }
+
+ public void test_close() throws Exception {
+ // Test for method void java.io.ObjectInputStream.close()
+ oos.writeObject(testString);
+ oos.close();
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ ois = new ObjectInputStream(sis);
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois.close();
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ ois.close();
+ }
+
+ public void test_enableResolveObjectB() throws IOException {
+ // Start testing without a SecurityManager.
+ BasicObjectInputStream bois = new BasicObjectInputStream();
+ assertFalse("Test 1: Object resolving must be disabled by default.",
+ bois.enableResolveObject(true));
+
+ assertTrue("Test 2: enableResolveObject did not return the previous value.",
+ bois.enableResolveObject(false));
+ }
+
+ public void test_read_IOException() throws IOException {
+ oos.writeObject(testString);
+ oos.close();
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ ois = new ObjectInputStream(sis);
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois.read();
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ ois.close();
+ }
+
+ public void test_read$BII_Exception() throws IOException {
+ byte[] buf = new byte[testLength];
+ oos.writeObject(testString);
+ oos.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ try {
+ ois.read(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.read(buf, -1,1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.read(buf, testLength, 1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ ois.close();
+
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ ois = new ObjectInputStream(sis);
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois.read(buf, 0, testLength);
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ ois.close();
+ }
+
+ public void test_readFully$B() throws IOException {
+ byte[] buf = new byte[testLength];
+ oos.writeBytes(testString);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ois.readFully(buf);
+ assertEquals("Test 1: Incorrect bytes read;",
+ testString, new String(buf));
+ ois.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ois.read();
+ try {
+ ois.readFully(buf);
+ fail("Test 2: EOFException expected.");
+ } catch (EOFException e) {
+ // Expected.
+ }
+ }
+
+ public void test_readFully$B_Exception() throws IOException {
+ byte[] buf = new byte[testLength];
+ oos.writeObject(testString);
+ oos.close();
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ ois = new ObjectInputStream(sis);
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois.readFully(buf);
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ ois.close();
+ }
+
+ public void test_readFully$BII() throws IOException {
+ // Test for method void java.io.ObjectInputStream.readFully(byte [],
+ // int, int)
+ byte[] buf = new byte[testLength];
+ oos.writeBytes(testString);
+ oos.close();
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ois.readFully(buf, 0, testLength);
+ assertEquals("Read incorrect bytes", testString, new String(buf));
+ ois.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ ois.read();
+ try {
+ ois.readFully(buf);
+ fail("Test 2: EOFException expected.");
+ } catch (EOFException e) {
+ // Expected.
+ }
+ }
+
+ public void test_readFully$BII_Exception() throws IOException {
+ byte[] buf = new byte[testLength];
+ oos.writeObject(testString);
+ oos.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ try {
+ ois.readFully(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.readFully(buf, -1,1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.readFully(buf, testLength, 1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ ois.close();
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ ois = new ObjectInputStream(sis);
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois.readFully(buf, 0, 1);
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ ois.close();
+ }
+
+ public void test_readLine_IOException() throws IOException {
+ oos.writeObject(testString);
+ oos.close();
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ ois = new ObjectInputStream(sis);
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois.readLine();
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ ois.close();
+ }
+
+ private void fillStreamHeader(byte[] buffer) {
+ short magic = java.io.ObjectStreamConstants.STREAM_MAGIC;
+ short version = java.io.ObjectStreamConstants.STREAM_VERSION;
+
+ if (buffer.length < 4) {
+ throw new IllegalArgumentException("The buffer's minimal length must be 4.");
+ }
+
+ // Initialize the buffer with the correct header for object streams
+ buffer[0] = (byte) (magic >> 8);
+ buffer[1] = (byte) magic;
+ buffer[2] = (byte) (version >> 8);
+ buffer[3] = (byte) (version);
+ }
+
+ public void test_readObjectOverride() throws Exception {
+ byte[] buffer = new byte[4];
+
+ // Initialize the buffer with the correct header for object streams
+ fillStreamHeader(buffer);
+
+ // Test 1: Check that readObjectOverride() returns null if there
+ // is no input stream.
+ BasicObjectInputStream bois = new BasicObjectInputStream();
+ assertNull("Test 1:", bois.readObjectOverride());
+
+ // Test 2: Check that readObjectOverride() throws an IOException
+ // if there is an input stream.
+ bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
+ try {
+ bois.readObjectOverride();
+ fail("Test 2: IOException expected.");
+ } catch (IOException e) {}
+
+ bois.close();
+ }
+
public void test_readObjectMissingClasses() throws Exception {
SerializationTest.verifySelf(new A1(), new SerializableAssert() {
public void assertDeserialized(Serializable initial,
@@ -139,9 +428,190 @@ public class ObjectInputStreamTest extends TestCase implements
});
}
- /**
- * java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
- */
+ public void test_readStreamHeader() throws IOException {
+ String testString = "Lorem ipsum";
+ BasicObjectInputStream bois;
+ short magic = java.io.ObjectStreamConstants.STREAM_MAGIC;
+ short version = java.io.ObjectStreamConstants.STREAM_VERSION;
+ byte[] buffer = new byte[20];
+
+ // Initialize the buffer with the correct header for object streams
+ fillStreamHeader(buffer);
+ System.arraycopy(testString.getBytes(), 0, buffer, 4, testString.length());
+
+ // Test 1: readStreamHeader should not throw a StreamCorruptedException.
+ // It should get called by the ObjectInputStream constructor.
+ try {
+ readStreamHeaderCalled = false;
+ bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
+ bois.close();
+ } catch (StreamCorruptedException e) {
+ fail("Test 1: Unexpected StreamCorruptedException.");
+ }
+ assertTrue("Test 1: readStreamHeader() has not been called.",
+ readStreamHeaderCalled);
+
+ // Test 2: Make the stream magic number invalid and check that
+ // readStreamHeader() throws an exception.
+ buffer[0] = (byte)magic;
+ buffer[1] = (byte)(magic >> 8);
+ try {
+ readStreamHeaderCalled = false;
+ bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
+ fail("Test 2: StreamCorruptedException expected.");
+ bois.close();
+ } catch (StreamCorruptedException e) {
+ }
+ assertTrue("Test 2: readStreamHeader() has not been called.",
+ readStreamHeaderCalled);
+
+ // Test 3: Make the stream version invalid and check that
+ // readStreamHeader() throws an exception.
+ buffer[0] = (byte)(magic >> 8);
+ buffer[1] = (byte)magic;
+ buffer[2] = (byte)(version);
+ buffer[3] = (byte)(version >> 8);
+ try {
+ readStreamHeaderCalled = false;
+ bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
+ fail("Test 3: StreamCorruptedException expected.");
+ bois.close();
+ } catch (StreamCorruptedException e) {
+ }
+ assertTrue("Test 3: readStreamHeader() has not been called.",
+ readStreamHeaderCalled);
+ }
+
+ public void test_readUnsignedByte() throws IOException {
+ oos.writeByte(-1);
+ oos.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertEquals("Test 1: Incorrect unsigned byte written or read.",
+ 255, ois.readUnsignedByte());
+
+ try {
+ ois.readUnsignedByte();
+ fail("Test 2: EOFException expected.");
+ } catch (EOFException e) {
+ // Expected.
+ }
+
+ ois.close();
+ try {
+ ois.readUnsignedByte();
+ fail("Test 3: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ }
+
+ public void test_readUnsignedShort() throws IOException {
+ // Test for method int java.io.ObjectInputStream.readUnsignedShort()
+ oos.writeShort(-1);
+ oos.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ assertEquals("Test 1: Incorrect unsigned short written or read.",
+ 65535, ois.readUnsignedShort());
+
+ try {
+ ois.readUnsignedShort();
+ fail("Test 2: EOFException expected.");
+ } catch (EOFException e) {
+ // Expected.
+ }
+
+ ois.close();
+ try {
+ ois.readUnsignedShort();
+ fail("Test 3: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ }
+
+ public void test_skipBytesI_IOException() throws IOException {
+ oos.writeObject(testString);
+ oos.close();
+
+ Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
+ ois = new ObjectInputStream(sis);
+ sis.throwExceptionOnNextUse = true;
+ try {
+ ois.skipBytes(5);
+ fail("Test 1: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ sis.throwExceptionOnNextUse = false;
+ ois.close();
+ }
+
+ public static class A implements Serializable {
+
+ private static final long serialVersionUID = 11L;
+
+ public String name = "name";
+ }
+
+ public static class B extends A {}
+
+ public static class C extends B {
+
+ private static final long serialVersionUID = 33L;
+ }
+
+ class BasicObjectInputStream extends ObjectInputStream {
+ public BasicObjectInputStream() throws IOException, SecurityException {
+ super();
+ }
+
+ public BasicObjectInputStream(InputStream input) throws IOException {
+ super(input);
+ }
+
+ public boolean enableResolveObject(boolean enable)
+ throws SecurityException {
+ return super.enableResolveObject(enable);
+ }
+
+ public Object readObjectOverride() throws ClassNotFoundException, IOException {
+ return super.readObjectOverride();
+ }
+
+ public void readStreamHeader() throws IOException {
+ readStreamHeaderCalled = true;
+ super.readStreamHeader();
+ }
+
+ public Class<?> resolveProxyClass(String[] interfaceNames)
+ throws IOException, ClassNotFoundException {
+ return super.resolveProxyClass(interfaceNames);
+ }
+ }
+
+ public static class ObjectInputStreamWithReadDesc extends
+ ObjectInputStream {
+ private Class returnClass;
+
+ public ObjectInputStreamWithReadDesc(InputStream is, Class returnClass)
+ throws IOException {
+ super(is);
+ this.returnClass = returnClass;
+ }
+
+ public ObjectStreamClass readClassDescriptor() throws IOException,
+ ClassNotFoundException {
+ return ObjectStreamClass.lookup(returnClass);
+
+ }
+ }
+
+ static class TestClassForSerialization implements Serializable {
+ private static final long serialVersionUID = 1L;
+ }
+
public void test_ConstructorLjava_io_InputStream() throws IOException {
oos.writeDouble(Double.MAX_VALUE);
oos.close();
@@ -207,9 +677,6 @@ public class ObjectInputStreamTest extends TestCase implements
}
- /**
- * java.io.ObjectInputStream#available()
- */
public void test_available() throws IOException {
oos.writeBytes("HelloWorld");
oos.close();
@@ -219,16 +686,6 @@ public class ObjectInputStreamTest extends TestCase implements
}
/**
- * java.io.ObjectInputStream#close()
- */
- public void test_close() throws IOException {
- oos.writeBytes("HelloWorld");
- oos.close();
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- ois.close();
- }
-
- /**
* java.io.ObjectInputStream#defaultReadObject()
*/
public void test_defaultReadObject() throws Exception {
@@ -356,34 +813,6 @@ public class ObjectInputStreamTest extends TestCase implements
}
/**
- * java.io.ObjectInputStream#readFully(byte[])
- */
- public void test_readFully$B() throws IOException {
- byte[] buf = new byte[10];
- oos.writeBytes("HelloWorld");
- oos.close();
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- ois.readFully(buf);
- ois.close();
- assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
- 10, "UTF-8"));
- }
-
- /**
- * java.io.ObjectInputStream#readFully(byte[], int, int)
- */
- public void test_readFully$BII() throws IOException {
- byte[] buf = new byte[10];
- oos.writeBytes("HelloWorld");
- oos.close();
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- ois.readFully(buf, 0, 10);
- ois.close();
- assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
- 10, "UTF-8"));
- }
-
- /**
* java.io.ObjectInputStream#readInt()
*/
public void test_readInt() throws IOException {
@@ -510,36 +939,6 @@ public class ObjectInputStreamTest extends TestCase implements
}
/**
- * java.io.ObjectInputStream#readObjectOverride()
- */
- public void test_readObjectOverride() throws Exception {
- // Regression for HARMONY-846
- assertNull(new ObjectInputStream() {
-
- @Override
- public Object readObjectOverride() throws IOException,
- ClassNotFoundException {
- return super.readObjectOverride();
- }
-
- }.readObjectOverride());
- }
-
- public static class A implements Serializable {
-
- private static final long serialVersionUID = 11L;
-
- public String name = "name";
- }
-
- public static class B extends A {}
-
- public static class C extends B {
-
- private static final long serialVersionUID = 33L;
- }
-
- /**
* java.io.ObjectInputStream#readObject()
*/
public void test_readObjectCorrupt() throws IOException, ClassNotFoundException {
@@ -568,30 +967,6 @@ public class ObjectInputStreamTest extends TestCase implements
}
/**
- * java.io.ObjectInputStream#readUnsignedByte()
- */
- public void test_readUnsignedByte() throws IOException {
- oos.writeByte(-1);
- oos.close();
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- assertEquals("Read incorrect unsignedByte value", 255, ois
- .readUnsignedByte());
- ois.close();
- }
-
- /**
- * java.io.ObjectInputStream#readUnsignedShort()
- */
- public void test_readUnsignedShort() throws IOException {
- oos.writeShort(-1);
- oos.close();
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- assertEquals("Read incorrect unsignedShort value", 65535, ois
- .readUnsignedShort());
- ois.close();
- }
-
- /**
* java.io.ObjectInputStream#readUTF()
*/
public void test_readUTF() throws IOException {
@@ -617,26 +992,27 @@ public class ObjectInputStreamTest extends TestCase implements
// Regression for HARMONY-844
try {
- new ObjectInputStream() {}.skipBytes(0);
+ new ObjectInputStream() {
+ }.skipBytes(0);
fail("NullPointerException expected");
- } catch (NullPointerException e) {}
+ } catch (NullPointerException e) {
+ }
}
// Regression Test for JIRA 2192
- public void test_readObject_withPrimitiveClass() throws Exception {
- File file = new File("test.ser");
- file.deleteOnExit();
- Test test = new Test();
- ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
- file));
- out.writeObject(test);
- out.close();
-
- ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
- Test another = (Test) in.readObject();
- in.close();
- assertEquals(test, another);
- }
+ public void test_readObject_withPrimitiveClass() throws Exception {
+ File file = File.createTempFile("ObjectInputStreamTest", ".ser");
+ Test test = new Test();
+ ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
+ file));
+ out.writeObject(test);
+ out.close();
+
+ ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
+ Test another = (Test) in.readObject();
+ in.close();
+ assertEquals(test, another);
+ }
//Regression Test for JIRA-2249
public static class ObjectOutputStreamWithWriteDesc extends
@@ -652,75 +1028,36 @@ public class ObjectInputStreamTest extends TestCase implements
}
}
- public static class ObjectIutputStreamWithReadDesc extends
+ // Regression Test for JIRA-2340
+ public static class ObjectOutputStreamWithWriteDesc1 extends
+ ObjectOutputStream {
+ public ObjectOutputStreamWithWriteDesc1(OutputStream os)
+ throws IOException {
+ super(os);
+ }
+
+ @Override
+ public void writeClassDescriptor(ObjectStreamClass desc)
+ throws IOException {
+ super.writeClassDescriptor(desc);
+ }
+ }
+
+ public static class ObjectInputStreamWithReadDesc1 extends
ObjectInputStream {
- private Class returnClass;
- public ObjectIutputStreamWithReadDesc(InputStream is, Class returnClass)
+ public ObjectInputStreamWithReadDesc1(InputStream is)
throws IOException {
super(is);
- this.returnClass = returnClass;
}
@Override
public ObjectStreamClass readClassDescriptor() throws IOException,
ClassNotFoundException {
- return ObjectStreamClass.lookup(returnClass);
-
+ return super.readClassDescriptor();
}
}
- static class TestClassForSerialization implements Serializable {
- private static final long serialVersionUID = 1L;
- }
-
- public void test_ClassDescriptor() throws IOException,
- ClassNotFoundException {
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStreamWithWriteDesc oos = new ObjectOutputStreamWithWriteDesc(
- baos);
- oos.writeObject(String.class);
- oos.close();
- Class cls = TestClassForSerialization.class;
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectIutputStreamWithReadDesc ois = new ObjectIutputStreamWithReadDesc(
- bais, cls);
- Object obj = ois.readObject();
- ois.close();
- assertEquals(cls, obj);
- }
-
- // Regression Test for JIRA-2340
- public static class ObjectOutputStreamWithWriteDesc1 extends
- ObjectOutputStream {
- public ObjectOutputStreamWithWriteDesc1(OutputStream os)
- throws IOException {
- super(os);
- }
-
- @Override
- public void writeClassDescriptor(ObjectStreamClass desc)
- throws IOException {
- super.writeClassDescriptor(desc);
- }
- }
-
- public static class ObjectIutputStreamWithReadDesc1 extends
- ObjectInputStream {
-
- public ObjectIutputStreamWithReadDesc1(InputStream is)
- throws IOException {
- super(is);
- }
-
- @Override
- public ObjectStreamClass readClassDescriptor() throws IOException,
- ClassNotFoundException {
- return super.readClassDescriptor();
- }
- }
-
// Regression test for Harmony-1921
public static class ObjectInputStreamWithResolve extends ObjectInputStream {
public ObjectInputStreamWithResolve(InputStream in) throws IOException {
@@ -769,7 +1106,7 @@ public class ObjectInputStreamTest extends TestCase implements
@Override
protected Object resolveObject(Object obj) throws IOException {
- if(obj instanceof Integer){
+ if (obj instanceof Integer) {
obj = intObj;
}
return super.resolveObject(obj);
@@ -792,7 +1129,7 @@ public class ObjectInputStreamTest extends TestCase implements
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStreamWithResolveObject ois =
- new ObjectInputStreamWithResolveObject(bais);
+ new ObjectInputStreamWithResolveObject(bais);
Integer actual = (Integer) ois.readObject();
ois.close();
@@ -800,30 +1137,30 @@ public class ObjectInputStreamTest extends TestCase implements
assertEquals(ObjectInputStreamWithResolveObject.intObj, actual);
}
- public void test_readClassDescriptor() throws IOException,
- ClassNotFoundException {
+ public void test_readClassDescriptor() throws IOException,
+ ClassNotFoundException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStreamWithWriteDesc1 oos = new ObjectOutputStreamWithWriteDesc1(
- baos);
- ObjectStreamClass desc = ObjectStreamClass
- .lookup(TestClassForSerialization.class);
- oos.writeClassDescriptor(desc);
- oos.close();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStreamWithWriteDesc1 oos = new ObjectOutputStreamWithWriteDesc1(
+ baos);
+ ObjectStreamClass desc = ObjectStreamClass
+ .lookup(TestClassForSerialization.class);
+ oos.writeClassDescriptor(desc);
+ oos.close();
byte[] bytes = baos.toByteArray();
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- ObjectIutputStreamWithReadDesc1 ois = new ObjectIutputStreamWithReadDesc1(
- bais);
- Object obj = ois.readClassDescriptor();
- ois.close();
- assertEquals(desc.getClass(), obj.getClass());
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ ObjectInputStreamWithReadDesc1 ois = new ObjectInputStreamWithReadDesc1(
+ bais);
+ Object obj = ois.readClassDescriptor();
+ ois.close();
+ assertEquals(desc.getClass(), obj.getClass());
//eof
bais = new ByteArrayInputStream(bytes);
ExceptionalBufferedInputStream bis = new ExceptionalBufferedInputStream(
bais);
- ois = new ObjectIutputStreamWithReadDesc1(bis);
+ ois = new ObjectInputStreamWithReadDesc1(bis);
bis.setEOF(true);
@@ -838,7 +1175,7 @@ public class ObjectInputStreamTest extends TestCase implements
//throw exception
bais = new ByteArrayInputStream(bytes);
bis = new ExceptionalBufferedInputStream(bais);
- ois = new ObjectIutputStreamWithReadDesc1(bis);
+ ois = new ObjectInputStreamWithReadDesc1(bis);
bis.setException(new IOException());
@@ -853,7 +1190,7 @@ public class ObjectInputStreamTest extends TestCase implements
//corrupt
bais = new ByteArrayInputStream(bytes);
bis = new ExceptionalBufferedInputStream(bais);
- ois = new ObjectIutputStreamWithReadDesc1(bis);
+ ois = new ObjectInputStreamWithReadDesc1(bis);
bis.setCorrupt(true);
@@ -864,7 +1201,7 @@ public class ObjectInputStreamTest extends TestCase implements
} finally {
ois.close();
}
- }
+ }
static class ExceptionalBufferedInputStream extends BufferedInputStream {
private boolean eof = false;
@@ -1000,26 +1337,15 @@ public class ObjectInputStreamTest extends TestCase implements
//Regression Test for HARMONY-3726
public void test_readObject_array() throws Exception {
-
- final String resourcePrefix = ObjectInputStreamTest.class.getPackage().getName().replace('.', '/');
-
-// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/temp/test_array_strings.ser"));
-// TestArray ta = new TestArray(new String[] { "AAA", "BBB" });
-// oos.writeObject(ta);
-// oos.close();
-// oos = new ObjectOutputStream(new FileOutputStream("/temp/test_array_integers.ser"));
-// ta = new TestArray(new Integer[] { 10, 20 });
-// oos.writeObject(ta);
-// oos.close();
-
+ final String resourcePrefix = "serialization/org/apache/harmony/luni/tests/java/io";
ObjectInputStream oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
- "serialization/" + resourcePrefix + "/test_array_strings.ser"));
- TestArray testArray = (TestArray) oin.readObject();
+ resourcePrefix + "/test_array_strings.ser"));
+ org.apache.harmony.luni.tests.java.io.TestArray testArray = (TestArray) oin.readObject();
String[] strings = new String[] { "AAA", "BBB" };
assertTrue(java.util.Arrays.equals(strings, testArray.array));
oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
- "serialization/" + resourcePrefix + "/test_array_integers.ser"));
+ resourcePrefix + "/test_array_integers.ser"));
testArray = (TestArray) oin.readObject();
Integer[] integers = new Integer[] { 10, 20 };
assertTrue(java.util.Arrays.equals(integers, testArray.array));
@@ -1046,7 +1372,8 @@ public class ObjectInputStreamTest extends TestCase implements
@Override
protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException {
- objs[pos++] = osc; }
+ objs[pos++] = osc;
+ }
}
static class TestObjectInputStream extends ObjectInputStream {
@@ -1078,6 +1405,27 @@ public class ObjectInputStreamTest extends TestCase implements
oin.readObject();
}
+ public void test_readObject_replacedClassField() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(out);
+ FieldReplacementTestClass obj = new FieldReplacementTestClass(1234);
+ oos.writeObject(obj);
+ out.flush();
+ out.close();
+
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(in);
+
+ try {
+ FieldReplacementTestClass result =
+ (FieldReplacementTestClass) ois.readObject();
+ fail("should throw ClassCastException");
+ } catch (ClassCastException e) {
+ // expected
+ }
+ ois.close();
+ }
+
/**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
@@ -1087,10 +1435,40 @@ public class ObjectInputStreamTest extends TestCase implements
super.setUp();
oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
}
+
+ public static class FieldReplacementTestClass implements Serializable {
+ private FieldClass c;
+
+ public FieldReplacementTestClass(int i) {
+ super();
+ c = new FieldClass(i);
+ }
+ }
+
+ public static class FieldClass implements Serializable {
+ private int i;
+
+ public FieldClass(int i) {
+ super();
+ this.i = i;
+ }
+
+ protected Object writeReplace() throws ObjectStreamException {
+ return new ReplacementFieldClass(i);
+ }
+ }
+
+ public static class ReplacementFieldClass implements Serializable {
+ private int i;
+
+ public ReplacementFieldClass(int i) {
+ super();
+ this.i = i;
+ }
+ }
}
-class TestArray implements Serializable
-{
+class TestArray implements Serializable {
private static final long serialVersionUID = 1L;
public Object[] array;
@@ -1098,20 +1476,19 @@ class TestArray implements Serializable
public TestArray(Object[] array) {
this.array = array;
}
-
}
class Test implements Serializable {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
- Class classes[] = new Class[] { byte.class, short.class, int.class,
- long.class, boolean.class, char.class, float.class, double.class };
+ Class<?> classes[] = new Class[] { byte.class, short.class, int.class,
+ long.class, boolean.class, char.class, float.class, double.class };
- @Override
+ @Override
public boolean equals(Object o) {
- if (!(o instanceof Test)) {
- return false;
- }
- return Arrays.equals(classes, ((Test) o).classes);
- }
+ if (!(o instanceof Test)) {
+ return false;
+ }
+ return Arrays.equals(classes, ((Test) o).classes);
+ }
}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerFactoryTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerFactoryTest.java
deleted file mode 100644
index 74b2276..0000000
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerFactoryTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package org.apache.harmony.luni.tests.java.net;
-
-import dalvik.annotation.SideEffect;
-
-import junit.framework.TestCase;
-
-import tests.support.Support_Configuration;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.net.ContentHandler;
-import java.net.ContentHandlerFactory;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-
-public class ContentHandlerFactoryTest extends TestCase {
-
- ContentHandlerFactory oldFactory = null;
- Field factoryField = null;
-
- boolean isTestable = false;
-
- boolean isGetContentCalled = false;
- boolean isCreateContentHandlerCalled = false;
-
- @SideEffect("This test affects tests that are run after this one." +
- " The reason are side effects due to caching in URLConnection." +
- " Maybe this test needs to be run in isolation.")
- public void test_createContentHandler() throws IOException {
-
- TestContentHandlerFactory factory = new TestContentHandlerFactory();
-
- if(isTestable) {
-
- assertFalse(isCreateContentHandlerCalled);
-
- URL url = new URL("http://" +
- Support_Configuration.SpecialInetTestAddress);
-
- URLConnection.setContentHandlerFactory(factory);
-
- URLConnection con = url.openConnection();
-
- try {
- con.getContent();
- assertTrue(isCreateContentHandlerCalled);
- assertTrue(isGetContentCalled);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- isGetContentCalled = false;
-
- try {
- con.getContent(new Class[] {});
- assertTrue(isGetContentCalled);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- try {
- con.setContentHandlerFactory(factory);
- fail("java.lang.Error was not thrown.");
- } catch(java.lang.Error e) {
- //expected
- }
-
- try {
- con.setContentHandlerFactory(null);
- fail("java.lang.Error was not thrown.");
- } catch(java.lang.Error e) {
- //expected
- }
-
- } else {
- ContentHandler ch = factory.createContentHandler("text/plain");
- URL url;
- try {
- url = new URL("http://" +
- Support_Configuration.SpecialInetTestAddress);
- assertNotNull(ch.getContent(url.openConnection()));
- } catch (MalformedURLException e) {
- fail("MalformedURLException was thrown: " + e.getMessage());
- } catch (IOException e) {
- fail("IOException was thrown.");
- }
- }
- }
-
- public void setUp() {
- Field [] fields = URLConnection.class.getDeclaredFields();
- int counter = 0;
- for (Field field : fields) {
- if (ContentHandlerFactory.class.equals(field.getType())) {
- counter++;
- factoryField = field;
- }
- }
-
- if(counter == 1) {
-
- isTestable = true;
-
- factoryField.setAccessible(true);
- try {
- oldFactory = (ContentHandlerFactory) factoryField.get(null);
- } catch (IllegalArgumentException e) {
- fail("IllegalArgumentException was thrown during setUp: "
- + e.getMessage());
- } catch (IllegalAccessException e) {
- fail("IllegalAccessException was thrown during setUp: "
- + e.getMessage());
- }
- }
- }
-
- public void tearDown() {
- if(isTestable) {
- try {
- factoryField.set(null, oldFactory);
- } catch (IllegalArgumentException e) {
- fail("IllegalArgumentException was thrown during tearDown: "
- + e.getMessage());
- } catch (IllegalAccessException e) {
- fail("IllegalAccessException was thrown during tearDown: "
- + e.getMessage());
- }
- }
- }
-
- public class TestContentHandler extends ContentHandler {
-
- public Object getContent(URLConnection u) {
- isGetContentCalled = true;
- return null;
- }
- }
-
- public class TestContentHandlerFactory implements ContentHandlerFactory {
-
- public ContentHandler createContentHandler(String mimetype) {
- isCreateContentHandlerCalled = true;
- return new TestContentHandler();
- }
- }
-}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
index d1674f3..5307cf4 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
@@ -16,7 +16,6 @@
package org.apache.harmony.luni.tests.java.net;
-import dalvik.annotation.BrokenTest;
import junit.framework.TestCase;
import tests.support.Support_Configuration;
import tests.support.Support_TestWebData;
@@ -209,10 +208,14 @@ public class URLConnectionTest extends TestCase {
URL url2;
+ URL url3;
+
URLConnection uc;
URLConnection uc2;
+ URLConnection uc3;
+
Support_TestWebServer server;
@Override
@@ -225,6 +228,8 @@ public class URLConnectionTest extends TestCase {
uc = url.openConnection();
url2 = new URL("http://localhost:" + port + "/test2");
uc2 = url2.openConnection();
+ url3 = new URL("http://localhost:" + port + "/test3");
+ uc3 = url3.openConnection();
fileURL = createTempHelloWorldFile();
fileURLCon = fileURL.openConnection();
@@ -239,6 +244,7 @@ public class URLConnectionTest extends TestCase {
server.close();
((HttpURLConnection) uc).disconnect();
((HttpURLConnection) uc2).disconnect();
+ ((HttpURLConnection) uc3).disconnect();
}
/**
@@ -432,39 +438,6 @@ public class URLConnectionTest extends TestCase {
}
/**
- * @throws IOException
- * {@link java.net.URLConnection#getContentEncoding()}
- */
- @BrokenTest("Fails in CTS, passes in CoreTestRunner")
- public void test_getContentEncoding() throws IOException {
- // faulty setup
- try {
-
- fileURLCon.getContentEncoding();
- fail("Exception expected");
- } catch (Throwable e) {
- //ok
- }
-
- // positive case
-
- URL url = new URL("http://www.amazon.com/");
-
- URLConnection con = url.openConnection();
- con.setRequestProperty("Accept-Encoding", "gzip");
- con.connect();
-
- assertEquals(con.getContentEncoding(), "gzip");
-
-
- uc2.setRequestProperty("Accept-Encoding", "bla");
- uc2.connect();
-
- assertNull(uc2.getContentEncoding());
-
- }
-
- /**
* {@link java.net.URLConnection#getContentLength()}
*/
public void test_getContentLength() throws Exception {
@@ -472,8 +445,8 @@ public class URLConnectionTest extends TestCase {
assertEquals(Support_TestWebData.test1.length, uc.getContentLength());
assertEquals(Support_TestWebData.test2.length, uc2.getContentLength());
- assertNotNull(jarURLCon.getContentLength());
- assertNotNull(gifURLCon.getContentLength());
+ assertTrue(jarURLCon.getContentLength() > 0);
+ assertTrue(gifURLCon.getContentLength() > 0);
fileURLCon.getInputStream().close();
}
@@ -719,17 +692,17 @@ public class URLConnectionTest extends TestCase {
}
/**
- * @throws IOException
* {@link java.net.URLConnection#getHeaderFieldInt(String, int)}
*/
public void test_getHeaderFieldInt() throws IOException, ParseException {
- Support_TestWebData params = Support_TestWebData.testParams[1];
+ // Test getHeaderFieldInt() can read an int value.
+ Support_TestWebData params1 = Support_TestWebData.testParams[1];
+ int hf = uc2.getHeaderFieldInt("Content-Length", Integer.MIN_VALUE);
+ assertEquals(params1.testLength, hf);
- int hf = 0;
+ // The remaining fields should be invalid or missing. Confirm the default is returned.
hf = uc2.getHeaderFieldInt("Content-Encoding", Integer.MIN_VALUE);
assertEquals(Integer.MIN_VALUE, hf);
- hf = uc2.getHeaderFieldInt("Content-Length", Integer.MIN_VALUE);
- assertEquals(params.testLength, hf);
hf = uc2.getHeaderFieldInt("Content-Type", Integer.MIN_VALUE);
assertEquals(Integer.MIN_VALUE, hf);
hf = uc2.getHeaderFieldInt("Date", Integer.MIN_VALUE);
@@ -745,6 +718,10 @@ public class URLConnectionTest extends TestCase {
hf = uc2.getHeaderFieldInt("DoesNotExist", Integer.MIN_VALUE);
assertEquals(Integer.MIN_VALUE, hf);
+ // Test getHeaderFieldInt() for a value outside of the range of int.
+ Support_TestWebData params2 = Support_TestWebData.testParams[2];
+ hf = uc3.getHeaderFieldInt("Content-Length", Integer.MIN_VALUE);
+ assertEquals(Integer.MIN_VALUE, hf);
}
/**
@@ -823,34 +800,6 @@ public class URLConnectionTest extends TestCase {
}
}
- /**
- * @throws IOException
- * {@link java.net.URLConnection#getLastModified()}
- */
- public void test_getLastModified() throws IOException {
-
- URL url4 = new URL(Support_Configuration.hTTPURLwLastModified);
- URLConnection uc4 = url4.openConnection();
-
- uc4.connect();
-
- if (uc4.getLastModified() == 0) {
- System.out
- .println("WARNING: Server does not support 'Last-Modified', test_getLastModified() not run");
- return;
- }
-
- long millis = uc4.getHeaderFieldDate("Last-Modified", 0);
-
- assertEquals(
- "Returned wrong getLastModified value. Wanted: "
- + " got: " + uc4.getLastModified(),
- millis, uc4.getLastModified());
-
-
- ((HttpURLConnection) uc).disconnect();
- }
-
public void test_getOutputStream_failAfterDisconnect() throws IOException {
((HttpURLConnection) uc2).disconnect();
@@ -1253,7 +1202,7 @@ public class URLConnectionTest extends TestCase {
String cts = System.getProperty("java.io.tmpdir");
File tmpDir = new File(cts);
Support_Resources.copyFile(tmpDir, null, "Harmony.GIF");
- URL fUrl1 = new URL("file:/" + tmpDir.getPath()
+ URL fUrl1 = new URL("file://" + tmpDir.getPath()
+ "/Harmony.GIF");
URLConnection con1 = fUrl1.openConnection();
return con1;
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
index a158c83..6b93abe 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
@@ -228,9 +228,6 @@ public class KeyStoreTest extends TestCase {
}
}
- /**
- * @test java.security.KeyStore.PasswordProtection.getPassword()
- */
public void testKeyStorePPGetPassword() {
// Regression for HARMONY-1539
// no exception expected
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java
index bef27ba..f939730 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java
@@ -124,13 +124,6 @@ public class ProviderServiceTest extends TestCase {
Object o = s.newInstance(null);
assertTrue("incorrect instance", o instanceof RandomImpl);
-
- try {
- o = s.newInstance(new Object());
- fail("No expected NoSuchAlgorithmException");
- } catch (NoSuchAlgorithmException e) {
- }
-
}
public void testGetAlgorithm() {
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
index 7886e3e..ad084e1 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
@@ -68,7 +68,17 @@ public class Signature2Test extends junit.framework.TestCase {
* java.security.Signature#clone()
*/
public void test_clone() throws Exception {
+ // A Signature may be cloneable according to the API, in practice the implementation isn't
+ // once it has been initialized. Checking for runtime exceptions rather than useful
+ // behavior.
Signature s = Signature.getInstance("DSA");
+ Signature clone = (Signature) s.clone();
+ assertNotNull(clone);
+ assertEquals(s.getAlgorithm(), clone.getAlgorithm());
+ assertEquals(s.getProvider(), clone.getProvider());
+
+ KeyPair keyPair = getDsaKeys();
+ s.initSign(keyPair.getPrivate());
try {
s.clone();
fail();
diff --git a/luni/src/test/java/tests/api/java/io/ComputeSerialVersionUIDTest.java b/luni/src/test/java/tests/api/java/io/ComputeSerialVersionUIDTest.java
deleted file mode 100644
index 458c27f..0000000
--- a/luni/src/test/java/tests/api/java/io/ComputeSerialVersionUIDTest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package tests.api.java.io;
-
-import java.io.ObjectInputStream;
-
-public class ComputeSerialVersionUIDTest extends junit.framework.TestCase {
-
-
- private String path = "/serialization/tests/api/java/io/";
-
- public void testComputeSUIDClass() throws Exception {
- ObjectInputStream ois = new ObjectInputStream(getClass()
- .getResourceAsStream(path + "testComputeSUIDClass.ser"));
- SerializationTestClass.TestClassName1 o1 = (SerializationTestClass.TestClassName1) ois
- .readObject();
- SerializationTestClass.TestClassName2T_T$T o2 = (SerializationTestClass.TestClassName2T_T$T) ois
- .readObject();
- SerializationTestClass.TestClassModifierPublic o6 = (SerializationTestClass.TestClassModifierPublic) ois
- .readObject();
- SerializationTestClass.TestClassModifierAbstract o3 = (SerializationTestClass.TestClassModifierAbstract) ois
- .readObject();
- SerializationTestClass.TestClassModifierFinal o4 = (SerializationTestClass.TestClassModifierFinal) ois
- .readObject();
- SerializationTestClass.TestClassModifierInterface o5 = (SerializationTestClass.TestClassModifierInterface) ois
- .readObject();
- ois.close();
- }
-
- public void testComputeSUIDInterfaces() throws Exception {
- ObjectInputStream ois = new ObjectInputStream(getClass()
- .getResourceAsStream(path + "testComputeSUIDInterfaces.ser"));
- SerializationTestClass.TestIntefaces o1 = (SerializationTestClass.TestIntefaces) ois
- .readObject();
- SerializationTestClass.TestIntefacesA o2 = (SerializationTestClass.TestIntefacesA) ois
- .readObject();
- SerializationTestClass.TestIntefacesAB o3 = (SerializationTestClass.TestIntefacesAB) ois
- .readObject();
- SerializationTestClass.TestIntefacesBA o4 = (SerializationTestClass.TestIntefacesBA) ois
- .readObject();
- SerializationTestClass.TestIntefacesC o5 = (SerializationTestClass.TestIntefacesC) ois
- .readObject();
- SerializationTestClass.TestIntefacesAC o6 = (SerializationTestClass.TestIntefacesAC) ois
- .readObject();
- SerializationTestClass.TestIntefacesCA o7 = (SerializationTestClass.TestIntefacesCA) ois
- .readObject();
- SerializationTestClass.TestIntefacesABC o8 = (SerializationTestClass.TestIntefacesABC) ois
- .readObject();
- SerializationTestClass.TestIntefacesACB o9 = (SerializationTestClass.TestIntefacesACB) ois
- .readObject();
- SerializationTestClass.TestIntefacesBAC o10 = (SerializationTestClass.TestIntefacesBAC) ois
- .readObject();
- SerializationTestClass.TestIntefacesBCA o11 = (SerializationTestClass.TestIntefacesBCA) ois
- .readObject();
- SerializationTestClass.TestIntefacesCAB o12 = (SerializationTestClass.TestIntefacesCAB) ois
- .readObject();
- SerializationTestClass.TestIntefacesCBA o13 = (SerializationTestClass.TestIntefacesCBA) ois
- .readObject();
- ois.close();
- }
-
- public void testComputeSUIDFields() throws Exception {
- ObjectInputStream ois = new ObjectInputStream(getClass()
- .getResourceAsStream(path + "testComputeSUIDFields.ser"));
- SerializationTestClass.TestFieldsNone o1 = (SerializationTestClass.TestFieldsNone) ois
- .readObject();
- SerializationTestClass.TestFieldsOneFinal o2 = (SerializationTestClass.TestFieldsOneFinal) ois
- .readObject();
- SerializationTestClass.TestFieldsTwoFinal o3 = (SerializationTestClass.TestFieldsTwoFinal) ois
- .readObject();
- SerializationTestClass.TestFieldsOnePrivate o4 = (SerializationTestClass.TestFieldsOnePrivate) ois
- .readObject();
- SerializationTestClass.TestFieldsTwoPrivate o5 = (SerializationTestClass.TestFieldsTwoPrivate) ois
- .readObject();
- SerializationTestClass.TestFieldsOneProtected o6 = (SerializationTestClass.TestFieldsOneProtected) ois
- .readObject();
- SerializationTestClass.TestFieldsTwoProtected o7 = (SerializationTestClass.TestFieldsTwoProtected) ois
- .readObject();
- SerializationTestClass.TestFieldsOnePublic o8 = (SerializationTestClass.TestFieldsOnePublic) ois
- .readObject();
- SerializationTestClass.TestFieldsTwoPublic o9 = (SerializationTestClass.TestFieldsTwoPublic) ois
- .readObject();
- SerializationTestClass.TestFieldsOneStatic o10 = (SerializationTestClass.TestFieldsOneStatic) ois
- .readObject();
- SerializationTestClass.TestFieldsTwoStatic o11 = (SerializationTestClass.TestFieldsTwoStatic) ois
- .readObject();
- SerializationTestClass.TestFieldsOneTransient o12 = (SerializationTestClass.TestFieldsOneTransient) ois
- .readObject();
- SerializationTestClass.TestFieldsTwoTransient o13 = (SerializationTestClass.TestFieldsTwoTransient) ois
- .readObject();
- SerializationTestClass.TestFieldsOneVolatile o14 = (SerializationTestClass.TestFieldsOneVolatile) ois
- .readObject();
- SerializationTestClass.TestFieldsTwoVolatile o15 = (SerializationTestClass.TestFieldsTwoVolatile) ois
- .readObject();
- SerializationTestClass.TestFieldSignatures o16 = (SerializationTestClass.TestFieldSignatures) ois
- .readObject();
- ois.close();
- }
-
- public void testComputeSUIDConstructors() throws Exception {
- ObjectInputStream ois = new ObjectInputStream(getClass()
- .getResourceAsStream(path + "testComputeSUIDConstructors.ser"));
- SerializationTestClass.TestConstructorNone o1 = (SerializationTestClass.TestConstructorNone) ois
- .readObject();
- SerializationTestClass.TestConstructorOne o2 = (SerializationTestClass.TestConstructorOne) ois
- .readObject();
- SerializationTestClass.TestConstructorPrivate o3 = (SerializationTestClass.TestConstructorPrivate) ois
- .readObject();
- SerializationTestClass.TestConstructorProtected o4 = (SerializationTestClass.TestConstructorProtected) ois
- .readObject();
- SerializationTestClass.TestConstructorPublic o5 = (SerializationTestClass.TestConstructorPublic) ois
- .readObject();
- SerializationTestClass.TestConstructorSignature o6 = (SerializationTestClass.TestConstructorSignature) ois
- .readObject();
- SerializationTestClass.TestConstructorTwo o7 = (SerializationTestClass.TestConstructorTwo) ois
- .readObject();
- SerializationTestClass.TestConstructorTwoReverse o8 = (SerializationTestClass.TestConstructorTwoReverse) ois
- .readObject();
- ois.close();
- }
-
- public void testComputeSUIDMethods() throws Exception {
- ObjectInputStream ois = new ObjectInputStream(getClass()
- .getResourceAsStream(path + "testComputeSUIDMethods.ser"));
- SerializationTestClass.TestMehodPrivate o1 = (SerializationTestClass.TestMehodPrivate) ois
- .readObject();
- SerializationTestClass.TestMethodAbstract o2 = (SerializationTestClass.TestMethodAbstract) ois
- .readObject();
- SerializationTestClass.TestMethodFinal o3 = (SerializationTestClass.TestMethodFinal) ois
- .readObject();
- SerializationTestClass.TestMethodNative o4 = (SerializationTestClass.TestMethodNative) ois
- .readObject();
- SerializationTestClass.TestMethodProtected o5 = (SerializationTestClass.TestMethodProtected) ois
- .readObject();
- SerializationTestClass.TestMethodPublic o6 = (SerializationTestClass.TestMethodPublic) ois
- .readObject();
- SerializationTestClass.TestMethodStatic o7 = (SerializationTestClass.TestMethodStatic) ois
- .readObject();
- SerializationTestClass.TestMethodSignature o9 = (SerializationTestClass.TestMethodSignature) ois
- .readObject();
- SerializationTestClass.TestMethodReturnSignature o10 = (SerializationTestClass.TestMethodReturnSignature) ois
- .readObject();
- SerializationTestClass.TestMethodSynchronized o8 = (SerializationTestClass.TestMethodSynchronized) ois
- .readObject();
- ois.close();
- }
-}
diff --git a/luni/src/test/java/tests/api/java/io/ObjectInputStreamTest.java b/luni/src/test/java/tests/api/java/io/ObjectInputStreamTest.java
deleted file mode 100644
index 434d31c..0000000
--- a/luni/src/test/java/tests/api/java/io/ObjectInputStreamTest.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.io;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamClass;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.io.StreamCorruptedException;
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.Vector;
-import org.apache.harmony.testframework.serialization.SerializationTest;
-import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
-import tests.support.Support_ASimpleInputStream;
-
-public class ObjectInputStreamTest extends junit.framework.TestCase implements
- Serializable {
-
- static final long serialVersionUID = 1L;
-
- ObjectInputStream ois;
-
- ObjectOutputStream oos;
-
- ByteArrayOutputStream bao;
-
- boolean readStreamHeaderCalled;
-
- private final String testString = "Lorem ipsum...";
-
- private final int testLength = testString.length();
-
- public void test_ConstructorLjava_io_InputStream_IOException() throws IOException {
- oos.writeObject(testString);
- oos.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- sis.throwExceptionOnNextUse = true;
- try {
- ois = new ObjectInputStream(sis);
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- }
-
- public void test_ClassDescriptor() throws IOException,
- ClassNotFoundException {
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStreamWithWriteDesc oos = new ObjectOutputStreamWithWriteDesc(
- baos);
- oos.writeObject(String.class);
- oos.close();
- Class<?> cls = TestClassForSerialization.class;
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectInputStreamWithReadDesc ois = new ObjectInputStreamWithReadDesc(
- bais, cls);
- Object obj = ois.readObject();
- ois.close();
- assertEquals(cls, obj);
- }
-
- public void test_available() throws IOException {
- // Test for method int java.io.ObjectInputStream.available()
- oos.writeBytes(testString);
- oos.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- assertEquals("Test 1: Incorrect number of bytes;", testLength, ois.available());
- ois.close();
- }
-
- public void test_available_IOException() throws IOException {
- oos.writeObject(testString);
- oos.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- sis.throwExceptionOnNextUse = true;
- try {
- ois.available();
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- ois.close();
- }
-
- public void test_close() throws Exception {
- // Test for method void java.io.ObjectInputStream.close()
- oos.writeObject(testString);
- oos.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- sis.throwExceptionOnNextUse = true;
- try {
- ois.close();
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- ois.close();
- }
-
- public void test_enableResolveObjectB() throws IOException {
- // Start testing without a SecurityManager.
- BasicObjectInputStream bois = new BasicObjectInputStream();
- assertFalse("Test 1: Object resolving must be disabled by default.",
- bois.enableResolveObject(true));
-
- assertTrue("Test 2: enableResolveObject did not return the previous value.",
- bois.enableResolveObject(false));
- }
-
- public void test_read_IOException() throws IOException {
- oos.writeObject(testString);
- oos.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- sis.throwExceptionOnNextUse = true;
- try {
- ois.read();
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- ois.close();
- }
-
- public void test_read$BII() throws IOException {
- // Test for method int java.io.ObjectInputStream.read(byte [], int, int)
- byte[] buf = new byte[testLength];
- oos.writeBytes(testString);
- oos.close();
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- ois.read(buf, 0, testLength);
- ois.close();
- assertEquals("Read incorrect bytes", testString, new String(buf));
- }
-
- public void test_read$BII_Exception() throws IOException {
- byte[] buf = new byte[testLength];
- oos.writeObject(testString);
- oos.close();
-
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- try {
- ois.read(buf, 0, -1);
- fail("IndexOutOfBoundsException was not thrown.");
- } catch (IndexOutOfBoundsException e) {
- // Expected
- }
- try {
- ois.read(buf, -1,1);
- fail("IndexOutOfBoundsException was not thrown.");
- } catch (IndexOutOfBoundsException e) {
- // Expected
- }
- try {
- ois.read(buf, testLength, 1);
- fail("IndexOutOfBoundsException was not thrown.");
- } catch (IndexOutOfBoundsException e) {
- // Expected
- }
- ois.close();
-
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- sis.throwExceptionOnNextUse = true;
- try {
- ois.read(buf, 0, testLength);
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- ois.close();
- }
-
- public void test_readFully$B() throws IOException {
- byte[] buf = new byte[testLength];
- oos.writeBytes(testString);
- oos.close();
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- ois.readFully(buf);
- assertEquals("Test 1: Incorrect bytes read;",
- testString, new String(buf));
- ois.close();
-
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- ois.read();
- try {
- ois.readFully(buf);
- fail("Test 2: EOFException expected.");
- } catch (EOFException e) {
- // Expected.
- }
- }
-
- public void test_readFully$B_Exception() throws IOException {
- byte[] buf = new byte[testLength];
- oos.writeObject(testString);
- oos.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- sis.throwExceptionOnNextUse = true;
- try {
- ois.readFully(buf);
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- ois.close();
- }
-
- public void test_readFully$BII() throws IOException {
- // Test for method void java.io.ObjectInputStream.readFully(byte [],
- // int, int)
- byte[] buf = new byte[testLength];
- oos.writeBytes(testString);
- oos.close();
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- ois.readFully(buf, 0, testLength);
- assertEquals("Read incorrect bytes", testString, new String(buf));
- ois.close();
-
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- ois.read();
- try {
- ois.readFully(buf);
- fail("Test 2: EOFException expected.");
- } catch (EOFException e) {
- // Expected.
- }
- }
-
- public void test_readFully$BII_Exception() throws IOException {
- byte[] buf = new byte[testLength];
- oos.writeObject(testString);
- oos.close();
-
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- try {
- ois.readFully(buf, 0, -1);
- fail("IndexOutOfBoundsException was not thrown.");
- } catch (IndexOutOfBoundsException e) {
- // Expected
- }
- try {
- ois.readFully(buf, -1,1);
- fail("IndexOutOfBoundsException was not thrown.");
- } catch (IndexOutOfBoundsException e) {
- // Expected
- }
- try {
- ois.readFully(buf, testLength, 1);
- fail("IndexOutOfBoundsException was not thrown.");
- } catch (IndexOutOfBoundsException e) {
- // Expected
- }
- ois.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- sis.throwExceptionOnNextUse = true;
- try {
- ois.readFully(buf, 0, 1);
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- ois.close();
- }
-
- @SuppressWarnings("deprecation")
- public void test_readLine() throws IOException {
- String line;
- oos.writeBytes("Lorem\nipsum\rdolor sit amet...");
- oos.close();
-
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- line = ois.readLine();
- assertTrue("Test 1: Incorrect line written or read: " + line,
- line.equals("Lorem"));
- line = ois.readLine();
- assertTrue("Test 2: Incorrect line written or read: " + line,
- line.equals("ipsum"));
- line = ois.readLine();
- assertTrue("Test 3: Incorrect line written or read: " + line,
- line.equals("dolor sit amet..."));
- ois.close();
- }
-
- public void test_readLine_IOException() throws IOException {
- oos.writeObject(testString);
- oos.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- sis.throwExceptionOnNextUse = true;
- try {
- ois.readLine();
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- ois.close();
- }
-
- private void fillStreamHeader(byte[] buffer) {
- short magic = java.io.ObjectStreamConstants.STREAM_MAGIC;
- short version = java.io.ObjectStreamConstants.STREAM_VERSION;
-
- if (buffer.length < 4) {
- throw new IllegalArgumentException("The buffer's minimal length must be 4.");
- }
-
- // Initialize the buffer with the correct header for object streams
- buffer[0] = (byte) (magic >> 8);
- buffer[1] = (byte) magic;
- buffer[2] = (byte) (version >> 8);
- buffer[3] = (byte) (version);
- }
-
- public void test_readObjectOverride() throws Exception {
- byte[] buffer = new byte[4];
-
- // Initialize the buffer with the correct header for object streams
- fillStreamHeader(buffer);
-
- // Test 1: Check that readObjectOverride() returns null if there
- // is no input stream.
- BasicObjectInputStream bois = new BasicObjectInputStream();
- assertNull("Test 1:", bois.readObjectOverride());
-
- // Test 2: Check that readObjectOverride() throws an IOException
- // if there is an input stream.
- bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
- try {
- bois.readObjectOverride();
- fail("Test 2: IOException expected.");
- } catch (IOException e) {}
-
- bois.close();
- }
-
- public void test_readObjectMissingClasses() throws Exception {
- SerializationTest.verifySelf(new A1(), new SerializableAssert() {
- public void assertDeserialized(Serializable initial,
- Serializable deserialized) {
- assertEquals(5, ((A1) deserialized).b1.i);
- }
- });
- }
-
- public void test_readObjectCorrupt() {
- byte[] bytes = { 00, 00, 00, 0x64, 0x43, 0x48, (byte) 0xFD, 0x71, 00,
- 00, 0x0B, (byte) 0xB8, 0x4D, 0x65 };
- ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
- boolean exception = false;
- try {
- ObjectInputStream in = new ObjectInputStream(bin);
- in.readObject();
- fail("Unexpected read of corrupted stream");
- } catch (StreamCorruptedException e) {
- exception = true;
- } catch (IOException e) {
- fail("Unexpected: " + e);
- } catch (ClassNotFoundException e) {
- fail("Unexpected: " + e);
- }
- assertTrue("Expected StreamCorruptedException", exception);
- }
-
- public void test_readStreamHeader() throws IOException {
- String testString = "Lorem ipsum";
- BasicObjectInputStream bois;
- short magic = java.io.ObjectStreamConstants.STREAM_MAGIC;
- short version = java.io.ObjectStreamConstants.STREAM_VERSION;
- byte[] buffer = new byte[20];
-
- // Initialize the buffer with the correct header for object streams
- fillStreamHeader(buffer);
- System.arraycopy(testString.getBytes(), 0, buffer, 4, testString.length());
-
- // Test 1: readStreamHeader should not throw a StreamCorruptedException.
- // It should get called by the ObjectInputStream constructor.
- try {
- readStreamHeaderCalled = false;
- bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
- bois.close();
- } catch (StreamCorruptedException e) {
- fail("Test 1: Unexpected StreamCorruptedException.");
- }
- assertTrue("Test 1: readStreamHeader() has not been called.",
- readStreamHeaderCalled);
-
- // Test 2: Make the stream magic number invalid and check that
- // readStreamHeader() throws an exception.
- buffer[0] = (byte)magic;
- buffer[1] = (byte)(magic >> 8);
- try {
- readStreamHeaderCalled = false;
- bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
- fail("Test 2: StreamCorruptedException expected.");
- bois.close();
- } catch (StreamCorruptedException e) {
- }
- assertTrue("Test 2: readStreamHeader() has not been called.",
- readStreamHeaderCalled);
-
- // Test 3: Make the stream version invalid and check that
- // readStreamHeader() throws an exception.
- buffer[0] = (byte)(magic >> 8);
- buffer[1] = (byte)magic;
- buffer[2] = (byte)(version);
- buffer[3] = (byte)(version >> 8);
- try {
- readStreamHeaderCalled = false;
- bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
- fail("Test 3: StreamCorruptedException expected.");
- bois.close();
- } catch (StreamCorruptedException e) {
- }
- assertTrue("Test 3: readStreamHeader() has not been called.",
- readStreamHeaderCalled);
- }
-
- public void test_readUnsignedByte() throws IOException {
- oos.writeByte(-1);
- oos.close();
-
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- assertEquals("Test 1: Incorrect unsigned byte written or read.",
- 255, ois.readUnsignedByte());
-
- try {
- ois.readUnsignedByte();
- fail("Test 2: EOFException expected.");
- } catch (EOFException e) {
- // Expected.
- }
-
- ois.close();
- try {
- ois.readUnsignedByte();
- fail("Test 3: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- }
-
- public void test_readUnsignedShort() throws IOException {
- // Test for method int java.io.ObjectInputStream.readUnsignedShort()
- oos.writeShort(-1);
- oos.close();
-
- ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
- assertEquals("Test 1: Incorrect unsigned short written or read.",
- 65535, ois.readUnsignedShort());
-
- try {
- ois.readUnsignedShort();
- fail("Test 2: EOFException expected.");
- } catch (EOFException e) {
- // Expected.
- }
-
- ois.close();
- try {
- ois.readUnsignedShort();
- fail("Test 3: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- }
-
- public void test_resolveProxyClass() throws IOException {
- BasicObjectInputStream bois;
- byte[] buffer = new byte[10];
-
- // Initialize the buffer with the header for object streams
- fillStreamHeader(buffer);
- bois = new BasicObjectInputStream(new ByteArrayInputStream(buffer));
-
- // Test 1: Check that a NullPointerException is thrown
- // if null is passed to the method.
- try {
- bois.resolveProxyClass(null);
- fail("Test 1: NullPointerException expected.");
- }
- catch (NullPointerException npe) {
- }
- catch (ClassNotFoundException cnfe) {
- fail("Test 1: Unexpected ClassNotFoundException.");
- }
-
- // Test 2: Check that visible interfaces are found.
- try {
- String[] interfaces = { "java.io.Closeable",
- "java.lang.Cloneable" };
- bois.resolveProxyClass(interfaces);
- }
- catch (ClassNotFoundException cnfe) {
- fail("Test 2: Unexpected ClassNotFoundException.");
- }
-
- // Test 3: Check that a ClassNotFoundException is thrown if the
- // array of interfaces is not valid.
- try {
- String[] interfaces = { "java.io.Closeable",
- "java.io.Closeable" };
- bois.resolveProxyClass(interfaces);
- fail ("Test 3: ClassNotFoundException expected.");
- }
- catch (ClassNotFoundException cnfe) {
- }
-
- bois.close();
- }
-
- public void test_skipBytesI_IOException() throws IOException {
- oos.writeObject(testString);
- oos.close();
-
- Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
- ois = new ObjectInputStream(sis);
- sis.throwExceptionOnNextUse = true;
- try {
- ois.skipBytes(5);
- fail("Test 1: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
- sis.throwExceptionOnNextUse = false;
- ois.close();
- }
-
- public static class A implements Serializable {
-
- private static final long serialVersionUID = 11L;
-
- public String name = "name";
- }
-
- public static class B extends A {}
-
- public static class C extends B {
-
- private static final long serialVersionUID = 33L;
- }
-
- public static class A1 implements Serializable {
-
- static final long serialVersionUID = 5942584913446079661L;
-
- B1 b1 = new B1();
-
- B1 b2 = b1;
-
- Vector v = new Vector();
- }
-
- public static class B1 implements Serializable {
-
- int i = 5;
-
- Hashtable h = new Hashtable();
- }
-
- class BasicObjectInputStream extends ObjectInputStream {
- public BasicObjectInputStream() throws IOException, SecurityException {
- super();
- }
-
- public BasicObjectInputStream(InputStream input) throws IOException {
- super(input);
- }
-
- public boolean enableResolveObject(boolean enable)
- throws SecurityException {
- return super.enableResolveObject(enable);
- }
-
- public Object readObjectOverride() throws ClassNotFoundException, IOException {
- return super.readObjectOverride();
- }
-
- public void readStreamHeader() throws IOException {
- readStreamHeaderCalled = true;
- super.readStreamHeader();
- }
-
- public Class<?> resolveProxyClass(String[] interfaceNames)
- throws IOException, ClassNotFoundException {
- return super.resolveProxyClass(interfaceNames);
- }
- }
-
- //Regression Test for JIRA-2249
- public static class ObjectOutputStreamWithWriteDesc extends
- ObjectOutputStream {
- public ObjectOutputStreamWithWriteDesc(OutputStream os)
- throws IOException {
- super(os);
- }
-
- public void writeClassDescriptor(ObjectStreamClass desc)
- throws IOException {
- }
- }
-
- public static class ObjectInputStreamWithReadDesc extends
- ObjectInputStream {
- private Class returnClass;
-
- public ObjectInputStreamWithReadDesc(InputStream is, Class returnClass)
- throws IOException {
- super(is);
- this.returnClass = returnClass;
- }
-
- public ObjectStreamClass readClassDescriptor() throws IOException,
- ClassNotFoundException {
- return ObjectStreamClass.lookup(returnClass);
-
- }
- }
-
- static class TestClassForSerialization implements Serializable {
- private static final long serialVersionUID = 1L;
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
- }
-}
-
-class Test implements Serializable {
- private static final long serialVersionUID = 1L;
-
- Class<?> classes[] = new Class[] { byte.class, short.class, int.class,
- long.class, boolean.class, char.class, float.class, double.class };
-
- public boolean equals(Object o) {
- if (!(o instanceof Test)) {
- return false;
- }
- return Arrays.equals(classes, ((Test) o).classes);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/io/SerializationTestClass.java b/luni/src/test/java/tests/api/java/io/SerializationTestClass.java
deleted file mode 100644
index 32c4d0b..0000000
--- a/luni/src/test/java/tests/api/java/io/SerializationTestClass.java
+++ /dev/null
@@ -1,335 +0,0 @@
-package tests.api.java.io;
-
-public class SerializationTestClass implements java.io.Serializable {
-
- // Test class names
- public class TestClassName1 implements java.io.Serializable {
- }
-
- public class TestClassName2T_T$T implements java.io.Serializable {
- }
-
- // Test Modifiers
- public class TestClassModifierPublic implements java.io.Serializable {
- }
-
- interface TestClassModifierInterfaceHelper extends java.io.Serializable {
- }
-
- public class TestClassModifierInterface implements
- TestClassModifierInterfaceHelper {
- }
-
- final class TestClassModifierFinal implements java.io.Serializable {
- }
-
- abstract class TestClassModifierAbstractHelper implements
- java.io.Serializable {
- }
-
- public class TestClassModifierAbstract extends
- TestClassModifierAbstractHelper {
- }
-
-
- // TODO Arrays always are abstract
-
- // TODO Non public interface has no abstract modifier
-
-
- // Test interfaces
- interface A extends java.io.Serializable {
- }
-
- interface B extends java.io.Serializable {
- }
-
- interface C extends A {
- }
-
- public class TestIntefaces implements java.io.Serializable {
- }
-
- public class TestIntefacesA implements A {
- }
-
- public class TestIntefacesAB implements A, B {
- }
-
- public class TestIntefacesBA implements B, A {
- }
-
- public class TestIntefacesC implements C {
- }
-
- public class TestIntefacesAC implements A, C {
- }
-
- public class TestIntefacesCA implements C, A {
- }
-
- public class TestIntefacesABC implements A, B, C {
- }
-
- public class TestIntefacesACB implements A, C, B {
- }
-
- public class TestIntefacesBAC implements B, A, C {
- }
-
- public class TestIntefacesBCA implements B, C, A {
- }
-
- public class TestIntefacesCAB implements C, A, B {
- }
-
- public class TestIntefacesCBA implements C, B, A {
- }
-
- /**
- * Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.STATIC |
- * Modifier.FINAL | Modifier.VOLATILE | Modifier.TRANSIENT
- */
- // Test Fields
- public class TestFieldsNone implements java.io.Serializable {
- }
-
- public class TestFieldsOnePublic implements java.io.Serializable {
- public int one;
- }
-
- public class TestFieldsTwoPublic implements java.io.Serializable {
- public int one;
- public int two;
- }
-
- @SuppressWarnings("unused")
- public class TestFieldsOnePrivate implements java.io.Serializable {
- private int one;
- }
-
- @SuppressWarnings("unused")
- public class TestFieldsTwoPrivate implements java.io.Serializable {
- private int one;
- private int two;
- }
-
- public class TestFieldsOneProtected implements java.io.Serializable {
- protected int one;
- }
-
- public class TestFieldsTwoProtected implements java.io.Serializable {
- protected int one;
- protected int two;
- }
-
- public static class TestFieldsOneStatic implements java.io.Serializable {
- static int one;
- }
-
- public static class TestFieldsTwoStatic implements java.io.Serializable {
- static int one;
- static int two;
- }
-
- public class TestFieldsOneFinal implements java.io.Serializable {
- final int one = 0;
- }
-
- public class TestFieldsTwoFinal implements java.io.Serializable {
- final int one = 0;
- final int two = 0;
- }
-
- public class TestFieldsOneVolatile implements java.io.Serializable {
- volatile int one;
- }
-
- public class TestFieldsTwoVolatile implements java.io.Serializable {
- volatile int one;
- volatile int two;
- }
-
- public class TestFieldsOneTransient implements java.io.Serializable {
- transient int one;
- }
-
- public class TestFieldsTwoTransient implements java.io.Serializable {
- transient int one;
- transient int two;
- }
-
- public class TestFieldSignatures implements java.io.Serializable {
- Object l;
- int i;
- short s;
- long j;
- boolean z;
- char c;
- double d;
- float f;
- byte b;
- }
-
-
- // Test Constructors
- public class TestConstructorNone implements java.io.Serializable {
- }
-
- public class TestConstructorOne implements java.io.Serializable {
- public TestConstructorOne() {
- }
- }
-
- public class TestConstructorTwo implements java.io.Serializable {
- public TestConstructorTwo(byte b) {
- }
-
- public TestConstructorTwo(char c) {
- }
- }
-
- public class TestConstructorTwoReverse implements java.io.Serializable {
- public TestConstructorTwoReverse(char c) {
- }
-
- public TestConstructorTwoReverse(byte b) {
- }
- }
-
-
- // Test Constructor Modifiers
- public class TestConstructorPublic implements java.io.Serializable {
- public TestConstructorPublic() {
- }
- }
-
- public class TestConstructorPrivate implements java.io.Serializable {
- private TestConstructorPrivate() {
- }
-
- public TestConstructorPrivate(int i) {
- this();
- }
- }
-
- public class TestConstructorProtected implements java.io.Serializable {
- protected TestConstructorProtected() {
- }
- }
- // TODO constructor modifier strict?
- // TODO constructor modifier static?
- // TODO constructor modifier final?
- // TODO constructor modifier synchronized?
- // TODO constructor modifier native?
- // TODO constructor modifier abstract?
-
-
- // Test constructor signature
- public class TestConstructorSignature implements java.io.Serializable {
- public TestConstructorSignature(boolean z, byte b, char c, short s,
- int i, float f, double j, Object l) {
- }
- }
-
-
- // Test Method Modifiers
- public class TestMethodPublic implements java.io.Serializable {
- public void method() {
- }
- }
-
- @SuppressWarnings("unused")
- public class TestMehodPrivate implements java.io.Serializable {
- private void method() {
- }
- }
-
- public class TestMethodProtected implements java.io.Serializable {
- protected void method() {
- }
- }
-
- public class TestMethodStrict implements java.io.Serializable {
- strictfp void method() {
- }
- }
-
- public static class TestMethodStatic implements java.io.Serializable {
- static void method() {
- }
- }
-
- public class TestMethodFinal implements java.io.Serializable {
- final void method() {
- }
- }
-
- public class TestMethodSynchronized implements java.io.Serializable {
- synchronized void method() {
- }
- }
-
- public class TestMethodNative implements java.io.Serializable {
- native void method();
- }
-
- public abstract class TestMethodAbstractHelper implements
- java.io.Serializable {
- abstract void method();
- }
-
- public class TestMethodAbstract extends TestMethodAbstractHelper implements
- java.io.Serializable {
- @Override
- void method() {
- }
- }
-
-
- // Test method signature
- public class TestMethodSignature implements java.io.Serializable {
- public void method(boolean z, byte b, char c, short s, int i, float f,
- double j, Object l) {
- }
- }
-
-
- // Test method return signature
- public class TestMethodReturnSignature implements java.io.Serializable {
- public void methodV() {
- }
-
- public boolean methodZ() {
- return false;
- }
-
- public byte methodB() {
- return 0;
- }
-
- public char methodC() {
- return '0';
- }
-
- public short methodS() {
- return 0;
- }
-
- public int methodI() {
- return 0;
- }
-
- public float methodF() {
- return 0F;
- }
-
- public double methodD() {
- return 0D;
- }
-
- public Object methodL() {
- return null;
- }
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/Process2Test.java b/luni/src/test/java/tests/api/java/lang/Process2Test.java
deleted file mode 100644
index 5d18d61..0000000
--- a/luni/src/test/java/tests/api/java/lang/Process2Test.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang;
-
-import dalvik.annotation.AndroidOnly;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import tests.support.Support_Exec;
-import static tests.support.Support_Exec.javaProcessBuilder;
-
-public class Process2Test extends junit.framework.TestCase {
- /**
- * java.lang.Process#getInputStream(),
- * java.lang.Process#getErrorStream()
- * java.lang.Process#getOutputStream()
- * Tests if these methods return buffered streams.
- */
- @AndroidOnly("dalvikvm specific")
- public void test_streams()
- throws IOException, InterruptedException {
- Process p = javaProcessBuilder().start();
- assertNotNull(p.getInputStream());
- assertNotNull(p.getErrorStream());
- assertNotNull(p.getOutputStream());
- }
-
- public void test_getErrorStream() {
- String[] commands = {"ls"};
- Process process = null;
- try {
- process = Runtime.getRuntime().exec(commands, null, null);
- InputStream is = process.getErrorStream();
- StringBuffer msg = new StringBuffer("");
- while (true) {
- int c = is.read();
- if (c == -1)
- break;
- msg.append((char) c);
- }
- assertEquals("", msg.toString());
- } catch (IOException e) {
- fail("IOException was thrown.");
- } finally {
- process.destroy();
- }
-
- String[] unknownCommands = {"mkdir", "-u", "test"};
- Process erProcess = null;
- try {
- erProcess = Runtime.getRuntime().exec(unknownCommands, null, null);
- InputStream is = erProcess.getErrorStream();
- StringBuffer msg = new StringBuffer("");
- while (true) {
- int c = is.read();
- if (c == -1)
- break;
- msg.append((char) c);
- }
- assertTrue("Error stream should not be empty",
- !"".equals(msg.toString()));
- } catch (IOException e) {
- fail("IOException was thrown.");
- } finally {
- erProcess.destroy();
- }
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/ProcessManagerTest.java b/luni/src/test/java/tests/api/java/lang/ProcessManagerTest.java
deleted file mode 100644
index 99e1df3..0000000
--- a/luni/src/test/java/tests/api/java/lang/ProcessManagerTest.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang;
-
-import dalvik.annotation.BrokenTest;
-
-import junit.framework.TestCase;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-
-public class ProcessManagerTest extends TestCase {
-
- Thread thread = null;
- Process process = null;
- boolean isThrown = false;
-
- public void testCat() throws IOException, InterruptedException {
- String[] commands = { "cat" };
- Process process = Runtime.getRuntime().exec(commands, null, null);
-
- OutputStream out = process.getOutputStream();
- String greeting = "Hello, World!";
- out.write(greeting.getBytes());
- out.write('\n');
- out.close();
-
- assertEquals(greeting, readLine(process));
- }
-
- @BrokenTest("Sporadic failures in CTS, but not in CoreTestRunner")
- public void testSleep() throws IOException {
- String[] commands = { "sleep", "1" };
- process = Runtime.getRuntime().exec(commands, null, null);
- try {
- assertEquals(0, process.waitFor());
-
- } catch(InterruptedException ie) {
- fail("InterruptedException was thrown.");
- }
-
- isThrown = false;
- thread = new Thread() {
- public void run() {
- String[] commands = { "sleep", "1000"};
- try {
- process = Runtime.getRuntime().exec(commands, null, null);
- } catch (IOException e1) {
- fail("IOException was thrown.");
- }
- try {
- process.waitFor();
- fail("InterruptedException was not thrown.");
- } catch(InterruptedException ie) {
- isThrown = true;
- }
- }
- };
-
- Thread interruptThread = new Thread() {
- public void run() {
- try {
- sleep(10);
- } catch(InterruptedException ie) {
- fail("InterruptedException was thrown in " +
- "the interruptThread.");
- }
- thread.interrupt();
- }
- };
- thread.start();
- interruptThread.start();
- try {
- interruptThread.join();
- } catch (InterruptedException e) {
- fail("InterruptedException was thrown.");
- }
- try {
- Thread.sleep(100);
- } catch(InterruptedException ie) {
-
- }
-
- thread.interrupt();
- //process.destroy();
- try {
- Thread.sleep(100);
- } catch(InterruptedException ie) {
-
- }
-
- assertTrue(isThrown);
- }
-
- public void testPwd() throws IOException, InterruptedException {
- String[] commands = { "sh", "-c", "pwd" };
- Process process = Runtime.getRuntime().exec(
- commands, null, new File("/"));
- logErrors(process);
- assertEquals("/", readLine(process));
- }
-
- public void testEnvironment() throws IOException, InterruptedException {
- String[] commands = { "sh", "-c", "echo $FOO" };
-
- // Remember to set the path so we can find sh.
- String[] environment = { "FOO=foo", "PATH=" + System.getenv("PATH") };
- Process process = Runtime.getRuntime().exec(
- commands, environment, null);
- logErrors(process);
- assertEquals("foo", readLine(process));
- }
-
- String readLine(Process process) throws IOException {
- InputStream in = process.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- return reader.readLine();
- }
-
- void logErrors(final Process process) throws IOException {
- Thread thread = new Thread() {
- public void run() {
- InputStream in = process.getErrorStream();
- BufferedReader reader
- = new BufferedReader(new InputStreamReader(in));
- String line;
- try {
- while ((line = reader.readLine()) != null) {
- System.err.println(line);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- };
- thread.setDaemon(true);
- thread.start();
- }
-
- public void testHeavyLoad() {
- int i;
- for (i = 0; i < 100; i++)
- stuff();
- }
-
- private static void stuff() {
- Runtime rt = Runtime.getRuntime();
- try {
- Process proc = rt.exec("ls");
- proc.waitFor();
- proc = null;
- } catch (Exception ex) {
- System.err.println("Failure: " + ex);
- throw new RuntimeException(ex);
- }
- rt.gc();
- rt = null;
- }
-
- InputStream in;
-
- public void testCloseNonStandardFds()
- throws IOException, InterruptedException {
- String[] commands = { "ls", "/proc/self/fd" };
-
- Process process = Runtime.getRuntime().exec(commands, null, null);
- int before = countLines(process);
-
- // Open a new fd.
- this.in = new FileInputStream("/proc/version");
-
- try {
- process = Runtime.getRuntime().exec(commands, null, null);
- int after = countLines(process);
-
- // Assert that the new fd wasn't open in the second run.
- assertEquals(before, after);
- } finally {
- this.in = null;
- }
- }
-
- /**
- * Counts lines of input from the given process. Equivalent to "wc -l".
- */
- private int countLines(Process process) throws IOException {
- logErrors(process);
- InputStream in = process.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- int count = 0;
- while (reader.readLine() != null) {
- count++;
- }
- return count;
- }
-
- public void testInvalidCommand()
- throws IOException, InterruptedException {
- try {
- String[] commands = { "doesnotexist" };
- Runtime.getRuntime().exec(commands, null, null);
- } catch (IOException e) { /* expected */ }
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/ProcessTest.java b/luni/src/test/java/tests/api/java/lang/ProcessTest.java
deleted file mode 100644
index 2a8e0bd..0000000
--- a/luni/src/test/java/tests/api/java/lang/ProcessTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-
-public class ProcessTest extends junit.framework.TestCase {
-
- public void test_55017() throws Exception {
- ArrayList<Process> children = new ArrayList<Process>();
- for (int i = 0; i < 256; ++i) {
- try {
- children.add(Runtime.getRuntime().exec(new String[] { "/system/bin/does-not-exist" }, null, null));
- System.gc();
- } catch (IOException expected) {
- }
- }
- assertEquals(0, children.size());
-
- boolean onDevice = new File("/system/bin").exists();
- String[] psCommand = onDevice ? new String[] { "ps" } : new String[] { "ps", "s" };
- Process ps = Runtime.getRuntime().exec(psCommand, null, null);
- int zombieCount = 0;
- for (String line : readAndCloseStream(ps.getInputStream()).split("\n")) {
- if (line.contains(" Z ") || line.contains(" Z+ ")) {
- ++zombieCount;
- }
- }
- assertEquals(0, zombieCount);
- }
-
- public void test_getOutputStream() throws Exception {
- String[] commands = { "cat", "-"};
- Process p = Runtime.getRuntime().exec(commands, null, null);
- OutputStream os = p.getOutputStream();
- // send data, and check if it is echoed back correctly
- String str1 = "Some data for testing communication between processes\n";
- String str2 = "More data that serves the same purpose.\n";
- String str3 = "Here is some more data.\n";
- os.write(str1.getBytes());
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- os.write(str2.getBytes());
- os.write(str3.getBytes());
- os.close();
-
- String received = readAndCloseStream(p.getInputStream());
- assertEquals(str1 + str2 + str3, received);
-
- String stderr = readAndCloseStream(p.getErrorStream());
- assertEquals("", stderr);
-
- p.waitFor();
- p.destroy();
- }
-
- public void test_getErrorStream() throws Exception {
- String[] commands = { "cat", "--no-such-option"};
- Process p = Runtime.getRuntime().exec(commands, null, null);
-
- p.getOutputStream().close();
-
- String received = readAndCloseStream(p.getInputStream());
- assertEquals("", received);
-
- String stderr = readAndCloseStream(p.getErrorStream());
- assertTrue(stderr, stderr.contains("unrecognized option") || stderr.contains("invalid option"));
-
- p.waitFor();
- p.destroy();
- }
-
- private String readAndCloseStream(InputStream is) throws IOException {
- StringBuffer result = new StringBuffer();
- while (true) {
- int c = is.read();
- if (c == -1) {
- break;
- }
- result.append((char) c);
- }
- is.close();
- return result.toString();
- }
-
- public void test_exitValue() throws Exception {
- String[] commands = { "ls" };
- Process process = Runtime.getRuntime().exec(commands, null, null);
- process.waitFor();
- assertEquals(0, process.exitValue());
-
- String[] commandsSleep = { "sleep", "3000" };
- process = Runtime.getRuntime().exec(commandsSleep, null, null);
- process.destroy();
- process.waitFor(); // destroy is asynchronous.
- assertTrue(process.exitValue() != 0);
-
- process = Runtime.getRuntime().exec(new String[] { "sleep", "3000" }, null, null);
- try {
- process.exitValue();
- fail();
- } catch(IllegalThreadStateException expected) {
- }
- }
-
- public void test_destroy() throws Exception {
- String[] commands = { "ls"};
- Process process = Runtime.getRuntime().exec(commands, null, null);
- process.destroy();
- process.destroy();
- process.destroy();
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/StringTest.java b/luni/src/test/java/tests/api/java/lang/StringTest.java
deleted file mode 100644
index 1e9933d..0000000
--- a/luni/src/test/java/tests/api/java/lang/StringTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for the class {@link String}.
- */
-public class StringTest extends TestCase {
- public void test_contains() {
- assertTrue("aabc".contains("abc"));
- assertTrue("abcd".contains("abc"));
- assertFalse("abcd".contains("cba"));
- }
- public void test_charAt() {
- assertTrue("abcd".charAt(0) == 'a');
- assertTrue("abcd".charAt(3) == 'd');
- }
- public void test_StartsWith() {
- assertTrue("abcd".startsWith("abc"));
- assertFalse("abcd".startsWith("aabc"));
- }
- public void test_EndsWith() {
- assertTrue("abcd".endsWith("bcd"));
- assertFalse("abcd".endsWith("bcde"));
- }
-
- public void test_CASE_INSENSITIVE_ORDER() {
- String s1 = "ABCDEFG";
- String s2 = "abcdefg";
-
- assertTrue(String.CASE_INSENSITIVE_ORDER.compare(s1, s2) == 0);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/ref/PhantomReferenceTest.java b/luni/src/test/java/tests/api/java/lang/ref/PhantomReferenceTest.java
deleted file mode 100644
index 6470579..0000000
--- a/luni/src/test/java/tests/api/java/lang/ref/PhantomReferenceTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.ref;
-
-import java.lang.ref.PhantomReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import libcore.java.lang.ref.FinalizationTester;
-
-//TODO: write a test to verify that the referent's finalize() happens
-// before the PhantomReference is enqueued.
-
-public class PhantomReferenceTest extends junit.framework.TestCase {
- static Boolean bool;
- public boolean isCalled = false;
- protected void doneSuite() {
- bool = null;
- }
-
- /**
- * java.lang.ref.PhantomReference#get()
- */
- public void test_get() {
- ReferenceQueue rq = new ReferenceQueue();
- bool = new Boolean(false);
- PhantomReference pr = new PhantomReference(bool, rq);
- assertNull("get() should return null.", pr.get());
- pr.enqueue();
- assertNull("get() should return null.", pr.get());
- pr.clear();
- assertNull("get() should return null.", pr.get());
- }
-
- /**
- * java.lang.Runtime#gc()
- */
- public void test_gcInteraction() {
- class TestPhantomReference<T> extends PhantomReference<T> {
- public TestPhantomReference(T referent,
- ReferenceQueue<? super T> q) {
- super(referent, q);
- }
- public boolean enqueue() {
- // Initiate another GC from inside enqueue() to
- // see if it causes any problems inside the VM.
- Runtime.getRuntime().gc();
- return super.enqueue();
- }
- }
-
- final ReferenceQueue rq = new ReferenceQueue();
- final PhantomReference[] tprs = new PhantomReference[4];
-
- class TestThread extends Thread {
- public void run() {
- // Create the object in a separate thread to ensure
- // it will be gc'ed.
- Object obj = new Object();
- tprs[0] = new TestPhantomReference(obj, rq);
- tprs[1] = new TestPhantomReference(obj, rq);
- tprs[2] = new TestPhantomReference(obj, rq);
- tprs[3] = new TestPhantomReference(obj, rq);
- }
- }
-
- try {
- Thread t = new TestThread();
- t.start();
- t.join();
-
- FinalizationTester.induceFinalization();
-
- assertNull("get() should return null.", tprs[0].get());
- assertNull("get() should return null.", tprs[1].get());
- assertNull("get() should return null.", tprs[2].get());
- assertNull("get() should return null.", tprs[3].get());
-
- for (int i = 0; i < 4; i++) {
- Reference r = rq.remove(100L);
- assertNotNull("Reference should have been enqueued.", r);
- }
-
- // These are to make sure that tprs and its elements don't get
- // optimized out.
- assertNull("get() should return null.", tprs[0].get());
- assertNull("get() should return null.", tprs[1].get());
- assertNull("get() should return null.", tprs[2].get());
- assertNull("get() should return null.", tprs[3].get());
- } catch (InterruptedException e) {
- fail("InterruptedException : " + e.getMessage());
- }
- }
-
- /**
- * java.lang.ref.PhantomReference#PhantomReference(java.lang.Object,
- * java.lang.ref.ReferenceQueue)
- */
- public void test_ConstructorLjava_lang_ObjectLjava_lang_ref_ReferenceQueue() {
- ReferenceQueue rq = new ReferenceQueue();
- bool = new Boolean(true);
- try {
- PhantomReference pr = new PhantomReference(bool, rq);
- // Allow the finalizer to run to potentially enqueue
- Thread.sleep(1000);
- assertTrue("Initialization failed.", !pr.isEnqueued());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- // need a reference to bool so the jit does not optimize it away
- assertTrue("should always pass", bool.booleanValue());
-
- boolean exception = false;
- try {
- new PhantomReference(bool, null);
- } catch (NullPointerException e) {
- exception = true;
- }
- assertTrue("Should not throw NullPointerException", !exception);
- }
-
- protected void setUp() {
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/ref/ReferenceQueueTest.java b/luni/src/test/java/tests/api/java/lang/ref/ReferenceQueueTest.java
deleted file mode 100644
index cad61b3..0000000
--- a/luni/src/test/java/tests/api/java/lang/ref/ReferenceQueueTest.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.ref;
-
-import java.lang.ref.PhantomReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
-import libcore.java.lang.ref.FinalizationTester;
-
-public class ReferenceQueueTest extends junit.framework.TestCase {
- static Boolean b;
-
- static Integer integer;
- boolean isThrown = false;
-
- protected void doneSuite() {
- b = null;
- integer = null;
- }
-
- public class ChildThread implements Runnable {
- public ChildThread() {
- }
-
- public void run() {
- try {
- rq.wait(1000);
- } catch (Exception e) {
- }
- synchronized (rq) {
- // store in a static so it won't be gc'ed because the jit
- // optimized it out
- integer = new Integer(667);
- SoftReference sr = new SoftReference(integer, rq);
- sr.enqueue();
- rq.notify();
- }
- }
- }
-
- ReferenceQueue rq;
-
- /**
- * java.lang.ref.ReferenceQueue#poll()
- */
- public void test_poll() {
- // store in a static so it won't be gc'ed because the jit
- // optimized it out
- b = new Boolean(true);
- Object obj = new Object();
- String str = "Test";
-
- SoftReference sr = new SoftReference(b, rq);
- WeakReference wr = new WeakReference(obj, rq);
- PhantomReference pr = new PhantomReference(str, rq);
- assertNull(rq.poll());
- sr.enqueue();
- wr.enqueue();
- pr.enqueue();
-
- try {
- assertNull("Remove failed.", rq.poll().get());
- } catch (Exception e) {
- fail("Exception during the test : " + e.getMessage());
- }
-
- try {
- assertEquals("Remove failed.", obj, (rq.poll().get()));
- } catch (Exception e) {
- fail("Exception during the test : " + e.getMessage());
- }
-
- try {
- assertTrue("Remove failed.", ((Boolean) rq.poll().get())
- .booleanValue());
- } catch (Exception e) {
- fail("Exception during the test : " + e.getMessage());
- }
- assertNull(rq.poll());
-
- sr.enqueue();
- wr.enqueue();
-
- FinalizationTester.induceFinalization();
-
- assertNull(rq.poll());
- }
-
- /**
- * java.lang.ref.ReferenceQueue#remove()
- */
- public void test_remove() {
- // store in a static so it won't be gc'ed because the jit
- // optimized it out
- b = new Boolean(true);
-
- SoftReference sr = new SoftReference(b, rq);
- sr.enqueue();
- try {
- assertTrue("Remove failed.", ((Boolean) rq.remove().get())
- .booleanValue());
- } catch (Exception e) {
- fail("Exception during the test : " + e.getMessage());
- }
-
- assertNull(rq.poll());
-
- sr.enqueue();
-
- class RemoveThread extends Thread {
- public void run() {
- try {
- rq.remove();
- } catch(InterruptedException ie) {
- isThrown = true;
- }
- }
- }
- RemoveThread rt = new RemoveThread();
- rt.start();
- try {
- Thread.sleep(100);
- } catch(InterruptedException ie) {
-
- }
- rt.interrupt();
- try {
- Thread.sleep(100);
- } catch(InterruptedException ie) {
-
- }
- assertTrue(isThrown);
- assertNull(rq.poll());
- }
-
- /**
- * java.lang.ref.ReferenceQueue#remove(long)
- */
- public void test_removeJ() {
- try {
- assertNull("Queue should be empty. (poll)", rq.poll());
- assertNull("Queue should be empty. (remove(1))",
- rq.remove((long) 1));
- Thread ct = new Thread(new ChildThread());
- ct.start();
- Reference ret = rq.remove(0L);
- assertNotNull("Delayed remove failed.", ret);
- } catch (InterruptedException e) {
- fail("InterruptedExeException during test : " + e.getMessage());
- }
- catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
-
- Object obj = new Object();
- WeakReference wr = new WeakReference(obj, rq);
- Boolean b = new Boolean(true);
- SoftReference sr = new SoftReference(b, rq);
- String str = "Test";
- PhantomReference pr = new PhantomReference(str, rq);
-
- pr.enqueue();
- wr.enqueue();
- sr.enqueue();
-
- try {
- Reference result = rq.remove(1L);
- assertTrue((Boolean)result.get());
- result = rq.remove(1L);
- assertEquals(obj, result.get());
- result = rq.remove(1L);
- assertNull(result.get());
- } catch (IllegalArgumentException e1) {
- fail("IllegalArgumentException was thrown.");
- } catch (InterruptedException e1) {
- fail("InterruptedException was thrown.");
- }
- rq = new ReferenceQueue();
- isThrown = false;
- assertNull(rq.poll());
-
- class RemoveThread extends Thread {
- public void run() {
- try {
- rq.remove(1000L);
- } catch(InterruptedException ie) {
- isThrown = true;
- }
- }
- }
- RemoveThread rt = new RemoveThread();
- rt.start();
- try {
- Thread.sleep(10);
- } catch(InterruptedException ie) {
-
- }
- rt.interrupt();
- try {
- Thread.sleep(10);
- } catch(InterruptedException ie) {
-
- }
- assertTrue(isThrown);
- assertNull(rq.poll());
-
- try {
- rq.remove(-1);
- fail("IllegalArgumentException expected.");
- } catch(IllegalArgumentException iae) {
- //expected
- } catch (InterruptedException e) {
- fail("Unexpected InterruptedException.");
- }
- }
-
- /**
- * java.lang.ref.ReferenceQueue#ReferenceQueue()
- */
- public void test_Constructor() {
- ReferenceQueue rq = new ReferenceQueue();
- assertNull(rq.poll());
- try {
- rq.remove(100L);
- } catch (InterruptedException e) {
- fail("InterruptedException was thrown.");
- }
- }
-
- protected void setUp() {
- rq = new ReferenceQueue();
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/ref/ReferenceTest.java b/luni/src/test/java/tests/api/java/lang/ref/ReferenceTest.java
deleted file mode 100644
index 7461b47..0000000
--- a/luni/src/test/java/tests/api/java/lang/ref/ReferenceTest.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.lang.ref;
-
-import java.lang.ref.PhantomReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
-import junit.framework.AssertionFailedError;
-import libcore.java.lang.ref.FinalizationTester;
-
-public class ReferenceTest extends junit.framework.TestCase {
- Object tmpA, tmpB, tmpC, obj;
-
- volatile Reference r;
-
- /*
- * For test_subclass().
- */
- static TestWeakReference twr;
- static AssertionFailedError error;
- static boolean testObjectFinalized;
- static class TestWeakReference<T> extends WeakReference<T> {
- public volatile boolean clearSeen = false;
- public volatile boolean enqueueSeen = false;
-
- public TestWeakReference(T referent) {
- super(referent);
- }
-
- public TestWeakReference(T referent, ReferenceQueue<? super T> q) {
- super(referent, q);
- }
-
- public void clear() {
- clearSeen = true;
- if (testObjectFinalized) {
- error = new AssertionFailedError("Clear should happen " +
- "before finalization.");
- throw error;
- }
- if (enqueueSeen) {
- error = new AssertionFailedError("Clear should happen " +
- "before enqueue.");
- throw error;
- }
- super.clear();
- }
-
- public boolean enqueue() {
- enqueueSeen = true;
- if (!clearSeen) {
- error = new AssertionFailedError("Clear should happen " +
- "before enqueue.");
- throw error;
- }
-
- /* Do this last; it may notify the main test thread,
- * and anything we'd do after it (e.g., setting clearSeen)
- * wouldn't be seen.
- */
- return super.enqueue();
- }
- }
-
- protected void doneSuite() {
- tmpA = tmpB = obj = null;
- }
-
- /**
- * java.lang.ref.Reference#clear()
- */
- public void test_clear() {
- tmpA = new Object();
- tmpB = new Object();
- tmpC = new Object();
- SoftReference sr = new SoftReference(tmpA, new ReferenceQueue());
- WeakReference wr = new WeakReference(tmpB, new ReferenceQueue());
- PhantomReference pr = new PhantomReference(tmpC, new ReferenceQueue());
- assertTrue("Start: Object not cleared.", (sr.get() != null)
- && (wr.get() != null));
- assertNull("Referent is not null.", pr.get());
- sr.clear();
- wr.clear();
- pr.clear();
- assertTrue("End: Object cleared.", (sr.get() == null)
- && (wr.get() == null));
- assertNull("Referent is not null.", pr.get());
- // Must reference tmpA and tmpB so the jit does not optimize them away
- assertTrue("should always pass", tmpA != sr.get() && tmpB != wr.get());
- }
-
- /**
- * java.lang.ref.Reference#enqueue()
- */
- public void test_enqueue() {
- ReferenceQueue rq = new ReferenceQueue();
- obj = new Object();
- Reference ref = new SoftReference(obj, rq);
- assertTrue("Enqueue failed.", (!ref.isEnqueued())
- && ((ref.enqueue()) && (ref.isEnqueued())));
- assertTrue("Not properly enqueued.", rq.poll().get() == obj);
- // This fails...
- assertTrue("Should remain enqueued.", !ref.isEnqueued());
- assertTrue("Can not enqueue twice.", (!ref.enqueue())
- && (rq.poll() == null));
-
- rq = new ReferenceQueue();
- obj = new Object();
-
- ref = new WeakReference(obj, rq);
- assertTrue("Enqueue failed2.", (!ref.isEnqueued())
- && ((ref.enqueue()) && (ref.isEnqueued())));
- assertTrue("Not properly enqueued2.", rq.poll().get() == obj);
- assertTrue("Should remain enqueued2.", !ref.isEnqueued()); // This
- // fails.
- assertTrue("Can not enqueue twice2.", (!ref.enqueue())
- && (rq.poll() == null));
-
- ref = new PhantomReference(obj, rq);
- assertTrue("Enqueue failed3.", (!ref.isEnqueued())
- && ((ref.enqueue()) && (ref.isEnqueued())));
- assertNull("Not properly enqueued3.", rq.poll().get());
- assertTrue("Should remain enqueued3.", !ref.isEnqueued()); // This
- // fails.
- assertTrue("Can not enqueue twice3.", (!ref.enqueue())
- && (rq.poll() == null));
- }
-
- public void test_get_WeakReference() throws Exception {
- // Test the general/overall functionality of Reference.
- ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
-
- r = newWeakReference(queue);
- FinalizationTester.induceFinalization();
- Reference ref = queue.remove();
- assertNotNull("Object not enqueued.", ref);
- assertSame("Unexpected ref1", ref, r);
- assertNull("Object could not be reclaimed1.", r.get());
-
- r = newWeakReference(queue);
- FinalizationTester.induceFinalization();
-
- // wait for the reference queue thread to enqueue the newly-finalized object
- Thread.yield();
- Thread.sleep(200);
-
- ref = queue.poll();
- assertNotNull("Object not enqueued.", ref);
- assertSame("Unexpected ref2", ref, r);
- assertNull("Object could not be reclaimed.", ref.get());
- assertNull("Object could not be reclaimed.", r.get());
- }
-
- /**
- * Makes sure that overridden versions of clear() and enqueue()
- * get called, and that clear/enqueue/finalize happen in the
- * right order for WeakReferences.
- *
- * java.lang.ref.Reference#clear()
- * java.lang.ref.Reference#enqueue()
- * java.lang.Object#finalize()
- */
- public void test_subclass() {
- error = null;
- testObjectFinalized = false;
- twr = null;
-
- class TestObject {
- public TestWeakReference testWeakReference = null;
-
- public void setTestWeakReference(TestWeakReference twr) {
- testWeakReference = twr;
- }
-
- protected void finalize() {
- testObjectFinalized = true;
- }
- }
-
- final ReferenceQueue rq = new ReferenceQueue();
-
- class TestThread extends Thread {
- public void run() {
- // Create the object in a separate thread to ensure it will be
- // gc'ed
- TestObject testObj = new TestObject();
- twr = new TestWeakReference(testObj, rq);
- testObj.setTestWeakReference(twr);
- testObj = null;
- }
- }
-
- Reference ref;
-
- try {
- Thread t = new TestThread();
- t.start();
- t.join();
- FinalizationTester.induceFinalization();
- ref = rq.remove(5000L); // Give up after five seconds.
-
- assertNotNull("Object not garbage collected.", ref);
- assertTrue("Unexpected reference.", ref == twr);
- assertNull("Object could not be reclaimed.", twr.get());
- //assertTrue("Overridden clear() should have been called.",
- // twr.clearSeen);
- //assertTrue("Overridden enqueue() should have been called.",
- // twr.enqueueSeen);
- assertTrue("finalize() should have been called.",
- testObjectFinalized);
- } catch (InterruptedException e) {
- fail("InterruptedException : " + e.getMessage());
- }
-
- }
-
- /**
- * java.lang.ref.Reference#get()
- */
- public void test_get() {
- WeakReference ref = newWeakReference(null);
-
- FinalizationTester.induceFinalization();
- assertNull("get() doesn't return null after gc for WeakReference", ref.get());
-
- obj = new Object();
- ref = new WeakReference<Object>(obj, new ReferenceQueue<Object>());
- ref.clear();
- assertNull("get() doesn't return null after clear for WeakReference", ref.get());
- }
-
- /**
- * Helper method to prevent live-precise bugs from interfering with analysis
- * of what is reachable. Do not inline this method; otherwise tests may fail
- * on VMs that are not live-precise. http://b/4191345
- */
- private WeakReference<Object> newWeakReference(ReferenceQueue<Object> queue) {
- Object o = new Object();
- WeakReference<Object> ref = new WeakReference<Object>(o, queue);
- assertSame(o, ref.get());
- return ref;
- }
-
- /**
- * java.lang.ref.Reference#isEnqueued()
- */
- public void test_isEnqueued() {
- ReferenceQueue rq = new ReferenceQueue();
- obj = new Object();
- Reference ref = new SoftReference(obj, rq);
- assertTrue("Should start off not enqueued.", !ref.isEnqueued());
- ref.enqueue();
- assertTrue("Should now be enqueued.", ref.isEnqueued());
- ref.enqueue();
- assertTrue("Should still be enqueued.", ref.isEnqueued());
- rq.poll();
- // This fails ...
- assertTrue("Should now be not enqueued.", !ref.isEnqueued());
- }
-
- /* Contrives a situation where the only reference to a string
- * is a WeakReference from an object that is being finalized.
- * Checks to make sure that the referent of the WeakReference
- * is still pointing to a valid object.
- */
- public void test_finalizeReferenceInteraction() {
- error = null;
- testObjectFinalized = false;
-
- class TestObject {
- WeakReference<String> stringRef;
-
- public TestObject(String referent) {
- stringRef = new WeakReference<String>(referent);
- }
-
- protected void finalize() {
- try {
- /* If a VM bug has caused the referent to get
- * freed without the reference getting cleared,
- * looking it up, assigning it to a local and
- * doing a GC should cause some sort of exception.
- */
- String s = stringRef.get();
- System.gc();
- testObjectFinalized = true;
- } catch (Throwable t) {
- error = new AssertionFailedError("something threw '" + t +
- "' in finalize()");
- }
- }
- }
-
- class TestThread extends Thread {
- public void run() {
- // Create the object in a separate thread to ensure it will be
- // gc'ed
- TestObject testObj = new TestObject(new String("sup /b/"));
- }
- }
-
- try {
- Thread t = new TestThread();
- t.start();
- t.join();
- FinalizationTester.induceFinalization();
- Thread.sleep(1000);
- if (error != null) {
- throw error;
- }
- assertTrue("finalize() should have been called.",
- testObjectFinalized);
- } catch (InterruptedException e) {
- fail("InterruptedException : " + e.getMessage());
- }
- }
-
-
- protected void setUp() {
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/ref/SoftReferenceTest.java b/luni/src/test/java/tests/api/java/lang/ref/SoftReferenceTest.java
deleted file mode 100644
index 197d829..0000000
--- a/luni/src/test/java/tests/api/java/lang/ref/SoftReferenceTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.lang.ref;
-
-import dalvik.annotation.SideEffect;
-
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.util.Vector;
-import libcore.java.lang.ref.FinalizationTester;
-
-public class SoftReferenceTest extends junit.framework.TestCase {
- static Boolean bool;
- SoftReference r;
-
- protected void doneSuite() {
- bool = null;
- }
-
- /**
- * java.lang.ref.SoftReference#SoftReference(java.lang.Object,
- * java.lang.ref.ReferenceQueue)
- */
- public void test_ConstructorLjava_lang_ObjectLjava_lang_ref_ReferenceQueue() {
- ReferenceQueue rq = new ReferenceQueue();
- bool = new Boolean(true);
- try {
- SoftReference sr = new SoftReference(bool, rq);
- assertTrue("Initialization failed.", ((Boolean) sr.get())
- .booleanValue());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
-
- boolean exception = false;
- try {
- new SoftReference(bool, null);
- } catch (NullPointerException e) {
- exception = true;
- }
- assertTrue("Should not throw NullPointerException", !exception);
- }
-
- /**
- * java.lang.ref.SoftReference#SoftReference(java.lang.Object)
- */
- public void test_ConstructorLjava_lang_Object() {
- bool = new Boolean(true);
- try {
- SoftReference sr = new SoftReference(bool);
- assertTrue("Initialization failed.", ((Boolean) sr.get())
- .booleanValue());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- }
-
- /**
- * java.lang.ref.SoftReference#get()
- */
- public void test_get() {
- bool = new Boolean(false);
- SoftReference sr = new SoftReference(bool);
- assertTrue("Same object not returned.", bool == sr.get());
- }
-
- @SideEffect("Causes OutOfMemoryError to test finalization")
- public void test_get_SoftReference() {
-
- class TestObject {
- public boolean finalized;
- public TestObject() {
- finalized = false;
- }
-
- protected void finalize() {
- finalized = true;
- }
- }
-
- final ReferenceQueue rq = new ReferenceQueue();
-
- class TestThread extends Thread {
- public void run() {
- Object testObj = new TestObject();
- r = new SoftReference(testObj, rq);
- }
- }
- Reference ref;
- try {
- TestThread t = new TestThread();
- t.start();
- t.join();
- Vector<StringBuffer> v = new Vector<StringBuffer>();
- try {
- while(true) {
- v.add(new StringBuffer(10000));
- }
- } catch(OutOfMemoryError ofme) {
- v = null;
- }
- } catch (InterruptedException e) {
- fail("InterruptedException : " + e.getMessage());
- }
-
- assertNull("get() should return null " +
- "if OutOfMemoryError is thrown.", r.get());
-
- try {
- TestThread t = new TestThread();
- t.start();
- t.join();
- FinalizationTester.induceFinalization();
- ref = rq.poll();
- assertNotNull("Object not garbage collected.", ref);
- assertNull("Object is not null.", ref.get());
- assertNotNull("Object could not be reclaimed.", r.get());
- } catch (Exception e) {
- fail("Exception : " + e.getMessage());
- }
- }
-
- protected void setUp() {
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/ref/WeakReferenceTest.java b/luni/src/test/java/tests/api/java/lang/ref/WeakReferenceTest.java
deleted file mode 100644
index 2bddc1b..0000000
--- a/luni/src/test/java/tests/api/java/lang/ref/WeakReferenceTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.ref;
-
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-
-public class WeakReferenceTest extends junit.framework.TestCase {
- static Boolean bool;
-
- protected void doneSuite() {
- bool = null;
- }
-
- /**
- * java.lang.ref.WeakReference#WeakReference(java.lang.Object,
- * java.lang.ref.ReferenceQueue)
- */
- public void test_ConstructorLjava_lang_ObjectLjava_lang_ref_ReferenceQueue() {
- ReferenceQueue rq = new ReferenceQueue();
- bool = new Boolean(true);
- try {
- // Allow the finalizer to run to potentially enqueue
- WeakReference wr = new WeakReference(bool, rq);
- assertTrue("Initialization failed.", ((Boolean) wr.get())
- .booleanValue());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- // need a reference to bool so the jit does not optimize it away
- assertTrue("should always pass", bool.booleanValue());
-
- boolean exception = false;
- try {
- new WeakReference(bool, null);
- } catch (NullPointerException e) {
- exception = true;
- }
- assertTrue("Should not throw NullPointerException", !exception);
- }
-
- /**
- * java.lang.ref.WeakReference#WeakReference(java.lang.Object)
- */
- public void test_ConstructorLjava_lang_Object() {
- bool = new Boolean(true);
- try {
- WeakReference wr = new WeakReference(bool);
- // Allow the finalizer to run to potentially enqueue
- Thread.sleep(1000);
- assertTrue("Initialization failed.", ((Boolean) wr.get())
- .booleanValue());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- // need a reference to bool so the jit does not optimize it away
- assertTrue("should always pass", bool.booleanValue());
- }
-
- protected void setUp() {
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/AccessibleObjectTest.java b/luni/src/test/java/tests/api/java/lang/reflect/AccessibleObjectTest.java
deleted file mode 100644
index 41c9798..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/AccessibleObjectTest.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Modifier;
-import java.util.HashSet;
-import java.util.Set;
-
-public class AccessibleObjectTest extends junit.framework.TestCase {
-
- public class TestClass {
- public Object aField;
-
- @InheritedRuntime
- public void annotatedMethod(){}
- }
-
- public class SubTestClass extends TestClass{
- @AnnotationRuntime0
- @AnnotationRuntime1
- @AnnotationClass0
- @AnnotationSource0
- public void annotatedMethod(){}
- }
-
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target( {ElementType.METHOD})
- static @interface AnnotationRuntime0 {
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target( { ElementType.METHOD})
- static @interface AnnotationRuntime1 {
- }
-
- @Retention(RetentionPolicy.CLASS)
- @Target( { ElementType.METHOD})
- static @interface AnnotationClass0 {
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @Target( {ElementType.METHOD})
- static @interface AnnotationSource0 {
- }
-
- @Inherited
- @Retention(RetentionPolicy.RUNTIME)
- @Target( {ElementType.METHOD})
- static @interface InheritedRuntime {
- }
-
- //used for constructor test
- private static class MyAccessibleObject extends AccessibleObject{
- public MyAccessibleObject() {
- super();
- }
- }
-
- /**
- * java.lang.reflect.AccessibleObject#AccessibleObject()
- */
- public void test_Constructor() {
- assertNotNull(new MyAccessibleObject());
- }
-
- /**
- * java.lang.reflect.AccessibleObject#isAccessible()
- */
- public void test_isAccessible() {
- // Test for method boolean
- // java.lang.reflect.AccessibleObject.isAccessible()
- try {
- AccessibleObject ao = TestClass.class.getField("aField");
- ao.setAccessible(true);
- assertTrue("Returned false to isAccessible", ao.isAccessible());
- ao.setAccessible(false);
- assertTrue("Returned true to isAccessible", !ao.isAccessible());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[],
- * boolean)
- */
- public void test_setAccessible$Ljava_lang_reflect_AccessibleObjectZ() {
- try {
- AccessibleObject ao = TestClass.class.getField("aField");
- AccessibleObject[] aoa = new AccessibleObject[] { ao };
- AccessibleObject.setAccessible(aoa, true);
- assertTrue("Returned false to isAccessible", ao.isAccessible());
- AccessibleObject.setAccessible(aoa, false);
- assertTrue("Returned true to isAccessible", !ao.isAccessible());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.AccessibleObject#setAccessible(boolean)
- */
- public void test_setAccessible() throws Exception {
- AccessibleObject ao = TestClass.class.getField("aField");
- ao.setAccessible(true);
- assertTrue("Returned false to isAccessible", ao.isAccessible());
- ao.setAccessible(false);
- assertFalse("Returned true to isAccessible", ao.isAccessible());
- }
-
- public void test_getAnnotation() throws Exception{
- AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
- //test error case
- boolean npeThrown = false;
- try {
- ao.getAnnotation(null);
- fail("NPE expected");
- } catch (NullPointerException e) {
- npeThrown = true;
- }
- assertTrue("NPE expected", npeThrown);
-
- //test inherited on method has no effect
- InheritedRuntime ir = ao.getAnnotation(InheritedRuntime.class);
- assertNull("Inherited Annotations should have no effect", ir);
-
- //test ordinary runtime annotation
- AnnotationRuntime0 rt0 = ao.getAnnotation(AnnotationRuntime0.class);
- assertNotNull("AnnotationRuntime0 instance expected", rt0);
- }
-
- public void test_getAnnotations() throws Exception {
- AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
- Annotation[] annotations = ao.getAnnotations();
- assertEquals(2, annotations.length);
-
- Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
- ignoreOrder.add(annotations[0].annotationType());
- ignoreOrder.add(annotations[1].annotationType());
-
- assertTrue("Missing @AnnotationRuntime0",
- ignoreOrder.contains(AnnotationRuntime0.class));
- assertTrue("Missing @AnnotationRuntime1",
- ignoreOrder.contains(AnnotationRuntime1.class));
- }
-
- public void test_getDeclaredAnnotations() throws Exception {
- AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
- Annotation[] annotations = ao.getDeclaredAnnotations();
- assertEquals(2, annotations.length);
-
- Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
- ignoreOrder.add(annotations[0].annotationType());
- ignoreOrder.add(annotations[1].annotationType());
-
- assertTrue("Missing @AnnotationRuntime0",
- ignoreOrder.contains(AnnotationRuntime0.class));
- assertTrue("Missing @AnnotationRuntime1",
- ignoreOrder.contains(AnnotationRuntime1.class));
- }
-
- public void test_isAnnotationPresent() throws Exception {
- AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
- assertTrue("Missing @AnnotationRuntime0",
- ao.isAnnotationPresent(AnnotationRuntime0.class));
- assertFalse("AnnotationSource0 should not be visible at runtime",
- ao.isAnnotationPresent(AnnotationSource0.class));
- boolean npeThrown = false;
- try {
- ao.isAnnotationPresent(null);
- fail("NPE expected");
- } catch (NullPointerException e) {
- npeThrown = true;
- }
- assertTrue("NPE expected", npeThrown);
- }
-
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/ArrayTest.java b/luni/src/test/java/tests/api/java/lang/reflect/ArrayTest.java
deleted file mode 100644
index d9e05fb..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/ArrayTest.java
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.reflect.Array;
-
-public class ArrayTest extends junit.framework.TestCase {
-
- /**
- * java.lang.reflect.Array#get(java.lang.Object, int)
- */
- public void test_getLjava_lang_ObjectI() {
- // Test for method java.lang.Object
- // java.lang.reflect.Array.get(java.lang.Object, int)
-
- int[] x = { 1 };
- Object ret = null;
- boolean thrown = false;
- try {
- ret = Array.get(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value",
- 1, ((Integer) ret).intValue());
- try {
- ret = Array.get(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.get(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- //same test with non primitive component type
- Integer[] y = new Integer[]{ 1 };
- ret = null;
- thrown = false;
- try {
- ret = Array.get(y, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value",
- 1, ((Integer) ret).intValue());
- try {
- ret = Array.get(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.get(y, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- }
-
- /**
- * java.lang.reflect.Array#getBoolean(java.lang.Object, int)
- */
- public void test_getBooleanLjava_lang_ObjectI() {
- // Test for method boolean
- // java.lang.reflect.Array.getBoolean(java.lang.Object, int)
- boolean[] x = { true };
- boolean ret = false;
- boolean thrown = false;
- try {
- ret = Array.getBoolean(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertTrue("Get returned incorrect value", ret);
- try {
- ret = Array.getBoolean(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getBoolean(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getBoolean(null, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#getByte(java.lang.Object, int)
- */
- public void test_getByteLjava_lang_ObjectI() {
- // Test for method byte
- // java.lang.reflect.Array.getByte(java.lang.Object, int)
- byte[] x = { 1 };
- byte ret = 0;
- boolean thrown = false;
- try {
- ret = Array.getByte(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, ret);
- try {
- ret = Array.getByte(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getByte(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getByte(null, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#getChar(java.lang.Object, int)
- */
- public void test_getCharLjava_lang_ObjectI() {
- // Test for method char
- // java.lang.reflect.Array.getChar(java.lang.Object, int)
- char[] x = { 1 };
- char ret = 0;
- boolean thrown = false;
- try {
- ret = Array.getChar(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, ret);
- try {
- ret = Array.getChar(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getChar(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getChar(null, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#getDouble(java.lang.Object, int)
- */
- public void test_getDoubleLjava_lang_ObjectI() {
- // Test for method double
- // java.lang.reflect.Array.getDouble(java.lang.Object, int)
- double[] x = { 1 };
- double ret = 0;
- boolean thrown = false;
- try {
- ret = Array.getDouble(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, ret, 0.0);
- try {
- ret = Array.getDouble(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
-
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getDouble(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getDouble(null, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#getFloat(java.lang.Object, int)
- */
- public void test_getFloatLjava_lang_ObjectI() {
- // Test for method float
- // java.lang.reflect.Array.getFloat(java.lang.Object, int)
- float[] x = { 1 };
- float ret = 0;
- boolean thrown = false;
- try {
- ret = Array.getFloat(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, ret, 0.0);
- try {
- ret = Array.getFloat(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getFloat(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getFloat(null, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#getInt(java.lang.Object, int)
- */
- public void test_getIntLjava_lang_ObjectI() {
- // Test for method int java.lang.reflect.Array.getInt(java.lang.Object,
- // int)
- int[] x = { 1 };
- int ret = 0;
- boolean thrown = false;
- try {
- ret = Array.getInt(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, ret);
- try {
- ret = Array.getInt(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getInt(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getInt(null, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#getLength(java.lang.Object)
- */
- public void test_getLengthLjava_lang_Object() {
- // Test for method int
- // java.lang.reflect.Array.getLength(java.lang.Object)
- long[] x = { 1 };
-
- assertEquals("Returned incorrect length", 1, Array.getLength(x));
- assertEquals("Returned incorrect length", 10000, Array
- .getLength(new Object[10000]));
- try {
- Array.getLength(new Object());
- } catch (IllegalArgumentException e) {
- // Correct
- return;
- }
- fail("Failed to throw exception when passed non-array");
- }
-
- /**
- * java.lang.reflect.Array#getLong(java.lang.Object, int)
- */
- public void test_getLongLjava_lang_ObjectI() {
- // Test for method long
- // java.lang.reflect.Array.getLong(java.lang.Object, int)
- long[] x = { 1 };
- long ret = 0;
- boolean thrown = false;
- try {
- ret = Array.getLong(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, ret);
- try {
- ret = Array.getLong(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getLong(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getLong(null, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#getShort(java.lang.Object, int)
- */
- public void test_getShortLjava_lang_ObjectI() {
- // Test for method short
- // java.lang.reflect.Array.getShort(java.lang.Object, int)
- short[] x = { 1 };
- short ret = 0;
- boolean thrown = false;
- try {
- ret = Array.getShort(x, 0);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, ret);
- try {
- ret = Array.getShort(new Object(), 0);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getShort(x, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
- thrown = false;
- try {
- ret = Array.getShort(null, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#newInstance(java.lang.Class, int[])
- */
- public void test_newInstanceLjava_lang_Class$I() {
- // Test for method java.lang.Object
- // java.lang.reflect.Array.newInstance(java.lang.Class, int [])
- int[][] x;
- int[] y = { 2 };
-
- x = (int[][]) Array.newInstance(int[].class, y);
- assertEquals("Failed to instantiate array properly", 2, x.length);
-
- boolean thrown = false;
- try {
- x = (int[][]) Array.newInstance(null, y);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
-
- thrown = false;
- try {
- Array.newInstance(int[].class, new int[]{1,-1});
- } catch (NegativeArraySizeException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Negative array size failed to throw NegativeArraySizeException");
- }
-
- thrown = false;
- try {
- Array.newInstance(int[].class, new int[]{});
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Zero array size failed to throw IllegalArgumentException");
- }
- }
-
- /**
- * java.lang.reflect.Array#newInstance(java.lang.Class, int)
- */
- public void test_newInstanceLjava_lang_ClassI() {
- // Test for method java.lang.Object
- // java.lang.reflect.Array.newInstance(java.lang.Class, int)
- int[] x;
-
- x = (int[]) Array.newInstance(int.class, 100);
- assertEquals("Failed to instantiate array properly", 100, x.length);
-
- boolean thrown = false;
- try {
- Array.newInstance(null, 100);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
-
- thrown = false;
- try {
- Array.newInstance(int[].class, -1);
- } catch (NegativeArraySizeException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Negative array size failed to throw NegativeArraySizeException");
- }
- }
-
- /**
- * java.lang.reflect.Array#set(java.lang.Object, int,
- * java.lang.Object)
- */
- public void test_setLjava_lang_ObjectILjava_lang_Object() {
- // Test for method void java.lang.reflect.Array.set(java.lang.Object,
- // int, java.lang.Object)
- int[] x = { 0 };
- boolean thrown = false;
- try {
- Array.set(x, 0, new Integer(1));
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, ((Integer) Array.get(x, 0))
- .intValue());
- try {
- Array.set(new Object(), 0, new Object());
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.set(x, 4, new Integer(1));
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- // trying to put null in a primitive array causes
- // a IllegalArgumentException in 5.0
- boolean exception = false;
- try {
- Array.set(new int[1], 0, null);
- } catch (IllegalArgumentException e) {
- exception = true;
- }
- assertTrue("expected exception not thrown", exception);
-
- thrown = false;
- try {
- Array.set(null, 0, 2);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#setBoolean(java.lang.Object, int, boolean)
- */
- public void test_setBooleanLjava_lang_ObjectIZ() {
- // Test for method void
- // java.lang.reflect.Array.setBoolean(java.lang.Object, int, boolean)
- boolean[] x = { false };
- boolean thrown = false;
- try {
- Array.setBoolean(x, 0, true);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertTrue("Failed to set correct value", Array.getBoolean(x, 0));
- try {
- Array.setBoolean(new Object(), 0, false);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown){
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.setBoolean(x, 4, false);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- thrown = false;
- try {
- Array.setBoolean(null, 0, true);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#setByte(java.lang.Object, int, byte)
- */
- public void test_setByteLjava_lang_ObjectIB() {
- // Test for method void
- // java.lang.reflect.Array.setByte(java.lang.Object, int, byte)
- byte[] x = { 0 };
- boolean thrown = false;
- try {
- Array.setByte(x, 0, (byte) 1);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, Array.getByte(x, 0));
- try {
- Array.setByte(new Object(), 0, (byte) 9);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.setByte(x, 4, (byte) 9);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- thrown = false;
- try {
- Array.setByte(null, 0, (byte)0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#setChar(java.lang.Object, int, char)
- */
- public void test_setCharLjava_lang_ObjectIC() {
- // Test for method void
- // java.lang.reflect.Array.setChar(java.lang.Object, int, char)
- char[] x = { 0 };
- boolean thrown = false;
- try {
- Array.setChar(x, 0, (char) 1);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, Array.getChar(x, 0));
- try {
- Array.setChar(new Object(), 0, (char) 9);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.setChar(x, 4, (char) 9);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- thrown = false;
- try {
- Array.setChar(null, 0, (char)0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#setDouble(java.lang.Object, int, double)
- */
- public void test_setDoubleLjava_lang_ObjectID() {
- // Test for method void
- // java.lang.reflect.Array.setDouble(java.lang.Object, int, double)
- double[] x = { 0 };
- boolean thrown = false;
- try {
- Array.setDouble(x, 0, 1);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, Array.getDouble(x, 0), 0.0);
- try {
- Array.setDouble(new Object(), 0, 9);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.setDouble(x, 4, 9);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- thrown = false;
- try {
- Array.setDouble(null, 0, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#setFloat(java.lang.Object, int, float)
- */
- public void test_setFloatLjava_lang_ObjectIF() {
- // Test for method void
- // java.lang.reflect.Array.setFloat(java.lang.Object, int, float)
- float[] x = { 0.0f };
- boolean thrown = false;
- try {
- Array.setFloat(x, 0, (float) 1);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, Array.getFloat(x, 0), 0.0);
- try {
- Array.setFloat(new Object(), 0, (float) 9);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.setFloat(x, 4, (float) 9);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- thrown = false;
- try {
- Array.setFloat(null, 0, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#setInt(java.lang.Object, int, int)
- */
- public void test_setIntLjava_lang_ObjectII() {
- // Test for method void java.lang.reflect.Array.setInt(java.lang.Object,
- // int, int)
- int[] x = { 0 };
- boolean thrown = false;
- try {
- Array.setInt(x, 0, (int) 1);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, Array.getInt(x, 0));
- try {
- Array.setInt(new Object(), 0, (int) 9);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.setInt(x, 4, (int) 9);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- thrown = false;
- try {
- Array.setInt(null, 0, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#setLong(java.lang.Object, int, long)
- */
- public void test_setLongLjava_lang_ObjectIJ() {
- // Test for method void
- // java.lang.reflect.Array.setLong(java.lang.Object, int, long)
- long[] x = { 0 };
- boolean thrown = false;
- try {
- Array.setLong(x, 0, 1);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, Array.getLong(x, 0));
- try {
- Array.setLong(new Object(), 0, 9);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.setLong(x, 4, 9);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- thrown = false;
- try {
- Array.setLong(null, 0, 0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * java.lang.reflect.Array#setShort(java.lang.Object, int, short)
- */
- public void test_setShortLjava_lang_ObjectIS() {
- // Test for method void
- // java.lang.reflect.Array.setShort(java.lang.Object, int, short)
- short[] x = { 0 };
- boolean thrown = false;
- try {
- Array.setShort(x, 0, (short) 1);
- } catch (Exception e) {
- fail("Exception during get test : " + e.getMessage());
- }
- assertEquals("Get returned incorrect value", 1, Array.getShort(x, 0));
- try {
- Array.setShort(new Object(), 0, (short) 9);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Passing non-array failed to throw exception");
- }
- thrown = false;
- try {
- Array.setShort(x, 4, (short) 9);
- } catch (ArrayIndexOutOfBoundsException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Invalid index failed to throw exception");
- }
-
- thrown = false;
- try {
- Array.setShort(null, 0, (short)0);
- } catch (NullPointerException e) {
- // Correct behaviour
- thrown = true;
- }
- if (!thrown) {
- fail("Null argument failed to throw NPE");
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/BoundedGenericMethodsTests.java b/luni/src/test/java/tests/api/java/lang/reflect/BoundedGenericMethodsTests.java
deleted file mode 100644
index 7949a30..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/BoundedGenericMethodsTests.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-
-/**
- * Tests bounded type parameters declared on methods.
- */
-public class BoundedGenericMethodsTests extends GenericReflectionTestsBase {
- @SuppressWarnings("unchecked")
- static class BoundedGenericMethods<S> {
-
- public <T extends BoundedGenericMethods> void noParamNoReturn() {}
- public <T extends BoundedGenericMethods> void paramNoReturn(T param) {}
-
- public <T extends BoundedGenericMethods> T noParamReturn() {
- return (T) new Object();
- }
- public <T extends BoundedGenericMethods> T paramReturn(T t) {
- return t;
- }
- }
- @SuppressWarnings("unchecked")
- private static Class<? extends BoundedGenericMethods> clazz = BoundedGenericMethodsTests.BoundedGenericMethods.class;
-
- /**
- * Tests whether the type parameter is upper bounded by BoundedGenericMethods.
- * <T extends BoundedGenericMethods>.
- *
- * @param method
- * the declaring method
- */
- private void checkBoundedTypeParameter(Method method) {
- TypeVariable<Method> typeParameter = getTypeParameter(method);
- assertEquals("T", typeParameter.getName());
- assertEquals(method, typeParameter.getGenericDeclaration());
-
- Type[] bounds = typeParameter.getBounds();
- assertLenghtOne(bounds);
- Type bound = bounds[0];
- assertEquals(BoundedGenericMethods.class, bound);
- }
-
- /**
- * Tests whether the specified method declares a parameter with the type of
- * the type parameter.
- *
- * @param method
- * the declaring method
- */
- private void parameterType(Method method) {
- TypeVariable<Method> typeParameter = getTypeParameter(method);
- assertLenghtOne(method.getGenericParameterTypes());
- Type genericParameterType = method.getGenericParameterTypes()[0];
- assertEquals(typeParameter, genericParameterType);
- assertTrue(genericParameterType instanceof TypeVariable);
- TypeVariable<?> typeVariable = (TypeVariable<?>) genericParameterType;
- assertEquals(method, typeVariable.getGenericDeclaration());
-
- Type[] paramBounds = typeVariable.getBounds();
- assertLenghtOne(paramBounds);
- Type paramBound = paramBounds[0];
- assertEquals(BoundedGenericMethods.class, paramBound);
- }
-
- @SuppressWarnings("unchecked")
- private void checkReturnType(Method method) {
- Type genericReturnType = method.getGenericReturnType();
- assertEquals(getTypeParameter(method), genericReturnType);
- assertTrue(genericReturnType instanceof TypeVariable);
-
- TypeVariable<Method> returnTypeVariable = (TypeVariable<Method>) genericReturnType;
- assertEquals(method, returnTypeVariable.getGenericDeclaration());
-
- Type[] bounds = returnTypeVariable.getBounds();
- assertLenghtOne(bounds);
- Type bound = bounds[0];
-
- assertEquals(BoundedGenericMethods.class, bound);
- }
-
-
-
- /**
- * Tests that there are is one Type Parameter on the Class itself.
- */
- public void testBoundedGenericMethods() {
- assertLenghtOne(clazz.getTypeParameters());
- }
- public void testNoParamNoReturn() throws SecurityException, NoSuchMethodException {
- Method method = clazz.getMethod("noParamNoReturn");
- checkBoundedTypeParameter(method);
- }
- public void testUnboundedParamNoReturn() throws SecurityException, NoSuchMethodException {
- Method method = clazz.getMethod("paramNoReturn", BoundedGenericMethods.class);
- checkBoundedTypeParameter(method);
- parameterType(method);
- }
- public void testNoParamReturn() throws SecurityException, NoSuchMethodException {
- Method method = clazz.getMethod("noParamReturn");
- checkBoundedTypeParameter(method);
- assertLenghtZero(method.getGenericParameterTypes());
- checkReturnType(method);
- }
- public void testUnboundedParamReturn() throws SecurityException, NoSuchMethodException {
- Method method = clazz.getMethod("paramReturn", BoundedGenericMethods.class);
- checkBoundedTypeParameter(method);
- parameterType(method);
- checkReturnType(method);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/ConstructorTest.java b/luni/src/test/java/tests/api/java/lang/reflect/ConstructorTest.java
deleted file mode 100644
index 932315c..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/ConstructorTest.java
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-public class ConstructorTest extends junit.framework.TestCase {
-
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
- static @interface ConstructorTestAnnotationRuntime0 {
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
- static @interface ConstructorTestAnnotationRuntime1 {
- }
-
- @Retention(RetentionPolicy.CLASS)
- @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
- static @interface ConstructorTestAnnotationClass0 {
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @Target( {ElementType.CONSTRUCTOR, ElementType.PARAMETER})
- static @interface ConstructorTestAnnotationSource0 {
- }
-
- static class ConstructorTestHelper extends Object {
- int cval;
-
- @ConstructorTestAnnotationRuntime0
- @ConstructorTestAnnotationRuntime1
- @ConstructorTestAnnotationClass0
- @ConstructorTestAnnotationSource0
- public ConstructorTestHelper() throws IndexOutOfBoundsException {
- cval = 99;
- }
-
- public ConstructorTestHelper(
- @ConstructorTestAnnotationRuntime0
- @ConstructorTestAnnotationRuntime1
- @ConstructorTestAnnotationClass0
- @ConstructorTestAnnotationSource0 Object x) {
- }
-
- public ConstructorTestHelper(String... x) {
- }
-
- private ConstructorTestHelper(int a) {
- }
-
- protected ConstructorTestHelper(long a) {
- }
-
- public int check() {
- return cval;
- }
- }
-
- static class GenericConstructorTestHelper<T, S extends T, E extends Exception> {
- public GenericConstructorTestHelper(T t, S s) {}
- public GenericConstructorTestHelper() throws E{}
- }
-
- static class NoPublicConstructorTestHelper {
- // This class has no public constructor.
- }
-
-// Used to test synthetic constructor.
-//
-// static class Outer {
-// private Outer(){}
-// class Inner {
-// {new Outer();}
-// }
-// }
-
- public void test_getParameterAnnotations() throws Exception {
- Constructor<ConstructorTestHelper> ctor1 = ConstructorTestHelper.class
- .getConstructor(Object.class);
- Annotation[][] paramAnnotations = ctor1.getParameterAnnotations();
- assertEquals("Annotations for wrong number of parameters returned", 1,
- paramAnnotations.length);
- assertEquals("Wrong number of annotations returned", 2,
- paramAnnotations[0].length);
-
- Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
- ignoreOrder.add(paramAnnotations[0][0].annotationType());
- ignoreOrder.add(paramAnnotations[0][1].annotationType());
-
- assertTrue("Missing ConstructorTestAnnotationRuntime0", ignoreOrder
- .contains(ConstructorTestAnnotationRuntime0.class));
- assertTrue("Missing ConstructorTestAnnotationRuntime1", ignoreOrder
- .contains(ConstructorTestAnnotationRuntime1.class));
- }
-
-
- public void test_getDeclaredAnnotations() throws Exception {
- Constructor<ConstructorTestHelper> ctor1 = null;
- ctor1 = ConstructorTestHelper.class.getConstructor(new Class[0]);
- Annotation[] annotations = ctor1.getDeclaredAnnotations();
- assertEquals("Wrong number of annotations returned", 2,
- annotations.length);
- Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
- ignoreOrder.add(annotations[0].annotationType());
- ignoreOrder.add(annotations[1].annotationType());
-
- assertTrue("Missing ConstructorTestAnnotationRuntime0", ignoreOrder
- .contains(ConstructorTestAnnotationRuntime0.class));
- assertTrue("Missing ConstructorTestAnnotationRuntime1", ignoreOrder
- .contains(ConstructorTestAnnotationRuntime1.class));
- }
-
- public void test_isVarArgs() throws Exception {
- Constructor<ConstructorTestHelper> varArgCtor = ConstructorTestHelper.class
- .getConstructor(String[].class);
- assertTrue("Vararg constructor not recognized", varArgCtor.isVarArgs());
-
- Constructor<ConstructorTestHelper> nonVarArgCtor = ConstructorTestHelper.class
- .getConstructor(Object.class);
- assertFalse("Non vararg constructor recognized as vararg constructor",
- nonVarArgCtor.isVarArgs());
- }
-
- public void test_hashCode() throws Exception {
- Constructor<ConstructorTestHelper> constructor = ConstructorTestHelper.class
- .getConstructor();
- assertEquals(
- "The constructor's hashCode is not equal to the hashCode of the name of the declaring class",
- ConstructorTestHelper.class.getName().hashCode(), constructor
- .hashCode());
- }
-
- @SuppressWarnings("unchecked")
- public void test_toGenericString() throws Exception {
- Constructor<GenericConstructorTestHelper> genericCtor = GenericConstructorTestHelper.class
- .getConstructor(Object.class, Object.class);
- assertEquals(
- "Wrong generic string returned",
- "public tests.api.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper(T,S)",
- genericCtor.toGenericString());
- Constructor<GenericConstructorTestHelper> ctor = GenericConstructorTestHelper.class
- .getConstructor();
- assertEquals(
- "Wrong generic string returned",
- "public tests.api.java.lang.reflect.ConstructorTest$GenericConstructorTestHelper() throws E",
- ctor.toGenericString());
- }
-
- public void test_equalsLjava_lang_Object() {
- Constructor<ConstructorTestHelper> ctor1 = null, ctor2 = null;
- try {
- ctor1 = ConstructorTestHelper.class.getConstructor(
- new Class[0]);
- ctor2 = ConstructorTestHelper.class.getConstructor(Object.class);
- } catch (Exception e) {
- fail("Exception during equals test : " + e.getMessage());
- }
- assertTrue("Different Contructors returned equal", !ctor1.equals(ctor2));
- }
-
- public void test_getDeclaringClass() {
- boolean val = false;
- try {
- Class<? extends ConstructorTestHelper> pclass = new ConstructorTestHelper().getClass();
- Constructor<? extends ConstructorTestHelper> ctor = pclass.getConstructor(new Class[0]);
- val = ctor.getDeclaringClass().equals(pclass);
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- assertTrue("Returned incorrect declaring class", val);
- }
-
- public void test_getExceptionTypes() {
- // Test for method java.lang.Class []
- // java.lang.reflect.Constructor.getExceptionTypes()
- Class[] exceptions = null;
- Class<? extends IndexOutOfBoundsException> ex = null;
- try {
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
- .getConstructor(new Class[0]);
- exceptions = ctor.getExceptionTypes();
- ex = new IndexOutOfBoundsException().getClass();
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- assertEquals("Returned exception list of incorrect length",
- 1, exceptions.length);
- assertTrue("Returned incorrect exception", exceptions[0].equals(ex));
- }
-
- public void test_getModifiers() {
- // Test for method int java.lang.reflect.Constructor.getModifiers()
- int mod = 0;
- try {
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
- .getConstructor(new Class[0]);
- mod = ctor.getModifiers();
- assertTrue("Returned incorrect modifers for public ctor",
- ((mod & Modifier.PUBLIC) == Modifier.PUBLIC)
- && ((mod & Modifier.PRIVATE) == 0));
- } catch (NoSuchMethodException e) {
- fail("Exception during test : " + e.getMessage());
- }
- try {
- Class[] cl = { int.class };
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
- .getDeclaredConstructor(cl);
- mod = ctor.getModifiers();
- assertTrue("Returned incorrect modifers for private ctor",
- ((mod & Modifier.PRIVATE) == Modifier.PRIVATE)
- && ((mod & Modifier.PUBLIC) == 0));
- } catch (NoSuchMethodException e) {
- fail("Exception during test : " + e.getMessage());
- }
- try {
- Class[] cl = { long.class };
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
- .getDeclaredConstructor(cl);
- mod = ctor.getModifiers();
- assertTrue("Returned incorrect modifers for private ctor",
- ((mod & Modifier.PROTECTED) == Modifier.PROTECTED)
- && ((mod & Modifier.PUBLIC) == 0));
- } catch (NoSuchMethodException e) {
- fail("NoSuchMethodException during test : " + e.getMessage());
- }
- }
-
- public void test_getName() {
- // Test for method java.lang.String
- // java.lang.reflect.Constructor.getName()
- try {
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
- .getConstructor(new Class[0]);
- assertTrue(
- "Returned incorrect name: " + ctor.getName(),
- ctor
- .getName()
- .equals(
- "tests.api.java.lang.reflect.ConstructorTest$ConstructorTestHelper"));
- } catch (Exception e) {
- fail("Exception obtaining contructor : " + e.getMessage());
- }
- }
-
- public void test_getParameterTypes() {
- // Test for method java.lang.Class []
- // java.lang.reflect.Constructor.getParameterTypes()
- Class[] types = null;
- try {
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
- .getConstructor(new Class[0]);
- types = ctor.getParameterTypes();
- } catch (Exception e) {
- fail("Exception during getParameterTypes test:"
- + e.toString());
- }
- assertEquals("Incorrect parameter returned", 0, types.length);
-
- Class[] parms = null;
- try {
- parms = new Class[1];
- parms[0] = new Object().getClass();
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
- .getConstructor(parms);
- types = ctor.getParameterTypes();
- } catch (Exception e) {
- fail("Exception during getParameterTypes test:"
- + e.toString());
- }
- assertTrue("Incorrect parameter returned", types[0].equals(parms[0]));
- }
-
- @SuppressWarnings("unchecked")
- public void test_getGenericParameterTypes() {
- Type[] types = null;
- try {
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
- .getClass().getConstructor(new Class[0]);
- types = ctor.getGenericParameterTypes();
- } catch (Exception e) {
- fail("Exception during getParameterTypes test:" + e.toString());
- }
- assertEquals("Incorrect parameter returned", 0, types.length);
-
- Class<?>[] parms = null;
- try {
- parms = new Class[] {Object.class};
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
- .getClass().getConstructor(parms);
- types = ctor.getGenericParameterTypes();
- } catch (Exception e) {
- fail("Exception during getParameterTypes test:" + e.toString());
- }
- assertTrue("Incorrect parameter returned", types[0].equals(parms[0]));
-
-
- try {
- Constructor<GenericConstructorTestHelper> constructor = GenericConstructorTestHelper.class
- .getConstructor(Object.class, Object.class);
- types = constructor.getGenericParameterTypes();
- } catch (Exception e) {
- fail("Exception during getParameterTypes test:" + e.toString());
- }
-
- assertEquals("Wrong number of parameter types returned", 2,
- types.length);
-
- assertEquals("Wrong number of parameter types returned", "T",
- ((TypeVariable)types[0]).getName());
- assertEquals("Wrong number of parameter types returned", "S",
- ((TypeVariable)types[1]).getName());
- }
-
- @SuppressWarnings("unchecked")
- public void test_getGenericExceptionTypes() {
- Type[] types = null;
-
- try {
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper()
- .getClass().getConstructor(new Class[0]);
- types = ctor.getGenericExceptionTypes();
- } catch (Exception e) {
- fail("Exception during getGenericExceptionTypes test:" + e.toString());
- }
- assertEquals("Wrong number of exception types returned", 1, types.length);
-
-
- try {
- Constructor<GenericConstructorTestHelper> constructor = GenericConstructorTestHelper.class
- .getConstructor();
- types = constructor.getGenericExceptionTypes();
- } catch (Exception e) {
- fail("Exception during getGenericExceptionTypes test:"
- + e.toString());
- }
-
- assertEquals("Wrong number of exception types returned", 1,
- types.length);
-
- assertEquals("Wrong exception name returned.", "E",
- ((TypeVariable)types[0]).getName());
-
- }
-
-
- public void test_newInstance$Ljava_lang_Object() {
- // Test for method java.lang.Object
- // java.lang.reflect.Constructor.newInstance(java.lang.Object [])
-
- ConstructorTestHelper test = null;
- try {
- Constructor<? extends ConstructorTestHelper> ctor = new ConstructorTestHelper().getClass()
- .getConstructor(new Class[0]);
- test = ctor.newInstance((Object[])null);
- } catch (Exception e) {
- fail("Failed to create instance : " + e.getMessage());
- }
- assertEquals("improper instance created", 99, test.check());
- }
-
- public void test_toString() {
- // Test for method java.lang.String
- // java.lang.reflect.Constructor.toString()
- Class[] parms = null;
- Constructor<? extends ConstructorTestHelper> ctor = null;
- try {
- parms = new Class[1];
- parms[0] = new Object().getClass();
- ctor = new ConstructorTestHelper().getClass().getConstructor(parms);
- } catch (Exception e) {
- fail("Exception during getParameterTypes test:"
- + e.toString());
- }
- assertTrue(
- "Returned incorrect string representation: " + ctor.toString(),
- ctor
- .toString()
- .equals(
- "public tests.api.java.lang.reflect.ConstructorTest$ConstructorTestHelper(java.lang.Object)"));
- }
-
- public void test_getConstructor() throws Exception {
- // Passing new Class[0] should be equivalent to (Class[]) null.
- Class<ConstructorTestHelper> c2 = ConstructorTestHelper.class;
- assertEquals(c2.getConstructor(new Class[0]), c2.getConstructor((Class[]) null));
- assertEquals(c2.getDeclaredConstructor(new Class[0]),
- c2.getDeclaredConstructor((Class[]) null));
-
- // We can get a non-public constructor via getDeclaredConstructor...
- Class<NoPublicConstructorTestHelper> c1 = NoPublicConstructorTestHelper.class;
- c1.getDeclaredConstructor((Class[]) null);
- // ...but not with getConstructor (which only returns public constructors).
- try {
- c1.getConstructor((Class[]) null);
- fail("Should throw NoSuchMethodException");
- } catch (NoSuchMethodException ex) {
- // Expected.
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/FieldTest.java b/luni/src/test/java/tests/api/java/lang/reflect/FieldTest.java
deleted file mode 100644
index a1ca151..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/FieldTest.java
+++ /dev/null
@@ -1,1868 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import tests.support.Support_Field;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.HashSet;
-import java.util.Set;
-
-public class FieldTest extends junit.framework.TestCase {
-
- // BEGIN android-note
- // This test had a couple of bugs in it. Some parts of the code were
- // unreachable before. Also some tests expected the wrong excpetions
- // to be thrown. This version has been validated to pass on a standard
- // JDK 1.5.
- // END android-note
-
- public class TestClass {
- @AnnotationRuntime0
- @AnnotationRuntime1
- @AnnotationClass0
- @AnnotationSource0
- public int annotatedField;
- class Inner{}
- }
-
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target( {ElementType.FIELD})
- static @interface AnnotationRuntime0 {
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target( { ElementType.FIELD})
- static @interface AnnotationRuntime1 {
- }
-
- @Retention(RetentionPolicy.CLASS)
- @Target( { ElementType.FIELD})
- static @interface AnnotationClass0 {
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @Target( {ElementType.FIELD})
- static @interface AnnotationSource0 {
- }
-
- @Inherited
- @Retention(RetentionPolicy.RUNTIME)
- @Target( {ElementType.FIELD})
- static @interface InheritedRuntime {
- }
-
- public class GenericField<S, T extends Number> {
- S field;
- T boundedField;
- int intField;
- }
-
-
- static class TestField {
- public static int pubfield1;
-
- private static int privfield1 = 123;
-
- protected int intField = Integer.MAX_VALUE;
- protected final int intFField = Integer.MAX_VALUE;
- protected static int intSField = Integer.MAX_VALUE;
- private final int intPFField = Integer.MAX_VALUE;
-
- protected short shortField = Short.MAX_VALUE;
- protected final short shortFField = Short.MAX_VALUE;
- protected static short shortSField = Short.MAX_VALUE;
- private final short shortPFField = Short.MAX_VALUE;
-
- protected boolean booleanField = true;
- protected static boolean booleanSField = true;
- protected final boolean booleanFField = true;
- private final boolean booleanPFField = true;
-
- protected byte byteField = Byte.MAX_VALUE;
- protected static byte byteSField = Byte.MAX_VALUE;
- protected final byte byteFField = Byte.MAX_VALUE;
- private final byte bytePFField = Byte.MAX_VALUE;
-
- protected long longField = Long.MAX_VALUE;
- protected final long longFField = Long.MAX_VALUE;
- protected static long longSField = Long.MAX_VALUE;
- private final long longPFField = Long.MAX_VALUE;
-
- protected double doubleField = Double.MAX_VALUE;
- protected static double doubleSField = Double.MAX_VALUE;
- protected static final double doubleSFField = Double.MAX_VALUE;
- protected final double doubleFField = Double.MAX_VALUE;
- private final double doublePFField = Double.MAX_VALUE;
-
- protected float floatField = Float.MAX_VALUE;
- protected final float floatFField = Float.MAX_VALUE;
- protected static float floatSField = Float.MAX_VALUE;
- private final float floatPFField = Float.MAX_VALUE;
-
- protected char charField = 'T';
- protected static char charSField = 'T';
- private final char charPFField = 'T';
-
- protected final char charFField = 'T';
-
- private static final int x = 1;
-
- public volatile transient int y = 0;
-
- protected static transient volatile int prsttrvol = 99;
- }
-
- public class TestFieldSub1 extends TestField {
- }
-
- public class TestFieldSub2 extends TestField {
- }
-
- static class A {
- protected short shortField = Short.MAX_VALUE;
- }
-
- static enum TestEnum {
- A, B, C;
- int field;
- }
-
- /**
- * java.lang.reflect.Field#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- // Test for method boolean
- // java.lang.reflect.Field.equals(java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- try {
- f = x.getClass().getDeclaredField("shortField");
- } catch (Exception e) {
- fail("Exception during getType test : " + e.getMessage());
- }
- try {
- assertTrue("Same Field returned false", f.equals(f));
- assertTrue("Inherited Field returned false", f.equals(x.getClass()
- .getDeclaredField("shortField")));
- assertTrue("Identical Field from different class returned true", !f
- .equals(A.class.getDeclaredField("shortField")));
- } catch (Exception e) {
- fail("Exception during getType test : " + e.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.Field#get(java.lang.Object)
- */
- public void test_getLjava_lang_Object() throws Throwable {
- // Test for method java.lang.Object
- // java.lang.reflect.Field.get(java.lang.Object)
- TestField x = new TestField();
- Field f = x.getClass().getDeclaredField("doubleField");
- Double val = (Double) f.get(x);
-
- assertTrue("Returned incorrect double field value",
- val.doubleValue() == Double.MAX_VALUE);
- // Test getting a static field;
- f = x.getClass().getDeclaredField("doubleSField");
- f.set(x, new Double(1.0));
- val = (Double) f.get(x);
- assertEquals("Returned incorrect double field value", 1.0, val
- .doubleValue());
-
- // Try a get on a private field
- boolean thrown = false;
- try {
- f = TestAccess.class.getDeclaredField("xxx");
- assertNotNull(f);
- f.get(null);
- fail("No expected IllegalAccessException");
- } catch (IllegalAccessException ok) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- // Try a get on a private field in nested member
- // temporarily commented because it breaks J9 VM
- // Regression for HARMONY-1309
- //f = x.getClass().getDeclaredField("privfield1");
- //assertEquals(x.privfield1, f.get(x));
-
- // Try a get using an invalid class.
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.get(new String());
- fail("No expected IllegalArgumentException");
- } catch (IllegalArgumentException exc) {
- // Correct - Passed an Object that does not declare or inherit f
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = TestField.class.getDeclaredField("intField");
- f.get(null);
- fail("Expected NullPointerException not thrown");
- } catch (NullPointerException exc) {
- // Correct - Passed an Object that does not declare or inherit f
- thrown = true;
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static fields
- thrown = false;
- try {
- f = TestField.class.getDeclaredField("doubleSField");
- f.get(null);
- assertTrue("Exception thrown", true);
- } catch (Exception exc) {
- fail("No exception expected");
- }
- }
-
- class SupportSubClass extends Support_Field {
-
- Object getField(char primitiveType, Object o, Field f,
- Class expectedException) {
- Object res = null;
- try {
- primitiveType = Character.toUpperCase(primitiveType);
- switch (primitiveType) {
- case 'I': // int
- res = new Integer(f.getInt(o));
- break;
- case 'J': // long
- res = new Long(f.getLong(o));
- break;
- case 'Z': // boolean
- res = new Boolean(f.getBoolean(o));
- break;
- case 'S': // short
- res = new Short(f.getShort(o));
- break;
- case 'B': // byte
- res = new Byte(f.getByte(o));
- break;
- case 'C': // char
- res = new Character(f.getChar(o));
- break;
- case 'D': // double
- res = new Double(f.getDouble(o));
- break;
- case 'F': // float
- res = new Float(f.getFloat(o));
- break;
- default:
- res = f.get(o);
- }
- if (expectedException != null) {
- fail("expected exception " + expectedException.getName());
- }
- } catch (Exception e) {
- if (expectedException == null) {
- fail("unexpected exception " + e);
- } else {
- assertTrue("expected exception "
- + expectedException.getName() + " and got " + e, e
- .getClass().equals(expectedException));
- }
- }
- return res;
- }
-
- void setField(char primitiveType, Object o, Field f,
- Class expectedException, Object value) {
- try {
- primitiveType = Character.toUpperCase(primitiveType);
- switch (primitiveType) {
- case 'I': // int
- f.setInt(o, ((Integer) value).intValue());
- break;
- case 'J': // long
- f.setLong(o, ((Long) value).longValue());
- break;
- case 'Z': // boolean
- f.setBoolean(o, ((Boolean) value).booleanValue());
- break;
- case 'S': // short
- f.setShort(o, ((Short) value).shortValue());
- break;
- case 'B': // byte
- f.setByte(o, ((Byte) value).byteValue());
- break;
- case 'C': // char
- f.setChar(o, ((Character) value).charValue());
- break;
- case 'D': // double
- f.setDouble(o, ((Double) value).doubleValue());
- break;
- case 'F': // float
- f.setFloat(o, ((Float) value).floatValue());
- break;
- default:
- f.set(o, value);
- }
- if (expectedException != null) {
- fail("expected exception " + expectedException.getName()
- + " for field " + f.getName() + ", value " + value);
- }
- } catch (Exception e) {
- if (expectedException == null) {
- fail("unexpected exception " + e + " for field "
- + f.getName() + ", value " + value);
- } else {
- assertTrue("expected exception "
- + expectedException.getName() + " and got " + e
- + " for field " + f.getName() + ", value " + value,
- e.getClass().equals(expectedException));
- }
- }
- }
- }
-
- /**
- * java.lang.reflect.Field#get(java.lang.Object)
- * java.lang.reflect.Field#getByte(java.lang.Object)
- * java.lang.reflect.Field#getBoolean(java.lang.Object)
- * java.lang.reflect.Field#getShort(java.lang.Object)
- * java.lang.reflect.Field#getInt(java.lang.Object)
- * java.lang.reflect.Field#getLong(java.lang.Object)
- * java.lang.reflect.Field#getFloat(java.lang.Object)
- * java.lang.reflect.Field#getDouble(java.lang.Object)
- * java.lang.reflect.Field#getChar(java.lang.Object)
- * java.lang.reflect.Field#set(java.lang.Object, java.lang.Object)
- * java.lang.reflect.Field#setByte(java.lang.Object, byte)
- * java.lang.reflect.Field#setBoolean(java.lang.Object, boolean)
- * java.lang.reflect.Field#setShort(java.lang.Object, short)
- * java.lang.reflect.Field#setInt(java.lang.Object, int)
- * java.lang.reflect.Field#setLong(java.lang.Object, long)
- * java.lang.reflect.Field#setFloat(java.lang.Object, float)
- * java.lang.reflect.Field#setDouble(java.lang.Object, double)
- * java.lang.reflect.Field#setChar(java.lang.Object, char)
- */
- public void testProtectedFieldAccess() {
- Class fieldClass = new Support_Field().getClass();
- String fieldName = null;
- Field objectField = null;
- Field booleanField = null;
- Field byteField = null;
- Field charField = null;
- Field shortField = null;
- Field intField = null;
- Field longField = null;
- Field floatField = null;
- Field doubleField = null;
- try {
- fieldName = "objectField";
- objectField = fieldClass.getDeclaredField(fieldName);
-
- fieldName = "booleanField";
- booleanField = fieldClass.getDeclaredField(fieldName);
-
- fieldName = "byteField";
- byteField = fieldClass.getDeclaredField(fieldName);
-
- fieldName = "charField";
- charField = fieldClass.getDeclaredField(fieldName);
-
- fieldName = "shortField";
- shortField = fieldClass.getDeclaredField(fieldName);
-
- fieldName = "intField";
- intField = fieldClass.getDeclaredField(fieldName);
-
- fieldName = "longField";
- longField = fieldClass.getDeclaredField(fieldName);
-
- fieldName = "floatField";
- floatField = fieldClass.getDeclaredField(fieldName);
-
- fieldName = "doubleField";
- doubleField = fieldClass.getDeclaredField(fieldName);
- } catch (NoSuchFieldException e) {
- fail("missing field " + fieldName + " in test support class "
- + fieldClass.getName());
- }
-
- // create the various objects that might or might not have an instance
- // of the field
- Support_Field parentClass = new Support_Field();
- SupportSubClass subclass = new SupportSubClass();
- SupportSubClass otherSubclass = new SupportSubClass();
- Object plainObject = new Object();
-
- Class illegalAccessExceptionClass = new IllegalAccessException()
- .getClass();
- Class illegalArgumentExceptionClass = new IllegalArgumentException()
- .getClass();
-
- // The test will attempt to use pass an object to set for object, byte,
- // short, ..., float and double fields
- // and pass a byte to to setByte for byte, short, ..., float and double
- // fields and so on.
- // It will also test if IllegalArgumentException is thrown when the
- // field does not exist in the given object and that
- // IllegalAccessException is thrown when trying to access an
- // inaccessible protected field.
- // The test will also check that IllegalArgumentException is thrown for
- // all other attempts.
-
- // Ordered by widening conversion, except for 'L' at the beg (which
- // stands for Object).
- // If the object provided to set can be unwrapped to a primitive, then
- // the set method can set
- // primitive fields.
- char types[] = { 'L', 'B', 'S', 'C', 'I', 'J', 'F', 'D' };
- Field fields[] = { objectField, byteField, shortField, charField,
- intField, longField, floatField, doubleField };
- Object values[] = { new Byte((byte) 1), new Byte((byte) 1),
- new Short((short) 1), new Character((char) 1), new Integer(1),
- new Long(1), new Float(1), new Double(1) };
-
- // test set methods
- for (int i = 0; i < types.length; i++) {
- char type = types[i];
- Object value = values[i];
- for (int j = i; j < fields.length; j++) {
- Field field = fields[j];
- fieldName = field.getName();
-
- if (field == charField && type != 'C') {
- // the exception is that bytes and shorts CANNOT be
- // converted into chars even though chars CAN be
- // converted into ints, longs, floats and doubles
- subclass.setField(type, subclass, field,
- illegalArgumentExceptionClass, value);
- } else {
- // setting type into field);
- subclass.setField(type, subclass, field, null, value);
- subclass.setField(type, otherSubclass, field, null, value);
- subclass.setField(type, parentClass, field,
- illegalAccessExceptionClass, value);
- subclass.setField(type, plainObject, field,
- // Failed on JDK.
- illegalAccessExceptionClass, value);
- }
- }
- for (int j = 0; j < i; j++) {
- Field field = fields[j];
- fieldName = field.getName();
- // not setting type into field);
- subclass.setField(type, subclass, field,
- illegalArgumentExceptionClass, value);
- }
- }
-
- // test setBoolean
- Boolean booleanValue = Boolean.TRUE;
- subclass.setField('Z', subclass, booleanField, null, booleanValue);
- subclass.setField('Z', otherSubclass, booleanField, null, booleanValue);
- subclass.setField('Z', parentClass, booleanField,
- illegalAccessExceptionClass, booleanValue);
- subclass.setField('Z', plainObject, booleanField,
- // Failed on JDK
- illegalAccessExceptionClass, booleanValue);
- for (int j = 0; j < fields.length; j++) {
- Field listedField = fields[j];
- fieldName = listedField.getName();
- // not setting boolean into listedField
- subclass.setField('Z', subclass, listedField,
- illegalArgumentExceptionClass, booleanValue);
- }
- for (int i = 0; i < types.length; i++) {
- char type = types[i];
- Object value = values[i];
- subclass.setField(type, subclass, booleanField,
- illegalArgumentExceptionClass, value);
- }
-
- // We perform the analagous test on the get methods.
-
- // ordered by widening conversion, except for 'L' at the end (which
- // stands for Object), to which all primitives can be converted by
- // wrapping
- char newTypes[] = new char[] { 'B', 'S', 'C', 'I', 'J', 'F', 'D', 'L' };
- Field newFields[] = { byteField, shortField, charField, intField,
- longField, floatField, doubleField, objectField };
- fields = newFields;
- types = newTypes;
- // test get methods
- for (int i = 0; i < types.length; i++) {
- char type = types[i];
- for (int j = 0; j <= i; j++) {
- Field field = fields[j];
- fieldName = field.getName();
- if (type == 'C' && field != charField) {
- // the exception is that bytes and shorts CANNOT be
- // converted into chars even though chars CAN be
- // converted into ints, longs, floats and doubles
- subclass.getField(type, subclass, field,
- illegalArgumentExceptionClass);
- } else {
- // getting type from field
- subclass.getField(type, subclass, field, null);
- subclass.getField(type, otherSubclass, field, null);
- subclass.getField(type, parentClass, field,
- illegalAccessExceptionClass);
- subclass.getField(type, plainObject, field,
- illegalAccessExceptionClass);
- }
- }
- for (int j = i + 1; j < fields.length; j++) {
- Field field = fields[j];
- fieldName = field.getName();
- subclass.getField(type, subclass, field,
- illegalArgumentExceptionClass);
- }
- }
-
- // test getBoolean
- subclass.getField('Z', subclass, booleanField, null);
- subclass.getField('Z', otherSubclass, booleanField, null);
- subclass.getField('Z', parentClass, booleanField,
- illegalAccessExceptionClass);
- subclass.getField('Z', plainObject, booleanField,
- illegalAccessExceptionClass);
- for (int j = 0; j < fields.length; j++) {
- Field listedField = fields[j];
- fieldName = listedField.getName();
- // not getting boolean from listedField
- subclass.getField('Z', subclass, listedField,
- illegalArgumentExceptionClass);
- }
- for (int i = 0; i < types.length - 1; i++) {
- char type = types[i];
- subclass.getField(type, subclass, booleanField,
- illegalArgumentExceptionClass);
- }
- Object res = subclass.getField('L', subclass, booleanField, null);
- assertTrue("unexpected object " + res, res instanceof Boolean);
- }
-
- /**
- * java.lang.reflect.Field#getBoolean(java.lang.Object)
- */
- public void test_getBooleanLjava_lang_Object() {
- TestField x = new TestField();
- Field f = null;
- boolean val = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- val = f.getBoolean(x);
- } catch (Exception e) {
- fail("Exception during getBoolean test: " + e.toString());
- }
- assertTrue("Returned incorrect boolean field value", val);
-
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.getBoolean(x);
- fail("IllegalArgumentException expected but not thrown");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalArgumentException expected but not thrown");
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanPFField");
- f.getBoolean(x);
- fail("IllegalAccessException expected but not thrown");
- } catch (IllegalAccessException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalAccessException expected but not thrown"
- + ex.getMessage());
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.getBoolean(null);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static field
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanSField");
- boolean staticValue = f.getBoolean(null);
- assertTrue("Wrong value returned", staticValue);
- } catch (Exception ex) {
- fail("No exception expected");
- }
- }
-
-
- /**
- * java.lang.reflect.Field#getByte(java.lang.Object)
- */
- public void test_getByteLjava_lang_Object() {
- // Test for method byte
- // java.lang.reflect.Field.getByte(java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- byte val = 0;
- try {
- f = x.getClass().getDeclaredField("byteField");
- val = f.getByte(x);
- } catch (Exception e) {
- fail("Exception during getbyte test : " + e.getMessage());
- }
- assertTrue("Returned incorrect byte field value", val == Byte.MAX_VALUE);
-
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.getByte(x);
- fail("IllegalArgumentException expected but not thrown");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalArgumentException expected but not thrown");
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("bytePFField");
- f.getByte(x);
- fail("IllegalAccessException expected but not thrown");
- } catch (IllegalAccessException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalAccessException expected but not thrown"
- + ex.getMessage());
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("byteField");
- f.getByte(null);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static field
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("byteSField");
- byte staticValue = f.getByte(null);
- assertEquals("Wrong value returned", Byte.MAX_VALUE, staticValue);
- } catch (Exception ex) {
- fail("No exception expected "+ ex.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.Field#getChar(java.lang.Object)
- */
- public void test_getCharLjava_lang_Object() {
- // Test for method char
- // java.lang.reflect.Field.getChar(java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- char val = 0;
- try {
- f = x.getClass().getDeclaredField("charField");
- val = f.getChar(x);
- } catch (Exception e) {
- fail("Exception during getCharacter test: " + e.toString());
- }
- assertEquals("Returned incorrect char field value", 'T', val);
-
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.getChar(x);
- fail("IllegalArgumentException expected but not thrown");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalArgumentException expected but not thrown");
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("charPFField");
- f.getChar(x);
- fail("IllegalAccessException expected but not thrown");
- } catch (IllegalAccessException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalAccessException expected but not thrown"
- + ex.getMessage());
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("charField");
- f.getChar(null);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static field
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("charSField");
- char staticValue = f.getChar(null);
- assertEquals("Wrong value returned", 'T', staticValue);
- } catch (Exception ex) {
- fail("No exception expected "+ ex.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.Field#getDeclaringClass()
- */
- public void test_getDeclaringClass() {
- // Test for method java.lang.Class
- // java.lang.reflect.Field.getDeclaringClass()
- Field[] fields;
-
- try {
- fields = new TestField().getClass().getFields();
- assertTrue("Returned incorrect declaring class", fields[0]
- .getDeclaringClass().equals(new TestField().getClass()));
-
- // Check the case where the field is inherited to be sure the parent
- // is returned as the declarator
- fields = new TestFieldSub1().getClass().getFields();
- assertTrue("Returned incorrect declaring class", fields[0]
- .getDeclaringClass().equals(new TestField().getClass()));
- } catch (Exception e) {
- fail("Exception : " + e.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.Field#getDouble(java.lang.Object)
- */
- public void test_getDoubleLjava_lang_Object() {
- // Test for method double
- // java.lang.reflect.Field.getDouble(java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- double val = 0.0;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- val = f.getDouble(x);
- } catch (Exception e) {
- fail("Exception during getDouble test: " + e.toString());
- }
- assertTrue("Returned incorrect double field value",
- val == Double.MAX_VALUE);
-
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.getDouble(x);
- fail("IllegalArgumentException expected but not thrown");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalArgumentException expected but not thrown "
- + ex.getMessage());
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("doublePFField");
- f.getDouble(x);
- fail("IllegalAccessException expected but not thrown");
- } catch (IllegalAccessException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalAccessException expected but not thrown"
- + ex.getMessage());
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.getDouble(null);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static field
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleSFField");
- double staticValue = f.getDouble(null);
- assertEquals("Wrong value returned", Double.MAX_VALUE, staticValue);
- } catch (Exception ex) {
- fail("No exception expected "+ ex.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.Field#getFloat(java.lang.Object)
- */
- public void test_getFloatLjava_lang_Object() {
- // Test for method float
- // java.lang.reflect.Field.getFloat(java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- float val = 0;
- try {
- f = x.getClass().getDeclaredField("floatField");
- val = f.getFloat(x);
- } catch (Exception e) {
- fail("Exception during getFloat test : " + e.getMessage());
- }
- assertTrue("Returned incorrect float field value",
- val == Float.MAX_VALUE);
-
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.getFloat(x);
- fail("IllegalArgumentException expected but not thrown");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalArgumentException expected but not thrown "
- + ex.getMessage());
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("floatPFField");
- f.getFloat(x);
- fail("IllegalAccessException expected but not thrown");
- } catch (IllegalAccessException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalAccessException expected but not thrown"
- + ex.getMessage());
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("floatField");
- f.getFloat(null);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static field
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("floatSField");
- float staticValue = f.getFloat(null);
- assertEquals("Wrong value returned", Float.MAX_VALUE, staticValue);
- } catch (Exception ex) {
- fail("No exception expected "+ ex.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.Field#getInt(java.lang.Object)
- */
- public void test_getIntLjava_lang_Object() {
- // Test for method int java.lang.reflect.Field.getInt(java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- int val = 0;
- try {
- f = x.getClass().getDeclaredField("intField");
- val = f.getInt(x);
- } catch (Exception e) {
- fail("Exception during getInt test : " + e.getMessage());
- }
- assertTrue("Returned incorrect Int field value",
- val == Integer.MAX_VALUE);
-
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.getInt(x);
- fail("IllegalArgumentException expected but not thrown");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalArgumentException expected but not thrown "
- + ex.getMessage());
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("intPFField");
- f.getInt(x);
- fail("IllegalAccessException expected but not thrown");
- } catch (IllegalAccessException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalAccessException expected but not thrown"
- + ex.getMessage());
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("intField");
- f.getInt(null);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static field
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("intSField");
- int staticValue = f.getInt(null);
- assertEquals("Wrong value returned", Integer.MAX_VALUE, staticValue);
- } catch (Exception ex) {
- fail("No exception expected " + ex.getMessage());
- }
-
- }
-
- /**
- * java.lang.reflect.Field#getLong(java.lang.Object)
- */
- public void test_getLongLjava_lang_Object() {
- // Test for method long
- // java.lang.reflect.Field.getLong(java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- long val = 0;
- try {
- f = x.getClass().getDeclaredField("longField");
- val = f.getLong(x);
- } catch (Exception e) {
- fail("Exception during getLong test : " + e.getMessage());
- }
-
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.getLong(x);
- fail("IllegalArgumentException expected but not thrown");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalArgumentException expected but not thrown "
- + ex.getMessage());
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("longPFField");
- f.getLong(x);
- fail("IllegalAccessException expected but not thrown");
- } catch (IllegalAccessException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalAccessException expected but not thrown"
- + ex.getMessage());
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("longField");
- f.getLong(null);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static field
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("longSField");
- long staticValue = f.getLong(null);
- assertEquals("Wrong value returned", Long.MAX_VALUE, staticValue);
- } catch (Exception ex) {
- fail("No exception expected "+ ex.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.Field#getModifiers()
- */
- public void test_getModifiers() {
- // Test for method int java.lang.reflect.Field.getModifiers()
- TestField x = new TestField();
- Field f = null;
- try {
- f = x.getClass().getDeclaredField("prsttrvol");
- } catch (Exception e) {
- fail("Exception during getModifiers test: " + e.toString());
- }
- int mod = f.getModifiers();
- int mask = (Modifier.PROTECTED | Modifier.STATIC)
- | (Modifier.TRANSIENT | Modifier.VOLATILE);
- int nmask = (Modifier.PUBLIC | Modifier.NATIVE);
- assertTrue("Returned incorrect field modifiers: ",
- ((mod & mask) == mask) && ((mod & nmask) == 0));
- }
-
- /**
- * java.lang.reflect.Field#getName()
- */
- public void test_getName() {
- // Test for method java.lang.String java.lang.reflect.Field.getName()
- TestField x = new TestField();
- Field f = null;
- try {
- f = x.getClass().getDeclaredField("shortField");
- } catch (Exception e) {
- fail("Exception during getType test : " + e.getMessage());
- }
- assertEquals("Returned incorrect field name",
- "shortField", f.getName());
- }
-
- /**
- * java.lang.reflect.Field#getShort(java.lang.Object)
- */
- public void test_getShortLjava_lang_Object() {
- // Test for method short
- // java.lang.reflect.Field.getShort(java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- short val = 0;
- ;
- try {
- f = x.getClass().getDeclaredField("shortField");
- val = f.getShort(x);
- } catch (Exception e) {
- fail("Exception during getShort test : " + e.getMessage());
- }
- assertTrue("Returned incorrect short field value",
- val == Short.MAX_VALUE);
-
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.getShort(x);
- fail("IllegalArgumentException expected but not thrown");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalArgumentException expected but not thrown "
- + ex.getMessage());
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("shortPFField");
- f.getShort(x);
- fail("IllegalAccessException expected but not thrown");
- } catch (IllegalAccessException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("IllegalAccessException expected but not thrown"
- + ex.getMessage());
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("shortField");
- f.getShort(null);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- //Test no NPE on static field
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("shortSField");
- short staticValue = f.getShort(null);
- assertEquals("Wrong value returned", Short.MAX_VALUE, staticValue);
- } catch (Exception ex) {
- fail("No exception expected "+ ex.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.Field#getType()
- */
- public void test_getType() {
- // Test for method java.lang.Class java.lang.reflect.Field.getType()
- TestField x = new TestField();
- Field f = null;
- try {
- f = x.getClass().getDeclaredField("shortField");
- } catch (Exception e) {
- fail("Exception during getType test : " + e.getMessage());
- }
- assertTrue("Returned incorrect field type: " + f.getType().toString(),
- f.getType().equals(short.class));
- }
-
- /**
- * java.lang.reflect.Field#set(java.lang.Object, java.lang.Object)
- */
- public void test_setLjava_lang_ObjectLjava_lang_Object() throws Exception{
- // Test for method void java.lang.reflect.Field.set(java.lang.Object,
- // java.lang.Object)
- TestField x = new TestField();
- Field f = null;
- double val = 0.0;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.set(x, new Double(1.0));
- val = f.getDouble(x);
- } catch (Exception e) {
- fail("Exception during set test : " + e.getMessage());
- }
- assertEquals("Returned incorrect double field value", 1.0, val);
-
- //test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.set(x, new Double(1.0));
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- //test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleFField");
- assertFalse(f.isAccessible());
- f.set(x, new Double(1.0));
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.set(null, true);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("doubleSField");
- f.set(null, new Double(1.0));
- val = f.getDouble(x);
- assertEquals("Returned incorrect double field value", 1.0, val);
- }
-
- /**
- * java.lang.reflect.Field#setBoolean(java.lang.Object, boolean)
- */
- public void test_setBooleanLjava_lang_ObjectZ() throws Exception{
- // Test for method void
- // java.lang.reflect.Field.setBoolean(java.lang.Object, boolean)
- TestField x = new TestField();
- Field f = null;
- boolean val = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setBoolean(x, false);
- val = f.getBoolean(x);
- } catch (Exception e) {
- fail("Exception during setboolean test: " + e.toString());
- }
- assertTrue("Returned incorrect float field value", !val);
-
- //test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.setBoolean(x, false);
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- //test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanPFField");
- assertFalse(f.isAccessible());
- f.setBoolean(x, true);
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setBoolean(null, true);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("booleanSField");
- f.setBoolean(null, false);
- val = f.getBoolean(x);
- assertFalse("Returned incorrect boolean field value", val);
- }
-
- /**
- * java.lang.reflect.Field#setByte(java.lang.Object, byte)
- */
- public void test_setByteLjava_lang_ObjectB() throws Exception{
- // Test for method void
- // java.lang.reflect.Field.setByte(java.lang.Object, byte)
- TestField x = new TestField();
- Field f = null;
- byte val = 0;
- try {
- f = x.getClass().getDeclaredField("byteField");
- f.setByte(x, (byte) 1);
- val = f.getByte(x);
- } catch (Exception e) {
- fail("Exception during setByte test : " + e.getMessage());
- }
- assertEquals("Returned incorrect float field value", 1, val);
-
- //test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setByte(x, Byte.MIN_VALUE);
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- //test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("bytePFField");
- assertFalse(f.isAccessible());
- f.setByte(x, Byte.MIN_VALUE);
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("byteField");
- f.setByte(null, Byte.MIN_VALUE);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("byteSField");
- f.setByte(null, Byte.MIN_VALUE);
- val = f.getByte(x);
- assertEquals("Returned incorrect byte field value", Byte.MIN_VALUE,
- val);
- }
-
- /**
- * java.lang.reflect.Field#setChar(java.lang.Object, char)
- */
- public void test_setCharLjava_lang_ObjectC() throws Exception{
- // Test for method void
- // java.lang.reflect.Field.setChar(java.lang.Object, char)
- TestField x = new TestField();
- Field f = null;
- char val = 0;
- try {
- f = x.getClass().getDeclaredField("charField");
- f.setChar(x, (char) 1);
- val = f.getChar(x);
- } catch (Exception e) {
- fail("Exception during setChar test : " + e.getMessage());
- }
- assertEquals("Returned incorrect float field value", 1, val);
-
- //test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setChar(x, Character.MIN_VALUE);
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- //test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("charPFField");
- assertFalse(f.isAccessible());
- f.setChar(x, Character.MIN_VALUE);
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("charField");
- f.setChar(null, Character.MIN_VALUE);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("charSField");
- f.setChar(null, Character.MIN_VALUE);
- val = f.getChar(x);
- assertEquals("Returned incorrect char field value",
- Character.MIN_VALUE, val);
- }
-
- /**
- * java.lang.reflect.Field#setDouble(java.lang.Object, double)
- */
- public void test_setDoubleLjava_lang_ObjectD() throws Exception{
- // Test for method void
- // java.lang.reflect.Field.setDouble(java.lang.Object, double)
- TestField x = new TestField();
- Field f = null;
- double val = 0.0;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.setDouble(x, Double.MIN_VALUE);
- val = f.getDouble(x);
- } catch (Exception e) {
- fail("Exception during setDouble test: " + e.toString());
- }
- assertEquals("Returned incorrect double field value", Double.MIN_VALUE,
- val);
-
- //test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setDouble(x, Double.MIN_VALUE);
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- //test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("doublePFField");
- assertFalse(f.isAccessible());
- f.setDouble(x, Double.MIN_VALUE);
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("doubleField");
- f.setDouble(null, Double.MIN_VALUE);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("doubleSField");
- f.setDouble(null, Double.MIN_VALUE);
- val = f.getDouble(x);
- assertEquals("Returned incorrect double field value",
- Double.MIN_VALUE, val);
- }
-
- /**
- * java.lang.reflect.Field#setFloat(java.lang.Object, float)
- */
- public void test_setFloatLjava_lang_ObjectF() throws Exception{
- // Test for method void
- // java.lang.reflect.Field.setFloat(java.lang.Object, float)
- TestField x = new TestField();
- Field f = null;
- float val = 0.0F;
- try {
- f = x.getClass().getDeclaredField("floatField");
- f.setFloat(x, Float.MIN_VALUE);
- val = f.getFloat(x);
- } catch (Exception e) {
- fail("Exception during setFloat test : " + e.getMessage());
- }
- assertEquals("Returned incorrect float field value", Float.MIN_VALUE,
- val, 0.0);
-
- //test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setFloat(x, Float.MIN_VALUE);
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- //test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("floatPFField");
- assertFalse(f.isAccessible());
- f.setFloat(x, Float.MIN_VALUE);
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- //Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("floatField");
- f.setFloat(null, Float.MIN_VALUE);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("floatSField");
- f.setFloat(null, Float.MIN_VALUE);
- val = f.getFloat(x);
- assertEquals("Returned incorrect float field value",
- Float.MIN_VALUE, val);
- }
-
- /**
- * java.lang.reflect.Field#setInt(java.lang.Object, int)
- */
- public void test_setIntLjava_lang_ObjectI() throws Exception{
- // Test for method void java.lang.reflect.Field.setInt(java.lang.Object,
- // int)
- TestField x = new TestField();
- Field f = null;
- int val = 0;
- try {
- f = x.getClass().getDeclaredField("intField");
- f.setInt(x, Integer.MIN_VALUE);
- val = f.getInt(x);
- } catch (Exception e) {
- fail("Exception during setInteger test: " + e.toString());
- }
- assertEquals("Returned incorrect int field value", Integer.MIN_VALUE,
- val);
-
- // test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setInt(x, Integer.MIN_VALUE);
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- // test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("intPFField");
- assertFalse(f.isAccessible());
- f.setInt(x, Integer.MIN_VALUE);
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- // Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("intField");
- f.setInt(null, Integer.MIN_VALUE);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("intSField");
- f.setInt(null, Integer.MIN_VALUE);
- val = f.getInt(x);
- assertEquals("Returned incorrect int field value",
- Integer.MIN_VALUE, val);
- }
-
- /**
- * java.lang.reflect.Field#setLong(java.lang.Object, long)
- */
- public void test_setLongLjava_lang_ObjectJ() throws Exception{
- // Test for method void
- // java.lang.reflect.Field.setLong(java.lang.Object, long)
- TestField x = new TestField();
- Field f = null;
- long val = 0L;
- try {
- f = x.getClass().getDeclaredField("longField");
- f.setLong(x, Long.MIN_VALUE);
- val = f.getLong(x);
- } catch (Exception e) {
- fail("Exception during setLong test : " + e.getMessage());
- }
- assertEquals("Returned incorrect long field value", Long.MIN_VALUE, val);
-
- // test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setLong(x, Long.MIN_VALUE);
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- // test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("longPFField");
- assertFalse(f.isAccessible());
- f.setLong(x, Long.MIN_VALUE);
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- // Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("longField");
- f.setLong(null, Long.MIN_VALUE);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("longSField");
- f.setLong(null, Long.MIN_VALUE);
- val = f.getLong(x);
- assertEquals("Returned incorrect long field value",
- Long.MIN_VALUE, val);
- }
-
- /**
- * java.lang.reflect.Field#setShort(java.lang.Object, short)
- */
- public void test_setShortLjava_lang_ObjectS() throws Exception{
- // Test for method void
- // java.lang.reflect.Field.setShort(java.lang.Object, short)
- TestField x = new TestField();
- Field f = null;
- short val = 0;
- try {
- f = x.getClass().getDeclaredField("shortField");
- f.setShort(x, Short.MIN_VALUE);
- val = f.getShort(x);
- } catch (Exception e) {
- fail("Exception during setShort test : " + e.getMessage());
- }
- assertEquals("Returned incorrect short field value", Short.MIN_VALUE,
- val);
-
- // test wrong type
- boolean thrown = false;
- try {
- f = x.getClass().getDeclaredField("booleanField");
- f.setShort(x, Short.MIN_VALUE);
- fail("Accessed field of invalid type");
- } catch (IllegalArgumentException ex) {
- thrown = true;
- }
- assertTrue("IllegalArgumentException expected but not thrown", thrown);
-
- // test not accessible
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("shortPFField");
- assertFalse(f.isAccessible());
- f.setShort(x, Short.MIN_VALUE);
- fail("Accessed inaccessible field");
- } catch (IllegalAccessException ex) {
- thrown = true;
- }
- assertTrue("IllegalAccessException expected but not thrown", thrown);
-
- // Test NPE
- thrown = false;
- try {
- f = x.getClass().getDeclaredField("shortField");
- f.setShort(null, Short.MIN_VALUE);
- fail("NullPointerException expected but not thrown");
- } catch (NullPointerException ex) {
- thrown = true;
- } catch (Exception ex) {
- fail("NullPointerException expected but not thrown");
- }
- assertTrue("NullPointerException expected but not thrown", thrown);
-
- // Test setting a static field;
- f = x.getClass().getDeclaredField("shortSField");
- f.setShort(null, Short.MIN_VALUE);
- val = f.getShort(x);
- assertEquals("Returned incorrect short field value",
- Short.MIN_VALUE, val);
- }
-
- /**
- * java.lang.reflect.Field#toString()
- */
- public void test_toString() {
- // Test for method java.lang.String java.lang.reflect.Field.toString()
- Field f = null;
-
- try {
- f = TestField.class.getDeclaredField("x");
- } catch (Exception e) {
- fail("Exception getting field : " + e.getMessage());
- }
- assertEquals("Field returned incorrect string",
- "private static final int tests.api.java.lang.reflect.FieldTest$TestField.x",
- f.toString());
- }
-
- public void test_getDeclaredAnnotations() throws Exception {
- Field field = TestClass.class.getField("annotatedField");
- Annotation[] annotations = field.getDeclaredAnnotations();
- assertEquals(2, annotations.length);
-
- Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
- ignoreOrder.add(annotations[0].annotationType());
- ignoreOrder.add(annotations[1].annotationType());
-
- assertTrue("Missing @AnnotationRuntime0", ignoreOrder
- .contains(AnnotationRuntime0.class));
- assertTrue("Missing @AnnotationRuntime1", ignoreOrder
- .contains(AnnotationRuntime1.class));
- }
-
- public void test_isEnumConstant() throws Exception {
- Field field = TestEnum.class.getDeclaredField("A");
- assertTrue("Enum constant not recognized", field.isEnumConstant());
-
- field = TestEnum.class.getDeclaredField("field");
- assertFalse("Non enum constant wrongly stated as enum constant", field
- .isEnumConstant());
-
- field = TestClass.class.getDeclaredField("annotatedField");
- assertFalse("Non enum constant wrongly stated as enum constant", field
- .isEnumConstant());
- }
-
- public void test_isSynthetic() throws Exception {
- Field[] fields = TestClass.Inner.class.getDeclaredFields();
- assertEquals("Not exactly one field returned", 1, fields.length);
-
- assertTrue("Enum constant not recognized", fields[0].isSynthetic());
-
- Field field = TestEnum.class.getDeclaredField("field");
- assertFalse("Non synthetic field wrongly stated as synthetic", field
- .isSynthetic());
-
- field = TestClass.class.getDeclaredField("annotatedField");
- assertFalse("Non synthetic field wrongly stated as synthetic", field
- .isSynthetic());
- }
-
-
- public void test_getGenericType() throws Exception {
- Field field = GenericField.class.getDeclaredField("field");
- Type type = field.getGenericType();
- @SuppressWarnings("unchecked")
- TypeVariable typeVar = (TypeVariable) type;
- assertEquals("Wrong type name returned", "S", typeVar.getName());
-
- Field boundedField = GenericField.class.getDeclaredField("boundedField");
- Type boundedType = boundedField.getGenericType();
- @SuppressWarnings("unchecked")
- TypeVariable boundedTypeVar = (TypeVariable) boundedType;
- assertEquals("Wrong type name returned", "T", boundedTypeVar.getName());
- assertEquals("More than one bound found", 1,
- boundedTypeVar.getBounds().length);
- assertEquals("Wrong bound returned", Number.class,
- boundedTypeVar.getBounds()[0]);
- }
-
-
- public void test_toGenericString() throws Exception {
- Field field = GenericField.class.getDeclaredField("field");
- assertEquals("Wrong generic string returned",
- "S tests.api.java.lang.reflect.FieldTest$GenericField.field",
- field.toGenericString());
-
- Field boundedField = GenericField.class
- .getDeclaredField("boundedField");
- assertEquals(
- "Wrong generic string returned",
- "T tests.api.java.lang.reflect.FieldTest$GenericField.boundedField",
- boundedField.toGenericString());
-
- Field ordinary = GenericField.class.getDeclaredField("intField");
- assertEquals(
- "Wrong generic string returned",
- "int tests.api.java.lang.reflect.FieldTest$GenericField.intField",
- ordinary.toGenericString());
- }
-
-
- public void test_hashCode() throws Exception {
- Field field = TestClass.class.getDeclaredField("annotatedField");
- assertEquals("Wrong hashCode returned", field.getName().hashCode()
- ^ field.getDeclaringClass().getName().hashCode(), field
- .hashCode());
- }
-
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
-
-class TestAccess {
- private static int xxx;
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/GenericArrayTypeTest.java b/luni/src/test/java/tests/api/java/lang/reflect/GenericArrayTypeTest.java
deleted file mode 100644
index e48e584..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/GenericArrayTypeTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-
-/**
- * Tests generic reflection on arrays with generic or parameterized component types.
- */
-public class GenericArrayTypeTest extends GenericReflectionTestsBase {
-
- static class A<T> {
- T[] array;
- }
- public void testGetGenericComponentType() throws Exception {
- @SuppressWarnings("unchecked")
- Class<? extends A> clazz = GenericArrayTypeTest.A.class;
- Field field = clazz.getDeclaredField("array");
- Type genericType = field.getGenericType();
- assertInstanceOf(GenericArrayType.class, genericType);
- Type componentType = ((GenericArrayType) genericType).getGenericComponentType();
- assertEquals(getTypeParameter(clazz), componentType);
- assertInstanceOf(TypeVariable.class, componentType);
- TypeVariable<?> componentTypeVariable = (TypeVariable<?>) componentType;
- assertEquals("T", componentTypeVariable.getName());
- assertEquals(clazz, componentTypeVariable.getGenericDeclaration());
- }
-
- static class B<T> {
- B<T>[] array;
- }
- public void testParameterizedComponentType() throws Exception {
- @SuppressWarnings("unchecked")
- Class<? extends B> clazz = GenericArrayTypeTest.B.class;
- Field field = clazz.getDeclaredField("array");
- Type genericType = field.getGenericType();
-
- assertInstanceOf(GenericArrayType.class, genericType);
- GenericArrayType arrayType = (GenericArrayType) genericType;
- Type componentType = arrayType.getGenericComponentType();
- assertInstanceOf(ParameterizedType.class, componentType);
- ParameterizedType parameteriezdType = (ParameterizedType) componentType;
- assertEquals(clazz, parameteriezdType.getRawType());
- assertEquals(clazz.getTypeParameters()[0], parameteriezdType.getActualTypeArguments()[0]);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/GenericMethodsTests.java b/luni/src/test/java/tests/api/java/lang/reflect/GenericMethodsTests.java
deleted file mode 100644
index 0bfc188..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/GenericMethodsTests.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-
-
-/**
- * Tests unbounded type parameters declared on methods.
- */
-public class GenericMethodsTests extends GenericReflectionTestsBase{
-
- static class GenericMethods {
-
- public <T> void noParamNoReturn() {}
-
- public <T> void paramNoReturn(T param) {}
-
- @SuppressWarnings("unchecked")
- public <T> T noParamReturn() { return (T) new Object(); }
-
- public <T> T paramReturn(T param) {return param;}
- }
-
- private static Class<? extends GenericMethods> clazz = GenericMethodsTests.GenericMethods.class;
-
- /**
- * Tests that there are no Type Parameters on the Class itself.
- */
- public void testGenericMethods() {
- assertLenghtZero(clazz.getTypeParameters());
- }
-
- /**
- * Tests whether the specified method declares a type parameter T.
- * @param method the method
- */
- private void checkTypeParameter(Method method) {
- TypeVariable<Method> typeParameter = getTypeParameter(method);
- assertEquals("T", typeParameter.getName());
- assertEquals(method, typeParameter.getGenericDeclaration());
- }
-
- /**
- * Tests whether the specified method declares a parameter with the
- * type of the type parameter.
- * @param method the method
- */
- private void checkParameterType(Method method) {
- TypeVariable<Method> typeParameter = getTypeParameter(method);
- assertLenghtOne(method.getGenericParameterTypes());
- Type genericParameterType = method.getGenericParameterTypes()[0];
- assertEquals(typeParameter, genericParameterType);
- assertInstanceOf(TypeVariable.class, genericParameterType);
- assertEquals(method, ((TypeVariable<?>) genericParameterType).getGenericDeclaration());
- }
-
- /**
- * Tests whether the type of the return type is the declared type parameter.
- * @param method the declaring method
- */
- private void checkReturnType(Method method) {
- TypeVariable<Method> typeParameter = getTypeParameter(method);
- Type genericReturnType = method.getGenericReturnType();
- assertEquals(typeParameter, genericReturnType);
- assertInstanceOf(TypeVariable.class, genericReturnType);
- assertEquals(method, ((TypeVariable<?>) genericReturnType).getGenericDeclaration());
- }
- public void testNoParamNoReturn() throws Exception {
- Method method = clazz.getMethod("noParamNoReturn");
- checkTypeParameter(method);
- }
-
- public void testParamNoReturn() throws Exception {
- Method method = clazz.getMethod("paramNoReturn", Object.class);
- checkTypeParameter(method);
- checkParameterType(method);
- }
-
- public void testNoParamReturn() throws Exception {
- Method method = clazz.getMethod("noParamReturn");
- checkTypeParameter(method);
- assertLenghtZero(method.getGenericParameterTypes());
- checkReturnType(method);
- }
- public void testParamReturn() throws Exception {
- Method method = clazz.getMethod("paramReturn", Object.class);
- checkTypeParameter(method);
- checkParameterType(method);
- checkReturnType(method);
- }
- public void testIndependencyOfMethodTypeParameters() throws Exception {
- Method method0 = clazz.getMethod("paramNoReturn", Object.class);
- TypeVariable<Method> typeParameter0 = method0.getTypeParameters()[0];
-
- Method method1 = clazz.getMethod("noParamNoReturn");
- TypeVariable<Method> typeParameter1 = method1.getTypeParameters()[0];
-
- //Generic method type parameters NAMES are equal
- assertEquals(typeParameter0.getName(), typeParameter1.getName());
- //Generic method type PARAMETERS are not equal
- assertNotEquals(typeParameter0, typeParameter1);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionTestsBase.java b/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionTestsBase.java
deleted file mode 100644
index 095bb72..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionTestsBase.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.TypeVariable;
-
-import junit.framework.TestCase;
-
-public class GenericReflectionTestsBase extends TestCase{
-
- /**
- * Returns the type parameter of the declaring method.
- *
- * @param method
- * the declaring method
- * @return the type parameter of the method
- */
- public TypeVariable<Method> getTypeParameter(Method method) {
- TypeVariable<Method>[] typeParameters = method.getTypeParameters();
- assertLenghtOne(typeParameters);
- TypeVariable<Method> typeParameter = typeParameters[0];
- return typeParameter;
- }
-
- /**
- * Returns the type parameter of the declaring class.
- *
- * @param method
- * the declaring method.
- * @return the type parameter of the method.
- */
- @SuppressWarnings("unchecked")
- public TypeVariable<Class> getTypeParameter(Class<?> clazz) {
- TypeVariable[] typeParameters = clazz.getTypeParameters();
- assertLenghtOne(typeParameters);
- TypeVariable<Class> typeVariable = typeParameters[0];
- assertEquals(clazz, typeVariable.getGenericDeclaration());
- assertEquals("T", typeVariable.getName());
- return typeVariable;
- }
-
- public static void assertLenghtOne(Object[] array) {
- TestCase.assertEquals("Array does NOT contain exactly one element.", 1, array.length);
- }
-
- public static void assertLenghtZero(Object[] array) {
- TestCase.assertEquals("Array has more than zero elements.", 0, array.length);
- }
-
- public static void assertInstanceOf(Class<?> expectedClass, Object actual) {
- TestCase.assertTrue(actual.getClass().getName() + " is not instance of :" + expectedClass.getName(), expectedClass
- .isInstance(actual));
- }
-
- public static void assertNotEquals(Object expected, Object actual) {
- TestCase.assertFalse(actual.toString() + " has not to be equal to " + expected.toString(), expected.equals(actual));
- }
-
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/GenericSignatureFormatErrorTest.java b/luni/src/test/java/tests/api/java/lang/reflect/GenericSignatureFormatErrorTest.java
deleted file mode 100644
index 954073c..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/GenericSignatureFormatErrorTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package tests.api.java.lang.reflect;
-
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.SideEffect;
-import dalvik.system.DexFile;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.GenericSignatureFormatError;
-import java.lang.reflect.TypeVariable;
-
-import tests.support.Support_ClassLoader;
-
-public class GenericSignatureFormatErrorTest extends TestCase{
-
- public void test_Constructor() {
- assertNotNull(new GenericSignatureFormatError());
- }
-
- public void test_readResource() throws Exception {
- File tf = File.createTempFile("classes", ".dex");
- // System.out.println("GenericSignatureFormatErrorTest:"
- // +tf.getAbsolutePath()+", canRead: "+tf.canRead()
- // +", canWrite: "+tf.canWrite());
- InputStream is = this.getClass().getResourceAsStream("dex1.bytes");
- assertNotNull(is);
- }
-
-
- @AndroidOnly("Uses Android specific class dalvik.system.DexFile " +
- "for loading classes.")
- @SideEffect("strange issue (exception: 'could not open dex file', " +
- "dalvikvm: 'waitpid failed' log msg - only occurs when @SideEffect is removed " +
- "and this test is run via running tests.luni.AllTestsLang TestSuite")
- public void test_signatureFormatError() throws Exception {
- /*
- * dex1.bytes is a jar file with a classes.dex in it.
- * the classes.dex was javac'ed, dx'ed and patched
- * with the following java file:
- *
- * package demo;
- * public class HelloWorld<U> {
- * public HelloWorld(U t) {}
- * }
- *
- * patch:
- * the string constant (class generics signature string)
- * "<U:" was changed to "<<:"
- *
- */
-
- File tf = File.createTempFile("classes", ".dex");
- // System.out.println("GenericSignatureFormatErrorTest:" +
- // tf.getAbsolutePath() + ", canRead: " + tf.canRead() +
- // ", canWrite: "+tf.canWrite());
- InputStream is = this.getClass().getResourceAsStream("dex1.bytes");
- assertNotNull(is);
- OutputStream fos = new FileOutputStream(tf);
- copy(is, fos);
- fos.flush();
- fos.close();
-
-
- // class signature string "<U:" was changed to "<<:"
- //System.out.println("file length:"+tf.length());
- try {
- // Was:
- // DexFile df = new DexFile(tf);
- // Class clazz = df.loadClass("demo/HelloWorld", this.getClass().getClassLoader());
-
- ClassLoader cl = Support_ClassLoader.getInstance(tf.toURL(),
- getClass().getClassLoader());
-
- Class clazz = cl.loadClass("demo/HelloWorld");
- TypeVariable[] tvs = clazz.getTypeParameters();
- fail("expecting a GenericSignatureFormatError");
- // for (TypeVariable tv : tvs) {
- // System.out.println("tv:"+tv.toString());
- // }
- } catch (GenericSignatureFormatError gsfe) {
- // expected
- }
- }
-
- private void copy(InputStream is, OutputStream os) {
- try {
- int b;
- while ((b = is.read()) != -1) {
- os.write(b);
- }
- is.close();
- } catch (IOException ex) {
- throw new RuntimeException("io error", ex);
- }
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/InvocationTargetExceptionTest.java b/luni/src/test/java/tests/api/java/lang/reflect/InvocationTargetExceptionTest.java
deleted file mode 100644
index 5e699a9..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/InvocationTargetExceptionTest.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.io.ByteArrayOutputStream;
-import java.io.CharArrayWriter;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-public class InvocationTargetExceptionTest extends junit.framework.TestCase {
-
- static class TestMethod {
- public TestMethod() {
- }
-
- public void voidMethod() throws IllegalArgumentException {
- }
-
- public void parmTest(int x, short y, String s, boolean bool, Object o,
- long l, byte b, char c, double d, float f) {
- }
-
- public int intMethod() {
- return 1;
- }
-
- public static final void printTest(int x, short y, String s,
- boolean bool, Object o, long l, byte b, char c, double d,
- float f) {
- }
-
- public double doubleMethod() {
- return 1.0;
- }
-
- public short shortMethod() {
- return (short) 1;
- }
-
- public byte byteMethod() {
- return (byte) 1;
- }
-
- public float floatMethod() {
- return 1.0f;
- }
-
- public long longMethod() {
- return 1l;
- }
-
- public char charMethod() {
- return 'T';
- }
-
- public Object objectMethod() {
- return new Object();
- }
-
- private static void prstatic() {
- }
-
- public static void pustatic() {
- }
-
- public static synchronized void pustatsynch() {
- }
-
- public static int invokeStaticTest() {
- return 1;
- }
-
- public int invokeInstanceTest() {
- return 1;
- }
-
- private int privateInvokeTest() {
- return 1;
- }
-
- public int invokeExceptionTest() throws NullPointerException {
- throw new NullPointerException();
- }
-
- public static synchronized native void pustatsynchnat();
-
- }
-
- abstract class AbstractTestMethod {
- public abstract void puabs();
- }
-
- class SubInvocationTargetException extends InvocationTargetException {}
-
- /**
- * java.lang.reflect.InvocationTargetException#InvocationTargetException()
- */
- public void test_Constructor() throws Exception {
- Constructor<InvocationTargetException> ctor = InvocationTargetException.class
- .getDeclaredConstructor();
- assertNotNull("Parameterless constructor does not exist.", ctor);
- assertTrue("Constructor is not protected", Modifier.isProtected(ctor
- .getModifiers()));
- //create an instance of a subtype using this constructor
- SubInvocationTargetException subException = new SubInvocationTargetException();
- }
-
- /**
- * java.lang.reflect.InvocationTargetException#InvocationTargetException(java.lang.Throwable)
- */
- public void test_ConstructorLjava_lang_Throwable() {
- // Test for method
- // java.lang.reflect.InvocationTargetException(java.lang.Throwable)
- try {
- Method mth = TestMethod.class.getDeclaredMethod(
- "invokeExceptionTest", new Class[0]);
- Object[] args = { Object.class };
- Object ret = mth.invoke(new TestMethod(), new Object[0]);
- } catch (InvocationTargetException e) {
- // Correct behaviour
- return;
- } catch (NoSuchMethodException e) {
- } catch (IllegalAccessException e) {
- }
- fail("Failed to throw exception");
- }
-
- /**
- * java.lang.reflect.InvocationTargetException#InvocationTargetException(java.lang.Throwable,
- * java.lang.String)
- */
- public void test_ConstructorLjava_lang_ThrowableLjava_lang_String() {
- // Test for method
- // java.lang.reflect.InvocationTargetException(java.lang.Throwable,
- // java.lang.String)
- try {
- Method mth = TestMethod.class.getDeclaredMethod(
- "invokeExceptionTest", new Class[0]);
- Object[] args = { Object.class };
- Object ret = mth.invoke(new TestMethod(), new Object[0]);
- } catch (InvocationTargetException e) {
- // Correct behaviour
- return;
- } catch (NoSuchMethodException e) {
- ;
- } catch (IllegalAccessException e) {
- }
- fail("Failed to throw exception");
- }
-
- /**
- * java.lang.reflect.InvocationTargetException#getTargetException()
- */
- public void test_getTargetException() {
- // Test for method java.lang.Throwable
- // java.lang.reflect.InvocationTargetException.getTargetException()
- try {
- Method mth = TestMethod.class.getDeclaredMethod(
- "invokeExceptionTest", new Class[0]);
- Object[] args = { Object.class };
- Object ret = mth.invoke(new TestMethod(), new Object[0]);
- } catch (InvocationTargetException e) {
- // Correct behaviour
- assertTrue("Returned incorrect target exception", e
- .getTargetException() instanceof NullPointerException);
- return;
- } catch (Exception e) {
- fail("Exception during constructor test : " + e.getMessage());
- }
- fail("Failed to throw exception");
- }
-
- /**
- * java.lang.reflect.InvocationTargetException#getCause()
- */
- public void test_getCause() {
- // java.lang.reflect.InvocationTargetException.getCause()
- try {
- Method mth = TestMethod.class.getDeclaredMethod(
- "invokeExceptionTest", new Class[0]);
- Object[] args = {Object.class};
- Object ret = mth.invoke(new TestMethod(), new Object[0]);
- } catch (InvocationTargetException e) {
- // Correct behaviour
- assertTrue("Returned incorrect cause",
- e.getCause() instanceof NullPointerException);
- return;
- } catch (Exception e) {
- fail("Exception during InvocationTargetException test : "
- + e.getMessage());
- }
- fail("Failed to throw exception");
- }
-
- /**
- * java.lang.reflect.InvocationTargetException#printStackTrace()
- */
- public void test_printStackTrace() {
- // Test for method void
- // java.lang.reflect.InvocationTargetException.printStackTrace()
- try {
- ByteArrayOutputStream bao = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(bao);
- PrintStream oldErr = System.err;
- System.setErr(ps);
- InvocationTargetException ite = new InvocationTargetException(null);
- ite.printStackTrace();
- System.setErr(oldErr);
-
- String s = new String(bao.toByteArray());
-
- assertTrue("Incorrect Stack trace: " + s, s != null
- && s.length() > 300);
- } catch (Exception e) {
- fail("printStackTrace() caused exception : " + e.getMessage());
- }
- }
-
- /**
- * java.lang.reflect.InvocationTargetException#printStackTrace(java.io.PrintStream)
- */
- public void test_printStackTraceLjava_io_PrintStream() {
- // Test for method void
- // java.lang.reflect.InvocationTargetException.printStackTrace(java.io.PrintStream)
- assertTrue("Tested via test_printStackTrace().", true);
- ByteArrayOutputStream bao = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(bao);
- InvocationTargetException ite = new InvocationTargetException(
- new InvocationTargetException(null));
- ite.printStackTrace(ps);
- String s = bao.toString();
- assertTrue("printStackTrace failed." + s.length(), s != null
- && s.length() > 400);
- }
-
- /**
- * java.lang.reflect.InvocationTargetException#printStackTrace(java.io.PrintWriter)
- */
- public void test_printStackTraceLjava_io_PrintWriter() {
- // Test for method void
- // java.lang.reflect.InvocationTargetException.printStackTrace(java.io.PrintWriter)
- try {
- PrintWriter pw;
- InvocationTargetException ite;
- String s;
- CharArrayWriter caw = new CharArrayWriter();
- pw = new PrintWriter(caw);
- ite = new InvocationTargetException(new InvocationTargetException(
- null));
- ite.printStackTrace(pw);
-
- s = caw.toString();
- assertTrue("printStackTrace failed." + s.length(), s != null
- && s.length() > 400);
- pw.close();
-
- ByteArrayOutputStream bao = new ByteArrayOutputStream();
- pw = new PrintWriter(bao);
- ite = new InvocationTargetException(new InvocationTargetException(
- null));
- ite.printStackTrace(pw);
-
- pw.flush(); // Test will fail if this line removed.
- s = bao.toString();
- assertTrue("printStackTrace failed." + s.length(), s != null
- && s.length() > 400);
-
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/MalformedParameterizedTypeExceptionTests.java b/luni/src/test/java/tests/api/java/lang/reflect/MalformedParameterizedTypeExceptionTests.java
deleted file mode 100644
index f86403d..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/MalformedParameterizedTypeExceptionTests.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package tests.api.java.lang.reflect;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.MalformedParameterizedTypeException;
-import java.lang.reflect.Modifier;
-
-public class MalformedParameterizedTypeExceptionTests extends junit.framework.TestCase {
-
- /**
- * java.lang.reflect.MalformedParameterizedTypeException#MalformedParameterizedTypeException()
- */
- public void test_Constructor() throws Exception {
- Constructor<MalformedParameterizedTypeException> ctor = MalformedParameterizedTypeException.class
- .getDeclaredConstructor();
- assertNotNull("Parameterless constructor does not exist.", ctor);
- assertTrue("Constructor is not protected", Modifier.isPublic(ctor
- .getModifiers()));
- assertNotNull(ctor.newInstance());
- }
-
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/MethodTest.java b/luni/src/test/java/tests/api/java/lang/reflect/MethodTest.java
deleted file mode 100644
index e8288d6..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/MethodTest.java
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.HashSet;
-import java.util.Set;
-
-public class MethodTest extends junit.framework.TestCase {
-
- static class TestMethod {
- public TestMethod() {
- }
-
- public void voidMethod() throws IllegalArgumentException {
- }
-
- public void parmTest(int x, short y, String s, boolean bool, Object o,
- long l, byte b, char c, double d, float f) {
- }
-
- public int intMethod() {
- return 1;
- }
-
- public static final void printTest(int x, short y, String s,
- boolean bool, Object o, long l, byte b, char c, double d,
- float f) {
- }
-
- public double doubleMethod() {
- return 1.0;
- }
-
- public short shortMethod() {
- return (short) 1;
- }
-
- public byte byteMethod() {
- return (byte) 1;
- }
-
- public float floatMethod() {
- return 1.0f;
- }
-
- public long longMethod() {
- return 1l;
- }
-
- public char charMethod() {
- return 'T';
- }
-
- public Object objectMethod() {
- return new Object();
- }
-
- private static void prstatic() {
- }
-
- public static void pustatic() {
- }
-
- public static synchronized void pustatsynch() {
- }
-
- public static int invokeStaticTest() {
- return 1;
- }
-
- public int invokeInstanceTest() {
- return 1;
- }
-
- private int privateInvokeTest() {
- return 1;
- }
-
- public int invokeExceptionTest() throws NullPointerException {
- throw new NullPointerException();
- }
-
- public static synchronized native void pustatsynchnat();
-
- public void publicVoidVarargs(Object... param){}
- public void publicVoidArray(Object[] param){}
-
- public void annotatedParameter(@TestAnno @Deprecated int a,
- @Deprecated int b, int c) {
- }
-
- @Deprecated
- @TestAnno
- public void annotatedMethod(){}
-
- public void hashCodeTest(int i){}
- public void hashCodeTest(String s){}
-
- public void invokeCastTest1(byte param) {
- }
-
- public void invokeCastTest1(short param) {
- }
-
- public void invokeCastTest1(int param) {
- }
-
- public void invokeCastTest1(long param) {
- }
-
- public void invokeCastTest1(float param) {
- }
-
- public void invokeCastTest1(double param) {
- }
-
- public void invokeCastTest1(char param) {
- }
-
- public void invokeCastTest1(boolean param) {
- }
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.PARAMETER, ElementType.METHOD})
- public static @interface TestAnno{
- public static final String DEFAULT_VALUE = "DEFAULT_VALUE";
-
- String value() default DEFAULT_VALUE;
- }
-
- abstract class AbstractTestMethod {
- public abstract void puabs();
- }
-
- class TestMethodSub extends TestMethod {
- public int invokeInstanceTest() {
- return 0;
- }
- }
-
- static interface IBrigeTest<T>{
- T m();
- }
-
- static class BrigeTest implements IBrigeTest<String> {
- public String m(){ return null; }
- }
-
- static class ExceptionTest<T extends Exception>{
- @SuppressWarnings("unused")
- void exceptionTest() throws T{}
- }
-
- static class GenericReturnType<T> {
- T returnGeneric(){return null;}
- }
-
- static class GenericString<T> {
- public static final String GENERIC =
- "T tests.api.java.lang.reflect.MethodTest$GenericString.genericString(T)";
- T genericString(T t) {
- return null;
- }
- }
-
- /**
- * java.lang.reflect.Method#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- // Test for method boolean
- // java.lang.reflect.Method.equals(java.lang.Object)
-
- Method m1 = null, m2 = null;
- try {
- m1 = TestMethod.class.getMethod("invokeInstanceTest", new Class[0]);
- m2 = TestMethodSub.class.getMethod("invokeInstanceTest",
- new Class[0]);
- } catch (Exception e) {
- fail("Exception during equals test : " + e.getMessage());
- }
- assertTrue("Overriden method returned equal", !m1.equals(m2));
- assertTrue("Same method returned not-equal", m1.equals(m1));
- try {
- m1 = TestMethod.class.getMethod("invokeStaticTest", new Class[0]);
- m2 = TestMethodSub.class
- .getMethod("invokeStaticTest", new Class[0]);
- } catch (Exception e) {
- fail("Exception during equals test : " + e.getMessage());
- }
- assertTrue("Inherited method returned not-equal", m1.equals(m2));
- }
-
- /**
- * java.lang.Class#getMethod(java.lang.String, java.lang.Class[])
- */
- public void test_getMethod() throws NoSuchMethodException, SecurityException {
- // Check that getMethod treats null parameterTypes the same as an empty array.
- Method m1 = TestMethod.class.getMethod("invokeInstanceTest", new Class[0]);
- Method m2 = TestMethod.class.getMethod("invokeInstanceTest", (Class[]) null);
- assertEquals(m1, m2);
- }
-
- /**
- * java.lang.Class#getDeclaredMethod(java.lang.String, java.lang.Class[])
- */
- public void test_getDeclaredMethod() throws NoSuchMethodException, SecurityException {
- // Check that getDeclaredMethod treats null parameterTypes the same as an empty array.
- Method m1 = TestMethod.class.getDeclaredMethod("invokeInstanceTest", new Class[0]);
- Method m2 = TestMethod.class.getDeclaredMethod("invokeInstanceTest", (Class[]) null);
- assertEquals(m1, m2);
- }
-
- /**
- * java.lang.reflect.Method#getDeclaringClass()
- */
- public void test_getDeclaringClass() {
- // Test for method java.lang.Class
- // java.lang.reflect.Method.getDeclaringClass()
-
- Method[] mths;
-
- try {
- mths = TestMethod.class.getDeclaredMethods();
- assertTrue("Returned incorrect declaring class: "
- + mths[0].getDeclaringClass().toString(), mths[0]
- .getDeclaringClass().equals(TestMethod.class));
- } catch (Exception e) {
- fail("Exception during getDeclaringClass test: "
- + e.toString());
- }
- }
-
- /**
- * java.lang.reflect.Method#getExceptionTypes()
- */
- public void test_getExceptionTypes() {
- // Test for method java.lang.Class []
- // java.lang.reflect.Method.getExceptionTypes()
-
- try {
- Method mth = TestMethod.class.getMethod("voidMethod", new Class[0]);
- Class[] ex = mth.getExceptionTypes();
- assertEquals("Returned incorrect number of exceptions",
- 1, ex.length);
- assertTrue("Returned incorrect exception type", ex[0]
- .equals(IllegalArgumentException.class));
- mth = TestMethod.class.getMethod("intMethod", new Class[0]);
- ex = mth.getExceptionTypes();
- assertEquals("Returned incorrect number of exceptions",
- 0, ex.length);
- } catch (Exception e) {
- fail("Exception during getExceptionTypes: " + e.toString());
- }
-
- }
-
- /**
- * java.lang.reflect.Method#getModifiers()
- */
- public void test_getModifiers() {
- // Test for method int java.lang.reflect.Method.getModifiers()
-
- Class cl = TestMethod.class;
- int mods = 0;
- Method mth = null;
- int mask = 0;
- try {
- mth = cl.getMethod("pustatic", new Class[0]);
- mods = mth.getModifiers();
- } catch (Exception e) {
- fail("Exception during getModfiers test: " + e.toString());
- }
- mask = Modifier.PUBLIC | Modifier.STATIC;
- assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
- try {
- mth = cl.getDeclaredMethod("prstatic", new Class[0]);
- mods = mth.getModifiers();
- } catch (Exception e) {
- fail("Exception during getModfiers test: " + e.toString());
- }
- mask = Modifier.PRIVATE | Modifier.STATIC;
- assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
- try {
- mth = cl.getDeclaredMethod("pustatsynch", new Class[0]);
- mods = mth.getModifiers();
- } catch (Exception e) {
- fail("Exception during getModfiers test: " + e.toString());
- }
- mask = (Modifier.PUBLIC | Modifier.STATIC) | Modifier.SYNCHRONIZED;
- assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
- try {
- mth = cl.getDeclaredMethod("pustatsynchnat", new Class[0]);
- mods = mth.getModifiers();
- } catch (Exception e) {
- fail("Exception during getModfiers test: " + e.toString());
- }
- mask = ((Modifier.PUBLIC | Modifier.STATIC) | Modifier.SYNCHRONIZED)
- | Modifier.NATIVE;
- assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
- cl = AbstractTestMethod.class;
- try {
- mth = cl.getDeclaredMethod("puabs", new Class[0]);
- mods = mth.getModifiers();
- } catch (Exception e) {
- fail("Exception during getModfiers test: " + e.toString());
- }
- mask = Modifier.PUBLIC | Modifier.ABSTRACT;
- assertTrue("Incorrect modifiers returned", (mods | mask) == mask);
- }
-
- /**
- * java.lang.reflect.Method#getName()
- */
- public void test_getName() {
- // Test for method java.lang.String java.lang.reflect.Method.getName()
- Method mth = null;
- try {
- mth = TestMethod.class.getMethod("voidMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getMethodName(): " + e.toString());
- }
- assertEquals("Returned incorrect method name",
- "voidMethod", mth.getName());
- }
-
- /**
- * java.lang.reflect.Method#isVarArgs()
- */
- public void test_isVarArgs() throws Exception {
- Method mth = TestMethod.class.getMethod("publicVoidVarargs",
- Object[].class);
- assertTrue("Varargs method stated as non vararg.", mth.isVarArgs());
-
- mth = TestMethod.class.getDeclaredMethod("publicVoidArray",
- Object[].class);
- assertFalse("Non varargs method stated as vararg.", mth.isVarArgs());
- }
-
- /**
- * java.lang.reflect.Method#isBridge()
- */
- public void test_isBridge() throws Exception {
- Method[] declaredMethods = BrigeTest.class.getDeclaredMethods();
- assertEquals("Bridge method not generated.", 2, declaredMethods.length);
- boolean foundBridgeMethod = false;
- for (Method method : declaredMethods) {
- if (method.getReturnType().equals(Object.class)) {
- assertTrue("Bridge method not stated as bridge.", method
- .isBridge());
- foundBridgeMethod = true;
- }
- }
- assertTrue("Bridge method not found.", foundBridgeMethod);
- }
-
- /**
- * java.lang.reflect.Method#isSynthetic()
- */
- public void test_isSynthetic() throws Exception {
- Method[] declaredMethods = BrigeTest.class.getDeclaredMethods();
- assertEquals("Synthetic method not generated.", 2,
- declaredMethods.length);
- boolean foundSyntheticMethod = false;
- for (Method method : declaredMethods) {
- if (method.getReturnType().equals(Object.class)) {
- assertTrue("Synthetic method not stated as synthetic.", method
- .isSynthetic());
- foundSyntheticMethod = true;
- }
- }
- assertTrue("Synthetic method not found.", foundSyntheticMethod);
- }
- /**
- * java.lang.reflect.Method#getParameterAnnotations()
- */
- public void test_getParameterAnnotations() throws Exception {
- Method method = TestMethod.class.getDeclaredMethod(
- "annotatedParameter", new Class[] {
- int.class, int.class, int.class});
- Annotation[][] annotations = method.getParameterAnnotations();
- assertEquals(3, annotations.length);
- assertEquals(
- "Wrong number of annotations returned for first parameter", 2,
- annotations[0].length);
- Set<Class<?>> annotationSet = new HashSet<Class<?>>();
- annotationSet.add(annotations[0][0].annotationType());
- annotationSet.add(annotations[0][1].annotationType());
- assertTrue("Missing TestAnno annotation", annotationSet
- .contains(TestAnno.class));
- assertTrue("Missing Deprecated annotation", annotationSet
- .contains(Deprecated.class));
-
- assertEquals(
- "Wrong number of annotations returned for second parameter",
- 1, annotations[1].length);
- annotationSet = new HashSet<Class<?>>();
- annotationSet.add(annotations[1][0].annotationType());
- assertTrue("Missing Deprecated annotation", annotationSet
- .contains(Deprecated.class));
- assertEquals(
- "Wrong number of annotations returned for third parameter", 0,
- annotations[2].length);
- }
-
- /**
- * java.lang.reflect.Method#getDeclaredAnnotations()
- */
- public void test_getDeclaredAnnotations() throws Exception {
- Method method = TestMethod.class.getDeclaredMethod("annotatedMethod");
- Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
- assertEquals(2, declaredAnnotations.length);
-
- Set<Class<?>> annotationSet = new HashSet<Class<?>>();
- annotationSet.add(declaredAnnotations[0].annotationType());
- annotationSet.add(declaredAnnotations[1].annotationType());
- assertTrue("Missing TestAnno annotation", annotationSet
- .contains(TestAnno.class));
- assertTrue("Missing Deprecated annotation", annotationSet
- .contains(Deprecated.class));
- }
-
- /**
- * java.lang.reflect.Method#getDefaultValue()
- */
- public void test_getDefaultValue() throws Exception {
- Method method = TestAnno.class.getDeclaredMethod("value");
- assertEquals("Wrong default value returned", TestAnno.DEFAULT_VALUE,
- method.getDefaultValue());
- }
-
- /**
- * java.lang.reflect.Method#getDefaultValue()
- */
- public void test_getGenericExceptionTypes() throws Exception {
- Method method = ExceptionTest.class.getDeclaredMethod("exceptionTest");
- Type[] genericExceptionTypes = method.getGenericExceptionTypes();
- assertEquals(1, genericExceptionTypes.length);
- assertTrue(genericExceptionTypes[0] instanceof TypeVariable<?>);
- @SuppressWarnings("unchecked")
- TypeVariable<Class<ExceptionTest<?>>> tv =
- (TypeVariable<Class<ExceptionTest<?>>>) genericExceptionTypes[0];
- assertEquals("T", tv.getName());
- }
-
- /**
- * java.lang.reflect.Method#getGenericReturnType()
- */
- public void test_getGenericReturnType() throws Exception {
- Method method = GenericReturnType.class
- .getDeclaredMethod("returnGeneric");
- Type returnType = method.getGenericReturnType();
- assertNotNull("getGenericReturnType returned null", returnType);
- assertTrue(returnType instanceof TypeVariable<?>);
- @SuppressWarnings("unchecked")
- TypeVariable<Class<ExceptionTest<?>>> tv =
- (TypeVariable<Class<ExceptionTest<?>>>) returnType;
- assertEquals("T", tv.getName());
- }
-
-
- /**
- * java.lang.reflect.Method#toGenericString()
- */
- public void test_toGenericString() throws Exception {
- Method method = GenericString.class.getDeclaredMethod("genericString",
- Object.class);
- assertEquals("Wrong generic String returned", GenericString.GENERIC,
- method.toGenericString());
- }
-
-
-
-
-
-
- /**
- * java.lang.reflect.Method#hashCode()
- */
- public void test_hashCode() throws Exception {
- Method mth0 = TestMethod.class.getMethod("hashCodeTest", String.class);
- Method mth1 = TestMethod.class.getDeclaredMethod("hashCodeTest",
- int.class);
- assertEquals("Methods with same name did not return same hashCode.",
- mth0.hashCode(), mth1.hashCode());
- }
-
- /**
- * java.lang.reflect.Method#getParameterTypes()
- */
- public void test_getParameterTypes() {
- // Test for method java.lang.Class []
- // java.lang.reflect.Method.getParameterTypes()
- Class cl = TestMethod.class;
- Method mth = null;
- Class[] parms = null;
- Method[] methods = null;
- Class[] plist = { int.class, short.class, String.class, boolean.class,
- Object.class, long.class, byte.class, char.class, double.class,
- float.class };
- try {
- mth = cl.getMethod("voidMethod", new Class[0]);
- parms = mth.getParameterTypes();
- } catch (Exception e) {
- fail("Exception during getParameterTypes test: "
- + e.toString());
- }
- assertEquals("Returned incorrect parameterTypes", 0, parms.length);
- try {
- mth = cl.getMethod("parmTest", plist);
- parms = mth.getParameterTypes();
- } catch (Exception e) {
- fail("Exception during getParameterTypes test: "
- + e.toString());
- }
- assertTrue("Invalid number of parameters returned",
- plist.length == parms.length);
- for (int i = 0; i < plist.length; i++)
- assertTrue("Incorrect parameter returned", plist[i]
- .equals(parms[i]));
-
- // Test same method. but this time pull it from the list of methods
- // rather than asking for it explicitly
- methods = cl.getDeclaredMethods();
-
- int i;
- for (i = 0; i < methods.length; i++)
- if (methods[i].getName().equals("parmTest")) {
- mth = methods[i];
- i = methods.length + 1;
- }
- if (i < methods.length) {
- parms = mth.getParameterTypes();
- assertTrue("Incorrect number of parameters returned",
- parms.length == plist.length);
- for (i = 0; i < plist.length; i++)
- assertTrue("Incorrect parameter returned", plist[i]
- .equals(parms[i]));
- }
- }
-
- /**
- * java.lang.reflect.Method#getReturnType()
- */
- public void test_getReturnType() {
- // Test for method java.lang.Class
- // java.lang.reflect.Method.getReturnType()
- Class cl = TestMethod.class;
- Method mth = null;
- try {
- mth = cl.getMethod("charMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test : " + e.getMessage());
- }
- assertTrue("Gave incorrect returne type, wanted char", mth
- .getReturnType().equals(char.class));
- try {
- mth = cl.getMethod("longMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test : " + e.getMessage());
- }
- assertTrue("Gave incorrect returne type, wanted long", mth
- .getReturnType().equals(long.class));
- try {
- mth = cl.getMethod("shortMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test : " + e.getMessage());
- }
- assertTrue("Gave incorrect returne type, wanted short", mth
- .getReturnType().equals(short.class));
- try {
- mth = cl.getMethod("intMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test : " + e.getMessage());
- }
- assertTrue("Gave incorrect returne type, wanted int: "
- + mth.getReturnType(), mth.getReturnType().equals(int.class));
- try {
- mth = cl.getMethod("doubleMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test : " + e.getMessage());
- }
- assertTrue("Gave incorrect returne type, wanted double", mth
- .getReturnType().equals(double.class));
- try {
- mth = cl.getMethod("byteMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test : " + e.getMessage());
- }
- assertTrue("Gave incorrect returne type, wanted byte", mth
- .getReturnType().equals(byte.class));
- try {
- mth = cl.getMethod("byteMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test:" + e.toString());
- }
- assertTrue("Gave incorrect returne type, wanted byte", mth
- .getReturnType().equals(byte.class));
- try {
- mth = cl.getMethod("objectMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test : " + e.getMessage());
- }
- assertTrue("Gave incorrect returne type, wanted Object", mth
- .getReturnType().equals(Object.class));
-
- try {
- mth = cl.getMethod("voidMethod", new Class[0]);
- } catch (Exception e) {
- fail("Exception during getReturnType test : " + e.getMessage());
- }
- assertTrue("Gave incorrect returne type, wanted void", mth
- .getReturnType().equals(void.class));
- }
-
- /**
- * java.lang.reflect.Method#invoke(java.lang.Object,
- * java.lang.Object[])
- */
- public void test_invokeLjava_lang_Object$Ljava_lang_Object() throws Exception{
- // Test for method java.lang.Object
- // java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object
- // [])
- Class cl = TestMethod.class;
- Class[] dcl = new Class[0];
-
- // Get and invoke a static method
- Method mth = cl.getDeclaredMethod("invokeStaticTest", dcl);
- Object ret = mth.invoke(null, new Object[0]);
- assertEquals("Invoke returned incorrect value", 1, ((Integer) ret)
- .intValue());
-
- // Get and invoke an instance method
- mth = cl.getDeclaredMethod("invokeInstanceTest", dcl);
- ret = mth.invoke(new TestMethod(), new Object[0]);
- assertEquals("Invoke returned incorrect value", 1, ((Integer) ret)
- .intValue());
-
- // Get and attempt to invoke a private method
- mth = cl.getDeclaredMethod("privateInvokeTest", dcl);
- try {
- ret = mth.invoke(new TestMethod(), new Object[0]);
- } catch (IllegalAccessException e) {
- // Correct behaviour
- } catch (Exception e) {
- fail("Exception during invoke test : " + e.getMessage());
- }
- // Generate an IllegalArgumentException
- mth = cl.getDeclaredMethod("invokeInstanceTest", dcl);
-
- try {
- Object[] args = { Object.class };
- ret = mth.invoke(new TestMethod(), args);
- } catch (IllegalArgumentException e) {
- // Correct behaviour
- } catch (Exception e) {
- fail("Exception during invoke test : " + e.getMessage());
- }
-
- // Generate a NullPointerException
- mth = cl.getDeclaredMethod("invokeInstanceTest", dcl);
-
- try {
- ret = mth.invoke(null, new Object[0]);
- } catch (NullPointerException e) {
- // Correct behaviour
- } catch (Exception e) {
- fail("Exception during invoke test : " + e.getMessage());
- }
-
- // Generate an InvocationTargetException
- mth = cl.getDeclaredMethod("invokeExceptionTest", dcl);
- try {
- ret = mth.invoke(new TestMethod(), new Object[0]);
- } catch (InvocationTargetException e) {
- // Correct behaviour
- } catch (Exception e) {
- fail("Exception during invoke test : " + e.getMessage());
- }
-
- TestMethod testMethod = new TestMethod();
- Method methods[] = cl.getMethods();
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].getName().startsWith("invokeCastTest1")) {
- Class param = methods[i].getParameterTypes()[0];
-
- try {
- methods[i].invoke(testMethod, new Object[] { new Byte(
- (byte) 1) });
- assertTrue("invalid invoke with Byte: " + methods[i],
- param == Byte.TYPE || param == Short.TYPE
- || param == Integer.TYPE
- || param == Long.TYPE
- || param == Float.TYPE
- || param == Double.TYPE);
- } catch (Exception e) {
- assertTrue("Byte invalid exception: " + e,
- e instanceof IllegalArgumentException);
- assertTrue("Byte invalid failure: " + methods[i],
- param == Boolean.TYPE || param == Character.TYPE);
- }
-
- try {
- methods[i].invoke(testMethod, new Object[] { new Short(
- (short) 1) });
- assertTrue("invalid invoke with Short: " + methods[i],
- param == Short.TYPE || param == Integer.TYPE
- || param == Long.TYPE
- || param == Float.TYPE
- || param == Double.TYPE);
- } catch (Exception e) {
- assertTrue("Short invalid exception: " + e,
- e instanceof IllegalArgumentException);
- assertTrue("Short invalid failure: " + methods[i],
- param == Byte.TYPE || param == Boolean.TYPE
- || param == Character.TYPE);
- }
-
- try {
- methods[i].invoke(testMethod,
- new Object[] { new Integer(1) });
- assertTrue("invalid invoke with Integer: " + methods[i],
- param == Integer.TYPE || param == Long.TYPE
- || param == Float.TYPE
- || param == Double.TYPE);
- } catch (Exception e) {
- assertTrue("Integer invalid exception: " + e,
- e instanceof IllegalArgumentException);
- assertTrue("Integer invalid failure: " + methods[i],
- param == Byte.TYPE || param == Short.TYPE
- || param == Boolean.TYPE
- || param == Character.TYPE);
- }
-
- try {
- methods[i].invoke(testMethod, new Object[] { new Long(1) });
- assertTrue("invalid invoke with Long: " + methods[i],
- param == Long.TYPE || param == Float.TYPE
- || param == Double.TYPE);
- } catch (Exception e) {
- assertTrue("Long invalid exception: " + e,
- e instanceof IllegalArgumentException);
- assertTrue("Long invalid failure: " + methods[i],
- param == Byte.TYPE || param == Short.TYPE
- || param == Integer.TYPE
- || param == Boolean.TYPE
- || param == Character.TYPE);
- }
-
- try {
- methods[i].invoke(testMethod, new Object[] { new Character(
- 'a') });
- assertTrue("invalid invoke with Character: " + methods[i],
- param == Character.TYPE || param == Integer.TYPE
- || param == Long.TYPE
- || param == Float.TYPE
- || param == Double.TYPE);
- } catch (Exception e) {
- assertTrue("Character invalid exception: " + e,
- e instanceof IllegalArgumentException);
- assertTrue("Character invalid failure: " + methods[i],
- param == Byte.TYPE || param == Short.TYPE
- || param == Boolean.TYPE);
- }
-
- try {
- methods[i]
- .invoke(testMethod, new Object[] { new Float(1) });
- assertTrue("invalid invoke with Float: " + methods[i],
- param == Float.TYPE || param == Double.TYPE);
- } catch (Exception e) {
- assertTrue("Float invalid exception: " + e,
- e instanceof IllegalArgumentException);
- assertTrue("Float invalid failure: " + methods[i],
- param == Byte.TYPE || param == Short.TYPE
- || param == Integer.TYPE
- || param == Long.TYPE
- || param == Boolean.TYPE
- || param == Character.TYPE);
- }
-
- try {
- methods[i].invoke(testMethod,
- new Object[] { new Double(1) });
- assertTrue("invalid invoke with Double: " + methods[i],
- param == Double.TYPE);
- } catch (Exception e) {
- assertTrue("Double invalid exception: " + e,
- e instanceof IllegalArgumentException);
- assertTrue("Double invalid failure: " + methods[i],
- param == Byte.TYPE || param == Short.TYPE
- || param == Integer.TYPE
- || param == Long.TYPE
- || param == Boolean.TYPE
- || param == Character.TYPE
- || param == Float.TYPE);
- }
-
- try {
- methods[i].invoke(testMethod, new Object[] { new Boolean(
- true) });
- assertTrue("invalid invoke with Boolean: " + methods[i],
- param == Boolean.TYPE);
- } catch (Exception e) {
- assertTrue("Boolean invalid exception: " + e,
- e instanceof IllegalArgumentException);
- assertTrue("Boolean invalid failure: " + methods[i],
- param == Byte.TYPE || param == Short.TYPE
- || param == Integer.TYPE
- || param == Long.TYPE
- || param == Character.TYPE
- || param == Float.TYPE
- || param == Double.TYPE);
- }
- }
- }
- }
-
- /**
- * java.lang.reflect.Method#toString()
- */
- public void test_toString() {
- // Test for method java.lang.String java.lang.reflect.Method.toString()
- Method mth = null;
- Class[] parms = { int.class, short.class, String.class, boolean.class,
- Object.class, long.class, byte.class, char.class, double.class,
- float.class };
- try {
-
- mth = TestMethod.class.getDeclaredMethod("printTest", parms);
- } catch (Exception e) {
- fail("Exception during toString test : " + e.getMessage());
- }
-
- assertTrue(
- "Returned incorrect string for method: " + mth.toString(),
- mth
- .toString()
- .equals(
- "public static final void tests.api.java.lang.reflect.MethodTest$TestMethod.printTest(int,short,java.lang.String,boolean,java.lang.Object,long,byte,char,double,float)"));
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/ParameterizedTypeTest.java b/luni/src/test/java/tests/api/java/lang/reflect/ParameterizedTypeTest.java
deleted file mode 100644
index fcb9042..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/ParameterizedTypeTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-
-/**
- * Tests parameterized types and their properties.
- */
-public class ParameterizedTypeTest extends GenericReflectionTestsBase {
-
- static class A<T>{}
- static class B extends A<String>{}
-
- public void testStringParameterizedSuperClass() {
- Class<? extends B> clazz = B.class;
- Type genericSuperclass = clazz.getGenericSuperclass();
- assertInstanceOf(ParameterizedType.class, genericSuperclass);
- ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
- assertEquals(ParameterizedTypeTest.class, parameterizedType.getOwnerType());
- assertEquals(A.class, parameterizedType.getRawType());
-
- Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
- assertLenghtOne(actualTypeArguments);
- assertEquals(String.class, actualTypeArguments[0]);
- }
-
- static class C<T>{}
- static class D<T> extends C<T>{}
-
- public void testTypeParameterizedSuperClass() {
- Class<? extends D> clazz = D.class;
- Type genericSuperclass = clazz.getGenericSuperclass();
- assertInstanceOf(ParameterizedType.class, genericSuperclass);
- ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
- assertEquals(ParameterizedTypeTest.class, parameterizedType.getOwnerType());
- assertEquals(C.class, parameterizedType.getRawType());
-
- Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
- assertLenghtOne(actualTypeArguments);
- assertEquals(getTypeParameter(D.class), actualTypeArguments[0]);
- }
-
- static class E<T>{}
- static class F<T>{
- E<T> e;
- }
-
- public void testParameterizedMemeber() throws Exception{
- Class<? extends F> clazz = F.class;
- Field field = clazz.getDeclaredField("e");
- assertInstanceOf(ParameterizedType.class, field.getGenericType());
- ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
- assertEquals(ParameterizedTypeTest.class, parameterizedType.getOwnerType());
- assertEquals(E.class, parameterizedType.getRawType());
-
- Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
- assertLenghtOne(actualTypeArguments);
- assertEquals(getTypeParameter(clazz), actualTypeArguments[0]);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/ProxyTest.java b/luni/src/test/java/tests/api/java/lang/reflect/ProxyTest.java
deleted file mode 100644
index dd496b1..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/ProxyTest.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.UndeclaredThrowableException;
-
-import tests.support.Support_Proxy_I1;
-import tests.support.Support_Proxy_I2;
-import tests.support.Support_Proxy_ParentException;
-import tests.support.Support_Proxy_SubException;
-
-public class ProxyTest extends junit.framework.TestCase {
-
- /*
- * When multiple interfaces define the same method, the list of thrown
- * exceptions are those which can be mapped to another exception in the
- * other method:
- *
- * String foo(String s) throws SubException, LinkageError;
- *
- * UndeclaredThrowableException wrappers any checked exception which is not
- * in the merged list. So ParentException would be wrapped, BUT LinkageError
- * would not be since its not an Error/RuntimeException.
- *
- * interface I1 { String foo(String s) throws ParentException, LinkageError; }
- * interface I2 { String foo(String s) throws SubException, Error; }
- */
-
- interface Broken1 {
- public float method(float _number0, float _number1);
- }
-
- class Broken1Invoke implements InvocationHandler {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- return args[1];
- }
- }
-
- class ProxyCoonstructorTest extends Proxy {
- protected ProxyCoonstructorTest(InvocationHandler h) {
- super(h);
- }
- }
-
- /**
- * java.lang.reflect.Proxy#getProxyClass(java.lang.ClassLoader,
- * java.lang.Class[])
- */
- public void test_getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class() {
- Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
- .getClassLoader(), new Class[] { Support_Proxy_I1.class });
-
- assertTrue("Did not create a Proxy subclass ",
- proxy.getSuperclass() == Proxy.class);
- assertTrue("Does not believe its a Proxy class ", Proxy
- .isProxyClass(proxy));
-
- assertTrue("Does not believe it's a Proxy class ", Proxy
- .isProxyClass(Proxy.getProxyClass(null,
- new Class[] { Comparable.class })));
-
- try {
- Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
- (Class<?>[]) null);
- fail("NPE expected");
- } catch (NullPointerException expected) {
- }
-
- try {
- Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
- new Class<?>[] {Support_Proxy_I1.class, null});
- fail("NPE expected");
- } catch (NullPointerException expected) {
- }
- }
-
- /**
- * java.lang.reflect.Proxy#Proxy(java.lang.reflect.InvocationHandler)
- */
- public void test_ProxyLjava_lang_reflect_InvocationHandler() {
- assertNotNull(new ProxyCoonstructorTest(new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- return null;
- }
- }));
- }
-
-
-
- /**
- * java.lang.reflect.Proxy#newProxyInstance(java.lang.ClassLoader,
- * java.lang.Class[], java.lang.reflect.InvocationHandler)
- */
- public void test_newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler() {
- Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
- .getClassLoader(), new Class[] { Support_Proxy_I1.class,
- Support_Proxy_I2.class }, new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- if (method.getName().equals("equals"))
- return new Boolean(proxy == args[0]);
- if (method.getName().equals("array"))
- return new int[] { (int) ((long[]) args[0])[1], -1 };
- if (method.getName().equals("string")) {
- if ("".equals(args[0]))
- throw new Support_Proxy_SubException();
- if ("clone".equals(args[0]))
- throw new Support_Proxy_ParentException();
- if ("error".equals(args[0]))
- throw new ArrayStoreException();
- if ("any".equals(args[0]))
- throw new IllegalAccessException();
- }
- return null;
- }
- });
-
- Support_Proxy_I1 proxy = (Support_Proxy_I1) p;
- assertTrue("Failed identity test ", proxy.equals(proxy));
- assertTrue("Failed not equals test ", !proxy.equals(""));
- int[] result = (int[]) proxy.array(new long[] { 100L, -200L });
- assertEquals("Failed primitive type conversion test ", -200, result[0]);
-
- boolean worked = false;
- try {
- proxy.string("");
- } catch (Support_Proxy_SubException e) {
- worked = true;
- } catch (Support_Proxy_ParentException e) { // is never thrown
- }
- assertTrue("Problem converting exception ", worked);
-
- worked = false;
- try {
- proxy.string("clone");
- } catch (Support_Proxy_ParentException e) { // is never thrown
- } catch (UndeclaredThrowableException e) {
- worked = true;
- }
- assertTrue("Problem converting exception ", worked);
-
- worked = false;
- try {
- proxy.string("error");
- } catch (Support_Proxy_ParentException e) { // is never thrown
- } catch (UndeclaredThrowableException e) {
- } catch (RuntimeException e) {
- worked = e.getClass() == ArrayStoreException.class;
- }
- assertTrue("Problem converting exception ", worked);
-
- worked = false;
- try {
- proxy.string("any");
- } catch (Support_Proxy_ParentException e) { // is never thrown
- } catch (UndeclaredThrowableException e) {
- worked = true;
- }
- assertTrue("Problem converting exception ", worked);
-
- Broken1 proxyObject = null;
- try {
- proxyObject = (Broken1) Proxy.newProxyInstance(Broken1.class
- .getClassLoader(), new Class[] { Broken1.class },
- new Broken1Invoke());
- } catch (Throwable e) {
- fail("Failed to create proxy for class: " + Broken1.class + " - "
- + e);
- }
- float brokenResult = proxyObject.method(2.1f, 5.8f);
- assertTrue("Invalid invoke result", brokenResult == 5.8f);
- }
-
- /**
- * java.lang.reflect.Proxy#isProxyClass(java.lang.Class)
- */
- public void test_isProxyClassLjava_lang_Class() {
- Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
- .getClassLoader(), new Class[] { Support_Proxy_I1.class });
-
- class Fake extends Proxy {
- Fake() {
- super(null);
- }
- }
-
- Proxy fake = new Proxy(new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- return null;
- }
- }) {
- };
-
- assertTrue("Does not believe its a Proxy class ", Proxy
- .isProxyClass(proxy));
- assertTrue("Proxy subclasses do not count ", !Proxy
- .isProxyClass(Fake.class));
- assertTrue("Is not a runtime generated Proxy class ", !Proxy
- .isProxyClass(fake.getClass()));
- boolean thrown = false;
- try{
- Proxy.isProxyClass(null);
- } catch (NullPointerException ex){
- thrown = true;
- }
- assertTrue("NPE not thrown.", thrown);
- }
-
- /**
- * java.lang.reflect.Proxy#getInvocationHandler(java.lang.Object)
- */
- public void test_getInvocationHandlerLjava_lang_Object() {
- InvocationHandler handler = new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- return null;
- }
- };
-
- Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
- .getClassLoader(), new Class[] { Support_Proxy_I1.class },
- handler);
-
- assertTrue("Did not return invocation handler ", Proxy
- .getInvocationHandler(p) == handler);
- boolean aborted = false;
- try {
- Proxy.getInvocationHandler("");
- } catch (IllegalArgumentException e) {
- aborted = true;
- }
- assertTrue("Did not detect non proxy object ", aborted);
- }
-
- //Regression Test for HARMONY-2355
- public void test_newProxyInstance_withCompatibleReturnTypes() {
- Object o = Proxy
- .newProxyInstance(this.getClass().getClassLoader(),
- new Class[] { ITestReturnObject.class,
- ITestReturnString.class },
- new TestProxyHandler(new TestProxyImpl()));
- assertNotNull(o);
- }
-
- public void test_newProxyInstance_withNonCompatibleReturnTypes() {
- try {
- Proxy.newProxyInstance(this.getClass().getClassLoader(),
- new Class[] { ITestReturnInteger.class,
- ITestReturnString.class }, new TestProxyHandler(
- new TestProxyImpl()));
- fail("should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- }
-
- public static interface ITestReturnObject {
- Object f();
- }
-
- public static interface ITestReturnString {
- String f();
- }
-
- public static interface ITestReturnInteger {
- Integer f();
- }
-
- public static class TestProxyImpl implements ITestReturnObject,
- ITestReturnString {
- public String f() {
- // do nothing
- return null;
- }
- }
-
- public static class TestProxyHandler implements InvocationHandler {
- private Object proxied;
-
- public TestProxyHandler(Object object) {
- proxied = object;
- }
-
- public Object invoke(Object object, Method method, Object[] args)
- throws Throwable {
- // do nothing
- return method.invoke(proxied, args);
- }
-
- }
-
- protected void setUp() {
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/TypeVariableTest.java b/luni/src/test/java/tests/api/java/lang/reflect/TypeVariableTest.java
deleted file mode 100644
index cc22852..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/TypeVariableTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-
-/**
- * Tests type variables and their properties.
- */
-public class TypeVariableTest extends GenericReflectionTestsBase {
-
- static class A<T>{}
- public void testSimpleTypeVariableOnClass(){
- Class<? extends A> clazz = A.class;
- TypeVariable[] typeParameters = clazz.getTypeParameters();
- assertLenghtOne(typeParameters);
- TypeVariable<Class> typeVariable = typeParameters[0];
- assertEquals(clazz, typeVariable.getGenericDeclaration());
- assertEquals("T", typeVariable.getName());
- Type[] bounds = typeVariable.getBounds();
- assertLenghtOne(bounds);
- assertEquals(Object.class, bounds[0]);
- }
-
- static class B{
- <T> void b(){};
- }
- public void testSimpleTypeVariableOnMethod() throws Exception{
- Class<? extends B> clazz = B.class;
- Method method = clazz.getDeclaredMethod("b");
- TypeVariable<Method>[] typeParameters = method.getTypeParameters();
- assertLenghtOne(typeParameters);
- TypeVariable<Method> typeVariable = typeParameters[0];
- assertEquals(method, typeVariable.getGenericDeclaration());
- assertEquals("T", typeVariable.getName());
- Type[] bounds = typeVariable.getBounds();
- assertLenghtOne(bounds);
- assertEquals(Object.class, bounds[0]);
- }
-
- static class C {
- <T>C(){}
- }
- public void testSimpleTypeVariableOnConstructor() throws Exception{
- Class<? extends C> clazz = C.class;
- Constructor<?> constructor = clazz.getDeclaredConstructor();
- TypeVariable<?>[] typeParameters = constructor.getTypeParameters();
- assertLenghtOne(typeParameters);
- TypeVariable<?> typeVariable = typeParameters[0];
- assertEquals(constructor, typeVariable.getGenericDeclaration());
- assertEquals("T", typeVariable.getName());
- Type[] bounds = typeVariable.getBounds();
- assertLenghtOne(bounds);
- assertEquals(Object.class, bounds[0]);
- }
-
- static class D<Q,R,S>{}
- public void testMultipleTypeVariablesOnClass() throws Exception {
- Class<? extends D> clazz = D.class;
- TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
- assertEquals(3, typeParameters.length);
- assertEquals("Q", typeParameters[0].getName());
- assertEquals(clazz, typeParameters[0].getGenericDeclaration());
-
- assertEquals("R", typeParameters[1].getName());
- assertEquals(clazz, typeParameters[1].getGenericDeclaration());
-
- assertEquals("S", typeParameters[2].getName());
- assertEquals(clazz, typeParameters[2].getGenericDeclaration());
-
- }
-
- static class E {
- <Q,R,S> void e(){}
- }
- public void testMultipleTypeVariablesOnMethod() throws Exception {
- Class<? extends E> clazz = E.class;
- Method method = clazz.getDeclaredMethod("e");
-
- TypeVariable<?>[] typeParameters = method.getTypeParameters();
- assertEquals(3, typeParameters.length);
- assertEquals("Q", typeParameters[0].getName());
- assertEquals(method, typeParameters[0].getGenericDeclaration());
-
- assertEquals("R", typeParameters[1].getName());
- assertEquals(method, typeParameters[1].getGenericDeclaration());
-
- assertEquals("S", typeParameters[2].getName());
- assertEquals(method, typeParameters[2].getGenericDeclaration());
- }
-
- static class F {
- <Q,R,S> F(){}
- }
- public void testMultipleTypeVariablesOnConstructor() throws Exception {
- Class<? extends F> clazz = F.class;
- Constructor<?> constructor = clazz.getDeclaredConstructor();
-
- TypeVariable<?>[] typeParameters = constructor.getTypeParameters();
- assertEquals(3, typeParameters.length);
- assertEquals("Q", typeParameters[0].getName());
- assertEquals(constructor, typeParameters[0].getGenericDeclaration());
-
- assertEquals("R", typeParameters[1].getName());
- assertEquals(constructor, typeParameters[1].getGenericDeclaration());
-
- assertEquals("S", typeParameters[2].getName());
- assertEquals(constructor, typeParameters[2].getGenericDeclaration());
- }
-
- static class G <T extends Number>{}
-
- public void testSingleBound() throws Exception {
- Class<? extends G> clazz = G.class;
- TypeVariable[] typeParameters = clazz.getTypeParameters();
- TypeVariable<Class> typeVariable = typeParameters[0];
- Type[] bounds = typeVariable.getBounds();
- assertLenghtOne(bounds);
- assertEquals(Number.class, bounds[0]);
- }
-
- static class H <T extends Number & Serializable >{}
- public void testMultipleBound() throws Exception {
- Class<? extends H> clazz = H.class;
- TypeVariable[] typeParameters = clazz.getTypeParameters();
- TypeVariable<Class> typeVariable = typeParameters[0];
- Type[] bounds = typeVariable.getBounds();
- assertEquals(2, bounds.length);
- assertEquals(Number.class, bounds[0]);
- assertEquals(Serializable.class, bounds[1]);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/UndeclaredThrowableExceptionTests.java b/luni/src/test/java/tests/api/java/lang/reflect/UndeclaredThrowableExceptionTests.java
deleted file mode 100644
index 8fd2ff3..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/UndeclaredThrowableExceptionTests.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package tests.api.java.lang.reflect;
-
-import junit.framework.TestCase;
-
-import java.io.EOFException;
-import java.lang.reflect.UndeclaredThrowableException;
-
-public class UndeclaredThrowableExceptionTests extends TestCase {
-
- private static EOFException throwable = new EOFException();
- private static String msg = "TEST_MSG";
- /**
- * java.lang.reflect.UndeclaredThrowableException#getCause()
- */
- public void test_getCause() throws Exception {
- UndeclaredThrowableException ute = new UndeclaredThrowableException(
- throwable);
- assertSame("Wrong cause returned", throwable, ute.getCause());
- }
-
- /**
- * java.lang.reflect.UndeclaredThrowableException#getUndeclaredThrowable()
- */
- public void test_getUndeclaredThrowable() throws Exception {
- UndeclaredThrowableException ute = new UndeclaredThrowableException(
- throwable);
- assertSame("Wrong undeclared throwable returned", throwable, ute
- .getUndeclaredThrowable());
- }
-
- /**
- * java.lang.reflect.UndeclaredThrowableException#UndeclaredThrowableException(java.lang.Throwable)
- */
- public void test_Constructor_Throwable() throws Exception {
- UndeclaredThrowableException e = new UndeclaredThrowableException(
- throwable);
- assertEquals("Wrong cause returned", throwable, e.getCause());
- assertEquals("Wrong throwable returned", throwable, e
- .getUndeclaredThrowable());
- }
-
- /**
- * java.lang.reflect.UndeclaredThrowableException#UndeclaredThrowableException(java.lang.Throwable, java.lang.String)
- */
- public void test_Constructor_Throwable_String() throws Exception {
- UndeclaredThrowableException e = new UndeclaredThrowableException(
- throwable, msg);
- assertEquals("Wrong cause returned", throwable, e.getCause());
- assertEquals("Wrong throwable returned", throwable, e
- .getUndeclaredThrowable());
- assertEquals("Wrong message returned", msg, e.getMessage());
- }
-}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/WildcardTypeTest.java b/luni/src/test/java/tests/api/java/lang/reflect/WildcardTypeTest.java
deleted file mode 100644
index 9f8baeb..0000000
--- a/luni/src/test/java/tests/api/java/lang/reflect/WildcardTypeTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.lang.reflect;
-
-
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-
-/**
- * Tests bounded type parameters declared on methods and bounded wildcards.
- */
-public class WildcardTypeTest extends GenericReflectionTestsBase {
- @SuppressWarnings({"unchecked", "hiding"})
- static class BoundedWildcardsGenericMethods<T> {
-
- public <T extends BoundedWildcardsGenericMethods> void lowerBoundedParamNoReturn( BoundedWildcardsGenericMethods<? super T> param) {}
-
- public <T extends BoundedWildcardsGenericMethods> void upperBoundedParamNoReturn( BoundedWildcardsGenericMethods<? extends T> param) {}
-
- public <T extends BoundedWildcardsGenericMethods> T lowerBoundedParamReturn(BoundedWildcardsGenericMethods<? super T> param) { return (T) new Object(); }
-
- public <T extends BoundedWildcardsGenericMethods> T upperBoundedParamReturn(BoundedWildcardsGenericMethods<? extends T> param) { return (T) new Object();}
- }
-
- @SuppressWarnings("unchecked")
- private static Class<? extends BoundedWildcardsGenericMethods> clazz = BoundedWildcardsGenericMethods.class;
-
- /**
- * Tests that there are is one Type Parameter on the Class itself.
- */
- public void testBoundedGenericMethods() {
- assertLenghtOne(clazz.getTypeParameters());
- }
-
- /**
- * Tests whether the type parameter is bounded by BoundedGenericMethods like:
- * <T extends BoundedGenericMethods>.
- * @param method the declaring method
- */
- private void checkBoundedTypeParameter(Method method) {
- TypeVariable<Method> typeParameter = getTypeParameter(method);
- assertEquals("T", typeParameter.getName());
- assertEquals(method, typeParameter.getGenericDeclaration());
-
- Type[] bounds = typeParameter.getBounds();
- assertLenghtOne(bounds);
- Type bound = bounds[0];
- assertEquals(BoundedWildcardsGenericMethods.class, bound);
- }
-
- private void checkLowerBoundedParameter(Method method) {
- Type genericParameterType = method.getGenericParameterTypes()[0];
- assertInstanceOf(ParameterizedType.class, genericParameterType);
-
- ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
-
- Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
- assertLenghtOne(actualTypeArguments);
- assertInstanceOf(WildcardType.class, actualTypeArguments[0]);
-
- WildcardType wildcardType = (WildcardType) actualTypeArguments[0];
-
- Type[] lowerBounds = wildcardType.getLowerBounds();
- assertLenghtOne(lowerBounds);
- Type lowerBound = lowerBounds[0];
- assertEquals(getTypeParameter(method), lowerBound);
-
- Type[] upperBounds = wildcardType.getUpperBounds();
- assertEquals(Object.class, upperBounds[0]);
- }
-
- private void checkUpperBoundedParameter(Method method) {
- assertLenghtOne(method.getGenericParameterTypes());
- Type genericParameterType = method.getGenericParameterTypes()[0];
- assertInstanceOf(ParameterizedType.class, genericParameterType);
-
- ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
- Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
- assertLenghtOne(actualTypeArguments);
- assertInstanceOf(WildcardType.class, actualTypeArguments[0]);
-
- WildcardType wildcardType = (WildcardType) actualTypeArguments[0];
- assertLenghtZero(wildcardType.getLowerBounds());
-
- Type[] upperBounds = wildcardType.getUpperBounds();
- assertLenghtOne(upperBounds);
- Type upperBound = upperBounds[0];
- assertEquals(getTypeParameter(method), upperBound);
- }
-
- @SuppressWarnings("unchecked")
- private void checkReturnType(Method method) {
- Type genericReturnType = method.getGenericReturnType();
- assertEquals(getTypeParameter(method), genericReturnType);
- assertTrue(genericReturnType instanceof TypeVariable);
-
- TypeVariable<Method> returnTypeVariable = (TypeVariable<Method>) genericReturnType;
- assertEquals(method, returnTypeVariable.getGenericDeclaration());
-
- Type[] bounds = returnTypeVariable.getBounds();
- assertLenghtOne(bounds);
- Type bound = bounds[0];
-
- assertEquals(BoundedWildcardsGenericMethods.class, bound);
- }
-
- public void testUpperBoundedParamNoReturn() throws Exception {
- Method method = clazz.getMethod("upperBoundedParamNoReturn", BoundedWildcardsGenericMethods.class);
- checkBoundedTypeParameter(method);
- checkUpperBoundedParameter(method);
- }
-
- public void testLowerBoundedParamReturn() throws Exception {
- Method method = clazz.getMethod("lowerBoundedParamReturn", BoundedWildcardsGenericMethods.class);
- checkBoundedTypeParameter(method);
- checkLowerBoundedParameter(method);
- checkReturnType(method);
- }
-
- public void testUpperBoundedParamReturn() throws Exception {
- Method method = clazz.getMethod("upperBoundedParamReturn", BoundedWildcardsGenericMethods.class);
- checkBoundedTypeParameter(method);
- checkUpperBoundedParameter(method);
- checkReturnType(method);
- }
-
- public void testLowerBoundedParamNoReturn() throws Exception {
- Method method = clazz.getMethod("lowerBoundedParamNoReturn", BoundedWildcardsGenericMethods.class);
- checkBoundedTypeParameter(method);
- assertLenghtOne(method.getGenericParameterTypes());
- checkLowerBoundedParameter(method);
- }
-
-}
diff --git a/luni/src/test/java/tests/api/java/math/MathContextTest.java b/luni/src/test/java/tests/api/java/math/MathContextTest.java
deleted file mode 100644
index 9e04342..0000000
--- a/luni/src/test/java/tests/api/java/math/MathContextTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.math;
-
-import java.math.BigDecimal;
-import java.math.MathContext;
-import java.math.RoundingMode;
-
-public class MathContextTest extends junit.framework.TestCase {
-
- /**
- * java.math.MathContext#MathContext(...)
- */
- public void test_MathContextConstruction() {
- String a = "-12380945E+61";
- BigDecimal aNumber = new BigDecimal(a);
- MathContext mcIntRm6hd = new MathContext(6, RoundingMode.HALF_DOWN);
- MathContext mcStr6hd = new MathContext("precision=6 roundingMode=HALF_DOWN");
- MathContext mcInt6 = new MathContext(6);
- MathContext mcInt134 = new MathContext(134);
-
- // getPrecision()
- assertEquals("MathContext.getPrecision() returns incorrect value",
- 6, mcIntRm6hd.getPrecision() );
- assertEquals("MathContext.getPrecision() returns incorrect value",
- 134, mcInt134.getPrecision() );
-
- // getRoundingMode()
- assertEquals("MathContext.getRoundingMode() returns incorrect value",
- RoundingMode.HALF_UP,
- mcInt6.getRoundingMode());
- assertEquals("MathContext.getRoundingMode() returns incorrect value",
- RoundingMode.HALF_DOWN, mcIntRm6hd.getRoundingMode() );
-
- // toString()
- assertEquals("MathContext.toString() returning incorrect value",
- "precision=6 roundingMode=HALF_DOWN", mcIntRm6hd.toString() );
- assertEquals("MathContext.toString() returning incorrect value",
- "precision=6 roundingMode=HALF_UP", mcInt6.toString() );
-
- // equals(.)
- assertEquals("Equal MathContexts are not equal ",
- mcIntRm6hd, mcStr6hd );
- assertFalse("Different MathContexts are reported as equal ",
- mcInt6.equals(mcStr6hd) );
- assertFalse("Different MathContexts are reported as equal ",
- mcInt6.equals(mcInt134) );
-
- // hashCode(.)
- assertEquals("Equal MathContexts have different hashcodes ",
- mcIntRm6hd.hashCode(), mcStr6hd.hashCode() );
- assertFalse("Different MathContexts have equal hashcodes ",
- mcInt6.hashCode() == mcStr6hd.hashCode() );
- assertFalse("Different MathContexts have equal hashcodes ",
- mcInt6.hashCode() == mcInt134.hashCode() );
-
- // other:
- BigDecimal res = aNumber.abs(mcInt6);
- assertEquals("MathContext Constructor with int precision failed",
- new BigDecimal("1.23809E+68"),
- res);
- }
-
-}
diff --git a/luni/src/test/java/tests/api/java/math/OldBigIntegerTest.java b/luni/src/test/java/tests/api/java/math/OldBigIntegerTest.java
deleted file mode 100644
index 167ebe8..0000000
--- a/luni/src/test/java/tests/api/java/math/OldBigIntegerTest.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.math;
-
-import java.math.BigInteger;
-import java.util.Random;
-
-public class OldBigIntegerTest extends junit.framework.TestCase {
-
- BigInteger minusOne = new BigInteger("-1", 10);
-
- BigInteger two = new BigInteger("2", 10);
-
- BigInteger aZillion = new BigInteger("100000000000000000000000000000000000000000000000000", 10);
-
- Random rand = new Random();
-
- BigInteger bi;
-
- BigInteger bi2;
-
- BigInteger bi3;
-
- /**
- * java.math.BigInteger#BigInteger(int, java.util.Random)
- */
- public void test_ConstructorILjava_util_Random() {
- // regression test for HARMONY-1047
- try {
- new BigInteger(128, (Random) null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- bi = new BigInteger(70, rand);
- bi2 = new BigInteger(70, rand);
- assertTrue("Random number is negative", bi.compareTo(BigInteger.ZERO) >= 0);
- assertTrue("Random number is too big", bi.compareTo(two.pow(70)) < 0);
- assertTrue(
- "Two random numbers in a row are the same (might not be a bug but it very likely is)",
- !bi.equals(bi2));
- assertTrue("Not zero", new BigInteger(0, rand).equals(BigInteger.ZERO));
-
- try {
- new BigInteger(-1, (Random)null);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- // PASSED
- }
- }
-
- /**
- * java.math.BigInteger#BigInteger(int, int, java.util.Random)
- */
- // BIGNUM returns no Primes smaller than 16 bits.
- public void test_ConstructorIILjava_util_Random() {
- BigInteger bi1 = new BigInteger(10, 5, rand);
- BigInteger bi2 = new BigInteger(10, 5, rand);
- assertTrue(bi1 + " is negative", bi1.compareTo(BigInteger.ZERO) >= 0);
- assertTrue(bi1 + " is too big", bi1.compareTo(new BigInteger("1024", 10)) < 0);
- assertTrue(bi2 + " is negative", bi2.compareTo(BigInteger.ZERO) >= 0);
- assertTrue(bi2 + " is too big", bi2.compareTo(new BigInteger("1024", 10)) < 0);
-
- Random rand = new Random();
- BigInteger bi;
- int certainty[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -2, -1 };
- for (int i = 2; i <= 20; i++) {
- for (int c = 0; c < certainty.length; c++) {
- bi = new BigInteger(i, c, rand); // Create BigInteger
- assertEquals(i, bi.bitLength());
- }
- }
-
- try {
- new BigInteger(1, 80, (Random)null);
- fail("ArithmeticException expected");
- } catch (ArithmeticException expected) {
- }
-
- try {
- new BigInteger(-1, (Random)null);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException expected) {
- }
- }
-
-// public void test_SpecialPrimes() {
-// System.out.println("test_SpecialPrimes");
-// final BigInteger TWO = BigInteger.valueOf(2);
-// BigInteger p, q;
-// for (;;) {
-// p = new BigInteger(1024, 23, new Random());
-// q = p.subtract(BigInteger.ONE).divide(TWO);
-// if (q.isProbablePrime(20)) {
-// System.out.println(q);
-// System.out.println(p);
-// break;
-// }
-// System.out.print(".");
-// }
-// fail("isProbablePrime failed for: " + bi);
-// }
-
- /**
- * java.math.BigInteger#isProbablePrime(int)
- */
- public void test_isProbablePrimeI() {
- int fails = 0;
- bi = new BigInteger(20, 20, rand);
- if (!bi.isProbablePrime(17)) {
- fails++;
- }
- bi = new BigInteger("4", 10);
- if (bi.isProbablePrime(17)) {
- fail("isProbablePrime failed for: " + bi);
- }
- bi = BigInteger.valueOf(17L * 13L);
- if (bi.isProbablePrime(17)) {
- fail("isProbablePrime failed for: " + bi);
- }
- for (long a = 2; a < 1000; a++) {
- if (isPrime(a)) {
- assertTrue("false negative on prime number <1000", BigInteger
- .valueOf(a).isProbablePrime(5));
- } else if (BigInteger.valueOf(a).isProbablePrime(17)) {
- System.out.println("isProbablePrime failed for: " + a);
- fails++;
- }
- }
- for (int a = 0; a < 1000; a++) {
- bi = BigInteger.valueOf(rand.nextInt(1000000)).multiply(
- BigInteger.valueOf(rand.nextInt(1000000)));
- if (bi.isProbablePrime(17)) {
- System.out.println("isProbablePrime failed for: " + bi);
- fails++;
- }
- }
- for (int a = 0; a < 200; a++) {
- bi = new BigInteger(70, rand).multiply(new BigInteger(70, rand));
- if (bi.isProbablePrime(17)) {
- System.out.println("isProbablePrime failed for: " + bi);
- fails++;
- }
- }
- assertTrue("Too many false positives - may indicate a problem",
- fails <= 1);
-
- //
- // And now some tests on real big integers:
- //
- bi = new BigInteger("153890972191202256150310830154922163807316525358455215516067727076235016932726922093888770552128767458882963869421440585369743", 10);
- if (!bi.isProbablePrime(80)) {
- fail("isProbablePrime failed for: " + bi);
- }
- bi = new BigInteger("2090575416269141767246491983797422123741252476560371649798066134123893524014911825188890458270426076468664046568752890122415061377308817346303546688282957897504000216241497550243010257911214329646877810655164658470278901030511157372440751259674247310396158238588463284702737181653", 10);
- if (!bi.isProbablePrime(80)) {
- fail("isProbablePrime failed for: " + bi);
- }
- //
- for (int bitLength = 100; bitLength <= 600; bitLength += 100) {
- BigInteger a = BigInteger.probablePrime(bitLength, rand);
- BigInteger b = BigInteger.probablePrime(bitLength, rand);
- BigInteger c = a.multiply(b);
- assertFalse("isProbablePrime failed for product of two large primes" +
- a + " * " + b + " = " + c +
- " (bitLength = " + bitLength + ")",
- c.isProbablePrime(80) );
- }
- }
-
- /**
- * java.math.BigInteger#nextProbablePrime()
- */
- public void test_nextProbablePrime() {
- largePrimesProduct(
- new BigInteger("2537895984043447429238717358455377929009126353874925049325287329295635198252046158619999217453233889378619619008359011789"),
- new BigInteger("1711501451602688337873833423534849678524059393231999670806585630179374689152366029939952735718718709436427337762082614710093"),
- "4343612660706993434504106787562106084038357258130862545477481433639575850237346784798851102536616749334772541987502120552264920040629526028540204698334741815536099373917351194423681128374184971846099257056996626343051832131340568120612204287123"
- );
-
- largePrimesProduct(
- new BigInteger("4617974730611208463200675282934641082129817404749925308887287017217158545765190433369842932770197341032031682222405074564586462802072184047198214312142847809259437477387527466762251087500170588962277514858557309036550499896961735701485020851"),
- new BigInteger("4313158964405728158057980867015758419530142215799386331265837224051830838583266274443105715022196238165196727467066901495701708590167750818040112544031694506528759169669442493029999154074962566165293254671176670719518898684698255068313216294333"),
- "19918059106734861363335842730108905466210762564765297409619920041621379008685530738918145604092111306972524565803236031571858280032420140331838737621152630780261815015157696362550138161774466814661069892975003440654998880587960037013294137372709096788892473385003457361736563927256562678181177287998121131179907762285048659075843995525830945659905573174849006768920618442371027575308854641789533211132313916836205357976988977849024687805212304038260207820679964201211309384057458137851"
- );
- }
-
- static void largePrimesProduct(BigInteger a, BigInteger b, String c) {
- BigInteger wp = a.multiply(b);
- assertFalse("isProbablePrime failed for product of two large primes" +
- a + " * " + b + " = " + c,
- wp.isProbablePrime(80) );
- BigInteger wpMinusOne = wp.subtract(BigInteger.ONE);
- BigInteger next = wpMinusOne.nextProbablePrime();
-// System.out.println(c);
-// System.out.println(next);
- assertTrue("nextProbablePrime returns wrong number: " + next +
- "instead of expected: " + c,
- next.toString().equals(c) );
- }
-
- /**
- * java.math.BigInteger#probablePrime(int, java.util.Random)
- */
- public void test_probablePrime() {
- for (int bitLength = 50; bitLength <= 1050; bitLength += 100) {
- BigInteger a = BigInteger.probablePrime(bitLength, rand);
- assertTrue("isProbablePrime(probablePrime()) failed for: " + bi,
- a.isProbablePrime(80));
-// System.out.println(a);
-// BigInteger prime = a.nextProbablePrime();
-// System.out.print("Next Probable Prime is ");
-// System.out.println(prime);
- }
- }
-
-// BEGIN android-added
-// public void testModPowPerformance() {
-// Random rnd = new Random();
-// for (int i = 0; i < 10; i++) {
-// BigInteger a = new BigInteger(512, rnd);
-// BigInteger m = new BigInteger(1024, rnd);
-// BigInteger p = new BigInteger(256, rnd);
-// BigInteger mp = a.modPow(p, m);
-// System.out.println(mp);
-// }
-// }
-
-// shows factor 20 speed up (BIGNUM to Harmony Java):
-// public void testNextProbablePrime() {
-// Random rnd = new Random();
-// rnd.setSeed(0);
-// for (int i = 1; i <= 32; i += 1) {
-// BigInteger a = new BigInteger(i, rnd);
-// System.out.println(a);
-// BigInteger prime = a.nextProbablePrime();
-// System.out.print("Next Probable Prime is ");
-// System.out.println(prime);
-// }
-// for (int i = 1; i <= 32; i += 4) {
-// BigInteger a = new BigInteger(32 * i, rnd);
-// System.out.println(a);
-// BigInteger prime = a.nextProbablePrime();
-// System.out.print("Next Probable Prime is ");
-// System.out.println(prime);
-// }
-// }
-
-// shows factor 20 speed up (BIGNUM to Harmony Java):
-// shows that certainty 80 is "practically aquivalent" to certainty 100
-// public void testPrimeGenPerformance() {
-// Random rnd = new Random();
-// rnd.setSeed(0);
-// for (int i = 1; i <= 32; i +=8 ) {
-// BigInteger a = new BigInteger(32 * i, 80, rnd);
-// System.out.println(a);
-// System.out.println("Now testing it again:");
-// if (a.isProbablePrime(100)) {
-// System.out.println("************************ PASSED! **************************");
-// } else {
-// System.out.println("************************ FAILED!!! **************************");
-// System.out.println("************************ FAILED!!! **************************");
-// System.out.println("************************ FAILED!!! **************************");
-// System.out.println("************************ FAILED!!! **************************");
-// System.out.println("************************ FAILED!!! **************************");
-// System.out.println("************************ FAILED!!! **************************");
-// }
-// }
-// }
-// END android-added
-
-
-
- /**
- * java.math.BigInteger#add(java.math.BigInteger)
- */
- public void test_addLjava_math_BigInteger() {
- assertTrue("Incorrect sum--wanted a zillion", aZillion.add(aZillion)
- .add(aZillion.negate()).equals(aZillion));
- assertTrue("0+0", BigInteger.ZERO.add(BigInteger.ZERO).equals(BigInteger.ZERO));
- assertTrue("0+1", BigInteger.ZERO.add(BigInteger.ONE).equals(BigInteger.ONE));
- assertTrue("1+0", BigInteger.ONE.add(BigInteger.ZERO).equals(BigInteger.ONE));
- assertTrue("1+1", BigInteger.ONE.add(BigInteger.ONE).equals(two));
- assertTrue("0+(-1)", BigInteger.ZERO.add(minusOne).equals(minusOne));
- assertTrue("(-1)+0", minusOne.add(BigInteger.ZERO).equals(minusOne));
- assertTrue("(-1)+(-1)", minusOne.add(minusOne).equals(new BigInteger("-2", 10)));
- assertTrue("1+(-1)", BigInteger.ONE.add(minusOne).equals(BigInteger.ZERO));
- assertTrue("(-1)+1", minusOne.add(BigInteger.ONE).equals(BigInteger.ZERO));
-
- for (int i = 0; i < 200; i++) {
- BigInteger midbit = BigInteger.ZERO.setBit(i);
- assertTrue("add fails to carry on bit " + i, midbit.add(midbit)
- .equals(BigInteger.ZERO.setBit(i + 1)));
- }
- BigInteger bi2p3 = bi2.add(bi3);
- BigInteger bi3p2 = bi3.add(bi2);
- assertTrue("bi2p3=bi3p2", bi2p3.equals(bi3p2));
-
-
- // BESSER UEBERGREIFENDE TESTS MACHEN IN FORM VON STRESS TEST.
- // add large positive + small positive
- BigInteger sum = aZillion;
- BigInteger increment = BigInteger.ONE;
- for (int i = 0; i < 20; i++) {
-
- }
-
- // add large positive + small negative
-
- // add large negative + small positive
-
- // add large negative + small negative
- }
-
- public void testClone() {
- // Regression test for HARMONY-1770
- MyBigInteger myBigInteger = new MyBigInteger("12345");
- myBigInteger = (MyBigInteger) myBigInteger.clone();
- }
-
- static class MyBigInteger extends BigInteger implements Cloneable {
- public MyBigInteger(String val) {
- super(val);
- }
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e); // android-changed
- }
- }
- }
-
- @Override
- protected void setUp() {
- bi2 = new BigInteger("4576829475724387584378543764555", 16);
- bi3 = new BigInteger("43987298363278574365732645872643587624387563245", 16);
- }
-
- private boolean isPrime(long b) {
- if (b == 2) {
- return true;
- }
- // check for div by 2
- if ((b & 1L) == 0) {
- return false;
- }
- long maxlen = ((long) Math.sqrt(b)) + 2;
- for (long x = 3; x < maxlen; x += 2) {
- if (b % x == 0) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/math/RoundingModeTest.java b/luni/src/test/java/tests/api/java/math/RoundingModeTest.java
deleted file mode 100644
index 50a77df..0000000
--- a/luni/src/test/java/tests/api/java/math/RoundingModeTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.math;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-
-public class RoundingModeTest extends junit.framework.TestCase {
-
- /**
- * java.math.RoundingMode#valueOf(int)
- */
- public void test_valueOfI() {
- assertEquals("valueOf failed for ROUND_CEILING", RoundingMode.valueOf(BigDecimal.ROUND_CEILING), RoundingMode.CEILING);
- assertEquals("valueOf failed for ROUND_DOWN", RoundingMode.valueOf(BigDecimal.ROUND_DOWN), RoundingMode.DOWN);
- assertEquals("valueOf failed for ROUND_FLOOR", RoundingMode.valueOf(BigDecimal.ROUND_FLOOR), RoundingMode.FLOOR);
- assertEquals("valueOf failed for ROUND_HALF_DOWN", RoundingMode.valueOf(BigDecimal.ROUND_HALF_DOWN), RoundingMode.HALF_DOWN);
- assertEquals("valueOf failed for ROUND_HALF_EVEN", RoundingMode.valueOf(BigDecimal.ROUND_HALF_EVEN), RoundingMode.HALF_EVEN);
- assertEquals("valueOf failed for ROUND_HALF_UP", RoundingMode.valueOf(BigDecimal.ROUND_HALF_UP), RoundingMode.HALF_UP);
- assertEquals("valueOf failed for ROUND_UNNECESSARY", RoundingMode.valueOf(BigDecimal.ROUND_UNNECESSARY), RoundingMode.UNNECESSARY);
- assertEquals("valueOf failed for ROUND_UP", RoundingMode.valueOf(BigDecimal.ROUND_UP), RoundingMode.UP);
- try {
- RoundingMode.valueOf(13);
- fail("IllegalArgumentException expected for RoundingMode(13)");
- } catch (IllegalArgumentException e) {
- }
- try {
- RoundingMode.valueOf(-1);
- fail("IllegalArgumentException expected for RoundingMode(-1)");
- } catch (IllegalArgumentException e) {
- }
- }
-
-}
diff --git a/luni/src/test/java/tests/api/java/util/AbstractListTest.java b/luni/src/test/java/tests/api/java/util/AbstractListTest.java
deleted file mode 100644
index 3cda30f..0000000
--- a/luni/src/test/java/tests/api/java/util/AbstractListTest.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.RandomAccess;
-
-public class AbstractListTest extends junit.framework.TestCase {
-
- static class SimpleList extends AbstractList {
- ArrayList arrayList;
-
- SimpleList() {
- this.arrayList = new ArrayList();
- }
-
- public Object get(int index) {
- return this.arrayList.get(index);
- }
-
- public void add(int i, Object o) {
- this.arrayList.add(i, o);
- }
-
- public Object remove(int i) {
- return this.arrayList.remove(i);
- }
-
- public int size() {
- return this.arrayList.size();
- }
- }
-
- /**
- * java.util.AbstractList#hashCode()
- */
- public void test_hashCode() {
-
- List list = new ArrayList();
- list.add(new Integer(3));
- list.add(new Integer(15));
- list.add(new Integer(5));
- list.add(new Integer(1));
- list.add(new Integer(7));
- int hashCode = 1;
- Iterator i = list.iterator();
- while (i.hasNext()) {
- Object obj = i.next();
- hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
- }
- assertTrue("Incorrect hashCode returned. Wanted: " + hashCode
- + " got: " + list.hashCode(), hashCode == list.hashCode());
- }
-
- /**
- * java.util.AbstractList#iterator()
- */
- public void test_iterator() {
- SimpleList list = new SimpleList();
- list.add(new Object());
- list.add(new Object());
- Iterator it = list.iterator();
- it.next();
- it.remove();
- it.next();
- }
-
- /**
- * java.util.AbstractList#listIterator()
- */
- public void test_listIterator() {
- Integer tempValue;
- List list = new ArrayList();
- list.add(new Integer(3));
- list.add(new Integer(15));
- list.add(new Integer(5));
- list.add(new Integer(1));
- list.add(new Integer(7));
- ListIterator lit = list.listIterator();
- assertTrue("Should not have previous", !lit.hasPrevious());
- assertTrue("Should have next", lit.hasNext());
- tempValue = (Integer) lit.next();
- assertTrue("next returned wrong value. Wanted 3, got: " + tempValue,
- tempValue.intValue() == 3);
- tempValue = (Integer) lit.previous();
-
- SimpleList list2 = new SimpleList();
- list2.add(new Object());
- ListIterator lit2 = list2.listIterator();
- lit2.add(new Object());
- lit2.next();
- }
-
- /**
- * java.util.AbstractList#subList(int, int)
- */
- public void test_subListII() {
- // Test each of the SubList operations to ensure a
- // ConcurrentModificationException does not occur on an AbstractList
- // which does not update modCount
- SimpleList mList = new SimpleList();
- mList.add(new Object());
- mList.add(new Object());
- List sList = mList.subList(0, 2);
- sList.add(new Object()); // calls add(int, Object)
- sList.get(0);
-
- sList.add(0, new Object());
- sList.get(0);
-
- sList.addAll(Arrays.asList(new String[] { "1", "2" }));
- sList.get(0);
-
- sList.addAll(0, Arrays.asList(new String[] { "3", "4" }));
- sList.get(0);
-
- sList.remove(0);
- sList.get(0);
-
- ListIterator lit = sList.listIterator();
- lit.add(new Object());
- lit.next();
- lit.remove();
- lit.next();
-
- sList.clear(); // calls removeRange()
- sList.add(new Object());
-
- // test the type of sublist that is returned
- List al = new ArrayList();
- for (int i = 0; i < 10; i++) {
- al.add(new Integer(i));
- }
- assertTrue(
- "Sublist returned should have implemented Random Access interface",
- al.subList(3, 7) instanceof RandomAccess);
-
- List ll = new LinkedList();
- for (int i = 0; i < 10; i++) {
- ll.add(new Integer(i));
- }
- assertTrue(
- "Sublist returned should not have implemented Random Access interface",
- !(ll.subList(3, 7) instanceof RandomAccess));
-
- }
-
- /**
- * java.util.AbstractList#subList(int, int)
- */
- public void test_subList_empty() {
- // Regression for HARMONY-389
- List al = new ArrayList();
- al.add("one");
- List emptySubList = al.subList(0, 0);
-
- try {
- emptySubList.get(0);
- fail("emptySubList.get(0) should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- emptySubList.set(0, "one");
- fail("emptySubList.set(0,Object) should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
-
- try {
- emptySubList.remove(0);
- fail("emptySubList.remove(0) should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- // expected
- }
- }
-
- /**
- * java.util.AbstractList#subList(int, int)
- */
- public void test_subList_addAll() {
- // Regression for HARMONY-390
- List mainList = new ArrayList();
- Object[] mainObjects = { "a", "b", "c" };
- mainList.addAll(Arrays.asList(mainObjects));
- List subList = mainList.subList(1, 2);
- assertFalse("subList should not contain \"a\"", subList.contains("a"));
- assertFalse("subList should not contain \"c\"", subList.contains("c"));
- assertTrue("subList should contain \"b\"", subList.contains("b"));
-
- Object[] subObjects = { "one", "two", "three" };
- subList.addAll(Arrays.asList(subObjects));
- assertFalse("subList should not contain \"a\"", subList.contains("a"));
- assertFalse("subList should not contain \"c\"", subList.contains("c"));
-
- Object[] expected = { "b", "one", "two", "three" };
- ListIterator iter = subList.listIterator();
- for (int i = 0; i < expected.length; i++) {
- assertTrue("subList should contain " + expected[i], subList
- .contains(expected[i]));
- assertTrue("should be more elements", iter.hasNext());
- assertEquals("element in incorrect position", expected[i], iter
- .next());
- }
- }
-
- public void test_indexOfLjava_lang_Object() {
- AbstractList al = new ArrayList();
- al.add(0);
- al.add(1);
- al.add(2);
- al.add(3);
- al.add(4);
-
- assertEquals(-1, al.indexOf(5));
- assertEquals(2, al.indexOf(2));
- }
-
- public void test_lastIndexOfLjava_lang_Object() {
- AbstractList al = new ArrayList();
- al.add(0);
- al.add(1);
- al.add(2);
- al.add(2);
- al.add(2);
- al.add(2);
- al.add(2);
- al.add(3);
- al.add(4);
-
- assertEquals(-1, al.lastIndexOf(5));
- assertEquals(6, al.lastIndexOf(2));
- }
-
- public void test_listIteratorI() {
- AbstractList al1 = new ArrayList();
- AbstractList al2 = new ArrayList();
- al1.add(0);
- al1.add(1);
- al1.add(2);
- al1.add(3);
- al1.add(4);
- al2.add(2);
- al2.add(3);
- al2.add(4);
-
- Iterator li1 = al1.listIterator(2);
- Iterator li2 = al2.listIterator();
-
- while(li1.hasNext()&&li2.hasNext()) {
- assertEquals(li1.next(), li2.next());
- }
- assertSame(li1.hasNext(),li2.hasNext());
-
- try {
- al1.listIterator(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- try {
- al1.listIterator(al1.size() + 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
- }
-
- protected void doneSuite() {}
-}
diff --git a/luni/src/test/java/tests/api/java/util/AbstractMapTest.java b/luni/src/test/java/tests/api/java/util/AbstractMapTest.java
deleted file mode 100644
index c8f9ce2..0000000
--- a/luni/src/test/java/tests/api/java/util/AbstractMapTest.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.AbstractMap;
-import java.util.AbstractSet;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.Vector;
-import java.util.WeakHashMap;
-
-public class AbstractMapTest extends junit.framework.TestCase {
-
- static final String specialKey = "specialKey".intern();
-
- static final String specialValue = "specialValue".intern();
-
- // The impl of MyMap is not realistic, but serves to create a type
- // that uses the default remove behavior.
- class MyMap extends AbstractMap {
- final Set mySet = new HashSet(1);
-
- MyMap() {
- mySet.add(new Map.Entry() {
- public Object getKey() {
- return specialKey;
- }
-
- public Object getValue() {
- return specialValue;
- }
-
- public Object setValue(Object object) {
- return null;
- }
- });
- }
-
- public Object put(Object key, Object value) {
- return null;
- }
-
- public Set entrySet() {
- return mySet;
- }
- }
-
- /**
- * java.util.AbstractMap#keySet()
- */
- public void test_keySet() {
- AbstractMap map1 = new HashMap(0);
- assertSame("HashMap(0)", map1.keySet(), map1.keySet());
-
- AbstractMap map2 = new HashMap(10);
- assertSame("HashMap(10)", map2.keySet(), map2.keySet());
-
- Map map3 = Collections.EMPTY_MAP;
- assertSame("EMPTY_MAP", map3.keySet(), map3.keySet());
-
- AbstractMap map4 = new IdentityHashMap(1);
- assertSame("IdentityHashMap", map4.keySet(), map4.keySet());
-
- AbstractMap map5 = new LinkedHashMap(122);
- assertSame("LinkedHashMap", map5.keySet(), map5.keySet());
-
- AbstractMap map6 = new TreeMap();
- assertSame("TreeMap", map6.keySet(), map6.keySet());
-
- AbstractMap map7 = new WeakHashMap();
- assertSame("WeakHashMap", map7.keySet(), map7.keySet());
- }
-
- /**
- * java.util.AbstractMap#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- Object key = new Object();
- Object value = new Object();
-
- AbstractMap map1 = new HashMap(0);
- map1.put("key", value);
- assertSame("HashMap(0)", map1.remove("key"), value);
-
- AbstractMap map4 = new IdentityHashMap(1);
- map4.put(key, value);
- assertSame("IdentityHashMap", map4.remove(key), value);
-
- AbstractMap map5 = new LinkedHashMap(122);
- map5.put(key, value);
- assertSame("LinkedHashMap", map5.remove(key), value);
-
- AbstractMap map6 = new TreeMap(new Comparator() {
- // Bogus comparator
- public int compare(Object object1, Object object2) {
- return 0;
- }
- });
- map6.put(key, value);
- assertSame("TreeMap", map6.remove(key), value);
-
- AbstractMap map7 = new WeakHashMap();
- map7.put(key, value);
- assertSame("WeakHashMap", map7.remove(key), value);
-
- AbstractMap aSpecialMap = new MyMap();
- aSpecialMap.put(specialKey, specialValue);
- Object valueOut = aSpecialMap.remove(specialKey);
- assertSame("MyMap", valueOut, specialValue);
- }
-
- /**
- * java.util.AbstractMap#values()
- */
- public void test_values() {
- AbstractMap map1 = new HashMap(0);
- assertSame("HashMap(0)", map1.values(), map1.values());
-
- AbstractMap map2 = new HashMap(10);
- assertSame("HashMap(10)", map2.values(), map2.values());
-
- Map map3 = Collections.EMPTY_MAP;
- assertSame("EMPTY_MAP", map3.values(), map3.values());
-
- AbstractMap map4 = new IdentityHashMap(1);
- assertSame("IdentityHashMap", map4.values(), map4.values());
-
- AbstractMap map5 = new LinkedHashMap(122);
- assertSame("IdentityHashMap", map5.values(), map5.values());
-
- AbstractMap map6 = new TreeMap();
- assertSame("TreeMap", map6.values(), map6.values());
-
- AbstractMap map7 = new WeakHashMap();
- assertSame("WeakHashMap", map7.values(), map7.values());
- }
-
- /**
- * java.util.AbstractMap#clone()
- */
- public void test_clone() {
- class MyMap extends AbstractMap implements Cloneable {
- private Map map = new HashMap();
-
- public Set entrySet() {
- return map.entrySet();
- }
-
- public Object put(Object key, Object value) {
- return map.put(key, value);
- }
-
- public Map getMap() {
- return map;
- }
-
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e); // android-changed
- }
- }
- }
- ;
- MyMap map = new MyMap();
- map.put("one", "1");
- Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
- assertTrue("entry not added", entry.getKey() == "one"
- && entry.getValue() == "1");
- MyMap mapClone = (MyMap) map.clone();
- assertTrue("clone not shallow", map.getMap() == mapClone.getMap());
- }
-
- public class AMT extends AbstractMap {
-
- // Very crude AbstractMap implementation
- Vector values = new Vector();
- Vector keys = new Vector();
-
- public Set entrySet() {
- return new AbstractSet() {
- public Iterator iterator() {
- return new Iterator() {
- int index = 0;
-
- public boolean hasNext() {
- return index < values.size();
- }
-
- public Object next() {
- if (index < values.size()) {
- Map.Entry me = new Map.Entry() {
- Object v = values.elementAt(index);
-
- Object k = keys.elementAt(index);
-
- public Object getKey() {
- return k;
- }
-
- public Object getValue() {
- return v;
- }
-
- public Object setValue(Object value) {
- return null;
- }
- };
- index++;
- return me;
- }
- return null;
- }
-
- public void remove() {
- }
- };
- }
-
- public int size() {
- return values.size();
- }
- };
- }
-
- public Object put(Object k, Object v) {
- keys.add(k);
- values.add(v);
- return v;
- }
- }
-
- /**
- * {@link java.util.AbstractMap#putAll(Map)}
- */
- public void test_putAllLMap() {
- Hashtable ht = new Hashtable();
- AMT amt = new AMT();
- ht.put("this", "that");
- amt.putAll(ht);
-
- assertEquals("Should be equal", amt, ht);
- }
-
- public void testEqualsWithNullValues() {
- Map<String, String> a = new HashMap<String, String>();
- a.put("a", null);
- a.put("b", null);
-
- Map<String, String> b = new HashMap<String, String>();
- a.put("c", "cat");
- a.put("d", "dog");
-
- assertFalse(a.equals(b));
- assertFalse(b.equals(a));
- }
-
- public void testNullsOnViews() {
- Map<String, String> nullHostile = new Hashtable<String, String>();
-
- nullHostile.put("a", "apple");
- testNullsOnView(nullHostile.entrySet());
-
- nullHostile.put("a", "apple");
- testNullsOnView(nullHostile.keySet());
-
- nullHostile.put("a", "apple");
- testNullsOnView(nullHostile.values());
- }
-
- private void testNullsOnView(Collection<?> view) {
- try {
- assertFalse(view.contains(null));
- } catch (NullPointerException optional) {
- }
-
- try {
- assertFalse(view.remove(null));
- } catch (NullPointerException optional) {
- }
-
- Set<Object> setOfNull = Collections.singleton(null);
- assertFalse(view.equals(setOfNull));
-
- try {
- assertFalse(view.removeAll(setOfNull));
- } catch (NullPointerException optional) {
- }
-
- try {
- assertTrue(view.retainAll(setOfNull)); // destructive
- } catch (NullPointerException optional) {
- }
- }
-
- protected void setUp() {
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/AbstractQueueTest.java b/luni/src/test/java/tests/api/java/util/AbstractQueueTest.java
deleted file mode 100644
index 5ae490c..0000000
--- a/luni/src/test/java/tests/api/java/util/AbstractQueueTest.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.util;
-
-import java.util.AbstractQueue;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-
-import junit.framework.TestCase;
-
-public class AbstractQueueTest extends TestCase {
-
- private MockAbstractQueue<Object> queue;
-
- private class MockAbstractQueue<E> extends AbstractQueue<E> {
-
- static final int CAPACITY = 10;
-
- private int size = 0;
-
- private Object[] elements = new Object[CAPACITY];
-
- public Iterator<E> iterator() {
- return new Iterator<E>() {
-
- private int currentIndex = -1;
-
- public boolean hasNext() {
- return size > 0 && currentIndex < size;
- }
-
- public E next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- currentIndex++;
- return (E) elements[currentIndex];
- }
-
- public void remove() {
- if (-1 == currentIndex) {
- throw new IllegalStateException();
- }
- for (int i = currentIndex; i < size - 1; i++) {
- elements[i] = elements[i + 1];
- }
- size--;
- }
- };
- }
-
- public int size() {
- return size;
- }
-
- public boolean offer(E o) {
- if (null == o) {
- throw new NullPointerException();
- }
-
- if (size >= CAPACITY) {
- return false;
- }
-
- elements[size++] = o;
- return true;
- }
-
- public E poll() {
- if (isEmpty()) {
- return null;
- }
- E e = (E) elements[0];
- for (int i = 0; i < size - 1; i++) {
- elements[i] = elements[i + 1];
- }
- size--;
- return e;
- }
-
- public E peek() {
- if (isEmpty()) {
- return null;
- }
- return (E) elements[0];
- }
-
- }
-
- /**
- * java.util.AbstractQueue.add(E)
- */
- public void test_addLE_null() {
- try {
- queue.add(null);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * java.util.AbstractQueue.add(E)
- */
- public void test_addLE_Full() {
- Object o = new Object();
-
- for(int i = 0; i < MockAbstractQueue.CAPACITY; i++ ) {
- queue.add(o);
- }
-
- try {
- queue.add(o);
- fail("should throw IllegalStateException");
- } catch (IllegalStateException e) {
- //expected
- }
- }
-
- /**
- * java.util.AbstractQueue#add(E)
- */
- public void test_addLE() {
- Object o = new Object();
- final int LAST_INDEX = 4;
- for (int i = 0; i < LAST_INDEX; i++) {
- queue.add(o);
- }
- Integer I = new Integer(123456);
- queue.add(I);
- assertTrue(queue.contains(I));
- Iterator iter = queue.iterator();
- for (int i = 0; i < LAST_INDEX; i++) {
- iter.next();
- }
- assertTrue(I == iter.next());
- }
-
- /**
- * java.util.AbstractQueue#addAll(E)
- */
- public void test_addAllLE_null() {
- try {
- queue.addAll(null);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * java.util.AbstractQueue#addAll(E)
- */
- public void test_addAllLE_with_null() {
- List list = Arrays.asList("MYTESTSTRING", null, new Float(123.456));
- try {
- queue.addAll(list);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * java.util.AbstractQueue#addAll(E)
- */
- public void test_addAllLE_full() {
- List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
- try {
- queue.addAll(list);
- fail("should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // expected
- }
- }
-
- /**
- * java.util.AbstractQueue#addAll(E)
- */
- public void test_addAllLE_empty() {
- // Regression test for HARMONY-1178
- List list = new ArrayList<Object>(0);
- assertFalse("Non modification to queue should return false", queue.addAll(list));
- }
-
- /**
- * java.util.AbstractQueue#addAll(E)
- */
- public void test_addAllLE_this() {
- try {
- queue.addAll(queue);
- fail("should throw IllegalArgumentException ");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void test_addAllLjava_lang_Object() {
- Collection c = new Vector();
-
- c.add(0);
- c.add(1);
- c.add(2);
- c.add(3);
- c.add(4);
- c.add(5);
-
- assertTrue(queue.addAll(c));
- assertEquals(6, queue.size());
- }
-
- /**
- * java.util.AbstractQueue#clear()
- */
- public void test_clear_empty() {
- queue.clear();
- assertTrue(queue.isEmpty());
- assertNull(queue.peek());
- }
-
- /**
- * java.util.AbstractQueue#clear()
- */
- public void test_clear() {
- List list = Arrays.asList(123.456, "MYTESTSTRING", new Object(), 'c');
- queue.addAll(list);
- queue.clear();
- assertTrue(queue.isEmpty());
- assertNull(queue.peek());
- }
-
- /**
- * java.util.AbstractQueue#AbstractQueue()
- */
- public void test_Constructor() {
- MockAbstractQueue queue = new MockAbstractQueue();
- assertNotNull(queue);
- }
-
- /**
- * java.util.AbstractQueue#remove()
- */
- public void test_remove_null() {
- try {
- queue.remove();
- fail("should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // expected
- }
-
- }
-
- /**
- * java.util.AbstractQueue#remove()
- */
- public void test_remove() {
- char c = 'a';
- queue.add(c);
- c = 'b';
- queue.add(c);
- assertEquals('a', queue.remove());
- assertEquals('b', queue.remove());
- try {
- queue.remove();
- fail("should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // expected
- }
- }
-
- /**
- * java.util.AbstractQueue#element()
- */
- public void test_element_empty() {
- try {
- queue.element();
- fail("should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // expected
- }
- }
-
- /**
- * java.util.AbstractQueue#element()
- */
- public void test_element() {
- String s = "MYTESTSTRING_ONE";
- queue.add(s);
- s = "MYTESTSTRING_TWO";
- queue.add(s);
- assertEquals("MYTESTSTRING_ONE", queue.element());
- // still the first element
- assertEquals("MYTESTSTRING_ONE", queue.element());
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- queue = new MockAbstractQueue<Object>();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- queue = null;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/AbstractSequentialListTest.java b/luni/src/test/java/tests/api/java/util/AbstractSequentialListTest.java
deleted file mode 100644
index 2068f1b..0000000
--- a/luni/src/test/java/tests/api/java/util/AbstractSequentialListTest.java
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.util;
-
-import java.util.AbstractSequentialList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Vector;
-
-import junit.framework.TestCase;
-
-public class AbstractSequentialListTest extends TestCase {
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- class ASLT<E> extends AbstractSequentialList<E> {
-
- LinkedList<E> l = new LinkedList<E>();
-
- @Override
- public ListIterator<E> listIterator(int index) {
- return l.listIterator(index);
- }
-
- @Override
- public int size() {
- return l.size();
- }
- }
-
- /**
- * {@link java.util.AbstractSequentialList#addAll(int, java.util.Collection)}
- */
- public void test_addAll_ILCollection() {
- AbstractSequentialList<String> al = new ASLT<String>();
- String[] someList = { "Aardvark" ,
- "Bear" ,
- "Chimpanzee",
- "Duck" };
- Collection<String> c = Arrays.asList(someList);
- al.addAll(c);
- assertTrue("Should return true", al.addAll(2, c));
- }
-
- class Mock_unsupportedListIterator implements ListIterator {
- public void add(Object o) {
- throw new UnsupportedOperationException();
- }
-
- public boolean hasNext() {
- return true;
- }
-
- public boolean hasPrevious() {
- return false;
- }
-
- public Object next() {
- return null;
- }
-
- public int nextIndex() {
- return 0;
- }
-
- public Object previous() {
- return null;
- }
-
- public int previousIndex() {
- return 0;
- }
-
- public void remove() {
- }
-
- public void set(Object o) {
- throw new UnsupportedOperationException();
- }
- }
-
- class Mock_ListIterator<E> implements ListIterator<E> {
- final String wrongElement = "String";
- public void add(E o) {
- if (o.equals(wrongElement)) throw new IllegalArgumentException();
- if (o == null) throw new NullPointerException();
- }
-
- public boolean hasNext() {
- return false;
- }
-
- public boolean hasPrevious() {
- return false;
- }
-
- public E next() {
- return null;
- }
-
- public int nextIndex() {
- return 0;
- }
-
- public E previous() {
- return null;
- }
-
- public int previousIndex() {
- return 0;
- }
-
- public void remove() {
- }
-
- public void set(E o) {
- }
- }
-
- public void test_addAllILjava_util_Collection() {
- AbstractSequentialList asl = new AbstractSequentialList() {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- return new Mock_unsupportedListIterator();
- }
- };
- Collection strV = new Vector<String>();
-
- strV.add("String");
- strV.add("1");
- strV.add("3.14");
-
- try {
- asl.addAll(0, strV);
- fail("UnsupportedOperationException expected.");
- } catch (UnsupportedOperationException ee) {
- //expected
- }
- try {
- asl.addAll(0, null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- //ClassCastException can not be checked for this method.
-
- asl = new AbstractSequentialList() {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- return new Mock_ListIterator();
- }
- };
-
- try {
- asl.addAll(0, strV);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- strV.remove("String");
- strV.add(null);
-
- try {
- asl.addAll(0, strV);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
-
- strV.remove(null);
- asl.addAll(0, strV);
-
- asl = new LinkedList();
-
- try {
- asl.addAll(-10, strV);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- asl.addAll(1, strV);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- public void test_addILjava_lang_Object() {
- AbstractSequentialList asl = new AbstractSequentialList() {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- return new Mock_unsupportedListIterator();
- }
- };
-
- try {
- asl.add(0, 1);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
-
- asl = new AbstractSequentialList() {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- return new Mock_ListIterator();
- }
- };
-
- try {
- asl.add(0, "String");
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ee) {
- //expected
- }
-
- try {
- asl.add(0, null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- //ClassCastException can not be checked for this method.
-
- asl.add(0, 1);
-
- asl = new LinkedList();
-
- try {
- asl.add(-1, 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- asl.add(0, 1);
-
- try {
- asl.add(2, 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
- }
-
- public void test_getI() {
- final String buff[] = {"0", "1", "2", "3", "4", "5"};
- AbstractSequentialList asl = new AbstractSequentialList() {
- int currPos = 0;
-
- @Override
- public int size() {
- return buff.length;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- currPos = index;
- return new ListIterator() {
- public void add(Object o) {
- }
-
- public boolean hasNext() {
- return true;
- }
-
- public boolean hasPrevious() {
- return false;
- }
-
- public Object next() {
- return buff[currPos];
- }
-
- public int nextIndex() {
- return 0;
- }
-
- public Object previous() {
- return null;
- }
-
- public int previousIndex() {
- return 0;
- }
-
- public void remove() {
- }
-
- public void set(Object o) {
- }
- };
- }
- };
-
- for (int i = 0; i < buff.length; i++) {
- assertEquals(buff[i], asl.get(i));
- }
-
- try {
- asl.get(asl.size() + 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- asl.get(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- public void test_iterrator() {
- AbstractSequentialList asl = new AbstractSequentialList() {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- return new Mock_unsupportedListIterator();
- }
- };
-
- assertTrue(asl.iterator().getClass().toString().contains("Mock_unsupportedListIterator"));
-
- asl = new AbstractSequentialList() {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- return new Mock_ListIterator();
- }
- };
-
- assertTrue(asl.iterator().getClass().toString().contains("Mock_ListIterator"));
-
- asl = new AbstractSequentialList() {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- return null;
- }
- };
- assertNull(asl.iterator());
- }
-
- public void test_removeI() {
- AbstractSequentialList asl = new AbstractSequentialList() {
- String buff[] = {"0", "1", "2", "3", "4", "5"};
- int currPos = 0;
-
- @Override
- public int size() {
- return buff.length;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- currPos = index;
- return new ListIterator() {
- public void add(Object o) {
- }
-
- public boolean hasNext() {
- return true;
- }
-
- public boolean hasPrevious() {
- return false;
- }
-
- public Object next() {
- return buff[currPos];
- }
-
- public int nextIndex() {
- return 0;
- }
-
- public Object previous() {
- return null;
- }
-
- public int previousIndex() {
- return 0;
- }
-
- public void remove() {
- buff[currPos] = "removed element";
- }
-
- public void set(Object o) {
- }
- };
- }
- };
-
- try {
- asl.remove(asl.size() + 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- asl.remove(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- for(int i = 0; i < asl.size(); i++) {
- assertFalse(asl.get(i).toString().contains("removed element"));
- asl.remove(i);
- assertTrue(asl.get(i).toString().contains("removed element"));
- }
- }
-
- public void test_setILjava_lang_Object() {
- AbstractSequentialList asl = new AbstractSequentialList() {
- String buff[] = {"0", "1", "2", "3", "4", "5"};
- final String illegalStr = "Illegal element";
- int currPos = 0;
-
- @Override
- public int size() {
- return buff.length;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- currPos = index;
- return new ListIterator() {
- public void add(Object o) {
- }
-
- public boolean hasNext() {
- return true;
- }
-
- public boolean hasPrevious() {
- return false;
- }
-
- public Object next() {
- return buff[currPos];
- }
-
- public int nextIndex() {
- return 0;
- }
-
- public Object previous() {
- return null;
- }
-
- public int previousIndex() {
- return 0;
- }
-
- public void remove() {
- buff[currPos] = "removed element";
- }
-
- public void set(Object o) {
- if (o == null) throw new NullPointerException();
- if (o.equals(illegalStr)) throw new IllegalArgumentException();
- buff[currPos] = (String) o;
- }
- };
- }
- };
-
- try {
- asl.set(asl.size() + 1, "new element");
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- asl.set(-1, "new element");
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- for(int i = 0; i < asl.size(); i++) {
- assertFalse(asl.get(i).toString().contains("new element"));
- asl.set(i, "new element");
- assertTrue(asl.get(i).toString().contains("new element"));
- }
-
- try {
- asl.set(1, new Double(1));
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //
- }
-
- try {
- asl.set(1, "Illegal element");
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ee) {
- //expected
- }
-
- try {
- asl.set(1, null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- asl = new AbstractSequentialList() {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public ListIterator listIterator(int index) {
- return new Mock_unsupportedListIterator();
- }
- };
-
- try {
- asl.set(0, "New element");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/ArrayListTest.java b/luni/src/test/java/tests/api/java/util/ArrayListTest.java
deleted file mode 100644
index 50d9aa3..0000000
--- a/luni/src/test/java/tests/api/java/util/ArrayListTest.java
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.util;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.ConcurrentModificationException;
-import java.util.Vector;
-
-import tests.support.Support_ListTest;
-
-public class ArrayListTest extends junit.framework.TestCase {
-
- List alist;
-
- Object[] objArray;
-
- /**
- * java.util.ArrayList#ArrayList()
- */
- public void test_Constructor() {
- // Test for method java.util.ArrayList()
- new Support_ListTest("", alist).runTest();
-
- ArrayList subList = new ArrayList();
- for (int i = -50; i < 150; i++)
- subList.add(new Integer(i));
- new Support_ListTest("", subList.subList(50, 150)).runTest();
- }
-
- /**
- * java.util.ArrayList#ArrayList(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.ArrayList(int)
- ArrayList al = new ArrayList(5);
- assertEquals("Incorrect arrayList created", 0, al.size());
-
- try {
- new ArrayList(-10);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.ArrayList#ArrayList(java.util.Collection)
- */
- public void test_ConstructorLjava_util_Collection() {
- // Test for method java.util.ArrayList(java.util.Collection)
- ArrayList al = new ArrayList(Arrays.asList(objArray));
- assertTrue("arrayList created from collection has incorrect size", al
- .size() == objArray.length);
- for (int counter = 0; counter < objArray.length; counter++)
- assertTrue(
- "arrayList created from collection has incorrect elements",
- al.get(counter) == objArray[counter]);
- try {
- new ArrayList(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
-
- }
-
- /**
- * java.util.ArrayList#add(int, java.lang.Object)
- */
- public void test_addILjava_lang_Object() {
- // Test for method void java.util.ArrayList.add(int, java.lang.Object)
- Object o;
- alist.add(50, o = new Object());
- assertTrue("Failed to add Object", alist.get(50) == o);
- assertTrue("Failed to fix up list after insert",
- alist.get(51) == objArray[50]
- && (alist.get(52) == objArray[51]));
- Object oldItem = alist.get(25);
- alist.add(25, null);
- assertNull("Should have returned null", alist.get(25));
- assertTrue("Should have returned the old item from slot 25", alist
- .get(26) == oldItem);
-
- try {
- alist.add(-1, null);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- alist.add(alist.size() + 1, null);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.ArrayList#add(java.lang.Object)
- */
- public void test_addLjava_lang_Object() {
- // Test for method boolean java.util.ArrayList.add(java.lang.Object)
- Object o = new Object();
- alist.add(o);
- assertTrue("Failed to add Object", alist.get(alist.size() - 1) == o);
- alist.add(null);
- assertNull("Failed to add null", alist.get(alist.size() - 1));
- }
-
- /**
- * java.util.ArrayList#addAll(int, java.util.Collection)
- */
- public void test_addAllILjava_util_Collection() {
- // Test for method boolean java.util.ArrayList.addAll(int,
- // java.util.Collection)
- alist.addAll(50, alist);
- assertEquals("Returned incorrect size after adding to existing list",
- 200, alist.size());
- for (int i = 0; i < 50; i++)
- assertTrue("Manipulated elements < index",
- alist.get(i) == objArray[i]);
- for (int i = 0; i >= 50 && (i < 150); i++)
- assertTrue("Failed to ad elements properly",
- alist.get(i) == objArray[i - 50]);
- for (int i = 0; i >= 150 && (i < 200); i++)
- assertTrue("Failed to ad elements properly",
- alist.get(i) == objArray[i - 100]);
- ArrayList listWithNulls = new ArrayList();
- listWithNulls.add(null);
- listWithNulls.add(null);
- listWithNulls.add("yoink");
- listWithNulls.add("kazoo");
- listWithNulls.add(null);
- alist.addAll(100, listWithNulls);
- assertTrue("Incorrect size: " + alist.size(), alist.size() == 205);
- assertNull("Item at slot 100 should be null", alist.get(100));
- assertNull("Item at slot 101 should be null", alist.get(101));
- assertEquals("Item at slot 102 should be 'yoink'",
- "yoink", alist.get(102));
- assertEquals("Item at slot 103 should be 'kazoo'",
- "kazoo", alist.get(103));
- assertNull("Item at slot 104 should be null", alist.get(104));
- alist.addAll(205, listWithNulls);
- assertTrue("Incorrect size2: " + alist.size(), alist.size() == 210);
-
- try {
- alist.addAll(-1, listWithNulls);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- alist.addAll(alist.size() + 1, listWithNulls);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- alist.addAll(0, null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
-// BEGIN android-removed
-// The spec does not mandate that IndexOutOfBoundsException be thrown in
-// preference to NullPointerException when the caller desserves both.
-//
-// /**
-// * java.util.ArrayList#addAll(int, java.util.Collection)
-// */
-// public void test_addAllILjava_util_Collection_2() {
-// // Regression for HARMONY-467
-// ArrayList obj = new ArrayList();
-// try {
-// obj.addAll((int) -1, (Collection) null);
-// fail("IndexOutOfBoundsException expected");
-// } catch (IndexOutOfBoundsException e) {
-// }
-// }
-// END android-removed
-
- /**
- * java.util.ArrayList#addAll(java.util.Collection)
- */
- public void test_addAllLjava_util_Collection() {
- // Test for method boolean
- // java.util.ArrayList.addAll(java.util.Collection)
- List l = new ArrayList();
- l.addAll(alist);
- for (int i = 0; i < alist.size(); i++)
- assertTrue("Failed to add elements properly", l.get(i).equals(
- alist.get(i)));
- alist.addAll(alist);
- assertEquals("Returned incorrect size after adding to existing list",
- 200, alist.size());
- for (int i = 0; i < 100; i++) {
- assertTrue("Added to list in incorrect order", alist.get(i)
- .equals(l.get(i)));
- assertTrue("Failed to add to existing list", alist.get(i + 100)
- .equals(l.get(i)));
- }
- Set setWithNulls = new HashSet();
- setWithNulls.add(null);
- setWithNulls.add(null);
- setWithNulls.add("yoink");
- setWithNulls.add("kazoo");
- setWithNulls.add(null);
- alist.addAll(100, setWithNulls);
- Iterator i = setWithNulls.iterator();
- assertTrue("Item at slot 100 is wrong: " + alist.get(100), alist
- .get(100) == i.next());
- assertTrue("Item at slot 101 is wrong: " + alist.get(101), alist
- .get(101) == i.next());
- assertTrue("Item at slot 103 is wrong: " + alist.get(102), alist
- .get(102) == i.next());
-
-
- // Regression test for Harmony-3481
- ArrayList<Integer> originalList = new ArrayList<Integer>(12);
- for (int j = 0; j < 12; j++) {
- originalList.add(j);
- }
-
- originalList.remove(0);
- originalList.remove(0);
-
- ArrayList<Integer> additionalList = new ArrayList<Integer>(11);
- for (int j = 0; j < 11; j++) {
- additionalList.add(j);
- }
- assertTrue(originalList.addAll(additionalList));
- assertEquals(21, originalList.size());
-
- try {
- alist.addAll(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.ArrayList#clear()
- */
- public void test_clear() {
- // Test for method void java.util.ArrayList.clear()
- alist.clear();
- assertEquals("List did not clear", 0, alist.size());
- alist.add(null);
- alist.add(null);
- alist.add(null);
- alist.add("bam");
- alist.clear();
- assertEquals("List with nulls did not clear", 0, alist.size());
- /*
- * for (int i = 0; i < alist.size(); i++) assertNull("Failed to clear
- * list", alist.get(i));
- */
-
- }
-
- /**
- * java.util.ArrayList#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.ArrayList.clone()
- ArrayList x = (ArrayList) (((ArrayList) (alist)).clone());
- assertTrue("Cloned list was inequal to original", x.equals(alist));
- for (int i = 0; i < alist.size(); i++)
- assertTrue("Cloned list contains incorrect elements",
- alist.get(i) == x.get(i));
-
- alist.add(null);
- alist.add(25, null);
- x = (ArrayList) (((ArrayList) (alist)).clone());
- assertTrue("nulls test - Cloned list was inequal to original", x
- .equals(alist));
- for (int i = 0; i < alist.size(); i++)
- assertTrue("nulls test - Cloned list contains incorrect elements",
- alist.get(i) == x.get(i));
-
- }
-
- /**
- * java.util.ArrayList#contains(java.lang.Object)
- */
- public void test_containsLjava_lang_Object() {
- // Test for method boolean
- // java.util.ArrayList.contains(java.lang.Object)
- assertTrue("Returned false for valid element", alist
- .contains(objArray[99]));
- assertTrue("Returned false for equal element", alist
- .contains(new Integer(8)));
- assertTrue("Returned true for invalid element", !alist
- .contains(new Object()));
- assertTrue("Returned true for null but should have returned false",
- !alist.contains(null));
- alist.add(null);
- assertTrue("Returned false for null but should have returned true",
- alist.contains(null));
- }
-
- /**
- * java.util.ArrayList#ensureCapacity(int)
- */
- public void test_ensureCapacityI() {
- // Test for method void java.util.ArrayList.ensureCapacity(int)
- // TODO : There is no good way to test this as it only really impacts on
- // the private implementation.
-
- Object testObject = new Object();
- int capacity = 20;
- ArrayList al = new ArrayList(capacity);
- int i;
- for (i = 0; i < capacity / 2; i++) {
- al.add(i, new Object());
- }
- al.add(i, testObject);
- int location = al.indexOf(testObject);
- try {
- al.ensureCapacity(capacity);
- assertTrue("EnsureCapacity moved objects around in array1.",
- location == al.indexOf(testObject));
- al.remove(0);
- al.ensureCapacity(capacity);
- assertTrue("EnsureCapacity moved objects around in array2.",
- --location == al.indexOf(testObject));
- al.ensureCapacity(capacity + 2);
- assertTrue("EnsureCapacity did not change location.",
- location == al.indexOf(testObject));
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- }
-
- /**
- * java.util.ArrayList#get(int)
- */
- public void test_getI() {
- // Test for method java.lang.Object java.util.ArrayList.get(int)
- assertTrue("Returned incorrect element", alist.get(22) == objArray[22]);
- try {
- alist.get(8765);
- fail("Failed to throw expected exception for index > size");
- } catch (IndexOutOfBoundsException e) {
- }
- }
-
- /**
- * java.util.ArrayList#indexOf(java.lang.Object)
- */
- public void test_indexOfLjava_lang_Object() {
- // Test for method int java.util.ArrayList.indexOf(java.lang.Object)
- assertEquals("Returned incorrect index",
- 87, alist.indexOf(objArray[87]));
- assertEquals("Returned index for invalid Object", -1, alist
- .indexOf(new Object()));
- alist.add(25, null);
- alist.add(50, null);
- assertTrue("Wrong indexOf for null. Wanted 25 got: "
- + alist.indexOf(null), alist.indexOf(null) == 25);
- }
-
- /**
- * java.util.ArrayList#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.ArrayList.isEmpty()
- assertTrue("isEmpty returned false for new list", new ArrayList()
- .isEmpty());
- assertTrue("Returned true for existing list with elements", !alist
- .isEmpty());
- }
-
- /**
- * java.util.ArrayList#lastIndexOf(java.lang.Object)
- */
- public void test_lastIndexOfLjava_lang_Object() {
- // Test for method int java.util.ArrayList.lastIndexOf(java.lang.Object)
- alist.add(new Integer(99));
- assertEquals("Returned incorrect index",
- 100, alist.lastIndexOf(objArray[99]));
- assertEquals("Returned index for invalid Object", -1, alist
- .lastIndexOf(new Object()));
- alist.add(25, null);
- alist.add(50, null);
- assertTrue("Wrong lastIndexOf for null. Wanted 50 got: "
- + alist.lastIndexOf(null), alist.lastIndexOf(null) == 50);
- }
-
- /**
- * java.util.ArrayList#remove(int)
- */
- public void test_removeI() {
- // Test for method java.lang.Object java.util.ArrayList.remove(int)
- alist.remove(10);
- assertEquals("Failed to remove element",
- -1, alist.indexOf(objArray[10]));
- try {
- alist.remove(999);
- fail("Failed to throw exception when index out of range");
- } catch (IndexOutOfBoundsException e) {
- }
-
- ArrayList myList = (ArrayList) (((ArrayList) (alist)).clone());
- alist.add(25, null);
- alist.add(50, null);
- alist.remove(50);
- alist.remove(25);
- assertTrue("Removing nulls did not work", alist.equals(myList));
-
- List list = new ArrayList(Arrays.asList(new String[] { "a", "b", "c",
- "d", "e", "f", "g" }));
- assertTrue("Removed wrong element 1", list.remove(0) == "a");
- assertTrue("Removed wrong element 2", list.remove(4) == "f");
- String[] result = new String[5];
- list.toArray(result);
- assertTrue("Removed wrong element 3", Arrays.equals(result,
- new String[] { "b", "c", "d", "e", "g" }));
-
- List l = new ArrayList(0);
- l.add(new Object());
- l.add(new Object());
- l.remove(0);
- l.remove(0);
- try {
- l.remove(-1);
- fail("-1 should cause exception");
- } catch (IndexOutOfBoundsException e) {
- }
- try {
- l.remove(0);
- fail("0 should case exception");
- } catch (IndexOutOfBoundsException e) {
- }
- }
-
- /**
- * java.util.ArrayList#set(int, java.lang.Object)
- */
- public void test_setILjava_lang_Object() {
- // Test for method java.lang.Object java.util.ArrayList.set(int,
- // java.lang.Object)
- Object obj;
- alist.set(65, obj = new Object());
- assertTrue("Failed to set object", alist.get(65) == obj);
- alist.set(50, null);
- assertNull("Setting to null did not work", alist.get(50));
- assertTrue("Setting increased the list's size to: " + alist.size(),
- alist.size() == 100);
-
- try {
- alist.set(-1, null);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- alist.set(alist.size() + 1, null);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.ArrayList#size()
- */
- public void test_size() {
- // Test for method int java.util.ArrayList.size()
- assertEquals("Returned incorrect size for exiting list",
- 100, alist.size());
- assertEquals("Returned incorrect size for new list", 0, new ArrayList()
- .size());
- }
-
- /**
- * java.util.ArrayList#toArray()
- */
- public void test_toArray() {
- // Test for method java.lang.Object [] java.util.ArrayList.toArray()
- alist.set(25, null);
- alist.set(75, null);
- Object[] obj = alist.toArray();
- assertEquals("Returned array of incorrect size", objArray.length,
- obj.length);
-
- for (int i = 0; i < obj.length; i++) {
- if ((i == 25) || (i == 75))
- assertNull("Should be null at: " + i + " but instead got: "
- + obj[i], obj[i]);
- else
- assertTrue("Returned incorrect array: " + i,
- obj[i] == objArray[i]);
- }
-
- }
-
- /**
- * java.util.ArrayList#toArray(java.lang.Object[])
- */
- public void test_toArray$Ljava_lang_Object() {
- // Test for method java.lang.Object []
- // java.util.ArrayList.toArray(java.lang.Object [])
- alist.set(25, null);
- alist.set(75, null);
- Integer[] argArray = new Integer[100];
- Object[] retArray;
- retArray = alist.toArray(argArray);
- assertTrue("Returned different array than passed", retArray == argArray);
- argArray = new Integer[1000];
- retArray = alist.toArray(argArray);
- assertNull("Failed to set first extra element to null", argArray[alist
- .size()]);
- for (int i = 0; i < 100; i++) {
- if ((i == 25) || (i == 75))
- assertNull("Should be null: " + i, retArray[i]);
- else
- assertTrue("Returned incorrect array: " + i,
- retArray[i] == objArray[i]);
- }
-
- String[] strArray = new String[100];
- try {
- alist.toArray(strArray);
- fail("ArrayStoreException expected");
- } catch (ArrayStoreException e) {
- //expected
- }
- }
-
- /**
- * java.util.ArrayList#trimToSize()
- */
- public void test_trimToSize_01() {
- // Test for method void java.util.ArrayList.trimToSize()
- for (int i = 99; i > 24; i--)
- alist.remove(i);
- ((ArrayList) alist).trimToSize();
- assertEquals("Returned incorrect size after trim", 25, alist.size());
- for (int i = 0; i < alist.size(); i++)
- assertTrue("Trimmed list contained incorrect elements", alist
- .get(i) == objArray[i]);
- Vector v = new Vector();
- v.add("a");
- v.add("b");
- ArrayList al = new ArrayList(v);
- Iterator it = al.iterator();
- al.remove(0);
- al.trimToSize();
- try {
- it.next();
- fail("should throw a ConcurrentModificationException");
- } catch (ConcurrentModificationException ioobe) {
- // expected
- }
- }
-
- public void test_trimToSize_02() {
- ArrayList list = new ArrayList(Arrays.asList(new String[] { "a", "b", "c",
- "d", "e", "f", "g" }));
- list.remove("a");
- list.remove("f");
- list.trimToSize();
- }
-
- /**
- * @test java.util.ArrayList#addAll(int, Collection)
- */
- public void test_addAll() {
- ArrayList list = new ArrayList();
- list.add("one");
- list.add("two");
- assertEquals(2, list.size());
-
- list.remove(0);
- assertEquals(1, list.size());
-
- ArrayList collection = new ArrayList();
- collection.add("1");
- collection.add("2");
- collection.add("3");
- assertEquals(3, collection.size());
-
- list.addAll(0, collection);
- assertEquals(4, list.size());
-
- list.remove(0);
- list.remove(0);
- assertEquals(2, list.size());
-
- collection.add("4");
- collection.add("5");
- collection.add("6");
- collection.add("7");
- collection.add("8");
- collection.add("9");
- collection.add("10");
- collection.add("11");
- collection.add("12");
-
- assertEquals(12, collection.size());
-
- list.addAll(0, collection);
- assertEquals(14, list.size());
- }
-
- public void test_removeLjava_lang_Object() {
- List list = new ArrayList(Arrays.asList(new String[] { "a", "b", "c",
- "d", "e", "f", "g" }));
- assertTrue("Removed wrong element 1", list.remove("a"));
- assertTrue("Removed wrong element 2", list.remove("f"));
- String[] result = new String[5];
- list.toArray(result);
- assertTrue("Removed wrong element 3", Arrays.equals(result,
- new String[] { "b", "c", "d", "e", "g" }));
- }
-
- class Mock_ArrayList extends ArrayList {
- public Mock_ArrayList() {
- }
-
- public void removeRange(int begin, int end) {
- super.removeRange(begin, end);
- }
- }
-
- public void test_removeRangeII() {
- Mock_ArrayList mal = new Mock_ArrayList();
- mal.add("a");
- mal.add("b");
- mal.add("c");
- mal.add("d");
- mal.add("e");
- mal.add("f");
- mal.add("g");
- mal.add("h");
-
- mal.removeRange(2, 4);
-
- String[] result = new String[6];
- mal.toArray(result);
- assertTrue("Removed wrong element 3", Arrays.equals(result,
- new String[] { "a", "b", "e", "f", "g", "h"}));
- }
-
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() throws Exception {
- super.setUp();
-
- objArray = new Object[100];
- for (int i = 0; i < objArray.length; i++) {
- objArray[i] = new Integer(i);
- }
-
- alist = new ArrayList();
- for (int i = 0; i < objArray.length; i++) {
- alist.add(objArray[i]);
- }
- }
-
- @Override
- protected void tearDown() throws Exception {
- objArray = null;
- alist = null;
-
- super.tearDown();
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/ArraysTest.java b/luni/src/test/java/tests/api/java/util/ArraysTest.java
deleted file mode 100644
index 2ca8e70..0000000
--- a/luni/src/test/java/tests/api/java/util/ArraysTest.java
+++ /dev/null
@@ -1,2403 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.util;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Random;
-
-import tests.support.Support_UnmodifiableCollectionTest;
-
-public class ArraysTest extends junit.framework.TestCase {
-
- public static class ReversedIntegerComparator implements Comparator {
- public int compare(Object o1, Object o2) {
- return -(((Integer) o1).compareTo((Integer) o2));
- }
-
- public boolean equals(Object o1, Object o2) {
- return ((Integer) o1).compareTo((Integer) o2) == 0;
- }
- }
-
- final static int arraySize = 100;
-
- Object[] objArray;
-
- boolean[] booleanArray;
-
- byte[] byteArray;
-
- char[] charArray;
-
- double[] doubleArray;
-
- float[] floatArray;
-
- int[] intArray;
-
- long[] longArray;
-
- Object[] objectArray;
-
- short[] shortArray;
-
- /**
- * java.util.Arrays#asList(java.lang.Object[])
- */
- public void test_asList$Ljava_lang_Object() {
- // Test for method java.util.List
- // java.util.Arrays.asList(java.lang.Object [])
- List convertedList = Arrays.asList(objectArray);
- for (int counter = 0; counter < arraySize; counter++) {
- assertTrue(
- "Array and List converted from array do not contain identical elements",
- convertedList.get(counter) == objectArray[counter]);
- }
- convertedList.set(50, new Integer(1000));
- assertTrue("set/get did not work on coverted list", convertedList.get(
- 50).equals(new Integer(1000)));
- convertedList.set(50, new Integer(50));
- new Support_UnmodifiableCollectionTest("", convertedList).runTest();
-
- Object[] myArray = (Object[]) (objectArray.clone());
- myArray[30] = null;
- myArray[60] = null;
- convertedList = Arrays.asList(myArray);
- for (int counter = 0; counter < arraySize; counter++) {
- assertTrue(
- "Array and List converted from array do not contain identical elements",
- convertedList.get(counter) == myArray[counter]);
- }
-
- try {
- Arrays.asList((Object[])null);
- fail("asList with null arg didn't throw NPE");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Arrays#binarySearch(byte[], byte)
- */
- public void test_binarySearch$BB() {
- // Test for method int java.util.Arrays.binarySearch(byte [], byte)
- for (byte counter = 0; counter < arraySize; counter++)
- assertTrue("Binary search on byte[] answered incorrect position",
- Arrays.binarySearch(byteArray, counter) == counter);
- assertEquals("Binary search succeeded for value not present in array 1",
- -1, Arrays.binarySearch(intArray, (byte) -1));
- assertTrue(
- "Binary search succeeded for value not present in array 2",
- Arrays.binarySearch(intArray, (byte) arraySize) == -(arraySize + 1));
- for (byte counter = 0; counter < arraySize; counter++)
- byteArray[counter] -= 50;
- for (byte counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on byte[] involving negative numbers answered incorrect position",
- Arrays.binarySearch(byteArray, (byte) (counter - 50)) == counter);
- }
-
- /**
- * java.util.Arrays#binarySearch(char[], char)
- */
- public void test_binarySearch$CC() {
- // Test for method int java.util.Arrays.binarySearch(char [], char)
- for (char counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on char[] answered incorrect position",
- Arrays.binarySearch(charArray, (char) (counter + 1)) == counter);
- assertEquals("Binary search succeeded for value not present in array 1",
- -1, Arrays.binarySearch(charArray, '\u0000'));
- assertTrue(
- "Binary search succeeded for value not present in array 2",
- Arrays.binarySearch(charArray, (char) (arraySize + 1)) == -(arraySize + 1));
- }
-
- /**
- * java.util.Arrays#binarySearch(double[], double)
- */
- public void test_binarySearch$DD() {
- // Test for method int java.util.Arrays.binarySearch(double [], double)
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on double[] answered incorrect position",
- Arrays.binarySearch(doubleArray, (double) counter) == (double) counter);
- assertEquals("Binary search succeeded for value not present in array 1",
- -1, Arrays.binarySearch(doubleArray, (double) -1));
- assertTrue(
- "Binary search succeeded for value not present in array 2",
- Arrays.binarySearch(doubleArray, (double) arraySize) == -(arraySize + 1));
- for (int counter = 0; counter < arraySize; counter++)
- doubleArray[counter] -= (double) 50;
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on double[] involving negative numbers answered incorrect position",
- Arrays.binarySearch(doubleArray, (double) (counter - 50)) == (double) counter);
-
- double[] specials = new double[] { Double.NEGATIVE_INFINITY,
- -Double.MAX_VALUE, -2d, -Double.MIN_VALUE, -0d, 0d,
- Double.MIN_VALUE, 2d, Double.MAX_VALUE,
- Double.POSITIVE_INFINITY, Double.NaN };
- for (int i = 0; i < specials.length; i++) {
- int result = Arrays.binarySearch(specials, specials[i]);
- assertTrue(specials[i] + " invalid: " + result, result == i);
- }
- assertEquals("-1d", -4, Arrays.binarySearch(specials, -1d));
- assertEquals("1d", -8, Arrays.binarySearch(specials, 1d));
-
- }
-
- /**
- * java.util.Arrays#binarySearch(float[], float)
- */
- public void test_binarySearch$FF() {
- // Test for method int java.util.Arrays.binarySearch(float [], float)
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on float[] answered incorrect position",
- Arrays.binarySearch(floatArray, (float) counter) == (float) counter);
- assertEquals("Binary search succeeded for value not present in array 1",
- -1, Arrays.binarySearch(floatArray, (float) -1));
- assertTrue(
- "Binary search succeeded for value not present in array 2",
- Arrays.binarySearch(floatArray, (float) arraySize) == -(arraySize + 1));
- for (int counter = 0; counter < arraySize; counter++)
- floatArray[counter] -= (float) 50;
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on float[] involving negative numbers answered incorrect position",
- Arrays.binarySearch(floatArray, (float) counter - 50) == (float) counter);
-
- float[] specials = new float[] { Float.NEGATIVE_INFINITY,
- -Float.MAX_VALUE, -2f, -Float.MIN_VALUE, -0f, 0f,
- Float.MIN_VALUE, 2f, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
- Float.NaN };
- for (int i = 0; i < specials.length; i++) {
- int result = Arrays.binarySearch(specials, specials[i]);
- assertTrue(specials[i] + " invalid: " + result, result == i);
- }
- assertEquals("-1f", -4, Arrays.binarySearch(specials, -1f));
- assertEquals("1f", -8, Arrays.binarySearch(specials, 1f));
- }
-
- /**
- * java.util.Arrays#binarySearch(int[], int)
- */
- public void test_binarySearch$II() {
- // Test for method int java.util.Arrays.binarySearch(int [], int)
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Binary search on int[] answered incorrect position",
- Arrays.binarySearch(intArray, counter) == counter);
- assertEquals("Binary search succeeded for value not present in array 1",
- -1, Arrays.binarySearch(intArray, -1));
- assertTrue("Binary search succeeded for value not present in array 2",
- Arrays.binarySearch(intArray, arraySize) == -(arraySize + 1));
- for (int counter = 0; counter < arraySize; counter++)
- intArray[counter] -= 50;
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on int[] involving negative numbers answered incorrect position",
- Arrays.binarySearch(intArray, counter - 50) == counter);
- }
-
- /**
- * java.util.Arrays#binarySearch(long[], long)
- */
- public void test_binarySearch$JJ() {
- // Test for method int java.util.Arrays.binarySearch(long [], long)
- for (long counter = 0; counter < arraySize; counter++)
- assertTrue("Binary search on long[] answered incorrect position",
- Arrays.binarySearch(longArray, counter) == counter);
- assertEquals("Binary search succeeded for value not present in array 1",
- -1, Arrays.binarySearch(longArray, (long) -1));
- assertTrue(
- "Binary search succeeded for value not present in array 2",
- Arrays.binarySearch(longArray, (long) arraySize) == -(arraySize + 1));
- for (long counter = 0; counter < arraySize; counter++)
- longArray[(int) counter] -= (long) 50;
- for (long counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on long[] involving negative numbers answered incorrect position",
- Arrays.binarySearch(longArray, counter - (long) 50) == counter);
- }
-
- /**
- * java.util.Arrays#binarySearch(java.lang.Object[],
- * java.lang.Object)
- */
- public void test_binarySearch$Ljava_lang_ObjectLjava_lang_Object() {
- // Test for method int java.util.Arrays.binarySearch(java.lang.Object
- // [], java.lang.Object)
- assertEquals(
- "Binary search succeeded for non-comparable value in empty array",
- -1, Arrays.binarySearch(new Object[] {}, new Object()));
- assertEquals(
- "Binary search succeeded for comparable value in empty array",
- -1, Arrays.binarySearch(new Object[] {}, new Integer(-1)));
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on Object[] answered incorrect position",
- Arrays.binarySearch(objectArray, objArray[counter]) == counter);
- assertEquals("Binary search succeeded for value not present in array 1",
- -1, Arrays.binarySearch(objectArray, new Integer(-1)));
- assertTrue(
- "Binary search succeeded for value not present in array 2",
- Arrays.binarySearch(objectArray, new Integer(arraySize)) == -(arraySize + 1));
-
- String[] sArray = new String[]{"1", "2", "3", "4", ""};
- Object[] oArray = sArray;
-
- try {
- Arrays.binarySearch(oArray, new Integer(10));
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#binarySearch(java.lang.Object[],
- * java.lang.Object, java.util.Comparator)
- */
- public void test_binarySearch$Ljava_lang_ObjectLjava_lang_ObjectLjava_util_Comparator() {
- // Test for method int java.util.Arrays.binarySearch(java.lang.Object
- // [], java.lang.Object, java.util.Comparator)
- Comparator comp = new ReversedIntegerComparator();
- for (int counter = 0; counter < arraySize; counter++)
- objectArray[counter] = objArray[arraySize - counter - 1];
- assertTrue(
- "Binary search succeeded for value not present in array 1",
- Arrays.binarySearch(objectArray, new Integer(-1), comp) == -(arraySize + 1));
- assertEquals("Binary search succeeded for value not present in array 2",
- -1, Arrays.binarySearch(objectArray, new Integer(arraySize), comp));
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on Object[] with custom comparator answered incorrect position",
- Arrays.binarySearch(objectArray, objArray[counter], comp) == arraySize
- - counter - 1);
- }
-
- /**
- * java.util.Arrays#binarySearch(short[], short)
- */
- public void test_binarySearch$SS() {
- // Test for method int java.util.Arrays.binarySearch(short [], short)
- for (short counter = 0; counter < arraySize; counter++)
- assertTrue("Binary search on short[] answered incorrect position",
- Arrays.binarySearch(shortArray, counter) == counter);
- assertEquals("Binary search succeeded for value not present in array 1",
- -1, Arrays.binarySearch(intArray, (short) -1));
- assertTrue(
- "Binary search succeeded for value not present in array 2",
- Arrays.binarySearch(intArray, (short) arraySize) == -(arraySize + 1));
- for (short counter = 0; counter < arraySize; counter++)
- shortArray[counter] -= 50;
- for (short counter = 0; counter < arraySize; counter++)
- assertTrue(
- "Binary search on short[] involving negative numbers answered incorrect position",
- Arrays.binarySearch(shortArray, (short) (counter - 50)) == counter);
- }
-
- /**
- * java.util.Arrays#fill(byte[], byte)
- */
- public void test_fill$BB() {
- // Test for method void java.util.Arrays.fill(byte [], byte)
-
- byte d[] = new byte[1000];
- Arrays.fill(d, Byte.MAX_VALUE);
- for (int i = 0; i < d.length; i++)
- assertTrue("Failed to fill byte array correctly",
- d[i] == Byte.MAX_VALUE);
- }
-
- /**
- * java.util.Arrays#fill(byte[], int, int, byte)
- */
- public void test_fill$BIIB() {
- // Test for method void java.util.Arrays.fill(byte [], int, int, byte)
- byte val = Byte.MAX_VALUE;
- byte d[] = new byte[1000];
- Arrays.fill(d, 400, d.length, val);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == val));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill byte array correctly", d[i] == val);
-
- int result;
- try {
- Arrays.fill(new byte[2], 2, 1, (byte) 27);
- result = 0;
- } catch (ArrayIndexOutOfBoundsException e) {
- result = 1;
- } catch (IllegalArgumentException e) {
- result = 2;
- }
- assertEquals("Wrong exception1", 2, result);
- try {
- Arrays.fill(new byte[2], -1, 1, (byte) 27);
- result = 0;
- } catch (ArrayIndexOutOfBoundsException e) {
- result = 1;
- } catch (IllegalArgumentException e) {
- result = 2;
- }
- assertEquals("Wrong exception2", 1, result);
- try {
- Arrays.fill(new byte[2], 1, 4, (byte) 27);
- result = 0;
- } catch (ArrayIndexOutOfBoundsException e) {
- result = 1;
- } catch (IllegalArgumentException e) {
- result = 2;
- }
- assertEquals("Wrong exception", 1, result);
- }
-
- /**
- * java.util.Arrays#fill(short[], short)
- */
- public void test_fill$SS() {
- // Test for method void java.util.Arrays.fill(short [], short)
-
- short d[] = new short[1000];
- Arrays.fill(d, Short.MAX_VALUE);
- for (int i = 0; i < d.length; i++)
- assertTrue("Failed to fill short array correctly",
- d[i] == Short.MAX_VALUE);
- }
-
- /**
- * java.util.Arrays#fill(short[], int, int, short)
- */
- public void test_fill$SIIS() {
- // Test for method void java.util.Arrays.fill(short [], int, int, short)
- short val = Short.MAX_VALUE;
- short d[] = new short[1000];
- Arrays.fill(d, 400, d.length, val);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == val));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill short array correctly", d[i] == val);
-
- try {
- Arrays.fill(d, 10, 0, val);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, -10, 0, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, 10, d.length+1, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#fill(char[], char)
- */
- public void test_fill$CC() {
- // Test for method void java.util.Arrays.fill(char [], char)
-
- char d[] = new char[1000];
- Arrays.fill(d, 'V');
- for (int i = 0; i < d.length; i++)
- assertEquals("Failed to fill char array correctly", 'V', d[i]);
- }
-
- /**
- * java.util.Arrays#fill(char[], int, int, char)
- */
- public void test_fill$CIIC() {
- // Test for method void java.util.Arrays.fill(char [], int, int, char)
- char val = 'T';
- char d[] = new char[1000];
- Arrays.fill(d, 400, d.length, val);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == val));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill char array correctly", d[i] == val);
-
- try {
- Arrays.fill(d, 10, 0, val);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, -10, 0, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, 10, d.length+1, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#fill(int[], int)
- */
- public void test_fill$II() {
- // Test for method void java.util.Arrays.fill(int [], int)
-
- int d[] = new int[1000];
- Arrays.fill(d, Integer.MAX_VALUE);
- for (int i = 0; i < d.length; i++)
- assertTrue("Failed to fill int array correctly",
- d[i] == Integer.MAX_VALUE);
- }
-
- /**
- * java.util.Arrays#fill(int[], int, int, int)
- */
- public void test_fill$IIII() {
- // Test for method void java.util.Arrays.fill(int [], int, int, int)
- int val = Integer.MAX_VALUE;
- int d[] = new int[1000];
- Arrays.fill(d, 400, d.length, val);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == val));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill int array correctly", d[i] == val);
-
- try {
- Arrays.fill(d, 10, 0, val);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, -10, 0, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, 10, d.length+1, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#fill(long[], long)
- */
- public void test_fill$JJ() {
- // Test for method void java.util.Arrays.fill(long [], long)
-
- long d[] = new long[1000];
- Arrays.fill(d, Long.MAX_VALUE);
- for (int i = 0; i < d.length; i++)
- assertTrue("Failed to fill long array correctly",
- d[i] == Long.MAX_VALUE);
- }
-
- /**
- * java.util.Arrays#fill(long[], int, int, long)
- */
- public void test_fill$JIIJ() {
- // Test for method void java.util.Arrays.fill(long [], int, int, long)
- long d[] = new long[1000];
- Arrays.fill(d, 400, d.length, Long.MAX_VALUE);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == Long.MAX_VALUE));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill long array correctly",
- d[i] == Long.MAX_VALUE);
-
- try {
- Arrays.fill(d, 10, 0, Long.MIN_VALUE);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, -10, 0, Long.MAX_VALUE);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, 10, d.length+1, Long.MAX_VALUE);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#fill(float[], float)
- */
- public void test_fill$FF() {
- // Test for method void java.util.Arrays.fill(float [], float)
- float d[] = new float[1000];
- Arrays.fill(d, Float.MAX_VALUE);
- for (int i = 0; i < d.length; i++)
- assertTrue("Failed to fill float array correctly",
- d[i] == Float.MAX_VALUE);
- }
-
- /**
- * java.util.Arrays#fill(float[], int, int, float)
- */
- public void test_fill$FIIF() {
- // Test for method void java.util.Arrays.fill(float [], int, int, float)
- float val = Float.MAX_VALUE;
- float d[] = new float[1000];
- Arrays.fill(d, 400, d.length, val);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == val));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill float array correctly", d[i] == val);
-
- try {
- Arrays.fill(d, 10, 0, val);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, -10, 0, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, 10, d.length+1, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#fill(double[], double)
- */
- public void test_fill$DD() {
- // Test for method void java.util.Arrays.fill(double [], double)
-
- double d[] = new double[1000];
- Arrays.fill(d, Double.MAX_VALUE);
- for (int i = 0; i < d.length; i++)
- assertTrue("Failed to fill double array correctly",
- d[i] == Double.MAX_VALUE);
- }
-
- /**
- * java.util.Arrays#fill(double[], int, int, double)
- */
- public void test_fill$DIID() {
- // Test for method void java.util.Arrays.fill(double [], int, int,
- // double)
- double val = Double.MAX_VALUE;
- double d[] = new double[1000];
- Arrays.fill(d, 400, d.length, val);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == val));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill double array correctly", d[i] == val);
-
- try {
- Arrays.fill(d, 10, 0, val);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, -10, 0, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, 10, d.length+1, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#fill(boolean[], boolean)
- */
- public void test_fill$ZZ() {
- // Test for method void java.util.Arrays.fill(boolean [], boolean)
-
- boolean d[] = new boolean[1000];
- Arrays.fill(d, true);
- for (int i = 0; i < d.length; i++)
- assertTrue("Failed to fill boolean array correctly", d[i]);
- }
-
- /**
- * java.util.Arrays#fill(boolean[], int, int, boolean)
- */
- public void test_fill$ZIIZ() {
- // Test for method void java.util.Arrays.fill(boolean [], int, int,
- // boolean)
- boolean val = true;
- boolean d[] = new boolean[1000];
- Arrays.fill(d, 400, d.length, val);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == val));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill boolean array correctly", d[i] == val);
-
- try {
- Arrays.fill(d, 10, 0, val);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, -10, 0, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, 10, d.length+1, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#fill(java.lang.Object[], java.lang.Object)
- */
- public void test_fill$Ljava_lang_ObjectLjava_lang_Object() {
- // Test for method void java.util.Arrays.fill(java.lang.Object [],
- // java.lang.Object)
- Object val = new Object();
- Object d[] = new Object[1000];
- Arrays.fill(d, 0, d.length, val);
- for (int i = 0; i < d.length; i++)
- assertTrue("Failed to fill Object array correctly", d[i] == val);
- }
-
- /**
- * java.util.Arrays#fill(java.lang.Object[], int, int,
- * java.lang.Object)
- */
- public void test_fill$Ljava_lang_ObjectIILjava_lang_Object() {
- // Test for method void java.util.Arrays.fill(java.lang.Object [], int,
- // int, java.lang.Object)
- Object val = new Object();
- Object d[] = new Object[1000];
- Arrays.fill(d, 400, d.length, val);
- for (int i = 0; i < 400; i++)
- assertTrue("Filled elements not in range", !(d[i] == val));
- for (int i = 400; i < d.length; i++)
- assertTrue("Failed to fill Object array correctly", d[i] == val);
-
- Arrays.fill(d, 400, d.length, null);
- for (int i = 400; i < d.length; i++)
- assertNull("Failed to fill Object array correctly with nulls",
- d[i]);
-
- try {
- Arrays.fill(d, 10, 0, val);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, -10, 0, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.fill(d, 10, d.length+1, val);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#equals(byte[], byte[])
- */
- public void test_equals$B$B() {
- // Test for method boolean java.util.Arrays.equals(byte [], byte [])
- byte d[] = new byte[1000];
- byte x[] = new byte[1000];
- Arrays.fill(d, Byte.MAX_VALUE);
- Arrays.fill(x, Byte.MIN_VALUE);
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, Byte.MAX_VALUE);
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
- }
-
- /**
- * java.util.Arrays#equals(short[], short[])
- */
- public void test_equals$S$S() {
- // Test for method boolean java.util.Arrays.equals(short [], short [])
- short d[] = new short[1000];
- short x[] = new short[1000];
- Arrays.fill(d, Short.MAX_VALUE);
- Arrays.fill(x, Short.MIN_VALUE);
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, Short.MAX_VALUE);
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
- }
-
- /**
- * java.util.Arrays#equals(char[], char[])
- */
- public void test_equals$C$C() {
- // Test for method boolean java.util.Arrays.equals(char [], char [])
- char d[] = new char[1000];
- char x[] = new char[1000];
- char c = 'T';
- Arrays.fill(d, c);
- Arrays.fill(x, 'L');
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, c);
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
- }
-
- /**
- * java.util.Arrays#equals(int[], int[])
- */
- public void test_equals$I$I() {
- // Test for method boolean java.util.Arrays.equals(int [], int [])
- int d[] = new int[1000];
- int x[] = new int[1000];
- Arrays.fill(d, Integer.MAX_VALUE);
- Arrays.fill(x, Integer.MIN_VALUE);
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, Integer.MAX_VALUE);
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
-
- assertTrue("wrong result for null array1", !Arrays.equals(new int[2],
- null));
- assertTrue("wrong result for null array2", !Arrays.equals(null,
- new int[2]));
- }
-
- /**
- * java.util.Arrays#equals(long[], long[])
- */
- public void test_equals$J$J() {
- // Test for method boolean java.util.Arrays.equals(long [], long [])
- long d[] = new long[1000];
- long x[] = new long[1000];
- Arrays.fill(d, Long.MAX_VALUE);
- Arrays.fill(x, Long.MIN_VALUE);
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, Long.MAX_VALUE);
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
-
- assertTrue("should be false", !Arrays.equals(
- new long[] { 0x100000000L }, new long[] { 0x200000000L }));
-
- }
-
- /**
- * java.util.Arrays#equals(float[], float[])
- */
- public void test_equals$F$F() {
- // Test for method boolean java.util.Arrays.equals(float [], float [])
- float d[] = new float[1000];
- float x[] = new float[1000];
- Arrays.fill(d, Float.MAX_VALUE);
- Arrays.fill(x, Float.MIN_VALUE);
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, Float.MAX_VALUE);
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
-
- assertTrue("NaN not equals", Arrays.equals(new float[] { Float.NaN },
- new float[] { Float.NaN }));
- assertTrue("0f equals -0f", !Arrays.equals(new float[] { 0f },
- new float[] { -0f }));
- }
-
- /**
- * java.util.Arrays#equals(double[], double[])
- */
- public void test_equals$D$D() {
- // Test for method boolean java.util.Arrays.equals(double [], double [])
- double d[] = new double[1000];
- double x[] = new double[1000];
- Arrays.fill(d, Double.MAX_VALUE);
- Arrays.fill(x, Double.MIN_VALUE);
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, Double.MAX_VALUE);
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
-
- assertTrue("should be false", !Arrays.equals(new double[] { 1.0 },
- new double[] { 2.0 }));
-
- assertTrue("NaN not equals", Arrays.equals(new double[] { Double.NaN },
- new double[] { Double.NaN }));
- assertTrue("0d equals -0d", !Arrays.equals(new double[] { 0d },
- new double[] { -0d }));
- }
-
- /**
- * java.util.Arrays#equals(boolean[], boolean[])
- */
- public void test_equals$Z$Z() {
- // Test for method boolean java.util.Arrays.equals(boolean [], boolean
- // [])
- boolean d[] = new boolean[1000];
- boolean x[] = new boolean[1000];
- Arrays.fill(d, true);
- Arrays.fill(x, false);
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, true);
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
- }
-
- /**
- * java.util.Arrays#equals(java.lang.Object[], java.lang.Object[])
- */
- public void test_equals$Ljava_lang_Object$Ljava_lang_Object() {
- // Test for method boolean java.util.Arrays.equals(java.lang.Object [],
- // java.lang.Object [])
- Object d[] = new Object[1000];
- Object x[] = new Object[1000];
- Object o = new Object();
- Arrays.fill(d, o);
- Arrays.fill(x, new Object());
- assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
- Arrays.fill(x, o);
- d[50] = null;
- x[50] = null;
- assertTrue("equal arrays returned false", Arrays.equals(d, x));
- }
-
- /**
- * java.util.Arrays#sort(byte[])
- */
- public void test_sort$B() {
- // Test for method void java.util.Arrays.sort(byte [])
- byte[] reversedArray = new byte[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- reversedArray[counter] = (byte) (arraySize - counter - 1);
- Arrays.sort(reversedArray);
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Resulting array not sorted",
- reversedArray[counter] == (byte) counter);
- }
-
- /**
- * java.util.Arrays#sort(byte[], int, int)
- */
- public void test_sort$BII() {
- // Test for method void java.util.Arrays.sort(byte [], int, int)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- byte[] reversedArray = new byte[arraySize];
- byte[] originalReversedArray = new byte[arraySize];
- for (int counter = 0; counter < arraySize; counter++) {
- reversedArray[counter] = (byte) (arraySize - counter - 1);
- originalReversedArray[counter] = reversedArray[counter];
- }
- Arrays.sort(reversedArray, startIndex, endIndex);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds",
- reversedArray[counter] <= reversedArray[counter + 1]);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
-
- //exception testing
- try {
- Arrays.sort(reversedArray, startIndex + 1, startIndex);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, -1, startIndex);
- fail("ArrayIndexOutOfBoundsException expected (1)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
- fail("ArrayIndexOutOfBoundsException expected (2)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
- }
-
- /**
- * java.util.Arrays#sort(char[])
- */
- public void test_sort$C() {
- // Test for method void java.util.Arrays.sort(char [])
- char[] reversedArray = new char[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- reversedArray[counter] = (char) (arraySize - counter - 1);
- Arrays.sort(reversedArray);
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Resulting array not sorted",
- reversedArray[counter] == (char) counter);
-
- }
-
- /**
- * java.util.Arrays#sort(char[], int, int)
- */
- public void test_sort$CII() {
- // Test for method void java.util.Arrays.sort(char [], int, int)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- char[] reversedArray = new char[arraySize];
- char[] originalReversedArray = new char[arraySize];
- for (int counter = 0; counter < arraySize; counter++) {
- reversedArray[counter] = (char) (arraySize - counter - 1);
- originalReversedArray[counter] = reversedArray[counter];
- }
- Arrays.sort(reversedArray, startIndex, endIndex);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds",
- reversedArray[counter] <= reversedArray[counter + 1]);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
-
- //exception testing
- try {
- Arrays.sort(reversedArray, startIndex + 1, startIndex);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, -1, startIndex);
- fail("ArrayIndexOutOfBoundsException expected (1)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
- fail("ArrayIndexOutOfBoundsException expected (2)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
- }
-
- /**
- * java.util.Arrays#sort(double[])
- */
- public void test_sort$D() {
- // Test for method void java.util.Arrays.sort(double [])
- double[] reversedArray = new double[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- reversedArray[counter] = (double) (arraySize - counter - 1);
- Arrays.sort(reversedArray);
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Resulting array not sorted",
- reversedArray[counter] == (double) counter);
-
- double[] specials1 = new double[] { Double.NaN, Double.MAX_VALUE,
- Double.MIN_VALUE, 0d, -0d, Double.POSITIVE_INFINITY,
- Double.NEGATIVE_INFINITY };
- double[] specials2 = new double[] { 0d, Double.POSITIVE_INFINITY, -0d,
- Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Double.NaN,
- Double.MAX_VALUE };
- double[] answer = new double[] { Double.NEGATIVE_INFINITY, -0d, 0d,
- Double.MIN_VALUE, Double.MAX_VALUE, Double.POSITIVE_INFINITY,
- Double.NaN };
-
- Arrays.sort(specials1);
- Object[] print1 = new Object[specials1.length];
- for (int i = 0; i < specials1.length; i++)
- print1[i] = new Double(specials1[i]);
- assertTrue("specials sort incorrectly 1: " + Arrays.asList(print1),
- Arrays.equals(specials1, answer));
-
- Arrays.sort(specials2);
- Object[] print2 = new Object[specials2.length];
- for (int i = 0; i < specials2.length; i++)
- print2[i] = new Double(specials2[i]);
- assertTrue("specials sort incorrectly 2: " + Arrays.asList(print2),
- Arrays.equals(specials2, answer));
- }
-
- /**
- * java.util.Arrays#sort(double[], int, int)
- */
- public void test_sort$DII() {
- // Test for method void java.util.Arrays.sort(double [], int, int)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- double[] reversedArray = new double[arraySize];
- double[] originalReversedArray = new double[arraySize];
- for (int counter = 0; counter < arraySize; counter++) {
- reversedArray[counter] = (double) (arraySize - counter - 1);
- originalReversedArray[counter] = reversedArray[counter];
- }
- Arrays.sort(reversedArray, startIndex, endIndex);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds",
- reversedArray[counter] <= reversedArray[counter + 1]);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
-
- //exception testing
- try {
- Arrays.sort(reversedArray, startIndex + 1, startIndex);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, -1, startIndex);
- fail("ArrayIndexOutOfBoundsException expected (1)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
- fail("ArrayIndexOutOfBoundsException expected (2)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
- }
-
- /**
- * java.util.Arrays#sort(float[])
- */
- public void test_sort$F() {
- // Test for method void java.util.Arrays.sort(float [])
- float[] reversedArray = new float[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- reversedArray[counter] = (float) (arraySize - counter - 1);
- Arrays.sort(reversedArray);
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Resulting array not sorted",
- reversedArray[counter] == (float) counter);
-
- float[] specials1 = new float[] { Float.NaN, Float.MAX_VALUE,
- Float.MIN_VALUE, 0f, -0f, Float.POSITIVE_INFINITY,
- Float.NEGATIVE_INFINITY };
- float[] specials2 = new float[] { 0f, Float.POSITIVE_INFINITY, -0f,
- Float.NEGATIVE_INFINITY, Float.MIN_VALUE, Float.NaN,
- Float.MAX_VALUE };
- float[] answer = new float[] { Float.NEGATIVE_INFINITY, -0f, 0f,
- Float.MIN_VALUE, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
- Float.NaN };
-
- Arrays.sort(specials1);
- Object[] print1 = new Object[specials1.length];
- for (int i = 0; i < specials1.length; i++)
- print1[i] = new Float(specials1[i]);
- assertTrue("specials sort incorrectly 1: " + Arrays.asList(print1),
- Arrays.equals(specials1, answer));
-
- Arrays.sort(specials2);
- Object[] print2 = new Object[specials2.length];
- for (int i = 0; i < specials2.length; i++)
- print2[i] = new Float(specials2[i]);
- assertTrue("specials sort incorrectly 2: " + Arrays.asList(print2),
- Arrays.equals(specials2, answer));
- }
-
- /**
- * java.util.Arrays#sort(float[], int, int)
- */
- public void test_sort$FII() {
- // Test for method void java.util.Arrays.sort(float [], int, int)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- float[] reversedArray = new float[arraySize];
- float[] originalReversedArray = new float[arraySize];
- for (int counter = 0; counter < arraySize; counter++) {
- reversedArray[counter] = (float) (arraySize - counter - 1);
- originalReversedArray[counter] = reversedArray[counter];
- }
- Arrays.sort(reversedArray, startIndex, endIndex);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds",
- reversedArray[counter] <= reversedArray[counter + 1]);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
-
- //exception testing
- try {
- Arrays.sort(reversedArray, startIndex + 1, startIndex);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, -1, startIndex);
- fail("ArrayIndexOutOfBoundsException expected (1)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
- fail("ArrayIndexOutOfBoundsException expected (2)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
- }
-
- /**
- * java.util.Arrays#sort(int[])
- */
- public void test_sort$I() {
- // Test for method void java.util.Arrays.sort(int [])
- int[] reversedArray = new int[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- reversedArray[counter] = arraySize - counter - 1;
- Arrays.sort(reversedArray);
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Resulting array not sorted",
- reversedArray[counter] == counter);
- }
-
- /**
- * java.util.Arrays#sort(int[], int, int)
- */
- public void test_sort$III() {
- // Test for method void java.util.Arrays.sort(int [], int, int)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- int[] reversedArray = new int[arraySize];
- int[] originalReversedArray = new int[arraySize];
- for (int counter = 0; counter < arraySize; counter++) {
- reversedArray[counter] = arraySize - counter - 1;
- originalReversedArray[counter] = reversedArray[counter];
- }
- Arrays.sort(reversedArray, startIndex, endIndex);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds",
- reversedArray[counter] <= reversedArray[counter + 1]);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
-
- //exception testing
- try {
- Arrays.sort(reversedArray, startIndex + 1, startIndex);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, -1, startIndex);
- fail("ArrayIndexOutOfBoundsException expected (1)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
- fail("ArrayIndexOutOfBoundsException expected (2)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
- }
-
- /**
- * java.util.Arrays#sort(long[])
- */
- public void test_sort$J() {
- // Test for method void java.util.Arrays.sort(long [])
- long[] reversedArray = new long[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- reversedArray[counter] = (long) (arraySize - counter - 1);
- Arrays.sort(reversedArray);
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Resulting array not sorted",
- reversedArray[counter] == (long) counter);
-
- }
-
- /**
- * java.util.Arrays#sort(long[], int, int)
- */
- public void test_sort$JII() {
- // Test for method void java.util.Arrays.sort(long [], int, int)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- long[] reversedArray = new long[arraySize];
- long[] originalReversedArray = new long[arraySize];
- for (int counter = 0; counter < arraySize; counter++) {
- reversedArray[counter] = (long) (arraySize - counter - 1);
- originalReversedArray[counter] = reversedArray[counter];
- }
- Arrays.sort(reversedArray, startIndex, endIndex);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds",
- reversedArray[counter] <= reversedArray[counter + 1]);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
-
- //exception testing
- try {
- Arrays.sort(reversedArray, startIndex + 1, startIndex);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, -1, startIndex);
- fail("ArrayIndexOutOfBoundsException expected (1)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
- fail("ArrayIndexOutOfBoundsException expected (2)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
- }
-
- /**
- * java.util.Arrays#sort(java.lang.Object[])
- */
- public void test_sort$Ljava_lang_Object() {
- // Test for method void java.util.Arrays.sort(java.lang.Object [])
- Object[] reversedArray = new Object[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- reversedArray[counter] = objectArray[arraySize - counter - 1];
- Arrays.sort(reversedArray);
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Resulting array not sorted",
- reversedArray[counter] == objectArray[counter]);
-
- Arrays.fill(reversedArray, 0, reversedArray.length/2, "String");
- Arrays.fill(reversedArray, reversedArray.length/2, reversedArray.length, new Integer(1));
-
- try {
- Arrays.sort(reversedArray);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#sort(java.lang.Object[], int, int)
- */
- public void test_sort$Ljava_lang_ObjectII() {
- // Test for method void java.util.Arrays.sort(java.lang.Object [], int,
- // int)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- Object[] reversedArray = new Object[arraySize];
- Object[] originalReversedArray = new Object[arraySize];
- for (int counter = 0; counter < arraySize; counter++) {
- reversedArray[counter] = objectArray[arraySize - counter - 1];
- originalReversedArray[counter] = reversedArray[counter];
- }
- Arrays.sort(reversedArray, startIndex, endIndex);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds",
- ((Comparable) reversedArray[counter])
- .compareTo(reversedArray[counter + 1]) <= 0);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
-
- //exception testing
- try {
- Arrays.sort(reversedArray, startIndex + 1, startIndex);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, -1, startIndex);
- fail("ArrayIndexOutOfBoundsException expected (1)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
- fail("ArrayIndexOutOfBoundsException expected (2)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- Arrays.fill(reversedArray, 0, reversedArray.length/2, "String");
- Arrays.fill(reversedArray, reversedArray.length/2, reversedArray.length, new Integer(1));
-
- try {
- Arrays.sort(reversedArray, reversedArray.length/4, 3*reversedArray.length/4);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
-
- Arrays.sort(reversedArray, 0, reversedArray.length/4);
- Arrays.sort(reversedArray, 3*reversedArray.length/4, reversedArray.length);
- }
-
- /**
- * java.util.Arrays#sort(java.lang.Object[], int, int,
- * java.util.Comparator)
- */
- public void test_sort$Ljava_lang_ObjectIILjava_util_Comparator() {
- // Test for method void java.util.Arrays.sort(java.lang.Object [], int,
- // int, java.util.Comparator)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- ReversedIntegerComparator comp = new ReversedIntegerComparator();
- Object[] originalArray = new Object[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- originalArray[counter] = objectArray[counter];
- Arrays.sort(objectArray, startIndex, endIndex, comp);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- objectArray[counter] == originalArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds", comp.compare(
- objectArray[counter], objectArray[counter + 1]) <= 0);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- objectArray[counter] == originalArray[counter]);
-
- Arrays.fill(originalArray, 0, originalArray.length/2, "String");
- Arrays.fill(originalArray, originalArray.length/2, originalArray.length, new Integer(1));
-
- try {
- Arrays.sort(originalArray, startIndex, endIndex, comp);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
-
- Arrays.sort(originalArray, endIndex, originalArray.length, comp);
-
- try {
- Arrays.sort(originalArray, endIndex, originalArray.length + 1, comp);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.sort(originalArray, -1, startIndex, comp);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- Arrays.sort(originalArray, originalArray.length, endIndex, comp);
- fail("IllegalArgumentException expected");
- } catch(IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#sort(java.lang.Object[], java.util.Comparator)
- */
- public void test_sort$Ljava_lang_ObjectLjava_util_Comparator() {
- // Test for method void java.util.Arrays.sort(java.lang.Object [],
- // java.util.Comparator)
- ReversedIntegerComparator comp = new ReversedIntegerComparator();
- Arrays.sort(objectArray, comp);
- for (int counter = 0; counter < arraySize - 1; counter++)
- assertTrue("Array not sorted correctly with custom comparator",
- comp
- .compare(objectArray[counter],
- objectArray[counter + 1]) <= 0);
-
- Arrays.fill(objectArray, 0, objectArray.length/2, "String");
- Arrays.fill(objectArray, objectArray.length/2, objectArray.length, new Integer(1));
-
- try {
- Arrays.sort(objectArray, comp);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
- }
-
- /**
- * java.util.Arrays#sort(short[])
- */
- public void test_sort$S() {
- // Test for method void java.util.Arrays.sort(short [])
- short[] reversedArray = new short[arraySize];
- for (int counter = 0; counter < arraySize; counter++)
- reversedArray[counter] = (short) (arraySize - counter - 1);
- Arrays.sort(reversedArray);
- for (int counter = 0; counter < arraySize; counter++)
- assertTrue("Resulting array not sorted",
- reversedArray[counter] == (short) counter);
- }
-
- /**
- * java.util.Arrays#sort(short[], int, int)
- */
- public void test_sort$SII() {
- // Test for method void java.util.Arrays.sort(short [], int, int)
- int startIndex = arraySize / 4;
- int endIndex = 3 * arraySize / 4;
- short[] reversedArray = new short[arraySize];
- short[] originalReversedArray = new short[arraySize];
- for (int counter = 0; counter < arraySize; counter++) {
- reversedArray[counter] = (short) (arraySize - counter - 1);
- originalReversedArray[counter] = reversedArray[counter];
- }
- Arrays.sort(reversedArray, startIndex, endIndex);
- for (int counter = 0; counter < startIndex; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
- for (int counter = startIndex; counter < endIndex - 1; counter++)
- assertTrue("Array not sorted within bounds",
- reversedArray[counter] <= reversedArray[counter + 1]);
- for (int counter = endIndex; counter < arraySize; counter++)
- assertTrue("Array modified outside of bounds",
- reversedArray[counter] == originalReversedArray[counter]);
-
- //exception testing
- try {
- Arrays.sort(reversedArray, startIndex + 1, startIndex);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, -1, startIndex);
- fail("ArrayIndexOutOfBoundsException expected (1)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
-
- try {
- Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
- fail("ArrayIndexOutOfBoundsException expected (2)");
- } catch (ArrayIndexOutOfBoundsException ignore) {
- }
- }
-
- /**
- * java.util.Arrays#sort(byte[], int, int)
- */
- public void test_java_util_Arrays_sort_byte_array_NPE() {
- byte[] byte_array_null = null;
- try {
- java.util.Arrays.sort(byte_array_null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(byte_array_null, (int) -1, (int) 1);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Arrays#sort(char[], int, int)
- */
- public void test_java_util_Arrays_sort_char_array_NPE() {
- char[] char_array_null = null;
- try {
- java.util.Arrays.sort(char_array_null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(char_array_null, (int) -1, (int) 1);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Arrays#sort(double[], int, int)
- */
- public void test_java_util_Arrays_sort_double_array_NPE() {
- double[] double_array_null = null;
- try {
- java.util.Arrays.sort(double_array_null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(double_array_null, (int) -1, (int) 1);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Arrays#sort(float[], int, int)
- */
- public void test_java_util_Arrays_sort_float_array_NPE() {
- float[] float_array_null = null;
- try {
- java.util.Arrays.sort(float_array_null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(float_array_null, (int) -1, (int) 1);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Arrays#sort(int[], int, int)
- */
- public void test_java_util_Arrays_sort_int_array_NPE() {
- int[] int_array_null = null;
- try {
- java.util.Arrays.sort(int_array_null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(int_array_null, (int) -1, (int) 1);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Arrays#sort(Object[], int, int)
- */
- public void test_java_util_Arrays_sort_object_array_NPE() {
- Object[] object_array_null = null;
- try {
- java.util.Arrays.sort(object_array_null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(object_array_null, (int) -1, (int) 1);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(object_array_null, (int) -1, (int) 1, null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Arrays#sort(long[], int, int)
- */
- public void test_java_util_Arrays_sort_long_array_NPE() {
- long[] long_array_null = null;
- try {
- java.util.Arrays.sort(long_array_null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(long_array_null, (int) -1, (int) 1);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Arrays#sort(short[], int, int)
- */
- public void test_java_util_Arrays_sort_short_array_NPE() {
- short[] short_array_null = null;
- try {
- java.util.Arrays.sort(short_array_null);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- try {
- // Regression for HARMONY-378
- java.util.Arrays.sort(short_array_null, (int) -1, (int) 1);
- fail("Should throw java.lang.NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- }
-
- // Lenghts of arrays to test in test_sort;
- private static final int[] LENGTHS = { 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 100, 1000, 10000 };
-
- /**
- * java.util.Arrays#sort()
- */
- public void test_sort() {
- for (int len : LENGTHS) {
- PrimitiveTypeArrayBuilder.reset();
- int[] golden = new int[len];
- for (int m = 1; m < 2 * len; m *= 2) {
- for (PrimitiveTypeArrayBuilder builder : PrimitiveTypeArrayBuilder.values()) {
- builder.build(golden, m);
- int[] test = golden.clone();
-
- for (PrimitiveTypeConverter converter : PrimitiveTypeConverter.values()) {
- Object convertedGolden = converter.convert(golden);
- Object convertedTest = converter.convert(test);
- sort(convertedTest);
- checkSorted(convertedTest);
- assertEquals(checkSum(convertedGolden), checkSum(convertedTest));
- }
- }
- }
- }
- }
-
- private void sort(Object array) {
- if (array instanceof int[]) {
- Arrays.sort((int[]) array);
- }
- else if (array instanceof long[]) {
- Arrays.sort((long[]) array);
- } else if (array instanceof short[]) {
- Arrays.sort((short[]) array);
- } else if (array instanceof byte[]) {
- Arrays.sort((byte[]) array);
- } else if (array instanceof char[]) {
- Arrays.sort((char[]) array);
- } else if (array instanceof float[]) {
- Arrays.sort((float[]) array);
- } else if (array instanceof double[]) {
- Arrays.sort((double[]) array);
- } else {
- fail("Unknow type of array: " + array.getClass());
- }
- }
-
- private void checkSorted(Object array) {
- if (array instanceof int[]) {
- checkSorted((int[]) array);
- } else if (array instanceof long[]) {
- checkSorted((long[]) array);
- } else if (array instanceof short[]) {
- checkSorted((short[]) array);
- } else if (array instanceof byte[]) {
- checkSorted((byte[]) array);
- } else if (array instanceof char[]) {
- checkSorted((char[]) array);
- } else if (array instanceof float[]) {
- checkSorted((float[]) array);
- } else if (array instanceof double[]) {
- checkSorted((double[]) array);
- } else {
- fail("Unknow type of array: " + array.getClass());
- }
- }
-
- private void checkSorted(int[] a) {
- for (int i = 0; i < a.length - 1; i++) {
- if (a[i] > a[i + 1]) {
- orderFail(i, "" + a[i], "" + a[i + 1]);
- }
- }
- }
-
- private void checkSorted(long[] a) {
- for (int i = 0; i < a.length - 1; i++) {
- if (a[i] > a[i + 1]) {
- orderFail(i, "" + a[i], "" + a[i + 1]);
- }
- }
- }
-
- private void checkSorted(short[] a) {
- for (int i = 0; i < a.length - 1; i++) {
- if (a[i] > a[i + 1]) {
- orderFail(i, "" + a[i], "" + a[i + 1]);
- }
- }
- }
-
- private void checkSorted(byte[] a) {
- for (int i = 0; i < a.length - 1; i++) {
- if (a[i] > a[i + 1]) {
- orderFail(i, "" + a[i], "" + a[i + 1]);
- }
- }
- }
-
- private void checkSorted(char[] a) {
- for (int i = 0; i < a.length - 1; i++) {
- if (a[i] > a[i + 1]) {
- orderFail(i, "" + a[i], "" + a[i + 1]);
- }
- }
- }
-
- private void checkSorted(float[] a) {
- for (int i = 0; i < a.length - 1; i++) {
- if (a[i] > a[i + 1]) {
- orderFail(i, "" + a[i], "" + a[i + 1]);
- }
- }
- }
-
- private void checkSorted(double[] a) {
- for (int i = 0; i < a.length - 1; i++) {
- if (a[i] > a[i + 1]) {
- orderFail(i, "" + a[i], "" + a[i + 1]);
- }
- }
- }
-
-
- private void orderFail(int index, String value1, String value2) {
- fail("Array is not sorted at " + index + "-th position: " + value1 + " and " + value2);
- }
-
- private int checkSum(Object array) {
- if (array instanceof int[]) {
- return checkSum((int[]) array);
- } else if (array instanceof long[]) {
- return checkSum((long[]) array);
- } else if (array instanceof short[]) {
- return checkSum((short[]) array);
- } else if (array instanceof byte[]) {
- return checkSum((byte[]) array);
- } else if (array instanceof char[]) {
- return checkSum((char[]) array);
- } else if (array instanceof float[]) {
- return checkSum((float[]) array);
- } else if (array instanceof double[]) {
- return checkSum((double[]) array);
- } else {
- fail("Unknow type of array: " + array.getClass());
- }
- throw new AssertionError(); // Needed to shut up compiler
- }
-
- private int checkSum(int[] a) {
- int checkSum = 0;
-
- for (int e : a) {
- checkSum ^= e; // xor
- }
- return checkSum;
- }
-
- private int checkSum(long[] a) {
- long checkSum = 0;
-
- for (long e : a) {
- checkSum ^= e; // xor
- }
- return (int) checkSum;
- }
-
- private int checkSum(short[] a) {
- short checkSum = 0;
-
- for (short e : a) {
- checkSum ^= e; // xor
- }
- return (int) checkSum;
- }
-
- private int checkSum(byte[] a) {
- byte checkSum = 0;
-
- for (byte e : a) {
- checkSum ^= e; // xor
- }
- return (int) checkSum;
- }
-
- private int checkSum(char[] a) {
- char checkSum = 0;
-
- for (char e : a) {
- checkSum ^= e; // xor
- }
- return (int) checkSum;
- }
-
- private int checkSum(float[] a) {
- int checkSum = 0;
-
- for (float e : a) {
- checkSum ^= (int) e; // xor
- }
- return checkSum;
- }
-
- private int checkSum(double[] a) {
- int checkSum = 0;
-
- for (double e : a) {
- checkSum ^= (int) e; // xor
- }
- return checkSum;
- }
-
- private enum PrimitiveTypeArrayBuilder {
-
- RANDOM {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = ourRandom.nextInt();
- }
- }
- },
-
- ASCENDING {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = m + i;
- }
- }
- },
-
- DESCENDING {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = a.length - m - i;
- }
- }
- },
-
- ALL_EQUAL {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = m;
- }
- }
- },
-
- SAW {
- void build(int[] a, int m) {
- int incCount = 1;
- int decCount = a.length;
- int i = 0;
- int period = m;
- m--;
-
- while (true) {
- for (int k = 1; k <= period; k++) {
- if (i >= a.length) {
- return;
- }
- a[i++] = incCount++;
- }
- period += m;
-
- for (int k = 1; k <= period; k++) {
- if (i >= a.length) {
- return;
- }
- a[i++] = decCount--;
- }
- period += m;
- }
- }
- },
-
- REPEATED {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = i % m;
- }
- }
- },
-
- DUPLICATED {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = ourRandom.nextInt(m);
- }
- }
- },
-
- ORGAN_PIPES {
- void build(int[] a, int m) {
- int middle = a.length / (m + 1);
-
- for (int i = 0; i < middle; i++) {
- a[i] = i;
- }
- for (int i = middle; i < a.length ; i++) {
- a[i] = a.length - i - 1;
- }
- }
- },
-
- STAGGER {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = (i * m + i) % a.length;
- }
- }
- },
-
- PLATEAU {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = Math.min(i, m);
- }
- }
- },
-
- SHUFFLE {
- void build(int[] a, int m) {
- for (int i = 0; i < a.length; i++) {
- a[i] = ourRandom.nextBoolean() ? (ourFirst += 2) : (ourSecond += 2);
- }
- }
- };
-
- abstract void build(int[] a, int m);
-
- static void reset() {
- ourRandom = new Random(666);
- ourFirst = 0;
- ourSecond = 0;
- }
-
- @Override
- public String toString() {
- String name = name();
-
- for (int i = name.length(); i < 12; i++) {
- name += " " ;
- }
- return name;
- }
-
- private static int ourFirst;
- private static int ourSecond;
- private static Random ourRandom = new Random(666);
- }
-
- private enum PrimitiveTypeConverter {
-
- INT {
- Object convert(int[] a) {
- return a;
- }
- },
-
- LONG {
- Object convert(int[] a) {
- long[] b = new long[a.length];
-
- for (int i = 0; i < a.length; i++) {
- b[i] = (int) a[i];
- }
- return b;
- }
- },
-
- BYTE {
- Object convert(int[] a) {
- byte[] b = new byte[a.length];
-
- for (int i = 0; i < a.length; i++) {
- b[i] = (byte) a[i];
- }
- return b;
- }
- },
-
- SHORT {
- Object convert(int[] a) {
- short[] b = new short[a.length];
-
- for (int i = 0; i < a.length; i++) {
- b[i] = (short) a[i];
- }
- return b;
- }
- },
-
- CHAR {
- Object convert(int[] a) {
- char[] b = new char[a.length];
-
- for (int i = 0; i < a.length; i++) {
- b[i] = (char) a[i];
- }
- return b;
- }
- },
-
- FLOAT {
- Object convert(int[] a) {
- float[] b = new float[a.length];
-
- for (int i = 0; i < a.length; i++) {
- b[i] = (float) a[i];
- }
- return b;
- }
- },
-
- DOUBLE {
- Object convert(int[] a) {
- double[] b = new double[a.length];
-
- for (int i = 0; i < a.length; i++) {
- b[i] = (double) a[i];
- }
- return b;
- }
- };
-
- abstract Object convert(int[] a);
-
- public String toString() {
- String name = name();
-
- for (int i = name.length(); i < 9; i++) {
- name += " " ;
- }
- return name;
- }
- }
-
-
- /**
- * java.util.Arrays#deepEquals(Object[], Object[])
- */
- public void test_deepEquals$Ljava_lang_ObjectLjava_lang_Object() {
- int [] a1 = {1, 2, 3};
- short [] a2 = {0, 1};
- Object [] a3 = {new Integer(1), a2};
- int [] a4 = {6, 5, 4};
-
- int [] b1 = {1, 2, 3};
- short [] b2 = {0, 1};
- Object [] b3 = {new Integer(1), b2};
-
- Object a [] = {a1, a2, a3};
- Object b [] = {b1, b2, b3};
-
- assertFalse(Arrays.equals(a, b));
- assertTrue(Arrays.deepEquals(a,b));
-
- a[2] = a4;
-
- assertFalse(Arrays.deepEquals(a, b));
- }
-
- /**
- * java.util.Arrays#deepHashCode(Object[])
- */
- public void test_deepHashCode$Ljava_lang_Object() {
- int [] a1 = {1, 2, 3};
- short [] a2 = {0, 1};
- Object [] a3 = {new Integer(1), a2};
-
- int [] b1 = {1, 2, 3};
- short [] b2 = {0, 1};
- Object [] b3 = {new Integer(1), b2};
-
- Object a [] = {a1, a2, a3};
- Object b [] = {b1, b2, b3};
-
- int deep_hash_a = Arrays.deepHashCode(a);
- int deep_hash_b = Arrays.deepHashCode(b);
-
- assertEquals(deep_hash_a, deep_hash_b);
- }
-
- /**
- * java.util.Arrays#hashCode(boolean[] a)
- */
- public void test_hashCode$LZ() {
- int listHashCode;
- int arrayHashCode;
-
- boolean [] boolArr = {true, false, false, true, false};
- List listOfBoolean = new LinkedList();
- for (int i = 0; i < boolArr.length; i++) {
- listOfBoolean.add(new Boolean(boolArr[i]));
- }
- listHashCode = listOfBoolean.hashCode();
- arrayHashCode = Arrays.hashCode(boolArr);
- assertEquals(listHashCode, arrayHashCode);
- }
-
- /**
- * java.util.Arrays#hashCode(int[] a)
- */
- public void test_hashCode$LI() {
- int listHashCode;
- int arrayHashCode;
-
- int [] intArr = {10, 5, 134, 7, 19};
- List listOfInteger = new LinkedList();
-
- for (int i = 0; i < intArr.length; i++) {
- listOfInteger.add(new Integer(intArr[i]));
- }
- listHashCode = listOfInteger.hashCode();
- arrayHashCode = Arrays.hashCode(intArr);
- assertEquals(listHashCode, arrayHashCode);
-
- int [] intArr2 = {10, 5, 134, 7, 19};
- assertEquals(Arrays.hashCode(intArr2), Arrays.hashCode(intArr));
- }
-
- /**
- * java.util.Arrays#hashCode(char[] a)
- */
- public void test_hashCode$LC() {
- int listHashCode;
- int arrayHashCode;
-
- char [] charArr = {'a', 'g', 'x', 'c', 'm'};
- List listOfCharacter = new LinkedList();
- for (int i = 0; i < charArr.length; i++) {
- listOfCharacter.add(new Character(charArr[i]));
- }
- listHashCode = listOfCharacter.hashCode();
- arrayHashCode = Arrays.hashCode(charArr);
- assertEquals(listHashCode, arrayHashCode);
- }
-
- /**
- * java.util.Arrays#hashCode(byte[] a)
- */
- public void test_hashCode$LB() {
- int listHashCode;
- int arrayHashCode;
-
- byte [] byteArr = {5, 9, 7, 6, 17};
- List listOfByte = new LinkedList();
- for (int i = 0; i < byteArr.length; i++) {
- listOfByte.add(new Byte(byteArr[i]));
- }
- listHashCode = listOfByte.hashCode();
- arrayHashCode = Arrays.hashCode(byteArr);
- assertEquals(listHashCode, arrayHashCode);
- }
-
- /**
- * java.util.Arrays#hashCode(long[] a)
- */
- public void test_hashCode$LJ() {
- int listHashCode;
- int arrayHashCode;
-
- long [] longArr = {67890234512l, 97587236923425l, 257421912912l,
- 6754268100l, 5};
- List listOfLong = new LinkedList();
- for (int i = 0; i < longArr.length; i++) {
- listOfLong.add(new Long(longArr[i]));
- }
- listHashCode = listOfLong.hashCode();
- arrayHashCode = Arrays.hashCode(longArr);
- assertEquals(listHashCode, arrayHashCode);
- }
-
- /**
- * java.util.Arrays#hashCode(float[] a)
- */
- public void test_hashCode$LF() {
- int listHashCode;
- int arrayHashCode;
-
- float [] floatArr = {0.13497f, 0.268934f, 12e-5f, -3e+2f, 10e-4f};
- List listOfFloat = new LinkedList();
- for (int i = 0; i < floatArr.length; i++) {
- listOfFloat.add(new Float(floatArr[i]));
- }
- listHashCode = listOfFloat.hashCode();
- arrayHashCode = Arrays.hashCode(floatArr);
- assertEquals(listHashCode, arrayHashCode);
-
- float [] floatArr2 = {0.13497f, 0.268934f, 12e-5f, -3e+2f, 10e-4f};
- assertEquals(Arrays.hashCode(floatArr2), Arrays.hashCode(floatArr));
- }
-
- /**
- * java.util.Arrays#hashCode(double[] a)
- */
- public void test_hashCode$LD() {
- int listHashCode;
- int arrayHashCode;
-
- double [] doubleArr = {0.134945657, 0.0038754, 11e-150, -30e-300, 10e-4};
- List listOfDouble = new LinkedList();
- for (int i = 0; i < doubleArr.length; i++) {
- listOfDouble.add(new Double(doubleArr[i]));
- }
- listHashCode = listOfDouble.hashCode();
- arrayHashCode = Arrays.hashCode(doubleArr);
- assertEquals(listHashCode, arrayHashCode);
- }
-
- /**
- * java.util.Arrays#hashCode(short[] a)
- */
- public void test_hashCode$LS() {
- int listHashCode;
- int arrayHashCode;
-
- short [] shortArr = {35, 13, 45, 2, 91};
- List listOfShort = new LinkedList();
- for (int i = 0; i < shortArr.length; i++) {
- listOfShort.add(new Short(shortArr[i]));
- }
- listHashCode = listOfShort.hashCode();
- arrayHashCode = Arrays.hashCode(shortArr);
- assertEquals(listHashCode, arrayHashCode);
- }
-
- /**
- * java.util.Arrays#hashCode(Object[] a)
- */
- public void test_hashCode$Ljava_lang_Object() {
- int listHashCode;
- int arrayHashCode;
-
- Object[] objectArr = {new Integer(1), new Float(10e-12f), null};
- List listOfObject= new LinkedList();
- for (int i = 0; i < objectArr.length; i++) {
- listOfObject.add(objectArr[i]);
- }
- listHashCode = listOfObject.hashCode();
- arrayHashCode = Arrays.hashCode(objectArr);
- assertEquals(listHashCode, arrayHashCode);
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- objArray = new Object[arraySize];
- for (int i = 0; i < objArray.length; i++)
- objArray[i] = new Integer(i);
-
- booleanArray = new boolean[arraySize];
- byteArray = new byte[arraySize];
- charArray = new char[arraySize];
- doubleArray = new double[arraySize];
- floatArray = new float[arraySize];
- intArray = new int[arraySize];
- longArray = new long[arraySize];
- objectArray = new Object[arraySize];
- shortArray = new short[arraySize];
-
- for (int counter = 0; counter < arraySize; counter++) {
- byteArray[counter] = (byte) counter;
- charArray[counter] = (char) (counter + 1);
- doubleArray[counter] = counter;
- floatArray[counter] = counter;
- intArray[counter] = counter;
- longArray[counter] = counter;
- objectArray[counter] = objArray[counter];
- shortArray[counter] = (short) counter;
- }
- for (int counter = 0; counter < arraySize; counter += 2) {
- booleanArray[counter] = false;
- booleanArray[counter + 1] = true;
- }
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- objArray = null;
- booleanArray = null;
- byteArray = null;
- charArray = null;
- doubleArray = null;
- floatArray = null;
- intArray = null;
- longArray = null;
- objectArray = null;
- shortArray = null;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/BitSetTest.java b/luni/src/test/java/tests/api/java/util/BitSetTest.java
deleted file mode 100644
index e1abc48..0000000
--- a/luni/src/test/java/tests/api/java/util/BitSetTest.java
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.BitSet;
-
-public class BitSetTest extends junit.framework.TestCase {
-
- BitSet eightbs;
-
- public void test_Constructor() {
- BitSet bs = new BitSet();
- // Default size for a BitSet should be 64 elements;
- assertEquals("Created BitSet of incorrect size", 64, bs.size());
- assertEquals("New BitSet had invalid string representation", "{}", bs.toString());
- }
-
- public void test_ConstructorI() {
- BitSet bs = new BitSet(128);
- // Default size for a BitSet should be 64 elements;
-
- assertEquals("Created BitSet of incorrect size", 128, bs.size());
- assertTrue("New BitSet had invalid string representation: "
- + bs.toString(), bs.toString().equals("{}"));
-
- // All BitSets are created with elements of multiples of 64
-
- bs = new BitSet(89);
- assertEquals("Failed to round BitSet element size", 128, bs.size());
-
- try {
- bs = new BitSet(-9);
- fail();
- } catch (NegativeArraySizeException expected) {
- }
- }
-
- public void test_clone() {
- BitSet bs = (BitSet) eightbs.clone();
- assertTrue("Clone failed to return equal BitSet", eightbs.equals(bs));
-
- }
-
- public void test_equalsLjava_lang_Object() {
- BitSet bs;
-
- bs = (BitSet) eightbs.clone();
- assertTrue("Same BitSet returned false", eightbs.equals(eightbs));
- assertTrue("Identical BitSets returned false", eightbs.equals(bs));
- bs.clear(6);
- assertTrue("Different BitSets returned true", !eightbs.equals(bs));
- // Grow the BitSet
- bs = (BitSet) eightbs.clone();
- bs.set(128);
- assertFalse(eightbs.equals(bs));
- bs.clear(128);
- assertTrue(eightbs.equals(bs));
- }
-
- public void test_hashCode() {
- BitSet bs = (BitSet) eightbs.clone();
- bs.clear(2);
- bs.clear(6);
- assertEquals("BitSet returns wrong hash value", 1129, bs.hashCode());
- bs.set(10);
- bs.clear(3);
- assertEquals("BitSet returns wrong hash value", 97, bs.hashCode());
- }
-
- public void test_clear() {
- eightbs.clear();
- for (int i = 0; i < 8; i++) {
- assertTrue("Clear didn't clear bit " + i, !eightbs.get(i));
- }
- assertEquals("Test1: Wrong length", 0, eightbs.length());
-
- BitSet bs = new BitSet(3400);
- bs.set(0, bs.size() - 1); // ensure all bits are 1's
- bs.set(bs.size() - 1);
- bs.clear();
- assertEquals(0, bs.length());
- assertTrue(bs.isEmpty());
- assertEquals(0, bs.cardinality());
- }
-
- public void test_clearI() {
- eightbs.clear(7);
- assertFalse("Failed to clear bit", eightbs.get(7));
-
- // Check to see all other bits are still set
- for (int i = 0; i < 7; i++)
- assertTrue("Clear cleared incorrect bits", eightbs.get(i));
-
- eightbs.clear(165);
- assertFalse("Failed to clear bit", eightbs.get(165));
- // Try out of range
- try {
- eightbs.clear(-1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- BitSet bs = new BitSet(0);
- assertEquals("Test1: Wrong length,", 0, bs.length());
- assertEquals("Test1: Wrong size,", 0, bs.size());
-
- bs.clear(0);
- assertEquals("Test2: Wrong length,", 0, bs.length());
- assertEquals("Test2: Wrong size,", 0, bs.size());
-
- bs.clear(60);
- assertEquals("Test3: Wrong length,", 0, bs.length());
- assertEquals("Test3: Wrong size,", 0, bs.size());
-
- bs.clear(120);
- assertEquals("Test4: Wrong size,", 0, bs.size());
- assertEquals("Test4: Wrong length,", 0, bs.length());
-
- bs.set(25);
- assertEquals("Test5: Wrong size,", 64, bs.size());
- assertEquals("Test5: Wrong length,", 26, bs.length());
-
- bs.clear(80);
- assertEquals("Test6: Wrong size,", 64, bs.size());
- assertEquals("Test6: Wrong length,", 26, bs.length());
-
- bs.clear(25);
- assertEquals("Test7: Wrong size,", 64, bs.size());
- assertEquals("Test7: Wrong length,", 0, bs.length());
- }
-
- public void test_clearII() {
- // Regression for HARMONY-98
- BitSet bitset = new BitSet();
- for (int i = 0; i < 20; i++) {
- bitset.set(i);
- }
- bitset.clear(10, 10);
-
- // pos1 and pos2 are in the same bitset element
- BitSet bs = new BitSet(16);
- int initialSize = bs.size();
- assertEquals(64, initialSize);
- bs.set(0, initialSize);
- bs.clear(5);
- bs.clear(15);
- bs.clear(7, 11);
- assertEquals("{0, 1, 2, 3, 4, 6, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, " +
- "26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, " +
- "46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}", bs.toString());
- for (int i = initialSize; i < bs.size(); i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
-
- // pos1 and pos2 is in the same bitset element, boundry testing
- bs = new BitSet(16);
- initialSize = bs.size();
- bs.set(0, initialSize);
- bs.clear(7, 64);
- assertEquals("Failed to grow BitSet", 64, bs.size());
- for (int i = 0; i < 7; i++) {
- assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
- }
- for (int i = 7; i < 64; i++) {
- assertFalse("Failed to clear bit " + i, bs.get(i));
- }
- for (int i = 64; i < bs.size(); i++) {
- assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
- }
- // more boundary testing
- bs = new BitSet(32);
- initialSize = bs.size();
- bs.set(0, initialSize);
- bs.clear(0, 64);
- for (int i = 0; i < 64; i++) {
- assertFalse("Failed to clear bit " + i, bs.get(i));
- }
- for (int i = 64; i < bs.size(); i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
-
- bs = new BitSet(32);
- initialSize = bs.size();
- bs.set(0, initialSize);
- bs.clear(0, 65);
- for (int i = 0; i < 65; i++) {
- assertFalse("Failed to clear bit " + i, bs.get(i));
- }
- for (int i = 65; i < bs.size(); i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
-
- // pos1 and pos2 are in two sequential bitset elements
- bs = new BitSet(128);
- initialSize = bs.size();
- bs.set(0, initialSize);
- bs.clear(7);
- bs.clear(110);
- bs.clear(9, 74);
- for (int i = 0; i < 9; i++) {
- if (i == 7) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- } else {
- assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
- }
- }
- for (int i = 9; i < 74; i++) {
- assertFalse("Failed to clear bit " + i, bs.get(i));
- }
- for (int i = 74; i < initialSize; i++) {
- if (i == 110) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- } else {
- assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
- }
- }
- for (int i = initialSize; i < bs.size(); i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
-
- // pos1 and pos2 are in two non-sequential bitset elements
- bs = new BitSet(256);
- bs.set(0, 256);
- bs.clear(7);
- bs.clear(255);
- bs.clear(9, 219);
- for (int i = 0; i < 9; i++) {
- if (i == 7) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- } else {
- assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
- }
- }
-
- for (int i = 9; i < 219; i++) {
- assertFalse("failed to clear bit " + i, bs.get(i));
- }
- for (int i = 219; i < 255; i++) {
- assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
- }
- for (int i = 255; i < bs.size(); i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
-
- // test illegal args
- bs = new BitSet(10);
- try {
- bs.clear(-1, 3);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- bs.clear(2, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- bs.set(2, 4);
- bs.clear(2, 2);
- assertTrue("Bit got cleared incorrectly ", bs.get(2));
-
- try {
- bs.clear(4, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- bs = new BitSet(0);
- assertEquals("Test1: Wrong length,", 0, bs.length());
- assertEquals("Test1: Wrong size,", 0, bs.size());
-
- bs.clear(0, 2);
- assertEquals("Test2: Wrong length,", 0, bs.length());
- assertEquals("Test2: Wrong size,", 0, bs.size());
-
- bs.clear(60, 64);
- assertEquals("Test3: Wrong length,", 0, bs.length());
- assertEquals("Test3: Wrong size,", 0, bs.size());
-
- bs.clear(64, 120);
- assertEquals("Test4: Wrong length,", 0, bs.length());
- assertEquals("Test4: Wrong size,", 0, bs.size());
-
- bs.set(25);
- assertEquals("Test5: Wrong length,", 26, bs.length());
- assertEquals("Test5: Wrong size,", 64, bs.size());
-
- bs.clear(60, 64);
- assertEquals("Test6: Wrong length,", 26, bs.length());
- assertEquals("Test6: Wrong size,", 64, bs.size());
-
- bs.clear(64, 120);
- assertEquals("Test7: Wrong size,", 64, bs.size());
- assertEquals("Test7: Wrong length,", 26, bs.length());
-
- bs.clear(80);
- assertEquals("Test8: Wrong size,", 64, bs.size());
- assertEquals("Test8: Wrong length,", 26, bs.length());
-
- bs.clear(25);
- assertEquals("Test9: Wrong size,", 64, bs.size());
- assertEquals("Test9: Wrong length,", 0, bs.length());
- }
-
- public void test_getI() {
- BitSet bs = new BitSet();
- bs.set(8);
- assertFalse("Get returned true for index out of range", eightbs.get(99));
- assertTrue("Get returned false for set value", eightbs.get(3));
- assertFalse("Get returned true for a non set value", bs.get(0));
-
- try {
- bs.get(-1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- bs = new BitSet(1);
- assertFalse("Access greater than size", bs.get(64));
-
- bs = new BitSet();
- bs.set(63);
- assertTrue("Test highest bit", bs.get(63));
-
- bs = new BitSet(0);
- assertEquals("Test1: Wrong length,", 0, bs.length());
- assertEquals("Test1: Wrong size,", 0, bs.size());
-
- bs.get(2);
- assertEquals("Test2: Wrong length,", 0, bs.length());
- assertEquals("Test2: Wrong size,", 0, bs.size());
-
- bs.get(70);
- assertEquals("Test3: Wrong length,", 0, bs.length());
- assertEquals("Test3: Wrong size,", 0, bs.size());
-
- }
-
- public void test_getII() {
- BitSet bitset = new BitSet(30);
- bitset.get(3, 3);
-
- BitSet bs, resultbs, correctbs;
- bs = new BitSet(512);
- bs.set(3, 9);
- bs.set(10, 20);
- bs.set(60, 75);
- bs.set(121);
- bs.set(130, 140);
-
- // pos1 and pos2 are in the same bitset element, at index0
- resultbs = bs.get(3, 6);
- correctbs = new BitSet(3);
- correctbs.set(0, 3);
- assertEquals("Test1: Returned incorrect BitSet", correctbs, resultbs);
-
- // pos1 and pos2 are in the same bitset element, at index 1
- resultbs = bs.get(100, 125);
- correctbs = new BitSet(25);
- correctbs.set(21);
- assertEquals("Test2: Returned incorrect BitSet", correctbs, resultbs);
-
- // pos1 in bitset element at index 0, and pos2 in bitset element at
- // index 1
- resultbs = bs.get(15, 125);
- correctbs = new BitSet(25);
- correctbs.set(0, 5);
- correctbs.set(45, 60);
- correctbs.set(121 - 15);
- assertEquals("Test3: Returned incorrect BitSet", correctbs, resultbs);
-
- // pos1 in bitset element at index 1, and pos2 in bitset element at
- // index 2
- resultbs = bs.get(70, 145);
- correctbs = new BitSet(75);
- correctbs.set(0, 5);
- correctbs.set(51);
- correctbs.set(60, 70);
- assertEquals("Test4: Returned incorrect BitSet", correctbs, resultbs);
-
- // pos1 in bitset element at index 0, and pos2 in bitset element at
- // index 2
- resultbs = bs.get(5, 145);
- correctbs = new BitSet(140);
- correctbs.set(0, 4);
- correctbs.set(5, 15);
- correctbs.set(55, 70);
- correctbs.set(116);
- correctbs.set(125, 135);
- assertEquals("Test5: Returned incorrect BitSet", correctbs, resultbs);
-
- // pos1 in bitset element at index 0, and pos2 in bitset element at
- // index 3
- resultbs = bs.get(5, 250);
- correctbs = new BitSet(200);
- correctbs.set(0, 4);
- correctbs.set(5, 15);
- correctbs.set(55, 70);
- correctbs.set(116);
- correctbs.set(125, 135);
- assertEquals("Test6: Returned incorrect BitSet", correctbs, resultbs);
-
- assertEquals("equality principle 1 ", bs.get(0, bs.size()), bs);
-
- // more tests
- BitSet bs2 = new BitSet(129);
- bs2.set(0, 20);
- bs2.set(62, 65);
- bs2.set(121, 123);
- resultbs = bs2.get(1, 124);
- correctbs = new BitSet(129);
- correctbs.set(0, 19);
- correctbs.set(61, 64);
- correctbs.set(120, 122);
- assertEquals("Test7: Returned incorrect BitSet", correctbs, resultbs);
-
- // equality principle with some boundary conditions
- bs2 = new BitSet(128);
- bs2.set(2, 20);
- bs2.set(62);
- bs2.set(121, 123);
- bs2.set(127);
- resultbs = bs2.get(0, bs2.size());
- assertEquals("equality principle 2 ", resultbs, bs2);
-
- bs2 = new BitSet(128);
- bs2.set(2, 20);
- bs2.set(62);
- bs2.set(121, 123);
- bs2.set(127);
- bs2.flip(0, 128);
- resultbs = bs2.get(0, bs.size());
- assertEquals("equality principle 3 ", resultbs, bs2);
-
- bs = new BitSet(0);
- assertEquals("Test1: Wrong length,", 0, bs.length());
- assertEquals("Test1: Wrong size,", 0, bs.size());
-
- bs.get(0, 2);
- assertEquals("Test2: Wrong length,", 0, bs.length());
- assertEquals("Test2: Wrong size,", 0, bs.size());
-
- bs.get(60, 64);
- assertEquals("Test3: Wrong length,", 0, bs.length());
- assertEquals("Test3: Wrong size,", 0, bs.size());
-
- bs.get(64, 120);
- assertEquals("Test4: Wrong length,", 0, bs.length());
- assertEquals("Test4: Wrong size,", 0, bs.size());
-
- bs.set(25);
- assertEquals("Test5: Wrong length,", 26, bs.length());
- assertEquals("Test5: Wrong size,", 64, bs.size());
-
- bs.get(60, 64);
- assertEquals("Test6: Wrong length,", 26, bs.length());
- assertEquals("Test6: Wrong size,", 64, bs.size());
-
- bs.get(64, 120);
- assertEquals("Test7: Wrong size,", 64, bs.size());
- assertEquals("Test7: Wrong length,", 26, bs.length());
-
- bs.get(80);
- assertEquals("Test8: Wrong size,", 64, bs.size());
- assertEquals("Test8: Wrong length,", 26, bs.length());
-
- bs.get(25);
- assertEquals("Test9: Wrong size,", 64, bs.size());
- assertEquals("Test9: Wrong length,", 26, bs.length());
-
- try {
- bs2.get(-1, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- bs2.get(bs2.size()/2, 0);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- bs2.get(bs2.size()/2, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void test_setI() {
- BitSet bs = new BitSet();
- bs.set(8);
- assertTrue("Failed to set bit", bs.get(8));
-
- try {
- bs.set(-1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- // Try setting a bit on a 64 boundary
- bs.set(128);
- assertEquals("Failed to grow BitSet", 192, bs.size());
- assertTrue("Failed to set bit", bs.get(128));
-
- bs = new BitSet(64);
- for (int i = bs.size(); --i >= 0;) {
- bs.set(i);
- assertTrue("Incorrectly set", bs.get(i));
- assertTrue("Incorrect length", bs.length() == (i + 1));
- for (int j = bs.size(); --j > i;)
- assertTrue("Incorrectly set bit " + j, !bs.get(j));
- for (int j = i; --j >= 0;)
- assertTrue("Incorrectly set bit " + j, !bs.get(j));
- bs.clear(i);
- }
-
- bs = new BitSet(0);
- assertTrue("Test1: Wrong length, " + bs.size(), bs.length() == 0);
- bs.set(0);
- assertTrue("Test2: Wrong length" + bs.size(), bs.length() == 1);
- }
-
- public void test_setIZ() {
- eightbs.set(5, false);
- assertTrue("Should have set bit 5 to true", !eightbs.get(5));
-
- eightbs.set(5, true);
- assertTrue("Should have set bit 5 to false", eightbs.get(5));
-
- try {
- eightbs.set(-5, false);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void test_setII() {
- BitSet bitset = new BitSet(30);
- bitset.set(29, 29);
-
- // pos1 and pos2 are in the same bitset element
- BitSet bs = new BitSet(16);
- bs.set(5);
- bs.set(15);
- bs.set(7, 11);
- assertEquals("{5, 7, 8, 9, 10, 15}", bs.toString());
- for (int i = 16; i < bs.size(); i++) {
- assertFalse("Shouldn't have set bit " + i, bs.get(i));
- }
-
- // pos1 and pos2 is in the same bitset element, boundry testing
- bs = new BitSet(16);
- bs.set(7, 64);
- assertEquals("Failed to grow BitSet", 64, bs.size());
- for (int i = 0; i < 7; i++) {
- assertFalse("Shouldn't have set bit " + i, bs.get(i));
- }
- for (int i = 7; i < 64; i++) {
- assertTrue("Failed to set bit " + i, bs.get(i));
- }
- assertFalse("Shouldn't have set bit 64", bs.get(64));
-
- // more boundary testing
- bs = new BitSet(32);
- bs.set(0, 64);
- for (int i = 0; i < 64; i++) {
- assertTrue("Failed to set bit " + i, bs.get(i));
- }
- assertFalse("Shouldn't have set bit 64", bs.get(64));
-
- bs = new BitSet(32);
- bs.set(0, 65);
- for (int i = 0; i < 65; i++) {
- assertTrue("Failed to set bit " + i, bs.get(i));
- }
- assertFalse("Shouldn't have set bit 65", bs.get(65));
-
- // pos1 and pos2 are in two sequential bitset elements
- bs = new BitSet(128);
- bs.set(7);
- bs.set(110);
- bs.set(9, 74);
- for (int i = 0; i < 9; i++) {
- if (i == 7) {
- assertTrue("Shouldn't have flipped bit " + i, bs.get(i));
- } else {
- assertFalse("Shouldn't have set bit " + i, bs.get(i));
- }
- }
- for (int i = 9; i < 74; i++) {
- assertTrue("Failed to set bit " + i, bs.get(i));
- }
- for (int i = 74; i < bs.size(); i++) {
- if (i == 110) {
- assertTrue("Shouldn't have flipped bit " + i, bs.get(i));
- } else {
- assertFalse("Shouldn't have set bit " + i, bs.get(i));
- }
- }
-
- // pos1 and pos2 are in two non-sequential bitset elements
- bs = new BitSet(256);
- bs.set(7);
- bs.set(255);
- bs.set(9, 219);
- for (int i = 0; i < 9; i++) {
- if (i == 7) {
- assertTrue("Shouldn't have set flipped " + i, bs.get(i));
- } else {
- assertFalse("Shouldn't have set bit " + i, bs.get(i));
- }
- }
-
- for (int i = 9; i < 219; i++) {
- assertTrue("failed to set bit " + i, bs.get(i));
- }
-
- for (int i = 219; i < 255; i++) {
- assertFalse("Shouldn't have set bit " + i, bs.get(i));
- }
-
- assertTrue("Shouldn't have flipped bit 255", bs.get(255));
-
- // test illegal args
- bs = new BitSet(10);
- try {
- bs.set(-1, 3);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- bs.set(2, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- bs.set(2, 2);
- assertFalse("Bit got set incorrectly ", bs.get(2));
-
- try {
- bs.set(4, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void test_setIIZ() {
- eightbs.set(3, 6, false);
- assertTrue("Should have set bits 3, 4, and 5 to false", !eightbs.get(3)
- && !eightbs.get(4) && !eightbs.get(5));
-
- eightbs.set(3, 6, true);
- assertTrue("Should have set bits 3, 4, and 5 to true", eightbs.get(3)
- && eightbs.get(4) && eightbs.get(5));
-
- try {
- eightbs.set(-3, 6, false);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- eightbs.set(3, -6, false);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- eightbs.set(6, 3, false);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void test_flipI() {
- BitSet bs = new BitSet();
- bs.clear(8);
- bs.clear(9);
- bs.set(10);
- bs.flip(9);
- assertFalse("Failed to flip bit", bs.get(8));
- assertTrue("Failed to flip bit", bs.get(9));
- assertTrue("Failed to flip bit", bs.get(10));
-
- bs.set(8);
- bs.set(9);
- bs.clear(10);
- bs.flip(9);
- assertTrue("Failed to flip bit", bs.get(8));
- assertFalse("Failed to flip bit", bs.get(9));
- assertFalse("Failed to flip bit", bs.get(10));
-
- try {
- bs.flip(-1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- // Try setting a bit on a 64 boundary
- bs.flip(128);
- assertEquals("Failed to grow BitSet", 192, bs.size());
- assertTrue("Failed to flip bit", bs.get(128));
-
- bs = new BitSet(64);
- for (int i = bs.size(); --i >= 0;) {
- bs.flip(i);
- assertTrue("Test1: Incorrectly flipped bit" + i, bs.get(i));
- assertEquals("Incorrect length", i+1, bs.length());
- for (int j = bs.size(); --j > i;) {
- assertTrue("Test2: Incorrectly flipped bit" + j, !bs.get(j));
- }
- for (int j = i; --j >= 0;) {
- assertTrue("Test3: Incorrectly flipped bit" + j, !bs.get(j));
- }
- bs.flip(i);
- }
-
- BitSet bs0 = new BitSet(0);
- assertEquals("Test1: Wrong size", 0, bs0.size());
- assertEquals("Test1: Wrong length", 0, bs0.length());
-
- bs0.flip(0);
- assertEquals("Test2: Wrong size", 64, bs0.size());
- assertEquals("Test2: Wrong length", 1, bs0.length());
-
- bs0.flip(63);
- assertEquals("Test3: Wrong size", 64, bs0.size());
- assertEquals("Test3: Wrong length", 64, bs0.length());
-
- eightbs.flip(7);
- assertTrue("Failed to flip bit 7", !eightbs.get(7));
-
- // Check to see all other bits are still set
- for (int i = 0; i < 7; i++) {
- assertTrue("Flip flipped incorrect bits", eightbs.get(i));
- }
-
- eightbs.flip(127);
- assertTrue("Failed to flip bit 127", eightbs.get(127));
-
- eightbs.flip(127);
- assertTrue("Failed to flip bit 127", !eightbs.get(127));
- }
-
- public void test_flipII() {
- BitSet bitset = new BitSet();
- for (int i = 0; i < 20; i++) {
- bitset.set(i);
- }
- bitset.flip(10, 10);
-
- // pos1 and pos2 are in the same bitset element
- BitSet bs = new BitSet(16);
- bs.set(7);
- bs.set(10);
- bs.flip(7, 11);
- for (int i = 0; i < 7; i++) {
- assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
- }
- assertFalse("Failed to flip bit 7", bs.get(7));
- assertTrue("Failed to flip bit 8", bs.get(8));
- assertTrue("Failed to flip bit 9", bs.get(9));
- assertFalse("Failed to flip bit 10", bs.get(10));
- for (int i = 11; i < bs.size(); i++) {
- assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
- }
-
- // pos1 and pos2 is in the same bitset element, boundry testing
- bs = new BitSet(16);
- bs.set(7);
- bs.set(10);
- bs.flip(7, 64);
- assertEquals("Failed to grow BitSet", 64, bs.size());
- for (int i = 0; i < 7; i++) {
- assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
- }
- assertFalse("Failed to flip bit 7", bs.get(7));
- assertTrue("Failed to flip bit 8", bs.get(8));
- assertTrue("Failed to flip bit 9", bs.get(9));
- assertFalse("Failed to flip bit 10", bs.get(10));
- for (int i = 11; i < 64; i++) {
- assertTrue("failed to flip bit " + i, bs.get(i));
- }
- assertFalse("Shouldn't have flipped bit 64", bs.get(64));
-
- // more boundary testing
- bs = new BitSet(32);
- bs.flip(0, 64);
- for (int i = 0; i < 64; i++) {
- assertTrue("Failed to flip bit " + i, bs.get(i));
- }
- assertFalse("Shouldn't have flipped bit 64", bs.get(64));
-
- bs = new BitSet(32);
- bs.flip(0, 65);
- for (int i = 0; i < 65; i++) {
- assertTrue("Failed to flip bit " + i, bs.get(i));
- }
- assertFalse("Shouldn't have flipped bit 65", bs.get(65));
-
- // pos1 and pos2 are in two sequential bitset elements
- bs = new BitSet(128);
- bs.set(7);
- bs.set(10);
- bs.set(72);
- bs.set(110);
- bs.flip(9, 74);
- for (int i = 0; i < 7; i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
- assertTrue("Shouldn't have flipped bit 7", bs.get(7));
- assertFalse("Shouldn't have flipped bit 8", bs.get(8));
- assertTrue("Failed to flip bit 9", bs.get(9));
- assertFalse("Failed to flip bit 10", bs.get(10));
- for (int i = 11; i < 72; i++) {
- assertTrue("failed to flip bit " + i, bs.get(i));
- }
- assertFalse("Failed to flip bit 72", bs.get(72));
- assertTrue("Failed to flip bit 73", bs.get(73));
- for (int i = 74; i < 110; i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
- assertTrue("Shouldn't have flipped bit 110", bs.get(110));
- for (int i = 111; i < bs.size(); i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
-
- // pos1 and pos2 are in two non-sequential bitset elements
- bs = new BitSet(256);
- bs.set(7);
- bs.set(10);
- bs.set(72);
- bs.set(110);
- bs.set(181);
- bs.set(220);
- bs.flip(9, 219);
- for (int i = 0; i < 7; i++) {
- assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
- }
- assertTrue("Shouldn't have flipped bit 7", bs.get(7));
- assertFalse("Shouldn't have flipped bit 8", bs.get(8));
- assertTrue("Failed to flip bit 9", bs.get(9));
- assertFalse("Failed to flip bit 10", bs.get(10));
- for (int i = 11; i < 72; i++) {
- assertTrue("failed to flip bit " + i, bs.get(i));
- }
- assertFalse("Failed to flip bit 72", bs.get(72));
- for (int i = 73; i < 110; i++) {
- assertTrue("failed to flip bit " + i, bs.get(i));
- }
- assertFalse("Failed to flip bit 110", bs.get(110));
- for (int i = 111; i < 181; i++) {
- assertTrue("failed to flip bit " + i, bs.get(i));
- }
- assertFalse("Failed to flip bit 181", bs.get(181));
- for (int i = 182; i < 219; i++) {
- assertTrue("failed to flip bit " + i, bs.get(i));
- }
- assertFalse("Shouldn't have flipped bit 219", bs.get(219));
- assertTrue("Shouldn't have flipped bit 220", bs.get(220));
- for (int i = 221; i < bs.size(); i++) {
- assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
- }
-
- // test illegal args
- bs = new BitSet(10);
- try {
- bs.flip(-1, 3);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- bs.flip(2, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- bs.flip(4, 2);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void test_111478() throws Exception {
- // BitSet shouldn't be modified by any of the operations below,
- // since the affected bits for these methods are defined as inclusive of
- // pos1, exclusive of pos2.
- eightbs.flip(0, 0);
- assertTrue("Bit got flipped incorrectly ", eightbs.get(0));
-
- BitSet bsnew = eightbs.get(2, 2);
- assertEquals(0, bsnew.cardinality());
-
- eightbs.set(10, 10);
- assertTrue("Bit got set incorrectly ", !eightbs.get(10));
-
- eightbs.clear(3, 3);
- assertTrue("Bit cleared incorrectly ", eightbs.get(3));
- }
-
- public void test_intersectsLjava_util_BitSet() {
- BitSet bs = new BitSet(500);
- bs.set(5);
- bs.set(63);
- bs.set(64);
- bs.set(71, 110);
- bs.set(127, 130);
- bs.set(192);
- bs.set(450);
-
- BitSet bs2 = new BitSet(8);
- assertFalse("Test1: intersects() returned incorrect value", bs.intersects(bs2));
- assertFalse("Test1: intersects() returned incorrect value", bs2.intersects(bs));
-
- bs2.set(4);
- assertFalse("Test2: intersects() returned incorrect value", bs.intersects(bs2));
- assertFalse("Test2: intersects() returned incorrect value", bs2.intersects(bs));
-
- bs2.clear();
- bs2.set(5);
- assertTrue("Test3: intersects() returned incorrect value", bs.intersects(bs2));
- assertTrue("Test3: intersects() returned incorrect value", bs2.intersects(bs));
-
- bs2.clear();
- bs2.set(63);
- assertTrue("Test4: intersects() returned incorrect value", bs.intersects(bs2));
- assertTrue("Test4: intersects() returned incorrect value", bs2.intersects(bs));
-
- bs2.clear();
- bs2.set(80);
- assertTrue("Test5: intersects() returned incorrect value", bs.intersects(bs2));
- assertTrue("Test5: intersects() returned incorrect value", bs2.intersects(bs));
-
- bs2.clear();
- bs2.set(127);
- assertTrue("Test6: intersects() returned incorrect value", bs.intersects(bs2));
- assertTrue("Test6: intersects() returned incorrect value", bs2.intersects(bs));
-
- bs2.clear();
- bs2.set(192);
- assertTrue("Test7: intersects() returned incorrect value", bs.intersects(bs2));
- assertTrue("Test7: intersects() returned incorrect value", bs2.intersects(bs));
-
- bs2.clear();
- bs2.set(450);
- assertTrue("Test8: intersects() returned incorrect value", bs.intersects(bs2));
- assertTrue("Test8: intersects() returned incorrect value", bs2.intersects(bs));
-
- bs2.clear();
- bs2.set(500);
- assertFalse("Test9: intersects() returned incorrect value", bs.intersects(bs2));
- assertFalse("Test9: intersects() returned incorrect value", bs2.intersects(bs));
- }
-
- public void test_andLjava_util_BitSet() {
- BitSet bs = new BitSet(128);
- // Initialize the bottom half of the BitSet
- for (int i = 64; i < 128; i++) {
- bs.set(i);
- }
- eightbs.and(bs);
- assertTrue("AND failed to clear bits", !eightbs.equals(bs));
- eightbs.set(3);
- bs.set(3);
- eightbs.and(bs);
- assertTrue("AND failed to maintain set bits", bs.get(3));
- bs.and(eightbs);
- for (int i = 64; i < 128; i++) {
- assertTrue("Failed to clear extra bits in the receiver BitSet", !bs.get(i));
- }
- }
-
- public void test_andNotLjava_util_BitSet() {
- BitSet bs = (BitSet) eightbs.clone();
- bs.clear(5);
- BitSet bs2 = new BitSet();
- bs2.set(2);
- bs2.set(3);
- bs.andNot(bs2);
- assertEquals("Incorrect bitset after andNot",
- "{0, 1, 4, 6, 7}", bs.toString());
-
- bs = new BitSet(0);
- bs.andNot(bs2);
- assertEquals("Incorrect size", 0, bs.size());
- }
-
- public void test_orLjava_util_BitSet() {
- BitSet bs = new BitSet(128);
- bs.or(eightbs);
- for (int i = 0; i < 8; i++) {
- assertTrue("OR failed to set bits", bs.get(i));
- }
- bs = new BitSet(0);
- bs.or(eightbs);
- for (int i = 0; i < 8; i++) {
- assertTrue("OR(0) failed to set bits", bs.get(i));
- }
- eightbs.clear(5);
- bs = new BitSet(128);
- bs.or(eightbs);
- assertTrue("OR set a bit which should be off", !bs.get(5));
- }
-
- public void test_xorLjava_util_BitSet() {
- BitSet bs = (BitSet) eightbs.clone();
- bs.xor(eightbs);
- for (int i = 0; i < 8; i++) {
- assertTrue("XOR failed to clear bit " + i + bs, !bs.get(i));
- }
- bs.xor(eightbs);
- for (int i = 0; i < 8; i++) {
- assertTrue("XOR failed to set bit " + i + bs, bs.get(i));
- }
- bs = new BitSet(0);
- bs.xor(eightbs);
- for (int i = 0; i < 8; i++) {
- assertTrue("XOR(0) failed to set bit " + i + bs, bs.get(i));
- }
- bs = new BitSet();
- bs.set(63);
- assertEquals("{63}", bs.toString());
- }
-
- public void test_size() {
- assertEquals("Returned incorrect size", 64, eightbs.size());
- eightbs.set(129);
- assertTrue("Returned incorrect size", eightbs.size() >= 129);
-
- }
-
- public void test_toString() {
- assertEquals("Returned incorrect string representation", "{0, 1, 2, 3, 4, 5, 6, 7}", eightbs.toString());
- eightbs.clear(2);
- assertEquals("Returned incorrect string representation", "{0, 1, 3, 4, 5, 6, 7}", eightbs.toString());
- }
-
- public void test_length() {
- BitSet bs = new BitSet();
- assertEquals(bs.toString(), 0, bs.length());
- bs.set(5);
- assertEquals(bs.toString(), 6, bs.length());
- bs.set(10);
- assertEquals(bs.toString(), 11, bs.length());
- bs.set(432);
- assertEquals(bs.toString(), 433, bs.length());
- bs.set(300);
- assertEquals(bs.toString(), 433, bs.length());
- }
-
- public void test_nextSetBitI() {
- BitSet bs = new BitSet(500);
- bs.set(5);
- bs.set(32);
- bs.set(63);
- bs.set(64);
- bs.set(71, 110);
- bs.set(127, 130);
- bs.set(193);
- bs.set(450);
- try {
- bs.nextSetBit(-1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- assertEquals(5, bs.nextSetBit(0));
- assertEquals(5, bs.nextSetBit(5));
- assertEquals(32, bs.nextSetBit(6));
- assertEquals(32, bs.nextSetBit(32));
- assertEquals(63, bs.nextSetBit(33));
-
- // boundary tests
- assertEquals(63, bs.nextSetBit(63));
- assertEquals(64, bs.nextSetBit(64));
-
- // at bitset element 1
- assertEquals(71, bs.nextSetBit(65));
- assertEquals(71, bs.nextSetBit(71));
- assertEquals(72, bs.nextSetBit(72));
- assertEquals(127, bs.nextSetBit(110));
-
- // boundary tests
- assertEquals(127, bs.nextSetBit(127));
- assertEquals(128, bs.nextSetBit(128));
-
- // at bitset element 2
- assertEquals(193, bs.nextSetBit(130));
-
- assertEquals(193, bs.nextSetBit(191));
- assertEquals(193, bs.nextSetBit(192));
- assertEquals(193, bs.nextSetBit(193));
- assertEquals(450, bs.nextSetBit(194));
- assertEquals(450, bs.nextSetBit(255));
- assertEquals(450, bs.nextSetBit(256));
- assertEquals(450, bs.nextSetBit(450));
-
- assertEquals(-1, bs.nextSetBit(451));
- assertEquals(-1, bs.nextSetBit(511));
- assertEquals(-1, bs.nextSetBit(512));
- assertEquals(-1, bs.nextSetBit(800));
- }
-
- public void test_nextClearBitI() {
- BitSet bs = new BitSet(500);
- // ensure all the bits from 0 to bs.size() - 1 are set to true
- bs.set(0, bs.size() - 1);
- bs.set(bs.size() - 1);
- bs.clear(5);
- bs.clear(32);
- bs.clear(63);
- bs.clear(64);
- bs.clear(71, 110);
- bs.clear(127, 130);
- bs.clear(193);
- bs.clear(450);
- try {
- bs.nextClearBit(-1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- assertEquals(5, bs.nextClearBit(0));
- assertEquals(5, bs.nextClearBit(5));
- assertEquals(32, bs.nextClearBit(6));
- assertEquals(32, bs.nextClearBit(32));
- assertEquals(63, bs.nextClearBit(33));
-
- // boundary tests
- assertEquals(63, bs.nextClearBit(63));
- assertEquals(64, bs.nextClearBit(64));
-
- // at bitset element 1
- assertEquals(71, bs.nextClearBit(65));
- assertEquals(71, bs.nextClearBit(71));
- assertEquals(72, bs.nextClearBit(72));
- assertEquals(127, bs.nextClearBit(110));
-
- // boundary tests
- assertEquals(127, bs.nextClearBit(127));
- assertEquals(128, bs.nextClearBit(128));
-
- // at bitset element 2
- assertEquals(193, bs.nextClearBit(130));
- assertEquals(193, bs.nextClearBit(191));
-
- assertEquals(193, bs.nextClearBit(192));
- assertEquals(193, bs.nextClearBit(193));
- assertEquals(450, bs.nextClearBit(194));
- assertEquals(450, bs.nextClearBit(255));
- assertEquals(450, bs.nextClearBit(256));
- assertEquals(450, bs.nextClearBit(450));
-
- // bitset has 1 still the end of bs.size() -1, but calling nextClearBit
- // with any index value after the last true bit should return bs.size()
- assertEquals(512, bs.nextClearBit(451));
- assertEquals(512, bs.nextClearBit(511));
- assertEquals(512, bs.nextClearBit(512));
-
- // if the index is larger than bs.size(), nextClearBit should return index
- assertEquals(513, bs.nextClearBit(513));
- assertEquals(800, bs.nextClearBit(800));
-
- bs.clear();
- assertEquals(0, bs.nextClearBit(0));
- assertEquals(3, bs.nextClearBit(3));
- assertEquals(64, bs.nextClearBit(64));
- assertEquals(128, bs.nextClearBit(128));
- }
-
- // http://code.google.com/p/android/issues/detail?id=31036
- public void test_31036_clear() {
- BitSet bs = new BitSet(500);
- for (int i = 0; i < 500; ++i) {
- int nextClear = bs.nextClearBit(0);
- assertEquals(i, nextClear);
- bs.set(i);
- }
- }
-
- // http://code.google.com/p/android/issues/detail?id=31036
- public void test_31036_set() {
- BitSet bs = new BitSet(500);
- bs.set(0, 511);
- for (int i = 0; i < 500; ++i) {
- int nextSet = bs.nextSetBit(0);
- assertEquals(i, nextSet);
- bs.clear(i);
- }
- }
-
- public void test_isEmpty() {
- BitSet bs = new BitSet(500);
- assertTrue("Test: isEmpty() returned wrong value", bs.isEmpty());
-
- // at bitset element 0
- bs.set(3);
- assertFalse("Test0: isEmpty() returned wrong value", bs.isEmpty());
-
- // at bitset element 1
- bs.clear();
- bs.set(12);
- assertFalse("Test1: isEmpty() returned wrong value", bs.isEmpty());
-
- // at bitset element 2
- bs.clear();
- bs.set(128);
- assertFalse("Test2: isEmpty() returned wrong value", bs.isEmpty());
-
- // boundary testing
- bs.clear();
- bs.set(459);
- assertFalse("Test3: isEmpty() returned wrong value", bs.isEmpty());
-
- bs.clear();
- bs.set(511);
- assertFalse("Test4: isEmpty() returned wrong value", bs.isEmpty());
- }
-
- public void test_cardinality() {
- BitSet bs = new BitSet(500);
- bs.set(5);
- bs.set(32);
- bs.set(63);
- bs.set(64);
- assertEquals(bs.toString(), 4, bs.cardinality());
- bs.set(71, 110);
- bs.set(127, 130);
- bs.set(193);
- bs.set(450);
- assertEquals(bs.toString(), 48, bs.cardinality());
-
- bs.flip(0, 500);
- assertEquals("cardinality() returned wrong value", 452, bs
- .cardinality());
-
- bs.clear();
- assertEquals("cardinality() returned wrong value", 0, bs.cardinality());
-
- bs.set(0, 500);
- assertEquals("cardinality() returned wrong value", 500, bs
- .cardinality());
- }
-
- private static void printBitset(BitSet bs) {
- System.out.println();
- for (int i = bs.size() - 1; i >= 0; i--) {
- if (bs.get(i))
- System.out.print(1);
- else
- System.out.print(0);
- }
- }
-
- protected void setUp() {
- eightbs = new BitSet();
- for (int i = 0; i < 8; i++) {
- eightbs.set(i);
- }
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/CalendarTest.java b/luni/src/test/java/tests/api/java/util/CalendarTest.java
deleted file mode 100644
index 54524ad..0000000
--- a/luni/src/test/java/tests/api/java/util/CalendarTest.java
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.text.DateFormatSymbols;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-public class CalendarTest extends junit.framework.TestCase {
-
- Locale defaultLocale;
-
- /**
- * java.util.Calendar#set(int, int)
- */
- public void test_setII() {
- // Test for correct result defined by the last set field
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- assertTrue("Incorrect result 0: " + cal.getTime().getTime(), cal
- .getTime().getTime() == 1009861200000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- assertTrue("Incorrect result 0a: " + cal.getTime(), cal.getTime()
- .getTime() == 1014958800000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DATE, 24);
- assertTrue("Incorrect result 0b: " + cal.getTime(), cal.getTime()
- .getTime() == 1011848400000L);
-
- cal.set(Calendar.MONTH, Calendar.OCTOBER);
- cal.set(Calendar.DATE, 31);
- cal.set(Calendar.MONTH, Calendar.NOVEMBER);
- cal.set(Calendar.DATE, 26);
- assertTrue("Incorrect month: " + cal.get(Calendar.MONTH), cal
- .get(Calendar.MONTH) == Calendar.NOVEMBER);
-
- int dow = cal.get(Calendar.DAY_OF_WEEK);
- cal.set(Calendar.DATE, 27);
- assertTrue("Incorrect DAY_OF_WEEK: " + cal.get(Calendar.DAY_OF_WEEK)
- + " expected: " + dow, cal.get(Calendar.DAY_OF_WEEK) != dow);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- assertTrue("Incorrect result 0c1: " + cal.getTime().getTime(), cal
- .getTime().getTime() == 1010379600000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
- assertTrue("Incorrect result 0c2: " + cal.getTime().getTime(), cal
- .getTime().getTime() == 1009861200000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
- assertTrue("Incorrect result 0c3: " + cal.getTime(), cal.getTime()
- .getTime() == 1010034000000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_MONTH, 2);
- assertTrue("Incorrect result 0d: " + cal.getTime(), cal.getTime()
- .getTime() == 1010293200000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2);
- assertTrue("Incorrect result 0e: " + cal.getTime(), cal.getTime()
- .getTime() == 1010898000000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 11);
- assertTrue("Incorrect result 0f: " + cal.getTime(), cal.getTime()
- .getTime() == 1015736400000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DATE, 24);
- cal.set(Calendar.WEEK_OF_YEAR, 11);
- assertTrue("Incorrect result 0g: " + cal.getTime(), cal.getTime()
- .getTime() == 1011848400000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.get(Calendar.WEEK_OF_YEAR); // Force fields to compute
- cal.set(Calendar.WEEK_OF_YEAR, 11);
- assertTrue("Incorrect result 0h: " + cal.getTime(), cal.getTime()
- .getTime() == 1015909200000L);
-
- // WEEK_OF_YEAR has priority over MONTH/DATE
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_YEAR, 170);
- cal.set(Calendar.WEEK_OF_YEAR, 11);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- cal.set(Calendar.DATE, 5);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- assertTrue("Incorrect result 1: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // WEEK_OF_YEAR has priority over MONTH/DATE
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 11);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- cal.set(Calendar.DATE, 5);
- cal.set(Calendar.DAY_OF_YEAR, 170);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- assertTrue("Incorrect result 1a: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // DAY_OF_WEEK has no effect when other fields not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.DATE, 11);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
- assertTrue("Incorrect result 1b: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
- // Regression for HARMONY-4384
- // Set DAY_OF_WEEK without DATE
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
- assertEquals("Incorrect result 1b: " + cal.getTime(), 1015304400000L, cal.getTime()
- .getTime());
-
-
- // WEEK_OF_MONTH has priority
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 12);
- cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
- cal.set(Calendar.WEEK_OF_MONTH, 3);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.DATE, 5);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- assertTrue("Incorrect result 2: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // DAY_OF_WEEK_IN_MONTH has priority over WEEK_OF_YEAR
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 12);
- cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.DATE, 5);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- assertTrue("Incorrect result 3: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // WEEK_OF_MONTH has priority, MONTH not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 12);
- cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
- cal.set(Calendar.WEEK_OF_MONTH, 3);
- cal.set(Calendar.DATE, 25);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- assertTrue("Incorrect result 4: " + cal.getTime(), cal.getTime()
- .getTime() == 1010984400000L);
-
- // WEEK_OF_YEAR has priority when MONTH set last and DAY_OF_WEEK set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 11);
- cal.set(Calendar.DATE, 25);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- assertTrue("Incorrect result 5: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // Use MONTH/DATE when WEEK_OF_YEAR set but not DAY_OF_WEEK
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 12);
- cal.set(Calendar.DATE, 11);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- assertTrue("Incorrect result 5a: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // Use MONTH/DATE when DAY_OF_WEEK is not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 12);
- cal.set(Calendar.DATE, 11);
- cal.set(Calendar.WEEK_OF_MONTH, 1);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- assertTrue("Incorrect result 5b: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // WEEK_OF_MONTH has priority
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 12);
- cal.set(Calendar.DATE, 5);
- cal.set(Calendar.WEEK_OF_MONTH, 3);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- assertTrue("Incorrect result 5c: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // DATE has priority when set last
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 12);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.DATE, 11);
- assertTrue("Incorrect result 6: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // DATE has priority when set last, MONTH not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 12);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- cal.set(Calendar.DATE, 14);
- assertTrue("Incorrect result 7: " + cal.getTime(), cal.getTime()
- .getTime() == 1010984400000L);
-
- // DAY_OF_YEAR has priority when MONTH set last and DATE not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_YEAR, 70);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- assertTrue("Incorrect result 8: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // DAY/MONTH has priority when DATE set after DAY_OF_YEAR
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_YEAR, 170);
- cal.set(Calendar.DATE, 11);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- assertTrue("Incorrect result 8a: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // DAY_OF_YEAR has priority when set after DATE
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DATE, 15);
- cal.set(Calendar.DAY_OF_YEAR, 70);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- assertTrue("Incorrect result 8b: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // DATE has priority when set last
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_YEAR, 70);
- cal.set(Calendar.DATE, 14);
- assertTrue("Incorrect result 9: " + cal.getTime(), cal.getTime()
- .getTime() == 1010984400000L);
-
- // DATE has priority when set last
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_YEAR, 15);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
- cal.set(Calendar.DATE, 14);
- assertTrue("Incorrect result 9a: " + cal.getTime(), cal.getTime()
- .getTime() == 1010984400000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- cal.set(Calendar.DATE, 14);
- cal.set(Calendar.WEEK_OF_YEAR, 11);
- assertTrue("Incorrect result 9b: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DATE, 14);
- cal.set(Calendar.WEEK_OF_YEAR, 11);
- assertTrue("Incorrect result 9c: " + cal.getTime(), cal.getTime()
- .getTime() == 1010984400000L);
-
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.WEEK_OF_MONTH, 1);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.DATE, 11);
- assertTrue("Incorrect result 9d: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // DAY_OF_YEAR has priority when DAY_OF_MONTH set last and other fields
- // not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_YEAR, 70);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
- assertTrue("Incorrect result 10: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // MONTH/DATE has priority when DAY_OF_WEEK_IN_MONTH set last but
- // DAY_OF_WEEK not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DATE, 11);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
- assertTrue("Incorrect result 11: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // MONTH/DATE has priority when WEEK_OF_YEAR set last but DAY_OF_WEEK
- // not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DATE, 11);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.WEEK_OF_YEAR, 15);
- assertTrue("Incorrect result 12: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // MONTH/DATE has priority when WEEK_OF_MONTH set last but DAY_OF_WEEK
- // not set
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DATE, 11);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.WEEK_OF_MONTH, 1);
- assertTrue("Incorrect result 13: " + cal.getTime(), cal.getTime()
- .getTime() == 1015822800000L);
-
- // Ensure last date field set is reset after computing
- cal.clear();
- cal.set(Calendar.YEAR, 2002);
- cal.set(Calendar.DAY_OF_YEAR, 111);
- cal.get(Calendar.YEAR);
- cal.set(Calendar.MONTH, Calendar.MARCH);
- cal.set(Calendar.AM_PM, Calendar.AM);
- assertTrue("Incorrect result 14: " + cal.getTime(), cal.getTime()
- .getTime() == 1016686800000L);
-
- int hour = cal.get(Calendar.HOUR);
- cal.set(Calendar.HOUR, hour);
- cal.set(Calendar.AM_PM, Calendar.PM);
- assertEquals("AM_PM not changed", Calendar.PM, cal.get(Calendar.AM_PM));
- // setting AM_PM without HOUR should not have any affect
- cal.set(Calendar.AM_PM, Calendar.AM);
- assertEquals("AM_PM was changed 1",
- Calendar.AM, cal.get(Calendar.AM_PM));
- int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
- hour = cal.get(Calendar.HOUR);
- cal.set(Calendar.AM_PM, Calendar.PM);
- assertEquals("AM_PM was changed 2",
- Calendar.PM, cal.get(Calendar.AM_PM));
- assertEquals(hour, cal.get(Calendar.HOUR));
- assertEquals(hourOfDay + 12, cal.get(Calendar.HOUR_OF_DAY));
-
- // regression test for Harmony-2122
- cal = Calendar.getInstance();
- int oldValue = cal.get(Calendar.AM_PM);
- int newValue = (oldValue == Calendar.AM) ? Calendar.PM : Calendar.AM;
- cal.set(Calendar.AM_PM, newValue);
- newValue = cal.get(Calendar.AM_PM);
- assertTrue(newValue != oldValue);
- }
-
- /**
- * java.util.Calendar#setTime(java.util.Date)
- */
- public void test_setTimeLjava_util_Date() {
- Calendar cal = Calendar.getInstance();
- // Use millisecond time for testing in Core
- cal.setTime(new Date(884581200000L)); // (98, Calendar.JANUARY, 12)
- assertEquals("incorrect millis", 884581200000L, cal.getTime().getTime());
- cal.setTimeZone(TimeZone.getTimeZone("EST"));
- cal.setTime(new Date(943506000000L)); // (99, Calendar.NOVEMBER, 25)
- assertTrue("incorrect fields", cal.get(Calendar.YEAR) == 1999
- && cal.get(Calendar.MONTH) == Calendar.NOVEMBER
- && cal.get(Calendar.DATE) == 25);
- }
-
- /**
- * java.util.Calendar#compareTo(Calendar)
- */
- public void test_compareToLjava_util_Calendar_null() {
- Calendar cal = Calendar.getInstance();
- try {
- cal.compareTo(null);
- fail("should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- }
-
- /**
- * java.util.Calendar#compareTo(Calendar)
- */
- public void test_compareToLjava_util_Calendar() {
- Calendar cal = Calendar.getInstance();
- cal.clear();
- cal.set(1997, 12, 13, 23, 57);
-
- Calendar anotherCal = Calendar.getInstance();
- anotherCal.clear();
- anotherCal.set(1997, 12, 13, 23, 57);
- assertEquals(0, cal.compareTo(anotherCal));
-
- anotherCal = Calendar.getInstance();
- anotherCal.clear();
- anotherCal.set(1997, 11, 13, 24, 57);
- assertEquals(1, cal.compareTo(anotherCal));
-
- anotherCal = Calendar.getInstance();
- anotherCal.clear();
- anotherCal.set(1997, 12, 13, 23, 58);
- assertEquals(-1, cal.compareTo(anotherCal));
- }
-
- /**
- * java.util.Calendar#clone()
- */
- public void test_clone() {
- // Regression for HARMONY-475
- Calendar cal = Calendar.getInstance();
- cal.set(2006, 5, 6, 11, 35);
- Calendar anotherCal = (Calendar) cal.clone();
- // should be deep clone
- assertNotSame("getTimeZone", cal.getTimeZone(), anotherCal
- .getTimeZone());
- }
-
- /**
- * java.util.Calendar#getTimeInMillis()
- */
- public void test_getTimeInMillis() {
- Calendar cal = Calendar.getInstance();
-
- int year = Integer.MIN_VALUE + 71;
- cal.setTimeZone(TimeZone.getTimeZone("GMT"));
- cal.set(Calendar.YEAR, year + 1900);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
-
- assertEquals(6017546357372606464L, cal.getTimeInMillis());
- }
-
- private static final Locale[] locales = new Locale[] { Locale.getDefault(),
- Locale.US, Locale.UK, Locale.TAIWAN, Locale.PRC, Locale.KOREA,
- Locale.JAPAN, Locale.ITALIAN, Locale.GERMAN, Locale.ENGLISH,
- Locale.CHINA, Locale.CANADA, Locale.FRANCE };
-
- /**
- * java.util.Calendar#before(Object)
- * java.util.Calendar#after(Object)
- */
- public void test_before_after() {
- Calendar early = Calendar.getInstance();
- Calendar late = Calendar.getInstance();
- // test by second
- early.set(2008, 3, 20, 17, 28, 12);
- late.set(2008, 3, 20, 17, 28, 22);
- // test before()
- assertTrue(early.before(late));
- assertFalse(early.before(early));
- assertFalse(late.before(early));
- // test after();
- assertTrue(late.after(early));
- assertFalse(late.after(late));
- assertFalse(early.after(late));
-
- // test by minute
- early.set(2008, 3, 20, 17, 18, 12);
- late.set(2008, 3, 20, 17, 28, 12);
- // test before()
- assertTrue(early.before(late));
- assertFalse(early.before(early));
- assertFalse(late.before(early));
- // test after();
- assertTrue(late.after(early));
- assertFalse(late.after(late));
- assertFalse(early.after(late));
-
- // test by hour
- early.set(2008, 3, 20, 17, 28, 12);
- late.set(2008, 3, 20, 27, 28, 12);
- // test before()
- assertTrue(early.before(late));
- assertFalse(early.before(early));
- assertFalse(late.before(early));
- // test after();
- assertTrue(late.after(early));
- assertFalse(late.after(late));
- assertFalse(early.after(late));
-
- // test by day
- early.set(2008, 3, 10, 17, 28, 12);
- late.set(2008, 3, 20, 17, 28, 12);
- // test before()
- assertTrue(early.before(late));
- assertFalse(early.before(early));
- assertFalse(late.before(early));
- // test after();
- assertTrue(late.after(early));
- assertFalse(late.after(late));
- assertFalse(early.after(late));
-
- // test by month
- early.set(2008, 2, 20, 17, 28, 12);
- late.set(2008, 3, 20, 17, 28, 12);
- // test before()
- assertTrue(early.before(late));
- assertFalse(early.before(early));
- assertFalse(late.before(early));
- // test after();
- assertTrue(late.after(early));
- assertFalse(late.after(late));
- assertFalse(early.after(late));
-
- // test by year
- early.set(2007, 3, 20, 17, 28, 12);
- late.set(2008, 3, 20, 17, 28, 12);
- // test before()
- assertTrue(early.before(late));
- assertFalse(early.before(early));
- assertFalse(late.before(early));
- // test after();
- assertTrue(late.after(early));
- assertFalse(late.after(late));
- assertFalse(early.after(late));
- }
-
- /**
- * java.util.Calendar#clear()
- * java.util.Calendar#clear(int)
- */
- public void test_clear() {
- Calendar calendar = Calendar.getInstance();
-
- int count = 6;
- int[] fields = new int[count];
- int[] defaults = new int[count];
-
- fields[0] = Calendar.YEAR;
- fields[1] = Calendar.MONTH;
- fields[2] = Calendar.DATE;
- fields[3] = Calendar.HOUR_OF_DAY;
- fields[4] = Calendar.MINUTE;
- fields[5] = Calendar.SECOND;
-
- defaults[0] = 1970;
- defaults[1] = 0;
- defaults[2] = 1;
- defaults[3] = 0;
- defaults[4] = 0;
- defaults[5] = 0;
-
- calendar.set(2008, 3, 20, 17, 28, 12);
-
- // test clear(int)
- for (int i = 0; i < fields.length; i++) {
- int index = fields[i];
- calendar.clear(index);
- if (5 == index) {
- // RI also doesn't change the value of DATE
- assertEquals("Field " + index + " Should equal to 20.", 20,
- calendar.get(index));
- } else if (11 == index) {
- // RI also doesn't change the value of HOUR
- assertEquals("Field " + index + " Should equal to 17.", 17,
- calendar.get(index));
- } else {
- // Other have been set to default values
- assertEquals("Field " + index + " Should equal to "
- + defaults[i] + ".", defaults[i], calendar.get(index));
- }
- }
-
- // test clear()
- calendar.set(2008, 3, 20, 17, 28, 12);
-
- calendar.clear();
-
- for (int i = 0; i < fields.length; i++) {
- int index = fields[i];
- assertEquals("Field " + index + " Should equal to "
- + defaults[i] + ".", defaults[i], calendar.get(index));
- }
- }
-
- /**
- * java.util.Calendar#isSet(int)
- */
- public void test_isSet() {
- Calendar calendar = Calendar.getInstance();
- calendar.clear();
- for (int i = 0; i < Calendar.FIELD_COUNT; i++) {
- assertFalse(calendar.isSet(i));
- }
- }
-
- /**
- * java.util.Calendar#getAvailableLocales()
- */
- public void test_getAvailableLocales() {
- Locale[] locales = Calendar.getAvailableLocales();
- boolean exist = false;
- for (int i = 0; i < locales.length; i++) {
- Locale l = locales[i];
- if (Locale.US.equals(l)) {
- exist = true;
- break;
- }
- }
- assertTrue(exist);
- }
-
- /**
- * java.util.Calendar#getInstance(Locale)
- * java.util.Calendar#getInstance(TimeZone, Locale)
- */
- public void test_getInstance() {
- // test getInstance(Locale)
- Calendar us_calendar = Calendar.getInstance(Locale.US);
- Calendar de_calendar = Calendar.getInstance(Locale.GERMAN);
- assertEquals(Calendar.SUNDAY, us_calendar
- .getFirstDayOfWeek());
- assertEquals(Calendar.MONDAY, de_calendar
- .getFirstDayOfWeek());
-
- // test getInstance(Locale, TimeZone)
- Calendar gmt_calendar = Calendar.getInstance(TimeZone
- .getTimeZone("GMT"), Locale.US);
- assertEquals(TimeZone.getTimeZone("GMT"),
- gmt_calendar.getTimeZone());
- Calendar est_calendar = Calendar.getInstance(TimeZone
- .getTimeZone("EST"), Locale.US);
- assertEquals(TimeZone.getTimeZone("EST")
- .getID(), est_calendar.getTimeZone().getID());
- }
-
- /**
- * java.util.Calendar#internalGet(int)
- */
- public void test_internalGet() {
- MockGregorianCalendar c = new MockGregorianCalendar();
- c.clear(Calendar.YEAR);
- assertEquals(0, c.internal_get(Calendar.YEAR));
- }
-
- /**
- * java.util.Calendar#hashCode()
- */
- public void test_hashcode() {
- Calendar calendar = Calendar.getInstance(Locale.JAPAN);
- assertTrue(calendar.hashCode() == calendar.hashCode());
- }
-
- /**
- * java.util.Calendar#roll(int, int)
- */
- public void test_roll() {
- Calendar calendar = Calendar.getInstance();
- calendar.set(2008, 3, 20, 17, 28, 12);
-
- // roll up
- calendar.roll(Calendar.DATE, 5);
- assertEquals(25, calendar.get(Calendar.DATE));
-
- // roll down
- calendar.roll(Calendar.DATE, -5);
- assertEquals(20, calendar.get(Calendar.DATE));
-
- // roll 0
- calendar.roll(Calendar.DATE, 0);
- assertEquals(20, calendar.get(Calendar.DATE));
-
- // roll overweight
- calendar.set(2008, 1, 31, 17, 28, 12);
- calendar.roll(Calendar.MONTH, 1);
- assertEquals(2, calendar.get(Calendar.DATE));
-
- }
-
- /**
- * java.util.Calendar#toString()
- */
- public void test_toString() {
- Calendar calendar = Calendar.getInstance();
- //Should be the current time with no interrogation in the string.
- assertTrue(calendar.toString() instanceof String);
- assertEquals(-1, calendar.toString().indexOf("?"));
- calendar.clear();
- assertTrue(calendar.toString() instanceof String);
- assertTrue(0 <= calendar.toString().indexOf("?"));
- }
-
- /**
- * serialization/deserialization.
- */
- public void testSerializationSelf() throws Exception {
- Calendar calendar = Calendar.getInstance();
- calendar.set(2008, 3, 20, 17, 28, 12);
-
- SerializationTest.verifySelf(calendar);
- }
-
-
- private class MockGregorianCalendar extends GregorianCalendar {
- public int internal_get(int field) {
- return super.internalGet(field);
- }
- }
-
- private class MockCalendar extends Calendar {
-
- public MockCalendar() {
- super();
- }
-
- @Override
- public void add(int field, int value) {
- }
-
- @Override
- protected void computeFields() {
- }
-
- @Override
- protected void computeTime() {
- }
-
- @Override
- public int getGreatestMinimum(int field) {
- return 0;
- }
-
- @Override
- public int getLeastMaximum(int field) {
- return 0;
- }
-
- @Override
- public int getMaximum(int field) {
- return 0;
- }
-
- @Override
- public int getMinimum(int field) {
- return 0;
- }
-
- @Override
- public void roll(int field, boolean increment) {
- }
- }
-
- /**
- * {@link java.util.Calendar#getDisplayName(int, int, Locale)}
- * @since 1.6
- */
- public void test_getDisplayNameIILjava_util_Locale() {
- Calendar cal = Calendar.getInstance();
- for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
- for (Locale locale : locales) {
- DateFormatSymbols symbols = new DateFormatSymbols(locale);
- String value = null;
- switch (field) {
- case Calendar.AM_PM:
- cal.set(Calendar.AM_PM, Calendar.AM);
- value = symbols.getAmPmStrings()[0];
- assertEquals(cal.getDisplayName(field, Calendar.SHORT,
- locale), value);
- assertEquals(cal.getDisplayName(field, Calendar.LONG,
- locale), value);
- cal.set(Calendar.AM_PM, Calendar.PM);
- value = symbols.getAmPmStrings()[1];
- assertEquals(cal.getDisplayName(field, Calendar.SHORT,
- locale), value);
- assertEquals(cal.getDisplayName(field, Calendar.LONG,
- locale), value);
- break;
- case Calendar.ERA:
- cal.set(Calendar.ERA, GregorianCalendar.BC);
- value = symbols.getEras()[0];
- assertEquals(cal.getDisplayName(field, Calendar.SHORT,
- locale), value);
- assertEquals(cal.getDisplayName(field, Calendar.LONG,
- locale), value);
- cal.set(Calendar.ERA, GregorianCalendar.AD);
- value = symbols.getEras()[1];
- assertEquals(cal.getDisplayName(field, Calendar.SHORT,
- locale), value);
- assertEquals(cal.getDisplayName(field, Calendar.LONG,
- locale), value);
- break;
- case Calendar.MONTH:
- cal.set(Calendar.DAY_OF_MONTH, 1);
- for (int month = 0; month <= 11; month++) {
- cal.set(Calendar.MONTH, month);
- value = symbols.getShortMonths()[month];
- assertEquals(cal.getDisplayName(field, Calendar.SHORT,
- locale), value);
- value = symbols.getMonths()[month];
- assertEquals(cal.getDisplayName(field, Calendar.LONG,
- locale), value);
- }
- break;
- case Calendar.DAY_OF_WEEK:
- for (int day = 1; day <= 7; day++) {
- cal.set(Calendar.DAY_OF_WEEK, day);
- value = symbols.getShortWeekdays()[day];
- assertEquals(cal.getDisplayName(field, Calendar.SHORT,
- locale), value);
- value = symbols.getWeekdays()[day];
- assertEquals(cal.getDisplayName(field, Calendar.LONG,
- locale), value);
- }
- break;
- default:
- assertNull(cal
- .getDisplayName(field, Calendar.SHORT, locale));
- assertNull(cal.getDisplayName(field, Calendar.LONG, locale));
- }
- }
- }
-
- cal.setLenient(true);
-
- try {
- cal.getDisplayName(-1, Calendar.SHORT, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayName(Calendar.FIELD_COUNT, Calendar.LONG, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayName(Calendar.MONTH, -1, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayName(Calendar.MONTH, 3, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- cal.getDisplayName(-1, Calendar.SHORT, null);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayName(Calendar.MONTH, -1, null);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- // in lenient mode, following cases pass
- cal.set(Calendar.SECOND, 999);
- cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US);
- // test for ALL_STYLES, it is equal to use SHORT
- for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
- for (Locale locale : locales) {
- String result = cal.getDisplayName(field, Calendar.ALL_STYLES,
- locale);
- if (field == Calendar.AM_PM || field == Calendar.ERA
- || field == Calendar.MONTH
- || field == Calendar.DAY_OF_WEEK) {
- assertEquals(result, cal.getDisplayName(field,
- Calendar.SHORT, locale));
- } else {
- assertNull(result);
- }
- }
- }
-
- // invalid value for an un-related field when the calendar is not
- // lenient
- cal.setLenient(false);
- assertNotNull(cal.getDisplayName(Calendar.MONTH, Calendar.SHORT,
- Locale.US));
- cal.set(Calendar.SECOND, 999);
- try {
- cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayName(Calendar.MONTH, Calendar.ALL_STYLES, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * {@link java.util.Calendar#getDisplayNames(int, int, Locale)}
- * @since 1.6
- */
- public void test_getDisplayNamesIILjava_util_Locale() {
- assertEquals(0, Calendar.ALL_STYLES);
- assertEquals(1, Calendar.SHORT);
- assertEquals(2, Calendar.LONG);
-
- Calendar cal = Calendar.getInstance(Locale.US);
-
- for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
- for (Locale locale : locales) {
- Map<String, Integer> shortResult = cal.getDisplayNames(field,
- Calendar.SHORT, locale);
- Map<String, Integer> longResult = cal.getDisplayNames(field,
- Calendar.LONG, locale);
- Map<String, Integer> allResult = cal.getDisplayNames(field,
- Calendar.ALL_STYLES, locale);
- DateFormatSymbols symbols = new DateFormatSymbols(locale);
- String[] values = null;
- switch (field) {
- case Calendar.AM_PM:
- case Calendar.ERA:
- values = (field == Calendar.AM_PM) ? symbols
- .getAmPmStrings() : symbols.getEras();
- assertDisplayNameMap(values, shortResult, 0);
- assertDisplayNameMap(values, longResult, 0);
- assertDisplayNameMap(values, allResult, 0);
- break;
- case Calendar.MONTH:
- values = symbols.getShortMonths();
- assertDisplayNameMap(values, shortResult, 0);
- values = symbols.getMonths();
- assertDisplayNameMap(values, longResult, 0);
- assertTrue(allResult.size() >= shortResult.size());
- assertTrue(allResult.size() >= longResult.size());
- assertTrue(allResult.size() <= shortResult.size()
- + longResult.size());
- break;
- case Calendar.DAY_OF_WEEK:
- values = symbols.getShortWeekdays();
- assertDisplayNameMap(values, shortResult, 1);
- values = symbols.getWeekdays();
- assertDisplayNameMap(values, longResult, 1);
- assertTrue(allResult.size() >= shortResult.size());
- assertTrue(allResult.size() >= longResult.size());
- assertTrue(allResult.size() <= shortResult.size()
- + longResult.size());
- break;
- default:
- assertNull(shortResult);
- assertNull(longResult);
- assertNull(allResult);
- }
- }
- }
-
- cal.setLenient(true);
-
- try {
- cal.getDisplayNames(-1, Calendar.SHORT, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayNames(Calendar.FIELD_COUNT, Calendar.LONG, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayNames(Calendar.MONTH, -1, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayNames(Calendar.MONTH, 3, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
- try {
- cal.getDisplayNames(-1, Calendar.SHORT, null);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- try {
- cal.getDisplayNames(Calendar.MONTH, -1, null);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- cal.set(Calendar.SECOND, 999);
- cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.US);
-
- // RI fails here
- // invalid value for an un-related field when the calendar is not
- // lenient
- cal.setLenient(false);
- cal.set(Calendar.SECOND, 999);
- try {
- cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.US);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- private void assertDisplayNameMap(String[] values,
- Map<String, Integer> result, int shift) {
- List<String> trimValue = new ArrayList<String>();
- for (String value : values) {
- if (value.trim().length() > 0) {
- trimValue.add(value);
- }
- }
- assertEquals(trimValue.size(), result.size());
- for (int i = 0; i < trimValue.size(); i++) {
- assertEquals(i + shift, result.get(trimValue.get(i)).intValue());
- }
- }
-
- /**
- * {@link java.util.Calendar#getActualMaximum(int)}
- */
- public void test_getActualMaximum_I() {
- Calendar c = new MockCalendar();
- assertEquals("should be equal to 0", 0, c.getActualMaximum(0));
- }
-
- /**
- * {@link java.util.Calendar#getActualMinimum(int)}
- */
- public void test_getActualMinimum_I() {
- Calendar c = new MockCalendar();
- assertEquals("should be equal to 0", 0, c.getActualMinimum(0));
- }
-
- protected void setUp() {
- defaultLocale = Locale.getDefault();
- Locale.setDefault(Locale.US);
- }
-
- protected void tearDown() {
- Locale.setDefault(defaultLocale);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/CollectionsTest.java b/luni/src/test/java/tests/api/java/util/CollectionsTest.java
deleted file mode 100644
index c308cf9..0000000
--- a/luni/src/test/java/tests/api/java/util/CollectionsTest.java
+++ /dev/null
@@ -1,2226 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Random;
-import java.util.RandomAccess;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.Arrays;
-
-import tests.support.Support_CollectionTest;
-import tests.support.Support_ListTest;
-import tests.support.Support_SetTest;
-import tests.support.Support_UnmodifiableCollectionTest;
-import tests.support.Support_UnmodifiableMapTest;
-
-public class CollectionsTest extends junit.framework.TestCase {
-
- private LinkedList ll;
-
- private LinkedList myll;
-
- private LinkedList reversedLinkedList;
-
- private LinkedList myReversedLinkedList;
-
- private Set s;
-
- private Set mys;
-
- private HashMap hm;
-
- private Object[] objArray;
-
- private Object[] myobjArray;
-
- public static class ReversedMyIntComparator implements Comparator {
- public int compare(Object o1, Object o2) {
- return -((MyInt) o1).compareTo((MyInt) o2);
- }
-
- public int equals(Object o1, Object o2) {
- return ((MyInt) o1).compareTo((MyInt) o2);
- }
- }
-
- public static class SynchCollectionChecker implements Runnable {
- Collection col;
-
- int colSize;
-
- int totalToRun;
-
- boolean offset;
-
- volatile int numberOfChecks = 0;
-
- boolean result = true;
-
- ArrayList normalCountingList;
-
- ArrayList offsetCountingList;
-
- public void run() {
- // ensure the list either contains the numbers from 0 to size-1 or
- // the numbers from size to 2*size -1
- while (numberOfChecks < totalToRun) {
- synchronized (col) {
- if (!(col.isEmpty() || col.containsAll(normalCountingList) || col
- .containsAll(offsetCountingList)))
- result = false;
- col.clear();
- }
- if (offset)
- col.addAll(offsetCountingList);
- else
- col.addAll(normalCountingList);
- numberOfChecks++;
- }
- }
-
- public SynchCollectionChecker(Collection c, boolean offset,
- int totalChecks) {
- // The collection to test, whether to offset the filler values by
- // size or not, and the min number of iterations to run
- totalToRun = totalChecks;
- col = c;
- colSize = c.size();
- normalCountingList = new ArrayList(colSize);
- offsetCountingList = new ArrayList(colSize);
- for (int counter = 0; counter < colSize; counter++)
- normalCountingList.add(new Integer(counter));
- for (int counter = 0; counter < colSize; counter++)
- offsetCountingList.add(new Integer(counter + colSize));
- col.clear();
- if (offset)
- col.addAll(offsetCountingList);
- else
- col.addAll(normalCountingList);
- }
-
- public boolean offset() {
- // answer true iff the list is filled with a counting sequence
- // starting at the value size to 2*size - 1
- // else the list with be filled starting at 0 to size - 1
- return offset;
- }
-
- public boolean getResult() {
- // answer true iff no corruption has been found in the collection
- return result;
- }
-
- public int getNumberOfChecks() {
- // answer the number of checks that have been performed on the list
- return numberOfChecks;
- }
- }
-
- public static class SynchMapChecker implements Runnable {
- Map map;
-
- int mapSize;
-
- int totalToRun;
-
- boolean offset;
-
- volatile int numberOfChecks = 0;
-
- boolean result = true;
-
- Map normalCountingMap;
-
- Map offsetCountingMap;
-
- public void run() {
- Object firstNormalValue = normalCountingMap.get(new Integer(0));
- Object lastNormalValue = normalCountingMap.get(new Integer(
- mapSize - 1));
- Object firstOffsetValue = offsetCountingMap
- .get(new Integer(mapSize));
- Object lastOffsetValue = offsetCountingMap.get(new Integer(
- 2 * mapSize - 1));
- // ensure the list either contains the numbers from 0 to size-1 or
- // the numbers from size to 2*size -1
- while (numberOfChecks < totalToRun) {
- synchronized (map) {
- if (!(map.isEmpty()
- || (map.containsValue(firstNormalValue) && map
- .containsValue(lastNormalValue)) || (map
- .containsValue(firstOffsetValue) && map
- .containsValue(lastOffsetValue))))
- result = false;
- map.clear();
- }
- if (offset)
- map.putAll(offsetCountingMap);
- else
- map.putAll(normalCountingMap);
- numberOfChecks++;
- }
- }
-
- public SynchMapChecker(Map m, boolean offset, int totalChecks) {
- // The collection to test, whether to offset the filler values by
- // size or not, and the min number of iterations to run
- Integer myInt;
- totalToRun = totalChecks;
- map = m;
- mapSize = m.size();
- normalCountingMap = new HashMap(mapSize);
- offsetCountingMap = new HashMap(mapSize);
- for (int counter = 0; counter < mapSize; counter++) {
- myInt = new Integer(counter);
- normalCountingMap.put(myInt, myInt);
- }
- for (int counter = 0; counter < mapSize; counter++) {
- myInt = new Integer(counter + mapSize);
- offsetCountingMap.put(myInt, myInt);
- }
- map.clear();
- if (offset)
- map.putAll(offsetCountingMap);
- else
- map.putAll(normalCountingMap);
- }
-
- public boolean offset() {
- // answer true iff the list is filled with a counting sequence
- // starting at the value size to 2*size - 1
- // else the list with be filled starting at 0 to size - 1
- return offset;
- }
-
- public boolean getResult() {
- // answer true iff no corruption has been found in the collection
- return result;
- }
-
- public int getNumberOfChecks() {
- // answer the number of checks that have been performed on the list
- return numberOfChecks;
- }
- }
-
- public static class CollectionTest extends junit.framework.TestCase {
-
- Collection col; // must contain the Integers 0 to 99
-
- public CollectionTest(String p1) {
- super(p1);
- }
-
- public CollectionTest(String p1, Collection c) {
- super(p1);
- col = c;
- }
-
- }
-
- static class MyInt {
- int data;
-
- public MyInt(int value) {
- data = value;
- }
-
- public int compareTo(MyInt object) {
- return data > object.data ? 1 : (data < object.data ? -1 : 0);
- }
- }
-
- /**
- * java.util.Collections#binarySearch(java.util.List,
- * java.lang.Object)
- */
- public void test_binarySearchLjava_util_ListLjava_lang_Object() {
- // Test for method int
- // java.util.Collections.binarySearch(java.util.List, java.lang.Object)
- // assumes ll is sorted and has no duplicate keys
- final int llSize = ll.size();
- // Ensure a NPE is thrown if the list is NULL
- try {
- Collections.binarySearch(null, new Object());
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
- for (int counter = 0; counter < llSize; counter++) {
- assertTrue("Returned incorrect binary search item position", ll
- .get(Collections.binarySearch(ll, ll.get(counter))) == ll
- .get(counter));
- }
- }
-
- /**
- * java.util.Collections#binarySearch(java.util.List,
- * java.lang.Object, java.util.Comparator)
- */
- public void test_binarySearchLjava_util_ListLjava_lang_ObjectLjava_util_Comparator() {
- // Test for method int
- // java.util.Collections.binarySearch(java.util.List, java.lang.Object,
- // java.util.Comparator)
- // assumes reversedLinkedList is sorted in reversed order and has no
- // duplicate keys
- final int rSize = myReversedLinkedList.size();
- ReversedMyIntComparator comp = new ReversedMyIntComparator();
- // Ensure a NPE is thrown if the list is NULL
- try {
- Collections.binarySearch(null, new Object(), comp);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
- for (int counter = 0; counter < rSize; counter++) {
- assertTrue(
- "Returned incorrect binary search item position using custom comparator",
- myReversedLinkedList.get(Collections.binarySearch(
- myReversedLinkedList, myReversedLinkedList
- .get(counter), comp)) == myReversedLinkedList
- .get(counter));
- }
- }
-
- class Mock_ArrayList extends ArrayList {
- @Override
- public
- Object set (int index, Object o){
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * java.util.Collections#copy(java.util.List, java.util.List)
- */
- public void test_copyLjava_util_ListLjava_util_List() {
- // Test for method void java.util.Collections.copy(java.util.List,
- // java.util.List)
- // Ensure a NPE is thrown if the list is NULL
- try {
- Collections.copy(null, ll);
- fail("Expected NullPointerException for null list first parameter");
- } catch (NullPointerException e) {
- }
- try {
- Collections.copy(ll, null);
- fail("Expected NullPointerException for null list second parameter");
- } catch (NullPointerException e) {
- }
- final int llSize = ll.size();
- ll.set(25, null);
- ArrayList al = new ArrayList();
- Integer extraElement = new Integer(1);
- Integer extraElement2 = new Integer(2);
- al.addAll(myReversedLinkedList);
- al.add(extraElement);
- al.add(extraElement2);
- Collections.copy(al, ll);
- for (int counter = 0; counter < llSize; counter++) {
- assertTrue("Elements do not match after copying collection", al
- .get(counter) == ll.get(counter));
- }
- assertTrue("Elements after copied elements affected by copy",
- extraElement == al.get(llSize)
- && extraElement2 == al.get(llSize + 1));
-
- ArrayList ar1 = new ArrayList();
- ArrayList ar2 = new ArrayList();
-
- int i;
-
- for(i = 0; i < 5; i ++) {
- ar2.add(new Integer(i));
- }
-
- for(i = 0; i < 10; i ++) {
- ar1.add(new Integer(i));
- }
-
- try {
- Collections.copy(ar2, ar1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- Mock_ArrayList mal1 = new Mock_ArrayList();
- Mock_ArrayList mal2 = new Mock_ArrayList();
-
- for(i = 0; i < 10; i ++) {
- mal1.add(new Integer(i));
- mal2.add(new Integer(10 - i));
- }
-
- try {
- Collections.copy(mal1, mal2);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#copy(java.util.List, java.util.List)
- */
- public void test_copy_check_index() {
- ArrayList a1 = new ArrayList();
- a1.add("one");
- a1.add("two");
-
- ArrayList a2 = new ArrayList();
- a2.add("aa");
-
- try {
- Collections.copy(a2, a1);
- fail("Expected IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException e) {
- }
-
- assertEquals("aa", a2.get(0));
- }
-
- /**
- * java.util.Collections#enumeration(java.util.Collection)
- */
- public void test_enumerationLjava_util_Collection() {
- // Test for method java.util.Enumeration
- // java.util.Collections.enumeration(java.util.Collection)
- TreeSet ts = new TreeSet();
- ts.addAll(s);
- Enumeration e = Collections.enumeration(ts);
- int count = 0;
- while (e.hasMoreElements())
- assertTrue("Returned incorrect enumeration",
- e.nextElement() == objArray[count++]);
- assertTrue("Enumeration missing elements: " + count,
- count == objArray.length);
- }
-
- /**
- * java.util.Collections#fill(java.util.List, java.lang.Object)
- */
- public void test_fillLjava_util_ListLjava_lang_Object() {
- // Test for method void java.util.Collections.fill(java.util.List,
- // java.lang.Object)
- try {
- Collections.fill(null, new Object());
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
- final int size = ll.size();
- Collections.fill(ll, "k");
- assertTrue("Fill modified list size", size == ll.size());
- Iterator i = ll.iterator();
- while (i.hasNext())
- assertEquals("Failed to fill elements", "k", i.next());
-
- Collections.fill(ll, null);
- assertTrue("Fill with nulls modified list size", size == ll.size());
- i = ll.iterator();
- while (i.hasNext())
- assertNull("Failed to fill with nulls", i.next());
-
- Mock_ArrayList mal = new Mock_ArrayList();
-
- mal.add("one");
- mal.add("two");
-
- try {
- Collections.fill(mal, "value");
- fail("UnsupportedOperationException ecpected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#max(java.util.Collection)
- */
- public void test_maxLjava_util_Collection() {
- // Test for method java.lang.Object
- // java.util.Collections.max(java.util.Collection)
- // assumes s, objArray are sorted
- assertTrue("Returned incorrect max element",
- Collections.max(s) == objArray[objArray.length - 1]);
-
- ArrayList al = new ArrayList();
-
- try {
- Collections.max(al);
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
-
- al.add("String");
- al.add(new Integer(1));
- al.add(new Double(3.14));
-
- try {
- Collections.max(al);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#max(java.util.Collection,
- * java.util.Comparator)
- */
- public void test_maxLjava_util_CollectionLjava_util_Comparator() {
- // Test for method java.lang.Object
- // java.util.Collections.max(java.util.Collection, java.util.Comparator)
- // assumes s, objArray are sorted
-
- // With this custom (backwards) comparator the 'max' element should be
- // the smallest in the list
- ReversedMyIntComparator rmic = new ReversedMyIntComparator();
- assertTrue(
- "Returned incorrect max element using custom comparator",
- Collections.max(mys, rmic) == myobjArray[0]);
-
- ArrayList al = new ArrayList();
-
- try {
- Collections.max(al, rmic);
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
-
- al.add("String");
- al.add(new Integer(1));
- al.add(new Double(3.14));
-
- try {
- Collections.max(al, rmic);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#min(java.util.Collection)
- */
- public void test_minLjava_util_Collection() {
- // Test for method java.lang.Object
- // java.util.Collections.min(java.util.Collection)
- // assumes s, objArray are sorted
- assertTrue("Returned incorrect min element",
- Collections.min(s) == objArray[0]);
- ArrayList al = new ArrayList();
-
- try {
- Collections.min(al);
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
-
- al.add("String");
- al.add(new Integer(1));
- al.add(new Double(3.14));
-
- try {
- Collections.min(al);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#min(java.util.Collection,
- * java.util.Comparator)
- */
- public void test_minLjava_util_CollectionLjava_util_Comparator() {
- // Test for method java.lang.Object
- // java.util.Collections.min(java.util.Collection, java.util.Comparator)
- // assumes s, objArray are sorted
-
- // With this custom (backwards) comparator the 'min' element should be
- // the largest in the list
- ReversedMyIntComparator rmic = new ReversedMyIntComparator();
-
- assertTrue(
- "Returned incorrect min element using custom comparator",
- Collections.min(mys, rmic) == myobjArray[objArray.length - 1]);
-
- ArrayList al = new ArrayList();
-
- try {
- Collections.min(al, rmic);
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
-
- al.add("String");
- al.add(new Integer(1));
- al.add(new Double(3.14));
-
- try {
- Collections.min(al, rmic);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#nCopies(int, java.lang.Object)
- */
- public void test_nCopiesILjava_lang_Object() {
- // Test for method java.util.List java.util.Collections.nCopies(int,
- // java.lang.Object)
- Object o = new Object();
- List l = Collections.nCopies(100, o);
- Iterator i = l.iterator();
- Object first = i.next();
- assertTrue("Returned list consists of copies not refs", first == o);
- assertEquals("Returned list of incorrect size", 100, l.size());
- assertTrue("Contains", l.contains(o));
- assertTrue("Contains null", !l.contains(null));
- assertTrue("null nCopies contains", !Collections.nCopies(2, null)
- .contains(o));
- assertTrue("null nCopies contains null", Collections.nCopies(2, null)
- .contains(null));
- l = Collections.nCopies(20, null);
- i = l.iterator();
- for (int counter = 0; i.hasNext(); counter++) {
- assertTrue("List is too large", counter < 20);
- assertNull("Element should be null: " + counter, i.next());
- }
- try {
- l.add(o);
- fail("Returned list is not immutable");
- } catch (UnsupportedOperationException e) {
- // Correct
- return;
- }
- try {
- Collections.nCopies(-2, new HashSet());
- fail("nCopies with negative arg didn't throw IAE");
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- /**
- * java.util.Collections#reverse(java.util.List)
- */
- public void test_reverseLjava_util_List() {
- // Test for method void java.util.Collections.reverse(java.util.List)
- try {
- Collections.reverse(null);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
- Collections.reverse(ll);
- Iterator i = ll.iterator();
- int count = objArray.length - 1;
- while (i.hasNext()) {
- assertTrue("Failed to reverse collection",
- i.next() == objArray[count]);
- --count;
- }
- ArrayList myList = new ArrayList();
- myList.add(null);
- myList.add(new Integer(20));
- Collections.reverse(myList);
- assertTrue("Did not reverse correctly--first element is: "
- + myList.get(0), myList.get(0).equals(new Integer(20)));
- assertNull("Did not reverse correctly--second element is: "
- + myList.get(1), myList.get(1));
-
- Mock_ArrayList mal = new Mock_ArrayList();
-
- mal.add("First");
- mal.add("Second");
-
- try {
- Collections.reverse(mal);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#reverseOrder()
- */
- public void test_reverseOrder() {
- // Test for method java.util.Comparator
- // java.util.Collections.reverseOrder()
- // assumes no duplicates in ll
- Comparator comp = Collections.reverseOrder();
- LinkedList list2 = new LinkedList(ll);
- Collections.sort(list2, comp);
- final int llSize = ll.size();
- for (int counter = 0; counter < llSize; counter++)
- assertTrue("New comparator does not reverse sorting order", ll
- .get(counter) == list2.get(llSize - counter - 1));
- }
-
- /**
- * java.util.Collections#shuffle(java.util.List)
- */
- public void test_shuffleLjava_util_List() {
- // Test for method void java.util.Collections.shuffle(java.util.List)
- // Assumes ll is sorted and has no duplicate keys and is large ( > 20
- // elements)
-
- // test shuffling a Sequential Access List
- try {
- Collections.shuffle(null);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
- ArrayList al = new ArrayList();
- al.addAll(ll);
- testShuffle(al, "Sequential Access", false);
-
- // test shuffling a Random Access List
- LinkedList ll2 = new LinkedList();
- ll2.addAll(ll);
- testShuffle(ll2, "Random Access", false);
- }
-
- public void testShuffleRandomAccessWithSeededRandom() {
- List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F", "G");
- Collections.shuffle(list, new Random(0));
- assertEquals(Arrays.asList("B", "A", "D", "C", "G", "E", "F"), list);
- }
-
- public void testShuffleWithSeededRandom() {
- List<String> list = new LinkedList<String>(Arrays.asList(
- "A", "B", "C", "D", "E", "F", "G"));
- Collections.shuffle(list, new Random(0));
- assertEquals(Arrays.asList("B", "A", "D", "C", "G", "E", "F"), list);
- }
-
- private void testShuffle(List list, String type, boolean random) {
- boolean sorted = true;
- boolean allMatch = true;
- int index = 0;
- final int size = list.size();
-
- if (random)
- Collections.shuffle(list);
- else
- Collections.shuffle(list, new Random(200));
-
- for (int counter = 0; counter < size - 1; counter++) {
- if (((Integer) list.get(counter)).compareTo((Integer)list.get(counter + 1)) > 0) {
- sorted = false;
- }
- }
- assertFalse("Shuffling sorted " + type
- + " list resulted in sorted list (should be unlikely)", sorted);
- for (int counter = 0; counter < 20; counter++) {
- index = 30031 * counter % (size + 1); // 30031 is a large prime
- if (list.get(index) != ll.get(index))
- allMatch = false;
- }
- assertFalse("Too many element positions match in shuffled " + type
- + " list", allMatch);
- }
-
- /**
- * java.util.Collections#shuffle(java.util.List, java.util.Random)
- */
- public void test_shuffleLjava_util_ListLjava_util_Random() {
- // Test for method void java.util.Collections.shuffle(java.util.List,
- // java.util.Random)
- // Assumes ll is sorted and has no duplicate keys and is large ( > 20
- // elements)
-
- // test shuffling a Sequential Access List
- try {
- Collections.shuffle(null, new Random(200));
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
- ArrayList al = new ArrayList();
- al.addAll(ll);
- testShuffle(al, "Sequential Access", true);
-
- // test shuffling a Random Access List
- LinkedList ll2 = new LinkedList();
- ll2.addAll(ll);
- testShuffle(ll2, "Random Access", true);
-
-
- Mock_ArrayList mal = new Mock_ArrayList();
-
- mal.add("First");
- mal.add("Second");
-
- try {
- Collections.shuffle(mal, new Random(200));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
-}
-
- /**
- * java.util.Collections#singleton(java.lang.Object)
- */
- public void test_singletonLjava_lang_Object() {
- // Test for method java.util.Set
- // java.util.Collections.singleton(java.lang.Object)
- Object o = new Object();
- Set single = Collections.singleton(o);
- assertEquals("Wrong size", 1, single.size());
- assertTrue("Contains", single.contains(o));
- assertTrue("Contains null", !single.contains(null));
- assertTrue("null nCopies contains", !Collections.singleton(null)
- .contains(o));
- assertTrue("null nCopies contains null", Collections.singleton(null)
- .contains(null));
- try {
- single.add("l");
- } catch (UnsupportedOperationException e) {
- // Correct
- return;
- }
- fail("Allowed modification of singleton");
- }
-
- /**
- * java.util.Collections#sort(java.util.List)
- */
- public void test_sortLjava_util_List() {
- // Test for method void java.util.Collections.sort(java.util.List)
- // assumes no duplicate keys in ll
- final int llSize = ll.size();
- final int rllSize = reversedLinkedList.size();
- try {
- Collections.sort((List)null);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
- Collections.shuffle(ll);
- Collections.sort(ll);
- Collections.sort(reversedLinkedList);
- for (int counter = 0; counter < llSize - 1; counter++) {
- assertTrue(
- "Sorting shuffled list resulted in unsorted list",
- ((Integer) ll.get(counter)).compareTo((Integer)ll.get(counter + 1)) < 0);
- }
-
- for (int counter = 0; counter < rllSize - 1; counter++) {
- assertTrue("Sorting reversed list resulted in unsorted list",
- ((Integer) reversedLinkedList.get(counter))
- .compareTo((Integer)reversedLinkedList.get(counter + 1)) < 0);
- }
-
- ArrayList al = new ArrayList();
-
- al.add("String");
- al.add(new Integer(1));
- al.add(new Double(3.14));
-
- try {
- Collections.sort(al);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
-
- Mock_ArrayList mal = new Mock_ArrayList();
-
- mal.add("First");
- mal.add("Second");
-
- try {
- Collections.sort(mal);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#sort(java.util.List, java.util.Comparator)
- */
- public void test_sortLjava_util_ListLjava_util_Comparator() {
- // Test for method void java.util.Collections.sort(java.util.List,
- // java.util.Comparator)
- Comparator comp = new ReversedMyIntComparator();
- try {
- Collections.sort(null, comp);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
- Collections.shuffle(myll);
- Collections.sort(myll, comp);
- final int llSize = myll.size();
-
- for (int counter = 0; counter < llSize - 1; counter++) {
- assertTrue(
- "Sorting shuffled list with custom comparator resulted in unsorted list",
- ((MyInt) myll.get(counter)).compareTo((MyInt) myll
- .get(counter + 1)) >= 0);
- }
-
- ArrayList al = new ArrayList();
-
- al.add("String");
- al.add(new Integer(1));
- al.add(new Double(3.14));
-
- try {
- Collections.sort(al, comp);
- fail("ClassCastException expected");
- } catch (ClassCastException e) {
- //expected
- }
-
- Mock_ArrayList mal = new Mock_ArrayList();
-
- mal.add(new MyInt(1));
- mal.add(new MyInt(2));
-
- try {
- Collections.sort(mal, comp);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#swap(java.util.List, int, int)
- */
- public void test_swapLjava_util_ListII() {
- // Test for method swap(java.util.List, int, int)
-
- LinkedList smallList = new LinkedList();
- for (int i = 0; i < 10; i++) {
- smallList.add(objArray[i]);
- }
-
- // test exception cases
- try {
- Collections.swap(smallList, -1, 6);
- fail("Expected IndexOutOfBoundsException for -1");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- Collections.swap(smallList, 6, -1);
- fail("Expected IndexOutOfBoundsException for -1");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- Collections.swap(smallList, 6, 11);
- fail("Expected IndexOutOfBoundsException for 11");
- } catch (IndexOutOfBoundsException e) {
- }
-
- try {
- Collections.swap(smallList, 11, 6);
- fail("Expected IndexOutOfBoundsException for 11");
- } catch (IndexOutOfBoundsException e) {
- }
-
- // Ensure a NPE is thrown if the list is NULL
- try {
- Collections.swap(null, 1, 1);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
-
- // test with valid parameters
- Collections.swap(smallList, 4, 7);
- assertEquals("Didn't Swap the element at position 4 ", new Integer(7),
- smallList.get(4));
- assertEquals("Didn't Swap the element at position 7 ", new Integer(4),
- smallList.get(7));
-
- // make sure other elements didn't get swapped by mistake
- for (int i = 0; i < 10; i++) {
- if (i != 4 && i != 7)
- assertEquals("shouldn't have swapped the element at position "
- + i, new Integer(i), smallList.get(i));
- }
- }
-
- /**
- * java.util.Collections#replaceAll(java.util.List, java.lang.Object,
- * java.lang.Object)
- */
- public void test_replaceAllLjava_util_ListLjava_lang_ObjectLjava_lang_Object() {
- // Test for method replaceAll(java.util.List, java.lang.Object,
- // java.lang.Object)
-
- String string1 = "A-B-C-D-E-S-JF-SUB-G-H-I-J-SUBL-K-L-LIST-M-N--S-S-O-SUBLIS-P-Q-R-SUBLIST-S-T-U-V-W-X-Y-Z";
- char[] chars = string1.toCharArray();
- List list = new ArrayList();
- for (int i = 0; i < chars.length; i++) {
- list.add(new Character(chars[i]));
- }
-
- try {
- Collections.replaceAll(null, new Object(), new Object());
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
-
- // test replace for an element that is not in the list
- boolean result = Collections.replaceAll(list, new Character('1'),
- new Character('Z'));
- assertFalse("Test1: Collections.replaceAll() returned wrong result",
- result);
- assertEquals("Test2 : ReplaceAll modified the list incorrectly",
- string1, getString(list));
-
- // test replace for an element that is in the list
- result = Collections.replaceAll(list, new Character('S'),
- new Character('K'));
- assertTrue("Test3: Collections.replaceAll() returned wrong result",
- result);
- assertEquals("Test4: ReplaceAll modified the list incorrectly",
- (string1 = string1.replace('S', 'K')), getString(list));
-
- // test replace for the last element in the list
- result = Collections.replaceAll(list, new Character('Z'),
- new Character('N'));
- assertTrue("Test5: Collections.replaceAll() returned wrong result",
- result);
- assertEquals("Test6: ReplaceAll modified the list incorrectly",
- (string1 = string1.replace('Z', 'N')), getString(list));
-
- // test replace for the first element in the list
- result = Collections.replaceAll(list, new Character('A'),
- new Character('B'));
- assertTrue("Test7: Collections.replaceAll() returned wrong result",
- result);
- assertEquals("Test8: ReplaceAll modified the list incorrectly",
- (string1 = string1.replace('A', 'B')), getString(list));
-
- // test replacing elements with null
- LinkedList smallList = new LinkedList();
- for (int i = 0; i < 10; i++) {
- smallList.add(objArray[i]);
- }
- smallList.set(4, new Integer(5));
- result = Collections.replaceAll(smallList, new Integer(5), null);
- assertTrue("Test9: Collections.replaceAll() returned wrong result",
- result);
- for (int i = 0; i < smallList.size(); i++) {
- if (i == 4 || i == 5)
- assertSame("Test9: ReplaceAll didn't replace element at " + i,
- null, smallList.get(i));
- else
- assertEquals(
- "Test9: ReplaceAll shouldn't have replaced element at "
- + i, new Integer(i), smallList.get(i));
- }
-
- // test replacing null elements with another value
- result = Collections.replaceAll(smallList, null, new Integer(99));
- assertTrue("Test10: Collections.replaceAll() returned wrong result",
- result);
-
- for (int i = 0; i < smallList.size(); i++) {
- if (i == 4 || i == 5)
- assertEquals("Test10: ReplaceAll didn't replace element at "
- + i, new Integer(99), smallList.get(i));
- else
- assertEquals(
- "Test10: ReplaceAll shouldn't have replaced element at "
- + i, new Integer(i), smallList.get(i));
- }
-
- Mock_ArrayList mal = new Mock_ArrayList();
-
- mal.add("First");
- mal.add("Second");
-
- try {
- Collections.replaceAll(mal, "Second", null);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /**
- * java.util.Collections#rotate(java.util.List, int)
- */
- public void test_rotateLjava_util_ListI() {
- // Test for method rotate(java.util.List, int)
-
- try {
- Collections.rotate(null, 0);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
-
- // Test rotating a Sequential Access List
- LinkedList list1 = new LinkedList();
- for (int i = 0; i < 10; i++) {
- list1.add(objArray[i]);
- }
- testRotate(list1, "Sequential Access");
-
- // Test rotating a Random Access List
- ArrayList list2 = new ArrayList();
- for (int i = 0; i < 10; i++) {
- list2.add(objArray[i]);
- }
- testRotate(list2, "Random Access");
- }
-
- private void testRotate(List list, String type) {
- // rotate with positive distance
- Collections.rotate(list, 7);
- assertEquals("Test1: rotate modified the " + type
- + " list incorrectly,", "3456789012", getString(list));
-
- // rotate with negative distance
- Collections.rotate(list, -2);
- assertEquals("Test2: rotate modified the " + type
- + " list incorrectly,", "5678901234", getString(list));
-
- // rotate sublist with negative distance
- List subList = list.subList(1, 5);
- Collections.rotate(subList, -1);
- assertEquals("Test3: rotate modified the " + type
- + " list incorrectly,", "5789601234", getString(list));
-
- // rotate sublist with positive distance
- Collections.rotate(subList, 2);
- assertEquals("Test4: rotate modified the " + type
- + " list incorrectly,", "5967801234", getString(list));
-
- // rotate with positive distance that is larger than list size
- Collections.rotate(list, 23);
- assertEquals("Test5: rotate modified the " + type
- + " list incorrectly,", "2345967801", getString(list));
-
- // rotate with negative distance that is larger than list size
- Collections.rotate(list, -23);
- assertEquals("Test6: rotate modified the " + type
- + " list incorrectly,", "5967801234", getString(list));
-
- // rotate with 0 and equivalent distances, this should make no
- // modifications to the list
- Collections.rotate(list, 0);
- assertEquals("Test7: rotate modified the " + type
- + " list incorrectly,", "5967801234", getString(list));
-
- Collections.rotate(list, -30);
- assertEquals("Test8: rotate modified the " + type
- + " list incorrectly,", "5967801234", getString(list));
-
- Collections.rotate(list, 30);
- assertEquals("Test9: rotate modified the " + type
- + " list incorrectly,", "5967801234", getString(list));
- }
-
- private String getString(List list) {
- StringBuffer buffer = new StringBuffer();
- for (int i = 0; i < list.size(); i++) {
- buffer.append(list.get(i));
- }
- return buffer.toString();
- }
-
- /**
- * java.util.Collections#rotate(java.util.List, int)
- */
- public void test_rotate2() {
- List list = new ArrayList();
- try {
- Collections.rotate(list, 5);
- } catch (UnsupportedOperationException e) {
- fail("Unexpected UnsupportedOperationException for empty list, "
- + e);
- }
-
- list.add(0, "zero");
- list.add(1, "one");
- list.add(2, "two");
- list.add(3, "three");
- list.add(4, "four");
-
- Collections.rotate(list, Integer.MIN_VALUE);
- assertEquals("Rotated incorrectly at position 0, ", "three",
- (String) list.get(0));
- assertEquals("Rotated incorrectly at position 1, ", "four",
- (String) list.get(1));
- assertEquals("Rotated incorrectly at position 2, ", "zero",
- (String) list.get(2));
- assertEquals("Rotated incorrectly at position 3, ", "one",
- (String) list.get(3));
- assertEquals("Rotated incorrectly at position 4, ", "two",
- (String) list.get(4));
- }
-
- /**
- * java.util.Collections#indexOfSubList(java.util.List,
- * java.util.List)
- */
- public void test_indexOfSubListLjava_util_ListLjava_util_List() {
- // Test for method int indexOfSubList(java.util.List, java.util.List)
- List list = new ArrayList();
- try {
- Collections.indexOfSubList(null, list);
- fail("Expected NullPointerException for null list first parameter");
- } catch (NullPointerException e) {
- }
- try {
- Collections.indexOfSubList(list, null);
- fail("Expected NullPointerException for null list second parameter");
- } catch (NullPointerException e) {
- }
-
- String string1 = "A-B-C-D-E-S-JF-SUB-G-H-I-J-SUBL-K-L-LIST-M-N--S-S-O-SUBLIS-P-Q-R-SUBLIST-S-T-U-V-W-X-Y-Z";
-
- testwithCharList(1, string1, "B", true);
- testwithCharList(2, string1, "LIST", true);
- testwithCharList(3, string1, "SUBLIST", true);
- testwithCharList(4, string1, "NONE", true);
- testwithCharList(5, string1, "END", true);
-
- // test boundary conditions:
- testwithCharList(6, "", "", true);
- testwithCharList(7, "LIST", "", true);
- testwithCharList(8, "", "SUBLIST", true);
- }
-
- /**
- * java.util.Collections#indexOfSubList(java.util.List,
- * java.util.List)
- */
- public void test_indexOfSubList2() {
- ArrayList sub = new ArrayList();
- sub.add(new Integer(1));
- sub.add(new Integer(2));
- sub.add(new Integer(3));
-
- ArrayList sub2 = new ArrayList();
- sub2.add(new Integer(7));
- sub2.add(new Integer(8));
-
- ArrayList src = new ArrayList();
- src.addAll(sub);
- src.addAll(sub);
- src.addAll(sub);
- src.add(new Integer(5));
- src.add(new Integer(6));
-
- // so src becomes a list like this:
- // [1, 2, 3, 1, 2, 3, 1, 2, 3, 5, 6]
-
- sub = new ArrayList(src.subList(3, 11));
- // [1, 2, 3, 1, 2, 3, 5, 6]
- assertEquals("TestA : Returned wrong indexOfSubList, ", 3, Collections
- .indexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(6, 11));
- // [1, 2, 3, 5, 6]
- assertEquals("TestB : Returned wrong indexOfSubList, ", 6, Collections
- .indexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(0, 3));
- // [1, 2, 3]
- assertEquals("TestCC : Returned wrong indexOfSubList, ", 0, Collections
- .indexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(9, 11));
- // [5, 6]
- assertEquals("TestD : Returned wrong indexOfSubList, ", 9, Collections
- .indexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(10, 11));
- // [6]
- assertEquals("TestE : Returned wrong indexOfSubList, ", 10, Collections
- .indexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(0, 11));
- // the whole list
- assertEquals("TestH : Returned wrong indexIndexOfSubList, ", 0,
- Collections.indexOfSubList(src, sub));
-
- // a non-matching list
- assertEquals("TestI : Returned wrong indexOfSubList, ", -1, Collections
- .indexOfSubList(src, sub2));
- }
-
-
- private void testwithCharList(int count, String string1, String string2,
- boolean first) {
- char[] chars = string1.toCharArray();
- List list = new ArrayList();
- for (int i = 0; i < chars.length; i++) {
- list.add(new Character(chars[i]));
- }
- chars = string2.toCharArray();
- List sublist = new ArrayList();
- for (int i = 0; i < chars.length; i++) {
- sublist.add(new Character(chars[i]));
- }
-
- if (first)
- assertEquals("Test " + count + ": Returned wrong index:", string1
- .indexOf(string2), Collections
- .indexOfSubList(list, sublist));
- else
- assertEquals("Test " + count + ": Returned wrong index:", string1
- .lastIndexOf(string2), Collections.lastIndexOfSubList(list,
- sublist));
- }
-
- /**
- * java.util.Collections#lastIndexOfSubList(java.util.List,
- * java.util.List)
- */
- public void test_lastIndexOfSubListLjava_util_ListLjava_util_List() {
- // Test for method int lastIndexOfSubList(java.util.List,
- // java.util.List)
- String string1 = "A-B-C-D-E-S-JF-SUB-G-H-I-J-SUBL-K-L-LIST-M-N--S-S-O-SUBLIS-P-Q-R-SUBLIST-S-T-U-V-W-X-Y-Z-END";
-
- List list = new ArrayList();
- try {
- Collections.lastIndexOfSubList(null, list);
- fail("Expected NullPointerException for null list first parameter");
- } catch (NullPointerException e) {
- }
- try {
- Collections.lastIndexOfSubList(list, null);
- fail("Expected NullPointerException for null list second parameter");
- } catch (NullPointerException e) {
- }
-
- testwithCharList(1, string1, "B", false);
- testwithCharList(2, string1, "LIST", false);
- testwithCharList(3, string1, "SUBLIST", false);
- testwithCharList(4, string1, "END", false);
- testwithCharList(5, string1, "NONE", false);
-
- // test boundary conditions
- testwithCharList(6, "", "", false);
- testwithCharList(7, "LIST", "", false);
- testwithCharList(8, "", "SUBLIST", false);
- }
-
- /**
- * java.util.Collections#lastIndexOfSubList(java.util.List,
- * java.util.List)
- */
- public void test_lastIndexOfSubList2() {
- ArrayList sub = new ArrayList();
- sub.add(new Integer(1));
- sub.add(new Integer(2));
- sub.add(new Integer(3));
-
- ArrayList sub2 = new ArrayList();
- sub2.add(new Integer(7));
- sub2.add(new Integer(8));
-
- ArrayList src = new ArrayList();
- src.addAll(sub);
- src.addAll(sub);
- src.addAll(sub);
- src.add(new Integer(5));
- src.add(new Integer(6));
-
- // so src is a list like this:
- // [1, 2, 3, 1, 2, 3, 1, 2, 3, 5, 6]
-
- Collections.reverse(src);
- // it becomes like this :
- // [6, 5, 3, 2, 1, 3, 2, 1, 3, 2, 1]
-
- sub = new ArrayList(src.subList(0, 8));
- // [6, 5, 3, 2, 1, 3, 2, 1]
- assertEquals("TestA : Returned wrong lastIndexOfSubList, ", 0,
- Collections.lastIndexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(0, 5));
- // [6, 5, 3, 2, 1]
- assertEquals("TestB : Returned wrong lastIndexOfSubList, ", 0,
- Collections.lastIndexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(2, 5));
- // [3, 2, 1]
- assertEquals("TestC : Returned wrong lastIndexOfSubList, ", 8,
- Collections.lastIndexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(9, 11));
- // [2, 1]
- assertEquals("TestD : Returned wrong lastIndexOfSubList, ", 9,
- Collections.lastIndexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(10, 11));
- // [1]
- assertEquals("TestE : Returned wrong lastIndexOfSubList, ", 10,
- Collections.lastIndexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(0, 2));
- // [6, 5]
- assertEquals("TestF : Returned wrong lastIndexOfSubList, ", 0,
- Collections.lastIndexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(0, 1));
- // [6]
- assertEquals("TestG : Returned wrong lastIndexOfSubList, ", 0,
- Collections.lastIndexOfSubList(src, sub));
-
- sub = new ArrayList(src.subList(0, 11));
- // the whole list
- assertEquals("TestH : Returned wrong lastIndexOfSubList, ", 0,
- Collections.lastIndexOfSubList(src, sub));
-
- // a non-matching list
- assertEquals("TestI : Returned wrong lastIndexOfSubList, ", -1,
- Collections.lastIndexOfSubList(src, sub2));
- }
-
- /**
- * java.util.Collections#list(java.util.Enumeration)
- */
- public void test_listLjava_util_Enumeration() {
- // Test for method java.util.ArrayList list(java.util.Enumeration)
-
- Enumeration e = Collections.enumeration(ll);
- ArrayList al = Collections.list(e);
-
- int size = al.size();
- assertEquals("Wrong size", ll.size(), size);
-
- for (int i = 0; i < size; i++) {
- assertEquals("wrong element at position " + i + ",", ll.get(i), al
- .get(i));
- }
- }
-
- /**
- * java.util.Collections#synchronizedCollection(java.util.Collection)
- */
- public void test_synchronizedCollectionLjava_util_Collection() {
- // Test for method java.util.Collection
- // java.util.Collections.synchronizedCollection(java.util.Collection)
-
- LinkedList smallList = new LinkedList();
- for (int i = 0; i < 50; i++) {
- smallList.add(objArray[i]);
- }
-
- final int numberOfLoops = 200;
- Collection synchCol = Collections.synchronizedCollection(smallList);
- // Replacing the previous line with the line below *should* cause the
- // test to fail--the collecion below isn't synchronized
- // Collection synchCol = smallList;
-
- SynchCollectionChecker normalSynchChecker = new SynchCollectionChecker(
- synchCol, false, numberOfLoops);
- SynchCollectionChecker offsetSynchChecker = new SynchCollectionChecker(
- synchCol, true, numberOfLoops);
- Thread normalThread = new Thread(normalSynchChecker);
- Thread offsetThread = new Thread(offsetSynchChecker);
- normalThread.start();
- offsetThread.start();
- while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
- || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- assertTrue("Returned collection corrupted by multiple thread access",
- normalSynchChecker.getResult()
- && offsetSynchChecker.getResult());
- try {
- normalThread.join(5000);
- offsetThread.join(5000);
- } catch (InterruptedException e) {
- fail("join() interrupted");
- }
-
- synchCol.add(null);
- assertTrue("Trying to use nulls in collection failed", synchCol
- .contains(null));
-
- smallList = new LinkedList();
- for (int i = 0; i < 100; i++) {
- smallList.add(objArray[i]);
- }
- new Support_CollectionTest("", Collections
- .synchronizedCollection(smallList)).runTest();
- }
-
- /**
- * java.util.Collections#synchronizedList(java.util.List)
- */
- public void test_synchronizedListLjava_util_List() {
- try {
- Collections.synchronizedList(null);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
-
- // test with a Sequential Access List
- List smallList = new LinkedList();
- testSynchronizedList(smallList, "Sequential Access");
-
- smallList = new LinkedList();
- List myList;
- for (int i = 0; i < 100; i++) {
- smallList.add(objArray[i]);
- }
- myList = Collections.synchronizedList(smallList);
- new Support_ListTest("", myList).runTest();
-
- // test with a Random Access List
- smallList = new ArrayList();
- testSynchronizedList(smallList, "Random Access");
-
- smallList = new ArrayList();
- for (int i = 0; i < 100; i++) {
- smallList.add(objArray[i]);
- }
- myList = Collections.synchronizedList(smallList);
- new Support_ListTest("", myList).runTest();
- }
-
- private void testSynchronizedList(List smallList, String type) {
- for (int i = 0; i < 50; i++) {
- smallList.add(objArray[i]);
- }
- final int numberOfLoops = 200;
- List synchList = Collections.synchronizedList(smallList);
- if (type.equals("Random Access"))
- assertTrue(
- "Returned synchronized list should implement the Random Access interface",
- synchList instanceof RandomAccess);
- else
- assertTrue(
- "Returned synchronized list should not implement the Random Access interface",
- !(synchList instanceof RandomAccess));
-
- // Replacing the previous line with the line below *should* cause the
- // test to fail--the list below isn't synchronized
- // List synchList = smallList;
- SynchCollectionChecker normalSynchChecker = new SynchCollectionChecker(
- synchList, false, numberOfLoops);
- SynchCollectionChecker offsetSynchChecker = new SynchCollectionChecker(
- synchList, true, numberOfLoops);
- Thread normalThread = new Thread(normalSynchChecker);
- Thread offsetThread = new Thread(offsetSynchChecker);
- normalThread.start();
- offsetThread.start();
- while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
- || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- assertTrue(
- type
- + " list tests: Returned list corrupted by multiple thread access",
- normalSynchChecker.getResult()
- && offsetSynchChecker.getResult());
- try {
- normalThread.join(5000);
- offsetThread.join(5000);
- } catch (InterruptedException e) {
- fail(type + " list tests: join() interrupted");
- }
- synchList.set(25, null);
- assertNull(type + " list tests: Trying to use nulls in list failed",
- synchList.get(25));
- }
-
- /**
- * java.util.Collections#synchronizedMap(java.util.Map)
- */
- public void test_synchronizedMapLjava_util_Map() {
- // Test for method java.util.Map
- // java.util.Collections.synchronizedMap(java.util.Map)
- HashMap smallMap = new HashMap();
- for (int i = 0; i < 50; i++) {
- smallMap.put(objArray[i], objArray[i]);
- }
-
- final int numberOfLoops = 200;
- Map synchMap = Collections.synchronizedMap(smallMap);
- // Replacing the previous line with the line below should cause the test
- // to fail--the list below isn't synchronized
- // Map synchMap = smallMap;
-
- SynchMapChecker normalSynchChecker = new SynchMapChecker(synchMap,
- false, numberOfLoops);
- SynchMapChecker offsetSynchChecker = new SynchMapChecker(synchMap,
- true, numberOfLoops);
- Thread normalThread = new Thread(normalSynchChecker);
- Thread offsetThread = new Thread(offsetSynchChecker);
- normalThread.start();
- offsetThread.start();
- while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
- || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- assertTrue("Returned map corrupted by multiple thread access",
- normalSynchChecker.getResult()
- && offsetSynchChecker.getResult());
- try {
- normalThread.join(5000);
- offsetThread.join(5000);
- } catch (InterruptedException e) {
- fail("join() interrupted");
- }
-
- // synchronized map does not have to permit null keys or values
- synchMap.put(new Long(25), null);
- synchMap.put(null, new Long(30));
- assertNull("Trying to use a null value in map failed", synchMap
- .get(new Long(25)));
- assertTrue("Trying to use a null key in map failed", synchMap.get(null)
- .equals(new Long(30)));
-
- smallMap = new HashMap();
- for (int i = 0; i < 100; i++) {
- smallMap.put(objArray[i].toString(), objArray[i]);
- }
- synchMap = Collections.synchronizedMap(smallMap);
- new Support_UnmodifiableMapTest("", synchMap).runTest();
- synchMap.keySet().remove(objArray[50].toString());
- assertNull(
- "Removing a key from the keySet of the synchronized map did not remove it from the synchronized map: ",
- synchMap.get(objArray[50].toString()));
- assertNull(
- "Removing a key from the keySet of the synchronized map did not remove it from the original map",
- smallMap.get(objArray[50].toString()));
- }
-
- /**
- * java.util.Collections#synchronizedSet(java.util.Set)
- */
- public void test_synchronizedSetLjava_util_Set() {
- // Test for method java.util.Set
- // java.util.Collections.synchronizedSet(java.util.Set)
- HashSet smallSet = new HashSet();
- for (int i = 0; i < 50; i++) {
- smallSet.add(objArray[i]);
- }
-
- final int numberOfLoops = 200;
- Set synchSet = Collections.synchronizedSet(smallSet);
- // Replacing the previous line with the line below should cause the test
- // to fail--the set below isn't synchronized
- // Set synchSet = smallSet;
-
- SynchCollectionChecker normalSynchChecker = new SynchCollectionChecker(
- synchSet, false, numberOfLoops);
- SynchCollectionChecker offsetSynchChecker = new SynchCollectionChecker(
- synchSet, true, numberOfLoops);
- Thread normalThread = new Thread(normalSynchChecker);
- Thread offsetThread = new Thread(offsetSynchChecker);
- normalThread.start();
- offsetThread.start();
- while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
- || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- assertTrue("Returned set corrupted by multiple thread access",
- normalSynchChecker.getResult()
- && offsetSynchChecker.getResult());
- try {
- normalThread.join(5000);
- offsetThread.join(5000);
- } catch (InterruptedException e) {
- fail("join() interrupted");
- }
-
- Set mySet = Collections.synchronizedSet(smallSet);
- mySet.add(null);
- assertTrue("Trying to use nulls in list failed", mySet.contains(null));
-
- smallSet = new HashSet();
- for (int i = 0; i < 100; i++) {
- smallSet.add(objArray[i]);
- }
- new Support_SetTest("", Collections.synchronizedSet(smallSet))
- .runTest();
- }
-
- /**
- * java.util.Collections#synchronizedSortedMap(java.util.SortedMap)
- */
- public void test_synchronizedSortedMapLjava_util_SortedMap() {
- // Test for method java.util.SortedMap
- // java.util.Collections.synchronizedSortedMap(java.util.SortedMap)
- TreeMap smallMap = new TreeMap();
- for (int i = 0; i < 50; i++) {
- smallMap.put(objArray[i], objArray[i]);
- }
-
- final int numberOfLoops = 200;
- Map synchMap = Collections.synchronizedMap(smallMap);
- // Replacing the previous line with the line below should cause the test
- // to fail--the list below isn't synchronized
- // Map synchMap = smallMap;
-
- SynchMapChecker normalSynchChecker = new SynchMapChecker(synchMap,
- false, numberOfLoops);
- SynchMapChecker offsetSynchChecker = new SynchMapChecker(synchMap,
- true, numberOfLoops);
- Thread normalThread = new Thread(normalSynchChecker);
- Thread offsetThread = new Thread(offsetSynchChecker);
- normalThread.start();
- offsetThread.start();
- while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
- || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- assertTrue("Returned map corrupted by multiple thread access",
- normalSynchChecker.getResult()
- && offsetSynchChecker.getResult());
- try {
- normalThread.join(5000);
- offsetThread.join(5000);
- } catch (InterruptedException e) {
- fail("join() interrupted");
- }
-
- smallMap = new TreeMap();
- for (int i = 0; i < 100; i++) {
- smallMap.put(objArray[i].toString(), objArray[i]);
- }
- synchMap = Collections.synchronizedSortedMap(smallMap);
- new Support_UnmodifiableMapTest("", synchMap).runTest();
- synchMap.keySet().remove(objArray[50].toString());
- assertNull(
- "Removing a key from the keySet of the synchronized map did not remove it from the synchronized map",
- synchMap.get(objArray[50].toString()));
- assertNull(
- "Removing a key from the keySet of the synchronized map did not remove it from the original map",
- smallMap.get(objArray[50].toString()));
- }
-
- /**
- * java.util.Collections#synchronizedSortedSet(java.util.SortedSet)
- */
- public void test_synchronizedSortedSetLjava_util_SortedSet() {
- // Test for method java.util.SortedSet
- // java.util.Collections.synchronizedSortedSet(java.util.SortedSet)
- TreeSet smallSet = new TreeSet();
- for (int i = 0; i < 50; i++) {
- smallSet.add(objArray[i]);
- }
-
- final int numberOfLoops = 200;
- Set synchSet = Collections.synchronizedSet(smallSet);
- // Replacing the previous line with the line below should cause the test
- // to fail--the list below isn't synchronized
- // Set synchSet = smallSet;
-
- SynchCollectionChecker normalSynchChecker = new SynchCollectionChecker(
- synchSet, false, numberOfLoops);
- SynchCollectionChecker offsetSynchChecker = new SynchCollectionChecker(
- synchSet, true, numberOfLoops);
- Thread normalThread = new Thread(normalSynchChecker);
- Thread offsetThread = new Thread(offsetSynchChecker);
- normalThread.start();
- offsetThread.start();
- while ((normalSynchChecker.getNumberOfChecks() < numberOfLoops)
- || (offsetSynchChecker.getNumberOfChecks() < numberOfLoops)) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- assertTrue("Returned set corrupted by multiple thread access",
- normalSynchChecker.getResult()
- && offsetSynchChecker.getResult());
- try {
- normalThread.join(5000);
- offsetThread.join(5000);
- } catch (InterruptedException e) {
- fail("join() interrupted");
- }
- }
-
- /**
- * java.util.Collections#unmodifiableCollection(java.util.Collection)
- */
- public void test_unmodifiableCollectionLjava_util_Collection() {
- // Test for method java.util.Collection
- // java.util.Collections.unmodifiableCollection(java.util.Collection)
- boolean exception = false;
- Collection c = Collections.unmodifiableCollection(ll);
- assertTrue("Returned collection is of incorrect size", c.size() == ll
- .size());
- Iterator i = ll.iterator();
- while (i.hasNext())
- assertTrue("Returned list missing elements", c.contains(i.next()));
- try {
- c.add(new Object());
- } catch (UnsupportedOperationException e) {
- exception = true;
- // Correct
- }
- if (!exception) {
- fail("Allowed modification of collection");
- }
-
- try {
- c.remove(new Object());
- fail("Allowed modification of collection");
- } catch (UnsupportedOperationException e) {
- // Correct
- }
-
- Collection myCollection = new ArrayList();
- myCollection.add(new Integer(20));
- myCollection.add(null);
- c = Collections.unmodifiableCollection(myCollection);
- assertTrue("Collection should contain null", c.contains(null));
- assertTrue("Collection should contain Integer(20)", c
- .contains(new Integer(20)));
-
- myCollection = new ArrayList();
- for (int counter = 0; counter < 100; counter++) {
- myCollection.add(objArray[counter]);
- }
- new Support_UnmodifiableCollectionTest("", Collections
- .unmodifiableCollection(myCollection)).runTest();
- }
-
- /**
- * java.util.Collections#unmodifiableList(java.util.List)
- */
- public void test_unmodifiableListLjava_util_List() {
- // Test for method java.util.List
- // java.util.Collections.unmodifiableList(java.util.List)
-
- // test with a Sequential Access List
- boolean exception = false;
- List c = Collections.unmodifiableList(ll);
- // Ensure a NPE is thrown if the list is NULL
- try {
- Collections.unmodifiableList(null);
- fail("Expected NullPointerException for null list parameter");
- } catch (NullPointerException e) {
- }
-
- assertTrue("Returned list is of incorrect size", c.size() == ll.size());
- assertTrue(
- "Returned List should not implement Random Access interface",
- !(c instanceof RandomAccess));
-
- Iterator i = ll.iterator();
- while (i.hasNext())
- assertTrue("Returned list missing elements", c.contains(i.next()));
- try {
- c.add(new Object());
- } catch (UnsupportedOperationException e) {
- exception = true;
- // Correct
- }
- if (!exception) {
- fail("Allowed modification of list");
- }
-
- try {
- c.remove(new Object());
- fail("Allowed modification of list");
- } catch (UnsupportedOperationException e) {
- // Correct
- }
-
- // test with a Random Access List
- List smallList = new ArrayList();
- smallList.add(null);
- smallList.add("yoink");
- c = Collections.unmodifiableList(smallList);
- assertNull("First element should be null", c.get(0));
- assertTrue("List should contain null", c.contains(null));
- assertTrue(
- "T1. Returned List should implement Random Access interface",
- c instanceof RandomAccess);
-
- smallList = new ArrayList();
- for (int counter = 0; counter < 100; counter++) {
- smallList.add(objArray[counter]);
- }
- List myList = Collections.unmodifiableList(smallList);
- assertTrue("List should not contain null", !myList.contains(null));
- assertTrue(
- "T2. Returned List should implement Random Access interface",
- myList instanceof RandomAccess);
-
- assertTrue("get failed on unmodifiable list", myList.get(50).equals(
- new Integer(50)));
- ListIterator listIterator = myList.listIterator();
- for (int counter = 0; listIterator.hasNext(); counter++) {
- assertTrue("List has wrong elements", ((Integer) listIterator
- .next()).intValue() == counter);
- }
- new Support_UnmodifiableCollectionTest("", smallList).runTest();
- }
-
- /**
- * java.util.Collections#unmodifiableMap(java.util.Map)
- */
- public void test_unmodifiableMapLjava_util_Map() {
- // Test for method java.util.Map
- // java.util.Collections.unmodifiableMap(java.util.Map)
- boolean exception = false;
- Map c = Collections.unmodifiableMap(hm);
- assertTrue("Returned map is of incorrect size", c.size() == hm.size());
- Iterator i = hm.keySet().iterator();
- while (i.hasNext()) {
- Object x = i.next();
- assertTrue("Returned map missing elements", c.get(x).equals(
- hm.get(x)));
- }
- try {
- c.put(new Object(), "");
- } catch (UnsupportedOperationException e) {
- exception = true;
- // Correct
- }
- assertTrue("Allowed modification of map", exception);
-
- exception = false;
- try {
- c.remove(new Object());
- } catch (UnsupportedOperationException e) {
- // Correct
- exception = true;
- }
- assertTrue("Allowed modification of map", exception);
-
- exception = false;
- Iterator it = c.entrySet().iterator();
- Map.Entry entry = (Map.Entry) it.next();
- try {
- entry.setValue("modified");
- } catch (UnsupportedOperationException e) {
- // Correct
- exception = true;
- }
- assertTrue("Allowed modification of entry", exception);
-
- exception = false;
- Object[] array = c.entrySet().toArray();
- try {
- ((Map.Entry) array[0]).setValue("modified");
- } catch (UnsupportedOperationException e) {
- // Correct
- exception = true;
- }
- assertTrue("Allowed modification of array entry", exception);
-
- exception = false;
- Map.Entry[] array2 = (Map.Entry[]) c.entrySet().toArray(
- new Map.Entry[0]);
- try {
- array2[0].setValue("modified");
- } catch (UnsupportedOperationException e) {
- // Correct
- exception = true;
- }
- assertTrue("Allowed modification of array entry2", exception);
-
- HashMap smallMap = new HashMap();
- smallMap.put(null, new Long(30));
- smallMap.put(new Long(25), null);
- Map unmodMap = Collections.unmodifiableMap(smallMap);
-
- assertNull("Trying to use a null value in map failed", unmodMap
- .get(new Long(25)));
- assertTrue("Trying to use a null key in map failed", unmodMap.get(null)
- .equals(new Long(30)));
-
- smallMap = new HashMap();
- for (int counter = 0; counter < 100; counter++) {
- smallMap.put(objArray[counter].toString(), objArray[counter]);
- }
- unmodMap = Collections.unmodifiableMap(smallMap);
- new Support_UnmodifiableMapTest("", unmodMap).runTest();
-
- }
-
- /**
- * java.util.Collections#unmodifiableSet(java.util.Set)
- */
- public void test_unmodifiableSetLjava_util_Set() {
- // Test for method java.util.Set
- // java.util.Collections.unmodifiableSet(java.util.Set)
- boolean exception = false;
- Set c = Collections.unmodifiableSet(s);
- assertTrue("Returned set is of incorrect size", c.size() == s.size());
- Iterator i = ll.iterator();
- while (i.hasNext())
- assertTrue("Returned set missing elements", c.contains(i.next()));
- try {
- c.add(new Object());
- } catch (UnsupportedOperationException e) {
- exception = true;
- // Correct
- }
- if (!exception) {
- fail("Allowed modification of set");
- }
- try {
- c.remove(new Object());
- fail("Allowed modification of set");
- } catch (UnsupportedOperationException e) {
- // Correct
- }
-
- Set mySet = Collections.unmodifiableSet(new HashSet());
- assertTrue("Should not contain null", !mySet.contains(null));
- mySet = Collections.unmodifiableSet(Collections.singleton(null));
- assertTrue("Should contain null", mySet.contains(null));
-
- mySet = new TreeSet();
- for (int counter = 0; counter < 100; counter++) {
- mySet.add(objArray[counter]);
- }
- new Support_UnmodifiableCollectionTest("", Collections
- .unmodifiableSet(mySet)).runTest();
- }
-
- /**
- * java.util.Collections#unmodifiableSortedMap(java.util.SortedMap)
- */
- public void test_unmodifiableSortedMapLjava_util_SortedMap() {
- // Test for method java.util.SortedMap
- // java.util.Collections.unmodifiableSortedMap(java.util.SortedMap)
- boolean exception = false;
- TreeMap tm = new TreeMap();
- tm.putAll(hm);
- Map c = Collections.unmodifiableSortedMap(tm);
- assertTrue("Returned map is of incorrect size", c.size() == tm.size());
- Iterator i = hm.keySet().iterator();
- while (i.hasNext()) {
- Object x = i.next();
- assertTrue("Returned map missing elements", c.get(x).equals(
- tm.get(x)));
- }
- try {
- c.put(new Object(), "");
- } catch (UnsupportedOperationException e) {
- exception = true;
- // Correct
- }
-
- if (!exception) {
- fail("Allowed modification of map");
- }
- try {
- c.remove(new Object());
- } catch (UnsupportedOperationException e) {
- // Correct
- return;
- }
- fail("Allowed modification of map");
- }
-
- /**
- * java.util.Collections#unmodifiableSortedSet(java.util.SortedSet)
- */
- public void test_unmodifiableSortedSetLjava_util_SortedSet() {
- // Test for method java.util.SortedSet
- // java.util.Collections.unmodifiableSortedSet(java.util.SortedSet)
- boolean exception = false;
- SortedSet ss = new TreeSet();
- ss.addAll(s);
- SortedSet c = Collections.unmodifiableSortedSet(ss);
- assertTrue("Returned set is of incorrect size", c.size() == ss.size());
- Iterator i = ll.iterator();
- while (i.hasNext())
- assertTrue("Returned set missing elements", c.contains(i.next()));
- try {
- c.add(new Object());
- } catch (UnsupportedOperationException e) {
- exception = true;
- // Correct
- }
- if (!exception) {
- fail("Allowed modification of set");
- }
- try {
- c.remove(new Object());
- } catch (UnsupportedOperationException e) {
- // Correct
- return;
- }
- fail("Allowed modification of set");
- }
-
- /**
- * Test unmodifiable objects toString methods
- */
- public void test_unmodifiable_toString_methods() {
- // Regression for HARMONY-552
- ArrayList al = new ArrayList();
- al.add("a");
- al.add("b");
- Collection uc = Collections.unmodifiableCollection(al);
- assertEquals("[a, b]", uc.toString());
- HashMap m = new HashMap();
- m.put("one", "1");
- m.put("two", "2");
- Map um = Collections.unmodifiableMap(m);
- assertTrue("{one=1, two=2}".equals(um.toString()) ||
- "{two=2, one=1}".equals(um.toString()));
- }
-
-
- public void test_singletonListLjava_lang_Object() {
- // Test for method java.util.Set
- // java.util.Collections.singleton(java.lang.Object)
- String str = "Singleton";
-
- List single = Collections.singletonList(str);
- assertEquals(1, single.size());
- assertTrue(single.contains(str));
- assertFalse(single.contains(null));
- assertFalse(Collections.singletonList(null).contains(str));
- assertTrue(Collections.singletonList(null).contains(null));
-
- try {
- single.add("New element");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void test_singletonMapLjava_lang_Object() {
- // Test for method java.util.Set
- // java.util.Collections.singleton(java.lang.Object)
- Double key = new Double (3.14);
- String value = "Fundamental constant";
-
- Map single = Collections.singletonMap(key, value);
- assertEquals(1, single.size());
- assertTrue(single.containsKey(key));
- assertTrue(single.containsValue(value));
- assertFalse(single.containsKey(null));
- assertFalse(single.containsValue(null));
- assertFalse(Collections.singletonMap(null, null).containsKey(key));
- assertFalse(Collections.singletonMap(null, null).containsValue(value));
- assertTrue(Collections.singletonMap(null, null).containsKey(null));
- assertTrue(Collections.singletonMap(null, null).containsValue(null));
-
- try {
- single.clear();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
-
- try {
- single.put(new Double(1), "one wrong value");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- objArray = new Object[1000];
- myobjArray = new Object[1000];
- for (int i = 0; i < objArray.length; i++) {
- objArray[i] = new Integer(i);
- myobjArray[i] = new MyInt(i);
- }
-
- ll = new LinkedList();
- myll = new LinkedList();
- s = new HashSet();
- mys = new HashSet();
- reversedLinkedList = new LinkedList(); // to be sorted in reverse order
- myReversedLinkedList = new LinkedList(); // to be sorted in reverse
- // order
- hm = new HashMap();
- for (int i = 0; i < objArray.length; i++) {
- ll.add(objArray[i]);
- myll.add(myobjArray[i]);
- s.add(objArray[i]);
- mys.add(myobjArray[i]);
- reversedLinkedList.add(objArray[objArray.length - i - 1]);
- myReversedLinkedList.add(myobjArray[myobjArray.length - i - 1]);
- hm.put(objArray[i].toString(), objArray[i]);
- }
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- objArray = null;
- myobjArray = null;
-
- ll = null;
- myll = null;
- reversedLinkedList = null;
- myReversedLinkedList = null;
- s = null;
- mys = null;
- hm = null;
- }
-
- protected void doneSuite() {
- objArray = null;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/ConcurrentModTest.java b/luni/src/test/java/tests/api/java/util/ConcurrentModTest.java
deleted file mode 100644
index 3750e81..0000000
--- a/luni/src/test/java/tests/api/java/util/ConcurrentModTest.java
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.List;
-import java.util.Vector;
-
-import junit.framework.TestCase;
-
-public class ConcurrentModTest extends TestCase {
-
- /*
- * Test method for 'java.util.AbstractList.subList(int, int)'
- */
- public void testGet() {
- AbstractList al = new ArrayList();
- Double one = new Double(1.0);
- Double two = new Double(2.0);
- Double three = new Double(3.0);
- Double four = new Double(4.0);
- al.add(one);
- al.add(two);
- al.add(three);
- al.add(four);
- List sub = al.subList(1, 3);
- assertEquals(2, sub.size());
- // the sub.get(1) is 3.0
- assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
- assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
-
- al.remove(1); // remove the 2.0
-
- try {
- // illegal call the subList's method get(int).
- sub.get(1);
- fail("It should throws ConcurrentModificationException.");
- } catch (ConcurrentModificationException e) {
- return;
- }
-
- try {
- al.get(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- try {
- al.get(al.size()+1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
- }
-
- /*
- * Test method for 'java.util.AbstractList.subList(int, int)'
- */
- public void testSet() {
- AbstractList al = new ArrayList();
- Double one = new Double(1.0);
- Double two = new Double(2.0);
- Double three = new Double(3.0);
- Double four = new Double(4.0);
- al.add(one);
- al.add(two);
- al.add(three);
- al.add(four);
- List sub = al.subList(1, 3);
- assertEquals(2, sub.size());
- // the sub.get(1) is 3.0
- assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
- assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
-
- al.remove(1); // remove the 2.0
-
- try {
- // illegal call the subList's method set(int,Object).
- sub.set(1, two);
- fail("It should throws ConcurrentModificationException.");
- } catch (ConcurrentModificationException e) {
- return;
- }
- }
-
- /*
- * Test method for 'java.util.AbstractList.subList(int, int)'
- */
- public void testAdd() {
- AbstractList al = new ArrayList();
- Double one = new Double(1.0);
- Double two = new Double(2.0);
- Double three = new Double(3.0);
- Double four = new Double(4.0);
- al.add(one);
- al.add(two);
- al.add(three);
- al.add(four);
- List sub = al.subList(1, 3);
- assertEquals(2, sub.size());
- // the sub.get(1) is 3.0
- assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
- assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
-
- al.remove(1); // remove the 2.0
-
- try {
- // illegal call the subList's method Add(int,Object).
- sub.add(1, two);
- fail("It should throws ConcurrentModificationException.");
- } catch (ConcurrentModificationException e) {
- return;
- }
- }
-
- /*
- * Test method for 'java.util.AbstractList.subList(int, int)'
- */
- public void testRemove() {
- AbstractList al = new ArrayList();
- Double one = new Double(1.0);
- Double two = new Double(2.0);
- Double three = new Double(3.0);
- Double four = new Double(4.0);
- al.add(one);
- al.add(two);
- al.add(three);
- al.add(four);
- List sub = al.subList(1, 3);
- assertEquals(2, sub.size());
- // the sub.get(1) is 3.0
- assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
- assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
-
- al.remove(1); // remove the 2.0
-
- try {
- // illegal call the subList's method remove(int).
- sub.remove(1);
- fail("It should throws ConcurrentModificationException.");
- } catch (ConcurrentModificationException e) {
- return;
- }
-
- try {
- sub.remove(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- try {
- sub.remove(sub.size() + 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- al = new AbstractList() {
-
- @Override
- public Object get(int index) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public int size() {
- // TODO Auto-generated method stub
- return 0;
- }
- };
-
- try {
- al.remove(1);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException ee) {
- //expected
- }
- }
-
- /*
- * Test method for 'java.util.AbstractList.subList(int, int)'
- */
- public void testAddAll() {
- AbstractList al = new ArrayList();
- Double one = new Double(1.0);
- Double two = new Double(2.0);
- Double three = new Double(3.0);
- Double four = new Double(4.0);
- al.add(one);
- al.add(two);
- al.add(three);
- al.add(four);
- List sub = al.subList(1, 3);
- assertEquals(2, sub.size());
- // the sub.get(1) is 3.0
- assertTrue(((Double) sub.get(1)).doubleValue() <= 3.0);
- assertTrue(((Double) sub.get(1)).doubleValue() > 2.0);
-
- al.remove(1); // remove the 2.0
-
- try {
- // illegal call the subList's method addAll(int,Collection).
- Collection c = new Vector();
- Double five = new Double(5.0);
- c.add(five);
- sub.addAll(1, c);
- fail("It should throws ConcurrentModificationException.");
- } catch (ConcurrentModificationException e) {
- return;
- }
- }
-
- public void test_addLjava_lang_Object() {
- AbstractList abstr = new AbstractList() {
-
- @Override
- public Object get(int arg0) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
-
- };
-
- try {
- abstr.add(null);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //ecpected
- }
- abstr = new AbstractList<Double>() {
- @Override
- public boolean add(Double value) {
- return true;
- }
-
- @Override
- public Double get(int index) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
-
- try {
- abstr.add(1);
- fail("ClassCastException expected");
- } catch (ClassCastException ee) {
- //expected
- }
-
- abstr = new AbstractList<Integer>() {
- final int forbiddenValue = 33;
- @Override
- public boolean add(Integer value) {
- if (value == forbiddenValue) {
- throw new IllegalArgumentException();
- }
- return true;
- }
-
- @Override
- public Integer get(int index) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
-
- abstr.add(1);
- try {
- abstr.add(33);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ee) {
- //expected
- }
- }
-
- public void test_addILjava_lang_Object() {
- AbstractList abstr = new AbstractList() {
-
- @Override
- public Object get(int arg0) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
-
- };
-
- try {
- abstr.add(1, null);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //ecpected
- }
- abstr = new AbstractList<Double>() {
- @Override
- public void add(int index, Double value) {
- }
-
- @Override
- public Double get(int index) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
-
- try {
- abstr.add(1, 1);
- fail("ClassCastException expected");
- } catch (ClassCastException ee) {
- //expected
- }
-
- abstr = new AbstractList<Integer>() {
- final int forbiddenValue = 33;
- @Override
- public void add(int index, Integer value) {
- if (value == forbiddenValue) {
- throw new IllegalArgumentException();
- }
- }
-
- @Override
- public Integer get(int index) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
-
- abstr.add(1, 1);
- try {
- abstr.add(1, 33);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ee) {
- //expected
- }
-
- abstr = new ArrayList();
-
- abstr.add(0, "element");
- abstr.add(1, null);
- abstr.add(2, 1);
- abstr.add(3, new Double(33));
-
- try {
- abstr.add(-3, new Double(33));
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- try {
- abstr.add(abstr.size() + 1, new Double(33));
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
- }
-
- public void test_addAllILjava_util_Collection() {
- Collection c = new Vector();
- c.add(new Double(33));
- c.add(10);
- c.add("String");
-
- AbstractList abstr = new AbstractList() {
- @Override
- public Object get(int arg0) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
-
- try {
- abstr.addAll(0, null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- try {
- abstr.addAll(0, c);
- fail("UnsuportedOperationException expected");
- } catch (UnsupportedOperationException ee) {
- //expected
- }
-
- abstr = new AbstractList<Double>() {
- @Override
- public void add(int index, Double value) {
- }
-
- @Override
- public Double get(int arg0) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
-
- try {
- abstr.addAll(0, c);
- fail("ClassCastException expected");
- } catch (ClassCastException ee) {
- //expectd
- }
-
- abstr = new AbstractList<Integer>() {
- final int forbiddenValue = 33;
- @Override
- public void add(int index, Integer value) {
- if (value == forbiddenValue) {
- throw new IllegalArgumentException();
- }
- }
-
- @Override
- public Integer get(int arg0) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
- c.clear();
- c.add(new Integer(1));
- c.add(new Integer(2));
- c.add(new Integer(3));
- c.add(new Integer(4));
- c.add(new Integer(5));
-
- abstr.addAll(0, c);
-
- c.add(new Integer(33));
-
- try {
- abstr.addAll(0, c);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ee) {
- //expected
- }
- abstr = new ArrayList();
- abstr.addAll(0, c);
-
- try {
- abstr.addAll(-1, c);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- try {
- abstr.addAll(abstr.size() + 1, c);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
- }
-
- public void test_clear() {
- AbstractList abstr = new ArrayList();
-
- assertEquals(0, abstr.size());
- abstr.add("String");
- abstr.add("1");
- abstr.add(2);
- abstr.add(new Double(3));
- assertEquals(4, abstr.size());
- abstr.clear();
- assertEquals(0, abstr.size());
- }
-
- public void test_equalsLjava_lang_Object() {
- Collection c = new Vector();
- c.add(new Double(33));
- c.add(10);
- c.add("String");
-
- AbstractList abstr = new ArrayList();
- AbstractList abstr1 = new ArrayList();
-
- assertFalse(abstr.equals(this));
- abstr.add(new Double(33));
- abstr.add(10);
- abstr.add("String");
- assertTrue(abstr.equals(c));
- abstr1.addAll(c);
- assertTrue(abstr.equals(abstr1));
- }
-
- public void test_setILjava_lang_Object() {
- Collection c = new Vector();
- c.add(new Double(33));
- c.add(10);
- c.add("String");
-
- AbstractList abstr1 = new ArrayList();
- AbstractList abstr2 = new ArrayList();
-
- abstr1.addAll(c);
- abstr2.addAll(c);
- assertTrue(abstr1.equals(abstr2));
- abstr1.set(1, 1);
- assertFalse(abstr1.equals(abstr2));
-
- try {
- abstr1.set(abstr1.size() + 1, 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- try {
- abstr1.set(-1, 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException ee) {
- //expected
- }
-
- AbstractList abstr = new AbstractList() {
-
- @Override
- public Object get(int index) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
-
- };
-
- try {
- abstr.set(0, null);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException ee) {
- //expected
- }
-
- abstr = new AbstractList<Double>() {
- @Override
- public Double set(int index, Double value) {
- return value;
- }
-
- @Override
- public Double get(int index) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
-
- try {
- abstr.set(0, 1);
- fail("ClassCastException expected");
- } catch (ClassCastException ee) {
- //expected
- }
-
- abstr = new AbstractList<Integer>() {
- final int forbiddenValue = 33;
- @Override
- public Integer set(int index, Integer value) {
- if (value == forbiddenValue) {
- throw new IllegalArgumentException();
- }
- return value;
- }
-
- @Override
- public Integer get(int index) {
- return null;
- }
-
- @Override
- public int size() {
- return 0;
- }
- };
-
- try {
- abstr.set(0, 33);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException ee) {
- //expected
- }
- }
- class Mock_ArrayList extends ArrayList {
- @Override
- public void removeRange(int fromIndex, int toIndex) {
- super.removeRange(fromIndex, toIndex);
- }
- }
-
- public void test_removeRangeII() {
- Mock_ArrayList al1 = new Mock_ArrayList();
- al1.add(1);
- al1.add(2);
- al1.add(3);
- al1.add(4);
- al1.add(5);
- Mock_ArrayList al2 = new Mock_ArrayList();
-
- al2.add(1);
- al2.add(5);
- assertNotSame(al1,al2);
- al1.removeRange(1, 4);
- assertEquals(al1,al2);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/ConcurrentModificationExceptionTest.java b/luni/src/test/java/tests/api/java/util/ConcurrentModificationExceptionTest.java
deleted file mode 100644
index 0cd4076..0000000
--- a/luni/src/test/java/tests/api/java/util/ConcurrentModificationExceptionTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-public class ConcurrentModificationExceptionTest extends
- junit.framework.TestCase {
-
- static public class CollectionModifier implements Runnable {
- Collection col;
-
- boolean keepGoing = true;
-
- public CollectionModifier(Collection c) {
- col = c;
- }
-
- public void stopNow() {
- keepGoing = false;
- }
-
- public void run() {
- Object someItem = new Integer(-1);
- while (keepGoing) {
- col.add(someItem);
- col.remove(someItem);
- }
- }
- }
-
- /**
- * java.util.ConcurrentModificationException#ConcurrentModificationException()
- */
- public void test_Constructor() {
- // Test for method java.util.ConcurrentModificationException()
- Collection myCollection = new LinkedList();
- Iterator myIterator = myCollection.iterator();
- for (int counter = 0; counter < 50; counter++)
- myCollection.add(new Integer(counter));
- CollectionModifier cm = new CollectionModifier(myCollection);
- Thread collectionSlapper = new Thread(cm);
- try {
- collectionSlapper.start();
- while (myIterator.hasNext())
- myIterator.next();
- } catch (ConcurrentModificationException e) {
- cm.stopNow();
- return;
- }
- cm.stopNow();
- // The exception should have been thrown--if the code flow makes it here
- // the test has failed
- fail("Failed to throw expected ConcurrentModificationException");
- }
-
- /**
- * java.util.ConcurrentModificationException#ConcurrentModificationException(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() {
- // Test for method
- // java.util.ConcurrentModificationException(java.lang.String)
- String errorMessage = "This is an error message";
- try {
- // This is here to stop "unreachable code" unresolved problem
- if (true)
- throw new ConcurrentModificationException(errorMessage);
- } catch (ConcurrentModificationException e) {
- assertTrue("Exception thrown without error message", e.getMessage()
- .equals(errorMessage));
- return;
- }
- fail("Failed to throw expected ConcurrentModificationException");
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/CurrencyTest.java b/luni/src/test/java/tests/api/java/util/CurrencyTest.java
deleted file mode 100644
index 82fd7cf..0000000
--- a/luni/src/test/java/tests/api/java/util/CurrencyTest.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Currency;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Set;
-
-public class CurrencyTest extends junit.framework.TestCase {
-
- private static Locale defaultLocale = Locale.getDefault();
-
- /**
- * java.util.Currency#getInstance(java.lang.String)
- */
- public void test_getInstanceLjava_lang_String() {
- // see test_getInstanceLjava_util_Locale() tests
- }
-
- /**
- * java.util.Currency#getInstance(java.util.Locale)
- */
- public void test_getInstanceLjava_util_Locale() {
- /*
- * the behaviour in all these three cases should be the same since this
- * method ignores language and variant component of the locale.
- */
- Currency c0 = Currency.getInstance("CAD");
- Currency c1 = Currency.getInstance(new Locale("en", "CA"));
- assertTrue(
- "Currency.getInstance(new Locale(\"en\",\"CA\")) isn't equal to Currency.getInstance(\"CAD\")",
- c1 == c0);
- Currency c2 = Currency.getInstance(new Locale("fr", "CA"));
- assertTrue(
- "Currency.getInstance(new Locale(\"fr\",\"CA\")) isn't equal to Currency.getInstance(\"CAD\")",
- c2 == c0);
- Currency c3 = Currency.getInstance(new Locale("", "CA"));
- assertTrue(
- "Currency.getInstance(new Locale(\"\",\"CA\")) isn't equal to Currency.getInstance(\"CAD\")",
- c3 == c0);
-
- c0 = Currency.getInstance("JPY");
- c1 = Currency.getInstance(new Locale("ja", "JP"));
- assertTrue(
- "Currency.getInstance(new Locale(\"ja\",\"JP\")) isn't equal to Currency.getInstance(\"JPY\")",
- c1 == c0);
- c2 = Currency.getInstance(new Locale("", "JP"));
- assertTrue(
- "Currency.getInstance(new Locale(\"\",\"JP\")) isn't equal to Currency.getInstance(\"JPY\")",
- c2 == c0);
- c3 = Currency.getInstance(new Locale("bogus", "JP"));
- assertTrue(
- "Currency.getInstance(new Locale(\"bogus\",\"JP\")) isn't equal to Currency.getInstance(\"JPY\")",
- c3 == c0);
-
- Locale localeGu = new Locale("gu", "IN");
- Currency cGu = Currency.getInstance(localeGu);
- Locale localeKn = new Locale("kn", "IN");
- Currency cKn = Currency.getInstance(localeKn);
- assertTrue("Currency.getInstance(Locale_" + localeGu.toString() + "))"
- + "isn't equal to " + "Currency.getInstance(Locale_"
- + localeKn.toString() + "))", cGu == cKn);
-
- // some teritories do not have currencies, like Antarctica
- Locale loc = new Locale("", "AQ");
- try {
- Currency curr = Currency.getInstance(loc);
- assertNull(
- "Currency.getInstance(new Locale(\"\", \"AQ\")) did not return null",
- curr);
- } catch (IllegalArgumentException e) {
- fail("Unexpected IllegalArgumentException " + e);
- }
-
- // unsupported/legacy iso3 countries
- loc = new Locale("", "ZR");
- try {
- Currency curr = Currency.getInstance(loc);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- loc = new Locale("", "ZAR");
- try {
- Currency curr = Currency.getInstance(loc);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- loc = new Locale("", "FX");
- try {
- Currency curr = Currency.getInstance(loc);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- loc = new Locale("", "FXX");
- try {
- Currency curr = Currency.getInstance(loc);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
- }
-
- /**
- * java.util.Currency#getSymbol()
- */
- public void test_getSymbol() {
- Currency currK = Currency.getInstance("KRW");
- Currency currI = Currency.getInstance("IEP");
- Currency currUS = Currency.getInstance("USD");
-
- Locale.setDefault(Locale.US);
- // BEGIN android-changed
- // KRW currency symbol is \u20a9 since CLDR1.7 release.
- assertEquals("currK.getSymbol()", "\u20a9", currK.getSymbol());
- // IEP currency symbol is IEP since CLDR2.0 release.
- assertEquals("currI.getSymbol()", "IEP", currI.getSymbol());
- // END android-changed
- assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
-
- Locale.setDefault(new Locale("en", "IE"));
- // BEGIN android-changed
- assertEquals("currK.getSymbol()", "\u20a9", currK.getSymbol());
- assertEquals("currI.getSymbol()", "IEP", currI.getSymbol());
- assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
- // END android-changed
-
- // test what happens if this is an invalid locale,
- // one with Korean country but an India language
- Locale.setDefault(new Locale("kr", "KR"));
- // BEGIN android-changed
- assertEquals("currK.getSymbol()", "\u20a9", currK.getSymbol());
- assertEquals("currI.getSymbol()", "IEP", currI.getSymbol());
- // END android-changed
- assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
- }
-
- /**
- * java.util.Currency#getSymbol(java.util.Locale)
- */
- public void test_getSymbolLjava_util_Locale() {
- //Tests was simplified because java specification not
- // includes strong requirements for returnig symbol.
- // on android platform used wrong character for yen
- // sign: \u00a5 instead of \uffe5
- Locale[] desiredLocales = new Locale[]{
- Locale.JAPAN, Locale.JAPANESE,
- Locale.FRANCE, Locale.FRENCH,
- Locale.US, Locale.UK,
- Locale.CANADA, Locale.CANADA_FRENCH,
- Locale.ENGLISH,
- new Locale("ja", "JP"), new Locale("", "JP"),
-
- new Locale("fr", "FR"), new Locale("", "FR"),
-
- new Locale("en", "US"), new Locale("", "US"),
- new Locale("es", "US"), new Locale("ar", "US"),
- new Locale("ja", "US"),
-
- new Locale("en", "CA"), new Locale("fr", "CA"),
- new Locale("", "CA"), new Locale("ar", "CA"),
-
- new Locale("ja", "JP"), new Locale("", "JP"),
- new Locale("ar", "JP"),
-
- new Locale("ja", "AE"), new Locale("en", "AE"),
- new Locale("ar", "AE"),
-
- new Locale("da", "DK"), new Locale("", "DK"),
-
- new Locale("da", ""), new Locale("ja", ""),
- new Locale("en", "")};
-
- Set<Locale> availableLocales = new HashSet<Locale>(Arrays.asList(Locale.getAvailableLocales()));
-
- ArrayList<Locale> locales = new ArrayList<Locale>();
- for (Locale desiredLocale : desiredLocales) {
- if (availableLocales.contains(desiredLocale)) {
- locales.add(desiredLocale);
- }
- }
-
- Locale[] loc1 = locales.toArray(new Locale[locales.size()]);
-
- String[] euro = new String[] {"EUR", "\u20ac"};
- // \u00a5 and \uffe5 are actually the same symbol, just different code points.
- // But the RI returns the \uffe5 and Android returns those with \u00a5
- String[] yen = new String[] {"JPY", "\u00a5", "\u00a5JP", "JP\u00a5", "\uffe5", "\uffe5JP", "JP\uffe5"};
- String[] dollar = new String[] {"USD", "$", "US$", "$US"};
- // BEGIN android-changed
- // Starting CLDR 1.7 release, currency symbol for CAD changed to CA$ in some locales such as ja.
- String[] cDollar = new String[] {"CA$", "CAD", "$", "Can$", "$CA"};
- // END android-changed
-
- Currency currE = Currency.getInstance("EUR");
- Currency currJ = Currency.getInstance("JPY");
- Currency currUS = Currency.getInstance("USD");
- Currency currCA = Currency.getInstance("CAD");
-
- int i, j, k;
- boolean flag;
-
- for(k = 0; k < loc1.length; k++) {
- Locale.setDefault(loc1[k]);
-
- for (i = 0; i < loc1.length; i++) {
- flag = false;
- for (j = 0; j < euro.length; j++) {
- if (currE.getSymbol(loc1[i]).equals(euro[j])) {
- flag = true;
- break;
- }
- }
- assertTrue("Default Locale is: " + Locale.getDefault()
- + ". For locale " + loc1[i]
- + " the Euro currency returned "
- + currE.getSymbol(loc1[i])
- + ". Expected was one of these: "
- + Arrays.toString(euro), flag);
- }
-
- for (i = 0; i < loc1.length; i++) {
- flag = false;
- for (j = 0; j < yen.length; j++) {
- byte[] b1 = null;
- byte[] b2 = null;
- if (currJ.getSymbol(loc1[i]).equals(yen[j])) {
- flag = true;
- break;
- }
- }
- assertTrue("Default Locale is: " + Locale.getDefault()
- + ". For locale " + loc1[i]
- + " the Yen currency returned "
- + currJ.getSymbol(loc1[i])
- + ". Expected was one of these: "
- + Arrays.toString(yen), flag);
- }
-
- for (i = 0; i < loc1.length; i++) {
- flag = false;
- for (j = 0; j < dollar.length; j++) {
- if (currUS.getSymbol(loc1[i]).equals(dollar[j])) {
- flag = true;
- break;
- }
- }
- assertTrue("Default Locale is: " + Locale.getDefault()
- + ". For locale " + loc1[i]
- + " the Dollar currency returned "
- + currUS.getSymbol(loc1[i])
- + ". Expected was one of these: "
- + Arrays.toString(dollar), flag);
- }
-
- for (i = 0; i < loc1.length; i++) {
- flag = false;
- for (j = 0; j < cDollar.length; j++) {
- if (currCA.getSymbol(loc1[i]).equals(cDollar[j])) {
- flag = true;
- break;
- }
- }
- assertTrue("Default Locale is: " + Locale.getDefault()
- + ". For locale " + loc1[i]
- + " the Canadian Dollar currency returned "
- + currCA.getSymbol(loc1[i])
- + ". Expected was one of these: "
- + Arrays.toString(cDollar), flag);
- }
- }
- }
-
- /**
- * java.util.Currency#getDefaultFractionDigits()
- */
- public void test_getDefaultFractionDigits() {
-
- Currency c1 = Currency.getInstance("TND");
- c1.getDefaultFractionDigits();
- assertEquals(" Currency.getInstance(\"" + c1
- + "\") returned incorrect number of digits. ", 3, c1
- .getDefaultFractionDigits());
-
- Currency c2 = Currency.getInstance("EUR");
- c2.getDefaultFractionDigits();
- assertEquals(" Currency.getInstance(\"" + c2
- + "\") returned incorrect number of digits. ", 2, c2
- .getDefaultFractionDigits());
-
- Currency c3 = Currency.getInstance("JPY");
- c3.getDefaultFractionDigits();
- assertEquals(" Currency.getInstance(\"" + c3
- + "\") returned incorrect number of digits. ", 0, c3
- .getDefaultFractionDigits());
-
- Currency c4 = Currency.getInstance("XXX");
- c4.getDefaultFractionDigits();
- assertEquals(" Currency.getInstance(\"" + c4
- + "\") returned incorrect number of digits. ", -1, c4
- .getDefaultFractionDigits());
- }
-
- /**
- * java.util.Currency#getCurrencyCode() Note: lines under remarks
- * (Locale.CHINESE, Locale.ENGLISH, Locale.FRENCH, Locale.GERMAN,
- * Locale.ITALIAN, Locale.JAPANESE, Locale.KOREAN) raises exception
- * on SUN VM
- */
- public void test_getCurrencyCode() {
- final Collection<Locale> locVal = Arrays.asList(
- Locale.CANADA,
- Locale.CANADA_FRENCH,
- Locale.CHINA,
- // Locale.CHINESE,
- // Locale.ENGLISH,
- Locale.FRANCE,
- // Locale.FRENCH,
- // Locale.GERMAN,
- Locale.GERMANY,
- // Locale.ITALIAN,
- Locale.ITALY, Locale.JAPAN,
- // Locale.JAPANESE,
- Locale.KOREA,
- // Locale.KOREAN,
- Locale.PRC, Locale.SIMPLIFIED_CHINESE, Locale.TAIWAN, Locale.TRADITIONAL_CHINESE,
- Locale.UK, Locale.US);
- final Collection<String> locDat = Arrays.asList("CAD", "CAD", "CNY", "EUR", "EUR", "EUR",
- "JPY", "KRW", "CNY", "CNY", "TWD", "TWD", "GBP", "USD");
-
- Iterator<String> dat = locDat.iterator();
- for (Locale l : locVal) {
- String d = dat.next().trim();
- assertEquals("For locale " + l + " currency code wrong", Currency.getInstance(l)
- .getCurrencyCode(), d);
- }
- }
-
- /**
- * java.util.Currency#toString() Note: lines under remarks
- * (Locale.CHINESE, Locale.ENGLISH, Locale.FRENCH, Locale.GERMAN,
- * Locale.ITALIAN, Locale.JAPANESE, Locale.KOREAN) raises exception
- * on SUN VM
- */
- public void test_toString() {
- final Collection<Locale> locVal = Arrays.asList(
- Locale.CANADA,
- Locale.CANADA_FRENCH,
- Locale.CHINA,
- // Locale.CHINESE,
- // Locale.ENGLISH,
- Locale.FRANCE,
- // Locale.FRENCH,
- // Locale.GERMAN,
- Locale.GERMANY,
- // Locale.ITALIAN,
- Locale.ITALY, Locale.JAPAN,
- // Locale.JAPANESE,
- Locale.KOREA,
- // Locale.KOREAN,
- Locale.PRC, Locale.SIMPLIFIED_CHINESE, Locale.TAIWAN, Locale.TRADITIONAL_CHINESE,
- Locale.UK, Locale.US);
- final Collection<String> locDat = Arrays.asList("CAD", "CAD", "CNY", "EUR", "EUR", "EUR",
- "JPY", "KRW", "CNY", "CNY", "TWD", "TWD", "GBP", "USD");
-
- Iterator<String> dat = locDat.iterator();
- for (Locale l : locVal) {
- String d = dat.next().trim();
- assertEquals("For locale " + l + " Currency.toString method returns wrong value",
- Currency.getInstance(l).toString(), d);
- }
- }
-
- protected void setUp() {
- Locale.setDefault(defaultLocale);
- }
-
- protected void tearDown() {
- }
-
- /**
- * Helper method to display Currency info
- *
- * @param c
- */
- private void printCurrency(Currency c) {
- System.out.println();
- System.out.println(c.getCurrencyCode());
- System.out.println(c.getSymbol());
- System.out.println(c.getDefaultFractionDigits());
- }
-
- /**
- * helper method to display Locale info
- */
- private static void printLocale(Locale loc) {
- System.out.println();
- System.out.println(loc.getDisplayName());
- System.out.println(loc.getCountry());
- System.out.println(loc.getLanguage());
- System.out.println(loc.getDisplayCountry());
- System.out.println(loc.getDisplayLanguage());
- System.out.println(loc.getDisplayName());
- System.out.println(loc.getISO3Country());
- System.out.println(loc.getISO3Language());
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/DateTest.java b/luni/src/test/java/tests/api/java/util/DateTest.java
deleted file mode 100644
index 6100527..0000000
--- a/luni/src/test/java/tests/api/java/util/DateTest.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.TimeZone;
-
-public class DateTest extends junit.framework.TestCase {
-
- /**
- * java.util.Date#Date()
- */
- public void test_Constructor() {
- // Test for method java.util.Date()
- GregorianCalendar gc = new GregorianCalendar(1998, Calendar.OCTOBER,
- 13, 19, 9);
- long oldTime = gc.getTime().getTime();
- long now = new Date().getTime();
- assertTrue("Created incorrect date: " + oldTime + " now: " + now,
- oldTime < now);
- }
-
- /**
- * java.util.Date#Date(int, int, int)
- */
- public void test_ConstructorIII() {
- // Test for method java.util.Date(int, int, int)
- Date d1 = new Date(70, 0, 1); // the epoch + local time
-
- // the epoch + local time
- Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000);
-
- assertTrue("Created incorrect date", d1.equals(d2));
-
- Date date = new Date(99, 5, 22);
- Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 22);
- assertTrue("Wrong time zone", date.equals(cal.getTime()));
- }
-
- /**
- * java.util.Date#Date(int, int, int, int, int)
- */
- public void test_ConstructorIIIII() {
- // Test for method java.util.Date(int, int, int, int, int)
-
- // the epoch + local time + (1 hour and 1 minute)
- Date d1 = new Date(70, 0, 1, 1, 1);
-
- // the epoch + local time + (1 hour and 1 minute)
- Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000 + 60 * 60
- * 1000 + 60 * 1000);
-
- assertTrue("Created incorrect date", d1.equals(d2));
- }
-
- /**
- * java.util.Date#Date(int, int, int, int, int, int)
- */
- public void test_ConstructorIIIIII() {
- // Test for method java.util.Date(int, int, int, int, int, int)
-
- // the epoch + local time + (1 hour and 1 minute + 1 second)
- Date d1 = new Date(70, 0, 1, 1, 1, 1);
-
- // the epoch + local time + (1 hour and 1 minute + 1 second)
- Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000 + 60 * 60
- * 1000 + 60 * 1000 + 1000);
-
- assertTrue("Created incorrect date", d1.equals(d2));
- }
-
- /**
- * java.util.Date#Date(long)
- */
- public void test_ConstructorJ() {
- // Test for method java.util.Date(long)
- assertTrue("Used to test", true);
- }
-
- /**
- * java.util.Date#Date(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.util.Date(java.lang.String)
- Date d1 = new Date("January 1, 1970, 00:00:00 GMT"); // the epoch
- Date d2 = new Date(0); // the epoch
- assertTrue("Created incorrect date", d1.equals(d2));
-
- try {
- // Regression for HARMONY-238
- new Date(null);
- fail("Constructor Date((String)null) should "
- + "throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * java.util.Date#after(java.util.Date)
- */
- public void test_afterLjava_util_Date() {
- // Test for method boolean java.util.Date.after(java.util.Date)
- Date d1 = new Date(0);
- Date d2 = new Date(1900000);
- assertTrue("Older was returned as newer", d2.after(d1));
- assertTrue("Newer was returned as older", !d1.after(d2));
-
- try {
- d1.after(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Date#before(java.util.Date)
- */
- public void test_beforeLjava_util_Date() {
- // Test for method boolean java.util.Date.before(java.util.Date)
- Date d1 = new Date(0);
- Date d2 = new Date(1900000);
- assertTrue("Older was returned as newer", !d2.before(d1));
- assertTrue("Newer was returned as older", d1.before(d2));
-
- try {
- d1.before(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Date#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.Date.clone()
- Date d1 = new Date(100000);
- Date d2 = (Date) d1.clone();
- assertTrue(
- "Cloning date results in same reference--new date is equivalent",
- d1 != d2);
- assertTrue("Cloning date results unequal date", d1.equals(d2));
- }
-
- /**
- * java.util.Date#compareTo(java.util.Date)
- */
- public void test_compareToLjava_util_Date() {
- // Test for method int java.util.Date.compareTo(java.util.Date)
- final int someNumber = 10000;
- Date d1 = new Date(someNumber);
- Date d2 = new Date(someNumber);
- Date d3 = new Date(someNumber + 1);
- Date d4 = new Date(someNumber - 1);
- assertEquals("Comparing a date to itself did not answer zero", 0, d1
- .compareTo(d1));
- assertEquals("Comparing equal dates did not answer zero", 0, d1
- .compareTo(d2));
- assertEquals("date1.compareTo(date2), where date1 > date2, did not result in 1",
- 1, d1.compareTo(d4));
- assertEquals("date1.compareTo(date2), where date1 < date2, did not result in -1",
- -1, d1.compareTo(d3));
-
- try {
- d1.compareTo(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Date#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- // Test for method boolean java.util.Date.equals(java.lang.Object)
- Date d1 = new Date(0);
- Date d2 = new Date(1900000);
- Date d3 = new Date(1900000);
- assertTrue("Equality test failed", d2.equals(d3));
- assertTrue("Equality test failed", !d1.equals(d2));
- }
-
- /**
- * java.util.Date#getDate()
- */
- public void test_getDate() {
- // Test for method int java.util.Date.getDate()
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- assertEquals("Returned incorrect date", 13, d.getDate());
- }
-
- /**
- * java.util.Date#getDay()
- */
- public void test_getDay() {
- // Test for method int java.util.Date.getDay()
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- assertEquals("Returned incorrect day", 2, d.getDay());
- }
-
- /**
- * java.util.Date#getHours()
- */
- public void test_getHours() {
- // Test for method int java.util.Date.getHours()
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- assertEquals("Returned incorrect hours", 19, d.getHours());
- }
-
- /**
- * java.util.Date#getMinutes()
- */
- public void test_getMinutes() {
- // Test for method int java.util.Date.getMinutes()
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- assertEquals("Returned incorrect minutes", 9, d.getMinutes());
- }
-
- /**
- * java.util.Date#getMonth()
- */
- public void test_getMonth() {
- // Test for method int java.util.Date.getMonth()
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- assertEquals("Returned incorrect month", 9, d.getMonth());
- }
-
- /**
- * java.util.Date#getSeconds()
- */
- public void test_getSeconds() {
- // Test for method int java.util.Date.getSeconds()
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- assertEquals("Returned incorrect seconds", 0, d.getSeconds());
- }
-
- /**
- * java.util.Date#getTime()
- */
- public void test_getTime() {
- // Test for method long java.util.Date.getTime()
- Date d1 = new Date(0);
- Date d2 = new Date(1900000);
- assertEquals("Returned incorrect time", 1900000, d2.getTime());
- assertEquals("Returned incorrect time", 0, d1.getTime());
- }
-
- /**
- * java.util.Date#getTimezoneOffset()
- */
- public void test_getTimezoneOffset() {
- // Test for method int java.util.Date.getTimezoneOffset()
- assertTrue("Used to test", true);
- int offset = new Date(96, 1, 14).getTimezoneOffset();
- assertTrue(offset > -720 && offset < 720);
- }
-
- /**
- * java.util.Date#getYear()
- */
- public void test_getYear() {
- // Test for method int java.util.Date.getYear()
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- assertEquals("Returned incorrect year", 98, d.getYear());
- }
-
- /**
- * java.util.Date#hashCode()
- */
- public void test_hashCode() {
- // Test for method int java.util.Date.hashCode()
- Date d1 = new Date(0);
- Date d2 = new Date(1900000);
- assertEquals("Returned incorrect hash", 1900000, d2.hashCode());
- assertEquals("Returned incorrect hash", 0, d1.hashCode());
- }
-
- /**
- * java.util.Date#parse(java.lang.String)
- */
- public void test_parseLjava_lang_String() {
- // Test for method long java.util.Date.parse(java.lang.String)
- Date d = new Date(Date.parse("13 October 1998"));
- GregorianCalendar cal = new GregorianCalendar();
- cal.setTime(d);
- assertEquals("Parsed incorrect month", 9, cal.get(Calendar.MONTH));
- assertEquals("Parsed incorrect year", 1998, cal.get(Calendar.YEAR));
- assertEquals("Parsed incorrect date", 13, cal.get(Calendar.DATE));
-
- d = new Date(Date.parse("Jan-12 1999"));
- assertTrue("Wrong parsed date 1", d.equals(new GregorianCalendar(1999,
- 0, 12).getTime()));
- d = new Date(Date.parse("Jan12-1999"));
- assertTrue("Wrong parsed date 2", d.equals(new GregorianCalendar(1999,
- 0, 12).getTime()));
- d = new Date(Date.parse("Jan12 69-1"));
- cal.setTimeZone(TimeZone.getTimeZone("GMT"));
- cal.clear();
- cal.set(1969, Calendar.JANUARY, 12, 1, 0);
- assertTrue("Wrong parsed date 3", d.equals(cal.getTime()));
- d = new Date(Date.parse("6:45:13 3/2/1200 MST"));
- cal.setTimeZone(TimeZone.getTimeZone("MST"));
- cal.clear();
- cal.set(1200, 2, 2, 6, 45, 13);
- assertTrue("Wrong parsed date 4", d.equals(cal.getTime()));
- d = new Date(Date.parse("Mon, 22 Nov 1999 12:52:06 GMT"));
- cal.setTimeZone(TimeZone.getTimeZone("GMT"));
- cal.clear();
- cal.set(1999, Calendar.NOVEMBER, 22, 12, 52, 06);
- assertTrue("Wrong parsed date 5", d.equals(cal.getTime()));
-
- try {
- // Regression for HARMONY-259
- Date.parse(null);
- fail("Date.parse(null) should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * java.util.Date#setDate(int)
- */
- public void test_setDateI() {
- // Test for method void java.util.Date.setDate(int)
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- d.setDate(23);
- assertEquals("Set incorrect date", 23, d.getDate());
- }
-
- /**
- * java.util.Date#setHours(int)
- */
- public void test_setHoursI() {
- // Test for method void java.util.Date.setHours(int)
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- d.setHours(23);
- assertEquals("Set incorrect hours", 23, d.getHours());
- }
-
- /**
- * java.util.Date#setMinutes(int)
- */
- public void test_setMinutesI() {
- // Test for method void java.util.Date.setMinutes(int)
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- d.setMinutes(45);
- assertEquals("Set incorrect mins", 45, d.getMinutes());
- }
-
- /**
- * java.util.Date#setMonth(int)
- */
- public void test_setMonthI() {
- // Test for method void java.util.Date.setMonth(int)
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- d.setMonth(0);
- assertEquals("Set incorrect month", 0, d.getMonth());
- }
-
- /**
- * java.util.Date#setSeconds(int)
- */
- public void test_setSecondsI() {
- // Test for method void java.util.Date.setSeconds(int)
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- d.setSeconds(13);
- assertEquals("Set incorrect seconds", 13, d.getSeconds());
- }
-
- /**
- * java.util.Date#setTime(long)
- */
- public void test_setTimeJ() {
- // Test for method void java.util.Date.setTime(long)
- Date d1 = new Date(0);
- Date d2 = new Date(1900000);
- d1.setTime(900);
- d2.setTime(890000);
- assertEquals("Returned incorrect time", 890000, d2.getTime());
- assertEquals("Returned incorrect time", 900, d1.getTime());
- }
-
- /**
- * java.util.Date#setYear(int)
- */
- public void test_setYearI() {
- // Test for method void java.util.Date.setYear(int)
- Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
- .getTime();
- d.setYear(8);
- assertEquals("Set incorrect year", 8, d.getYear());
- }
-
- /**
- * java.util.Date#toGMTString()
- */
- public void test_toGMTString() {
- // Test for method java.lang.String java.util.Date.toGMTString()
- assertEquals("Did not convert epoch to GMT string correctly", "1 Jan 1970 00:00:00 GMT", new Date(0)
- .toGMTString());
- assertEquals("Did not convert epoch + 1yr to GMT string correctly",
- "1 Jan 1971 00:00:00 GMT", new Date((long) 365 * 24 * 60 * 60 * 1000).toGMTString()
- );
- }
-
- /**
- * java.util.Date#toString()
- */
- public void test_toString() {
- // Test for method java.lang.String java.util.Date.toString()
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.MONTH, Calendar.JANUARY);
- cal.set(Calendar.YEAR, 1970);
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- Date d = cal.getTime();
- String result = d.toString();
- assertTrue("Incorrect result: " + d, result
- .startsWith("Thu Jan 01 00:00:00")
- && result.endsWith("1970"));
-
- TimeZone tz = TimeZone.getDefault();
- TimeZone.setDefault(TimeZone.getTimeZone("GMT-5"));
- try {
- Date d1 = new Date(0);
- assertTrue("Returned incorrect string: " + d1, d1.toString()
- .equals("Wed Dec 31 19:00:00 GMT-05:00 1969"));
- } finally {
- TimeZone.setDefault(tz);
- }
- }
-
- /**
- * java.util.Date#UTC(int, int, int, int, int, int)
- */
- public void test_UTCIIIIII() {
- // Test for method long java.util.Date.UTC(int, int, int, int, int, int)
- assertTrue("Returned incorrect UTC value for epoch", Date.UTC(70, 0, 1,
- 0, 0, 0) == (long) 0);
- assertTrue("Returned incorrect UTC value for epoch +1yr", Date.UTC(71,
- 0, 1, 0, 0, 0) == (long) 365 * 24 * 60 * 60 * 1000);
- }
- /**
- * java.util.Date#toLocaleString() Test for method java.lang.String
- * java.util.Date.toGMTString()
- */
- public void test_toLocaleString() {
- Locale loc = Locale.getDefault();
- Locale.setDefault(Locale.US);
- TimeZone tz = TimeZone.getDefault();
- TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
- try {
- assertEquals("Did not convert epoch to GMT string correctly", "Jan 1, 1970 12:00:00 AM",
- new Date(0).toLocaleString());
- assertEquals("Did not convert epoch + 1yr to GMT string correctly",
- "Jan 1, 1971 12:00:00 AM", new Date((long)365 * 24 * 60 * 60 * 1000)
- .toLocaleString());
- } finally {
- Locale.setDefault(loc);
- TimeZone.setDefault(tz);
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/EmptyStackExceptionTest.java b/luni/src/test/java/tests/api/java/util/EmptyStackExceptionTest.java
deleted file mode 100644
index 31ee1e2..0000000
--- a/luni/src/test/java/tests/api/java/util/EmptyStackExceptionTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.EmptyStackException;
-import java.util.Stack;
-
-public class EmptyStackExceptionTest extends junit.framework.TestCase {
-
- Object[] objArray = new Object[10];
- Stack s;
-
- /**
- * java.util.EmptyStackException#EmptyStackException()
- */
- public void test_Constructor() {
- // Test for method java.util.EmptyStackException()
- try {
- for (int counter = 0; counter < objArray.length + 1; counter++)
- s.pop();
- } catch (EmptyStackException e) {
- return;
- }
- fail("Expected EmptyStackException not thrown");
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- for (int counter = 0; counter < objArray.length; counter++) {
- objArray[counter] = new Integer(counter);
- }
-
- s = new Stack();
- for (int counter = 0; counter < objArray.length; counter++) {
- s.push(objArray[counter]);
- }
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- objArray = null;
- s = null;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/EnumMapTest.java b/luni/src/test/java/tests/api/java/util/EnumMapTest.java
deleted file mode 100644
index 05826d1..0000000
--- a/luni/src/test/java/tests/api/java/util/EnumMapTest.java
+++ /dev/null
@@ -1,1175 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import dalvik.annotation.AndroidOnly;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-import junit.framework.TestCase;
-
-public class EnumMapTest extends TestCase {
- enum Size {
- Small, Middle, Big {};
- }
-
- enum Color {
- Red, Green, Blue {};
- }
-
- enum Empty {
- //Empty
- }
-
- private static class MockEntry<K, V> implements Map.Entry<K, V> {
- private K key;
-
- private V value;
-
- public MockEntry(K key, V value) {
- this.key = key;
- this.value = value;
- }
-
- @Override
- public int hashCode() {
- return (key == null ? 0 : key.hashCode())
- ^ (value == null ? 0 : value.hashCode());
- }
-
- public K getKey() {
- return key;
- }
-
- public V getValue() {
- return value;
- }
-
- public V setValue(V object) {
- V oldValue = value;
- value = object;
- return oldValue;
- }
- }
-
- /**
- * java.util.EnumMap#EnumMap(Class)
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_ConstructorLjava_lang_Class() {
- try {
- new EnumMap((Class) null);
- fail("Expected NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
-
-
- try {
- new EnumMap(Size.Big.getClass());
- fail("Expected NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
-
- try {
- new EnumMap(Integer.class);
- fail("Expected NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
-
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- assertNull("Return non-null for non mapped key", enumColorMap.put(
- Color.Green, 2));
- assertEquals("Get returned incorrect value for given key", 2,
- enumColorMap.get(Color.Green));
-
- EnumMap enumEmptyMap = new EnumMap<Empty, Double>(Empty.class);
- try {
- enumEmptyMap.put(Color.Red, 2);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
-
- EnumMap enumSizeMap = new EnumMap(Size.class);
- assertNull("Return non-null for non mapped key", enumSizeMap.put(
- Size.Big, 2));
- assertEquals("Get returned incorrect value for given key", 2,
- enumSizeMap.get(Size.Big));
- try {
- enumSizeMap.put(Color.Red, 2);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
-
- enumSizeMap = new EnumMap(Size.Middle.getClass());
- assertNull("Return non-null for non mapped key", enumSizeMap.put(
- Size.Small, 1));
- assertEquals("Get returned incorrect value for given key", 1,
- enumSizeMap.get(Size.Small));
- try {
- enumSizeMap.put(Color.Red, 2);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
- }
-
- /**
- * java.util.EnumMap#EnumMap(EnumMap)
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_ConstructorLjava_util_EnumMap() {
- EnumMap enumMap;
- EnumMap enumColorMap = null;
- try {
- enumMap = new EnumMap(enumColorMap);
- fail("Expected NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
-
- enumColorMap = new EnumMap<Color, Double>(Color.class);
- Double double1 = new Double(1);
- enumColorMap.put(Color.Green, 2);
- enumColorMap.put(Color.Blue, double1);
-
- enumMap = new EnumMap(enumColorMap);
- assertEquals("Constructor fails", 2, enumMap.get(Color.Green));
- assertSame("Constructor fails", double1, enumMap.get(Color.Blue));
- assertNull("Constructor fails", enumMap.get(Color.Red));
- enumMap.put(Color.Red, 1);
- assertEquals("Wrong value", 1, enumMap.get(Color.Red));
-
- try {
- enumMap.put(Size.Middle, 2);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
- }
-
- /**
- * java.util.EnumMap#EnumMap(Map)
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_ConstructorLjava_util_Map() {
- EnumMap enumMap;
- Map enumColorMap = null;
- try {
- enumMap = new EnumMap(enumColorMap);
- fail("Expected NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- enumColorMap = new EnumMap<Color, Double>(Color.class);
- enumMap = new EnumMap(enumColorMap);
- enumColorMap.put(Color.Blue, 3);
- enumMap = new EnumMap(enumColorMap);
-
- HashMap hashColorMap = null;
- try {
- enumMap = new EnumMap(hashColorMap);
- fail("Expected NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
-
- hashColorMap = new HashMap();
- try {
- enumMap = new EnumMap(hashColorMap);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected
- }
-
- hashColorMap.put(Color.Green, 2);
- enumMap = new EnumMap(hashColorMap);
- assertEquals("Constructor fails", 2, enumMap.get(Color.Green));
- assertNull("Constructor fails", enumMap.get(Color.Red));
- enumMap.put(Color.Red, 1);
- assertEquals("Wrong value", 1, enumMap.get(Color.Red));
- hashColorMap.put(Size.Big, 3);
- try {
- enumMap = new EnumMap(hashColorMap);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
-
- hashColorMap = new HashMap();
- hashColorMap.put(new Integer(1), 1);
- try {
- enumMap = new EnumMap(hashColorMap);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
- }
-
- /**
- * java.util.EnumMap#clear()
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_clear() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Small, 1);
- enumSizeMap.clear();
- assertNull("Failed to clear all elements", enumSizeMap.get(Size.Small));
- }
-
- /**
- * java.util.EnumMap#containsKey(Object)
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void test_containsKeyLjava_lang_Object() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- assertFalse("Returned true for uncontained key", enumSizeMap
- .containsKey(Size.Small));
- enumSizeMap.put(Size.Small, 1);
- assertTrue("Returned false for contained key", enumSizeMap
- .containsKey(Size.Small));
-
- enumSizeMap.put(Size.Big, null);
- assertTrue("Returned false for contained key", enumSizeMap
- .containsKey(Size.Big));
-
- assertFalse("Returned true for uncontained key", enumSizeMap
- .containsKey(Color.Red));
- assertFalse("Returned true for uncontained key", enumSizeMap
- .containsKey(new Integer("3")));
- assertFalse("Returned true for uncontained key", enumSizeMap
- .containsKey(null));
- }
-
- /**
- * java.util.EnumMap#clone()
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void test_clone() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- Integer integer = new Integer("3");
- enumSizeMap.put(Size.Small, integer);
- EnumMap enumSizeMapClone = enumSizeMap.clone();
- assertNotSame("Should not be same", enumSizeMap, enumSizeMapClone);
- assertEquals("Clone answered unequal EnumMap", enumSizeMap,
- enumSizeMapClone);
-
- assertSame("Should be same", enumSizeMap.get(Size.Small),
- enumSizeMapClone.get(Size.Small));
- assertSame("Clone is not shallow clone", integer, enumSizeMapClone
- .get(Size.Small));
- enumSizeMap.remove(Size.Small);
- assertSame("Clone is not shallow clone", integer, enumSizeMapClone
- .get(Size.Small));
- }
-
- /**
- * java.util.EnumMap#containsValue(Object)
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void test_containsValueLjava_lang_Object() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- Double double1 = new Double(3);
- Double double2 = new Double(3);
-
- assertFalse("Returned true for uncontained value", enumSizeMap
- .containsValue(double1));
- enumSizeMap.put(Size.Middle, 2);
- enumSizeMap.put(Size.Small, double1);
- assertTrue("Returned false for contained value", enumSizeMap
- .containsValue(double1));
- assertTrue("Returned false for contained value", enumSizeMap
- .containsValue(double2));
- assertTrue("Returned false for contained value", enumSizeMap
- .containsValue(2));
- assertFalse("Returned true for uncontained value", enumSizeMap
- .containsValue(1));
-
- assertFalse("Returned true for uncontained value", enumSizeMap
- .containsValue(null));
- enumSizeMap.put(Size.Big, null);
- assertTrue("Returned false for contained value", enumSizeMap
- .containsValue(null));
- }
-
- /**
- * java.util.EnumMap#entrySet()
- */
- @AndroidOnly("Map.Entry is indirectly modified on RI when Iterator.next() is invoked")
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_entrySet() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- MockEntry mockEntry = new MockEntry(Size.Middle, 1);
- Set set = enumSizeMap.entrySet();
-
- Set set1 = enumSizeMap.entrySet();
- assertSame("Should be same", set1, set);
- try {
- set.add(mockEntry);
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
-
- assertTrue("Returned false for contained object", set
- .contains(mockEntry));
- mockEntry = new MockEntry(Size.Middle, null);
- assertFalse("Returned true for uncontained object", set
- .contains(mockEntry));
- assertFalse("Returned true for uncontained object", set
- .contains(Size.Small));
- mockEntry = new MockEntry(new Integer(1), 1);
- assertFalse("Returned true for uncontained object", set
- .contains(mockEntry));
- assertFalse("Returned true for uncontained object", set
- .contains(new Integer(1)));
-
- mockEntry = new MockEntry(Size.Big, null);
- assertTrue("Returned false for contained object", set
- .contains(mockEntry));
- assertTrue("Returned false when the object can be removed", set
- .remove(mockEntry));
- assertFalse("Returned true for uncontained object", set
- .contains(mockEntry));
- assertFalse("Returned true when the object can not be removed", set
- .remove(mockEntry));
- mockEntry = new MockEntry(new Integer(1), 1);
- assertFalse("Returned true when the object can not be removed", set
- .remove(mockEntry));
- assertFalse("Returned true when the object can not be removed", set
- .remove(new Integer(1)));
-
- // The set is backed by the map so changes to one are reflected by the
- // other.
- enumSizeMap.put(Size.Big, 3);
- mockEntry = new MockEntry(Size.Big, 3);
- assertTrue("Returned false for contained object", set
- .contains(mockEntry));
- enumSizeMap.remove(Size.Big);
- assertFalse("Returned true for uncontained object", set
- .contains(mockEntry));
-
- assertEquals("Wrong size", 1, set.size());
- set.clear();
- assertEquals("Wrong size", 0, set.size());
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.entrySet();
- Collection c = new ArrayList();
- c.add(new MockEntry(Size.Middle, 1));
- assertTrue("Return wrong value", set.containsAll(c));
- assertTrue("Remove does not success", set.removeAll(c));
-
- enumSizeMap.put(Size.Middle, 1);
- c.add(new MockEntry(Size.Big, 3));
- assertTrue("Remove does not success", set.removeAll(c));
- assertFalse("Should return false", set.removeAll(c));
- assertEquals("Wrong size", 1, set.size());
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.entrySet();
- c = new ArrayList();
- c.add(new MockEntry(Size.Middle, 1));
- c.add(new MockEntry(Size.Big, 3));
-
- assertTrue("Retain does not success", set.retainAll(c));
- assertEquals("Wrong size", 1, set.size());
- assertFalse("Should return false", set.retainAll(c));
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
-
- set = enumSizeMap.entrySet();
- Object[] array = set.toArray();
- assertEquals("Wrong length", 2, array.length);
- Map.Entry entry = (Map.Entry) array[0];
- assertEquals("Wrong key", Size.Middle, entry.getKey());
- assertEquals("Wrong value", 1, entry.getValue());
-
- Object[] array1 = new Object[10];
- array1 = set.toArray();
- assertEquals("Wrong length", 2, array1.length);
- entry = (Map.Entry) array[0];
- assertEquals("Wrong key", Size.Middle, entry.getKey());
- assertEquals("Wrong value", 1, entry.getValue());
-
- array1 = new Object[10];
- array1 = set.toArray(array1);
- assertEquals("Wrong length", 10, array1.length);
- entry = (Map.Entry) array[1];
- assertEquals("Wrong key", Size.Big, entry.getKey());
- assertNull("Should be null", array1[2]);
-
- set = enumSizeMap.entrySet();
- Integer integer = new Integer("1");
- assertFalse("Returned true when the object can not be removed", set
- .remove(integer));
- assertTrue("Returned false when the object can be removed", set
- .remove(entry));
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.entrySet();
- Iterator iter = set.iterator();
- entry = (Map.Entry) iter.next();
- assertTrue("Returned false for contained object", set.contains(entry));
- mockEntry = new MockEntry(Size.Middle, 2);
- assertFalse("Returned true for uncontained object", set
- .contains(mockEntry));
- mockEntry = new MockEntry(new Integer(2), 2);
- assertFalse("Returned true for uncontained object", set
- .contains(mockEntry));
- entry = (Map.Entry) iter.next();
- assertTrue("Returned false for contained object", set.contains(entry));
-
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.remove(Size.Big);
- mockEntry = new MockEntry(Size.Big, null);
- assertEquals("Wrong size", 1, set.size());
- assertFalse("Returned true for uncontained object", set.contains(mockEntry));
- enumSizeMap.put(Size.Big, 2);
- mockEntry = new MockEntry(Size.Big, 2);
- assertTrue("Returned false for contained object", set
- .contains(mockEntry));
-
- iter.remove();
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- try {
- entry.setValue(2);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- try {
- set.contains(entry);
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.entrySet();
- iter = set.iterator();
- entry = (Map.Entry) iter.next();
- assertEquals("Wrong key", Size.Middle, entry.getKey());
-
- assertTrue("Returned false for contained object", set.contains(entry));
- enumSizeMap.put(Size.Middle, 3);
- assertTrue("Returned false for contained object", set.contains(entry));
- entry.setValue(2);
- assertTrue("Returned false for contained object", set.contains(entry));
- assertFalse("Returned true for uncontained object", set
- .remove(new Integer(1)));
-
- iter.next();
- assertEquals("Wrong key", Size.Middle, entry.getKey());
- set.clear();
- assertEquals("Wrong size", 0, set.size());
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.entrySet();
- iter = set.iterator();
- mockEntry = new MockEntry(Size.Middle, 1);
-
- assertFalse("Wrong result", entry.equals(mockEntry));
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- entry = (Map.Entry) iter.next();
- assertEquals("Wrong key", Size.Middle, entry.getKey());
- assertTrue("Should return true", entry.equals(mockEntry));
- assertEquals("Should be equal", mockEntry.hashCode(), entry.hashCode());
- mockEntry = new MockEntry(Size.Big, 1);
- assertFalse("Wrong result", entry.equals(mockEntry));
-
- entry = (Map.Entry) iter.next();
- assertFalse("Wrong result", entry.equals(mockEntry));
- assertEquals("Wrong key", Size.Big, entry.getKey());
- iter.remove();
- assertFalse("Wrong result", entry.equals(mockEntry));
- assertEquals("Wrong size", 1, set.size());
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- try {
- iter.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // Expected
- }
- }
-
- /**
- * java.util.EnumMap#equals(Object)
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void test_equalsLjava_lang_Object() {
- EnumMap enumMap = new EnumMap(Size.class);
- enumMap.put(Size.Small, 1);
-
- EnumMap enumSizeMap = new EnumMap(Size.class);
- assertFalse("Returned true for unequal EnumMap", enumSizeMap
- .equals(enumMap));
- enumSizeMap.put(Size.Small, 1);
- assertTrue("Returned false for equal EnumMap", enumSizeMap
- .equals(enumMap));
- enumSizeMap.put(Size.Big, null);
- assertFalse("Returned true for unequal EnumMap", enumSizeMap
- .equals(enumMap));
-
- enumMap.put(Size.Middle, null);
- assertFalse("Returned true for unequal EnumMap", enumSizeMap
- .equals(enumMap));
- enumMap.remove(Size.Middle);
- enumMap.put(Size.Big, 3);
- assertFalse("Returned true for unequal EnumMap", enumSizeMap
- .equals(enumMap));
- enumMap.put(Size.Big, null);
- assertTrue("Returned false for equal EnumMap", enumSizeMap
- .equals(enumMap));
-
- HashMap hashMap = new HashMap();
- hashMap.put(Size.Small, 1);
- assertFalse("Returned true for unequal EnumMap", hashMap
- .equals(enumMap));
- hashMap.put(Size.Big, null);
- assertTrue("Returned false for equal EnumMap", enumMap.equals(hashMap));
-
- assertFalse("Should return false", enumSizeMap
- .equals(new Integer(1)));
- }
-
- /**
- * java.util.EnumMap#keySet()
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void test_keySet() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 2);
- enumSizeMap.put(Size.Big, null);
- Set set = enumSizeMap.keySet();
-
- Set set1 = enumSizeMap.keySet();
- assertSame("Should be same", set1, set);
- try {
- set.add(Size.Big);
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
-
- assertTrue("Returned false for contained object", set
- .contains(Size.Middle));
- assertTrue("Returned false for contained object", set
- .contains(Size.Big));
- assertFalse("Returned true for uncontained object", set
- .contains(Size.Small));
- assertFalse("Returned true for uncontained object", set
- .contains(new Integer(1)));
- assertTrue("Returned false when the object can be removed", set
- .remove(Size.Big));
- assertFalse("Returned true for uncontained object", set
- .contains(Size.Big));
- assertFalse("Returned true when the object can not be removed", set
- .remove(Size.Big));
- assertFalse("Returned true when the object can not be removed", set
- .remove(new Integer(1)));
-
- // The set is backed by the map so changes to one are reflected by the
- // other.
- enumSizeMap.put(Size.Big, 3);
- assertTrue("Returned false for contained object", set
- .contains(Size.Big));
- enumSizeMap.remove(Size.Big);
- assertFalse("Returned true for uncontained object", set
- .contains(Size.Big));
-
- assertEquals("Wrong size", 1, set.size());
- set.clear();
- assertEquals("Wrong size", 0, set.size());
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.keySet();
- Collection c = new ArrayList();
- c.add(Size.Big);
- assertTrue("Should return true", set.containsAll(c));
- c.add(Size.Small);
- assertFalse("Should return false", set.containsAll(c));
- assertTrue("Should return true", set.removeAll(c));
- assertEquals("Wrong size", 1, set.size());
- assertFalse("Should return false", set.removeAll(c));
- assertEquals("Wrong size", 1, set.size());
- try {
- set.addAll(c);
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
-
- enumSizeMap.put(Size.Big, null);
- assertEquals("Wrong size", 2, set.size());
- assertTrue("Should return true", set.retainAll(c));
- assertEquals("Wrong size", 1, set.size());
- assertFalse("Should return false", set.retainAll(c));
- assertEquals(1, set.size());
- Object[] array = set.toArray();
- assertEquals("Wrong length", 1, array.length);
- assertEquals("Wrong key", Size.Big, array[0]);
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.keySet();
- c = new ArrayList();
- c.add(Color.Blue);
- assertFalse("Should return false", set.remove(c));
- assertEquals("Wrong size", 2, set.size());
- assertTrue("Should return true", set.retainAll(c));
- assertEquals("Wrong size", 0, set.size());
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.keySet();
-
- Iterator iter = set.iterator();
- Enum enumKey = (Enum) iter.next();
- assertTrue("Returned false for contained object", set.contains(enumKey));
- enumKey = (Enum) iter.next();
- assertTrue("Returned false for contained object", set.contains(enumKey));
-
- enumSizeMap.remove(Size.Big);
- assertFalse("Returned true for uncontained object", set
- .contains(enumKey));
- iter.remove();
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- assertFalse("Returned true for uncontained object", set
- .contains(enumKey));
-
- iter = set.iterator();
- enumKey = (Enum) iter.next();
- assertTrue("Returned false for contained object", set.contains(enumKey));
- enumSizeMap.put(Size.Middle, 3);
- assertTrue("Returned false for contained object", set.contains(enumKey));
-
- enumSizeMap = new EnumMap(Size.class);
- enumSizeMap.put(Size.Middle, 1);
- enumSizeMap.put(Size.Big, null);
- set = enumSizeMap.keySet();
- iter = set.iterator();
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- enumKey = (Enum) iter.next();
- assertEquals("Wrong key", Size.Middle, enumKey);
- assertSame("Wrong key", Size.Middle, enumKey);
- assertFalse("Returned true for unequal object", iter.equals(enumKey));
- iter.remove();
- assertFalse("Returned true for uncontained object", set
- .contains(enumKey));
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
-
- assertEquals("Wrong size", 1, set.size());
- enumKey = (Enum) iter.next();
- assertEquals("Wrong key", Size.Big, enumKey);
- iter.remove();
- try {
- iter.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // Expected
- }
- }
-
- /**
- * java.util.EnumMap#get(Object)
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_getLjava_lang_Object() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- assertNull("Get returned non-null for non mapped key", enumSizeMap
- .get(Size.Big));
- enumSizeMap.put(Size.Big, 1);
- assertEquals("Get returned incorrect value for given key", 1,
- enumSizeMap.get(Size.Big));
-
- assertNull("Get returned non-null for non mapped key", enumSizeMap
- .get(Size.Small));
- assertNull("Get returned non-null for non existent key", enumSizeMap
- .get(Color.Red));
- assertNull("Get returned non-null for non existent key", enumSizeMap
- .get(new Integer(1)));
- assertNull("Get returned non-null for non existent key", enumSizeMap
- .get(null));
-
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- assertNull("Get returned non-null for non mapped key", enumColorMap
- .get(Color.Green));
- enumColorMap.put(Color.Green, 2);
- assertEquals("Get returned incorrect value for given key", 2,
- enumColorMap.get(Color.Green));
- assertNull("Get returned non-null for non mapped key", enumColorMap
- .get(Color.Blue));
-
- enumColorMap.put(Color.Green, new Double(4));
- assertEquals("Get returned incorrect value for given key",
- new Double(4), enumColorMap.get(Color.Green));
- enumColorMap.put(Color.Green, new Integer("3"));
- assertEquals("Get returned incorrect value for given key", new Integer(
- "3"), enumColorMap.get(Color.Green));
- enumColorMap.put(Color.Green, null);
- assertNull("Can not handle null value", enumColorMap.get(Color.Green));
- Float f = new Float("3.4");
- enumColorMap.put(Color.Green, f);
- assertSame("Get returned incorrect value for given key", f,
- enumColorMap.get(Color.Green));
- }
-
- /**
- * java.util.EnumMap#put(Object,Object)
- */
- public void test_putLjava_lang_ObjectLjava_lang_Object() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- try {
- enumSizeMap.put(Color.Red, 2);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
- assertNull("Return non-null for non mapped key", enumSizeMap.put(
- Size.Small, 1));
-
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- try {
- enumColorMap.put(Size.Big, 2);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
- try {
- enumColorMap.put(null, 2);
- fail("Expected NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
- assertNull("Return non-null for non mapped key", enumColorMap.put(
- Color.Green, 2));
- assertEquals("Return wrong value", 2, enumColorMap.put(Color.Green,
- new Double(4)));
- assertEquals("Return wrong value", new Double(4), enumColorMap.put(
- Color.Green, new Integer("3")));
- assertEquals("Return wrong value", new Integer("3"), enumColorMap.put(
- Color.Green, null));
- Float f = new Float("3.4");
- assertNull("Return non-null for non mapped key", enumColorMap.put(
- Color.Green, f));
- assertNull("Return non-null for non mapped key", enumColorMap.put(
- Color.Blue, 2));
- assertEquals("Return wrong value", 2, enumColorMap.put(Color.Blue,
- new Double(4)));
- }
-
- /**
- * java.util.EnumMap#putAll(Map)
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_putAllLjava_util_Map() {
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- enumColorMap.put(Color.Green, 2);
-
- EnumMap enumSizeMap = new EnumMap(Size.class);
- enumColorMap.putAll(enumSizeMap);
-
- enumSizeMap.put(Size.Big, 1);
- try {
- enumColorMap.putAll(enumSizeMap);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
-
- EnumMap enumColorMap1 = new EnumMap<Color, Double>(Color.class);
- enumColorMap1.put(Color.Blue, 3);
- enumColorMap.putAll(enumColorMap1);
- assertEquals("Get returned incorrect value for given key", 3,
- enumColorMap.get(Color.Blue));
- assertEquals("Wrong Size", 2, enumColorMap.size());
-
- enumColorMap = new EnumMap<Color, Double>(Color.class);
-
- HashMap hashColorMap = null;
- try {
- enumColorMap.putAll(hashColorMap);
- fail("Expected NullPointerException");
- } catch (NullPointerException e) {
- // Expected
- }
-
- hashColorMap = new HashMap();
- enumColorMap.putAll(hashColorMap);
-
- hashColorMap.put(Color.Green, 2);
- enumColorMap.putAll(hashColorMap);
- assertEquals("Get returned incorrect value for given key", 2,
- enumColorMap.get(Color.Green));
- assertNull("Get returned non-null for non mapped key", enumColorMap
- .get(Color.Red));
- hashColorMap.put(Color.Red, new Integer(1));
- enumColorMap.putAll(hashColorMap);
- assertEquals("Get returned incorrect value for given key", new Integer(
- 2), enumColorMap.get(Color.Green));
- hashColorMap.put(Size.Big, 3);
- try {
- enumColorMap.putAll(hashColorMap);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
-
- hashColorMap = new HashMap();
- hashColorMap.put(new Integer(1), 1);
- try {
- enumColorMap.putAll(hashColorMap);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
- }
-
- /**
- * java.util.EnumMap#remove(Object)
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_removeLjava_lang_Object() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- assertNull("Remove of non-mapped key returned non-null", enumSizeMap
- .remove(Size.Big));
- enumSizeMap.put(Size.Big, 3);
- enumSizeMap.put(Size.Middle, 2);
-
- assertNull("Get returned non-null for non mapped key", enumSizeMap
- .get(Size.Small));
- assertEquals("Remove returned incorrect value", 3, enumSizeMap
- .remove(Size.Big));
- assertNull("Get returned non-null for non mapped key", enumSizeMap
- .get(Size.Big));
- assertNull("Remove of non-mapped key returned non-null", enumSizeMap
- .remove(Size.Big));
- assertNull("Remove of non-existent key returned non-null", enumSizeMap
- .remove(Color.Red));
- assertNull("Remove of non-existent key returned non-null", enumSizeMap
- .remove(new Double(4)));
- assertNull("Remove of non-existent key returned non-null", enumSizeMap
- .remove(null));
-
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- assertNull("Get returned non-null for non mapped key", enumColorMap
- .get(Color.Green));
- enumColorMap.put(Color.Green, new Double(4));
- assertEquals("Remove returned incorrect value", new Double(4),
- enumColorMap.remove(Color.Green));
- assertNull("Get returned non-null for non mapped key", enumColorMap
- .get(Color.Green));
- enumColorMap.put(Color.Green, null);
- assertNull("Can not handle null value", enumColorMap
- .remove(Color.Green));
- assertNull("Get returned non-null for non mapped key", enumColorMap
- .get(Color.Green));
- }
-
- /**
- * java.util.EnumMap#size()
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void test_size() {
- EnumMap enumSizeMap = new EnumMap(Size.class);
- assertEquals("Wrong size", 0, enumSizeMap.size());
- enumSizeMap.put(Size.Small, 1);
- assertEquals("Wrong size", 1, enumSizeMap.size());
- enumSizeMap.put(Size.Small, 0);
- assertEquals("Wrong size", 1, enumSizeMap.size());
- try {
- enumSizeMap.put(Color.Red, 2);
- fail("Expected ClassCastException");
- } catch (ClassCastException e) {
- // Expected
- }
- assertEquals("Wrong size", 1, enumSizeMap.size());
-
- enumSizeMap.put(Size.Middle, null);
- assertEquals("Wrong size", 2, enumSizeMap.size());
- enumSizeMap.remove(Size.Big);
- assertEquals("Wrong size", 2, enumSizeMap.size());
- enumSizeMap.remove(Size.Middle);
- assertEquals("Wrong size", 1, enumSizeMap.size());
- enumSizeMap.remove(Color.Green);
- assertEquals("Wrong size", 1, enumSizeMap.size());
-
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- enumColorMap.put(Color.Green, 2);
- assertEquals("Wrong size", 1, enumColorMap.size());
- enumColorMap.remove(Color.Green);
- assertEquals("Wrong size", 0, enumColorMap.size());
-
- EnumMap enumEmptyMap = new EnumMap<Empty, Double>(Empty.class);
- assertEquals("Wrong size", 0, enumEmptyMap.size());
- }
-
- /**
- * java.util.EnumMap#values()
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void test_values() {
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- enumColorMap.put(Color.Red, 1);
- enumColorMap.put(Color.Blue, null);
- Collection collection = enumColorMap.values();
-
- Collection collection1 = enumColorMap.values();
- assertSame("Should be same", collection1, collection);
- try {
- collection.add(new Integer(1));
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
-
- assertTrue("Returned false for contained object", collection
- .contains(1));
- assertTrue("Returned false for contained object", collection
- .contains(null));
- assertFalse("Returned true for uncontained object", collection
- .contains(2));
-
- assertTrue("Returned false when the object can be removed", collection
- .remove(null));
- assertFalse("Returned true for uncontained object", collection
- .contains(null));
- assertFalse("Returned true when the object can not be removed",
- collection.remove(null));
-
- // The set is backed by the map so changes to one are reflected by the
- // other.
- enumColorMap.put(Color.Blue, 3);
- assertTrue("Returned false for contained object", collection
- .contains(3));
- enumColorMap.remove(Color.Blue);
- assertFalse("Returned true for uncontained object", collection
- .contains(3));
-
- assertEquals("Wrong size", 1, collection.size());
- collection.clear();
- assertEquals("Wrong size", 0, collection.size());
-
- enumColorMap = new EnumMap<Color, Double>(Color.class);
- enumColorMap.put(Color.Red, 1);
- enumColorMap.put(Color.Blue, null);
- collection = enumColorMap.values();
- Collection c = new ArrayList();
- c.add(new Integer(1));
- assertTrue("Should return true", collection.containsAll(c));
- c.add(new Double(3.4));
- assertFalse("Should return false", collection.containsAll(c));
- assertTrue("Should return true", collection.removeAll(c));
- assertEquals("Wrong size", 1, collection.size());
- assertFalse("Should return false", collection.removeAll(c));
- assertEquals("Wrong size", 1, collection.size());
- try {
- collection.addAll(c);
- fail("Should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
-
- enumColorMap.put(Color.Red, 1);
- assertEquals("Wrong size", 2, collection.size());
- assertTrue("Should return true", collection.retainAll(c));
- assertEquals("Wrong size", 1, collection.size());
- assertFalse("Should return false", collection.retainAll(c));
- assertEquals(1, collection.size());
- Object[] array = collection.toArray();
- assertEquals("Wrong length", 1, array.length);
- assertEquals("Wrong key", 1, array[0]);
-
- enumColorMap = new EnumMap<Color, Double>(Color.class);
- enumColorMap.put(Color.Red, 1);
- enumColorMap.put(Color.Blue, null);
- collection = enumColorMap.values();
-
- assertEquals("Wrong size", 2, collection.size());
- assertFalse("Returned true when the object can not be removed",
- collection.remove(new Integer("10")));
-
- Iterator iter = enumColorMap.values().iterator();
- Object value = iter.next();
- assertTrue("Returned false for contained object", collection
- .contains(value));
- value = iter.next();
- assertTrue("Returned false for contained object", collection
- .contains(value));
-
- enumColorMap.put(Color.Green, 1);
- enumColorMap.remove(Color.Blue);
- assertFalse("Returned true for uncontained object", collection
- .contains(value));
- iter.remove();
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- assertFalse("Returned true for uncontained object", collection
- .contains(value));
-
- iter = enumColorMap.values().iterator();
- value = iter.next();
- assertTrue("Returned false for contained object", collection
- .contains(value));
- enumColorMap.put(Color.Green, 3);
- assertTrue("Returned false for contained object", collection
- .contains(value));
- assertTrue("Returned false for contained object", collection
- .remove(new Integer("1")));
- assertEquals("Wrong size", 1, collection.size());
- collection.clear();
- assertEquals("Wrong size", 0, collection.size());
-
- enumColorMap = new EnumMap<Color, Double>(Color.class);
- Integer integer1 = new Integer(1);
- enumColorMap.put(Color.Green, integer1);
- enumColorMap.put(Color.Blue, null);
- collection = enumColorMap.values();
- iter = enumColorMap.values().iterator();
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- value = iter.next();
- assertEquals("Wrong value", integer1, value);
- assertSame("Wrong value", integer1, value);
- assertFalse("Returned true for unequal object", iter.equals(value));
- iter.remove();
- assertFalse("Returned true for unequal object", iter.equals(value));
- try {
- iter.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // Expected
- }
- assertEquals("Wrong size", 1, collection.size());
- value = iter.next();
- assertFalse("Returned true for unequal object", iter.equals(value));
- iter.remove();
- try {
- iter.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // Expected
- }
- }
-
- /**
- * serialization/deserialization.
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void testSerializationSelf() throws Exception {
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- enumColorMap.put(Color.Blue, 3);
- SerializationTest.verifySelf(enumColorMap);
- }
-
- /**
- * serialization/deserialization compatibility with RI.
- */
- @SuppressWarnings({ "unchecked", "boxing" })
- public void testSerializationCompatibility() throws Exception {
- EnumMap enumColorMap = new EnumMap<Color, Double>(Color.class);
- enumColorMap.put(Color.Red, 1);
- enumColorMap.put(Color.Blue, 3);
- SerializationTest.verifyGolden(this, enumColorMap);
- }
-
- /**
- * Sets up the fixture.
- */
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- /**
- * Tears down the fixture.
- */
- @Override
- protected void tearDown() throws Exception{
- super.tearDown();
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/EnumSetTest.java b/luni/src/test/java/tests/api/java/util/EnumSetTest.java
deleted file mode 100644
index 2b33877..0000000
--- a/luni/src/test/java/tests/api/java/util/EnumSetTest.java
+++ /dev/null
@@ -1,2003 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-public class EnumSetTest extends TestCase {
- static final boolean disableRIBugs = true;
-
- static enum EnumWithInnerClass {
- a, b, c, d, e, f {
- },
- }
-
- enum EnumWithAllInnerClass {
- a {},
- b {},
- }
-
- static enum EnumFoo {
- a, b,c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, aa, bb, cc, dd, ee, ff, gg, hh, ii, jj, kk, ll,
- }
-
- static enum EmptyEnum {
- // expected
- }
-
- static enum HugeEnumWithInnerClass {
- a{}, b{}, c{}, d{}, e{}, f{}, g{}, h{}, i{}, j{}, k{}, l{}, m{}, n{}, o{}, p{}, q{}, r{}, s{}, t{}, u{}, v{}, w{}, x{}, y{}, z{}, A{}, B{}, C{}, D{}, E{}, F{}, G{}, H{}, I{}, J{}, K{}, L{}, M{}, N{}, O{}, P{}, Q{}, R{}, S{}, T{}, U{}, V{}, W{}, X{}, Y{}, Z{}, aa{}, bb{}, cc{}, dd{}, ee{}, ff{}, gg{}, hh{}, ii{}, jj{}, kk{}, ll{}, mm{},
- }
-
- static enum HugeEnum {
- a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, aa, bb, cc, dd, ee, ff, gg, hh, ii, jj, kk, ll, mm,
- }
-
- static enum HugeEnumCount {
- NO1, NO2, NO3, NO4, NO5, NO6, NO7, NO8, NO9, NO10, NO11, NO12, NO13, NO14, NO15, NO16, NO17, NO18, NO19, NO20,
- NO21, NO22, NO23, NO24, NO25, NO26, NO27, NO28, NO29, NO30, NO31, NO32, NO33, NO34, NO35, NO36, NO37, NO38, NO39, NO40,
- NO41, NO42, NO43, NO44, NO45, NO46, NO47, NO48, NO49, NO50, NO51, NO52, NO53, NO54, NO55, NO56, NO57, NO58, NO59, NO60,
- NO61, NO62, NO63, NO64, NO65, NO66, NO67, NO68, NO69, NO70, NO71, NO72, NO73, NO74, NO75, NO76, NO77, NO78, NO79, NO80,
- NO81, NO82, NO83, NO84, NO85, NO86, NO87, NO88, NO89, NO90, NO91, NO92, NO93, NO94, NO95, NO96, NO97, NO98, NO99, NO100,
- NO101, NO102, NO103, NO104, NO105, NO106, NO107, NO108, NO109, NO110, NO111, NO112, NO113, NO114, NO115, NO116, NO117, NO118, NO119, NO120,
- NO121, NO122, NO123, NO124, NO125, NO126, NO127, NO128, NO129, NO130,
- }
-
- /**
- * java.util.EnumSet#noneOf(java.lang.Class)
- */
- @SuppressWarnings("unchecked")
- public void test_NoneOf_LClass() {
- try {
- EnumSet.noneOf((Class) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- EnumSet.noneOf(Enum.class);
- fail("Should throw ClassCastException");
- } catch (ClassCastException cce) {
- // expected
- }
-
- Class<EnumWithAllInnerClass> c = (Class<EnumWithAllInnerClass>) EnumWithAllInnerClass.a
- .getClass();
- try {
- EnumSet.noneOf(c);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
-
- EnumSet<EnumWithAllInnerClass> setWithInnerClass = EnumSet
- .noneOf(EnumWithAllInnerClass.class);
- assertNotNull(setWithInnerClass);
-
- // test enum type with more than 64 elements
- Class<HugeEnumWithInnerClass> hc = (Class<HugeEnumWithInnerClass>) HugeEnumWithInnerClass.a
- .getClass();
- try {
- EnumSet.noneOf(hc);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
-
- EnumSet<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
- .noneOf(HugeEnumWithInnerClass.class);
- assertNotNull(hugeSetWithInnerClass);
- }
-
- /**
- * java.util.HugeEnumSet#iterator()
- */
- public void test_iterator_HugeEnumSet() {
- EnumSet<HugeEnumCount> set;
- Object[] array;
-
- // Test HugeEnumSet with 65 elements
- // which is more than the bits of Long
- set = EnumSet.range(HugeEnumCount.NO1, HugeEnumCount.NO65);
- array = set.toArray();
- for (HugeEnumCount count : set) {
- assertEquals(count, (HugeEnumCount) array[count.ordinal()]);
- }
-
- // Test HugeEnumSet with 130 elements
- // which is more than twice of the bits of Long
- set = EnumSet.range(HugeEnumCount.NO1, HugeEnumCount.NO130);
- array = set.toArray();
- for (HugeEnumCount count : set) {
- assertEquals(count, (HugeEnumCount) array[count.ordinal()]);
- }
- }
-
- public void testRemoveIteratorRemoveFromHugeEnumSet() {
- EnumSet<HugeEnumCount> set = EnumSet.noneOf(HugeEnumCount.class);
- set.add(HugeEnumCount.NO64);
- set.add(HugeEnumCount.NO65);
- set.add(HugeEnumCount.NO128);
- Iterator<HugeEnumCount> iterator = set.iterator();
- assertTrue(iterator.hasNext());
- assertEquals(HugeEnumCount.NO64, iterator.next());
- assertTrue(iterator.hasNext());
- iterator.remove();
- assertEquals(HugeEnumCount.NO65, iterator.next());
- assertTrue(iterator.hasNext());
- assertEquals(HugeEnumCount.NO128, iterator.next());
- assertFalse(iterator.hasNext());
- assertEquals(EnumSet.of(HugeEnumCount.NO65, HugeEnumCount.NO128), set);
- iterator.remove();
- assertEquals(EnumSet.of(HugeEnumCount.NO65), set);
- }
-
- /**
- * java.util.EnumSet#allOf(java.lang.Class)
- */
- @SuppressWarnings("unchecked")
- public void test_AllOf_LClass() {
- try {
- EnumSet.allOf((Class) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- EnumSet.allOf(Enum.class);
- fail("Should throw ClassCastException");
- } catch (ClassCastException cce) {
- // expected
- }
-
- EnumSet<EnumFoo> enumSet = EnumSet.allOf(EnumFoo.class);
- assertEquals("Size of enumSet should be 64", 64, enumSet.size());
-
- assertFalse(
- "enumSet should not contain null value", enumSet.contains(null));
- assertTrue(
- "enumSet should contain EnumFoo.a", enumSet.contains(EnumFoo.a));
- assertTrue(
- "enumSet should contain EnumFoo.b", enumSet.contains(EnumFoo.b));
-
- enumSet.add(EnumFoo.a);
- assertEquals("Should be equal", 64, enumSet.size());
-
- EnumSet<EnumFoo> anotherSet = EnumSet.allOf(EnumFoo.class);
- assertEquals("Should be equal", enumSet, anotherSet);
- assertNotSame("Should not be identical", enumSet, anotherSet);
-
- // test enum with more than 64 elements
- EnumSet<HugeEnum> hugeEnumSet = EnumSet.allOf(HugeEnum.class);
- assertEquals(65, hugeEnumSet.size());
-
- assertFalse(hugeEnumSet.contains(null));
- assertTrue(hugeEnumSet.contains(HugeEnum.a));
- assertTrue(hugeEnumSet.contains(HugeEnum.b));
-
- hugeEnumSet.add(HugeEnum.a);
- assertEquals(65, hugeEnumSet.size());
-
- EnumSet<HugeEnum> anotherHugeSet = EnumSet.allOf(HugeEnum.class);
- assertEquals(hugeEnumSet, anotherHugeSet);
- assertNotSame(hugeEnumSet, anotherHugeSet);
-
- }
-
- /**
- * java.util.EnumSet#add(E)
- */
- @SuppressWarnings("unchecked")
- public void test_add_E() {
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- set.add(EnumFoo.a);
- set.add(EnumFoo.b);
-
- try {
- set.add(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- // test enum type with more than 64 elements
- Set rawSet = set;
- try {
- rawSet.add(HugeEnumWithInnerClass.b);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
-
- set.clear();
- try {
- set.add(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- boolean result = set.add(EnumFoo.a);
- assertEquals("Size should be 1:", 1, set.size());
- assertTrue("Return value should be true", result);
-
- result = set.add(EnumFoo.a);
- assertEquals("Size should be 1:", 1, set.size());
- assertFalse("Return value should be false", result);
-
- set.add(EnumFoo.b);
- assertEquals("Size should be 2:", 2, set.size());
-
- rawSet = set;
- try {
- rawSet.add(EnumWithAllInnerClass.a);
- fail("Should throw ClassCastException");
- } catch(ClassCastException e) {
- // expected
- }
-
- try {
- rawSet.add(EnumWithInnerClass.a);
- fail("Should throw ClassCastException");
- } catch(ClassCastException e) {
- // expected
- }
-
- try {
- rawSet.add(new Object());
- fail("Should throw ClassCastException");
- } catch(ClassCastException e) {
- // expected
- }
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
- result = hugeSet.add(HugeEnum.a);
- assertTrue(result);
-
- result = hugeSet.add(HugeEnum.a);
- assertFalse(result);
-
- try {
- hugeSet.add(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- rawSet = hugeSet;
- try {
- rawSet.add(HugeEnumWithInnerClass.b);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
-
- try {
- rawSet.add(new Object());
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
-
- result = hugeSet.add(HugeEnum.mm);
- assertTrue(result);
- result = hugeSet.add(HugeEnum.mm);
- assertFalse(result);
- assertEquals(2, hugeSet.size());
-
- }
-
- /**
- * java.util.EnumSet#addAll(Collection)
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void test_addAll_LCollection() {
-
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- assertEquals("Size should be 0:", 0, set.size());
-
- try {
- set.addAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- Set emptySet = EnumSet.noneOf(EmptyEnum.class);
- Enum[] elements = EmptyEnum.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- emptySet.add(elements[i]);
- }
- boolean result = set.addAll(emptySet);
- assertFalse(result);
-
- Collection<EnumFoo> collection = new ArrayList<EnumFoo>();
- collection.add(EnumFoo.a);
- collection.add(EnumFoo.b);
- result = set.addAll(collection);
- assertTrue("addAll should be successful", result);
- assertEquals("Size should be 2:", 2, set.size());
-
- set = EnumSet.noneOf(EnumFoo.class);
-
- Collection rawCollection = new ArrayList<Integer>();
- result = set.addAll(rawCollection);
- assertFalse(result);
- rawCollection.add(1);
- try {
- set.addAll(rawCollection);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
-
- Set<EnumFoo> fullSet = EnumSet.noneOf(EnumFoo.class);
- fullSet.add(EnumFoo.a);
- fullSet.add(EnumFoo.b);
- result = set.addAll(fullSet);
- assertTrue("addAll should be successful", result);
- assertEquals("Size of set should be 2", 2, set.size());
-
- try {
- fullSet.addAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- Set fullSetWithSubclass = EnumSet.noneOf(EnumWithInnerClass.class);
- elements = EnumWithInnerClass.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- fullSetWithSubclass.add(elements[i]);
- }
- try {
- set.addAll(fullSetWithSubclass);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
- Set<EnumWithInnerClass> setWithSubclass = fullSetWithSubclass;
- result = setWithSubclass.addAll(setWithSubclass);
- assertFalse("Should return false", result);
-
- Set<EnumWithInnerClass> anotherSetWithSubclass = EnumSet
- .noneOf(EnumWithInnerClass.class);
- elements = EnumWithInnerClass.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- anotherSetWithSubclass.add((EnumWithInnerClass) elements[i]);
- }
- result = setWithSubclass.addAll(anotherSetWithSubclass);
- assertFalse("Should return false", result);
-
- anotherSetWithSubclass.remove(EnumWithInnerClass.a);
- result = setWithSubclass.addAll(anotherSetWithSubclass);
- assertFalse("Should return false", result);
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
- assertEquals(0, hugeSet.size());
-
- try {
- hugeSet.addAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- hugeSet = EnumSet.allOf(HugeEnum.class);
- result = hugeSet.addAll(hugeSet);
- assertFalse(result);
-
- hugeSet = EnumSet.noneOf(HugeEnum.class);
- Collection<HugeEnum> hugeCollection = new ArrayList<HugeEnum>();
- hugeCollection.add(HugeEnum.a);
- hugeCollection.add(HugeEnum.b);
- result = hugeSet.addAll(hugeCollection);
- assertTrue(result);
- assertEquals(2, set.size());
-
- hugeSet = EnumSet.noneOf(HugeEnum.class);
-
- rawCollection = new ArrayList<Integer>();
- result = hugeSet.addAll(rawCollection);
- assertFalse(result);
- rawCollection.add(1);
- try {
- hugeSet.addAll(rawCollection);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
-
- EnumSet<HugeEnum> aHugeSet = EnumSet.noneOf(HugeEnum.class);
- aHugeSet.add(HugeEnum.a);
- aHugeSet.add(HugeEnum.b);
- result = hugeSet.addAll(aHugeSet);
- assertTrue(result);
- assertEquals(2, hugeSet.size());
-
- try {
- aHugeSet.addAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- Set hugeSetWithSubclass = EnumSet.allOf(HugeEnumWithInnerClass.class);
- try {
- hugeSet.addAll(hugeSetWithSubclass);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
- Set<HugeEnumWithInnerClass> hugeSetWithInnerSubclass = hugeSetWithSubclass;
- result = hugeSetWithInnerSubclass.addAll(hugeSetWithInnerSubclass);
- assertFalse(result);
-
- Set<HugeEnumWithInnerClass> anotherHugeSetWithSubclass = EnumSet
- .allOf(HugeEnumWithInnerClass.class);
- result = hugeSetWithSubclass.addAll(anotherHugeSetWithSubclass);
- assertFalse(result);
-
- anotherHugeSetWithSubclass.remove(HugeEnumWithInnerClass.a);
- result = setWithSubclass.addAll(anotherSetWithSubclass);
- assertFalse(result);
-
- }
-
- /**
- * java.util.EnumSet#remove(Object)
- */
- public void test_remove_LOject() {
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- Enum[] elements = EnumFoo.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- set.add((EnumFoo) elements[i]);
- }
-
- boolean result = set.remove(null);
- assertFalse("'set' does not contain null", result);
-
- result = set.remove(EnumFoo.a);
- assertTrue("Should return true", result);
- result = set.remove(EnumFoo.a);
- assertFalse("Should return false", result);
-
- assertEquals("Size of set should be 63:", 63, set.size());
-
- result = set.remove(EnumWithInnerClass.a);
- assertFalse("Should return false", result);
- result = set.remove(EnumWithInnerClass.f);
- assertFalse("Should return false", result);
-
- // test enum with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
-
- result = hugeSet.remove(null);
- assertFalse("'set' does not contain null", result);
-
- result = hugeSet.remove(HugeEnum.a);
- assertTrue("Should return true", result);
- result = hugeSet.remove(HugeEnum.a);
- assertFalse("Should return false", result);
-
- assertEquals("Size of set should be 64:", 64, hugeSet.size());
-
- result = hugeSet.remove(HugeEnumWithInnerClass.a);
- assertFalse("Should return false", result);
- result = hugeSet.remove(HugeEnumWithInnerClass.f);
- assertFalse("Should return false", result);
- }
-
- /**
- * java.util.EnumSet#equals(Object)
- */
- public void test_equals_LObject() {
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- Enum[] elements = EnumFoo.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- set.add((EnumFoo) elements[i]);
- }
-
- assertFalse("Should return false", set.equals(null));
- assertFalse(
- "Should return false", set.equals(new Object()));
-
- Set<EnumFoo> anotherSet = EnumSet.noneOf(EnumFoo.class);
- elements = EnumFoo.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- anotherSet.add((EnumFoo) elements[i]);
- }
- assertTrue("Should return true", set.equals(anotherSet));
-
- anotherSet.remove(EnumFoo.a);
- assertFalse(
- "Should return false", set.equals(anotherSet));
-
- Set<EnumWithInnerClass> setWithInnerClass = EnumSet
- .noneOf(EnumWithInnerClass.class);
- elements = EnumWithInnerClass.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- setWithInnerClass.add((EnumWithInnerClass) elements[i]);
- }
-
- assertFalse(
- "Should return false", set.equals(setWithInnerClass));
-
- setWithInnerClass.clear();
- set.clear();
- assertTrue("Should be equal", set.equals(setWithInnerClass));
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
- assertTrue(hugeSet.equals(set));
-
- hugeSet = EnumSet.allOf(HugeEnum.class);
- assertFalse(hugeSet.equals(null));
- assertFalse(hugeSet.equals(new Object()));
-
- Set<HugeEnum> anotherHugeSet = EnumSet.allOf(HugeEnum.class);
- anotherHugeSet.remove(HugeEnum.a);
- assertFalse(hugeSet.equals(anotherHugeSet));
-
- Set<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
- .allOf(HugeEnumWithInnerClass.class);
- assertFalse(hugeSet.equals(hugeSetWithInnerClass));
- hugeSetWithInnerClass.clear();
- hugeSet.clear();
- assertTrue(hugeSet.equals(hugeSetWithInnerClass));
- }
-
- /**
- * java.util.EnumSet#clear()
- */
- public void test_clear() {
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- set.add(EnumFoo.a);
- set.add(EnumFoo.b);
- assertEquals("Size should be 2", 2, set.size());
-
- set.clear();
-
- assertEquals("Size should be 0", 0, set.size());
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
- assertEquals(65, hugeSet.size());
-
- boolean result = hugeSet.contains(HugeEnum.aa);
- assertTrue(result);
-
- hugeSet.clear();
- assertEquals(0, hugeSet.size());
- result = hugeSet.contains(HugeEnum.aa);
- assertFalse(result);
- }
-
- /**
- * java.util.EnumSet#size()
- */
- public void test_size() {
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- set.add(EnumFoo.a);
- set.add(EnumFoo.b);
- assertEquals("Size should be 2", 2, set.size());
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
- hugeSet.add(HugeEnum.a);
- hugeSet.add(HugeEnum.bb);
- assertEquals("Size should be 2", 2, hugeSet.size());
- }
-
- /**
- * java.util.EnumSet#complementOf(java.util.EnumSet)
- */
- public void test_ComplementOf_LEnumSet() {
-
- try {
- EnumSet.complementOf((EnumSet<EnumFoo>) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- EnumSet<EnumWithInnerClass> set = EnumSet
- .noneOf(EnumWithInnerClass.class);
- set.add(EnumWithInnerClass.d);
- set.add(EnumWithInnerClass.e);
- set.add(EnumWithInnerClass.f);
-
- assertEquals("Size should be 3:", 3, set.size());
-
- EnumSet<EnumWithInnerClass> complementOfE = EnumSet.complementOf(set);
- assertTrue(set.contains(EnumWithInnerClass.d));
- assertEquals(
- "complementOfE should have size 3", 3, complementOfE.size());
- assertTrue("complementOfE should contain EnumWithSubclass.a:",
- complementOfE.contains(EnumWithInnerClass.a));
- assertTrue("complementOfE should contain EnumWithSubclass.b:",
- complementOfE.contains(EnumWithInnerClass.b));
- assertTrue("complementOfE should contain EnumWithSubclass.c:",
- complementOfE.contains(EnumWithInnerClass.c));
-
- // test enum type with more than 64 elements
- EnumSet<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
- assertEquals(0, hugeSet.size());
- Set<HugeEnum> complementHugeSet = EnumSet.complementOf(hugeSet);
- assertEquals(65, complementHugeSet.size());
-
- hugeSet.add(HugeEnum.A);
- hugeSet.add(HugeEnum.mm);
- complementHugeSet = EnumSet.complementOf(hugeSet);
- assertEquals(63, complementHugeSet.size());
-
- try {
- EnumSet.complementOf((EnumSet<HugeEnum>) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
- }
-
- /**
- * java.util.EnumSet#contains(Object)
- */
- public void test_contains_LObject() {
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- Enum[] elements = EnumFoo.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- set.add((EnumFoo)elements[i]);
- }
- boolean result = set.contains(null);
- assertFalse("Should not contain null:", result);
-
- result = set.contains(EnumFoo.a);
- assertTrue("Should contain EnumFoo.a", result);
- result = set.contains(EnumFoo.ll);
- assertTrue("Should contain EnumFoo.ll", result);
-
- result = set.contains(EnumFoo.b);
- assertTrue("Should contain EnumFoo.b", result);
-
- result = set.contains(new Object());
- assertFalse("Should not contain Object instance", result);
-
- result = set.contains(EnumWithInnerClass.a);
- assertFalse("Should not contain EnumWithSubclass.a", result);
-
- set = EnumSet.noneOf(EnumFoo.class);
- set.add(EnumFoo.aa);
- set.add(EnumFoo.bb);
- set.add(EnumFoo.cc);
-
- assertEquals("Size of set should be 3", 3, set.size());
- assertTrue("set should contain EnumFoo.aa", set.contains(EnumFoo.aa));
-
- Set<EnumWithInnerClass> setWithSubclass = EnumSet
- .noneOf(EnumWithInnerClass.class);
- setWithSubclass.add(EnumWithInnerClass.a);
- setWithSubclass.add(EnumWithInnerClass.b);
- setWithSubclass.add(EnumWithInnerClass.c);
- setWithSubclass.add(EnumWithInnerClass.d);
- setWithSubclass.add(EnumWithInnerClass.e);
- setWithSubclass.add(EnumWithInnerClass.f);
- result = setWithSubclass.contains(EnumWithInnerClass.f);
- assertTrue("Should contain EnumWithSubclass.f", result);
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
- hugeSet.add(HugeEnum.a);
- result = hugeSet.contains(HugeEnum.a);
- assertTrue(result);
-
- result = hugeSet.contains(HugeEnum.b);
- assertTrue(result);
-
- result = hugeSet.contains(null);
- assertFalse(result);
-
- result = hugeSet.contains(HugeEnum.a);
- assertTrue(result);
-
- result = hugeSet.contains(HugeEnum.ll);
- assertTrue(result);
-
- result = hugeSet.contains(new Object());
- assertFalse(result);
-
- result = hugeSet.contains(Enum.class);
- assertFalse(result);
-
- }
-
- /**
- * java.util.EnumSet#containsAll(Collection)
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void test_containsAll_LCollection() {
- EnumSet<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- Enum[] elements = EnumFoo.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- set.add((EnumFoo)elements[i]);
- }
- try {
- set.containsAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- EnumSet<EmptyEnum> emptySet = EnumSet.noneOf(EmptyEnum.class);
- elements = EmptyEnum.class.getEnumConstants();
- for(int i = 0; i < elements.length; i++) {
- emptySet.add((EmptyEnum)elements[i]);
- }
- boolean result = set.containsAll(emptySet);
- assertTrue("Should return true", result);
-
- Collection rawCollection = new ArrayList();
- result = set.containsAll(rawCollection);
- assertTrue("Should contain empty collection:", result);
-
- rawCollection.add(1);
- result = set.containsAll(rawCollection);
- assertFalse("Should return false", result);
-
- rawCollection.add(EnumWithInnerClass.a);
- result = set.containsAll(rawCollection);
- assertFalse("Should return false", result);
-
- EnumSet rawSet = EnumSet.noneOf(EnumFoo.class);
- result = set.containsAll(rawSet);
- assertTrue("Should contain empty set", result);
-
- emptySet = EnumSet.noneOf(EmptyEnum.class);
- result = set.containsAll(emptySet);
- assertTrue("No class cast should be performed on empty set", result);
-
- Collection<EnumFoo> collection = new ArrayList<EnumFoo>();
- collection.add(EnumFoo.a);
- result = set.containsAll(collection);
- assertTrue("Should contain all elements in collection", result);
-
- EnumSet<EnumFoo> fooSet = EnumSet.noneOf(EnumFoo.class);
- fooSet.add(EnumFoo.a);
- result = set.containsAll(fooSet);
- assertTrue("Should return true", result);
-
- set.clear();
- try {
- set.containsAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- Collection<EnumWithInnerClass> collectionWithSubclass = new ArrayList<EnumWithInnerClass>();
- collectionWithSubclass.add(EnumWithInnerClass.a);
- result = set.containsAll(collectionWithSubclass);
- assertFalse("Should return false", result);
-
- EnumSet<EnumWithInnerClass> setWithSubclass = EnumSet
- .noneOf(EnumWithInnerClass.class);
- setWithSubclass.add(EnumWithInnerClass.a);
- result = set.containsAll(setWithSubclass);
- assertFalse("Should return false", result);
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
- hugeSet.add(HugeEnum.a);
- hugeSet.add(HugeEnum.b);
- hugeSet.add(HugeEnum.aa);
- hugeSet.add(HugeEnum.bb);
- hugeSet.add(HugeEnum.cc);
- hugeSet.add(HugeEnum.dd);
-
- Set<HugeEnum> anotherHugeSet = EnumSet.noneOf(HugeEnum.class);
- hugeSet.add(HugeEnum.b);
- hugeSet.add(HugeEnum.cc);
- result = hugeSet.containsAll(anotherHugeSet);
- assertTrue(result);
-
- try {
- hugeSet.containsAll(null);
- fail("Should throw NullPointerException");
- } catch(NullPointerException e) {
- // expected
- }
-
- Set<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
- .noneOf(HugeEnumWithInnerClass.class);
- hugeSetWithInnerClass.add(HugeEnumWithInnerClass.a);
- hugeSetWithInnerClass.add(HugeEnumWithInnerClass.b);
- result = hugeSetWithInnerClass.containsAll(hugeSetWithInnerClass);
- assertTrue(result);
- result = hugeSet.containsAll(hugeSetWithInnerClass);
- assertFalse(result);
-
- rawCollection = new ArrayList();
- result = hugeSet.containsAll(rawCollection);
- assertTrue("Should contain empty collection:", result);
-
- rawCollection.add(1);
- result = hugeSet.containsAll(rawCollection);
- assertFalse("Should return false", result);
-
- rawCollection.add(EnumWithInnerClass.a);
- result = set.containsAll(rawCollection);
- assertFalse("Should return false", result);
-
- rawSet = EnumSet.noneOf(HugeEnum.class);
- result = hugeSet.containsAll(rawSet);
- assertTrue("Should contain empty set", result);
-
- EnumSet<HugeEnumWithInnerClass> emptyHugeSet
- = EnumSet.noneOf(HugeEnumWithInnerClass.class);
- result = hugeSet.containsAll(emptyHugeSet);
- assertTrue("No class cast should be performed on empty set", result);
-
- Collection<HugeEnum> hugeCollection = new ArrayList<HugeEnum>();
- hugeCollection.add(HugeEnum.a);
- result = hugeSet.containsAll(hugeCollection);
- assertTrue("Should contain all elements in collection", result);
-
- hugeSet.clear();
- try {
- hugeSet.containsAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- Collection<HugeEnumWithInnerClass> hugeCollectionWithSubclass = new ArrayList<HugeEnumWithInnerClass>();
- hugeCollectionWithSubclass.add(HugeEnumWithInnerClass.a);
- result = hugeSet.containsAll(hugeCollectionWithSubclass);
- assertFalse("Should return false", result);
-
- EnumSet<HugeEnumWithInnerClass> hugeSetWithSubclass = EnumSet
- .noneOf(HugeEnumWithInnerClass.class);
- hugeSetWithSubclass.add(HugeEnumWithInnerClass.a);
- result = hugeSet.containsAll(hugeSetWithSubclass);
- assertFalse("Should return false", result);
- }
-
- /**
- * java.util.EnumSet#copyOf(java.util.Collection)
- */
- @SuppressWarnings("unchecked")
- public void test_CopyOf_LCollection() {
- try {
- EnumSet.copyOf((Collection) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- Collection collection = new ArrayList();
- try {
- EnumSet.copyOf(collection);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- collection.add(new Object());
- try {
- EnumSet.copyOf(collection);
- fail("Should throw ClassCastException");
- } catch (ClassCastException e) {
- // expected
- }
-
- Collection<EnumFoo> enumCollection = new ArrayList<EnumFoo>();
- enumCollection.add(EnumFoo.b);
-
- EnumSet<EnumFoo> copyOfEnumCollection = EnumSet.copyOf(enumCollection);
- assertEquals("Size of copyOfEnumCollection should be 1:",
- 1, copyOfEnumCollection.size());
- assertTrue("copyOfEnumCollection should contain EnumFoo.b:",
- copyOfEnumCollection.contains(EnumFoo.b));
-
- enumCollection.add(null);
- assertEquals("Size of enumCollection should be 2:",
- 2, enumCollection.size());
-
- try {
- copyOfEnumCollection = EnumSet.copyOf(enumCollection);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- Collection rawEnumCollection = new ArrayList();
- rawEnumCollection.add(EnumFoo.a);
- rawEnumCollection.add(EnumWithInnerClass.a);
- try {
- EnumSet.copyOf(rawEnumCollection);
- fail("Should throw ClassCastException");
- } catch(ClassCastException e) {
- // expected
- }
-
- // test enum type with more than 64 elements
- Collection<HugeEnum> hugeEnumCollection = new ArrayList<HugeEnum>();
- hugeEnumCollection.add(HugeEnum.b);
-
- EnumSet<HugeEnum> copyOfHugeEnumCollection = EnumSet.copyOf(hugeEnumCollection);
- assertEquals(1, copyOfHugeEnumCollection.size());
- assertTrue(copyOfHugeEnumCollection.contains(HugeEnum.b));
-
- hugeEnumCollection.add(null);
- assertEquals(2, hugeEnumCollection.size());
-
- try {
- copyOfHugeEnumCollection = EnumSet.copyOf(hugeEnumCollection);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- rawEnumCollection = new ArrayList();
- rawEnumCollection.add(HugeEnum.a);
- rawEnumCollection.add(HugeEnumWithInnerClass.a);
- try {
- EnumSet.copyOf(rawEnumCollection);
- fail("Should throw ClassCastException");
- } catch(ClassCastException e) {
- // expected
- }
- }
-
- /**
- * java.util.EnumSet#copyOf(java.util.EnumSet)
- */
- @SuppressWarnings("unchecked")
- public void test_CopyOf_LEnumSet() {
- EnumSet<EnumWithInnerClass> enumSet = EnumSet
- .noneOf(EnumWithInnerClass.class);
- enumSet.add(EnumWithInnerClass.a);
- enumSet.add(EnumWithInnerClass.f);
- EnumSet<EnumWithInnerClass> copyOfE = EnumSet.copyOf(enumSet);
- assertEquals("Size of enumSet and copyOfE should be equal",
- enumSet.size(), copyOfE.size());
-
- assertTrue("EnumWithSubclass.a should be contained in copyOfE",
- copyOfE.contains(EnumWithInnerClass.a));
- assertTrue("EnumWithSubclass.f should be contained in copyOfE",
- copyOfE.contains(EnumWithInnerClass.f));
-
- Object[] enumValue = copyOfE.toArray();
- assertSame("enumValue[0] should be identical with EnumWithSubclass.a",
- enumValue[0], EnumWithInnerClass.a);
- assertSame("enumValue[1] should be identical with EnumWithSubclass.f",
- enumValue[1], EnumWithInnerClass.f);
-
- try {
- EnumSet.copyOf((EnumSet) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- // test enum type with more than 64 elements
- EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet
- .noneOf(HugeEnumWithInnerClass.class);
- hugeEnumSet.add(HugeEnumWithInnerClass.a);
- hugeEnumSet.add(HugeEnumWithInnerClass.f);
- EnumSet<HugeEnumWithInnerClass> copyOfHugeEnum = EnumSet.copyOf(hugeEnumSet);
- assertEquals(enumSet.size(), copyOfE.size());
-
- assertTrue(copyOfHugeEnum.contains(HugeEnumWithInnerClass.a));
- assertTrue(copyOfHugeEnum.contains(HugeEnumWithInnerClass.f));
-
- Object[] hugeEnumValue = copyOfHugeEnum.toArray();
- assertSame(hugeEnumValue[0], HugeEnumWithInnerClass.a);
- assertSame(hugeEnumValue[1], HugeEnumWithInnerClass.f);
- }
-
- /**
- * java.util.EnumSet#removeAll(Collection)
- */
- @SuppressWarnings("unchecked")
- public void test_removeAll_LCollection() {
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- try {
- set.removeAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- set = EnumSet.allOf(EnumFoo.class);
- assertEquals("Size of set should be 64:", 64, set.size());
-
- try {
- set.removeAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- Collection<EnumFoo> collection = new ArrayList<EnumFoo>();
- collection.add(EnumFoo.a);
-
- boolean result = set.removeAll(collection);
- assertTrue("Should return true", result);
- assertEquals("Size of set should be 63", 63, set.size());
-
- collection = new ArrayList();
- result = set.removeAll(collection);
- assertFalse("Should return false", result);
-
- Set<EmptyEnum> emptySet = EnumSet.noneOf(EmptyEnum.class);
- result = set.removeAll(emptySet);
- assertFalse("Should return false", result);
-
- EnumSet<EnumFoo> emptyFooSet = EnumSet.noneOf(EnumFoo.class);
- result = set.removeAll(emptyFooSet);
- assertFalse("Should return false", result);
-
- emptyFooSet.add(EnumFoo.a);
- result = set.removeAll(emptyFooSet);
- assertFalse("Should return false", result);
-
- Set<EnumWithInnerClass> setWithSubclass = EnumSet
- .noneOf(EnumWithInnerClass.class);
- result = set.removeAll(setWithSubclass);
- assertFalse("Should return false", result);
-
- setWithSubclass.add(EnumWithInnerClass.a);
- result = set.removeAll(setWithSubclass);
- assertFalse("Should return false", result);
-
- Set<EnumFoo> anotherSet = EnumSet.noneOf(EnumFoo.class);
- anotherSet.add(EnumFoo.a);
-
- set = EnumSet.allOf(EnumFoo.class);
- result = set.removeAll(anotherSet);
- assertTrue("Should return true", result);
- assertEquals("Size of set should be 63:", 63, set.size());
-
- Set<EnumWithInnerClass> setWithInnerClass = EnumSet
- .noneOf(EnumWithInnerClass.class);
- setWithInnerClass.add(EnumWithInnerClass.a);
- setWithInnerClass.add(EnumWithInnerClass.b);
-
- Set<EnumWithInnerClass> anotherSetWithInnerClass = EnumSet
- .noneOf(EnumWithInnerClass.class);
- anotherSetWithInnerClass.add(EnumWithInnerClass.c);
- anotherSetWithInnerClass.add(EnumWithInnerClass.d);
- result = anotherSetWithInnerClass.removeAll(setWithInnerClass);
- assertFalse("Should return false", result);
-
- anotherSetWithInnerClass.add(EnumWithInnerClass.a);
- result = anotherSetWithInnerClass.removeAll(setWithInnerClass);
- assertTrue("Should return true", result);
- assertEquals("Size of anotherSetWithInnerClass should remain 2",
- 2, anotherSetWithInnerClass.size());
-
- anotherSetWithInnerClass.remove(EnumWithInnerClass.c);
- anotherSetWithInnerClass.remove(EnumWithInnerClass.d);
- result = anotherSetWithInnerClass.remove(setWithInnerClass);
- assertFalse("Should return false", result);
-
- Set rawSet = EnumSet.allOf(EnumWithAllInnerClass.class);
- result = rawSet.removeAll(EnumSet.allOf(EnumFoo.class));
- assertFalse("Should return false", result);
-
- setWithInnerClass = EnumSet.allOf(EnumWithInnerClass.class);
- anotherSetWithInnerClass = EnumSet.allOf(EnumWithInnerClass.class);
- setWithInnerClass.remove(EnumWithInnerClass.a);
- anotherSetWithInnerClass.remove(EnumWithInnerClass.f);
- result = setWithInnerClass.removeAll(anotherSetWithInnerClass);
- assertTrue("Should return true", result);
- assertEquals("Size of setWithInnerClass should be 1", 1, setWithInnerClass.size());
-
- result = setWithInnerClass.contains(EnumWithInnerClass.f);
- assertTrue("Should return true", result);
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
-
- Collection<HugeEnum> hugeCollection = new ArrayList<HugeEnum>();
- hugeCollection.add(HugeEnum.a);
-
- result = hugeSet.removeAll(hugeCollection);
- assertTrue(result);
- assertEquals(64, hugeSet.size());
-
- collection = new ArrayList();
- result = hugeSet.removeAll(collection);
- assertFalse(result);
-
- Set<HugeEnum> emptyHugeSet = EnumSet.noneOf(HugeEnum.class);
- result = hugeSet.removeAll(emptyHugeSet);
- assertFalse(result);
-
- Set<HugeEnumWithInnerClass> hugeSetWithSubclass = EnumSet
- .noneOf(HugeEnumWithInnerClass.class);
- result = hugeSet.removeAll(hugeSetWithSubclass);
- assertFalse(result);
-
- hugeSetWithSubclass.add(HugeEnumWithInnerClass.a);
- result = hugeSet.removeAll(hugeSetWithSubclass);
- assertFalse(result);
-
- Set<HugeEnum> anotherHugeSet = EnumSet.noneOf(HugeEnum.class);
- anotherHugeSet.add(HugeEnum.a);
-
- hugeSet = EnumSet.allOf(HugeEnum.class);
- result = hugeSet.removeAll(anotherHugeSet);
- assertTrue(result);
- assertEquals(63, set.size());
-
- Set<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
- .noneOf(HugeEnumWithInnerClass.class);
- hugeSetWithInnerClass.add(HugeEnumWithInnerClass.a);
- hugeSetWithInnerClass.add(HugeEnumWithInnerClass.b);
-
- Set<HugeEnumWithInnerClass> anotherHugeSetWithInnerClass = EnumSet
- .noneOf(HugeEnumWithInnerClass.class);
- anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.c);
- anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.d);
- result = anotherHugeSetWithInnerClass.removeAll(setWithInnerClass);
- assertFalse("Should return false", result);
-
- anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.a);
- result = anotherHugeSetWithInnerClass.removeAll(hugeSetWithInnerClass);
- assertTrue(result);
- assertEquals(2, anotherHugeSetWithInnerClass.size());
-
- anotherHugeSetWithInnerClass.remove(HugeEnumWithInnerClass.c);
- anotherHugeSetWithInnerClass.remove(HugeEnumWithInnerClass.d);
- result = anotherHugeSetWithInnerClass.remove(hugeSetWithInnerClass);
- assertFalse(result);
-
- rawSet = EnumSet.allOf(HugeEnumWithInnerClass.class);
- result = rawSet.removeAll(EnumSet.allOf(HugeEnum.class));
- assertFalse(result);
-
- hugeSetWithInnerClass = EnumSet.allOf(HugeEnumWithInnerClass.class);
- anotherHugeSetWithInnerClass = EnumSet.allOf(HugeEnumWithInnerClass.class);
- hugeSetWithInnerClass.remove(HugeEnumWithInnerClass.a);
- anotherHugeSetWithInnerClass.remove(HugeEnumWithInnerClass.f);
- result = hugeSetWithInnerClass.removeAll(anotherHugeSetWithInnerClass);
- assertTrue(result);
- assertEquals(1, hugeSetWithInnerClass.size());
-
- result = hugeSetWithInnerClass.contains(HugeEnumWithInnerClass.f);
- assertTrue(result);
- }
-
- /**
- * java.util.EnumSet#retainAll(Collection)
- */
- @SuppressWarnings("unchecked")
- public void test_retainAll_LCollection() {
- Set<EnumFoo> set = EnumSet.allOf(EnumFoo.class);
-
- try {
- set.retainAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- set.clear();
- boolean result = set.retainAll(null);
- assertFalse("Should return false", result);
-
- Collection rawCollection = new ArrayList();
- result = set.retainAll(rawCollection);
- assertFalse("Should return false", result);
-
- rawCollection.add(EnumFoo.a);
- result = set.retainAll(rawCollection);
- assertFalse("Should return false", result);
-
- rawCollection.add(EnumWithInnerClass.a);
- result = set.retainAll(rawCollection);
- assertFalse("Should return false", result);
- assertEquals("Size of set should be 0:", 0, set.size());
-
- rawCollection.remove(EnumFoo.a);
- result = set.retainAll(rawCollection);
- assertFalse("Should return false", result);
-
- Set<EnumFoo> anotherSet = EnumSet.allOf(EnumFoo.class);
- result = set.retainAll(anotherSet);
- assertFalse("Should return false", result);
- assertEquals("Size of set should be 0", 0, set.size());
-
- Set<EnumWithInnerClass> setWithInnerClass = EnumSet
- .allOf(EnumWithInnerClass.class);
- result = set.retainAll(setWithInnerClass);
- assertFalse("Should return false", result);
- assertEquals("Size of set should be 0", 0, set.size());
-
- setWithInnerClass = EnumSet.noneOf(EnumWithInnerClass.class);
- result = set.retainAll(setWithInnerClass);
- assertFalse("Should return false", result);
-
- Set<EmptyEnum> emptySet = EnumSet.allOf(EmptyEnum.class);
- result = set.retainAll(emptySet);
- assertFalse("Should return false", result);
-
- Set<EnumWithAllInnerClass> setWithAllInnerClass = EnumSet
- .allOf(EnumWithAllInnerClass.class);
- result = set.retainAll(setWithAllInnerClass);
- assertFalse("Should return false", result);
-
- set.add(EnumFoo.a);
- result = set.retainAll(setWithInnerClass);
- assertTrue("Should return true", result);
- assertEquals("Size of set should be 0", 0, set.size());
-
- setWithInnerClass = EnumSet.allOf(EnumWithInnerClass.class);
- setWithInnerClass.remove(EnumWithInnerClass.f);
- Set<EnumWithInnerClass> anotherSetWithInnerClass = EnumSet
- .noneOf(EnumWithInnerClass.class);
- anotherSetWithInnerClass.add(EnumWithInnerClass.e);
- anotherSetWithInnerClass.add(EnumWithInnerClass.f);
-
- result = setWithInnerClass.retainAll(anotherSetWithInnerClass);
- assertTrue("Should return true", result);
- result = setWithInnerClass.contains(EnumWithInnerClass.e);
- assertTrue("Should contain EnumWithInnerClass.e", result);
- result = setWithInnerClass.contains(EnumWithInnerClass.b);
- assertFalse("Should not contain EnumWithInnerClass.b", result);
- assertEquals("Size of set should be 1:", 1, setWithInnerClass.size());
-
- anotherSetWithInnerClass = EnumSet.allOf(EnumWithInnerClass.class);
- result = setWithInnerClass.retainAll(anotherSetWithInnerClass);
-
- assertFalse("Return value should be false", result);
-
- rawCollection = new ArrayList();
- rawCollection.add(EnumWithInnerClass.e);
- rawCollection.add(EnumWithInnerClass.f);
- result = setWithInnerClass.retainAll(rawCollection);
- assertFalse("Should return false", result);
-
- set = EnumSet.allOf(EnumFoo.class);
- set.remove(EnumFoo.a);
- anotherSet = EnumSet.noneOf(EnumFoo.class);
- anotherSet.add(EnumFoo.a);
- result = set.retainAll(anotherSet);
- assertTrue("Should return true", result);
- assertEquals("size should be 0", 0, set.size());
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.allOf(HugeEnum.class);
-
- try {
- hugeSet.retainAll(null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- hugeSet.clear();
- result = hugeSet.retainAll(null);
- assertFalse(result);
-
- rawCollection = new ArrayList();
- result = hugeSet.retainAll(rawCollection);
- assertFalse(result);
-
- rawCollection.add(HugeEnum.a);
- result = hugeSet.retainAll(rawCollection);
- assertFalse(result);
-
- rawCollection.add(HugeEnumWithInnerClass.a);
- result = hugeSet.retainAll(rawCollection);
- assertFalse(result);
- assertEquals(0, set.size());
-
- rawCollection.remove(HugeEnum.a);
- result = set.retainAll(rawCollection);
- assertFalse(result);
-
- Set<HugeEnum> anotherHugeSet = EnumSet.allOf(HugeEnum.class);
- result = hugeSet.retainAll(anotherHugeSet);
- assertFalse(result);
- assertEquals(0, hugeSet.size());
-
- Set<HugeEnumWithInnerClass> hugeSetWithInnerClass = EnumSet
- .allOf(HugeEnumWithInnerClass.class);
- result = hugeSet.retainAll(hugeSetWithInnerClass);
- assertFalse(result);
- assertEquals(0, hugeSet.size());
-
- hugeSetWithInnerClass = EnumSet.noneOf(HugeEnumWithInnerClass.class);
- result = hugeSet.retainAll(hugeSetWithInnerClass);
- assertFalse(result);
-
- Set<HugeEnumWithInnerClass> hugeSetWithAllInnerClass = EnumSet
- .allOf(HugeEnumWithInnerClass.class);
- result = hugeSet.retainAll(hugeSetWithAllInnerClass);
- assertFalse(result);
-
- hugeSet.add(HugeEnum.a);
- result = hugeSet.retainAll(hugeSetWithInnerClass);
- assertTrue(result);
- assertEquals(0, hugeSet.size());
-
- hugeSetWithInnerClass = EnumSet.allOf(HugeEnumWithInnerClass.class);
- hugeSetWithInnerClass.remove(HugeEnumWithInnerClass.f);
- Set<HugeEnumWithInnerClass> anotherHugeSetWithInnerClass = EnumSet
- .noneOf(HugeEnumWithInnerClass.class);
- anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.e);
- anotherHugeSetWithInnerClass.add(HugeEnumWithInnerClass.f);
-
- result = hugeSetWithInnerClass.retainAll(anotherHugeSetWithInnerClass);
- assertTrue(result);
- result = hugeSetWithInnerClass.contains(HugeEnumWithInnerClass.e);
- assertTrue("Should contain HugeEnumWithInnerClass.e", result);
- result = hugeSetWithInnerClass.contains(HugeEnumWithInnerClass.b);
- assertFalse("Should not contain HugeEnumWithInnerClass.b", result);
- assertEquals("Size of hugeSet should be 1:", 1, hugeSetWithInnerClass.size());
-
- anotherHugeSetWithInnerClass = EnumSet.allOf(HugeEnumWithInnerClass.class);
- result = hugeSetWithInnerClass.retainAll(anotherHugeSetWithInnerClass);
-
- assertFalse("Return value should be false", result);
-
- rawCollection = new ArrayList();
- rawCollection.add(HugeEnumWithInnerClass.e);
- rawCollection.add(HugeEnumWithInnerClass.f);
- result = hugeSetWithInnerClass.retainAll(rawCollection);
- assertFalse(result);
-
- hugeSet = EnumSet.allOf(HugeEnum.class);
- hugeSet.remove(HugeEnum.a);
- anotherHugeSet = EnumSet.noneOf(HugeEnum.class);
- anotherHugeSet.add(HugeEnum.a);
- result = hugeSet.retainAll(anotherHugeSet);
- assertTrue(result);
- assertEquals(0, hugeSet.size());
- }
-
- /**
- * java.util.EnumSet#iterator()
- */
- public void test_iterator() {
- Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
- set.add(EnumFoo.a);
- set.add(EnumFoo.b);
-
- Iterator<EnumFoo> iterator = set.iterator();
- Iterator<EnumFoo> anotherIterator = set.iterator();
- assertNotSame("Should not be same", iterator, anotherIterator);
- try {
- iterator.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // expectedd
- }
-
- assertTrue("Should has next element:", iterator.hasNext());
- assertSame("Should be identical", EnumFoo.a, iterator.next());
- iterator.remove();
- assertTrue("Should has next element:", iterator.hasNext());
- assertSame("Should be identical", EnumFoo.b, iterator.next());
- assertFalse("Should not has next element:", iterator.hasNext());
- assertFalse("Should not has next element:", iterator.hasNext());
-
- assertEquals("Size should be 1:", 1, set.size());
-
- try {
- iterator.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // expected
- }
- set = EnumSet.noneOf(EnumFoo.class);
- set.add(EnumFoo.a);
- iterator = set.iterator();
- assertEquals("Should be equal", EnumFoo.a, iterator.next());
- iterator.remove();
- try {
- iterator.remove();
- fail("Should throw IllegalStateException");
- } catch(IllegalStateException e) {
- // expected
- }
-
- Set<EmptyEnum> emptySet = EnumSet.allOf(EmptyEnum.class);
- Iterator<EmptyEnum> emptyIterator = emptySet.iterator();
- try {
- emptyIterator.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // expected
- }
-
- Set<EnumWithInnerClass> setWithSubclass = EnumSet
- .allOf(EnumWithInnerClass.class);
- setWithSubclass.remove(EnumWithInnerClass.e);
- Iterator<EnumWithInnerClass> iteratorWithSubclass = setWithSubclass
- .iterator();
- assertSame("Should be same", EnumWithInnerClass.a, iteratorWithSubclass.next());
-
- assertTrue("Should return true", iteratorWithSubclass.hasNext());
- assertSame("Should be same", EnumWithInnerClass.b, iteratorWithSubclass.next());
-
- setWithSubclass.remove(EnumWithInnerClass.c);
- assertTrue("Should return true", iteratorWithSubclass.hasNext());
- assertSame("Should be same", EnumWithInnerClass.c, iteratorWithSubclass.next());
-
- assertTrue("Should return true", iteratorWithSubclass.hasNext());
- assertSame("Should be same", EnumWithInnerClass.d, iteratorWithSubclass.next());
-
- setWithSubclass.add(EnumWithInnerClass.e);
- assertTrue("Should return true", iteratorWithSubclass.hasNext());
- assertSame("Should be same", EnumWithInnerClass.f, iteratorWithSubclass.next());
-
- set = EnumSet.noneOf(EnumFoo.class);
- iterator = set.iterator();
- try {
- iterator.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // expected
- }
-
- set.add(EnumFoo.a);
- iterator = set.iterator();
- assertEquals("Should return EnumFoo.a", EnumFoo.a, iterator.next());
- assertEquals("Size of set should be 1", 1, set.size());
- iterator.remove();
- assertEquals("Size of set should be 0", 0, set.size());
- assertFalse("Should return false", set.contains(EnumFoo.a));
-
- set.add(EnumFoo.a);
- set.add(EnumFoo.b);
- iterator = set.iterator();
- assertEquals("Should be equals", EnumFoo.a, iterator.next());
- iterator.remove();
- try {
- iterator.remove();
- fail("Should throw IllegalStateException");
- } catch(IllegalStateException e) {
- // expected
- }
-
- assertTrue("Should have next element", iterator.hasNext());
- try {
- iterator.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // expected
- }
- assertEquals("Size of set should be 1", 1, set.size());
- assertTrue("Should have next element", iterator.hasNext());
- assertEquals("Should return EnumFoo.b", EnumFoo.b, iterator.next());
- set.remove(EnumFoo.b);
- assertEquals("Size of set should be 0", 0, set.size());
- iterator.remove();
- assertFalse("Should return false", set.contains(EnumFoo.a));
-
- // RI's bug, EnumFoo.b should not exist at the moment.
- if (!disableRIBugs) {
- assertFalse("Should return false", set.contains(EnumFoo.b));
- }
-
- // test enum type with more than 64 elements
- Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
- hugeSet.add(HugeEnum.a);
- hugeSet.add(HugeEnum.b);
-
- Iterator<HugeEnum> hIterator = hugeSet.iterator();
- Iterator<HugeEnum> anotherHugeIterator = hugeSet.iterator();
- assertNotSame(hIterator, anotherHugeIterator);
- try {
- hIterator.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // expectedd
- }
-
- assertTrue(hIterator.hasNext());
- assertSame(HugeEnum.a, hIterator.next());
- hIterator.remove();
- assertTrue(hIterator.hasNext());
- assertSame(HugeEnum.b, hIterator.next());
- assertFalse(hIterator.hasNext());
- assertFalse(hIterator.hasNext());
-
- assertEquals(1, hugeSet.size());
-
- try {
- hIterator.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // expected
- }
-
- Set<HugeEnumWithInnerClass> hugeSetWithSubclass = EnumSet
- .allOf(HugeEnumWithInnerClass.class);
- hugeSetWithSubclass.remove(HugeEnumWithInnerClass.e);
- Iterator<HugeEnumWithInnerClass> hugeIteratorWithSubclass = hugeSetWithSubclass
- .iterator();
- assertSame(HugeEnumWithInnerClass.a, hugeIteratorWithSubclass.next());
-
- assertTrue(hugeIteratorWithSubclass.hasNext());
- assertSame(HugeEnumWithInnerClass.b, hugeIteratorWithSubclass.next());
-
- setWithSubclass.remove(HugeEnumWithInnerClass.c);
- assertTrue(hugeIteratorWithSubclass.hasNext());
- assertSame(HugeEnumWithInnerClass.c, hugeIteratorWithSubclass.next());
-
- assertTrue(hugeIteratorWithSubclass.hasNext());
- assertSame(HugeEnumWithInnerClass.d, hugeIteratorWithSubclass.next());
-
- hugeSetWithSubclass.add(HugeEnumWithInnerClass.e);
- assertTrue(hugeIteratorWithSubclass.hasNext());
- assertSame(HugeEnumWithInnerClass.f, hugeIteratorWithSubclass.next());
-
- hugeSet = EnumSet.noneOf(HugeEnum.class);
- hIterator = hugeSet.iterator();
- try {
- hIterator.next();
- fail("Should throw NoSuchElementException");
- } catch (NoSuchElementException e) {
- // expected
- }
-
- hugeSet.add(HugeEnum.a);
- hIterator = hugeSet.iterator();
- assertEquals(HugeEnum.a, hIterator.next());
- assertEquals(1, hugeSet.size());
- hIterator.remove();
- assertEquals(0, hugeSet.size());
- assertFalse(hugeSet.contains(HugeEnum.a));
-
- hugeSet.add(HugeEnum.a);
- hugeSet.add(HugeEnum.b);
- hIterator = hugeSet.iterator();
- hIterator.next();
- hIterator.remove();
-
- assertTrue(hIterator.hasNext());
- try {
- hIterator.remove();
- fail("Should throw IllegalStateException");
- } catch (IllegalStateException e) {
- // expected
- }
- assertEquals(1, hugeSet.size());
- assertTrue(hIterator.hasNext());
- assertEquals(HugeEnum.b, hIterator.next());
- hugeSet.remove(HugeEnum.b);
- assertEquals(0, hugeSet.size());
- hIterator.remove();
- assertFalse(hugeSet.contains(HugeEnum.a));
- // RI's bug, EnumFoo.b should not exist at the moment.
- if(!disableRIBugs) {
- assertFalse("Should return false", set.contains(EnumFoo.b));
- }
- }
-
- /**
- * java.util.EnumSet#of(E)
- */
- public void test_Of_E() {
- EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a);
- assertEquals("enumSet should have length 1:", 1, enumSet.size());
-
- assertTrue("enumSet should contain EnumWithSubclass.a:",
- enumSet.contains(EnumWithInnerClass.a));
-
- try {
- EnumSet.of((EnumWithInnerClass) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- // test enum type with more than 64 elements
- EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a);
- assertEquals(1, hugeEnumSet.size());
-
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
- }
-
- /**
- * java.util.EnumSet#of(E, E)
- */
- public void test_Of_EE() {
- EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
- EnumWithInnerClass.b);
- assertEquals("enumSet should have length 2:", 2, enumSet.size());
-
- assertTrue("enumSet should contain EnumWithSubclass.a:",
- enumSet.contains(EnumWithInnerClass.a));
- assertTrue("enumSet should contain EnumWithSubclass.b:",
- enumSet.contains(EnumWithInnerClass.b));
-
- try {
- EnumSet.of((EnumWithInnerClass) null, EnumWithInnerClass.a);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- try {
- EnumSet.of( EnumWithInnerClass.a, (EnumWithInnerClass) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- try {
- EnumSet.of( (EnumWithInnerClass) null, (EnumWithInnerClass) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- enumSet = EnumSet.of(EnumWithInnerClass.a, EnumWithInnerClass.a);
- assertEquals("Size of enumSet should be 1",
- 1, enumSet.size());
-
- // test enum type with more than 64 elements
- EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
- HugeEnumWithInnerClass.b);
- assertEquals(2, hugeEnumSet.size());
-
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.b));
-
- try {
- EnumSet.of((HugeEnumWithInnerClass) null, HugeEnumWithInnerClass.a);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- try {
- EnumSet.of( HugeEnumWithInnerClass.a, (HugeEnumWithInnerClass) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- try {
- EnumSet.of( (HugeEnumWithInnerClass) null, (HugeEnumWithInnerClass) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.a);
- assertEquals(1, hugeEnumSet.size());
- }
-
- /**
- * java.util.EnumSet#of(E, E, E)
- */
- public void test_Of_EEE() {
- EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
- EnumWithInnerClass.b, EnumWithInnerClass.c);
- assertEquals("Size of enumSet should be 3:", 3, enumSet.size());
-
- assertTrue(
- "enumSet should contain EnumWithSubclass.a:", enumSet.contains(EnumWithInnerClass.a));
- assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.c));
-
- try {
- EnumSet.of((EnumWithInnerClass) null, null, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- enumSet = EnumSet.of(EnumWithInnerClass.a, EnumWithInnerClass.b,
- EnumWithInnerClass.b);
- assertEquals("enumSet should contain 2 elements:", 2, enumSet.size());
-
- // test enum type with more than 64 elements
- EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
- HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.c);
- assertEquals(3, hugeEnumSet.size());
-
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.c));
-
- try {
- EnumSet.of((HugeEnumWithInnerClass) null, null, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.b,
- HugeEnumWithInnerClass.b);
- assertEquals(2, hugeEnumSet.size());
- }
-
- /**
- * java.util.EnumSet#of(E, E, E, E)
- */
- public void test_Of_EEEE() {
- EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
- EnumWithInnerClass.b, EnumWithInnerClass.c,
- EnumWithInnerClass.d);
- assertEquals("Size of enumSet should be 4", 4, enumSet.size());
-
- assertTrue(
- "enumSet should contain EnumWithSubclass.a:", enumSet.contains(EnumWithInnerClass.a));
- assertTrue("enumSet should contain EnumWithSubclass.d:", enumSet
- .contains(EnumWithInnerClass.d));
-
- try {
- EnumSet.of((EnumWithInnerClass) null, null, null, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- // test enum type with more than 64 elements
- EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
- HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.c,
- HugeEnumWithInnerClass.d);
- assertEquals(4, hugeEnumSet.size());
-
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.d));
-
- try {
- EnumSet.of((HugeEnumWithInnerClass) null, null, null, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
- }
-
- /**
- * java.util.EnumSet#of(E, E, E, E, E)
- */
- public void test_Of_EEEEE() {
- EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
- EnumWithInnerClass.b, EnumWithInnerClass.c,
- EnumWithInnerClass.d, EnumWithInnerClass.e);
- assertEquals("Size of enumSet should be 5:", 5, enumSet.size());
-
- assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.a));
- assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.e));
-
- try {
- EnumSet.of((EnumWithInnerClass) null, null, null, null, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- // test enum with more than 64 elements
- EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
- HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.c,
- HugeEnumWithInnerClass.d, HugeEnumWithInnerClass.e);
- assertEquals(5, hugeEnumSet.size());
-
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.e));
-
- try {
- EnumSet.of((HugeEnumWithInnerClass) null, null, null, null, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
- }
-
- /**
- * java.util.EnumSet#of(E, E...)
- */
- public void test_Of_EEArray() {
- EnumWithInnerClass[] enumArray = new EnumWithInnerClass[] {
- EnumWithInnerClass.b, EnumWithInnerClass.c };
- EnumSet<EnumWithInnerClass> enumSet = EnumSet.of(EnumWithInnerClass.a,
- enumArray);
- assertEquals("Should be equal", 3, enumSet.size());
-
- assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.a));
- assertTrue("Should return true", enumSet.contains(EnumWithInnerClass.c));
-
- try {
- EnumSet.of(EnumWithInnerClass.a, (EnumWithInnerClass[])null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- EnumFoo[] foos = {EnumFoo.a, EnumFoo.c, EnumFoo.d};
- EnumSet<EnumFoo> set = EnumSet.of(EnumFoo.c, foos);
- assertEquals("size of set should be 1", 3, set.size());
- assertTrue("Should contain EnumFoo.a", set.contains(EnumFoo.a));
- assertTrue("Should contain EnumFoo.c", set.contains(EnumFoo.c));
- assertTrue("Should contain EnumFoo.d", set.contains(EnumFoo.d));
-
- // test enum type with more than 64 elements
- HugeEnumWithInnerClass[] hugeEnumArray = new HugeEnumWithInnerClass[] {
- HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.c };
- EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.of(HugeEnumWithInnerClass.a,
- hugeEnumArray);
- assertEquals(3, hugeEnumSet.size());
-
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.a));
- assertTrue(hugeEnumSet.contains(HugeEnumWithInnerClass.c));
-
- try {
- EnumSet.of(HugeEnumWithInnerClass.a, (HugeEnumWithInnerClass[])null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException npe) {
- // expected
- }
-
- HugeEnumWithInnerClass[] huges = {HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.c, HugeEnumWithInnerClass.d};
- EnumSet<HugeEnumWithInnerClass> hugeSet = EnumSet.of(HugeEnumWithInnerClass.c, huges);
- assertEquals(3, hugeSet.size());
- assertTrue(hugeSet.contains(HugeEnumWithInnerClass.a));
- assertTrue(hugeSet.contains(HugeEnumWithInnerClass.c));
- assertTrue(hugeSet.contains(HugeEnumWithInnerClass.d));
- }
-
- /**
- * java.util.EnumSet#range(E, E)
- */
- public void test_Range_EE() {
- try {
- EnumSet.range(EnumWithInnerClass.c, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- EnumSet.range(null, EnumWithInnerClass.c);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- EnumSet.range(null, (EnumWithInnerClass) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- EnumSet.range(EnumWithInnerClass.b, EnumWithInnerClass.a);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- EnumSet<EnumWithInnerClass> enumSet = EnumSet.range(
- EnumWithInnerClass.a, EnumWithInnerClass.a);
- assertEquals("Size of enumSet should be 1", 1, enumSet.size());
-
- enumSet = EnumSet.range(
- EnumWithInnerClass.a, EnumWithInnerClass.c);
- assertEquals("Size of enumSet should be 3", 3, enumSet.size());
-
- // test enum with more than 64 elements
- try {
- EnumSet.range(HugeEnumWithInnerClass.c, null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- EnumSet.range(null, HugeEnumWithInnerClass.c);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- EnumSet.range(null, (HugeEnumWithInnerClass) null);
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected
- }
-
- try {
- EnumSet.range(HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.a);
- fail("Should throw IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- EnumSet<HugeEnumWithInnerClass> hugeEnumSet = EnumSet.range(
- HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.a);
- assertEquals(1, hugeEnumSet.size());
-
- hugeEnumSet = EnumSet.range(
- HugeEnumWithInnerClass.c, HugeEnumWithInnerClass.aa);
- assertEquals(51, hugeEnumSet.size());
-
- hugeEnumSet = EnumSet.range(
- HugeEnumWithInnerClass.a, HugeEnumWithInnerClass.mm);
- assertEquals(65, hugeEnumSet.size());
-
- hugeEnumSet = EnumSet.range(
- HugeEnumWithInnerClass.b, HugeEnumWithInnerClass.mm);
- assertEquals(64, hugeEnumSet.size());
- }
-
- /**
- * java.util.EnumSet#clone()
- */
- public void test_Clone() {
- EnumSet<EnumFoo> enumSet = EnumSet.allOf(EnumFoo.class);
- EnumSet<EnumFoo> clonedEnumSet = enumSet.clone();
- assertEquals(enumSet, clonedEnumSet);
- assertNotSame(enumSet, clonedEnumSet);
- assertTrue(clonedEnumSet.contains(EnumFoo.a));
- assertTrue(clonedEnumSet.contains(EnumFoo.b));
- assertEquals(64, clonedEnumSet.size());
-
- // test enum type with more than 64 elements
- EnumSet<HugeEnum> hugeEnumSet = EnumSet.allOf(HugeEnum.class);
- EnumSet<HugeEnum> hugeClonedEnumSet = hugeEnumSet.clone();
- assertEquals(hugeEnumSet, hugeClonedEnumSet);
- assertNotSame(hugeEnumSet, hugeClonedEnumSet);
- assertTrue(hugeClonedEnumSet.contains(HugeEnum.a));
- assertTrue(hugeClonedEnumSet.contains(HugeEnum.b));
- assertEquals(65, hugeClonedEnumSet.size());
-
- hugeClonedEnumSet.remove(HugeEnum.a);
- assertEquals(64, hugeClonedEnumSet.size());
- assertFalse(hugeClonedEnumSet.contains(HugeEnum.a));
- assertEquals(65, hugeEnumSet.size());
- assertTrue(hugeEnumSet.contains(HugeEnum.a));
- }
-
- /**
- * java.util.EnumSet#Serialization()
- */
- public void test_serialization() throws Exception {
- EnumSet<EnumFoo> set = EnumSet.allOf(EnumFoo.class);
- SerializationTest.verifySelf(set);
- }
-
- /**
- * serialization/deserialization compatibility with RI.
- */
- @SuppressWarnings( { "unchecked", "boxing" })
- public void testSerializationCompatibility() throws Exception {
- EnumSet<EnumFoo> set = EnumSet.allOf(EnumFoo.class);
- SerializationTest.verifyGolden(this, set);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/FormattableFlagsTest.java b/luni/src/test/java/tests/api/java/util/FormattableFlagsTest.java
deleted file mode 100644
index 2aa4954..0000000
--- a/luni/src/test/java/tests/api/java/util/FormattableFlagsTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.util;
-
-import java.util.FormattableFlags;
-import junit.framework.TestCase;
-
-public class FormattableFlagsTest extends TestCase {
-
- /**
- * @test java.util.FormattableFlags ConstantFieldValues
- */
- public void test_ConstantFieldValues() {
- assertEquals(1, FormattableFlags.LEFT_JUSTIFY);
- assertEquals(2, FormattableFlags.UPPERCASE);
- assertEquals(4, FormattableFlags.ALTERNATE);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/HashMapTest.java b/luni/src/test/java/tests/api/java/util/HashMapTest.java
deleted file mode 100644
index b37e813..0000000
--- a/luni/src/test/java/tests/api/java/util/HashMapTest.java
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.*;
-
-import tests.support.Support_MapTest2;
-import tests.support.Support_UnmodifiableCollectionTest;
-
-public class HashMapTest extends junit.framework.TestCase {
- class MockMap extends AbstractMap {
- public Set entrySet() {
- return Collections.EMPTY_SET;
- }
- public int size(){
- return 0;
- }
- }
-
- private static class MockMapNull extends AbstractMap {
- public Set entrySet() {
- return null;
- }
-
- public int size() {
- return 10;
- }
- }
-
- HashMap hm;
-
- final static int hmSize = 1000;
-
- Object[] objArray;
-
- Object[] objArray2;
-
- /**
- * java.util.HashMap#HashMap()
- */
- public void test_Constructor() {
- // Test for method java.util.HashMap()
- new Support_MapTest2(new HashMap()).runTest();
-
- HashMap hm2 = new HashMap();
- assertEquals("Created incorrect HashMap", 0, hm2.size());
- }
-
- /**
- * java.util.HashMap#HashMap(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.HashMap(int)
- HashMap hm2 = new HashMap(5);
- assertEquals("Created incorrect HashMap", 0, hm2.size());
- try {
- new HashMap(-1);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- HashMap empty = new HashMap(0);
- assertNull("Empty hashmap access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
- }
-
- /**
- * java.util.HashMap#HashMap(int, float)
- */
- public void test_ConstructorIF() {
- // Test for method java.util.HashMap(int, float)
- HashMap hm2 = new HashMap(5, (float) 0.5);
- assertEquals("Created incorrect HashMap", 0, hm2.size());
- try {
- new HashMap(0, 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- HashMap empty = new HashMap(0, 0.75f);
- assertNull("Empty hashtable access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
- }
-
- /**
- * java.util.HashMap#HashMap(java.util.Map)
- */
- public void test_ConstructorLjava_util_Map() {
- // Test for method java.util.HashMap(java.util.Map)
- Map myMap = new TreeMap();
- for (int counter = 0; counter < hmSize; counter++)
- myMap.put(objArray2[counter], objArray[counter]);
- HashMap hm2 = new HashMap(myMap);
- for (int counter = 0; counter < hmSize; counter++)
- assertTrue("Failed to construct correct HashMap", hm
- .get(objArray2[counter]) == hm2.get(objArray2[counter]));
-
- Map mockMap = new MockMap();
- hm = new HashMap(mockMap);
- assertEquals(hm, mockMap);
- }
-
- /**
- * java.util.HashMap#clear()
- */
- public void test_clear() {
- // Test for method void java.util.HashMap.clear()
- hm.clear();
- assertEquals("Clear failed to reset size", 0, hm.size());
- for (int i = 0; i < hmSize; i++)
- assertNull("Failed to clear all elements",
- hm.get(objArray2[i]));
-
- }
-
- /**
- * java.util.HashMap#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.HashMap.clone()
- HashMap hm2 = (HashMap) hm.clone();
- assertTrue("Clone answered equivalent HashMap", hm2 != hm);
- for (int counter = 0; counter < hmSize; counter++)
- assertTrue("Clone answered unequal HashMap", hm
- .get(objArray2[counter]) == hm2.get(objArray2[counter]));
-
- HashMap map = new HashMap();
- map.put("key", "value");
- // get the keySet() and values() on the original Map
- Set keys = map.keySet();
- Collection values = map.values();
- assertEquals("values() does not work",
- "value", values.iterator().next());
- assertEquals("keySet() does not work",
- "key", keys.iterator().next());
- AbstractMap map2 = (AbstractMap) map.clone();
- map2.put("key", "value2");
- Collection values2 = map2.values();
- assertTrue("values() is identical", values2 != values);
- // values() and keySet() on the cloned() map should be different
- assertEquals("values() was not cloned",
- "value2", values2.iterator().next());
- map2.clear();
- map2.put("key2", "value3");
- Set key2 = map2.keySet();
- assertTrue("keySet() is identical", key2 != keys);
- assertEquals("keySet() was not cloned",
- "key2", key2.iterator().next());
-
- // regresion test for HARMONY-4603
- HashMap hashmap = new HashMap();
- MockClonable mock = new MockClonable(1);
- hashmap.put(1, mock);
- assertEquals(1, ((MockClonable) hashmap.get(1)).i);
- HashMap hm3 = (HashMap)hashmap.clone();
- assertEquals(1, ((MockClonable) hm3.get(1)).i);
- mock.i = 0;
- assertEquals(0, ((MockClonable) hashmap.get(1)).i);
- assertEquals(0, ((MockClonable) hm3.get(1)).i);
- }
-
- /**
- * java.util.HashMap#containsKey(java.lang.Object)
- */
- public void test_containsKeyLjava_lang_Object() {
- // Test for method boolean
- // java.util.HashMap.containsKey(java.lang.Object)
- assertTrue("Returned false for valid key", hm.containsKey(new Integer(
- 876).toString()));
- assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
-
- HashMap m = new HashMap();
- m.put(null, "test");
- assertTrue("Failed with null key", m.containsKey(null));
- assertTrue("Failed with missing key matching null hash", !m
- .containsKey(new Integer(0)));
- }
-
- /**
- * java.util.HashMap#containsValue(java.lang.Object)
- */
- public void test_containsValueLjava_lang_Object() {
- // Test for method boolean
- // java.util.HashMap.containsValue(java.lang.Object)
- assertTrue("Returned false for valid value", hm
- .containsValue(new Integer(875)));
- assertTrue("Returned true for invalid valie", !hm
- .containsValue(new Integer(-9)));
- }
-
- /**
- * java.util.HashMap#entrySet()
- */
- public void test_entrySet() {
- // Test for method java.util.Set java.util.HashMap.entrySet()
- Set s = hm.entrySet();
- Iterator i = s.iterator();
- assertTrue("Returned set of incorrect size", hm.size() == s.size());
- while (i.hasNext()) {
- Map.Entry m = (Map.Entry) i.next();
- assertTrue("Returned incorrect entry set", hm.containsKey(m
- .getKey())
- && hm.containsValue(m.getValue()));
- }
- }
-
- /**
- * java.util.HashMap#entrySet()
- */
- public void test_entrySetEquals() {
- Set s1 = hm.entrySet();
- Set s2 = new HashMap(hm).entrySet();
- assertEquals(s1, s2);
- }
-
- /**
- * java.util.HashMap#entrySet()
- */
- public void test_removeFromViews() {
- hm.put("A", null);
- hm.put("B", null);
- assertTrue(hm.keySet().remove("A"));
-
- Map<String, String> m2 = new HashMap<String, String>();
- m2.put("B", null);
- assertTrue(hm.entrySet().remove(m2.entrySet().iterator().next()));
- }
-
- /**
- * java.util.HashMap#get(java.lang.Object)
- */
- public void test_getLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.HashMap.get(java.lang.Object)
- assertNull("Get returned non-null for non existent key",
- hm.get("T"));
- hm.put("T", "HELLO");
- assertEquals("Get returned incorrect value for existing key", "HELLO", hm.get("T")
- );
-
- HashMap m = new HashMap();
- m.put(null, "test");
- assertEquals("Failed with null key", "test", m.get(null));
- assertNull("Failed with missing key matching null hash", m
- .get(new Integer(0)));
-
- // Regression for HARMONY-206
- ReusableKey k = new ReusableKey();
- HashMap map = new HashMap();
- k.setKey(1);
- map.put(k, "value1");
-
- k.setKey(18);
- assertNull(map.get(k));
-
- k.setKey(17);
- assertNull(map.get(k));
- }
-
- /**
- * java.util.HashMap#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.HashMap.isEmpty()
- assertTrue("Returned false for new map", new HashMap().isEmpty());
- assertTrue("Returned true for non-empty", !hm.isEmpty());
- }
-
- /**
- * java.util.HashMap#keySet()
- */
- public void test_keySet() {
- // Test for method java.util.Set java.util.HashMap.keySet()
- Set s = hm.keySet();
- assertTrue("Returned set of incorrect size()", s.size() == hm.size());
- for (int i = 0; i < objArray.length; i++)
- assertTrue("Returned set does not contain all keys", s
- .contains(objArray[i].toString()));
-
- HashMap m = new HashMap();
- m.put(null, "test");
- assertTrue("Failed with null key", m.keySet().contains(null));
- assertNull("Failed with null key", m.keySet().iterator().next());
-
- Map map = new HashMap(101);
- map.put(new Integer(1), "1");
- map.put(new Integer(102), "102");
- map.put(new Integer(203), "203");
- Iterator it = map.keySet().iterator();
- Integer remove1 = (Integer) it.next();
- it.hasNext();
- it.remove();
- Integer remove2 = (Integer) it.next();
- it.remove();
- ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
- new Integer(1), new Integer(102), new Integer(203) }));
- list.remove(remove1);
- list.remove(remove2);
- assertTrue("Wrong result", it.next().equals(list.get(0)));
- assertEquals("Wrong size", 1, map.size());
- assertTrue("Wrong contents", map.keySet().iterator().next().equals(
- list.get(0)));
-
- Map map2 = new HashMap(101);
- map2.put(new Integer(1), "1");
- map2.put(new Integer(4), "4");
- Iterator it2 = map2.keySet().iterator();
- Integer remove3 = (Integer) it2.next();
- Integer next;
- if (remove3.intValue() == 1)
- next = new Integer(4);
- else
- next = new Integer(1);
- it2.hasNext();
- it2.remove();
- assertTrue("Wrong result 2", it2.next().equals(next));
- assertEquals("Wrong size 2", 1, map2.size());
- assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
- next));
- }
-
- /**
- * java.util.HashMap#put(java.lang.Object, java.lang.Object)
- */
- public void test_putLjava_lang_ObjectLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.HashMap.put(java.lang.Object, java.lang.Object)
- hm.put("KEY", "VALUE");
- assertEquals("Failed to install key/value pair",
- "VALUE", hm.get("KEY"));
-
- HashMap m = new HashMap();
- m.put(new Short((short) 0), "short");
- m.put(null, "test");
- m.put(new Integer(0), "int");
- assertEquals("Failed adding to bucket containing null", "short", m.get(
- new Short((short) 0)));
- assertEquals("Failed adding to bucket containing null2", "int", m.get(
- new Integer(0)));
- }
-
- /**
- * java.util.HashMap#putAll(java.util.Map)
- */
- public void test_putAllLjava_util_Map() {
- // Test for method void java.util.HashMap.putAll(java.util.Map)
- HashMap hm2 = new HashMap();
- hm2.putAll(hm);
- for (int i = 0; i < 1000; i++)
- assertTrue("Failed to clear all elements", hm2.get(
- new Integer(i).toString()).equals((new Integer(i))));
-
- Map mockMap = new MockMap();
- hm2 = new HashMap();
- hm2.putAll(mockMap);
- assertEquals("Size should be 0", 0, hm2.size());
- }
-
- /**
- * java.util.HashMap#putAll(java.util.Map)
- */
- public void test_putAllLjava_util_Map_Null() {
- HashMap hashMap = new HashMap();
- try {
- hashMap.putAll(new MockMapNull());
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected.
- }
-
- try {
- hashMap = new HashMap(new MockMapNull());
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected.
- }
- }
-
- public void test_putAllLjava_util_Map_Resize() {
- Random rnd = new Random(666);
-
- Map<Integer,Integer> m1 = new HashMap<Integer, Integer>();
- int MID = 10000;
- for (int i = 0; i < MID; i++) {
- Integer j = rnd.nextInt();
- m1.put(j, j);
- }
-
- Map<Integer,Integer> m2 = new HashMap<Integer, Integer>();
- int HI = 30000;
- for (int i = MID; i < HI; i++) {
- Integer j = rnd.nextInt();
- m2.put(j, j);
- }
-
- m1.putAll(m2);
-
- rnd = new Random(666);
- for (int i = 0; i < HI; i++) {
- Integer j = rnd.nextInt();
- assertEquals(j, m1.get(j));
- }
- }
-
- /**
- * java.util.HashMap#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.HashMap.remove(java.lang.Object)
- int size = hm.size();
- Integer y = new Integer(9);
- Integer x = ((Integer) hm.remove(y.toString()));
- assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
- assertNull("Failed to remove given key", hm.get(new Integer(9)));
- assertTrue("Failed to decrement size", hm.size() == (size - 1));
- assertNull("Remove of non-existent key returned non-null", hm
- .remove("LCLCLC"));
-
- HashMap m = new HashMap();
- m.put(null, "test");
- assertNull("Failed with same hash as null",
- m.remove(new Integer(0)));
- assertEquals("Failed with null key", "test", m.remove(null));
- }
-
- /**
- * java.util.HashMap#size()
- */
- public void test_size() {
- // Test for method int java.util.HashMap.size()
- assertTrue("Returned incorrect size",
- hm.size() == (objArray.length + 2));
- }
-
- /**
- * java.util.HashMap#values()
- */
- public void test_values() {
- // Test for method java.util.Collection java.util.HashMap.values()
- Collection c = hm.values();
- assertTrue("Returned collection of incorrect size()", c.size() == hm
- .size());
- for (int i = 0; i < objArray.length; i++)
- assertTrue("Returned collection does not contain all keys", c
- .contains(objArray[i]));
-
- HashMap myHashMap = new HashMap();
- for (int i = 0; i < 100; i++)
- myHashMap.put(objArray2[i], objArray[i]);
- Collection values = myHashMap.values();
- new Support_UnmodifiableCollectionTest(
- "Test Returned Collection From HashMap.values()", values)
- .runTest();
- values.remove(new Integer(0));
- assertTrue(
- "Removing from the values collection should remove from the original map",
- !myHashMap.containsValue(new Integer(0)));
-
- }
-
- static class ReusableKey {
- private int key = 0;
-
- public void setKey(int key) {
- this.key = key;
- }
-
- public int hashCode() {
- return key;
- }
-
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof ReusableKey)) {
- return false;
- }
- return key == ((ReusableKey) o).key;
- }
- }
- public void test_Map_Entry_hashCode() {
- //Related to HARMONY-403
- HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(10);
- Integer key = new Integer(1);
- Integer val = new Integer(2);
- map.put(key, val);
- int expected = key.hashCode() ^ val.hashCode();
- assertEquals(expected, map.hashCode());
- key = new Integer(4);
- val = new Integer(8);
- map.put(key, val);
- expected += key.hashCode() ^ val.hashCode();
- assertEquals(expected, map.hashCode());
- }
-
- class MockClonable implements Cloneable{
- public int i;
-
- public MockClonable(int i) {
- this.i = i;
- }
-
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return new MockClonable(i);
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- objArray = new Object[hmSize];
- objArray2 = new Object[hmSize];
- for (int i = 0; i < objArray.length; i++) {
- objArray[i] = new Integer(i);
- objArray2[i] = objArray[i].toString();
- }
-
- hm = new HashMap();
- for (int i = 0; i < objArray.length; i++)
- hm.put(objArray2[i], objArray[i]);
- hm.put("test", null);
- hm.put(null, "test");
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- hm = null;
- objArray = null;
- objArray2 = null;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/HashSetTest.java b/luni/src/test/java/tests/api/java/util/HashSetTest.java
deleted file mode 100644
index e4a65b7..0000000
--- a/luni/src/test/java/tests/api/java/util/HashSetTest.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.io.ObjectOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-public class HashSetTest extends junit.framework.TestCase {
-
- HashSet hs;
-
- Object[] objArray;
-
- /**
- * java.util.HashSet#HashSet()
- */
- public void test_Constructor() {
- // Test for method java.util.HashSet()
- HashSet hs2 = new HashSet();
- assertEquals("Created incorrect HashSet", 0, hs2.size());
- }
-
- /**
- * java.util.HashSet#HashSet(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.HashSet(int)
- HashSet hs2 = new HashSet(5);
- assertEquals("Created incorrect HashSet", 0, hs2.size());
- try {
- new HashSet(-1);
- } catch (IllegalArgumentException e) {
- return;
- }
- fail(
- "Failed to throw IllegalArgumentException for capacity < 0");
- }
-
- /**
- * java.util.HashSet#HashSet(int, float)
- */
- public void test_ConstructorIF() {
- // Test for method java.util.HashSet(int, float)
- HashSet hs2 = new HashSet(5, (float) 0.5);
- assertEquals("Created incorrect HashSet", 0, hs2.size());
- try {
- new HashSet(0, 0);
- } catch (IllegalArgumentException e) {
- return;
- }
- fail(
- "Failed to throw IllegalArgumentException for initial load factor <= 0");
- }
-
- /**
- * java.util.HashSet#HashSet(java.util.Collection)
- */
- public void test_ConstructorLjava_util_Collection() {
- // Test for method java.util.HashSet(java.util.Collection)
- HashSet hs2 = new HashSet(Arrays.asList(objArray));
- for (int counter = 0; counter < objArray.length; counter++)
- assertTrue("HashSet does not contain correct elements", hs
- .contains(objArray[counter]));
- assertTrue("HashSet created from collection incorrect size",
- hs2.size() == objArray.length);
-
- try {
- new HashSet(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.HashSet#add(java.lang.Object)
- */
- public void test_addLjava_lang_Object() {
- // Test for method boolean java.util.HashSet.add(java.lang.Object)
- int size = hs.size();
- hs.add(new Integer(8));
- assertTrue("Added element already contained by set", hs.size() == size);
- hs.add(new Integer(-9));
- assertTrue("Failed to increment set size after add",
- hs.size() == size + 1);
- assertTrue("Failed to add element to set", hs.contains(new Integer(-9)));
- }
-
- /**
- * java.util.HashSet#clear()
- */
- public void test_clear() {
- // Test for method void java.util.HashSet.clear()
- Set orgSet = (Set) hs.clone();
- hs.clear();
- Iterator i = orgSet.iterator();
- assertEquals("Returned non-zero size after clear", 0, hs.size());
- while (i.hasNext())
- assertTrue("Failed to clear set", !hs.contains(i.next()));
- }
-
- /**
- * java.util.HashSet#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.HashSet.clone()
- HashSet hs2 = (HashSet) hs.clone();
- assertTrue("clone returned an equivalent HashSet", hs != hs2);
- assertTrue("clone did not return an equal HashSet", hs.equals(hs2));
- }
-
- /**
- * java.util.HashSet#contains(java.lang.Object)
- */
- public void test_containsLjava_lang_Object() {
- // Test for method boolean java.util.HashSet.contains(java.lang.Object)
- assertTrue("Returned false for valid object", hs.contains(objArray[90]));
- assertTrue("Returned true for invalid Object", !hs
- .contains(new Object()));
-
- HashSet s = new HashSet();
- s.add(null);
- assertTrue("Cannot handle null", s.contains(null));
- }
-
- /**
- * java.util.HashSet#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.HashSet.isEmpty()
- assertTrue("Empty set returned false", new HashSet().isEmpty());
- assertTrue("Non-empty set returned true", !hs.isEmpty());
- }
-
- /**
- * java.util.HashSet#iterator()
- */
- public void test_iterator() {
- // Test for method java.util.Iterator java.util.HashSet.iterator()
- Iterator i = hs.iterator();
- int x = 0;
- while (i.hasNext()) {
- assertTrue("Failed to iterate over all elements", hs.contains(i
- .next()));
- ++x;
- }
- assertTrue("Returned iteration of incorrect size", hs.size() == x);
-
- HashSet s = new HashSet();
- s.add(null);
- assertNull("Cannot handle null", s.iterator().next());
- }
-
- /**
- * java.util.HashSet#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method boolean java.util.HashSet.remove(java.lang.Object)
- int size = hs.size();
- hs.remove(new Integer(98));
- assertTrue("Failed to remove element", !hs.contains(new Integer(98)));
- assertTrue("Failed to decrement set size", hs.size() == size - 1);
-
- HashSet s = new HashSet();
- s.add(null);
- assertTrue("Cannot handle null", s.remove(null));
- assertFalse(hs.remove(new Integer(-98)));
- }
-
- /**
- * java.util.HashSet#size()
- */
- public void test_size() {
- // Test for method int java.util.HashSet.size()
- assertTrue("Returned incorrect size", hs.size() == (objArray.length + 1));
- hs.clear();
- assertEquals("Cleared set returned non-zero size", 0, hs.size());
- }
-
- /**
- * java.util.HashSet#SerializationTest
- */
- public void test_Serialization() throws Exception{
- HashSet<String> hs = new HashSet<String>();
- hs.add("hello");
- hs.add("world");
- SerializationTest.verifySelf(hs, comparator);
- SerializationTest.verifyGolden(this, hs, comparator);
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- objArray = new Object[1000];
- for (int i = 0; i < objArray.length; i++) {
- objArray[i] = new Integer(i);
- }
-
- hs = new HashSet();
- for (int i = 0; i < objArray.length; i++) {
- hs.add(objArray[i]);
- }
-
- hs.add(null);
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- hs = null;
- objArray = null;
- }
-
- private static final SerializationTest.SerializableAssert comparator = new
- SerializationTest.SerializableAssert() {
- public void assertDeserialized(Serializable initial, Serializable deserialized) {
- HashSet<String> initialHs = (HashSet<String>) initial;
- HashSet<String> deseriaHs = (HashSet<String>) deserialized;
- assertEquals("should be equal", initialHs.size(), deseriaHs.size());
- assertEquals("should be equal", initialHs, deseriaHs);
- }
-
- };
-}
diff --git a/luni/src/test/java/tests/api/java/util/HashtableTest.java b/luni/src/test/java/tests/api/java/util/HashtableTest.java
deleted file mode 100644
index 9c97c7b..0000000
--- a/luni/src/test/java/tests/api/java/util/HashtableTest.java
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.Vector;
-import java.util.Collections;
-
-import tests.api.java.util.HashMapTest.ReusableKey;
-import tests.support.Support_MapTest2;
-import tests.support.Support_UnmodifiableCollectionTest;
-
-public class HashtableTest extends junit.framework.TestCase {
-
- private Hashtable ht10;
-
- private Hashtable ht100;
-
- private Hashtable htfull;
-
- private Vector keyVector;
-
- private Vector elmVector;
-
- private String h10sVal;
-
- /**
- * java.util.Hashtable#Hashtable()
- */
- public void test_Constructor() {
- // Test for method java.util.Hashtable()
- new Support_MapTest2(new Hashtable()).runTest();
-
- Hashtable h = new Hashtable();
-
- assertEquals("Created incorrect hashtable", 0, h.size());
- }
-
- /**
- * java.util.Hashtable#Hashtable(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.Hashtable(int)
- Hashtable h = new Hashtable(9);
-
- assertEquals("Created incorrect hashtable", 0, h.size());
-
- Hashtable empty = new Hashtable(0);
- assertNull("Empty hashtable access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
-
- try {
- new Hashtable(-1);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#Hashtable(int, float)
- */
- public void test_ConstructorIF() {
- // Test for method java.util.Hashtable(int, float)
- Hashtable h = new java.util.Hashtable(10, 0.5f);
- assertEquals("Created incorrect hashtable", 0, h.size());
-
- Hashtable empty = new Hashtable(0, 0.75f);
- assertNull("Empty hashtable access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
-
- try {
- new Hashtable(-1, 0.75f);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new Hashtable(0, -0.75f);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#Hashtable(java.util.Map)
- */
- public void test_ConstructorLjava_util_Map() {
- // Test for method java.util.Hashtable(java.util.Map)
- Map map = new TreeMap();
- Object firstVal = "Gabba";
- Object secondVal = new Integer(5);
- map.put("Gah", firstVal);
- map.put("Ooga", secondVal);
- Hashtable ht = new Hashtable(map);
- assertTrue("a) Incorrect Hashtable constructed",
- ht.get("Gah") == firstVal);
- assertTrue("b) Incorrect Hashtable constructed",
- ht.get("Ooga") == secondVal);
-
- try {
- new Hashtable(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#Hashtable(java.util.Map)
- */
- public void test_ConversionConstructorNullValue() {
- Map<String, Void> map = Collections.singletonMap("Dog", null);
- try {
- new Hashtable<String, Void>(map);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
- /**
- * java.util.Hashtable#clear()
- */
- public void test_clear() {
- // Test for method void java.util.Hashtable.clear()
- Hashtable h = hashtableClone(htfull);
- h.clear();
- assertEquals("Hashtable was not cleared", 0, h.size());
- Enumeration el = h.elements();
- Enumeration keys = h.keys();
- assertTrue("Hashtable improperly cleared", !el.hasMoreElements()
- && !(keys.hasMoreElements()));
- }
-
- /**
- * java.util.Hashtable#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.Hashtable.clone()
-
- Hashtable h = (Hashtable) htfull.clone();
- assertTrue("Clone different size than original", h.size() == htfull
- .size());
-
- Enumeration org = htfull.keys();
- Enumeration cpy = h.keys();
-
- String okey, ckey;
- while (org.hasMoreElements()) {
- assertTrue("Key comparison failed", (okey = (String) org
- .nextElement()).equals(ckey = (String) cpy.nextElement()));
- assertTrue("Value comparison failed", ((String) htfull.get(okey))
- .equals((String) h.get(ckey)));
- }
- assertTrue("Copy has more keys than original", !cpy.hasMoreElements());
- }
-
- /**
- * java.util.Hashtable#contains(java.lang.Object)
- */
- public void test_containsLjava_lang_Object() {
- // Test for method boolean
- // java.util.Hashtable.contains(java.lang.Object)
- assertTrue("Element not found", ht10.contains("Val 7"));
- assertTrue("Invalid element found", !ht10.contains("ZZZZZZZZZZZZZZZZ"));
-
- try {
- ht10.contains(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#containsKey(java.lang.Object)
- */
- public void test_containsKeyLjava_lang_Object() {
- // Test for method boolean
- // java.util.Hashtable.containsKey(java.lang.Object)
-
- assertTrue("Failed to find key", htfull.containsKey("FKey 4"));
- assertTrue("Failed to find key", !htfull.containsKey("FKey 99"));
-
- try {
- htfull.containsKey(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#containsValue(java.lang.Object)
- */
- public void test_containsValueLjava_lang_Object() {
- // Test for method boolean
- // java.util.Hashtable.containsValue(java.lang.Object)
- Enumeration e = elmVector.elements();
- while (e.hasMoreElements())
- assertTrue("Returned false for valid value", ht10.containsValue(e
- .nextElement()));
- assertTrue("Returned true for invalid value", !ht10
- .containsValue(new Object()));
-
- try {
- ht10.containsValue(null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#elements()
- */
- public void test_elements() {
- // Test for method java.util.Enumeration java.util.Hashtable.elements()
- Enumeration elms = ht10.elements();
- int i = 0;
- while (elms.hasMoreElements()) {
- String s = (String) elms.nextElement();
- assertTrue("Missing key from enumeration", elmVector.contains(s));
- ++i;
- }
-
- assertEquals("All keys not retrieved", 10, ht10.size());
- }
-
-// BEGIN android-removed
-// implementation dependent
-// /**
-// * java.util.Hashtable#elements()
-// */
-// public void test_elements_subtest0() {
-// // this is the reference implementation behavior
-// final Hashtable ht = new Hashtable(7);
-// ht.put("1", "a");
-// // these three elements hash to the same bucket in a 7 element Hashtable
-// ht.put("2", "b");
-// ht.put("9", "c");
-// ht.put("12", "d");
-// // Hashtable looks like:
-// // 0: "1"
-// // 1: "12" -> "9" -> "2"
-// Enumeration en = ht.elements();
-// // cache the first entry
-// en.hasMoreElements();
-// ht.remove("12");
-// ht.remove("9");
-// boolean exception = false;
-// try {
-// // cached "12"
-// Object result = en.nextElement();
-// assertNull("unexpected: " + result, result);
-// // next is removed "9"
-// result = en.nextElement();
-// assertNull("unexpected: " + result, result);
-// result = en.nextElement();
-// assertTrue("unexpected: " + result, "b".equals(result));
-// } catch (NoSuchElementException e) {
-// exception = true;
-// }
-// assertTrue("unexpected NoSuchElementException", !exception);
-// }
-// END android-removed
-
- /**
- * java.util.Hashtable#entrySet()
- */
- public void test_entrySet() {
- // Test for method java.util.Set java.util.Hashtable.entrySet()
- Set s = ht10.entrySet();
- Set s2 = new HashSet();
- Iterator i = s.iterator();
- while (i.hasNext())
- s2.add(((Map.Entry) i.next()).getValue());
- Enumeration e = elmVector.elements();
- while (e.hasMoreElements())
- assertTrue("Returned incorrect entry set", s2.contains(e
- .nextElement()));
-// BEGIN android-removed
-// implementation dependent
-// assertEquals("Not synchronized",
-// "java.util.Collections$SynchronizedSet", s.getClass().getName());
-// END android-removed
-
- boolean exception = false;
- try {
- ((Map.Entry) ht10.entrySet().iterator().next()).setValue(null);
- } catch (NullPointerException e1) {
- exception = true;
- }
- assertTrue(
- "Should not be able to assign null to a Hashtable entrySet() Map.Entry",
- exception);
- }
-
- /**
- * java.util.Hashtable#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- // Test for method boolean java.util.Hashtable.equals(java.lang.Object)
- Hashtable h = hashtableClone(ht10);
- assertTrue("Returned false for equal tables", ht10.equals(h));
- assertTrue("Returned true for unequal tables", !ht10.equals(htfull));
- }
-
- /**
- * java.util.Hashtable#get(java.lang.Object)
- */
- public void test_getLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.Hashtable.get(java.lang.Object)
- Hashtable h = hashtableClone(htfull);
- assertEquals("Could not retrieve element", "FVal 2", ((String) h.get("FKey 2"))
- );
-
-// BEGIN android-removed
-// implementation dependent
-// // Regression for HARMONY-262
-// ReusableKey k = new ReusableKey();
-// Hashtable h2 = new Hashtable();
-// k.setKey(1);
-// h2.put(k, "value1");
-//
-// k.setKey(13);
-// assertNull(h2.get(k));
-//
-// k.setKey(12);
-// assertNull(h2.get(k));
-//
-// try {
-// h2.get(null);
-// fail("NullPointerException expected");
-// } catch (NullPointerException e) {
-// //expected
-// }
-// END android-removed
- }
-
- /**
- * java.util.Hashtable#hashCode()
- */
- public void test_hashCode() {
- // Test for method int java.util.Hashtable.hashCode()
- Set entrySet = ht10.entrySet();
- Iterator iterator = entrySet.iterator();
- int expectedHash;
- for (expectedHash = 0; iterator.hasNext(); expectedHash += iterator
- .next().hashCode())
- ;
- assertTrue("Incorrect hashCode returned. Wanted: " + expectedHash
- + " got: " + ht10.hashCode(), expectedHash == ht10.hashCode());
- }
-
- /**
- * java.util.Hashtable#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.Hashtable.isEmpty()
-
- assertTrue("isEmpty returned incorrect value", !ht10.isEmpty());
- assertTrue("isEmpty returned incorrect value",
- new java.util.Hashtable().isEmpty());
-
- final Hashtable ht = new Hashtable();
- ht.put("0", "");
- Thread t1 = new Thread() {
- public void run() {
- while (!ht.isEmpty())
- ;
- ht.put("final", "");
- }
- };
- t1.start();
- for (int i = 1; i < 10000; i++) {
- synchronized (ht) {
- ht.remove(String.valueOf(i - 1));
- ht.put(String.valueOf(i), "");
- }
- int size;
- if ((size = ht.size()) != 1) {
- String result = "Size is not 1: " + size + " " + ht;
- // terminate the thread
- ht.clear();
- fail(result);
- }
- }
- // terminate the thread
- ht.clear();
- }
-
- /**
- * java.util.Hashtable#keys()
- */
- public void test_keys() {
- // Test for method java.util.Enumeration java.util.Hashtable.keys()
-
- Enumeration keys = ht10.keys();
- int i = 0;
- while (keys.hasMoreElements()) {
- String s = (String) keys.nextElement();
- assertTrue("Missing key from enumeration", keyVector.contains(s));
- ++i;
- }
-
- assertEquals("All keys not retrieved", 10, ht10.size());
- }
-
- /**
- * java.util.Hashtable#keys()
- */
- public void test_keys_subtest0() {
- // this is the reference implementation behavior
- final Hashtable ht = new Hashtable(3);
- ht.put("initial", "");
- Enumeration en = ht.keys();
- en.hasMoreElements();
- ht.remove("initial");
- boolean exception = false;
- try {
- Object result = en.nextElement();
- assertTrue("unexpected: " + result, "initial".equals(result));
- } catch (NoSuchElementException e) {
- exception = true;
- }
- assertTrue("unexpected NoSuchElementException", !exception);
- }
-
- /**
- * java.util.Hashtable#keySet()
- */
- public void test_keySet() {
- // Test for method java.util.Set java.util.Hashtable.keySet()
- Set s = ht10.keySet();
- Enumeration e = keyVector.elements();
- while (e.hasMoreElements())
- assertTrue("Returned incorrect key set", s
- .contains(e.nextElement()));
-
-// BEGIN android-removed
-// implementation dependent
-// assertEquals("Not synchronized",
-// "java.util.Collections$SynchronizedSet", s.getClass().getName());
-// END android-removed
-
- Map map = new Hashtable(101);
- map.put(new Integer(1), "1");
- map.put(new Integer(102), "102");
- map.put(new Integer(203), "203");
- Iterator it = map.keySet().iterator();
- Integer remove1 = (Integer) it.next();
- it.remove();
- Integer remove2 = (Integer) it.next();
- it.remove();
- ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
- new Integer(1), new Integer(102), new Integer(203) }));
- list.remove(remove1);
- list.remove(remove2);
- assertTrue("Wrong result", it.next().equals(list.get(0)));
- assertEquals("Wrong size", 1, map.size());
- assertTrue("Wrong contents", map.keySet().iterator().next().equals(
- list.get(0)));
-
- Map map2 = new Hashtable(101);
- map2.put(new Integer(1), "1");
- map2.put(new Integer(4), "4");
- Iterator it2 = map2.keySet().iterator();
- Integer remove3 = (Integer) it2.next();
- Integer next;
- if (remove3.intValue() == 1)
- next = new Integer(4);
- else
- next = new Integer(1);
- it2.hasNext();
- it2.remove();
- assertTrue("Wrong result 2", it2.next().equals(next));
- assertEquals("Wrong size 2", 1, map2.size());
- assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
- next));
- }
-
- /**
- * java.util.Hashtable#keySet()
- */
- public void test_keySet_subtest0() {
- Set s1 = ht10.keySet();
- assertTrue("should contain key", s1.remove("Key 0"));
- assertTrue("should not contain key", !s1.remove("Key 0"));
-
- final int iterations = 10000;
- final Hashtable ht = new Hashtable();
- Thread t1 = new Thread() {
- public void run() {
- for (int i = 0; i < iterations; i++) {
- ht.put(String.valueOf(i), "");
- ht.remove(String.valueOf(i));
- }
- }
- };
- t1.start();
- Set set = ht.keySet();
- for (int i = 0; i < iterations; i++) {
- Iterator it = set.iterator();
- try {
- it.next();
- it.remove();
- int size;
- // ensure removing with the iterator doesn't corrupt the
- // Hashtable
- if ((size = ht.size()) < 0) {
- fail("invalid size: " + size);
- }
- } catch (NoSuchElementException e) {
- } catch (ConcurrentModificationException e) {
- }
- }
- }
-
-// BEGIN android-removed
-// implementation dependent
-// /**
-// * java.util.Hashtable#keySet()
-// */
-// public void test_keySet_subtest1() {
-// // this is the reference implementation behavior
-// final Hashtable ht = new Hashtable(7);
-// ht.put("1", "a");
-// // these three elements hash to the same bucket in a 7 element Hashtable
-// ht.put("2", "b");
-// ht.put("9", "c");
-// ht.put("12", "d");
-// // Hashtable looks like:
-// // 0: "1"
-// // 1: "12" -> "9" -> "2"
-// Enumeration en = ht.elements();
-// // cache the first entry
-// en.hasMoreElements();
-// Iterator it = ht.keySet().iterator();
-// // this is mostly a copy of the test in test_elements_subtest0()
-// // test removing with the iterator does not null the values
-// while (it.hasNext()) {
-// String key = (String) it.next();
-// if ("12".equals(key) || "9".equals(key)) {
-// it.remove();
-// }
-// }
-// it.remove();
-// boolean exception = false;
-// try {
-// // cached "12"
-// Object result = en.nextElement();
-// assertTrue("unexpected: " + result, "d".equals(result));
-// // next is removed "9"
-// result = en.nextElement();
-// assertTrue("unexpected: " + result, "c".equals(result));
-// result = en.nextElement();
-// assertTrue("unexpected: " + result, "b".equals(result));
-// } catch (NoSuchElementException e) {
-// exception = true;
-// }
-// assertTrue("unexpected NoSuchElementException", !exception);
-// }
-// END android-removed
-
- /**
- * java.util.Hashtable#put(java.lang.Object, java.lang.Object)
- */
- public void test_putLjava_lang_ObjectLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.Hashtable.put(java.lang.Object, java.lang.Object)
- Hashtable h = hashtableClone(ht100);
- Integer key = new Integer(100);
- h.put("Value 100", key);
- assertTrue("Key/Value not inserted", h.size() == 1 && (h.contains(key)));
-
- // Put into "full" table
- h = hashtableClone(htfull);
- h.put("Value 100", key);
- assertTrue("Key/Value not inserted into full table", h.size() == 8
- && (h.contains(key)));
-
- try {
- h.put(null, key);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
-
- try {
- h.put("Value 100", null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#putAll(java.util.Map)
- */
- public void test_putAllLjava_util_Map() {
- // Test for method void java.util.Hashtable.putAll(java.util.Map)
- Hashtable h = new Hashtable();
- h.putAll(ht10);
- Enumeration e = keyVector.elements();
- while (e.hasMoreElements()) {
- Object x = e.nextElement();
- assertTrue("Failed to put all elements", h.get(x).equals(
- ht10.get(x)));
- }
-
- try {
- h.putAll(null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.Hashtable.remove(java.lang.Object)
- Hashtable h = hashtableClone(htfull);
- Object k = h.remove("FKey 0");
- assertTrue("Remove failed", !h.containsKey("FKey 0") || k == null);
- assertNull(h.remove("FKey 0"));
-
- try {
- h.remove(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Hashtable#size()
- */
- public void test_size() {
- // Test for method int java.util.Hashtable.size()
- assertTrue("Returned invalid size", ht10.size() == 10
- && (ht100.size() == 0));
-
- final Hashtable ht = new Hashtable();
- ht.put("0", "");
- Thread t1 = new Thread() {
- public void run() {
- while (ht.size() > 0)
- ;
- ht.put("final", "");
- }
- };
- t1.start();
- for (int i = 1; i < 10000; i++) {
- synchronized (ht) {
- ht.remove(String.valueOf(i - 1));
- ht.put(String.valueOf(i), "");
- }
- int size;
- if ((size = ht.size()) != 1) {
- String result = "Size is not 1: " + size + " " + ht;
- // terminate the thread
- ht.clear();
- fail(result);
- }
- }
- // terminate the thread
- ht.clear();
- }
-
- /**
- * java.util.Hashtable#toString()
- */
- public void test_toString() {
- // Test for method java.lang.String java.util.Hashtable.toString()
- Hashtable h = new Hashtable();
- assertEquals("Incorrect toString for Empty table",
- "{}", h.toString());
-
- h.put("one", "1");
- h.put("two", h);
- h.put(h, "3");
- h.put(h, h);
- String result = h.toString();
- assertTrue("should contain self ref", result.indexOf("(this") > -1);
- }
-
- /**
- * java.util.Hashtable#values()
- */
- public void test_values() {
- // Test for method java.util.Collection java.util.Hashtable.values()
- Collection c = ht10.values();
- Enumeration e = elmVector.elements();
- while (e.hasMoreElements())
- assertTrue("Returned incorrect values", c.contains(e.nextElement()));
-
-// BEGIN android-removed
-// implementation dependent
-// assertEquals("Not synchronized",
-// "java.util.Collections$SynchronizedCollection", c.getClass().getName());
-// END android-removed
-
- Hashtable myHashtable = new Hashtable();
- for (int i = 0; i < 100; i++)
- myHashtable.put(new Integer(i), new Integer(i));
- Collection values = myHashtable.values();
- new Support_UnmodifiableCollectionTest(
- "Test Returned Collection From Hashtable.values()", values)
- .runTest();
- values.remove(new Integer(0));
- assertTrue(
- "Removing from the values collection should remove from the original map",
- !myHashtable.containsValue(new Integer(0)));
- }
-
- /**
- * Regression Test for JIRA 2181
- */
- public void test_entrySet_remove()
- {
- Hashtable<String,String> hashtable = new Hashtable<String,String>();
- hashtable.put("my.nonexistent.prop", "AAA");
- hashtable.put( "parse.error", "BBB" );
- Iterator<Map.Entry<String,String>> iterator =
- hashtable.entrySet().iterator();
- while(iterator.hasNext())
- {
- Map.Entry entry = iterator.next();
- final Object value = entry.getValue();
- if(value.equals("AAA"))
- {
- iterator.remove();
- }
- }
- assertFalse(hashtable.containsKey("my.nonexistent.prop"));
- }
-
- class Mock_Hashtable extends Hashtable {
- boolean flag = false;
-
- public Mock_Hashtable(int i) {
- super(i);
- }
-
- @Override
- protected void rehash() {
- flag = true;
- super.rehash();
- }
-
- public boolean isRehashed() {
- return flag;
- }
- }
-
- public void test_rehash() {
- Mock_Hashtable mht = new Mock_Hashtable(5);
-
- assertFalse(mht.isRehashed());
- for(int i = 0; i < 10; i++) {
- mht.put(i, "New value");
- }
- assertTrue(mht.isRehashed());
- }
-
- protected Hashtable hashtableClone(Hashtable s) {
- return (Hashtable) s.clone();
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
-
- ht10 = new Hashtable(10);
- ht100 = new Hashtable(100);
- htfull = new Hashtable(10);
- keyVector = new Vector(10);
- elmVector = new Vector(10);
-
- for (int i = 0; i < 10; i++) {
- ht10.put("Key " + i, "Val " + i);
- keyVector.addElement("Key " + i);
- elmVector.addElement("Val " + i);
- }
-
- for (int i = 0; i < 7; i++)
- htfull.put("FKey " + i, "FVal " + i);
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- ht10 = null;
- ht100 = null;
- htfull = null;
- keyVector = null;
- elmVector = null;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/IdentityHashMapTest.java b/luni/src/test/java/tests/api/java/util/IdentityHashMapTest.java
deleted file mode 100644
index 3bf1257..0000000
--- a/luni/src/test/java/tests/api/java/util/IdentityHashMapTest.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.io.Serializable;
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import tests.support.Support_MapTest2;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-public class IdentityHashMapTest extends junit.framework.TestCase {
- private static final String ID = "hello";
-
- class MockMap extends AbstractMap {
- public Set entrySet() {
- return null;
- }
- public int size(){
- return 0;
- }
- }
- /*
- * TODO: change all the statements testing the keys and values with equals()
- * method to check for reference equality instead
- */
-
- IdentityHashMap hm;
-
- final static int hmSize = 1000;
-
- Object[] objArray;
-
- Object[] objArray2;
-
- /**
- * java.util.IdentityHashMap#IdentityHashMap()
- */
- public void test_Constructor() {
- // Test for method java.util.IdentityHashMap()
- new Support_MapTest2(new IdentityHashMap()).runTest();
-
- IdentityHashMap hm2 = new IdentityHashMap();
- assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
- }
-
- /**
- * java.util.IdentityHashMap#IdentityHashMap(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.IdentityHashMap(int)
- IdentityHashMap hm2 = new IdentityHashMap(5);
- assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
- try {
- new IdentityHashMap(-1);
- fail("Failed to throw IllegalArgumentException for initial capacity < 0");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- IdentityHashMap empty = new IdentityHashMap(0);
- assertNull("Empty IdentityHashMap access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
- }
-
- /**
- * java.util.IdentityHashMap#IdentityHashMap(java.util.Map)
- */
- public void test_ConstructorLjava_util_Map() {
- // Test for method java.util.IdentityHashMap(java.util.Map)
- Map myMap = new TreeMap();
- for (int counter = 0; counter < hmSize; counter++)
- myMap.put(objArray2[counter], objArray[counter]);
- IdentityHashMap hm2 = new IdentityHashMap(myMap);
- for (int counter = 0; counter < hmSize; counter++)
- assertTrue("Failed to construct correct IdentityHashMap", hm
- .get(objArray2[counter]) == hm2.get(objArray2[counter]));
-
- Map mockMap = new MockMap();
- hm2 = new IdentityHashMap(mockMap);
- assertEquals("Size should be 0", 0, hm2.size());
-
- try {
- new IdentityHashMap(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.IdentityHashMap#clear()
- */
- public void test_clear() {
- // Test for method void java.util.IdentityHashMap.clear()
- hm.clear();
- assertEquals("Clear failed to reset size", 0, hm.size());
- for (int i = 0; i < hmSize; i++)
- assertNull("Failed to clear all elements",
- hm.get(objArray2[i]));
-
- }
-
- /**
- * java.util.IdentityHashMap#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.IdentityHashMap.clone()
- IdentityHashMap hm2 = (IdentityHashMap) hm.clone();
- assertTrue("Clone answered equivalent IdentityHashMap", hm2 != hm);
- for (int counter = 0; counter < hmSize; counter++)
- assertTrue("Clone answered unequal IdentityHashMap", hm
- .get(objArray2[counter]) == hm2.get(objArray2[counter]));
-
- IdentityHashMap map = new IdentityHashMap();
- map.put("key", "value");
- // get the keySet() and values() on the original Map
- Set keys = map.keySet();
- Collection values = map.values();
- assertEquals("values() does not work",
- "value", values.iterator().next());
- assertEquals("keySet() does not work",
- "key", keys.iterator().next());
- AbstractMap map2 = (AbstractMap) map.clone();
- map2.put("key", "value2");
- Collection values2 = map2.values();
- assertTrue("values() is identical", values2 != values);
- // values() and keySet() on the cloned() map should be different
- assertEquals("values() was not cloned",
- "value2", values2.iterator().next());
- map2.clear();
- map2.put("key2", "value3");
- Set key2 = map2.keySet();
- assertTrue("keySet() is identical", key2 != keys);
- assertEquals("keySet() was not cloned",
- "key2", key2.iterator().next());
- }
-
- /**
- * java.util.IdentityHashMap#containsKey(java.lang.Object)
- */
- public void test_containsKeyLjava_lang_Object() {
- // Test for method boolean
- // java.util.IdentityHashMap.containsKey(java.lang.Object)
- assertTrue("Returned false for valid key", hm
- .containsKey(objArray2[23]));
- assertTrue("Returned true for copy of valid key", !hm
- .containsKey(new Integer(23).toString()));
- assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
-
- IdentityHashMap m = new IdentityHashMap();
- m.put(null, "test");
- assertTrue("Failed with null key", m.containsKey(null));
- assertTrue("Failed with missing key matching null hash", !m
- .containsKey(new Integer(0)));
- }
-
- /**
- * java.util.IdentityHashMap#containsValue(java.lang.Object)
- */
- public void test_containsValueLjava_lang_Object() {
- // Test for method boolean
- // java.util.IdentityHashMap.containsValue(java.lang.Object)
- assertTrue("Returned false for valid value", hm
- .containsValue(objArray[19]));
- assertTrue("Returned true for invalid valie", !hm
- .containsValue(new Integer(-9)));
- }
-
- /**
- * java.util.IdentityHashMap#entrySet()
- */
- public void test_entrySet() {
- // Test for method java.util.Set java.util.IdentityHashMap.entrySet()
- Set s = hm.entrySet();
- Iterator i = s.iterator();
- assertTrue("Returned set of incorrect size", hm.size() == s.size());
- while (i.hasNext()) {
- Map.Entry m = (Map.Entry) i.next();
- assertTrue("Returned incorrect entry set", hm.containsKey(m
- .getKey())
- && hm.containsValue(m.getValue()));
- }
- }
-
- /**
- * java.util.IdentityHashMap#get(java.lang.Object)
- */
- public void test_getLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.IdentityHashMap.get(java.lang.Object)
- assertNull("Get returned non-null for non existent key",
- hm.get("T"));
- hm.put("T", "HELLO");
- assertEquals("Get returned incorecct value for existing key", "HELLO", hm.get("T")
- );
-
- IdentityHashMap m = new IdentityHashMap();
- m.put(null, "test");
- assertEquals("Failed with null key", "test", m.get(null));
- assertNull("Failed with missing key matching null hash", m
- .get(new Integer(0)));
- }
-
- /**
- * java.util.IdentityHashMap#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.IdentityHashMap.isEmpty()
- assertTrue("Returned false for new map", new IdentityHashMap()
- .isEmpty());
- assertTrue("Returned true for non-empty", !hm.isEmpty());
- }
-
- /**
- * java.util.IdentityHashMap#keySet()
- */
- public void test_keySet() {
- // Test for method java.util.Set java.util.IdentityHashMap.keySet()
- Set s = hm.keySet();
- assertTrue("Returned set of incorrect size()", s.size() == hm.size());
- for (int i = 0; i < objArray.length; i++) {
- assertTrue("Returned set does not contain all keys", s
- .contains(objArray2[i]));
- }
-
- IdentityHashMap m = new IdentityHashMap();
- m.put(null, "test");
- assertTrue("Failed with null key", m.keySet().contains(null));
- assertNull("Failed with null key", m.keySet().iterator().next());
-
- Map map = new IdentityHashMap(101);
- map.put(new Integer(1), "1");
- map.put(new Integer(102), "102");
- map.put(new Integer(203), "203");
- Iterator it = map.keySet().iterator();
- Integer remove1 = (Integer) it.next();
- it.hasNext();
- it.remove();
- Integer remove2 = (Integer) it.next();
- it.remove();
- ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
- new Integer(1), new Integer(102), new Integer(203) }));
- list.remove(remove1);
- list.remove(remove2);
- assertTrue("Wrong result", it.next().equals(list.get(0)));
- assertEquals("Wrong size", 1, map.size());
- assertTrue("Wrong contents", map.keySet().iterator().next().equals(
- list.get(0)));
-
- Map map2 = new IdentityHashMap(101);
- map2.put(new Integer(1), "1");
- map2.put(new Integer(4), "4");
- Iterator it2 = map2.keySet().iterator();
- Integer remove3 = (Integer) it2.next();
- Integer next;
- if (remove3.intValue() == 1)
- next = new Integer(4);
- else
- next = new Integer(1);
- it2.hasNext();
- it2.remove();
- assertTrue("Wrong result 2", it2.next().equals(next));
- assertEquals("Wrong size 2", 1, map2.size());
- assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
- next));
- }
-
- /**
- * java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
- */
- public void test_putLjava_lang_ObjectLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.IdentityHashMap.put(java.lang.Object, java.lang.Object)
- hm.put("KEY", "VALUE");
- assertEquals("Failed to install key/value pair",
- "VALUE", hm.get("KEY"));
-
- IdentityHashMap m = new IdentityHashMap();
- Short s0 = new Short((short) 0);
- m.put(s0, "short");
- m.put(null, "test");
- Integer i0 = new Integer(0);
- m.put(i0, "int");
- assertEquals("Failed adding to bucket containing null",
- "short", m.get(s0));
- assertEquals("Failed adding to bucket containing null2", "int", m.get(i0)
- );
- }
-
- /**
- * java.util.IdentityHashMap#putAll(java.util.Map)
- */
- public void test_putAllLjava_util_Map() {
- // Test for method void java.util.IdentityHashMap.putAll(java.util.Map)
- IdentityHashMap hm2 = new IdentityHashMap();
- hm2.putAll(hm);
- for (int i = 0; i < 1000; i++)
- assertTrue("Failed to clear all elements", hm2.get(objArray2[i])
- .equals((new Integer(i))));
-
- hm2 = new IdentityHashMap();
- Map mockMap = new MockMap();
- hm2.putAll(mockMap);
- assertEquals("Size should be 0", 0, hm2.size());
-
- try {
- hm2.putAll(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.IdentityHashMap#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.IdentityHashMap.remove(java.lang.Object)
- int size = hm.size();
- Integer x = ((Integer) hm.remove(objArray2[9]));
- assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
- assertNull("Failed to remove given key", hm.get(objArray2[9]));
- assertTrue("Failed to decrement size", hm.size() == (size - 1));
- assertNull("Remove of non-existent key returned non-null", hm
- .remove("LCLCLC"));
-
- IdentityHashMap m = new IdentityHashMap();
- m.put(null, "test");
- assertNull("Failed with same hash as null",
- m.remove(objArray[0]));
- assertEquals("Failed with null key", "test", m.remove(null));
- }
-
- /**
- * java.util.IdentityHashMap#size()
- */
- public void test_size() {
- // Test for method int java.util.IdentityHashMap.size()
- assertEquals("Returned incorrect size, ", (objArray.length + 2), hm
- .size());
- }
-
- /**
- * java.util.IdentityHashMap#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- IdentityHashMap mapOne = new IdentityHashMap();
- IdentityHashMap mapTwo = new IdentityHashMap();
- IdentityHashMap mapThree = new IdentityHashMap();
- IdentityHashMap mapFour = new IdentityHashMap();
-
- String one = "one";
- String alsoOne = new String(one); // use the new operator to ensure a
- // new reference is constructed
- String two = "two";
- String alsoTwo = new String(two); // use the new operator to ensure a
- // new reference is constructed
-
- mapOne.put(one, two);
- mapFour.put(one, two);
-
- // these two are not equal to the above two
- mapTwo.put(alsoOne, two);
- mapThree.put(one, alsoTwo);
-
- assertEquals("failure of equality of IdentityHashMaps", mapOne, mapFour);
- assertTrue("failure of non-equality of IdentityHashMaps one and two",
- !mapOne.equals(mapTwo));
- assertTrue("failure of non-equality of IdentityHashMaps one and three",
- !mapOne.equals(mapThree));
- assertTrue("failure of non-equality of IdentityHashMaps two and three",
- !mapTwo.equals(mapThree));
-
- HashMap hashMapTwo = new HashMap();
- HashMap hashMapThree = new HashMap();
- hashMapTwo.put(alsoOne, two);
- hashMapThree.put(one, alsoTwo);
-
- assertTrue(
- "failure of non-equality of IdentityHashMaps one and Hashmap two",
- !mapOne.equals(hashMapTwo));
- assertTrue(
- "failure of non-equality of IdentityHashMaps one and Hashmap three",
- !mapOne.equals(hashMapThree));
- }
-
- /**
- * java.util.IdentityHashMap#values()
- */
- public void test_values() {
- // Test for method java.util.Collection
- // java.util.IdentityHashMap.values()
- Collection c = hm.values();
- assertTrue("Returned collection of incorrect size()", c.size() == hm
- .size());
- for (int i = 0; i < objArray.length; i++)
- assertTrue("Returned collection does not contain all keys", c
- .contains(objArray[i]));
-
- IdentityHashMap myIdentityHashMap = new IdentityHashMap();
- for (int i = 0; i < 100; i++)
- myIdentityHashMap.put(objArray2[i], objArray[i]);
- Collection values = myIdentityHashMap.values();
- values.remove(objArray[0]);
- assertTrue(
- "Removing from the values collection should remove from the original map",
- !myIdentityHashMap.containsValue(objArray2[0]));
-
- }
-
- /**
- * java.util.IdentityHashMap#Serialization()
- */
- public void test_Serialization() throws Exception {
- IdentityHashMap<String, String> map = new IdentityHashMap<String, String>();
- map.put(ID, "world");
- // BEGIN android-added
- // Regression test for null key in serialized IdentityHashMap (1178549)
- // Together with this change the IdentityHashMap.golden.ser resource
- // was replaced by a version that contains a map with a null key.
- map.put(null, "null");
- // END android-added
- SerializationTest.verifySelf(map, comparator);
- SerializationTest.verifyGolden(this, map, comparator);
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- objArray = new Object[hmSize];
- objArray2 = new Object[hmSize];
- for (int i = 0; i < objArray.length; i++) {
- objArray[i] = new Integer(i);
- // android-changed: the containsKey test requires unique strings.
- objArray2[i] = new String(objArray[i].toString());
- }
-
- hm = new IdentityHashMap();
- for (int i = 0; i < objArray.length; i++)
- hm.put(objArray2[i], objArray[i]);
- hm.put("test", null);
- hm.put(null, "test");
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- objArray = null;
- objArray2 = null;
- hm = null;
- }
-
- private static final SerializationTest.SerializableAssert comparator = new
- SerializationTest.SerializableAssert() {
-
- public void assertDeserialized(Serializable initial, Serializable deserialized) {
- IdentityHashMap<String, String> initialMap = (IdentityHashMap<String, String>) initial;
- IdentityHashMap<String, String> deseriaMap = (IdentityHashMap<String, String>) deserialized;
- assertEquals("should be equal", initialMap.size(), deseriaMap.size());
- }
-
- };
-}
diff --git a/luni/src/test/java/tests/api/java/util/InvalidPropertiesFormatExceptionTest.java b/luni/src/test/java/tests/api/java/util/InvalidPropertiesFormatExceptionTest.java
deleted file mode 100644
index 0b144a4..0000000
--- a/luni/src/test/java/tests/api/java/util/InvalidPropertiesFormatExceptionTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.java.util;
-
-import java.io.NotSerializableException;
-import java.util.InvalidPropertiesFormatException;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
-public class InvalidPropertiesFormatExceptionTest extends
- junit.framework.TestCase {
-
- /**
- * java.util.InvalidPropertiesFormatException#SerializationTest()
- */
- public void test_Serialization() throws Exception {
- InvalidPropertiesFormatException ipfe = new InvalidPropertiesFormatException(
- "Hey, this is InvalidPropertiesFormatException");
- try {
- SerializationTest.verifySelf(ipfe);
- } catch (NotSerializableException e) {
- // expected
- }
- }
-
-}
diff --git a/luni/src/test/java/tests/api/java/util/LinkedHashMapTest.java b/luni/src/test/java/tests/api/java/util/LinkedHashMapTest.java
deleted file mode 100644
index eff9493..0000000
--- a/luni/src/test/java/tests/api/java/util/LinkedHashMapTest.java
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import tests.support.Support_MapTest2;
-import tests.support.Support_UnmodifiableCollectionTest;
-
-/**
- * java.util.LinkedHashMap
- */
-public class LinkedHashMapTest extends junit.framework.TestCase {
-
- LinkedHashMap hm;
-
- final static int hmSize = 1000;
-
- Object[] objArray;
-
- Object[] objArray2;
-
- static final class CacheMap extends LinkedHashMap {
- protected boolean removeEldestEntry(Map.Entry e) {
- return size() > 5;
- }
- }
-
- private static class MockMapNull extends AbstractMap {
- @Override
- public Set entrySet() {
- return null;
- }
-
- @Override
- public int size() {
- return 10;
- }
- }
-
- /**
- * java.util.LinkedHashMap#LinkedHashMap()
- */
- public void test_Constructor() {
- // Test for method java.util.LinkedHashMap()
- new Support_MapTest2(new LinkedHashMap()).runTest();
-
- LinkedHashMap hm2 = new LinkedHashMap();
- assertEquals("Created incorrect LinkedHashMap", 0, hm2.size());
- }
-
- /**
- * java.util.LinkedHashMap#LinkedHashMap(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.LinkedHashMap(int)
- LinkedHashMap hm2 = new LinkedHashMap(5);
- assertEquals("Created incorrect LinkedHashMap", 0, hm2.size());
- try {
- new LinkedHashMap(-1);
- fail("Failed to throw IllegalArgumentException for initial " +
- "capacity < 0");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- LinkedHashMap empty = new LinkedHashMap(0);
- assertNull("Empty LinkedHashMap access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
- }
-
- /**
- * java.util.LinkedHashMap#LinkedHashMap(int, float)
- */
- public void test_ConstructorIF() {
- // Test for method java.util.LinkedHashMap(int, float)
- LinkedHashMap hm2 = new LinkedHashMap(5, (float) 0.5);
- assertEquals("Created incorrect LinkedHashMap", 0, hm2.size());
- try {
- new LinkedHashMap(0, 0);
- fail("Failed to throw IllegalArgumentException for initial " +
- "load factor <= 0");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- LinkedHashMap empty = new LinkedHashMap(0, 0.75f);
- assertNull("Empty hashtable access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
- }
-
- /**
- * java.util.LinkedHashMap#LinkedHashMap(java.util.Map)
- */
- public void test_ConstructorLjava_util_Map() {
- // Test for method java.util.LinkedHashMap(java.util.Map)
- Map myMap = new TreeMap();
- for (int counter = 0; counter < hmSize; counter++)
- myMap.put(objArray2[counter], objArray[counter]);
- LinkedHashMap hm2 = new LinkedHashMap(myMap);
- for (int counter = 0; counter < hmSize; counter++)
- assertTrue("Failed to construct correct LinkedHashMap", hm
- .get(objArray2[counter]) == hm2.get(objArray2[counter]));
- }
-
- /**
- * java.util.LinkedHashMap#get(java.lang.Object)
- */
- public void test_getLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.LinkedHashMap.get(java.lang.Object)
- assertNull("Get returned non-null for non existent key",
- hm.get("T"));
- hm.put("T", "HELLO");
- assertEquals("Get returned incorecct value for existing key", "HELLO", hm.get("T")
- );
-
- LinkedHashMap m = new LinkedHashMap();
- m.put(null, "test");
- assertEquals("Failed with null key", "test", m.get(null));
- assertNull("Failed with missing key matching null hash", m
- .get(new Integer(0)));
- }
-
- /**
- * java.util.LinkedHashMap#put(java.lang.Object, java.lang.Object)
- */
- public void test_putLjava_lang_ObjectLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.LinkedHashMap.put(java.lang.Object, java.lang.Object)
- hm.put("KEY", "VALUE");
- assertEquals("Failed to install key/value pair",
- "VALUE", hm.get("KEY"));
-
- LinkedHashMap m = new LinkedHashMap();
- m.put(new Short((short) 0), "short");
- m.put(null, "test");
- m.put(new Integer(0), "int");
- assertEquals("Failed adding to bucket containing null", "short", m.get(
- new Short((short) 0)));
- assertEquals("Failed adding to bucket containing null2", "int", m.get(
- new Integer(0)));
- }
-
-
- public void test_putPresent() {
- Map<String, String> m = new LinkedHashMap<String, String>(8, .75f, true);
- m.put("KEY", "VALUE");
- m.put("WOMBAT", "COMBAT");
- m.put("KEY", "VALUE");
- Map.Entry newest = null;
- for (Map.Entry<String, String> e : m.entrySet()) {
- newest = e;
- }
- assertEquals("KEY", newest.getKey());
- assertEquals("VALUE", newest.getValue());
- }
-
- /**
- * java.util.LinkedHashMap#putAll(java.util.Map)
- */
- public void test_putAllLjava_util_Map() {
- // Test for method void java.util.LinkedHashMap.putAll(java.util.Map)
- LinkedHashMap hm2 = new LinkedHashMap();
- hm2.putAll(hm);
- for (int i = 0; i < 1000; i++)
- assertTrue("Failed to clear all elements", hm2.get(
- new Integer(i).toString()).equals((new Integer(i))));
- }
-
- /**
- * java.util.LinkedHashMap#putAll(java.util.Map)
- */
- public void test_putAll_Ljava_util_Map_Null() {
- LinkedHashMap linkedHashMap = new LinkedHashMap();
- try {
- linkedHashMap.putAll(new MockMapNull());
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected.
- }
-
- try {
- linkedHashMap = new LinkedHashMap(new MockMapNull());
- fail("Should throw NullPointerException");
- } catch (NullPointerException e) {
- // expected.
- }
- }
-
- /**
- * java.util.LinkedHashMap#entrySet()
- */
- public void test_entrySet() {
- // Test for method java.util.Set java.util.LinkedHashMap.entrySet()
- Set s = hm.entrySet();
- Iterator i = s.iterator();
- assertTrue("Returned set of incorrect size", hm.size() == s.size());
- while (i.hasNext()) {
- Map.Entry m = (Map.Entry) i.next();
- assertTrue("Returned incorrect entry set", hm.containsKey(m
- .getKey())
- && hm.containsValue(m.getValue()));
- }
- }
-
- public void test_entrySetRemove() {
- entrySetRemoveHelper("military", "intelligence");
- entrySetRemoveHelper(null, "hypothesis");
- }
- private void entrySetRemoveHelper(String key, String value) {
- Map<String, String> m1 = new LinkedHashMap<String, String>();
- m1.put(key, value);
- m1.put("jumbo", "shrimp");
- LinkedHashMap<String, String> m2 = new LinkedHashMap<String, String>(m1);
- Set<Map.Entry<String, String>> s1 = m1.entrySet();
- s1.remove(m2.entrySet().iterator().next());
- assertEquals("jumbo", s1.iterator().next().getKey());
- }
-
- /**
- * java.util.LinkedHashMap#keySet()
- */
- public void test_keySet() {
- // Test for method java.util.Set java.util.LinkedHashMap.keySet()
- Set s = hm.keySet();
- assertTrue("Returned set of incorrect size()", s.size() == hm.size());
- for (int i = 0; i < objArray.length; i++)
- assertTrue("Returned set does not contain all keys", s
- .contains(objArray[i].toString()));
-
- LinkedHashMap m = new LinkedHashMap();
- m.put(null, "test");
- assertTrue("Failed with null key", m.keySet().contains(null));
- assertNull("Failed with null key", m.keySet().iterator().next());
-
- Map map = new LinkedHashMap(101);
- map.put(new Integer(1), "1");
- map.put(new Integer(102), "102");
- map.put(new Integer(203), "203");
- Iterator it = map.keySet().iterator();
- Integer remove1 = (Integer) it.next();
- it.hasNext();
- it.remove();
- Integer remove2 = (Integer) it.next();
- it.remove();
- ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
- new Integer(1), new Integer(102), new Integer(203) }));
- list.remove(remove1);
- list.remove(remove2);
- assertTrue("Wrong result", it.next().equals(list.get(0)));
- assertEquals("Wrong size", 1, map.size());
- assertTrue("Wrong contents", map.keySet().iterator().next().equals(
- list.get(0)));
-
- Map map2 = new LinkedHashMap(101);
- map2.put(new Integer(1), "1");
- map2.put(new Integer(4), "4");
- Iterator it2 = map2.keySet().iterator();
- Integer remove3 = (Integer) it2.next();
- Integer next;
- if (remove3.intValue() == 1)
- next = new Integer(4);
- else
- next = new Integer(1);
- it2.hasNext();
- it2.remove();
- assertTrue("Wrong result 2", it2.next().equals(next));
- assertEquals("Wrong size 2", 1, map2.size());
- assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
- next));
- }
-
- /**
- * java.util.LinkedHashMap#values()
- */
- public void test_values() {
- // Test for method java.util.Collection java.util.LinkedHashMap.values()
- Collection c = hm.values();
- assertTrue("Returned collection of incorrect size()", c.size() == hm
- .size());
- for (int i = 0; i < objArray.length; i++)
- assertTrue("Returned collection does not contain all keys", c
- .contains(objArray[i]));
-
- LinkedHashMap myLinkedHashMap = new LinkedHashMap();
- for (int i = 0; i < 100; i++)
- myLinkedHashMap.put(objArray2[i], objArray[i]);
- Collection values = myLinkedHashMap.values();
- new Support_UnmodifiableCollectionTest(
- "Test Returned Collection From LinkedHashMap.values()", values)
- .runTest();
- values.remove(new Integer(0));
- assertTrue(
- "Removing from the values collection should remove from the original map",
- !myLinkedHashMap.containsValue(new Integer(0)));
-
- }
-
- /**
- * java.util.LinkedHashMap#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.LinkedHashMap.remove(java.lang.Object)
- int size = hm.size();
- Integer y = new Integer(9);
- Integer x = ((Integer) hm.remove(y.toString()));
- assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
- assertNull("Failed to remove given key", hm.get(new Integer(9)));
- assertTrue("Failed to decrement size", hm.size() == (size - 1));
- assertNull("Remove of non-existent key returned non-null", hm
- .remove("LCLCLC"));
-
- LinkedHashMap m = new LinkedHashMap();
- m.put(null, "test");
- assertNull("Failed with same hash as null",
- m.remove(new Integer(0)));
- assertEquals("Failed with null key", "test", m.remove(null));
- }
-
- /**
- * java.util.LinkedHashMap#clear()
- */
- public void test_clear() {
- // Test for method void java.util.LinkedHashMap.clear()
- hm.clear();
- assertEquals("Clear failed to reset size", 0, hm.size());
- for (int i = 0; i < hmSize; i++)
- assertNull("Failed to clear all elements",
- hm.get(objArray2[i]));
-
- }
-
- /**
- * java.util.LinkedHashMap#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.LinkedHashMap.clone()
- LinkedHashMap hm2 = (LinkedHashMap) hm.clone();
- assertTrue("Clone answered equivalent LinkedHashMap", hm2 != hm);
- for (int counter = 0; counter < hmSize; counter++)
- assertTrue("Clone answered unequal LinkedHashMap", hm
- .get(objArray2[counter]) == hm2.get(objArray2[counter]));
-
- LinkedHashMap map = new LinkedHashMap();
- map.put("key", "value");
- // get the keySet() and values() on the original Map
- Set keys = map.keySet();
- Collection values = map.values();
- assertEquals("values() does not work",
- "value", values.iterator().next());
- assertEquals("keySet() does not work",
- "key", keys.iterator().next());
- AbstractMap map2 = (AbstractMap) map.clone();
- map2.put("key", "value2");
- Collection values2 = map2.values();
- assertTrue("values() is identical", values2 != values);
-
- // values() and keySet() on the cloned() map should be different
- assertEquals("values() was not cloned",
- "value2", values2.iterator().next());
- map2.clear();
- map2.put("key2", "value3");
- Set key2 = map2.keySet();
- assertTrue("keySet() is identical", key2 != keys);
- assertEquals("keySet() was not cloned",
- "key2", key2.iterator().next());
- }
-
- /**
- * java.util.LinkedHashMap#clone()
- */
- public void test_clone_ordered() {
- // Test for method java.lang.Object java.util.LinkedHashMap.clone()
- LinkedHashMap<String, String> hm1 = new LinkedHashMap<String, String>(10, 0.75f, true);
- hm1.put("a", "a");
- hm1.put("b", "b");
- hm1.put("c", "c");
- LinkedHashMap<String, String> hm2 = (LinkedHashMap<String, String>) hm1.clone();
- hm1.get("a");
-
- Map.Entry<String, String>[] set = new Map.Entry[3];
- Iterator<Map.Entry<String,String>> iterator = hm1.entrySet().iterator();
-
- assertEquals("b", iterator.next().getKey());
- assertEquals("c", iterator.next().getKey());
- assertEquals("a", iterator.next().getKey());
-
- iterator = hm2.entrySet().iterator();
- assertEquals("a", iterator.next().getKey());
- assertEquals("b", iterator.next().getKey());
- assertEquals("c", iterator.next().getKey());
- }
-
- // regresion test for HARMONY-4603
- public void test_clone_Mock() {
- LinkedHashMap hashMap = new MockMap();
- String value = "value a";
- hashMap.put("key", value);
- MockMap cloneMap = (MockMap) hashMap.clone();
- assertEquals(value, cloneMap.get("key"));
- assertEquals(hashMap, cloneMap);
- assertEquals(1, cloneMap.num);
-
- hashMap.put("key", "value b");
- assertFalse(hashMap.equals(cloneMap));
- }
-
- class MockMap extends LinkedHashMap {
- int num;
-
- public Object put(Object k, Object v) {
- num++;
- return super.put(k, v);
- }
-
- protected boolean removeEldestEntry(Map.Entry e) {
- return num > 1;
- }
- }
-
- /**
- * put/get interaction in access-order map where removeEldest
- * returns true.
- */
- public void test_removeEldestFromSameBucketAsNewEntry() {
- LinkedHashMap<String, String> map
- = new LinkedHashMap<String, String>(6, 0.75F, true) {
- @Override
- protected boolean removeEldestEntry(Entry<String, String> e) {
- return true;
- }
- };
- map.put("N", "E");
- map.put("F", "I");
- assertEquals(null, map.get("N"));
- }
-
- /**
- * java.util.LinkedHashMap#containsKey(java.lang.Object)
- */
- public void test_containsKeyLjava_lang_Object() {
- // Test for method boolean
- // java.util.LinkedHashMap.containsKey(java.lang.Object)
- assertTrue("Returned false for valid key", hm.containsKey(new Integer(
- 876).toString()));
- assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
-
- LinkedHashMap m = new LinkedHashMap();
- m.put(null, "test");
- assertTrue("Failed with null key", m.containsKey(null));
- assertTrue("Failed with missing key matching null hash", !m
- .containsKey(new Integer(0)));
- }
-
- /**
- * java.util.LinkedHashMap#containsValue(java.lang.Object)
- */
- public void test_containsValueLjava_lang_Object() {
- // Test for method boolean
- // java.util.LinkedHashMap.containsValue(java.lang.Object)
- assertTrue("Returned false for valid value", hm
- .containsValue(new Integer(875)));
- assertTrue("Returned true for invalid valie", !hm
- .containsValue(new Integer(-9)));
- }
-
- /**
- * java.util.LinkedHashMap#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.LinkedHashMap.isEmpty()
- assertTrue("Returned false for new map", new LinkedHashMap().isEmpty());
- assertTrue("Returned true for non-empty", !hm.isEmpty());
- }
-
- /**
- * java.util.LinkedHashMap#size()
- */
- public void test_size() {
- // Test for method int java.util.LinkedHashMap.size()
- assertTrue("Returned incorrect size",
- hm.size() == (objArray.length + 2));
- }
-
- /**
- * java.util.LinkedHashMap#entrySet()
- */
- public void test_ordered_entrySet() {
- int i;
- int sz = 100;
- LinkedHashMap lhm = new LinkedHashMap();
- for (i = 0; i < sz; i++) {
- Integer ii = new Integer(i);
- lhm.put(ii, ii.toString());
- }
-
- Set s1 = lhm.entrySet();
- Iterator it1 = s1.iterator();
- assertTrue("Returned set of incorrect size 1", lhm.size() == s1.size());
- for (i = 0; it1.hasNext(); i++) {
- Map.Entry m = (Map.Entry) it1.next();
- Integer jj = (Integer) m.getKey();
- assertTrue("Returned incorrect entry set 1", jj.intValue() == i);
- }
-
- LinkedHashMap lruhm = new LinkedHashMap(200, .75f, true);
- for (i = 0; i < sz; i++) {
- Integer ii = new Integer(i);
- lruhm.put(ii, ii.toString());
- }
-
- Set s3 = lruhm.entrySet();
- Iterator it3 = s3.iterator();
- assertTrue("Returned set of incorrect size 2", lruhm.size() == s3
- .size());
- for (i = 0; i < sz && it3.hasNext(); i++) {
- Map.Entry m = (Map.Entry) it3.next();
- Integer jj = (Integer) m.getKey();
- assertTrue("Returned incorrect entry set 2", jj.intValue() == i);
- }
-
- /* fetch the even numbered entries to affect traversal order */
- int p = 0;
- for (i = 0; i < sz; i += 2) {
- String ii = (String) lruhm.get(new Integer(i));
- p = p + Integer.parseInt(ii);
- }
- assertEquals("invalid sum of even numbers", 2450, p);
-
- Set s2 = lruhm.entrySet();
- Iterator it2 = s2.iterator();
- assertTrue("Returned set of incorrect size 3", lruhm.size() == s2
- .size());
- for (i = 1; i < sz && it2.hasNext(); i += 2) {
- Map.Entry m = (Map.Entry) it2.next();
- Integer jj = (Integer) m.getKey();
- assertTrue("Returned incorrect entry set 3", jj.intValue() == i);
- }
- for (i = 0; i < sz && it2.hasNext(); i += 2) {
- Map.Entry m = (Map.Entry) it2.next();
- Integer jj = (Integer) m.getKey();
- assertTrue("Returned incorrect entry set 4", jj.intValue() == i);
- }
- assertTrue("Entries left to iterate on", !it2.hasNext());
- }
-
- /**
- * java.util.LinkedHashMap#keySet()
- */
- public void test_ordered_keySet() {
- int i;
- int sz = 100;
- LinkedHashMap lhm = new LinkedHashMap();
- for (i = 0; i < sz; i++) {
- Integer ii = new Integer(i);
- lhm.put(ii, ii.toString());
- }
-
- Set s1 = lhm.keySet();
- Iterator it1 = s1.iterator();
- assertTrue("Returned set of incorrect size", lhm.size() == s1.size());
- for (i = 0; it1.hasNext(); i++) {
- Integer jj = (Integer) it1.next();
- assertTrue("Returned incorrect entry set", jj.intValue() == i);
- }
-
- LinkedHashMap lruhm = new LinkedHashMap(200, .75f, true);
- for (i = 0; i < sz; i++) {
- Integer ii = new Integer(i);
- lruhm.put(ii, ii.toString());
- }
-
- Set s3 = lruhm.keySet();
- Iterator it3 = s3.iterator();
- assertTrue("Returned set of incorrect size", lruhm.size() == s3.size());
- for (i = 0; i < sz && it3.hasNext(); i++) {
- Integer jj = (Integer) it3.next();
- assertTrue("Returned incorrect entry set", jj.intValue() == i);
- }
-
- /* fetch the even numbered entries to affect traversal order */
- int p = 0;
- for (i = 0; i < sz; i += 2) {
- String ii = (String) lruhm.get(new Integer(i));
- p = p + Integer.parseInt(ii);
- }
- assertEquals("invalid sum of even numbers", 2450, p);
-
- Set s2 = lruhm.keySet();
- Iterator it2 = s2.iterator();
- assertTrue("Returned set of incorrect size", lruhm.size() == s2.size());
- for (i = 1; i < sz && it2.hasNext(); i += 2) {
- Integer jj = (Integer) it2.next();
- assertTrue("Returned incorrect entry set", jj.intValue() == i);
- }
- for (i = 0; i < sz && it2.hasNext(); i += 2) {
- Integer jj = (Integer) it2.next();
- assertTrue("Returned incorrect entry set", jj.intValue() == i);
- }
- assertTrue("Entries left to iterate on", !it2.hasNext());
- }
-
- /**
- * java.util.LinkedHashMap#values()
- */
- public void test_ordered_values() {
- int i;
- int sz = 100;
- LinkedHashMap lhm = new LinkedHashMap();
- for (i = 0; i < sz; i++) {
- Integer ii = new Integer(i);
- lhm.put(ii, new Integer(i * 2));
- }
-
- Collection s1 = lhm.values();
- Iterator it1 = s1.iterator();
- assertTrue("Returned set of incorrect size 1", lhm.size() == s1.size());
- for (i = 0; it1.hasNext(); i++) {
- Integer jj = (Integer) it1.next();
- assertTrue("Returned incorrect entry set 1", jj.intValue() == i * 2);
- }
-
- LinkedHashMap lruhm = new LinkedHashMap(200, .75f, true);
- for (i = 0; i < sz; i++) {
- Integer ii = new Integer(i);
- lruhm.put(ii, new Integer(i * 2));
- }
-
- Collection s3 = lruhm.values();
- Iterator it3 = s3.iterator();
- assertTrue("Returned set of incorrect size", lruhm.size() == s3.size());
- for (i = 0; i < sz && it3.hasNext(); i++) {
- Integer jj = (Integer) it3.next();
- assertTrue("Returned incorrect entry set", jj.intValue() == i * 2);
- }
-
- // fetch the even numbered entries to affect traversal order
- int p = 0;
- for (i = 0; i < sz; i += 2) {
- Integer ii = (Integer) lruhm.get(new Integer(i));
- p = p + ii.intValue();
- }
- assertTrue("invalid sum of even numbers", p == 2450 * 2);
-
- Collection s2 = lruhm.values();
- Iterator it2 = s2.iterator();
- assertTrue("Returned set of incorrect size", lruhm.size() == s2.size());
- for (i = 1; i < sz && it2.hasNext(); i += 2) {
- Integer jj = (Integer) it2.next();
- assertTrue("Returned incorrect entry set", jj.intValue() == i * 2);
- }
- for (i = 0; i < sz && it2.hasNext(); i += 2) {
- Integer jj = (Integer) it2.next();
- assertTrue("Returned incorrect entry set", jj.intValue() == i * 2);
- }
- assertTrue("Entries left to iterate on", !it2.hasNext());
- }
-
- /**
- * java.util.LinkedHashMap#removeEldestEntry(java.util.Map$Entry)
- */
- public void test_remove_eldest() {
- int i;
- int sz = 10;
- CacheMap lhm = new CacheMap();
- for (i = 0; i < sz; i++) {
- Integer ii = new Integer(i);
- lhm.put(ii, new Integer(i * 2));
- }
-
- Collection s1 = lhm.values();
- Iterator it1 = s1.iterator();
- assertTrue("Returned set of incorrect size 1", lhm.size() == s1.size());
- for (i = 5; it1.hasNext(); i++) {
- Integer jj = (Integer) it1.next();
- assertTrue("Returned incorrect entry set 1", jj.intValue() == i * 2);
- }
- assertTrue("Entries left in map", !it1.hasNext());
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- objArray = new Object[hmSize];
- objArray2 = new Object[hmSize];
- for (int i = 0; i < objArray.length; i++) {
- objArray[i] = new Integer(i);
- objArray2[i] = objArray[i].toString();
- }
-
- hm = new LinkedHashMap();
- for (int i = 0; i < objArray.length; i++)
- hm.put(objArray2[i], objArray[i]);
- hm.put("test", null);
- hm.put(null, "test");
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- objArray = null;
- objArray2 = null;
- hm = null;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/LinkedHashSetTest.java b/luni/src/test/java/tests/api/java/util/LinkedHashSetTest.java
deleted file mode 100644
index f54d01d..0000000
--- a/luni/src/test/java/tests/api/java/util/LinkedHashSetTest.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.Vector;
-
-/**
- * java.util.LinkedHashSet
- */
-
-public class LinkedHashSetTest extends junit.framework.TestCase {
-
- LinkedHashSet hs;
-
- Object[] objArray;
-
- /**
- * java.util.LinkedHashSet#LinkedHashSet()
- */
- public void test_Constructor() {
- // Test for method java.util.LinkedHashSet()
- LinkedHashSet hs2 = new LinkedHashSet();
- assertEquals("Created incorrect LinkedHashSet", 0, hs2.size());
- }
-
- /**
- * java.util.LinkedHashSet#LinkedHashSet(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.LinkedHashSet(int)
- LinkedHashSet hs2 = new LinkedHashSet(5);
- assertEquals("Created incorrect LinkedHashSet", 0, hs2.size());
- try {
- new LinkedHashSet(-1);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedHashSet#LinkedHashSet(int, float)
- */
- public void test_ConstructorIF() {
- // Test for method java.util.LinkedHashSet(int, float)
- LinkedHashSet hs2 = new LinkedHashSet(5, (float) 0.5);
- assertEquals("Created incorrect LinkedHashSet", 0, hs2.size());
-
- try {
- new LinkedHashSet(-1, 0.5f);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new LinkedHashSet(1, -0.5f);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new LinkedHashSet(1, 0f);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedHashSet#LinkedHashSet(java.util.Collection)
- */
- public void test_ConstructorLjava_util_Collection() {
- // Test for method java.util.LinkedHashSet(java.util.Collection)
- LinkedHashSet hs2 = new LinkedHashSet(Arrays.asList(objArray));
- for (int counter = 0; counter < objArray.length; counter++)
- assertTrue("LinkedHashSet does not contain correct elements", hs
- .contains(objArray[counter]));
- assertTrue("LinkedHashSet created from collection incorrect size", hs2
- .size() == objArray.length);
-
- try {
- new LinkedHashSet(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedHashSet#add(java.lang.Object)
- */
- public void test_addLjava_lang_Object() {
- // Test for method boolean java.util.LinkedHashSet.add(java.lang.Object)
- int size = hs.size();
- hs.add(new Integer(8));
- assertTrue("Added element already contained by set", hs.size() == size);
- hs.add(new Integer(-9));
- assertTrue("Failed to increment set size after add",
- hs.size() == size + 1);
- assertTrue("Failed to add element to set", hs.contains(new Integer(-9)));
- }
-
- /**
- * java.util.LinkedHashSet#clear()
- */
- public void test_clear() {
- // Test for method void java.util.LinkedHashSet.clear()
- Set orgSet = (Set) hs.clone();
- hs.clear();
- Iterator i = orgSet.iterator();
- assertEquals("Returned non-zero size after clear", 0, hs.size());
- while (i.hasNext())
- assertTrue("Failed to clear set", !hs.contains(i.next()));
- }
-
- /**
- * java.util.LinkedHashSet#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.LinkedHashSet.clone()
- LinkedHashSet hs2 = (LinkedHashSet) hs.clone();
- assertTrue("clone returned an equivalent LinkedHashSet", hs != hs2);
- assertTrue("clone did not return an equal LinkedHashSet", hs
- .equals(hs2));
- }
-
- /**
- * java.util.LinkedHashSet#contains(java.lang.Object)
- */
- public void test_containsLjava_lang_Object() {
- // Test for method boolean
- // java.util.LinkedHashSet.contains(java.lang.Object)
- assertTrue("Returned false for valid object", hs.contains(objArray[90]));
- assertTrue("Returned true for invalid Object", !hs
- .contains(new Object()));
-
- LinkedHashSet s = new LinkedHashSet();
- s.add(null);
- assertTrue("Cannot handle null", s.contains(null));
- }
-
- /**
- * java.util.LinkedHashSet#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.LinkedHashSet.isEmpty()
- assertTrue("Empty set returned false", new LinkedHashSet().isEmpty());
- assertTrue("Non-empty set returned true", !hs.isEmpty());
- }
-
- /**
- * java.util.LinkedHashSet#iterator()
- */
- public void test_iterator() {
- // Test for method java.util.Iterator java.util.LinkedHashSet.iterator()
- Iterator i = hs.iterator();
- int x = 0;
- int j;
- for (j = 0; i.hasNext(); j++) {
- Object oo = i.next();
- if (oo != null) {
- Integer ii = (Integer) oo;
- assertTrue("Incorrect element found", ii.intValue() == j);
- } else {
- assertTrue("Cannot find null", hs.contains(oo));
- }
- ++x;
- }
- assertTrue("Returned iteration of incorrect size", hs.size() == x);
-
- LinkedHashSet s = new LinkedHashSet();
- s.add(null);
- assertNull("Cannot handle null", s.iterator().next());
- }
-
- /**
- * java.util.LinkedHashSet#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method boolean
- // java.util.LinkedHashSet.remove(java.lang.Object)
- int size = hs.size();
- hs.remove(new Integer(98));
- assertTrue("Failed to remove element", !hs.contains(new Integer(98)));
- assertTrue("Failed to decrement set size", hs.size() == size - 1);
-
- LinkedHashSet s = new LinkedHashSet();
- s.add(null);
- assertTrue("Cannot handle null", s.remove(null));
- }
-
- /**
- * java.util.LinkedHashSet#size()
- */
- public void test_size() {
- // Test for method int java.util.LinkedHashSet.size()
- assertTrue("Returned incorrect size", hs.size() == (objArray.length + 1));
- hs.clear();
- assertEquals("Cleared set returned non-zero size", 0, hs.size());
- }
-
- class Mock_LinkedHashSet extends LinkedHashSet {
- @Override
- public boolean retainAll(Collection c) {
- throw new UnsupportedOperationException();
- }
- }
-
- public void test_retainAllLjava_util_Collection() {
- LinkedHashSet<Integer> lhs = new LinkedHashSet<Integer>();
- Vector v = new Vector<Float>();
- v.add(new Float(3.14));
- lhs.add(new Integer(1));
- assertEquals(1, lhs.size());
- lhs.retainAll(v);
- assertEquals(0, lhs.size());
- v = new Vector<Integer>();
- v.add(new Integer(1));
- v.add(new Integer(2));
- v.add(new Integer(3));
- v.add(new Integer(4));
- v.add(new Integer(5));
- v.add(new Integer(6));
- lhs.add(new Integer(1));
- lhs.add(new Integer(6));
- lhs.add(new Integer(7));
- lhs.add(new Integer(8));
- lhs.add(new Integer(9));
- lhs.add(new Integer(10));
- lhs.add(new Integer(11));
- lhs.add(new Integer(12));
- lhs.add(new Integer(13));
- assertEquals(9, lhs.size());
- lhs.retainAll(v);
- assertEquals(2, lhs.size());
-
- try {
- lhs.retainAll(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
-
- lhs = new Mock_LinkedHashSet();
-
- try {
- lhs.retainAll(v);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- public void test_toArray() {
- LinkedHashSet<Integer> lhs = new LinkedHashSet<Integer>();
- lhs.add(new Integer(1));
- lhs.add(new Integer(6));
- lhs.add(new Integer(7));
- lhs.add(new Integer(8));
- lhs.add(new Integer(9));
- lhs.add(new Integer(10));
- lhs.add(new Integer(11));
- lhs.add(new Integer(12));
- lhs.add(new Integer(13));
-
- Object[] o = lhs.toArray();
- for (int i = 0; i < o.length; i++) {
- assertTrue(lhs.contains(o[i]));
- }
- assertEquals(lhs.size(), o.length);
- }
-
- public void test_toArray$Ljava_lang_Object() {
- LinkedHashSet<Integer> lhs = new LinkedHashSet<Integer>();
- lhs.add(new Integer(1));
- lhs.add(new Integer(6));
- lhs.add(new Integer(7));
- lhs.add(new Integer(8));
- lhs.add(new Integer(9));
- lhs.add(new Integer(10));
- lhs.add(new Integer(11));
- lhs.add(new Integer(12));
- lhs.add(new Integer(13));
-
- Object[] o1 = new Object[lhs.size()];
- Object[] o2 = new Double[lhs.size()];
- lhs.toArray(o1);
- for (int i = 0; i < o1.length; i++) {
- assertTrue(lhs.contains(o1[i]));
- }
-
- try {
- lhs.toArray(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
-
- try {
- lhs.toArray(o2);
- fail("ArrayStoreException expected");
- } catch (ArrayStoreException e) {
- //expected
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- objArray = new Object[1000];
- for (int i = 0; i < objArray.length; i++)
- objArray[i] = new Integer(i);
-
- hs = new LinkedHashSet();
- for (int i = 0; i < objArray.length; i++)
- hs.add(objArray[i]);
- hs.add(null);
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- objArray = null;
- hs = null;
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/LinkedListTest.java b/luni/src/test/java/tests/api/java/util/LinkedListTest.java
deleted file mode 100644
index c0cec45..0000000
--- a/luni/src/test/java/tests/api/java/util/LinkedListTest.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-
-import tests.support.Support_ListTest;
-
-public class LinkedListTest extends junit.framework.TestCase {
-
- LinkedList ll;
-
- Object[] objArray;
-
- /**
- * java.util.LinkedList#LinkedList()
- */
- public void test_Constructor() {
- // Test for method java.util.LinkedList()
- new Support_ListTest("", ll).runTest();
-
- LinkedList subList = new LinkedList();
- for (int i = -50; i < 150; i++)
- subList.add(new Integer(i));
- new Support_ListTest("", subList.subList(50, 150)).runTest();
- }
-
- /**
- * java.util.LinkedList#LinkedList(java.util.Collection)
- */
- public void test_ConstructorLjava_util_Collection() {
- // Test for method java.util.LinkedList(java.util.Collection)
- assertTrue("Incorrect LinkedList constructed", new LinkedList(ll)
- .equals(ll));
-
- try {
- new LinkedList(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#add(int, java.lang.Object)
- */
- public void test_addILjava_lang_Object() {
- // Test for method void java.util.LinkedList.add(int, java.lang.Object)
- Object o;
- ll.add(50, o = "Test");
- assertTrue("Failed to add Object>: " + ll.get(50).toString(), ll
- .get(50) == o);
- assertTrue("Failed to fix up list after insert",
- ll.get(51) == objArray[50] && (ll.get(52) == objArray[51]));
- ll.add(50, null);
- assertNull("Did not add null correctly", ll.get(50));
- }
-
- /**
- * java.util.LinkedList#add(java.lang.Object)
- */
- public void test_addLjava_lang_Object() {
- // Test for method boolean java.util.LinkedList.add(java.lang.Object)
- Object o;
- ll.add(o = new Object());
- assertTrue("Failed to add Object", ll.getLast() == o);
- ll.add(null);
- assertNull("Did not add null correctly", ll.get(ll.size() - 1));
- }
-
- /**
- * java.util.LinkedList#addAll(int, java.util.Collection)
- */
- public void test_addAllILjava_util_Collection() {
- // Test for method boolean java.util.LinkedList.addAll(int,
- // java.util.Collection)
- ll.addAll(50, (Collection) ll.clone());
- assertEquals("Returned incorrect size after adding to existing list", 200, ll
- .size());
- for (int i = 0; i < 50; i++)
- assertTrue("Manipulated elements < index", ll.get(i) == objArray[i]);
- for (int i = 0; i >= 50 && (i < 150); i++)
- assertTrue("Failed to ad elements properly",
- ll.get(i) == objArray[i - 50]);
- for (int i = 0; i >= 150 && (i < 200); i++)
- assertTrue("Failed to ad elements properly",
- ll.get(i) == objArray[i - 100]);
- List myList = new LinkedList();
- myList.add(null);
- myList.add("Blah");
- myList.add(null);
- myList.add("Booga");
- myList.add(null);
- ll.addAll(50, myList);
- assertNull("a) List w/nulls not added correctly", ll.get(50));
- assertEquals("b) List w/nulls not added correctly",
- "Blah", ll.get(51));
- assertNull("c) List w/nulls not added correctly", ll.get(52));
- assertEquals("d) List w/nulls not added correctly",
- "Booga", ll.get(53));
- assertNull("e) List w/nulls not added correctly", ll.get(54));
-
- try {
- ll.addAll(-1, (Collection) null);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- ll.addAll(ll.size() + 1, (Collection) null);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- ll.addAll(0, null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#addAll(int, java.util.Collection)
- */
- public void test_addAllILjava_util_Collection_2() {
- // Regression for HARMONY-467
- LinkedList obj = new LinkedList();
- try {
- obj.addAll(-1, (Collection) null);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
- }
-
- /**
- * java.util.LinkedList#addAll(java.util.Collection)
- */
- public void test_addAllLjava_util_Collection() {
- // Test for method boolean
- // java.util.LinkedList.addAll(java.util.Collection)
- List l = new ArrayList();
- l.addAll((Collection) ll.clone());
- for (int i = 0; i < ll.size(); i++)
- assertTrue("Failed to add elements properly", l.get(i).equals(
- ll.get(i)));
- ll.addAll((Collection) ll.clone());
- assertEquals("Returned incorrect siZe after adding to existing list", 200, ll
- .size());
- for (int i = 0; i < 100; i++) {
- assertTrue("Added to list in incorrect order", ll.get(i).equals(
- l.get(i)));
- assertTrue("Failed to add to existing list", ll.get(i + 100)
- .equals(l.get(i)));
- }
- List myList = new LinkedList();
- myList.add(null);
- myList.add("Blah");
- myList.add(null);
- myList.add("Booga");
- myList.add(null);
- ll.addAll(myList);
- assertNull("a) List w/nulls not added correctly", ll.get(200));
- assertEquals("b) List w/nulls not added correctly",
- "Blah", ll.get(201));
- assertNull("c) List w/nulls not added correctly", ll.get(202));
- assertEquals("d) List w/nulls not added correctly",
- "Booga", ll.get(203));
- assertNull("e) List w/nulls not added correctly", ll.get(204));
-
- try {
- ll.addAll(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#addFirst(java.lang.Object)
- */
- public void test_addFirstLjava_lang_Object() {
- // Test for method void java.util.LinkedList.addFirst(java.lang.Object)
- Object o;
- ll.addFirst(o = new Object());
- assertTrue("Failed to add Object", ll.getFirst() == o);
- ll.addFirst(null);
- assertNull("Failed to add null", ll.getFirst());
- }
-
- /**
- * java.util.LinkedList#addLast(java.lang.Object)
- */
- public void test_addLastLjava_lang_Object() {
- // Test for method void java.util.LinkedList.addLast(java.lang.Object)
- Object o;
- ll.addLast(o = new Object());
- assertTrue("Failed to add Object", ll.getLast() == o);
- ll.addLast(null);
- assertNull("Failed to add null", ll.getLast());
- }
-
- /**
- * java.util.LinkedList#clear()
- */
- public void test_clear() {
- // Test for method void java.util.LinkedList.clear()
- ll.clear();
- for (int i = 0; i < ll.size(); i++)
- assertNull("Failed to clear list", ll.get(i));
- }
-
- /**
- * java.util.LinkedList#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.LinkedList.clone()
- Object x = ll.clone();
- assertTrue("Cloned list was inequal to cloned", x.equals(ll));
- for (int i = 0; i < ll.size(); i++)
- assertTrue("Cloned list contains incorrect elements", ll.get(i)
- .equals(((LinkedList) x).get(i)));
- ll.addFirst(null);
- x = ll.clone();
- assertTrue("List with a null did not clone properly", ll.equals(x));
- }
-
- /**
- * java.util.LinkedList#contains(java.lang.Object)
- */
- public void test_containsLjava_lang_Object() {
- // Test for method boolean
- // java.util.LinkedList.contains(java.lang.Object)
- assertTrue("Returned false for valid element", ll
- .contains(objArray[99]));
- assertTrue("Returned false for equal element", ll.contains(new Integer(
- 8)));
- assertTrue("Returned true for invalid element", !ll
- .contains(new Object()));
- assertTrue("Should not contain null", !ll.contains(null));
- ll.add(25, null);
- assertTrue("Should contain null", ll.contains(null));
- }
-
- /**
- * java.util.LinkedList#get(int)
- */
- public void test_getI() {
- // Test for method java.lang.Object java.util.LinkedList.get(int)
- assertTrue("Returned incorrect element", ll.get(22) == objArray[22]);
- try {
- ll.get(8765);
- fail("Failed to throw expected exception for index > size");
- } catch (IndexOutOfBoundsException e) {
- }
- }
-
- /**
- * java.util.LinkedList#getFirst()
- */
- public void test_getFirst() {
- // Test for method java.lang.Object java.util.LinkedList.getFirst()
- assertTrue("Returned incorrect first element", ll.getFirst().equals(
- objArray[0]));
-
- ll.clear();
- try {
- ll.getFirst();
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#getLast()
- */
- public void test_getLast() {
- // Test for method java.lang.Object java.util.LinkedList.getLast()
- assertTrue("Returned incorrect first element", ll.getLast().equals(
- objArray[objArray.length - 1]));
-
- ll.clear();
- try {
- ll.getLast();
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#indexOf(java.lang.Object)
- */
- public void test_indexOfLjava_lang_Object() {
- // Test for method int java.util.LinkedList.indexOf(java.lang.Object)
- assertEquals("Returned incorrect index", 87, ll.indexOf(objArray[87]));
- assertEquals("Returned index for invalid Object", -1, ll
- .indexOf(new Object()));
- ll.add(20, null);
- ll.add(24, null);
- assertTrue("Index of null should be 20, but got: " + ll.indexOf(null),
- ll.indexOf(null) == 20);
- }
-
- /**
- * java.util.LinkedList#lastIndexOf(java.lang.Object)
- */
- public void test_lastIndexOfLjava_lang_Object() {
- // Test for method int
- // java.util.LinkedList.lastIndexOf(java.lang.Object)
- ll.add(new Integer(99));
- assertEquals("Returned incorrect index",
- 100, ll.lastIndexOf(objArray[99]));
- assertEquals("Returned index for invalid Object", -1, ll
- .lastIndexOf(new Object()));
- ll.add(20, null);
- ll.add(24, null);
- assertTrue("Last index of null should be 20, but got: "
- + ll.lastIndexOf(null), ll.lastIndexOf(null) == 24);
- }
-
- /**
- * java.util.LinkedList#listIterator(int)
- */
- public void test_listIteratorI() {
- // Test for method java.util.ListIterator
- // java.util.LinkedList.listIterator(int)
- ListIterator i1 = ll.listIterator();
- ListIterator i2 = ll.listIterator(0);
- Object elm;
- int n = 0;
- while (i2.hasNext()) {
- if (n == 0 || n == objArray.length - 1) {
- if (n == 0)
- assertTrue("First element claimed to have a previous", !i2
- .hasPrevious());
- if (n == objArray.length)
- assertTrue("Last element claimed to have next", !i2
- .hasNext());
- }
- elm = i2.next();
- assertTrue("Iterator returned elements in wrong order",
- elm == objArray[n]);
- if (n > 0 && n < objArray.length - 1) {
- assertTrue("Next index returned incorrect value",
- i2.nextIndex() == n + 1);
- assertTrue("previousIndex returned incorrect value : "
- + i2.previousIndex() + ", n val: " + n, i2
- .previousIndex() == n);
- }
- elm = i1.next();
- assertTrue("Iterator returned elements in wrong order",
- elm == objArray[n]);
- ++n;
- }
-
- i2 = ll.listIterator(ll.size()/2);
- assertTrue((Integer)i2.next() == ll.size()/2);
- List myList = new LinkedList();
- myList.add(null);
- myList.add("Blah");
- myList.add(null);
- myList.add("Booga");
- myList.add(null);
- ListIterator li = myList.listIterator();
- assertTrue("li.hasPrevious() should be false", !li.hasPrevious());
- assertNull("li.next() should be null", li.next());
- assertTrue("li.hasPrevious() should be true", li.hasPrevious());
- assertNull("li.prev() should be null", li.previous());
- assertNull("li.next() should be null", li.next());
- assertEquals("li.next() should be Blah", "Blah", li.next());
- assertNull("li.next() should be null", li.next());
- assertEquals("li.next() should be Booga", "Booga", li.next());
- assertTrue("li.hasNext() should be true", li.hasNext());
- assertNull("li.next() should be null", li.next());
- assertTrue("li.hasNext() should be false", !li.hasNext());
-
- try {
- ll.listIterator(-1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- ll.listIterator(ll.size() + 1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#remove(int)
- */
- public void test_removeI() {
- // Test for method java.lang.Object java.util.LinkedList.remove(int)
- ll.remove(10);
- assertEquals("Failed to remove element", -1, ll.indexOf(objArray[10]));
- try {
- ll.remove(999);
- fail("Failed to throw expected exception when index out of range");
- } catch (IndexOutOfBoundsException e) {
- // Correct
- }
-
- ll.add(20, null);
- ll.remove(20);
- assertNotNull("Should have removed null", ll.get(20));
- }
-
- /**
- * java.util.LinkedList#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method boolean java.util.LinkedList.remove(java.lang.Object)
- assertTrue("Failed to remove valid Object", ll.remove(objArray[87]));
- assertTrue("Removed invalid object", !ll.remove(new Object()));
- assertEquals("Found Object after removal", -1, ll.indexOf(objArray[87]));
- ll.add(null);
- ll.remove(null);
- assertTrue("Should not contain null afrer removal", !ll.contains(null));
- }
-
- /**
- * java.util.LinkedList#removeFirst()
- */
- public void test_removeFirst() {
- // Test for method java.lang.Object java.util.LinkedList.removeFirst()
- ll.removeFirst();
- assertTrue("Failed to remove first element",
- ll.getFirst() != objArray[0]);
-
- ll.clear();
- try {
- ll.removeFirst();
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#removeLast()
- */
- public void test_removeLast() {
- // Test for method java.lang.Object java.util.LinkedList.removeLast()
- ll.removeLast();
- assertTrue("Failed to remove last element",
- ll.getLast() != objArray[objArray.length - 1]);
-
- ll.clear();
- try {
- ll.removeLast();
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#set(int, java.lang.Object)
- */
- public void test_setILjava_lang_Object() {
- // Test for method java.lang.Object java.util.LinkedList.set(int,
- // java.lang.Object)
- Object obj;
- ll.set(65, obj = new Object());
- assertTrue("Failed to set object", ll.get(65) == obj);
-
- try {
- ll.set(-1, obj = new Object());
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- ll.set(ll.size() + 1, obj = new Object());
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.LinkedList#size()
- */
- public void test_size() {
- // Test for method int java.util.LinkedList.size()
- assertTrue("Returned incorrect size", ll.size() == objArray.length);
- ll.removeFirst();
- assertTrue("Returned incorrect size", ll.size() == objArray.length - 1);
- }
-
- /**
- * java.util.LinkedList#toArray()
- */
- public void test_toArray() {
- // Test for method java.lang.Object [] java.util.LinkedList.toArray()
- ll.add(null);
- Object[] obj = ll.toArray();
- assertEquals("Returned array of incorrect size", objArray.length + 1, obj.length);
-
- for (int i = 0; i < obj.length - 1; i++)
- assertTrue("Returned incorrect array: " + i, obj[i] == objArray[i]);
- assertNull("Returned incorrect array--end isn't null",
- obj[obj.length - 1]);
- }
-
- /**
- * java.util.LinkedList#toArray(java.lang.Object[])
- */
- public void test_toArray$Ljava_lang_Object() {
- // Test for method java.lang.Object []
- // java.util.LinkedList.toArray(java.lang.Object [])
- Integer[] argArray = new Integer[100];
- Object[] retArray;
- retArray = ll.toArray(argArray);
- assertTrue("Returned different array than passed", retArray == argArray);
- List retList = new LinkedList(Arrays.asList(retArray));
- Iterator li = ll.iterator();
- Iterator ri = retList.iterator();
- while (li.hasNext())
- assertTrue("Lists are not equal", li.next() == ri.next());
- argArray = new Integer[1000];
- retArray = ll.toArray(argArray);
- assertNull("Failed to set first extra element to null", argArray[ll
- .size()]);
- for (int i = 0; i < ll.size(); i++)
- assertTrue("Returned incorrect array: " + i,
- retArray[i] == objArray[i]);
- ll.add(50, null);
- argArray = new Integer[101];
- retArray = ll.toArray(argArray);
- assertTrue("Returned different array than passed", retArray == argArray);
- retArray = ll.toArray(argArray);
- assertTrue("Returned different array than passed", retArray == argArray);
- retList = new LinkedList(Arrays.asList(retArray));
- li = ll.iterator();
- ri = retList.iterator();
- while (li.hasNext())
- assertTrue("Lists are not equal", li.next() == ri.next());
-
- try {
- ll.toArray(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
-
- LinkedList<String> lls = new LinkedList<String>();
- lls.add("First");
- lls.add("Second");
-
- try {
- lls.toArray(argArray);
- fail("ArrayStoreException expected");
- } catch (ArrayStoreException e) {
- //expected
- }
- }
- public void test_offer() {
- int origSize = ll.size();
- assertTrue("offer() should return true'", ll.offer(objArray[0]));
- assertEquals("offer() should add an element as the last one", origSize, ll.lastIndexOf(objArray[0]));
- }
- public void test_poll() {
- for (int i = 0; i < objArray.length; i++) {
- assertEquals("should remove the head", objArray[i], ll.poll());
- }
- assertEquals("should be empty", 0, ll.size());
- assertNull("should return 'null' if list is empty", ll.poll());
- }
- public void test_remove() {
- for (int i = 0; i < objArray.length; i++) {
- assertEquals("should remove the head", objArray[i], ll.remove());
- }
- assertEquals("should be empty", 0, ll.size());
- try {
- ll.remove();
- fail("NoSuchElementException is expected when removing from the empty list");
- } catch (NoSuchElementException e) {
- //-- expected
- }
- }
- public void test_element() {
- assertEquals("should return the head", objArray[0], ll.element());
- assertEquals("element() should remove nothing", objArray.length, ll.size());
- try {
- new LinkedList().remove();
- fail("NoSuchElementException is expected when the list is empty");
- } catch (NoSuchElementException e) {
- //-- expected
- }
- }
-
- public void test_peek() {
- assertEquals("should remove the head", objArray[0], ll.peek());
- assertEquals("should remove the head", objArray[0], ll.peek());
-
- ll.clear();
-
- assertNull("should return 'null' if list is empty", ll.peek());
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() throws Exception {
- super.setUp();
-
- objArray = new Object[100];
- for (int i = 0; i < objArray.length; i++) {
- objArray[i] = new Integer(i);
- }
-
- ll = new LinkedList();
- for (int i = 0; i < objArray.length; i++) {
- ll.add(objArray[i]);
- }
- }
-
- @Override
- protected void tearDown() throws Exception {
- objArray = null;
- ll = null;
-
- super.tearDown();
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/ListResourceBundleTest.java b/luni/src/test/java/tests/api/java/util/ListResourceBundleTest.java
deleted file mode 100644
index 8be04db..0000000
--- a/luni/src/test/java/tests/api/java/util/ListResourceBundleTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Enumeration;
-import java.util.ListResourceBundle;
-import java.util.Locale;
-import java.util.ResourceBundle;
-import java.util.Vector;
-
-public class ListResourceBundleTest extends junit.framework.TestCase {
-
- /**
- * java.util.ListResourceBundle#getKeys()
- */
- public void test_getKeys() {
- ResourceBundle bundle;
- String name = "tests.support.Support_TestResource";
- Locale.setDefault(new Locale("en", "US"));
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
- Enumeration keys = bundle.getKeys();
- Vector result = new Vector();
- while (keys.hasMoreElements()) {
- result.addElement(keys.nextElement());
- }
- assertTrue("Missing key parent1", result.contains("parent1"));
- assertTrue("Missing key parent2", result.contains("parent2"));
- assertTrue("Missing key parent3", result.contains("parent3"));
- assertTrue("Missing key parent4", result.contains("parent4"));
- assertTrue("Missing key child1", result.contains("child1"));
- assertTrue("Missing key child2", result.contains("child2"));
- assertTrue("Missing key child3", result.contains("child3"));
- }
-
-
- public void test_handleGetObjectLjava_lang_String() {
- ListResourceBundle bundle;
- String name = "tests.support.Support_TestResource";
- Locale.setDefault(new Locale("en", "US"));
- bundle = (ListResourceBundle)ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
- Enumeration keys = bundle.getKeys();
- String keyValue = null;
- Vector result = new Vector();
- while (keys.hasMoreElements()) {
- result.addElement(bundle.handleGetObject((String)keys.nextElement()));
- }
- assertEquals(9, result.size());
- assertTrue(result.contains(null));
- assertTrue(result.contains("frFRVARValue4"));
- assertTrue(result.contains("frFRVARChildValue1"));
- assertTrue(result.contains("frFRVARChildValue2"));
- assertTrue(result.contains("frFRVARChildValue3"));
- assertTrue(result.remove(null));
- assertTrue(result.remove(null));
- assertTrue(result.remove(null));
- }
-
- protected void setUp() {
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/LocaleTest.java b/luni/src/test/java/tests/api/java/util/LocaleTest.java
deleted file mode 100644
index 7615a76..0000000
--- a/luni/src/test/java/tests/api/java/util/LocaleTest.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.security.Permission;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.Set;
-
-public class LocaleTest extends junit.framework.TestCase {
-
- Locale testLocale;
-
- Locale l;
-
- Locale defaultLocale;
-
- /**
- * java.util.Locale#Locale(java.lang.String, java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.util.Locale(java.lang.String)
- Locale x = new Locale("xx");
- assertTrue("Failed to create Locale", x.getVariant().equals(""));
-
- try {
- new Locale(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Locale#Locale(java.lang.String, java.lang.String)
- */
- public void test_ConstructorLjava_lang_StringLjava_lang_String() {
- // Test for method java.util.Locale(java.lang.String, java.lang.String)
- Locale x = new Locale("xx", "CV");
- assertTrue("Failed to create Locale", x.getCountry().equals("CV")
- && x.getVariant().equals(""));
-
- try {
- new Locale("xx", null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
-
- try {
- new Locale(null, "CV");
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Locale#Locale(java.lang.String, java.lang.String,
- * java.lang.String)
- */
- public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String() {
- // Test for method java.util.Locale(java.lang.String, java.lang.String,
- // java.lang.String)
- Locale x = new Locale("xx", "CV", "ZZ");
- assertTrue("Failed to create Locale", x.getLanguage().equals("xx")
- && (x.getCountry().equals("CV") && x.getVariant().equals("ZZ")));
- try {
- new Locale(null, "CV", "ZZ");
- fail("expected NullPointerException with 1st parameter == null");
- } catch(NullPointerException e) {
- }
-
- try {
- new Locale("xx", null, "ZZ");
- fail("expected NullPointerException with 2nd parameter == null");
- } catch(NullPointerException e) {
- }
-
- try {
- new Locale("xx", "CV", null);
- fail("expected NullPointerException with 3rd parameter == null");
- } catch(NullPointerException e) {
- }
- }
-
- /**
- * java.util.Locale#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.Locale.clone()
- assertTrue("Clone failed", l.clone().equals(l));
- }
-
- /**
- * java.util.Locale#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- // Test for method boolean java.util.Locale.equals(java.lang.Object)
- Locale l2 = new Locale("en", "CA", "WIN32");
- assertTrue("Same object returned false", testLocale.equals(testLocale));
- assertTrue("Same values returned false", testLocale.equals(l2));
- assertTrue("Different locales returned true", !testLocale.equals(l));
-
- }
-
- /**
- * java.util.Locale#getAvailableLocales()
- */
- public void test_getAvailableLocales() {
-// BEGIN android-changed
- // Test for method java.util.Locale []
- // java.util.Locale.getAvailableLocales()
- // Assumes there will generally be about 10+ available locales...
- // even in minimal configurations for android
- try {
- Locale[] locales = Locale.getAvailableLocales();
- assertTrue("Wrong number of locales: " + locales.length, locales.length > 10);
- // regression test for HARMONY-1514
- // HashSet can filter duplicate locales
- Set<Locale> localesSet = new HashSet<Locale>(Arrays.asList(locales));
- assertEquals(localesSet.size(), locales.length);
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
-// END android-changed
- }
-
- /**
- * java.util.Locale#getCountry()
- */
- public void test_getCountry() {
- // Test for method java.lang.String java.util.Locale.getCountry()
- assertTrue("Returned incorrect country: " + testLocale.getCountry(),
- testLocale.getCountry().equals("CA"));
- }
-
- /**
- * java.util.Locale#getDefault()
- */
- public void test_getDefault() {
- // Test for method java.util.Locale java.util.Locale.getDefault()
- assertTrue("returns copy", Locale.getDefault() == Locale.getDefault());
- Locale org = Locale.getDefault();
- Locale.setDefault(l);
- Locale x = Locale.getDefault();
- Locale.setDefault(org);
- assertEquals("Failed to get locale", "fr_CA_WIN32", x.toString());
- }
-
- /**
- * java.util.Locale#getDisplayCountry()
- */
- public void test_getDisplayCountry() {
- // Test for method java.lang.String java.util.Locale.getDisplayCountry()
- assertTrue("Returned incorrect country: "
- + testLocale.getDisplayCountry(), testLocale
- .getDisplayCountry().equals("Canada"));
-
- // Regression for Harmony-1146
- Locale l_countryCD = new Locale("", "CD");
- assertEquals("Congo [DRC]",
- l_countryCD.getDisplayCountry());
- }
-
- public void test_getDisplayCountryLjava_util_Locale() {
- assertEquals("Italie", Locale.ITALY.getDisplayCountry(new Locale("fr", "CA", "WIN32")));
- }
-
- /**
- * java.util.Locale#getDisplayLanguage()
- */
- public void test_getDisplayLanguage() {
- // Test for method java.lang.String
- // java.util.Locale.getDisplayLanguage()
- assertTrue("Returned incorrect language: "
- + testLocale.getDisplayLanguage(), testLocale
- .getDisplayLanguage().equals("English"));
-
- // Regression for Harmony-1146
- Locale l_languageAE = new Locale("ae", "");
- assertEquals("Avestan", l_languageAE.getDisplayLanguage());
- }
-
- public void test_getDisplayLanguageLjava_util_Locale() {
- assertEquals("anglais", new Locale("en", "CA", "WIN32").getDisplayLanguage(l));
- }
-
- public void test_getDisplayName() {
- assertEquals("English (Canada,WIN32)", new Locale("en", "CA", "WIN32").getDisplayName());
- }
-
- public void test_getDisplayNameLjava_util_Locale() {
- assertEquals("anglais (Canada,WIN32)", new Locale("en", "CA", "WIN32").getDisplayName(l));
- }
-
- /**
- * java.util.Locale#getDisplayVariant()
- */
- public void test_getDisplayVariant() {
- // Test for method java.lang.String java.util.Locale.getDisplayVariant()
- assertTrue("Returned incorrect variant: "
- + testLocale.getDisplayVariant(), testLocale
- .getDisplayVariant().equals("WIN32"));
- }
-
- /**
- * java.util.Locale#getDisplayVariant(java.util.Locale)
- */
- public void test_getDisplayVariantLjava_util_Locale() {
- // Test for method java.lang.String
- // java.util.Locale.getDisplayVariant(java.util.Locale)
- assertTrue("Returned incorrect variant: "
- + testLocale.getDisplayVariant(l), testLocale
- .getDisplayVariant(l).equals("WIN32"));
- }
-
- public void test_getISO3Language() {
- Locale l = new Locale("ae");
- assertEquals("ave", l.getISO3Language());
-
- // Regression for Harmony-1146
- Locale l_CountryCS = new Locale("", "CS");
- assertEquals("SCG", l_CountryCS.getISO3Country());
-
- // Regression for Harmony-1129
- l = new Locale("ak", "");
- assertEquals("aka", l.getISO3Language());
- }
-
- /**
- * java.util.Locale#getISOCountries()
- */
- public void test_getISOCountries() {
- // Test for method java.lang.String []
- // java.util.Locale.getISOCountries()
- // Assumes all countries are 2 digits, and that there will always be
- // 230 countries on the list...
- String[] isoCountries = Locale.getISOCountries();
- int length = isoCountries.length;
- int familiarCount = 0;
- for (int i = 0; i < length; i++) {
- if (isoCountries[i].length() != 2) {
- fail("Wrong format for ISOCountries.");
- }
- if (isoCountries[i].equals("CA") || isoCountries[i].equals("BB")
- || isoCountries[i].equals("US")
- || isoCountries[i].equals("KR"))
- familiarCount++;
- }
- assertTrue("ISOCountries missing.", familiarCount == 4 && length > 230);
- }
-
- /**
- * java.util.Locale#getISOLanguages()
- */
- public void test_getISOLanguages() {
- // Test for method java.lang.String []
- // java.util.Locale.getISOLanguages()
- // Assumes always at least 131 ISOlanguages...
- String[] isoLang = Locale.getISOLanguages();
- int length = isoLang.length;
-
- // BEGIN android-changed
- // Language codes are 2- and 3-letter, with preference given
- // to 2-letter codes where possible. 3-letter codes are used
- // when lack a 2-letter equivalent.
- assertTrue("Random element in wrong format.",
- (isoLang[length / 2].length() == 2 || isoLang[length / 2].length() == 3)
- && isoLang[length / 2].toLowerCase().equals(isoLang[length / 2]));
- // END android-changed
-
- assertTrue("Wrong number of ISOLanguages.", length > 130);
- }
-
- /**
- * java.util.Locale#getLanguage()
- */
- public void test_getLanguage() {
- // Test for method java.lang.String java.util.Locale.getLanguage()
- assertTrue("Returned incorrect language: " + testLocale.getLanguage(),
- testLocale.getLanguage().equals("en"));
- }
-
- /**
- * java.util.Locale#getVariant()
- */
- public void test_getVariant() {
- // Test for method java.lang.String java.util.Locale.getVariant()
- assertTrue("Returned incorrect variant: " + testLocale.getVariant(),
- testLocale.getVariant().equals("WIN32"));
- }
-
- SecurityManager sm = new SecurityManager() {
- final String forbidenPermissionName = "user.language";
-
- public void checkPermission(Permission perm) {
- if (perm.getName().equals(forbidenPermissionName)) {
- throw new SecurityException();
- }
- }
- };
- /**
- * java.util.Locale#setDefault(java.util.Locale)
- */
- public void test_setDefaultLjava_util_Locale() {
- // Test for method void java.util.Locale.setDefault(java.util.Locale)
-
- Locale org = Locale.getDefault();
- Locale.setDefault(l);
- Locale x = Locale.getDefault();
- Locale.setDefault(org);
- assertEquals("Failed to set locale", "fr_CA_WIN32", x.toString());
-
- Locale.setDefault(new Locale("tr", ""));
- String res1 = "\u0069".toUpperCase();
- String res2 = "\u0049".toLowerCase();
- Locale.setDefault(org);
- assertEquals("Wrong toUppercase conversion", "\u0130", res1);
- assertEquals("Wrong toLowercase conversion", "\u0131", res2);
-
- try {
- Locale.setDefault(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Locale#toString()
- */
- public void test_toString() {
- // Test for method java.lang.String java.util.Locale.toString()
- assertEquals("en_CA_WIN32", new Locale("en", "CA", "WIN32").toString());
-
- Locale l = new Locale("en", "");
- assertEquals("Wrong representation 1", "en", l.toString());
- l = new Locale("", "CA");
- assertEquals("Wrong representation 2", "_CA", l.toString());
- l = new Locale("", "CA", "var");
- assertEquals("Wrong representation 2.5", "_CA_var", l.toString());
- l = new Locale("en", "", "WIN");
- assertEquals("Wrong representation 4", "en__WIN", l.toString());
- l = new Locale("en", "CA");
- assertEquals("Wrong representation 6", "en_CA", l.toString());
- l = new Locale("en", "CA", "VAR");
- assertEquals("Wrong representation 7", "en_CA_VAR", l.toString());
-
- l = new Locale("", "", "var");
- assertEquals("Wrong representation 8", "", l.toString());
-
- }
-
- public void test_hashCode() {
- Locale l1 = new Locale("en", "US");
- Locale l2 = new Locale("fr", "CA");
-
- assertTrue(l1.hashCode() != l2.hashCode());
- }
-
-// BEGIN android-removed
-// These locales are not part of the android reference impl
-// // Regression Test for HARMONY-2953
-// public void test_getISO() {
-// Locale locale = new Locale("an");
-// assertEquals("arg", locale.getISO3Language());
-//
-// locale = new Locale("PS");
-// assertEquals("pus", locale.getISO3Language());
-//
-// List<String> languages = Arrays.asList(Locale.getISOLanguages());
-// assertTrue(languages.contains("ak"));
-//
-// List<String> countries = Arrays.asList(Locale.getISOCountries());
-// assertTrue(countries.contains("CS"));
-// }
-// END android-removed
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- defaultLocale = Locale.getDefault();
- Locale.setDefault(Locale.US);
- testLocale = new Locale("en", "CA", "WIN32");
- l = new Locale("fr", "CA", "WIN32");
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- Locale.setDefault(defaultLocale);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/MissingResourceExceptionTest.java b/luni/src/test/java/tests/api/java/util/MissingResourceExceptionTest.java
deleted file mode 100644
index fc7189e..0000000
--- a/luni/src/test/java/tests/api/java/util/MissingResourceExceptionTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-public class MissingResourceExceptionTest extends junit.framework.TestCase {
-
- /**
- * java.util.MissingResourceException#MissingResourceException(java.lang.String,
- * java.lang.String, java.lang.String)
- */
- public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String() {
- // Test for method java.util.MissingResourceException(java.lang.String,
- // java.lang.String, java.lang.String)
- assertNotNull(new MissingResourceException("Detail string", "Class name string", "Key string"));
- assertNotNull(new MissingResourceException(null, "Class name string", "Key string"));
- assertNotNull(new MissingResourceException("Detail string", null, "Key string"));
- assertNotNull(new MissingResourceException("Detail string", "Class name string", null));
- try {
- ResourceBundle.getBundle("Non-ExistentBundle");
- } catch (MissingResourceException e) {
- return;
- }
- fail("Failed to generate expected exception");
- }
-
- /**
- * java.util.MissingResourceException#getClassName()
- */
- public void test_getClassName() {
- // Test for method java.lang.String
- // java.util.MissingResourceException.getClassName()
- try {
- ResourceBundle.getBundle("Non-ExistentBundle");
- } catch (MissingResourceException e) {
- assertEquals("Returned incorrect class name", "Non-ExistentBundle"
- + '_' + Locale.getDefault(), e.getClassName());
- }
- }
-
- /**
- * java.util.MissingResourceException#getKey()
- */
- public void test_getKey() {
- // Test for method java.lang.String
- // java.util.MissingResourceException.getKey()
- try {
- ResourceBundle.getBundle("Non-ExistentBundle");
- } catch (MissingResourceException e) {
- assertTrue("Returned incorrect class name", e.getKey().equals(""));
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/NoSuchElementExceptionTest.java b/luni/src/test/java/tests/api/java/util/NoSuchElementExceptionTest.java
deleted file mode 100644
index cfda941..0000000
--- a/luni/src/test/java/tests/api/java/util/NoSuchElementExceptionTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.NoSuchElementException;
-import java.util.Vector;
-
-public class NoSuchElementExceptionTest extends junit.framework.TestCase {
-
- /**
- * java.util.NoSuchElementException#NoSuchElementException()
- */
- public void test_Constructor() {
- // Test for method java.util.NoSuchElementException()
-
- assertNotNull(new NoSuchElementException());
-
- try {
- Vector v = new Vector();
- v.elements().nextElement();
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
- }
-
- /**
- * java.util.NoSuchElementException#NoSuchElementException(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.util.NoSuchElementException(java.lang.String)
-
- assertNotNull(new NoSuchElementException("String"));
- assertNotNull(new NoSuchElementException(null));
-
- try {
- Vector v = new Vector();
- v.firstElement();
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/ObservableTest.java b/luni/src/test/java/tests/api/java/util/ObservableTest.java
deleted file mode 100644
index 3a0d31c..0000000
--- a/luni/src/test/java/tests/api/java/util/ObservableTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Observable;
-import java.util.Observer;
-import java.util.Vector;
-
-public class ObservableTest extends junit.framework.TestCase {
-
- static class TestObserver implements Observer {
- public Vector objv = new Vector();
-
- int updateCount = 0;
-
- public void update(Observable observed, Object arg) {
- ++updateCount;
- objv.add(arg);
- }
-
- public int updateCount() {
- return updateCount;
- }
-
- }
-
- static class DeleteTestObserver implements Observer {
- int updateCount = 0;
-
- boolean deleteAll = false;
-
- public DeleteTestObserver(boolean all) {
- deleteAll = all;
- }
-
- public void update(Observable observed, Object arg) {
- ++updateCount;
- if (deleteAll)
- observed.deleteObservers();
- else
- observed.deleteObserver(this);
- }
-
- public int updateCount() {
- return updateCount;
- }
-
- }
-
- static class TestObservable extends Observable {
- public void doChange() {
- setChanged();
- }
-
- public void clearChange() {
- clearChanged();
- }
- }
-
- Observer observer;
-
- TestObservable observable;
-
- /**
- * java.util.Observable#Observable()
- */
- public void test_Constructor() {
- // Test for method java.util.Observable()
- try {
- Observable ov = new Observable();
- assertTrue("Wrong initial values.", !ov.hasChanged());
- assertEquals("Wrong initial values.", 0, ov.countObservers());
- } catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
- }
- }
-
- /**
- * java.util.Observable#addObserver(java.util.Observer)
- */
- public void test_addObserverLjava_util_Observer() {
- // Test for method void
- // java.util.Observable.addObserver(java.util.Observer)
- TestObserver test = new TestObserver();
- observable.addObserver(test);
- assertEquals("Failed to add observer", 1, observable.countObservers());
- observable.addObserver(test);
- assertEquals("Duplicate observer", 1, observable.countObservers());
-
- Observable o = new Observable();
- try {
- o.addObserver(null);
- fail("Expected adding a null observer to throw a NPE.");
- } catch (NullPointerException ex) {
- // expected;
- } catch (Throwable ex) {
- fail("Did not expect adding a new observer to throw a "
- + ex.getClass().getName());
- }
- }
-
- /**
- * java.util.Observable#countObservers()
- */
- public void test_countObservers() {
- // Test for method int java.util.Observable.countObservers()
- assertEquals("New observable had > 0 observers", 0, observable
- .countObservers());
- observable.addObserver(new TestObserver());
- assertEquals("Observable with observer returned other than 1", 1, observable
- .countObservers());
- }
-
- /**
- * java.util.Observable#deleteObserver(java.util.Observer)
- */
- public void test_deleteObserverLjava_util_Observer() {
- // Test for method void
- // java.util.Observable.deleteObserver(java.util.Observer)
- observable.addObserver(observer = new TestObserver());
- observable.deleteObserver(observer);
- assertEquals("Failed to delete observer",
- 0, observable.countObservers());
- observable.deleteObserver(observer);
- observable.deleteObserver(null);
- }
-
- /**
- * java.util.Observable#deleteObservers()
- */
- public void test_deleteObservers() {
- // Test for method void java.util.Observable.deleteObservers()
- observable.addObserver(new TestObserver());
- observable.addObserver(new TestObserver());
- observable.addObserver(new TestObserver());
- observable.addObserver(new TestObserver());
- observable.addObserver(new TestObserver());
- observable.addObserver(new TestObserver());
- observable.addObserver(new TestObserver());
- observable.addObserver(new TestObserver());
- observable.deleteObservers();
- assertEquals("Failed to delete observers",
- 0, observable.countObservers());
- }
-
- /**
- * java.util.Observable#hasChanged()
- */
- public void test_hasChanged() {
- assertFalse(observable.hasChanged());
- observable.addObserver(observer = new TestObserver());
- observable.doChange();
- assertTrue(observable.hasChanged());
- }
-
- public void test_clearChanged() {
- assertFalse(observable.hasChanged());
- observable.addObserver(observer = new TestObserver());
- observable.doChange();
- assertTrue(observable.hasChanged());
- observable.clearChange();
- assertFalse(observable.hasChanged());
- }
-
- /**
- * java.util.Observable#notifyObservers()
- */
- public void test_notifyObservers() {
- // Test for method void java.util.Observable.notifyObservers()
- observable.addObserver(observer = new TestObserver());
- observable.notifyObservers();
- assertEquals("Notified when unchnaged", 0, ((TestObserver) observer)
- .updateCount());
- ((TestObservable) observable).doChange();
- observable.notifyObservers();
- assertEquals("Failed to notify",
- 1, ((TestObserver) observer).updateCount());
-
- DeleteTestObserver observer1, observer2;
- observable.deleteObservers();
- observable.addObserver(observer1 = new DeleteTestObserver(false));
- observable.addObserver(observer2 = new DeleteTestObserver(false));
- observable.doChange();
- observable.notifyObservers();
- assertTrue("Failed to notify all", observer1.updateCount() == 1
- && observer2.updateCount() == 1);
- assertEquals("Failed to delete all", 0, observable.countObservers());
-
- observable.addObserver(observer1 = new DeleteTestObserver(false));
- observable.addObserver(observer2 = new DeleteTestObserver(false));
- observable.doChange();
- observable.notifyObservers();
- assertTrue("Failed to notify all 2", observer1.updateCount() == 1
- && observer2.updateCount() == 1);
- assertEquals("Failed to delete all 2", 0, observable.countObservers());
- }
-
- /**
- * java.util.Observable#notifyObservers(java.lang.Object)
- */
- public void test_notifyObserversLjava_lang_Object() {
- // Test for method void
- // java.util.Observable.notifyObservers(java.lang.Object)
- Object obj;
- observable.addObserver(observer = new TestObserver());
- observable.notifyObservers();
- assertEquals("Notified when unchanged", 0, ((TestObserver) observer)
- .updateCount());
- ((TestObservable) observable).doChange();
- observable.notifyObservers(obj = new Object());
- assertEquals("Failed to notify",
- 1, ((TestObserver) observer).updateCount());
- assertTrue("Failed to pass Object arg", ((TestObserver) observer).objv
- .elementAt(0).equals(obj));
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- observable = new TestObservable();
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/PropertyResourceBundleTest.java b/luni/src/test/java/tests/api/java/util/PropertyResourceBundleTest.java
deleted file mode 100644
index bc6a4fe..0000000
--- a/luni/src/test/java/tests/api/java/util/PropertyResourceBundleTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Enumeration;
-import java.util.MissingResourceException;
-import java.util.PropertyResourceBundle;
-import java.util.Vector;
-
-public class PropertyResourceBundleTest extends junit.framework.TestCase {
-
- static PropertyResourceBundle prb;
-
- /**
- * java.util.PropertyResourceBundle#PropertyResourceBundle(java.io.InputStream)
- */
- public void test_ConstructorLjava_io_InputStream() {
- // Test for method java.util.PropertyResourceBundle(java.io.InputStream)
- assertTrue("Used to test", true);
- }
-
- /**
- * java.util.PropertyResourceBundle#getKeys()
- */
- public void test_getKeys() {
- Enumeration keyEnum = prb.getKeys();
- Vector test = new Vector();
- int keyCount = 0;
- while (keyEnum.hasMoreElements()) {
- test.addElement(keyEnum.nextElement());
- keyCount++;
- }
-
- assertEquals("Returned the wrong number of keys", 2, keyCount);
- assertTrue("Returned the wrong keys", test.contains("p1")
- && test.contains("p2"));
- }
-
- /**
- * java.util.PropertyResourceBundle#handleGetObject(java.lang.String)
- */
- public void test_handleGetObjectLjava_lang_String() {
- // Test for method java.lang.Object
- // java.util.PropertyResourceBundle.handleGetObject(java.lang.String)
- try {
- assertTrue("Returned incorrect objects", prb.getObject("p1")
- .equals("one")
- && prb.getObject("p2").equals("two"));
- } catch (MissingResourceException e) {
- fail(
- "Threw MisingResourceException for a key contained in the bundle");
- }
- try {
- prb.getObject("Not in the bundle");
- } catch (MissingResourceException e) {
- return;
- }
- fail(
- "Failed to throw MissingResourceException for object not in the bundle");
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- java.io.InputStream propertiesStream = new java.io.ByteArrayInputStream(
- "p1=one\np2=two".getBytes());
- try {
- prb = new PropertyResourceBundle(propertiesStream);
- } catch (java.io.IOException e) {
- fail(
- "Contruction of PropertyResourceBundle threw IOException");
- }
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/RandomTest.java b/luni/src/test/java/tests/api/java/util/RandomTest.java
deleted file mode 100644
index bb72191..0000000
--- a/luni/src/test/java/tests/api/java/util/RandomTest.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Random;
-
-public class RandomTest extends junit.framework.TestCase {
-
- Random r;
-
- /**
- * java.util.Random#Random()
- */
- public void test_Constructor() {
- // Test for method java.util.Random()
- assertTrue("Used to test", true);
- }
-
- /**
- * java.util.Random#Random(long)
- */
- public void test_ConstructorJ() {
- Random r = new Random(8409238L);
- Random r2 = new Random(8409238L);
- for (int i = 0; i < 100; i++)
- assertTrue("Values from randoms with same seed don't match", r
- .nextInt() == r2.nextInt());
- }
-
- /**
- * java.util.Random#nextBoolean()
- */
- public void test_nextBoolean() {
- // Test for method boolean java.util.Random.nextBoolean()
- boolean falseAppeared = false, trueAppeared = false;
- for (int counter = 0; counter < 100; counter++)
- if (r.nextBoolean())
- trueAppeared = true;
- else
- falseAppeared = true;
- assertTrue("Calling nextBoolean() 100 times resulted in all trues",
- falseAppeared);
- assertTrue("Calling nextBoolean() 100 times resulted in all falses",
- trueAppeared);
- }
-
- /**
- * java.util.Random#nextBytes(byte[])
- */
- public void test_nextBytes$B() {
- // Test for method void java.util.Random.nextBytes(byte [])
- boolean someDifferent = false;
- byte[] randomBytes = new byte[100];
- r.nextBytes(randomBytes);
- byte firstByte = randomBytes[0];
- for (int counter = 1; counter < randomBytes.length; counter++)
- if (randomBytes[counter] != firstByte)
- someDifferent = true;
- assertTrue(
- "nextBytes() returned an array of length 100 of the same byte",
- someDifferent);
- }
-
- /**
- * java.util.Random#nextDouble()
- */
- public void test_nextDouble() {
- // Test for method double java.util.Random.nextDouble()
- double lastNum = r.nextDouble();
- double nextNum;
- boolean someDifferent = false;
- boolean inRange = true;
- for (int counter = 0; counter < 100; counter++) {
- nextNum = r.nextDouble();
- if (nextNum != lastNum)
- someDifferent = true;
- if (!(0 <= nextNum && nextNum < 1.0))
- inRange = false;
- lastNum = nextNum;
- }
- assertTrue("Calling nextDouble 100 times resulted in same number",
- someDifferent);
- assertTrue(
- "Calling nextDouble resulted in a number out of range [0,1)",
- inRange);
- }
-
- /**
- * java.util.Random#nextFloat()
- */
- public void test_nextFloat() {
- // Test for method float java.util.Random.nextFloat()
- float lastNum = r.nextFloat();
- float nextNum;
- boolean someDifferent = false;
- boolean inRange = true;
- for (int counter = 0; counter < 100; counter++) {
- nextNum = r.nextFloat();
- if (nextNum != lastNum)
- someDifferent = true;
- if (!(0 <= nextNum && nextNum < 1.0))
- inRange = false;
- lastNum = nextNum;
- }
- assertTrue("Calling nextFloat 100 times resulted in same number",
- someDifferent);
- assertTrue("Calling nextFloat resulted in a number out of range [0,1)",
- inRange);
- }
-
- /**
- * java.util.Random#nextGaussian()
- */
- public void test_nextGaussian() {
- // Test for method double java.util.Random.nextGaussian()
- double lastNum = r.nextGaussian();
- double nextNum;
- boolean someDifferent = false;
- boolean someInsideStd = false;
- for (int counter = 0; counter < 100; counter++) {
- nextNum = r.nextGaussian();
- if (nextNum != lastNum)
- someDifferent = true;
- if (-1.0 <= nextNum && nextNum <= 1.0)
- someInsideStd = true;
- lastNum = nextNum;
- }
- assertTrue("Calling nextGaussian 100 times resulted in same number",
- someDifferent);
- assertTrue(
- "Calling nextGaussian 100 times resulted in no number within 1 std. deviation of mean",
- someInsideStd);
- }
-
- /**
- * java.util.Random#nextInt()
- */
- public void test_nextInt() {
- // Test for method int java.util.Random.nextInt()
- int lastNum = r.nextInt();
- int nextNum;
- boolean someDifferent = false;
- for (int counter = 0; counter < 100; counter++) {
- nextNum = r.nextInt();
- if (nextNum != lastNum)
- someDifferent = true;
- lastNum = nextNum;
- }
- assertTrue("Calling nextInt 100 times resulted in same number",
- someDifferent);
- }
-
- /**
- * java.util.Random#nextInt(int)
- */
- public void test_nextIntI() {
- // Test for method int java.util.Random.nextInt(int)
- final int range = 10;
- int lastNum = r.nextInt(range);
- int nextNum;
- boolean someDifferent = false;
- boolean inRange = true;
- for (int counter = 0; counter < 100; counter++) {
- nextNum = r.nextInt(range);
- if (nextNum != lastNum)
- someDifferent = true;
- if (!(0 <= nextNum && nextNum < range))
- inRange = false;
- lastNum = nextNum;
- }
- assertTrue("Calling nextInt (range) 100 times resulted in same number",
- someDifferent);
- assertTrue(
- "Calling nextInt (range) resulted in a number outside of [0, range)",
- inRange);
-
- }
-
- /**
- * java.util.Random#nextLong()
- */
- public void test_nextLong() {
- // Test for method long java.util.Random.nextLong()
- long lastNum = r.nextLong();
- long nextNum;
- boolean someDifferent = false;
- for (int counter = 0; counter < 100; counter++) {
- nextNum = r.nextLong();
- if (nextNum != lastNum)
- someDifferent = true;
- lastNum = nextNum;
- }
- assertTrue("Calling nextLong 100 times resulted in same number",
- someDifferent);
- }
-
- /**
- * java.util.Random#setSeed(long)
- */
- public void test_setSeedJ() {
- // Test for method void java.util.Random.setSeed(long)
- long[] randomArray = new long[100];
- boolean someDifferent = false;
- final long firstSeed = 1000;
- long aLong, anotherLong, yetAnotherLong;
- Random aRandom = new Random();
- Random anotherRandom = new Random();
- Random yetAnotherRandom = new Random();
- aRandom.setSeed(firstSeed);
- anotherRandom.setSeed(firstSeed);
- for (int counter = 0; counter < randomArray.length; counter++) {
- aLong = aRandom.nextLong();
- anotherLong = anotherRandom.nextLong();
- assertTrue(
- "Two randoms with same seeds gave differing nextLong values",
- aLong == anotherLong);
- yetAnotherLong = yetAnotherRandom.nextLong();
- randomArray[counter] = aLong;
- if (aLong != yetAnotherLong)
- someDifferent = true;
- }
- assertTrue(
- "Two randoms with the different seeds gave the same chain of values",
- someDifferent);
- aRandom.setSeed(firstSeed);
- for (int counter = 0; counter < randomArray.length; counter++)
- assertTrue(
- "Reseting a random to its old seed did not result in the same chain of values as it gave before",
- aRandom.nextLong() == randomArray[counter]);
- }
-
- class Mock_Random extends Random {
- boolean nextCalled = false;
-
- public boolean getFlag () {
- boolean retVal = nextCalled;
- nextCalled = false;
- return retVal;
- }
-
- @Override
- protected int next(int bits) {
- nextCalled = true;
- return super.next(bits);
- }
- }
-
- public void test_next() {
- Mock_Random mr = new Mock_Random();
- assertFalse(mr.getFlag());
- mr.nextBoolean();
- assertTrue(mr.getFlag());
- mr.nextBytes(new byte[10]);
- assertTrue(mr.getFlag());
- mr.nextDouble();
- assertTrue(mr.getFlag());
- mr.nextFloat();
- assertTrue(mr.getFlag());
- mr.nextGaussian();
- assertTrue(mr.getFlag());
- mr.nextInt();
- assertTrue(mr.getFlag());
- mr.nextInt(10);
- assertTrue(mr.getFlag());
- mr.nextLong();
- assertTrue(mr.getFlag());
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- r = new Random();
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java b/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
deleted file mode 100644
index 587a549..0000000
--- a/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import dalvik.annotation.KnownFailure;
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import tests.api.java.util.support.B;
-import tests.support.resource.Support_Resources;
-
-public class ResourceBundleTest extends junit.framework.TestCase {
-
- public void test_getCandidateLocales() throws Exception {
- ResourceBundle.Control c = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
- assertEquals("[en_US, en, ]", c.getCandidateLocales("base", Locale.US).toString());
- assertEquals("[de_CH, de, ]", c.getCandidateLocales("base", new Locale("de", "CH")).toString());
- }
-
- /**
- * java.util.ResourceBundle#getBundle(java.lang.String,
- * java.util.Locale)
- */
- public void test_getBundleLjava_lang_StringLjava_util_Locale() {
- ResourceBundle bundle;
- String name = "tests.support.Support_TestResource";
- Locale defLocale = Locale.getDefault();
-
- Locale.setDefault(new Locale("en", "US"));
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
- assertEquals("Wrong bundle fr_FR_VAR", "frFRVARValue4", bundle.getString("parent4"));
-
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "v1"));
- assertEquals("Wrong bundle fr_FR_v1", "frFRValue4", bundle.getString("parent4"));
-
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "US", "VAR"));
- assertEquals("Wrong bundle fr_US_var", "frValue4", bundle.getString("parent4"));
-
- bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "VAR"));
- assertEquals("Wrong bundle de_FR_var", "enUSValue4", bundle.getString("parent4"));
-
- Locale.setDefault(new Locale("fr", "FR", "VAR"));
- bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "v1"));
- assertEquals("Wrong bundle de_FR_var 2", "frFRVARValue4", bundle.getString("parent4"));
-
- Locale.setDefault(new Locale("de", "US"));
- bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "var"));
- assertEquals("Wrong bundle de_FR_var 2", "parentValue4", bundle.getString("parent4")
- );
-
- try {
- ResourceBundle.getBundle(null, Locale.US);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
- try {
- ResourceBundle.getBundle("blah", (Locale) null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
-
- try {
- ResourceBundle.getBundle("", new Locale("xx", "yy"));
- fail("MissingResourceException expected");
- } catch (MissingResourceException ee) {
- //expected
- }
- }
-
- /**
- * java.util.ResourceBundle#getBundle(java.lang.String,
- * java.util.Locale, java.lang.ClassLoader)
- */
- @KnownFailure("It's not allowed to pass null as parent class loader to"
- + " a new ClassLoader anymore. Maybe we need to change"
- + " URLClassLoader to allow this? It's not specified.")
- public void test_getBundleLjava_lang_StringLjava_util_LocaleLjava_lang_ClassLoader() {
- String classPath = System.getProperty("java.class.path");
- StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator);
- Vector<URL> urlVec = new Vector<URL>();
- String resPackage = Support_Resources.RESOURCE_PACKAGE;
- try {
- while (tok.hasMoreTokens()) {
- String path = tok.nextToken();
- String url;
- if (new File(path).isDirectory())
- url = "file:" + path + resPackage + "subfolder/";
- else
- url = "jar:file:" + path + "!" + resPackage + "subfolder/";
- urlVec.addElement(new URL(url));
- }
- } catch (MalformedURLException e) {
- }
- URL[] urls = new URL[urlVec.size()];
- for (int i = 0; i < urlVec.size(); i++)
- urls[i] = urlVec.elementAt(i);
- URLClassLoader loader = new URLClassLoader(urls, null);
-
- String name = Support_Resources.RESOURCE_PACKAGE_NAME
- + ".hyts_resource";
- ResourceBundle bundle = ResourceBundle.getBundle(name, Locale
- .getDefault());
- assertEquals("Wrong value read", "parent", bundle.getString("property"));
- bundle = ResourceBundle.getBundle(name, Locale.getDefault(), loader);
- assertEquals("Wrong cached value",
- "resource", bundle.getString("property"));
-
- try {
- ResourceBundle.getBundle(null, Locale.getDefault(), loader);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- try {
- ResourceBundle.getBundle(name, null, loader);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- try {
- ResourceBundle.getBundle(name, Locale.getDefault(), (ClassLoader) null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- try {
- ResourceBundle.getBundle("", Locale.getDefault(), loader);
- fail("MissingResourceException expected");
- } catch (MissingResourceException ee) {
- //expected
- }
-
- // Regression test for Harmony-3823
- B bb = new B();
- String s = bb.find("nonexistent");
- s = bb.find("name");
- assertEquals("Wrong property got", "Name", s);
- }
-
- /**
- * java.util.ResourceBundle#getString(java.lang.String)
- */
- public void test_getStringLjava_lang_String() {
- ResourceBundle bundle;
- String name = "tests.support.Support_TestResource";
- Locale.setDefault(new Locale("en", "US"));
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
- assertEquals("Wrong value parent4",
- "frFRVARValue4", bundle.getString("parent4"));
- assertEquals("Wrong value parent3",
- "frFRValue3", bundle.getString("parent3"));
- assertEquals("Wrong value parent2",
- "frValue2", bundle.getString("parent2"));
- assertEquals("Wrong value parent1",
- "parentValue1", bundle.getString("parent1"));
- assertEquals("Wrong value child3",
- "frFRVARChildValue3", bundle.getString("child3"));
- assertEquals("Wrong value child2",
- "frFRVARChildValue2", bundle.getString("child2"));
- assertEquals("Wrong value child1",
- "frFRVARChildValue1", bundle.getString("child1"));
-
- try {
- bundle.getString(null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- try {
- bundle.getString("");
- fail("MissingResourceException expected");
- } catch (MissingResourceException ee) {
- //expected
- }
-
- try {
- bundle.getString("IntegerVal");
- fail("ClassCastException expected");
- } catch (ClassCastException ee) {
- //expected
- }
- }
- public void test_getBundle_getClassName() {
- // Regression test for Harmony-1759
- Locale locale = Locale.GERMAN;
- String nonExistentBundle = "Non-ExistentBundle";
- try {
- ResourceBundle.getBundle(nonExistentBundle, locale, this.getClass()
- .getClassLoader());
- fail("MissingResourceException expected!");
- } catch (MissingResourceException e) {
- assertEquals(nonExistentBundle + "_" + locale, e.getClassName());
- }
-
- try {
- ResourceBundle.getBundle(nonExistentBundle, locale);
- fail("MissingResourceException expected!");
- } catch (MissingResourceException e) {
- assertEquals(nonExistentBundle + "_" + locale, e.getClassName());
- }
-
- locale = Locale.getDefault();
- try {
- ResourceBundle.getBundle(nonExistentBundle);
- fail("MissingResourceException expected!");
- } catch (MissingResourceException e) {
- assertEquals(nonExistentBundle + "_" + locale, e.getClassName());
- }
- }
-
- class Mock_ResourceBundle extends ResourceBundle {
- @Override
- public Enumeration<String> getKeys() {
- return null;
- }
-
- @Override
- protected Object handleGetObject(String key) {
- return null;
- }
- }
-
- public void test_constructor() {
- assertNotNull(new Mock_ResourceBundle());
- }
-
- public void test_getLocale() {
- ResourceBundle bundle;
- String name = "tests.support.Support_TestResource";
- Locale loc = Locale.getDefault();
- Locale.setDefault(new Locale("en", "US"));
-
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
- assertEquals("fr_FR_VAR", bundle.getLocale().toString());
-
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "v1"));
- assertEquals("fr_FR", bundle.getLocale().toString());
-
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "US", "VAR"));
- assertEquals("fr", bundle.getLocale().toString());
-
- bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "VAR"));
- assertEquals("en_US", bundle.getLocale().toString());
-
- bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "v1"));
- assertEquals("en_US", bundle.getLocale().toString());
-
- bundle = ResourceBundle.getBundle(name, new Locale("de", "FR", "var"));
- assertEquals("en_US", bundle.getLocale().toString());
-
- Locale.setDefault(loc);
- }
-
- public void test_getObjectLjava_lang_String() {
- ResourceBundle bundle;
- String name = "tests.support.Support_TestResource";
- Locale.setDefault(new Locale("en", "US"));
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
- assertEquals("Wrong value parent4",
- "frFRVARValue4", (String)bundle.getObject("parent4"));
- assertEquals("Wrong value parent3",
- "frFRValue3", (String)bundle.getObject("parent3"));
- assertEquals("Wrong value parent2",
- "frValue2", (String) bundle.getObject("parent2"));
- assertEquals("Wrong value parent1",
- "parentValue1", (String)bundle.getObject("parent1"));
- assertEquals("Wrong value child3",
- "frFRVARChildValue3", (String)bundle.getObject("child3"));
- assertEquals("Wrong value child2",
- "frFRVARChildValue2", (String) bundle.getObject("child2"));
- assertEquals("Wrong value child1",
- "frFRVARChildValue1", (String)bundle.getObject("child1"));
- assertEquals("Wrong value IntegerVal",
- 1, bundle.getObject("IntegerVal"));
-
- try {
- bundle.getObject(null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- try {
- bundle.getObject("");
- fail("MissingResourceException expected");
- } catch (MissingResourceException ee) {
- //expected
- }
- }
-
- public void test_getStringArrayLjava_lang_String() {
- ResourceBundle bundle;
- String name = "tests.support.Support_TestResource";
- Locale.setDefault(new Locale("en", "US"));
- bundle = ResourceBundle.getBundle(name, new Locale("fr", "FR", "VAR"));
-
- String[] array = bundle.getStringArray("StringArray");
- for(int i = 0; i < array.length; i++) {
- assertEquals("Str" + (i + 1), array[i]);
- }
-
- try {
- bundle.getStringArray(null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- try {
- bundle.getStringArray("");
- fail("MissingResourceException expected");
- } catch (MissingResourceException ee) {
- //expected
- }
-
- try {
- bundle.getStringArray("IntegerVal");
- fail("ClassCastException expected");
- } catch (ClassCastException ee) {
- //expected
- }
- }
-
- public void test_getBundleLjava_lang_String() {
- ResourceBundle bundle;
- String name = "tests.support.Support_TestResource";
- Locale defLocale = Locale.getDefault();
-
- Locale.setDefault(new Locale("en", "US"));
- bundle = ResourceBundle.getBundle(name);
- assertEquals("enUSValue4", bundle.getString("parent4"));
-
- Locale.setDefault(new Locale("fr", "FR", "v1"));
- bundle = ResourceBundle.getBundle(name);
- assertEquals("Wrong bundle fr_FR_v1", "frFRValue4", bundle.getString("parent4"));
-
- Locale.setDefault(new Locale("fr", "US", "VAR"));
- bundle = ResourceBundle.getBundle(name);
- assertEquals("Wrong bundle fr_US_var", "frValue4", bundle.getString("parent4"));
-
- Locale.setDefault(new Locale("de", "FR", "VAR"));
- bundle = ResourceBundle.getBundle(name);
- assertEquals("Wrong bundle de_FR_var", "parentValue4", bundle.getString("parent4"));
-
- Locale.setDefault(new Locale("de", "FR", "v1"));
- bundle = ResourceBundle.getBundle(name);
- assertEquals("Wrong bundle de_FR_var 2", "parentValue4", bundle.getString("parent4"));
-
- Locale.setDefault(new Locale("de", "FR", "var"));
- bundle = ResourceBundle.getBundle(name);
- assertEquals("Wrong bundle de_FR_var 2", "parentValue4", bundle.getString("parent4"));
-
- try {
- ResourceBundle.getBundle(null);
- fail("NullPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
- try {
- ResourceBundle.getBundle("");
- fail("MissingResourceException expected");
- } catch (MissingResourceException ee) {
- //expected
- }
-
- Locale.setDefault(defLocale);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/SampleBundleClass.java b/luni/src/test/java/tests/api/java/util/SampleBundleClass.java
deleted file mode 100644
index ceb0901..0000000
--- a/luni/src/test/java/tests/api/java/util/SampleBundleClass.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * Part of the ResourceBundleTest
- */
-public class SampleBundleClass {
-
- private static SampleBundleClass singleton;
- private static ResourceBundle bundle;
-
- public SampleBundleClass() {
- super();
- if (singleton != null) {
- throw new RuntimeException();
- }
- singleton = this;
- try {
- bundle = ResourceBundle.getBundle("tests.api.simple.SampleBundleClass");
- } catch (MissingResourceException x) {
- System.out.println("Missing resource");
- bundle = null;
- }
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/SimpleTimeZoneTest.java b/luni/src/test/java/tests/api/java/util/SimpleTimeZoneTest.java
deleted file mode 100644
index eeb5b30..0000000
--- a/luni/src/test/java/tests/api/java/util/SimpleTimeZoneTest.java
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.SimpleTimeZone;
-import java.util.TimeZone;
-
-public class SimpleTimeZoneTest extends junit.framework.TestCase {
-
- SimpleTimeZone st1;
-
- SimpleTimeZone st2;
-
- /**
- * java.util.SimpleTimeZone#SimpleTimeZone(int, java.lang.String)
- */
- public void test_ConstructorILjava_lang_String() {
- // Test for method java.util.SimpleTimeZone(int, java.lang.String)
-
- SimpleTimeZone st = new SimpleTimeZone(1000, "TEST");
- assertEquals("Incorrect TZ constructed", "TEST", st.getID());
- assertTrue("Incorrect TZ constructed: " + "returned wrong offset", st
- .getRawOffset() == 1000);
- assertTrue("Incorrect TZ constructed" + "using daylight savings", !st
- .useDaylightTime());
- }
-
- /**
- * java.util.SimpleTimeZone#SimpleTimeZone(int, java.lang.String,
- * int, int, int, int, int, int, int, int)
- */
- public void test_ConstructorILjava_lang_StringIIIIIIII() {
- // Test for method java.util.SimpleTimeZone(int, java.lang.String, int,
- // int, int, int, int, int, int, int)
- SimpleTimeZone st = new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0);
- assertTrue("Incorrect TZ constructed", st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.NOVEMBER,
- 13).getTime()));
- assertTrue("Incorrect TZ constructed", !(st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
- 13).getTime())));
- assertEquals("Incorrect TZ constructed", "TEST", st.getID());
- assertEquals("Incorrect TZ constructed", 1000, st.getRawOffset());
- assertTrue("Incorrect TZ constructed", st.useDaylightTime());
-
- try {
- new SimpleTimeZone(1000, "TEST", 12,
- 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 10, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 1, 10, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.DECEMBER,
- 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -10, Calendar.SUNDAY,
- 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#SimpleTimeZone(int, java.lang.String,
- * int, int, int, int, int, int, int, int, int)
- */
- public void test_ConstructorILjava_lang_StringIIIIIIIII() {
- // Test for method java.util.SimpleTimeZone(int, java.lang.String, int,
- // int, int, int, int, int, int, int, int)
- SimpleTimeZone st = new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0, 1000 * 60 * 60);
- assertTrue("Incorrect TZ constructed", st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.NOVEMBER,
- 13).getTime()));
- assertTrue("Incorrect TZ constructed", !(st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
- 13).getTime())));
- assertEquals("Incorrect TZ constructed", "TEST", st.getID());
- assertEquals("Incorrect TZ constructed", 1000, st.getRawOffset());
- assertTrue("Incorrect TZ constructed", st.useDaylightTime());
- assertTrue("Incorrect TZ constructed",
- st.getDSTSavings() == 1000 * 60 * 60);
-
- try {
- new SimpleTimeZone(1000, "TEST", 12,
- 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0, 1000 * 60 * 60);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 10, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0, 1000 * 60 * 60);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 1, 10, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0, 1000 * 60 * 60);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.DECEMBER,
- 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -10, Calendar.SUNDAY,
- 0, 1000 * 60 * 60);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#SimpleTimeZone(int, java.lang.String,
- * int, int, int, int, int, int, int, int, int, int, int)
- */
- public void test_ConstructorILjava_lang_StringIIIIIIIIIII() {
- // Test for method java.util.SimpleTimeZone(int, java.lang.String, int,
- // int, int, int, int, int, int, int, int, int, int)
- // TODO : Implement test
- //Regression for HARMONY-1241
- assertNotNull(new SimpleTimeZone(
- TimeZone.LONG,
- "Europe/Paris",
- SimpleTimeZone.STANDARD_TIME,
- SimpleTimeZone.STANDARD_TIME,
- SimpleTimeZone.UTC_TIME,
- SimpleTimeZone.WALL_TIME,
- SimpleTimeZone.WALL_TIME,
- TimeZone.SHORT,
- SimpleTimeZone.STANDARD_TIME,
- TimeZone.LONG,
- SimpleTimeZone.UTC_TIME,
- SimpleTimeZone.STANDARD_TIME,
- TimeZone.LONG));
- //seems RI doesn't check the startTimeMode and endTimeMode at all
- //this behavior is contradicts with spec
- assertNotNull(new SimpleTimeZone(
- TimeZone.LONG,
- "Europe/Paris",
- SimpleTimeZone.STANDARD_TIME,
- SimpleTimeZone.STANDARD_TIME,
- SimpleTimeZone.UTC_TIME,
- SimpleTimeZone.WALL_TIME,
- Integer.MAX_VALUE,
- TimeZone.SHORT,
- SimpleTimeZone.STANDARD_TIME,
- TimeZone.LONG,
- SimpleTimeZone.UTC_TIME,
- Integer.MIN_VALUE,
- TimeZone.LONG));
-
- try {
- new SimpleTimeZone(1000, "TEST", 12,
- 1, Calendar.SUNDAY, 0, Integer.MAX_VALUE, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0, Integer.MAX_VALUE, 1000 * 60 * 60);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 10, Calendar.SUNDAY, 0, Integer.MAX_VALUE, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0, Integer.MAX_VALUE, 1000 * 60 * 60);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 1, 10, 0, Calendar.NOVEMBER, Integer.MAX_VALUE, -1, Calendar.SUNDAY,
- 0, Integer.MAX_VALUE, 1000 * 60 * 60);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new SimpleTimeZone(1000, "TEST", Calendar.DECEMBER,
- 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, Integer.MAX_VALUE, -10, Calendar.SUNDAY,
- 0, Integer.MAX_VALUE, 1000 * 60 * 60);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.SimpleTimeZone.clone()
- SimpleTimeZone st1 = new SimpleTimeZone(1000, "TEST",
- Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER,
- -1, Calendar.SUNDAY, 0);
- SimpleTimeZone stA = new SimpleTimeZone(1, "Gah");
- assertTrue("Clone resulted in same reference", st1.clone() != st1);
- assertTrue("Clone resulted in unequal object", ((SimpleTimeZone) st1
- .clone()).equals(st1));
- assertTrue("Clone resulted in same reference", stA.clone() != stA);
- assertTrue("Clone resulted in unequal object", ((SimpleTimeZone) stA
- .clone()).equals(stA));
- }
-
- /**
- * java.util.SimpleTimeZone#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- // Test for method boolean
- // java.util.SimpleTimeZone.equals(java.lang.Object)
- TimeZone tz = TimeZone.getTimeZone("EST");
- st1 = new SimpleTimeZone(tz.getRawOffset(), "EST");
- st2 = new SimpleTimeZone(0, "EST");
- assertFalse(st1.equals(st2));
- st1.setRawOffset(st2.getRawOffset());
- assertTrue(st1.equals(st2));
- }
-
- /**
- * java.util.SimpleTimeZone#getDSTSavings()
- */
- public void test_getDSTSavings() {
- // Test for method int java.util.SimpleTimeZone.getDSTSavings()
- st1 = new SimpleTimeZone(0, "TEST");
-
- assertEquals("Non-zero default daylight savings",
- 0, st1.getDSTSavings());
- st1.setStartRule(0, 1, 1, 1);
- st1.setEndRule(11, 1, 1, 1);
-
- assertEquals("Incorrect default daylight savings",
- 3600000, st1.getDSTSavings());
- st1 = new SimpleTimeZone(-5 * 3600000, "EST", Calendar.APRIL, 1,
- -Calendar.SUNDAY, 2 * 3600000, Calendar.OCTOBER, -1,
- Calendar.SUNDAY, 2 * 3600000, 7200000);
- assertEquals("Incorrect daylight savings from constructor", 7200000, st1
- .getDSTSavings());
-
- }
-
- /**
- * java.util.SimpleTimeZone#getOffset(int, int, int, int, int, int)
- */
- public void test_getOffsetIIIIII() {
- // Test for method int java.util.SimpleTimeZone.getOffset(int, int, int,
- // int, int, int)
-// TimeZone st1 = TimeZone.getTimeZone("EST");
- st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
- assertTrue("Incorrect offset returned", st1.getOffset(
- GregorianCalendar.AD, 1998, Calendar.NOVEMBER, 11,
- Calendar.WEDNESDAY, 0) == -(5 * 60 * 60 * 1000));
-
- st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
- assertEquals("Incorrect offset returned", -(5 * 60 * 60 * 1000), st1
- .getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 11,
- Calendar.THURSDAY, 0));
-
- // Regression for HARMONY-5459
- st1 = new SimpleTimeZone(TimeZone.getDefault().getRawOffset(), TimeZone.getDefault().getID());
- int fourHours = 4*60*60*1000;
- st1.setRawOffset(fourHours);
- assertEquals(fourHours, st1.getOffset(1, 2099, 01, 1, 5, 0));
-
- try {
- st1.getOffset(-1, 2099, 01, 1, 5, 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- st1.getOffset(1, 2099, 15, 1, 5, 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- st1.getOffset(1, 2099, 01, 100, 5, 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- st1.getOffset(1, 2099, 01, 1, 50, 0);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- st1.getOffset(1, 2099, 01, 1, 5, -10);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#getRawOffset()
- */
- public void test_getRawOffset() {
- // Test for method int java.util.SimpleTimeZone.getRawOffset()
- st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
- assertTrue("Incorrect offset returned",
- st1.getRawOffset() == -(5 * 60 * 60 * 1000));
-
- }
-
- /**
- * java.util.SimpleTimeZone#hashCode()
- */
- public void test_hashCode() {
- // Test for method int java.util.SimpleTimeZone.hashCode()
- // For lack of a better test.
- st1 = new SimpleTimeZone(-5 * 3600000, "EST", Calendar.APRIL, 1,
- -Calendar.SUNDAY, 2 * 3600000, Calendar.OCTOBER, -1,
- Calendar.SUNDAY, 2 * 3600000);
- assertTrue(TimeZone.getTimeZone("EST").hashCode() != 0);
- assertTrue(st1.hashCode() != 0);
- }
-
- /**
- * java.util.SimpleTimeZone#hasSameRules(java.util.TimeZone)
- */
- public void test_hasSameRulesLjava_util_TimeZone() {
- // Test for method boolean
- // java.util.SimpleTimeZone.hasSameRules(java.util.TimeZone)
- SimpleTimeZone st = new SimpleTimeZone(1000, "TEST", Calendar.NOVEMBER,
- 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER, -1, Calendar.SUNDAY,
- 0);
- SimpleTimeZone sameAsSt = new SimpleTimeZone(1000, "REST",
- Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0, Calendar.NOVEMBER,
- -1, Calendar.SUNDAY, 0);
- SimpleTimeZone notSameAsSt = new SimpleTimeZone(1000, "PEST",
- Calendar.NOVEMBER, 2, Calendar.SUNDAY, 0, Calendar.NOVEMBER,
- -1, Calendar.SUNDAY, 0);
- assertTrue("Time zones have same rules but return false", st
- .hasSameRules(sameAsSt));
- assertTrue("Time zones have different rules but return true", !st
- .hasSameRules(notSameAsSt));
- }
-
- /**
- * java.util.SimpleTimeZone#inDaylightTime(java.util.Date)
- */
- public void test_inDaylightTimeLjava_util_Date() {
- // Test for method boolean
- // java.util.SimpleTimeZone.inDaylightTime(java.util.Date)
- TimeZone tz = TimeZone.getTimeZone("EST");
- SimpleTimeZone zone = new SimpleTimeZone(tz.getRawOffset(), "EST",
- Calendar.APRIL, 1, -Calendar.SUNDAY, 7200000, Calendar.OCTOBER, -1, Calendar.SUNDAY, 7200000, 3600000);
- GregorianCalendar gc = new GregorianCalendar(1998, Calendar.JUNE, 11);
-
- assertTrue("Returned incorrect daylight value1", zone.inDaylightTime(gc
- .getTime()));
- gc = new GregorianCalendar(1998, Calendar.NOVEMBER, 11);
- assertTrue("Returned incorrect daylight value2", !(zone
- .inDaylightTime(gc.getTime())));
- gc = new GregorianCalendar(zone);
- gc.set(1999, Calendar.APRIL, 4, 1, 59, 59);
- assertTrue("Returned incorrect daylight value3", !(zone
- .inDaylightTime(gc.getTime())));
- Date date = new Date(gc.getTime().getTime() + 1000);
- assertTrue("Returned incorrect daylight value4", zone
- .inDaylightTime(date));
- gc.set(1999, Calendar.OCTOBER, 31, 1, 0, 0);
- assertTrue("Returned incorrect daylight value5", !(zone
- .inDaylightTime(gc.getTime())));
- date = new Date(gc.getTime().getTime() - 1000);
- assertTrue("Returned incorrect daylight value6", zone
- .inDaylightTime(date));
-
- assertTrue("Returned incorrect daylight value7", !zone
- .inDaylightTime(new Date(891752400000L + 7200000 - 1)));
- assertTrue("Returned incorrect daylight value8", zone
- .inDaylightTime(new Date(891752400000L + 7200000)));
- assertTrue("Returned incorrect daylight value9", zone
- .inDaylightTime(new Date(909288000000L + 7200000 - 1)));
- assertTrue("Returned incorrect daylight value10", !zone
- .inDaylightTime(new Date(909288000000L + 7200000)));
- }
-
- /**
- * java.util.SimpleTimeZone#setDSTSavings(int)
- */
- public void test_setDSTSavingsI() {
- // Test for method void java.util.SimpleTimeZone.setDSTSavings(int)
- SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
- st.setStartRule(0, 1, 1, 1);
- st.setEndRule(11, 1, 1, 1);
- st.setDSTSavings(1);
- assertEquals(1, st.getDSTSavings());
- try {
- st.setDSTSavings(0);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- st.setDSTSavings(-1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- /**
- * java.util.SimpleTimeZone#setEndRule(int, int, int)
- */
- public void test_setEndRuleIII() {
- SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
- st.setStartRule(Calendar.NOVEMBER, 1, 0);
- st.setEndRule(Calendar.NOVEMBER, 20, 0);
- assertTrue("StartRule improperly set1", st.useDaylightTime());
- assertTrue("StartRule improperly set2", st.inDaylightTime(
- new GregorianCalendar(1998, Calendar.NOVEMBER,
- 13).getTime()));
- assertTrue("StartRule improperly set3", !(st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
- 13).getTime())));
-
- try {
- st.setEndRule(13, 20, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setEndRule(1, 32, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setEndRule(1, 30, 10);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#setEndRule(int, int, int, int)
- */
- public void test_setEndRuleIIII() {
- // Test for method void java.util.SimpleTimeZone.setEndRule(int, int,
- // int, int)
- SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
- // Spec indicates that both end and start must be set or result is
- // undefined
- st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0);
- st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, 0);
- assertTrue("StartRule improperly set1", st.useDaylightTime());
- assertTrue("StartRule improperly set2", st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.NOVEMBER,
- 13).getTime()));
- assertTrue("StartRule improperly set3", !(st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
- 13).getTime())));
-
- try {
- st.setEndRule(12, -1, Calendar.SUNDAY, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setEndRule(Calendar.NOVEMBER, 10, Calendar.SUNDAY, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setEndRule(Calendar.NOVEMBER, -1, 8, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, -10);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#setEndRule(int, int, int, int, boolean)
- */
- public void test_setEndRuleIIIIZ() {
- // Test for method void java.util.SimpleTimeZone.setEndRule(int, int,
- // int, int, boolean)
- SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
- // Spec indicates that both end and start must be set or result is
- // undefined
- st.setStartRule(Calendar.NOVEMBER, 8, Calendar.SUNDAY, 1, false);
- st.setEndRule(Calendar.NOVEMBER, 15, Calendar.SUNDAY, 1, true);
- assertTrue("StartRule improperly set1", st.useDaylightTime());
- assertTrue("StartRule improperly set2", st
- .inDaylightTime((new GregorianCalendar(1999, Calendar.NOVEMBER,
- 7, 12, 0).getTime())));
- assertTrue("StartRule improperly set3", st
- .inDaylightTime((new GregorianCalendar(1999, Calendar.NOVEMBER,
- 20, 12, 0).getTime())));
- assertTrue("StartRule improperly set4", !(st
- .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
- 6, 12, 0).getTime())));
- assertTrue("StartRule improperly set5", !(st
- .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
- 21, 12, 0).getTime())));
-
- try {
- st.setEndRule(20, 15, Calendar.SUNDAY, 1, true);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setEndRule(Calendar.NOVEMBER, 35, Calendar.SUNDAY, 1, true);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setEndRule(Calendar.NOVEMBER, 15, 12, 1, true);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setEndRule(Calendar.NOVEMBER, 15, Calendar.SUNDAY, -1, true);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#setRawOffset(int)
- */
- public void test_setRawOffsetI() {
- // Test for method void java.util.SimpleTimeZone.setRawOffset(int)
-
- st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
- int off = st1.getRawOffset();
- st1.setRawOffset(1000);
- boolean val = st1.getRawOffset() == 1000;
- st1.setRawOffset(off);
- assertTrue("Incorrect offset set", val);
- }
-
- /**
- * java.util.SimpleTimeZone#setStartRule(int, int, int)
- */
- public void test_setStartRuleIII() {
- // Test for method void java.util.SimpleTimeZone.setStartRule(int, int,
- // int)
- SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
- // Spec indicates that both end and start must be set or result is
- // undefined
- st.setStartRule(Calendar.NOVEMBER, 1, 1);
- st.setEndRule(Calendar.DECEMBER, 1, 1);
- assertTrue("StartRule improperly set", st.useDaylightTime());
- assertTrue("StartRule improperly set", st
- .inDaylightTime((new GregorianCalendar(1998, Calendar.NOVEMBER,
- 13).getTime())));
- assertTrue("StartRule improperly set", !(st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
- 13).getTime())));
-
- try {
- st.setStartRule(13, 20, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setStartRule(1, 32, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setStartRule(1, 30, 10);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#setStartRule(int, int, int, int)
- */
- public void test_setStartRuleIIII() {
- // Test for method void java.util.SimpleTimeZone.setStartRule(int, int,
- // int, int)
- SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
- // Spec indicates that both end and start must be set or result is
- // undefined
- st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0);
- st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, 0);
- assertTrue("StartRule improperly set1", st.useDaylightTime());
- assertTrue("StartRule improperly set2", st
- .inDaylightTime((new GregorianCalendar(1998, Calendar.NOVEMBER,
- 13).getTime())));
- assertTrue("StartRule improperly set3", !(st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
- 13).getTime())));
-
- try {
- st.setStartRule(12, -1, Calendar.SUNDAY, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setStartRule(Calendar.NOVEMBER, 10, Calendar.SUNDAY, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setStartRule(Calendar.NOVEMBER, -1, 8, 0);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setStartRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, -10);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#setStartRule(int, int, int, int, boolean)
- */
- public void test_setStartRuleIIIIZ() {
- TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
- // Test for method void java.util.SimpleTimeZone.setStartRule(int, int,
- // int, int, boolean)
- SimpleTimeZone st = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
- // Spec indicates that both end and start must be set or result is
- // undefined
- st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 1, true);
- st.setEndRule(Calendar.NOVEMBER, 15, Calendar.SUNDAY, 1, false);
- assertTrue("StartRule improperly set1", st.useDaylightTime());
- assertTrue("StartRule improperly set2", st
- .inDaylightTime((new GregorianCalendar(1999, Calendar.NOVEMBER,
- 7, 12, 0).getTime())));
- assertTrue("StartRule improperly set3", st
- .inDaylightTime((new GregorianCalendar(1999, Calendar.NOVEMBER,
- 13, 12, 0).getTime())));
- assertTrue("StartRule improperly set4", !(st
- .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
- 6, 12, 0).getTime())));
- assertTrue("StartRule improperly set5", !(st
- .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
- 14, 12, 0).getTime())));
-
- try {
- st.setStartRule(20, 15, Calendar.SUNDAY, 1, true);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setStartRule(Calendar.NOVEMBER, 35, Calendar.SUNDAY, 1, true);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setStartRule(Calendar.NOVEMBER, 15, 12, 1, true);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
-
- try {
- st.setStartRule(Calendar.NOVEMBER, 15, Calendar.SUNDAY, -1, true);
- fail("IllegalArgumentException is not thrown.");
- } catch(IllegalArgumentException iae) {
- //expected
- }
- }
-
- /**
- * java.util.SimpleTimeZone#setStartYear(int)
- */
- public void test_setStartYearI() {
- // Test for method void java.util.SimpleTimeZone.setStartYear(int)
- SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
- st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0);
- st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, 0);
- st.setStartYear(1999);
- assertTrue("set year improperly set1", !(st
- .inDaylightTime(new GregorianCalendar(1999, Calendar.JULY, 12)
- .getTime())));
- assertTrue("set year improperly set2", !(st
- .inDaylightTime(new GregorianCalendar(1998, Calendar.OCTOBER,
- 13).getTime())));
- assertTrue("set year improperly set3", (st
- .inDaylightTime(new GregorianCalendar(1999, Calendar.NOVEMBER,
- 13).getTime())));
- }
-
- /**
- * java.util.SimpleTimeZone#toString()
- */
- public void test_toString() {
- // Test for method java.lang.String java.util.SimpleTimeZone.toString()
- String string = TimeZone.getTimeZone("EST").toString();
- assertNotNull("toString() returned null", string);
- assertTrue("toString() is empty", string.length() != 0);
- }
-
- /**
- * java.util.SimpleTimeZone#useDaylightTime()
- */
- public void test_useDaylightTime() {
- // Test for method boolean java.util.SimpleTimeZone.useDaylightTime()
- SimpleTimeZone st = new SimpleTimeZone(1000, "Test_TZ");
- assertTrue("useDaylightTime returned incorrect value", !st
- .useDaylightTime());
- // Spec indicates that both end and start must be set or result is
- // undefined
- st.setStartRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0);
- st.setEndRule(Calendar.NOVEMBER, -1, Calendar.SUNDAY, 0);
- assertTrue("useDaylightTime returned incorrect value", st
- .useDaylightTime());
- }
-
- public void test_getOffsetJ() {
- Calendar cal = Calendar.getInstance();
- cal.set(1998, Calendar.NOVEMBER, 11, 0, 0);
- st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
-
- assertTrue("Incorrect offset returned", st1.getOffset(cal.getTimeInMillis()) ==
- -(5 * 60 * 60 * 1000));
-
- st1 = new SimpleTimeZone(TimeZone.getTimeZone("EST").getRawOffset(), "EST");
- cal.set(1998, Calendar.JUNE, 11, 0, 0);
- assertEquals("Incorrect offset returned", -(5 * 60 * 60 * 1000), st1
- .getOffset(cal.getTimeInMillis()));
-
- // Regression for HARMONY-5459
- st1 = new SimpleTimeZone(TimeZone.getDefault().getRawOffset(), TimeZone.getDefault().getID());
- int fourHours = 4*60*60*1000;
- st1.setRawOffset(fourHours);
- cal.set(2099, 01, 1, 0, 0);
-
- assertEquals(fourHours, st1.getOffset(cal.getTimeInMillis()));
-
- }
-
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/StackTest.java b/luni/src/test/java/tests/api/java/util/StackTest.java
deleted file mode 100644
index 465df13..0000000
--- a/luni/src/test/java/tests/api/java/util/StackTest.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.EmptyStackException;
-import java.util.Stack;
-
-public class StackTest extends junit.framework.TestCase {
-
- Stack s;
-
- /**
- * java.util.Stack#Stack()
- */
- public void test_Constructor() {
- // Test for method java.util.Stack()
- assertEquals("Stack creation failed", 0, s.size());
- }
-
- /**
- * java.util.Stack#empty()
- */
- public void test_empty() {
- // Test for method boolean java.util.Stack.empty()
- assertTrue("New stack answers non-empty", s.empty());
- s.push("blah");
- assertTrue("Stack should not be empty but answers empty", !s.empty());
- s.pop();
- assertTrue("Stack should be empty but answers non-empty", s.empty());
- s.push(null);
- assertTrue("Stack with null should not be empty but answers empty", !s
- .empty());
- }
-
- /**
- * java.util.Stack#peek()
- */
- public void test_peek() {
- // Test for method java.lang.Object java.util.Stack.peek()
- String item1 = "Ichi";
- String item2 = "Ni";
- String item3 = "San";
- s.push(item1);
- assertTrue("Peek did not return top item when it was the only item", s
- .peek() == item1);
- s.push(item2);
- s.push(item3);
- assertTrue("Peek did not return top item amoung many other items", s
- .peek() == item3);
- s.pop();
- assertTrue("Peek did not return top item after a pop", s.pop() == item2);
- s.push(null);
- assertNull("Peek did not return top item (wanted: null)",
- s.peek());
- s.pop();
- s.pop();
- try {
- s.pop();
- fail("EmptyStackException expected");
- } catch (EmptyStackException e) {
- //expected
- }
- }
-
- /**
- * java.util.Stack#pop()
- */
- public void test_pop() {
- // Test for method java.lang.Object java.util.Stack.pop()
- String item1 = "Ichi";
- String item2 = "Ni";
- Object lastPopped;
- s.push(item1);
- s.push(item2);
-
- try {
- lastPopped = s.pop();
- assertTrue("a) Pop did not return top item", lastPopped == item2);
- } catch (EmptyStackException e) {
- fail(
- "a) Pop threw EmptyStackException when stack should not have been empty");
- }
-
- try {
- lastPopped = s.pop();
- assertTrue("b) Pop did not return top item", lastPopped == item1);
- } catch (EmptyStackException e) {
- fail(
- "b) Pop threw EmptyStackException when stack should not have been empty");
- }
-
- s.push(null);
- try {
- lastPopped = s.pop();
- assertNull("c) Pop did not return top item", lastPopped);
- } catch (EmptyStackException e) {
- fail(
- "c) Pop threw EmptyStackException when stack should not have been empty");
- }
-
- try {
- lastPopped = s.pop();
- fail(
- "d) Pop did not throw EmptyStackException when stack should have been empty");
- } catch (EmptyStackException e) {
- return;
- }
-
- }
-
- /**
- * java.util.Stack#push(java.lang.Object)
- */
- public void test_pushLjava_lang_Object() {
- Object [] array = {new Integer(0), new Object(),
- new Float(0), new String()};
-
- Stack<Object> stack = new Stack<Object>();
- for(int i = 0; i < array.length; i++) {
- stack.push(array[i]);
- }
- for(int i = 0; i < array.length; i++) {
- assertEquals(array.length - i, stack.search(array[i]));
- }
- }
-
- /**
- * java.util.Stack#search(java.lang.Object)
- */
- public void test_searchLjava_lang_Object() {
- // Test for method int java.util.Stack.search(java.lang.Object)
- String item1 = "Ichi";
- String item2 = "Ni";
- String item3 = "San";
- s.push(item1);
- s.push(item2);
- s.push(item3);
- assertEquals("Search returned incorrect value for equivalent object", 3, s
- .search(item1));
- assertEquals("Search returned incorrect value for equal object", 3, s
- .search("Ichi"));
- s.pop();
- assertEquals("Search returned incorrect value for equivalent object at top of stack",
- 1, s.search(item2));
- assertEquals("Search returned incorrect value for equal object at top of stack",
- 1, s.search("Ni"));
- s.push(null);
- assertEquals("Search returned incorrect value for search for null at top of stack",
- 1, s.search(null));
- s.push("Shi");
- assertEquals("Search returned incorrect value for search for null", 2, s
- .search(null));
- s.pop();
- s.pop();
- assertEquals("Search returned incorrect value for search for null--wanted -1",
- -1, s.search(null));
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- s = new Stack();
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/StringTokenizerTest.java b/luni/src/test/java/tests/api/java/util/StringTokenizerTest.java
deleted file mode 100644
index 809ed99..0000000
--- a/luni/src/test/java/tests/api/java/util/StringTokenizerTest.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-
-public class StringTokenizerTest extends junit.framework.TestCase {
-
- /**
- * java.util.StringTokenizer#StringTokenizer(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.util.StringTokenizer(java.lang.String)
- try {
- new StringTokenizer(null);
- fail("NullPointerException is not thrown.");
- } catch(NullPointerException npe) {
- //expected
- }
- }
-
- /**
- * java.util.StringTokenizer#StringTokenizer(java.lang.String,
- * java.lang.String)
- */
- public void test_ConstructorLjava_lang_StringLjava_lang_String() {
- // Test for method java.util.StringTokenizer(java.lang.String,
- // java.lang.String)
- StringTokenizer st = new StringTokenizer("This:is:a:test:String", ":");
- assertTrue("Created incorrect tokenizer", st.countTokens() == 5
- && (st.nextElement().equals("This")));
- st = new StringTokenizer("This:is:a:test:String", null);
-
- try {
- new StringTokenizer(null, ":");
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.StringTokenizer#StringTokenizer(java.lang.String,
- * java.lang.String, boolean)
- */
- public void test_ConstructorLjava_lang_StringLjava_lang_StringZ() {
- // Test for method java.util.StringTokenizer(java.lang.String,
- // java.lang.String, boolean)
- StringTokenizer st = new StringTokenizer("This:is:a:test:String", ":",
- true);
- st.nextElement();
- assertTrue("Created incorrect tokenizer", st.countTokens() == 8
- && (st.nextElement().equals(":")));
- st = new StringTokenizer("This:is:a:test:String", null, true);
- st = new StringTokenizer("This:is:a:test:String", null, false);
-
- try {
- new StringTokenizer(null, ":", true);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.StringTokenizer#countTokens()
- */
- public void test_countTokens() {
- // Test for method int java.util.StringTokenizer.countTokens()
- StringTokenizer st = new StringTokenizer("This is a test String");
-
- assertEquals("Incorrect token count returned", 5, st.countTokens());
- }
-
- /**
- * java.util.StringTokenizer#hasMoreElements()
- */
- public void test_hasMoreElements() {
- // Test for method boolean java.util.StringTokenizer.hasMoreElements()
-
- StringTokenizer st = new StringTokenizer("This is a test String");
- st.nextElement();
- assertTrue("hasMoreElements returned incorrect value", st
- .hasMoreElements());
- st.nextElement();
- st.nextElement();
- st.nextElement();
- st.nextElement();
- assertTrue("hasMoreElements returned incorrect value", !st
- .hasMoreElements());
- }
-
- /**
- * java.util.StringTokenizer#hasMoreTokens()
- */
- public void test_hasMoreTokens() {
- // Test for method boolean java.util.StringTokenizer.hasMoreTokens()
- StringTokenizer st = new StringTokenizer("This is a test String");
- for (int counter = 0; counter < 5; counter++) {
- assertTrue(
- "StringTokenizer incorrectly reports it has no more tokens",
- st.hasMoreTokens());
- st.nextToken();
- }
- assertTrue("StringTokenizer incorrectly reports it has more tokens",
- !st.hasMoreTokens());
- }
-
- /**
- * java.util.StringTokenizer#nextElement()
- */
- public void test_nextElement() {
- // Test for method java.lang.Object
- // java.util.StringTokenizer.nextElement()
- StringTokenizer st = new StringTokenizer("This is a test String");
- assertEquals("nextElement returned incorrect value", "This", ((String) st
- .nextElement()));
- assertEquals("nextElement returned incorrect value", "is", ((String) st
- .nextElement()));
- assertEquals("nextElement returned incorrect value", "a", ((String) st
- .nextElement()));
- assertEquals("nextElement returned incorrect value", "test", ((String) st
- .nextElement()));
- assertEquals("nextElement returned incorrect value", "String", ((String) st
- .nextElement()));
- try {
- st.nextElement();
- fail(
- "nextElement failed to throw a NoSuchElementException when it should have been out of elements");
- } catch (NoSuchElementException e) {
- return;
- }
- }
-
- /**
- * java.util.StringTokenizer#nextToken()
- */
- public void test_nextToken() {
- // Test for method java.lang.String
- // java.util.StringTokenizer.nextToken()
- StringTokenizer st = new StringTokenizer("This is a test String");
- assertEquals("nextToken returned incorrect value",
- "This", st.nextToken());
- assertEquals("nextToken returned incorrect value",
- "is", st.nextToken());
- assertEquals("nextToken returned incorrect value",
- "a", st.nextToken());
- assertEquals("nextToken returned incorrect value",
- "test", st.nextToken());
- assertEquals("nextToken returned incorrect value",
- "String", st.nextToken());
- try {
- st.nextToken();
- fail(
- "nextToken failed to throw a NoSuchElementException when it should have been out of elements");
- } catch (NoSuchElementException e) {
- return;
- }
- }
-
- /**
- * java.util.StringTokenizer#nextToken(java.lang.String)
- */
- public void test_nextTokenLjava_lang_String() {
- // Test for method java.lang.String
- // java.util.StringTokenizer.nextToken(java.lang.String)
- StringTokenizer st = new StringTokenizer("This is a test String");
- assertEquals("nextToken(String) returned incorrect value with normal token String",
- "This", st.nextToken(" "));
- assertEquals("nextToken(String) returned incorrect value with custom token String",
- " is a ", st.nextToken("tr"));
- assertEquals("calling nextToken() did not use the new default delimiter list",
- "es", st.nextToken());
- st = new StringTokenizer("This:is:a:test:String", " ");
- assertTrue(st.nextToken(":").equals("This"));
- assertTrue(st.nextToken(":").equals("is"));
- assertTrue(st.nextToken(":").equals("a"));
- assertTrue(st.nextToken(":").equals("test"));
- assertTrue(st.nextToken(":").equals("String"));
-
- try {
- st.nextToken(":");
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
-
- try {
- st.nextToken(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/TimerTaskTest.java b/luni/src/test/java/tests/api/java/util/TimerTaskTest.java
deleted file mode 100644
index 97ff8ea..0000000
--- a/luni/src/test/java/tests/api/java/util/TimerTaskTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-public class TimerTaskTest extends junit.framework.TestCase {
- /**
- * Warning: These tests have the possibility to leave a VM hanging if the
- * Timer is not cancelled.
- */
- class TimerTestTask extends TimerTask {
-
- private final Object sync = new Object();
- private final Object start = new Object();
-
- private int wasRun = 0;
-
- // Set this to true to see normal tests fail (or hang possibly)
- // The default is false and needs to be set by some tests
- private boolean sleepInRun = false;
-
- public void run() {
- synchronized (this) {
- wasRun++;
- }
- synchronized (start) {
- start.notify();
- }
- if (sleepInRun) {
-
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- }
- }
- synchronized (sync) {
- sync.notify();
- }
- }
-
- public synchronized int wasRun() {
- return wasRun;
- }
-
- public void sleepInRun(boolean value) {
- sleepInRun = value;
- }
- }
-
- /**
- * java.util.TimerTask#TimerTask()
- */
- public void test_Constructor() {
- // Ensure the constructor does not fail
- new TimerTestTask();
- }
-
- /**
- * java.util.TimerTask#cancel()
- */
- public void test_cancel() {
- Timer t = null;
- try {
- // Ensure cancel returns false if never scheduled
- TimerTestTask testTask = new TimerTestTask();
- assertTrue("Unsheduled tasks should return false for cancel()",
- !testTask.cancel());
-
- // Ensure cancelled task never runs
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 500);
- assertTrue("TimerTask should not have run yet", testTask.cancel());
- t.cancel();
-
- // Ensure cancelling a task which has already run returns true
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 50);
- while (testTask.wasRun() == 0) {
- try {
- Thread.sleep(150);
- } catch (InterruptedException e) {
- }
- }
- assertFalse(
- "TimerTask.cancel() should return false if task has run",
- testTask.cancel());
- assertFalse(
- "TimerTask.cancel() should return false if called a second time",
- testTask.cancel());
- t.cancel();
-
- // Ensure cancelling a repeated execution task which has never run
- // returns true
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 500, 500); // should never run
- assertTrue(
- "TimerTask.cancel() should return true if sheduled for repeated execution even if not run",
- testTask.cancel());
- t.cancel();
-
- // Ensure cancelling a repeated execution task which HAS run returns
- // true
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 50, 50);
- while (testTask.wasRun() == 0) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- }
- }
- assertTrue(
- "TimerTask.cancel() should return true if sheduled for repeated execution and run",
- testTask.cancel());
- t.cancel();
-
- // Ensure calling cancel a second returns false
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 5000); // Should never run
- assertTrue(
- "TimerTask.cancel() should return true if task has never run",
- testTask.cancel());
- assertFalse(
- "TimerTask.cancel() should return false if called a second time",
- testTask.cancel());
- t.cancel();
-
- // Ensure cancelling a task won't cause deadlock
- t = new Timer();
- testTask = new TimerTestTask();
- testTask.sleepInRun(true);
- synchronized (testTask.start) {
- t.schedule(testTask, 0);
- try {
- testTask.start.wait();
- Thread.sleep(50);
- } catch (InterruptedException e) {
- }
- }
- assertFalse("TimerTask should have been cancelled", testTask
- .cancel());
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
- }
-
- /**
- * java.util.TimerTask#scheduledExecutionTime()
- */
- public void test_scheduledExecutionTime() {
- Timer t = null;
- try {
- // Ensure scheduledExecutionTime is roughly right
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- t.schedule(testTask, 100);
- long time = System.currentTimeMillis() + 100;
- synchronized (testTask.sync) {
- try {
- testTask.sync.wait(500);
- } catch (InterruptedException e) {
- }
- }
- long scheduledExecutionTime = testTask.scheduledExecutionTime();
- assertTrue(scheduledExecutionTime <= time);
- t.cancel();
-
- // Ensure scheduledExecutionTime is the last scheduled time
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 100, 500);
- long estNow = System.currentTimeMillis() + 100;
- // Will wake in 100, and every 500 run again
- // We want to try to get it after it's run at least once but not
- // twice
- synchronized (testTask.sync) {
- try {
- testTask.sync.wait(500);
- } catch (InterruptedException e) {
- }
- }
- scheduledExecutionTime = testTask.scheduledExecutionTime();
- assertTrue(scheduledExecutionTime <= estNow);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
-
- }
-
- /**
- * java.util.TimerTask#run()
- */
- public void test_run() {
- Timer t = null;
- try {
- // Ensure a new task is never run
- TimerTestTask testTask = new TimerTestTask();
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- }
- assertEquals("TimerTask.run() method should not have been called",
- 0, testTask.wasRun());
-
- // Ensure a task is run
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 200);
- while(testTask.wasRun() < 1) {
- try {
- Thread.sleep(400);
- } catch (InterruptedException e) {
- }
- }
- assertFalse(testTask.cancel());
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
-
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/TimerTest.java b/luni/src/test/java/tests/api/java/util/TimerTest.java
deleted file mode 100644
index 739c018..0000000
--- a/luni/src/test/java/tests/api/java/util/TimerTest.java
+++ /dev/null
@@ -1,986 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.Date;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.atomic.AtomicReference;
-import junit.framework.TestCase;
-
-public class TimerTest extends TestCase {
-
- int timerCounter = 0;
-
- private final Object sync = new Object();
-
- /**
- * Warning: These tests have the possibility to leave a VM hanging if the
- * Timer is not cancelled.
- */
- class TimerTestTask extends TimerTask {
- int wasRun = 0;
-
- // Should we sleep for 200 ms each run()?
- boolean sleepInRun = false;
-
- // Should we increment the timerCounter?
- boolean incrementCount = false;
-
- // Should we terminate the timer at a specific timerCounter?
- int terminateCount = -1;
-
- // The timer we belong to
- Timer timer = null;
-
- public TimerTestTask() {
- }
-
- public TimerTestTask(Timer t) {
- timer = t;
- }
-
- public void run() {
- synchronized (this) {
- wasRun++;
- }
- if (incrementCount) {
- timerCounter++;
- }
- if (terminateCount == timerCounter && timer != null) {
- timer.cancel();
- }
- if (sleepInRun) {
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- synchronized (sync) {
- sync.notify();
- }
- }
-
- public synchronized int wasRun() {
- return wasRun;
- }
-
- public void sleepInRun(boolean sleepInRun) {
- this.sleepInRun = sleepInRun;
- }
-
- public void incrementCount(boolean incrementCount) {
- this.incrementCount = incrementCount;
- }
-
- public void terminateCount(int terminateCount) {
- this.terminateCount = terminateCount;
- }
- }
-
- private void awaitRun(TimerTestTask task) throws Exception {
- while (task.wasRun() == 0) {
- Thread.sleep(150);
- }
- }
-
- /**
- * java.util.Timer#Timer(boolean)
- */
- public void test_ConstructorZ() throws Exception {
- Timer t = null;
- try {
- // Ensure a task is run
- t = new Timer(true);
- TimerTestTask testTask = new TimerTestTask();
- t.schedule(testTask, 200);
- awaitRun(testTask);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
-
- }
-
- /**
- * java.util.Timer#Timer()
- */
- public void test_Constructor() throws Exception {
- Timer t = null;
- try {
- // Ensure a task is run
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- t.schedule(testTask, 200);
- awaitRun(testTask);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
-
- }
-
- /**
- * java.util.Timer#Timer(String, boolean)
- */
- public void test_ConstructorSZ() throws Exception {
- Timer t = null;
- try {
- // Ensure a task is run
- t = new Timer("test_ConstructorSZThread", true);
- TimerTestTask testTask = new TimerTestTask();
- t.schedule(testTask, 200);
- awaitRun(testTask);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
-
- try {
- new Timer(null, true);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- new Timer(null, false);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- /**
- * java.util.Timer#Timer(String)
- */
- public void test_ConstructorS() throws Exception {
- Timer t = null;
- try {
- // Ensure a task is run
- t = new Timer("test_ConstructorSThread");
- TimerTestTask testTask = new TimerTestTask();
- t.schedule(testTask, 200);
- awaitRun(testTask);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
-
- try {
- new Timer(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- /**
- * java.util.Timer#cancel()
- */
- public void test_cancel() throws Exception {
- Timer t = null;
- try {
- // Ensure a task throws an IllegalStateException after cancelled
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- t.cancel();
- try {
- t.schedule(testTask, 100, 200);
- fail("Scheduling a task after Timer.cancel() should throw exception");
- } catch (IllegalStateException expected) {
- }
-
- // Ensure a task is run but not after cancel
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 100, 500);
- awaitRun(testTask);
- t.cancel();
- synchronized (sync) {
- sync.wait(500);
- }
- assertEquals("TimerTask.run() method should not have been called after cancel",
- 1, testTask.wasRun());
-
- // Ensure you can call cancel more than once
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 100, 500);
- awaitRun(testTask);
- t.cancel();
- t.cancel();
- t.cancel();
- synchronized (sync) {
- sync.wait(500);
- }
- assertEquals("TimerTask.run() method should not have been called after cancel",
- 1, testTask.wasRun());
-
- // Ensure that a call to cancel from within a timer ensures no more
- // run
- t = new Timer();
- testTask = new TimerTestTask(t);
- testTask.incrementCount(true);
- testTask.terminateCount(5); // Terminate after 5 runs
- t.schedule(testTask, 100, 100);
- synchronized (sync) {
- sync.wait(200);
- assertEquals(1, testTask.wasRun());
- sync.wait(200);
- assertEquals(2, testTask.wasRun());
- sync.wait(200);
- assertEquals(3, testTask.wasRun());
- sync.wait(200);
- assertEquals(4, testTask.wasRun());
- sync.wait(200);
- assertEquals(5, testTask.wasRun());
- sync.wait(200);
- assertEquals(5, testTask.wasRun());
- }
- t.cancel();
- Thread.sleep(200);
- } finally {
- if (t != null)
- t.cancel();
- }
-
- }
-
- /**
- * java.util.Timer#purge()
- */
- public void test_purge() throws Exception {
- Timer t = null;
- try {
- t = new Timer();
- assertEquals(0, t.purge());
-
- TimerTestTask[] tasks = new TimerTestTask[100];
- int[] delayTime = { 50, 80, 20, 70, 40, 10, 90, 30, 60 };
-
- int j = 0;
- for (int i = 0; i < 100; i++) {
- tasks[i] = new TimerTestTask();
- t.schedule(tasks[i], delayTime[j++], 200);
- if (j == 9) {
- j = 0;
- }
- }
-
- for (int i = 0; i < 50; i++) {
- tasks[i].cancel();
- }
-
- assertTrue(t.purge() <= 50);
- assertEquals(0, t.purge());
- } finally {
- if (t != null) {
- t.cancel();
- }
- }
- }
-
- /**
- * java.util.Timer#schedule(java.util.TimerTask, java.util.Date)
- */
- public void test_scheduleLjava_util_TimerTaskLjava_util_Date() throws Exception {
- Timer t = null;
- try {
- // Ensure a Timer throws an IllegalStateException after cancelled
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- Date d = new Date(System.currentTimeMillis() + 100);
- t.cancel();
- try {
- t.schedule(testTask, d);
- fail("Scheduling a task after Timer.cancel() should throw exception");
- } catch (IllegalStateException expected) {
- }
-
- // Ensure a Timer throws an IllegalStateException if task already
- // cancelled
- t = new Timer();
- testTask = new TimerTestTask();
- d = new Date(System.currentTimeMillis() + 100);
- testTask.cancel();
- try {
- t.schedule(testTask, d);
- fail("Scheduling a task after cancelling it should throw exception");
- } catch (IllegalStateException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if delay is
- // negative
- t = new Timer();
- testTask = new TimerTestTask();
- d = new Date(-100);
- try {
- t.schedule(testTask, d);
- fail("Scheduling a task with negative date should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws a NullPointerException if the task is null
- t = new Timer();
- d = new Date(System.currentTimeMillis() + 100);
- try {
- t.schedule(null, d);
- fail("Scheduling a null task should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws a NullPointerException if the date is null
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.schedule(testTask, null);
- fail("Scheduling a null date should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- t.cancel();
-
- // Ensure proper sequence of exceptions
- t = new Timer();
- d = new Date(-100);
- try {
- t.schedule(null, d);
- fail("Scheduling a null task with negative date should throw IllegalArgumentException first");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a task is run
- t = new Timer();
- testTask = new TimerTestTask();
- d = new Date(System.currentTimeMillis() + 200);
- t.schedule(testTask, d);
- awaitRun(testTask);
- t.cancel();
-
- // Ensure multiple tasks are run
- t = new Timer();
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- d = new Date(System.currentTimeMillis() + 100);
- t.schedule(testTask, d);
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- d = new Date(System.currentTimeMillis() + 150);
- t.schedule(testTask, d);
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- d = new Date(System.currentTimeMillis() + 70);
- t.schedule(testTask, d);
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- d = new Date(System.currentTimeMillis() + 10);
- t.schedule(testTask, d);
- Thread.sleep(400);
- assertTrue("Multiple tasks should have incremented counter 4 times not "
- + timerCounter, timerCounter == 4);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
- }
-
- /**
- * java.util.Timer#schedule(java.util.TimerTask, long)
- */
- public void test_scheduleLjava_util_TimerTaskJ() throws Exception {
- Timer t = null;
- try {
- // Ensure a Timer throws an IllegalStateException after cancelled
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- t.cancel();
- try {
- t.schedule(testTask, 100);
- fail("Scheduling a task after Timer.cancel() should throw exception");
- } catch (IllegalStateException expected) {
- }
-
- // Ensure a Timer throws an IllegalStateException if task already
- // cancelled
- t = new Timer();
- testTask = new TimerTestTask();
- testTask.cancel();
- try {
- t.schedule(testTask, 100);
- fail("Scheduling a task after cancelling it should throw exception");
- } catch (IllegalStateException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if delay is
- // negative
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.schedule(testTask, -100);
- fail("Scheduling a task with negative delay should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws a NullPointerException if the task is null
- t = new Timer();
- try {
- t.schedule(null, 10);
- fail("Scheduling a null task should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- t.cancel();
-
- // Ensure proper sequence of exceptions
- t = new Timer();
- try {
- t.schedule(null, -10);
- fail("Scheduling a null task with negative delays should throw IllegalArgumentException first");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a task is run
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 200);
- awaitRun(testTask);
- t.cancel();
-
- // Ensure multiple tasks are run
- t = new Timer();
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- t.schedule(testTask, 100);
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- t.schedule(testTask, 150);
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- t.schedule(testTask, 70);
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- t.schedule(testTask, 10);
- Thread.sleep(400);
- assertTrue("Multiple tasks should have incremented counter 4 times not "
- + timerCounter, timerCounter == 4);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
- }
-
- /**
- * java.util.Timer#schedule(java.util.TimerTask, long, long)
- */
- public void test_scheduleLjava_util_TimerTaskJJ() throws Exception {
- Timer t = null;
- try {
- // Ensure a Timer throws an IllegalStateException after cancelled
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- t.cancel();
- try {
- t.schedule(testTask, 100, 100);
- fail("Scheduling a task after Timer.cancel() should throw exception");
- } catch (IllegalStateException expected) {
- }
-
- // Ensure a Timer throws an IllegalStateException if task already
- // cancelled
- t = new Timer();
- testTask = new TimerTestTask();
- testTask.cancel();
- try {
- t.schedule(testTask, 100, 100);
- fail("Scheduling a task after cancelling it should throw exception");
- } catch (IllegalStateException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if delay is
- // negative
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.schedule(testTask, -100, 100);
- fail("Scheduling a task with negative delay should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if period is
- // negative
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.schedule(testTask, 100, -100);
- fail("Scheduling a task with negative period should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if period is
- // zero
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.schedule(testTask, 100, 0);
- fail("Scheduling a task with 0 period should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws a NullPointerException if the task is null
- t = new Timer();
- try {
- t.schedule(null, 10, 10);
- fail("Scheduling a null task should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- t.cancel();
-
- // Ensure proper sequence of exceptions
- t = new Timer();
- try {
- t.schedule(null, -10, -10);
- fail("Scheduling a null task with negative delays should throw IllegalArgumentException first");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a task is run at least twice
- t = new Timer();
- testTask = new TimerTestTask();
- t.schedule(testTask, 100, 100);
- Thread.sleep(400);
- assertTrue("TimerTask.run() method should have been called at least twice ("
- + testTask.wasRun() + ")", testTask.wasRun() >= 2);
- t.cancel();
-
- // Ensure multiple tasks are run
- t = new Timer();
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- t.schedule(testTask, 100, 100); // at least 9 times
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- t.schedule(testTask, 200, 100); // at least 7 times
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- t.schedule(testTask, 300, 200); // at least 4 times
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- t.schedule(testTask, 100, 200); // at least 4 times
- Thread.sleep(1200); // Allowed more room for error
- assertTrue("Multiple tasks should have incremented counter 24 times not "
- + timerCounter, timerCounter >= 24);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
- }
-
- /**
- * java.util.Timer#schedule(java.util.TimerTask, java.util.Date,
- * long)
- */
- public void test_scheduleLjava_util_TimerTaskLjava_util_DateJ() throws Exception {
- Timer t = null;
- try {
- // Ensure a Timer throws an IllegalStateException after cancelled
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- Date d = new Date(System.currentTimeMillis() + 100);
- t.cancel();
- try {
- t.schedule(testTask, d, 100);
- fail("Scheduling a task after Timer.cancel() should throw exception");
- } catch (IllegalStateException expected) {
- }
-
- // Ensure a Timer throws an IllegalStateException if task already
- // cancelled
- t = new Timer();
- d = new Date(System.currentTimeMillis() + 100);
- testTask = new TimerTestTask();
- testTask.cancel();
- try {
- t.schedule(testTask, d, 100);
- fail("Scheduling a task after cancelling it should throw exception");
- } catch (IllegalStateException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if delay is
- // negative
- t = new Timer();
- d = new Date(-100);
- testTask = new TimerTestTask();
- try {
- t.schedule(testTask, d, 100);
- fail("Scheduling a task with negative delay should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if period is
- // negative
- t = new Timer();
- d = new Date(System.currentTimeMillis() + 100);
- testTask = new TimerTestTask();
- try {
- t.schedule(testTask, d, -100);
- fail("Scheduling a task with negative period should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws a NullPointerException if the task is null
- t = new Timer();
- d = new Date(System.currentTimeMillis() + 100);
- try {
- t.schedule(null, d, 10);
- fail("Scheduling a null task should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws a NullPointerException if the date is null
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.schedule(testTask, null, 10);
- fail("Scheduling a null task should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- t.cancel();
-
- // Ensure proper sequence of exceptions
- t = new Timer();
- d = new Date(-100);
- try {
- t.schedule(null, d, 10);
- fail("Scheduling a null task with negative dates should throw IllegalArgumentException first");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a task is run at least twice
- t = new Timer();
- d = new Date(System.currentTimeMillis() + 100);
- testTask = new TimerTestTask();
- t.schedule(testTask, d, 100);
- Thread.sleep(800);
- assertTrue("TimerTask.run() method should have been called at least twice ("
- + testTask.wasRun() + ")", testTask.wasRun() >= 2);
- t.cancel();
-
- // Ensure multiple tasks are run
- t = new Timer();
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- d = new Date(System.currentTimeMillis() + 100);
- t.schedule(testTask, d, 100); // at least 9 times
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- d = new Date(System.currentTimeMillis() + 200);
- t.schedule(testTask, d, 100); // at least 7 times
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- d = new Date(System.currentTimeMillis() + 300);
- t.schedule(testTask, d, 200); // at least 4 times
- testTask = new TimerTestTask();
- testTask.incrementCount(true);
- d = new Date(System.currentTimeMillis() + 100);
- t.schedule(testTask, d, 200); // at least 4 times
- Thread.sleep(3000);
- assertTrue("Multiple tasks should have incremented counter 24 times not "
- + timerCounter, timerCounter >= 24);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
- }
-
- /**
- * java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long,
- * long)
- */
- public void test_scheduleAtFixedRateLjava_util_TimerTaskJJ() throws Exception {
- Timer t = null;
- try {
- // Ensure a Timer throws an IllegalStateException after cancelled
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- t.cancel();
- try {
- t.scheduleAtFixedRate(testTask, 100, 100);
- fail("scheduleAtFixedRate after Timer.cancel() should throw exception");
- } catch (IllegalStateException expected) {
- }
-
- // Ensure a Timer throws an IllegalArgumentException if delay is
- // negative
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.scheduleAtFixedRate(testTask, -100, 100);
- fail("scheduleAtFixedRate with negative delay should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if period is
- // negative
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.scheduleAtFixedRate(testTask, 100, -100);
- fail("scheduleAtFixedRate with negative period should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a task is run at least twice
- t = new Timer();
- testTask = new TimerTestTask();
- t.scheduleAtFixedRate(testTask, 100, 100);
- Thread.sleep(400);
- assertTrue("TimerTask.run() method should have been called at least twice ("
- + testTask.wasRun() + ")", testTask.wasRun() >= 2);
- t.cancel();
-
- class SlowThenFastTask extends TimerTask {
- int wasRun = 0;
-
- long startedAt;
-
- long lastDelta;
-
- public void run() {
- if (wasRun == 0)
- startedAt = System.currentTimeMillis();
- lastDelta = System.currentTimeMillis()
- - (startedAt + (100 * wasRun));
- wasRun++;
- if (wasRun == 2) {
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public long lastDelta() {
- return lastDelta;
- }
-
- public int wasRun() {
- return wasRun;
- }
- }
-
- // Ensure multiple tasks are run
- t = new Timer();
- SlowThenFastTask slowThenFastTask = new SlowThenFastTask();
-
- // at least 9 times even when asleep
- t.scheduleAtFixedRate(slowThenFastTask, 100, 100);
- Thread.sleep(1000);
- long lastDelta = slowThenFastTask.lastDelta();
- assertTrue("Fixed Rate Schedule should catch up, but is off by "
- + lastDelta + " ms", slowThenFastTask.lastDelta < 300);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
- }
-
- /**
- * java.util.Timer#scheduleAtFixedRate(java.util.TimerTask,
- * java.util.Date, long)
- */
- public void test_scheduleAtFixedRateLjava_util_TimerTaskLjava_util_DateJ() throws Exception {
- Timer t = null;
- try {
- // Ensure a Timer throws an IllegalStateException after cancelled
- t = new Timer();
- TimerTestTask testTask = new TimerTestTask();
- t.cancel();
- Date d = new Date(System.currentTimeMillis() + 100);
- try {
- t.scheduleAtFixedRate(testTask, d, 100);
- fail("scheduleAtFixedRate after Timer.cancel() should throw exception");
- } catch (IllegalStateException expected) {
- }
-
- // Ensure a Timer throws an IllegalArgumentException if delay is
- // negative
- t = new Timer();
- testTask = new TimerTestTask();
- d = new Date(-100);
- try {
- t.scheduleAtFixedRate(testTask, d, 100);
- fail("scheduleAtFixedRate with negative Date should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an IllegalArgumentException if period is
- // negative
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.scheduleAtFixedRate(testTask, d, -100);
- fail("scheduleAtFixedRate with negative period should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a Timer throws an NullPointerException if date is Null
- t = new Timer();
- testTask = new TimerTestTask();
- try {
- t.scheduleAtFixedRate(testTask, null, 100);
- fail("scheduleAtFixedRate with null date should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- t.cancel();
-
- // Ensure proper sequence of exceptions
- t = new Timer();
- d = new Date(-100);
- try {
- t.scheduleAtFixedRate(null, d, 10);
- fail("Scheduling a null task with negative date should throw IllegalArgumentException first");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure proper sequence of exceptions
- t = new Timer();
- try {
- t.scheduleAtFixedRate(null, null, -10);
- fail("Scheduling a null task & null date & negative period should throw IllegalArgumentException first");
- } catch (IllegalArgumentException expected) {
- }
- t.cancel();
-
- // Ensure a task is run at least twice
- t = new Timer();
- testTask = new TimerTestTask();
- d = new Date(System.currentTimeMillis() + 100);
- t.scheduleAtFixedRate(testTask, d, 100);
- Thread.sleep(400);
- assertTrue("TimerTask.run() method should have been called at least twice ("
- + testTask.wasRun() + ")", testTask.wasRun() >= 2);
- t.cancel();
-
- class SlowThenFastTask extends TimerTask {
- int wasRun = 0;
-
- long startedAt;
-
- long lastDelta;
-
- public void run() {
- if (wasRun == 0)
- startedAt = System.currentTimeMillis();
- lastDelta = System.currentTimeMillis()
- - (startedAt + (100 * wasRun));
- wasRun++;
- if (wasRun == 2) {
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public long lastDelta() {
- return lastDelta;
- }
-
- public int wasRun() {
- return wasRun;
- }
- }
-
- // Ensure multiple tasks are run
- t = new Timer();
- SlowThenFastTask slowThenFastTask = new SlowThenFastTask();
- d = new Date(System.currentTimeMillis() + 100);
-
- // at least 9 times even when asleep
- t.scheduleAtFixedRate(slowThenFastTask, d, 100);
- Thread.sleep(1000);
- long lastDelta = slowThenFastTask.lastDelta();
- assertTrue("Fixed Rate Schedule should catch up, but is off by "
- + lastDelta + " ms", lastDelta < 300);
- t.cancel();
- } finally {
- if (t != null)
- t.cancel();
- }
- }
-
- /**
- * We used to swallow RuntimeExceptions thrown by tasks. Instead, we need to
- * let those exceptions bubble up, where they will both notify the thread's
- * uncaught exception handler and terminate the timer's thread.
- */
- public void testThrowingTaskKillsTimerThread() throws Exception {
- final AtomicReference<Thread> threadRef = new AtomicReference<Thread>();
- new Timer().schedule(new TimerTask() {
- @Override public void run() {
- Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
- public void uncaughtException(Thread thread, Throwable ex) {}
- });
- threadRef.set(Thread.currentThread());
- throw new RuntimeException("task failure!");
- }
- }, 1);
-
- Thread.sleep(400);
- Thread timerThread = threadRef.get();
- assertFalse(timerThread.isAlive());
- }
-
- protected void setUp() {
- timerCounter = 0;
- }
-
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/TooManyListenersExceptionTest.java b/luni/src/test/java/tests/api/java/util/TooManyListenersExceptionTest.java
deleted file mode 100644
index 48df5fd..0000000
--- a/luni/src/test/java/tests/api/java/util/TooManyListenersExceptionTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.TooManyListenersException;
-
-public class TooManyListenersExceptionTest extends junit.framework.TestCase {
-
- /**
- * java.util.TooManyListenersException#TooManyListenersException()
- */
- public void test_Constructor() {
- // Test for method java.util.TooManyListenersException()
- try {
- throw new TooManyListenersException();
- } catch (TooManyListenersException e) {
- assertNull(
- "Message thrown with exception constructed with no message",
- e.getMessage());
- }
- }
-
- /**
- * java.util.TooManyListenersException#TooManyListenersException(java.lang.String)
- */
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.util.TooManyListenersException(java.lang.String)
- try {
- throw new TooManyListenersException("Gah");
- } catch (TooManyListenersException e) {
- assertEquals("Incorrect message thrown with exception", "Gah", e
- .getMessage());
- }
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/VectorTest.java b/luni/src/test/java/tests/api/java/util/VectorTest.java
deleted file mode 100644
index 6228cb3..0000000
--- a/luni/src/test/java/tests/api/java/util/VectorTest.java
+++ /dev/null
@@ -1,1198 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-
-import tests.support.Support_ListTest;
-
-public class VectorTest extends junit.framework.TestCase {
-
- private Vector tVector = new Vector();
-
- Object[] objArray;
-
- private String vString = "[Test 0, Test 1, Test 2, Test 3, Test 4, Test 5, Test 6, Test 7, Test 8, Test 9, Test 10, Test 11, Test 12, Test 13, Test 14, Test 15, Test 16, Test 17, Test 18, Test 19, Test 20, Test 21, Test 22, Test 23, Test 24, Test 25, Test 26, Test 27, Test 28, Test 29, Test 30, Test 31, Test 32, Test 33, Test 34, Test 35, Test 36, Test 37, Test 38, Test 39, Test 40, Test 41, Test 42, Test 43, Test 44, Test 45, Test 46, Test 47, Test 48, Test 49, Test 50, Test 51, Test 52, Test 53, Test 54, Test 55, Test 56, Test 57, Test 58, Test 59, Test 60, Test 61, Test 62, Test 63, Test 64, Test 65, Test 66, Test 67, Test 68, Test 69, Test 70, Test 71, Test 72, Test 73, Test 74, Test 75, Test 76, Test 77, Test 78, Test 79, Test 80, Test 81, Test 82, Test 83, Test 84, Test 85, Test 86, Test 87, Test 88, Test 89, Test 90, Test 91, Test 92, Test 93, Test 94, Test 95, Test 96, Test 97, Test 98, Test 99]";
-
- /**
- * java.util.Vector#Vector()
- */
- public void test_Constructor() {
- // Test for method java.util.Vector()
-
- Vector tv = new Vector(100);
- for (int i = 0; i < 100; i++)
- tv.addElement(new Integer(i));
- new Support_ListTest("", tv).runTest();
-
- tv = new Vector(200);
- for (int i = -50; i < 150; i++)
- tv.addElement(new Integer(i));
- new Support_ListTest("", tv.subList(50, 150)).runTest();
-
- Vector v = new Vector();
- assertEquals("Vector creation failed", 0, v.size());
- assertEquals("Wrong capacity", 10, v.capacity());
- }
-
- /**
- * java.util.Vector#Vector(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.Vector(int)
-
- Vector v = new Vector(100);
- assertEquals("Vector creation failed", 0, v.size());
- assertEquals("Wrong capacity", 100, v.capacity());
-
- try {
- new Vector(-1);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#Vector(int, int)
- */
- public void test_ConstructorII() {
- // Test for method java.util.Vector(int, int)
-
- Vector v = new Vector(2, 10);
- v.addElement(new Object());
- v.addElement(new Object());
- v.addElement(new Object());
-
- assertEquals("Failed to inc capacity by proper amount",
- 12, v.capacity());
-
- Vector grow = new Vector(3, -1);
- grow.addElement("one");
- grow.addElement("two");
- grow.addElement("three");
- grow.addElement("four");
- assertEquals("Wrong size", 4, grow.size());
- assertEquals("Wrong capacity", 6, grow.capacity());
-
- try {
- new Vector(-1, 1);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#Vector(java.util.Collection)
- */
- public void test_ConstructorLjava_util_Collection() {
- // Test for method java.util.Vector(java.util.Collection)
- Collection l = new LinkedList();
- for (int i = 0; i < 100; i++)
- l.add("Test " + i);
- Vector myVector = new Vector(l);
- assertTrue("Vector is not correct size",
- myVector.size() == objArray.length);
- for (int counter = 0; counter < objArray.length; counter++)
- assertTrue("Vector does not contain correct elements", myVector
- .contains(((List) l).get(counter)));
-
- try {
- new Vector(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#add(int, java.lang.Object)
- */
- public void test_addILjava_lang_Object() {
- // Test for method void java.util.Vector.add(int, java.lang.Object)
- Object o = new Object();
- Object prev = tVector.get(45);
- tVector.add(45, o);
- assertTrue("Failed to add Object", tVector.get(45) == o);
- assertTrue("Failed to fix-up existing indices", tVector.get(46) == prev);
- assertEquals("Wrong size after add", 101, tVector.size());
-
- prev = tVector.get(50);
- tVector.add(50, null);
- assertNull("Failed to add null", tVector.get(50));
- assertTrue("Failed to fix-up existing indices after adding null",
- tVector.get(51) == prev);
- assertEquals("Wrong size after add", 102, tVector.size());
-
- try {
- tVector.add(-5, null);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.add(tVector.size() + 1, null);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#add(java.lang.Object)
- */
- public void test_addLjava_lang_Object() {
- // Test for method boolean java.util.Vector.add(java.lang.Object)
- Object o = new Object();
- tVector.add(o);
- assertTrue("Failed to add Object", tVector.lastElement() == o);
- assertEquals("Wrong size after add", 101, tVector.size());
-
- tVector.add(null);
- assertNull("Failed to add null", tVector.lastElement());
- assertEquals("Wrong size after add", 102, tVector.size());
- }
-
- /**
- * java.util.Vector#addAll(int, java.util.Collection)
- */
- public void test_addAllILjava_util_Collection() {
- // Test for method boolean java.util.Vector.addAll(int,
- // java.util.Collection)
- Collection l = new LinkedList();
- for (int i = 0; i < 100; i++)
- l.add("Test " + i);
- Vector v = new Vector();
- tVector.addAll(50, l);
- for (int i = 50; i < 100; i++)
- assertTrue("Failed to add all elements",
- tVector.get(i) == ((List) l).get(i - 50));
- v = new Vector();
- v.add("one");
- int r = 0;
- try {
- v.addAll(3, Arrays.asList(new String[] { "two", "three" }));
- } catch (ArrayIndexOutOfBoundsException e) {
- r = 1;
- } catch (IndexOutOfBoundsException e) {
- r = 2;
- }
- assertTrue("Invalid add: " + r, r == 1);
- l = new LinkedList();
- l.add(null);
- l.add("gah");
- l.add(null);
- tVector.addAll(50, l);
- assertNull("Wrong element at position 50--wanted null",
- tVector.get(50));
- assertEquals("Wrong element at position 51--wanted 'gah'", "gah", tVector
- .get(51));
- assertNull("Wrong element at position 52--wanted null",
- tVector.get(52));
-
- try {
- tVector.addAll(-5, Arrays.asList(new String[] { "two", "three" }));
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.addAll(tVector.size() + 1, Arrays.asList(new String[] { "two", "three" }));
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.addAll(tVector.size() / 2, null);
- fail("NullPointerException expected");
- } catch(NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#addAll(java.util.Collection)
- */
- public void test_addAllLjava_util_Collection() {
- // Test for method boolean java.util.Vector.addAll(java.util.Collection)
- Vector v = new Vector();
- Collection l = new LinkedList();
- for (int i = 0; i < 100; i++)
- l.add("Test " + i);
- v.addAll(l);
- assertTrue("Failed to add all elements", tVector.equals(v));
-
- v.addAll(l);
- int vSize = tVector.size();
- for (int counter = vSize - 1; counter >= 0; counter--)
- assertTrue("Failed to add elements correctly", v.get(counter) == v
- .get(counter + vSize));
-
- l = new LinkedList();
- l.add(null);
- l.add("gah");
- l.add(null);
- tVector.addAll(l);
- assertNull("Wrong element at 3rd last position--wanted null", tVector
- .get(vSize));
- assertEquals("Wrong element at 2nd last position--wanted 'gah'", "gah", tVector
- .get(vSize + 1));
- assertNull("Wrong element at last position--wanted null", tVector
- .get(vSize + 2));
-
- try {
- tVector.addAll(tVector.size() / 2, null);
- fail("NullPointerException expected");
- } catch(NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#addElement(java.lang.Object)
- */
- public void test_addElementLjava_lang_Object() {
- // Test for method void java.util.Vector.addElement(java.lang.Object)
- Vector v = vectorClone(tVector);
- v.addElement("Added Element");
- assertTrue("Failed to add element", v.contains("Added Element"));
- assertEquals("Added Element to wrong slot", "Added Element", ((String) v.elementAt(100))
- );
- v.addElement(null);
- assertTrue("Failed to add null", v.contains(null));
- assertNull("Added null to wrong slot", v.elementAt(101));
- }
-
- /**
- * java.util.Vector#addElement(java.lang.Object)
- */
- public void test_addElementLjava_lang_Object_subtest0() {
- // Test for method void java.util.Vector.addElement(java.lang.Object)
- Vector v = vectorClone(tVector);
- v.addElement("Added Element");
- assertTrue("Failed to add element", v.contains("Added Element"));
- assertEquals("Added Element to wrong slot", "Added Element", ((String) v.elementAt(100))
- );
- v.addElement(null);
- assertTrue("Failed to add null", v.contains(null));
- assertNull("Added null to wrong slot", v.elementAt(101));
- }
-
- /**
- * java.util.Vector#capacity()
- */
- public void test_capacity() {
- // Test for method int java.util.Vector.capacity()
-
- Vector v = new Vector(9);
- assertEquals("Incorrect capacity returned", 9, v.capacity());
- }
-
- /**
- * java.util.Vector#clear()
- */
- public void test_clear() {
- // Test for method void java.util.Vector.clear()
- Vector orgVector = vectorClone(tVector);
- tVector.clear();
- assertEquals("a) Cleared Vector has non-zero size", 0, tVector.size());
- Enumeration e = orgVector.elements();
- while (e.hasMoreElements())
- assertTrue("a) Cleared vector contained elements", !tVector
- .contains(e.nextElement()));
-
- tVector.add(null);
- tVector.clear();
- assertEquals("b) Cleared Vector has non-zero size", 0, tVector.size());
- e = orgVector.elements();
- while (e.hasMoreElements())
- assertTrue("b) Cleared vector contained elements", !tVector
- .contains(e.nextElement()));
- }
-
- /**
- * java.util.Vector#clone()
- */
- public void test_clone() {
- // Test for method java.lang.Object java.util.Vector.clone()
- tVector.add(25, null);
- tVector.add(75, null);
- Vector v = (Vector) tVector.clone();
- Enumeration orgNum = tVector.elements();
- Enumeration cnum = v.elements();
-
- while (orgNum.hasMoreElements()) {
- assertTrue("Not enough elements copied", cnum.hasMoreElements());
- assertTrue("Vector cloned improperly, elements do not match",
- orgNum.nextElement() == cnum.nextElement());
- }
- assertTrue("Not enough elements copied", !cnum.hasMoreElements());
-
- }
-
- /**
- * java.util.Vector#contains(java.lang.Object)
- */
- public void test_containsLjava_lang_Object() {
- // Test for method boolean java.util.Vector.contains(java.lang.Object)
- assertTrue("Did not find element", tVector.contains("Test 42"));
- assertTrue("Found bogus element", !tVector.contains("Hello"));
- assertTrue(
- "Returned true looking for null in vector without null element",
- !tVector.contains(null));
- tVector.insertElementAt(null, 20);
- assertTrue(
- "Returned false looking for null in vector with null element",
- tVector.contains(null));
- }
-
- /**
- * java.util.Vector#containsAll(java.util.Collection)
- */
- public void test_containsAllLjava_util_Collection() {
- // Test for method boolean
- // java.util.Vector.containsAll(java.util.Collection)
- Collection s = new HashSet();
- for (int i = 0; i < 100; i++)
- s.add("Test " + i);
-
- assertTrue("Returned false for valid collection", tVector
- .containsAll(s));
- s.add(null);
- assertTrue("Returned true for invlaid collection containing null",
- !tVector.containsAll(s));
- tVector.add(25, null);
- assertTrue("Returned false for valid collection containing null",
- tVector.containsAll(s));
- s = new HashSet();
- s.add(new Object());
- assertTrue("Returned true for invalid collection", !tVector
- .containsAll(s));
-
- try {
- tVector.containsAll(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#copyInto(java.lang.Object[])
- */
- public void test_copyInto$Ljava_lang_Object() {
- // Test for method void java.util.Vector.copyInto(java.lang.Object [])
-
- Object[] a = new Object[100];
- tVector.setElementAt(null, 20);
- tVector.copyInto(a);
-
- for (int i = 0; i < 100; i++)
- assertTrue("copyInto failed", a[i] == tVector.elementAt(i));
-
- try {
- tVector.copyInto(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#elementAt(int)
- */
- public void test_elementAtI() {
- // Test for method java.lang.Object java.util.Vector.elementAt(int)
- assertEquals("Incorrect element returned", "Test 18", ((String) tVector
- .elementAt(18)));
- tVector.setElementAt(null, 20);
- assertNull("Incorrect element returned--wanted null", tVector
- .elementAt(20));
-
- try {
- tVector.elementAt(-5);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.elementAt(tVector.size() + 1);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#elements()
- */
- public void test_elements() {
- // Test for method java.util.Enumeration java.util.Vector.elements()
- tVector.insertElementAt(null, 20);
- Enumeration e = tVector.elements();
- int i = 0;
- while (e.hasMoreElements()) {
- assertTrue("Enumeration returned incorrect element at pos: " + i, e
- .nextElement() == tVector.elementAt(i));
- i++;
- }
- assertTrue("Invalid enumeration", i == tVector.size());
- }
-
- /**
- * java.util.Vector#elements()
- */
- public void test_elements_subtest0() {
- final int iterations = 10000;
- final Vector v = new Vector();
- Thread t1 = new Thread() {
- public void run() {
- for (int i = 0; i < iterations; i++) {
- synchronized (v) {
- v.addElement(String.valueOf(i));
- v.removeElementAt(0);
- }
- }
- }
- };
- t1.start();
- for (int i = 0; i < iterations; i++) {
- Enumeration en = v.elements();
- try {
- while (true) {
- Object result = en.nextElement();
- if (result == null) {
- fail("Null result: " + i);
- }
- }
- } catch (NoSuchElementException e) {
- }
- }
- }
-
- /**
- * java.util.Vector#ensureCapacity(int)
- */
- public void test_ensureCapacityI() {
- // Test for method void java.util.Vector.ensureCapacity(int)
-
- Vector v = new Vector(9);
- v.ensureCapacity(20);
- assertEquals("ensureCapacity failed to set correct capacity", 20, v
- .capacity());
- v = new Vector(100);
- assertEquals("ensureCapacity reduced capacity", 100, v.capacity());
- }
-
- /**
- * java.util.Vector#equals(java.lang.Object)
- */
- public void test_equalsLjava_lang_Object() {
- // Test for method boolean java.util.Vector.equals(java.lang.Object)
- Vector v = new Vector();
- for (int i = 0; i < 100; i++)
- v.addElement("Test " + i);
- assertTrue("a) Equal vectors returned false", tVector.equals(v));
- v.addElement(null);
- assertTrue("b) UnEqual vectors returned true", !tVector.equals(v));
- tVector.addElement(null);
- assertTrue("c) Equal vectors returned false", tVector.equals(v));
- tVector.removeElementAt(22);
- assertTrue("d) UnEqual vectors returned true", !tVector.equals(v));
- }
-
- /**
- * java.util.Vector#firstElement()
- */
- public void test_firstElement() {
- // Test for method java.lang.Object java.util.Vector.firstElement()
- assertEquals("Returned incorrect firstElement", "Test 0", tVector.firstElement()
- );
- tVector.insertElementAt(null, 0);
- assertNull("Returned incorrect firstElement--wanted null", tVector
- .firstElement());
-
- tVector = new Vector(10);
-
- try {
- tVector.firstElement();
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#get(int)
- */
- public void test_getI() {
- // Test for method java.lang.Object java.util.Vector.get(int)
- assertEquals("Get returned incorrect object",
- "Test 80", tVector.get(80));
- tVector.add(25, null);
- assertNull("Returned incorrect element--wanted null",
- tVector.get(25));
-
- try {
- tVector.get(-5);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.get(tVector.size() + 1);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#hashCode()
- */
- public void test_hashCode() {
- // Test for method int java.util.Vector.hashCode()
- int hashCode = 1; // one
- tVector.insertElementAt(null, 20);
- for (int i = 0; i < tVector.size(); i++) {
- Object obj = tVector.elementAt(i);
- hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
- }
- assertTrue("Incorrect hashCode returned. Wanted: " + hashCode
- + " got: " + tVector.hashCode(), tVector.hashCode() == hashCode);
- }
-
- /**
- * java.util.Vector#indexOf(java.lang.Object)
- */
- public void test_indexOfLjava_lang_Object() {
- // Test for method int java.util.Vector.indexOf(java.lang.Object)
- assertEquals("Incorrect index returned", 10, tVector.indexOf("Test 10"));
- assertEquals("Index returned for invalid Object", -1, tVector
- .indexOf("XXXXXXXXXXX"));
- tVector.setElementAt(null, 20);
- tVector.setElementAt(null, 40);
- assertTrue("Incorrect indexOf returned for null: "
- + tVector.indexOf(null), tVector.indexOf(null) == 20);
- }
-
- /**
- * java.util.Vector#indexOf(java.lang.Object, int)
- */
- public void test_indexOfLjava_lang_ObjectI() {
- // Test for method int java.util.Vector.indexOf(java.lang.Object, int)
- assertTrue("Failed to find correct index", (tVector.indexOf("Test 98",
- 50) == 98));
- assertTrue("Found index of bogus element", (tVector.indexOf(
- "Test 1001", 50) == -1));
- tVector.setElementAt(null, 20);
- tVector.setElementAt(null, 40);
- tVector.setElementAt(null, 60);
- assertTrue("a) Incorrect indexOf returned for null: "
- + tVector.indexOf(null, 25), tVector.indexOf(null, 25) == 40);
- assertTrue("b) Incorrect indexOf returned for null: "
- + tVector.indexOf(null, 20), tVector.indexOf(null, 20) == 20);
-
- try {
- tVector.indexOf(null, -1);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#insertElementAt(java.lang.Object, int)
- */
- public void test_insertElementAtLjava_lang_ObjectI() {
- // Test for method void
- // java.util.Vector.insertElementAt(java.lang.Object, int)
- Vector v = vectorClone(tVector);
- String prevElement = (String) v.elementAt(99);
- v.insertElementAt("Inserted Element", 99);
- assertEquals("Element not inserted", "Inserted Element", ((String) v.elementAt(99))
- );
- assertTrue("Elements shifted incorrectly", ((String) v.elementAt(100))
- .equals(prevElement));
- v.insertElementAt(null, 20);
- assertNull("null not inserted", v.elementAt(20));
-
- try {
- tVector.insertElementAt(null, -5);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.insertElementAt(null, tVector.size() + 1);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.Vector.isEmpty()Vector
- Vector v = new java.util.Vector();
- assertTrue("Empty vector returned false", v.isEmpty());
- v.addElement(new Object());
- assertTrue("non-Empty vector returned true", !v.isEmpty());
- }
-
- /**
- * java.util.Vector#isEmpty()
- */
- public void test_isEmpty_subtest0() {
- final Vector v = new Vector();
- v.addElement("initial");
- Thread t1 = new Thread() {
- public void run() {
- while (!v.isEmpty())
- ;
- v.addElement("final");
- }
- };
- t1.start();
- for (int i = 0; i < 10000; i++) {
- synchronized (v) {
- v.removeElementAt(0);
- v.addElement(String.valueOf(i));
- }
- int size;
- if ((size = v.size()) != 1) {
- String result = "Size is not 1: " + size + " " + v;
- // terminate the thread
- v.removeAllElements();
- fail(result);
- }
- }
- // terminate the thread
- v.removeElementAt(0);
- }
-
- /**
- * java.util.Vector#lastElement()
- */
- public void test_lastElement() {
- // Test for method java.lang.Object java.util.Vector.lastElement()
- assertEquals("Incorrect last element returned", "Test 99", tVector.lastElement()
- );
- tVector.addElement(null);
- assertNull("Incorrect last element returned--wanted null", tVector
- .lastElement());
-
- tVector = new Vector(10);
-
- try {
- tVector.lastElement();
- fail("NoSuchElementException expected");
- } catch (NoSuchElementException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#lastIndexOf(java.lang.Object)
- */
- public void test_lastIndexOfLjava_lang_Object() {
- // Test for method int java.util.Vector.lastIndexOf(java.lang.Object)
- Vector v = new Vector(9);
- for (int i = 0; i < 9; i++)
- v.addElement("Test");
- v.addElement("z");
- assertEquals("Failed to return correct index", 8, v.lastIndexOf("Test"));
- tVector.setElementAt(null, 20);
- tVector.setElementAt(null, 40);
- assertTrue("Incorrect lastIndexOf returned for null: "
- + tVector.lastIndexOf(null), tVector.lastIndexOf(null) == 40);
- }
-
- /**
- * java.util.Vector#lastIndexOf(java.lang.Object, int)
- */
- public void test_lastIndexOfLjava_lang_ObjectI() {
- // Test for method int java.util.Vector.lastIndexOf(java.lang.Object,
- // int)
- assertEquals("Failed to find object",
- 0, tVector.lastIndexOf("Test 0", 0));
- assertTrue("Found Object outside of index", (tVector.lastIndexOf(
- "Test 0", 10) > -1));
- tVector.setElementAt(null, 20);
- tVector.setElementAt(null, 40);
- tVector.setElementAt(null, 60);
- assertTrue("Incorrect lastIndexOf returned for null: "
- + tVector.lastIndexOf(null, 15),
- tVector.lastIndexOf(null, 15) == -1);
- assertTrue("Incorrect lastIndexOf returned for null: "
- + tVector.lastIndexOf(null, 45),
- tVector.lastIndexOf(null, 45) == 40);
-
- try {
- tVector.lastIndexOf(null, tVector.size());
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#remove(int)
- */
- public void test_removeI() {
- // Test for method java.lang.Object java.util.Vector.remove(int)
- tVector.remove(36);
- assertTrue("Contained element after remove", !tVector
- .contains("Test 36"));
- assertEquals("Failed to decrement size after remove",
- 99, tVector.size());
- tVector.add(20, null);
- tVector.remove(19);
- assertNull("Didn't move null element over", tVector.get(19));
- tVector.remove(19);
- assertNotNull("Didn't remove null element", tVector.get(19));
- assertEquals("Failed to decrement size after removing null", 98, tVector
- .size());
-
- try {
- tVector.remove(-5);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.remove(tVector.size() + 1);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method boolean java.util.Vector.remove(java.lang.Object)
- tVector.remove("Test 0");
- assertTrue("Contained element after remove", !tVector
- .contains("Test 0"));
- assertEquals("Failed to decrement size after remove",
- 99, tVector.size());
- tVector.add(null);
- tVector.remove(null);
- assertTrue("Contained null after remove", !tVector.contains(null));
- assertEquals("Failed to decrement size after removing null", 99, tVector
- .size());
- }
-
- /**
- * java.util.Vector#removeAll(java.util.Collection)
- */
- public void test_removeAllLjava_util_Collection() {
- // Test for method boolean
- // java.util.Vector.removeAll(java.util.Collection)
- Vector v = new Vector();
- Collection l = new LinkedList();
- for (int i = 0; i < 5; i++)
- l.add("Test " + i);
- v.addElement(l);
-
- Collection s = new HashSet();
- Object o;
- s.add(o = v.firstElement());
- v.removeAll(s);
- assertTrue("Failed to remove items in collection", !v.contains(o));
- v.removeAll(l);
- assertTrue("Failed to remove all elements", v.isEmpty());
-
- v.add(null);
- v.add(null);
- v.add("Boom");
- v.removeAll(s);
- assertEquals("Should not have removed any elements", 3, v.size());
- l = new LinkedList();
- l.add(null);
- v.removeAll(l);
- assertEquals("Should only have one element", 1, v.size());
- assertEquals("Element should be 'Boom'", "Boom", v.firstElement());
-
- try {
- v.removeAll(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#removeAllElements()
- */
- public void test_removeAllElements() {
- // Test for method void java.util.Vector.removeAllElements()
- Vector v = vectorClone(tVector);
- v.removeAllElements();
- assertEquals("Failed to remove all elements", 0, v.size());
- }
-
- /**
- * java.util.Vector#removeElement(java.lang.Object)
- */
- public void test_removeElementLjava_lang_Object() {
- // Test for method boolean
- // java.util.Vector.removeElement(java.lang.Object)
- Vector v = vectorClone(tVector);
- v.removeElement("Test 98");
- assertEquals("Element not removed", "Test 99", ((String) v.elementAt(98))
- );
- assertTrue("Vector is wrong size after removal: " + v.size(),
- v.size() == 99);
- tVector.addElement(null);
- v.removeElement(null);
- assertTrue("Vector is wrong size after removing null: " + v.size(), v
- .size() == 99);
- }
-
- /**
- * java.util.Vector#removeElementAt(int)
- */
- public void test_removeElementAtI() {
- // Test for method void java.util.Vector.removeElementAt(int)
- Vector v = vectorClone(tVector);
- v.removeElementAt(50);
- assertEquals("Failed to remove element", -1, v.indexOf("Test 50", 0));
- tVector.insertElementAt(null, 60);
- tVector.removeElementAt(60);
- assertNotNull("Element at 60 should not be null after removal", tVector
- .elementAt(60));
-
- try {
- tVector.elementAt(-5);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.elementAt(tVector.size() + 1);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#retainAll(java.util.Collection)
- */
- public void test_retainAllLjava_util_Collection() {
- // Test for method boolean
- // java.util.Vector.retainAll(java.util.Collection)
- Object o = tVector.firstElement();
- tVector.add(null);
- Collection s = new HashSet();
- s.add(o);
- s.add(null);
- tVector.retainAll(s);
- assertTrue("Retained items other than specified", tVector.size() == 2
- && tVector.contains(o) && tVector.contains(null));
-
- Iterator i = s.iterator();
-
- while (i.hasNext()) {
- assertTrue(tVector.contains(i.next()));
- }
-
- try {
- tVector.retainAll(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#set(int, java.lang.Object)
- */
- public void test_setILjava_lang_Object() {
- // Test for method java.lang.Object java.util.Vector.set(int,
- // java.lang.Object)
- Object o = new Object();
- tVector.set(23, o);
- assertTrue("Failed to set Object", tVector.get(23) == o);
-
- try {
- tVector.set(-5, "Wrong position");
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.set(tVector.size() + 1, "Wrong position");
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#setElementAt(java.lang.Object, int)
- */
- public void test_setElementAtLjava_lang_ObjectI() {
- // Test for method void java.util.Vector.setElementAt(java.lang.Object,
- // int)
- Vector v = vectorClone(tVector);
- v.setElementAt("Inserted Element", 99);
- assertEquals("Element not set", "Inserted Element", ((String) v.elementAt(99))
- );
-
- try {
- tVector.setElementAt("Wrong position", -5);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.setElementAt("Wrong position", tVector.size() + 1);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#setSize(int)
- */
- public void test_setSizeI() {
- // Test for method void java.util.Vector.setSize(int)
- Vector v = vectorClone(tVector);
- v.setSize(10);
- assertEquals("Failed to set size", 10, v.size());
-
- try {
- tVector.setSize(-5);
- fail("ArrayIndexOutOfBoundsException expected");
- } catch(ArrayIndexOutOfBoundsException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#size()
- */
- public void test_size() {
- // Test for method int java.util.Vector.size()
- assertEquals("Returned incorrect size", 100, tVector.size());
-
- final Vector v = new Vector();
- v.addElement("initial");
- Thread t1 = new Thread() {
- public void run() {
- while (v.size() > 0)
- ;
- v.addElement("final");
- }
- };
- t1.start();
- for (int i = 0; i < 10000; i++) {
- synchronized (v) {
- v.removeElementAt(0);
- v.addElement(String.valueOf(i));
- }
- int size;
- if ((size = v.size()) != 1) {
- String result = "Size is not 1: " + size + " " + v;
- // terminate the thread
- v.removeAllElements();
- fail(result);
- }
- }
- // terminate the thread
- v.removeElementAt(0);
- }
-
- /**
- * java.util.Vector#subList(int, int)
- */
- public void test_subListII() {
- // Test for method java.util.List java.util.Vector.subList(int, int)
- List sl = tVector.subList(10, 25);
- assertEquals("Returned sublist of incorrect size", 15, sl.size());
- for (int i = 10; i < 25; i++)
- assertTrue("Returned incorrect sublist", sl
- .contains(tVector.get(i)));
-
- assertEquals("Not synchronized random access", "java.util.Collections$SynchronizedRandomAccessList", sl.getClass().getName()
- );
-
- try {
- tVector.subList(-10, 25);
- fail("IndexOutOfBoundsException expected");
- } catch(IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.subList(10, tVector.size() + 1);
- fail("IndexOutOfBoundsException expected");
- } catch(IndexOutOfBoundsException e) {
- //expected
- }
-
- try {
- tVector.subList(25, 10);
- fail("IllegalArgumentException expected");
- } catch(IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#toArray()
- */
- public void test_toArray() {
- // Test for method java.lang.Object [] java.util.Vector.toArray()
- assertTrue("Returned incorrect array", Arrays.equals(objArray, tVector
- .toArray()));
- }
-
- /**
- * java.util.Vector#toArray(java.lang.Object[])
- */
- public void test_toArray$Ljava_lang_Object() {
- // Test for method java.lang.Object []
- // java.util.Vector.toArray(java.lang.Object [])
- Object[] o = new Object[1000];
- Object f = new Object();
- for (int i = 0; i < o.length; i++)
- o[i] = f;
- tVector.toArray(o);
- assertNull("Failed to set slot to null", o[100]);
- for (int i = 0; i < tVector.size(); i++)
- assertTrue("Returned incorrect array", tVector.elementAt(i) == o[i]);
-
- try {
- tVector.toArray(null);
- fail("NullPointerException expected");
- } catch(NullPointerException e) {
- //expected
- }
- tVector = new Vector<Integer>();
- tVector.add(new Integer(1));
- tVector.add(new Integer(2));
- tVector.add(new Integer(3));
- try {
- tVector.toArray(new String[tVector.size()]);
- fail("ArrayStoreException expected");
- } catch(ArrayStoreException e) {
- //expected
- }
- }
-
- /**
- * java.util.Vector#toString()
- */
- public void test_toString() {
- // Test for method java.lang.String java.util.Vector.toString()
- assertTrue("Incorrect String returned", tVector.toString().equals(
- vString));
-
- Vector v = new Vector();
- v.addElement("one");
- v.addElement(v);
- v.addElement("3");
- // test last element
- v.addElement(v);
- String result = v.toString();
- assertTrue("should contain self ref", result.indexOf("(this") > -1);
- }
-
- /**
- * java.util.Vector#trimToSize()
- */
- public void test_trimToSize() {
- // Test for method void java.util.Vector.trimToSize()
- Vector v = new Vector(10);
- v.addElement(new Object());
- v.trimToSize();
- assertEquals("Failed to trim capacity", 1, v.capacity());
- }
-
- class Mock_Vector extends Vector {
- @Override
- protected void removeRange(int from, int to) {
- super.removeRange(from, to);
- }
- }
-
- public void test_removeRangeII() {
- Mock_Vector mv = new Mock_Vector();
- mv.add("First");
- mv.add("Second");
- mv.add("One more");
- mv.add("Last");
- mv.removeRange(1, 3);
- assertTrue(mv.contains("First"));
- assertFalse(mv.contains("Second"));
- assertFalse(mv.contains("One more"));
- assertTrue(mv.contains("Last"));
- }
-
- protected Vector vectorClone(Vector s) {
- return (Vector) s.clone();
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- for (int i = 0; i < 100; i++) {
- tVector.addElement("Test " + i);
- }
- objArray = new Object[100];
- for (int i = 0; i < 100; i++) {
- objArray[i] = "Test " + i;
- }
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/WeakHashMapTest.java b/luni/src/test/java/tests/api/java/util/WeakHashMapTest.java
deleted file mode 100644
index d1a43e5..0000000
--- a/luni/src/test/java/tests/api/java/util/WeakHashMapTest.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.java.util;
-
-import java.util.AbstractMap;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import libcore.java.lang.ref.FinalizationTester;
-
-import tests.support.Support_MapTest2;
-
-public class WeakHashMapTest extends junit.framework.TestCase {
- class MockMap extends AbstractMap {
- public Set entrySet() {
- return null;
- }
- public int size(){
- return 0;
- }
- }
-
- Object[] keyArray = new Object[100];
-
- Object[] valueArray = new Object[100];
-
- WeakHashMap whm;
-
- /**
- * java.util.WeakHashMap#WeakHashMap()
- */
- public void test_Constructor() {
- // Test for method java.util.WeakHashMap()
- new Support_MapTest2(new WeakHashMap()).runTest();
-
- whm = new WeakHashMap();
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
- for (int i = 0; i < 100; i++)
- assertTrue("Incorrect value retrieved",
- whm.get(keyArray[i]) == valueArray[i]);
-
- }
-
- /**
- * java.util.WeakHashMap#WeakHashMap(int)
- */
- public void test_ConstructorI() {
- // Test for method java.util.WeakHashMap(int)
- whm = new WeakHashMap(50);
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
- for (int i = 0; i < 100; i++)
- assertTrue("Incorrect value retrieved",
- whm.get(keyArray[i]) == valueArray[i]);
-
- WeakHashMap empty = new WeakHashMap(0);
- assertNull("Empty weakhashmap access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
-
- try {
- new WeakHashMap(-50);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.WeakHashMap#WeakHashMap(int, float)
- */
- public void test_ConstructorIF() {
- // Test for method java.util.WeakHashMap(int, float)
- whm = new WeakHashMap(50, 0.5f);
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
- for (int i = 0; i < 100; i++)
- assertTrue("Incorrect value retrieved",
- whm.get(keyArray[i]) == valueArray[i]);
-
- WeakHashMap empty = new WeakHashMap(0, 0.75f);
- assertNull("Empty hashtable access", empty.get("nothing"));
- empty.put("something", "here");
- assertTrue("cannot get element", empty.get("something") == "here");
-
- try {
- new WeakHashMap(50, -0.5f);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
-
- try {
- new WeakHashMap(-50, 0.5f);
- fail("IllegalArgumentException expected");
- } catch (IllegalArgumentException e) {
- //expected
- }
- }
-
- /**
- * java.util.WeakHashMap#WeakHashMap(java.util.Map)
- */
- public void test_ConstructorLjava_util_Map() {
- Map mockMap = new MockMap();
- WeakHashMap map = new WeakHashMap(mockMap);
- assertEquals("Size should be 0", 0, map.size());
-
- try {
- new WeakHashMap(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.WeakHashMap#clear()
- */
- public void test_clear() {
- // Test for method boolean java.util.WeakHashMap.clear()
- whm = new WeakHashMap();
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
- whm.clear();
- assertTrue("Cleared map should be empty", whm.isEmpty());
- for (int i = 0; i < 100; i++)
- assertNull("Cleared map should only return null", whm
- .get(keyArray[i]));
-
- }
-
- /**
- * java.util.WeakHashMap#containsKey(java.lang.Object)
- */
- public void test_containsKeyLjava_lang_Object() {
- // Test for method boolean java.util.WeakHashMap.containsKey()
- whm = new WeakHashMap();
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
- for (int i = 0; i < 100; i++)
- assertTrue("Should contain referenced key", whm
- .containsKey(keyArray[i]));
- keyArray[25] = null;
- keyArray[50] = null;
- }
-
- /**
- * java.util.WeakHashMap#containsValue(java.lang.Object)
- */
- public void test_containsValueLjava_lang_Object() {
- // Test for method boolean java.util.WeakHashMap.containsValue()
- whm = new WeakHashMap();
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
- for (int i = 0; i < 100; i++)
- assertTrue("Should contain referenced value", whm
- .containsValue(valueArray[i]));
- keyArray[25] = null;
- keyArray[50] = null;
- }
-
- /**
- * java.util.WeakHashMap#entrySet()
- */
- public void test_entrySet() {
- // Test for method java.util.Set java.util.WeakHashMap.entrySet()
- whm = new WeakHashMap();
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
- List keys = Arrays.asList(keyArray);
- List values = Arrays.asList(valueArray);
- Set entrySet = whm.entrySet();
- assertTrue("Incorrect number of entries returned--wanted 100, got: "
- + entrySet.size(), entrySet.size() == 100);
- Iterator it = entrySet.iterator();
- while (it.hasNext()) {
- Map.Entry entry = (Map.Entry) it.next();
- assertTrue("Invalid map entry returned--bad key", keys
- .contains(entry.getKey()));
- assertTrue("Invalid map entry returned--bad key", values
- .contains(entry.getValue()));
- }
- keys = null;
- values = null;
- keyArray[50] = null;
-
- int count = 0;
- do {
- System.gc();
- System.gc();
- FinalizationTester.induceFinalization();
- count++;
- } while (count <= 5 && entrySet.size() == 100);
-
- assertTrue(
- "Incorrect number of entries returned after gc--wanted 99, got: "
- + entrySet.size(), entrySet.size() == 99);
- }
-
- /**
- * java.util.WeakHashMap#isEmpty()
- */
- public void test_isEmpty() {
- // Test for method boolean java.util.WeakHashMap.isEmpty()
- whm = new WeakHashMap();
- assertTrue("New map should be empty", whm.isEmpty());
- Object myObject = new Object();
- whm.put(myObject, myObject);
- assertTrue("Map should not be empty", !whm.isEmpty());
- whm.remove(myObject);
- assertTrue("Map with elements removed should be empty", whm.isEmpty());
- }
-
- /**
- * java.util.WeakHashMap#put(java.lang.Object, java.lang.Object)
- */
- public void test_putLjava_lang_ObjectLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.WeakHashMap.put(java.lang.Object, java.lang.Object)
- WeakHashMap map = new WeakHashMap();
- map.put(null, "value"); // add null key
- System.gc();
- System.gc();
- FinalizationTester.induceFinalization();
- map.remove("nothing"); // Cause objects in queue to be removed
- assertEquals("null key was removed", 1, map.size());
- }
-
- /**
- * java.util.WeakHashMap#putAll(java.util.Map)
- */
- public void test_putAllLjava_util_Map() {
- Map mockMap=new MockMap();
- WeakHashMap map = new WeakHashMap();
- map.putAll(mockMap);
- assertEquals("Size should be 0", 0, map.size());
-
- try {
- map.putAll(null);
- fail("NullPointerException exected");
- } catch (NullPointerException e) {
- //expected
- }
- }
-
- /**
- * java.util.WeakHashMap#remove(java.lang.Object)
- */
- public void test_removeLjava_lang_Object() {
- // Test for method java.lang.Object
- // java.util.WeakHashMap.remove(java.lang.Object)
- whm = new WeakHashMap();
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
-
- assertTrue("Remove returned incorrect value",
- whm.remove(keyArray[25]) == valueArray[25]);
- assertNull("Remove returned incorrect value",
- whm.remove(keyArray[25]));
- assertEquals("Size should be 99 after remove", 99, whm.size());
- }
-
- /**
- * java.util.WeakHashMap#size()
- */
- public void test_size() {
- whm = new WeakHashMap();
- assertEquals(0, whm.size());
- }
-
- /**
- * java.util.WeakHashMap#keySet()
- */
- public void test_keySet() {
- // Test for method java.util.Set java.util.WeakHashMap.keySet()
- whm = new WeakHashMap();
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
-
- List keys = Arrays.asList(keyArray);
- List values = Arrays.asList(valueArray);
-
- Set keySet = whm.keySet();
- assertEquals("Incorrect number of keys returned,", 100, keySet.size());
- Iterator it = keySet.iterator();
- while (it.hasNext()) {
- Object key = it.next();
- assertTrue("Invalid map entry returned--bad key", keys
- .contains(key));
- }
- keys = null;
- values = null;
- keyArray[50] = null;
-
- int count = 0;
- do {
- System.gc();
- System.gc();
- FinalizationTester.induceFinalization();
- count++;
- } while (count <= 5 && keySet.size() == 100);
-
- assertEquals("Incorrect number of keys returned after gc,", 99, keySet
- .size());
- }
-
- /**
- * java.util.WeakHashMap#values()
- */
- public void test_values() {
- // Test for method java.util.Set java.util.WeakHashMap.values()
- whm = new WeakHashMap();
- for (int i = 0; i < 100; i++)
- whm.put(keyArray[i], valueArray[i]);
-
- List keys = Arrays.asList(keyArray);
- List values = Arrays.asList(valueArray);
-
- Collection valuesCollection = whm.values();
- assertEquals("Incorrect number of keys returned,", 100,
- valuesCollection.size());
- Iterator it = valuesCollection.iterator();
- while (it.hasNext()) {
- Object value = it.next();
- assertTrue("Invalid map entry returned--bad value", values
- .contains(value));
- }
- keys = null;
- values = null;
- keyArray[50] = null;
-
- int count = 0;
- do {
- System.gc();
- System.gc();
- FinalizationTester.induceFinalization();
- count++;
- } while (count <= 5 && valuesCollection.size() == 100);
-
- assertEquals("Incorrect number of keys returned after gc,", 99,
- valuesCollection.size());
- }
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- for (int i = 0; i < 100; i++) {
- keyArray[i] = new Object();
- valueArray[i] = new Object();
- }
-
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/support/A.java b/luni/src/test/java/tests/api/java/util/support/A.java
deleted file mode 100644
index c2b43b5..0000000
--- a/luni/src/test/java/tests/api/java/util/support/A.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package tests.api.java.util.support;
-
-public class A implements I {
- private static P pp = new P();
-
- public A() {
- pp.setClazz(getClass());
- }
-
- public String find(String key) {
- return pp.findProp(key);
- }
-}
diff --git a/luni/src/test/java/tests/api/java/util/support/B.java b/luni/src/test/java/tests/api/java/util/support/B.java
deleted file mode 100644
index baafdbe..0000000
--- a/luni/src/test/java/tests/api/java/util/support/B.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package tests.api.java.util.support;
-
-public class B extends A {
-}
diff --git a/luni/src/test/java/tests/api/java/util/support/I.java b/luni/src/test/java/tests/api/java/util/support/I.java
deleted file mode 100644
index a1cd73a..0000000
--- a/luni/src/test/java/tests/api/java/util/support/I.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package tests.api.java.util.support;
-
-public interface I {
- String find(String key);
-}
diff --git a/luni/src/test/java/tests/api/java/util/support/P.java b/luni/src/test/java/tests/api/java/util/support/P.java
deleted file mode 100644
index 6883936..0000000
--- a/luni/src/test/java/tests/api/java/util/support/P.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package tests.api.java.util.support;
-
-import java.util.ResourceBundle;
-
-public class P {
- private Class c;
-
- public void setClazz(Class c) {
- this.c = c;
- }
-
- public String findProp(String key) {
- return findProp(this.c, key);
- }
-
- private String findProp(Class cls, String key) {
- String ret = null;
- try {
- ResourceBundle b = ResourceBundle.getBundle(cls.getName());
- ret = (String)b.getObject(key);
- } catch (Exception e) {
- }
- if (ret == null && !cls.equals(Object.class) && !cls.isPrimitive()) {
- ret = findProp(cls.getSuperclass(), key);
- }
- return ret;
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/net/SocketFactoryTest.java b/luni/src/test/java/tests/api/javax/net/SocketFactoryTest.java
deleted file mode 100644
index e939a9b..0000000
--- a/luni/src/test/java/tests/api/javax/net/SocketFactoryTest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
-package tests.api.javax.net;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-
-import javax.net.SocketFactory;
-
-import junit.framework.TestCase;
-
-public class SocketFactoryTest extends TestCase {
-
- public void test_Constructor() throws Exception {
- new MySocketFactory();
- }
-
- public final void test_createSocket() throws Exception {
- SocketFactory sf = SocketFactory.getDefault();
-
- Socket s = sf.createSocket();
- assertNotNull(s);
- assertEquals(-1, s.getLocalPort());
- assertEquals(0, s.getPort());
-
- MySocketFactory msf = new MySocketFactory();
- try {
- msf.createSocket();
- fail("No expected SocketException");
- } catch (SocketException expected) {
- }
- }
-
- public final void test_createSocket_StringI() throws Exception {
- SocketFactory sf = SocketFactory.getDefault();
- int sport = new ServerSocket(0).getLocalPort();
- int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
-
- Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport);
- assertNotNull(s);
- assertTrue("Failed to create socket", s.getPort() == sport);
-
- try {
- sf.createSocket("bla-bla", sport);
- fail("UnknownHostException wasn't thrown");
- } catch (UnknownHostException expected) {
- }
-
- for (int i = 0; i < invalidPorts.length; i++) {
- try {
- sf.createSocket(InetAddress.getLocalHost().getHostName(), invalidPorts[i]);
- fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
- } catch (IllegalArgumentException expected) {
- }
- }
-
- try {
- sf.createSocket(InetAddress.getLocalHost().getHostName(), s.getLocalPort());
- fail("IOException wasn't thrown");
- } catch (IOException expected) {
- }
-
- SocketFactory f = SocketFactory.getDefault();
- try {
- f.createSocket(InetAddress.getLocalHost().getHostName(), 8082);
- fail("IOException wasn't thrown ...");
- } catch (IOException expected) {
- }
- }
-
- public final void test_createSocket_InetAddressI() throws Exception {
- SocketFactory sf = SocketFactory.getDefault();
- int sport = new ServerSocket(0).getLocalPort();
- int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
-
- Socket s = sf.createSocket(InetAddress.getLocalHost(), sport);
- assertNotNull(s);
- assertTrue("Failed to create socket", s.getPort() == sport);
-
- for (int i = 0; i < invalidPorts.length; i++) {
- try {
- sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i]);
- fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
- } catch (IllegalArgumentException expected) {
- }
- }
-
- try {
- sf.createSocket(InetAddress.getLocalHost(), s.getLocalPort());
- fail("IOException wasn't thrown");
- } catch (IOException expected) {
- }
-
- SocketFactory f = SocketFactory.getDefault();
- try {
- f.createSocket(InetAddress.getLocalHost(), 8081);
- fail("IOException wasn't thrown ...");
- } catch (IOException expected) {
- }
- }
-
- public final void test_createSocket_InetAddressIInetAddressI() throws Exception {
- SocketFactory sf = SocketFactory.getDefault();
- int sport = new ServerSocket(0).getLocalPort();
- int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
-
- Socket s = sf.createSocket(InetAddress.getLocalHost(), sport,
- InetAddress.getLocalHost(), 0);
- assertNotNull(s);
- assertTrue("1: Failed to create socket", s.getPort() == sport);
- int portNumber = s.getLocalPort();
-
- for (int i = 0; i < invalidPorts.length; i++) {
- try {
- sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i],
- InetAddress.getLocalHost(), portNumber);
- fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- sf.createSocket(InetAddress.getLocalHost(), sport,
- InetAddress.getLocalHost(), invalidPorts[i]);
- fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
- } catch (IllegalArgumentException expected) {
- }
- }
-
- try {
- sf.createSocket(InetAddress.getLocalHost(), sport,
- InetAddress.getLocalHost(), portNumber);
- fail("IOException wasn't thrown");
- } catch (IOException expected) {
- }
-
- SocketFactory f = SocketFactory.getDefault();
- try {
- f.createSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082);
- fail("IOException wasn't thrown ...");
- } catch (IOException expected) {
- }
- }
-
- /**
- * javax.net.SocketFactory#createSocket(String host, int port,
- * InetAddress localHost, int localPort)
- */
- public final void test_createSocket_05() throws Exception {
- SocketFactory sf = SocketFactory.getDefault();
- int sport = new ServerSocket(0).getLocalPort();
- int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE};
-
- Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport,
- InetAddress.getLocalHost(), 0);
- assertNotNull(s);
- assertTrue("1: Failed to create socket", s.getPort() == sport);
-
- try {
- sf.createSocket("bla-bla", sport, InetAddress.getLocalHost(), 0);
- fail("UnknownHostException wasn't thrown");
- } catch (UnknownHostException expected) {
- }
-
- for (int i = 0; i < invalidPorts.length; i++) {
- try {
- sf.createSocket(InetAddress.getLocalHost().getHostName(), invalidPorts[i],
- InetAddress.getLocalHost(), 0);
- fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
- } catch (IllegalArgumentException expected) {
- }
- try {
- sf.createSocket(InetAddress.getLocalHost().getHostName(), sport,
- InetAddress.getLocalHost(), invalidPorts[i]);
- fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]);
- } catch (IllegalArgumentException expected) {
- }
- }
-
- try {
- sf.createSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082);
- fail("IOException wasn't thrown ...");
- } catch (IOException expected) {
- }
- }
-
- /**
- * javax.net.SocketFactory#getDefault()
- */
- public final void test_getDefault() {
- SocketFactory sf = SocketFactory.getDefault();
- Socket s;
- try {
- s = sf.createSocket(InetAddress.getLocalHost().getHostName(), 8082);
- s.close();
- } catch (IOException e) {
- }
- try {
- s = sf.createSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082);
- s.close();
- } catch (IOException e) {
- }
- try {
- s = sf.createSocket(InetAddress.getLocalHost(), 8081);
- s.close();
- } catch (IOException e) {
- }
- try {
- s = sf.createSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082);
- s.close();
- } catch (IOException e) {
- }
- }
-}
-
-class MySocketFactory extends SocketFactory {
-
- public MySocketFactory() {
- super();
- }
-
- @Override
- public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
- return null;
- }
-
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
- throws IOException, UnknownHostException {
- return null;
- }
-
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- return null;
- }
-
- @Override
- public Socket createSocket(InetAddress address, int port,
- InetAddress localAddress, int localPort) throws IOException {
- return null;
- }
-
-}
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java
deleted file mode 100644
index 30a1a9c..0000000
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java
+++ /dev/null
@@ -1,1482 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.net.ssl;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ReadOnlyBufferException;
-import java.nio.channels.Pipe;
-import java.nio.channels.Pipe.SinkChannel;
-import java.nio.channels.Pipe.SourceChannel;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
-
-import junit.framework.TestCase;
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.KnownFailure;
-
-
-/**
- * Tests for SSLEngine class
- *
- */
-public class SSLEngineTest extends TestCase {
-
- private HandshakeHandler clientEngine;
- private HandshakeHandler serverEngine;
-
- @Override protected void setUp() throws Exception {
- super.setUp();
- }
-
- /**
- * Test for <code>SSLEngine()</code> constructor Assertion: creates
- * SSLEngine object with null host and -1 port
- * @throws NoSuchAlgorithmException
- */
- public void test_Constructor() throws NoSuchAlgorithmException {
- SSLEngine e = getEngine();
- assertNull(e.getPeerHost());
- assertEquals(-1, e.getPeerPort());
- String[] suites = e.getSupportedCipherSuites();
- e.setEnabledCipherSuites(suites);
- assertEquals(e.getEnabledCipherSuites().length, suites.length);
- }
-
- /**
- * Test for <code>SSLEngine(String host, int port)</code> constructor
- * @throws NoSuchAlgorithmException
- */
- public void test_ConstructorLjava_lang_StringI01() throws NoSuchAlgorithmException {
- int port = 1010;
- SSLEngine e = getEngine(null, port);
- assertNull(e.getPeerHost());
- assertEquals(e.getPeerPort(), port);
- try {
- e.beginHandshake();
- } catch (IllegalStateException ex) {
- // expected
- } catch (SSLException ex) {
- fail("unexpected SSLException was thrown.");
- }
- e = getEngine(null, port);
- e.setUseClientMode(true);
- try {
- e.beginHandshake();
- } catch (SSLException ex) {
- // expected
- }
- e = getEngine(null, port);
- e.setUseClientMode(false);
- try {
- e.beginHandshake();
- } catch (SSLException ex) {
- // expected
- }
- }
-
- /**
- * Test for <code>SSLEngine(String host, int port)</code> constructor
- * @throws NoSuchAlgorithmException
- */
- public void test_ConstructorLjava_lang_StringI02() throws NoSuchAlgorithmException {
- String host = "new host";
- int port = 8080;
- SSLEngine e = getEngine(host, port);
- assertEquals(e.getPeerHost(), host);
- assertEquals(e.getPeerPort(), port);
- String[] suites = e.getSupportedCipherSuites();
- e.setEnabledCipherSuites(suites);
- assertEquals(e.getEnabledCipherSuites().length, suites.length);
- e.setUseClientMode(true);
- assertTrue(e.getUseClientMode());
- }
-
- /**
- * Test for <code>getPeerHost()</code> method
- * @throws NoSuchAlgorithmException
- */
- public void test_getPeerHost() throws NoSuchAlgorithmException {
- SSLEngine e = getEngine();
- assertNull(e.getPeerHost());
- e = getEngine("www.fortify.net", 80);
- assertEquals("Incorrect host name", "www.fortify.net", e.getPeerHost());
- }
-
- /**
- * Test for <code>getPeerPort()</code> method
- * @throws NoSuchAlgorithmException
- */
- public void test_getPeerPort() throws NoSuchAlgorithmException {
- SSLEngine e = getEngine();
- assertEquals("Incorrect default value of peer port",
- -1 ,e.getPeerPort());
- e = getEngine("www.fortify.net", 80);
- assertEquals("Incorrect peer port", 80, e.getPeerPort());
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#getSupportedProtocols()
- */
- public void test_getSupportedProtocols() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- String[] res = sse.getSupportedProtocols();
- assertNotNull(res);
- assertTrue(res.length > 0);
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#setEnabledProtocols(String[] protocols)
- * javax.net.ssl.SSLEngine#getEnabledProtocols()
- */
- public void test_EnabledProtocols() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- String[] pr = sse.getSupportedProtocols();
- try {
- sse.setEnabledProtocols(pr);
- String[] res = sse.getEnabledProtocols();
- assertNotNull("Null array was returned", res);
- assertEquals("Incorrect array length", res.length, pr.length);
- assertTrue("Incorrect array was returned", Arrays.equals(res, pr));
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- try {
- sse.setEnabledProtocols(null);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#getSupportedCipherSuites()
- */
- public void test_getSupportedCipherSuites() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- String[] res = sse.getSupportedCipherSuites();
- assertNotNull(res);
- assertTrue(res.length > 0);
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#setEnabledCipherSuites(String[] suites)
- * javax.net.ssl.SSLEngine#getEnabledCipherSuites()
- */
- public void test_EnabledCipherSuites() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- String[] st = sse.getSupportedCipherSuites();
- try {
- sse.setEnabledCipherSuites(st);
- String[] res = sse.getEnabledCipherSuites();
- assertNotNull("Null array was returned", res);
- assertEquals("Incorrect array length", res.length, st.length);
- assertTrue("Incorrect array was returned", Arrays.equals(res, st));
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- try {
- sse.setEnabledCipherSuites(null);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#setEnableSessionCreation(boolean flag)
- * javax.net.ssl.SSLEngine#getEnableSessionCreation()
- */
- public void test_EnableSessionCreation() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- assertTrue(sse.getEnableSessionCreation());
- sse.setEnableSessionCreation(false);
- assertFalse(sse.getEnableSessionCreation());
- sse.setEnableSessionCreation(true);
- assertTrue(sse.getEnableSessionCreation());
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#setNeedClientAuth(boolean need)
- * javax.net.ssl.SSLEngine#getNeedClientAuth()
- */
- public void test_NeedClientAuth() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- sse.setNeedClientAuth(false);
- assertFalse(sse.getNeedClientAuth());
- sse.setNeedClientAuth(true);
- assertTrue(sse.getNeedClientAuth());
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#setWantClientAuth(boolean want)
- * javax.net.ssl.SSLEngine#getWantClientAuth()
- */
- public void test_WantClientAuth() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- sse.setWantClientAuth(false);
- assertFalse(sse.getWantClientAuth());
- sse.setWantClientAuth(true);
- assertTrue(sse.getWantClientAuth());
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#beginHandshake()
- */
- public void test_beginHandshake() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- sse.beginHandshake();
- fail("IllegalStateException wasn't thrown");
- } catch (IllegalStateException se) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalStateException");
- }
- sse = getEngine("new host", 1080);
- try {
- sse.beginHandshake();
- fail("IllegalStateException wasn't thrown");
- } catch (IllegalStateException ise) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalStateException");
- }
- sse = getEngine();
- try {
- sse.setUseClientMode(true);
- sse.beginHandshake();
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#setUseClientMode(boolean mode)
- * javax.net.ssl.SSLEngine#getUseClientMode()
- */
- @AndroidOnly("The RI doesn't throw the expected IllegalStateException.")
- public void test_UseClientMode() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- sse.setUseClientMode(false);
- assertFalse(sse.getUseClientMode());
- sse.setUseClientMode(true);
- assertTrue(sse.getUseClientMode());
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
-
- try {
- sse = getEngine(null, 1080);
- sse.setUseClientMode(true);
- sse.beginHandshake();
- try {
- sse.setUseClientMode(false);
- fail("IllegalArgumentException was not thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- }
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#getSession()
- */
- public void test_getSession() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- assertNotNull(sse.getSession());
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#getHandshakeStatus()
- */
- public void test_getHandshakeStatus() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- assertEquals(sse.getHandshakeStatus().toString(), "NOT_HANDSHAKING");
- sse.setUseClientMode(true);
- sse.beginHandshake();
- assertEquals(sse.getHandshakeStatus().toString(), "NEED_WRAP");
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#getDelegatedTask()
- */
- @KnownFailure("com.android.org.conscrypt.SSLEngineImpl#getDelegatedTask() throws NPE instead of returning null")
- public void test_getDelegatedTask() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
- try {
- assertNull(sse.getDelegatedTask());
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- }
-
- /**
- * @throws IOException
- * @throws InterruptedException
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
- * int offset, int length)
- * Exception case: SSLException should be thrown.
- */
- public void test_unwrap_01() throws IOException, InterruptedException {
- prepareEngines();
- doHandshake();
-
- ByteBuffer bbs = ByteBuffer.wrap(new byte[] {1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,31,2,3,1,2,3,1,2,3,1,2,3});
- ByteBuffer bbd = ByteBuffer.allocate(100);
- try {
- clientEngine.engine.unwrap(bbs, new ByteBuffer[] { bbd }, 0, 1);
- fail("SSLException wasn't thrown");
- } catch (SSLException ex) {
- //expected
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
- * int offset, int length)
- * Exception case: IndexOutOfBoundsException should be thrown.
- */
- @KnownFailure("Fixed in DonutBurger, boundary checks missing")
- public void test_unwrap_02() throws SSLException {
- String host = "new host";
- int port = 8080;
- ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
-
- ByteBuffer bb = ByteBuffer.allocate(10);
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.unwrap(bb, bbA, -1, 3);
- fail("IndexOutOfBoundsException wasn't thrown");
- } catch (IndexOutOfBoundsException iobe) {
- //expected
- }
- try {
- sse.unwrap(bb, bbA, 0, -3);
- fail("IndexOutOfBoundsException wasn't thrown");
- } catch (IndexOutOfBoundsException iobe) {
- //expected
- }
- try {
- sse.unwrap(bb, bbA, bbA.length + 1, bbA.length);
- fail("IndexOutOfBoundsException wasn't thrown");
- } catch (IndexOutOfBoundsException iobe) {
- //expected
- }
- try {
- sse.unwrap(bb, bbA, 0, bbA.length + 1);
- fail("IndexOutOfBoundsException wasn't thrown");
- } catch (IndexOutOfBoundsException iobe) {
- //expected
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
- * int offset, int length)
- * Exception case: ReadOnlyBufferException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_unwrap_03() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbR = ByteBuffer.allocate(100).asReadOnlyBuffer();
- ByteBuffer[] bbA = { bbR, ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
-
- ByteBuffer bb = ByteBuffer.allocate(10);
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.unwrap(bb, bbA, 0, bbA.length);
- fail("ReadOnlyBufferException wasn't thrown");
- } catch (ReadOnlyBufferException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of ReadOnlyBufferException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
- * int offset, int length)
- * Exception case: IllegalArgumentException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_unwrap_04() {
- String host = "new host";
- int port = 8080;
- ByteBuffer[] bbA = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100)};
- ByteBuffer[] bbAN = {ByteBuffer.allocate(100), null, ByteBuffer.allocate(100)};
- ByteBuffer[] bbN = null;
- ByteBuffer bb = ByteBuffer.allocate(10);
- ByteBuffer bN = null;
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.unwrap(bN, bbA, 0, 3);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- try {
- sse.unwrap(bb, bbAN, 0, 3);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- try {
- sse.unwrap(bb, bbN, 0, 0);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- try {
- sse.unwrap(bN, bbN, 0, 0);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
- * int offset, int length)
- * Exception case: IllegalStateException should be thrown.
- */
- @AndroidOnly("The RI doesn't throw the IllegalStateException.")
- public void test_unwrap_05() {
- String host = "new host";
- int port = 8080;
- ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
-
- ByteBuffer bb = ByteBuffer.allocate(10);
- SSLEngine sse = getEngine(host, port);
-
- try {
- sse.unwrap(bb, bbA, 0, bbA.length);
- fail("IllegalStateException wasn't thrown");
- } catch (IllegalStateException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalStateException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts,
- * int offset, int length)
- */
- public void test_unwrap_06() {
- String host = "new host";
- int port = 8080;
- ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
-
- ByteBuffer bb = ByteBuffer.allocate(10);
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- SSLEngineResult res = sse.unwrap(bb, bbA, 0, bbA.length);
- assertEquals(0, res.bytesConsumed());
- assertEquals(0, res.bytesProduced());
- } catch (Exception ex) {
- fail("Unexpected exception: " + ex);
- }
- }
-
- public void test_wrap_01() throws IOException, InterruptedException {
- prepareEngines();
- doHandshake();
- ByteBuffer bbs = ByteBuffer.allocate(100);
- ByteBuffer bbd = ByteBuffer.allocate(20000);
- clientEngine.engine.wrap(new ByteBuffer[] { bbs }, 0, 1, bbd);
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
- * int length, ByteBuffer dst)
- * Exception case: IndexOutOfBoundsException should be thrown.
- */
- @KnownFailure("Fixed in DonutBurger, boundary checks missing")
- public void test_wrap_02() throws SSLException {
- String host = "new host";
- int port = 8080;
- ByteBuffer bb = ByteBuffer.allocate(10);
- ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.wrap(bbA, -1, 3, bb);
- fail("IndexOutOfBoundsException wasn't thrown");
- } catch (IndexOutOfBoundsException iobe) {
- //expected
- }
- try {
- sse.wrap(bbA, 0, -3, bb);
- fail("IndexOutOfBoundsException wasn't thrown");
- } catch (IndexOutOfBoundsException iobe) {
- //expected
- }
- try {
- sse.wrap(bbA, bbA.length + 1, bbA.length, bb);
- fail("IndexOutOfBoundsException wasn't thrown");
- } catch (IndexOutOfBoundsException iobe) {
- //expected
- }
- try {
- sse.wrap(bbA, 0, bbA.length + 1, bb);
- fail("IndexOutOfBoundsException wasn't thrown");
- } catch (IndexOutOfBoundsException iobe) {
- //expected
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
- * int length, ByteBuffer dst)
- * Exception case: ReadOnlyBufferException should be thrown.
- */
- public void test_wrap_03() throws SSLException {
- String host = "new host";
- int port = 8080;
- ByteBuffer bb = ByteBuffer.allocate(10).asReadOnlyBuffer();
- ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.wrap(bbA, 0, bbA.length, bb);
- fail("ReadOnlyBufferException wasn't thrown");
- } catch (ReadOnlyBufferException iobe) {
- //expected
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
- * int length, ByteBuffer dst)
- * Exception case: IllegalArgumentException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_wrap_04() {
- String host = "new host";
- int port = 8080;
- ByteBuffer[] bbA = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100)};
- ByteBuffer[] bbN = null;
- ByteBuffer bN = null;
- SSLEngine e = getEngine(host, port);
- e.setUseClientMode(true);
-
- try {
- e.wrap(bbA, 0, 3, bN);
- fail("IllegalArgumentException must be thrown for null srcs byte buffer array");
- } catch (NullPointerException npe) {
- } catch (IllegalArgumentException ex) {
- } catch (Exception ex) {
- fail(ex + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- e.wrap(bbN, 0, 0, bN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException ex) {
- } catch (NullPointerException npe) {
- } catch (Exception ex) {
- fail(ex + " was thrown instead of IllegalArgumentException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
- * int length, ByteBuffer dst)
- * Exception case: IllegalStateException should be thrown.
- */
- @AndroidOnly("The RI doesn't throw the IllegalStateException.")
- public void test_wrap_05() throws SSLException {
- String host = "new host";
- int port = 8080;
- ByteBuffer bb = ByteBuffer.allocate(10);
- ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
- SSLEngine sse = getEngine(host, port);
-
- try {
- sse.wrap(bbA, 0, bbA.length, bb);
- fail("IllegalStateException wasn't thrown");
- } catch (IllegalStateException iobe) {
- //expected
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, int offset,
- * int length, ByteBuffer dst)
- */
- public void test_wrap_06() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bb = ByteBuffer.allocate(10);
- ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.wrap(bbA, 0, bbA.length, bb);
- } catch (Exception ex) {
- fail("Unexpected exception: " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#closeOutbound()
- * javax.net.ssl.SSLEngine#isOutboundDone()
- */
- public void test_closeOutbound() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
-
- try {
- assertFalse(sse.isOutboundDone());
- sse.closeOutbound();
- assertTrue(sse.isOutboundDone());
- } catch (Exception ex) {
- fail("Unexpected exception: " + ex);
- }
- }
-
- /**
- * @throws NoSuchAlgorithmException
- * javax.net.ssl.SSLEngine#closeInbound()
- * javax.net.ssl.SSLEngine#isInboundDone()
- */
- public void test_closeInbound() throws NoSuchAlgorithmException {
- SSLEngine sse = getEngine();
-
- try {
- assertFalse(sse.isInboundDone());
- sse.closeInbound();
- assertTrue(sse.isInboundDone());
- } catch (Exception ex) {
- fail("Unexpected exception: " + ex);
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
- * SSLException should be thrown.
- */
- public void test_unwrap_ByteBuffer_ByteBuffer_01() throws InterruptedException, IOException {
- prepareEngines();
- doHandshake();
- ByteBuffer bbs = ByteBuffer.allocate(100);
- ByteBuffer bbd = ByteBuffer.allocate(100);
-
- try {
- SSLEngineResult unwrap = clientEngine.engine.unwrap(bbs, bbd);
- fail("SSLException wasn't thrown");
- } catch (SSLException ex) {
- //expected
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
- * ReadOnlyBufferException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_unwrap_ByteBuffer_ByteBuffer_02() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer bbd = ByteBuffer.allocate(100).asReadOnlyBuffer();
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.unwrap(bbs, bbd);
- fail("ReadOnlyBufferException wasn't thrown");
- } catch (ReadOnlyBufferException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of ReadOnlyBufferException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
- * IllegalArgumentException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_unwrap_ByteBuffer_ByteBuffer_03() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbsN = null;
- ByteBuffer bbdN = null;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer bbd = ByteBuffer.allocate(100);
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.unwrap(bbsN, bbd);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.unwrap(bbs, bbdN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.unwrap(bbsN, bbdN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
- * IllegalStateException should be thrown.
- */
- @AndroidOnly("The RI doesn't throw the IllegalStateException.")
- public void test_unwrap_ByteBuffer_ByteBuffer_04() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer bbd = ByteBuffer.allocate(100);
- SSLEngine sse = getEngine(host, port);
-
- try {
- sse.unwrap(bbs, bbd);
- fail("IllegalStateException wasn't thrown");
- } catch (IllegalStateException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalStateException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer dst)
- */
- public void test_unwrap_ByteBuffer_ByteBuffer_05() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer bbd = ByteBuffer.allocate(100);
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- SSLEngineResult res = sse.unwrap(bbs, bbd);
- assertEquals(0, res.bytesConsumed());
- assertEquals(0, res.bytesProduced());
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
- * SSLException should be thrown.
- */
- public void test_unwrap_ByteBuffer$ByteBuffer_01() throws IOException, InterruptedException {
- prepareEngines();
- doHandshake();
-
- ByteBuffer bbs = ByteBuffer.allocate(100);
- ByteBuffer bbd = ByteBuffer.allocate(100);
-
- try {
- clientEngine.engine.unwrap(bbs, new ByteBuffer[] { bbd });
- fail("SSLException wasn't thrown");
- } catch (SSLException ex) {
- //expected
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
- * ReadOnlyBufferException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_unwrap_ByteBuffer$ByteBuffer_02() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer bbR = ByteBuffer.allocate(100).asReadOnlyBuffer();
- ByteBuffer[] bbA = { bbR, ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.unwrap(bbs, bbA);
- fail("ReadOnlyBufferException wasn't thrown");
- } catch (ReadOnlyBufferException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of ReadOnlyBufferException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
- * IllegalArgumentException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_unwrap_ByteBuffer$ByteBuffer_03() {
- String host = "new host";
- int port = 8080;
- ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
- ByteBuffer[] bbN = { ByteBuffer.allocate(100), null, ByteBuffer.allocate(100) };
- ByteBuffer[] bbAN = null;
- ByteBuffer bb = ByteBuffer.allocate(10);
- ByteBuffer bN = null;
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.unwrap(bN, bbA);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.unwrap(bb, bbAN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.unwrap(bb, bbN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.unwrap(bN, bbAN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
- * IllegalStateException should be thrown.
- */
- @AndroidOnly("The RI doesn't throw the IllegalStateException.")
- public void test_unwrap_ByteBuffer$ByteBuffer_04() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer[] bbd = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
- SSLEngine sse = getEngine(host, port);
-
- try {
- sse.unwrap(bbs, bbd);
- fail("IllegalStateException wasn't thrown");
- } catch (IllegalStateException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalStateException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#unwrap(ByteBuffer src, ByteBuffer[] dsts)
- */
- public void test_unwrap_ByteBuffer$ByteBuffer_05() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer[] bbd = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- SSLEngineResult res = sse.unwrap(bbs, bbd);
- assertEquals(0, res.bytesConsumed());
- assertEquals(0, res.bytesProduced());
- } catch (Exception ex) {
- fail("Unexpected exception: " + ex);
- }
- }
-
- public void test_wrap_ByteBuffer_ByteBuffer_01() throws IOException, InterruptedException {
- prepareEngines();
- doHandshake();
- ByteBuffer bbs = ByteBuffer.allocate(20);
- ByteBuffer bbd = ByteBuffer.allocate(20000);
- clientEngine.engine.wrap(bbs, bbd);
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer src, ByteBuffer dst)
- * ReadOnlyBufferException should be thrown.
- */
- public void test_wrap_ByteBuffer_ByteBuffer_02() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer bbd = ByteBuffer.allocate(100).asReadOnlyBuffer();
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.wrap(bbs, bbd);
- fail("ReadOnlyBufferException wasn't thrown");
- } catch (ReadOnlyBufferException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of ReadOnlyBufferException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer src, ByteBuffer dst)
- * IllegalArgumentException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_wrap_ByteBuffer_ByteBuffer_03() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbsN = null;
- ByteBuffer bbdN = null;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer bbd = ByteBuffer.allocate(100);
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.wrap(bbsN, bbd);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.wrap(bbs, bbdN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.wrap(bbsN, bbdN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer src, ByteBuffer dst)
- * IllegalStateException should be thrown.
- */
- @AndroidOnly("The RI doesn't throw the IllegalStateException.")
- public void test_wrap_ByteBuffer_ByteBuffer_04() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bbs = ByteBuffer.allocate(10);
- ByteBuffer bbd = ByteBuffer.allocate(10);
- SSLEngine sse = getEngine(host, port);
-
- try {
- sse.wrap(bbs, bbd);
- fail("IllegalStateException wasn't thrown");
- } catch (IllegalStateException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalStateException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer src, ByteBuffer dst)
- */
- public void test_wrap_ByteBuffer_ByteBuffer_05() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bb = ByteBuffer.allocate(10);
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- SSLEngineResult res = sse.wrap(bb, ByteBuffer.allocate(10));
- assertEquals(0, res.bytesConsumed());
- assertEquals(0, res.bytesProduced());
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- /**
- * @throws IOException
- * @throws InterruptedException
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
- * SSLException should be thrown.
- */
- public void test_wrap_ByteBuffer$ByteBuffer_01() throws IOException, InterruptedException {
- prepareEngines();
- doHandshake();
- ByteBuffer bbs = ByteBuffer.allocate(100);
- ByteBuffer bbd = ByteBuffer.allocate(20000);
-
- try {
- clientEngine.engine.wrap(new ByteBuffer[] { bbs }, bbd);
- serverEngine.engine.wrap(new ByteBuffer[] { bbs }, bbd);
- //fail("SSLException wasn't thrown");
- } catch (SSLException ex) {
- //expected
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
- * ReadOnlyBufferException should be thrown.
- */
- public void test_wrap_ByteBuffer$ByteBuffer_02() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bb = ByteBuffer.allocate(10).asReadOnlyBuffer();
- ByteBuffer[] bbA = {ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5)};
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.wrap(bbA, bb);
- fail("ReadOnlyBufferException wasn't thrown");
- } catch (ReadOnlyBufferException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of ReadOnlyBufferException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
- * IllegalArgumentException should be thrown.
- */
- @KnownFailure("Fixed on DonutBurger, Wrong Exception thrown")
- public void test_wrap_ByteBuffer$ByteBuffer_03() {
- String host = "new host";
- int port = 8080;
- ByteBuffer[] bbA = {ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100)};
- ByteBuffer[] bbAN = null;
- ByteBuffer bb = ByteBuffer.allocate(10);
- ByteBuffer bN = null;
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- sse.wrap(bbA, bN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.wrap(bbAN, bb);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- try {
- sse.wrap(bbAN, bN);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iobe) {
- //expected
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
- * IllegalStateException should be thrown.
- */
- @AndroidOnly("The RI doesn't throw the IllegalStateException.")
- public void test_wrap_ByteBuffer$ByteBuffer_04() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bb = ByteBuffer.allocate(10);
- ByteBuffer[] bbA = { ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5) };
- SSLEngine sse = getEngine(host, port);
-
- try {
- sse.wrap(bbA, bb);
- fail("IllegalStateException wasn't thrown");
- } catch (IllegalStateException iobe) {
- //expected
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalStateException");
- }
- }
-
- /**
- * javax.net.ssl.SSLEngine#wrap(ByteBuffer[] srcs, ByteBuffer dst)
- */
- public void test_wrap_ByteBuffer$ByteBuffer_05() {
- String host = "new host";
- int port = 8080;
- ByteBuffer bb = ByteBuffer.allocate(10);
- ByteBuffer[] bbA = { ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5) };
- SSLEngine sse = getEngine(host, port);
- sse.setUseClientMode(true);
-
- try {
- SSLEngineResult res = sse.wrap(bbA, bb);
- assertEquals(0, res.bytesConsumed());
- assertEquals(0, res.bytesProduced());
- } catch (Exception ex) {
- fail("Unexpected exception: " + ex);
- }
- }
-
- private SSLEngine getEngine() {
- SSLContext context = null;
- try {
- context = SSLContext.getInstance("TLS");
- context.init(null, null, null);
- } catch (KeyManagementException e) {
- fail("Could not get SSLEngine: key management exception "
- + e.getMessage());
- } catch (NoSuchAlgorithmException e) {
- fail("Could not get SSLEngine: no such algorithm " + e.getMessage());
- }
- return context.createSSLEngine();
- }
-
- private SSLEngine getEngine(String host, int port) {
- SSLContext context = null;
- try {
- context = SSLContext.getInstance("TLS");
- context.init(null, null, null);
- } catch (KeyManagementException e) {
- fail("Could not get SSLEngine: key management exception "
- + e.getMessage());
- } catch (NoSuchAlgorithmException e) {
- fail("Could not get SSLEngine: no such algorithm " + e.getMessage());
- }
- return context.createSSLEngine(host, port);
- }
-
- class HandshakeHandler implements Runnable {
-
- private final SSLEngine engine;
-
- private final SourceChannel in;
-
- private final SinkChannel out;
-
- private final ByteBuffer EMPTY = ByteBuffer.allocate(0);
-
- @SuppressWarnings("unused")
- private final String LOGTAG;
-
- private SSLEngineResult.HandshakeStatus status;
-
- private ByteBuffer readBuffer;
-
- private ByteBuffer writeBuffer;
-
- HandshakeHandler(boolean clientMode, SourceChannel in, SinkChannel out)
- throws SSLException {
- this.in = in;
- this.out = out;
- engine = getEngine();
- engine.setUseClientMode(clientMode);
- String[] cipherSuites = engine.getSupportedCipherSuites();
- Set<String> enabledSuites = new HashSet<String>();
- for (String cipherSuite : cipherSuites) {
- if (cipherSuite.contains("anon")) {
- enabledSuites.add(cipherSuite);
- }
- }
- engine.setEnabledCipherSuites((String[]) enabledSuites.toArray(
- new String[enabledSuites.size()]));
-
- engine.beginHandshake();
- status = engine.getHandshakeStatus();
-
- if (clientMode) {
- LOGTAG = "CLIENT: ";
- } else {
- LOGTAG = "SERVER: ";
- }
-
- log("CipherSuites: " + Arrays.toString(engine.getEnabledCipherSuites()));
- log(status);
-
- readBuffer = ByteBuffer.allocate(200000);
- writeBuffer = ByteBuffer.allocate(20000);
- }
-
- public SSLEngineResult.HandshakeStatus getStatus() {
- return status;
- }
-
- private void log(Object o) {
- //System.out.print(LOGTAG);
- //System.out.println(o);
- }
-
- private ByteBuffer read() throws IOException {
- if (readBuffer == null || readBuffer.remaining() == 0 || readBuffer.position() == 0) {
- readBuffer.clear();
- int read = in.read(readBuffer);
- log("read: " + read);
- readBuffer.rewind();
- readBuffer.limit(read);
- }
- return readBuffer;
- }
-
- public void run() {
- try {
- while (true) {
- switch (status) {
- case FINISHED: {
- log(status);
- return;
- }
- case NEED_TASK: {
- log(status);
- Runnable task;
- while ((task = engine.getDelegatedTask()) != null) {
- task.run();
- }
- status = engine.getHandshakeStatus();
- break;
- }
- case NEED_UNWRAP: {
- log(status);
- ByteBuffer source = read();
- writeBuffer.clear();
-
- while (status == HandshakeStatus.NEED_UNWRAP) {
- SSLEngineResult result = engine.unwrap(source, writeBuffer);
- status = result.getHandshakeStatus();
- log(result);
- }
- break;
- }
- case NEED_WRAP: {
- log(status);
- writeBuffer.clear();
-
- int produced = 0;
- SSLEngineResult result = null;
- while (status == HandshakeStatus.NEED_WRAP) {
- result = engine.wrap(EMPTY, writeBuffer);
- status = result.getHandshakeStatus();
- produced += result.bytesProduced();
- log(result);
- }
- writeBuffer.rewind();
- writeBuffer.limit(produced);
- log("write: " + produced);
- out.write(writeBuffer);
- break;
- }
- case NOT_HANDSHAKING: {
- log("Not Handshaking");
- return;
- }
- }
- }
- } catch (IOException e) {
- log(e);
- } catch (RuntimeException e) {
- // ignore;
- }
- }
- }
-
- @KnownFailure("Handshake Status is never finished. NPE in "
- + "ClientSessionContext$HostAndPort.hashCode() when host is null")
- public void testHandshake() throws IOException, InterruptedException {
-
- prepareEngines();
-
- assertTrue("handshake failed", doHandshake());
-
- System.out.println(clientEngine.engine.getSession().getCipherSuite());
-
- assertEquals("Handshake not finished",
- SSLEngineResult.HandshakeStatus.FINISHED,
- clientEngine.getStatus());
- assertEquals("Handshake not finished",
- SSLEngineResult.HandshakeStatus.FINISHED,
- serverEngine.getStatus());
- }
-
- void prepareEngines() throws IOException {
- Pipe clientSendPipe = Pipe.open();
- Pipe serverSendPipe = Pipe.open();
-
- SinkChannel clientSink = clientSendPipe.sink();
- SourceChannel serverSource = clientSendPipe.source();
- SinkChannel serverSink = serverSendPipe.sink();
- SourceChannel clientSource = serverSendPipe.source();
-
- clientEngine = new HandshakeHandler(true, clientSource, clientSink);
- serverEngine = new HandshakeHandler(false, serverSource, serverSink);
- }
-
- boolean doHandshake() throws InterruptedException {
- Thread clientThread = new Thread(clientEngine);
- clientThread.start();
-
- Thread serverThread = new Thread(serverEngine);
- serverThread.start();
-
- int i = 0;
- while (clientThread.isAlive() && serverThread.isAlive() && i < 20) {
- Thread.sleep(500);
- i++;
- }
-
- if (clientThread.isAlive()) {
- clientThread.interrupt();
- }
-
- if (serverThread.isAlive()) {
- serverThread.interrupt();
- }
-
- return clientEngine.getStatus() == HandshakeStatus.FINISHED && serverEngine.getStatus() == HandshakeStatus.FINISHED;
- }
-
-}
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
deleted file mode 100644
index 5084422..0000000
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.net.ssl;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.security.KeyStore;
-import java.security.Principal;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionBindingEvent;
-import javax.net.ssl.SSLSessionBindingListener;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.TrustManager;
-import junit.framework.TestCase;
-import libcore.io.Base64;
-import tests.api.javax.net.ssl.HandshakeCompletedEventTest.MyHandshakeListener;
-import tests.api.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager;
-
-public class SSLSessionTest extends TestCase {
-
- // set to true if on Android, false if on RI
- boolean useBKS = true;
-
- /**
- * javax.net.ssl.SSLSession#getPeerHost()
- * javax.net.ssl.SSLSession#getPeerPort()
- */
- public void test_getPeerHost() throws Exception {
- SSLSession s = clientSession;
- assertEquals(InetAddress.getLocalHost().getHostName(), s.getPeerHost());
- assertEquals(serverSocket.getLocalPort(), s.getPeerPort());
- }
-
- /**
- * javax.net.ssl.SSLSession#invalidate()
- * javax.net.ssl.SSLSession#isValid()
- */
- public void test_invalidate() {
- SSLSession s = clientSession;
- assertTrue(s.isValid());
- s.invalidate();
- assertFalse(s.isValid());
- }
-
- /**
- * javax.net.ssl.SSLSession#getPeerPrincipal()
- */
- public void test_getPeerPrincipal() throws Exception {
- Principal p1 = clientSession.getPeerPrincipal();
- KeyStore store = server.getStore();
- X509Certificate cert = (X509Certificate)store.getCertificate("mykey");
- Principal p2 = cert.getSubjectX500Principal();
- assertEquals(p1, p2);
- }
-
- /**
- * javax.net.ssl.SSLSession#getApplicationBufferSize()
- */
- public void test_getApplicationBufferSize() {
- assertTrue(clientSession.getApplicationBufferSize() > 0);
- }
-
- /**
- * javax.net.ssl.SSLSession#getCipherSuite()
- */
- public void test_getCipherSuite() {
- assertEquals(CIPHER_SUITE, clientSession.getCipherSuite());
- }
-
- /**
- * javax.net.ssl.SSLSession#getCreationTime()
- */
- public void test_getCreationTime() {
- // check if creation time was in the last 10 seconds
- long currentTime = System.currentTimeMillis();
- long sessionTime = clientSession.getCreationTime();
- long diff = currentTime - sessionTime;
- assertTrue("diff between " + currentTime + " and " + sessionTime + " should be < 10000",
- diff < 10000);
- }
-
- /**
- * javax.net.ssl.SSLSession#getId()
- */
- public void test_getId() {
- byte[] id = clientSession.getId();
- SSLSession sess = clientSslContext.getClientSessionContext().getSession(id);
- assertNotNull("Could not find session for id " + id, sess);
- assertEquals(clientSession, sess);
- }
-
- /**
- * javax.net.ssl.SSLSession#getLastAccessedTime()
- */
- public void test_getLastAccessedTime() {
- // check if last access time was in the last 10 seconds
- long currentTime = System.currentTimeMillis();
- long sessionTime = clientSession.getLastAccessedTime();
- long diff = currentTime - sessionTime;
- assertTrue("diff between " + currentTime + " and " + sessionTime + " should be < 10000",
- diff < 10000);
- assertTrue ("diff should be < 10000 but is " + diff, diff < 10000);
- }
-
- /**
- * javax.net.ssl.SSLSession#getLocalCertificates()
- */
- public void test_getLocalCertificates() throws Exception {
- KeyStore store = client.getStore();
- Certificate cert = store.getCertificate("mykey");
- Certificate[] certs = clientSession.getLocalCertificates();
- assertEquals(cert, certs[0]);
- }
-
- /**
- * javax.net.ssl.SSLSession#getLocalPrincipal()
- */
- public void test_getLocalPrincipal() throws Exception {
- Principal p1 = clientSession.getLocalPrincipal();
- KeyStore store = client.getStore();
- X509Certificate cert = (X509Certificate)store.getCertificate("mykey");
- Principal p2 = cert.getSubjectX500Principal();
- assertEquals(p1, p2);
- }
-
- /**
- * javax.net.ssl.SSLSession#getPacketBufferSize()
- */
- public void test_getPacketBufferSize() {
- assertTrue(clientSession.getPacketBufferSize() > 0);
- }
-
- /**
- * javax.net.ssl.SSLSession#getPeerCertificates()
- */
- public void test_getPeerCertificates() throws Exception {
- Certificate[] res = clientSession.getPeerCertificates();
- assertTrue(res.length > 0);
- }
-
- /**
- * javax.net.ssl.SSLSession#getPeerCertificateChain()
- */
- public void test_getPeerCertificateChain() throws Exception {
- javax.security.cert.X509Certificate[] res = clientSession.getPeerCertificateChain();
- assertTrue(res.length > 0);
- }
-
- /**
- * javax.net.ssl.SSLSession#getProtocol()
- */
- public void test_getProtocol() {
- assertEquals("TLSv1", clientSession.getProtocol());
- }
-
- /**
- * javax.net.ssl.SSLSession#getSessionContext()
- */
- public void test_getSessionContext() {
- assertEquals(clientSession.getSessionContext(),
- clientSslContext.getClientSessionContext());
- }
-
- /**
- * javax.net.ssl.SSLSession#putValue(String name, Object value)
- * javax.net.ssl.SSLSession#removeValue(String name)
- * javax.net.ssl.SSLSession#getValueNames()
- */
- public void test_putValue() {
- SSLSession s = clientSession;
- mySSLSessionBindingListener sbl = new mySSLSessionBindingListener();
- assertNotNull(s.getValueNames());
- assertEquals(0, s.getValueNames().length);
- s.putValue("Name_01", sbl);
- s.putValue("Name_02", sbl);
- s.putValue("Name_03", sbl);
- assertEquals(3, s.getValueNames().length);
- s.removeValue("Name_01");
- assertEquals(2, s.getValueNames().length);
-
- try {
- s.putValue(null, null);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- try {
- s.putValue("ABC", null);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- try {
- s.putValue(null, sbl);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException expected) {
- // expected
- }
-
- try {
- s.removeValue(null);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- /**
- * javax.net.ssl.SSLSession#getValue(String name)
- */
- public void test_getValue() {
- SSLSession s = clientSession;
- mySSLSessionBindingListener sbl = new mySSLSessionBindingListener();
-
- try {
- s.getValue(null);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException expected) {
- // expected
- }
-
- s.putValue("Name", sbl);
- Object obj = s.getValue("Name");
- assertTrue(obj instanceof SSLSessionBindingListener);
- }
-
- Thread serverThread, clientThread;
- TestServer server;
- TestClient client;
-
- @Override
- protected void setUp() throws Exception {
- String serverKeys = (useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS);
- String clientKeys = (useBKS ? CLIENT_KEYS_BKS : CLIENT_KEYS_JKS);
- server = new TestServer(true, TestServer.CLIENT_AUTH_WANTED, serverKeys);
- client = new TestClient(true, clientKeys);
-
- serverThread = new Thread(server);
- clientThread = new Thread(client);
-
- serverThread.start();
- try {
- Thread.currentThread().sleep(1000);
- clientThread.start();
- } catch (InterruptedException e) {
- fail("Could not create server or cient " + e.getMessage());
- }
- while (clientSession == null
- && server.exception == null
- && client.exception == null) {
- try {
- Thread.currentThread().sleep(500);
- } catch (InterruptedException e) {
- fail("couldn't create session");
- }
- }
- if (server.exception != null) {
- server.exception.printStackTrace();
- }
- assertNull("server thread has a pending exception: " + server.exception,
- server.exception);
- if (client.exception != null) {
- client.exception.printStackTrace();
- }
- assertNull("client thread has a pending exception: " + client.exception,
- client.exception);
- assertNotNull("Could not initialize session", clientSession);
- }
-
- @Override
- protected void tearDown() {
- notFinished = false;
- try {
- serverThread.join();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- try {
- clientThread.join();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
-
- // The server must have completed without an exception.
- if (server.getException() != null) {
- throw new RuntimeException(server.getException());
- }
-
- // The client must have completed without an exception.
- if (client.getException() != null) {
- throw new RuntimeException(client.getException());
- }
- }
-
- public class mySSLSessionBindingListener implements
- SSLSessionBindingListener {
- mySSLSessionBindingListener() {
- }
- public void valueBound(SSLSessionBindingEvent event) {}
- public void valueUnbound(SSLSessionBindingEvent event) {}
- }
-
- /**
- * Defines the keystore contents for the server, BKS version. Holds just a
- * single self-generated key. The subject name is "Test Server".
- */
- private static final String SERVER_KEYS_BKS =
- "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41"
- + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET"
- + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV"
- + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw"
- + "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U"
- + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl"
- + "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy"
- + "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV"
- + "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG"
- + "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU"
- + "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV"
- + "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx"
- + "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR"
- + "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN"
- + "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs"
- + "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck"
- + "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM"
- + "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI"
- + "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f"
- + "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx"
- + "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt"
- + "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw"
- + "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl"
- + "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw=";
-
- /**
- * Defines the keystore contents for the client, BKS version. Holds just a
- * single self-generated key. The subject name is "Test Client".
- */
- private static final String CLIENT_KEYS_BKS =
- "AAAAAQAAABT4Rka6fxbFps98Y5k2VilmbibNkQAABfQEAAVteWtleQAAARpYl+POAAAAAQAFWC41"
- + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU9TANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET"
- + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV"
- + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgQ2xpZW50MB4XDTA4MDYwNTExNTg0NVoXDTA4MDkw"
- + "MzExNTg0NVowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U"
- + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVu"
- + "dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApUvmWsQDHPpbDKK13Yez2/q54tTOmRml/qva"
- + "2K6dZjkjSTW0iRuk7ztaVEvdJpfVIDv1oBsCI51ttyLHROy1epjF+GoL74mJb7fkcd0VOoSOTjtD"
- + "+3GgZkHPAm5YmUYxiJXqxKKJJqMCTIW46eJaA2nAep9QIwZ14/NFAs4ObV8CAwEAATANBgkqhkiG"
- + "9w0BAQUFAAOBgQCJrCr3hZQFDlLIfsSKI1/w+BLvyf4fubOid0pBxfklR8KBNPTiqjSmu7pd/C/F"
- + "1FR8CdZUDoPflZHCOU+fj5r5KUC1HyigY/tEUvlforBpfB0uCF+tXW4DbUfOWhfMtLV4nCOJOOZg"
- + "awfZLJWBJouLKOp427vDftxTSB+Ks8YjlgAAAqwAAAAU+NH6TtrzjyDdCXm5B6Vo7xX5G4YAAAZx"
- + "EAUkcZtmykn7YdaYxC1jRFJ+GEJpC8nZVg83QClVuCSIS8a5f8Hl44Bk4oepOZsPzhtz3RdVzDVi"
- + "RFfoyZFsrk9F5bDTVJ6sQbb/1nfJkLhZFXokka0vND5AXMSoD5Bj1Fqem3cK7fSUyqKvFoRKC3XD"
- + "FQvhqoam29F1rbl8FaYdPvhhZo8TfZQYUyUKwW+RbR44M5iHPx+ykieMe/C/4bcM3z8cwIbYI1aO"
- + "gjQKS2MK9bs17xaDzeAh4sBKrskFGrDe+2dgvrSKdoakJhLTNTBSG6m+rzqMSCeQpafLKMSjTSSz"
- + "+KoQ9bLyax8cbvViGGju0SlVhquloZmKOfHr8TukIoV64h3uCGFOVFtQjCYDOq6NbfRvMh14UVF5"
- + "zgDIGczoD9dMoULWxBmniGSntoNgZM+QP6Id7DBasZGKfrHIAw3lHBqcvB5smemSu7F4itRoa3D8"
- + "N7hhUEKAc+xA+8NKmXfiCBoHfPHTwDvt4IR7gWjeP3Xv5vitcKQ/MAfO5RwfzkYCXQ3FfjfzmsE1"
- + "1IfLRDiBj+lhQSulhRVStKI88Che3M4JUNGKllrc0nt1pWa1vgzmUhhC4LSdm6trTHgyJnB6OcS9"
- + "t2furYjK88j1AuB4921oxMxRm8c4Crq8Pyuf+n3YKi8Pl2BzBtw++0gj0ODlgwut8SrVj66/nvIB"
- + "jN3kLVahR8nZrEFF6vTTmyXi761pzq9yOVqI57wJGx8o3Ygox1p+pWUPl1hQR7rrhUbgK/Q5wno9"
- + "uJk07h3IZnNxE+/IKgeMTP/H4+jmyT4mhsexJ2BFHeiKF1KT/FMcJdSi+ZK5yoNVcYuY8aZbx0Ef"
- + "lHorCXAmLFB0W6Cz4KPP01nD9YBB4olxiK1t7m0AU9zscdivNiuUaB5OIEr+JuZ6dNw=";
-
- private static final String CIPHER_SUITE = "SSL_RSA_WITH_RC4_128_MD5";
- /**
- * Defines the keystore contents for the server, JKS version. Holds just a
- * single self-generated key. The subject name is "Test Server".
- */
- private static final String SERVER_KEYS_JKS =
- "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFfBeAAAArowggK2MA4GCisGAQQBKgIRAQEFAASC"
- + "AqI2kp5XjnF8YZkhcF92YsJNQkvsmH7zqMM87j23zSoV4DwyE3XeC/gZWq1ToScIhoqZkzlbWcu4"
- + "T/Zfc/DrfGk/rKbBL1uWKGZ8fMtlZk8KoAhxZk1JSyJvdkyKxqmzUbxk1OFMlN2VJNu97FPVH+du"
- + "dvjTvmpdoM81INWBW/1fZJeQeDvn4mMbbe0IxgpiLnI9WSevlaDP/sm1X3iO9yEyzHLL+M5Erspo"
- + "Cwa558fOu5DdsICMXhvDQxjWFKFhPHnKtGe+VvwkG9/bAaDgx3kfhk0w5zvdnkKb+8Ed9ylNRzdk"
- + "ocAa/mxlMTOsTvDKXjjsBupNPIIj7OP4GNnZaxkJjSs98pEO67op1GX2qhy6FSOPNuq8k/65HzUc"
- + "PYn6voEeh6vm02U/sjEnzRevQ2+2wXoAdp0EwtQ/DlMe+NvcwPGWKuMgX4A4L93DZGb04N2VmAU3"
- + "YLOtZwTO0LbuWrcCM/q99G/7LcczkxIVrO2I/rh8RXVczlf9QzcrFObFv4ATuspWJ8xG7DhsMbnk"
- + "rT94Pq6TogYeoz8o8ZMykesAqN6mt/9+ToIemmXv+e+KU1hI5oLwWMnUG6dXM6hIvrULY6o+QCPH"
- + "172YQJMa+68HAeS+itBTAF4Clm/bLn6reHCGGU6vNdwU0lYldpiOj9cB3t+u2UuLo6tiFWjLf5Zs"
- + "EQJETd4g/EK9nHxJn0GAKrWnTw7pEHQJ08elzUuy04C/jEEG+4QXU1InzS4o/kR0Sqz2WTGDoSoq"
- + "ewuPRU5bzQs/b9daq3mXrnPtRBL6HfSDAdpTK76iHqLCGdqx3avHjVSBm4zFvEuYBCev+3iKOBmg"
- + "yh7eQRTjz4UOWfy85omMBr7lK8PtfVBDzOXpasxS0uBgdUyBDX4tO6k9jZ8a1kmQRQAAAAEABVgu"
- + "NTA5AAACSDCCAkQwggGtAgRIR8SKMA0GCSqGSIb3DQEBBAUAMGkxCzAJBgNVBAYTAlVTMRMwEQYD"
- + "VQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMH"
- + "QW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBTZXJ2ZXIwHhcNMDgwNjA1MTA0ODQyWhcNMDgwOTAzMTA0"
- + "ODQyWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8w"
- + "DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGf"
- + "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoC6chqCI84rj1PrXuJgbiit4EV909zR6N0jNlYfg"
- + "itwB39bP39wH03rFm8T59b3mbSptnGmCIpLZn25KPPFsYD3JJ+wFlmiUdEP9H05flfwtFQJnw9uT"
- + "3rRIdYVMPcQ3RoZzwAMliGr882I2thIDbA6xjGU/1nRIdvk0LtxH3QIDAQABMA0GCSqGSIb3DQEB"
- + "BAUAA4GBAJn+6YgUlY18Ie+0+Vt8oEi81DNi/bfPrAUAh63fhhBikx/3R9dl3wh09Z6p7cIdNxjW"
- + "n2ll+cRW9eqF7z75F0Omm0C7/KAEPjukVbszmzeU5VqzkpSt0j84YWi+TfcHRrfvhLbrlmGITVpY"
- + "ol5pHLDyqGmDs53pgwipWqsn/nEXEBgj3EoqPeqHbDf7YaP8h/5BSt0=";
-
- /**
- * Defines the keystore contents for the client, JKS version. Holds just a
- * single self-generated key. The subject name is "Test Client".
- */
- private static final String CLIENT_KEYS_JKS =
- "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFhyMAAAArkwggK1MA4GCisGAQQBKgIRAQEFAASC"
- + "AqGVSfXolBStZy4nnRNn4fAr+S7kfU2BS23wwW8uB2Ru3GvtLzlK9q08Gvq/LNqBafjyFTVL5FV5"
- + "SED/8YomO5a98GpskSeRvytCiTBLJdgGhws5TOGekgIAcBROPGIyOtJPQ0HfOQs+BqgzGDHzHQhw"
- + "u/8Tm6yQwiP+W/1I9B1QnaEztZA3mhTyMMJsmsFTYroGgAog885D5Cmzd8sYGfxec3R6I+xcmBAY"
- + "eibR5kGpWwt1R+qMvRrtBqh5r6WSKhCBNax+SJVbtUNRiKyjKccdJg6fGqIWWeivwYTy0OhjA6b4"
- + "NiZ/ZZs5pxFGWUj/Rlp0RYy8fCF6aw5/5s4Bf4MI6dPSqMG8Hf7sJR91GbcELyzPdM0h5lNavgit"
- + "QPEzKeuDrGxhY1frJThBsNsS0gxeu+OgfJPEb/H4lpYX5IvuIGbWKcxoO9zq4/fimIZkdA8A+3eY"
- + "mfDaowvy65NBVQPJSxaOyFhLHfeLqOeCsVENAea02vA7andZHTZehvcrqyKtm+z8ncHGRC2H9H8O"
- + "jKwKHfxxrYY/jMAKLl00+PBb3kspO+BHI2EcQnQuMw/zr83OR9Meq4TJ0TMuNkApZELAeFckIBbS"
- + "rBr8NNjAIfjuCTuKHhsTFWiHfk9ZIzigxXagfeDRiyVc6khOuF/bGorj23N2o7Rf3uLoU6PyXWi4"
- + "uhctR1aL6NzxDoK2PbYCeA9hxbDv8emaVPIzlVwpPK3Ruvv9mkjcOhZ74J8bPK2fQmbplbOljcZi"
- + "tZijOfzcO/11JrwhuJZRA6wanTqHoujgChV9EukVrmbWGGAcewFnAsSbFXIik7/+QznXaDIt5NgL"
- + "H/Bcz4Z/fdV7Ae1eUaxKXdPbI//4J+8liVT/d8awjW2tldIaDlmGMR3aoc830+3mAAAAAQAFWC41"
- + "MDkAAAJIMIICRDCCAa0CBEhHxLgwDQYJKoZIhvcNAQEEBQAwaTELMAkGA1UEBhMCVVMxEzARBgNV"
- + "BAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01UVjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdB"
- + "bmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVudDAeFw0wODA2MDUxMDQ5MjhaFw0wODA5MDMxMDQ5"
- + "MjhaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzAN"
- + "BgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBDbGllbnQwgZ8w"
- + "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIK3Q+KiFbmCGg422TAo4gggdhMH6FJhiuz8DxRyeMKR"
- + "UAfP4MK0wtc8N42waZ6OKvxpBFUy0BRfBsX0GD4Ku99yu9/tavSigTraeJtwV3WWRRjIqk7L3wX5"
- + "cmgS2KSD43Y0rNUKrko26lnt9N4qiYRBSj+tcAN3Lx9+ptqk1LApAgMBAAEwDQYJKoZIhvcNAQEE"
- + "BQADgYEANb7Q1GVSuy1RPJ0FmiXoMYCCtvlRLkmJphwxovK0cAQK12Vll+yAzBhHiQHy/RA11mng"
- + "wYudC7u3P8X/tBT8GR1Yk7QW3KgFyPafp3lQBBCraSsfrjKj+dCLig1uBLUr4f68W8VFWZWWTHqp"
- + "NMGpCX6qmjbkJQLVK/Yfo1ePaUexPSOX0G9m8+DoV3iyNw6at01NRw==";
-
-
- SSLServerSocket serverSocket;
- MyHandshakeListener listener;
- String host = "localhost";
- boolean notFinished = true;
- SSLSession clientSession = null;
- SSLContext clientSslContext = null;
- String testData = "PING";
-
- private String PASSWORD = "android";
-
- /**
- * Implements a test SSL socket server. It waits for a connection on a given
- * port, requests client authentication (if specified), reads from the socket,
- * and writes to the socket.
- */
- class TestServer implements Runnable {
-
- public static final int CLIENT_AUTH_NONE = 0;
-
- public static final int CLIENT_AUTH_WANTED = 1;
-
- public static final int CLIENT_AUTH_NEEDED = 2;
-
- private TestTrustManager trustManager;
-
- private Exception exception;
-
- String keys;
-
- private int clientAuth;
-
- private boolean provideKeys;
-
- private KeyStore store;
-
- public TestServer(boolean provideKeys, int clientAuth, String keys) throws Exception {
- this.keys = keys;
- this.clientAuth = clientAuth;
- this.provideKeys = provideKeys;
-
- trustManager = new TestTrustManager();
-
- store = provideKeys ? getKeyStore(keys) : null;
- KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null;
- TrustManager[] trustManagers = new TrustManager[] { trustManager };
-
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(keyManagers, trustManagers, null);
-
- serverSocket = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket();
-
- if (clientAuth == CLIENT_AUTH_WANTED) {
- serverSocket.setWantClientAuth(true);
- } else if (clientAuth == CLIENT_AUTH_NEEDED) {
- serverSocket.setNeedClientAuth(true);
- } else {
- serverSocket.setWantClientAuth(false);
- }
-
- serverSocket.bind(null);
- }
-
- public void run() {
- try {
- SSLSocket clientSocket = (SSLSocket)serverSocket.accept();
-
- InputStream istream = clientSocket.getInputStream();
- byte[] buffer = new byte[1024];
- istream.read(buffer);
-
- OutputStream ostream = clientSocket.getOutputStream();
- ostream.write(testData.getBytes());
- ostream.flush();
-
- while (notFinished) {
- Thread.currentThread().sleep(500);
- }
-
- clientSocket.close();
- serverSocket.close();
-
- } catch (Exception ex) {
- exception = ex;
- }
- }
-
- public Exception getException() {
- return exception;
- }
-
- public javax.security.cert.X509Certificate[] getChain() {
- return trustManager.getChain();
- }
-
- public KeyStore getStore() {
- return store;
- }
-
- }
-
- /**
- * Implements a test SSL socket client. It opens a connection to localhost on
- * a given port, writes to the socket, and reads from the socket.
- */
- class TestClient implements Runnable {
-
- private TestTrustManager trustManager;
-
- private Exception exception;
-
- private String keys;
-
- private boolean provideKeys;
-
- private KeyStore store;
-
- public TestClient(boolean provideKeys, String keys) {
- this.keys = keys;
- this.provideKeys = provideKeys;
-
- trustManager = new TestTrustManager();
- }
-
- public void run() {
- try {
- store = provideKeys ? getKeyStore(keys) : null;
- KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null;
- TrustManager[] trustManagers = new TrustManager[] { trustManager };
-
- clientSslContext = SSLContext.getInstance("TLS");
- clientSslContext.init(keyManagers, trustManagers, null);
-
- SSLSocket socket = (SSLSocket)clientSslContext.getSocketFactory().createSocket();
-
- socket.connect(serverSocket.getLocalSocketAddress());
- OutputStream ostream = socket.getOutputStream();
- ostream.write(testData.getBytes());
- ostream.flush();
-
- InputStream istream = socket.getInputStream();
- byte[] buffer = new byte[1024];
- istream.read(buffer);
-
- clientSession = socket.getSession();
- while (notFinished) {
- Thread.currentThread().sleep(500);
- }
- socket.close();
-
- } catch (Exception ex) {
- exception = ex;
- }
- }
-
- public Exception getException() {
- return exception;
- }
-
- public javax.security.cert.X509Certificate[] getChain() {
- return trustManager.getChain();
- }
-
- public KeyStore getStore() {
- return store;
- }
- }
-
- /**
- * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
- * for the result.
- */
- private KeyStore getKeyStore(String keys) throws Exception {
- byte[] bytes = Base64.decode(keys.getBytes());
- InputStream inputStream = new ByteArrayInputStream(bytes);
-
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- keyStore.load(inputStream, PASSWORD.toCharArray());
- inputStream.close();
- return keyStore;
- }
-
- /**
- * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
- * for the result.
- */
- private KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception {
- String algorithm = KeyManagerFactory.getDefaultAlgorithm();
- KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm);
- keyManagerFactory.init(keyStore, PASSWORD.toCharArray());
-
- return keyManagerFactory.getKeyManagers();
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketFactoryTest.java
deleted file mode 100644
index 0d91116..0000000
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketFactoryTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.javax.net.ssl;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLSocketFactory;
-
-import junit.framework.TestCase;
-
-public class SSLSocketFactoryTest extends TestCase {
-
- private ServerSocket ss;
-
- protected int startServer(String name) {
- try {
- ss = new ServerSocket(0);
- } catch (IOException e) {
- fail(name + ": " + e);
- }
- return ss.getLocalPort();
- }
-
- /**
- * javax.net.ssl.SSLSocketFactory#SSLSocketFactory()
- */
- public void test_Constructor() {
- try {
- SocketFactory sf = SSLSocketFactory.getDefault();
- assertTrue(sf instanceof SSLSocketFactory);
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- /**
- * javax.net.ssl.SSLSocketFactory#getDefault()
- */
- public void test_getDefault() {
- assertNotNull("Incorrect default socket factory",
- SSLSocketFactory.getDefault());
- }
-
- /**
- * javax.net.ssl.SSLSocketFactory#createSocket(Socket s, String host, int port, boolean autoClose)
- */
- public void test_createSocket() {
- SSLSocketFactory sf = (SSLSocketFactory)SSLSocketFactory.getDefault();
- int sport = startServer("test_createSocket()");
- int[] invalid = {
- Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE
- };
- try {
- Socket st = new Socket("localhost", sport);
- Socket s = sf.createSocket(st, "localhost", sport, false);
- assertFalse(s.isClosed());
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- try {
- Socket st = new Socket("localhost", sport);
- Socket s = sf.createSocket(st, "localhost", sport, true);
- s.close();
- assertTrue(st.isClosed());
- } catch (Exception ex) {
- fail("Unexpected exception " + ex);
- }
- try {
- sf.createSocket(null, "localhost", sport, true);
- fail("IOException wasn't thrown");
- } catch (IOException ioe) {
- // expected
- } catch (NullPointerException e) {
- // expected
- }
- for (int i = 0; i < invalid.length; i++) {
- try {
- Socket s = sf.createSocket(new Socket(), "localhost", 1080, false);
- fail("IOException wasn't thrown");
- } catch (IOException ioe) {
- // expected
- }
- }
-
- try {
- Socket st = new Socket("bla-bla", sport);
- Socket s = sf.createSocket(st, "bla-bla", sport, false);
- fail("UnknownHostException wasn't thrown: " + "bla-bla");
- } catch (UnknownHostException uhe) {
- // expected
- } catch (Exception e) {
- fail(e + " was thrown instead of UnknownHostException");
- }
- }
-
- /**
- * javax.net.ssl.SSLSocketFactory#getDefaultCipherSuites()
- */
- public void test_getDefaultCipherSuites() {
- try {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- assertTrue("no default cipher suites returned",
- sf.getDefaultCipherSuites().length > 0);
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
- /**
- * javax.net.ssl.SSLSocketFactory#getSupportedCipherSuites()
- */
- public void test_getSupportedCipherSuites() {
- try {
- SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
- assertTrue("no supported cipher suites returned",
- sf.getSupportedCipherSuites().length > 0);
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
- }
-
-}
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java
deleted file mode 100644
index b4cbde2..0000000
--- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.javax.net.ssl;
-
-import dalvik.annotation.AndroidOnly;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import javax.net.ssl.HandshakeCompletedEvent;
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.security.cert.X509Certificate;
-import junit.framework.TestCase;
-import libcore.io.Base64;
-import tests.api.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager;
-import libcore.java.security.StandardNames;
-
-public class SSLSocketTest extends TestCase {
-
- public class HandshakeCL implements HandshakeCompletedListener {
- public void handshakeCompleted(HandshakeCompletedEvent event) {
- }
- }
-
- /**
- * javax.net.ssl.SSLSocket#SSLSocket()
- */
- public void testConstructor() throws Exception {
- SSLSocket ssl = getSSLSocket();
- assertNotNull(ssl);
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#SSLSocket(InetAddress address, int port)
- */
- public void testConstructor_InetAddressI() throws Exception {
- int sport = startServer("Cons InetAddress,I");
- int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE};
-
- SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost(), sport);
- assertNotNull(ssl);
- assertEquals(sport, ssl.getPort());
- ssl.close();
-
- try {
- getSSLSocket(InetAddress.getLocalHost(), sport + 1);
- fail();
- } catch (IOException expected) {
- }
-
- for (int i = 0; i < invalidPort.length; i++) {
- try {
- getSSLSocket(InetAddress.getLocalHost(), invalidPort[i]);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
- }
-
- /**
- * javax.net.ssl.SSLSocket#SSLSocket(InetAddress address, int port,
- * InetAddress clientAddress, int clientPort)
- */
- public void testConstructor_InetAddressIInetAddressI() throws Exception {
- int sport = startServer("Cons InetAddress,I,InetAddress,I");
-
- SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost(), sport,
- InetAddress.getLocalHost(), 0);
- assertNotNull(ssl);
- assertEquals(sport, ssl.getPort());
- ssl.close();
-
- try {
- getSSLSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082);
- fail();
- } catch (IOException expected) {
- }
-
- try {
- getSSLSocket(InetAddress.getLocalHost(), -1, InetAddress.getLocalHost(), sport + 1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- getSSLSocket(InetAddress.getLocalHost(), sport, InetAddress.getLocalHost(), -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- getSSLSocket(InetAddress.getLocalHost(), Integer.MIN_VALUE,
- InetAddress.getLocalHost(), sport + 1);
- fail();
- } catch (IOException expectedOnRI) {
- assertTrue(StandardNames.IS_RI);
- } catch (IllegalArgumentException expectedOnAndroid) {
- assertFalse(StandardNames.IS_RI);
- }
- try {
- getSSLSocket(InetAddress.getLocalHost(), sport,
- InetAddress.getLocalHost(), Integer.MAX_VALUE);
- fail();
- } catch (IllegalArgumentException expectedOnAndroid) {
- assertFalse(StandardNames.IS_RI);
- }
- }
-
- /**
- * javax.net.ssl.SSLSocket#SSLSocket(String host, int port)
- */
- public void testConstructor_StringI() throws Exception {
- int sport = startServer("Cons String,I");
- int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE};
-
- SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost().getHostName(), sport);
- assertNotNull(ssl);
- assertEquals(sport, ssl.getPort());
- ssl.close();
-
- try {
- getSSLSocket("localhost", 8082);
- fail();
- } catch (IOException expected) {
- }
-
- for (int i = 0; i < invalidPort.length; i++) {
- try {
- getSSLSocket(InetAddress.getLocalHost().getHostName(), invalidPort[i]);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- try {
- getSSLSocket("bla-bla", sport);
- fail();
- } catch (UnknownHostException expected) {
- }
- }
-
- /**
- * javax.net.ssl.SSLSocket#SSLSocket(String host, int port, InetAddress clientAddress,
- * int clientPort)
- */
- public void testConstructor_StringIInetAddressI() throws Exception {
- int sport = startServer("Cons String,I,InetAddress,I");
- int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE};
-
- SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost().getHostName(), sport,
- InetAddress.getLocalHost(), 0);
- assertNotNull(ssl);
- assertEquals(sport, ssl.getPort());
-
- try {
- getSSLSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082);
- fail();
- } catch (IOException expected) {
- }
-
- for (int i = 0; i < invalidPort.length; i++) {
- try {
- getSSLSocket(InetAddress.getLocalHost().getHostName(), invalidPort[i],
- InetAddress.getLocalHost(), 0);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- getSSLSocket(InetAddress.getLocalHost().getHostName(), sport,
- InetAddress.getLocalHost(), invalidPort[i]);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- try {
- getSSLSocket("bla-bla", sport, InetAddress.getLocalHost(), 0);
- fail();
- } catch (UnknownHostException expected) {
- }
- }
-
- public void test_creationStressTest() throws Exception {
- // Test the default codepath, which uses /dev/urandom.
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, null, null);
- for (int i = 0; i < 2048; ++i) {
- sslContext.getSocketFactory().createSocket().close();
- }
-
- // Test the other codepath, which copies a seed from a byte[].
- sslContext.init(null, null, new SecureRandom());
- for (int i = 0; i < 2048; ++i) {
- sslContext.getSocketFactory().createSocket().close();
- }
- }
-
- /**
- * javax.net.ssl.SSLSocket#addHandshakeCompletedListener(HandshakeCompletedListener listener)
- */
- @AndroidOnly("RI doesn't throw the specified IAE")
- public void test_addHandshakeCompletedListener() throws IOException {
- SSLSocket ssl = getSSLSocket();
- HandshakeCompletedListener ls = new HandshakeCL();
- try {
- ssl.addHandshakeCompletedListener(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- ssl.addHandshakeCompletedListener(ls);
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#removeHandshakeCompletedListener(HandshakeCompletedListener listener)
- */
- public void test_removeHandshakeCompletedListener() throws IOException {
- SSLSocket ssl = getSSLSocket();
- HandshakeCompletedListener ls = new HandshakeCL();
- try {
- ssl.removeHandshakeCompletedListener(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- ssl.removeHandshakeCompletedListener(ls);
- } catch (IllegalArgumentException expected) {
- }
-
- ssl.addHandshakeCompletedListener(ls);
- ssl.removeHandshakeCompletedListener(ls);
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#setEnableSessionCreation(boolean flag)
- * javax.net.ssl.SSLSocket#getEnableSessionCreation()
- */
- public void test_EnableSessionCreation() throws IOException {
- SSLSocket ssl = getSSLSocket();
- assertTrue(ssl.getEnableSessionCreation());
- ssl.setEnableSessionCreation(false);
- assertFalse(ssl.getEnableSessionCreation());
- ssl.setEnableSessionCreation(true);
- assertTrue(ssl.getEnableSessionCreation());
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#setNeedClientAuth(boolean need)
- * javax.net.ssl.SSLSocket#getNeedClientAuthCreation()
- */
- public void test_NeedClientAuth() throws UnknownHostException, IOException {
- SSLSocket ssl = getSSLSocket();
- ssl.setNeedClientAuth(true);
- assertTrue(ssl.getNeedClientAuth());
- ssl.setNeedClientAuth(false);
- assertFalse(ssl.getNeedClientAuth());
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#setWantClientAuth(boolean want)
- * javax.net.ssl.SSLSocket#getWantClientAuthCreation()
- */
- public void test_WantClientAuth() throws UnknownHostException, IOException {
- SSLSocket ssl = getSSLSocket();
- ssl.setWantClientAuth(true);
- assertTrue(ssl.getWantClientAuth());
- ssl.setWantClientAuth(false);
- assertFalse(ssl.getWantClientAuth());
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#getSupportedProtocols()
- */
- public void test_getSupportedProtocols() throws IOException {
- SSLSocket ssl = getSSLSocket();
- String[] res = ssl.getSupportedProtocols();
- assertTrue("No supported protocols found", res.length > 0);
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#getEnabledProtocols()
- * javax.net.ssl.SSLSocket#setEnabledProtocols(String[] protocols)
- */
- public void test_EnabledProtocols() throws IOException {
- SSLSocket ssl = getSSLSocket();
- try {
- ssl.setEnabledProtocols(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- ssl.setEnabledProtocols(new String[] {});
- try {
- ssl.setEnabledProtocols(new String[] {"blubb"});
- fail();
- } catch (IllegalArgumentException expected) {
- }
- ssl.setEnabledProtocols(ssl.getEnabledProtocols());
- String[] res = ssl.getEnabledProtocols();
- assertEquals("no enabled protocols set",
- ssl.getEnabledProtocols().length, res.length);
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#getSession()
- */
- public void test_getSession() throws IOException {
- SSLSocket ssl = getSSLSocket();
- assertNotNull(ssl.getSession());
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#getSupportedCipherSuites()
- */
- public void test_getSupportedCipherSuites() throws IOException {
- SSLSocket ssl = getSSLSocket();
- String[] res = ssl.getSupportedCipherSuites();
- assertTrue("no supported cipher suites", res.length > 0);
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#getEnabledCipherSuites()
- * javax.net.ssl.SSLSocket#setEnabledCipherSuites(String[] suites)
- */
- public void test_EnabledCipherSuites() throws IOException {
- SSLSocket ssl = getSSLSocket();
- try {
- ssl.setEnabledCipherSuites(null);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- ssl.setEnabledCipherSuites(new String[] {});
- try {
- ssl.setEnabledCipherSuites(new String[] {"blubb"});
- fail();
- } catch (IllegalArgumentException expected) {
- }
- ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
- String[] res = ssl.getEnabledCipherSuites();
- assertNotNull("NULL result", res);
- assertEquals("not all supported cipher suites were enabled",
- Arrays.asList(ssl.getSupportedCipherSuites()),
- Arrays.asList(res));
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#getUseClientMode()
- * javax.net.ssl.SSLSocket#setUseClientMode(boolean mode)
- */
- public void test_UseClientMode() throws IOException {
- SSLSocket ssl = getSSLSocket();
- assertTrue(ssl.getUseClientMode());
- ssl.setUseClientMode(false);
- assertFalse(ssl.getUseClientMode());
- ssl.close();
-
- ssl = getSSLSocket("localhost", startServer("UseClientMode"));
- try {
- ssl.startHandshake();
- } catch (IOException ioe) {
- //fail(ioe + " was thrown for method startHandshake()");
- }
- try {
- ssl.setUseClientMode(false);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- ssl.close();
- }
-
- /**
- * javax.net.ssl.SSLSocket#startHandshake()
- */
- public void test_startHandshake() throws IOException {
- SSLSocket ssl = getSSLSocket();
- try {
- ssl.startHandshake();
- fail();
- } catch (IOException expected) {
- }
- ssl.close();
- }
-
- private boolean useBKS = !StandardNames.IS_RI;
-
- private String PASSWORD = "android";
-
- private boolean serverReady = false;
-
- /**
- * Defines the keystore contents for the server, BKS version. Holds just a
- * single self-generated key. The subject name is "Test Server".
- */
- private static final String SERVER_KEYS_BKS = ""
- + "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41"
- + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET"
- + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV"
- + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw"
- + "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U"
- + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl"
- + "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy"
- + "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV"
- + "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG"
- + "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU"
- + "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV"
- + "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx"
- + "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR"
- + "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN"
- + "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs"
- + "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck"
- + "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM"
- + "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI"
- + "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f"
- + "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx"
- + "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt"
- + "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw"
- + "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl"
- + "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw=";
-
- /**
- * Defines the keystore contents for the server, JKS version. Holds just a
- * single self-generated key. The subject name is "Test Server".
- */
- private static final String SERVER_KEYS_JKS = ""
- + "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFfBeAAAArowggK2MA4GCisGAQQBKgIRAQEFAASC"
- + "AqI2kp5XjnF8YZkhcF92YsJNQkvsmH7zqMM87j23zSoV4DwyE3XeC/gZWq1ToScIhoqZkzlbWcu4"
- + "T/Zfc/DrfGk/rKbBL1uWKGZ8fMtlZk8KoAhxZk1JSyJvdkyKxqmzUbxk1OFMlN2VJNu97FPVH+du"
- + "dvjTvmpdoM81INWBW/1fZJeQeDvn4mMbbe0IxgpiLnI9WSevlaDP/sm1X3iO9yEyzHLL+M5Erspo"
- + "Cwa558fOu5DdsICMXhvDQxjWFKFhPHnKtGe+VvwkG9/bAaDgx3kfhk0w5zvdnkKb+8Ed9ylNRzdk"
- + "ocAa/mxlMTOsTvDKXjjsBupNPIIj7OP4GNnZaxkJjSs98pEO67op1GX2qhy6FSOPNuq8k/65HzUc"
- + "PYn6voEeh6vm02U/sjEnzRevQ2+2wXoAdp0EwtQ/DlMe+NvcwPGWKuMgX4A4L93DZGb04N2VmAU3"
- + "YLOtZwTO0LbuWrcCM/q99G/7LcczkxIVrO2I/rh8RXVczlf9QzcrFObFv4ATuspWJ8xG7DhsMbnk"
- + "rT94Pq6TogYeoz8o8ZMykesAqN6mt/9+ToIemmXv+e+KU1hI5oLwWMnUG6dXM6hIvrULY6o+QCPH"
- + "172YQJMa+68HAeS+itBTAF4Clm/bLn6reHCGGU6vNdwU0lYldpiOj9cB3t+u2UuLo6tiFWjLf5Zs"
- + "EQJETd4g/EK9nHxJn0GAKrWnTw7pEHQJ08elzUuy04C/jEEG+4QXU1InzS4o/kR0Sqz2WTGDoSoq"
- + "ewuPRU5bzQs/b9daq3mXrnPtRBL6HfSDAdpTK76iHqLCGdqx3avHjVSBm4zFvEuYBCev+3iKOBmg"
- + "yh7eQRTjz4UOWfy85omMBr7lK8PtfVBDzOXpasxS0uBgdUyBDX4tO6k9jZ8a1kmQRQAAAAEABVgu"
- + "NTA5AAACSDCCAkQwggGtAgRIR8SKMA0GCSqGSIb3DQEBBAUAMGkxCzAJBgNVBAYTAlVTMRMwEQYD"
- + "VQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMH"
- + "QW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBTZXJ2ZXIwHhcNMDgwNjA1MTA0ODQyWhcNMDgwOTAzMTA0"
- + "ODQyWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8w"
- + "DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGf"
- + "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoC6chqCI84rj1PrXuJgbiit4EV909zR6N0jNlYfg"
- + "itwB39bP39wH03rFm8T59b3mbSptnGmCIpLZn25KPPFsYD3JJ+wFlmiUdEP9H05flfwtFQJnw9uT"
- + "3rRIdYVMPcQ3RoZzwAMliGr882I2thIDbA6xjGU/1nRIdvk0LtxH3QIDAQABMA0GCSqGSIb3DQEB"
- + "BAUAA4GBAJn+6YgUlY18Ie+0+Vt8oEi81DNi/bfPrAUAh63fhhBikx/3R9dl3wh09Z6p7cIdNxjW"
- + "n2ll+cRW9eqF7z75F0Omm0C7/KAEPjukVbszmzeU5VqzkpSt0j84YWi+TfcHRrfvhLbrlmGITVpY"
- + "ol5pHLDyqGmDs53pgwipWqsn/nEXEBgj3EoqPeqHbDf7YaP8h/5BSt0=";
-
- protected int startServer(String name) {
- String keys = useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS;
- TestServer server = new TestServer(true, keys);
- Thread serverThread = new Thread(server);
- serverThread.start();
- try {
- while (!serverReady) {
- Exception e = server.getException();
- if (e != null) {
- throw new AssertionError(e);
- }
- Thread.currentThread().sleep(50);
- }
- // give the server 100 millis to accept
- Thread.currentThread().sleep(100);
- } catch (InterruptedException ignore) {
- }
- return server.sport;
- }
-
- /**
- * Implements a test SSL socket server. It wait for a connection on a given
- * port, requests client authentication (if specified), and read 256 bytes
- * from the socket.
- */
- class TestServer implements Runnable {
-
- public static final int CLIENT_AUTH_NONE = 0;
-
- public static final int CLIENT_AUTH_WANTED = 1;
-
- public static final int CLIENT_AUTH_NEEDED = 2;
-
- private TestTrustManager trustManager;
-
- private Exception exception;
-
- String keys;
-
- private boolean provideKeys;
-
- int sport;
-
- public TestServer(boolean provideKeys, String keys) {
- this.keys = keys;
- this.provideKeys = provideKeys;
-
- trustManager = new TestTrustManager();
- }
-
- public void run() {
- try {
- KeyManager[] keyManagers = provideKeys ? getKeyManagers(keys) : null;
- TrustManager[] trustManagers = new TrustManager[] { trustManager };
-
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(keyManagers, trustManagers, null);
-
- SSLServerSocket serverSocket = (SSLServerSocket)
- sslContext.getServerSocketFactory().createServerSocket();
- try {
- serverSocket.bind(new InetSocketAddress(0));
- sport = serverSocket.getLocalPort();
- serverReady = true;
-
- SSLSocket clientSocket = (SSLSocket)serverSocket.accept();
-
- try {
- InputStream stream = clientSocket.getInputStream();
- try {
- for (int i = 0; i < 256; i++) {
- int j = stream.read();
- if (i != j) {
- throw new RuntimeException("Error reading socket, expected " + i
- + ", got " + j);
- }
- }
- } finally {
- stream.close();
- }
- } finally {
- clientSocket.close();
- }
- } finally {
- serverSocket.close();
- }
- } catch (Exception ex) {
- exception = ex;
- }
- }
-
- public Exception getException() {
- return exception;
- }
-
- public X509Certificate[] getChain() {
- return trustManager.getChain();
- }
-
- }
-
- /**
- * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
- * for the result.
- */
- private KeyManager[] getKeyManagers(String keys) throws Exception {
- byte[] bytes = Base64.decode(keys.getBytes());
- InputStream inputStream = new ByteArrayInputStream(bytes);
-
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- keyStore.load(inputStream, PASSWORD.toCharArray());
- inputStream.close();
-
- String algorithm = KeyManagerFactory.getDefaultAlgorithm();
- KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm);
- keyManagerFactory.init(keyStore, PASSWORD.toCharArray());
-
- return keyManagerFactory.getKeyManagers();
- }
-
- private SSLSocket getSSLSocket() throws IOException {
- return (SSLSocket) SSLSocketFactory.getDefault().createSocket();
- }
-
- private SSLSocket getSSLSocket(InetAddress host, int port) throws IOException {
- return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port);
- }
-
- private SSLSocket getSSLSocket(String host, int port) throws UnknownHostException, IOException {
- return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port);
- }
-
- private SSLSocket getSSLSocket(InetAddress host, int port, InetAddress localHost, int localPort)
- throws IOException {
- return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host,
- port,
- localHost,
- localPort);
- }
-
- private SSLSocket getSSLSocket(String host, int port, InetAddress localHost, int localPort)
- throws UnknownHostException, IOException {
- return (SSLSocket) SSLSocketFactory.getDefault().createSocket(host,
- port,
- localHost,
- localPort);
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/security/auth/CallbackHandlerTest.java b/luni/src/test/java/tests/api/javax/security/auth/CallbackHandlerTest.java
deleted file mode 100644
index 76c860a..0000000
--- a/luni/src/test/java/tests/api/javax/security/auth/CallbackHandlerTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.security.auth;
-
-import junit.framework.TestCase;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-
-/**
- * Tests for <code>CallbackHandler</code> class constructors and methods.
- *
- */
-public class CallbackHandlerTest extends TestCase {
-
- /**
- * javax.security.auth.callback.CallbackHandler#handle(Callback[] callbacks)
- */
- public void test_CallbackHandler() {
- CallbackHandlerImpl ch = new CallbackHandlerImpl();
- assertFalse(ch.called);
- ch.handle(null);
- assertTrue(ch.called);
- }
-
- private class CallbackHandlerImpl implements CallbackHandler {
- boolean called = false;
- public void handle(Callback[] callbacks) {
- called = true;
- }
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/security/auth/DestroyFailedExceptionTest.java b/luni/src/test/java/tests/api/javax/security/auth/DestroyFailedExceptionTest.java
deleted file mode 100644
index 4472241..0000000
--- a/luni/src/test/java/tests/api/javax/security/auth/DestroyFailedExceptionTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.security.auth;
-
-import junit.framework.TestCase;
-
-import javax.security.auth.DestroyFailedException;
-
-/**
- * Tests for <code>DestroyFailedException</code> class constructors and methods.
- *
- */
-public class DestroyFailedExceptionTest extends TestCase {
-
- private static String[] msgs = {
- "",
- "Check new message",
- "Check new message Check new message Check new message Check new message Check new message" };
-
-
- /**
- * javax.security.auth.DestroyFailedException#DestroyFailedException()
- * Assertion: constructs DestroyFailedException with no detail message
- */
- public void testDestroyFailedException01() {
- DestroyFailedException dfE = new DestroyFailedException();
- assertNull("getMessage() must return null.", dfE.getMessage());
- assertNull("getCause() must return null", dfE.getCause());
- }
-
- /**
- * javax.security.auth.DestroyFailedException#DestroyFailedException(String msg)
- * Assertion: constructs with not null parameter.
- */
- public void testDestroyFailedException02() {
- DestroyFailedException dfE;
- for (int i = 0; i < msgs.length; i++) {
- dfE = new DestroyFailedException(msgs[i]);
- assertEquals("getMessage() must return: ".concat(msgs[i]), dfE.getMessage(), msgs[i]);
- assertNull("getCause() must return null", dfE.getCause());
- }
- }
-
- /**
- * javax.security.auth.DestroyFailedException#DestroyFailedException(String msg)
- * Assertion: constructs with null parameter.
- */
- public void testDestroyFailedException03() {
- String msg = null;
- DestroyFailedException dfE = new DestroyFailedException(msg);
- assertNull("getMessage() must return null.", dfE.getMessage());
- assertNull("getCause() must return null", dfE.getCause());
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/security/auth/DestroyableTest.java b/luni/src/test/java/tests/api/javax/security/auth/DestroyableTest.java
deleted file mode 100644
index 4ae47ce..0000000
--- a/luni/src/test/java/tests/api/javax/security/auth/DestroyableTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.security.auth;
-
-import junit.framework.TestCase;
-
-import javax.security.auth.Destroyable;
-import javax.security.auth.DestroyFailedException;
-
-
-/**
- * Tests for <code>Destroyable</code> class constructors and methods.
- *
- */
-public class DestroyableTest extends TestCase {
-
- /**
- * javax.security.auth.Destroyable#destroy()
- * javax.security.auth.Destroyable#isDestroyed()
- */
- public void test_destroy() {
- myDestroyable md = new myDestroyable();
- try {
- assertFalse(md.isDestroyed());
- md.destroy();
- assertTrue(md.isDestroyed());
- } catch (Exception e) {
- fail("Unexpected exception " + e);
- }
- }
-
- private class myDestroyable implements Destroyable {
-
- boolean destroyDone = false;
-
- myDestroyable() {
- }
-
- public void destroy() throws DestroyFailedException {
- destroyDone = true;
- }
-
- public boolean isDestroyed() {
- return destroyDone;
- }
- }
-}
-
-
diff --git a/luni/src/test/java/tests/api/javax/security/auth/LoginExceptionTest.java b/luni/src/test/java/tests/api/javax/security/auth/LoginExceptionTest.java
deleted file mode 100644
index 307d401..0000000
--- a/luni/src/test/java/tests/api/javax/security/auth/LoginExceptionTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.security.auth;
-
-import junit.framework.TestCase;
-
-import javax.security.auth.login.LoginException;
-
-/**
- * Tests for <code>LoginException</code> class constructors and methods.
- *
- */
-public class LoginExceptionTest extends TestCase {
-
- private static String[] msgs = {
- "",
- "Check new message",
- "Check new message Check new message Check new message Check new message Check new message" };
-
-
- /**
- * javax.security.auth.login.LoginException#LoginException()
- * Assertion: constructs LoginException with no detail message
- */
- public void testLoginException01() {
- LoginException lE = new LoginException();
- assertNull("getMessage() must return null.", lE.getMessage());
- assertNull("getCause() must return null", lE.getCause());
- }
-
- /**
- * javax.security.auth.login.LoginException#LoginException(String msg)
- * Assertion: constructs with not null parameter.
- */
- public void testLoginException02() {
- LoginException lE;
- for (int i = 0; i < msgs.length; i++) {
- lE = new LoginException(msgs[i]);
- assertEquals("getMessage() must return: ".concat(msgs[i]), lE.getMessage(), msgs[i]);
- assertNull("getCause() must return null", lE.getCause());
- }
- }
-
- /**
- * javax.security.auth.login.LoginException#LoginException(String msg)
- * Assertion: constructs with null parameter.
- */
- public void testLoginException03() {
- String msg = null;
- LoginException lE = new LoginException(msg);
- assertNull("getMessage() must return null.", lE.getMessage());
- assertNull("getCause() must return null", lE.getCause());
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/security/auth/PasswordCallbackTest.java b/luni/src/test/java/tests/api/javax/security/auth/PasswordCallbackTest.java
deleted file mode 100644
index cdd992b..0000000
--- a/luni/src/test/java/tests/api/javax/security/auth/PasswordCallbackTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.security.auth;
-
-import junit.framework.TestCase;
-
-import javax.security.auth.callback.PasswordCallback;
-
-/**
- * Tests for <code>PasswordCallback</code> class constructors and methods.
- *
- */
-public class PasswordCallbackTest extends TestCase {
-
- /**
- * javax.security.auth.callback.PasswordCallback#PasswordCallback(String prompt, boolean echoOn)
- * javax.security.auth.callback.PasswordCallback#getPrompt()
- * javax.security.auth.callback.PasswordCallback#isEchoOn()
- */
- public void test_PasswordCallback() {
- String prompt = "promptTest";
-
- try {
- PasswordCallback pc = new PasswordCallback(prompt, true);
- assertNotNull("Null object returned", pc);
- assertEquals(prompt, pc.getPrompt());
- assertEquals(true, pc.isEchoOn());
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- PasswordCallback pc = new PasswordCallback(prompt, false);
- assertNotNull("Null object returned", pc);
- assertEquals(prompt, pc.getPrompt());
- assertEquals(false, pc.isEchoOn());
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- PasswordCallback pc = new PasswordCallback(null, true);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException npe) {
- }
-
- try {
- PasswordCallback pc = new PasswordCallback("", true);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException npe) {
- }
- }
-
- /**
- * javax.security.auth.callback.PasswordCallback#getPassword()
- * javax.security.auth.callback.PasswordCallback#setPassword(char[] password)
- * javax.security.auth.callback.PasswordCallback#clearPassword()
- */
- public void test_Password() {
- String prompt = "promptTest";
- char[] psw1 = "testPassword".toCharArray();
- char[] psw2 = "newPassword".toCharArray();
- PasswordCallback pc = new PasswordCallback(prompt, true);
-
- try {
- assertNull(pc.getPassword());
- pc.setPassword(psw1);
- assertEquals(psw1.length, pc.getPassword().length);
- pc.setPassword(null);
- assertNull(pc.getPassword());
- pc.setPassword(psw2);
- char[] res = pc.getPassword();
- assertEquals(psw2.length, res.length);
- for (int i = 0; i < res.length; i++) {
- assertEquals("Incorrect password was returned", psw2[i], res[i]);
- }
- pc.clearPassword();
- res = pc.getPassword();
- if (res.equals(psw2)) {
- fail("Incorrect password was returned after clear");
- }
- pc.setPassword(psw1);
- res = pc.getPassword();
- assertEquals(psw1.length, res.length);
- for (int i = 0; i < res.length; i++) {
- assertEquals("Incorrect result", psw1[i], res[i]);
- }
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/security/auth/SubjectTest.java b/luni/src/test/java/tests/api/javax/security/auth/SubjectTest.java
deleted file mode 100644
index 05741a9..0000000
--- a/luni/src/test/java/tests/api/javax/security/auth/SubjectTest.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.security.auth;
-
-import junit.framework.TestCase;
-
-import javax.security.auth.AuthPermission;
-import javax.security.auth.PrivateCredentialPermission;
-import javax.security.auth.Subject;
-
-import java.util.Set;
-import java.util.HashSet;
-import java.security.Permission;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.ProtectionDomain;
-
-/**
- * Tests for <code>Subject</code> class constructors and methods.
- *
- */
-public class SubjectTest extends TestCase {
-
- /**
- * javax.security.auth.Subject#Subject()
- */
- public void test_Constructor_01() {
- try {
- Subject s = new Subject();
- assertNotNull("Null object returned", s);
- assertTrue("Set of principal is not empty", s.getPrincipals().isEmpty());
- assertTrue("Set of private credentials is not empty", s.getPrivateCredentials().isEmpty());
- assertTrue("Set of public credentials is not empty", s.getPublicCredentials().isEmpty());
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- /**
- * javax.security.auth.Subject#doAs(Subject subject, PrivilegedAction action)
- */
- public void test_doAs_01() {
- Subject subj = new Subject();
- PrivilegedAction<Object> pa = new myPrivilegedAction();
- PrivilegedAction<Object> paNull = null;
-
- try {
- Object obj = Subject.doAs(null, pa);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- Object obj = Subject.doAs(subj, pa);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- Object obj = Subject.doAs(subj, paNull);
- fail("NullPointerException wasn't thrown");
- } catch (NullPointerException npe) {
- }
- }
-
- /**
- * javax.security.auth.Subject#doAs(Subject subject, PrivilegedExceptionAction action)
- */
- public void test_doAs_02() {
- Subject subj = new Subject();
- PrivilegedExceptionAction<Object> pea = new myPrivilegedExceptionAction();
- PrivilegedExceptionAction<Object> peaNull = null;
-
- try {
- Object obj = Subject.doAs(null, pea);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- Object obj = Subject.doAs(subj, pea);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- Object obj = Subject.doAs(subj, peaNull);
- fail("NullPointerException wasn't thrown");
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of NullPointerException");
- }
-
- try {
- Subject.doAs(subj, new PrivilegedExceptionAction<Object>(){
- public Object run() throws PrivilegedActionException {
- throw new PrivilegedActionException(null);
- }
- });
- fail("PrivilegedActionException wasn't thrown");
- } catch (PrivilegedActionException e) {
- }
- }
-
- /**
- * javax.security.auth.Subject#doAsPrivileged(Subject subject,
- * PrivilegedAction action,
- * AccessControlContext acc)
- */
- public void test_doAsPrivileged_01() {
- Subject subj = new Subject();
- PrivilegedAction<Object> pa = new myPrivilegedAction();
- PrivilegedAction<Object> paNull = null;
- AccessControlContext acc = AccessController.getContext();
-
- try {
- Object obj = Subject.doAsPrivileged(null, pa, acc);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- Object obj = Subject.doAsPrivileged(subj, pa, acc);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- Object obj = Subject.doAsPrivileged(subj, paNull, acc);
- fail("NullPointerException wasn't thrown");
- } catch (NullPointerException npe) {
- }
- }
-
- /**
- * javax.security.auth.Subject#doAsPrivileged(Subject subject,
- * PrivilegedExceptionAction action,
- * AccessControlContext acc)
- */
- public void test_doAsPrivileged_02() {
- Subject subj = new Subject();
- PrivilegedExceptionAction<Object> pea = new myPrivilegedExceptionAction();
- PrivilegedExceptionAction<Object> peaNull = null;
- AccessControlContext acc = AccessController.getContext();
-
- try {
- Object obj = Subject.doAsPrivileged(null, pea, acc);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- Object obj = Subject.doAsPrivileged(subj, pea, acc);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- Object obj = Subject.doAsPrivileged(subj, peaNull, acc);
- fail("NullPointerException wasn't thrown");
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of NullPointerException");
- }
-
- try {
- Subject.doAsPrivileged(subj, new PrivilegedExceptionAction<Object>(){
- public Object run() throws PrivilegedActionException {
- throw new PrivilegedActionException(null);
- }
- }, acc);
- fail("PrivilegedActionException wasn't thrown");
- } catch (PrivilegedActionException e) {
- }
- }
-
- /**
- * javax.security.auth.Subject#getSubject(AccessControlContext acc)
- */
- public void test_getSubject() {
- Subject subj = new Subject();
- AccessControlContext acc = new AccessControlContext(new ProtectionDomain[0]);
-
- try {
- assertNull(Subject.getSubject(acc));
- } catch (Exception e) {
- fail("Unexpected exception " + e);
- }
- }
-
- /**
- * javax.security.auth.Subject#toString()
- */
- public void test_toString() {
- Subject subj = new Subject();
-
- try {
- assertNotNull("Null returned", subj.toString());
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- /**
- * javax.security.auth.Subject#hashCode()
- */
- public void test_hashCode() {
- Subject subj = new Subject();
-
- try {
- assertNotNull("Null returned", subj.hashCode());
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-}
-
-
-class myPrivilegedAction implements PrivilegedAction <Object> {
- myPrivilegedAction(){}
- public Object run() {
- return new Object();
- }
-}
-
-class myPrivilegedExceptionAction implements PrivilegedExceptionAction <Object> {
- myPrivilegedExceptionAction(){}
- public Object run() {
- return new Object();
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/security/auth/UnsupportedCallbackExceptionTest.java b/luni/src/test/java/tests/api/javax/security/auth/UnsupportedCallbackExceptionTest.java
deleted file mode 100644
index abef563..0000000
--- a/luni/src/test/java/tests/api/javax/security/auth/UnsupportedCallbackExceptionTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.security.auth;
-
-import junit.framework.TestCase;
-
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.callback.Callback;
-
-/**
- * Tests for <code>UnsupportedCallbackException</code> class constructors and methods.
- *
- */
-public class UnsupportedCallbackExceptionTest extends TestCase {
-
- private static String[] msgs = {
- "",
- "Check new message",
- "Check new message Check new message Check new message Check new message Check new message" };
-
-
- /**
- * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback)
- * javax.security.auth.callback.UnsupportedCallbackExceptionTest#getCallback()
- * Assertion: constructs with null parameter.
- */
- public void testUnsupportedCallbackException01() {
- Callback c = null;
- UnsupportedCallbackException ucE = new UnsupportedCallbackException(c);
- assertNull("getMessage() must return null.", ucE.getMessage());
- assertNull("getCallback() must return null", ucE.getCallback());
- }
-
- /**
- * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback)
- * javax.security.auth.callback.UnsupportedCallbackExceptionTest#getCallback()
- * Assertion: constructs with not null parameter.
- */
- public void testUnsupportedCallbackException02() {
- myCallback c = new myCallback();
- assertNotNull("Callback object is null", c);
- UnsupportedCallbackException ucE = new UnsupportedCallbackException(c);
- assertNull("getMessage() must return null.", ucE.getMessage());
- assertEquals("Incorrect callback object was returned", c, ucE.getCallback());
- }
-
- /**
- * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback, String msg)
- * Assertion: constructs with null callback parameter and null message.
- */
- public void testUnsupportedCallbackException03() {
- UnsupportedCallbackException ucE = new UnsupportedCallbackException(null, null);
- assertNull("getMessage() must return null.", ucE.getMessage());
- assertNull("getCallback() must return null.", ucE.getCallback());
- }
-
- /**
- * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback, String msg)
- * Assertion: constructs with null callback parameter and not null message.
- */
- public void testUnsupportedCallbackException04() {
- UnsupportedCallbackException ucE;
- for (int i = 0; i < msgs.length; i++) {
- ucE = new UnsupportedCallbackException(null, msgs[i]);
- assertEquals("getMessage() must return: ".concat(msgs[i]), ucE.getMessage(), msgs[i]);
- assertNull("getCallback() must return null.", ucE.getCallback());
- }
- }
-
- /**
- * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback, String msg)
- * Assertion: constructs with not null callback parameter and null message.
- */
- public void testUnsupportedCallbackException05() {
- myCallback c = new myCallback();
- assertNotNull("Callback object is null", c);
- UnsupportedCallbackException ucE = new UnsupportedCallbackException(c, null);
- assertNull("getMessage() must return null.", ucE.getMessage());
- assertEquals("Incorrect callback object was returned", c, ucE.getCallback());
- }
-
- /**
- * javax.security.auth.callback.UnsupportedCallbackExceptionTest#UnsupportedCallbackException(Callback callback, String msg)
- * Assertion: constructs with not null parameters.
- */
- public void testUnsupportedCallbackException06() {
- myCallback c = new myCallback();
- assertNotNull("Callback object is null", c);
- UnsupportedCallbackException ucE;
- for (int i = 0; i < msgs.length; i++) {
- ucE = new UnsupportedCallbackException(c, msgs[i]);
- assertEquals("getMessage() must return: ".concat(msgs[i]), ucE.getMessage(), msgs[i]);
- assertEquals("Incorrect callback object was returned", c, ucE.getCallback());
- }
- }
-}
-
-class myCallback implements Callback {
- myCallback(){
- }
-}
-
diff --git a/luni/src/test/java/tests/api/javax/security/auth/X500PrincipalTest.java b/luni/src/test/java/tests/api/javax/security/auth/X500PrincipalTest.java
deleted file mode 100644
index 7cb81bb..0000000
--- a/luni/src/test/java/tests/api/javax/security/auth/X500PrincipalTest.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.api.javax.security.auth;
-
-import junit.framework.TestCase;
-
-import javax.security.auth.x500.X500Principal;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import org.apache.harmony.security.tests.support.cert.TestUtils;
-
-/**
- * Tests for <code>X500Principal</code> class constructors and methods.
- *
- */
-public class X500PrincipalTest extends TestCase {
-
- /**
- * javax.security.auth.x500.X500Principal#X500Principal(String name)
- */
- public void test_X500Principal_01() {
- String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
-
- try {
- X500Principal xpr = new X500Principal(name);
- assertNotNull("Null object returned", xpr);
- String resName = xpr.getName();
- assertEquals(name, resName);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- X500Principal xpr = new X500Principal((String)null);
- fail("NullPointerException wasn't thrown");
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of NullPointerException");
- }
-
- try {
- X500Principal xpr = new X500Principal("X500PrincipalName");
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- }
-
- /**
- * javax.security.auth.x500.X500Principal#X500Principal(InputStream is)
- */
- public void test_X500Principal_02() {
- String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
- byte[] ba = getByteArray(TestUtils.getX509Certificate_v1());
- ByteArrayInputStream is = new ByteArrayInputStream(ba);
- InputStream isNull = null;
-
- try {
- X500Principal xpr = new X500Principal(is);
- assertNotNull("Null object returned", xpr);
- byte[] resArray = xpr.getEncoded();
- assertEquals(ba.length, resArray.length);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- X500Principal xpr = new X500Principal(isNull);
- fail("NullPointerException wasn't thrown");
- } catch (NullPointerException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of NullPointerException");
- }
-
- is = new ByteArrayInputStream(name.getBytes());
- try {
- X500Principal xpr = new X500Principal(is);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- }
-
- /**
- * javax.security.auth.x500.X500Principal#X500Principal(byte[] name)
- */
- public void test_X500Principal_03() {
- String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
- byte[] ba = getByteArray(TestUtils.getX509Certificate_v1());
- byte[] baNull = null;
-
- try {
- X500Principal xpr = new X500Principal(ba);
- assertNotNull("Null object returned", xpr);
- byte[] resArray = xpr.getEncoded();
- assertEquals(ba.length, resArray.length);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- X500Principal xpr = new X500Principal(baNull);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
-
- ba = name.getBytes();
- try {
- X500Principal xpr = new X500Principal(ba);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException npe) {
- } catch (Exception e) {
- fail(e + " was thrown instead of IllegalArgumentException");
- }
- }
-
- /**
- * javax.security.auth.x500.X500Principal#getName()
- */
- public void test_getName() {
- String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
- X500Principal xpr = new X500Principal(name);
- try {
- String resName = xpr.getName();
- assertEquals(name, resName);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- /**
- * javax.security.auth.x500.X500Principal#getName(String format)
- */
- public void test_getName_Format() {
- String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
- String expectedName = "cn=duke,ou=javasoft,o=sun microsystems,c=us";
- X500Principal xpr = new X500Principal(name);
- try {
- String resName = xpr.getName(X500Principal.CANONICAL);
- assertEquals(expectedName, resName);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- expectedName = "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US";
- try {
- String resName = xpr.getName(X500Principal.RFC1779);
- assertEquals(expectedName, resName);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- String resName = xpr.getName(X500Principal.RFC2253);
- assertEquals(name, resName);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
-
- try {
- String resName = xpr.getName(null);
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- }
- try {
- String resName = xpr.getName("RFC2254");
- fail("IllegalArgumentException wasn't thrown");
- } catch (IllegalArgumentException iae) {
- }
- }
-
- /**
- * javax.security.auth.x500.X500Principal#hashCode()
- */
- public void test_hashCode() {
- String name = "CN=Duke,OU=JavaSoft,O=Sun Microsystems,C=US";
- X500Principal xpr = new X500Principal(name);
- try {
- int res = xpr.hashCode();
- assertNotNull(res);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- /**
- * javax.security.auth.x500.X500Principal#toString()
- */
- public void test_toString() {
- String name = "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US";
- X500Principal xpr = new X500Principal(name);
- try {
- String res = xpr.toString();
- assertNotNull(res);
- assertEquals(name, res);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- /**
- * javax.security.auth.x500.X500Principal#getEncoded()
- */
- public void test_getEncoded() {
- byte[] ba = getByteArray(TestUtils.getX509Certificate_v1());
- X500Principal xpr = new X500Principal(ba);
- try {
- byte[] res = xpr.getEncoded();
- assertNotNull(res);
- assertEquals(ba.length, res.length);
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- /**
- * javax.security.auth.x500.X500Principal#equals(Object o)
- */
- public void test_equals() {
- String name1 = "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US";
- String name2 = "cn=duke,ou=javasoft,o=sun microsystems,c=us";
- String name3 = "CN=Alex Astapchuk, OU=SSG, O=Intel ZAO, C=RU";
- X500Principal xpr1 = new X500Principal(name1);
- X500Principal xpr2 = new X500Principal(name2);
- X500Principal xpr3 = new X500Principal(name3);
- try {
- assertTrue("False returned", xpr1.equals(xpr2));
- assertFalse("True returned", xpr1.equals(xpr3));
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- private byte[] getByteArray(byte[] array) {
- byte[] x = null;
- try {
- ByteArrayInputStream is = new ByteArrayInputStream(array);
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- X509Certificate cert = (X509Certificate)cf.generateCertificate(is);
- X500Principal xx = cert.getIssuerX500Principal();
- x = xx.getEncoded();
- } catch (Exception e) {
- return null;
- }
- return x;
- }
-}
-
diff --git a/luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java b/luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
deleted file mode 100644
index e937db9..0000000
--- a/luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Alexander Y. Kleymenov
- * @version $Revision$
- */
-
-package tests.api.javax.security.cert;
-
-import dalvik.annotation.BrokenTest;
-import dalvik.annotation.SideEffect;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import tests.targets.security.cert.CertificateFactoryTestX509;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.SignatureException;
-import java.security.Provider.Service;
-import java.security.cert.CertificateFactory;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Set;
-import java.util.logging.Logger;
-
-import javax.security.cert.Certificate;
-import javax.security.cert.CertificateEncodingException;
-import javax.security.cert.CertificateException;
-import javax.security.cert.CertificateExpiredException;
-import javax.security.cert.CertificateNotYetValidException;
-import javax.security.cert.X509Certificate;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-import tests.targets.security.cert.CertificateFactoryTestX509;
-
-/**
- */
-public class X509CertificateTest extends TestCase {
-
- // Testing data was generated by using of classes
- // from org.apache.harmony.security.asn1 package encoded
- // by org.apache.harmony.misc.Base64 class.
-
- private static String base64cert = "-----BEGIN CERTIFICATE-----\n"
- + "MIIC+jCCAragAwIBAgICAiswDAYHKoZIzjgEAwEBADAdMRswGQYDVQQKExJDZXJ0a"
- + "WZpY2F0ZSBJc3N1ZXIwIhgPMTk3MDAxMTIxMzQ2NDBaGA8xOTcwMDEyNDAzMzMyMF"
- + "owHzEdMBsGA1UEChMUU3ViamVjdCBPcmdhbml6YXRpb24wGTAMBgcqhkjOOAQDAQE"
- + "AAwkAAQIDBAUGBwiBAgCqggIAVaOCAhQwggIQMA8GA1UdDwEB/wQFAwMBqoAwEgYD"
- + "VR0TAQH/BAgwBgEB/wIBBTAUBgNVHSABAf8ECjAIMAYGBFUdIAAwZwYDVR0RAQH/B"
- + "F0wW4EMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBcxFTATBgNVBAoTDE9yZ2FuaXphdG"
- + "lvboYaaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWSHBP///wCIByoDolyDsgMwDAY"
- + "DVR0eAQH/BAIwADAMBgNVHSQBAf8EAjAAMIGZBgNVHSUBAf8EgY4wgYsGBFUdJQAG"
- + "CCsGAQUFBwMBBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDB"
- + "AYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUFBw"
- + "MJBggrBgEFBQgCAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GA1UdNgEB/wQDAgE"
- + "BMA4GBCpNhgkBAf8EAwEBATBkBgNVHRIEXTBbgQxyZmNAODIyLk5hbWWCB2ROU05h"
- + "bWWkFzEVMBMGA1UEChMMT3JnYW5pemF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvd"
- + "XJjZS5JZIcE////AIgHKgOiXIOyAzAJBgNVHR8EAjAAMAoGA1UdIwQDAQEBMAoGA1"
- + "UdDgQDAQEBMAoGA1UdIQQDAQEBMAwGByqGSM44BAMBAQADMAAwLQIUAL4QvoazNWP"
- + "7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
- + "-----END CERTIFICATE-----";
-
- /*
- * a self-signed certificate
- */
- private static final String selfSignedCert = "-----BEGIN CERTIFICATE-----\n" +
- "MIIDPzCCAqigAwIBAgIBADANBgkqhkiG9w0BAQUFADB5MQswCQYDVQQGEwJBTjEQ" +
- "MA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5k" +
- "cm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBh" +
- "bmRyb2lkLmNvbTAeFw0wOTAzMjAxNzAwMDZaFw0xMjAzMTkxNzAwMDZaMHkxCzAJ" +
- "BgNVBAYTAkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQKEwdBbmRyb2lkMRAw" +
- "DgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMSIwIAYJKoZIhvcNAQkB" +
- "FhNhbmRyb2lkQGFuZHJvaWQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" +
- "gQCqQkDtkiEXmV8O5EK4y2Y9YyoWNDx70z4fqD+9muuzJGuM5NovMbxhBycuKHF3" +
- "WK60iXzrsAYkB1c8VHHbcUEFqz2fBdLKyxy/nYohlo8TYSVpEjt3vfc0sgmp4FKU" +
- "RDHO2z3rZPHWysV9L9ZvjeQpiwaYipU9epdBmvFmxQmCDQIDAQABo4HWMIHTMB0G" +
- "A1UdDgQWBBTnm32QKeqQC38IQXZOQSPoQyypAzCBowYDVR0jBIGbMIGYgBTnm32Q" +
- "KeqQC38IQXZOQSPoQyypA6F9pHsweTELMAkGA1UEBhMCQU4xEDAOBgNVBAgTB0Fu" +
- "ZHJvaWQxEDAOBgNVBAoTB0FuZHJvaWQxEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNV" +
- "BAMTB0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb22C" +
- "AQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAUmDApQu+r5rglS1WF" +
- "BKXE3R2LasFvbBwdw2E0MAc0TWqLVW91VW4VWMX4r+C+c7rZpYXXtRqFRCuI/czL" +
- "0e1GaUP/Wa6bXBcm2u7Iv2dVAaAOELmFSVTZeR57Lm9lT9kQLp24kmNndIsiDW3T" +
- "XZ4pY/k2kxungOKx8b8pGYE9Bw==\n" +
- "-----END CERTIFICATE-----";
-
- private java.security.cert.X509Certificate cert;
-
- private javax.security.cert.X509Certificate tbt_cert;
-
- private java.security.cert.X509Certificate javaCert;
-
- private Provider myProvider;
-
- private javax.security.cert.X509Certificate javaxCert;
-
- private java.security.cert.Certificate javaSSCert;
-
- private Provider mySSProvider;
-
- private Certificate javaxSSCert;
-
- @Override
- protected void setUp() throws Exception {
- try {
- ByteArrayInputStream bais = new ByteArrayInputStream(base64cert
- .getBytes());
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- this.cert = (java.security.cert.X509Certificate) cf
- .generateCertificate(bais);
- this.tbt_cert = X509Certificate.getInstance(cert.getEncoded());
-
- // non self signed cert
- this.javaCert = (java.security.cert.X509Certificate)cf
- .generateCertificate(new ByteArrayInputStream(selfSignedCert.getBytes()));
- this.javaxCert = X509Certificate.getInstance(javaCert.getEncoded());
- myProvider = cf.getProvider();
- Security.addProvider(myProvider);
-
- // self signed cert
- this.javaSSCert = cf.generateCertificate(new ByteArrayInputStream(
- selfSignedCert.getBytes()));
- this.javaxSSCert = X509Certificate.getInstance(javaCert
- .getEncoded());
- mySSProvider = cf.getProvider();
- Security.addProvider(mySSProvider);
-
- } catch (java.security.cert.CertificateException e) {
- // The requested certificate type is not available.
- // Test pass..
- this.cert = null;
- Logger.global.warning("Error in test setup: Certificate type not supported");
- } catch (javax.security.cert.CertificateException e) {
- // The requested certificate type is not available.
- // Test pass..
- this.cert = null;
- Logger.global.warning("Error in test setup: Certificate type not supported");
- }
- }
-
- /**
- * X509Certificate() constructor testing.
- * {@link X509Certificate#X509Certificate() }
- */
- public void testConstructor() {
- //Direct constructor, check if it throws an exception
- X509Certificate cert = new MyCertificate();
- }
-
- /**
- * getInstance(InputStream inStream) method testing.
- */
- public void testGetInstance1() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- try {
- ByteArrayInputStream bais = new ByteArrayInputStream(cert
- .getEncoded());
-
- X509Certificate.getInstance(bais);
- } catch (java.security.cert.CertificateEncodingException e) {
- fail("Unexpected CertificateEncodingException was thrown.");
- } catch (CertificateEncodingException e) {
- fail("Unexpected CertificateEncodingException was thrown.");
- } catch (CertificateException e) {
- // The requested certificate type is not available.
- // Test pass..
- }
-
- // Regression for HARMONY-756
- try {
- X509Certificate.getInstance((InputStream) null);
- fail("No expected CertificateException");
- } catch (CertificateException e) {
- // expected;
- }
- }
-
- /**
- * getInstance(byte[] certData) method testing.
- * @throws CertificateEncodingException
- * @throws java.security.cert.CertificateEncodingException
- */
- public void testGetInstance2() throws java.security.cert.CertificateEncodingException, CertificateEncodingException {
- boolean certificateException = false;
- X509Certificate c = null;
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- try {
- c = X509Certificate.getInstance(cert.getEncoded());
- } catch (java.security.cert.CertificateEncodingException e) {
- fail("Unexpected CertificateEncodingException was thrown.");
- } catch (CertificateException e) {
- // The requested certificate type is not available.
- // Test pass..
- certificateException = true;
-
- }
-
- if (! certificateException) {
- assertNotNull(c);
- assertTrue(Arrays.equals(c.getEncoded(),cert.getEncoded() ));
- }
-
- try {
- X509Certificate.getInstance(new byte[]{(byte) 1 });
- } catch (CertificateException e) {
- //ok
- }
-
- // Regression for HARMONY-756
- try {
- X509Certificate.getInstance((byte[]) null);
- fail("No expected CertificateException");
- } catch (CertificateException e) {
- // expected;
- }
-
- }
-
- /**
- * checkValidity() method testing.
- * @throws CertificateNotYetValidException
- * @throws CertificateExpiredException
- * @throws java.security.cert.CertificateExpiredException
- * @throws java.security.cert.CertificateNotYetValidException
- */
- public void testCheckValidity1() throws CertificateExpiredException, CertificateNotYetValidException, java.security.cert.CertificateExpiredException, java.security.cert.CertificateNotYetValidException {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- Date date = new Date();
- Date nb_date = tbt_cert.getNotBefore();
- Date na_date = tbt_cert.getNotAfter();
- try {
- tbt_cert.checkValidity();
- assertFalse("CertificateExpiredException expected", date
- .compareTo(na_date) > 0);
- assertFalse("CertificateNotYetValidException expected", date
- .compareTo(nb_date) < 0);
- } catch (CertificateExpiredException e) {
- assertTrue("Unexpected CertificateExpiredException was thrown",
- date.compareTo(na_date) > 0);
- } catch (CertificateNotYetValidException e) {
- assertTrue("Unexpected CertificateNotYetValidException was thrown",
- date.compareTo(nb_date) < 0);
- }
-
- try {
- tbt_cert.checkValidity();
- } catch (CertificateExpiredException e) {
- // ok
- }
-
- try {
- cert.checkValidity();
- } catch (java.security.cert.CertificateExpiredException e) {
- // ok
- }
-
- }
-
- /**
- * checkValidity(Date date) method testing.
- * @throws CertificateNotYetValidException
- * @throws CertificateExpiredException
- */
- public void testCheckValidity2() throws CertificateNotYetValidException, CertificateExpiredException {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- Date[] date = new Date[8];
- Calendar calendar = Calendar.getInstance();
- for (int i = 0; i < date.length; i++) {
- calendar.set(i * 500, Calendar.JANUARY, 1);
- date[i] = calendar.getTime();
- }
- Date nb_date = tbt_cert.getNotBefore();
- Date na_date = tbt_cert.getNotAfter();
- for (int i = 0; i < date.length; i++) {
- try {
- tbt_cert.checkValidity(date[i]);
- assertFalse("CertificateExpiredException expected", date[i]
- .compareTo(na_date) > 0);
- assertFalse("CertificateNotYetValidException expected", date[i]
- .compareTo(nb_date) < 0);
- } catch (CertificateExpiredException e) {
- assertTrue("Unexpected CertificateExpiredException was thrown",
- date[i].compareTo(na_date) > 0);
- } catch (CertificateNotYetValidException e) {
- assertTrue("Unexpected CertificateNotYetValidException "
- + "was thrown", date[i].compareTo(nb_date) < 0);
- }
- }
-
- Calendar calendarNow = Calendar.getInstance();
-
- try {
- tbt_cert.checkValidity(calendarNow.getTime());
- } catch (CertificateExpiredException e) {
- //ok
- }
-
- Calendar calendarPast = GregorianCalendar.getInstance();
- calendarPast.clear();
-
- try {
- tbt_cert.checkValidity(calendarPast.getTime());
- } catch (CertificateNotYetValidException e) {
- //ok
- }
-
- }
-
- /**
- * getVersion() method testing.
- */
- public void testGetVersion() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- assertEquals("The version is not correct.", tbt_cert.getVersion(), 2);
- }
-
- /**
- * getSerialNumber() method testing.
- */
- public void testGetSerialNumber() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- assertEquals("The serial number is not correct.", tbt_cert
- .getSerialNumber(), cert.getSerialNumber());
- }
-
- /**
- * getIssuerDN() method testing.
- */
- public void testGetIssuerDN() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- Logger.global.warning("testGetIssuerDN: error in test setup.");
- }
- assertEquals("The issuer DN is not correct.", tbt_cert.getIssuerDN(),
- cert.getIssuerDN());
- }
-
- /**
- * getSubjectDN() method testing.
- */
- public void testGetSubjectDN() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- assertEquals("The subject DN is not correct.", tbt_cert.getSubjectDN(),
- cert.getSubjectDN());
- }
-
- /**
- * getNotBefore() method testing.
- */
- public void testGetNotBefore() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- assertEquals("The NotBefore date is not correct.", tbt_cert
- .getNotBefore(), cert.getNotBefore());
- }
-
- /**
- * getNotAfter() method testing.
- */
- public void testGetNotAfter() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- assertEquals("The NotAfter date is not correct.", tbt_cert
- .getNotAfter(), cert.getNotAfter());
- }
-
- /**
- * getSigAlgName() method testing.
- */
- public void testGetSigAlgName() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- assertEquals("The name of signature algorithm is not correct.",
- tbt_cert.getSigAlgName(), cert.getSigAlgName());
- }
-
- /**
- * getSigAlgOID() method testing.
- */
- public void testGetSigAlgOID() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- assertEquals("The name of OID of signature algorithm is not correct.",
- tbt_cert.getSigAlgOID(), cert.getSigAlgOID());
- }
-
- /**
- * getSigAlgParams() method testing.
- */
- public void testGetSigAlgParams() {
- if (this.cert == null) {
- // The requested certificate type is not available.
- // Test can not be applied.
- return;
- }
- assertTrue("The byte array with encoded algorithm parameters "
- + "is not correct.", Arrays.equals(tbt_cert.getSigAlgParams(),
- cert.getSigAlgParams()));
- }
-
- /**
- * The stub class used for testing of non abstract methods.
- */
- private class MyCertificate extends X509Certificate {
-
- public MyCertificate() {
- super();
- }
-
- @Override
- public void checkValidity() throws CertificateExpiredException,
- CertificateNotYetValidException {
- }
-
- @Override
- public void checkValidity(Date arg0)
- throws CertificateExpiredException,
- CertificateNotYetValidException {
- }
-
- @Override
- public Principal getIssuerDN() {
- return null;
- }
-
- @Override
- public Date getNotAfter() {
- return null;
- }
-
- @Override
- public Date getNotBefore() {
- return null;
- }
-
- @Override
- public BigInteger getSerialNumber() {
- return null;
- }
-
- @Override
- public String getSigAlgName() {
- return null;
- }
-
- @Override
- public String getSigAlgOID() {
- return null;
- }
-
- @Override
- public byte[] getSigAlgParams() {
- return null;
- }
-
- @Override
- public Principal getSubjectDN() {
- return null;
- }
-
- @Override
- public int getVersion() {
- return 0;
- }
-
- @Override
- public byte[] getEncoded() throws CertificateEncodingException {
- return null;
- }
-
- @Override
- public PublicKey getPublicKey() {
- return null;
- }
-
- @Override
- public String toString() {
- return null;
- }
-
- @Override
- public void verify(PublicKey key) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException,
- NoSuchProviderException, SignatureException {
- }
-
- @Override
- public void verify(PublicKey key, String sigProvider)
- throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException,
- SignatureException {
- }
- }
-
- public class MyModifiablePublicKey implements PublicKey {
-
- private PublicKey key;
- private boolean modifiedAlgo;
- private String algo;
- private String format;
- private boolean modifiedFormat;
- private boolean modifiedEncoding;
- private byte[] encoding;
-
- public MyModifiablePublicKey(PublicKey k) {
- super();
- this.key = k;
- }
-
- public String getAlgorithm() {
- if (modifiedAlgo) {
- return algo;
- } else {
- return key.getAlgorithm();
- }
- }
-
- public String getFormat() {
- if (modifiedFormat) {
- return this.format;
- } else {
- return key.getFormat();
- }
-
- }
-
- public byte[] getEncoded() {
- if (modifiedEncoding) {
- return this.encoding;
- } else {
- return key.getEncoded();
- }
-
- }
-
- public long getSerVerUID() {
- return key.serialVersionUID;
- }
-
- public void setAlgorithm(String myAlgo) {
- modifiedAlgo = true;
- this.algo = myAlgo;
- }
-
- public void setFormat(String myFormat) {
- modifiedFormat = true;
- format = myFormat;
- }
-
- public void setEncoding(byte[] myEncoded) {
- modifiedEncoding = true;
- encoding = myEncoded;
- }
- }
-
- /**
- * @throws CertificateEncodingException
- * {@link Certificate#getEncoded()}
- */
- public void testGetEncoded()
- throws CertificateEncodingException, java.security.cert.CertificateException {
- // cert = DER encoding of the ASN1.0 structure
- assertTrue(Arrays.equals(cert.getEncoded(), tbt_cert.getEncoded()));
- assertFalse(Arrays.equals(javaxCert.getEncoded(), tbt_cert.getEncoded()));
- }
-
- /**
- * {@link Certificate#getPublicKey()}
- */
- public void testGetPublicKey() {
- PublicKey key = javaxCert.getPublicKey();
- assertNotNull(key);
- assertEquals(javaxCert.getPublicKey(), javaCert.getPublicKey());
- assertEquals(key.getAlgorithm(),"RSA");
-
- key = javaxSSCert.getPublicKey();
- assertNotNull(key);
- assertEquals(key.getAlgorithm(),"RSA");
-
- //assertTrue(mySSProvider.containsKey(key));
-
- }
-
- /**
- * @throws SignatureException
- * @throws NoSuchProviderException
- * @throws NoSuchAlgorithmException
- * @throws InvalidKeyException
- * @throws CertificateException
- * {@link Certificate#verify(PublicKey)}
- */
- @SideEffect("Destroys MD5 provider, hurts succeeding tests")
- public void testVerifyPublicKey() throws InvalidKeyException,
- NoSuchAlgorithmException, NoSuchProviderException,
- SignatureException, CertificateException {
-
- // Preconditions
- assertNotNull(javaxCert.getPublicKey());
- assertNotNull(javaxSSCert.getPublicKey());
- //precondition for self signed certificates
- /*assertEquals(((X509Certificate) javaxSSCert).getIssuerDN().getName(),
- ((X509Certificate) javaxSSCert).getSubjectDN());*/
-
- // must always evaluate true for self signed
- // here not self signed:
- try {
- javaxCert.verify(javaxCert.getPublicKey());
- } catch (SignatureException e) {
- // ok
- }
-
- PublicKey k = javaxCert.getPublicKey();
-
- MyModifiablePublicKey changedEncoding = new MyModifiablePublicKey(k);
- changedEncoding
- .setEncoding(new byte[javaxCert.getEncoded().length - 1]);
-
- try {
- javaxCert.verify(tbt_cert.getPublicKey());
- } catch (InvalidKeyException e) {
- // ok
- }
-
-
- try {
- javaxCert.verify(null);
- } catch (Exception e) {
- // ok
- }
-
- try {
- javaxCert.verify(changedEncoding);
- fail("Exception expected");
- } catch (Exception e) {
- // ok
- }
-
- // following test doesn't work because the algorithm is derived from
- // somewhere else.
-
- // MyModifiablePublicKey changedAlgo = new MyModifiablePublicKey(k);
- // changedAlgo.setAlgorithm("MD5withBla");
-
- // try {
- // javaxCert.verify(changedAlgo);
- // fail("Exception expected");
- // } catch (SignatureException e) {
- // // ok
- // }
-
- // Security.removeProvider(mySSProvider.getName());
-
- // try {
- // javaxSSCert.verify(javaxSSCert.getPublicKey());
- // } catch (NoSuchProviderException e) {
- // // ok
- // }
-
- // Security.addProvider(mySSProvider);
-
- // must always evaluate true for self signed
- // javaxSSCert.verify(javaxSSCert.getPublicKey());
- }
-
- /**
- * @throws SignatureException
- * @throws NoSuchProviderException
- * @throws NoSuchAlgorithmException
- * @throws java.security.cert.CertificateException
- * @throws InvalidKeyException
- * @throws IOException
- * @throws CertificateException
- * {@link Certificate#verify(PublicKey, String)}
- */
- @SideEffect("Destroys MD5 provider, hurts succeeding tests")
- public void testVerifyPublicKeyString() throws InvalidKeyException,
- java.security.cert.CertificateException, NoSuchAlgorithmException,
- NoSuchProviderException, SignatureException, IOException,
- CertificateException {
-
- try {
- javaxCert.verify(javaxCert.getPublicKey(), myProvider.getName());
- } catch (NoSuchAlgorithmException e) {
- // ok
- }
-
- // myProvider.getService(type, algorithm)
-
- Security.removeProvider(myProvider.getName());
- try {
- javaxCert.verify(javaxCert.getPublicKey(), myProvider.getName());
- } catch (NoSuchProviderException e) {
- // ok
- }
- Security.addProvider(myProvider);
-
- Provider[] providers = Security.getProviders("Signature.MD5withRSA");
- if (providers == null || providers.length == 0) {
- fail("no Provider for Signature.MD5withRSA");
- return;
- }
-
- // self signed cert: should verify with provider
- try {
- javaxSSCert.verify(javaxSSCert.getPublicKey(),
- providers[0].getName());
- } catch (SignatureException e) {
- fail("blu");
- }
-
- }
-
- public static Test suite() {
- return new TestSuite(X509CertificateTest.class);
- }
-}
diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java b/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
deleted file mode 100644
index 3586162..0000000
--- a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
+++ /dev/null
@@ -1,922 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.api.javax.xml.parsers;
-
-import dalvik.annotation.KnownFailure;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Vector;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import junit.framework.TestCase;
-import org.xml.sax.HandlerBase;
-import org.xml.sax.InputSource;
-import org.xml.sax.Parser;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.helpers.DefaultHandler;
-import tests.api.javax.xml.parsers.SAXParserTestSupport.MyDefaultHandler;
-import tests.api.javax.xml.parsers.SAXParserTestSupport.MyHandler;
-import tests.api.org.xml.sax.support.BrokenInputStream;
-import tests.api.org.xml.sax.support.MethodLogger;
-import tests.api.org.xml.sax.support.MockHandler;
-import tests.support.resource.Support_Resources;
-
-@SuppressWarnings("deprecation")
-public class SAXParserTest extends TestCase {
-
- private class MockSAXParser extends SAXParser {
- public MockSAXParser() {
- super();
- }
-
- /*
- * @see javax.xml.parsers.SAXParser#getParser()
- */
- @Override
- public Parser getParser() throws SAXException {
- // it is a fake
- return null;
- }
-
- /*
- * @see javax.xml.parsers.SAXParser#getProperty(java.lang.String)
- */
- @Override
- public Object getProperty(String name) throws SAXNotRecognizedException,
- SAXNotSupportedException {
- // it is a fake
- return null;
- }
-
- /*
- * @see javax.xml.parsers.SAXParser#getXMLReader()
- */
- @Override
- public XMLReader getXMLReader() throws SAXException {
- // it is a fake
- return null;
- }
-
- /*
- * @see javax.xml.parsers.SAXParser#isNamespaceAware()
- */
- @Override
- public boolean isNamespaceAware() {
- // it is a fake
- return false;
- }
-
- /*
- * @see javax.xml.parsers.SAXParser#isValidating()
- */
- @Override
- public boolean isValidating() {
- // it is a fake
- return false;
- }
-
- /*
- * @see javax.xml.parsers.SAXParser#setProperty(java.lang.String,
- * java.lang.Object)
- */
- @Override
- public void setProperty(String name, Object value) throws
- SAXNotRecognizedException, SAXNotSupportedException {
- // it is a fake
- }
- }
-
- private static final String LEXICAL_HANDLER_PROPERTY
- = "http://xml.org/sax/properties/lexical-handler";
-
- SAXParserFactory spf;
-
- SAXParser parser;
-
- static HashMap<String, String> ns;
-
- static Vector<String> el;
-
- static HashMap<String, String> attr;
-
- SAXParserTestSupport sp = new SAXParserTestSupport();
-
- File [] list_wf;
- File [] list_nwf;
- File [] list_out_dh;
- File [] list_out_hb;
-
- boolean validating = false;
-
- private InputStream getResource(String name) {
- return this.getClass().getResourceAsStream(name);
- }
-
- public void initFiles() throws Exception {
- // we differntiate between a validating and a non validating parser
- try {
- SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
- validating = parser.isValidating();
- } catch (Exception e) {
- fail("could not obtain a SAXParser");
- }
-
- String tmpPath = System.getProperty("java.io.tmpdir");
-
- // nwf = not well formed, wf = well formed
- list_wf = new File[] {new File(tmpPath + "/" +
- SAXParserTestSupport.XML_WF + "staff.xml")};
- list_nwf = new File[] {new File(tmpPath + "/" +
- SAXParserTestSupport.XML_NWF + "staff.xml")};
- list_out_dh = new File[] {new File(tmpPath + "/" +
- SAXParserTestSupport.XML_WF_OUT_DH + "staff.out")};
- list_out_hb = new File[] {new File(tmpPath + "/" +
- SAXParserTestSupport.XML_WF_OUT_HB + "staff.out")};
-
- list_wf[0].deleteOnExit();
- list_nwf[0].deleteOnExit();
- list_out_hb[0].deleteOnExit();
- list_out_dh[0].deleteOnExit();
-
-
- Support_Resources.copyLocalFileto(list_wf[0],
- getResource(SAXParserTestSupport.XML_WF + "staff.xml"));
- Support_Resources.copyLocalFileto(new File(
- tmpPath + "/" + SAXParserTestSupport.XML_WF + "staff.dtd"),
- getResource(SAXParserTestSupport.XML_WF + "staff.dtd"));
-
- Support_Resources.copyLocalFileto(list_nwf[0],
- getResource(SAXParserTestSupport.XML_NWF + "staff.xml"));
- Support_Resources.copyLocalFileto(new File(
- tmpPath + "/" + SAXParserTestSupport.XML_NWF + "staff.dtd"),
- getResource(SAXParserTestSupport.XML_NWF + "staff.dtd"));
-
- Support_Resources.copyLocalFileto(list_out_dh[0],
- getResource(SAXParserTestSupport.XML_WF_OUT_DH + "staff.out"));
- Support_Resources.copyLocalFileto(list_out_hb[0],
- getResource(SAXParserTestSupport.XML_WF_OUT_HB + "staff.out"));
- }
-
- @Override
- protected void setUp() throws Exception {
- spf = SAXParserFactory.newInstance();
- parser = spf.newSAXParser();
- assertNotNull(parser);
-
- ns = new HashMap<String, String>();
- attr = new HashMap<String, String>();
- el = new Vector<String>();
- initFiles();
- }
-
- @Override
- protected void tearDown() throws Exception {
- }
-
-// public static void main(String[] args) throws Exception {
-// SAXParserTest st = new SAXParserTest();
-// st.setUp();
-// st.generateDataFromReferenceImpl();
-//
-// }
-//
-// private void generateDataFromReferenceImpl() {
-// try {
-// for(int i = 0; i < list_wf.length; i++) {
-// MyDefaultHandler dh = new MyDefaultHandler();
-// InputStream is = new FileInputStream(list_wf[i]);
-// parser.parse(is, dh, ParsingSupport.XML_SYSTEM_ID);
-// HashMap refHm = dh.createData();
-//
-// StringBuilder sb = new StringBuilder();
-// for (int j = 0; j < ParsingSupport.KEYS.length; j++) {
-// String key = ParsingSupport.KEYS[j];
-// sb.append(refHm.get(key)).append(
-// ParsingSupport.SEPARATOR_DATA);
-// }
-// FileWriter fw = new FileWriter("/tmp/build_dh"+i+".out");
-// fw.append(sb.toString());
-// fw.close();
-// }
-//
-// for(int i = 0; i < list_nwf.length; i++) {
-// MyHandler hb = new MyHandler();
-// InputStream is = new FileInputStream(list_wf[i]);
-// parser.parse(is, hb, ParsingSupport.XML_SYSTEM_ID);
-// HashMap refHm = hb.createData();
-//
-// StringBuilder sb = new StringBuilder();
-// for (int j = 0; j < ParsingSupport.KEYS.length; j++) {
-// String key = ParsingSupport.KEYS[j];
-// sb.append(refHm.get(key)).append(
-// ParsingSupport.SEPARATOR_DATA);
-// }
-// FileWriter fw = new FileWriter("/tmp/build_hb"+i+".out");
-// fw.append(sb.toString());
-// fw.close();
-// }
-//
-//
-// } catch (Exception e) {
-// e.printStackTrace();
-// }
-// }
-
- public void testSAXParser() {
- try {
- new MockSAXParser();
- } catch (Exception e) {
- fail("unexpected exception " + e.toString());
- }
- }
-
- /**
- * javax.xml.parser.SAXParser#getSchema().
- * TODO getSchema() IS NOT SUPPORTED
- */
- /* public void test_getSchema() {
- assertNull(parser.getSchema());
- SchemaFactory sf =
- SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- try {
- Schema schema = sf.newSchema();
- spf.setSchema(schema);
- assertNotNull(spf.newSAXParser().getSchema());
- } catch (ParserConfigurationException pce) {
- fail("Unexpected ParserConfigurationException " + pce.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
- }
- */
-
- public void testIsNamespaceAware() {
- try {
- spf.setNamespaceAware(true);
- assertTrue(spf.newSAXParser().isNamespaceAware());
- spf.setNamespaceAware(false);
- assertFalse(spf.newSAXParser().isNamespaceAware());
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
- }
-
- public void testIsValidating() {
- try {
- spf.setValidating(false);
- assertFalse(spf.newSAXParser().isValidating());
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
- }
-
- public void testIsXIncludeAware() {
- try {
- spf.setXIncludeAware(false);
- assertFalse(spf.newSAXParser().isXIncludeAware());
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
- }
-
- /**
- * @test javax.xml.parsers.SAXParser#parse(java.io.File,
- * org.xml.sax.helpers.DefaultHandler)
- */
- public void test_parseLjava_io_FileLorg_xml_sax_helpers_DefaultHandler()
- throws Exception {
-
- for(int i = 0; i < list_wf.length; i++) {
- HashMap<String, String> hm =
- new SAXParserTestSupport().readFile(list_out_dh[i].getPath());
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse(list_wf[i], dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
- }
-
- for(int i = 0; i < list_nwf.length; i++) {
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse(list_nwf[i], dh);
- fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- }
- }
-
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse((File) null, dh);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- }
-
- try {
- parser.parse(list_wf[0], (DefaultHandler) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- }
- }
-
- public void testParseFileHandlerBase() {
- for(int i = 0; i < list_wf.length; i++) {
- try {
- HashMap<String, String> hm = sp.readFile(
- list_out_hb[i].getPath());
- MyHandler dh = new MyHandler();
- parser.parse(list_wf[i], dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm,
- dh.createData()));
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
- }
-
- for(int i = 0; i < list_nwf.length; i++) {
- try {
- MyHandler dh = new MyHandler();
- parser.parse(list_nwf[i], dh);
- fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- }
- }
-
- try {
- MyHandler dh = new MyHandler();
- parser.parse((File) null, dh);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
-
- try {
- parser.parse(list_wf[0], (HandlerBase) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch(IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
- }
-
- /**
- * @test javax.xml.parsers.SAXParser#parse(org.xml.sax.InputSource,
- * org.xml.sax.helpers.DefaultHandler)
- */
- public void test_parseLorg_xml_sax_InputSourceLorg_xml_sax_helpers_DefaultHandler()
- throws Exception {
- for(int i = 0; i < list_wf.length; i++) {
- HashMap<String, String> hm = new SAXParserTestSupport().readFile(
- list_out_dh[i].getPath());
- MyDefaultHandler dh = new MyDefaultHandler();
- InputSource is = new InputSource(new FileInputStream(list_wf[i]));
- parser.parse(is, dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
- }
-
- for (File file : list_nwf) {
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- InputSource is = new InputSource(new FileInputStream(file));
- parser.parse(is, dh);
- fail("SAXException is not thrown");
- } catch (SAXException expected) {
- }
- }
-
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse((InputSource) null, dh);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch (IllegalArgumentException expected) {
- }
-
- InputSource is = new InputSource(new FileInputStream(list_wf[0]));
- parser.parse(is, (DefaultHandler) null);
-
- InputStream in = null;
- try {
- in = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
- is = new InputSource(in);
- parser.parse(is, (DefaultHandler) null);
- fail("IOException expected");
- } catch(IOException expected) {
- } finally {
- in.close();
- }
- }
-
- public void testParseInputSourceHandlerBase() throws Exception {
- for(int i = 0; i < list_wf.length; i++) {
- HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
- MyHandler dh = new MyHandler();
- InputSource is = new InputSource(new FileInputStream(list_wf[i]));
- parser.parse(is, dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
- }
-
- for (File file : list_nwf) {
- try {
- MyHandler dh = new MyHandler();
- InputSource is = new InputSource(new FileInputStream(file));
- parser.parse(is, dh);
- fail("SAXException is not thrown");
- } catch (SAXException expected) {
- }
- }
-
- try {
- MyHandler dh = new MyHandler();
- parser.parse((InputSource) null, dh);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch(IllegalArgumentException expected) {
- }
-
- InputSource is = new InputSource(new FileInputStream(list_wf[0]));
- parser.parse(is, (HandlerBase) null);
-
- // Reader case
- is = new InputSource(new InputStreamReader(new FileInputStream(list_wf[0])));
- parser.parse(is, (HandlerBase) null);
-
- // SystemID case
- is = new InputSource(list_wf[0].toURI().toString());
- parser.parse(is, (HandlerBase) null);
-
- // Inject IOException
- InputStream in = null;
- try {
- in = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
- parser.parse(in, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
- fail("IOException expected");
- } catch(IOException expected) {
- } finally {
- in.close();
- }
- }
-
- /**
- * @test javax.xml.parsers.SAXParser#parse(java.io.InputStream,
- * org.xml.sax.helpers.DefaultHandler)
- */
- public void test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandler()
- throws Exception {
-
- for(int i = 0; i < list_wf.length; i++) {
-
- HashMap<String, String> hm = new SAXParserTestSupport().readFile(
- list_out_dh[i].getPath());
- MyDefaultHandler dh = new MyDefaultHandler();
- InputStream is = new FileInputStream(list_wf[i]);
- parser.parse(is, dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
- }
-
- for(int i = 0; i < list_nwf.length; i++) {
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- InputStream is = new FileInputStream(list_nwf[i]);
- parser.parse(is, dh);
- fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- }
- }
-
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse((InputStream) null, dh);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- }
-
- try {
- InputStream is = new FileInputStream(list_wf[0]);
- parser.parse(is, (DefaultHandler) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- }
- }
-
- /**
- * @test javax.xml.parsers.SAXParser#parse(java.io.InputStream,
- * org.xml.sax.helpers.DefaultHandler, java.lang.String)
- */
- @KnownFailure("We supply optional qnames, but this test doesn't expect them")
- public void test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandlerLjava_lang_String() {
- for(int i = 0; i < list_wf.length; i++) {
- try {
- HashMap<String, String> hm = sp.readFile(
- list_out_hb[i].getPath());
- MyDefaultHandler dh = new MyDefaultHandler();
- InputStream is = new FileInputStream(list_wf[i]);
- parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
- assertEquals(hm, dh.createData());
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
- }
-
- for(int i = 0; i < list_nwf.length; i++) {
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- InputStream is = new FileInputStream(list_nwf[i]);
- parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
- fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- }
- }
-
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse((InputStream) null, dh,
- SAXParserTestSupport.XML_SYSTEM_ID);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
-
- try {
- InputStream is = new FileInputStream(list_wf[0]);
- parser.parse(is, (DefaultHandler) null,
- SAXParserTestSupport.XML_SYSTEM_ID);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch(IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
-//
-// for(int i = 0; i < list_wf.length; i++) {
-//
-// HashMap<String, String> hm = new SAXParserTestSupport().readFile(
-// list_out_dh[i].getPath());
-// MyDefaultHandler dh = new MyDefaultHandler();
-// InputStream is = new FileInputStream(list_wf[i]);
-// parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
-// assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
-// }
-//
-// for(int i = 0; i < list_nwf.length; i++) {
-// try {
-// MyDefaultHandler dh = new MyDefaultHandler();
-// InputStream is = new FileInputStream(list_nwf[i]);
-// parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
-// fail("SAXException is not thrown");
-// } catch(org.xml.sax.SAXException se) {
-// //expected
-// }
-// }
-//
-// try {
-// MyDefaultHandler dh = new MyDefaultHandler();
-// parser.parse((InputStream) null, dh,
-// SAXParserTestSupport.XML_SYSTEM_ID);
-// fail("java.lang.IllegalArgumentException is not thrown");
-// } catch(java.lang.IllegalArgumentException iae) {
-// //expected
-// }
-//
-// try {
-// InputStream is = new FileInputStream(list_wf[0]);
-// parser.parse(is, (DefaultHandler) null,
-// SAXParserTestSupport.XML_SYSTEM_ID);
-// } catch(java.lang.IllegalArgumentException iae) {
-// fail("java.lang.IllegalArgumentException is thrown");
-// }
-//
-// // TODO commented out since our parser is nonvalidating and thus never
-// // tries to load staff.dtd in "/" ... and therefore never can fail with
-// // an IOException
-// /*try {
-// MyDefaultHandler dh = new MyDefaultHandler();
-// InputStream is = new FileInputStream(list_wf[0]);
-// parser.parse(is, dh, "/");
-// fail("Expected IOException was not thrown");
-// } catch(IOException ioe) {
-// // expected
-// }*/
- }
-
- public void testParseInputStreamHandlerBase() throws Exception {
- for(int i = 0; i < list_wf.length; i++) {
- HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
- MyHandler dh = new MyHandler();
- InputStream is = new FileInputStream(list_wf[i]);
- parser.parse(is, dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
- }
-
- for (File file : list_nwf) {
- try {
- MyHandler dh = new MyHandler();
- InputStream is = new FileInputStream(file);
- parser.parse(is, dh);
- fail("SAXException is not thrown");
- } catch (SAXException expected) {
- }
- }
-
- try {
- MyHandler dh = new MyHandler();
- parser.parse((InputStream) null, dh);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch (IllegalArgumentException expected) {
- }
-
- InputStream is = new FileInputStream(list_wf[0]);
- parser.parse(is, (HandlerBase) null);
-
- // Inject IOException
- try {
- is = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
- parser.parse(is, (HandlerBase) null);
- fail("IOException expected");
- } catch(IOException e) {
- // Expected
- } finally {
- is.close();
- }
- }
-
- public void testParseInputStreamHandlerBaseString() throws Exception {
- for(int i = 0; i < list_wf.length; i++) {
- HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
- MyHandler dh = new MyHandler();
- InputStream is = new FileInputStream(list_wf[i]);
- parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
- assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
- }
-
- for (File file : list_nwf) {
- try {
- MyHandler dh = new MyHandler();
- InputStream is = new FileInputStream(file);
- parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
- fail("SAXException is not thrown");
- } catch (SAXException expected) {
- }
- }
-
- try {
- MyHandler dh = new MyHandler();
- parser.parse(null, dh, SAXParserTestSupport.XML_SYSTEM_ID);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch(IllegalArgumentException expected) {
- }
-
- InputStream is = new FileInputStream(list_wf[0]);
- parser.parse(is, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
-
- // Inject IOException
- try {
- is = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
- parser.parse(is, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
- fail("IOException expected");
- } catch(IOException expected) {
- } finally {
- is.close();
- }
- }
-
- /**
- * @test javax.xml.parsers.SAXParser#parse(java.lang.String,
- * org.xml.sax.helpers.DefaultHandler)
- */
- public void test_parseLjava_lang_StringLorg_xml_sax_helpers_DefaultHandler()
- throws Exception {
-
- for(int i = 0; i < list_wf.length; i++) {
-
- HashMap<String, String> hm = new SAXParserTestSupport().readFile(
- list_out_dh[i].getPath());
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse(list_wf[i].toURI().toString(), dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
- }
-
- for(int i = 0; i < list_nwf.length; i++) {
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse(list_nwf[i].toURI().toString(), dh);
- fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- }
- }
-
- try {
- MyDefaultHandler dh = new MyDefaultHandler();
- parser.parse((String) null, dh);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- }
-
- try {
- parser.parse(list_wf[0].toURI().toString(), (DefaultHandler) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- }
- }
-
- public void testParseStringHandlerBase() {
- for(int i = 0; i < list_wf.length; i++) {
- try {
- HashMap<String, String> hm = sp.readFile(
- list_out_hb[i].getPath());
- MyHandler dh = new MyHandler();
- parser.parse(list_wf[i].toURI().toString(), dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm,
- dh.createData()));
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
- }
-
- for(int i = 0; i < list_nwf.length; i++) {
- try {
- MyHandler dh = new MyHandler();
- parser.parse(list_nwf[i].toURI().toString(), dh);
- fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- }
- }
-
- try {
- MyHandler dh = new MyHandler();
- parser.parse((String) null, dh);
- fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
-
- try {
- parser.parse(list_wf[0].toURI().toString(), (HandlerBase) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch(IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
- }
-
- public void testReset() {
- try {
- spf = SAXParserFactory.newInstance();
- parser = spf.newSAXParser();
-
- parser.setProperty(LEXICAL_HANDLER_PROPERTY, new MockHandler(new MethodLogger()));
- parser.reset();
- assertEquals(null, parser.getProperty(LEXICAL_HANDLER_PROPERTY));
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
- }
-
- public void testGetParser() {
- spf = SAXParserFactory.newInstance();
- try {
- Parser parser = spf.newSAXParser().getParser();
- assertNotNull(parser);
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
- }
-
- public void testGetReader() {
- spf = SAXParserFactory.newInstance();
- try {
- XMLReader reader = spf.newSAXParser().getXMLReader();
- assertNotNull(reader);
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
- }
-
- public void testSetGetProperty() {
- // Ordinary case
- String validName = "http://xml.org/sax/properties/lexical-handler";
- LexicalHandler validValue = new MockHandler(new MethodLogger());
-
- try {
- SAXParser parser = spf.newSAXParser();
- parser.setProperty(validName, validValue);
- assertEquals(validValue, parser.getProperty(validName));
-
- parser.setProperty(validName, null);
- assertEquals(null, parser.getProperty(validName));
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
-
- // Unsupported property
- try {
- SAXParser parser = spf.newSAXParser();
- parser.setProperty("foo", "bar");
- fail("SAXNotRecognizedException expected");
- } catch (SAXNotRecognizedException e) {
- // Expected
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
-
- try {
- SAXParser parser = spf.newSAXParser();
- parser.getProperty("foo");
- fail("SAXNotRecognizedException expected");
- } catch (SAXNotRecognizedException e) {
- // Expected
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
-
- // No name case
- try {
- SAXParser parser = spf.newSAXParser();
- parser.setProperty(null, "bar");
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- // Expected
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
-
- try {
- SAXParser parser = spf.newSAXParser();
- parser.getProperty(null);
- fail("NullPointerException expected");
- } catch (NullPointerException e) {
- // Expected
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
- }
- }
-
-}
diff --git a/luni/src/test/java/tests/java/sql/SqlDateTest.java b/luni/src/test/java/tests/java/sql/SqlDateTest.java
new file mode 100644
index 0000000..fb226af
--- /dev/null
+++ b/luni/src/test/java/tests/java/sql/SqlDateTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.sql.Date;
+
+import junit.framework.TestCase;
+
+public class SqlDateTest extends TestCase {
+
+ public void testValueOf() {
+ String[] dates = {
+ "2001-12-31", "2001-12-1", "2001-1-1", "1900-12-31"
+ };
+
+ for (String date : dates) {
+ Date.valueOf(date);
+ }
+ }
+
+ public void testValueOfInvalidDate() {
+ String[] invalidDates = {
+ "",
+ "+2001-12-31", "2001-+12-31", "2001-12-+31",
+ "-2001-12-31", "2001--12-31", "2001-12--31",
+ "2001--","2001--31","-12-31", "-12-", "--31",
+ "2000000001-12-31"
+ };
+
+ for (String date : invalidDates) {
+ try {
+ Date.valueOf(date);
+ fail();
+ } catch (IllegalArgumentException expected) { }
+ }
+ }
+
+}
diff --git a/luni/src/test/java/tests/security/cert/CertificateRevocationExceptionTest.java b/luni/src/test/java/tests/security/cert/CertificateRevocationExceptionTest.java
new file mode 100644
index 0000000..c3894f8
--- /dev/null
+++ b/luni/src/test/java/tests/security/cert/CertificateRevocationExceptionTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.security.cert;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.cert.CRLReason;
+import java.security.cert.CertificateRevokedException;
+import java.security.cert.Extension;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.x500.X500Principal;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+public class CertificateRevocationExceptionTest extends TestCase implements SerializableAssert {
+ private CertificateRevokedException getTestException() {
+ HashMap<String, Extension> extensions = new HashMap<String, Extension>();
+ // REASON_CODE
+ extensions.put("2.5.29.21", getReasonExtension());
+ extensions.put("2.5.29.24", getInvalidityExtension());
+ return new CertificateRevokedException(
+ new Date(1199226851000L),
+ CRLReason.CESSATION_OF_OPERATION,
+ new X500Principal("CN=test1"),
+ extensions);
+ }
+
+ private Extension getReasonExtension() {
+ return new Extension() {
+ @Override
+ public String getId() {
+ return "2.5.29.21";
+ }
+
+ @Override
+ public boolean isCritical() {
+ return false;
+ }
+
+ @Override
+ public byte[] getValue() {
+ return new byte[] {4, 3, 10, 1, 5};
+ }
+
+ @Override
+ public void encode(OutputStream out) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ private Extension getInvalidityExtension() {
+ return new Extension() {
+ @Override
+ public String getId() {
+ return "2.5.29.24";
+ }
+
+ @Override
+ public boolean isCritical() {
+ return false;
+ }
+
+ @Override
+ public byte[] getValue() {
+ return new byte[] {
+ 0x18, 0x0F, 0x32, 0x30, 0x31, 0x34, 0x30, 0x31, 0x31, 0x37, 0x30, 0x38,
+ 0x33, 0x30, 0x30, 0x39, 0x5a
+ };
+ }
+
+ @Override
+ public void encode(OutputStream out) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ public void testGetExtensions() throws Exception {
+ CertificateRevokedException original = getTestException();
+ Map<String, Extension> extensions = original.getExtensions();
+ assertNotSame(extensions, original.getExtensions());
+
+ try {
+ extensions.put("2.2.2.2", getReasonExtension());
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ public void testGetRevocationDate() throws Exception {
+ CertificateRevokedException exception = getTestException();
+
+ Date firstDate = exception.getRevocationDate();
+ assertNotSame(firstDate, exception.getRevocationDate());
+
+ firstDate.setYear(firstDate.getYear() + 1);
+ assertTrue(firstDate.compareTo(exception.getRevocationDate()) > 0);
+ }
+
+ public void testGetInvalidityDate() throws Exception {
+ CertificateRevokedException exception = getTestException();
+
+ Date firstDate = exception.getInvalidityDate();
+ assertNotSame(firstDate, exception.getInvalidityDate());
+
+ firstDate.setYear(firstDate.getYear() + 1);
+ assertTrue(firstDate.compareTo(exception.getInvalidityDate()) > 0);
+ }
+
+
+ /**
+ * serialization/deserialization compatibility.
+ */
+ public void testSerializationCertificateRevokedExceptionSelf() throws Exception {
+ SerializationTest.verifySelf(getTestException(), this);
+ }
+
+ /**
+ * serialization/deserialization compatibility with RI.
+ */
+ public void testSerializationCertificateRevokedExceptionCompatability() throws Exception {
+ // create test file (once)
+ // SerializationTest.createGoldenFile("/tmp", this, getTestException());
+ SerializationTest.verifyGolden(this, getTestException());
+ }
+
+ @Override
+ public void assertDeserialized(Serializable initial, Serializable deserialized) {
+ assertTrue(initial instanceof CertificateRevokedException);
+ assertTrue(deserialized instanceof CertificateRevokedException);
+
+ CertificateRevokedException expected = (CertificateRevokedException) initial;
+ CertificateRevokedException actual = (CertificateRevokedException) deserialized;
+
+ assertEquals(expected.getInvalidityDate(), actual.getInvalidityDate());
+ assertNotSame(expected.getInvalidityDate(), actual.getInvalidityDate());
+ assertEquals(expected.getRevocationDate(), actual.getRevocationDate());
+ assertNotSame(expected.getRevocationDate(), actual.getRevocationDate());
+ assertEquals(expected.getRevocationReason(), expected.getRevocationReason());
+
+ assertEquals(expected.getExtensions().size(), actual.getExtensions().size());
+ assertEquals(expected.getExtensions().keySet(), actual.getExtensions().keySet());
+ }
+}
diff --git a/luni/src/test/native/dalvik_system_JniTest.cpp b/luni/src/test/native/dalvik_system_JniTest.cpp
new file mode 100644
index 0000000..df48ca9
--- /dev/null
+++ b/luni/src/test/native/dalvik_system_JniTest.cpp
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+#include <stdlib.h> // for abort
+
+extern "C" jobject Java_dalvik_system_JniTest_returnThis(JNIEnv*, jobject obj) {
+ return obj;
+}
+
+extern "C" jclass Java_dalvik_system_JniTest_returnClass(JNIEnv*, jclass klass) {
+ return klass;
+}
+
+extern "C" jobject Java_dalvik_system_JniTest_returnObjectArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jobject o1, jobject o2, jobject o3, jobject o4, jobject o5,
+ jobject o6, jobject o7, jobject o8, jobject o9, jobject o10,
+ jobject o11, jobject o12, jobject o13, jobject o14, jobject o15,
+ jobject o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jboolean Java_dalvik_system_JniTest_returnBooleanArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jboolean o1, jboolean o2, jboolean o3, jboolean o4, jboolean o5,
+ jboolean o6, jboolean o7, jboolean o8, jboolean o9, jboolean o10,
+ jboolean o11, jboolean o12, jboolean o13, jboolean o14, jboolean o15,
+ jboolean o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jchar Java_dalvik_system_JniTest_returnCharArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jchar o1, jchar o2, jchar o3, jchar o4, jchar o5,
+ jchar o6, jchar o7, jchar o8, jchar o9, jchar o10,
+ jchar o11, jchar o12, jchar o13, jchar o14, jchar o15,
+ jchar o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jbyte Java_dalvik_system_JniTest_returnByteArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jbyte o1, jbyte o2, jbyte o3, jbyte o4, jbyte o5,
+ jbyte o6, jbyte o7, jbyte o8, jbyte o9, jbyte o10,
+ jbyte o11, jbyte o12, jbyte o13, jbyte o14, jbyte o15,
+ jbyte o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jshort Java_dalvik_system_JniTest_returnShortArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jshort o1, jshort o2, jshort o3, jshort o4, jshort o5,
+ jshort o6, jshort o7, jshort o8, jshort o9, jshort o10,
+ jshort o11, jshort o12, jshort o13, jshort o14, jshort o15,
+ jshort o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jint Java_dalvik_system_JniTest_returnIntArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jint o1, jint o2, jint o3, jint o4, jint o5,
+ jint o6, jint o7, jint o8, jint o9, jint o10,
+ jint o11, jint o12, jint o13, jint o14, jint o15,
+ jint o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jlong Java_dalvik_system_JniTest_returnLongArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jlong o1, jlong o2, jlong o3, jlong o4, jlong o5,
+ jlong o6, jlong o7, jlong o8, jlong o9, jlong o10,
+ jlong o11, jlong o12, jlong o13, jlong o14, jlong o15,
+ jlong o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jfloat Java_dalvik_system_JniTest_returnFloatArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jfloat o1, jfloat o2, jfloat o3, jfloat o4, jfloat o5,
+ jfloat o6, jfloat o7, jfloat o8, jfloat o9, jfloat o10,
+ jfloat o11, jfloat o12, jfloat o13, jfloat o14, jfloat o15,
+ jfloat o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jdouble Java_dalvik_system_JniTest_returnDoubleArgFrom16(
+ JNIEnv*, jobject, int arg_no,
+ jdouble o1, jdouble o2, jdouble o3, jdouble o4, jdouble o5,
+ jdouble o6, jdouble o7, jdouble o8, jdouble o9, jdouble o10,
+ jdouble o11, jdouble o12, jdouble o13, jdouble o14, jdouble o15,
+ jdouble o16) {
+ switch(arg_no){
+ case 0: return o1;
+ case 1: return o2;
+ case 2: return o3;
+ case 3: return o4;
+ case 4: return o5;
+ case 5: return o6;
+ case 6: return o7;
+ case 7: return o8;
+ case 8: return o9;
+ case 9: return o10;
+ case 10: return o11;
+ case 11: return o12;
+ case 12: return o13;
+ case 13: return o14;
+ case 14: return o15;
+ case 15: return o16;
+ default: abort();
+ }
+}
+
+extern "C" jclass Java_dalvik_system_JniTest_envGetSuperclass(
+ JNIEnv* env, jobject, jclass clazz) {
+ return env->GetSuperclass(clazz);
+}
diff --git a/luni/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider b/luni/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider
deleted file mode 100644
index d29245f..0000000
--- a/luni/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider
+++ /dev/null
@@ -1,2 +0,0 @@
-tests.api.java.nio.charset.CharsetTest$MockCharsetProvider
-tests.api.java.nio.charset.CharsetTest$MockCharsetProviderASCII
diff --git a/luni/src/test/resources/math_important_numbers.csv b/luni/src/test/resources/math_important_numbers.csv
new file mode 100644
index 0000000..3c71a4e
--- /dev/null
+++ b/luni/src/test/resources/math_important_numbers.csv
@@ -0,0 +1,738 @@
+#These numbers are automatically generated to test numbers such as pi, pi/2, 0, etc.
+abs,0x1.5bf0a8b145769p1,0x1.5bf0a8b145769p1,2.718281828459045
+abs,0x1.5bf0a8b145769p1,-0x1.5bf0a8b145769p1,-2.718281828459045
+abs,0x0.0p0,0x0.0p0,0.0
+abs,0x0.0p0,-0x0.0p0,-0.0
+abs,0x1.0p0,0x1.0p0,1.0
+abs,0x1.0p0,-0x1.0p0,-1.0
+abs,0x1.0p-1,-0x1.0p-1,-0.5
+abs,0x1.0p-1,0x1.0p-1,0.5
+abs,0x1.921fb54442d18p2,-0x1.921fb54442d18p2,-6.283185307179586
+abs,0x1.815e630c155e1p2,-0x1.815e630c155e1p2,-6.021385919380436
+abs,0x1.709d10d3e7eabp2,-0x1.709d10d3e7eabp2,-5.759586531581287
+abs,0x1.5fdbbe9bba775p2,-0x1.5fdbbe9bba775p2,-5.497787143782138
+abs,0x1.4f1a6c638d03fp2,-0x1.4f1a6c638d03fp2,-5.235987755982989
+abs,0x1.3e591a2b5f908p2,-0x1.3e591a2b5f908p2,-4.974188368183839
+abs,0x1.2d97c7f3321d2p2,-0x1.2d97c7f3321d2p2,-4.71238898038469
+abs,0x1.1cd675bb04a9cp2,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+abs,0x1.0c152382d7365p2,-0x1.0c152382d7365p2,-4.1887902047863905
+abs,0x1.f6a7a2955385dp1,-0x1.f6a7a2955385dp1,-3.926990816987241
+abs,0x1.d524fe24f89f1p1,-0x1.d524fe24f89f1p1,-3.665191429188092
+abs,0x1.b3a259b49db85p1,-0x1.b3a259b49db85p1,-3.4033920413889427
+abs,0x1.921fb54442d18p1,-0x1.921fb54442d18p1,-3.141592653589793
+abs,0x1.709d10d3e7eabp1,-0x1.709d10d3e7eabp1,-2.8797932657906435
+abs,0x1.4f1a6c638d03fp1,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+abs,0x1.2d97c7f3321d2p1,-0x1.2d97c7f3321d2p1,-2.356194490192345
+abs,0x1.0c152382d7365p1,-0x1.0c152382d7365p1,-2.0943951023931953
+abs,0x1.d524fe24f89f1p0,-0x1.d524fe24f89f1p0,-1.832595714594046
+abs,0x1.921fb54442d18p0,-0x1.921fb54442d18p0,-1.5707963267948966
+abs,0x1.4f1a6c638d03fp0,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+abs,0x1.0c152382d7365p0,-0x1.0c152382d7365p0,-1.0471975511965976
+abs,0x1.921fb54442d18p-1,-0x1.921fb54442d18p-1,-0.7853981633974483
+abs,0x1.0c152382d7365p-1,-0x1.0c152382d7365p-1,-0.5235987755982988
+abs,0x1.0c152382d7365p-2,-0x1.0c152382d7365p-2,-0.2617993877991494
+abs,0x0.0p0,0x0.0p0,0.0
+abs,0x1.0c152382d7365p-2,0x1.0c152382d7365p-2,0.2617993877991494
+abs,0x1.0c152382d7365p-1,0x1.0c152382d7365p-1,0.5235987755982988
+abs,0x1.921fb54442d18p-1,0x1.921fb54442d18p-1,0.7853981633974483
+abs,0x1.0c152382d7365p0,0x1.0c152382d7365p0,1.0471975511965976
+abs,0x1.4f1a6c638d03fp0,0x1.4f1a6c638d03fp0,1.3089969389957472
+abs,0x1.921fb54442d18p0,0x1.921fb54442d18p0,1.5707963267948966
+abs,0x1.d524fe24f89f1p0,0x1.d524fe24f89f1p0,1.832595714594046
+abs,0x1.0c152382d7365p1,0x1.0c152382d7365p1,2.0943951023931953
+abs,0x1.2d97c7f3321d2p1,0x1.2d97c7f3321d2p1,2.356194490192345
+abs,0x1.4f1a6c638d03fp1,0x1.4f1a6c638d03fp1,2.6179938779914944
+abs,0x1.709d10d3e7eabp1,0x1.709d10d3e7eabp1,2.8797932657906435
+abs,0x1.921fb54442d18p1,0x1.921fb54442d18p1,3.141592653589793
+abs,0x1.b3a259b49db85p1,0x1.b3a259b49db85p1,3.4033920413889427
+abs,0x1.d524fe24f89f1p1,0x1.d524fe24f89f1p1,3.665191429188092
+abs,0x1.f6a7a2955385dp1,0x1.f6a7a2955385dp1,3.926990816987241
+abs,0x1.0c152382d7365p2,0x1.0c152382d7365p2,4.1887902047863905
+abs,0x1.1cd675bb04a9cp2,0x1.1cd675bb04a9cp2,4.4505895925855405
+abs,0x1.2d97c7f3321d2p2,0x1.2d97c7f3321d2p2,4.71238898038469
+abs,0x1.3e591a2b5f908p2,0x1.3e591a2b5f908p2,4.974188368183839
+abs,0x1.4f1a6c638d03fp2,0x1.4f1a6c638d03fp2,5.235987755982989
+abs,0x1.5fdbbe9bba775p2,0x1.5fdbbe9bba775p2,5.497787143782138
+abs,0x1.709d10d3e7eabp2,0x1.709d10d3e7eabp2,5.759586531581287
+abs,0x1.815e630c155e1p2,0x1.815e630c155e1p2,6.021385919380436
+abs,0x1.921fb54442d18p2,0x1.921fb54442d18p2,6.283185307179586
+acos,0x1.921fb54442d18p0,0x0.0p0,0.0
+acos,0x1.921fb54442d18p0,-0x0.0p0,-0.0
+acos,0x0.0p0,0x1.0p0,1.0
+acos,0x1.921fb54442d18p1,-0x1.0p0,-1.0
+acos,0x1.0c152382d7366p1,-0x1.0p-1,-0.5
+acos,0x1.0c152382d7366p0,0x1.0p-1,0.5
+acos,0x1.3cb0785319b73p1,-0x1.921fb54442d18p-1,-0.7853981633974483
+acos,0x1.0f994d58bf2a8p1,-0x1.0c152382d7365p-1,-0.5235987755982988
+acos,0x1.d5ef495ee4bfcp0,-0x1.0c152382d7365p-2,-0.2617993877991494
+acos,0x1.921fb54442d18p0,0x0.0p0,0.0
+acos,0x1.4e502129a0e35p0,0x1.0c152382d7365p-2,0.2617993877991494
+acos,0x1.050ccfd7074dfp0,0x1.0c152382d7365p-1,0.5235987755982988
+acos,0x1.55bcf3c4a4694p-1,0x1.921fb54442d18p-1,0.7853981633974483
+asin,0x0.0p0,0x0.0p0,0.0
+asin,-0x0.0p0,-0x0.0p0,-0.0
+asin,0x1.921fb54442d18p0,0x1.0p0,1.0
+asin,-0x1.921fb54442d18p0,-0x1.0p0,-1.0
+asin,-0x1.0c152382d7366p-1,-0x1.0p-1,-0.5
+asin,0x1.0c152382d7366p-1,0x1.0p-1,0.5
+asin,-0x1.ce8276c3e139cp-1,-0x1.921fb54442d18p-1,-0.7853981633974483
+asin,-0x1.1a25cada77072p-1,-0x1.0c152382d7365p-1,-0.5235987755982988
+asin,-0x1.0f3e506a87b8dp-2,-0x1.0c152382d7365p-2,-0.2617993877991494
+asin,0x0.0p0,0x0.0p0,0.0
+asin,0x1.0f3e506a87b8dp-2,0x1.0c152382d7365p-2,0.2617993877991494
+asin,0x1.1a25cada77072p-1,0x1.0c152382d7365p-1,0.5235987755982988
+asin,0x1.ce8276c3e139cp-1,0x1.921fb54442d18p-1,0.7853981633974483
+atan,0x1.37e1637253389p0,0x1.5bf0a8b145769p1,2.718281828459045
+atan,-0x1.37e1637253389p0,-0x1.5bf0a8b145769p1,-2.718281828459045
+atan,0x0.0p0,0x0.0p0,0.0
+atan,-0x0.0p0,-0x0.0p0,-0.0
+atan,0x1.921fb54442d18p-1,0x1.0p0,1.0
+atan,-0x1.921fb54442d18p-1,-0x1.0p0,-1.0
+atan,-0x1.dac670561bb4fp-2,-0x1.0p-1,-0.5
+atan,0x1.dac670561bb4fp-2,0x1.0p-1,0.5
+atan,-0x1.69b8154baf42ep0,-0x1.921fb54442d18p2,-6.283185307179586
+atan,-0x1.67fe45e9cabc4p0,-0x1.815e630c155e1p2,-6.021385919380436
+atan,-0x1.661d6ceb7c4e6p0,-0x1.709d10d3e7eabp2,-5.759586531581287
+atan,-0x1.64102fc571c74p0,-0x1.5fdbbe9bba775p2,-5.497787143782138
+atan,-0x1.61d03090f6048p0,-0x1.4f1a6c638d03fp2,-5.235987755982989
+atan,-0x1.5f55ce92d0fd9p0,-0x1.3e591a2b5f908p2,-4.974188368183839
+atan,-0x1.5c97d37d98aa4p0,-0x1.2d97c7f3321d2p2,-4.71238898038469
+atan,-0x1.598b06657c521p0,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+atan,-0x1.56219a568d94cp0,-0x1.0c152382d7365p2,-4.1887902047863905
+atan,-0x1.524a69fcff2afp0,-0x1.f6a7a2955385dp1,-3.926990816987241
+atan,-0x1.4defeaff7c88p0,-0x1.d524fe24f89f1p1,-3.665191429188092
+atan,-0x1.48f6b941de94p0,-0x1.b3a259b49db85p1,-3.4033920413889427
+atan,-0x1.433b8a322ddd2p0,-0x1.921fb54442d18p1,-3.141592653589793
+atan,-0x1.3c903f4b32aaap0,-0x1.709d10d3e7eabp1,-2.8797932657906435
+atan,-0x1.34b7a85467ddcp0,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+atan,-0x1.2b5f4b53c7949p0,-0x1.2d97c7f3321d2p1,-2.356194490192345
+atan,-0x1.201634ac2828bp0,-0x1.0c152382d7365p1,-2.0943951023931953
+atan,-0x1.123f6ef47e0c2p0,-0x1.d524fe24f89f1p0,-1.832595714594046
+atan,-0x1.00fe987ed02ffp0,-0x1.921fb54442d18p0,-1.5707963267948966
+atan,-0x1.d63c8fb14e334p-1,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+atan,-0x1.9ded0009ac5adp-1,-0x1.0c152382d7365p0,-1.0471975511965976
+atan,-0x1.54e04c05d06ap-1,-0x1.921fb54442d18p-1,-0.7853981633974483
+atan,-0x1.edec9c192bfaap-2,-0x1.0c152382d7365p-1,-0.5235987755982988
+atan,-0x1.0632b28478608p-2,-0x1.0c152382d7365p-2,-0.2617993877991494
+atan,0x0.0p0,0x0.0p0,0.0
+atan,0x1.0632b28478608p-2,0x1.0c152382d7365p-2,0.2617993877991494
+atan,0x1.edec9c192bfaap-2,0x1.0c152382d7365p-1,0.5235987755982988
+atan,0x1.54e04c05d06ap-1,0x1.921fb54442d18p-1,0.7853981633974483
+atan,0x1.9ded0009ac5adp-1,0x1.0c152382d7365p0,1.0471975511965976
+atan,0x1.d63c8fb14e334p-1,0x1.4f1a6c638d03fp0,1.3089969389957472
+atan,0x1.00fe987ed02ffp0,0x1.921fb54442d18p0,1.5707963267948966
+atan,0x1.123f6ef47e0c2p0,0x1.d524fe24f89f1p0,1.832595714594046
+atan,0x1.201634ac2828bp0,0x1.0c152382d7365p1,2.0943951023931953
+atan,0x1.2b5f4b53c7949p0,0x1.2d97c7f3321d2p1,2.356194490192345
+atan,0x1.34b7a85467ddcp0,0x1.4f1a6c638d03fp1,2.6179938779914944
+atan,0x1.3c903f4b32aaap0,0x1.709d10d3e7eabp1,2.8797932657906435
+atan,0x1.433b8a322ddd2p0,0x1.921fb54442d18p1,3.141592653589793
+atan,0x1.48f6b941de94p0,0x1.b3a259b49db85p1,3.4033920413889427
+atan,0x1.4defeaff7c88p0,0x1.d524fe24f89f1p1,3.665191429188092
+atan,0x1.524a69fcff2afp0,0x1.f6a7a2955385dp1,3.926990816987241
+atan,0x1.56219a568d94cp0,0x1.0c152382d7365p2,4.1887902047863905
+atan,0x1.598b06657c521p0,0x1.1cd675bb04a9cp2,4.4505895925855405
+atan,0x1.5c97d37d98aa4p0,0x1.2d97c7f3321d2p2,4.71238898038469
+atan,0x1.5f55ce92d0fd9p0,0x1.3e591a2b5f908p2,4.974188368183839
+atan,0x1.61d03090f6048p0,0x1.4f1a6c638d03fp2,5.235987755982989
+atan,0x1.64102fc571c74p0,0x1.5fdbbe9bba775p2,5.497787143782138
+atan,0x1.661d6ceb7c4e6p0,0x1.709d10d3e7eabp2,5.759586531581287
+atan,0x1.67fe45e9cabc4p0,0x1.815e630c155e1p2,6.021385919380436
+atan,0x1.69b8154baf42ep0,0x1.921fb54442d18p2,6.283185307179586
+cos,-0x1.d2cec9a554007p-1,0x1.5bf0a8b145769p1,2.718281828459045
+cos,-0x1.d2cec9a554007p-1,-0x1.5bf0a8b145769p1,-2.718281828459045
+cos,0x1.0p0,0x0.0p0,0.0
+cos,0x1.0p0,-0x0.0p0,-0.0
+cos,0x1.14a280fb5068cp-1,0x1.0p0,1.0
+cos,0x1.14a280fb5068cp-1,-0x1.0p0,-1.0
+cos,0x1.c1528065b7d5p-1,-0x1.0p-1,-0.5
+cos,0x1.c1528065b7d5p-1,0x1.0p-1,0.5
+cos,0x1.0p0,-0x1.921fb54442d18p2,-6.283185307179586
+cos,0x1.ee8dd4748bf13p-1,-0x1.815e630c155e1p2,-6.021385919380436
+cos,0x1.bb67ae8584ca8p-1,-0x1.709d10d3e7eabp2,-5.759586531581287
+cos,0x1.6a09e667f3bcbp-1,-0x1.5fdbbe9bba775p2,-5.497787143782138
+cos,0x1.0000000000001p-1,-0x1.4f1a6c638d03fp2,-5.235987755982989
+cos,0x1.0907dc1930688p-2,-0x1.3e591a2b5f908p2,-4.974188368183839
+cos,-0x1.a79394c9e8a0ap-53,-0x1.2d97c7f3321d2p2,-4.71238898038469
+cos,-0x1.0907dc193068ep-2,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+cos,-0x1.0000000000004p-1,-0x1.0c152382d7365p2,-4.1887902047863905
+cos,-0x1.6a09e667f3bdp-1,-0x1.f6a7a2955385dp1,-3.926990816987241
+cos,-0x1.bb67ae8584cacp-1,-0x1.d524fe24f89f1p1,-3.665191429188092
+cos,-0x1.ee8dd4748bf15p-1,-0x1.b3a259b49db85p1,-3.4033920413889427
+cos,-0x1.0p0,-0x1.921fb54442d18p1,-3.141592653589793
+cos,-0x1.ee8dd4748bf14p-1,-0x1.709d10d3e7eabp1,-2.8797932657906435
+cos,-0x1.bb67ae8584cabp-1,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+cos,-0x1.6a09e667f3bccp-1,-0x1.2d97c7f3321d2p1,-2.356194490192345
+cos,-0x1.ffffffffffffcp-2,-0x1.0c152382d7365p1,-2.0943951023931953
+cos,-0x1.0907dc193068ep-2,-0x1.d524fe24f89f1p0,-1.832595714594046
+cos,0x1.1a62633145c07p-54,-0x1.921fb54442d18p0,-1.5707963267948966
+cos,0x1.0907dc193069p-2,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+cos,0x1.0000000000001p-1,-0x1.0c152382d7365p0,-1.0471975511965976
+cos,0x1.6a09e667f3bcdp-1,-0x1.921fb54442d18p-1,-0.7853981633974483
+cos,0x1.bb67ae8584cabp-1,-0x1.0c152382d7365p-1,-0.5235987755982988
+cos,0x1.ee8dd4748bf15p-1,-0x1.0c152382d7365p-2,-0.2617993877991494
+cos,0x1.0p0,0x0.0p0,0.0
+cos,0x1.ee8dd4748bf15p-1,0x1.0c152382d7365p-2,0.2617993877991494
+cos,0x1.bb67ae8584cabp-1,0x1.0c152382d7365p-1,0.5235987755982988
+cos,0x1.6a09e667f3bcdp-1,0x1.921fb54442d18p-1,0.7853981633974483
+cos,0x1.0000000000001p-1,0x1.0c152382d7365p0,1.0471975511965976
+cos,0x1.0907dc193069p-2,0x1.4f1a6c638d03fp0,1.3089969389957472
+cos,0x1.1a62633145c07p-54,0x1.921fb54442d18p0,1.5707963267948966
+cos,-0x1.0907dc193068ep-2,0x1.d524fe24f89f1p0,1.832595714594046
+cos,-0x1.ffffffffffffcp-2,0x1.0c152382d7365p1,2.0943951023931953
+cos,-0x1.6a09e667f3bccp-1,0x1.2d97c7f3321d2p1,2.356194490192345
+cos,-0x1.bb67ae8584cabp-1,0x1.4f1a6c638d03fp1,2.6179938779914944
+cos,-0x1.ee8dd4748bf14p-1,0x1.709d10d3e7eabp1,2.8797932657906435
+cos,-0x1.0p0,0x1.921fb54442d18p1,3.141592653589793
+cos,-0x1.ee8dd4748bf15p-1,0x1.b3a259b49db85p1,3.4033920413889427
+cos,-0x1.bb67ae8584cacp-1,0x1.d524fe24f89f1p1,3.665191429188092
+cos,-0x1.6a09e667f3bdp-1,0x1.f6a7a2955385dp1,3.926990816987241
+cos,-0x1.0000000000004p-1,0x1.0c152382d7365p2,4.1887902047863905
+cos,-0x1.0907dc193068ep-2,0x1.1cd675bb04a9cp2,4.4505895925855405
+cos,-0x1.a79394c9e8a0ap-53,0x1.2d97c7f3321d2p2,4.71238898038469
+cos,0x1.0907dc1930688p-2,0x1.3e591a2b5f908p2,4.974188368183839
+cos,0x1.0000000000001p-1,0x1.4f1a6c638d03fp2,5.235987755982989
+cos,0x1.6a09e667f3bcbp-1,0x1.5fdbbe9bba775p2,5.497787143782138
+cos,0x1.bb67ae8584ca8p-1,0x1.709d10d3e7eabp2,5.759586531581287
+cos,0x1.ee8dd4748bf13p-1,0x1.815e630c155e1p2,6.021385919380436
+cos,0x1.0p0,0x1.921fb54442d18p2,6.283185307179586
+cosh,0x1.e70c4a4f41685p2,0x1.5bf0a8b145769p1,2.718281828459045
+cosh,0x1.e70c4a4f41685p2,-0x1.5bf0a8b145769p1,-2.718281828459045
+cosh,0x1.0p0,0x0.0p0,0.0
+cosh,0x1.0p0,-0x0.0p0,-0.0
+cosh,0x1.8b07551d9f551p0,0x1.0p0,1.0
+cosh,0x1.8b07551d9f551p0,-0x1.0p0,-1.0
+cosh,0x1.20ac1862ae8dp0,-0x1.0p-1,-0.5
+cosh,0x1.20ac1862ae8dp0,0x1.0p-1,0.5
+cosh,0x1.0bbf2bc2b69c6p8,-0x1.921fb54442d18p2,-6.283185307179586
+cosh,0x1.9c26de7a4c876p7,-0x1.815e630c155e1p2,-6.021385919380436
+cosh,0x1.3d38653fd9955p7,-0x1.709d10d3e7eabp2,-5.759586531581287
+cosh,0x1.e84f70f559672p6,-0x1.5fdbbe9bba775p2,-5.497787143782138
+cosh,0x1.77d703b1fef8ep6,-0x1.4f1a6c638d03fp2,-5.235987755982989
+cosh,0x1.2146cfce7a73dp6,-0x1.3e591a2b5f908p2,-4.974188368183839
+cosh,0x1.bd4e9aa3e9cdbp5,-0x1.2d97c7f3321d2p2,-4.71238898038469
+cosh,0x1.56c1a783ea3bcp5,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+cosh,0x1.07d51ffbc7ab2p5,-0x1.0c152382d7365p2,-4.1887902047863905
+cosh,0x1.9630955c947f2p4,-0x1.f6a7a2955385dp1,-3.926990816987241
+cosh,0x1.38b6b51cfc1f1p4,-0x1.d524fe24f89f1p1,-3.665191429188092
+cosh,0x1.e19635bf3b425p3,-0x1.b3a259b49db85p1,-3.4033920413889427
+cosh,0x1.72f147fee4p3,-0x1.921fb54442d18p1,-3.141592653589793
+cosh,0x1.1dde27bb3f2c8p3,-0x1.709d10d3e7eabp1,-2.8797932657906435
+cosh,0x1.b8ff233b92bd2p2,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+cosh,0x1.54a7f8a1b9b92p2,-0x1.2d97c7f3321d2p1,-2.356194490192345
+cosh,0x1.07cc2972b616ep2,-0x1.0c152382d7365p1,-2.0943951023931953
+cosh,0x1.9a3edca811aeep1,-0x1.d524fe24f89f1p0,-1.832595714594046
+cosh,0x1.412cc2a8d4e9ep1,-0x1.921fb54442d18p0,-1.5707963267948966
+cosh,0x1.fc7c7b72ba27ep0,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+cosh,0x1.99ac66460ce4p0,-0x1.0c152382d7365p0,-1.0471975511965976
+cosh,0x1.531994ce525b9p0,-0x1.921fb54442d18p-1,-0.7853981633974483
+cosh,0x1.23e6a89aab514p0,-0x1.0c152382d7365p-1,-0.5235987755982988
+cosh,0x1.08d2bd7d0bc1bp0,-0x1.0c152382d7365p-2,-0.2617993877991494
+cosh,0x1.0p0,0x0.0p0,0.0
+cosh,0x1.08d2bd7d0bc1bp0,0x1.0c152382d7365p-2,0.2617993877991494
+cosh,0x1.23e6a89aab514p0,0x1.0c152382d7365p-1,0.5235987755982988
+cosh,0x1.531994ce525b9p0,0x1.921fb54442d18p-1,0.7853981633974483
+cosh,0x1.99ac66460ce4p0,0x1.0c152382d7365p0,1.0471975511965976
+cosh,0x1.fc7c7b72ba27ep0,0x1.4f1a6c638d03fp0,1.3089969389957472
+cosh,0x1.412cc2a8d4e9ep1,0x1.921fb54442d18p0,1.5707963267948966
+cosh,0x1.9a3edca811aeep1,0x1.d524fe24f89f1p0,1.832595714594046
+cosh,0x1.07cc2972b616ep2,0x1.0c152382d7365p1,2.0943951023931953
+cosh,0x1.54a7f8a1b9b92p2,0x1.2d97c7f3321d2p1,2.356194490192345
+cosh,0x1.b8ff233b92bd2p2,0x1.4f1a6c638d03fp1,2.6179938779914944
+cosh,0x1.1dde27bb3f2c8p3,0x1.709d10d3e7eabp1,2.8797932657906435
+cosh,0x1.72f147fee4p3,0x1.921fb54442d18p1,3.141592653589793
+cosh,0x1.e19635bf3b425p3,0x1.b3a259b49db85p1,3.4033920413889427
+cosh,0x1.38b6b51cfc1f1p4,0x1.d524fe24f89f1p1,3.665191429188092
+cosh,0x1.9630955c947f2p4,0x1.f6a7a2955385dp1,3.926990816987241
+cosh,0x1.07d51ffbc7ab2p5,0x1.0c152382d7365p2,4.1887902047863905
+cosh,0x1.56c1a783ea3bcp5,0x1.1cd675bb04a9cp2,4.4505895925855405
+cosh,0x1.bd4e9aa3e9cdbp5,0x1.2d97c7f3321d2p2,4.71238898038469
+cosh,0x1.2146cfce7a73dp6,0x1.3e591a2b5f908p2,4.974188368183839
+cosh,0x1.77d703b1fef8ep6,0x1.4f1a6c638d03fp2,5.235987755982989
+cosh,0x1.e84f70f559672p6,0x1.5fdbbe9bba775p2,5.497787143782138
+cosh,0x1.3d38653fd9955p7,0x1.709d10d3e7eabp2,5.759586531581287
+cosh,0x1.9c26de7a4c876p7,0x1.815e630c155e1p2,6.021385919380436
+cosh,0x1.0bbf2bc2b69c6p8,0x1.921fb54442d18p2,6.283185307179586
+exp,0x1.e4efb75e4527ap3,0x1.5bf0a8b145769p1,2.718281828459045
+exp,0x1.0e49787e20548p-4,-0x1.5bf0a8b145769p1,-2.718281828459045
+exp,0x1.0p0,0x0.0p0,0.0
+exp,0x1.0p0,-0x0.0p0,-0.0
+exp,0x1.5bf0a8b14576ap1,0x1.0p0,1.0
+exp,0x1.78b56362cef38p-2,-0x1.0p0,-1.0
+exp,0x1.368b2fc6f960ap-1,-0x1.0p-1,-0.5
+exp,0x1.a61298e1e069cp0,0x1.0p-1,0.5
+exp,0x1.e989f5d6dff5ep-10,-0x1.921fb54442d18p2,-6.283185307179586
+exp,0x1.3e0545d310facp-9,-0x1.815e630c155e1p2,-6.021385919380436
+exp,0x1.9d317c88e8c75p-9,-0x1.709d10d3e7eabp2,-5.759586531581287
+exp,0x1.0c6c89f32cf3bp-8,-0x1.5fdbbe9bba775p2,-5.497787143782138
+exp,0x1.5cc10db1e9ap-8,-0x1.4f1a6c638d03fp2,-5.235987755982989
+exp,0x1.c51fd34fff925p-8,-0x1.3e591a2b5f908p2,-4.974188368183839
+exp,0x1.265d4e92b6b9cp-7,-0x1.2d97c7f3321d2p2,-4.71238898038469
+exp,0x1.7e752d40d9f68p-7,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+exp,0x1.f0ea0d2fef998p-7,-0x1.0c152382d7365p2,-4.1887902047863905
+exp,0x1.42cfd6c758445p-6,-0x1.f6a7a2955385dp1,-3.926990816987241
+exp,0x1.a36b1f41cd0d4p-6,-0x1.d524fe24f89f1p1,-3.665191429188092
+exp,0x1.1077d12ac7f27p-5,-0x1.b3a259b49db85p1,-3.4033920413889427
+exp,0x1.620227b598efap-5,-0x1.921fb54442d18p1,-3.141592653589793
+exp,0x1.cbf37855eeab7p-5,-0x1.709d10d3e7eabp1,-2.8797932657906435
+exp,0x1.2acca269f2ff5p-4,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+exp,0x1.843844e012c48p-4,-0x1.2d97c7f3321d2p1,-2.356194490192345
+exp,0x1.f86696ab8ba32p-4,-0x1.0c152382d7365p1,-2.0943951023931953
+exp,0x1.47ace27295d4bp-3,-0x1.d524fe24f89f1p0,-1.832595714594046
+exp,0x1.a9bcc46f767ep-3,-0x1.921fb54442d18p0,-1.5707963267948966
+exp,0x1.1492b1531c763p-2,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+exp,0x1.6757859d664c8p-2,-0x1.0c152382d7365p0,-1.0471975511965976
+exp,0x1.d2e171cf04879p-2,-0x1.921fb54442d18p-1,-0.7853981633974483
+exp,0x1.2f4d1112a3e2ap-1,-0x1.0c152382d7365p-1,-0.5235987755982988
+exp,0x1.8a1195bf0aa84p-1,-0x1.0c152382d7365p-2,-0.2617993877991494
+exp,0x1.0p0,0x0.0p0,0.0
+exp,0x1.4c9cb01a922f4p0,0x1.0c152382d7365p-2,0.2617993877991494
+exp,0x1.b026c8ac04b14p0,0x1.0c152382d7365p-1,0.5235987755982988
+exp,0x1.18bd669471caap1,0x1.921fb54442d18p-1,0.7853981633974483
+exp,0x1.6cc17592601a7p1,0x1.0c152382d7365p0,1.0471975511965976
+exp,0x1.d9ea254856992p1,0x1.4f1a6c638d03fp0,1.3089969389957472
+exp,0x1.33dedc855935fp2,0x1.921fb54442d18p0,1.5707963267948966
+exp,0x1.900175947d004p2,0x1.d524fe24f89f1p0,1.832595714594046
+exp,0x1.03db5c455effap3,0x1.0c152382d7365p1,2.0943951023931953
+exp,0x1.519f8817f9939p3,0x1.2d97c7f3321d2p1,2.356194490192345
+exp,0x1.b6a989f6bed72p3,0x1.4f1a6c638d03fp1,2.6179938779914944
+exp,0x1.1cf82dff14353p4,0x1.709d10d3e7eabp1,2.8797932657906435
+exp,0x1.724046eb09339p4,0x1.921fb54442d18p1,3.141592653589793
+exp,0x1.e10df9d6a5de5p4,0x1.b3a259b49db85p1,3.4033920413889427
+exp,0x1.388247b913e57p5,0x1.d524fe24f89f1p1,3.665191429188092
+exp,0x1.96083b61bb941p5,0x1.f6a7a2955385dp1,3.926990816987241
+exp,0x1.07c598ab5e2bap6,0x1.0c152382d7365p2,4.1887902047863905
+exp,0x1.56b5b3da8034fp6,0x1.1cd675bb04a9cp2,4.4505895925855405
+exp,0x1.bd4567b97538p6,0x1.2d97c7f3321d2p2,4.71238898038469
+exp,0x1.2143458ed3d3dp7,0x1.3e591a2b5f908p2,4.974188368183839
+exp,0x1.77d44a2fe3951p7,0x1.4f1a6c638d03fp2,5.235987755982989
+exp,0x1.e84d581c4580cp7,0x1.5fdbbe9bba775p2,5.497787143782138
+exp,0x1.3d3796a71b50ep8,0x1.709d10d3e7eabp2,5.759586531581287
+exp,0x1.9c263f77a99ddp8,0x1.815e630c155e1p2,6.021385919380436
+exp,0x1.0bbeee9177e18p9,0x1.921fb54442d18p2,6.283185307179586
+log,0x1.0p0,0x1.5bf0a8b145769p1,2.718281828459045
+log,0x0.0p0,0x1.0p0,1.0
+log,-0x1.62e42fefa39efp-1,0x1.0p-1,0.5
+log,-0x1.5715d30bf9b3dp0,0x1.0c152382d7365p-2,0.2617993877991494
+log,-0x1.4b4776284fc8bp-1,0x1.0c152382d7365p-1,0.5235987755982988
+log,-0x1.eeb95b094c193p-3,0x1.921fb54442d18p-1,0.7853981633974483
+log,0x1.79cb9c753d63fp-5,0x1.0c152382d7365p0,1.0471975511965976
+log,0x1.13b931cb7c7dbp-2,0x1.4f1a6c638d03fp0,1.3089969389957472
+log,0x1.ce6bb25aa1315p-2,0x1.921fb54442d18p0,1.5707963267948966
+log,0x1.3622afae57e34p-1,0x1.d524fe24f89f1p0,1.832595714594046
+log,0x1.7a80e9b6f7753p-1,0x1.0c152382d7365p1,2.0943951023931953
+log,0x1.b6cef8934d5bp-1,0x1.2d97c7f3321d2p1,2.356194490192345
+log,0x1.ecc0c8d561dddp-1,0x1.4f1a6c638d03fp1,2.6179938779914944
+log,0x1.0ec6a3e3ed35ap0,0x1.709d10d3e7eabp1,2.8797932657906435
+log,0x1.250d048e7a1bdp0,0x1.921fb54442d18p1,3.141592653589793
+log,0x1.398ab25a37d65p0,0x1.b3a259b49db85p1,3.4033920413889427
+log,0x1.4c836fcefdc12p0,0x1.d524fe24f89f1p1,3.665191429188092
+log,0x1.5e2cf41daf501p0,0x1.f6a7a2955385dp1,3.926990816987241
+log,0x1.6eb28cd34d8a1p0,0x1.0c152382d7365p2,4.1887902047863905
+log,0x1.7e37a533563b7p0,0x1.1cd675bb04a9cp2,4.4505895925855405
+log,0x1.8cd99441787dp0,0x1.2d97c7f3321d2p2,4.71238898038469
+log,0x1.9ab0edb49cb1cp0,0x1.3e591a2b5f908p2,4.974188368183839
+log,0x1.a7d27c6282be6p0,0x1.4f1a6c638d03fp2,5.235987755982989
+log,0x1.b44fff81fc225p0,0x1.5fdbbe9bba775p2,5.497787143782138
+log,0x1.c038bbdbbf052p0,0x1.709d10d3e7eabp2,5.759586531581287
+log,0x1.cb99ecae3cca3p0,0x1.815e630c155e1p2,6.021385919380436
+log,0x1.d67f1c864beb4p0,0x1.921fb54442d18p2,6.283185307179586
+log10,0x1.bcb7b1526e50ep-2,0x1.5bf0a8b145769p1,2.718281828459045
+log10,0x0.0p0,0x1.0p0,1.0
+log10,-0x1.34413509f79ffp-2,0x1.0p-1,0.5
+log10,-0x1.2a0004239932p-1,0x1.0c152382d7365p-2,0.2617993877991494
+log10,-0x1.1fbed33d3ac41p-2,0x1.0c152382d7365p-1,0.5235987755982988
+log10,-0x1.adb63b88d410dp-4,0x1.921fb54442d18p-1,0.7853981633974483
+log10,0x1.48261ccbcdbd2p-6,0x1.0c152382d7365p0,1.0471975511965976
+log10,0x1.defb0abb57f05p-4,0x1.4f1a6c638d03fp0,1.3089969389957472
+log10,0x1.91a74c4f85377p-3,0x1.921fb54442d18p0,1.5707963267948966
+log10,0x1.0d615927e723dp-2,0x1.d524fe24f89f1p0,1.832595714594046
+log10,0x1.48c396d6b47bcp-2,0x1.0c152382d7365p1,2.0943951023931953
+log10,0x1.7d24ea82c85bap-2,0x1.2d97c7f3321d2p1,2.356194490192345
+log10,0x1.abfff7b8cd9cp-2,0x1.4f1a6c638d03fp1,2.6179938779914944
+log10,0x1.d662cfccfef7ap-2,0x1.709d10d3e7eabp1,2.8797932657906435
+log10,0x1.fd14db31ba3bap-2,0x1.921fb54442d18p1,3.141592653589793
+log10,0x1.1056c453e917ep-1,0x1.b3a259b49db85p1,3.4033920413889427
+log10,0x1.20d14718ef61ep-1,0x1.d524fe24f89f1p1,3.665191429188092
+log10,0x1.30289e09e9adep-1,0x1.f6a7a2955385dp1,3.926990816987241
+log10,0x1.3e8265f0560dep-1,0x1.0c152382d7365p2,4.1887902047863905
+log10,0x1.4bfd6285d680ep-1,0x1.1cd675bb04a9cp2,4.4505895925855405
+log10,0x1.58b30fc65ffdcp-1,0x1.2d97c7f3321d2p2,4.71238898038469
+log10,0x1.64b8c69bdef01p-1,0x1.3e591a2b5f908p2,4.974188368183839
+log10,0x1.70209661629ep-1,0x1.4f1a6c638d03fp2,5.235987755982989
+log10,0x1.7af9e9467241ep-1,0x1.5fdbbe9bba775p2,5.497787143782138
+log10,0x1.8552026b7b4bcp-1,0x1.709d10d3e7eabp2,5.759586531581287
+log10,0x1.8f345fefe5fdep-1,0x1.815e630c155e1p2,6.021385919380436
+log10,0x1.98ab081dd8eddp-1,0x1.921fb54442d18p2,6.283185307179586
+sin,0x1.a4a3d9c2131dfp-2,0x1.5bf0a8b145769p1,2.718281828459045
+sin,-0x1.a4a3d9c2131dfp-2,-0x1.5bf0a8b145769p1,-2.718281828459045
+sin,0x0.0p0,0x0.0p0,0.0
+sin,-0x0.0p0,-0x0.0p0,-0.0
+sin,0x1.aed548f090ceep-1,0x1.0p0,1.0
+sin,-0x1.aed548f090ceep-1,-0x1.0p0,-1.0
+sin,-0x1.eaee8744b05fp-2,-0x1.0p-1,-0.5
+sin,0x1.eaee8744b05fp-2,0x1.0p-1,0.5
+sin,0x1.1a62633145c07p-52,-0x1.921fb54442d18p2,-6.283185307179586
+sin,0x1.0907dc193069fp-2,-0x1.815e630c155e1p2,-6.021385919380436
+sin,0x1.0000000000004p-1,-0x1.709d10d3e7eabp2,-5.759586531581287
+sin,0x1.6a09e667f3bcep-1,-0x1.5fdbbe9bba775p2,-5.497787143782138
+sin,0x1.bb67ae8584caap-1,-0x1.4f1a6c638d03fp2,-5.235987755982989
+sin,0x1.ee8dd4748bf16p-1,-0x1.3e591a2b5f908p2,-4.974188368183839
+sin,0x1.0p0,-0x1.2d97c7f3321d2p2,-4.71238898038469
+sin,0x1.ee8dd4748bf15p-1,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+sin,0x1.bb67ae8584ca9p-1,-0x1.0c152382d7365p2,-4.1887902047863905
+sin,0x1.6a09e667f3bc9p-1,-0x1.f6a7a2955385dp1,-3.926990816987241
+sin,0x1.ffffffffffffbp-2,-0x1.d524fe24f89f1p1,-3.665191429188092
+sin,0x1.0907dc1930691p-2,-0x1.b3a259b49db85p1,-3.4033920413889427
+sin,-0x1.1a62633145c07p-53,-0x1.921fb54442d18p1,-3.141592653589793
+sin,-0x1.0907dc1930695p-2,-0x1.709d10d3e7eabp1,-2.8797932657906435
+sin,-0x1.fffffffffffffp-2,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+sin,-0x1.6a09e667f3bcdp-1,-0x1.2d97c7f3321d2p1,-2.356194490192345
+sin,-0x1.bb67ae8584cabp-1,-0x1.0c152382d7365p1,-2.0943951023931953
+sin,-0x1.ee8dd4748bf15p-1,-0x1.d524fe24f89f1p0,-1.832595714594046
+sin,-0x1.0p0,-0x1.921fb54442d18p0,-1.5707963267948966
+sin,-0x1.ee8dd4748bf15p-1,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+sin,-0x1.bb67ae8584caap-1,-0x1.0c152382d7365p0,-1.0471975511965976
+sin,-0x1.6a09e667f3bccp-1,-0x1.921fb54442d18p-1,-0.7853981633974483
+sin,-0x1.fffffffffffffp-2,-0x1.0c152382d7365p-1,-0.5235987755982988
+sin,-0x1.0907dc193069p-2,-0x1.0c152382d7365p-2,-0.2617993877991494
+sin,0x0.0p0,0x0.0p0,0.0
+sin,0x1.0907dc193069p-2,0x1.0c152382d7365p-2,0.2617993877991494
+sin,0x1.fffffffffffffp-2,0x1.0c152382d7365p-1,0.5235987755982988
+sin,0x1.6a09e667f3bccp-1,0x1.921fb54442d18p-1,0.7853981633974483
+sin,0x1.bb67ae8584caap-1,0x1.0c152382d7365p0,1.0471975511965976
+sin,0x1.ee8dd4748bf15p-1,0x1.4f1a6c638d03fp0,1.3089969389957472
+sin,0x1.0p0,0x1.921fb54442d18p0,1.5707963267948966
+sin,0x1.ee8dd4748bf15p-1,0x1.d524fe24f89f1p0,1.832595714594046
+sin,0x1.bb67ae8584cabp-1,0x1.0c152382d7365p1,2.0943951023931953
+sin,0x1.6a09e667f3bcdp-1,0x1.2d97c7f3321d2p1,2.356194490192345
+sin,0x1.fffffffffffffp-2,0x1.4f1a6c638d03fp1,2.6179938779914944
+sin,0x1.0907dc1930695p-2,0x1.709d10d3e7eabp1,2.8797932657906435
+sin,0x1.1a62633145c07p-53,0x1.921fb54442d18p1,3.141592653589793
+sin,-0x1.0907dc1930691p-2,0x1.b3a259b49db85p1,3.4033920413889427
+sin,-0x1.ffffffffffffbp-2,0x1.d524fe24f89f1p1,3.665191429188092
+sin,-0x1.6a09e667f3bc9p-1,0x1.f6a7a2955385dp1,3.926990816987241
+sin,-0x1.bb67ae8584ca9p-1,0x1.0c152382d7365p2,4.1887902047863905
+sin,-0x1.ee8dd4748bf15p-1,0x1.1cd675bb04a9cp2,4.4505895925855405
+sin,-0x1.0p0,0x1.2d97c7f3321d2p2,4.71238898038469
+sin,-0x1.ee8dd4748bf16p-1,0x1.3e591a2b5f908p2,4.974188368183839
+sin,-0x1.bb67ae8584caap-1,0x1.4f1a6c638d03fp2,5.235987755982989
+sin,-0x1.6a09e667f3bcep-1,0x1.5fdbbe9bba775p2,5.497787143782138
+sin,-0x1.0000000000004p-1,0x1.709d10d3e7eabp2,5.759586531581287
+sin,-0x1.0907dc193069fp-2,0x1.815e630c155e1p2,6.021385919380436
+sin,-0x1.1a62633145c07p-52,0x1.921fb54442d18p2,6.283185307179586
+sinh,0x1.e2d3246d48e6fp2,0x1.5bf0a8b145769p1,2.718281828459045
+sinh,-0x1.e2d3246d48e6fp2,-0x1.5bf0a8b145769p1,-2.718281828459045
+sinh,0x0.0p0,0x0.0p0,0.0
+sinh,-0x0.0p0,-0x0.0p0,-0.0
+sinh,0x1.2cd9fc44eb982p0,0x1.0p0,1.0
+sinh,-0x1.2cd9fc44eb982p0,-0x1.0p0,-1.0
+sinh,-0x1.0acd00fe63b97p-1,-0x1.0p-1,-0.5
+sinh,0x1.0acd00fe63b97p-1,0x1.0p-1,0.5
+sinh,-0x1.0bbeb1603926ap8,-0x1.921fb54442d18p2,-6.283185307179586
+sinh,-0x1.9c25a07506b44p7,-0x1.815e630c155e1p2,-6.021385919380436
+sinh,-0x1.3d36c80e5d0c7p7,-0x1.709d10d3e7eabp2,-5.759586531581287
+sinh,-0x1.e84b3f43319a6p6,-0x1.5fdbbe9bba775p2,-5.497787143782138
+sinh,-0x1.77d190adc8314p6,-0x1.4f1a6c638d03fp2,-5.235987755982989
+sinh,-0x1.213fbb4f2d33dp6,-0x1.3e591a2b5f908p2,-4.974188368183839
+sinh,-0x1.bd3c34cf00a25p5,-0x1.2d97c7f3321d2p2,-4.71238898038469
+sinh,-0x1.56a9c031162e2p5,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+sinh,-0x1.07b6115af4ac2p5,-0x1.0c152382d7365p2,-4.1887902047863905
+sinh,-0x1.95dfe166e2a9p4,-0x1.f6a7a2955385dp1,-3.926990816987241
+sinh,-0x1.384dda552babdp4,-0x1.d524fe24f89f1p1,-3.665191429188092
+sinh,-0x1.e085bdee107a5p3,-0x1.b3a259b49db85p1,-3.4033920413889427
+sinh,-0x1.718f45d72e672p3,-0x1.921fb54442d18p1,-3.141592653589793
+sinh,-0x1.1c123442e93dep3,-0x1.709d10d3e7eabp1,-2.8797932657906435
+sinh,-0x1.b453f0b1eaf12p2,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+sinh,-0x1.4e97178e396ep2,-0x1.2d97c7f3321d2p1,-2.356194490192345
+sinh,-0x1.ffd51e300fd0ap1,-0x1.0c152382d7365p1,-2.0943951023931953
+sinh,-0x1.85c40e80e851ap1,-0x1.d524fe24f89f1p0,-1.832595714594046
+sinh,-0x1.2690f661dd82p1,-0x1.921fb54442d18p0,-1.5707963267948966
+sinh,-0x1.b757cf1df30a6p0,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+sinh,-0x1.3fd684deb350ep0,-0x1.0c152382d7365p0,-1.0471975511965976
+sinh,-0x1.bcc270b522736p-1,-0x1.921fb54442d18p-1,-0.7853981633974483
+sinh,-0x1.18804022b2bffp-1,-0x1.0c152382d7365p-1,-0.5235987755982988
+sinh,-0x1.0f27ca7619b64p-2,-0x1.0c152382d7365p-2,-0.2617993877991494
+sinh,0x0.0p0,0x0.0p0,0.0
+sinh,0x1.0f27ca7619b64p-2,0x1.0c152382d7365p-2,0.2617993877991494
+sinh,0x1.18804022b2bffp-1,0x1.0c152382d7365p-1,0.5235987755982988
+sinh,0x1.bcc270b522736p-1,0x1.921fb54442d18p-1,0.7853981633974483
+sinh,0x1.3fd684deb350ep0,0x1.0c152382d7365p0,1.0471975511965976
+sinh,0x1.b757cf1df30a6p0,0x1.4f1a6c638d03fp0,1.3089969389957472
+sinh,0x1.2690f661dd82p1,0x1.921fb54442d18p0,1.5707963267948966
+sinh,0x1.85c40e80e851ap1,0x1.d524fe24f89f1p0,1.832595714594046
+sinh,0x1.ffd51e300fd0ap1,0x1.0c152382d7365p1,2.0943951023931953
+sinh,0x1.4e97178e396ep2,0x1.2d97c7f3321d2p1,2.356194490192345
+sinh,0x1.b453f0b1eaf12p2,0x1.4f1a6c638d03fp1,2.6179938779914944
+sinh,0x1.1c123442e93dep3,0x1.709d10d3e7eabp1,2.8797932657906435
+sinh,0x1.718f45d72e672p3,0x1.921fb54442d18p1,3.141592653589793
+sinh,0x1.e085bdee107a5p3,0x1.b3a259b49db85p1,3.4033920413889427
+sinh,0x1.384dda552babdp4,0x1.d524fe24f89f1p1,3.665191429188092
+sinh,0x1.95dfe166e2a9p4,0x1.f6a7a2955385dp1,3.926990816987241
+sinh,0x1.07b6115af4ac2p5,0x1.0c152382d7365p2,4.1887902047863905
+sinh,0x1.56a9c031162e2p5,0x1.1cd675bb04a9cp2,4.4505895925855405
+sinh,0x1.bd3c34cf00a25p5,0x1.2d97c7f3321d2p2,4.71238898038469
+sinh,0x1.213fbb4f2d33dp6,0x1.3e591a2b5f908p2,4.974188368183839
+sinh,0x1.77d190adc8314p6,0x1.4f1a6c638d03fp2,5.235987755982989
+sinh,0x1.e84b3f43319a6p6,0x1.5fdbbe9bba775p2,5.497787143782138
+sinh,0x1.3d36c80e5d0c7p7,0x1.709d10d3e7eabp2,5.759586531581287
+sinh,0x1.9c25a07506b44p7,0x1.815e630c155e1p2,6.021385919380436
+sinh,0x1.0bbeb1603926ap8,0x1.921fb54442d18p2,6.283185307179586
+sqrt,0x1.a61298e1e069cp0,0x1.5bf0a8b145769p1,2.718281828459045
+sqrt,0x0.0p0,0x0.0p0,0.0
+sqrt,-0x0.0p0,-0x0.0p0,-0.0
+sqrt,0x1.0p0,0x1.0p0,1.0
+sqrt,0x1.6a09e667f3bcdp-1,0x1.0p-1,0.5
+sqrt,0x0.0p0,0x0.0p0,0.0
+sqrt,0x1.05f8bd37c0e62p-1,0x1.0c152382d7365p-2,0.2617993877991494
+sqrt,0x1.727bdd17583bbp-1,0x1.0c152382d7365p-1,0.5235987755982988
+sqrt,0x1.c5bf891b4ef6ap-1,0x1.921fb54442d18p-1,0.7853981633974483
+sqrt,0x1.05f8bd37c0e62p0,0x1.0c152382d7365p0,1.0471975511965976
+sqrt,0x1.24e4a86554ee4p0,0x1.4f1a6c638d03fp0,1.3089969389957472
+sqrt,0x1.40d931ff62705p0,0x1.921fb54442d18p0,1.5707963267948966
+sqrt,0x1.5a8e4f8ccf0dcp0,0x1.d524fe24f89f1p0,1.832595714594046
+sqrt,0x1.727bdd17583bbp0,0x1.0c152382d7365p1,2.0943951023931953
+sqrt,0x1.88f51bd3a1593p0,0x1.2d97c7f3321d2p1,2.356194490192345
+sqrt,0x1.9e36a9c593d0bp0,0x1.4f1a6c638d03fp1,2.6179938779914944
+sqrt,0x1.b26e49c64a5f3p0,0x1.709d10d3e7eabp1,2.8797932657906435
+sqrt,0x1.c5bf891b4ef6ap0,0x1.921fb54442d18p1,3.141592653589793
+sqrt,0x1.d846ad8819ddap0,0x1.b3a259b49db85p1,3.4033920413889427
+sqrt,0x1.ea1aa3667d6bep0,0x1.d524fe24f89f1p1,3.665191429188092
+sqrt,0x1.fb4e4f1347eb8p0,0x1.f6a7a2955385dp1,3.926990816987241
+sqrt,0x1.05f8bd37c0e62p1,0x1.0c152382d7365p2,4.1887902047863905
+sqrt,0x1.0e08c0345b894p1,0x1.1cd675bb04a9cp2,4.4505895925855405
+sqrt,0x1.15dce5d1822ccp1,0x1.2d97c7f3321d2p2,4.71238898038469
+sqrt,0x1.1d7a1aea4fad7p1,0x1.3e591a2b5f908p2,4.974188368183839
+sqrt,0x1.24e4a86554ee4p1,0x1.4f1a6c638d03fp2,5.235987755982989
+sqrt,0x1.2c204f9612dc7p1,0x1.5fdbbe9bba775p2,5.497787143782138
+sqrt,0x1.333060993db51p1,0x1.709d10d3e7eabp2,5.759586531581287
+sqrt,0x1.3a17cc297b8dcp1,0x1.815e630c155e1p2,6.021385919380436
+sqrt,0x1.40d931ff62705p1,0x1.921fb54442d18p2,6.283185307179586
+tan,-0x1.cd5cdb683b402p-2,0x1.5bf0a8b145769p1,2.718281828459045
+tan,0x1.cd5cdb683b402p-2,-0x1.5bf0a8b145769p1,-2.718281828459045
+tan,0x0.0p0,0x0.0p0,0.0
+tan,-0x0.0p0,-0x0.0p0,-0.0
+tan,0x1.8eb245cbee3a6p0,0x1.0p0,1.0
+tan,-0x1.8eb245cbee3a6p0,-0x1.0p0,-1.0
+tan,-0x1.17b4f5bf3474ap-1,-0x1.0p-1,-0.5
+tan,0x1.17b4f5bf3474ap-1,0x1.0p-1,0.5
+tan,0x1.1a62633145c07p-52,-0x1.921fb54442d18p2,-6.283185307179586
+tan,0x1.126145e9ecd66p-2,-0x1.815e630c155e1p2,-6.021385919380436
+tan,0x1.279a745903322p-1,-0x1.709d10d3e7eabp2,-5.759586531581287
+tan,0x1.0000000000002p0,-0x1.5fdbbe9bba775p2,-5.497787143782138
+tan,0x1.bb67ae8584ca9p0,-0x1.4f1a6c638d03fp2,-5.235987755982989
+tan,0x1.ddb3d742c2666p1,-0x1.3e591a2b5f908p2,-4.974188368183839
+tan,-0x1.3570efd768923p52,-0x1.2d97c7f3321d2p2,-4.71238898038469
+tan,-0x1.ddb3d742c2659p1,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+tan,-0x1.bb67ae8584ca2p0,-0x1.0c152382d7365p2,-4.1887902047863905
+tan,-0x1.ffffffffffff5p-1,-0x1.f6a7a2955385dp1,-3.926990816987241
+tan,-0x1.279a745903319p-1,-0x1.d524fe24f89f1p1,-3.665191429188092
+tan,-0x1.126145e9ecd56p-2,-0x1.b3a259b49db85p1,-3.4033920413889427
+tan,0x1.1a62633145c07p-53,-0x1.921fb54442d18p1,-3.141592653589793
+tan,0x1.126145e9ecd5bp-2,-0x1.709d10d3e7eabp1,-2.8797932657906435
+tan,0x1.279a74590331cp-1,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+tan,0x1.0000000000001p0,-0x1.2d97c7f3321d2p1,-2.356194490192345
+tan,0x1.bb67ae8584cafp0,-0x1.0c152382d7365p1,-2.0943951023931953
+tan,0x1.ddb3d742c265ap1,-0x1.d524fe24f89f1p0,-1.832595714594046
+tan,-0x1.d02967c31cdb5p53,-0x1.921fb54442d18p0,-1.5707963267948966
+tan,-0x1.ddb3d742c2656p1,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+tan,-0x1.bb67ae8584ca8p0,-0x1.0c152382d7365p0,-1.0471975511965976
+tan,-0x1.fffffffffffffp-1,-0x1.921fb54442d18p-1,-0.7853981633974483
+tan,-0x1.279a74590331cp-1,-0x1.0c152382d7365p-1,-0.5235987755982988
+tan,-0x1.126145e9ecd56p-2,-0x1.0c152382d7365p-2,-0.2617993877991494
+tan,0x0.0p0,0x0.0p0,0.0
+tan,0x1.126145e9ecd56p-2,0x1.0c152382d7365p-2,0.2617993877991494
+tan,0x1.279a74590331cp-1,0x1.0c152382d7365p-1,0.5235987755982988
+tan,0x1.fffffffffffffp-1,0x1.921fb54442d18p-1,0.7853981633974483
+tan,0x1.bb67ae8584ca8p0,0x1.0c152382d7365p0,1.0471975511965976
+tan,0x1.ddb3d742c2656p1,0x1.4f1a6c638d03fp0,1.3089969389957472
+tan,0x1.d02967c31cdb5p53,0x1.921fb54442d18p0,1.5707963267948966
+tan,-0x1.ddb3d742c265ap1,0x1.d524fe24f89f1p0,1.832595714594046
+tan,-0x1.bb67ae8584cafp0,0x1.0c152382d7365p1,2.0943951023931953
+tan,-0x1.0000000000001p0,0x1.2d97c7f3321d2p1,2.356194490192345
+tan,-0x1.279a74590331cp-1,0x1.4f1a6c638d03fp1,2.6179938779914944
+tan,-0x1.126145e9ecd5bp-2,0x1.709d10d3e7eabp1,2.8797932657906435
+tan,-0x1.1a62633145c07p-53,0x1.921fb54442d18p1,3.141592653589793
+tan,0x1.126145e9ecd56p-2,0x1.b3a259b49db85p1,3.4033920413889427
+tan,0x1.279a745903319p-1,0x1.d524fe24f89f1p1,3.665191429188092
+tan,0x1.ffffffffffff5p-1,0x1.f6a7a2955385dp1,3.926990816987241
+tan,0x1.bb67ae8584ca2p0,0x1.0c152382d7365p2,4.1887902047863905
+tan,0x1.ddb3d742c2659p1,0x1.1cd675bb04a9cp2,4.4505895925855405
+tan,0x1.3570efd768923p52,0x1.2d97c7f3321d2p2,4.71238898038469
+tan,-0x1.ddb3d742c2666p1,0x1.3e591a2b5f908p2,4.974188368183839
+tan,-0x1.bb67ae8584ca9p0,0x1.4f1a6c638d03fp2,5.235987755982989
+tan,-0x1.0000000000002p0,0x1.5fdbbe9bba775p2,5.497787143782138
+tan,-0x1.279a745903322p-1,0x1.709d10d3e7eabp2,5.759586531581287
+tan,-0x1.126145e9ecd66p-2,0x1.815e630c155e1p2,6.021385919380436
+tan,-0x1.1a62633145c07p-52,0x1.921fb54442d18p2,6.283185307179586
+tanh,0x1.fb8f76b1e2ab6p-1,0x1.5bf0a8b145769p1,2.718281828459045
+tanh,-0x1.fb8f76b1e2ab6p-1,-0x1.5bf0a8b145769p1,-2.718281828459045
+tanh,0x0.0p0,0x0.0p0,0.0
+tanh,-0x0.0p0,-0x0.0p0,-0.0
+tanh,0x1.85efab514f394p-1,0x1.0p0,1.0
+tanh,-0x1.85efab514f394p-1,-0x1.0p0,-1.0
+tanh,-0x1.d9353d7568af3p-2,-0x1.0p-1,-0.5
+tanh,0x1.d9353d7568af3p-2,0x1.0p-1,0.5
+tanh,-0x1.ffff15f81f9abp-1,-0x1.921fb54442d18p2,-6.283185307179586
+tanh,-0x1.fffe74ef7ed71p-1,-0x1.815e630c155e1p2,-6.021385919380436
+tanh,-0x1.fffd6518fcf42p-1,-0x1.709d10d3e7eabp2,-5.759586531581287
+tanh,-0x1.fffb9a371a4ddp-1,-0x1.5fdbbe9bba775p2,-5.497787143782138
+tanh,-0x1.fff893980bbap-1,-0x1.4f1a6c638d03fp2,-5.235987755982989
+tanh,-0x1.fff37800ab4eep-1,-0x1.3e591a2b5f908p2,-4.974188368183839
+tanh,-0x1.ffead8c8b7e1ep-1,-0x1.2d97c7f3321d2p2,-4.71238898038469
+tanh,-0x1.ffdc4b203d5d5p-1,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+tanh,-0x1.ffc3bacfc46c5p-1,-0x1.0c152382d7365p2,-4.1887902047863905
+tanh,-0x1.ff9a463bc561p-1,-0x1.f6a7a2955385dp1,-3.926990816987241
+tanh,-0x1.ff5452d7bd334p-1,-0x1.d524fe24f89f1p1,-3.665191429188092
+tanh,-0x1.fede53348bdfbp-1,-0x1.b3a259b49db85p1,-3.4033920413889427
+tanh,-0x1.fe175fa29281p-1,-0x1.921fb54442d18p1,-3.141592653589793
+tanh,-0x1.fcc835d71f5fdp-1,-0x1.709d10d3e7eabp1,-2.8797932657906435
+tanh,-0x1.fa945e2f9ed74p-1,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+tanh,-0x1.f6e20cfaf5241p-1,-0x1.2d97c7f3321d2p1,-2.356194490192345
+tanh,-0x1.f0b411c9f4d9fp-1,-0x1.0c152382d7365p1,-2.0943951023931953
+tanh,-0x1.e670ce4d24dc4p-1,-0x1.d524fe24f89f1p0,-1.832595714594046
+tanh,-0x1.d594fdae482bap-1,-0x1.921fb54442d18p0,-1.5707963267948966
+tanh,-0x1.ba6102fbc2ee2p-1,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+tanh,-0x1.8fb9cd6ec42dap-1,-0x1.0c152382d7365p0,-1.0471975511965976
+tanh,-0x1.4fc441fa6d6d6p-1,-0x1.921fb54442d18p-1,-0.7853981633974483
+tanh,-0x1.ec010e53336dap-2,-0x1.0c152382d7365p-1,-0.5235987755982988
+tanh,-0x1.061f0aa540191p-2,-0x1.0c152382d7365p-2,-0.2617993877991494
+tanh,0x0.0p0,0x0.0p0,0.0
+tanh,0x1.061f0aa540191p-2,0x1.0c152382d7365p-2,0.2617993877991494
+tanh,0x1.ec010e53336dap-2,0x1.0c152382d7365p-1,0.5235987755982988
+tanh,0x1.4fc441fa6d6d6p-1,0x1.921fb54442d18p-1,0.7853981633974483
+tanh,0x1.8fb9cd6ec42dap-1,0x1.0c152382d7365p0,1.0471975511965976
+tanh,0x1.ba6102fbc2ee2p-1,0x1.4f1a6c638d03fp0,1.3089969389957472
+tanh,0x1.d594fdae482bap-1,0x1.921fb54442d18p0,1.5707963267948966
+tanh,0x1.e670ce4d24dc4p-1,0x1.d524fe24f89f1p0,1.832595714594046
+tanh,0x1.f0b411c9f4d9fp-1,0x1.0c152382d7365p1,2.0943951023931953
+tanh,0x1.f6e20cfaf5241p-1,0x1.2d97c7f3321d2p1,2.356194490192345
+tanh,0x1.fa945e2f9ed74p-1,0x1.4f1a6c638d03fp1,2.6179938779914944
+tanh,0x1.fcc835d71f5fdp-1,0x1.709d10d3e7eabp1,2.8797932657906435
+tanh,0x1.fe175fa29281p-1,0x1.921fb54442d18p1,3.141592653589793
+tanh,0x1.fede53348bdfbp-1,0x1.b3a259b49db85p1,3.4033920413889427
+tanh,0x1.ff5452d7bd334p-1,0x1.d524fe24f89f1p1,3.665191429188092
+tanh,0x1.ff9a463bc561p-1,0x1.f6a7a2955385dp1,3.926990816987241
+tanh,0x1.ffc3bacfc46c5p-1,0x1.0c152382d7365p2,4.1887902047863905
+tanh,0x1.ffdc4b203d5d5p-1,0x1.1cd675bb04a9cp2,4.4505895925855405
+tanh,0x1.ffead8c8b7e1ep-1,0x1.2d97c7f3321d2p2,4.71238898038469
+tanh,0x1.fff37800ab4eep-1,0x1.3e591a2b5f908p2,4.974188368183839
+tanh,0x1.fff893980bbap-1,0x1.4f1a6c638d03fp2,5.235987755982989
+tanh,0x1.fffb9a371a4ddp-1,0x1.5fdbbe9bba775p2,5.497787143782138
+tanh,0x1.fffd6518fcf42p-1,0x1.709d10d3e7eabp2,5.759586531581287
+tanh,0x1.fffe74ef7ed71p-1,0x1.815e630c155e1p2,6.021385919380436
+tanh,0x1.ffff15f81f9abp-1,0x1.921fb54442d18p2,6.283185307179586
+ceil,0x1.8p1,0x1.5bf0a8b145769p1,2.718281828459045
+ceil,-0x1.0p1,-0x1.5bf0a8b145769p1,-2.718281828459045
+ceil,0x0.0p0,0x0.0p0,0.0
+ceil,-0x0.0p0,-0x0.0p0,-0.0
+ceil,0x1.0p0,0x1.0p0,1.0
+ceil,-0x1.0p0,-0x1.0p0,-1.0
+ceil,-0x0.0p0,-0x1.0p-1,-0.5
+ceil,0x1.0p0,0x1.0p-1,0.5
+ceil,-0x1.8p2,-0x1.921fb54442d18p2,-6.283185307179586
+ceil,-0x1.8p2,-0x1.815e630c155e1p2,-6.021385919380436
+ceil,-0x1.4p2,-0x1.709d10d3e7eabp2,-5.759586531581287
+ceil,-0x1.4p2,-0x1.5fdbbe9bba775p2,-5.497787143782138
+ceil,-0x1.4p2,-0x1.4f1a6c638d03fp2,-5.235987755982989
+ceil,-0x1.0p2,-0x1.3e591a2b5f908p2,-4.974188368183839
+ceil,-0x1.0p2,-0x1.2d97c7f3321d2p2,-4.71238898038469
+ceil,-0x1.0p2,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+ceil,-0x1.0p2,-0x1.0c152382d7365p2,-4.1887902047863905
+ceil,-0x1.8p1,-0x1.f6a7a2955385dp1,-3.926990816987241
+ceil,-0x1.8p1,-0x1.d524fe24f89f1p1,-3.665191429188092
+ceil,-0x1.8p1,-0x1.b3a259b49db85p1,-3.4033920413889427
+ceil,-0x1.8p1,-0x1.921fb54442d18p1,-3.141592653589793
+ceil,-0x1.0p1,-0x1.709d10d3e7eabp1,-2.8797932657906435
+ceil,-0x1.0p1,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+ceil,-0x1.0p1,-0x1.2d97c7f3321d2p1,-2.356194490192345
+ceil,-0x1.0p1,-0x1.0c152382d7365p1,-2.0943951023931953
+ceil,-0x1.0p0,-0x1.d524fe24f89f1p0,-1.832595714594046
+ceil,-0x1.0p0,-0x1.921fb54442d18p0,-1.5707963267948966
+ceil,-0x1.0p0,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+ceil,-0x1.0p0,-0x1.0c152382d7365p0,-1.0471975511965976
+ceil,-0x0.0p0,-0x1.921fb54442d18p-1,-0.7853981633974483
+ceil,-0x0.0p0,-0x1.0c152382d7365p-1,-0.5235987755982988
+ceil,-0x0.0p0,-0x1.0c152382d7365p-2,-0.2617993877991494
+ceil,0x0.0p0,0x0.0p0,0.0
+ceil,0x1.0p0,0x1.0c152382d7365p-2,0.2617993877991494
+ceil,0x1.0p0,0x1.0c152382d7365p-1,0.5235987755982988
+ceil,0x1.0p0,0x1.921fb54442d18p-1,0.7853981633974483
+ceil,0x1.0p1,0x1.0c152382d7365p0,1.0471975511965976
+ceil,0x1.0p1,0x1.4f1a6c638d03fp0,1.3089969389957472
+ceil,0x1.0p1,0x1.921fb54442d18p0,1.5707963267948966
+ceil,0x1.0p1,0x1.d524fe24f89f1p0,1.832595714594046
+ceil,0x1.8p1,0x1.0c152382d7365p1,2.0943951023931953
+ceil,0x1.8p1,0x1.2d97c7f3321d2p1,2.356194490192345
+ceil,0x1.8p1,0x1.4f1a6c638d03fp1,2.6179938779914944
+ceil,0x1.8p1,0x1.709d10d3e7eabp1,2.8797932657906435
+ceil,0x1.0p2,0x1.921fb54442d18p1,3.141592653589793
+ceil,0x1.0p2,0x1.b3a259b49db85p1,3.4033920413889427
+ceil,0x1.0p2,0x1.d524fe24f89f1p1,3.665191429188092
+ceil,0x1.0p2,0x1.f6a7a2955385dp1,3.926990816987241
+ceil,0x1.4p2,0x1.0c152382d7365p2,4.1887902047863905
+ceil,0x1.4p2,0x1.1cd675bb04a9cp2,4.4505895925855405
+ceil,0x1.4p2,0x1.2d97c7f3321d2p2,4.71238898038469
+ceil,0x1.4p2,0x1.3e591a2b5f908p2,4.974188368183839
+ceil,0x1.8p2,0x1.4f1a6c638d03fp2,5.235987755982989
+ceil,0x1.8p2,0x1.5fdbbe9bba775p2,5.497787143782138
+ceil,0x1.8p2,0x1.709d10d3e7eabp2,5.759586531581287
+ceil,0x1.cp2,0x1.815e630c155e1p2,6.021385919380436
+ceil,0x1.cp2,0x1.921fb54442d18p2,6.283185307179586
+floor,0x1.0p1,0x1.5bf0a8b145769p1,2.718281828459045
+floor,-0x1.8p1,-0x1.5bf0a8b145769p1,-2.718281828459045
+floor,0x0.0p0,0x0.0p0,0.0
+floor,-0x0.0p0,-0x0.0p0,-0.0
+floor,0x1.0p0,0x1.0p0,1.0
+floor,-0x1.0p0,-0x1.0p0,-1.0
+floor,-0x1.0p0,-0x1.0p-1,-0.5
+floor,0x0.0p0,0x1.0p-1,0.5
+floor,-0x1.cp2,-0x1.921fb54442d18p2,-6.283185307179586
+floor,-0x1.cp2,-0x1.815e630c155e1p2,-6.021385919380436
+floor,-0x1.8p2,-0x1.709d10d3e7eabp2,-5.759586531581287
+floor,-0x1.8p2,-0x1.5fdbbe9bba775p2,-5.497787143782138
+floor,-0x1.8p2,-0x1.4f1a6c638d03fp2,-5.235987755982989
+floor,-0x1.4p2,-0x1.3e591a2b5f908p2,-4.974188368183839
+floor,-0x1.4p2,-0x1.2d97c7f3321d2p2,-4.71238898038469
+floor,-0x1.4p2,-0x1.1cd675bb04a9cp2,-4.4505895925855405
+floor,-0x1.4p2,-0x1.0c152382d7365p2,-4.1887902047863905
+floor,-0x1.0p2,-0x1.f6a7a2955385dp1,-3.926990816987241
+floor,-0x1.0p2,-0x1.d524fe24f89f1p1,-3.665191429188092
+floor,-0x1.0p2,-0x1.b3a259b49db85p1,-3.4033920413889427
+floor,-0x1.0p2,-0x1.921fb54442d18p1,-3.141592653589793
+floor,-0x1.8p1,-0x1.709d10d3e7eabp1,-2.8797932657906435
+floor,-0x1.8p1,-0x1.4f1a6c638d03fp1,-2.6179938779914944
+floor,-0x1.8p1,-0x1.2d97c7f3321d2p1,-2.356194490192345
+floor,-0x1.8p1,-0x1.0c152382d7365p1,-2.0943951023931953
+floor,-0x1.0p1,-0x1.d524fe24f89f1p0,-1.832595714594046
+floor,-0x1.0p1,-0x1.921fb54442d18p0,-1.5707963267948966
+floor,-0x1.0p1,-0x1.4f1a6c638d03fp0,-1.3089969389957472
+floor,-0x1.0p1,-0x1.0c152382d7365p0,-1.0471975511965976
+floor,-0x1.0p0,-0x1.921fb54442d18p-1,-0.7853981633974483
+floor,-0x1.0p0,-0x1.0c152382d7365p-1,-0.5235987755982988
+floor,-0x1.0p0,-0x1.0c152382d7365p-2,-0.2617993877991494
+floor,0x0.0p0,0x0.0p0,0.0
+floor,0x0.0p0,0x1.0c152382d7365p-2,0.2617993877991494
+floor,0x0.0p0,0x1.0c152382d7365p-1,0.5235987755982988
+floor,0x0.0p0,0x1.921fb54442d18p-1,0.7853981633974483
+floor,0x1.0p0,0x1.0c152382d7365p0,1.0471975511965976
+floor,0x1.0p0,0x1.4f1a6c638d03fp0,1.3089969389957472
+floor,0x1.0p0,0x1.921fb54442d18p0,1.5707963267948966
+floor,0x1.0p0,0x1.d524fe24f89f1p0,1.832595714594046
+floor,0x1.0p1,0x1.0c152382d7365p1,2.0943951023931953
+floor,0x1.0p1,0x1.2d97c7f3321d2p1,2.356194490192345
+floor,0x1.0p1,0x1.4f1a6c638d03fp1,2.6179938779914944
+floor,0x1.0p1,0x1.709d10d3e7eabp1,2.8797932657906435
+floor,0x1.8p1,0x1.921fb54442d18p1,3.141592653589793
+floor,0x1.8p1,0x1.b3a259b49db85p1,3.4033920413889427
+floor,0x1.8p1,0x1.d524fe24f89f1p1,3.665191429188092
+floor,0x1.8p1,0x1.f6a7a2955385dp1,3.926990816987241
+floor,0x1.0p2,0x1.0c152382d7365p2,4.1887902047863905
+floor,0x1.0p2,0x1.1cd675bb04a9cp2,4.4505895925855405
+floor,0x1.0p2,0x1.2d97c7f3321d2p2,4.71238898038469
+floor,0x1.0p2,0x1.3e591a2b5f908p2,4.974188368183839
+floor,0x1.4p2,0x1.4f1a6c638d03fp2,5.235987755982989
+floor,0x1.4p2,0x1.5fdbbe9bba775p2,5.497787143782138
+floor,0x1.4p2,0x1.709d10d3e7eabp2,5.759586531581287
+floor,0x1.8p2,0x1.815e630c155e1p2,6.021385919380436
+floor,0x1.8p2,0x1.921fb54442d18p2,6.283185307179586
diff --git a/luni/src/test/resources/math_java_only.csv b/luni/src/test/resources/math_java_only.csv
new file mode 100644
index 0000000..7497244
--- /dev/null
+++ b/luni/src/test/resources/math_java_only.csv
@@ -0,0 +1,4132 @@
+#These tests are randomly generated.
+#Many of these test functions specific to java.
+cbrt,-0x1.28c16bdbe5b02p341,-0x1.8ec3beb2d4185p1023
+cbrt,-0x1.2e14b2c0fd516p341,-0x1.a49ea827e7d05p1023
+cbrt,-0x1.5e34a2f636f55p340,-0x1.47afe754a89fep1021
+cbrt,-0x1.f8a0db364f2c1p340,-0x1.ea33b08c7fbfbp1022
+cbrt,0x1.13fe315a92f2fp341,0x1.40c8f2c416881p1023
+cbrt,-0x1.f058cbbc49543p340,-0x1.d2762c5e7c22bp1022
+cbrt,0x1.4785ce183fe27p340,0x1.0c0c8b67b7daep1021
+cbrt,-0x1.250fa24b85fe4p341,-0x1.800e50b80ea85p1023
+cbrt,0x1.377220bf3a7dfp340,0x1.ccf6eeb86909cp1020
+cbrt,-0x1.c98f0eb5c5dcbp340,-0x1.6d6d5ccb7231fp1022
+cbrt,0x1.12ca9d6611445p341,0x1.3c9d1f4fb1b51p1023
+cbrt,-0x1.b8ce4aa4646f8p340,-0x1.46bd646b348a7p1022
+cbrt,0x1.39bb533ac53a5p341,0x1.d730774e9d4c9p1023
+cbrt,0x1.3ee216e720331p341,0x1.eec87765e84c1p1023
+cbrt,0x1.4490997193764p340,0x1.04da2953b2f46p1021
+cbrt,0x1.c37cdb4e17ca4p340,0x1.5f12c97e6cc4fp1022
+cbrt,-0x1.d903a0b4c6addp340,-0x1.93b8dc284f903p1022
+cbrt,-0x1.09f259fb99e2ep341,-0x1.1f03b54fdb6b3p1023
+cbrt,-0x1.1aee008eb2a55p341,-0x1.5995eb7752bb1p1023
+cbrt,-0x1.3734bc7ba5d4p340,-0x1.cbe68c7a0015cp1020
+cbrt,0x1.ed248b63d1995p340,0x1.c97c7a91bfb13p1022
+cbrt,-0x1.2fae8e1a994bdp341,-0x1.ab57cf7150fc7p1023
+cbrt,-0x1.e5dfd116468ddp340,-0x1.b58ddd93bfea3p1022
+cbrt,-0x1.3e1eb876a6e8ap341,-0x1.eb3d3b0b459ffp1023
+cbrt,-0x1.0ac38f307f1edp341,-0x1.21ab226ac9ce9p1023
+cbrt,-0x1.fb71e0cc80f22p340,-0x1.f274aa94c0813p1022
+cbrt,0x1.3bad1837822d4p341,0x1.e0012c863f62bp1023
+cbrt,0x1.fe974a28b759ep340,0x1.fbc8d827034c3p1022
+cbrt,0x1.07f5d2281bd68p341,0x1.18a1877e00a5fp1023
+cbrt,-0x1.b6ca6a7542dd8p340,-0x1.424779e743077p1022
+expm1,-0x1.0p0,-0x1.8ec3beb2d4185p1023
+expm1,-0x1.0p0,-0x1.a49ea827e7d05p1023
+expm1,-0x1.0p0,-0x1.47afe754a89fep1021
+expm1,-0x1.0p0,-0x1.ea33b08c7fbfbp1022
+expm1,Infinity,0x1.40c8f2c416881p1023
+expm1,-0x1.0p0,-0x1.d2762c5e7c22bp1022
+expm1,Infinity,0x1.0c0c8b67b7daep1021
+expm1,-0x1.0p0,-0x1.800e50b80ea85p1023
+expm1,Infinity,0x1.ccf6eeb86909cp1020
+expm1,-0x1.0p0,-0x1.6d6d5ccb7231fp1022
+expm1,Infinity,0x1.3c9d1f4fb1b51p1023
+expm1,-0x1.0p0,-0x1.46bd646b348a7p1022
+expm1,Infinity,0x1.d730774e9d4c9p1023
+expm1,Infinity,0x1.eec87765e84c1p1023
+expm1,Infinity,0x1.04da2953b2f46p1021
+expm1,Infinity,0x1.5f12c97e6cc4fp1022
+expm1,-0x1.0p0,-0x1.93b8dc284f903p1022
+expm1,-0x1.0p0,-0x1.1f03b54fdb6b3p1023
+expm1,-0x1.0p0,-0x1.5995eb7752bb1p1023
+expm1,-0x1.0p0,-0x1.cbe68c7a0015cp1020
+expm1,Infinity,0x1.c97c7a91bfb13p1022
+expm1,-0x1.0p0,-0x1.ab57cf7150fc7p1023
+expm1,-0x1.0p0,-0x1.b58ddd93bfea3p1022
+expm1,-0x1.0p0,-0x1.eb3d3b0b459ffp1023
+expm1,-0x1.0p0,-0x1.21ab226ac9ce9p1023
+expm1,-0x1.0p0,-0x1.f274aa94c0813p1022
+expm1,Infinity,0x1.e0012c863f62bp1023
+expm1,Infinity,0x1.fbc8d827034c3p1022
+expm1,Infinity,0x1.18a1877e00a5fp1023
+expm1,-0x1.0p0,-0x1.424779e743077p1022
+getExponent,0x1.ff8p9,-0x1.8ec3beb2d4185p1023
+getExponent,0x1.ff8p9,-0x1.a49ea827e7d05p1023
+getExponent,0x1.fe8p9,-0x1.47afe754a89fep1021
+getExponent,0x1.ffp9,-0x1.ea33b08c7fbfbp1022
+getExponent,0x1.ff8p9,0x1.40c8f2c416881p1023
+getExponent,0x1.ffp9,-0x1.d2762c5e7c22bp1022
+getExponent,0x1.fe8p9,0x1.0c0c8b67b7daep1021
+getExponent,0x1.ff8p9,-0x1.800e50b80ea85p1023
+getExponent,0x1.fep9,0x1.ccf6eeb86909cp1020
+getExponent,0x1.ffp9,-0x1.6d6d5ccb7231fp1022
+getExponent,0x1.ff8p9,0x1.3c9d1f4fb1b51p1023
+getExponent,0x1.ffp9,-0x1.46bd646b348a7p1022
+getExponent,0x1.ff8p9,0x1.d730774e9d4c9p1023
+getExponent,0x1.ff8p9,0x1.eec87765e84c1p1023
+getExponent,0x1.fe8p9,0x1.04da2953b2f46p1021
+getExponent,0x1.ffp9,0x1.5f12c97e6cc4fp1022
+getExponent,0x1.ffp9,-0x1.93b8dc284f903p1022
+getExponent,0x1.ff8p9,-0x1.1f03b54fdb6b3p1023
+getExponent,0x1.ff8p9,-0x1.5995eb7752bb1p1023
+getExponent,0x1.fep9,-0x1.cbe68c7a0015cp1020
+getExponent,0x1.ffp9,0x1.c97c7a91bfb13p1022
+getExponent,0x1.ff8p9,-0x1.ab57cf7150fc7p1023
+getExponent,0x1.ffp9,-0x1.b58ddd93bfea3p1022
+getExponent,0x1.ff8p9,-0x1.eb3d3b0b459ffp1023
+getExponent,0x1.ff8p9,-0x1.21ab226ac9ce9p1023
+getExponent,0x1.ffp9,-0x1.f274aa94c0813p1022
+getExponent,0x1.ff8p9,0x1.e0012c863f62bp1023
+getExponent,0x1.ffp9,0x1.fbc8d827034c3p1022
+getExponent,0x1.ff8p9,0x1.18a1877e00a5fp1023
+getExponent,0x1.ffp9,-0x1.424779e743077p1022
+log1p,NaN,-0x1.8ec3beb2d4185p1023
+log1p,NaN,-0x1.a49ea827e7d05p1023
+log1p,NaN,-0x1.47afe754a89fep1021
+log1p,NaN,-0x1.ea33b08c7fbfbp1022
+log1p,0x1.62a857235842dp9,0x1.40c8f2c416881p1023
+log1p,NaN,-0x1.d2762c5e7c22bp1022
+log1p,0x1.61dfe7df97bep9,0x1.0c0c8b67b7daep1021
+log1p,NaN,-0x1.800e50b80ea85p1023
+log1p,0x1.61cc940b2d36ap9,0x1.ccf6eeb86909cp1020
+log1p,NaN,-0x1.6d6d5ccb7231fp1022
+log1p,0x1.62a6aa4225779p9,0x1.3c9d1f4fb1b51p1023
+log1p,NaN,-0x1.46bd646b348a7p1022
+log1p,0x1.62d98e12c9f96p9,0x1.d730774e9d4c9p1023
+log1p,0x1.62dfcf19a6049p9,0x1.eec87765e84c1p1023
+log1p,0x1.61dc6c10526cfp9,0x1.04da2953b2f46p1021
+log1p,0x1.625b2a8fb49e6p9,0x1.5f12c97e6cc4fp1022
+log1p,NaN,-0x1.93b8dc284f903p1022
+log1p,NaN,-0x1.1f03b54fdb6b3p1023
+log1p,NaN,-0x1.5995eb7752bb1p1023
+log1p,NaN,-0x1.cbe68c7a0015cp1020
+log1p,0x1.627d0df092aa8p9,0x1.c97c7a91bfb13p1022
+log1p,NaN,-0x1.ab57cf7150fc7p1023
+log1p,NaN,-0x1.b58ddd93bfea3p1022
+log1p,NaN,-0x1.eb3d3b0b459ffp1023
+log1p,NaN,-0x1.21ab226ac9ce9p1023
+log1p,NaN,-0x1.f274aa94c0813p1022
+log1p,0x1.62dbed736c836p9,0x1.e0012c863f62bp1023
+log1p,0x1.628a67fbcd68fp9,0x1.fbc8d827034c3p1022
+log1p,0x1.6297390f32c3p9,0x1.18a1877e00a5fp1023
+log1p,NaN,-0x1.424779e743077p1022
+nextUp,-0x1.8ec3beb2d4184p1023,-0x1.8ec3beb2d4185p1023
+nextUp,-0x1.a49ea827e7d04p1023,-0x1.a49ea827e7d05p1023
+nextUp,-0x1.47afe754a89fdp1021,-0x1.47afe754a89fep1021
+nextUp,-0x1.ea33b08c7fbfap1022,-0x1.ea33b08c7fbfbp1022
+nextUp,0x1.40c8f2c416882p1023,0x1.40c8f2c416881p1023
+nextUp,-0x1.d2762c5e7c22ap1022,-0x1.d2762c5e7c22bp1022
+nextUp,0x1.0c0c8b67b7dafp1021,0x1.0c0c8b67b7daep1021
+nextUp,-0x1.800e50b80ea84p1023,-0x1.800e50b80ea85p1023
+nextUp,0x1.ccf6eeb86909dp1020,0x1.ccf6eeb86909cp1020
+nextUp,-0x1.6d6d5ccb7231ep1022,-0x1.6d6d5ccb7231fp1022
+nextUp,0x1.3c9d1f4fb1b52p1023,0x1.3c9d1f4fb1b51p1023
+nextUp,-0x1.46bd646b348a6p1022,-0x1.46bd646b348a7p1022
+nextUp,0x1.d730774e9d4cap1023,0x1.d730774e9d4c9p1023
+nextUp,0x1.eec87765e84c2p1023,0x1.eec87765e84c1p1023
+nextUp,0x1.04da2953b2f47p1021,0x1.04da2953b2f46p1021
+nextUp,0x1.5f12c97e6cc5p1022,0x1.5f12c97e6cc4fp1022
+nextUp,-0x1.93b8dc284f902p1022,-0x1.93b8dc284f903p1022
+nextUp,-0x1.1f03b54fdb6b2p1023,-0x1.1f03b54fdb6b3p1023
+nextUp,-0x1.5995eb7752bbp1023,-0x1.5995eb7752bb1p1023
+nextUp,-0x1.cbe68c7a0015bp1020,-0x1.cbe68c7a0015cp1020
+nextUp,0x1.c97c7a91bfb14p1022,0x1.c97c7a91bfb13p1022
+nextUp,-0x1.ab57cf7150fc6p1023,-0x1.ab57cf7150fc7p1023
+nextUp,-0x1.b58ddd93bfea2p1022,-0x1.b58ddd93bfea3p1022
+nextUp,-0x1.eb3d3b0b459fep1023,-0x1.eb3d3b0b459ffp1023
+nextUp,-0x1.21ab226ac9ce8p1023,-0x1.21ab226ac9ce9p1023
+nextUp,-0x1.f274aa94c0812p1022,-0x1.f274aa94c0813p1022
+nextUp,0x1.e0012c863f62cp1023,0x1.e0012c863f62bp1023
+nextUp,0x1.fbc8d827034c4p1022,0x1.fbc8d827034c3p1022
+nextUp,0x1.18a1877e00a6p1023,0x1.18a1877e00a5fp1023
+nextUp,-0x1.424779e743076p1022,-0x1.424779e743077p1022
+rint,-0x1.8ec3beb2d4185p1023,-0x1.8ec3beb2d4185p1023
+rint,-0x1.a49ea827e7d05p1023,-0x1.a49ea827e7d05p1023
+rint,-0x1.47afe754a89fep1021,-0x1.47afe754a89fep1021
+rint,-0x1.ea33b08c7fbfbp1022,-0x1.ea33b08c7fbfbp1022
+rint,0x1.40c8f2c416881p1023,0x1.40c8f2c416881p1023
+rint,-0x1.d2762c5e7c22bp1022,-0x1.d2762c5e7c22bp1022
+rint,0x1.0c0c8b67b7daep1021,0x1.0c0c8b67b7daep1021
+rint,-0x1.800e50b80ea85p1023,-0x1.800e50b80ea85p1023
+rint,0x1.ccf6eeb86909cp1020,0x1.ccf6eeb86909cp1020
+rint,-0x1.6d6d5ccb7231fp1022,-0x1.6d6d5ccb7231fp1022
+rint,0x1.3c9d1f4fb1b51p1023,0x1.3c9d1f4fb1b51p1023
+rint,-0x1.46bd646b348a7p1022,-0x1.46bd646b348a7p1022
+rint,0x1.d730774e9d4c9p1023,0x1.d730774e9d4c9p1023
+rint,0x1.eec87765e84c1p1023,0x1.eec87765e84c1p1023
+rint,0x1.04da2953b2f46p1021,0x1.04da2953b2f46p1021
+rint,0x1.5f12c97e6cc4fp1022,0x1.5f12c97e6cc4fp1022
+rint,-0x1.93b8dc284f903p1022,-0x1.93b8dc284f903p1022
+rint,-0x1.1f03b54fdb6b3p1023,-0x1.1f03b54fdb6b3p1023
+rint,-0x1.5995eb7752bb1p1023,-0x1.5995eb7752bb1p1023
+rint,-0x1.cbe68c7a0015cp1020,-0x1.cbe68c7a0015cp1020
+rint,0x1.c97c7a91bfb13p1022,0x1.c97c7a91bfb13p1022
+rint,-0x1.ab57cf7150fc7p1023,-0x1.ab57cf7150fc7p1023
+rint,-0x1.b58ddd93bfea3p1022,-0x1.b58ddd93bfea3p1022
+rint,-0x1.eb3d3b0b459ffp1023,-0x1.eb3d3b0b459ffp1023
+rint,-0x1.21ab226ac9ce9p1023,-0x1.21ab226ac9ce9p1023
+rint,-0x1.f274aa94c0813p1022,-0x1.f274aa94c0813p1022
+rint,0x1.e0012c863f62bp1023,0x1.e0012c863f62bp1023
+rint,0x1.fbc8d827034c3p1022,0x1.fbc8d827034c3p1022
+rint,0x1.18a1877e00a5fp1023,0x1.18a1877e00a5fp1023
+rint,-0x1.424779e743077p1022,-0x1.424779e743077p1022
+signum,-0x1.0p0,-0x1.8ec3beb2d4185p1023
+signum,-0x1.0p0,-0x1.a49ea827e7d05p1023
+signum,-0x1.0p0,-0x1.47afe754a89fep1021
+signum,-0x1.0p0,-0x1.ea33b08c7fbfbp1022
+signum,0x1.0p0,0x1.40c8f2c416881p1023
+signum,-0x1.0p0,-0x1.d2762c5e7c22bp1022
+signum,0x1.0p0,0x1.0c0c8b67b7daep1021
+signum,-0x1.0p0,-0x1.800e50b80ea85p1023
+signum,0x1.0p0,0x1.ccf6eeb86909cp1020
+signum,-0x1.0p0,-0x1.6d6d5ccb7231fp1022
+signum,0x1.0p0,0x1.3c9d1f4fb1b51p1023
+signum,-0x1.0p0,-0x1.46bd646b348a7p1022
+signum,0x1.0p0,0x1.d730774e9d4c9p1023
+signum,0x1.0p0,0x1.eec87765e84c1p1023
+signum,0x1.0p0,0x1.04da2953b2f46p1021
+signum,0x1.0p0,0x1.5f12c97e6cc4fp1022
+signum,-0x1.0p0,-0x1.93b8dc284f903p1022
+signum,-0x1.0p0,-0x1.1f03b54fdb6b3p1023
+signum,-0x1.0p0,-0x1.5995eb7752bb1p1023
+signum,-0x1.0p0,-0x1.cbe68c7a0015cp1020
+signum,0x1.0p0,0x1.c97c7a91bfb13p1022
+signum,-0x1.0p0,-0x1.ab57cf7150fc7p1023
+signum,-0x1.0p0,-0x1.b58ddd93bfea3p1022
+signum,-0x1.0p0,-0x1.eb3d3b0b459ffp1023
+signum,-0x1.0p0,-0x1.21ab226ac9ce9p1023
+signum,-0x1.0p0,-0x1.f274aa94c0813p1022
+signum,0x1.0p0,0x1.e0012c863f62bp1023
+signum,0x1.0p0,0x1.fbc8d827034c3p1022
+signum,0x1.0p0,0x1.18a1877e00a5fp1023
+signum,-0x1.0p0,-0x1.424779e743077p1022
+toDegrees,-Infinity,-0x1.8ec3beb2d4185p1023
+toDegrees,-Infinity,-0x1.a49ea827e7d05p1023
+toDegrees,-Infinity,-0x1.47afe754a89fep1021
+toDegrees,-Infinity,-0x1.ea33b08c7fbfbp1022
+toDegrees,Infinity,0x1.40c8f2c416881p1023
+toDegrees,-Infinity,-0x1.d2762c5e7c22bp1022
+toDegrees,Infinity,0x1.0c0c8b67b7daep1021
+toDegrees,-Infinity,-0x1.800e50b80ea85p1023
+toDegrees,Infinity,0x1.ccf6eeb86909cp1020
+toDegrees,-Infinity,-0x1.6d6d5ccb7231fp1022
+toDegrees,Infinity,0x1.3c9d1f4fb1b51p1023
+toDegrees,-Infinity,-0x1.46bd646b348a7p1022
+toDegrees,Infinity,0x1.d730774e9d4c9p1023
+toDegrees,Infinity,0x1.eec87765e84c1p1023
+toDegrees,Infinity,0x1.04da2953b2f46p1021
+toDegrees,Infinity,0x1.5f12c97e6cc4fp1022
+toDegrees,-Infinity,-0x1.93b8dc284f903p1022
+toDegrees,-Infinity,-0x1.1f03b54fdb6b3p1023
+toDegrees,-Infinity,-0x1.5995eb7752bb1p1023
+toDegrees,-Infinity,-0x1.cbe68c7a0015cp1020
+toDegrees,Infinity,0x1.c97c7a91bfb13p1022
+toDegrees,-Infinity,-0x1.ab57cf7150fc7p1023
+toDegrees,-Infinity,-0x1.b58ddd93bfea3p1022
+toDegrees,-Infinity,-0x1.eb3d3b0b459ffp1023
+toDegrees,-Infinity,-0x1.21ab226ac9ce9p1023
+toDegrees,-Infinity,-0x1.f274aa94c0813p1022
+toDegrees,Infinity,0x1.e0012c863f62bp1023
+toDegrees,Infinity,0x1.fbc8d827034c3p1022
+toDegrees,Infinity,0x1.18a1877e00a5fp1023
+toDegrees,-Infinity,-0x1.424779e743077p1022
+toRadians,-0x1.bd6ca335c8f8bp1017,-0x1.8ec3beb2d4185p1023
+toRadians,-0x1.d5d636d37463cp1017,-0x1.a49ea827e7d05p1023
+toRadians,-0x1.6e07b010242a3p1015,-0x1.47afe754a89fep1021
+toRadians,-0x1.11c7c808a0662p1017,-0x1.ea33b08c7fbfbp1022
+toRadians,0x1.6651facd75f48p1017,0x1.40c8f2c416881p1023
+toRadians,-0x1.048574b80ff57p1017,-0x1.d2762c5e7c22bp1022
+toRadians,0x1.2b69e24b71de8p1015,0x1.0c0c8b67b7daep1021
+toRadians,-0x1.acfe9cbf85fcep1017,-0x1.800e50b80ea85p1023
+toRadians,0x1.0173811fff46ap1015,0x1.ccf6eeb86909cp1020
+toRadians,-0x1.982fa40f44f9ap1016,-0x1.6d6d5ccb7231fp1022
+toRadians,0x1.61a934e496335p1017,0x1.3c9d1f4fb1b51p1023
+toRadians,-0x1.6cf8ccc8ea027p1016,-0x1.46bd646b348a7p1022
+toRadians,0x1.072969315a381p1018,0x1.d730774e9d4c9p1023
+toRadians,0x1.1456c8928aff4p1018,0x1.eec87765e84c1p1023
+toRadians,0x1.235fec19c543cp1015,0x1.04da2953b2f46p1021
+toRadians,0x1.882719ca8a188p1016,0x1.5f12c97e6cc4fp1022
+toRadians,-0x1.c2f640afddd61p1016,-0x1.93b8dc284f903p1022
+toRadians,-0x1.40992763eae48p1017,-0x1.1f03b54fdb6b3p1023
+toRadians,-0x1.8205d95283762p1017,-0x1.5995eb7752bb1p1023
+toRadians,-0x1.00db6068f8009p1015,-0x1.cbe68c7a0015cp1020
+toRadians,0x1.ff045cc909d01p1016,0x1.c97c7a91bfb13p1022
+toRadians,-0x1.dd58c2d344925p1017,-0x1.ab57cf7150fc7p1023
+toRadians,-0x1.e8c0b050f0382p1016,-0x1.b58ddd93bfea3p1022
+toRadians,-0x1.125c16633ee83p1018,-0x1.eb3d3b0b459ffp1023
+toRadians,-0x1.4390148899c34p1017,-0x1.21ab226ac9ce9p1023
+toRadians,-0x1.1663e3e36d831p1017,-0x1.f274aa94c0813p1022
+toRadians,0x1.0c15cb5b07c69p1018,0x1.e0012c863f62bp1023
+toRadians,0x1.1b99b34e2a2c9p1017,0x1.fbc8d827034c3p1022
+toRadians,0x1.3977c2280a1dep1017,0x1.18a1877e00a5fp1023
+toRadians,-0x1.67fd447707815p1016,-0x1.424779e743077p1022
+ulp,0x1.0p971,-0x1.8ec3beb2d4185p1023
+ulp,0x1.0p971,-0x1.a49ea827e7d05p1023
+ulp,0x1.0p969,-0x1.47afe754a89fep1021
+ulp,0x1.0p970,-0x1.ea33b08c7fbfbp1022
+ulp,0x1.0p971,0x1.40c8f2c416881p1023
+ulp,0x1.0p970,-0x1.d2762c5e7c22bp1022
+ulp,0x1.0p969,0x1.0c0c8b67b7daep1021
+ulp,0x1.0p971,-0x1.800e50b80ea85p1023
+ulp,0x1.0p968,0x1.ccf6eeb86909cp1020
+ulp,0x1.0p970,-0x1.6d6d5ccb7231fp1022
+ulp,0x1.0p971,0x1.3c9d1f4fb1b51p1023
+ulp,0x1.0p970,-0x1.46bd646b348a7p1022
+ulp,0x1.0p971,0x1.d730774e9d4c9p1023
+ulp,0x1.0p971,0x1.eec87765e84c1p1023
+ulp,0x1.0p969,0x1.04da2953b2f46p1021
+ulp,0x1.0p970,0x1.5f12c97e6cc4fp1022
+ulp,0x1.0p970,-0x1.93b8dc284f903p1022
+ulp,0x1.0p971,-0x1.1f03b54fdb6b3p1023
+ulp,0x1.0p971,-0x1.5995eb7752bb1p1023
+ulp,0x1.0p968,-0x1.cbe68c7a0015cp1020
+ulp,0x1.0p970,0x1.c97c7a91bfb13p1022
+ulp,0x1.0p971,-0x1.ab57cf7150fc7p1023
+ulp,0x1.0p970,-0x1.b58ddd93bfea3p1022
+ulp,0x1.0p971,-0x1.eb3d3b0b459ffp1023
+ulp,0x1.0p971,-0x1.21ab226ac9ce9p1023
+ulp,0x1.0p970,-0x1.f274aa94c0813p1022
+ulp,0x1.0p971,0x1.e0012c863f62bp1023
+ulp,0x1.0p970,0x1.fbc8d827034c3p1022
+ulp,0x1.0p971,0x1.18a1877e00a5fp1023
+ulp,0x1.0p970,-0x1.424779e743077p1022
+nextUp,-0x1.8ec3beb2d4184p1023,-0x1.8ec3beb2d4185p1023
+nextUp,-0x1.a49ea827e7d04p1023,-0x1.a49ea827e7d05p1023
+nextUp,-0x1.47afe754a89fdp1021,-0x1.47afe754a89fep1021
+nextUp,-0x1.ea33b08c7fbfap1022,-0x1.ea33b08c7fbfbp1022
+nextUp,0x1.40c8f2c416882p1023,0x1.40c8f2c416881p1023
+nextUp,-0x1.d2762c5e7c22ap1022,-0x1.d2762c5e7c22bp1022
+nextUp,0x1.0c0c8b67b7dafp1021,0x1.0c0c8b67b7daep1021
+nextUp,-0x1.800e50b80ea84p1023,-0x1.800e50b80ea85p1023
+nextUp,0x1.ccf6eeb86909dp1020,0x1.ccf6eeb86909cp1020
+nextUp,-0x1.6d6d5ccb7231ep1022,-0x1.6d6d5ccb7231fp1022
+nextUp,0x1.3c9d1f4fb1b52p1023,0x1.3c9d1f4fb1b51p1023
+nextUp,-0x1.46bd646b348a6p1022,-0x1.46bd646b348a7p1022
+nextUp,0x1.d730774e9d4cap1023,0x1.d730774e9d4c9p1023
+nextUp,0x1.eec87765e84c2p1023,0x1.eec87765e84c1p1023
+nextUp,0x1.04da2953b2f47p1021,0x1.04da2953b2f46p1021
+nextUp,0x1.5f12c97e6cc5p1022,0x1.5f12c97e6cc4fp1022
+nextUp,-0x1.93b8dc284f902p1022,-0x1.93b8dc284f903p1022
+nextUp,-0x1.1f03b54fdb6b2p1023,-0x1.1f03b54fdb6b3p1023
+nextUp,-0x1.5995eb7752bbp1023,-0x1.5995eb7752bb1p1023
+nextUp,-0x1.cbe68c7a0015bp1020,-0x1.cbe68c7a0015cp1020
+nextUp,0x1.c97c7a91bfb14p1022,0x1.c97c7a91bfb13p1022
+nextUp,-0x1.ab57cf7150fc6p1023,-0x1.ab57cf7150fc7p1023
+nextUp,-0x1.b58ddd93bfea2p1022,-0x1.b58ddd93bfea3p1022
+nextUp,-0x1.eb3d3b0b459fep1023,-0x1.eb3d3b0b459ffp1023
+nextUp,-0x1.21ab226ac9ce8p1023,-0x1.21ab226ac9ce9p1023
+nextUp,-0x1.f274aa94c0812p1022,-0x1.f274aa94c0813p1022
+nextUp,0x1.e0012c863f62cp1023,0x1.e0012c863f62bp1023
+nextUp,0x1.fbc8d827034c4p1022,0x1.fbc8d827034c3p1022
+nextUp,0x1.18a1877e00a6p1023,0x1.18a1877e00a5fp1023
+nextUp,-0x1.424779e743076p1022,-0x1.424779e743077p1022
+expm1,-0x1.9cce617760b86p-1,-0x1.a428e298f71edp0
+expm1,-0x1.c31b9fecb2667p-1,-0x1.108a530fc0d2p1
+expm1,0x1.d84cfb46444c3p1,0x1.8b9f5d1de5c3dp0
+expm1,-0x1.be3c4e9d3d4bp-1,-0x1.06affbb00d98fp1
+expm1,0x1.488d1a8fb117fp-1,0x1.fba17da5f8b4p-2
+expm1,0x1.4f362dab45f2cp-2,0x1.21fc1ec020265p-2
+expm1,-0x1.f6037ebeb4cc2p-1,-0x1.f7f314af56e93p1
+expm1,0x1.8c60ee23a58bdp0,0x1.def2ff6a5a047p-1
+expm1,0x1.2fb26016d86a5p-3,0x1.1b2f14c6ae1c5p-3
+expm1,0x1.17a5f93a6bfb8p0,0x1.7a0282d891ad3p-1
+expm1,0x1.113b136256129p-2,0x1.e4622024c81ebp-3
+expm1,0x1.7ff45eaad7988p24,0x1.10a770e97d9e7p4
+expm1,0x1.8a9d18e586db4p-2,0x1.4dc9651946b7ap-2
+expm1,0x1.3dc4de5d5ab42p-1,0x1.ee6915f64a79cp-2
+expm1,0x1.2a8d7c3f893fdp1,0x1.34260cf244cdp0
+expm1,0x1.6ab8fa5d2e61p1,0x1.5806777a3c3p0
+expm1,-0x1.79481038a9e3ep-5,-0x1.823ee1dc7fe48p-5
+expm1,0x1.555c872c09367p-3,0x1.3bb984b9c4954p-3
+expm1,0x1.0407e741c6d8ep-2,0x1.cf6feff705532p-3
+expm1,-0x1.08bae127926d4p-1,-0x1.74a7eff601cdcp-1
+expm1,0x1.50a2c9ded20fep23,0x1.0375984fb2281p4
+expm1,0x1.f6f4625d227dfp4,0x1.bd5755943de38p1
+expm1,0x1.d1d886cfed521p0,0x1.0960da57be582p0
+expm1,0x1.7fb6c0fe4b3f4p-3,0x1.5fb557ca64795p-3
+expm1,-0x1.e71cda74e9a52p-3,-0x1.1620bd9fc350fp-2
+expm1,-0x1.8e3322ce2ba4dp-1,-0x1.80fe46017449cp0
+expm1,-0x1.498d5bb3c3d3fp-1,-0x1.0828010a23fap0
+expm1,0x1.67234fceaea03p-1,0x1.101d9566db9cdp-1
+expm1,-0x1.db7e672db7ed9p-1,-0x1.520717e55c7cep1
+expm1,0x1.675c1aa18e11p3,0x1.407f835a98e74p1
+expm1,-0x1.6fb54f7ee5624p-2,-0x1.c78b0c72df77bp-2
+expm1,-0x1.ef6a015b45da5p-1,-0x1.b702b9b97b225p1
+expm1,0x1.fd8f7e7d22f9fp12,0x1.2033482ef147cp3
+expm1,0x1.347088405765ep-3,0x1.1f4f60b28d4b2p-3
+expm1,-0x1.91c228406494ep-1,-0x1.892064e9fbe38p0
+expm1,-0x1.c378b0f9be9ebp-1,-0x1.114e8b4e47b56p1
+expm1,0x1.0c37fefe1bd74p-1,0x1.af5c13c6cc9dp-2
+expm1,0x1.28663408d756bp-5,0x1.2329bed5f8384p-5
+expm1,0x1.89088de6f271ep-5,0x1.7fe5679450e6cp-5
+expm1,-0x1.6b946b2a63306p-1,-0x1.3cffb74d9883ap0
+expm1,0x1.65198db542bp3,0x1.3fc1bdbc5959bp1
+expm1,0x1.b4d62828103c6p0,0x1.fdc177ce6b2fp-1
+expm1,-0x1.a933d54962e62p-1,-0x1.c655c955055a4p0
+expm1,-0x1.4d9b515febaf6p-1,-0x1.0de8d59773e34p0
+expm1,0x1.1c1cfbfabe627p0,0x1.7e4287e158391p-1
+expm1,-0x1.783de8234820fp-1,-0x1.53d3b9e746ce5p0
+expm1,0x1.8782f9dfef649p25,0x1.1c0e68278cbe8p4
+expm1,-0x1.2c4d9740abd87p-1,-0x1.c42ebb78fbe73p-1
+expm1,0x1.45891e11d7d3ep0,0x1.a417e40cf4b43p-1
+expm1,0x1.50d809895a98ep24,0x1.0e8f417663934p4
+expm1,-0x1.ac7b2ffccc578p-4,-0x1.c496f63767e31p-4
+expm1,0x1.23f9698df255ep1,0x1.302b763fe6981p0
+expm1,-0x1.372fb3a1c8b16p-1,-0x1.df34782f9a1a5p-1
+expm1,0x1.31989d562b56ep3,0x1.2d95289794af2p1
+expm1,0x1.1a5b54e16683ap-1,0x1.c1bfc1f99f2e4p-2
+expm1,0x1.24deab3524f3bp0,0x1.867e7e0cc218ep-1
+expm1,0x1.4a933382051b6p0,0x1.a882d2b39ac55p-1
+expm1,-0x1.205716f69f914p-1,-0x1.a809a09f4f09bp-1
+expm1,0x1.59caf3c696abcp4,0x1.8f2a729c39e94p1
+expm1,0x1.e4d273a09d1f6p1,0x1.90e848d448a5cp0
+expm1,0x1.8e9c29fbb3306p-2,0x1.50aad6a5c5abp-2
+expm1,0x1.0ff80a690234ep-1,0x1.b4451257c6c54p-2
+expm1,0x1.0a404fd922ddp7,0x1.39858ee3507c2p2
+expm1,0x1.85a6937fa51d4p-6,0x1.8116e6578fb2dp-6
+expm1,-0x1.3afb4d3f1fe44p-1,-0x1.e8f9655fdf834p-1
+expm1,0x1.9e3df7b42b57bp4,0x1.a5585e10e1aa9p1
+expm1,-0x1.694462acf4144p-2,-0x1.bd8acde22cb7ap-2
+expm1,0x1.f89157586270bp0,0x1.16c158baaac49p0
+expm1,0x1.c988d67b49f5p-3,0x1.9cf4962ba6c93p-3
+expm1,0x1.6912956ef46f2p1,0x1.5729bdac949ffp0
+expm1,0x1.976bd3c015fd5p0,0x1.e78b094b3102ap-1
+expm1,0x1.8ff8984c9a5e9p3,0x1.4d22bdcf14f59p1
+expm1,0x1.20d1be1acf74ap0,0x1.82b3a24c13b11p-1
+expm1,-0x1.d693360e8c6aep-1,-0x1.41d934d83ecacp1
+expm1,0x1.ef46f146273dap0,0x1.139bdec0344acp0
+expm1,0x1.6f6a2734bc0cp-3,0x1.51ef54872e016p-3
+expm1,0x1.6d57ad055f3aap-4,0x1.5df51d8826a33p-4
+expm1,-0x1.21951d9534acfp-1,-0x1.aae3adbfd838dp-1
+expm1,0x1.24a9441e3b6b6p1,0x1.3096916641fcdp0
+expm1,-0x1.11ec382c1c485p-1,-0x1.880dad5ffc433p-1
+expm1,-0x1.2cf8056959716p-1,-0x1.c5cb938de2e43p-1
+expm1,0x1.e78acec13ab66p-3,0x1.b5567396909d5p-3
+expm1,0x1.0acdf96f8a344p1,0x1.20592c22f0e12p0
+expm1,0x1.0aae10d4f76f2p0,0x1.6d7620cd67311p-1
+expm1,-0x1.fff141245875cp-1,-0x1.22f64374a5fefp3
+expm1,-0x1.704270d7d5b56p-2,-0x1.c8675818dde29p-2
+expm1,0x1.0ea5330cfe07cp8,0x1.66b0150f95df3p2
+expm1,-0x1.110b939bd2f2cp-1,-0x1.862b74fd88896p-1
+expm1,-0x1.6d35632ffa269p-1,-0x1.3fd2e487b56e7p0
+expm1,-0x1.dfa7e2e9baa38p-2,-0x1.438717b32225cp-1
+expm1,0x1.70d19617dce74p-4,0x1.6125d50ed9678p-4
+expm1,-0x1.7580ffd64dce4p-1,-0x1.4eb72c14c261fp0
+expm1,0x1.24db28dd6a517p1,0x1.30b4eca7db93dp0
+expm1,-0x1.21e6aac0620bcp-2,-0x1.54d0dac99524ep-2
+expm1,-0x1.bfe1f0bc058ccp-1,-0x1.09ef1385af04ep1
+expm1,-0x1.fbfdbe07160d3p-1,-0x1.3663949103991p2
+expm1,0x1.b8c985fd94ab2p-4,0x1.a2a513214cf08p-4
+expm1,-0x1.d6bb18b6e1ceep-1,-0x1.4254ae7d34b85p1
+expm1,0x1.26e534694e3fap6,0x1.141548c4753dcp2
+expm1,-0x1.ffffffffec6fdp-1,-0x1.9720442923732p4
+expm1,-0x1.ff5ad1e90c8c8p-1,-0x1.ab4b38457d0ebp2
+expm1,-0x1.1854a1c9511f8p-3,-0x1.2d781c2629e67p-3
+expm1,0x1.49ae4bd04aec5p-2,0x1.1dcf3fe420e8cp-2
+expm1,0x1.64b8d50747509p1,0x1.54e02692fbe63p0
+expm1,-0x1.93a152134879dp-1,-0x1.8d82a61085183p0
+expm1,0x1.5eb4a9cb49518p-4,0x1.507f4aea5278ep-4
+expm1,-0x1.60ed8908acc26p-3,-0x1.835b0033fa82ap-3
+expm1,0x1.894401e1471aep5,0x1.f524b041d6afep1
+expm1,0x1.5e7713610bc9p4,0x1.90ceeb59d2e65p1
+expm1,0x1.1a9381803652ep18,0x1.9269de86ceb5bp3
+expm1,0x1.84df8f292531dp-1,0x1.214ceb7bf4fe3p-1
+expm1,0x1.af8deb21df20dp31,0x1.60280da9f724p4
+expm1,-0x1.f3c026d29d55ep-1,-0x1.ddcdee9ac0aedp1
+expm1,-0x1.8c475f33dd3cdp-1,-0x1.7cb5417d1500cp0
+expm1,0x1.eaf808c699c4p1,0x1.93765b7874f94p0
+expm1,-0x1.3f9c68880e8dp-2,-0x1.7f1ed1aa3dfbep-2
+expm1,0x1.028b61870c1ebp13,0x1.20ab69b28a6f2p3
+expm1,-0x1.e29e39ada503bp-1,-0x1.6dd121a3784ecp1
+expm1,0x1.d44a26593915ap-1,0x1.4c8e56d4b38f6p-1
+expm1,0x1.a12b346528777p-2,0x1.5df08a69ffa25p-2
+expm1,0x1.de99015a25355p0,0x1.0ddc7b316f55cp0
+expm1,-0x1.4751ce9f04508p-3,-0x1.64a58d2d3d862p-3
+expm1,0x1.c1f8914a16a78p0,0x1.03af8005e67f4p0
+expm1,0x1.1eac11460d1ddp0,0x1.80ae0cd2144f9p-1
+expm1,0x1.d5625b899ba64p0,0x1.0aa15159453cap0
+expm1,-0x1.b2d1ac357493fp-2,-0x1.1b0087f018c8ep-1
+expm1,0x1.519ad3e7f43aep0,0x1.ae9c503c2cb75p-1
+expm1,-0x1.fff8c6ad7f403p-1,-0x1.39cb9cb664d73p3
+expm1,0x1.051e09bc2e036p-1,0x1.a5ff2b458f59p-2
+expm1,0x1.9d35b26f2f0ecp-1,0x1.2ef2c216d36d7p-1
+expm1,0x1.6ddab7f791d8ep1,0x1.59a763b7ec024p0
+expm1,0x1.bdd26e12355b2p0,0x1.022d35d7df995p0
+expm1,-0x1.ed601aef58865p-1,-0x1.a82bf8e819c95p1
+expm1,-0x1.37184d31e17ecp-2,-0x1.72d082e93cd4dp-2
+expm1,0x1.daa52813f98e3p0,0x1.0c7ae8f0e2dadp0
+expm1,0x1.e17ce6f653039p1,0x1.8f82bfe855b11p0
+expm1,-0x1.acc878996cb32p-1,-0x1.d11ea87778deap0
+expm1,-0x1.7f2d6f558e874p-2,-0x1.dff7f18b3eb8dp-2
+expm1,0x1.019a0c524a6d4p4,0x1.6b6721fb77d64p1
+expm1,0x1.2eee056e6be7fp0,0x1.8fcb18f982104p-1
+expm1,-0x1.ee02c1c1f29a4p-1,-0x1.ac9d546d777f1p1
+expm1,0x1.e0f8520e3f74fp7,0x1.5f27da12948d5p2
+expm1,-0x1.fa51f9013364ep-1,-0x1.2017185e263aap2
+expm1,-0x1.fffff347e2e97p-1,-0x1.d9235e1b7a5a9p3
+expm1,-0x1.4fadeda3c8741p-1,-0x1.10e6bc2ddc52p0
+expm1,-0x1.8374a531bf374p-1,-0x1.69e5ccaf5364fp0
+expm1,-0x1.f243817ff9248p-1,-0x1.cf23dfadf368ep1
+expm1,0x1.87df0d951cb24p-2,0x1.4bce259942fcap-2
+expm1,-0x1.fd7cf4a0733a6p-1,-0x1.544e73656c7d8p2
+expm1,-0x1.fffffffdd8918p-1,-0x1.61b44adda7663p4
+expm1,0x1.3de6ebcb26012p-1,0x1.ee931b172020ap-2
+expm1,-0x1.ffffb1a5737ap-1,-0x1.9ef551cf59b37p3
+expm1,0x1.07d0e99a02bc2p-2,0x1.d57736189731ap-3
+expm1,0x1.a44f8299e564cp0,0x1.f1652af1430b5p-1
+expm1,0x1.bf47a56b4930ep0,0x1.02b5348d41e5bp0
+expm1,-0x1.9eb51a0d87adbp-1,-0x1.a91d363e50b44p0
+expm1,-0x1.77ca3c0fe0726p-1,-0x1.52f9f6f4c9acp0
+expm1,0x1.166de4ef3d416p1,0x1.27c6f62d2c468p0
+expm1,0x1.08f3ece97b06ap0,0x1.6bc44e11565c8p-1
+expm1,-0x1.23a705dc834e6p-2,-0x1.5743044c93751p-2
+expm1,0x1.b6edc05359a9bp-1,0x1.3cfc92a47c822p-1
+expm1,-0x1.3993741effd9bp-1,-0x1.e555903f9fc13p-1
+expm1,0x1.92613113c8a48p2,0x1.fc7228bab038bp0
+expm1,-0x1.7755e7311d1aep-1,-0x1.521fb0710abc3p0
+expm1,0x1.1a21c198f89bep1,0x1.2a194b3e5d53ep0
+expm1,-0x1.c9d0eaca3311bp-4,-0x1.e57bc924e2f2dp-4
+expm1,-0x1.febb541b2821dp-1,-0x1.800b46e48f2b6p2
+expm1,-0x1.ffc5b8ba75354p-1,-0x1.edf824a841cdbp2
+expm1,0x1.2cfdd76a7d35fp12,0x1.0f5b2a5d63f27p3
+expm1,-0x1.dcf1c5cf2184cp-2,-0x1.40fbd7c074ceap-1
+expm1,-0x1.f1ff96299ef96p-2,-0x1.5513e8d699d37p-1
+expm1,0x1.f428621e562fap1,0x1.973c1debbda23p0
+expm1,0x1.16ea64da4a6fp-1,0x1.bd4dae186e0dap-2
+expm1,-0x1.558389c108432p-1,-0x1.1983ffafcc07ap0
+expm1,0x1.235fb25f5a3cap0,0x1.8518c2271a4efp-1
+expm1,-0x1.73ac79e363b7bp-4,-0x1.85a1b57606f2dp-4
+expm1,-0x1.82d81ce50142ep-1,-0x1.68a4d5e78b7e3p0
+expm1,0x1.f581bb202cb26p-4,0x1.d919f2643fc6ep-4
+expm1,-0x1.6986e8c578466p-3,-0x1.8dc57cf5061e6p-3
+expm1,-0x1.352b3b5f86f8p-1,-0x1.da163c15bcbcbp-1
+expm1,-0x1.51f36d5848994p-1,-0x1.14387fc6f05bbp0
+expm1,-0x1.c08862cefbe94p-1,-0x1.0b3d0dd5bcb51p1
+expm1,-0x1.a6fdd18c77ce1p-1,-0x1.bfe54b897ab48p0
+expm1,-0x1.715d4d5a12f71p-1,-0x1.472d19c0097fp0
+expm1,0x1.25c83b0e671c1p0,0x1.87582f2251831p-1
+expm1,-0x1.0p0,-0x1.6d094519728eep5
+expm1,0x1.ac3d6de48d199p-3,0x1.84de863d16378p-3
+expm1,-0x1.0p0,-0x1.399ead5a292dcp6
+expm1,-0x1.2f6eb3e922f15p-1,-0x1.cbceb9f83bfb9p-1
+expm1,-0x1.2b7be3da57f59p-1,-0x1.c23489eca97bp-1
+expm1,0x1.8897fbecee0f6p8,0x1.7e6ba0eb82ac8p2
+expm1,0x1.af2c7f9a305b7p-8,0x1.adc2f9e2071fdp-8
+expm1,-0x1.bad097ccf9d39p-2,-0x1.21ff7db3be30ep-1
+expm1,0x1.76d7bf831b3ap13,0x1.2c8def13c5c46p3
+expm1,-0x1.e34e24d9fde43p-3,-0x1.13a212e510428p-2
+expm1,0x1.812e3302714c6p0,0x1.d615987472fadp-1
+expm1,-0x1.f327d02c5f307p-2,-0x1.56349189bf5c1p-1
+expm1,-0x1.8fc27592d306bp-4,-0x1.a4a3312901e9ep-4
+expm1,-0x1.060664c4e8ff6p-1,-0x1.6f15dac9569f1p-1
+expm1,0x1.1b42f11d89058p-2,0x1.f4288b79c0776p-3
+pow,NaN,-0x1.3543856880754p-1,0x1.35716fc87723bp0
+pow,0x1.1d4a986c89024p0,0x1.43ced9e886399p-3,-0x1.e126d87d20ed6p-5
+pow,0x1.522cbcdf959dep1,0x1.3c7d675466f15p-1,-0x1.0284cd3f0c777p1
+pow,0x1.b9bb1a3e302d4p4,0x1.5b6d1c408c6b9p-3,-0x1.decec1eac9a7cp0
+pow,0x1.73657e5443b04p15,0x1.b14dd1bdae0bp2,0x1.685fb1288c6ebp2
+pow,0x1.42aabebdcc329p-3,0x1.dbac3718db8c6p2,-0x1.d7b5616fb60a8p-1
+pow,NaN,-0x1.02396705ce823p1,-0x1.8534721a7fab8p-1
+pow,0x1.0d1bfde3040d9p0,0x1.0bcf497703256p0,0x1.1b7acc031c2b8p0
+pow,NaN,-0x1.673a84a184115p-1,0x1.da2090fb36b4ap0
+pow,NaN,-0x1.0acacaef8fc6ap0,-0x1.608b00fd22779p-1
+pow,NaN,-0x1.31a1f56d0d76cp0,-0x1.8ee0c2486c56cp-3
+pow,0x1.5833b6886737cp8,0x1.6cbf4ee77bc2bp8,0x1.faf7da80b95ap-1
+pow,0x1.8b0d0db11da52p-2,0x1.0c796357a15bap3,-0x1.ca895d25c2f87p-2
+pow,NaN,-0x1.9557e8d5ff0a4p3,0x1.53602f904ab43p-1
+pow,NaN,-0x1.e33ddb97a2aa5p-1,-0x1.de3bf71f3e726p-4
+pow,0x1.f9cdb40f437b6p1,0x1.023eb1fa2e356p-2,-0x1.feb82de9ff0a9p-1
+pow,NaN,-0x1.0d703b600d22ap-1,0x1.0f8b218cb4213p1
+pow,0x1.beac94ab9f868p-2,0x1.0e80760e867b5p1,-0x1.1bd8f6483defap0
+pow,NaN,-0x1.67450003d3a11p1,-0x1.2d82492ed37bap-4
+pow,0x1.206859cb610d6p0,0x1.230e63e0b0af4p1,0x1.292a06365effep-3
+pow,NaN,-0x1.e8c208b279e31p1,-0x1.db752e355f602p-1
+pow,NaN,-0x1.4129bf9beb84ep-1,-0x1.b18d8d5a363bap5
+pow,0x1.6ddd050ff85d3p0,0x1.9c311e9bc98dp-2,-0x1.91d2ce7ba1c81p-2
+pow,NaN,-0x1.6cdde918c6bb7p1,-0x1.13660ce5486d7p1
+pow,NaN,-0x1.d8a622fb32304p-1,-0x1.e3d8cb360b95cp0
+pow,NaN,-0x1.1f6deb57fbf3ep2,0x1.71a34e498178ep1
+pow,NaN,-0x1.aca945800269dp-1,0x1.246c80ddde002p5
+pow,0x1.f6fb38b81fe63p-1,0x1.f9269e1b13d24p-1,0x1.51d06818109ecp0
+pow,NaN,-0x1.70b5d7bc0df1ep2,0x1.1f8857556cb22p-1
+pow,0x1.be5f7398575d1p-1,0x1.89ddac959f5c5p0,-0x1.46063f0f1fd94p-2
+pow,NaN,-0x1.052522d976421p0,-0x1.576e0648a6313p-1
+pow,NaN,-0x1.c610ba3656ed4p-2,0x1.cc5ea57d50651p-2
+pow,NaN,-0x1.3b298780eaf4bp0,-0x1.9e4a93144fbf4p-2
+pow,0x1.3405a5acb927ep-1,0x1.31f27c400e9c7p0,-0x1.6cee77b97b391p1
+pow,NaN,-0x1.d4cc72dde98bdp0,-0x1.4c12bfe6381cbp-1
+pow,NaN,-0x1.a6654edf4e215p-1,-0x1.4cfa4851698bbp0
+pow,0x1.19cce90d83238p-146,0x1.5fd6a4426b0edp3,-0x1.515f384fdff55p5
+pow,NaN,-0x1.1b6e4a199b791p3,0x1.34e2a9b51e552p0
+pow,0x1.b1ab929e7ffdep-2,0x1.0231b33713194p1,-0x1.3976d1457c252p0
+pow,0x1.50d9f2fe33c7p-3,0x1.dde75639ea142p0,-0x1.721d427b01b2p1
+pow,0x1.0c7b1dd03f4b5p-4,0x1.7e424718ff1fdp-6,0x1.73435e4223861p-1
+pow,0x1.e130ed2ab279ap-3,0x1.674d21afc87dcp2,-0x1.add1aebe71ca4p-1
+pow,0x1.60dc514240fe2p0,0x1.ef54ddeb53ad2p-2,-0x1.c475f576d0f2dp-2
+pow,NaN,-0x1.012aeea2abd2ap0,0x1.2392fbe81d72cp-2
+pow,0x1.4f079d2764c28p7,0x1.6887b16643f58p-1,-0x1.d3364956d4d5cp3
+pow,0x1.9b8abb1d635b7p-2,0x1.cf76925768938p-6,0x1.05cf3eadaebdcp-2
+pow,NaN,-0x1.35634d0706b66p0,-0x1.22acb280acafdp0
+pow,0x1.f78cf9a9f2a4cp1,0x1.3e469a290341p1,0x1.80ef0426de88cp0
+pow,NaN,-0x1.9be8a4e6909dcp1,-0x1.901663cbb84fep-3
+pow,NaN,-0x1.1b2752600a802p-2,-0x1.da6c7a226c522p-1
+pow,NaN,-0x1.5fd774062642fp-2,0x1.886753a936a35p2
+pow,0x1.3edebd5811a14p-2,0x1.f20639aad80eap3,-0x1.b33cc11620f11p-2
+pow,0x1.fb715a6f77759p-1,0x1.ea47747e9fbf6p-1,0x1.a6639ae10617ep-3
+pow,0x1.17099bd97d53p-1,0x1.1138cc352d8dbp1,-0x1.99da752c2b32ap-1
+pow,NaN,-0x1.042cb9e40a3c3p1,-0x1.40cd562224abcp-1
+pow,NaN,-0x1.1c50c06fa3246p1,-0x1.31cef7cdd7413p0
+pow,0x1.ad60687187bfp0,0x1.3883a387b687cp-1,-0x1.0c2d4d6d96bb2p0
+pow,NaN,-0x1.a4f79c9fb339ep-4,0x1.59da8f5b4a73ep-2
+pow,NaN,-0x1.4c934c90f450ap0,0x1.5536d4aef0549p-2
+pow,NaN,-0x1.ad336d4adc286p-1,0x1.58ca22de47548p2
+pow,0x1.1c20079b73d21p0,0x1.840da607c2a5ap1,0x1.80f3df570f788p-4
+pow,0x1.7fb0f215b758ep0,0x1.b7b453bf4d92ap-4,-0x1.735b8374b0c87p-3
+pow,NaN,-0x1.fcab6aae1796fp-2,-0x1.780f83d5141cep-1
+pow,0x1.69c9ece38bf9cp3,0x1.3ae7171e64493p-3,-0x1.4b9afac6a55e4p0
+pow,0x1.0a21f58dbc366p-1,0x1.7a545c00cb271p0,-0x1.acdcac99c85abp0
+pow,NaN,-0x1.3e08913f9f21fp-3,0x1.81e633124343p-1
+pow,0x1.d2cb35b746486p-1,0x1.e695c53b4eeaep-6,0x1.aea9911568678p-6
+pow,0x1.0dbb3a7334225p0,0x1.6675cb29a0c1p0,0x1.3ddd7059c104cp-3
+pow,NaN,-0x1.070c2fa9e6802p1,0x1.9112142d4e9dcp-1
+pow,0x1.0a902bf5722d5p0,0x1.447dceaefa645p-1,-0x1.6b248caf29d8dp-4
+pow,0x1.1330f22590c4ap1,0x1.d72e780e0abfep-2,-0x1.f8e198dc7ba8ap-1
+pow,0x1.05b20b0a7d5c5p-3,0x1.a08b5114d4794p-3,0x1.4ab6ce7f2d8d9p0
+pow,NaN,-0x1.6cb5596f5bccap-1,-0x1.e026f2be2c735p-6
+pow,NaN,-0x1.bff74445e3f44p1,0x1.ff1d828a8f9fdp-2
+pow,0x1.bb29b1a0d9593p-1,0x1.19280f7df4f31p0,-0x1.8a574b3c6c21fp0
+pow,0x1.515d6f04001f2p0,0x1.8d40690d3afa9p1,0x1.f3137043bca52p-3
+pow,0x1.e69a356a6053p-1,0x1.e6272faa3e942p-1,0x1.f6de8fe572b0ep-1
+pow,0x1.de90ff863552cp-9,0x1.9d5d54f838bcp2,-0x1.811f7d5c9582p1
+pow,NaN,-0x1.023f6037d59cfp2,-0x1.4dfb18419fccp-2
+pow,NaN,-0x1.1cc20d156cb79p-1,0x1.459252a9af3d3p-2
+pow,0x1.d9135c8e48446p1,0x1.eb6de3ef8ffdfp-6,-0x1.7db8a8d7ce896p-2
+pow,0x1.0bfa0812358ap0,0x1.cb17ab770fd1ep-1,-0x1.ad40b171d56aep-2
+pow,NaN,-0x1.a8b99e1b72634p2,0x1.34643c33653d7p0
+pow,0x1.51a6995175d4ep-6,0x1.4708da39879c3p0,-0x1.fb4623599a3d8p3
+pow,0x1.0edaeef4b9561p0,0x1.0dbb2725712a2p0,0x1.1460b8658035p0
+pow,NaN,-0x1.045318f41eb9ap-1,-0x1.39c26e9f74658p-1
+pow,0x1.06c00c0bbad58p0,0x1.e5d8aef9c4c71p-1,-0x1.fc4b3bfffb0bcp-2
+pow,0x1.947f16f7e69b2p2,0x1.043dc775b7b51p3,0x1.c269498ff8d8ap-1
+pow,NaN,-0x1.5c12f7f31b4c3p-3,0x1.bfe15378a1e56p-3
+pow,NaN,-0x1.1f0cc14e65be8p0,-0x1.2f686c552f4bap-3
+pow,0x1.96a6a076abc92p1,0x1.fb9f996009b44p0,0x1.b04577c9d132dp0
+pow,NaN,-0x1.9033f9bf4d8bcp-1,0x1.71c885dc2d9aap-1
+pow,0x1.1b25976c149efp0,0x1.dbca857fcd851p-1,-0x1.5fc86ea34c098p0
+pow,0x1.0d9020d171475p-1,0x1.da9962780fcafp0,-0x1.0a0c5a536525ep0
+pow,NaN,-0x1.f0be3b0aed394p-3,0x1.6684a2e93eacfp-1
+pow,NaN,-0x1.13347d844b3ap2,0x1.52e80bda362f6p0
+pow,0x1.8ecabf0927c74p-1,0x1.08ef4600ac2a6p-1,0x1.8461b6ebd2638p-2
+pow,NaN,-0x1.545bab8fdb374p1,0x1.140b5443f6851p0
+pow,0x1.605e3b7e1a8a9p0,0x1.b694715b3bb5fp0,0x1.2fda4421ec27bp-1
+pow,0x1.19d126e964ecdp2,0x1.3886382511f91p2,0x1.de9b9c6ec17c8p-1
+pow,0x1.4b2a7193ded54p2,0x1.ffdaafc6d81ecp0,0x1.2faa4a532094dp1
+pow,0x1.07232bb72bf0ep182,0x1.e9c446b9f242cp-4,-0x1.db4ab29699bb1p5
+pow,NaN,-0x1.9e3204055de95p-1,0x1.0a5e93db70184p-1
+pow,0x1.1acd2b9124f7dp0,0x1.275823342912fp0,0x1.649532579916dp-1
+pow,0x1.0f47ca3682eccp0,0x1.485e42c4fd541p0,0x1.dcec8bd69c924p-3
+pow,NaN,-0x1.23bb2f8be2d74p0,-0x1.c9da27afeb55dp-2
+pow,NaN,-0x1.c587034a392cbp-2,-0x1.f25c5fb1a07bbp-1
+pow,0x1.05db5e5eda5c5p0,0x1.8db9e4a05f398p-1,-0x1.6edc4a7b93097p-4
+pow,NaN,-0x1.ab87fc0e311b7p1,-0x1.53034039016e2p1
+pow,NaN,-0x1.44bb4f7048ddfp-1,0x1.e6e647080ff5bp-2
+pow,NaN,-0x1.7817a6eb0dc76p-2,0x1.02e617c35511ap-2
+pow,NaN,-0x1.e01714a11dc2bp0,0x1.94ac311105b4ep-4
+pow,NaN,-0x1.48ad415149238p3,-0x1.7356089af8d59p-2
+pow,0x1.7aa3cf5e026e7p-2,0x1.06ed5362f04e2p-1,0x1.7e2962d832e75p0
+pow,0x1.5570ae9493bbfp0,0x1.e323a27f94fcbp-5,-0x1.a0bd6a6e9f10cp-4
+pow,0x1.152ee4ea3f7a5p1,0x1.b32a1da818d0dp1,0x1.4347b7ca029a7p-1
+pow,NaN,-0x1.03714e497f8fbp2,0x1.61ebbba8e8d3p0
+pow,NaN,-0x1.f94e76ca5ba42p-1,0x1.5fdaf42945025p0
+pow,0x1.188dcd71a310ap0,0x1.0f34cf5f7df65p0,0x1.965694c95ecc6p0
+pow,0x1.0b2cadb4cb147p0,0x1.0c40249de3f62p0,0x1.d3f98bdbca83dp-1
+pow,0x1.a5b803cf49fc6p-1,0x1.a5ea87cc7b8c2p0,-0x1.8d93f53a8c9abp-2
+pow,NaN,-0x1.045dd160caeb5p1,-0x1.562ce2be56b8ep0
+pow,0x1.84030e972f55cp1,0x1.009aa78e33834p2,0x1.98e4d1f15c54cp-1
+pow,NaN,-0x1.6e44edc8b9975p0,0x1.27b05fd665f56p-2
+pow,0x1.1d6e82b8c4526p-2,0x1.e25695af839a1p-2,0x1.b267e3187f557p0
+pow,0x1.67b1c3b809065p2,0x1.ad50aab97c6f6p-1,-0x1.39a5dd9c9ec23p3
+pow,NaN,-0x1.378b7a14b3123p-1,-0x1.d623cb500779bp-1
+pow,NaN,-0x1.b6b576540adb8p-4,-0x1.67f919b7388efp1
+pow,NaN,-0x1.a0e03f2c21b03p0,0x1.a0a6719a89da7p-4
+pow,NaN,-0x1.90f94b1510e6bp0,-0x1.2c5145f8c1ca6p-2
+pow,0x1.0820f220c6429p-3,0x1.c653e462f289fp2,-0x1.0b86c892c6d69p0
+pow,0x1.53298c15fd8dcp-3,0x1.d85a4c492edd1p0,-0x1.77beacc12e4cap1
+pow,0x1.e6872737c5bb5p-1,0x1.f99b40b5f414dp-2,0x1.282ec81705241p-4
+pow,0x1.05d050c7ea53bp0,0x1.16ce13c6d382cp0,0x1.0d76f4e269154p-2
+pow,0x1.3baf902827162p2,0x1.52d54e6210d31p-2,-0x1.7165fe6d96d64p0
+pow,0x1.8702acf8bd48ep2,0x1.83b27f2d7efbp-3,-0x1.165f690b351f5p0
+pow,NaN,-0x1.9785fb65297f6p2,-0x1.1b458cc769686p3
+pow,NaN,-0x1.09cb066385f12p0,0x1.f753576d60128p-6
+pow,0x1.e4b995c800645p-5,0x1.06d720a7e6f88p4,-0x1.02985a86e666ap0
+pow,NaN,-0x1.0939085a6f701p0,0x1.7ddd006196baap2
+pow,NaN,-0x1.d87072a74d8a6p6,0x1.790eaae918275p0
+pow,NaN,-0x1.fcc2b5194f768p-1,-0x1.c9d5f2a783883p-1
+pow,NaN,-0x1.6692393959fe5p-1,-0x1.3863994c1922cp1
+pow,NaN,-0x1.b0f50f7bf364cp-2,-0x1.14d074c377108p-5
+pow,NaN,-0x1.a20e8f0b2b858p-2,-0x1.2c0f54e075332p-2
+pow,NaN,-0x1.12d268bbaeea4p0,0x1.597d686214e67p0
+pow,0x1.b13cdddcc07c3p-2,0x1.46bbc31488813p3,-0x1.7b1c6344453f9p-2
+pow,NaN,-0x1.ff476e8f0a7e3p0,-0x1.62a04be50d505p0
+pow,NaN,-0x1.bf00588a896d3p-2,0x1.6c1c5d07803cap-1
+pow,0x1.e55b9058bb955p-7,0x1.1ec2d27a4235p1,-0x1.4e3872a7c948fp2
+pow,NaN,-0x1.b88b3d3bdf5d4p-2,-0x1.37bd82f1781b7p0
+pow,0x1.13812f08fe19dp0,0x1.d40211a90d254p-1,-0x1.a2775702dff48p-1
+pow,0x1.b3ada66ab5246p-1,0x1.869cdca43c5c8p-1,0x1.3169cc46548ep-1
+pow,NaN,-0x1.37849bc093986p0,-0x1.2aa7282eb9ebap-3
+pow,NaN,-0x1.a8944dda7586ep6,-0x1.2e47aadc1b58dp0
+pow,0x1.5aba3298bf201p-2,0x1.40a04ef8a623bp1,-0x1.2de9e2569d6d5p0
+pow,0x1.db384c61b4a74p-1,0x1.2914b4157ee24p0,-0x1.00758c0c2d72ep-1
+pow,0x1.03facf5415462p2,0x1.ada67df67a3b8p-2,-0x1.9d2c32cfcee69p0
+pow,NaN,-0x1.3088491768175p-1,0x1.bd3501f5958ap0
+pow,0x1.03796726a06a6p0,0x1.843fc5dd50c7ep-1,-0x1.8f1eee57736edp-5
+pow,NaN,-0x1.73a9bb89db993p-4,0x1.f9336be7fc6f5p0
+pow,0x1.3c59529730582p-1,0x1.931b3f08ef975p2,-0x1.0be83f40ce812p-2
+pow,NaN,-0x1.1c52401964251p0,-0x1.e209fab00f3cdp3
+pow,0x1.5870ce3110d05p-8,0x1.37a7a966690aap-5,0x1.9b0295360af3cp0
+pow,NaN,-0x1.97947ee95e148p2,0x1.fdf94a10f85d8p-2
+pow,NaN,-0x1.e3bd8870685d6p-1,0x1.0c9f51eb9fb1p-4
+pow,NaN,-0x1.06c9285154c11p-1,0x1.d21f5ac0f88dcp-4
+pow,NaN,-0x1.e851a51621887p-2,-0x1.495544552cfd7p-1
+pow,0x1.b15715904a6d4p-2,0x1.bccef58928994p-1,0x1.87377793afff2p2
+pow,0x1.3630070d85688p1,0x1.16030ade3d166p-1,-0x1.7311d0f1c9818p0
+pow,0x1.7b0bf1f3677efp0,0x1.5a0c8170f9574p0,0x1.4d5c01933c90ap0
+pow,0x1.4347bb7dbd2bap-5,0x1.00ab1db1da50fp-1,0x1.2b94fcad8bb28p2
+pow,0x1.e1d6f6b4ad3dcp0,0x1.1a71c356fda77p-1,-0x1.102d8be7b68b2p0
+pow,0x1.71ca2e9c802efp-1,0x1.93e69c1931aa2p0,-0x1.6d5b4b1eae5bap-1
+pow,0x1.60ee40140178cp-2,0x1.efd52cc8e9b32p-3,0x1.8082bff8e9734p-1
+pow,NaN,-0x1.3aa803d4e5afcp0,-0x1.853016b0f962ap0
+pow,0x1.1248c3ab2c50ap0,0x1.0a086b18b7be1p-1,-0x1.af9a7315362dcp-4
+pow,NaN,-0x1.1c65baf6ed71bp-1,-0x1.e4ce9408d718cp1
+pow,NaN,-0x1.129c9c18a45c9p0,0x1.dbd7977bbb3dbp1
+pow,NaN,-0x1.f8a2cbe4c9971p0,-0x1.6402723e29405p0
+pow,NaN,-0x1.090715aeef52ap-3,0x1.ff3c3f34c1216p0
+pow,0x1.633a5b7a503a6p6,0x1.48716eed60949p4,0x1.7c16158088824p0
+pow,NaN,-0x1.44930bdd5a09fp0,0x1.f17780da0c3bcp-4
+pow,0x1.3d8d6624ecbp-10,0x1.d6ec1a8e01545p-7,0x1.95411fce4c444p0
+pow,0x1.e5f2940ed1965p-1,0x1.1a84da1d7650cp1,-0x1.0e2f2b637c419p-4
+pow,0x1.5b1f6c1d4f497p-2,0x1.5e69e0f96815bp-2,0x1.0240a70912ecap0
+pow,0x1.7fd48e097e9a4p-4,0x1.23cefbdbeed36p3,-0x1.123500770a0b2p0
+pow,0x1.3c6a0ee0f14a2p-2,0x1.412b81765458dp-1,0x1.42579fdaa45edp1
+pow,0x1.1c477b9b71089p0,0x1.1d8bb34a7e43ap0,0x1.eb29bada420cfp-1
+pow,NaN,-0x1.7f6d0fa1fb44ep1,0x1.6b638367aa265p0
+pow,NaN,-0x1.42b4ebd31e0a3p3,-0x1.6d3fb072dd01dp1
+pow,0x1.52f4fb825bbf4p-1,0x1.7fc88d75156c4p-1,0x1.6e4f6fe5266fdp0
+pow,NaN,-0x1.2f63c263fcce9p-1,-0x1.fd3f99df0dd14p-1
+pow,0x1.aa8e9f53ca8adp1,0x1.eee1f221556d9p-4,-0x1.239c3f92a6941p-1
+pow,0x1.2fd9a918fec76p0,0x1.19574be3b830ap0,0x1.d0bf5745a62fbp0
+pow,0x1.e900a2abe38b7p-3,0x1.95f0e06b551e5p-7,0x1.4e01d522f7c2bp-2
+pow,NaN,-0x1.961230e761e2bp0,-0x1.a8d9a224ff5abp-2
+pow,NaN,-0x1.22a4b03c16fd4p-1,-0x1.bba2e8dcba702p-1
+pow,NaN,-0x1.9f94bd566490ap-1,-0x1.25051ed331b22p0
+pow,NaN,-0x1.0c252587ffbbep2,0x1.3df68e7581d3bp1
+nextUp,0x1.d3040e41e2ed6p-1,0x1.d3040e41e2ed5p-1
+nextUp,-0x1.53b76e8b2e194p0,-0x1.53b76e8b2e195p0
+nextUp,-0x1.2e7cc91f10c7fp3,-0x1.2e7cc91f10c8p3
+nextUp,0x1.115ecd0d3d8a9p-1,0x1.115ecd0d3d8a8p-1
+nextUp,-0x1.0a68bfff8d648p0,-0x1.0a68bfff8d649p0
+nextUp,-0x1.be4afc4ccae83p-1,-0x1.be4afc4ccae84p-1
+nextUp,-0x1.451ff3485acbbp-1,-0x1.451ff3485acbcp-1
+nextUp,0x1.14c999736e394p-1,0x1.14c999736e393p-1
+nextUp,-0x1.b01b9c1b9a649p3,-0x1.b01b9c1b9a64ap3
+nextUp,-0x1.665f667e2b3d1p0,-0x1.665f667e2b3d2p0
+nextUp,-0x1.1760f0ff2b4e3p0,-0x1.1760f0ff2b4e4p0
+nextUp,-0x1.910dc2365ef13p-1,-0x1.910dc2365ef14p-1
+nextUp,-0x1.16d967cb6fe61p1,-0x1.16d967cb6fe62p1
+nextUp,0x1.1f04263fb3e0fp0,0x1.1f04263fb3e0ep0
+nextUp,-0x1.69d304c513701p0,-0x1.69d304c513702p0
+nextUp,0x1.f529637ef54c6p-2,0x1.f529637ef54c5p-2
+nextUp,0x1.9acafec6b8ff6p-8,0x1.9acafec6b8ff5p-8
+nextUp,0x1.0375a2b72b97cp0,0x1.0375a2b72b97bp0
+nextUp,-0x1.9646c16b6fb92p-1,-0x1.9646c16b6fb93p-1
+nextUp,0x1.1e60599537373p0,0x1.1e60599537372p0
+nextUp,-0x1.8a8df712b9d86p-2,-0x1.8a8df712b9d87p-2
+nextUp,-0x1.a016f5f219b25p0,-0x1.a016f5f219b26p0
+nextUp,-0x1.e239718239c74p-1,-0x1.e239718239c75p-1
+nextUp,0x1.7c453055df8bbp-1,0x1.7c453055df8bap-1
+nextUp,0x1.72a89333661e3p-1,0x1.72a89333661e2p-1
+nextUp,-0x1.e638b805d1849p1,-0x1.e638b805d184ap1
+nextUp,0x1.88445788e7263p4,0x1.88445788e7262p4
+nextUp,-0x1.5bc1c772e6149p-1,-0x1.5bc1c772e614ap-1
+nextUp,-0x1.8d8971d94147fp-2,-0x1.8d8971d94148p-2
+nextUp,0x1.1216da190a47fp0,0x1.1216da190a47ep0
+nextUp,0x1.1f616373910f9p0,0x1.1f616373910f8p0
+nextUp,0x1.d7189f97e6d8ap-1,0x1.d7189f97e6d89p-1
+nextUp,-0x1.17b972d833cap0,-0x1.17b972d833ca1p0
+nextUp,-0x1.06b0482e9926ap0,-0x1.06b0482e9926bp0
+nextUp,-0x1.f0ad7aa11b04ep-3,-0x1.f0ad7aa11b04fp-3
+nextUp,-0x1.4744eeb81da2fp-9,-0x1.4744eeb81da3p-9
+nextUp,0x1.ff2a8df85b779p-1,0x1.ff2a8df85b778p-1
+nextUp,0x1.3130e66165a86p2,0x1.3130e66165a85p2
+nextUp,-0x1.3f67ba776c895p-2,-0x1.3f67ba776c896p-2
+nextUp,-0x1.dc657d757ae33p4,-0x1.dc657d757ae34p4
+nextUp,0x1.8e2bc626c19a4p-1,0x1.8e2bc626c19a3p-1
+nextUp,0x1.b80a35d69ebf3p-1,0x1.b80a35d69ebf2p-1
+nextUp,0x1.0c580407a5e36p-1,0x1.0c580407a5e35p-1
+nextUp,-0x1.e454f464be1ffp-5,-0x1.e454f464be2p-5
+nextUp,0x1.d02a4bdd0ebd8p-1,0x1.d02a4bdd0ebd7p-1
+nextUp,0x1.14cdd76d4b8dfp-9,0x1.14cdd76d4b8dep-9
+nextUp,0x1.e0a2080f509d3p4,0x1.e0a2080f509d2p4
+nextUp,0x1.381f37d3f5cd6p-1,0x1.381f37d3f5cd5p-1
+nextUp,0x1.158054cb50452p2,0x1.158054cb50451p2
+nextUp,0x1.5b2e36af1be1cp-4,0x1.5b2e36af1be1bp-4
+nextUp,-0x1.66961ded5be6ap-3,-0x1.66961ded5be6bp-3
+nextUp,-0x1.33a1f920451ffp0,-0x1.33a1f920452p0
+nextUp,0x1.511eabb05221dp-1,0x1.511eabb05221cp-1
+nextUp,-0x1.242fae41c6d6cp-1,-0x1.242fae41c6d6dp-1
+nextUp,-0x1.1774360b28c26p3,-0x1.1774360b28c27p3
+nextUp,0x1.d50670fb00411p2,0x1.d50670fb0041p2
+nextUp,-0x1.6f974900aa57fp-1,-0x1.6f974900aa58p-1
+nextUp,-0x1.15bdfc41db415p0,-0x1.15bdfc41db416p0
+nextUp,0x1.8016e77d9964fp-2,0x1.8016e77d9964ep-2
+nextUp,-0x1.3ab0226ac5151p-1,-0x1.3ab0226ac5152p-1
+nextUp,-0x1.27ef4b6c31cc5p2,-0x1.27ef4b6c31cc6p2
+nextUp,-0x1.604d629ffd6a8p-2,-0x1.604d629ffd6a9p-2
+nextUp,-0x1.a8e830ae29d51p-2,-0x1.a8e830ae29d52p-2
+nextUp,0x1.06c642cd93e74p-5,0x1.06c642cd93e73p-5
+nextUp,-0x1.6510315f22106p0,-0x1.6510315f22107p0
+nextUp,-0x1.59d954d49e322p2,-0x1.59d954d49e323p2
+nextUp,-0x1.a0d80268e728ep3,-0x1.a0d80268e728fp3
+nextUp,0x1.4750981c87bf6p-1,0x1.4750981c87bf5p-1
+nextUp,0x1.ca59601a4ecf2p1,0x1.ca59601a4ecf1p1
+nextUp,0x1.a4016ef4f07fep-1,0x1.a4016ef4f07fdp-1
+nextUp,0x1.5ae95775ad60fp-1,0x1.5ae95775ad60ep-1
+nextUp,0x1.7705ff641e54ep-1,0x1.7705ff641e54dp-1
+nextUp,-0x1.78f81f25c9ba3p-2,-0x1.78f81f25c9ba4p-2
+nextUp,0x1.2ae4ee50ec5adp-4,0x1.2ae4ee50ec5acp-4
+nextUp,-0x1.3cffd8537ef94p-3,-0x1.3cffd8537ef95p-3
+nextUp,-0x1.1dcaac99cc075p-1,-0x1.1dcaac99cc076p-1
+nextUp,0x1.6aa92508d4bd3p-1,0x1.6aa92508d4bd2p-1
+nextUp,-0x1.ee62b4748493bp-1,-0x1.ee62b4748493cp-1
+nextUp,-0x1.62b0a345a381dp0,-0x1.62b0a345a381ep0
+nextUp,-0x1.ca89336b0d6d7p0,-0x1.ca89336b0d6d8p0
+nextUp,0x1.5d52c172e660bp-1,0x1.5d52c172e660ap-1
+nextUp,-0x1.33b3a532f18efp-1,-0x1.33b3a532f18fp-1
+nextUp,0x1.5ee286d7628c6p0,0x1.5ee286d7628c5p0
+nextUp,-0x1.f54896afd80d9p1,-0x1.f54896afd80dap1
+nextUp,-0x1.7e0ed231e05fbp-1,-0x1.7e0ed231e05fcp-1
+nextUp,0x1.190d97337d16dp-2,0x1.190d97337d16cp-2
+nextUp,-0x1.47e39d27543e6p1,-0x1.47e39d27543e7p1
+nextUp,0x1.f710402c5a0b6p-1,0x1.f710402c5a0b5p-1
+nextUp,0x1.9eab86259cc5ep-1,0x1.9eab86259cc5dp-1
+nextUp,-0x1.e61993c4f1049p-3,-0x1.e61993c4f104ap-3
+nextUp,-0x1.a993a82593211p2,-0x1.a993a82593212p2
+nextUp,-0x1.dcd0767944698p-1,-0x1.dcd0767944699p-1
+nextUp,0x1.27ad12aa4aa63p-1,0x1.27ad12aa4aa62p-1
+nextUp,-0x1.0d8f21dcbd40fp0,-0x1.0d8f21dcbd41p0
+nextUp,-0x1.25ce2fc3e4012p0,-0x1.25ce2fc3e4013p0
+nextUp,-0x1.d32b06d8ec84fp0,-0x1.d32b06d8ec85p0
+nextUp,0x1.09d85d8919589p-6,0x1.09d85d8919588p-6
+nextUp,-0x1.560b1bfb41db6p0,-0x1.560b1bfb41db7p0
+nextUp,-0x1.2f96ae30cdd89p-1,-0x1.2f96ae30cdd8ap-1
+nextUp,-0x1.01755e3844e7dp-3,-0x1.01755e3844e7ep-3
+nextUp,-0x1.9f12b7eb60b02p1,-0x1.9f12b7eb60b03p1
+nextUp,0x1.460ef7006e16ap-1,0x1.460ef7006e169p-1
+nextUp,-0x1.6f2c9a0b25e78p-4,-0x1.6f2c9a0b25e79p-4
+nextUp,0x1.ccf1eb5e43126p-2,0x1.ccf1eb5e43125p-2
+nextUp,0x1.ee914a4e8319dp-1,0x1.ee914a4e8319cp-1
+nextUp,0x1.b9f2373904ccbp-1,0x1.b9f2373904ccap-1
+nextUp,-0x1.22698a06f367dp2,-0x1.22698a06f367ep2
+nextUp,0x1.bee5f900ae40ap-1,0x1.bee5f900ae409p-1
+nextUp,0x1.57c1d081e07e1p0,0x1.57c1d081e07ep0
+nextUp,0x1.32246ec86182cp2,0x1.32246ec86182bp2
+nextUp,-0x1.5ceea872790a6p1,-0x1.5ceea872790a7p1
+nextUp,0x1.db0b05d54a72fp-2,0x1.db0b05d54a72ep-2
+nextUp,0x1.afd3e9982737cp-1,0x1.afd3e9982737bp-1
+nextUp,-0x1.a646aa4a4d81fp-1,-0x1.a646aa4a4d82p-1
+nextUp,-0x1.65e897637b5f9p-3,-0x1.65e897637b5fap-3
+nextUp,-0x1.0f942a08ff30bp0,-0x1.0f942a08ff30cp0
+nextUp,0x1.dad26b69ba743p-1,0x1.dad26b69ba742p-1
+nextUp,-0x1.18c2ecb354efap0,-0x1.18c2ecb354efbp0
+nextUp,-0x1.8ec681589c041p-1,-0x1.8ec681589c042p-1
+nextUp,0x1.6c9430a270787p2,0x1.6c9430a270786p2
+nextUp,0x1.a85867e471f68p-1,0x1.a85867e471f67p-1
+nextUp,0x1.0843a878e12a1p0,0x1.0843a878e12ap0
+nextUp,0x1.6ccc6e57b1cd6p-1,0x1.6ccc6e57b1cd5p-1
+nextUp,0x1.b2aaeb34d39fbp3,0x1.b2aaeb34d39fap3
+nextUp,0x1.2abdb28b7c1e4p5,0x1.2abdb28b7c1e3p5
+nextUp,0x1.b313f8d493a33p-4,0x1.b313f8d493a32p-4
+nextUp,0x1.2be3833358578p-1,0x1.2be3833358577p-1
+nextUp,-0x1.71c37e4676141p4,-0x1.71c37e4676142p4
+nextUp,0x1.3e11db2e11d1cp-1,0x1.3e11db2e11d1bp-1
+nextUp,-0x1.0981ee2170da8p2,-0x1.0981ee2170da9p2
+nextUp,-0x1.5c8e75bf0af76p0,-0x1.5c8e75bf0af77p0
+nextUp,0x1.219e33d06f3d4p-2,0x1.219e33d06f3d3p-2
+nextUp,-0x1.573b7638ca558p-2,-0x1.573b7638ca559p-2
+nextUp,-0x1.dce03b67e91bp-1,-0x1.dce03b67e91b1p-1
+nextUp,0x1.d773763c9af9dp3,0x1.d773763c9af9cp3
+nextUp,-0x1.41215262e0d1p-1,-0x1.41215262e0d11p-1
+nextUp,0x1.24dffa399cd09p-1,0x1.24dffa399cd08p-1
+nextUp,0x1.6a2d79c75bd4p0,0x1.6a2d79c75bd3fp0
+nextUp,0x1.ccaeced5c93cbp1,0x1.ccaeced5c93cap1
+nextUp,-0x1.c2510db061757p-1,-0x1.c2510db061758p-1
+nextUp,-0x1.40258b211f9ecp-1,-0x1.40258b211f9edp-1
+nextUp,-0x1.41bb57a04554dp0,-0x1.41bb57a04554ep0
+nextUp,-0x1.582bf88c38d7p1,-0x1.582bf88c38d71p1
+nextUp,0x1.f59aec20bb862p-1,0x1.f59aec20bb861p-1
+nextUp,-0x1.15e39558d7f1p0,-0x1.15e39558d7f11p0
+nextUp,0x1.067c6d1b9c875p3,0x1.067c6d1b9c874p3
+nextUp,0x1.720a0ee1f2929p1,0x1.720a0ee1f2928p1
+nextUp,-0x1.aff57264e19dep-1,-0x1.aff57264e19dfp-1
+nextUp,0x1.045acc1c7c2efp-2,0x1.045acc1c7c2eep-2
+nextUp,-0x1.038f9095fbf4ep-3,-0x1.038f9095fbf4fp-3
+nextUp,-0x1.4a75d4c6d9f9p1,-0x1.4a75d4c6d9f91p1
+nextUp,0x1.299d935604783p-1,0x1.299d935604782p-1
+nextUp,0x1.27edf0b504754p1,0x1.27edf0b504753p1
+nextUp,-0x1.e4a6ca55e9e11p-3,-0x1.e4a6ca55e9e12p-3
+nextUp,-0x1.818f39f9060bep-1,-0x1.818f39f9060bfp-1
+nextUp,-0x1.36b15ae996101p-1,-0x1.36b15ae996102p-1
+nextUp,0x1.2dff034240e3bp2,0x1.2dff034240e3ap2
+nextUp,-0x1.c206b32a07242p1,-0x1.c206b32a07243p1
+nextUp,0x1.622128d7ead69p1,0x1.622128d7ead68p1
+nextUp,-0x1.e55d3fed82a0dp0,-0x1.e55d3fed82a0ep0
+nextUp,0x1.78c61780b267ep0,0x1.78c61780b267dp0
+nextUp,-0x1.a7cc575e5e61ap-1,-0x1.a7cc575e5e61bp-1
+nextUp,0x1.8c19aeb88f752p-2,0x1.8c19aeb88f751p-2
+nextUp,-0x1.def690507cf6bp-2,-0x1.def690507cf6cp-2
+nextUp,-0x1.17eb10ad97c13p-1,-0x1.17eb10ad97c14p-1
+nextUp,-0x1.1493191c91951p-1,-0x1.1493191c91952p-1
+nextUp,-0x1.4e5c6f56aa9adp-1,-0x1.4e5c6f56aa9aep-1
+nextUp,0x1.0f8f2deae231cp0,0x1.0f8f2deae231bp0
+nextUp,0x1.0bb8d0ee5a33dp-1,0x1.0bb8d0ee5a33cp-1
+nextUp,0x1.f453228e2a49bp2,0x1.f453228e2a49ap2
+nextUp,0x1.2bb00a8ecd186p-1,0x1.2bb00a8ecd185p-1
+nextUp,0x1.7abc047124f6ep-1,0x1.7abc047124f6dp-1
+nextUp,0x1.1b107be53002ep0,0x1.1b107be53002dp0
+nextUp,0x1.96bff92299892p1,0x1.96bff92299891p1
+nextUp,-0x1.fe95a2514fdb4p-1,-0x1.fe95a2514fdb5p-1
+nextUp,-0x1.3aab5df9db757p2,-0x1.3aab5df9db758p2
+nextUp,0x1.09114a178ef03p1,0x1.09114a178ef02p1
+nextUp,0x1.5a610cc38f488p1,0x1.5a610cc38f487p1
+nextUp,-0x1.6463a38870952p-3,-0x1.6463a38870953p-3
+nextUp,0x1.203de7acd52fdp0,0x1.203de7acd52fcp0
+nextUp,0x1.8bca2b5dddde1p-2,0x1.8bca2b5ddddep-2
+nextUp,0x1.2010056a0e9b7p-1,0x1.2010056a0e9b6p-1
+nextUp,-0x1.101cfc82211b4p-1,-0x1.101cfc82211b5p-1
+nextUp,0x1.be249fc8f9c52p-1,0x1.be249fc8f9c51p-1
+nextUp,0x1.783250d25c4fp-2,0x1.783250d25c4efp-2
+nextUp,0x1.71d19e2dc8f26p-2,0x1.71d19e2dc8f25p-2
+nextUp,0x1.0ab3f9ad495abp-1,0x1.0ab3f9ad495aap-1
+nextUp,-0x1.8e1f9722cb3eap-4,-0x1.8e1f9722cb3ebp-4
+nextUp,-0x1.f348e4e4a0a9fp-3,-0x1.f348e4e4a0aap-3
+nextUp,-0x1.4b1fa0a51eb9ap-3,-0x1.4b1fa0a51eb9bp-3
+nextUp,0x1.a428c1153bc54p2,0x1.a428c1153bc53p2
+nextUp,0x1.550447afd1e9cp-2,0x1.550447afd1e9bp-2
+nextUp,0x1.88f5e56cea93dp-1,0x1.88f5e56cea93cp-1
+nextUp,-0x1.49784bda32a1ep0,-0x1.49784bda32a1fp0
+nextUp,-0x1.ea3924a7ff3d9p1,-0x1.ea3924a7ff3dap1
+nextUp,-0x1.2fedfee49a714p-1,-0x1.2fedfee49a715p-1
+nextUp,0x1.592aad0aca4d9p0,0x1.592aad0aca4d8p0
+nextUp,-0x1.01545a95f248bp-2,-0x1.01545a95f248cp-2
+nextUp,0x1.764e065a3531fp-5,0x1.764e065a3531ep-5
+nextUp,0x1.7c608d2ea5e87p0,0x1.7c608d2ea5e86p0
+nextAfter,0x1.be08ed06ae399p-1,0x1.be08ed06ae39ap-1,-0x1.feeeaeefa83a6p0
+nextAfter,-0x1.1558e1e8299b7p0,-0x1.1558e1e8299b8p0,0x1.60d227f2f9e01p0
+nextAfter,0x1.912a35080f8b2p1,0x1.912a35080f8b3p1,-0x1.88072eb78a283p-2
+nextAfter,-0x1.e23dcc6153801p-1,-0x1.e23dcc6153802p-1,0x1.3bfd03c91e4ep8
+nextAfter,-0x1.122410b658edcp4,-0x1.122410b658eddp4,-0x1.35494eb6d5691p0
+nextAfter,-0x1.69355b8af8cd6p-1,-0x1.69355b8af8cd5p-1,-0x1.f0006d9d37145p-1
+nextAfter,-0x1.32a0dd3b6dd81p4,-0x1.32a0dd3b6dd82p4,-0x1.df3a32573fc8bp-2
+nextAfter,-0x1.6f6ec240848bfp-2,-0x1.6f6ec240848cp-2,-0x1.668e7e853506ep-2
+nextAfter,-0x1.81169faed0f51p-1,-0x1.81169faed0f52p-1,0x1.77d54e6483199p-1
+nextAfter,0x1.2d8f948b56dd7p4,0x1.2d8f948b56dd8p4,-0x1.d02d0fde59b9p1
+nextAfter,0x1.364bb6648481bp0,0x1.364bb6648481cp0,0x1.a679f94159201p-1
+nextAfter,-0x1.2ed1480b21aa2p-2,-0x1.2ed1480b21aa1p-2,-0x1.a995b18a896aep0
+nextAfter,0x1.b340ca4d97a4p-1,0x1.b340ca4d97a41p-1,-0x1.8ab2eb2634cf2p0
+nextAfter,0x1.eaa2ef7dbb9ep-1,0x1.eaa2ef7dbb9dfp-1,0x1.4dc94628ade56p0
+nextAfter,-0x1.09a5110d0e06dp0,-0x1.09a5110d0e06cp0,-0x1.2151d458f1cc9p0
+nextAfter,0x1.60da362a6212cp0,0x1.60da362a6212bp0,0x1.967dfbf52867bp0
+nextAfter,-0x1.c4e39b3bd6527p-1,-0x1.c4e39b3bd6528p-1,0x1.56333202bfbf1p-1
+nextAfter,0x1.d5a570731850ap4,0x1.d5a570731850bp4,-0x1.02688722f3b3fp0
+nextAfter,-0x1.97187568c9e9bp-1,-0x1.97187568c9e9ap-1,-0x1.81e2e09c8a0b1p2
+nextAfter,-0x1.7b2339123d502p-1,-0x1.7b2339123d503p-1,0x1.71b783b0efbfdp1
+nextAfter,0x1.7c4855534b564p1,0x1.7c4855534b565p1,-0x1.4e4cf60d4c8bfp0
+nextAfter,0x1.8bc32d4fd64f9p-1,0x1.8bc32d4fd64fap-1,-0x1.82480521fb705p0
+nextAfter,-0x1.2854a547967d3p3,-0x1.2854a547967d4p3,0x1.758478347d297p-3
+nextAfter,0x1.805683c6f76abp-1,0x1.805683c6f76aap-1,0x1.130156800e03p0
+nextAfter,-0x1.18ef725ab9968p-4,-0x1.18ef725ab9967p-4,-0x1.f146ef18a8022p-2
+nextAfter,-0x1.1f99b1d1c8feep-1,-0x1.1f99b1d1c8fefp-1,0x1.4ced4a2f389e2p-1
+nextAfter,-0x1.2611251b5806dp-2,-0x1.2611251b5806cp-2,-0x1.45f32769bed38p0
+nextAfter,-0x1.019e9cda4d56bp1,-0x1.019e9cda4d56cp1,-0x1.f103c160f70d1p-4
+nextAfter,-0x1.4bc4d28d6cdb6p2,-0x1.4bc4d28d6cdb7p2,0x1.61d7ef134d991p-1
+nextAfter,-0x1.67d2a760f5a3ap-6,-0x1.67d2a760f5a39p-6,-0x1.8c6752ff63432p-4
+nextAfter,-0x1.ab515f69190d8p2,-0x1.ab515f69190d9p2,-0x1.d72aae7ba1c68p-1
+nextAfter,-0x1.be2206d553e09p-2,-0x1.be2206d553e08p-2,-0x1.1060952b96b9ep-1
+nextAfter,0x1.cf365b29af936p-2,0x1.cf365b29af937p-2,-0x1.d288d17edddcp3
+nextAfter,-0x1.9a8387254ff5p1,-0x1.9a8387254ff51p1,0x1.d887ffbf1c225p0
+nextAfter,-0x1.d591a4ef45463p0,-0x1.d591a4ef45464p0,0x1.2248bba3318f3p0
+nextAfter,0x1.c5f0fdeba15bep-2,0x1.c5f0fdeba15bdp-2,0x1.2d4ae33b96f28p1
+nextAfter,0x1.12b003b9459cep-1,0x1.12b003b9459cfp-1,0x1.00ce7e72b7671p-1
+nextAfter,0x1.f5c5f4d5d62b7p-1,0x1.f5c5f4d5d62b8p-1,-0x1.00126d22c88dep-1
+nextAfter,0x1.10b04f432546cp0,0x1.10b04f432546dp0,-0x1.2cf01d09a9d1cp-1
+nextAfter,-0x1.98cdc00c06459p-1,-0x1.98cdc00c0645ap-1,0x1.b940443f519cdp0
+nextAfter,-0x1.bac06bffc30cdp1,-0x1.bac06bffc30cep1,-0x1.343aa5170ae4ep0
+nextAfter,0x1.150e265344e05p3,0x1.150e265344e06p3,-0x1.75b6356e210f8p-1
+nextAfter,0x1.d497e81b6cfa6p0,0x1.d497e81b6cfa7p0,0x1.9c6a2c4745f4ap-3
+nextAfter,0x1.5c7ac51d66174p-3,0x1.5c7ac51d66173p-3,0x1.cb7f5aec6eeb4p-2
+nextAfter,0x1.2ff8ab2a9ad62p0,0x1.2ff8ab2a9ad63p0,0x1.b1e04ed2de4e2p-1
+nextAfter,-0x1.04f992ba0eb58p0,-0x1.04f992ba0eb59p0,0x1.983e7b8bb7799p-1
+nextAfter,0x1.24a2da8478553p1,0x1.24a2da8478554p1,-0x1.243234bb62d2cp-2
+nextAfter,-0x1.85ee4008ad957p-2,-0x1.85ee4008ad958p-2,0x1.a5c5ca534bde7p0
+nextAfter,-0x1.997b182a9bb8p-3,-0x1.997b182a9bb7fp-3,-0x1.7889b32f872afp1
+nextAfter,0x1.efd864156ce0ep1,0x1.efd864156ce0fp1,-0x1.aa95787fc93edp1
+nextAfter,-0x1.9df023878d598p-1,-0x1.9df023878d599p-1,-0x1.2f73e50521bebp-2
+nextAfter,0x1.e72c1c9dcbedcp-3,0x1.e72c1c9dcbedbp-3,0x1.60971ac27b339p-2
+nextAfter,0x1.429a3e120ceaap0,0x1.429a3e120ceabp0,-0x1.0eb1e8536fe8bp0
+nextAfter,0x1.22e87863e519bp1,0x1.22e87863e519cp1,0x1.c6edc845c23d7p-1
+nextAfter,-0x1.b28da712af136p-1,-0x1.b28da712af137p-1,0x1.3e7c56007b11cp0
+nextAfter,0x1.34fa489be89c5p1,0x1.34fa489be89c6p1,-0x1.40a0c5e9d0fap-2
+nextAfter,0x1.19fcb20977287p3,0x1.19fcb20977288p3,-0x1.d943548d5f4b3p-5
+nextAfter,-0x1.817d9e10d3c75p1,-0x1.817d9e10d3c76p1,0x1.0d9e5aa41b3bdp2
+nextAfter,-0x1.24f917bbea9cp1,-0x1.24f917bbea9bfp1,-0x1.17908c48308f2p3
+nextAfter,-0x1.3285535c65036p0,-0x1.3285535c65035p0,-0x1.67bf9e6bd0e81p2
+nextAfter,-0x1.b83b7791e0baap0,-0x1.b83b7791e0babp0,-0x1.83b535ef83ff4p-1
+nextAfter,0x1.9125f81a5384cp-2,0x1.9125f81a5384bp-2,0x1.3b06893bb2556p0
+nextAfter,0x1.ad2b9aebd79bdp-1,0x1.ad2b9aebd79bep-1,-0x1.6300c36f4ea11p1
+nextAfter,0x1.2536e7ab2f17ep-2,0x1.2536e7ab2f17fp-2,0x1.625c3899e4f1dp-3
+nextAfter,-0x1.cb1c17d6292edp0,-0x1.cb1c17d6292eep0,0x1.402ddf503a101p0
+nextAfter,0x1.022c5ff67e8c5p0,0x1.022c5ff67e8c6p0,-0x1.ee13a25f9dcb4p3
+nextAfter,0x1.28eddab43c629p-2,0x1.28eddab43c628p-2,0x1.882dfc92fb49ap-1
+nextAfter,-0x1.01028dbd448d3p1,-0x1.01028dbd448d4p1,0x1.e9e56cfed0b34p0
+nextAfter,-0x1.5948348da9d86p-3,-0x1.5948348da9d87p-3,0x1.187bcbf7e8822p0
+nextAfter,0x1.6569c14304536p2,0x1.6569c14304537p2,-0x1.5054778b7a41fp-4
+nextAfter,-0x1.31541348909dfp2,-0x1.31541348909dep2,-0x1.846247c90221dp6
+nextAfter,-0x1.161c5cb703094p-3,-0x1.161c5cb703095p-3,0x1.f5541aff83618p1
+nextAfter,0x1.4beb4cad04695p0,0x1.4beb4cad04696p0,-0x1.91ac38ba89d5p0
+nextAfter,0x1.63c948150dd55p1,0x1.63c948150dd56p1,0x1.2dec1beb8af59p0
+nextAfter,0x1.98396629159cap-2,0x1.98396629159cbp-2,-0x1.9a25f676f5ffdp3
+nextAfter,0x1.a2e4939826476p2,0x1.a2e4939826477p2,0x1.3811e8ce43d01p0
+nextAfter,0x1.cf91f1698bbbap0,0x1.cf91f1698bbbbp0,-0x1.e036c0ca70cc9p-1
+nextAfter,0x1.0197750c62814p1,0x1.0197750c62815p1,0x1.8785e6aa38b3p-1
+nextAfter,0x1.2604374abf14ap0,0x1.2604374abf14bp0,-0x1.de65dc822a41ap-1
+nextAfter,0x1.4179ba5ebf2cp0,0x1.4179ba5ebf2c1p0,-0x1.9282734f2c477p5
+nextAfter,-0x1.9ad34119967d5p-1,-0x1.9ad34119967d6p-1,0x1.1587b953f681ep4
+nextAfter,0x1.9e6e7f25dc222p1,0x1.9e6e7f25dc223p1,-0x1.c2b2217411099p-1
+nextAfter,0x1.ae9e76e403cacp-1,0x1.ae9e76e403cadp-1,0x1.4c8dee18dd07p-7
+nextAfter,-0x1.11b2b9b348b5ep0,-0x1.11b2b9b348b5fp0,0x1.54d5f0bfc3e0fp0
+nextAfter,-0x1.1ba62c98dd46ap5,-0x1.1ba62c98dd46bp5,-0x1.e248655bfa8e2p-3
+nextAfter,0x1.053c6ed019c3fp0,0x1.053c6ed019c3ep0,0x1.741b833ba4264p0
+nextAfter,0x1.36c6119693a9fp0,0x1.36c6119693aap0,0x1.271cd019886ep0
+nextAfter,-0x1.14a41a276793ap-1,-0x1.14a41a276793bp-1,0x1.700723f91afc5p1
+nextAfter,0x1.0813380b99a9ap-1,0x1.0813380b99a9bp-1,-0x1.7c6622ee9a4fdp-1
+nextAfter,0x1.562bd1efcce1bp1,0x1.562bd1efcce1cp1,-0x1.0607dbc96d55ep3
+nextAfter,-0x1.90914d5da476ep0,-0x1.90914d5da476fp0,0x1.b5db24cebb4b2p-1
+nextAfter,-0x1.ab9eec55c7e3bp-1,-0x1.ab9eec55c7e3ap-1,-0x1.8cc010f6eb178p0
+nextAfter,0x1.2e679cc6e7224p0,0x1.2e679cc6e7225p0,0x1.30b5eb876dd6ep-1
+nextAfter,-0x1.112d5a8018aeap0,-0x1.112d5a8018aebp0,-0x1.d403dacfe3de2p-3
+nextAfter,-0x1.661c3fd6e470cp-4,-0x1.661c3fd6e470bp-4,-0x1.0b168f2c6b6ddp-2
+nextAfter,0x1.d209cbe3b1233p-1,0x1.d209cbe3b1232p-1,0x1.9fbf1b70821b9p1
+nextAfter,-0x1.14389111cc836p0,-0x1.14389111cc835p0,-0x1.2c67f46aa3c71p6
+nextAfter,0x1.393e6502546a6p1,0x1.393e6502546a7p1,-0x1.379ba570db078p0
+nextAfter,-0x1.ed6ce6384ef4ep2,-0x1.ed6ce6384ef4fp2,-0x1.37ac832cc3709p2
+nextAfter,0x1.73cbb8b795d61p4,0x1.73cbb8b795d62p4,0x1.8617316b1a779p-1
+nextAfter,0x1.3b2fa2e6c5bccp-1,0x1.3b2fa2e6c5bcdp-1,0x1.0c5acf0887cb2p-3
+nextAfter,-0x1.a81a4e1f5fd2dp1,-0x1.a81a4e1f5fd2ep1,0x1.72a39cece6988p-7
+nextAfter,-0x1.b47b120119042p-4,-0x1.b47b120119043p-4,0x1.0681dd0520a87p1
+nextAfter,0x1.c922bcbf67df4p-2,0x1.c922bcbf67df3p-2,0x1.1aac0d1be7f1p0
+nextAfter,0x1.119a9e8c2e15dp-1,0x1.119a9e8c2e15ep-1,-0x1.3e830aba61194p6
+nextAfter,-0x1.b5fde7070ac02p-5,-0x1.b5fde7070ac01p-5,-0x1.1451b0a839408p-1
+nextAfter,-0x1.411bb9b2b7d27p0,-0x1.411bb9b2b7d28p0,0x1.ed46666675a55p-1
+nextAfter,0x1.38ea05849874bp-1,0x1.38ea05849874cp-1,-0x1.fb18ec8f0c20cp-2
+nextAfter,-0x1.1534f39d7e135p-1,-0x1.1534f39d7e136p-1,0x1.78a4eedfaf3c4p0
+nextAfter,0x1.d8514ada63677p-1,0x1.d8514ada63676p-1,0x1.a4ba56fb5e95bp5
+nextAfter,-0x1.d2465e495e8f7p0,-0x1.d2465e495e8f8p0,0x1.2c92fdd2e8d32p0
+nextAfter,-0x1.86dc8707e63aap-1,-0x1.86dc8707e63abp-1,-0x1.2587435604f05p-2
+nextAfter,0x1.a723492cee1f4p0,0x1.a723492cee1f5p0,-0x1.47acb72c77762p-1
+nextAfter,0x1.8a4dc1e79fb62p-1,0x1.8a4dc1e79fb63p-1,0x1.1d2349af00cebp-1
+nextAfter,0x1.ad536251cf312p1,0x1.ad536251cf313p1,-0x1.4d0fff627210ep0
+nextAfter,-0x1.ef00c43645a3p-2,-0x1.ef00c43645a2fp-2,-0x1.5736c1d77de5bp2
+nextAfter,0x1.03558e0a72a2bp1,0x1.03558e0a72a2cp1,-0x1.8bb3ee5723bd9p0
+nextAfter,-0x1.059903c241cfbp0,-0x1.059903c241cfcp0,-0x1.959e8b56b89dbp-1
+nextAfter,-0x1.58ea3f0f2a56fp0,-0x1.58ea3f0f2a57p0,-0x1.50340dd6f0845p-3
+nextAfter,0x1.4882208f0cceep2,0x1.4882208f0ccefp2,-0x1.42e1e171eb0b6p2
+nextAfter,-0x1.3ba88c9df1697p-3,-0x1.3ba88c9df1696p-3,-0x1.8e04ae862d44ep2
+nextAfter,-0x1.dd5b75b8dc45dp1,-0x1.dd5b75b8dc45ep1,-0x1.648e1fc2e480bp-1
+nextAfter,-0x1.2aa6c715a1ad1p2,-0x1.2aa6c715a1ad2p2,-0x1.b30486358e2c5p1
+nextAfter,0x1.f02d719ee0e57p2,0x1.f02d719ee0e58p2,-0x1.3d4980849f152p-3
+nextAfter,-0x1.fcde0b5ea3b9fp-3,-0x1.fcde0b5ea3bap-3,-0x1.9351ec231b852p-3
+nextAfter,0x1.24eb83fa49e5cp-1,0x1.24eb83fa49e5bp-1,0x1.4a1a34417a1a2p1
+nextAfter,-0x1.036d6c4794c26p0,-0x1.036d6c4794c27p0,0x1.67aa7817a0d7p-2
+nextAfter,0x1.470a86b0f5795p1,0x1.470a86b0f5796p1,-0x1.0223f8be643e2p0
+nextAfter,-0x1.739de6b861d6p-1,-0x1.739de6b861d61p-1,0x1.81318046a727p-6
+nextAfter,-0x1.7cfdb659fff4p-1,-0x1.7cfdb659fff41p-1,0x1.f2d2d8bbddcb4p-1
+nextAfter,-0x1.862d750f0fc1fp0,-0x1.862d750f0fc2p0,-0x1.58cc5ef2f1669p-2
+nextAfter,-0x1.11344da901121p-1,-0x1.11344da90112p-1,-0x1.5a89a905652afp3
+nextAfter,0x1.5211661bc634bp-1,0x1.5211661bc634cp-1,-0x1.41aa7790f999ap1
+nextAfter,-0x1.3dd9e192b371bp1,-0x1.3dd9e192b371cp1,-0x1.0ee658dd025cp0
+nextAfter,0x1.8ccf3a1cb7e0ep-2,0x1.8ccf3a1cb7e0dp-2,0x1.190f4c5074b9fp0
+nextAfter,0x1.26aeb852f5c0fp0,0x1.26aeb852f5c1p0,-0x1.b5accc2fb8a9p-1
+nextAfter,0x1.3af5db50e71afp1,0x1.3af5db50e71bp1,0x1.b840b2022cc05p0
+nextAfter,0x1.04070e9aa96cep1,0x1.04070e9aa96cfp1,0x1.5cb117d184102p0
+nextAfter,0x1.7ee2cd94d2b95p0,0x1.7ee2cd94d2b96p0,-0x1.d681391227728p-1
+nextAfter,0x1.2486672587039p2,0x1.248667258703ap2,0x1.20e4c8a83353fp0
+nextAfter,0x1.10b25729ee664p-1,0x1.10b25729ee665p-1,-0x1.6cdfb8b3c1d2ep-3
+nextAfter,-0x1.05accfc2cd87ep-1,-0x1.05accfc2cd87fp-1,0x1.b76292642ac94p1
+nextAfter,0x1.1312882e464cdp1,0x1.1312882e464cep1,-0x1.f3b346a25174p-1
+nextAfter,-0x1.2e39389f91825p-7,-0x1.2e39389f91826p-7,0x1.31957b7ce603fp-2
+nextAfter,0x1.0404311fd38a1p0,0x1.0404311fd38ap0,0x1.db676eba6fed8p0
+nextAfter,-0x1.7744fb7dd7754p-1,-0x1.7744fb7dd7755p-1,0x1.075f2e9c47bf9p0
+nextAfter,0x1.bc1f6e00f5653p-3,0x1.bc1f6e00f5652p-3,0x1.3daa3d6afeb7cp2
+nextAfter,-0x1.c3fa1c5007a79p-2,-0x1.c3fa1c5007a78p-2,-0x1.78f60d3038c85p0
+nextAfter,0x1.8554149e7b9fap-4,0x1.8554149e7b9fbp-4,-0x1.102e3f3445a0fp-2
+nextAfter,-0x1.1c6206a0ed743p-1,-0x1.1c6206a0ed744p-1,-0x1.e74f2c15e4d54p-2
+nextAfter,-0x1.137691287d8b5p-2,-0x1.137691287d8b6p-2,0x1.06dee8d77e3d4p0
+nextAfter,0x1.5082525ceb9dp0,0x1.5082525ceb9d1p0,-0x1.27df8770d5364p0
+nextAfter,-0x1.16e8b2c8f8c5bp0,-0x1.16e8b2c8f8c5cp0,-0x1.a2ac01f652f22p-2
+nextAfter,-0x1.18c24796b1f6ep0,-0x1.18c24796b1f6fp0,0x1.090a349f4f2cp-3
+nextAfter,0x1.01faad9be063ap0,0x1.01faad9be063bp0,-0x1.701e1211a7b79p0
+nextAfter,0x1.99eb635ab89d1p-1,0x1.99eb635ab89d2p-1,-0x1.02f2bbb004abp1
+nextAfter,-0x1.c0b2ae0869a07p-4,-0x1.c0b2ae0869a08p-4,0x1.df7f53186a43ep0
+nextAfter,-0x1.b73d82e0c9a3dp0,-0x1.b73d82e0c9a3ep0,0x1.cc10ae0c5afe1p1
+nextAfter,0x1.129bd54ca61fp0,0x1.129bd54ca61f1p0,-0x1.db17ccd4a3f39p0
+nextAfter,0x1.a1146b7fbd789p-2,0x1.a1146b7fbd788p-2,0x1.996c59bfa19aap0
+nextAfter,-0x1.82335e167998fp4,-0x1.82335e167999p4,0x1.63f96ea33b812p-1
+nextAfter,0x1.27428424410acp0,0x1.27428424410abp0,0x1.7fa5a37c5990ap0
+nextAfter,-0x1.e222b0b6465ecp-2,-0x1.e222b0b6465edp-2,0x1.a0ef11dc9f2cep1
+nextAfter,-0x1.067fe1e10df97p1,-0x1.067fe1e10df98p1,0x1.4023b82c14d38p0
+nextAfter,0x1.418b7723e09edp0,0x1.418b7723e09eep0,-0x1.664ba9ba979ap-1
+nextAfter,-0x1.87080d5637d8cp-2,-0x1.87080d5637d8dp-2,0x1.4a6dd635b9104p-1
+nextAfter,-0x1.fc18e6d02940ap-1,-0x1.fc18e6d02940bp-1,-0x1.f19d7613c72abp-1
+nextAfter,0x1.d9d98db8c362dp1,0x1.d9d98db8c362ep1,-0x1.5d41c3f9a33dbp0
+nextAfter,-0x1.45b9cb3f31823p3,-0x1.45b9cb3f31824p3,0x1.603e322c512bap3
+nextAfter,-0x1.c71b747662ba7p-1,-0x1.c71b747662ba8p-1,-0x1.bab823fa2de24p-3
+nextAfter,0x1.1903f8b16baf3p-1,0x1.1903f8b16baf4p-1,-0x1.86c449048485p1
+nextAfter,0x1.2d7b9c45c61bbp1,0x1.2d7b9c45c61bcp1,0x1.754bcf7aa2cd2p-2
+nextAfter,-0x1.d121889bcf0edp-1,-0x1.d121889bcf0ecp-1,-0x1.d06b6c9d7c26ep3
+nextAfter,0x1.16cb05c6d4645p0,0x1.16cb05c6d4646p0,-0x1.e2d9919ca51f8p-1
+nextAfter,0x1.4bae2cc676e97p-2,0x1.4bae2cc676e96p-2,0x1.8212b8c75df29p-2
+nextAfter,0x1.ad92ab032b5b4p1,0x1.ad92ab032b5b5p1,-0x1.9ff12fc6dc92cp-3
+nextAfter,-0x1.f913004a6399dp1,-0x1.f913004a6399ep1,0x1.29b1616a10495p0
+nextAfter,0x1.f93514db1fcfp-5,0x1.f93514db1fcf1p-5,-0x1.5790d7e78012cp2
+nextAfter,-0x1.0a8f781a1d27ap-2,-0x1.0a8f781a1d27bp-2,0x1.1828e6ac11606p-2
+nextAfter,-0x1.f2b96848b118p0,-0x1.f2b96848b1181p0,-0x1.996c5e493b133p-3
+nextAfter,-0x1.6ae18cdc74a13p0,-0x1.6ae18cdc74a14p0,0x1.98a080c9ed305p3
+nextAfter,0x1.3d0661436de95p0,0x1.3d0661436de96p0,0x1.37e201923b73p-3
+nextAfter,0x1.f4d8d3f543b5p-3,0x1.f4d8d3f543b51p-3,-0x1.3f559c695c16fp-2
+nextAfter,-0x1.4da6088d207c9p2,-0x1.4da6088d207cap2,-0x1.2af134a1bc648p-2
+nextAfter,-0x1.3d16920744586p-2,-0x1.3d16920744587p-2,0x1.3696a5fd98068p-4
+nextAfter,0x1.c41e3a3208421p0,0x1.c41e3a3208422p0,0x1.766db3acfc398p-3
+nextAfter,0x1.861318513750bp-2,0x1.861318513750cp-2,0x1.10c6e3b329af8p-3
+nextAfter,0x1.090651142e1abp0,0x1.090651142e1acp0,-0x1.74cef95bb9b64p0
+nextAfter,0x1.a9afabf9d5443p5,0x1.a9afabf9d5444p5,0x1.d065e0ec9c193p-1
+nextAfter,-0x1.c134856a41724p-3,-0x1.c134856a41723p-3,-0x1.2452964c029f3p0
+nextAfter,-0x1.2f346c7a138c1p0,-0x1.2f346c7a138c2p0,0x1.e562ef5cbebe8p-1
+nextAfter,-0x1.52c791174a317p-2,-0x1.52c791174a318p-2,0x1.56a9ee5847c78p-2
+nextAfter,-0x1.e423e909074fap-1,-0x1.e423e909074fbp-1,-0x1.95c79cb8c6e94p-1
+nextAfter,0x1.7873f2f45fc5bp-2,0x1.7873f2f45fc5ap-2,0x1.500a588920313p1
+nextAfter,-0x1.79121493e8b55p-1,-0x1.79121493e8b56p-1,0x1.f252fbb8e02e9p0
+nextAfter,0x1.123d12f953371p-1,0x1.123d12f953372p-1,-0x1.006ee4c39945ep-1
+nextAfter,0x1.fc2f68afca109p0,0x1.fc2f68afca10ap0,0x1.ce207ceb1a883p0
+nextAfter,0x1.d430566acb85bp1,0x1.d430566acb85cp1,-0x1.71e632ff3e8c9p-2
+nextAfter,-0x1.4688d70c88797p-1,-0x1.4688d70c88798p-1,0x1.065d6da6343b4p0
+nextAfter,0x1.0f474783bacaap-1,0x1.0f474783bacabp-1,0x1.44bc0e877138dp-3
+abs,0x1.93d505df96a7bp1,-0x1.93d505df96a7bp1
+abs,0x1.772aabf17e9fap1,-0x1.772aabf17e9fap1
+abs,0x1.37482866cf6fbp0,0x1.37482866cf6fbp0
+abs,0x1.2f2d86b7d412bp0,-0x1.2f2d86b7d412bp0
+abs,0x1.1472bc84f162dp1,-0x1.1472bc84f162dp1
+abs,0x1.6f1aef4f2128fp-1,0x1.6f1aef4f2128fp-1
+abs,0x1.30f9423f14eeap0,-0x1.30f9423f14eeap0
+abs,0x1.a1c4694bb59efp-3,-0x1.a1c4694bb59efp-3
+abs,0x1.1103fecbf63fp0,-0x1.1103fecbf63fp0
+abs,0x1.2790898fcdf8ap1,-0x1.2790898fcdf8ap1
+abs,0x1.85960bf9370e4p2,-0x1.85960bf9370e4p2
+abs,0x1.f4e26ba23a8f5p-2,0x1.f4e26ba23a8f5p-2
+abs,0x1.10c18cfc2266p1,-0x1.10c18cfc2266p1
+abs,0x1.d7b107ca6e1afp3,-0x1.d7b107ca6e1afp3
+abs,0x1.ddee38e42203ep1,-0x1.ddee38e42203ep1
+abs,0x1.28da1d4f6bc26p2,-0x1.28da1d4f6bc26p2
+abs,0x1.3d5c63e8ecb65p-3,0x1.3d5c63e8ecb65p-3
+abs,0x1.3f055832d962dp2,0x1.3f055832d962dp2
+abs,0x1.1bece9ca0b776p5,-0x1.1bece9ca0b776p5
+abs,0x1.0bc00f4c3d999p-1,-0x1.0bc00f4c3d999p-1
+abs,0x1.68fd72aee66edp-2,-0x1.68fd72aee66edp-2
+abs,0x1.05123af8e5f4bp2,-0x1.05123af8e5f4bp2
+abs,0x1.ae1da006f080cp-6,0x1.ae1da006f080cp-6
+abs,0x1.90f8995fe2c91p-2,-0x1.90f8995fe2c91p-2
+abs,0x1.a87467f025ae1p-1,-0x1.a87467f025ae1p-1
+abs,0x1.e7fc319a4a286p-1,-0x1.e7fc319a4a286p-1
+abs,0x1.c93f851b2b5acp0,-0x1.c93f851b2b5acp0
+abs,0x1.103f892adf582p-1,0x1.103f892adf582p-1
+abs,0x1.6b0c4defd374p1,0x1.6b0c4defd374p1
+abs,0x1.07a14b2653758p0,0x1.07a14b2653758p0
+abs,0x1.8d534af6cd513p-2,-0x1.8d534af6cd513p-2
+abs,0x1.11d810c944e87p-4,-0x1.11d810c944e87p-4
+abs,0x1.b829be3ebdb13p-1,0x1.b829be3ebdb13p-1
+abs,0x1.fbeb13841fb27p-2,-0x1.fbeb13841fb27p-2
+abs,0x1.37d5860b925e1p-5,-0x1.37d5860b925e1p-5
+abs,0x1.3dd9a55c7b433p0,-0x1.3dd9a55c7b433p0
+abs,0x1.2bc0c7abed8a9p1,0x1.2bc0c7abed8a9p1
+abs,0x1.fd5a3d1160a29p2,0x1.fd5a3d1160a29p2
+abs,0x1.688a787f82432p-1,-0x1.688a787f82432p-1
+abs,0x1.951f0f59938e3p-3,0x1.951f0f59938e3p-3
+abs,0x1.a56f068d6f1c2p-2,-0x1.a56f068d6f1c2p-2
+abs,0x1.b734658226c62p1,0x1.b734658226c62p1
+abs,0x1.1edb19bf46cb3p-3,-0x1.1edb19bf46cb3p-3
+abs,0x1.e22fb685f7d56p-1,-0x1.e22fb685f7d56p-1
+abs,0x1.892b4e3724ad9p-1,0x1.892b4e3724ad9p-1
+abs,0x1.0ffcf5c95424cp0,-0x1.0ffcf5c95424cp0
+abs,0x1.6fd78d74ab1b4p-1,-0x1.6fd78d74ab1b4p-1
+abs,0x1.3ae03f54dd5efp5,0x1.3ae03f54dd5efp5
+abs,0x1.cc99e81a48a56p-3,0x1.cc99e81a48a56p-3
+abs,0x1.23749e32db3d7p0,0x1.23749e32db3d7p0
+abs,0x1.1a7f86b7edab4p1,-0x1.1a7f86b7edab4p1
+abs,0x1.023b9d65c66a8p0,-0x1.023b9d65c66a8p0
+abs,0x1.4a1fb6a7915fdp0,-0x1.4a1fb6a7915fdp0
+abs,0x1.af81ac251ece4p-3,-0x1.af81ac251ece4p-3
+abs,0x1.2923d510927d4p-1,-0x1.2923d510927d4p-1
+abs,0x1.4e77c7d585158p-2,0x1.4e77c7d585158p-2
+abs,0x1.f4b87199262b2p-2,0x1.f4b87199262b2p-2
+abs,0x1.18f7365dfc421p-1,-0x1.18f7365dfc421p-1
+abs,0x1.1924ecd75569p0,0x1.1924ecd75569p0
+abs,0x1.3f49e95c8e8cep0,-0x1.3f49e95c8e8cep0
+abs,0x1.2720bb83cb3a6p0,0x1.2720bb83cb3a6p0
+abs,0x1.1989d4d299b09p-2,0x1.1989d4d299b09p-2
+abs,0x1.40cce21585167p-2,0x1.40cce21585167p-2
+abs,0x1.6c17acb277c0fp-3,-0x1.6c17acb277c0fp-3
+abs,0x1.00f459acf7914p0,-0x1.00f459acf7914p0
+abs,0x1.438edcbe43ed7p-3,0x1.438edcbe43ed7p-3
+abs,0x1.bd85ef8c20593p-6,0x1.bd85ef8c20593p-6
+abs,0x1.df891eda559c8p-1,-0x1.df891eda559c8p-1
+abs,0x1.6e5b75d1137dp0,-0x1.6e5b75d1137dp0
+abs,0x1.02e678934f154p0,0x1.02e678934f154p0
+abs,0x1.d2d8c6b8d0cd8p-1,0x1.d2d8c6b8d0cd8p-1
+abs,0x1.4459aafa382f2p0,-0x1.4459aafa382f2p0
+abs,0x1.d1577c82fe71fp1,0x1.d1577c82fe71fp1
+abs,0x1.6a6fb3441e988p-1,-0x1.6a6fb3441e988p-1
+abs,0x1.3abccc514a8c2p1,0x1.3abccc514a8c2p1
+abs,0x1.55d0a948b9f51p0,-0x1.55d0a948b9f51p0
+abs,0x1.419af57d62a18p5,-0x1.419af57d62a18p5
+abs,0x1.d7374f447eb99p-1,0x1.d7374f447eb99p-1
+abs,0x1.1591ca359bf86p0,-0x1.1591ca359bf86p0
+abs,0x1.56227bd3b5c0ep0,0x1.56227bd3b5c0ep0
+abs,0x1.0d669e52d26eep0,0x1.0d669e52d26eep0
+abs,0x1.55967a2c5f14ep-1,0x1.55967a2c5f14ep-1
+abs,0x1.21c92c1da676ap-2,0x1.21c92c1da676ap-2
+abs,0x1.fa1f74f8ccfap-6,0x1.fa1f74f8ccfap-6
+abs,0x1.12f3cceec5f58p4,-0x1.12f3cceec5f58p4
+abs,0x1.f79f3804c644ep-2,0x1.f79f3804c644ep-2
+abs,0x1.077734a841ac4p0,0x1.077734a841ac4p0
+abs,0x1.6eb70a69e7edbp-7,-0x1.6eb70a69e7edbp-7
+abs,0x1.7b1acb6262a38p-5,0x1.7b1acb6262a38p-5
+abs,0x1.26bf90d99bad7p3,0x1.26bf90d99bad7p3
+abs,0x1.15e178c6e9cp-3,0x1.15e178c6e9cp-3
+abs,0x1.3db9d902c913dp-1,-0x1.3db9d902c913dp-1
+abs,0x1.5dc144017990dp2,0x1.5dc144017990dp2
+abs,0x1.57c20767d2d27p0,0x1.57c20767d2d27p0
+abs,0x1.51d561635d354p-1,-0x1.51d561635d354p-1
+abs,0x1.0767340df1842p-4,-0x1.0767340df1842p-4
+abs,0x1.6fe0b7cce7cacp-2,0x1.6fe0b7cce7cacp-2
+abs,0x1.b6cd599938293p1,0x1.b6cd599938293p1
+abs,0x1.6f4f9e1225456p0,0x1.6f4f9e1225456p0
+abs,0x1.e7fa55fb7eccep2,0x1.e7fa55fb7eccep2
+abs,0x1.e90530c032792p-1,-0x1.e90530c032792p-1
+abs,0x1.aede143746faap-2,0x1.aede143746faap-2
+abs,0x1.6969e23784517p-6,-0x1.6969e23784517p-6
+abs,0x1.28e79aec5c026p3,-0x1.28e79aec5c026p3
+abs,0x1.ce037c05e44c8p3,-0x1.ce037c05e44c8p3
+abs,0x1.9ceb675a53092p0,0x1.9ceb675a53092p0
+abs,0x1.e9100a74f2906p-3,-0x1.e9100a74f2906p-3
+abs,0x1.2e45cd1f857cbp0,0x1.2e45cd1f857cbp0
+abs,0x1.2fc7655c2a88cp0,-0x1.2fc7655c2a88cp0
+abs,0x1.f41aa97894034p-2,-0x1.f41aa97894034p-2
+abs,0x1.8f78641653a81p0,0x1.8f78641653a81p0
+abs,0x1.c891dfa01be47p-1,-0x1.c891dfa01be47p-1
+abs,0x1.14ada2fcadc78p0,-0x1.14ada2fcadc78p0
+abs,0x1.61ff113bad7cap-2,0x1.61ff113bad7cap-2
+abs,0x1.fe4f83a15e2bp0,0x1.fe4f83a15e2bp0
+abs,0x1.abf03b3e3555dp0,-0x1.abf03b3e3555dp0
+abs,0x1.36aeceb0a212fp2,0x1.36aeceb0a212fp2
+abs,0x1.4fd78714a7b1ap-1,0x1.4fd78714a7b1ap-1
+abs,0x1.b44cc28a57d79p-3,-0x1.b44cc28a57d79p-3
+abs,0x1.403f7b6e94691p-1,-0x1.403f7b6e94691p-1
+abs,0x1.1a3cf368dc818p-4,0x1.1a3cf368dc818p-4
+abs,0x1.e0927ac119806p-2,0x1.e0927ac119806p-2
+abs,0x1.19cdadc198e92p3,0x1.19cdadc198e92p3
+abs,0x1.e79c9a1248809p-1,-0x1.e79c9a1248809p-1
+abs,0x1.54e193436987ap-3,0x1.54e193436987ap-3
+abs,0x1.693883c2944e3p-1,0x1.693883c2944e3p-1
+abs,0x1.1610075970857p0,-0x1.1610075970857p0
+abs,0x1.ffd1d6b52e1f3p-1,-0x1.ffd1d6b52e1f3p-1
+abs,0x1.8e440475d4b95p0,-0x1.8e440475d4b95p0
+abs,0x1.3458e2df37c7ap3,0x1.3458e2df37c7ap3
+abs,0x1.5296b97c17ad7p-1,-0x1.5296b97c17ad7p-1
+abs,0x1.7bd42777c3a3cp0,-0x1.7bd42777c3a3cp0
+abs,0x1.f4011e1c00b13p-1,0x1.f4011e1c00b13p-1
+abs,0x1.effdb5c5f6168p1,0x1.effdb5c5f6168p1
+abs,0x1.106cfc6aa32dbp-1,-0x1.106cfc6aa32dbp-1
+abs,0x1.0891330243a0bp0,-0x1.0891330243a0bp0
+abs,0x1.2bb3ae2cd64ccp0,0x1.2bb3ae2cd64ccp0
+abs,0x1.be9ff1ff5cfbp-5,-0x1.be9ff1ff5cfbp-5
+abs,0x1.08f773894eb8bp1,-0x1.08f773894eb8bp1
+abs,0x1.c7b5126250ef1p0,0x1.c7b5126250ef1p0
+abs,0x1.5b72114574e27p-2,-0x1.5b72114574e27p-2
+abs,0x1.32da8c745294p1,0x1.32da8c745294p1
+abs,0x1.cba8780008dcbp-2,0x1.cba8780008dcbp-2
+abs,0x1.186280b392bep4,0x1.186280b392bep4
+abs,0x1.8b8c0931b034cp0,-0x1.8b8c0931b034cp0
+abs,0x1.5fa67dd961167p-1,-0x1.5fa67dd961167p-1
+abs,0x1.551e21d78f0d4p-1,0x1.551e21d78f0d4p-1
+abs,0x1.22b4cdfbcb362p2,0x1.22b4cdfbcb362p2
+abs,0x1.ca225fdeac97fp-4,0x1.ca225fdeac97fp-4
+abs,0x1.0b0315413a0adp-1,0x1.0b0315413a0adp-1
+abs,0x1.ab4f4dc47ce3dp-3,-0x1.ab4f4dc47ce3dp-3
+abs,0x1.459687e380122p-1,0x1.459687e380122p-1
+abs,0x1.2f865e72c5265p0,-0x1.2f865e72c5265p0
+abs,0x1.34f6f6cb1934ep0,0x1.34f6f6cb1934ep0
+abs,0x1.432e98ef925b8p0,-0x1.432e98ef925b8p0
+abs,0x1.030bc46593191p1,0x1.030bc46593191p1
+abs,0x1.b98a6750454a2p1,-0x1.b98a6750454a2p1
+abs,0x1.8c7a3a12eee03p-1,-0x1.8c7a3a12eee03p-1
+abs,0x1.fe3058a015c36p0,0x1.fe3058a015c36p0
+abs,0x1.4d5d66f59a092p2,-0x1.4d5d66f59a092p2
+abs,0x1.74fcf42a3e1e6p-2,-0x1.74fcf42a3e1e6p-2
+abs,0x1.65ed78fde4a9fp-1,0x1.65ed78fde4a9fp-1
+abs,0x1.d6ad78f43f9fp-2,-0x1.d6ad78f43f9fp-2
+abs,0x1.1bf0d35c15f61p0,-0x1.1bf0d35c15f61p0
+abs,0x1.c234de2271c65p-1,-0x1.c234de2271c65p-1
+abs,0x1.a7ad8ccd0f414p-1,-0x1.a7ad8ccd0f414p-1
+abs,0x1.b91cb0c0fa85ep-1,0x1.b91cb0c0fa85ep-1
+abs,0x1.121ac693ebb86p-3,0x1.121ac693ebb86p-3
+abs,0x1.774634c5bc94fp1,0x1.774634c5bc94fp1
+abs,0x1.23736fad28ac2p0,-0x1.23736fad28ac2p0
+abs,0x1.16dcf13a36185p0,-0x1.16dcf13a36185p0
+abs,0x1.82f85e5afa85ap-1,0x1.82f85e5afa85ap-1
+abs,0x1.895fc8b8eacc6p-1,0x1.895fc8b8eacc6p-1
+abs,0x1.2117248907393p-3,-0x1.2117248907393p-3
+abs,0x1.f1f1146df8bfep-1,-0x1.f1f1146df8bfep-1
+abs,0x1.4d08b68590db6p1,0x1.4d08b68590db6p1
+abs,0x1.0c2eedacd78ecp2,-0x1.0c2eedacd78ecp2
+abs,0x1.04ff93904e7a1p0,0x1.04ff93904e7a1p0
+abs,0x1.52aea1019dbc7p0,0x1.52aea1019dbc7p0
+abs,0x1.49086e1eb7f06p2,0x1.49086e1eb7f06p2
+abs,0x1.0b51b71c9c682p0,-0x1.0b51b71c9c682p0
+abs,0x1.3200aefc70fc2p-2,0x1.3200aefc70fc2p-2
+abs,0x1.e2e55f712f1adp-2,0x1.e2e55f712f1adp-2
+abs,0x1.5ea7722f6926cp-1,-0x1.5ea7722f6926cp-1
+abs,0x1.605dda7bbb498p-3,0x1.605dda7bbb498p-3
+abs,0x1.f5e9671f15694p-4,0x1.f5e9671f15694p-4
+abs,0x1.4f51d4031a0dp1,0x1.4f51d4031a0dp1
+abs,0x1.9f16ddc8cc68p-1,-0x1.9f16ddc8cc68p-1
+abs,0x1.da1e2e2f3ba9ap1,-0x1.da1e2e2f3ba9ap1
+abs,0x1.3e8a3a1ab480dp0,0x1.3e8a3a1ab480dp0
+abs,0x1.38e94bfc0c46ep1,0x1.38e94bfc0c46ep1
+abs,0x1.85788c2b568c8p0,0x1.85788c2b568c8p0
+abs,0x1.3f840392c269p0,-0x1.3f840392c269p0
+abs,0x1.cd26590ce463ap-7,-0x1.cd26590ce463ap-7
+abs,0x1.5e41a655a608ep-3,0x1.5e41a655a608ep-3
+abs,0x1.aa8028d9180efp0,-0x1.aa8028d9180efp0
+abs,0x1.11f51d15d857fp0,-0x1.11f51d15d857fp0
+abs,0x1.672f3ae9686cp0,-0x1.672f3ae9686cp0
+abs,0x1.89d73545edf5ap-2,0x1.89d73545edf5ap-2
+abs,0x1.152d198dcbd0ep2,0x1.152d198dcbd0ep2
+atan2,0x1.de03edb049d13p-1,0x1.8531a596c72ddp0,0x1.2010ab87fdf6dp0
+atan2,0x1.5e0006fe03d5ep0,0x1.c182771ea4203p0,0x1.733d7681a0201p-2
+atan2,0x1.b72d4f4b19fddp-4,0x1.301d6da490bbdp-2,0x1.612ec509c4202p1
+atan2,0x1.6f866e02214e2p1,0x1.2351cd82c823bp0,-0x1.06d812d67873ap2
+atan2,-0x1.0b52faa4294e2p1,-0x1.8e2cbf42c945fp-2,-0x1.c580a7fc9515bp-3
+atan2,0x1.cf2522c614544p-2,0x1.7d2347a2a0dd1p-1,0x1.883636d3453dap0
+atan2,0x1.890fffc7530aap-3,0x1.a4d671182277ep-1,0x1.0eb7570fae77p2
+atan2,0x1.a6f9610e27639p0,0x1.cefa08776cab6p-2,-0x1.2e54c0dcddf09p-5
+atan2,-0x1.5ea763bb781efp1,-0x1.fcf1dc252265dp0,-0x1.2b2e4e65498dcp2
+atan2,0x1.97705aba63a9cp0,0x1.d48096493194ap2,-0x1.374eb130f3a5p-3
+atan2,-0x1.37b0fe54312dap0,-0x1.4a82d8a0972abp0,0x1.e7762fe006ed3p-2
+atan2,0x1.55af893e47505p-2,0x1.c29ff37dccd13p-1,0x1.44feece352863p1
+atan2,0x1.e79c3c35f399bp0,0x1.752f79cfd059fp1,-0x1.02eefddee1837p0
+atan2,-0x1.985b3b66967cfp0,-0x1.02a40ab498803p8,-0x1.9313481211377p2
+atan2,0x1.ebc6d113c5787p0,0x1.47e0d187a983ep0,-0x1.df0bc161eaf0ep-2
+atan2,0x1.24643d4b7307bp0,0x1.c500dc3114dd9p0,0x1.9e0679427dbcbp-1
+atan2,0x1.8075840902432p-1,0x1.365917ef27714p0,0x1.4c8992bb60496p0
+atan2,0x1.4bca202ed05bdp1,0x1.772950cedf728p-1,-0x1.324df7fca4f85p0
+atan2,-0x1.8a7ecc4cdab06p1,-0x1.5b61bc78e19a7p-3,-0x1.6bdd688222debp1
+atan2,-0x1.7dfc6760ba829p0,-0x1.6468153072616p0,0x1.c181fa014bbffp-4
+atan2,0x1.067687fca9579p1,0x1.a106a730216ffp-2,-0x1.b1e4ecbdc6b6dp-3
+atan2,-0x1.aaf01c5d7b691p0,-0x1.9253b2abd0f6cp2,-0x1.38f60891bbacbp-1
+atan2,0x1.c60716ff8b4e5p0,0x1.ded02fca4aaccp1,-0x1.89b9e49345cbcp-1
+atan2,0x1.d589c41922022p0,0x1.0456351e08dfdp2,-0x1.18beb9570a313p0
+atan2,0x1.6dea06954837bp-2,0x1.849cec7964a43p-2,0x1.043565f785b81p0
+atan2,0x1.d1b8b75ca0805p0,0x1.bfa160b08cdf7p-1,-0x1.c632f73f14dfcp-3
+atan2,0x1.a498ca4fb0bc5p-2,0x1.010d5c02134edp0,0x1.271dbba8fa0abp1
+atan2,0x1.cba2802a80af5p-2,0x1.3feeced139a2dp-1,0x1.4c1ebc6c3c97p0
+atan2,-0x1.6bb2871a033dap1,-0x1.e2f34e0f5f988p-1,-0x1.8606a5e36c881p1
+atan2,0x1.1e2c1bae7d344p-2,0x1.1fca5abfa28d3p-3,0x1.f56b92435c166p-2
+atan2,-0x1.2d97b06159e9ap0,-0x1.95ad099b4ffbap-1,0x1.501303e00fa1dp-2
+atan2,0x1.709095033bc0ap1,0x1.8b8012a0223bap-2,-0x1.7071fcced3a65p0
+atan2,-0x1.0e6ae461133f2p1,-0x1.2b5cc52a3cf34p0,-0x1.6864a45b28908p-1
+atan2,-0x1.30b6cec1fc3f2p0,-0x1.acf7dd9105681p1,0x1.572cd3952f421p0
+atan2,0x1.370509592bb79p0,0x1.1777716e04b44p-1,0x1.9f833a4b4c096p-3
+atan2,0x1.7de31c93532acp1,0x1.5ff6c65ef376ap-2,-0x1.13f48c186e1c8p1
+atan2,0x1.ae9074154b5eap-3,0x1.3b0d32e25bbafp-1,0x1.711a84da4c808p1
+atan2,0x1.d665ce6a0df3cp-2,0x1.f00bdaf915ee6p-2,0x1.f564b5ae2ab47p-1
+atan2,-0x1.24546839d5b5fp1,-0x1.6bcd13101c4d2p-2,-0x1.3a9e6f6d70c5cp-2
+atan2,0x1.b0b4973d0e301p-3,0x1.89b90df4f741bp-2,0x1.caebbbdbb7369p0
+atan2,0x1.01f719228a78p1,0x1.ce7c2ec5315c8p-1,-0x1.b89e4d2564028p-2
+atan2,-0x1.789052f3b2dc7p0,-0x1.3a30f0aabfdebp1,0x1.f798c6ae52b61p-3
+atan2,-0x1.2d3cbab22d24p-2,-0x1.507136d9a808p0,0x1.159f593069f8dp2
+atan2,-0x1.a917d9f1c7243p0,-0x1.e5f48d5274b6cp-1,-0x1.5dc0db2921ab6p-4
+atan2,0x1.7fde965bf75f6p1,0x1.1879ea9a3f83ap-4,-0x1.e85693e92bd12p-2
+atan2,-0x1.37321703b449ep-1,-0x1.5678e01a6da7ap0,0x1.ec4d3620d0bdep0
+atan2,-0x1.48851ef932712p0,-0x1.8d2218d992ac1p-1,0x1.d5be246627fdp-3
+atan2,0x1.609789f81f64dp0,0x1.54a5a5ed0a069p3,0x1.0afa9ca5db82ap1
+atan2,0x1.821ae4a866496p1,0x1.79b65fcbdac1fp-1,-0x1.774c1b6003141p2
+atan2,0x1.14a8aa61cb474p-2,0x1.62d5ae5a96817p-1,0x1.404f660747c32p1
+atan2,0x1.72c718376a293p0,0x1.6e7770b244647p2,0x1.68c890c719b54p-1
+atan2,0x1.8f2e449945382p1,0x1.e442bbdf44b94p-2,-0x1.49056da0024d3p4
+atan2,0x1.40ff4e69cabaap0,0x1.b985a770343b2p0,0x1.2198e0b9d8d86p-1
+atan2,-0x1.e2b69f2c7b8a5p-13,-0x1.ee045e5e8d48bp-4,0x1.05fea7c172b9ap9
+atan2,-0x1.62313f6cb77bp0,-0x1.9873918570a35p0,0x1.3586d6eb4034p-2
+atan2,0x1.a210376fa870cp-1,0x1.958578988276p-1,0x1.7d06dbbc83cfcp-1
+atan2,0x1.8c129ae734679p0,0x1.9adca1b305d52p0,0x1.36d53bd11117cp-5
+atan2,-0x1.4196e5881496ap-1,-0x1.f977843e6d1d2p-1,0x1.5c03b1b1397e1p0
+atan2,0x1.c6e4a0a217f9bp-2,0x1.7a682e6a5d087p-3,0x1.8d84fdf370e1ep-2
+atan2,-0x1.17494c09f4f49p0,-0x1.a6724ea3a4c16p0,0x1.b7aeb0c75bfb7p-1
+atan2,-0x1.769ba827e371ep1,-0x1.114d061d2e95ep-2,-0x1.38edcb6d51326p0
+atan2,-0x1.888fe8d4addf5p1,-0x1.89e8bc6b0ef05p-1,-0x1.48f5709f268f7p3
+atan2,0x1.53d830906ecfp1,0x1.4c1cc00421dbap0,-0x1.39ebc36d9eb3fp1
+atan2,0x1.dff17c7821d6cp0,0x1.4ca941e6f8208p1,-0x1.a16e0565eb6b7p-1
+atan2,-0x1.5e0acc5f8fa83p-2,-0x1.01bd6aa09efd9p-1,0x1.6a30fb1f64f7dp0
+atan2,-0x1.6f33096e2714cp0,-0x1.a090328de346ap1,0x1.c9798e65adb9bp-2
+atan2,-0x1.a8eb5e1bb1255p0,-0x1.94664cc1227aep0,-0x1.20d79cf55f344p-3
+atan2,0x1.a3b503a18cc39p-1,0x1.9b54e5610ff14p-2,0x1.8001d5a6b8da1p-2
+atan2,-0x1.0fd6e19af269ep1,-0x1.6206ad4eae709p0,-0x1.b4fd0b775e25p-1
+atan2,0x1.fae70394d2c5p-4,0x1.5249bb08021cp-2,0x1.53f19d1ca151p1
+atan2,-0x1.29a0832eebf8dp0,-0x1.1c96da5e6fc3fp1,0x1.ec51a5852bfefp-1
+atan2,-0x1.7e6b861b81ef1p-1,-0x1.2a298c65321p-2,0x1.420ac5a0e085ep-2
+atan2,-0x1.742fea3c19d5bp1,-0x1.aa4dc36acc419p-1,-0x1.bf58b46f897f4p1
+atan2,0x1.078c9ce3d28bcp-1,0x1.1aab5553a169fp0,0x1.f3c3ce535d04bp0
+atan2,-0x1.4ea1d1782dbe1p-2,-0x1.1ac709ff8ecc6p0,0x1.a125f33f1e745p1
+atan2,0x1.18a1758a0aeacp-3,0x1.1b257d57e6401p-1,0x1.00ad22300d8c1p2
+atan2,-0x1.54f133eca1efep-5,-0x1.062c7be3ee3aap-2,0x1.897c055a404b6p2
+atan2,0x1.db66a72b7feb7p-1,0x1.0c2a245ff88d3p-2,0x1.9139391cabeb7p-3
+atan2,-0x1.36a51f11e0a19p1,-0x1.34d94e40c206cp0,-0x1.63f0e9f526d3dp0
+atan2,-0x1.56e0fce629779p-1,-0x1.bb76e79222ffep-2,0x1.180e60c28dd0dp-1
+atan2,0x1.1555fc07b00dp0,0x1.954dd20260f1bp0,0x1.adb8675b4478dp-1
+atan2,0x1.8242b6b8dc774p1,0x1.9a2f1c20f8cb6p-6,-0x1.9b997997aa3acp-3
+atan2,0x1.c9f77561fdda3p-1,0x1.04c5e032acc82p1,0x1.a2990c116f182p0
+atan2,0x1.06ae73edd64f8p1,0x1.afe9a377db5bbp-1,-0x1.c342047c5e69ep-2
+atan2,-0x1.0925a20bab4c3p1,-0x1.02e714ca716aap0,-0x1.1b534b24dc808p-1
+atan2,0x1.0318b83509e4ap0,0x1.53e60fb0dda16p0,0x1.a8f809c1ee6d2p-1
+atan2,-0x1.1c163bdeb02cp1,-0x1.8324618f989a3p0,-0x1.2578f25491111p0
+atan2,-0x1.509d46bb514dbp-3,-0x1.11db57a457979p-3,0x1.9cc945e5ab0e9p-1
+atan2,-0x1.273d736490657p-3,-0x1.e62a841d979dp-1,0x1.a2a03f25d4f12p2
+atan2,0x1.5d211bb9a4f16p-1,0x1.1979327f1dda2p-1,0x1.5aba887618f13p-1
+atan2,0x1.f99ef79bfe351p0,0x1.cabcf958e7b22p-1,-0x1.888bc54c3d127p-2
+atan2,-0x1.69d9687d7e301p1,-0x1.48c15fcf05e9fp-3,-0x1.f91123678c42dp-2
+atan2,-0x1.95683b903b191p0,-0x1.25b5c01517032p1,-0x1.e231fdffb84c1p-6
+atan2,-0x1.a3937ba3870a3p-1,-0x1.fdfa9b8718bbfp-2,0x1.dc587bb5598fbp-2
+atan2,0x1.d53cd872fe0b9p-4,0x1.e65900eeed15fp-4,0x1.082c408376464p0
+atan2,0x1.9b565b8da9814p0,0x1.fcff459d37763p-3,-0x1.253a8897ee4b5p-7
+atan2,0x1.4da18efc303a4p1,0x1.82ad70acbf6b7p0,-0x1.4626ca1c67ec6p1
+atan2,0x1.604db2b36a6e5p-2,0x1.ac15184e794f7p-4,0x1.2ab1717453984p-2
+atan2,0x1.2012611f36814p0,0x1.0e343be9dc285p1,0x1.02108970390f7p0
+atan2,0x1.b72104f7430a1p0,0x1.06f82022d9733p-1,-0x1.323c7773d129fp-4
+atan2,-0x1.d86db4c7e68fcp0,-0x1.15fff12ca5807p1,-0x1.394d52d5023d1p-1
+atan2,-0x1.bf6905834b3ebp0,-0x1.75abb1869d4bep2,-0x1.0b33cbeef85b1p0
+atan2,-0x1.19f27ea9add42p1,-0x1.adcf68cc0ca0bp0,-0x1.3aa4f4cda49a5p0
+atan2,0x1.1306a149435bp1,0x1.70eefafe5917p0,-0x1.e127fb7ac364dp-1
+atan2,0x1.065c279976392p-1,0x1.4d44ea2be9449p0,0x1.28378318fb1a8p1
+atan2,0x1.0b42d6b5b60d3p0,0x1.b82ba68eeaecap0,0x1.0004f4f2b9327p0
+atan2,-0x1.82e8284d431c9p1,-0x1.46ccb8a2d679ep-4,-0x1.55fec3def5839p-1
+atan2,0x1.f57bf8bd7c88dp-2,0x1.22bb569e3959ep-1,0x1.10b5b96e5ea49p0
+atan2,-0x1.63bf11e016f7dp-5,-0x1.efdc0bc4c9265p-4,0x1.649a61b038e17p1
+atan2,0x1.f108930cd5e6fp0,0x1.932ebb0529ffcp3,-0x1.39725a3cb358fp2
+atan2,0x1.81f09ceac7869p1,0x1.5fe4076ec4b1bp-2,-0x1.5a08f1681a41ap1
+atan2,-0x1.4b77647f83b03p0,-0x1.7fc8488ed5daap-3,0x1.b2cd533f2ac1ep-5
+atan2,0x1.101599c7ae0bep1,0x1.7979dcd1b104fp1,-0x1.d3ee7246ffaebp0
+atan2,-0x1.7b4853c777fbfp1,-0x1.596b976af1eb8p-1,-0x1.dec68c99aa45ap1
+atan2,-0x1.7453cfed8453fp1,-0x1.8ebf10238b687p-1,-0x1.a478b2a6f406dp1
+atan2,0x1.6142b2fc8b2c8p1,0x1.27e2fd81b5286p1,-0x1.7088c6d494f5dp2
+atan2,0x1.10cb9ed389c7ap1,0x1.b277dc0802e77p-1,-0x1.10a47abc4594bp-1
+atan2,-0x1.84f3f975b062p-1,-0x1.025d458a8188cp0,0x1.1002c8cd205d3p0
+atan2,-0x1.45988b51f4ab8p0,-0x1.e7f58fefb33f3p0,0x1.2cc049c474f57p-1
+atan2,-0x1.830ebac024c1fp1,-0x1.4045312f6bdbcp-3,-0x1.528bad6448038p0
+atan2,0x1.c8bb6ff9d42e3p0,0x1.f93e9e6e08b08p-1,-0x1.b5c332f661ca3p-3
+atan2,-0x1.465edfae23b18p1,-0x1.1f89c7d0ccc82p0,-0x1.abc2121cfab0ap0
+atan2,0x1.8565facce856ap0,0x1.d460bf318d18fp0,0x1.74d420fa2210dp-4
+atan2,0x1.0a0b88c880adap1,0x1.140ce10bdcd4cp1,-0x1.3324b090e8ee9p0
+atan2,0x1.5743b0ba8309cp-3,0x1.77d22d03e36c2p-2,0x1.15a687f77a71dp1
+atan2,-0x1.27ddefe6d9ffdp1,-0x1.149def9def705p-1,-0x1.f9d384ccbcc0bp-2
+atan2,0x1.404d2e333699ap1,0x1.989bc87d39ca8p-1,-0x1.12d6dc77dea54p0
+atan2,0x1.df721ca61dep-4,0x1.b2c02bf4a8d96p-1,0x1.ce25d8f777814p2
+atan2,-0x1.b3266f9c4939p0,-0x1.26854202382ebp2,-0x1.31a9f064ac1f9p-1
+atan2,0x1.8b84119b2494cp1,0x1.1688fb5dd5857p-4,-0x1.50e9627d3598dp0
+atan2,-0x1.f98f119fd229p0,-0x1.f3346f229d591p0,-0x1.aae318faf10a1p-1
+atan2,0x1.3983f65ece5e1p0,0x1.717c62e3fd8f4p2,0x1.0a81a9cf2bf7bp1
+atan2,-0x1.6932ebbc0a0fap0,-0x1.c92cf129a6261p1,0x1.26dbabb91199ap-1
+atan2,0x1.7a70a47a07ebep0,0x1.25cfb390c3934p1,0x1.b4281314ab214p-3
+atan2,0x1.c798a348bd1d6p0,0x1.e26ba3d7617afp0,-0x1.9907f947b4d63p-2
+atan2,-0x1.ec5187825e41bp0,-0x1.86ee51516a48ap1,-0x1.1f762d273aa95p0
+atan2,-0x1.73d313d8a95dep0,-0x1.7952cd69e1a04p-2,0x1.66f2af5e4527ap-5
+atan2,-0x1.7b64745f8ab0cp0,-0x1.5e15714a4c344p2,0x1.f2ae5421949dcp-2
+atan2,0x1.749f1ecb63879p-1,0x1.cfc73426ef23ep0,0x1.0447b54270e27p1
+atan2,-0x1.0aabe585fc8bap1,-0x1.7462ea39e2844p-1,-0x1.a31dbcb30d94bp-2
+atan2,-0x1.dd882de264022p0,-0x1.143c00f69d8fbp-1,-0x1.4f39c4340c992p-3
+atan2,-0x1.b50e6f8ffeedep0,-0x1.a8c4cc4862be3p-1,-0x1.d298460311b81p-4
+atan2,0x1.59f326f55e2p-1,0x1.c21458620b4b8p-3,0x1.18c1c5f7cbaf8p-2
+atan2,-0x1.e8638ced79c02p-1,-0x1.00a539603b877p2,0x1.6c0e1f5008171p1
+atan2,0x1.953f61e4f0744p0,0x1.0f8c3405d7a69p1,-0x1.a8243d0f95c4p-6
+atan2,-0x1.1a47bfebeeca8p1,-0x1.08ad8ea32e6d2p1,-0x1.85a2f8fd8f9afp0
+atan2,-0x1.660582e3c4a18p-2,-0x1.5d413746cc898p-2,0x1.def17c3f1dca3p-1
+atan2,-0x1.c5f468ac0cc53p0,-0x1.61793f458a773p1,-0x1.223d67c9babfap-1
+atan2,0x1.35e032a100decp1,0x1.b90c7fac94cd9p-1,-0x1.f62b796c51d15p-1
+atan2,-0x1.0d74faaea9b69p0,-0x1.126cdf0fefbdbp-1,0x1.38f65b42f19e1p-2
+atan2,-0x1.2d5bfee8358dp-4,-0x1.f21811e033cafp-4,0x1.a65bf6789b3adp0
+atan2,0x1.fead2bcbda9a7p-3,0x1.7f2398c779c02p-2,0x1.78232e66cfe1fp0
+atan2,-0x1.a8eff7b510feep0,-0x1.375321eeb9911p-3,-0x1.bd145be95394ep-7
+atan2,0x1.888bddd2168b6p1,0x1.3dd43a7b8369fp-3,-0x1.08fbe2f16fa6ep1
+atan2,0x1.89d07ec3a987dp1,0x1.4ae2b3dcfee33p-1,-0x1.3e1dcfa5a2338p3
+atan2,-0x1.04505b38996eep-2,-0x1.2da56f69e264dp0,0x1.223abfcf0e517p2
+atan2,0x1.8a68bdd90bdb3p1,0x1.ff097deb57743p-4,-0x1.08a5878452126p1
+atan2,0x1.1b492e98b09f4p1,0x1.98f1db91e4747p-2,-0x1.31fd43259db6ep-2
+atan2,-0x1.cdeca28129f61p0,-0x1.0ddb5ec777b1ep3,-0x1.00d69e4f78288p1
+atan2,-0x1.8a732af02607bp-2,-0x1.32d285280db1fp-1,0x1.7a5cd769730f5p0
+atan2,-0x1.d8e363a972f7bp-4,-0x1.53e99b8f23c3ep0,0x1.6e63b6d4cbd22p3
+atan2,0x1.50dac88f484bbp-4,0x1.74a21b041d867p-5,0x1.1a8d4f888e88bp-1
+atan2,-0x1.816dd590faa0dp-2,-0x1.9213b4b67e0f6p-2,0x1.fca66e9b5d54ap-1
+atan2,0x1.a9a5ee00ac2dap0,0x1.8bae1f4196731p2,-0x1.23b31b9f32697p-1
+atan2,-0x1.faf0ce42c982ep-3,-0x1.29eb4169cb92cp1,0x1.26b8c05863f5bp3
+atan2,-0x1.eaaa5f467858fp0,-0x1.285c4e6cdf603p4,-0x1.ab2cbbadc1ddcp2
+atan2,0x1.ff4616f547a1ep0,0x1.8f8a31e1ca847p-2,-0x1.6af7802be4411p-3
+atan2,0x1.cfc8e24b5ea9fp-3,0x1.87bfad3f0dbc1p-1,0x1.a90e8f3a59402p1
+atan2,-0x1.8c8e52931226p1,-0x1.1ccf95145909p-5,-0x1.98f596f1b4914p-1
+atan2,0x1.30b7fbf4dda28p1,0x1.e86261670c322p-3,-0x1.006b6e47fcd0bp-2
+atan2,-0x1.357969aa6c1fep-9,-0x1.73bb55f449d6ep-3,0x1.337fda2a0394cp6
+atan2,-0x1.3d8aabdd357b4p1,-0x1.a304e63201fa1p0,-0x1.0d8170f940b17p1
+atan2,0x1.53f514034b516p-1,0x1.5c7a0f825fe66p-1,0x1.bd565e2aecf06p-1
+atan2,-0x1.5537c9fb835f4p-1,-0x1.05594de0c6ab9p0,0x1.4c4d84ae99b4bp0
+atan2,0x1.91f6f316cdc95p0,0x1.0f89a40ddf756p5,0x1.59dbc42aaec81p-6
+atan2,0x1.2d38e3c622bdbp1,0x1.c1aed8b1f0143p-1,-0x1.bf160907fe663p-1
+atan2,0x1.3a0ab45adb6ecp1,0x1.dcdfaf809f942p-1,-0x1.21fe4001672c3p0
+atan2,0x1.482e04a12cf2cp1,0x1.96b5b564c76d5p-1,-0x1.37f4dc2a85229p0
+atan2,-0x1.81fa9ebfcb2afp0,-0x1.04d705862e8c4p1,0x1.078d1ec038372p-3
+atan2,-0x1.4760cd439a41p0,-0x1.88b2f42d8944ap2,0x1.d8208920c4bep0
+atan2,-0x1.8bf3a7e26c76ap1,-0x1.a5e48f83b1e79p-1,-0x1.113551b415d1ep4
+atan2,0x1.5ece1300019a2p-1,0x1.2d5d5f1151862p0,0x1.70c22c9b532dfp0
+atan2,0x1.75203047182d4p0,0x1.4d6f118d774ffp3,0x1.2f74303910affp0
+atan2,-0x1.1bbb29dcfb463p0,-0x1.0ea2cc1ee2516p-1,0x1.0dd73d3be7cb4p-2
+atan2,0x1.045677713c2f9p0,0x1.90363e597b217p0,0x1.eeff07e652f6cp-1
+atan2,0x1.59e138f72538fp0,0x1.57c714f819c95p2,0x1.3312c3f0441d2p0
+atan2,-0x1.4de5bb8a088p-1,-0x1.a9638aec111dap-3,0x1.168b6bc596bb7p-2
+atan2,-0x1.8300988d4fbbcp1,-0x1.8bdf43770c699p-5,-0x1.a0eb5ece9ec6p-2
+atan2,0x1.07ce9b0b696eap-1,0x1.080444b721de1p0,0x1.d23d1e62ebe9ap0
+atan2,0x1.8165148cf64ap1,0x1.8755b7b0e38d6p-1,-0x1.7425d5e8213fdp2
+atan2,-0x1.7dbffaedfd904p1,-0x1.656aad633ba21p-1,-0x1.164f9c7898dbfp2
+atan2,0x1.14e8210eff74p1,0x1.ebba1b0512f93p0,-0x1.4b0c862007029p0
+atan2,0x1.8586c56cb0933p1,0x1.2e545fdd7b153p2,-0x1.7ebfbbb4eba28p5
+atan2,-0x1.75153d5f09e71p1,-0x1.f184a4d2915ddp-2,-0x1.0d6304e29e117p1
+atan2,-0x1.bb77ae1fdab8dp0,-0x1.cb2a56fefe0d3p1,-0x1.2b39678ca203fp-1
+atan2,0x1.8e5a65499458cp1,0x1.2894a3902f614p-4,-0x1.3a8549dc9b0ccp1
+atan2,-0x1.b91719f497b41p-3,-0x1.df4d1dd714f07p-2,0x1.11dcbf1574eefp1
+atan2,0x1.305e7fb3b741p1,0x1.6b4faec249ebp-2,-0x1.7b6c5993b8edfp-2
+atan2,0x1.edd2c7199e7ddp0,0x1.54448cf99a1a1p1,-0x1.fd8485d86e3d1p-1
+atan2,-0x1.3401bfed63a95p0,-0x1.66e0a92ea0f2ep-2,0x1.147299409fd4cp-3
+atan,-0x1.33165704aa45cp0,-0x1.48ce7d70e6a0ap1
+atan,-0x1.de5952193ae66p-1,-0x1.5a57f5de17072p0
+atan,0x1.06f3498431431p-2,0x1.0ce2f7d413cdbp-2
+atan,0x1.09880a837be19p-1,0x1.243625fb54079p-1
+atan,0x1.2fe6d3eaa8704p-1,0x1.597506ebdf281p-1
+atan,-0x1.0fcd8b99dfc03p0,-0x1.caabf588a3cc5p0
+atan,-0x1.a49bc345118c4p-2,-0x1.bdf9ec63e50ffp-2
+atan,0x1.5ac7ec427eac8p-1,0x1.9bc23b48b72d8p-1
+atan,0x1.41945d04de0cp0,0x1.8951863009812p1
+atan,-0x1.6c74432d0e219p0,-0x1.afcb6cee7c77ap2
+atan,-0x1.41c41c994a946p-1,-0x1.741794913226p-1
+atan,-0x1.2443ef2c3806fp0,-0x1.17bc6ed44f9f3p1
+atan,0x1.1128bf0f3871cp-1,0x1.2e694c7b05c15p-1
+atan,0x1.d4698288791cap-1,0x1.4ca3b26d8d82ep0
+atan,0x1.afcc60f0bcb0ep-1,0x1.1f89a522d3316p0
+atan,0x1.6d125a9b7bb56p0,0x1.b7186b7ade84ep2
+atan,0x1.ea0dadeb6b082p-1,0x1.6b7073c21e62cp0
+atan,-0x1.78aba01034404p-3,-0x1.7cf9d37c81681p-3
+atan,-0x1.5c930372a9d6cp0,-0x1.2d7bde8a004bdp2
+atan,-0x1.6d98da8db709bp-1,-0x1.bbb3f45e04d65p-1
+atan,0x1.9829a4523d781p-1,0x1.061c755ae1857p0
+atan,-0x1.2c06abf12181cp0,-0x1.2fbf66a7eebc8p1
+atan,-0x1.34f2d200715c2p0,-0x1.50034d8a3d3b3p1
+atan,-0x1.c7fcc5d31d0a2p-2,-0x1.e8b9e81bde969p-2
+atan,-0x1.17da370518f56p0,-0x1.ee98d1470ab33p0
+atan,-0x1.4d3468cfee20ap0,-0x1.cfe9d17d70632p1
+atan,-0x1.b52fd5ded91dfp-1,-0x1.25b43aad343c1p0
+atan,-0x1.3521e834ac2acp0,-0x1.50bd7036a1a14p1
+atan,0x1.c383a281514a8p-2,0x1.e33ed607c28fep-2
+atan,0x1.0eb0e18395494p0,0x1.c606bace6103bp0
+atan,0x1.26feeb6ecedd6p-1,0x1.4ca55ad8d1706p-1
+atan,-0x1.fe2c5be73da28p-1,-0x1.8b95bd1c4cdefp0
+atan,0x1.0f98bcd9dd79dp-1,0x1.2c4eb5ee7b93fp-1
+atan,0x1.355f89cd233a4p0,0x1.51b222746e1dbp1
+atan,0x1.4abb434831bcep0,0x1.bf061660d03d2p1
+atan,0x1.353715d6ccacdp-1,0x1.613e9203ee421p-1
+atan,-0x1.eb96418ceb959p-1,-0x1.6dc2e3d405926p0
+atan,0x1.2fe249360fc78p-1,0x1.596e6aef899d8p-1
+atan,0x1.c881a53fe929bp-1,0x1.3d1a43a0ec22bp0
+atan,-0x1.926d325cac869p-1,-0x1.004d88d506e55p0
+atan,0x1.0f06eb6365d4ap-1,0x1.2b8adad3f7469p-1
+atan,-0x1.ef1f54763a778p-2,-0x1.0cd8a9c8498a9p-1
+atan,-0x1.3c8c4e149aad4p-2,-0x1.47083d40a57bep-2
+atan,-0x1.0c6e0ae142604p0,-0x1.bccc22763b743p0
+atan,-0x1.2809e19754ddcp0,-0x1.22ff391284474p1
+atan,-0x1.16c7aa436594p0,-0x1.e98fe178c5c6ep0
+atan,0x1.6aff81476fbb2p-4,0x1.6bf38e022962bp-4
+atan,0x1.4fdd199943858p0,0x1.e371388d4c39fp1
+atan,0x1.7a4bb67128b3p0,0x1.56cd60b54446ep3
+atan,-0x1.3059942eaa704p-2,-0x1.39a3e3bf39e3ep-2
+atan,-0x1.3afd7b1c0e3a4p-2,-0x1.4550f332fd795p-2
+atan,0x1.347d64811efa8p0,0x1.4e3626bfb4c66p1
+atan,-0x1.12a6812d28c97p-3,-0x1.144f0f9b4d222p-3
+atan,-0x1.bfc52ead8cf51p-1,-0x1.3242afc2d5d0bp0
+atan,-0x1.b943df8d2808dp-1,-0x1.2a78891234ae7p0
+atan,-0x1.d545f6a23e406p-1,-0x1.4dccad3454358p0
+atan,0x1.d3a6888178694p-1,0x1.4b9e1e2213afap0
+atan,-0x1.78855f59205fbp-1,-0x1.cf31b2af98fbfp-1
+atan,0x1.24fc92601a428p0,0x1.19d4fbe477393p1
+atan,0x1.36cb4173e1262p-1,0x1.639466b78c0f4p-1
+atan,-0x1.5429610212e13p0,-0x1.033c41b92f0c3p2
+atan,-0x1.6aa01d66ca951p0,-0x1.9b8135c13d607p2
+atan,0x1.7e9f911fb35b1p0,0x1.a34720e578bp3
+atan,-0x1.eb5861b0dc1aap-1,-0x1.6d64dcdac7ca9p0
+atan,0x1.3b6335e848a48p0,0x1.6b38851191959p1
+atan,0x1.9bc09f7f59a63p-1,0x1.09d075c2661e9p0
+atan,-0x1.5272e2663d8a2p-2,-0x1.5f561c854244bp-2
+atan,-0x1.5f4b029f05c7p-1,-0x1.a33e03ca2098bp-1
+atan,-0x1.65dccee7071ddp0,-0x1.6e7824e12489fp2
+atan,-0x1.4dc9067ff1774p0,-0x1.d40cebe43f5f1p1
+atan,0x1.efd23c5ce2b7p-2,0x1.0d4ad22f826e2p-1
+atan,0x1.c2ee2f5856f38p-1,0x1.362170d1b0351p0
+atan,-0x1.85dc612ef9b63p-2,-0x1.99dba0d07634p-2
+atan,0x1.ca97437ccf1e8p-4,0x1.cc8446c65c6c5p-4
+atan,0x1.1411864cf386ap-1,0x1.32594c18ceadep-1
+atan,0x1.7296c27cf33d3p0,0x1.0275bea97e23dp3
+atan,0x1.782a4d0bb9283p-4,0x1.7939f249ae61ep-4
+atan,0x1.1bb405cbc8839p0,0x1.00af2f404991cp1
+atan,-0x1.3b37b44c27275p-2,-0x1.45910de53f2b7p-2
+atan,-0x1.f18b875c89894p-1,-0x1.76f9a6aa08e08p0
+atan,-0x1.d915b11dc1407p-1,-0x1.52feed902fba7p0
+atan,0x1.a88f73a728872p-1,0x1.177b006d6a75dp0
+atan,-0x1.f3eaa84bd5d49p-3,-0x1.fe1698c27c477p-3
+atan,-0x1.0d78245ba4e99p-2,-0x1.13dde72124156p-2
+atan,0x1.54786c45385c6p-1,0x1.9177dd1ebae81p-1
+atan,-0x1.3fdfde6471406p0,-0x1.80983c9ee91edp1
+atan,-0x1.c24edb8cfd9e4p-1,-0x1.355d26b233bbp0
+atan,0x1.27e6a825ce0bep-1,0x1.4def4a28afc6cp-1
+atan,-0x1.671235f445918p-9,-0x1.671270d28f888p-9
+atan,-0x1.168af6cc8109ap-3,-0x1.1845eb7ce10dep-3
+atan,-0x1.0af38f85b3ffdp0,-0x1.b6ea28d59635fp0
+atan,-0x1.17cad0f7c3cd5p0,-0x1.ee4ff932ba75fp0
+atan,-0x1.dfa325de2bae3p-2,-0x1.030bcce52d3fp-1
+atan,0x1.9fb60472c6027p-1,0x1.0df5fe264e83ap0
+atan,0x1.4566ccb67f798p0,0x1.9e3c08443230cp1
+atan,-0x1.81c26948658ddp0,-0x1.f3ea63670b06p3
+atan,-0x1.64332a21e0951p-3,-0x1.67d5e748d5bdbp-3
+atan,-0x1.4748db7a8e569p-3,-0x1.4a1975881b88cp-3
+atan,0x1.669aeb9f7d992p0,0x1.74d92729a23bbp2
+atan,0x1.b6b04a9422536p-1,0x1.2772fb93942cfp0
+atan,-0x1.33816bb25942fp-1,-0x1.5eba0ed9aaae7p-1
+atan,0x1.4348ea6b35971p-4,0x1.43f5327378dcdp-4
+atan,-0x1.7e422af591522p0,-0x1.9b8c2286641ep3
+atan,0x1.5d78b6712df06p-1,0x1.a0355485836d6p-1
+atan,0x1.885669177868p-1,0x1.eccacb067b7adp-1
+atan,-0x1.12a0f62d61ab8p-2,-0x1.1968856cc5476p-2
+atan,-0x1.7fcd7f2f67864p0,-0x1.be5ec2f68c954p3
+atan,-0x1.849099f32d7a5p-1,-0x1.e593597e6fc7ap-1
+atan,-0x1.14a1e3eaf0c74p-1,-0x1.331d79f2731f6p-1
+atan,0x1.0584405998b0bp-1,0x1.1ee99f427692bp-1
+atan,0x1.4fa26243ec533p-5,0x1.4fd27e42fee18p-5
+atan,0x1.23f76c5b291dap0,0x1.16e006acb8705p1
+atan,0x1.6a2c00d87d8cbp0,0x1.96c1f56bb3ecp2
+atan,0x1.ce2ede3cfe213p-1,0x1.4465757dbedfbp0
+atan,-0x1.96de145a3522ap-3,-0x1.9c4e5eeeecbbep-3
+atan,0x1.fc986a4e02d85p-1,0x1.88ecbcd2d2faep0
+atan,-0x1.7d2bdd9dd963dp-1,-0x1.d7b88883d1ccp-1
+atan,-0x1.6ccc6912a2b52p-2,-0x1.7d0e90eb3979p-2
+atan,-0x1.7cce0b00139a5p-1,-0x1.d70b2efdbf7d6p-1
+atan,-0x1.c84f09989be7dp-1,-0x1.3cda2a813a76cp0
+atan,0x1.49997b5bd68fbp0,0x1.b7ab14bfee8e3p1
+atan,-0x1.8a17b210ea8f4p-2,-0x1.9ec69523e8b5dp-2
+atan,0x1.c2c2f910f5a49p-5,0x1.c337932bafc7fp-5
+atan,0x1.30b5e4abffe2bp-1,0x1.5aa2ae345e042p-1
+atan,-0x1.6f0d238644b13p0,-0x1.d038428eb72a2p2
+atan,0x1.eb0f0065197c4p-1,0x1.6cf583df7da58p0
+atan,-0x1.17f88069bcfb3p0,-0x1.ef28488b9b37ap0
+atan,0x1.9f15a9cdc1a55p-6,0x1.9f2c676017f62p-6
+atan,0x1.7a8eb9b9f6c8cp0,0x1.5aa1c940df06fp3
+atan,0x1.084798bf4f5bp-1,0x1.228deadc77f93p-1
+atan,-0x1.94d86a3730fcap-1,-0x1.02bc6fc2b9406p0
+atan,0x1.7f716012bca93p0,0x1.b5bdf80140d62p3
+atan,-0x1.0cd2bf725cd1fp0,-0x1.be61f0ae4b482p0
+atan,-0x1.81e572dd21298p-1,-0x1.e0881c5defdfbp-1
+atan,0x1.39aaae5bda58ep-6,0x1.39b47e2cbc2e1p-6
+atan,-0x1.48b9f68aa1f3ep0,-0x1.b225466841e6p1
+atan,0x1.5b28184ab3592p-1,0x1.9c60b29b278adp-1
+atan,0x1.0f7ef35db0cedp0,0x1.c961c61bb393cp0
+atan,0x1.0f0f5b6d2caa4p-1,0x1.2b962e4e16b09p-1
+atan,0x1.a5c56336af70cp-2,0x1.bf5c2d5f26beep-2
+atan,0x1.680ec9ce7c643p0,0x1.81f872a48680cp2
+atan,-0x1.48d23d579898ep0,-0x1.b2bd3e6325baep1
+atan,0x1.007eec1dce73dp-2,0x1.05ff912205895p-2
+atan,-0x1.a69fd5ea0e91p-5,-0x1.a6ffec34fdae1p-5
+atan,-0x1.f7938809d3e5dp-1,-0x1.80a0b8352e767p0
+atan,0x1.f515ff0fef504p-2,0x1.10a975f570853p-1
+atan,0x1.902e97ef8d67dp-1,0x1.fc2185cdb31a7p-1
+atan,0x1.6c5893306ecc8p-2,0x1.7c8ab62ecbab7p-2
+atan,0x1.b8c6aad242c76p-2,0x1.d62e14e11b1e7p-2
+atan,-0x1.1549e561cc3bfp-2,-0x1.1c4567ed7dd9bp-2
+atan,-0x1.0012912d25ea6p0,-0x1.8ef1e714578d8p0
+atan,-0x1.a2ec60e1153ccp-2,-0x1.bbf914ae73ba7p-2
+atan,0x1.55d9a44b6a28p0,0x1.0ac904e60e827p2
+atan,0x1.5e12c30d51e21p0,0x1.366bd74b5179dp2
+atan,0x1.7944f6639bf71p0,0x1.488ff56433813p3
+atan,0x1.9189a07a9863fp-1,0x1.fed42e46b2658p-1
+atan,0x1.4bc249840a266p0,0x1.c5e64aa13a641p1
+atan,-0x1.e0e2d63a8acaep-1,-0x1.5df559f13edbcp0
+atan,0x1.c358a9a45837p-3,0x1.cacc5dc9f46b9p-3
+atan,-0x1.a12e8b47bb59ap-1,-0x1.0f84d28c6afc3p0
+atan,0x1.beaa600735ac2p-1,0x1.30ebca35d471fp0
+atan,-0x1.3446c8ecbbfcfp-1,-0x1.5fdc5566d7c64p-1
+atan,0x1.42a6ca35be6dcp0,0x1.8efd0101ce554p1
+atan,-0x1.14b7ab3e48f35p-1,-0x1.333b180971a27p-1
+atan,-0x1.c192207f495cp-1,-0x1.347561bd4d841p0
+atan,0x1.dbe77966530f2p-1,0x1.56e7f4b249cd2p0
+atan,-0x1.1096376ddecc2p-2,-0x1.17369abf533b1p-2
+atan,0x1.83b362fd21348p-4,0x1.84dcdc2401be9p-4
+atan,0x1.834bdf0a516b8p-1,0x1.e32bfcdef37f3p-1
+atan,-0x1.8aae6465ee3d2p-1,-0x1.f153b4e67b34bp-1
+atan,-0x1.0cdd6ce8d2931p-1,-0x1.28a5bd4c72f68p-1
+atan,0x1.ab12e9bcfca44p-2,0x1.c5b07ae2644dep-2
+atan,-0x1.d8f3f0d9d900ep-1,-0x1.52d07a14b002ep0
+atan,0x1.55e73c1c43e7p0,0x1.0b07857cdb669p2
+atan,-0x1.993310a26c8c3p-1,-0x1.072cdbc0c3265p0
+atan,-0x1.1d9a4ed57ce1ap0,-0x1.058691ac7450ap1
+atan,-0x1.b4f4e4258ab19p-1,-0x1.256fffde053cdp0
+atan,0x1.78415f04d47b4p0,0x1.3b999693d4792p3
+atan,0x1.84665e9dbda69p0,0x1.2a2b7551ba18fp4
+atan,0x1.8ce99d073e7cap-1,0x1.f5ae9abbf5021p-1
+atan,0x1.aedf77914b5b2p-2,0x1.ca3dddb2e10edp-2
+atan,-0x1.4c5ad4fe03441p-1,-0x1.8485cc6541d79p-1
+atan,-0x1.68a1270c8a7ecp0,-0x1.87628ace570afp2
+atan,-0x1.26d36b5410e32p-1,-0x1.4c678181ece16p-1
+atan,0x1.090b91cfd10dep0,0x1.af7fe532b4115p0
+atan,0x1.6dc1a49fa96dap-2,0x1.7e25daf2404ebp-2
+atan,0x1.118cffbae8892p0,0x1.d21f2971059d7p0
+atan,0x1.4c8b94010a5f2p-1,0x1.84d2a2b940b3dp-1
+atan,0x1.f5ad4729db9adp-2,0x1.110a9555d7137p-1
+atan,0x1.7a8d8f3aa2a3ep-1,0x1.d2e70a2cd9268p-1
+atan,-0x1.bc217e08d139bp-3,-0x1.c33a03fbf97d3p-3
+atan,-0x1.297dd7227bb5ep-1,-0x1.5034dd186346cp-1
+atan,-0x1.ce6b7fbcba912p-1,-0x1.44b47fc0f18e4p0
+atan,0x1.93289102e9a14p-1,0x1.010965205f73fp0
+atan,-0x1.46d8b28b0f8f2p-1,-0x1.7be99431179dfp-1
+atan,-0x1.7e6490113792fp-1,-0x1.d9fbeffa46b75p-1
+atan,-0x1.8fe43874effc4p-8,-0x1.8fe57db7b553ep-8
+atan,-0x1.d37c2a2e19a16p-2,-0x1.f6eb6496635d2p-2
+atan,-0x1.9cb07072a00c7p-1,-0x1.0aca1ef2353e8p0
+atan,0x1.9c487bff5a805p-2,0x1.b41b45eb4edbp-2
+ceil,0x1.0p1,0x1.1529c4488417ep0
+ceil,0x1.0p1,0x1.8fa0a5e8cee32p0
+ceil,-0x0.0p0,-0x1.8819e79d62b8p-1
+ceil,-0x1.0p3,-0x1.1824560a8c094p3
+ceil,0x1.0p0,0x1.c7993d0a6bab1p-5
+ceil,0x1.0p0,0x1.d3f48401ae71dp-2
+ceil,-0x0.0p0,-0x1.fe333a8929a13p-4
+ceil,-0x1.0p0,-0x1.d3f9245636b8cp0
+ceil,-0x1.0p0,-0x1.38b161487c697p0
+ceil,-0x1.8p1,-0x1.c652252a89289p1
+ceil,0x1.0p0,0x1.8a14843eadfc1p-1
+ceil,-0x1.2p3,-0x1.2a33602af54ccp3
+ceil,-0x1.0p1,-0x1.3c7c5d5fb992ap1
+ceil,0x1.0p0,0x1.3268391790ec4p-1
+ceil,0x1.0p0,0x1.9094f869a3e47p-1
+ceil,0x1.0p0,0x1.8af45bc4cf8a4p-2
+ceil,0x1.0p2,0x1.d5c53dc486547p1
+ceil,-0x0.0p0,-0x1.275b5fb11c3a7p-1
+ceil,0x1.8p1,0x1.5bf1bc1ca6e71p1
+ceil,0x1.0p0,0x1.b20f092a375bep-2
+ceil,0x1.0p0,0x1.90e6fb00878ffp-4
+ceil,0x1.8p1,0x1.6645838752797p1
+ceil,-0x1.0p0,-0x1.090e646874031p0
+ceil,-0x0.0p0,-0x1.244624fd8840ep-1
+ceil,0x1.0p1,0x1.1dbcee46033afp0
+ceil,-0x0.0p0,-0x1.369578820b61fp-1
+ceil,0x1.0p0,0x1.dd12b37cb5c3dp-1
+ceil,-0x0.0p0,-0x1.aed83bf3664f7p-1
+ceil,0x1.0p0,0x1.79c6eb37d3bddp-2
+ceil,-0x0.0p0,-0x1.d3a80f7edc393p-9
+ceil,0x1.0p0,0x1.250e28aaafd2fp-1
+ceil,0x1.0p1,0x1.a130baee91cb9p0
+ceil,0x1.0p1,0x1.3b015aff7a8cap0
+ceil,-0x1.0p0,-0x1.27ed2173f606ap0
+ceil,0x1.8p1,0x1.2bc99fc2d28c7p1
+ceil,-0x0.0p0,-0x1.6407f78e81b44p-4
+ceil,-0x1.0p3,-0x1.0133e906d864ep3
+ceil,-0x1.0p1,-0x1.43744f4b6b838p1
+ceil,0x1.0p0,0x1.21f601ab8929bp-2
+ceil,-0x1.0p0,-0x1.0821a86abccecp0
+ceil,-0x0.0p0,-0x1.3e013d62a6722p-5
+ceil,0x1.0p1,0x1.ddeac791f09dep0
+ceil,0x1.0p0,0x1.577b2bc7f7031p-6
+ceil,0x1.8p1,0x1.03d2215d352dap1
+ceil,-0x0.0p0,-0x1.60e23c27385ap-1
+ceil,0x1.8p1,0x1.38514c0fe5f1dp1
+ceil,0x1.0p1,0x1.0b728ebae056bp0
+ceil,0x1.0p0,0x1.ebc2a1f6424cdp-1
+ceil,-0x0.0p0,-0x1.dee83d06f7f71p-1
+ceil,-0x0.0p0,-0x1.66edb73e176c4p-1
+ceil,0x1.0p0,0x1.fe84691bb10dap-2
+ceil,-0x1.0p1,-0x1.01915fd676f7ap1
+ceil,0x1.0p0,0x1.ff569cc31f4cdp-1
+ceil,-0x1.0p0,-0x1.b14772771033bp0
+ceil,0x1.0p0,0x1.27516fd308a65p-2
+ceil,0x1.0p0,0x1.e5837ca4f09d2p-1
+ceil,-0x1.0p0,-0x1.173346f7f2aa6p0
+ceil,0x1.0p1,0x1.7c11f2024962bp0
+ceil,-0x0.0p0,-0x1.a83c9b9ceca0ap-1
+ceil,-0x1.0p0,-0x1.422206d211aa1p0
+ceil,0x1.0p1,0x1.1ae5cbbea5764p0
+ceil,0x1.0p1,0x1.6eb6884552292p0
+ceil,0x1.f8p5,0x1.f0f5662565457p5
+ceil,-0x1.0p0,-0x1.4b85db6fcd1eep0
+ceil,-0x0.0p0,-0x1.dc8865f77e0c6p-1
+ceil,0x1.0p0,0x1.2ff388d1bfc0ap-1
+ceil,0x1.0p2,0x1.feb52d333684dp1
+ceil,-0x0.0p0,-0x1.8684a25997011p-1
+ceil,0x1.8p1,0x1.1065bca309eabp1
+ceil,-0x1.0p1,-0x1.2bad263cc2bbdp1
+ceil,0x1.0p3,0x1.c03e4c3d9a2fbp2
+ceil,-0x1.0p3,-0x1.0d3236eb056a6p3
+ceil,0x1.0p0,0x1.cedd70625e604p-1
+ceil,-0x1.0p3,-0x1.111661321bcfbp3
+ceil,0x1.0p0,0x1.fbe1cf7ae152bp-4
+ceil,-0x1.8p2,-0x1.b3d4537ae5063p2
+ceil,-0x1.bp4,-0x1.b7c60675c92b8p4
+ceil,0x1.0p1,0x1.346350e06b91cp0
+ceil,-0x0.0p0,-0x1.cdacbbaf88c8dp-1
+ceil,0x1.0p0,0x1.10c7104e9e63fp-1
+ceil,0x1.3p4,0x1.204422a4f53fep4
+ceil,-0x1.0p1,-0x1.0662f72abe8a6p1
+ceil,-0x1.0p0,-0x1.a3d7a01a3f3edp0
+ceil,-0x0.0p0,-0x1.87236c099c455p-1
+ceil,-0x1.0p1,-0x1.1d23595667d0ap1
+ceil,-0x1.0p1,-0x1.2fa6984e9bce5p1
+ceil,0x1.0p0,0x1.8653440b01b0cp-1
+ceil,0x1.0p1,0x1.110d9cff88cb3p0
+ceil,-0x0.0p0,-0x1.ce628c70988e6p-1
+ceil,-0x1.cp3,-0x1.dfb37608c0c64p3
+ceil,0x1.8p1,0x1.18034b67f0851p1
+ceil,0x1.ap3,0x1.92212ab8078d4p3
+ceil,-0x0.0p0,-0x1.16237c5f2fec2p-2
+ceil,-0x0.0p0,-0x1.3437619f7a954p-2
+ceil,0x1.0p1,0x1.65c8478a49299p0
+ceil,0x1.0p0,0x1.5c0bab7760c84p-2
+ceil,0x1.8p1,0x1.1f819dfae4afp1
+ceil,-0x1.0p0,-0x1.7cf71f30f00a1p0
+ceil,-0x1.4p3,-0x1.4343496871035p3
+ceil,0x1.8p2,0x1.7eed6e5ec8f76p2
+ceil,-0x0.0p0,-0x1.6250ab358d26ep-1
+ceil,-0x1.0p0,-0x1.061e9fa685ef2p0
+ceil,-0x1.0p0,-0x1.db3ce5988640bp0
+ceil,-0x0.0p0,-0x1.ccbb1731eab01p-3
+ceil,0x1.4p2,0x1.3d89f980914b3p2
+ceil,-0x0.0p0,-0x1.8561418dcb05fp-1
+ceil,-0x0.0p0,-0x1.7e6ae3e00fda7p-1
+ceil,-0x1.8p1,-0x1.b4d580276c008p1
+ceil,-0x0.0p0,-0x1.4481bfbcdeac8p-2
+ceil,-0x1.0p0,-0x1.f0bd42cf0da5p0
+ceil,0x1.0p0,0x1.6825db009c06fp-6
+ceil,-0x1.7cp6,-0x1.7e258696b572dp6
+ceil,-0x1.0p0,-0x1.08a7031acc1fbp0
+ceil,-0x1.0p0,-0x1.3bf4bdcfc2fcbp0
+ceil,-0x0.0p0,-0x1.af07481527887p-2
+ceil,-0x1.cp2,-0x1.c4323c29863c1p2
+ceil,0x1.0p0,0x1.e647720b87a44p-1
+ceil,-0x1.0p3,-0x1.1ce9f63825e86p3
+ceil,0x1.0p0,0x1.27092264d1649p-1
+ceil,0x1.0p2,0x1.ad5ee9acacce9p1
+ceil,-0x1.0p0,-0x1.563e9a4c62f6ep0
+ceil,0x1.0p0,0x1.c6a06bb05af8fp-1
+ceil,-0x0.0p0,-0x1.ba5fa6bbd75aap-1
+ceil,-0x1.0p1,-0x1.2a716a394422ep1
+ceil,-0x1.0p0,-0x1.5ce4388bb2741p0
+ceil,-0x1.8p1,-0x1.9647c24134d4fp1
+ceil,0x1.0p1,0x1.3c201ab593d83p0
+ceil,-0x1.8p1,-0x1.9fd79f468a524p1
+ceil,-0x1.0p0,-0x1.7f8801da75951p0
+ceil,-0x1.0p0,-0x1.c4b2c1f85d17ep0
+ceil,0x1.8p1,0x1.324fd4c7777afp1
+ceil,0x1.0p0,0x1.17dbcdbd1808dp-2
+ceil,-0x1.8p1,-0x1.91dd59b003aa4p1
+ceil,0x1.0p1,0x1.bb7f4cb0d714ep0
+ceil,-0x1.8p1,-0x1.ebb29f8a0960dp1
+ceil,-0x1.0p0,-0x1.7078ebcdda1c5p0
+ceil,0x1.4p2,0x1.18426a14825adp2
+ceil,0x1.8p1,0x1.1c4eed388ae27p1
+ceil,-0x1.0p0,-0x1.1a672e6f342cap0
+ceil,0x1.0p0,0x1.24df781832f6cp-2
+ceil,0x1.0p1,0x1.0a1f891d533b5p0
+ceil,-0x0.0p0,-0x1.ad75df6d0acc4p-5
+ceil,0x1.4p2,0x1.2278ad791ea05p2
+ceil,0x1.0p1,0x1.3453656d1d512p0
+ceil,0x1.8p1,0x1.777b9363eaa83p1
+ceil,0x1.0p0,0x1.298f39f5ec8cfp-1
+ceil,0x1.0p1,0x1.d874534d73fb8p0
+ceil,-0x1.0p1,-0x1.457fc8ce77418p1
+ceil,-0x1.4p3,-0x1.578f3415c0213p3
+ceil,0x1.0p0,0x1.19a28add78761p-2
+ceil,0x1.0p0,0x1.93ccc9c24d8bap-1
+ceil,-0x0.0p0,-0x1.ab3ce1ce572c5p-3
+ceil,-0x1.0p0,-0x1.02be59a5332b9p0
+ceil,0x1.0p0,0x1.e099afd9aa97dp-1
+ceil,0x1.8p1,0x1.27f2155750c05p1
+ceil,-0x0.0p0,-0x1.d355da98f638fp-4
+ceil,-0x1.0p0,-0x1.0041d23ea4d7bp0
+ceil,0x1.0p1,0x1.51145fc5e1f75p0
+ceil,-0x0.0p0,-0x1.6c1df0f11a2e7p-2
+ceil,-0x0.0p0,-0x1.21db253403df3p-1
+ceil,-0x1.0p0,-0x1.389765eb19788p0
+ceil,0x1.0p0,0x1.9394bba3f12b1p-1
+ceil,0x1.0p1,0x1.36f2b043cd3c6p0
+ceil,-0x1.0p1,-0x1.651fab3095a4p1
+ceil,-0x1.0p0,-0x1.19bc2e8032b5dp0
+ceil,0x1.0p0,0x1.52521ff2087fep-1
+ceil,0x1.0p0,0x1.d19920fd65aedp-1
+ceil,0x1.0p2,0x1.ca65379dbc236p1
+ceil,-0x0.0p0,-0x1.4182a228c01d8p-1
+ceil,-0x0.0p0,-0x1.31e846b97569ep-4
+ceil,-0x0.0p0,-0x1.7cf3e72de231dp-1
+ceil,-0x0.0p0,-0x1.73c457b5b6f22p-2
+ceil,-0x1.8p1,-0x1.9c10281fbe6a1p1
+ceil,0x1.0p0,0x1.d9d17cc9eb21bp-1
+ceil,-0x1.8p2,-0x1.a59ad9f77bc62p2
+ceil,0x1.0p0,0x1.0e8e995cbe5e5p-2
+ceil,0x1.0p1,0x1.a06747e83f024p0
+ceil,0x1.0p0,0x1.4f4bdabe2938p-1
+ceil,0x1.0p1,0x1.386e6fa60b62dp0
+ceil,0x1.0p0,0x1.72e70f3c3565cp-3
+ceil,-0x0.0p0,-0x1.57af1fd8538a3p-2
+ceil,0x1.0p0,0x1.113dddb6f917cp-2
+ceil,0x1.0p3,0x1.d2b6aec26de9fp2
+ceil,0x1.0p1,0x1.a74c3bfcfb9dbp0
+ceil,0x1.0p1,0x1.95f962791803p0
+ceil,-0x0.0p0,-0x1.340954bbf6f2fp-3
+ceil,-0x0.0p0,-0x1.9763472624c7ap-1
+ceil,-0x0.0p0,-0x1.4a8957e0afd17p-2
+ceil,-0x0.0p0,-0x1.f44af2012da19p-2
+ceil,0x1.0p1,0x1.c2a009304a9afp0
+ceil,-0x0.0p0,-0x1.2f91f183cfcafp-1
+ceil,0x1.0p0,0x1.a44995b6d17f8p-1
+ceil,-0x1.0p0,-0x1.3dcaa9d221b29p0
+ceil,-0x0.0p0,-0x1.4377f9d707078p-1
+ceil,-0x1.0p0,-0x1.ae0e18d669e6dp0
+ceil,0x1.0p2,0x1.ed421922674e3p1
+ceil,0x1.0p1,0x1.3048c00d10bf6p0
+ceil,0x1.0p0,0x1.96900a95da243p-2
+ceil,0x1.0p0,0x1.2d536970cab18p-2
+ceil,0x1.8p1,0x1.7274657cd9bf7p1
+floor,-0x1.0p0,-0x1.60ea637ea2799p-1
+floor,0x1.0p0,0x1.a0e6ad21f666dp0
+floor,-0x1.0p0,-0x1.8140ade02e521p-1
+floor,0x1.0p0,0x1.e8f78ef0d2ee3p0
+floor,0x0.0p0,0x1.4768d41c69116p-3
+floor,0x0.0p0,0x1.b135df74fb11ap-2
+floor,-0x1.0p1,-0x1.467b1c700773ap0
+floor,-0x1.8p1,-0x1.262bff2a64dfbp1
+floor,0x0.0p0,0x1.e0c30caa288c9p-5
+floor,0x0.0p0,0x1.c9114e290ccb5p-4
+floor,0x1.0p3,0x1.0a7b9c7291c7cp3
+floor,-0x1.8p1,-0x1.00a8853762f52p1
+floor,-0x1.0p1,-0x1.0dc1bfba6c846p0
+floor,0x1.0p0,0x1.1778a75927d75p0
+floor,0x1.0p0,0x1.519ca23faddbfp0
+floor,0x1.0p0,0x1.5e1c3249ec62dp0
+floor,-0x1.0p0,-0x1.3e3c0cdde87b8p-1
+floor,-0x1.0p0,-0x1.ca5fe8d10aa5cp-1
+floor,0x1.0p1,0x1.2aed263c57cacp1
+floor,-0x1.0p0,-0x1.4b67a366df0eep-1
+floor,-0x1.0p0,-0x1.ce05fad1edb67p-7
+floor,0x0.0p0,0x1.1bb55f4aa4993p-2
+floor,0x1.0p4,0x1.0a823844e502cp4
+floor,0x1.0p0,0x1.3a4cbb7c16ed9p0
+floor,-0x1.0p1,-0x1.b6d5224a0854cp0
+floor,0x0.0p0,0x1.167bad5a4ef99p-1
+floor,-0x1.0p0,-0x1.736d2d56b012ap-1
+floor,-0x1.0p1,-0x1.25a79ea67b0ddp0
+floor,0x1.0p0,0x1.704f495734a57p0
+floor,0x0.0p0,0x1.4c4b08060544dp-3
+floor,0x0.0p0,0x1.c40ab6550f5bap-4
+floor,0x1.0p1,0x1.2176c61aa4165p1
+floor,-0x1.0p0,-0x1.e8712f6aec8d6p-2
+floor,0x1.0p1,0x1.1a68bcf1c854ap1
+floor,-0x1.0p1,-0x1.65d0481233f84p0
+floor,0x0.0p0,0x1.73ed43d3e7f11p-1
+floor,0x0.0p0,0x1.dd7b26440e0fp-1
+floor,-0x1.8p1,-0x1.1c7a19a7c154ep1
+floor,0x0.0p0,0x1.d7e8971cb7371p-2
+floor,0x0.0p0,0x1.3dcd455837f28p-3
+floor,-0x1.0p0,-0x1.5b079da41f53fp-2
+floor,0x0.0p0,0x1.2a52ab19ae71bp-1
+floor,-0x1.cp2,-0x1.a483cfe4e5739p2
+floor,0x1.0p0,0x1.7a00e9fce97eep0
+floor,-0x1.0p0,-0x1.ed6655cca4ad1p-1
+floor,0x0.0p0,0x1.5555ca39f41dap-1
+floor,-0x1.8p1,-0x1.08b8f0227c007p1
+floor,0x1.0p0,0x1.7a7038a587767p0
+floor,0x1.3p4,0x1.32c7c23003bp4
+floor,0x1.cp2,0x1.dddf2d57aff3fp2
+floor,-0x1.0p0,-0x1.3d7423fd71bd3p-1
+floor,0x0.0p0,0x1.b792fa35f95c3p-1
+floor,-0x1.0p1,-0x1.3b6e1f376d271p0
+floor,-0x1.0p2,-0x1.daacf3a509866p1
+floor,-0x1.0p0,-0x1.bc1b98f41db09p-3
+floor,0x0.0p0,0x1.5b415fcfabca7p-1
+floor,0x1.bap7,0x1.baf7c0481a882p7
+floor,0x1.0p0,0x1.0cde4d5f908d1p0
+floor,0x1.5p4,0x1.52b25de23940ep4
+floor,-0x1.0p1,-0x1.32433c100d7c5p0
+floor,-0x1.0p1,-0x1.9590f9188898dp0
+floor,0x0.0p0,0x1.ae6a210494d6cp-1
+floor,-0x1.0p0,-0x1.57cde9e191efbp-3
+floor,0x1.0p1,0x1.3469d5db5ff16p1
+floor,-0x1.0p0,-0x1.3ed490470f44p-5
+floor,0x1.0p0,0x1.3a36b9f710262p0
+floor,0x0.0p0,0x1.12a59e5193b61p-2
+floor,0x0.0p0,0x1.4eb8dd0b28615p-1
+floor,0x1.0p1,0x1.66f0dc8b5c339p1
+floor,0x0.0p0,0x1.23a078e3b5e6p-2
+floor,0x0.0p0,0x1.da1a50e522d41p-3
+floor,-0x1.0p0,-0x1.d5912533e23bfp-1
+floor,-0x1.0p0,-0x1.d0aac7b5164a6p-3
+floor,0x1.0p0,0x1.153d729a3811ap0
+floor,-0x1.0p0,-0x1.35e3b75b5846ap-2
+floor,-0x1.0p1,-0x1.3357b71d4bd17p0
+floor,0x0.0p0,0x1.e96464db621dfp-2
+floor,0x1.0p0,0x1.40bd49dee854bp0
+floor,0x1.0p1,0x1.062e799f901dep1
+floor,-0x1.0p0,-0x1.04a4254ba4316p-2
+floor,0x0.0p0,0x1.2b58e8fb659abp-1
+floor,0x0.0p0,0x1.d59c6d5f0b9a5p-1
+floor,-0x1.0p1,-0x1.ce04754179edbp0
+floor,0x0.0p0,0x1.3d88c164be795p-1
+floor,0x0.0p0,0x1.9df30bf9eedfep-3
+floor,-0x1.0p0,-0x1.bd28c6cb9c04fp-1
+floor,0x1.0p0,0x1.5c84d6e9ecf5ep0
+floor,-0x1.0p0,-0x1.5ef4731d7afb8p-1
+floor,-0x1.0p1,-0x1.514f5822c3e18p0
+floor,0x1.0p1,0x1.1f445dca8719cp1
+floor,-0x1.0p1,-0x1.c32d845859f41p0
+floor,-0x1.0p0,-0x1.1499d5f055ed4p-2
+floor,0x0.0p0,0x1.f96e2e85d76ddp-1
+floor,0x1.2p4,0x1.2f54d9becdb9ap4
+floor,0x1.0p0,0x1.b4a70a664f94cp0
+floor,0x0.0p0,0x1.89925cf338b0ap-3
+floor,0x0.0p0,0x1.46bfd9a028234p-1
+floor,-0x1.4p2,-0x1.0cc01fd33b135p2
+floor,0x0.0p0,0x1.b2e629cd67709p-1
+floor,-0x1.0p1,-0x1.ae455bde069edp0
+floor,-0x1.0p0,-0x1.a7a453b404f81p-2
+floor,0x1.0p2,0x1.3c570740ad475p2
+floor,-0x1.0p0,-0x1.cf72c10746e05p-2
+floor,-0x1.8p1,-0x1.76f04aca37abap1
+floor,0x0.0p0,0x1.bec66b0a86f77p-1
+floor,0x1.0p4,0x1.0ba4c7ed4ce2ep4
+floor,0x1.0p1,0x1.0a46dbc6d5d34p1
+floor,-0x1.0p0,-0x1.00117e3bb17bp-2
+floor,-0x1.ep3,-0x1.dc28d1350a5ffp3
+floor,0x1.0p0,0x1.cd3d22916dea2p0
+floor,-0x1.0p0,-0x1.d535e729151f2p-2
+floor,-0x1.0p0,-0x1.87a04f8c3f0f3p-3
+floor,0x0.0p0,0x1.d5a27a7fa5ca6p-2
+floor,-0x1.0p0,-0x1.fe33a0c1cd67dp-1
+floor,-0x1.8p1,-0x1.1629a92d4c7e5p1
+floor,0x1.8p1,0x1.f01fb38ad0a02p1
+floor,-0x1.0p1,-0x1.1d61b49bf1823p0
+floor,-0x1.0p1,-0x1.dead34e8651f2p0
+floor,-0x1.2p3,-0x1.0813c277add17p3
+floor,0x1.0p0,0x1.4d2255b09c941p0
+floor,0x0.0p0,0x1.cf7ffb800697p-2
+floor,0x0.0p0,0x1.b11c2fbff3b72p-2
+floor,-0x1.0p0,-0x1.e94968648ecd3p-3
+floor,0x0.0p0,0x1.31b74583c0577p-1
+floor,0x0.0p0,0x1.be82361931e57p-3
+floor,0x1.8p1,0x1.dad0eb6f40657p1
+floor,-0x1.0p1,-0x1.5f1d91f872285p0
+floor,-0x1.8p2,-0x1.49a98786ea925p2
+floor,-0x1.8p1,-0x1.573ee5fbff85ep1
+floor,0x0.0p0,0x1.23d95b8567a42p-2
+floor,-0x1.0p2,-0x1.daa4ab42e2285p1
+floor,0x1.0p2,0x1.0ee22526606fep2
+floor,-0x1.0p0,-0x1.5a9ae8bc2ee6ap-2
+floor,-0x1.2cp6,-0x1.2a5ceb52951p6
+floor,-0x1.8p1,-0x1.6bc8f8b516b47p1
+floor,0x1.8p1,0x1.e9e0f48e16c06p1
+floor,0x0.0p0,0x1.d526a6e007cp-1
+floor,0x1.8p1,0x1.fbe84243ca9aep1
+floor,0x1.0p0,0x1.a5958e7ea9034p0
+floor,0x0.0p0,0x1.4cddd2d0f089p-2
+floor,0x1.0p0,0x1.22aee3a4b1f97p0
+floor,0x0.0p0,0x1.6be900fb60ba3p-2
+floor,0x1.0p1,0x1.7cd1b9585b0a6p1
+floor,-0x1.0p0,-0x1.2f87e8b9b32c5p-5
+floor,0x1.0p0,0x1.439b764651b23p0
+floor,-0x1.0p2,-0x1.8ec036fdd0566p1
+floor,0x1.0p2,0x1.02e194a0b1f1ep2
+floor,0x0.0p0,0x1.9b85107063739p-1
+floor,0x1.0p0,0x1.cf6177e36e21p0
+floor,-0x1.0p1,-0x1.7caa1215c337fp0
+floor,-0x1.0p1,-0x1.16416e7476fbfp0
+floor,0x0.0p0,0x1.c1b12bf16539ep-4
+floor,-0x1.cp2,-0x1.bc048d8aa90d4p2
+floor,-0x1.0p1,-0x1.23b3f2fd28dfp0
+floor,0x0.0p0,0x1.e4bae2b8297d9p-1
+floor,-0x1.4p2,-0x1.2b42ab1745eb3p2
+floor,-0x1.0p1,-0x1.07de022cfd745p0
+floor,0x0.0p0,0x1.323fcc0c22a1p-1
+floor,0x0.0p0,0x1.f5bce5b7c966cp-3
+floor,0x0.0p0,0x1.5993da56bb29cp-3
+floor,-0x1.4p2,-0x1.03a9d3b28df3fp2
+floor,-0x1.0p0,-0x1.59389b5a584a1p-2
+floor,0x0.0p0,0x1.c044a36dba2dep-6
+floor,-0x1.0p1,-0x1.6b4c7e12fa7bap0
+floor,0x0.0p0,0x1.8e7465c37d836p-2
+floor,0x0.0p0,0x1.4dc98a95e1b73p-2
+floor,0x0.0p0,0x1.441dde51458dbp-1
+floor,-0x1.0p0,-0x1.fdf675799bd3ap-1
+floor,-0x1.0p0,-0x1.1eb3acc2f5f8ep-1
+floor,-0x1.0p0,-0x1.5835ed6b38475p-2
+floor,0x1.8p2,0x1.99615c66977fbp2
+floor,-0x1.0p0,-0x1.5038df45d5039p-1
+floor,0x1.8p3,0x1.8a28ebd6820b9p3
+floor,0x1.8p1,0x1.8407d341a1b3ap1
+floor,-0x1.0p1,-0x1.e7c141af0dd15p0
+floor,-0x1.0p1,-0x1.9148faf3c8186p0
+floor,0x1.0p0,0x1.70792e2fc4575p0
+floor,0x1.2p5,0x1.27bdbf35f1357p5
+floor,0x0.0p0,0x1.ed53509ca5181p-1
+floor,-0x1.0p1,-0x1.16cea1321677cp0
+floor,0x1.0p0,0x1.35ec318d055dap0
+floor,-0x1.4p2,-0x1.1b3a65f84f0d3p2
+floor,0x1.0p0,0x1.da1158fdf2d88p0
+floor,-0x1.0p0,-0x1.2241894bf9a26p-1
+floor,-0x1.4p2,-0x1.26f9c915dfca7p2
+floor,-0x1.0p1,-0x1.37701c8fd1802p0
+floor,0x1.0p0,0x1.8359fb530facp0
+floor,-0x1.0p0,-0x1.9bc54c822ae78p-1
+floor,0x1.0p1,0x1.0edbd4f2daa43p1
+floor,0x1.2p4,0x1.2d57e9335a4a4p4
+floor,0x0.0p0,0x1.35eebd2e25a13p-4
+floor,-0x1.0p1,-0x1.4fc7efa4afbb4p0
+floor,0x0.0p0,0x1.89cfce5943f74p-1
+floor,-0x1.0p0,-0x1.f7b8793b8fb79p-2
+floor,0x1.4p3,0x1.51116bcb39f21p3
+floor,-0x1.0p1,-0x1.00861713523cap0
+floor,-0x1.0p1,-0x1.355af729b4d59p0
+floor,-0x1.0p0,-0x1.144405a9b9f7ap-2
+floor,0x1.0p0,0x1.58cd4d03e688p0
+floor,-0x1.0p0,-0x1.8a6380518a9eap-1
+copySign,-0x1.f0df8a466700bp1,-0x1.f0df8a466700bp1,-0x1.6e938e3732539p-1
+copySign,-0x1.58e4f34672f61p4,0x1.58e4f34672f61p4,-0x1.27d6a2e67009cp-1
+copySign,-0x1.f4b9bf237c55fp0,-0x1.f4b9bf237c55fp0,-0x1.37c0ebff02017p0
+copySign,-0x1.59f3d2a9fe64ap2,-0x1.59f3d2a9fe64ap2,-0x1.2669d7ca6a8d6p0
+copySign,-0x1.c46d4baa04314p-2,-0x1.c46d4baa04314p-2,-0x1.5d0597ad91f24p-2
+copySign,0x1.27953254ab2d4p0,-0x1.27953254ab2d4p0,0x1.cf0f007876816p-1
+copySign,-0x1.ee50997f5ec0cp-2,0x1.ee50997f5ec0cp-2,-0x1.1fe2c0d6e4b9bp-1
+copySign,0x1.3318225589ce5p1,0x1.3318225589ce5p1,0x1.8013386023341p1
+copySign,0x1.836934e49ccf1p-1,-0x1.836934e49ccf1p-1,0x1.23098c339673cp1
+copySign,-0x1.a76ccea1e588ap0,-0x1.a76ccea1e588ap0,-0x1.1bf459b597376p-1
+copySign,-0x1.0474aaa82fa0dp3,0x1.0474aaa82fa0dp3,-0x1.10aae9980d88ap-1
+copySign,0x1.3ad3f960b27ffp5,-0x1.3ad3f960b27ffp5,0x1.dbb76f5f93749p-1
+copySign,-0x1.759f798e531dbp-1,0x1.759f798e531dbp-1,-0x1.35757ea9c1ecep6
+copySign,0x1.07a6b63ed401cp2,0x1.07a6b63ed401cp2,0x1.5d12b41ddbb79p0
+copySign,0x1.1beba7d00213p-3,-0x1.1beba7d00213p-3,0x1.73b0d543f50eap1
+copySign,-0x1.ec2d7caf4bb15p-1,-0x1.ec2d7caf4bb15p-1,-0x1.35763cca9e848p-1
+copySign,-0x1.320be2d4133e4p1,0x1.320be2d4133e4p1,-0x1.f1aabc8d9cacdp-2
+copySign,-0x1.e81f03d1b1f11p-4,0x1.e81f03d1b1f11p-4,-0x1.c9787b7217e15p0
+copySign,-0x1.9e5de05c3a504p0,0x1.9e5de05c3a504p0,-0x1.9662999a6d0ecp0
+copySign,0x1.1ac5a7d39dd98p1,-0x1.1ac5a7d39dd98p1,0x1.f7df0731acbdfp-2
+copySign,0x1.81a4cc956f6d4p-1,0x1.81a4cc956f6d4p-1,0x1.1c8c997022c39p-1
+copySign,0x1.5a8a187b65edcp-2,0x1.5a8a187b65edcp-2,0x1.ed1693c7a34f7p-3
+copySign,-0x1.949965fc32defp-1,0x1.949965fc32defp-1,-0x1.20a1e248f5809p3
+copySign,0x1.0ad14bba1ef12p-2,0x1.0ad14bba1ef12p-2,0x1.4141fe80406c7p-5
+copySign,-0x1.0137cbd8c37ep4,0x1.0137cbd8c37ep4,-0x1.bbafad456d25ap-2
+copySign,-0x1.da814e501ccf5p-2,-0x1.da814e501ccf5p-2,-0x1.e7de8b3c8aa78p0
+copySign,-0x1.250e6e8bd43a9p3,-0x1.250e6e8bd43a9p3,-0x1.1c8849158f73bp-6
+copySign,0x1.9e75347b82bc2p2,-0x1.9e75347b82bc2p2,0x1.1cb9afbcdef47p4
+copySign,-0x1.e2f8822f31c16p-1,0x1.e2f8822f31c16p-1,-0x1.8ad3c5ca6b65dp-2
+copySign,0x1.b685eb38af916p0,0x1.b685eb38af916p0,0x1.6374ea7717b05p-6
+copySign,-0x1.979c64e9e1356p-1,-0x1.979c64e9e1356p-1,-0x1.d49e9503981dp0
+copySign,0x1.ab8e31884c0d5p1,0x1.ab8e31884c0d5p1,0x1.9c39fa86c97dp-2
+copySign,-0x1.1b35d4050d6eep3,0x1.1b35d4050d6eep3,-0x1.e52447d0af096p-1
+copySign,0x1.01ece3c27d9dcp-1,-0x1.01ece3c27d9dcp-1,0x1.145244847160cp6
+copySign,-0x1.b80c2678de384p-2,0x1.b80c2678de384p-2,-0x1.936c44fccd21fp-1
+copySign,-0x1.2052a36acdfedp3,-0x1.2052a36acdfedp3,-0x1.ba743cfd12628p0
+copySign,0x1.34e2b497e5db1p-1,0x1.34e2b497e5db1p-1,0x1.820c9bc86002cp1
+copySign,0x1.3b3c577d99964p-3,-0x1.3b3c577d99964p-3,0x1.049d22834db6cp0
+copySign,-0x1.85098ad6879f3p2,-0x1.85098ad6879f3p2,-0x1.2f3901f936a51p-2
+copySign,0x1.5ae7b6579504cp0,-0x1.5ae7b6579504cp0,0x1.784a5a5c4d26cp-1
+copySign,0x1.fafc40bb0a19cp-3,-0x1.fafc40bb0a19cp-3,0x1.69103cc689b08p3
+copySign,0x1.eabdbee4f9632p-3,-0x1.eabdbee4f9632p-3,0x1.d2afea24a5b42p-5
+copySign,-0x1.891004033ecd1p2,0x1.891004033ecd1p2,-0x1.3a11454e346a5p1
+copySign,-0x1.f01b6dc4ac0bbp1,-0x1.f01b6dc4ac0bbp1,-0x1.cfb6825579416p0
+copySign,0x1.f7c899d54f5c6p-1,-0x1.f7c899d54f5c6p-1,0x1.2d0fbe2b02166p-2
+copySign,0x1.7b38b91e000ccp-2,0x1.7b38b91e000ccp-2,0x1.ec7a13fe10c32p-2
+copySign,0x1.29200e4e691e8p0,-0x1.29200e4e691e8p0,0x1.22167b0a7138cp-1
+copySign,0x1.e1d6dede8d29bp-2,0x1.e1d6dede8d29bp-2,0x1.bb6f58f17f526p-5
+copySign,0x1.70b38d09c870dp0,-0x1.70b38d09c870dp0,0x1.5e3f8440b9a55p0
+copySign,-0x1.0d86ce4639fe5p-1,0x1.0d86ce4639fe5p-1,-0x1.a68483813b43cp-1
+copySign,0x1.704c56be88329p-1,-0x1.704c56be88329p-1,0x1.725af47086397p0
+copySign,-0x1.0d77a56187861p0,-0x1.0d77a56187861p0,-0x1.4e8f6c5c4da1fp-1
+copySign,0x1.616bc7a37d586p-4,0x1.616bc7a37d586p-4,0x1.dce538f8baef8p-1
+copySign,0x1.1984f7e58eb9fp-2,0x1.1984f7e58eb9fp-2,0x1.6bad4065ab9f9p-1
+copySign,-0x1.3bc46c7e3db39p0,-0x1.3bc46c7e3db39p0,-0x1.e3769055ffdd5p-1
+copySign,-0x1.890686c4cf1c2p1,-0x1.890686c4cf1c2p1,-0x1.c9f71a96f48b2p-2
+copySign,-0x1.60aaa4be5d131p1,0x1.60aaa4be5d131p1,-0x1.7cebdbee0a5fap0
+copySign,0x1.207e879e82852p1,0x1.207e879e82852p1,0x1.d738021c0a414p-1
+copySign,0x1.ca8842b5fa409p-1,0x1.ca8842b5fa409p-1,0x1.da66adef17274p0
+copySign,0x1.453da6fd920acp1,0x1.453da6fd920acp1,0x1.490346809f2c9p-1
+copySign,0x1.f40f26c3c0defp-1,0x1.f40f26c3c0defp-1,0x1.4bf3bcd970cfp-1
+copySign,-0x1.e17b7648f17b4p-3,0x1.e17b7648f17b4p-3,-0x1.ce8fac44b0264p-3
+copySign,0x1.c9e6c3dc73255p2,-0x1.c9e6c3dc73255p2,0x1.6e828ba149045p2
+copySign,0x1.d3e8a30c46d7p1,-0x1.d3e8a30c46d7p1,0x1.44afccd04b2c2p1
+copySign,0x1.1fe16aed90d5dp-1,-0x1.1fe16aed90d5dp-1,0x1.05f6ff020d2d3p1
+copySign,-0x1.0b67d7e1e5c5fp2,-0x1.0b67d7e1e5c5fp2,-0x1.7485440d87bedp-3
+copySign,0x1.6d14c2a1d5884p-2,0x1.6d14c2a1d5884p-2,0x1.0b603f6bc0c5cp1
+copySign,-0x1.200e9e5b458f1p1,-0x1.200e9e5b458f1p1,-0x1.1ddf63e8e2fdap5
+copySign,-0x1.191e5d337dd5p-2,0x1.191e5d337dd5p-2,-0x1.9159611a2cbe6p-2
+copySign,-0x1.5a4cdfcb8e387p0,0x1.5a4cdfcb8e387p0,-0x1.99b71920b3a42p-3
+copySign,-0x1.4edb118a322a9p1,-0x1.4edb118a322a9p1,-0x1.500dace8c8b9p0
+copySign,0x1.b8378828e00b7p0,0x1.b8378828e00b7p0,0x1.4a394aabf206ep-7
+copySign,0x1.ab4f73b6406b6p-3,-0x1.ab4f73b6406b6p-3,0x1.f9a4a4b155866p-1
+copySign,-0x1.7eacb4c59fb12p0,0x1.7eacb4c59fb12p0,-0x1.07fe825ae7a4fp-1
+copySign,0x1.15a0a17ecbc34p3,-0x1.15a0a17ecbc34p3,0x1.badefca8d13e1p3
+copySign,0x1.3ff41675d0a7ap-4,0x1.3ff41675d0a7ap-4,0x1.cb1c672a1658ep-1
+copySign,-0x1.b23ebb9174357p0,-0x1.b23ebb9174357p0,-0x1.dd12778fe5673p-1
+copySign,0x1.4bdada96f6dcap1,0x1.4bdada96f6dcap1,0x1.c26f18e638d3fp-1
+copySign,-0x1.bba29d24035efp-3,-0x1.bba29d24035efp-3,-0x1.3c380889a325cp-1
+copySign,0x1.02a89c0b5268cp0,-0x1.02a89c0b5268cp0,0x1.e300d4eec6a0ap-2
+copySign,0x1.55b2e0992047fp-2,0x1.55b2e0992047fp-2,0x1.1ac3b1feb5c5dp0
+copySign,-0x1.ce50f2788c33cp-1,0x1.ce50f2788c33cp-1,-0x1.b626ad516319ep-2
+copySign,-0x1.c2ca018fb926p-2,0x1.c2ca018fb926p-2,-0x1.9407139503761p-2
+copySign,-0x1.da74920d86b9ep2,-0x1.da74920d86b9ep2,-0x1.97c65cd575edcp-2
+copySign,0x1.bb518ae8cbeb5p-1,0x1.bb518ae8cbeb5p-1,0x1.538290c7db1f4p-2
+copySign,0x1.af5b250d0967ap-1,-0x1.af5b250d0967ap-1,0x1.f25525da93bfcp-1
+copySign,0x1.efcce730317acp0,0x1.efcce730317acp0,0x1.0e3cc24d1a6d3p0
+copySign,0x1.79e981a3dcf5fp-1,0x1.79e981a3dcf5fp-1,0x1.3718c1db7ea36p0
+copySign,-0x1.b3b07fab25362p-1,-0x1.b3b07fab25362p-1,-0x1.497027db2e31ap0
+copySign,0x1.a3f51d0063acfp0,-0x1.a3f51d0063acfp0,0x1.12bafba6131b7p1
+copySign,-0x1.6ae64480fad1p-1,0x1.6ae64480fad1p-1,-0x1.ae894d9208326p-3
+copySign,0x1.38ec72aab42efp-2,-0x1.38ec72aab42efp-2,0x1.37609b0c15295p7
+copySign,0x1.7261f9d8a06b6p-1,-0x1.7261f9d8a06b6p-1,0x1.5f7d4239730a7p3
+copySign,0x1.aa8341e431eeep-2,0x1.aa8341e431eeep-2,0x1.4965abdf5ea5ep2
+copySign,0x1.1876fd62a3b1bp0,-0x1.1876fd62a3b1bp0,0x1.d54386f9ede1p-2
+copySign,0x1.043f7753c91cp-1,-0x1.043f7753c91cp-1,0x1.a10b36b6b25b6p-1
+copySign,0x1.dc7a76693435dp-2,0x1.dc7a76693435dp-2,0x1.0d6f38f02ce74p-5
+copySign,-0x1.f5c235cf85acap-1,0x1.f5c235cf85acap-1,-0x1.9d1ba81be1b39p-2
+copySign,-0x1.8fd6c0e1894f8p-2,-0x1.8fd6c0e1894f8p-2,-0x1.9bb19e55de9b7p3
+copySign,-0x1.52b7a40bdb00bp-2,0x1.52b7a40bdb00bp-2,-0x1.b880297c99ddp-2
+copySign,-0x1.606226946e86ap-4,-0x1.606226946e86ap-4,-0x1.e3b5e858e235p-2
+copySign,0x1.be16c6dbe7e77p-1,0x1.be16c6dbe7e77p-1,0x1.18d16a97bf8e3p3
+copySign,0x1.93d6bff47ced7p-2,0x1.93d6bff47ced7p-2,0x1.bb654aa0e7343p-1
+copySign,0x1.c3ef005ead94dp-2,-0x1.c3ef005ead94dp-2,0x1.f96d72f57382fp-3
+copySign,-0x1.5d08152ecd007p-2,-0x1.5d08152ecd007p-2,-0x1.41e2bed9e0eb2p0
+copySign,0x1.0f0426ab5da2dp0,0x1.0f0426ab5da2dp0,0x1.180f1ed88e77bp-1
+copySign,-0x1.bf30ea42a1c62p6,0x1.bf30ea42a1c62p6,-0x1.79f4301027c34p0
+copySign,-0x1.4b2c95d80c1f8p-1,-0x1.4b2c95d80c1f8p-1,-0x1.bfdb14bead7b1p-2
+copySign,-0x1.fe8d41355fb51p-3,-0x1.fe8d41355fb51p-3,-0x1.106b10a1cf095p0
+copySign,-0x1.1e9ae4c0043cdp2,0x1.1e9ae4c0043cdp2,-0x1.b284b7bf2ed48p-1
+copySign,0x1.cf4752a33791ep2,-0x1.cf4752a33791ep2,0x1.d18edfd8af2d2p-2
+copySign,-0x1.34da3b809aa63p-3,-0x1.34da3b809aa63p-3,-0x1.5ed7996eb0cfep1
+copySign,-0x1.08462543a7f67p1,0x1.08462543a7f67p1,-0x1.622b88c45b6cp0
+copySign,0x1.ddb0f2a6118dp-4,-0x1.ddb0f2a6118dp-4,0x1.e2e91a136308ap-4
+copySign,0x1.0dc2c166f994fp0,-0x1.0dc2c166f994fp0,0x1.e2f251db9710dp2
+copySign,-0x1.7816949fdf252p-3,-0x1.7816949fdf252p-3,-0x1.25d0dfae54b6bp-2
+copySign,-0x1.6f32771c047f7p-2,0x1.6f32771c047f7p-2,-0x1.295d96f1a5e5bp-5
+copySign,0x1.023e90b9993efp0,-0x1.023e90b9993efp0,0x1.7c18d9c85dedcp-3
+copySign,0x1.84f071dee523ep-1,0x1.84f071dee523ep-1,0x1.d71ebec495bdcp3
+copySign,-0x1.0a7423ef61323p-1,0x1.0a7423ef61323p-1,-0x1.dd15fae5be205p-4
+copySign,-0x1.5f988007a55a1p-1,-0x1.5f988007a55a1p-1,-0x1.069d6b7740021p1
+copySign,-0x1.4cf28b55574adp0,-0x1.4cf28b55574adp0,-0x1.6778e69e6539ep0
+copySign,0x1.ebe7db995647dp-3,-0x1.ebe7db995647dp-3,0x1.81096c1fb11cep-2
+copySign,0x1.52e5afde5170dp-2,0x1.52e5afde5170dp-2,0x1.8a52b211e5e23p1
+copySign,-0x1.949c8dcc34bfep0,-0x1.949c8dcc34bfep0,-0x1.8f3553a64e9a3p4
+copySign,-0x1.3c33f5987f788p-4,0x1.3c33f5987f788p-4,-0x1.6e6b1f686a8f3p4
+copySign,-0x1.651f1423e68eap-1,-0x1.651f1423e68eap-1,-0x1.c526e77ba01eap1
+copySign,0x1.77e7bf9e99a76p-5,-0x1.77e7bf9e99a76p-5,0x1.e38cc78fad0c6p-1
+copySign,-0x1.1c181d4e01548p2,-0x1.1c181d4e01548p2,-0x1.7af633d5d0b38p-2
+copySign,-0x1.3001934e6ae0bp-2,-0x1.3001934e6ae0bp-2,-0x1.491f87b4ac373p1
+copySign,-0x1.af547dca7b826p-2,-0x1.af547dca7b826p-2,-0x1.4a4dd74c4d68p2
+copySign,0x1.78dba1b16b7dbp2,0x1.78dba1b16b7dbp2,0x1.6b74066c6b196p1
+copySign,-0x1.380961d62ec0dp-3,-0x1.380961d62ec0dp-3,-0x1.6e6aaee6298edp1
+copySign,-0x1.5cf87826e093ep-1,0x1.5cf87826e093ep-1,-0x1.ad5aa17eda056p-2
+copySign,-0x1.6fc1179d396p0,-0x1.6fc1179d396p0,-0x1.04302fee70a54p2
+copySign,-0x1.390659f7eb4cdp0,0x1.390659f7eb4cdp0,-0x1.8142f4ee52932p0
+copySign,-0x1.457189185be35p1,0x1.457189185be35p1,-0x1.a29b4fbc2cecep-1
+copySign,-0x1.2fdafd8daf546p1,0x1.2fdafd8daf546p1,-0x1.3352829eeb52ap1
+copySign,-0x1.3170c9d66604p-1,-0x1.3170c9d66604p-1,-0x1.153af45d94cb7p1
+copySign,0x1.722586c5396b4p-2,-0x1.722586c5396b4p-2,0x1.23fdf3add3787p-3
+copySign,0x1.d2b1ba3089506p-1,-0x1.d2b1ba3089506p-1,0x1.10002fbd075c2p0
+copySign,-0x1.48dbcf5c8188ep-1,0x1.48dbcf5c8188ep-1,-0x1.99be7ebce555bp-2
+copySign,-0x1.a9a87920c5ce4p3,-0x1.a9a87920c5ce4p3,-0x1.a05b68dd80554p-4
+copySign,0x1.1a9f934df77b5p-2,0x1.1a9f934df77b5p-2,0x1.b025bec52f56dp-3
+copySign,-0x1.a2adfb75ca99dp2,0x1.a2adfb75ca99dp2,-0x1.ba885fb9e404bp0
+copySign,-0x1.e09d728dc57ebp-1,0x1.e09d728dc57ebp-1,-0x1.75b95bff62f6cp-3
+copySign,0x1.c5593cba00eebp-5,0x1.c5593cba00eebp-5,0x1.7fb0e235bc2eep-3
+copySign,-0x1.3e89b0b0ab25fp0,-0x1.3e89b0b0ab25fp0,-0x1.8fa7c9a2f9bedp0
+copySign,-0x1.6faf937ce04c1p-1,-0x1.6faf937ce04c1p-1,-0x1.5feb7bf313fc1p-1
+copySign,0x1.bc23b8cbe4b6p-2,0x1.bc23b8cbe4b6p-2,0x1.19f1f78354f98p-1
+copySign,-0x1.c2119915765e5p-1,-0x1.c2119915765e5p-1,-0x1.876e1aa39077cp-10
+copySign,-0x1.01c346d4d878bp1,-0x1.01c346d4d878bp1,-0x1.d7c1227d6c119p1
+copySign,0x1.8ce2de24cf505p0,-0x1.8ce2de24cf505p0,0x1.198d30e9c11b4p2
+copySign,-0x1.288e3cab6a2e7p-1,0x1.288e3cab6a2e7p-1,-0x1.a89c4e9eb65cfp0
+copySign,0x1.b07ddc10ef97ap-1,-0x1.b07ddc10ef97ap-1,0x1.d789628d9a124p-4
+copySign,-0x1.dd2a148950301p-6,-0x1.dd2a148950301p-6,-0x1.2e6b8091614eap1
+copySign,-0x1.12f308ce41398p2,0x1.12f308ce41398p2,-0x1.bc8b51e9f443p6
+copySign,-0x1.4afaffad92481p-4,0x1.4afaffad92481p-4,-0x1.d89782a668c16p-1
+copySign,0x1.3ba2157bb5a21p-2,-0x1.3ba2157bb5a21p-2,0x1.d6c3f693229b1p1
+copySign,0x1.62c5c83d97087p2,0x1.62c5c83d97087p2,0x1.b1ec78bb1ee77p-2
+copySign,-0x1.1aa870ae181d3p5,-0x1.1aa870ae181d3p5,-0x1.a8c38c3d5764bp0
+copySign,-0x1.13237983c28bap-1,-0x1.13237983c28bap-1,-0x1.073560686b125p2
+copySign,0x1.440485a03c6bep-1,-0x1.440485a03c6bep-1,0x1.6c7ec47e69b2ep0
+copySign,-0x1.6b009e3e24ff3p1,-0x1.6b009e3e24ff3p1,-0x1.3bdf6b2ca1226p4
+copySign,0x1.86b6cc68a7493p4,-0x1.86b6cc68a7493p4,0x1.04b84cf137d19p-1
+copySign,0x1.239128f3f2cfcp-1,-0x1.239128f3f2cfcp-1,0x1.c2e45a93aa284p2
+copySign,0x1.b06c161e3d158p6,0x1.b06c161e3d158p6,0x1.418d5736566b4p1
+copySign,0x1.c4d364c8d6207p4,-0x1.c4d364c8d6207p4,0x1.ba81bd348bd68p-4
+copySign,0x1.e7b1ac8d6a23fp-1,0x1.e7b1ac8d6a23fp-1,0x1.bd3e6e94926ffp-3
+copySign,-0x1.84646cc829cfp-6,-0x1.84646cc829cfp-6,-0x1.067c187661027p0
+copySign,-0x1.1bfebdb2633a7p0,0x1.1bfebdb2633a7p0,-0x1.7a5e223dc1889p-2
+copySign,0x1.69bfe282b29a4p-2,0x1.69bfe282b29a4p-2,0x1.27729dac24612p0
+copySign,0x1.364c8afd2288ep1,-0x1.364c8afd2288ep1,0x1.4939bf2cc79bfp1
+copySign,0x1.1e104e615f229p2,0x1.1e104e615f229p2,0x1.5a0f78ff1b844p0
+copySign,0x1.080264d2974b4p0,0x1.080264d2974b4p0,0x1.48e2c5ad03dcep-2
+copySign,0x1.36ea7ecc7d913p-1,-0x1.36ea7ecc7d913p-1,0x1.5b8e5b16557d9p-3
+copySign,0x1.98ceb0be39d06p-1,0x1.98ceb0be39d06p-1,0x1.fd5fd1a41ade2p4
+copySign,0x1.461791ed70eedp0,-0x1.461791ed70eedp0,0x1.2098034e5257dp-2
+copySign,-0x1.0e863aa823658p-2,-0x1.0e863aa823658p-2,-0x1.6981ad1a51b86p5
+copySign,-0x1.cac1a69192654p-2,0x1.cac1a69192654p-2,-0x1.f55c98e03b68cp-6
+copySign,0x1.3309aa77b2c1ap-2,-0x1.3309aa77b2c1ap-2,0x1.f11564c63426ap-1
+copySign,0x1.edc084fb770ddp-5,0x1.edc084fb770ddp-5,0x1.2b912a59f3388p-1
+copySign,-0x1.b295af3affc24p-1,-0x1.b295af3affc24p-1,-0x1.c8ad5de54acecp1
+copySign,-0x1.43808dc4810f3p1,-0x1.43808dc4810f3p1,-0x1.8541214a13d1ap0
+copySign,-0x1.43990d0fc0ba3p4,0x1.43990d0fc0ba3p4,-0x1.165cc99ddcb41p1
+copySign,0x1.7af9a0494eb75p-2,0x1.7af9a0494eb75p-2,0x1.fca02fa705a9dp1
+copySign,0x1.2876d5adb29f5p-1,-0x1.2876d5adb29f5p-1,0x1.f8df58a3c29dbp-5
+copySign,-0x1.49f5e691137bdp0,0x1.49f5e691137bdp0,-0x1.455ada7c15032p-1
+copySign,-0x1.b5528b875cf65p1,-0x1.b5528b875cf65p1,-0x1.c5ea3878debd1p1
+copySign,-0x1.9ce99488b7ab4p3,0x1.9ce99488b7ab4p3,-0x1.8889d891b4a49p0
+copySign,0x1.b904b7fb7b589p-2,-0x1.b904b7fb7b589p-2,0x1.995da0765a726p-2
+copySign,0x1.9bdff08e77031p-2,0x1.9bdff08e77031p-2,0x1.8ec0666ac4f3fp-2
+copySign,-0x1.b8aee5bca4d84p-1,0x1.b8aee5bca4d84p-1,-0x1.9fdaa7abca4bcp0
+copySign,-0x1.f827acaf13633p4,0x1.f827acaf13633p4,-0x1.60d4ca7425722p-2
+copySign,0x1.1cc9b76dd0a65p0,0x1.1cc9b76dd0a65p0,0x1.1833bb6dccccdp-2
+copySign,-0x1.5748ad869338p4,0x1.5748ad869338p4,-0x1.d9c10e045123ap0
+copySign,-0x1.2743ef4061547p-1,-0x1.2743ef4061547p-1,-0x1.ac1f4d91209c3p-2
+copySign,0x1.bbb679a1647bbp-2,-0x1.bbb679a1647bbp-2,0x1.08b5bf8219ce6p0
+copySign,-0x1.069560250720cp0,0x1.069560250720cp0,-0x1.eba02acdec778p-1
+copySign,-0x1.365d3d73c52eep0,-0x1.365d3d73c52eep0,-0x1.818c200aa658ep-1
+hypot,0x1.8017a82d3363ep-3,0x1.035c9512d358dp-3,-0x1.1b4ca1504820ep-3
+hypot,0x1.bd197423d6635p0,-0x1.3179605bcd7dcp0,-0x1.43ba11665365cp0
+hypot,0x1.8aeac7c229b6p0,0x1.4fe074e3fd676p-1,-0x1.656e15ef969b7p0
+hypot,0x1.3580d43a93011p0,0x1.db8918b2fdcd8p-1,0x1.8c46c14d5afd9p-1
+hypot,0x1.373c78d07e52ep2,0x1.3641d487af99ap2,0x1.8aae0a08413d2p-2
+hypot,0x1.ad5fee98eb29bp-1,-0x1.accbc0217cb2p-1,0x1.649a1fcc0c4cbp-5
+hypot,0x1.7f5068cf4051bp1,-0x1.51fcf9b757d42p-3,-0x1.7ebb48fe34bf4p1
+hypot,0x1.58bc792d25202p2,-0x1.583c47afb2afep2,0x1.29307fc5a7ce2p-2
+hypot,0x1.53d3ad09df1fp1,0x1.073cf82be91edp1,-0x1.add3e494d4037p0
+hypot,0x1.016262e6307c2p1,0x1.28b80cd44885ep0,-0x1.a4a5da3ce316cp0
+hypot,0x1.0e4d8b6aa5e08p0,0x1.311064835aa81p-1,-0x1.be4ec7072592ep-1
+hypot,0x1.c11c1064ada32p4,0x1.a29a96a022628p-3,-0x1.c119040ae336dp4
+hypot,0x1.36c5961898dcfp2,0x1.34faef20b84efp1,-0x1.0da6c8cf17ee6p2
+hypot,0x1.4f3ff6aae5b99p0,0x1.040ee18ba0b07p-3,-0x1.4dab8c8f91fc1p0
+hypot,0x1.150ca9e71cd52p-1,-0x1.018ffca31383ap-1,0x1.984636905034cp-3
+hypot,0x1.bbb863c31d863p0,-0x1.bad342a98f7a6p0,-0x1.c2b4118dcde48p-4
+hypot,0x1.0c4a62f52adaap-1,0x1.0b1407c9dad71p-1,0x1.979f0307c39c2p-5
+hypot,0x1.57706318dcb2ap0,0x1.0f04ea72fde9p0,-0x1.a5e53d8a1dfdbp-1
+hypot,0x1.267541d554099p0,0x1.24faed88c1f27p0,0x1.d76dc40c15bf5p-4
+hypot,0x1.ec90fa1bf5a7fp-1,0x1.1eaa2c83eeeb3p-1,0x1.908e450f1847bp-1
+hypot,0x1.8c991ba802047p2,0x1.8651546f312e4p2,-0x1.19338343ba90cp0
+hypot,0x1.aad92cdc39b04p-2,0x1.152c91603038ap-2,-0x1.449d18ccb278cp-2
+hypot,0x1.21631ed90a577p1,0x1.a5bdc726dc45cp0,-0x1.8c604a66e05fap0
+hypot,0x1.1f21086b6526ap8,-0x1.c71e00f4249e2p-2,-0x1.1f20f1e04804fp8
+hypot,0x1.ab87a4b1099ap2,0x1.81a3fc7bb3c75p-1,-0x1.a8cdb4f1abeb8p2
+hypot,0x1.2281b0a4e7f7bp-2,-0x1.f81b8704b0955p-3,0x1.20e16841b160dp-3
+hypot,0x1.b65b179cf8c09p0,0x1.c06d19a70a803p-1,-0x1.78ace437034e7p0
+hypot,0x1.15dcce3c9decbp2,0x1.5bdf98fb6e2acp0,0x1.07e6d32abf5f7p2
+hypot,0x1.02bd3d2489d54p3,0x1.ea299155c629bp2,-0x1.4bcfd37dbd568p1
+hypot,0x1.186d9f5735b5fp-1,0x1.5c2c052c73881p-5,0x1.179527dc936bep-1
+hypot,0x1.43cee56f1a6dap1,0x1.2a16c30a612b2p1,-0x1.f9e19c365281ep-1
+hypot,0x1.20c79ed160387p2,0x1.1fee89d5737ecp2,0x1.61d3c2bd3d1efp-2
+hypot,0x1.9f2c1f990436cp-1,0x1.7564938f7927dp-3,-0x1.948abdc960078p-1
+hypot,0x1.93d9b49c8582fp-1,0x1.25d4214478fc7p-1,-0x1.150e45cd98ec1p-1
+hypot,0x1.268de963b13ccp-1,0x1.e19dc7b818391p-4,-0x1.20562925e0f3dp-1
+hypot,0x1.7bc04cf01f1dfp1,0x1.127b246843ab5p0,0x1.6215b0dc45a05p1
+hypot,0x1.493e2cba014fdp0,-0x1.98cea00a3d00cp-1,-0x1.021bcd4dfc3fep0
+hypot,0x1.074a8b6052eddp0,-0x1.0123efcaacc6bp0,-0x1.c49fdc1d31fc7p-3
+hypot,0x1.f87d0d411fb77p0,0x1.93dbe10d976c8p0,-0x1.2e55d460a68c1p0
+hypot,0x1.21b01adc7d5d4p1,0x1.09326ba7a131fp0,-0x1.018f261f8bb48p1
+hypot,0x1.a4091c6c7c7b5p1,-0x1.d698ccadef1ecp0,-0x1.5bf17c59a59fbp1
+hypot,0x1.a8da74b2de311p-1,0x1.d585820bc3e5cp-2,-0x1.6219f0919d956p-1
+hypot,0x1.e58e00daab4a8p-1,-0x1.8b7fff8553f0cp-1,0x1.19adda623b4e9p-1
+hypot,0x1.3c9125f484936p6,-0x1.3c90d882521c8p6,0x1.badef208bfb0fp-3
+hypot,0x1.ea3011c0f543bp-1,-0x1.bffa7db8de42cp-1,-0x1.8dfdda7c84022p-2
+hypot,0x1.c8417faa23771p0,-0x1.955d9ddff7839p0,0x1.a2cc6f7327644p-1
+hypot,0x1.5015828227fb4p0,0x1.0bc0514d1c9c5p-2,0x1.4959bf24e337fp0
+hypot,0x1.990caeba62831p-2,-0x1.71b0789a25c69p-2,0x1.5e267e0dfc068p-3
+hypot,0x1.7fdf153ba4ff5p2,-0x1.7e1ee76937d61p2,0x1.24f5b006b7dc6p-1
+hypot,0x1.18b4266b31b5p-1,-0x1.6ac13bedf55a7p-3,0x1.09a68045c0587p-1
+hypot,0x1.a535e62cc0e8dp3,0x1.0d68613d532b2p0,0x1.a3dcb7e793c5ap3
+hypot,0x1.51c58e272bebdp1,-0x1.493a047c97239p1,0x1.2dfb3b898aa8ep-1
+hypot,0x1.9fbba7b9f3223p0,-0x1.ab81047c0cb26p-2,0x1.91c2adf1cf61bp0
+hypot,0x1.c3cae8c055d28p-1,0x1.2b932f024eecap-1,0x1.52303de03e6cbp-1
+hypot,0x1.33cd3514c8c65p2,0x1.69ffa312bee3dp0,-0x1.263253bcf5adp2
+hypot,0x1.09dc1b47d4ff8p0,0x1.b30d7d6238dc5p-2,0x1.e53049c9b3acfp-1
+hypot,0x1.196d25030df8bp1,0x1.031723fc14628p1,0x1.b7820e016903bp-1
+hypot,0x1.9522414a32e74p0,-0x1.8572babad0f62p0,0x1.be8f8e453bc15p-2
+hypot,0x1.2f6cd48321bd7p1,-0x1.3cb3f1ad69bd3p-1,-0x1.24e9b837ea81ap1
+hypot,0x1.468c5be6ec2e4p1,-0x1.62dcd50a03becp-2,0x1.438580f9f8247p1
+hypot,0x1.9da77b392891fp-1,-0x1.6d574288b80f7p-1,0x1.83ffd55cb8a81p-2
+hypot,0x1.5176d43794d74p2,-0x1.5fac9f69cf192p-2,0x1.50bf648ff6d77p2
+hypot,0x1.70b66b40649d9p1,-0x1.6cb8e89367344p1,-0x1.b0c8f5127f707p-2
+hypot,0x1.234cbaed97268p1,-0x1.f7503d9f20336p0,0x1.256c922374787p0
+hypot,0x1.6d8784c3d84f3p1,0x1.5392d579bf882p1,0x1.0e90ef5859ae4p0
+hypot,0x1.e07408fa3aa64p-3,-0x1.a68e1b31b06b9p-4,-0x1.af8172d58ce1fp-3
+hypot,0x1.521dfd2317ef8p1,-0x1.432f3b3e0759dp1,-0x1.8d7de6d9c2bd8p-1
+hypot,0x1.6c63f48e45a31p-1,-0x1.6faf2282d0664p-2,0x1.3a9d661f261cap-1
+hypot,0x1.674bdc02e9a0bp1,0x1.674812a58db7ep1,-0x1.a14d5314f5264p-6
+hypot,0x1.f270ac8ef01b8p4,0x1.415b60ca7fcb2p-1,-0x1.f256c5e73cda2p4
+hypot,0x1.b7d8a2fbd6d1p2,-0x1.bffec7a06d6b7p-3,-0x1.b79f95d650223p2
+hypot,0x1.cd258330efbf7p0,0x1.44c8adf48bcecp0,0x1.475ee2b6c13c9p0
+hypot,0x1.a5506d089e931p0,-0x1.6df2b4cc974c5p-1,0x1.7b81fb6e663b1p0
+hypot,0x1.0014714db98e5p4,0x1.29f330b17d953p-1,-0x1.ffd230a5359bbp3
+hypot,0x1.acec442e7685cp7,-0x1.56f7de02b4136p-3,0x1.acec3b9c8dd78p7
+hypot,0x1.bd93ebfa0ed76p0,0x1.ad647304443a9p0,-0x1.dc035804e718ap-2
+hypot,0x1.8e03b5175cfb5p4,-0x1.b59106fcb173fp0,0x1.8d12e5f9f295ap4
+hypot,0x1.75941a32ed72ap0,0x1.880260c6fc7d8p-3,-0x1.7259d593af329p0
+hypot,0x1.a6bb3a0e03076p-1,0x1.8e6d7ada69108p-1,0x1.1a8a38056a267p-2
+hypot,0x1.aa5fffbbdfc31p-1,0x1.a45685abf4b7ap-1,-0x1.1dfb80efd3d33p-3
+hypot,0x1.b2d38ba4bfb8fp0,0x1.69617ec3eddc1p0,-0x1.e3a4d310e1969p-1
+hypot,0x1.a49fb548a8466p13,-0x1.6f75774d5f61ap-1,0x1.a49fb53ea02a6p13
+hypot,0x1.dd09a931578dp-1,-0x1.2082ff195f618p-1,-0x1.7be712002fbf2p-1
+hypot,0x1.401b22ceafd65p2,0x1.304116b6ca78bp2,-0x1.8df04eef5e3cep0
+hypot,0x1.39419858ee9dbp0,0x1.b05855f0ecfa8p-1,0x1.c56d30ad78eecp-1
+hypot,0x1.36ba750030663p2,-0x1.2eca04c9a45c9p2,-0x1.172a7006032acp0
+hypot,0x1.e4416f30acd7p0,-0x1.af16b5e1c9306p0,-0x1.b9351d8fcde7fp-1
+hypot,0x1.5f0dd88adfb2bp4,0x1.f9e4410be1debp-3,0x1.5f08267385e12p4
+hypot,0x1.7f6bd3646c94ap1,-0x1.abf9bcbba3bedp0,-0x1.3e270dc19ed1ap1
+hypot,0x1.1dc2e97a10a62p2,0x1.1a4350d7d067p2,-0x1.649f8a6ad3ab9p-1
+hypot,0x1.2d689682c167p2,0x1.2777997d3769p2,0x1.dc674976e59b6p-1
+hypot,0x1.3e109e9759f4cp-1,-0x1.dfc4c4f6c55d6p-4,0x1.385c2844181a3p-1
+hypot,0x1.f9056bb6ba48dp0,-0x1.b8f9d9f98d7p0,0x1.ec496ad9afd83p-1
+hypot,0x1.0b15ce9210793p3,-0x1.0aa38f9333759p3,0x1.edddac1222d8ap-2
+hypot,0x1.465d27068cb34p-1,0x1.033f2dfa7587ap-1,-0x1.8c81d44d2edd7p-2
+hypot,0x1.35f9b4f20ff7cp4,0x1.33aba6f1d125cp4,0x1.2dd8aa83efbeep1
+hypot,0x1.087346cd87a42p1,0x1.749d839bdf0bfp0,0x1.775bab304f38dp0
+hypot,0x1.a89eada56eed3p-2,0x1.9b91c9774806bp-2,0x1.a1da5c1595ca8p-4
+hypot,0x1.041e756d2a036p-4,-0x1.02b1e5879107ep-4,0x1.b2e6f33868b43p-8
+hypot,0x1.2415d267484d5p2,-0x1.1fc31fd3b33dfp0,-0x1.1b1650be2a772p2
+hypot,0x1.045e089a1ae7cp5,-0x1.044e7f6844b59p5,0x1.67c23d0c7967ep-1
+hypot,0x1.ee981daa3af01p-3,-0x1.da6609cbf5c63p-3,0x1.17c808e69464dp-4
+hypot,0x1.76c197cc053bcp2,-0x1.6b80ab7a7dcabp2,-0x1.6c98345550a4dp0
+hypot,0x1.26dd9f912c6d3p1,0x1.b4c2ecd022fc1p-6,0x1.26d891a499cddp1
+hypot,0x1.37e3348a3266dp-1,-0x1.156481f292284p-1,-0x1.1d259111e5715p-2
+hypot,0x1.3119960ee85dap1,0x1.b4a7a666a7cep-5,-0x1.31060df4f99edp1
+hypot,0x1.1519f4cf0ea02p1,0x1.05949b6f7ac3bp0,-0x1.e8960a19b528cp0
+hypot,0x1.fb63131444d72p-1,0x1.3ddacbc4d63e9p-3,0x1.f52036c5be9fcp-1
+hypot,0x1.8e62df654957cp1,0x1.546b78d0e40abp1,0x1.9de377eedc526p0
+hypot,0x1.168806ceaf54ap1,-0x1.c15b0d201cda2p0,-0x1.493d317cda155p0
+hypot,0x1.3225c5f998373p0,-0x1.2830126a5c178p0,-0x1.35d0e543809e4p-2
+hypot,0x1.ad83881035fa4p-1,-0x1.25c678eb6e408p-3,0x1.a7302276676d9p-1
+hypot,0x1.926e8d9f40793p-2,0x1.2f4c778b2da78p-4,-0x1.8b395829adc47p-2
+hypot,0x1.2d3e7ab1cf40dp1,0x1.e2a1b88474772p-2,-0x1.27242d9f3bd04p1
+hypot,0x1.38cae4e02bff1p4,-0x1.38411d9304aa3p4,-0x1.257570c64c2f3p0
+hypot,0x1.71ca45acb60e9p-3,0x1.0324663656b88p-5,-0x1.6c1221fc33928p-3
+hypot,0x1.01432baacbdc3p1,-0x1.50a65058c6723p0,-0x1.851ae4d375c3bp0
+hypot,0x1.13d28ce29c231p2,0x1.11265e394534ap1,0x1.df4587b32d3b1p1
+hypot,0x1.afc91f2dd16d6p0,0x1.a6fbb94c03904p0,0x1.5af68f6d9bbcp-2
+hypot,0x1.bff22080c3055p0,-0x1.38847b1044ce5p-5,-0x1.bfd6de9a148cp0
+hypot,0x1.c47f5855fa922p3,-0x1.507a0b8186773p-3,0x1.c47786a33add8p3
+hypot,0x1.66a689bcf92d7p-1,0x1.191b9b482a7fbp-1,-0x1.bd75b0d18cea2p-2
+hypot,0x1.02575fd2bf78ep4,0x1.817ccc59a8271p-3,0x1.0252e15d0388ep4
+hypot,0x1.d6ee5545f763ap0,-0x1.9bf454314d092p-2,-0x1.cb881aadaca7dp0
+hypot,0x1.81cf4cb57f074p1,-0x1.ee7fc6f4fff17p-1,0x1.6d7789a8f0cbfp1
+hypot,0x1.58a4d388253bfp1,0x1.d92b7f594eef9p0,-0x1.f539eceee06fap0
+hypot,0x1.aaf11e3d43fa6p4,0x1.aaf0b4237b71ep4,0x1.2cfe8369e23c4p-4
+hypot,0x1.43119ce321232p1,-0x1.36ad99667b8d3p1,0x1.627563d2d87cfp-1
+hypot,0x1.3a67807d50897p1,0x1.d94d0af047ce5p0,0x1.9dfd0e6432532p0
+hypot,0x1.c6c8ce885af15p0,-0x1.f6a2103fd574dp-1,-0x1.7b096810d00bfp0
+hypot,0x1.7eb6eb5b2d209p2,0x1.75fe4773e99p2,-0x1.44f29d9b38acap0
+hypot,0x1.1174ddb59c62bp1,0x1.3b812b948c3d1p0,0x1.bebbbec78a821p0
+hypot,0x1.8b090f8456993p0,-0x1.8422e7e1768dp-1,-0x1.58144753460ebp0
+hypot,0x1.b8e5e3a91d0dbp1,-0x1.d4a84fc843599p-1,-0x1.a90b9d04bd13ep1
+hypot,0x1.59a78eb87b229p0,-0x1.048bc8710db5cp-4,0x1.59454e6a140b1p0
+hypot,0x1.1fecf764af115p1,0x1.3c5c7003e5afep0,-0x1.e12a681e8034ep0
+hypot,0x1.7f118ef06aec5p0,0x1.86df8d0a2c418p-2,0x1.726532058c327p0
+hypot,0x1.f8f42b5158094p1,0x1.8209e521b3935p-2,0x1.f6a48f603e064p1
+hypot,0x1.32115d8e1bc4dp3,-0x1.f8d14cb4cb74ap0,0x1.2b7e06b2fbd07p3
+hypot,0x1.6b950430e37dbp0,-0x1.44a5a8119fdb4p0,0x1.47641324ef577p-1
+hypot,0x1.c1f2b2ff94756p2,-0x1.8886fc5e32efp2,-0x1.b7e3919de6f4ep1
+hypot,0x1.4acf61319f386p1,0x1.41fa14e8008aap1,0x1.2fbdea47bd94fp-1
+hypot,0x1.cc0c55809e1a6p0,0x1.81703e54c1c4p0,-0x1.f6521b1f1354dp-1
+hypot,0x1.99fdf6a85eef6p1,0x1.1e8543c9774b4p0,-0x1.8025fb6a780cep1
+hypot,0x1.8c40f4899458bp1,-0x1.f74893f7b1928p-1,0x1.77bf572b54b79p1
+hypot,0x1.f35832c710289p0,-0x1.28d787a926bcep-1,-0x1.dcc6e0481f2f1p0
+hypot,0x1.4648f024ad8dap0,-0x1.2683ffd9a9185p0,-0x1.18df74dfc99cbp-1
+hypot,0x1.63ef5de5b5ee8p1,-0x1.0db098198b967p1,-0x1.d092d38c00816p0
+hypot,0x1.104d8ab3eb11bp3,0x1.4a90dcca30dcep-1,-0x1.0f849acddd53ap3
+hypot,0x1.2907643018514p2,-0x1.25bdc94ce5d1cp2,-0x1.608f72e4bd0fap-1
+hypot,0x1.56a72ae4b9e94p0,0x1.c172c5b8dc582p-6,0x1.5694be2afe189p0
+hypot,0x1.7c913da22a1b4p0,0x1.6ceabebeb1aa6p0,-0x1.b00ebbe92fe9ep-2
+hypot,0x1.9b79e9c4011d4p0,0x1.424af6585a36ap0,-0x1.ff9ffbffd1331p-1
+hypot,0x1.b3821e3ebf1b5p0,-0x1.2687bc1b2e4cdp0,0x1.40cf80485c17bp0
+hypot,0x1.cde6ed75e0459p-1,-0x1.94fdeaec94d8cp-1,0x1.bc3ae9e16d5f8p-2
+hypot,0x1.62e1a9b5bd5b4p-1,0x1.14bc4656a0dddp-6,-0x1.62c6af2ad15d4p-1
+hypot,0x1.843071da576b2p0,0x1.517b32a05ad5fp-1,0x1.5d989f0bed307p0
+hypot,0x1.ea4dd008eaa16p1,0x1.e98659e3b8254p1,0x1.ba15766e322d9p-3
+hypot,0x1.eccb4068cf0d1p-1,-0x1.7feee220563bp-1,0x1.34ef8588ec801p-1
+hypot,0x1.13ac3ec05c11dp0,0x1.a8468d66bd8e7p-1,0x1.6018d1abe1a61p-1
+hypot,0x1.e602f9743bb51p0,0x1.3884aef9b9575p0,0x1.74358720cd00fp0
+hypot,0x1.919bb779dea3dp0,0x1.561919639cff9p0,0x1.a4c0985f4044p-1
+hypot,0x1.79fae38a64176p0,0x1.cc02224bb6489p-1,0x1.2bf1ea03166e8p0
+hypot,0x1.9e419a0dfc32p0,-0x1.2cc3028a36a64p-1,-0x1.81ff4870c85ccp0
+hypot,0x1.eef893d3dcbe6p2,-0x1.e6f1a4c783a04p0,-0x1.dfc46cc74dd64p2
+hypot,0x1.d2c1e613e4a55p-1,0x1.d158adbf0339cp-1,-0x1.22207fa622328p-4
+hypot,0x1.894e2337fc0d9p-1,-0x1.5b60941b5241p-1,-0x1.70e12d3fa5db9p-2
+hypot,0x1.5b1ab4e7fba04p-2,-0x1.4c42574154c9p-2,0x1.91b3aad06999bp-4
+hypot,0x1.c6037ec51f64cp1,0x1.b9275edc200e8p1,-0x1.ad2bc12e2599p-1
+hypot,0x1.af2b1a2685f99p0,-0x1.ab9b0e474d967p-3,0x1.abd7ac669b2d2p0
+hypot,0x1.48a9c2589c728p0,0x1.1dcef0625d0a2p-1,-0x1.27f825ee39e79p0
+hypot,0x1.3659f059cad77p-1,0x1.417f43db8ce85p-4,-0x1.33bd0960ab133p-1
+hypot,0x1.fe90bc6be9ef4p1,0x1.00e72de68d745p1,-0x1.b9391d6441499p1
+hypot,0x1.1568085ae001fp1,0x1.23cd4482baa0ep0,0x1.d7e0c765b481fp0
+hypot,0x1.a047c49b0bde1p-2,0x1.47511ca4d566ep-2,0x1.0133c8166661ap-2
+hypot,0x1.10cce99512b87p0,-0x1.107bb18770d41p0,0x1.a4e42adbe428dp-5
+hypot,0x1.457a166cb4078p3,-0x1.4579ff77f47a2p3,0x1.e8f8b25e670edp-7
+hypot,0x1.952b55bc85bd5p2,-0x1.951e3c55c86c3p2,0x1.9c1986dfb62bfp-4
+hypot,0x1.4ed6383e6299cp0,0x1.43d537aa1be88p0,0x1.548a19f98e3a8p-2
+hypot,0x1.000528b3f0ed7p1,-0x1.8a727b769138dp-3,-0x1.fda92ebdb0fd4p0
+hypot,0x1.978ed2893e4ecp-1,0x1.c0875a3cb510bp-2,0x1.544e9fab93924p-1
+hypot,0x1.2f1f72c453c24p2,0x1.e9d79a82803b3p0,-0x1.1548ea1f30464p2
+hypot,0x1.15518286d99e5p1,-0x1.0941e6e741adbp1,-0x1.439468d92ee49p-1
+hypot,0x1.50a58b6e00083p0,-0x1.8f9811df2239ap-2,-0x1.417b9ffd99018p0
+hypot,0x1.784f5a15004bbp2,-0x1.41da2a0bf3807p-1,0x1.76273812c2c52p2
+hypot,0x1.70af7ebdaf6ccp1,0x1.e5b3ebf06c063p0,0x1.156711d3ca2ccp1
+hypot,0x1.0d938539dbe96p0,-0x1.0eb2ac33bf57cp-2,-0x1.04f18a62ee1adp0
+hypot,0x1.f62262f339a7ep0,0x1.6100184e24683p-1,0x1.d61792743ce6dp0
+hypot,0x1.793302d58395fp2,-0x1.96bbe5f70caecp-3,-0x1.78fc2c3f53676p2
+hypot,0x1.2cc612f04cb84p1,0x1.161ad1d26afb7p1,-0x1.ca3719322ca2ep-1
+hypot,0x1.eb865a4473334p2,0x1.ea4e0f45d30bcp2,-0x1.14dd9faadeda6p-1
+hypot,0x1.374733be9f265p3,-0x1.36eb870cf1d02p3,-0x1.dda8f30fd43f9p-2
+hypot,0x1.00d5ba2f84b1dp5,-0x1.00d398c19548dp5,-0x1.08a750aec5e2cp-2
+hypot,0x1.30335553c8f9bp3,-0x1.efda9ea09b8d6p2,-0x1.6088dc8957025p2
+hypot,0x1.a0d8bd280e2c5p0,0x1.8f1ee95246894p0,0x1.e10fafc6cb42ap-2
+hypot,0x1.50eedd03ad891p0,-0x1.c0f1d9414c899p-1,0x1.f689a99fe4f7fp-1
+hypot,0x1.411383f09b35cp0,-0x1.244c4d4b2c51p-4,0x1.408e5b9ef6893p0
+hypot,0x1.937fffc74dd4fp1,-0x1.6658a91669e4cp1,0x1.72f2113c8c03dp0
+hypot,0x1.0dbe619dab1a1p2,-0x1.b3821369a8b0fp-1,0x1.08317c141257bp2
+hypot,0x1.ba6329899a6ep0,0x1.02970362943cep0,-0x1.66f09bd0d6d81p0
+IEEEremainder,0x1.92c6b518a96cp-4,-0x1.95cc024bc2e3dp2,-0x1.12ba136ac3b1p0
+IEEEremainder,-0x1.9a2601ee0b37cp-3,0x1.68e971ffed245p0,-0x1.12c976d3c9b23p-1
+IEEEremainder,-0x1.59e4503ff371p-3,-0x1.59e4503ff371p-3,-0x1.0c912a93f545ap-1
+IEEEremainder,-0x1.1741eb551c2a8p-3,-0x1.7b22c6245681cp0,-0x1.583a88b9b2fc7p0
+IEEEremainder,-0x1.d7104568a7836p-1,-0x1.d7104568a7836p-1,0x1.1165425b27d26p3
+IEEEremainder,-0x1.c961b96a089p-8,-0x1.3cc42fab56789p0,-0x1.3afacdf1ec7p-1
+IEEEremainder,0x1.67ad60a725d94p-3,-0x1.9e305f6421286p-1,-0x1.f81bb78dea9ebp-1
+IEEEremainder,0x1.98ebb4994eb7p-2,-0x1.16cff8747f0bep2,0x1.95d39a52c549cp0
+IEEEremainder,0x1.ae51d87c54eb6p-7,-0x1.e04eec4369cp-1,-0x1.d8460389127fbp-6
+IEEEremainder,0x1.530e632e0fdep-5,0x1.7a4ee15cae799p1,0x1.4b90952aa1facp-3
+IEEEremainder,-0x1.125599ee187fp-2,-0x1.5d9b3beed2a9fp0,0x1.1905d5734c8a3p0
+IEEEremainder,0x1.bf7034499694fp-6,0x1.bf7034499694fp-6,0x1.ebb4f6d58bb0bp0
+IEEEremainder,-0x1.a5151b60d8bbp-7,-0x1.4aeaf96c5ad82p0,0x1.766ea3aaf82c3p-3
+IEEEremainder,0x1.a1abeca2f5a04p-1,0x1.a1abeca2f5a04p-1,0x1.89d9fa4183389p7
+IEEEremainder,0x1.be4eb07f74d0bp-2,0x1.be4eb07f74d0bp-2,0x1.eaf676f43fb5ep-1
+IEEEremainder,0x1.3817ca0dd4788p-2,0x1.05a60fc50797fp2,-0x1.42db6edae315ep0
+IEEEremainder,0x1.5727f14b4a2d4p-2,-0x1.baa350a59c65ap0,0x1.6048ddfaf4a0ap-1
+IEEEremainder,-0x1.560ac9f65ba88p-2,0x1.f9013c566b5c8p0,0x1.2741f76a01235p0
+IEEEremainder,-0x1.c209a136b2107p-3,-0x1.c209a136b2107p-3,-0x1.bf8cef105da2bp-1
+IEEEremainder,-0x1.8a0951dd94f8p-4,-0x1.dbb3ba40684ccp1,-0x1.cf636fb17ba5p-1
+IEEEremainder,-0x1.1aa58e7a688dp-3,0x1.78312de742afcp-1,0x1.beda9185dcd3p-1
+IEEEremainder,-0x1.6766e2484b6e6p-2,-0x1.6766e2484b6e6p-2,0x1.577d4e4f0a8adp3
+IEEEremainder,-0x1.c53f47ce2dcep-4,0x1.511dfb3f748bp0,-0x1.6d71efbc5767ep-2
+IEEEremainder,0x1.9e954913c2dd4p0,0x1.9e954913c2dd4p0,0x1.53fb22fb97bp2
+IEEEremainder,-0x1.355a2d8403ea8p-3,-0x1.25c864b796e12p2,0x1.7ad219b9f3ad1p-1
+IEEEremainder,-0x1.34dbe8a6a7924p0,0x1.109179f49d05p1,-0x1.aaff6e47f0ce2p1
+IEEEremainder,0x1.ec34fbb4845b4p-3,-0x1.146ddb5d93238p-1,-0x1.8f7b1a4ab43a5p-1
+IEEEremainder,0x1.34d78f654359p-3,0x1.df2ba06f0eedp-1,0x1.91f5bc95be16cp-1
+IEEEremainder,0x1.4602d01729278p-1,-0x1.169c4aaf3aaa2p1,0x1.681cfeb504f4p0
+IEEEremainder,-0x1.3e96fbbad1928p-4,0x1.1936c90d6d1ccp1,-0x1.843a0139af8c7p-1
+IEEEremainder,0x1.e7de6e593b4c9p-1,0x1.e7de6e593b4c9p-1,-0x1.f4fed08490e1ap3
+IEEEremainder,0x1.3af0189c84d26p1,0x1.3af0189c84d26p1,0x1.7b6bd7a20d154p4
+IEEEremainder,0x1.7d2d2251f0754p-1,0x1.7d2d2251f0754p-1,-0x1.9c6393376bfd1p0
+IEEEremainder,0x1.a31c623321f7cp-1,-0x1.b9a70bc0f5db9p1,-0x1.11371226df2ccp2
+IEEEremainder,-0x1.0cd0bd0e6842p-10,0x1.a6e596084c617p-1,-0x1.d3395f56fb20ap-9
+IEEEremainder,-0x1.64ca49c110acp-16,0x1.07e061bfc14e8p-3,-0x1.d1f4946d915f6p-11
+IEEEremainder,-0x1.c4452529a9659p-2,0x1.f5555f0474e8bp-2,-0x1.dccd42170f272p-1
+IEEEremainder,-0x1.60cbc9caaa554p-7,0x1.bc5c37443371ap-3,-0x1.0a851da51131bp-5
+IEEEremainder,0x1.d171a1425a2a2p-4,0x1.d171a1425a2a2p-4,0x1.b32fd3630b0a2p-1
+IEEEremainder,-0x1.08655b374b8ccp-3,-0x1.1ec25309b279fp0,0x1.fb6b4f459210bp-1
+IEEEremainder,0x1.be5e794c843p-5,0x1.1b14147e07b68p8,0x1.0c594009b566cp0
+IEEEremainder,-0x1.633debecdeeep-4,-0x1.4775fe0141a8p0,-0x1.31421f4273b92p-2
+IEEEremainder,0x1.f6dba8e8a3c8bp2,0x1.f6dba8e8a3c8bp2,-0x1.016df1a64bdc5p5
+IEEEremainder,-0x1.221bc0b1a575p-1,-0x1.3304df061564ap3,-0x1.812ed94ea411cp0
+IEEEremainder,0x1.4249f849fd958p-5,0x1.f1e7f8eda3c1ap-2,0x1.c99eb9e4640efp-2
+IEEEremainder,-0x1.6ca2e52eb0cf8p-4,0x1.42e03452c82bep-1,0x1.707490f89e45dp-1
+IEEEremainder,-0x1.111fa3d8ce6bp-2,0x1.ad3896820fcb4p0,0x1.f1807f784366p0
+IEEEremainder,0x1.6aa7b57fa52c9p-6,0x1.6aa7b57fa52c9p-6,0x1.0a8a01b31c07ap-2
+IEEEremainder,0x1.d0e82b44db0d8p-3,0x1.01dd957f2f574p0,0x1.8f81202d27eb2p-1
+IEEEremainder,-0x1.eba043b61e22bp-2,-0x1.eba043b61e22bp-2,0x1.823946b1a8b2dp5
+IEEEremainder,0x1.8f3a751f5e40dp-1,0x1.8f3a751f5e40dp-1,-0x1.11254ed0e4508p1
+IEEEremainder,0x1.8f7337e12436p-2,0x1.5fbe1b7bb322fp1,0x1.2dcfb47f8e9c3p0
+IEEEremainder,0x1.801173086a19cp-2,-0x1.f28701e56f1acp-1,-0x1.5947ddb4d213dp0
+IEEEremainder,0x1.2d16336b4f27p-5,-0x1.2761251b0a27cp5,0x1.3636fe96f8a33p-2
+IEEEremainder,0x1.0e9be76ca753p-2,-0x1.2191cbc42d8bbp0,0x1.6538c59f57607p-1
+IEEEremainder,0x1.f06beaa1ecffp-4,0x1.2340bf87d2f7dp3,-0x1.486d9b1535d8fp-2
+IEEEremainder,-0x1.f2bfee626cf63p-1,-0x1.f2bfee626cf63p-1,-0x1.f81068e93d56ep5
+IEEEremainder,0x1.15cf59d769c4ep-3,0x1.15cf59d769c4ep-3,0x1.b1ca867b89e08p0
+IEEEremainder,-0x1.80addfdd0941p-4,-0x1.80addfdd0941p-4,-0x1.005e82dd26f59p1
+IEEEremainder,0x1.24aafaa91869fp0,0x1.24aafaa91869fp0,0x1.7dfab3cc95b52p2
+IEEEremainder,-0x1.f92f4d9bed0cp-3,-0x1.1bb7032f2fbc6p1,0x1.5030131c968f8p-1
+IEEEremainder,-0x1.b4c7cdb3ae61cp-2,-0x1.b4c7cdb3ae61cp-2,0x1.325583f80f736p0
+IEEEremainder,-0x1.b8c5db7d4a0ap-5,0x1.d7cf470433cd5p-1,0x1.4ce7c328059eap-3
+IEEEremainder,-0x1.4f82aca892d2p-5,0x1.2fe0b25c9b32p1,0x1.9c28fc1451fc6p-1
+IEEEremainder,-0x1.39acd6a8b27c5p-3,-0x1.39acd6a8b27c5p-3,-0x1.7af77e4a212e7p-1
+IEEEremainder,0x1.8c0696e5b34e9p-2,0x1.8c0696e5b34e9p-2,0x1.9b7f48ed07846p-1
+IEEEremainder,0x1.698974bdc50fp-9,-0x1.c0c8dfb7b7bb9p-1,-0x1.0ac88a2d4f1cdp-5
+IEEEremainder,0x1.9510bee0122a8p-3,-0x1.5ab25b780c4f5p0,0x1.8d5473540e94ap-1
+IEEEremainder,-0x1.9a93749e545a4p-1,-0x1.9a93749e545a4p-1,0x1.d2bfce6af6e8bp0
+IEEEremainder,-0x1.1c1b92874640bp-2,-0x1.1c1b92874640bp-2,0x1.7164c361b4fb2p-1
+IEEEremainder,0x1.9ab124bd90451p-2,-0x1.b7713f10f18cfp-2,0x1.a91131e740e9p-1
+IEEEremainder,-0x1.de23f63acdb76p-4,0x1.b80bd10967ca1p-3,0x1.538ee6136752ep-2
+IEEEremainder,0x1.2aaf4c0aa998p-6,0x1.44c087f959307p1,-0x1.426b296143dd4p0
+IEEEremainder,0x1.60a5b367a21p-1,0x1.26fa1c4ae3125p4,0x1.1bf4eeafa601dp1
+IEEEremainder,-0x1.923d2cfb69cf4p-1,-0x1.923d2cfb69cf4p-1,-0x1.9750d975a46c2p2
+IEEEremainder,-0x1.164f2c1d842fcp0,-0x1.164f2c1d842fcp0,0x1.16f9c68a74e4dp1
+IEEEremainder,0x1.68e94f7bcb251p-3,0x1.68e94f7bcb251p-3,0x1.0a8ede9c2f8ccp-1
+IEEEremainder,-0x1.18a29df42db78p-3,0x1.0e898090ee4a5p-1,-0x1.54b2280df9b83p-1
+IEEEremainder,0x1.6fa5356df394p-9,-0x1.d91bc89cac659p-2,-0x1.0ffd2f7204be2p-4
+IEEEremainder,0x1.22f5024349918p-6,0x1.4fad4097e876dp2,-0x1.5954f32f1e1e3p-4
+IEEEremainder,-0x1.4af7a4c3b892p-7,-0x1.256481e2329efp5,0x1.5a06de444e51ep-4
+IEEEremainder,0x1.4b39ddcc0e938p-5,0x1.49b4d70083a66p1,-0x1.72e47f785f56fp-2
+IEEEremainder,0x1.61bd946f1d0c8p-3,0x1.3aa06dbb9394dp1,-0x1.86061b462d056p-1
+IEEEremainder,-0x1.384e7178de044p-1,-0x1.ee295446e3e42p0,0x1.52021b8a74e2p0
+IEEEremainder,0x1.d5cc2f6198654p-6,-0x1.9b664b57eebf3p0,0x1.f048deea0613ep-5
+IEEEremainder,-0x1.08dadc47e3e4fp0,-0x1.08dadc47e3e4fp0,-0x1.354cbca212e52p1
+IEEEremainder,-0x1.916e3613b954p-3,-0x1.341bb9b9bf9ccp2,0x1.2790480921d22p0
+IEEEremainder,0x1.13770164501dp-3,-0x1.83d9670ce8401p1,0x1.440d78e8f1018p-1
+IEEEremainder,-0x1.7e1599abf88d2p-1,-0x1.4383fb2757057p1,0x1.c7fd2978b1c45p0
+IEEEremainder,-0x1.1b01d08de8179p-1,-0x1.1b01d08de8179p-1,-0x1.21d9a4a26db98p1
+IEEEremainder,-0x1.e41655279f92cp-1,0x1.688ea04e5c7acp0,0x1.2d4ce57116221p1
+IEEEremainder,-0x1.6ac9fddf4c2a6p-2,0x1.0c8e40f30dd9fp1,0x1.a28a00e949d45p-1
+IEEEremainder,-0x1.b215df61001dp-6,-0x1.d1baea2634851p-2,-0x1.5ee13cf35069p-4
+IEEEremainder,0x1.5ef9acbc8d206p-3,0x1.5ef9acbc8d206p-3,-0x1.f228f6f21ec12p-1
+IEEEremainder,0x1.1c31d39c6df9ap-3,0x1.1c31d39c6df9ap-3,0x1.c28d77df17f78p-1
+IEEEremainder,0x1.cd1c08e3be29p-4,-0x1.a3f47d0f2b0aap-2,0x1.0b9dbfa40d4a7p-2
+IEEEremainder,-0x1.0e60e475204p-10,0x1.850a519b5bad9p0,-0x1.854de9d478f5ap0
+IEEEremainder,-0x1.1b3d8cf21f434p-2,0x1.1459eb7cc6c09p-1,0x1.a1f8b1f5d6623p-1
+IEEEremainder,0x1.3c8e07e87cd3p-3,0x1.4a657594ff29dp-1,-0x1.f683e735bfea2p-2
+IEEEremainder,0x1.397b539fcea7p-3,0x1.28363fbac5405p0,-0x1.0106d546cb6b7p-1
+IEEEremainder,-0x1.1c55238bd3a5ep-2,0x1.2ff0484ad2a9p1,-0x1.c4a3e65066d25p-1
+IEEEremainder,0x1.703495b8c3537p-4,0x1.703495b8c3537p-4,-0x1.fa9864790c4c8p-3
+IEEEremainder,0x1.7155ccb6adb4p-6,0x1.546c341ff48f8p0,0x1.be33d13c22764p-3
+IEEEremainder,-0x1.c85aaf7aa4dbdp0,-0x1.c85aaf7aa4dbdp0,-0x1.a19a554f8fb0dp2
+IEEEremainder,0x1.59d7f420d6604p-2,-0x1.3c961c035d721p0,0x1.930c190b930a2p-1
+IEEEremainder,-0x1.7d37127616d11p-2,-0x1.7d37127616d11p-2,-0x1.9e0c653b825f5p0
+IEEEremainder,0x1.c105434e9e858p0,-0x1.00c6e4c4ab6a5p4,0x1.7bc9a14cc718ep2
+IEEEremainder,0x1.217e17fbaa198p0,0x1.217e17fbaa198p0,-0x1.c49ecbec7927dp4
+IEEEremainder,-0x1.138fc24a55672p-2,-0x1.05b84b6b50fc8p0,0x1.81a8b5b177457p-1
+IEEEremainder,0x1.9ed238fe1b80ap-6,0x1.9ed238fe1b80ap-6,-0x1.d4fe0e4e2c1ffp3
+IEEEremainder,0x1.4e164c6236a06p-1,-0x1.2a59f20997f46p0,-0x1.d165183ab3449p0
+IEEEremainder,0x1.d8e9b187f42ep-6,0x1.65593a63826f6p1,0x1.d789deab435ebp-4
+IEEEremainder,0x1.141578906beb3p-2,0x1.141578906beb3p-2,-0x1.0aae845ac8ed1p1
+IEEEremainder,0x1.db03194fa9092p-2,0x1.db03194fa9092p-2,0x1.b4ec10edb7605p2
+IEEEremainder,0x1.718f32fdb8cdcp-2,-0x1.56af54047de67p1,-0x1.0340d19823557p0
+IEEEremainder,-0x1.3df2956b19378p-5,0x1.21a18fc05f703p-3,0x1.711e351b25be1p-4
+IEEEremainder,0x1.915f9b24cf9ep-9,-0x1.39f19304c5942p1,0x1.92597e9e27667p-4
+IEEEremainder,-0x1.341222a731e64p-2,-0x1.03c739f1bda5p4,0x1.0ff656d467529p0
+IEEEremainder,0x1.2aa3c6cd7066fp-1,-0x1.d15153e9429f9p-1,0x1.7dfa8d5b59834p0
+IEEEremainder,0x1.9599ad0617bccp-2,-0x1.233788b724cd4p3,0x1.e63a236555ab7p0
+IEEEremainder,0x1.28357c323b3ep-2,-0x1.644e42bd4b7bap1,0x1.8954f24392e36p1
+IEEEremainder,-0x1.ab2ade18b8968p-4,0x1.f18fa04c46186p3,-0x1.c9f6d250e251ep-2
+IEEEremainder,-0x1.09e9c86d9134ap2,-0x1.09e9c86d9134ap2,0x1.6744144abe6p6
+IEEEremainder,-0x1.1da10fbf01c6fp-3,-0x1.1da10fbf01c6fp-3,0x1.13fbd42bacaccp0
+IEEEremainder,0x1.b703466af4f34p-3,-0x1.5ea8dd2e07097p-1,-0x1.cc69aec8c4464p-2
+IEEEremainder,0x1.aaf1453f17caap-2,-0x1.f02e901b9f26bp-1,-0x1.62d3995d9586p0
+IEEEremainder,-0x1.d2cbf13d5e3b4p-5,-0x1.d2cbf13d5e3b4p-5,0x1.70bb139c7f2ap4
+IEEEremainder,-0x1.bf89e288347p-7,-0x1.be1730e6eca82p1,0x1.bc57a7046473bp-2
+IEEEremainder,-0x1.0a6e862d907c4p0,-0x1.0a6e862d907c4p0,0x1.0c0fce2bc8d9ep1
+IEEEremainder,0x1.17f13c338e8f7p-2,0x1.17f13c338e8f7p-2,0x1.4cb7fd951aa3dp-1
+IEEEremainder,0x1.0143242f852b4p-4,0x1.645d7495bfbbdp-2,0x1.240cab89de71p-2
+IEEEremainder,0x1.1f47bbb3ba59p-3,-0x1.421ca57f8ccddp0,-0x1.66059cf60418fp-1
+IEEEremainder,0x1.76bb632d282c8p-2,0x1.dc64de3e6b886p1,-0x1.ad8d71d8c682dp1
+IEEEremainder,0x1.2647c10751ccp-6,-0x1.e3221751eabf1p0,0x1.e7bb365608064p-3
+IEEEremainder,-0x1.60376893d0838p-3,0x1.06eab1e883e1cp5,0x1.bd1fd9cbf203dp-2
+IEEEremainder,0x1.1a53f04d90e4cp-3,-0x1.2ddbaaae6a3fap-2,-0x1.bb05a2d532b2p-2
+IEEEremainder,0x1.548d3c188c51p-2,0x1.acbf9b5e7fe7ap0,0x1.579c4c585cd36p0
+IEEEremainder,-0x1.3839ceab3512p-4,0x1.a17de66dfd29bp1,-0x1.1cd5234239e18p-1
+IEEEremainder,0x1.dfb6af012bebep-1,0x1.dfb6af012bebep-1,0x1.23b777febfe1p3
+IEEEremainder,0x1.77027d1100f14p-1,-0x1.7fe4f5b4b64eep0,0x1.1db31a1e9b63cp1
+IEEEremainder,-0x1.ebb1ba9524da5p-4,-0x1.ebb1ba9524da5p-4,-0x1.8519f63a6904fp-1
+IEEEremainder,-0x1.708245d14a8b9p-1,-0x1.708245d14a8b9p-1,0x1.e8ec7cb7029b7p1
+IEEEremainder,-0x1.b532570494bdp-4,0x1.93d754a1d81d4p0,-0x1.af2a7a1221691p-2
+IEEEremainder,-0x1.270f63114a4e4p0,0x1.bc5a725b4cc0cp0,-0x1.71b4eab64b878p1
+IEEEremainder,-0x1.3813e4e6125c4p-2,-0x1.3813e4e6125c4p-2,0x1.6934bcf3ca13bp0
+IEEEremainder,0x1.3372b6c66f77ap-2,-0x1.bf1925b89cc6p0,-0x1.5d4e8cf17b17fp-1
+IEEEremainder,0x1.1414a3adb4c8p-1,0x1.1414a3adb4c8p-1,0x1.bcd487b099ff8p0
+IEEEremainder,-0x1.354e616b029b5p0,-0x1.354e616b029b5p0,0x1.2987b0d2c1c6ap4
+IEEEremainder,-0x1.07bd37471195dp-5,-0x1.07bd37471195dp-5,-0x1.3c87767dbe507p1
+IEEEremainder,-0x1.e3718da73d2cp-6,-0x1.9bf3f2267ec33p0,0x1.94662befe1ce8p-1
+IEEEremainder,0x1.4c2195d13e1ep-6,-0x1.44b69a320cb66p0,0x1.b7ded60c6ce92p-2
+IEEEremainder,0x1.038c62b1406b2p-6,-0x1.235df5ff05e7ap1,0x1.fb7e5ebb842a5p-5
+IEEEremainder,-0x1.939ff0dd73098p-2,0x1.6e869ba2dc439p2,0x1.bfb78c37a884cp-1
+IEEEremainder,-0x1.0186124b4bafp-2,0x1.fe393974641eep-2,0x1.7fdfa5dfd7e6fp-1
+IEEEremainder,0x1.1b9967dea8df8p-4,-0x1.82953f59dd2c5p-1,-0x1.a6086c55b2484p-1
+IEEEremainder,-0x1.3a3022dfc5a6ap0,-0x1.3a3022dfc5a6ap0,-0x1.67d0bdb25fc11p1
+IEEEremainder,0x1.131e46b7df6p-6,-0x1.9ba50827a27edp-1,0x1.a43dfa5d6179dp-2
+IEEEremainder,0x1.5e518f746e9ccp-2,0x1.85868ab677113p0,-0x1.2df226d95b6ap0
+IEEEremainder,-0x1.51e44e4fc4adep-2,-0x1.51e44e4fc4adep-2,0x1.8aa9327c3acacp-1
+IEEEremainder,0x1.822409e9132dp-3,-0x1.e4afee99b8ef4p-1,0x1.229c7889fedd4p0
+IEEEremainder,0x1.909d89e1f7307p-1,0x1.909d89e1f7307p-1,-0x1.75fc9f092b3a8p3
+IEEEremainder,0x1.44cda9dc59618p-1,0x1.44cda9dc59618p-1,0x1.2ba91f120e2dcp3
+IEEEremainder,0x1.1fc0ff61f7441p-1,-0x1.285e3caffdc53p-1,0x1.240f9e08fa84ap0
+IEEEremainder,-0x1.a1c7aba6daab9p-1,-0x1.a1c7aba6daab9p-1,-0x1.bc452fec006aep1
+IEEEremainder,-0x1.4035da047fb8p-4,-0x1.b4d8ac411492dp1,-0x1.aad6fd70f0951p-2
+IEEEremainder,0x1.b18fdae37de4p-8,0x1.8542f580f9183p-1,-0x1.762e62b585edp-6
+IEEEremainder,-0x1.1ed76b98f035cp-2,0x1.50a2ec449b72fp0,0x1.9858c72ad7806p-1
+IEEEremainder,0x1.27f544e1eb74dp1,-0x1.ae8037eb76c01p1,0x1.6b3abe66b11a7p2
+IEEEremainder,0x1.556c2751e3bfp-4,0x1.cfac7c5e66f14p0,0x1.ba55b9e948b55p-1
+IEEEremainder,0x1.939b8787f8a0cp-1,-0x1.a8442e2d22de2p-1,0x1.9defdada8dbf7p0
+IEEEremainder,0x1.2c877e8dcd8ep-4,-0x1.9bc975650ef5bp-1,-0x1.c15a6536c8a77p-2
+IEEEremainder,-0x1.2251737ff9d98p-3,-0x1.65b6be6482d5ep5,0x1.d1bca3305753ap-1
+IEEEremainder,0x1.ddb56687b4393p-5,0x1.ddb56687b4393p-5,0x1.72298db54d895p-3
+IEEEremainder,0x1.8ae6bfe8a9fdp-3,-0x1.417eacb67439ep0,-0x1.72db84b389798p-1
+IEEEremainder,0x1.e5e97b41c94bp-2,-0x1.8599a94908bd3p0,0x1.ff1408197b0ffp0
+IEEEremainder,0x1.bc8222d2d3c4p-5,0x1.6b90c5493d89cp0,0x1.5dacb432a6ebap0
+IEEEremainder,0x1.3cbcc2fea741p-4,-0x1.908c2172b4a34p-1,-0x1.b823b9d2898b6p-1
+IEEEremainder,0x1.069d3d55bdfa6p0,-0x1.a3b4f3d523d38p2,0x1.4392d771b78c1p1
+IEEEremainder,0x1.a717c4f38c853p-5,0x1.a717c4f38c853p-5,-0x1.a9c0eaf5d230ap0
+IEEEremainder,0x1.64d7ff718bba8p-1,0x1.64d7ff718bba8p-1,0x1.27a98dd41fd91p3
+IEEEremainder,-0x1.202706163244cp-1,-0x1.3d777b18721p5,-0x1.72ebb2f6a2b2ep0
+IEEEremainder,0x1.2967f1e7aeef8p-2,0x1.9af9a33b2fdccp0,0x1.509fa6c14420ep0
+IEEEremainder,-0x1.edef5630a84aep-1,-0x1.edef5630a84aep-1,0x1.2e01cbe060fbbp6
+IEEEremainder,-0x1.466c1a8b2e87p-5,0x1.38ce3ba3159f1p-1,0x1.4d34fd4bc8878p-2
+IEEEremainder,-0x1.1b5a021ae8447p-3,-0x1.1b5a021ae8447p-3,0x1.2deee2768e629p8
+IEEEremainder,-0x1.835165b6d5381p2,-0x1.835165b6d5381p2,0x1.72b2d8bc2092dp4
+IEEEremainder,0x1.8e6ba7288b34p-3,0x1.2661ac17c7835p1,0x1.0d7af1a53ed01p0
+IEEEremainder,-0x1.89f86f3ed2696p-1,0x1.3eade66d10b55p0,0x1.01d50f063cf5p1
+IEEEremainder,-0x1.13813e6f99302p-2,0x1.7e26c6bb96e0fp0,-0x1.2caf643a53735p-1
+IEEEremainder,-0x1.4e5482593a22p-1,0x1.0ecbcfc05249dp0,-0x1.b5f610ecef5adp0
+IEEEremainder,-0x1.8a4fb71feaebep-4,0x1.0b594e5f6c4dcp2,-0x1.a0c6ef9843023p-3
+IEEEremainder,-0x1.d39e274325d28p-2,0x1.47a1933a4a8a6p3,-0x1.c8535b45da4bfp0
+IEEEremainder,-0x1.83130de2f670ap-4,-0x1.83130de2f670ap-4,0x1.3c89aa3c489edp-2
+IEEEremainder,-0x1.c89c4903975d8p-3,0x1.a86a46eb2d8acp0,0x1.40fe8ab26af9ap-1
+IEEEremainder,0x1.4ac369a655b8ap-1,0x1.4ac369a655b8ap-1,-0x1.6d6526e38cecp0
+IEEEremainder,0x1.5227707fdb7ap-2,0x1.6a725355f68c1p2,0x1.554fdc4df8d47p-1
+IEEEremainder,0x1.3fd82958212dp-4,-0x1.541fb6d735eaep0,-0x1.681d396cb7fdbp-2
+IEEEremainder,-0x1.f4326fce678dfp-2,-0x1.f4326fce678dfp-2,-0x1.6f861c35a4158p0
+IEEEremainder,-0x1.89edf6bf8f46p-4,0x1.3f80a8f4e298dp5,-0x1.559f9988cf55dp-2
+IEEEremainder,-0x1.4800ae86e9d7dp0,-0x1.4800ae86e9d7dp0,0x1.ef985af4ec19dp2
+max,0x1.715eda6ab8562p2,-0x1.123d877d62ecbp2,0x1.715eda6ab8562p2
+max,0x1.6bf99eae2daf1p-1,0x1.04a084b48941ap-5,0x1.6bf99eae2daf1p-1
+max,0x1.71d3162e989e1p-2,-0x1.217c07c022339p1,0x1.71d3162e989e1p-2
+max,0x1.037880e10da75p0,0x1.5ca0113354b34p-2,0x1.037880e10da75p0
+max,-0x1.16982379a6ff7p-6,-0x1.4b06ec133eb96p-1,-0x1.16982379a6ff7p-6
+max,0x1.ec44f0f2f90acp-1,-0x1.34ea1e1f5a4e9p0,0x1.ec44f0f2f90acp-1
+max,0x1.9f4c3f68431f6p0,-0x1.01a6366c18264p1,0x1.9f4c3f68431f6p0
+max,0x1.30c55ff162bb6p4,0x1.30c55ff162bb6p4,0x1.3a5a028db64d5p2
+max,0x1.bf9b42ac4f87fp-1,-0x1.8a3e408bc21dbp1,0x1.bf9b42ac4f87fp-1
+max,0x1.f6c2140945b18p0,0x1.f6c2140945b18p0,0x1.bd6a19029eb1fp0
+max,0x1.361fe90d27d6cp0,-0x1.eb5bd9156282dp1,0x1.361fe90d27d6cp0
+max,-0x1.3a7b369b89b3fp-3,-0x1.c1423acc0c629p-3,-0x1.3a7b369b89b3fp-3
+max,0x1.d27991c908bf4p0,0x1.c36246cf7bc62p-2,0x1.d27991c908bf4p0
+max,-0x1.2fa756615e776p-1,-0x1.2ec76e5f00cb2p1,-0x1.2fa756615e776p-1
+max,-0x1.584cbd3d68345p-2,-0x1.584cbd3d68345p-2,-0x1.0da698ff2189fp0
+max,0x1.0c1cb0a904868p0,0x1.86872e85fffa9p-1,0x1.0c1cb0a904868p0
+max,0x1.0670c61480ba2p-1,-0x1.3bc0af2977443p-1,0x1.0670c61480ba2p-1
+max,0x1.2df485b8c1266p0,-0x1.a256078c47936p-1,0x1.2df485b8c1266p0
+max,-0x1.f38f820ff6615p-2,-0x1.01a1f7668b30ep1,-0x1.f38f820ff6615p-2
+max,-0x1.607caf8f08634p-3,-0x1.607caf8f08634p-3,-0x1.bd9ff189e6452p-1
+max,-0x1.b3584f460ebp-1,-0x1.d0e68946f28eep1,-0x1.b3584f460ebp-1
+max,-0x1.f97bf5141db1cp-3,-0x1.f97bf5141db1cp-3,-0x1.6db0a4b285f5cp3
+max,0x1.8ee8bddeb6d5ap-1,-0x1.93a1a1f3bd04ep0,0x1.8ee8bddeb6d5ap-1
+max,0x1.2728b6cd3c3d6p1,0x1.2728b6cd3c3d6p1,0x1.136773166616cp-2
+max,-0x1.eabb7b627b94p-3,-0x1.83bc983ee0ee9p-1,-0x1.eabb7b627b94p-3
+max,-0x1.38bea79bd28ffp-1,-0x1.38bea79bd28ffp-1,-0x1.0de83a1879db6p0
+max,-0x1.951d35a1da33dp-2,-0x1.951d35a1da33dp-2,-0x1.4abcb196e114ap-1
+max,0x1.0c6b8df400fe2p3,0x1.e47b3f44f389ap0,0x1.0c6b8df400fe2p3
+max,-0x1.83e508272f9c9p-1,-0x1.c1fa7b1d558a9p2,-0x1.83e508272f9c9p-1
+max,-0x1.b8135fe636e83p-1,-0x1.b8135fe636e83p-1,-0x1.0f39893694473p0
+max,0x1.24d75898c990bp-2,0x1.24d75898c990bp-2,-0x1.7004d30c2bf16p-1
+max,-0x1.ebbe591280802p0,-0x1.ebbe591280802p0,-0x1.8f7b657584d81p1
+max,-0x1.5e836be36ab5ap-3,-0x1.5e836be36ab5ap-3,-0x1.2e83e0ec4b20cp0
+max,0x1.84e6de8132685p-1,0x1.84e6de8132685p-1,-0x1.79f0d4fcacc49p-1
+max,0x1.818ace8d1e8adp0,0x1.c32c0459a4543p-1,0x1.818ace8d1e8adp0
+max,0x1.5ce7f477b5eebp-1,0x1.ec114bb26ae73p-2,0x1.5ce7f477b5eebp-1
+max,-0x1.069211abc123dp0,-0x1.9a15177bbfc47p0,-0x1.069211abc123dp0
+max,0x1.4ad52107f7727p-1,0x1.2bb4b116c81dep-1,0x1.4ad52107f7727p-1
+max,0x1.4cc769cfe9596p0,0x1.4cc769cfe9596p0,-0x1.169630d7de745p0
+max,0x1.7345b49b70be8p0,0x1.7345b49b70be8p0,0x1.0517fde42ca7dp0
+max,0x1.c4f4c38294774p0,0x1.4acb03f65488ap-5,0x1.c4f4c38294774p0
+max,0x1.4d16731fd3b9bp1,-0x1.e69f72e796907p-2,0x1.4d16731fd3b9bp1
+max,-0x1.454ece2014dc9p-1,-0x1.d552258c9a76ep-1,-0x1.454ece2014dc9p-1
+max,0x1.6fd73ebf324fp-2,-0x1.abb9930e9d057p-5,0x1.6fd73ebf324fp-2
+max,0x1.48a204ec37209p0,0x1.48a204ec37209p0,0x1.7d7fd6725396bp-1
+max,0x1.481e1a898f8d4p0,0x1.481e1a898f8d4p0,0x1.9cd901c3a1706p-1
+max,0x1.25cda40ee14ccp-3,-0x1.5c4cfc7b02eaep1,0x1.25cda40ee14ccp-3
+max,0x1.066d62f2bb4c1p0,0x1.066d62f2bb4c1p0,-0x1.a16b49a62fcfep-2
+max,0x1.301bff1794761p1,0x1.301bff1794761p1,-0x1.4815e57b7ec39p1
+max,-0x1.50844bd0c2fe1p0,-0x1.50844bd0c2fe1p0,-0x1.0f44240c9a3eap4
+max,0x1.f775724f9ed8dp0,0x1.f9f83c6009199p-3,0x1.f775724f9ed8dp0
+max,0x1.cfe7908fa475cp3,-0x1.4e5b60ae25edcp1,0x1.cfe7908fa475cp3
+max,0x1.2fbd00c704c43p-1,0x1.14b855d469e2bp-1,0x1.2fbd00c704c43p-1
+max,0x1.23466b685575bp2,0x1.a846a5c2b602cp-1,0x1.23466b685575bp2
+max,-0x1.0e0421fe943dbp1,-0x1.444d05ceb82d9p2,-0x1.0e0421fe943dbp1
+max,-0x1.d7bf6d0f640e6p-3,-0x1.d7bf6d0f640e6p-3,-0x1.93d6d88b65475p-2
+max,0x1.2c2a52842bcaep0,0x1.2c2a52842bcaep0,-0x1.3a47ff2c86de4p0
+max,0x1.937cf65a16ef7p4,0x1.a92448b787444p2,0x1.937cf65a16ef7p4
+max,0x1.708da1a5f1218p8,0x1.708da1a5f1218p8,0x1.34fafae05fb8ap-1
+max,0x1.a25f647876149p0,0x1.a25f647876149p0,0x1.6be965de57989p-4
+max,0x1.969fa2309498fp0,0x1.7b1f02d845448p-1,0x1.969fa2309498fp0
+max,0x1.4074059f5f18fp-3,0x1.4074059f5f18fp-3,-0x1.e3237282cb7ecp0
+max,0x1.9c01ebf07555fp1,0x1.fbd34ac0f39b7p-1,0x1.9c01ebf07555fp1
+max,0x1.90c7632923b73p-2,0x1.90c7632923b73p-2,-0x1.8152574bb0256p-1
+max,-0x1.841b121c3df5ap0,-0x1.841b121c3df5ap0,-0x1.5a0bc05bda8bp1
+max,-0x1.6cb075dcc54b8p-3,-0x1.a5dd9922cb9c1p0,-0x1.6cb075dcc54b8p-3
+max,0x1.a2494106a27f9p-1,0x1.a2494106a27f9p-1,-0x1.2b605d792e652p-1
+max,0x1.b13301e8f9cc5p1,0x1.b13301e8f9cc5p1,-0x1.3f3e72b6d33b4p0
+max,0x1.0bdc0c6797ebcp0,0x1.0bdc0c6797ebcp0,-0x1.08b82c1e635efp0
+max,0x1.245c222ba2cc1p0,0x1.644982935e712p-1,0x1.245c222ba2cc1p0
+max,0x1.52fb4ada5ee08p0,-0x1.05d3d956fa82ap4,0x1.52fb4ada5ee08p0
+max,-0x1.488ad710699ebp0,-0x1.488ad710699ebp0,-0x1.033b00e6a52e4p2
+max,0x1.e0d08b88b0fefp-1,0x1.e0d08b88b0fefp-1,-0x1.d324ede2c9a2dp-1
+max,0x1.c1f03b5c16e5fp-1,-0x1.02593399b1ba9p1,0x1.c1f03b5c16e5fp-1
+max,-0x1.b27fab5b5f889p-6,-0x1.b27fab5b5f889p-6,-0x1.4e834b39a50adp-2
+max,-0x1.22f533bcce775p-1,-0x1.22f533bcce775p-1,-0x1.6d68dc73dde4ap3
+max,0x1.da40eff1835b9p-3,0x1.da40eff1835b9p-3,-0x1.1eae7dfffe30bp2
+max,0x1.0e8be2988575dp-2,-0x1.59b27bbd180fap-2,0x1.0e8be2988575dp-2
+max,-0x1.0976afc0a9856p-3,-0x1.32a346caf9a8ep5,-0x1.0976afc0a9856p-3
+max,0x1.f24f3a1dca83p1,-0x1.1131e584a301ep-9,0x1.f24f3a1dca83p1
+max,0x1.9de4a5bce44bp-3,0x1.9de4a5bce44bp-3,-0x1.91cbaecf6868ep-2
+max,0x1.4c8c2b604cc7ap-1,0x1.4c8c2b604cc7ap-1,-0x1.25d9225df065bp-2
+max,0x1.f3993ce1d34d7p-4,-0x1.828ccd9d93983p2,0x1.f3993ce1d34d7p-4
+max,0x1.811a9846af52p-1,0x1.811a9846af52p-1,0x1.2a940e0025e4bp-3
+max,0x1.03276c4c1edf8p2,0x1.03276c4c1edf8p2,0x1.00fab79405848p-4
+max,-0x1.4223e3c3fcc54p-2,-0x1.4223e3c3fcc54p-2,-0x1.b34bd3516cf55p-2
+max,0x1.a7dc019ee8b93p-1,0x1.0c101e188a668p-3,0x1.a7dc019ee8b93p-1
+max,0x1.6b73c740b2a91p1,0x1.6b73c740b2a91p1,-0x1.5c10a67c1a282p-3
+max,-0x1.c0c1f9d834eeap-1,-0x1.c0c1f9d834eeap-1,-0x1.ec07432e06953p-1
+max,-0x1.eebed0cb2df88p-1,-0x1.eebed0cb2df88p-1,-0x1.1184b287779a4p0
+max,0x1.b7efe44adf4c4p0,-0x1.5a74dc1b5f887p0,0x1.b7efe44adf4c4p0
+max,0x1.323224efdc45ep-2,-0x1.8603e2a67a9ebp-2,0x1.323224efdc45ep-2
+max,0x1.49adbf589f7cdp-2,0x1.49adbf589f7cdp-2,-0x1.7e1ede8b0dcf1p0
+max,0x1.feadf76e213c5p-2,-0x1.38424eaa9f7d7p-1,0x1.feadf76e213c5p-2
+max,0x1.169084b55ce96p0,0x1.169084b55ce96p0,0x1.00dd40de863e5p0
+max,-0x1.3bd29ad82ab5fp-1,-0x1.ddb7032b6ec4ep3,-0x1.3bd29ad82ab5fp-1
+max,0x1.a4b7216b2e697p-1,0x1.0e69e57c45876p-1,0x1.a4b7216b2e697p-1
+max,0x1.42b704013ef84p0,-0x1.9871fcfe384eep-1,0x1.42b704013ef84p0
+max,0x1.375f4517cc0f8p-2,0x1.375f4517cc0f8p-2,-0x1.104d97045573fp0
+max,0x1.dcae4475307ccp-1,0x1.6d0a9164169e2p-3,0x1.dcae4475307ccp-1
+max,-0x1.f19b81b13d60fp-1,-0x1.f19b81b13d60fp-1,-0x1.12d9ae07eb3e6p0
+max,0x1.9b5c6c0054a45p0,-0x1.8b39de59fe01ap2,0x1.9b5c6c0054a45p0
+max,0x1.a14d6b9b7b3e6p-5,0x1.a14d6b9b7b3e6p-5,0x1.033cd886eed37p-5
+max,-0x1.c16334a678feap-1,-0x1.c16334a678feap-1,-0x1.21eb26cd790ddp0
+max,-0x1.77317877b98eap0,-0x1.1230ac4fdeaefp1,-0x1.77317877b98eap0
+max,0x1.53daa2336cc14p6,0x1.ae5c124ff767dp-1,0x1.53daa2336cc14p6
+max,0x1.508ec20cff9c8p3,0x1.508ec20cff9c8p3,-0x1.ca02307be68b8p1
+max,0x1.2f38cee16d234p1,-0x1.154fba07bd232p0,0x1.2f38cee16d234p1
+max,0x1.91d1d90fe15e1p0,-0x1.836bbbddcf13bp0,0x1.91d1d90fe15e1p0
+max,-0x1.fa036659caf6bp-1,-0x1.fa036659caf6bp-1,-0x1.9bc1460fe4d16p0
+max,0x1.3174b9a6a4a0cp0,0x1.3174b9a6a4a0cp0,-0x1.b5665b6332761p-1
+max,-0x1.11fa1ba53bea8p-4,-0x1.11fa1ba53bea8p-4,-0x1.b409525077441p-2
+max,0x1.36487ea0ca3f4p-1,-0x1.6d228f1905fap-1,0x1.36487ea0ca3f4p-1
+max,0x1.394210da3385ap1,0x1.6784e31973bbfp-1,0x1.394210da3385ap1
+max,0x1.d493b91366591p1,0x1.d493b91366591p1,0x1.1854337bb9aa5p-1
+max,0x1.a16d26d4804fep1,0x1.46098dafdf442p-4,0x1.a16d26d4804fep1
+max,0x1.ad5bebfca748fp2,-0x1.08911ef2e9a3dp0,0x1.ad5bebfca748fp2
+max,0x1.d937b7c5283edp-3,0x1.3ae867da6c443p-3,0x1.d937b7c5283edp-3
+max,0x1.3d711a6e2853fp0,0x1.3d711a6e2853fp0,-0x1.4e308f2d90dap-2
+max,0x1.35c41375b8715p1,0x1.02661c271b354p1,0x1.35c41375b8715p1
+max,-0x1.181f3885ccaabp-5,-0x1.847a53004ca9fp-1,-0x1.181f3885ccaabp-5
+max,0x1.bce610feea79cp3,0x1.b68d06485e079p0,0x1.bce610feea79cp3
+max,0x1.05a4b8c49b9c6p2,0x1.05a4b8c49b9c6p2,0x1.23e045b36cf71p-1
+max,0x1.23c70a9355ee2p6,-0x1.be2c987cc3f46p-2,0x1.23c70a9355ee2p6
+max,0x1.6aa2ccce0ee2p-1,0x1.1c6b6c3be7217p-1,0x1.6aa2ccce0ee2p-1
+max,0x1.47b5a27f88cd4p0,-0x1.ba7f7c40d48bap-1,0x1.47b5a27f88cd4p0
+max,0x1.1ffc51da30594p4,0x1.1ffc51da30594p4,-0x1.a99227ca9ec4dp-4
+max,0x1.f350685643306p4,0x1.f350685643306p4,-0x1.1ce3ee03d9515p2
+max,0x1.164ba7603719p-2,0x1.439bd3af0c60cp-5,0x1.164ba7603719p-2
+max,-0x1.0c5c4e2fa7943p-1,-0x1.0c5c4e2fa7943p-1,-0x1.685ba9ed1cd17p1
+max,-0x1.60bf854ce3c4dp-5,-0x1.2ef2aa9007428p0,-0x1.60bf854ce3c4dp-5
+max,0x1.cee376c29a96p-1,0x1.cee376c29a96p-1,-0x1.9654482c44979p-1
+max,-0x1.1caeeb891affdp1,-0x1.cb3ebdd8be3f5p1,-0x1.1caeeb891affdp1
+max,0x1.174344e5e0291p3,0x1.174344e5e0291p3,0x1.a6f7bfffd3397p-1
+max,-0x1.325ede26966aep-2,-0x1.9e6840eb53a02p0,-0x1.325ede26966aep-2
+max,0x1.e87e0753cc668p0,0x1.4dcd0a4107d63p-2,0x1.e87e0753cc668p0
+max,0x1.f450bb8dc737p-3,-0x1.884d05667a039p-2,0x1.f450bb8dc737p-3
+max,0x1.79db0a88a6178p-5,-0x1.b779584a48313p-2,0x1.79db0a88a6178p-5
+max,0x1.627d2bd7d0c3p-1,0x1.627d2bd7d0c3p-1,-0x1.5d3cc03d1c5dp-2
+max,-0x1.6e681a570701dp-1,-0x1.321834c90d23ep0,-0x1.6e681a570701dp-1
+max,-0x1.03f4bfa45cb81p1,-0x1.68648b4580fccp4,-0x1.03f4bfa45cb81p1
+max,-0x1.a5a2883f67b46p-4,-0x1.617687be3ec66p-2,-0x1.a5a2883f67b46p-4
+max,0x1.23efdf13fb84ap0,0x1.ab50f49f951aep-1,0x1.23efdf13fb84ap0
+max,0x1.b78f97655b26fp-1,0x1.b78f97655b26fp-1,0x1.1c7a04b4e9c28p-1
+max,0x1.4a3e497c49471p0,0x1.6548680dd16d5p-2,0x1.4a3e497c49471p0
+max,-0x1.dd070798cfdb3p0,-0x1.dd070798cfdb3p0,-0x1.03ee413663952p5
+max,0x1.300b8893f13f6p0,-0x1.0330898a2cc48p1,0x1.300b8893f13f6p0
+max,0x1.0ab1704aee3d6p0,0x1.b4bd912f7d76ep-5,0x1.0ab1704aee3d6p0
+max,-0x1.1b8dc0def141ap-1,-0x1.745059407937cp1,-0x1.1b8dc0def141ap-1
+max,0x1.87de0f34c2334p-2,0x1.87de0f34c2334p-2,-0x1.14bbf7bcc0a22p1
+max,0x1.5cfe604aa0362p-4,0x1.5cfe604aa0362p-4,-0x1.19824c8deb282p0
+max,0x1.817696d8ca183p-3,-0x1.3eb71189b4143p-1,0x1.817696d8ca183p-3
+max,0x1.66f42e69b47d7p-1,0x1.66f42e69b47d7p-1,-0x1.d449b1f44e633p0
+max,0x1.b92e7b3d72f42p1,0x1.0e56c2680ae1ap-2,0x1.b92e7b3d72f42p1
+max,0x1.7884f26864993p-1,-0x1.07ce3589c58f3p0,0x1.7884f26864993p-1
+max,-0x1.a8e4d58a575e4p-2,-0x1.a8e4d58a575e4p-2,-0x1.52b57140d661cp-1
+max,0x1.074337293b9dap1,0x1.074337293b9dap1,0x1.0d1f59d7b33d2p0
+max,0x1.b030a230348f5p-1,0x1.b030a230348f5p-1,-0x1.1ea0d9f821ddcp1
+max,-0x1.086488fa12f92p0,-0x1.b9fb23d610031p0,-0x1.086488fa12f92p0
+max,-0x1.5f4dd1578a099p-3,-0x1.5f4dd1578a099p-3,-0x1.a7081c64b4c25p-2
+max,-0x1.1fc6aa5158e82p-2,-0x1.1fc6aa5158e82p-2,-0x1.5392d0c9f5f0ep0
+max,0x1.44d25fe19310bp-1,0x1.44d25fe19310bp-1,0x1.6937b399c0539p-4
+max,0x1.417bad30a66f2p-1,-0x1.eb6772df6580ap0,0x1.417bad30a66f2p-1
+max,0x1.abb329087d29p-3,0x1.abb329087d29p-3,0x1.395b340a208b1p-3
+max,0x1.5374167cdb884p1,0x1.5374167cdb884p1,-0x1.b02196e1ff943p3
+max,0x1.56d6c27e9a1fp0,0x1.e505c8e2c4f68p-2,0x1.56d6c27e9a1fp0
+max,0x1.0c078dba2e9b6p4,0x1.0c078dba2e9b6p4,-0x1.6231dba32a3c8p-2
+max,-0x1.9b4d30df0f9e9p0,-0x1.34e1cb729841dp2,-0x1.9b4d30df0f9e9p0
+max,0x1.21ff139342d29p0,-0x1.56d9f8f4d560ep2,0x1.21ff139342d29p0
+max,-0x1.09729d33fdad6p0,-0x1.a1ac1648c825p1,-0x1.09729d33fdad6p0
+max,0x1.6e1aeba8be2e1p2,-0x1.07f074add9e8cp1,0x1.6e1aeba8be2e1p2
+max,0x1.a474ba1acb868p-1,0x1.a474ba1acb868p-1,-0x1.07813c5159cb8p0
+max,0x1.46456ec6f64b7p-4,0x1.46456ec6f64b7p-4,-0x1.f81c22ba6fd27p3
+max,-0x1.a90402ec8c761p-1,-0x1.a90402ec8c761p-1,-0x1.30989e3693c89p3
+max,0x1.19ebb41478199p0,0x1.19ebb41478199p0,0x1.168cc73044492p0
+max,0x1.f89e84c96dc67p0,0x1.f89e84c96dc67p0,0x1.1728a3644e497p-2
+max,0x1.cce3b436bec31p1,0x1.cce3b436bec31p1,-0x1.b6ea28bd83144p-1
+max,0x1.09c94ad4a514fp-1,0x1.09c94ad4a514fp-1,-0x1.b6a6a20dd7c58p-2
+max,0x1.04f2c8d7f6f81p-3,0x1.04f2c8d7f6f81p-3,-0x1.1dca4777e34edp0
+max,0x1.0e51e5bae1b4fp3,-0x1.eedd537f6ff89p-2,0x1.0e51e5bae1b4fp3
+max,-0x1.01be92a228736p0,-0x1.1b163fbe40b0ap0,-0x1.01be92a228736p0
+max,0x1.3209d6c43fef1p0,0x1.3209d6c43fef1p0,-0x1.3b26a1e0fb67dp0
+max,-0x1.ca4fd4ce38496p0,-0x1.82f541d1d82ap6,-0x1.ca4fd4ce38496p0
+max,0x1.21463a760ffe5p-2,-0x1.ea66ae1526363p-1,0x1.21463a760ffe5p-2
+max,0x1.5abae34817b0dp-1,0x1.5abae34817b0dp-1,0x1.ad6480acff31bp-4
+max,0x1.197568e5da05p0,0x1.6be9f832a5009p-1,0x1.197568e5da05p0
+max,-0x1.31cdc26bee4dap-2,-0x1.31cdc26bee4dap-2,-0x1.c97651d6a2bb1p-2
+max,0x1.de296ad50534fp-3,-0x1.d7d84b8df6dc8p2,0x1.de296ad50534fp-3
+max,0x1.a138e38ed9c27p-1,0x1.a138e38ed9c27p-1,-0x1.a461a761a5258p-5
+max,0x1.33fa6b58ddf8ep2,0x1.33fa6b58ddf8ep2,-0x1.4bd861119b025p0
+max,-0x1.0bcc00461b547p1,-0x1.50643ab09ebecp1,-0x1.0bcc00461b547p1
+max,0x1.a5405570b9037p1,-0x1.2c220c5318d9bp0,0x1.a5405570b9037p1
+max,0x1.0ab97b7b68f01p1,0x1.0ab97b7b68f01p1,-0x1.50348eb28878bp0
+max,0x1.eebcd506d7814p0,0x1.eebcd506d7814p0,-0x1.e3279f6a1fdc4p-2
+max,0x1.cbc718a2e8753p0,0x1.0b2651a6c4e51p0,0x1.cbc718a2e8753p0
+max,0x1.af34db6a803bp-2,0x1.af34db6a803bp-2,-0x1.364e5e5cce93p0
+max,0x1.d07715682f3e9p-2,0x1.be703a2ad1a97p-2,0x1.d07715682f3e9p-2
+max,-0x1.0f68a842c56edp4,-0x1.0f68a842c56edp4,-0x1.1f458b97e53d4p14
+max,-0x1.bb28456fa0b39p-1,-0x1.150b185442475p2,-0x1.bb28456fa0b39p-1
+max,0x1.ddb257fcd3ef2p-4,-0x1.e468c0dddb3a4p0,0x1.ddb257fcd3ef2p-4
+min,-0x1.13a94916c6632p1,0x1.ac23ebf48ab15p-1,-0x1.13a94916c6632p1
+min,0x1.2d7766f5c9b61p0,0x1.2d7766f5c9b61p0,0x1.59be058e00538p0
+min,0x1.fe34c9c10228dp-2,0x1.0c09f682d7678p3,0x1.fe34c9c10228dp-2
+min,-0x1.ce89c50cf4192p-1,0x1.3491274e10f1ep-1,-0x1.ce89c50cf4192p-1
+min,-0x1.4981407ee7abep3,-0x1.32fa1d18254cbp2,-0x1.4981407ee7abep3
+min,-0x1.3e13233971719p0,-0x1.3e13233971719p0,0x1.4239cce7fed1ap0
+min,-0x1.b93ae6945c66cp-2,-0x1.b93ae6945c66cp-2,0x1.4e41c5625209ap2
+min,-0x1.bae87769f9bc5p-4,0x1.1cfccaf510c3dp1,-0x1.bae87769f9bc5p-4
+min,-0x1.4513fe72d84fcp-1,-0x1.2204a6b91c706p-2,-0x1.4513fe72d84fcp-1
+min,-0x1.7d39541b56792p-1,-0x1.7d39541b56792p-1,0x1.9e00ae836a6d8p-4
+min,0x1.fcec31bd378f2p-4,0x1.cbcbe0818db38p-1,0x1.fcec31bd378f2p-4
+min,-0x1.074fee289c7a2p-1,-0x1.074fee289c7a2p-1,-0x1.3709c74314ba2p-2
+min,0x1.509aa2555639dp-2,0x1.7ac8e766b2394p-1,0x1.509aa2555639dp-2
+min,-0x1.b04a57efa1058p4,-0x1.b04a57efa1058p4,-0x1.8a85df2ddf534p-3
+min,-0x1.ca5a826213c65p0,-0x1.adfd7e008374ap0,-0x1.ca5a826213c65p0
+min,-0x1.3d06c467df783p0,0x1.b3362c98633e6p-3,-0x1.3d06c467df783p0
+min,-0x1.9cc47a7ba3095p-3,0x1.9d58995951072p2,-0x1.9cc47a7ba3095p-3
+min,0x1.86c86459dcf24p-1,0x1.86c86459dcf24p-1,0x1.b629984e3e5cep1
+min,0x1.61b79fa5440edp-1,0x1.f0b0816f2d328p1,0x1.61b79fa5440edp-1
+min,-0x1.de5e4512ed9afp-2,-0x1.de5e4512ed9afp-2,-0x1.594a6949300bfp-3
+min,-0x1.50b9c30194096p0,0x1.16d29d92eda58p1,-0x1.50b9c30194096p0
+min,0x1.dbdd3fd40e2c8p-1,0x1.dbdd3fd40e2c8p-1,0x1.03caf44b9ff2bp3
+min,0x1.6bfe7dedc912p2,0x1.6bfe7dedc912p2,0x1.c0c15315feae2p11
+min,-0x1.42f6f8eb41752p1,-0x1.82a5d68d432f7p-1,-0x1.42f6f8eb41752p1
+min,-0x1.3af239c2fc405p1,0x1.e184a195ab379p-2,-0x1.3af239c2fc405p1
+min,-0x1.26818ff4a5f7cp0,-0x1.095d94f089fcep0,-0x1.26818ff4a5f7cp0
+min,-0x1.bb0050d3325f6p-2,-0x1.521fc1c60961ep-3,-0x1.bb0050d3325f6p-2
+min,-0x1.2b9268bb58f28p-1,0x1.d90661b86086dp-3,-0x1.2b9268bb58f28p-1
+min,-0x1.24ee803b1efa2p1,0x1.71b5596e0ed89p-1,-0x1.24ee803b1efa2p1
+min,-0x1.b2249746077e9p-1,-0x1.b2249746077e9p-1,0x1.0946a46409006p-3
+min,0x1.0b91b04e6c8e2p0,0x1.0b91b04e6c8e2p0,0x1.27c18403a04f5p0
+min,0x1.27e9a5f752112p-2,0x1.52fc515f8014p-2,0x1.27e9a5f752112p-2
+min,0x1.d500a898f7f24p-1,0x1.d500a898f7f24p-1,0x1.4498cb7af2b64p2
+min,0x1.b8f586841bffcp0,0x1.61c0998390625p1,0x1.b8f586841bffcp0
+min,-0x1.443e68ba0322fp1,0x1.d7890d0ecaee8p3,-0x1.443e68ba0322fp1
+min,0x1.804ac6cecdb39p1,0x1.895ea7c1fcf4fp1,0x1.804ac6cecdb39p1
+min,-0x1.815862f8f6485p1,-0x1.815862f8f6485p1,-0x1.bfe7b047c0cd2p-1
+min,-0x1.19c230e5106cep-4,-0x1.19c230e5106cep-4,0x1.83646939220bap-3
+min,-0x1.33ed0b4cef53ep1,-0x1.bcbe25bbe45a3p-1,-0x1.33ed0b4cef53ep1
+min,-0x1.6edaedc73ac28p-1,-0x1.6edaedc73ac28p-1,0x1.f5ea59a73d2c8p-1
+min,-0x1.8a32540cff257p-1,0x1.d891764b4afc7p0,-0x1.8a32540cff257p-1
+min,0x1.fd551bb1c0d14p-3,0x1.a10e43e8080e7p-2,0x1.fd551bb1c0d14p-3
+min,-0x1.bd5990bc301d7p-5,-0x1.bd5990bc301d7p-5,-0x1.3ad52414fb659p-5
+min,0x1.cc95de78aef8dp-2,0x1.5cda5bd72af8fp0,0x1.cc95de78aef8dp-2
+min,-0x1.a7a2275c32905p-3,0x1.95476aa06da47p1,-0x1.a7a2275c32905p-3
+min,-0x1.4e336ed184b9p1,-0x1.0a824d5327642p0,-0x1.4e336ed184b9p1
+min,0x1.2696241411401p-4,0x1.2696241411401p-4,0x1.9c63dc87aaa93p-2
+min,-0x1.fd70ee2cf166dp1,-0x1.8b5e045b5fdbap-1,-0x1.fd70ee2cf166dp1
+min,0x1.f8c4c8fa2978ap-2,0x1.d9d4d4e4e68fap-1,0x1.f8c4c8fa2978ap-2
+min,-0x1.a0857e256e027p-3,0x1.4b4c644c8e532p4,-0x1.a0857e256e027p-3
+min,-0x1.bd89e6a9ea89p0,-0x1.bd89e6a9ea89p0,-0x1.9636ca86ebaadp-3
+min,-0x1.cffefe8a12e9ep0,0x1.3829a15c0609fp0,-0x1.cffefe8a12e9ep0
+min,-0x1.e80ec3fbd90a2p1,0x1.7a1ed46d8f78ep-2,-0x1.e80ec3fbd90a2p1
+min,0x1.d2c97c3e885aap-1,0x1.6bc43d43e903ep3,0x1.d2c97c3e885aap-1
+min,-0x1.bb71e7c6cab53p-7,-0x1.bb71e7c6cab53p-7,0x1.d8c3440fd7647p-1
+min,-0x1.67046d956ab12p1,-0x1.67046d956ab12p1,0x1.0ca6a127b808bp-3
+min,-0x1.07e98dc39755ep2,-0x1.752531e8e90d2p0,-0x1.07e98dc39755ep2
+min,-0x1.44a6e426d8222p2,0x1.e22481ebfe03bp5,-0x1.44a6e426d8222p2
+min,0x1.e41e3f941ff5ep-1,0x1.6d8025be2dbffp2,0x1.e41e3f941ff5ep-1
+min,-0x1.5446e930c75aap1,-0x1.49da496af8d41p1,-0x1.5446e930c75aap1
+min,0x1.5f38f4ec94713p-2,0x1.5f38f4ec94713p-2,0x1.7a01220226f5fp-2
+min,-0x1.9b4a035c03614p-1,-0x1.6a4d29ecc2fa7p-4,-0x1.9b4a035c03614p-1
+min,0x1.20b4c80b25be9p-1,0x1.dc7c67c9fd726p-1,0x1.20b4c80b25be9p-1
+min,0x1.f22075cdec45cp-5,0x1.7cbbc02f42fb1p-2,0x1.f22075cdec45cp-5
+min,-0x1.3dab3dd2da974p0,-0x1.3dab3dd2da974p0,-0x1.577dbfedb7979p-2
+min,-0x1.008180aa3ad24p1,-0x1.008180aa3ad24p1,-0x1.aa8ca022955dep-1
+min,-0x1.63f7ea987d0adp-4,-0x1.63f7ea987d0adp-4,0x1.d0e077799d2e8p1
+min,-0x1.dde07e80db509p-1,-0x1.dde07e80db509p-1,0x1.db20cf698cfe4p-1
+min,-0x1.ae1b9fe894e52p-2,0x1.6432af4638239p0,-0x1.ae1b9fe894e52p-2
+min,-0x1.9d83a101a86ccp0,-0x1.a653f08061f97p-4,-0x1.9d83a101a86ccp0
+min,0x1.99efea49f1495p-3,0x1.fad7dd51e4117p-1,0x1.99efea49f1495p-3
+min,-0x1.35497388bf3cbp2,-0x1.35497388bf3cbp2,0x1.2baeb4219b47ap-1
+min,0x1.0fadb0fb155c3p-1,0x1.0fadb0fb155c3p-1,0x1.8657d9977d917p0
+min,-0x1.46e4e9b96f9f7p1,-0x1.46e4e9b96f9f7p1,0x1.18aa8945c41ffp0
+min,-0x1.a0fd901352ccap0,-0x1.a0fd901352ccap0,0x1.88c5018a56f78p-5
+min,-0x1.674b8a2044c13p-1,-0x1.674b8a2044c13p-1,-0x1.0de4dda748eeep-1
+min,-0x1.a85f46badbc5cp0,-0x1.a85f46badbc5cp0,-0x1.7261fbfb3c976p-1
+min,-0x1.b9df217db7a2cp-2,0x1.0889c05cd2ecap-1,-0x1.b9df217db7a2cp-2
+min,-0x1.33221e13fc2dbp0,-0x1.6330d5283a276p-2,-0x1.33221e13fc2dbp0
+min,-0x1.88c13d0fb5a22p-2,-0x1.88c13d0fb5a22p-2,0x1.3986eb6becbbp-2
+min,-0x1.5d76c17f9c893p2,-0x1.7aa2aa56413p1,-0x1.5d76c17f9c893p2
+min,-0x1.360be8f735b0dp1,-0x1.b9df1f32ccee4p-3,-0x1.360be8f735b0dp1
+min,-0x1.3772007c0cb03p2,-0x1.3772007c0cb03p2,0x1.d1758810db26dp-4
+min,-0x1.4bd7e063b8ad8p2,-0x1.4bd7e063b8ad8p2,0x1.39a6d6f00bffdp0
+min,0x1.bd9ebd3b18aa4p-6,0x1.bd9ebd3b18aa4p-6,0x1.39d2605c7222ep0
+min,0x1.460bd0bfb9812p-2,0x1.cb61badc0d42ep-2,0x1.460bd0bfb9812p-2
+min,-0x1.1af162c525724p-2,-0x1.1af162c525724p-2,-0x1.09732a07365f2p-2
+min,-0x1.e358d4f069a66p2,-0x1.e358d4f069a66p2,0x1.ba64b7678c87dp4
+min,-0x1.cbf7833006116p0,-0x1.300a6e593b6cp-2,-0x1.cbf7833006116p0
+min,-0x1.20c3eb07baaeap-2,0x1.0a2dab0d9ca46p3,-0x1.20c3eb07baaeap-2
+min,0x1.8b2a647a609b7p-3,0x1.c8624c1a9621dp1,0x1.8b2a647a609b7p-3
+min,-0x1.3b0a1b6d077cdp4,-0x1.3b0a1b6d077cdp4,-0x1.067de6054e823p-1
+min,0x1.073456880db89p-1,0x1.073456880db89p-1,0x1.0f6614b3fe878p1
+min,-0x1.92a1feb2add1p-1,0x1.aa2e925776006p-2,-0x1.92a1feb2add1p-1
+min,-0x1.2d091736427b3p-1,-0x1.2d091736427b3p-1,-0x1.01434fc9abe1fp-1
+min,0x1.8c7b2d04ee95dp-4,0x1.8c7b2d04ee95dp-4,0x1.081d466e3ce4ap0
+min,-0x1.af8113522be2ep0,0x1.b3e4760fe707fp-2,-0x1.af8113522be2ep0
+min,-0x1.763300581d26dp-1,0x1.15a23a4a37ccfp0,-0x1.763300581d26dp-1
+min,-0x1.59565079e018cp-3,-0x1.59565079e018cp-3,0x1.b902426c23202p-3
+min,-0x1.2995e3abc47ddp-1,-0x1.2995e3abc47ddp-1,-0x1.089159215c8c7p-3
+min,0x1.b9ac949a714f4p-3,0x1.288efd4ea3781p1,0x1.b9ac949a714f4p-3
+min,-0x1.1b107e57195ecp0,-0x1.1b107e57195ecp0,0x1.dd5dfc47faebep3
+min,-0x1.891d8dc7f1cf5p0,-0x1.891d8dc7f1cf5p0,0x1.396c3e23a8d67p0
+min,-0x1.6e11956e6e222p2,-0x1.26aa706380677p0,-0x1.6e11956e6e222p2
+min,-0x1.31b28d71015dap-1,-0x1.31b28d71015dap-1,0x1.1fd5d137a4772p-2
+min,-0x1.7fac3d710e52ep0,0x1.893d0c6cfb41dp-1,-0x1.7fac3d710e52ep0
+min,-0x1.290ea7b4320f4p0,-0x1.290ea7b4320f4p0,-0x1.24d9a6462daf6p-3
+min,-0x1.0b73073da946p-1,-0x1.0b73073da946p-1,0x1.e39bf03d1f4afp-2
+min,0x1.7977ae89fa154p-1,0x1.7977ae89fa154p-1,0x1.ec60c74e164c8p-1
+min,0x1.d7aee0c6e6625p-3,0x1.bb8fc43d257d3p2,0x1.d7aee0c6e6625p-3
+min,-0x1.00ab753ab9c6ep0,-0x1.00ab753ab9c6ep0,0x1.fc49a71d17689p-2
+min,-0x1.482cfb8593e2p1,-0x1.482cfb8593e2p1,0x1.29df7c855981dp-2
+min,-0x1.b198b34422c07p-2,0x1.7f835f4bd8af2p-2,-0x1.b198b34422c07p-2
+min,0x1.a42c893fc161ap-1,0x1.a42c893fc161ap-1,0x1.c2173bc38cff3p1
+min,-0x1.f82ca9ee2de92p-2,0x1.02345d34264eap0,-0x1.f82ca9ee2de92p-2
+min,-0x1.2061d589bb4b6p2,-0x1.2061d589bb4b6p2,0x1.e2c0aacc85133p-1
+min,-0x1.2916403a07566p-1,-0x1.2916403a07566p-1,0x1.8470750c4fc3bp0
+min,0x1.e4ff5339ae12ap-1,0x1.1d98ea2485102p0,0x1.e4ff5339ae12ap-1
+min,0x1.dba31dc5ef2c4p-2,0x1.dba31dc5ef2c4p-2,0x1.92996be0e867bp-1
+min,0x1.979e52581bed3p-2,0x1.979e52581bed3p-2,0x1.56b76e856e6abp0
+min,-0x1.1be67a6ba09cdp2,-0x1.1be67a6ba09cdp2,0x1.9da5e6efa4367p-1
+min,-0x1.31cb8169ce6d1p0,-0x1.31cb8169ce6d1p0,0x1.fd8e186d36bfcp-3
+min,-0x1.634cf9402ddcep1,0x1.00473f38f91fap2,-0x1.634cf9402ddcep1
+min,-0x1.f0ae14204a759p2,-0x1.f0ae14204a759p2,0x1.45265bfbf6a3fp3
+min,0x1.8f09f028feaf6p-2,0x1.8f09f028feaf6p-2,0x1.9253fc0fb0c25p-1
+min,-0x1.3cd8d2ab263f1p-1,0x1.77becee8a3f81p0,-0x1.3cd8d2ab263f1p-1
+min,-0x1.3ce7a97163386p-1,-0x1.3ce7a97163386p-1,0x1.4aaadecc0b55p1
+min,-0x1.48e10ed6a0916p-2,-0x1.48e10ed6a0916p-2,0x1.84c5c9b63cd65p0
+min,0x1.2fdf5cb32b13bp-1,0x1.53b0c65709e7ep1,0x1.2fdf5cb32b13bp-1
+min,-0x1.5765b10b1fbc1p-1,0x1.1ade9d6dc4727p0,-0x1.5765b10b1fbc1p-1
+min,-0x1.10ae54518de82p0,-0x1.10ae54518de82p0,-0x1.19089b42bf9e3p-3
+min,0x1.eab67589caa88p-2,0x1.eab67589caa88p-2,0x1.bc68d01d7cbb4p1
+min,0x1.0781058915ba1p-1,0x1.0781058915ba1p-1,0x1.7b9108f9ad7p2
+min,-0x1.158873373f889p-1,0x1.7cd00b4b7869bp1,-0x1.158873373f889p-1
+min,0x1.7c365dec96c43p-2,0x1.7c365dec96c43p-2,0x1.86104c7100905p0
+min,-0x1.82fb00359be92p-2,0x1.b292515ab07a9p2,-0x1.82fb00359be92p-2
+min,-0x1.eaadde36a5e87p0,-0x1.16bce129cd9c8p-1,-0x1.eaadde36a5e87p0
+min,-0x1.008ae7b47fc2fp1,-0x1.c0555a351b89ap-2,-0x1.008ae7b47fc2fp1
+min,-0x1.9d065ed72be6dp1,0x1.1534ff6bbb57p-2,-0x1.9d065ed72be6dp1
+min,0x1.07938b9c6febep1,0x1.2252865eae102p1,0x1.07938b9c6febep1
+min,0x1.838467e24e11ep-3,0x1.838467e24e11ep-3,0x1.09a6301cf209ap0
+min,-0x1.75cd92b765f79p-3,0x1.fcbd7a7e6a031p1,-0x1.75cd92b765f79p-3
+min,-0x1.291c03cea77a4p1,0x1.383becfd3de9cp-2,-0x1.291c03cea77a4p1
+min,-0x1.dded413d25462p-1,-0x1.bc1a66ad220a2p-1,-0x1.dded413d25462p-1
+min,-0x1.c46c3d6f0a42fp-2,0x1.b5a7b9ec5f02fp-1,-0x1.c46c3d6f0a42fp-2
+min,-0x1.579a90bbd54d2p3,-0x1.23e73b0fa51fdp-1,-0x1.579a90bbd54d2p3
+min,-0x1.fff1fc8af0ea8p0,0x1.339b2190df843p0,-0x1.fff1fc8af0ea8p0
+min,-0x1.a15357ed77e9p-3,0x1.aca7e28d1eee6p-1,-0x1.a15357ed77e9p-3
+min,-0x1.86f0707a28e74p1,-0x1.5212591d1b84bp0,-0x1.86f0707a28e74p1
+min,0x1.b7f4f1cc7086dp-1,0x1.b7f4f1cc7086dp-1,0x1.23a5b48fcc793p0
+min,-0x1.4639a5f929423p-3,0x1.3d16734d170f6p0,-0x1.4639a5f929423p-3
+min,-0x1.11552179c7f92p-1,-0x1.11552179c7f92p-1,0x1.a1b4268ed58fbp0
+min,-0x1.42ce24a8a256fp0,-0x1.42ce24a8a256fp0,-0x1.205189643d941p-1
+min,-0x1.e24d0eef7619p1,0x1.fdbb6fec69597p-2,-0x1.e24d0eef7619p1
+min,-0x1.148aead0c530bp5,-0x1.148aead0c530bp5,-0x1.3571cb1c20489p0
+min,-0x1.1efd819f91dbfp-2,-0x1.6cf5c6cd76b48p-3,-0x1.1efd819f91dbfp-2
+min,0x1.4c2aab84a2edbp-1,0x1.3cc62c5b5d4acp1,0x1.4c2aab84a2edbp-1
+min,-0x1.c4bec7964c1dp1,-0x1.c4bec7964c1dp1,-0x1.16585f3a378bcp1
+min,-0x1.e50e295fe6847p-1,-0x1.e50e295fe6847p-1,0x1.16226dfd2aabp0
+min,-0x1.a29e12c602ea1p-6,-0x1.a29e12c602ea1p-6,0x1.0f621347a3362p-5
+min,-0x1.185b0afb229dcp-2,-0x1.185b0afb229dcp-2,0x1.7b94a5681c7c7p-1
+min,-0x1.efd68d4fc0d47p0,-0x1.efd68d4fc0d47p0,-0x1.f7908abf9d8cdp-1
+min,-0x1.3a0267472a46cp2,0x1.2fd06ba2f553p-1,-0x1.3a0267472a46cp2
+min,-0x1.5df3ef4ea824dp-3,-0x1.5df3ef4ea824dp-3,0x1.5a16dd49f65fap0
+min,-0x1.39730602fe424p2,-0x1.56da97ba0787dp-3,-0x1.39730602fe424p2
+min,-0x1.af04c0e061947p0,0x1.e80882cd87a91p-2,-0x1.af04c0e061947p0
+min,-0x1.35cb5a414d308p2,-0x1.cb532bb97b52dp0,-0x1.35cb5a414d308p2
+min,0x1.b5f60b456b70dp-2,0x1.b5f60b456b70dp-2,0x1.82fffd7d5415dp0
+min,0x1.5c8a81e9f07e7p0,0x1.2e731b3b69a8cp1,0x1.5c8a81e9f07e7p0
+min,-0x1.7b0832976dff7p0,-0x1.7b0832976dff7p0,0x1.e364f679bf66bp-4
+min,-0x1.29e86809f4d32p2,0x1.e901e1b270bcfp-1,-0x1.29e86809f4d32p2
+min,-0x1.9c34005f9660dp-2,-0x1.9c34005f9660dp-2,0x1.5f03fa3b42fe1p-2
+min,-0x1.a046e65b3c456p-1,-0x1.a046e65b3c456p-1,0x1.f03620aa8ec09p-2
+min,-0x1.f581433baebbfp-8,-0x1.f581433baebbfp-8,0x1.b3456be2b36f8p-2
+min,-0x1.19389067a4bd5p-1,0x1.c5f73e666db0cp-2,-0x1.19389067a4bd5p-1
+min,-0x1.05f048693203fp1,-0x1.f5cacbe6855c4p-3,-0x1.05f048693203fp1
+min,-0x1.5ab3f8d498c8bp0,0x1.7c28d87baaecdp-1,-0x1.5ab3f8d498c8bp0
+min,-0x1.980a2fbf39e6bp-1,0x1.3b230bd4ceb4ap2,-0x1.980a2fbf39e6bp-1
+min,-0x1.07f038d7ae4bp0,-0x1.6cceed5d8afe1p-2,-0x1.07f038d7ae4bp0
+min,-0x1.1028a1ea4819ep0,0x1.246cb2321c69ep3,-0x1.1028a1ea4819ep0
+min,-0x1.3915753b2f211p0,0x1.b6ff957de56cp-8,-0x1.3915753b2f211p0
+min,-0x1.fc7df66f806f8p-1,0x1.764610e115881p-1,-0x1.fc7df66f806f8p-1
+min,-0x1.23c638306f8e8p-7,0x1.e5e780c1ed765p-1,-0x1.23c638306f8e8p-7
+min,0x1.86e6ffdca85bcp-1,0x1.1610ff1ddd62ep0,0x1.86e6ffdca85bcp-1
+min,0x1.3369be7382cb8p-1,0x1.aa86c4209f5eap-1,0x1.3369be7382cb8p-1
+min,-0x1.655e6a5389e78p1,-0x1.655e6a5389e78p1,0x1.c857034185afdp-1
+min,-0x1.9a3df57c6e1e4p-5,0x1.5003df95d3ec1p0,-0x1.9a3df57c6e1e4p-5
+min,-0x1.b0c7bfebfb80fp4,-0x1.b0c7bfebfb80fp4,0x1.bacb853d5d68cp3
+min,0x1.6e77565bcbec2p-1,0x1.5f57d8bdecf2fp1,0x1.6e77565bcbec2p-1
+min,-0x1.7a344909b4508p-7,0x1.658a46fe9a9fbp1,-0x1.7a344909b4508p-7
+min,-0x1.b9d0826f5f698p-5,0x1.5bded8ac0971cp-1,-0x1.b9d0826f5f698p-5
+min,-0x1.97e6fe051caf9p-1,-0x1.97e6fe051caf9p-1,-0x1.1cd6541c7dc28p-1
+min,-0x1.e826faa85a8cap0,0x1.1ee6597d17c77p0,-0x1.e826faa85a8cap0
+min,0x1.c081562b3d5f9p-5,0x1.9973cd63cbc18p-1,0x1.c081562b3d5f9p-5
+min,-0x1.4ce116f80496ep-4,0x1.1a22bb6efef72p-6,-0x1.4ce116f80496ep-4
+min,-0x1.0f004c5397ce5p0,-0x1.e03a80bc462b9p-2,-0x1.0f004c5397ce5p0
+min,-0x1.e54e81b91b3a6p0,-0x1.090169b160b8ap0,-0x1.e54e81b91b3a6p0
+min,-0x1.8a92051939d93p-2,-0x1.8a92051939d93p-2,-0x1.7d9eb3345b248p-2
+min,-0x1.f78dd1ca43a2dp-2,0x1.2665f9efc27dfp-1,-0x1.f78dd1ca43a2dp-2
+min,-0x1.1f4f31c42bfebp0,-0x1.1f4f31c42bfebp0,0x1.1c156fc7f2067p-1
+rint,-0x0.0p0,-0x1.268abd7b97d4dp-4
+rint,-0x0.0p0,-0x1.ce90039b60aebp-4
+rint,0x1.0p0,0x1.e4ecfa4f952e7p-1
+rint,-0x1.8p1,-0x1.afd4d19b7f8dap1
+rint,0x1.0p2,0x1.da3bd68bd4ddp1
+rint,-0x1.0p0,-0x1.0c3beddeb78a4p-1
+rint,0x1.0p0,0x1.75ef526669baap-1
+rint,0x1.0p0,0x1.74c104b92d4f9p0
+rint,-0x1.0p0,-0x1.3ed05cc70184fp0
+rint,-0x1.0p0,-0x1.e1a608b27df63p-1
+rint,-0x0.0p0,-0x1.af55e5fdbcc39p-3
+rint,0x1.0p0,0x1.ad5f44a429e87p-1
+rint,0x0.0p0,0x1.27cb5aab0dc54p-2
+rint,0x0.0p0,0x1.6699d74d1ce71p-2
+rint,0x0.0p0,0x1.ea333793843b6p-2
+rint,-0x1.0p0,-0x1.1bd32dc0009bfp-1
+rint,-0x1.8p1,-0x1.6ee93cb207aefp1
+rint,-0x1.0p0,-0x1.0de525de65447p-1
+rint,0x1.0p0,0x1.0148b70820c4dp-1
+rint,-0x0.0p0,-0x1.10805217b21aap-2
+rint,0x0.0p0,0x1.3d5c1de583edbp-3
+rint,0x1.0p0,0x1.a03b3152d028dp-1
+rint,-0x1.0p0,-0x1.5f041c44e90d1p-1
+rint,0x1.0p0,0x1.49439046777f9p0
+rint,-0x1.0p1,-0x1.28d5436eb7d2cp1
+rint,0x1.8p2,0x1.8b46c1838b98ap2
+rint,-0x0.0p0,-0x1.0471304f5a054p-5
+rint,0x0.0p0,0x1.9e8b18c8ebb83p-3
+rint,-0x1.0p1,-0x1.0a1df02bedaefp1
+rint,-0x0.0p0,-0x1.9a5d030e54e1cp-3
+rint,-0x1.8p1,-0x1.52f62b561d26ap1
+rint,0x0.0p0,0x1.be298f5967fd8p-6
+rint,-0x0.0p0,-0x1.f3f7d52af06dp-3
+rint,0x0.0p0,0x1.1f1297cdaad7fp-4
+rint,0x1.cp3,0x1.c5acc7f21f38dp3
+rint,-0x0.0p0,-0x1.c007c15df048ep-2
+rint,0x1.0p0,0x1.ddb83a6a98236p-1
+rint,-0x1.0p0,-0x1.10a321d00f1ebp-1
+rint,-0x1.8p1,-0x1.74981d40f271ep1
+rint,-0x1.0p0,-0x1.1fb6fbae1d141p-1
+rint,-0x0.0p0,-0x1.415207ed705b6p-2
+rint,0x0.0p0,0x1.721d06298d307p-3
+rint,0x0.0p0,0x1.f48709c1582f3p-4
+rint,0x1.0p1,0x1.f2cc062d0b567p0
+rint,0x1.0p1,0x1.ceac8b442b1b2p0
+rint,-0x1.0p0,-0x1.3522e3b9f349ap-1
+rint,-0x1.0p1,-0x1.35afc5d834dfap1
+rint,0x1.8p1,0x1.7e7edf2fdff71p1
+rint,-0x1.0p2,-0x1.10fc2ad87812cp2
+rint,-0x0.0p0,-0x1.8e02dcac1f3e3p-4
+rint,0x0.0p0,0x1.9c3a20144eb05p-7
+rint,-0x1.0p1,-0x1.3d52736f68b18p1
+rint,-0x1.cp2,-0x1.acb397da75f33p2
+rint,0x0.0p0,0x1.2b2b450cc38c6p-2
+rint,0x1.0p0,0x1.0a831b90c4eeep-1
+rint,-0x1.0p0,-0x1.12eedbd5f386fp0
+rint,0x1.0p0,0x1.34a220f0a02e2p0
+rint,0x1.0p1,0x1.04a277452476ep1
+rint,0x1.0p0,0x1.74e575fa823c4p-1
+rint,-0x1.8p2,-0x1.78205b0f35ab5p2
+rint,-0x1.0p0,-0x1.24a7e6a756508p0
+rint,-0x0.0p0,-0x1.6974bb79f8e3bp-2
+rint,-0x1.2p3,-0x1.15a591f8587fep3
+rint,-0x1.8p1,-0x1.be9c1872a9ae6p1
+rint,-0x1.8p2,-0x1.6b63b4774299ap2
+rint,-0x1.0p0,-0x1.01adda08540dp0
+rint,-0x1.0p0,-0x1.340ebda39a1d7p0
+rint,-0x1.0p0,-0x1.0b2ef4d4a5c38p0
+rint,0x0.0p0,0x1.02a715d4ded6dp-4
+rint,0x1.8p1,0x1.8970f490209afp1
+rint,-0x0.0p0,-0x1.e2a29b50fab79p-5
+rint,0x1.0p1,0x1.bd3180ca69342p0
+rint,-0x1.8p1,-0x1.6a707eb8365a4p1
+rint,-0x0.0p0,-0x1.0822c287571bbp-2
+rint,-0x0.0p0,-0x1.0774d818c096bp-2
+rint,-0x0.0p0,-0x1.cb57cd88b6814p-2
+rint,-0x1.6cp6,-0x1.6b3ee9a81134ep6
+rint,0x1.0p1,0x1.a4a0c509da1adp0
+rint,0x1.4p2,0x1.51c88432f3971p2
+rint,-0x1.0p0,-0x1.486abf9b592f6p-1
+rint,0x1.0p0,0x1.d80857586bc6fp-1
+rint,0x0.0p0,0x1.578876d5d5b3p-4
+rint,0x0.0p0,0x1.5b4c6a063ecddp-2
+rint,-0x1.8p3,-0x1.8109174b6f54fp3
+rint,0x1.3b4p10,0x1.3b4fc176c52cbp10
+rint,0x1.0p0,0x1.88530af7996bfp-1
+rint,0x0.0p0,0x1.c6ef91def2719p-7
+rint,-0x1.0p0,-0x1.003eb6cf0dc56p0
+rint,-0x0.0p0,-0x1.a80b404026eb5p-2
+rint,0x1.0p0,0x1.298d6a47d157ap0
+rint,-0x0.0p0,-0x1.933e7d46c7f34p-2
+rint,-0x1.0p1,-0x1.3c9574c6d096ap1
+rint,-0x0.0p0,-0x1.61caab39e144ep-2
+rint,-0x1.0p1,-0x1.042a8d6059565p1
+rint,-0x0.0p0,-0x1.0af3cdc9934e8p-5
+rint,-0x1.0p0,-0x1.3484927522febp0
+rint,0x0.0p0,0x1.734e12503c09bp-2
+rint,-0x1.0p3,-0x1.0e6cc242db1fdp3
+rint,-0x1.8p1,-0x1.4def7e9d6dfb9p1
+rint,0x1.0p1,0x1.867db25aa4c32p0
+rint,0x1.8p2,0x1.81caf889ccfb8p2
+rint,0x0.0p0,0x1.3251cfb971c4p-3
+rint,-0x1.0p0,-0x1.3cdad02b0127ep-1
+rint,-0x1.0p0,-0x1.072c2cf906319p0
+rint,-0x1.0p4,-0x1.045edd6c4c77cp4
+rint,-0x1.4p2,-0x1.2683e3e45b08cp2
+rint,-0x1.0p0,-0x1.356de8ee4699bp-1
+rint,0x1.0p2,0x1.c608611d27d43p1
+rint,0x0.0p0,0x1.72093650a52e4p-5
+rint,-0x1.0p0,-0x1.af9180dd287afp-1
+rint,-0x0.0p0,-0x1.6d67d3b3f0b87p-2
+rint,0x0.0p0,0x1.b8160d95ed57fp-2
+rint,0x1.4p2,0x1.55631268345bp2
+rint,0x1.0p0,0x1.2d1e3d29b568ap-1
+rint,-0x0.0p0,-0x1.53cf3c25e9902p-2
+rint,0x0.0p0,0x1.810155815f88p-2
+rint,0x1.0p1,0x1.e27bb3c0d372ap0
+rint,0x1.0p0,0x1.f93f6636ecd53p-1
+rint,0x1.8p1,0x1.a15121e27b58fp1
+rint,-0x1.0p0,-0x1.c79b4a9a78428p-1
+rint,-0x1.8p1,-0x1.54539c2aee079p1
+rint,0x1.0p1,0x1.a621d064219ecp0
+rint,0x1.0p0,0x1.4b2e7fd5a37c8p-1
+rint,-0x1.8p1,-0x1.589f47d9d3c4cp1
+rint,0x1.4p3,0x1.3818b56b20c08p3
+rint,-0x1.0p2,-0x1.f347d0a2f131fp1
+rint,-0x1.1p5,-0x1.0c44185d3cadfp5
+rint,-0x1.8p1,-0x1.4fe27fb2b0c53p1
+rint,0x1.0p0,0x1.5a582cbefb753p0
+rint,-0x1.0p2,-0x1.f092a0e332f9cp1
+rint,-0x1.0p0,-0x1.129eb68b04642p-1
+rint,0x1.0p2,0x1.c69b739b282fap1
+rint,0x0.0p0,0x1.604287f5a9429p-3
+rint,0x1.8p1,0x1.aa964836cb159p1
+rint,-0x1.0p1,-0x1.2fa3611ab6901p1
+rint,-0x1.6p3,-0x1.608a85772ead9p3
+rint,0x1.0p0,0x1.34f6be354890ap0
+rint,0x0.0p0,0x1.b2383068a5d09p-3
+rint,-0x1.0p0,-0x1.39707c4318253p0
+rint,-0x1.0p1,-0x1.199a1176dbd0ap1
+rint,-0x1.0p1,-0x1.a3f67dd020e44p0
+rint,-0x1.0p0,-0x1.8e05241eda779p-1
+rint,0x1.8p1,0x1.5d3a575dd10d8p1
+rint,-0x1.0p0,-0x1.14c85ca3d3d11p0
+rint,-0x1.0p0,-0x1.9e8c010f8ac2fp-1
+rint,-0x0.0p0,-0x1.c638361514109p-3
+rint,0x1.0p0,0x1.975be2d983681p-1
+rint,-0x1.1p5,-0x1.0f5471d8cd949p5
+rint,-0x1.0p1,-0x1.2173e0a3d232fp1
+rint,-0x0.0p0,-0x1.85e89615d5d38p-7
+rint,0x1.0p0,0x1.d74d2a411a4bbp-1
+rint,0x1.0p0,0x1.b64cf0264b1cp-1
+rint,0x0.0p0,0x1.6b739bd0f2b3p-2
+rint,0x0.0p0,0x1.d36b272bef8a3p-3
+rint,-0x1.0p0,-0x1.4fcbac94f975bp0
+rint,-0x1.0p0,-0x1.0c75ec256951ep0
+rint,0x0.0p0,0x1.d04737a528f0bp-2
+rint,-0x1.0p0,-0x1.3b8eb84ec9779p0
+rint,-0x1.0p0,-0x1.f6761584c5abbp-1
+rint,0x0.0p0,0x1.c2e85bc939218p-2
+rint,-0x1.0p1,-0x1.ca9e6a69f834ep0
+rint,-0x1.0p0,-0x1.916e37ff31e97p-1
+rint,0x1.0p1,0x1.3c871f6a61f44p1
+rint,0x1.4p2,0x1.295c95d904121p2
+rint,0x0.0p0,0x1.7645fac957147p-2
+rint,-0x1.8p1,-0x1.411df06a5babp1
+rint,-0x1.0p0,-0x1.21c5d31f6d27dp0
+rint,0x0.0p0,0x1.6fcc22eb7ce3ep-3
+rint,-0x0.0p0,-0x1.f98ce2709e33cp-2
+rint,0x1.0p1,0x1.28a6a7522f16ap1
+rint,-0x1.0p0,-0x1.3a507d95ce782p-1
+rint,-0x1.0p0,-0x1.420022071b16fp-1
+rint,-0x1.0p0,-0x1.1f391e0a98888p-1
+rint,0x1.0p1,0x1.bed218a13531ap0
+rint,0x1.0p2,0x1.db4357d53c349p1
+rint,-0x1.0p3,-0x1.f0827e913504dp2
+rint,0x0.0p0,0x1.31c6aa34c1195p-4
+rint,-0x1.0p0,-0x1.985452fd721c5p-1
+rint,-0x0.0p0,-0x1.4ad70030a2d28p-3
+rint,-0x1.1p4,-0x1.17d28e9b110d3p4
+rint,0x1.0p0,0x1.595b1ca5e2a74p0
+rint,-0x1.0p0,-0x1.04e0cd5ad5047p0
+rint,0x0.0p0,0x1.66693ef0a6de5p-2
+rint,-0x0.0p0,-0x1.23dc08e8cd76dp-9
+rint,0x0.0p0,0x1.438d036dcda45p-4
+rint,0x1.0p0,0x1.def796f294cbp-1
+rint,-0x0.0p0,-0x1.bf0fb62b5523fp-2
+rint,0x1.0p1,0x1.b39853ef0793bp0
+rint,0x1.0p4,0x1.f436c1fd8da07p3
+rint,-0x1.0p0,-0x1.a8160b5980e3ep-1
+rint,0x1.9p4,0x1.8833cb03caaa3p4
+rint,-0x0.0p0,-0x1.22fc97f963e56p-2
+rint,-0x1.0p0,-0x1.1bccce0791131p0
+rint,-0x1.cp2,-0x1.caa0e2178cd8ep2
+rint,0x1.bp5,0x1.b264348bcc276p5
+rint,0x0.0p0,0x1.8c6767b398dcep-2
+rint,-0x1.0p0,-0x1.7dccb23a33987p0
+rint,-0x1.0p0,-0x1.f26cf24d7d559p-1
+rint,-0x1.0p1,-0x1.eaaffa465b2a9p0
+rint,0x1.0p0,0x1.6c6dc2105be73p0
+signum,0x1.0p0,0x1.1a3d4fc7a8b02p-2
+signum,-0x1.0p0,-0x1.fe228b95ba25p-1
+signum,-0x1.0p0,-0x1.21fb1cbc2abdap0
+signum,-0x1.0p0,-0x1.3868b16944313p0
+signum,0x1.0p0,0x1.c66f8e4997682p-1
+signum,-0x1.0p0,-0x1.b0044eb46302p0
+signum,-0x1.0p0,-0x1.0131e3e8d92bdp-2
+signum,0x1.0p0,0x1.cac5840d66fe4p-3
+signum,0x1.0p0,0x1.572daf6ef2c5ap0
+signum,0x1.0p0,0x1.2e0c4ad74ec76p3
+signum,0x1.0p0,0x1.2710c81ed7afdp-2
+signum,-0x1.0p0,-0x1.e0e0fd00294d8p1
+signum,0x1.0p0,0x1.291f5a63a7303p3
+signum,0x1.0p0,0x1.b57ee4f88101bp0
+signum,-0x1.0p0,-0x1.3d767f97d77a5p0
+signum,-0x1.0p0,-0x1.84de638b42e32p0
+signum,-0x1.0p0,-0x1.0325a07f68cc8p1
+signum,0x1.0p0,0x1.4fe6826cce163p0
+signum,0x1.0p0,0x1.5fef43261ddabp1
+signum,-0x1.0p0,-0x1.bb43de2566d35p-3
+signum,-0x1.0p0,-0x1.fb641d350b093p0
+signum,0x1.0p0,0x1.887f25688ea32p-2
+signum,-0x1.0p0,-0x1.8f20d2d9d6ee5p-1
+signum,-0x1.0p0,-0x1.a19d0ac67fbb6p0
+signum,-0x1.0p0,-0x1.2bf0b23fc1b4ep1
+signum,0x1.0p0,0x1.650cec3003075p-1
+signum,-0x1.0p0,-0x1.ea4e336101c8p1
+signum,0x1.0p0,0x1.675f330659971p0
+signum,0x1.0p0,0x1.73fffcb287664p0
+signum,0x1.0p0,0x1.365746730f361p0
+signum,0x1.0p0,0x1.5f4d80f30fe66p-2
+signum,0x1.0p0,0x1.9a043c1b669p-6
+signum,0x1.0p0,0x1.763b03359f34ep-3
+signum,-0x1.0p0,-0x1.2245446decb07p0
+signum,-0x1.0p0,-0x1.ca16429735d7fp-2
+signum,-0x1.0p0,-0x1.430f48f2008d1p-2
+signum,-0x1.0p0,-0x1.28d356e3ae333p-1
+signum,0x1.0p0,0x1.b2fb022a4b2edp-5
+signum,-0x1.0p0,-0x1.0f49c17309a43p-4
+signum,-0x1.0p0,-0x1.4de1cb5097a3ep-2
+signum,0x1.0p0,0x1.4b43fccb09cb6p-1
+signum,0x1.0p0,0x1.b518077afad3dp-1
+signum,0x1.0p0,0x1.a071852a00314p0
+signum,-0x1.0p0,-0x1.dd00ccaa516c9p-1
+signum,-0x1.0p0,-0x1.68a31396f668ep0
+signum,-0x1.0p0,-0x1.22c69d1964442p0
+signum,0x1.0p0,0x1.57c6f812fee5fp-2
+signum,0x1.0p0,0x1.9a39f3f040c8ap6
+signum,-0x1.0p0,-0x1.1b0911ab7ac1dp-2
+signum,0x1.0p0,0x1.31801f7d375a2p-1
+signum,-0x1.0p0,-0x1.f3f8fcc027d4cp-2
+signum,-0x1.0p0,-0x1.71cc9ad409ea3p1
+signum,-0x1.0p0,-0x1.e2fed0da81e26p-3
+signum,0x1.0p0,0x1.7370cd960d4bp-2
+signum,0x1.0p0,0x1.fe003e889800cp0
+signum,0x1.0p0,0x1.1a5aefcdaa3ecp1
+signum,-0x1.0p0,-0x1.3a970a5def0b2p1
+signum,-0x1.0p0,-0x1.28aaff34f1f45p7
+signum,0x1.0p0,0x1.1c0a51cf8cdd6p2
+signum,0x1.0p0,0x1.4438e1b39db8ep-2
+signum,0x1.0p0,0x1.cd7c85cfe2a64p0
+signum,-0x1.0p0,-0x1.af0deb5d481a6p-4
+signum,-0x1.0p0,-0x1.ca053b9bfce0dp-2
+signum,-0x1.0p0,-0x1.2895c9f97406fp2
+signum,-0x1.0p0,-0x1.f22fca52bf512p5
+signum,0x1.0p0,0x1.41482e8745338p0
+signum,-0x1.0p0,-0x1.25f7f46a2f42bp1
+signum,0x1.0p0,0x1.567ad05164c56p-3
+signum,-0x1.0p0,-0x1.8055a246a94fap1
+signum,0x1.0p0,0x1.9a42bc3a82794p0
+signum,-0x1.0p0,-0x1.3bb3ad9a7630dp1
+signum,-0x1.0p0,-0x1.246146574c798p-1
+signum,0x1.0p0,0x1.4f78727ba4c6ap-3
+signum,0x1.0p0,0x1.1b98c2b509583p1
+signum,-0x1.0p0,-0x1.3dac8b72f4cfp1
+signum,0x1.0p0,0x1.6f46aff1cfca7p4
+signum,0x1.0p0,0x1.4515b3ad37985p1
+signum,-0x1.0p0,-0x1.21571f9f3d1aap-2
+signum,0x1.0p0,0x1.7a60191e80647p-1
+signum,-0x1.0p0,-0x1.e53fc2572804ep0
+signum,0x1.0p0,0x1.0f1a092b52ab7p1
+signum,0x1.0p0,0x1.f6d2a77acdf0bp1
+signum,0x1.0p0,0x1.1b946f3faf8c1p0
+signum,-0x1.0p0,-0x1.aeeaa2713927cp-1
+signum,-0x1.0p0,-0x1.f0c59b6da2eedp-6
+signum,-0x1.0p0,-0x1.908bd8875fb43p-1
+signum,-0x1.0p0,-0x1.8e5f9318ff445p0
+signum,-0x1.0p0,-0x1.58ad85cb73478p-3
+signum,-0x1.0p0,-0x1.27491677b5921p4
+signum,0x1.0p0,0x1.1a49b147641bdp1
+signum,-0x1.0p0,-0x1.29fe7b26dabdp-2
+signum,0x1.0p0,0x1.525fe0c81e43cp0
+signum,-0x1.0p0,-0x1.5d8e7da56990ap2
+signum,-0x1.0p0,-0x1.798a32640bacbp-1
+signum,0x1.0p0,0x1.942046d0d9f15p0
+signum,-0x1.0p0,-0x1.8383fe82a12c8p-1
+signum,0x1.0p0,0x1.5898f1786262ap-1
+signum,-0x1.0p0,-0x1.021b830a8beb8p0
+signum,-0x1.0p0,-0x1.b1230ebba73fbp-2
+signum,0x1.0p0,0x1.a3e32096e6635p0
+signum,0x1.0p0,0x1.dad58f3211322p-3
+signum,-0x1.0p0,-0x1.3c3b078d86766p-3
+signum,0x1.0p0,0x1.ccc09ab1c1addp0
+signum,-0x1.0p0,-0x1.58d9b6a6d1431p0
+signum,0x1.0p0,0x1.e34a9c872b574p6
+signum,0x1.0p0,0x1.7482aceab150ep0
+signum,-0x1.0p0,-0x1.486a2958dd734p1
+signum,-0x1.0p0,-0x1.0b9f0216571b4p-1
+signum,-0x1.0p0,-0x1.35777db826f93p-6
+signum,0x1.0p0,0x1.0d42beac642dp1
+signum,0x1.0p0,0x1.a87e45f5905ep-2
+signum,-0x1.0p0,-0x1.f9722a203855ep3
+signum,0x1.0p0,0x1.d584c8358f506p-2
+signum,-0x1.0p0,-0x1.e1320ee76d769p1
+signum,-0x1.0p0,-0x1.88334cc2177cbp-1
+signum,0x1.0p0,0x1.e908ff7ee1169p-1
+signum,0x1.0p0,0x1.55ef3fc6f89b2p-2
+signum,-0x1.0p0,-0x1.9ac2c7f86c6cdp-2
+signum,0x1.0p0,0x1.83f8e75e71eb2p-1
+signum,0x1.0p0,0x1.c9b44dfc4af65p1
+signum,0x1.0p0,0x1.9355350574ca9p2
+signum,0x1.0p0,0x1.585b4f630c574p1
+signum,0x1.0p0,0x1.1c96d0c66af4dp0
+signum,-0x1.0p0,-0x1.ab681f99c5d86p-3
+signum,0x1.0p0,0x1.9482749d0aa73p2
+signum,0x1.0p0,0x1.67cc7b0b4c26cp0
+signum,-0x1.0p0,-0x1.085f59e533c7ep-1
+signum,-0x1.0p0,-0x1.afefdc4c46c3ap0
+signum,0x1.0p0,0x1.6bb5e4a51967cp3
+signum,0x1.0p0,0x1.bfd9ab5f4332bp-1
+signum,-0x1.0p0,-0x1.1767d42fb2752p-3
+signum,0x1.0p0,0x1.95aaf6213e9c6p2
+signum,0x1.0p0,0x1.8825bf4dfdabfp0
+signum,-0x1.0p0,-0x1.1135f535c69dep-4
+signum,0x1.0p0,0x1.1f9e7b6d921b4p-2
+signum,0x1.0p0,0x1.4a9c752e94911p0
+signum,-0x1.0p0,-0x1.27f4c44a73fe6p-1
+signum,-0x1.0p0,-0x1.11f97648b9f8ap3
+signum,0x1.0p0,0x1.c77d53a50b053p0
+signum,-0x1.0p0,-0x1.d8113d6e9f8bcp-3
+signum,-0x1.0p0,-0x1.1d72c07d87e62p-2
+signum,-0x1.0p0,-0x1.358fe8d5cc199p0
+signum,-0x1.0p0,-0x1.aeead14f758b7p0
+signum,-0x1.0p0,-0x1.2a7e904ae4a44p1
+signum,-0x1.0p0,-0x1.e6b3bf0d17edbp-2
+signum,-0x1.0p0,-0x1.f4605a9efd9f1p0
+signum,-0x1.0p0,-0x1.d42845ce529bfp-3
+signum,-0x1.0p0,-0x1.64682ee910c7dp-8
+signum,0x1.0p0,0x1.8d935ae25468bp0
+signum,0x1.0p0,0x1.9de083cf13d31p0
+signum,0x1.0p0,0x1.33c2a52e9e197p-3
+signum,-0x1.0p0,-0x1.fdfbf0f5f8398p-4
+signum,-0x1.0p0,-0x1.c72c98ed1485dp0
+signum,-0x1.0p0,-0x1.bb8932b45fb62p-1
+signum,0x1.0p0,0x1.6e160c56703eap-1
+signum,-0x1.0p0,-0x1.fa25a6ee41b41p-1
+signum,-0x1.0p0,-0x1.272ac69f3cf22p0
+signum,-0x1.0p0,-0x1.71454149572f4p0
+signum,0x1.0p0,0x1.05c13c3872b5ap0
+signum,-0x1.0p0,-0x1.dc99d4ea8c043p-2
+signum,-0x1.0p0,-0x1.28eb471a3a91p-2
+signum,0x1.0p0,0x1.f40a33e7d49fbp-1
+signum,-0x1.0p0,-0x1.fda94be1a7904p-3
+signum,0x1.0p0,0x1.27074a195fb51p2
+signum,0x1.0p0,0x1.87b04e5581039p-3
+signum,0x1.0p0,0x1.9a188523a000cp2
+signum,-0x1.0p0,-0x1.e2a7f0d1cfdb8p-1
+signum,-0x1.0p0,-0x1.819901f0b0904p-3
+signum,0x1.0p0,0x1.2bb070c99fb6cp0
+signum,0x1.0p0,0x1.bb7402e945b7fp-4
+signum,-0x1.0p0,-0x1.7bf8d55eaefbdp1
+signum,-0x1.0p0,-0x1.199a2ffa37bf6p1
+signum,-0x1.0p0,-0x1.899df2cc40a33p-1
+signum,0x1.0p0,0x1.d8b19d1bed5eap-1
+signum,0x1.0p0,0x1.41ef45e1d237cp-1
+signum,0x1.0p0,0x1.fd50fff158b77p3
+signum,-0x1.0p0,-0x1.61db1558b5de3p5
+signum,0x1.0p0,0x1.082ef19a40405p1
+signum,0x1.0p0,0x1.48158d2f038eep-1
+signum,-0x1.0p0,-0x1.b9651dbebc609p2
+signum,0x1.0p0,0x1.c8f519f2f3045p-2
+signum,0x1.0p0,0x1.72a1e287cbf08p0
+signum,0x1.0p0,0x1.f09e7d5cd1a2ep-3
+signum,-0x1.0p0,-0x1.755699aee4ad9p-3
+signum,0x1.0p0,0x1.33c7b83b94af2p2
+signum,-0x1.0p0,-0x1.6c7c38f40084p1
+signum,-0x1.0p0,-0x1.e8073e9378aa3p-4
+signum,-0x1.0p0,-0x1.0d9e13d7f9284p0
+signum,-0x1.0p0,-0x1.14e0bcfb1aa8bp0
+signum,0x1.0p0,0x1.f2f0b1c247f41p-2
+signum,0x1.0p0,0x1.93c091038736cp2
+signum,0x1.0p0,0x1.5e0f2e629f9bep1
+signum,0x1.0p0,0x1.b5720829fea68p5
+signum,0x1.0p0,0x1.c056f6d23d03cp-1
+signum,-0x1.0p0,-0x1.2f7d64e8f0761p0
+signum,-0x1.0p0,-0x1.553f5170e1d75p-3
+signum,0x1.0p0,0x1.d8b9fda94abd4p-1
+signum,0x1.0p0,0x1.c31faf27fa01ep3
+signum,-0x1.0p0,-0x1.06058171a93d9p0
+signum,-0x1.0p0,-0x1.852592119514fp0
+toDegrees,0x1.9cc4da55f56cbp4,0x1.cd113dd73a73cp-2
+toDegrees,-0x1.94c416d548e15p2,-0x1.c420c0252959cp-4
+toDegrees,-0x1.7b02a36e7559fp5,-0x1.a75bcb9bdae6fp-1
+toDegrees,0x1.0f6e61abce825p7,0x1.2f31087c78663p1
+toDegrees,-0x1.be896265c1388p6,-0x1.f2c946a2c6a66p0
+toDegrees,-0x1.560657ad9eebdp4,-0x1.7e0b9b7822823p-2
+toDegrees,0x1.c97fc36ec2798p0,0x1.ff080809e5354p-6
+toDegrees,-0x1.231218346bfap6,-0x1.45210ae12d5dep0
+toDegrees,0x1.acd981a0f8f16p5,0x1.df07967013bfbp-1
+toDegrees,0x1.ffc04d8008847p5,0x1.1dd0d6e0a9014p0
+toDegrees,-0x1.22b4bf371bcefp6,-0x1.44b8c5afa5478p0
+toDegrees,-0x1.38f0f9d667f87p6,-0x1.5d8f0d930782dp0
+toDegrees,-0x1.516ecfff380abp7,-0x1.78ea87163eeabp1
+toDegrees,-0x1.2ae526db45ae4p7,-0x1.4dde7a996b9c8p1
+toDegrees,-0x1.a6b4650d4c965p5,-0x1.d82a67b42deaap-1
+toDegrees,0x1.7773b321056e7p6,0x1.a362445ee7c18p0
+toDegrees,-0x1.190c89382e7e9p4,-0x1.39ef493e52db9p-2
+toDegrees,0x1.42d69a1fb31b4p6,0x1.689d23fbea30ap0
+toDegrees,0x1.c8f48084d3c8fp6,0x1.fe6c7995f196fp0
+toDegrees,0x1.c5c438960265fp6,0x1.fadcae2a0e937p0
+toDegrees,-0x1.a296ca69d0b03p4,-0x1.d391849fee2e3p-2
+toDegrees,-0x1.90854d79fef1ep-1,-0x1.bf62cc5fffe35p-7
+toDegrees,-0x1.8e1570b872b7ap9,-0x1.bca9effb7253dp3
+toDegrees,0x1.0a21d4a34b9a3p3,0x1.2945c0511b397p-3
+toDegrees,-0x1.960053e8339dbp3,-0x1.c581fe108de79p-3
+toDegrees,0x1.880aeb1504fb8p4,0x1.b5ea74abe58d2p-2
+toDegrees,-0x1.74d2108f3c1aap3,-0x1.a071cf3c58906p-3
+toDegrees,0x1.c4324f9a9f8bdp5,0x1.f91bbe117d1cp-1
+toDegrees,0x1.18467de646d62p7,0x1.3912118f3c746p1
+toDegrees,0x1.0eed528a37375p9,0x1.2ea0df6c23f34p3
+toDegrees,-0x1.450d273c40222p6,-0x1.6b15fbfe1b148p0
+toDegrees,0x1.dd9b163174e74p3,0x1.0abed2c6e1761p-2
+toDegrees,0x1.60880fe3738a2p3,0x1.89c80d8ae0428p-3
+toDegrees,0x1.12bfe174fb77ap2,0x1.32e5eecd756dbp-4
+toDegrees,0x1.90c57dddec21ap1,0x1.bfaa7f87fb8a7p-5
+toDegrees,-0x1.3a350b8cda184p6,-0x1.5ef90ab264d6p0
+toDegrees,0x1.75031f7ed32cdp6,0x1.a0a89bb3a76ap0
+toDegrees,0x1.fcb5dee07145fp4,0x1.1c1e14b2b9db4p-1
+toDegrees,0x1.69114d2c22ba8p4,0x1.9350fd1d452d5p-2
+toDegrees,-0x1.526b1f129d2c1p5,-0x1.7a045c02d25bfp-1
+toDegrees,0x1.e2dfecd8124b2p3,0x1.0db028288dd15p-2
+toDegrees,-0x1.0dd14c6709a48p7,-0x1.2d639d6b5ce98p1
+toDegrees,0x1.2a01518efb356p6,0x1.4cdffc9db8986p0
+toDegrees,-0x1.9bc784f0c6b48p5,-0x1.cbf643e726dd8p-1
+toDegrees,-0x1.4f0025a5e36cep6,-0x1.763300f441a5p0
+toDegrees,0x1.689f3d35e9e25p3,0x1.92d19471a60b9p-3
+toDegrees,0x1.071bc5fd59a7fp4,0x1.25e51efb7444dp-2
+toDegrees,0x1.3d28cd1ab705cp6,0x1.62453abb2adc3p0
+toDegrees,-0x1.713bef68c5494p3,-0x1.9c703fc03e9d5p-3
+toDegrees,0x1.6618e48537401p3,0x1.8fff9a9c68351p-3
+toDegrees,-0x1.358164697bc5cp4,-0x1.59b88c71a52ddp-2
+toDegrees,0x1.7717dd5882015p6,0x1.a2fbafb0d679cp0
+toDegrees,-0x1.1b5f7b4512444p5,-0x1.3c87d8bc0f4f4p-1
+toDegrees,0x1.044ba83c26953p6,0x1.22c0be546d685p0
+toDegrees,-0x1.6d40cb9cad76ep9,-0x1.97fddbe158cc3p3
+toDegrees,0x1.3708b29f0dc25p5,0x1.5b6da41c12f38p-1
+toDegrees,-0x1.975ed02c432d9p6,-0x1.c7097d08166fp0
+toDegrees,0x1.4c557ad19a278p6,0x1.733875000be6cp0
+toDegrees,0x1.4734be48e506dp5,0x1.6d7e1dc7db526p-1
+toDegrees,0x1.485976815821dp6,0x1.6ec51657a80b1p0
+toDegrees,0x1.f2596d0c82a2fp5,0x1.1654ad221e6ep0
+toDegrees,0x1.8eff75442afa9p5,0x1.bdaf56785b7cbp-1
+toDegrees,0x1.e8e4b12a2aba2p8,0x1.110caef53c05dp3
+toDegrees,-0x1.c4fa982ea8112p6,-0x1.f9fb761682d11p0
+toDegrees,0x1.1a5f7514640c3p5,0x1.3b69dd67cf39fp-1
+toDegrees,-0x1.794600ac5da92p7,-0x1.a56b21e64998p1
+toDegrees,0x1.e35d13fe74edfp5,0x1.0df60e3206348p0
+toDegrees,-0x1.c4e1b476eda0ep4,-0x1.f9dfa8cf9b3d5p-2
+toDegrees,0x1.69682c8023cc2p5,0x1.93b206aeab843p-1
+toDegrees,-0x1.6b3653d3330f4p4,-0x1.95b641b33e0c1p-2
+toDegrees,0x1.b4a966dff8b42p5,0x1.e7c17e0aedc62p-1
+toDegrees,0x1.90ec5ba49fbb5p4,0x1.bfd5e989b0585p-2
+toDegrees,-0x1.e889680f077cap5,-0x1.10d9b32fdd367p0
+toDegrees,-0x1.3730338445bfcp7,-0x1.5b99c4527ddd1p1
+toDegrees,-0x1.022c00433be75p5,-0x1.20617946cc6bep-1
+toDegrees,0x1.12162302b21bp7,0x1.322853b853541p1
+toDegrees,0x1.b9be356b5ae5p6,0x1.ed6e81ec514c4p0
+toDegrees,0x1.9e768d7447387p3,0x1.cef5b0528789cp-3
+toDegrees,0x1.2adffc78f9eb4p6,0x1.4dd8b57b73478p0
+toDegrees,-0x1.3f4e073a6bbd3p7,-0x1.64aab8cf9710fp1
+toDegrees,0x1.c0aa08f3f6bbap4,0x1.f529a80fabcc6p-2
+toDegrees,-0x1.e192542d3cd5ap2,-0x1.0cf5d76d8bc39p-3
+toDegrees,0x1.04ab229374e59p6,0x1.232b64afd152ep0
+toDegrees,-0x1.f9e0a77142ffdp-1,-0x1.1a890b24927f6p-6
+toDegrees,0x1.e97f3f3966932p5,0x1.116300d074b9bp0
+toDegrees,-0x1.1cec99f1b0757p6,-0x1.3e436f08204c9p0
+toDegrees,-0x1.7d252f6ad8e33p6,-0x1.a9be4b43df93ap0
+toDegrees,-0x1.8a42007322f05p3,-0x1.b863e4e12bc6fp-3
+toDegrees,-0x1.278d84dfc3f4cp4,-0x1.4a22ba5b4331p-2
+toDegrees,-0x1.ed3a5058db8abp3,-0x1.137869c4a0318p-2
+toDegrees,-0x1.b5b4e4413337ep7,-0x1.e8ec48029555bp1
+toDegrees,0x1.5684eea8fbe01p3,0x1.7e99026a5d775p-3
+toDegrees,-0x1.4b23ed2f49fp5,-0x1.71e32698a8e3fp-1
+toDegrees,-0x1.df05855cfd054p8,-0x1.0b893eacbacc4p3
+toDegrees,-0x1.40573e27c281fp6,-0x1.65d2f82c221f3p0
+toDegrees,-0x1.68c5edf3d9b3ep5,-0x1.92fccc2599ddp-1
+toDegrees,0x1.16f591c9d9791p7,0x1.3799b906d8ee9p1
+toDegrees,0x1.2c9a73b1f03b8p3,0x1.4fc6f2a6f562cp-3
+toDegrees,-0x1.98e03048c019dp4,-0x1.c8b7f4f73266cp-2
+toDegrees,-0x1.be6f129011c73p6,-0x1.f2abe2a2e1c9dp0
+toDegrees,0x1.e5d4c67fad724p8,0x1.0f56dc9cfb8ddp3
+toDegrees,0x1.e8a586d34db52p7,0x1.10e967bc9c3f8p2
+toDegrees,0x1.0acde77827a8ep7,0x1.2a05f5915fde8p1
+toDegrees,-0x1.66c7f595b3323p4,-0x1.90c327c09c62ap-2
+toDegrees,0x1.8dd01c0733ae9p4,0x1.bc5c7e80a714cp-2
+toDegrees,0x1.1b088597a996dp6,0x1.3c26b633ca24fp0
+toDegrees,-0x1.cddf63ec90861p3,-0x1.01f55555933f7p-2
+toDegrees,-0x1.02b7b8b3d1fe1p6,-0x1.20fd8b01dd796p0
+toDegrees,-0x1.559d98a788a77p7,-0x1.7d969accdb9d9p1
+toDegrees,-0x1.3f5f0d0bfb216p6,-0x1.64bdbc8a7e518p0
+toDegrees,0x1.16226547ded9dp4,0x1.36add6dc29f2ap-2
+toDegrees,0x1.d4d4543876317p3,0x1.05d7ff438dc75p-2
+toDegrees,0x1.1d28bbaefee9dp5,0x1.3e869a00f7c61p-1
+toDegrees,-0x1.86579970698fap5,-0x1.b404332954a1ep-1
+toDegrees,0x1.2ef51ad45c23bp9,0x1.52681e197503fp3
+toDegrees,-0x1.3cf9701fe3407p6,-0x1.621052ffaaa7ap0
+toDegrees,0x1.e7244245038d5p3,0x1.10123b28dd00ap-2
+toDegrees,0x1.a5a03aa78362p5,0x1.d6f5ecd5f2423p-1
+toDegrees,0x1.e8f39b8a61b6ap3,0x1.1115038a9416bp-2
+toDegrees,0x1.3bf51b0182135p5,0x1.60ed87afc67a6p-1
+toDegrees,0x1.5b13311fb6c09p7,0x1.83afbbe37580cp1
+toDegrees,0x1.395e71b8dc57ap9,0x1.5e09548dca6fap3
+toDegrees,0x1.b5fd9e97cb653p7,0x1.e93d84e4beffdp1
+toDegrees,0x1.0b5531c717ccdp10,0x1.2a9d14762cdbep4
+toDegrees,-0x1.0f7be127bd95dp6,-0x1.2f401c4c8c6dap0
+toDegrees,-0x1.f8a402b4d979cp5,-0x1.19d832498ae13p0
+toDegrees,-0x1.8d2c07dfa6e11p5,-0x1.bba537696177bp-1
+toDegrees,-0x1.c154bc5577641p5,-0x1.f5e854bcf804bp-1
+toDegrees,-0x1.39d507bcace13p3,-0x1.5e8dcac830903p-3
+toDegrees,0x1.11e06dc88ae51p4,0x1.31ec55af95699p-2
+toDegrees,0x1.1ebf16f38b1d9p7,0x1.404c8193c1f93p1
+toDegrees,-0x1.708e7799a7b4ep4,-0x1.9bae7bc08c7c8p-2
+toDegrees,-0x1.5c8a2d06523abp9,-0x1.85529856c320fp3
+toDegrees,-0x1.5e2b963a36dp7,-0x1.8724d8fae038fp1
+toDegrees,0x1.3e13287c19be7p7,0x1.634b0236da71bp1
+toDegrees,0x1.a3ff712c87297p6,0x1.d5245e9b2e50cp0
+toDegrees,0x1.80d8a3f61cf0dp5,0x1.ade09c96d6ep-1
+toDegrees,0x1.cbaa19fa7d4edp5,0x1.00b99dd1e4d8ep0
+toDegrees,0x1.dc522f7f9e4e9p4,0x1.0a07215ac31f7p-1
+toDegrees,-0x1.2c3cf84f90a7ep3,-0x1.4f5e870a148f8p-3
+toDegrees,-0x1.1dc120f5ca3afp7,-0x1.3f30d4407fa7fp1
+toDegrees,0x1.6e2c3ba13a4d3p5,0x1.9904d85ecc7c9p-1
+toDegrees,-0x1.ea38a3aa95e47p7,-0x1.11ca8bb9c2c15p2
+toDegrees,-0x1.322c04414ec4cp8,-0x1.55ff51a36f15dp2
+toDegrees,-0x1.4fe90d155a88dp6,-0x1.773728f881204p0
+toDegrees,0x1.ff58a2d82d4b1p8,0x1.1d96f0e567a04p3
+toDegrees,-0x1.a25d798c48c75p5,-0x1.d3517ee076ecap-1
+toDegrees,0x1.6c39408ca491fp4,0x1.96d77a72adc61p-2
+toDegrees,0x1.58be156cc8725p7,0x1.8114c1f74781cp1
+toDegrees,-0x1.45cb34c0c3921p3,-0x1.6bea467e50e53p-3
+toDegrees,0x1.cf7a84939fa02p6,0x1.02daf3455c5ebp1
+toDegrees,0x1.c8d9ec779379ap5,0x1.fe4ec9630f342p-1
+toDegrees,0x1.40f290dd23f99p5,0x1.6680778b4b4dbp-1
+toDegrees,-0x1.d007e807137ccp5,-0x1.0329ea9fd53c5p0
+toDegrees,-0x1.0b45c757e1c32p5,-0x1.2a8bdc408764ap-1
+toDegrees,-0x1.260688556fd89p3,-0x1.486dfdea7261dp-3
+toDegrees,-0x1.e5e3535741671p8,-0x1.0f5efcf51e5d2p3
+toDegrees,-0x1.0086c685a5706p6,-0x1.1e8af5d50c276p0
+toDegrees,0x1.57a34296c3044p7,0x1.7fd8d738cb1ddp1
+toDegrees,0x1.2a33a57def28bp7,0x1.4d18341b9bfep1
+toDegrees,0x1.a7c08f4d64de1p6,0x1.d955f2c4fe762p0
+toDegrees,0x1.7128c6132b42ap3,0x1.9c5ad8709aa79p-3
+toDegrees,-0x1.688e096df3805p7,-0x1.92be5d5f8c398p1
+toDegrees,0x1.000dfdac23b5cp3,0x1.1e040ae962b82p-3
+toDegrees,-0x1.1af109f43a815p5,-0x1.3c0c7b234319cp-1
+toDegrees,0x1.fc9f8ecba486dp6,0x1.1c119e785bc66p1
+toDegrees,-0x1.aab953e1cd1d7p5,-0x1.dca7bbf503ce4p-1
+toDegrees,-0x1.5e8928b59890ep7,-0x1.878d5e64a5e27p1
+toDegrees,0x1.836a93ac41202p3,0x1.b0bf889de387cp-3
+toDegrees,0x1.3b7cdcc880872p6,0x1.6067379d26339p0
+toDegrees,0x1.c8056c371e64dp5,0x1.fd616bb8f3785p-1
+toDegrees,-0x1.ec401ac74c4bcp4,-0x1.12ecab81b3564p-1
+toDegrees,-0x1.ca28aa208a7a4p5,-0x1.ffc4b21fba5b4p-1
+toDegrees,-0x1.1a006a6cef937p6,-0x1.3affb3cdd2bf1p0
+toDegrees,0x1.563d185336d2bp9,0x1.7e48c436ce2a6p3
+toDegrees,-0x1.4ca0d7ea15c7fp8,-0x1.738ca398485b2p2
+toDegrees,0x1.009f3a101b96dp4,0x1.1ea645ce750cdp-2
+toDegrees,-0x1.2beb979f7ba94p5,-0x1.4f03a0b42782dp-1
+toDegrees,-0x1.0c9a2275da42ap6,-0x1.2c080aa4dcbeap0
+toDegrees,-0x1.6162e5122ed34p4,-0x1.8abc7dcdd3575p-2
+toDegrees,-0x1.41e855cd03379p6,-0x1.6792fe6ff2af7p0
+toDegrees,0x1.2db550afa1b3ap7,0x1.5102e8bd4e53ep1
+toDegrees,-0x1.f55dbe6f2720ep6,-0x1.1804051e6ce8ep1
+toDegrees,-0x1.2eb22726e4acdp3,-0x1.521d54e55310dp-3
+toDegrees,-0x1.3ef9ae1414208p7,-0x1.644c8107f5d37p1
+toDegrees,-0x1.2a6babb40908dp8,-0x1.4d56c882fd11ap2
+toDegrees,-0x1.6eb2ba40302ebp4,-0x1.999b13be37afp-2
+toDegrees,-0x1.1f825cdc83933p8,-0x1.4126a0d7b7ec8p2
+toDegrees,0x1.196d47a93599dp6,0x1.3a5b599fc865dp0
+toDegrees,-0x1.152cb9e9e5ap2,-0x1.359b6c87594cep-4
+toDegrees,0x1.e8033ad066cefp5,0x1.108ec2f31fd2p0
+toDegrees,-0x1.380d292404d8ap1,-0x1.5c9094bb0fa5ap-5
+toDegrees,-0x1.e3b0170b51c6cp8,-0x1.0e246b0558ec9p3
+toDegrees,0x1.5292d8b4c17e7p7,0x1.7a30bb99bbf7ap1
+toDegrees,0x1.a643cd81be412p8,0x1.d7aca37eb05a1p2
+toDegrees,-0x1.6202c5199be34p2,-0x1.8b6f12d9e8ceap-4
+toDegrees,-0x1.5c58d80880982p5,-0x1.851b7d9eba78dp-1
+toDegrees,-0x1.43b8e1a23e479p7,-0x1.6999e5a23a02fp1
+toDegrees,-0x1.8815f8f42cea6p5,-0x1.b5f6cdab230d6p-1
+toDegrees,-0x1.4bf63f89b2173p7,-0x1.72ce151501a48p1
+toRadians,0x1.343b2ed481bd1p-6,0x1.13f162387c30ep0
+toRadians,0x1.62b1bc6a273c9p-7,0x1.3d89f0fad72e1p-1
+toRadians,-0x1.269dd1f61b4dfp-6,-0x1.07c11fe9ef09ap0
+toRadians,0x1.8f9413ec4afd4p-5,0x1.65b8a1590af12p1
+toRadians,-0x1.d5e34359a07fep-6,-0x1.a4aa56bfa319bp0
+toRadians,0x1.dccef5cda0302p-8,0x1.aadc71cf68e4p-2
+toRadians,-0x1.756bb6c6074bp-6,-0x1.4e4dbbcc2fa9fp0
+toRadians,0x1.bd04cff56f47ep-7,0x1.8e66cbb71fd56p-1
+toRadians,0x1.78fefa23b96fap-6,0x1.51811ea8e898bp0
+toRadians,0x1.0d4d232276716p-6,0x1.e22ea197722cep-1
+toRadians,-0x1.33d9fd2988496p-4,-0x1.139a5efe42b6ap2
+toRadians,-0x1.229982e2b8d7cp-5,-0x1.042888e04d436p1
+toRadians,-0x1.29c7dd4973314p-6,-0x1.0a965060eb912p0
+toRadians,0x1.20d720e76b068p-5,0x1.029554c15c57ap1
+toRadians,0x1.7f5bf73fdde9cp-7,0x1.5733775f2d25p-1
+toRadians,0x1.42170369d60b3p-4,0x1.2059910e0b436p2
+toRadians,0x1.a8b0ae7ecdabdp-3,0x1.7c33d0cf9cf15p3
+toRadians,0x1.630ea69bd5949p-5,0x1.3ddd1f7cf69b8p1
+toRadians,0x1.7f69b05ec6601p-3,0x1.573fc07b23f0dp3
+toRadians,0x1.af6c649a981abp-5,0x1.823af65afedeap1
+toRadians,-0x1.4a937400ee9d5p-5,-0x1.27f26f955178ap1
+toRadians,-0x1.b809620a4ff24p-4,-0x1.89f0f8d5f08f1p2
+toRadians,0x1.5fc99f56b4abap-7,0x1.3aefc6b5b91b7p-1
+toRadians,-0x1.517b699ec7bep-4,-0x1.2e21320a4ff91p2
+toRadians,-0x1.0bb8960d4d455p-7,-0x1.df5a490650c4ap-2
+toRadians,-0x1.ec1e137eb7753p-7,-0x1.b891050802839p-1
+toRadians,0x1.29829f741d254p-6,0x1.0a5853632a0e3p0
+toRadians,-0x1.4f91fde8cb341p-6,-0x1.2c6b0b115881dp0
+toRadians,0x1.33d962b6df19p-6,0x1.1399d4b969204p0
+toRadians,-0x1.c22d9a20d8453p-3,-0x1.93053a6c3aac9p3
+toRadians,0x1.8a562054567fdp-5,0x1.610740b5d01cbp1
+toRadians,-0x1.f38e2489f0cc6p-9,-0x1.bf39a0f24dfa5p-3
+toRadians,0x1.d8241c6f90ae7p-6,0x1.a6aec291de8e6p0
+toRadians,0x1.ea933e48ad7p-7,0x1.b72f8c019babcp-1
+toRadians,0x1.3a4dc8294ed8p-7,0x1.1961220e2d1bfp-1
+toRadians,-0x1.19ba22c2bb686p-7,-0x1.f86e2feb49188p-2
+toRadians,-0x1.85b38b279cecbp-9,-0x1.5ce0f7fbeaff5p-3
+toRadians,-0x1.eb71d9b818fd5p-7,-0x1.b7f6d5cfb47c3p-1
+toRadians,0x1.6ac5dcc337895p-3,0x1.44c56ca0989b1p3
+toRadians,-0x1.8d19564a6d62bp-5,-0x1.6380617bbb3d9p1
+toRadians,-0x1.241f2b58bedb9p-3,-0x1.05855fec5a98bp3
+toRadians,-0x1.6366121646645p-8,-0x1.3e2b62a393a8ap-2
+toRadians,0x1.6ecc94720253cp-6,0x1.48602bae2826p0
+toRadians,0x1.71d14914d9a1p-7,0x1.4b13eec2e34aep-1
+toRadians,-0x1.5a9a542f7ce34p-6,-0x1.364b856e7ad01p0
+toRadians,-0x1.0a0bba58bd01dp-7,-0x1.dc5a6ae50df52p-2
+toRadians,-0x1.8c8b2bf16c84ap-2,-0x1.63011b91a72d5p4
+toRadians,-0x1.d56110f9c4a6ap-7,-0x1.a435c7d87ec43p-1
+toRadians,0x1.96182610fd5dp-10,0x1.6b8df7081097cp-4
+toRadians,0x1.3d395c885fe78p-6,0x1.1bfe66ac6aca2p0
+toRadians,0x1.fa9331390851p-7,0x1.c5826e5d6a8fdp-1
+toRadians,-0x1.3a41e6900b66ep-7,-0x1.19567f131b0b3p-1
+toRadians,0x1.ef7b1d4585839p-6,0x1.bb93dc72c9319p0
+toRadians,0x1.62d84b7aedaa3p-5,0x1.3dac76046aacep1
+toRadians,-0x1.0f20042155341p-6,-0x1.e572931c5417bp-1
+toRadians,-0x1.690ea94f0a1b8p-6,-0x1.433c3b2cb5df1p0
+toRadians,-0x1.94c307b06c295p-8,-0x1.6a5c9464a575dp-2
+toRadians,-0x1.c7c50a49a546cp-9,-0x1.9806b7e00001p-3
+toRadians,0x1.73099f305d1fep-4,0x1.4c2b8cfb45c8bp2
+toRadians,-0x1.389be50a6fd97p-8,-0x1.17dcb26fb38ap-2
+toRadians,0x1.5fbc85728b899p-8,0x1.3ae40c2677db1p-2
+toRadians,0x1.ef94c7f3a2ecfp-6,0x1.bbaad6d3bf4d2p0
+toRadians,-0x1.8f2d697a05737p-9,-0x1.655cb8140865dp-3
+toRadians,0x1.b20508bdffb78p-5,0x1.848dfae3dca6ep1
+toRadians,-0x1.bdb35ca54ab81p-7,-0x1.8f030f8701c68p-1
+toRadians,0x1.0861b9ad91254p-5,0x1.d95fa9ae542c1p0
+toRadians,0x1.a76bd0ab65c66p-7,0x1.7b10fae457027p-1
+toRadians,0x1.54c5e8e9a7843p-7,0x1.3113702f0fc4fp-1
+toRadians,-0x1.13d8a20895e4fp0,-0x1.ede6983faab45p5
+toRadians,-0x1.cebc35c4a890bp-8,-0x1.9e43184cdea2ap-2
+toRadians,0x1.3d3e1280d3313p-4,0x1.1c029e507fabcp2
+toRadians,-0x1.5f6a1f54ab2a4p-7,-0x1.3a9a47b707798p-1
+toRadians,-0x1.3c0058e027e76p-6,-0x1.1ae62d156322p0
+toRadians,0x1.91a20082f74adp-3,0x1.678f764a36e11p3
+toRadians,0x1.5a7a88c4fde6ep-8,0x1.362f0ea5bddffp-2
+toRadians,-0x1.dd2d62c4677b5p-7,-0x1.ab30fa92aab8ep-1
+toRadians,0x1.c090beda0a1ebp-4,0x1.91939eabe933ep2
+toRadians,-0x1.fa64fbfece91ep-8,-0x1.c559104a2fc35p-2
+toRadians,0x1.03e06cf40987fp-6,0x1.d14eb0092067dp-1
+toRadians,-0x1.9e2d350067dbbp-8,-0x1.72ca4846014p-2
+toRadians,0x1.2b149a9831e4ep-2,0x1.0bc032a6985a2p4
+toRadians,-0x1.eb36b025b1424p-7,-0x1.b7c1deca5038ep-1
+toRadians,-0x1.581a480c8d362p-4,-0x1.340e855ef1af6p2
+toRadians,-0x1.0c3f652158269p-7,-0x1.e04ba8df602b9p-2
+toRadians,-0x1.309379cfc0976p-11,-0x1.10abb1f2f2834p-5
+toRadians,0x1.3f6a7aa234715p-7,0x1.1df4bd59b7a1fp-1
+toRadians,-0x1.65dd0dca04ae2p-7,-0x1.40604556bbc5ap-1
+toRadians,-0x1.69934495b8f4ap-6,-0x1.43b2f25b4c342p0
+toRadians,-0x1.f6766633423b6p-7,-0x1.c1d3ebf82f78ep-1
+toRadians,0x1.4c96adb0ee339p-6,0x1.29bfb0889a191p0
+toRadians,0x1.51c4cc005ef3ep-7,0x1.2e62e47bbc5f8p-1
+toRadians,-0x1.37fcc828121c6p-8,-0x1.174e407648858p-2
+toRadians,0x1.3c85a053a8dbfp-6,0x1.1b5d7e6798ac9p0
+toRadians,0x1.2fa1707ca7533p-6,0x1.0fd303496037ep0
+toRadians,-0x1.fd30ff4ab5bb4p-8,-0x1.c7da125a7e8cp-2
+toRadians,-0x1.07053d4647f61p-3,-0x1.d6efb37cbda3cp2
+toRadians,0x1.2e6539dacf422p-6,0x1.0eb7ec831448p0
+toRadians,0x1.90768a6c41a28p-6,0x1.66835ed1b0038p0
+toRadians,-0x1.3b5f769af4c14p-9,-0x1.1a5625378947dp-3
+toRadians,0x1.5e2305a747b1bp-7,0x1.397571d90c1e8p-1
+toRadians,-0x1.9684bb151928dp-6,-0x1.6bef2c36e0214p0
+toRadians,0x1.80aab10e1f8a3p-10,0x1.585f20e007884p-4
+toRadians,-0x1.73454254905c1p-9,-0x1.4c60f0d6580cep-3
+toRadians,-0x1.64e173018ac6bp-6,-0x1.3f7f05ce9fc63p0
+toRadians,0x1.6c33df8f50558p-9,0x1.460d18271bc01p-3
+toRadians,-0x1.a66398e8cab57p-11,-0x1.7a2470a132a52p-5
+toRadians,-0x1.4044a3024d4c3p-6,-0x1.1eb80b6a865f3p0
+toRadians,0x1.a5edecbd257d2p-7,0x1.79bb1811e0512p-1
+toRadians,0x1.2f63061aafa03p-9,0x1.0f9b22b1cf7b8p-3
+toRadians,0x1.57a84a0a48335p-6,0x1.33a878472947cp0
+toRadians,-0x1.1fbadf0bde297p-5,-0x1.0196d9ca7dd6dp1
+toRadians,0x1.0579eb2f75c14p-5,0x1.d42be1d80dafap0
+toRadians,0x1.4bb08a6dddaffp-10,0x1.28f1a8d929a18p-4
+toRadians,-0x1.785e5c8f3248bp-6,-0x1.50f15449acabep0
+toRadians,0x1.7c2e98ed7c20ap-6,0x1.545b4d0e37923p0
+toRadians,0x1.8afa8d5f6beb4p-7,0x1.619a745cb9468p-1
+toRadians,0x1.9ab81ca6e2142p-7,0x1.6fb1e76a3d452p-1
+toRadians,0x1.5abbd97d5f2dfp-8,0x1.366987d08a848p-2
+toRadians,0x1.10b1ed52fa65ap-5,0x1.e8423180e2757p0
+toRadians,0x1.1977488637e48p-7,0x1.f7f67cff2be2p-2
+toRadians,-0x1.ea464cd97d49ep-5,-0x1.b6eaa9f230e9ap1
+toRadians,0x1.b91c40b587a6dp-4,0x1.8ae70c5a81ab4p2
+toRadians,0x1.4437a94ee4aa7p-5,0x1.2241293012d19p1
+toRadians,0x1.f5efccce5b07bp-6,0x1.c15b6c1b274d9p0
+toRadians,-0x1.9f99237013c3ep-9,-0x1.741017345ad98p-3
+toRadians,-0x1.0973876df224ap-6,-0x1.db49e80f5e81ep-1
+toRadians,0x1.6fa164f8ba5d2p-6,0x1.491eb12f08f23p0
+toRadians,0x1.6c2759fa3c865p-9,0x1.4601e25dc1082p-3
+toRadians,-0x1.9e741ead7ac95p-9,-0x1.7309c44a173a5p-3
+toRadians,0x1.9030fa34f406dp-6,0x1.664518133618ep0
+toRadians,-0x1.efe26ef81c43dp-4,-0x1.bbf05b72f4d36p2
+toRadians,-0x1.f34430fc0f19fp-7,-0x1.bef76c89ad7e8p-1
+toRadians,-0x1.2cbb12850bd1p-6,-0x1.0d3a694a092f3p0
+toRadians,-0x1.6ca79b649b4dap-6,-0x1.4674b45e4bef9p0
+toRadians,-0x1.5ed33ec70db7ap-6,-0x1.3a1335377f47p0
+toRadians,0x1.4bb2ac4bfd435p0,0x1.28f39188d12e9p6
+toRadians,-0x1.1e73f51abbca9p-5,-0x1.00722ea8a6779p1
+toRadians,0x1.50359082fe9fap-6,0x1.2cfd7b2947624p0
+toRadians,-0x1.6890f9618d29ep-7,-0x1.42cbb5c946d7ep-1
+toRadians,-0x1.b7177f3ea7634p-7,-0x1.89186caa94425p-1
+toRadians,0x1.14ded07f7b65p-6,0x1.efbc076595c42p-1
+toRadians,0x1.94c88977ca0cap-6,0x1.6a61827e245e2p0
+toRadians,-0x1.f25873e1c75c3p-8,-0x1.be24613628b96p-2
+toRadians,-0x1.caa05a18ca625p-6,-0x1.9a956c2ee4594p0
+toRadians,-0x1.6674a31e63532p-7,-0x1.40e7f9ad2943fp-1
+toRadians,0x1.5ebd1a81b95b7p-6,0x1.39ff62b7845c3p0
+toRadians,0x1.7770bfa4cac45p-8,0x1.501c9b691eb28p-2
+toRadians,0x1.52c145c51ab79p0,0x1.2f44eba454717p6
+toRadians,-0x1.5082c8921deefp-5,-0x1.2d429c72b1d75p1
+toRadians,0x1.288a3adfc8e7ap-5,0x1.0979f3ee43321p1
+toRadians,-0x1.ef75b508090c5p-8,-0x1.bb8f05364e233p-2
+toRadians,0x1.365709f9e92dbp-5,0x1.15d4b01c6f66fp1
+toRadians,0x1.bd29cf8766e9fp-8,0x1.8e87eb1b1cb6ap-2
+toRadians,0x1.5705e9472736dp-10,0x1.331719fc9f227p-4
+toRadians,-0x1.c0f0760371a15p-5,-0x1.91e94f0aeb6fdp1
+toRadians,0x1.aa4b9d7189cd6p-11,0x1.7da3b3ce92d0bp-5
+toRadians,-0x1.e36f3239795c7p-7,-0x1.b0cafe786941p-1
+toRadians,-0x1.5d453f9711567p-6,-0x1.38aee7103062ap0
+toRadians,0x1.4f5935250958dp-9,0x1.2c3835144a6c6p-3
+toRadians,-0x1.fc315cc3236d5p-5,-0x1.c6f5372783487p1
+toRadians,-0x1.5f6f0db8815dcp-11,-0x1.3a9eb1dd80ae8p-5
+toRadians,0x1.044ced10f50cep-6,0x1.d210f4f97b4fap-1
+toRadians,-0x1.0820c249570a6p-12,-0x1.d8eb574a001cap-7
+toRadians,0x1.c0dce341827e4p-7,0x1.91d7c92de11e9p-1
+toRadians,-0x1.54c0758b47cf8p-5,-0x1.310e8efc1fc1dp1
+toRadians,-0x1.0c22f069d37e6p-6,-0x1.e018b5a31fb2cp-1
+toRadians,-0x1.0d44d90e1098cp-6,-0x1.e21fca05c552fp-1
+toRadians,0x1.aa370725bfc19p-6,0x1.7d914597b0f93p0
+toRadians,0x1.5dae1ab6a26cap-8,0x1.390cc646e30c2p-2
+toRadians,-0x1.93d8aca9afc4cp-6,-0x1.698ac60d72cfap0
+toRadians,0x1.dde50e06e847bp-8,0x1.abd568673b34cp-2
+toRadians,0x1.85367605681f8p-8,0x1.5c70fd2cabf94p-2
+toRadians,0x1.0f398ad1f05d4p-6,0x1.e5a0476d86f65p-1
+toRadians,-0x1.d61f59195aa6cp-7,-0x1.a4e02134d1a6bp-1
+toRadians,-0x1.2ea0ffdaa0e6p-6,-0x1.0eed6f92fd525p0
+toRadians,-0x1.ed05911e835b4p-7,-0x1.b96042cbd3729p-1
+toRadians,0x1.2cd0b41a46717p-3,0x1.0d4dc6ca8eaa8p3
+toRadians,0x1.381d20fe74a4p-6,0x1.176b35da6d972p0
+toRadians,-0x1.135812197a196p-5,-0x1.ed0067a8591e4p0
+toRadians,0x1.9487e02c71b95p-4,0x1.6a279f36895cap2
+toRadians,0x1.2f1b98fbb5e38p-7,0x1.0f5b3100c4226p-1
+toRadians,-0x1.df126097b8ce9p-10,-0x1.ace32a703c8p-4
+toRadians,0x1.27602746d31p-5,0x1.086f19d122d5p1
+toRadians,-0x1.6f00c2e92cd4ep-7,-0x1.488ee2ccee45dp-1
+toRadians,-0x1.6d6cad1da49f1p-8,-0x1.4725214f128bcp-2
+toRadians,0x1.53853b6e52504p-6,0x1.2ff45a46f0239p0
+toRadians,-0x1.35bedb84f10a2p-6,-0x1.154c72afce441p0
+toRadians,0x1.e5b425177b774p-8,0x1.b2d3161ad8a1fp-2
+toRadians,-0x1.0bfd2695d0ed9p-8,-0x1.dfd50cb6eb642p-3
+toRadians,0x1.9e42202419179p-7,0x1.72dd02718e33ep-1
+toRadians,0x1.91ed5a574b502p-7,0x1.67d2eb7176ee9p-1
+toRadians,0x1.88624a4753cb9p-5,0x1.5f47c6b4bedb7p1
+toRadians,-0x1.88c9a0d956ca6p-10,-0x1.5fa44a11aabe3p-4
+toRadians,-0x1.a5a8e50293634p-8,-0x1.797d4b83f869p-2
+toRadians,-0x1.aee96588d5d7ap-6,-0x1.81c5b0333bb09p0
+toRadians,-0x1.a0bb132c02b9p-7,-0x1.7513a7bf2c3eep-1
+toRadians,-0x1.159284ff767c1p-2,-0x1.f0fdca230f3f5p3
+toRadians,0x1.6ec5baab9dfccp-7,0x1.485a099e8a8a4p-1
+toRadians,-0x1.479fe44ef6b39p-4,-0x1.254e05afbfe62p2
+toRadians,0x1.0ce113f6e801dp-4,0x1.e16d26e044eb6p1
+ulp,0x1.0p-52,-0x1.9369810dd84a3p0
+ulp,0x1.0p-54,-0x1.9f2928d31e01cp-2
+ulp,0x1.0p-51,-0x1.73ea1caeccadfp1
+ulp,0x1.0p-56,-0x1.b86c6f1a71af3p-4
+ulp,0x1.0p-52,-0x1.a6ef99791510fp0
+ulp,0x1.0p-52,-0x1.5d387a9331d4bp0
+ulp,0x1.0p-51,-0x1.1e9fa73b0f17ep1
+ulp,0x1.0p-53,0x1.5ae973c9b8796p-1
+ulp,0x1.0p-52,-0x1.0442e3e3b3b79p0
+ulp,0x1.0p-53,0x1.54c946e25ac81p-1
+ulp,0x1.0p-50,-0x1.823ca7a97f04fp2
+ulp,0x1.0p-52,-0x1.2224e7e88298ep0
+ulp,0x1.0p-54,-0x1.fea5f17ff5016p-2
+ulp,0x1.0p-54,-0x1.871996754d049p-2
+ulp,0x1.0p-52,-0x1.907690c67abfbp0
+ulp,0x1.0p-53,0x1.b27d04e53486bp-1
+ulp,0x1.0p-50,-0x1.9f83f235455adp2
+ulp,0x1.0p-55,-0x1.27db0f3453088p-3
+ulp,0x1.0p-53,0x1.dcb0659fc998p-1
+ulp,0x1.0p-55,0x1.fb07cf43a2d89p-3
+ulp,0x1.0p-54,-0x1.9edeb774425ebp-2
+ulp,0x1.0p-52,0x1.1555de3dd020dp0
+ulp,0x1.0p-55,0x1.88207d030a31ep-3
+ulp,0x1.0p-55,0x1.a43d08b26be4ap-3
+ulp,0x1.0p-52,-0x1.15f5854c2bcd5p0
+ulp,0x1.0p-51,0x1.1a7ea8c3d6b39p1
+ulp,0x1.0p-51,-0x1.6f1f146ede7c2p1
+ulp,0x1.0p-51,0x1.feb1e4c4d0e41p1
+ulp,0x1.0p-53,-0x1.acf03f6287edfp-1
+ulp,0x1.0p-52,0x1.4fe731c91c69cp0
+ulp,0x1.0p-50,-0x1.e07be31b55062p2
+ulp,0x1.0p-55,0x1.dc1cf3e87e286p-3
+ulp,0x1.0p-53,-0x1.aaceaee575b18p-1
+ulp,0x1.0p-52,0x1.05f4ba3309817p0
+ulp,0x1.0p-55,-0x1.8865f997482aep-3
+ulp,0x1.0p-51,-0x1.3fefc64092de6p1
+ulp,0x1.0p-51,0x1.2719b1d2899ap1
+ulp,0x1.0p-50,-0x1.08cecb8ac651fp2
+ulp,0x1.0p-50,-0x1.2685e7840932dp2
+ulp,0x1.0p-52,-0x1.d0bd1fa84868ep0
+ulp,0x1.0p-50,0x1.bb4733e2cd111p2
+ulp,0x1.0p-53,0x1.ad427a13426a2p-1
+ulp,0x1.0p-54,0x1.5f1c41010e9dep-2
+ulp,0x1.0p-55,-0x1.2fc9edef312b5p-3
+ulp,0x1.0p-51,0x1.11242db5bd479p1
+ulp,0x1.0p-50,0x1.024f116156aeap2
+ulp,0x1.0p-52,-0x1.2f61c2afb9797p0
+ulp,0x1.0p-52,0x1.074aab47fa7bap0
+ulp,0x1.0p-52,-0x1.1e23ee7e724fp0
+ulp,0x1.0p-53,-0x1.10d1095c94562p-1
+ulp,0x1.0p-53,0x1.f797fb150a518p-1
+ulp,0x1.0p-52,-0x1.6ba40f9142b55p0
+ulp,0x1.0p-57,0x1.f6be0e1131cd9p-5
+ulp,0x1.0p-51,0x1.60936f7891dcbp1
+ulp,0x1.0p-52,0x1.76daad2da2fe2p0
+ulp,0x1.0p-52,0x1.3176325cb1721p0
+ulp,0x1.0p-55,0x1.35bfdee8919fdp-3
+ulp,0x1.0p-53,-0x1.271b0dd5cae1ap-1
+ulp,0x1.0p-56,0x1.eeb504b6dfd4ap-4
+ulp,0x1.0p-54,-0x1.62f2ea303123cp-2
+ulp,0x1.0p-53,-0x1.0b9b74d01a53p-1
+ulp,0x1.0p-54,-0x1.a25637868c8afp-2
+ulp,0x1.0p-51,0x1.4937474239c4cp1
+ulp,0x1.0p-53,-0x1.24e1d894ebd5bp-1
+ulp,0x1.0p-55,-0x1.aa1959b2ee2e7p-3
+ulp,0x1.0p-53,-0x1.519d5013ccc5ap-1
+ulp,0x1.0p-56,0x1.31cd2f93f176bp-4
+ulp,0x1.0p-53,0x1.a774c37c3fe41p-1
+ulp,0x1.0p-52,-0x1.8fd2aa3d25cf2p0
+ulp,0x1.0p-52,-0x1.0dd5221361bbfp0
+ulp,0x1.0p-54,-0x1.8e228ae1ed28ap-2
+ulp,0x1.0p-54,0x1.31010af798345p-2
+ulp,0x1.0p-55,0x1.fc20dfe30e64dp-3
+ulp,0x1.0p-49,-0x1.c2cbf5304bf0fp3
+ulp,0x1.0p-53,-0x1.599ea9e345bc3p-1
+ulp,0x1.0p-50,-0x1.5de71437e6098p2
+ulp,0x1.0p-51,-0x1.e0b06deed431ep1
+ulp,0x1.0p-53,0x1.a1c4c4cfd06e5p-1
+ulp,0x1.0p-52,0x1.af15d99cd9357p0
+ulp,0x1.0p-49,-0x1.c07b831808071p3
+ulp,0x1.0p-53,-0x1.24e1dfa1b04e1p-1
+ulp,0x1.0p-52,-0x1.0523d74000559p0
+ulp,0x1.0p-53,0x1.98227ece1cdebp-1
+ulp,0x1.0p-52,0x1.031b64f8b50bp0
+ulp,0x1.0p-50,-0x1.13e9f65198dc9p2
+ulp,0x1.0p-51,0x1.8101df83d5ff7p1
+ulp,0x1.0p-51,-0x1.5a449b9d853fbp1
+ulp,0x1.0p-52,-0x1.63b66f63b7592p0
+ulp,0x1.0p-50,-0x1.75d152f3855e4p2
+ulp,0x1.0p-52,-0x1.60b419eb80a92p0
+ulp,0x1.0p-54,0x1.0ab24d9767072p-2
+ulp,0x1.0p-56,-0x1.677f82863e19bp-4
+ulp,0x1.0p-53,-0x1.c1d83c1e436a5p-1
+ulp,0x1.0p-53,-0x1.8a192f285be71p-1
+ulp,0x1.0p-52,-0x1.52c3011b6fe09p0
+ulp,0x1.0p-49,-0x1.3076869da11dbp3
+ulp,0x1.0p-47,-0x1.62753b9029688p5
+ulp,0x1.0p-50,0x1.6d859d4adc109p2
+ulp,0x1.0p-53,0x1.e2598b488484p-1
+ulp,0x1.0p-56,-0x1.b89a9bb75880dp-4
+ulp,0x1.0p-57,-0x1.344e647fb82dbp-5
+ulp,0x1.0p-53,-0x1.3d3c417ea51c6p-1
+ulp,0x1.0p-54,0x1.f0b8097570173p-2
+ulp,0x1.0p-52,0x1.4e14e33ecdf99p0
+ulp,0x1.0p-51,0x1.1391e3bde920bp1
+ulp,0x1.0p-54,0x1.24809ab102362p-2
+ulp,0x1.0p-53,0x1.4bc9511d85d9cp-1
+ulp,0x1.0p-52,-0x1.09a22fbedba27p0
+ulp,0x1.0p-50,-0x1.a4d703650a565p2
+ulp,0x1.0p-51,-0x1.feb1e72fa3007p1
+ulp,0x1.0p-51,0x1.b01b70b420dc8p1
+ulp,0x1.0p-54,0x1.2773164ad9322p-2
+ulp,0x1.0p-52,-0x1.7502d121daceap0
+ulp,0x1.0p-53,-0x1.eae29ee9c5ef1p-1
+ulp,0x1.0p-50,-0x1.483240344459bp2
+ulp,0x1.0p-55,0x1.c0103c2efe682p-3
+ulp,0x1.0p-54,0x1.b37df0c13405p-2
+ulp,0x1.0p-53,0x1.1e5fccb8bb648p-1
+ulp,0x1.0p-52,-0x1.d6fce3c72d00dp0
+ulp,0x1.0p-52,0x1.bbbdbba0acfe1p0
+ulp,0x1.0p-50,0x1.4879b63b323bap2
+ulp,0x1.0p-51,0x1.2c7eb76edde01p1
+ulp,0x1.0p-53,-0x1.7cb31a5805664p-1
+ulp,0x1.0p-54,0x1.dff05a29b1a26p-2
+ulp,0x1.0p-51,-0x1.51dbe032b9c06p1
+ulp,0x1.0p-53,0x1.534efa559f66fp-1
+ulp,0x1.0p-53,0x1.2a916c337b64ap-1
+ulp,0x1.0p-52,-0x1.1adcf04b3064bp0
+ulp,0x1.0p-53,-0x1.568dee10a8ad9p-1
+ulp,0x1.0p-53,0x1.5442044e7c1c7p-1
+ulp,0x1.0p-46,-0x1.31ab0c728438fp6
+ulp,0x1.0p-51,-0x1.7259325752162p1
+ulp,0x1.0p-57,-0x1.1a30486920f7bp-5
+ulp,0x1.0p-51,-0x1.b16030f80babp1
+ulp,0x1.0p-54,0x1.2614558cba404p-2
+ulp,0x1.0p-51,-0x1.7d5d8217e0831p1
+ulp,0x1.0p-53,-0x1.a0f4358bb963p-1
+ulp,0x1.0p-51,-0x1.a088924c7d188p1
+ulp,0x1.0p-55,-0x1.e7f3eef54f87ap-3
+ulp,0x1.0p-50,-0x1.fe3cd0e46db73p2
+ulp,0x1.0p-54,-0x1.39983772d5ab8p-2
+ulp,0x1.0p-57,0x1.dd29df7b3f96ap-5
+ulp,0x1.0p-52,0x1.3dffeec0811f1p0
+ulp,0x1.0p-52,-0x1.d2bad5256de4p0
+ulp,0x1.0p-48,0x1.5fb78d86618a6p4
+ulp,0x1.0p-49,-0x1.5ae03318632e8p3
+ulp,0x1.0p-56,-0x1.bde7eaeb40779p-4
+ulp,0x1.0p-52,0x1.f1974828ea84p0
+ulp,0x1.0p-53,0x1.80b6f42d2bdefp-1
+ulp,0x1.0p-55,0x1.b63403d4a8bd4p-3
+ulp,0x1.0p-53,0x1.601d62621a398p-1
+ulp,0x1.0p-56,-0x1.8da30ebf2699ep-4
+ulp,0x1.0p-53,0x1.52e994b0bf5fap-1
+ulp,0x1.0p-44,0x1.68b8d3d4caec1p8
+ulp,0x1.0p-52,0x1.290206f80c1bbp0
+ulp,0x1.0p-47,-0x1.31f2eb6da1f32p5
+ulp,0x1.0p-48,0x1.2eb942192a685p4
+ulp,0x1.0p-51,0x1.4985c432f4e67p1
+ulp,0x1.0p-57,-0x1.c41bd03336427p-5
+ulp,0x1.0p-56,0x1.e05e5b77d153cp-4
+ulp,0x1.0p-50,0x1.e8e2441e1dd1bp2
+ulp,0x1.0p-51,-0x1.1d17c19fb812bp1
+ulp,0x1.0p-51,0x1.bd7d2fbe8ab71p1
+ulp,0x1.0p-53,0x1.67be4b958620dp-1
+ulp,0x1.0p-52,-0x1.3f3300c19df5bp0
+ulp,0x1.0p-52,-0x1.d474a6d231974p0
+ulp,0x1.0p-51,-0x1.b2ffcba471472p1
+ulp,0x1.0p-51,0x1.a50dfd97235aep1
+ulp,0x1.0p-52,-0x1.565eeb5a460aap0
+ulp,0x1.0p-47,0x1.ce6d570b266b2p5
+ulp,0x1.0p-52,0x1.8d85cece5190cp0
+ulp,0x1.0p-46,-0x1.1b29a95d8973p6
+ulp,0x1.0p-52,0x1.44e58ae4e0f71p0
+ulp,0x1.0p-55,-0x1.09d04981b12a3p-3
+ulp,0x1.0p-52,0x1.e135d7eb33b54p0
+ulp,0x1.0p-54,-0x1.24f0a8aa287bep-2
+ulp,0x1.0p-52,-0x1.0cca58d230b3cp0
+ulp,0x1.0p-52,-0x1.0bbdc09c44261p0
+ulp,0x1.0p-53,0x1.cc27aac8ccd2bp-1
+ulp,0x1.0p-55,0x1.849ac758f5bbap-3
+ulp,0x1.0p-52,-0x1.716751ce9b3p0
+ulp,0x1.0p-52,0x1.06d1aadc5d03fp0
+ulp,0x1.0p-51,-0x1.37c7c20ede5dp1
+ulp,0x1.0p-52,0x1.af0bc6aa67949p0
+ulp,0x1.0p-52,0x1.13e3c05223dd8p0
+ulp,0x1.0p-53,-0x1.fcfccf983f742p-1
+ulp,0x1.0p-52,0x1.2109216556897p0
+ulp,0x1.0p-58,-0x1.cf9910c8f7fb7p-6
+ulp,0x1.0p-54,-0x1.710efab54e94bp-2
+ulp,0x1.0p-52,0x1.1b38ea6942004p0
+ulp,0x1.0p-52,0x1.ed158cf170328p0
+ulp,0x1.0p-51,0x1.b52c5e8111303p1
+ulp,0x1.0p-49,-0x1.2e7f6bbcee20ep3
+ulp,0x1.0p-54,0x1.8a5fd3b9ca19ap-2
+ulp,0x1.0p-52,0x1.a6c899c30c922p0
+ulp,0x1.0p-53,0x1.afeba7ea55248p-1
+ulp,0x1.0p-53,-0x1.8ea9b89dffed6p-1
+ulp,0x1.0p-54,-0x1.efd893fe08d6fp-2
+ulp,0x1.0p-58,0x1.4b9af1ea9f96fp-6
+ulp,0x1.0p-46,0x1.1a46e5c8b221p6
diff --git a/luni/src/test/resources/math_tests.csv b/luni/src/test/resources/math_tests.csv
new file mode 100644
index 0000000..3393400
--- /dev/null
+++ b/luni/src/test/resources/math_tests.csv
@@ -0,0 +1,5199 @@
+#These tests come from the intel tests in bionic
+tan,0x1.5078cebff9c73p-5,0x1.50486b2f87014p-5
+tan,-0x1.5078cebff9c73p-5,-0x1.50486b2f87014p-5
+tan,0x1.5389e6df41979p-4,0x1.52c39ef070cadp-4
+tan,-0x1.5389e6df41979p-4,-0x1.52c39ef070cadp-4
+tan,0x1.a933fe176b375p-3,0x1.a33f32ac5ceb5p-3
+tan,-0x1.a933fe176b375p-3,-0x1.a33f32ac5ceb5p-3
+tan,0x1.fac71cd34eea7p-2,0x1.d696bfa988db9p-2
+tan,-0x1.fac71cd34eea7p-2,-0x1.d696bfa988db9p-2
+tan,0x1.7ba49f739829fp-1,0x1.46ac372243536p-1
+tan,-0x1.7ba49f739829fp-1,-0x1.46ac372243536p-1
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x1.8f048832144b7p0,-0x1.0018p0
+tan,0x1.8f048832144b7p0,0x1.0018p0
+tan,-0x1.8e884b24313afp0,-0x1.090cca18a5565p2
+tan,0x1.8e884b24313afp0,0x1.090cca18a5565p2
+tan,-0x1.ca18654b35697p0,-0x1.0faa7650df144p0
+tan,0x1.ca18654b35697p0,0x1.0faa7650df144p0
+tan,-0x1.e52fafa22ef14p-2,-0x1.180000000004p5
+tan,0x1.e52fafa22ef14p-2,0x1.180000000004p5
+tan,-0x1.a3ca421dc30f2p-3,-0x1.4000527aca388p99
+tan,0x1.a3ca421dc30f2p-3,0x1.4000527aca388p99
+tan,0x1.1f3b7d1978609p1,-0x1.486c3634751ecp2
+tan,-0x1.1f3b7d1978609p1,0x1.486c3634751ecp2
+tan,-0x1.7eb873343fa7ap-1,-0x1.48a71800b5713p-1
+tan,0x1.7eb873343fa7ap-1,0x1.48a71800b5713p-1
+tan,0x1.be071572f64e8p-1,-0x1.49af0314eea3cp299
+tan,-0x1.be071572f64e8p-1,0x1.49af0314eea3cp299
+tan,0x1.ffbb2647f57a2p-1,-0x1.5fe00c814ffd6p2
+tan,-0x1.ffbb2647f57a2p-1,0x1.5fe00c814ffd6p2
+tan,-0x1.a8eb142b2f428p-1,-0x1.62ac241f79439p-1
+tan,0x1.a8eb142b2f428p-1,0x1.62ac241f79439p-1
+tan,-0x1.7d1d3559ddac9p-4,-0x1.7c051b476ca8dp-4
+tan,0x1.7d1d3559ddac9p-4,0x1.7c051b476ca8dp-4
+tan,-0x1.0e1d0305b7b72p2,-0x1.7e43c880074c6p996
+tan,0x1.0e1d0305b7b72p2,0x1.7e43c880074c6p996
+tan,-0x1.812bdfe0246bcp-4,-0x1.800ac363398c4p-4
+tan,0x1.812bdfe0246bcp-4,0x1.800ac363398c4p-4
+tan,-0x1.850e5544b0c79p-4,-0x1.83e46aedbff36p-4
+tan,0x1.850e5544b0c79p-4,0x1.83e46aedbff36p-4
+tan,0x1.e6b5d91bba934p-2,-0x1.83ecf42e9265ap3
+tan,-0x1.e6b5d91bba934p-2,0x1.83ecf42e9265ap3
+tan,-0x1.f3688bc2594e2p-1,-0x1.8bcp-1
+tan,0x1.f3688bc2594e2p-1,0x1.8bcp-1
+tan,0x1.ec0d0facdd08bp-2,-0x1.8d2ffffffffd1p9
+tan,-0x1.ec0d0facdd08bp-2,0x1.8d2ffffffffd1p9
+tan,0x1.ec0336d539259p-2,-0x1.8d3000fffffd1p9
+tan,-0x1.ec0336d539259p-2,0x1.8d3000fffffd1p9
+tan,-0x1.f8093a017021fp-1,-0x1.baeee6f6fa538p6
+tan,0x1.f8093a017021fp-1,0x1.baeee6f6fa538p6
+tan,0x1.deaf34994b7e7p3,-0x1.c6867e07455eap3
+tan,-0x1.deaf34994b7e7p3,0x1.c6867e07455eap3
+tan,-0x1.f29aa87d4e1dep-1,-0x1.d27ffffffep7
+tan,0x1.f29aa87d4e1dep-1,0x1.d27ffffffep7
+tan,0x1.762fb47a1925ap-3,-0x1.f0df38029c9efp3
+tan,-0x1.762fb47a1925ap-3,0x1.f0df38029c9efp3
+tan,-0x1.8eb23ef2126bcp0,-0x1.fffffc0000fffp-1
+tan,0x1.8eb23ef2126bcp0,0x1.fffffc0000fffp-1
+tan,-0x1.d299d285bf018p-2,-0x1.ffffffffffffcp1023
+tan,0x1.d299d285bf018p-2,0x1.ffffffffffffcp1023
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,-0x1.82bee572e2ac9p-6,0x1.0p64
+tan,0x1.82bee572e2ac9p-6,-0x1.0p64
+tan,0x1.f53a8d05afcf7p4,0x1.0000000000001p51
+tan,-0x1.f53a8d05afcf7p4,-0x1.0000000000001p51
+tan,-0x1.6b371df5980cep-1,0x1.0000000000001p1017
+tan,0x1.6b371df5980cep-1,-0x1.0000000000001p1017
+tan,-0x1.b32e78f49a0c8p2,0x1.0000000000003p3
+tan,0x1.b32e78f49a0c8p2,-0x1.0000000000003p3
+tan,0x1.98afbd24264bcp-1,0x1.0000000000003p21
+tan,-0x1.98afbd24264bcp-1,-0x1.0000000000003p21
+tan,0x1.b667a2abe36c3p0,0x1.0000000000003p511
+tan,-0x1.b667a2abe36c3p0,-0x1.0000000000003p511
+tan,0x1.204c26a427862p-2,0x1.0000000000003p716
+tan,-0x1.204c26a427862p-2,-0x1.0000000000003p716
+tan,0x1.91c8f2938262dp4,0x1.0000000000007p8
+tan,-0x1.91c8f2938262dp4,-0x1.0000000000007p8
+tan,-0x1.27f7f0880032p-2,0x1.0000000000038p380
+tan,0x1.27f7f0880032p-2,-0x1.0000000000038p380
+tan,-0x1.d6890cc32711dp-3,0x1.0000000000118p380
+tan,0x1.d6890cc32711dp-3,-0x1.0000000000118p380
+tan,0x1.9af0e6f72f912p-3,0x1.0000000000908p500
+tan,-0x1.9af0e6f72f912p-3,-0x1.0000000000908p500
+tan,0x1.17b4f5bf44098p-1,0x1.000000000cp-1
+tan,-0x1.17b4f5bf44098p-1,-0x1.000000000cp-1
+tan,-0x1.17eb22e4dba73p0,0x1.00000001cp40
+tan,0x1.17eb22e4dba73p0,-0x1.00000001cp40
+tan,0x1.f6f03ce5690a7p-1,0x1.0000001p250
+tan,-0x1.f6f03ce5690a7p-1,-0x1.0000001p250
+tan,0x1.e23b78282a75dp-1,0x1.000000988p27
+tan,-0x1.e23b78282a75dp-1,-0x1.000000988p27
+tan,-0x1.981b657e1ca27p-3,0x1.00000cp429
+tan,0x1.981b657e1ca27p-3,-0x1.00000cp429
+tan,-0x1.455a2184f4c3ep-1,0x1.00000fcp1000
+tan,0x1.455a2184f4c3ep-1,-0x1.00000fcp1000
+tan,0x1.8ee66962f210cp0,0x1.000f371b7a006p0
+tan,-0x1.8ee66962f210cp0,-0x1.000f371b7a006p0
+tan,-0x1.ecd75cf6d4664p-3,0x1.001p15
+tan,0x1.ecd75cf6d4664p-3,-0x1.001p15
+tan,0x1.17d42033277ccp-1,0x1.0017ffffffffdp-1
+tan,-0x1.17d42033277ccp-1,-0x1.0017ffffffffdp-1
+tan,0x1.8f048832144b7p0,0x1.0018p0
+tan,-0x1.8f048832144b7p0,-0x1.0018p0
+tan,-0x1.18273cc3e7639p-2,0x1.001fffep500
+tan,0x1.18273cc3e7639p-2,-0x1.001fffep500
+tan,-0x1.d8f90cad30547p-2,0x1.018p40
+tan,0x1.d8f90cad30547p-2,-0x1.018p40
+tan,0x1.b079ea0d14a4ap-2,0x1.01b8a484ac0b6p4
+tan,-0x1.b079ea0d14a4ap-2,-0x1.01b8a484ac0b6p4
+tan,-0x1.a40c262f6ab9ap-1,0x1.026ac0ef32d4p28
+tan,0x1.a40c262f6ab9ap-1,-0x1.026ac0ef32d4p28
+tan,0x1.03b8c1f329665p-4,0x1.035fdcd08a596p-4
+tan,-0x1.03b8c1f329665p-4,-0x1.035fdcd08a596p-4
+tan,0x1.044979d134ed9p-4,0x1.03fp-4
+tan,-0x1.044979d134ed9p-4,-0x1.03fp-4
+tan,-0x1.e717de7da2ce8p0,0x1.07p1
+tan,0x1.e717de7da2ce8p0,-0x1.07p1
+tan,-0x1.8c896f607ff52p-1,0x1.07p30
+tan,0x1.8c896f607ff52p-1,-0x1.07p30
+tan,0x1.fffffffff5d84p-1,0x1.07e4cef4cbb0ep4
+tan,-0x1.fffffffff5d84p-1,-0x1.07e4cef4cbb0ep4
+tan,0x1.b476d32c1b745p0,0x1.0a53a78b13ab2p0
+tan,-0x1.b476d32c1b745p0,-0x1.0a53a78b13ab2p0
+tan,0x1.f2df7c02d20cep-1,0x1.0afbc268b9848p6
+tan,-0x1.f2df7c02d20cep-1,-0x1.0afbc268b9848p6
+tan,-0x1.b571af562f08ap0,0x1.0cd5d435bea6dp1
+tan,0x1.b571af562f08ap0,-0x1.0cd5d435bea6dp1
+tan,-0x1.ac73d2920a795p0,0x1.0ep1
+tan,0x1.ac73d2920a795p0,-0x1.0ep1
+tan,-0x1.126dce8ac7c81p-1,0x1.1086210842108p5
+tan,0x1.126dce8ac7c81p-1,-0x1.1086210842108p5
+tan,-0x1.9680c02601047p0,0x1.11p1
+tan,0x1.9680c02601047p0,-0x1.11p1
+tan,0x1.d1e716934469bp0,0x1.118p0
+tan,-0x1.d1e716934469bp0,-0x1.118p0
+tan,-0x1.6aa7310143084p-1,0x1.19df389f39e0ap3
+tan,0x1.6aa7310143084p-1,-0x1.19df389f39e0ap3
+tan,0x1.cb9a99227bdc9p1,0x1.1c3598211013ap2
+tan,-0x1.cb9a99227bdc9p1,-0x1.1c3598211013ap2
+tan,-0x1.bc109c3e61724p7,0x1.1d65aa4224c3p118
+tan,0x1.bc109c3e61724p7,-0x1.1d65aa4224c3p118
+tan,-0x1.09b393f48b2c6p-1,0x1.1e4658272dc6fp3
+tan,0x1.09b393f48b2c6p-1,-0x1.1e4658272dc6fp3
+tan,0x1.200000000007ap-22,0x1.2p-22
+tan,-0x1.200000000007ap-22,-0x1.2p-22
+tan,-0x1.02a335b00707ap0,0x1.2127409620cacp95
+tan,0x1.02a335b00707ap0,-0x1.2127409620cacp95
+tan,0x1.2508b9c1273acp-4,0x1.2489224892248p-4
+tan,-0x1.2508b9c1273acp-4,-0x1.2489224892248p-4
+tan,0x1.fded5f53d132dp2,0x1.2a52d119da061p237
+tan,-0x1.fded5f53d132dp2,-0x1.2a52d119da061p237
+tan,0x1.2de56a6ef9c5ep-4,0x1.2d59ebab8dae4p-4
+tan,-0x1.2de56a6ef9c5ep-4,-0x1.2d59ebab8dae4p-4
+tan,0x1.31665eb191fbbp-4,0x1.30d5f8e54b6d8p-4
+tan,-0x1.31665eb191fbbp-4,-0x1.30d5f8e54b6d8p-4
+tan,0x1.3cc1d4d28bfd2p-2,0x1.333275d63ec5p-2
+tan,-0x1.3cc1d4d28bfd2p-2,-0x1.333275d63ec5p-2
+tan,0x1.3cc237c0c7dccp-2,0x1.3332d020b6da9p-2
+tan,-0x1.3cc237c0c7dccp-2,-0x1.3332d020b6da9p-2
+tan,0x1.5e472e16999dfp-1,0x1.333333401e66bp-1
+tan,-0x1.5e472e16999dfp-1,-0x1.333333401e66bp-1
+tan,0x1.b5ed1c2080a98p-1,0x1.38f137cb9dbfcp9
+tan,-0x1.b5ed1c2080a98p-1,-0x1.38f137cb9dbfcp9
+tan,0x1.01aa22e2133d4p1,0x1.39a383f3fa003p85
+tan,-0x1.01aa22e2133d4p1,-0x1.39a383f3fa003p85
+tan,0x1.ffffffffff582p-1,0x1.3a28c59d54311p4
+tan,-0x1.ffffffffff582p-1,-0x1.3a28c59d54311p4
+tan,0x1.7166689d4803fp-1,0x1.4000000003fffp-1
+tan,-0x1.7166689d4803fp-1,-0x1.4000000003fffp-1
+tan,-0x1.ff7d27b37eba1p-1,0x1.40724a44714cfp5
+tan,0x1.ff7d27b37eba1p-1,-0x1.40724a44714cfp5
+tan,0x1.453a7d29dadadp-4,0x1.448c2d6e1e1afp-4
+tan,-0x1.453a7d29dadadp-4,-0x1.448c2d6e1e1afp-4
+tan,-0x1.a50f7601413e5p0,0x1.478fc08p43
+tan,0x1.a50f7601413e5p0,-0x1.478fc08p43
+tan,-0x1.a9991acb7636cp-4,0x1.4e93bee72b565p62
+tan,0x1.a9991acb7636cp-4,-0x1.4e93bee72b565p62
+tan,0x1.2952396945948p1,0x1.4f0f308p488
+tan,-0x1.2952396945948p1,-0x1.4f0f308p488
+tan,0x1.5078cebff9c73p-5,0x1.50486b2f87014p-5
+tan,-0x1.5078cebff9c73p-5,-0x1.50486b2f87014p-5
+tan,-0x1.1c929b6ede9eep-1,0x1.5130d552f1036p1
+tan,0x1.1c929b6ede9eep-1,-0x1.5130d552f1036p1
+tan,0x1.2ab3189e2d4aep1,0x1.52f00ep793
+tan,-0x1.2ab3189e2d4aep1,-0x1.52f00ep793
+tan,-0x1.7d2e63fb98891p0,0x1.5371684e5fb34p2
+tan,0x1.7d2e63fb98891p0,-0x1.5371684e5fb34p2
+tan,-0x1.f9f4f0da4de54p-1,0x1.54ef2208956p239
+tan,0x1.f9f4f0da4de54p-1,-0x1.54ef2208956p239
+tan,0x1.1483073142e6p2,0x1.57e590af09014p0
+tan,-0x1.1483073142e6p2,-0x1.57e590af09014p0
+tan,0x1.9972d4021c972p-1,0x1.596p-1
+tan,-0x1.9972d4021c972p-1,-0x1.596p-1
+tan,-0x1.e501ffd3a68c4p-2,0x1.5981293783e1fp1
+tan,0x1.e501ffd3a68c4p-2,-0x1.5981293783e1fp1
+tan,0x1.1604cc3dfc418p-1,0x1.5bea01p468
+tan,-0x1.1604cc3dfc418p-1,-0x1.5bea01p468
+tan,-0x1.f76ca50bbbaebp-1,0x1.60661c1969666p2
+tan,0x1.f76ca50bbbaebp-1,-0x1.60661c1969666p2
+tan,0x1.cd8b73c9430ffp0,0x1.62c5a850a142ap59
+tan,-0x1.cd8b73c9430ffp0,-0x1.62c5a850a142ap59
+tan,0x1.3accfd453ee67p0,0x1.64ef438p142
+tan,-0x1.3accfd453ee67p0,-0x1.64ef438p142
+tan,-0x1.acd9302d72de4p-1,0x1.658p2
+tan,0x1.acd9302d72de4p-1,-0x1.658p2
+tan,0x1.f004f875c2e74p-1,0x1.6603c65d348d2p5
+tan,-0x1.f004f875c2e74p-1,-0x1.6603c65d348d2p5
+tan,0x1.f53496e6d7f72p-1,0x1.660e6bf2e092ap5
+tan,-0x1.f53496e6d7f72p-1,-0x1.660e6bf2e092ap5
+tan,0x1.b64ee24f0119cp-1,0x1.6a8p-1
+tan,-0x1.b64ee24f0119cp-1,-0x1.6a8p-1
+tan,-0x1.d9ba9a7975636p60,0x1.6ac5b262ca1ffp849
+tan,0x1.d9ba9a7975636p60,-0x1.6ac5b262ca1ffp849
+tan,0x1.b6f557b999e23p-1,0x1.6aep-1
+tan,-0x1.b6f557b999e23p-1,-0x1.6aep-1
+tan,0x1.c1e1d5c4c0f08p-1,0x1.6cdb36cdb36c9p239
+tan,-0x1.c1e1d5c4c0f08p-1,-0x1.6cdb36cdb36c9p239
+tan,0x1.95bce4f578698p-1,0x1.6f1af1612270ap6
+tan,-0x1.95bce4f578698p-1,-0x1.6f1af1612270ap6
+tan,0x1.711e8f5fffba2p-4,0x1.702p-4
+tan,-0x1.711e8f5fffba2p-4,-0x1.702p-4
+tan,0x1.fb5898f29bb26p2,0x1.72p0
+tan,-0x1.fb5898f29bb26p2,-0x1.72p0
+tan,-0x1.ff9b771284d23p1,0x1.7348c347ddc2p239
+tan,0x1.ff9b771284d23p1,-0x1.7348c347ddc2p239
+tan,0x1.f72d47a0080e3p-2,0x1.739ce739ce738p100
+tan,-0x1.f72d47a0080e3p-2,-0x1.739ce739ce738p100
+tan,0x1.76441e7f8ea6p-4,0x1.753acc3d3ff35p-4
+tan,-0x1.76441e7f8ea6p-4,-0x1.753acc3d3ff35p-4
+tan,0x1.ce3f642e15af4p-1,0x1.77fffffffffffp-1
+tan,-0x1.ce3f642e15af4p-1,-0x1.77fffffffffffp-1
+tan,0x1.f425002a548ebp42,0x1.78fdb9effea26p4
+tan,-0x1.f425002a548ebp42,-0x1.78fdb9effea26p4
+tan,-0x1.dbc80de7dd043p-1,0x1.7a5f74607e851p19
+tan,0x1.dbc80de7dd043p-1,-0x1.7a5f74607e851p19
+tan,0x1.7b3bb3d0b3ca4p42,0x1.7f7ef77e83f1ap19
+tan,-0x1.7b3bb3d0b3ca4p42,-0x1.7f7ef77e83f1ap19
+tan,0x1.e7f05b71cd2d1p33,0x1.7f7f10a07f45ep20
+tan,-0x1.e7f05b71cd2d1p33,-0x1.7f7f10a07f45ep20
+tan,0x1.8000000000004p-25,0x1.7ffffffffffffp-25
+tan,-0x1.8000000000004p-25,-0x1.7ffffffffffffp-25
+tan,0x1.8000000000007p-25,0x1.8000000000002p-25
+tan,-0x1.8000000000007p-25,-0x1.8000000000002p-25
+tan,0x1.24245af4cd995p-52,0x1.81ae0dffa3b33p959
+tan,-0x1.24245af4cd995p-52,-0x1.81ae0dffa3b33p959
+tan,0x1.d72261d98e26cp-1,0x1.846bd7a4dce55p698
+tan,-0x1.d72261d98e26cp-1,-0x1.846bd7a4dce55p698
+tan,0x1.42d8a1ba441adp1,0x1.8720588p392
+tan,-0x1.42d8a1ba441adp1,-0x1.8720588p392
+tan,0x1.ea7b444cd798ep-1,0x1.8722a67ea14acp-1
+tan,-0x1.ea7b444cd798ep-1,-0x1.8722a67ea14acp-1
+tan,-0x1.c7dc7f08dbbap-1,0x1.89936c8828d38p299
+tan,0x1.c7dc7f08dbbap-1,-0x1.89936c8828d38p299
+tan,0x1.569653e319bbap1,0x1.8a69106fb9798p6
+tan,-0x1.569653e319bbap1,-0x1.8a69106fb9798p6
+tan,0x1.f2db21469f3d6p-1,0x1.8b777e1d2308cp-1
+tan,-0x1.f2db21469f3d6p-1,-0x1.8b777e1d2308cp-1
+tan,0x1.f3688bc2594e2p-1,0x1.8bcp-1
+tan,-0x1.f3688bc2594e2p-1,-0x1.8bcp-1
+tan,0x1.8d3a2544566dfp-4,0x1.8bfd2274d851ap-4
+tan,-0x1.8d3a2544566dfp-4,-0x1.8bfd2274d851ap-4
+tan,0x1.f4575cc4e477fp-1,0x1.8c3a450071dd9p-1
+tan,-0x1.f4575cc4e477fp-1,-0x1.8c3a450071dd9p-1
+tan,-0x1.1e09f66c4250cp11,0x1.8cc0dd2b0f4b8p200
+tan,0x1.1e09f66c4250cp11,-0x1.8cc0dd2b0f4b8p200
+tan,0x1.f71496cb921e6p-1,0x1.8dap-1
+tan,-0x1.f71496cb921e6p-1,-0x1.8dap-1
+tan,0x1.f71b4a659116ap-1,0x1.8da368da368d8p-1
+tan,-0x1.f71b4a659116ap-1,-0x1.8da368da368d8p-1
+tan,0x1.ff9b68ccadb3p-1,0x1.91ed64b977a9ap-1
+tan,-0x1.ff9b68ccadb3p-1,-0x1.91ed64b977a9ap-1
+tan,0x1.0000000029048p18,0x1.921f754442d19p0
+tan,-0x1.0000000029048p18,-0x1.921f754442d19p0
+tan,0x1.eef067afd328fp48,0x1.921fb54442d1p0
+tan,-0x1.eef067afd328fp48,-0x1.921fb54442d1p0
+tan,0x1.0000000003af3p-17,0x1.921ff54442d18p1
+tan,-0x1.0000000003af3p-17,-0x1.921ff54442d18p1
+tan,-0x1.b6772cb667dc2p17,0x1.922p0
+tan,0x1.b6772cb667dc2p17,-0x1.922p0
+tan,-0x1.fffffffceeefep-1,0x1.922071c31fc99p20
+tan,0x1.fffffffceeefep-1,-0x1.922071c31fc99p20
+tan,0x1.9d7c1354ba6f8p-3,0x1.97fffffffffffp-3
+tan,-0x1.9d7c1354ba6f8p-3,-0x1.97fffffffffffp-3
+tan,0x1.9af8877bb45e4p-4,0x1.999999a10a13cp-4
+tan,-0x1.9af8877bb45e4p-4,-0x1.999999a10a13cp-4
+tan,-0x1.b6ce128587cdp4,0x1.9b74446ed05dcp0
+tan,0x1.b6ce128587cdp4,-0x1.9b74446ed05dcp0
+tan,0x1.ff65aef54c8fcp-1,0x1.9eae494d2b275p4
+tan,-0x1.ff65aef54c8fcp-1,-0x1.9eae494d2b275p4
+tan,0x1.61776aa407a44p-3,0x1.a8p1
+tan,-0x1.61776aa407a44p-3,-0x1.a8p1
+tan,0x1.b6001de13ad96p-3,0x1.af8p-3
+tan,-0x1.b6001de13ad96p-3,-0x1.af8p-3
+tan,0x1.b5a0503ae354bp-4,0x1.b3f8ea7b1f91bp-4
+tan,-0x1.b5a0503ae354bp-4,-0x1.b3f8ea7b1f91bp-4
+tan,0x1.b5a0503ae4c7bp-4,0x1.b3f8ea7b21008p-4
+tan,-0x1.b5a0503ae4c7bp-4,-0x1.b3f8ea7b21008p-4
+tan,0x1.057584c429b3ap59,0x1.b951f1572eba5p23
+tan,-0x1.057584c429b3ap59,-0x1.b951f1572eba5p23
+tan,-0x1.9a282fa1ff7dap2,0x1.b9cp0
+tan,0x1.9a282fa1ff7dap2,-0x1.b9cp0
+tan,-0x1.027d184afb198p-52,0x1.bab62ed655019p970
+tan,0x1.027d184afb198p-52,-0x1.bab62ed655019p970
+tan,0x1.ca6efdf845d6dp2,0x1.bea1b35f3cb6dp84
+tan,-0x1.ca6efdf845d6dp2,-0x1.bea1b35f3cb6dp84
+tan,0x1.fd87b34747b74p42,0x1.c463abeccb27bp3
+tan,-0x1.fd87b34747b74p42,-0x1.c463abeccb27bp3
+tan,0x1.ffffffffffffbp-1,0x1.c463abeccb2bbp2
+tan,-0x1.ffffffffffffbp-1,-0x1.c463abeccb2bbp2
+tan,0x1.fb057029acfd2p-1,0x1.c6cbe26b7b45fp86
+tan,-0x1.fb057029acfd2p-1,-0x1.c6cbe26b7b45fp86
+tan,0x1.c8d5a08be40c2p-117,0x1.c8d5a08be40c2p-117
+tan,-0x1.c8d5a08be40c2p-117,-0x1.c8d5a08be40c2p-117
+tan,0x1.e5dffd7f06cb3p-2,0x1.cad4e9827a2bep1
+tan,-0x1.e5dffd7f06cb3p-2,-0x1.cad4e9827a2bep1
+tan,0x1.e6be378b1b4ecp-2,0x1.caeb940e4b997p1
+tan,-0x1.e6be378b1b4ecp-2,-0x1.caeb940e4b997p1
+tan,0x1.e72bd025a1fd6p-2,0x1.caf6c04ecd034p1
+tan,-0x1.e72bd025a1fd6p-2,-0x1.caf6c04ecd034p1
+tan,0x1.e844b3d7cbe44p-2,0x1.cb135ec1c956ep1
+tan,-0x1.e844b3d7cbe44p-2,-0x1.cb135ec1c956ep1
+tan,0x1.dd38a1f1d289bp-54,0x1.cb44e86bc192bp648
+tan,-0x1.dd38a1f1d289bp-54,-0x1.cb44e86bc192bp648
+tan,0x1.dd38a1f1d289bp-53,0x1.cb44e86bc192bp649
+tan,-0x1.dd38a1f1d289bp-53,-0x1.cb44e86bc192bp649
+tan,-0x1.fff6e755320edp1,0x1.cb61afedb2b3cp119
+tan,0x1.fff6e755320edp1,-0x1.cb61afedb2b3cp119
+tan,0x1.ccdf4aa6c229p-7,0x1.ccd7834ba3804p-7
+tan,-0x1.ccdf4aa6c229p-7,-0x1.ccd7834ba3804p-7
+tan,0x1.cee50016fc2d9p-4,0x1.ccf0599da478ep-4
+tan,-0x1.cee50016fc2d9p-4,-0x1.ccf0599da478ep-4
+tan,0x1.44cf3ee8a75a8p0,0x1.ce8p-1
+tan,-0x1.44cf3ee8a75a8p0,-0x1.ce8p-1
+tan,0x1.45aa12ff98152p0,0x1.cf276c9cb9afp-1
+tan,-0x1.45aa12ff98152p0,-0x1.cf276c9cb9afp-1
+tan,0x1.f9bc744f61e0fp-4,0x1.d2e979148a458p61
+tan,-0x1.f9bc744f61e0fp-4,-0x1.d2e979148a458p61
+tan,0x1.6e70f9edbd1ap-2,0x1.d6b5ad6b5ab68p100
+tan,-0x1.6e70f9edbd1ap-2,-0x1.d6b5ad6b5ab68p100
+tan,0x1.13e9c6a348e4ap2,0x1.d96e058p488
+tan,-0x1.13e9c6a348e4ap2,-0x1.d96e058p488
+tan,-0x1.d355463c23036p-5,0x1.dd10f25171bc9p5
+tan,0x1.d355463c23036p-5,-0x1.dd10f25171bc9p5
+tan,0x1.ddf21ebf6fc93p-6,0x1.ddcf6e56696a4p-6
+tan,-0x1.ddf21ebf6fc93p-6,-0x1.ddcf6e56696a4p-6
+tan,0x1.5cb0bfc1558p0,0x1.ep-1
+tan,-0x1.5cb0bfc1558p0,-0x1.ep-1
+tan,-0x1.97b5e8ae9a21dp1,0x1.ep0
+tan,0x1.97b5e8ae9a21dp1,-0x1.ep0
+tan,-0x1.f8bf68d0c23f3p0,0x1.e779de779de71p118
+tan,0x1.f8bf68d0c23f3p0,-0x1.e779de779de71p118
+tan,-0x1.fffffffffd71dp-1,0x1.eb0567bed1f71p12
+tan,0x1.fffffffffd71dp-1,-0x1.eb0567bed1f71p12
+tan,0x1.ee788d1cc7955p-4,0x1.ec16f30a34fbcp-4
+tan,-0x1.ee788d1cc7955p-4,-0x1.ec16f30a34fbcp-4
+tan,0x1.efdad938b4b0fp-4,0x1.ed7424ba2aa4ep-4
+tan,-0x1.efdad938b4b0fp-4,-0x1.ed7424ba2aa4ep-4
+tan,0x1.da347607948f4p-1,0x1.ee9eda589039p499
+tan,-0x1.da347607948f4p-1,-0x1.ee9eda589039p499
+tan,0x1.f682d27a8be88p0,0x1.f4ff0d7b3ac1p100
+tan,-0x1.f682d27a8be88p0,-0x1.f4ff0d7b3ac1p100
+tan,-0x1.ffd36a753ced9p-1,0x1.f5a814afd69f5p119
+tan,0x1.ffd36a753ced9p-1,-0x1.f5a814afd69f5p119
+tan,-0x1.0fa7701d059b5p-9,0x1.f8fc824d2693bp61
+tan,0x1.0fa7701d059b5p-9,-0x1.f8fc824d2693bp61
+tan,-0x1.afe3875bd3afep-4,0x1.f9be6f9be6f98p9
+tan,0x1.afe3875bd3afep-4,-0x1.f9be6f9be6f98p9
+tan,0x1.fd1032e82deabp-4,0x1.fa775cd264f43p-4
+tan,-0x1.fd1032e82deabp-4,-0x1.fa775cd264f43p-4
+tan,0x1.fea8c67dd46cbp-4,0x1.fc09b47402d82p-4
+tan,-0x1.fea8c67dd46cbp-4,-0x1.fc09b47402d82p-4
+tan,-0x1.9020caf18a874p-1,0x1.feeffffffffc6p995
+tan,0x1.9020caf18a874p-1,-0x1.feeffffffffc6p995
+tan,0x1.af135beb0f281p0,0x1.ff01fffffffffp7
+tan,-0x1.af135beb0f281p0,-0x1.ff01fffffffffp7
+tan,-0x1.fd97532efd89bp3,0x1.ff8ffffffffffp540
+tan,0x1.fd97532efd89bp3,-0x1.ff8ffffffffffp540
+tan,-0x1.cc32cb9338181p-1,0x1.ff8ffffffffffp870
+tan,0x1.cc32cb9338181p-1,-0x1.ff8ffffffffffp870
+tan,-0x1.8659d3e2b52b8p-1,0x1.ffc1p9
+tan,0x1.8659d3e2b52b8p-1,-0x1.ffc1p9
+tan,-0x1.b66066fb812eep-2,0x1.ffcfff8p19
+tan,0x1.b66066fb812eep-2,-0x1.ffcfff8p19
+tan,-0x1.520ebd32e1d8fp1,0x1.ffcfff8p365
+tan,0x1.520ebd32e1d8fp1,-0x1.ffcfff8p365
+tan,0x1.489813c24d13bp0,0x1.ffcffffffff6cp720
+tan,-0x1.489813c24d13bp0,-0x1.ffcffffffff6cp720
+tan,0x1.413e63f7dd608p0,0x1.ffcfffffffff9p320
+tan,-0x1.413e63f7dd608p0,-0x1.ffcfffffffff9p320
+tan,-0x1.fc3928a39b652p-2,0x1.ffcffffffffffp990
+tan,0x1.fc3928a39b652p-2,-0x1.ffcffffffffffp990
+tan,-0x1.9ad70d284f16ep-1,0x1.ffeffffffffccp995
+tan,0x1.9ad70d284f16ep-1,-0x1.ffeffffffffccp995
+tan,0x1.aad6effcb6784p-3,0x1.ffefffffffffdp366
+tan,-0x1.aad6effcb6784p-3,-0x1.ffefffffffffdp366
+tan,0x1.c88645f9d119fp2,0x1.ffeffffffffffp180
+tan,-0x1.c88645f9d119fp2,-0x1.ffeffffffffffp180
+tan,0x1.131aa7b9d4aap2,0x1.ffeffffffffffp231
+tan,-0x1.131aa7b9d4aap2,-0x1.ffeffffffffffp231
+tan,0x1.f671719be50d2p-3,0x1.ffeffffffffffp1019
+tan,-0x1.f671719be50d2p-3,-0x1.ffeffffffffffp1019
+tan,0x1.ff078a2d2d872p-1,0x1.fff1fffffffffp40
+tan,-0x1.ff078a2d2d872p-1,-0x1.fff1fffffffffp40
+tan,0x1.0784b04fc42a6p9,0x1.fff1fffffffffp41
+tan,-0x1.0784b04fc42a6p9,-0x1.fff1fffffffffp41
+tan,0x1.8eb22dd167a37p0,0x1.fffff1fffffffp-1
+tan,-0x1.8eb22dd167a37p0,-0x1.fffff1fffffffp-1
+tan,-0x1.22e7346fd3ddap1,0x1.ffffff8p119
+tan,0x1.22e7346fd3ddap1,-0x1.ffffff8p119
+tan,-0x1.db0b3b019f176p-3,0x1.ffffff8p192
+tan,0x1.db0b3b019f176p-3,-0x1.ffffff8p192
+tan,0x1.06b6bede91026p-1,0x1.ffffff8p543
+tan,-0x1.06b6bede91026p-1,-0x1.ffffff8p543
+tan,-0x1.40f02a15dfa3dp1,0x1.ffffffffbbfffp40
+tan,0x1.40f02a15dfa3dp1,-0x1.ffffffffbbfffp40
+tan,0x1.ab60112ef4fdep-2,0x1.fffffffff7fffp231
+tan,-0x1.ab60112ef4fdep-2,-0x1.fffffffff7fffp231
+tan,0x1.35a9929eeafd7p0,0x1.fffffffffff78p920
+tan,-0x1.35a9929eeafd7p0,-0x1.fffffffffff78p920
+tan,0x1.4630298f3b993p0,0x1.fffffffffffd5p995
+tan,-0x1.4630298f3b993p0,-0x1.fffffffffffd5p995
+tan,-0x1.9472e045129fep-1,0x1.fffffffffffe8p720
+tan,0x1.9472e045129fep-1,-0x1.fffffffffffe8p720
+tan,0x1.42e586daa1b42p0,0x1.fffffffffffebp920
+tan,-0x1.42e586daa1b42p0,-0x1.fffffffffffebp920
+tan,-0x1.bfc436b94374cp-1,0x1.ffffffffffff1p245
+tan,0x1.bfc436b94374cp-1,-0x1.ffffffffffff1p245
+tan,0x1.35117d4a4f1e5p0,0x1.ffffffffffff4p845
+tan,-0x1.35117d4a4f1e5p0,-0x1.ffffffffffff4p845
+tan,-0x1.bfdd9292798aap-1,0x1.ffffffffffff4p1020
+tan,0x1.bfdd9292798aap-1,-0x1.ffffffffffff4p1020
+tan,-0x1.9b768ccdae6ecp9,0x1.ffffffffffffcp45
+tan,0x1.9b768ccdae6ecp9,-0x1.ffffffffffffcp45
+tan,0x1.feca047f2730fp-1,0x1.ffffffffffffcp474
+tan,-0x1.feca047f2730fp-1,-0x1.ffffffffffffcp474
+tan,-0x1.449f15cc94559p-2,0x1.ffffffffffffcp976
+tan,0x1.449f15cc94559p-2,-0x1.ffffffffffffcp976
+tan,0x1.fffc58da07952p-2,0x1.ffffffffffffep881
+tan,-0x1.fffc58da07952p-2,-0x1.ffffffffffffep881
+tan,-0x1.c1c9195ec23aap-1,0x1.ffffffffffffep970
+tan,0x1.c1c9195ec23aap-1,-0x1.ffffffffffffep970
+tan,0x1.3cc1ed3906d2fp-2,0x1.33328c1b37321p-2
+tan,-0x1.3cc1ed3906d2fp-2,-0x1.33328c1b37321p-2
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x0.0p0,-0x0.0p0
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,-0x1.0000000000001p-1022,-0x1.0000000000001p-1022
+tan,0x1.0000000000001p-1022,0x1.0000000000001p-1022
+tan,-0x1.0p-1022,-0x1.0p-1022
+tan,0x1.0p-1022,0x1.0p-1022
+tan,-0x0.fffffffffffffp-1022,-0x0.fffffffffffffp-1022
+tan,0x0.fffffffffffffp-1022,0x0.fffffffffffffp-1022
+tan,0x0.fffffffffffffp-1022,0x0.fffffffffffffp-1022
+tan,-0x0.fffffffffffffp-1022,-0x0.fffffffffffffp-1022
+tan,0x1.0p-1022,0x1.0p-1022
+tan,-0x1.0p-1022,-0x1.0p-1022
+tan,0x1.0000000000001p-1022,0x1.0000000000001p-1022
+tan,-0x1.0000000000001p-1022,-0x1.0000000000001p-1022
+tan,0x1.999999f0fb38cp-13,0x1.999999999999ap-13
+tan,-0x1.999999f0fb38cp-13,-0x1.999999999999ap-13
+tan,0x1.99999af720174p-12,0x1.999999999999ap-12
+tan,-0x1.99999af720174p-12,-0x1.999999999999ap-12
+tan,0x1.33333581062a4p-11,0x1.3333333333334p-11
+tan,-0x1.33333581062a4p-11,-0x1.3333333333334p-11
+tan,0x1.99999f0fb3a1p-11,0x1.999999999999ap-11
+tan,-0x1.99999f0fb3a1p-11,-0x1.999999999999ap-11
+tan,0x1.0000055555777p-10,0x1.0p-10
+tan,-0x1.0000055555777p-10,-0x1.0p-10
+tan,0x1.33333c6a7f4ecp-10,0x1.3333333333333p-10
+tan,-0x1.33333c6a7f4ecp-10,-0x1.3333333333333p-10
+tan,0x1.66667508e0a1bp-10,0x1.6666666666666p-10
+tan,-0x1.66667508e0a1bp-10,-0x1.6666666666666p-10
+tan,0x1.9999af7202c36p-10,0x1.9999999999999p-10
+tan,-0x1.9999af7202c36p-10,-0x1.9999999999999p-10
+tan,0x1.ccccebe76f103p-10,0x1.cccccccccccccp-10
+tan,-0x1.ccccebe76f103p-10,-0x1.cccccccccccccp-10
+tan,0x1.0667d5fcf3d08p-7,0x1.0666666666666p-7
+tan,-0x1.0667d5fcf3d08p-7,-0x1.0666666666666p-7
+tan,0x1.ccd4939d0ccd7p-7,0x1.cccccccccccccp-7
+tan,-0x1.ccd4939d0ccd7p-7,-0x1.cccccccccccccp-7
+tan,0x1.49a4fc02ad194p-6,0x1.4999999999999p-6
+tan,-0x1.49a4fc02ad194p-6,-0x1.4999999999999p-6
+tan,0x1.ace5ded5f6be7p-6,0x1.accccccccccccp-6
+tan,-0x1.ace5ded5f6be7p-6,-0x1.accccccccccccp-6
+tan,0x1.081767fd3cb68p-5,0x1.08p-5
+tan,-0x1.081767fd3cb68p-5,-0x1.08p-5
+tan,0x1.39c0d6dea66fbp-5,0x1.399999999999ap-5
+tan,-0x1.39c0d6dea66fbp-5,-0x1.399999999999ap-5
+tan,0x1.6b702b954bc1dp-5,0x1.6b33333333334p-5
+tan,-0x1.6b702b954bc1dp-5,-0x1.6b33333333334p-5
+tan,0x1.9d265618dd0c7p-5,0x1.9cccccccccccep-5
+tan,-0x1.9d265618dd0c7p-5,-0x1.9cccccccccccep-5
+tan,0x1.cee446e4cfd4cp-5,0x1.ce66666666666p-5
+tan,-0x1.cee446e4cfd4cp-5,-0x1.ce66666666666p-5
+tan,0x1.a1eaedd5a4314p-1,0x1.5e7fc4369bdadp-1
+tan,-0x1.a1eaedd5a4314p-1,-0x1.5e7fc4369bdadp-1
+tan,0x1.d93b8aad424dep1,0x1.4e7fc4369bdadp0
+tan,-0x1.d93b8aad424dep1,-0x1.4e7fc4369bdadp0
+tan,-0x1.563acf158c2ebp1,0x1.edbfa651e9c84p0
+tan,0x1.563acf158c2ebp1,-0x1.edbfa651e9c84p0
+tan,-0x1.576b77609f089p-1,0x1.467fc4369bdadp1
+tan,0x1.576b77609f089p-1,-0x1.467fc4369bdadp1
+tan,0x1.00155777aebf7p-5,0x1.961fb54442d18p1
+tan,-0x1.00155777aebf7p-5,-0x1.961fb54442d18p1
+tan,0x1.87e9966e7d22dp-1,0x1.e5bfa651e9c83p1
+tan,-0x1.87e9966e7d22dp-1,-0x1.e5bfa651e9c83p1
+tan,0x1.a49e7d8987851p1,0x1.1aafcbafc85f7p2
+tan,-0x1.a49e7d8987851p1,-0x1.1aafcbafc85f7p2
+tan,-0x1.79ced8156d041p1,0x1.427fc4369bdadp2
+tan,0x1.79ced8156d041p1,-0x1.427fc4369bdadp2
+tan,-0x1.6f1f65cd1e91bp-1,0x1.6a4fbcbd6f562p2
+tan,0x1.6f1f65cd1e91bp-1,-0x1.6a4fbcbd6f562p2
+tan,-0x1.67747d5f844e2p-1,0x1.6af2eff0a2896p2
+tan,0x1.67747d5f844e2p-1,-0x1.6af2eff0a2896p2
+tan,-0x1.626a258815d18p1,0x1.43c62a9d02414p2
+tan,0x1.626a258815d18p1,-0x1.43c62a9d02414p2
+tan,0x1.d6adaf80f8b05p1,0x1.1c99654961f92p2
+tan,-0x1.d6adaf80f8b05p1,-0x1.1c99654961f92p2
+tan,0x1.a94d1b21370d5p-1,0x1.ead93feb8361fp1
+tan,-0x1.a94d1b21370d5p-1,-0x1.ead93feb8361fp1
+tan,0x1.4cba9e7822234p-4,0x1.9c7fb54442d1ap1
+tan,-0x1.4cba9e7822234p-4,-0x1.9c7fb54442d1ap1
+tan,-0x1.2cb6d02634532p-1,0x1.4e262a9d02415p1
+tan,0x1.2cb6d02634532p-1,-0x1.4e262a9d02415p1
+tan,-0x1.18d9112308d5bp1,0x1.ff993feb8362p0
+tan,0x1.18d9112308d5bp1,-0x1.ff993feb8362p0
+tan,0x1.56fe0145cf29p2,0x1.62e62a9d02416p0
+tan,-0x1.56fe0145cf29p2,-0x1.62e62a9d02416p0
+tan,0x1.f4ad353aca454p-1,0x1.8c662a9d02419p-1
+tan,-0x1.f4ad353aca454p-1,-0x1.8c662a9d02419p-1
+tan,0x1.6a7e1f6407ee6p3,-0x1.a8aa1d11c44ffp0
+tan,-0x1.6a7e1f6407ee6p3,0x1.a8aa1d11c44ffp0
+tan,0x1.0d718cfc82464p6,-0x1.95ec8b9e03d54p0
+tan,-0x1.0d718cfc82464p6,0x1.95ec8b9e03d54p0
+tan,-0x1.11d87146c2d5ap4,-0x1.832efa2a435a9p0
+tan,0x1.11d87146c2d5ap4,0x1.832efa2a435a9p0
+tan,-0x1.e3a3729b3e86ep2,-0x1.707168b682dfep0
+tan,0x1.e3a3729b3e86ep2,0x1.707168b682dfep0
+tan,-0x1.3429e61a5d1f3p2,-0x1.5db3d742c2653p0
+tan,0x1.3429e61a5d1f3p2,0x1.5db3d742c2653p0
+tan,-0x1.c08caec5cf997p1,-0x1.4af645cf01ea8p0
+tan,0x1.c08caec5cf997p1,0x1.4af645cf01ea8p0
+tan,-0x1.5d603d751767fp1,-0x1.3838b45b416fdp0
+tan,0x1.5d603d751767fp1,0x1.3838b45b416fdp0
+tan,-0x1.1b48a35b1b278p1,-0x1.257b22e780f52p0
+tan,0x1.1b48a35b1b278p1,0x1.257b22e780f52p0
+tan,-0x1.d74caf9912dc8p0,-0x1.12bd9173c07abp0
+tan,0x1.d74caf9912dc8p0,0x1.12bd9173c07abp0
+tan,-0x1.6be702e1f6cd6p0,-0x1.ea5c3ed5b385p-1
+tan,0x1.6be702e1f6cd6p0,0x1.ea5c3ed5b385p-1
+tan,-0x1.4d0df1fc1d348p0,-0x1.d4b87dab670ap-1
+tan,0x1.4d0df1fc1d348p0,0x1.d4b87dab670ap-1
+tan,-0x1.316c8b068a7afp0,-0x1.bf14bc811a8fp-1
+tan,0x1.316c8b068a7afp0,0x1.bf14bc811a8fp-1
+tan,-0x1.1872a1aaa7e27p0,-0x1.a970fb56ce14p-1
+tan,0x1.1872a1aaa7e27p0,0x1.a970fb56ce14p-1
+tan,-0x1.01aeeed04cbb1p0,-0x1.93cd3a2c8199p-1
+tan,0x1.01aeeed04cbb1p0,0x1.93cd3a2c8199p-1
+tan,-0x1.d98e408ac2086p-1,-0x1.7e297902351ep-1
+tan,0x1.d98e408ac2086p-1,0x1.7e297902351ep-1
+tan,-0x1.b2e4750631c54p-1,-0x1.6885b7d7e8a3p-1
+tan,0x1.b2e4750631c54p-1,0x1.6885b7d7e8a3p-1
+tan,-0x1.8ee916392e046p-1,-0x1.52e1f6ad9c28p-1
+tan,0x1.8ee916392e046p-1,0x1.52e1f6ad9c28p-1
+tan,-0x1.6d395e495f77ep-1,-0x1.3d3e35834fadp-1
+tan,0x1.6d395e495f77ep-1,0x1.3d3e35834fadp-1
+tan,-0x1.24e3e017a098fp-1,-0x1.0a0b02501c799p-1
+tan,0x1.24e3e017a098fp-1,0x1.0a0b02501c799p-1
+tan,-0x1.fdbd5f0596bdcp-2,-0x1.d8f7208e6b82cp-2
+tan,0x1.fdbd5f0596bdcp-2,0x1.d8f7208e6b82cp-2
+tan,-0x1.b5f3d6afbe6f2p-2,-0x1.9dd83c7c9e126p-2
+tan,0x1.b5f3d6afbe6f2p-2,0x1.9dd83c7c9e126p-2
+tan,-0x1.71a0f98081eaap-2,-0x1.62b9586ad0a2p-2
+tan,0x1.71a0f98081eaap-2,0x1.62b9586ad0a2p-2
+tan,-0x1.301909a2c36e9p-2,-0x1.279a74590331ap-2
+tan,0x1.301909a2c36e9p-2,0x1.279a74590331ap-2
+tan,-0x1.e18e941cc7fd5p-3,-0x1.d8f7208e6b829p-3
+tan,0x1.e18e941cc7fd5p-3,0x1.d8f7208e6b829p-3
+tan,-0x1.6650784bbdccp-3,-0x1.62b9586ad0a1ep-3
+tan,0x1.6650784bbdccp-3,0x1.62b9586ad0a1ep-3
+tan,-0x1.db142468cdafcp-4,-0x1.d8f7208e6b826p-4
+tan,0x1.db142468cdafcp-4,0x1.d8f7208e6b826p-4
+tan,-0x1.d97dd6d2e53f3p-5,-0x1.d8f7208e6b82dp-5
+tan,0x1.d97dd6d2e53f3p-5,0x1.d8f7208e6b82dp-5
+tan,0x1.d97dd6d2e53f3p-5,0x1.d8f7208e6b82dp-5
+tan,-0x1.d97dd6d2e53f3p-5,-0x1.d8f7208e6b82dp-5
+tan,0x1.db142468cdb03p-4,0x1.d8f7208e6b82dp-4
+tan,-0x1.db142468cdb03p-4,-0x1.d8f7208e6b82dp-4
+tan,0x1.6650784bbdcc4p-3,0x1.62b9586ad0a22p-3
+tan,-0x1.6650784bbdcc4p-3,-0x1.62b9586ad0a22p-3
+tan,0x1.e18e941cc7fd9p-3,0x1.d8f7208e6b82dp-3
+tan,-0x1.e18e941cc7fd9p-3,-0x1.d8f7208e6b82dp-3
+tan,0x1.301909a2c36ebp-2,0x1.279a74590331cp-2
+tan,-0x1.301909a2c36ebp-2,-0x1.279a74590331cp-2
+tan,0x1.71a0f98081eacp-2,0x1.62b9586ad0a22p-2
+tan,-0x1.71a0f98081eacp-2,-0x1.62b9586ad0a22p-2
+tan,0x1.b5f3d6afbe6f5p-2,0x1.9dd83c7c9e128p-2
+tan,-0x1.b5f3d6afbe6f5p-2,-0x1.9dd83c7c9e128p-2
+tan,0x1.fdbd5f0596bdfp-2,0x1.d8f7208e6b82ep-2
+tan,-0x1.fdbd5f0596bdfp-2,-0x1.d8f7208e6b82ep-2
+tan,0x1.24e3e017a098fp-1,0x1.0a0b02501c799p-1
+tan,-0x1.24e3e017a098fp-1,-0x1.0a0b02501c799p-1
+tan,0x1.6d395e495f778p-1,0x1.3d3e35834faccp-1
+tan,-0x1.6d395e495f778p-1,-0x1.3d3e35834faccp-1
+tan,0x1.8ee916392e03fp-1,0x1.52e1f6ad9c27cp-1
+tan,-0x1.8ee916392e03fp-1,-0x1.52e1f6ad9c27cp-1
+tan,0x1.b2e4750631c4dp-1,0x1.6885b7d7e8a2cp-1
+tan,-0x1.b2e4750631c4dp-1,-0x1.6885b7d7e8a2cp-1
+tan,0x1.d98e408ac207ep-1,0x1.7e297902351dcp-1
+tan,-0x1.d98e408ac207ep-1,-0x1.7e297902351dcp-1
+tan,0x1.01aeeed04cbadp0,0x1.93cd3a2c8198cp-1
+tan,-0x1.01aeeed04cbadp0,-0x1.93cd3a2c8198cp-1
+tan,0x1.1872a1aaa7e22p0,0x1.a970fb56ce13cp-1
+tan,-0x1.1872a1aaa7e22p0,-0x1.a970fb56ce13cp-1
+tan,0x1.316c8b068a7aap0,0x1.bf14bc811a8ecp-1
+tan,-0x1.316c8b068a7aap0,-0x1.bf14bc811a8ecp-1
+tan,0x1.4d0df1fc1d343p0,0x1.d4b87dab6709cp-1
+tan,-0x1.4d0df1fc1d343p0,-0x1.d4b87dab6709cp-1
+tan,0x1.6be702e1f6cdp0,0x1.ea5c3ed5b384cp-1
+tan,-0x1.6be702e1f6cdp0,-0x1.ea5c3ed5b384cp-1
+tan,0x1.d74caf9912dc8p0,0x1.12bd9173c07abp0
+tan,-0x1.d74caf9912dc8p0,-0x1.12bd9173c07abp0
+tan,0x1.1b48a35b1b284p1,0x1.257b22e780f56p0
+tan,-0x1.1b48a35b1b284p1,-0x1.257b22e780f56p0
+tan,0x1.5d603d751769p1,0x1.3838b45b41701p0
+tan,-0x1.5d603d751769p1,-0x1.3838b45b41701p0
+tan,0x1.c08caec5cf9b2p1,0x1.4af645cf01eacp0
+tan,-0x1.c08caec5cf9b2p1,-0x1.4af645cf01eacp0
+tan,0x1.3429e61a5d20bp2,0x1.5db3d742c2657p0
+tan,-0x1.3429e61a5d20bp2,-0x1.5db3d742c2657p0
+tan,0x1.e3a3729b3e8a8p2,0x1.707168b682e02p0
+tan,-0x1.e3a3729b3e8a8p2,-0x1.707168b682e02p0
+tan,0x1.11d87146c2da4p4,0x1.832efa2a435adp0
+tan,-0x1.11d87146c2da4p4,-0x1.832efa2a435adp0
+tan,-0x1.0d718cfc82349p6,0x1.95ec8b9e03d58p0
+tan,0x1.0d718cfc82349p6,-0x1.95ec8b9e03d58p0
+tan,-0x1.6a7e1f6407ee6p3,0x1.a8aa1d11c44ffp0
+tan,0x1.6a7e1f6407ee6p3,-0x1.a8aa1d11c44ffp0
+tan,0x1.9f39ea5bbe475p0,0x1.04aff6d330942p0
+tan,-0x1.9f39ea5bbe475p0,-0x1.04aff6d330942p0
+tan,0x1.9f3c4b8469f85p0,0x1.04b09e98dcdb4p0
+tan,-0x1.9f3c4b8469f85p0,-0x1.04b09e98dcdb4p0
+tan,0x1.9f3eacb224c21p0,0x1.04b1465e89226p0
+tan,-0x1.9f3eacb224c21p0,-0x1.04b1465e89226p0
+tan,0x1.9f410de4eeb69p0,0x1.04b1ee2435698p0
+tan,-0x1.9f410de4eeb69p0,-0x1.04b1ee2435698p0
+tan,0x1.9f436f1cc7e82p0,0x1.04b295e9e1b0ap0
+tan,-0x1.9f436f1cc7e82p0,-0x1.04b295e9e1b0ap0
+tan,0x1.9f45d059b068fp0,0x1.04b33daf8df7cp0
+tan,-0x1.9f45d059b068fp0,-0x1.04b33daf8df7cp0
+tan,0x1.9f48319ba84b2p0,0x1.04b3e5753a3eep0
+tan,-0x1.9f48319ba84b2p0,-0x1.04b3e5753a3eep0
+tan,0x1.9f4a92e2afa0dp0,0x1.04b48d3ae686p0
+tan,-0x1.9f4a92e2afa0dp0,-0x1.04b48d3ae686p0
+tan,0x1.9f4cf42ec67bbp0,0x1.04b5350092ccfp0
+tan,-0x1.9f4cf42ec67bbp0,-0x1.04b5350092ccfp0
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x0.0p0,-0x0.0p0
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,0x1.4d82b68cac19ep-1,0x1.279a74590331bp-1
+tan,-0x1.4d82b68cac19ep-1,-0x1.279a74590331bp-1
+tan,0x1.4d82b68cac1ap-1,0x1.279a74590331cp-1
+tan,-0x1.4d82b68cac1ap-1,-0x1.279a74590331cp-1
+tan,0x1.4d82b68cac1a1p-1,0x1.279a74590331dp-1
+tan,-0x1.4d82b68cac1a1p-1,-0x1.279a74590331dp-1
+tan,-0x1.89712eeca32bfp2,0x1.bb67ae8584ca9p0
+tan,0x1.89712eeca32bfp2,-0x1.bb67ae8584ca9p0
+tan,-0x1.89712eeca32b5p2,0x1.bb67ae8584caap0
+tan,0x1.89712eeca32b5p2,-0x1.bb67ae8584caap0
+tan,-0x1.89712eeca32abp2,0x1.bb67ae8584cabp0
+tan,0x1.89712eeca32abp2,-0x1.bb67ae8584cabp0
+tan,0x1.def49eaab37ap-2,0x1.bffffffffffffp-2
+tan,-0x1.def49eaab37ap-2,-0x1.bffffffffffffp-2
+tan,0x1.def49eaab37a1p-2,0x1.cp-2
+tan,-0x1.def49eaab37a1p-2,-0x1.cp-2
+tan,0x1.def49eaab37a3p-2,0x1.c000000000001p-2
+tan,-0x1.def49eaab37a3p-2,-0x1.c000000000001p-2
+tan,0x1.a46cb2be6a0bp-1,0x1.5ffffffffffffp-1
+tan,-0x1.a46cb2be6a0bp-1,-0x1.5ffffffffffffp-1
+tan,0x1.a46cb2be6a0b2p-1,0x1.6p-1
+tan,-0x1.a46cb2be6a0b2p-1,-0x1.6p-1
+tan,0x1.a46cb2be6a0b4p-1,0x1.6000000000001p-1
+tan,-0x1.a46cb2be6a0b4p-1,-0x1.6000000000001p-1
+tan,0x1.3d6dc956eac7ap1,0x1.2ffffffffffffp0
+tan,-0x1.3d6dc956eac7ap1,-0x1.2ffffffffffffp0
+tan,0x1.3d6dc956eac7dp1,0x1.3p0
+tan,-0x1.3d6dc956eac7dp1,-0x1.3p0
+tan,0x1.3d6dc956eac81p1,0x1.3000000000001p0
+tan,-0x1.3d6dc956eac81p1,-0x1.3000000000001p0
+tan,-0x1.b2d89a9382954p-1,0x1.37fffffffffffp1
+tan,0x1.b2d89a9382954p-1,-0x1.37fffffffffffp1
+tan,-0x1.b2d89a938294cp-1,0x1.38p1
+tan,0x1.b2d89a938294cp-1,-0x1.38p1
+tan,-0x1.b2d89a9382946p-1,0x1.3800000000001p1
+tan,0x1.b2d89a9382946p-1,-0x1.3800000000001p1
+tan,0x1.06f8d014bf084p-4,0x1.069c8b46b3792p-4
+tan,-0x1.06f8d014bf084p-4,-0x1.069c8b46b3792p-4
+tan,0x1.080f73b07051ep-3,0x1.069c8b46b3792p-3
+tan,-0x1.080f73b07051ep-3,-0x1.069c8b46b3792p-3
+tan,0x1.8ed9142fc9189p-3,0x1.89ead0ea0d35bp-3
+tan,-0x1.8ed9142fc9189p-3,-0x1.89ead0ea0d35bp-3
+tan,0x1.0c864083d1e7dp-2,0x1.069c8b46b3792p-2
+tan,-0x1.0c864083d1e7dp-2,-0x1.069c8b46b3792p-2
+tan,0x1.53fdcdfd37f04p-2,0x1.4843ae1860576p-2
+tan,-0x1.53fdcdfd37f04p-2,-0x1.4843ae1860576p-2
+tan,0x1.9e9257e6b62a1p-2,0x1.89ead0ea0d35ap-2
+tan,-0x1.9e9257e6b62a1p-2,-0x1.89ead0ea0d35ap-2
+tan,0x1.ed21e59972b08p-2,0x1.cb91f3bbba13ep-2
+tan,-0x1.ed21e59972b08p-2,-0x1.cb91f3bbba13ep-2
+tan,0x1.205a6009d5e3ep-1,0x1.069c8b46b3791p-1
+tan,-0x1.205a6009d5e3ep-1,-0x1.069c8b46b3791p-1
+tan,0x1.4d466accad48ep-1,0x1.27701caf89e83p-1
+tan,-0x1.4d466accad48ep-1,-0x1.27701caf89e83p-1
+tan,0x1.7e1d936f4d615p-1,0x1.4843ae1860575p-1
+tan,-0x1.7e1d936f4d615p-1,-0x1.4843ae1860575p-1
+tan,0x1.b3df386f18228p-1,0x1.69173f8136c67p-1
+tan,-0x1.b3df386f18228p-1,-0x1.69173f8136c67p-1
+tan,0x1.efd82742d778cp-1,0x1.89ead0ea0d359p-1
+tan,-0x1.efd82742d778cp-1,-0x1.89ead0ea0d359p-1
+tan,0x1.19e26b5ecd5cp0,0x1.aabe6252e3a4bp-1
+tan,-0x1.19e26b5ecd5cp0,-0x1.aabe6252e3a4bp-1
+tan,0x1.41038b70be0fap0,0x1.cb91f3bbba13dp-1
+tan,-0x1.41038b70be0fap0,-0x1.cb91f3bbba13dp-1
+tan,0x1.6efec8c1e493bp0,0x1.ec6585249082fp-1
+tan,-0x1.6efec8c1e493bp0,-0x1.ec6585249082fp-1
+tan,0x1.a64c7c9d65346p0,0x1.069c8b46b3791p0
+tan,-0x1.a64c7c9d65346p0,-0x1.069c8b46b3791p0
+tan,0x1.eab43e0e5e87cp0,0x1.170653fb1eb0ap0
+tan,-0x1.eab43e0e5e87cp0,-0x1.170653fb1eb0ap0
+tan,0x1.21277b97c0137p1,0x1.27701caf89e83p0
+tan,-0x1.21277b97c0137p1,-0x1.27701caf89e83p0
+tan,0x1.5bd13dda077cdp1,0x1.37d9e563f51fcp0
+tan,-0x1.5bd13dda077cdp1,-0x1.37d9e563f51fcp0
+tan,0x1.af4643e9371f9p1,0x1.4843ae1860575p0
+tan,-0x1.af4643e9371f9p1,-0x1.4843ae1860575p0
+tan,0x1.1866fe845e75ap2,0x1.58ad76cccb8eep0
+tan,-0x1.1866fe845e75ap2,-0x1.58ad76cccb8eep0
+tan,0x1.8bdcd54bd5981p2,0x1.69173f8136c67p0
+tan,-0x1.8bdcd54bd5981p2,-0x1.69173f8136c67p0
+tan,0x1.4bb6a64e0625cp3,0x1.79810835a1fep0
+tan,-0x1.4bb6a64e0625cp3,-0x1.79810835a1fep0
+tan,0x1.f2f05cfb656a4p4,0x1.89ead0ea0d359p0
+tan,-0x1.f2f05cfb656a4p4,-0x1.89ead0ea0d359p0
+tan,-0x1.f2f05cfb657f5p4,0x1.9a54999e786d2p0
+tan,0x1.f2f05cfb657f5p4,-0x1.9a54999e786d2p0
+tan,-0x1.4bb6a64e062a7p3,0x1.aabe6252e3a4bp0
+tan,0x1.4bb6a64e062a7p3,-0x1.aabe6252e3a4bp0
+tan,-0x1.8bdcd54bd59b7p2,0x1.bb282b074edc4p0
+tan,0x1.8bdcd54bd59b7p2,-0x1.bb282b074edc4p0
+tan,-0x1.1866fe845e776p2,0x1.cb91f3bbba13dp0
+tan,0x1.1866fe845e776p2,-0x1.cb91f3bbba13dp0
+tan,-0x1.af4643e93721bp1,0x1.dbfbbc70254b6p0
+tan,0x1.af4643e93721bp1,-0x1.dbfbbc70254b6p0
+tan,-0x1.5bd13dda077e4p1,0x1.ec6585249082fp0
+tan,0x1.5bd13dda077e4p1,-0x1.ec6585249082fp0
+tan,-0x1.21277b97c0148p1,0x1.fccf4dd8fbba8p0
+tan,0x1.21277b97c0148p1,-0x1.fccf4dd8fbba8p0
+tan,-0x1.eab43e0e5e891p0,0x1.069c8b46b3791p1
+tan,0x1.eab43e0e5e891p0,-0x1.069c8b46b3791p1
+tan,-0x1.a64c7c9d65353p0,0x1.0ed16fa0e914ep1
+tan,0x1.a64c7c9d65353p0,-0x1.0ed16fa0e914ep1
+tan,-0x1.6efec8c1e4945p0,0x1.170653fb1eb0bp1
+tan,0x1.6efec8c1e4945p0,-0x1.170653fb1eb0bp1
+tan,-0x1.41038b70be1p0,0x1.1f3b3855544c8p1
+tan,0x1.41038b70be1p0,-0x1.1f3b3855544c8p1
+tan,-0x1.19e26b5ecd5c3p0,0x1.27701caf89e85p1
+tan,0x1.19e26b5ecd5c3p0,-0x1.27701caf89e85p1
+tan,-0x1.efd82742d778cp-1,0x1.2fa50109bf842p1
+tan,0x1.efd82742d778cp-1,-0x1.2fa50109bf842p1
+tan,-0x1.b3df386f18225p-1,0x1.37d9e563f51ffp1
+tan,0x1.b3df386f18225p-1,-0x1.37d9e563f51ffp1
+tan,-0x1.7e1d936f4d60fp-1,0x1.400ec9be2abbcp1
+tan,0x1.7e1d936f4d60fp-1,-0x1.400ec9be2abbcp1
+tan,-0x1.4d466accad486p-1,0x1.4843ae1860579p1
+tan,0x1.4d466accad486p-1,-0x1.4843ae1860579p1
+tan,-0x1.205a6009d5e34p-1,0x1.5078927295f36p1
+tan,0x1.205a6009d5e34p-1,-0x1.5078927295f36p1
+tan,-0x1.ed21e59972aefp-2,0x1.58ad76cccb8f3p1
+tan,0x1.ed21e59972aefp-2,-0x1.58ad76cccb8f3p1
+tan,-0x1.9e9257e6b6285p-2,0x1.60e25b27012bp1
+tan,0x1.9e9257e6b6285p-2,-0x1.60e25b27012bp1
+tan,-0x1.53fdcdfd37ee5p-2,0x1.69173f8136c6dp1
+tan,0x1.53fdcdfd37ee5p-2,-0x1.69173f8136c6dp1
+tan,-0x1.0c864083d1e5bp-2,0x1.714c23db6c62ap1
+tan,0x1.0c864083d1e5bp-2,-0x1.714c23db6c62ap1
+tan,-0x1.8ed9142fc913fp-3,0x1.79810835a1fe7p1
+tan,0x1.8ed9142fc913fp-3,-0x1.79810835a1fe7p1
+tan,-0x1.080f73b0704cfp-3,0x1.81b5ec8fd79a4p1
+tan,0x1.080f73b0704cfp-3,-0x1.81b5ec8fd79a4p1
+tan,-0x1.06f8d014bf09bp-4,0x1.89ead0ea0d35bp1
+tan,0x1.06f8d014bf09bp-4,-0x1.89ead0ea0d35bp1
+tan,0x1.0c864083d1e7fp-2,-0x1.81b5ec8fd799fp2
+tan,-0x1.0c864083d1e7fp-2,0x1.81b5ec8fd799fp2
+tan,0x1.205a6009d5e3fp-1,-0x1.714c23db6c626p2
+tan,-0x1.205a6009d5e3fp-1,0x1.714c23db6c626p2
+tan,0x1.efd82742d778ep-1,-0x1.60e25b27012adp2
+tan,-0x1.efd82742d778ep-1,0x1.60e25b27012adp2
+tan,0x1.a64c7c9d65347p0,-0x1.5078927295f34p2
+tan,-0x1.a64c7c9d65347p0,0x1.5078927295f34p2
+tan,0x1.af4643e9371f9p1,-0x1.400ec9be2abbbp2
+tan,-0x1.af4643e9371f9p1,0x1.400ec9be2abbbp2
+tan,0x1.f2f05cfb656aap4,-0x1.2fa50109bf842p2
+tan,-0x1.f2f05cfb656aap4,0x1.2fa50109bf842p2
+tan,-0x1.1866fe845e775p2,-0x1.1f3b3855544c9p2
+tan,0x1.1866fe845e775p2,0x1.1f3b3855544c9p2
+tan,-0x1.eab43e0e5e896p0,-0x1.0ed16fa0e915p2
+tan,0x1.eab43e0e5e896p0,0x1.0ed16fa0e915p2
+tan,-0x1.19e26b5ecd5cdp0,-0x1.fccf4dd8fbbaep1
+tan,0x1.19e26b5ecd5cdp0,0x1.fccf4dd8fbbaep1
+tan,-0x1.4d466accad49fp-1,-0x1.dbfbbc70254bcp1
+tan,0x1.4d466accad49fp-1,0x1.dbfbbc70254bcp1
+tan,-0x1.53fdcdfd37f1fp-2,-0x1.bb282b074edcap1
+tan,0x1.53fdcdfd37f1fp-2,0x1.bb282b074edcap1
+tan,-0x1.06f8d014bf0e9p-4,-0x1.9a54999e786d8p1
+tan,0x1.06f8d014bf0e9p-4,0x1.9a54999e786d8p1
+tan,0x1.8ed9142fc915p-3,-0x1.79810835a1fe6p1
+tan,-0x1.8ed9142fc915p-3,0x1.79810835a1fe6p1
+tan,0x1.ed21e59972ae6p-2,-0x1.58ad76cccb8f4p1
+tan,-0x1.ed21e59972ae6p-2,0x1.58ad76cccb8f4p1
+tan,0x1.b3df386f1821p-1,-0x1.37d9e563f5202p1
+tan,-0x1.b3df386f1821p-1,0x1.37d9e563f5202p1
+tan,0x1.6efec8c1e4926p0,-0x1.170653fb1eb1p1
+tan,-0x1.6efec8c1e4926p0,0x1.170653fb1eb1p1
+tan,0x1.5bd13dda077aep1,-0x1.ec6585249083cp0
+tan,-0x1.5bd13dda077aep1,0x1.ec6585249083cp0
+tan,0x1.4bb6a64e061f7p3,-0x1.aabe6252e3a58p0
+tan,-0x1.4bb6a64e061f7p3,0x1.aabe6252e3a58p0
+tan,-0x1.8bdcd54bd5ap2,-0x1.69173f8136c74p0
+tan,0x1.8bdcd54bd5ap2,0x1.69173f8136c74p0
+tan,-0x1.21277b97c015fp1,-0x1.27701caf89e9p0
+tan,0x1.21277b97c015fp1,0x1.27701caf89e9p0
+tan,-0x1.41038b70be11bp0,-0x1.cb91f3bbba157p-1
+tan,0x1.41038b70be11bp0,0x1.cb91f3bbba157p-1
+tan,-0x1.7e1d936f4d63cp-1,-0x1.4843ae186058ep-1
+tan,0x1.7e1d936f4d63cp-1,0x1.4843ae186058ep-1
+tan,-0x1.9e9257e6b62d9p-2,-0x1.89ead0ea0d38ap-2
+tan,0x1.9e9257e6b62d9p-2,0x1.89ead0ea0d38ap-2
+tan,-0x1.080f73b07057ep-3,-0x1.069c8b46b37fp-3
+tan,0x1.080f73b07057ep-3,0x1.069c8b46b37fp-3
+tan,0x1.080f73b0704bfp-3,0x1.069c8b46b3734p-3
+tan,-0x1.080f73b0704bfp-3,-0x1.069c8b46b3734p-3
+tan,0x1.9e9257e6b626bp-2,0x1.89ead0ea0d32cp-2
+tan,-0x1.9e9257e6b626bp-2,-0x1.89ead0ea0d32cp-2
+tan,0x1.7e1d936f4d5f3p-1,0x1.4843ae186055fp-1
+tan,-0x1.7e1d936f4d5f3p-1,-0x1.4843ae186055fp-1
+tan,0x1.41038b70be0dfp0,0x1.cb91f3bbba128p-1
+tan,-0x1.41038b70be0dfp0,-0x1.cb91f3bbba128p-1
+tan,0x1.21277b97c0116p1,0x1.27701caf89e78p0
+tan,-0x1.21277b97c0116p1,-0x1.27701caf89e78p0
+tan,0x1.8bdcd54bd5915p2,0x1.69173f8136c5cp0
+tan,-0x1.8bdcd54bd5915p2,-0x1.69173f8136c5cp0
+tan,-0x1.4bb6a64e0633cp3,0x1.aabe6252e3a4p0
+tan,0x1.4bb6a64e0633cp3,-0x1.aabe6252e3a4p0
+tan,-0x1.5bd13dda07812p1,0x1.ec65852490824p0
+tan,0x1.5bd13dda07812p1,-0x1.ec65852490824p0
+tan,-0x1.6efec8c1e497p0,0x1.170653fb1eb04p1
+tan,0x1.6efec8c1e497p0,-0x1.170653fb1eb04p1
+tan,-0x1.b3df386f18263p-1,0x1.37d9e563f51f6p1
+tan,0x1.b3df386f18263p-1,-0x1.37d9e563f51f6p1
+tan,-0x1.ed21e59972b5cp-2,0x1.58ad76cccb8e8p1
+tan,0x1.ed21e59972b5cp-2,-0x1.58ad76cccb8e8p1
+tan,-0x1.8ed9142fc9217p-3,0x1.79810835a1fdap1
+tan,0x1.8ed9142fc9217p-3,-0x1.79810835a1fdap1
+tan,0x1.06f8d014bef68p-4,0x1.9a54999e786ccp1
+tan,-0x1.06f8d014bef68p-4,-0x1.9a54999e786ccp1
+tan,0x1.53fdcdfd37eb4p-2,0x1.bb282b074edbep1
+tan,-0x1.53fdcdfd37eb4p-2,-0x1.bb282b074edbep1
+tan,0x1.4d466accad45ap-1,0x1.dbfbbc70254bp1
+tan,-0x1.4d466accad45ap-1,-0x1.dbfbbc70254bp1
+tan,0x1.19e26b5ecd598p0,0x1.fccf4dd8fbba2p1
+tan,-0x1.19e26b5ecd598p0,-0x1.fccf4dd8fbba2p1
+tan,0x1.eab43e0e5e825p0,0x1.0ed16fa0e914ap2
+tan,-0x1.eab43e0e5e825p0,-0x1.0ed16fa0e914ap2
+tan,0x1.1866fe845e6fcp2,0x1.1f3b3855544c3p2
+tan,-0x1.1866fe845e6fcp2,-0x1.1f3b3855544c3p2
+tan,-0x1.f2f05cfb65c5ep4,0x1.2fa50109bf83cp2
+tan,0x1.f2f05cfb65c5ep4,-0x1.2fa50109bf83cp2
+tan,-0x1.af4643e93728dp1,0x1.400ec9be2abb5p2
+tan,0x1.af4643e93728dp1,-0x1.400ec9be2abb5p2
+tan,-0x1.a64c7c9d653ap0,0x1.5078927295f2ep2
+tan,0x1.a64c7c9d653ap0,-0x1.5078927295f2ep2
+tan,-0x1.efd82742d77ebp-1,0x1.60e25b27012a7p2
+tan,0x1.efd82742d77ebp-1,-0x1.60e25b27012a7p2
+tan,-0x1.205a6009d5e7fp-1,0x1.714c23db6c62p2
+tan,0x1.205a6009d5e7fp-1,-0x1.714c23db6c62p2
+tan,-0x1.0c864083d1ee6p-2,0x1.81b5ec8fd7999p2
+tan,0x1.0c864083d1ee6p-2,-0x1.81b5ec8fd7999p2
+tan,0x1.f09b63aa81fc3p-5,0x1.effffffffffffp-5
+tan,-0x1.f09b63aa81fc3p-5,-0x1.effffffffffffp-5
+tan,0x1.f09b63aa81fc4p-5,0x1.fp-5
+tan,-0x1.f09b63aa81fc4p-5,-0x1.fp-5
+tan,0x1.f09b63aa81fc5p-5,0x1.f000000000001p-5
+tan,-0x1.f09b63aa81fc5p-5,-0x1.f000000000001p-5
+tan,0x1.fa8f21c8a33afp-4,0x1.f7fffffffffffp-4
+tan,-0x1.fa8f21c8a33afp-4,-0x1.f7fffffffffffp-4
+tan,0x1.fa8f21c8a33bp-4,0x1.f8p-4
+tan,-0x1.fa8f21c8a33bp-4,-0x1.f8p-4
+tan,0x1.fa8f21c8a33b1p-4,0x1.f800000000001p-4
+tan,-0x1.fa8f21c8a33b1p-4,-0x1.f800000000001p-4
+tan,0x1.4ef06cb4f0a87p-3,0x1.4bfffffffffffp-3
+tan,-0x1.4ef06cb4f0a87p-3,-0x1.4bfffffffffffp-3
+tan,0x1.4ef06cb4f0a88p-3,0x1.4cp-3
+tan,-0x1.4ef06cb4f0a88p-3,-0x1.4cp-3
+tan,0x1.4ef06cb4f0a89p-3,0x1.4c00000000001p-3
+tan,-0x1.4ef06cb4f0a89p-3,-0x1.4c00000000001p-3
+tan,0x1.3cc2a44e29996p-2,0x1.3333333333332p-2
+tan,-0x1.3cc2a44e29996p-2,-0x1.3333333333332p-2
+tan,0x1.3cc2a44e29998p-2,0x1.3333333333333p-2
+tan,-0x1.3cc2a44e29998p-2,-0x1.3333333333333p-2
+tan,0x1.3cc2a44e29999p-2,0x1.3333333333334p-2
+tan,-0x1.3cc2a44e29999p-2,-0x1.3333333333334p-2
+tan,0x1.9943711dc2ce8p-1,0x1.594317acc4ef8p-1
+tan,-0x1.9943711dc2ce8p-1,-0x1.594317acc4ef8p-1
+tan,0x1.9943711dc2ceap-1,0x1.594317acc4ef9p-1
+tan,-0x1.9943711dc2ceap-1,-0x1.594317acc4ef9p-1
+tan,0x1.9943711dc2cecp-1,0x1.594317acc4efap-1
+tan,-0x1.9943711dc2cecp-1,-0x1.594317acc4efap-1
+tan,0x1.fbc511df5917dp-1,0x1.8ffffffffffffp-1
+tan,-0x1.fbc511df5917dp-1,-0x1.8ffffffffffffp-1
+tan,0x1.fbc511df5917fp-1,0x1.9p-1
+tan,-0x1.fbc511df5917fp-1,-0x1.9p-1
+tan,0x1.fbc511df59181p-1,0x1.9000000000001p-1
+tan,-0x1.fbc511df59181p-1,-0x1.9000000000001p-1
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x0.0p0,-0x0.0p0
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,0x1.927278a3b1161p-5,0x1.921fb54442d17p-5
+tan,-0x1.927278a3b1161p-5,-0x1.921fb54442d17p-5
+tan,0x1.927278a3b1162p-5,0x1.921fb54442d18p-5
+tan,-0x1.927278a3b1162p-5,-0x1.921fb54442d18p-5
+tan,0x1.927278a3b1163p-5,0x1.921fb54442d19p-5
+tan,-0x1.927278a3b1163p-5,-0x1.921fb54442d19p-5
+tan,0x1.936bb8c5b2da1p-4,0x1.921fb54442d17p-4
+tan,-0x1.936bb8c5b2da1p-4,-0x1.921fb54442d17p-4
+tan,0x1.936bb8c5b2da2p-4,0x1.921fb54442d18p-4
+tan,-0x1.936bb8c5b2da2p-4,-0x1.921fb54442d18p-4
+tan,0x1.936bb8c5b2da3p-4,0x1.921fb54442d19p-4
+tan,-0x1.936bb8c5b2da3p-4,-0x1.921fb54442d19p-4
+tan,0x1.975f5e0553157p-3,0x1.921fb54442d17p-3
+tan,-0x1.975f5e0553157p-3,-0x1.921fb54442d17p-3
+tan,0x1.975f5e0553158p-3,0x1.921fb54442d18p-3
+tan,-0x1.975f5e0553158p-3,-0x1.921fb54442d18p-3
+tan,0x1.975f5e0553159p-3,0x1.921fb54442d19p-3
+tan,-0x1.975f5e0553159p-3,-0x1.921fb54442d19p-3
+tan,0x1.a827999fcef31p-2,0x1.921fb54442d17p-2
+tan,-0x1.a827999fcef31p-2,-0x1.921fb54442d17p-2
+tan,0x1.a827999fcef32p-2,0x1.921fb54442d18p-2
+tan,-0x1.a827999fcef32p-2,-0x1.921fb54442d18p-2
+tan,0x1.a827999fcef33p-2,0x1.921fb54442d19p-2
+tan,-0x1.a827999fcef33p-2,-0x1.921fb54442d19p-2
+tan,0x1.ffffffffffffdp-1,0x1.921fb54442d17p-1
+tan,-0x1.ffffffffffffdp-1,-0x1.921fb54442d17p-1
+tan,0x1.fffffffffffffp-1,0x1.921fb54442d18p-1
+tan,-0x1.fffffffffffffp-1,-0x1.921fb54442d18p-1
+tan,0x1.0000000000001p0,0x1.921fb54442d19p-1
+tan,-0x1.0000000000001p0,-0x1.921fb54442d19p-1
+tan,0x1.9153d9443ed0bp51,0x1.921fb54442d17p0
+tan,-0x1.9153d9443ed0bp51,-0x1.921fb54442d17p0
+tan,0x1.d02967c31cdb5p53,0x1.921fb54442d18p0
+tan,-0x1.d02967c31cdb5p53,-0x1.921fb54442d18p0
+tan,-0x1.617a15494767ap52,0x1.921fb54442d19p0
+tan,0x1.617a15494767ap52,-0x1.921fb54442d19p0
+tan,-0x1.469898cc51702p-51,0x1.921fb54442d17p1
+tan,0x1.469898cc51702p-51,-0x1.921fb54442d17p1
+tan,-0x1.1a62633145c07p-53,0x1.921fb54442d18p1
+tan,0x1.1a62633145c07p-53,-0x1.921fb54442d18p1
+tan,0x1.72cece675d1fdp-52,0x1.921fb54442d19p1
+tan,-0x1.72cece675d1fdp-52,-0x1.921fb54442d19p1
+tan,-0x1.469898cc51702p-50,0x1.921fb54442d17p2
+tan,0x1.469898cc51702p-50,-0x1.921fb54442d17p2
+tan,-0x1.1a62633145c07p-52,0x1.921fb54442d18p2
+tan,0x1.1a62633145c07p-52,-0x1.921fb54442d18p2
+tan,0x1.72cece675d1fdp-51,0x1.921fb54442d19p2
+tan,-0x1.72cece675d1fdp-51,-0x1.921fb54442d19p2
+tan,-0x1.469898cc51702p-49,0x1.921fb54442d17p3
+tan,0x1.469898cc51702p-49,-0x1.921fb54442d17p3
+tan,-0x1.1a62633145c07p-51,0x1.921fb54442d18p3
+tan,0x1.1a62633145c07p-51,-0x1.921fb54442d18p3
+tan,0x1.72cece675d1fdp-50,0x1.921fb54442d19p3
+tan,-0x1.72cece675d1fdp-50,-0x1.921fb54442d19p3
+tan,-0x1.469898cc51702p-48,0x1.921fb54442d17p4
+tan,0x1.469898cc51702p-48,-0x1.921fb54442d17p4
+tan,-0x1.1a62633145c07p-50,0x1.921fb54442d18p4
+tan,0x1.1a62633145c07p-50,-0x1.921fb54442d18p4
+tan,0x1.72cece675d1fdp-49,0x1.921fb54442d19p4
+tan,-0x1.72cece675d1fdp-49,-0x1.921fb54442d19p4
+tan,-0x1.469898cc51702p-47,0x1.921fb54442d17p5
+tan,0x1.469898cc51702p-47,-0x1.921fb54442d17p5
+tan,-0x1.1a62633145c07p-49,0x1.921fb54442d18p5
+tan,0x1.1a62633145c07p-49,-0x1.921fb54442d18p5
+tan,0x1.72cece675d1fdp-48,0x1.921fb54442d19p5
+tan,-0x1.72cece675d1fdp-48,-0x1.921fb54442d19p5
+tan,-0x1.469898cc51702p-46,0x1.921fb54442d17p6
+tan,0x1.469898cc51702p-46,-0x1.921fb54442d17p6
+tan,-0x1.1a62633145c07p-48,0x1.921fb54442d18p6
+tan,0x1.1a62633145c07p-48,-0x1.921fb54442d18p6
+tan,0x1.72cece675d1fdp-47,0x1.921fb54442d19p6
+tan,-0x1.72cece675d1fdp-47,-0x1.921fb54442d19p6
+tan,-0x1.469898cc51702p-45,0x1.921fb54442d17p7
+tan,0x1.469898cc51702p-45,-0x1.921fb54442d17p7
+tan,-0x1.1a62633145c07p-47,0x1.921fb54442d18p7
+tan,0x1.1a62633145c07p-47,-0x1.921fb54442d18p7
+tan,0x1.72cece675d1fdp-46,0x1.921fb54442d19p7
+tan,-0x1.72cece675d1fdp-46,-0x1.921fb54442d19p7
+tan,-0x1.0000000000005p0,0x1.2d97c7f3321d1p1
+tan,0x1.0000000000005p0,-0x1.2d97c7f3321d1p1
+tan,-0x1.0000000000001p0,0x1.2d97c7f3321d2p1
+tan,0x1.0000000000001p0,-0x1.2d97c7f3321d2p1
+tan,-0x1.ffffffffffffap-1,0x1.2d97c7f3321d3p1
+tan,0x1.ffffffffffffap-1,-0x1.2d97c7f3321d3p1
+tan,0x1.ffffffffffff5p-1,0x1.f6a7a2955385dp1
+tan,-0x1.ffffffffffff5p-1,-0x1.f6a7a2955385dp1
+tan,0x1.ffffffffffffdp-1,0x1.f6a7a2955385ep1
+tan,-0x1.ffffffffffffdp-1,-0x1.f6a7a2955385ep1
+tan,0x1.0000000000003p0,0x1.f6a7a2955385fp1
+tan,-0x1.0000000000003p0,-0x1.f6a7a2955385fp1
+tan,0x1.a8410087262e4p49,0x1.2d97c7f3321d1p2
+tan,-0x1.a8410087262e4p49,-0x1.2d97c7f3321d1p2
+tan,0x1.3570efd768923p52,0x1.2d97c7f3321d2p2
+tan,-0x1.3570efd768923p52,-0x1.2d97c7f3321d2p2
+tan,-0x1.42c0d64d5de51p50,0x1.2d97c7f3321d3p2
+tan,0x1.42c0d64d5de51p50,-0x1.2d97c7f3321d3p2
+tan,-0x1.000000000000ap0,0x1.5fdbbe9bba774p2
+tan,0x1.000000000000ap0,-0x1.5fdbbe9bba774p2
+tan,-0x1.0000000000002p0,0x1.5fdbbe9bba775p2
+tan,0x1.0000000000002p0,-0x1.5fdbbe9bba775p2
+tan,-0x1.ffffffffffff4p-1,0x1.5fdbbe9bba776p2
+tan,0x1.ffffffffffff4p-1,-0x1.5fdbbe9bba776p2
+tan,0x1.fffffffffffebp-1,0x1.c463abeccb2bap2
+tan,-0x1.fffffffffffebp-1,-0x1.c463abeccb2bap2
+tan,0x1.ffffffffffffbp-1,0x1.c463abeccb2bbp2
+tan,-0x1.ffffffffffffbp-1,-0x1.c463abeccb2bbp2
+tan,0x1.0000000000006p0,0x1.c463abeccb2bcp2
+tan,-0x1.0000000000006p0,-0x1.c463abeccb2bcp2
+tan,0x1.7cc080f895856p49,0x1.f6a7a2955385dp2
+tan,-0x1.7cc080f895856p49,-0x1.f6a7a2955385dp2
+tan,0x1.735453027d7c4p51,0x1.f6a7a2955385ep2
+tan,-0x1.735453027d7c4p51,-0x1.f6a7a2955385ep2
+tan,-0x1.86aa4a3a127a4p50,0x1.f6a7a2955385fp2
+tan,0x1.86aa4a3a127a4p50,-0x1.f6a7a2955385fp2
+tan,-0x1.000000000001bp0,0x1.1475cc9eedeffp3
+tan,0x1.000000000001bp0,-0x1.1475cc9eedeffp3
+tan,-0x1.000000000000bp0,0x1.1475cc9eedfp3
+tan,0x1.000000000000bp0,-0x1.1475cc9eedfp3
+tan,-0x1.ffffffffffff6p-1,0x1.1475cc9eedf01p3
+tan,0x1.ffffffffffff6p-1,-0x1.1475cc9eedf01p3
+tan,-0x1.34f272993d141p-49,0x1.2d97c7f3321d1p3
+tan,0x1.34f272993d141p-49,-0x1.2d97c7f3321d1p3
+tan,-0x1.a79394c9e8a0ap-52,0x1.2d97c7f3321d2p3
+tan,0x1.a79394c9e8a0ap-52,-0x1.2d97c7f3321d2p3
+tan,0x1.961b1acd85d7dp-50,0x1.2d97c7f3321d3p3
+tan,-0x1.961b1acd85d7dp-50,-0x1.2d97c7f3321d3p3
+tan,0x1.fffffffffffc9p-1,0x1.46b9c347764a2p3
+tan,-0x1.fffffffffffc9p-1,-0x1.46b9c347764a2p3
+tan,0x1.fffffffffffe9p-1,0x1.46b9c347764a3p3
+tan,-0x1.fffffffffffe9p-1,-0x1.46b9c347764a3p3
+tan,0x1.0000000000004p0,0x1.46b9c347764a4p3
+tan,-0x1.0000000000004p0,-0x1.46b9c347764a4p3
+tan,0x1.9c78eea78baa7p48,0x1.5fdbbe9bba774p3
+tan,-0x1.9c78eea78baa7p48,-0x1.5fdbbe9bba774p3
+tan,0x1.093c3b4aebeb1p51,0x1.5fdbbe9bba775p3
+tan,-0x1.093c3b4aebeb1p51,-0x1.5fdbbe9bba775p3
+tan,-0x1.516ac96142185p49,0x1.5fdbbe9bba776p3
+tan,0x1.516ac96142185p49,-0x1.5fdbbe9bba776p3
+tan,-0x1.000000000001cp0,0x1.78fdb9effea45p3
+tan,0x1.000000000001cp0,-0x1.78fdb9effea45p3
+tan,-0x1.000000000000cp0,0x1.78fdb9effea46p3
+tan,0x1.000000000000cp0,-0x1.78fdb9effea46p3
+tan,-0x1.ffffffffffff8p-1,0x1.78fdb9effea47p3
+tan,0x1.ffffffffffff8p-1,-0x1.78fdb9effea47p3
+tan,0x1.fffffffffffc7p-1,0x1.ab41b09886fe8p3
+tan,-0x1.fffffffffffc7p-1,-0x1.ab41b09886fe8p3
+tan,0x1.fffffffffffe7p-1,0x1.ab41b09886fe9p3
+tan,-0x1.fffffffffffe7p-1,-0x1.ab41b09886fe9p3
+tan,0x1.0000000000003p0,0x1.ab41b09886feap3
+tan,-0x1.0000000000003p0,-0x1.ab41b09886feap3
+tan,0x1.86c4e333b3c9fp48,0x1.c463abeccb2bap3
+tan,-0x1.86c4e333b3c9fp48,-0x1.c463abeccb2bap3
+tan,0x1.9c96951f36184p50,0x1.c463abeccb2bbp3
+tan,-0x1.9c96951f36184p50,-0x1.c463abeccb2bbp3
+tan,-0x1.73244d369e0b7p49,0x1.c463abeccb2bcp3
+tan,0x1.73244d369e0b7p49,-0x1.c463abeccb2bcp3
+tan,-0x1.000000000001dp0,0x1.dd85a7410f58bp3
+tan,0x1.000000000001dp0,-0x1.dd85a7410f58bp3
+tan,-0x1.000000000000dp0,0x1.dd85a7410f58cp3
+tan,0x1.000000000000dp0,-0x1.dd85a7410f58cp3
+tan,-0x1.ffffffffffffap-1,0x1.dd85a7410f58dp3
+tan,0x1.ffffffffffffap-1,-0x1.dd85a7410f58dp3
+tan,-0x1.583ebeff65cc2p-49,0x1.f6a7a2955385dp3
+tan,0x1.583ebeff65cc2p-49,-0x1.f6a7a2955385dp3
+tan,-0x1.60fafbfd97309p-51,0x1.f6a7a2955385ep3
+tan,0x1.60fafbfd97309p-51,-0x1.f6a7a2955385ep3
+tan,0x1.4f8282013467cp-50,0x1.f6a7a2955385fp3
+tan,-0x1.4f8282013467cp-50,-0x1.f6a7a2955385fp3
+tan,0x1.fffffffffff84p-1,0x1.07e4cef4cbd96p4
+tan,-0x1.fffffffffff84p-1,-0x1.07e4cef4cbd96p4
+tan,0x1.fffffffffffc4p-1,0x1.07e4cef4cbd97p4
+tan,-0x1.fffffffffffc4p-1,-0x1.07e4cef4cbd97p4
+tan,0x1.0000000000002p0,0x1.07e4cef4cbd98p4
+tan,-0x1.0000000000002p0,-0x1.07e4cef4cbd98p4
+tan,0x1.2f0842389e5bcp47,0x1.1475cc9eedeffp4
+tan,-0x1.2f0842389e5bcp47,-0x1.1475cc9eedeffp4
+tan,0x1.733c4e8ef9c51p48,0x1.1475cc9eedfp4
+tan,-0x1.733c4e8ef9c51p48,-0x1.1475cc9eedfp4
+tan,-0x1.9c5b4c7289899p49,0x1.1475cc9eedf01p4
+tan,0x1.9c5b4c7289899p49,-0x1.1475cc9eedf01p4
+tan,-0x1.000000000002ep0,0x1.2106ca4910068p4
+tan,0x1.000000000002ep0,-0x1.2106ca4910068p4
+tan,-0x1.000000000000ep0,0x1.2106ca4910069p4
+tan,0x1.000000000000ep0,-0x1.2106ca4910069p4
+tan,-0x1.fffffffffffddp-1,0x1.2106ca491006ap4
+tan,0x1.fffffffffffddp-1,-0x1.2106ca491006ap4
+tan,-0x1.34f272993d141p-48,0x1.2d97c7f3321d1p4
+tan,0x1.34f272993d141p-48,-0x1.2d97c7f3321d1p4
+tan,-0x1.a79394c9e8a0ap-51,0x1.2d97c7f3321d2p4
+tan,0x1.a79394c9e8a0ap-51,-0x1.2d97c7f3321d2p4
+tan,0x1.961b1acd85d7dp-49,0x1.2d97c7f3321d3p4
+tan,-0x1.961b1acd85d7dp-49,-0x1.2d97c7f3321d3p4
+tan,0x1.fffffffffff82p-1,0x1.3a28c59d54339p4
+tan,-0x1.fffffffffff82p-1,-0x1.3a28c59d54339p4
+tan,0x1.fffffffffffc2p-1,0x1.3a28c59d5433ap4
+tan,-0x1.fffffffffffc2p-1,-0x1.3a28c59d5433ap4
+tan,0x1.0000000000001p0,0x1.3a28c59d5433bp4
+tan,-0x1.0000000000001p0,-0x1.3a28c59d5433bp4
+tan,0x1.28f934315e5ecp47,0x1.46b9c347764a2p4
+tan,-0x1.28f934315e5ecp47,-0x1.46b9c347764a2p4
+tan,0x1.618fdb7f21c14p48,0x1.46b9c347764a3p4
+tan,-0x1.618fdb7f21c14p48,-0x1.46b9c347764a3p4
+tan,-0x1.cfde61218ab9ep49,0x1.46b9c347764a4p4
+tan,0x1.cfde61218ab9ep49,-0x1.46b9c347764a4p4
+tan,-0x1.000000000002fp0,0x1.534ac0f19860bp4
+tan,0x1.000000000002fp0,-0x1.534ac0f19860bp4
+tan,-0x1.000000000000fp0,0x1.534ac0f19860cp4
+tan,0x1.000000000000fp0,-0x1.534ac0f19860cp4
+tan,-0x1.fffffffffffdfp-1,0x1.534ac0f19860dp4
+tan,0x1.fffffffffffdfp-1,-0x1.534ac0f19860dp4
+tan,-0x1.3dc585b2c7422p-48,0x1.5fdbbe9bba774p4
+tan,0x1.3dc585b2c7422p-48,-0x1.5fdbbe9bba774p4
+tan,-0x1.ee2c2d963a10cp-51,0x1.5fdbbe9bba775p4
+tan,0x1.ee2c2d963a10cp-51,-0x1.5fdbbe9bba775p4
+tan,0x1.8474f49a717bdp-49,0x1.5fdbbe9bba776p4
+tan,-0x1.8474f49a717bdp-49,-0x1.5fdbbe9bba776p4
+tan,0x1.fffffffffff8p-1,0x1.6c6cbc45dc8dcp4
+tan,-0x1.fffffffffff8p-1,-0x1.6c6cbc45dc8dcp4
+tan,0x1.fffffffffffcp-1,0x1.6c6cbc45dc8ddp4
+tan,-0x1.fffffffffffcp-1,-0x1.6c6cbc45dc8ddp4
+tan,0x1.0p0,0x1.6c6cbc45dc8dep4
+tan,-0x1.0p0,-0x1.6c6cbc45dc8dep4
+tan,0x1.2326f4e8f2bb2p47,0x1.78fdb9effea45p4
+tan,-0x1.2326f4e8f2bb2p47,-0x1.78fdb9effea45p4
+tan,0x1.517ea08708ba7p48,0x1.78fdb9effea46p4
+tan,-0x1.517ea08708ba7p48,-0x1.78fdb9effea46p4
+tan,-0x1.090b3d5161786p50,0x1.78fdb9effea47p4
+tan,0x1.090b3d5161786p50,-0x1.78fdb9effea47p4
+tan,-0x1.0000000000031p0,0x1.858eb79a20baep4
+tan,0x1.0000000000031p0,-0x1.858eb79a20baep4
+tan,-0x1.0000000000011p0,0x1.858eb79a20bafp4
+tan,0x1.0000000000011p0,-0x1.858eb79a20bafp4
+tan,-0x1.fffffffffffe1p-1,0x1.858eb79a20bbp4
+tan,0x1.fffffffffffe1p-1,-0x1.858eb79a20bbp4
+tan,-0x1.af0792001f856p2,0x1.fffffffffffffp62
+tan,0x1.af0792001f856p2,-0x1.fffffffffffffp62
+tan,0x1.52f50e757941dp6,0x1.0p63
+tan,-0x1.52f50e757941dp6,-0x1.0p63
+tan,0x1.7570667d032edp1,0x1.0000000000001p63
+tan,-0x1.7570667d032edp1,-0x1.0000000000001p63
+tan,-0x1.2e8fc248e7b85p0,0x1.fffffffffffffp26
+tan,0x1.2e8fc248e7b85p0,-0x1.fffffffffffffp26
+tan,-0x1.2e8fc1af81d8cp0,0x1.0p27
+tan,0x1.2e8fc1af81d8cp0,-0x1.0p27
+tan,-0x1.2e8fc07cb61a9p0,0x1.0000000000001p27
+tan,0x1.2e8fc07cb61a9p0,-0x1.0000000000001p27
+tan,-0x1.3ea282860e7fcp0,0x1.fffffffffffffp23
+tan,0x1.3ea282860e7fcp0,-0x1.fffffffffffffp23
+tan,-0x1.3ea28271a9beap0,0x1.0p24
+tan,0x1.3ea28271a9beap0,-0x1.0p24
+tan,-0x1.3ea28248e03c7p0,0x1.0000000000001p24
+tan,0x1.3ea28248e03c7p0,-0x1.0000000000001p24
+tan,0x1.2866f9be4de0fp0,0x1.fffffffffffffp1
+tan,-0x1.2866f9be4de0fp0,-0x1.fffffffffffffp1
+tan,0x1.2866f9be4de14p0,0x1.0p2
+tan,-0x1.2866f9be4de14p0,-0x1.0p2
+tan,0x1.2866f9be4de1dp0,0x1.0000000000001p2
+tan,-0x1.2866f9be4de1dp0,-0x1.0000000000001p2
+tan,-0x1.17af62e0950fbp1,0x1.fffffffffffffp0
+tan,0x1.17af62e0950fbp1,-0x1.fffffffffffffp0
+tan,-0x1.17af62e0950f8p1,0x1.0p1
+tan,0x1.17af62e0950f8p1,-0x1.0p1
+tan,-0x1.17af62e0950f2p1,0x1.0000000000001p1
+tan,0x1.17af62e0950f2p1,-0x1.0000000000001p1
+tan,0x1.8eb245cbee3a4p0,0x1.fffffffffffffp-1
+tan,-0x1.8eb245cbee3a4p0,-0x1.fffffffffffffp-1
+tan,0x1.8eb245cbee3a6p0,0x1.0p0
+tan,-0x1.8eb245cbee3a6p0,-0x1.0p0
+tan,0x1.8eb245cbee3a9p0,0x1.0000000000001p0
+tan,-0x1.8eb245cbee3a9p0,-0x1.0000000000001p0
+tan,0x1.17b4f5bf3474ap-1,0x1.fffffffffffffp-2
+tan,-0x1.17b4f5bf3474ap-1,-0x1.fffffffffffffp-2
+tan,0x1.17b4f5bf3474ap-1,0x1.0p-1
+tan,-0x1.17b4f5bf3474ap-1,-0x1.0p-1
+tan,0x1.17b4f5bf3474cp-1,0x1.0000000000001p-1
+tan,-0x1.17b4f5bf3474cp-1,-0x1.0000000000001p-1
+tan,0x1.05785a43c4c55p-2,0x1.fffffffffffffp-3
+tan,-0x1.05785a43c4c55p-2,-0x1.fffffffffffffp-3
+tan,0x1.05785a43c4c56p-2,0x1.0p-2
+tan,-0x1.05785a43c4c56p-2,-0x1.0p-2
+tan,0x1.05785a43c4c57p-2,0x1.0000000000001p-2
+tan,-0x1.05785a43c4c57p-2,-0x1.0000000000001p-2
+tan,0x1.01577af1511a4p-3,0x1.fffffffffffffp-4
+tan,-0x1.01577af1511a4p-3,-0x1.fffffffffffffp-4
+tan,0x1.01577af1511a5p-3,0x1.0p-3
+tan,-0x1.01577af1511a5p-3,-0x1.0p-3
+tan,0x1.01577af1511a6p-3,0x1.0000000000001p-3
+tan,-0x1.01577af1511a6p-3,-0x1.0000000000001p-3
+tan,0x1.005577854dfp-4,0x1.fffffffffffffp-5
+tan,-0x1.005577854dfp-4,-0x1.fffffffffffffp-5
+tan,0x1.005577854df01p-4,0x1.0p-4
+tan,-0x1.005577854df01p-4,-0x1.0p-4
+tan,0x1.005577854df02p-4,0x1.0000000000001p-4
+tan,-0x1.005577854df02p-4,-0x1.0000000000001p-4
+tan,0x1.00155777aec08p-5,0x1.fffffffffffffp-6
+tan,-0x1.00155777aec08p-5,-0x1.fffffffffffffp-6
+tan,0x1.00155777aec08p-5,0x1.0p-5
+tan,-0x1.00155777aec08p-5,-0x1.0p-5
+tan,0x1.00155777aec09p-5,0x1.0000000000001p-5
+tan,-0x1.00155777aec09p-5,-0x1.0000000000001p-5
+tan,0x1.0005557778548p-6,0x1.fffffffffffffp-7
+tan,-0x1.0005557778548p-6,-0x1.fffffffffffffp-7
+tan,0x1.0005557778549p-6,0x1.0p-6
+tan,-0x1.0005557778549p-6,-0x1.0p-6
+tan,0x1.000555777854ap-6,0x1.0000000000001p-6
+tan,-0x1.000555777854ap-6,-0x1.0000000000001p-6
+tan,0x1.0000000555555p-14,0x1.fffffffffffffp-15
+tan,-0x1.0000000555555p-14,-0x1.fffffffffffffp-15
+tan,0x1.0000000555555p-14,0x1.0p-14
+tan,-0x1.0000000555555p-14,-0x1.0p-14
+tan,0x1.0000000555556p-14,0x1.0000000000001p-14
+tan,-0x1.0000000555556p-14,-0x1.0000000000001p-14
+tan,0x1.fffffffffffffp-28,0x1.fffffffffffffp-28
+tan,-0x1.fffffffffffffp-28,-0x1.fffffffffffffp-28
+tan,0x1.0p-27,0x1.0p-27
+tan,-0x1.0p-27,-0x1.0p-27
+tan,0x1.0000000000001p-27,0x1.0000000000001p-27
+tan,-0x1.0000000000001p-27,-0x1.0000000000001p-27
+tan,0x1.fffffffffffffp-31,0x1.fffffffffffffp-31
+tan,-0x1.fffffffffffffp-31,-0x1.fffffffffffffp-31
+tan,0x1.0p-30,0x1.0p-30
+tan,-0x1.0p-30,-0x1.0p-30
+tan,0x1.0000000000001p-30,0x1.0000000000001p-30
+tan,-0x1.0000000000001p-30,-0x1.0000000000001p-30
+tan,0x1.4530cfe729484p-8,-0x1.fffffffffffffp1023
+tan,-0x1.4530cfe729484p-8,0x1.fffffffffffffp1023
+tan,-0x1.4530cfe729484p-8,0x1.fffffffffffffp1023
+tan,0x1.4530cfe729484p-8,-0x1.fffffffffffffp1023
+tan,-0x1.4530cfe729484p-8,0x1.fffffffffffffp1023
+tan,0x1.4530cfe729484p-8,-0x1.fffffffffffffp1023
+tan,0x1.3c6e9970f78b8p1,0x1.ffffffffffffep1023
+tan,-0x1.3c6e9970f78b8p1,-0x1.ffffffffffffep1023
+tan,-0x1.1a62633145c07p-53,0x1.921fb54442d18p1
+tan,0x1.1a62633145c07p-53,-0x1.921fb54442d18p1
+tan,0x1.d02967c31cdb5p53,0x1.921fb54442d18p0
+tan,-0x1.d02967c31cdb5p53,-0x1.921fb54442d18p0
+tan,0x1.8eb245cbee3a9p0,0x1.0000000000001p0
+tan,-0x1.8eb245cbee3a9p0,-0x1.0000000000001p0
+tan,0x1.8eb245cbee3a6p0,0x1.0p0
+tan,-0x1.8eb245cbee3a6p0,-0x1.0p0
+tan,0x1.8eb245cbee3a4p0,0x1.fffffffffffffp-1
+tan,-0x1.8eb245cbee3a4p0,-0x1.fffffffffffffp-1
+tan,0x1.fffffffffffffp-1,0x1.921fb54442d18p-1
+tan,-0x1.fffffffffffffp-1,-0x1.921fb54442d18p-1
+tan,0x1.0000000000001p-1022,0x1.0000000000001p-1022
+tan,-0x1.0000000000001p-1022,-0x1.0000000000001p-1022
+tan,0x1.0p-1022,0x1.0p-1022
+tan,-0x1.0p-1022,-0x1.0p-1022
+tan,0x0.fffffffffffffp-1022,0x0.fffffffffffffp-1022
+tan,-0x0.fffffffffffffp-1022,-0x0.fffffffffffffp-1022
+tan,0x0.ffffffffffffep-1022,0x0.ffffffffffffep-1022
+tan,-0x0.ffffffffffffep-1022,-0x0.ffffffffffffep-1022
+tan,0x0.0000000000002p-1022,0x0.0000000000002p-1022
+tan,-0x0.0000000000002p-1022,-0x0.0000000000002p-1022
+tan,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+tan,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+tan,0x0.0p0,0x0.0p0
+tan,-0x0.0p0,-0x0.0p0
+log,0x1.d77fd13d27fffp-11,0x1.003af6c37c1d3p0
+log,0x1.411efd297c781p-6,0x1.05112792934b3p0
+log,0x1.d4840664446fcp-6,0x1.076d1d8c75ea6p0
+log,0x1.f6e4c3ced7c72p-3,0x1.47408cb9583cep0
+log,0x1.1a0408712e00ap-2,0x1.512b3126454f3p0
+log,0x1.8b52c15ea9c24p-2,0x1.789e95b11578cp0
+log,0x1.d707029bb59d9p-2,0x1.958497f7b353fp0
+log,0x1.0727af5fee8f6p-1,0x1.ac032a8d2ec23p0
+log,0x1.12fcce02efb32p-1,0x1.b604e1942098dp0
+log,0x1.178e6d3ecaceap-1,0x1.b9f1fa4587967p0
+log,0x1.62f71c4656b61p-1,0x1.000976581ce4ep1
+log,0x1.d6336a88077aap0,0x1.91a8dff540ff7p2
+log,0x1.016e82ceda359p1,0x1.de37fb31fd5fcp2
+log,0x1.1e126f5d95f38p1,0x1.2b1199e497739p3
+log,0x1.2f3832cad3d5fp1,0x1.55f0eaa1b2fc8p3
+log,0x1.42ee3c7dc4946p1,0x1.8ede492d96072p3
+log,0x1.6b5df7e3cd422p1,0x1.11867637cbd03p4
+log,0x1.7e7f095703eeep1,0x1.3d9d7d597a9ddp4
+log,0x1.9687c83faf006p1,0x1.7f3825778aaafp4
+log,0x1.83d4bcdebb3f4p2,0x1.ac50b409c8aeep8
+log,0x1.fffffffffffffp-53,0x1.0000000000001p0
+log,0x1.76e7e5d7b6eacp3,0x1.de7cd6751029ap16
+log,0x1.fffffffffffffp-53,0x1.0000000000001p0
+log,-0x1.91550c357f884p8,0x1.0000000000003p-579
+log,0x1.7fffffffffffcp-50,0x1.0000000000006p0
+log,0x1.bffffffffffe8p-48,0x1.000000000001cp0
+log,0x1.7fdfffffff701p-41,0x1.0000000000bffp0
+log,0x1.0fffffffedfp-35,0x1.0000000022p0
+log,0x1.ffffffffp-33,0x1.00000001p0
+log,0x1.7fffff7000004p-25,0x1.000000cp0
+log,0x1.0a2ea3e77af06p1,0x1.0007p3
+log,0x1.90412094d368p-13,0x1.000c82573f5f9p0
+log,0x1.ffe002aa6ab11p-12,0x1.002p0
+log,0x1.bfcf07242969dp-11,0x1.0038p0
+log,0x1.d77fd13d27fffp-11,0x1.003af6c37c1d3p0
+log,0x1.ea054ce8508e5p-10,0x1.007a9ea7a9e8p0
+log,0x1.ff004a7ab9084p-10,0x1.007fdff7fdfep0
+log,0x1.ffda65d44dccdp-10,0x1.0080169a16cd5p0
+log,0x1.b956989d2589dp-9,0x1.00dd0a8317176p0
+log,0x1.fd0816d97152cp-9,0x1.00ff02ba8a543p0
+log,-0x1.37915555785bp9,0x1.00fffffffffffp-899
+log,0x1.64a2a9b6a4058p0,0x1.01c00000000dcp2
+log,0x1.d465957106bd3p-8,0x1.01d6131d09dc5p0
+log,0x1.fdf639bea5ad3p-8,0x1.01fff37a34084p0
+log,0x1.fdf6e4fcf4569p-8,0x1.01fff426c8cb6p0
+log,0x1.fdf6e4fd0426fp-8,0x1.01fff426c8db5p0
+log,0x1.fdfe9c57debe1p-8,0x1.01fffbed922e3p0
+log,-0x1.d17be245122ap3,0x1.028p-21
+log,0x1.6dcb2fed7f25dp-7,0x1.02dfafa07df6dp0
+log,0x1.ff092a85ee03p-7,0x1.040615461f6cap0
+log,0x1.0aa53cea3f1acp-6,0x1.04334eec5a65dp0
+log,0x1.6ea07021c1335p-6,0x1.05cb09bb9fed7p0
+log,0x1.7199f984f5608p-6,0x1.05d735184261cp0
+log,0x1.7788bc9c08318p-6,0x1.05ef7bdee7bep0
+log,0x1.c2688e952a724p-6,0x1.0722a05711778p0
+log,0x1.e02151352512fp-6,0x1.079cf00fe24f9p0
+log,-0x1.3e1fee699c6bcp8,0x1.07cp-459
+log,0x1.f31b56b8b6f1ap-6,0x1.07eb259ee01b5p0
+log,-0x1.d0819095fcd6cp3,0x1.0a8551f8fc7f8p-21
+log,-0x1.0268d40000c72p1,0x1.0fff8p-3
+log,0x1.6b5df7e3cd422p1,0x1.11867637cbd03p4
+log,0x1.6b96cb66f55c2p1,0x1.11ffffffffff8p4
+log,-0x1.f7a213a7cd381p0,0x1.1e6p-3
+log,-0x1.a0765853dec07p8,0x1.206658d9b0f05p-601
+log,0x1.0d7b6ff6e3a24p6,0x1.2514738e6dcadp97
+log,0x1.1ee3899f6818ep1,0x1.2cfbb9e4a1599p3
+log,-0x1.331533367928ap6,0x1.2f0617037e59p-111
+log,-0x1.04c1e6cec9638p3,0x1.2f29fd4b42515p-12
+log,-0x1.0578bc4a143d6p-1,0x1.333e1f03af55ep-1
+log,-0x1.fd2a1d4dcf23ep-2,0x1.3767a0aaf1452p-1
+log,-0x1.fb0ce0ec79bcap-2,0x1.380c640e6246cp-1
+log,-0x1.ee693caa501aap-2,0x1.3bec837d601c1p-1
+log,-0x1.ed67b9b0f2f8ep-2,0x1.3c3cp-1
+log,0x1.25397dc9f85bep1,0x1.3c419b9db662ap3
+log,0x1.9c041f7ed8d33p0,0x1.3ffffffffffffp2
+log,0x1.c8ff7c79a9a22p-3,0x1.4p0
+log,0x1.d42adfec35d14p-3,0x1.41cp0
+log,0x1.d7577477b9eaep-3,0x1.423fc24d04fc6p0
+log,-0x1.d360e90c3850cp-2,0x1.446p-1
+log,-0x1.cdeabe01a86b2p-2,0x1.461c159a76d4bp-1
+log,0x1.fb9186d5e3e24p-3,0x1.47fffffffffffp0
+log,0x1.fb9186d5e3e2ap-3,0x1.48p0
+log,0x1.fb920464f5fc8p-3,0x1.4800141bea83fp0
+log,0x1.fb9c2792045eap-3,0x1.4801b3bf42a4ap0
+log,0x1.fc46718a2dc22p-3,0x1.481cfade8a64dp0
+log,0x1.ff9bd7855aaebp-3,0x1.48a5d0c7ac5b5p0
+log,0x1.ffd65f29bfd4ep-3,0x1.48af356081ca1p0
+log,0x1.e737cb23865c6p-1,0x1.4b8p1
+log,0x1.90ed52d1a23c5p8,0x1.556ee611fa309p578
+log,-0x1.b25b8d863b3b4p3,0x1.55ep-20
+log,0x1.16758a93d29bp6,0x1.5996659966598p100
+log,-0x1.7e3a93bf3540dp-2,0x1.608054de74582p-1
+log,0x1.583a417be2216p-2,0x1.6649bb515354fp0
+log,-0x1.4f7dac3f1d7f4p5,0x1.69b109377f7p-61
+log,0x1.62e42fefa3837p-2,0x1.6a09e667f3b31p0
+log,-0x1.e7a2dd016daa8p1,0x1.6bp-6
+log,0x1.739d7f6bbd006p-2,0x1.7p0
+log,-0x1.4c3af47972063p-2,0x1.7223cef78e25dp-1
+log,-0x1.48e65fe2c2305p-2,0x1.73587ce75368p-1
+log,-0x1.4057b02bfdd0ap-2,0x1.76764087395fcp-1
+log,0x1.4a5f12ed407a4p8,0x1.8ad934b838bdap476
+log,-0x1.83d0f90690d1p1,0x1.8bep-5
+log,-0x1.e387545735931p-1,0x1.8e4p-2
+log,-0x1.fcc59e0136976p-3,0x1.8f6p-1
+log,-0x1.edd6149b33156p-3,0x1.924c57d629082p-1
+log,0x1.cfbe6164a73f2p-2,0x1.92a4cb798664bp0
+log,-0x1.b428216a5c158p4,0x1.98p-40
+log,-0x1.d081f0f25d664p-3,0x1.9819d0255be6p-1
+log,-0x1.cc0d6a92b7916p-1,0x1.a0ef883be2177p-2
+log,-0x1.8f62e2cb65864p-3,0x1.a549336310e6fp-1
+log,-0x1.3651d0de2368ep-3,0x1.b80300c030118p-1
+log,0x1.20f25e686e7fap-1,0x1.c22024dc8289cp0
+log,-0x1.9e327eb6ac2c4p-1,0x1.c8p-2
+log,-0x1.b76f3d0aaf0cap-4,0x1.cbea22c8a9a16p-1
+log,-0x1.9335e5d594992p-4,0x1.cffffffffffffp-1
+log,0x1.b6cc2b05c90a8p2,0x1.dae1894a2dbedp9
+log,-0x1.fc702b8d96d0ep-5,0x1.e1304c1304c13p-1
+log,-0x1.f6c7f7d0b0356p-5,0x1.e185646bc7856p-1
+log,-0x1.eb8dcb764e07ep-5,0x1.e22e7349f6e97p-1
+log,-0x1.d94a9c323e77cp-5,0x1.e341f0592c2abp-1
+log,-0x1.ccb106085394fp-5,0x1.e4005dfd66c32p-1
+log,-0x1.a9bd8afc6d84cp-5,0x1.e61222241ca7fp-1
+log,-0x1.787392a45888ep-5,0x1.e901133e161e4p-1
+log,-0x1.79a634cdfb256p4,0x1.eddc0821c76c1p-35
+log,0x1.5172153d5fe9cp-1,0x1.eed9208a6a349p0
+log,-0x1.12b227244ff98p-5,0x1.ef1dbcea195cdp-1
+log,-0x1.f8a34d2505f81p-6,0x1.f0786fa48bd9cp-1
+log,0x1.06885d03c19c4p1,0x1.f1a945a457d96p2
+log,0x1.a28cccb9c6f0dp6,0x1.f1fffffffffffp150
+log,-0x1.b032da095671ep-6,0x1.f2ab9dee841b5p-1
+log,-0x1.9d66ada690565p-6,0x1.f33e2a944ac96p-1
+log,-0x1.88e7a6bf1b5bap-6,0x1.f3de268394e8dp-1
+log,-0x1.84e362ad21702p-6,0x1.f3fd86b392884p-1
+log,-0x1.744eff6d77ddep-6,0x1.f47f1e1f53f24p-1
+log,-0x1.68b4f86497a0ap0,0x1.f48p-3
+log,-0x1.6f51e68fcd7cep-6,0x1.f4a622df760c9p-1
+log,-0x1.6bab4f93a372p-6,0x1.f4c2b2a5a5c1dp-1
+log,-0x1.65ae4deeda7b8p-6,0x1.f4f18fab5c3b8p-1
+log,-0x1.4c2a64cb22442p-6,0x1.f5b96e5b96eb7p-1
+log,-0x1.43ae6c44b9f76p-6,0x1.f5fbf5cedc48p-1
+log,-0x1.41f7812310c9bp-6,0x1.f60968a5952d9p-1
+log,-0x1.3b0cb0b1469dcp-6,0x1.f63fae6bae321p-1
+log,-0x1.311e67575b4f5p-6,0x1.f68da368da368p-1
+log,-0x1.020da703f2f9dp-6,0x1.f7ffbefc5d9d8p-1
+log,-0x1.0205658935b94p-6,0x1.f7fffffffffe6p-1
+log,-0x1.ae825fe2eb67p-7,0x1.f95139c561139p-1
+log,-0x1.23851c80dddf2p-7,0x1.fb77177fb5d35p-1
+log,-0x1.7c498eb87ed68p-8,0x1.fd09a0b5b17fp-1
+log,-0x1.50dd41aeb4865p-8,0x1.fd6p-1
+log,-0x1.08b8bba5db3a8p-8,0x1.fdef9fe7f9fe3p-1
+log,-0x1.07c989add9f58p-8,0x1.fdf17c5f17cp-1
+log,-0x1.008055958e10bp-8,0x1.fdfffffffff55p-1
+log,-0x1.1f3e47178f97cp-9,0x1.fee1123d05c1bp-1
+log,-0x1.ff7faa9ab1367p-10,0x1.ff007ffffffffp-1
+log,-0x1.ff39ecbe26759p-10,0x1.ff00a2cd88b55p-1
+log,-0x1.6363477698d25p0,0x1.ff020ffffffffp-3
+log,-0x1.f7a248bf22faap-10,0x1.ff046cbe6cbddp-1
+log,-0x1.dae60fee9fa9fp-10,0x1.ff12c3ff12c3p-1
+log,-0x1.d208bc8587776p-10,0x1.ff17309fefcd2p-1
+log,-0x1.babff263eabf8p-12,0x1.ffc8aaff534d4p-1
+log,-0x1.c00c40725b061p-13,0x1.ffe3fffffffffp-1
+log,-0x1.78bfa50041531p-13,0x1.ffe874904abdp-1
+log,-0x1.1148dff957e7cp-13,0x1.ffeeebbaeebb8p-1
+log,-0x1.4aa196aae1ef9p8,0x1.fffffbbffffffp-478
+log,0x1.8e8f43d38041p8,0x1.fffffbbffffffp574
+log,-0x1.0000040100001p-31,0x1.fffffffbfffffp-1
+log,-0x1.ff8040007fc02p-34,0x1.ffffffff003fep-1
+log,0x1.86ef5ccdfa1b1p7,0x1.ffffffffddfffp281
+log,-0x1.0008000000801p-40,0x1.fffffffffdfffp-1
+log,-0x1.0020000000201p-42,0x1.ffffffffff7ffp-1
+log,-0x1.0040000000101p-43,0x1.ffffffffffbffp-1
+log,0x1.30fc1931f09c9p7,0x1.fffffffffffeep219
+log,-0x1.0000000000001p-51,0x1.ffffffffffffcp-1
+log,-0x1.0000000000001p-52,0x1.ffffffffffffep-1
+log,-0x1.03fe55a061c76p-1,0x1.342185798f6d6p-1
+log,-0x1.62e42fefa39f1p-2,0x1.6a09e667f3bccp-1
+log,-0x1.da391c9043a0fp-3,0x1.962b5f9438d25p-1
+log,-0x1.06fbec52082bdp-3,0x1.c24cd8c07de7ep-1
+log,-0x1.1e0a8f670c50bp-5,0x1.ee6e51ecc2fd7p-1
+log,0x1.9e548e7e3dde8p-5,0x1.0d47e58c84098p0
+log,0x1.08e0bae73ac24p-3,0x1.2358a222a6944p0
+log,0x1.9e6462187c36bp-3,0x1.39695eb8c91fp0
+log,0x1.14dd6b0af939bp-2,0x1.4f7a1b4eeba9cp0
+log,0x1.56181f19d7198p-2,0x1.658ad7e50e348p0
+log,0x1.936a82fadcd86p-2,0x1.7b9b947b30bf4p0
+log,0x1.cd45b0a9f2502p-2,0x1.91ac5111534ap0
+log,0x1.02044c9b70627p-1,0x1.a7bd0da775d4cp0
+log,0x1.1c01dad59e73p-1,0x1.bdcdca3d985f8p0
+log,0x1.34bde9b821fe3p-1,0x1.d3de86d3baea4p0
+log,0x1.4c561dbbb21dap-1,0x1.e9ef4369dd75p0
+log,0x1.62e42fefa39ebp-1,0x1.ffffffffffffcp0
+log,-0x1.62e42fefa39f1p-2,0x1.6a09e667f3bccp-1
+log,-0x1.24cfce6f80d9bp-2,0x1.80aa84ce72f89p-1
+log,-0x1.d490246defa6cp-3,0x1.974b2334f2346p-1
+log,-0x1.65d558d4ce00ap-3,0x1.adebc19b71703p-1
+log,-0x1.f991c6cb3b377p-4,0x1.c48c6001f0acp-1
+log,-0x1.31b994d3a4f8p-4,0x1.db2cfe686fe7dp-1
+log,-0x1.ccb73cdddb2b4p-6,0x1.f1cd9cceef23ap-1
+log,0x1.0b94f7c196175p-6,0x1.04371d9ab72fbp0
+log,0x1.e27076e2af2d9p-5,0x1.0f876ccdf6cd9p0
+log,0x1.986d3228180bep-4,0x1.1ad7bc01366b7p0
+log,0x1.1c898c16999f3p-3,0x1.26280b3476095p0
+log,0x1.69d4592a03622p-3,0x1.31785a67b5a73p0
+log,0x1.b44f77bcc8f56p-3,0x1.3cc8a99af5451p0
+log,0x1.fc2d6cf47cf0cp-3,0x1.4818f8ce34e2fp0
+log,0x1.20cdcd192ab65p-2,0x1.536948017480dp0
+log,0x1.426174dbd515ep-2,0x1.5eb99734b41ebp0
+log,0x1.62e42fefa39e5p-2,0x1.6a09e667f3bc9p0
+log,-0x1.269621134db92p-2,0x1.8p-1
+log,-0x1.89fa465cb93c4p-3,0x1.a666666666666p-1
+log,-0x1.af8e8210a4165p-4,0x1.cccccccccccccp-1
+log,-0x1.9ece955321b91p-6,0x1.f333333333332p-1
+log,0x1.8fb063ef2c7d1p-5,0x1.0ccccccccccccp0
+log,0x1.e27076e2af2d8p-4,0x1.1ffffffffffffp0
+log,0x1.7565011e4966ep-3,0x1.3333333333332p0
+log,0x1.f18dc41e8ef17p-3,0x1.4666666666665p0
+log,0x1.334e9e47d07fp-2,0x1.5999999999998p0
+log,0x1.6aac04146152p-2,0x1.6cccccccccccbp0
+log,0x1.9f323ecbf9846p-2,0x1.7fffffffffffep0
+log,0x0.0p0,0x1.0p0
+log,0x1.8663f793c46ccp-4,0x1.199999999999ap0
+log,0x1.7565011e4967cp-3,0x1.3333333333334p0
+log,0x1.0ca937be1b9ep-2,0x1.4cccccccccccep0
+log,0x1.588c2d9133494p-2,0x1.6666666666668p0
+log,0x1.9f323ecbf9851p-2,0x1.8000000000002p0
+log,0x1.e148a1a2726d4p-2,0x1.999999999999cp0
+log,0x1.0fae81914a994p-1,0x1.b333333333336p0
+log,0x1.2cf25fad8f1c7p-1,0x1.cccccccccccdp0
+log,0x1.48a11293d786p-1,0x1.e66666666666ap0
+log,0x1.62e42fefa39efp-1,0x1.0p1
+log,0x1.1542457337d43p6,0x1.0p100
+log,0x1.15a3de711cc55p6,0x1.199999999999ap100
+log,0x1.15fcf7f3c6f8ep6,0x1.3333333333334p100
+log,0x1.164eeeaaf5efdp6,0x1.4cccccccccccep100
+log,0x1.169ad1a0c9077p6,0x1.6666666666668p100
+log,0x1.16e177b203cdbp6,0x1.8000000000002p100
+log,0x1.17238e14da46ap6,0x1.999999999999cp100
+log,0x1.1761a2765a696p6,0x1.b333333333336p100
+log,0x1.179c2a3292f26p6,0x1.cccccccccccdp100
+log,0x1.17d387985f834p6,0x1.e66666666666ap100
+log,0x1.18080dd3171b7p6,0x1.0p101
+log,0x1.1542457337d43p7,0x1.0p200
+log,0x1.157311f22a4ccp7,0x1.199999999999ap200
+log,0x1.159f9eb37f669p7,0x1.3333333333334p200
+log,0x1.15c89a0f16e2p7,0x1.4cccccccccccep200
+log,0x1.15ee8b8a006ddp7,0x1.6666666666668p200
+log,0x1.1611de929dd0fp7,0x1.8000000000002p200
+log,0x1.1632e9c4090d6p7,0x1.999999999999cp200
+log,0x1.1651f3f4c91ecp7,0x1.b333333333336p200
+log,0x1.166f37d2e5635p7,0x1.cccccccccccdp200
+log,0x1.168ae685cbabbp7,0x1.e66666666666ap200
+log,0x1.16a529a32777dp7,0x1.0p201
+log,0x1.5a92d6d005c94p9,0x1.0p1000
+log,-0x1.0000080000555p-20,0x1.ffffep-1
+log,-0x1.0000040000155p-21,0x1.fffffp-1
+log,0x0.0p0,0x1.0p0
+log,0x1.fffff800002abp-22,0x1.000008p0
+log,0x1.fffff00000aabp-21,0x1.00001p0
+log,-0x1.00000002p-30,0x1.fffffff8p-1
+log,-0x1.00000001p-31,0x1.fffffffcp-1
+log,0x0.0p0,0x1.0p0
+log,0x1.fffffffep-32,0x1.00000002p0
+log,0x1.fffffffcp-31,0x1.00000004p0
+log,-0x1.00000000008p-40,0x1.fffffffffep-1
+log,-0x1.00000000004p-41,0x1.ffffffffffp-1
+log,0x0.0p0,0x1.0p0
+log,0x1.ffffffffff8p-42,0x1.00000000008p0
+log,0x1.ffffffffffp-41,0x1.0000000001p0
+log,-0x1.0000000000002p-50,0x1.ffffffffffff8p-1
+log,-0x1.0000000000001p-51,0x1.ffffffffffffcp-1
+log,0x0.0p0,0x1.0p0
+log,0x1.ffffffffffffep-52,0x1.0000000000002p0
+log,0x1.ffffffffffffcp-51,0x1.0000000000004p0
+log,0x1.62e42fefa39efp9,0x1.fffffffffffffp1023
+log,-0x1.74385446d71c3p9,0x0.0000000000001p-1022
+log,-0x1.62e42fefa39f4p-2,0x1.6a09e667f3bcbp-1
+log,-0x1.62e42fefa39f1p-2,0x1.6a09e667f3bccp-1
+log,-0x1.62e42fefa39eep-2,0x1.6a09e667f3bcdp-1
+log,0x1.62e42fefa39ebp-2,0x1.6a09e667f3bcbp0
+log,0x1.62e42fefa39eep-2,0x1.6a09e667f3bccp0
+log,0x1.62e42fefa39fp-2,0x1.6a09e667f3bcdp0
+log,-0x1.62e42fefa39fp-1,0x1.fffffffffffffp-2
+log,-0x1.62e42fefa39efp-1,0x1.0p-1
+log,-0x1.62e42fefa39edp-1,0x1.0000000000001p-1
+log,-0x1.269621134db95p-2,0x1.7ffffffffffffp-1
+log,-0x1.269621134db92p-2,0x1.8p-1
+log,-0x1.269621134db9p-2,0x1.8000000000001p-1
+log,0x1.9f323ecbf9849p-2,0x1.7ffffffffffffp0
+log,0x1.9f323ecbf984cp-2,0x1.8p0
+log,0x1.9f323ecbf984ep-2,0x1.8000000000001p0
+log,0x1.54e3c0b10a364p-9,0x1.00aaaaaaaaaaap0
+log,0x1.54e3c0b10a563p-9,0x1.00aaaaaaaaaabp0
+log,0x1.54e3c0b10a762p-9,0x1.00aaaaaaaaaacp0
+log,0x1.62e42fefa39efp0,0x1.fffffffffffffp1
+log,0x1.62e42fefa39efp0,0x1.0p2
+log,0x1.62e42fefa39fp0,0x1.0000000000001p2
+log,0x1.62e42fefa39eep-1,0x1.fffffffffffffp0
+log,0x1.62e42fefa39efp-1,0x1.0p1
+log,0x1.62e42fefa39f1p-1,0x1.0000000000001p1
+log,-0x1.0p-53,0x1.fffffffffffffp-1
+log,0x0.0p0,0x1.0p0
+log,0x1.fffffffffffffp-53,0x1.0000000000001p0
+log,-0x1.62e42fefa39fp-1,0x1.fffffffffffffp-2
+log,-0x1.62e42fefa39efp-1,0x1.0p-1
+log,-0x1.62e42fefa39edp-1,0x1.0000000000001p-1
+log,-0x1.62e42fefa39fp0,0x1.fffffffffffffp-3
+log,-0x1.62e42fefa39efp0,0x1.0p-2
+log,-0x1.62e42fefa39eep0,0x1.0000000000001p-2
+log,-0x1.0a2b23f3bab74p1,0x1.fffffffffffffp-4
+log,-0x1.0a2b23f3bab73p1,0x1.0p-3
+log,-0x1.0a2b23f3bab73p1,0x1.0000000000001p-3
+log,-0x1.62e42fefa39efp1,0x1.fffffffffffffp-5
+log,-0x1.62e42fefa39efp1,0x1.0p-4
+log,-0x1.62e42fefa39efp1,0x1.0000000000001p-4
+log,-0x1.bb9d3beb8c86bp1,0x1.fffffffffffffp-6
+log,-0x1.bb9d3beb8c86bp1,0x1.0p-5
+log,-0x1.bb9d3beb8c86bp1,0x1.0000000000001p-5
+log,-0x1.0a2b23f3bab74p2,0x1.fffffffffffffp-7
+log,-0x1.0a2b23f3bab73p2,0x1.0p-6
+log,-0x1.0a2b23f3bab73p2,0x1.0000000000001p-6
+log,-0x1.3687a9f1af2b1p2,0x1.fffffffffffffp-8
+log,-0x1.3687a9f1af2b1p2,0x1.0p-7
+log,-0x1.3687a9f1af2b1p2,0x1.0000000000001p-7
+log,-0x1.62e42fefa39efp2,0x1.fffffffffffffp-9
+log,-0x1.62e42fefa39efp2,0x1.0p-8
+log,-0x1.62e42fefa39efp2,0x1.0000000000001p-8
+log,-0x1.8f40b5ed9812dp2,0x1.fffffffffffffp-10
+log,-0x1.8f40b5ed9812dp2,0x1.0p-9
+log,-0x1.8f40b5ed9812dp2,0x1.0000000000001p-9
+log,-0x1.bb9d3beb8c86bp2,0x1.fffffffffffffp-11
+log,-0x1.bb9d3beb8c86bp2,0x1.0p-10
+log,-0x1.bb9d3beb8c86bp2,0x1.0000000000001p-10
+log,-0x1.205966f2b4f12p3,0x1.fffffffffffffp-14
+log,-0x1.205966f2b4f12p3,0x1.0p-13
+log,-0x1.205966f2b4f12p3,0x1.0000000000001p-13
+log,-0x1.205966f2b4f12p3,0x1.fffffffffffffp-14
+log,-0x1.205966f2b4f12p3,0x1.0p-13
+log,-0x1.205966f2b4f12p3,0x1.0000000000001p-13
+log,-0x1.0a2b23f3bab74p1,0x1.fffffffffffffp-4
+log,-0x1.0a2b23f3bab73p1,0x1.0p-3
+log,-0x1.0a2b23f3bab73p1,0x1.0000000000001p-3
+log,-0x1.1178e8227e48p-3,0x1.bffffffffffffp-1
+log,-0x1.1178e8227e47cp-3,0x1.cp-1
+log,-0x1.1178e8227e477p-3,0x1.c000000000001p-1
+log,-0x1.62e42fefa39efp1,0x1.fffffffffffffp-5
+log,-0x1.62e42fefa39efp1,0x1.0p-4
+log,-0x1.62e42fefa39efp1,0x1.0000000000001p-4
+log,-0x1.08598b59e3a0fp-4,0x1.dffffffffffffp-1
+log,-0x1.08598b59e3a07p-4,0x1.ep-1
+log,-0x1.08598b59e39fep-4,0x1.e000000000001p-1
+log,-0x1.bb9d3beb8c86bp1,0x1.fffffffffffffp-6
+log,-0x1.bb9d3beb8c86bp1,0x1.0p-5
+log,-0x1.bb9d3beb8c86bp1,0x1.0000000000001p-5
+log,-0x1.0415d89e74455p-5,0x1.effffffffffffp-1
+log,-0x1.0415d89e74444p-5,0x1.fp-1
+log,-0x1.0415d89e74434p-5,0x1.f000000000001p-1
+log,-0x1.0a2b23f3bab74p2,0x1.fffffffffffffp-7
+log,-0x1.0a2b23f3bab73p2,0x1.0p-6
+log,-0x1.0a2b23f3bab73p2,0x1.0000000000001p-6
+log,-0x1.0205658935868p-6,0x1.f7fffffffffffp-1
+log,-0x1.0205658935847p-6,0x1.f8p-1
+log,-0x1.0205658935827p-6,0x1.f800000000001p-1
+log,-0x1.3687a9f1af2b1p2,0x1.fffffffffffffp-8
+log,-0x1.3687a9f1af2b1p2,0x1.0p-7
+log,-0x1.3687a9f1af2b1p2,0x1.0000000000001p-7
+log,-0x1.010157588deb2p-7,0x1.fbfffffffffffp-1
+log,-0x1.010157588de71p-7,0x1.fcp-1
+log,-0x1.010157588de31p-7,0x1.fc00000000001p-1
+log,-0x1.62e42fefa39efp2,0x1.fffffffffffffp-9
+log,-0x1.62e42fefa39efp2,0x1.0p-8
+log,-0x1.62e42fefa39efp2,0x1.0000000000001p-8
+log,-0x1.0080559588bb6p-8,0x1.fdfffffffffffp-1
+log,-0x1.0080559588b35p-8,0x1.fep-1
+log,-0x1.0080559588ab5p-8,0x1.fe00000000001p-1
+log,-0x1.8f40b5ed9812dp2,0x1.fffffffffffffp-10
+log,-0x1.8f40b5ed9812dp2,0x1.0p-9
+log,-0x1.8f40b5ed9812dp2,0x1.0000000000001p-9
+log,-0x1.0040155d5899ep-9,0x1.fefffffffffffp-1
+log,-0x1.0040155d5889ep-9,0x1.ffp-1
+log,-0x1.0040155d5879dp-9,0x1.ff00000000001p-1
+log,-0x1.bb9d3beb8c86bp2,0x1.fffffffffffffp-11
+log,-0x1.bb9d3beb8c86bp2,0x1.0p-10
+log,-0x1.bb9d3beb8c86bp2,0x1.0000000000001p-10
+log,-0x1.0020055655a8ap-10,0x1.ff7ffffffffffp-1
+log,-0x1.0020055655889p-10,0x1.ff8p-1
+log,-0x1.0020055655689p-10,0x1.ff80000000001p-1
+log,-0x1.205966f2b4f12p3,0x1.fffffffffffffp-14
+log,-0x1.205966f2b4f12p3,0x1.0p-13
+log,-0x1.205966f2b4f12p3,0x1.0000000000001p-13
+log,-0x1.0004001556d56p-13,0x1.ffeffffffffffp-1
+log,-0x1.0004001555d56p-13,0x1.fffp-1
+log,-0x1.0004001554d55p-13,0x1.fff0000000001p-1
+log,0x1.62e42fefa39efp9,0x1.fffffffffffffp1023
+log,0x1.62e42fefa39efp9,0x1.ffffffffffffep1023
+log,0x1.250d048e7a1bdp0,0x1.921fb54442d18p1
+log,0x1.ce6bb25aa1315p-2,0x1.921fb54442d18p0
+log,0x1.fffffffffffffp-53,0x1.0000000000001p0
+log,0x0.0p0,0x1.0p0
+log,-0x1.0p-53,0x1.fffffffffffffp-1
+log,-0x1.eeb95b094c193p-3,0x1.921fb54442d18p-1
+log,-0x1.6232bdd7abcd2p9,0x1.0000000000001p-1022
+log,-0x1.6232bdd7abcd2p9,0x1.0p-1022
+log,-0x1.6232bdd7abcd2p9,0x0.fffffffffffffp-1022
+log,-0x1.6232bdd7abcd2p9,0x0.ffffffffffffep-1022
+log,-0x1.73df9b3adb335p9,0x0.0000000000002p-1022
+log,-0x1.74385446d71c3p9,0x0.0000000000001p-1022
+sin,0x1.9259e3708bd3ap-5,0x1.9283586503fep-5
+sin,-0x1.9259e3708bd3ap-5,-0x1.9283586503fep-5
+sin,0x1.d77b117f230d6p-5,0x1.d7bdcd778049fp-5
+sin,-0x1.d77b117f230d6p-5,-0x1.d7bdcd778049fp-5
+sin,0x1.a1490c8c06ba7p-4,0x1.a202b3fb84788p-4
+sin,-0x1.a1490c8c06ba7p-4,-0x1.a202b3fb84788p-4
+sin,0x1.cc40c3805229ap-3,0x1.d037cb27ee6dfp-3
+sin,-0x1.cc40c3805229ap-3,-0x1.d037cb27ee6dfp-3
+sin,0x1.d0ef799001ba9p-3,0x1.d5064e6fe82c5p-3
+sin,-0x1.d0ef799001ba9p-3,-0x1.d5064e6fe82c5p-3
+sin,0x1.e9950730c4696p-2,0x1.fe767739d0f6dp-2
+sin,-0x1.e9950730c4696p-2,-0x1.fe767739d0f6dp-2
+sin,0x1.98dcd09337793p-1,0x1.d98c4c612718dp-1
+sin,-0x1.98dcd09337793p-1,-0x1.d98c4c612718dp-1
+sin,0x1.0p0,0x1.921fb54442d18p0
+sin,-0x1.0p0,-0x1.921fb54442d18p0
+sin,0x1.70a9d825b5064p-1,-0x1.0000001f8p500
+sin,-0x1.70a9d825b5064p-1,0x1.0000001f8p500
+sin,0x1.bf3980c6c1e9fp-1,-0x1.00c0bf8p700
+sin,-0x1.bf3980c6c1e9fp-1,0x1.00c0bf8p700
+sin,0x1.d62899d48b43ap-4,-0x1.13fffffffff8p6
+sin,-0x1.d62899d48b43ap-4,0x1.13fffffffff8p6
+sin,-0x1.17b7a60ce1f15p-5,-0x1.17c5920767dfcp-5
+sin,0x1.17b7a60ce1f15p-5,0x1.17c5920767dfcp-5
+sin,0x1.f0192b794fbbep-1,-0x1.1d99be08713ccp2
+sin,-0x1.f0192b794fbbep-1,0x1.1d99be08713ccp2
+sin,-0x1.5e61328c0034fp-3,-0x1.1ddbfd64fc0d3p81
+sin,0x1.5e61328c0034fp-3,0x1.1ddbfd64fc0d3p81
+sin,0x1.fb028c5df1db4p-1,-0x1.1e2a1563e068ep7
+sin,-0x1.fb028c5df1db4p-1,0x1.1e2a1563e068ep7
+sin,-0x1.2cefb196ba208p-3,-0x1.2e07a91314dp-3
+sin,0x1.2cefb196ba208p-3,0x1.2e07a91314dp-3
+sin,0x1.b80f489d3edf5p-2,-0x1.3bcec270444e2p3
+sin,-0x1.b80f489d3edf5p-2,0x1.3bcec270444e2p3
+sin,-0x1.4fffffffffa39p-20,-0x1.500000000004p-20
+sin,0x1.4fffffffffa39p-20,0x1.500000000004p-20
+sin,-0x1.d29da5b44f51cp-2,-0x1.559001a42d90cp1
+sin,0x1.d29da5b44f51cp-2,0x1.559001a42d90cp1
+sin,-0x1.f85f526147f78p-1,-0x1.597bf3e9776b7p99
+sin,0x1.f85f526147f78p-1,0x1.597bf3e9776b7p99
+sin,-0x1.6d61b58c99c43p-59,-0x1.6c6cbc45dc8dep7
+sin,0x1.6d61b58c99c43p-59,0x1.6c6cbc45dc8dep7
+sin,0x1.e5c3c08a258a8p-1,-0x1.73d8d173f90dp4
+sin,-0x1.e5c3c08a258a8p-1,0x1.73d8d173f90dp4
+sin,0x1.feb36806ca5fbp-1,-0x1.8c202d3a31802p6
+sin,-0x1.feb36806ca5fbp-1,0x1.8c202d3a31802p6
+sin,-0x1.7c6c7b01b98dap-1,-0x1.acd538b1a6d5dp-1
+sin,0x1.7c6c7b01b98dap-1,0x1.acd538b1a6d5dp-1
+sin,-0x1.191be2059dcb6p-1,-0x1.b7525ac97e0d2p2
+sin,0x1.191be2059dcb6p-1,0x1.b7525ac97e0d2p2
+sin,-0x1.f8305993a212cp-1,-0x1.bee5fa8a84b02p0
+sin,0x1.f8305993a212cp-1,0x1.bee5fa8a84b02p0
+sin,0x1.ff3b13530fd71p-1,-0x1.c393979fe5921p9
+sin,-0x1.ff3b13530fd71p-1,0x1.c393979fe5921p9
+sin,-0x1.f119da81a4da6p-1,-0x1.c48ffc72563c8p18
+sin,0x1.f119da81a4da6p-1,0x1.c48ffc72563c8p18
+sin,-0x1.fd73b81e04cccp-1,-0x1.c79548bc31856p3
+sin,0x1.fd73b81e04cccp-1,0x1.c79548bc31856p3
+sin,-0x1.c7885aef33a95p-3,-0x1.cb6p-3
+sin,0x1.c7885aef33a95p-3,0x1.cb6p-3
+sin,-0x1.e6494911eedd1p-7,-0x1.e64ddaf7bd72fp-7
+sin,0x1.e6494911eedd1p-7,0x1.e64ddaf7bd72fp-7
+sin,0x1.e180eef5b1c88p-1,-0x1.ecdd0fbf07942p5
+sin,-0x1.e180eef5b1c88p-1,0x1.ecdd0fbf07942p5
+sin,-0x1.fd98d20c1be44p-1,-0x1.f073a23292337p2
+sin,0x1.fd98d20c1be44p-1,0x1.f073a23292337p2
+sin,-0x1.7268c112297c8p-5,-0x1.f5e4c410f4ef8p15
+sin,0x1.7268c112297c8p-5,0x1.f5e4c410f4ef8p15
+sin,0x1.420796146070ep-18,-0x1.f8000000002p95
+sin,-0x1.420796146070ep-18,0x1.f8000000002p95
+sin,-0x1.e4f6dc499d9ccp-2,-0x1.f9365d79546e1p-2
+sin,0x1.e4f6dc499d9ccp-2,0x1.f9365d79546e1p-2
+sin,0x1.b2ef99b140d65p-14,-0x1.ffffffffffe7ep1023
+sin,-0x1.b2ef99b140d65p-14,0x1.ffffffffffe7ep1023
+sin,0x1.db0ffc3ecc6e4p-1,0x1.0p15
+sin,-0x1.db0ffc3ecc6e4p-1,-0x1.0p15
+sin,-0x1.e98f87098b627p-1,0x1.0000000000001p13
+sin,0x1.e98f87098b627p-1,-0x1.0000000000001p13
+sin,0x1.053c35068e10dp-4,0x1.0000000000001p52
+sin,-0x1.053c35068e10dp-4,-0x1.0000000000001p52
+sin,0x1.72d421b6884e5p-1,0x1.0000000000001p228
+sin,-0x1.72d421b6884e5p-1,-0x1.0000000000001p228
+sin,0x1.77fba987c5654p-1,0x1.0000000000001p491
+sin,-0x1.77fba987c5654p-1,-0x1.0000000000001p491
+sin,-0x1.723b2625331afp-1,0x1.0000000000003p215
+sin,0x1.723b2625331afp-1,-0x1.0000000000003p215
+sin,0x1.aed548f090cf5p-1,0x1.0000000000006p0
+sin,-0x1.aed548f090cf5p-1,-0x1.0000000000006p0
+sin,-0x1.ff983208c7dc9p-1,0x1.0000000000007p8
+sin,0x1.ff983208c7dc9p-1,-0x1.0000000000007p8
+sin,0x1.ffef29dc38453p-1,0x1.0000000000007p275
+sin,-0x1.ffef29dc38453p-1,-0x1.0000000000007p275
+sin,-0x1.fa88c375723c1p-8,0x1.0000000000007p449
+sin,0x1.fa88c375723c1p-8,-0x1.0000000000007p449
+sin,0x1.fff5322c94eaep-1,0x1.0000000000011p644
+sin,-0x1.fff5322c94eaep-1,-0x1.0000000000011p644
+sin,-0x1.a73630af8f15cp-1,0x1.000000000001fp164
+sin,0x1.a73630af8f15cp-1,-0x1.000000000001fp164
+sin,0x1.1c548f9249e44p-2,0x1.0000000000038p380
+sin,-0x1.1c548f9249e44p-2,-0x1.0000000000038p380
+sin,0x1.ca965bd2c4dffp-3,0x1.0000000000118p380
+sin,-0x1.ca965bd2c4dffp-3,-0x1.0000000000118p380
+sin,-0x1.837b9dddc24dp-1,0x1.000000000012cp2
+sin,0x1.837b9dddc24dp-1,-0x1.000000000012cp2
+sin,0x1.d82c1784c3eccp-2,0x1.00000000001f8p700
+sin,-0x1.d82c1784c3eccp-2,-0x1.00000000001f8p700
+sin,0x1.fffeaaaaef2eep-8,0x1.00000000002p-7
+sin,-0x1.fffeaaaaef2eep-8,-0x1.00000000002p-7
+sin,-0x1.0871bddd90fc6p-1,0x1.00000000002p40
+sin,0x1.0871bddd90fc6p-1,-0x1.00000000002p40
+sin,0x1.fffeaaaaef2fp-8,0x1.0000000000201p-7
+sin,-0x1.fffeaaaaef2fp-8,-0x1.0000000000201p-7
+sin,0x1.fffeaaaaef33p-8,0x1.0000000000221p-7
+sin,-0x1.fffeaaaaef33p-8,-0x1.0000000000221p-7
+sin,0x1.fffeaaaaef362p-8,0x1.000000000023ap-7
+sin,-0x1.fffeaaaaef362p-8,-0x1.000000000023ap-7
+sin,0x1.e0c6edfa93601p-9,0x1.0000000004p45
+sin,-0x1.e0c6edfa93601p-9,-0x1.0000000004p45
+sin,0x1.ea1f618356db1p-5,0x1.0000000cp40
+sin,-0x1.ea1f618356db1p-5,-0x1.0000000cp40
+sin,0x1.faaeed7587542p-3,0x1.00000013c86f4p-2
+sin,-0x1.faaeed7587542p-3,-0x1.00000013c86f4p-2
+sin,0x1.540bc7785680bp-1,0x1.001p13
+sin,-0x1.540bc7785680bp-1,-0x1.001p13
+sin,-0x1.37a7cb907a2e5p-1,0x1.003p699
+sin,0x1.37a7cb907a2e5p-1,-0x1.003p699
+sin,-0x1.29e5845fc54b5p-1,0x1.0038p40
+sin,0x1.29e5845fc54b5p-1,-0x1.0038p40
+sin,0x1.ffe5ca4656491p-1,0x1.007p10
+sin,-0x1.ffe5ca4656491p-1,-0x1.007p10
+sin,0x1.ea4df82db014bp-1,0x1.007p25
+sin,-0x1.ea4df82db014bp-1,-0x1.007p25
+sin,0x1.fe757aef1c80cp-1,0x1.007p41
+sin,-0x1.fe757aef1c80cp-1,-0x1.007p41
+sin,0x1.e9b71805ec068p-7,0x1.00cp41
+sin,-0x1.e9b71805ec068p-7,-0x1.00cp41
+sin,0x1.b0b6d0a540583p-1,0x1.01c00000001p0
+sin,-0x1.b0b6d0a540583p-1,-0x1.01c00000001p0
+sin,0x1.fef0092627012p-3,0x1.02322e46da919p-2
+sin,-0x1.fef0092627012p-3,-0x1.02322e46da919p-2
+sin,0x1.ffc90059804a1p-3,0x1.02a236478p-2
+sin,-0x1.ffc90059804a1p-3,-0x1.02a236478p-2
+sin,0x1.ffd10a6b5429fp-3,0x1.02a65d08ca5e5p-2
+sin,-0x1.ffd10a6b5429fp-3,-0x1.02a65d08ca5e5p-2
+sin,0x1.ffd10ab302a3fp-3,0x1.02a65d2dce49ap-2
+sin,-0x1.ffd10ab302a3fp-3,-0x1.02a65d2dce49ap-2
+sin,0x1.ffe0b1764ca4cp-3,0x1.02ae7238ap-2
+sin,-0x1.ffe0b1764ca4cp-3,-0x1.02ae7238ap-2
+sin,-0x1.f68f0e26c0f6bp-3,0x1.0501d22221dacp621
+sin,0x1.f68f0e26c0f6bp-3,-0x1.0501d22221dacp621
+sin,0x1.b63c41f09eb75p-1,0x1.06ffffffffff8p0
+sin,-0x1.b63c41f09eb75p-1,-0x1.06ffffffffff8p0
+sin,-0x1.ffdc173adabb2p-1,0x1.07023d3d44215p12
+sin,0x1.ffdc173adabb2p-1,-0x1.07023d3d44215p12
+sin,0x1.0889e11bef135p-5,0x1.0895a7a3e8ae6p-5
+sin,-0x1.0889e11bef135p-5,-0x1.0895a7a3e8ae6p-5
+sin,0x1.08ca077c76445p-5,0x1.08d5d69840601p-5
+sin,-0x1.08ca077c76445p-5,-0x1.08d5d69840601p-5
+sin,-0x1.ff7fbe518023fp-1,0x1.0ep6
+sin,0x1.ff7fbe518023fp-1,-0x1.0ep6
+sin,-0x1.fd6c68b877afep-1,0x1.107ba49c346e4p9
+sin,0x1.fd6c68b877afep-1,-0x1.107ba49c346e4p9
+sin,-0x1.a2ba6bc70bce4p-1,0x1.149154477444p745
+sin,0x1.a2ba6bc70bce4p-1,-0x1.149154477444p745
+sin,0x1.165609790f235p-5,0x1.1663c0e51818p-5
+sin,-0x1.165609790f235p-5,-0x1.1663c0e51818p-5
+sin,-0x1.fc0523ff94e45p-1,0x1.1745d1745d176p238
+sin,0x1.fc0523ff94e45p-1,-0x1.1745d1745d176p238
+sin,0x1.f34a729c584bdp-1,0x1.17472a408a3ep97
+sin,-0x1.f34a729c584bdp-1,-0x1.17472a408a3ep97
+sin,0x1.177fae169fdf1p-5,0x1.178d91b6b992dp-5
+sin,-0x1.177fae169fdf1p-5,-0x1.178d91b6b992dp-5
+sin,0x1.177fae16a120fp-5,0x1.178d91b6bad4ep-5
+sin,-0x1.177fae16a120fp-5,-0x1.178d91b6bad4ep-5
+sin,0x1.177fae16a1f79p-5,0x1.178d91b6bbabap-5
+sin,-0x1.177fae16a1f79p-5,-0x1.178d91b6bbabap-5
+sin,0x1.177fae16a40ffp-5,0x1.178d91b6bdc45p-5
+sin,-0x1.177fae16a40ffp-5,-0x1.178d91b6bdc45p-5
+sin,0x1.297c768f2413p-1,0x1.19752dbee5f6ap933
+sin,-0x1.297c768f2413p-1,-0x1.19752dbee5f6ap933
+sin,0x1.b826df5cafafap-2,0x1.1b3009cfe4dbcp8
+sin,-0x1.b826df5cafafap-2,-0x1.1b3009cfe4dbcp8
+sin,0x1.b7a5956250b6bp-2,0x1.1f6475d95bf18p3
+sin,-0x1.b7a5956250b6bp-2,-0x1.1f6475d95bf18p3
+sin,0x1.4db6566b64548p-1,0x1.229148a452291p118
+sin,-0x1.4db6566b64548p-1,-0x1.229148a452291p118
+sin,0x1.1686fee2c49a8p-1,0x1.268p-1
+sin,-0x1.1686fee2c49a8p-1,-0x1.268p-1
+sin,0x1.22eb21a44d627p-2,0x1.26fb3844dd19p-2
+sin,-0x1.22eb21a44d627p-2,-0x1.26fb3844dd19p-2
+sin,0x1.d4a216d89b2b3p-1,0x1.27fffffffe6bp0
+sin,-0x1.d4a216d89b2b3p-1,-0x1.27fffffffe6bp0
+sin,-0x1.76c9b0f3a22f8p-1,0x1.284b84048d481p204
+sin,0x1.76c9b0f3a22f8p-1,-0x1.284b84048d481p204
+sin,-0x1.ff01226f97d33p-1,0x1.2999e3109cad4p2
+sin,0x1.ff01226f97d33p-1,-0x1.2999e3109cad4p2
+sin,0x1.2a8f11e7ae82cp-5,0x1.2aap-5
+sin,-0x1.2a8f11e7ae82cp-5,-0x1.2aap-5
+sin,0x1.2b03d1bf773dfp-5,0x1.2b14d3be0c23p-5
+sin,-0x1.2b03d1bf773dfp-5,-0x1.2b14d3be0c23p-5
+sin,-0x1.ffb90ee641792p-1,0x1.2b7cb44849981p2
+sin,0x1.ffb90ee641792p-1,-0x1.2b7cb44849981p2
+sin,-0x1.ffffff79e71a4p-1,0x1.2becc8685258p200
+sin,0x1.ffffff79e71a4p-1,-0x1.2becc8685258p200
+sin,-0x1.fff9edaf85b77p-1,0x1.2cfa14ce27cd5p2
+sin,0x1.fff9edaf85b77p-1,-0x1.2cfa14ce27cd5p2
+sin,0x1.2cbaaa4cebb52p-4,0x1.2dp-4
+sin,-0x1.2cbaaa4cebb52p-4,-0x1.2dp-4
+sin,-0x1.ffffbc177e01p-1,0x1.2d76d18721be8p2
+sin,0x1.ffffbc177e01p-1,-0x1.2d76d18721be8p2
+sin,0x1.745843dfafefdp-18,0x1.302a494e0909p97
+sin,-0x1.745843dfafefdp-18,-0x1.302a494e0909p97
+sin,0x1.ffcc568d42376p-1,0x1.31cc731cc731cp1000
+sin,-0x1.ffcc568d42376p-1,-0x1.31cc731cc731cp1000
+sin,0x1.b676077d4faf8p-1,0x1.328463d4f8ca6p441
+sin,-0x1.b676077d4faf8p-1,-0x1.328463d4f8ca6p441
+sin,-0x1.0p0,0x1.32ce90b32171ep18
+sin,0x1.0p0,-0x1.32ce90b32171ep18
+sin,0x1.35cbd3240d149p-5,0x1.35debd7f020ecp-5
+sin,-0x1.35cbd3240d149p-5,-0x1.35debd7f020ecp-5
+sin,0x1.3bb2086559faap-7,0x1.3bb3487893405p-7
+sin,-0x1.3bb2086559faap-7,-0x1.3bb3487893405p-7
+sin,0x1.3bb2086559facp-7,0x1.3bb3487893407p-7
+sin,-0x1.3bb2086559facp-7,-0x1.3bb3487893407p-7
+sin,0x1.dff197edc51d2p-16,0x1.3bb681d65aa6p100
+sin,-0x1.dff197edc51d2p-16,-0x1.3bb681d65aa6p100
+sin,-0x1.5d08d3dbb41bp-3,0x1.3f9aa8626042fp83
+sin,0x1.5d08d3dbb41bp-3,-0x1.3f9aa8626042fp83
+sin,0x1.fb503983f94bbp-3,0x1.3fep19
+sin,-0x1.fb503983f94bbp-3,-0x1.3fep19
+sin,-0x1.d3876eacc9ee7p-1,0x1.4285478f1e3c8p58
+sin,0x1.d3876eacc9ee7p-1,-0x1.4285478f1e3c8p58
+sin,0x1.42b66d54f69c1p-5,0x1.42cbcf45a169ep-5
+sin,-0x1.42b66d54f69c1p-5,-0x1.42cbcf45a169ep-5
+sin,0x1.b45e9e9427554p-1,0x1.43fffffffff6ap557
+sin,-0x1.b45e9e9427554p-1,-0x1.43fffffffff6ap557
+sin,0x1.43ffffffea603p-17,0x1.44p-17
+sin,-0x1.43ffffffea603p-17,-0x1.44p-17
+sin,-0x1.6a4e98d2d8b1cp-1,0x1.4748c08dc0976p200
+sin,0x1.6a4e98d2d8b1cp-1,-0x1.4748c08dc0976p200
+sin,-0x1.b57ca8aacf2a9p-1,0x1.478fc08p43
+sin,0x1.b57ca8aacf2a9p-1,-0x1.478fc08p43
+sin,0x1.ffe38008ef6b5p-1,0x1.4cf36d17c596ep200
+sin,-0x1.ffe38008ef6b5p-1,-0x1.4cf36d17c596ep200
+sin,0x1.d6457a3f12e6cp-1,0x1.4f0f308p488
+sin,-0x1.d6457a3f12e6cp-1,-0x1.4f0f308p488
+sin,0x1.4fffffffff9f9p-20,0x1.5p-20
+sin,-0x1.4fffffffff9f9p-20,-0x1.5p-20
+sin,-0x1.cbad095f503a2p-1,0x1.5143e25a488f1p3
+sin,0x1.cbad095f503a2p-1,-0x1.5143e25a488f1p3
+sin,-0x1.f942d6262e82ep-5,0x1.51f0f44da4df4p200
+sin,0x1.f942d6262e82ep-5,-0x1.51f0f44da4df4p200
+sin,-0x1.fc466ccaece8p-3,0x1.52ad6c5a3602fp16
+sin,0x1.fc466ccaece8p-3,-0x1.52ad6c5a3602fp16
+sin,0x1.d69c3cf4eecdep-1,0x1.52f00ep793
+sin,-0x1.d69c3cf4eecdep-1,-0x1.52f00ep793
+sin,0x1.e120292f3d495p-1,0x1.5555555555556p239
+sin,-0x1.e120292f3d495p-1,-0x1.5555555555556p239
+sin,-0x1.fd1d85b7ef004p-1,0x1.5a0000008p6
+sin,0x1.fd1d85b7ef004p-1,-0x1.5a0000008p6
+sin,0x1.5aff9664b07e2p-6,0x1.5b063ad2dd08fp-6
+sin,-0x1.5aff9664b07e2p-6,-0x1.5b063ad2dd08fp-6
+sin,-0x1.83f8bbb59f2f8p-1,0x1.5b179d75fa285p2
+sin,0x1.83f8bbb59f2f8p-1,-0x1.5b179d75fa285p2
+sin,0x1.fa865b0d99497p-1,0x1.5bb5967402f9cp79
+sin,-0x1.fa865b0d99497p-1,-0x1.5bb5967402f9cp79
+sin,0x1.e8a523fce884dp-2,0x1.5bea01p468
+sin,-0x1.e8a523fce884dp-2,-0x1.5bea01p468
+sin,-0x1.ff2ad941f0a41p-1,0x1.5f19fbc507af6p9
+sin,0x1.ff2ad941f0a41p-1,-0x1.5f19fbc507af6p9
+sin,-0x1.75ce4a0d0bd03p-1,0x1.60a610a658da9p889
+sin,0x1.75ce4a0d0bd03p-1,-0x1.60a610a658da9p889
+sin,-0x1.721586594ab48p-1,0x1.62ad7ce17143dp62
+sin,0x1.721586594ab48p-1,-0x1.62ad7ce17143dp62
+sin,0x1.b8d27019d1b9fp-2,0x1.645926cc1132cp9
+sin,-0x1.b8d27019d1b9fp-2,-0x1.645926cc1132cp9
+sin,0x1.647e09059c1eap-9,0x1.647e25d391f17p-9
+sin,-0x1.647e09059c1eap-9,-0x1.647e25d391f17p-9
+sin,-0x1.8d3b53ff85a82p-1,0x1.64ef438p142
+sin,0x1.8d3b53ff85a82p-1,-0x1.64ef438p142
+sin,-0x1.f7c8630e62a02p-1,0x1.6599665996658p3
+sin,0x1.f7c8630e62a02p-1,-0x1.6599665996658p3
+sin,0x1.67028e3602035p-5,0x1.672p-5
+sin,-0x1.67028e3602035p-5,-0x1.672p-5
+sin,0x1.bc60c8c33cb5fp-2,0x1.688ae6c138ea8p299
+sin,-0x1.bc60c8c33cb5fp-2,-0x1.688ae6c138ea8p299
+sin,-0x1.fc3b4bb8b012ep-1,0x1.6aa78p17
+sin,0x1.fc3b4bb8b012ep-1,-0x1.6aa78p17
+sin,0x1.0p0,0x1.6ac5b262ca1ffp849
+sin,-0x1.0p0,-0x1.6ac5b262ca1ffp849
+sin,-0x1.82317836a97c8p-1,0x1.6d88083749412p4
+sin,0x1.82317836a97c8p-1,-0x1.6d88083749412p4
+sin,0x1.6f781c78cc82bp-6,0x1.6f8p-6
+sin,-0x1.6f781c78cc82bp-6,-0x1.6f8p-6
+sin,-0x1.fdbe5085494aep-1,0x1.729aa6859d1f4p396
+sin,0x1.fdbe5085494aep-1,-0x1.729aa6859d1f4p396
+sin,-0x1.fffffae862b5p-1,0x1.73e2dbe9a2f8p10
+sin,0x1.fffffae862b5p-1,-0x1.73e2dbe9a2f8p10
+sin,0x1.769ac74459b06p-7,0x1.769cde0b90b8p-7
+sin,-0x1.769ac74459b06p-7,-0x1.769cde0b90b8p-7
+sin,0x1.769e8afb6a4ecp-5,0x1.76cp-5
+sin,-0x1.769e8afb6a4ecp-5,-0x1.76cp-5
+sin,0x1.fd562611f5bd4p-1,0x1.78001p0
+sin,-0x1.fd562611f5bd4p-1,-0x1.78001p0
+sin,0x1.fdba784ca00f2p-1,0x1.7ap0
+sin,-0x1.fdba784ca00f2p-1,-0x1.7ap0
+sin,0x1.f930c222a8683p-5,0x1.7abd870381c2dp38
+sin,-0x1.f930c222a8683p-5,-0x1.7abd870381c2dp38
+sin,0x1.ffeb2ff2b6923p-1,0x1.7dc945c21248p95
+sin,-0x1.ffeb2ff2b6923p-1,-0x1.7dc945c21248p95
+sin,0x1.b279153c23fb2p-2,0x1.7f73e1594b70cp98
+sin,-0x1.b279153c23fb2p-2,-0x1.7f73e1594b70cp98
+sin,-0x1.599fad35cf60bp-41,0x1.7f7ef77e83f1ap21
+sin,0x1.599fad35cf60bp-41,-0x1.7f7ef77e83f1ap21
+sin,0x1.feb7a9b2c6d8bp-1,0x1.8p0
+sin,-0x1.feb7a9b2c6d8bp-1,-0x1.8p0
+sin,0x1.f798d01ec615cp-1,0x1.8p6
+sin,-0x1.f798d01ec615cp-1,-0x1.8p6
+sin,0x1.fee1a2a977bcfp-1,0x1.8132ceb1c4f39p0
+sin,-0x1.fee1a2a977bcfp-1,-0x1.8132ceb1c4f39p0
+sin,-0x1.24245af4cd995p-52,0x1.81ae0dffa3b33p959
+sin,0x1.24245af4cd995p-52,-0x1.81ae0dffa3b33p959
+sin,0x1.85d41b0bf3091p-4,0x1.85ec5a399a2e6p1
+sin,-0x1.85d41b0bf3091p-4,-0x1.85ec5a399a2e6p1
+sin,0x1.1e42ae3cfbdc6p-24,0x1.86a0092754022p16
+sin,-0x1.1e42ae3cfbdc6p-24,-0x1.86a0092754022p16
+sin,-0x1.dbf4e594cefe1p-1,0x1.8720588p392
+sin,0x1.dbf4e594cefe1p-1,-0x1.8720588p392
+sin,0x1.44302d6a82d4p-9,0x1.8929354ebc6aap43
+sin,-0x1.44302d6a82d4p-9,-0x1.8929354ebc6aap43
+sin,0x1.8a52189ec3487p-5,0x1.8a791e4791e75p-5
+sin,-0x1.8a52189ec3487p-5,-0x1.8a791e4791e75p-5
+sin,-0x1.fe8566e538123p-1,0x1.8ba761438f5edp11
+sin,0x1.fe8566e538123p-1,-0x1.8ba761438f5edp11
+sin,0x1.fff42aca4cb5ap-1,0x1.8eaf16de6392p0
+sin,-0x1.fff42aca4cb5ap-1,-0x1.8eaf16de6392p0
+sin,0x1.fffb7d3f3a253p-1,0x1.9p0
+sin,-0x1.fffb7d3f3a253p-1,-0x1.9p0
+sin,-0x1.e815770667fd9p-4,0x1.91a5657fb6a9ap6
+sin,0x1.e815770667fd9p-4,-0x1.91a5657fb6a9ap6
+sin,-0x1.fffffffd311dcp-1,0x1.921fb54468847p37
+sin,0x1.fffffffd311dcp-1,-0x1.921fb54468847p37
+sin,0x1.ffffffff875e6p-17,0x1.921ff54442d18p2
+sin,-0x1.ffffffff875e6p-17,-0x1.921ff54442d18p2
+sin,0x1.812a5da3777cdp-8,0x1.928p2
+sin,-0x1.812a5da3777cdp-8,-0x1.928p2
+sin,0x1.fff9be8d82573p-1,0x1.94ap0
+sin,-0x1.fff9be8d82573p-1,-0x1.94ap0
+sin,0x1.947b0ace235f3p-5,0x1.94a5294a51bdep-5
+sin,-0x1.947b0ace235f3p-5,-0x1.94a5294a51bdep-5
+sin,0x1.c34f70e55a708p-2,0x1.94a5294a52948p100
+sin,-0x1.c34f70e55a708p-2,-0x1.94a5294a52948p100
+sin,0x1.950bcfc0f3d51p-5,0x1.95361b8f7697dp-5
+sin,-0x1.950bcfc0f3d51p-5,-0x1.95361b8f7697dp-5
+sin,0x1.6c548bfcce696p-1,0x1.956p-1
+sin,-0x1.6c548bfcce696p-1,-0x1.956p-1
+sin,0x1.ffeffdbf67ca6p-1,0x1.962p0
+sin,-0x1.ffeffdbf67ca6p-1,-0x1.962p0
+sin,0x1.9708213bf67f5p-5,0x1.97330d2ea16d9p-5
+sin,-0x1.9708213bf67f5p-5,-0x1.97330d2ea16d9p-5
+sin,0x1.972bf92713d51p-5,0x1.9756f073b6b61p-5
+sin,-0x1.972bf92713d51p-5,-0x1.9756f073b6b61p-5
+sin,0x1.976845ebe7119p-5,0x1.97935055cec1bp-5
+sin,-0x1.976845ebe7119p-5,-0x1.97935055cec1bp-5
+sin,0x1.97535cee51a43p-4,0x1.98p-4
+sin,-0x1.97535cee51a43p-4,-0x1.98p-4
+sin,0x1.6f494c3356177p-1,0x1.999999a42160cp-1
+sin,-0x1.6f494c3356177p-1,-0x1.999999a42160cp-1
+sin,0x1.6f494c37edd6ep-1,0x1.999999aab8f5p-1
+sin,-0x1.6f494c37edd6ep-1,-0x1.999999aab8f5p-1
+sin,0x1.6fa912bdeaab2p-1,0x1.9a2324b9c6326p-1
+sin,-0x1.6fa912bdeaab2p-1,-0x1.9a2324b9c6326p-1
+sin,0x1.70c7ef4ef9b34p-1,0x1.9bcp-1
+sin,-0x1.70c7ef4ef9b34p-1,-0x1.9bcp-1
+sin,0x1.ff28176ad3164p-1,0x1.a0d1d817d6c4ap0
+sin,-0x1.ff28176ad3164p-1,-0x1.a0d1d817d6c4ap0
+sin,0x1.749468a7248dep-1,0x1.a141c9de12fdfp-1
+sin,-0x1.749468a7248dep-1,-0x1.a141c9de12fdfp-1
+sin,0x1.754ebb7e73f46p-1,0x1.a251bc6766f2p-1
+sin,-0x1.754ebb7e73f46p-1,-0x1.a251bc6766f2p-1
+sin,-0x1.7c3bfefa74bd1p-1,0x1.a2689ae1b86ddp62
+sin,0x1.7c3bfefa74bd1p-1,-0x1.a2689ae1b86ddp62
+sin,-0x1.ffff4f3648e03p-1,0x1.a3f66180c455p100
+sin,0x1.ffff4f3648e03p-1,-0x1.a3f66180c455p100
+sin,-0x1.1cf463983c0e3p-3,0x1.a3fdd2a5286c3p1
+sin,0x1.1cf463983c0e3p-3,-0x1.a3fdd2a5286c3p1
+sin,0x1.feb7948d224d8p-1,0x1.a44p0
+sin,-0x1.feb7948d224d8p-1,-0x1.a44p0
+sin,0x1.78801e3e11665p-1,0x1.a701ef3c7d54bp-1
+sin,-0x1.78801e3e11665p-1,-0x1.a701ef3c7d54bp-1
+sin,-0x1.fff11e871d59cp-1,0x1.a8c01fd43cp537
+sin,0x1.fff11e871d59cp-1,-0x1.a8c01fd43cp537
+sin,0x1.fdfa4366eb733p-1,0x1.a8e29b7602f3bp0
+sin,-0x1.fdfa4366eb733p-1,-0x1.a8e29b7602f3bp0
+sin,0x1.fde98b94e7948p-1,0x1.a94p0
+sin,-0x1.fde98b94e7948p-1,-0x1.a94p0
+sin,0x1.7931cba100008p-2,0x1.aa445fce93b82p2
+sin,-0x1.7931cba100008p-2,-0x1.aa445fce93b82p2
+sin,0x1.7af3f76c7a708p-1,0x1.aaa3fbc359fbep-1
+sin,-0x1.7af3f76c7a708p-1,-0x1.aaa3fbc359fbep-1
+sin,0x1.fd74e53ae32fdp-6,0x1.abdd3dbd4d86p119
+sin,-0x1.fd74e53ae32fdp-6,-0x1.abdd3dbd4d86p119
+sin,0x1.7d4a7bf183a34p-1,0x1.ae2165a0c9f8ep-1
+sin,-0x1.7d4a7bf183a34p-1,-0x1.ae2165a0c9f8ep-1
+sin,0x1.b81410edc79e1p-2,0x1.ae8dfefcfe13bp2
+sin,-0x1.b81410edc79e1p-2,-0x1.ae8dfefcfe13bp2
+sin,-0x1.ff751561dc50ap-2,0x1.b5597f950ee8cp29
+sin,0x1.ff751561dc50ap-2,-0x1.b5597f950ee8cp29
+sin,0x1.027d184afb198p-52,0x1.bab62ed655019p970
+sin,-0x1.027d184afb198p-52,-0x1.bab62ed655019p970
+sin,0x1.bc572e5e413e1p-10,0x1.bc573c4ffffffp-10
+sin,-0x1.bc572e5e413e1p-10,-0x1.bc573c4ffffffp-10
+sin,0x1.fb300f1e39afep-1,0x1.bef5cd25ab1adp9
+sin,-0x1.fb300f1e39afep-1,-0x1.bef5cd25ab1adp9
+sin,0x1.b1baaf622d3a3p-2,0x1.bfdf6df2a24c1p-2
+sin,-0x1.b1baaf622d3a3p-2,-0x1.bfdf6df2a24c1p-2
+sin,0x1.88fb762c35ce4p-1,0x1.bfffffdffffffp-1
+sin,-0x1.88fb762c35ce4p-1,-0x1.bfffffdffffffp-1
+sin,0x1.fe0ebff99ab8dp-1,0x1.c2b489520e376p920
+sin,-0x1.fe0ebff99ab8dp-1,-0x1.c2b489520e376p920
+sin,0x1.cf7f749f2a836p-4,0x1.c54beb008547p5
+sin,-0x1.cf7f749f2a836p-4,-0x1.c54beb008547p5
+sin,0x1.b6facf6658915p-2,0x1.c5ad34f5f472ap-2
+sin,-0x1.b6facf6658915p-2,-0x1.c5ad34f5f472ap-2
+sin,0x1.b851cd9b84ee7p-2,0x1.c728fc2f34bd6p-2
+sin,-0x1.b851cd9b84ee7p-2,-0x1.c728fc2f34bd6p-2
+sin,0x1.ba21b53cf2ff3p-2,0x1.c92b0f6105089p-2
+sin,-0x1.ba21b53cf2ff3p-2,-0x1.c92b0f6105089p-2
+sin,0x1.c9a2b68e30ec7p-5,0x1.c9dfbbe9ec704p-5
+sin,-0x1.c9a2b68e30ec7p-5,-0x1.c9dfbbe9ec704p-5
+sin,0x1.f370115c9ab35p-1,0x1.caf31bd7ee217p0
+sin,-0x1.f370115c9ab35p-1,-0x1.caf31bd7ee217p0
+sin,-0x1.dd38a1f1d289bp-54,0x1.cb44e86bc192bp648
+sin,0x1.dd38a1f1d289bp-54,-0x1.cb44e86bc192bp648
+sin,0x1.dd38a1f1d289bp-53,0x1.cb44e86bc192bp649
+sin,-0x1.dd38a1f1d289bp-53,-0x1.cb44e86bc192bp649
+sin,0x1.c7885aef33a95p-3,0x1.cb6p-3
+sin,-0x1.c7885aef33a95p-3,-0x1.cb6p-3
+sin,0x1.cd279aa6196b6p-4,0x1.ce2271d2f662fp-4
+sin,-0x1.cd279aa6196b6p-4,-0x1.ce2271d2f662fp-4
+sin,0x1.930b705f9fad2p-1,0x1.d0000000004p-1
+sin,-0x1.930b705f9fad2p-1,-0x1.d0000000004p-1
+sin,0x1.7ef24c8e67d9ap-1,0x1.d01p199
+sin,-0x1.7ef24c8e67d9ap-1,-0x1.d01p199
+sin,0x1.ffff124c001abp-1,0x1.d024ba6f953cfp1000
+sin,-0x1.ffff124c001abp-1,-0x1.d024ba6f953cfp1000
+sin,-0x1.f83a0983dd15dp-2,0x1.d4067c60f471ep1
+sin,0x1.f83a0983dd15dp-2,-0x1.d4067c60f471ep1
+sin,0x1.d79b9896ff555p-5,0x1.d7de6263bcaabp-5
+sin,-0x1.d79b9896ff555p-5,-0x1.d7de6263bcaabp-5
+sin,0x1.ed0b908a2983p-1,0x1.d800000002274p0
+sin,-0x1.ed0b908a2983p-1,-0x1.d800000002274p0
+sin,-0x1.f2c217cbc7dcdp-1,0x1.d96e058p488
+sin,0x1.f2c217cbc7dcdp-1,-0x1.d96e058p488
+sin,0x1.98dcd09337793p-1,0x1.d98c4c612718dp-1
+sin,-0x1.98dcd09337793p-1,-0x1.d98c4c612718dp-1
+sin,0x1.db3ba8775ca26p-5,0x1.db8p-5
+sin,-0x1.db3ba8775ca26p-5,-0x1.db8p-5
+sin,-0x1.9fee37697d582p-2,0x1.de386d6090303p200
+sin,0x1.9fee37697d582p-2,-0x1.de386d6090303p200
+sin,-0x1.5361ee6553188p-53,0x1.de5e5054e921bp35
+sin,0x1.5361ee6553188p-53,-0x1.de5e5054e921bp35
+sin,0x1.fec48d5e769ecp-1,0x1.df77ddf77ddf4p10
+sin,-0x1.fec48d5e769ecp-1,-0x1.df77ddf77ddf4p10
+sin,-0x1.2902a83d72632p-1,0x1.e1562b0448a86p1
+sin,0x1.2902a83d72632p-1,-0x1.e1562b0448a86p1
+sin,0x1.9e26c7bc96b69p-1,0x1.e2700cdc86635p-1
+sin,-0x1.9e26c7bc96b69p-1,-0x1.e2700cdc86635p-1
+sin,0x1.e6494911eedd2p-7,0x1.e64ddaf7bd73p-7
+sin,-0x1.e6494911eedd2p-7,-0x1.e64ddaf7bd73p-7
+sin,0x1.eb26c690bda25p-5,0x1.eb7239bca8afap-5
+sin,-0x1.eb26c690bda25p-5,-0x1.eb7239bca8afap-5
+sin,0x1.c73238790a4cfp-3,0x1.ef7b83f7bdef4p3
+sin,-0x1.c73238790a4cfp-3,-0x1.ef7b83f7bdef4p3
+sin,0x1.ed1b575acb8c8p-3,0x1.f20000000109bp-3
+sin,-0x1.ed1b575acb8c8p-3,-0x1.f20000000109bp-3
+sin,0x1.c1b50a56c8809p-1,0x1.f40ca67a9e8d7p9
+sin,-0x1.c1b50a56c8809p-1,-0x1.f40ca67a9e8d7p9
+sin,0x1.e321fea643a96p-2,0x1.f7224d2c7754p-2
+sin,-0x1.e321fea643a96p-2,-0x1.f7224d2c7754p-2
+sin,0x1.c1269b020a108p-3,0x1.f78a0d05e60e2p6
+sin,-0x1.c1269b020a108p-3,-0x1.f78a0d05e60e2p6
+sin,0x1.f76cae28a0775p-5,0x1.f7bdef7bdf073p-5
+sin,-0x1.f76cae28a0775p-5,-0x1.f7bdef7bdf073p-5
+sin,0x1.e42c139dc2054p-2,0x1.f8502d5955443p-2
+sin,-0x1.e42c139dc2054p-2,-0x1.f8502d5955443p-2
+sin,0x1.0fa749e07f64p-9,0x1.f8fc824d2693bp61
+sin,-0x1.0fa749e07f64p-9,-0x1.f8fc824d2693bp61
+sin,0x1.ffa80324e2d8fp-1,0x1.f8fffffffffffp2
+sin,-0x1.ffa80324e2d8fp-1,-0x1.f8fffffffffffp2
+sin,-0x1.7cdf79d5e37b8p-1,0x1.fd8p1
+sin,0x1.7cdf79d5e37b8p-1,-0x1.fd8p1
+sin,0x1.fd3f48847a1d1p-5,0x1.fd9364d936596p-5
+sin,-0x1.fd3f48847a1d1p-5,-0x1.fd9364d936596p-5
+sin,0x1.f93ad471d262fp-3,0x1.fe8p-3
+sin,-0x1.f93ad471d262fp-3,-0x1.fe8p-3
+sin,0x1.83b3062414974p-1,0x1.febb646e2ee57p13
+sin,-0x1.83b3062414974p-1,-0x1.febb646e2ee57p13
+sin,0x1.3b45bd7449775p-1,0x1.feeffffffffc6p995
+sin,-0x1.3b45bd7449775p-1,-0x1.feeffffffffc6p995
+sin,-0x1.eefb59d143646p-1,0x1.ff8ffffffffffp7
+sin,0x1.eefb59d143646p-1,-0x1.ff8ffffffffffp7
+sin,-0x1.56433f0c6bceep-1,0x1.ff8ffffffffffp870
+sin,0x1.56433f0c6bceep-1,-0x1.ff8ffffffffffp870
+sin,-0x1.930006246a6cp-2,0x1.ffcfff8p19
+sin,0x1.930006246a6cp-2,-0x1.ffcfff8p19
+sin,0x1.ded37a1f0aa6dp-1,0x1.ffcfff8p365
+sin,-0x1.ded37a1f0aa6dp-1,-0x1.ffcfff8p365
+sin,-0x1.93e4d96b621ep-1,0x1.ffcffffffff6cp720
+sin,0x1.93e4d96b621ep-1,-0x1.ffcffffffff6cp720
+sin,0x1.9068b90e42606p-1,0x1.ffcfffffffff9p320
+sin,-0x1.9068b90e42606p-1,-0x1.ffcfffffffff9p320
+sin,0x1.cf81642e7421cp-1,0x1.ffcffffffffffp12
+sin,-0x1.cf81642e7421cp-1,-0x1.ffcffffffffffp12
+sin,0x1.ffffffe61fe61p-1,0x1.ffcffffffffffp404
+sin,-0x1.ffffffe61fe61p-1,-0x1.ffcffffffffffp404
+sin,-0x1.406ee9ae91e17p-1,0x1.ffeffffffffccp995
+sin,0x1.406ee9ae91e17p-1,-0x1.ffeffffffffccp995
+sin,0x1.fa9f6ca0ec44ep-3,0x1.ffeffffffffffp-3
+sin,-0x1.fa9f6ca0ec44ep-3,-0x1.ffeffffffffffp-3
+sin,0x1.6b491db8b66d9p-4,0x1.ffeffffffffffp55
+sin,-0x1.6b491db8b66d9p-4,-0x1.ffeffffffffffp55
+sin,0x1.fb0ab102cb13p-1,0x1.ffeffffffffffp180
+sin,-0x1.fb0ab102cb13p-1,-0x1.ffeffffffffffp180
+sin,0x1.e4315ec04635dp-3,0x1.ffeffffffffffp706
+sin,-0x1.e4315ec04635dp-3,-0x1.ffeffffffffffp706
+sin,0x1.ffffc39997ef6p-1,0x1.fff1fffffffffp41
+sin,-0x1.ffffc39997ef6p-1,-0x1.fff1fffffffffp41
+sin,0x1.fff163992831fp-7,0x1.fff6b89ffffffp-7
+sin,-0x1.fff163992831fp-7,-0x1.fff6b89ffffffp-7
+sin,-0x1.d9757a05fcc43p-1,0x1.fffdffff0001fp105
+sin,0x1.d9757a05fcc43p-1,-0x1.fffdffff0001fp105
+sin,-0x1.83791fe63a17ap-1,0x1.ffff0c0000002p1
+sin,0x1.83791fe63a17ap-1,-0x1.ffff0c0000002p1
+sin,-0x1.d9d3a85acc50dp-1,0x1.ffffc00000055p150
+sin,0x1.d9d3a85acc50dp-1,-0x1.ffffc00000055p150
+sin,-0x1.f25d858dcdee7p-3,0x1.ffffe3fffffffp40
+sin,0x1.f25d858dcdee7p-3,-0x1.ffffe3fffffffp40
+sin,0x1.d18f7bfe557ecp-1,0x1.ffffefffcffaep0
+sin,-0x1.d18f7bfe557ecp-1,-0x1.ffffefffcffaep0
+sin,-0x1.bc14ebf6bfb52p-4,0x1.fffffbfffffffp228
+sin,0x1.bc14ebf6bfb52p-4,-0x1.fffffbfffffffp228
+sin,0x1.bb887a06f6c51p-3,0x1.fffffbfffffffp735
+sin,-0x1.bb887a06f6c51p-3,-0x1.fffffbfffffffp735
+sin,0x1.ffaaadef54e2fp-5,0x1.fffffefffffffp-5
+sin,-0x1.ffaaadef54e2fp-5,-0x1.fffffefffffffp-5
+sin,0x1.d4a3c62c5be09p-1,0x1.ffffff8p119
+sin,-0x1.d4a3c62c5be09p-1,-0x1.ffffff8p119
+sin,0x1.cec20f197703fp-3,0x1.ffffff8p192
+sin,-0x1.cec20f197703fp-3,-0x1.ffffff8p192
+sin,0x1.d37aadc7c8662p-2,0x1.ffffff8p543
+sin,-0x1.d37aadc7c8662p-2,-0x1.ffffff8p543
+sin,0x1.fa8d2a4d0a202p-1,0x1.ffffffc0018ffp2
+sin,-0x1.fa8d2a4d0a202p-1,-0x1.ffffffc0018ffp2
+sin,0x1.fa8d2a029f978p-1,0x1.ffffffffeffffp2
+sin,-0x1.fa8d2a029f978p-1,-0x1.ffffffffeffffp2
+sin,-0x1.2763f02a2d1eap-4,0x1.fffffffff825p943
+sin,0x1.2763f02a2d1eap-4,-0x1.fffffffff825p943
+sin,0x1.fcff128f77ddbp-1,0x1.fffffffffe09dp320
+sin,-0x1.fcff128f77ddbp-1,-0x1.fffffffffe09dp320
+sin,-0x1.fcc0bfedd84a6p-1,0x1.fffffffffe6e3p720
+sin,0x1.fcc0bfedd84a6p-1,-0x1.fffffffffe6e3p720
+sin,0x1.aed548f090c1ep-1,0x1.ffffffffffe7fp-1
+sin,-0x1.aed548f090c1ep-1,-0x1.ffffffffffe7fp-1
+sin,-0x1.f5e11def99d2bp-1,0x1.ffffffffffeffp250
+sin,0x1.f5e11def99d2bp-1,-0x1.ffffffffffeffp250
+sin,0x1.8a9cbf48fec9fp-1,0x1.fffffffffff78p920
+sin,-0x1.8a9cbf48fec9fp-1,-0x1.fffffffffff78p920
+sin,-0x1.7eba5894844ccp-3,0x1.fffffffffff83p150
+sin,0x1.7eba5894844ccp-3,-0x1.fffffffffff83p150
+sin,0x1.92c4f06d2cdd1p-1,0x1.fffffffffffd5p995
+sin,-0x1.92c4f06d2cdd1p-1,-0x1.fffffffffffd5p995
+sin,-0x1.3d5f7deb1d3bbp-1,0x1.fffffffffffe8p720
+sin,0x1.3d5f7deb1d3bbp-1,-0x1.fffffffffffe8p720
+sin,-0x1.91349b0ae90e5p-1,0x1.fffffffffffebp920
+sin,0x1.91349b0ae90e5p-1,-0x1.fffffffffffebp920
+sin,-0x1.837b9dddc1e88p-1,0x1.ffffffffffff1p1
+sin,0x1.837b9dddc1e88p-1,-0x1.ffffffffffff1p1
+sin,0x1.510e062e7fa2p-1,0x1.ffffffffffff1p245
+sin,-0x1.510e062e7fa2p-1,-0x1.ffffffffffff1p245
+sin,0x1.eaee8744b05e5p-2,0x1.ffffffffffff3p-2
+sin,-0x1.eaee8744b05e5p-2,-0x1.ffffffffffff3p-2
+sin,0x1.8a4dee8f40628p-1,0x1.ffffffffffff4p845
+sin,-0x1.8a4dee8f40628p-1,-0x1.ffffffffffff4p845
+sin,0x1.5118d6bbde07ep-1,0x1.ffffffffffff4p1020
+sin,-0x1.5118d6bbde07ep-1,-0x1.ffffffffffff4p1020
+sin,-0x1.5cd5c53cf30a9p-1,0x1.ffffffffffff8p616
+sin,0x1.5cd5c53cf30a9p-1,-0x1.ffffffffffff8p616
+sin,0x1.ffffa1f0d7dafp-1,0x1.ffffffffffffcp475
+sin,-0x1.ffffa1f0d7dafp-1,-0x1.ffffffffffffcp475
+sin,0x1.51e9d840106d7p-1,0x1.ffffffffffffep970
+sin,-0x1.51e9d840106d7p-1,-0x1.ffffffffffffep970
+sin,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+sin,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+sin,-0x0.0p0,-0x0.0p0
+sin,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+sin,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+sin,-0x1.0000000000001p-1022,-0x1.0000000000001p-1022
+sin,0x1.0000000000001p-1022,0x1.0000000000001p-1022
+sin,-0x1.0p-1022,-0x1.0p-1022
+sin,0x1.0p-1022,0x1.0p-1022
+sin,-0x0.fffffffffffffp-1022,-0x0.fffffffffffffp-1022
+sin,0x0.fffffffffffffp-1022,0x0.fffffffffffffp-1022
+sin,0x0.fffffffffffffp-1022,0x0.fffffffffffffp-1022
+sin,-0x0.fffffffffffffp-1022,-0x0.fffffffffffffp-1022
+sin,0x1.0p-1022,0x1.0p-1022
+sin,-0x1.0p-1022,-0x1.0p-1022
+sin,0x1.0000000000001p-1022,0x1.0000000000001p-1022
+sin,-0x1.0000000000001p-1022,-0x1.0000000000001p-1022
+sin,0x1.9999996de8ca2p-13,0x1.999999999999ap-13
+sin,-0x1.9999996de8ca2p-13,-0x1.999999999999ap-13
+sin,0x1.999998ead65b9p-12,0x1.999999999999ap-12
+sin,-0x1.999998ead65b9p-12,-0x1.999999999999ap-12
+sin,0x1.3333320c49bacp-11,0x1.3333333333334p-11
+sin,-0x1.3333320c49bacp-11,-0x1.3333333333334p-11
+sin,0x1.999996de8ca29p-11,0x1.999999999999ap-11
+sin,-0x1.999996de8ca29p-11,-0x1.999999999999ap-11
+sin,0x1.fffffaaaaaaefp-11,0x1.0p-10
+sin,-0x1.fffffaaaaaaefp-11,-0x1.0p-10
+sin,0x1.33332e978d553p-10,0x1.3333333333333p-10
+sin,-0x1.33332e978d553p-10,-0x1.3333333333333p-10
+sin,0x1.66665f1529bp-10,0x1.6666666666666p-10
+sin,-0x1.66665f1529bp-10,-0x1.6666666666666p-10
+sin,0x1.99998ead65cep-10,0x1.9999999999999p-10
+sin,-0x1.99998ead65cep-10,-0x1.9999999999999p-10
+sin,0x1.ccccbd3f7d15dp-10,0x1.cccccccccccccp-10
+sin,-0x1.ccccbd3f7d15dp-10,-0x1.cccccccccccccp-10
+sin,0x1.0665ae9c7b44fp-7,0x1.0666666666666p-7
+sin,-0x1.0665ae9c7b44fp-7,-0x1.0666666666666p-7
+sin,0x1.ccc8e97b59f62p-7,0x1.cccccccccccccp-7
+sin,-0x1.ccc8e97b59f62p-7,-0x1.cccccccccccccp-7
+sin,0x1.4993e8a8ff79bp-6,0x1.4999999999999p-6
+sin,-0x1.4993e8a8ff79bp-6,-0x1.4999999999999p-6
+sin,0x1.acc044c56db0ep-6,0x1.accccccccccccp-6
+sin,-0x1.acc044c56db0ep-6,-0x1.accccccccccccp-6
+sin,0x1.07f44d67cf41bp-5,0x1.08p-5
+sin,-0x1.07f44d67cf41bp-5,-0x1.08p-5
+sin,0x1.3985fe46f1c87p-5,0x1.399999999999ap-5
+sin,-0x1.3985fe46f1c87p-5,-0x1.399999999999ap-5
+sin,0x1.6b14bde93ac5fp-5,0x1.6b33333333334p-5
+sin,-0x1.6b14bde93ac5fp-5,-0x1.6b33333333334p-5
+sin,0x1.9ca0153ed8397p-5,0x1.9cccccccccccep-5
+sin,-0x1.9ca0153ed8397p-5,-0x1.9cccccccccccep-5
+sin,0x1.ce278d4027d34p-5,0x1.ce66666666666p-5
+sin,-0x1.ce278d4027d34p-5,-0x1.ce66666666666p-5
+sin,0x1.43c1e9c171a66p-1,0x1.5e7fc4369bdadp-1
+sin,-0x1.43c1e9c171a66p-1,-0x1.5e7fc4369bdadp-1
+sin,0x1.ee3d6bcea09cap-1,0x1.4e7fc4369bdadp0
+sin,-0x1.ee3d6bcea09cap-1,-0x1.4e7fc4369bdadp0
+sin,0x1.df8e22ea809d6p-1,0x1.edbfa651e9c84p0
+sin,-0x1.df8e22ea809d6p-1,-0x1.edbfa651e9c84p0
+sin,0x1.1d3479eac7ae3p-1,0x1.467fc4369bdadp1
+sin,-0x1.1d3479eac7ae3p-1,-0x1.467fc4369bdadp1
+sin,-0x1.ffeaaaeeee84bp-6,0x1.961fb54442d18p1
+sin,0x1.ffeaaaeeee84bp-6,-0x1.961fb54442d18p1
+sin,-0x1.3734d32d49bd1p-1,0x1.e5bfa651e9c83p1
+sin,0x1.3734d32d49bd1p-1,-0x1.e5bfa651e9c83p1
+sin,-0x1.e9d25d19911e2p-1,0x1.1aafcbafc85f7p2
+sin,0x1.e9d25d19911e2p-1,-0x1.1aafcbafc85f7p2
+sin,-0x1.e4ecdc5a4e466p-1,0x1.427fc4369bdadp2
+sin,0x1.e4ecdc5a4e466p-1,-0x1.427fc4369bdadp2
+sin,-0x1.2a59f10344262p-1,0x1.6a4fbcbd6f562p2
+sin,0x1.2a59f10344262p-1,-0x1.6a4fbcbd6f562p2
+sin,-0x1.26312443bd35fp-1,0x1.6af2eff0a2896p2
+sin,0x1.26312443bd35fp-1,-0x1.6af2eff0a2896p2
+sin,-0x1.e18e660a5e2fbp-1,0x1.43c62a9d02414p2
+sin,0x1.e18e660a5e2fbp-1,-0x1.43c62a9d02414p2
+sin,-0x1.ee0e83a0198b7p-1,0x1.1c99654961f92p2
+sin,0x1.ee0e83a0198b7p-1,-0x1.1c99654961f92p2
+sin,-0x1.4727747338e46p-1,0x1.ead93feb8361fp1
+sin,0x1.4727747338e46p-1,-0x1.ead93feb8361fp1
+sin,-0x1.4ba2f75dda5fep-4,0x1.9c7fb54442d1ap1
+sin,0x1.4ba2f75dda5fep-4,-0x1.9c7fb54442d1ap1
+sin,0x1.034c4d633b4efp-1,0x1.4e262a9d02415p1
+sin,-0x1.034c4d633b4efp-1,-0x1.4e262a9d02415p1
+sin,0x1.d1e4cde2f3945p-1,0x1.ff993feb8362p0
+sin,-0x1.d1e4cde2f3945p-1,-0x1.ff993feb8362p0
+sin,0x1.f750235c94992p-1,0x1.62e62a9d02416p0
+sin,-0x1.f750235c94992p-1,-0x1.62e62a9d02416p0
+sin,0x1.65f7d571279b1p-1,0x1.8c662a9d02419p-1
+sin,-0x1.65f7d571279b1p-1,-0x1.8c662a9d02419p-1
+sin,-0x1.fe043f57369d7p-1,-0x1.a8aa1d11c44ffp0
+sin,0x1.fe043f57369d7p-1,0x1.a8aa1d11c44ffp0
+sin,-0x1.fff18f24f3e4cp-1,-0x1.95ec8b9e03d54p0
+sin,0x1.fff18f24f3e4cp-1,0x1.95ec8b9e03d54p0
+sin,-0x1.ff20d961624e7p-1,-0x1.832efa2a435a9p0
+sin,0x1.ff20d961624e7p-1,0x1.832efa2a435a9p0
+sin,-0x1.fb933c40107fdp-1,-0x1.707168b682dfep0
+sin,0x1.fb933c40107fdp-1,0x1.707168b682dfep0
+sin,-0x1.f54d971881ad7p-1,-0x1.5db3d742c2653p0
+sin,0x1.f54d971881ad7p-1,0x1.5db3d742c2653p0
+sin,-0x1.ec5883b7b6cf5p-1,-0x1.4af645cf01ea8p0
+sin,0x1.ec5883b7b6cf5p-1,0x1.4af645cf01ea8p0
+sin,-0x1.e0c04a94e1731p-1,-0x1.3838b45b416fdp0
+sin,0x1.e0c04a94e1731p-1,0x1.3838b45b416fdp0
+sin,-0x1.d294d1f96c7ecp-1,-0x1.257b22e780f52p0
+sin,0x1.d294d1f96c7ecp-1,0x1.257b22e780f52p0
+sin,-0x1.c1e9883373d7fp-1,-0x1.12bd9173c07abp0
+sin,0x1.c1e9883373d7fp-1,0x1.12bd9173c07abp0
+sin,-0x1.a2c289d9d055bp-1,-0x1.ea5c3ed5b385p-1
+sin,0x1.a2c289d9d055bp-1,0x1.ea5c3ed5b385p-1
+sin,-0x1.95f05257dbcb6p-1,-0x1.d4b87dab670ap-1
+sin,0x1.95f05257dbcb6p-1,0x1.d4b87dab670ap-1
+sin,-0x1.88647f26a6e0fp-1,-0x1.bf14bc811a8fp-1
+sin,0x1.88647f26a6e0fp-1,0x1.bf14bc811a8fp-1
+sin,-0x1.7a2541dfd4e75p-1,-0x1.a970fb56ce14p-1
+sin,0x1.7a2541dfd4e75p-1,0x1.a970fb56ce14p-1
+sin,-0x1.6b391e25bc26dp-1,-0x1.93cd3a2c8199p-1
+sin,0x1.6b391e25bc26dp-1,0x1.93cd3a2c8199p-1
+sin,-0x1.5ba6e6a8e7065p-1,-0x1.7e297902351ep-1
+sin,0x1.5ba6e6a8e7065p-1,0x1.7e297902351ep-1
+sin,-0x1.4b75ba096fa55p-1,-0x1.6885b7d7e8a3p-1
+sin,0x1.4b75ba096fa55p-1,0x1.6885b7d7e8a3p-1
+sin,-0x1.3aacff95a3123p-1,-0x1.52e1f6ad9c28p-1
+sin,0x1.3aacff95a3123p-1,0x1.52e1f6ad9c28p-1
+sin,-0x1.295463e769285p-1,-0x1.3d3e35834fadp-1
+sin,0x1.295463e769285p-1,0x1.3d3e35834fadp-1
+sin,-0x1.fc769b77e5885p-2,-0x1.0a0b02501c799p-1
+sin,0x1.fc769b77e5885p-2,0x1.0a0b02501c799p-1
+sin,-0x1.c853c78462de4p-2,-0x1.d8f7208e6b82cp-2
+sin,0x1.c853c78462de4p-2,0x1.d8f7208e6b82cp-2
+sin,-0x1.92aba90aaf272p-2,-0x1.9dd83c7c9e126p-2
+sin,0x1.92aba90aaf272p-2,0x1.9dd83c7c9e126p-2
+sin,-0x1.5bac064658f39p-2,-0x1.62b9586ad0a2p-2
+sin,0x1.5bac064658f39p-2,0x1.62b9586ad0a2p-2
+sin,-0x1.2383ca8078e58p-2,-0x1.279a74590331ap-2
+sin,0x1.2383ca8078e58p-2,0x1.279a74590331ap-2
+sin,-0x1.d4c5bc11d2372p-3,-0x1.d8f7208e6b829p-3
+sin,0x1.d4c5bc11d2372p-3,0x1.d8f7208e6b829p-3
+sin,-0x1.60f3faaf43024p-3,-0x1.62b9586ad0a1ep-3
+sin,0x1.60f3faaf43024p-3,0x1.62b9586ad0a1ep-3
+sin,-0x1.d7ea3de45a9d6p-4,-0x1.d8f7208e6b826p-4
+sin,0x1.d7ea3de45a9d6p-4,0x1.d8f7208e6b826p-4
+sin,-0x1.d8b3df489987ap-5,-0x1.d8f7208e6b82dp-5
+sin,0x1.d8b3df489987ap-5,0x1.d8f7208e6b82dp-5
+sin,0x1.d8b3df489987ap-5,0x1.d8f7208e6b82dp-5
+sin,-0x1.d8b3df489987ap-5,-0x1.d8f7208e6b82dp-5
+sin,0x1.d7ea3de45a9ddp-4,0x1.d8f7208e6b82dp-4
+sin,-0x1.d7ea3de45a9ddp-4,-0x1.d8f7208e6b82dp-4
+sin,0x1.60f3faaf43028p-3,0x1.62b9586ad0a22p-3
+sin,-0x1.60f3faaf43028p-3,-0x1.62b9586ad0a22p-3
+sin,0x1.d4c5bc11d2376p-3,0x1.d8f7208e6b82dp-3
+sin,-0x1.d4c5bc11d2376p-3,-0x1.d8f7208e6b82dp-3
+sin,0x1.2383ca8078e5ap-2,0x1.279a74590331cp-2
+sin,-0x1.2383ca8078e5ap-2,-0x1.279a74590331cp-2
+sin,0x1.5bac064658f3bp-2,0x1.62b9586ad0a22p-2
+sin,-0x1.5bac064658f3bp-2,-0x1.62b9586ad0a22p-2
+sin,0x1.92aba90aaf274p-2,0x1.9dd83c7c9e128p-2
+sin,-0x1.92aba90aaf274p-2,-0x1.9dd83c7c9e128p-2
+sin,0x1.c853c78462de6p-2,0x1.d8f7208e6b82ep-2
+sin,-0x1.c853c78462de6p-2,-0x1.d8f7208e6b82ep-2
+sin,0x1.fc769b77e5885p-2,0x1.0a0b02501c799p-1
+sin,-0x1.fc769b77e5885p-2,-0x1.0a0b02501c799p-1
+sin,0x1.295463e769281p-1,0x1.3d3e35834faccp-1
+sin,-0x1.295463e769281p-1,-0x1.3d3e35834faccp-1
+sin,0x1.3aacff95a312p-1,0x1.52e1f6ad9c27cp-1
+sin,-0x1.3aacff95a312p-1,-0x1.52e1f6ad9c27cp-1
+sin,0x1.4b75ba096fa52p-1,0x1.6885b7d7e8a2cp-1
+sin,-0x1.4b75ba096fa52p-1,-0x1.6885b7d7e8a2cp-1
+sin,0x1.5ba6e6a8e7062p-1,0x1.7e297902351dcp-1
+sin,-0x1.5ba6e6a8e7062p-1,-0x1.7e297902351dcp-1
+sin,0x1.6b391e25bc26ap-1,0x1.93cd3a2c8198cp-1
+sin,-0x1.6b391e25bc26ap-1,-0x1.93cd3a2c8198cp-1
+sin,0x1.7a2541dfd4e73p-1,0x1.a970fb56ce13cp-1
+sin,-0x1.7a2541dfd4e73p-1,-0x1.a970fb56ce13cp-1
+sin,0x1.88647f26a6e0dp-1,0x1.bf14bc811a8ecp-1
+sin,-0x1.88647f26a6e0dp-1,-0x1.bf14bc811a8ecp-1
+sin,0x1.95f05257dbcb4p-1,0x1.d4b87dab6709cp-1
+sin,-0x1.95f05257dbcb4p-1,-0x1.d4b87dab6709cp-1
+sin,0x1.a2c289d9d0558p-1,0x1.ea5c3ed5b384cp-1
+sin,-0x1.a2c289d9d0558p-1,-0x1.ea5c3ed5b384cp-1
+sin,0x1.c1e9883373d7fp-1,0x1.12bd9173c07abp0
+sin,-0x1.c1e9883373d7fp-1,-0x1.12bd9173c07abp0
+sin,0x1.d294d1f96c7efp-1,0x1.257b22e780f56p0
+sin,-0x1.d294d1f96c7efp-1,-0x1.257b22e780f56p0
+sin,0x1.e0c04a94e1733p-1,0x1.3838b45b41701p0
+sin,-0x1.e0c04a94e1733p-1,-0x1.3838b45b41701p0
+sin,0x1.ec5883b7b6cf7p-1,0x1.4af645cf01eacp0
+sin,-0x1.ec5883b7b6cf7p-1,-0x1.4af645cf01eacp0
+sin,0x1.f54d971881ad8p-1,0x1.5db3d742c2657p0
+sin,-0x1.f54d971881ad8p-1,-0x1.5db3d742c2657p0
+sin,0x1.fb933c40107fep-1,0x1.707168b682e02p0
+sin,-0x1.fb933c40107fep-1,-0x1.707168b682e02p0
+sin,0x1.ff20d961624e7p-1,0x1.832efa2a435adp0
+sin,-0x1.ff20d961624e7p-1,-0x1.832efa2a435adp0
+sin,0x1.fff18f24f3e4bp-1,0x1.95ec8b9e03d58p0
+sin,-0x1.fff18f24f3e4bp-1,-0x1.95ec8b9e03d58p0
+sin,0x1.fe043f57369d7p-1,0x1.a8aa1d11c44ffp0
+sin,-0x1.fe043f57369d7p-1,-0x1.a8aa1d11c44ffp0
+sin,0x1.b3d3695acc413p-1,0x1.04aff6d330942p0
+sin,-0x1.b3d3695acc413p-1,-0x1.04aff6d330942p0
+sin,0x1.b3d41972dc806p-1,0x1.04b09e98dcdb4p0
+sin,-0x1.b3d41972dc806p-1,-0x1.04b09e98dcdb4p0
+sin,0x1.b3d4c98a318fbp-1,0x1.04b1465e89226p0
+sin,-0x1.b3d4c98a318fbp-1,-0x1.04b1465e89226p0
+sin,0x1.b3d579a0cb6eep-1,0x1.04b1ee2435698p0
+sin,-0x1.b3d579a0cb6eep-1,-0x1.04b1ee2435698p0
+sin,0x1.b3d629b6aa1dap-1,0x1.04b295e9e1b0ap0
+sin,-0x1.b3d629b6aa1dap-1,-0x1.04b295e9e1b0ap0
+sin,0x1.b3d6d9cbcd9bap-1,0x1.04b33daf8df7cp0
+sin,-0x1.b3d6d9cbcd9bap-1,-0x1.04b33daf8df7cp0
+sin,0x1.b3d789e035e89p-1,0x1.04b3e5753a3eep0
+sin,-0x1.b3d789e035e89p-1,-0x1.04b3e5753a3eep0
+sin,0x1.b3d839f3e3043p-1,0x1.04b48d3ae686p0
+sin,-0x1.b3d839f3e3043p-1,-0x1.04b48d3ae686p0
+sin,0x1.b3d8ea06d4eep-1,0x1.04b5350092ccfp0
+sin,-0x1.b3d8ea06d4eep-1,-0x1.04b5350092ccfp0
+sin,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+sin,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+sin,-0x0.0p0,-0x0.0p0
+sin,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+sin,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+sin,0x1.1773d561fd506p-1,0x1.279a74590331bp-1
+sin,-0x1.1773d561fd506p-1,-0x1.279a74590331bp-1
+sin,0x1.1773d561fd507p-1,0x1.279a74590331cp-1
+sin,-0x1.1773d561fd507p-1,-0x1.279a74590331cp-1
+sin,0x1.1773d561fd508p-1,0x1.279a74590331dp-1
+sin,-0x1.1773d561fd508p-1,-0x1.279a74590331dp-1
+sin,0x1.f95b8e7107419p-1,0x1.bb67ae8584ca9p0
+sin,-0x1.f95b8e7107419p-1,-0x1.bb67ae8584ca9p0
+sin,0x1.f95b8e7107418p-1,0x1.bb67ae8584caap0
+sin,-0x1.f95b8e7107418p-1,-0x1.bb67ae8584caap0
+sin,0x1.f95b8e7107418p-1,0x1.bb67ae8584cabp0
+sin,-0x1.f95b8e7107418p-1,-0x1.bb67ae8584cabp0
+sin,0x1.b1d8305321616p-2,0x1.bffffffffffffp-2
+sin,-0x1.b1d8305321616p-2,-0x1.bffffffffffffp-2
+sin,0x1.b1d8305321617p-2,0x1.cp-2
+sin,-0x1.b1d8305321617p-2,-0x1.cp-2
+sin,0x1.b1d8305321617p-2,0x1.c000000000001p-2
+sin,-0x1.b1d8305321617p-2,-0x1.c000000000001p-2
+sin,0x1.44eb381cf386ap-1,0x1.5ffffffffffffp-1
+sin,-0x1.44eb381cf386ap-1,-0x1.5ffffffffffffp-1
+sin,0x1.44eb381cf386bp-1,0x1.6p-1
+sin,-0x1.44eb381cf386bp-1,-0x1.6p-1
+sin,0x1.44eb381cf386cp-1,0x1.6000000000001p-1
+sin,-0x1.44eb381cf386cp-1,-0x1.6000000000001p-1
+sin,0x1.dad902fa8ac86p-1,0x1.2ffffffffffffp0
+sin,-0x1.dad902fa8ac86p-1,-0x1.2ffffffffffffp0
+sin,0x1.dad902fa8ac87p-1,0x1.3p0
+sin,-0x1.dad902fa8ac87p-1,-0x1.3p0
+sin,0x1.dad902fa8ac88p-1,0x1.3000000000001p0
+sin,-0x1.dad902fa8ac88p-1,-0x1.3000000000001p0
+sin,0x1.4b707a7acdedp-1,0x1.37fffffffffffp1
+sin,-0x1.4b707a7acdedp-1,-0x1.37fffffffffffp1
+sin,0x1.4b707a7acdecdp-1,0x1.38p1
+sin,-0x1.4b707a7acdecdp-1,-0x1.38p1
+sin,0x1.4b707a7acdecap-1,0x1.3800000000001p1
+sin,-0x1.4b707a7acdecap-1,-0x1.3800000000001p1
+sin,0x1.066e7eb76f5c6p-4,0x1.069c8b46b3792p-4
+sin,-0x1.066e7eb76f5c6p-4,-0x1.069c8b46b3792p-4
+sin,0x1.05e4761ab8d8fp-3,0x1.069c8b46b3792p-3
+sin,-0x1.05e4761ab8d8fp-3,-0x1.069c8b46b3792p-3
+sin,0x1.877e2cd4f6fdap-3,0x1.89ead0ea0d35bp-3
+sin,-0x1.877e2cd4f6fdap-3,-0x1.89ead0ea0d35bp-3
+sin,0x1.03be06f97cbeep-2,0x1.069c8b46b3792p-2
+sin,-0x1.03be06f97cbeep-2,-0x1.069c8b46b3792p-2
+sin,0x1.42abba8c72fbcp-2,0x1.4843ae1860576p-2
+sin,-0x1.42abba8c72fbcp-2,-0x1.4843ae1860576p-2
+sin,0x1.8045fe64e62dcp-2,0x1.89ead0ea0d35ap-2
+sin,-0x1.8045fe64e62dcp-2,-0x1.89ead0ea0d35ap-2
+sin,0x1.bc4c04d71abbfp-2,0x1.cb91f3bbba13ep-2
+sin,-0x1.bc4c04d71abbfp-2,-0x1.cb91f3bbba13ep-2
+sin,0x1.f67ea975b86ap-2,0x1.069c8b46b3791p-1
+sin,-0x1.f67ea975b86ap-2,-0x1.069c8b46b3791p-1
+sin,0x1.175059bf0d425p-1,0x1.27701caf89e83p-1
+sin,-0x1.175059bf0d425p-1,-0x1.27701caf89e83p-1
+sin,0x1.323b8b1fb4ba2p-1,0x1.4843ae1860575p-1
+sin,-0x1.323b8b1fb4ba2p-1,-0x1.4843ae1860575p-1
+sin,0x1.4be4979c5efb3p-1,0x1.69173f8136c67p-1
+sin,-0x1.4be4979c5efb3p-1,-0x1.69173f8136c67p-1
+sin,0x1.643080d67acc1p-1,0x1.89ead0ea0d359p-1
+sin,-0x1.643080d67acc1p-1,-0x1.89ead0ea0d359p-1
+sin,0x1.7b05b7b6c612ep-1,0x1.aabe6252e3a4bp-1
+sin,-0x1.7b05b7b6c612ep-1,-0x1.aabe6252e3a4bp-1
+sin,0x1.904c37505de49p-1,0x1.cb91f3bbba13dp-1
+sin,-0x1.904c37505de49p-1,-0x1.cb91f3bbba13dp-1
+sin,0x1.a3ed9e252938ap-1,0x1.ec6585249082fp-1
+sin,-0x1.a3ed9e252938ap-1,-0x1.ec6585249082fp-1
+sin,0x1.b5d545b109bf9p-1,0x1.069c8b46b3791p0
+sin,-0x1.b5d545b109bf9p-1,-0x1.069c8b46b3791p0
+sin,0x1.c5f058230e7fdp-1,0x1.170653fb1eb0ap0
+sin,-0x1.c5f058230e7fdp-1,-0x1.170653fb1eb0ap0
+sin,0x1.d42de42dce134p-1,0x1.27701caf89e83p0
+sin,-0x1.d42de42dce134p-1,-0x1.27701caf89e83p0
+sin,0x1.e07eeeda109cbp-1,0x1.37d9e563f51fcp0
+sin,-0x1.e07eeeda109cbp-1,-0x1.37d9e563f51fcp0
+sin,0x1.ead6834909b93p-1,0x1.4843ae1860575p0
+sin,-0x1.ead6834909b93p-1,-0x1.4843ae1860575p0
+sin,0x1.f329c0558e968p-1,0x1.58ad76cccb8eep0
+sin,-0x1.f329c0558e968p-1,-0x1.58ad76cccb8eep0
+sin,0x1.f96fe405f1ac6p-1,0x1.69173f8136c67p0
+sin,-0x1.f96fe405f1ac6p-1,-0x1.69173f8136c67p0
+sin,0x1.fda254c27a01fp-1,0x1.79810835a1fep0
+sin,-0x1.fda254c27a01fp-1,-0x1.79810835a1fep0
+sin,0x1.ffbca846c4fcap-1,0x1.89ead0ea0d359p0
+sin,-0x1.ffbca846c4fcap-1,-0x1.89ead0ea0d359p0
+sin,0x1.ffbca846c4fcap-1,0x1.9a54999e786d2p0
+sin,-0x1.ffbca846c4fcap-1,-0x1.9a54999e786d2p0
+sin,0x1.fda254c27a02p-1,0x1.aabe6252e3a4bp0
+sin,-0x1.fda254c27a02p-1,-0x1.aabe6252e3a4bp0
+sin,0x1.f96fe405f1ac8p-1,0x1.bb282b074edc4p0
+sin,-0x1.f96fe405f1ac8p-1,-0x1.bb282b074edc4p0
+sin,0x1.f329c0558e96ap-1,0x1.cb91f3bbba13dp0
+sin,-0x1.f329c0558e96ap-1,-0x1.cb91f3bbba13dp0
+sin,0x1.ead6834909b96p-1,0x1.dbfbbc70254b6p0
+sin,-0x1.ead6834909b96p-1,-0x1.dbfbbc70254b6p0
+sin,0x1.e07eeeda109cfp-1,0x1.ec6585249082fp0
+sin,-0x1.e07eeeda109cfp-1,-0x1.ec6585249082fp0
+sin,0x1.d42de42dce139p-1,0x1.fccf4dd8fbba8p0
+sin,-0x1.d42de42dce139p-1,-0x1.fccf4dd8fbba8p0
+sin,0x1.c5f058230e801p-1,0x1.069c8b46b3791p1
+sin,-0x1.c5f058230e801p-1,-0x1.069c8b46b3791p1
+sin,0x1.b5d545b109bfdp-1,0x1.0ed16fa0e914ep1
+sin,-0x1.b5d545b109bfdp-1,-0x1.0ed16fa0e914ep1
+sin,0x1.a3ed9e252938dp-1,0x1.170653fb1eb0bp1
+sin,-0x1.a3ed9e252938dp-1,-0x1.170653fb1eb0bp1
+sin,0x1.904c37505de4cp-1,0x1.1f3b3855544c8p1
+sin,-0x1.904c37505de4cp-1,-0x1.1f3b3855544c8p1
+sin,0x1.7b05b7b6c613p-1,0x1.27701caf89e85p1
+sin,-0x1.7b05b7b6c613p-1,-0x1.27701caf89e85p1
+sin,0x1.643080d67acc1p-1,0x1.2fa50109bf842p1
+sin,-0x1.643080d67acc1p-1,-0x1.2fa50109bf842p1
+sin,0x1.4be4979c5efb2p-1,0x1.37d9e563f51ffp1
+sin,-0x1.4be4979c5efb2p-1,-0x1.37d9e563f51ffp1
+sin,0x1.323b8b1fb4b9fp-1,0x1.400ec9be2abbcp1
+sin,-0x1.323b8b1fb4b9fp-1,-0x1.400ec9be2abbcp1
+sin,0x1.175059bf0d42p-1,0x1.4843ae1860579p1
+sin,-0x1.175059bf0d42p-1,-0x1.4843ae1860579p1
+sin,0x1.f67ea975b8692p-2,0x1.5078927295f36p1
+sin,-0x1.f67ea975b8692p-2,-0x1.5078927295f36p1
+sin,0x1.bc4c04d71abadp-2,0x1.58ad76cccb8f3p1
+sin,-0x1.bc4c04d71abadp-2,-0x1.58ad76cccb8f3p1
+sin,0x1.8045fe64e62c6p-2,0x1.60e25b27012bp1
+sin,-0x1.8045fe64e62c6p-2,-0x1.60e25b27012bp1
+sin,0x1.42abba8c72fa1p-2,0x1.69173f8136c6dp1
+sin,-0x1.42abba8c72fa1p-2,-0x1.69173f8136c6dp1
+sin,0x1.03be06f97cbdp-2,0x1.714c23db6c62ap1
+sin,-0x1.03be06f97cbdp-2,-0x1.714c23db6c62ap1
+sin,0x1.877e2cd4f6f94p-3,0x1.79810835a1fe7p1
+sin,-0x1.877e2cd4f6f94p-3,-0x1.79810835a1fe7p1
+sin,0x1.05e4761ab8d42p-3,0x1.81b5ec8fd79a4p1
+sin,-0x1.05e4761ab8d42p-3,-0x1.81b5ec8fd79a4p1
+sin,0x1.066e7eb76f5ddp-4,0x1.89ead0ea0d35bp1
+sin,-0x1.066e7eb76f5ddp-4,-0x1.89ead0ea0d35bp1
+sin,0x1.03be06f97cbf1p-2,-0x1.81b5ec8fd799fp2
+sin,-0x1.03be06f97cbf1p-2,0x1.81b5ec8fd799fp2
+sin,0x1.f67ea975b86a2p-2,-0x1.714c23db6c626p2
+sin,-0x1.f67ea975b86a2p-2,0x1.714c23db6c626p2
+sin,0x1.643080d67acc2p-1,-0x1.60e25b27012adp2
+sin,-0x1.643080d67acc2p-1,0x1.60e25b27012adp2
+sin,0x1.b5d545b109bf9p-1,-0x1.5078927295f34p2
+sin,-0x1.b5d545b109bf9p-1,0x1.5078927295f34p2
+sin,0x1.ead6834909b93p-1,-0x1.400ec9be2abbbp2
+sin,-0x1.ead6834909b93p-1,0x1.400ec9be2abbbp2
+sin,0x1.ffbca846c4fcap-1,-0x1.2fa50109bf842p2
+sin,-0x1.ffbca846c4fcap-1,0x1.2fa50109bf842p2
+sin,0x1.f329c0558e96ap-1,-0x1.1f3b3855544c9p2
+sin,-0x1.f329c0558e96ap-1,0x1.1f3b3855544c9p2
+sin,0x1.c5f058230e802p-1,-0x1.0ed16fa0e915p2
+sin,-0x1.c5f058230e802p-1,0x1.0ed16fa0e915p2
+sin,0x1.7b05b7b6c6136p-1,-0x1.fccf4dd8fbbaep1
+sin,-0x1.7b05b7b6c6136p-1,0x1.fccf4dd8fbbaep1
+sin,0x1.175059bf0d42fp-1,-0x1.dbfbbc70254bcp1
+sin,-0x1.175059bf0d42fp-1,0x1.dbfbbc70254bcp1
+sin,0x1.42abba8c72fd2p-2,-0x1.bb282b074edcap1
+sin,-0x1.42abba8c72fd2p-2,0x1.bb282b074edcap1
+sin,0x1.066e7eb76f62bp-4,-0x1.9a54999e786d8p1
+sin,-0x1.066e7eb76f62bp-4,0x1.9a54999e786d8p1
+sin,-0x1.877e2cd4f6fa4p-3,-0x1.79810835a1fe6p1
+sin,0x1.877e2cd4f6fa4p-3,0x1.79810835a1fe6p1
+sin,-0x1.bc4c04d71aba6p-2,-0x1.58ad76cccb8f4p1
+sin,0x1.bc4c04d71aba6p-2,0x1.58ad76cccb8f4p1
+sin,-0x1.4be4979c5efa8p-1,-0x1.37d9e563f5202p1
+sin,0x1.4be4979c5efa8p-1,0x1.37d9e563f5202p1
+sin,-0x1.a3ed9e2529382p-1,-0x1.170653fb1eb1p1
+sin,0x1.a3ed9e2529382p-1,0x1.170653fb1eb1p1
+sin,-0x1.e07eeeda109c6p-1,-0x1.ec6585249083cp0
+sin,0x1.e07eeeda109c6p-1,0x1.ec6585249083cp0
+sin,-0x1.fda254c27a01ep-1,-0x1.aabe6252e3a58p0
+sin,0x1.fda254c27a01ep-1,0x1.aabe6252e3a58p0
+sin,-0x1.f96fe405f1acap-1,-0x1.69173f8136c74p0
+sin,0x1.f96fe405f1acap-1,0x1.69173f8136c74p0
+sin,-0x1.d42de42dce13fp-1,-0x1.27701caf89e9p0
+sin,0x1.d42de42dce13fp-1,0x1.27701caf89e9p0
+sin,-0x1.904c37505de59p-1,-0x1.cb91f3bbba157p-1
+sin,0x1.904c37505de59p-1,0x1.cb91f3bbba157p-1
+sin,-0x1.323b8b1fb4bb6p-1,-0x1.4843ae186058ep-1
+sin,0x1.323b8b1fb4bb6p-1,0x1.4843ae186058ep-1
+sin,-0x1.8045fe64e6309p-2,-0x1.89ead0ea0d38ap-2
+sin,0x1.8045fe64e6309p-2,0x1.89ead0ea0d38ap-2
+sin,-0x1.05e4761ab8decp-3,-0x1.069c8b46b37fp-3
+sin,0x1.05e4761ab8decp-3,0x1.069c8b46b37fp-3
+sin,0x1.05e4761ab8d32p-3,0x1.069c8b46b3734p-3
+sin,-0x1.05e4761ab8d32p-3,-0x1.069c8b46b3734p-3
+sin,0x1.8045fe64e62b2p-2,0x1.89ead0ea0d32cp-2
+sin,-0x1.8045fe64e62b2p-2,-0x1.89ead0ea0d32cp-2
+sin,0x1.323b8b1fb4b9p-1,0x1.4843ae186055fp-1
+sin,-0x1.323b8b1fb4b9p-1,-0x1.4843ae186055fp-1
+sin,0x1.904c37505de3cp-1,0x1.cb91f3bbba128p-1
+sin,-0x1.904c37505de3cp-1,-0x1.cb91f3bbba128p-1
+sin,0x1.d42de42dce12bp-1,0x1.27701caf89e78p0
+sin,-0x1.d42de42dce12bp-1,-0x1.27701caf89e78p0
+sin,0x1.f96fe405f1ac2p-1,0x1.69173f8136c5cp0
+sin,-0x1.f96fe405f1ac2p-1,-0x1.69173f8136c5cp0
+sin,0x1.fda254c27a022p-1,0x1.aabe6252e3a4p0
+sin,-0x1.fda254c27a022p-1,-0x1.aabe6252e3a4p0
+sin,0x1.e07eeeda109d7p-1,0x1.ec65852490824p0
+sin,-0x1.e07eeeda109d7p-1,-0x1.ec65852490824p0
+sin,0x1.a3ed9e252939ep-1,0x1.170653fb1eb04p1
+sin,-0x1.a3ed9e252939ep-1,-0x1.170653fb1eb04p1
+sin,0x1.4be4979c5efcdp-1,0x1.37d9e563f51f6p1
+sin,-0x1.4be4979c5efcdp-1,-0x1.37d9e563f51f6p1
+sin,0x1.bc4c04d71abfcp-2,0x1.58ad76cccb8e8p1
+sin,-0x1.bc4c04d71abfcp-2,-0x1.58ad76cccb8e8p1
+sin,0x1.877e2cd4f7061p-3,0x1.79810835a1fdap1
+sin,-0x1.877e2cd4f7061p-3,-0x1.79810835a1fdap1
+sin,-0x1.066e7eb76f4acp-4,0x1.9a54999e786ccp1
+sin,0x1.066e7eb76f4acp-4,-0x1.9a54999e786ccp1
+sin,-0x1.42abba8c72f77p-2,0x1.bb282b074edbep1
+sin,0x1.42abba8c72f77p-2,-0x1.bb282b074edbep1
+sin,-0x1.175059bf0d407p-1,0x1.dbfbbc70254bp1
+sin,0x1.175059bf0d407p-1,-0x1.dbfbbc70254bp1
+sin,-0x1.7b05b7b6c6116p-1,0x1.fccf4dd8fbba2p1
+sin,0x1.7b05b7b6c6116p-1,-0x1.fccf4dd8fbba2p1
+sin,-0x1.c5f058230e7ecp-1,0x1.0ed16fa0e914ap2
+sin,0x1.c5f058230e7ecp-1,-0x1.0ed16fa0e914ap2
+sin,-0x1.f329c0558e96p-1,0x1.1f3b3855544c3p2
+sin,0x1.f329c0558e96p-1,-0x1.1f3b3855544c3p2
+sin,-0x1.ffbca846c4fcbp-1,0x1.2fa50109bf83cp2
+sin,0x1.ffbca846c4fcbp-1,-0x1.2fa50109bf83cp2
+sin,-0x1.ead6834909ba1p-1,0x1.400ec9be2abb5p2
+sin,0x1.ead6834909ba1p-1,-0x1.400ec9be2abb5p2
+sin,-0x1.b5d545b109c12p-1,0x1.5078927295f2ep2
+sin,0x1.b5d545b109c12p-1,-0x1.5078927295f2ep2
+sin,-0x1.643080d67ace4p-1,0x1.60e25b27012a7p2
+sin,0x1.643080d67ace4p-1,-0x1.60e25b27012a7p2
+sin,-0x1.f67ea975b86f6p-2,0x1.714c23db6c62p2
+sin,0x1.f67ea975b86f6p-2,-0x1.714c23db6c62p2
+sin,-0x1.03be06f97cc4dp-2,0x1.81b5ec8fd7999p2
+sin,0x1.03be06f97cc4dp-2,-0x1.81b5ec8fd7999p2
+sin,0x1.efb26ef930c4cp-5,0x1.effffffffffffp-5
+sin,-0x1.efb26ef930c4cp-5,-0x1.effffffffffffp-5
+sin,0x1.efb26ef930c4dp-5,0x1.fp-5
+sin,-0x1.efb26ef930c4dp-5,-0x1.fp-5
+sin,0x1.efb26ef930c4ep-5,0x1.f000000000001p-5
+sin,-0x1.efb26ef930c4ep-5,-0x1.f000000000001p-5
+sin,0x1.f6baaa131de63p-4,0x1.f7fffffffffffp-4
+sin,-0x1.f6baaa131de63p-4,-0x1.f7fffffffffffp-4
+sin,0x1.f6baaa131de64p-4,0x1.f8p-4
+sin,-0x1.f6baaa131de64p-4,-0x1.f8p-4
+sin,0x1.f6baaa131de65p-4,0x1.f800000000001p-4
+sin,-0x1.f6baaa131de65p-4,-0x1.f800000000001p-4
+sin,0x1.4a8c3b4e9c7ffp-3,0x1.4bfffffffffffp-3
+sin,-0x1.4a8c3b4e9c7ffp-3,-0x1.4bfffffffffffp-3
+sin,0x1.4a8c3b4e9c8p-3,0x1.4cp-3
+sin,-0x1.4a8c3b4e9c8p-3,-0x1.4cp-3
+sin,0x1.4a8c3b4e9c801p-3,0x1.4c00000000001p-3
+sin,-0x1.4a8c3b4e9c801p-3,-0x1.4c00000000001p-3
+sin,0x1.2e9cd95baba32p-2,0x1.3333333333332p-2
+sin,-0x1.2e9cd95baba32p-2,-0x1.3333333333332p-2
+sin,0x1.2e9cd95baba33p-2,0x1.3333333333333p-2
+sin,-0x1.2e9cd95baba33p-2,-0x1.3333333333333p-2
+sin,0x1.2e9cd95baba34p-2,0x1.3333333333334p-2
+sin,-0x1.2e9cd95baba34p-2,-0x1.3333333333334p-2
+sin,0x1.3faefc7a5466fp-1,0x1.594317acc4ef8p-1
+sin,-0x1.3faefc7a5466fp-1,-0x1.594317acc4ef8p-1
+sin,0x1.3faefc7a5467p-1,0x1.594317acc4ef9p-1
+sin,-0x1.3faefc7a5467p-1,-0x1.594317acc4ef9p-1
+sin,0x1.3faefc7a5467p-1,0x1.594317acc4efap-1
+sin,-0x1.3faefc7a5467p-1,-0x1.594317acc4efap-1
+sin,0x1.6888a4e134b2ep-1,0x1.8ffffffffffffp-1
+sin,-0x1.6888a4e134b2ep-1,-0x1.8ffffffffffffp-1
+sin,0x1.6888a4e134b2fp-1,0x1.9p-1
+sin,-0x1.6888a4e134b2fp-1,-0x1.9p-1
+sin,0x1.6888a4e134b2fp-1,0x1.9000000000001p-1
+sin,-0x1.6888a4e134b2fp-1,-0x1.9000000000001p-1
+sin,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+sin,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+sin,-0x0.0p0,-0x0.0p0
+sin,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+sin,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+sin,0x1.91f65f10dd813p-5,0x1.921fb54442d17p-5
+sin,-0x1.91f65f10dd813p-5,-0x1.921fb54442d17p-5
+sin,0x1.91f65f10dd814p-5,0x1.921fb54442d18p-5
+sin,-0x1.91f65f10dd814p-5,-0x1.921fb54442d18p-5
+sin,0x1.91f65f10dd815p-5,0x1.921fb54442d19p-5
+sin,-0x1.91f65f10dd815p-5,-0x1.921fb54442d19p-5
+sin,0x1.917a6bc29b42bp-4,0x1.921fb54442d17p-4
+sin,-0x1.917a6bc29b42bp-4,-0x1.921fb54442d17p-4
+sin,0x1.917a6bc29b42cp-4,0x1.921fb54442d18p-4
+sin,-0x1.917a6bc29b42cp-4,-0x1.921fb54442d18p-4
+sin,0x1.917a6bc29b42dp-4,0x1.921fb54442d19p-4
+sin,-0x1.917a6bc29b42dp-4,-0x1.921fb54442d19p-4
+sin,0x1.8f8b83c69a609p-3,0x1.921fb54442d17p-3
+sin,-0x1.8f8b83c69a609p-3,-0x1.921fb54442d17p-3
+sin,0x1.8f8b83c69a60ap-3,0x1.921fb54442d18p-3
+sin,-0x1.8f8b83c69a60ap-3,-0x1.921fb54442d18p-3
+sin,0x1.8f8b83c69a60bp-3,0x1.921fb54442d19p-3
+sin,-0x1.8f8b83c69a60bp-3,-0x1.921fb54442d19p-3
+sin,0x1.87de2a6aea962p-2,0x1.921fb54442d17p-2
+sin,-0x1.87de2a6aea962p-2,-0x1.921fb54442d17p-2
+sin,0x1.87de2a6aea963p-2,0x1.921fb54442d18p-2
+sin,-0x1.87de2a6aea963p-2,-0x1.921fb54442d18p-2
+sin,0x1.87de2a6aea964p-2,0x1.921fb54442d19p-2
+sin,-0x1.87de2a6aea964p-2,-0x1.921fb54442d19p-2
+sin,0x1.6a09e667f3bccp-1,0x1.921fb54442d17p-1
+sin,-0x1.6a09e667f3bccp-1,-0x1.921fb54442d17p-1
+sin,0x1.6a09e667f3bccp-1,0x1.921fb54442d18p-1
+sin,-0x1.6a09e667f3bccp-1,-0x1.921fb54442d18p-1
+sin,0x1.6a09e667f3bcdp-1,0x1.921fb54442d19p-1
+sin,-0x1.6a09e667f3bcdp-1,-0x1.921fb54442d19p-1
+sin,0x1.0p0,0x1.921fb54442d17p0
+sin,-0x1.0p0,-0x1.921fb54442d17p0
+sin,0x1.0p0,0x1.921fb54442d18p0
+sin,-0x1.0p0,-0x1.921fb54442d18p0
+sin,0x1.0p0,0x1.921fb54442d19p0
+sin,-0x1.0p0,-0x1.921fb54442d19p0
+sin,0x1.469898cc51702p-51,0x1.921fb54442d17p1
+sin,-0x1.469898cc51702p-51,-0x1.921fb54442d17p1
+sin,0x1.1a62633145c07p-53,0x1.921fb54442d18p1
+sin,-0x1.1a62633145c07p-53,-0x1.921fb54442d18p1
+sin,-0x1.72cece675d1fdp-52,0x1.921fb54442d19p1
+sin,0x1.72cece675d1fdp-52,-0x1.921fb54442d19p1
+sin,-0x1.469898cc51702p-50,0x1.921fb54442d17p2
+sin,0x1.469898cc51702p-50,-0x1.921fb54442d17p2
+sin,-0x1.1a62633145c07p-52,0x1.921fb54442d18p2
+sin,0x1.1a62633145c07p-52,-0x1.921fb54442d18p2
+sin,0x1.72cece675d1fdp-51,0x1.921fb54442d19p2
+sin,-0x1.72cece675d1fdp-51,-0x1.921fb54442d19p2
+sin,-0x1.469898cc51702p-49,0x1.921fb54442d17p3
+sin,0x1.469898cc51702p-49,-0x1.921fb54442d17p3
+sin,-0x1.1a62633145c07p-51,0x1.921fb54442d18p3
+sin,0x1.1a62633145c07p-51,-0x1.921fb54442d18p3
+sin,0x1.72cece675d1fdp-50,0x1.921fb54442d19p3
+sin,-0x1.72cece675d1fdp-50,-0x1.921fb54442d19p3
+sin,-0x1.469898cc51702p-48,0x1.921fb54442d17p4
+sin,0x1.469898cc51702p-48,-0x1.921fb54442d17p4
+sin,-0x1.1a62633145c07p-50,0x1.921fb54442d18p4
+sin,0x1.1a62633145c07p-50,-0x1.921fb54442d18p4
+sin,0x1.72cece675d1fdp-49,0x1.921fb54442d19p4
+sin,-0x1.72cece675d1fdp-49,-0x1.921fb54442d19p4
+sin,-0x1.469898cc51702p-47,0x1.921fb54442d17p5
+sin,0x1.469898cc51702p-47,-0x1.921fb54442d17p5
+sin,-0x1.1a62633145c07p-49,0x1.921fb54442d18p5
+sin,0x1.1a62633145c07p-49,-0x1.921fb54442d18p5
+sin,0x1.72cece675d1fdp-48,0x1.921fb54442d19p5
+sin,-0x1.72cece675d1fdp-48,-0x1.921fb54442d19p5
+sin,-0x1.469898cc51702p-46,0x1.921fb54442d17p6
+sin,0x1.469898cc51702p-46,-0x1.921fb54442d17p6
+sin,-0x1.1a62633145c07p-48,0x1.921fb54442d18p6
+sin,0x1.1a62633145c07p-48,-0x1.921fb54442d18p6
+sin,0x1.72cece675d1fdp-47,0x1.921fb54442d19p6
+sin,-0x1.72cece675d1fdp-47,-0x1.921fb54442d19p6
+sin,-0x1.469898cc51702p-45,0x1.921fb54442d17p7
+sin,0x1.469898cc51702p-45,-0x1.921fb54442d17p7
+sin,-0x1.1a62633145c07p-47,0x1.921fb54442d18p7
+sin,0x1.1a62633145c07p-47,-0x1.921fb54442d18p7
+sin,0x1.72cece675d1fdp-46,0x1.921fb54442d19p7
+sin,-0x1.72cece675d1fdp-46,-0x1.921fb54442d19p7
+sin,0x1.6a09e667f3bdp-1,0x1.2d97c7f3321d1p1
+sin,-0x1.6a09e667f3bdp-1,-0x1.2d97c7f3321d1p1
+sin,0x1.6a09e667f3bcdp-1,0x1.2d97c7f3321d2p1
+sin,-0x1.6a09e667f3bcdp-1,-0x1.2d97c7f3321d2p1
+sin,0x1.6a09e667f3bcap-1,0x1.2d97c7f3321d3p1
+sin,-0x1.6a09e667f3bcap-1,-0x1.2d97c7f3321d3p1
+sin,-0x1.6a09e667f3bc9p-1,0x1.f6a7a2955385dp1
+sin,0x1.6a09e667f3bc9p-1,-0x1.f6a7a2955385dp1
+sin,-0x1.6a09e667f3bccp-1,0x1.f6a7a2955385ep1
+sin,0x1.6a09e667f3bccp-1,-0x1.f6a7a2955385ep1
+sin,-0x1.6a09e667f3bcep-1,0x1.f6a7a2955385fp1
+sin,0x1.6a09e667f3bcep-1,-0x1.f6a7a2955385fp1
+sin,-0x1.0p0,0x1.2d97c7f3321d1p2
+sin,0x1.0p0,-0x1.2d97c7f3321d1p2
+sin,-0x1.0p0,0x1.2d97c7f3321d2p2
+sin,0x1.0p0,-0x1.2d97c7f3321d2p2
+sin,-0x1.0p0,0x1.2d97c7f3321d3p2
+sin,0x1.0p0,-0x1.2d97c7f3321d3p2
+sin,-0x1.6a09e667f3bd4p-1,0x1.5fdbbe9bba774p2
+sin,0x1.6a09e667f3bd4p-1,-0x1.5fdbbe9bba774p2
+sin,-0x1.6a09e667f3bcep-1,0x1.5fdbbe9bba775p2
+sin,0x1.6a09e667f3bcep-1,-0x1.5fdbbe9bba775p2
+sin,-0x1.6a09e667f3bc8p-1,0x1.5fdbbe9bba776p2
+sin,0x1.6a09e667f3bc8p-1,-0x1.5fdbbe9bba776p2
+sin,0x1.6a09e667f3bc5p-1,0x1.c463abeccb2bap2
+sin,-0x1.6a09e667f3bc5p-1,-0x1.c463abeccb2bap2
+sin,0x1.6a09e667f3bcbp-1,0x1.c463abeccb2bbp2
+sin,-0x1.6a09e667f3bcbp-1,-0x1.c463abeccb2bbp2
+sin,0x1.6a09e667f3bd1p-1,0x1.c463abeccb2bcp2
+sin,-0x1.6a09e667f3bd1p-1,-0x1.c463abeccb2bcp2
+sin,0x1.0p0,0x1.f6a7a2955385dp2
+sin,-0x1.0p0,-0x1.f6a7a2955385dp2
+sin,0x1.0p0,0x1.f6a7a2955385ep2
+sin,-0x1.0p0,-0x1.f6a7a2955385ep2
+sin,0x1.0p0,0x1.f6a7a2955385fp2
+sin,-0x1.0p0,-0x1.f6a7a2955385fp2
+sin,0x1.6a09e667f3bdfp-1,0x1.1475cc9eedeffp3
+sin,-0x1.6a09e667f3bdfp-1,-0x1.1475cc9eedeffp3
+sin,0x1.6a09e667f3bd4p-1,0x1.1475cc9eedfp3
+sin,-0x1.6a09e667f3bd4p-1,-0x1.1475cc9eedfp3
+sin,0x1.6a09e667f3bc9p-1,0x1.1475cc9eedf01p3
+sin,-0x1.6a09e667f3bc9p-1,-0x1.1475cc9eedf01p3
+sin,0x1.34f272993d141p-49,0x1.2d97c7f3321d1p3
+sin,-0x1.34f272993d141p-49,-0x1.2d97c7f3321d1p3
+sin,0x1.a79394c9e8a0ap-52,0x1.2d97c7f3321d2p3
+sin,-0x1.a79394c9e8a0ap-52,-0x1.2d97c7f3321d2p3
+sin,-0x1.961b1acd85d7dp-50,0x1.2d97c7f3321d3p3
+sin,0x1.961b1acd85d7dp-50,-0x1.2d97c7f3321d3p3
+sin,-0x1.6a09e667f3bb9p-1,0x1.46b9c347764a2p3
+sin,0x1.6a09e667f3bb9p-1,-0x1.46b9c347764a2p3
+sin,-0x1.6a09e667f3bc4p-1,0x1.46b9c347764a3p3
+sin,0x1.6a09e667f3bc4p-1,-0x1.46b9c347764a3p3
+sin,-0x1.6a09e667f3bdp-1,0x1.46b9c347764a4p3
+sin,0x1.6a09e667f3bdp-1,-0x1.46b9c347764a4p3
+sin,-0x1.0p0,0x1.5fdbbe9bba774p3
+sin,0x1.0p0,-0x1.5fdbbe9bba774p3
+sin,-0x1.0p0,0x1.5fdbbe9bba775p3
+sin,0x1.0p0,-0x1.5fdbbe9bba775p3
+sin,-0x1.0p0,0x1.5fdbbe9bba776p3
+sin,0x1.0p0,-0x1.5fdbbe9bba776p3
+sin,-0x1.6a09e667f3bep-1,0x1.78fdb9effea45p3
+sin,0x1.6a09e667f3bep-1,-0x1.78fdb9effea45p3
+sin,-0x1.6a09e667f3bd5p-1,0x1.78fdb9effea46p3
+sin,0x1.6a09e667f3bd5p-1,-0x1.78fdb9effea46p3
+sin,-0x1.6a09e667f3bcap-1,0x1.78fdb9effea47p3
+sin,0x1.6a09e667f3bcap-1,-0x1.78fdb9effea47p3
+sin,0x1.6a09e667f3bb8p-1,0x1.ab41b09886fe8p3
+sin,-0x1.6a09e667f3bb8p-1,-0x1.ab41b09886fe8p3
+sin,0x1.6a09e667f3bc4p-1,0x1.ab41b09886fe9p3
+sin,-0x1.6a09e667f3bc4p-1,-0x1.ab41b09886fe9p3
+sin,0x1.6a09e667f3bcfp-1,0x1.ab41b09886feap3
+sin,-0x1.6a09e667f3bcfp-1,-0x1.ab41b09886feap3
+sin,0x1.0p0,0x1.c463abeccb2bap3
+sin,-0x1.0p0,-0x1.c463abeccb2bap3
+sin,0x1.0p0,0x1.c463abeccb2bbp3
+sin,-0x1.0p0,-0x1.c463abeccb2bbp3
+sin,0x1.0p0,0x1.c463abeccb2bcp3
+sin,-0x1.0p0,-0x1.c463abeccb2bcp3
+sin,0x1.6a09e667f3be1p-1,0x1.dd85a7410f58bp3
+sin,-0x1.6a09e667f3be1p-1,-0x1.dd85a7410f58bp3
+sin,0x1.6a09e667f3bd6p-1,0x1.dd85a7410f58cp3
+sin,-0x1.6a09e667f3bd6p-1,-0x1.dd85a7410f58cp3
+sin,0x1.6a09e667f3bcbp-1,0x1.dd85a7410f58dp3
+sin,-0x1.6a09e667f3bcbp-1,-0x1.dd85a7410f58dp3
+sin,0x1.583ebeff65cc2p-49,0x1.f6a7a2955385dp3
+sin,-0x1.583ebeff65cc2p-49,-0x1.f6a7a2955385dp3
+sin,0x1.60fafbfd97309p-51,0x1.f6a7a2955385ep3
+sin,-0x1.60fafbfd97309p-51,-0x1.f6a7a2955385ep3
+sin,-0x1.4f8282013467cp-50,0x1.f6a7a2955385fp3
+sin,0x1.4f8282013467cp-50,-0x1.f6a7a2955385fp3
+sin,-0x1.6a09e667f3ba1p-1,0x1.07e4cef4cbd96p4
+sin,0x1.6a09e667f3ba1p-1,-0x1.07e4cef4cbd96p4
+sin,-0x1.6a09e667f3bb8p-1,0x1.07e4cef4cbd97p4
+sin,0x1.6a09e667f3bb8p-1,-0x1.07e4cef4cbd97p4
+sin,-0x1.6a09e667f3bcep-1,0x1.07e4cef4cbd98p4
+sin,0x1.6a09e667f3bcep-1,-0x1.07e4cef4cbd98p4
+sin,-0x1.0p0,0x1.1475cc9eedeffp4
+sin,0x1.0p0,-0x1.1475cc9eedeffp4
+sin,-0x1.0p0,0x1.1475cc9eedfp4
+sin,0x1.0p0,-0x1.1475cc9eedfp4
+sin,-0x1.0p0,0x1.1475cc9eedf01p4
+sin,0x1.0p0,-0x1.1475cc9eedf01p4
+sin,-0x1.6a09e667f3bedp-1,0x1.2106ca4910068p4
+sin,0x1.6a09e667f3bedp-1,-0x1.2106ca4910068p4
+sin,-0x1.6a09e667f3bd7p-1,0x1.2106ca4910069p4
+sin,0x1.6a09e667f3bd7p-1,-0x1.2106ca4910069p4
+sin,-0x1.6a09e667f3bcp-1,0x1.2106ca491006ap4
+sin,0x1.6a09e667f3bcp-1,-0x1.2106ca491006ap4
+sin,-0x1.34f272993d141p-48,0x1.2d97c7f3321d1p4
+sin,0x1.34f272993d141p-48,-0x1.2d97c7f3321d1p4
+sin,-0x1.a79394c9e8a0ap-51,0x1.2d97c7f3321d2p4
+sin,0x1.a79394c9e8a0ap-51,-0x1.2d97c7f3321d2p4
+sin,0x1.961b1acd85d7dp-49,0x1.2d97c7f3321d3p4
+sin,-0x1.961b1acd85d7dp-49,-0x1.2d97c7f3321d3p4
+sin,0x1.6a09e667f3bap-1,0x1.3a28c59d54339p4
+sin,-0x1.6a09e667f3bap-1,-0x1.3a28c59d54339p4
+sin,0x1.6a09e667f3bb7p-1,0x1.3a28c59d5433ap4
+sin,-0x1.6a09e667f3bb7p-1,-0x1.3a28c59d5433ap4
+sin,0x1.6a09e667f3bcep-1,0x1.3a28c59d5433bp4
+sin,-0x1.6a09e667f3bcep-1,-0x1.3a28c59d5433bp4
+sin,0x1.0p0,0x1.46b9c347764a2p4
+sin,-0x1.0p0,-0x1.46b9c347764a2p4
+sin,0x1.0p0,0x1.46b9c347764a3p4
+sin,-0x1.0p0,-0x1.46b9c347764a3p4
+sin,0x1.0p0,0x1.46b9c347764a4p4
+sin,-0x1.0p0,-0x1.46b9c347764a4p4
+sin,0x1.6a09e667f3beep-1,0x1.534ac0f19860bp4
+sin,-0x1.6a09e667f3beep-1,-0x1.534ac0f19860bp4
+sin,0x1.6a09e667f3bd8p-1,0x1.534ac0f19860cp4
+sin,-0x1.6a09e667f3bd8p-1,-0x1.534ac0f19860cp4
+sin,0x1.6a09e667f3bc1p-1,0x1.534ac0f19860dp4
+sin,-0x1.6a09e667f3bc1p-1,-0x1.534ac0f19860dp4
+sin,0x1.3dc585b2c7422p-48,0x1.5fdbbe9bba774p4
+sin,-0x1.3dc585b2c7422p-48,-0x1.5fdbbe9bba774p4
+sin,0x1.ee2c2d963a10cp-51,0x1.5fdbbe9bba775p4
+sin,-0x1.ee2c2d963a10cp-51,-0x1.5fdbbe9bba775p4
+sin,-0x1.8474f49a717bdp-49,0x1.5fdbbe9bba776p4
+sin,0x1.8474f49a717bdp-49,-0x1.5fdbbe9bba776p4
+sin,-0x1.6a09e667f3b9fp-1,0x1.6c6cbc45dc8dcp4
+sin,0x1.6a09e667f3b9fp-1,-0x1.6c6cbc45dc8dcp4
+sin,-0x1.6a09e667f3bb6p-1,0x1.6c6cbc45dc8ddp4
+sin,0x1.6a09e667f3bb6p-1,-0x1.6c6cbc45dc8ddp4
+sin,-0x1.6a09e667f3bcdp-1,0x1.6c6cbc45dc8dep4
+sin,0x1.6a09e667f3bcdp-1,-0x1.6c6cbc45dc8dep4
+sin,-0x1.0p0,0x1.78fdb9effea45p4
+sin,0x1.0p0,-0x1.78fdb9effea45p4
+sin,-0x1.0p0,0x1.78fdb9effea46p4
+sin,0x1.0p0,-0x1.78fdb9effea46p4
+sin,-0x1.0p0,0x1.78fdb9effea47p4
+sin,0x1.0p0,-0x1.78fdb9effea47p4
+sin,-0x1.6a09e667f3befp-1,0x1.858eb79a20baep4
+sin,0x1.6a09e667f3befp-1,-0x1.858eb79a20baep4
+sin,-0x1.6a09e667f3bd8p-1,0x1.858eb79a20bafp4
+sin,0x1.6a09e667f3bd8p-1,-0x1.858eb79a20bafp4
+sin,-0x1.6a09e667f3bc2p-1,0x1.858eb79a20bbp4
+sin,0x1.6a09e667f3bc2p-1,-0x1.858eb79a20bbp4
+sin,0x1.fa7299b17573dp-1,0x1.fffffffffffffp62
+sin,-0x1.fa7299b17573dp-1,-0x1.fffffffffffffp62
+sin,0x1.fff6dfd42dc54p-1,0x1.0p63
+sin,-0x1.fff6dfd42dc54p-1,-0x1.0p63
+sin,0x1.e456b818e7397p-1,0x1.0000000000001p63
+sin,-0x1.e456b818e7397p-1,-0x1.0000000000001p63
+sin,-0x1.86dcca0d689e8p-1,0x1.fffffffffffffp26
+sin,0x1.86dcca0d689e8p-1,-0x1.fffffffffffffp26
+sin,-0x1.86dcc9babb0a4p-1,0x1.0p27
+sin,0x1.86dcc9babb0a4p-1,-0x1.0p27
+sin,-0x1.86dcc9155fe18p-1,0x1.0000000000001p27
+sin,0x1.86dcc9155fe18p-1,-0x1.0000000000001p27
+sin,-0x1.8f22f84d42da2p-1,0x1.fffffffffffffp23
+sin,0x1.8f22f84d42da2p-1,-0x1.fffffffffffffp23
+sin,-0x1.8f22f8433d6eep-1,0x1.0p24
+sin,0x1.8f22f8433d6eep-1,-0x1.0p24
+sin,-0x1.8f22f82f32986p-1,0x1.0000000000001p24
+sin,0x1.8f22f82f32986p-1,-0x1.0000000000001p24
+sin,-0x1.837b9dddc1eacp-1,0x1.fffffffffffffp1
+sin,0x1.837b9dddc1eacp-1,-0x1.fffffffffffffp1
+sin,-0x1.837b9dddc1eaep-1,0x1.0p2
+sin,0x1.837b9dddc1eaep-1,-0x1.0p2
+sin,-0x1.837b9dddc1eb4p-1,0x1.0000000000001p2
+sin,0x1.837b9dddc1eb4p-1,-0x1.0000000000001p2
+sin,0x1.d18f6ead1b447p-1,0x1.fffffffffffffp0
+sin,-0x1.d18f6ead1b447p-1,-0x1.fffffffffffffp0
+sin,0x1.d18f6ead1b446p-1,0x1.0p1
+sin,-0x1.d18f6ead1b446p-1,-0x1.0p1
+sin,0x1.d18f6ead1b444p-1,0x1.0000000000001p1
+sin,-0x1.d18f6ead1b444p-1,-0x1.0000000000001p1
+sin,0x1.aed548f090cedp-1,0x1.fffffffffffffp-1
+sin,-0x1.aed548f090cedp-1,-0x1.fffffffffffffp-1
+sin,0x1.aed548f090ceep-1,0x1.0p0
+sin,-0x1.aed548f090ceep-1,-0x1.0p0
+sin,0x1.aed548f090cefp-1,0x1.0000000000001p0
+sin,-0x1.aed548f090cefp-1,-0x1.0000000000001p0
+sin,0x1.eaee8744b05efp-2,0x1.fffffffffffffp-2
+sin,-0x1.eaee8744b05efp-2,-0x1.fffffffffffffp-2
+sin,0x1.eaee8744b05fp-2,0x1.0p-1
+sin,-0x1.eaee8744b05fp-2,-0x1.0p-1
+sin,0x1.eaee8744b05f2p-2,0x1.0000000000001p-1
+sin,-0x1.eaee8744b05f2p-2,-0x1.0000000000001p-1
+sin,0x1.faaeed4f31576p-3,0x1.fffffffffffffp-3
+sin,-0x1.faaeed4f31576p-3,-0x1.fffffffffffffp-3
+sin,0x1.faaeed4f31577p-3,0x1.0p-2
+sin,-0x1.faaeed4f31577p-3,-0x1.0p-2
+sin,0x1.faaeed4f31579p-3,0x1.0000000000001p-2
+sin,-0x1.faaeed4f31579p-3,-0x1.0000000000001p-2
+sin,0x1.feaaeee86ee35p-4,0x1.fffffffffffffp-4
+sin,-0x1.feaaeee86ee35p-4,-0x1.fffffffffffffp-4
+sin,0x1.feaaeee86ee36p-4,0x1.0p-3
+sin,-0x1.feaaeee86ee36p-4,-0x1.0p-3
+sin,0x1.feaaeee86ee38p-4,0x1.0000000000001p-3
+sin,-0x1.feaaeee86ee38p-4,-0x1.0000000000001p-3
+sin,0x1.ffaaaeeed4edap-5,0x1.fffffffffffffp-5
+sin,-0x1.ffaaaeeed4edap-5,-0x1.fffffffffffffp-5
+sin,0x1.ffaaaeeed4edbp-5,0x1.0p-4
+sin,-0x1.ffaaaeeed4edbp-5,-0x1.0p-4
+sin,0x1.ffaaaeeed4eddp-5,0x1.0000000000001p-4
+sin,-0x1.ffaaaeeed4eddp-5,-0x1.0000000000001p-4
+sin,0x1.ffeaaaeeee86ep-6,0x1.fffffffffffffp-6
+sin,-0x1.ffeaaaeeee86ep-6,-0x1.fffffffffffffp-6
+sin,0x1.ffeaaaeeee86fp-6,0x1.0p-5
+sin,-0x1.ffeaaaeeee86fp-6,-0x1.0p-5
+sin,0x1.ffeaaaeeee871p-6,0x1.0000000000001p-5
+sin,-0x1.ffeaaaeeee871p-6,-0x1.0000000000001p-5
+sin,0x1.fffaaaaeeeed4p-7,0x1.fffffffffffffp-7
+sin,-0x1.fffaaaaeeeed4p-7,-0x1.fffffffffffffp-7
+sin,0x1.fffaaaaeeeed5p-7,0x1.0p-6
+sin,-0x1.fffaaaaeeeed5p-7,-0x1.0p-6
+sin,0x1.fffaaaaeeeed7p-7,0x1.0000000000001p-6
+sin,-0x1.fffaaaaeeeed7p-7,-0x1.0000000000001p-6
+sin,0x1.fffffffaaaaaap-15,0x1.fffffffffffffp-15
+sin,-0x1.fffffffaaaaaap-15,-0x1.fffffffffffffp-15
+sin,0x1.fffffffaaaaabp-15,0x1.0p-14
+sin,-0x1.fffffffaaaaabp-15,-0x1.0p-14
+sin,0x1.fffffffaaaaadp-15,0x1.0000000000001p-14
+sin,-0x1.fffffffaaaaadp-15,-0x1.0000000000001p-14
+sin,0x1.fffffffffffffp-28,0x1.fffffffffffffp-28
+sin,-0x1.fffffffffffffp-28,-0x1.fffffffffffffp-28
+sin,0x1.0p-27,0x1.0p-27
+sin,-0x1.0p-27,-0x1.0p-27
+sin,0x1.0000000000001p-27,0x1.0000000000001p-27
+sin,-0x1.0000000000001p-27,-0x1.0000000000001p-27
+sin,0x1.fffffffffffffp-31,0x1.fffffffffffffp-31
+sin,-0x1.fffffffffffffp-31,-0x1.fffffffffffffp-31
+sin,0x1.0p-30,0x1.0p-30
+sin,-0x1.0p-30,-0x1.0p-30
+sin,0x1.0000000000001p-30,0x1.0000000000001p-30
+sin,-0x1.0000000000001p-30,-0x1.0000000000001p-30
+sin,-0x1.452fc98b34e97p-8,-0x1.fffffffffffffp1023
+sin,0x1.452fc98b34e97p-8,0x1.fffffffffffffp1023
+sin,0x1.452fc98b34e97p-8,0x1.fffffffffffffp1023
+sin,-0x1.452fc98b34e97p-8,-0x1.fffffffffffffp1023
+sin,0x1.452fc98b34e97p-8,0x1.fffffffffffffp1023
+sin,-0x1.452fc98b34e97p-8,-0x1.fffffffffffffp1023
+sin,0x1.daa3677c6ee8ap-1,0x1.ffffffffffffep1023
+sin,-0x1.daa3677c6ee8ap-1,-0x1.ffffffffffffep1023
+sin,0x1.1a62633145c07p-53,0x1.921fb54442d18p1
+sin,-0x1.1a62633145c07p-53,-0x1.921fb54442d18p1
+sin,0x1.0p0,0x1.921fb54442d18p0
+sin,-0x1.0p0,-0x1.921fb54442d18p0
+sin,0x1.aed548f090cefp-1,0x1.0000000000001p0
+sin,-0x1.aed548f090cefp-1,-0x1.0000000000001p0
+sin,0x1.aed548f090ceep-1,0x1.0p0
+sin,-0x1.aed548f090ceep-1,-0x1.0p0
+sin,0x1.aed548f090cedp-1,0x1.fffffffffffffp-1
+sin,-0x1.aed548f090cedp-1,-0x1.fffffffffffffp-1
+sin,0x1.6a09e667f3bccp-1,0x1.921fb54442d18p-1
+sin,-0x1.6a09e667f3bccp-1,-0x1.921fb54442d18p-1
+sin,0x1.0000000000001p-1022,0x1.0000000000001p-1022
+sin,-0x1.0000000000001p-1022,-0x1.0000000000001p-1022
+sin,0x1.0p-1022,0x1.0p-1022
+sin,-0x1.0p-1022,-0x1.0p-1022
+sin,0x0.fffffffffffffp-1022,0x0.fffffffffffffp-1022
+sin,-0x0.fffffffffffffp-1022,-0x0.fffffffffffffp-1022
+sin,0x0.ffffffffffffep-1022,0x0.ffffffffffffep-1022
+sin,-0x0.ffffffffffffep-1022,-0x0.ffffffffffffep-1022
+sin,0x0.0000000000002p-1022,0x0.0000000000002p-1022
+sin,-0x0.0000000000002p-1022,-0x0.0000000000002p-1022
+sin,0x0.0000000000001p-1022,0x0.0000000000001p-1022
+sin,-0x0.0000000000001p-1022,-0x0.0000000000001p-1022
+sin,0x0.0p0,0x0.0p0
+cos,0x1.c1a27ae836f13p-1,0x1.feb1f7920e248p-2
+cos,0x1.c1a27ae836f13p-1,-0x1.feb1f7920e248p-2
+cos,0x1.78daf01036d0dp-1,0x1.7cb7648526f99p-1
+cos,0x1.78daf01036d0dp-1,-0x1.7cb7648526f99p-1
+cos,0x1.ff8eb6a91ecbp-1,0x1.549ec0c0c5afap-5
+cos,0x1.ff8eb6a91ecbp-1,-0x1.549ec0c0c5afap-5
+cos,0x1.fed0476fc75cap-1,0x1.16e534ee3658p-4
+cos,0x1.fed0476fc75cap-1,-0x1.16e534ee3658p-4
+cos,0x1.f10fc61e2c78fp-1,0x1.efeef61d39ac2p-3
+cos,0x1.f10fc61e2c78fp-1,-0x1.efeef61d39ac2p-3
+cos,0x1.434a3645be208p-1,0x1.c65a170474549p-1
+cos,0x1.434a3645be208p-1,-0x1.c65a170474549p-1
+cos,0x1.337fc5b072c53p-3,0x1.6b8a6273d7c21p0
+cos,0x1.337fc5b072c53p-3,-0x1.6b8a6273d7c21p0
+cos,0x1.efa7cddb128fcp-1,-0x1.036f4ba7e90aap-2
+cos,0x1.efa7cddb128fcp-1,0x1.036f4ba7e90aap-2
+cos,0x1.0p0,-0x1.1500766c9df2p-31
+cos,0x1.0p0,0x1.1500766c9df2p-31
+cos,0x1.ec231802917bep-1,-0x1.1e2a1563e068ep-2
+cos,0x1.ec231802917bep-1,0x1.1e2a1563e068ep-2
+cos,0x1.dc044ac92b7fcp-8,-0x1.2115aa73f8d05p5
+cos,0x1.dc044ac92b7fcp-8,0x1.2115aa73f8d05p5
+cos,0x1.d1fa67c50dd53p-4,-0x1.34e3bcdf8f69ap2
+cos,0x1.d1fa67c50dd53p-4,0x1.34e3bcdf8f69ap2
+cos,0x1.e2f8d19fb8db8p-2,-0x1.380000000000bp7
+cos,0x1.e2f8d19fb8db8p-2,0x1.380000000000bp7
+cos,0x1.8da9c90c3eda1p-1,-0x1.440000004p6
+cos,0x1.8da9c90c3eda1p-1,0x1.440000004p6
+cos,0x1.b59b320603f83p-1,-0x1.550c8ee67a4c4p29
+cos,0x1.b59b320603f83p-1,0x1.550c8ee67a4c4p29
+cos,0x1.ffffff7af6c88p-1,-0x1.711789fdb2e8ap-13
+cos,0x1.ffffff7af6c88p-1,0x1.711789fdb2e8ap-13
+cos,0x1.c1b68ebb0b4fep-2,-0x1.77e000002p8
+cos,0x1.c1b68ebb0b4fep-2,0x1.77e000002p8
+cos,0x1.1161e1dad76dcp-4,-0x1.8106561931b43p0
+cos,0x1.1161e1dad76dcp-4,0x1.8106561931b43p0
+cos,0x1.f828c3226b3d7p-5,-0x1.825be2461cad4p0
+cos,0x1.f828c3226b3d7p-5,0x1.825be2461cad4p0
+cos,0x1.f2990d742e9fbp-5,-0x1.8288755803b08p0
+cos,0x1.f2990d742e9fbp-5,0x1.8288755803b08p0
+cos,-0x1.ff150dda7524dp-1,-0x1.8a75701f4ccd3p1
+cos,-0x1.ff150dda7524dp-1,0x1.8a75701f4ccd3p1
+cos,0x1.015c47c32b574p-1,-0x1.b389316f37f37p3
+cos,0x1.015c47c32b574p-1,0x1.b389316f37f37p3
+cos,0x1.d681a366a0534p-1,-0x1.c602c465d7d27p6
+cos,0x1.d681a366a0534p-1,0x1.c602c465d7d27p6
+cos,-0x1.84e896c7543d6p-1,-0x1.cfb81fe69664cp4
+cos,-0x1.84e896c7543d6p-1,0x1.cfb81fe69664cp4
+cos,0x1.fc5dcfddd54cp-1,-0x1.d08f2d86b12c6p13
+cos,0x1.fc5dcfddd54cp-1,0x1.d08f2d86b12c6p13
+cos,0x1.fe83235fbe016p-3,-0x1.de13f0943c494p99
+cos,0x1.fe83235fbe016p-3,0x1.de13f0943c494p99
+cos,-0x1.720321239ec5p-1,-0x1.de3c1f1285e8bp3
+cos,-0x1.720321239ec5p-1,0x1.de3c1f1285e8bp3
+cos,0x1.f7143c8bba407p-4,-0x1.fffffffffff7fp1023
+cos,0x1.f7143c8bba407p-4,0x1.fffffffffff7fp1023
+cos,-0x1.fffe62ecfab75p-1,-0x1.fffffffffffffp1023
+cos,-0x1.fffe62ecfab75p-1,0x1.fffffffffffffp1023
+cos,0x1.055e457ac1227p-5,0x1.0000000000001p51
+cos,0x1.055e457ac1227p-5,-0x1.0000000000001p51
+cos,0x1.c1528065b7d4ep-1,0x1.0000000000003p-1
+cos,0x1.c1528065b7d4ep-1,-0x1.0000000000003p-1
+cos,0x1.0p0,0x1.0000000000003p-32
+cos,0x1.0p0,-0x1.0000000000003p-32
+cos,0x1.fffea444bc05ep-1,0x1.000000000002p150
+cos,0x1.fffea444bc05ep-1,-0x1.000000000002p150
+cos,-0x1.ebddee876f434p-1,0x1.0000000000038p380
+cos,-0x1.ebddee876f434p-1,-0x1.0000000000038p380
+cos,-0x1.f2ffc51dc6968p-1,0x1.0000000000118p380
+cos,-0x1.f2ffc51dc6968p-1,-0x1.0000000000118p380
+cos,-0x1.f8fbb4d358b2p-1,0x1.00000000003ffp641
+cos,-0x1.f8fbb4d358b2p-1,-0x1.00000000003ffp641
+cos,-0x1.aa2265753e668p-2,0x1.0000000001p1
+cos,-0x1.aa2265753e668p-2,-0x1.0000000001p1
+cos,0x1.fd1242c25994dp-1,0x1.000000008p452
+cos,0x1.fd1242c25994dp-1,-0x1.000000008p452
+cos,0x1.fffc0001554dap-1,0x1.00000000effafp-7
+cos,0x1.fffc0001554dap-1,-0x1.00000000effafp-7
+cos,0x1.14a27f2925522p-1,0x1.00000114fefe2p0
+cos,0x1.14a27f2925522p-1,-0x1.00000114fefe2p0
+cos,0x1.bf81e0269c59dp-3,0x1.000007p40
+cos,0x1.bf81e0269c59dp-3,-0x1.000007p40
+cos,0x1.14a26ed1960d6p-1,0x1.00000acadb3d3p0
+cos,0x1.14a26ed1960d6p-1,-0x1.00000acadb3d3p0
+cos,0x1.ffffffffbfffep-1,0x1.00003p-17
+cos,0x1.ffffffffbfffep-1,-0x1.00003p-17
+cos,0x1.ffffffffeffffp-1,0x1.00003ffffffaep-18
+cos,0x1.ffffffffeffffp-1,-0x1.00003ffffffaep-18
+cos,0x1.ffffffffeffffp-1,0x1.00003ffffffffp-18
+cos,0x1.ffffffffeffffp-1,-0x1.00003ffffffffp-18
+cos,-0x1.dab7efeb35baep-2,0x1.00007ffffdeap41
+cos,-0x1.dab7efeb35baep-2,-0x1.00007ffffdeap41
+cos,0x1.fffffffffcp-1,0x1.0000ffff8p-19
+cos,0x1.fffffffffcp-1,-0x1.0000ffff8p-19
+cos,0x1.ffffffffffp-1,0x1.0003fff800051p-20
+cos,0x1.ffffffffffp-1,-0x1.0003fff800051p-20
+cos,0x1.ffffffffffp-1,0x1.0003fff800096p-20
+cos,0x1.ffffffffffp-1,-0x1.0003fff800096p-20
+cos,-0x1.fbf2b71a23a58p-2,0x1.000fd2p334
+cos,-0x1.fbf2b71a23a58p-2,-0x1.000fd2p334
+cos,0x1.fccc87eae7737p-5,0x1.003p514
+cos,0x1.fccc87eae7737p-5,-0x1.003p514
+cos,-0x1.a43f40d92b7edp-7,0x1.00600000015f4p41
+cos,-0x1.a43f40d92b7edp-7,-0x1.00600000015f4p41
+cos,0x1.c11cc38f40ab3p-1,0x1.007p-1
+cos,0x1.c11cc38f40ab3p-1,-0x1.007p-1
+cos,0x1.ffffffffffbfcp-1,0x1.007p-21
+cos,0x1.ffffffffffbfcp-1,-0x1.007p-21
+cos,0x1.e9ba98231f734p-8,0x1.00cp40
+cos,0x1.e9ba98231f734p-8,-0x1.00cp40
+cos,0x1.fefdf48ed649dp-1,0x1.011p-4
+cos,0x1.fefdf48ed649dp-1,-0x1.011p-4
+cos,-0x1.ffc16a0f12ff2p-1,0x1.011p996
+cos,-0x1.ffc16a0f12ff2p-1,-0x1.011p996
+cos,0x1.efd5b61a30a38p-1,0x1.02p-2
+cos,0x1.efd5b61a30a38p-1,-0x1.02p-2
+cos,0x1.c97b8161dc50ap-2,0x1.0204260c18307p59
+cos,0x1.c97b8161dc50ap-2,-0x1.0204260c18307p59
+cos,-0x1.bf26a3c9b9fbfp-2,0x1.02e78a321155ep1
+cos,-0x1.bf26a3c9b9fbfp-2,-0x1.02e78a321155ep1
+cos,0x1.fef806b1f84e5p-1,0x1.04p-4
+cos,0x1.fef806b1f84e5p-1,-0x1.04p-4
+cos,0x1.fe851fbf87d17p-1,0x1.04bde8bb80258p98
+cos,0x1.fe851fbf87d17p-1,-0x1.04bde8bb80258p98
+cos,0x1.70f6a51da8effp-1,0x1.077e749e37ceep236
+cos,0x1.70f6a51da8effp-1,-0x1.077e749e37ceep236
+cos,0x1.6b408c856bda6p-3,0x1.07f8p300
+cos,0x1.6b408c856bda6p-3,-0x1.07f8p300
+cos,0x1.2b2f965ae40fcp-1,0x1.07f9bea1b3546p27
+cos,0x1.2b2f965ae40fcp-1,-0x1.07f9bea1b3546p27
+cos,-0x1.4eed2f3fc76a8p-1,0x1.090d18372f2d5p4
+cos,-0x1.4eed2f3fc76a8p-1,-0x1.090d18372f2d5p4
+cos,0x1.fba59aecee5p-1,0x1.0b4p-3
+cos,0x1.fba59aecee5p-1,-0x1.0b4p-3
+cos,0x1.fffd1bcda7a7dp-1,0x1.0c0d5c2af3c2ep346
+cos,0x1.fffd1bcda7a7dp-1,-0x1.0c0d5c2af3c2ep346
+cos,-0x1.e4dfe83129286p-1,0x1.0d30596ee91fdp216
+cos,-0x1.e4dfe83129286p-1,-0x1.0d30596ee91fdp216
+cos,0x1.fb8432886a284p-2,0x1.0d6p0
+cos,0x1.fb8432886a284p-2,-0x1.0d6p0
+cos,0x1.ffffee202854p-1,0x1.0e9474c68831cp-10
+cos,0x1.ffffee202854p-1,-0x1.0e9474c68831cp-10
+cos,-0x1.b70d3d5584b1bp-2,0x1.113bae4049849p2
+cos,-0x1.b70d3d5584b1bp-2,-0x1.113bae4049849p2
+cos,0x1.fed8df58f626p-1,0x1.12eb87097654p-4
+cos,0x1.fed8df58f626p-1,-0x1.12eb87097654p-4
+cos,0x1.e536ae395dfcep-2,0x1.13cp0
+cos,0x1.e536ae395dfcep-2,-0x1.13cp0
+cos,0x1.fed0476fc75cap-1,0x1.16e534ee3658p-4
+cos,0x1.fed0476fc75cap-1,-0x1.16e534ee3658p-4
+cos,0x1.fb38e82e3193ap-1,0x1.17fffffffea98p-3
+cos,0x1.fb38e82e3193ap-1,-0x1.17fffffffea98p-3
+cos,0x1.fb38e82e3188p-1,0x1.18p-3
+cos,0x1.fb38e82e3188p-1,-0x1.18p-3
+cos,-0x1.e59647f1fe9c7p-1,0x1.1a191ebbb4d7fp7
+cos,-0x1.e59647f1fe9c7p-1,-0x1.1a191ebbb4d7fp7
+cos,-0x1.d0dca1f8715bep-4,0x1.1da84f2b7b1d8p7
+cos,-0x1.d0dca1f8715bep-4,-0x1.1da84f2b7b1d8p7
+cos,0x1.b917ebbc30e1ep-2,0x1.201e973251302p0
+cos,0x1.b917ebbc30e1ep-2,-0x1.201e973251302p0
+cos,0x1.fffadf12ff414p-1,0x1.21e02p-7
+cos,0x1.fffadf12ff414p-1,-0x1.21e02p-7
+cos,-0x1.598a4dab3de5ap-1,0x1.27e29a4b985bfp1
+cos,-0x1.598a4dab3de5ap-1,-0x1.27e29a4b985bfp1
+cos,0x1.fa95c1154abf5p-1,0x1.2a1f28dbfb6cp-3
+cos,0x1.fa95c1154abf5p-1,-0x1.2a1f28dbfb6cp-3
+cos,-0x1.6412293adb7bcp-1,0x1.2b8p1
+cos,-0x1.6412293adb7bcp-1,-0x1.2b8p1
+cos,0x1.fffa518a7d0e7p-1,0x1.31199def72f4dp-7
+cos,0x1.fffa518a7d0e7p-1,-0x1.31199def72f4dp-7
+cos,0x1.f36895fe177f8p-1,0x1.31260e1485014p4
+cos,0x1.f36895fe177f8p-1,-0x1.31260e1485014p4
+cos,0x1.d36207b4fee17p-4,0x1.34e964cd103bdp2
+cos,0x1.d36207b4fee17p-4,-0x1.34e964cd103bdp2
+cos,-0x1.84a37f4fa7616p-1,0x1.37618a0ba785p1
+cos,-0x1.84a37f4fa7616p-1,-0x1.37618a0ba785p1
+cos,-0x1.c830bbc99e229p-39,0x1.379704f5f1eb3p24
+cos,-0x1.c830bbc99e229p-39,-0x1.379704f5f1eb3p24
+cos,0x1.b5daaa233bd5p-3,0x1.3b61dd166d47p2
+cos,0x1.b5daaa233bd5p-3,-0x1.3b61dd166d47p2
+cos,-0x1.ffd00dc4db401p-4,0x1.3c011022acbdp37
+cos,-0x1.ffd00dc4db401p-4,-0x1.3c011022acbdp37
+cos,-0x1.14052b4016ff5p-1,0x1.3e7788e900b7p727
+cos,-0x1.14052b4016ff5p-1,-0x1.3e7788e900b7p727
+cos,0x1.ffffe6a5e4198p-1,0x1.423eafdcc2779p-10
+cos,0x1.ffffe6a5e4198p-1,-0x1.423eafdcc2779p-10
+cos,-0x1.fe09fc3d16feep-6,0x1.4321828c1b538p119
+cos,-0x1.fe09fc3d16feep-6,-0x1.4321828c1b538p119
+cos,0x1.b685d949a27ap-14,0x1.43506cb22975dp22
+cos,0x1.b685d949a27ap-14,-0x1.43506cb22975dp22
+cos,0x1.fe398090e203cp-1,0x1.439f63495786ap67
+cos,0x1.fe398090e203cp-1,-0x1.439f63495786ap67
+cos,0x1.fe6274e000974p-1,0x1.457538a6bd073p-4
+cos,0x1.fe6274e000974p-1,-0x1.457538a6bd073p-4
+cos,0x1.09fcb69359c0ap-1,0x1.478fc08p43
+cos,0x1.09fcb69359c0ap-1,-0x1.478fc08p43
+cos,-0x1.20c2158511e79p-9,0x1.48a45797cbe63p61
+cos,-0x1.20c2158511e79p-9,-0x1.48a45797cbe63p61
+cos,0x1.990d17aae253p-1,0x1.4a62e0e12c173p-1
+cos,0x1.990d17aae253p-1,-0x1.4a62e0e12c173p-1
+cos,0x1.fdd4f1e00b387p-3,0x1.4c596642a9488p9
+cos,0x1.fdd4f1e00b387p-3,-0x1.4c596642a9488p9
+cos,0x1.fe4f141032f38p-1,0x1.4dp-4
+cos,0x1.fe4f141032f38p-1,-0x1.4dp-4
+cos,0x1.94e9f45d43c14p-2,0x1.4f0f308p488
+cos,0x1.94e9f45d43c14p-2,-0x1.4f0f308p488
+cos,0x1.9355f69ad4326p-2,0x1.52f00ep793
+cos,0x1.9355f69ad4326p-2,-0x1.52f00ep793
+cos,0x1.1a19be8bea10ap-1,0x1.52f06c730ec02p2
+cos,0x1.1a19be8bea10ap-1,-0x1.52f06c730ec02p2
+cos,0x1.385d92ec0c734p-1,0x1.53e7d5845fe3dp220
+cos,0x1.385d92ec0c734p-1,-0x1.53e7d5845fe3dp220
+cos,0x1.fffffffffe2f1p-1,0x1.59p-20
+cos,0x1.fffffffffe2f1p-1,-0x1.59p-20
+cos,-0x1.ffd7bc28ded92p-1,0x1.592f1176f098p86
+cos,-0x1.ffd7bc28ded92p-1,-0x1.592f1176f098p86
+cos,-0x1.cee28b3d79799p-1,0x1.5999999dc09dcp1
+cos,-0x1.cee28b3d79799p-1,-0x1.5999999dc09dcp1
+cos,0x1.c1f1eb08c2604p-1,0x1.5bea01p468
+cos,0x1.c1f1eb08c2604p-1,-0x1.5bea01p468
+cos,0x1.fffe35ab09a65p-1,0x1.5cb80a6135e5ap1000
+cos,0x1.fffe35ab09a65p-1,-0x1.5cb80a6135e5ap1000
+cos,-0x1.07b85f606e75dp-3,0x1.5d5be48730d2dp13
+cos,-0x1.07b85f606e75dp-3,-0x1.5d5be48730d2dp13
+cos,0x1.ffffffffff862p-1,0x1.614p-21
+cos,0x1.ffffffffff862p-1,-0x1.614p-21
+cos,-0x1.dd3a806e89cf2p-1,0x1.62adc8a660364p1
+cos,-0x1.dd3a806e89cf2p-1,-0x1.62adc8a660364p1
+cos,-0x1.4308b14f4b6eep-1,0x1.64ef438p142
+cos,-0x1.4308b14f4b6eep-1,-0x1.64ef438p142
+cos,0x1.6623d2eb6add2p-3,0x1.652p0
+cos,0x1.6623d2eb6add2p-3,-0x1.652p0
+cos,0x1.fff832c50f472p-1,0x1.65865b2cb08a2p-7
+cos,0x1.fff832c50f472p-1,-0x1.65865b2cb08a2p-7
+cos,0x1.acc251be33023p-1,0x1.6a937daabc20ep375
+cos,0x1.acc251be33023p-1,-0x1.6a937daabc20ep375
+cos,-0x1.14ae72e6ba22fp-61,0x1.6ac5b262ca1ffp849
+cos,-0x1.14ae72e6ba22fp-61,-0x1.6ac5b262ca1ffp849
+cos,0x1.e0619960a11c6p-2,0x1.6f7bdef7bdef4p3
+cos,0x1.e0619960a11c6p-2,-0x1.6f7bdef7bdef4p3
+cos,0x1.8d23f97901a3p-1,0x1.739ce759ce738p200
+cos,0x1.8d23f97901a3p-1,-0x1.739ce759ce738p200
+cos,0x1.fffff78a14ba1p-1,0x1.7450c3f49d0b2p-11
+cos,0x1.fffff78a14ba1p-1,-0x1.7450c3f49d0b2p-11
+cos,0x1.d6f1c727fb2ccp-4,0x1.749fe53f963fdp0
+cos,0x1.d6f1c727fb2ccp-4,-0x1.749fe53f963fdp0
+cos,-0x1.f284b5028c184p-1,0x1.74af6725c6206p1
+cos,-0x1.f284b5028c184p-1,-0x1.74af6725c6206p1
+cos,-0x1.f3165a0b306b2p-1,0x1.7550d28ffccc4p1
+cos,-0x1.f3165a0b306b2p-1,-0x1.7550d28ffccc4p1
+cos,0x1.d66d2078ebdecp-1,0x1.775e397cd6aap6
+cos,0x1.d66d2078ebdecp-1,-0x1.775e397cd6aap6
+cos,0x1.7af9a13085f53p-1,0x1.799302bf7f29p-1
+cos,0x1.7af9a13085f53p-1,-0x1.799302bf7f29p-1
+cos,0x1.ffdd2fdac0c25p-1,0x1.799fffffffffdp-6
+cos,0x1.ffdd2fdac0c25p-1,-0x1.799fffffffffdp-6
+cos,0x1.fff744f185a73p-1,0x1.7a3692ca9449p-7
+cos,0x1.fff744f185a73p-1,-0x1.7a3692ca9449p-7
+cos,0x1.7a6b326b690fbp-1,0x1.7a66a638ac5b5p-1
+cos,0x1.7a6b326b690fbp-1,-0x1.7a66a638ac5b5p-1
+cos,0x1.671fdb64ffbeep-4,0x1.7ba65462b49ap0
+cos,0x1.671fdb64ffbeep-4,-0x1.7ba65462b49ap0
+cos,0x1.ffa55490f206ep-1,0x1.7cdf37cdf37c9p239
+cos,0x1.ffa55490f206ep-1,-0x1.7cdf37cdf37c9p239
+cos,0x1.4c5b5970a3a49p-4,0x1.7d542565f472ep0
+cos,0x1.4c5b5970a3a49p-4,-0x1.7d542565f472ep0
+cos,0x1.479a5667c63f6p-4,0x1.7da0751649058p0
+cos,0x1.479a5667c63f6p-4,-0x1.7da0751649058p0
+cos,0x1.fff717511dcb5p-1,0x1.7e0ddcda6cc0dp-7
+cos,0x1.fff717511dcb5p-1,-0x1.7e0ddcda6cc0dp-7
+cos,0x1.ffffffffff707p-1,0x1.7f6p-21
+cos,0x1.ffffffffff707p-1,-0x1.7f6p-21
+cos,-0x1.fff9e1554698p-1,0x1.7f90117d44c74p100
+cos,-0x1.fff9e1554698p-1,-0x1.7f90117d44c74p100
+cos,0x1.ffdc006bff7eap-1,0x1.7ffffffffef7ap-6
+cos,0x1.ffdc006bff7eap-1,-0x1.7ffffffffef7ap-6
+cos,0x1.ffdc006bff7e8p-1,0x1.7fffffffffa26p-6
+cos,0x1.ffdc006bff7e8p-1,-0x1.7fffffffffa26p-6
+cos,0x1.ffdc006bff7e7p-1,0x1.7ffffffffff8p-6
+cos,0x1.ffdc006bff7e7p-1,-0x1.7ffffffffff8p-6
+cos,0x1.760718ab44398p-1,0x1.80ep-1
+cos,0x1.760718ab44398p-1,-0x1.80ep-1
+cos,-0x1.0p0,0x1.81ae0dffa3b33p959
+cos,-0x1.0p0,-0x1.81ae0dffa3b33p959
+cos,-0x1.fbdc48125b345p-1,0x1.81d612289c5cfp1
+cos,-0x1.fbdc48125b345p-1,-0x1.81d612289c5cfp1
+cos,0x1.ff9e396651ccap-5,0x1.8220192270a0ep0
+cos,0x1.ff9e396651ccap-5,-0x1.8220192270a0ep0
+cos,0x1.fe2b26dddb5c9p-5,0x1.822bb780e9104p0
+cos,0x1.fe2b26dddb5c9p-5,-0x1.822bb780e9104p0
+cos,0x1.eb87cff7c9115p-5,0x1.82c119c4b8e49p0
+cos,0x1.eb87cff7c9115p-5,-0x1.82c119c4b8e49p0
+cos,0x1.eb87cff7a62b7p-5,0x1.82c119c4b9fc4p0
+cos,0x1.eb87cff7a62b7p-5,-0x1.82c119c4b9fc4p0
+cos,0x1.eb87cff795ab1p-5,0x1.82c119c4ba808p0
+cos,0x1.eb87cff795ab1p-5,-0x1.82c119c4ba808p0
+cos,0x1.de1d17ab0d6a5p-5,0x1.832c9fc76527p0
+cos,0x1.de1d17ab0d6a5p-5,-0x1.832c9fc76527p0
+cos,0x1.dc86e7bec0c45p-5,0x1.833956ce7d1f9p0
+cos,0x1.dc86e7bec0c45p-5,-0x1.833956ce7d1f9p0
+cos,0x1.db03cbb942a7bp-5,0x1.834574eb1c099p0
+cos,0x1.db03cbb942a7bp-5,-0x1.834574eb1c099p0
+cos,0x1.ce431710d1507p-5,0x1.83aba5688e13ep0
+cos,0x1.ce431710d1507p-5,-0x1.83aba5688e13ep0
+cos,0x1.cd46b3a77f6ddp-5,0x1.83b38bbafd75bp0
+cos,0x1.cd46b3a77f6ddp-5,-0x1.83b38bbafd75bp0
+cos,-0x1.ff29bc666bee7p-1,0x1.86a017cb1c31cp16
+cos,-0x1.ff29bc666bee7p-1,-0x1.86a017cb1c31cp16
+cos,-0x1.7968916e4c646p-2,0x1.8720588p392
+cos,-0x1.7968916e4c646p-2,-0x1.8720588p392
+cos,0x1.fb97c7e452918p-1,0x1.88a2288a22888p9
+cos,0x1.fb97c7e452918p-1,-0x1.88a2288a22888p9
+cos,-0x1.ae44a5f01bf63p-1,0x1.8cf013991c308p1000
+cos,-0x1.ae44a5f01bf63p-1,-0x1.8cf013991c308p1000
+cos,0x1.d96e82f71a9dcp-1,0x1.9p-2
+cos,0x1.d96e82f71a9dcp-1,-0x1.9p-2
+cos,0x1.0fd9d5c093df5p-7,0x1.9p0
+cos,0x1.0fd9d5c093df5p-7,-0x1.9p0
+cos,0x1.0fd9d5c05e5fdp-7,0x1.90000000006bp0
+cos,0x1.0fd9d5c05e5fdp-7,-0x1.90000000006bp0
+cos,0x1.bc8be725417d8p-1,0x1.900c206d44162p6
+cos,0x1.bc8be725417d8p-1,-0x1.900c206d44162p6
+cos,0x1.fffffffff63b6p-1,0x1.900c2af7baef3p-19
+cos,0x1.fffffffff63b6p-1,-0x1.900c2af7baef3p-19
+cos,0x1.bd464c9352d11p-1,0x1.900f11bd8955dp6
+cos,0x1.bd464c9352d11p-1,-0x1.900f11bd8955dp6
+cos,0x1.fffffda85cdd1p-1,0x1.910b35c3253d4p100
+cos,0x1.fffffda85cdd1p-1,-0x1.910b35c3253d4p100
+cos,0x1.1a62633145c07p-54,0x1.921fb54442d18p0
+cos,0x1.1a62633145c07p-54,-0x1.921fb54442d18p0
+cos,-0x1.2aeef4b9ea1aep-18,0x1.922p0
+cos,-0x1.2aeef4b9ea1aep-18,-0x1.922p0
+cos,-0x1.ffffffffd9048p-18,0x1.9220354442d18p0
+cos,-0x1.ffffffffd9048p-18,-0x1.9220354442d18p0
+cos,-0x1.0p0,0x1.9251f93aeb59dp12
+cos,-0x1.0p0,-0x1.9251f93aeb59dp12
+cos,0x1.ffb8c4d1f78a8p-1,0x1.943be221d909ap2
+cos,0x1.ffb8c4d1f78a8p-1,-0x1.943be221d909ap2
+cos,0x1.fff6011fdddabp-1,0x1.94af699302875p-7
+cos,0x1.fff6011fdddabp-1,-0x1.94af699302875p-7
+cos,0x1.d7954e7a3ee99p-1,0x1.999999ab7b0edp-2
+cos,0x1.d7954e7a3ee99p-1,-0x1.999999ab7b0edp-2
+cos,0x1.d7954e76c8e31p-1,0x1.999999bd4190bp-2
+cos,0x1.d7954e76c8e31p-1,-0x1.999999bd4190bp-2
+cos,0x1.fa23cfb820224p-1,0x1.9bd0f19479a24p2
+cos,0x1.fa23cfb820224p-1,-0x1.9bd0f19479a24p2
+cos,-0x1.6a09e667f3af1p-1,0x1.9c55835e7e83ep8
+cos,-0x1.6a09e667f3af1p-1,-0x1.9c55835e7e83ep8
+cos,0x1.fff59c1255809p-1,0x1.9c9942b14448dp-7
+cos,0x1.fff59c1255809p-1,-0x1.9c9942b14448dp-7
+cos,0x1.ffece5cab4ca5p-1,0x1.9d3d92485e2b5p523
+cos,0x1.ffece5cab4ca5p-1,-0x1.9d3d92485e2b5p523
+cos,-0x1.ff55301d3a781p-5,0x1.a0d068341a08p1000
+cos,-0x1.ff55301d3a781p-5,-0x1.a0d068341a08p1000
+cos,0x1.5a5615acd0dcp-1,0x1.a7ep-1
+cos,0x1.5a5615acd0dcp-1,-0x1.a7ep-1
+cos,0x1.766ad27a1de5p-14,0x1.a858343863965p119
+cos,0x1.766ad27a1de5p-14,-0x1.a858343863965p119
+cos,0x1.6bd4d5be72494p-1,0x1.ab190633d88eap3
+cos,0x1.6bd4d5be72494p-1,-0x1.ab190633d88eap3
+cos,0x1.ffffffffff4a5p-1,0x1.af4bd2f4bd2fp-21
+cos,0x1.ffffffffff4a5p-1,-0x1.af4bd2f4bd2fp-21
+cos,0x1.7ff2934ad29a8p-1,0x1.afa70300aee6p72
+cos,0x1.7ff2934ad29a8p-1,-0x1.afa70300aee6p72
+cos,0x1.ff866aebdce0ap-1,0x1.b5ab427cffb4cp94
+cos,0x1.ff866aebdce0ap-1,-0x1.b5ab427cffb4cp94
+cos,-0x1.f54f5227a4e84p-60,0x1.b951f1572eba5p23
+cos,-0x1.f54f5227a4e84p-60,-0x1.b951f1572eba5p23
+cos,0x1.fffd06d35579cp-1,0x1.b96e5b96e5b91p-8
+cos,0x1.fffd06d35579cp-1,-0x1.b96e5b96e5b91p-8
+cos,-0x1.7c4128e2aff4cp-1,0x1.ba3b18395d17bp8
+cos,-0x1.7c4128e2aff4cp-1,-0x1.ba3b18395d17bp8
+cos,-0x1.0p0,0x1.bab62ed655019p970
+cos,-0x1.0p0,-0x1.bab62ed655019p970
+cos,0x1.ffffff3e53446p-1,0x1.bd55aa411ab46p-13
+cos,0x1.ffffff3e53446p-1,-0x1.bd55aa411ab46p-13
+cos,-0x1.7fdb07b9f77ep-1,0x1.bd616d4fe95cdp36
+cos,-0x1.7fdb07b9f77ep-1,-0x1.bd616d4fe95cdp36
+cos,0x1.ffcf4da76222dp-1,0x1.beap-6
+cos,0x1.ffcf4da76222dp-1,-0x1.beap-6
+cos,-0x1.ddee13357ec6fp-1,0x1.c11516af585a4p1
+cos,-0x1.ddee13357ec6fp-1,-0x1.c11516af585a4p1
+cos,0x1.58cccec059da2p-1,0x1.c75e54de4c06ep2
+cos,0x1.58cccec059da2p-1,-0x1.c75e54de4c06ep2
+cos,-0x1.0p0,0x1.cb44e86bc192bp648
+cos,-0x1.0p0,-0x1.cb44e86bc192bp648
+cos,0x1.0p0,0x1.cb44e86bc192bp649
+cos,0x1.0p0,-0x1.cb44e86bc192bp649
+cos,-0x1.ca281d7fe44bp-1,0x1.cd5a6f8762affp1
+cos,-0x1.ca281d7fe44bp-1,-0x1.cd5a6f8762affp1
+cos,0x1.e80ad4fe54c72p-5,0x1.d0cb95f02ad77p464
+cos,0x1.e80ad4fe54c72p-5,-0x1.d0cb95f02ad77p464
+cos,0x1.0df8eb409efe4p-1,0x1.d31bd604903ap2
+cos,0x1.0df8eb409efe4p-1,-0x1.d31bd604903ap2
+cos,0x1.ff2ae968efe71p-1,0x1.d32f4610180f6p-5
+cos,0x1.ff2ae968efe71p-1,-0x1.d32f4610180f6p-5
+cos,-0x1.cec307a674d3fp-3,0x1.d96e058p488
+cos,-0x1.cec307a674d3fp-3,-0x1.d96e058p488
+cos,-0x1.ac8dbf9cdc955p-5,0x1.db0803c392b4cp15
+cos,-0x1.ac8dbf9cdc955p-5,-0x1.db0803c392b4cp15
+cos,-0x1.ac94870ca6317p-5,0x1.db0803c3ff51dp15
+cos,-0x1.ac94870ca6317p-5,-0x1.db0803c3ff51dp15
+cos,0x1.ff229073fd8b6p-1,0x1.dc4p-5
+cos,0x1.ff229073fd8b6p-1,-0x1.dc4p-5
+cos,0x1.ff21e5f976p-1,0x1.dcf73dcf73dccp-5
+cos,0x1.ff21e5f976p-1,-0x1.dcf73dcf73dccp-5
+cos,0x1.2f011326420e5p-1,0x1.dffffffffffffp-1
+cos,0x1.2f011326420e5p-1,-0x1.dffffffffffffp-1
+cos,0x1.f72c8e16dbc79p-1,0x1.e123691a7c4bep26
+cos,0x1.f72c8e16dbc79p-1,-0x1.e123691a7c4bep26
+cos,-0x1.4b0c6bb623f58p-2,0x1.e666666f9cf49p0
+cos,-0x1.4b0c6bb623f58p-2,-0x1.e666666f9cf49p0
+cos,0x1.fd74b55875885p-1,0x1.e83accfc50b7p995
+cos,0x1.fd74b55875885p-1,-0x1.e83accfc50b7p995
+cos,0x1.fff169b6ab7d1p-1,0x1.e8ep-7
+cos,0x1.fff169b6ab7d1p-1,-0x1.e8ep-7
+cos,0x1.7d39c9f1b0b3cp-1,0x1.eaf5ea5317442p4
+cos,0x1.7d39c9f1b0b3cp-1,-0x1.eaf5ea5317442p4
+cos,0x1.7f13af7081a68p-1,0x1.eb0c2b00b1b83p4
+cos,0x1.7f13af7081a68p-1,-0x1.eb0c2b00b1b83p4
+cos,-0x1.7ad7b88a1fe1p-1,0x1.ebc6b555311c4p15
+cos,-0x1.7ad7b88a1fe1p-1,-0x1.ebc6b555311c4p15
+cos,0x1.b06b2b58a2a24p-5,0x1.ef7bdef7bdef2p239
+cos,0x1.b06b2b58a2a24p-5,-0x1.ef7bdef7bdef2p239
+cos,0x1.fe6ded53172a7p-1,0x1.efbbeefbbeef8p15
+cos,0x1.fe6ded53172a7p-1,-0x1.efbbeefbbeef8p15
+cos,-0x1.fe2bcb87a7e16p-1,0x1.f07c1f07c1ef7p239
+cos,-0x1.fe2bcb87a7e16p-1,-0x1.f07c1f07c1ef7p239
+cos,-0x1.79d08d6b3a883p-1,0x1.f0f2b5e060b29p1
+cos,-0x1.79d08d6b3a883p-1,-0x1.f0f2b5e060b29p1
+cos,0x1.f0d11d321178ep-1,0x1.f4p-3
+cos,0x1.f0d11d321178ep-1,-0x1.f4p-3
+cos,0x1.e3ff5b15f723ep-4,0x1.f43d49f947e87p9
+cos,0x1.e3ff5b15f723ep-4,-0x1.f43d49f947e87p9
+cos,-0x1.6636c9f6a87aap-1,0x1.f7fffffffffffp1
+cos,-0x1.6636c9f6a87aap-1,-0x1.f7fffffffffffp1
+cos,0x1.ffc1be3309286p-1,0x1.f8fffffffffffp-6
+cos,0x1.ffc1be3309286p-1,-0x1.f8fffffffffffp-6
+cos,0x1.ffc1be3309285p-1,0x1.f9p-6
+cos,0x1.ffc1be3309285p-1,-0x1.f9p-6
+cos,-0x1.fffffffcab0d6p-1,0x1.fa0236523ce54p344
+cos,-0x1.fffffffcab0d6p-1,-0x1.fa0236523ce54p344
+cos,0x1.fc0d98ace2308p-1,0x1.fceab54d37dap-4
+cos,0x1.fc0d98ace2308p-1,-0x1.fceab54d37dap-4
+cos,-0x1.9589bca128b92p-4,0x1.fd0072fffffffp2
+cos,-0x1.9589bca128b92p-4,-0x1.fd0072fffffffp2
+cos,-0x1.4d304b07fc898p-2,0x1.fe0f827673422p62
+cos,-0x1.4d304b07fc898p-2,-0x1.fe0f827673422p62
+cos,0x1.c1a27ae836f13p-1,0x1.feb1f7920e248p-2
+cos,0x1.c1a27ae836f13p-1,-0x1.feb1f7920e248p-2
+cos,-0x1.936b64e955979p-1,0x1.feeffffffffc6p995
+cos,-0x1.936b64e955979p-1,-0x1.feeffffffffc6p995
+cos,0x1.fff007147ea57p-1,0x1.ff8ffffffffffp-7
+cos,0x1.fff007147ea57p-1,-0x1.ff8ffffffffffp-7
+cos,0x1.ffffc01bfe443p-1,0x1.ff8ffffffffffp-10
+cos,0x1.ffffc01bfe443p-1,-0x1.ff8ffffffffffp-10
+cos,0x1.7cc9fb75317aep-1,0x1.ff8ffffffffffp870
+cos,0x1.7cc9fb75317aep-1,-0x1.ff8ffffffffffp870
+cos,0x1.d6aea48015589p-1,0x1.ffcfff8p19
+cos,0x1.d6aea48015589p-1,-0x1.ffcfff8p19
+cos,-0x1.6a9972eee19bbp-2,0x1.ffcfff8p365
+cos,-0x1.6a9972eee19bbp-2,-0x1.ffcfff8p365
+cos,-0x1.3aaa15f7544b7p-1,0x1.ffcffffffff6cp720
+cos,-0x1.3aaa15f7544b7p-1,-0x1.ffcffffffff6cp720
+cos,0x1.3f164bce055c5p-1,0x1.ffcfffffffff9p320
+cos,0x1.3f164bce055c5p-1,-0x1.ffcfffffffff9p320
+cos,0x1.fffff002fff15p-1,0x1.ffcffffffffffp-11
+cos,0x1.fffff002fff15p-1,-0x1.ffcffffffffffp-11
+cos,-0x1.ffffff987f986p-1,0x1.ffcffffffffffp405
+cos,-0x1.ffffff987f986p-1,-0x1.ffcffffffffffp405
+cos,-0x1.ffff6235a25eep-1,0x1.ffcffffffffffp567
+cos,-0x1.ffff6235a25eep-1,-0x1.ffcffffffffffp567
+cos,0x1.fdf11ae4608b1p-3,0x1.ffefff8ffffffp16
+cos,0x1.fdf11ae4608b1p-3,-0x1.ffefff8ffffffp16
+cos,0x1.8f5525ab4583cp-1,0x1.ffeffffffffccp995
+cos,0x1.8f5525ab4583cp-1,-0x1.ffeffffffffccp995
+cos,0x1.a0af44a45c057p-8,0x1.ffeffffffffffp77
+cos,0x1.a0af44a45c057p-8,-0x1.ffeffffffffffp77
+cos,-0x1.df7546c31bf8dp-1,0x1.ffeffffffffffp122
+cos,-0x1.df7546c31bf8dp-1,-0x1.ffeffffffffffp122
+cos,-0x1.825a7bea27d5bp-1,0x1.ffeffffffffffp179
+cos,-0x1.825a7bea27d5bp-1,-0x1.ffeffffffffffp179
+cos,-0x1.1be2ab2078d54p-1,0x1.ffeffffffffffp238
+cos,-0x1.1be2ab2078d54p-1,-0x1.ffeffffffffffp238
+cos,-0x1.a4cc5f838f529p-7,0x1.fff0000002511p492
+cos,-0x1.a4cc5f838f529p-7,-0x1.fff0000002511p492
+cos,0x1.f16437d6119f9p-10,0x1.fff1fffffffffp41
+cos,0x1.f16437d6119f9p-10,-0x1.fff1fffffffffp41
+cos,0x1.898324c2f1cfcp-11,0x1.ffffc7fffffffp45
+cos,0x1.898324c2f1cfcp-11,-0x1.ffffc7fffffffp45
+cos,0x1.f0154c00688f8p-1,0x1.ffffdf1ffffffp-3
+cos,0x1.f0154c00688f8p-1,-0x1.ffffdf1ffffffp-3
+cos,0x1.ffc00157126a8p-1,0x1.fffff8fffffffp-6
+cos,0x1.ffc00157126a8p-1,-0x1.fffff8fffffffp-6
+cos,-0x1.e0d9f0f38c73fp-2,0x1.fffffbfffffffp968
+cos,-0x1.e0d9f0f38c73fp-2,-0x1.fffffbfffffffp968
+cos,0x1.fff4699dd560bp-1,0x1.fffffcfffffffp40
+cos,0x1.fff4699dd560bp-1,-0x1.fffffcfffffffp40
+cos,0x1.ff0015559f228p-1,0x1.ffffff000004p-5
+cos,0x1.ff0015559f228p-1,-0x1.ffffff000004p-5
+cos,-0x1.9c6951cccd39cp-2,0x1.ffffff8p119
+cos,-0x1.9c6951cccd39cp-2,-0x1.ffffff8p119
+cos,-0x1.f2c2263590035p-1,0x1.ffffff8p192
+cos,-0x1.f2c2263590035p-1,-0x1.ffffff8p192
+cos,0x1.c7884d6cfb551p-1,0x1.ffffff8p543
+cos,0x1.c7884d6cfb551p-1,-0x1.ffffff8p543
+cos,0x1.e66c79e776a1fp-2,0x1.ffffffc3fffffp500
+cos,0x1.e66c79e776a1fp-2,-0x1.ffffffc3fffffp500
+cos,0x1.c7c9a9c57c0b2p-3,0x1.ffffffe1fffffp700
+cos,0x1.c7c9a9c57c0b2p-3,-0x1.ffffffe1fffffp700
+cos,0x1.7bb28daf5f9aep-1,0x1.ffffffff0f0ffp400
+cos,0x1.7bb28daf5f9aep-1,-0x1.ffffffff0f0ffp400
+cos,0x1.fc015527d8bb3p-1,0x1.ffffffff3ffffp-4
+cos,0x1.fc015527d8bb3p-1,-0x1.ffffffff3ffffp-4
+cos,-0x1.ea5257eb66e3cp-1,0x1.ffffffff8ffffp3
+cos,-0x1.ea5257eb66e3cp-1,-0x1.ffffffff8ffffp3
+cos,-0x1.4eaa606dbef97p-1,0x1.fffffffffbcffp1
+cos,-0x1.4eaa606dbef97p-1,-0x1.fffffffffbcffp1
+cos,-0x1.fc9cd6b5f0095p-1,0x1.fffffffffe0b5p720
+cos,-0x1.fc9cd6b5f0095p-1,-0x1.fffffffffe0b5p720
+cos,0x1.e96ac045dd139p-3,0x1.fffffffffe7ffp41
+cos,0x1.e96ac045dd139p-3,-0x1.fffffffffe7ffp41
+cos,-0x1.fcaf39cfb94d5p-1,0x1.fffffffffee09p720
+cos,-0x1.fcaf39cfb94d5p-1,-0x1.fffffffffee09p720
+cos,0x1.8432232a6d1dap-1,0x1.ffffffffffdffp40
+cos,0x1.8432232a6d1dap-1,-0x1.ffffffffffdffp40
+cos,0x1.9e375143139dap-6,0x1.ffffffffffeffp41
+cos,0x1.9e375143139dap-6,-0x1.ffffffffffeffp41
+cos,0x1.fffc000155552p-1,0x1.fffffffffff4ap-8
+cos,0x1.fffc000155552p-1,-0x1.fffffffffff4ap-8
+cos,0x1.463a895c4ea5dp-1,0x1.fffffffffff78p920
+cos,0x1.463a895c4ea5dp-1,-0x1.fffffffffff78p920
+cos,0x1.3c1a48635cf38p-1,0x1.fffffffffffd5p995
+cos,0x1.3c1a48635cf38p-1,-0x1.fffffffffffd5p995
+cos,0x1.91c4e0708bd48p-1,0x1.fffffffffffe8p720
+cos,0x1.91c4e0708bd48p-1,-0x1.fffffffffffe8p720
+cos,-0x1.3e15cb849b5eap-1,0x1.fffffffffffebp920
+cos,-0x1.3e15cb849b5eap-1,-0x1.fffffffffffebp920
+cos,-0x1.816808349b80ep-1,0x1.ffffffffffff1p245
+cos,-0x1.816808349b80ep-1,-0x1.ffffffffffff1p245
+cos,0x1.4699c814c5f07p-1,0x1.ffffffffffff4p845
+cos,0x1.4699c814c5f07p-1,-0x1.ffffffffffff4p845
+cos,-0x1.815e92b7a2a01p-1,0x1.ffffffffffff4p1020
+cos,-0x1.815e92b7a2a01p-1,-0x1.ffffffffffff4p1020
+cos,-0x1.3e8d028153202p-10,0x1.ffffffffffffcp45
+cos,-0x1.3e8d028153202p-10,-0x1.ffffffffffffcp45
+cos,0x1.7d6765714c786p-1,0x1.ffffffffffffep105
+cos,0x1.7d6765714c786p-1,-0x1.ffffffffffffep105
+cos,-0x1.f869fb14d2569p-3,0x1.ffffffffffffep480
+cos,-0x1.f869fb14d2569p-3,-0x1.ffffffffffffep480
+cos,-0x1.80a75b369d3c4p-1,0x1.ffffffffffffep970
+cos,-0x1.80a75b369d3c4p-1,-0x1.ffffffffffffep970
+cos,-0x1.9dba69e853bd8p-4,0x1.0000000000001p42
+cos,-0x1.9dba69e853bd8p-4,-0x1.0000000000001p42
+cos,0x1.0p0,-0x0.0000000000001p-1022
+cos,0x1.0p0,0x0.0000000000001p-1022
+cos,0x1.0p0,-0x0.0p0
+cos,0x1.0p0,0x0.0000000000001p-1022
+cos,0x1.0p0,-0x0.0000000000001p-1022
+cos,0x1.0p0,-0x1.0000000000001p-1022
+cos,0x1.0p0,0x1.0000000000001p-1022
+cos,0x1.0p0,-0x1.0p-1022
+cos,0x1.0p0,0x1.0p-1022
+cos,0x1.0p0,-0x0.fffffffffffffp-1022
+cos,0x1.0p0,0x0.fffffffffffffp-1022
+cos,0x1.0p0,0x0.fffffffffffffp-1022
+cos,0x1.0p0,-0x0.fffffffffffffp-1022
+cos,0x1.0p0,0x1.0p-1022
+cos,0x1.0p0,-0x1.0p-1022
+cos,0x1.0p0,0x1.0000000000001p-1022
+cos,0x1.0p0,-0x1.0000000000001p-1022
+cos,0x1.ffffff5c28f5dp-1,0x1.999999999999ap-13
+cos,0x1.ffffff5c28f5dp-1,-0x1.999999999999ap-13
+cos,0x1.fffffd70a3d79p-1,0x1.999999999999ap-12
+cos,0x1.fffffd70a3d79p-1,-0x1.999999999999ap-12
+cos,0x1.fffffa3d70a6ap-1,0x1.3333333333334p-11
+cos,0x1.fffffa3d70a6ap-1,-0x1.3333333333334p-11
+cos,0x1.fffff5c28f64ep-1,0x1.999999999999ap-11
+cos,0x1.fffff5c28f64ep-1,-0x1.999999999999ap-11
+cos,0x1.fffff00000155p-1,0x1.0p-10
+cos,0x1.fffff00000155p-1,-0x1.0p-10
+cos,0x1.ffffe8f5c2bbap-1,0x1.3333333333333p-10
+cos,0x1.ffffe8f5c2bbap-1,-0x1.3333333333333p-10
+cos,0x1.ffffe0a3d75c3p-1,0x1.6666666666666p-10
+cos,0x1.ffffe0a3d75c3p-1,-0x1.6666666666666p-10
+cos,0x1.ffffd70a3dfc7p-1,0x1.9999999999999p-10
+cos,0x1.ffffd70a3dfc7p-1,-0x1.9999999999999p-10
+cos,0x1.ffffcc28f6a28p-1,0x1.cccccccccccccp-10
+cos,0x1.ffffcc28f6a28p-1,-0x1.cccccccccccccp-10
+cos,0x1.fffbcc2a6e87p-1,0x1.0666666666666p-7
+cos,0x1.fffbcc2a6e87p-1,-0x1.0666666666666p-7
+cos,0x1.fff30a4b6fcc1p-1,0x1.cccccccccccccp-7
+cos,0x1.fff30a4b6fcc1p-1,-0x1.cccccccccccccp-7
+cos,0x1.ffe57a780f38cp-1,0x1.4999999999999p-6
+cos,0x1.ffe57a780f38cp-1,-0x1.4999999999999p-6
+cos,0x1.ffd31cd0e1d63p-1,0x1.accccccccccccp-6
+cos,0x1.ffd31cd0e1d63p-1,-0x1.accccccccccccp-6
+cos,0x1.ffbbf18207543p-1,0x1.08p-5
+cos,0x1.ffbbf18207543p-1,-0x1.08p-5
+cos,0x1.ff9ff8c3299f5p-1,0x1.399999999999ap-5
+cos,0x1.ff9ff8c3299f5p-1,-0x1.399999999999ap-5
+cos,0x1.ff7f32d77c5b2p-1,0x1.6b33333333334p-5
+cos,0x1.ff7f32d77c5b2p-1,-0x1.6b33333333334p-5
+cos,0x1.ff59a00dbc409p-1,0x1.9cccccccccccep-5
+cos,0x1.ff59a00dbc409p-1,-0x1.9cccccccccccep-5
+cos,0x1.ff2f40c02e60fp-1,0x1.ce66666666666p-5
+cos,0x1.ff2f40c02e60fp-1,-0x1.ce66666666666p-5
+cos,0x1.8ca46c7d8975ep-1,0x1.5e7fc4369bdadp-1
+cos,0x1.8ca46c7d8975ep-1,-0x1.5e7fc4369bdadp-1
+cos,0x1.0b5d3802fc799p-2,0x1.4e7fc4369bdadp0
+cos,0x1.0b5d3802fc799p-2,-0x1.4e7fc4369bdadp0
+cos,-0x1.66b96f53323afp-2,0x1.edbfa651e9c84p0
+cos,-0x1.66b96f53323afp-2,-0x1.edbfa651e9c84p0
+cos,-0x1.a93554888c33p-1,0x1.467fc4369bdadp1
+cos,-0x1.a93554888c33p-1,-0x1.467fc4369bdadp1
+cos,-0x1.ffc00155527d3p-1,0x1.961fb54442d18p1
+cos,-0x1.ffc00155527d3p-1,-0x1.961fb54442d18p1
+cos,-0x1.96907c5c7c25cp-1,0x1.e5bfa651e9c83p1
+cos,-0x1.96907c5c7c25cp-1,-0x1.e5bfa651e9c83p1
+cos,-0x1.2a1e5a50f948dp-2,0x1.1aafcbafc85f7p2
+cos,-0x1.2a1e5a50f948dp-2,-0x1.1aafcbafc85f7p2
+cos,0x1.4894f695dc56cp-2,0x1.427fc4369bdadp2
+cos,0x1.4894f695dc56cp-2,-0x1.427fc4369bdadp2
+cos,0x1.a016ea3a692cep-1,0x1.6a4fbcbd6f562p2
+cos,0x1.a016ea3a692cep-1,-0x1.6a4fbcbd6f562p2
+cos,0x1.a30a69f5537ecp-1,0x1.6af2eff0a2896p2
+cos,0x1.a30a69f5537ecp-1,-0x1.6af2eff0a2896p2
+cos,0x1.5bd62e8b04ad6p-2,0x1.43c62a9d02414p2
+cos,0x1.5bd62e8b04ad6p-2,-0x1.43c62a9d02414p2
+cos,-0x1.0cb71f671e634p-2,0x1.1c99654961f92p2
+cos,-0x1.0cb71f671e634p-2,-0x1.1c99654961f92p2
+cos,-0x1.89d86aa8521c1p-1,0x1.ead93feb8361fp1
+cos,-0x1.89d86aa8521c1p-1,-0x1.ead93feb8361fp1
+cos,-0x1.fe51ac554a16bp-1,0x1.9c7fb54442d1ap1
+cos,-0x1.fe51ac554a16bp-1,-0x1.9c7fb54442d1ap1
+cos,-0x1.b97c04d08bc5dp-1,0x1.4e262a9d02415p1
+cos,-0x1.b97c04d08bc5dp-1,-0x1.4e262a9d02415p1
+cos,-0x1.a8ac8a3e58f6dp-2,0x1.ff993feb8362p0
+cos,-0x1.a8ac8a3e58f6dp-2,-0x1.ff993feb8362p0
+cos,0x1.77a8b9b3d254bp-3,0x1.62e62a9d02416p0
+cos,0x1.77a8b9b3d254bp-3,-0x1.62e62a9d02416p0
+cos,0x1.6e1061205dd79p-1,0x1.8c662a9d02419p-1
+cos,0x1.6e1061205dd79p-1,-0x1.8c662a9d02419p-1
+cos,-0x1.682f3cc3c7a09p-4,-0x1.a8aa1d11c44ffp0
+cos,-0x1.682f3cc3c7a09p-4,0x1.a8aa1d11c44ffp0
+cos,-0x1.e6669a270c36dp-7,-0x1.95ec8b9e03d54p0
+cos,-0x1.e6669a270c36dp-7,0x1.95ec8b9e03d54p0
+cos,0x1.ddd1ec25e209fp-5,-0x1.832efa2a435a9p0
+cos,0x1.ddd1ec25e209fp-5,0x1.832efa2a435a9p0
+cos,0x1.0cab9115640dap-3,-0x1.707168b682dfep0
+cos,0x1.0cab9115640dap-3,0x1.707168b682dfep0
+cos,0x1.a0723a95492eep-3,-0x1.5db3d742c2653p0
+cos,0x1.a0723a95492eep-3,0x1.5db3d742c2653p0
+cos,0x1.18fee96a1a586p-2,-0x1.4af645cf01ea8p0
+cos,0x1.18fee96a1a586p-2,0x1.4af645cf01ea8p0
+cos,0x1.6043621b13be3p-2,-0x1.3838b45b416fdp0
+cos,0x1.6043621b13be3p-2,0x1.3838b45b416fdp0
+cos,0x1.a5a4ccf40d9dap-2,-0x1.257b22e780f52p0
+cos,0x1.a5a4ccf40d9dap-2,0x1.257b22e780f52p0
+cos,0x1.e8c405f36f85cp-2,-0x1.12bd9173c07abp0
+cos,0x1.e8c405f36f85cp-2,0x1.12bd9173c07abp0
+cos,0x1.26976a6c4e0f8p-1,-0x1.ea5c3ed5b385p-1
+cos,0x1.26976a6c4e0f8p-1,0x1.ea5c3ed5b385p-1
+cos,0x1.3805a1882009fp-1,-0x1.d4b87dab670ap-1
+cos,0x1.3805a1882009fp-1,0x1.d4b87dab670ap-1
+cos,0x1.48e52e0a65bcbp-1,-0x1.bf14bc811a8fp-1
+cos,0x1.48e52e0a65bcbp-1,0x1.bf14bc811a8fp-1
+cos,0x1.592e58ea0a9efp-1,-0x1.a970fb56ce14p-1
+cos,0x1.592e58ea0a9efp-1,0x1.a970fb56ce14p-1
+cos,0x1.68d9afe052d1fp-1,-0x1.93cd3a2c8199p-1
+cos,0x1.68d9afe052d1fp-1,0x1.93cd3a2c8199p-1
+cos,0x1.77e008d0775e7p-1,-0x1.7e297902351ep-1
+cos,0x1.77e008d0775e7p-1,0x1.7e297902351ep-1
+cos,0x1.863a850e438fep-1,-0x1.6885b7d7e8a3p-1
+cos,0x1.863a850e438fep-1,0x1.6885b7d7e8a3p-1
+cos,0x1.93e2948233fcep-1,-0x1.52e1f6ad9c28p-1
+cos,0x1.93e2948233fcep-1,0x1.52e1f6ad9c28p-1
+cos,0x1.a0d1f8a9a791dp-1,-0x1.3d3e35834fadp-1
+cos,0x1.a0d1f8a9a791dp-1,0x1.3d3e35834fadp-1
+cos,0x1.bc6bd861e13dep-1,-0x1.0a0b02501c799p-1
+cos,0x1.bc6bd861e13dep-1,0x1.0a0b02501c799p-1
+cos,0x1.ca59c6fa3d9cep-1,-0x1.d8f7208e6b82cp-2
+cos,0x1.ca59c6fa3d9cep-1,0x1.d8f7208e6b82cp-2
+cos,0x1.d6c0b125791dp-1,-0x1.9dd83c7c9e126p-2
+cos,0x1.d6c0b125791dp-1,0x1.9dd83c7c9e126p-2
+cos,0x1.e196026182986p-1,-0x1.62b9586ad0a2p-2
+cos,0x1.e196026182986p-1,0x1.62b9586ad0a2p-2
+cos,0x1.ead07cc635696p-1,-0x1.279a74590331ap-2
+cos,0x1.ead07cc635696p-1,0x1.279a74590331ap-2
+cos,0x1.f26840e7b2189p-1,-0x1.d8f7208e6b829p-3
+cos,0x1.f26840e7b2189p-1,0x1.d8f7208e6b829p-3
+cos,0x1.f856d48db797ep-1,-0x1.62b9586ad0a1ep-3
+cos,0x1.f856d48db797ep-1,0x1.62b9586ad0a1ep-3
+cos,0x1.fc97283a42479p-1,-0x1.d8f7208e6b826p-4
+cos,0x1.fc97283a42479p-1,0x1.d8f7208e6b826p-4
+cos,0x1.ff259b7ab9f5p-1,-0x1.d8f7208e6b82dp-5
+cos,0x1.ff259b7ab9f5p-1,0x1.d8f7208e6b82dp-5
+cos,0x1.ff259b7ab9f5p-1,0x1.d8f7208e6b82dp-5
+cos,0x1.ff259b7ab9f5p-1,-0x1.d8f7208e6b82dp-5
+cos,0x1.fc97283a42479p-1,0x1.d8f7208e6b82dp-4
+cos,0x1.fc97283a42479p-1,-0x1.d8f7208e6b82dp-4
+cos,0x1.f856d48db797ep-1,0x1.62b9586ad0a22p-3
+cos,0x1.f856d48db797ep-1,-0x1.62b9586ad0a22p-3
+cos,0x1.f26840e7b2189p-1,0x1.d8f7208e6b82dp-3
+cos,0x1.f26840e7b2189p-1,-0x1.d8f7208e6b82dp-3
+cos,0x1.ead07cc635696p-1,0x1.279a74590331cp-2
+cos,0x1.ead07cc635696p-1,-0x1.279a74590331cp-2
+cos,0x1.e196026182985p-1,0x1.62b9586ad0a22p-2
+cos,0x1.e196026182985p-1,-0x1.62b9586ad0a22p-2
+cos,0x1.d6c0b125791dp-1,0x1.9dd83c7c9e128p-2
+cos,0x1.d6c0b125791dp-1,-0x1.9dd83c7c9e128p-2
+cos,0x1.ca59c6fa3d9cep-1,0x1.d8f7208e6b82ep-2
+cos,0x1.ca59c6fa3d9cep-1,-0x1.d8f7208e6b82ep-2
+cos,0x1.bc6bd861e13dep-1,0x1.0a0b02501c799p-1
+cos,0x1.bc6bd861e13dep-1,-0x1.0a0b02501c799p-1
+cos,0x1.a0d1f8a9a792p-1,0x1.3d3e35834faccp-1
+cos,0x1.a0d1f8a9a792p-1,-0x1.3d3e35834faccp-1
+cos,0x1.93e2948233fd1p-1,0x1.52e1f6ad9c27cp-1
+cos,0x1.93e2948233fd1p-1,-0x1.52e1f6ad9c27cp-1
+cos,0x1.863a850e439p-1,0x1.6885b7d7e8a2cp-1
+cos,0x1.863a850e439p-1,-0x1.6885b7d7e8a2cp-1
+cos,0x1.77e008d0775eap-1,0x1.7e297902351dcp-1
+cos,0x1.77e008d0775eap-1,-0x1.7e297902351dcp-1
+cos,0x1.68d9afe052d22p-1,0x1.93cd3a2c8198cp-1
+cos,0x1.68d9afe052d22p-1,-0x1.93cd3a2c8198cp-1
+cos,0x1.592e58ea0a9f2p-1,0x1.a970fb56ce13cp-1
+cos,0x1.592e58ea0a9f2p-1,-0x1.a970fb56ce13cp-1
+cos,0x1.48e52e0a65bcep-1,0x1.bf14bc811a8ecp-1
+cos,0x1.48e52e0a65bcep-1,-0x1.bf14bc811a8ecp-1
+cos,0x1.3805a188200a2p-1,0x1.d4b87dab6709cp-1
+cos,0x1.3805a188200a2p-1,-0x1.d4b87dab6709cp-1
+cos,0x1.26976a6c4e0fcp-1,0x1.ea5c3ed5b384cp-1
+cos,0x1.26976a6c4e0fcp-1,-0x1.ea5c3ed5b384cp-1
+cos,0x1.e8c405f36f85cp-2,0x1.12bd9173c07abp0
+cos,0x1.e8c405f36f85cp-2,-0x1.12bd9173c07abp0
+cos,0x1.a5a4ccf40d9cbp-2,0x1.257b22e780f56p0
+cos,0x1.a5a4ccf40d9cbp-2,-0x1.257b22e780f56p0
+cos,0x1.6043621b13bd4p-2,0x1.3838b45b41701p0
+cos,0x1.6043621b13bd4p-2,-0x1.3838b45b41701p0
+cos,0x1.18fee96a1a576p-2,0x1.4af645cf01eacp0
+cos,0x1.18fee96a1a576p-2,-0x1.4af645cf01eacp0
+cos,0x1.a0723a95492cfp-3,0x1.5db3d742c2657p0
+cos,0x1.a0723a95492cfp-3,-0x1.5db3d742c2657p0
+cos,0x1.0cab9115640bap-3,0x1.707168b682e02p0
+cos,0x1.0cab9115640bap-3,-0x1.707168b682e02p0
+cos,0x1.ddd1ec25e201fp-5,0x1.832efa2a435adp0
+cos,0x1.ddd1ec25e201fp-5,-0x1.832efa2a435adp0
+cos,-0x1.e6669a270c56dp-7,0x1.95ec8b9e03d58p0
+cos,-0x1.e6669a270c56dp-7,-0x1.95ec8b9e03d58p0
+cos,-0x1.682f3cc3c7a09p-4,0x1.a8aa1d11c44ffp0
+cos,-0x1.682f3cc3c7a09p-4,-0x1.a8aa1d11c44ffp0
+cos,0x1.0cb3469a29ea6p-1,0x1.04aff6d330942p0
+cos,0x1.0cb3469a29ea6p-1,-0x1.04aff6d330942p0
+cos,0x1.0cb228fa7f811p-1,0x1.04b09e98dcdb4p0
+cos,0x1.0cb228fa7f811p-1,-0x1.04b09e98dcdb4p0
+cos,0x1.0cb10b5a61b06p-1,0x1.04b1465e89226p0
+cos,0x1.0cb10b5a61b06p-1,-0x1.04b1465e89226p0
+cos,0x1.0cafedb9d078bp-1,0x1.04b1ee2435698p0
+cos,0x1.0cafedb9d078bp-1,-0x1.04b1ee2435698p0
+cos,0x1.0caed018cbda8p-1,0x1.04b295e9e1b0ap0
+cos,0x1.0caed018cbda8p-1,-0x1.04b295e9e1b0ap0
+cos,0x1.0cadb27753d65p-1,0x1.04b33daf8df7cp0
+cos,0x1.0cadb27753d65p-1,-0x1.04b33daf8df7cp0
+cos,0x1.0cac94d5686cbp-1,0x1.04b3e5753a3eep0
+cos,0x1.0cac94d5686cbp-1,-0x1.04b3e5753a3eep0
+cos,0x1.0cab7733099dfp-1,0x1.04b48d3ae686p0
+cos,0x1.0cab7733099dfp-1,-0x1.04b48d3ae686p0
+cos,0x1.0caa5990376bp-1,0x1.04b5350092ccfp0
+cos,0x1.0caa5990376bp-1,-0x1.04b5350092ccfp0
+cos,0x1.0p0,-0x0.0000000000001p-1022
+cos,0x1.0p0,0x0.0000000000001p-1022
+cos,0x1.0p0,-0x0.0p0
+cos,0x1.0p0,0x0.0000000000001p-1022
+cos,0x1.0p0,-0x0.0000000000001p-1022
+cos,0x1.ad02c771c35edp-1,0x1.279a74590331bp-1
+cos,0x1.ad02c771c35edp-1,-0x1.279a74590331bp-1
+cos,0x1.ad02c771c35edp-1,0x1.279a74590331cp-1
+cos,0x1.ad02c771c35edp-1,-0x1.279a74590331cp-1
+cos,0x1.ad02c771c35ecp-1,0x1.279a74590331dp-1
+cos,0x1.ad02c771c35ecp-1,-0x1.279a74590331dp-1
+cos,-0x1.48d1ddd2b2b4p-3,0x1.bb67ae8584ca9p0
+cos,-0x1.48d1ddd2b2b4p-3,-0x1.bb67ae8584ca9p0
+cos,-0x1.48d1ddd2b2b47p-3,0x1.bb67ae8584caap0
+cos,-0x1.48d1ddd2b2b47p-3,-0x1.bb67ae8584caap0
+cos,-0x1.48d1ddd2b2b4fp-3,0x1.bb67ae8584cabp0
+cos,-0x1.48d1ddd2b2b4fp-3,-0x1.bb67ae8584cabp0
+cos,0x1.cfc6cfa52adap-1,0x1.bffffffffffffp-2
+cos,0x1.cfc6cfa52adap-1,-0x1.bffffffffffffp-2
+cos,0x1.cfc6cfa52ad9fp-1,0x1.cp-2
+cos,0x1.cfc6cfa52ad9fp-1,-0x1.cp-2
+cos,0x1.cfc6cfa52ad9fp-1,0x1.c000000000001p-2
+cos,0x1.cfc6cfa52ad9fp-1,-0x1.c000000000001p-2
+cos,0x1.8bb105a5dc901p-1,0x1.5ffffffffffffp-1
+cos,0x1.8bb105a5dc901p-1,-0x1.5ffffffffffffp-1
+cos,0x1.8bb105a5dc9p-1,0x1.6p-1
+cos,0x1.8bb105a5dc9p-1,-0x1.6p-1
+cos,0x1.8bb105a5dc9p-1,0x1.6000000000001p-1
+cos,0x1.8bb105a5dc9p-1,-0x1.6000000000001p-1
+cos,0x1.7ef4842f0bcd1p-2,0x1.2ffffffffffffp0
+cos,0x1.7ef4842f0bcd1p-2,-0x1.2ffffffffffffp0
+cos,0x1.7ef4842f0bccdp-2,0x1.3p0
+cos,0x1.7ef4842f0bccdp-2,-0x1.3p0
+cos,0x1.7ef4842f0bccap-2,0x1.3000000000001p0
+cos,0x1.7ef4842f0bccap-2,-0x1.3000000000001p0
+cos,-0x1.863efa361dc22p-1,0x1.37fffffffffffp1
+cos,-0x1.863efa361dc22p-1,-0x1.37fffffffffffp1
+cos,-0x1.863efa361dc25p-1,0x1.38p1
+cos,-0x1.863efa361dc25p-1,-0x1.38p1
+cos,-0x1.863efa361dc28p-1,0x1.3800000000001p1
+cos,-0x1.863efa361dc28p-1,-0x1.3800000000001p1
+cos,0x1.fef2b2d21cf6cp-1,0x1.069c8b46b3792p-4
+cos,0x1.fef2b2d21cf6cp-1,-0x1.069c8b46b3792p-4
+cos,0x1.fbcbe693bd8edp-1,0x1.069c8b46b3792p-3
+cos,0x1.fbcbe693bd8edp-1,-0x1.069c8b46b3792p-3
+cos,0x1.f68eebfcbb5e8p-1,0x1.89ead0ea0d35bp-3
+cos,0x1.f68eebfcbb5e8p-1,-0x1.89ead0ea0d35bp-3
+cos,0x1.ef4145b4aedp-1,0x1.069c8b46b3792p-2
+cos,0x1.ef4145b4aedp-1,-0x1.069c8b46b3792p-2
+cos,0x1.e5eaa286fbbc6p-1,0x1.4843ae1860576p-2
+cos,0x1.e5eaa286fbbc6p-1,-0x1.4843ae1860576p-2
+cos,0x1.da94d54dd4c08p-1,0x1.89ead0ea0d35ap-2
+cos,0x1.da94d54dd4c08p-1,-0x1.89ead0ea0d35ap-2
+cos,0x1.cd4bca9cb5c71p-1,0x1.cb91f3bbba13ep-2
+cos,0x1.cd4bca9cb5c71p-1,-0x1.cb91f3bbba13ep-2
+cos,0x1.be1d7c3534c4p-1,0x1.069c8b46b3791p-1
+cos,0x1.be1d7c3534c4p-1,-0x1.069c8b46b3791p-1
+cos,0x1.ad19e2535aa96p-1,0x1.27701caf89e83p-1
+cos,0x1.ad19e2535aa96p-1,-0x1.27701caf89e83p-1
+cos,0x1.9a52e2e0fbcb4p-1,0x1.4843ae1860575p-1
+cos,0x1.9a52e2e0fbcb4p-1,-0x1.4843ae1860575p-1
+cos,0x1.85dc3ea1bbceap-1,0x1.69173f8136c67p-1
+cos,0x1.85dc3ea1bbceap-1,-0x1.69173f8136c67p-1
+cos,0x1.6fcb7c6b8b91ap-1,0x1.89ead0ea0d359p-1
+cos,0x1.6fcb7c6b8b91ap-1,-0x1.89ead0ea0d359p-1
+cos,0x1.5837d2817cf3p-1,0x1.aabe6252e3a4bp-1
+cos,0x1.5837d2817cf3p-1,-0x1.aabe6252e3a4bp-1
+cos,0x1.3f3a0e28bedd4p-1,0x1.cb91f3bbba13dp-1
+cos,0x1.3f3a0e28bedd4p-1,-0x1.cb91f3bbba13dp-1
+cos,0x1.24ec799171643p-1,0x1.ec6585249082fp-1
+cos,0x1.24ec799171643p-1,-0x1.ec6585249082fp-1
+cos,0x1.096ac02ec42c8p-1,0x1.069c8b46b3791p0
+cos,0x1.096ac02ec42c8p-1,-0x1.069c8b46b3791p0
+cos,0x1.d9a3a336edb76p-2,0x1.170653fb1eb0ap0
+cos,0x1.d9a3a336edb76p-2,-0x1.170653fb1eb0ap0
+cos,0x1.9e7f8652b4758p-2,0x1.27701caf89e83p0
+cos,0x1.9e7f8652b4758p-2,-0x1.27701caf89e83p0
+cos,0x1.61a76077aee08p-2,0x1.37d9e563f51fcp0
+cos,0x1.61a76077aee08p-2,-0x1.37d9e563f51fcp0
+cos,0x1.235b331d8f749p-2,0x1.4843ae1860575p0
+cos,0x1.235b331d8f749p-2,-0x1.4843ae1860575p0
+cos,0x1.c7b90e3024594p-3,0x1.58ad76cccb8eep0
+cos,0x1.c7b90e3024594p-3,-0x1.58ad76cccb8eep0
+cos,0x1.46dc4f4ce83dap-3,0x1.69173f8136c67p0
+cos,0x1.46dc4f4ce83dap-3,-0x1.69173f8136c67p0
+cos,0x1.894f70befbb9ap-4,0x1.79810835a1fep0
+cos,0x1.894f70befbb9ap-4,-0x1.79810835a1fep0
+cos,0x1.069107ae9333p-5,0x1.89ead0ea0d359p0
+cos,0x1.069107ae9333p-5,-0x1.89ead0ea0d359p0
+cos,-0x1.069107ae9327ep-5,0x1.9a54999e786d2p0
+cos,-0x1.069107ae9327ep-5,-0x1.9a54999e786d2p0
+cos,-0x1.894f70befbb41p-4,0x1.aabe6252e3a4bp0
+cos,-0x1.894f70befbb41p-4,-0x1.aabe6252e3a4bp0
+cos,-0x1.46dc4f4ce83afp-3,0x1.bb282b074edc4p0
+cos,-0x1.46dc4f4ce83afp-3,-0x1.bb282b074edc4p0
+cos,-0x1.c7b90e3024569p-3,0x1.cb91f3bbba13dp0
+cos,-0x1.c7b90e3024569p-3,-0x1.cb91f3bbba13dp0
+cos,-0x1.235b331d8f734p-2,0x1.dbfbbc70254b6p0
+cos,-0x1.235b331d8f734p-2,-0x1.dbfbbc70254b6p0
+cos,-0x1.61a76077aedf3p-2,0x1.ec6585249082fp0
+cos,-0x1.61a76077aedf3p-2,-0x1.ec6585249082fp0
+cos,-0x1.9e7f8652b4744p-2,0x1.fccf4dd8fbba8p0
+cos,-0x1.9e7f8652b4744p-2,-0x1.fccf4dd8fbba8p0
+cos,-0x1.d9a3a336edb66p-2,0x1.069c8b46b3791p1
+cos,-0x1.d9a3a336edb66p-2,-0x1.069c8b46b3791p1
+cos,-0x1.096ac02ec42c2p-1,0x1.0ed16fa0e914ep1
+cos,-0x1.096ac02ec42c2p-1,-0x1.0ed16fa0e914ep1
+cos,-0x1.24ec79917163ep-1,0x1.170653fb1eb0bp1
+cos,-0x1.24ec79917163ep-1,-0x1.170653fb1eb0bp1
+cos,-0x1.3f3a0e28bedd1p-1,0x1.1f3b3855544c8p1
+cos,-0x1.3f3a0e28bedd1p-1,-0x1.1f3b3855544c8p1
+cos,-0x1.5837d2817cf2fp-1,0x1.27701caf89e85p1
+cos,-0x1.5837d2817cf2fp-1,-0x1.27701caf89e85p1
+cos,-0x1.6fcb7c6b8b91ap-1,0x1.2fa50109bf842p1
+cos,-0x1.6fcb7c6b8b91ap-1,-0x1.2fa50109bf842p1
+cos,-0x1.85dc3ea1bbcebp-1,0x1.37d9e563f51ffp1
+cos,-0x1.85dc3ea1bbcebp-1,-0x1.37d9e563f51ffp1
+cos,-0x1.9a52e2e0fbcb6p-1,0x1.400ec9be2abbcp1
+cos,-0x1.9a52e2e0fbcb6p-1,-0x1.400ec9be2abbcp1
+cos,-0x1.ad19e2535aa9ap-1,0x1.4843ae1860579p1
+cos,-0x1.ad19e2535aa9ap-1,-0x1.4843ae1860579p1
+cos,-0x1.be1d7c3534c44p-1,0x1.5078927295f36p1
+cos,-0x1.be1d7c3534c44p-1,-0x1.5078927295f36p1
+cos,-0x1.cd4bca9cb5c76p-1,0x1.58ad76cccb8f3p1
+cos,-0x1.cd4bca9cb5c76p-1,-0x1.58ad76cccb8f3p1
+cos,-0x1.da94d54dd4c0dp-1,0x1.60e25b27012bp1
+cos,-0x1.da94d54dd4c0dp-1,-0x1.60e25b27012bp1
+cos,-0x1.e5eaa286fbbcbp-1,0x1.69173f8136c6dp1
+cos,-0x1.e5eaa286fbbcbp-1,-0x1.69173f8136c6dp1
+cos,-0x1.ef4145b4aed04p-1,0x1.714c23db6c62ap1
+cos,-0x1.ef4145b4aed04p-1,-0x1.714c23db6c62ap1
+cos,-0x1.f68eebfcbb5ecp-1,0x1.79810835a1fe7p1
+cos,-0x1.f68eebfcbb5ecp-1,-0x1.79810835a1fe7p1
+cos,-0x1.fbcbe693bd8efp-1,0x1.81b5ec8fd79a4p1
+cos,-0x1.fbcbe693bd8efp-1,-0x1.81b5ec8fd79a4p1
+cos,-0x1.fef2b2d21cf6cp-1,0x1.89ead0ea0d35bp1
+cos,-0x1.fef2b2d21cf6cp-1,-0x1.89ead0ea0d35bp1
+cos,0x1.ef4145b4aecffp-1,-0x1.81b5ec8fd799fp2
+cos,0x1.ef4145b4aecffp-1,0x1.81b5ec8fd799fp2
+cos,0x1.be1d7c3534c4p-1,-0x1.714c23db6c626p2
+cos,0x1.be1d7c3534c4p-1,0x1.714c23db6c626p2
+cos,0x1.6fcb7c6b8b919p-1,-0x1.60e25b27012adp2
+cos,0x1.6fcb7c6b8b919p-1,0x1.60e25b27012adp2
+cos,0x1.096ac02ec42c8p-1,-0x1.5078927295f34p2
+cos,0x1.096ac02ec42c8p-1,0x1.5078927295f34p2
+cos,0x1.235b331d8f748p-2,-0x1.400ec9be2abbbp2
+cos,0x1.235b331d8f748p-2,0x1.400ec9be2abbbp2
+cos,0x1.069107ae9332cp-5,-0x1.2fa50109bf842p2
+cos,0x1.069107ae9332cp-5,0x1.2fa50109bf842p2
+cos,-0x1.c7b90e3024569p-3,-0x1.1f3b3855544c9p2
+cos,-0x1.c7b90e3024569p-3,0x1.1f3b3855544c9p2
+cos,-0x1.d9a3a336edb63p-2,-0x1.0ed16fa0e915p2
+cos,-0x1.d9a3a336edb63p-2,0x1.0ed16fa0e915p2
+cos,-0x1.5837d2817cf28p-1,-0x1.fccf4dd8fbbaep1
+cos,-0x1.5837d2817cf28p-1,0x1.fccf4dd8fbbaep1
+cos,-0x1.ad19e2535aa9p-1,-0x1.dbfbbc70254bcp1
+cos,-0x1.ad19e2535aa9p-1,0x1.dbfbbc70254bcp1
+cos,-0x1.e5eaa286fbbc3p-1,-0x1.bb282b074edcap1
+cos,-0x1.e5eaa286fbbc3p-1,0x1.bb282b074edcap1
+cos,-0x1.fef2b2d21cf6bp-1,-0x1.9a54999e786d8p1
+cos,-0x1.fef2b2d21cf6bp-1,0x1.9a54999e786d8p1
+cos,-0x1.f68eebfcbb5ebp-1,-0x1.79810835a1fe6p1
+cos,-0x1.f68eebfcbb5ebp-1,0x1.79810835a1fe6p1
+cos,-0x1.cd4bca9cb5c77p-1,-0x1.58ad76cccb8f4p1
+cos,-0x1.cd4bca9cb5c77p-1,0x1.58ad76cccb8f4p1
+cos,-0x1.85dc3ea1bbcf3p-1,-0x1.37d9e563f5202p1
+cos,-0x1.85dc3ea1bbcf3p-1,0x1.37d9e563f5202p1
+cos,-0x1.24ec79917164ep-1,-0x1.170653fb1eb1p1
+cos,-0x1.24ec79917164ep-1,0x1.170653fb1eb1p1
+cos,-0x1.61a76077aee24p-2,-0x1.ec6585249083cp0
+cos,-0x1.61a76077aee24p-2,0x1.ec6585249083cp0
+cos,-0x1.894f70befbc1p-4,-0x1.aabe6252e3a58p0
+cos,-0x1.894f70befbc1p-4,0x1.aabe6252e3a58p0
+cos,0x1.46dc4f4ce8374p-3,-0x1.69173f8136c74p0
+cos,0x1.46dc4f4ce8374p-3,0x1.69173f8136c74p0
+cos,0x1.9e7f8652b4729p-2,-0x1.27701caf89e9p0
+cos,0x1.9e7f8652b4729p-2,0x1.27701caf89e9p0
+cos,0x1.3f3a0e28bedcp-1,-0x1.cb91f3bbba157p-1
+cos,0x1.3f3a0e28bedcp-1,0x1.cb91f3bbba157p-1
+cos,0x1.9a52e2e0fbca5p-1,-0x1.4843ae186058ep-1
+cos,0x1.9a52e2e0fbca5p-1,0x1.4843ae186058ep-1
+cos,0x1.da94d54dd4bffp-1,-0x1.89ead0ea0d38ap-2
+cos,0x1.da94d54dd4bffp-1,0x1.89ead0ea0d38ap-2
+cos,0x1.fbcbe693bd8eap-1,-0x1.069c8b46b37fp-3
+cos,0x1.fbcbe693bd8eap-1,0x1.069c8b46b37fp-3
+cos,0x1.fbcbe693bd8fp-1,0x1.069c8b46b3734p-3
+cos,0x1.fbcbe693bd8fp-1,-0x1.069c8b46b3734p-3
+cos,0x1.da94d54dd4c11p-1,0x1.89ead0ea0d32cp-2
+cos,0x1.da94d54dd4c11p-1,-0x1.89ead0ea0d32cp-2
+cos,0x1.9a52e2e0fbcc1p-1,0x1.4843ae186055fp-1
+cos,0x1.9a52e2e0fbcc1p-1,-0x1.4843ae186055fp-1
+cos,0x1.3f3a0e28bede4p-1,0x1.cb91f3bbba128p-1
+cos,0x1.3f3a0e28bede4p-1,-0x1.cb91f3bbba128p-1
+cos,0x1.9e7f8652b478p-2,0x1.27701caf89e78p0
+cos,0x1.9e7f8652b478p-2,-0x1.27701caf89e78p0
+cos,0x1.46dc4f4ce8431p-3,0x1.69173f8136c5cp0
+cos,0x1.46dc4f4ce8431p-3,-0x1.69173f8136c5cp0
+cos,-0x1.894f70befba92p-4,0x1.aabe6252e3a4p0
+cos,-0x1.894f70befba92p-4,-0x1.aabe6252e3a4p0
+cos,-0x1.61a76077aedcap-2,0x1.ec65852490824p0
+cos,-0x1.61a76077aedcap-2,-0x1.ec65852490824p0
+cos,-0x1.24ec799171627p-1,0x1.170653fb1eb04p1
+cos,-0x1.24ec799171627p-1,-0x1.170653fb1eb04p1
+cos,-0x1.85dc3ea1bbcd3p-1,0x1.37d9e563f51f6p1
+cos,-0x1.85dc3ea1bbcd3p-1,-0x1.37d9e563f51f6p1
+cos,-0x1.cd4bca9cb5c63p-1,0x1.58ad76cccb8e8p1
+cos,-0x1.cd4bca9cb5c63p-1,-0x1.58ad76cccb8e8p1
+cos,-0x1.f68eebfcbb5e2p-1,0x1.79810835a1fdap1
+cos,-0x1.f68eebfcbb5e2p-1,-0x1.79810835a1fdap1
+cos,-0x1.fef2b2d21cf6ep-1,0x1.9a54999e786ccp1
+cos,-0x1.fef2b2d21cf6ep-1,-0x1.9a54999e786ccp1
+cos,-0x1.e5eaa286fbbd2p-1,0x1.bb282b074edbep1
+cos,-0x1.e5eaa286fbbd2p-1,-0x1.bb282b074edbep1
+cos,-0x1.ad19e2535aaaap-1,0x1.dbfbbc70254bp1
+cos,-0x1.ad19e2535aaaap-1,-0x1.dbfbbc70254bp1
+cos,-0x1.5837d2817cf4bp-1,0x1.fccf4dd8fbba2p1
+cos,-0x1.5837d2817cf4bp-1,-0x1.fccf4dd8fbba2p1
+cos,-0x1.d9a3a336edbb8p-2,0x1.0ed16fa0e914ap2
+cos,-0x1.d9a3a336edbb8p-2,-0x1.0ed16fa0e914ap2
+cos,-0x1.c7b90e3024625p-3,0x1.1f3b3855544c3p2
+cos,-0x1.c7b90e3024625p-3,-0x1.1f3b3855544c3p2
+cos,0x1.069107ae9302dp-5,0x1.2fa50109bf83cp2
+cos,0x1.069107ae9302dp-5,-0x1.2fa50109bf83cp2
+cos,0x1.235b331d8f6ecp-2,0x1.400ec9be2abb5p2
+cos,0x1.235b331d8f6ecp-2,-0x1.400ec9be2abb5p2
+cos,0x1.096ac02ec429fp-1,0x1.5078927295f2ep2
+cos,0x1.096ac02ec429fp-1,-0x1.5078927295f2ep2
+cos,0x1.6fcb7c6b8b8f7p-1,0x1.60e25b27012a7p2
+cos,0x1.6fcb7c6b8b8f7p-1,-0x1.60e25b27012a7p2
+cos,0x1.be1d7c3534c28p-1,0x1.714c23db6c62p2
+cos,0x1.be1d7c3534c28p-1,-0x1.714c23db6c62p2
+cos,0x1.ef4145b4aecf3p-1,0x1.81b5ec8fd7999p2
+cos,0x1.ef4145b4aecf3p-1,-0x1.81b5ec8fd7999p2
+cos,0x1.ff0fd2c96adfcp-1,0x1.effffffffffffp-5
+cos,0x1.ff0fd2c96adfcp-1,-0x1.effffffffffffp-5
+cos,0x1.ff0fd2c96adfcp-1,0x1.fp-5
+cos,0x1.ff0fd2c96adfcp-1,-0x1.fp-5
+cos,0x1.ff0fd2c96adfcp-1,0x1.f000000000001p-5
+cos,0x1.ff0fd2c96adfcp-1,-0x1.f000000000001p-5
+cos,0x1.fc210055467fep-1,0x1.f7fffffffffffp-4
+cos,0x1.fc210055467fep-1,-0x1.f7fffffffffffp-4
+cos,0x1.fc210055467fep-1,0x1.f8p-4
+cos,0x1.fc210055467fep-1,-0x1.f8p-4
+cos,0x1.fc210055467fep-1,0x1.f800000000001p-4
+cos,0x1.fc210055467fep-1,-0x1.f800000000001p-4
+cos,0x1.f94984b2552e2p-1,0x1.4bfffffffffffp-3
+cos,0x1.f94984b2552e2p-1,-0x1.4bfffffffffffp-3
+cos,0x1.f94984b2552e2p-1,0x1.4cp-3
+cos,0x1.f94984b2552e2p-1,-0x1.4cp-3
+cos,0x1.f94984b2552e2p-1,0x1.4c00000000001p-3
+cos,0x1.f94984b2552e2p-1,-0x1.4c00000000001p-3
+cos,0x1.e921dd42f09bbp-1,0x1.3333333333332p-2
+cos,0x1.e921dd42f09bbp-1,-0x1.3333333333332p-2
+cos,0x1.e921dd42f09bap-1,0x1.3333333333333p-2
+cos,0x1.e921dd42f09bap-1,-0x1.3333333333333p-2
+cos,0x1.e921dd42f09bap-1,0x1.3333333333334p-2
+cos,0x1.e921dd42f09bap-1,-0x1.3333333333334p-2
+cos,0x1.8feedb86bf0efp-1,0x1.594317acc4ef8p-1
+cos,0x1.8feedb86bf0efp-1,-0x1.594317acc4ef8p-1
+cos,0x1.8feedb86bf0efp-1,0x1.594317acc4ef9p-1
+cos,0x1.8feedb86bf0efp-1,-0x1.594317acc4ef9p-1
+cos,0x1.8feedb86bf0eep-1,0x1.594317acc4efap-1
+cos,0x1.8feedb86bf0eep-1,-0x1.594317acc4efap-1
+cos,0x1.6b898fa9efb5ep-1,0x1.8ffffffffffffp-1
+cos,0x1.6b898fa9efb5ep-1,-0x1.8ffffffffffffp-1
+cos,0x1.6b898fa9efb5dp-1,0x1.9p-1
+cos,0x1.6b898fa9efb5dp-1,-0x1.9p-1
+cos,0x1.6b898fa9efb5cp-1,0x1.9000000000001p-1
+cos,0x1.6b898fa9efb5cp-1,-0x1.9000000000001p-1
+cos,0x1.0p0,-0x0.0000000000001p-1022
+cos,0x1.0p0,0x0.0000000000001p-1022
+cos,0x1.0p0,-0x0.0p0
+cos,0x1.0p0,0x0.0000000000001p-1022
+cos,0x1.0p0,-0x0.0000000000001p-1022
+cos,0x1.ff621e3796d7ep-1,0x1.921fb54442d17p-5
+cos,0x1.ff621e3796d7ep-1,-0x1.921fb54442d17p-5
+cos,0x1.ff621e3796d7ep-1,0x1.921fb54442d18p-5
+cos,0x1.ff621e3796d7ep-1,-0x1.921fb54442d18p-5
+cos,0x1.ff621e3796d7ep-1,0x1.921fb54442d19p-5
+cos,0x1.ff621e3796d7ep-1,-0x1.921fb54442d19p-5
+cos,0x1.fd88da3d12526p-1,0x1.921fb54442d17p-4
+cos,0x1.fd88da3d12526p-1,-0x1.921fb54442d17p-4
+cos,0x1.fd88da3d12526p-1,0x1.921fb54442d18p-4
+cos,0x1.fd88da3d12526p-1,-0x1.921fb54442d18p-4
+cos,0x1.fd88da3d12526p-1,0x1.921fb54442d19p-4
+cos,0x1.fd88da3d12526p-1,-0x1.921fb54442d19p-4
+cos,0x1.f6297cff75cbp-1,0x1.921fb54442d17p-3
+cos,0x1.f6297cff75cbp-1,-0x1.921fb54442d17p-3
+cos,0x1.f6297cff75cbp-1,0x1.921fb54442d18p-3
+cos,0x1.f6297cff75cbp-1,-0x1.921fb54442d18p-3
+cos,0x1.f6297cff75cbp-1,0x1.921fb54442d19p-3
+cos,0x1.f6297cff75cbp-1,-0x1.921fb54442d19p-3
+cos,0x1.d906bcf328d46p-1,0x1.921fb54442d17p-2
+cos,0x1.d906bcf328d46p-1,-0x1.921fb54442d17p-2
+cos,0x1.d906bcf328d46p-1,0x1.921fb54442d18p-2
+cos,0x1.d906bcf328d46p-1,-0x1.921fb54442d18p-2
+cos,0x1.d906bcf328d46p-1,0x1.921fb54442d19p-2
+cos,0x1.d906bcf328d46p-1,-0x1.921fb54442d19p-2
+cos,0x1.6a09e667f3bcep-1,0x1.921fb54442d17p-1
+cos,0x1.6a09e667f3bcep-1,-0x1.921fb54442d17p-1
+cos,0x1.6a09e667f3bcdp-1,0x1.921fb54442d18p-1
+cos,0x1.6a09e667f3bcdp-1,-0x1.921fb54442d18p-1
+cos,0x1.6a09e667f3bccp-1,0x1.921fb54442d19p-1
+cos,0x1.6a09e667f3bccp-1,-0x1.921fb54442d19p-1
+cos,0x1.469898cc51702p-52,0x1.921fb54442d17p0
+cos,0x1.469898cc51702p-52,-0x1.921fb54442d17p0
+cos,0x1.1a62633145c07p-54,0x1.921fb54442d18p0
+cos,0x1.1a62633145c07p-54,-0x1.921fb54442d18p0
+cos,-0x1.72cece675d1fdp-53,0x1.921fb54442d19p0
+cos,-0x1.72cece675d1fdp-53,-0x1.921fb54442d19p0
+cos,-0x1.0p0,0x1.921fb54442d17p1
+cos,-0x1.0p0,-0x1.921fb54442d17p1
+cos,-0x1.0p0,0x1.921fb54442d18p1
+cos,-0x1.0p0,-0x1.921fb54442d18p1
+cos,-0x1.0p0,0x1.921fb54442d19p1
+cos,-0x1.0p0,-0x1.921fb54442d19p1
+cos,0x1.0p0,0x1.921fb54442d17p2
+cos,0x1.0p0,-0x1.921fb54442d17p2
+cos,0x1.0p0,0x1.921fb54442d18p2
+cos,0x1.0p0,-0x1.921fb54442d18p2
+cos,0x1.0p0,0x1.921fb54442d19p2
+cos,0x1.0p0,-0x1.921fb54442d19p2
+cos,0x1.0p0,0x1.921fb54442d17p3
+cos,0x1.0p0,-0x1.921fb54442d17p3
+cos,0x1.0p0,0x1.921fb54442d18p3
+cos,0x1.0p0,-0x1.921fb54442d18p3
+cos,0x1.0p0,0x1.921fb54442d19p3
+cos,0x1.0p0,-0x1.921fb54442d19p3
+cos,0x1.0p0,0x1.921fb54442d17p4
+cos,0x1.0p0,-0x1.921fb54442d17p4
+cos,0x1.0p0,0x1.921fb54442d18p4
+cos,0x1.0p0,-0x1.921fb54442d18p4
+cos,0x1.0p0,0x1.921fb54442d19p4
+cos,0x1.0p0,-0x1.921fb54442d19p4
+cos,0x1.0p0,0x1.921fb54442d17p5
+cos,0x1.0p0,-0x1.921fb54442d17p5
+cos,0x1.0p0,0x1.921fb54442d18p5
+cos,0x1.0p0,-0x1.921fb54442d18p5
+cos,0x1.0p0,0x1.921fb54442d19p5
+cos,0x1.0p0,-0x1.921fb54442d19p5
+cos,0x1.0p0,0x1.921fb54442d17p6
+cos,0x1.0p0,-0x1.921fb54442d17p6
+cos,0x1.0p0,0x1.921fb54442d18p6
+cos,0x1.0p0,-0x1.921fb54442d18p6
+cos,0x1.0p0,0x1.921fb54442d19p6
+cos,0x1.0p0,-0x1.921fb54442d19p6
+cos,0x1.0p0,0x1.921fb54442d17p7
+cos,0x1.0p0,-0x1.921fb54442d17p7
+cos,0x1.0p0,0x1.921fb54442d18p7
+cos,0x1.0p0,-0x1.921fb54442d18p7
+cos,0x1.0p0,0x1.921fb54442d19p7
+cos,0x1.0p0,-0x1.921fb54442d19p7
+cos,-0x1.6a09e667f3bc9p-1,0x1.2d97c7f3321d1p1
+cos,-0x1.6a09e667f3bc9p-1,-0x1.2d97c7f3321d1p1
+cos,-0x1.6a09e667f3bccp-1,0x1.2d97c7f3321d2p1
+cos,-0x1.6a09e667f3bccp-1,-0x1.2d97c7f3321d2p1
+cos,-0x1.6a09e667f3bcfp-1,0x1.2d97c7f3321d3p1
+cos,-0x1.6a09e667f3bcfp-1,-0x1.2d97c7f3321d3p1
+cos,-0x1.6a09e667f3bdp-1,0x1.f6a7a2955385dp1
+cos,-0x1.6a09e667f3bdp-1,-0x1.f6a7a2955385dp1
+cos,-0x1.6a09e667f3bcep-1,0x1.f6a7a2955385ep1
+cos,-0x1.6a09e667f3bcep-1,-0x1.f6a7a2955385ep1
+cos,-0x1.6a09e667f3bcbp-1,0x1.f6a7a2955385fp1
+cos,-0x1.6a09e667f3bcbp-1,-0x1.f6a7a2955385fp1
+cos,-0x1.34f272993d141p-50,0x1.2d97c7f3321d1p2
+cos,-0x1.34f272993d141p-50,-0x1.2d97c7f3321d1p2
+cos,-0x1.a79394c9e8a0ap-53,0x1.2d97c7f3321d2p2
+cos,-0x1.a79394c9e8a0ap-53,-0x1.2d97c7f3321d2p2
+cos,0x1.961b1acd85d7dp-51,0x1.2d97c7f3321d3p2
+cos,0x1.961b1acd85d7dp-51,-0x1.2d97c7f3321d3p2
+cos,0x1.6a09e667f3bc6p-1,0x1.5fdbbe9bba774p2
+cos,0x1.6a09e667f3bc6p-1,-0x1.5fdbbe9bba774p2
+cos,0x1.6a09e667f3bcbp-1,0x1.5fdbbe9bba775p2
+cos,0x1.6a09e667f3bcbp-1,-0x1.5fdbbe9bba775p2
+cos,0x1.6a09e667f3bd1p-1,0x1.5fdbbe9bba776p2
+cos,0x1.6a09e667f3bd1p-1,-0x1.5fdbbe9bba776p2
+cos,0x1.6a09e667f3bd4p-1,0x1.c463abeccb2bap2
+cos,0x1.6a09e667f3bd4p-1,-0x1.c463abeccb2bap2
+cos,0x1.6a09e667f3bcep-1,0x1.c463abeccb2bbp2
+cos,0x1.6a09e667f3bcep-1,-0x1.c463abeccb2bbp2
+cos,0x1.6a09e667f3bc9p-1,0x1.c463abeccb2bcp2
+cos,0x1.6a09e667f3bc9p-1,-0x1.c463abeccb2bcp2
+cos,0x1.583ebeff65cc2p-50,0x1.f6a7a2955385dp2
+cos,0x1.583ebeff65cc2p-50,-0x1.f6a7a2955385dp2
+cos,0x1.60fafbfd97309p-52,0x1.f6a7a2955385ep2
+cos,0x1.60fafbfd97309p-52,-0x1.f6a7a2955385ep2
+cos,-0x1.4f8282013467cp-51,0x1.f6a7a2955385fp2
+cos,-0x1.4f8282013467cp-51,-0x1.f6a7a2955385fp2
+cos,-0x1.6a09e667f3bb9p-1,0x1.1475cc9eedeffp3
+cos,-0x1.6a09e667f3bb9p-1,-0x1.1475cc9eedeffp3
+cos,-0x1.6a09e667f3bc5p-1,0x1.1475cc9eedfp3
+cos,-0x1.6a09e667f3bc5p-1,-0x1.1475cc9eedfp3
+cos,-0x1.6a09e667f3bdp-1,0x1.1475cc9eedf01p3
+cos,-0x1.6a09e667f3bdp-1,-0x1.1475cc9eedf01p3
+cos,-0x1.0p0,0x1.2d97c7f3321d1p3
+cos,-0x1.0p0,-0x1.2d97c7f3321d1p3
+cos,-0x1.0p0,0x1.2d97c7f3321d2p3
+cos,-0x1.0p0,-0x1.2d97c7f3321d2p3
+cos,-0x1.0p0,0x1.2d97c7f3321d3p3
+cos,-0x1.0p0,-0x1.2d97c7f3321d3p3
+cos,-0x1.6a09e667f3bep-1,0x1.46b9c347764a2p3
+cos,-0x1.6a09e667f3bep-1,-0x1.46b9c347764a2p3
+cos,-0x1.6a09e667f3bd5p-1,0x1.46b9c347764a3p3
+cos,-0x1.6a09e667f3bd5p-1,-0x1.46b9c347764a3p3
+cos,-0x1.6a09e667f3bc9p-1,0x1.46b9c347764a4p3
+cos,-0x1.6a09e667f3bc9p-1,-0x1.46b9c347764a4p3
+cos,-0x1.3dc585b2c7422p-49,0x1.5fdbbe9bba774p3
+cos,-0x1.3dc585b2c7422p-49,-0x1.5fdbbe9bba774p3
+cos,-0x1.ee2c2d963a10cp-52,0x1.5fdbbe9bba775p3
+cos,-0x1.ee2c2d963a10cp-52,-0x1.5fdbbe9bba775p3
+cos,0x1.8474f49a717bdp-50,0x1.5fdbbe9bba776p3
+cos,0x1.8474f49a717bdp-50,-0x1.5fdbbe9bba776p3
+cos,0x1.6a09e667f3bb9p-1,0x1.78fdb9effea45p3
+cos,0x1.6a09e667f3bb9p-1,-0x1.78fdb9effea45p3
+cos,0x1.6a09e667f3bc4p-1,0x1.78fdb9effea46p3
+cos,0x1.6a09e667f3bc4p-1,-0x1.78fdb9effea46p3
+cos,0x1.6a09e667f3bcfp-1,0x1.78fdb9effea47p3
+cos,0x1.6a09e667f3bcfp-1,-0x1.78fdb9effea47p3
+cos,0x1.6a09e667f3be1p-1,0x1.ab41b09886fe8p3
+cos,0x1.6a09e667f3be1p-1,-0x1.ab41b09886fe8p3
+cos,0x1.6a09e667f3bd6p-1,0x1.ab41b09886fe9p3
+cos,0x1.6a09e667f3bd6p-1,-0x1.ab41b09886fe9p3
+cos,0x1.6a09e667f3bcap-1,0x1.ab41b09886feap3
+cos,0x1.6a09e667f3bcap-1,-0x1.ab41b09886feap3
+cos,0x1.4f6babe5db9e2p-49,0x1.c463abeccb2bap3
+cos,0x1.4f6babe5db9e2p-49,-0x1.c463abeccb2bap3
+cos,0x1.3daeaf976e788p-51,0x1.c463abeccb2bbp3
+cos,0x1.3daeaf976e788p-51,-0x1.c463abeccb2bbp3
+cos,-0x1.6128a83448c3cp-50,0x1.c463abeccb2bcp3
+cos,-0x1.6128a83448c3cp-50,-0x1.c463abeccb2bcp3
+cos,-0x1.6a09e667f3bb8p-1,0x1.dd85a7410f58bp3
+cos,-0x1.6a09e667f3bb8p-1,-0x1.dd85a7410f58bp3
+cos,-0x1.6a09e667f3bc3p-1,0x1.dd85a7410f58cp3
+cos,-0x1.6a09e667f3bc3p-1,-0x1.dd85a7410f58cp3
+cos,-0x1.6a09e667f3bcep-1,0x1.dd85a7410f58dp3
+cos,-0x1.6a09e667f3bcep-1,-0x1.dd85a7410f58dp3
+cos,-0x1.0p0,0x1.f6a7a2955385dp3
+cos,-0x1.0p0,-0x1.f6a7a2955385dp3
+cos,-0x1.0p0,0x1.f6a7a2955385ep3
+cos,-0x1.0p0,-0x1.f6a7a2955385ep3
+cos,-0x1.0p0,0x1.f6a7a2955385fp3
+cos,-0x1.0p0,-0x1.f6a7a2955385fp3
+cos,-0x1.6a09e667f3bf8p-1,0x1.07e4cef4cbd96p4
+cos,-0x1.6a09e667f3bf8p-1,-0x1.07e4cef4cbd96p4
+cos,-0x1.6a09e667f3be2p-1,0x1.07e4cef4cbd97p4
+cos,-0x1.6a09e667f3be2p-1,-0x1.07e4cef4cbd97p4
+cos,-0x1.6a09e667f3bcbp-1,0x1.07e4cef4cbd98p4
+cos,-0x1.6a09e667f3bcbp-1,-0x1.07e4cef4cbd98p4
+cos,-0x1.b088e90c77fd1p-48,0x1.1475cc9eedeffp4
+cos,-0x1.b088e90c77fd1p-48,-0x1.1475cc9eedeffp4
+cos,-0x1.6111d218effa2p-49,0x1.1475cc9eedfp4
+cos,-0x1.6111d218effa2p-49,-0x1.1475cc9eedfp4
+cos,0x1.3ddc5bce200bbp-50,0x1.1475cc9eedf01p4
+cos,0x1.3ddc5bce200bbp-50,-0x1.1475cc9eedf01p4
+cos,0x1.6a09e667f3bacp-1,0x1.2106ca4910068p4
+cos,0x1.6a09e667f3bacp-1,-0x1.2106ca4910068p4
+cos,0x1.6a09e667f3bc3p-1,0x1.2106ca4910069p4
+cos,0x1.6a09e667f3bc3p-1,-0x1.2106ca4910069p4
+cos,0x1.6a09e667f3bd9p-1,0x1.2106ca491006ap4
+cos,0x1.6a09e667f3bd9p-1,-0x1.2106ca491006ap4
+cos,0x1.0p0,0x1.2d97c7f3321d1p4
+cos,0x1.0p0,-0x1.2d97c7f3321d1p4
+cos,0x1.0p0,0x1.2d97c7f3321d2p4
+cos,0x1.0p0,-0x1.2d97c7f3321d2p4
+cos,0x1.0p0,0x1.2d97c7f3321d3p4
+cos,0x1.0p0,-0x1.2d97c7f3321d3p4
+cos,0x1.6a09e667f3bf9p-1,0x1.3a28c59d54339p4
+cos,0x1.6a09e667f3bf9p-1,-0x1.3a28c59d54339p4
+cos,0x1.6a09e667f3be2p-1,0x1.3a28c59d5433ap4
+cos,0x1.6a09e667f3be2p-1,-0x1.3a28c59d5433ap4
+cos,0x1.6a09e667f3bccp-1,0x1.3a28c59d5433bp4
+cos,0x1.6a09e667f3bccp-1,-0x1.3a28c59d5433bp4
+cos,0x1.b95bfc26022b1p-48,0x1.46b9c347764a2p4
+cos,0x1.b95bfc26022b1p-48,-0x1.46b9c347764a2p4
+cos,0x1.72b7f84c04563p-49,0x1.46b9c347764a3p4
+cos,0x1.72b7f84c04563p-49,-0x1.46b9c347764a3p4
+cos,-0x1.1a900f67f753ap-50,0x1.46b9c347764a4p4
+cos,-0x1.1a900f67f753ap-50,-0x1.46b9c347764a4p4
+cos,-0x1.6a09e667f3babp-1,0x1.534ac0f19860bp4
+cos,-0x1.6a09e667f3babp-1,-0x1.534ac0f19860bp4
+cos,-0x1.6a09e667f3bc2p-1,0x1.534ac0f19860cp4
+cos,-0x1.6a09e667f3bc2p-1,-0x1.534ac0f19860cp4
+cos,-0x1.6a09e667f3bd8p-1,0x1.534ac0f19860dp4
+cos,-0x1.6a09e667f3bd8p-1,-0x1.534ac0f19860dp4
+cos,-0x1.0p0,0x1.5fdbbe9bba774p4
+cos,-0x1.0p0,-0x1.5fdbbe9bba774p4
+cos,-0x1.0p0,0x1.5fdbbe9bba775p4
+cos,-0x1.0p0,-0x1.5fdbbe9bba775p4
+cos,-0x1.0p0,0x1.5fdbbe9bba776p4
+cos,-0x1.0p0,-0x1.5fdbbe9bba776p4
+cos,-0x1.6a09e667f3bfap-1,0x1.6c6cbc45dc8dcp4
+cos,-0x1.6a09e667f3bfap-1,-0x1.6c6cbc45dc8dcp4
+cos,-0x1.6a09e667f3be3p-1,0x1.6c6cbc45dc8ddp4
+cos,-0x1.6a09e667f3be3p-1,-0x1.6c6cbc45dc8ddp4
+cos,-0x1.6a09e667f3bcdp-1,0x1.6c6cbc45dc8dep4
+cos,-0x1.6a09e667f3bcdp-1,-0x1.6c6cbc45dc8dep4
+cos,-0x1.c22f0f3f8c592p-48,0x1.78fdb9effea45p4
+cos,-0x1.c22f0f3f8c592p-48,-0x1.78fdb9effea45p4
+cos,-0x1.845e1e7f18b23p-49,0x1.78fdb9effea46p4
+cos,-0x1.845e1e7f18b23p-49,-0x1.78fdb9effea46p4
+cos,0x1.ee8786039d373p-51,0x1.78fdb9effea47p4
+cos,0x1.ee8786039d373p-51,-0x1.78fdb9effea47p4
+cos,0x1.6a09e667f3baap-1,0x1.858eb79a20baep4
+cos,0x1.6a09e667f3baap-1,-0x1.858eb79a20baep4
+cos,0x1.6a09e667f3bc1p-1,0x1.858eb79a20bafp4
+cos,0x1.6a09e667f3bc1p-1,-0x1.858eb79a20bafp4
+cos,0x1.6a09e667f3bd8p-1,0x1.858eb79a20bbp4
+cos,0x1.6a09e667f3bd8p-1,-0x1.858eb79a20bbp4
+cos,-0x1.2ccaf641d4262p-3,0x1.fffffffffffffp62
+cos,-0x1.2ccaf641d4262p-3,-0x1.fffffffffffffp62
+cos,0x1.82aa375b3c33ep-7,0x1.0p63
+cos,0x1.82aa375b3c33ep-7,-0x1.0p63
+cos,0x1.4c0622a6e35dep-2,0x1.0000000000001p63
+cos,0x1.4c0622a6e35dep-2,-0x1.0000000000001p63
+cos,0x1.4ab650b8c6073p-1,0x1.fffffffffffffp26
+cos,0x1.4ab650b8c6073p-1,-0x1.fffffffffffffp26
+cos,0x1.4ab6511a7d39bp-1,0x1.0p27
+cos,0x1.4ab6511a7d39bp-1,-0x1.0p27
+cos,0x1.4ab651ddeb9e6p-1,0x1.0000000000001p27
+cos,0x1.4ab651ddeb9e6p-1,-0x1.0000000000001p27
+cos,0x1.40ad67e777b1ep-1,0x1.fffffffffffffp23
+cos,0x1.40ad67e777b1ep-1,-0x1.fffffffffffffp23
+cos,0x1.40ad67f3f0c9ap-1,0x1.0p24
+cos,0x1.40ad67f3f0c9ap-1,-0x1.0p24
+cos,0x1.40ad680ce2f92p-1,0x1.0000000000001p24
+cos,0x1.40ad680ce2f92p-1,-0x1.0000000000001p24
+cos,-0x1.4eaa606db24c4p-1,0x1.fffffffffffffp1
+cos,-0x1.4eaa606db24c4p-1,-0x1.fffffffffffffp1
+cos,-0x1.4eaa606db24c1p-1,0x1.0p2
+cos,-0x1.4eaa606db24c1p-1,-0x1.0p2
+cos,-0x1.4eaa606db24bbp-1,0x1.0000000000001p2
+cos,-0x1.4eaa606db24bbp-1,-0x1.0000000000001p2
+cos,-0x1.aa22657537201p-2,0x1.fffffffffffffp0
+cos,-0x1.aa22657537201p-2,-0x1.fffffffffffffp0
+cos,-0x1.aa22657537205p-2,0x1.0p1
+cos,-0x1.aa22657537205p-2,-0x1.0p1
+cos,-0x1.aa2265753720cp-2,0x1.0000000000001p1
+cos,-0x1.aa2265753720cp-2,-0x1.0000000000001p1
+cos,0x1.14a280fb5068cp-1,0x1.fffffffffffffp-1
+cos,0x1.14a280fb5068cp-1,-0x1.fffffffffffffp-1
+cos,0x1.14a280fb5068cp-1,0x1.0p0
+cos,0x1.14a280fb5068cp-1,-0x1.0p0
+cos,0x1.14a280fb5068ap-1,0x1.0000000000001p0
+cos,0x1.14a280fb5068ap-1,-0x1.0000000000001p0
+cos,0x1.c1528065b7d5p-1,0x1.fffffffffffffp-2
+cos,0x1.c1528065b7d5p-1,-0x1.fffffffffffffp-2
+cos,0x1.c1528065b7d5p-1,0x1.0p-1
+cos,0x1.c1528065b7d5p-1,-0x1.0p-1
+cos,0x1.c1528065b7d4fp-1,0x1.0000000000001p-1
+cos,0x1.c1528065b7d4fp-1,-0x1.0000000000001p-1
+cos,0x1.f01549f7deea2p-1,0x1.fffffffffffffp-3
+cos,0x1.f01549f7deea2p-1,-0x1.fffffffffffffp-3
+cos,0x1.f01549f7deea1p-1,0x1.0p-2
+cos,0x1.f01549f7deea1p-1,-0x1.0p-2
+cos,0x1.f01549f7deea1p-1,0x1.0000000000001p-2
+cos,0x1.f01549f7deea1p-1,-0x1.0000000000001p-2
+cos,0x1.fc015527d5bd3p-1,0x1.fffffffffffffp-4
+cos,0x1.fc015527d5bd3p-1,-0x1.fffffffffffffp-4
+cos,0x1.fc015527d5bd3p-1,0x1.0p-3
+cos,0x1.fc015527d5bd3p-1,-0x1.0p-3
+cos,0x1.fc015527d5bd3p-1,0x1.0000000000001p-3
+cos,0x1.fc015527d5bd3p-1,-0x1.0000000000001p-3
+cos,0x1.ff0015549f4d3p-1,0x1.fffffffffffffp-5
+cos,0x1.ff0015549f4d3p-1,-0x1.fffffffffffffp-5
+cos,0x1.ff0015549f4d3p-1,0x1.0p-4
+cos,0x1.ff0015549f4d3p-1,-0x1.0p-4
+cos,0x1.ff0015549f4d3p-1,0x1.0000000000001p-4
+cos,0x1.ff0015549f4d3p-1,-0x1.0000000000001p-4
+cos,0x1.ffc00155527d3p-1,0x1.fffffffffffffp-6
+cos,0x1.ffc00155527d3p-1,-0x1.fffffffffffffp-6
+cos,0x1.ffc00155527d3p-1,0x1.0p-5
+cos,0x1.ffc00155527d3p-1,-0x1.0p-5
+cos,0x1.ffc00155527d3p-1,0x1.0000000000001p-5
+cos,0x1.ffc00155527d3p-1,-0x1.0000000000001p-5
+cos,0x1.fff000155549fp-1,0x1.fffffffffffffp-7
+cos,0x1.fff000155549fp-1,-0x1.fffffffffffffp-7
+cos,0x1.fff000155549fp-1,0x1.0p-6
+cos,0x1.fff000155549fp-1,-0x1.0p-6
+cos,0x1.fff000155549fp-1,0x1.0000000000001p-6
+cos,0x1.fff000155549fp-1,-0x1.0000000000001p-6
+cos,0x1.fffffffp-1,0x1.fffffffffffffp-15
+cos,0x1.fffffffp-1,-0x1.fffffffffffffp-15
+cos,0x1.fffffffp-1,0x1.0p-14
+cos,0x1.fffffffp-1,-0x1.0p-14
+cos,0x1.fffffffp-1,0x1.0000000000001p-14
+cos,0x1.fffffffp-1,-0x1.0000000000001p-14
+cos,0x1.0p0,0x1.fffffffffffffp-28
+cos,0x1.0p0,-0x1.fffffffffffffp-28
+cos,0x1.0p0,0x1.0p-27
+cos,0x1.0p0,-0x1.0p-27
+cos,0x1.0p0,0x1.0000000000001p-27
+cos,0x1.0p0,-0x1.0000000000001p-27
+cos,0x1.0p0,0x1.fffffffffffffp-31
+cos,0x1.0p0,-0x1.fffffffffffffp-31
+cos,0x1.0p0,0x1.0p-30
+cos,0x1.0p0,-0x1.0p-30
+cos,0x1.0p0,0x1.0000000000001p-30
+cos,0x1.0p0,-0x1.0000000000001p-30
+cos,-0x1.fffe62ecfab75p-1,-0x1.fffffffffffffp1023
+cos,-0x1.fffe62ecfab75p-1,0x1.fffffffffffffp1023
+cos,-0x1.fffe62ecfab75p-1,0x1.fffffffffffffp1023
+cos,-0x1.fffe62ecfab75p-1,-0x1.fffffffffffffp1023
+cos,-0x1.fffe62ecfab75p-1,0x1.fffffffffffffp1023
+cos,-0x1.fffe62ecfab75p-1,-0x1.fffffffffffffp1023
+cos,0x1.7ffdfb4c5309p-2,0x1.ffffffffffffep1023
+cos,0x1.7ffdfb4c5309p-2,-0x1.ffffffffffffep1023
+cos,-0x1.0p0,0x1.921fb54442d18p1
+cos,-0x1.0p0,-0x1.921fb54442d18p1
+cos,0x1.1a62633145c07p-54,0x1.921fb54442d18p0
+cos,0x1.1a62633145c07p-54,-0x1.921fb54442d18p0
+cos,0x1.14a280fb5068ap-1,0x1.0000000000001p0
+cos,0x1.14a280fb5068ap-1,-0x1.0000000000001p0
+cos,0x1.14a280fb5068cp-1,0x1.0p0
+cos,0x1.14a280fb5068cp-1,-0x1.0p0
+cos,0x1.14a280fb5068cp-1,0x1.fffffffffffffp-1
+cos,0x1.14a280fb5068cp-1,-0x1.fffffffffffffp-1
+cos,0x1.6a09e667f3bcdp-1,0x1.921fb54442d18p-1
+cos,0x1.6a09e667f3bcdp-1,-0x1.921fb54442d18p-1
+cos,0x1.0p0,0x1.0000000000001p-1022
+cos,0x1.0p0,-0x1.0000000000001p-1022
+cos,0x1.0p0,0x1.0p-1022
+cos,0x1.0p0,-0x1.0p-1022
+cos,0x1.0p0,0x0.fffffffffffffp-1022
+cos,0x1.0p0,-0x0.fffffffffffffp-1022
+cos,0x1.0p0,0x0.ffffffffffffep-1022
+cos,0x1.0p0,-0x0.ffffffffffffep-1022
+cos,0x1.0p0,0x0.0000000000002p-1022
+cos,0x1.0p0,-0x0.0000000000002p-1022
+cos,0x1.0p0,0x0.0000000000001p-1022
+cos,0x1.0p0,-0x0.0000000000001p-1022
+cos,0x1.0p0,0x0.0p0
+cos,0x1.0p0,-0x0.0p0
+exp,0x1.0000000000002p0,0x1.ffffffffffffep-52
+exp,0x1.000000000012p0,0x1.1ffffffffff5ep-44
+exp,0x1.000000000208p0,0x1.03fffffffef7fp-39
+exp,0x1.00000000c1b59p0,0x1.836b2fff6d6cbp-33
+exp,0x1.000000033d397p0,0x1.9e9cbbfd6080bp-31
+exp,0x1.003af6c37c1d3p0,0x1.d77fd13d27fffp-11
+exp,0x1.016b4df3299d8p0,0x1.6a4d1af9cc989p-8
+exp,0x1.0ca4a41663fep0,0x1.8ae823850230bp-5
+exp,0x1.1538ea18a4585p0,0x1.46370d915991bp-4
+exp,0x1.47408cb9583cep0,0x1.f6e4c3ced7c72p-3
+exp,0x1.27c2e4bc1ee7p1,0x1.accfbe46b4efp-1
+exp,0x1.557d4acd7e556p2,0x1.aca7ae8da5a7bp0
+exp,0x1.91a8dff540ff7p2,0x1.d6336a88077aap0
+exp,0x1.8ede492d96072p3,0x1.42ee3c7dc4946p1
+exp,0x1.ac50b409c8aeep8,0x1.83d4bcdebb3f4p2
+exp,0x1.f3e558cf4de54p-23,-0x1.e8bdbfcd9144ep3
+exp,0x1.951c6dc5d24e2p-9,-0x1.71e0b869b5e79p2
+exp,0x1.1064b2c103ddap-3,-0x1.02393d5976769p1
+exp,0x1.3ef1e9b3a81c8p-2,-0x1.2a9cad9998262p0
+exp,0x1.534d4de870713p-3,-0x1.cc37ef7de7501p0
+exp,0x1.2217147b85eaap-1,-0x1.22e24fa3d5cf9p-1
+exp,0x1.9403fd0ee51c8p-2,-0x1.dc2b5df1f7d3dp-1
+exp,0x1.baded30cbf1c4p-1,-0x1.290ea09e36479p-3
+exp,0x1.ffe5d0bb7eabfp-1,-0x1.a2fefefd580dfp-13
+exp,0x1.ffffff84b39c5p-1,-0x1.ed318efb627eap-27
+exp,0x1.fffffffad0ae6p-1,-0x1.4bd46601ae1efp-31
+exp,0x1.ffffffffff7p-1,-0x1.2000000000288p-42
+exp,0x1.fffffffffffdp-1,-0x1.8000000000012p-48
+exp,0x1.ffffffffffffcp-1,-0x1.0000000000001p-51
+exp,0x1.0000000000001p0,0x1.fffffffffffffp-53
+exp,0x1.000000000002p0,0x1.fffffffffffep-48
+exp,0x1.000000017ffe8p0,0x1.7ffe7ffee0024p-32
+exp,0x1.0000000180018p0,0x1.80017ffedffdcp-32
+exp,0x1.00000075e9f64p0,0x1.d7a7d893609e5p-26
+exp,0x1.0006e83736f8cp0,0x1.ba07d73250de7p-14
+exp,0x1.de7cd6751029ap16,0x1.76e7e5d7b6eacp3
+exp,0x1.1d71965f516aep19,0x1.a8ead058bc6b8p3
+exp,0x1.a8c02e974c315p25,0x1.1d5c2daebe367p4
+exp,0x1.b890ca8637ae2p40,0x1.c44ce0d716a1ap4
+exp,0x1.f03f56a88b5d8p-1,-0x1.0000000000001p-5
+exp,0x1.ff003ff556aa8p-1,-0x1.000000000000ap-9
+exp,0x1.8ebef9eac81fcp-1,-0x1.0000000000025p-2
+exp,0x1.fc03fd56a469cp-1,-0x1.0000000171051p-7
+exp,0x1.78b5612dbee01p-2,-0x1.0000018p0
+exp,0x1.969c870ea9f5ap-93,-0x1.000001e3ep6
+exp,0x1.78af867bc511ep-2,-0x1.0003fcp0
+exp,0x1.fffffffffefffp-1,-0x1.00080000004p-41
+exp,0x1.789214093c81ep-2,-0x1.0018p0
+exp,0x1.8e298e52fcce8p-1,-0x1.018p-2
+exp,0x1.aa6ffb0ba51ap-24,-0x1.0201p4
+exp,0x1.dd7a46b8d85d6p-376,-0x1.04p8
+exp,0x1.33e96ca3bcf3ep-1,-0x1.045b94872413p-1
+exp,0x1.ef2f652dc2606p-1,-0x1.118e05cfa3e8p-5
+exp,0x1.a5d2ce977bbe2p-7,-0x1.169156e17b9b9p2
+exp,0x1.a0207cf4190f7p-7,-0x1.17701b3bf0502p2
+exp,0x1.fb97e1ff8cbbap-1,-0x1.1b4p-7
+exp,0x1.bcff09ae30c46p-1,-0x1.1f4p-3
+exp,0x1.fee70cf5e86efp-833,-0x1.2059ad42c3cf7p9
+exp,0x1.7ccd3f3340746p-1,-0x1.2f269d2ca38d2p-2
+exp,0x1.09cdb36e977bcp-14,-0x1.3553cf1828b0bp3
+exp,0x1.f9dc5cd546d9cp-449,-0x1.368ac083128fcp8
+exp,0x1.f1c53c907f6f5p-15,-0x1.376e8f679ae16p3
+exp,0x1.f24595954e662p-8,-0x1.3844f67495f7dp2
+exp,0x1.fb56521290a22p-905,-0x1.394e9e1b089d7p9
+exp,0x1.dc1658ff6e07p-114,-0x1.3997ea51e5271p6
+exp,0x1.ec8b3c090f8b9p-1,-0x1.3d5de560e1906p-5
+exp,0x1.af411bf985221p-951,-0x1.4954aa552a96p9
+exp,0x1.e1b71d238d508p-957,-0x1.4b5ad6a9ad6adp9
+exp,0x1.cc666a3519cap-973,-0x1.50ec32686a834p9
+exp,0x1.22462bd5f72b1p-976,-0x1.52316872b0222p9
+exp,0x1.c1ebc18610302p-981,-0x1.53b4ed3b4ec77p9
+exp,0x1.8d015bcaf9e19p-981,-0x1.53c4f13c4f079p9
+exp,0x1.fd5835460ed49p-989,-0x1.566ad4a41becp9
+exp,0x1.58733fbc088fp-994,-0x1.585883e7b3b38p9
+exp,0x1.b052090690482p-32,-0x1.5a81ecf68beccp4
+exp,0x1.df6154bc644dbp-1015,-0x1.5f75629af4eb7p9
+exp,0x0.ffa586d1b841ap-1022,-0x1.6232eb1c432f2p9
+exp,0x0.b12f6ea63a89fp-1022,-0x1.6261d7dbf48ccp9
+exp,0x1.d572d24973be2p-1,-0x1.6364b8f747e32p-4
+exp,0x1.ee4dd79224578p-9,-0x1.6524796b40895p2
+exp,0x1.f660c59b2945p-5,-0x1.6551daae369cep1
+exp,0x0.0003540e0893ep-1022,-0x1.672463f141607p9
+exp,0x1.d4e7fc331b732p-1,-0x1.6820c99c1dc16p-4
+exp,0x1.fcc448acf4765p-528,-0x1.6d4b7e82c3f02p8
+exp,0x1.7fff5a1bffcb2p-529,-0x1.6e44f765fda76p8
+exp,0x1.fa4ecd8ae5718p-1,-0x1.6e56e725b8304p-7
+exp,0x1.e8d2dafd017cep-3,-0x1.6ecp0
+exp,0x0.0000000001215p-1022,-0x1.7p9
+exp,0x0.000000000000ep-1022,-0x1.72e42p9
+exp,0x1.a349b2329c678p-273,-0x1.7978bac71121cp7
+exp,0x1.d2a6d5ea995c2p-1,-0x1.7bde79e0f970cp-4
+exp,0x1.b776dc64c76d2p-3,-0x1.8ap0
+exp,0x1.4446fcf7da68ap-72,-0x1.8d5c84f0bac8cp5
+exp,0x1.e72a0b68bb82cp-73,-0x1.8fa68b444723p5
+exp,0x1.fc33d5e1ca6dfp-75,-0x1.9a671693b946bp5
+exp,0x1.e6981fd6ef79cp-1,-0x1.a0ec89f897a75p-5
+exp,0x1.f2b9d3b6cf227p-1,-0x1.ae6p-6
+exp,0x1.e5034c8d191bcp-1,-0x1.bb9706e2f1bb4p-5
+exp,0x1.f24dc90f9fbecp-1,-0x1.bc3edad2e1efbp-6
+exp,0x1.71f237d64a6ecp-11,-0x1.d0697edbe0052p2
+exp,0x1.f12c0d3addaa4p-1,-0x1.e18p-6
+exp,0x1.f110dd9073d72p-1,-0x1.e5p-6
+exp,0x1.f3aa7a860574cp-705,-0x1.e7fffffffffffp8
+exp,0x1.f0f898d55117p-1,-0x1.e82p-6
+exp,0x1.ff814fff18dadp-1,-0x1.fafebfafebfbp-11
+exp,0x1.ffffffff01c07p-1,-0x1.fc7f1fc7f2p-34
+exp,0x1.7907d4148bd92p-2,-0x1.ff8ffffffffffp-1
+exp,0x1.ffffffffffff8p-1,-0x1.ff8ffffffffffp-51
+exp,0x1.e0fbb03a0c27ep-1,-0x1.ffeffffffffffp-5
+exp,0x1.ffffffffff001p-1,-0x1.ffeffffffffffp-42
+exp,0x1.ffffffffffp-1,-0x1.fff00000008p-42
+exp,0x1.0p0,-0x1.fff8e61eadd48p-101
+exp,0x1.fffffffffc001p-1,-0x1.fffbfffffffffp-40
+exp,0x1.fffffffffcp-1,-0x1.fffff1fffffffp-40
+exp,0x1.ff800ffeaac01p-1,-0x1.ffffffffffda5p-11
+exp,0x1.e355bbaee8d86p-24,-0x1.fffffffffff7dp3
+exp,0x1.78b56362cef3ep-2,-0x1.ffffffffffff8p-1
+exp,0x1.0p0,-0x0.ffffffffffffep-1022
+exp,0x1.42eb9f39afbacp-185,-0x1.ffffffffffffep6
+exp,0x1.0p0,0x1.0p-53
+exp,0x1.95e54c5dd4218p184,0x1.0p7
+exp,0x1.9476504ba8857p738,0x1.0000000000001p9
+exp,0x1.0100802ab5578p0,0x1.0000000000003p-8
+exp,0x1.0000004000001p0,0x1.0000000000007p-26
+exp,0x1.d8e64b8f26c12p2,0x1.000000008p1
+exp,0x1.749ea7e015bc2p11,0x1.00000001p3
+exp,0x1.0f2ebd2c65d9ap23,0x1.00000002p4
+exp,0x1.0f2ec1473afeap23,0x1.0000004p4
+exp,0x1.0000000001p0,0x1.0008p-40
+exp,0x1.00000000008p0,0x1.001p-41
+exp,0x1.0000000000001p0,0x1.001p-53
+exp,0x1.a8bf81a597eddp184,0x1.00173eab3623ap7
+exp,0x1.75e54175aabb4p11,0x1.001cp3
+exp,0x1.60008fbed6c52p1,0x1.02f8af8af8affp0
+exp,0x1.04184bb80ff44p0,0x1.04p-6
+exp,0x1.0000084000221p0,0x1.08p-21
+exp,0x1.2338ab9b7432p0,0x1.08000001d0fc8p-3
+exp,0x1.acc91bfa7c54cp0,0x1.0814419d6a65ap-1
+exp,0x1.a4e4693413b9ap400,0x1.15c18de877563p8
+exp,0x1.0000000000004p0,0x1.1ffffffffffffp-50
+exp,0x1.eaa521edf1bc2p846,0x1.2586ca9cf411bp9
+exp,0x1.fca9c47016cb1p26,0x1.2b55c037ebb9dp4
+exp,0x1.fcbb1e5c8d535p26,0x1.2b564bee0a6cap4
+exp,0x1.cc0f9d911f1d1p0,0x1.2c2p-1
+exp,0x1.b68a28b09fe94p6,0x1.2c9e33f794769p2
+exp,0x1.d2e035b1892d6p0,0x1.33a74ff06fb66p-1
+exp,0x1.6acde844356cap3,0x1.36cce3c3925p1
+exp,0x1.06dadee28c11cp7,0x1.38389c48b0fcep2
+exp,0x1.c78f37f07cea6p904,0x1.3997381d7d94fp9
+exp,0x1.bfe0c519166c4p1,0x1.40a339c81cecbp0
+exp,0x1.fbc9c30603087p927,0x1.419dbcc48677p9
+exp,0x1.f1ef9c8a4fdaep930,0x1.42a565e456e04p9
+exp,0x1.da134d5a4d1e2p934,0x1.44020100804p9
+exp,0x1.f4ec44194b642p938,0x1.456bf23e02428p9
+exp,0x1.ea91d9533b394p939,0x1.45c1feef8086cp9
+exp,0x1.cb419b9279b36p943,0x1.471c71c71c71cp9
+exp,0x1.6d14308828322p29,0x1.474c9cc44cc25p4
+exp,0x1.c0194b4186e28p956,0x1.4b9ab1781203p9
+exp,0x1.15c605853476cp0,0x1.4e59dc7e2b053p-4
+exp,0x1.6dee38735a6d4p972,0x1.510c5465d984bp9
+exp,0x1.f1e96be2a52cdp0,0x1.549b0f5742382p-1
+exp,0x1.f253c5990aad2p0,0x1.55085fb86501ap-1
+exp,0x1.279b1c43a2662p993,0x1.58383126e94bfp9
+exp,0x1.6fd5ab59153f4p996,0x1.595e5795e592bp9
+exp,0x1.5ecf187653954p1004,0x1.5c1e0f0783c1p9
+exp,0x1.f2a3c29fc6d72p1008,0x1.5dadf5d1e452cp9
+exp,0x1.edcb14879613ep1009,0x1.5e056ed40e56ep9
+exp,0x1.fcc7e5ca80b1fp0,0x1.5fa97bb4e906p-1
+exp,0x1.f8b5c987a3d88p3,0x1.610e47e1325dcp1
+exp,0x1.f1e9d8cf24fcep7,0x1.611b19dcc53e4p2
+exp,0x1.ffc045692e8ap1023,0x1.62e41fffffffap9
+exp,0x1.ffc045693009dp1023,0x1.62e42p9
+exp,0x1.ffc04569a2fb8p1023,0x1.62e42000001ccp9
+exp,0x1.fffffffffeb2ap1023,0x1.62e42fefa39eap9
+exp,0x1.00000b40003f5p0,0x1.68p-21
+exp,0x1.17e62f70bec9ap8,0x1.689a7dc5921b8p2
+exp,0x1.6daaa1336a315p264,0x1.6eb1de69ace32p7
+exp,0x1.72a9dadea7498p0,0x1.7bp-2
+exp,0x1.1ed3fe64fc53ap2,0x1.7fffffffffff9p0
+exp,0x1.0000000000001p0,0x1.7ffffffffffffp-52
+exp,0x1.fe31152b7ef6bp553,0x1.8p8
+exp,0x1.74d77b76d9516p0,0x1.81p-2
+exp,0x1.f0e3e5b6c17cp556,0x1.820d92fc4b42ap8
+exp,0x1.00000000c1b59p0,0x1.836b2fff6d6cbp-33
+exp,0x1.78b69d690db7ap570,0x1.8b7aee631f489p8
+exp,0x1.4dad95877ae08p144,0x1.905011e0df629p6
+exp,0x1.fcbb8778f6121p144,0x1.91fffp6
+exp,0x1.7a5b2771e0a16p4,0x1.94e54738fb4b7p1
+exp,0x1.7d676a26fe5cap0,0x1.984p-2
+exp,0x1.698764128a444p147,0x1.98f381d7db44fp6
+exp,0x1.44e5a752f9e1fp9,0x1.9e8186b267a28p2
+exp,0x1.8023d298e373p0,0x1.9f91c1449c421p-2
+exp,0x1.df9bd06daf8cep299,0x1.9fc1f212d70f6p7
+exp,0x1.81a4fbca9dcdcp0,0x1.a392789eafce9p-2
+exp,0x1.825f354ccf6f3p0,0x1.a5807ca1392b2p-2
+exp,0x1.3c1e2876834aap0,0x1.bp-3
+exp,0x1.1c7e1aca53796p0,0x1.b04p-4
+exp,0x1.a2d50b8b2880ep331,0x1.cbd917ccad096p7
+exp,0x1.419c8a8da1b7ap1,0x1.d7b677e333d38p-1
+exp,0x1.41d1b8b4649ecp1,0x1.d80b1a6330bebp-1
+exp,0x1.bf3447921fd3ap10,0x1.df50d9af9e41p2
+exp,0x1.9919794bc862ap0,0x1.e0081ebc3264ep-2
+exp,0x1.76a62bad715b4p5,0x1.ec5bb209e5707p1
+exp,0x1.c701554c761aap2,0x1.f62p0
+exp,0x1.c3dda3c952b92p727,0x1.f87c7820d8446p8
+exp,0x1.d28c6097b9d56p2,0x1.fc89dc1aa909cp0
+exp,0x1.4231178c2349p734,0x1.fcfffffffffffp8
+exp,0x1.04034591911e8p0,0x1.fda6dfe27ffffp-7
+exp,0x1.a5b5691c4b0fp0,0x1.ff1dd1fffffffp-2
+exp,0x1.0000000000004p0,0x1.ff8ffffffffffp-51
+exp,0x1.6d4fd9ab47c92p738,0x1.ffe5effffffffp8
+exp,0x1.0000000000fffp0,0x1.ffefffffff001p-41
+exp,0x1.74418bce788ecp11,0x1.ffeffffffffffp2
+exp,0x1.0000000001p0,0x1.fffp-41
+exp,0x1.0000000001p0,0x1.ffffe3fffffffp-41
+exp,0x1.d8e64b8d21852p2,0x1.ffffffffe7fffp0
+exp,0x1.0p0,0x0.ffffffffffffep-1022
+exp,0x1.0p0,0x1.ffffffffffffep-54
+exp,0x1.0p0,0x1.fffffffffffffp-54
+exp,0x1.304d6aeca2525p69,0x1.7ffffffffffffp5
+exp,0x1.304d6aeca254bp69,0x1.8p5
+exp,0x1.304d6aeca2571p69,0x1.8000000000001p5
+exp,0x1.f8e6c24b558efp-76,-0x1.a000000000001p5
+exp,0x1.f8e6c24b5592ep-76,-0x1.ap5
+exp,0x1.f8e6c24b5596dp-76,-0x1.9ffffffffffffp5
+exp,0x1.55779b984f396p115,0x1.3ffffffffffffp6
+exp,0x1.55779b984f3ebp115,0x1.4p6
+exp,0x1.55779b984f44p115,0x1.4000000000001p6
+exp,0x1.07b7112bc1fbcp-127,-0x1.6000000000001p6
+exp,0x1.07b7112bc1ffep-127,-0x1.6p6
+exp,0x1.07b7112bc204p-127,-0x1.5ffffffffffffp6
+exp,0x1.40a4b9c271508p923,0x1.3ffffffffffffp9
+exp,0x1.40a4b9c27178ap923,0x1.4p9
+exp,0x1.40a4b9c271a0bp923,0x1.4000000000001p9
+exp,0x1.44a3824e525d6p-1016,-0x1.6000000000001p9
+exp,0x1.44a3824e5285fp-1016,-0x1.6p9
+exp,0x1.44a3824e52ae8p-1016,-0x1.5ffffffffffffp9
+exp,0x1.03996528e072bp75,0x1.9ffffffffffffp5
+exp,0x1.03996528e074cp75,0x1.ap5
+exp,0x1.03996528e076cp75,0x1.a000000000001p5
+exp,0x1.aebabae3a417fp-70,-0x1.8000000000001p5
+exp,0x1.aebabae3a41b5p-70,-0x1.8p5
+exp,0x1.aebabae3a41eap-70,-0x1.7ffffffffffffp5
+exp,0x1.f1056dc7bf1b1p126,0x1.5ffffffffffffp6
+exp,0x1.f1056dc7bf22dp126,0x1.6p6
+exp,0x1.f1056dc7bf2aap126,0x1.6000000000001p6
+exp,0x1.7fd974d372de4p-116,-0x1.4000000000001p6
+exp,0x1.7fd974d372e44p-116,-0x1.4p6
+exp,0x1.7fd974d372ea4p-116,-0x1.3ffffffffffffp6
+exp,0x1.93bf4ec282bd4p1015,0x1.5ffffffffffffp9
+exp,0x1.93bf4ec282efbp1015,0x1.6p9
+exp,0x1.93bf4ec283223p1015,0x1.6000000000001p9
+exp,0x1.98c72ca0cab15p-924,-0x1.4000000000001p9
+exp,0x1.98c72ca0cae46p-924,-0x1.4p9
+exp,0x1.98c72ca0cb178p-924,-0x1.3ffffffffffffp9
+exp,0x1.61013a44a981cp-822,-0x1.1cb90bfbe8e7cp9
+exp,0x1.8087717a7f08ap-905,-0x1.397217f7d1cf8p9
+exp,0x1.a2de59d854521p-988,-0x1.562b23f3bab73p9
+exp,0x1.fffffffffffffp-2,-0x1.62e42fefa39fp-1
+exp,0x1.0p-1,-0x1.62e42fefa39efp-1
+exp,0x1.0000000000001p-1,-0x1.62e42fefa39eep-1
+exp,0x1.6a09e667f3bccp-1,-0x1.62e42fefa39fp-2
+exp,0x1.6a09e667f3bccp-1,-0x1.62e42fefa39efp-2
+exp,0x1.6a09e667f3bcdp-1,-0x1.62e42fefa39eep-2
+exp,0x1.ae89f995ad3adp-1,-0x1.62e42fefa39fp-3
+exp,0x1.ae89f995ad3aep-1,-0x1.62e42fefa39efp-3
+exp,0x1.ae89f995ad3aep-1,-0x1.62e42fefa39eep-3
+exp,0x1.d5818dcfba487p-1,-0x1.62e42fefa39fp-4
+exp,0x1.d5818dcfba487p-1,-0x1.62e42fefa39efp-4
+exp,0x1.d5818dcfba487p-1,-0x1.62e42fefa39eep-4
+exp,0x1.ea4afa2a490dap-1,-0x1.62e42fefa39fp-5
+exp,0x1.ea4afa2a490dap-1,-0x1.62e42fefa39efp-5
+exp,0x1.ea4afa2a490dap-1,-0x1.62e42fefa39eep-5
+exp,0x1.f50765b6e454p-1,-0x1.62e42fefa39fp-6
+exp,0x1.f50765b6e454p-1,-0x1.62e42fefa39efp-6
+exp,0x1.f50765b6e454p-1,-0x1.62e42fefa39eep-6
+exp,0x1.059b0d3158574p0,0x1.62e42fefa39eep-6
+exp,0x1.059b0d3158574p0,0x1.62e42fefa39efp-6
+exp,0x1.059b0d3158574p0,0x1.62e42fefa39fp-6
+exp,0x1.0b5586cf9890fp0,0x1.62e42fefa39eep-5
+exp,0x1.0b5586cf9890fp0,0x1.62e42fefa39efp-5
+exp,0x1.0b5586cf9890fp0,0x1.62e42fefa39fp-5
+exp,0x1.172b83c7d517bp0,0x1.62e42fefa39eep-4
+exp,0x1.172b83c7d517bp0,0x1.62e42fefa39efp-4
+exp,0x1.172b83c7d517bp0,0x1.62e42fefa39fp-4
+exp,0x1.306fe0a31b715p0,0x1.62e42fefa39eep-3
+exp,0x1.306fe0a31b715p0,0x1.62e42fefa39efp-3
+exp,0x1.306fe0a31b715p0,0x1.62e42fefa39fp-3
+exp,0x1.6a09e667f3bccp0,0x1.62e42fefa39eep-2
+exp,0x1.6a09e667f3bccp0,0x1.62e42fefa39efp-2
+exp,0x1.6a09e667f3bcdp0,0x1.62e42fefa39fp-2
+exp,0x1.fffffffffffffp0,0x1.62e42fefa39eep-1
+exp,0x1.0p1,0x1.62e42fefa39efp-1
+exp,0x1.0p1,0x1.62e42fefa39fp-1
+exp,0x1.ffffffffffffep1,0x1.62e42fefa39eep0
+exp,0x1.0p2,0x1.62e42fefa39efp0
+exp,0x1.0000000000001p2,0x1.62e42fefa39fp0
+exp,0x1.ffffffffffffbp3,0x1.62e42fefa39eep1
+exp,0x1.fffffffffffffp3,0x1.62e42fefa39efp1
+exp,0x1.0000000000002p4,0x1.62e42fefa39fp1
+exp,0x1.ffffffffffff6p7,0x1.62e42fefa39eep2
+exp,0x1.ffffffffffffep7,0x1.62e42fefa39efp2
+exp,0x1.0000000000003p8,0x1.62e42fefa39fp2
+exp,0x1.fffffffffffedp15,0x1.62e42fefa39eep3
+exp,0x1.ffffffffffffdp15,0x1.62e42fefa39efp3
+exp,0x1.0000000000006p16,0x1.62e42fefa39fp3
+exp,0x1.fffffffffffd9p31,0x1.62e42fefa39eep4
+exp,0x1.ffffffffffff9p31,0x1.62e42fefa39efp4
+exp,0x1.000000000000dp32,0x1.62e42fefa39fp4
+exp,0x1.ffffffffffb2ap1023,0x1.62e42fefa39eep9
+exp,0x1.fffffffffff2ap1023,0x1.62e42fefa39efp9
+exp,0x0.000000000000ep-1022,-0x1.72e42fefa39fp9
+exp,0x0.000000000000ep-1022,-0x1.72e42fefa39efp9
+exp,0x0.000000000000ep-1022,-0x1.72e42fefa39eep9
+exp,0x1.8ebef9eac820ap-1,-0x1.0000000000001p-2
+exp,0x1.8ebef9eac820bp-1,-0x1.0p-2
+exp,0x1.8ebef9eac820bp-1,-0x1.fffffffffffffp-3
+exp,0x1.c3d6a24ed8221p-1,-0x1.0000000000001p-3
+exp,0x1.c3d6a24ed8222p-1,-0x1.0p-3
+exp,0x1.c3d6a24ed8222p-1,-0x1.fffffffffffffp-4
+exp,0x1.e0fabfbc702a4p-1,-0x1.0000000000001p-4
+exp,0x1.e0fabfbc702a4p-1,-0x1.0p-4
+exp,0x1.e0fabfbc702a4p-1,-0x1.fffffffffffffp-5
+exp,0x1.f03f56a88b5d8p-1,-0x1.0000000000001p-5
+exp,0x1.f03f56a88b5d8p-1,-0x1.0p-5
+exp,0x1.f03f56a88b5d8p-1,-0x1.fffffffffffffp-6
+exp,0x1.f80feabfeefa5p-1,-0x1.0000000000001p-6
+exp,0x1.f80feabfeefa5p-1,-0x1.0p-6
+exp,0x1.f80feabfeefa5p-1,-0x1.fffffffffffffp-7
+exp,0x1.fc03fd56aa225p-1,-0x1.0000000000001p-7
+exp,0x1.fc03fd56aa225p-1,-0x1.0p-7
+exp,0x1.fc03fd56aa225p-1,-0x1.fffffffffffffp-8
+exp,0x1.fe00ffaabffbcp-1,-0x1.0000000000001p-8
+exp,0x1.fe00ffaabffbcp-1,-0x1.0p-8
+exp,0x1.fe00ffaabffbcp-1,-0x1.fffffffffffffp-9
+exp,0x1.ff003ff556aa9p-1,-0x1.0000000000001p-9
+exp,0x1.ff003ff556aa9p-1,-0x1.0p-9
+exp,0x1.ff003ff556aa9p-1,-0x1.fffffffffffffp-10
+exp,0x1.ff800ffeaacp-1,-0x1.0000000000001p-10
+exp,0x1.ff800ffeaacp-1,-0x1.0p-10
+exp,0x1.ff800ffeaacp-1,-0x1.fffffffffffffp-11
+exp,0x1.fff0003fff555p-1,-0x1.0000000000001p-13
+exp,0x1.fff0003fff555p-1,-0x1.0p-13
+exp,0x1.fff0003fff555p-1,-0x1.fffffffffffffp-14
+exp,0x1.48b5e3c3e8186p0,0x1.fffffffffffffp-3
+exp,0x1.48b5e3c3e8186p0,0x1.0p-2
+exp,0x1.48b5e3c3e8187p0,0x1.0000000000001p-2
+exp,0x1.2216045b6f5cdp0,0x1.fffffffffffffp-4
+exp,0x1.2216045b6f5cdp0,0x1.0p-3
+exp,0x1.2216045b6f5cdp0,0x1.0000000000001p-3
+exp,0x1.1082b577d34edp0,0x1.fffffffffffffp-5
+exp,0x1.1082b577d34eep0,0x1.0p-4
+exp,0x1.1082b577d34eep0,0x1.0000000000001p-4
+exp,0x1.08205601127edp0,0x1.fffffffffffffp-6
+exp,0x1.08205601127edp0,0x1.0p-5
+exp,0x1.08205601127edp0,0x1.0000000000001p-5
+exp,0x1.04080ab55de39p0,0x1.fffffffffffffp-7
+exp,0x1.04080ab55de39p0,0x1.0p-6
+exp,0x1.04080ab55de39p0,0x1.0000000000001p-6
+exp,0x1.0202015600446p0,0x1.fffffffffffffp-8
+exp,0x1.0202015600446p0,0x1.0p-7
+exp,0x1.0202015600446p0,0x1.0000000000001p-7
+exp,0x1.0100802ab5577p0,0x1.fffffffffffffp-9
+exp,0x1.0100802ab5577p0,0x1.0p-8
+exp,0x1.0100802ab5577p0,0x1.0000000000001p-8
+exp,0x1.0080200556001p0,0x1.fffffffffffffp-10
+exp,0x1.0080200556001p0,0x1.0p-9
+exp,0x1.0080200556001p0,0x1.0000000000001p-9
+exp,0x1.00400800aab55p0,0x1.fffffffffffffp-11
+exp,0x1.00400800aab55p0,0x1.0p-10
+exp,0x1.00400800aab55p0,0x1.0000000000001p-10
+exp,0x1.0008002000555p0,0x1.fffffffffffffp-14
+exp,0x1.0008002000555p0,0x1.0p-13
+exp,0x1.0008002000555p0,0x1.0000000000001p-13
+exp,0x1.44109edb206a9p-739,-0x1.0000000000001p9
+exp,0x1.44109edb20931p-739,-0x1.0p9
+exp,0x1.44109edb20a76p-739,-0x1.fffffffffffffp8
+exp,0x1.9755956ad4d05p-370,-0x1.0000000000001p8
+exp,0x1.9755956ad4e9cp-370,-0x1.0p8
+exp,0x1.9755956ad4f68p-370,-0x1.fffffffffffffp7
+exp,0x1.42eb9f39afa6ap-185,-0x1.0000000000001p7
+exp,0x1.42eb9f39afb0bp-185,-0x1.0p7
+exp,0x1.42eb9f39afb5cp-185,-0x1.fffffffffffffp6
+exp,0x1.969d47321e466p-93,-0x1.0000000000001p6
+exp,0x1.969d47321e4ccp-93,-0x1.0p6
+exp,0x1.969d47321e4fep-93,-0x1.fffffffffffffp5
+exp,0x1.c8464f761642fp-47,-0x1.0000000000001p5
+exp,0x1.c8464f7616468p-47,-0x1.0p5
+exp,0x1.c8464f7616485p-47,-0x1.fffffffffffffp4
+exp,0x1.e355bbaee85adp-24,-0x1.0000000000001p4
+exp,0x1.e355bbaee85cbp-24,-0x1.0p4
+exp,0x1.e355bbaee85dap-24,-0x1.fffffffffffffp3
+exp,0x1.5fc21041027a2p-12,-0x1.0000000000001p3
+exp,0x1.5fc21041027adp-12,-0x1.0p3
+exp,0x1.5fc21041027b2p-12,-0x1.fffffffffffffp2
+exp,0x1.2c155b8213cfp-6,-0x1.0000000000001p2
+exp,0x1.2c155b8213cf4p-6,-0x1.0p2
+exp,0x1.2c155b8213cf7p-6,-0x1.fffffffffffffp1
+exp,0x1.152aaa3bf81c9p-3,-0x1.0000000000001p1
+exp,0x1.152aaa3bf81ccp-3,-0x1.0p1
+exp,0x1.152aaa3bf81cdp-3,-0x1.fffffffffffffp0
+exp,0x1.78b56362cef36p-2,-0x1.0000000000001p0
+exp,0x1.78b56362cef38p-2,-0x1.0p0
+exp,0x1.78b56362cef38p-2,-0x1.fffffffffffffp-1
+exp,0x1.9476504ba839ap738,0x1.fffffffffffffp8
+exp,0x1.9476504ba852ep738,0x1.0p9
+exp,0x1.9476504ba8857p738,0x1.0000000000001p9
+exp,0x1.41c7a8814be19p369,0x1.fffffffffffffp7
+exp,0x1.41c7a8814bebap369,0x1.0p8
+exp,0x1.41c7a8814bffcp369,0x1.0000000000001p8
+exp,0x1.95e54c5dd41b2p184,0x1.fffffffffffffp6
+exp,0x1.95e54c5dd4218p184,0x1.0p7
+exp,0x1.95e54c5dd42e2p184,0x1.0000000000001p7
+exp,0x1.425982cf597a5p92,0x1.fffffffffffffp5
+exp,0x1.425982cf597cdp92,0x1.0p6
+exp,0x1.425982cf5981ep92,0x1.0000000000001p6
+exp,0x1.1f43fcc4b661bp46,0x1.fffffffffffffp4
+exp,0x1.1f43fcc4b662cp46,0x1.0p5
+exp,0x1.1f43fcc4b665p46,0x1.0000000000001p5
+exp,0x1.0f2ebd0a80018p23,0x1.fffffffffffffp3
+exp,0x1.0f2ebd0a8002p23,0x1.0p4
+exp,0x1.0f2ebd0a80031p23,0x1.0000000000001p4
+exp,0x1.749ea7d470c68p11,0x1.fffffffffffffp2
+exp,0x1.749ea7d470c6ep11,0x1.0p3
+exp,0x1.749ea7d470c7ap11,0x1.0000000000001p3
+exp,0x1.b4c902e273a55p5,0x1.fffffffffffffp1
+exp,0x1.b4c902e273a58p5,0x1.0p2
+exp,0x1.b4c902e273a5fp5,0x1.0000000000001p2
+exp,0x1.d8e64b8d4ddacp2,0x1.fffffffffffffp0
+exp,0x1.d8e64b8d4ddaep2,0x1.0p1
+exp,0x1.d8e64b8d4ddb2p2,0x1.0000000000001p1
+exp,0x1.5bf0a8b145769p1,0x1.fffffffffffffp-1
+exp,0x1.5bf0a8b14576ap1,0x1.0p0
+exp,0x1.5bf0a8b14576bp1,0x1.0000000000001p0
+exp,0x1.ffc045692fc9ep1023,0x1.62e41ffffffffp9
+exp,0x1.ffc045693009dp1023,0x1.62e42p9
+exp,0x1.ffc045693049dp1023,0x1.62e4200000001p9
+exp,0x0.000000000000ep-1022,-0x1.72e4200000001p9
+exp,0x0.000000000000ep-1022,-0x1.72e42p9
+exp,0x0.000000000000ep-1022,-0x1.72e41ffffffffp9
+exp,0x1.724046eb09339p4,0x1.921fb54442d18p1
+exp,0x1.33dedc855935fp2,0x1.921fb54442d18p0
+exp,0x1.5bf0a8b14576bp1,0x1.0000000000001p0
+exp,0x1.5bf0a8b14576ap1,0x1.0p0
+exp,0x1.5bf0a8b145769p1,0x1.fffffffffffffp-1
+exp,0x1.18bd669471caap1,0x1.921fb54442d18p-1
+exp,0x1.0p0,0x1.0000000000001p-1022
+exp,0x1.0p0,0x1.0p-1022
+exp,0x1.0p0,0x0.fffffffffffffp-1022
+exp,0x1.0p0,0x0.ffffffffffffep-1022
+exp,0x1.0p0,0x0.0000000000002p-1022
+exp,0x1.0p0,0x0.0000000000001p-1022
+exp,0x1.0p0,0x0.0p0
+exp,0x1.0p0,-0x0.0p0
+exp,0x1.0p0,-0x0.0000000000001p-1022
+exp,0x1.0p0,-0x0.0000000000002p-1022
+exp,0x1.0p0,-0x0.ffffffffffffep-1022
+exp,0x1.0p0,-0x0.fffffffffffffp-1022
+exp,0x1.0p0,-0x1.0p-1022
+exp,0x1.0p0,-0x1.0000000000001p-1022
+exp,0x1.d2e171cf04879p-2,-0x1.921fb54442d18p-1
+exp,0x1.78b56362cef38p-2,-0x1.fffffffffffffp-1
+exp,0x1.78b56362cef38p-2,-0x1.0p0
+exp,0x1.78b56362cef36p-2,-0x1.0000000000001p0
+exp,0x1.a9bcc46f767ep-3,-0x1.921fb54442d18p0
+exp,0x1.620227b598efap-5,-0x1.921fb54442d18p1
+exp,0x0.0p0,-0x1.ffffffffffffep1023
+exp,0x0.0p0,-0x1.fffffffffffffp1023
+exp,0x1.fffffffffff2ap1023,0x1.62e42fefa39efp9
+exp,0x1.000000000007cp-1022,-0x1.6232bdd7abcd2p9
+exp,0x0.ffffffffffe7cp-1022,-0x1.6232bdd7abcd3p9
+abs,0x1.5bf0a8b145769p1,0x1.5bf0a8b145769p1,2.718281828459045
+abs,0x1.5bf0a8b145769p1,-0x1.5bf0a8b145769p1,-2.718281828459045
+abs,0x0.0p0,0x0.0p0,0.0
+abs,0x0.0p0,-0x0.0p0,-0.0
+abs,0x1.0p0,0x1.0p0,1.0
+abs,0x1.0p0,-0x1.0p0,-1.0
+abs,0x1.0p-1,-0x1.0p-1,-0.5
+abs,0x1.0p-1,0x1.0p-1,0.5
+abs,0x1.921fb54442d18p2,-0x1.921fb54442d18p2,-6.283185307179586
+abs,0x1.2d97c7f3321d2p2,-0x1.2d97c7f3321d2p2,-4.71238898038469
+abs,0x1.921fb54442d18p1,-0x1.921fb54442d18p1,-3.141592653589793
+abs,0x1.921fb54442d18p0,-0x1.921fb54442d18p0,-1.5707963267948966
+abs,0x0.0p0,0x0.0p0,0.0
+abs,0x1.921fb54442d18p0,0x1.921fb54442d18p0,1.5707963267948966
+abs,0x1.921fb54442d18p1,0x1.921fb54442d18p1,3.141592653589793
+abs,0x1.2d97c7f3321d2p2,0x1.2d97c7f3321d2p2,4.71238898038469
+abs,0x1.921fb54442d18p2,0x1.921fb54442d18p2,6.283185307179586
+acos,0x1.921fb54442d18p0,0x0.0p0,0.0
+acos,0x1.921fb54442d18p0,-0x0.0p0,-0.0
+acos,0x0.0p0,0x1.0p0,1.0
+acos,0x1.921fb54442d18p1,-0x1.0p0,-1.0
+acos,0x1.0c152382d7366p1,-0x1.0p-1,-0.5
+acos,0x1.0c152382d7366p0,0x1.0p-1,0.5
+acos,0x1.921fb54442d18p0,0x0.0p0,0.0
+asin,0x0.0p0,0x0.0p0,0.0
+asin,-0x0.0p0,-0x0.0p0,-0.0
+asin,0x1.921fb54442d18p0,0x1.0p0,1.0
+asin,-0x1.921fb54442d18p0,-0x1.0p0,-1.0
+asin,-0x1.0c152382d7366p-1,-0x1.0p-1,-0.5
+asin,0x1.0c152382d7366p-1,0x1.0p-1,0.5
+asin,0x0.0p0,0x0.0p0,0.0
+atan,0x1.37e1637253389p0,0x1.5bf0a8b145769p1,2.718281828459045
+atan,-0x1.37e1637253389p0,-0x1.5bf0a8b145769p1,-2.718281828459045
+atan,0x0.0p0,0x0.0p0,0.0
+atan,-0x0.0p0,-0x0.0p0,-0.0
+atan,0x1.921fb54442d18p-1,0x1.0p0,1.0
+atan,-0x1.921fb54442d18p-1,-0x1.0p0,-1.0
+atan,-0x1.dac670561bb4fp-2,-0x1.0p-1,-0.5
+atan,0x1.dac670561bb4fp-2,0x1.0p-1,0.5
+atan,-0x1.69b8154baf42ep0,-0x1.921fb54442d18p2,-6.283185307179586
+atan,-0x1.5c97d37d98aa4p0,-0x1.2d97c7f3321d2p2,-4.71238898038469
+atan,-0x1.433b8a322ddd2p0,-0x1.921fb54442d18p1,-3.141592653589793
+atan,-0x1.00fe987ed02ffp0,-0x1.921fb54442d18p0,-1.5707963267948966
+atan,0x0.0p0,0x0.0p0,0.0
+atan,0x1.00fe987ed02ffp0,0x1.921fb54442d18p0,1.5707963267948966
+atan,0x1.433b8a322ddd2p0,0x1.921fb54442d18p1,3.141592653589793
+atan,0x1.5c97d37d98aa4p0,0x1.2d97c7f3321d2p2,4.71238898038469
+atan,0x1.69b8154baf42ep0,0x1.921fb54442d18p2,6.283185307179586
+cos,-0x1.d2cec9a554007p-1,0x1.5bf0a8b145769p1,2.718281828459045
+cos,-0x1.d2cec9a554007p-1,-0x1.5bf0a8b145769p1,-2.718281828459045
+cos,0x1.0p0,0x0.0p0,0.0
+cos,0x1.0p0,-0x0.0p0,-0.0
+cos,0x1.14a280fb5068cp-1,0x1.0p0,1.0
+cos,0x1.14a280fb5068cp-1,-0x1.0p0,-1.0
+cos,0x1.c1528065b7d5p-1,-0x1.0p-1,-0.5
+cos,0x1.c1528065b7d5p-1,0x1.0p-1,0.5
+cos,0x1.0p0,-0x1.921fb54442d18p2,-6.283185307179586
+cos,-0x1.a79394c9e8a0ap-53,-0x1.2d97c7f3321d2p2,-4.71238898038469
+cos,-0x1.0p0,-0x1.921fb54442d18p1,-3.141592653589793
+cos,0x1.1a62633145c07p-54,-0x1.921fb54442d18p0,-1.5707963267948966
+cos,0x1.0p0,0x0.0p0,0.0
+cos,0x1.1a62633145c07p-54,0x1.921fb54442d18p0,1.5707963267948966
+cos,-0x1.0p0,0x1.921fb54442d18p1,3.141592653589793
+cos,-0x1.a79394c9e8a0ap-53,0x1.2d97c7f3321d2p2,4.71238898038469
+cos,0x1.0p0,0x1.921fb54442d18p2,6.283185307179586
+cosh,0x1.e70c4a4f41685p2,0x1.5bf0a8b145769p1,2.718281828459045
+cosh,0x1.e70c4a4f41685p2,-0x1.5bf0a8b145769p1,-2.718281828459045
+cosh,0x1.0p0,0x0.0p0,0.0
+cosh,0x1.0p0,-0x0.0p0,-0.0
+cosh,0x1.8b07551d9f551p0,0x1.0p0,1.0
+cosh,0x1.8b07551d9f551p0,-0x1.0p0,-1.0
+cosh,0x1.20ac1862ae8dp0,-0x1.0p-1,-0.5
+cosh,0x1.20ac1862ae8dp0,0x1.0p-1,0.5
+cosh,0x1.0bbf2bc2b69c6p8,-0x1.921fb54442d18p2,-6.283185307179586
+cosh,0x1.bd4e9aa3e9cdbp5,-0x1.2d97c7f3321d2p2,-4.71238898038469
+cosh,0x1.72f147fee4p3,-0x1.921fb54442d18p1,-3.141592653589793
+cosh,0x1.412cc2a8d4e9ep1,-0x1.921fb54442d18p0,-1.5707963267948966
+cosh,0x1.0p0,0x0.0p0,0.0
+cosh,0x1.412cc2a8d4e9ep1,0x1.921fb54442d18p0,1.5707963267948966
+cosh,0x1.72f147fee4p3,0x1.921fb54442d18p1,3.141592653589793
+cosh,0x1.bd4e9aa3e9cdbp5,0x1.2d97c7f3321d2p2,4.71238898038469
+cosh,0x1.0bbf2bc2b69c6p8,0x1.921fb54442d18p2,6.283185307179586
+exp,0x1.e4efb75e4527ap3,0x1.5bf0a8b145769p1,2.718281828459045
+exp,0x1.0e49787e20548p-4,-0x1.5bf0a8b145769p1,-2.718281828459045
+exp,0x1.0p0,0x0.0p0,0.0
+exp,0x1.0p0,-0x0.0p0,-0.0
+exp,0x1.5bf0a8b14576ap1,0x1.0p0,1.0
+exp,0x1.78b56362cef38p-2,-0x1.0p0,-1.0
+exp,0x1.368b2fc6f960ap-1,-0x1.0p-1,-0.5
+exp,0x1.a61298e1e069cp0,0x1.0p-1,0.5
+exp,0x1.e989f5d6dff5ep-10,-0x1.921fb54442d18p2,-6.283185307179586
+exp,0x1.265d4e92b6b9cp-7,-0x1.2d97c7f3321d2p2,-4.71238898038469
+exp,0x1.620227b598efap-5,-0x1.921fb54442d18p1,-3.141592653589793
+exp,0x1.a9bcc46f767ep-3,-0x1.921fb54442d18p0,-1.5707963267948966
+exp,0x1.0p0,0x0.0p0,0.0
+exp,0x1.33dedc855935fp2,0x1.921fb54442d18p0,1.5707963267948966
+exp,0x1.724046eb09339p4,0x1.921fb54442d18p1,3.141592653589793
+exp,0x1.bd4567b97538p6,0x1.2d97c7f3321d2p2,4.71238898038469
+exp,0x1.0bbeee9177e18p9,0x1.921fb54442d18p2,6.283185307179586
+log,0x1.0p0,0x1.5bf0a8b145769p1,2.718281828459045
+log,0x0.0p0,0x1.0p0,1.0
+log,-0x1.62e42fefa39efp-1,0x1.0p-1,0.5
+log,0x1.ce6bb25aa1315p-2,0x1.921fb54442d18p0,1.5707963267948966
+log,0x1.250d048e7a1bdp0,0x1.921fb54442d18p1,3.141592653589793
+log,0x1.8cd99441787dp0,0x1.2d97c7f3321d2p2,4.71238898038469
+log,0x1.d67f1c864beb4p0,0x1.921fb54442d18p2,6.283185307179586
+log10,0x1.bcb7b1526e50ep-2,0x1.5bf0a8b145769p1,2.718281828459045
+log10,0x0.0p0,0x1.0p0,1.0
+log10,-0x1.34413509f79ffp-2,0x1.0p-1,0.5
+log10,0x1.91a74c4f85377p-3,0x1.921fb54442d18p0,1.5707963267948966
+log10,0x1.fd14db31ba3bap-2,0x1.921fb54442d18p1,3.141592653589793
+log10,0x1.58b30fc65ffdcp-1,0x1.2d97c7f3321d2p2,4.71238898038469
+log10,0x1.98ab081dd8eddp-1,0x1.921fb54442d18p2,6.283185307179586
+sin,0x1.a4a3d9c2131dfp-2,0x1.5bf0a8b145769p1,2.718281828459045
+sin,-0x1.a4a3d9c2131dfp-2,-0x1.5bf0a8b145769p1,-2.718281828459045
+sin,0x0.0p0,0x0.0p0,0.0
+sin,-0x0.0p0,-0x0.0p0,-0.0
+sin,0x1.aed548f090ceep-1,0x1.0p0,1.0
+sin,-0x1.aed548f090ceep-1,-0x1.0p0,-1.0
+sin,-0x1.eaee8744b05fp-2,-0x1.0p-1,-0.5
+sin,0x1.eaee8744b05fp-2,0x1.0p-1,0.5
+sin,0x1.1a62633145c07p-52,-0x1.921fb54442d18p2,-6.283185307179586
+sin,0x1.0p0,-0x1.2d97c7f3321d2p2,-4.71238898038469
+sin,-0x1.1a62633145c07p-53,-0x1.921fb54442d18p1,-3.141592653589793
+sin,-0x1.0p0,-0x1.921fb54442d18p0,-1.5707963267948966
+sin,0x0.0p0,0x0.0p0,0.0
+sin,0x1.0p0,0x1.921fb54442d18p0,1.5707963267948966
+sin,0x1.1a62633145c07p-53,0x1.921fb54442d18p1,3.141592653589793
+sin,-0x1.0p0,0x1.2d97c7f3321d2p2,4.71238898038469
+sin,-0x1.1a62633145c07p-52,0x1.921fb54442d18p2,6.283185307179586
+sinh,0x1.e2d3246d48e6fp2,0x1.5bf0a8b145769p1,2.718281828459045
+sinh,-0x1.e2d3246d48e6fp2,-0x1.5bf0a8b145769p1,-2.718281828459045
+sinh,0x0.0p0,0x0.0p0,0.0
+sinh,-0x0.0p0,-0x0.0p0,-0.0
+sinh,0x1.2cd9fc44eb982p0,0x1.0p0,1.0
+sinh,-0x1.2cd9fc44eb982p0,-0x1.0p0,-1.0
+sinh,-0x1.0acd00fe63b97p-1,-0x1.0p-1,-0.5
+sinh,0x1.0acd00fe63b97p-1,0x1.0p-1,0.5
+sinh,-0x1.0bbeb1603926ap8,-0x1.921fb54442d18p2,-6.283185307179586
+sinh,-0x1.bd3c34cf00a25p5,-0x1.2d97c7f3321d2p2,-4.71238898038469
+sinh,-0x1.718f45d72e672p3,-0x1.921fb54442d18p1,-3.141592653589793
+sinh,-0x1.2690f661dd82p1,-0x1.921fb54442d18p0,-1.5707963267948966
+sinh,0x0.0p0,0x0.0p0,0.0
+sinh,0x1.2690f661dd82p1,0x1.921fb54442d18p0,1.5707963267948966
+sinh,0x1.718f45d72e672p3,0x1.921fb54442d18p1,3.141592653589793
+sinh,0x1.bd3c34cf00a25p5,0x1.2d97c7f3321d2p2,4.71238898038469
+sinh,0x1.0bbeb1603926ap8,0x1.921fb54442d18p2,6.283185307179586
+sqrt,0x1.a61298e1e069cp0,0x1.5bf0a8b145769p1,2.718281828459045
+sqrt,0x0.0p0,0x0.0p0,0.0
+sqrt,-0x0.0p0,-0x0.0p0,-0.0
+sqrt,0x1.0p0,0x1.0p0,1.0
+sqrt,0x1.6a09e667f3bcdp-1,0x1.0p-1,0.5
+sqrt,0x0.0p0,0x0.0p0,0.0
+sqrt,0x1.40d931ff62705p0,0x1.921fb54442d18p0,1.5707963267948966
+sqrt,0x1.c5bf891b4ef6ap0,0x1.921fb54442d18p1,3.141592653589793
+sqrt,0x1.15dce5d1822ccp1,0x1.2d97c7f3321d2p2,4.71238898038469
+sqrt,0x1.40d931ff62705p1,0x1.921fb54442d18p2,6.283185307179586
+tan,-0x1.cd5cdb683b402p-2,0x1.5bf0a8b145769p1,2.718281828459045
+tan,0x1.cd5cdb683b402p-2,-0x1.5bf0a8b145769p1,-2.718281828459045
+tan,0x0.0p0,0x0.0p0,0.0
+tan,-0x0.0p0,-0x0.0p0,-0.0
+tan,0x1.8eb245cbee3a6p0,0x1.0p0,1.0
+tan,-0x1.8eb245cbee3a6p0,-0x1.0p0,-1.0
+tan,-0x1.17b4f5bf3474ap-1,-0x1.0p-1,-0.5
+tan,0x1.17b4f5bf3474ap-1,0x1.0p-1,0.5
+tan,0x1.1a62633145c07p-52,-0x1.921fb54442d18p2,-6.283185307179586
+tan,-0x1.3570efd768923p52,-0x1.2d97c7f3321d2p2,-4.71238898038469
+tan,0x1.1a62633145c07p-53,-0x1.921fb54442d18p1,-3.141592653589793
+tan,-0x1.d02967c31cdb5p53,-0x1.921fb54442d18p0,-1.5707963267948966
+tan,0x0.0p0,0x0.0p0,0.0
+tan,0x1.d02967c31cdb5p53,0x1.921fb54442d18p0,1.5707963267948966
+tan,-0x1.1a62633145c07p-53,0x1.921fb54442d18p1,3.141592653589793
+tan,0x1.3570efd768923p52,0x1.2d97c7f3321d2p2,4.71238898038469
+tan,-0x1.1a62633145c07p-52,0x1.921fb54442d18p2,6.283185307179586
+tanh,0x1.fb8f76b1e2ab6p-1,0x1.5bf0a8b145769p1,2.718281828459045
+tanh,-0x1.fb8f76b1e2ab6p-1,-0x1.5bf0a8b145769p1,-2.718281828459045
+tanh,0x0.0p0,0x0.0p0,0.0
+tanh,-0x0.0p0,-0x0.0p0,-0.0
+tanh,0x1.85efab514f394p-1,0x1.0p0,1.0
+tanh,-0x1.85efab514f394p-1,-0x1.0p0,-1.0
+tanh,-0x1.d9353d7568af3p-2,-0x1.0p-1,-0.5
+tanh,0x1.d9353d7568af3p-2,0x1.0p-1,0.5
+tanh,-0x1.ffff15f81f9abp-1,-0x1.921fb54442d18p2,-6.283185307179586
+tanh,-0x1.ffead8c8b7e1ep-1,-0x1.2d97c7f3321d2p2,-4.71238898038469
+tanh,-0x1.fe175fa29281p-1,-0x1.921fb54442d18p1,-3.141592653589793
+tanh,-0x1.d594fdae482bap-1,-0x1.921fb54442d18p0,-1.5707963267948966
+tanh,0x0.0p0,0x0.0p0,0.0
+tanh,0x1.d594fdae482bap-1,0x1.921fb54442d18p0,1.5707963267948966
+tanh,0x1.fe175fa29281p-1,0x1.921fb54442d18p1,3.141592653589793
+tanh,0x1.ffead8c8b7e1ep-1,0x1.2d97c7f3321d2p2,4.71238898038469
+tanh,0x1.ffff15f81f9abp-1,0x1.921fb54442d18p2,6.283185307179586
diff --git a/luni/src/test/resources/org/apache/harmony/tests/java/lang/test#.properties b/luni/src/test/resources/org/apache/harmony/tests/java/lang/test#.properties
new file mode 100644
index 0000000..299569a
--- /dev/null
+++ b/luni/src/test/resources/org/apache/harmony/tests/java/lang/test#.properties
@@ -0,0 +1 @@
+This is a resource file with a # in the name \ No newline at end of file
diff --git a/luni/src/test/resources/org/apache/harmony/tests/java/lang/test.properties b/luni/src/test/resources/org/apache/harmony/tests/java/lang/test.properties
new file mode 100644
index 0000000..2a248d0
--- /dev/null
+++ b/luni/src/test/resources/org/apache/harmony/tests/java/lang/test.properties
@@ -0,0 +1 @@
+This is just a resource file for getResource() tests \ No newline at end of file
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.0.ser b/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.0.ser
deleted file mode 100644
index b9a4d75..0000000
--- a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.0.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.1.ser b/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.1.ser
deleted file mode 100644
index 6fe88ee..0000000
--- a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.1.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.2.ser b/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.2.ser
deleted file mode 100644
index 8ef8f0b..0000000
--- a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.2.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.3.ser b/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.3.ser
deleted file mode 100644
index 00ac616..0000000
--- a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.golden.3.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.harmony.ser b/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.harmony.ser
deleted file mode 100644
index 8ef8f0b..0000000
--- a/luni/src/test/resources/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.harmony.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDClass.ser b/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDClass.ser
deleted file mode 100644
index b93df24..0000000
--- a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDClass.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDConstructors.ser b/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDConstructors.ser
deleted file mode 100644
index a333f4e..0000000
--- a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDConstructors.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDFields.ser b/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDFields.ser
deleted file mode 100644
index 7f93135..0000000
--- a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDFields.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDInterfaces.ser b/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDInterfaces.ser
deleted file mode 100644
index c579d14..0000000
--- a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDInterfaces.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDMethods.ser b/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDMethods.ser
deleted file mode 100644
index 48618eb..0000000
--- a/luni/src/test/resources/serialization/tests/api/java/io/testComputeSUIDMethods.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/util/EnumMapTest.golden.ser b/luni/src/test/resources/serialization/tests/api/java/util/EnumMapTest.golden.ser
deleted file mode 100644
index 76f7668..0000000
--- a/luni/src/test/resources/serialization/tests/api/java/util/EnumMapTest.golden.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/api/java/util/EnumSetTest.golden.ser b/luni/src/test/resources/serialization/tests/api/java/util/EnumSetTest.golden.ser
deleted file mode 100644
index 66040e5..0000000
--- a/luni/src/test/resources/serialization/tests/api/java/util/EnumSetTest.golden.ser
+++ /dev/null
Binary files differ
diff --git a/luni/src/test/resources/serialization/tests/security/cert/CertificateRevocationExceptionTest.golden.ser b/luni/src/test/resources/serialization/tests/security/cert/CertificateRevocationExceptionTest.golden.ser
new file mode 100644
index 0000000..f9f2746
--- /dev/null
+++ b/luni/src/test/resources/serialization/tests/security/cert/CertificateRevocationExceptionTest.golden.ser
Binary files differ
diff --git a/luni/src/test/resources/tests/resources/java/util/zip/EmptyArchive.zip b/luni/src/test/resources/tests/resources/java/util/zip/EmptyArchive.zip
new file mode 100644
index 0000000..15cb0ec
--- /dev/null
+++ b/luni/src/test/resources/tests/resources/java/util/zip/EmptyArchive.zip
Binary files differ
diff --git a/support/src/test/java/libcore/dalvik/system/CloseGuardTester.java b/support/src/test/java/libcore/dalvik/system/CloseGuardTester.java
deleted file mode 100644
index e82d33d..0000000
--- a/support/src/test/java/libcore/dalvik/system/CloseGuardTester.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.dalvik.system;
-
-import dalvik.system.CloseGuard;
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Handler;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-import junit.framework.Assert;
-import libcore.java.lang.ref.FinalizationTester;
-
-public final class CloseGuardTester implements Closeable {
-
- private final List<LogRecord> logRecords = new CopyOnWriteArrayList<LogRecord>();
- private final Logger logger = Logger.getLogger(CloseGuard.class.getName());
-
- private final Handler logWatcher = new Handler() {
- @Override public void close() {}
- @Override public void flush() {}
- @Override public void publish(LogRecord record) {
- logRecords.add(record);
- }
- };
-
- public CloseGuardTester() {
- /*
- * Collect immediately before we start monitoring the CloseGuard logs.
- * This lowers the chance that we'll report an unrelated leak.
- */
- FinalizationTester.induceFinalization();
- logger.addHandler(logWatcher);
- }
-
- public void assertEverythingWasClosed() {
- FinalizationTester.induceFinalization();
-
- if (!logRecords.isEmpty()) {
- // print the log records with the output of this test
- for (LogRecord leak : logRecords) {
- new ConsoleHandler().publish(leak);
- }
- Assert.fail("CloseGuard detected unclosed resources!");
- }
- }
-
- @Override public void close() throws IOException {
- Logger.getLogger(CloseGuard.class.getName()).removeHandler(logWatcher);
- }
-}
diff --git a/support/src/test/java/libcore/java/lang/ref/FinalizationTester.java b/support/src/test/java/libcore/java/lang/ref/FinalizationTester.java
index 66ac1a4..d758317 100644
--- a/support/src/test/java/libcore/java/lang/ref/FinalizationTester.java
+++ b/support/src/test/java/libcore/java/lang/ref/FinalizationTester.java
@@ -26,7 +26,9 @@ public final class FinalizationTester {
private FinalizationTester() {}
public static void induceFinalization() {
- System.gc();
+ // System.gc() does not garbage collect every time. Runtime.gc() is
+ // more likely to perfom a gc.
+ Runtime.getRuntime().gc();
enqueueReferences();
System.runFinalization();
}
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index 42ddcfa..528a651 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -24,11 +24,11 @@ import java.security.spec.ECPublicKeySpec;
import java.security.spec.KeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
@@ -49,12 +49,12 @@ import junit.framework.Assert;
* </a>.
*
* Updated based on the
- * <a href="http://download.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html">
+ * <a href="http://download.java.net/jdk8/docs/technotes/guides/security/SunProviders.html">
* Java &trade; Cryptography Architecture Oracle Providers Documentation
* for Java &trade; Platform Standard Edition 7
* </a>.
* See also the
- * <a href="http://download.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html">
+ * <a href="http://download.java.net/jdk8/docs/technotes/guides/security/StandardNames.html">
* Java &trade; Cryptography Architecture Standard Algorithm Name Documentation
* </a>.
*
@@ -143,6 +143,7 @@ public final class StandardNames extends Assert {
provide("AlgorithmParameters", "DESede");
provide("AlgorithmParameters", "DSA");
provide("AlgorithmParameters", "DiffieHellman");
+ provide("AlgorithmParameters", "GCM");
provide("AlgorithmParameters", "OAEP");
provide("AlgorithmParameters", "PBEWithMD5AndDES");
provide("AlgorithmParameters", "PBEWithMD5AndTripleDES");
@@ -164,6 +165,7 @@ public final class StandardNames extends Assert {
provide("Cipher", "DES");
provide("Cipher", "DESede");
provide("Cipher", "DESedeWrap");
+ provide("Cipher", "GCM");
provide("Cipher", "PBEWithMD5AndDES");
provide("Cipher", "PBEWithMD5AndTripleDES");
provide("Cipher", "PBEWithSHA1AndDESede");
@@ -186,6 +188,7 @@ public final class StandardNames extends Assert {
provide("KeyGenerator", "DESede");
provide("KeyGenerator", "HmacMD5");
provide("KeyGenerator", "HmacSHA1");
+ provide("KeyGenerator", "HmacSHA224");
provide("KeyGenerator", "HmacSHA256");
provide("KeyGenerator", "HmacSHA384");
provide("KeyGenerator", "HmacSHA512");
@@ -200,12 +203,14 @@ public final class StandardNames extends Assert {
provide("KeyStore", "PKCS12");
provide("Mac", "HmacMD5");
provide("Mac", "HmacSHA1");
+ provide("Mac", "HmacSHA224");
provide("Mac", "HmacSHA256");
provide("Mac", "HmacSHA384");
provide("Mac", "HmacSHA512");
// If adding a new MessageDigest, consider adding it to JarVerifier
provide("MessageDigest", "MD2");
provide("MessageDigest", "MD5");
+ provide("MessageDigest", "SHA-224");
provide("MessageDigest", "SHA-256");
provide("MessageDigest", "SHA-384");
provide("MessageDigest", "SHA-512");
@@ -227,7 +232,10 @@ public final class StandardNames extends Assert {
provide("Signature", "MD5withRSA");
provide("Signature", "NONEwithDSA");
provide("Signature", "SHA1withDSA");
+ provide("Signature", "SHA224withDSA");
+ provide("Signature", "SHA256withDSA");
provide("Signature", "SHA1withRSA");
+ provide("Signature", "SHA224withRSA");
provide("Signature", "SHA256withRSA");
provide("Signature", "SHA384withRSA");
provide("Signature", "SHA512withRSA");
@@ -309,6 +317,7 @@ public final class StandardNames extends Assert {
provide("Signature", "NONEWITHECDSA");
provide("Signature", "RAWDSA");
provide("Signature", "SHA1WITHECDSA");
+ provide("Signature", "SHA224WITHECDSA");
provide("Signature", "SHA256WITHECDSA");
provide("Signature", "SHA384WITHECDSA");
provide("Signature", "SHA512WITHECDSA");
@@ -439,22 +448,34 @@ public final class StandardNames extends Assert {
// Needed by our OpenSSL provider
provide("Cipher", "AES/CBC/NOPADDING");
provide("Cipher", "AES/CBC/PKCS5PADDING");
+ provide("Cipher", "AES/CBC/PKCS7PADDING");
provide("Cipher", "AES/CFB/NOPADDING");
provide("Cipher", "AES/CFB/PKCS5PADDING");
+ provide("Cipher", "AES/CFB/PKCS7PADDING");
provide("Cipher", "AES/CTR/NOPADDING");
provide("Cipher", "AES/CTR/PKCS5PADDING");
+ provide("Cipher", "AES/CTR/PKCS7PADDING");
provide("Cipher", "AES/ECB/NOPADDING");
provide("Cipher", "AES/ECB/PKCS5PADDING");
+ provide("Cipher", "AES/ECB/PKCS7PADDING");
provide("Cipher", "AES/OFB/NOPADDING");
provide("Cipher", "AES/OFB/PKCS5PADDING");
+ provide("Cipher", "AES/OFB/PKCS7PADDING");
provide("Cipher", "DESEDE/CBC/NOPADDING");
provide("Cipher", "DESEDE/CBC/PKCS5PADDING");
+ provide("Cipher", "DESEDE/CBC/PKCS7PADDING");
provide("Cipher", "DESEDE/CFB/NOPADDING");
provide("Cipher", "DESEDE/CFB/PKCS5PADDING");
+ provide("Cipher", "DESEDE/CFB/PKCS7PADDING");
provide("Cipher", "DESEDE/ECB/NOPADDING");
provide("Cipher", "DESEDE/ECB/PKCS5PADDING");
+ provide("Cipher", "DESEDE/ECB/PKCS7PADDING");
provide("Cipher", "DESEDE/OFB/NOPADDING");
provide("Cipher", "DESEDE/OFB/PKCS5PADDING");
+ provide("Cipher", "DESEDE/OFB/PKCS7PADDING");
+
+ // Provided by our OpenSSL provider
+ provideCipherPaddings("AES", new String[] { "PKCS7Padding" });
// removed LDAP
unprovide("CertStore", "LDAP");
@@ -493,6 +514,7 @@ public final class StandardNames extends Assert {
provide("KeyPairGenerator", "EC");
provide("Signature", "NONEWITHECDSA");
provide("Signature", "ECDSA"); // as opposed to SHA1WITHECDSA
+ provide("Signature", "SHA224WITHECDSA");
provide("Signature", "SHA256WITHECDSA");
provide("Signature", "SHA384WITHECDSA");
provide("Signature", "SHA512WITHECDSA");
@@ -528,12 +550,18 @@ public final class StandardNames extends Assert {
public static final Set<String> KEY_TYPES = new HashSet<String>(Arrays.asList(
"RSA",
"DSA",
- // DH_* are specified by standard names, but do not seem to be supported by RI
- // "DH_RSA",
- // "DH_DSA",
+ "DH_RSA",
+ "DH_DSA",
"EC",
"EC_EC",
"EC_RSA"));
+ static {
+ if (IS_RI) {
+ // DH_* are specified by standard names, but do not seem to be supported by RI
+ KEY_TYPES.remove("DH_RSA");
+ KEY_TYPES.remove("DH_DSA");
+ }
+ }
public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<String>(Arrays.asList(
// "SSLv2",
@@ -541,6 +569,18 @@ public final class StandardNames extends Assert {
"TLSv1",
"TLSv1.1",
"TLSv1.2"));
+ public static final Set<String> SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT =
+ new HashSet<String>(Arrays.asList(
+ "SSLv3",
+ "TLSv1",
+ "TLSv1.1",
+ "TLSv1.2"));
+ public static final Set<String> SSL_SOCKET_PROTOCOLS_SERVER_DEFAULT =
+ new HashSet<String>(Arrays.asList(
+ "SSLv3",
+ "TLSv1",
+ "TLSv1.1",
+ "TLSv1.2"));
static {
if (IS_RI) {
/* Even though we use OpenSSL's SSLv23_method which
@@ -553,15 +593,6 @@ public final class StandardNames extends Assert {
}
}
- public static final Set<String> SSL_SOCKET_PROTOCOLS_SSLENGINE = new HashSet<String>(SSL_SOCKET_PROTOCOLS);
- static {
- // No TLSv1.1 or TLSv1.2 support on SSLEngine based provider
- if (!IS_RI) {
- SSL_SOCKET_PROTOCOLS_SSLENGINE.remove("TLSv1.1");
- SSL_SOCKET_PROTOCOLS_SSLENGINE.remove("TLSv1.2");
- }
- }
-
/**
* Valid values for X509TrustManager.checkClientTrusted authType,
* either the algorithm of the public key or UNKNOWN.
@@ -624,29 +655,15 @@ public final class StandardNames extends Assert {
}
static {
- // Note these are added in priority order as defined by RI 7 documentation.
- // defaultCipherSuites
- addNeither("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
- addNeither("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
- addNeither("TLS_RSA_WITH_AES_256_CBC_SHA256");
- addNeither("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384");
- addNeither("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384");
- addNeither("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256");
- addNeither("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256");
- addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
- addOpenSsl("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
- addOpenSsl("TLS_RSA_WITH_AES_256_CBC_SHA");
- addOpenSsl("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
- addOpenSsl("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA");
- addOpenSsl("TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
- addOpenSsl("TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
- addRi( "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
- addRi( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
- addRi( "TLS_RSA_WITH_AES_128_CBC_SHA256");
- addRi( "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256");
- addRi( "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256");
- addRi( "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256");
- addRi( "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256");
+ // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
+ // javax.net.ssl.SSLEngine.
+ addBoth( "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
+ addBoth( "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
+ addBoth( "TLS_RSA_WITH_AES_256_CBC_SHA");
+ addBoth( "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
+ addBoth( "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA");
+ addBoth( "TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
+ addBoth( "TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
addBoth( "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
addBoth( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
addBoth( "TLS_RSA_WITH_AES_128_CBC_SHA");
@@ -667,6 +684,50 @@ public final class StandardNames extends Assert {
addBoth( "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
addBoth( "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
addBoth( "SSL_RSA_WITH_RC4_128_MD5");
+
+ // TLSv1.2 cipher suites
+ addBoth( "TLS_RSA_WITH_NULL_SHA256");
+ addBoth( "TLS_RSA_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_RSA_WITH_AES_256_CBC_SHA256");
+ addOpenSsl("TLS_RSA_WITH_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_RSA_WITH_AES_256_GCM_SHA384");
+ addBoth( "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256");
+ addOpenSsl("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384");
+ addBoth( "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256");
+ addOpenSsl("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384");
+ addBoth( "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384");
+ addOpenSsl("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384");
+ addBoth( "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384");
+ addOpenSsl("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384");
+ addBoth( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
+ addOpenSsl("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384");
+ addBoth( "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
+ addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
+ addBoth( "TLS_DH_anon_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_DH_anon_WITH_AES_256_CBC_SHA256");
+ addOpenSsl("TLS_DH_anon_WITH_AES_128_GCM_SHA256");
+ addOpenSsl("TLS_DH_anon_WITH_AES_256_GCM_SHA384");
+
+ // Pre-Shared Key (PSK) cipher suites
+ addOpenSsl("TLS_PSK_WITH_RC4_128_SHA");
+ addOpenSsl("TLS_PSK_WITH_3DES_EDE_CBC_SHA");
+ addOpenSsl("TLS_PSK_WITH_AES_128_CBC_SHA");
+ addOpenSsl("TLS_PSK_WITH_AES_256_CBC_SHA");
+ addOpenSsl("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA");
+ addOpenSsl("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA");
+
// RFC 5746's Signaling Cipher Suite Value to indicate a request for secure renegotiation
addBoth(CIPHER_SUITE_SECURE_RENEGOTIATION);
@@ -675,17 +736,14 @@ public final class StandardNames extends Assert {
addOpenSsl(CIPHER_SUITE_FALLBACK);
// non-defaultCipherSuites
- addNeither("TLS_DH_anon_WITH_AES_256_CBC_SHA256");
- addOpenSsl("TLS_ECDH_anon_WITH_AES_256_CBC_SHA");
- addOpenSsl("TLS_DH_anon_WITH_AES_256_CBC_SHA");
- addRi( "TLS_DH_anon_WITH_AES_128_CBC_SHA256");
+ addBoth( "TLS_ECDH_anon_WITH_AES_256_CBC_SHA");
+ addBoth( "TLS_DH_anon_WITH_AES_256_CBC_SHA");
addBoth( "TLS_ECDH_anon_WITH_AES_128_CBC_SHA");
addBoth( "TLS_DH_anon_WITH_AES_128_CBC_SHA");
addBoth( "TLS_ECDH_anon_WITH_RC4_128_SHA");
addBoth( "SSL_DH_anon_WITH_RC4_128_MD5");
addBoth( "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA");
addBoth( "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA");
- addRi( "TLS_RSA_WITH_NULL_SHA256");
addBoth( "TLS_ECDHE_ECDSA_WITH_NULL_SHA");
addBoth( "TLS_ECDHE_RSA_WITH_NULL_SHA");
addBoth( "SSL_RSA_WITH_NULL_SHA");
@@ -732,79 +790,118 @@ public final class StandardNames extends Assert {
CIPHER_SUITES = (IS_RI) ? CIPHER_SUITES_RI : CIPHER_SUITES_OPENSSL;
}
+ /**
+ * Cipher suites that are not negotiated when TLSv1.2 is selected on the RI.
+ */
+ public static final List<String> CIPHER_SUITES_OBSOLETE_TLS12 =
+ Arrays.asList(
+ "SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_DH_anon_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"
+ );
+
+ // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
+ // javax.net.ssl.SSLEngine.
public static final List<String> CIPHER_SUITES_DEFAULT = (IS_RI)
- ? Arrays.asList("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
- "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
- "SSL_RSA_WITH_RC4_128_SHA",
- "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
- "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
- "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDH_RSA_WITH_RC4_128_SHA",
- "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
- "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
+ ? Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
+ "TLS_RSA_WITH_AES_256_CBC_SHA256",
+ "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
+ "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
+ "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
+ "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
+ "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+ "TLS_RSA_WITH_AES_256_CBC_SHA",
+ "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
+ "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
+ "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
+ "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
+ "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
+ "TLS_RSA_WITH_AES_128_CBC_SHA256",
+ "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
+ "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
+ "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
- "SSL_RSA_WITH_RC4_128_MD5",
+ "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
+ "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
- "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
- "SSL_RSA_WITH_3DES_EDE_CBC_SHA")
- : Arrays.asList("SSL_RSA_WITH_RC4_128_MD5",
+ "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+ "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"SSL_RSA_WITH_RC4_128_SHA",
- "TLS_RSA_WITH_AES_128_CBC_SHA",
- "TLS_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
- "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDH_RSA_WITH_RC4_128_SHA",
- "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+ "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
+ "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+ "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
+ "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+ "SSL_RSA_WITH_RC4_128_MD5",
+ "TLS_EMPTY_RENEGOTIATION_INFO_SCSV")
+ : Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
- "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
- "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
- "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
- "SSL_RSA_WITH_DES_CBC_SHA",
- "SSL_DHE_RSA_WITH_DES_CBC_SHA",
- "SSL_DHE_DSS_WITH_DES_CBC_SHA",
- "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
- "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
- "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
- "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+ "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+ "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+ "TLS_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
+ "TLS_RSA_WITH_AES_256_CBC_SHA",
+ "SSL_RSA_WITH_RC4_128_SHA",
CIPHER_SUITE_SECURE_RENEGOTIATION);
- public static final Set<String> CIPHER_SUITES_SSLENGINE = new HashSet<String>(CIPHER_SUITES);
- static {
- // No Elliptic Curve support on SSLEngine based provider
- if (!IS_RI) {
- Iterator<String> i = CIPHER_SUITES_SSLENGINE.iterator();
- while (i.hasNext()) {
- String cs = i.next();
- if (cs.startsWith("TLS_EC")
- || cs.equals(CIPHER_SUITE_SECURE_RENEGOTIATION)
- || cs.equals(CIPHER_SUITE_FALLBACK)) {
- i.remove();
- }
- }
- }
- }
+ // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
+ // javax.net.ssl.SSLEngine.
+ public static final List<String> CIPHER_SUITES_DEFAULT_PSK = Arrays.asList(
+ "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
+ "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
+ "TLS_PSK_WITH_AES_128_CBC_SHA",
+ "TLS_PSK_WITH_AES_256_CBC_SHA"
+ );
+
+ private static final Set<String> PERMITTED_DEFAULT_KEY_EXCHANGE_ALGS =
+ new HashSet<String>(Arrays.asList("RSA",
+ "DHE_RSA",
+ "DHE_DSS",
+ "ECDHE_RSA",
+ "ECDHE_ECDSA"));
+
+ private static final Set<String> PERMITTED_DEFAULT_BULK_ENCRYPTION_CIPHERS =
+ new HashSet<String>(Arrays.asList("RC4_128",
+ "AES_128_CBC",
+ "AES_256_CBC",
+ "AES_128_GCM",
+ "AES_256_GCM"));
+
+ private static final Set<String> PERMITTED_DEFAULT_MACS =
+ new HashSet<String>(Arrays.asList("SHA",
+ "SHA256",
+ "SHA384"));
public static final Map<String, Class<? extends KeySpec>> PRIVATE_KEY_SPEC_CLASSES;
public static final Map<String, Class<? extends KeySpec>> PUBLIC_KEY_SPEC_CLASSES;
@@ -815,7 +912,7 @@ public final class StandardNames extends Assert {
MINIMUM_KEY_SIZE = new HashMap<String, Integer>();
PRIVATE_KEY_SPEC_CLASSES.put("RSA", RSAPrivateCrtKeySpec.class);
PUBLIC_KEY_SPEC_CLASSES.put("RSA", RSAPublicKeySpec.class);
- MINIMUM_KEY_SIZE.put("RSA", 256);
+ MINIMUM_KEY_SIZE.put("RSA", 512);
PRIVATE_KEY_SPEC_CLASSES.put("DSA", DSAPrivateKeySpec.class);
PUBLIC_KEY_SPEC_CLASSES.put("DSA", DSAPublicKeySpec.class);
MINIMUM_KEY_SIZE.put("DSA", 512);
@@ -909,11 +1006,119 @@ public final class StandardNames extends Assert {
}
/**
- * Assert cipher suites match the default list in content and priority order.
+ * Asserts that the protocols array is non-null and that all of its contents are supported
+ * protocols.
*/
- public static void assertDefaultCipherSuites(String[] cipherSuites) {
+ public static void assertValidProtocols(String[] protocols) {
+ assertValidProtocols(SSL_SOCKET_PROTOCOLS, protocols);
+ }
+
+ /**
+ * Asserts that the provided list of protocols matches the supported list of protocols.
+ */
+ public static void assertSupportedProtocols(String[] protocols) {
+ assertSupportedProtocols(SSL_SOCKET_PROTOCOLS, protocols);
+ }
+
+ /**
+ * Asserts that the protocols array contains all the protocols enabled by default for client use
+ * and no other ones.
+ */
+ public static void assertDefaultProtocolsClient(String[] protocols) {
+ assertValidProtocols(protocols);
+ assertSupportedProtocols(SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT, protocols);
+ }
+
+ /**
+ * Asserts that the protocols array contains all the protocols enabled by default for server use
+ * and no other ones.
+ */
+ public static void assertDefaultProtocolsServer(String[] protocols) {
+ assertValidProtocols(protocols);
+ assertSupportedProtocols(SSL_SOCKET_PROTOCOLS_SERVER_DEFAULT, protocols);
+ }
+
+ /**
+ * Asserts that the protocols array contains all the protocols enabled by default for
+ * {@link javax.net.ssl.SSLEngine} and no other ones.
+ */
+ public static void assertSSLEngineDefaultProtocols(String[] protocols) {
+ assertValidProtocols(protocols);
+ assertSupportedProtocols(SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT, protocols);
+ }
+
+ /**
+ * Assert that the provided list of cipher suites contains only the supported cipher suites.
+ */
+ public static void assertValidCipherSuites(String[] cipherSuites) {
assertValidCipherSuites(CIPHER_SUITES, cipherSuites);
+ }
+
+ /**
+ * Assert that the provided list of cipher suites matches the supported list.
+ */
+ public static void assertSupportedCipherSuites(String[] cipherSuites) {
+ assertSupportedCipherSuites(CIPHER_SUITES, cipherSuites);
+ }
+
+ /**
+ * Assert cipher suites match the default list in content and priority order and contain
+ * only cipher suites permitted by default.
+ */
+ public static void assertDefaultCipherSuites(String[] cipherSuites) {
+ assertValidCipherSuites(cipherSuites);
assertEquals(CIPHER_SUITES_DEFAULT, Arrays.asList(cipherSuites));
+
+ // Assert that all the cipher suites are permitted to be in the default list.
+ // This assertion is a backup for the stricter assertion above.
+ //
+ // There is no point in asserting this for the RI as it's outside of our control.
+ if (!IS_RI) {
+ List<String> disallowedDefaultCipherSuites = new ArrayList<String>();
+ for (String cipherSuite : cipherSuites) {
+ if (!isPermittedDefaultCipherSuite(cipherSuite)) {
+ disallowedDefaultCipherSuites.add(cipherSuite);
+ }
+ }
+ assertEquals(Collections.EMPTY_LIST, disallowedDefaultCipherSuites);
+ }
+ }
+
+ private static boolean isPermittedDefaultCipherSuite(String cipherSuite) {
+ assertNotNull(cipherSuite);
+ if (CIPHER_SUITE_SECURE_RENEGOTIATION.equals(cipherSuite)) {
+ return true;
+ }
+ assertTrue(cipherSuite, cipherSuite.startsWith("TLS_") || cipherSuite.startsWith("SSL_"));
+
+ // Example: RSA_WITH_AES_128_CBC_SHA
+ String remainder = cipherSuite.substring("TLS_".length());
+ int macDelimiterIndex = remainder.lastIndexOf('_');
+ assertTrue(cipherSuite, macDelimiterIndex != -1);
+ // Example: SHA
+ String mac = remainder.substring(macDelimiterIndex + 1);
+
+ // Example: RSA_WITH_AES_128_CBC
+ remainder = remainder.substring(0, macDelimiterIndex);
+ int withDelimiterIndex = remainder.indexOf("_WITH_");
+ assertTrue(cipherSuite, withDelimiterIndex != -1);
+
+ // Example: RSA
+ String keyExchange = remainder.substring(0, withDelimiterIndex);
+ // Example: AES_128_CBC
+ String bulkEncryptionCipher = remainder.substring(withDelimiterIndex + "_WITH_".length());
+
+ if (!PERMITTED_DEFAULT_MACS.contains(mac)) {
+ return false;
+ }
+ if (!PERMITTED_DEFAULT_KEY_EXCHANGE_ALGS.contains(keyExchange)) {
+ return false;
+ }
+ if (!PERMITTED_DEFAULT_BULK_ENCRYPTION_CIPHERS.contains(bulkEncryptionCipher)) {
+ return false;
+ }
+
+ return true;
}
/**
diff --git a/support/src/test/java/libcore/java/security/TestKeyStore.java b/support/src/test/java/libcore/java/security/TestKeyStore.java
index aee7f8a..203c028 100644
--- a/support/src/test/java/libcore/java/security/TestKeyStore.java
+++ b/support/src/test/java/libcore/java/security/TestKeyStore.java
@@ -54,6 +54,7 @@ import java.security.cert.X509Certificate;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@@ -78,6 +79,7 @@ public final class TestKeyStore extends Assert {
private static TestKeyStore ROOT_CA;
private static TestKeyStore INTERMEDIATE_CA;
+ private static TestKeyStore INTERMEDIATE_CA_2;
private static TestKeyStore SERVER;
private static TestKeyStore CLIENT;
@@ -101,7 +103,6 @@ public final class TestKeyStore extends Assert {
public final char[] keyPassword;
public final KeyManager[] keyManagers;
public final TrustManager[] trustManagers;
- public final TestKeyManager keyManager;
public final TestTrustManager trustManager;
private TestKeyStore(KeyStore keyStore, char[] storePassword, char[] keyPassword) {
@@ -110,7 +111,6 @@ public final class TestKeyStore extends Assert {
this.keyPassword = keyPassword;
this.keyManagers = createKeyManagers(keyStore, storePassword);
this.trustManagers = createTrustManagers(keyStore);
- this.keyManager = (TestKeyManager)keyManagers[0];
this.trustManager = (TestTrustManager)trustManagers[0];
}
@@ -155,11 +155,16 @@ public final class TestKeyStore extends Assert {
.signer(ROOT_CA.getPrivateKey("RSA", "RSA"))
.rootCa(ROOT_CA.getRootCertificate("RSA"))
.build();
- SERVER = new Builder()
- .aliasPrefix("server")
- .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA"))
- .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA"))
- .build();
+ try {
+ SERVER = new Builder()
+ .aliasPrefix("server")
+ .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA"))
+ .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA"))
+ .addSubjectAltNameIpAddress(InetAddress.getLocalHost().getAddress())
+ .build();
+ } catch (UnknownHostException e) {
+ throw new RuntimeException(e);
+ }
CLIENT = new TestKeyStore(createClient(INTERMEDIATE_CA.keyStore), null, null);
CLIENT_CERTIFICATE = new Builder()
.aliasPrefix("client")
@@ -172,6 +177,13 @@ public final class TestKeyStore extends Assert {
.subject("CN=Test Root Certificate Authority 2")
.ca(true)
.build();
+ INTERMEDIATE_CA_2 = new Builder()
+ .aliasPrefix("IntermediateCA")
+ .subject("CN=Test Intermediate Certificate Authority")
+ .ca(true)
+ .signer(rootCa2.getPrivateKey("RSA", "RSA"))
+ .rootCa(rootCa2.getRootCertificate("RSA"))
+ .build();
CLIENT_2 = new TestKeyStore(createClient(rootCa2.keyStore), null, null);
}
@@ -192,6 +204,14 @@ public final class TestKeyStore extends Assert {
}
/**
+ * Return an intermediate CA that can be used to issue new certificates.
+ */
+ public static TestKeyStore getIntermediateCa2() {
+ initCerts();
+ return INTERMEDIATE_CA_2;
+ }
+
+ /**
* Return a server keystore with a matched RSA certificate and
* private key as well as a CA certificate.
*/
@@ -352,10 +372,15 @@ public final class TestKeyStore extends Assert {
for (String keyAlgorithm : keyAlgorithms) {
String publicAlias = aliasPrefix + "-public-" + keyAlgorithm;
String privateAlias = aliasPrefix + "-private-" + keyAlgorithm;
- if (keyAlgorithm.equals("EC_RSA") && signer == null && rootCa == null) {
+ if ((keyAlgorithm.equals("EC_RSA") || keyAlgorithm.equals("DH_RSA"))
+ && signer == null && rootCa == null) {
createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias,
privateKey(keyStore, keyPassword, "RSA", "RSA"));
continue;
+ } else if (keyAlgorithm.equals("DH_DSA") && signer == null && rootCa == null) {
+ createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias,
+ privateKey(keyStore, keyPassword, "DSA", "DSA"));
+ continue;
}
createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias, signer);
}
@@ -417,8 +442,14 @@ public final class TestKeyStore extends Assert {
if (keyAlgorithm.equals("RSA")) {
// 512 breaks SSL_RSA_EXPORT_* on RI and TLS_ECDHE_RSA_WITH_RC4_128_SHA for us
keySize = 1024;
+ } else if (keyAlgorithm.equals("DH_RSA")) {
+ keySize = 512;
+ keyAlgorithm = "DH";
} else if (keyAlgorithm.equals("DSA")) {
keySize = 512;
+ } else if (keyAlgorithm.equals("DH_DSA")) {
+ keySize = 512;
+ keyAlgorithm = "DH";
} else if (keyAlgorithm.equals("EC")) {
keySize = 256;
} else if (keyAlgorithm.equals("EC_RSA")) {
@@ -576,14 +607,6 @@ public final class TestKeyStore extends Assert {
excludedNameConstraints.size()])));
}
- if (privateKey instanceof ECPrivateKey) {
- /*
- * bouncycastle needs its own ECPrivateKey implementation
- */
- KeyFactory kf = KeyFactory.getInstance(keyAlgorithm, "BC");
- PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(privateKey.getEncoded());
- privateKey = kf.generatePrivate(ks);
- }
X509Certificate x509c = x509cg.generateX509Certificate(privateKey);
if (StandardNames.IS_RI) {
/*
@@ -675,7 +698,7 @@ public final class TestKeyStore extends Assert {
continue;
}
if (found != null) {
- throw new IllegalStateException("KeyStore has more than one private key for "
+ throw new IllegalStateException("KeyStore has more than one private key for"
+ " keyAlgorithm: " + keyAlgorithm
+ " signatureAlgorithm: " + signatureAlgorithm
+ "\nfirst: " + found.getPrivateKey()
@@ -684,13 +707,14 @@ public final class TestKeyStore extends Assert {
found = privateKey;
}
if (found == null) {
- throw new IllegalStateException("KeyStore contained no private key for "
+ throw new IllegalStateException("KeyStore contained no private key for"
+ " keyAlgorithm: " + keyAlgorithm
+ " signatureAlgorithm: " + signatureAlgorithm);
}
return found;
} catch (Exception e) {
- throw new RuntimeException(e);
+ throw new RuntimeException("Problem getting key for " + keyAlgorithm
+ + " and signature " + signatureAlgorithm, e);
}
}
diff --git a/support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java b/support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java
index fd5cc0b..ce40129 100644
--- a/support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java
+++ b/support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java
@@ -21,6 +21,7 @@ import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
+import java.security.interfaces.ECPrivateKey;
import java.security.spec.DSAParameterSpec;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.RSAPrivateKeySpec;
@@ -71,6 +72,10 @@ public class RandomPrivateKeyX509ExtendedKeyManager extends ForwardingX509Extend
keyPairGenerator.initialize(new DSAParameterSpec(
originalKeySpec.getP(), originalKeySpec.getQ(), originalKeySpec.getG()));
result = keyPairGenerator.generateKeyPair().getPrivate();
+ } else if ("EC".equals(keyAlgorithm)) {
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyAlgorithm);
+ keyPairGenerator.initialize(((ECPrivateKey) originalPrivateKey).getParams());
+ result = keyPairGenerator.generateKeyPair().getPrivate();
} else {
Assert.fail("Unsupported key algorithm: " + originalPrivateKey.getAlgorithm());
result = null;
diff --git a/support/src/test/java/libcore/javax/net/ssl/SSLDefaultConfigurationAsserts.java b/support/src/test/java/libcore/javax/net/ssl/SSLDefaultConfigurationAsserts.java
new file mode 100644
index 0000000..d54f5e5
--- /dev/null
+++ b/support/src/test/java/libcore/javax/net/ssl/SSLDefaultConfigurationAsserts.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import junit.framework.Assert;
+import libcore.java.security.StandardNames;
+
+/**
+ * Assertions about the default configuration of TLS/SSL primitives.
+ */
+public abstract class SSLDefaultConfigurationAsserts extends Assert {
+
+ /** Hidden constructor to prevent instantiation. */
+ private SSLDefaultConfigurationAsserts() {}
+
+ /**
+ * Asserts that the provided {@link SSLContext} has the expected default configuration.
+ */
+ public static void assertSSLContext(SSLContext sslContext) throws IOException {
+ assertDefaultSSLParametersClient(sslContext.getDefaultSSLParameters());
+ assertSupportedSSLParametersClient(sslContext.getSupportedSSLParameters());
+ assertSSLSocketFactory(sslContext.getSocketFactory());
+ assertSSLServerSocketFactory(sslContext.getServerSocketFactory());
+ assertSSLEngine(sslContext.createSSLEngine());
+ assertSSLEngine(sslContext.createSSLEngine(null, -1));
+ }
+
+ /**
+ * Asserts that the provided {@link SSLSocketFactory} has the expected default configuration.
+ */
+ public static void assertSSLSocketFactory(SSLSocketFactory sslSocketFactory) throws IOException {
+ StandardNames.assertDefaultCipherSuites(sslSocketFactory.getDefaultCipherSuites());
+ StandardNames.assertSupportedCipherSuites(sslSocketFactory.getSupportedCipherSuites());
+ assertContainsAll("Unsupported default cipher suites",
+ sslSocketFactory.getSupportedCipherSuites(),
+ sslSocketFactory.getDefaultCipherSuites());
+
+ assertSSLSocket((SSLSocket) sslSocketFactory.createSocket());
+ }
+
+ /**
+ * Asserts that the provided {@link SSLServerSocketFactory} has the expected default
+ * configuration.
+ */
+ public static void assertSSLServerSocketFactory(SSLServerSocketFactory sslServerSocketFactory)
+ throws IOException {
+ StandardNames.assertDefaultCipherSuites(sslServerSocketFactory.getDefaultCipherSuites());
+ StandardNames.assertSupportedCipherSuites(sslServerSocketFactory.getSupportedCipherSuites());
+ assertContainsAll("Unsupported default cipher suites",
+ sslServerSocketFactory.getSupportedCipherSuites(),
+ sslServerSocketFactory.getDefaultCipherSuites());
+
+ assertSSLServerSocket((SSLServerSocket) sslServerSocketFactory.createServerSocket());
+ }
+
+ /**
+ * Asserts that the provided {@link SSLSocket} has the expected default configuration.
+ */
+ public static void assertSSLSocket(SSLSocket sslSocket) {
+ assertSSLParametersClient(sslSocket.getSSLParameters());
+
+ StandardNames.assertDefaultCipherSuites(sslSocket.getEnabledCipherSuites());
+ StandardNames.assertSupportedCipherSuites(sslSocket.getSupportedCipherSuites());
+ assertContainsAll("Unsupported enabled cipher suites",
+ sslSocket.getSupportedCipherSuites(),
+ sslSocket.getEnabledCipherSuites());
+
+ StandardNames.assertDefaultProtocolsClient(sslSocket.getEnabledProtocols());
+ StandardNames.assertSupportedProtocols(sslSocket.getSupportedProtocols());
+ assertContainsAll("Unsupported enabled protocols",
+ sslSocket.getSupportedProtocols(),
+ sslSocket.getEnabledProtocols());
+
+ assertTrue(sslSocket.getUseClientMode());
+ assertTrue(sslSocket.getEnableSessionCreation());
+ assertFalse(sslSocket.getNeedClientAuth());
+ assertFalse(sslSocket.getWantClientAuth());
+ }
+
+ /**
+ * Asserts that the provided {@link SSLServerSocket} has the expected default configuration.
+ */
+ public static void assertSSLServerSocket(SSLServerSocket sslServerSocket) {
+ // TODO: Check SSLParameters when supported by SSLServerSocket API
+
+ StandardNames.assertDefaultCipherSuites(sslServerSocket.getEnabledCipherSuites());
+ StandardNames.assertSupportedCipherSuites(sslServerSocket.getSupportedCipherSuites());
+ assertContainsAll("Unsupported enabled cipher suites",
+ sslServerSocket.getSupportedCipherSuites(),
+ sslServerSocket.getEnabledCipherSuites());
+
+ StandardNames.assertDefaultProtocolsServer(sslServerSocket.getEnabledProtocols());
+ StandardNames.assertSupportedProtocols(sslServerSocket.getSupportedProtocols());
+ assertContainsAll("Unsupported enabled protocols",
+ sslServerSocket.getSupportedProtocols(),
+ sslServerSocket.getEnabledProtocols());
+
+ assertTrue(sslServerSocket.getEnableSessionCreation());
+ assertFalse(sslServerSocket.getNeedClientAuth());
+ assertFalse(sslServerSocket.getWantClientAuth());
+ }
+
+ /**
+ * Asserts that the provided {@link SSLEngine} has the expected default configuration.
+ */
+ public static void assertSSLEngine(SSLEngine sslEngine) {
+ assertFalse(sslEngine.getUseClientMode());
+ assertSSLEngineSSLParameters(sslEngine.getSSLParameters());
+
+ StandardNames.assertDefaultCipherSuites(sslEngine.getEnabledCipherSuites());
+ StandardNames.assertSupportedCipherSuites(sslEngine.getSupportedCipherSuites());
+ assertContainsAll("Unsupported enabled cipher suites",
+ sslEngine.getSupportedCipherSuites(),
+ sslEngine.getEnabledCipherSuites());
+
+ StandardNames.assertSSLEngineDefaultProtocols(sslEngine.getEnabledProtocols());
+ StandardNames.assertSupportedProtocols(sslEngine.getSupportedProtocols());
+ assertContainsAll("Unsupported enabled protocols",
+ sslEngine.getSupportedProtocols(),
+ sslEngine.getEnabledProtocols());
+
+ assertTrue(sslEngine.getEnableSessionCreation());
+ assertFalse(sslEngine.getNeedClientAuth());
+ assertFalse(sslEngine.getWantClientAuth());
+ }
+
+ /**
+ * Asserts that the provided {@link SSLParameters} describe the expected default configuration
+ * for client-side mode of operation.
+ */
+ public static void assertSSLParametersClient(SSLParameters sslParameters) {
+ assertDefaultSSLParametersClient(sslParameters);
+ }
+
+ /**
+ * Asserts that the provided default {@link SSLParameters} are as expected for client-side mode of
+ * operation.
+ */
+ private static void assertDefaultSSLParametersClient(SSLParameters sslParameters) {
+ StandardNames.assertDefaultCipherSuites(sslParameters.getCipherSuites());
+ StandardNames.assertDefaultProtocolsClient(sslParameters.getProtocols());
+ assertFalse(sslParameters.getWantClientAuth());
+ assertFalse(sslParameters.getNeedClientAuth());
+ }
+
+ /**
+ * Asserts that the provided supported {@link SSLParameters} are as expected for client-side mode
+ * of operation.
+ */
+ private static void assertSupportedSSLParametersClient(SSLParameters sslParameters) {
+ StandardNames.assertSupportedCipherSuites(sslParameters.getCipherSuites());
+ StandardNames.assertSupportedProtocols(sslParameters.getProtocols());
+ assertFalse(sslParameters.getWantClientAuth());
+ assertFalse(sslParameters.getNeedClientAuth());
+ }
+
+ /**
+ * Asserts that the provided {@link SSLParameters} has the expected default configuration for
+ * {@link SSLEngine}.
+ */
+ public static void assertSSLEngineSSLParameters(SSLParameters sslParameters) {
+ StandardNames.assertDefaultCipherSuites(sslParameters.getCipherSuites());
+ StandardNames.assertSSLEngineDefaultProtocols(sslParameters.getProtocols());
+ assertFalse(sslParameters.getWantClientAuth());
+ assertFalse(sslParameters.getNeedClientAuth());
+ }
+
+ /**
+ * Asserts that the {@code container} contains all the {@code elements}.
+ */
+ private static void assertContainsAll(String message, String[] container, String[] elements) {
+ Set<String> elementsNotInContainer = new HashSet<String>(Arrays.asList(elements));
+ elementsNotInContainer.removeAll(Arrays.asList(container));
+ assertEquals(message, Collections.EMPTY_SET, elementsNotInContainer);
+ }
+}
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java b/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
index 5c424bc..8dd2085 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
@@ -33,7 +33,6 @@ import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509TrustManager;
import junit.framework.Assert;
import libcore.java.security.StandardNames;
@@ -81,8 +80,8 @@ public final class TestSSLContext extends Assert {
public final char[] clientStorePassword;
public final KeyStore serverKeyStore;
public final char[] serverStorePassword;
- public final X509ExtendedKeyManager clientKeyManager;
- public final X509ExtendedKeyManager serverKeyManager;
+ public final KeyManager[] clientKeyManagers;
+ public final KeyManager[] serverKeyManagers;
public final X509TrustManager clientTrustManager;
public final X509TrustManager serverTrustManager;
public final SSLContext clientContext;
@@ -95,8 +94,8 @@ public final class TestSSLContext extends Assert {
char[] clientStorePassword,
KeyStore serverKeyStore,
char[] serverStorePassword,
- X509ExtendedKeyManager clientKeyManager,
- X509ExtendedKeyManager serverKeyManager,
+ KeyManager[] clientKeyManagers,
+ KeyManager[] serverKeyManagers,
X509TrustManager clientTrustManager,
X509TrustManager serverTrustManager,
SSLContext clientContext,
@@ -108,8 +107,8 @@ public final class TestSSLContext extends Assert {
this.clientStorePassword = clientStorePassword;
this.serverKeyStore = serverKeyStore;
this.serverStorePassword = serverStorePassword;
- this.clientKeyManager = clientKeyManager;
- this.serverKeyManager = serverKeyManager;
+ this.clientKeyManagers = clientKeyManagers;
+ this.serverKeyManagers = serverKeyManagers;
this.clientTrustManager = clientTrustManager;
this.serverTrustManager = serverTrustManager;
this.clientContext = clientContext;
@@ -141,20 +140,27 @@ public final class TestSSLContext extends Assert {
* TestSSLContext creation method that allows separate creation of server key store
*/
public static TestSSLContext create(TestKeyStore client, TestKeyStore server) {
- String provider = StandardNames.JSSE_PROVIDER_NAME;
- return create(client, server, provider, provider);
+ return createWithAdditionalKeyManagers(client, server, null, null);
}
- public static TestSSLContext create(TestKeyStore client, TestKeyStore server,
- String clientProvider, String serverProvider) {
- String protocol = "TLS";
- SSLContext clientContext = createSSLContext(protocol, clientProvider,
- client.keyManagers, client.trustManagers);
- SSLContext serverContext = createSSLContext(protocol, serverProvider,
- server.keyManagers, server.trustManagers);
+
+ /**
+ * TestSSLContext creation method that allows separate creation of server key store and
+ * the use of additional {@code KeyManager} instances
+ */
+ public static TestSSLContext createWithAdditionalKeyManagers(
+ TestKeyStore client, TestKeyStore server,
+ KeyManager[] additionalClientKeyManagers, KeyManager[] additionalServerKeyManagers) {
+ String protocol = "TLSv1.2";
+ KeyManager[] clientKeyManagers = concat(client.keyManagers, additionalClientKeyManagers);
+ KeyManager[] serverKeyManagers = concat(server.keyManagers, additionalServerKeyManagers);
+ SSLContext clientContext =
+ createSSLContext(protocol, clientKeyManagers, client.trustManagers);
+ SSLContext serverContext =
+ createSSLContext(protocol, serverKeyManagers, server.trustManagers);
return create(client.keyStore, client.storePassword,
server.keyStore, server.storePassword,
- client.keyManagers[0],
- server.keyManagers[0],
+ clientKeyManagers,
+ serverKeyManagers,
client.trustManagers[0],
server.trustManagers[0],
clientContext,
@@ -166,8 +172,8 @@ public final class TestSSLContext extends Assert {
*/
public static TestSSLContext create(KeyStore clientKeyStore, char[] clientStorePassword,
KeyStore serverKeyStore, char[] serverStorePassword,
- KeyManager clientKeyManagers,
- KeyManager serverKeyManagers,
+ KeyManager[] clientKeyManagers,
+ KeyManager[] serverKeyManagers,
TrustManager clientTrustManagers,
TrustManager serverTrustManagers,
SSLContext clientContext,
@@ -180,8 +186,8 @@ public final class TestSSLContext extends Assert {
return new TestSSLContext(clientKeyStore, clientStorePassword,
serverKeyStore, serverStorePassword,
- (X509ExtendedKeyManager) clientKeyManagers,
- (X509ExtendedKeyManager) serverKeyManagers,
+ clientKeyManagers,
+ serverKeyManagers,
(X509TrustManager) clientTrustManagers,
(X509TrustManager) serverTrustManagers,
clientContext, serverContext,
@@ -199,12 +205,11 @@ public final class TestSSLContext extends Assert {
* using the certificates authorities from the same KeyStore.
*/
public static final SSLContext createSSLContext(final String protocol,
- final String provider,
final KeyManager[] keyManagers,
final TrustManager[] trustManagers)
{
try {
- SSLContext context = SSLContext.getInstance(protocol, provider);
+ SSLContext context = SSLContext.getInstance(protocol);
context.init(keyManagers, trustManagers, new SecureRandom());
return context;
} catch (Exception e) {
@@ -302,4 +307,17 @@ public final class TestSSLContext extends Assert {
}
};
}
+
+ private static KeyManager[] concat(KeyManager[] a, KeyManager[] b) {
+ if ((a == null) || (a.length == 0)) {
+ return b;
+ }
+ if ((b == null) || (b.length == 0)) {
+ return a;
+ }
+ KeyManager[] result = new KeyManager[a.length + b.length];
+ System.arraycopy(a, 0, result, 0, a.length);
+ System.arraycopy(b, 0, result, a.length, b.length);
+ return result;
+ }
}
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java b/support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java
index b6efdeb..709f568 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java
@@ -47,10 +47,19 @@ public final class TestSSLEnginePair extends Assert {
}
public static TestSSLEnginePair create(TestSSLContext c, Hooks hooks) throws IOException {
- SSLEngine[] engines = connect(c, hooks);
+ return create(c, hooks, null);
+ }
+
+ public static TestSSLEnginePair create(TestSSLContext c, Hooks hooks, boolean[] finished)
+ throws IOException {
+ SSLEngine[] engines = connect(c, hooks, finished);
return new TestSSLEnginePair(c, engines[0], engines[1]);
}
+ public static SSLEngine[] connect(TestSSLContext c, Hooks hooks) throws IOException {
+ return connect(c, hooks, null);
+ }
+
/**
* Create a new connected server/client engine pair within a
* existing SSLContext. Optionally specify clientCipherSuites to
@@ -59,11 +68,16 @@ public final class TestSSLEnginePair extends Assert {
* cipher suite negotiation.
*/
public static SSLEngine[] connect(final TestSSLContext c,
- Hooks hooks) throws IOException {
+ Hooks hooks,
+ boolean finished[]) throws IOException {
if (hooks == null) {
hooks = new Hooks();
}
+ // FINISHED state should be returned only once.
+ boolean[] clientFinished = new boolean[1];
+ boolean[] serverFinished = new boolean[1];
+
SSLSession session = c.clientContext.createSSLEngine().getSession();
int packetBufferSize = session.getPacketBufferSize();
@@ -73,7 +87,7 @@ public final class TestSSLEnginePair extends Assert {
int applicationBufferSize = session.getApplicationBufferSize();
ByteBuffer scratch = ByteBuffer.allocate(applicationBufferSize);
- SSLEngine client = c.clientContext.createSSLEngine();
+ SSLEngine client = c.clientContext.createSSLEngine(c.host.getHostName(), c.port);
SSLEngine server = c.serverContext.createSSLEngine();
client.setUseClientMode(true);
server.setUseClientMode(false);
@@ -93,20 +107,26 @@ public final class TestSSLEnginePair extends Assert {
progress |= handshakeCompleted(client,
clientToServer,
serverToClient,
- scratch);
+ scratch,
+ clientFinished);
}
if (!serverDone) {
progress |= handshakeCompleted(server,
serverToClient,
clientToServer,
- scratch);
+ scratch,
+ serverFinished);
}
if (!progress) {
- // let caller detect the problem, but don't just hang here
break;
}
}
+ if (finished != null) {
+ assertEquals(2, finished.length);
+ finished[0] = clientFinished[0];
+ finished[1] = serverFinished[0];
+ }
return new SSLEngine[] { server, client };
}
@@ -119,7 +139,8 @@ public final class TestSSLEnginePair extends Assert {
private static boolean handshakeCompleted(SSLEngine engine,
ByteBuffer output,
ByteBuffer input,
- ByteBuffer scratch) throws IOException {
+ ByteBuffer scratch,
+ boolean[] finished) throws IOException {
try {
// make the other side's output into our input
input.flip();
@@ -127,7 +148,7 @@ public final class TestSSLEnginePair extends Assert {
HandshakeStatus status = engine.getHandshakeStatus();
switch (status) {
- case NEED_TASK:
+ case NEED_TASK: {
boolean progress = false;
while (true) {
Runnable runnable = engine.getDelegatedTask();
@@ -137,8 +158,9 @@ public final class TestSSLEnginePair extends Assert {
runnable.run();
progress = true;
}
+ }
- case NEED_UNWRAP:
+ case NEED_UNWRAP: {
// avoid underflow
if (input.remaining() == 0) {
return false;
@@ -146,16 +168,20 @@ public final class TestSSLEnginePair extends Assert {
SSLEngineResult unwrapResult = engine.unwrap(input, scratch);
assertEquals(SSLEngineResult.Status.OK, unwrapResult.getStatus());
assertEquals(0, scratch.position());
+ assertFinishedOnce(finished, unwrapResult);
return true;
+ }
- case NEED_WRAP:
+ case NEED_WRAP: {
// avoid possible overflow
if (output.remaining() != output.capacity()) {
return false;
}
SSLEngineResult wrapResult = engine.wrap(EMPTY_BYTE_BUFFER, output);
assertEquals(SSLEngineResult.Status.OK, wrapResult.getStatus());
+ assertFinishedOnce(finished, wrapResult);
return true;
+ }
case NOT_HANDSHAKING:
// should have been checked by caller before calling
@@ -170,4 +196,11 @@ public final class TestSSLEnginePair extends Assert {
input.compact();
}
}
+
+ private static void assertFinishedOnce(boolean[] finishedOut, SSLEngineResult result) {
+ if (result.getHandshakeStatus() == HandshakeStatus.FINISHED) {
+ assertFalse("should only return FINISHED once", finishedOut[0]);
+ finishedOut[0] = true;
+ }
+ }
}
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java b/support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java
index c3511b4..dc4bb28 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java
@@ -17,6 +17,8 @@
package libcore.javax.net.ssl;
import java.io.PrintStream;
+import java.net.Socket;
+import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
@@ -45,10 +47,10 @@ public final class TestTrustManager implements X509TrustManager {
}
public static TrustManager wrap(TrustManager trustManager) {
- if (!(trustManager instanceof X509TrustManager)) {
- return trustManager;
+ if (trustManager instanceof X509TrustManager) {
+ return new TestTrustManager((X509TrustManager) trustManager);
}
- return new TestTrustManager((X509TrustManager) trustManager);
+ return trustManager;
}
public TestTrustManager(X509TrustManager trustManager) {
diff --git a/support/src/test/java/org/apache/harmony/testframework/CharSinkTester.java b/support/src/test/java/org/apache/harmony/testframework/CharSinkTester.java
new file mode 100644
index 0000000..7a1ce25
--- /dev/null
+++ b/support/src/test/java/org/apache/harmony/testframework/CharSinkTester.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.testframework;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Tests behaviour common to all implementations of {@link Writer}. This adapts
+ * writers that collects untransformed chars so that they may be tested.
+ */
+public abstract class CharSinkTester {
+
+ private boolean throwsExceptions = true;
+
+ /**
+ * Creates a new writer ready to receive an arbitrary number of chars. Each
+ * time this method is invoked, any previously returned writers may be
+ * discarded.
+ */
+ public abstract Writer create() throws Exception;
+
+ /**
+ * Returns the current set of chars written to the writer last returned by
+ * {@link #create}, and releases any resources held by that writer.
+ */
+ public abstract char[] getChars() throws Exception;
+
+ /**
+ * Configures whether the writer is expected to throw exceptions when an
+ * error is encountered. Classes like {@code PrintWriter} report errors via
+ * an API method instead.
+ */
+ public CharSinkTester setThrowsExceptions(boolean throwsExceptions) {
+ this.throwsExceptions = throwsExceptions;
+ return this;
+ }
+
+ public final TestSuite createTests() {
+ TestSuite result = new TestSuite();
+ result.addTest(new SinkTestCase("sinkTestNoWriting"));
+ result.addTest(new SinkTestCase("sinkTestWriteZeroChars"));
+ result.addTest(new SinkTestCase("sinkTestWriteCharByChar"));
+ result.addTest(new SinkTestCase("sinkTestWriteArray"));
+ result.addTest(new SinkTestCase("sinkTestWriteOffset"));
+ result.addTest(new SinkTestCase("sinkTestWriteLargeArray"));
+
+ if (throwsExceptions) {
+ result.addTest(new SinkTestCase("sinkTestWriteAfterClose"));
+ } else {
+ result.addTest(new SinkTestCase("sinkTestWriteAfterCloseSuppressed"));
+ }
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getName();
+ }
+
+ private static void assertArrayEquals(char[] expected, char[] actual) {
+ Assert.assertEquals(Arrays.toString(expected), Arrays.toString(actual));
+ }
+
+ public class SinkTestCase extends TestCase {
+
+ private SinkTestCase(String name) {
+ super(name);
+ }
+
+ public void sinkTestNoWriting() throws Exception {
+ char[] expected = new char[] { };
+
+ Writer out = create();
+ out.close();
+ assertArrayEquals(expected, getChars());
+ }
+
+ public void sinkTestWriteZeroChars() throws Exception {
+ char[] expected = new char[] { };
+
+ Writer out = create();
+ char[] a = new char[1024];
+ out.write(a, 1000, 0);
+ out.write(a, 0, 0);
+ out.write(new char[] { });
+
+ out.close();
+ assertArrayEquals(expected, getChars());
+ }
+
+ public void sinkTestWriteCharByChar() throws Exception {
+ char[] expected = "EFGCDECBA".toCharArray();
+
+ Writer out = create();
+ for (char c : expected) {
+ out.write(c);
+ }
+
+ out.close();
+ assertArrayEquals(expected, getChars());
+ }
+
+ public void sinkTestWriteArray() throws Exception {
+ char[] expected = "EFGCDECBA".toCharArray();
+
+ Writer out = create();
+
+ out.write("EF".toCharArray());
+ out.write("GCDE".toCharArray());
+ out.write("CBA".toCharArray());
+
+ out.close();
+ assertArrayEquals(expected, getChars());
+ }
+
+ public void sinkTestWriteOffset() throws Exception {
+ char[] expected = "EFGCDECBA".toCharArray();
+ Writer out = create();
+
+ char[] a = new char[1024];
+ a[1000] = 'E';
+ a[1001] = 'F';
+ out.write(a, 1000, 2);
+
+ char[] b = new char[1024];
+ b[1020] = 'G';
+ b[1021] = 'C';
+ b[1022] = 'D';
+ b[1023] = 'E';
+ out.write(b, 1020, 4);
+
+ char[] c = new char[1024];
+ c[0] = 'C';
+ c[1] = 'B';
+ c[2] = 'A';
+ out.write(c, 0, 3);
+
+ out.close();
+ assertArrayEquals(expected, getChars());
+ }
+
+ public void sinkTestWriteLargeArray() throws Exception {
+ Random dice = new Random();
+ char[] expected = new char[(1024 * 1024) + 1]; // 2 MB + 1 char
+ for (int c = 0; c < expected.length; c++) {
+ expected[c] = (char) ('A' + dice.nextInt(26));
+ }
+
+ Writer out = create();
+ out.write(expected);
+ out.close();
+
+ assertArrayEquals(expected, getChars());
+ }
+
+ public void sinkTestWriteAfterClose() throws Exception {
+ char[] expectedChars = "EF".toCharArray();
+ Writer out = create();
+
+ out.write(expectedChars);
+ out.close();
+
+ try {
+ out.write("GCDE".toCharArray());
+ fail("expected already closed exception");
+ } catch (IOException expected) {
+ }
+
+ assertArrayEquals(expectedChars, getChars());
+ }
+
+ public void sinkTestWriteAfterCloseSuppressed() throws Exception {
+ Writer out = create();
+ out.write("EF".toCharArray());
+ out.close();
+ out.write("GCDE".toCharArray()); // no exception expected!
+ }
+
+ // adding a new test? Don't forget to update createTests().
+
+ @Override
+ public String getName() {
+ return CharSinkTester.this.toString() + ":" + super.getName();
+ }
+ }
+}
diff --git a/support/src/test/java/org/apache/harmony/testframework/CharWrapperTester.java b/support/src/test/java/org/apache/harmony/testframework/CharWrapperTester.java
new file mode 100644
index 0000000..3bbebf2
--- /dev/null
+++ b/support/src/test/java/org/apache/harmony/testframework/CharWrapperTester.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.testframework;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * Tests behaviour common to wrapping and filtering implementations of {@link
+ * Writer}.
+ */
+public abstract class CharWrapperTester {
+
+ private boolean throwsExceptions = true;
+
+ /**
+ * Creates a new output stream that receives one stream of chars, optionally
+ * transforms it, and emits another stream of chars to {@code delegate}.
+ */
+ public abstract Writer create(Writer delegate) throws Exception;
+
+ /**
+ * Decodes the chars received by the delegate into their original form: the
+ * chars originally received by this wrapper.
+ */
+ public abstract char[] decode(char[] delegateChars) throws Exception;
+
+ /**
+ * Configures whether the writer is expected to throw exceptions when an
+ * error is encountered. Classes like {@code PrintWriter} report errors via
+ * an API method instead.
+ */
+ public CharWrapperTester setThrowsExceptions(boolean throwsExceptions) {
+ this.throwsExceptions = throwsExceptions;
+ return this;
+ }
+
+ public final TestSuite createTests() {
+ TestSuite result = new TestSuite();
+ result.addTest(new WrapperSinkTester()
+ .setThrowsExceptions(throwsExceptions)
+ .createTests());
+
+ if (throwsExceptions) {
+ result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlush"));
+ result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaClose"));
+ result.addTest(new WrapperTestCase("wrapperTestCloseThrows"));
+ } else {
+ result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlushSuppressed"));
+ result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaCloseSuppressed"));
+ result.addTest(new WrapperTestCase("wrapperTestCloseThrowsSuppressed"));
+ }
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getName();
+ }
+
+ private class WrapperSinkTester extends CharSinkTester {
+ private ClosableStringWriter delegate;
+
+ @Override
+ public Writer create() throws Exception {
+ delegate = new ClosableStringWriter();
+ return CharWrapperTester.this.create(delegate);
+ }
+
+ @Override
+ public char[] getChars() throws Exception {
+ return decode(delegate.buffer.toString().toCharArray());
+ }
+
+ @Override
+ public String toString() {
+ return CharWrapperTester.this.toString();
+ }
+ }
+
+ public class WrapperTestCase extends TestCase {
+
+ private WrapperTestCase(String name) {
+ super(name);
+ }
+
+ @Override
+ public String getName() {
+ return CharWrapperTester.this.toString() + ":" + super.getName();
+ }
+
+ public void wrapperTestFlushThrowsViaFlushSuppressed() throws Exception {
+ FailOnFlushWriter delegate = new FailOnFlushWriter();
+ Writer o = create(delegate);
+ o.write("BUT");
+ o.write("TERS");
+ o.flush();
+ assertTrue(delegate.flushed);
+ }
+
+ public void wrapperTestFlushThrowsViaCloseSuppressed() throws Exception {
+ FailOnFlushWriter delegate = new FailOnFlushWriter();
+ Writer o = create(delegate);
+ o.write("BUT");
+ o.write("TERS");
+ o.close();
+ assertTrue(delegate.flushed);
+ }
+
+ public void wrapperTestFlushThrowsViaFlush() throws Exception {
+ FailOnFlushWriter delegate = new FailOnFlushWriter();
+
+ Writer o = create(delegate);
+ try {
+ // any of these is permitted to flush
+ o.write("BUT");
+ o.write("TERS");
+ o.flush();
+ assertTrue(delegate.flushed);
+ fail("flush exception ignored");
+ } catch (IOException expected) {
+ assertEquals("Flush failed", expected.getMessage());
+ }
+ }
+
+ public void wrapperTestFlushThrowsViaClose() throws Exception {
+ FailOnFlushWriter delegate = new FailOnFlushWriter();
+
+ Writer o = create(delegate);
+ try {
+ // any of these is permitted to flush
+ o.write("BUT");
+ o.write("TERS");
+ o.close();
+ assertTrue(delegate.flushed);
+ fail("flush exception ignored");
+ } catch (IOException expected) {
+ assertEquals("Flush failed", expected.getMessage());
+ }
+
+ try {
+ o.write("BARK");
+ fail("expected already closed exception");
+ } catch (IOException expected) {
+ }
+ }
+
+ public void wrapperTestCloseThrows() throws Exception {
+ FailOnCloseWriter delegate = new FailOnCloseWriter();
+ Writer o = create(delegate);
+ try {
+ o.close();
+ assertTrue(delegate.closed);
+ fail("close exception ignored");
+ } catch (IOException expected) {
+ assertEquals("Close failed", expected.getMessage());
+ }
+ }
+
+ public void wrapperTestCloseThrowsSuppressed() throws Exception {
+ FailOnCloseWriter delegate = new FailOnCloseWriter();
+ Writer o = create(delegate);
+ o.close();
+ assertTrue(delegate.closed);
+ }
+
+ // adding a new test? Don't forget to update createTests().
+ }
+
+ /**
+ * A custom Writer that respects the closed state. The built-in StringWriter
+ * doesn't respect close(), which makes testing wrapped streams difficult.
+ */
+ private static class ClosableStringWriter extends Writer {
+ private final StringBuilder buffer = new StringBuilder();
+ private boolean closed = false;
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ }
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ @Override
+ public void write(char[] buf, int offset, int count) throws IOException {
+ if (closed) {
+ throw new IOException();
+ }
+ buffer.append(buf, offset, count);
+ }
+ }
+
+ private static class FailOnFlushWriter extends Writer {
+ boolean flushed = false;
+ boolean closed = false;
+
+ @Override
+ public void write(char[] buf, int offset, int count) throws IOException {
+ if (closed) {
+ throw new IOException("Already closed");
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ flush();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ if (!flushed) {
+ flushed = true;
+ throw new IOException("Flush failed");
+ }
+ }
+ }
+
+ private static class FailOnCloseWriter extends Writer {
+ boolean closed = false;
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ @Override
+ public void write(char[] buf, int offset, int count) throws IOException {
+ }
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ throw new IOException("Close failed");
+ }
+ }
+} \ No newline at end of file
diff --git a/support/src/test/java/org/apache/harmony/testframework/SinkTester.java b/support/src/test/java/org/apache/harmony/testframework/SinkTester.java
new file mode 100644
index 0000000..6c12384
--- /dev/null
+++ b/support/src/test/java/org/apache/harmony/testframework/SinkTester.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.testframework;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Tests behaviour common to all implementations of {@link OutputStream}. This
+ * adapts streams that collects untransformed bytes so that they may be tested.
+ */
+public abstract class SinkTester {
+
+ private boolean throwsExceptions = true;
+
+ /**
+ * Creates a new output stream ready to receive an arbitrary number of
+ * bytes. Each time this method is invoked, any previously returned output
+ * streams may be discarded.
+ */
+ public abstract OutputStream create() throws Exception;
+
+ /**
+ * Returns the current set of bytes written to the output stream last
+ * returned by {@link #create}, and releases any resources held by that
+ * stream.
+ */
+ public abstract byte[] getBytes() throws Exception;
+
+ /**
+ * Configures whether the stream is expected to throw exceptions when an
+ * error is encountered. Classes like {@code PrintStream} report errors via
+ * an API method instead.
+ */
+ public SinkTester setThrowsExceptions(boolean throwsExceptions) {
+ this.throwsExceptions = throwsExceptions;
+ return this;
+ }
+
+ public final TestSuite createTests() {
+ TestSuite result = new TestSuite();
+ result.addTest(new SinkTestCase("sinkTestNoWriting"));
+ result.addTest(new SinkTestCase("sinkTestWriteZeroBytes"));
+ result.addTest(new SinkTestCase("sinkTestWriteByteByByte"));
+ result.addTest(new SinkTestCase("sinkTestWriteArray"));
+ result.addTest(new SinkTestCase("sinkTestWriteOffset"));
+ result.addTest(new SinkTestCase("sinkTestWriteLargeArray"));
+
+ if (throwsExceptions) {
+ result.addTest(new SinkTestCase("sinkTestWriteAfterClose"));
+ } else {
+ result.addTest(new SinkTestCase("sinkTestWriteAfterCloseSuppressed"));
+ }
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getName();
+ }
+
+ private static void assertArrayEquals(byte[] expected, byte[] actual) {
+ Assert.assertEquals(Arrays.toString(expected), Arrays.toString(actual));
+ }
+
+ public class SinkTestCase extends TestCase {
+
+ private SinkTestCase(String name) {
+ super(name);
+ }
+
+ public void sinkTestNoWriting() throws Exception {
+ byte[] expected = new byte[] { };
+
+ OutputStream out = create();
+ out.close();
+ assertArrayEquals(expected, getBytes());
+ }
+
+ public void sinkTestWriteZeroBytes() throws Exception {
+ byte[] expected = new byte[] { };
+
+ OutputStream out = create();
+ byte[] a = new byte[1024];
+ out.write(a, 1000, 0);
+ out.write(a, 0, 0);
+ out.write(new byte[] { });
+
+ out.close();
+ assertArrayEquals(expected, getBytes());
+ }
+
+ public void sinkTestWriteByteByByte() throws Exception {
+ byte[] expected = new byte[] { 5, 6, 7, 3, 4, 5, 3, 2, 1 };
+
+ OutputStream out = create();
+ for (byte b : expected) {
+ out.write(b);
+ }
+
+ out.close();
+ assertArrayEquals(expected, getBytes());
+ }
+
+ public void sinkTestWriteArray() throws Exception {
+ byte[] expected = new byte[] {
+ 5, 6,
+ 7, 3, 4, 5,
+ 3, 2, 1
+ };
+
+ OutputStream out = create();
+
+ byte[] a = new byte[] { 5, 6 };
+ out.write(a);
+
+ byte[] b = new byte[] { 7, 3, 4, 5 };
+ out.write(b);
+
+ byte[] c = new byte[] { 3, 2, 1 };
+ out.write(c);
+
+ out.close();
+ assertArrayEquals(expected, getBytes());
+ }
+
+ public void sinkTestWriteOffset() throws Exception {
+ byte[] expected = new byte[] {
+ 5, 6,
+ 7, 3, 4, 5,
+ 3, 2, 1
+ };
+
+ OutputStream out = create();
+
+ byte[] a = new byte[1024];
+ a[1000] = 5;
+ a[1001] = 6;
+ out.write(a, 1000, 2);
+
+ byte[] b = new byte[1024];
+ b[1020] = 7;
+ b[1021] = 3;
+ b[1022] = 4;
+ b[1023] = 5;
+ out.write(b, 1020, 4);
+
+ byte[] c = new byte[1024];
+ c[0] = 3;
+ c[1] = 2;
+ c[2] = 1;
+ out.write(c, 0, 3);
+
+ out.close();
+ assertArrayEquals(expected, getBytes());
+ }
+
+ public void sinkTestWriteLargeArray() throws Exception {
+ byte[] expected = new byte[(1024 * 1024) + 1]; // 1 MB + 1 byte
+ new Random().nextBytes(expected);
+
+ OutputStream out = create();
+ out.write(expected);
+ out.close();
+
+ assertArrayEquals(expected, getBytes());
+ }
+
+ public void sinkTestWriteAfterClose() throws Exception {
+ byte[] expectedBytes = { 5, 6 };
+ OutputStream out = create();
+
+ out.write(expectedBytes);
+ out.close();
+
+ try {
+ out.write(new byte[] { 7, 3, 4, 5 });
+ fail("expected already closed exception");
+ } catch (IOException expected) {
+ }
+
+ assertArrayEquals(expectedBytes, getBytes());
+ }
+
+ public void sinkTestWriteAfterCloseSuppressed() throws Exception {
+ OutputStream out = create();
+ out.write(new byte[] { 5, 6 });
+ out.close();
+ out.write(new byte[] { 7, 3, 4, 5 }); // no exception expected!
+ }
+
+ // adding a new test? Don't forget to update createTests().
+
+ @Override
+ public String getName() {
+ return SinkTester.this.toString() + ":" + super.getName();
+ }
+ }
+}
diff --git a/support/src/test/java/org/apache/harmony/testframework/WrapperTester.java b/support/src/test/java/org/apache/harmony/testframework/WrapperTester.java
new file mode 100644
index 0000000..515c94f
--- /dev/null
+++ b/support/src/test/java/org/apache/harmony/testframework/WrapperTester.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.testframework;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Tests behaviour common to wrapping and filtering implementations of {@link
+ * OutputStream}.
+ */
+public abstract class WrapperTester {
+
+ private boolean throwsExceptions = true;
+
+ /**
+ * Creates a new output stream that receives one stream of bytes, optionally
+ * transforms it, and emits another stream of bytes to {@code delegate}.
+ */
+ public abstract OutputStream create(OutputStream delegate) throws Exception;
+
+ /**
+ * Decodes the bytes received by the delegate into their original form: the
+ * bytes originally received by this wrapper.
+ */
+ public abstract byte[] decode(byte[] delegateBytes) throws Exception;
+
+ /**
+ * Configures whether the stream is expected to throw exceptions when an
+ * error is encountered. Classes like {@code PrintStream} report errors via
+ * an API method instead.
+ */
+ public WrapperTester setThrowsExceptions(boolean throwsExceptions) {
+ this.throwsExceptions = throwsExceptions;
+ return this;
+ }
+
+ public final TestSuite createTests() {
+ TestSuite result = new TestSuite();
+ result.addTest(new WrapperSinkTester()
+ .setThrowsExceptions(throwsExceptions)
+ .createTests());
+
+ if (throwsExceptions) {
+ result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlush"));
+ result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaClose"));
+ result.addTest(new WrapperTestCase("wrapperTestCloseThrows"));
+ } else {
+ result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlushSuppressed"));
+ result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaCloseSuppressed"));
+ result.addTest(new WrapperTestCase("wrapperTestCloseThrowsSuppressed"));
+ }
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getName();
+ }
+
+ private class WrapperSinkTester extends SinkTester {
+ private ClosableByteArrayOutputStream delegate;
+
+ @Override
+ public OutputStream create() throws Exception {
+ delegate = new ClosableByteArrayOutputStream();
+ return WrapperTester.this.create(delegate);
+ }
+
+ @Override
+ public byte[] getBytes() throws Exception {
+ return WrapperTester.this.decode(delegate.bytesOut.toByteArray());
+ }
+
+ @Override
+ public String toString() {
+ return WrapperTester.this.toString();
+ }
+ }
+
+ public class WrapperTestCase extends TestCase {
+
+ private WrapperTestCase(String name) {
+ super(name);
+ }
+
+ @Override
+ public String getName() {
+ return WrapperTester.this.toString() + ":" + super.getName();
+ }
+
+ public void wrapperTestFlushThrowsViaFlushSuppressed() throws Exception {
+ FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
+ OutputStream o = create(delegate);
+ o.write(new byte[] { 8, 6, 7, 5 });
+ o.write(new byte[] { 3, 0, 9 });
+ o.flush();
+ assertTrue(delegate.flushed);
+ }
+
+ public void wrapperTestFlushThrowsViaCloseSuppressed() throws Exception {
+ FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
+ OutputStream o = create(delegate);
+ o.write(new byte[] { 8, 6, 7, 5 });
+ o.write(new byte[] { 3, 0, 9 });
+ o.close();
+ assertTrue(delegate.flushed);
+ }
+
+ public void wrapperTestFlushThrowsViaFlush() throws Exception {
+ FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
+
+ OutputStream o = create(delegate);
+ try {
+ // any of these is permitted to flush
+ o.write(new byte[] { 8, 6, 7, 5 });
+ o.write(new byte[] { 3, 0, 9 });
+ o.flush();
+ assertTrue(delegate.flushed);
+ fail("flush exception ignored");
+ } catch (IOException expected) {
+ assertEquals("Flush failed", expected.getMessage());
+ }
+ }
+
+ public void wrapperTestFlushThrowsViaClose() throws Exception {
+ FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
+
+ OutputStream o = create(delegate);
+ try {
+ // any of these is permitted to flush
+ o.write(new byte[] { 8, 6, 7, 5 });
+ o.write(new byte[] { 3, 0, 9 });
+ o.close();
+ assertTrue(delegate.flushed);
+ fail("flush exception ignored");
+ } catch (IOException expected) {
+ assertEquals("Flush failed", expected.getMessage());
+ }
+
+ try {
+ o.write(new byte[] { 4, 4, 5 });
+ fail("expected already closed exception");
+ } catch (IOException expected) {
+ }
+ }
+
+ public void wrapperTestCloseThrows() throws Exception {
+ FailOnCloseOutputStream delegate = new FailOnCloseOutputStream();
+ OutputStream o = create(delegate);
+ try {
+ o.close();
+ assertTrue(delegate.closed);
+ fail("close exception ignored");
+ } catch (IOException expected) {
+ assertEquals("Close failed", expected.getMessage());
+ }
+ }
+
+ public void wrapperTestCloseThrowsSuppressed() throws Exception {
+ FailOnCloseOutputStream delegate = new FailOnCloseOutputStream();
+ OutputStream o = create(delegate);
+ o.close();
+ assertTrue(delegate.closed);
+ }
+
+ // adding a new test? Don't forget to update createTests().
+ }
+
+ private static class ClosableByteArrayOutputStream extends OutputStream {
+ private final ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+ private boolean closed = false;
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ }
+
+ @Override
+ public void write(int oneByte) throws IOException {
+ if (closed) {
+ throw new IOException();
+ }
+ bytesOut.write(oneByte);
+ }
+ }
+
+ private static class FailOnFlushOutputStream extends OutputStream {
+ boolean flushed = false;
+ boolean closed = false;
+
+ @Override
+ public void write(int oneByte) throws IOException {
+ if (closed) {
+ throw new IOException("Already closed");
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ flush();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ if (!flushed) {
+ flushed = true;
+ throw new IOException("Flush failed");
+ }
+ }
+ }
+
+ private static class FailOnCloseOutputStream extends ByteArrayOutputStream {
+ boolean closed = false;
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ throw new IOException("Close failed");
+ }
+ }
+}
diff --git a/support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java b/support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java
index 8d0c3a4..4f0b90b 100644
--- a/support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java
+++ b/support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java
@@ -22,6 +22,7 @@
package org.apache.harmony.testframework.serialization;
+import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -38,7 +39,6 @@ import java.security.PermissionCollection;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
-import junit.framework.TestCase;
/**
* Framework for serialization testing. Subclasses only need to override
@@ -98,7 +98,6 @@ public abstract class SerializationTest extends TestCase {
*/
public void testGolden() throws Throwable {
-
verifyGolden(this, getData());
}
@@ -427,7 +426,9 @@ public abstract class SerializationTest extends TestCase {
path.append(test.getClass().getName().replace('.', File.separatorChar));
path.append(toAppend);
- InputStream in = SerializationTest.class.getResourceAsStream(path.toString());
+ String pathString = path.toString();
+
+ InputStream in = SerializationTest.class.getResourceAsStream(pathString);
assertNotNull("Failed to load serialization resource file: " + path, in);
return getObjectFromStream(in);
}
diff --git a/support/src/test/java/tests/io/MockOs.java b/support/src/test/java/tests/io/MockOs.java
index d7e284f..b1c6cee 100644
--- a/support/src/test/java/tests/io/MockOs.java
+++ b/support/src/test/java/tests/io/MockOs.java
@@ -16,6 +16,8 @@
package tests.io;
+import android.system.ErrnoException;
+import android.system.OsConstants;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -24,10 +26,8 @@ import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
-import libcore.io.ErrnoException;
import libcore.io.Libcore;
import libcore.io.Os;
-import libcore.io.OsConstants;
/**
* A mocking interceptor that wraps another {@link Os} to add faults. This can
diff --git a/support/src/test/java/tests/resources/ServiceLoader/AbstractService.java b/support/src/test/java/tests/resources/ServiceLoader/AbstractService.java
new file mode 100644
index 0000000..bff9660
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/AbstractService.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public abstract class AbstractService {
+ /**
+ * @return name of the class
+ */
+ public abstract String myNameIs();
+
+ /**
+ * test of internal interface
+ */
+ public interface InternalService {
+ /**
+ * @return name
+ */
+ public String myInternalNameIs();
+ }
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/Service.java b/support/src/test/java/tests/resources/ServiceLoader/Service.java
new file mode 100644
index 0000000..c36fdb3
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/Service.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface Service {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceDuplicateIn2File.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceDuplicateIn2File.java
new file mode 100644
index 0000000..b09bc81
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceDuplicateIn2File.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceDuplicateIn2File {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceFinalClass.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceFinalClass.java
new file mode 100644
index 0000000..767f016
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceFinalClass.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public final class ServiceFinalClass {
+ /**
+ * @return name of the class
+ */
+ @SuppressWarnings("nls")
+ public String myNameIs() {
+ return "ServiceFinalClass";
+ }
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceForAllCommentTest.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceForAllCommentTest.java
new file mode 100644
index 0000000..e982b3f
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceForAllCommentTest.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceForAllCommentTest {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceForEmptyTest.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceForEmptyTest.java
new file mode 100644
index 0000000..d777293
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceForEmptyTest.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceForEmptyTest {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceForIllegalNameTest.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceForIllegalNameTest.java
new file mode 100644
index 0000000..4e9cde7
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceForIllegalNameTest.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceForIllegalNameTest {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceForWrongNameTest.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceForWrongNameTest.java
new file mode 100644
index 0000000..910faec
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceForWrongNameTest.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceForWrongNameTest {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2File.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2File.java
new file mode 100644
index 0000000..49f19d7
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2File.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceIn2File {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2FileWithEmptyConfig.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2FileWithEmptyConfig.java
new file mode 100644
index 0000000..ad63606
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2FileWithEmptyConfig.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceIn2FileWithEmptyConfig {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceMoreThanOne.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceMoreThanOne.java
new file mode 100644
index 0000000..895972e
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceMoreThanOne.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public class ServiceMoreThanOne {
+ /**
+ * @return name of the class
+ */
+ @SuppressWarnings("nls")
+ public String myNameIs() {
+ return "ServiceMoreThanOne";
+ }
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceWithDuplicateSons.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceWithDuplicateSons.java
new file mode 100644
index 0000000..a299931
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceWithDuplicateSons.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceWithDuplicateSons {
+ /**
+ * @return name of the class
+ */
+ public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/hyts_services.jar b/support/src/test/java/tests/resources/ServiceLoader/hyts_services.jar
new file mode 100644
index 0000000..12503a6
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/hyts_services.jar
Binary files differ
diff --git a/support/src/test/java/tests/resources/ServiceLoader/hyts_services2.jar b/support/src/test/java/tests/resources/ServiceLoader/hyts_services2.jar
new file mode 100644
index 0000000..a7a754a
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/hyts_services2.jar
Binary files differ
diff --git a/support/src/test/java/tests/resources/cts_dalvikExecTest.jar b/support/src/test/java/tests/resources/cts_dalvikExecTest.jar
deleted file mode 100644
index b6af791..0000000
--- a/support/src/test/java/tests/resources/cts_dalvikExecTest.jar
+++ /dev/null
Binary files differ
diff --git a/support/src/test/java/tests/resources/cts_dalvikExecTest_classes.dex b/support/src/test/java/tests/resources/cts_dalvikExecTest_classes.dex
deleted file mode 100644
index 415c50a..0000000
--- a/support/src/test/java/tests/resources/cts_dalvikExecTest_classes.dex
+++ /dev/null
Binary files differ
diff --git a/support/src/test/java/tests/resources/hyts_signed_ambiguousSignerArray.jar b/support/src/test/java/tests/resources/hyts_signed_ambiguousSignerArray.jar
new file mode 100644
index 0000000..7da4b59
--- /dev/null
+++ b/support/src/test/java/tests/resources/hyts_signed_ambiguousSignerArray.jar
Binary files differ
diff --git a/support/src/test/java/tests/resources/hyts_signed_sha256digest_sha256withecdsa.jar b/support/src/test/java/tests/resources/hyts_signed_sha256digest_sha256withecdsa.jar
new file mode 100644
index 0000000..c5e7a16
--- /dev/null
+++ b/support/src/test/java/tests/resources/hyts_signed_sha256digest_sha256withecdsa.jar
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cacert.pem b/support/src/test/java/tests/resources/x509/cacert.pem
new file mode 100644
index 0000000..51d0e53
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/cacert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDBDCCAm2gAwIBAgIJAJU3Hqerwtd/MA0GCSqGSIb3DQEBBQUAMGAxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTYW4gTWF0ZW8x
+FzAVBgNVBAoTDkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMwHhcNMTQw
+MTI4MjE0MjE1WhcNMjQwMTI2MjE0MjE1WjBgMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU2FuIE1hdGVvMRcwFQYDVQQKEw5HZW5p
+dXMuY29tIEluYzEPMA0GA1UECxMGTmV0T3BzMIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQCu7zFhEei5eH4LMzO06nAlvY477CViGo1d6LoJ+26Z4chpRLwjc+f/
+5Azs2DJh0N6H1yqWBPyH0nQaajO42mXVyRu7zZzMd3OIaMzTskDrg9Zghcyut7Qe
+nPHYgeW5F1UlBPyXi1aoeiSrf/HPJOKkBw2+hA4SzmGHp70p1jOQuwIDAQABo4HF
+MIHCMB0GA1UdDgQWBBSyGQgp55x6ufO+WsHUnGwNMiLcwzCBkgYDVR0jBIGKMIGH
+gBSyGQgp55x6ufO+WsHUnGwNMiLcw6FkpGIwYDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVNhbiBNYXRlbzEXMBUGA1UEChMOR2Vu
+aXVzLmNvbSBJbmMxDzANBgNVBAsTBk5ldE9wc4IJAJU3Hqerwtd/MAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEASwI0qAyXBtjgIIIdL1DKNGyten9kb/UL
+k4HhRbntTInEPlFKfnm+1pkwLHNJJfGmYdE5CTlP0HF91I9fTGTKdaYY5Dv4VBYS
+vAuoaAKVwV8JiW80wLjyhjiFSIBKazpz1X4UqzUsMKKOW6uVMN90UMD6hTK/Ddkk
+2m3ETfAmEN0=
+-----END CERTIFICATE-----
diff --git a/support/src/test/java/tests/resources/x509/cakey.pem b/support/src/test/java/tests/resources/x509/cakey.pem
new file mode 100644
index 0000000..006da59
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/cakey.pem
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAK7vMWER6Ll4fgsz
+M7TqcCW9jjvsJWIajV3ougn7bpnhyGlEvCNz5//kDOzYMmHQ3ofXKpYE/IfSdBpq
+M7jaZdXJG7vNnMx3c4hozNOyQOuD1mCFzK63tB6c8diB5bkXVSUE/JeLVqh6JKt/
+8c8k4qQHDb6EDhLOYYenvSnWM5C7AgMBAAECgYAZ1TzHhuuFKCQE52TFXLF/AUUV
+2EOU/zLNIWcHvleQ5eTAluPpoF4sTbMS7sJR65RRHxcs3EOmkw+OLwzASZAsCWEx
+IVtl6rkB08+RYY+D+cs3kxXT96rjUd23ytjnoa+SeDpInaYLWutj8Lj/EfRlo82R
+dHvu/fX8j8aVCN5PwQJBANuo32XbbairI1/ISjYYHYrkks09cvK2rC/Y7FBCp1g1
+N1RNvyw5cKrrNZ7lFmdsP/tDcwJ96r8NV+myeIV5V1ECQQDL4Bfas17Aa+eh3zVk
+OSn9aOfz/GX/9G1hYNPX5Ovnq3vY3qXMLwUaOM2JhcUzPV8e6Ml3ysmTuGy/EdAs
+MDxLAkATDQ5zExjrrAwhXomxL15AkZp52n6Btn4wmCvGukExUUw/L48JEuJGsKex
+5ESRK75Q2IS9Dpaxg0LArg3t5ZxBAkEAvAQrG5bl4ADjOiYWIBqTvc68cwcmrfil
+0vMwCt9kK1+7NFKIhpgqVXdjHduO9GU5ztCR0/bhFWk0aLUtzUKipwJBAJPUvMPJ
++BDk29AWJLMN2v1vpx96NDr3RWsQB7X+IczLhixPrmguNQ3uI4H+zYT2mqLedbwp
+b4sz8X7ZPwbgRYc=
+-----END PRIVATE KEY-----
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-dirname.der b/support/src/test/java/tests/resources/x509/cert-alt-dirname.der
index e96fc33..cf065c1 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-dirname.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-dirname.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-dns.der b/support/src/test/java/tests/resources/x509/cert-alt-dns.der
index 7f245f1..0b902c9 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-dns.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-dns.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-email.der b/support/src/test/java/tests/resources/x509/cert-alt-email.der
index 94db3e9..067b701 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-email.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-email.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-none.der b/support/src/test/java/tests/resources/x509/cert-alt-none.der
index 6b7ab1d..3781325 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-none.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-none.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-other.der b/support/src/test/java/tests/resources/x509/cert-alt-other.der
index fb66368..07b6fb6 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-other.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-other.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-rid.der b/support/src/test/java/tests/resources/x509/cert-alt-rid.der
index 6773b4f..82a4051 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-rid.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-rid.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-uri.der b/support/src/test/java/tests/resources/x509/cert-alt-uri.der
index c21ae4c..d706d1e 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-uri.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-uri.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-ca.der b/support/src/test/java/tests/resources/x509/cert-ca.der
index 0570113..4d3712a 100644
--- a/support/src/test/java/tests/resources/x509/cert-ca.der
+++ b/support/src/test/java/tests/resources/x509/cert-ca.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-caWithPathLen.der b/support/src/test/java/tests/resources/x509/cert-caWithPathLen.der
index c964a0b..2f1ab9e 100644
--- a/support/src/test/java/tests/resources/x509/cert-caWithPathLen.der
+++ b/support/src/test/java/tests/resources/x509/cert-caWithPathLen.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-crl-ca.der b/support/src/test/java/tests/resources/x509/cert-crl-ca.der
index d58022c..fad1b2d 100644
--- a/support/src/test/java/tests/resources/x509/cert-crl-ca.der
+++ b/support/src/test/java/tests/resources/x509/cert-crl-ca.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-dsa.der b/support/src/test/java/tests/resources/x509/cert-dsa.der
index 09f83eb..0f60f2d 100644
--- a/support/src/test/java/tests/resources/x509/cert-dsa.der
+++ b/support/src/test/java/tests/resources/x509/cert-dsa.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-ec.der b/support/src/test/java/tests/resources/x509/cert-ec.der
index ca746cc..2d30151 100644
--- a/support/src/test/java/tests/resources/x509/cert-ec.der
+++ b/support/src/test/java/tests/resources/x509/cert-ec.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.der b/support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.der
index 33673aa..74e8fe4 100644
--- a/support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.der
+++ b/support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-ipv6.der b/support/src/test/java/tests/resources/x509/cert-ipv6.der
index 0e6c5ed..904c33c 100644
--- a/support/src/test/java/tests/resources/x509/cert-ipv6.der
+++ b/support/src/test/java/tests/resources/x509/cert-ipv6.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.der b/support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.der
index 1d5fdea..4b98f6a 100644
--- a/support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.der
+++ b/support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-dates.txt b/support/src/test/java/tests/resources/x509/cert-rsa-dates.txt
index cbd8632..654000d 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-dates.txt
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-dates.txt
@@ -1,2 +1,2 @@
-notBefore=Mar 6 00:42:06 2013 GMT
-notAfter=Mar 4 00:42:06 2023 GMT
+notBefore=Jan 28 21:42:14 2014 GMT
+notAfter=Jan 26 21:42:14 2024 GMT
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-pubkey.der b/support/src/test/java/tests/resources/x509/cert-rsa-pubkey.der
index 4fb898b..e525a6f 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-pubkey.der
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-pubkey.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-serial.txt b/support/src/test/java/tests/resources/x509/cert-rsa-serial.txt
index 07ed8ec..72d5240 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-serial.txt
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-serial.txt
@@ -1 +1 @@
-serial=BFC278DBB294AC42
+serial=-056BC75E2D630FFFFF
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-sig.der b/support/src/test/java/tests/resources/x509/cert-rsa-sig.der
index 54361b5..e291aa5 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-sig.der
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-sig.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-tbs.der b/support/src/test/java/tests/resources/x509/cert-rsa-tbs.der
index cbe67b7..ffae8c0 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-tbs.der
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-tbs.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa.der b/support/src/test/java/tests/resources/x509/cert-rsa.der
index e27787b..12b3595 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa.der
+++ b/support/src/test/java/tests/resources/x509/cert-rsa.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-sigopt.der b/support/src/test/java/tests/resources/x509/cert-sigopt.der
index d808282..2472d1f 100644
--- a/support/src/test/java/tests/resources/x509/cert-sigopt.der
+++ b/support/src/test/java/tests/resources/x509/cert-sigopt.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-unsupported.der b/support/src/test/java/tests/resources/x509/cert-unsupported.der
index c0db35a..ff7004e 100644
--- a/support/src/test/java/tests/resources/x509/cert-unsupported.der
+++ b/support/src/test/java/tests/resources/x509/cert-unsupported.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-userWithPathLen.der b/support/src/test/java/tests/resources/x509/cert-userWithPathLen.der
index e5ec37e..6f166a9 100644
--- a/support/src/test/java/tests/resources/x509/cert-userWithPathLen.der
+++ b/support/src/test/java/tests/resources/x509/cert-userWithPathLen.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/certs-pk7.der b/support/src/test/java/tests/resources/x509/certs-pk7.der
index f7f8abc..677d4c0 100644
--- a/support/src/test/java/tests/resources/x509/certs-pk7.der
+++ b/support/src/test/java/tests/resources/x509/certs-pk7.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/certs-pk7.pem b/support/src/test/java/tests/resources/x509/certs-pk7.pem
index feef173..89d0962 100644
--- a/support/src/test/java/tests/resources/x509/certs-pk7.pem
+++ b/support/src/test/java/tests/resources/x509/certs-pk7.pem
@@ -1,45 +1,51 @@
-----BEGIN PKCS7-----
-MIIICAYJKoZIhvcNAQcCoIIH+TCCB/UCAQExADALBgkqhkiG9w0BBwGgggfbMIIE
-vDCCBCWgAwIBAgIJAL/CeNuylKxCMA0GCSqGSIb3DQEBBQUAMGAxCzAJBgNVBAYT
+MIIJDAYJKoZIhvcNAQcCoIII/TCCCPkCAQExADALBgkqhkiG9w0BBwGgggjfMIIF
+wTCCBKmgAwIBAgIJ+pQ4odKc8AABMA0GCSqGSIb3DQEBBQUAMGAxCzAJBgNVBAYT
AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTYW4gTWF0ZW8xFzAV
-BgNVBAoTDkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMwHhcNMTMwMzA2
-MDA0MjA2WhcNMjMwMzA0MDA0MjA2WjBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
+BgNVBAoTDkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMwHhcNMTQwMTI4
+MjE0MjE0WhcNMjQwMTI2MjE0MjE0WjBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
Q2FsaWZvcm5pYTESMBAGA1UEBxMJU2FuIE1hdGVvMRcwFQYDVQQKEw5HZW5pdXMu
-Y29tIEluYzEPMA0GA1UECxMGTmV0T3BzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
-iQKBgQCxtuZhs1g1NvAYRkbdyDwNh+KLxc/GWDC+reFz9bO8NDmINjLVoe3Pu5S1
-ONXEgpkvSj6v8a9S7FgSShautZd6G1fm6XFB2Nn+eUjN56o86xNHMiEOG+QCTRRu
-pAkZaa3W1WEh+zqq2x0X9JlYY/xpDmP3voGC6rOcfnOoyl/fPQIDAQABo4ICfDCC
-AngwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFL8PXLxMk0+9Upkm
-yqlonexUHoq4MIGSBgNVHSMEgYowgYeAFL8PXLxMk0+9UpkmyqlonexUHoq4oWSk
-YjBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJ
-U2FuIE1hdGVvMRcwFQYDVQQKEw5HZW5pdXMuY29tIEluYzEPMA0GA1UECxMGTmV0
-T3BzggkAv8J427KUrEIwHgYJYIZIAYb4QgENBBEWD1guNTA5IFVuaXQgVGVzdDCB
-wwYDVR0RBIG7MIG4oA4GAyoDBKAHDAV0ZXN0MYEQeDUwOUBleGFtcGxlLmNvbYIQ
-eDUwOS5leGFtcGxlLmNvbaRQME4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1Bd2Vz
-b21lIER1ZGVzMRcwFQYDVQQLFA7DnGJlciBGcsOuZW5kczEOMAwGA1UEAxQF4oiG
-xpKGJWh0dHA6Ly93d3cuZXhhbXBsZS5jb20vP3E9YXdlc29tZW5lc3OHBMCoAAGI
-AyoDBDCBwwYDVR0SBIG7MIG4oA4GAyoDBKAHDAV0ZXN0MYEQeDUwOUBleGFtcGxl
-LmNvbYIQeDUwOS5leGFtcGxlLmNvbaRQME4xCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1Bd2Vzb21lIER1ZGVzMRcwFQYDVQQLFA7DnGJlciBGcsOuZW5kczEOMAwGA1UE
-AxQF4oiGxpKGJWh0dHA6Ly93d3cuZXhhbXBsZS5jb20vP3E9YXdlc29tZW5lc3OH
-BMCoAAGIAyoDBDANBgkqhkiG9w0BAQUFAAOBgQAaN9rhafhvcIyhXyUVNfPQ/Tod
-mSV/2Kr+IgfCjanjUusQxATHnJeMb5HHgd608hmqQODnHUjEk/KMatrxUcxPp9Hc
-QTNlBBWTz0Oj60KgAb+xYEi/cBn3Cxubyxo+hgjpLhc1st/vgMQnyXHWa3vjFuRD
-1b7munGaUBNsFi0BnzCCAxcwggLVoAMCAQICCQDoI9YBeCh6fzAJBgcqhkjOOAQD
-MGAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlT
-YW4gTWF0ZW8xFzAVBgNVBAoTDkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRP
-cHMwHhcNMTMwMzA2MDA0MjA4WhcNMTMwNDA1MDA0MjA4WjBgMQswCQYDVQQGEwJV
-UzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU2FuIE1hdGVvMRcwFQYD
-VQQKEw5HZW5pdXMuY29tIEluYzEPMA0GA1UECxMGTmV0T3BzMIIBtjCCASsGByqG
-SM44BAEwggEeAoGBAJSFHSZWbyn0lJm3v2VeFoVNPSCM4akS+YxZ8NyYjEwl58aC
-YW/StslxMQeQvow++1bzM2GMMq6i29fSy/y8w/kNgua6mC+H1rkoAPy1zr/qiYD5
-4LgVm53sjur9HZaSP5h5U1u0f7uYrnxd5r8ns/pNJ1HnVdPzbFEgBU0LRjUtAhUA
-vcuQ5p9rxRPOegf2e3DP8dgc+LcCgYAJ2OG3B4JdOOowJidNeIFL2E86nQ9YqY+y
-Qn760g3L23PX+tjJag1vJfvS2pwU1X0w3YwvdoPBFLwBfy0vEwEFqR70iJC/E2st
-3geZqbPjZWkoUS6Rq3++JsKoLxYMLns/2U9/vpl/KF2053Xa3QvTyd0Dxs1o3T0m
-g2rhP8FldAOBhAACgYAYB+w4767ypZaw1RYNLWWl+UFe4L2cfsZKGM5Z8flqcJke
-y5fhk2VPRFa/YXUEYuYkganGQFNqrv2tlLalpcqRX00BXLFGx2WFrhpY1u2YYnDV
-5xGFpLH4MV0Nvw0iDMD+q+Wo2sH5MgUbCmnlwtZ8xhQYF3M2Cyb4fnm+tQsNnKMa
-MBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCADcwCQYHKoZIzjgEAwMxADAuAhUAt3Mt
-TCmXGAdJ8gGtrg/BfAQ/lPoCFQCMlyzUwS31EtfnLSu/SGFR6xxTMqEAMQA=
+Y29tIEluYzEPMA0GA1UECxMGTmV0T3BzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEArfmkkDffJP6ODl13KnTaB8cwvB4anWw8+bGa8y9N7wPx7RWZWFMr
+fOac01p2fhq+oUIw3/uxRcDAQBQx0ZFLx3OFMuQkTpFbzHeSctsXi1Kk28pn4K3B
+K2CModRh8ir/qdhu0PG4SsXdyN8uT8H6bitmH4vpLaAMMi6aa1M6Ygio8a37UCQQ
+7fw2P7YVR61BsyqwsM/eYtgd2LqrObLwkkOvxTwpZPWDftHI4ucz1rgNnD9q0H3g
+kyGyGq9NBkBHJ25+CkMe+1q/eh4Xt2kt2ML4q5YZmQEwHm1eIR3/uGlb1+bueRMd
+hrueth/FsUiKPJ0gzmsxzQefgcLnctIx3wIDAQABo4ICfDCCAngwCQYDVR0TBAIw
+ADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFJ/uU/wudzNDSI/SWkNNTXNLq2EIMIGS
+BgNVHSMEgYowgYeAFJ/uU/wudzNDSI/SWkNNTXNLq2EIoWSkYjBgMQswCQYDVQQG
+EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU2FuIE1hdGVvMRcw
+FQYDVQQKEw5HZW5pdXMuY29tIEluYzEPMA0GA1UECxMGTmV0T3Bzggn6lDih0pzw
+AAEwHgYJYIZIAYb4QgENBBEWD1guNTA5IFVuaXQgVGVzdDCBwwYDVR0RBIG7MIG4
+oA4GAyoDBKAHDAV0ZXN0MYEQeDUwOUBleGFtcGxlLmNvbYIQeDUwOS5leGFtcGxl
+LmNvbaRQME4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1Bd2Vzb21lIER1ZGVzMRcw
+FQYDVQQLFA7DnGJlciBGcsOuZW5kczEOMAwGA1UEAxQF4oiGxpKGJWh0dHA6Ly93
+d3cuZXhhbXBsZS5jb20vP3E9YXdlc29tZW5lc3OHBMCoAAGIAyoDBDCBwwYDVR0S
+BIG7MIG4oA4GAyoDBKAHDAV0ZXN0MYEQeDUwOUBleGFtcGxlLmNvbYIQeDUwOS5l
+eGFtcGxlLmNvbaRQME4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1Bd2Vzb21lIER1
+ZGVzMRcwFQYDVQQLFA7DnGJlciBGcsOuZW5kczEOMAwGA1UEAxQF4oiGxpKGJWh0
+dHA6Ly93d3cuZXhhbXBsZS5jb20vP3E9YXdlc29tZW5lc3OHBMCoAAGIAyoDBDAN
+BgkqhkiG9w0BAQUFAAOCAQEAQK5jBzTq2lX1GpVD9RHxtTHJn/WkYOpMJYJruw8j
+HGfQwAkhlL9AqWgodTruoTnXgZbA7F3S8hx9gmUbHVjVeBvxZnGEJ8g7So1erFKv
+yQD1Ajtn7+uGXw6s0Dvde2ZVzV05pRk9ybg7kxKNXvVbKS3kyd6XoA27H5CSmzDu
+8cwHQkN4mJlwAiNCwMarpN4m4X0rQ+g1Ncfq+4sRjFLd8VVCbCpzD8UMBOVTpxxj
+kSyRPJZ7Db8SY0H2vcTUj2Yyog1RQ+RA/xp7Fgw+leEiveIE23Dq62hCHq6rU5Vj
+6L/LlLiKZ17lZT4z0fJ0lukPUpmVTynALKsKNm57+fOfnzCCAxYwggLWoAMCAQIC
+CQDcaK5WyhbztjAJBgcqhkjOOAQDMGAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
+YWxpZm9ybmlhMRIwEAYDVQQHEwlTYW4gTWF0ZW8xFzAVBgNVBAoTDkdlbml1cy5j
+b20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMwHhcNMTQwMTI4MjE0MjE1WhcNMTQwMjI3
+MjE0MjE1WjBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAG
+A1UEBxMJU2FuIE1hdGVvMRcwFQYDVQQKEw5HZW5pdXMuY29tIEluYzEPMA0GA1UE
+CxMGTmV0T3BzMIIBtzCCASsGByqGSM44BAEwggEeAoGBAIiv42coWuyVXpYoyEwf
+7uevd4ILhylFuvKH5tRWRcZENuxPOmXfr3L43PCdbnJhXMg3RkkWgjaE7lBk5evx
+LKH6rU2a1GnGmoY34OIvVvGL3xi96uYTTvLIX3+6NXaAlNppIBSHXcYx8cMdtYIn
+3J6JGSHEPo36ay4rDZbfS1frAhUAxF6k+/9T00QMolE41R+6ytzrawkCgYA4soyt
+rrIrQq6gwm2HanT8coIChr3/Et8rMamj7gS1yT9kH8HNGf217XtE3f/LUZZWUkBq
+3PNOuxhprNmvSAdQ7ZzhWfRvOFHKaH/DtKvLeEC5I00DfYSI64/V869Jy7lnyY7M
+h7ShLIwOlwnBDIL5oluircfXTr20a/Jv9pS1AAOBhQACgYEAhg6lELBZAIHVkjm7
+bwVJ5G/ka+KCjXxWXo+BCbqo0LqfrKQoQwUcwDzuKdqWxYbyUd0cl5/9fX59/RT/
+9ULklGy+dTyUSc/hj85PCXLYly3G6WECiN29TK0QLhEMZfi+iSm3YxNX3rxvmrHb
+bfO2SMef4r6ujv9KscDg0zQ4AgajGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgA3
+MAkGByqGSM44BAMDLwAwLAIUVcYZ1LNv22fDBiajZ99FpTn05SMCFCgMXzUGLdPy
+gY460q7tGpuydry+oQAxAA==
-----END PKCS7-----
diff --git a/support/src/test/java/tests/resources/x509/create.sh b/support/src/test/java/tests/resources/x509/create.sh
index a1d2f35..0020b47 100755
--- a/support/src/test/java/tests/resources/x509/create.sh
+++ b/support/src/test/java/tests/resources/x509/create.sh
@@ -18,9 +18,13 @@ set -e
DIR=$(dirname $0)
-openssl req -config ${DIR}/default.cnf -new -nodes -batch > /tmp/cert-rsa-req.pem
+if [ ! -f ${DIR}/privkey.pem ]; then
+ openssl genrsa -out ${DIR}/privkey.pem 2048
+fi
+
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch > /tmp/cert-rsa-req.pem
openssl req -in /tmp/cert-rsa-req.pem -pubkey -noout | openssl rsa -pubin -pubout -outform der > ${DIR}/cert-rsa-pubkey.der
-openssl x509 -extfile ${DIR}/default.cnf -days 3650 -extensions usr_cert -req -signkey /tmp/privkey.pem -outform d < /tmp/cert-rsa-req.pem > ${DIR}/cert-rsa.der
+openssl x509 -extfile ${DIR}/default.cnf -days 3650 -extensions usr_cert -req -signkey ${DIR}/privkey.pem -outform d -set_serial -99999999999999999999 < /tmp/cert-rsa-req.pem > ${DIR}/cert-rsa.der
rm /tmp/cert-rsa-req.pem
openssl asn1parse -in ${DIR}/cert-rsa.der -inform d -out ${DIR}/cert-rsa-tbs.der -noout -strparse 4
@@ -33,43 +37,47 @@ openssl x509 -in ${DIR}/cert-rsa.der -inform d -noout -startdate -enddate > ${DI
# extract serial
openssl x509 -in ${DIR}/cert-rsa.der -inform d -noout -serial > ${DIR}/cert-rsa-serial.txt
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions keyUsage_extraLong_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-keyUsage-extraLong.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions keyUsage_extraLong_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-keyUsage-extraLong.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions extendedKeyUsage_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-extendedKeyUsage.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions extendedKeyUsage_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-extendedKeyUsage.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions ca_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-ca.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions ca_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-ca.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions userWithPathLen_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-userWithPathLen.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions userWithPathLen_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-userWithPathLen.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions caWithPathLen_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-caWithPathLen.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions caWithPathLen_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-caWithPathLen.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_other_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-alt-other.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_other_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-alt-other.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_email_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-alt-email.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_email_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-alt-email.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_dns_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-alt-dns.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_dns_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-alt-dns.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_dirname_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-alt-dirname.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_dirname_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-alt-dirname.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_uri_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-alt-uri.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_uri_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-alt-uri.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_rid_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-alt-rid.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_rid_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-alt-rid.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_none_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-alt-none.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions alt_none_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-alt-none.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions ipv6_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-ipv6.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions ipv6_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-ipv6.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions unsupported_cert -req -signkey /tmp/privkey.pem -outform d > ${DIR}/cert-unsupported.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions unsupported_cert -req -signkey ${DIR}/privkey.pem -outform d > ${DIR}/cert-unsupported.der
-openssl req -config ${DIR}/default.cnf -new -nodes -batch -config ${DIR}/default.cnf -extensions usr_cert -x509 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:1 -outform d > ${DIR}/cert-sigopt.der
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/privkey.pem -nodes -batch -config ${DIR}/default.cnf -extensions usr_cert -x509 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:1 -outform d > ${DIR}/cert-sigopt.der
-openssl dsaparam -out /tmp/dsaparam.pem 1024
-openssl req -config ${DIR}/default.cnf -newkey dsa:/tmp/dsaparam.pem -keyout /tmp/dsapriv.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions keyUsage_cert -req -signkey /tmp/dsapriv.pem -outform d > ${DIR}/cert-dsa.der
-rm /tmp/dsaparam.pem
+if [ ! -f ${DIR}/dsapriv.pem ]; then
+ openssl dsaparam -out /tmp/dsaparam.pem 1024
+ openssl gendsa -out ${DIR}/dsapriv.pem /tmp/dsaparam.pem
+ rm -f /tmp/dsaparam.pem
+fi
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/dsapriv.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions keyUsage_cert -req -signkey ${DIR}/dsapriv.pem -outform d > ${DIR}/cert-dsa.der
-openssl ecparam -name sect283k1 -out /tmp/ecparam.pem
-openssl req -config ${DIR}/default.cnf -newkey ec:/tmp/ecparam.pem -keyout /tmp/ecpriv.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions keyUsage_critical_cert -req -signkey /tmp/ecpriv.pem -outform d > ${DIR}/cert-ec.der
-rm /tmp/ecparam.pem
+if [ ! -f ${DIR}/ecpriv.pem ]; then
+ openssl ecparam -name prime256v1 -genkey -out ${DIR}/ecpriv.pem -noout
+fi
+openssl req -config ${DIR}/default.cnf -new -key ${DIR}/ecpriv.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions keyUsage_critical_cert -req -signkey ${DIR}/ecpriv.pem -outform d > ${DIR}/cert-ec.der
# Create temporary CA for CRL generation
rm -rf /tmp/ca
@@ -77,7 +85,10 @@ mkdir -p /tmp/ca
touch /tmp/ca/index.txt
touch /tmp/ca/index.txt.attr
echo "01" > /tmp/ca/serial
-openssl req -new -nodes -batch -x509 -extensions v3_ca -keyout /tmp/cakey.pem -out /tmp/cacert.pem -days 3650 -config ${DIR}/default.cnf
+if [ ! -f ${DIR}/cakey.pem ]; then
+ openssl req -new -nodes -batch -x509 -extensions v3_ca -keyout ${DIR}/cakey.pem -out ${DIR}/cacert.pem -days 3650 -config ${DIR}/default.cnf
+fi
+cp ${DIR}/cakey.pem ${DIR}/cacert.pem /tmp
openssl x509 -in /tmp/cacert.pem -outform d > ${DIR}/cert-crl-ca.der
openssl ca -gencrl -crlhours 70 -keyfile /tmp/cakey.pem -cert /tmp/cacert.pem -out /tmp/crl-empty.pem -config ${DIR}/default.cnf
@@ -94,8 +105,8 @@ openssl asn1parse -in ${DIR}/crl-rsa.der -inform d -strparse ${SIG_OFFSET} -noou
openssl x509 -inform d -in ${DIR}/cert-dsa.der -out /tmp/cert-dsa.pem
openssl ca -revoke /tmp/cert-dsa.pem -keyfile /tmp/cakey.pem -cert /tmp/cacert.pem -crl_reason cessationOfOperation -extensions unsupported_cert -config ${DIR}/default.cnf
-openssl ca -gencrl -crldays 30 -keyfile /tmp/cakey.pem -cert /tmp/cacert.pem -out /tmp/crl-rsa-dsa.pem -config ${DIR}/default.cnf
-openssl ca -gencrl -crldays 30 -keyfile /tmp/cakey.pem -cert /tmp/cacert.pem -out ${DIR}/crl-rsa-dsa-sigopt.pem -config ${DIR}/default.cnf -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:1
+openssl ca -gencrl -startdate 140101010101Z -crldays 30 -keyfile /tmp/cakey.pem -cert /tmp/cacert.pem -out /tmp/crl-rsa-dsa.pem -config ${DIR}/default.cnf
+openssl ca -gencrl -startdate 140101010101Z -crldays 30 -keyfile /tmp/cakey.pem -cert /tmp/cacert.pem -out ${DIR}/crl-rsa-dsa-sigopt.pem -config ${DIR}/default.cnf -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:1
openssl crl -in /tmp/crl-rsa-dsa.pem -outform d -out ${DIR}/crl-rsa-dsa.der
openssl crl -in ${DIR}/crl-rsa-dsa-sigopt.pem -outform d -out ${DIR}/crl-rsa-dsa-sigopt.der
@@ -109,9 +120,6 @@ openssl crl -inform d -in ${DIR}/crl-rsa-dsa.der -noout -lastupdate -nextupdate
rm /tmp/cert-rsa.pem /tmp/cert-dsa.pem /tmp/cacert.pem /tmp/cakey.pem /tmp/crl-rsa.pem /tmp/crl-rsa-dsa.pem /tmp/crl-unsupported.pem /tmp/crl-empty.pem
rm -r /tmp/ca
-rm /tmp/privkey.pem
-rm /tmp/dsapriv.pem
-rm /tmp/ecpriv.pem
cat ${DIR}/cert-rsa.der ${DIR}/cert-dsa.der > /tmp/certs.der
openssl x509 -inform d -in ${DIR}/cert-rsa.der > /tmp/certs.pem
diff --git a/support/src/test/java/tests/resources/x509/crl-empty.der b/support/src/test/java/tests/resources/x509/crl-empty.der
index c5d21a4..8311f48 100644
--- a/support/src/test/java/tests/resources/x509/crl-empty.der
+++ b/support/src/test/java/tests/resources/x509/crl-empty.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dates.txt b/support/src/test/java/tests/resources/x509/crl-rsa-dates.txt
index 4669357..5cee7ef 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-dates.txt
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dates.txt
@@ -1,2 +1,2 @@
-lastUpdate=Mar 6 00:42:08 2013 GMT
-nextUpdate=Mar 8 22:42:08 2013 GMT
+lastUpdate=Jan 28 21:42:15 2014 GMT
+nextUpdate=Jan 31 19:42:15 2014 GMT
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt
index 7700c7e..026eaa5 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt
@@ -1,2 +1,2 @@
-lastUpdate=Mar 6 00:42:08 2013 GMT
-nextUpdate=Apr 5 00:42:08 2013 GMT
+lastUpdate=Jan 28 21:42:16 2014 GMT
+nextUpdate=Feb 27 21:42:16 2014 GMT
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.der b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.der
index ec83979..e30a1d6 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.pem b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.pem
index 87531a2..139f79d 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.pem
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.pem
@@ -1,10 +1,10 @@
-----BEGIN X509 CRL-----
MIIBejCB3wIBATASBgkqhkiG9w0BAQowBaIDAgEBMGAxCzAJBgNVBAYTAlVTMRMw
EQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTYW4gTWF0ZW8xFzAVBgNVBAoT
-Dkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMXDTEzMDMwNjAwNDIwOFoX
-DTEzMDQwNTAwNDIwOFowRjAaAgkAv8J427KUrEIXDTEzMDMwNjAwNDIwOFowKAIJ
-AOgj1gF4KHp/Fw0xMzAzMDYwMDQyMDhaMAwwCgYDVR0VBAMKAQUwEgYJKoZIhvcN
-AQEKMAWiAwIBAQOBgQBDETj4knxhTVoHhpHOAwskEfJLk0i5jW6iSn7nJ62ASlwj
-lXjpgIbEkohn6AkzLMiHXTzZDWu0iEiPwNK17RKlxWAiqVoH0igL50Luc6rNcsit
-+RNnINYIN67JSkLfCxW2iWSDSONRTnbwCo1/XdcpoUFcNkwy5qDWJvcHdjgtGg==
+Dkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMXDTE0MDEyODIxNDIxNloX
+DTE0MDIyNzIxNDIxNlowRjAoAgkA3GiuVsoW87YXDTE0MDEyODIxNDIxNVowDDAK
+BgNVHRUEAwoBBTAaAgn6lDih0pzwAAEXDTE0MDEyODIxNDIxNVowEgYJKoZIhvcN
+AQEKMAWiAwIBAQOBgQARDZPj+o5Ap6hyQn5RYC7/SBIRyhQqY/CwpwsgOUDzJlkn
+3JYbylQ5etrZmspWNu+Yc+smIMEq+EIrsU/hkHNRT7Y3CBl4st4BRBMEIQWQF1qp
+XJ6vvv9wCAX30fDW0GhT/MJS5EW00GGIUAqxOQEZ6mqdAuqwj2z+uMyRvlhl4w==
-----END X509 CRL-----
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dsa.der b/support/src/test/java/tests/resources/x509/crl-rsa-dsa.der
index 32366fa..8e7f241 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-dsa.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dsa.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-sig.der b/support/src/test/java/tests/resources/x509/crl-rsa-sig.der
index 80c915b..1cfb445 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-sig.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-sig.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-tbs.der b/support/src/test/java/tests/resources/x509/crl-rsa-tbs.der
index c444c3a..68e8e98 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-tbs.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-tbs.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa.der b/support/src/test/java/tests/resources/x509/crl-rsa.der
index bde1720..5eddb92 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-unsupported.der b/support/src/test/java/tests/resources/x509/crl-unsupported.der
index 19ffc9c..0636714 100644
--- a/support/src/test/java/tests/resources/x509/crl-unsupported.der
+++ b/support/src/test/java/tests/resources/x509/crl-unsupported.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/dsapriv.pem b/support/src/test/java/tests/resources/x509/dsapriv.pem
new file mode 100644
index 0000000..421bb56
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/dsapriv.pem
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCIr+NnKFrslV6WKMhMH+7nr3eCC4cpRbryh+bUVkXGRDbsTzpl
+369y+NzwnW5yYVzIN0ZJFoI2hO5QZOXr8Syh+q1NmtRpxpqGN+DiL1bxi98Yverm
+E07yyF9/ujV2gJTaaSAUh13GMfHDHbWCJ9yeiRkhxD6N+msuKw2W30tX6wIVAMRe
+pPv/U9NEDKJRONUfusrc62sJAoGAOLKMra6yK0KuoMJth2p0/HKCAoa9/xLfKzGp
+o+4Etck/ZB/BzRn9te17RN3/y1GWVlJAatzzTrsYaazZr0gHUO2c4Vn0bzhRymh/
+w7Sry3hAuSNNA32EiOuP1fOvScu5Z8mOzIe0oSyMDpcJwQyC+aJboq3H1069tGvy
+b/aUtQACgYEAhg6lELBZAIHVkjm7bwVJ5G/ka+KCjXxWXo+BCbqo0LqfrKQoQwUc
+wDzuKdqWxYbyUd0cl5/9fX59/RT/9ULklGy+dTyUSc/hj85PCXLYly3G6WECiN29
+TK0QLhEMZfi+iSm3YxNX3rxvmrHbbfO2SMef4r6ujv9KscDg0zQ4AgYCFBBVJa4Q
+qeta5uYpxwaKIDY63vvK
+-----END DSA PRIVATE KEY-----
diff --git a/support/src/test/java/tests/resources/x509/ecpriv.pem b/support/src/test/java/tests/resources/x509/ecpriv.pem
new file mode 100644
index 0000000..d50ec23
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/ecpriv.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIP+PCqz+I09lnFC8xKUy3ptyvG++iclfVeM6JqjjsFfzoAoGCCqGSM49
+AwEHoUQDQgAE601gdw3eA8D6VYybCSzh4/kbkFrc5+ixMUxQzQEF081+O8xypajz
+fjL+L7JJjNA8AD4ii8uFX8uVuqqYAr6bYg==
+-----END EC PRIVATE KEY-----
diff --git a/support/src/test/java/tests/resources/x509/privkey.pem b/support/src/test/java/tests/resources/x509/privkey.pem
new file mode 100644
index 0000000..8f76a5b
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/privkey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEArfmkkDffJP6ODl13KnTaB8cwvB4anWw8+bGa8y9N7wPx7RWZ
+WFMrfOac01p2fhq+oUIw3/uxRcDAQBQx0ZFLx3OFMuQkTpFbzHeSctsXi1Kk28pn
+4K3BK2CModRh8ir/qdhu0PG4SsXdyN8uT8H6bitmH4vpLaAMMi6aa1M6Ygio8a37
+UCQQ7fw2P7YVR61BsyqwsM/eYtgd2LqrObLwkkOvxTwpZPWDftHI4ucz1rgNnD9q
+0H3gkyGyGq9NBkBHJ25+CkMe+1q/eh4Xt2kt2ML4q5YZmQEwHm1eIR3/uGlb1+bu
+eRMdhrueth/FsUiKPJ0gzmsxzQefgcLnctIx3wIDAQABAoIBAFAIqUjjOxdkt2sq
+WjjA2tB7NRNFcg77jS19JAA9wcdz9CaSKiI02Kuz129vjVVD7nB2588SlaG2I3sX
+DzgOdGMD5MHdrEosmqN8WnXWDoW8djTab2Ev7c6LswZ7krd6SnUTKR+cI6DaV8Yh
+zcdJQHDQLEHU9mdT2mh3gfhfqFsSR+X62SiZfVWPyb31IZV7nbUoSYA3NJ9inC1W
+6cstzzi4IC7Dr+7B1U6FXpInrYZ3dnJRMDJIZDewSxK3BAn3XpUk+03jdGXoA910
+d0tdH6QQdFXhv7ufe3QwxHn1NX7mnCEEqOQiM9cb3WdvZy7STmAf1rRsDzj9VDes
+5jGwkVECgYEA5jf5gI7bK437juBmxJYfCHBS5SigKAGTCTB+EwZ5TXPk9RAO0rj7
+8aNfiNUVe2RqKkzYjJAytg+x+CjVgppRYto/Ho3yEmjJZ94leXgfTzMCqeHIqc/u
+SYI6P9H6bJT7qJtDUEu7qx2r0RXjQ549jH7QlndsE1T55J7GRYjIULcCgYEAwXVA
+XJle7DFm6zOswX5RdZWQWnNvvLWX9UhjQO+HSz9jo1dKnDO99hV4GY8hBawhEFc1
+U41yoyEypsWI3RF/tDHY4v9wa+iA1lx/NrLvQrBQOsNmQV6eSoLtmHlKsI8wXkTc
+QTNemMD7UXUGx38HhEE01IzkV0Y/kBmEHljgMBkCgYBCrEtR9A19W61S/6JDpMZw
+Bze6rj1T2MDglG6uy90tlTbl0jS4ymIM5Sex1SRXjAlDHuZILyrAl2MPX6QWIuMX
+IeXNz4Yf1sEdl7R6rVND+J343S7kHxf/qft8qC9CaxNHDVA9XPGI6Rrtfs1Gs/lX
+SxLVwNhH8QA+Oc1qLeb1mQKBgAaxIp/RYlozP0cli3VKBFFX8h1e3t+dPHtsnJpT
+bs+oiq7MxzTuCUUo6vWfYNoMYTxqd9rDCtMfw9vG+3wCLfOywbjgcygYa9R+cJwY
+xnP9G1ldBv1942Xab5OVpoLDAT5RjXjn6P7JtifUL37ZIw5tHwG3OfLW6D340/wk
+wOSJAoGBALMKM7bSqug2GA7hi4thbfFB7YO+5lUyVlYHMfhCfFtOO2rRl8XIKu9h
+q/XNWuHOLCcz4Y/uixZh7FHdo5/5mlwV703psZ75fEzYN/PSvDtxwE1RlB3JcBL/
+f/Aae1KAK7lLYtVUD+F8lK7V4XIZG+bXBQFqFZCupWV8gq8jf26A
+-----END RSA PRIVATE KEY-----
diff --git a/support/src/test/java/tests/support/Streams.java b/support/src/test/java/tests/support/Streams.java
new file mode 100644
index 0000000..f9f5c77
--- /dev/null
+++ b/support/src/test/java/tests/support/Streams.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.support;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+
+/**
+ * Utility methods for working with byte and character streams.
+ */
+public class Streams {
+ private Streams() {
+ }
+
+ /**
+ * Drains the stream into a byte array and returns the result.
+ */
+ public static byte[] streamToBytes(InputStream source) throws IOException {
+ byte[] buffer = new byte[1024];
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ int count;
+ while ((count = source.read(buffer)) != -1) {
+ out.write(buffer, 0, count);
+ }
+ return out.toByteArray();
+ }
+
+ /**
+ * Drains the stream into a string and returns the result.
+ */
+ public static String streamToString(Reader fileReader) throws IOException {
+ char[] buffer = new char[1024];
+ StringWriter out = new StringWriter();
+ int count;
+ while ((count = fileReader.read(buffer)) != -1) {
+ out.write(buffer, 0, count);
+ }
+ return out.toString();
+ }
+}
diff --git a/support/src/test/java/tests/support/Support_Configuration.java b/support/src/test/java/tests/support/Support_Configuration.java
index 9cb617d..313a448 100644
--- a/support/src/test/java/tests/support/Support_Configuration.java
+++ b/support/src/test/java/tests/support/Support_Configuration.java
@@ -91,8 +91,6 @@ public class Support_Configuration {
// than one addresses returned for this host name as needed by a test
// END android-changed
- public static String hTTPURLwLastModified = "http://www.php.net/manual/en/function.explode.php";
-
public static int SpecialInetTestAddressNumber = 4;
/**
diff --git a/support/src/test/java/tests/support/Support_MapTest.java b/support/src/test/java/tests/support/Support_MapTest.java
new file mode 100644
index 0000000..5dfc69d
--- /dev/null
+++ b/support/src/test/java/tests/support/Support_MapTest.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.support;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import junit.framework.TestCase;
+
+public class Support_MapTest extends TestCase {
+
+ // must be a map containing the string keys "0"-"99" paired with the Integer
+ // values Integer(0) to Integer(99)
+ private final Map<String, Integer> modifiableMap;
+ private final Map<String, Integer> unmodifiableMap;
+
+ public Support_MapTest(String p1, Map<String, Integer> modifiableMap) {
+ super(p1);
+ this.modifiableMap = modifiableMap;
+ unmodifiableMap = Collections.unmodifiableMap(modifiableMap);
+ }
+
+ @Override
+ public void runTest() {
+ testContents(modifiableMap);
+ testContents(unmodifiableMap);
+
+ // values()
+ new Support_UnmodifiableCollectionTest("values() from map test", modifiableMap.values())
+ .runTest();
+ new Support_UnmodifiableCollectionTest("values() from unmodifiable map test",
+ unmodifiableMap.values()).runTest();
+
+ // entrySet()
+ testEntrySet(modifiableMap.entrySet(), unmodifiableMap.entrySet());
+
+ // keySet()
+ testKeySet(modifiableMap.keySet(), unmodifiableMap.keySet());
+ }
+
+ private void testContents(Map<String, Integer> map) {
+ // size
+ assertTrue("Size should return 100, returned: " + map.size(), map.size() == 100);
+
+ // containsKey
+ assertTrue("Should contain the key \"0\"", map.containsKey("0"));
+ assertTrue("Should contain the key \"50\"", map.containsKey("50"));
+ assertTrue("Should not contain the key \"100\"", !map.containsKey("100"));
+
+ // containsValue
+ assertTrue("Should contain the value 0", map.containsValue(0));
+ assertTrue("Should contain the value 50", map.containsValue(50));
+ assertTrue("Should not contain value 100", !map.containsValue(100));
+
+ // get
+ assertTrue("getting \"0\" didn't return 0", map.get("0") == 0);
+ assertTrue("getting \"50\" didn't return 50", map.get("50") == 50);
+ assertNull("getting \"100\" didn't return null", map.get("100"));
+
+ // isEmpty
+ assertTrue("should have returned false to isEmpty", !map.isEmpty());
+ }
+
+ private static void testEntrySet(
+ Set<Map.Entry<String, Integer>> referenceEntrySet,
+ Set<Map.Entry<String, Integer>> entrySet) {
+ // entrySet should be a set of mappings {"0", 0}, {"1",1}... {"99", 99}
+ assertEquals(100, referenceEntrySet.size());
+ assertEquals(100, entrySet.size());
+
+ // The ordering may be undefined for a map implementation but the ordering must be the
+ // same across iterator(), toArray() and toArray(T[]) for a given map *and* the same for the
+ // modifiable and unmodifiable map.
+ crossCheckOrdering(referenceEntrySet, entrySet, Map.Entry.class);
+ }
+
+ private static void testKeySet(Set<String> referenceKeySet, Set<String> keySet) {
+ // keySet should be a set of the strings "0" to "99"
+ testKeySetContents(referenceKeySet);
+ testKeySetContents(keySet);
+
+ // The ordering may be undefined for a map implementation but the ordering must be the
+ // same across iterator(), toArray() and toArray(T[]) for a given map *and* the same for the
+ // modifiable and unmodifiable map.
+ crossCheckOrdering(referenceKeySet, keySet, String.class);
+ }
+
+ private static void testKeySetContents(Set<String> keySet) {
+ // contains
+ assertTrue("should contain \"0\"", keySet.contains("0"));
+ assertTrue("should contain \"50\"", keySet.contains("50"));
+ assertTrue("should not contain \"100\"", !keySet.contains("100"));
+
+ // containsAll
+ HashSet<String> hs = new HashSet<String>();
+ hs.add("0");
+ hs.add("25");
+ hs.add("99");
+ assertTrue("Should contain set of \"0\", \"25\", and \"99\"", keySet.containsAll(hs));
+ hs.add("100");
+ assertTrue("Should not contain set of \"0\", \"25\", \"99\" and \"100\"",
+ !keySet.containsAll(hs));
+
+ // isEmpty
+ assertTrue("Should not be empty", !keySet.isEmpty());
+
+ // size
+ assertEquals("Returned wrong size.", 100, keySet.size());
+ }
+
+ private static <T> void crossCheckOrdering(Set<T> set1, Set<T> set2, Class<?> elementType) {
+ Iterator<T> set1Iterator = set1.iterator();
+ Iterator<T> set2Iterator = set2.iterator();
+
+ T[] zeroLengthArray = createArray(elementType, 0);
+ T[] set1TypedArray1 = set1.toArray(zeroLengthArray);
+ assertEquals(set1.size(), set1TypedArray1.length);
+
+ // Compare set1.iterator(), set2.iterator() and set1.toArray(new T[0])
+ int entryCount = 0;
+ while (set1Iterator.hasNext()) {
+ T set1Entry = set1Iterator.next();
+ T set2Entry = set2Iterator.next();
+
+ // Compare set1 with set2
+ assertEquals(set1Entry, set2Entry);
+
+ // Compare the iterator with the array. The arrays will be checked against each other.
+ assertEquals(set1Entry, set1TypedArray1[entryCount]);
+
+ entryCount++;
+ }
+ assertFalse(set2Iterator.hasNext());
+ assertEquals(set1.size(), entryCount);
+
+ // Compare the various arrays with each other.
+
+ // set1.toArray(new T[size])
+ T[] parameterArray1 = createArray(elementType, set1.size());
+ T[] set1TypedArray2 = set1.toArray(parameterArray1);
+ assertSame(set1TypedArray2, parameterArray1);
+ assertArrayEquals(set1TypedArray1, set1TypedArray2);
+
+ // set1.toArray()
+ Object[] set1UntypedArray = set1.toArray();
+ assertEquals(set1.size(), set1UntypedArray.length);
+ assertArrayEquals(set1TypedArray1, set1UntypedArray);
+
+ // set2.toArray(new T[0])
+ T[] set2TypedArray1 = set2.toArray(zeroLengthArray);
+ assertEquals(set1.size(), set2TypedArray1.length);
+ assertArrayEquals(set1TypedArray1, set2TypedArray1);
+
+ // set2.toArray(new T[size])
+ T[] parameterArray2 = createArray(elementType, set2.size());
+ T[] set2TypedArray2 = set1.toArray(parameterArray2);
+ assertSame(set2TypedArray2, parameterArray2);
+ assertArrayEquals(set1TypedArray1, set1TypedArray2);
+
+ // set2.toArray()
+ Object[] set2UntypedArray = set2.toArray();
+ assertArrayEquals(set1TypedArray1, set2UntypedArray);
+ }
+
+ private static <T> void assertArrayEquals(T[] array1, T[] array2) {
+ assertTrue(Arrays.equals(array1, array2));
+ }
+
+ private static <T> T[] createArray(Class<?> elementType, int size) {
+ return (T[]) Array.newInstance(elementType, size);
+ }
+}
diff --git a/support/src/test/java/tests/support/Support_PlatformFile.java b/support/src/test/java/tests/support/Support_PlatformFile.java
deleted file mode 100644
index 1486b20..0000000
--- a/support/src/test/java/tests/support/Support_PlatformFile.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.support;
-
-public class Support_PlatformFile {
-
- private static String platformId = null;
-
- public static String getNewPlatformFile(String pre, String post) {
- if (platformId == null) {
- String property = System.getProperty("com.ibm.oti.configuration");
- if (property == null) {
- property = "JDK";
- }
- platformId = property
- + System.getProperty("java.vm.version").replace('.', '-');
- }
- return pre + platformId + post;
- }
-
-}
diff --git a/support/src/test/java/tests/support/Support_PortManager.java b/support/src/test/java/tests/support/Support_PortManager.java
deleted file mode 100644
index b68a445..0000000
--- a/support/src/test/java/tests/support/Support_PortManager.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.support;
-
-import java.net.DatagramSocket;
-import java.net.ServerSocket;
-import java.util.Calendar;
-import java.util.TimeZone;
-
-/**
- * The port manager is supposed to help finding a free
- * network port on the machine; however, it uses strange
- * logic, so leave it to the OS.
- *
- * @deprecated Use the OS to find free ports.
- */
-public class Support_PortManager {
-
- private static int lastAssignedPort = somewhatRandomPort();
- private static boolean failedOnce = false;
-
- public static synchronized int getNextPort() {
- if (!failedOnce) {
- try {
- ServerSocket ss = new ServerSocket(0);
- int port = ss.getLocalPort();
-
- ss.close();
- return port;
- } catch (Exception ex) {
- failedOnce = true;
- }
- }
- return getNextPort_unsafe();
- }
-
- /**
- * Returns 1 free ports to be used.
- */
- public static synchronized int getNextPortForUDP() {
- return getNextPortsForUDP(1)[0];
- }
-
- /**
- * Returns the specified number of free ports to be used.
- */
- public static synchronized int[] getNextPortsForUDP(int num) {
- if (num <= 0) {
- throw new IllegalArgumentException("Invalid ports number: " + num);
- }
- DatagramSocket[] dss = new DatagramSocket[num];
- int[] ports = new int[num];
-
- try {
- for (int i = 0; i < num; ++i) {
- dss[i] = new DatagramSocket(0);
- ports[i] = dss[i].getLocalPort();
- }
- } catch (Exception ex) {
- throw new Error("Unable to get " + num + " ports for UDP: " + ex);
- } finally {
- for (int i = 0; i < num; ++i) {
- if (dss[i] != null) {
- dss[i].close();
- }
- }
- }
- return ports;
- }
-
- public static synchronized int getNextPort_unsafe() {
- if (++lastAssignedPort > 65534) {
- lastAssignedPort = 6000;
- }
- return lastAssignedPort;
- }
-
- /*
- * Returns a different port number every 6 seconds or so. The port number
- * should be about += 100 at each 6 second interval
- */
- private static int somewhatRandomPort() {
- Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- int minutes = c.get(Calendar.MINUTE);
- int seconds = c.get(Calendar.SECOND);
-
- return 6000 + (1000 * minutes) + ((seconds / 6) * 100);
- }
-
-}
diff --git a/support/src/test/java/tests/support/Support_TestWebData.java b/support/src/test/java/tests/support/Support_TestWebData.java
index 9fdd021..e7f13e8 100644
--- a/support/src/test/java/tests/support/Support_TestWebData.java
+++ b/support/src/test/java/tests/support/Support_TestWebData.java
@@ -19,7 +19,6 @@ package tests.support;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
@@ -31,6 +30,12 @@ public class Support_TestWebData {
public final static byte[] test1 = utfBytes();
public final static byte[] test2 = newBinaryFile(8192);
+ // Although the tests report the content length of this file as being large, a file is created
+ // that is much shorter. Actually creating a large file is not practical during tests. This
+ // file should only be used for checking header information.
+ private static final long TEST_3_CONTENT_LENGTH = ((long) Integer.MAX_VALUE) + 1;
+ public final static byte[] test3 = newBinaryFile(3);
+
private static byte[] utfBytes() {
try {
return "<html>\n<body>\n<h1>Hello World!</h1>\n</body>\n</html>\n".getBytes("UTF-8");
@@ -53,7 +58,8 @@ public class Support_TestWebData {
// Array of all test data
public final static byte[][] tests = {
test1,
- test2
+ test2,
+ test3,
};
/**
@@ -62,7 +68,9 @@ public class Support_TestWebData {
public static Support_TestWebData[] testParams = {
new Support_TestWebData(test1.length, 14000000, "test1", "text/html", false, 0),
new Support_TestWebData(test2.length, 14000002, "test2", "unknown/unknown", false,
- new Date().getTime() + 100000)
+ new Date().getTime() + 100000),
+ new Support_TestWebData(TEST_3_CONTENT_LENGTH, 14000004, "test3", "unknown/unknown", false,
+ new Date().getTime() + 100000),
};
/**
@@ -85,7 +93,7 @@ public class Support_TestWebData {
* Creates a data package with information used by the server when responding
* to requests
*/
- Support_TestWebData(int length, int lastModified, String name, String type, boolean isDir, long expDate) {
+ Support_TestWebData(long length, int lastModified, String name, String type, boolean isDir, long expDate) {
testLength = length;
testLastModified = lastModified;
testName = name;
diff --git a/support/src/test/java/tests/support/Support_TimeZone.java b/support/src/test/java/tests/support/Support_TimeZone.java
new file mode 100644
index 0000000..e2c3e65
--- /dev/null
+++ b/support/src/test/java/tests/support/Support_TimeZone.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.support;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * Sample java.util.TimeZone subclass to test getDSTSavings() and getOffset(long)
+ * APIs
+ */
+public class Support_TimeZone extends TimeZone {
+ private static final long serialVersionUID = 1L;
+
+ int rawOffset;
+
+ boolean useDaylightTime;
+
+ public Support_TimeZone(int rawOffset, boolean useDaylightTime) {
+ this.rawOffset = rawOffset;
+ this.useDaylightTime = useDaylightTime;
+ }
+
+ @Override
+ public int getRawOffset() {
+ return rawOffset;
+ }
+
+ /**
+ * let's assume this timezone has daylight savings from the 4th month till
+ * the 10th month of the year to ame things simple.
+ */
+ @Override
+ public boolean inDaylightTime(java.util.Date p1) {
+ if (!useDaylightTime) {
+ return false;
+ }
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setTime(p1);
+ int month = cal.get(Calendar.MONTH);
+
+ if (month > 4 && month < 10) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean useDaylightTime() {
+ return useDaylightTime;
+ }
+
+ /*
+ * return 0 to keep it simple, since this subclass is not used to test this
+ * method..
+ */
+ @Override
+ public int getOffset(int p1, int p2, int p3, int p4, int p5, int p6) {
+ return 0;
+ }
+
+ @Override
+ public void setRawOffset(int p1) {
+ rawOffset = p1;
+ }
+}
diff --git a/support/src/test/java/tests/support/Support_UnmodifiableMapTest.java b/support/src/test/java/tests/support/Support_UnmodifiableMapTest.java
deleted file mode 100644
index e7a1620..0000000
--- a/support/src/test/java/tests/support/Support_UnmodifiableMapTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.support;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import junit.framework.TestCase;
-
-public class Support_UnmodifiableMapTest extends TestCase {
-
- Map<String, Integer> map;
-
- // must be a map containing the string keys "0"-"99" paired with the Integer
- // values Integer(0) to Integer(99)
-
- public Support_UnmodifiableMapTest(String p1) {
- super(p1);
- }
-
- public Support_UnmodifiableMapTest(String p1, Map<String, Integer> m) {
- super(p1);
- map = m;
- }
-
- @Override
- public void runTest() {
- // containsKey
- assertTrue("UnmodifiableMapTest - Should contain the key \"0\"", map
- .containsKey("0"));
- assertTrue("UnmodifiableMapTest - Should contain the key \"50\"", map
- .containsKey("50"));
- assertTrue("UnmodifiableMapTest - Should not contain the key \"100\"",
- !map.containsKey("100"));
-
- // containsValue
- assertTrue("UnmodifiableMapTest - Should contain the value 0", map
- .containsValue(new Integer(0)));
- assertTrue("UnmodifiableMapTest - Should contain the value 50", map
- .containsValue(new Integer(50)));
- assertTrue("UnmodifiableMapTest - Should not contain value 100", !map
- .containsValue(new Integer(100)));
-
- // entrySet
- Set<?> entrySet = map.entrySet();
- Iterator<?> entrySetIterator = entrySet.iterator();
- int myCounter = 0;
- while (entrySetIterator.hasNext()) {
- Map.Entry<?, ?> me = (Map.Entry<?, ?>) entrySetIterator.next();
- assertTrue("UnmodifiableMapTest - Incorrect Map.Entry returned",
- map.get(me.getKey()).equals(me.getValue()));
- myCounter++;
- }
- assertEquals("UnmodifiableMapTest - Incorrect number of map entries returned",
- 100, myCounter);
-
- // get
- assertTrue("UnmodifiableMapTest - getting \"0\" didn't return 0",
- map.get("0").intValue() == 0);
- assertTrue("UnmodifiableMapTest - getting \"50\" didn't return 0",
- map.get("0").intValue() == 0);
- assertNull("UnmodifiableMapTest - getting \"100\" didn't return null",
- map.get("100"));
-
- // isEmpty
- assertTrue(
- "UnmodifiableMapTest - should have returned false to isEmpty",
- !map.isEmpty());
-
- // keySet
- Set<?> keySet = map.keySet();
- t_KeySet(keySet);
-
- // size
- assertTrue("Size should return 100, returned: " + map.size(), map
- .size() == 100);
-
- // values
- new Support_UnmodifiableCollectionTest("Unmod--from map test", map
- .values());
-
- }
-
- void t_KeySet(Set<?> keySet) {
- // keySet should be a set of the strings "0" to "99"
-
- // contains
- assertTrue("UnmodifiableMapTest - keySetTest - should contain \"0\"",
- keySet.contains("0"));
- assertTrue("UnmodifiableMapTest - keySetTest - should contain \"50\"",
- keySet.contains("50"));
- assertTrue(
- "UnmodifiableMapTest - keySetTest - should not contain \"100\"",
- !keySet.contains("100"));
-
- // containsAll
- HashSet<String> hs = new HashSet<String>();
- hs.add("0");
- hs.add("25");
- hs.add("99");
- assertTrue(
- "UnmodifiableMapTest - keySetTest - should contain set of \"0\", \"25\", and \"99\"",
- keySet.containsAll(hs));
- hs.add("100");
- assertTrue(
- "UnmodifiableMapTest - keySetTest - should not contain set of \"0\", \"25\", \"99\" and \"100\"",
- !keySet.containsAll(hs));
-
- // isEmpty
- assertTrue("UnmodifiableMapTest - keySetTest - should not be empty",
- !keySet.isEmpty());
-
- // iterator
- Iterator<?> it = keySet.iterator();
- while (it.hasNext()) {
- assertTrue(
- "UnmodifiableMapTest - keySetTest - Iterator returned wrong values",
- keySet.contains(it.next()));
- }
-
- // size
- assertTrue(
- "UnmodifiableMapTest - keySetTest - returned wrong size. Wanted 100, got: "
- + keySet.size(), keySet.size() == 100);
-
- // toArray
- Object[] objArray;
- objArray = keySet.toArray();
- for (int counter = 0; it.hasNext(); counter++) {
- assertTrue(
- "UnmodifiableMapTest - keySetTest - toArray returned incorrect array",
- objArray[counter] == it.next());
- }
-
- // toArray (Object[])
- objArray = new Object[100];
- keySet.toArray(objArray);
- for (int counter = 0; it.hasNext(); counter++) {
- assertTrue(
- "UnmodifiableMapTest - keySetTest - toArray(Object) filled array incorrectly",
- objArray[counter] == it.next());
- }
- }
-
-}
diff --git a/support/src/test/java/tests/support/resource/Support_Resources.java b/support/src/test/java/tests/support/resource/Support_Resources.java
index ddcb881..82143ac 100644
--- a/support/src/test/java/tests/support/resource/Support_Resources.java
+++ b/support/src/test/java/tests/support/resource/Support_Resources.java
@@ -196,4 +196,18 @@ public class Support_Resources {
xml.close();
return f;
}
+
+ public static void copyLocalFileTo(File dest, InputStream in) throws IOException {
+ if (!dest.exists()) {
+ FileOutputStream out = new FileOutputStream(dest);
+ int result;
+ byte[] buf = new byte[4096];
+ while ((result = in.read(buf)) != -1) {
+ out.write(buf, 0, result);
+ }
+ in.close();
+ out.close();
+ dest.deleteOnExit();
+ }
+ }
}
diff --git a/support/src/test/java/tests/util/SerializationTester.java b/support/src/test/java/tests/util/SerializationTester.java
new file mode 100644
index 0000000..22635e1
--- /dev/null
+++ b/support/src/test/java/tests/util/SerializationTester.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.net.URL;
+
+/**
+ * This class simplifies the serialization test.
+ */
+public class SerializationTester {
+ private SerializationTester() {
+
+ }
+
+ /**
+ * Serialize an object and then deserialize it.
+ *
+ * @param inputObject the input object
+ * @return the deserialized object
+ */
+ public static Object getDeserilizedObject(Object inputObject)
+ throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(inputObject);
+ oos.close();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bis);
+ Object outputObject = ois.readObject();
+ ois.close();
+ return outputObject;
+ }
+
+ /**
+ * Tests the serialization and deserialization of const objects.
+ *
+ * @param inputObject A const object
+ * @return true if the deserialized object is the same as the input object,
+ * otherwise false
+ * @throws Exception If any occurs.
+ */
+ public static boolean assertSame(Object inputObject) throws Exception {
+ return inputObject == getDeserilizedObject(inputObject);
+ }
+
+ /**
+ * Tests the serialization and deserialization of instance objects.
+ *
+ * @param inputObject An object
+ * @return true if the deserialized object is equal to the input object,
+ * otherwise false
+ * @throws Exception If any occurs.
+ */
+ public static boolean assertEquals(Object inputObject) throws Exception {
+ return inputObject.equals(getDeserilizedObject(inputObject));
+ }
+
+ /**
+ * Tests the serialization compatibility with reference const objects.
+ *
+ * @param obj the object to be checked
+ * @param fileName the serialization output file generated by reference
+ * @return true if compatible, otherwise false
+ * @throws Exception If any occurs.
+ */
+ public static boolean assertCompabilitySame(Object obj, String fileName)
+ throws Exception {
+ return obj == readObject(obj, fileName);
+ }
+
+ /**
+ * Tests the serialization compatibility with reference for instance
+ * objects.
+ *
+ * @param obj the object to be checked
+ * @param fileName the serialization output file generated by reference
+ * @return true if compatible, otherwise false
+ * @throws Exception If any occurs.
+ */
+ public static boolean assertCompabilityEquals(Object obj, String fileName)
+ throws Exception {
+ return obj.equals(readObject(obj, fileName));
+ }
+
+ /**
+ * Deserialize an object from a file.
+ *
+ * @param obj the object to be serialized if no serialization file is found
+ * @param fileName the serialization file
+ * @return the deserialized object
+ * @throws Exception If any occurs.
+ */
+ public static Object readObject(Object obj, String fileName)
+ throws Exception {
+ InputStream input = null;
+ ObjectInputStream oinput = null;
+ URL url = SerializationTester.class.getClassLoader().getResource(fileName);
+ if (null == url) {
+ // serialization file does not exist, create one in the current dir
+ writeObject(obj, new File(fileName).getName());
+ throw new Error(
+ "Serialization file does not exist, created in the current dir.");
+ }
+ input = url.openStream();
+ try {
+ oinput = new ObjectInputStream(input);
+ Object newObj = oinput.readObject();
+ return newObj;
+ } finally {
+ try {
+ if (null != oinput) {
+ oinput.close();
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ try {
+ if (null != input) {
+ input.close();
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ /*
+ * Creates a serialization output.
+ *
+ * @param obj the object to be serialized @param fileName the output file
+ * @throws Exception If any occurs.
+ */
+ public static void writeObject(Object obj, String fileName)
+ throws Exception {
+ // String path = SerializationTester.class.getResource(".").getPath();
+ // if (path.endsWith(".")) {
+ // path = path.substring(0, path.length() - 1);
+ // }
+ // if (!path.endsWith("/")) {
+ // path += "/";
+ // }
+ // path += fileName;
+ // System.out.println(path);
+ OutputStream output = null;
+ ObjectOutputStream ooutput = null;
+ try {
+ output = new FileOutputStream(fileName);
+ ooutput = new ObjectOutputStream(output);
+ ooutput.writeObject(obj);
+ } finally {
+ try {
+ if (null != ooutput) {
+ ooutput.close();
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ try {
+ if (null != output) {
+ output.close();
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/xml/src/main/java/org/kxml2/io/KXmlParser.java b/xml/src/main/java/org/kxml2/io/KXmlParser.java
index 84376ae..a90db3b 100644
--- a/xml/src/main/java/org/kxml2/io/KXmlParser.java
+++ b/xml/src/main/java/org/kxml2/io/KXmlParser.java
@@ -163,6 +163,9 @@ public class KXmlParser implements XmlPullParser, Closeable {
private boolean degenerated;
private int attributeCount;
+ // true iff. we've encountered the START_TAG of an XML element at depth == 0;
+ private boolean parsedTopLevelStartTag;
+
/*
* The current element's attributes arranged in groups of 4:
* i + 0 = attribute namespace URI
@@ -416,6 +419,9 @@ public class KXmlParser implements XmlPullParser, Closeable {
break;
case DOCDECL:
readDoctype(justOneToken);
+ if (parsedTopLevelStartTag) {
+ throw new XmlPullParserException("Unexpected token", this, null);
+ }
break;
default:
@@ -1128,6 +1134,9 @@ public class KXmlParser implements XmlPullParser, Closeable {
}
int sp = depth++ * 4;
+ if (depth == 1) {
+ parsedTopLevelStartTag = true;
+ }
elementStack = ensureCapacity(elementStack, sp + 4);
elementStack[sp + 3] = name;
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
index e042eb8..0958bbf 100644
--- a/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
@@ -913,7 +913,7 @@ public interface XmlPullParser {
throws XmlPullParserException;
/**
- * Get next parsing event - element content wil be coalesced and only one
+ * Get next parsing event - element content will be coalesced and only one
* TEXT event must be returned for whole element content
* (comments and processing instructions will be ignored and entity references
* must be expanded or exception mus be thrown if entity reference can not be expanded).
@@ -1052,7 +1052,7 @@ public interface XmlPullParser {
* If current event is START_TAG then if next element is TEXT then element content is returned
* or if next event is END_TAG then empty string is returned, otherwise exception is thrown.
* After calling this function successfully parser will be positioned on END_TAG.
- *
+ *
* <p>The motivation for this function is to allow to parse consistently both
* empty elements and elements that has non empty content, for example for input: <ol>
* <li>&lt;tag&gt;foo&lt;/tag&gt;
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
index 4375a41..41db89c 100644
--- a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
@@ -3,28 +3,15 @@
package org.xmlpull.v1;
-import java.io.InputStream;
+import org.kxml2.io.KXmlParser;
+import org.kxml2.io.KXmlSerializer;
+
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
+import java.util.Map;
/**
* This class is used to create implementations of XML Pull Parser defined in XMPULL V1 API.
- * The name of actual factory class will be determined based on several parameters.
- * It works similar to JAXP but tailored to work in J2ME environments
- * (no access to system properties or file system) so name of parser class factory to use
- * and its class used for loading (no class loader - on J2ME no access to context class loaders)
- * must be passed explicitly. If no name of parser factory was passed (or is null)
- * it will try to find name by searching in CLASSPATH for
- * META-INF/services/org.xmlpull.v1.XmlPullParserFactory resource that should contain
- * a comma separated list of class names of factories or parsers to try (in order from
- * left to the right). If none found, it will throw an exception.
- *
- * <br /><strong>NOTE:</strong>In J2SE or J2EE environments, you may want to use
- * <code>newInstance(property, classLoaderCtx)</code>
- * where first argument is
- * <code>System.getProperty(XmlPullParserFactory.PROPERTY_NAME)</code>
- * and second is <code>Thread.getContextClassLoader().getClass()</code> .
*
* @see XmlPullParser
*
@@ -33,50 +20,33 @@ import java.util.Iterator;
*/
public class XmlPullParserFactory {
- /** used as default class to server as context class in newInstance() */
- final static Class referenceContextClass;
-
- static {
- XmlPullParserFactory f = new XmlPullParserFactory();
- referenceContextClass = f.getClass();
- }
-
- /** Name of the system or midlet property that should be used for
- a system property containing a comma separated list of factory
- or parser class names (value:
- org.xmlpull.v1.XmlPullParserFactory). */
-
-
- public static final String PROPERTY_NAME =
- "org.xmlpull.v1.XmlPullParserFactory";
-
- private static final String RESOURCE_NAME =
- "/META-INF/services/" + PROPERTY_NAME;
-
-
- // public static final String DEFAULT_PROPERTY =
- // "org.xmlpull.xpp3.XmlPullParser,org.kxml2.io.KXmlParser";
-
+ public static final String PROPERTY_NAME = "org.xmlpull.v1.XmlPullParserFactory";
protected ArrayList parserClasses;
- protected String classNamesLocation;
-
protected ArrayList serializerClasses;
+ /** Unused, but we have to keep it because it's public API. */
+ protected String classNamesLocation = null;
// features are kept there
- protected HashMap features = new HashMap();
-
+ // TODO: This can't be made final because it's a public API.
+ protected HashMap<String, Boolean> features = new HashMap<String, Boolean>();
/**
* Protected constructor to be called by factory implementations.
*/
-
protected XmlPullParserFactory() {
+ parserClasses = new ArrayList<String>();
+ serializerClasses = new ArrayList<String>();
+
+ try {
+ parserClasses.add(Class.forName("org.kxml2.io.KXmlParser"));
+ serializerClasses.add(Class.forName("org.kxml2.io.KXmlSerializer"));
+ } catch (ClassNotFoundException e) {
+ throw new AssertionError();
+ }
}
-
-
/**
* Set the features to be set when XML Pull Parser is created by this factory.
* <p><b>NOTE:</b> factory features are not used for XML Serializer.
@@ -84,7 +54,6 @@ public class XmlPullParserFactory {
* @param name string with URI identifying feature
* @param state if true feature will be set; if false will be ignored
*/
-
public void setFeature(String name, boolean state) throws XmlPullParserException {
features.put(name, state);
}
@@ -98,9 +67,8 @@ public class XmlPullParserFactory {
* @return The value of named feature.
* Unknown features are <string>always</strong> returned as false
*/
-
- public boolean getFeature (String name) {
- Boolean value = (Boolean) features.get(name);
+ public boolean getFeature(String name) {
+ Boolean value = features.get(name);
return value != null ? value.booleanValue() : false;
}
@@ -112,7 +80,6 @@ public class XmlPullParserFactory {
* @param awareness true if the parser produced by this code
* will provide support for XML namespaces; false otherwise.
*/
-
public void setNamespaceAware(boolean awareness) {
features.put (XmlPullParser.FEATURE_PROCESS_NAMESPACES, awareness);
}
@@ -125,12 +92,10 @@ public class XmlPullParserFactory {
* @return true if the factory is configured to produce parsers
* which are namespace aware; false otherwise.
*/
-
public boolean isNamespaceAware() {
- return getFeature (XmlPullParser.FEATURE_PROCESS_NAMESPACES);
+ return getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
}
-
/**
* Specifies that the parser produced by this factory will be validating
* (it simply set feature XmlPullParser.FEATURE_VALIDATION to true or false).
@@ -139,9 +104,8 @@ public class XmlPullParserFactory {
*
* @param validating - if true the parsers created by this factory must be validating.
*/
-
public void setValidating(boolean validating) {
- features.put (XmlPullParser.FEATURE_VALIDATION, validating);
+ features.put(XmlPullParser.FEATURE_VALIDATION, validating);
}
/**
@@ -153,7 +117,7 @@ public class XmlPullParserFactory {
*/
public boolean isValidating() {
- return getFeature (XmlPullParser.FEATURE_VALIDATION);
+ return getFeature(XmlPullParser.FEATURE_VALIDATION);
}
/**
@@ -161,42 +125,81 @@ public class XmlPullParserFactory {
* using the currently configured factory features.
*
* @return A new instance of a XML Pull Parser.
- * @throws XmlPullParserException if a parser cannot be created which satisfies the
- * requested configuration.
*/
-
public XmlPullParser newPullParser() throws XmlPullParserException {
+ final XmlPullParser pp = getParserInstance();
+ for (Map.Entry<String, Boolean> entry : features.entrySet()) {
+ // NOTE: This test is needed for compatibility reasons. We guarantee
+ // that we only set a feature on a parser if its value is true.
+ if (entry.getValue()) {
+ pp.setFeature(entry.getKey(), entry.getValue());
+ }
+ }
- if (parserClasses == null) throw new XmlPullParserException
- ("Factory initialization was incomplete - has not tried "+classNamesLocation);
+ return pp;
+ }
- if (parserClasses.size() == 0) throw new XmlPullParserException
- ("No valid parser classes found in "+classNamesLocation);
+ private XmlPullParser getParserInstance() throws XmlPullParserException {
+ ArrayList<Exception> exceptions = null;
+
+ if (parserClasses != null && !parserClasses.isEmpty()) {
+ exceptions = new ArrayList<Exception>();
+ for (Object o : parserClasses) {
+ try {
+ if (o != null) {
+ Class<?> parserClass = (Class<?>) o;
+ return (XmlPullParser) parserClass.newInstance();
+ }
+ } catch (InstantiationException e) {
+ exceptions.add(e);
+ } catch (IllegalAccessException e) {
+ exceptions.add(e);
+ } catch (ClassCastException e) {
+ exceptions.add(e);
+ }
+ }
+ }
- final StringBuilder issues = new StringBuilder();
+ throw newInstantiationException("Invalid parser class list", exceptions);
+ }
- for (int i = 0; i < parserClasses.size(); i++) {
- final Class ppClass = (Class) parserClasses.get(i);
- try {
- final XmlPullParser pp = (XmlPullParser) ppClass.newInstance();
+ private XmlSerializer getSerializerInstance() throws XmlPullParserException {
+ ArrayList<Exception> exceptions = null;
- for (Iterator iter = features.keySet().iterator(); iter.hasNext(); ) {
- final String key = (String) iter.next();
- final Boolean value = (Boolean) features.get(key);
- if(value != null && value.booleanValue()) {
- pp.setFeature(key, true);
+ if (serializerClasses != null && !serializerClasses.isEmpty()) {
+ exceptions = new ArrayList<Exception>();
+ for (Object o : serializerClasses) {
+ try {
+ if (o != null) {
+ Class<?> serializerClass = (Class<?>) o;
+ return (XmlSerializer) serializerClass.newInstance();
}
+ } catch (InstantiationException e) {
+ exceptions.add(e);
+ } catch (IllegalAccessException e) {
+ exceptions.add(e);
+ } catch (ClassCastException e) {
+ exceptions.add(e);
}
- return pp;
-
- } catch(Exception ex) {
- issues.append (ppClass.getName () + ": "+ ex.toString ()+"; ");
}
}
- throw new XmlPullParserException ("could not create parser: "+issues);
+ throw newInstantiationException("Invalid serializer class list", exceptions);
}
+ private static XmlPullParserException newInstantiationException(String message,
+ ArrayList<Exception> exceptions) {
+ if (exceptions == null || exceptions.isEmpty()) {
+ return new XmlPullParserException(message);
+ } else {
+ XmlPullParserException exception = new XmlPullParserException(message);
+ for (Exception ex : exceptions) {
+ exception.addSuppressed(ex);
+ }
+
+ return exception;
+ }
+ }
/**
* Creates a new instance of a XML Serializer.
@@ -209,137 +212,26 @@ public class XmlPullParserFactory {
*/
public XmlSerializer newSerializer() throws XmlPullParserException {
-
- if (serializerClasses == null) {
- throw new XmlPullParserException
- ("Factory initialization incomplete - has not tried "+classNamesLocation);
- }
- if(serializerClasses.size() == 0) {
- throw new XmlPullParserException
- ("No valid serializer classes found in "+classNamesLocation);
- }
-
- final StringBuilder issues = new StringBuilder ();
-
- for (int i = 0; i < serializerClasses.size (); i++) {
- final Class ppClass = (Class) serializerClasses.get(i);
- try {
- final XmlSerializer ser = (XmlSerializer) ppClass.newInstance();
-
- return ser;
-
- } catch(Exception ex) {
- issues.append (ppClass.getName () + ": "+ ex.toString ()+"; ");
- }
- }
-
- throw new XmlPullParserException ("could not create serializer: "+issues);
+ return getSerializerInstance();
}
/**
- * Create a new instance of a PullParserFactory that can be used
- * to create XML pull parsers (see class description for more
- * details).
- *
- * @return a new instance of a PullParserFactory, as returned by newInstance (null, null);
+ * Creates a new instance of a PullParserFactory that can be used
+ * to create XML pull parsers. The factory will always return instances
+ * of {@link KXmlParser} and {@link KXmlSerializer}.
*/
public static XmlPullParserFactory newInstance () throws XmlPullParserException {
- return newInstance(null, null);
+ return new XmlPullParserFactory();
}
- public static XmlPullParserFactory newInstance (String classNames, Class context)
+ /**
+ * Creates a factory that always returns instances of of {@link KXmlParser} and
+ * {@link KXmlSerializer}. This <b>does not</b> support factories capable of
+ * creating arbitrary parser and serializer implementations. Both arguments to this
+ * method are unused.
+ */
+ public static XmlPullParserFactory newInstance (String unused, Class unused2)
throws XmlPullParserException {
-
- /*
- if (context == null) {
- //NOTE: make sure context uses the same class loader as API classes
- // this is the best we can do without having access to context classloader in J2ME
- // if API is in the same classloader as implementation then this will work
- context = referenceContextClass;
- }
-
- String classNamesLocation = null;
-
- if (classNames == null || classNames.length() == 0 || "DEFAULT".equals(classNames)) {
- try {
- InputStream is = context.getResourceAsStream (RESOURCE_NAME);
-
- if (is == null) throw new XmlPullParserException
- ("resource not found: "+RESOURCE_NAME
- +" make sure that parser implementing XmlPull API is available");
- final StringBuilder sb = new StringBuilder();
-
- while (true) {
- final int ch = is.read();
- if (ch < 0) break;
- else if (ch > ' ')
- sb.append((char) ch);
- }
- is.close ();
-
- classNames = sb.toString ();
- }
- catch (Exception e) {
- throw new XmlPullParserException (null, null, e);
- }
- classNamesLocation = "resource "+RESOURCE_NAME+" that contained '"+classNames+"'";
- } else {
- classNamesLocation =
- "parameter classNames to newInstance() that contained '"+classNames+"'";
- }
- */
- classNames = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
-
- XmlPullParserFactory factory = null;
- final ArrayList parserClasses = new ArrayList();
- final ArrayList serializerClasses = new ArrayList();
- int pos = 0;
-
- while (pos < classNames.length ()) {
- int cut = classNames.indexOf (',', pos);
-
- if (cut == -1) cut = classNames.length ();
- final String name = classNames.substring (pos, cut);
-
- Class candidate = null;
- Object instance = null;
-
- try {
- candidate = Class.forName (name);
- // necessary because of J2ME .class issue
- instance = candidate.newInstance ();
- }
- catch (Exception e) {}
-
- if (candidate != null) {
- boolean recognized = false;
- if (instance instanceof XmlPullParser) {
- parserClasses.add(candidate);
- recognized = true;
- }
- if (instance instanceof XmlSerializer) {
- serializerClasses.add(candidate);
- recognized = true;
- }
- if (instance instanceof XmlPullParserFactory) {
- if (factory == null) {
- factory = (XmlPullParserFactory) instance;
- }
- recognized = true;
- }
- if (!recognized) {
- throw new XmlPullParserException ("incompatible class: "+name);
- }
- }
- pos = cut + 1;
- }
-
- if (factory == null) {
- factory = new XmlPullParserFactory ();
- }
- factory.parserClasses = parserClasses;
- factory.serializerClasses = serializerClasses;
- factory.classNamesLocation = "org.kxml2.io.kXmlParser,org.kxml2.io.KXmlSerializer";
- return factory;
+ return newInstance();
}
}
diff --git a/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java b/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java
index 88cffd7..7b5b440 100644
--- a/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java
+++ b/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java
@@ -36,7 +36,7 @@ import org.xmlpull.v1.XmlPullParserFactory;
/**
* SAX2 Driver that pulls events from XmlPullParser
- * and comverts them into SAX2 callbacks.
+ * and converts them into SAX2 callbacks.
*
* @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
*/